* [PATCH] ARM: OMAP2+: voltage: fixup oscillator handling when CONFIG_PM=n
From: Kevin Hilman @ 2012-11-15 1:13 UTC (permalink / raw)
To: linux-arm-kernel
From: Kevin Hilman <khilman@ti.com>
commit 908b75e8 (ARM: OMAP: add support for oscillator setup) added a new
API for oscillator setup, but is broken when CONFIG_PM=n.
The new functions have dummy definitions when CONFIG_PM=n, but also have
full implementations available, which conflict.
To fix, wrap the PM implmentations in #ifdef CONFIG_PM.
Cc: Tero Kristo <t-kristo@ti.com>
Signed-off-by: Kevin Hilman <khilman@ti.com>
---
This applies to Tony's omap-for-v3.8/pm branch, which includes my
for_3.8-pm-voltage tag where this bug was introduced.
arch/arm/mach-omap2/pm.c | 2 ++
arch/arm/mach-omap2/pm.h | 2 +-
arch/arm/mach-omap2/vc.c | 2 ++
3 files changed, 5 insertions(+), 1 deletion(-)
diff --git a/arch/arm/mach-omap2/pm.c b/arch/arm/mach-omap2/pm.c
index 109a02e..ef668c756 100644
--- a/arch/arm/mach-omap2/pm.c
+++ b/arch/arm/mach-omap2/pm.c
@@ -39,6 +39,7 @@ static struct omap_device_pm_latency *pm_lats;
*/
int (*omap_pm_suspend)(void);
+#ifdef CONFIG_PM
/**
* struct omap2_oscillator - Describe the board main oscillator latencies
* @startup_time: oscillator startup latency
@@ -68,6 +69,7 @@ void omap_pm_get_oscillator(u32 *tstart, u32 *tshut)
*tstart = oscillator.startup_time;
*tshut = oscillator.shutdown_time;
}
+#endif
static int __init _init_omap_device(char *name)
{
diff --git a/arch/arm/mach-omap2/pm.h b/arch/arm/mach-omap2/pm.h
index 4db7b23..02c291c 100644
--- a/arch/arm/mach-omap2/pm.h
+++ b/arch/arm/mach-omap2/pm.h
@@ -135,7 +135,7 @@ extern void omap_pm_get_oscillator(u32 *tstart, u32 *tshut);
extern void omap_pm_setup_sr_i2c_pcb_length(u32 mm);
#else
static inline void omap_pm_setup_oscillator(u32 tstart, u32 tshut) { }
-static inline void omap_pm_get_oscillator(u32 *tstart, u32 *tshut) { }
+static inline void omap_pm_get_oscillator(u32 *tstart, u32 *tshut) { *tstart = *tshut = 0; }
static inline void omap_pm_setup_sr_i2c_pcb_length(u32 mm) { }
#endif
diff --git a/arch/arm/mach-omap2/vc.c b/arch/arm/mach-omap2/vc.c
index 687aa86..a89ec8a 100644
--- a/arch/arm/mach-omap2/vc.c
+++ b/arch/arm/mach-omap2/vc.c
@@ -666,6 +666,7 @@ static u8 omap_vc_calc_vsel(struct voltagedomain *voltdm, u32 uvolt)
return voltdm->pmic->uv_to_vsel(uvolt);
}
+#ifdef CONFIG_PM
/**
* omap_pm_setup_sr_i2c_pcb_length - set length of SR I2C traces on PCB
* @mm: length of the PCB trace in millimetres
@@ -678,6 +679,7 @@ void __init omap_pm_setup_sr_i2c_pcb_length(u32 mm)
{
sr_i2c_pcb_length = mm;
}
+#endif
void __init omap_vc_init_channel(struct voltagedomain *voltdm)
{
--
1.8.0
^ permalink raw reply related
* [PATCH] ARM: Fix errata 751472 handling on Cortex-A9 r1p*
From: Rob Herring @ 2012-11-15 0:54 UTC (permalink / raw)
To: linux-arm-kernel
In-Reply-To: <20121114222159.GB6801@atomide.com>
On 11/14/2012 04:21 PM, Tony Lindgren wrote:
> * Rob Herring <robherring2@gmail.com> [121114 13:59]:
>> On 11/14/2012 02:32 PM, Tony Lindgren wrote:
>>>
>>> Checking for the bit already set should work in this case, I'll post
>>> a patch for that shortly.
>>
>> Can you actually read the state of the diagnostic register in non-secure
>> mode? If you can on the A9, is the same true on A8 or others?
>
> Looks like it can be read on at least TI omap 4430 which is A9.
> But it reads as zero, so the below patch is what I came up with.
>
> No idea if assuming that zero value for the diagnostic register
> is safe.. What's the default value of the diagnostic register supposed
> to be?
RTFM. Oh, wait it's a super secret, undocumented register. We shouldn't
even be talking about it.
It could vary by rev, but I see 0 for the reset value, so this would not
work if the bootloader did not do any setup of the diagnostic register.
One way to determine secure mode on the A9 would be seeing if you can
change the auxcr register. Something like this (untested):
mrc p15, 0, r0, c1, c0, 1; Read ACTLR
eor r1, r0, #0x100 ; Modify alloc in 1 way
mcr p15, 0, r1, c1, c0, 1
mrc p15, 0, r2, c1, c0, 1; Read ACTLR
mcr p15, 0, r0, c1, c0, 1 ; Restore original value
cmp r1, r2
bne skip_errata
It would be good to do this test for all the errata rather than just
this one.
Rob
>> Multi-platform kernels present a new problem in that we basically need
>> to enable all errata work-arounds. I've been meaning to look thru the
>> errata work-arounds to figure out which ones can be selected for
>> multi-platform kernels without side effects on unaffected parts (i.e.
>> set a chicken bit based on core revision). For any in runtime paths, we
>> may need to do runtime patching if they have performance impact.
>
> Yeah that's how I ran into it as multiplatform enabled omap booted
> on other omaps but not on omap4.
>
> Regards,
>
> Tony
>
>
> From: Tony Lindgren <tony@atomide.com>
> Date: Tue, 13 Nov 2012 16:57:42 -0800
> Subject: [PATCH] ARM: Fix errata 751472 handling on Cortex-A9 for secure mode
>
> Looks like enabling CONFIG_ARM_ERRATA_751472 causes TI omap4 blaze
> to not boot when enabled. The ARM core on it is an earlier r1p2.
>
> This seems to be caused by the write to the diagnostic register
> that shortly after causes an exception as writing to the diagnostic
> register on systems with secure mode is not allowed.
>
> Also it seems that reading the diagnostic register results zero
> so we may not be able to check if bit #11 is already set.
>
> Let's assume that if the diagnostic register is zero, we don't
> want to touch it as it seems to hint secure mode at least on
> TI omaps. If it's non-zero, check if bit #11 is set and only
> attempt to set it if not set.
>
> --- a/arch/arm/mm/proc-v7.S
> +++ b/arch/arm/mm/proc-v7.S
> @@ -238,9 +238,13 @@ __v7_setup:
> #if defined(CONFIG_ARM_ERRATA_751472) && defined(CONFIG_SMP)
> ALT_SMP(cmp r6, #0x30) @ present prior to r3p0
> ALT_UP_B(1f)
> - mrclt p15, 0, r10, c15, c0, 1 @ read diagnostic register
> - orrlt r10, r10, #1 << 11 @ set bit #11
> - mcrlt p15, 0, r10, c15, c0, 1 @ write diagnostic register
> + bge 1f @ not needed for r3p0 and later
> + mrc p15, 0, r10, c15, c0, 1 @ read diagnostic register
> + teq r10, #0 @ zero for secure mode?
> + beq 1f @ bail out for secure mode
> + tst r10, #1 << 11 @ bit #11 already set?
> + orreq r10, r10, #1 << 11 @ set bit #11 if not set
> + mcreq p15, 0, r10, c15, c0, 1 @ write diagnostic register
> 1:
> #endif
>
>
^ permalink raw reply
* [PATCH] ARM: OMAP4: PM: fix errata handling when CONFIG_PM=n
From: Kevin Hilman @ 2012-11-15 0:54 UTC (permalink / raw)
To: linux-arm-kernel
From: Kevin Hilman <khilman@ti.com>
commit c9621844 (ARM: OMAP4: PM: add errata support) introduced errata
handling for OMAP4, but was broken when CONFIG_PM=n.
When CONFIG_PM=n, pm44xx.c is not compiled, yet that is where pm44xx_errata
is defined. However, these errata are needed for the SMP boot/hotplug case
also, and are primarily used in omap-smp.c.
Move the definition of pm44xx_errata to omap-smp.c so that it's available
even in the CONFIG_PM=n case.
Cc: Tero Kristo <t-kristo@ti.com>
Signed-off-by: Kevin Hilman <khilman@ti.com>
---
This patch applies on top of Tony's fixes-non-critical-part-2.
The bug was introduced in my for_3.8-fixes-pm tag (now included in Tony's fixes-non-critical-part2.)
arch/arm/mach-omap2/omap-smp.c | 2 ++
arch/arm/mach-omap2/pm44xx.c | 1 -
2 files changed, 2 insertions(+), 1 deletion(-)
diff --git a/arch/arm/mach-omap2/omap-smp.c b/arch/arm/mach-omap2/omap-smp.c
index 49a08df..cd42d92 100644
--- a/arch/arm/mach-omap2/omap-smp.c
+++ b/arch/arm/mach-omap2/omap-smp.c
@@ -40,6 +40,8 @@
#define OMAP5_CORE_COUNT 0x2
+u16 pm44xx_errata;
+
/* SCU base address */
static void __iomem *scu_base;
diff --git a/arch/arm/mach-omap2/pm44xx.c b/arch/arm/mach-omap2/pm44xx.c
index 0adbd7d..04922d1 100644
--- a/arch/arm/mach-omap2/pm44xx.c
+++ b/arch/arm/mach-omap2/pm44xx.c
@@ -34,7 +34,6 @@ struct power_state {
};
static LIST_HEAD(pwrst_list);
-u16 pm44xx_errata;
#ifdef CONFIG_SUSPEND
static int omap4_pm_suspend(void)
--
1.8.0
^ permalink raw reply related
* [PATCH v3 4/4] ARM: OMAP: gpmc: add DT bindings for GPMC timings and NAND
From: Daniel Mack @ 2012-11-15 0:26 UTC (permalink / raw)
To: linux-arm-kernel
In-Reply-To: <509EA360.2050504@gmail.com>
On 11.11.2012 02:56, Daniel Mack wrote:
> On 07.11.2012 16:37, Philip, Avinash wrote:
>> On Wed, Nov 07, 2012 at 15:18:37, Daniel Mack wrote:
>>> On 05.11.2012 14:29, Philip, Avinash wrote:
>>>> On Mon, Nov 05, 2012 at 18:28:22, Daniel Mack wrote:
>>>>> On 05.11.2012 12:03, Philip, Avinash wrote:
>>>>>> On Fri, Nov 02, 2012 at 20:55:56, Daniel Mack wrote:
>>>>>>> This patch adds basic DT bindings for OMAP GPMC.
>>>>>>>
>>>>>>> The actual peripherals are instanciated from child nodes within the GPMC
>>>>>>> node, and the only type of device that is currently supported is NAND.
>>>>>>>
>>>>>>> Code was added to parse the generic GPMC timing parameters and some
>>>>>>> documentation with examples on how to use them.
>>>>>>>
>>>>>>> Successfully tested on an AM33xx board.
>>>>>>>
>>>>>>> Signed-off-by: Daniel Mack <zonque@gmail.com>
>>>>>> [...]
>>>>>>> +
>>>>>>> + nand at 0,0 {
>>>>>>> + reg = <0 0 0>; /* CS0, offset 0 */
>>>>>>> + nand-bus-width = <16>;
>>>>>>> + nand-ecc-mode = "none";
>>>>>>> +
>>>>>>> + gpmc,sync-clk = <0>;
>>>>>>> + gpmc,cs-on = <0>;
>>>>>>> + gpmc,cs-rd-off = <36>;
>>>>>>> + gpmc,cs-wr-off = <36>;
>>>>>>> + gpmc,adv-on = <6>;
>>>>>>> + gpmc,adv-rd-off = <24>;
>>>>>>> + gpmc,adv-wr-off = <36>;
>>>>>>> + gpmc,we-off = <30>;
>>>>>>> + gpmc,oe-off = <48>;
>>>>>>> + gpmc,access = <54>;
>>>>>>> + gpmc,rd-cycle = <72>;
>>>>>>> + gpmc,wr-cycle = <72>;
>>>>>>> + gpmc,wr-access = <30>;
>>>>>>> + gpmc,wr-data-mux-bus = <0>;
>>>>>>> +
>>>>>>> + #address-cells = <1>;
>>>>>>> + #size-cells = <1>;
>>>>>>> +
>>>>>>
>>>>>> Can you take the timings (for example) from arago tree. The timings is tested in am335x-evm
>>>>>> So the timings can be directly used to populate GPMC timings. Timings can found at
>>>>>>
>>>>>> http://arago-project.org/git/projects/?p=linux-am33x.git;a=commitdiff;
>>>>>> h=66bfbd2c5b35dc81edce0c24843c476161ab5978;hp=370630359cb8db711cf0941cd2a242e28ccfb61e
>>>>>>
>>>>>> [...]
>>>>>>> +static int gpmc_probe_dt(struct platform_device *pdev)
>>>>>>
>>>>>> Can you take care of the following section mismatch.
>>>>>> WARNING: vmlinux.o(.text+0x1e2d0): Section mismatch in reference
>>>>>> from the function gpmc_probe_dt() to the function .init.text:gpmc_nand_init().
>>>>>
>>>>> Sore, both fixed for v4.
>>>>>
>>>>>> [...]
>>>>>>> +
>>>>>>> + val = of_get_nand_ecc_mode(child);
>>>>>>> + if (val >= 0)
>>>>>>> + gpmc_nand_data->ecc_opt = val;
>>>>>>
>>>>>> This will fail for BCH. Index of "soft_bch" is 5 & also don't have selection
>>>>>> option between for BCH4 & BCH8 also.
>>>>>> Can you use the of_property_read_u32 (as done early) to pass the ecc selection
>>>>>> from dt file. This will help selection of BCH4 & BCH8 ecc options.
>>>>>
>>>>> Hmm. Shouldn't we rather teach of_get_nand_ecc_mode() that two modes and
>>>>> bring the enum in sync?
>>>>
>>>> ecc_opt is for selecting different ecc layout and not for selecting ecc mode.
>>>>
>>>> In omap2 driver NAND_ECC_HW ecc mode supports 3 ecc layout
>>>> OMAP_ECC_HAMMING_CODE_HW_ROMCODE
>>>> OMAP_ECC_BCH4_CODE_HW
>>>> OMAP_ECC_BCH8_CODE_HW
>>>>
>>>> So selection of ecc layout data should come from DT not ecc mode.
>>>
>>> Ok, I see. I would still like to set them by string rather than magic
>>> numbers that map to enum entries. Valid values would be "none", "hw",
>>> "hw-romcode", "bch4" and "bch8". Are you ok with that?
>>
>> Ok, that's nice. Better use ecc_opt instead of ecc_mode.
>
> I did some more extensive tests that include reading the same nand pages
> from both U-Boot and the kernel with BCH8 ECC, and it turns out that
> ->is_elm_used needs to be set in the pdata in order to make this work.
>
> So the question is whether we actually want to have a DT property for
> that or just always enable that bit in case a hardware supported ecc
> mode is selected. Any opinion on this?
>
> That's the last topic before I'm clear to send off v4.
Any opionion on this, anyone?
Thanks,
Daniel
^ permalink raw reply
* Kernel uncompression error
From: Woody Wu @ 2012-11-14 23:40 UTC (permalink / raw)
To: linux-arm-kernel
In-Reply-To: <20121114173453.GJ3290@n2100.arm.linux.org.uk>
2012-11-15 AM1:34?"Russell King - ARM Linux" <linux@arm.linux.org.uk>
>
> On Wed, Nov 14, 2012 at 10:23:55PM +0800, woody wrote:
> > I just built a 3.2.x ARM kernel and tried to have it boot by a boot
> > loader (vivi) on my s3c2410a ARM board. The kernel was built with
> > default configuration s3c2410.
>
> I reported that S3C2410 is totally dead with 3.x kernels about a month
> ago and got no response what so ever from anyone. I guess S3C2410 is
> just not cared for anymore.
>
> When I get sufficient motivation, I'll try and track down what's going
> wrong, but it means taking the old mailing list server (and now list
> archive) offline for a while.
>
> I don't think it's cache related; different image sizes seem to behave
> differently - and when they _do_ successfully decompress, they don't
> boot at all.
So, in your opinion, what version of kernel I should go for s3c2410?
BTW: what people are using after days of s4c2410? I can remember it's quit
popular at then.
-------------- next part --------------
An HTML attachment was scrubbed...
URL: <http://lists.infradead.org/pipermail/linux-arm-kernel/attachments/20121115/8944a2ea/attachment-0001.html>
^ permalink raw reply
* OMAP baseline test results for v3.7-rc5
From: Tony Lindgren @ 2012-11-14 23:36 UTC (permalink / raw)
To: linux-arm-kernel
In-Reply-To: <87obj1f0v8.fsf@deeprootsystems.com>
* Kevin Hilman <khilman@deeprootsystems.com> [121113 17:09]:
> Tony Lindgren <tony@atomide.com> writes:
> >
> > Here's one more booting issue I recently ran into:
> >
> > - If DEBUG_LL and earlyprintk are enabled, and omap-serial.c
> > is compiled as a module, the kernel boot hangs early as the
> > clocks for serial port are cut while earlyprintk still uses
> > the port. This might be regression from v3.6.
> >
>
> Can you test if the patch below[1] helps? With that, it seems to finish
> booting for me (based solely on a ping test.)
>
> The problem is a race between the late_initcall for omap_device (which
> idles devices that have no drivers) and the late_initcall in
> kernel/printk.c which turns off the earlyconsole. Any printks
> that happen between this omap_device late initcall and the earlyconsole
> late initcall will crash when accessing the UART.
Yeh that fixes it for me:
Tested-by: Tony Lindgren <tony@atomide.com>
> Kevin
>
> [1]
>
> diff --git a/arch/arm/plat-omap/omap_device.c b/arch/arm/plat-omap/omap_device.c
> index 7a7d1f2..138114a 100644
> --- a/arch/arm/plat-omap/omap_device.c
> +++ b/arch/arm/plat-omap/omap_device.c
> @@ -1275,4 +1275,4 @@ static int __init omap_device_late_init(void)
> bus_for_each_dev(&platform_bus_type, NULL, NULL, omap_device_late_idle);
> return 0;
> }
> -late_initcall(omap_device_late_init);
> +late_initcall_sync(omap_device_late_init);
^ permalink raw reply
* [PATCH v3 07/11] ARM: Exynos4: allow legacy board support to specify xxti and xusbxti clock speed
From: Tomasz Figa @ 2012-11-14 23:36 UTC (permalink / raw)
To: linux-arm-kernel
In-Reply-To: <1352930853-12268-8-git-send-email-thomas.abraham@linaro.org>
On Thursday 15 of November 2012 03:37:29 Thomas Abraham wrote:
> The clock speed of xxti and xusbxti clocks depends on the oscillator
> used on the board to generate these clocks. For non-dt platforms, allow
> the board support for those platforms to set the clock frequency of
> xxti and xusbxti clocks.
>
> Cc: Kukjin Kim <kgene.kim@samsung.com>
> Signed-off-by: Thomas Abraham <thomas.abraham@linaro.org>
> ---
> arch/arm/mach-exynos/common.c | 2 ++
> arch/arm/mach-exynos/common.h | 1 +
> arch/arm/mach-exynos/mach-nuri.c | 2 ++
> arch/arm/mach-exynos/mach-origen.c | 2 ++
> arch/arm/mach-exynos/mach-smdkv310.c | 2 ++
> arch/arm/mach-exynos/mach-universal_c210.c | 2 ++
> arch/arm/mach-exynos/mct.c | 1 +
> 7 files changed, 12 insertions(+), 0 deletions(-)
>
> diff --git a/arch/arm/mach-exynos/common.c
> b/arch/arm/mach-exynos/common.c index 138a41d..64c0012 100644
> --- a/arch/arm/mach-exynos/common.c
> +++ b/arch/arm/mach-exynos/common.c
> @@ -65,6 +65,8 @@ static void exynos5_init_clocks(int xtal);
> static void exynos4_init_uarts(struct s3c2410_uartcfg *cfg, int no);
> static int exynos_init(void);
>
> +unsigned long xxti_f = 0, xusbxti_f = 0;
> +
> static struct cpu_table cpu_ids[] __initdata = {
> {
> .idcode = EXYNOS4210_CPU_ID,
> diff --git a/arch/arm/mach-exynos/common.h
> b/arch/arm/mach-exynos/common.h index 2cacd48..f947789 100644
> --- a/arch/arm/mach-exynos/common.h
> +++ b/arch/arm/mach-exynos/common.h
> @@ -22,6 +22,7 @@ void exynos4_restart(char mode, const char *cmd);
> void exynos5_restart(char mode, const char *cmd);
> void exynos_init_late(void);
>
> +extern unsigned long xxti_f, xusbxti_f;
> void exynos4_clk_init(void);
> void exynos4_clk_register_fixed_ext(unsigned long, unsigned long);
>
> diff --git a/arch/arm/mach-exynos/mach-nuri.c
> b/arch/arm/mach-exynos/mach-nuri.c index 5b5c941..e14332c 100644
> --- a/arch/arm/mach-exynos/mach-nuri.c
> +++ b/arch/arm/mach-exynos/mach-nuri.c
> @@ -1332,6 +1332,8 @@ static void __init nuri_map_io(void)
> {
> exynos_init_io(NULL, 0);
> s3c24xx_init_uarts(nuri_uartcfgs, ARRAY_SIZE(nuri_uartcfgs));
> + xxti_f = 0;
> + xusbxti_f = 24000000;
I don't like setting these variables directly from board code.
If you didn't remove clock initialization call from board code, you could
extend that function to take these two frequencies as arguments?
> }
>
> static void __init nuri_reserve(void)
[snip]
> diff --git a/arch/arm/mach-exynos/mct.c b/arch/arm/mach-exynos/mct.c
> index c2e806c..cd061b2 100644
> --- a/arch/arm/mach-exynos/mct.c
> +++ b/arch/arm/mach-exynos/mct.c
> @@ -532,6 +532,7 @@ static void __init exynos4_timer_init(void)
> if (soc_is_exynos4210() || soc_is_exynos4212() ||
> soc_is_exynos4412()) {
> exynos4_clk_init();
> + exynos4_clk_register_fixed_ext(xxti_f, xusbxti_f);
I don't like registering clocks from unrelated code. IMHO any clock
registration should be done from code in drivers/clk/samsung.
Best regards,
Tomasz Figa
^ permalink raw reply
* [PATCH v3 04/11] ARM: Exynos4: Migrate clock support to common clock framework
From: Tomasz Figa @ 2012-11-14 23:31 UTC (permalink / raw)
To: linux-arm-kernel
In-Reply-To: <1352930853-12268-5-git-send-email-thomas.abraham@linaro.org>
On Thursday 15 of November 2012 03:37:26 Thomas Abraham wrote:
> Remove Samsung specific clock support in Exynos4 and migrate to use
> common clock framework.
>
> Cc: Kukjin Kim <kgene.kim@samsung.com>
> Signed-off-by: Thomas Abraham <thomas.abraham@linaro.org>
> ---
> arch/arm/mach-exynos/Kconfig | 1 +
> arch/arm/mach-exynos/Makefile | 3 -
> arch/arm/mach-exynos/clock-exynos4.c | 1602
> ---------------------------- arch/arm/mach-exynos/clock-exynos4.h
> | 35 -
> arch/arm/mach-exynos/clock-exynos4210.c | 188 ----
> arch/arm/mach-exynos/clock-exynos4212.c | 192 ----
> arch/arm/mach-exynos/common.c | 22 +-
> arch/arm/mach-exynos/common.h | 3 +
> arch/arm/mach-exynos/mach-armlex4210.c | 1 -
> arch/arm/mach-exynos/mach-exynos4-dt.c | 1 -
> arch/arm/mach-exynos/mach-nuri.c | 1 -
> arch/arm/mach-exynos/mach-origen.c | 1 -
> arch/arm/mach-exynos/mach-smdk4x12.c | 1 -
> arch/arm/mach-exynos/mach-smdkv310.c | 1 -
> arch/arm/mach-exynos/mach-universal_c210.c | 1 -
> arch/arm/mach-exynos/mct.c | 19 +
> arch/arm/plat-samsung/Kconfig | 4 +-
> 17 files changed, 27 insertions(+), 2049 deletions(-)
> delete mode 100644 arch/arm/mach-exynos/clock-exynos4.c
> delete mode 100644 arch/arm/mach-exynos/clock-exynos4.h
> delete mode 100644 arch/arm/mach-exynos/clock-exynos4210.c
> delete mode 100644 arch/arm/mach-exynos/clock-exynos4212.c
>
[snip]
> diff --git a/arch/arm/mach-exynos/mct.c b/arch/arm/mach-exynos/mct.c
> index f7792b8..c2e806c 100644
> --- a/arch/arm/mach-exynos/mct.c
> +++ b/arch/arm/mach-exynos/mct.c
> @@ -31,6 +31,7 @@
> #include <mach/map.h>
> #include <mach/irqs.h>
> #include <asm/mach/time.h>
> +#include "common.h"
>
> #define EXYNOS4_MCTREG(x) (x)
> #define EXYNOS4_MCT_G_CNT_L EXYNOS4_MCTREG(0x100)
> @@ -517,6 +518,24 @@ static void __init exynos4_timer_init(void)
> struct device_node *np;
> u32 nr_irqs, i;
>
> +#ifdef CONFIG_COMMON_CLK
> + /*
> + * Clock lookup should be functional now since the MCT controller
> driver + * looks up clocks. So the clock initialization is initiated
> here. + */
> + if (of_have_populated_dt()) {
> + if (of_machine_is_compatible("samsung,exynos4210") ||
> + of_machine_is_compatible("samsung,exynos4212") ||
> + of_machine_is_compatible("samsung,exynos4412"))
> + exynos4_clk_init();
> + } else {
> + if (soc_is_exynos4210() || soc_is_exynos4212() ||
> + soc_is_exynos4412()) {
> + exynos4_clk_init();
> + }
> + }
> +#endif
> +
I don't like the idea of initializing the clocks from timer
initialization. What about some platforms where MCT isn't used? It is also
far from being elegant.
Best regards,
Tomasz Figa
^ permalink raw reply
* [PATCH v3 05/11] ARM: dts: add exynos4 clock controller nodes
From: Tomasz Figa @ 2012-11-14 23:27 UTC (permalink / raw)
To: linux-arm-kernel
In-Reply-To: <1352930853-12268-6-git-send-email-thomas.abraham@linaro.org>
On Thursday 15 of November 2012 03:37:27 Thomas Abraham wrote:
> Add clock controller nodes for Exynos4210 and Exynos4x12 SoC's.
>
> Cc: Kukjin Kim <kgene.kim@samsung.com>
> Signed-off-by: Thomas Abraham <thomas.abraham@linaro.org>
> ---
> arch/arm/boot/dts/exynos4210.dtsi | 6 ++++++
> arch/arm/boot/dts/exynos4x12.dtsi | 6 ++++++
> 2 files changed, 12 insertions(+), 0 deletions(-)
>
> diff --git a/arch/arm/boot/dts/exynos4210.dtsi
> b/arch/arm/boot/dts/exynos4210.dtsi index d6fc306..f7daa09 100644
> --- a/arch/arm/boot/dts/exynos4210.dtsi
> +++ b/arch/arm/boot/dts/exynos4210.dtsi
> @@ -50,6 +50,12 @@
> samsung,mct-nr-local-irqs = <4>;
> };
>
> + clock: clock-controller at 0x10030000 {
> + compatible = "samsung,exynos4210-clock";
> + reg = <0x10030000 0x20000>;
> + #clock-cells = <1>;
> + };
> +
> pinctrl_0: pinctrl at 11400000 {
> compatible = "samsung,pinctrl-exynos4210";
> reg = <0x11400000 0x1000>;
> diff --git a/arch/arm/boot/dts/exynos4x12.dtsi
> b/arch/arm/boot/dts/exynos4x12.dtsi index 7cbbd19..bcfdaac 100644
> --- a/arch/arm/boot/dts/exynos4x12.dtsi
> +++ b/arch/arm/boot/dts/exynos4x12.dtsi
> @@ -35,6 +35,12 @@
> <0 16 0>, <0 17 0>, <0 18 0>, <0 19 0>;
> };
>
> + clock: clock-controller at 0x10030000 {
> + compatible = "samsung,exynos4412-clock";
nitpick: I forgot to mention about it in my comments for patch 3, but
wouldn't it be better to call it "samsung,exynos4x12-clock"?
> + reg = <0x10030000 0x20000>;
> + #clock-cells = <1>;
> + };
> +
> pinctrl_0: pinctrl at 11400000 {
> compatible = "samsung,pinctrl-exynos4x12";
> reg = <0x11400000 0x1000>;
Otherwise looks fine.
Best regards,
Tomasz Figa
^ permalink raw reply
* arch-vt8500 and wm8850 support
From: Arnd Bergmann @ 2012-11-14 23:26 UTC (permalink / raw)
To: linux-arm-kernel
In-Reply-To: <1352914966.3238.3.camel@gitbox>
On Wednesday 14 November 2012, Tony Prisk wrote:
> Makes sense - That's basically what I had in mind. My concern is with
> the bit that made no sense to me - the non-multiplatform version of the
> same. At the moment, we have the default xx_SINGLE for ARCH_VT8500.
> Would I need to add an additional xx_SINGLE variant for each different
> version?
I think either one option or two (v5 and v6/v7), but we don't need three
separate ones, as it should be possible to build v6 and v7 together.
> We would need ARCH_WM8505 (To cover VT8500/WM8505/WM8650 ARM926),
> ARCH_WM8750 (for ARMv6) and ARCH_WM8850 (for ARMv7).
Ah, right, I was mixing up the numbers.
> Do I need a ARCH_WM8750_SINGLE, ARCH_WM8850_SINGLE etc for each one to
> allow use to continue using earlyprintk?
You just need to ensure that we always set at least one of them, and
that ARCH_WM8505 isn't set at the same time as one of the v6/v7 parts.
Maybe something like
config ARCH_VT8500
bool
select FOO
select BAR
config ARCH_WM8505
bool "WonderMedia WM8505/WM8650 or VIA VT8500" if !ARCH_VT8500_SINGLE
depends on ARCH_MULTI_V5
default ARCH_VT8500_SINGLE
select ARCH_VT8500
select CPU_ARM926
config ARCH_WM8750
bool "WonderMedia WM 8750"
depends on ARCH_MULTI_V6 || ARCH_WM8750_SINGLE
select ARCH_VT8500
select CPU_V6
config ARCH_WM8850
bool "WonderMedia WM 8850/8950"
depends on ARCH_MULTI_V7 || ARCH_WM8750_SINGLE
select ARCH_VT8500
select CPU_V7
config ARCH_WM8850_AUTO
def_bool y
depends on ARCH_WM8750_SINGLE && !ARCH_WM8750
select ARCH_WM8850 # ensure that ARCH_WM8850 is on if ARCH_WM8750 is off
Arnd
^ permalink raw reply
* Decoding the PTM traces
From: Arve Hjønnevåg @ 2012-11-14 23:25 UTC (permalink / raw)
To: linux-arm-kernel
In-Reply-To: <CAKZGPAN-DEFD-X4az0O06ngjwdFAyrdowQ57QvtDpe8axZiwTg@mail.gmail.com>
On Wed, Nov 14, 2012 at 6:04 AM, Arun KS <arunks.linux@gmail.com> wrote:
> Hello,
>
> I m trying to capture and decode PTM trace from Cortex A9 dual core.
>
> I m successful in configuring the driver(arch/arm/kernel/etm.c) and
> setting the funnel to get data in ETB.
> But I don't know how to decode these traces.
>
> Anyone has any pointers?
>
> Thanks,
> Arun
I attached some tools I use to decode the traces. I have used this on
the A8, A9 and A15. I assume since you cc-ed me you have already
applied the kernel patches I posted a while back. Without them you
will not get useful trace data from a dual core processor.
--
Arve Hj?nnev?g
-------------- next part --------------
A non-text attachment was scrubbed...
Name: etm.c
Type: text/x-csrc
Size: 20847 bytes
Desc: not available
URL: <http://lists.infradead.org/pipermail/linux-arm-kernel/attachments/20121114/7058a281/attachment-0001.bin>
-------------- next part --------------
A non-text attachment was scrubbed...
Name: objdump.py
Type: application/octet-stream
Size: 6317 bytes
Desc: not available
URL: <http://lists.infradead.org/pipermail/linux-arm-kernel/attachments/20121114/7058a281/attachment-0002.obj>
-------------- next part --------------
A non-text attachment was scrubbed...
Name: etm-objdump.py
Type: application/octet-stream
Size: 6984 bytes
Desc: not available
URL: <http://lists.infradead.org/pipermail/linux-arm-kernel/attachments/20121114/7058a281/attachment-0003.obj>
^ permalink raw reply
* [PATCH v3 03/11] clk: exynos4: register clocks using common clock framework
From: Tomasz Figa @ 2012-11-14 23:24 UTC (permalink / raw)
To: linux-arm-kernel
In-Reply-To: <1352930853-12268-4-git-send-email-thomas.abraham@linaro.org>
Hi Thomas,
Looks mostly good, but I have some minor comments inline.
On Thursday 15 of November 2012 03:37:25 Thomas Abraham wrote:
> The Exynos4 clocks are statically listed and registered using the
> Samsung specific common clock helper functions. Both device tree based
> clock lookup and clkdev based clock lookups are supported.
>
> Cc: Mike Turquette <mturquette@linaro.org>
> Cc: Kukjin Kim <kgene.kim@samsung.com>
> Signed-off-by: Thomas Abraham <thomas.abraham@linaro.org>
> ---
> .../devicetree/bindings/clock/exynos4-clock.txt | 215 +++++++
> drivers/clk/samsung/Makefile | 1 +
> drivers/clk/samsung/clk-exynos4.c | 641
> ++++++++++++++++++++ 3 files changed, 857 insertions(+), 0 deletions(-)
> create mode 100644
> Documentation/devicetree/bindings/clock/exynos4-clock.txt create mode
> 100644 drivers/clk/samsung/clk-exynos4.c
>
> diff --git a/Documentation/devicetree/bindings/clock/exynos4-clock.txt
> b/Documentation/devicetree/bindings/clock/exynos4-clock.txt new file
> mode 100644
> index 0000000..e874add
> --- /dev/null
> +++ b/Documentation/devicetree/bindings/clock/exynos4-clock.txt
> @@ -0,0 +1,215 @@
> +* Samsung Exynos4 Clock Controller
> +
> +The Exynos4 clock controller generates and supplies clock to various
> controllers +within the Exynos4 SoC. The clock binding described here
> is applicable to all +SoC's in the Exynos4 family.
> +
> +Required Properties:
> +
> +- comptible: should be one of the following.
> + - "samsung,exynos4210-clock" - controller compatible with Exynos4210
> SoC. + - "samsung,exynos4412-clock" - controller compatible with
> Exynos4412 SoC. +
> +- reg: physical base address of the controller and length of memory
> mapped + region.
> +
> +- #clock-cells: should be 1.
> +
> +The following is the list of clocks generated by the controller. Each
> clock is +assigned an identifier and client nodes use this identifier
> to specify the +clock which they consume. Some of the clocks are
> available only on a particular +Exynos4 SoC and this is specified where
> applicable.
> +
> +
> + [Core Clocks]
> +
> + Clock ID SoC (if specific)
> + -----------------------------------------------
> +
> + xxti 1
> + xusbxti 2
> + fin_pll 3
> + fout_apll 4
> + fout_mpll 5
> + fout_epll 6
> + fout_vpll 7
> + sclk_apll 8
> + sclk_mpll 9
> + sclk_epll 10
> + sclk_vpll 11
> + arm_clk 12
> + aclk200 13
> + aclk100 14
> + aclk160 15
> + aclk133 16
> +
> +
> + [Clock Gate for Special Clocks]
> +
> + Clock ID SoC (if specific)
> + -----------------------------------------------
> +
> + sclk_fimc0 128
> + sclk_fimc1 129
> + sclk_fimc2 130
> + sclk_fimc3 131
> + sclk_cam0 132
> + sclk_cam1 133
> + sclk_csis0 134
> + sclk_csis1 135
> + sclk_hdmi 136
> + sclk_mixer 137
> + sclk_dac 138
> + sclk_pixel 139
> + sclk_fimd0 140
> + sclk_mdnie0 141 Exynos4412
> + sclk_mdnie_pwm0 12 142 Exynos4412
> + sclk_mipi0 143
> + sclk_audio0 144
> + sclk_mmc0 145
> + sclk_mmc1 146
> + sclk_mmc2 147
> + sclk_mmc3 148
> + sclk_mmc4 149
> + sclk_sata 150 Exynos4210
> + sclk_uart0 151
> + sclk_uart1 152
> + sclk_uart2 153
> + sclk_uart3 154
> + sclk_uart4 155
> + sclk_audio1 156
> + sclk_audio2 157
> + sclk_spdif 158
> + sclk_spi0 159
> + sclk_spi1 160
> + sclk_spi2 161
> + sclk_slimbus 162
> + sclk_fimd1 163 Exynos4210
> + sclk_mipi1 164 Exynos4210
> + sclk_pcm1 165
> + sclk_pcm2 166
> + sclk_i2s1 167
> + sclk_i2s2 168
> + sclk_mipihsi 169 Exynos4412
> +
> +
> + [Peripheral Clock Gates]
> +
> + Clock ID SoC (if specific)
> + -----------------------------------------------
> +
> + fimc0 256
> + fimc1 257
> + fimc2 258
> + fimc3 259
> + csis0 260
> + csis1 261
> + jpeg 262
> + smmu_fimc0 263
> + smmu_fimc1 264
> + smmu_fimc2 265
> + smmu_fimc3 266
> + smmu_jpeg 267
> + vp 268
> + mixer 269
> + tvenc 270 Exynos4210
> + hdmi 271
> + smmu_tv 272
> + mfc 273
> + smmu_mfcl 274
> + smmu_mfcr 275
> + g3d 276
> + g2d 277 Exynos4210
> + rotator 278 Exynos4210
> + mdma 279 Exynos4210
> + smmu_g2d 280 Exynos4210
> + smmu_rotator 281 Exynos4210
> + smmu_mdma 282 Exynos4210
> + fimd0 283
> + mie0 284
> + mdnie0 285 Exynos4412
> + dsim0 286
> + smmu_fimd0 287
> + fimd1 288 Exynos4210
> + mie1 289 Exynos4210
> + dsim1 290 Exynos4210
> + smmu_fimd1 291 Exynos4210
> + pdma0 292
> + pdma1 293
> + pcie_phy 294
> + sata_phy 295 Exynos4210
> + tsi 296
> + sdmmc0 297
> + sdmmc1 298
> + sdmmc2 299
> + sdmmc3 300
> + sdmmc4 301
> + sata 302 Exynos4210
> + sromc 303
> + usb_host 304
> + usb_device 305
> + pcie 306
> + onenand 307
> + nfcon 308
> + smmu_pcie 309
> + gps 310
> + smmu_gps 311
> + uart0 312
> + uart1 313
> + uart2 314
> + uart3 315
> + uart4 316
> + i2c0 317
> + i2c1 318
> + i2c2 319
> + i2c3 320
> + i2c4 321
> + i2c5 322
> + i2c6 323
> + i2c7 324
> + i2c_hdmi 325
> + tsadc 326
> + spi0 327
> + spi1 328
> + spi2 329
> + i2s1 330
> + i2s2 331
> + pcm0 332
> + i2s0 333
> + pcm1 334
> + pcm2 335
> + pwm 336
> + slimbus 337
> + spdif 338
> + ac97 339
> + modemif 340
> + chipid 341
> + sysreg 342
> + hdmi_cec 343
> + mct 344
> + wdt 345
> + rtc 346
> + keyif 347
> + audss 348
> + mipi_hsi 349 Exynos4210
> + mdma2 350 Exynos4210
I wonder what is the state of including the possibility of defining
constants in dts into dtc. Is it already merged?
If yes, maybe we could define all those constants instead of specifying
these raw numbers?
> +Example 1: An example of a clock controller node is listed below.
> +
> + clock: clock-controller at 0x10030000 {
> + compatible = "samsung,exynos4210-clock";
> + reg = <0x10030000 0x20000>;
> + #clock-cells = <1>;
> + };
> +
> +Example 2: UART controller node that consumes the clock generated by
> the clock + controller. Refer to the standard clock bindings for
> information + about 'clocks' and 'clock-names' property.
> +
> + serial at 13820000 {
> + compatible = "samsung,exynos4210-uart";
> + reg = <0x13820000 0x100>;
> + interrupts = <0 54 0>;
> + clocks = <&clock 314>, <&clock 153>;
> + clock-names = "uart", "clk_uart_baud0";
> + };
> diff --git a/drivers/clk/samsung/Makefile b/drivers/clk/samsung/Makefile
> index a5bf189..5d98904 100644
> --- a/drivers/clk/samsung/Makefile
> +++ b/drivers/clk/samsung/Makefile
> @@ -3,3 +3,4 @@
> #
>
> obj-$(CONFIG_PLAT_SAMSUNG) += clk.o clk-pll.o
> +obj-$(CONFIG_ARCH_EXYNOS4) += clk-exynos4.o
> diff --git a/drivers/clk/samsung/clk-exynos4.c
> b/drivers/clk/samsung/clk-exynos4.c new file mode 100644
> index 0000000..6f0b6a7
> --- /dev/null
> +++ b/drivers/clk/samsung/clk-exynos4.c
> @@ -0,0 +1,641 @@
> +/*
> + * Copyright (c) 2012 Samsung Electronics Co., Ltd.
> + * Copyright (c) 2012 Linaro Ltd.
> + * Author: Thomas Abraham <thomas.ab@samsung.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.
> + *
> + * Common Clock Framework support for all Exynos4 SoC's.
> +*/
> +
> +#include <linux/clk.h>
> +#include <linux/clkdev.h>
> +#include <linux/clk-provider.h>
> +#include <linux/of.h>
> +#include <linux/of_address.h>
> +
> +#include <plat/cpu.h>
> +#include "clk.h"
> +#include "clk-pll.h"
> +
> +/* the exynos4 soc type */
> +enum exynos4_soc {
> + EXYNOS4210,
> + EXYNOS4X12,
> +};
> +
> +/*
> + * Let each supported clock get a unique id. This id is used to lookup
> the clock + * for device tree based platforms. The clocks are
> categorized into three + * sections: core, sclk gate and bus interface
> gate clocks.
> + *
> + * When adding a new clock to this list, it is advised to choose a
> clock + * category and add it to the end of that category. That is
> because the the + * device tree source file is referring to these ids
> and any change in the + * sequence number of existing clocks will
> require corresponding change in the + * device tree files. This
> limitation would go away when pre-processor support + * for dtc would
> be available.
> + */
> +enum exynos4_clks {
> + none,
> +
> + /* core clocks */
> + xxti, xusbxti, fin_pll, fout_apll, fout_mpll, fout_epll, fout_vpll,
> + sclk_apll, sclk_mpll, sclk_epll, sclk_vpll, arm_clk, aclk200,
aclk100,
> + aclk160, aclk133,
> +
> + /* gate for special clocks (sclk) */
> + sclk_fimc0 = 128, sclk_fimc1, sclk_fimc2, sclk_fimc3, sclk_cam0,
> + sclk_cam1, sclk_csis0, sclk_csis1, sclk_hdmi, sclk_mixer, sclk_dac,
> + sclk_pixel, sclk_fimd0, sclk_mdnie0, sclk_mdnie_pwm0, sclk_mipi0,
> + sclk_audio0, sclk_mmc0, sclk_mmc1, sclk_mmc2, sclk_mmc3, sclk_mmc4,
> + sclk_sata, sclk_uart0, sclk_uart1, sclk_uart2, sclk_uart3,
sclk_uart4,
> + sclk_audio1, sclk_audio2, sclk_spdif, sclk_spi0, sclk_spi1,
> sclk_spi2, + sclk_slimbus, sclk_fimd1, sclk_mipi1, sclk_pcm1,
> sclk_pcm2, sclk_i2s1, + sclk_i2s2, sclk_mipihsi,
> +
> + /* gate clocks */
> + fimc0 = 256, fimc1, fimc2, fimc3, csis0, csis1, jpeg, smmu_fimc0,
> + smmu_fimc1, smmu_fimc2, smmu_fimc3, smmu_jpeg, vp, mixer, tvenc,
hdmi,
> + smmu_tv, mfc, smmu_mfcl, smmu_mfcr, g3d, g2d, rotator, mdma,
> smmu_g2d, + smmu_rotator, smmu_mdma, fimd0, mie0, mdnie0, dsim0,
> smmu_fimd0, fimd1, + mie1, dsim1, smmu_fimd1, pdma0, pdma1, pcie_phy,
> sata_phy, tsi, sdmmc0, + sdmmc1, sdmmc2, sdmmc3, sdmmc4, sata, sromc,
> usb_host, usb_device, pcie, + onenand, nfcon, smmu_pcie, gps,
smmu_gps,
> uart0, uart1, uart2, uart3, + uart4, i2c0, i2c1, i2c2, i2c3, i2c4,
> i2c5, i2c6, i2c7, i2c_hdmi, tsadc, + spi0, spi1, spi2, i2s1, i2s2,
> pcm0, i2s0, pcm1, pcm2, pwm, slimbus, + spdif, ac97, modemif,
chipid,
> sysreg, hdmi_cec, mct, wdt, rtc, keyif, + audss, mipi_hsi, mdma2,
> +
> + nr_clks,
> +};
> +/* list of all parent clock list */
> +PNAME(mout_apll_p) = { "fin_pll", "fout_apll", };
> +PNAME(mout_mpll_p) = { "fin_pll", "fout_mpll", };
> +PNAME(mout_epll_p) = { "fin_pll", "fout_epll", };
> +PNAME(mout_vpllsrc_p) = { "fin_pll", "sclk_hdmi24m", };
> +PNAME(sclk_vpll_p4210) = { "mout_vpllsrc", "fout_vpll", };
> +PNAME(mout_vpll_p) = { "fin_pll", "fout_vpll", };
> +PNAME(mout_core_p) = { "mout_apll", "sclk_mpll", };
> +PNAME(sclk_ampll_p) = { "sclk_mpll", "sclk_apll", };
> +PNAME(mout_mpll_user_p) = { "fin_pll", "sclk_mpll", };
> +PNAME(aclk_p4412) = { "mout_mpll_user", "sclk_apll", };
> +PNAME(sclk_evpll_p) = { "sclk_epll", "sclk_vpll", };
> +PNAME(mout_mfc_p) = { "mout_mfc0", "mout_mfc1", };
> +PNAME(mout_g3d_p) = { "mout_g3d0", "mout_g3d1", };
> +PNAME(mout_g2d_p) = { "mout_g2d0", "mout_g2d1", };
> +PNAME(mout_mixer_p4210) = { "sclk_dac", "sclk_hdmi", };
> +PNAME(mout_dac_p4210) = { "sclk_vpll", "sclk_hdmiphy", };
> +PNAME(mout_hdmi_p) = { "sclk_pixel", "sclk_hdmiphy", };
> +PNAME(mout_jpeg_p) = { "mout_jpeg0", "mout_jpeg1", };
> +PNAME(group1_p) = { "xxti", "xusbxti", "sclk_hdmi24m",
"sclk_usbphy0",
> + "none", "sclk_hdmiphy", "sclk_mpll",
> + "mout_epll", "mout_vpll", };
> +PNAME(mout_audio0_p) = { "cdclk0", "none", "sclk_hdmi24m",
> "sclk_usbphy0", + "xxti", "xusbxti", "sclk_mpll",
"sclk_epll",
> + "sclk_vpll" };
> +PNAME(mout_audio1_p) = { "cdclk1", "none", "sclk_hdmi24m",
> "sclk_usbphy0", + "xxti", "xusbxti", "sclk_mpll",
"mout_epll",
> + "mout_vpll", };
> +PNAME(mout_audio2_p) = { "cdclk2", "none", "sclk_hdmi24m",
> "sclk_usbphy0", + "xxti", "xusbxti", "sclk_mpll",
"mout_epll",
> + "mout_vpll", };
> +PNAME(mout_spdif_p) = { "sclk_audio0", "sclk_audio1", "sclk_audio2",
> + "spdif_extclk", };
> +
> +/* fixed rate clocks generated outside the soc */
> +struct samsung_fixed_rate_clock exynos4_fixed_rate_ext_clks[] = {
> + FRATE(xxti, "xxti", NULL, CLK_IS_ROOT, 0),
> + FRATE(xusbxti, "xusbxti", NULL, CLK_IS_ROOT, 0),
> +};
> +
> +/* fixed rate clocks generated inside the soc */
> +struct samsung_fixed_rate_clock exynos4_fixed_rate_clks[] = {
> + FRATE(none, "sclk_hdmi24m", NULL, CLK_IS_ROOT, 24000000),
> + FRATE(none, "sclk_hdmiphy", NULL, CLK_IS_ROOT, 27000000),
> + FRATE(none, "sclk_usbphy0", NULL, CLK_IS_ROOT, 48000000),
> +};
> +
> +struct samsung_fixed_rate_clock exynos4210_fixed_rate_clks[] = {
> + FRATE(none, "sclk_usbphy1", NULL, CLK_IS_ROOT, 48000000),
> +};
> +
> +/* list of mux clocks supported in all exynos4 soc's */
> +struct samsung_mux_clock exynos4_mux_clks[] = {
> + MUX(none, "mout_apll", mout_apll_p, 0x14200, 0, 1),
> + MUX(none, "mout_core", mout_core_p, 0x14200, 16, 1),
> + MUX_A(sclk_epll, "sclk_epll", mout_epll_p, 0xc210, 4, 1,
"sclk_epll"),
> + MUX(none, "mout_fimc0", group1_p, 0xc220, 0, 4),
> + MUX(none, "mout_fimc1", group1_p, 0xc220, 4, 4),
> + MUX(none, "mout_fimc2", group1_p, 0xc220, 8, 4),
> + MUX(none, "mout_fimc3", group1_p, 0xc220, 12, 4),
> + MUX(none, "mout_cam0", group1_p, 0xc220, 16, 4),
> + MUX(none, "mout_cam1", group1_p, 0xc220, 20, 4),
> + MUX(none, "mout_csis0", group1_p, 0xc220, 24, 4),
> + MUX(none, "mout_csis1", group1_p, 0xc220, 28, 4),
> + MUX(none, "mout_hdmi", mout_hdmi_p, 0xc224, 0, 1),
> + MUX(none, "mout_mfc0", sclk_ampll_p, 0xc228, 0, 1),
> + MUX(none, "mout_mfc1", sclk_evpll_p, 0xc228, 4, 1),
> + MUX(none, "mout_mfc", mout_mfc_p, 0xc228, 8, 1),
> + MUX(none, "mout_g3d0", sclk_ampll_p, 0xc22c, 0, 1),
> + MUX(none, "mout_g3d1", sclk_evpll_p, 0xc22c, 4, 1),
> + MUX(none, "mout_g3d", mout_g3d_p, 0xc22c, 8, 1),
> + MUX(none, "mout_fimd0", group1_p, 0xc234, 0, 4),
> + MUX(none, "mout_mipi0", group1_p, 0xc234, 12, 4),
> + MUX(none, "mout_audio0", mout_audio0_p, 0xc23c, 0, 4),
> + MUX(none, "mout_mmc0", group1_p, 0xc240, 0, 4),
> + MUX(none, "mout_mmc1", group1_p, 0xc240, 4, 4),
> + MUX(none, "mout_mmc2", group1_p, 0xc240, 8, 4),
> + MUX(none, "mout_mmc3", group1_p, 0xc240, 12, 4),
> + MUX(none, "mout_mmc4", group1_p, 0xc240, 16, 4),
> + MUX(none, "mout_uart0", group1_p, 0xc250, 0, 4),
> + MUX(none, "mout_uart1", group1_p, 0xc250, 4, 4),
> + MUX(none, "mout_uart2", group1_p, 0xc250, 8, 4),
> + MUX(none, "mout_uart3", group1_p, 0xc250, 12, 4),
> + MUX(none, "mout_uart4", group1_p, 0xc250, 16, 4),
> + MUX(none, "mout_audio1", mout_audio1_p, 0xc254, 0, 4),
> + MUX(none, "mout_audio2", mout_audio2_p, 0xc254, 4, 4),
> + MUX(none, "mout_spdif", mout_spdif_p, 0xc254, 8, 2),
> + MUX(none, "mout_spi0", group1_p, 0xc254, 16, 4),
> + MUX(none, "mout_spi1", group1_p, 0xc254, 20, 4),
> + MUX(none, "mout_spi2", group1_p, 0xc254, 24, 4),
> +};
> +
> +/* list of mux clocks supported in exynos4210 soc */
> +struct samsung_mux_clock exynos4210_mux_clks[] = {
> + MUX(none, "mout_aclk200", sclk_ampll_p, 0xc210, 12, 1),
> + MUX(none, "mout_aclk100", sclk_ampll_p, 0xc210, 16, 1),
> + MUX(none, "mout_aclk160", sclk_ampll_p, 0xc210, 20, 1),
> + MUX(none, "mout_aclk133", sclk_ampll_p, 0xc210, 24, 1),
> + MUX(none, "mout_vpllsrc", mout_vpllsrc_p, 0xc214, 0, 1),
> + MUX_A(sclk_mpll, "sclk_mpll", mout_mpll_p, 0x14200, 8, 1,
> "sclk_mpll"), + MUX_A(sclk_vpll, "sclk_vpll", sclk_vpll_p4210, 0xc210,
> 8, 1, "sclk_vpll"), + MUX(none, "mout_mixer", mout_mixer_p4210,
0xc224,
> 4, 1),
> + MUX(none, "mout_dac", mout_dac_p4210, 0xc224, 8, 1),
> + MUX(none, "mout_g2d0", sclk_ampll_p, 0xc230, 0, 1),
> + MUX(none, "mout_g2d1", sclk_evpll_p, 0xc230, 4, 1),
> + MUX(none, "mout_g2d", mout_g2d_p, 0xc230, 8, 1),
> + MUX(none, "mout_fimd1", group1_p, 0xc238, 0, 4),
> + MUX(none, "mout_mipi1", group1_p, 0xc238, 12, 4),
> +};
> +
> +/* list of mux clocks supported in exynos4x12 soc */
> +struct samsung_mux_clock exynos4x12_mux_clks[] = {
> + MUX_A(sclk_mpll, "sclk_mpll", mout_mpll_p, 0x10200, 12, 1,
> "sclk_mpll"), + MUX(none, "mout_mpll_user", mout_mpll_user_p, 0x4200,
> 4, 1), + MUX_A(sclk_vpll, "sclk_vpll", mout_vpll_p, 0xc210, 8, 1,
> "sclk_vpll"), + MUX(none, "mout_aclk200", aclk_p4412, 0xc210, 12, 1),
> + MUX(none, "mout_aclk100", aclk_p4412, 0xc210, 16, 1),
> + MUX(none, "mout_aclk160", aclk_p4412, 0xc210, 20, 1),
> + MUX(none, "mout_aclk133", aclk_p4412, 0xc210, 24, 1),
> + MUX(none, "mout_mdnie0", group1_p, 0xc234, 4, 4),
> + MUX(none, "mout_mdnie_pwm0", group1_p, 0xc234, 8, 4),
> + MUX(none, "mout_sata", sclk_ampll_p, 0xc240, 24, 1),
> + MUX(none, "mout_jpeg0", sclk_ampll_p, 0xc258, 0, 1),
> + MUX(none, "mout_jpeg1", sclk_evpll_p, 0xc258, 4, 1),
> + MUX(none, "mout_jpeg", mout_jpeg_p, 0xc258, 8, 1),
> +};
> +
> +/* list of divider clocks supported in all exynos4 soc's */
> +struct samsung_div_clock exynos4_div_clks[] = {
> + DIV_A(sclk_apll, "sclk_apll", "mout_apll", 0x14500, 24, 3,
> "sclk_apll"), + DIV(none, "div_core", "mout_core", 0x14500, 0, 3),
> + DIV(none, "div_core2", "div_core", 0x14500, 28, 3),
> + DIV_A(arm_clk, "arm_clk", "div_core2", 0x14500, 28, 3, "arm_clk"),
> + DIV(aclk200, "aclk200", "mout_aclk200", 0xc510, 0, 3),
> + DIV(aclk100, "aclk100", "mout_aclk100", 0xc510, 4, 4),
> + DIV(aclk160, "aclk160", "mout_aclk160", 0xc510, 8, 3),
> + DIV(aclk133, "aclk133", "mout_aclk133", 0xc510, 12, 3),
> + DIV(none, "div_fimc0", "mout_fimc0", 0xc520, 0, 4),
> + DIV(none, "div_fimc1", "mout_fimc1", 0xc520, 4, 4),
> + DIV(none, "div_fimc2", "mout_fimc2", 0xc520, 8, 4),
> + DIV(none, "div_fimc3", "mout_fimc3", 0xc520, 12, 4),
> + DIV(none, "div_cam0", "mout_cam0", 0xc520, 16, 4),
> + DIV(none, "div_cam1", "mout_cam1", 0xc520, 20, 4),
> + DIV(none, "div_csis0", "mout_csis0", 0xc520, 24, 4),
> + DIV(none, "div_csis1", "mout_csis1", 0xc520, 28, 4),
> + DIV(sclk_pixel, "sclk_pixel", "sclk_vpll", 0xc524, 0, 4),
> + DIV(none, "div_mfc", "mout_mfc", 0xc528, 0, 4),
> + DIV(none, "div_g3d", "mout_g3d", 0xc52c, 0, 4),
> + DIV(none, "div_fimd0", "mout_fimd0", 0xc534, 0, 4),
> + DIV(none, "div_mipi0", "mout_mipi0", 0xc534, 16, 4),
> + DIV(none, "div_mipi_pre0", "div_mipi0", 0xc534, 20, 4),
> + DIV(none, "div_audio0", "mout_audio0", 0xc53c, 0, 4),
> + DIV(none, "div_pcm0", "sclk_audio0", 0xc53c, 4, 8),
> + DIV(none, "div_mmc0", "mout_mmc0", 0xc544, 0, 4),
> + DIV(none, "div_mmc_pre0", "div_mmc0", 0xc544, 8, 8),
> + DIV(none, "div_mmc1", "mout_mmc1", 0xc544, 16, 4),
> + DIV(none, "div_mmc_pre1", "div_mmc1", 0xc544, 24, 8),
> + DIV(none, "div_mmc2", "mout_mmc2", 0xc548, 0, 4),
> + DIV(none, "div_mmc_pre2", "div_mmc2", 0xc548, 8, 8),
> + DIV(none, "div_mmc3", "mout_mmc3", 0xc548, 16, 4),
> + DIV(none, "div_mmc_pre3", "div_mmc3", 0xc548, 24, 8),
> + DIV(none, "div_mmc4", "mout_mmc4", 0xc54c, 0, 4),
> + DIV(none, "div_mmc_pre4", "div_mmc4", 0xc54c, 8, 8),
> + DIV(none, "div_uart0", "mout_uart0", 0xc550, 0, 4),
> + DIV(none, "div_uart1", "mout_uart1", 0xc550, 4, 4),
> + DIV(none, "div_uart2", "mout_uart2", 0xc550, 8, 4),
> + DIV(none, "div_uart3", "mout_uart3", 0xc550, 12, 4),
> + DIV(none, "div_uart4", "mout_uart4", 0xc550, 16, 4),
> + DIV(none, "div_spi0", "mout_spi0", 0xc554, 0, 4),
> + DIV(none, "div_spi_pre0", "div_spi0", 0xc554, 8, 8),
> + DIV(none, "div_spi1", "mout_spi1", 0xc554, 16, 4),
> + DIV(none, "div_spi_pre1", "div_spi1", 0xc554, 24, 8),
> + DIV(none, "div_spi2", "mout_spi2", 0xc558, 0, 4),
> + DIV(none, "div_spi_pre2", "div_spi2", 0xc558, 8, 8),
> + DIV(sclk_slimbus, "sclk_slimbus", "sclk_epll", 0xc55c, 4, 4),
> + DIV(none, "div_audio1", "mout_audio1", 0xc560, 0, 4),
> + DIV(sclk_pcm1, "sclk_pcm1", "sclk_audio1", 0xc560, 4, 8),
> + DIV(none, "div_audio2", "mout_audio2", 0xc560, 16, 4),
> + DIV(sclk_pcm2, "sclk_pcm2", "sclk_audio2", 0xc560, 20, 8),
> + DIV(sclk_i2s1, "sclk_i2s1", "sclk_audio1", 0xc564, 0, 6),
> + DIV(sclk_i2s2, "sclk_i2s2", "sclk_audio2", 0xc564, 8, 6),
> +};
> +
> +/* list of divider clocks supported in exynos4210 soc */
> +struct samsung_div_clock exynos4210_div_clks[] = {
> + DIV(none, "div_g2d", "mout_g2d", 0xc530, 0, 4),
> + DIV(none, "div_fimd1", "mout_fimd1", 0xc538, 0, 4),
> + DIV(none, "div_mipi1", "mout_mipi1", 0xc538, 16, 4),
> + DIV(none, "div_mipi_pre1", "div_mipi1", 0xc538, 20, 4),
> + DIV(none, "div_sata", "mout_sata", 0xc540, 20, 4),
> +};
> +
> +/* list of divider clocks supported in exynos4x12 soc */
> +struct samsung_div_clock exynos4x12_div_clks[] = {
> + DIV(none, "div_mdnie0", "mout_mdnie0", 0xc534, 4, 4),
> + DIV(none, "div_mdnie_pwm0", "mout_mdnie_pwm0", 0xc534, 8, 4),
> + DIV(none, "div_mdnie_pwm_pre0", "div_mdnie_pwm0", 0xc534, 12, 4),
> + DIV(none, "div_mipihsi", "mout_mipihsi", 0xc540, 20, 4),
> + DIV(none, "div_jpeg", "mout_jpeg", 0xc568, 0, 4),
> +};
> +
> +/* list of gate clocks supported in all exynos4 soc's */
> +struct samsung_gate_clock exynos4_gate_clks[] = {
> + /*
> + * After all Exynos4 based platforms are migrated to use device
tree,
> + * the device name and clock alias names specified below for some
> + * of the clocks can be removed.
> + */
> + GATE_DA(sclk_fimc0, "exynos4-fimc.0", "sclk_fimc0", "div_fimc0",
> + 0xc320, 0, CLK_SET_RATE_PARENT, 0, "sclk_fimc"),
> + GATE_DA(sclk_fimc1, "exynos4-fimc.1", "sclk_fimc1", "div_fimc1",
> + 0xc320, 4, CLK_SET_RATE_PARENT, 0, "sclk_fimc"),
> + GATE_DA(sclk_fimc2, "exynos4-fimc.2", "sclk_fimc2", "div_fimc2",
> + 0xc320, 8, CLK_SET_RATE_PARENT, 0, "sclk_fimc"),
> + GATE_DA(sclk_fimc3, "exynos4-fimc.3", "sclk_fimc3", "div_fimc3",
> + 0xc320, 12, CLK_SET_RATE_PARENT, 0, "sclk_fimc"),
> + GATE_DA(sclk_csis0, "s5p-mipi-csis.0", "sclk_csis0", "div_csis0",
> + 0xc320, 24, CLK_SET_RATE_PARENT, 0, "sclk_csis"),
> + GATE_DA(sclk_csis1, "s5p-mipi-csis.1", "sclk_csis1", "div_csis1",
> + 0xc320, 28, CLK_SET_RATE_PARENT, 0, "sclk_csis"),
> + GATE(sclk_hdmi, "sclk_hdmi", "mout_hdmi", 0xc324, 0, 0, 0),
> + GATE(sclk_mixer, "sclk_mixer", "mout_mixer", 0xc324, 4, 0, 0),
> + GATE(sclk_dac, "sclk_dac", "mout_dac", 0xc324, 8, 0, 0),
> + GATE_DA(sclk_fimd0, "exynos4-fb.0", "sclk_fimd0", "div_fimd0",
> + 0xc334, 0, CLK_SET_RATE_PARENT, 0, "sclk_fimd"),
> + GATE(sclk_mipi0, "sclk_mipi0", "div_mipi_pre0",
> + 0xc334, 12, CLK_SET_RATE_PARENT, 0),
> + GATE_DA(sclk_mmc0, "exynos4-sdhci.0", "sclk_mmc0", "div_mmc-pre0",
> + 0xc340, 0, CLK_SET_RATE_PARENT, 0, "mmc_busclk.2"),
> + GATE_DA(sclk_mmc1, "exynos4-sdhci.1", "sclk_mmc1", "div_mmc-pre1",
> + 0xc340, 4, CLK_SET_RATE_PARENT, 0, "mmc_busclk.2"),
> + GATE_DA(sclk_mmc2, "exynos4-sdhci.2", "sclk_mmc2", "div_mmc-pre2",
> + 0xc340, 8, CLK_SET_RATE_PARENT, 0, "mmc_busclk.2"),
> + GATE_DA(sclk_mmc3, "exynos4-sdhci.3", "sclk_mmc3", "div_mmc-pre3",
> + 0xc340, 12, CLK_SET_RATE_PARENT, 0, "mmc_busclk.2"),
> + GATE_DA(sclk_mmc4, NULL, "sclk_mmc4", "div_mmc-pre4",
> + 0xc340, 16, CLK_SET_RATE_PARENT, 0, "ciu"),
> + GATE_DA(sclk_uart0, "exynos4210-uart.0", "uclk0", "div_uart0",
> + 0xc350, 0, CLK_SET_RATE_PARENT, 0, "clk_uart_baud0"),
> + GATE_DA(sclk_uart1, "exynos4210-uart.1", "uclk1", "div_uart1",
> + 0xc350, 4, CLK_SET_RATE_PARENT, 0, "clk_uart_baud0"),
> + GATE_DA(sclk_uart2, "exynos4210-uart.2", "uclk2", "div_uart2",
> + 0xc350, 8, CLK_SET_RATE_PARENT, 0, "clk_uart_baud0"),
> + GATE_DA(sclk_uart3, "exynos4210-uart.3", "uclk3", "div_uart3",
> + 0xc350, 12, CLK_SET_RATE_PARENT, 0, "clk_uart_baud0"),
> + GATE_DA(sclk_uart4, "exynos4210-uart.4", "uclk4", "div_uart4",
> + 0xc350, 16, CLK_SET_RATE_PARENT, 0, "clk_uart_baud0"),
> + GATE(sclk_audio1, "sclk_audio1", "div_audio1", 0xc354, 0,
> CLK_SET_RATE_PARENT, 0), + GATE(sclk_audio2, "sclk_audio2",
> "div_audio2", 0xc354, 4, CLK_SET_RATE_PARENT, 0), + GATE(sclk_spdif,
> "sclk_spdif", "mout_spdif", 0xc354, 8, 0, 0), + GATE_DA(sclk_spi0,
> "exynos4210-spi.0", "sclk_spi0", "div_spi_pre0", +
0xc354, 16,
> CLK_SET_RATE_PARENT, 0, "spi_busclk0"),
> + GATE_DA(sclk_spi1, "exynos4210-spi.1", "sclk_spi1", "div_spi_pre1",
> + 0xc354, 20, CLK_SET_RATE_PARENT, 0, "spi_busclk0"),
> + GATE_DA(sclk_spi2, "exynos4210-spi.2", "sclk_spi2", "div_spi_pre2",
> + 0xc354, 24, CLK_SET_RATE_PARENT, 0, "spi_busclk0"),
> + GATE_DA(fimc0, "exynos4-fimc.0", "fimc0", "aclk160", 0xc920, 0, 0,
0,
> "fimc"), + GATE_DA(fimc1, "exynos4-fimc.1", "fimc1", "aclk160",
0xc920,
> 1, 0, 0, "fimc"), + GATE_DA(fimc2, "exynos4-fimc.2", "fimc2",
> "aclk160", 0xc920, 2, 0, 0, "fimc"), + GATE_DA(fimc3, "exynos4-
fimc.3",
> "fimc3", "aclk160", 0xc920, 3, 0, 0, "fimc"), + GATE_DA(csis0,
> "s5p-mipi-csis.0", "csis0", "aclk160", 0xc920, 4, 0, 0, "fimc"),
> + GATE_DA(csis1, "s5p-mipi-csis.1", "csis1", "aclk160", 0xc920, 5, 0,
> 0, "fimc"), + GATE(jpeg, "jpeg", "aclk160", 0xc920, 6, 0, 0),
> + GATE_DA(smmu_fimc0, "exynos-sysmmu.5", "smmu_fimc0", "aclk160",
> + 0xc920, 7, 0, 0, "sysmmu"),
> + GATE_DA(smmu_fimc1, "exynos-sysmmu.6", "smmu_fimc1", "aclk160",
> + 0xc920, 8, 0, 0, "sysmmu"),
> + GATE_DA(smmu_fimc2, "exynos-sysmmu.7", "smmu_fimc2", "aclk160",
> + 0xc920, 9, 0, 0, "sysmmu"),
> + GATE_DA(smmu_fimc3, "exynos-sysmmu.8", "smmu_fimc3", "aclk160",
> + 0xc920, 10, 0, 0, "sysmmu"),
> + GATE_DA(smmu_jpeg, "exynos-sysmmu.3", "smmu_jpeg", "aclk160",
0xc920,
> 11, 0, 0, "sysmmu"), + GATE_D(vp, "s5p-mixer", "vp", "aclk160",
0xc924,
> 0, 0, 0),
> + GATE_D(mixer, "s5p-mixer", "mixer", "aclk160", 0xc924, 1, 0, 0),
> + GATE_D(hdmi, "exynos4-hdmi", "hdmi", "aclk160", 0xc924, 3, 0, 0),
> + GATE_DA(smmu_tv, "exynos-sysmmu.2", "smmu_tv", "aclk160", 0xc924, 4,
> 0, 0, "sysmmu"), + GATE_DA(mfc, "s5p-mfc", "mfc", "aclk100", 0xc928,
0,
> 0, 0, "mfc"), + GATE_DA(smmu_mfcl, "exynos-sysmmu.0", "smmu_mfcl",
> "aclk100", 0xc928, 1, 0, 0, "sysmmu"), + GATE_DA(smmu_mfcr,
> "exynos-sysmmu.1", "smmu_mfcr", "aclk100", 0xc928, 2, 0, 0, "sysmmu"),
> + GATE(g3d, "g3d", "aclk200", 0xc92c, 0, 0, 0),
> + GATE_DA(fimd0, "exynos4-fb.0", "fimd0", "aclk160", 0xc934, 0, 0, 0,
> "fimd"), + GATE(mie0, "mie0", "aclk160", 0xc934, 1, 0, 0),
> + GATE(dsim0, "dsim0", "aclk160", 0xc934, 3, 0, 0),
> + GATE_DA(smmu_fimd0, "exynos-sysmmu.10", "smmu_fimd0", "aclk160",
> + 0xc934, 4, 0, 0, "sysmmu"),
> + GATE(fimd1, "fimd1", "aclk160", 0xc938, 0, 0, 0),
> + GATE(mie1, "mie1", "aclk160", 0xc938, 1, 0, 0),
> + GATE(dsim1, "dsim1", "aclk160", 0xc938, 3, 0, 0),
> + GATE(smmu_fimd1, "smmu_fimd1", "aclk160", 0xc938, 4, 0, 0),
> + GATE_DA(pdma0, "dma-pl330.0", "pdma0", "aclk133", 0xc940, 0, 0, 0,
> "dma"), + GATE_DA(pdma1, "dma-pl330.1", "pdma1", "aclk133", 0xc940, 1,
> 0, 0, "dma"), + GATE(tsi, "tsi", "aclk133", 0xc940, 4, 0, 0),
> + GATE_DA(sdmmc0, "exynos4-sdhci.0", "sdmmc0", "aclk133", 0xc940, 5,
0,
> 0, "hsmmc"), + GATE_DA(sdmmc1, "exynos4-sdhci.1", "sdmmc1", "aclk133",
> 0xc940, 6, 0, 0, "hsmmc"), + GATE_DA(sdmmc2, "exynos4-sdhci.2",
> "sdmmc2", "aclk133", 0xc940, 7, 0, 0, "hsmmc"), + GATE_DA(sdmmc3,
> "exynos4-sdhci.3", "sdmmc3", "aclk133", 0xc940, 8, 0, 0, "hsmmc"),
> + GATE_A(sdmmc4, "sdmmc4", "aclk133", 0xc940, 9, 0, 0, "biu"),
> + GATE(sromc, "sromc", "aclk133", 0xc940, 11, 0, 0),
> + GATE_A(usb_host, "usb_host", "aclk133", 0xc940, 12, 0, 0,
"usbhost"),
> + GATE(usb_device, "usb_device", "aclk133", 0xc940, 13, 0, 0),
> + GATE(onenand, "onenand", "aclk133", 0xc940, 15, 0, 0),
> + GATE(nfcon, "nfcon", "aclk133", 0xc940, 16, 0, 0),
> + GATE(gps, "gps", "aclk133", 0xc94c, 0, 0, 0),
> + GATE(smmu_gps, "smmu_gps", "aclk133", 0xc94c, 1, 0, 0),
> + GATE_DA(uart0, "exynos4210-uart.0", "uart0", "aclk100", 0xc950, 0,
0,
> 0, "uart"), + GATE_DA(uart1, "exynos4210-uart.1", "uart1", "aclk100",
> 0xc950, 1, 0, 0, "uart"), + GATE_DA(uart2, "exynos4210-uart.2",
> "uart2", "aclk100", 0xc950, 2, 0, 0, "uart"), + GATE_DA(uart3,
> "exynos4210-uart.3", "uart3", "aclk100", 0xc950, 3, 0, 0, "uart"),
> + GATE_DA(uart4, "exynos4210-uart.4", "uart4", "aclk100", 0xc950, 4,
0,
> 0, "uart"), + GATE_DA(i2c0, "s3c2440-i2c.0", "i2c0", "aclk100", 0xc950,
> 6, 0, 0, "i2c"), + GATE_DA(i2c1, "s3c2440-i2c.1", "i2c1", "aclk100",
> 0xc950, 7, 0, 0, "i2c"), + GATE_DA(i2c2, "s3c2440-i2c.2", "i2c2",
> "aclk100", 0xc950, 8, 0, 0, "i2c"), + GATE_DA(i2c3, "s3c2440-i2c.3",
> "i2c3", "aclk100", 0xc950, 9, 0, 0, "i2c"), + GATE_DA(i2c4,
> "s3c2440-i2c.4", "i2c4", "aclk100", 0xc950, 10, 0, 0, "i2c"),
> + GATE_DA(i2c5, "s3c2440-i2c.5", "i2c5", "aclk100", 0xc950, 11, 0, 0,
> "i2c"), + GATE_DA(i2c6, "s3c2440-i2c.6", "i2c6", "aclk100", 0xc950, 12,
> 0, 0, "i2c"), + GATE_DA(i2c7, "s3c2440-i2c.7", "i2c7", "aclk100",
> 0xc950, 13, 0, 0, "i2c"), + GATE_DA(i2c_hdmi, "s3c2440-hdmiphy-i2c",
> "i2c-hdmi", "aclk100", 0xc950, 14, 0, 0, "i2c"), + GATE_DA(spi0,
> "exynos4210-spi.0", "spi0", "aclk100", 0xc950, 16, 0, 0, "spi"),
> + GATE_DA(spi1, "exynos4210-spi.1", "spi1", "aclk100", 0xc950, 17, 0,
> 0, "spi"), + GATE_DA(spi2, "exynos4210-spi.2", "spi2", "aclk100",
> 0xc950, 18, 0, 0, "spi"), + GATE_DA(i2s1, "samsung-i2s.1", "i2s1",
> "aclk100", 0xc950, 20, 0, 0, "iis"), + GATE_DA(i2s2, "samsung-
i2s.2",
> "i2s2", "aclk100", 0xc950, 21, 0, 0, "iis"), + GATE_DA(pcm1,
> "samsung-pcm.1", "pcm1", "aclk100", 0xc950, 22, 0, 0, "pcm"),
> + GATE_DA(pcm2, "samsung-pcm.2", "pcm2", "aclk100", 0xc950, 23, 0, 0,
> "pcm"), + GATE_A(pwm, "pwm", "aclk100", 0xc950, 24, 0, 0, "timers"),
> + GATE(slimbus, "slimbus", "aclk100", 0xc950, 25, 0, 0),
> + GATE_DA(spdif, "samsung-spdif", "spdif", "aclk100", 0xc950, 26, 0,
0,
> "spdif"), + GATE_DA(ac97, "samsung-ac97", "ac97", "aclk100", 0xc950,
> 27, 0, 0, "ac97"), +};
> +
> +/* list of gate clocks supported in exynos4210 soc */
> +struct samsung_gate_clock exynos4210_gate_clks[] = {
> + GATE_DA(sclk_fimd1, "exynos4-fb.1", "sclk_fimd1", "div_fimd1",
> + 0xc338, 0, CLK_SET_RATE_PARENT, 0, "sclk_fimd"),
> + GATE(sclk_mipi1, "sclk_mipi1", "div_mipi_pre1", 0xc338, 12,
> CLK_SET_RATE_PARENT, 0), + GATE(sclk_sata, "sclk_sata", "div_sata",
> 0xc340, 24, CLK_SET_RATE_PARENT, 0), + GATE(sclk_cam0, "sclk_cam0",
> "div_cam0", 0xc820, 4, CLK_SET_RATE_PARENT, 0), + GATE(sclk_cam1,
> "sclk_cam1", "div_cam1", 0xc820, 5, CLK_SET_RATE_PARENT, 0),
> + GATE(tvenc, "tvenc", "aclk160", 0xc924, 2, 0, 0),
> + GATE(g2d, "g2d", "aclk200", 0xc930, 0, 0, 0),
> + GATE(rotator, "rotator", "aclk200", 0xc930, 1, 0, 0),
> + GATE(mdma, "mdma", "aclk200", 0xc930, 2, 0, 0),
> + GATE(smmu_g2d, "smmu_g2d", "aclk200", 0xc930, 3, 0, 0),
> + GATE(smmu_rotator, "smmu_rotator", "aclk200", 0xc930, 4, 0, 0),
> + GATE(smmu_mdma, "smmu_mdma", "aclk200", 0xc930, 5, 0, 0),
> + GATE(pcie_phy, "pcie_phy", "aclk133", 0xc940, 2, 0, 0),
> + GATE(sata_phy, "sata_phy", "aclk133", 0xc940, 3, 0, 0),
> + GATE(sata, "sata", "aclk133", 0xc940, 10, 0, 0),
> + GATE(pcie, "pcie", "aclk133", 0xc940, 14, 0, 0),
> + GATE(smmu_pcie, "smmu_pcie", "aclk133", 0xc940, 18, 0, 0),
> + GATE_A(tsadc, "tsadc", "aclk100", 0xc950, 15, 0, 0, "adc"),
> + GATE(modemif, "modemif", "aclk100", 0xc950, 28, 0, 0),
> + GATE(chipid, "chipid", "aclk100", 0xc960, 0, 0, 0),
> + GATE(sysreg, "sysreg", "aclk100", 0xc960, 0, 0, 0),
> + GATE(hdmi_cec, "hdmi_cec", "aclk100", 0xc960, 11, 0, 0),
> + GATE_A(mct, "mct", "aclk100", 0xc960, 13, 0, 0, "mct"),
> + GATE_A(wdt, "watchdog", "aclk100", 0xc960, 14, 0, 0, "watchdog"),
> + GATE_A(rtc, "rtc", "aclk100", 0xc960, 15, 0, 0, "rtc"),
> + GATE_A(keyif, "keyif", "aclk100", 0xc960, 16, 0, 0, "keypad"),
> +};
> +
> +/* list of gate clocks supported in exynos4x12 soc */
> +struct samsung_gate_clock exynos4x12_gate_clks[] = {
> + GATE(sclk_mdnie0, "sclk_mdnie0", "div_mdnie0", 0xc334, 4,
> CLK_SET_RATE_PARENT, 0), + GATE(sclk_mdnie_pwm0, "sclk_mdnie_pwm0",
> "div_mdnie_pwm_pre0", + 0xc334, 8, CLK_SET_RATE_PARENT,
0),
> + GATE(sclk_mipihsi, "sclk_mipihsi", "div_mipihsi", 0xc340, 24,
> CLK_SET_RATE_PARENT, 0), + GATE(audss, "audss", "sclk_epll", 0xc93c, 0,
> 0, 0),
> + GATE(mdnie0, "mdnie0", "aclk160", 0xc934, 2, 0, 0),
> + GATE_DA(pcm0, "samsung-pcm.0", "pcm0", "aclk100", 0xc93c, 2, 0, 0,
> "pcm"), + GATE_DA(i2s0, "samsung-i2s.0", "i2s0", "aclk100", 0xc93c, 3,
> 0, 0, "iis"), + GATE(mipi_hsi, "mipi_hsi", "aclk133", 0xc940, 10, 0,
> 0),
> + GATE(chipid, "chipid", "aclk100", 0x8960, 0, 0, 0),
> + GATE(sysreg, "sysreg", "aclk100", 0x8960, 1, 0, 0),
> + GATE(hdmi_cec, "hdmi_cec", "aclk100", 0x8960, 11, 0, 0),
> + GATE_A(mct, "mct", "aclk100", 0x8960, 13, 0, 0, "mct"),
> + GATE_A(wdt, "watchdog", "aclk100", 0x8960, 14, 0, 0, "watchdog"),
> + GATE_A(rtc, "rtc", "aclk100", 0x8960, 15, 0, 0, "rtc"),
> + GATE_A(keyif, "keyif", "aclk100", 0x8960, 16, 0, 0, "keypad"),
> + GATE(rotator, "rotator", "aclk200", 0x4930, 1, 0, 0),
> + GATE(mdma2, "mdma2", "aclk200", 0x4930, 2, 0, 0),
> + GATE(smmu_rotator, "smmu_rotator", "aclk200", 0x4930, 4, 0, 0),
> + GATE(smmu_mdma, "smmu_mdma", "aclk200", 0x4930, 5, 0, 0),
> +};
> +
> +static struct of_device_id exynos4_clk_ids[] = {
> + { .compatible = "samsung,exynos4210-clock",
> + .data = (void *)EXYNOS4210, },
> + { .compatible = "samsung,exynos4412-clock",
> + .data = (void *)EXYNOS4X12, },
> + { },
> +};
I wonder if most of these static arrays couldn't be marked as initdata to
be dropped after initialization.
Correct me if I'm wrong, but from what I see these data are referenced by
common clock framework core only when registering these clocks.
Best regards,
Tomasz Figa
^ permalink raw reply
* [PATCH v3 01/11] clk: samsung: add common clock framework helper functions for Samsung platforms
From: Tomasz Figa @ 2012-11-14 23:12 UTC (permalink / raw)
To: linux-arm-kernel
In-Reply-To: <1352930853-12268-2-git-send-email-thomas.abraham@linaro.org>
Hi Thomas,
Looks mostly good, but I have some minor comments inline.
On Thursday 15 of November 2012 03:37:23 Thomas Abraham wrote:
> All Samsung platforms include different types of clock including
> fixed-rate, mux, divider and gate clock types. There are typically
> hundreds of such clocks on each of the Samsung platforms. To enable
> Samsung platforms to register these clocks using the common clock
> framework, a bunch of utility functions are introduced here which
> simplify the clock registration process. The clocks are usually
> statically instantiated and registered with common clock framework.
>
> Cc: Mike Turquette <mturquette@linaro.org>
> Cc: Kukjin Kim <kgene.kim@samsung.com>
> Signed-off-by: Thomas Abraham <thomas.abraham@linaro.org>
> ---
> drivers/clk/Makefile | 1 +
> drivers/clk/samsung/Makefile | 5 +
> drivers/clk/samsung/clk.c | 176 ++++++++++++++++++++++++++++++++++
> drivers/clk/samsung/clk.h | 218
> ++++++++++++++++++++++++++++++++++++++++++ 4 files changed, 400
> insertions(+), 0 deletions(-)
> create mode 100644 drivers/clk/samsung/Makefile
> create mode 100644 drivers/clk/samsung/clk.c
> create mode 100644 drivers/clk/samsung/clk.h
>
> diff --git a/drivers/clk/Makefile b/drivers/clk/Makefile
> index 2701235..808f8e1 100644
> --- a/drivers/clk/Makefile
> +++ b/drivers/clk/Makefile
> @@ -19,6 +19,7 @@ endif
> obj-$(CONFIG_MACH_LOONGSON1) += clk-ls1x.o
> obj-$(CONFIG_ARCH_U8500) += ux500/
> obj-$(CONFIG_ARCH_VT8500) += clk-vt8500.o
> +obj-$(CONFIG_PLAT_SAMSUNG) += samsung/
>
> # Chip specific
> obj-$(CONFIG_COMMON_CLK_WM831X) += clk-wm831x.o
> diff --git a/drivers/clk/samsung/Makefile b/drivers/clk/samsung/Makefile
> new file mode 100644
> index 0000000..3f926b0
> --- /dev/null
> +++ b/drivers/clk/samsung/Makefile
> @@ -0,0 +1,5 @@
> +#
> +# Samsung Clock specific Makefile
> +#
> +
> +obj-$(CONFIG_PLAT_SAMSUNG) += clk.o
> diff --git a/drivers/clk/samsung/clk.c b/drivers/clk/samsung/clk.c
> new file mode 100644
> index 0000000..ebc6fb6
> --- /dev/null
> +++ b/drivers/clk/samsung/clk.c
> @@ -0,0 +1,176 @@
> +/*
> + * Copyright (c) 2012 Samsung Electronics Co., Ltd.
> + * Copyright (c) 2012 Linaro Ltd.
> + * Author: Thomas Abraham <thomas.ab@samsung.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.
> + *
> + * This file includes utility functions to register clocks to common
> + * clock framework for Samsung platforms.
> +*/
> +
> +#include "clk.h"
> +
> +static DEFINE_SPINLOCK(lock);
> +static struct clk **clk_table;
> +static struct clk_onecell_data clk_data;
> +void __iomem *reg_base;
Shouldn't it be static?
> +
> +/* setup the essentials required to support clock lookup using ccf */
> +void __init samsung_clk_init(struct device_node *np, void __iomem
> *base, + unsigned long nr_clks)
> +{
> + reg_base = base;
> + if (!np)
> + return;
> +
> + clk_table = kzalloc(sizeof(struct clk *) * nr_clks, GFP_KERNEL);
> + if (!clk_table)
> + panic("could not allocate clock lookup table\n");
> +
> + clk_data.clks = clk_table;
> + clk_data.clk_num = nr_clks;
> + of_clk_add_provider(np, of_clk_src_onecell_get, &clk_data);
> +}
> +
> +/* add a clock instance to the clock lookup table used for dt based
> lookup */ +void samsung_clk_add_lookup(struct clk *clk, unsigned int
> id) +{
> + if (clk_table && id)
I'm not sure if we really need this kind of checks, but if we do, then
shouldn't we also check id against clk_data.clk_num to prevent out of
bound index?
> + clk_table[id] = clk;
> +}
> +
> +/* register a list of fixed clocks */
> +void __init samsung_clk_register_fixed_rate(
> + struct samsung_fixed_rate_clock *list, unsigned int nr_clk)
> +{
> + struct clk *clk;
> + unsigned int idx, ret;
> +
> + for (idx = 0; idx < nr_clk; idx++, list++) {
> + clk = clk_register_fixed_rate(NULL, list->name,
> + list->parent_name, list->flags, list->fixed_rate);
> + if (IS_ERR(clk)) {
> + pr_err("%s: failed to register clock %s\n", __func__,
> + list->name);
> + continue;
> + }
> +
> + samsung_clk_add_lookup(clk, list->id);
> +
> + /*
> + * Unconditionally add a clock lookup for the fixed rate
clocks.
> + * There are not many of these on any of Samsung platforms.
> + */
> + ret = clk_register_clkdev(clk, list->name, NULL);
> + if (ret)
> + pr_err("%s: failed to register clock lookup for %s",
> + __func__, list->name);
> + }
> +}
> +
> +/* register a list of mux clocks */
> +void __init samsung_clk_register_mux(struct samsung_mux_clock *list,
> + unsigned int nr_clk)
> +{
> + struct clk *clk;
> + unsigned int idx, ret;
> +
> + for (idx = 0; idx < nr_clk; idx++, list++) {
> + clk = clk_register_mux(NULL, list->name, list->parent_names,
> + list->num_parents, list->flags, reg_base + list->offset,
> + list->shift, list->width, list->mux_flags, &lock);
> + if (IS_ERR(clk)) {
> + pr_err("%s: failed to register clock %s\n", __func__,
> + list->name);
> + continue;
> + }
> +
> + samsung_clk_add_lookup(clk, list->id);
> +
> + /* register a clock lookup only if a clock alias is specified
*/
> + if (list->alias) {
> + ret = clk_register_clkdev(clk, list->alias,
> + list->dev_name);
> + if (ret)
> + pr_err("%s: failed to register lookup %s\n",
> + __func__, list->alias);
> + }
> + }
> +}
> +
> +/* register a list of div clocks */
> +void __init samsung_clk_register_div(struct samsung_div_clock *list,
> + unsigned int nr_clk)
> +{
> + struct clk *clk;
> + unsigned int idx, ret;
> +
> + for (idx = 0; idx < nr_clk; idx++, list++) {
> + clk = clk_register_divider(NULL, list->name, list-
>parent_name,
> + list->flags, reg_base + list->offset, list->shift,
> + list->width, list->div_flags, &lock);
> + if (IS_ERR(clk)) {
> + pr_err("clock: failed to register clock %s\n",
> + list->name);
> + continue;
> + }
> +
> + samsung_clk_add_lookup(clk, list->id);
> +
> + /* register a clock lookup only if a clock alias is specified
*/
> + if (list->alias) {
> + ret = clk_register_clkdev(clk, list->alias,
> + list->dev_name);
> + if (ret)
> + pr_err("%s: failed to register lookup %s\n",
> + __func__, list->alias);
> + }
> + }
> +}
> +
> +/* register a list of gate clocks */
> +void __init samsung_clk_register_gate(struct samsung_gate_clock *list,
> + unsigned int nr_clk)
> +{
> + struct clk *clk;
> + unsigned int idx, ret;
> +
> + for (idx = 0; idx < nr_clk; idx++, list++) {
> + clk = clk_register_gate(NULL, list->name, list->parent_name,
> + list->flags, reg_base + list->offset,
> + list->bit_idx, list->gate_flags, &lock);
> + if (IS_ERR(clk)) {
> + pr_err("clock: failed to register clock %s\n",
> + list->name);
> + continue;
> + }
> +
> + /* register a clock lookup only if a clock alias is specified
*/
> + if (list->alias) {
> + ret = clk_register_clkdev(clk, list->alias,
> + list->dev_name);
> + if (ret)
> + pr_err("%s: failed to register lookup %s\n",
> + __func__, list->alias);
> + }
> +
> + samsung_clk_add_lookup(clk, list->id);
> + }
> +}
> +
> +/* utility function to get the rate of a specified clock */
> +unsigned long _get_rate(const char *clk_name)
> +{
> + struct clk *clk;
> + unsigned long rate;
> +
> + clk = clk_get(NULL, clk_name);
> + if (IS_ERR(clk))
> + return 0;
> + rate = clk_get_rate(clk);
> + clk_put(clk);
> + return rate;
> +}
> diff --git a/drivers/clk/samsung/clk.h b/drivers/clk/samsung/clk.h
> new file mode 100644
> index 0000000..ab43498
> --- /dev/null
> +++ b/drivers/clk/samsung/clk.h
> @@ -0,0 +1,218 @@
> +/*
> + * Copyright (c) 2012 Samsung Electronics Co., Ltd.
> + * Copyright (c) 2012 Linaro Ltd.
> + * Author: Thomas Abraham <thomas.ab@samsung.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.
> + *
> + * Common Clock Framework support for all Samsung platforms
> +*/
> +
> +#ifndef __SAMSUNG_CLK_H
> +#define __SAMSUNG_CLK_H
> +
> +#include <linux/clk.h>
> +#include <linux/clkdev.h>
> +#include <linux/io.h>
> +#include <linux/clk-provider.h>
> +#include <linux/of.h>
> +#include <linux/of_address.h>
> +
> +#include <mach/map.h>
> +
> +/**
> + * struct samsung_fixed_rate_clock: information about fixed-rate clock
> + * @id: platform specific id of the clock.
> + * @name: name of this fixed-rate clock.
> + * @parent_name: optional parent clock name.
> + * @flags: optional fixed-rate clock flags.
> + * @fixed-rate: fixed clock rate of this clock.
> + */
> +struct samsung_fixed_rate_clock {
> + unsigned int id;
> + char *name;
Shouldn't it be const char *name?
> + const char *parent_name;
> + unsigned long flags;
> + unsigned long fixed_rate;
> +};
> +
> +#define FRATE(_id, cname, pname, f, frate) \
> + { \
> + .id = _id, \
> + .name = cname, \
> + .parent_name = pname, \
> + .flags = f, \
> + .fixed_rate = frate, \
> + }
> +
> +/**
> + * struct samsung_mux_clock: information about mux clock
> + * @id: platform specific id of the clock.
> + * @dev_name: name of the device to which this clock belongs.
> + * @name: name of this mux clock.
> + * @parent_names: array of pointer to parent clock names.
> + * @num_parents: number of parents listed in @parent_names.
> + * @flags: optional flags for basic clock.
> + * @offset: offset of the register for configuring the mux.
> + * @shift: starting bit location of the mux control bit-field in @reg.
> + * @width: width of the mux control bit-field in @reg.
> + * @mux_flags: flags for mux-type clock.
> + * @alias: optional clock alias name to be assigned to this clock.
> + */
> +struct samsung_mux_clock {
> + const unsigned int id;
Is const unsigned int really correct?
> + const char *dev_name;
> + const char *name;
> + const char **parent_names;
> + u8 num_parents;
> + unsigned long flags;
> + unsigned long offset;
> + u8 shift;
> + u8 width;
> + u8 mux_flags;
> + const char *alias;
> +};
> +
> +#define __MUX(_id, dname, cname, pnames, o, s, w, f, mf, a) \
> + { \
> + .id = _id, \
> + .dev_name = dname, \
> + .name = cname, \
> + .parent_names = pnames, \
> + .num_parents = ARRAY_SIZE(pnames), \
> + .flags = f, \
> + .offset = o, \
> + .shift = s, \
> + .width = w, \
> + .mux_flags = mf, \
> + .alias = a, \
> + }
> +
> +#define MUX(_id, cname, pnames, o, s, w) \
> + __MUX(_id, NULL, cname, pnames, o, s, w, 0, 0, NULL)
> +
> +#define MUX_A(_id, cname, pnames, o, s, w, a) \
> + __MUX(_id, NULL, cname, pnames, o, s, w, 0, 0, a)
> +
> +#define MUX_F(_id, cname, pnames, o, s, w, f, mf) \
> + __MUX(_id, NULL, cname, pnames, o, s, w, f, mf, NULL)
> +
> +/**
> + * @id: platform specific id of the clock.
> + * struct samsung_div_clock: information about div clock
> + * @dev_name: name of the device to which this clock belongs.
> + * @name: name of this div clock.
> + * @parent_name: name of the parent clock.
> + * @flags: optional flags for basic clock.
> + * @offset: offset of the register for configuring the div.
> + * @shift: starting bit location of the div control bit-field in @reg.
> + * @div_flags: flags for div-type clock.
> + * @alias: optional clock alias name to be assigned to this clock.
> + */
> +struct samsung_div_clock {
> + const unsigned int id;
ditto
> + const char *dev_name;
> + const char *name;
> + const char *parent_name;
> + unsigned long flags;
> + unsigned long offset;
> + u8 shift;
> + u8 width;
> + u8 div_flags;
> + const char *alias;
> +};
> +
> +#define __DIV(_id, dname, cname, pname, o, s, w, f, df, a) \
> + { \
> + .id = _id, \
> + .dev_name = dname, \
> + .name = cname, \
> + .parent_name = pname, \
> + .flags = f, \
> + .offset = o, \
> + .shift = s, \
> + .width = w, \
> + .div_flags = df, \
> + .alias = a, \
> + }
> +
> +#define DIV(_id, cname, pname, o, s, w) \
> + __DIV(_id, NULL, cname, pname, o, s, w, 0, 0, NULL)
> +
> +#define DIV_A(_id, cname, pname, o, s, w, a) \
> + __DIV(_id, NULL, cname, pname, o, s, w, 0, 0, a)
> +
> +#define DIV_F(_id, cname, pname, o, s, w, f, df) \
> + __DIV(_id, NULL, cname, pname, o, s, w, f, df, NULL)
> +
> +/**
> + * struct samsung_gate_clock: information about gate clock
> + * @id: platform specific id of the clock.
> + * @dev_name: name of the device to which this clock belongs.
> + * @name: name of this gate clock.
> + * @parent_name: name of the parent clock.
> + * @flags: optional flags for basic clock.
> + * @offset: offset of the register for configuring the gate.
> + * @bit_idx: bit index of the gate control bit-field in @reg.
> + * @gate_flags: flags for gate-type clock.
> + * @alias: optional clock alias name to be assigned to this clock.
> + */
> +struct samsung_gate_clock {
> + const unsigned int id;
ditto
> + const char *dev_name;
> + const char *name;
> + const char *parent_name;
> + unsigned long flags;
> + unsigned long offset;
> + u8 bit_idx;
> + u8 gate_flags;
> + const char *alias;
> +};
> +
> +#define __GATE(_id, dname, cname, pname, o, b, f, gf, a) \
> + { \
> + .id = _id, \
> + .dev_name = dname, \
> + .name = cname, \
> + .parent_name = pname, \
> + .flags = f, \
> + .offset = o, \
> + .bit_idx = b, \
> + .gate_flags = gf, \
> + .alias = a, \
> + }
> +
> +#define GATE(_id, cname, pname, o, b, f, gf) \
> + __GATE(_id, NULL, cname, pname, o, b, f, gf, NULL)
> +
> +#define GATE_A(_id, cname, pname, o, b, f, gf, a) \
> + __GATE(_id, NULL, cname, pname, o, b, f, gf, a)
> +
> +#define GATE_D(_id, dname, cname, pname, o, b, f, gf) \
> + __GATE(_id, dname, cname, pname, o, b, f, gf, NULL)
> +
> +#define GATE_DA(_id, dname, cname, pname, o, b, f, gf, a) \
> + __GATE(_id, dname, cname, pname, o, b, f, gf, a)
> +
> +#define PNAME(x) static const char *x[] __initdata
> +
> +extern void __iomem *reg_base;
Where is it used? The name suggests that it should rather be static.
--
Best regards,
Tomasz Figa
^ permalink raw reply
* [PATCH resend] rtc: i.MX dryice: Add devicetree support
From: Andrew Morton @ 2012-11-14 22:52 UTC (permalink / raw)
To: linux-arm-kernel
In-Reply-To: <1352709770-5919-1-git-send-email-s.hauer@pengutronix.de>
On Mon, 12 Nov 2012 09:42:50 +0100
Sascha Hauer <s.hauer@pengutronix.de> wrote:
> Add devicetree probing, fixing some whitespace damage along the way.
>
I've already merged the below. It has better code but a little less
documentation:
From: Roland Stigge <stigge@antcom.de>
Subject: drivers/rtc/rtc-imxdi.c: add devicetree support
Add device tree support to the rtc-imxdi driver.
Signed-off-by: Roland Stigge <stigge@antcom.de>
Cc: Alessandro Zummo <a.zummo@towertech.it>
Cc: Grant Likely <grant.likely@secretlab.ca>
Cc: Sascha Hauer <kernel@pengutronix.de>
Cc: Russell King <linux@arm.linux.org.uk>
Signed-off-by: Andrew Morton <akpm@linux-foundation.org>
---
Documentation/devicetree/bindings/rtc/imxdi-rtc.txt | 17 ++++++++++
drivers/rtc/rtc-imxdi.c | 11 ++++++
2 files changed, 28 insertions(+)
diff -puN /dev/null Documentation/devicetree/bindings/rtc/imxdi-rtc.txt
--- /dev/null
+++ a/Documentation/devicetree/bindings/rtc/imxdi-rtc.txt
@@ -0,0 +1,17 @@
+* i.MX25 Real Time Clock controller
+
+This binding supports the following chips: i.MX25, i.MX53
+
+Required properties:
+- compatible: should be: "fsl,imx25-rtc"
+- reg: physical base address of the controller and length of memory mapped
+ region.
+- interrupts: rtc alarm interrupt
+
+Example:
+
+rtc at 80056000 {
+ compatible = "fsl,imx53-rtc", "fsl,imx25-rtc";
+ reg = <0x80056000 2000>;
+ interrupts = <29>;
+};
diff -puN drivers/rtc/rtc-imxdi.c~rtc-imxdi-add-devicetree-support drivers/rtc/rtc-imxdi.c
--- a/drivers/rtc/rtc-imxdi.c~rtc-imxdi-add-devicetree-support
+++ a/drivers/rtc/rtc-imxdi.c
@@ -37,6 +37,7 @@
#include <linux/rtc.h>
#include <linux/sched.h>
#include <linux/workqueue.h>
+#include <linux/of.h>
/* DryIce Register Definitions */
@@ -495,10 +496,20 @@ static int __devexit dryice_rtc_remove(s
return 0;
}
+#ifdef CONFIG_OF
+static const struct of_device_id dryice_dt_ids[] = {
+ { .compatible = "fsl,imx25-rtc" },
+ { /* sentinel */ }
+};
+
+MODULE_DEVICE_TABLE(of, dryice_dt_ids);
+#endif
+
static struct platform_driver dryice_rtc_driver = {
.driver = {
.name = "imxdi_rtc",
.owner = THIS_MODULE,
+ .of_match_table = of_match_ptr(dryice_dt_ids),
},
.remove = __devexit_p(dryice_rtc_remove),
};
_
^ permalink raw reply
* [PATCH V3 4/5] arm: mm: Added support for PJ4B cpu and init routines
From: Gregory CLEMENT @ 2012-11-14 22:31 UTC (permalink / raw)
To: linux-arm-kernel
In-Reply-To: <1352931637-3405-5-git-send-email-gregory.clement@free-electrons.com>
Hello Russell,
With the 2 changes I have done on according your comments
do you think you can give your acked-by for this patch?
Thanks
On 11/14/2012 11:20 PM, Gregory CLEMENT wrote:
> From: Yehuda Yitschak <yehuday@marvell.com>
>
> Signed-off-by: Yehuda Yitschak <yehuday@marvell.com>
> Signed-off-by: Gregory CLEMENT <gregory.clement@free-electrons.com>
> ---
> arch/arm/mach-mvebu/Kconfig | 2 +-
> arch/arm/mm/Kconfig | 4 ++++
> arch/arm/mm/proc-v7.S | 51 +++++++++++++++++++++++++++++++++++++++++++
> 3 files changed, 56 insertions(+), 1 deletion(-)
>
> diff --git a/arch/arm/mach-mvebu/Kconfig b/arch/arm/mach-mvebu/Kconfig
> index 17d246b..9bfaa0c 100644
> --- a/arch/arm/mach-mvebu/Kconfig
> +++ b/arch/arm/mach-mvebu/Kconfig
> @@ -22,7 +22,7 @@ config MVEBU_CLK_CPU
> config MACH_ARMADA_370_XP
> bool
> select ARMADA_370_XP_TIMER
> - select CPU_V7
> + select CPU_PJ4B
>
> config MACH_ARMADA_370
> bool "Marvell Armada 370 boards"
> diff --git a/arch/arm/mm/Kconfig b/arch/arm/mm/Kconfig
> index 94186b6..3fd629d 100644
> --- a/arch/arm/mm/Kconfig
> +++ b/arch/arm/mm/Kconfig
> @@ -352,6 +352,10 @@ config CPU_PJ4
> select ARM_THUMBEE
> select CPU_V7
>
> +config CPU_PJ4B
> + bool
> + select CPU_V7
> +
> # ARMv6
> config CPU_V6
> bool "Support ARM V6 processor" if ARCH_INTEGRATOR || MACH_REALVIEW_EB || MACH_REALVIEW_PBX
> diff --git a/arch/arm/mm/proc-v7.S b/arch/arm/mm/proc-v7.S
> index 846d279..a4c0ccf 100644
> --- a/arch/arm/mm/proc-v7.S
> +++ b/arch/arm/mm/proc-v7.S
> @@ -169,6 +169,47 @@ __v7_ca15mp_setup:
> orreq r0, r0, r10 @ Enable CPU-specific SMP bits
> mcreq p15, 0, r0, c1, c0, 1
> #endif
> +
> +__v7_pj4b_setup:
> +#ifdef CONFIG_CPU_PJ4B
> +
> +#define SNOOP_DATA (1 << 25) /* Dont interleave write and snoop data */
> +#define CWF (1 << 27) /* Disable Critical Word First feature */
> +#define OUTSANDING_NC (1 << 29) /* Disable outstanding non cacheable request */
> +#define L1_REP_RR (1 << 30) /* L1 replacement - Strict round robin */
> +
> +#define AUX_DBG_CTRL2 (SNOOP_DATA | CWF | OUTSANDING_NC | L1_REP_RR)
> +
> + /* Auxiliary Debug Modes Control 1 Register */
> + mrc p15, 1, r0, c15, c1, 1
> + orr r0, r0, #(1 << 16) @ Disable data transfer for clean line.
> + orr r0, r0, #(1 << 5) @ Enable the back off of STREX instr
> + orr r0, r0, #(1 << 8) @ Disable Internal Parity Handling
> + bic r0, r0, #(1 << 2) @ Disable Static BP
> + mcr p15, 1, r0, c15, c1, 1
> +
> + /* Auxiliary Debug Modes Control 2 Register */
> + mrc p15, 1, r0, c15, c1, 2
> + bic r0, r0, #(1 << 23) @ Enable fast LDR.
> + orr r0, r0, #AUX_DBG_CTRL2
> + mcr p15, 1, r0, c15, c1, 2
> +
> + /* Auxiliary Functional Modes Control Register 0 */
> + mrc p15, 1, r0, c15, c2, 0
> +#ifdef CONFIG_SMP
> + orr r0, r0, #(1 << 1) @ Set SMP mode. Join the coherency fabric
> +#endif
> + orr r0, r0, #(1 << 2) @ Support L1 parity checking
> + orr r0, r0, #(1 << 8) @ Broadcast Cache and TLB maintenance
> + mcr p15, 1, r0, c15, c2, 0
> +
> + /* Auxiliary Debug Modes Control 0 Register */
> + mrc p15, 1, r0, c15, c1, 0
> + orr r0, r0, #(1 << 22) @ WFI/WFE - serve the DVM and back to idle
> + mcr p15, 1, r0, c15, c1, 0
> +
> +#endif /* CONFIG_CPU_PJ4B */
> +
> __v7_setup:
> adr r12, __v7_setup_stack @ the local stack
> stmia r12, {r0-r5, r7, r9, r11, lr}
> @@ -342,6 +383,16 @@ __v7_ca9mp_proc_info:
> .long 0xff0ffff0
> __v7_proc __v7_ca9mp_setup
> .size __v7_ca9mp_proc_info, . - __v7_ca9mp_proc_info
> +
> + /*
> + * Marvell PJ4B processor.
> + */
> + .type __v7_pj4b_proc_info, #object
> +__v7_pj4b_proc_info:
> + .long 0x562f5840
> + .long 0xfffffff0
> + __v7_proc __v7_pj4b_setup
> + .size __v7_pj4b_proc_info, . - __v7_pj4b_proc_info
> #endif /* CONFIG_ARM_LPAE */
>
> /*
>
--
Gregory Clement, Free Electrons
Kernel, drivers, real-time and embedded Linux
development, consulting, training and support.
http://free-electrons.com
^ permalink raw reply
* [PATCH] ARM: Fix errata 751472 handling on Cortex-A9 r1p*
From: Tony Lindgren @ 2012-11-14 22:21 UTC (permalink / raw)
To: linux-arm-kernel
In-Reply-To: <50A413D4.7000405@gmail.com>
* Rob Herring <robherring2@gmail.com> [121114 13:59]:
> On 11/14/2012 02:32 PM, Tony Lindgren wrote:
> >
> > Checking for the bit already set should work in this case, I'll post
> > a patch for that shortly.
>
> Can you actually read the state of the diagnostic register in non-secure
> mode? If you can on the A9, is the same true on A8 or others?
Looks like it can be read on at least TI omap 4430 which is A9.
But it reads as zero, so the below patch is what I came up with.
No idea if assuming that zero value for the diagnostic register
is safe.. What's the default value of the diagnostic register supposed
to be?
> Multi-platform kernels present a new problem in that we basically need
> to enable all errata work-arounds. I've been meaning to look thru the
> errata work-arounds to figure out which ones can be selected for
> multi-platform kernels without side effects on unaffected parts (i.e.
> set a chicken bit based on core revision). For any in runtime paths, we
> may need to do runtime patching if they have performance impact.
Yeah that's how I ran into it as multiplatform enabled omap booted
on other omaps but not on omap4.
Regards,
Tony
From: Tony Lindgren <tony@atomide.com>
Date: Tue, 13 Nov 2012 16:57:42 -0800
Subject: [PATCH] ARM: Fix errata 751472 handling on Cortex-A9 for secure mode
Looks like enabling CONFIG_ARM_ERRATA_751472 causes TI omap4 blaze
to not boot when enabled. The ARM core on it is an earlier r1p2.
This seems to be caused by the write to the diagnostic register
that shortly after causes an exception as writing to the diagnostic
register on systems with secure mode is not allowed.
Also it seems that reading the diagnostic register results zero
so we may not be able to check if bit #11 is already set.
Let's assume that if the diagnostic register is zero, we don't
want to touch it as it seems to hint secure mode at least on
TI omaps. If it's non-zero, check if bit #11 is set and only
attempt to set it if not set.
--- a/arch/arm/mm/proc-v7.S
+++ b/arch/arm/mm/proc-v7.S
@@ -238,9 +238,13 @@ __v7_setup:
#if defined(CONFIG_ARM_ERRATA_751472) && defined(CONFIG_SMP)
ALT_SMP(cmp r6, #0x30) @ present prior to r3p0
ALT_UP_B(1f)
- mrclt p15, 0, r10, c15, c0, 1 @ read diagnostic register
- orrlt r10, r10, #1 << 11 @ set bit #11
- mcrlt p15, 0, r10, c15, c0, 1 @ write diagnostic register
+ bge 1f @ not needed for r3p0 and later
+ mrc p15, 0, r10, c15, c0, 1 @ read diagnostic register
+ teq r10, #0 @ zero for secure mode?
+ beq 1f @ bail out for secure mode
+ tst r10, #1 << 11 @ bit #11 already set?
+ orreq r10, r10, #1 << 11 @ set bit #11 if not set
+ mcreq p15, 0, r10, c15, c0, 1 @ write diagnostic register
1:
#endif
^ permalink raw reply
* [PATCH V3 5/5] arm: mvebu: Added SMP support for Armada XP
From: Gregory CLEMENT @ 2012-11-14 22:20 UTC (permalink / raw)
To: linux-arm-kernel
In-Reply-To: <1352931637-3405-1-git-send-email-gregory.clement@free-electrons.com>
From: Yehuda Yitschak <yehuday@marvell.com>
1. added smp init functions in platsmp.c
2. added secondary cpu entry point in headsmp.S
3. added hotplog initial support in hotplug.c
4. added SMP support for PJ4B cpu
Signed-off-by: Yehuda Yitschak <yehuday@marvell.com>
Signed-off-by: Gregory CLEMENT <gregory.clement@free-electrons.com>
---
arch/arm/boot/dts/armada-xp.dtsi | 4 ++
arch/arm/configs/mvebu_defconfig | 3 +
arch/arm/mach-mvebu/Kconfig | 1 +
arch/arm/mach-mvebu/Makefile | 2 +
arch/arm/mach-mvebu/armada-370-xp.c | 3 +
arch/arm/mach-mvebu/common.h | 3 +
arch/arm/mach-mvebu/headsmp.S | 66 +++++++++++++++++++
arch/arm/mach-mvebu/hotplug.c | 30 +++++++++
arch/arm/mach-mvebu/platsmp.c | 124 +++++++++++++++++++++++++++++++++++
9 files changed, 236 insertions(+)
create mode 100644 arch/arm/mach-mvebu/headsmp.S
create mode 100644 arch/arm/mach-mvebu/hotplug.c
create mode 100644 arch/arm/mach-mvebu/platsmp.c
diff --git a/arch/arm/boot/dts/armada-xp.dtsi b/arch/arm/boot/dts/armada-xp.dtsi
index 531619f..7f968dc 100644
--- a/arch/arm/boot/dts/armada-xp.dtsi
+++ b/arch/arm/boot/dts/armada-xp.dtsi
@@ -38,24 +38,28 @@
#size-cells = <0>;
cpu at 0 {
+ device_type = "cpu";
compatible = "marvell,sheeva-v7";
reg = <0>;
clocks = <&cpuclk 0>;
};
cpu at 1 {
+ device_type = "cpu";
compatible = "marvell,sheeva-v7";
reg = <1>;
clocks = <&cpuclk 1>;
};
cpu at 2 {
+ device_type = "cpu";
compatible = "marvell,sheeva-v7";
reg = <2>;
clocks = <&cpuclk 2>;
};
cpu at 3 {
+ device_type = "cpu";
compatible = "marvell,sheeva-v7";
reg = <3>;
clocks = <&cpuclk 3>;
diff --git a/arch/arm/configs/mvebu_defconfig b/arch/arm/configs/mvebu_defconfig
index 3458752..da598d3 100644
--- a/arch/arm/configs/mvebu_defconfig
+++ b/arch/arm/configs/mvebu_defconfig
@@ -12,6 +12,9 @@ CONFIG_ARCH_MVEBU=y
CONFIG_MACH_ARMADA_370=y
CONFIG_MACH_ARMADA_XP=y
# CONFIG_CACHE_L2X0 is not set
+# CONFIG_SWP_EMULATE is not set
+CONFIG_SMP=y
+# CONFIG_LOCAL_TIMERS is not set
CONFIG_AEABI=y
CONFIG_HIGHMEM=y
# CONFIG_COMPACTION is not set
diff --git a/arch/arm/mach-mvebu/Kconfig b/arch/arm/mach-mvebu/Kconfig
index 9bfaa0c..d70afe3 100644
--- a/arch/arm/mach-mvebu/Kconfig
+++ b/arch/arm/mach-mvebu/Kconfig
@@ -22,6 +22,7 @@ config MVEBU_CLK_CPU
config MACH_ARMADA_370_XP
bool
select ARMADA_370_XP_TIMER
+ select HAVE_SMP
select CPU_PJ4B
config MACH_ARMADA_370
diff --git a/arch/arm/mach-mvebu/Makefile b/arch/arm/mach-mvebu/Makefile
index 8e6e50b..eb3cbd1 100644
--- a/arch/arm/mach-mvebu/Makefile
+++ b/arch/arm/mach-mvebu/Makefile
@@ -3,3 +3,5 @@ ccflags-$(CONFIG_ARCH_MULTIPLATFORM) := -I$(srctree)/$(src)/include \
obj-y += system-controller.o
obj-$(CONFIG_MACH_ARMADA_370_XP) += armada-370-xp.o irq-armada-370-xp.o addr-map.o coherency.o pmsu.o
+obj-$(CONFIG_SMP) += platsmp.o headsmp.o
+obj-$(CONFIG_HOTPLUG_CPU) += hotplug.o
diff --git a/arch/arm/mach-mvebu/armada-370-xp.c b/arch/arm/mach-mvebu/armada-370-xp.c
index 2af6ce5..66befa1 100644
--- a/arch/arm/mach-mvebu/armada-370-xp.c
+++ b/arch/arm/mach-mvebu/armada-370-xp.c
@@ -22,6 +22,7 @@
#include <asm/mach/time.h>
#include "armada-370-xp.h"
#include "common.h"
+#include "coherency.h"
static struct map_desc armada_370_xp_io_desc[] __initdata = {
{
@@ -50,6 +51,7 @@ struct sys_timer armada_370_xp_timer = {
static void __init armada_370_xp_dt_init(void)
{
of_platform_populate(NULL, of_default_bus_match_table, NULL, NULL);
+ coherency_init();
}
static const char * const armada_370_xp_dt_board_dt_compat[] = {
@@ -59,6 +61,7 @@ static const char * const armada_370_xp_dt_board_dt_compat[] = {
};
DT_MACHINE_START(ARMADA_XP_DT, "Marvell Aramada 370/XP (Device Tree)")
+ .smp = smp_ops(armada_xp_smp_ops),
.init_machine = armada_370_xp_dt_init,
.map_io = armada_370_xp_map_io,
.init_irq = armada_370_xp_init_irq,
diff --git a/arch/arm/mach-mvebu/common.h b/arch/arm/mach-mvebu/common.h
index 74ee0b2..86484bb 100644
--- a/arch/arm/mach-mvebu/common.h
+++ b/arch/arm/mach-mvebu/common.h
@@ -21,7 +21,10 @@ void mvebu_clocks_init(void);
void armada_370_xp_init_irq(void);
void armada_370_xp_handle_irq(struct pt_regs *regs);
+void armada_xp_cpu_die(unsigned int cpu);
int armada_370_xp_coherency_init(void);
int armada_370_xp_pmsu_init(void);
+void armada_xp_secondary_startup(void);
+extern struct smp_operations armada_xp_smp_ops;
#endif
diff --git a/arch/arm/mach-mvebu/headsmp.S b/arch/arm/mach-mvebu/headsmp.S
new file mode 100644
index 0000000..33db1d5
--- /dev/null
+++ b/arch/arm/mach-mvebu/headsmp.S
@@ -0,0 +1,66 @@
+/*
+ * SMP support: Entry point for secondary CPUs
+ *
+ * Copyright (C) 2012 Marvell
+ *
+ * Yehuda Yitschak <yehuday@marvell.com>
+ * Gregory CLEMENT <gregory.clement@free-electrons.com>
+ * Thomas Petazzoni <thomas.petazzoni@free-electrons.com>
+ *
+ * This file is licensed under the terms of the GNU General Public
+ * License version 2. This program is licensed "as is" without any
+ * warranty of any kind, whether express or implied.
+ *
+ * This file implements the assembly entry point for secondary CPUs
+ * in an SMP kernel. The only thing we need to do is to add the CPU
+ * to the coherency fabric by writing to 2 registers. Currently these
+ * register addresses are hard coded due to the early initialisation problems.
+ */
+
+#include <linux/linkage.h>
+#include <linux/init.h>
+
+/*
+ * At this stage the secondary CPUs don't have acces yet to the MMU, so
+ * we have to provide physical addresses
+ */
+#define ARMADA_XP_COHERENCY_FABRIC_CTL_REG 0xD0020200
+#define ARMADA_XP_COHERENCY_FABRIC_CFG_REG 0xD0020204
+
+ __INIT
+
+/*
+ * Armada XP specific entry point for secondary CPUs.
+ * We add the CPU to the coherency fabric and then jump to secondary
+ * startup
+ */
+
+ENTRY(armada_xp_secondary_startup)
+
+ /* Read CPU id */
+ mrc p15, 0, r1, c0, c0, 5
+ and r1, r1, #0xF
+
+ /* Add CPU to coherency fabric */
+
+ /* Create bit by cpu index */
+ mov r2,r1
+ add r2,r2,#24
+ mov r3, #1
+ lsl r3, r3, r2
+
+ /* Add CPU to SMP group - Atomic */
+ ldr r0, = ARMADA_XP_COHERENCY_FABRIC_CTL_REG
+ ldr r10, [r0]
+ orr r10 , r10, r3
+ str r10,[r0]
+
+ /* Enable coherency on CPU - Atomic*/
+ ldr r0, = ARMADA_XP_COHERENCY_FABRIC_CFG_REG
+ ldr r10, [r0]
+ orr r10 , r10, r3
+ str r10,[r0]
+
+ b secondary_startup
+
+ENDPROC(armada_xp_secondary_startup)
diff --git a/arch/arm/mach-mvebu/hotplug.c b/arch/arm/mach-mvebu/hotplug.c
new file mode 100644
index 0000000..b228b6a
--- /dev/null
+++ b/arch/arm/mach-mvebu/hotplug.c
@@ -0,0 +1,30 @@
+/*
+ * Symmetric Multi Processing (SMP) support for Armada XP
+ *
+ * Copyright (C) 2012 Marvell
+ *
+ * Lior Amsalem <alior@marvell.com>
+ * Gregory CLEMENT <gregory.clement@free-electrons.com>
+ * Thomas Petazzoni <thomas.petazzoni@free-electrons.com>
+ *
+ * This file is licensed under the terms of the GNU General Public
+ * License version 2. This program is licensed "as is" without any
+ * warranty of any kind, whether express or implied.
+ */
+#include <linux/kernel.h>
+#include <linux/errno.h>
+#include <linux/smp.h>
+#include <asm/proc-fns.h>
+
+/*
+ * platform-specific code to shutdown a CPU
+ *
+ * Called with IRQs disabled
+ */
+void __ref armada_xp_cpu_die(unsigned int cpu)
+{
+ cpu_do_idle();
+
+ /* We should never return from idle */
+ panic("mvebu: cpu %d unexpectedly exit from shutdown\n", cpu);
+}
diff --git a/arch/arm/mach-mvebu/platsmp.c b/arch/arm/mach-mvebu/platsmp.c
new file mode 100644
index 0000000..1cd6c08
--- /dev/null
+++ b/arch/arm/mach-mvebu/platsmp.c
@@ -0,0 +1,124 @@
+/*
+ * Symmetric Multi Processing (SMP) support for Armada XP
+ *
+ * Copyright (C) 2012 Marvell
+ *
+ * Lior Amsalem <alior@marvell.com>
+ * Yehuda Yitschak <yehuday@marvell.com>
+ * Gregory CLEMENT <gregory.clement@free-electrons.com>
+ * Thomas Petazzoni <thomas.petazzoni@free-electrons.com>
+ *
+ * This file is licensed under the terms of the GNU General Public
+ * License version 2. This program is licensed "as is" without any
+ * warranty of any kind, whether express or implied.
+ *
+ * The Armada XP SoC has 4 ARMv7 PJ4B CPUs running in full HW coherency
+ * This file implements the routines for preparing the SMP infrastructure
+ * and waking up the secondary CPUs
+ */
+
+#include <linux/init.h>
+#include <linux/smp.h>
+#include <linux/clk.h>
+#include <linux/of.h>
+#include <asm/cacheflush.h>
+#include <asm/smp_plat.h>
+#include "common.h"
+#include "armada-370-xp.h"
+#include "pmsu.h"
+#include "coherency.h"
+
+void __init set_secondary_cpus_clock(void)
+{
+ int cpu;
+ unsigned long rate;
+ struct clk *cpu_clk = NULL;
+ struct device_node *np = NULL;
+
+ cpu = smp_processor_id();
+ np = of_find_node_by_type(np, "cpu");
+ np = NULL;
+ while ((np = of_find_node_by_type(np, "cpu"))) {
+ const u32 *reg;
+ int len;
+ reg = of_get_property(np, "reg", &len);
+ if (!reg || len != 4) {
+ pr_err("%s missing reg property\n", np->full_name);
+ continue;
+ }
+ if (be32_to_cpup(reg) == cpu) {
+ cpu_clk = of_clk_get(np, 0);
+ break;
+ }
+ }
+ WARN_ON(IS_ERR(cpu_clk));
+ clk_prepare_enable(cpu_clk);
+ rate = clk_get_rate(cpu_clk);
+
+ /* set all the other CPU clk to the same rate than the boot CPU */
+ np = NULL;
+ while ((np = of_find_node_by_type(np, "cpu"))) {
+ const u32 *reg;
+ int len;
+ reg = of_get_property(np, "reg", &len);
+ if (!reg || len != 4) {
+ pr_err("%s missing reg property\n", np->full_name);
+ continue;
+ }
+ if (be32_to_cpup(reg) != cpu) {
+ cpu_clk = of_clk_get(np, 0);
+ clk_set_rate(cpu_clk, rate);
+ }
+ }
+}
+
+static void __cpuinit armada_xp_secondary_init(unsigned int cpu)
+{
+ armada_xp_mpic_smp_cpu_init();
+}
+
+static int __cpuinit armada_xp_boot_secondary(unsigned int cpu,
+ struct task_struct *idle)
+{
+ pr_info("Booting CPU %d\n", cpu);
+
+ armada_xp_boot_cpu(cpu, armada_xp_secondary_startup);
+
+ return 0;
+}
+
+static void __init armada_xp_smp_init_cpus(void)
+{
+ unsigned int i, ncores;
+ ncores = coherency_get_cpu_count();
+
+ /* Limit possbile CPUs to defconfig */
+ if (ncores > nr_cpu_ids) {
+ pr_warn("SMP: %d CPUs physically present. Only %d configured.",
+ ncores, nr_cpu_ids);
+ pr_warn("Clipping CPU count to %d\n", nr_cpu_ids);
+ ncores = nr_cpu_ids;
+ }
+
+ for (i = 0; i < ncores; i++)
+ set_cpu_possible(i, true);
+
+ set_smp_cross_call(armada_mpic_send_doorbell);
+}
+
+void __init armada_xp_smp_prepare_cpus(unsigned int max_cpus)
+{
+ set_secondary_cpus_clock();
+ flush_cache_all();
+ set_cpu_coherent(cpu_logical_map(smp_processor_id()), 0);
+}
+
+struct smp_operations armada_xp_smp_ops __initdata = {
+ .smp_init_cpus = armada_xp_smp_init_cpus,
+ .smp_prepare_cpus = armada_xp_smp_prepare_cpus,
+ .smp_secondary_init = armada_xp_secondary_init,
+ .smp_boot_secondary = armada_xp_boot_secondary,
+#ifdef CONFIG_HOTPLUG_CPU
+ .cpu_die = armada_xp_cpu_die,
+#endif
+};
--
1.7.9.5
^ permalink raw reply related
* [PATCH V3 4/5] arm: mm: Added support for PJ4B cpu and init routines
From: Gregory CLEMENT @ 2012-11-14 22:20 UTC (permalink / raw)
To: linux-arm-kernel
In-Reply-To: <1352931637-3405-1-git-send-email-gregory.clement@free-electrons.com>
From: Yehuda Yitschak <yehuday@marvell.com>
Signed-off-by: Yehuda Yitschak <yehuday@marvell.com>
Signed-off-by: Gregory CLEMENT <gregory.clement@free-electrons.com>
---
arch/arm/mach-mvebu/Kconfig | 2 +-
arch/arm/mm/Kconfig | 4 ++++
arch/arm/mm/proc-v7.S | 51 +++++++++++++++++++++++++++++++++++++++++++
3 files changed, 56 insertions(+), 1 deletion(-)
diff --git a/arch/arm/mach-mvebu/Kconfig b/arch/arm/mach-mvebu/Kconfig
index 17d246b..9bfaa0c 100644
--- a/arch/arm/mach-mvebu/Kconfig
+++ b/arch/arm/mach-mvebu/Kconfig
@@ -22,7 +22,7 @@ config MVEBU_CLK_CPU
config MACH_ARMADA_370_XP
bool
select ARMADA_370_XP_TIMER
- select CPU_V7
+ select CPU_PJ4B
config MACH_ARMADA_370
bool "Marvell Armada 370 boards"
diff --git a/arch/arm/mm/Kconfig b/arch/arm/mm/Kconfig
index 94186b6..3fd629d 100644
--- a/arch/arm/mm/Kconfig
+++ b/arch/arm/mm/Kconfig
@@ -352,6 +352,10 @@ config CPU_PJ4
select ARM_THUMBEE
select CPU_V7
+config CPU_PJ4B
+ bool
+ select CPU_V7
+
# ARMv6
config CPU_V6
bool "Support ARM V6 processor" if ARCH_INTEGRATOR || MACH_REALVIEW_EB || MACH_REALVIEW_PBX
diff --git a/arch/arm/mm/proc-v7.S b/arch/arm/mm/proc-v7.S
index 846d279..a4c0ccf 100644
--- a/arch/arm/mm/proc-v7.S
+++ b/arch/arm/mm/proc-v7.S
@@ -169,6 +169,47 @@ __v7_ca15mp_setup:
orreq r0, r0, r10 @ Enable CPU-specific SMP bits
mcreq p15, 0, r0, c1, c0, 1
#endif
+
+__v7_pj4b_setup:
+#ifdef CONFIG_CPU_PJ4B
+
+#define SNOOP_DATA (1 << 25) /* Dont interleave write and snoop data */
+#define CWF (1 << 27) /* Disable Critical Word First feature */
+#define OUTSANDING_NC (1 << 29) /* Disable outstanding non cacheable request */
+#define L1_REP_RR (1 << 30) /* L1 replacement - Strict round robin */
+
+#define AUX_DBG_CTRL2 (SNOOP_DATA | CWF | OUTSANDING_NC | L1_REP_RR)
+
+ /* Auxiliary Debug Modes Control 1 Register */
+ mrc p15, 1, r0, c15, c1, 1
+ orr r0, r0, #(1 << 16) @ Disable data transfer for clean line.
+ orr r0, r0, #(1 << 5) @ Enable the back off of STREX instr
+ orr r0, r0, #(1 << 8) @ Disable Internal Parity Handling
+ bic r0, r0, #(1 << 2) @ Disable Static BP
+ mcr p15, 1, r0, c15, c1, 1
+
+ /* Auxiliary Debug Modes Control 2 Register */
+ mrc p15, 1, r0, c15, c1, 2
+ bic r0, r0, #(1 << 23) @ Enable fast LDR.
+ orr r0, r0, #AUX_DBG_CTRL2
+ mcr p15, 1, r0, c15, c1, 2
+
+ /* Auxiliary Functional Modes Control Register 0 */
+ mrc p15, 1, r0, c15, c2, 0
+#ifdef CONFIG_SMP
+ orr r0, r0, #(1 << 1) @ Set SMP mode. Join the coherency fabric
+#endif
+ orr r0, r0, #(1 << 2) @ Support L1 parity checking
+ orr r0, r0, #(1 << 8) @ Broadcast Cache and TLB maintenance
+ mcr p15, 1, r0, c15, c2, 0
+
+ /* Auxiliary Debug Modes Control 0 Register */
+ mrc p15, 1, r0, c15, c1, 0
+ orr r0, r0, #(1 << 22) @ WFI/WFE - serve the DVM and back to idle
+ mcr p15, 1, r0, c15, c1, 0
+
+#endif /* CONFIG_CPU_PJ4B */
+
__v7_setup:
adr r12, __v7_setup_stack @ the local stack
stmia r12, {r0-r5, r7, r9, r11, lr}
@@ -342,6 +383,16 @@ __v7_ca9mp_proc_info:
.long 0xff0ffff0
__v7_proc __v7_ca9mp_setup
.size __v7_ca9mp_proc_info, . - __v7_ca9mp_proc_info
+
+ /*
+ * Marvell PJ4B processor.
+ */
+ .type __v7_pj4b_proc_info, #object
+__v7_pj4b_proc_info:
+ .long 0x562f5840
+ .long 0xfffffff0
+ __v7_proc __v7_pj4b_setup
+ .size __v7_pj4b_proc_info, . - __v7_pj4b_proc_info
#endif /* CONFIG_ARM_LPAE */
/*
--
1.7.9.5
^ permalink raw reply related
* [PATCH V3 3/5] arm: mvebu: Added IPI support via doorbells
From: Gregory CLEMENT @ 2012-11-14 22:20 UTC (permalink / raw)
To: linux-arm-kernel
In-Reply-To: <1352931637-3405-1-git-send-email-gregory.clement@free-electrons.com>
From: Yehuda Yitschak <yehuday@marvell.com>
Signed-off-by: Yehuda Yitschak <yehuday@marvell.com>
Signed-off-by: Gregory CLEMENT <gregory.clement@free-electrons.com>
---
.../devicetree/bindings/arm/armada-370-xp-mpic.txt | 12 ++-
arch/arm/boot/dts/armada-xp.dtsi | 2 +-
arch/arm/mach-mvebu/armada-370-xp.h | 10 +++
arch/arm/mach-mvebu/irq-armada-370-xp.c | 92 ++++++++++++++++++--
4 files changed, 106 insertions(+), 10 deletions(-)
diff --git a/Documentation/devicetree/bindings/arm/armada-370-xp-mpic.txt b/Documentation/devicetree/bindings/arm/armada-370-xp-mpic.txt
index 70c0dc5..61df564 100644
--- a/Documentation/devicetree/bindings/arm/armada-370-xp-mpic.txt
+++ b/Documentation/devicetree/bindings/arm/armada-370-xp-mpic.txt
@@ -6,9 +6,15 @@ Required properties:
- interrupt-controller: Identifies the node as an interrupt controller.
- #interrupt-cells: The number of cells to define the interrupts. Should be 1.
The cell is the IRQ number
+
- reg: Should contain PMIC registers location and length. First pair
for the main interrupt registers, second pair for the per-CPU
- interrupt registers
+ interrupt registers. For this last pair, to be compliant with SMP
+ support, the "virtual" must be use (For the record, these registers
+ automatically map to the interrupt controller registers of the
+ current CPU)
+
+
Example:
@@ -18,6 +24,6 @@ Example:
#address-cells = <1>;
#size-cells = <1>;
interrupt-controller;
- reg = <0xd0020000 0x1000>,
- <0xd0021000 0x1000>;
+ reg = <0xd0020a00 0x1d0>,
+ <0xd0021070 0x58>;
};
diff --git a/arch/arm/boot/dts/armada-xp.dtsi b/arch/arm/boot/dts/armada-xp.dtsi
index f521ed8..531619f 100644
--- a/arch/arm/boot/dts/armada-xp.dtsi
+++ b/arch/arm/boot/dts/armada-xp.dtsi
@@ -24,7 +24,7 @@
mpic: interrupt-controller at d0020000 {
reg = <0xd0020a00 0x1d0>,
- <0xd0021870 0x58>;
+ <0xd0021070 0x58>;
};
armada-370-xp-pmsu at d0022000 {
diff --git a/arch/arm/mach-mvebu/armada-370-xp.h b/arch/arm/mach-mvebu/armada-370-xp.h
index aac9beb..dce590d 100644
--- a/arch/arm/mach-mvebu/armada-370-xp.h
+++ b/arch/arm/mach-mvebu/armada-370-xp.h
@@ -19,4 +19,14 @@
#define ARMADA_370_XP_REGS_VIRT_BASE IOMEM(0xfeb00000)
#define ARMADA_370_XP_REGS_SIZE SZ_1M
+#ifndef __ASSEMBLY__
+
+#ifdef CONFIG_SMP
+#include <linux/cpumask.h>
+
+void armada_mpic_send_doorbell(const struct cpumask *mask, unsigned int irq);
+void armada_xp_mpic_smp_cpu_init(void);
+#endif
+#endif
+
#endif /* __MACH_ARMADA_370_XP_H */
diff --git a/arch/arm/mach-mvebu/irq-armada-370-xp.c b/arch/arm/mach-mvebu/irq-armada-370-xp.c
index 5f5f939..549b684 100644
--- a/arch/arm/mach-mvebu/irq-armada-370-xp.c
+++ b/arch/arm/mach-mvebu/irq-armada-370-xp.c
@@ -24,6 +24,7 @@
#include <linux/irqdomain.h>
#include <asm/mach/arch.h>
#include <asm/exception.h>
+#include <asm/smp_plat.h>
/* Interrupt Controller Registers Map */
#define ARMADA_370_XP_INT_SET_MASK_OFFS (0x48)
@@ -35,6 +36,12 @@
#define ARMADA_370_XP_CPU_INTACK_OFFS (0x44)
+#define ARMADA_370_XP_SW_TRIG_INT_OFFS (0x4)
+#define ARMADA_370_XP_IN_DRBEL_MSK_OFFS (0xc)
+#define ARMADA_370_XP_IN_DRBEL_CAUSE_OFFS (0x8)
+
+#define ACTIVE_DOORBELLS (8)
+
static void __iomem *per_cpu_int_base;
static void __iomem *main_int_base;
static struct irq_domain *armada_370_xp_mpic_domain;
@@ -51,11 +58,22 @@ static void armada_370_xp_irq_unmask(struct irq_data *d)
per_cpu_int_base + ARMADA_370_XP_INT_CLEAR_MASK_OFFS);
}
+#ifdef CONFIG_SMP
+static int armada_xp_set_affinity(struct irq_data *d,
+ const struct cpumask *mask_val, bool force)
+{
+ return 0;
+}
+#endif
+
static struct irq_chip armada_370_xp_irq_chip = {
.name = "armada_370_xp_irq",
.irq_mask = armada_370_xp_irq_mask,
.irq_mask_ack = armada_370_xp_irq_mask,
.irq_unmask = armada_370_xp_irq_unmask,
+#ifdef CONFIG_SMP
+ .irq_set_affinity = armada_xp_set_affinity,
+#endif
};
static int armada_370_xp_mpic_irq_map(struct irq_domain *h,
@@ -72,6 +90,41 @@ static int armada_370_xp_mpic_irq_map(struct irq_domain *h,
return 0;
}
+#ifdef CONFIG_SMP
+void armada_mpic_send_doorbell(const struct cpumask *mask, unsigned int irq)
+{
+ int cpu;
+ unsigned long map = 0;
+
+ /* Convert our logical CPU mask into a physical one. */
+ for_each_cpu(cpu, mask)
+ map |= 1 << cpu_logical_map(cpu);
+
+ /*
+ * Ensure that stores to Normal memory are visible to the
+ * other CPUs before issuing the IPI.
+ */
+ dsb();
+
+ /* submit softirq */
+ writel((map << 8) | irq, main_int_base +
+ ARMADA_370_XP_SW_TRIG_INT_OFFS);
+}
+
+void armada_xp_mpic_smp_cpu_init(void)
+{
+ /* Clear pending IPIs */
+ writel(0, per_cpu_int_base + ARMADA_370_XP_IN_DRBEL_CAUSE_OFFS);
+
+ /* Enable first 8 IPIs */
+ writel((1 << ACTIVE_DOORBELLS) - 1, per_cpu_int_base +
+ ARMADA_370_XP_IN_DRBEL_MSK_OFFS);
+
+ /* Unmask IPI interrupt */
+ writel(0, per_cpu_int_base + ARMADA_370_XP_INT_CLEAR_MASK_OFFS);
+}
+#endif /* CONFIG_SMP */
+
static struct irq_domain_ops armada_370_xp_mpic_irq_ops = {
.map = armada_370_xp_mpic_irq_map,
.xlate = irq_domain_xlate_onecell,
@@ -91,13 +144,18 @@ static int __init armada_370_xp_mpic_of_init(struct device_node *node,
control = readl(main_int_base + ARMADA_370_XP_INT_CONTROL);
armada_370_xp_mpic_domain =
- irq_domain_add_linear(node, (control >> 2) & 0x3ff,
- &armada_370_xp_mpic_irq_ops, NULL);
+ irq_domain_add_linear(node, (control >> 2) & 0x3ff,
+ &armada_370_xp_mpic_irq_ops, NULL);
if (!armada_370_xp_mpic_domain)
panic("Unable to add Armada_370_Xp MPIC irq domain (DT)\n");
irq_set_default_host(armada_370_xp_mpic_domain);
+
+#ifdef CONFIG_SMP
+ armada_xp_mpic_smp_cpu_init();
+#endif
+
return 0;
}
@@ -111,14 +169,36 @@ asmlinkage void __exception_irq_entry armada_370_xp_handle_irq(struct pt_regs
ARMADA_370_XP_CPU_INTACK_OFFS);
irqnr = irqstat & 0x3FF;
- if (irqnr < 1023) {
- irqnr =
- irq_find_mapping(armada_370_xp_mpic_domain, irqnr);
+ if (irqnr > 1022)
+ break;
+
+ if (irqnr >= 8) {
+ irqnr = irq_find_mapping(armada_370_xp_mpic_domain,
+ irqnr);
handle_IRQ(irqnr, regs);
continue;
}
+#ifdef CONFIG_SMP
+ /* IPI Handling */
+ if (irqnr == 0) {
+ u32 ipimask, ipinr;
+
+ ipimask = readl_relaxed(per_cpu_int_base +
+ ARMADA_370_XP_IN_DRBEL_CAUSE_OFFS)
+ & 0xFF;
+
+ writel(0x0, per_cpu_int_base +
+ ARMADA_370_XP_IN_DRBEL_CAUSE_OFFS);
+
+ /* Handle all pending doorbells */
+ for (ipinr = 0; ipinr < ACTIVE_DOORBELLS; ipinr++) {
+ if (ipimask & (0x1 << ipinr))
+ handle_IPI(ipinr, regs);
+ }
+ continue;
+ }
+#endif
- break;
} while (1);
}
--
1.7.9.5
^ permalink raw reply related
* [PATCH V3 2/5] arm: mvebu: Added initial support for power managmement service unit
From: Gregory CLEMENT @ 2012-11-14 22:20 UTC (permalink / raw)
To: linux-arm-kernel
In-Reply-To: <1352931637-3405-1-git-send-email-gregory.clement@free-electrons.com>
From: Yehuda Yitschak <yehuday@marvell.com>
Signed-off-by: Yehuda Yitschak <yehuday@marvell.com>
Signed-off-by: Gregory CLEMENT <gregory.clement@free-electrons.com>
---
.../devicetree/bindings/arm/armada-370-xp-pmsu.txt | 20 ++++++
arch/arm/boot/dts/armada-xp.dtsi | 6 ++
arch/arm/mach-mvebu/Makefile | 2 +-
arch/arm/mach-mvebu/common.h | 1 +
arch/arm/mach-mvebu/pmsu.c | 75 ++++++++++++++++++++
arch/arm/mach-mvebu/pmsu.h | 16 +++++
6 files changed, 119 insertions(+), 1 deletion(-)
create mode 100644 Documentation/devicetree/bindings/arm/armada-370-xp-pmsu.txt
create mode 100644 arch/arm/mach-mvebu/pmsu.c
create mode 100644 arch/arm/mach-mvebu/pmsu.h
diff --git a/Documentation/devicetree/bindings/arm/armada-370-xp-pmsu.txt b/Documentation/devicetree/bindings/arm/armada-370-xp-pmsu.txt
new file mode 100644
index 0000000..926b4d6
--- /dev/null
+++ b/Documentation/devicetree/bindings/arm/armada-370-xp-pmsu.txt
@@ -0,0 +1,20 @@
+Power Management Service Unit(PMSU)
+-----------------------------------
+Available on Marvell SOCs: Armada 370 and Armada XP
+
+Required properties:
+
+- compatible: "marvell,armada-370-xp-pmsu"
+
+- reg: Should contain PMSU registers location and length. First pair
+ for the per-CPU SW Reset Control registers, second pair for the
+ Power Management Service Unit.
+
+Example:
+
+armada-370-xp-pmsu at d0022000 {
+ compatible = "marvell,armada-370-xp-pmsu";
+ reg = <0xd0022100 0x430>,
+ <0xd0020800 0x20>;
+};
+
diff --git a/arch/arm/boot/dts/armada-xp.dtsi b/arch/arm/boot/dts/armada-xp.dtsi
index a564b52..f521ed8 100644
--- a/arch/arm/boot/dts/armada-xp.dtsi
+++ b/arch/arm/boot/dts/armada-xp.dtsi
@@ -27,6 +27,12 @@
<0xd0021870 0x58>;
};
+ armada-370-xp-pmsu at d0022000 {
+ compatible = "marvell,armada-370-xp-pmsu";
+ reg = <0xd0022100 0x430>,
+ <0xd0020800 0x20>;
+ };
+
cpus {
#address-cells = <1>;
#size-cells = <0>;
diff --git a/arch/arm/mach-mvebu/Makefile b/arch/arm/mach-mvebu/Makefile
index abd6d3b..8e6e50b 100644
--- a/arch/arm/mach-mvebu/Makefile
+++ b/arch/arm/mach-mvebu/Makefile
@@ -2,4 +2,4 @@ ccflags-$(CONFIG_ARCH_MULTIPLATFORM) := -I$(srctree)/$(src)/include \
-I$(srctree)/arch/arm/plat-orion/include
obj-y += system-controller.o
-obj-$(CONFIG_MACH_ARMADA_370_XP) += armada-370-xp.o irq-armada-370-xp.o addr-map.o coherency.o
+obj-$(CONFIG_MACH_ARMADA_370_XP) += armada-370-xp.o irq-armada-370-xp.o addr-map.o coherency.o pmsu.o
diff --git a/arch/arm/mach-mvebu/common.h b/arch/arm/mach-mvebu/common.h
index ea08919..74ee0b2 100644
--- a/arch/arm/mach-mvebu/common.h
+++ b/arch/arm/mach-mvebu/common.h
@@ -23,4 +23,5 @@ void armada_370_xp_handle_irq(struct pt_regs *regs);
int armada_370_xp_coherency_init(void);
+int armada_370_xp_pmsu_init(void);
#endif
diff --git a/arch/arm/mach-mvebu/pmsu.c b/arch/arm/mach-mvebu/pmsu.c
new file mode 100644
index 0000000..3cc4bef
--- /dev/null
+++ b/arch/arm/mach-mvebu/pmsu.c
@@ -0,0 +1,75 @@
+/*
+ * Power Management Service Unit(PMSU) support for Armada 370/XP platforms.
+ *
+ * Copyright (C) 2012 Marvell
+ *
+ * Yehuda Yitschak <yehuday@marvell.com>
+ * Gregory Clement <gregory.clement@free-electrons.com>
+ * Thomas Petazzoni <thomas.petazzoni@free-electrons.com>
+ *
+ * This file is licensed under the terms of the GNU General Public
+ * License version 2. This program is licensed "as is" without any
+ * warranty of any kind, whether express or implied.
+ *
+ * The Armada 370 and Armada XP SOCs have a power management service
+ * unit which is responsible for powering down and waking up CPUs and
+ * other SOC units
+ */
+
+#include <linux/kernel.h>
+#include <linux/init.h>
+#include <linux/of_address.h>
+#include <linux/io.h>
+#include <linux/smp.h>
+#include <asm/smp_plat.h>
+
+static void __iomem *pmsu_mp_base;
+static void __iomem *pmsu_reset_base;
+
+#define PMSU_BOOT_ADDR_REDIRECT_OFFSET(cpu) ((cpu * 0x100) + 0x24)
+#define PMSU_RESET_CTL_OFFSET(cpu) (cpu * 0x8)
+
+static struct of_device_id of_pmsu_table[] = {
+ {.compatible = "marvell,armada-370-xp-pmsu"},
+ { /* end of list */ },
+};
+
+#ifdef CONFIG_SMP
+int armada_xp_boot_cpu(unsigned int cpu_id, void *boot_addr)
+{
+ int reg, hw_cpu;
+
+ if (!pmsu_mp_base || !pmsu_reset_base) {
+ pr_warn("Can't boot CPU. PMSU is uninitialized\n");
+ return 1;
+ }
+
+ hw_cpu = cpu_logical_map(cpu_id);
+
+ writel(virt_to_phys(boot_addr), pmsu_mp_base +
+ PMSU_BOOT_ADDR_REDIRECT_OFFSET(hw_cpu));
+
+ /* Release CPU from reset by clearing reset bit*/
+ reg = readl(pmsu_reset_base + PMSU_RESET_CTL_OFFSET(hw_cpu));
+ reg &= (~0x1);
+ writel(reg, pmsu_reset_base + PMSU_RESET_CTL_OFFSET(hw_cpu));
+
+ return 0;
+}
+#endif
+
+int __init armada_370_xp_pmsu_init(void)
+{
+ struct device_node *np;
+
+ np = of_find_matching_node(NULL, of_pmsu_table);
+ if (np) {
+ pr_info("Initializing Power Management Service Unit\n");
+ pmsu_mp_base = of_iomap(np, 0);
+ pmsu_reset_base = of_iomap(np, 1);
+ }
+
+ return 0;
+}
+
+early_initcall(armada_370_xp_pmsu_init);
diff --git a/arch/arm/mach-mvebu/pmsu.h b/arch/arm/mach-mvebu/pmsu.h
new file mode 100644
index 0000000..07a737c
--- /dev/null
+++ b/arch/arm/mach-mvebu/pmsu.h
@@ -0,0 +1,16 @@
+/*
+ * Power Management Service Unit (PMSU) support for Armada 370/XP platforms.
+ *
+ * Copyright (C) 2012 Marvell
+ *
+ * This file is licensed under the terms of the GNU General Public
+ * License version 2. This program is licensed "as is" without any
+ * warranty of any kind, whether express or implied.
+ */
+
+#ifndef __MACH_MVEBU_PMSU_H
+#define __MACH_MVEBU_PMSU_H
+
+int armada_xp_boot_cpu(unsigned int cpu_id, void *phys_addr);
+
+#endif /* __MACH_370_XP_PMSU_H */
--
1.7.9.5
^ permalink raw reply related
* [PATCH V3 1/5] arm: mvebu: Added support for coherency fabric in mach-mvebu
From: Gregory CLEMENT @ 2012-11-14 22:20 UTC (permalink / raw)
To: linux-arm-kernel
In-Reply-To: <1352931637-3405-1-git-send-email-gregory.clement@free-electrons.com>
From: Yehuda Yitschak <yehuday@marvell.com>
Signed-off-by: Yehuda Yitschak <yehuday@marvell.com>
Signed-off-by: Gregory CLEMENT <gregory.clement@free-electrons.com>
---
.../devicetree/bindings/arm/coherency-fabric.txt | 16 ++++
arch/arm/boot/dts/armada-370-xp.dtsi | 5 ++
arch/arm/mach-mvebu/Makefile | 2 +-
arch/arm/mach-mvebu/coherency.c | 89 ++++++++++++++++++++
arch/arm/mach-mvebu/coherency.h | 24 ++++++
arch/arm/mach-mvebu/common.h | 2 +
6 files changed, 137 insertions(+), 1 deletion(-)
create mode 100644 Documentation/devicetree/bindings/arm/coherency-fabric.txt
create mode 100644 arch/arm/mach-mvebu/coherency.c
create mode 100644 arch/arm/mach-mvebu/coherency.h
diff --git a/Documentation/devicetree/bindings/arm/coherency-fabric.txt b/Documentation/devicetree/bindings/arm/coherency-fabric.txt
new file mode 100644
index 0000000..2bfbf67
--- /dev/null
+++ b/Documentation/devicetree/bindings/arm/coherency-fabric.txt
@@ -0,0 +1,16 @@
+Coherency fabric
+----------------
+Available on Marvell SOCs: Armada 370 and Armada XP
+
+Required properties:
+
+- compatible: "marvell,coherency-fabric"
+- reg: Should contain,coherency fabric registers location and length.
+
+Example:
+
+coherency-fabric at d0020200 {
+ compatible = "marvell,coherency-fabric";
+ reg = <0xd0020200 0xb0>;
+};
+
diff --git a/arch/arm/boot/dts/armada-370-xp.dtsi b/arch/arm/boot/dts/armada-370-xp.dtsi
index 94b4b9e..b0d075b 100644
--- a/arch/arm/boot/dts/armada-370-xp.dtsi
+++ b/arch/arm/boot/dts/armada-370-xp.dtsi
@@ -36,6 +36,11 @@
interrupt-controller;
};
+ coherency-fabric at d0020200 {
+ compatible = "marvell,coherency-fabric";
+ reg = <0xd0020200 0xb0>;
+ };
+
soc {
#address-cells = <1>;
#size-cells = <1>;
diff --git a/arch/arm/mach-mvebu/Makefile b/arch/arm/mach-mvebu/Makefile
index 57f996b..abd6d3b 100644
--- a/arch/arm/mach-mvebu/Makefile
+++ b/arch/arm/mach-mvebu/Makefile
@@ -2,4 +2,4 @@ ccflags-$(CONFIG_ARCH_MULTIPLATFORM) := -I$(srctree)/$(src)/include \
-I$(srctree)/arch/arm/plat-orion/include
obj-y += system-controller.o
-obj-$(CONFIG_MACH_ARMADA_370_XP) += armada-370-xp.o irq-armada-370-xp.o addr-map.o
+obj-$(CONFIG_MACH_ARMADA_370_XP) += armada-370-xp.o irq-armada-370-xp.o addr-map.o coherency.o
diff --git a/arch/arm/mach-mvebu/coherency.c b/arch/arm/mach-mvebu/coherency.c
new file mode 100644
index 0000000..20a0ccc
--- /dev/null
+++ b/arch/arm/mach-mvebu/coherency.c
@@ -0,0 +1,89 @@
+/*
+ * Coherency fabric (Aurora) support for Armada 370 and XP platforms.
+ *
+ * Copyright (C) 2012 Marvell
+ *
+ * Yehuda Yitschak <yehuday@marvell.com>
+ * Gregory Clement <gregory.clement@free-electrons.com>
+ * Thomas Petazzoni <thomas.petazzoni@free-electrons.com>
+ *
+ * This file is licensed under the terms of the GNU General Public
+ * License version 2. This program is licensed "as is" without any
+ * warranty of any kind, whether express or implied.
+ *
+ * The Armada 370 and Armada XP SOCs have a coherency fabric which is
+ * responsible for ensuring hardware coherency between all CPUs and between
+ * CPUs and I/O masters. This file initializes the coherency fabric and
+ * supplies basic routines for configuring and controlling hardware coherency
+ */
+
+#include <linux/kernel.h>
+#include <linux/init.h>
+#include <linux/of_address.h>
+#include <linux/io.h>
+#include <linux/smp.h>
+#include <asm/smp_plat.h>
+#include "armada-370-xp.h"
+
+/* Some functions in this file are called very early during SMP
+ * initialization. At that time the device tree framework is not yet
+ * ready, and it is not possible to get the register address to
+ * ioremap it. That's why the pointer below is given with an initial
+ * value matching its virtual mapping
+ */
+static void __iomem *coherency_base = ARMADA_370_XP_REGS_VIRT_BASE + 0x20200;
+
+/* Coherency fabric registers */
+#define COHERENCY_FABRIC_CTL_OFFSET 0x0
+#define COHERENCY_FABRIC_CFG_OFFSET 0x4
+
+static struct of_device_id of_coherency_table[] = {
+ {.compatible = "marvell,coherency-fabric"},
+ { /* end of list */ },
+};
+#ifdef CONFIG_SMP
+int coherency_get_cpu_count(void)
+{
+ int reg, cnt;
+
+ reg = readl(coherency_base + COHERENCY_FABRIC_CFG_OFFSET);
+ cnt = (reg & 0xF) + 1;
+
+ return cnt;
+}
+#endif
+int set_cpu_coherent(unsigned int hw_cpu_id, int smp_group_id)
+{
+ int reg;
+
+ if (!coherency_base) {
+ pr_warn("Can't make CPU %d cache coherent.\n", hw_cpu_id);
+ pr_warn("Coherency fabric is not initialized\n");
+ return 1;
+ }
+
+ /* Enable the CPU in coherency fabric */
+ reg = readl(coherency_base + COHERENCY_FABRIC_CTL_OFFSET);
+ reg |= 1 << (24 + hw_cpu_id);
+ writel(reg, coherency_base + COHERENCY_FABRIC_CTL_OFFSET);
+
+ /* Add CPU to SMP group */
+ reg = readl(coherency_base + COHERENCY_FABRIC_CFG_OFFSET);
+ reg |= 1 << (16 + hw_cpu_id + (smp_group_id == 0 ? 8 : 0));
+ writel(reg, coherency_base + COHERENCY_FABRIC_CFG_OFFSET);
+
+ return 0;
+}
+
+int __init coherency_init(void)
+{
+ struct device_node *np;
+
+ np = of_find_matching_node(NULL, of_coherency_table);
+ if (np) {
+ pr_info("Initializing Coherency fabric\n");
+ coherency_base = of_iomap(np, 0);
+ }
+
+ return 0;
+}
diff --git a/arch/arm/mach-mvebu/coherency.h b/arch/arm/mach-mvebu/coherency.h
new file mode 100644
index 0000000..2f42813
--- /dev/null
+++ b/arch/arm/mach-mvebu/coherency.h
@@ -0,0 +1,24 @@
+/*
+ * arch/arm/mach-mvebu/include/mach/coherency.h
+ *
+ *
+ * Coherency fabric (Aurora) support for Armada 370 and XP platforms.
+ *
+ * Copyright (C) 2012 Marvell
+ *
+ * This file is licensed under the terms of the GNU General Public
+ * License version 2. This program is licensed "as is" without any
+ * warranty of any kind, whether express or implied.
+ */
+
+#ifndef __MACH_370_XP_COHERENCY_H
+#define __MACH_370_XP_COHERENCY_H
+
+#ifdef CONFIG_SMP
+int coherency_get_cpu_count(void);
+#endif
+
+int set_cpu_coherent(int cpu_id, int smp_group_id);
+int coherency_init(void);
+
+#endif /* __MACH_370_XP_COHERENCY_H */
diff --git a/arch/arm/mach-mvebu/common.h b/arch/arm/mach-mvebu/common.h
index 281fab3..ea08919 100644
--- a/arch/arm/mach-mvebu/common.h
+++ b/arch/arm/mach-mvebu/common.h
@@ -21,4 +21,6 @@ void mvebu_clocks_init(void);
void armada_370_xp_init_irq(void);
void armada_370_xp_handle_irq(struct pt_regs *regs);
+
+int armada_370_xp_coherency_init(void);
#endif
--
1.7.9.5
^ permalink raw reply related
* [PATCH V3 0/5] SMP support for Armada XP
From: Gregory CLEMENT @ 2012-11-14 22:20 UTC (permalink / raw)
To: linux-arm-kernel
Hello,
The purpose of this patch set is to add the SMP support for the Armada
XP SoCs. Beside the SMP support itself brought by the last 3 patches,
this patch set also adds the support for the coherency fabric unit and
the power management service unit.
The coherency fabric is responsible for ensuring hardware coherency
between all CPUs and between CPUs and I/O masters. This unit is also
available for Armada 370 and will be used in an incoming patch set
for hardware I/O cache coherency.
The power management service unit is responsible for powering down and
waking up CPUs and other SOC units.
The original code is from Yehuda Yitschak, it was reworked by myself
and reviewed by Yehuda.
This patch set is based on 3.7-rc5 and depends one the framework clock
support which should be being included in the marvell branch
maintained by Jason Cooper. The git branch called
ArmadaXP-SMP-for-3.8-V3 is also available at
https://github.com/MISL-EBU-System-SW/mainline-public.git.
Changelog:
V2 -> V3:
- Rebased on to v3.7-rc5
- removed the unnecessary used of __iomem flag for a pointer to a
function. the second parameter of armada_xp_boot_cpu is now just a
void *.
- removed the dsb() call in armada_xp_boot_cpu(), as the following
writel calls dsb if needed.
- Change the PJ4B mask for proc_info in arch/arm/mm/proc-v7.S to be
less restrictive, the last 4 bits contain revision information
- Merge the multiple 'or' instruction in a single instruction in
__v7_pj4b_setup
V1 -> V2:
- Rebased on to v3.7-rc3
- Fixed typos found by Alexandre Belloni
- Added clk_prepare_enable() before getting rate clk in
set_secondary_cpus_clock()
- Add explanation in the binding documentation about the per-CPU
interrupt registers: the address of the virtual register must be
used.
- Removed the armada_xp prefix in the coherency.c file to be more
compliant with the name convention of the other files.
- Coherency_init is now called from armada_370_xp_dt_init() and is no
more an early_init() call. As the device tree is not available from
an early_init(), it was useless to call coherency_init() so
early. The need to be able to call some function very early during
the boot were already resolved by using the hard code address of the
register.
Yehuda Yitschak (5):
arm: mvebu: Added support for coherency fabric in mach-mvebu
arm: mvebu: Added initial support for power managmement service unit
arm: mvebu: Added IPI support via doorbells
arm: mm: Added support for PJ4B cpu and init routines
arm: mvebu: Added SMP support for Armada XP
.../devicetree/bindings/arm/armada-370-xp-mpic.txt | 12 +-
.../devicetree/bindings/arm/armada-370-xp-pmsu.txt | 20 ++++
.../devicetree/bindings/arm/coherency-fabric.txt | 16 +++
arch/arm/boot/dts/armada-370-xp.dtsi | 5 +
arch/arm/boot/dts/armada-xp.dtsi | 12 +-
arch/arm/configs/mvebu_defconfig | 3 +
arch/arm/mach-mvebu/Kconfig | 3 +-
arch/arm/mach-mvebu/Makefile | 4 +-
arch/arm/mach-mvebu/armada-370-xp.c | 3 +
arch/arm/mach-mvebu/armada-370-xp.h | 10 ++
arch/arm/mach-mvebu/coherency.c | 89 ++++++++++++++
arch/arm/mach-mvebu/coherency.h | 24 ++++
arch/arm/mach-mvebu/common.h | 6 +
arch/arm/mach-mvebu/headsmp.S | 66 +++++++++++
arch/arm/mach-mvebu/hotplug.c | 30 +++++
arch/arm/mach-mvebu/irq-armada-370-xp.c | 92 ++++++++++++++-
arch/arm/mach-mvebu/platsmp.c | 124 ++++++++++++++++++++
arch/arm/mach-mvebu/pmsu.c | 75 ++++++++++++
arch/arm/mach-mvebu/pmsu.h | 16 +++
arch/arm/mm/Kconfig | 4 +
arch/arm/mm/proc-v7.S | 51 ++++++++
21 files changed, 653 insertions(+), 12 deletions(-)
create mode 100644 Documentation/devicetree/bindings/arm/armada-370-xp-pmsu.txt
create mode 100644 Documentation/devicetree/bindings/arm/coherency-fabric.txt
create mode 100644 arch/arm/mach-mvebu/coherency.c
create mode 100644 arch/arm/mach-mvebu/coherency.h
create mode 100644 arch/arm/mach-mvebu/headsmp.S
create mode 100644 arch/arm/mach-mvebu/hotplug.c
create mode 100644 arch/arm/mach-mvebu/platsmp.c
create mode 100644 arch/arm/mach-mvebu/pmsu.c
create mode 100644 arch/arm/mach-mvebu/pmsu.h
--
1.7.9.5
^ permalink raw reply
* [PATCH v3 11/11] ARM: Exynos: add support for mct clock setup
From: Thomas Abraham @ 2012-11-14 22:07 UTC (permalink / raw)
To: linux-arm-kernel
In-Reply-To: <1352930853-12268-1-git-send-email-thomas.abraham@linaro.org>
Add support for mct clock lookup and setup to ensure that the mct clock
is has been turned on.
Cc: Kukjin Kim <kgene.kim@samsung.com>
Signed-off-by: Thomas Abraham <thomas.abraham@linaro.org>
---
arch/arm/mach-exynos/mct.c | 7 ++++++-
1 files changed, 6 insertions(+), 1 deletions(-)
diff --git a/arch/arm/mach-exynos/mct.c b/arch/arm/mach-exynos/mct.c
index 47bc6b35..09815a9 100644
--- a/arch/arm/mach-exynos/mct.c
+++ b/arch/arm/mach-exynos/mct.c
@@ -489,7 +489,12 @@ static struct local_timer_ops exynos4_mct_tick_ops __cpuinitdata = {
static void __init exynos4_timer_resources(struct device_node *np)
{
- struct clk *tick_clk;
+ struct clk *mct_clk, *tick_clk;
+
+ mct_clk = clk_get(NULL, "mct");
+ if (IS_ERR(mct_clk))
+ panic("%s: unable to retrieve mct clock instance\n", __func__);
+ clk_prepare_enable(mct_clk);
tick_clk = clk_get(NULL, "fin_pll");
if (IS_ERR(tick_clk))
--
1.7.4.4
^ permalink raw reply related
* [PATCH v3 10/11] ARM: Exynos: use fin_pll clock as the tick clock source for mct
From: Thomas Abraham @ 2012-11-14 22:07 UTC (permalink / raw)
To: linux-arm-kernel
In-Reply-To: <1352930853-12268-1-git-send-email-thomas.abraham@linaro.org>
With the migration of Exynos4 clocks to use common clock framework, the old
styled 'xtal' clock is not used anymore. Instead, the clock 'fin_pll' is used
as the tick clock for mct controller.
Cc: Kukjin Kim <kgene.kim@samsung.com>
Signed-off-by: Thomas Abraham <thomas.abraham@linaro.org>
---
arch/arm/mach-exynos/mct.c | 8 +++++---
1 files changed, 5 insertions(+), 3 deletions(-)
diff --git a/arch/arm/mach-exynos/mct.c b/arch/arm/mach-exynos/mct.c
index cd061b2..47bc6b35 100644
--- a/arch/arm/mach-exynos/mct.c
+++ b/arch/arm/mach-exynos/mct.c
@@ -489,10 +489,12 @@ static struct local_timer_ops exynos4_mct_tick_ops __cpuinitdata = {
static void __init exynos4_timer_resources(struct device_node *np)
{
- struct clk *mct_clk;
- mct_clk = clk_get(NULL, "xtal");
+ struct clk *tick_clk;
- clk_rate = clk_get_rate(mct_clk);
+ tick_clk = clk_get(NULL, "fin_pll");
+ if (IS_ERR(tick_clk))
+ panic("%s: unable to determine tick clock rate\n", __func__);
+ clk_rate = clk_get_rate(tick_clk);
reg_base = (np) ? of_iomap(np, 0) : S5P_VA_SYSTIMER;
if (!reg_base)
--
1.7.4.4
^ permalink raw reply related
* [PATCH v3 09/11] ARM: Exynos4: remove auxdata table from machine file
From: Thomas Abraham @ 2012-11-14 22:07 UTC (permalink / raw)
To: linux-arm-kernel
In-Reply-To: <1352930853-12268-1-git-send-email-thomas.abraham@linaro.org>
With support for device tree based clock lookup now available, remove the
auxdata table from exynos4 dt-enabled machine file.
Cc: Kukjin Kim <kgene.kim@samsung.com>
Signed-off-by: Thomas Abraham <thomas.abraham@linaro.org>
---
arch/arm/mach-exynos/mach-exynos4-dt.c | 68 +-------------------------------
1 files changed, 2 insertions(+), 66 deletions(-)
diff --git a/arch/arm/mach-exynos/mach-exynos4-dt.c b/arch/arm/mach-exynos/mach-exynos4-dt.c
index 059332e..8e72ab7 100644
--- a/arch/arm/mach-exynos/mach-exynos4-dt.c
+++ b/arch/arm/mach-exynos/mach-exynos4-dt.c
@@ -11,77 +11,14 @@
* published by the Free Software Foundation.
*/
+#include <linux/kernel.h>
#include <linux/of_platform.h>
-#include <linux/serial_core.h>
#include <asm/mach/arch.h>
#include <asm/hardware/gic.h>
-#include <mach/map.h>
-
-#include <plat/cpu.h>
-#include <plat/regs-serial.h>
#include "common.h"
-/*
- * The following lookup table is used to override device names when devices
- * are registered from device tree. This is temporarily added to enable
- * device tree support addition for the Exynos4 architecture.
- *
- * For drivers that require platform data to be provided from the machine
- * file, a platform data pointer can also be supplied along with the
- * devices names. Usually, the platform data elements that cannot be parsed
- * from the device tree by the drivers (example: function pointers) are
- * supplied. But it should be noted that this is a temporary mechanism and
- * at some point, the drivers should be capable of parsing all the platform
- * data from the device tree.
- */
-static const struct of_dev_auxdata exynos4_auxdata_lookup[] __initconst = {
- OF_DEV_AUXDATA("samsung,exynos4210-uart", EXYNOS4_PA_UART0,
- "exynos4210-uart.0", NULL),
- OF_DEV_AUXDATA("samsung,exynos4210-uart", EXYNOS4_PA_UART1,
- "exynos4210-uart.1", NULL),
- OF_DEV_AUXDATA("samsung,exynos4210-uart", EXYNOS4_PA_UART2,
- "exynos4210-uart.2", NULL),
- OF_DEV_AUXDATA("samsung,exynos4210-uart", EXYNOS4_PA_UART3,
- "exynos4210-uart.3", NULL),
- OF_DEV_AUXDATA("samsung,exynos4210-sdhci", EXYNOS4_PA_HSMMC(0),
- "exynos4-sdhci.0", NULL),
- OF_DEV_AUXDATA("samsung,exynos4210-sdhci", EXYNOS4_PA_HSMMC(1),
- "exynos4-sdhci.1", NULL),
- OF_DEV_AUXDATA("samsung,exynos4210-sdhci", EXYNOS4_PA_HSMMC(2),
- "exynos4-sdhci.2", NULL),
- OF_DEV_AUXDATA("samsung,exynos4210-sdhci", EXYNOS4_PA_HSMMC(3),
- "exynos4-sdhci.3", NULL),
- OF_DEV_AUXDATA("samsung,s3c2440-i2c", EXYNOS4_PA_IIC(0),
- "s3c2440-i2c.0", NULL),
- OF_DEV_AUXDATA("samsung,s3c2440-i2c", EXYNOS4_PA_IIC(1),
- "s3c2440-i2c.1", NULL),
- OF_DEV_AUXDATA("samsung,s3c2440-i2c", EXYNOS4_PA_IIC(2),
- "s3c2440-i2c.2", NULL),
- OF_DEV_AUXDATA("samsung,s3c2440-i2c", EXYNOS4_PA_IIC(3),
- "s3c2440-i2c.3", NULL),
- OF_DEV_AUXDATA("samsung,s3c2440-i2c", EXYNOS4_PA_IIC(4),
- "s3c2440-i2c.4", NULL),
- OF_DEV_AUXDATA("samsung,s3c2440-i2c", EXYNOS4_PA_IIC(5),
- "s3c2440-i2c.5", NULL),
- OF_DEV_AUXDATA("samsung,s3c2440-i2c", EXYNOS4_PA_IIC(6),
- "s3c2440-i2c.6", NULL),
- OF_DEV_AUXDATA("samsung,s3c2440-i2c", EXYNOS4_PA_IIC(7),
- "s3c2440-i2c.7", NULL),
- OF_DEV_AUXDATA("samsung,exynos4210-spi", EXYNOS4_PA_SPI0,
- "exynos4210-spi.0", NULL),
- OF_DEV_AUXDATA("samsung,exynos4210-spi", EXYNOS4_PA_SPI1,
- "exynos4210-spi.1", NULL),
- OF_DEV_AUXDATA("samsung,exynos4210-spi", EXYNOS4_PA_SPI2,
- "exynos4210-spi.2", NULL),
- OF_DEV_AUXDATA("arm,pl330", EXYNOS4_PA_PDMA0, "dma-pl330.0", NULL),
- OF_DEV_AUXDATA("arm,pl330", EXYNOS4_PA_PDMA1, "dma-pl330.1", NULL),
- OF_DEV_AUXDATA("samsung,exynos4210-tmu", EXYNOS4_PA_TMU,
- "exynos-tmu", NULL),
- {},
-};
-
static void __init exynos4_dt_map_io(void)
{
exynos_init_io(NULL, 0);
@@ -89,8 +26,7 @@ static void __init exynos4_dt_map_io(void)
static void __init exynos4_dt_machine_init(void)
{
- of_platform_populate(NULL, of_default_bus_match_table,
- exynos4_auxdata_lookup, NULL);
+ of_platform_populate(NULL, of_default_bus_match_table, NULL, NULL);
}
static char const *exynos4_dt_compat[] __initdata = {
--
1.7.4.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