* [PATCH v2] ARM: Thumb-2: Reflect ARM/Thumb-2 configuration in module vermagic
From: Dave Martin @ 2011-02-25 18:18 UTC (permalink / raw)
To: linux-arm-kernel
In-Reply-To: <4D67EC9F.8010305@ru.mvista.com>
On Fri, Feb 25, 2011 at 5:53 PM, Sergei Shtylyov <sshtylyov@mvista.com> wrote:
> Hello.
>
> Dave Martin wrote:
>
>>>> Loading Thumb-2 modules into an ARM kernel or vice-versa isn't
>>>> guaranteed to work safely, since the kernel is not interworking-
>>>> aware everywhere.
>>>> This patch adds "thumb2" to the module vermagic when
>>>> CONFIG_THUMB2_KERNEL is enabled, to help avoid accidental loading
>>>> of modules into the wrong kernel.
>>>> v2: modified to apply consistently on top of rmk's p2v branch.
>
>>> ?Patch changelog should follow the -- tearline.
>
>>>> Signed-off-by: Dave Martin<dave.martin@linaro.org>
>>>> Acked-by: Nicolas Pitre<nicolas.pitre@linaro.org>
>
> ?> Opinions seem to differ... I have no strong opinion on this myself.
>
> ? At least that's what Documentation/SubmittingPatches suggests:
>
> <<
> One good use for the additional comments after the "---" marker is for
> a diffstat, to show what files have changed, and the number of
> inserted and deleted lines per file. ?A diffstat is especially useful
> on bigger patches. ?Other comments relevant only to the moment or the
> maintainer, not suitable for the permanent changelog, should also go
> here. ?A good example of such comments might be "patch changelogs"
> which describe what has changed between the v1 and v2 version of the
> patch.
Fair enough. Doesn't sounds like a inflexible rule all the same, but
when the history ceases to be relevant when the patch is merged
upstream (as in my case) is may be better to do as you suggest. I
agree with Grant that it may sometimes be useful to preserve some of
this information in the final commit for more complex/subtle cases,
though.
I normally tidy up the cruft before sending a patch to Russell's patch
system in any case.
Cheers
---Dave
^ permalink raw reply
* [PATCH] OMAP4: PandaBoard: Adding DVI support
From: Jan, Sebastien @ 2011-02-25 18:57 UTC (permalink / raw)
To: linux-arm-kernel
In-Reply-To: <F55C15BA-2C89-4DB7-9930-5176AA72C2A7@dominion.thruhere.net>
On Fri, Feb 11, 2011 at 4:38 PM, Koen Kooi <koen@dominion.thruhere.net> wrote:
>> I fetched this branch which contains 35 patches on top of 2.6.38-rc4.
>> After fixing some conflict, I applied these 35 patches on our Ubuntu
>> ti-omap-dev kernel. With built-in the DSS2 driver and GENERIC_DPI
>> driver, kernel boots fine on my Panda with Ubuntu GUI. But I have to
>> set the kernel boot command args with omapfb.mode=dvi:1024x768MR-24 at 60
>> omapdss.def_disp=dvi, pointed out by Sebastien. Without this bootargs,
>> no graphic at all. so as Robert concerned, EDID detection doesn't
>> work. Does that related to I2C driver? I2C driver always tell me
>> timeout in dmesg.
>
> AIUI the i2c bus is only hooked up to the HDMI port, so unless you plug in something there, no dice.
Are you sure? According to the pandaboard user manual, there seem to
be an i2c connection (i2c3): page 31, fig 9:
http://pandaboard.org/sites/default/files/board_reference/A1/Panda_Board_Spec_DOC-21010_REV0_6.pdf
^ permalink raw reply
* [PATCH v2 2/2] msm: add single-wire serial bus interface (SSBI) driver
From: David Brown @ 2011-02-25 19:00 UTC (permalink / raw)
To: linux-arm-kernel
In-Reply-To: <1298600621.17118.27.camel@m0nster>
On Thu, Feb 24 2011, Daniel Walker wrote:
>> Based on a patch by Dima Zavin <dima@android.com> that can be found at:
>> http://android.git.kernel.org/?p=kernel/msm.git;a=commitdiff;h=eb060bac4
>
> I don't really like links in the commit text, cause as soon as Google
> deletes this tree the link is worthless.
I'm not sure how to better convey the information. The tree is at least
on kernel.org, and there's good useful information there that works
now. Links in commit text seem fairly common.
I think it is helpful to demonstrate that Ken is trying to be diligent
about indicating where the code comes from.
Thanks,
David
--
Sent by an employee of the Qualcomm Innovation Center, Inc.
The Qualcomm Innovation Center, Inc. is a member of the Code Aurora Forum.
^ permalink raw reply
* [PATCH 1/4] msm: scm: Mark inline asm as volatile
From: Stephen Boyd @ 2011-02-25 19:05 UTC (permalink / raw)
To: linux-arm-kernel
In-Reply-To: <1298635017.958.0.camel@e102144-lin.cambridge.arm.com>
On 02/25/2011 03:56 AM, Will Deacon wrote:
> Hi Stephen,
>
> On Thu, 2011-02-24 at 18:44 +0000, Stephen Boyd wrote:
>> We don't want the compiler to remove these asm statements or
>> reorder them in any way. Mark them as volatile to be sure.
>>
>> Signed-off-by: Stephen Boyd <sboyd@codeaurora.org>
>> ---
>> arch/arm/mach-msm/scm.c | 4 ++--
>> 1 files changed, 2 insertions(+), 2 deletions(-)
>>
>> diff --git a/arch/arm/mach-msm/scm.c b/arch/arm/mach-msm/scm.c
>> index f4b9bc9..ba57b5a 100644
>> --- a/arch/arm/mach-msm/scm.c
>> +++ b/arch/arm/mach-msm/scm.c
>> @@ -174,7 +174,7 @@ static u32 smc(u32 cmd_addr)
>> register u32 r0 asm("r0") = 1;
>> register u32 r1 asm("r1") = (u32)&context_id;
>> register u32 r2 asm("r2") = cmd_addr;
>> - asm(
>> + asm volatile(
>> __asmeq("%0", "r0")
>> __asmeq("%1", "r0")
>> __asmeq("%2", "r1")
>> @@ -271,7 +271,7 @@ u32 scm_get_version(void)
>> return version;
>>
>> mutex_lock(&scm_lock);
>> - asm(
>> + asm volatile(
>> __asmeq("%0", "r1")
>> __asmeq("%1", "r0")
>> __asmeq("%2", "r1")
>
>
> These asm blocks all have sensible looking output constraints. Why
> do they need to be marked volatile?
I'm not seeing any different code with or without this so I saw little
harm in marking them as volatile. I really don't want the compiler
moving them or deleting them so it seemed safer to just mark it volatile
to make sure nothing happens to the smc instructions.
--
Sent by an employee of the Qualcomm Innovation Center, Inc.
The Qualcomm Innovation Center, Inc. is a member of the Code Aurora Forum.
^ permalink raw reply
* [PATCH 2/4] msm: scm: Fix improper register assignment
From: Stephen Boyd @ 2011-02-25 19:22 UTC (permalink / raw)
To: linux-arm-kernel
In-Reply-To: <1298640219.958.74.camel@e102144-lin.cambridge.arm.com>
On 02/25/2011 05:23 AM, Will Deacon wrote:
> On Thu, 2011-02-24 at 18:44 +0000, Stephen Boyd wrote:
>> Assign the registers used in the inline assembly immediately
>> before the inline assembly block. This ensures the compiler
>> doesn't optimize away dead register assignments when it
>> shouldn't.
>>
>> Signed-off-by: Stephen Boyd <sboyd@codeaurora.org>
>> ---
>> arch/arm/mach-msm/scm.c | 7 +++++--
>> 1 files changed, 5 insertions(+), 2 deletions(-)
>>
>> diff --git a/arch/arm/mach-msm/scm.c b/arch/arm/mach-msm/scm.c
>> index ba57b5a..5eddf54 100644
>> --- a/arch/arm/mach-msm/scm.c
>> +++ b/arch/arm/mach-msm/scm.c
>> @@ -264,13 +264,16 @@ u32 scm_get_version(void)
>> {
>> int context_id;
>> static u32 version = -1;
>> - register u32 r0 asm("r0") = 0x1 << 8;
>> - register u32 r1 asm("r1") = (u32)&context_id;
>> + register u32 r0 asm("r0");
>> + register u32 r1 asm("r1");
>>
>> if (version != -1)
>> return version;
>>
>> mutex_lock(&scm_lock);
>> +
>> + r0 = 0x1 << 8;
>> + r1 = (u32)&context_id;
>> asm volatile(
>> __asmeq("%0", "r1")
>> __asmeq("%1", "r0")
>
>
> Whoa, have you seen the compiler `optimise' the original assignments
> away? Since there is a use in the asm block, the definition shouldn't
> be omitted. What toolchain are you using
Yes I've seen the r0 and r1 assignments get optimized away. I'm
suspecting it's because the mutex_lock() is between the assignments and
usage. I'm guessing the assignment to r0 and r1 are actually generated,
but then they're optimized away because the mutex_lock() isn't inlined
and thus r0 and r1 assigned to something that isn't &scm_lock can be
"safely" removed (dead register assignments). I can't confirm any of
this since I don't know what gcc is doing internally or even how to
probe what it's doing (yeah I know I could go read gcc sources).
Suggestions?
I've seen it with two different compilers so far:
gcc (Sourcery G++ Lite 2010.09-50) 4.5.1
arm-eabi-gcc (GCC) 4.4.0
--
Sent by an employee of the Qualcomm Innovation Center, Inc.
The Qualcomm Innovation Center, Inc. is a member of the Code Aurora Forum.
^ permalink raw reply
* [PATCH V3 0/5] sdhci-esdhc-imx: use gpio for write protection and card detection
From: Arnaud Patard (Rtp) @ 2011-02-25 19:31 UTC (permalink / raw)
To: linux-arm-kernel
In-Reply-To: <4D66AAE4.4000308@eukrea.com>
Eric Benard <eric@eukrea.com> writes:
> Hi Arnaud,
Salut !
>
> On 24/02/2011 12:40, Arnaud Patard (Rtp) wrote:
>> Wolfram Sang<w.sang@pengutronix.de> writes:
>>
>> Hi,
>>
>>> Take #3, changes:
>>>
>>> * also intercept calls to SDHCI_SIGNAL_ENABLE (needed on mx25)
>>> * remove unconditional BROKEN_CARD_DETECTION (leftover)
>>> * improved kernel-doc about unused GPIO
>>> * added tags from Eric
>>>
>>> Tested now by me and Marc on mx35, Eric on mx25/35/51. Arnaud, did you have a
>>> chance to retest on mx51? What about the FSL guys? :)
>>
>> I'm getting a hard freeze on my efika sb and mx once I remove the
>> unconditional BROKEN_CARD_DETECTION flag. I'm still investigating the
>> issue. I'll keep you informed if I find something.
>>
> may you please test the attached patch. It may give someone with a
> better knowledge of sdhci than me an idea of what is wrong.
I've tested this patch on my efikamx and this patch does solve the
issue. I didn't test on the efika smartbook but I guess it'll be fine
here too. Thanks.
>
> Here are the workaround this patch add :
> - we can't let enable or disable irq enabled when the card is
> present/not present, else the irq triger again which explains why you
> get the freeze -> so we must rely on the card presence bit to enable
> the right interrupt,
so, we're getting an interrupt storm, right ? can't it be fixed by
setting a different irq type ?
> - we can't turn the clock off if we want the card detect to work when
> the card is removed -> as a quick workaround this patch prevents
> sdhci_set_clock from turning off the clocks when the
> SDHCI_INT_CARD_INSERT interrupt is enabled.
>
> Also, I had to change the MX51_PAD_GPIO1_0__SD1_CD pad setting as
> follows to enable the internal pull up :
> _MX51_PAD_GPIO1_0__SD1_CD | MUX_PAD_CTRL(PAD_CTL_PUS_22K_UP |
> PAD_CTL_PKE | PAD_CTL_SRE_FAST |
> PAD_CTL_DSE_HIGH | PAD_CTL_PUE | PAD_CTL_HYS),
It worked without changing this.
Arnaud
^ permalink raw reply
* [PATCH v2 2/9] omap4: prcm: Fix the CPUx clockdomain offsets
From: Paul Walmsley @ 2011-02-25 20:07 UTC (permalink / raw)
To: linux-arm-kernel
In-Reply-To: <1296813544-25170-3-git-send-email-santosh.shilimkar@ti.com>
On Fri, 4 Feb 2011, Santosh Shilimkar wrote:
> CPU0 and CPU1 clockdomain is at the offset of 0x18 from the LPRM base.
> The header file has set it wrongly to 0x0. Offset 0x0 is for CPUx power
> domain control register
>
> Fix the same.
>
> The autogen scripts is fixed thanks to Benoit Cousson
>
> Signed-off-by: Santosh Shilimkar <santosh.shilimkar@ti.com>
> Cc: Paul Walmsley <paul@pwsan.com>
> Cc: Rajendra Nayak <rnayak@ti.com>
> Cc: Benoit Cousson <b-cousson@ti.com>
Will submit this one for -rc series, since this could result in writes to
an incorrect register. Updated patch below.
- Paul
From: Santosh Shilimkar <santosh.shilimkar@ti.com>
Date: Fri, 4 Feb 2011 15:28:57 +0530
Subject: [PATCH] omap4: prcm: Fix the CPUx clockdomain offsets
CPU0 and CPU1 clockdomain is at the offset of 0x18 from the LPRM base.
The header file has set it wrongly to 0x0. Offset 0x0 is for CPUx power
domain control register
Fix the same.
The autogen scripts is fixed thanks to Benoit Cousson
With the old value, the clockdomain code would access the
*_PWRSTCTRL.POWERSTATE field when it thought it was accessing the
*_CLKSTCTRL.CLKTRCTRL field. In the worst case, this could cause
system power management to behave incorrectly.
Signed-off-by: Santosh Shilimkar <santosh.shilimkar@ti.com>
Cc: Paul Walmsley <paul@pwsan.com>
Cc: Rajendra Nayak <rnayak@ti.com>
Cc: Benoit Cousson <b-cousson@ti.com>
[paul at pwsan.com: added second paragraph to commit message]
Signed-off-by: Paul Walmsley <paul@pwsan.com>
---
arch/arm/mach-omap2/prcm_mpu44xx.h | 4 ++--
1 files changed, 2 insertions(+), 2 deletions(-)
diff --git a/arch/arm/mach-omap2/prcm_mpu44xx.h b/arch/arm/mach-omap2/prcm_mpu44xx.h
index 729a644..3300ff6 100644
--- a/arch/arm/mach-omap2/prcm_mpu44xx.h
+++ b/arch/arm/mach-omap2/prcm_mpu44xx.h
@@ -38,8 +38,8 @@
#define OMAP4430_PRCM_MPU_CPU1_INST 0x0800
/* PRCM_MPU clockdomain register offsets (from instance start) */
-#define OMAP4430_PRCM_MPU_CPU0_MPU_CDOFFS 0x0000
-#define OMAP4430_PRCM_MPU_CPU1_MPU_CDOFFS 0x0000
+#define OMAP4430_PRCM_MPU_CPU0_MPU_CDOFFS 0x0018
+#define OMAP4430_PRCM_MPU_CPU1_MPU_CDOFFS 0x0018
/*
--
1.7.2.3
^ permalink raw reply related
* [PATCH v2 3/9] omap4: powerdomain: Use intended PWRSTS_* flags instead of values
From: Paul Walmsley @ 2011-02-25 20:10 UTC (permalink / raw)
To: linux-arm-kernel
In-Reply-To: <8dcdd90dcde5ddefc02b08dc2faf9169@mail.gmail.com>
On Tue, 8 Feb 2011, Santosh Shilimkar wrote:
> > -----Original Message-----
> > From: Paul Walmsley [mailto:paul at pwsan.com]
> > Sent: Tuesday, February 08, 2011 7:16 AM
> > To: Santosh Shilimkar
> > Cc: linux-omap at vger.kernel.org; khilman at ti.com; b-cousson at ti.com;
> > rnayak at ti.com; linux-arm-kernel at lists.infradead.org
> > Subject: Re: [PATCH v2 3/9] omap4: powerdomain: Use intended
> > PWRSTS_* flags instead of values
> >
> > On Fri, 4 Feb 2011, Santosh Shilimkar wrote:
> >
> > > IVAHD and ABE power domain logic state is populated using directly
> > > value instead of the capability flags.
> > >
> > > Fix the same.
> > >
> > > This was getting generated due to a bug 'gen_logicst' macro
> > > in powerdomain autogen script bug which is fixed as well.
> >
> > Should we try to get this one into the -rc series, since it is a
> > bug-fix ?
> >
> Make sense.
Upon further reflection, I don't think that this is needed for 2.6.38-rc,
so will queue it for .39 instead.
- Paul
^ permalink raw reply
* OMAP2+: clock/MPU prcm: patches for the 2.6.38-rc series
From: Paul Walmsley @ 2011-02-25 20:16 UTC (permalink / raw)
To: linux-arm-kernel
In-Reply-To: <20110224211328.GK20560@atomide.com>
Hi Tony
The following changes since commit f5412be599602124d2bdd49947b231dd77c0bf99:
Linux 2.6.38-rc6 (2011-02-21 17:25:52 -0800)
are available in the git repository at:
git://git.pwsan.com/linux-2.6 patches_for_2.6.38rc
John Ogness (1):
OMAP2/3: clock: fix fint calculation for DPLL_FREQSEL
Santosh Shilimkar (1):
omap4: prcm: Fix the CPUx clockdomain offsets
arch/arm/mach-omap2/clkt_dpll.c | 2 +-
arch/arm/mach-omap2/prcm_mpu44xx.h | 4 ++--
2 files changed, 3 insertions(+), 3 deletions(-)
- Paul
^ permalink raw reply
* [PATCH] msm: gpiomux: Remove GPIOMUX_VALID and merge config enums
From: Rohit Vaswani @ 2011-02-25 20:19 UTC (permalink / raw)
To: linux-arm-kernel
Remove GPIOMUX_VALID, simplify the API, and absorb the complexity
of determining which gpiomux configs are used and which are
not back into the gpiomux implementation where it belongs.
Allow NULL settings to be represented appropriately.
The configuration enumerations represent a single abstraction
and were needlessly split. As such, collapse the conflicting
abstractions into a consistent one and move the implementation
complexity down into the implementation (where it belongs) and
away from the interface (where it doesn't belong).
Signed-off-by: Rohit Vaswani <rvaswani@codeaurora.org>
---
arch/arm/mach-msm/board-msm7x30.c | 23 +++++++--
arch/arm/mach-msm/board-qsd8x50.c | 17 +++++--
arch/arm/mach-msm/gpiomux-v1.c | 9 ++-
arch/arm/mach-msm/gpiomux-v1.h | 59 ----------------------
arch/arm/mach-msm/gpiomux-v2.c | 8 ++-
arch/arm/mach-msm/gpiomux-v2.h | 59 ----------------------
arch/arm/mach-msm/gpiomux.c | 77 +++++++++++++++++-------------
arch/arm/mach-msm/gpiomux.h | 96
+++++++++++++++++++++++-------------
8 files changed, 145 insertions(+), 203 deletions(-)
delete mode 100644 arch/arm/mach-msm/gpiomux-v1.h
delete mode 100644 arch/arm/mach-msm/gpiomux-v2.h
diff --git a/arch/arm/mach-msm/board-msm7x30.c
b/arch/arm/mach-msm/board-msm7x30.c
index 59b91de..4223329 100644
--- a/arch/arm/mach-msm/board-msm7x30.c
+++ b/arch/arm/mach-msm/board-msm7x30.c
@@ -39,8 +39,11 @@
#include "gpiomux.h"
#include "proc_comm.h"
-#define UART2_SUSPENDED (GPIOMUX_DRV_2MA | GPIOMUX_PULL_DOWN |\
- GPIOMUX_FUNC_2 | GPIOMUX_VALID)
+static struct gpiomux_setting uart2_suspended = {
+ .func = GPIOMUX_FUNC_2,
+ .drv = GPIOMUX_DRV_2MA,
+ .pull = GPIOMUX_PULL_DOWN,
+};
extern struct sys_timer msm_timer;
@@ -59,19 +62,27 @@ static struct msm_otg_platform_data msm_otg_pdata = {
struct msm_gpiomux_config msm7x30_uart2_configs[] __initdata = {
{
.gpio = 49, /* UART2 RFR */
- .suspended = UART2_SUSPENDED,
+ .settings = {
+ [GPIOMUX_SUSPENDED] = &uart2_suspended,
+ },
},
{
.gpio = 50, /* UART2 CTS */
- .suspended = UART2_SUSPENDED,
+ .settings = {
+ [GPIOMUX_SUSPENDED] = &uart2_suspended,
+ },
},
{
.gpio = 51, /* UART2 RX */
- .suspended = UART2_SUSPENDED,
+ .settings = {
+ [GPIOMUX_SUSPENDED] = &uart2_suspended,
+ },
},
{
.gpio = 52, /* UART2 TX */
- .suspended = UART2_SUSPENDED,
+ .settings = {
+ [GPIOMUX_SUSPENDED] = &uart2_suspended,
+ },
},
};
diff --git a/arch/arm/mach-msm/board-qsd8x50.c
b/arch/arm/mach-msm/board-qsd8x50.c
index 33ab1fe..d665b0e 100644
--- a/arch/arm/mach-msm/board-qsd8x50.c
+++ b/arch/arm/mach-msm/board-qsd8x50.c
@@ -38,19 +38,26 @@
#include "devices.h"
#include "gpiomux.h"
-#define UART3_SUSPENDED (GPIOMUX_DRV_2MA | GPIOMUX_PULL_DOWN |\
- GPIOMUX_FUNC_1 | GPIOMUX_VALID)
+static struct gpiomux_setting uart3_suspended = {
+ .drv = GPIOMUX_DRV_2MA,
+ .pull = GPIOMUX_PULL_DOWN,
+ .func = GPIOMUX_FUNC_1,
+};
extern struct sys_timer msm_timer;
-struct msm_gpiomux_config qsd8x50_uart3_configs[] __initdata = {
+struct msm_gpiomux_config qsd8x50_uart3_configs[] = {
{
.gpio = 86, /* UART3 RX */
- .suspended = UART3_SUSPENDED,
+ .settings = {
+ [GPIOMUX_SUSPENDED] = &uart3_suspended,
+ },
},
{
.gpio = 87, /* UART3 TX */
- .suspended = UART3_SUSPENDED,
+ .settings = {
+ [GPIOMUX_SUSPENDED] = &uart3_suspended,
+ },
},
};
diff --git a/arch/arm/mach-msm/gpiomux-v1.c b/arch/arm/mach-msm/gpiomux-v1.c
index 27de2ab..a9525c2 100644
--- a/arch/arm/mach-msm/gpiomux-v1.c
+++ b/arch/arm/mach-msm/gpiomux-v1.c
@@ -18,13 +18,16 @@
#include "gpiomux.h"
#include "proc_comm.h"
-void __msm_gpiomux_write(unsigned gpio, gpiomux_config_t val)
+void __msm_gpiomux_write(unsigned gpio, struct gpiomux_setting val)
{
- unsigned tlmm_config = (val & ~GPIOMUX_CTL_MASK) |
- ((gpio & 0x3ff) << 4);
+ unsigned tlmm_config;
unsigned tlmm_disable = 0;
int rc;
+ tlmm_config = (val.drv << 17) |
+ (val.pull << 15) |
+ ((gpio & 0x3ff) << 4) |
+ val.func;
rc = msm_proc_comm(PCOM_RPC_GPIO_TLMM_CONFIG_EX,
&tlmm_config, &tlmm_disable);
if (rc)
diff --git a/arch/arm/mach-msm/gpiomux-v1.h b/arch/arm/mach-msm/gpiomux-v1.h
deleted file mode 100644
index 96ad5fa..0000000
--- a/arch/arm/mach-msm/gpiomux-v1.h
+++ /dev/null
@@ -1,59 +0,0 @@
-/* Copyright (c) 2010, Code Aurora Forum. All rights reserved.
- *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License version 2 and
- * only version 2 as published by the Free Software Foundation.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- * GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with this program; if not, write to the Free Software
- * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
- * 02110-1301, USA.
- */
-#ifndef __ARCH_ARM_MACH_MSM_GPIOMUX_V1_H
-#define __ARCH_ARM_MACH_MSM_GPIOMUX_V1_H
-
-typedef u32 gpiomux_config_t;
-
-enum {
- GPIOMUX_DRV_2MA = 0UL << 17,
- GPIOMUX_DRV_4MA = 1UL << 17,
- GPIOMUX_DRV_6MA = 2UL << 17,
- GPIOMUX_DRV_8MA = 3UL << 17,
- GPIOMUX_DRV_10MA = 4UL << 17,
- GPIOMUX_DRV_12MA = 5UL << 17,
- GPIOMUX_DRV_14MA = 6UL << 17,
- GPIOMUX_DRV_16MA = 7UL << 17,
-};
-
-enum {
- GPIOMUX_FUNC_GPIO = 0UL,
- GPIOMUX_FUNC_1 = 1UL,
- GPIOMUX_FUNC_2 = 2UL,
- GPIOMUX_FUNC_3 = 3UL,
- GPIOMUX_FUNC_4 = 4UL,
- GPIOMUX_FUNC_5 = 5UL,
- GPIOMUX_FUNC_6 = 6UL,
- GPIOMUX_FUNC_7 = 7UL,
- GPIOMUX_FUNC_8 = 8UL,
- GPIOMUX_FUNC_9 = 9UL,
- GPIOMUX_FUNC_A = 10UL,
- GPIOMUX_FUNC_B = 11UL,
- GPIOMUX_FUNC_C = 12UL,
- GPIOMUX_FUNC_D = 13UL,
- GPIOMUX_FUNC_E = 14UL,
- GPIOMUX_FUNC_F = 15UL,
-};
-
-enum {
- GPIOMUX_PULL_NONE = 0UL << 15,
- GPIOMUX_PULL_DOWN = 1UL << 15,
- GPIOMUX_PULL_KEEPER = 2UL << 15,
- GPIOMUX_PULL_UP = 3UL << 15,
-};
-
-#endif
diff --git a/arch/arm/mach-msm/gpiomux-v2.c b/arch/arm/mach-msm/gpiomux-v2.c
index 273396d..0a04d60 100644
--- a/arch/arm/mach-msm/gpiomux-v2.c
+++ b/arch/arm/mach-msm/gpiomux-v2.c
@@ -18,8 +18,10 @@
#include <mach/msm_iomap.h>
#include "gpiomux.h"
-void __msm_gpiomux_write(unsigned gpio, gpiomux_config_t val)
+void __msm_gpiomux_write(unsigned gpio, struct gpiomux_setting val)
{
- writel(val & ~GPIOMUX_CTL_MASK,
- MSM_TLMM_BASE + 0x1000 + (0x10 * gpio));
+ uint32_t bits;
+
+ bits = (val.drv << 6) | (val.func << 2) | val.pull;
+ writel(bits, MSM_TLMM_BASE + 0x1000 + (0x10 * gpio));
}
diff --git a/arch/arm/mach-msm/gpiomux-v2.h b/arch/arm/mach-msm/gpiomux-v2.h
deleted file mode 100644
index a7dec1ea..0000000
--- a/arch/arm/mach-msm/gpiomux-v2.h
+++ /dev/null
@@ -1,59 +0,0 @@
-/* Copyright (c) 2010, Code Aurora Forum. All rights reserved.
- *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License version 2 and
- * only version 2 as published by the Free Software Foundation.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- * GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with this program; if not, write to the Free Software
- * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
- * 02110-1301, USA.
- */
-#ifndef __ARCH_ARM_MACH_MSM_GPIOMUX_V2_H
-#define __ARCH_ARM_MACH_MSM_GPIOMUX_V2_H
-
-typedef u16 gpiomux_config_t;
-
-enum {
- GPIOMUX_DRV_2MA = 0UL << 6,
- GPIOMUX_DRV_4MA = 1UL << 6,
- GPIOMUX_DRV_6MA = 2UL << 6,
- GPIOMUX_DRV_8MA = 3UL << 6,
- GPIOMUX_DRV_10MA = 4UL << 6,
- GPIOMUX_DRV_12MA = 5UL << 6,
- GPIOMUX_DRV_14MA = 6UL << 6,
- GPIOMUX_DRV_16MA = 7UL << 6,
-};
-
-enum {
- GPIOMUX_FUNC_GPIO = 0UL << 2,
- GPIOMUX_FUNC_1 = 1UL << 2,
- GPIOMUX_FUNC_2 = 2UL << 2,
- GPIOMUX_FUNC_3 = 3UL << 2,
- GPIOMUX_FUNC_4 = 4UL << 2,
- GPIOMUX_FUNC_5 = 5UL << 2,
- GPIOMUX_FUNC_6 = 6UL << 2,
- GPIOMUX_FUNC_7 = 7UL << 2,
- GPIOMUX_FUNC_8 = 8UL << 2,
- GPIOMUX_FUNC_9 = 9UL << 2,
- GPIOMUX_FUNC_A = 10UL << 2,
- GPIOMUX_FUNC_B = 11UL << 2,
- GPIOMUX_FUNC_C = 12UL << 2,
- GPIOMUX_FUNC_D = 13UL << 2,
- GPIOMUX_FUNC_E = 14UL << 2,
- GPIOMUX_FUNC_F = 15UL << 2,
-};
-
-enum {
- GPIOMUX_PULL_NONE = 0UL,
- GPIOMUX_PULL_DOWN = 1UL,
- GPIOMUX_PULL_KEEPER = 2UL,
- GPIOMUX_PULL_UP = 3UL,
-};
-
-#endif
diff --git a/arch/arm/mach-msm/gpiomux.c b/arch/arm/mach-msm/gpiomux.c
index 9ef9864..1ca26ec 100644
--- a/arch/arm/mach-msm/gpiomux.c
+++ b/arch/arm/mach-msm/gpiomux.c
@@ -20,21 +20,21 @@
#include "gpiomux.h"
struct msm_gpiomux_rec {
- gpiomux_config_t active;
- gpiomux_config_t suspended;
- int ref;
+ struct gpiomux_setting *sets[GPIOMUX_NSETTINGS];
+ int ref;
};
static DEFINE_SPINLOCK(gpiomux_lock);
static struct msm_gpiomux_rec *msm_gpiomux_recs;
+static struct gpiomux_setting *msm_gpiomux_sets;
static unsigned msm_gpiomux_ngpio;
-int msm_gpiomux_write(unsigned gpio,
- gpiomux_config_t active,
- gpiomux_config_t suspended)
+int msm_gpiomux_write(unsigned gpio, enum msm_gpiomux_setting which,
+ struct gpiomux_setting *setting)
{
- struct msm_gpiomux_rec *cfg = msm_gpiomux_recs + gpio;
+ struct msm_gpiomux_rec *rec = msm_gpiomux_recs + gpio;
+ unsigned set_slot = gpio * GPIOMUX_NSETTINGS + which;
unsigned long irq_flags;
- gpiomux_config_t setting;
+ struct gpiomux_setting *new_set;
if (!msm_gpiomux_recs)
return -EFAULT;
@@ -44,15 +44,17 @@ int msm_gpiomux_write(unsigned gpio,
spin_lock_irqsave(&gpiomux_lock, irq_flags);
- if (active & GPIOMUX_VALID)
- cfg->active = active;
-
- if (suspended & GPIOMUX_VALID)
- cfg->suspended = suspended;
+ if (setting) {
+ msm_gpiomux_sets[set_slot] = *setting;
+ rec->sets[which] = &msm_gpiomux_sets[set_slot];
+ } else {
+ rec->sets[which] = NULL;
+ }
- setting = cfg->ref ? active : suspended;
- if (setting & GPIOMUX_VALID)
- __msm_gpiomux_write(gpio, setting);
+ new_set = rec->ref ? rec->sets[GPIOMUX_ACTIVE] :
+ rec->sets[GPIOMUX_SUSPENDED];
+ if (new_set)
+ __msm_gpiomux_write(gpio, *new_set);
spin_unlock_irqrestore(&gpiomux_lock, irq_flags);
return 0;
@@ -61,7 +63,7 @@ EXPORT_SYMBOL(msm_gpiomux_write);
int msm_gpiomux_get(unsigned gpio)
{
- struct msm_gpiomux_rec *cfg = msm_gpiomux_recs + gpio;
+ struct msm_gpiomux_rec *rec = msm_gpiomux_recs + gpio;
unsigned long irq_flags;
if (!msm_gpiomux_recs)
@@ -71,8 +73,8 @@ int msm_gpiomux_get(unsigned gpio)
return -EINVAL;
spin_lock_irqsave(&gpiomux_lock, irq_flags);
- if (cfg->ref++ == 0 && cfg->active & GPIOMUX_VALID)
- __msm_gpiomux_write(gpio, cfg->active);
+ if (rec->ref++ == 0 && rec->sets[GPIOMUX_ACTIVE])
+ __msm_gpiomux_write(gpio, *rec->sets[GPIOMUX_ACTIVE]);
spin_unlock_irqrestore(&gpiomux_lock, irq_flags);
return 0;
}
@@ -80,7 +82,7 @@ EXPORT_SYMBOL(msm_gpiomux_get);
int msm_gpiomux_put(unsigned gpio)
{
- struct msm_gpiomux_rec *cfg = msm_gpiomux_recs + gpio;
+ struct msm_gpiomux_rec *rec = msm_gpiomux_recs + gpio;
unsigned long irq_flags;
if (!msm_gpiomux_recs)
@@ -90,9 +92,9 @@ int msm_gpiomux_put(unsigned gpio)
return -EINVAL;
spin_lock_irqsave(&gpiomux_lock, irq_flags);
- BUG_ON(cfg->ref == 0);
- if (--cfg->ref == 0 && cfg->suspended & GPIOMUX_VALID)
- __msm_gpiomux_write(gpio, cfg->suspended);
+ BUG_ON(rec->ref == 0);
+ if (--rec->ref == 0 && rec->sets[GPIOMUX_SUSPENDED])
+ __msm_gpiomux_write(gpio, *rec->sets[GPIOMUX_SUSPENDED]);
spin_unlock_irqrestore(&gpiomux_lock, irq_flags);
return 0;
}
@@ -111,6 +113,17 @@ int msm_gpiomux_init(size_t ngpio)
if (!msm_gpiomux_recs)
return -ENOMEM;
+ /* There is no need to zero this memory, as clients will be blindly
+ * installing settings on top of it.
+ */
+ msm_gpiomux_sets = kmalloc(sizeof(struct gpiomux_setting) * ngpio *
+ GPIOMUX_NSETTINGS, GFP_KERNEL);
+ if (!msm_gpiomux_sets) {
+ kfree(msm_gpiomux_recs);
+ msm_gpiomux_recs = NULL;
+ return -ENOMEM;
+ }
+
msm_gpiomux_ngpio = ngpio;
return 0;
@@ -119,18 +132,16 @@ EXPORT_SYMBOL(msm_gpiomux_init);
void msm_gpiomux_install(struct msm_gpiomux_config *configs, unsigned
nconfigs)
{
- unsigned n;
+ unsigned c, s;
int rc;
- if (!msm_gpiomux_recs)
- return;
-
- for (n = 0; n < nconfigs; ++n) {
- rc = msm_gpiomux_write(configs[n].gpio,
- configs[n].active,
- configs[n].suspended);
- if (rc)
- pr_err("%s: write failure: %d\n", __func__, rc);
+ for (c = 0; c < nconfigs; ++c) {
+ for (s = 0; s < GPIOMUX_NSETTINGS; ++s) {
+ rc = msm_gpiomux_write(configs[c].gpio, s,
+ configs[c].settings[s]);
+ if (rc)
+ pr_err("%s: write failure: %d\n", __func__, rc);
+ }
}
}
EXPORT_SYMBOL(msm_gpiomux_install);
diff --git a/arch/arm/mach-msm/gpiomux.h b/arch/arm/mach-msm/gpiomux.h
index 38bf511..bd8d6c2 100644
--- a/arch/arm/mach-msm/gpiomux.h
+++ b/arch/arm/mach-msm/gpiomux.h
@@ -20,44 +20,73 @@
#include <linux/bitops.h>
#include <linux/errno.h>
-#if defined(CONFIG_MSM_V2_TLMM)
-#include "gpiomux-v2.h"
-#else
-#include "gpiomux-v1.h"
-#endif
+enum msm_gpiomux_setting {
+ GPIOMUX_ACTIVE = 0,
+ GPIOMUX_SUSPENDED,
+ GPIOMUX_NSETTINGS
+};
+
+enum gpiomux_drv {
+ GPIOMUX_DRV_2MA = 0,
+ GPIOMUX_DRV_4MA,
+ GPIOMUX_DRV_6MA,
+ GPIOMUX_DRV_8MA,
+ GPIOMUX_DRV_10MA,
+ GPIOMUX_DRV_12MA,
+ GPIOMUX_DRV_14MA,
+ GPIOMUX_DRV_16MA,
+};
+
+enum gpiomux_func {
+ GPIOMUX_FUNC_GPIO = 0,
+ GPIOMUX_FUNC_1,
+ GPIOMUX_FUNC_2,
+ GPIOMUX_FUNC_3,
+ GPIOMUX_FUNC_4,
+ GPIOMUX_FUNC_5,
+ GPIOMUX_FUNC_6,
+ GPIOMUX_FUNC_7,
+ GPIOMUX_FUNC_8,
+ GPIOMUX_FUNC_9,
+ GPIOMUX_FUNC_A,
+ GPIOMUX_FUNC_B,
+ GPIOMUX_FUNC_C,
+ GPIOMUX_FUNC_D,
+ GPIOMUX_FUNC_E,
+ GPIOMUX_FUNC_F,
+};
+
+enum gpiomux_pull {
+ GPIOMUX_PULL_NONE = 0,
+ GPIOMUX_PULL_DOWN,
+ GPIOMUX_PULL_KEEPER,
+ GPIOMUX_PULL_UP,
+};
+
+struct gpiomux_setting {
+ enum gpiomux_func func;
+ enum gpiomux_drv drv;
+ enum gpiomux_pull pull;
+};
/**
* struct msm_gpiomux_config: gpiomux settings for one gpio line.
*
- * A complete gpiomux config is the bitwise-or of a drive-strength,
+ * A complete gpiomux setting is the combination of a drive-strength,
* function, and pull. For functions other than GPIO, the OE
* is hard-wired according to the function. For GPIO mode,
* OE is controlled by gpiolib.
*
- * Available settings differ by target; see the gpiomux header
- * specific to your target arch for available configurations.
- *
* @gpio: The index number of the gpio being described.
- * @active: The configuration to be installed when the line is
- * active, or its reference count is > 0.
- * @suspended: The configuration to be installed when the line
- * is suspended, or its reference count is 0.
+ * @settings: The settings to be installed, specifically:
+ * GPIOMUX_ACTIVE: The setting to be installed when the
+ * line is active, or its reference count is > 0.
+ * GPIOMUX_SUSPENDED: The setting to be installed when
+ * the line is suspended, or its reference count is 0.
*/
struct msm_gpiomux_config {
- unsigned gpio;
- gpiomux_config_t active;
- gpiomux_config_t suspended;
-};
-
-/**
- * @GPIOMUX_VALID: If set, the config field contains 'good data'.
- * The absence of this bit will prevent the gpiomux
- * system from applying the configuration under all
- * circumstances.
- */
-enum {
- GPIOMUX_VALID = BIT(sizeof(gpiomux_config_t) * BITS_PER_BYTE - 1),
- GPIOMUX_CTL_MASK = GPIOMUX_VALID,
+ unsigned gpio;
+ struct gpiomux_setting *settings[GPIOMUX_NSETTINGS];
};
#ifdef CONFIG_MSM_GPIOMUX
@@ -79,12 +108,10 @@ int __must_check msm_gpiomux_get(unsigned gpio);
/* Decrement a gpio's reference count, possibly suspending the line. */
int msm_gpiomux_put(unsigned gpio);
-/* Install a new configuration to the gpio line. To avoid overwriting
- * a configuration, leave the VALID bit out.
+/* Install a new setting in a gpio. To erase a slot, use NULL.
*/
-int msm_gpiomux_write(unsigned gpio,
- gpiomux_config_t active,
- gpiomux_config_t suspended);
+int msm_gpiomux_write(unsigned gpio, enum msm_gpiomux_setting which,
+ struct gpiomux_setting *setting);
/* Architecture-internal function for use by the framework only.
* This function can assume the following:
@@ -94,7 +121,7 @@ int msm_gpiomux_write(unsigned gpio,
* This function is not for public consumption. External users
* should use msm_gpiomux_write.
*/
-void __msm_gpiomux_write(unsigned gpio, gpiomux_config_t val);
+void __msm_gpiomux_write(unsigned gpio, struct gpiomux_setting val);
#else
static inline int msm_gpiomux_init(size_t ngpio)
{
@@ -115,8 +142,7 @@ static inline int msm_gpiomux_put(unsigned gpio)
}
static inline int msm_gpiomux_write(unsigned gpio,
- gpiomux_config_t active,
- gpiomux_config_t suspended)
+ enum msm_gpiomux_setting which, struct gpiomux_setting *setting)
{
return -ENOSYS;
}
--
1.7.3.3
Thanks,
Rohit Vaswani
--
Sent by an employee of the Qualcomm Innovation Center, Inc.
The Qualcomm Innovation Center, Inc. is a member of the Code Aurora Forum.
^ permalink raw reply related
* [PATCH v2 2/2] msm: add single-wire serial bus interface (SSBI) driver
From: Brian Swetland @ 2011-02-25 20:21 UTC (permalink / raw)
To: linux-arm-kernel
In-Reply-To: <8yak4go9bxw.fsf@huya.qualcomm.com>
On Fri, Feb 25, 2011 at 11:00 AM, David Brown <davidb@codeaurora.org> wrote:
> On Thu, Feb 24 2011, Daniel Walker wrote:
>
>>> Based on a patch by Dima Zavin <dima@android.com> that can be found at:
>>> http://android.git.kernel.org/?p=kernel/msm.git;a=commitdiff;h=eb060bac4
>>
>> I don't really like links in the commit text, cause as soon as Google
>> deletes this tree the link is worthless.
>
> I'm not sure how to better convey the information. ?The tree is at least
> on kernel.org, and there's good useful information there that works
> now. ?Links in commit text seem fairly common.
>
> I think it is helpful to demonstrate that Ken is trying to be diligent
> about indicating where the code comes from.
We do also keep older branches around, since this is how we publish
kernel sources when we ship devices. So while I can't be sure these
links will work *forever*, barring mishap they should exist for quite
a while.
Brian
^ permalink raw reply
* [PATCH v2 5/5] mmc: sdhci-esdhc: enable esdhc on imx53
From: Wolfram Sang @ 2011-02-25 20:38 UTC (permalink / raw)
To: linux-arm-kernel
In-Reply-To: <1298369606-29972-5-git-send-email-Hong-Xing.Zhu@freescale.com>
On Tue, Feb 22, 2011 at 06:13:26PM +0800, Richard Zhu wrote:
> Fix the NO INT in the Multi-BLK IO in SD/MMC, and
> Multi-BLK read in SDIO
This description is too short. Why does it not work before, and why does
this patch help?
>
> Signed-off-by: Richard Zhu <Hong-Xing.Zhu@freescale.com>
> ---
> drivers/mmc/host/sdhci-esdhc-imx.c | 41 +++++++++++++++++++++++++++++++++++-
> drivers/mmc/host/sdhci-esdhc.h | 5 ++++
> 2 files changed, 45 insertions(+), 1 deletions(-)
>
> diff --git a/drivers/mmc/host/sdhci-esdhc-imx.c b/drivers/mmc/host/sdhci-esdhc-imx.c
> index 9b82910..a09f786 100644
> --- a/drivers/mmc/host/sdhci-esdhc-imx.c
> +++ b/drivers/mmc/host/sdhci-esdhc-imx.c
> @@ -17,6 +17,8 @@
> #include <linux/clk.h>
> #include <linux/mmc/host.h>
> #include <linux/mmc/sdhci-pltfm.h>
> +#include <linux/mmc/mmc.h>
> +#include <linux/mmc/sdio.h>
> #include <mach/hardware.h>
> #include "sdhci.h"
> #include "sdhci-pltfm.h"
> @@ -38,6 +40,27 @@ static u16 esdhc_readw_le(struct sdhci_host *host, int reg)
> return readw(host->ioaddr + reg);
> }
>
> +static void esdhc_writel_le(struct sdhci_host *host, u32 val, int reg)
> +{
> + switch (reg) {
> + case SDHCI_INT_STATUS:
> + /*
> + * Fix no INT bug in SDIO MULTI-BLK read
> + * clear bit1 of Vendor Spec registor after TC
> + */
Same for this comment. Make it more descriptive, please
> + if (val & SDHCI_INT_DATA_END) {
> + u32 v;
> + v = readl(host->ioaddr + SDHCI_VENDOR_SPEC);
> + if (v & 0x2) {
> + v &= (~0x2);
Braces not needed.
> + writel(v, host->ioaddr + SDHCI_VENDOR_SPEC);
> + }
Can't you clear it unconditionally?
> + }
> + break;
> + }
> + writel(val, host->ioaddr + reg);
> +}
> +
> static void esdhc_writew_le(struct sdhci_host *host, u16 val, int reg)
> {
> struct sdhci_pltfm_host *pltfm_host = sdhci_priv(host);
> @@ -45,12 +68,27 @@ static void esdhc_writew_le(struct sdhci_host *host, u16 val, int reg)
> switch (reg) {
> case SDHCI_TRANSFER_MODE:
> /*
> + * Fix no INT bug in SDIO MULTI-BLK read
> + * set bit1 of Vendor Spec registor
> + */
> + if ((host->cmd->opcode == SD_IO_RW_EXTENDED)
> + && (host->cmd->data->blocks > 1)
> + && (host->cmd->data->flags & MMC_DATA_READ)) {
> + u32 v;
> + v = readl(host->ioaddr + SDHCI_VENDOR_SPEC);
> + v |= 0x2;
> + writel(v, host->ioaddr + SDHCI_VENDOR_SPEC);
> + }
> + /*
> * Postpone this write, we must do it together with a
> * command write that is down below.
> */
> pltfm_host->scratchpad = val;
> return;
> case SDHCI_COMMAND:
> + /*Set the CMD_TYPE of the CMD12, fix no INT in MULTI_BLK IO */
> + if (host->cmd->opcode == MMC_STOP_TRANSMISSION)
> + val |= SDHCI_CMD_ABORTCMD;
Can't we handle it the same way than the SDIO case? I have to admit,
even after reading the docs, I don't fully get what this bit1 is about.
> writel(val << 16 | pltfm_host->scratchpad,
> host->ioaddr + SDHCI_TRANSFER_MODE);
> return;
> @@ -113,7 +151,7 @@ static int esdhc_pltfm_init(struct sdhci_host *host, struct sdhci_pltfm_data *pd
> clk_enable(clk);
> pltfm_host->clk = clk;
>
> - if (cpu_is_mx35() || cpu_is_mx51())
> + if (!cpu_is_mx25())
> host->quirks |= SDHCI_QUIRK_BROKEN_TIMEOUT_VAL;
>
> /* Fix errata ENGcm07207 which is present on i.MX25 and i.MX35 */
> @@ -133,6 +171,7 @@ static void esdhc_pltfm_exit(struct sdhci_host *host)
>
> static struct sdhci_ops sdhci_esdhc_ops = {
> .read_w = esdhc_readw_le,
> + .write_l = esdhc_writel_le,
You are applying it for all imx-versions?
> .write_w = esdhc_writew_le,
> .write_b = esdhc_writeb_le,
> .set_clock = esdhc_set_clock,
> diff --git a/drivers/mmc/host/sdhci-esdhc.h b/drivers/mmc/host/sdhci-esdhc.h
> index 303cde0..c93168c 100644
> --- a/drivers/mmc/host/sdhci-esdhc.h
> +++ b/drivers/mmc/host/sdhci-esdhc.h
> @@ -43,6 +43,11 @@
>
> #define ESDHC_HOST_CONTROL_RES 0x05
>
> +/* Abort type definition in the command register */
> +#define SDHCI_CMD_ABORTCMD 0xC0
So, this is vendor-specific, too?
> +/* VENDOR SPEC register */
> +#define SDHCI_VENDOR_SPEC 0xC0
> +
> static inline void esdhc_set_clock(struct sdhci_host *host, unsigned int clock)
> {
> int pre_div = 2;
Regards,
Wolfram
--
Pengutronix e.K. | Wolfram Sang |
Industrial Linux Solutions | http://www.pengutronix.de/ |
-------------- next part --------------
A non-text attachment was scrubbed...
Name: not available
Type: application/pgp-signature
Size: 198 bytes
Desc: Digital signature
URL: <http://lists.infradead.org/pipermail/linux-arm-kernel/attachments/20110225/0ebb7bf1/attachment.sig>
^ permalink raw reply
* [PATCH v3 4/6] ARM: mxs: fix typo "GPO" in iomux-mx23.h
From: Uwe Kleine-König @ 2011-02-25 20:55 UTC (permalink / raw)
To: linux-arm-kernel
In-Reply-To: <1298284979-14853-5-git-send-email-shawn.guo@freescale.com>
Hello,
On Mon, Feb 21, 2011 at 06:42:57PM +0800, Shawn Guo wrote:
> Signed-off-by: Shawn Guo <shawn.guo@freescale.com>
Assuming this is just s/GPO/GPIO/ ...
Acked-by: Uwe Kleine-K?nig <u.kleine-koenig@pengutronix.de>
--
Pengutronix e.K. | Uwe Kleine-K?nig |
Industrial Linux Solutions | http://www.pengutronix.de/ |
^ permalink raw reply
* [PATCH V3 0/5] sdhci-esdhc-imx: use gpio for write protection and card detection
From: Eric Benard @ 2011-02-25 21:29 UTC (permalink / raw)
To: linux-arm-kernel
In-Reply-To: <874o7r29oa.fsf@lebrac.rtp-net.org>
Hi,
On 25/02/2011 20:31, Arnaud Patard (Rtp) wrote:
> Eric Benard<eric@eukrea.com> writes:
>> may you please test the attached patch. It may give someone with a
>> better knowledge of sdhci than me an idea of what is wrong.
>
> I've tested this patch on my efikamx and this patch does solve the
> issue. I didn't test on the efika smartbook but I guess it'll be fine
> here too. Thanks.
>
good. Now we have to find can how this code be integrated properly in the
sdhci driver.
>>
>> Here are the workaround this patch add :
>> - we can't let enable or disable irq enabled when the card is
>> present/not present, else the irq triger again which explains why you
>> get the freeze -> so we must rely on the card presence bit to enable
>> the right interrupt,
>
> so, we're getting an interrupt storm, right ? can't it be fixed by
> setting a different irq type ?
>
no this seems to be the way the SDHCI works, at least the i.MX51 ref manual says :
- When the CRM bit is cleared, if no card is inserted it is immediately set
again: this can be prevented by clearing the card removal status enable bit in
interrupt status enable register.
- When the CIN bit is cleared, if a card is inserted it is immediately set
again: this can be prevented by clearing the card inserted status enable bit
in interrupt status enable register.
As, unless I'm mistaken, sdhci host actually consider card detect as broken by
default, I think this code in not actually used so it may not be really tested.
>> - we can't turn the clock off if we want the card detect to work when
>> the card is removed -> as a quick workaround this patch prevents
>> sdhci_set_clock from turning off the clocks when the
>> SDHCI_INT_CARD_INSERT interrupt is enabled.
>>
>> Also, I had to change the MX51_PAD_GPIO1_0__SD1_CD pad setting as
>> follows to enable the internal pull up :
>> _MX51_PAD_GPIO1_0__SD1_CD | MUX_PAD_CTRL(PAD_CTL_PUS_22K_UP |
>> PAD_CTL_PKE | PAD_CTL_SRE_FAST |
>> PAD_CTL_DSE_HIGH | PAD_CTL_PUE | PAD_CTL_HYS),
>
> It worked without changing this.
>
this could mean you have an external pull up resistor on the board which was
not the case on the prototype I was working on which is partially mounted ;-)
Eric
^ permalink raw reply
* [PATCH 0/3] OMAP2+: voltage: first pass at cleanup/reorganization
From: Paul Walmsley @ 2011-02-25 21:42 UTC (permalink / raw)
To: linux-arm-kernel
In-Reply-To: <152f5892a6651cd0268573cb9b317efa@mail.gmail.com>
On Fri, 25 Feb 2011, Rajendra Nayak wrote:
> I agree it makes sense to fold these changes into the original patch.
> Please go ahead.
Great. Here's the revised patch, queued for 2.6.39. Please let me know
if you'd like changes to what I added to the commit message.
- Paul
From: Paul Walmsley <paul@pwsan.com>
Date: Fri, 25 Feb 2011 11:56:51 -0700
Subject: [PATCH] OMAP2+: voltage: reorganize, split code from data
This is a first pass at reorganizing mach-omap2/voltage.c:
- Separate almost all of the data from the code of mach-omap2/voltage.c.
The code remains in mach-omap2/voltage.c. The data goes into one
of several places, depending on what type of data it is:
- Silicon process/validation data: mach-omap2/opp*_data.c
- VC (Voltage Controller) data: mach-omap2/vc*_data.c
- VP (Voltage Processor) data: mach-omap2/vp*_data.c
- Voltage domain data: mach-omap2/voltagedomains*_data.c
The ultimate goal is for all this data to be autogenerated, the same
way we autogenerate the rest of our data.
- Separate VC and VP common data from VDD-specific VC and VP data.
- Separate common voltage.c code from SoC-specific code; reuse common code.
- Reorganize structures to avoid unnecessary memory loss due to unpacked
fields.
There is much left to be done. VC code and VP code should be separated out
into vc*.c and vp*.c files. Many fields in the existing structures are
superfluous, and should be removed. Some code in voltage.c seems to be
duplicated; that code should be moved into functions of its own. Proper
voltage domain code should be created, as was done with the powerdomain
and clockdomains, and powerdomains should reference voltagedomains.
Thanks to Shweta Gulati <shweta.gulati@ti.com> for comments. Thanks
to Rajendra Nayak <rnayak@ti.com> for finding and fixing some bugs
that prevented OMAP4 from booting:
https://patchwork.kernel.org/patch/587311/
His patch has been folded into this one to avoid breaking OMAP4 between
patches.
Signed-off-by: Paul Walmsley <paul@pwsan.com>
Cc: Shweta Gulati <shweta.gulati@ti.com>
Cc: Rajendra Nayak <rnayak@ti.com>
---
arch/arm/mach-omap2/Makefile | 20 +-
arch/arm/mach-omap2/omap_opp_data.h | 24 +
arch/arm/mach-omap2/opp3xxx_data.c | 66 ++-
arch/arm/mach-omap2/opp4xxx_data.c | 43 +-
arch/arm/mach-omap2/vc.h | 83 ++
arch/arm/mach-omap2/vc3xxx_data.c | 63 ++
arch/arm/mach-omap2/vc44xx_data.c | 75 ++
arch/arm/mach-omap2/voltage.c | 1015 +++++++------------------
arch/arm/mach-omap2/voltage.h | 89 ++-
arch/arm/mach-omap2/voltagedomains3xxx_data.c | 95 +++
arch/arm/mach-omap2/voltagedomains44xx_data.c | 102 +++
arch/arm/mach-omap2/vp.h | 143 ++++
arch/arm/mach-omap2/vp3xxx_data.c | 82 ++
arch/arm/mach-omap2/vp44xx_data.c | 100 +++
14 files changed, 1222 insertions(+), 778 deletions(-)
create mode 100644 arch/arm/mach-omap2/vc.h
create mode 100644 arch/arm/mach-omap2/vc3xxx_data.c
create mode 100644 arch/arm/mach-omap2/vc44xx_data.c
create mode 100644 arch/arm/mach-omap2/voltagedomains3xxx_data.c
create mode 100644 arch/arm/mach-omap2/voltagedomains44xx_data.c
create mode 100644 arch/arm/mach-omap2/vp.h
create mode 100644 arch/arm/mach-omap2/vp3xxx_data.c
create mode 100644 arch/arm/mach-omap2/vp44xx_data.c
diff --git a/arch/arm/mach-omap2/Makefile b/arch/arm/mach-omap2/Makefile
index 1c0c2b0..d5c1dba 100644
--- a/arch/arm/mach-omap2/Makefile
+++ b/arch/arm/mach-omap2/Makefile
@@ -59,10 +59,10 @@ endif
# Power Management
ifeq ($(CONFIG_PM),y)
obj-$(CONFIG_ARCH_OMAP2) += pm24xx.o
-obj-$(CONFIG_ARCH_OMAP2) += sleep24xx.o pm_bus.o voltage.o
-obj-$(CONFIG_ARCH_OMAP3) += pm34xx.o sleep34xx.o voltage.o \
+obj-$(CONFIG_ARCH_OMAP2) += sleep24xx.o pm_bus.o
+obj-$(CONFIG_ARCH_OMAP3) += pm34xx.o sleep34xx.o \
cpuidle34xx.o pm_bus.o
-obj-$(CONFIG_ARCH_OMAP4) += pm44xx.o voltage.o pm_bus.o
+obj-$(CONFIG_ARCH_OMAP4) += pm44xx.o pm_bus.o
obj-$(CONFIG_PM_DEBUG) += pm-debug.o
obj-$(CONFIG_OMAP_SMARTREFLEX) += sr_device.o smartreflex.o
obj-$(CONFIG_OMAP_SMARTREFLEX_CLASS3) += smartreflex-class3.o
@@ -78,13 +78,23 @@ endif
# PRCM
obj-$(CONFIG_ARCH_OMAP2) += prcm.o cm2xxx_3xxx.o prm2xxx_3xxx.o
-obj-$(CONFIG_ARCH_OMAP3) += prcm.o cm2xxx_3xxx.o prm2xxx_3xxx.o
+obj-$(CONFIG_ARCH_OMAP3) += prcm.o cm2xxx_3xxx.o prm2xxx_3xxx.o \
+ vc3xxx_data.o vp3xxx_data.o
# XXX The presence of cm2xxx_3xxx.o on the line below is temporary and
# will be removed once the OMAP4 part of the codebase is converted to
# use OMAP4-specific PRCM functions.
obj-$(CONFIG_ARCH_OMAP4) += prcm.o cm2xxx_3xxx.o cminst44xx.o \
cm44xx.o prcm_mpu44xx.o \
- prminst44xx.o
+ prminst44xx.o vc44xx_data.o \
+ vp44xx_data.o
+
+# OMAP voltage domains
+voltagedomain-common := voltage.o
+obj-$(CONFIG_ARCH_OMAP2) += $(voltagedomain-common)
+obj-$(CONFIG_ARCH_OMAP3) += $(voltagedomain-common) \
+ voltagedomains3xxx_data.o
+obj-$(CONFIG_ARCH_OMAP4) += $(voltagedomain-common) \
+ voltagedomains44xx_data.o
# OMAP powerdomain framework
powerdomain-common += powerdomain.o powerdomain-common.o
diff --git a/arch/arm/mach-omap2/omap_opp_data.h b/arch/arm/mach-omap2/omap_opp_data.h
index 46ac27d..c784c12 100644
--- a/arch/arm/mach-omap2/omap_opp_data.h
+++ b/arch/arm/mach-omap2/omap_opp_data.h
@@ -21,6 +21,8 @@
#include <plat/omap_hwmod.h>
+#include "voltage.h"
+
/*
* *BIG FAT WARNING*:
* USE the following ONLY in opp data initialization common to an SoC.
@@ -65,8 +67,30 @@ struct omap_opp_def {
.u_volt = _uv, \
}
+/*
+ * Initialization wrapper used to define SmartReflex process data
+ * XXX Is this needed? Just use C99 initializers in data files?
+ */
+#define VOLT_DATA_DEFINE(_v_nom, _efuse_offs, _errminlimit, _errgain) \
+{ \
+ .volt_nominal = _v_nom, \
+ .sr_efuse_offs = _efuse_offs, \
+ .sr_errminlimit = _errminlimit, \
+ .vp_errgain = _errgain \
+}
+
/* Use this to initialize the default table */
extern int __init omap_init_opp_table(struct omap_opp_def *opp_def,
u32 opp_def_size);
+
+extern struct omap_volt_data omap34xx_vddmpu_volt_data[];
+extern struct omap_volt_data omap34xx_vddcore_volt_data[];
+extern struct omap_volt_data omap36xx_vddmpu_volt_data[];
+extern struct omap_volt_data omap36xx_vddcore_volt_data[];
+
+extern struct omap_volt_data omap44xx_vdd_mpu_volt_data[];
+extern struct omap_volt_data omap44xx_vdd_iva_volt_data[];
+extern struct omap_volt_data omap44xx_vdd_core_volt_data[];
+
#endif /* __ARCH_ARM_MACH_OMAP2_OMAP_OPP_DATA_H */
diff --git a/arch/arm/mach-omap2/opp3xxx_data.c b/arch/arm/mach-omap2/opp3xxx_data.c
index 0486fce..3bba920 100644
--- a/arch/arm/mach-omap2/opp3xxx_data.c
+++ b/arch/arm/mach-omap2/opp3xxx_data.c
@@ -4,8 +4,9 @@
* Copyright (C) 2009-2010 Texas Instruments Incorporated - http://www.ti.com/
* Nishanth Menon
* Kevin Hilman
- * Copyright (C) 2010 Nokia Corporation.
+ * Copyright (C) 2010-2011 Nokia Corporation.
* Eduardo Valentin
+ * Paul Walmsley
*
* 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
@@ -20,8 +21,71 @@
#include <plat/cpu.h>
+#include "control.h"
#include "omap_opp_data.h"
+/* 34xx */
+
+/* VDD1 */
+
+#define OMAP3430_VDD_MPU_OPP1_UV 975000
+#define OMAP3430_VDD_MPU_OPP2_UV 1075000
+#define OMAP3430_VDD_MPU_OPP3_UV 1200000
+#define OMAP3430_VDD_MPU_OPP4_UV 1270000
+#define OMAP3430_VDD_MPU_OPP5_UV 1350000
+
+struct omap_volt_data omap34xx_vddmpu_volt_data[] = {
+ VOLT_DATA_DEFINE(OMAP3430_VDD_MPU_OPP1_UV, OMAP343X_CONTROL_FUSE_OPP1_VDD1, 0xf4, 0x0c),
+ VOLT_DATA_DEFINE(OMAP3430_VDD_MPU_OPP2_UV, OMAP343X_CONTROL_FUSE_OPP2_VDD1, 0xf4, 0x0c),
+ VOLT_DATA_DEFINE(OMAP3430_VDD_MPU_OPP3_UV, OMAP343X_CONTROL_FUSE_OPP3_VDD1, 0xf9, 0x18),
+ VOLT_DATA_DEFINE(OMAP3430_VDD_MPU_OPP4_UV, OMAP343X_CONTROL_FUSE_OPP4_VDD1, 0xf9, 0x18),
+ VOLT_DATA_DEFINE(OMAP3430_VDD_MPU_OPP5_UV, OMAP343X_CONTROL_FUSE_OPP5_VDD1, 0xf9, 0x18),
+ VOLT_DATA_DEFINE(0, 0, 0, 0),
+};
+
+/* VDD2 */
+
+#define OMAP3430_VDD_CORE_OPP1_UV 975000
+#define OMAP3430_VDD_CORE_OPP2_UV 1050000
+#define OMAP3430_VDD_CORE_OPP3_UV 1150000
+
+struct omap_volt_data omap34xx_vddcore_volt_data[] = {
+ VOLT_DATA_DEFINE(OMAP3430_VDD_CORE_OPP1_UV, OMAP343X_CONTROL_FUSE_OPP1_VDD2, 0xf4, 0x0c),
+ VOLT_DATA_DEFINE(OMAP3430_VDD_CORE_OPP2_UV, OMAP343X_CONTROL_FUSE_OPP2_VDD2, 0xf4, 0x0c),
+ VOLT_DATA_DEFINE(OMAP3430_VDD_CORE_OPP3_UV, OMAP343X_CONTROL_FUSE_OPP3_VDD2, 0xf9, 0x18),
+ VOLT_DATA_DEFINE(0, 0, 0, 0),
+};
+
+/* 36xx */
+
+/* VDD1 */
+
+#define OMAP3630_VDD_MPU_OPP50_UV 1012500
+#define OMAP3630_VDD_MPU_OPP100_UV 1200000
+#define OMAP3630_VDD_MPU_OPP120_UV 1325000
+#define OMAP3630_VDD_MPU_OPP1G_UV 1375000
+
+struct omap_volt_data omap36xx_vddmpu_volt_data[] = {
+ VOLT_DATA_DEFINE(OMAP3630_VDD_MPU_OPP50_UV, OMAP3630_CONTROL_FUSE_OPP50_VDD1, 0xf4, 0x0c),
+ VOLT_DATA_DEFINE(OMAP3630_VDD_MPU_OPP100_UV, OMAP3630_CONTROL_FUSE_OPP100_VDD1, 0xf9, 0x16),
+ VOLT_DATA_DEFINE(OMAP3630_VDD_MPU_OPP120_UV, OMAP3630_CONTROL_FUSE_OPP120_VDD1, 0xfa, 0x23),
+ VOLT_DATA_DEFINE(OMAP3630_VDD_MPU_OPP1G_UV, OMAP3630_CONTROL_FUSE_OPP1G_VDD1, 0xfa, 0x27),
+ VOLT_DATA_DEFINE(0, 0, 0, 0),
+};
+
+/* VDD2 */
+
+#define OMAP3630_VDD_CORE_OPP50_UV 1000000
+#define OMAP3630_VDD_CORE_OPP100_UV 1200000
+
+struct omap_volt_data omap36xx_vddcore_volt_data[] = {
+ VOLT_DATA_DEFINE(OMAP3630_VDD_CORE_OPP50_UV, OMAP3630_CONTROL_FUSE_OPP50_VDD2, 0xf4, 0x0c),
+ VOLT_DATA_DEFINE(OMAP3630_VDD_CORE_OPP100_UV, OMAP3630_CONTROL_FUSE_OPP100_VDD2, 0xf9, 0x16),
+ VOLT_DATA_DEFINE(0, 0, 0, 0),
+};
+
+/* OPP data */
+
static struct omap_opp_def __initdata omap34xx_opp_def_list[] = {
/* MPU OPP1 */
OPP_INITIALIZER("mpu", true, 125000000, 975000),
diff --git a/arch/arm/mach-omap2/opp4xxx_data.c b/arch/arm/mach-omap2/opp4xxx_data.c
index a11fa56..fdee8d4 100644
--- a/arch/arm/mach-omap2/opp4xxx_data.c
+++ b/arch/arm/mach-omap2/opp4xxx_data.c
@@ -5,8 +5,9 @@
* Nishanth Menon
* Kevin Hilman
* Thara Gopinath
- * Copyright (C) 2010 Nokia Corporation.
+ * Copyright (C) 2010-2011 Nokia Corporation.
* Eduardo Valentin
+ * Paul Walmsley
*
* 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
@@ -21,8 +22,48 @@
#include <plat/cpu.h>
+#include "control.h"
#include "omap_opp_data.h"
+/*
+ * Structures containing OMAP4430 voltage supported and various
+ * voltage dependent data for each VDD.
+ */
+
+#define OMAP4430_VDD_MPU_OPP50_UV 930000
+#define OMAP4430_VDD_MPU_OPP100_UV 1100000
+#define OMAP4430_VDD_MPU_OPPTURBO_UV 1260000
+#define OMAP4430_VDD_MPU_OPPNITRO_UV 1350000
+
+struct omap_volt_data omap44xx_vdd_mpu_volt_data[] = {
+ VOLT_DATA_DEFINE(OMAP4430_VDD_MPU_OPP50_UV, OMAP44XX_CONTROL_FUSE_MPU_OPP50, 0xf4, 0x0c),
+ VOLT_DATA_DEFINE(OMAP4430_VDD_MPU_OPP100_UV, OMAP44XX_CONTROL_FUSE_MPU_OPP100, 0xf9, 0x16),
+ VOLT_DATA_DEFINE(OMAP4430_VDD_MPU_OPPTURBO_UV, OMAP44XX_CONTROL_FUSE_MPU_OPPTURBO, 0xfa, 0x23),
+ VOLT_DATA_DEFINE(OMAP4430_VDD_MPU_OPPNITRO_UV, OMAP44XX_CONTROL_FUSE_MPU_OPPNITRO, 0xfa, 0x27),
+ VOLT_DATA_DEFINE(0, 0, 0, 0),
+};
+
+#define OMAP4430_VDD_IVA_OPP50_UV 930000
+#define OMAP4430_VDD_IVA_OPP100_UV 1100000
+#define OMAP4430_VDD_IVA_OPPTURBO_UV 1260000
+
+struct omap_volt_data omap44xx_vdd_iva_volt_data[] = {
+ VOLT_DATA_DEFINE(OMAP4430_VDD_IVA_OPP50_UV, OMAP44XX_CONTROL_FUSE_IVA_OPP50, 0xf4, 0x0c),
+ VOLT_DATA_DEFINE(OMAP4430_VDD_IVA_OPP100_UV, OMAP44XX_CONTROL_FUSE_IVA_OPP100, 0xf9, 0x16),
+ VOLT_DATA_DEFINE(OMAP4430_VDD_IVA_OPPTURBO_UV, OMAP44XX_CONTROL_FUSE_IVA_OPPTURBO, 0xfa, 0x23),
+ VOLT_DATA_DEFINE(0, 0, 0, 0),
+};
+
+#define OMAP4430_VDD_CORE_OPP50_UV 930000
+#define OMAP4430_VDD_CORE_OPP100_UV 1100000
+
+struct omap_volt_data omap44xx_vdd_core_volt_data[] = {
+ VOLT_DATA_DEFINE(OMAP4430_VDD_CORE_OPP50_UV, OMAP44XX_CONTROL_FUSE_CORE_OPP50, 0xf4, 0x0c),
+ VOLT_DATA_DEFINE(OMAP4430_VDD_CORE_OPP100_UV, OMAP44XX_CONTROL_FUSE_CORE_OPP100, 0xf9, 0x16),
+ VOLT_DATA_DEFINE(0, 0, 0, 0),
+};
+
+
static struct omap_opp_def __initdata omap44xx_opp_def_list[] = {
/* MPU OPP1 - OPP50 */
OPP_INITIALIZER("mpu", true, 300000000, 1100000),
diff --git a/arch/arm/mach-omap2/vc.h b/arch/arm/mach-omap2/vc.h
new file mode 100644
index 0000000..e776777
--- /dev/null
+++ b/arch/arm/mach-omap2/vc.h
@@ -0,0 +1,83 @@
+/*
+ * OMAP3/4 Voltage Controller (VC) structure and macro definitions
+ *
+ * Copyright (C) 2007, 2010 Texas Instruments, Inc.
+ * Rajendra Nayak <rnayak@ti.com>
+ * Lesly A M <x0080970@ti.com>
+ * Thara Gopinath <thara@ti.com>
+ *
+ * Copyright (C) 2008, 2011 Nokia Corporation
+ * Kalle Jokiniemi
+ * Paul Walmsley
+ *
+ * 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.
+ */
+#ifndef __ARCH_ARM_MACH_OMAP2_VC_H
+#define __ARCH_ARM_MACH_OMAP2_VC_H
+
+#include <linux/kernel.h>
+
+/**
+ * struct omap_vc_common_data - per-VC register/bitfield data
+ * @cmd_on_mask: ON bitmask in PRM_VC_CMD_VAL* register
+ * @valid: VALID bitmask in PRM_VC_BYPASS_VAL register
+ * @smps_sa_reg: Offset of PRM_VC_SMPS_SA reg from PRM start
+ * @smps_volra_reg: Offset of PRM_VC_SMPS_VOL_RA reg from PRM start
+ * @bypass_val_reg: Offset of PRM_VC_BYPASS_VAL reg from PRM start
+ * @data_shift: DATA field shift in PRM_VC_BYPASS_VAL register
+ * @slaveaddr_shift: SLAVEADDR field shift in PRM_VC_BYPASS_VAL register
+ * @regaddr_shift: REGADDR field shift in PRM_VC_BYPASS_VAL register
+ * @cmd_on_shift: ON field shift in PRM_VC_CMD_VAL_* register
+ * @cmd_onlp_shift: ONLP field shift in PRM_VC_CMD_VAL_* register
+ * @cmd_ret_shift: RET field shift in PRM_VC_CMD_VAL_* register
+ * @cmd_off_shift: OFF field shift in PRM_VC_CMD_VAL_* register
+ *
+ * XXX One of cmd_on_mask and cmd_on_shift are not needed
+ * XXX VALID should probably be a shift, not a mask
+ */
+struct omap_vc_common_data {
+ u32 cmd_on_mask;
+ u32 valid;
+ u8 smps_sa_reg;
+ u8 smps_volra_reg;
+ u8 bypass_val_reg;
+ u8 data_shift;
+ u8 slaveaddr_shift;
+ u8 regaddr_shift;
+ u8 cmd_on_shift;
+ u8 cmd_onlp_shift;
+ u8 cmd_ret_shift;
+ u8 cmd_off_shift;
+};
+
+/**
+ * struct omap_vc_instance_data - VC per-instance data
+ * @vc_common: pointer to VC common data for this platform
+ * @smps_sa_mask: SA* bitmask in the PRM_VC_SMPS_SA register
+ * @smps_volra_mask: VOLRA* bitmask in the PRM_VC_VOL_RA register
+ * @smps_sa_shift: SA* field shift in the PRM_VC_SMPS_SA register
+ * @smps_volra_shift: VOLRA* field shift in the PRM_VC_VOL_RA register
+ *
+ * XXX It is not necessary to have both a *_mask and a *_shift -
+ * remove one
+ */
+struct omap_vc_instance_data {
+ const struct omap_vc_common_data *vc_common;
+ u32 smps_sa_mask;
+ u32 smps_volra_mask;
+ u8 cmdval_reg;
+ u8 smps_sa_shift;
+ u8 smps_volra_shift;
+};
+
+extern struct omap_vc_instance_data omap3_vc1_data;
+extern struct omap_vc_instance_data omap3_vc2_data;
+
+extern struct omap_vc_instance_data omap4_vc_mpu_data;
+extern struct omap_vc_instance_data omap4_vc_iva_data;
+extern struct omap_vc_instance_data omap4_vc_core_data;
+
+#endif
+
diff --git a/arch/arm/mach-omap2/vc3xxx_data.c b/arch/arm/mach-omap2/vc3xxx_data.c
new file mode 100644
index 0000000..f37dc4b
--- /dev/null
+++ b/arch/arm/mach-omap2/vc3xxx_data.c
@@ -0,0 +1,63 @@
+/*
+ * OMAP3 Voltage Controller (VC) data
+ *
+ * Copyright (C) 2007, 2010 Texas Instruments, Inc.
+ * Rajendra Nayak <rnayak@ti.com>
+ * Lesly A M <x0080970@ti.com>
+ * Thara Gopinath <thara@ti.com>
+ *
+ * Copyright (C) 2008, 2011 Nokia Corporation
+ * Kalle Jokiniemi
+ * Paul Walmsley
+ *
+ * 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/io.h>
+#include <linux/err.h>
+#include <linux/init.h>
+
+#include <plat/common.h>
+
+#include "prm-regbits-34xx.h"
+#include "voltage.h"
+
+#include "vc.h"
+
+/*
+ * VC data common to 34xx/36xx chips
+ * XXX This stuff presumably belongs in the vc3xxx.c or vc.c file.
+ */
+static struct omap_vc_common_data omap3_vc_common = {
+ .smps_sa_reg = OMAP3_PRM_VC_SMPS_SA_OFFSET,
+ .smps_volra_reg = OMAP3_PRM_VC_SMPS_VOL_RA_OFFSET,
+ .bypass_val_reg = OMAP3_PRM_VC_BYPASS_VAL_OFFSET,
+ .data_shift = OMAP3430_DATA_SHIFT,
+ .slaveaddr_shift = OMAP3430_SLAVEADDR_SHIFT,
+ .regaddr_shift = OMAP3430_REGADDR_SHIFT,
+ .valid = OMAP3430_VALID_MASK,
+ .cmd_on_shift = OMAP3430_VC_CMD_ON_SHIFT,
+ .cmd_on_mask = OMAP3430_VC_CMD_ON_MASK,
+ .cmd_onlp_shift = OMAP3430_VC_CMD_ONLP_SHIFT,
+ .cmd_ret_shift = OMAP3430_VC_CMD_RET_SHIFT,
+ .cmd_off_shift = OMAP3430_VC_CMD_OFF_SHIFT,
+};
+
+struct omap_vc_instance_data omap3_vc1_data = {
+ .vc_common = &omap3_vc_common,
+ .cmdval_reg = OMAP3_PRM_VC_CMD_VAL_0_OFFSET,
+ .smps_sa_shift = OMAP3430_PRM_VC_SMPS_SA_SA0_SHIFT,
+ .smps_sa_mask = OMAP3430_PRM_VC_SMPS_SA_SA0_MASK,
+ .smps_volra_shift = OMAP3430_VOLRA0_SHIFT,
+ .smps_volra_mask = OMAP3430_VOLRA0_MASK,
+};
+
+struct omap_vc_instance_data omap3_vc2_data = {
+ .vc_common = &omap3_vc_common,
+ .cmdval_reg = OMAP3_PRM_VC_CMD_VAL_1_OFFSET,
+ .smps_sa_shift = OMAP3430_PRM_VC_SMPS_SA_SA1_SHIFT,
+ .smps_sa_mask = OMAP3430_PRM_VC_SMPS_SA_SA1_MASK,
+ .smps_volra_shift = OMAP3430_VOLRA1_SHIFT,
+ .smps_volra_mask = OMAP3430_VOLRA1_MASK,
+};
diff --git a/arch/arm/mach-omap2/vc44xx_data.c b/arch/arm/mach-omap2/vc44xx_data.c
new file mode 100644
index 0000000..a98da8d
--- /dev/null
+++ b/arch/arm/mach-omap2/vc44xx_data.c
@@ -0,0 +1,75 @@
+/*
+ * OMAP4 Voltage Controller (VC) data
+ *
+ * Copyright (C) 2007, 2010 Texas Instruments, Inc.
+ * Rajendra Nayak <rnayak@ti.com>
+ * Lesly A M <x0080970@ti.com>
+ * Thara Gopinath <thara@ti.com>
+ *
+ * Copyright (C) 2008, 2011 Nokia Corporation
+ * Kalle Jokiniemi
+ * Paul Walmsley
+ *
+ * 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/io.h>
+#include <linux/err.h>
+#include <linux/init.h>
+
+#include <plat/common.h>
+
+#include "prm44xx.h"
+#include "prm-regbits-44xx.h"
+#include "voltage.h"
+
+#include "vc.h"
+
+/*
+ * VC data common to 44xx chips
+ * XXX This stuff presumably belongs in the vc3xxx.c or vc.c file.
+ */
+static const struct omap_vc_common_data omap4_vc_common = {
+ .smps_sa_reg = OMAP4_PRM_VC_SMPS_SA_OFFSET,
+ .smps_volra_reg = OMAP4_PRM_VC_VAL_SMPS_RA_VOL_OFFSET,
+ .bypass_val_reg = OMAP4_PRM_VC_VAL_BYPASS_OFFSET,
+ .data_shift = OMAP4430_DATA_SHIFT,
+ .slaveaddr_shift = OMAP4430_SLAVEADDR_SHIFT,
+ .regaddr_shift = OMAP4430_REGADDR_SHIFT,
+ .valid = OMAP4430_VALID_MASK,
+ .cmd_on_shift = OMAP4430_ON_SHIFT,
+ .cmd_on_mask = OMAP4430_ON_MASK,
+ .cmd_onlp_shift = OMAP4430_ONLP_SHIFT,
+ .cmd_ret_shift = OMAP4430_RET_SHIFT,
+ .cmd_off_shift = OMAP4430_OFF_SHIFT,
+};
+
+/* VC instance data for each controllable voltage line */
+struct omap_vc_instance_data omap4_vc_mpu_data = {
+ .vc_common = &omap4_vc_common,
+ .cmdval_reg = OMAP4_PRM_VC_VAL_CMD_VDD_MPU_L_OFFSET,
+ .smps_sa_shift = OMAP4430_SA_VDD_MPU_L_PRM_VC_SMPS_SA_SHIFT,
+ .smps_sa_mask = OMAP4430_SA_VDD_MPU_L_PRM_VC_SMPS_SA_MASK,
+ .smps_volra_shift = OMAP4430_VOLRA_VDD_MPU_L_SHIFT,
+ .smps_volra_mask = OMAP4430_VOLRA_VDD_MPU_L_MASK,
+};
+
+struct omap_vc_instance_data omap4_vc_iva_data = {
+ .vc_common = &omap4_vc_common,
+ .cmdval_reg = OMAP4_PRM_VC_VAL_CMD_VDD_IVA_L_OFFSET,
+ .smps_sa_shift = OMAP4430_SA_VDD_IVA_L_PRM_VC_SMPS_SA_SHIFT,
+ .smps_sa_mask = OMAP4430_SA_VDD_IVA_L_PRM_VC_SMPS_SA_MASK,
+ .smps_volra_shift = OMAP4430_VOLRA_VDD_IVA_L_SHIFT,
+ .smps_volra_mask = OMAP4430_VOLRA_VDD_IVA_L_MASK,
+};
+
+struct omap_vc_instance_data omap4_vc_core_data = {
+ .vc_common = &omap4_vc_common,
+ .cmdval_reg = OMAP4_PRM_VC_VAL_CMD_VDD_CORE_L_OFFSET,
+ .smps_sa_shift = OMAP4430_SA_VDD_CORE_L_0_6_SHIFT,
+ .smps_sa_mask = OMAP4430_SA_VDD_CORE_L_0_6_MASK,
+ .smps_volra_shift = OMAP4430_VOLRA_VDD_CORE_L_SHIFT,
+ .smps_volra_mask = OMAP4430_VOLRA_VDD_CORE_L_MASK,
+};
+
diff --git a/arch/arm/mach-omap2/voltage.c b/arch/arm/mach-omap2/voltage.c
index 3c9bcdc..e0cbd93 100644
--- a/arch/arm/mach-omap2/voltage.c
+++ b/arch/arm/mach-omap2/voltage.c
@@ -7,8 +7,9 @@
* Rajendra Nayak <rnayak@ti.com>
* Lesly A M <x0080970@ti.com>
*
- * Copyright (C) 2008 Nokia Corporation
+ * Copyright (C) 2008, 2011 Nokia Corporation
* Kalle Jokiniemi
+ * Paul Walmsley
*
* Copyright (C) 2010 Texas Instruments, Inc.
* Thara Gopinath <thara@ti.com>
@@ -36,284 +37,28 @@
#include "voltage.h"
-#define VP_IDLE_TIMEOUT 200
-#define VP_TRANXDONE_TIMEOUT 300
+#include "vc.h"
+#include "vp.h"
+
#define VOLTAGE_DIR_SIZE 16
-/* Voltage processor register offsets */
-struct vp_reg_offs {
- u8 vpconfig;
- u8 vstepmin;
- u8 vstepmax;
- u8 vlimitto;
- u8 vstatus;
- u8 voltage;
-};
-
-/* Voltage Processor bit field values, shifts and masks */
-struct vp_reg_val {
- /* PRM module */
- u16 prm_mod;
- /* VPx_VPCONFIG */
- u32 vpconfig_erroroffset;
- u16 vpconfig_errorgain;
- u32 vpconfig_errorgain_mask;
- u8 vpconfig_errorgain_shift;
- u32 vpconfig_initvoltage_mask;
- u8 vpconfig_initvoltage_shift;
- u32 vpconfig_timeouten;
- u32 vpconfig_initvdd;
- u32 vpconfig_forceupdate;
- u32 vpconfig_vpenable;
- /* VPx_VSTEPMIN */
- u8 vstepmin_stepmin;
- u16 vstepmin_smpswaittimemin;
- u8 vstepmin_stepmin_shift;
- u8 vstepmin_smpswaittimemin_shift;
- /* VPx_VSTEPMAX */
- u8 vstepmax_stepmax;
- u16 vstepmax_smpswaittimemax;
- u8 vstepmax_stepmax_shift;
- u8 vstepmax_smpswaittimemax_shift;
- /* VPx_VLIMITTO */
- u8 vlimitto_vddmin;
- u8 vlimitto_vddmax;
- u16 vlimitto_timeout;
- u8 vlimitto_vddmin_shift;
- u8 vlimitto_vddmax_shift;
- u8 vlimitto_timeout_shift;
- /* PRM_IRQSTATUS*/
- u32 tranxdone_status;
-};
-
-/* Voltage controller registers and offsets */
-struct vc_reg_info {
- /* PRM module */
- u16 prm_mod;
- /* VC register offsets */
- u8 smps_sa_reg;
- u8 smps_volra_reg;
- u8 bypass_val_reg;
- u8 cmdval_reg;
- u8 voltsetup_reg;
- /*VC_SMPS_SA*/
- u8 smps_sa_shift;
- u32 smps_sa_mask;
- /* VC_SMPS_VOL_RA */
- u8 smps_volra_shift;
- u32 smps_volra_mask;
- /* VC_BYPASS_VAL */
- u8 data_shift;
- u8 slaveaddr_shift;
- u8 regaddr_shift;
- u32 valid;
- /* VC_CMD_VAL */
- u8 cmd_on_shift;
- u8 cmd_onlp_shift;
- u8 cmd_ret_shift;
- u8 cmd_off_shift;
- u32 cmd_on_mask;
- /* PRM_VOLTSETUP */
- u8 voltsetup_shift;
- u32 voltsetup_mask;
-};
-/**
- * omap_vdd_info - Per Voltage Domain info
- *
- * @volt_data : voltage table having the distinct voltages supported
- * by the domain and other associated per voltage data.
- * @pmic_info : pmic specific parameters which should be populted by
- * the pmic drivers.
- * @vp_offs : structure containing the offsets for various
- * vp registers
- * @vp_reg : the register values, shifts, masks for various
- * vp registers
- * @vc_reg : structure containing various various vc registers,
- * shifts, masks etc.
- * @voltdm : pointer to the voltage domain structure
- * @debug_dir : debug directory for this voltage domain.
- * @curr_volt : current voltage for this vdd.
- * @ocp_mod : The prm module for accessing the prm irqstatus reg.
- * @prm_irqst_reg : prm irqstatus register.
- * @vp_enabled : flag to keep track of whether vp is enabled or not
- * @volt_scale : API to scale the voltage of the vdd.
- */
-struct omap_vdd_info {
- struct omap_volt_data *volt_data;
- struct omap_volt_pmic_info *pmic_info;
- struct vp_reg_offs vp_offs;
- struct vp_reg_val vp_reg;
- struct vc_reg_info vc_reg;
- struct voltagedomain voltdm;
- struct dentry *debug_dir;
- u32 curr_volt;
- u16 ocp_mod;
- u8 prm_irqst_reg;
- bool vp_enabled;
- u32 (*read_reg) (u16 mod, u8 offset);
- void (*write_reg) (u32 val, u16 mod, u8 offset);
- int (*volt_scale) (struct omap_vdd_info *vdd,
- unsigned long target_volt);
-};
-
-static struct omap_vdd_info *vdd_info;
+static struct omap_vdd_info **vdd_info;
+
/*
* Number of scalable voltage domains.
*/
static int nr_scalable_vdd;
-/* OMAP3 VDD sturctures */
-static struct omap_vdd_info omap3_vdd_info[] = {
- {
- .vp_offs = {
- .vpconfig = OMAP3_PRM_VP1_CONFIG_OFFSET,
- .vstepmin = OMAP3_PRM_VP1_VSTEPMIN_OFFSET,
- .vstepmax = OMAP3_PRM_VP1_VSTEPMAX_OFFSET,
- .vlimitto = OMAP3_PRM_VP1_VLIMITTO_OFFSET,
- .vstatus = OMAP3_PRM_VP1_STATUS_OFFSET,
- .voltage = OMAP3_PRM_VP1_VOLTAGE_OFFSET,
- },
- .voltdm = {
- .name = "mpu",
- },
- },
- {
- .vp_offs = {
- .vpconfig = OMAP3_PRM_VP2_CONFIG_OFFSET,
- .vstepmin = OMAP3_PRM_VP2_VSTEPMIN_OFFSET,
- .vstepmax = OMAP3_PRM_VP2_VSTEPMAX_OFFSET,
- .vlimitto = OMAP3_PRM_VP2_VLIMITTO_OFFSET,
- .vstatus = OMAP3_PRM_VP2_STATUS_OFFSET,
- .voltage = OMAP3_PRM_VP2_VOLTAGE_OFFSET,
- },
- .voltdm = {
- .name = "core",
- },
- },
-};
-
-#define OMAP3_NR_SCALABLE_VDD ARRAY_SIZE(omap3_vdd_info)
-
-/* OMAP4 VDD sturctures */
-static struct omap_vdd_info omap4_vdd_info[] = {
- {
- .vp_offs = {
- .vpconfig = OMAP4_PRM_VP_MPU_CONFIG_OFFSET,
- .vstepmin = OMAP4_PRM_VP_MPU_VSTEPMIN_OFFSET,
- .vstepmax = OMAP4_PRM_VP_MPU_VSTEPMAX_OFFSET,
- .vlimitto = OMAP4_PRM_VP_MPU_VLIMITTO_OFFSET,
- .vstatus = OMAP4_PRM_VP_MPU_STATUS_OFFSET,
- .voltage = OMAP4_PRM_VP_MPU_VOLTAGE_OFFSET,
- },
- .voltdm = {
- .name = "mpu",
- },
- },
- {
- .vp_offs = {
- .vpconfig = OMAP4_PRM_VP_IVA_CONFIG_OFFSET,
- .vstepmin = OMAP4_PRM_VP_IVA_VSTEPMIN_OFFSET,
- .vstepmax = OMAP4_PRM_VP_IVA_VSTEPMAX_OFFSET,
- .vlimitto = OMAP4_PRM_VP_IVA_VLIMITTO_OFFSET,
- .vstatus = OMAP4_PRM_VP_IVA_STATUS_OFFSET,
- .voltage = OMAP4_PRM_VP_IVA_VOLTAGE_OFFSET,
- },
- .voltdm = {
- .name = "iva",
- },
- },
- {
- .vp_offs = {
- .vpconfig = OMAP4_PRM_VP_CORE_CONFIG_OFFSET,
- .vstepmin = OMAP4_PRM_VP_CORE_VSTEPMIN_OFFSET,
- .vstepmax = OMAP4_PRM_VP_CORE_VSTEPMAX_OFFSET,
- .vlimitto = OMAP4_PRM_VP_CORE_VLIMITTO_OFFSET,
- .vstatus = OMAP4_PRM_VP_CORE_STATUS_OFFSET,
- .voltage = OMAP4_PRM_VP_CORE_VOLTAGE_OFFSET,
- },
- .voltdm = {
- .name = "core",
- },
- },
-};
-
-#define OMAP4_NR_SCALABLE_VDD ARRAY_SIZE(omap4_vdd_info)
-
-/*
- * Structures containing OMAP3430/OMAP3630 voltage supported and various
- * voltage dependent data for each VDD.
- */
-#define VOLT_DATA_DEFINE(_v_nom, _efuse_offs, _errminlimit, _errgain) \
-{ \
- .volt_nominal = _v_nom, \
- .sr_efuse_offs = _efuse_offs, \
- .sr_errminlimit = _errminlimit, \
- .vp_errgain = _errgain \
-}
-
-/* VDD1 */
-static struct omap_volt_data omap34xx_vddmpu_volt_data[] = {
- VOLT_DATA_DEFINE(OMAP3430_VDD_MPU_OPP1_UV, OMAP343X_CONTROL_FUSE_OPP1_VDD1, 0xf4, 0x0c),
- VOLT_DATA_DEFINE(OMAP3430_VDD_MPU_OPP2_UV, OMAP343X_CONTROL_FUSE_OPP2_VDD1, 0xf4, 0x0c),
- VOLT_DATA_DEFINE(OMAP3430_VDD_MPU_OPP3_UV, OMAP343X_CONTROL_FUSE_OPP3_VDD1, 0xf9, 0x18),
- VOLT_DATA_DEFINE(OMAP3430_VDD_MPU_OPP4_UV, OMAP343X_CONTROL_FUSE_OPP4_VDD1, 0xf9, 0x18),
- VOLT_DATA_DEFINE(OMAP3430_VDD_MPU_OPP5_UV, OMAP343X_CONTROL_FUSE_OPP5_VDD1, 0xf9, 0x18),
- VOLT_DATA_DEFINE(0, 0, 0, 0),
-};
-
-static struct omap_volt_data omap36xx_vddmpu_volt_data[] = {
- VOLT_DATA_DEFINE(OMAP3630_VDD_MPU_OPP50_UV, OMAP3630_CONTROL_FUSE_OPP50_VDD1, 0xf4, 0x0c),
- VOLT_DATA_DEFINE(OMAP3630_VDD_MPU_OPP100_UV, OMAP3630_CONTROL_FUSE_OPP100_VDD1, 0xf9, 0x16),
- VOLT_DATA_DEFINE(OMAP3630_VDD_MPU_OPP120_UV, OMAP3630_CONTROL_FUSE_OPP120_VDD1, 0xfa, 0x23),
- VOLT_DATA_DEFINE(OMAP3630_VDD_MPU_OPP1G_UV, OMAP3630_CONTROL_FUSE_OPP1G_VDD1, 0xfa, 0x27),
- VOLT_DATA_DEFINE(0, 0, 0, 0),
-};
-
-/* VDD2 */
-static struct omap_volt_data omap34xx_vddcore_volt_data[] = {
- VOLT_DATA_DEFINE(OMAP3430_VDD_CORE_OPP1_UV, OMAP343X_CONTROL_FUSE_OPP1_VDD2, 0xf4, 0x0c),
- VOLT_DATA_DEFINE(OMAP3430_VDD_CORE_OPP2_UV, OMAP343X_CONTROL_FUSE_OPP2_VDD2, 0xf4, 0x0c),
- VOLT_DATA_DEFINE(OMAP3430_VDD_CORE_OPP3_UV, OMAP343X_CONTROL_FUSE_OPP3_VDD2, 0xf9, 0x18),
- VOLT_DATA_DEFINE(0, 0, 0, 0),
-};
-
-static struct omap_volt_data omap36xx_vddcore_volt_data[] = {
- VOLT_DATA_DEFINE(OMAP3630_VDD_CORE_OPP50_UV, OMAP3630_CONTROL_FUSE_OPP50_VDD2, 0xf4, 0x0c),
- VOLT_DATA_DEFINE(OMAP3630_VDD_CORE_OPP100_UV, OMAP3630_CONTROL_FUSE_OPP100_VDD2, 0xf9, 0x16),
- VOLT_DATA_DEFINE(0, 0, 0, 0),
-};
-
-/*
- * Structures containing OMAP4430 voltage supported and various
- * voltage dependent data for each VDD.
- */
-static struct omap_volt_data omap44xx_vdd_mpu_volt_data[] = {
- VOLT_DATA_DEFINE(OMAP4430_VDD_MPU_OPP50_UV, OMAP44XX_CONTROL_FUSE_MPU_OPP50, 0xf4, 0x0c),
- VOLT_DATA_DEFINE(OMAP4430_VDD_MPU_OPP100_UV, OMAP44XX_CONTROL_FUSE_MPU_OPP100, 0xf9, 0x16),
- VOLT_DATA_DEFINE(OMAP4430_VDD_MPU_OPPTURBO_UV, OMAP44XX_CONTROL_FUSE_MPU_OPPTURBO, 0xfa, 0x23),
- VOLT_DATA_DEFINE(OMAP4430_VDD_MPU_OPPNITRO_UV, OMAP44XX_CONTROL_FUSE_MPU_OPPNITRO, 0xfa, 0x27),
- VOLT_DATA_DEFINE(0, 0, 0, 0),
-};
-
-static struct omap_volt_data omap44xx_vdd_iva_volt_data[] = {
- VOLT_DATA_DEFINE(OMAP4430_VDD_IVA_OPP50_UV, OMAP44XX_CONTROL_FUSE_IVA_OPP50, 0xf4, 0x0c),
- VOLT_DATA_DEFINE(OMAP4430_VDD_IVA_OPP100_UV, OMAP44XX_CONTROL_FUSE_IVA_OPP100, 0xf9, 0x16),
- VOLT_DATA_DEFINE(OMAP4430_VDD_IVA_OPPTURBO_UV, OMAP44XX_CONTROL_FUSE_IVA_OPPTURBO, 0xfa, 0x23),
- VOLT_DATA_DEFINE(0, 0, 0, 0),
-};
-
-static struct omap_volt_data omap44xx_vdd_core_volt_data[] = {
- VOLT_DATA_DEFINE(OMAP4430_VDD_CORE_OPP50_UV, OMAP44XX_CONTROL_FUSE_CORE_OPP50, 0xf4, 0x0c),
- VOLT_DATA_DEFINE(OMAP4430_VDD_CORE_OPP100_UV, OMAP44XX_CONTROL_FUSE_CORE_OPP100, 0xf9, 0x16),
- VOLT_DATA_DEFINE(0, 0, 0, 0),
-};
+/* XXX document */
+static s16 prm_mod_offs;
+static s16 prm_irqst_ocp_mod_offs;
static struct dentry *voltage_dir;
/* Init function pointers */
-static void (*vc_init) (struct omap_vdd_info *vdd);
-static int (*vdd_data_configure) (struct omap_vdd_info *vdd);
+static int vp_forceupdate_scale_voltage(struct omap_vdd_info *vdd,
+ unsigned long target_volt);
static u32 omap3_voltage_read_reg(u16 mod, u8 offset)
{
@@ -336,6 +81,60 @@ static void omap4_voltage_write_reg(u32 val, u16 mod, u8 offset)
omap4_prminst_write_inst_reg(val, OMAP4430_PRM_PARTITION, mod, offset);
}
+static int __init _config_common_vdd_data(struct omap_vdd_info *vdd)
+{
+ char *sys_ck_name;
+ struct clk *sys_ck;
+ u32 sys_clk_speed, timeout_val, waittime;
+
+ /*
+ * XXX Clockfw should handle this, or this should be in a
+ * struct record
+ */
+ if (cpu_is_omap24xx() || cpu_is_omap34xx())
+ sys_ck_name = "sys_ck";
+ else if (cpu_is_omap44xx())
+ sys_ck_name = "sys_clkin_ck";
+
+ /*
+ * Sys clk rate is require to calculate vp timeout value and
+ * smpswaittimemin and smpswaittimemax.
+ */
+ sys_ck = clk_get(NULL, sys_ck_name);
+ if (IS_ERR(sys_ck)) {
+ pr_warning("%s: Could not get the sys clk to calculate"
+ "various vdd_%s params\n", __func__, vdd->voltdm.name);
+ return -EINVAL;
+ }
+ sys_clk_speed = clk_get_rate(sys_ck);
+ clk_put(sys_ck);
+ /* Divide to avoid overflow */
+ sys_clk_speed /= 1000;
+
+ /* Generic voltage parameters */
+ vdd->curr_volt = 1200000;
+ vdd->volt_scale = vp_forceupdate_scale_voltage;
+ vdd->vp_enabled = false;
+
+ vdd->vp_rt_data.vpconfig_erroroffset =
+ (vdd->pmic_info->vp_erroroffset <<
+ vdd->vp_data->vp_common->vpconfig_erroroffset_shift);
+
+ timeout_val = (sys_clk_speed * vdd->pmic_info->vp_timeout_us) / 1000;
+ vdd->vp_rt_data.vlimitto_timeout = timeout_val;
+ vdd->vp_rt_data.vlimitto_vddmin = vdd->pmic_info->vp_vddmin;
+ vdd->vp_rt_data.vlimitto_vddmax = vdd->pmic_info->vp_vddmax;
+
+ waittime = ((vdd->pmic_info->step_size / vdd->pmic_info->slew_rate) *
+ sys_clk_speed) / 1000;
+ vdd->vp_rt_data.vstepmin_smpswaittimemin = waittime;
+ vdd->vp_rt_data.vstepmax_smpswaittimemax = waittime;
+ vdd->vp_rt_data.vstepmin_stepmin = vdd->pmic_info->vp_vstepmin;
+ vdd->vp_rt_data.vstepmax_stepmax = vdd->pmic_info->vp_vstepmax;
+
+ return 0;
+}
+
/* Voltage debugfs support */
static int vp_volt_debug_get(void *data, u64 *val)
{
@@ -347,7 +146,7 @@ static int vp_volt_debug_get(void *data, u64 *val)
return -EINVAL;
}
- vsel = vdd->read_reg(vdd->vp_reg.prm_mod, vdd->vp_offs.voltage);
+ vsel = vdd->read_reg(prm_mod_offs, vdd->vp_data->voltage);
pr_notice("curr_vsel = %x\n", vsel);
if (!vdd->pmic_info->vsel_to_uv) {
@@ -380,7 +179,6 @@ DEFINE_SIMPLE_ATTRIBUTE(nom_volt_debug_fops, nom_volt_debug_get, NULL,
static void vp_latch_vsel(struct omap_vdd_info *vdd)
{
u32 vpconfig;
- u16 mod;
unsigned long uvdc;
char vsel;
@@ -397,30 +195,27 @@ static void vp_latch_vsel(struct omap_vdd_info *vdd)
return;
}
- mod = vdd->vp_reg.prm_mod;
-
vsel = vdd->pmic_info->uv_to_vsel(uvdc);
- vpconfig = vdd->read_reg(mod, vdd->vp_offs.vpconfig);
- vpconfig &= ~(vdd->vp_reg.vpconfig_initvoltage_mask |
- vdd->vp_reg.vpconfig_initvdd);
- vpconfig |= vsel << vdd->vp_reg.vpconfig_initvoltage_shift;
+ vpconfig = vdd->read_reg(prm_mod_offs, vdd->vp_data->vpconfig);
+ vpconfig &= ~(vdd->vp_data->vp_common->vpconfig_initvoltage_mask |
+ vdd->vp_data->vp_common->vpconfig_initvdd);
+ vpconfig |= vsel << vdd->vp_data->vp_common->vpconfig_initvoltage_shift;
- vdd->write_reg(vpconfig, mod, vdd->vp_offs.vpconfig);
+ vdd->write_reg(vpconfig, prm_mod_offs, vdd->vp_data->vpconfig);
/* Trigger initVDD value copy to voltage processor */
- vdd->write_reg((vpconfig | vdd->vp_reg.vpconfig_initvdd), mod,
- vdd->vp_offs.vpconfig);
+ vdd->write_reg((vpconfig | vdd->vp_data->vp_common->vpconfig_initvdd),
+ prm_mod_offs, vdd->vp_data->vpconfig);
/* Clear initVDD copy trigger bit */
- vdd->write_reg(vpconfig, mod, vdd->vp_offs.vpconfig);
+ vdd->write_reg(vpconfig, prm_mod_offs, vdd->vp_data->vpconfig);
}
/* Generic voltage init functions */
static void __init vp_init(struct omap_vdd_info *vdd)
{
u32 vp_val;
- u16 mod;
if (!vdd->read_reg || !vdd->write_reg) {
pr_err("%s: No read/write API for accessing vdd_%s regs\n",
@@ -428,33 +223,31 @@ static void __init vp_init(struct omap_vdd_info *vdd)
return;
}
- mod = vdd->vp_reg.prm_mod;
-
- vp_val = vdd->vp_reg.vpconfig_erroroffset |
- (vdd->vp_reg.vpconfig_errorgain <<
- vdd->vp_reg.vpconfig_errorgain_shift) |
- vdd->vp_reg.vpconfig_timeouten;
- vdd->write_reg(vp_val, mod, vdd->vp_offs.vpconfig);
-
- vp_val = ((vdd->vp_reg.vstepmin_smpswaittimemin <<
- vdd->vp_reg.vstepmin_smpswaittimemin_shift) |
- (vdd->vp_reg.vstepmin_stepmin <<
- vdd->vp_reg.vstepmin_stepmin_shift));
- vdd->write_reg(vp_val, mod, vdd->vp_offs.vstepmin);
-
- vp_val = ((vdd->vp_reg.vstepmax_smpswaittimemax <<
- vdd->vp_reg.vstepmax_smpswaittimemax_shift) |
- (vdd->vp_reg.vstepmax_stepmax <<
- vdd->vp_reg.vstepmax_stepmax_shift));
- vdd->write_reg(vp_val, mod, vdd->vp_offs.vstepmax);
-
- vp_val = ((vdd->vp_reg.vlimitto_vddmax <<
- vdd->vp_reg.vlimitto_vddmax_shift) |
- (vdd->vp_reg.vlimitto_vddmin <<
- vdd->vp_reg.vlimitto_vddmin_shift) |
- (vdd->vp_reg.vlimitto_timeout <<
- vdd->vp_reg.vlimitto_timeout_shift));
- vdd->write_reg(vp_val, mod, vdd->vp_offs.vlimitto);
+ vp_val = vdd->vp_rt_data.vpconfig_erroroffset |
+ (vdd->vp_rt_data.vpconfig_errorgain <<
+ vdd->vp_data->vp_common->vpconfig_errorgain_shift) |
+ vdd->vp_data->vp_common->vpconfig_timeouten;
+ vdd->write_reg(vp_val, prm_mod_offs, vdd->vp_data->vpconfig);
+
+ vp_val = ((vdd->vp_rt_data.vstepmin_smpswaittimemin <<
+ vdd->vp_data->vp_common->vstepmin_smpswaittimemin_shift) |
+ (vdd->vp_rt_data.vstepmin_stepmin <<
+ vdd->vp_data->vp_common->vstepmin_stepmin_shift));
+ vdd->write_reg(vp_val, prm_mod_offs, vdd->vp_data->vstepmin);
+
+ vp_val = ((vdd->vp_rt_data.vstepmax_smpswaittimemax <<
+ vdd->vp_data->vp_common->vstepmax_smpswaittimemax_shift) |
+ (vdd->vp_rt_data.vstepmax_stepmax <<
+ vdd->vp_data->vp_common->vstepmax_stepmax_shift));
+ vdd->write_reg(vp_val, prm_mod_offs, vdd->vp_data->vstepmax);
+
+ vp_val = ((vdd->vp_rt_data.vlimitto_vddmax <<
+ vdd->vp_data->vp_common->vlimitto_vddmax_shift) |
+ (vdd->vp_rt_data.vlimitto_vddmin <<
+ vdd->vp_data->vp_common->vlimitto_vddmin_shift) |
+ (vdd->vp_rt_data.vlimitto_timeout <<
+ vdd->vp_data->vp_common->vlimitto_timeout_shift));
+ vdd->write_reg(vp_val, prm_mod_offs, vdd->vp_data->vlimitto);
}
static void __init vdd_debugfs_init(struct omap_vdd_info *vdd)
@@ -481,23 +274,23 @@ static void __init vdd_debugfs_init(struct omap_vdd_info *vdd)
}
(void) debugfs_create_x16("vp_errorgain", S_IRUGO, vdd->debug_dir,
- &(vdd->vp_reg.vpconfig_errorgain));
+ &(vdd->vp_rt_data.vpconfig_errorgain));
(void) debugfs_create_x16("vp_smpswaittimemin", S_IRUGO,
vdd->debug_dir,
- &(vdd->vp_reg.vstepmin_smpswaittimemin));
+ &(vdd->vp_rt_data.vstepmin_smpswaittimemin));
(void) debugfs_create_x8("vp_stepmin", S_IRUGO, vdd->debug_dir,
- &(vdd->vp_reg.vstepmin_stepmin));
+ &(vdd->vp_rt_data.vstepmin_stepmin));
(void) debugfs_create_x16("vp_smpswaittimemax", S_IRUGO,
vdd->debug_dir,
- &(vdd->vp_reg.vstepmax_smpswaittimemax));
+ &(vdd->vp_rt_data.vstepmax_smpswaittimemax));
(void) debugfs_create_x8("vp_stepmax", S_IRUGO, vdd->debug_dir,
- &(vdd->vp_reg.vstepmax_stepmax));
+ &(vdd->vp_rt_data.vstepmax_stepmax));
(void) debugfs_create_x8("vp_vddmax", S_IRUGO, vdd->debug_dir,
- &(vdd->vp_reg.vlimitto_vddmax));
+ &(vdd->vp_rt_data.vlimitto_vddmax));
(void) debugfs_create_x8("vp_vddmin", S_IRUGO, vdd->debug_dir,
- &(vdd->vp_reg.vlimitto_vddmin));
+ &(vdd->vp_rt_data.vlimitto_vddmin));
(void) debugfs_create_x16("vp_timeout", S_IRUGO, vdd->debug_dir,
- &(vdd->vp_reg.vlimitto_timeout));
+ &(vdd->vp_rt_data.vlimitto_timeout));
(void) debugfs_create_file("curr_vp_volt", S_IRUGO, vdd->debug_dir,
(void *) vdd, &vp_volt_debug_fops);
(void) debugfs_create_file("curr_nominal_volt", S_IRUGO,
@@ -510,8 +303,12 @@ static int _pre_volt_scale(struct omap_vdd_info *vdd,
unsigned long target_volt, u8 *target_vsel, u8 *current_vsel)
{
struct omap_volt_data *volt_data;
+ const struct omap_vc_common_data *vc_common;
+ const struct omap_vp_common_data *vp_common;
u32 vc_cmdval, vp_errgain_val;
- u16 vp_mod, vc_mod;
+
+ vc_common = vdd->vc_data->vc_common;
+ vp_common = vdd->vp_data->vp_common;
/* Check if suffiecient pmic info is available for this vdd */
if (!vdd->pmic_info) {
@@ -533,33 +330,30 @@ static int _pre_volt_scale(struct omap_vdd_info *vdd,
return -EINVAL;
}
- vp_mod = vdd->vp_reg.prm_mod;
- vc_mod = vdd->vc_reg.prm_mod;
-
/* Get volt_data corresponding to target_volt */
volt_data = omap_voltage_get_voltdata(&vdd->voltdm, target_volt);
if (IS_ERR(volt_data))
volt_data = NULL;
*target_vsel = vdd->pmic_info->uv_to_vsel(target_volt);
- *current_vsel = vdd->read_reg(vp_mod, vdd->vp_offs.voltage);
+ *current_vsel = vdd->read_reg(prm_mod_offs, vdd->vp_data->voltage);
/* Setting the ON voltage to the new target voltage */
- vc_cmdval = vdd->read_reg(vc_mod, vdd->vc_reg.cmdval_reg);
- vc_cmdval &= ~vdd->vc_reg.cmd_on_mask;
- vc_cmdval |= (*target_vsel << vdd->vc_reg.cmd_on_shift);
- vdd->write_reg(vc_cmdval, vc_mod, vdd->vc_reg.cmdval_reg);
+ vc_cmdval = vdd->read_reg(prm_mod_offs, vdd->vc_data->cmdval_reg);
+ vc_cmdval &= ~vc_common->cmd_on_mask;
+ vc_cmdval |= (*target_vsel << vc_common->cmd_on_shift);
+ vdd->write_reg(vc_cmdval, prm_mod_offs, vdd->vc_data->cmdval_reg);
/* Setting vp errorgain based on the voltage */
if (volt_data) {
- vp_errgain_val = vdd->read_reg(vp_mod,
- vdd->vp_offs.vpconfig);
- vdd->vp_reg.vpconfig_errorgain = volt_data->vp_errgain;
- vp_errgain_val &= ~vdd->vp_reg.vpconfig_errorgain_mask;
- vp_errgain_val |= vdd->vp_reg.vpconfig_errorgain <<
- vdd->vp_reg.vpconfig_errorgain_shift;
- vdd->write_reg(vp_errgain_val, vp_mod,
- vdd->vp_offs.vpconfig);
+ vp_errgain_val = vdd->read_reg(prm_mod_offs,
+ vdd->vp_data->vpconfig);
+ vdd->vp_rt_data.vpconfig_errorgain = volt_data->vp_errgain;
+ vp_errgain_val &= ~vp_common->vpconfig_errorgain_mask;
+ vp_errgain_val |= vdd->vp_rt_data.vpconfig_errorgain <<
+ vp_common->vpconfig_errorgain_shift;
+ vdd->write_reg(vp_errgain_val, prm_mod_offs,
+ vdd->vp_data->vpconfig);
}
return 0;
@@ -585,7 +379,6 @@ static int vc_bypass_scale_voltage(struct omap_vdd_info *vdd,
{
u32 loop_cnt = 0, retries_cnt = 0;
u32 vc_valid, vc_bypass_val_reg, vc_bypass_value;
- u16 mod;
u8 target_vsel, current_vsel;
int ret;
@@ -593,20 +386,19 @@ static int vc_bypass_scale_voltage(struct omap_vdd_info *vdd,
if (ret)
return ret;
- mod = vdd->vc_reg.prm_mod;
-
- vc_valid = vdd->vc_reg.valid;
- vc_bypass_val_reg = vdd->vc_reg.bypass_val_reg;
- vc_bypass_value = (target_vsel << vdd->vc_reg.data_shift) |
+ vc_valid = vdd->vc_data->vc_common->valid;
+ vc_bypass_val_reg = vdd->vc_data->vc_common->bypass_val_reg;
+ vc_bypass_value = (target_vsel << vdd->vc_data->vc_common->data_shift) |
(vdd->pmic_info->pmic_reg <<
- vdd->vc_reg.regaddr_shift) |
+ vdd->vc_data->vc_common->regaddr_shift) |
(vdd->pmic_info->i2c_slave_addr <<
- vdd->vc_reg.slaveaddr_shift);
+ vdd->vc_data->vc_common->slaveaddr_shift);
- vdd->write_reg(vc_bypass_value, mod, vc_bypass_val_reg);
- vdd->write_reg(vc_bypass_value | vc_valid, mod, vc_bypass_val_reg);
+ vdd->write_reg(vc_bypass_value, prm_mod_offs, vc_bypass_val_reg);
+ vdd->write_reg(vc_bypass_value | vc_valid, prm_mod_offs,
+ vc_bypass_val_reg);
- vc_bypass_value = vdd->read_reg(mod, vc_bypass_val_reg);
+ vc_bypass_value = vdd->read_reg(prm_mod_offs, vc_bypass_val_reg);
/*
* Loop till the bypass command is acknowledged from the SMPS.
* NOTE: This is legacy code. The loop count and retry count needs
@@ -625,7 +417,8 @@ static int vc_bypass_scale_voltage(struct omap_vdd_info *vdd,
loop_cnt = 0;
udelay(10);
}
- vc_bypass_value = vdd->read_reg(mod, vc_bypass_val_reg);
+ vc_bypass_value = vdd->read_reg(prm_mod_offs,
+ vc_bypass_val_reg);
}
_post_volt_scale(vdd, target_volt, target_vsel, current_vsel);
@@ -637,7 +430,6 @@ static int vp_forceupdate_scale_voltage(struct omap_vdd_info *vdd,
unsigned long target_volt)
{
u32 vpconfig;
- u16 mod, ocp_mod;
u8 target_vsel, current_vsel, prm_irqst_reg;
int ret, timeout = 0;
@@ -645,20 +437,18 @@ static int vp_forceupdate_scale_voltage(struct omap_vdd_info *vdd,
if (ret)
return ret;
- mod = vdd->vp_reg.prm_mod;
- ocp_mod = vdd->ocp_mod;
- prm_irqst_reg = vdd->prm_irqst_reg;
+ prm_irqst_reg = vdd->vp_data->prm_irqst_data->prm_irqst_reg;
/*
* Clear all pending TransactionDone interrupt/status. Typical latency
* is <3us
*/
while (timeout++ < VP_TRANXDONE_TIMEOUT) {
- vdd->write_reg(vdd->vp_reg.tranxdone_status,
- ocp_mod, prm_irqst_reg);
- if (!(vdd->read_reg(ocp_mod, prm_irqst_reg) &
- vdd->vp_reg.tranxdone_status))
- break;
+ vdd->write_reg(vdd->vp_data->prm_irqst_data->tranxdone_status,
+ prm_irqst_ocp_mod_offs, prm_irqst_reg);
+ if (!(vdd->read_reg(prm_irqst_ocp_mod_offs, prm_irqst_reg) &
+ vdd->vp_data->prm_irqst_data->tranxdone_status))
+ break;
udelay(1);
}
if (timeout >= VP_TRANXDONE_TIMEOUT) {
@@ -668,30 +458,30 @@ static int vp_forceupdate_scale_voltage(struct omap_vdd_info *vdd,
}
/* Configure for VP-Force Update */
- vpconfig = vdd->read_reg(mod, vdd->vp_offs.vpconfig);
- vpconfig &= ~(vdd->vp_reg.vpconfig_initvdd |
- vdd->vp_reg.vpconfig_forceupdate |
- vdd->vp_reg.vpconfig_initvoltage_mask);
+ vpconfig = vdd->read_reg(prm_mod_offs, vdd->vp_data->vpconfig);
+ vpconfig &= ~(vdd->vp_data->vp_common->vpconfig_initvdd |
+ vdd->vp_data->vp_common->vpconfig_forceupdate |
+ vdd->vp_data->vp_common->vpconfig_initvoltage_mask);
vpconfig |= ((target_vsel <<
- vdd->vp_reg.vpconfig_initvoltage_shift));
- vdd->write_reg(vpconfig, mod, vdd->vp_offs.vpconfig);
+ vdd->vp_data->vp_common->vpconfig_initvoltage_shift));
+ vdd->write_reg(vpconfig, prm_mod_offs, vdd->vp_data->vpconfig);
/* Trigger initVDD value copy to voltage processor */
- vpconfig |= vdd->vp_reg.vpconfig_initvdd;
- vdd->write_reg(vpconfig, mod, vdd->vp_offs.vpconfig);
+ vpconfig |= vdd->vp_data->vp_common->vpconfig_initvdd;
+ vdd->write_reg(vpconfig, prm_mod_offs, vdd->vp_data->vpconfig);
/* Force update of voltage */
- vpconfig |= vdd->vp_reg.vpconfig_forceupdate;
- vdd->write_reg(vpconfig, mod, vdd->vp_offs.vpconfig);
+ vpconfig |= vdd->vp_data->vp_common->vpconfig_forceupdate;
+ vdd->write_reg(vpconfig, prm_mod_offs, vdd->vp_data->vpconfig);
/*
* Wait for TransactionDone. Typical latency is <200us.
* Depends on SMPSWAITTIMEMIN/MAX and voltage change
*/
timeout = 0;
- omap_test_timeout((vdd->read_reg(ocp_mod, prm_irqst_reg) &
- vdd->vp_reg.tranxdone_status),
- VP_TRANXDONE_TIMEOUT, timeout);
+ omap_test_timeout((vdd->read_reg(prm_irqst_ocp_mod_offs, prm_irqst_reg) &
+ vdd->vp_data->prm_irqst_data->tranxdone_status),
+ VP_TRANXDONE_TIMEOUT, timeout);
if (timeout >= VP_TRANXDONE_TIMEOUT)
pr_err("%s: vdd_%s TRANXDONE timeout exceeded."
"TRANXDONE never got set after the voltage update\n",
@@ -705,11 +495,11 @@ static int vp_forceupdate_scale_voltage(struct omap_vdd_info *vdd,
*/
timeout = 0;
while (timeout++ < VP_TRANXDONE_TIMEOUT) {
- vdd->write_reg(vdd->vp_reg.tranxdone_status,
- ocp_mod, prm_irqst_reg);
- if (!(vdd->read_reg(ocp_mod, prm_irqst_reg) &
- vdd->vp_reg.tranxdone_status))
- break;
+ vdd->write_reg(vdd->vp_data->prm_irqst_data->tranxdone_status,
+ prm_irqst_ocp_mod_offs, prm_irqst_reg);
+ if (!(vdd->read_reg(prm_irqst_ocp_mod_offs, prm_irqst_reg) &
+ vdd->vp_data->prm_irqst_data->tranxdone_status))
+ break;
udelay(1);
}
@@ -718,222 +508,95 @@ static int vp_forceupdate_scale_voltage(struct omap_vdd_info *vdd,
"to clear the TRANXDONE status\n",
__func__, vdd->voltdm.name);
- vpconfig = vdd->read_reg(mod, vdd->vp_offs.vpconfig);
+ vpconfig = vdd->read_reg(prm_mod_offs, vdd->vp_data->vpconfig);
/* Clear initVDD copy trigger bit */
- vpconfig &= ~vdd->vp_reg.vpconfig_initvdd;;
- vdd->write_reg(vpconfig, mod, vdd->vp_offs.vpconfig);
+ vpconfig &= ~vdd->vp_data->vp_common->vpconfig_initvdd;
+ vdd->write_reg(vpconfig, prm_mod_offs, vdd->vp_data->vpconfig);
/* Clear force bit */
- vpconfig &= ~vdd->vp_reg.vpconfig_forceupdate;
- vdd->write_reg(vpconfig, mod, vdd->vp_offs.vpconfig);
+ vpconfig &= ~vdd->vp_data->vp_common->vpconfig_forceupdate;
+ vdd->write_reg(vpconfig, prm_mod_offs, vdd->vp_data->vpconfig);
return 0;
}
-/* OMAP3 specific voltage init functions */
+static void __init omap3_vfsm_init(struct omap_vdd_info *vdd)
+{
+ /*
+ * Voltage Manager FSM parameters init
+ * XXX This data should be passed in from the board file
+ */
+ vdd->write_reg(OMAP3_CLKSETUP, prm_mod_offs, OMAP3_PRM_CLKSETUP_OFFSET);
+ vdd->write_reg(OMAP3_VOLTOFFSET, prm_mod_offs,
+ OMAP3_PRM_VOLTOFFSET_OFFSET);
+ vdd->write_reg(OMAP3_VOLTSETUP2, prm_mod_offs,
+ OMAP3_PRM_VOLTSETUP2_OFFSET);
+}
-/*
- * Intializes the voltage controller registers with the PMIC and board
- * specific parameters and voltage setup times for OMAP3.
- */
static void __init omap3_vc_init(struct omap_vdd_info *vdd)
{
- u32 vc_val;
- u16 mod;
- u8 on_vsel, onlp_vsel, ret_vsel, off_vsel;
static bool is_initialized;
+ u8 on_vsel, onlp_vsel, ret_vsel, off_vsel;
+ u32 vc_val;
- if (!vdd->pmic_info || !vdd->pmic_info->uv_to_vsel) {
- pr_err("%s: PMIC info requried to configure vc for"
- "vdd_%s not populated.Hence cannot initialize vc\n",
- __func__, vdd->voltdm.name);
- return;
- }
-
- if (!vdd->read_reg || !vdd->write_reg) {
- pr_err("%s: No read/write API for accessing vdd_%s regs\n",
- __func__, vdd->voltdm.name);
+ if (is_initialized)
return;
- }
-
- mod = vdd->vc_reg.prm_mod;
-
- /* Set up the SMPS_SA(i2c slave address in VC */
- vc_val = vdd->read_reg(mod, vdd->vc_reg.smps_sa_reg);
- vc_val &= ~vdd->vc_reg.smps_sa_mask;
- vc_val |= vdd->pmic_info->i2c_slave_addr << vdd->vc_reg.smps_sa_shift;
- vdd->write_reg(vc_val, mod, vdd->vc_reg.smps_sa_reg);
-
- /* Setup the VOLRA(pmic reg addr) in VC */
- vc_val = vdd->read_reg(mod, vdd->vc_reg.smps_volra_reg);
- vc_val &= ~vdd->vc_reg.smps_volra_mask;
- vc_val |= vdd->pmic_info->pmic_reg << vdd->vc_reg.smps_volra_shift;
- vdd->write_reg(vc_val, mod, vdd->vc_reg.smps_volra_reg);
-
- /*Configure the setup times */
- vc_val = vdd->read_reg(mod, vdd->vc_reg.voltsetup_reg);
- vc_val &= ~vdd->vc_reg.voltsetup_mask;
- vc_val |= vdd->pmic_info->volt_setup_time <<
- vdd->vc_reg.voltsetup_shift;
- vdd->write_reg(vc_val, mod, vdd->vc_reg.voltsetup_reg);
/* Set up the on, inactive, retention and off voltage */
on_vsel = vdd->pmic_info->uv_to_vsel(vdd->pmic_info->on_volt);
onlp_vsel = vdd->pmic_info->uv_to_vsel(vdd->pmic_info->onlp_volt);
ret_vsel = vdd->pmic_info->uv_to_vsel(vdd->pmic_info->ret_volt);
off_vsel = vdd->pmic_info->uv_to_vsel(vdd->pmic_info->off_volt);
- vc_val = ((on_vsel << vdd->vc_reg.cmd_on_shift) |
- (onlp_vsel << vdd->vc_reg.cmd_onlp_shift) |
- (ret_vsel << vdd->vc_reg.cmd_ret_shift) |
- (off_vsel << vdd->vc_reg.cmd_off_shift));
- vdd->write_reg(vc_val, mod, vdd->vc_reg.cmdval_reg);
-
- if (is_initialized)
- return;
+ vc_val = ((on_vsel << vdd->vc_data->vc_common->cmd_on_shift) |
+ (onlp_vsel << vdd->vc_data->vc_common->cmd_onlp_shift) |
+ (ret_vsel << vdd->vc_data->vc_common->cmd_ret_shift) |
+ (off_vsel << vdd->vc_data->vc_common->cmd_off_shift));
+ vdd->write_reg(vc_val, prm_mod_offs, vdd->vc_data->cmdval_reg);
- /* Generic VC parameters init */
- vdd->write_reg(OMAP3430_CMD1_MASK | OMAP3430_RAV1_MASK, mod,
+ /*
+ * Generic VC parameters init
+ * XXX This data should be abstracted out
+ */
+ vdd->write_reg(OMAP3430_CMD1_MASK | OMAP3430_RAV1_MASK, prm_mod_offs,
OMAP3_PRM_VC_CH_CONF_OFFSET);
- vdd->write_reg(OMAP3430_MCODE_SHIFT | OMAP3430_HSEN_MASK, mod,
+ vdd->write_reg(OMAP3430_MCODE_SHIFT | OMAP3430_HSEN_MASK, prm_mod_offs,
OMAP3_PRM_VC_I2C_CFG_OFFSET);
- vdd->write_reg(OMAP3_CLKSETUP, mod, OMAP3_PRM_CLKSETUP_OFFSET);
- vdd->write_reg(OMAP3_VOLTOFFSET, mod, OMAP3_PRM_VOLTOFFSET_OFFSET);
- vdd->write_reg(OMAP3_VOLTSETUP2, mod, OMAP3_PRM_VOLTSETUP2_OFFSET);
+
+ omap3_vfsm_init(vdd);
+
is_initialized = true;
}
-/* Sets up all the VDD related info for OMAP3 */
-static int __init omap3_vdd_data_configure(struct omap_vdd_info *vdd)
+
+/* OMAP4 specific voltage init functions */
+static void __init omap4_vc_init(struct omap_vdd_info *vdd)
{
- struct clk *sys_ck;
- u32 sys_clk_speed, timeout_val, waittime;
+ static bool is_initialized;
+ u32 vc_val;
- if (!vdd->pmic_info) {
- pr_err("%s: PMIC info requried to configure vdd_%s not"
- "populated.Hence cannot initialize vdd_%s\n",
- __func__, vdd->voltdm.name, vdd->voltdm.name);
- return -EINVAL;
- }
+ if (is_initialized)
+ return;
- if (!strcmp(vdd->voltdm.name, "mpu")) {
- if (cpu_is_omap3630())
- vdd->volt_data = omap36xx_vddmpu_volt_data;
- else
- vdd->volt_data = omap34xx_vddmpu_volt_data;
-
- vdd->vp_reg.tranxdone_status = OMAP3430_VP1_TRANXDONE_ST_MASK;
- vdd->vc_reg.cmdval_reg = OMAP3_PRM_VC_CMD_VAL_0_OFFSET;
- vdd->vc_reg.smps_sa_shift = OMAP3430_PRM_VC_SMPS_SA_SA0_SHIFT;
- vdd->vc_reg.smps_sa_mask = OMAP3430_PRM_VC_SMPS_SA_SA0_MASK;
- vdd->vc_reg.smps_volra_shift = OMAP3430_VOLRA0_SHIFT;
- vdd->vc_reg.smps_volra_mask = OMAP3430_VOLRA0_MASK;
- vdd->vc_reg.voltsetup_shift = OMAP3430_SETUP_TIME1_SHIFT;
- vdd->vc_reg.voltsetup_mask = OMAP3430_SETUP_TIME1_MASK;
- } else if (!strcmp(vdd->voltdm.name, "core")) {
- if (cpu_is_omap3630())
- vdd->volt_data = omap36xx_vddcore_volt_data;
- else
- vdd->volt_data = omap34xx_vddcore_volt_data;
-
- vdd->vp_reg.tranxdone_status = OMAP3430_VP2_TRANXDONE_ST_MASK;
- vdd->vc_reg.cmdval_reg = OMAP3_PRM_VC_CMD_VAL_1_OFFSET;
- vdd->vc_reg.smps_sa_shift = OMAP3430_PRM_VC_SMPS_SA_SA1_SHIFT;
- vdd->vc_reg.smps_sa_mask = OMAP3430_PRM_VC_SMPS_SA_SA1_MASK;
- vdd->vc_reg.smps_volra_shift = OMAP3430_VOLRA1_SHIFT;
- vdd->vc_reg.smps_volra_mask = OMAP3430_VOLRA1_MASK;
- vdd->vc_reg.voltsetup_shift = OMAP3430_SETUP_TIME2_SHIFT;
- vdd->vc_reg.voltsetup_mask = OMAP3430_SETUP_TIME2_MASK;
- } else {
- pr_warning("%s: vdd_%s does not exisit in OMAP3\n",
- __func__, vdd->voltdm.name);
- return -EINVAL;
- }
+ /* TODO: Configure setup times and CMD_VAL values*/
/*
- * Sys clk rate is require to calculate vp timeout value and
- * smpswaittimemin and smpswaittimemax.
+ * Generic VC parameters init
+ * XXX This data should be abstracted out
*/
- sys_ck = clk_get(NULL, "sys_ck");
- if (IS_ERR(sys_ck)) {
- pr_warning("%s: Could not get the sys clk to calculate"
- "various vdd_%s params\n", __func__, vdd->voltdm.name);
- return -EINVAL;
- }
- sys_clk_speed = clk_get_rate(sys_ck);
- clk_put(sys_ck);
- /* Divide to avoid overflow */
- sys_clk_speed /= 1000;
-
- /* Generic voltage parameters */
- vdd->curr_volt = 1200000;
- vdd->ocp_mod = OCP_MOD;
- vdd->prm_irqst_reg = OMAP3_PRM_IRQSTATUS_MPU_OFFSET;
- vdd->read_reg = omap3_voltage_read_reg;
- vdd->write_reg = omap3_voltage_write_reg;
- vdd->volt_scale = vp_forceupdate_scale_voltage;
- vdd->vp_enabled = false;
+ vc_val = (OMAP4430_RAV_VDD_MPU_L_MASK | OMAP4430_CMD_VDD_MPU_L_MASK |
+ OMAP4430_RAV_VDD_IVA_L_MASK | OMAP4430_CMD_VDD_IVA_L_MASK |
+ OMAP4430_RAV_VDD_CORE_L_MASK | OMAP4430_CMD_VDD_CORE_L_MASK);
+ vdd->write_reg(vc_val, prm_mod_offs, OMAP4_PRM_VC_CFG_CHANNEL_OFFSET);
- /* VC parameters */
- vdd->vc_reg.prm_mod = OMAP3430_GR_MOD;
- vdd->vc_reg.smps_sa_reg = OMAP3_PRM_VC_SMPS_SA_OFFSET;
- vdd->vc_reg.smps_volra_reg = OMAP3_PRM_VC_SMPS_VOL_RA_OFFSET;
- vdd->vc_reg.bypass_val_reg = OMAP3_PRM_VC_BYPASS_VAL_OFFSET;
- vdd->vc_reg.voltsetup_reg = OMAP3_PRM_VOLTSETUP1_OFFSET;
- vdd->vc_reg.data_shift = OMAP3430_DATA_SHIFT;
- vdd->vc_reg.slaveaddr_shift = OMAP3430_SLAVEADDR_SHIFT;
- vdd->vc_reg.regaddr_shift = OMAP3430_REGADDR_SHIFT;
- vdd->vc_reg.valid = OMAP3430_VALID_MASK;
- vdd->vc_reg.cmd_on_shift = OMAP3430_VC_CMD_ON_SHIFT;
- vdd->vc_reg.cmd_on_mask = OMAP3430_VC_CMD_ON_MASK;
- vdd->vc_reg.cmd_onlp_shift = OMAP3430_VC_CMD_ONLP_SHIFT;
- vdd->vc_reg.cmd_ret_shift = OMAP3430_VC_CMD_RET_SHIFT;
- vdd->vc_reg.cmd_off_shift = OMAP3430_VC_CMD_OFF_SHIFT;
-
- vdd->vp_reg.prm_mod = OMAP3430_GR_MOD;
-
- /* VPCONFIG bit fields */
- vdd->vp_reg.vpconfig_erroroffset = (vdd->pmic_info->vp_erroroffset <<
- OMAP3430_ERROROFFSET_SHIFT);
- vdd->vp_reg.vpconfig_errorgain_mask = OMAP3430_ERRORGAIN_MASK;
- vdd->vp_reg.vpconfig_errorgain_shift = OMAP3430_ERRORGAIN_SHIFT;
- vdd->vp_reg.vpconfig_initvoltage_shift = OMAP3430_INITVOLTAGE_SHIFT;
- vdd->vp_reg.vpconfig_initvoltage_mask = OMAP3430_INITVOLTAGE_MASK;
- vdd->vp_reg.vpconfig_timeouten = OMAP3430_TIMEOUTEN_MASK;
- vdd->vp_reg.vpconfig_initvdd = OMAP3430_INITVDD_MASK;
- vdd->vp_reg.vpconfig_forceupdate = OMAP3430_FORCEUPDATE_MASK;
- vdd->vp_reg.vpconfig_vpenable = OMAP3430_VPENABLE_MASK;
-
- /* VSTEPMIN VSTEPMAX bit fields */
- waittime = ((vdd->pmic_info->step_size / vdd->pmic_info->slew_rate) *
- sys_clk_speed) / 1000;
- vdd->vp_reg.vstepmin_smpswaittimemin = waittime;
- vdd->vp_reg.vstepmax_smpswaittimemax = waittime;
- vdd->vp_reg.vstepmin_stepmin = vdd->pmic_info->vp_vstepmin;
- vdd->vp_reg.vstepmax_stepmax = vdd->pmic_info->vp_vstepmax;
- vdd->vp_reg.vstepmin_smpswaittimemin_shift =
- OMAP3430_SMPSWAITTIMEMIN_SHIFT;
- vdd->vp_reg.vstepmax_smpswaittimemax_shift =
- OMAP3430_SMPSWAITTIMEMAX_SHIFT;
- vdd->vp_reg.vstepmin_stepmin_shift = OMAP3430_VSTEPMIN_SHIFT;
- vdd->vp_reg.vstepmax_stepmax_shift = OMAP3430_VSTEPMAX_SHIFT;
-
- /* VLIMITTO bit fields */
- timeout_val = (sys_clk_speed * vdd->pmic_info->vp_timeout_us) / 1000;
- vdd->vp_reg.vlimitto_timeout = timeout_val;
- vdd->vp_reg.vlimitto_vddmin = vdd->pmic_info->vp_vddmin;
- vdd->vp_reg.vlimitto_vddmax = vdd->pmic_info->vp_vddmax;
- vdd->vp_reg.vlimitto_vddmin_shift = OMAP3430_VDDMIN_SHIFT;
- vdd->vp_reg.vlimitto_vddmax_shift = OMAP3430_VDDMAX_SHIFT;
- vdd->vp_reg.vlimitto_timeout_shift = OMAP3430_TIMEOUT_SHIFT;
+ /* XXX These are magic numbers and do not belong! */
+ vc_val = (0x60 << OMAP4430_SCLL_SHIFT | 0x26 << OMAP4430_SCLH_SHIFT);
+ vdd->write_reg(vc_val, prm_mod_offs, OMAP4_PRM_VC_CFG_I2C_CLK_OFFSET);
- return 0;
+ is_initialized = true;
}
-/* OMAP4 specific voltage init functions */
-static void __init omap4_vc_init(struct omap_vdd_info *vdd)
+static void __init omap_vc_init(struct omap_vdd_info *vdd)
{
u32 vc_val;
- u16 mod;
- static bool is_initialized;
if (!vdd->pmic_info || !vdd->pmic_info->uv_to_vsel) {
pr_err("%s: PMIC info requried to configure vc for"
@@ -948,173 +611,61 @@ static void __init omap4_vc_init(struct omap_vdd_info *vdd)
return;
}
- mod = vdd->vc_reg.prm_mod;
-
/* Set up the SMPS_SA(i2c slave address in VC */
- vc_val = vdd->read_reg(mod, vdd->vc_reg.smps_sa_reg);
- vc_val &= ~vdd->vc_reg.smps_sa_mask;
- vc_val |= vdd->pmic_info->i2c_slave_addr << vdd->vc_reg.smps_sa_shift;
- vdd->write_reg(vc_val, mod, vdd->vc_reg.smps_sa_reg);
+ vc_val = vdd->read_reg(prm_mod_offs,
+ vdd->vc_data->vc_common->smps_sa_reg);
+ vc_val &= ~vdd->vc_data->smps_sa_mask;
+ vc_val |= vdd->pmic_info->i2c_slave_addr << vdd->vc_data->smps_sa_shift;
+ vdd->write_reg(vc_val, prm_mod_offs,
+ vdd->vc_data->vc_common->smps_sa_reg);
/* Setup the VOLRA(pmic reg addr) in VC */
- vc_val = vdd->read_reg(mod, vdd->vc_reg.smps_volra_reg);
- vc_val &= ~vdd->vc_reg.smps_volra_mask;
- vc_val |= vdd->pmic_info->pmic_reg << vdd->vc_reg.smps_volra_shift;
- vdd->write_reg(vc_val, mod, vdd->vc_reg.smps_volra_reg);
-
- /* TODO: Configure setup times and CMD_VAL values*/
-
- if (is_initialized)
- return;
-
- /* Generic VC parameters init */
- vc_val = (OMAP4430_RAV_VDD_MPU_L_MASK | OMAP4430_CMD_VDD_MPU_L_MASK |
- OMAP4430_RAV_VDD_IVA_L_MASK | OMAP4430_CMD_VDD_IVA_L_MASK |
- OMAP4430_RAV_VDD_CORE_L_MASK | OMAP4430_CMD_VDD_CORE_L_MASK);
- vdd->write_reg(vc_val, mod, OMAP4_PRM_VC_CFG_CHANNEL_OFFSET);
-
- vc_val = (0x60 << OMAP4430_SCLL_SHIFT | 0x26 << OMAP4430_SCLH_SHIFT);
- vdd->write_reg(vc_val, mod, OMAP4_PRM_VC_CFG_I2C_CLK_OFFSET);
+ vc_val = vdd->read_reg(prm_mod_offs,
+ vdd->vc_data->vc_common->smps_volra_reg);
+ vc_val &= ~vdd->vc_data->smps_volra_mask;
+ vc_val |= vdd->pmic_info->pmic_reg << vdd->vc_data->smps_volra_shift;
+ vdd->write_reg(vc_val, prm_mod_offs,
+ vdd->vc_data->vc_common->smps_volra_reg);
+
+ /* Configure the setup times */
+ vc_val = vdd->read_reg(prm_mod_offs, vdd->vfsm->voltsetup_reg);
+ vc_val &= ~vdd->vfsm->voltsetup_mask;
+ vc_val |= vdd->pmic_info->volt_setup_time <<
+ vdd->vfsm->voltsetup_shift;
+ vdd->write_reg(vc_val, prm_mod_offs, vdd->vfsm->voltsetup_reg);
- is_initialized = true;
+ if (cpu_is_omap34xx())
+ omap3_vc_init(vdd);
+ else if (cpu_is_omap44xx())
+ omap4_vc_init(vdd);
}
-/* Sets up all the VDD related info for OMAP4 */
-static int __init omap4_vdd_data_configure(struct omap_vdd_info *vdd)
+static int __init omap_vdd_data_configure(struct omap_vdd_info *vdd)
{
- struct clk *sys_ck;
- u32 sys_clk_speed, timeout_val, waittime;
+ int ret = -EINVAL;
if (!vdd->pmic_info) {
pr_err("%s: PMIC info requried to configure vdd_%s not"
"populated.Hence cannot initialize vdd_%s\n",
__func__, vdd->voltdm.name, vdd->voltdm.name);
- return -EINVAL;
+ goto ovdc_out;
}
- if (!strcmp(vdd->voltdm.name, "mpu")) {
- vdd->volt_data = omap44xx_vdd_mpu_volt_data;
- vdd->vp_reg.tranxdone_status =
- OMAP4430_VP_MPU_TRANXDONE_ST_MASK;
- vdd->vc_reg.cmdval_reg = OMAP4_PRM_VC_VAL_CMD_VDD_MPU_L_OFFSET;
- vdd->vc_reg.smps_sa_shift =
- OMAP4430_SA_VDD_MPU_L_PRM_VC_SMPS_SA_SHIFT;
- vdd->vc_reg.smps_sa_mask =
- OMAP4430_SA_VDD_MPU_L_PRM_VC_SMPS_SA_MASK;
- vdd->vc_reg.smps_volra_shift = OMAP4430_VOLRA_VDD_MPU_L_SHIFT;
- vdd->vc_reg.smps_volra_mask = OMAP4430_VOLRA_VDD_MPU_L_MASK;
- vdd->vc_reg.voltsetup_reg =
- OMAP4_PRM_VOLTSETUP_MPU_RET_SLEEP_OFFSET;
- vdd->prm_irqst_reg = OMAP4_PRM_IRQSTATUS_MPU_2_OFFSET;
- } else if (!strcmp(vdd->voltdm.name, "core")) {
- vdd->volt_data = omap44xx_vdd_core_volt_data;
- vdd->vp_reg.tranxdone_status =
- OMAP4430_VP_CORE_TRANXDONE_ST_MASK;
- vdd->vc_reg.cmdval_reg =
- OMAP4_PRM_VC_VAL_CMD_VDD_CORE_L_OFFSET;
- vdd->vc_reg.smps_sa_shift = OMAP4430_SA_VDD_CORE_L_0_6_SHIFT;
- vdd->vc_reg.smps_sa_mask = OMAP4430_SA_VDD_CORE_L_0_6_MASK;
- vdd->vc_reg.smps_volra_shift = OMAP4430_VOLRA_VDD_CORE_L_SHIFT;
- vdd->vc_reg.smps_volra_mask = OMAP4430_VOLRA_VDD_CORE_L_MASK;
- vdd->vc_reg.voltsetup_reg =
- OMAP4_PRM_VOLTSETUP_CORE_RET_SLEEP_OFFSET;
- vdd->prm_irqst_reg = OMAP4_PRM_IRQSTATUS_MPU_OFFSET;
- } else if (!strcmp(vdd->voltdm.name, "iva")) {
- vdd->volt_data = omap44xx_vdd_iva_volt_data;
- vdd->vp_reg.tranxdone_status =
- OMAP4430_VP_IVA_TRANXDONE_ST_MASK;
- vdd->vc_reg.cmdval_reg = OMAP4_PRM_VC_VAL_CMD_VDD_IVA_L_OFFSET;
- vdd->vc_reg.smps_sa_shift =
- OMAP4430_SA_VDD_IVA_L_PRM_VC_SMPS_SA_SHIFT;
- vdd->vc_reg.smps_sa_mask =
- OMAP4430_SA_VDD_IVA_L_PRM_VC_SMPS_SA_MASK;
- vdd->vc_reg.smps_volra_shift = OMAP4430_VOLRA_VDD_IVA_L_SHIFT;
- vdd->vc_reg.smps_volra_mask = OMAP4430_VOLRA_VDD_IVA_L_MASK;
- vdd->vc_reg.voltsetup_reg =
- OMAP4_PRM_VOLTSETUP_IVA_RET_SLEEP_OFFSET;
- vdd->prm_irqst_reg = OMAP4_PRM_IRQSTATUS_MPU_OFFSET;
- } else {
- pr_warning("%s: vdd_%s does not exisit in OMAP4\n",
- __func__, vdd->voltdm.name);
- return -EINVAL;
- }
+ if (IS_ERR_VALUE(_config_common_vdd_data(vdd)))
+ goto ovdc_out;
- /*
- * Sys clk rate is require to calculate vp timeout value and
- * smpswaittimemin and smpswaittimemax.
- */
- sys_ck = clk_get(NULL, "sys_clkin_ck");
- if (IS_ERR(sys_ck)) {
- pr_warning("%s: Could not get the sys clk to calculate"
- "various vdd_%s params\n", __func__, vdd->voltdm.name);
- return -EINVAL;
+ if (cpu_is_omap34xx()) {
+ vdd->read_reg = omap3_voltage_read_reg;
+ vdd->write_reg = omap3_voltage_write_reg;
+ ret = 0;
+ } else if (cpu_is_omap44xx()) {
+ vdd->read_reg = omap4_voltage_read_reg;
+ vdd->write_reg = omap4_voltage_write_reg;
+ ret = 0;
}
- sys_clk_speed = clk_get_rate(sys_ck);
- clk_put(sys_ck);
- /* Divide to avoid overflow */
- sys_clk_speed /= 1000;
-
- /* Generic voltage parameters */
- vdd->curr_volt = 1200000;
- vdd->ocp_mod = OMAP4430_PRM_OCP_SOCKET_INST;
- vdd->read_reg = omap4_voltage_read_reg;
- vdd->write_reg = omap4_voltage_write_reg;
- vdd->volt_scale = vp_forceupdate_scale_voltage;
- vdd->vp_enabled = false;
- /* VC parameters */
- vdd->vc_reg.prm_mod = OMAP4430_PRM_DEVICE_INST;
- vdd->vc_reg.smps_sa_reg = OMAP4_PRM_VC_SMPS_SA_OFFSET;
- vdd->vc_reg.smps_volra_reg = OMAP4_PRM_VC_VAL_SMPS_RA_VOL_OFFSET;
- vdd->vc_reg.bypass_val_reg = OMAP4_PRM_VC_VAL_BYPASS_OFFSET;
- vdd->vc_reg.data_shift = OMAP4430_DATA_SHIFT;
- vdd->vc_reg.slaveaddr_shift = OMAP4430_SLAVEADDR_SHIFT;
- vdd->vc_reg.regaddr_shift = OMAP4430_REGADDR_SHIFT;
- vdd->vc_reg.valid = OMAP4430_VALID_MASK;
- vdd->vc_reg.cmd_on_shift = OMAP4430_ON_SHIFT;
- vdd->vc_reg.cmd_on_mask = OMAP4430_ON_MASK;
- vdd->vc_reg.cmd_onlp_shift = OMAP4430_ONLP_SHIFT;
- vdd->vc_reg.cmd_ret_shift = OMAP4430_RET_SHIFT;
- vdd->vc_reg.cmd_off_shift = OMAP4430_OFF_SHIFT;
-
- vdd->vp_reg.prm_mod = OMAP4430_PRM_DEVICE_INST;
-
- /* VPCONFIG bit fields */
- vdd->vp_reg.vpconfig_erroroffset = (vdd->pmic_info->vp_erroroffset <<
- OMAP4430_ERROROFFSET_SHIFT);
- vdd->vp_reg.vpconfig_errorgain_mask = OMAP4430_ERRORGAIN_MASK;
- vdd->vp_reg.vpconfig_errorgain_shift = OMAP4430_ERRORGAIN_SHIFT;
- vdd->vp_reg.vpconfig_initvoltage_shift = OMAP4430_INITVOLTAGE_SHIFT;
- vdd->vp_reg.vpconfig_initvoltage_mask = OMAP4430_INITVOLTAGE_MASK;
- vdd->vp_reg.vpconfig_timeouten = OMAP4430_TIMEOUTEN_MASK;
- vdd->vp_reg.vpconfig_initvdd = OMAP4430_INITVDD_MASK;
- vdd->vp_reg.vpconfig_forceupdate = OMAP4430_FORCEUPDATE_MASK;
- vdd->vp_reg.vpconfig_vpenable = OMAP4430_VPENABLE_MASK;
-
- /* VSTEPMIN VSTEPMAX bit fields */
- waittime = ((vdd->pmic_info->step_size / vdd->pmic_info->slew_rate) *
- sys_clk_speed) / 1000;
- vdd->vp_reg.vstepmin_smpswaittimemin = waittime;
- vdd->vp_reg.vstepmax_smpswaittimemax = waittime;
- vdd->vp_reg.vstepmin_stepmin = vdd->pmic_info->vp_vstepmin;
- vdd->vp_reg.vstepmax_stepmax = vdd->pmic_info->vp_vstepmax;
- vdd->vp_reg.vstepmin_smpswaittimemin_shift =
- OMAP4430_SMPSWAITTIMEMIN_SHIFT;
- vdd->vp_reg.vstepmax_smpswaittimemax_shift =
- OMAP4430_SMPSWAITTIMEMAX_SHIFT;
- vdd->vp_reg.vstepmin_stepmin_shift = OMAP4430_VSTEPMIN_SHIFT;
- vdd->vp_reg.vstepmax_stepmax_shift = OMAP4430_VSTEPMAX_SHIFT;
-
- /* VLIMITTO bit fields */
- timeout_val = (sys_clk_speed * vdd->pmic_info->vp_timeout_us) / 1000;
- vdd->vp_reg.vlimitto_timeout = timeout_val;
- vdd->vp_reg.vlimitto_vddmin = vdd->pmic_info->vp_vddmin;
- vdd->vp_reg.vlimitto_vddmax = vdd->pmic_info->vp_vddmax;
- vdd->vp_reg.vlimitto_vddmin_shift = OMAP4430_VDDMIN_SHIFT;
- vdd->vp_reg.vlimitto_vddmax_shift = OMAP4430_VDDMAX_SHIFT;
- vdd->vp_reg.vlimitto_timeout_shift = OMAP4430_TIMEOUT_SHIFT;
-
- return 0;
+ovdc_out:
+ return ret;
}
/* Public functions */
@@ -1162,8 +713,7 @@ unsigned long omap_vp_get_curr_volt(struct voltagedomain *voltdm)
return 0;
}
- curr_vsel = vdd->read_reg(vdd->vp_reg.prm_mod,
- vdd->vp_offs.voltage);
+ curr_vsel = vdd->read_reg(prm_mod_offs, vdd->vp_data->voltage);
if (!vdd->pmic_info || !vdd->pmic_info->vsel_to_uv) {
pr_warning("%s: PMIC function to convert vsel to voltage"
@@ -1185,7 +735,6 @@ void omap_vp_enable(struct voltagedomain *voltdm)
{
struct omap_vdd_info *vdd;
u32 vpconfig;
- u16 mod;
if (!voltdm || IS_ERR(voltdm)) {
pr_warning("%s: VDD specified does not exist!\n", __func__);
@@ -1199,8 +748,6 @@ void omap_vp_enable(struct voltagedomain *voltdm)
return;
}
- mod = vdd->vp_reg.prm_mod;
-
/* If VP is already enabled, do nothing. Return */
if (vdd->vp_enabled)
return;
@@ -1208,9 +755,9 @@ void omap_vp_enable(struct voltagedomain *voltdm)
vp_latch_vsel(vdd);
/* Enable VP */
- vpconfig = vdd->read_reg(mod, vdd->vp_offs.vpconfig);
- vpconfig |= vdd->vp_reg.vpconfig_vpenable;
- vdd->write_reg(vpconfig, mod, vdd->vp_offs.vpconfig);
+ vpconfig = vdd->read_reg(prm_mod_offs, vdd->vp_data->vpconfig);
+ vpconfig |= vdd->vp_data->vp_common->vpconfig_vpenable;
+ vdd->write_reg(vpconfig, prm_mod_offs, vdd->vp_data->vpconfig);
vdd->vp_enabled = true;
}
@@ -1225,7 +772,6 @@ void omap_vp_disable(struct voltagedomain *voltdm)
{
struct omap_vdd_info *vdd;
u32 vpconfig;
- u16 mod;
int timeout;
if (!voltdm || IS_ERR(voltdm)) {
@@ -1240,8 +786,6 @@ void omap_vp_disable(struct voltagedomain *voltdm)
return;
}
- mod = vdd->vp_reg.prm_mod;
-
/* If VP is already disabled, do nothing. Return */
if (!vdd->vp_enabled) {
pr_warning("%s: Trying to disable VP for vdd_%s when"
@@ -1250,14 +794,14 @@ void omap_vp_disable(struct voltagedomain *voltdm)
}
/* Disable VP */
- vpconfig = vdd->read_reg(mod, vdd->vp_offs.vpconfig);
- vpconfig &= ~vdd->vp_reg.vpconfig_vpenable;
- vdd->write_reg(vpconfig, mod, vdd->vp_offs.vpconfig);
+ vpconfig = vdd->read_reg(prm_mod_offs, vdd->vp_data->vpconfig);
+ vpconfig &= ~vdd->vp_data->vp_common->vpconfig_vpenable;
+ vdd->write_reg(vpconfig, prm_mod_offs, vdd->vp_data->vpconfig);
/*
* Wait for VP idle Typical latency is <2us. Maximum latency is ~100us
*/
- omap_test_timeout((vdd->read_reg(mod, vdd->vp_offs.vstatus)),
+ omap_test_timeout((vdd->read_reg(prm_mod_offs, vdd->vp_data->vstatus)),
VP_IDLE_TIMEOUT, timeout);
if (timeout >= VP_IDLE_TIMEOUT)
@@ -1510,8 +1054,8 @@ struct voltagedomain *omap_voltage_domain_lookup(char *name)
}
for (i = 0; i < nr_scalable_vdd; i++) {
- if (!(strcmp(name, vdd_info[i].voltdm.name)))
- return &vdd_info[i].voltdm;
+ if (!(strcmp(name, vdd_info[i]->voltdm.name)))
+ return &vdd_info[i]->voltdm;
}
return ERR_PTR(-EINVAL);
@@ -1539,35 +1083,24 @@ int __init omap_voltage_late_init(void)
pr_err("%s: Unable to create voltage debugfs main dir\n",
__func__);
for (i = 0; i < nr_scalable_vdd; i++) {
- if (vdd_data_configure(&vdd_info[i]))
+ if (omap_vdd_data_configure(vdd_info[i]))
continue;
- vc_init(&vdd_info[i]);
- vp_init(&vdd_info[i]);
- vdd_debugfs_init(&vdd_info[i]);
+ omap_vc_init(vdd_info[i]);
+ vp_init(vdd_info[i]);
+ vdd_debugfs_init(vdd_info[i]);
}
return 0;
}
-/**
- * omap_voltage_early_init()- Volatage driver early init
- */
-static int __init omap_voltage_early_init(void)
+/* XXX document */
+int __init omap_voltage_early_init(s16 prm_mod, s16 prm_irqst_ocp_mod,
+ struct omap_vdd_info *omap_vdd_array[],
+ u8 omap_vdd_count)
{
- if (cpu_is_omap34xx()) {
- vdd_info = omap3_vdd_info;
- nr_scalable_vdd = OMAP3_NR_SCALABLE_VDD;
- vc_init = omap3_vc_init;
- vdd_data_configure = omap3_vdd_data_configure;
- } else if (cpu_is_omap44xx()) {
- vdd_info = omap4_vdd_info;
- nr_scalable_vdd = OMAP4_NR_SCALABLE_VDD;
- vc_init = omap4_vc_init;
- vdd_data_configure = omap4_vdd_data_configure;
- } else {
- pr_warning("%s: voltage driver support not added\n", __func__);
- }
-
+ prm_mod_offs = prm_mod;
+ prm_irqst_ocp_mod_offs = prm_irqst_ocp_mod;
+ vdd_info = omap_vdd_array;
+ nr_scalable_vdd = omap_vdd_count;
return 0;
}
-core_initcall(omap_voltage_early_init);
diff --git a/arch/arm/mach-omap2/voltage.h b/arch/arm/mach-omap2/voltage.h
index 5bd204e..e9f5408 100644
--- a/arch/arm/mach-omap2/voltage.h
+++ b/arch/arm/mach-omap2/voltage.h
@@ -16,6 +16,10 @@
#include <linux/err.h>
+#include "vc.h"
+#include "vp.h"
+
+/* XXX document */
#define VOLTSCALE_VPFORCEUPDATE 1
#define VOLTSCALE_VCBYPASS 2
@@ -27,36 +31,22 @@
#define OMAP3_VOLTOFFSET 0xff
#define OMAP3_VOLTSETUP2 0xff
-/* Voltage value defines */
-#define OMAP3430_VDD_MPU_OPP1_UV 975000
-#define OMAP3430_VDD_MPU_OPP2_UV 1075000
-#define OMAP3430_VDD_MPU_OPP3_UV 1200000
-#define OMAP3430_VDD_MPU_OPP4_UV 1270000
-#define OMAP3430_VDD_MPU_OPP5_UV 1350000
-
-#define OMAP3430_VDD_CORE_OPP1_UV 975000
-#define OMAP3430_VDD_CORE_OPP2_UV 1050000
-#define OMAP3430_VDD_CORE_OPP3_UV 1150000
-
-#define OMAP3630_VDD_MPU_OPP50_UV 1012500
-#define OMAP3630_VDD_MPU_OPP100_UV 1200000
-#define OMAP3630_VDD_MPU_OPP120_UV 1325000
-#define OMAP3630_VDD_MPU_OPP1G_UV 1375000
-
-#define OMAP3630_VDD_CORE_OPP50_UV 1000000
-#define OMAP3630_VDD_CORE_OPP100_UV 1200000
-
-#define OMAP4430_VDD_MPU_OPP50_UV 930000
-#define OMAP4430_VDD_MPU_OPP100_UV 1100000
-#define OMAP4430_VDD_MPU_OPPTURBO_UV 1260000
-#define OMAP4430_VDD_MPU_OPPNITRO_UV 1350000
-
-#define OMAP4430_VDD_IVA_OPP50_UV 930000
-#define OMAP4430_VDD_IVA_OPP100_UV 1100000
-#define OMAP4430_VDD_IVA_OPPTURBO_UV 1260000
-
-#define OMAP4430_VDD_CORE_OPP50_UV 930000
-#define OMAP4430_VDD_CORE_OPP100_UV 1100000
+/**
+ * struct omap_vfsm_instance_data - per-voltage manager FSM register/bitfield
+ * data
+ * @voltsetup_mask: SETUP_TIME* bitmask in the PRM_VOLTSETUP* register
+ * @voltsetup_reg: register offset of PRM_VOLTSETUP from PRM base
+ * @voltsetup_shift: SETUP_TIME* field shift in the PRM_VOLTSETUP* register
+ *
+ * XXX What about VOLTOFFSET/VOLTCTRL?
+ * XXX It is not necessary to have both a _mask and a _shift for the same
+ * bitfield - remove one!
+ */
+struct omap_vfsm_instance_data {
+ u32 voltsetup_mask;
+ u8 voltsetup_reg;
+ u8 voltsetup_shift;
+};
/**
* struct voltagedomain - omap voltage domain global structure.
@@ -113,6 +103,42 @@ struct omap_volt_pmic_info {
u8 (*uv_to_vsel) (unsigned long uV);
};
+/**
+ * omap_vdd_info - Per Voltage Domain info
+ *
+ * @volt_data : voltage table having the distinct voltages supported
+ * by the domain and other associated per voltage data.
+ * @pmic_info : pmic specific parameters which should be populted by
+ * the pmic drivers.
+ * @vp_data : the register values, shifts, masks for various
+ * vp registers
+ * @vp_rt_data : VP data derived at runtime, not predefined
+ * @vc_data : structure containing various various vc registers,
+ * shifts, masks etc.
+ * @vfsm : voltage manager FSM data
+ * @voltdm : pointer to the voltage domain structure
+ * @debug_dir : debug directory for this voltage domain.
+ * @curr_volt : current voltage for this vdd.
+ * @vp_enabled : flag to keep track of whether vp is enabled or not
+ * @volt_scale : API to scale the voltage of the vdd.
+ */
+struct omap_vdd_info {
+ struct omap_volt_data *volt_data;
+ struct omap_volt_pmic_info *pmic_info;
+ struct omap_vp_instance_data *vp_data;
+ struct omap_vp_runtime_data vp_rt_data;
+ struct omap_vc_instance_data *vc_data;
+ const struct omap_vfsm_instance_data *vfsm;
+ struct voltagedomain voltdm;
+ struct dentry *debug_dir;
+ u32 curr_volt;
+ bool vp_enabled;
+ u32 (*read_reg) (u16 mod, u8 offset);
+ void (*write_reg) (u32 val, u16 mod, u8 offset);
+ int (*volt_scale) (struct omap_vdd_info *vdd,
+ unsigned long target_volt);
+};
+
unsigned long omap_vp_get_curr_volt(struct voltagedomain *voltdm);
void omap_vp_enable(struct voltagedomain *voltdm);
void omap_vp_disable(struct voltagedomain *voltdm);
@@ -125,6 +151,9 @@ struct omap_volt_data *omap_voltage_get_voltdata(struct voltagedomain *voltdm,
unsigned long volt);
unsigned long omap_voltage_get_nom_volt(struct voltagedomain *voltdm);
struct dentry *omap_voltage_get_dbgdir(struct voltagedomain *voltdm);
+int __init omap_voltage_early_init(s16 prm_mod, s16 prm_irqst_mod,
+ struct omap_vdd_info *omap_vdd_array[],
+ u8 omap_vdd_count);
#ifdef CONFIG_PM
int omap_voltage_register_pmic(struct voltagedomain *voltdm,
struct omap_volt_pmic_info *pmic_info);
diff --git a/arch/arm/mach-omap2/voltagedomains3xxx_data.c b/arch/arm/mach-omap2/voltagedomains3xxx_data.c
new file mode 100644
index 0000000..def230f
--- /dev/null
+++ b/arch/arm/mach-omap2/voltagedomains3xxx_data.c
@@ -0,0 +1,95 @@
+/*
+ * OMAP3 voltage domain data
+ *
+ * Copyright (C) 2007, 2010 Texas Instruments, Inc.
+ * Rajendra Nayak <rnayak@ti.com>
+ * Lesly A M <x0080970@ti.com>
+ * Thara Gopinath <thara@ti.com>
+ *
+ * Copyright (C) 2008, 2011 Nokia Corporation
+ * Kalle Jokiniemi
+ * Paul Walmsley
+ *
+ * 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/kernel.h>
+#include <linux/err.h>
+#include <linux/init.h>
+
+#include <plat/common.h>
+#include <plat/cpu.h>
+
+#include "prm-regbits-34xx.h"
+#include "omap_opp_data.h"
+#include "voltage.h"
+#include "vc.h"
+#include "vp.h"
+
+/*
+ * VDD data
+ */
+
+static const struct omap_vfsm_instance_data omap3_vdd1_vfsm_data = {
+ .voltsetup_reg = OMAP3_PRM_VOLTSETUP1_OFFSET,
+ .voltsetup_shift = OMAP3430_SETUP_TIME1_SHIFT,
+ .voltsetup_mask = OMAP3430_SETUP_TIME1_MASK,
+};
+
+static struct omap_vdd_info omap3_vdd1_info = {
+ .vp_data = &omap3_vp1_data,
+ .vc_data = &omap3_vc1_data,
+ .vfsm = &omap3_vdd1_vfsm_data,
+ .voltdm = {
+ .name = "mpu",
+ },
+};
+
+static const struct omap_vfsm_instance_data omap3_vdd2_vfsm_data = {
+ .voltsetup_reg = OMAP3_PRM_VOLTSETUP1_OFFSET,
+ .voltsetup_shift = OMAP3430_SETUP_TIME2_SHIFT,
+ .voltsetup_mask = OMAP3430_SETUP_TIME2_MASK,
+};
+
+static struct omap_vdd_info omap3_vdd2_info = {
+ .vp_data = &omap3_vp2_data,
+ .vc_data = &omap3_vc2_data,
+ .vfsm = &omap3_vdd2_vfsm_data,
+ .voltdm = {
+ .name = "core",
+ },
+};
+
+/* OMAP3 VDD structures */
+static struct omap_vdd_info *omap3_vdd_info[] = {
+ &omap3_vdd1_info,
+ &omap3_vdd2_info,
+};
+
+/* OMAP3 specific voltage init functions */
+static int __init omap3xxx_voltage_early_init(void)
+{
+ s16 prm_mod = OMAP3430_GR_MOD;
+ s16 prm_irqst_ocp_mod = OCP_MOD;
+
+ if (!cpu_is_omap34xx())
+ return 0;
+
+ /*
+ * XXX Will depend on the process, validation, and binning
+ * for the currently-running IC
+ */
+ if (cpu_is_omap3630()) {
+ omap3_vdd1_info.volt_data = omap36xx_vddmpu_volt_data;
+ omap3_vdd2_info.volt_data = omap36xx_vddcore_volt_data;
+ } else {
+ omap3_vdd1_info.volt_data = omap34xx_vddmpu_volt_data;
+ omap3_vdd2_info.volt_data = omap34xx_vddcore_volt_data;
+ }
+
+ return omap_voltage_early_init(prm_mod, prm_irqst_ocp_mod,
+ omap3_vdd_info,
+ ARRAY_SIZE(omap3_vdd_info));
+};
+core_initcall(omap3xxx_voltage_early_init);
diff --git a/arch/arm/mach-omap2/voltagedomains44xx_data.c b/arch/arm/mach-omap2/voltagedomains44xx_data.c
new file mode 100644
index 0000000..cb64996
--- /dev/null
+++ b/arch/arm/mach-omap2/voltagedomains44xx_data.c
@@ -0,0 +1,102 @@
+/*
+ * OMAP3/OMAP4 Voltage Management Routines
+ *
+ * Author: Thara Gopinath <thara@ti.com>
+ *
+ * Copyright (C) 2007 Texas Instruments, Inc.
+ * Rajendra Nayak <rnayak@ti.com>
+ * Lesly A M <x0080970@ti.com>
+ *
+ * Copyright (C) 2008 Nokia Corporation
+ * Kalle Jokiniemi
+ *
+ * Copyright (C) 2010 Texas Instruments, Inc.
+ * Thara Gopinath <thara@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/kernel.h>
+#include <linux/err.h>
+#include <linux/init.h>
+
+#include <plat/common.h>
+
+#include "prm-regbits-44xx.h"
+#include "prm44xx.h"
+#include "prcm44xx.h"
+#include "prminst44xx.h"
+#include "voltage.h"
+#include "omap_opp_data.h"
+#include "vc.h"
+#include "vp.h"
+
+static const struct omap_vfsm_instance_data omap4_vdd_mpu_vfsm_data = {
+ .voltsetup_reg = OMAP4_PRM_VOLTSETUP_MPU_RET_SLEEP_OFFSET,
+};
+
+static struct omap_vdd_info omap4_vdd_mpu_info = {
+ .vp_data = &omap4_vp_mpu_data,
+ .vc_data = &omap4_vc_mpu_data,
+ .vfsm = &omap4_vdd_mpu_vfsm_data,
+ .voltdm = {
+ .name = "mpu",
+ },
+};
+
+static const struct omap_vfsm_instance_data omap4_vdd_iva_vfsm_data = {
+ .voltsetup_reg = OMAP4_PRM_VOLTSETUP_IVA_RET_SLEEP_OFFSET,
+};
+
+static struct omap_vdd_info omap4_vdd_iva_info = {
+ .vp_data = &omap4_vp_iva_data,
+ .vc_data = &omap4_vc_iva_data,
+ .vfsm = &omap4_vdd_iva_vfsm_data,
+ .voltdm = {
+ .name = "iva",
+ },
+};
+
+static const struct omap_vfsm_instance_data omap4_vdd_core_vfsm_data = {
+ .voltsetup_reg = OMAP4_PRM_VOLTSETUP_CORE_RET_SLEEP_OFFSET,
+};
+
+static struct omap_vdd_info omap4_vdd_core_info = {
+ .vp_data = &omap4_vp_core_data,
+ .vc_data = &omap4_vc_core_data,
+ .vfsm = &omap4_vdd_core_vfsm_data,
+ .voltdm = {
+ .name = "core",
+ },
+};
+
+/* OMAP4 VDD structures */
+static struct omap_vdd_info *omap4_vdd_info[] = {
+ &omap4_vdd_mpu_info,
+ &omap4_vdd_iva_info,
+ &omap4_vdd_core_info,
+};
+
+/* OMAP4 specific voltage init functions */
+static int __init omap44xx_voltage_early_init(void)
+{
+ s16 prm_mod = OMAP4430_PRM_DEVICE_INST;
+ s16 prm_irqst_ocp_mod = OMAP4430_PRM_OCP_SOCKET_INST;
+
+ if (!cpu_is_omap44xx())
+ return 0;
+
+ /*
+ * XXX Will depend on the process, validation, and binning
+ * for the currently-running IC
+ */
+ omap4_vdd_mpu_info.volt_data = omap44xx_vdd_mpu_volt_data;
+ omap4_vdd_iva_info.volt_data = omap44xx_vdd_iva_volt_data;
+ omap4_vdd_core_info.volt_data = omap44xx_vdd_core_volt_data;
+
+ return omap_voltage_early_init(prm_mod, prm_irqst_ocp_mod,
+ omap4_vdd_info,
+ ARRAY_SIZE(omap4_vdd_info));
+};
+core_initcall(omap44xx_voltage_early_init);
diff --git a/arch/arm/mach-omap2/vp.h b/arch/arm/mach-omap2/vp.h
new file mode 100644
index 0000000..7ce134f
--- /dev/null
+++ b/arch/arm/mach-omap2/vp.h
@@ -0,0 +1,143 @@
+/*
+ * OMAP3/4 Voltage Processor (VP) structure and macro definitions
+ *
+ * Copyright (C) 2007, 2010 Texas Instruments, Inc.
+ * Rajendra Nayak <rnayak@ti.com>
+ * Lesly A M <x0080970@ti.com>
+ * Thara Gopinath <thara@ti.com>
+ *
+ * Copyright (C) 2008, 2011 Nokia Corporation
+ * Kalle Jokiniemi
+ * Paul Walmsley
+ *
+ * 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.
+ */
+#ifndef __ARCH_ARM_MACH_OMAP2_VP_H
+#define __ARCH_ARM_MACH_OMAP2_VP_H
+
+#include <linux/kernel.h>
+
+/* XXX document */
+#define VP_IDLE_TIMEOUT 200
+#define VP_TRANXDONE_TIMEOUT 300
+
+
+/**
+ * struct omap_vp_common_data - register data common to all VDDs
+ * @vpconfig_errorgain_mask: ERRORGAIN bitmask in the PRM_VP*_CONFIG reg
+ * @vpconfig_initvoltage_mask: INITVOLTAGE bitmask in the PRM_VP*_CONFIG reg
+ * @vpconfig_timeouten_mask: TIMEOUT bitmask in the PRM_VP*_CONFIG reg
+ * @vpconfig_initvdd: INITVDD bitmask in the PRM_VP*_CONFIG reg
+ * @vpconfig_forceupdate: FORCEUPDATE bitmask in the PRM_VP*_CONFIG reg
+ * @vpconfig_vpenable: VPENABLE bitmask in the PRM_VP*_CONFIG reg
+ * @vpconfig_erroroffset_shift: ERROROFFSET field shift in PRM_VP*_CONFIG reg
+ * @vpconfig_errorgain_shift: ERRORGAIN field shift in PRM_VP*_CONFIG reg
+ * @vpconfig_initvoltage_shift: INITVOLTAGE field shift in PRM_VP*_CONFIG reg
+ * @vpconfig_stepmin_shift: VSTEPMIN field shift in the PRM_VP*_VSTEPMIN reg
+ * @vpconfig_smpswaittimemin_shift: SMPSWAITTIMEMIN field shift in PRM_VP*_VSTEPMIN reg
+ * @vpconfig_stepmax_shift: VSTEPMAX field shift in the PRM_VP*_VSTEPMAX reg
+ * @vpconfig_smpswaittimemax_shift: SMPSWAITTIMEMAX field shift in PRM_VP*_VSTEPMAX reg
+ * @vpconfig_vlimitto_vddmin_shift: VDDMIN field shift in PRM_VP*_VLIMITTO reg
+ * @vpconfig_vlimitto_vddmax_shift: VDDMAX field shift in PRM_VP*_VLIMITTO reg
+ * @vpconfig_vlimitto_timeout_shift: TIMEOUT field shift in PRM_VP*_VLIMITTO reg
+ *
+ * XXX It it not necessary to have both a mask and a shift for the same
+ * bitfield - remove one
+ * XXX Many of these fields are wrongly named -- e.g., vpconfig_smps* -- fix!
+ */
+struct omap_vp_common_data {
+ u32 vpconfig_errorgain_mask;
+ u32 vpconfig_initvoltage_mask;
+ u32 vpconfig_timeouten;
+ u32 vpconfig_initvdd;
+ u32 vpconfig_forceupdate;
+ u32 vpconfig_vpenable;
+ u8 vpconfig_erroroffset_shift;
+ u8 vpconfig_errorgain_shift;
+ u8 vpconfig_initvoltage_shift;
+ u8 vstepmin_stepmin_shift;
+ u8 vstepmin_smpswaittimemin_shift;
+ u8 vstepmax_stepmax_shift;
+ u8 vstepmax_smpswaittimemax_shift;
+ u8 vlimitto_vddmin_shift;
+ u8 vlimitto_vddmax_shift;
+ u8 vlimitto_timeout_shift;
+};
+
+/**
+ * struct omap_vp_prm_irqst_data - PRM_IRQSTATUS_MPU.VP_TRANXDONE_ST data
+ * @prm_irqst_reg: reg offset for PRM_IRQSTATUS_MPU from top of PRM
+ * @tranxdone_status: VP_TRANXDONE_ST bitmask in PRM_IRQSTATUS_MPU reg
+ *
+ * XXX prm_irqst_reg does not belong here
+ * XXX Note that on OMAP3, VP_TRANXDONE interrupt may not work due to a
+ * hardware bug
+ * XXX This structure is probably not needed
+ */
+struct omap_vp_prm_irqst_data {
+ u8 prm_irqst_reg;
+ u32 tranxdone_status;
+};
+
+/**
+ * struct omap_vp_instance_data - VP register offsets (per-VDD)
+ * @vp_common: pointer to struct omap_vp_common_data * for this SoC
+ * @prm_irqst_data: pointer to struct omap_vp_prm_irqst_data for this VDD
+ * @vpconfig: PRM_VP*_CONFIG reg offset from PRM start
+ * @vstepmin: PRM_VP*_VSTEPMIN reg offset from PRM start
+ * @vlimitto: PRM_VP*_VLIMITTO reg offset from PRM start
+ * @vstatus: PRM_VP*_VSTATUS reg offset from PRM start
+ * @voltage: PRM_VP*_VOLTAGE reg offset from PRM start
+ *
+ * XXX vp_common is probably not needed since it is per-SoC
+ */
+struct omap_vp_instance_data {
+ const struct omap_vp_common_data *vp_common;
+ const struct omap_vp_prm_irqst_data *prm_irqst_data;
+ u8 vpconfig;
+ u8 vstepmin;
+ u8 vstepmax;
+ u8 vlimitto;
+ u8 vstatus;
+ u8 voltage;
+};
+
+/**
+ * struct omap_vp_runtime_data - VP data populated at runtime by code
+ * @vpconfig_erroroffset: value of ERROROFFSET bitfield in PRM_VP*_CONFIG
+ * @vpconfig_errorgain: value of ERRORGAIN bitfield in PRM_VP*_CONFIG
+ * @vstepmin_smpswaittimemin: value of SMPSWAITTIMEMIN bitfield in PRM_VP*_VSTEPMIN
+ * @vstepmax_smpswaittimemax: value of SMPSWAITTIMEMAX bitfield in PRM_VP*_VSTEPMAX
+ * @vlimitto_timeout: value of TIMEOUT bitfield in PRM_VP*_VLIMITTO
+ * @vstepmin_stepmin: value of VSTEPMIN bitfield in PRM_VP*_VSTEPMIN
+ * @vstepmax_stepmax: value of VSTEPMAX bitfield in PRM_VP*_VSTEPMAX
+ * @vlimitto_vddmin: value of VDDMIN bitfield in PRM_VP*_VLIMITTO
+ * @vlimitto_vddmax: value of VDDMAX bitfield in PRM_VP*_VLIMITTO
+ *
+ * XXX Is this structure really needed? Why not just program the
+ * device directly? They are in PRM space, therefore in the WKUP
+ * powerdomain, so register contents should not be lost in off-mode.
+ * XXX Some of these fields are incorrectly named, e.g., vstep*
+ */
+struct omap_vp_runtime_data {
+ u32 vpconfig_erroroffset;
+ u16 vpconfig_errorgain;
+ u16 vstepmin_smpswaittimemin;
+ u16 vstepmax_smpswaittimemax;
+ u16 vlimitto_timeout;
+ u8 vstepmin_stepmin;
+ u8 vstepmax_stepmax;
+ u8 vlimitto_vddmin;
+ u8 vlimitto_vddmax;
+};
+
+extern struct omap_vp_instance_data omap3_vp1_data;
+extern struct omap_vp_instance_data omap3_vp2_data;
+
+extern struct omap_vp_instance_data omap4_vp_mpu_data;
+extern struct omap_vp_instance_data omap4_vp_iva_data;
+extern struct omap_vp_instance_data omap4_vp_core_data;
+
+#endif
diff --git a/arch/arm/mach-omap2/vp3xxx_data.c b/arch/arm/mach-omap2/vp3xxx_data.c
new file mode 100644
index 0000000..6452170
--- /dev/null
+++ b/arch/arm/mach-omap2/vp3xxx_data.c
@@ -0,0 +1,82 @@
+/*
+ * OMAP3 Voltage Processor (VP) data
+ *
+ * Copyright (C) 2007, 2010 Texas Instruments, Inc.
+ * Rajendra Nayak <rnayak@ti.com>
+ * Lesly A M <x0080970@ti.com>
+ * Thara Gopinath <thara@ti.com>
+ *
+ * Copyright (C) 2008, 2011 Nokia Corporation
+ * Kalle Jokiniemi
+ * Paul Walmsley
+ *
+ * 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/io.h>
+#include <linux/err.h>
+#include <linux/init.h>
+
+#include <plat/common.h>
+
+#include "prm-regbits-34xx.h"
+#include "voltage.h"
+
+#include "vp.h"
+
+/*
+ * VP data common to 34xx/36xx chips
+ * XXX This stuff presumably belongs in the vp3xxx.c or vp.c file.
+ */
+static const struct omap_vp_common_data omap3_vp_common = {
+ .vpconfig_erroroffset_shift = OMAP3430_ERROROFFSET_SHIFT,
+ .vpconfig_errorgain_mask = OMAP3430_ERRORGAIN_MASK,
+ .vpconfig_errorgain_shift = OMAP3430_ERRORGAIN_SHIFT,
+ .vpconfig_initvoltage_shift = OMAP3430_INITVOLTAGE_SHIFT,
+ .vpconfig_initvoltage_mask = OMAP3430_INITVOLTAGE_MASK,
+ .vpconfig_timeouten = OMAP3430_TIMEOUTEN_MASK,
+ .vpconfig_initvdd = OMAP3430_INITVDD_MASK,
+ .vpconfig_forceupdate = OMAP3430_FORCEUPDATE_MASK,
+ .vpconfig_vpenable = OMAP3430_VPENABLE_MASK,
+ .vstepmin_smpswaittimemin_shift = OMAP3430_SMPSWAITTIMEMIN_SHIFT,
+ .vstepmax_smpswaittimemax_shift = OMAP3430_SMPSWAITTIMEMAX_SHIFT,
+ .vstepmin_stepmin_shift = OMAP3430_VSTEPMIN_SHIFT,
+ .vstepmax_stepmax_shift = OMAP3430_VSTEPMAX_SHIFT,
+ .vlimitto_vddmin_shift = OMAP3430_VDDMIN_SHIFT,
+ .vlimitto_vddmax_shift = OMAP3430_VDDMAX_SHIFT,
+ .vlimitto_timeout_shift = OMAP3430_TIMEOUT_SHIFT,
+};
+
+static const struct omap_vp_prm_irqst_data omap3_vp1_prm_irqst_data = {
+ .prm_irqst_reg = OMAP3_PRM_IRQSTATUS_MPU_OFFSET,
+ .tranxdone_status = OMAP3430_VP1_TRANXDONE_ST_MASK,
+};
+
+struct omap_vp_instance_data omap3_vp1_data = {
+ .vp_common = &omap3_vp_common,
+ .vpconfig = OMAP3_PRM_VP1_CONFIG_OFFSET,
+ .vstepmin = OMAP3_PRM_VP1_VSTEPMIN_OFFSET,
+ .vstepmax = OMAP3_PRM_VP1_VSTEPMAX_OFFSET,
+ .vlimitto = OMAP3_PRM_VP1_VLIMITTO_OFFSET,
+ .vstatus = OMAP3_PRM_VP1_STATUS_OFFSET,
+ .voltage = OMAP3_PRM_VP1_VOLTAGE_OFFSET,
+ .prm_irqst_data = &omap3_vp1_prm_irqst_data,
+};
+
+static const struct omap_vp_prm_irqst_data omap3_vp2_prm_irqst_data = {
+ .prm_irqst_reg = OMAP3_PRM_IRQSTATUS_MPU_OFFSET,
+ .tranxdone_status = OMAP3430_VP2_TRANXDONE_ST_MASK,
+};
+
+struct omap_vp_instance_data omap3_vp2_data = {
+ .vp_common = &omap3_vp_common,
+ .vpconfig = OMAP3_PRM_VP2_CONFIG_OFFSET,
+ .vstepmin = OMAP3_PRM_VP2_VSTEPMIN_OFFSET,
+ .vstepmax = OMAP3_PRM_VP2_VSTEPMAX_OFFSET,
+ .vlimitto = OMAP3_PRM_VP2_VLIMITTO_OFFSET,
+ .vstatus = OMAP3_PRM_VP2_STATUS_OFFSET,
+ .voltage = OMAP3_PRM_VP2_VOLTAGE_OFFSET,
+ .prm_irqst_data = &omap3_vp2_prm_irqst_data,
+};
diff --git a/arch/arm/mach-omap2/vp44xx_data.c b/arch/arm/mach-omap2/vp44xx_data.c
new file mode 100644
index 0000000..65d1ad6
--- /dev/null
+++ b/arch/arm/mach-omap2/vp44xx_data.c
@@ -0,0 +1,100 @@
+/*
+ * OMAP3 Voltage Processor (VP) data
+ *
+ * Copyright (C) 2007, 2010 Texas Instruments, Inc.
+ * Rajendra Nayak <rnayak@ti.com>
+ * Lesly A M <x0080970@ti.com>
+ * Thara Gopinath <thara@ti.com>
+ *
+ * Copyright (C) 2008, 2011 Nokia Corporation
+ * Kalle Jokiniemi
+ * Paul Walmsley
+ *
+ * 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/io.h>
+#include <linux/err.h>
+#include <linux/init.h>
+
+#include <plat/common.h>
+
+#include "prm44xx.h"
+#include "prm-regbits-44xx.h"
+#include "voltage.h"
+
+#include "vp.h"
+
+/*
+ * VP data common to 44xx chips
+ * XXX This stuff presumably belongs in the vp44xx.c or vp.c file.
+ */
+static const struct omap_vp_common_data omap4_vp_common = {
+ .vpconfig_erroroffset_shift = OMAP4430_ERROROFFSET_SHIFT,
+ .vpconfig_errorgain_mask = OMAP4430_ERRORGAIN_MASK,
+ .vpconfig_errorgain_shift = OMAP4430_ERRORGAIN_SHIFT,
+ .vpconfig_initvoltage_shift = OMAP4430_INITVOLTAGE_SHIFT,
+ .vpconfig_initvoltage_mask = OMAP4430_INITVOLTAGE_MASK,
+ .vpconfig_timeouten = OMAP4430_TIMEOUTEN_MASK,
+ .vpconfig_initvdd = OMAP4430_INITVDD_MASK,
+ .vpconfig_forceupdate = OMAP4430_FORCEUPDATE_MASK,
+ .vpconfig_vpenable = OMAP4430_VPENABLE_MASK,
+ .vstepmin_smpswaittimemin_shift = OMAP4430_SMPSWAITTIMEMIN_SHIFT,
+ .vstepmax_smpswaittimemax_shift = OMAP4430_SMPSWAITTIMEMAX_SHIFT,
+ .vstepmin_stepmin_shift = OMAP4430_VSTEPMIN_SHIFT,
+ .vstepmax_stepmax_shift = OMAP4430_VSTEPMAX_SHIFT,
+ .vlimitto_vddmin_shift = OMAP4430_VDDMIN_SHIFT,
+ .vlimitto_vddmax_shift = OMAP4430_VDDMAX_SHIFT,
+ .vlimitto_timeout_shift = OMAP4430_TIMEOUT_SHIFT,
+};
+
+static const struct omap_vp_prm_irqst_data omap4_vp_mpu_prm_irqst_data = {
+ .prm_irqst_reg = OMAP4_PRM_IRQSTATUS_MPU_2_OFFSET,
+ .tranxdone_status = OMAP4430_VP_MPU_TRANXDONE_ST_MASK,
+};
+
+struct omap_vp_instance_data omap4_vp_mpu_data = {
+ .vp_common = &omap4_vp_common,
+ .vpconfig = OMAP4_PRM_VP_MPU_CONFIG_OFFSET,
+ .vstepmin = OMAP4_PRM_VP_MPU_VSTEPMIN_OFFSET,
+ .vstepmax = OMAP4_PRM_VP_MPU_VSTEPMAX_OFFSET,
+ .vlimitto = OMAP4_PRM_VP_MPU_VLIMITTO_OFFSET,
+ .vstatus = OMAP4_PRM_VP_MPU_STATUS_OFFSET,
+ .voltage = OMAP4_PRM_VP_MPU_VOLTAGE_OFFSET,
+ .prm_irqst_data = &omap4_vp_mpu_prm_irqst_data,
+};
+
+static const struct omap_vp_prm_irqst_data omap4_vp_iva_prm_irqst_data = {
+ .prm_irqst_reg = OMAP4_PRM_IRQSTATUS_MPU_OFFSET,
+ .tranxdone_status = OMAP4430_VP_IVA_TRANXDONE_ST_MASK,
+};
+
+struct omap_vp_instance_data omap4_vp_iva_data = {
+ .vp_common = &omap4_vp_common,
+ .vpconfig = OMAP4_PRM_VP_IVA_CONFIG_OFFSET,
+ .vstepmin = OMAP4_PRM_VP_IVA_VSTEPMIN_OFFSET,
+ .vstepmax = OMAP4_PRM_VP_IVA_VSTEPMAX_OFFSET,
+ .vlimitto = OMAP4_PRM_VP_IVA_VLIMITTO_OFFSET,
+ .vstatus = OMAP4_PRM_VP_IVA_STATUS_OFFSET,
+ .voltage = OMAP4_PRM_VP_IVA_VOLTAGE_OFFSET,
+ .prm_irqst_data = &omap4_vp_iva_prm_irqst_data,
+};
+
+static const struct omap_vp_prm_irqst_data omap4_vp_core_prm_irqst_data = {
+ .prm_irqst_reg = OMAP4_PRM_IRQSTATUS_MPU_OFFSET,
+ .tranxdone_status = OMAP4430_VP_CORE_TRANXDONE_ST_MASK,
+};
+
+struct omap_vp_instance_data omap4_vp_core_data = {
+ .vp_common = &omap4_vp_common,
+ .vpconfig = OMAP4_PRM_VP_CORE_CONFIG_OFFSET,
+ .vstepmin = OMAP4_PRM_VP_CORE_VSTEPMIN_OFFSET,
+ .vstepmax = OMAP4_PRM_VP_CORE_VSTEPMAX_OFFSET,
+ .vlimitto = OMAP4_PRM_VP_CORE_VLIMITTO_OFFSET,
+ .vstatus = OMAP4_PRM_VP_CORE_STATUS_OFFSET,
+ .voltage = OMAP4_PRM_VP_CORE_VOLTAGE_OFFSET,
+ .prm_irqst_data = &omap4_vp_core_prm_irqst_data,
+};
+
--
1.7.2.3
^ permalink raw reply related
* [PATCH 2/4] msm: iommu: Rework clock logic and add IOMMU bus clock control
From: Stepan Moskovchenko @ 2011-02-25 22:09 UTC (permalink / raw)
To: linux-arm-kernel
In-Reply-To: <4D675A42.9090803@codeaurora.org>
On 2/24/2011 11:29 PM, Trilok Soni wrote:
> Hi Steve,
Hello
>> @@ -130,117 +131,134 @@ static int msm_iommu_probe(struct platform_device *pdev)
>> {
>> struct resource *r, *r2;
>> struct clk *iommu_clk;
>> + struct clk *iommu_pclk;
>> struct msm_iommu_drvdata *drvdata;
>> struct msm_iommu_dev *iommu_dev = pdev->dev.platform_data;
> const please.
>
I am not clear on what you mean. Please be more specific here.
>> + iommu_pclk = clk_get(NULL, "smmu_pclk");
>> + if (IS_ERR(iommu_pclk)) {
>> + ret = -ENODEV;
>> + goto fail;
>> + }
> I am not a big fan of this when you have the "device" around. You should just do
>
> iommu_pclk = clk_get(&pdev->dev, NULL);
>
> ...error logic...
>
> iommu_clk = clk_get(&pdev->dev, "iommu_clk");
>
> ...error logic...
>
The pclk is a "special" bus clock and does not have a specific device
instance associated with it, so passing a device would not be
appropriate in this case. I pass the device for other clocks that are
indeed associated with devices, but this is not one of them. I suppose
we could create 11 or 12 aliases for the pclk and associate it with all
the IOMMU devices, but I would prefer to avoid doing that as I believe
the current approach is cleaner.
>> - ret = -EBUSY;
>> - goto fail;
>> - }
>> + len = r->end - r->start + 1;
>
> resource_size please.
>
Ok
^ permalink raw reply
* [PATCH] PM: OPP: opp_find_freq_exact documentation fix
From: Rafael J. Wysocki @ 2011-02-25 22:59 UTC (permalink / raw)
To: linux-arm-kernel
In-Reply-To: <1298618044-8292-1-git-send-email-nm@ti.com>
On Friday, February 25, 2011, Nishanth Menon wrote:
> opp_find_freq_exact documentation has is_available instead
> of available. This also fixes warning with the kernel-doc:
> scripts/kernel-doc drivers/base/power/opp.c >/dev/null
> Warning(drivers/base/power/opp.c:246): No description found for parameter 'available'
> Warning(drivers/base/power/opp.c:246): Excess function parameter 'is_available' description in 'opp_find_freq_exact'
>
> Signed-off-by: Nishanth Menon <nm@ti.com>
Applied to suspend-2.6/linux-next.
Thanks,
Rafael
> ---
> drivers/base/power/opp.c | 2 +-
> 1 files changed, 1 insertions(+), 1 deletions(-)
>
> diff --git a/drivers/base/power/opp.c b/drivers/base/power/opp.c
> index 2bb9b4c..56a6899 100644
> --- a/drivers/base/power/opp.c
> +++ b/drivers/base/power/opp.c
> @@ -222,7 +222,7 @@ int opp_get_opp_count(struct device *dev)
> * opp_find_freq_exact() - search for an exact frequency
> * @dev: device for which we do this operation
> * @freq: frequency to search for
> - * @is_available: true/false - match for available opp
> + * @available: true/false - match for available opp
> *
> * Searches for exact match in the opp list and returns pointer to the matching
> * opp if found, else returns ERR_PTR in case of error and should be handled
>
^ permalink raw reply
* [PATCH 0/4] OMAP2/3: clock/clockdomains: miscellaneous fixes
From: Paul Walmsley @ 2011-02-26 0:20 UTC (permalink / raw)
To: linux-arm-kernel
Hello,
here are a few miscellaneous OMAP2 clock and clockdomain
data for 2.6.39.
Boot-tested on N800. Compile-tested for omap2plus_defconfig and
omap3_defconfig.
This series is available via git in the branch 'clk_clkdm_a_2.6.39' of
git://git.pwsan.com/linux-2.6.
- Paul
---
clk_clkdm_a_2.6.39
text data bss dec hex filename
3701835 230192 5390012 9322039 8e3e37 vmlinux.n800_config.orig
3701803 230064 5390012 9321879 8e3d97 vmlinux.n800_config
Paul Walmsley (4):
OMAP2xxx: clock: remove dsp_irate_ick
OMAP2/3: clockdomains: remove warnings on an OMAP3-only compile
OMAP2xxx: clock: fix clockdomains on gpt7_ick, 2430 mmchs2_fck clocks
OMAP2xxx: clock data: clean up some comments
arch/arm/mach-omap2/clock.h | 1
arch/arm/mach-omap2/clock2420_data.c | 55 +++++++--------------
arch/arm/mach-omap2/clock2430_data.c | 58 ++++++++--------------
arch/arm/mach-omap2/clock_common_data.c | 6 ++
arch/arm/mach-omap2/clockdomains2xxx_3xxx_data.c | 4 ++
5 files changed, 51 insertions(+), 73 deletions(-)
^ permalink raw reply
* [PATCH 1/4] OMAP2xxx: clock: remove dsp_irate_ick
From: Paul Walmsley @ 2011-02-26 0:20 UTC (permalink / raw)
To: linux-arm-kernel
In-Reply-To: <20110226001601.28142.46636.stgit@twilight.localdomain>
After commit 81b34fbecbfbf24ed95c2d80d5cb14149652408f ("OMAP2 clock:
split OMAP2420, OMAP2430 clock data into their own files"), it's
possible to remove dsp_irate_ick from the OMAP2420 and OMAP2430 clock
files. It was originally only needed due to a 2420/2430 clock tree difference,
and now that the data is in separate files, it's superfluous.
Signed-off-by: Paul Walmsley <paul@pwsan.com>
---
arch/arm/mach-omap2/clock.h | 1 +
arch/arm/mach-omap2/clock2420_data.c | 31 ++++++++-----------------------
arch/arm/mach-omap2/clock2430_data.c | 31 ++++++++-----------------------
arch/arm/mach-omap2/clock_common_data.c | 6 ++++++
4 files changed, 23 insertions(+), 46 deletions(-)
diff --git a/arch/arm/mach-omap2/clock.h b/arch/arm/mach-omap2/clock.h
index 62cfd6c..e10ff2b 100644
--- a/arch/arm/mach-omap2/clock.h
+++ b/arch/arm/mach-omap2/clock.h
@@ -139,6 +139,7 @@ extern struct clk *vclk, *sclk;
extern const struct clksel_rate gpt_32k_rates[];
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)
extern void omap2_clk_init_cpufreq_table(struct cpufreq_frequency_table **table);
diff --git a/arch/arm/mach-omap2/clock2420_data.c b/arch/arm/mach-omap2/clock2420_data.c
index 22eeafc..53bd999 100644
--- a/arch/arm/mach-omap2/clock2420_data.c
+++ b/arch/arm/mach-omap2/clock2420_data.c
@@ -454,36 +454,22 @@ static struct clk dsp_fck = {
.recalc = &omap2_clksel_recalc,
};
-/* DSP interface clock */
-static const struct clksel_rate dsp_irate_ick_rates[] = {
- { .div = 1, .val = 1, .flags = RATE_IN_24XX },
- { .div = 2, .val = 2, .flags = RATE_IN_24XX },
- { .div = 0 },
-};
-
-static const struct clksel dsp_irate_ick_clksel[] = {
- { .parent = &dsp_fck, .rates = dsp_irate_ick_rates },
+static const struct clksel dsp_ick_clksel[] = {
+ { .parent = &dsp_fck, .rates = dsp_ick_rates },
{ .parent = NULL }
};
-/* This clock does not exist as such in the TRM. */
-static struct clk dsp_irate_ick = {
- .name = "dsp_irate_ick",
- .ops = &clkops_null,
- .parent = &dsp_fck,
- .clksel_reg = OMAP_CM_REGADDR(OMAP24XX_DSP_MOD, CM_CLKSEL),
- .clksel_mask = OMAP24XX_CLKSEL_DSP_IF_MASK,
- .clksel = dsp_irate_ick_clksel,
- .recalc = &omap2_clksel_recalc,
-};
-
-/* 2420 only */
static struct clk dsp_ick = {
.name = "dsp_ick", /* apparently ipi and isp */
.ops = &clkops_omap2_iclk_dflt_wait,
- .parent = &dsp_irate_ick,
+ .parent = &dsp_fck,
+ .clkdm_name = "dsp_clkdm",
.enable_reg = OMAP_CM_REGADDR(OMAP24XX_DSP_MOD, CM_ICLKEN),
.enable_bit = OMAP2420_EN_DSP_IPI_SHIFT, /* for ipi */
+ .clksel_reg = OMAP_CM_REGADDR(OMAP24XX_DSP_MOD, CM_CLKSEL),
+ .clksel_mask = OMAP24XX_CLKSEL_DSP_IF_MASK,
+ .clksel = dsp_ick_clksel,
+ .recalc = &omap2_clksel_recalc,
};
/*
@@ -1812,7 +1798,6 @@ static struct omap_clk omap2420_clks[] = {
CLK(NULL, "mpu_ck", &mpu_ck, CK_242X),
/* dsp domain clocks */
CLK(NULL, "dsp_fck", &dsp_fck, CK_242X),
- CLK(NULL, "dsp_irate_ick", &dsp_irate_ick, CK_242X),
CLK(NULL, "dsp_ick", &dsp_ick, CK_242X),
CLK(NULL, "iva1_ifck", &iva1_ifck, CK_242X),
CLK(NULL, "iva1_mpu_int_ifck", &iva1_mpu_int_ifck, CK_242X),
diff --git a/arch/arm/mach-omap2/clock2430_data.c b/arch/arm/mach-omap2/clock2430_data.c
index df4cac5..36dde26 100644
--- a/arch/arm/mach-omap2/clock2430_data.c
+++ b/arch/arm/mach-omap2/clock2430_data.c
@@ -433,37 +433,23 @@ static struct clk dsp_fck = {
.recalc = &omap2_clksel_recalc,
};
-/* DSP interface clock */
-static const struct clksel_rate dsp_irate_ick_rates[] = {
- { .div = 1, .val = 1, .flags = RATE_IN_24XX },
- { .div = 2, .val = 2, .flags = RATE_IN_24XX },
- { .div = 3, .val = 3, .flags = RATE_IN_243X },
- { .div = 0 },
-};
-
-static const struct clksel dsp_irate_ick_clksel[] = {
- { .parent = &dsp_fck, .rates = dsp_irate_ick_rates },
+static const struct clksel dsp_ick_clksel[] = {
+ { .parent = &dsp_fck, .rates = dsp_ick_rates },
{ .parent = NULL }
};
-/* This clock does not exist as such in the TRM. */
-static struct clk dsp_irate_ick = {
- .name = "dsp_irate_ick",
- .ops = &clkops_null,
- .parent = &dsp_fck,
- .clksel_reg = OMAP_CM_REGADDR(OMAP24XX_DSP_MOD, CM_CLKSEL),
- .clksel_mask = OMAP24XX_CLKSEL_DSP_IF_MASK,
- .clksel = dsp_irate_ick_clksel,
- .recalc = &omap2_clksel_recalc,
-};
-
/* 2430 only - EN_DSP controls both dsp fclk and iclk on 2430 */
static struct clk iva2_1_ick = {
.name = "iva2_1_ick",
.ops = &clkops_omap2_dflt_wait,
- .parent = &dsp_irate_ick,
+ .parent = &dsp_fck,
+ .clkdm_name = "dsp_clkdm",
.enable_reg = OMAP_CM_REGADDR(OMAP24XX_DSP_MOD, CM_FCLKEN),
.enable_bit = OMAP24XX_CM_FCLKEN_DSP_EN_DSP_SHIFT,
+ .clksel_reg = OMAP_CM_REGADDR(OMAP24XX_DSP_MOD, CM_CLKSEL),
+ .clksel_mask = OMAP24XX_CLKSEL_DSP_IF_MASK,
+ .clksel = dsp_ick_clksel,
+ .recalc = &omap2_clksel_recalc,
};
/*
@@ -1900,7 +1886,6 @@ static struct omap_clk omap2430_clks[] = {
CLK(NULL, "mpu_ck", &mpu_ck, CK_243X),
/* dsp domain clocks */
CLK(NULL, "dsp_fck", &dsp_fck, CK_243X),
- CLK(NULL, "dsp_irate_ick", &dsp_irate_ick, CK_243X),
CLK(NULL, "iva2_1_ick", &iva2_1_ick, CK_243X),
/* GFX domain clocks */
CLK(NULL, "gfx_3d_fck", &gfx_3d_fck, CK_243X),
diff --git a/arch/arm/mach-omap2/clock_common_data.c b/arch/arm/mach-omap2/clock_common_data.c
index 1cf8131..6424d46 100644
--- a/arch/arm/mach-omap2/clock_common_data.c
+++ b/arch/arm/mach-omap2/clock_common_data.c
@@ -37,3 +37,9 @@ const struct clksel_rate gfx_l3_rates[] = {
{ .div = 0 }
};
+const struct clksel_rate dsp_ick_rates[] = {
+ { .div = 1, .val = 1, .flags = RATE_IN_24XX },
+ { .div = 2, .val = 2, .flags = RATE_IN_24XX },
+ { .div = 3, .val = 3, .flags = RATE_IN_243X },
+ { .div = 0 },
+};
^ permalink raw reply related
* [PATCH 2/4] OMAP2/3: clockdomains: remove warnings on an OMAP3-only compile
From: Paul Walmsley @ 2011-02-26 0:20 UTC (permalink / raw)
To: linux-arm-kernel
In-Reply-To: <20110226001601.28142.46636.stgit@twilight.localdomain>
Resolve these compile-time gcc warnings on OMAP3-only kernel compiles:
.../mach-omap2/clockdomains2xxx_3xxx_data.c:95: warning: 'dsp_24xx_wkdeps' defined but not used
.../mach-omap2/clockdomains2xxx_3xxx_data.c:119: warning: 'mpu_24xx_wkdeps' defined but not used
.../mach-omap2/clockdomains2xxx_3xxx_data.c:147: warning: 'core_24xx_wkdeps' defined but not used
Signed-off-by: Paul Walmsley <paul@pwsan.com>
---
arch/arm/mach-omap2/clockdomains2xxx_3xxx_data.c | 4 ++++
1 files changed, 4 insertions(+), 0 deletions(-)
diff --git a/arch/arm/mach-omap2/clockdomains2xxx_3xxx_data.c b/arch/arm/mach-omap2/clockdomains2xxx_3xxx_data.c
index ffdfe54..f9df791 100644
--- a/arch/arm/mach-omap2/clockdomains2xxx_3xxx_data.c
+++ b/arch/arm/mach-omap2/clockdomains2xxx_3xxx_data.c
@@ -89,6 +89,8 @@ static struct clkdm_dep gfx_sgx_wkdeps[] = {
/* 24XX-specific possible dependencies */
+#ifdef CONFIG_ARCH_OMAP2
+
/* Wakeup dependency source arrays */
/* 2420/2430 PM_WKDEP_DSP: CORE, MPU, WKUP */
@@ -168,6 +170,8 @@ static struct clkdm_dep core_24xx_wkdeps[] = {
{ NULL },
};
+#endif
+
/* 2430-specific possible wakeup dependencies */
^ permalink raw reply related
* [PATCH 3/4] OMAP2xxx: clock: fix clockdomains on gpt7_ick, 2430 mmchs2_fck clocks
From: Paul Walmsley @ 2011-02-26 0:20 UTC (permalink / raw)
To: linux-arm-kernel
In-Reply-To: <20110226001601.28142.46636.stgit@twilight.localdomain>
Add a clockdomain to the GPTIMER7 interface and 2430 HSMMC2 functional
clocks - both were previously missing them.
Also, the 2430 mmchs1_fck is in core_l3_clkdm, but should be in
core_l4_clkdm; fix this.
Signed-off-by: Paul Walmsley <paul@pwsan.com>
---
arch/arm/mach-omap2/clock2420_data.c | 1 +
arch/arm/mach-omap2/clock2430_data.c | 4 +++-
2 files changed, 4 insertions(+), 1 deletions(-)
diff --git a/arch/arm/mach-omap2/clock2420_data.c b/arch/arm/mach-omap2/clock2420_data.c
index 53bd999..5e80d3d 100644
--- a/arch/arm/mach-omap2/clock2420_data.c
+++ b/arch/arm/mach-omap2/clock2420_data.c
@@ -987,6 +987,7 @@ static struct clk gpt7_ick = {
.name = "gpt7_ick",
.ops = &clkops_omap2_iclk_dflt_wait,
.parent = &l4_ck,
+ .clkdm_name = "core_l4_clkdm",
.enable_reg = OMAP_CM_REGADDR(CORE_MOD, CM_ICLKEN1),
.enable_bit = OMAP24XX_EN_GPT7_SHIFT,
.recalc = &followparent_recalc,
diff --git a/arch/arm/mach-omap2/clock2430_data.c b/arch/arm/mach-omap2/clock2430_data.c
index 36dde26..8957fc6 100644
--- a/arch/arm/mach-omap2/clock2430_data.c
+++ b/arch/arm/mach-omap2/clock2430_data.c
@@ -975,6 +975,7 @@ static struct clk gpt7_ick = {
.name = "gpt7_ick",
.ops = &clkops_omap2_iclk_dflt_wait,
.parent = &l4_ck,
+ .clkdm_name = "core_l4_clkdm",
.enable_reg = OMAP_CM_REGADDR(CORE_MOD, CM_ICLKEN1),
.enable_bit = OMAP24XX_EN_GPT7_SHIFT,
.recalc = &followparent_recalc,
@@ -1747,7 +1748,7 @@ static struct clk mmchs1_fck = {
.name = "mmchs1_fck",
.ops = &clkops_omap2_dflt_wait,
.parent = &func_96m_ck,
- .clkdm_name = "core_l3_clkdm",
+ .clkdm_name = "core_l4_clkdm",
.enable_reg = OMAP_CM_REGADDR(CORE_MOD, OMAP24XX_CM_FCLKEN2),
.enable_bit = OMAP2430_EN_MMCHS1_SHIFT,
.recalc = &followparent_recalc,
@@ -1767,6 +1768,7 @@ static struct clk mmchs2_fck = {
.name = "mmchs2_fck",
.ops = &clkops_omap2_dflt_wait,
.parent = &func_96m_ck,
+ .clkdm_name = "core_l4_clkdm",
.enable_reg = OMAP_CM_REGADDR(CORE_MOD, OMAP24XX_CM_FCLKEN2),
.enable_bit = OMAP2430_EN_MMCHS2_SHIFT,
.recalc = &followparent_recalc,
^ permalink raw reply related
* [PATCH 4/4] OMAP2xxx: clock data: clean up some comments
From: Paul Walmsley @ 2011-02-26 0:20 UTC (permalink / raw)
To: linux-arm-kernel
In-Reply-To: <20110226001601.28142.46636.stgit@twilight.localdomain>
Minor cleanup of some clock data comments. No functional changes.
Signed-off-by: Paul Walmsley <paul@pwsan.com>
---
arch/arm/mach-omap2/clock2420_data.c | 23 ++++++++++-------------
arch/arm/mach-omap2/clock2430_data.c | 23 ++++++++++-------------
2 files changed, 20 insertions(+), 26 deletions(-)
diff --git a/arch/arm/mach-omap2/clock2420_data.c b/arch/arm/mach-omap2/clock2420_data.c
index 5e80d3d..b6f65d4 100644
--- a/arch/arm/mach-omap2/clock2420_data.c
+++ b/arch/arm/mach-omap2/clock2420_data.c
@@ -1,12 +1,12 @@
/*
- * linux/arch/arm/mach-omap2/clock2420_data.c
+ * OMAP2420 clock data
*
- * Copyright (C) 2005-2009 Texas Instruments, Inc.
- * Copyright (C) 2004-2011 Nokia Corporation
+ * Copyright (C) 2005-2009 Texas Instruments, Inc.
+ * Copyright (C) 2004-2011 Nokia Corporation
*
- * Contacts:
- * Richard Woodruff <r-woodruff2@ti.com>
- * Paul Walmsley
+ * Contacts:
+ * Richard Woodruff <r-woodruff2@ti.com>
+ * Paul Walmsley
*
* 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
@@ -34,18 +34,15 @@
/*
* 2420 clock tree.
*
- * NOTE:In many cases here we are assigning a 'default' parent. In many
- * cases the parent is selectable. The get/set parent calls will also
- * switch sources.
- *
- * Many some clocks say always_enabled, but they can be auto idled for
- * power savings. They will always be available upon clock request.
+ * NOTE:In many cases here we are assigning a 'default' parent. In
+ * many cases the parent is selectable. The set parent calls will
+ * also switch sources.
*
* Several sources are given initial rates which may be wrong, this will
* be fixed up in the init func.
*
* Things are broadly separated below by clock domains. It is
- * noteworthy that most periferals have dependencies on multiple clock
+ * noteworthy that most peripherals have dependencies on multiple clock
* domains. Many get their interface clocks from the L4 domain, but get
* functional clocks from fixed sources or other core domain derived
* clocks.
diff --git a/arch/arm/mach-omap2/clock2430_data.c b/arch/arm/mach-omap2/clock2430_data.c
index 8957fc6..5c2a075 100644
--- a/arch/arm/mach-omap2/clock2430_data.c
+++ b/arch/arm/mach-omap2/clock2430_data.c
@@ -1,12 +1,12 @@
/*
- * linux/arch/arm/mach-omap2/clock2430_data.c
+ * OMAP2430 clock data
*
- * Copyright (C) 2005-2009 Texas Instruments, Inc.
- * Copyright (C) 2004-2011 Nokia Corporation
+ * Copyright (C) 2005-2009 Texas Instruments, Inc.
+ * Copyright (C) 2004-2011 Nokia Corporation
*
- * Contacts:
- * Richard Woodruff <r-woodruff2@ti.com>
- * Paul Walmsley
+ * Contacts:
+ * Richard Woodruff <r-woodruff2@ti.com>
+ * Paul Walmsley
*
* 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
@@ -34,18 +34,15 @@
/*
* 2430 clock tree.
*
- * NOTE:In many cases here we are assigning a 'default' parent. In many
- * cases the parent is selectable. The get/set parent calls will also
- * switch sources.
- *
- * Many some clocks say always_enabled, but they can be auto idled for
- * power savings. They will always be available upon clock request.
+ * NOTE:In many cases here we are assigning a 'default' parent. In
+ * many cases the parent is selectable. The set parent calls will
+ * also switch sources.
*
* Several sources are given initial rates which may be wrong, this will
* be fixed up in the init func.
*
* Things are broadly separated below by clock domains. It is
- * noteworthy that most periferals have dependencies on multiple clock
+ * noteworthy that most peripherals have dependencies on multiple clock
* domains. Many get their interface clocks from the L4 domain, but get
* functional clocks from fixed sources or other core domain derived
* clocks.
^ permalink raw reply related
* [PATCH] msm: gpiomux: Remove GPIOMUX_VALID and merge config enums
From: Dima Zavin @ 2011-02-26 1:20 UTC (permalink / raw)
To: linux-arm-kernel
In-Reply-To: <4D680EEE.1070706@codeaurora.org>
On Fri, Feb 25, 2011 at 12:19 PM, Rohit Vaswani <rvaswani@codeaurora.org> wrote:
> Remove GPIOMUX_VALID, simplify the API, and absorb the complexity
> of determining which gpiomux configs are used and which are
> not back into the gpiomux implementation where it belongs.
> Allow NULL settings to be represented appropriately.
> The configuration enumerations represent a single abstraction
> and were needlessly split. As such, collapse the conflicting
> abstractions into a consistent one and move the implementation
> complexity down into the implementation (where it belongs) and
> away from the interface (where it doesn't belong).
>
> Signed-off-by: Rohit Vaswani <rvaswani@codeaurora.org>
> ---
> ?arch/arm/mach-msm/board-msm7x30.c | ? 23 +++++++--
> ?arch/arm/mach-msm/board-qsd8x50.c | ? 17 +++++--
> ?arch/arm/mach-msm/gpiomux-v1.c ? ?| ? ?9 ++-
> ?arch/arm/mach-msm/gpiomux-v1.h ? ?| ? 59 ----------------------
> ?arch/arm/mach-msm/gpiomux-v2.c ? ?| ? ?8 ++-
> ?arch/arm/mach-msm/gpiomux-v2.h ? ?| ? 59 ----------------------
> ?arch/arm/mach-msm/gpiomux.c ? ? ? | ? 77 +++++++++++++++++-------------
> ?arch/arm/mach-msm/gpiomux.h ? ? ? | ? 96
> +++++++++++++++++++++++-------------
> ?8 files changed, 145 insertions(+), 203 deletions(-)
> ?delete mode 100644 arch/arm/mach-msm/gpiomux-v1.h
> ?delete mode 100644 arch/arm/mach-msm/gpiomux-v2.h
>
> diff --git a/arch/arm/mach-msm/board-msm7x30.c
> b/arch/arm/mach-msm/board-msm7x30.c
> index 59b91de..4223329 100644
> --- a/arch/arm/mach-msm/board-msm7x30.c
> +++ b/arch/arm/mach-msm/board-msm7x30.c
> @@ -39,8 +39,11 @@
> ?#include "gpiomux.h"
> ?#include "proc_comm.h"
>
> -#define UART2_SUSPENDED (GPIOMUX_DRV_2MA | GPIOMUX_PULL_DOWN |\
> - ? ? ? ? ? ?GPIOMUX_FUNC_2 | GPIOMUX_VALID)
> +static struct gpiomux_setting uart2_suspended = {
> + ? ?.func = GPIOMUX_FUNC_2,
> + ? ?.drv = GPIOMUX_DRV_2MA,
> + ? ?.pull = GPIOMUX_PULL_DOWN,
> +};
>
> ?extern struct sys_timer msm_timer;
>
> @@ -59,19 +62,27 @@ static struct msm_otg_platform_data msm_otg_pdata = {
> ?struct msm_gpiomux_config msm7x30_uart2_configs[] __initdata = {
> ? ? {
> ? ? ? ? .gpio = 49, /* UART2 RFR */
> - ? ? ? ?.suspended = UART2_SUSPENDED,
> + ? ? ? ?.settings = {
> + ? ? ? ? ? ?[GPIOMUX_SUSPENDED] = &uart2_suspended,
> + ? ? ? ?},
> ? ? },
> ? ? {
> ? ? ? ? .gpio = 50, /* UART2 CTS */
> - ? ? ? ?.suspended = UART2_SUSPENDED,
> + ? ? ? ?.settings = {
> + ? ? ? ? ? ?[GPIOMUX_SUSPENDED] = &uart2_suspended,
> + ? ? ? ?},
> ? ? },
> ? ? {
> ? ? ? ? .gpio = 51, /* UART2 RX */
> - ? ? ? ?.suspended = UART2_SUSPENDED,
> + ? ? ? ?.settings = {
> + ? ? ? ? ? ?[GPIOMUX_SUSPENDED] = &uart2_suspended,
> + ? ? ? ?},
> ? ? },
> ? ? {
> ? ? ? ? .gpio = 52, /* UART2 TX */
> - ? ? ? ?.suspended = UART2_SUSPENDED,
> + ? ? ? ?.settings = {
> + ? ? ? ? ? ?[GPIOMUX_SUSPENDED] = &uart2_suspended,
> + ? ? ? ?},
> ? ? },
> ?};
>
> diff --git a/arch/arm/mach-msm/board-qsd8x50.c
> b/arch/arm/mach-msm/board-qsd8x50.c
> index 33ab1fe..d665b0e 100644
> --- a/arch/arm/mach-msm/board-qsd8x50.c
> +++ b/arch/arm/mach-msm/board-qsd8x50.c
> @@ -38,19 +38,26 @@
> ?#include "devices.h"
> ?#include "gpiomux.h"
>
> -#define UART3_SUSPENDED (GPIOMUX_DRV_2MA | GPIOMUX_PULL_DOWN |\
> - ? ? ? ? ? ?GPIOMUX_FUNC_1 | GPIOMUX_VALID)
> +static struct gpiomux_setting uart3_suspended = {
> + ? ?.drv = GPIOMUX_DRV_2MA,
> + ? ?.pull = GPIOMUX_PULL_DOWN,
> + ? ?.func = GPIOMUX_FUNC_1,
> +};
>
> ?extern struct sys_timer msm_timer;
>
> -struct msm_gpiomux_config qsd8x50_uart3_configs[] __initdata = {
> +struct msm_gpiomux_config qsd8x50_uart3_configs[] = {
> ? ? {
> ? ? ? ? .gpio = 86, /* UART3 RX */
> - ? ? ? ?.suspended = UART3_SUSPENDED,
> + ? ? ? ?.settings = {
> + ? ? ? ? ? ?[GPIOMUX_SUSPENDED] = &uart3_suspended,
> + ? ? ? ?},
> ? ? },
> ? ? {
> ? ? ? ? .gpio = 87, /* UART3 TX */
> - ? ? ? ?.suspended = UART3_SUSPENDED,
> + ? ? ? ?.settings = {
> + ? ? ? ? ? ?[GPIOMUX_SUSPENDED] = &uart3_suspended,
> + ? ? ? ?},
> ? ? },
> ?};
I think this new interface is way too verbose and will quickly get
unwieldy for configurations that have more than a few pins. For
instance, imagine what the above would look like when muxing a 24bit
LCD pin list...
How about adding a "bool valid" to gpiomux_setting, and convert the
"sets" array to an array of settings and not pointers to settings.
This will allow us to do (in gpiomux.h):
struct msm_gpiomux_rec {
?struct gpiomux_setting sets[GPIOMUX_NSETTINGS];
int ref;
};
struct gpiomux_setting {
enum gpiomux_func func;
enum gpiomux_drv ?drv;
enum gpiomux_pull pull;
bool valid;
};
This way, I can do something like (very rough):
#define GPIOMUX_SET(func,drv,pull) { \
.func = GPIOMUX_##func, \
.drv = GPIOMUX_##drv, \
.pull = GPIOMUX_##pull, \
.valid = true, \
}
#define GPIOMUX_SET_NONE { .valid = false, }
#define GPIOMUX_CFG(g, active, suspended) { \
.gpio = g, \
.sets = { \
[GPIOMUX_ACTIVE] = active, \
[GPIOMUX_SUSPENDED] = suspended, \
}, \
}
This will then allow me to define the uart3 pinmuxing in my board file
as follows:
struct msm_gpiomux_rec uart3_mux_cfg[] = {
GPIOMUX_CFG(86, GPIOMUX_SET_NONE,
GPIOMUX_SET(FUNC_1, DRV_2MA, PULL_DOWN)),
GPIOMUX_CFG(87, GPIOMUX_SET_NONE,
GPIOMUX_SET(FUNC_1, DRV_2MA, PULL_DOWN)),
};
Thoughts?
--Dima
>
> diff --git a/arch/arm/mach-msm/gpiomux-v1.c b/arch/arm/mach-msm/gpiomux-v1.c
> index 27de2ab..a9525c2 100644
> --- a/arch/arm/mach-msm/gpiomux-v1.c
> +++ b/arch/arm/mach-msm/gpiomux-v1.c
> @@ -18,13 +18,16 @@
> ?#include "gpiomux.h"
> ?#include "proc_comm.h"
>
> -void __msm_gpiomux_write(unsigned gpio, gpiomux_config_t val)
> +void __msm_gpiomux_write(unsigned gpio, struct gpiomux_setting val)
> ?{
> - ? ?unsigned tlmm_config ?= (val & ~GPIOMUX_CTL_MASK) |
> - ? ? ? ? ? ? ? ?((gpio & 0x3ff) << 4);
> + ? ?unsigned tlmm_config;
> ? ? unsigned tlmm_disable = 0;
> ? ? int rc;
>
> + ? ?tlmm_config ?= (val.drv << 17) |
> + ? ? ? ?(val.pull << 15) |
> + ? ? ? ?((gpio & 0x3ff) << 4) |
> + ? ? ? ?val.func;
> ? ? rc = msm_proc_comm(PCOM_RPC_GPIO_TLMM_CONFIG_EX,
> &tlmm_config, &tlmm_disable);
> ? ? if (rc)
> diff --git a/arch/arm/mach-msm/gpiomux-v1.h b/arch/arm/mach-msm/gpiomux-v1.h
> deleted file mode 100644
> index 96ad5fa..0000000
> --- a/arch/arm/mach-msm/gpiomux-v1.h
> +++ /dev/null
> @@ -1,59 +0,0 @@
> -/* Copyright (c) 2010, Code Aurora Forum. All rights reserved.
> - *
> - * This program is free software; you can redistribute it and/or modify
> - * it under the terms of the GNU General Public License version 2 and
> - * only version 2 as published by the Free Software Foundation.
> - *
> - * This program is distributed in the hope that it will be useful,
> - * but WITHOUT ANY WARRANTY; without even the implied warranty of
> - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. ?See the
> - * GNU General Public License for more details.
> - *
> - * You should have received a copy of the GNU General Public License
> - * along with this program; if not, write to the Free Software
> - * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
> - * 02110-1301, USA.
> - */
> -#ifndef __ARCH_ARM_MACH_MSM_GPIOMUX_V1_H
> -#define __ARCH_ARM_MACH_MSM_GPIOMUX_V1_H
> -
> -typedef u32 gpiomux_config_t;
> -
> -enum {
> - ? ?GPIOMUX_DRV_2MA ?= 0UL << 17,
> - ? ?GPIOMUX_DRV_4MA ?= 1UL << 17,
> - ? ?GPIOMUX_DRV_6MA ?= 2UL << 17,
> - ? ?GPIOMUX_DRV_8MA ?= 3UL << 17,
> - ? ?GPIOMUX_DRV_10MA = 4UL << 17,
> - ? ?GPIOMUX_DRV_12MA = 5UL << 17,
> - ? ?GPIOMUX_DRV_14MA = 6UL << 17,
> - ? ?GPIOMUX_DRV_16MA = 7UL << 17,
> -};
> -
> -enum {
> - ? ?GPIOMUX_FUNC_GPIO = 0UL,
> - ? ?GPIOMUX_FUNC_1 ? ?= 1UL,
> - ? ?GPIOMUX_FUNC_2 ? ?= 2UL,
> - ? ?GPIOMUX_FUNC_3 ? ?= 3UL,
> - ? ?GPIOMUX_FUNC_4 ? ?= 4UL,
> - ? ?GPIOMUX_FUNC_5 ? ?= 5UL,
> - ? ?GPIOMUX_FUNC_6 ? ?= 6UL,
> - ? ?GPIOMUX_FUNC_7 ? ?= 7UL,
> - ? ?GPIOMUX_FUNC_8 ? ?= 8UL,
> - ? ?GPIOMUX_FUNC_9 ? ?= 9UL,
> - ? ?GPIOMUX_FUNC_A ? ?= 10UL,
> - ? ?GPIOMUX_FUNC_B ? ?= 11UL,
> - ? ?GPIOMUX_FUNC_C ? ?= 12UL,
> - ? ?GPIOMUX_FUNC_D ? ?= 13UL,
> - ? ?GPIOMUX_FUNC_E ? ?= 14UL,
> - ? ?GPIOMUX_FUNC_F ? ?= 15UL,
> -};
> -
> -enum {
> - ? ?GPIOMUX_PULL_NONE ? = 0UL << 15,
> - ? ?GPIOMUX_PULL_DOWN ? = 1UL << 15,
> - ? ?GPIOMUX_PULL_KEEPER = 2UL << 15,
> - ? ?GPIOMUX_PULL_UP ? ? = 3UL << 15,
> -};
> -
> -#endif
> diff --git a/arch/arm/mach-msm/gpiomux-v2.c b/arch/arm/mach-msm/gpiomux-v2.c
> index 273396d..0a04d60 100644
> --- a/arch/arm/mach-msm/gpiomux-v2.c
> +++ b/arch/arm/mach-msm/gpiomux-v2.c
> @@ -18,8 +18,10 @@
> ?#include <mach/msm_iomap.h>
> ?#include "gpiomux.h"
>
> -void __msm_gpiomux_write(unsigned gpio, gpiomux_config_t val)
> +void __msm_gpiomux_write(unsigned gpio, struct gpiomux_setting val)
> ?{
> - ? ?writel(val & ~GPIOMUX_CTL_MASK,
> - ? ? ? ? ? MSM_TLMM_BASE + 0x1000 + (0x10 * gpio));
> + ? ?uint32_t bits;
> +
> + ? ?bits = (val.drv << 6) | (val.func << 2) | val.pull;
> + ? ?writel(bits, MSM_TLMM_BASE + 0x1000 + (0x10 * gpio));
> ?}
> diff --git a/arch/arm/mach-msm/gpiomux-v2.h b/arch/arm/mach-msm/gpiomux-v2.h
> deleted file mode 100644
> index a7dec1ea..0000000
> --- a/arch/arm/mach-msm/gpiomux-v2.h
> +++ /dev/null
> @@ -1,59 +0,0 @@
> -/* Copyright (c) 2010, Code Aurora Forum. All rights reserved.
> - *
> - * This program is free software; you can redistribute it and/or modify
> - * it under the terms of the GNU General Public License version 2 and
> - * only version 2 as published by the Free Software Foundation.
> - *
> - * This program is distributed in the hope that it will be useful,
> - * but WITHOUT ANY WARRANTY; without even the implied warranty of
> - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. ?See the
> - * GNU General Public License for more details.
> - *
> - * You should have received a copy of the GNU General Public License
> - * along with this program; if not, write to the Free Software
> - * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
> - * 02110-1301, USA.
> - */
> -#ifndef __ARCH_ARM_MACH_MSM_GPIOMUX_V2_H
> -#define __ARCH_ARM_MACH_MSM_GPIOMUX_V2_H
> -
> -typedef u16 gpiomux_config_t;
> -
> -enum {
> - ? ?GPIOMUX_DRV_2MA ?= 0UL << 6,
> - ? ?GPIOMUX_DRV_4MA ?= 1UL << 6,
> - ? ?GPIOMUX_DRV_6MA ?= 2UL << 6,
> - ? ?GPIOMUX_DRV_8MA ?= 3UL << 6,
> - ? ?GPIOMUX_DRV_10MA = 4UL << 6,
> - ? ?GPIOMUX_DRV_12MA = 5UL << 6,
> - ? ?GPIOMUX_DRV_14MA = 6UL << 6,
> - ? ?GPIOMUX_DRV_16MA = 7UL << 6,
> -};
> -
> -enum {
> - ? ?GPIOMUX_FUNC_GPIO = 0UL << 2,
> - ? ?GPIOMUX_FUNC_1 ? ?= 1UL << 2,
> - ? ?GPIOMUX_FUNC_2 ? ?= 2UL << 2,
> - ? ?GPIOMUX_FUNC_3 ? ?= 3UL << 2,
> - ? ?GPIOMUX_FUNC_4 ? ?= 4UL << 2,
> - ? ?GPIOMUX_FUNC_5 ? ?= 5UL << 2,
> - ? ?GPIOMUX_FUNC_6 ? ?= 6UL << 2,
> - ? ?GPIOMUX_FUNC_7 ? ?= 7UL << 2,
> - ? ?GPIOMUX_FUNC_8 ? ?= 8UL << 2,
> - ? ?GPIOMUX_FUNC_9 ? ?= 9UL << 2,
> - ? ?GPIOMUX_FUNC_A ? ?= 10UL << 2,
> - ? ?GPIOMUX_FUNC_B ? ?= 11UL << 2,
> - ? ?GPIOMUX_FUNC_C ? ?= 12UL << 2,
> - ? ?GPIOMUX_FUNC_D ? ?= 13UL << 2,
> - ? ?GPIOMUX_FUNC_E ? ?= 14UL << 2,
> - ? ?GPIOMUX_FUNC_F ? ?= 15UL << 2,
> -};
> -
> -enum {
> - ? ?GPIOMUX_PULL_NONE ? = 0UL,
> - ? ?GPIOMUX_PULL_DOWN ? = 1UL,
> - ? ?GPIOMUX_PULL_KEEPER = 2UL,
> - ? ?GPIOMUX_PULL_UP ? ? = 3UL,
> -};
> -
> -#endif
> diff --git a/arch/arm/mach-msm/gpiomux.c b/arch/arm/mach-msm/gpiomux.c
> index 9ef9864..1ca26ec 100644
> --- a/arch/arm/mach-msm/gpiomux.c
> +++ b/arch/arm/mach-msm/gpiomux.c
> @@ -20,21 +20,21 @@
> ?#include "gpiomux.h"
>
> ?struct msm_gpiomux_rec {
> - ? ?gpiomux_config_t active;
> - ? ?gpiomux_config_t suspended;
> - ? ?int ? ? ? ? ? ? ?ref;
> + ? ?struct gpiomux_setting *sets[GPIOMUX_NSETTINGS];
> + ? ?int ref;
> ?};
> ?static DEFINE_SPINLOCK(gpiomux_lock);
> ?static struct msm_gpiomux_rec *msm_gpiomux_recs;
> +static struct gpiomux_setting *msm_gpiomux_sets;
> ?static unsigned msm_gpiomux_ngpio;
>
> -int msm_gpiomux_write(unsigned gpio,
> - ? ? ? ? ? ? ?gpiomux_config_t active,
> - ? ? ? ? ? ? ?gpiomux_config_t suspended)
> +int msm_gpiomux_write(unsigned gpio, enum msm_gpiomux_setting which,
> + ? ?struct gpiomux_setting *setting)
> ?{
> - ? ?struct msm_gpiomux_rec *cfg = msm_gpiomux_recs + gpio;
> + ? ?struct msm_gpiomux_rec *rec = msm_gpiomux_recs + gpio;
> + ? ?unsigned set_slot = gpio * GPIOMUX_NSETTINGS + which;
> ? ? unsigned long irq_flags;
> - ? ?gpiomux_config_t setting;
> + ? ?struct gpiomux_setting *new_set;
>
> ? ? if (!msm_gpiomux_recs)
> ? ? ? ? return -EFAULT;
> @@ -44,15 +44,17 @@ int msm_gpiomux_write(unsigned gpio,
>
> ? ? spin_lock_irqsave(&gpiomux_lock, irq_flags);
>
> - ? ?if (active & GPIOMUX_VALID)
> - ? ? ? ?cfg->active = active;
> -
> - ? ?if (suspended & GPIOMUX_VALID)
> - ? ? ? ?cfg->suspended = suspended;
> + ? ?if (setting) {
> + ? ? ? ?msm_gpiomux_sets[set_slot] = *setting;
> + ? ? ? ?rec->sets[which] = &msm_gpiomux_sets[set_slot];
> + ? ?} else {
> + ? ? ? ?rec->sets[which] = NULL;
> + ? ?}
>
> - ? ?setting = cfg->ref ? active : suspended;
> - ? ?if (setting & GPIOMUX_VALID)
> - ? ? ? ?__msm_gpiomux_write(gpio, setting);
> + ? ?new_set = rec->ref ? rec->sets[GPIOMUX_ACTIVE] :
> + ? ? ? ?rec->sets[GPIOMUX_SUSPENDED];
> + ? ?if (new_set)
> + ? ? ? ?__msm_gpiomux_write(gpio, *new_set);
>
> ? ? spin_unlock_irqrestore(&gpiomux_lock, irq_flags);
> ? ? return 0;
> @@ -61,7 +63,7 @@ EXPORT_SYMBOL(msm_gpiomux_write);
>
> ?int msm_gpiomux_get(unsigned gpio)
> ?{
> - ? ?struct msm_gpiomux_rec *cfg = msm_gpiomux_recs + gpio;
> + ? ?struct msm_gpiomux_rec *rec = msm_gpiomux_recs + gpio;
> ? ? unsigned long irq_flags;
>
> ? ? if (!msm_gpiomux_recs)
> @@ -71,8 +73,8 @@ int msm_gpiomux_get(unsigned gpio)
> ? ? ? ? return -EINVAL;
>
> ? ? spin_lock_irqsave(&gpiomux_lock, irq_flags);
> - ? ?if (cfg->ref++ == 0 && cfg->active & GPIOMUX_VALID)
> - ? ? ? ?__msm_gpiomux_write(gpio, cfg->active);
> + ? ?if (rec->ref++ == 0 && rec->sets[GPIOMUX_ACTIVE])
> + ? ? ? ?__msm_gpiomux_write(gpio, *rec->sets[GPIOMUX_ACTIVE]);
> ? ? spin_unlock_irqrestore(&gpiomux_lock, irq_flags);
> ? ? return 0;
> ?}
> @@ -80,7 +82,7 @@ EXPORT_SYMBOL(msm_gpiomux_get);
>
> ?int msm_gpiomux_put(unsigned gpio)
> ?{
> - ? ?struct msm_gpiomux_rec *cfg = msm_gpiomux_recs + gpio;
> + ? ?struct msm_gpiomux_rec *rec = msm_gpiomux_recs + gpio;
> ? ? unsigned long irq_flags;
>
> ? ? if (!msm_gpiomux_recs)
> @@ -90,9 +92,9 @@ int msm_gpiomux_put(unsigned gpio)
> ? ? ? ? return -EINVAL;
>
> ? ? spin_lock_irqsave(&gpiomux_lock, irq_flags);
> - ? ?BUG_ON(cfg->ref == 0);
> - ? ?if (--cfg->ref == 0 && cfg->suspended & GPIOMUX_VALID)
> - ? ? ? ?__msm_gpiomux_write(gpio, cfg->suspended);
> + ? ?BUG_ON(rec->ref == 0);
> + ? ?if (--rec->ref == 0 && rec->sets[GPIOMUX_SUSPENDED])
> + ? ? ? ?__msm_gpiomux_write(gpio, *rec->sets[GPIOMUX_SUSPENDED]);
> ? ? spin_unlock_irqrestore(&gpiomux_lock, irq_flags);
> ? ? return 0;
> ?}
> @@ -111,6 +113,17 @@ int msm_gpiomux_init(size_t ngpio)
> ? ? if (!msm_gpiomux_recs)
> ? ? ? ? return -ENOMEM;
>
> + ? ?/* There is no need to zero this memory, as clients will be blindly
> + ? ? * installing settings on top of it.
> + ? ? */
> + ? ?msm_gpiomux_sets = kmalloc(sizeof(struct gpiomux_setting) * ngpio *
> + ? ? ? ?GPIOMUX_NSETTINGS, GFP_KERNEL);
> + ? ?if (!msm_gpiomux_sets) {
> + ? ? ? ?kfree(msm_gpiomux_recs);
> + ? ? ? ?msm_gpiomux_recs = NULL;
> + ? ? ? ?return -ENOMEM;
> + ? ?}
> +
> ? ? msm_gpiomux_ngpio = ngpio;
>
> ? ? return 0;
> @@ -119,18 +132,16 @@ EXPORT_SYMBOL(msm_gpiomux_init);
>
> ?void msm_gpiomux_install(struct msm_gpiomux_config *configs, unsigned
> nconfigs)
> ?{
> - ? ?unsigned n;
> + ? ?unsigned c, s;
> ? ? int rc;
>
> - ? ?if (!msm_gpiomux_recs)
> - ? ? ? ?return;
> -
> - ? ?for (n = 0; n < nconfigs; ++n) {
> - ? ? ? ?rc = msm_gpiomux_write(configs[n].gpio,
> - ? ? ? ? ? ? ? ? ? ? ? configs[n].active,
> - ? ? ? ? ? ? ? ? ? ? ? configs[n].suspended);
> - ? ? ? ?if (rc)
> - ? ? ? ? ? ?pr_err("%s: write failure: %d\n", __func__, rc);
> + ? ?for (c = 0; c < nconfigs; ++c) {
> + ? ? ? ?for (s = 0; s < GPIOMUX_NSETTINGS; ++s) {
> + ? ? ? ? ? ?rc = msm_gpiomux_write(configs[c].gpio, s,
> + ? ? ? ? ? ? ? ?configs[c].settings[s]);
> + ? ? ? ? ? ?if (rc)
> + ? ? ? ? ? ? ? ?pr_err("%s: write failure: %d\n", __func__, rc);
> + ? ? ? ?}
> ? ? }
> ?}
> ?EXPORT_SYMBOL(msm_gpiomux_install);
> diff --git a/arch/arm/mach-msm/gpiomux.h b/arch/arm/mach-msm/gpiomux.h
> index 38bf511..bd8d6c2 100644
> --- a/arch/arm/mach-msm/gpiomux.h
> +++ b/arch/arm/mach-msm/gpiomux.h
> @@ -20,44 +20,73 @@
> ?#include <linux/bitops.h>
> ?#include <linux/errno.h>
>
> -#if defined(CONFIG_MSM_V2_TLMM)
> -#include "gpiomux-v2.h"
> -#else
> -#include "gpiomux-v1.h"
> -#endif
> +enum msm_gpiomux_setting {
> + ? ?GPIOMUX_ACTIVE = 0,
> + ? ?GPIOMUX_SUSPENDED,
> + ? ?GPIOMUX_NSETTINGS
> +};
> +
> +enum gpiomux_drv {
> + ? ?GPIOMUX_DRV_2MA = 0,
> + ? ?GPIOMUX_DRV_4MA,
> + ? ?GPIOMUX_DRV_6MA,
> + ? ?GPIOMUX_DRV_8MA,
> + ? ?GPIOMUX_DRV_10MA,
> + ? ?GPIOMUX_DRV_12MA,
> + ? ?GPIOMUX_DRV_14MA,
> + ? ?GPIOMUX_DRV_16MA,
> +};
> +
> +enum gpiomux_func {
> + ? ?GPIOMUX_FUNC_GPIO = 0,
> + ? ?GPIOMUX_FUNC_1,
> + ? ?GPIOMUX_FUNC_2,
> + ? ?GPIOMUX_FUNC_3,
> + ? ?GPIOMUX_FUNC_4,
> + ? ?GPIOMUX_FUNC_5,
> + ? ?GPIOMUX_FUNC_6,
> + ? ?GPIOMUX_FUNC_7,
> + ? ?GPIOMUX_FUNC_8,
> + ? ?GPIOMUX_FUNC_9,
> + ? ?GPIOMUX_FUNC_A,
> + ? ?GPIOMUX_FUNC_B,
> + ? ?GPIOMUX_FUNC_C,
> + ? ?GPIOMUX_FUNC_D,
> + ? ?GPIOMUX_FUNC_E,
> + ? ?GPIOMUX_FUNC_F,
> +};
> +
> +enum gpiomux_pull {
> + ? ?GPIOMUX_PULL_NONE = 0,
> + ? ?GPIOMUX_PULL_DOWN,
> + ? ?GPIOMUX_PULL_KEEPER,
> + ? ?GPIOMUX_PULL_UP,
> +};
> +
> +struct gpiomux_setting {
> + ? ?enum gpiomux_func func;
> + ? ?enum gpiomux_drv ?drv;
> + ? ?enum gpiomux_pull pull;
> +};
>
> ?/**
> ?* struct msm_gpiomux_config: gpiomux settings for one gpio line.
> ?*
> - * A complete gpiomux config is the bitwise-or of a drive-strength,
> + * A complete gpiomux setting is the combination of a drive-strength,
> ?* function, and pull. ?For functions other than GPIO, the OE
> ?* is hard-wired according to the function. ?For GPIO mode,
> ?* OE is controlled by gpiolib.
> ?*
> - * Available settings differ by target; see the gpiomux header
> - * specific to your target arch for available configurations.
> - *
> ?* @gpio: The index number of the gpio being described.
> - * @active: The configuration to be installed when the line is
> - * active, or its reference count is > 0.
> - * @suspended: The configuration to be installed when the line
> - * is suspended, or its reference count is 0.
> + * @settings: The settings to be installed, specifically:
> + * ? ? ? ? ? GPIOMUX_ACTIVE: The setting to be installed when the
> + * ? ? ? ? ? line is active, or its reference count is > 0.
> + * ? ? ? ? ? GPIOMUX_SUSPENDED: The setting to be installed when
> + * ? ? ? ? ? the line is suspended, or its reference count is 0.
> ?*/
> ?struct msm_gpiomux_config {
> - ? ?unsigned ? ? ? ? gpio;
> - ? ?gpiomux_config_t active;
> - ? ?gpiomux_config_t suspended;
> -};
> -
> -/**
> - * @GPIOMUX_VALID: ? ?If set, the config field contains 'good data'.
> - * ? ? ? ? ? ? ? ? ? ? ?The absence of this bit will prevent the gpiomux
> - * ? ? ? ? ? ?system from applying the configuration under all
> - * ? ? ? ? ? ?circumstances.
> - */
> -enum {
> - ? ?GPIOMUX_VALID ? ? = BIT(sizeof(gpiomux_config_t) * BITS_PER_BYTE - 1),
> - ? ?GPIOMUX_CTL_MASK = GPIOMUX_VALID,
> + ? ?unsigned gpio;
> + ? ?struct gpiomux_setting *settings[GPIOMUX_NSETTINGS];
> ?};
>
> ?#ifdef CONFIG_MSM_GPIOMUX
> @@ -79,12 +108,10 @@ int __must_check msm_gpiomux_get(unsigned gpio);
> ?/* Decrement a gpio's reference count, possibly suspending the line. */
> ?int msm_gpiomux_put(unsigned gpio);
>
> -/* Install a new configuration to the gpio line. ?To avoid overwriting
> - * a configuration, leave the VALID bit out.
> +/* Install a new setting in a gpio. ?To erase a slot, use NULL.
> ?*/
> -int msm_gpiomux_write(unsigned gpio,
> - ? ? ? ? ? ? ?gpiomux_config_t active,
> - ? ? ? ? ? ? ?gpiomux_config_t suspended);
> +int msm_gpiomux_write(unsigned gpio, enum msm_gpiomux_setting which,
> + ? ?struct gpiomux_setting *setting);
>
> ?/* Architecture-internal function for use by the framework only.
> ?* This function can assume the following:
> @@ -94,7 +121,7 @@ int msm_gpiomux_write(unsigned gpio,
> ?* This function is not for public consumption. ?External users
> ?* should use msm_gpiomux_write.
> ?*/
> -void __msm_gpiomux_write(unsigned gpio, gpiomux_config_t val);
> +void __msm_gpiomux_write(unsigned gpio, struct gpiomux_setting val);
> ?#else
> ?static inline int msm_gpiomux_init(size_t ngpio)
> ?{
> @@ -115,8 +142,7 @@ static inline int msm_gpiomux_put(unsigned gpio)
> ?}
>
> ?static inline int msm_gpiomux_write(unsigned gpio,
> - ? ? ? ? ? ? ? ? ? ?gpiomux_config_t active,
> - ? ? ? ? ? ? ? ? ? ?gpiomux_config_t suspended)
> + ? ?enum msm_gpiomux_setting which, struct gpiomux_setting *setting)
> ?{
> ? ? return -ENOSYS;
> ?}
> --
> 1.7.3.3
>
>
> Thanks,
> Rohit Vaswani
>
> --
> Sent by an employee of the Qualcomm Innovation Center, Inc.
> The Qualcomm Innovation Center, Inc. is a member of the Code Aurora Forum.
>
>
^ permalink raw reply
* [PATCH] OMAP2+: sdrc: fix compile break on OMAP4-only config on current omap-for-linus
From: Paul Walmsley @ 2011-02-26 1:40 UTC (permalink / raw)
To: linux-arm-kernel
On non-OMAP2 and non-OMAP3 kernel configs, turn omap2_sdrc_init() into
a no-op. Otherwise, compilation breaks on an OMAP4-only config with
the current omap-for-linus branch:
arch/arm/mach-omap2/built-in.o: In function `omap2_init_common_devices':
../mach-omap2/io.c:421: undefined reference to `omap2_sdrc_init'
Signed-off-by: Paul Walmsley <paul@pwsan.com>
Cc: Tony Lindgren <tony@atomide.com>
---
arch/arm/plat-omap/include/plat/sdrc.h | 5 +++++
1 files changed, 5 insertions(+), 0 deletions(-)
diff --git a/arch/arm/plat-omap/include/plat/sdrc.h b/arch/arm/plat-omap/include/plat/sdrc.h
index efd87c8..5a44b14 100644
--- a/arch/arm/plat-omap/include/plat/sdrc.h
+++ b/arch/arm/plat-omap/include/plat/sdrc.h
@@ -124,8 +124,13 @@ struct omap_sdrc_params {
u32 mr;
};
+#if defined(CONFIG_ARCH_OMAP2) || defined(CONFIG_ARCH_OMAP3)
void __init omap2_sdrc_init(struct omap_sdrc_params *sdrc_cs0,
struct omap_sdrc_params *sdrc_cs1);
+#else
+#define omap2_sdrc_init(x, y) 0
+#endif
+
int omap2_sdrc_get_params(unsigned long r,
struct omap_sdrc_params **sdrc_cs0,
struct omap_sdrc_params **sdrc_cs1);
--
1.7.2.3
^ permalink raw reply related
* [PATCH V2] arm: mach-mmp: brownstone.c support multiple sd slots
From: Philip Rakity @ 2011-02-26 1:50 UTC (permalink / raw)
To: linux-arm-kernel
Support multiple sd/eMMC interfaces. enable mmc1, 2, and 3.
mmc2 is used eMMC and slot is marked PERMANENT and 8 bit device.
mmc1 is used for Wifi and slot is marked PERMANENT
Note: eMMC (mmc2) is set to initialize first to workaround a problem
where booting in logical order requires mmc create work queue
to be multi-threaded otherwise boot process hangs. BUG report
send to linux-mmc and linux-kernel mailing list.
Wifi (mmc1) requires we enable power on the device by toggling
the gpio lines for power and reset.
Signed-off-by: Philip Rakity <prakity@marvell.com>
---
arch/arm/mach-mmp/brownstone.c | 42 ++++++++++++++++++++++++++++++++++++++++
1 files changed, 42 insertions(+), 0 deletions(-)
diff --git a/arch/arm/mach-mmp/brownstone.c b/arch/arm/mach-mmp/brownstone.c
index 7bb78fd..36d5b82 100644
--- a/arch/arm/mach-mmp/brownstone.c
+++ b/arch/arm/mach-mmp/brownstone.c
@@ -19,6 +19,7 @@
#include <linux/regulator/max8649.h>
#include <linux/regulator/fixed.h>
#include <linux/mfd/max8925.h>
+#include <linux/delay.h>
#include <asm/mach-types.h>
#include <asm/mach/arch.h>
@@ -180,6 +181,45 @@ static struct sdhci_pxa_platdata mmp2_sdh_platdata_mmc0 = {
.max_speed = 25000000,
};
+static struct sdhci_pxa_platdata mmp2_sdh_platdata_mmc1 = {
+ .flags = PXA_FLAG_CARD_PERMANENT,
+};
+
+static struct sdhci_pxa_platdata mmp2_sdh_platdata_mmc2 = {
+ .flags = PXA_FLAG_CARD_PERMANENT |
+ PXA_FLAG_SD_8_BIT_CAPABLE_SLOT,
+};
+
+static void __init mmc_sdio_wifi(void)
+{
+ int poweron;
+ int reset;
+
+ poweron = mfp_to_gpio(GPIO57_GPIO);
+ reset = mfp_to_gpio(GPIO58_GPIO);
+
+ if(gpio_request(reset, "sd8xxx reset")) {
+ printk(KERN_INFO "gpio %d request failed\n", reset);
+ return;
+ }
+
+ if(gpio_request(poweron, "sd8xxx PDn")) {
+ gpio_free(reset);
+ printk(KERN_INFO "gpio %d request failed\n", poweron);
+ return;
+ }
+
+ gpio_direction_output(poweron, 1);
+ msleep (1);
+ gpio_direction_output(reset, 0);
+ msleep (1);
+ gpio_direction_output(reset, 1);
+ gpio_free(reset);
+ gpio_free(poweron);
+
+ mmp2_add_sdhost(1, &mmp2_sdh_platdata_mmc1); /* Wifi */
+}
+
static void __init brownstone_init(void)
{
mfp_config(ARRAY_AND_SIZE(brownstone_pin_config));
@@ -188,7 +228,9 @@ static void __init brownstone_init(void)
mmp2_add_uart(1);
mmp2_add_uart(3);
mmp2_add_twsi(1, NULL, ARRAY_AND_SIZE(brownstone_twsi1_info));
+ mmp2_add_sdhost(2, &mmp2_sdh_platdata_mmc2); /* eMMC */
mmp2_add_sdhost(0, &mmp2_sdh_platdata_mmc0); /* SD/MMC */
+ mmc_sdio_wifi();
/* enable 5v regulator */
platform_device_register(&brownstone_v_5vp_device);
--
1.7.0.4
^ permalink raw reply related
page: next (older) | prev (newer) | latest
- recent:[subjects (threaded)|topics (new)|topics (active)]
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox