From mboxrd@z Thu Jan 1 00:00:00 1970 From: Thara Gopinath Subject: [PATCH 3/8] OMAP3: PM: Adding smartreflex device file. Date: Sat, 29 May 2010 22:02:23 +0530 Message-ID: <1275150748-15386-4-git-send-email-thara@ti.com> References: <1275150748-15386-1-git-send-email-thara@ti.com> <1275150748-15386-2-git-send-email-thara@ti.com> <1275150748-15386-3-git-send-email-thara@ti.com> Return-path: Received: from arroyo.ext.ti.com ([192.94.94.40]:38806 "EHLO arroyo.ext.ti.com" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S1757367Ab0E2Qcj (ORCPT ); Sat, 29 May 2010 12:32:39 -0400 In-Reply-To: <1275150748-15386-3-git-send-email-thara@ti.com> Sender: linux-omap-owner@vger.kernel.org List-Id: linux-omap@vger.kernel.org To: linux-omap@vger.kernel.org Cc: khilman@deeprootsystems.com, paul@pwsan.com, b-cousson@ti.com, vishwanath.bs@ti.com, sawant@ti.com, Thara Gopinath This patch adds support for device registration of various smartreflex module present in the system. This patch introduces the platform data for smartreflex devices which include the efused and test n-target vaules, module enable/disable pointers and a parameter to indicate whether smartreflex autocompensation needs to be enabled on init or not. Currently auocompensation is enabled on init by default for OMAP3430 ES3.1 chip. Signed-off-by: Thara Gopinath --- arch/arm/mach-omap2/Makefile | 2 +- arch/arm/mach-omap2/sr_device.c | 177 +++++++++++++++++++++++++++++++++++++++ 2 files changed, 178 insertions(+), 1 deletions(-) create mode 100644 arch/arm/mach-omap2/sr_device.c diff --git a/arch/arm/mach-omap2/Makefile b/arch/arm/mach-omap2/Makefile index 9ff9869..ab3772a 100644 --- a/arch/arm/mach-omap2/Makefile +++ b/arch/arm/mach-omap2/Makefile @@ -49,7 +49,7 @@ obj-$(CONFIG_ARCH_OMAP2) += sleep24xx.o obj-$(CONFIG_ARCH_OMAP3) += pm34xx.o sleep34xx.o cpuidle34xx.o \ voltage.o obj-$(CONFIG_PM_DEBUG) += pm-debug.o -obj-$(CONFIG_OMAP_SMARTREFLEX) += smartreflex.o +obj-$(CONFIG_OMAP_SMARTREFLEX) += sr_device.o smartreflex.o AFLAGS_sleep24xx.o :=-Wa,-march=armv6 AFLAGS_sleep34xx.o :=-Wa,-march=armv7-a diff --git a/arch/arm/mach-omap2/sr_device.c b/arch/arm/mach-omap2/sr_device.c new file mode 100644 index 0000000..5ca0253 --- /dev/null +++ b/arch/arm/mach-omap2/sr_device.c @@ -0,0 +1,177 @@ +/* + * OMAP3/OMAP4 smartreflex device file + * + * Author: Thara Gopinath + * + * Based originally on code from smartreflex.c + * Copyright (C) 2010 Texas Instruments, Inc. + * Thara Gopinath + * + * Copyright (C) 2008 Nokia Corporation + * Kalle Jokiniemi + * + * Copyright (C) 2007 Texas Instruments, Inc. + * Lesly A M + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License version 2 as + * published by the Free Software Foundation. + */ + +#include +#include + +#include +#include +#include +#include +#include + +#include "voltage.h" + +struct omap_device_pm_latency omap_sr_latency[] = { + { + .deactivate_func = omap_device_idle_hwmods, + .activate_func = omap_device_enable_hwmods, + .flags = OMAP_DEVICE_LATENCY_AUTO_ADJUST + }, +}; + +/* Read EFUSE values from control registers for OMAP3430 */ +static void __init sr_read_efuse(struct omap_sr_dev_data *dev_data, + struct omap_sr_data *sr_data) +{ + int i; + + if (!dev_data || !dev_data->volts_supported || !dev_data->volt_data || + !dev_data->efuse_nvalues_offs) { + pr_warning("%s: Bad parameters! dev_data = %x," + "dev_data->volts_supported = %x," + "dev_data->volt_data = %x," + "dev_data->efuse_nvalues_offs = %x\n", __func__, + (unsigned int)dev_data, dev_data->volts_supported, + (unsigned int)dev_data->volt_data, + (unsigned int)dev_data->efuse_nvalues_offs); + return; + } + + /* + * From OMAP3630 onwards there are no efuse registers for senn_mod + * and senp_mod. They have to be 0x1 by default. + */ + if (!dev_data->efuse_sr_control) { + sr_data->senn_mod = 0x1; + sr_data->senp_mod = 0x1; + } else { + sr_data->senn_mod = + ((omap_ctrl_readl(dev_data->efuse_sr_control) & + (0x3 << dev_data->sennenable_shift)) >> + dev_data->sennenable_shift); + sr_data->senp_mod = + ((omap_ctrl_readl(dev_data->efuse_sr_control) & + (0x3 << dev_data->senpenable_shift)) >> + dev_data->senpenable_shift); + } + + for (i = 0; i < dev_data->volts_supported; i++) + dev_data->volt_data[i].sr_nvalue = omap_ctrl_readl( + dev_data->efuse_nvalues_offs[i]); +} + +/* + * Hard coded nvalues for testing purposes for OMAP3430, + * may cause device to hang! + */ +static void __init sr_set_testing_nvalues(struct omap_sr_dev_data *dev_data, + struct omap_sr_data *sr_data) +{ + int i; + + if (!dev_data || !dev_data->volts_supported || + !dev_data->volt_data || !dev_data->test_nvalues) { + pr_warning("%s: Bad parameters! dev_data = %x," + "dev_data->volts_supported = %x," + "dev_data->volt_data = %x," + "dev_data->test_nvalues = %x\n", __func__, + (unsigned int)dev_data, dev_data->volts_supported, + (unsigned int)dev_data->volt_data, + (unsigned int)dev_data->test_nvalues); + return; + } + + sr_data->senn_mod = dev_data->test_sennenable; + sr_data->senp_mod = dev_data->test_senpenable; + for (i = 0; i < dev_data->volts_supported; i++) + dev_data->volt_data[i].sr_nvalue = dev_data->test_nvalues[i]; +} + +static void __init sr_set_nvalues(struct omap_sr_dev_data *dev_data, + struct omap_sr_data *sr_data) +{ + if (SR_TESTING_NVALUES) + sr_set_testing_nvalues(dev_data, sr_data); + else + sr_read_efuse(dev_data, sr_data); +} + +static int sr_dev_init(struct omap_hwmod *oh, void *user) +{ + struct omap_sr_data *sr_data; + struct omap_sr_dev_data *sr_dev_data; + struct omap_device *od; + char *name = "smartreflex"; + static int i; + + sr_data = kzalloc(sizeof(struct omap_sr_data), GFP_KERNEL); + if (!sr_data) { + pr_err("%s: Unable to allocate memory for %s sr_data.Error!\n", + __func__, oh->name); + return -ENOMEM; + } + + sr_dev_data = (struct omap_sr_dev_data *)oh->dev_attr; + /* + * OMAP3430 ES3.1 chips by default come with Efuse burnt + * with parameters required for full functionality of + * smartreflex AVS feature like ntarget values , sennenable + * and senpenable. So enable the SR AVS feature during boot up + * itself if it is a OMAP3430 ES3.1 chip. + */ + if (cpu_is_omap343x()) { + if (omap_rev() == OMAP3430_REV_ES3_1) + sr_data->enable_on_init = true; + else + sr_data->enable_on_init = false; + } else { + sr_data->enable_on_init = false; + } + sr_data->device_enable = omap_device_enable; + sr_data->device_shutdown = omap_device_shutdown; + sr_data->device_idle = omap_device_idle; + sr_dev_data->volts_supported = omap_get_voltage_table(i, + &sr_dev_data->volt_data); + if (!sr_dev_data->volts_supported) { + pr_warning("%s: No Voltage table registerd fo VDD%d.Something \ + really wrong\n\n", __func__, i + 1); + i++; + kfree(sr_data); + return 0; + } + sr_set_nvalues(sr_dev_data, sr_data); + od = omap_device_build(name, i, oh, sr_data, sizeof(*sr_data), + omap_sr_latency, + ARRAY_SIZE(omap_sr_latency), 0); + if (IS_ERR(od)) { + pr_warning("%s: Could not build omap_device for %s: %s.\n\n", + __func__, name, oh->name); + kfree(sr_data); + } + i++; + return 0; +} + +static int __init omap_devinit_smartreflex(void) +{ + return omap_hwmod_for_each_by_class("smartreflex", sr_dev_init, NULL); +} +subsys_initcall(omap_devinit_smartreflex); -- 1.7.0.rc1.33.g07cf0f