mirror of
https://git.yoctoproject.org/meta-ti
synced 2026-05-29 23:12:45 +00:00
linux 3.0: initial recipe that will track 3.0rc till 3.0 final
Signed-off-by: Koen Kooi <koen@dominion.thruhere.net>
This commit is contained in:
+196
@@ -0,0 +1,196 @@
|
|||||||
|
From 033514238d4b2b59b1507f39372dbabe7365c102 Mon Sep 17 00:00:00 2001
|
||||||
|
From: Fernandes, Joel A <joelagnel@ti.com>
|
||||||
|
Date: Tue, 7 Jun 2011 15:54:45 -0500
|
||||||
|
Subject: [PATCH] OMAP3: beagle: add support for beagleboard xM revision C
|
||||||
|
|
||||||
|
OMAP3: beagle: add support for beagleboard xM revision C
|
||||||
|
|
||||||
|
The USB enable GPIO has been in beagleboard xM revision C.
|
||||||
|
The USER button has been moved since beagleboard xM.
|
||||||
|
Also, board specific initialization has been moved to beagle_config struct
|
||||||
|
and initialized in omap3_beagle_init_rev. Default values in struct are for xMC.
|
||||||
|
|
||||||
|
Signed-off-by: Joel A Fernandes <joelagnel@ti.com>
|
||||||
|
Signed-off-by: Koen Kooi <koen@dominion.thruhere.net>
|
||||||
|
---
|
||||||
|
arch/arm/mach-omap2/board-omap3beagle.c | 78 ++++++++++++++++++++-----------
|
||||||
|
1 files changed, 51 insertions(+), 27 deletions(-)
|
||||||
|
|
||||||
|
diff --git a/arch/arm/mach-omap2/board-omap3beagle.c b/arch/arm/mach-omap2/board-omap3beagle.c
|
||||||
|
index 7f21d24..4b113b2 100644
|
||||||
|
--- a/arch/arm/mach-omap2/board-omap3beagle.c
|
||||||
|
+++ b/arch/arm/mach-omap2/board-omap3beagle.c
|
||||||
|
@@ -61,7 +61,8 @@
|
||||||
|
* AXBX = GPIO173, GPIO172, GPIO171: 1 1 1
|
||||||
|
* C1_3 = GPIO173, GPIO172, GPIO171: 1 1 0
|
||||||
|
* C4 = GPIO173, GPIO172, GPIO171: 1 0 1
|
||||||
|
- * XM = GPIO173, GPIO172, GPIO171: 0 0 0
|
||||||
|
+ * XMA/XMB = GPIO173, GPIO172, GPIO171: 0 0 0
|
||||||
|
+ * XMC = GPIO173, GPIO172, GPIO171: 0 1 0
|
||||||
|
*/
|
||||||
|
enum {
|
||||||
|
OMAP3BEAGLE_BOARD_UNKN = 0,
|
||||||
|
@@ -69,14 +70,26 @@ enum {
|
||||||
|
OMAP3BEAGLE_BOARD_C1_3,
|
||||||
|
OMAP3BEAGLE_BOARD_C4,
|
||||||
|
OMAP3BEAGLE_BOARD_XM,
|
||||||
|
+ OMAP3BEAGLE_BOARD_XMC,
|
||||||
|
};
|
||||||
|
|
||||||
|
static u8 omap3_beagle_version;
|
||||||
|
|
||||||
|
-static u8 omap3_beagle_get_rev(void)
|
||||||
|
-{
|
||||||
|
- return omap3_beagle_version;
|
||||||
|
-}
|
||||||
|
+/*
|
||||||
|
+ * Board-specific configuration
|
||||||
|
+ * Defaults to BeagleBoard-xMC
|
||||||
|
+ */
|
||||||
|
+static struct {
|
||||||
|
+ int mmc1_gpio_wp;
|
||||||
|
+ int usb_pwr_level;
|
||||||
|
+ int reset_gpio;
|
||||||
|
+ int usr_button_gpio;
|
||||||
|
+} beagle_config = {
|
||||||
|
+ .mmc1_gpio_wp = -EINVAL,
|
||||||
|
+ .usb_pwr_level = GPIOF_OUT_INIT_LOW,
|
||||||
|
+ .reset_gpio = 129,
|
||||||
|
+ .usr_button_gpio = 4,
|
||||||
|
+};
|
||||||
|
|
||||||
|
static struct gpio omap3_beagle_rev_gpios[] __initdata = {
|
||||||
|
{ 171, GPIOF_IN, "rev_id_0" },
|
||||||
|
@@ -111,18 +124,32 @@ static void __init omap3_beagle_init_rev(void)
|
||||||
|
case 7:
|
||||||
|
printk(KERN_INFO "OMAP3 Beagle Rev: Ax/Bx\n");
|
||||||
|
omap3_beagle_version = OMAP3BEAGLE_BOARD_AXBX;
|
||||||
|
+ beagle_config.mmc1_gpio_wp = 29;
|
||||||
|
+ beagle_config.reset_gpio = 170;
|
||||||
|
+ beagle_config.usr_button_gpio = 7;
|
||||||
|
break;
|
||||||
|
case 6:
|
||||||
|
printk(KERN_INFO "OMAP3 Beagle Rev: C1/C2/C3\n");
|
||||||
|
omap3_beagle_version = OMAP3BEAGLE_BOARD_C1_3;
|
||||||
|
+ beagle_config.mmc1_gpio_wp = 23;
|
||||||
|
+ beagle_config.reset_gpio = 170;
|
||||||
|
+ beagle_config.usr_button_gpio = 7;
|
||||||
|
break;
|
||||||
|
case 5:
|
||||||
|
printk(KERN_INFO "OMAP3 Beagle Rev: C4\n");
|
||||||
|
omap3_beagle_version = OMAP3BEAGLE_BOARD_C4;
|
||||||
|
+ beagle_config.mmc1_gpio_wp = 23;
|
||||||
|
+ beagle_config.reset_gpio = 170;
|
||||||
|
+ beagle_config.usr_button_gpio = 7;
|
||||||
|
break;
|
||||||
|
case 0:
|
||||||
|
- printk(KERN_INFO "OMAP3 Beagle Rev: xM\n");
|
||||||
|
+ printk(KERN_INFO "OMAP3 Beagle Rev: xM Ax/Bx\n");
|
||||||
|
omap3_beagle_version = OMAP3BEAGLE_BOARD_XM;
|
||||||
|
+ beagle_config.usb_pwr_level = GPIOF_OUT_INIT_HIGH;
|
||||||
|
+ break;
|
||||||
|
+ case 2:
|
||||||
|
+ printk(KERN_INFO "OMAP3 Beagle Rev: xM C\n");
|
||||||
|
+ omap3_beagle_version = OMAP3BEAGLE_BOARD_XMC;
|
||||||
|
break;
|
||||||
|
default:
|
||||||
|
printk(KERN_INFO "OMAP3 Beagle Rev: unknown %hd\n", beagle_rev);
|
||||||
|
@@ -234,7 +261,7 @@ static struct omap2_hsmmc_info mmc[] = {
|
||||||
|
{
|
||||||
|
.mmc = 1,
|
||||||
|
.caps = MMC_CAP_4_BIT_DATA | MMC_CAP_8_BIT_DATA,
|
||||||
|
- .gpio_wp = 29,
|
||||||
|
+ .gpio_wp = -EINVAL,
|
||||||
|
},
|
||||||
|
{} /* Terminator */
|
||||||
|
};
|
||||||
|
@@ -252,17 +279,11 @@ static struct gpio_led gpio_leds[];
|
||||||
|
static int beagle_twl_gpio_setup(struct device *dev,
|
||||||
|
unsigned gpio, unsigned ngpio)
|
||||||
|
{
|
||||||
|
- int r, usb_pwr_level;
|
||||||
|
-
|
||||||
|
- if (omap3_beagle_get_rev() == OMAP3BEAGLE_BOARD_XM) {
|
||||||
|
- mmc[0].gpio_wp = -EINVAL;
|
||||||
|
- } else if ((omap3_beagle_get_rev() == OMAP3BEAGLE_BOARD_C1_3) ||
|
||||||
|
- (omap3_beagle_get_rev() == OMAP3BEAGLE_BOARD_C4)) {
|
||||||
|
- omap_mux_init_gpio(23, OMAP_PIN_INPUT);
|
||||||
|
- mmc[0].gpio_wp = 23;
|
||||||
|
- } else {
|
||||||
|
- omap_mux_init_gpio(29, OMAP_PIN_INPUT);
|
||||||
|
- }
|
||||||
|
+ int r;
|
||||||
|
+
|
||||||
|
+ if (beagle_config.mmc1_gpio_wp != -EINVAL)
|
||||||
|
+ omap_mux_init_gpio(beagle_config.mmc1_gpio_wp, OMAP_PIN_INPUT);
|
||||||
|
+ mmc[0].gpio_wp = beagle_config.mmc1_gpio_wp;
|
||||||
|
/* gpio + 0 is "mmc0_cd" (input/IRQ) */
|
||||||
|
mmc[0].gpio_cd = gpio + 0;
|
||||||
|
omap2_hsmmc_init(mmc);
|
||||||
|
@@ -276,9 +297,8 @@ static int beagle_twl_gpio_setup(struct device *dev,
|
||||||
|
* high / others active low)
|
||||||
|
* DVI reset GPIO is different between beagle revisions
|
||||||
|
*/
|
||||||
|
- if (omap3_beagle_get_rev() == OMAP3BEAGLE_BOARD_XM) {
|
||||||
|
- usb_pwr_level = GPIOF_OUT_INIT_HIGH;
|
||||||
|
- beagle_dvi_device.reset_gpio = 129;
|
||||||
|
+ /* Valid for all -xM revisions */
|
||||||
|
+ if (cpu_is_omap3630()) {
|
||||||
|
/*
|
||||||
|
* gpio + 1 on Xm controls the TFP410's enable line (active low)
|
||||||
|
* gpio + 2 control varies depending on the board rev as below:
|
||||||
|
@@ -296,8 +316,6 @@ static int beagle_twl_gpio_setup(struct device *dev,
|
||||||
|
pr_err("%s: unable to configure DVI_LDO_EN\n",
|
||||||
|
__func__);
|
||||||
|
} else {
|
||||||
|
- usb_pwr_level = GPIOF_OUT_INIT_LOW;
|
||||||
|
- beagle_dvi_device.reset_gpio = 170;
|
||||||
|
/*
|
||||||
|
* REVISIT: need ehci-omap hooks for external VBUS
|
||||||
|
* power switch and overcurrent detect
|
||||||
|
@@ -305,8 +323,10 @@ static int beagle_twl_gpio_setup(struct device *dev,
|
||||||
|
if (gpio_request_one(gpio + 1, GPIOF_IN, "EHCI_nOC"))
|
||||||
|
pr_err("%s: unable to configure EHCI_nOC\n", __func__);
|
||||||
|
}
|
||||||
|
+ beagle_dvi_device.reset_gpio = beagle_config.reset_gpio;
|
||||||
|
|
||||||
|
- gpio_request_one(gpio + TWL4030_GPIO_MAX, usb_pwr_level, "nEN_USB_PWR");
|
||||||
|
+ gpio_request_one(gpio + TWL4030_GPIO_MAX, beagle_config.usb_pwr_level,
|
||||||
|
+ "nEN_USB_PWR");
|
||||||
|
|
||||||
|
/* TWL4030_GPIO_MAX + 1 == ledB, PMU_STAT (out, active low LED) */
|
||||||
|
gpio_leds[2].gpio = gpio + TWL4030_GPIO_MAX + 1;
|
||||||
|
@@ -458,7 +478,8 @@ static struct platform_device leds_gpio = {
|
||||||
|
static struct gpio_keys_button gpio_buttons[] = {
|
||||||
|
{
|
||||||
|
.code = BTN_EXTRA,
|
||||||
|
- .gpio = 7,
|
||||||
|
+ /* Dynamically assigned depending on board */
|
||||||
|
+ .gpio = -EINVAL,
|
||||||
|
.desc = "user",
|
||||||
|
.wakeup = 1,
|
||||||
|
},
|
||||||
|
@@ -525,8 +546,8 @@ static void __init beagle_opp_init(void)
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
- /* Custom OPP enabled for XM */
|
||||||
|
- if (omap3_beagle_get_rev() == OMAP3BEAGLE_BOARD_XM) {
|
||||||
|
+ /* Custom OPP enabled for all xM versions */
|
||||||
|
+ if (cpu_is_omap3630()) {
|
||||||
|
struct omap_hwmod *mh = omap_hwmod_lookup("mpu");
|
||||||
|
struct omap_hwmod *dh = omap_hwmod_lookup("iva");
|
||||||
|
struct device *dev;
|
||||||
|
@@ -566,6 +587,9 @@ static void __init omap3_beagle_init(void)
|
||||||
|
omap3_mux_init(board_mux, OMAP_PACKAGE_CBB);
|
||||||
|
omap3_beagle_init_rev();
|
||||||
|
omap3_beagle_i2c_init();
|
||||||
|
+
|
||||||
|
+ gpio_buttons[0].gpio = beagle_config.usr_button_gpio;
|
||||||
|
+
|
||||||
|
platform_add_devices(omap3_beagle_devices,
|
||||||
|
ARRAY_SIZE(omap3_beagle_devices));
|
||||||
|
omap_display_init(&beagle_dss_data);
|
||||||
|
--
|
||||||
|
1.6.6.1
|
||||||
|
|
||||||
File diff suppressed because it is too large
Load Diff
+36
@@ -0,0 +1,36 @@
|
|||||||
|
From 0c06ec8074efa965a12ce79122ab64cebbb27dc9 Mon Sep 17 00:00:00 2001
|
||||||
|
From: Nishanth Menon <nm@ti.com>
|
||||||
|
Date: Mon, 14 Feb 2011 12:41:10 +0530
|
||||||
|
Subject: [PATCH 1/7] OMAP3+: SR: disable interrupt by default
|
||||||
|
|
||||||
|
We will enable and disable interrupt on a need basis in the class
|
||||||
|
driver. We need to keep the IRQ disabled by default else the
|
||||||
|
forceupdate or vcbypass events could trigger events that we don't
|
||||||
|
need/expect to handle.
|
||||||
|
|
||||||
|
This is a preparation for SmartReflex AVS class drivers such as
|
||||||
|
class 2 and class 1.5 which would need to use interrupts. Existing
|
||||||
|
SmartReflex AVS class 3 driver does not require to use interrupts
|
||||||
|
and is not impacted by this change.
|
||||||
|
|
||||||
|
Signed-off-by: Nishanth Menon <nm@ti.com>
|
||||||
|
Signed-off-by: Kevin Hilman <khilman@ti.com>
|
||||||
|
---
|
||||||
|
arch/arm/mach-omap2/smartreflex.c | 1 +
|
||||||
|
1 files changed, 1 insertions(+), 0 deletions(-)
|
||||||
|
|
||||||
|
diff --git a/arch/arm/mach-omap2/smartreflex.c b/arch/arm/mach-omap2/smartreflex.c
|
||||||
|
index fb7dc52..998b57f 100644
|
||||||
|
--- a/arch/arm/mach-omap2/smartreflex.c
|
||||||
|
+++ b/arch/arm/mach-omap2/smartreflex.c
|
||||||
|
@@ -270,6 +270,7 @@ static int sr_late_init(struct omap_sr *sr_info)
|
||||||
|
0, name, (void *)sr_info);
|
||||||
|
if (ret)
|
||||||
|
goto error;
|
||||||
|
+ disable_irq(sr_info->irq);
|
||||||
|
}
|
||||||
|
|
||||||
|
if (pdata && pdata->enable_on_init)
|
||||||
|
--
|
||||||
|
1.6.6.1
|
||||||
|
|
||||||
+40
@@ -0,0 +1,40 @@
|
|||||||
|
From 2c555d8ee3544326033cb3b0ead6c0eb48cb4919 Mon Sep 17 00:00:00 2001
|
||||||
|
From: Nishanth Menon <nm@ti.com>
|
||||||
|
Date: Mon, 14 Feb 2011 21:14:17 +0530
|
||||||
|
Subject: [PATCH 2/7] OMAP3+: SR: enable/disable SR only on need
|
||||||
|
|
||||||
|
Since we already know the state of the autocomp enablement, we can
|
||||||
|
see if the requested state is different from the current state and
|
||||||
|
enable/disable SR only on the need basis.
|
||||||
|
|
||||||
|
Signed-off-by: Nishanth Menon <nm@ti.com>
|
||||||
|
Signed-off-by: Kevin Hilman <khilman@ti.com>
|
||||||
|
---
|
||||||
|
arch/arm/mach-omap2/smartreflex.c | 11 +++++++----
|
||||||
|
1 files changed, 7 insertions(+), 4 deletions(-)
|
||||||
|
|
||||||
|
diff --git a/arch/arm/mach-omap2/smartreflex.c b/arch/arm/mach-omap2/smartreflex.c
|
||||||
|
index 998b57f..a4b4319 100644
|
||||||
|
--- a/arch/arm/mach-omap2/smartreflex.c
|
||||||
|
+++ b/arch/arm/mach-omap2/smartreflex.c
|
||||||
|
@@ -809,10 +809,13 @@ static int omap_sr_autocomp_store(void *data, u64 val)
|
||||||
|
return -EINVAL;
|
||||||
|
}
|
||||||
|
|
||||||
|
- if (!val)
|
||||||
|
- sr_stop_vddautocomp(sr_info);
|
||||||
|
- else
|
||||||
|
- sr_start_vddautocomp(sr_info);
|
||||||
|
+ /* control enable/disable only if there is a delta in value */
|
||||||
|
+ if (sr_info->autocomp_active != val) {
|
||||||
|
+ if (!val)
|
||||||
|
+ sr_stop_vddautocomp(sr_info);
|
||||||
|
+ else
|
||||||
|
+ sr_start_vddautocomp(sr_info);
|
||||||
|
+ }
|
||||||
|
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
--
|
||||||
|
1.6.6.1
|
||||||
|
|
||||||
+48
@@ -0,0 +1,48 @@
|
|||||||
|
From 60b31f5fad1dda709f3e38ad88dcc8d1496db52d Mon Sep 17 00:00:00 2001
|
||||||
|
From: Nishanth Menon <nm@ti.com>
|
||||||
|
Date: Mon, 14 Feb 2011 12:33:13 +0530
|
||||||
|
Subject: [PATCH 3/7] OMAP3+: SR: fix cosmetic indentation
|
||||||
|
|
||||||
|
Error label case seems to have a 2 tab indentation when just 1 is
|
||||||
|
necessary.
|
||||||
|
|
||||||
|
Signed-off-by: Nishanth Menon <nm@ti.com>
|
||||||
|
Signed-off-by: Kevin Hilman <khilman@ti.com>
|
||||||
|
---
|
||||||
|
arch/arm/mach-omap2/smartreflex.c | 20 ++++++++++----------
|
||||||
|
1 files changed, 10 insertions(+), 10 deletions(-)
|
||||||
|
|
||||||
|
diff --git a/arch/arm/mach-omap2/smartreflex.c b/arch/arm/mach-omap2/smartreflex.c
|
||||||
|
index a4b4319..931879d 100644
|
||||||
|
--- a/arch/arm/mach-omap2/smartreflex.c
|
||||||
|
+++ b/arch/arm/mach-omap2/smartreflex.c
|
||||||
|
@@ -279,16 +279,16 @@ static int sr_late_init(struct omap_sr *sr_info)
|
||||||
|
return ret;
|
||||||
|
|
||||||
|
error:
|
||||||
|
- iounmap(sr_info->base);
|
||||||
|
- mem = platform_get_resource(sr_info->pdev, IORESOURCE_MEM, 0);
|
||||||
|
- release_mem_region(mem->start, resource_size(mem));
|
||||||
|
- list_del(&sr_info->node);
|
||||||
|
- dev_err(&sr_info->pdev->dev, "%s: ERROR in registering"
|
||||||
|
- "interrupt handler. Smartreflex will"
|
||||||
|
- "not function as desired\n", __func__);
|
||||||
|
- kfree(name);
|
||||||
|
- kfree(sr_info);
|
||||||
|
- return ret;
|
||||||
|
+ iounmap(sr_info->base);
|
||||||
|
+ mem = platform_get_resource(sr_info->pdev, IORESOURCE_MEM, 0);
|
||||||
|
+ release_mem_region(mem->start, resource_size(mem));
|
||||||
|
+ list_del(&sr_info->node);
|
||||||
|
+ dev_err(&sr_info->pdev->dev, "%s: ERROR in registering"
|
||||||
|
+ "interrupt handler. Smartreflex will"
|
||||||
|
+ "not function as desired\n", __func__);
|
||||||
|
+ kfree(name);
|
||||||
|
+ kfree(sr_info);
|
||||||
|
+ return ret;
|
||||||
|
}
|
||||||
|
|
||||||
|
static void sr_v1_disable(struct omap_sr *sr)
|
||||||
|
--
|
||||||
|
1.6.6.1
|
||||||
|
|
||||||
+79
@@ -0,0 +1,79 @@
|
|||||||
|
From e38ec7b32ebb15b1e703743ea14ca7a29675a3ba Mon Sep 17 00:00:00 2001
|
||||||
|
From: Kevin Hilman <khilman@ti.com>
|
||||||
|
Date: Thu, 26 May 2011 14:48:19 -0700
|
||||||
|
Subject: [PATCH 4/7] OMAP3: PM debug: remove sleep_while_idle feature
|
||||||
|
|
||||||
|
Remove the OMAP-specific PM debug 'sleep_while_idle' feature which is
|
||||||
|
currently available as an OMAP-specific debugfs entry.
|
||||||
|
|
||||||
|
This duplicates existing ARM-generic functionality available as a
|
||||||
|
boot-time option using the boot cmdline option 'hohlt'.
|
||||||
|
|
||||||
|
If runtime configuration of this is needed, then adding a debugfs
|
||||||
|
entry for the ARM-generic hlt/nohlt interface should be added.
|
||||||
|
|
||||||
|
Tested-by: Santosh Shilimkar <santosh.shilimkar@ti.com>
|
||||||
|
Acked-by: Santosh Shilimkar <santosh.shilimkar@ti.com>
|
||||||
|
Acked-by: Jean Pihet <j-pihet@ti.com>
|
||||||
|
Signed-off-by: Kevin Hilman <khilman@ti.com>
|
||||||
|
---
|
||||||
|
arch/arm/mach-omap2/pm-debug.c | 3 ---
|
||||||
|
arch/arm/mach-omap2/pm.h | 2 --
|
||||||
|
arch/arm/mach-omap2/pm34xx.c | 2 --
|
||||||
|
3 files changed, 0 insertions(+), 7 deletions(-)
|
||||||
|
|
||||||
|
diff --git a/arch/arm/mach-omap2/pm-debug.c b/arch/arm/mach-omap2/pm-debug.c
|
||||||
|
index e01da45..d9f0821 100644
|
||||||
|
--- a/arch/arm/mach-omap2/pm-debug.c
|
||||||
|
+++ b/arch/arm/mach-omap2/pm-debug.c
|
||||||
|
@@ -40,7 +40,6 @@
|
||||||
|
|
||||||
|
int omap2_pm_debug;
|
||||||
|
u32 enable_off_mode;
|
||||||
|
-u32 sleep_while_idle;
|
||||||
|
u32 wakeup_timer_seconds;
|
||||||
|
u32 wakeup_timer_milliseconds;
|
||||||
|
|
||||||
|
@@ -639,8 +638,6 @@ static int pm_dbg_init(void)
|
||||||
|
|
||||||
|
(void) debugfs_create_file("enable_off_mode", S_IRUGO | S_IWUSR, d,
|
||||||
|
&enable_off_mode, &pm_dbg_option_fops);
|
||||||
|
- (void) debugfs_create_file("sleep_while_idle", S_IRUGO | S_IWUSR, d,
|
||||||
|
- &sleep_while_idle, &pm_dbg_option_fops);
|
||||||
|
(void) debugfs_create_file("wakeup_timer_seconds", S_IRUGO | S_IWUSR, d,
|
||||||
|
&wakeup_timer_seconds, &pm_dbg_option_fops);
|
||||||
|
(void) debugfs_create_file("wakeup_timer_milliseconds",
|
||||||
|
diff --git a/arch/arm/mach-omap2/pm.h b/arch/arm/mach-omap2/pm.h
|
||||||
|
index 45bcfce..674eedc 100644
|
||||||
|
--- a/arch/arm/mach-omap2/pm.h
|
||||||
|
+++ b/arch/arm/mach-omap2/pm.h
|
||||||
|
@@ -69,13 +69,11 @@ extern void omap2_pm_dump(int mode, int resume, unsigned int us);
|
||||||
|
extern void omap2_pm_wakeup_on_timer(u32 seconds, u32 milliseconds);
|
||||||
|
extern int omap2_pm_debug;
|
||||||
|
extern u32 enable_off_mode;
|
||||||
|
-extern u32 sleep_while_idle;
|
||||||
|
#else
|
||||||
|
#define omap2_pm_dump(mode, resume, us) do {} while (0);
|
||||||
|
#define omap2_pm_wakeup_on_timer(seconds, milliseconds) do {} while (0);
|
||||||
|
#define omap2_pm_debug 0
|
||||||
|
#define enable_off_mode 0
|
||||||
|
-#define sleep_while_idle 0
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#if defined(CONFIG_PM_DEBUG) && defined(CONFIG_DEBUG_FS)
|
||||||
|
diff --git a/arch/arm/mach-omap2/pm34xx.c b/arch/arm/mach-omap2/pm34xx.c
|
||||||
|
index c155c9d..cb34244 100644
|
||||||
|
--- a/arch/arm/mach-omap2/pm34xx.c
|
||||||
|
+++ b/arch/arm/mach-omap2/pm34xx.c
|
||||||
|
@@ -497,8 +497,6 @@ console_still_active:
|
||||||
|
|
||||||
|
int omap3_can_sleep(void)
|
||||||
|
{
|
||||||
|
- if (!sleep_while_idle)
|
||||||
|
- return 0;
|
||||||
|
if (!omap_uart_can_sleep())
|
||||||
|
return 0;
|
||||||
|
return 1;
|
||||||
|
--
|
||||||
|
1.6.6.1
|
||||||
|
|
||||||
+215
@@ -0,0 +1,215 @@
|
|||||||
|
From 51ea2570669b64adfaee2c4a757122f0376255dd Mon Sep 17 00:00:00 2001
|
||||||
|
From: Kevin Hilman <khilman@ti.com>
|
||||||
|
Date: Thu, 26 May 2011 14:07:41 -0700
|
||||||
|
Subject: [PATCH 5/7] OMAP2: PM debug: remove register dumping
|
||||||
|
|
||||||
|
Tested-by: Santosh Shilimkar <santosh.shilimkar@ti.com>
|
||||||
|
Acked-by: Santosh Shilimkar <santosh.shilimkar@ti.com>
|
||||||
|
Signed-off-by: Kevin Hilman <khilman@ti.com>
|
||||||
|
---
|
||||||
|
arch/arm/mach-omap2/pm-debug.c | 119 ----------------------------------------
|
||||||
|
arch/arm/mach-omap2/pm.h | 4 -
|
||||||
|
arch/arm/mach-omap2/pm24xx.c | 6 +-
|
||||||
|
3 files changed, 2 insertions(+), 127 deletions(-)
|
||||||
|
|
||||||
|
diff --git a/arch/arm/mach-omap2/pm-debug.c b/arch/arm/mach-omap2/pm-debug.c
|
||||||
|
index d9f0821..a8425d6 100644
|
||||||
|
--- a/arch/arm/mach-omap2/pm-debug.c
|
||||||
|
+++ b/arch/arm/mach-omap2/pm-debug.c
|
||||||
|
@@ -38,129 +38,10 @@
|
||||||
|
#include "prm2xxx_3xxx.h"
|
||||||
|
#include "pm.h"
|
||||||
|
|
||||||
|
-int omap2_pm_debug;
|
||||||
|
u32 enable_off_mode;
|
||||||
|
u32 wakeup_timer_seconds;
|
||||||
|
u32 wakeup_timer_milliseconds;
|
||||||
|
|
||||||
|
-#define DUMP_PRM_MOD_REG(mod, reg) \
|
||||||
|
- regs[reg_count].name = #mod "." #reg; \
|
||||||
|
- regs[reg_count++].val = omap2_prm_read_mod_reg(mod, reg)
|
||||||
|
-#define DUMP_CM_MOD_REG(mod, reg) \
|
||||||
|
- regs[reg_count].name = #mod "." #reg; \
|
||||||
|
- regs[reg_count++].val = omap2_cm_read_mod_reg(mod, reg)
|
||||||
|
-#define DUMP_PRM_REG(reg) \
|
||||||
|
- regs[reg_count].name = #reg; \
|
||||||
|
- regs[reg_count++].val = __raw_readl(reg)
|
||||||
|
-#define DUMP_CM_REG(reg) \
|
||||||
|
- regs[reg_count].name = #reg; \
|
||||||
|
- regs[reg_count++].val = __raw_readl(reg)
|
||||||
|
-#define DUMP_INTC_REG(reg, off) \
|
||||||
|
- regs[reg_count].name = #reg; \
|
||||||
|
- regs[reg_count++].val = \
|
||||||
|
- __raw_readl(OMAP2_L4_IO_ADDRESS(0x480fe000 + (off)))
|
||||||
|
-
|
||||||
|
-void omap2_pm_dump(int mode, int resume, unsigned int us)
|
||||||
|
-{
|
||||||
|
- struct reg {
|
||||||
|
- const char *name;
|
||||||
|
- u32 val;
|
||||||
|
- } regs[32];
|
||||||
|
- int reg_count = 0, i;
|
||||||
|
- const char *s1 = NULL, *s2 = NULL;
|
||||||
|
-
|
||||||
|
- if (!resume) {
|
||||||
|
-#if 0
|
||||||
|
- /* MPU */
|
||||||
|
- DUMP_PRM_MOD_REG(OCP_MOD, OMAP2_PRM_IRQENABLE_MPU_OFFSET);
|
||||||
|
- DUMP_CM_MOD_REG(MPU_MOD, OMAP2_CM_CLKSTCTRL);
|
||||||
|
- DUMP_PRM_MOD_REG(MPU_MOD, OMAP2_PM_PWSTCTRL);
|
||||||
|
- DUMP_PRM_MOD_REG(MPU_MOD, OMAP2_PM_PWSTST);
|
||||||
|
- DUMP_PRM_MOD_REG(MPU_MOD, PM_WKDEP);
|
||||||
|
-#endif
|
||||||
|
-#if 0
|
||||||
|
- /* INTC */
|
||||||
|
- DUMP_INTC_REG(INTC_MIR0, 0x0084);
|
||||||
|
- DUMP_INTC_REG(INTC_MIR1, 0x00a4);
|
||||||
|
- DUMP_INTC_REG(INTC_MIR2, 0x00c4);
|
||||||
|
-#endif
|
||||||
|
-#if 0
|
||||||
|
- DUMP_CM_MOD_REG(CORE_MOD, CM_FCLKEN1);
|
||||||
|
- if (cpu_is_omap24xx()) {
|
||||||
|
- DUMP_CM_MOD_REG(CORE_MOD, OMAP24XX_CM_FCLKEN2);
|
||||||
|
- DUMP_PRM_MOD_REG(OMAP24XX_GR_MOD,
|
||||||
|
- OMAP2_PRCM_CLKEMUL_CTRL_OFFSET);
|
||||||
|
- DUMP_PRM_MOD_REG(OMAP24XX_GR_MOD,
|
||||||
|
- OMAP2_PRCM_CLKSRC_CTRL_OFFSET);
|
||||||
|
- }
|
||||||
|
- DUMP_CM_MOD_REG(WKUP_MOD, CM_FCLKEN);
|
||||||
|
- DUMP_CM_MOD_REG(CORE_MOD, CM_ICLKEN1);
|
||||||
|
- DUMP_CM_MOD_REG(CORE_MOD, CM_ICLKEN2);
|
||||||
|
- DUMP_CM_MOD_REG(WKUP_MOD, CM_ICLKEN);
|
||||||
|
- DUMP_CM_MOD_REG(PLL_MOD, CM_CLKEN);
|
||||||
|
- DUMP_CM_MOD_REG(PLL_MOD, CM_AUTOIDLE);
|
||||||
|
- DUMP_PRM_MOD_REG(CORE_MOD, OMAP2_PM_PWSTST);
|
||||||
|
-#endif
|
||||||
|
-#if 0
|
||||||
|
- /* DSP */
|
||||||
|
- if (cpu_is_omap24xx()) {
|
||||||
|
- DUMP_CM_MOD_REG(OMAP24XX_DSP_MOD, CM_FCLKEN);
|
||||||
|
- DUMP_CM_MOD_REG(OMAP24XX_DSP_MOD, CM_ICLKEN);
|
||||||
|
- DUMP_CM_MOD_REG(OMAP24XX_DSP_MOD, CM_IDLEST);
|
||||||
|
- DUMP_CM_MOD_REG(OMAP24XX_DSP_MOD, CM_AUTOIDLE);
|
||||||
|
- DUMP_CM_MOD_REG(OMAP24XX_DSP_MOD, CM_CLKSEL);
|
||||||
|
- DUMP_CM_MOD_REG(OMAP24XX_DSP_MOD, OMAP2_CM_CLKSTCTRL);
|
||||||
|
- DUMP_PRM_MOD_REG(OMAP24XX_DSP_MOD, OMAP2_RM_RSTCTRL);
|
||||||
|
- DUMP_PRM_MOD_REG(OMAP24XX_DSP_MOD, OMAP2_RM_RSTST);
|
||||||
|
- DUMP_PRM_MOD_REG(OMAP24XX_DSP_MOD, OMAP2_PM_PWSTCTRL);
|
||||||
|
- DUMP_PRM_MOD_REG(OMAP24XX_DSP_MOD, OMAP2_PM_PWSTST);
|
||||||
|
- }
|
||||||
|
-#endif
|
||||||
|
- } else {
|
||||||
|
- DUMP_PRM_MOD_REG(CORE_MOD, PM_WKST1);
|
||||||
|
- if (cpu_is_omap24xx())
|
||||||
|
- DUMP_PRM_MOD_REG(CORE_MOD, OMAP24XX_PM_WKST2);
|
||||||
|
- DUMP_PRM_MOD_REG(WKUP_MOD, PM_WKST);
|
||||||
|
- DUMP_PRM_MOD_REG(OCP_MOD, OMAP2_PRCM_IRQSTATUS_MPU_OFFSET);
|
||||||
|
-#if 1
|
||||||
|
- DUMP_INTC_REG(INTC_PENDING_IRQ0, 0x0098);
|
||||||
|
- DUMP_INTC_REG(INTC_PENDING_IRQ1, 0x00b8);
|
||||||
|
- DUMP_INTC_REG(INTC_PENDING_IRQ2, 0x00d8);
|
||||||
|
-#endif
|
||||||
|
- }
|
||||||
|
-
|
||||||
|
- switch (mode) {
|
||||||
|
- case 0:
|
||||||
|
- s1 = "full";
|
||||||
|
- s2 = "retention";
|
||||||
|
- break;
|
||||||
|
- case 1:
|
||||||
|
- s1 = "MPU";
|
||||||
|
- s2 = "retention";
|
||||||
|
- break;
|
||||||
|
- case 2:
|
||||||
|
- s1 = "MPU";
|
||||||
|
- s2 = "idle";
|
||||||
|
- break;
|
||||||
|
- }
|
||||||
|
-
|
||||||
|
- if (!resume)
|
||||||
|
-#ifdef CONFIG_NO_HZ
|
||||||
|
- printk(KERN_INFO
|
||||||
|
- "--- Going to %s %s (next timer after %u ms)\n", s1, s2,
|
||||||
|
- jiffies_to_msecs(get_next_timer_interrupt(jiffies) -
|
||||||
|
- jiffies));
|
||||||
|
-#else
|
||||||
|
- printk(KERN_INFO "--- Going to %s %s\n", s1, s2);
|
||||||
|
-#endif
|
||||||
|
- else
|
||||||
|
- printk(KERN_INFO "--- Woke up (slept for %u.%03u ms)\n",
|
||||||
|
- us / 1000, us % 1000);
|
||||||
|
-
|
||||||
|
- for (i = 0; i < reg_count; i++)
|
||||||
|
- printk(KERN_INFO "%-20s: 0x%08x\n", regs[i].name, regs[i].val);
|
||||||
|
-}
|
||||||
|
-
|
||||||
|
void omap2_pm_wakeup_on_timer(u32 seconds, u32 milliseconds)
|
||||||
|
{
|
||||||
|
u32 tick_rate, cycles;
|
||||||
|
diff --git a/arch/arm/mach-omap2/pm.h b/arch/arm/mach-omap2/pm.h
|
||||||
|
index 674eedc..acac275 100644
|
||||||
|
--- a/arch/arm/mach-omap2/pm.h
|
||||||
|
+++ b/arch/arm/mach-omap2/pm.h
|
||||||
|
@@ -65,14 +65,10 @@ extern u32 wakeup_timer_milliseconds;
|
||||||
|
extern struct omap_dm_timer *gptimer_wakeup;
|
||||||
|
|
||||||
|
#ifdef CONFIG_PM_DEBUG
|
||||||
|
-extern void omap2_pm_dump(int mode, int resume, unsigned int us);
|
||||||
|
extern void omap2_pm_wakeup_on_timer(u32 seconds, u32 milliseconds);
|
||||||
|
-extern int omap2_pm_debug;
|
||||||
|
extern u32 enable_off_mode;
|
||||||
|
#else
|
||||||
|
-#define omap2_pm_dump(mode, resume, us) do {} while (0);
|
||||||
|
#define omap2_pm_wakeup_on_timer(seconds, milliseconds) do {} while (0);
|
||||||
|
-#define omap2_pm_debug 0
|
||||||
|
#define enable_off_mode 0
|
||||||
|
#endif
|
||||||
|
|
||||||
|
diff --git a/arch/arm/mach-omap2/pm24xx.c b/arch/arm/mach-omap2/pm24xx.c
|
||||||
|
index df3ded6..bf089e7 100644
|
||||||
|
--- a/arch/arm/mach-omap2/pm24xx.c
|
||||||
|
+++ b/arch/arm/mach-omap2/pm24xx.c
|
||||||
|
@@ -53,6 +53,8 @@
|
||||||
|
#include "powerdomain.h"
|
||||||
|
#include "clockdomain.h"
|
||||||
|
|
||||||
|
+static int omap2_pm_debug;
|
||||||
|
+
|
||||||
|
#ifdef CONFIG_SUSPEND
|
||||||
|
static suspend_state_t suspend_state = PM_SUSPEND_ON;
|
||||||
|
static inline bool is_suspending(void)
|
||||||
|
@@ -123,7 +125,6 @@ static void omap2_enter_full_retention(void)
|
||||||
|
omap2_gpio_prepare_for_idle(0);
|
||||||
|
|
||||||
|
if (omap2_pm_debug) {
|
||||||
|
- omap2_pm_dump(0, 0, 0);
|
||||||
|
getnstimeofday(&ts_preidle);
|
||||||
|
}
|
||||||
|
|
||||||
|
@@ -160,7 +161,6 @@ no_sleep:
|
||||||
|
getnstimeofday(&ts_postidle);
|
||||||
|
ts_idle = timespec_sub(ts_postidle, ts_preidle);
|
||||||
|
tmp = timespec_to_ns(&ts_idle) * NSEC_PER_USEC;
|
||||||
|
- omap2_pm_dump(0, 1, tmp);
|
||||||
|
}
|
||||||
|
omap2_gpio_resume_after_idle();
|
||||||
|
|
||||||
|
@@ -247,7 +247,6 @@ static void omap2_enter_mpu_retention(void)
|
||||||
|
}
|
||||||
|
|
||||||
|
if (omap2_pm_debug) {
|
||||||
|
- omap2_pm_dump(only_idle ? 2 : 1, 0, 0);
|
||||||
|
getnstimeofday(&ts_preidle);
|
||||||
|
}
|
||||||
|
|
||||||
|
@@ -259,7 +258,6 @@ static void omap2_enter_mpu_retention(void)
|
||||||
|
getnstimeofday(&ts_postidle);
|
||||||
|
ts_idle = timespec_sub(ts_postidle, ts_preidle);
|
||||||
|
tmp = timespec_to_ns(&ts_idle) * NSEC_PER_USEC;
|
||||||
|
- omap2_pm_dump(only_idle ? 2 : 1, 1, tmp);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
--
|
||||||
|
1.6.6.1
|
||||||
|
|
||||||
+313
@@ -0,0 +1,313 @@
|
|||||||
|
From 2cb229bc89ac3f0b369ffcfb375bb1469f77d98b Mon Sep 17 00:00:00 2001
|
||||||
|
From: Kevin Hilman <khilman@ti.com>
|
||||||
|
Date: Thu, 26 May 2011 15:34:39 -0700
|
||||||
|
Subject: [PATCH 6/7] OMAP3: PM debug: remove register dumping
|
||||||
|
|
||||||
|
Remove OMAP3-specific register dumping feature from PM debug layer.
|
||||||
|
This is removed because:
|
||||||
|
|
||||||
|
- it's ugly
|
||||||
|
- it's OMAP3-specific, and will obviously not scale to OMAP4+
|
||||||
|
- userspace /dev/mem-based tools (like omapconf) can do this much better
|
||||||
|
|
||||||
|
Tested-by: Santosh Shilimkar <santosh.shilimkar@ti.com>
|
||||||
|
Acked-by: Santosh Shilimkar <santosh.shilimkar@ti.com>
|
||||||
|
Acked-by: Jean Pihet <j-pihet@ti.com>
|
||||||
|
Signed-off-by: Kevin Hilman <khilman@ti.com>
|
||||||
|
---
|
||||||
|
arch/arm/mach-omap2/pm-debug.c | 221 ----------------------------------------
|
||||||
|
arch/arm/mach-omap2/pm.h | 4 -
|
||||||
|
2 files changed, 0 insertions(+), 225 deletions(-)
|
||||||
|
|
||||||
|
diff --git a/arch/arm/mach-omap2/pm-debug.c b/arch/arm/mach-omap2/pm-debug.c
|
||||||
|
index a8425d6..3d1cce2 100644
|
||||||
|
--- a/arch/arm/mach-omap2/pm-debug.c
|
||||||
|
+++ b/arch/arm/mach-omap2/pm-debug.c
|
||||||
|
@@ -63,10 +63,6 @@ void omap2_pm_wakeup_on_timer(u32 seconds, u32 milliseconds)
|
||||||
|
#include <linux/debugfs.h>
|
||||||
|
#include <linux/seq_file.h>
|
||||||
|
|
||||||
|
-static void pm_dbg_regset_store(u32 *ptr);
|
||||||
|
-
|
||||||
|
-static struct dentry *pm_dbg_dir;
|
||||||
|
-
|
||||||
|
static int pm_dbg_init_done;
|
||||||
|
|
||||||
|
static int pm_dbg_init(void);
|
||||||
|
@@ -76,160 +72,6 @@ enum {
|
||||||
|
DEBUG_FILE_TIMERS,
|
||||||
|
};
|
||||||
|
|
||||||
|
-struct pm_module_def {
|
||||||
|
- char name[8]; /* Name of the module */
|
||||||
|
- short type; /* CM or PRM */
|
||||||
|
- unsigned short offset;
|
||||||
|
- int low; /* First register address on this module */
|
||||||
|
- int high; /* Last register address on this module */
|
||||||
|
-};
|
||||||
|
-
|
||||||
|
-#define MOD_CM 0
|
||||||
|
-#define MOD_PRM 1
|
||||||
|
-
|
||||||
|
-static const struct pm_module_def *pm_dbg_reg_modules;
|
||||||
|
-static const struct pm_module_def omap3_pm_reg_modules[] = {
|
||||||
|
- { "IVA2", MOD_CM, OMAP3430_IVA2_MOD, 0, 0x4c },
|
||||||
|
- { "OCP", MOD_CM, OCP_MOD, 0, 0x10 },
|
||||||
|
- { "MPU", MOD_CM, MPU_MOD, 4, 0x4c },
|
||||||
|
- { "CORE", MOD_CM, CORE_MOD, 0, 0x4c },
|
||||||
|
- { "SGX", MOD_CM, OMAP3430ES2_SGX_MOD, 0, 0x4c },
|
||||||
|
- { "WKUP", MOD_CM, WKUP_MOD, 0, 0x40 },
|
||||||
|
- { "CCR", MOD_CM, PLL_MOD, 0, 0x70 },
|
||||||
|
- { "DSS", MOD_CM, OMAP3430_DSS_MOD, 0, 0x4c },
|
||||||
|
- { "CAM", MOD_CM, OMAP3430_CAM_MOD, 0, 0x4c },
|
||||||
|
- { "PER", MOD_CM, OMAP3430_PER_MOD, 0, 0x4c },
|
||||||
|
- { "EMU", MOD_CM, OMAP3430_EMU_MOD, 0x40, 0x54 },
|
||||||
|
- { "NEON", MOD_CM, OMAP3430_NEON_MOD, 0x20, 0x48 },
|
||||||
|
- { "USB", MOD_CM, OMAP3430ES2_USBHOST_MOD, 0, 0x4c },
|
||||||
|
-
|
||||||
|
- { "IVA2", MOD_PRM, OMAP3430_IVA2_MOD, 0x50, 0xfc },
|
||||||
|
- { "OCP", MOD_PRM, OCP_MOD, 4, 0x1c },
|
||||||
|
- { "MPU", MOD_PRM, MPU_MOD, 0x58, 0xe8 },
|
||||||
|
- { "CORE", MOD_PRM, CORE_MOD, 0x58, 0xf8 },
|
||||||
|
- { "SGX", MOD_PRM, OMAP3430ES2_SGX_MOD, 0x58, 0xe8 },
|
||||||
|
- { "WKUP", MOD_PRM, WKUP_MOD, 0xa0, 0xb0 },
|
||||||
|
- { "CCR", MOD_PRM, PLL_MOD, 0x40, 0x70 },
|
||||||
|
- { "DSS", MOD_PRM, OMAP3430_DSS_MOD, 0x58, 0xe8 },
|
||||||
|
- { "CAM", MOD_PRM, OMAP3430_CAM_MOD, 0x58, 0xe8 },
|
||||||
|
- { "PER", MOD_PRM, OMAP3430_PER_MOD, 0x58, 0xe8 },
|
||||||
|
- { "EMU", MOD_PRM, OMAP3430_EMU_MOD, 0x58, 0xe4 },
|
||||||
|
- { "GLBL", MOD_PRM, OMAP3430_GR_MOD, 0x20, 0xe4 },
|
||||||
|
- { "NEON", MOD_PRM, OMAP3430_NEON_MOD, 0x58, 0xe8 },
|
||||||
|
- { "USB", MOD_PRM, OMAP3430ES2_USBHOST_MOD, 0x58, 0xe8 },
|
||||||
|
- { "", 0, 0, 0, 0 },
|
||||||
|
-};
|
||||||
|
-
|
||||||
|
-#define PM_DBG_MAX_REG_SETS 4
|
||||||
|
-
|
||||||
|
-static void *pm_dbg_reg_set[PM_DBG_MAX_REG_SETS];
|
||||||
|
-
|
||||||
|
-static int pm_dbg_get_regset_size(void)
|
||||||
|
-{
|
||||||
|
- static int regset_size;
|
||||||
|
-
|
||||||
|
- if (regset_size == 0) {
|
||||||
|
- int i = 0;
|
||||||
|
-
|
||||||
|
- while (pm_dbg_reg_modules[i].name[0] != 0) {
|
||||||
|
- regset_size += pm_dbg_reg_modules[i].high +
|
||||||
|
- 4 - pm_dbg_reg_modules[i].low;
|
||||||
|
- i++;
|
||||||
|
- }
|
||||||
|
- }
|
||||||
|
- return regset_size;
|
||||||
|
-}
|
||||||
|
-
|
||||||
|
-static int pm_dbg_show_regs(struct seq_file *s, void *unused)
|
||||||
|
-{
|
||||||
|
- int i, j;
|
||||||
|
- unsigned long val;
|
||||||
|
- int reg_set = (int)s->private;
|
||||||
|
- u32 *ptr;
|
||||||
|
- void *store = NULL;
|
||||||
|
- int regs;
|
||||||
|
- int linefeed;
|
||||||
|
-
|
||||||
|
- if (reg_set == 0) {
|
||||||
|
- store = kmalloc(pm_dbg_get_regset_size(), GFP_KERNEL);
|
||||||
|
- ptr = store;
|
||||||
|
- pm_dbg_regset_store(ptr);
|
||||||
|
- } else {
|
||||||
|
- ptr = pm_dbg_reg_set[reg_set - 1];
|
||||||
|
- }
|
||||||
|
-
|
||||||
|
- i = 0;
|
||||||
|
-
|
||||||
|
- while (pm_dbg_reg_modules[i].name[0] != 0) {
|
||||||
|
- regs = 0;
|
||||||
|
- linefeed = 0;
|
||||||
|
- if (pm_dbg_reg_modules[i].type == MOD_CM)
|
||||||
|
- seq_printf(s, "MOD: CM_%s (%08x)\n",
|
||||||
|
- pm_dbg_reg_modules[i].name,
|
||||||
|
- (u32)(OMAP3430_CM_BASE +
|
||||||
|
- pm_dbg_reg_modules[i].offset));
|
||||||
|
- else
|
||||||
|
- seq_printf(s, "MOD: PRM_%s (%08x)\n",
|
||||||
|
- pm_dbg_reg_modules[i].name,
|
||||||
|
- (u32)(OMAP3430_PRM_BASE +
|
||||||
|
- pm_dbg_reg_modules[i].offset));
|
||||||
|
-
|
||||||
|
- for (j = pm_dbg_reg_modules[i].low;
|
||||||
|
- j <= pm_dbg_reg_modules[i].high; j += 4) {
|
||||||
|
- val = *(ptr++);
|
||||||
|
- if (val != 0) {
|
||||||
|
- regs++;
|
||||||
|
- if (linefeed) {
|
||||||
|
- seq_printf(s, "\n");
|
||||||
|
- linefeed = 0;
|
||||||
|
- }
|
||||||
|
- seq_printf(s, " %02x => %08lx", j, val);
|
||||||
|
- if (regs % 4 == 0)
|
||||||
|
- linefeed = 1;
|
||||||
|
- }
|
||||||
|
- }
|
||||||
|
- seq_printf(s, "\n");
|
||||||
|
- i++;
|
||||||
|
- }
|
||||||
|
-
|
||||||
|
- if (store != NULL)
|
||||||
|
- kfree(store);
|
||||||
|
-
|
||||||
|
- return 0;
|
||||||
|
-}
|
||||||
|
-
|
||||||
|
-static void pm_dbg_regset_store(u32 *ptr)
|
||||||
|
-{
|
||||||
|
- int i, j;
|
||||||
|
- u32 val;
|
||||||
|
-
|
||||||
|
- i = 0;
|
||||||
|
-
|
||||||
|
- while (pm_dbg_reg_modules[i].name[0] != 0) {
|
||||||
|
- for (j = pm_dbg_reg_modules[i].low;
|
||||||
|
- j <= pm_dbg_reg_modules[i].high; j += 4) {
|
||||||
|
- if (pm_dbg_reg_modules[i].type == MOD_CM)
|
||||||
|
- val = omap2_cm_read_mod_reg(
|
||||||
|
- pm_dbg_reg_modules[i].offset, j);
|
||||||
|
- else
|
||||||
|
- val = omap2_prm_read_mod_reg(
|
||||||
|
- pm_dbg_reg_modules[i].offset, j);
|
||||||
|
- *(ptr++) = val;
|
||||||
|
- }
|
||||||
|
- i++;
|
||||||
|
- }
|
||||||
|
-}
|
||||||
|
-
|
||||||
|
-int pm_dbg_regset_save(int reg_set)
|
||||||
|
-{
|
||||||
|
- if (pm_dbg_reg_set[reg_set-1] == NULL)
|
||||||
|
- return -EINVAL;
|
||||||
|
-
|
||||||
|
- pm_dbg_regset_store(pm_dbg_reg_set[reg_set-1]);
|
||||||
|
-
|
||||||
|
- return 0;
|
||||||
|
-}
|
||||||
|
-
|
||||||
|
static const char pwrdm_state_names[][PWRDM_MAX_PWRSTS] = {
|
||||||
|
"OFF",
|
||||||
|
"RET",
|
||||||
|
@@ -349,11 +191,6 @@ static int pm_dbg_open(struct inode *inode, struct file *file)
|
||||||
|
};
|
||||||
|
}
|
||||||
|
|
||||||
|
-static int pm_dbg_reg_open(struct inode *inode, struct file *file)
|
||||||
|
-{
|
||||||
|
- return single_open(file, pm_dbg_show_regs, inode->i_private);
|
||||||
|
-}
|
||||||
|
-
|
||||||
|
static const struct file_operations debug_fops = {
|
||||||
|
.open = pm_dbg_open,
|
||||||
|
.read = seq_read,
|
||||||
|
@@ -361,40 +198,6 @@ static const struct file_operations debug_fops = {
|
||||||
|
.release = single_release,
|
||||||
|
};
|
||||||
|
|
||||||
|
-static const struct file_operations debug_reg_fops = {
|
||||||
|
- .open = pm_dbg_reg_open,
|
||||||
|
- .read = seq_read,
|
||||||
|
- .llseek = seq_lseek,
|
||||||
|
- .release = single_release,
|
||||||
|
-};
|
||||||
|
-
|
||||||
|
-int pm_dbg_regset_init(int reg_set)
|
||||||
|
-{
|
||||||
|
- char name[2];
|
||||||
|
-
|
||||||
|
- if (!pm_dbg_init_done)
|
||||||
|
- pm_dbg_init();
|
||||||
|
-
|
||||||
|
- if (reg_set < 1 || reg_set > PM_DBG_MAX_REG_SETS ||
|
||||||
|
- pm_dbg_reg_set[reg_set-1] != NULL)
|
||||||
|
- return -EINVAL;
|
||||||
|
-
|
||||||
|
- pm_dbg_reg_set[reg_set-1] =
|
||||||
|
- kmalloc(pm_dbg_get_regset_size(), GFP_KERNEL);
|
||||||
|
-
|
||||||
|
- if (pm_dbg_reg_set[reg_set-1] == NULL)
|
||||||
|
- return -ENOMEM;
|
||||||
|
-
|
||||||
|
- if (pm_dbg_dir != NULL) {
|
||||||
|
- sprintf(name, "%d", reg_set);
|
||||||
|
-
|
||||||
|
- (void) debugfs_create_file(name, S_IRUGO,
|
||||||
|
- pm_dbg_dir, (void *)reg_set, &debug_reg_fops);
|
||||||
|
- }
|
||||||
|
-
|
||||||
|
- return 0;
|
||||||
|
-}
|
||||||
|
-
|
||||||
|
static int pwrdm_suspend_get(void *data, u64 *val)
|
||||||
|
{
|
||||||
|
int ret = -EINVAL;
|
||||||
|
@@ -477,20 +280,11 @@ DEFINE_SIMPLE_ATTRIBUTE(pm_dbg_option_fops, option_get, option_set, "%llu\n");
|
||||||
|
|
||||||
|
static int pm_dbg_init(void)
|
||||||
|
{
|
||||||
|
- int i;
|
||||||
|
struct dentry *d;
|
||||||
|
- char name[2];
|
||||||
|
|
||||||
|
if (pm_dbg_init_done)
|
||||||
|
return 0;
|
||||||
|
|
||||||
|
- if (cpu_is_omap34xx())
|
||||||
|
- pm_dbg_reg_modules = omap3_pm_reg_modules;
|
||||||
|
- else {
|
||||||
|
- printk(KERN_ERR "%s: only OMAP3 supported\n", __func__);
|
||||||
|
- return -ENODEV;
|
||||||
|
- }
|
||||||
|
-
|
||||||
|
d = debugfs_create_dir("pm_debug", NULL);
|
||||||
|
if (IS_ERR(d))
|
||||||
|
return PTR_ERR(d);
|
||||||
|
@@ -502,21 +296,6 @@ static int pm_dbg_init(void)
|
||||||
|
|
||||||
|
pwrdm_for_each(pwrdms_setup, (void *)d);
|
||||||
|
|
||||||
|
- pm_dbg_dir = debugfs_create_dir("registers", d);
|
||||||
|
- if (IS_ERR(pm_dbg_dir))
|
||||||
|
- return PTR_ERR(pm_dbg_dir);
|
||||||
|
-
|
||||||
|
- (void) debugfs_create_file("current", S_IRUGO,
|
||||||
|
- pm_dbg_dir, (void *)0, &debug_reg_fops);
|
||||||
|
-
|
||||||
|
- for (i = 0; i < PM_DBG_MAX_REG_SETS; i++)
|
||||||
|
- if (pm_dbg_reg_set[i] != NULL) {
|
||||||
|
- sprintf(name, "%d", i+1);
|
||||||
|
- (void) debugfs_create_file(name, S_IRUGO,
|
||||||
|
- pm_dbg_dir, (void *)(i+1), &debug_reg_fops);
|
||||||
|
-
|
||||||
|
- }
|
||||||
|
-
|
||||||
|
(void) debugfs_create_file("enable_off_mode", S_IRUGO | S_IWUSR, d,
|
||||||
|
&enable_off_mode, &pm_dbg_option_fops);
|
||||||
|
(void) debugfs_create_file("wakeup_timer_seconds", S_IRUGO | S_IWUSR, d,
|
||||||
|
diff --git a/arch/arm/mach-omap2/pm.h b/arch/arm/mach-omap2/pm.h
|
||||||
|
index acac275..ea58f5d 100644
|
||||||
|
--- a/arch/arm/mach-omap2/pm.h
|
||||||
|
+++ b/arch/arm/mach-omap2/pm.h
|
||||||
|
@@ -74,12 +74,8 @@ extern u32 enable_off_mode;
|
||||||
|
|
||||||
|
#if defined(CONFIG_PM_DEBUG) && defined(CONFIG_DEBUG_FS)
|
||||||
|
extern void pm_dbg_update_time(struct powerdomain *pwrdm, int prev);
|
||||||
|
-extern int pm_dbg_regset_save(int reg_set);
|
||||||
|
-extern int pm_dbg_regset_init(int reg_set);
|
||||||
|
#else
|
||||||
|
#define pm_dbg_update_time(pwrdm, prev) do {} while (0);
|
||||||
|
-#define pm_dbg_regset_save(reg_set) do {} while (0);
|
||||||
|
-#define pm_dbg_regset_init(reg_set) do {} while (0);
|
||||||
|
#endif /* CONFIG_PM_DEBUG */
|
||||||
|
|
||||||
|
extern void omap24xx_idle_loop_suspend(void);
|
||||||
|
--
|
||||||
|
1.6.6.1
|
||||||
|
|
||||||
+37
@@ -0,0 +1,37 @@
|
|||||||
|
From 7472bb7b89bfdc6beef83bb6008219158e072975 Mon Sep 17 00:00:00 2001
|
||||||
|
From: Sanjeev Premi <premi@ti.com>
|
||||||
|
Date: Fri, 17 Jun 2011 02:01:00 +0530
|
||||||
|
Subject: [PATCH 7/7] OMAP2+: PM: fix section mismatch in pm_dbg_init()
|
||||||
|
|
||||||
|
Fix the section mismatch warning:
|
||||||
|
|
||||||
|
WARNING: vmlinux.o(.text+0x21118): Section mismatch
|
||||||
|
in reference from the function pm_dbg_init() to the
|
||||||
|
function .init.text:pwrdms_setup()
|
||||||
|
The function pm_dbg_init() references
|
||||||
|
the function __init pwrdms_setup().
|
||||||
|
This is often because pm_dbg_init lacks a __init
|
||||||
|
annotation or the annotation of pwrdms_setup is wrong.
|
||||||
|
|
||||||
|
Signed-off-by: Sanjeev Premi <premi@ti.com>
|
||||||
|
Signed-off-by: Kevin Hilman <khilman@ti.com>
|
||||||
|
---
|
||||||
|
arch/arm/mach-omap2/pm-debug.c | 2 +-
|
||||||
|
1 files changed, 1 insertions(+), 1 deletions(-)
|
||||||
|
|
||||||
|
diff --git a/arch/arm/mach-omap2/pm-debug.c b/arch/arm/mach-omap2/pm-debug.c
|
||||||
|
index 3d1cce2..3feb475 100644
|
||||||
|
--- a/arch/arm/mach-omap2/pm-debug.c
|
||||||
|
+++ b/arch/arm/mach-omap2/pm-debug.c
|
||||||
|
@@ -278,7 +278,7 @@ static int option_set(void *data, u64 val)
|
||||||
|
|
||||||
|
DEFINE_SIMPLE_ATTRIBUTE(pm_dbg_option_fops, option_get, option_set, "%llu\n");
|
||||||
|
|
||||||
|
-static int pm_dbg_init(void)
|
||||||
|
+static int __init pm_dbg_init(void)
|
||||||
|
{
|
||||||
|
struct dentry *d;
|
||||||
|
|
||||||
|
--
|
||||||
|
1.6.6.1
|
||||||
|
|
||||||
+84
@@ -0,0 +1,84 @@
|
|||||||
|
From e029940bc6c0ff4ad3c8e2b4f31d0a3de78eff32 Mon Sep 17 00:00:00 2001
|
||||||
|
From: Nishanth Menon <nm@ti.com>
|
||||||
|
Date: Wed, 25 May 2011 00:43:26 -0700
|
||||||
|
Subject: [PATCH 01/19] PM: OPP: introduce function to free cpufreq table
|
||||||
|
|
||||||
|
cpufreq table allocated by opp_init_cpufreq_table is better
|
||||||
|
freed by OPP layer itself. This allows future modifications to
|
||||||
|
the table handling to be transparent to the users.
|
||||||
|
|
||||||
|
Signed-off-by: Nishanth Menon <nm@ti.com>
|
||||||
|
Acked-by: Kevin Hilman <khilman@ti.com>
|
||||||
|
---
|
||||||
|
Documentation/power/opp.txt | 2 ++
|
||||||
|
drivers/base/power/opp.c | 17 +++++++++++++++++
|
||||||
|
include/linux/opp.h | 8 ++++++++
|
||||||
|
3 files changed, 27 insertions(+), 0 deletions(-)
|
||||||
|
|
||||||
|
diff --git a/Documentation/power/opp.txt b/Documentation/power/opp.txt
|
||||||
|
index 5ae70a1..3035d00 100644
|
||||||
|
--- a/Documentation/power/opp.txt
|
||||||
|
+++ b/Documentation/power/opp.txt
|
||||||
|
@@ -321,6 +321,8 @@ opp_init_cpufreq_table - cpufreq framework typically is initialized with
|
||||||
|
addition to CONFIG_PM as power management feature is required to
|
||||||
|
dynamically scale voltage and frequency in a system.
|
||||||
|
|
||||||
|
+opp_free_cpufreq_table - Free up the table allocated by opp_init_cpufreq_table
|
||||||
|
+
|
||||||
|
7. Data Structures
|
||||||
|
==================
|
||||||
|
Typically an SoC contains multiple voltage domains which are variable. Each
|
||||||
|
diff --git a/drivers/base/power/opp.c b/drivers/base/power/opp.c
|
||||||
|
index 56a6899..5cc1232 100644
|
||||||
|
--- a/drivers/base/power/opp.c
|
||||||
|
+++ b/drivers/base/power/opp.c
|
||||||
|
@@ -625,4 +625,21 @@ int opp_init_cpufreq_table(struct device *dev,
|
||||||
|
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
+
|
||||||
|
+/**
|
||||||
|
+ * opp_free_cpufreq_table() - free the cpufreq table
|
||||||
|
+ * @dev: device for which we do this operation
|
||||||
|
+ * @table: table to free
|
||||||
|
+ *
|
||||||
|
+ * Free up the table allocated by opp_init_cpufreq_table
|
||||||
|
+ */
|
||||||
|
+void opp_free_cpufreq_table(struct device *dev,
|
||||||
|
+ struct cpufreq_frequency_table **table)
|
||||||
|
+{
|
||||||
|
+ if (!table)
|
||||||
|
+ return;
|
||||||
|
+
|
||||||
|
+ kfree(*table);
|
||||||
|
+ *table = NULL;
|
||||||
|
+}
|
||||||
|
#endif /* CONFIG_CPU_FREQ */
|
||||||
|
diff --git a/include/linux/opp.h b/include/linux/opp.h
|
||||||
|
index 5449945..7020e97 100644
|
||||||
|
--- a/include/linux/opp.h
|
||||||
|
+++ b/include/linux/opp.h
|
||||||
|
@@ -94,12 +94,20 @@ static inline int opp_disable(struct device *dev, unsigned long freq)
|
||||||
|
#if defined(CONFIG_CPU_FREQ) && defined(CONFIG_PM_OPP)
|
||||||
|
int opp_init_cpufreq_table(struct device *dev,
|
||||||
|
struct cpufreq_frequency_table **table);
|
||||||
|
+void opp_free_cpufreq_table(struct device *dev,
|
||||||
|
+ struct cpufreq_frequency_table **table);
|
||||||
|
#else
|
||||||
|
static inline int opp_init_cpufreq_table(struct device *dev,
|
||||||
|
struct cpufreq_frequency_table **table)
|
||||||
|
{
|
||||||
|
return -EINVAL;
|
||||||
|
}
|
||||||
|
+
|
||||||
|
+static inline
|
||||||
|
+void opp_free_cpufreq_table(struct device *dev,
|
||||||
|
+ struct cpufreq_frequency_table **table)
|
||||||
|
+{
|
||||||
|
+}
|
||||||
|
#endif /* CONFIG_CPU_FREQ */
|
||||||
|
|
||||||
|
#endif /* __LINUX_OPP_H__ */
|
||||||
|
--
|
||||||
|
1.6.6.1
|
||||||
|
|
||||||
+28
@@ -0,0 +1,28 @@
|
|||||||
|
From 895fc8961297666b46b4cd3f8c01010051d2164e Mon Sep 17 00:00:00 2001
|
||||||
|
From: Peter 'p2' De Schrijver <peter.de-schrijver@nokia.com>
|
||||||
|
Date: Wed, 11 Aug 2010 17:02:43 -0700
|
||||||
|
Subject: [PATCH 02/19] OMAP: CPUfreq: ensure driver initializes after cpufreq framework and governors
|
||||||
|
|
||||||
|
Signed-off-by: Peter 'p2' De Schrijver <peter.de-schrijver@nokia.com>
|
||||||
|
Signed-off-by: Kevin Hilman <khilman@deeprootsystems.com>
|
||||||
|
Signed-off-by: Koen Kooi <koen@dominion.thruhere.net>
|
||||||
|
---
|
||||||
|
arch/arm/plat-omap/cpu-omap.c | 2 +-
|
||||||
|
1 files changed, 1 insertions(+), 1 deletions(-)
|
||||||
|
|
||||||
|
diff --git a/arch/arm/plat-omap/cpu-omap.c b/arch/arm/plat-omap/cpu-omap.c
|
||||||
|
index da4f68d..cd09d4b 100644
|
||||||
|
--- a/arch/arm/plat-omap/cpu-omap.c
|
||||||
|
+++ b/arch/arm/plat-omap/cpu-omap.c
|
||||||
|
@@ -160,7 +160,7 @@ static int __init omap_cpufreq_init(void)
|
||||||
|
return cpufreq_register_driver(&omap_driver);
|
||||||
|
}
|
||||||
|
|
||||||
|
-arch_initcall(omap_cpufreq_init);
|
||||||
|
+late_initcall(omap_cpufreq_init);
|
||||||
|
|
||||||
|
/*
|
||||||
|
* if ever we want to remove this, upon cleanup call:
|
||||||
|
--
|
||||||
|
1.6.6.1
|
||||||
|
|
||||||
+32
@@ -0,0 +1,32 @@
|
|||||||
|
From 62bd1b0f18ee6c6bad1573c2f06e74b0abc418a3 Mon Sep 17 00:00:00 2001
|
||||||
|
From: Kevin Hilman <khilman@deeprootsystems.com>
|
||||||
|
Date: Wed, 11 Aug 2010 17:05:38 -0700
|
||||||
|
Subject: [PATCH 03/19] OMAP: CPUfreq: ensure policy is fully initialized
|
||||||
|
|
||||||
|
Ensure policy min/max/cur values are initialized when OMAP
|
||||||
|
CPUfreq driver starts.
|
||||||
|
|
||||||
|
Signed-off-by: Kevin Hilman <khilman@deeprootsystems.com>
|
||||||
|
Signed-off-by: Koen Kooi <koen@dominion.thruhere.net>
|
||||||
|
---
|
||||||
|
arch/arm/plat-omap/cpu-omap.c | 4 ++++
|
||||||
|
1 files changed, 4 insertions(+), 0 deletions(-)
|
||||||
|
|
||||||
|
diff --git a/arch/arm/plat-omap/cpu-omap.c b/arch/arm/plat-omap/cpu-omap.c
|
||||||
|
index cd09d4b..1b36664 100644
|
||||||
|
--- a/arch/arm/plat-omap/cpu-omap.c
|
||||||
|
+++ b/arch/arm/plat-omap/cpu-omap.c
|
||||||
|
@@ -126,6 +126,10 @@ static int __cpuinit omap_cpu_init(struct cpufreq_policy *policy)
|
||||||
|
VERY_HI_RATE) / 1000;
|
||||||
|
}
|
||||||
|
|
||||||
|
+ policy->min = policy->cpuinfo.min_freq;
|
||||||
|
+ policy->max = policy->cpuinfo.max_freq;
|
||||||
|
+ policy->cur = omap_getspeed(0);
|
||||||
|
+
|
||||||
|
/* FIXME: what's the actual transition time? */
|
||||||
|
policy->cpuinfo.transition_latency = 300 * 1000;
|
||||||
|
|
||||||
|
--
|
||||||
|
1.6.6.1
|
||||||
|
|
||||||
+264
@@ -0,0 +1,264 @@
|
|||||||
|
From afa9b062a33a9d9d2d9077cc519e1375b8338e39 Mon Sep 17 00:00:00 2001
|
||||||
|
From: Rajendra Nayak <rnayak@ti.com>
|
||||||
|
Date: Mon, 10 Nov 2008 17:00:25 +0530
|
||||||
|
Subject: [PATCH 04/19] OMAP3 PM: CPUFreq driver for OMAP3
|
||||||
|
|
||||||
|
CPUFreq driver for OMAP3
|
||||||
|
|
||||||
|
With additional fixes and cleanups from Tero Kristo:
|
||||||
|
- Fix rate calculation bug in omap3_select_table_rate
|
||||||
|
- Refreshed DVFS VDD1 control against latest clock fw
|
||||||
|
|
||||||
|
Signed-off-by: Tero Kristo <tero.kristo@nokia.com>
|
||||||
|
Signed-off-by: Rajendra Nayak <rnayak@ti.com>
|
||||||
|
|
||||||
|
OMAP3: PM: CPUFreq: Fix omap_getspeed.
|
||||||
|
|
||||||
|
Signed-off-by: Peter 'p2' De Schrijver <peter.de-schrijver@nokia.com>
|
||||||
|
|
||||||
|
Make sure omap cpufreq driver initializes after cpufreq framework and governors
|
||||||
|
|
||||||
|
Signed-off-by: Peter 'p2' De Schrijver <peter.de-schrijver@nokia.com>
|
||||||
|
|
||||||
|
merge: CPUFreq: remove obsolete funcs
|
||||||
|
|
||||||
|
OMAP3 clock: Update cpufreq driver
|
||||||
|
|
||||||
|
This patch removes all refrences to virtual clock
|
||||||
|
nodes in CPUFreq driver.
|
||||||
|
|
||||||
|
Signed-off-by: Rajendra Nayak <rnayak@ti.com>
|
||||||
|
Signed-off-by: Tero Kristo <tero.kristo@nokia.com>
|
||||||
|
Signed-off-by: Jean Pihet <jpihet@mvista.com>
|
||||||
|
|
||||||
|
PM: Prevent direct cpufreq scaling during initialization
|
||||||
|
|
||||||
|
It is seen that the OMAP specific cpufreq initialization code tries to
|
||||||
|
scale the MPU frequency to the highest possible without taking care of
|
||||||
|
the voltage level. On power on reset the power IC does not provide the
|
||||||
|
necessary voltage for the highest available MPU frequency (that would
|
||||||
|
satisfy all Si families). This potentially is an window of opportunity
|
||||||
|
for things to go wrong.
|
||||||
|
|
||||||
|
Signed-off-by: Romit Dasgupta <romit@ti.com>
|
||||||
|
Signed-off-by: Kevin Hilman <khilman@deeprootsystems.com>
|
||||||
|
|
||||||
|
OMAP3: PM: enable 600MHz (overdrive) OPP
|
||||||
|
|
||||||
|
Signed-off-by: Kevin Hilman <khilman@deeprootsystems.com>
|
||||||
|
|
||||||
|
omap3: introduce cpufreq
|
||||||
|
|
||||||
|
OMAP OPP layer functions now have dependencies of CONFIG_CPU_FREQ only.
|
||||||
|
|
||||||
|
With this patch, omap opp layer now has its compilation flags
|
||||||
|
bound to CONFIG_CPU_FREQ. Also its code has been removed from pm34xx.c.
|
||||||
|
|
||||||
|
A new file has been created to contain cpu freq code related to
|
||||||
|
OMAP3: cpufreq34xx.c
|
||||||
|
|
||||||
|
OMAP34xx and OMAP36xx family OPPs are made available
|
||||||
|
|
||||||
|
Signed-off-by: Eduardo Valentin <eduardo.valentin@nokia.com>
|
||||||
|
Signed-off-by: Paul Walmsley <paul@pwsan.com>
|
||||||
|
Signed-off-by: Nishanth Menon <nm@ti.com>
|
||||||
|
Signed-off-by: Vishwanath BS <vishwanath.bs@ti.com>
|
||||||
|
Signed-off-by: Kevin Hilman <khilman@deeprootsystems.com>
|
||||||
|
Signed-off-by: Romit Dasgupta <romit@ti.com>
|
||||||
|
Signed-off-by: Rajendra Nayak <rnayak@ti.com>
|
||||||
|
|
||||||
|
omap3: cpufreq: allow default opp table init
|
||||||
|
|
||||||
|
For board files which choose to override the defaults, the existing
|
||||||
|
mechanism will work, for boards that would like to work with defaults,
|
||||||
|
allow init_common_hw to call init_opp_table to initialize if not
|
||||||
|
already initialized. this will allow all omap boards which have opp
|
||||||
|
tables predefined for a silicon to use the same.
|
||||||
|
|
||||||
|
Originally reported for overo:
|
||||||
|
http://marc.info/?t=127265269400004&r=1&w=2
|
||||||
|
|
||||||
|
Signed-off-by: Nishanth Menon <nm@ti.com>
|
||||||
|
Reported-by: Peter Tseng <tsenpet09@gmail.com>
|
||||||
|
Cc: Cliff Brake <cliff.brake@gmail.com>
|
||||||
|
Cc: Kevin Hilman <khilman@deeprootsystems.com>
|
||||||
|
|
||||||
|
OMAP2: update OPP data to be device based
|
||||||
|
|
||||||
|
Cc: Nishanth Menon <nm@ti.com>
|
||||||
|
Signed-off-by: Kevin Hilman <khilman@deeprootsystems.com>
|
||||||
|
|
||||||
|
OMAP3: CPUfreq: update to device-based OPP API
|
||||||
|
|
||||||
|
Update usage of OPP API to use new device-based API. This requires
|
||||||
|
getting the 'struct device' for the MPU and using that with the OPP
|
||||||
|
API.
|
||||||
|
|
||||||
|
Signed-off-by: Kevin Hilman <khilman@deeprootsystems.com>
|
||||||
|
|
||||||
|
omap3: opp: make independent of cpufreq
|
||||||
|
|
||||||
|
Make opp3xx data which is registered with the opp layer
|
||||||
|
dependent purely on CONFIG_PM as opp layer and pm.c users
|
||||||
|
are CONFIG_PM dependent not cpufreq dependent.
|
||||||
|
so we rename the data definition to opp3xxx_data.c (inline with what
|
||||||
|
we have for omap2), also move the build definition to be under
|
||||||
|
the existing CONFIG_PM build instead of CPUFREQ.
|
||||||
|
|
||||||
|
Cc: Eduardo Valentin <eduardo.valentin@nokia.com>
|
||||||
|
Cc: Kevin Hilman <khilman@deeprootsystems.com>
|
||||||
|
Cc: Paul Walmsley <paul@pwsan.com>
|
||||||
|
Cc: Rajendra Nayak <rnayak@ti.com>
|
||||||
|
Cc: Sanjeev Premi <premi@ti.com>
|
||||||
|
Cc: Thara Gopinath <thara@ti.com>
|
||||||
|
Cc: Tony Lindgren <tony@atomide.com>
|
||||||
|
|
||||||
|
Signed-off-by: Nishanth Menon <nm@ti.com>
|
||||||
|
Signed-off-by: Koen Kooi <koen@dominion.thruhere.net>
|
||||||
|
---
|
||||||
|
arch/arm/mach-omap2/clock.h | 14 +++++++++++++-
|
||||||
|
arch/arm/mach-omap2/clock34xx.c | 2 ++
|
||||||
|
arch/arm/plat-omap/cpu-omap.c | 34 +++++++++++++++++++++++++++++++---
|
||||||
|
3 files changed, 46 insertions(+), 4 deletions(-)
|
||||||
|
|
||||||
|
diff --git a/arch/arm/mach-omap2/clock.h b/arch/arm/mach-omap2/clock.h
|
||||||
|
index e10ff2b..0a07e50 100644
|
||||||
|
--- a/arch/arm/mach-omap2/clock.h
|
||||||
|
+++ b/arch/arm/mach-omap2/clock.h
|
||||||
|
@@ -141,7 +141,9 @@ extern const struct clksel_rate gpt_sys_rates[];
|
||||||
|
extern const struct clksel_rate gfx_l3_rates[];
|
||||||
|
extern const struct clksel_rate dsp_ick_rates[];
|
||||||
|
|
||||||
|
-#if defined(CONFIG_ARCH_OMAP2) && defined(CONFIG_CPU_FREQ)
|
||||||
|
+#ifdef CONFIG_CPU_FREQ
|
||||||
|
+
|
||||||
|
+#ifdef CONFIG_ARCH_OMAP2
|
||||||
|
extern void omap2_clk_init_cpufreq_table(struct cpufreq_frequency_table **table);
|
||||||
|
extern void omap2_clk_exit_cpufreq_table(struct cpufreq_frequency_table **table);
|
||||||
|
#else
|
||||||
|
@@ -149,6 +151,16 @@ extern void omap2_clk_exit_cpufreq_table(struct cpufreq_frequency_table **table)
|
||||||
|
#define omap2_clk_exit_cpufreq_table 0
|
||||||
|
#endif
|
||||||
|
|
||||||
|
+#ifdef CONFIG_ARCH_OMAP3
|
||||||
|
+extern void omap3_clk_init_cpufreq_table(struct cpufreq_frequency_table **table);
|
||||||
|
+extern void omap3_clk_exit_cpufreq_table(struct cpufreq_frequency_table **table);
|
||||||
|
+#else
|
||||||
|
+#define omap3_clk_init_cpufreq_table 0
|
||||||
|
+#define omap3_clk_exit_cpufreq_table 0
|
||||||
|
+#endif
|
||||||
|
+
|
||||||
|
+#endif /* CONFIG_CPU_FREQ */
|
||||||
|
+
|
||||||
|
extern const struct clkops clkops_omap2_iclk_dflt_wait;
|
||||||
|
extern const struct clkops clkops_omap2_iclk_dflt;
|
||||||
|
extern const struct clkops clkops_omap2_iclk_idle_only;
|
||||||
|
diff --git a/arch/arm/mach-omap2/clock34xx.c b/arch/arm/mach-omap2/clock34xx.c
|
||||||
|
index 1fc96b9..119e135 100644
|
||||||
|
--- a/arch/arm/mach-omap2/clock34xx.c
|
||||||
|
+++ b/arch/arm/mach-omap2/clock34xx.c
|
||||||
|
@@ -20,6 +20,8 @@
|
||||||
|
#include <linux/kernel.h>
|
||||||
|
#include <linux/clk.h>
|
||||||
|
#include <linux/io.h>
|
||||||
|
+#include <linux/err.h>
|
||||||
|
+#include <linux/cpufreq.h>
|
||||||
|
|
||||||
|
#include <plat/clock.h>
|
||||||
|
|
||||||
|
diff --git a/arch/arm/plat-omap/cpu-omap.c b/arch/arm/plat-omap/cpu-omap.c
|
||||||
|
index 1b36664..f0f9430 100644
|
||||||
|
--- a/arch/arm/plat-omap/cpu-omap.c
|
||||||
|
+++ b/arch/arm/plat-omap/cpu-omap.c
|
||||||
|
@@ -8,6 +8,10 @@
|
||||||
|
*
|
||||||
|
* Based on cpu-sa1110.c, Copyright (C) 2001 Russell King
|
||||||
|
*
|
||||||
|
+ * Copyright (C) 2007-2008 Texas Instruments, Inc.
|
||||||
|
+ * Updated to support OMAP3
|
||||||
|
+ * Rajendra Nayak <rnayak@ti.com>
|
||||||
|
+ *
|
||||||
|
* 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.
|
||||||
|
@@ -26,12 +30,19 @@
|
||||||
|
#include <plat/clock.h>
|
||||||
|
#include <asm/system.h>
|
||||||
|
|
||||||
|
+#if defined(CONFIG_ARCH_OMAP3) && !defined(CONFIG_OMAP_PM_NONE)
|
||||||
|
+#include <plat/omap-pm.h>
|
||||||
|
+#include <plat/opp.h>
|
||||||
|
+#endif
|
||||||
|
+
|
||||||
|
#define VERY_HI_RATE 900000000
|
||||||
|
|
||||||
|
static struct cpufreq_frequency_table *freq_table;
|
||||||
|
|
||||||
|
#ifdef CONFIG_ARCH_OMAP1
|
||||||
|
#define MPU_CLK "mpu"
|
||||||
|
+#elif CONFIG_ARCH_OMAP3
|
||||||
|
+#define MPU_CLK "arm_fck"
|
||||||
|
#else
|
||||||
|
#define MPU_CLK "virt_prcm_set"
|
||||||
|
#endif
|
||||||
|
@@ -73,7 +84,13 @@ static int omap_target(struct cpufreq_policy *policy,
|
||||||
|
unsigned int target_freq,
|
||||||
|
unsigned int relation)
|
||||||
|
{
|
||||||
|
+#ifdef CONFIG_ARCH_OMAP1
|
||||||
|
struct cpufreq_freqs freqs;
|
||||||
|
+#endif
|
||||||
|
+#if defined(CONFIG_ARCH_OMAP3) && !defined(CONFIG_OMAP_PM_NONE)
|
||||||
|
+ unsigned long freq;
|
||||||
|
+ struct device *mpu_dev = omap2_get_mpuss_device();
|
||||||
|
+#endif
|
||||||
|
int ret = 0;
|
||||||
|
|
||||||
|
/* Ensure desired rate is within allowed range. Some govenors
|
||||||
|
@@ -83,13 +100,13 @@ static int omap_target(struct cpufreq_policy *policy,
|
||||||
|
if (target_freq > policy->max)
|
||||||
|
target_freq = policy->max;
|
||||||
|
|
||||||
|
+#ifdef CONFIG_ARCH_OMAP1
|
||||||
|
freqs.old = omap_getspeed(0);
|
||||||
|
freqs.new = clk_round_rate(mpu_clk, target_freq * 1000) / 1000;
|
||||||
|
freqs.cpu = 0;
|
||||||
|
|
||||||
|
if (freqs.old == freqs.new)
|
||||||
|
return ret;
|
||||||
|
-
|
||||||
|
cpufreq_notify_transition(&freqs, CPUFREQ_PRECHANGE);
|
||||||
|
#ifdef CONFIG_CPU_FREQ_DEBUG
|
||||||
|
printk(KERN_DEBUG "cpufreq-omap: transition: %u --> %u\n",
|
||||||
|
@@ -97,7 +114,11 @@ static int omap_target(struct cpufreq_policy *policy,
|
||||||
|
#endif
|
||||||
|
ret = clk_set_rate(mpu_clk, freqs.new * 1000);
|
||||||
|
cpufreq_notify_transition(&freqs, CPUFREQ_POSTCHANGE);
|
||||||
|
-
|
||||||
|
+#elif defined(CONFIG_ARCH_OMAP3) && !defined(CONFIG_OMAP_PM_NONE)
|
||||||
|
+ freq = target_freq * 1000;
|
||||||
|
+ if (opp_find_freq_ceil(mpu_dev, &freq))
|
||||||
|
+ omap_pm_cpu_set_freq(freq);
|
||||||
|
+#endif
|
||||||
|
return ret;
|
||||||
|
}
|
||||||
|
|
||||||
|
@@ -114,7 +135,14 @@ static int __cpuinit omap_cpu_init(struct cpufreq_policy *policy)
|
||||||
|
|
||||||
|
policy->cur = policy->min = policy->max = omap_getspeed(0);
|
||||||
|
|
||||||
|
- clk_init_cpufreq_table(&freq_table);
|
||||||
|
+ if (!cpu_is_omap34xx()) {
|
||||||
|
+ clk_init_cpufreq_table(&freq_table);
|
||||||
|
+ } else {
|
||||||
|
+ struct device *mpu_dev = omap2_get_mpuss_device();
|
||||||
|
+
|
||||||
|
+ opp_init_cpufreq_table(mpu_dev, &freq_table);
|
||||||
|
+ }
|
||||||
|
+
|
||||||
|
if (freq_table) {
|
||||||
|
result = cpufreq_frequency_table_cpuinfo(policy, freq_table);
|
||||||
|
if (!result)
|
||||||
|
--
|
||||||
|
1.6.6.1
|
||||||
|
|
||||||
+33
@@ -0,0 +1,33 @@
|
|||||||
|
From c93327d36f0dc4ea6693fcae54c561eb8bafdd1e Mon Sep 17 00:00:00 2001
|
||||||
|
From: Silesh C V <silesh@ti.com>
|
||||||
|
Date: Wed, 29 Sep 2010 14:52:54 +0530
|
||||||
|
Subject: [PATCH 05/19] OMAP: PM: CPUFREQ: Fix conditional compilation
|
||||||
|
|
||||||
|
Fix conditional compilation. A conditional expresiion
|
||||||
|
should follow "#elif", in this case #elif clause should
|
||||||
|
check whether CONFIG_ARCH_OMAP3 is defined or not
|
||||||
|
(ie. defined(CONFIG_ARCH_OMAP3)) rather than checking for
|
||||||
|
the value of the macro.
|
||||||
|
|
||||||
|
Signed-off-by: Silesh C V <silesh@ti.com>
|
||||||
|
Signed-off-by: Koen Kooi <koen@dominion.thruhere.net>
|
||||||
|
---
|
||||||
|
arch/arm/plat-omap/cpu-omap.c | 2 +-
|
||||||
|
1 files changed, 1 insertions(+), 1 deletions(-)
|
||||||
|
|
||||||
|
diff --git a/arch/arm/plat-omap/cpu-omap.c b/arch/arm/plat-omap/cpu-omap.c
|
||||||
|
index f0f9430..c3ac065 100644
|
||||||
|
--- a/arch/arm/plat-omap/cpu-omap.c
|
||||||
|
+++ b/arch/arm/plat-omap/cpu-omap.c
|
||||||
|
@@ -41,7 +41,7 @@ static struct cpufreq_frequency_table *freq_table;
|
||||||
|
|
||||||
|
#ifdef CONFIG_ARCH_OMAP1
|
||||||
|
#define MPU_CLK "mpu"
|
||||||
|
-#elif CONFIG_ARCH_OMAP3
|
||||||
|
+#elif defined(CONFIG_ARCH_OMAP3)
|
||||||
|
#define MPU_CLK "arm_fck"
|
||||||
|
#else
|
||||||
|
#define MPU_CLK "virt_prcm_set"
|
||||||
|
--
|
||||||
|
1.6.6.1
|
||||||
|
|
||||||
+34
@@ -0,0 +1,34 @@
|
|||||||
|
From b8246b5d5edc98155628ba88510bc7e67baf7acf Mon Sep 17 00:00:00 2001
|
||||||
|
From: Kevin Hilman <khilman@deeprootsystems.com>
|
||||||
|
Date: Tue, 16 Nov 2010 11:48:41 -0800
|
||||||
|
Subject: [PATCH 06/19] cpufreq: fixup after new OPP layer merged
|
||||||
|
|
||||||
|
Signed-off-by: Koen Kooi <koen@dominion.thruhere.net>
|
||||||
|
---
|
||||||
|
arch/arm/plat-omap/cpu-omap.c | 3 ++-
|
||||||
|
1 files changed, 2 insertions(+), 1 deletions(-)
|
||||||
|
|
||||||
|
diff --git a/arch/arm/plat-omap/cpu-omap.c b/arch/arm/plat-omap/cpu-omap.c
|
||||||
|
index c3ac065..9cd2709 100644
|
||||||
|
--- a/arch/arm/plat-omap/cpu-omap.c
|
||||||
|
+++ b/arch/arm/plat-omap/cpu-omap.c
|
||||||
|
@@ -25,6 +25,7 @@
|
||||||
|
#include <linux/err.h>
|
||||||
|
#include <linux/clk.h>
|
||||||
|
#include <linux/io.h>
|
||||||
|
+#include <linux/opp.h>
|
||||||
|
|
||||||
|
#include <mach/hardware.h>
|
||||||
|
#include <plat/clock.h>
|
||||||
|
@@ -32,7 +33,7 @@
|
||||||
|
|
||||||
|
#if defined(CONFIG_ARCH_OMAP3) && !defined(CONFIG_OMAP_PM_NONE)
|
||||||
|
#include <plat/omap-pm.h>
|
||||||
|
-#include <plat/opp.h>
|
||||||
|
+#include <plat/common.h>
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#define VERY_HI_RATE 900000000
|
||||||
|
--
|
||||||
|
1.6.6.1
|
||||||
|
|
||||||
+673
@@ -0,0 +1,673 @@
|
|||||||
|
From 9f9061d3e98aa6db7d5c3feabd5a2d93eb3cb737 Mon Sep 17 00:00:00 2001
|
||||||
|
From: Santosh Shilimkar <santosh.shilimkar@ti.com>
|
||||||
|
Date: Mon, 14 Mar 2011 17:08:48 +0530
|
||||||
|
Subject: [PATCH 07/19] OMAP: cpufreq: Split OMAP1 and OMAP2PLUS CPUfreq drivers.
|
||||||
|
|
||||||
|
This patch is an attempt to cleanup the #ifdeferry in the
|
||||||
|
omap CPUfreq drivers.
|
||||||
|
|
||||||
|
The split betwenn OMAP1 and OMAP2PLUS is logical because
|
||||||
|
- OMAP1 doesn't support opp layer.
|
||||||
|
- OMAP1 build is seperate from omap2plus.
|
||||||
|
|
||||||
|
Includes minor header/copyright updates reported by Todd Poynor.
|
||||||
|
|
||||||
|
Signed-off-by: Santosh Shilimkar <santosh.shilimkar@ti.com>
|
||||||
|
Cc: Kevin Hilman <khilman@ti.com>
|
||||||
|
Cc: Vishwanath BS <vishwanath.bs@ti.com>
|
||||||
|
Cc: Todd Poynor <toddpoynor@google.com>
|
||||||
|
Cc: Nishanth Menon <nm@ti.com>
|
||||||
|
Signed-off-by: Koen Kooi <koen@dominion.thruhere.net>
|
||||||
|
---
|
||||||
|
arch/arm/mach-omap1/Makefile | 3 +
|
||||||
|
arch/arm/mach-omap1/omap1-cpufreq.c | 175 ++++++++++++++++++++++++++
|
||||||
|
arch/arm/mach-omap2/Makefile | 3 +
|
||||||
|
arch/arm/mach-omap2/omap2plus-cpufreq.c | 201 ++++++++++++++++++++++++++++++
|
||||||
|
arch/arm/plat-omap/Makefile | 1 -
|
||||||
|
arch/arm/plat-omap/cpu-omap.c | 204 -------------------------------
|
||||||
|
6 files changed, 382 insertions(+), 205 deletions(-)
|
||||||
|
create mode 100644 arch/arm/mach-omap1/omap1-cpufreq.c
|
||||||
|
create mode 100644 arch/arm/mach-omap2/omap2plus-cpufreq.c
|
||||||
|
delete mode 100644 arch/arm/plat-omap/cpu-omap.c
|
||||||
|
|
||||||
|
diff --git a/arch/arm/mach-omap1/Makefile b/arch/arm/mach-omap1/Makefile
|
||||||
|
index 5b114d1..9600410 100644
|
||||||
|
--- a/arch/arm/mach-omap1/Makefile
|
||||||
|
+++ b/arch/arm/mach-omap1/Makefile
|
||||||
|
@@ -10,6 +10,9 @@ obj-$(CONFIG_OMAP_MCBSP) += mcbsp.o
|
||||||
|
|
||||||
|
obj-$(CONFIG_OMAP_32K_TIMER) += timer32k.o
|
||||||
|
|
||||||
|
+# CPUFREQ driver
|
||||||
|
+obj-$(CONFIG_CPU_FREQ) += omap1-cpufreq.o
|
||||||
|
+
|
||||||
|
# Power Management
|
||||||
|
obj-$(CONFIG_PM) += pm.o sleep.o
|
||||||
|
|
||||||
|
diff --git a/arch/arm/mach-omap1/omap1-cpufreq.c b/arch/arm/mach-omap1/omap1-cpufreq.c
|
||||||
|
new file mode 100644
|
||||||
|
index 0000000..7c5216e
|
||||||
|
--- /dev/null
|
||||||
|
+++ b/arch/arm/mach-omap1/omap1-cpufreq.c
|
||||||
|
@@ -0,0 +1,175 @@
|
||||||
|
+/*
|
||||||
|
+ * OMAP1 cpufreq driver
|
||||||
|
+ *
|
||||||
|
+ * CPU frequency scaling for OMAP
|
||||||
|
+ *
|
||||||
|
+ * Copyright (C) 2005 Nokia Corporation
|
||||||
|
+ * Written by Tony Lindgren <tony@atomide.com>
|
||||||
|
+ *
|
||||||
|
+ * Based on cpu-sa1110.c, Copyright (C) 2001 Russell King
|
||||||
|
+ *
|
||||||
|
+ * Copyright (C) 2007-2008 Texas Instruments, Inc.
|
||||||
|
+ * Rajendra Nayak <rnayak@ti.com>
|
||||||
|
+ *
|
||||||
|
+ * 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 <linux/types.h>
|
||||||
|
+#include <linux/kernel.h>
|
||||||
|
+#include <linux/sched.h>
|
||||||
|
+#include <linux/cpufreq.h>
|
||||||
|
+#include <linux/delay.h>
|
||||||
|
+#include <linux/init.h>
|
||||||
|
+#include <linux/err.h>
|
||||||
|
+#include <linux/clk.h>
|
||||||
|
+#include <linux/io.h>
|
||||||
|
+#include <linux/opp.h>
|
||||||
|
+
|
||||||
|
+#include <asm/system.h>
|
||||||
|
+
|
||||||
|
+#include <plat/clock.h>
|
||||||
|
+#include <plat/omap-pm.h>
|
||||||
|
+
|
||||||
|
+#include <mach/hardware.h>
|
||||||
|
+
|
||||||
|
+#define VERY_HI_RATE 900000000
|
||||||
|
+
|
||||||
|
+static struct cpufreq_frequency_table *freq_table;
|
||||||
|
+static struct clk *mpu_clk;
|
||||||
|
+
|
||||||
|
+static int omap_verify_speed(struct cpufreq_policy *policy)
|
||||||
|
+{
|
||||||
|
+ if (freq_table)
|
||||||
|
+ return cpufreq_frequency_table_verify(policy, freq_table);
|
||||||
|
+
|
||||||
|
+ if (policy->cpu)
|
||||||
|
+ return -EINVAL;
|
||||||
|
+
|
||||||
|
+ cpufreq_verify_within_limits(policy, policy->cpuinfo.min_freq,
|
||||||
|
+ policy->cpuinfo.max_freq);
|
||||||
|
+
|
||||||
|
+ policy->min = clk_round_rate(mpu_clk, policy->min * 1000) / 1000;
|
||||||
|
+ policy->max = clk_round_rate(mpu_clk, policy->max * 1000) / 1000;
|
||||||
|
+ cpufreq_verify_within_limits(policy, policy->cpuinfo.min_freq,
|
||||||
|
+ policy->cpuinfo.max_freq);
|
||||||
|
+ return 0;
|
||||||
|
+}
|
||||||
|
+
|
||||||
|
+static unsigned int omap_getspeed(unsigned int cpu)
|
||||||
|
+{
|
||||||
|
+ unsigned long rate;
|
||||||
|
+
|
||||||
|
+ if (cpu)
|
||||||
|
+ return 0;
|
||||||
|
+
|
||||||
|
+ rate = clk_get_rate(mpu_clk) / 1000;
|
||||||
|
+ return rate;
|
||||||
|
+}
|
||||||
|
+
|
||||||
|
+static int omap_target(struct cpufreq_policy *policy,
|
||||||
|
+ unsigned int target_freq,
|
||||||
|
+ unsigned int relation)
|
||||||
|
+{
|
||||||
|
+ struct cpufreq_freqs freqs;
|
||||||
|
+ int ret = 0;
|
||||||
|
+
|
||||||
|
+ /* Ensure desired rate is within allowed range. Some govenors
|
||||||
|
+ * (ondemand) will just pass target_freq=0 to get the minimum. */
|
||||||
|
+ if (target_freq < policy->min)
|
||||||
|
+ target_freq = policy->min;
|
||||||
|
+ if (target_freq > policy->max)
|
||||||
|
+ target_freq = policy->max;
|
||||||
|
+
|
||||||
|
+ freqs.old = omap_getspeed(0);
|
||||||
|
+ freqs.new = clk_round_rate(mpu_clk, target_freq * 1000) / 1000;
|
||||||
|
+ freqs.cpu = 0;
|
||||||
|
+
|
||||||
|
+ if (freqs.old == freqs.new)
|
||||||
|
+ return ret;
|
||||||
|
+
|
||||||
|
+ cpufreq_notify_transition(&freqs, CPUFREQ_PRECHANGE);
|
||||||
|
+
|
||||||
|
+#ifdef CONFIG_CPU_FREQ_DEBUG
|
||||||
|
+ pr_info("cpufreq-omap: transition: %u --> %u\n", freqs.old, freqs.new);
|
||||||
|
+#endif
|
||||||
|
+ ret = clk_set_rate(mpu_clk, freqs.new * 1000);
|
||||||
|
+
|
||||||
|
+ cpufreq_notify_transition(&freqs, CPUFREQ_POSTCHANGE);
|
||||||
|
+
|
||||||
|
+ return ret;
|
||||||
|
+}
|
||||||
|
+
|
||||||
|
+static int __init omap_cpu_init(struct cpufreq_policy *policy)
|
||||||
|
+{
|
||||||
|
+ int result = 0;
|
||||||
|
+
|
||||||
|
+ mpu_clk = clk_get(NULL, "mpu");
|
||||||
|
+ if (IS_ERR(mpu_clk))
|
||||||
|
+ return PTR_ERR(mpu_clk);
|
||||||
|
+
|
||||||
|
+ if (policy->cpu != 0)
|
||||||
|
+ return -EINVAL;
|
||||||
|
+
|
||||||
|
+ policy->cur = policy->min = policy->max = omap_getspeed(0);
|
||||||
|
+
|
||||||
|
+ clk_init_cpufreq_table(&freq_table);
|
||||||
|
+
|
||||||
|
+ if (freq_table) {
|
||||||
|
+ result = cpufreq_frequency_table_cpuinfo(policy, freq_table);
|
||||||
|
+ if (!result)
|
||||||
|
+ cpufreq_frequency_table_get_attr(freq_table,
|
||||||
|
+ policy->cpu);
|
||||||
|
+ } else {
|
||||||
|
+ policy->cpuinfo.min_freq = clk_round_rate(mpu_clk, 0) / 1000;
|
||||||
|
+ policy->cpuinfo.max_freq = clk_round_rate(mpu_clk,
|
||||||
|
+ VERY_HI_RATE) / 1000;
|
||||||
|
+ }
|
||||||
|
+
|
||||||
|
+ policy->min = policy->cpuinfo.min_freq;
|
||||||
|
+ policy->max = policy->cpuinfo.max_freq;
|
||||||
|
+ policy->cur = omap_getspeed(0);
|
||||||
|
+
|
||||||
|
+ /* FIXME: what's the actual transition time? */
|
||||||
|
+ policy->cpuinfo.transition_latency = 300 * 1000;
|
||||||
|
+
|
||||||
|
+ return 0;
|
||||||
|
+}
|
||||||
|
+
|
||||||
|
+static int omap_cpu_exit(struct cpufreq_policy *policy)
|
||||||
|
+{
|
||||||
|
+ clk_exit_cpufreq_table(&freq_table);
|
||||||
|
+ clk_put(mpu_clk);
|
||||||
|
+ return 0;
|
||||||
|
+}
|
||||||
|
+
|
||||||
|
+static struct freq_attr *omap_cpufreq_attr[] = {
|
||||||
|
+ &cpufreq_freq_attr_scaling_available_freqs,
|
||||||
|
+ NULL,
|
||||||
|
+};
|
||||||
|
+
|
||||||
|
+static struct cpufreq_driver omap_driver = {
|
||||||
|
+ .flags = CPUFREQ_STICKY,
|
||||||
|
+ .verify = omap_verify_speed,
|
||||||
|
+ .target = omap_target,
|
||||||
|
+ .get = omap_getspeed,
|
||||||
|
+ .init = omap_cpu_init,
|
||||||
|
+ .exit = omap_cpu_exit,
|
||||||
|
+ .name = "omap1",
|
||||||
|
+ .attr = omap_cpufreq_attr,
|
||||||
|
+};
|
||||||
|
+
|
||||||
|
+static int __init omap_cpufreq_init(void)
|
||||||
|
+{
|
||||||
|
+ return cpufreq_register_driver(&omap_driver);
|
||||||
|
+}
|
||||||
|
+
|
||||||
|
+static void __exit omap_cpufreq_exit(void)
|
||||||
|
+{
|
||||||
|
+ cpufreq_unregister_driver(&omap_driver);
|
||||||
|
+}
|
||||||
|
+
|
||||||
|
+MODULE_DESCRIPTION("cpufreq driver for OMAP1 SOCs");
|
||||||
|
+MODULE_LICENSE("GPL");
|
||||||
|
+module_init(omap_cpufreq_init);
|
||||||
|
+module_exit(omap_cpufreq_exit);
|
||||||
|
diff --git a/arch/arm/mach-omap2/Makefile b/arch/arm/mach-omap2/Makefile
|
||||||
|
index b148077..5024064 100644
|
||||||
|
--- a/arch/arm/mach-omap2/Makefile
|
||||||
|
+++ b/arch/arm/mach-omap2/Makefile
|
||||||
|
@@ -56,6 +56,9 @@ obj-$(CONFIG_ARCH_OMAP3) += opp3xxx_data.o
|
||||||
|
obj-$(CONFIG_ARCH_OMAP4) += opp4xxx_data.o
|
||||||
|
endif
|
||||||
|
|
||||||
|
+# CPUFREQ driver
|
||||||
|
+obj-$(CONFIG_CPU_FREQ) += omap2plus-cpufreq.o
|
||||||
|
+
|
||||||
|
# Power Management
|
||||||
|
ifeq ($(CONFIG_PM),y)
|
||||||
|
obj-$(CONFIG_ARCH_OMAP2) += pm24xx.o
|
||||||
|
diff --git a/arch/arm/mach-omap2/omap2plus-cpufreq.c b/arch/arm/mach-omap2/omap2plus-cpufreq.c
|
||||||
|
new file mode 100644
|
||||||
|
index 0000000..27f641b
|
||||||
|
--- /dev/null
|
||||||
|
+++ b/arch/arm/mach-omap2/omap2plus-cpufreq.c
|
||||||
|
@@ -0,0 +1,201 @@
|
||||||
|
+/*
|
||||||
|
+ * OMAP2PLUS cpufreq driver
|
||||||
|
+ *
|
||||||
|
+ * CPU frequency scaling for OMAP
|
||||||
|
+ *
|
||||||
|
+ * Copyright (C) 2005 Nokia Corporation
|
||||||
|
+ * Written by Tony Lindgren <tony@atomide.com>
|
||||||
|
+ *
|
||||||
|
+ * Based on cpu-sa1110.c, Copyright (C) 2001 Russell King
|
||||||
|
+ *
|
||||||
|
+ * Copyright (C) 2007-2011 Texas Instruments, Inc.
|
||||||
|
+ * Updated to support OMAP3
|
||||||
|
+ * Rajendra Nayak <rnayak@ti.com>
|
||||||
|
+ *
|
||||||
|
+ * 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 <linux/types.h>
|
||||||
|
+#include <linux/kernel.h>
|
||||||
|
+#include <linux/sched.h>
|
||||||
|
+#include <linux/cpufreq.h>
|
||||||
|
+#include <linux/delay.h>
|
||||||
|
+#include <linux/init.h>
|
||||||
|
+#include <linux/err.h>
|
||||||
|
+#include <linux/clk.h>
|
||||||
|
+#include <linux/io.h>
|
||||||
|
+#include <linux/opp.h>
|
||||||
|
+
|
||||||
|
+#include <asm/system.h>
|
||||||
|
+#include <asm/smp_plat.h>
|
||||||
|
+
|
||||||
|
+#include <plat/clock.h>
|
||||||
|
+#include <plat/omap-pm.h>
|
||||||
|
+#include <plat/common.h>
|
||||||
|
+
|
||||||
|
+#include <mach/hardware.h>
|
||||||
|
+
|
||||||
|
+#define VERY_HI_RATE 900000000
|
||||||
|
+
|
||||||
|
+static struct cpufreq_frequency_table *freq_table;
|
||||||
|
+static struct clk *mpu_clk;
|
||||||
|
+
|
||||||
|
+static int omap_verify_speed(struct cpufreq_policy *policy)
|
||||||
|
+{
|
||||||
|
+ if (freq_table)
|
||||||
|
+ return cpufreq_frequency_table_verify(policy, freq_table);
|
||||||
|
+
|
||||||
|
+ if (policy->cpu)
|
||||||
|
+ return -EINVAL;
|
||||||
|
+
|
||||||
|
+ cpufreq_verify_within_limits(policy, policy->cpuinfo.min_freq,
|
||||||
|
+ policy->cpuinfo.max_freq);
|
||||||
|
+
|
||||||
|
+ policy->min = clk_round_rate(mpu_clk, policy->min * 1000) / 1000;
|
||||||
|
+ policy->max = clk_round_rate(mpu_clk, policy->max * 1000) / 1000;
|
||||||
|
+ cpufreq_verify_within_limits(policy, policy->cpuinfo.min_freq,
|
||||||
|
+ policy->cpuinfo.max_freq);
|
||||||
|
+ return 0;
|
||||||
|
+}
|
||||||
|
+
|
||||||
|
+static unsigned int omap_getspeed(unsigned int cpu)
|
||||||
|
+{
|
||||||
|
+ unsigned long rate;
|
||||||
|
+
|
||||||
|
+ if (cpu)
|
||||||
|
+ return 0;
|
||||||
|
+
|
||||||
|
+ rate = clk_get_rate(mpu_clk) / 1000;
|
||||||
|
+ return rate;
|
||||||
|
+}
|
||||||
|
+
|
||||||
|
+static int omap_target(struct cpufreq_policy *policy,
|
||||||
|
+ unsigned int target_freq,
|
||||||
|
+ unsigned int relation)
|
||||||
|
+{
|
||||||
|
+ int ret = 0;
|
||||||
|
+ struct cpufreq_freqs freqs;
|
||||||
|
+
|
||||||
|
+ /* Ensure desired rate is within allowed range. Some govenors
|
||||||
|
+ * (ondemand) will just pass target_freq=0 to get the minimum. */
|
||||||
|
+ if (target_freq < policy->min)
|
||||||
|
+ target_freq = policy->min;
|
||||||
|
+ if (target_freq > policy->max)
|
||||||
|
+ target_freq = policy->max;
|
||||||
|
+
|
||||||
|
+ freqs.old = omap_getspeed(0);
|
||||||
|
+ freqs.new = clk_round_rate(mpu_clk, target_freq * 1000) / 1000;
|
||||||
|
+ freqs.cpu = 0;
|
||||||
|
+
|
||||||
|
+ if (freqs.old == freqs.new)
|
||||||
|
+ return ret;
|
||||||
|
+
|
||||||
|
+ cpufreq_notify_transition(&freqs, CPUFREQ_PRECHANGE);
|
||||||
|
+
|
||||||
|
+#ifdef CONFIG_CPU_FREQ_DEBUG
|
||||||
|
+ pr_info("cpufreq-omap: transition: %u --> %u\n", freqs.old, freqs.new);
|
||||||
|
+#endif
|
||||||
|
+
|
||||||
|
+ ret = clk_set_rate(mpu_clk, freqs.new * 1000);
|
||||||
|
+
|
||||||
|
+ /*
|
||||||
|
+ * Generic CPUFREQ driver jiffy update is under !SMP. So jiffies
|
||||||
|
+ * won't get updated when UP machine cpufreq build with
|
||||||
|
+ * CONFIG_SMP enabled. Below code is added only to manage that
|
||||||
|
+ * scenario
|
||||||
|
+ */
|
||||||
|
+ if (!is_smp())
|
||||||
|
+ loops_per_jiffy =
|
||||||
|
+ cpufreq_scale(loops_per_jiffy, freqs.old, freqs.new);
|
||||||
|
+
|
||||||
|
+ cpufreq_notify_transition(&freqs, CPUFREQ_POSTCHANGE);
|
||||||
|
+
|
||||||
|
+ return ret;
|
||||||
|
+}
|
||||||
|
+
|
||||||
|
+static int __cpuinit omap_cpu_init(struct cpufreq_policy *policy)
|
||||||
|
+{
|
||||||
|
+ int result = 0;
|
||||||
|
+ struct device *mpu_dev;
|
||||||
|
+
|
||||||
|
+ if (cpu_is_omap24xx())
|
||||||
|
+ mpu_clk = clk_get(NULL, "virt_prcm_set");
|
||||||
|
+ else if (cpu_is_omap34xx())
|
||||||
|
+ mpu_clk = clk_get(NULL, "dpll1_ck");
|
||||||
|
+ else if (cpu_is_omap34xx())
|
||||||
|
+ mpu_clk = clk_get(NULL, "dpll_mpu_ck");
|
||||||
|
+
|
||||||
|
+ if (IS_ERR(mpu_clk))
|
||||||
|
+ return PTR_ERR(mpu_clk);
|
||||||
|
+
|
||||||
|
+ if (policy->cpu != 0)
|
||||||
|
+ return -EINVAL;
|
||||||
|
+
|
||||||
|
+ policy->cur = policy->min = policy->max = omap_getspeed(0);
|
||||||
|
+
|
||||||
|
+ mpu_dev = omap2_get_mpuss_device();
|
||||||
|
+ if (!mpu_dev) {
|
||||||
|
+ pr_warning("%s: unable to get the mpu device\n", __func__);
|
||||||
|
+ return -EINVAL;
|
||||||
|
+ }
|
||||||
|
+ opp_init_cpufreq_table(mpu_dev, &freq_table);
|
||||||
|
+
|
||||||
|
+ if (freq_table) {
|
||||||
|
+ result = cpufreq_frequency_table_cpuinfo(policy, freq_table);
|
||||||
|
+ if (!result)
|
||||||
|
+ cpufreq_frequency_table_get_attr(freq_table,
|
||||||
|
+ policy->cpu);
|
||||||
|
+ } else {
|
||||||
|
+ policy->cpuinfo.min_freq = clk_round_rate(mpu_clk, 0) / 1000;
|
||||||
|
+ policy->cpuinfo.max_freq = clk_round_rate(mpu_clk,
|
||||||
|
+ VERY_HI_RATE) / 1000;
|
||||||
|
+ }
|
||||||
|
+
|
||||||
|
+ policy->min = policy->cpuinfo.min_freq;
|
||||||
|
+ policy->max = policy->cpuinfo.max_freq;
|
||||||
|
+ policy->cur = omap_getspeed(0);
|
||||||
|
+
|
||||||
|
+ /* FIXME: what's the actual transition time? */
|
||||||
|
+ policy->cpuinfo.transition_latency = 300 * 1000;
|
||||||
|
+
|
||||||
|
+ return 0;
|
||||||
|
+}
|
||||||
|
+
|
||||||
|
+static int omap_cpu_exit(struct cpufreq_policy *policy)
|
||||||
|
+{
|
||||||
|
+ clk_exit_cpufreq_table(&freq_table);
|
||||||
|
+ clk_put(mpu_clk);
|
||||||
|
+ return 0;
|
||||||
|
+}
|
||||||
|
+
|
||||||
|
+static struct freq_attr *omap_cpufreq_attr[] = {
|
||||||
|
+ &cpufreq_freq_attr_scaling_available_freqs,
|
||||||
|
+ NULL,
|
||||||
|
+};
|
||||||
|
+
|
||||||
|
+static struct cpufreq_driver omap_driver = {
|
||||||
|
+ .flags = CPUFREQ_STICKY,
|
||||||
|
+ .verify = omap_verify_speed,
|
||||||
|
+ .target = omap_target,
|
||||||
|
+ .get = omap_getspeed,
|
||||||
|
+ .init = omap_cpu_init,
|
||||||
|
+ .exit = omap_cpu_exit,
|
||||||
|
+ .name = "omap2plus",
|
||||||
|
+ .attr = omap_cpufreq_attr,
|
||||||
|
+};
|
||||||
|
+
|
||||||
|
+static int __init omap_cpufreq_init(void)
|
||||||
|
+{
|
||||||
|
+ return cpufreq_register_driver(&omap_driver);
|
||||||
|
+}
|
||||||
|
+
|
||||||
|
+static void __exit omap_cpufreq_exit(void)
|
||||||
|
+{
|
||||||
|
+ cpufreq_unregister_driver(&omap_driver);
|
||||||
|
+}
|
||||||
|
+
|
||||||
|
+MODULE_DESCRIPTION("cpufreq driver for OMAP2PLUS SOCs");
|
||||||
|
+MODULE_LICENSE("GPL");
|
||||||
|
+module_init(omap_cpufreq_init);
|
||||||
|
+module_exit(omap_cpufreq_exit);
|
||||||
|
diff --git a/arch/arm/plat-omap/Makefile b/arch/arm/plat-omap/Makefile
|
||||||
|
index f0233e6..4ef7493 100644
|
||||||
|
--- a/arch/arm/plat-omap/Makefile
|
||||||
|
+++ b/arch/arm/plat-omap/Makefile
|
||||||
|
@@ -21,7 +21,6 @@ obj-$(CONFIG_OMAP_MCBSP) += mcbsp.o
|
||||||
|
obj-$(CONFIG_OMAP_IOMMU) += iommu.o iovmm.o
|
||||||
|
obj-$(CONFIG_OMAP_IOMMU_DEBUG) += iommu-debug.o
|
||||||
|
|
||||||
|
-obj-$(CONFIG_CPU_FREQ) += cpu-omap.o
|
||||||
|
obj-$(CONFIG_OMAP_DM_TIMER) += dmtimer.o
|
||||||
|
obj-$(CONFIG_OMAP_DEBUG_DEVICES) += debug-devices.o
|
||||||
|
obj-$(CONFIG_OMAP_DEBUG_LEDS) += debug-leds.o
|
||||||
|
diff --git a/arch/arm/plat-omap/cpu-omap.c b/arch/arm/plat-omap/cpu-omap.c
|
||||||
|
deleted file mode 100644
|
||||||
|
index 9cd2709..0000000
|
||||||
|
--- a/arch/arm/plat-omap/cpu-omap.c
|
||||||
|
+++ /dev/null
|
||||||
|
@@ -1,204 +0,0 @@
|
||||||
|
-/*
|
||||||
|
- * linux/arch/arm/plat-omap/cpu-omap.c
|
||||||
|
- *
|
||||||
|
- * CPU frequency scaling for OMAP
|
||||||
|
- *
|
||||||
|
- * Copyright (C) 2005 Nokia Corporation
|
||||||
|
- * Written by Tony Lindgren <tony@atomide.com>
|
||||||
|
- *
|
||||||
|
- * Based on cpu-sa1110.c, Copyright (C) 2001 Russell King
|
||||||
|
- *
|
||||||
|
- * Copyright (C) 2007-2008 Texas Instruments, Inc.
|
||||||
|
- * Updated to support OMAP3
|
||||||
|
- * Rajendra Nayak <rnayak@ti.com>
|
||||||
|
- *
|
||||||
|
- * 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 <linux/types.h>
|
||||||
|
-#include <linux/kernel.h>
|
||||||
|
-#include <linux/sched.h>
|
||||||
|
-#include <linux/cpufreq.h>
|
||||||
|
-#include <linux/delay.h>
|
||||||
|
-#include <linux/init.h>
|
||||||
|
-#include <linux/err.h>
|
||||||
|
-#include <linux/clk.h>
|
||||||
|
-#include <linux/io.h>
|
||||||
|
-#include <linux/opp.h>
|
||||||
|
-
|
||||||
|
-#include <mach/hardware.h>
|
||||||
|
-#include <plat/clock.h>
|
||||||
|
-#include <asm/system.h>
|
||||||
|
-
|
||||||
|
-#if defined(CONFIG_ARCH_OMAP3) && !defined(CONFIG_OMAP_PM_NONE)
|
||||||
|
-#include <plat/omap-pm.h>
|
||||||
|
-#include <plat/common.h>
|
||||||
|
-#endif
|
||||||
|
-
|
||||||
|
-#define VERY_HI_RATE 900000000
|
||||||
|
-
|
||||||
|
-static struct cpufreq_frequency_table *freq_table;
|
||||||
|
-
|
||||||
|
-#ifdef CONFIG_ARCH_OMAP1
|
||||||
|
-#define MPU_CLK "mpu"
|
||||||
|
-#elif defined(CONFIG_ARCH_OMAP3)
|
||||||
|
-#define MPU_CLK "arm_fck"
|
||||||
|
-#else
|
||||||
|
-#define MPU_CLK "virt_prcm_set"
|
||||||
|
-#endif
|
||||||
|
-
|
||||||
|
-static struct clk *mpu_clk;
|
||||||
|
-
|
||||||
|
-/* TODO: Add support for SDRAM timing changes */
|
||||||
|
-
|
||||||
|
-static int omap_verify_speed(struct cpufreq_policy *policy)
|
||||||
|
-{
|
||||||
|
- if (freq_table)
|
||||||
|
- return cpufreq_frequency_table_verify(policy, freq_table);
|
||||||
|
-
|
||||||
|
- if (policy->cpu)
|
||||||
|
- return -EINVAL;
|
||||||
|
-
|
||||||
|
- cpufreq_verify_within_limits(policy, policy->cpuinfo.min_freq,
|
||||||
|
- policy->cpuinfo.max_freq);
|
||||||
|
-
|
||||||
|
- policy->min = clk_round_rate(mpu_clk, policy->min * 1000) / 1000;
|
||||||
|
- policy->max = clk_round_rate(mpu_clk, policy->max * 1000) / 1000;
|
||||||
|
- cpufreq_verify_within_limits(policy, policy->cpuinfo.min_freq,
|
||||||
|
- policy->cpuinfo.max_freq);
|
||||||
|
- return 0;
|
||||||
|
-}
|
||||||
|
-
|
||||||
|
-static unsigned int omap_getspeed(unsigned int cpu)
|
||||||
|
-{
|
||||||
|
- unsigned long rate;
|
||||||
|
-
|
||||||
|
- if (cpu)
|
||||||
|
- return 0;
|
||||||
|
-
|
||||||
|
- rate = clk_get_rate(mpu_clk) / 1000;
|
||||||
|
- return rate;
|
||||||
|
-}
|
||||||
|
-
|
||||||
|
-static int omap_target(struct cpufreq_policy *policy,
|
||||||
|
- unsigned int target_freq,
|
||||||
|
- unsigned int relation)
|
||||||
|
-{
|
||||||
|
-#ifdef CONFIG_ARCH_OMAP1
|
||||||
|
- struct cpufreq_freqs freqs;
|
||||||
|
-#endif
|
||||||
|
-#if defined(CONFIG_ARCH_OMAP3) && !defined(CONFIG_OMAP_PM_NONE)
|
||||||
|
- unsigned long freq;
|
||||||
|
- struct device *mpu_dev = omap2_get_mpuss_device();
|
||||||
|
-#endif
|
||||||
|
- int ret = 0;
|
||||||
|
-
|
||||||
|
- /* Ensure desired rate is within allowed range. Some govenors
|
||||||
|
- * (ondemand) will just pass target_freq=0 to get the minimum. */
|
||||||
|
- if (target_freq < policy->min)
|
||||||
|
- target_freq = policy->min;
|
||||||
|
- if (target_freq > policy->max)
|
||||||
|
- target_freq = policy->max;
|
||||||
|
-
|
||||||
|
-#ifdef CONFIG_ARCH_OMAP1
|
||||||
|
- freqs.old = omap_getspeed(0);
|
||||||
|
- freqs.new = clk_round_rate(mpu_clk, target_freq * 1000) / 1000;
|
||||||
|
- freqs.cpu = 0;
|
||||||
|
-
|
||||||
|
- if (freqs.old == freqs.new)
|
||||||
|
- return ret;
|
||||||
|
- cpufreq_notify_transition(&freqs, CPUFREQ_PRECHANGE);
|
||||||
|
-#ifdef CONFIG_CPU_FREQ_DEBUG
|
||||||
|
- printk(KERN_DEBUG "cpufreq-omap: transition: %u --> %u\n",
|
||||||
|
- freqs.old, freqs.new);
|
||||||
|
-#endif
|
||||||
|
- ret = clk_set_rate(mpu_clk, freqs.new * 1000);
|
||||||
|
- cpufreq_notify_transition(&freqs, CPUFREQ_POSTCHANGE);
|
||||||
|
-#elif defined(CONFIG_ARCH_OMAP3) && !defined(CONFIG_OMAP_PM_NONE)
|
||||||
|
- freq = target_freq * 1000;
|
||||||
|
- if (opp_find_freq_ceil(mpu_dev, &freq))
|
||||||
|
- omap_pm_cpu_set_freq(freq);
|
||||||
|
-#endif
|
||||||
|
- return ret;
|
||||||
|
-}
|
||||||
|
-
|
||||||
|
-static int __cpuinit omap_cpu_init(struct cpufreq_policy *policy)
|
||||||
|
-{
|
||||||
|
- int result = 0;
|
||||||
|
-
|
||||||
|
- mpu_clk = clk_get(NULL, MPU_CLK);
|
||||||
|
- if (IS_ERR(mpu_clk))
|
||||||
|
- return PTR_ERR(mpu_clk);
|
||||||
|
-
|
||||||
|
- if (policy->cpu != 0)
|
||||||
|
- return -EINVAL;
|
||||||
|
-
|
||||||
|
- policy->cur = policy->min = policy->max = omap_getspeed(0);
|
||||||
|
-
|
||||||
|
- if (!cpu_is_omap34xx()) {
|
||||||
|
- clk_init_cpufreq_table(&freq_table);
|
||||||
|
- } else {
|
||||||
|
- struct device *mpu_dev = omap2_get_mpuss_device();
|
||||||
|
-
|
||||||
|
- opp_init_cpufreq_table(mpu_dev, &freq_table);
|
||||||
|
- }
|
||||||
|
-
|
||||||
|
- if (freq_table) {
|
||||||
|
- result = cpufreq_frequency_table_cpuinfo(policy, freq_table);
|
||||||
|
- if (!result)
|
||||||
|
- cpufreq_frequency_table_get_attr(freq_table,
|
||||||
|
- policy->cpu);
|
||||||
|
- } else {
|
||||||
|
- policy->cpuinfo.min_freq = clk_round_rate(mpu_clk, 0) / 1000;
|
||||||
|
- policy->cpuinfo.max_freq = clk_round_rate(mpu_clk,
|
||||||
|
- VERY_HI_RATE) / 1000;
|
||||||
|
- }
|
||||||
|
-
|
||||||
|
- policy->min = policy->cpuinfo.min_freq;
|
||||||
|
- policy->max = policy->cpuinfo.max_freq;
|
||||||
|
- policy->cur = omap_getspeed(0);
|
||||||
|
-
|
||||||
|
- /* FIXME: what's the actual transition time? */
|
||||||
|
- policy->cpuinfo.transition_latency = 300 * 1000;
|
||||||
|
-
|
||||||
|
- return 0;
|
||||||
|
-}
|
||||||
|
-
|
||||||
|
-static int omap_cpu_exit(struct cpufreq_policy *policy)
|
||||||
|
-{
|
||||||
|
- clk_exit_cpufreq_table(&freq_table);
|
||||||
|
- clk_put(mpu_clk);
|
||||||
|
- return 0;
|
||||||
|
-}
|
||||||
|
-
|
||||||
|
-static struct freq_attr *omap_cpufreq_attr[] = {
|
||||||
|
- &cpufreq_freq_attr_scaling_available_freqs,
|
||||||
|
- NULL,
|
||||||
|
-};
|
||||||
|
-
|
||||||
|
-static struct cpufreq_driver omap_driver = {
|
||||||
|
- .flags = CPUFREQ_STICKY,
|
||||||
|
- .verify = omap_verify_speed,
|
||||||
|
- .target = omap_target,
|
||||||
|
- .get = omap_getspeed,
|
||||||
|
- .init = omap_cpu_init,
|
||||||
|
- .exit = omap_cpu_exit,
|
||||||
|
- .name = "omap",
|
||||||
|
- .attr = omap_cpufreq_attr,
|
||||||
|
-};
|
||||||
|
-
|
||||||
|
-static int __init omap_cpufreq_init(void)
|
||||||
|
-{
|
||||||
|
- return cpufreq_register_driver(&omap_driver);
|
||||||
|
-}
|
||||||
|
-
|
||||||
|
-late_initcall(omap_cpufreq_init);
|
||||||
|
-
|
||||||
|
-/*
|
||||||
|
- * if ever we want to remove this, upon cleanup call:
|
||||||
|
- *
|
||||||
|
- * cpufreq_unregister_driver()
|
||||||
|
- * cpufreq_frequency_table_put_attr()
|
||||||
|
- */
|
||||||
|
-
|
||||||
|
--
|
||||||
|
1.6.6.1
|
||||||
|
|
||||||
+171
@@ -0,0 +1,171 @@
|
|||||||
|
From f5dc16c8178d0c0bcad795f8ebc71934c4028472 Mon Sep 17 00:00:00 2001
|
||||||
|
From: Santosh Shilimkar <santosh.shilimkar@ti.com>
|
||||||
|
Date: Mon, 14 Mar 2011 17:08:49 +0530
|
||||||
|
Subject: [PATCH 08/19] OMAP2PLUS: cpufreq: Add SMP support to cater OMAP4430
|
||||||
|
|
||||||
|
On OMAP SMP configuartion, both processors share the voltage
|
||||||
|
and clock. So both CPUs needs to be scaled together and hence
|
||||||
|
needs software co-ordination.
|
||||||
|
|
||||||
|
Signed-off-by: Santosh Shilimkar <santosh.shilimkar@ti.com>
|
||||||
|
Cc: Kevin Hilman <khilman@ti.com>
|
||||||
|
cc: Vishwanath BS <vishwanath.bs@ti.com>
|
||||||
|
Signed-off-by: Koen Kooi <koen@dominion.thruhere.net>
|
||||||
|
---
|
||||||
|
arch/arm/mach-omap2/omap2plus-cpufreq.c | 73 ++++++++++++++++++++++++++-----
|
||||||
|
1 files changed, 62 insertions(+), 11 deletions(-)
|
||||||
|
|
||||||
|
diff --git a/arch/arm/mach-omap2/omap2plus-cpufreq.c b/arch/arm/mach-omap2/omap2plus-cpufreq.c
|
||||||
|
index 27f641b..3730f96 100644
|
||||||
|
--- a/arch/arm/mach-omap2/omap2plus-cpufreq.c
|
||||||
|
+++ b/arch/arm/mach-omap2/omap2plus-cpufreq.c
|
||||||
|
@@ -26,9 +26,11 @@
|
||||||
|
#include <linux/clk.h>
|
||||||
|
#include <linux/io.h>
|
||||||
|
#include <linux/opp.h>
|
||||||
|
+#include <linux/cpu.h>
|
||||||
|
|
||||||
|
#include <asm/system.h>
|
||||||
|
#include <asm/smp_plat.h>
|
||||||
|
+#include <asm/cpu.h>
|
||||||
|
|
||||||
|
#include <plat/clock.h>
|
||||||
|
#include <plat/omap-pm.h>
|
||||||
|
@@ -63,7 +65,7 @@ static unsigned int omap_getspeed(unsigned int cpu)
|
||||||
|
{
|
||||||
|
unsigned long rate;
|
||||||
|
|
||||||
|
- if (cpu)
|
||||||
|
+ if (cpu >= NR_CPUS)
|
||||||
|
return 0;
|
||||||
|
|
||||||
|
rate = clk_get_rate(mpu_clk) / 1000;
|
||||||
|
@@ -74,9 +76,13 @@ static int omap_target(struct cpufreq_policy *policy,
|
||||||
|
unsigned int target_freq,
|
||||||
|
unsigned int relation)
|
||||||
|
{
|
||||||
|
- int ret = 0;
|
||||||
|
+ int i, ret = 0;
|
||||||
|
struct cpufreq_freqs freqs;
|
||||||
|
|
||||||
|
+ /* Changes not allowed until all CPUs are online */
|
||||||
|
+ if (is_smp() && (num_online_cpus() < NR_CPUS))
|
||||||
|
+ return ret;
|
||||||
|
+
|
||||||
|
/* Ensure desired rate is within allowed range. Some govenors
|
||||||
|
* (ondemand) will just pass target_freq=0 to get the minimum. */
|
||||||
|
if (target_freq < policy->min)
|
||||||
|
@@ -84,15 +90,25 @@ static int omap_target(struct cpufreq_policy *policy,
|
||||||
|
if (target_freq > policy->max)
|
||||||
|
target_freq = policy->max;
|
||||||
|
|
||||||
|
- freqs.old = omap_getspeed(0);
|
||||||
|
+ freqs.old = omap_getspeed(policy->cpu);
|
||||||
|
freqs.new = clk_round_rate(mpu_clk, target_freq * 1000) / 1000;
|
||||||
|
- freqs.cpu = 0;
|
||||||
|
+ freqs.cpu = policy->cpu;
|
||||||
|
|
||||||
|
if (freqs.old == freqs.new)
|
||||||
|
return ret;
|
||||||
|
|
||||||
|
- cpufreq_notify_transition(&freqs, CPUFREQ_PRECHANGE);
|
||||||
|
+ if (!is_smp()) {
|
||||||
|
+ cpufreq_notify_transition(&freqs, CPUFREQ_PRECHANGE);
|
||||||
|
+ goto set_freq;
|
||||||
|
+ }
|
||||||
|
+
|
||||||
|
+ /* notifiers */
|
||||||
|
+ for_each_cpu(i, policy->cpus) {
|
||||||
|
+ freqs.cpu = i;
|
||||||
|
+ cpufreq_notify_transition(&freqs, CPUFREQ_PRECHANGE);
|
||||||
|
+ }
|
||||||
|
|
||||||
|
+set_freq:
|
||||||
|
#ifdef CONFIG_CPU_FREQ_DEBUG
|
||||||
|
pr_info("cpufreq-omap: transition: %u --> %u\n", freqs.old, freqs.new);
|
||||||
|
#endif
|
||||||
|
@@ -105,12 +121,33 @@ static int omap_target(struct cpufreq_policy *policy,
|
||||||
|
* CONFIG_SMP enabled. Below code is added only to manage that
|
||||||
|
* scenario
|
||||||
|
*/
|
||||||
|
- if (!is_smp())
|
||||||
|
+ freqs.new = omap_getspeed(policy->cpu);
|
||||||
|
+ if (!is_smp()) {
|
||||||
|
loops_per_jiffy =
|
||||||
|
cpufreq_scale(loops_per_jiffy, freqs.old, freqs.new);
|
||||||
|
+ cpufreq_notify_transition(&freqs, CPUFREQ_POSTCHANGE);
|
||||||
|
+ goto skip_lpj;
|
||||||
|
+ }
|
||||||
|
|
||||||
|
- cpufreq_notify_transition(&freqs, CPUFREQ_POSTCHANGE);
|
||||||
|
+#ifdef CONFIG_SMP
|
||||||
|
+ /*
|
||||||
|
+ * Note that loops_per_jiffy is not updated on SMP systems in
|
||||||
|
+ * cpufreq driver. So, update the per-CPU loops_per_jiffy value
|
||||||
|
+ * on frequency transition. We need to update all dependent CPUs.
|
||||||
|
+ */
|
||||||
|
+ for_each_cpu(i, policy->cpus)
|
||||||
|
+ per_cpu(cpu_data, i).loops_per_jiffy =
|
||||||
|
+ cpufreq_scale(per_cpu(cpu_data, i).loops_per_jiffy,
|
||||||
|
+ freqs.old, freqs.new);
|
||||||
|
+#endif
|
||||||
|
|
||||||
|
+ /* notifiers */
|
||||||
|
+ for_each_cpu(i, policy->cpus) {
|
||||||
|
+ freqs.cpu = i;
|
||||||
|
+ cpufreq_notify_transition(&freqs, CPUFREQ_POSTCHANGE);
|
||||||
|
+ }
|
||||||
|
+
|
||||||
|
+skip_lpj:
|
||||||
|
return ret;
|
||||||
|
}
|
||||||
|
|
||||||
|
@@ -118,6 +155,7 @@ static int __cpuinit omap_cpu_init(struct cpufreq_policy *policy)
|
||||||
|
{
|
||||||
|
int result = 0;
|
||||||
|
struct device *mpu_dev;
|
||||||
|
+ static cpumask_var_t cpumask;
|
||||||
|
|
||||||
|
if (cpu_is_omap24xx())
|
||||||
|
mpu_clk = clk_get(NULL, "virt_prcm_set");
|
||||||
|
@@ -129,12 +167,12 @@ static int __cpuinit omap_cpu_init(struct cpufreq_policy *policy)
|
||||||
|
if (IS_ERR(mpu_clk))
|
||||||
|
return PTR_ERR(mpu_clk);
|
||||||
|
|
||||||
|
- if (policy->cpu != 0)
|
||||||
|
+ if (policy->cpu >= NR_CPUS)
|
||||||
|
return -EINVAL;
|
||||||
|
|
||||||
|
- policy->cur = policy->min = policy->max = omap_getspeed(0);
|
||||||
|
-
|
||||||
|
+ policy->cur = policy->min = policy->max = omap_getspeed(policy->cpu);
|
||||||
|
mpu_dev = omap2_get_mpuss_device();
|
||||||
|
+
|
||||||
|
if (!mpu_dev) {
|
||||||
|
pr_warning("%s: unable to get the mpu device\n", __func__);
|
||||||
|
return -EINVAL;
|
||||||
|
@@ -154,7 +192,20 @@ static int __cpuinit omap_cpu_init(struct cpufreq_policy *policy)
|
||||||
|
|
||||||
|
policy->min = policy->cpuinfo.min_freq;
|
||||||
|
policy->max = policy->cpuinfo.max_freq;
|
||||||
|
- policy->cur = omap_getspeed(0);
|
||||||
|
+ policy->cur = omap_getspeed(policy->cpu);
|
||||||
|
+
|
||||||
|
+ /*
|
||||||
|
+ * On OMAP SMP configuartion, both processors share the voltage
|
||||||
|
+ * and clock. So both CPUs needs to be scaled together and hence
|
||||||
|
+ * needs software co-ordination. Use cpufreq affected_cpus
|
||||||
|
+ * interface to handle this scenario. Additional is_smp() check
|
||||||
|
+ * is to keep SMP_ON_UP build working.
|
||||||
|
+ */
|
||||||
|
+ if (is_smp()) {
|
||||||
|
+ policy->shared_type = CPUFREQ_SHARED_TYPE_ANY;
|
||||||
|
+ cpumask_or(cpumask, cpumask_of(policy->cpu), cpumask);
|
||||||
|
+ cpumask_copy(policy->cpus, cpumask);
|
||||||
|
+ }
|
||||||
|
|
||||||
|
/* FIXME: what's the actual transition time? */
|
||||||
|
policy->cpuinfo.transition_latency = 300 * 1000;
|
||||||
|
--
|
||||||
|
1.6.6.1
|
||||||
|
|
||||||
+30
@@ -0,0 +1,30 @@
|
|||||||
|
From 07367b4c3afd8e881c4cf50ef35d081c4ac252b8 Mon Sep 17 00:00:00 2001
|
||||||
|
From: Jarkko Nikula <jhnikula@gmail.com>
|
||||||
|
Date: Thu, 14 Apr 2011 16:21:58 +0300
|
||||||
|
Subject: [PATCH 09/19] OMAP2PLUS: cpufreq: Fix typo when attempting to set mpu_clk for OMAP4
|
||||||
|
|
||||||
|
Fix this typo as there is no dpll_mpu_ck for OMAP3 and code flow is clearly
|
||||||
|
trying to set mpu_clk for OMAP4 for which this dpll_mpu_ck is available.
|
||||||
|
|
||||||
|
Signed-off-by: Jarkko Nikula <jhnikula@gmail.com>
|
||||||
|
Signed-off-by: Koen Kooi <koen@dominion.thruhere.net>
|
||||||
|
---
|
||||||
|
arch/arm/mach-omap2/omap2plus-cpufreq.c | 2 +-
|
||||||
|
1 files changed, 1 insertions(+), 1 deletions(-)
|
||||||
|
|
||||||
|
diff --git a/arch/arm/mach-omap2/omap2plus-cpufreq.c b/arch/arm/mach-omap2/omap2plus-cpufreq.c
|
||||||
|
index 3730f96..a725d90 100644
|
||||||
|
--- a/arch/arm/mach-omap2/omap2plus-cpufreq.c
|
||||||
|
+++ b/arch/arm/mach-omap2/omap2plus-cpufreq.c
|
||||||
|
@@ -161,7 +161,7 @@ static int __cpuinit omap_cpu_init(struct cpufreq_policy *policy)
|
||||||
|
mpu_clk = clk_get(NULL, "virt_prcm_set");
|
||||||
|
else if (cpu_is_omap34xx())
|
||||||
|
mpu_clk = clk_get(NULL, "dpll1_ck");
|
||||||
|
- else if (cpu_is_omap34xx())
|
||||||
|
+ else if (cpu_is_omap44xx())
|
||||||
|
mpu_clk = clk_get(NULL, "dpll_mpu_ck");
|
||||||
|
|
||||||
|
if (IS_ERR(mpu_clk))
|
||||||
|
--
|
||||||
|
1.6.6.1
|
||||||
|
|
||||||
+64
@@ -0,0 +1,64 @@
|
|||||||
|
From 4d3e024c2f7f0334874bbb2a168b62e91cb2517a Mon Sep 17 00:00:00 2001
|
||||||
|
From: Nishanth Menon <nm@ti.com>
|
||||||
|
Date: Wed, 25 May 2011 16:38:46 -0700
|
||||||
|
Subject: [PATCH 10/19] OMAP2+: cpufreq: move clk name decision to init
|
||||||
|
|
||||||
|
Clk name does'nt need to dynamically detected during clk init.
|
||||||
|
move them off to driver initialization, if we dont have a clk name,
|
||||||
|
there is no point in registering the driver anyways. The actual clk
|
||||||
|
get and put is left at cpu_init and exit functions.
|
||||||
|
|
||||||
|
Signed-off-by: Nishanth Menon <nm@ti.com>
|
||||||
|
Signed-off-by: Koen Kooi <koen@dominion.thruhere.net>
|
||||||
|
---
|
||||||
|
arch/arm/mach-omap2/omap2plus-cpufreq.c | 20 +++++++++++++-------
|
||||||
|
1 files changed, 13 insertions(+), 7 deletions(-)
|
||||||
|
|
||||||
|
diff --git a/arch/arm/mach-omap2/omap2plus-cpufreq.c b/arch/arm/mach-omap2/omap2plus-cpufreq.c
|
||||||
|
index a725d90..c46d0cd 100644
|
||||||
|
--- a/arch/arm/mach-omap2/omap2plus-cpufreq.c
|
||||||
|
+++ b/arch/arm/mach-omap2/omap2plus-cpufreq.c
|
||||||
|
@@ -42,6 +42,7 @@
|
||||||
|
|
||||||
|
static struct cpufreq_frequency_table *freq_table;
|
||||||
|
static struct clk *mpu_clk;
|
||||||
|
+static char *mpu_clk_name;
|
||||||
|
|
||||||
|
static int omap_verify_speed(struct cpufreq_policy *policy)
|
||||||
|
{
|
||||||
|
@@ -157,13 +158,7 @@ static int __cpuinit omap_cpu_init(struct cpufreq_policy *policy)
|
||||||
|
struct device *mpu_dev;
|
||||||
|
static cpumask_var_t cpumask;
|
||||||
|
|
||||||
|
- if (cpu_is_omap24xx())
|
||||||
|
- mpu_clk = clk_get(NULL, "virt_prcm_set");
|
||||||
|
- else if (cpu_is_omap34xx())
|
||||||
|
- mpu_clk = clk_get(NULL, "dpll1_ck");
|
||||||
|
- else if (cpu_is_omap44xx())
|
||||||
|
- mpu_clk = clk_get(NULL, "dpll_mpu_ck");
|
||||||
|
-
|
||||||
|
+ mpu_clk = clk_get(NULL, mpu_clk_name);
|
||||||
|
if (IS_ERR(mpu_clk))
|
||||||
|
return PTR_ERR(mpu_clk);
|
||||||
|
|
||||||
|
@@ -238,6 +233,17 @@ static struct cpufreq_driver omap_driver = {
|
||||||
|
|
||||||
|
static int __init omap_cpufreq_init(void)
|
||||||
|
{
|
||||||
|
+ if (cpu_is_omap24xx())
|
||||||
|
+ mpu_clk_name = "virt_prcm_set";
|
||||||
|
+ else if (cpu_is_omap34xx())
|
||||||
|
+ mpu_clk_name = "dpll1_ck";
|
||||||
|
+ else if (cpu_is_omap44xx())
|
||||||
|
+ mpu_clk_name = "dpll_mpu_ck";
|
||||||
|
+
|
||||||
|
+ if (!mpu_clk_name) {
|
||||||
|
+ pr_err("%s: unsupported Silicon?\n", __func__);
|
||||||
|
+ return -EINVAL;
|
||||||
|
+ }
|
||||||
|
return cpufreq_register_driver(&omap_driver);
|
||||||
|
}
|
||||||
|
|
||||||
|
--
|
||||||
|
1.6.6.1
|
||||||
|
|
||||||
+64
@@ -0,0 +1,64 @@
|
|||||||
|
From 85afa12ad2a6e7a23ddf4b25e78e0ce5b9f18a64 Mon Sep 17 00:00:00 2001
|
||||||
|
From: Nishanth Menon <nm@ti.com>
|
||||||
|
Date: Wed, 25 May 2011 16:38:47 -0700
|
||||||
|
Subject: [PATCH 11/19] OMAP2+: cpufreq: deny initialization if no mpudev
|
||||||
|
|
||||||
|
if we do not have mpu_dev we normally fail in cpu_init. It is better
|
||||||
|
to fail driver registration if the devices are not available.
|
||||||
|
|
||||||
|
Signed-off-by: Nishanth Menon <nm@ti.com>
|
||||||
|
Signed-off-by: Koen Kooi <koen@dominion.thruhere.net>
|
||||||
|
---
|
||||||
|
arch/arm/mach-omap2/omap2plus-cpufreq.c | 15 ++++++++-------
|
||||||
|
1 files changed, 8 insertions(+), 7 deletions(-)
|
||||||
|
|
||||||
|
diff --git a/arch/arm/mach-omap2/omap2plus-cpufreq.c b/arch/arm/mach-omap2/omap2plus-cpufreq.c
|
||||||
|
index c46d0cd..33a91ec 100644
|
||||||
|
--- a/arch/arm/mach-omap2/omap2plus-cpufreq.c
|
||||||
|
+++ b/arch/arm/mach-omap2/omap2plus-cpufreq.c
|
||||||
|
@@ -43,6 +43,7 @@
|
||||||
|
static struct cpufreq_frequency_table *freq_table;
|
||||||
|
static struct clk *mpu_clk;
|
||||||
|
static char *mpu_clk_name;
|
||||||
|
+static struct device *mpu_dev;
|
||||||
|
|
||||||
|
static int omap_verify_speed(struct cpufreq_policy *policy)
|
||||||
|
{
|
||||||
|
@@ -155,7 +156,6 @@ skip_lpj:
|
||||||
|
static int __cpuinit omap_cpu_init(struct cpufreq_policy *policy)
|
||||||
|
{
|
||||||
|
int result = 0;
|
||||||
|
- struct device *mpu_dev;
|
||||||
|
static cpumask_var_t cpumask;
|
||||||
|
|
||||||
|
mpu_clk = clk_get(NULL, mpu_clk_name);
|
||||||
|
@@ -166,12 +166,6 @@ static int __cpuinit omap_cpu_init(struct cpufreq_policy *policy)
|
||||||
|
return -EINVAL;
|
||||||
|
|
||||||
|
policy->cur = policy->min = policy->max = omap_getspeed(policy->cpu);
|
||||||
|
- mpu_dev = omap2_get_mpuss_device();
|
||||||
|
-
|
||||||
|
- if (!mpu_dev) {
|
||||||
|
- pr_warning("%s: unable to get the mpu device\n", __func__);
|
||||||
|
- return -EINVAL;
|
||||||
|
- }
|
||||||
|
opp_init_cpufreq_table(mpu_dev, &freq_table);
|
||||||
|
|
||||||
|
if (freq_table) {
|
||||||
|
@@ -244,6 +238,13 @@ static int __init omap_cpufreq_init(void)
|
||||||
|
pr_err("%s: unsupported Silicon?\n", __func__);
|
||||||
|
return -EINVAL;
|
||||||
|
}
|
||||||
|
+
|
||||||
|
+ mpu_dev = omap2_get_mpuss_device();
|
||||||
|
+ if (!mpu_dev) {
|
||||||
|
+ pr_warning("%s: unable to get the mpu device\n", __func__);
|
||||||
|
+ return -EINVAL;
|
||||||
|
+ }
|
||||||
|
+
|
||||||
|
return cpufreq_register_driver(&omap_driver);
|
||||||
|
}
|
||||||
|
|
||||||
|
--
|
||||||
|
1.6.6.1
|
||||||
|
|
||||||
+129
@@ -0,0 +1,129 @@
|
|||||||
|
From 345f93655f425c87ba01e949dc038e04542d8cd4 Mon Sep 17 00:00:00 2001
|
||||||
|
From: Nishanth Menon <nm@ti.com>
|
||||||
|
Date: Thu, 26 May 2011 19:39:17 -0700
|
||||||
|
Subject: [PATCH 12/19] OMAP2+: cpufreq: dont support !freq_table
|
||||||
|
|
||||||
|
OMAP2+ all have frequency tables, hence the hacks we had for older
|
||||||
|
silicon do not need to be carried forward. As part of this change,
|
||||||
|
use cpufreq_frequency_table_target to find the best match for
|
||||||
|
frequency requested.
|
||||||
|
|
||||||
|
Signed-off-by: Nishanth Menon <nm@ti.com>
|
||||||
|
Signed-off-by: Koen Kooi <koen@dominion.thruhere.net>
|
||||||
|
---
|
||||||
|
arch/arm/mach-omap2/omap2plus-cpufreq.c | 67 +++++++++++++++----------------
|
||||||
|
1 files changed, 33 insertions(+), 34 deletions(-)
|
||||||
|
|
||||||
|
diff --git a/arch/arm/mach-omap2/omap2plus-cpufreq.c b/arch/arm/mach-omap2/omap2plus-cpufreq.c
|
||||||
|
index 33a91ec..acf18e8 100644
|
||||||
|
--- a/arch/arm/mach-omap2/omap2plus-cpufreq.c
|
||||||
|
+++ b/arch/arm/mach-omap2/omap2plus-cpufreq.c
|
||||||
|
@@ -38,8 +38,6 @@
|
||||||
|
|
||||||
|
#include <mach/hardware.h>
|
||||||
|
|
||||||
|
-#define VERY_HI_RATE 900000000
|
||||||
|
-
|
||||||
|
static struct cpufreq_frequency_table *freq_table;
|
||||||
|
static struct clk *mpu_clk;
|
||||||
|
static char *mpu_clk_name;
|
||||||
|
@@ -47,20 +45,9 @@ static struct device *mpu_dev;
|
||||||
|
|
||||||
|
static int omap_verify_speed(struct cpufreq_policy *policy)
|
||||||
|
{
|
||||||
|
- if (freq_table)
|
||||||
|
- return cpufreq_frequency_table_verify(policy, freq_table);
|
||||||
|
-
|
||||||
|
- if (policy->cpu)
|
||||||
|
+ if (!freq_table)
|
||||||
|
return -EINVAL;
|
||||||
|
-
|
||||||
|
- cpufreq_verify_within_limits(policy, policy->cpuinfo.min_freq,
|
||||||
|
- policy->cpuinfo.max_freq);
|
||||||
|
-
|
||||||
|
- policy->min = clk_round_rate(mpu_clk, policy->min * 1000) / 1000;
|
||||||
|
- policy->max = clk_round_rate(mpu_clk, policy->max * 1000) / 1000;
|
||||||
|
- cpufreq_verify_within_limits(policy, policy->cpuinfo.min_freq,
|
||||||
|
- policy->cpuinfo.max_freq);
|
||||||
|
- return 0;
|
||||||
|
+ return cpufreq_frequency_table_verify(policy, freq_table);
|
||||||
|
}
|
||||||
|
|
||||||
|
static unsigned int omap_getspeed(unsigned int cpu)
|
||||||
|
@@ -78,22 +65,35 @@ static int omap_target(struct cpufreq_policy *policy,
|
||||||
|
unsigned int target_freq,
|
||||||
|
unsigned int relation)
|
||||||
|
{
|
||||||
|
- int i, ret = 0;
|
||||||
|
+ unsigned int i;
|
||||||
|
+ int ret = 0;
|
||||||
|
struct cpufreq_freqs freqs;
|
||||||
|
|
||||||
|
/* Changes not allowed until all CPUs are online */
|
||||||
|
if (is_smp() && (num_online_cpus() < NR_CPUS))
|
||||||
|
return ret;
|
||||||
|
|
||||||
|
- /* Ensure desired rate is within allowed range. Some govenors
|
||||||
|
- * (ondemand) will just pass target_freq=0 to get the minimum. */
|
||||||
|
- if (target_freq < policy->min)
|
||||||
|
- target_freq = policy->min;
|
||||||
|
- if (target_freq > policy->max)
|
||||||
|
- target_freq = policy->max;
|
||||||
|
+ if (!freq_table) {
|
||||||
|
+ dev_err(mpu_dev, "%s: cpu%d: no freq table!\n", __func__,
|
||||||
|
+ policy->cpu);
|
||||||
|
+ return -EINVAL;
|
||||||
|
+ }
|
||||||
|
+
|
||||||
|
+ ret = cpufreq_frequency_table_target(policy, freq_table, target_freq,
|
||||||
|
+ relation, &i);
|
||||||
|
+ if (ret) {
|
||||||
|
+ dev_dbg(mpu_dev, "%s: cpu%d: no freq match for %d(ret=%d)\n",
|
||||||
|
+ __func__, policy->cpu, target_freq, ret);
|
||||||
|
+ return ret;
|
||||||
|
+ }
|
||||||
|
+ freqs.new = freq_table[i].frequency;
|
||||||
|
+ if (!freqs.new) {
|
||||||
|
+ dev_err(mpu_dev, "%s: cpu%d: no match for freq %d\n", __func__,
|
||||||
|
+ policy->cpu, target_freq);
|
||||||
|
+ return -EINVAL;
|
||||||
|
+ }
|
||||||
|
|
||||||
|
freqs.old = omap_getspeed(policy->cpu);
|
||||||
|
- freqs.new = clk_round_rate(mpu_clk, target_freq * 1000) / 1000;
|
||||||
|
freqs.cpu = policy->cpu;
|
||||||
|
|
||||||
|
if (freqs.old == freqs.new)
|
||||||
|
@@ -166,19 +166,18 @@ static int __cpuinit omap_cpu_init(struct cpufreq_policy *policy)
|
||||||
|
return -EINVAL;
|
||||||
|
|
||||||
|
policy->cur = policy->min = policy->max = omap_getspeed(policy->cpu);
|
||||||
|
- opp_init_cpufreq_table(mpu_dev, &freq_table);
|
||||||
|
-
|
||||||
|
- if (freq_table) {
|
||||||
|
- result = cpufreq_frequency_table_cpuinfo(policy, freq_table);
|
||||||
|
- if (!result)
|
||||||
|
- cpufreq_frequency_table_get_attr(freq_table,
|
||||||
|
- policy->cpu);
|
||||||
|
- } else {
|
||||||
|
- policy->cpuinfo.min_freq = clk_round_rate(mpu_clk, 0) / 1000;
|
||||||
|
- policy->cpuinfo.max_freq = clk_round_rate(mpu_clk,
|
||||||
|
- VERY_HI_RATE) / 1000;
|
||||||
|
+ result = opp_init_cpufreq_table(mpu_dev, &freq_table);
|
||||||
|
+
|
||||||
|
+ if (result) {
|
||||||
|
+ dev_err(mpu_dev, "%s: cpu%d: failed creating freq table[%d]\n",
|
||||||
|
+ __func__, policy->cpu, result);
|
||||||
|
+ return result;
|
||||||
|
}
|
||||||
|
|
||||||
|
+ result = cpufreq_frequency_table_cpuinfo(policy, freq_table);
|
||||||
|
+ if (!result)
|
||||||
|
+ cpufreq_frequency_table_get_attr(freq_table, policy->cpu);
|
||||||
|
+
|
||||||
|
policy->min = policy->cpuinfo.min_freq;
|
||||||
|
policy->max = policy->cpuinfo.max_freq;
|
||||||
|
policy->cur = omap_getspeed(policy->cpu);
|
||||||
|
--
|
||||||
|
1.6.6.1
|
||||||
|
|
||||||
+46
@@ -0,0 +1,46 @@
|
|||||||
|
From 1e5757cbc79685c6294a178d1bea76a52cffcae9 Mon Sep 17 00:00:00 2001
|
||||||
|
From: Nishanth Menon <nm@ti.com>
|
||||||
|
Date: Thu, 26 May 2011 19:39:18 -0700
|
||||||
|
Subject: [PATCH 13/19] OMAP2+: cpufreq: only supports OPP library
|
||||||
|
|
||||||
|
OMAP2 is the only family using clk_[init|exit]_cpufreq_table, however,
|
||||||
|
the cpufreq code does not currently use clk_init_cpufreq_table. As a
|
||||||
|
result, it is unusuable for OMAP2 and only usable only on platforms
|
||||||
|
using OPP library.
|
||||||
|
|
||||||
|
Remove the unbalanced clk_exit_cpufreq_table(). Any platforms where
|
||||||
|
OPPs are not availble will fail on init because a freq table will not
|
||||||
|
be properly initialized.
|
||||||
|
|
||||||
|
Signed-off-by: Nishanth Menon <nm@ti.com>
|
||||||
|
[khilman@ti.com: changelog edits, and graceful failure mode changes]
|
||||||
|
Acked-by: Kevin Hilman <khilman@ti.com>
|
||||||
|
Signed-off-by: Koen Kooi <koen@dominion.thruhere.net>
|
||||||
|
---
|
||||||
|
arch/arm/mach-omap2/omap2plus-cpufreq.c | 3 +--
|
||||||
|
1 files changed, 1 insertions(+), 2 deletions(-)
|
||||||
|
|
||||||
|
diff --git a/arch/arm/mach-omap2/omap2plus-cpufreq.c b/arch/arm/mach-omap2/omap2plus-cpufreq.c
|
||||||
|
index acf18e8..3af7cda 100644
|
||||||
|
--- a/arch/arm/mach-omap2/omap2plus-cpufreq.c
|
||||||
|
+++ b/arch/arm/mach-omap2/omap2plus-cpufreq.c
|
||||||
|
@@ -1,7 +1,7 @@
|
||||||
|
/*
|
||||||
|
* OMAP2PLUS cpufreq driver
|
||||||
|
*
|
||||||
|
- * CPU frequency scaling for OMAP
|
||||||
|
+ * CPU frequency scaling for OMAP using OPP information
|
||||||
|
*
|
||||||
|
* Copyright (C) 2005 Nokia Corporation
|
||||||
|
* Written by Tony Lindgren <tony@atomide.com>
|
||||||
|
@@ -203,7 +203,6 @@ static int __cpuinit omap_cpu_init(struct cpufreq_policy *policy)
|
||||||
|
|
||||||
|
static int omap_cpu_exit(struct cpufreq_policy *policy)
|
||||||
|
{
|
||||||
|
- clk_exit_cpufreq_table(&freq_table);
|
||||||
|
clk_put(mpu_clk);
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
--
|
||||||
|
1.6.6.1
|
||||||
|
|
||||||
+61
@@ -0,0 +1,61 @@
|
|||||||
|
From bec0338ead64cdd8515ae4c94462ffbfd6ae6418 Mon Sep 17 00:00:00 2001
|
||||||
|
From: Nishanth Menon <nm@ti.com>
|
||||||
|
Date: Thu, 26 May 2011 19:39:19 -0700
|
||||||
|
Subject: [PATCH 14/19] OMAP2+: cpufreq: put clk if cpu_init failed
|
||||||
|
|
||||||
|
Release the mpu_clk in fail paths.
|
||||||
|
|
||||||
|
Reported-by: Todd Poynor <toddpoynor@google.com>
|
||||||
|
Signed-off-by: Nishanth Menon <nm@ti.com>
|
||||||
|
Signed-off-by: Koen Kooi <koen@dominion.thruhere.net>
|
||||||
|
---
|
||||||
|
arch/arm/mach-omap2/omap2plus-cpufreq.c | 14 +++++++++++---
|
||||||
|
1 files changed, 11 insertions(+), 3 deletions(-)
|
||||||
|
|
||||||
|
diff --git a/arch/arm/mach-omap2/omap2plus-cpufreq.c b/arch/arm/mach-omap2/omap2plus-cpufreq.c
|
||||||
|
index 3af7cda..e019297 100644
|
||||||
|
--- a/arch/arm/mach-omap2/omap2plus-cpufreq.c
|
||||||
|
+++ b/arch/arm/mach-omap2/omap2plus-cpufreq.c
|
||||||
|
@@ -162,8 +162,10 @@ static int __cpuinit omap_cpu_init(struct cpufreq_policy *policy)
|
||||||
|
if (IS_ERR(mpu_clk))
|
||||||
|
return PTR_ERR(mpu_clk);
|
||||||
|
|
||||||
|
- if (policy->cpu >= NR_CPUS)
|
||||||
|
- return -EINVAL;
|
||||||
|
+ if (policy->cpu >= NR_CPUS) {
|
||||||
|
+ result = -EINVAL;
|
||||||
|
+ goto fail_ck;
|
||||||
|
+ }
|
||||||
|
|
||||||
|
policy->cur = policy->min = policy->max = omap_getspeed(policy->cpu);
|
||||||
|
result = opp_init_cpufreq_table(mpu_dev, &freq_table);
|
||||||
|
@@ -171,12 +173,14 @@ static int __cpuinit omap_cpu_init(struct cpufreq_policy *policy)
|
||||||
|
if (result) {
|
||||||
|
dev_err(mpu_dev, "%s: cpu%d: failed creating freq table[%d]\n",
|
||||||
|
__func__, policy->cpu, result);
|
||||||
|
- return result;
|
||||||
|
+ goto fail_ck;
|
||||||
|
}
|
||||||
|
|
||||||
|
result = cpufreq_frequency_table_cpuinfo(policy, freq_table);
|
||||||
|
if (!result)
|
||||||
|
cpufreq_frequency_table_get_attr(freq_table, policy->cpu);
|
||||||
|
+ else
|
||||||
|
+ goto fail_ck;
|
||||||
|
|
||||||
|
policy->min = policy->cpuinfo.min_freq;
|
||||||
|
policy->max = policy->cpuinfo.max_freq;
|
||||||
|
@@ -199,6 +203,10 @@ static int __cpuinit omap_cpu_init(struct cpufreq_policy *policy)
|
||||||
|
policy->cpuinfo.transition_latency = 300 * 1000;
|
||||||
|
|
||||||
|
return 0;
|
||||||
|
+
|
||||||
|
+fail_ck:
|
||||||
|
+ clk_put(mpu_clk);
|
||||||
|
+ return result;
|
||||||
|
}
|
||||||
|
|
||||||
|
static int omap_cpu_exit(struct cpufreq_policy *policy)
|
||||||
|
--
|
||||||
|
1.6.6.1
|
||||||
|
|
||||||
+90
@@ -0,0 +1,90 @@
|
|||||||
|
From 0054f5049a4e65a359eca6fa8c6668fb047c9270 Mon Sep 17 00:00:00 2001
|
||||||
|
From: Nishanth Menon <nm@ti.com>
|
||||||
|
Date: Thu, 26 May 2011 19:39:20 -0700
|
||||||
|
Subject: [PATCH 15/19] OMAP2+: cpufreq: fix freq_table leak
|
||||||
|
|
||||||
|
We use a single frequency table for multiple CPUs. But, with
|
||||||
|
OMAP4, since we have multiple CPUs, the cpu_init call for CPU1
|
||||||
|
causes freq_table previously allocated for CPU0 to be overwritten.
|
||||||
|
In addition, we dont free the table on exit path.
|
||||||
|
|
||||||
|
We solve this by maintaining an atomic type counter to ensure
|
||||||
|
just a single table exists at a given time.
|
||||||
|
|
||||||
|
Signed-off-by: Nishanth Menon <nm@ti.com>
|
||||||
|
Signed-off-by: Koen Kooi <koen@dominion.thruhere.net>
|
||||||
|
---
|
||||||
|
arch/arm/mach-omap2/omap2plus-cpufreq.c | 22 +++++++++++++++++-----
|
||||||
|
1 files changed, 17 insertions(+), 5 deletions(-)
|
||||||
|
|
||||||
|
diff --git a/arch/arm/mach-omap2/omap2plus-cpufreq.c b/arch/arm/mach-omap2/omap2plus-cpufreq.c
|
||||||
|
index e019297..a962a31 100644
|
||||||
|
--- a/arch/arm/mach-omap2/omap2plus-cpufreq.c
|
||||||
|
+++ b/arch/arm/mach-omap2/omap2plus-cpufreq.c
|
||||||
|
@@ -39,6 +39,7 @@
|
||||||
|
#include <mach/hardware.h>
|
||||||
|
|
||||||
|
static struct cpufreq_frequency_table *freq_table;
|
||||||
|
+static atomic_t freq_table_users = ATOMIC_INIT(0);
|
||||||
|
static struct clk *mpu_clk;
|
||||||
|
static char *mpu_clk_name;
|
||||||
|
static struct device *mpu_dev;
|
||||||
|
@@ -153,6 +154,12 @@ skip_lpj:
|
||||||
|
return ret;
|
||||||
|
}
|
||||||
|
|
||||||
|
+static inline void freq_table_free(void)
|
||||||
|
+{
|
||||||
|
+ if (atomic_dec_and_test(&freq_table_users))
|
||||||
|
+ opp_free_cpufreq_table(mpu_dev, &freq_table);
|
||||||
|
+}
|
||||||
|
+
|
||||||
|
static int __cpuinit omap_cpu_init(struct cpufreq_policy *policy)
|
||||||
|
{
|
||||||
|
int result = 0;
|
||||||
|
@@ -168,7 +175,9 @@ static int __cpuinit omap_cpu_init(struct cpufreq_policy *policy)
|
||||||
|
}
|
||||||
|
|
||||||
|
policy->cur = policy->min = policy->max = omap_getspeed(policy->cpu);
|
||||||
|
- result = opp_init_cpufreq_table(mpu_dev, &freq_table);
|
||||||
|
+
|
||||||
|
+ if (atomic_inc_return(&freq_table_users) == 1)
|
||||||
|
+ result = opp_init_cpufreq_table(mpu_dev, &freq_table);
|
||||||
|
|
||||||
|
if (result) {
|
||||||
|
dev_err(mpu_dev, "%s: cpu%d: failed creating freq table[%d]\n",
|
||||||
|
@@ -177,10 +186,10 @@ static int __cpuinit omap_cpu_init(struct cpufreq_policy *policy)
|
||||||
|
}
|
||||||
|
|
||||||
|
result = cpufreq_frequency_table_cpuinfo(policy, freq_table);
|
||||||
|
- if (!result)
|
||||||
|
- cpufreq_frequency_table_get_attr(freq_table, policy->cpu);
|
||||||
|
- else
|
||||||
|
- goto fail_ck;
|
||||||
|
+ if (result)
|
||||||
|
+ goto fail_table;
|
||||||
|
+
|
||||||
|
+ cpufreq_frequency_table_get_attr(freq_table, policy->cpu);
|
||||||
|
|
||||||
|
policy->min = policy->cpuinfo.min_freq;
|
||||||
|
policy->max = policy->cpuinfo.max_freq;
|
||||||
|
@@ -204,6 +213,8 @@ static int __cpuinit omap_cpu_init(struct cpufreq_policy *policy)
|
||||||
|
|
||||||
|
return 0;
|
||||||
|
|
||||||
|
+fail_table:
|
||||||
|
+ freq_table_free();
|
||||||
|
fail_ck:
|
||||||
|
clk_put(mpu_clk);
|
||||||
|
return result;
|
||||||
|
@@ -211,6 +222,7 @@ fail_ck:
|
||||||
|
|
||||||
|
static int omap_cpu_exit(struct cpufreq_policy *policy)
|
||||||
|
{
|
||||||
|
+ freq_table_free();
|
||||||
|
clk_put(mpu_clk);
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
--
|
||||||
|
1.6.6.1
|
||||||
|
|
||||||
+58
@@ -0,0 +1,58 @@
|
|||||||
|
From 255f1830ab71e130bbdffd84e61fc7a8c3791120 Mon Sep 17 00:00:00 2001
|
||||||
|
From: Santosh Shilimkar <santosh.shilimkar@ti.com>
|
||||||
|
Date: Fri, 3 Jun 2011 17:46:57 +0530
|
||||||
|
Subject: [PATCH 16/19] OMAP2+: CPUfreq: Remove superfluous check in target() for online CPU's.
|
||||||
|
|
||||||
|
Current OMAP2PLUS CPUfreq tagret() functions returns when all
|
||||||
|
the CPU's are not online. This breaks CPUfreq when secondary CPUs
|
||||||
|
are offlined on SMP system.
|
||||||
|
|
||||||
|
The intention of that check was just avoid CPU frequency change
|
||||||
|
during the window when CPU becomes online but it's cpufreq_init is
|
||||||
|
not done yet. Otherwise it can lead to notifiers being sent on
|
||||||
|
a CPU which is not yet registered to the governor.
|
||||||
|
|
||||||
|
But this race conditions is already managed by the CPUfreq
|
||||||
|
core driver by updating the available cpumask accordingly.
|
||||||
|
|
||||||
|
OMAP CPUFReq driver make use same cpumask for the notifiers
|
||||||
|
so the above problem doesn't exist. In my initial implementation
|
||||||
|
of the OMAP4 CPUFreq driver, I was using 'for_each_online_cpu()'
|
||||||
|
for notifiers which lead me to add that check. Later I fixed
|
||||||
|
the notifies but didn't realise that the check has become
|
||||||
|
redundant then.
|
||||||
|
|
||||||
|
Fix it by removing the superfluous check in target().
|
||||||
|
|
||||||
|
Thanks for Nishant Menon <nm@ti.com> for reporting issue
|
||||||
|
with hot-plug and Kevin Hilman <khilman@ti.com> for his
|
||||||
|
comment on excessive check in target().
|
||||||
|
|
||||||
|
Signed-off-by: Santosh Shilimkar <santosh.shilimkar@ti.com>
|
||||||
|
Reported-by: Nishanth Menon <nm@ti.com>
|
||||||
|
Tested-by: Vishwanath BS <vishwanath.bs@ti.com>
|
||||||
|
Cc: Kevin Hilman <khilman@ti.com>
|
||||||
|
Tested-by: Nishanth Menon <nm@ti.com>
|
||||||
|
Signed-off-by: Koen Kooi <koen@dominion.thruhere.net>
|
||||||
|
---
|
||||||
|
arch/arm/mach-omap2/omap2plus-cpufreq.c | 4 ----
|
||||||
|
1 files changed, 0 insertions(+), 4 deletions(-)
|
||||||
|
|
||||||
|
diff --git a/arch/arm/mach-omap2/omap2plus-cpufreq.c b/arch/arm/mach-omap2/omap2plus-cpufreq.c
|
||||||
|
index a962a31..eaefa49 100644
|
||||||
|
--- a/arch/arm/mach-omap2/omap2plus-cpufreq.c
|
||||||
|
+++ b/arch/arm/mach-omap2/omap2plus-cpufreq.c
|
||||||
|
@@ -70,10 +70,6 @@ static int omap_target(struct cpufreq_policy *policy,
|
||||||
|
int ret = 0;
|
||||||
|
struct cpufreq_freqs freqs;
|
||||||
|
|
||||||
|
- /* Changes not allowed until all CPUs are online */
|
||||||
|
- if (is_smp() && (num_online_cpus() < NR_CPUS))
|
||||||
|
- return ret;
|
||||||
|
-
|
||||||
|
if (!freq_table) {
|
||||||
|
dev_err(mpu_dev, "%s: cpu%d: no freq table!\n", __func__,
|
||||||
|
policy->cpu);
|
||||||
|
--
|
||||||
|
1.6.6.1
|
||||||
|
|
||||||
+48
@@ -0,0 +1,48 @@
|
|||||||
|
From 3bf92d672cb3ee7c1ec39f1f0fcf6e8dbde2ceb9 Mon Sep 17 00:00:00 2001
|
||||||
|
From: Colin Cross <ccross@google.com>
|
||||||
|
Date: Mon, 6 Jun 2011 21:05:29 -0500
|
||||||
|
Subject: [PATCH 17/19] OMAP2+: cpufreq: notify even with bad boot frequency
|
||||||
|
|
||||||
|
Sometimes, bootloaders starts up with a frequency which is not
|
||||||
|
in the OPP table. At cpu_init, policy->cur contains the frequency
|
||||||
|
we pick at boot. It is possible that system might have fixed
|
||||||
|
it's boot frequency later on as part of power initialization.
|
||||||
|
After this condition, the first call to omap_target results in the
|
||||||
|
following:
|
||||||
|
|
||||||
|
omap_getspeed(actual device frequency) != policy->cur(frequency that
|
||||||
|
cpufreq thinks that the system is at), and it is possible that
|
||||||
|
freqs.old == freqs.new (because the governor requested a scale down).
|
||||||
|
|
||||||
|
We exit without triggering the notifiers in the current code, which
|
||||||
|
does'nt let code which depends on cpufreq_notify_transition to have
|
||||||
|
accurate information as to what the system frequency is.
|
||||||
|
|
||||||
|
Instead, we do a normal transition if policy->cur is wrong, then,
|
||||||
|
freqs.old will be the actual cpu frequency, freqs.new will be the
|
||||||
|
actual new cpu frequency and all required notifiers have the accurate
|
||||||
|
information.
|
||||||
|
|
||||||
|
Acked-by: Nishanth Menon <nm@ti.com>
|
||||||
|
Signed-off-by: Colin Cross <ccross@google.com>
|
||||||
|
Signed-off-by: Koen Kooi <koen@dominion.thruhere.net>
|
||||||
|
---
|
||||||
|
arch/arm/mach-omap2/omap2plus-cpufreq.c | 2 +-
|
||||||
|
1 files changed, 1 insertions(+), 1 deletions(-)
|
||||||
|
|
||||||
|
diff --git a/arch/arm/mach-omap2/omap2plus-cpufreq.c b/arch/arm/mach-omap2/omap2plus-cpufreq.c
|
||||||
|
index eaefa49..8598928 100644
|
||||||
|
--- a/arch/arm/mach-omap2/omap2plus-cpufreq.c
|
||||||
|
+++ b/arch/arm/mach-omap2/omap2plus-cpufreq.c
|
||||||
|
@@ -93,7 +93,7 @@ static int omap_target(struct cpufreq_policy *policy,
|
||||||
|
freqs.old = omap_getspeed(policy->cpu);
|
||||||
|
freqs.cpu = policy->cpu;
|
||||||
|
|
||||||
|
- if (freqs.old == freqs.new)
|
||||||
|
+ if (freqs.old == freqs.new && policy->cur == freqs.new)
|
||||||
|
return ret;
|
||||||
|
|
||||||
|
if (!is_smp()) {
|
||||||
|
--
|
||||||
|
1.6.6.1
|
||||||
|
|
||||||
+42
@@ -0,0 +1,42 @@
|
|||||||
|
From 6e092f78e67d722be6036131df6aa0b8b2fec879 Mon Sep 17 00:00:00 2001
|
||||||
|
From: Todd Poynor <toddpoynor@google.com>
|
||||||
|
Date: Tue, 7 Jun 2011 13:57:52 -0700
|
||||||
|
Subject: [PATCH 18/19] OMAP2+: cpufreq: Enable all CPUs in shared policy mask
|
||||||
|
|
||||||
|
Enable all CPUs in the shared policy in the CPU init callback.
|
||||||
|
Otherwise, the governor CPUFREQ_GOV_START event is invoked with
|
||||||
|
a policy that only includes the first CPU, leaving other CPUs
|
||||||
|
uninitialized by the governor.
|
||||||
|
|
||||||
|
Signed-off-by: Todd Poynor <toddpoynor@google.com>
|
||||||
|
Acked-by: Santosh Shilimkar <santosh.shilimkar@ti.com>
|
||||||
|
Signed-off-by: Koen Kooi <koen@dominion.thruhere.net>
|
||||||
|
---
|
||||||
|
arch/arm/mach-omap2/omap2plus-cpufreq.c | 4 +---
|
||||||
|
1 files changed, 1 insertions(+), 3 deletions(-)
|
||||||
|
|
||||||
|
diff --git a/arch/arm/mach-omap2/omap2plus-cpufreq.c b/arch/arm/mach-omap2/omap2plus-cpufreq.c
|
||||||
|
index 8598928..1f3b2e1 100644
|
||||||
|
--- a/arch/arm/mach-omap2/omap2plus-cpufreq.c
|
||||||
|
+++ b/arch/arm/mach-omap2/omap2plus-cpufreq.c
|
||||||
|
@@ -159,7 +159,6 @@ static inline void freq_table_free(void)
|
||||||
|
static int __cpuinit omap_cpu_init(struct cpufreq_policy *policy)
|
||||||
|
{
|
||||||
|
int result = 0;
|
||||||
|
- static cpumask_var_t cpumask;
|
||||||
|
|
||||||
|
mpu_clk = clk_get(NULL, mpu_clk_name);
|
||||||
|
if (IS_ERR(mpu_clk))
|
||||||
|
@@ -200,8 +199,7 @@ static int __cpuinit omap_cpu_init(struct cpufreq_policy *policy)
|
||||||
|
*/
|
||||||
|
if (is_smp()) {
|
||||||
|
policy->shared_type = CPUFREQ_SHARED_TYPE_ANY;
|
||||||
|
- cpumask_or(cpumask, cpumask_of(policy->cpu), cpumask);
|
||||||
|
- cpumask_copy(policy->cpus, cpumask);
|
||||||
|
+ cpumask_setall(policy->cpus);
|
||||||
|
}
|
||||||
|
|
||||||
|
/* FIXME: what's the actual transition time? */
|
||||||
|
--
|
||||||
|
1.6.6.1
|
||||||
|
|
||||||
+121
@@ -0,0 +1,121 @@
|
|||||||
|
From e8fa6ffc7822b7c7e81fafb112f3064f31c5c0e3 Mon Sep 17 00:00:00 2001
|
||||||
|
From: Russell King <rmk+kernel@arm.linux.org.uk>
|
||||||
|
Date: Mon, 11 Jul 2011 23:10:04 +0530
|
||||||
|
Subject: [PATCH 19/19] OMAP2+: CPUfreq: update lpj with reference value to avoid progressive error.
|
||||||
|
|
||||||
|
Adjust _both_ the per-cpu loops_per_jiffy and global lpj. Calibrate them
|
||||||
|
with with reference to the initial values to avoid a progressively
|
||||||
|
bigger and bigger error in the value over time.
|
||||||
|
|
||||||
|
While at this, re-use the notifiers for UP/SMP since on
|
||||||
|
UP machine or UP_ON_SMP policy->cpus mask would contain only
|
||||||
|
the boot CPU.
|
||||||
|
|
||||||
|
Signed-off-by: Santosh Shilimkar <santosh.shilimkar@ti.com>
|
||||||
|
[santosh.shilimkar@ti.com: re-based against omap cpufreq
|
||||||
|
upstream branch and fixed notifiers]
|
||||||
|
Signed-off-by: Russell King <rmk+kernel@arm.linux.org.uk>
|
||||||
|
Cc: Kevin Hilman <khilman@ti.com>
|
||||||
|
Signed-off-by: Koen Kooi <koen@dominion.thruhere.net>
|
||||||
|
---
|
||||||
|
arch/arm/mach-omap2/omap2plus-cpufreq.c | 50 ++++++++++++++++--------------
|
||||||
|
1 files changed, 27 insertions(+), 23 deletions(-)
|
||||||
|
|
||||||
|
diff --git a/arch/arm/mach-omap2/omap2plus-cpufreq.c b/arch/arm/mach-omap2/omap2plus-cpufreq.c
|
||||||
|
index 1f3b2e1..de82e87 100644
|
||||||
|
--- a/arch/arm/mach-omap2/omap2plus-cpufreq.c
|
||||||
|
+++ b/arch/arm/mach-omap2/omap2plus-cpufreq.c
|
||||||
|
@@ -38,6 +38,16 @@
|
||||||
|
|
||||||
|
#include <mach/hardware.h>
|
||||||
|
|
||||||
|
+#ifdef CONFIG_SMP
|
||||||
|
+struct lpj_info {
|
||||||
|
+ unsigned long ref;
|
||||||
|
+ unsigned int freq;
|
||||||
|
+};
|
||||||
|
+
|
||||||
|
+static DEFINE_PER_CPU(struct lpj_info, lpj_ref);
|
||||||
|
+static struct lpj_info global_lpj_ref;
|
||||||
|
+#endif
|
||||||
|
+
|
||||||
|
static struct cpufreq_frequency_table *freq_table;
|
||||||
|
static atomic_t freq_table_users = ATOMIC_INIT(0);
|
||||||
|
static struct clk *mpu_clk;
|
||||||
|
@@ -96,37 +106,18 @@ static int omap_target(struct cpufreq_policy *policy,
|
||||||
|
if (freqs.old == freqs.new && policy->cur == freqs.new)
|
||||||
|
return ret;
|
||||||
|
|
||||||
|
- if (!is_smp()) {
|
||||||
|
- cpufreq_notify_transition(&freqs, CPUFREQ_PRECHANGE);
|
||||||
|
- goto set_freq;
|
||||||
|
- }
|
||||||
|
-
|
||||||
|
/* notifiers */
|
||||||
|
for_each_cpu(i, policy->cpus) {
|
||||||
|
freqs.cpu = i;
|
||||||
|
cpufreq_notify_transition(&freqs, CPUFREQ_PRECHANGE);
|
||||||
|
}
|
||||||
|
|
||||||
|
-set_freq:
|
||||||
|
#ifdef CONFIG_CPU_FREQ_DEBUG
|
||||||
|
pr_info("cpufreq-omap: transition: %u --> %u\n", freqs.old, freqs.new);
|
||||||
|
#endif
|
||||||
|
|
||||||
|
ret = clk_set_rate(mpu_clk, freqs.new * 1000);
|
||||||
|
-
|
||||||
|
- /*
|
||||||
|
- * Generic CPUFREQ driver jiffy update is under !SMP. So jiffies
|
||||||
|
- * won't get updated when UP machine cpufreq build with
|
||||||
|
- * CONFIG_SMP enabled. Below code is added only to manage that
|
||||||
|
- * scenario
|
||||||
|
- */
|
||||||
|
freqs.new = omap_getspeed(policy->cpu);
|
||||||
|
- if (!is_smp()) {
|
||||||
|
- loops_per_jiffy =
|
||||||
|
- cpufreq_scale(loops_per_jiffy, freqs.old, freqs.new);
|
||||||
|
- cpufreq_notify_transition(&freqs, CPUFREQ_POSTCHANGE);
|
||||||
|
- goto skip_lpj;
|
||||||
|
- }
|
||||||
|
|
||||||
|
#ifdef CONFIG_SMP
|
||||||
|
/*
|
||||||
|
@@ -134,10 +125,24 @@ set_freq:
|
||||||
|
* cpufreq driver. So, update the per-CPU loops_per_jiffy value
|
||||||
|
* on frequency transition. We need to update all dependent CPUs.
|
||||||
|
*/
|
||||||
|
- for_each_cpu(i, policy->cpus)
|
||||||
|
+ for_each_cpu(i, policy->cpus) {
|
||||||
|
+ struct lpj_info *lpj = &per_cpu(lpj_ref, i);
|
||||||
|
+ if (!lpj->freq) {
|
||||||
|
+ lpj->ref = per_cpu(cpu_data, i).loops_per_jiffy;
|
||||||
|
+ lpj->freq = freqs.old;
|
||||||
|
+ }
|
||||||
|
+
|
||||||
|
per_cpu(cpu_data, i).loops_per_jiffy =
|
||||||
|
- cpufreq_scale(per_cpu(cpu_data, i).loops_per_jiffy,
|
||||||
|
- freqs.old, freqs.new);
|
||||||
|
+ cpufreq_scale(lpj->ref, lpj->freq, freqs.new);
|
||||||
|
+ }
|
||||||
|
+
|
||||||
|
+ /* And don't forget to adjust the global one */
|
||||||
|
+ if (!global_lpj_ref.freq) {
|
||||||
|
+ global_lpj_ref.ref = loops_per_jiffy;
|
||||||
|
+ global_lpj_ref.freq = freqs.old;
|
||||||
|
+ }
|
||||||
|
+ loops_per_jiffy = cpufreq_scale(global_lpj_ref.ref, global_lpj_ref.freq,
|
||||||
|
+ freqs.new);
|
||||||
|
#endif
|
||||||
|
|
||||||
|
/* notifiers */
|
||||||
|
@@ -146,7 +151,6 @@ set_freq:
|
||||||
|
cpufreq_notify_transition(&freqs, CPUFREQ_POSTCHANGE);
|
||||||
|
}
|
||||||
|
|
||||||
|
-skip_lpj:
|
||||||
|
return ret;
|
||||||
|
}
|
||||||
|
|
||||||
|
--
|
||||||
|
1.6.6.1
|
||||||
|
|
||||||
File diff suppressed because it is too large
Load Diff
@@ -0,0 +1,51 @@
|
|||||||
|
require linux.inc
|
||||||
|
|
||||||
|
DESCRIPTION = "Linux kernel for TI processors"
|
||||||
|
KERNEL_IMAGETYPE = "uImage"
|
||||||
|
|
||||||
|
COMPATIBLE_MACHINE = "(beagleboard)"
|
||||||
|
|
||||||
|
# Somewhere after 3.0rc7
|
||||||
|
SRCREV_pn-${PN} = "e6625fa48e6580a74b7e700efd7e6463e282810b"
|
||||||
|
|
||||||
|
|
||||||
|
# The main PR is now using MACHINE_KERNEL_PR, for omap3 see conf/machine/include/omap3.inc
|
||||||
|
MACHINE_KERNEL_PR_append = "a"
|
||||||
|
|
||||||
|
FILESPATHPKG_prepend = "linux-3.0:"
|
||||||
|
|
||||||
|
SRC_URI += "git://git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git;protocol=git \
|
||||||
|
file://beagle/0001-OMAP3-beagle-add-support-for-beagleboard-xM-revision.patch \
|
||||||
|
file://pm-wip/cpufreq/0001-PM-OPP-introduce-function-to-free-cpufreq-table.patch \
|
||||||
|
file://pm-wip/cpufreq/0002-OMAP-CPUfreq-ensure-driver-initializes-after-cpufreq.patch \
|
||||||
|
file://pm-wip/cpufreq/0003-OMAP-CPUfreq-ensure-policy-is-fully-initialized.patch \
|
||||||
|
file://pm-wip/cpufreq/0004-OMAP3-PM-CPUFreq-driver-for-OMAP3.patch \
|
||||||
|
file://pm-wip/cpufreq/0005-OMAP-PM-CPUFREQ-Fix-conditional-compilation.patch \
|
||||||
|
file://pm-wip/cpufreq/0006-cpufreq-fixup-after-new-OPP-layer-merged.patch \
|
||||||
|
file://pm-wip/cpufreq/0007-OMAP-cpufreq-Split-OMAP1-and-OMAP2PLUS-CPUfreq-drive.patch \
|
||||||
|
file://pm-wip/cpufreq/0008-OMAP2PLUS-cpufreq-Add-SMP-support-to-cater-OMAP4430.patch \
|
||||||
|
file://pm-wip/cpufreq/0009-OMAP2PLUS-cpufreq-Fix-typo-when-attempting-to-set-mp.patch \
|
||||||
|
file://pm-wip/cpufreq/0010-OMAP2-cpufreq-move-clk-name-decision-to-init.patch \
|
||||||
|
file://pm-wip/cpufreq/0011-OMAP2-cpufreq-deny-initialization-if-no-mpudev.patch \
|
||||||
|
file://pm-wip/cpufreq/0012-OMAP2-cpufreq-dont-support-freq_table.patch \
|
||||||
|
file://pm-wip/cpufreq/0013-OMAP2-cpufreq-only-supports-OPP-library.patch \
|
||||||
|
file://pm-wip/cpufreq/0014-OMAP2-cpufreq-put-clk-if-cpu_init-failed.patch \
|
||||||
|
file://pm-wip/cpufreq/0015-OMAP2-cpufreq-fix-freq_table-leak.patch \
|
||||||
|
file://pm-wip/cpufreq/0016-OMAP2-CPUfreq-Remove-superfluous-check-in-target-for.patch \
|
||||||
|
file://pm-wip/cpufreq/0017-OMAP2-cpufreq-notify-even-with-bad-boot-frequency.patch \
|
||||||
|
file://pm-wip/cpufreq/0018-OMAP2-cpufreq-Enable-all-CPUs-in-shared-policy-mask.patch \
|
||||||
|
file://pm-wip/cpufreq/0019-OMAP2-CPUfreq-update-lpj-with-reference-value-to-avo.patch \
|
||||||
|
file://for_3.1/pm-misc/0001-OMAP3-SR-disable-interrupt-by-default.patch \
|
||||||
|
file://for_3.1/pm-misc/0002-OMAP3-SR-enable-disable-SR-only-on-need.patch \
|
||||||
|
file://for_3.1/pm-misc/0003-OMAP3-SR-fix-cosmetic-indentation.patch \
|
||||||
|
file://for_3.1/pm-misc/0004-OMAP3-PM-debug-remove-sleep_while_idle-feature.patch \
|
||||||
|
file://for_3.1/pm-misc/0005-OMAP2-PM-debug-remove-register-dumping.patch \
|
||||||
|
file://for_3.1/pm-misc/0006-OMAP3-PM-debug-remove-register-dumping.patch \
|
||||||
|
file://for_3.1/pm-misc/0007-OMAP2-PM-fix-section-mismatch-in-pm_dbg_init.patch \
|
||||||
|
file://defconfig"
|
||||||
|
|
||||||
|
SRC_URI_append_beagleboard = " file://logo_linux_clut224.ppm \
|
||||||
|
"
|
||||||
|
|
||||||
|
S = "${WORKDIR}/git"
|
||||||
|
|
||||||
Reference in New Issue
Block a user