From 0c0a5d61ed9319e7e666990a7888f3b00868ac20 Mon Sep 17 00:00:00 2001 From: Thara Gopinath Date: Sat, 29 May 2010 22:02:23 +0530 Subject: OMAP3: PM: Adding smartreflex device file. 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 n-target vaules, a parameter to indicate whether smartreflex autocompensation needs to be enabled on init or not. An API omap_enable_smartreflex_on_init is provided for the board files to enable smartreflex autocompensation during system boot up. Signed-off-by: Thara Gopinath Signed-off-by: Kevin Hilman --- arch/arm/mach-omap2/sr_device.c | 131 ++++++++++++++++++++++++++++++++++++++++ 1 file changed, 131 insertions(+) create mode 100644 arch/arm/mach-omap2/sr_device.c (limited to 'arch/arm/mach-omap2/sr_device.c') diff --git a/arch/arm/mach-omap2/sr_device.c b/arch/arm/mach-omap2/sr_device.c new file mode 100644 index 000000000000..9a3538fb633a --- /dev/null +++ b/arch/arm/mach-omap2/sr_device.c @@ -0,0 +1,131 @@ +/* + * 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 "control.h" + +static bool sr_enable_on_init; + +static 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_set_nvalues(struct omap_volt_data *volt_data, + struct omap_sr_data *sr_data) +{ + struct omap_sr_nvalue_table *nvalue_table; + int i, count = 0; + + while (volt_data[count].volt_nominal) + count++; + + nvalue_table = kzalloc(sizeof(struct omap_sr_nvalue_table)*count, + GFP_KERNEL); + + for (i = 0; i < count; i++) { + u32 v = omap_ctrl_readl(volt_data[i].sr_efuse_offs); + + nvalue_table[i].efuse_offs = volt_data[i].sr_efuse_offs; + nvalue_table[i].nvalue = v; + } + + sr_data->nvalue_table = nvalue_table; + sr_data->nvalue_count = count; +} + +static int sr_dev_init(struct omap_hwmod *oh, void *user) +{ + struct omap_sr_data *sr_data; + struct omap_device *od; + struct omap_volt_data *volt_data; + 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; + } + + if (!oh->vdd_name) { + pr_err("%s: No voltage domain specified for %s." + "Cannot initialize\n", __func__, oh->name); + goto exit; + } + + sr_data->ip_type = oh->class->rev; + sr_data->senn_mod = 0x1; + sr_data->senp_mod = 0x1; + + sr_data->voltdm = omap_voltage_domain_lookup(oh->vdd_name); + if (IS_ERR(sr_data->voltdm)) { + pr_err("%s: Unable to get voltage domain pointer for VDD %s\n", + __func__, oh->vdd_name); + goto exit; + } + + omap_voltage_get_volttable(sr_data->voltdm, &volt_data); + if (!volt_data) { + pr_warning("%s: No Voltage table registerd fo VDD%d." + "Something really wrong\n\n", __func__, i + 1); + goto exit; + } + + sr_set_nvalues(volt_data, sr_data); + + sr_data->enable_on_init = sr_enable_on_init; + + 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); +exit: + i++; + kfree(sr_data); + return 0; +} + +/* + * API to be called from board files to enable smartreflex + * autocompensation at init. + */ +void __init omap_enable_smartreflex_on_init(void) +{ + sr_enable_on_init = true; +} + +int __init omap_devinit_smartreflex(void) +{ + return omap_hwmod_for_each_by_class("smartreflex", sr_dev_init, NULL); +} -- cgit v1.2.3 From b35cecf978e33bf8f4be0f36ffe00fe10f381c4a Mon Sep 17 00:00:00 2001 From: Thara Gopinath Date: Wed, 18 Aug 2010 12:23:12 +0530 Subject: OMAP4: Smartreflex framework extensions This patch extends the smartreflex framework to support OMAP4. The changes are minor like compiling smartreflex Kconfig option for OMAP4 also, and a couple of OMAP4 checks in the smartreflex framework. The change in sr_device.c where new logic has to be introduced for reading the efuse registers is due to the fact that in OMAP4 the efuse registers are 24 bit aligned. A __raw_readl will fail for non-32 bit aligned address and hence the 8-bit read and shift. Signed-off-by: Thara Gopinath Signed-off-by: Kevin Hilman --- arch/arm/mach-omap2/smartreflex.c | 8 ++++++-- arch/arm/mach-omap2/sr_device.c | 17 ++++++++++++++++- arch/arm/plat-omap/Kconfig | 2 +- 3 files changed, 23 insertions(+), 4 deletions(-) (limited to 'arch/arm/mach-omap2/sr_device.c') diff --git a/arch/arm/mach-omap2/smartreflex.c b/arch/arm/mach-omap2/smartreflex.c index 52a05b336c08..77ecebf3fae2 100644 --- a/arch/arm/mach-omap2/smartreflex.c +++ b/arch/arm/mach-omap2/smartreflex.c @@ -153,7 +153,11 @@ static void sr_set_clk_length(struct omap_sr *sr) struct clk *sys_ck; u32 sys_clk_speed; - sys_ck = clk_get(NULL, "sys_ck"); + if (cpu_is_omap34xx()) + sys_ck = clk_get(NULL, "sys_ck"); + else + sys_ck = clk_get(NULL, "sys_clkin_ck"); + if (IS_ERR(sys_ck)) { dev_err(&sr->pdev->dev, "%s: unable to get sys clk\n", __func__); @@ -193,7 +197,7 @@ static void sr_set_regfields(struct omap_sr *sr) * file or pmic specific data structure. In that case these structure * fields will have to be populated using the pdata or pmic structure. */ - if (cpu_is_omap34xx()) { + if (cpu_is_omap34xx() || cpu_is_omap44xx()) { sr->err_weight = OMAP3430_SR_ERRWEIGHT; sr->err_maxlimit = OMAP3430_SR_ERRMAXLIMIT; sr->accum_data = OMAP3430_SR_ACCUMDATA; diff --git a/arch/arm/mach-omap2/sr_device.c b/arch/arm/mach-omap2/sr_device.c index 9a3538fb633a..786d685c09a9 100644 --- a/arch/arm/mach-omap2/sr_device.c +++ b/arch/arm/mach-omap2/sr_device.c @@ -20,6 +20,7 @@ #include #include +#include #include #include @@ -51,7 +52,21 @@ static void __init sr_set_nvalues(struct omap_volt_data *volt_data, GFP_KERNEL); for (i = 0; i < count; i++) { - u32 v = omap_ctrl_readl(volt_data[i].sr_efuse_offs); + u32 v; + /* + * In OMAP4 the efuse registers are 24 bit aligned. + * A __raw_readl will fail for non-32 bit aligned address + * and hence the 8-bit read and shift. + */ + if (cpu_is_omap44xx()) { + u16 offset = volt_data[i].sr_efuse_offs; + + v = omap_ctrl_readb(offset) | + omap_ctrl_readb(offset + 1) << 8 | + omap_ctrl_readb(offset + 2) << 16; + } else { + v = omap_ctrl_readl(volt_data[i].sr_efuse_offs); + } nvalue_table[i].efuse_offs = volt_data[i].sr_efuse_offs; nvalue_table[i].nvalue = v; diff --git a/arch/arm/plat-omap/Kconfig b/arch/arm/plat-omap/Kconfig index f4e05134aafa..11bf9f991509 100644 --- a/arch/arm/plat-omap/Kconfig +++ b/arch/arm/plat-omap/Kconfig @@ -37,7 +37,7 @@ config OMAP_DEBUG_LEDS config OMAP_SMARTREFLEX bool "SmartReflex support" - depends on ARCH_OMAP3 && PM + depends on (ARCH_OMAP3 || ARCH_OMAP4) && PM help Say Y if you want to enable SmartReflex. -- cgit v1.2.3