Linux-ARM-Kernel Archive on lore.kernel.org
 help / color / mirror / Atom feed
* [PATCH v2 4/5] ARM: init: add support for reserved memory defined by device tree
From: Marek Szyprowski @ 2014-02-11 10:52 UTC (permalink / raw)
  To: linux-arm-kernel
In-Reply-To: <20140210215929.4473BC408F7@trevor.secretlab.ca>


On 2014-02-10 22:59, Grant Likely wrote:
> On Thu, 06 Feb 2014 14:26:13 +0100, Marek Szyprowski <m.szyprowski@samsung.com> wrote:
> > Hello,
> >
> > On 2014-02-05 11:15, Grant Likely wrote:
> > > On Tue, 04 Feb 2014 13:09:32 +0100, Marek Szyprowski <m.szyprowski@samsung.com> wrote:
> > > > Enable reserved memory initialization from device tree.
> > > >
> > > > Cc: Benjamin Herrenschmidt <benh@kernel.crashing.org>
> > > > Cc: Laura Abbott <lauraa@codeaurora.org>
> > > > Signed-off-by: Marek Szyprowski <m.szyprowski@samsung.com>
> > > > ---
> > > >  arch/arm/mm/init.c |    3 +++
> > > >  1 file changed, 3 insertions(+)
> > > >
> > > > diff --git a/arch/arm/mm/init.c b/arch/arm/mm/init.c
> > > > index 804d61566a53..ebafdb479410 100644
> > > > --- a/arch/arm/mm/init.c
> > > > +++ b/arch/arm/mm/init.c
> > > > @@ -17,6 +17,7 @@
> > > >  #include <linux/nodemask.h>
> > > >  #include <linux/initrd.h>
> > > >  #include <linux/of_fdt.h>
> > > > +#include <linux/of_reserved_mem.h>
> > > >  #include <linux/highmem.h>
> > > >  #include <linux/gfp.h>
> > > >  #include <linux/memblock.h>
> > > > @@ -323,6 +324,8 @@ void __init arm_memblock_init(struct meminfo *mi,
> > > >  	if (mdesc->reserve)
> > > >  		mdesc->reserve();
> > > >
> > > > +	early_init_dt_scan_reserved_mem();
> > > > +
> > >
> > > The new binding is being made fundamental. If the reserved-memory node
> > > is present, then it needs to be honored, even if the kernel doesn't know
> > > how to use the regions. Therefore, This needs to be unconditional for
> > > all architectures. The hook should be called in early_init_dt_scan()
> > > (drivers/of/fdt.c) immediately after the early_init_dt_scan_memory()
> > > hook.
> >
> > In theory this will be the best solution, but it practice there is a
> > problem. early_init_dt_scan() is called as the first function from kernel
> > booting code. That time there is no memory yet added to the system, so it
> > would be really hard to reserve anything. Memory nodes are being added
> > later either with memblock_add() or by some other arch specific way.
>
> Hmmm, depends on the architecture. On ARM the memory is loaded into the
> meminfo structure first, and it isn't until arm_memblock_init() that
> memblock_add() gets called on all the regions. Some architectures do the
> memblock_add() directly from early_init_dt_add_memory_arch() function.
>
> The default early_init_dt_add_memory_arch() in drivers/of/fdt.c is
> overridden by ARM and a number of other architectures. However...
>
> > Finally, once all memory has been added to the system we can parse and
> > reserve all regions defined in the device tree. This really requires
> > creating another function which will be called by arch specific code.
>
> ...Or it means getting rid of meminfo entirely so that memblock is
> available earlier. Laura Abbott has just posted v2 of her series to do
> exactly that. If you base on that then you should be able to do exactly
> what I suggested.

I've checked Laura's patches and in fact it is possible to do memory
reservation as a last step in early_init_dt_scan_memory(). However still
see some problem which I have no idea how to resolve. Right now I focus
only on ARM, so I have no idea how it is solved by other architectures.
On of the key features of the new binding is the ability to automatically
allocate reserved regions of the given size. However kernel, initrd, dt
and other sub-arch specific critical regions are marked/allocated in
arm_memblock_init(), which is called after setup_machine_fdt(). This
might lead to some serious failures when automatically reserved region
overlaps with some critical resources. Do you have any idea how to solve
this without a new callback?

Best regards
-- 
Marek Szyprowski, PhD
Samsung R&D Institute Poland

^ permalink raw reply

* [PATCH RESEND] arm: add DSB after icache flush in __flush_icache_all()
From: Catalin Marinas @ 2014-02-11 10:52 UTC (permalink / raw)
  To: linux-arm-kernel
In-Reply-To: <1392109811-8525-1-git-send-email-vkale@apm.com>

On Tue, Feb 11, 2014 at 09:10:11AM +0000, Vinayak Kale wrote:
> Add DSB after icache flush to complete the cache maintenance operation.
> 
> Signed-off-by: Vinayak Kale <vkale@apm.com>
> Acked-by: Catalin Marinas <catalin.marinas@arm.com>

I guess what you need to do is add:

Cc: <stable@vger.kernel.org>

and send the patch to Russell's patch system (and add any other acks you
may get in the meantime).

-- 
Catalin

^ permalink raw reply

* [RFC/PATCH v2] ARM: vDSO gettimeofday using generic timer architecture
From: Will Deacon @ 2014-02-11 10:45 UTC (permalink / raw)
  To: linux-arm-kernel
In-Reply-To: <52F9675F.1040403@mentor.com>

On Mon, Feb 10, 2014 at 11:57:19PM +0000, Nathan Lynch wrote:
> On 02/09/2014 04:20 AM, Russell King - ARM Linux wrote:
> > On Fri, Feb 07, 2014 at 05:05:49PM -0600, Nathan Lynch wrote:
> >> +	/* Grab the vDSO code pages. */
> >> +	for (i = 0; i < vdso_pages; i++) {
> >> +		pg = virt_to_page(&vdso_start + i*PAGE_SIZE);
> >> +		ClearPageReserved(pg);
> >> +		get_page(pg);
> >> +		vdso_pagelist[i] = pg;
> >> +	}
> > 
> > Why do we want to clear the reserved status?  This looks over complicated
> > to me.
> > 
> >> +
> >> +	/* Sanity check the shared object header. */
> >> +	vbase = vmap(vdso_pagelist, 1, 0, PAGE_KERNEL);
> >> +	if (vbase == NULL) {
> >> +		pr_err("Failed to map vDSO pagelist!\n");
> >> +		return -ENOMEM;
> >> +	} else if (memcmp(vbase, "\177ELF", 4)) {
> >> +		pr_err("vDSO is not a valid ELF object!\n");
> >> +		ret = -EINVAL;
> >> +		goto unmap;
> >> +	}
> > 
> > Why do we need to vmap() pages which are already accessible - vdso_start
> > must be part of the kernel image, and therefore will be accessible via
> > standard mappings.
> 
> Right, this stuff doesn't appear to be necessary.  Removed the vmap,
> get_page, and ClearPageReserved calls for v3.

Can you make the corresponding change for arm64 too, please?

> >> +static long clock_gettime_fallback(clockid_t _clkid, struct timespec *_ts)
> >> +{
> >> +	register struct timespec *ts asm("r1") = _ts;
> >> +	register clockid_t clkid asm("r0") = _clkid;
> >> +	register long ret asm ("r0");
> >> +	register long nr asm("r7") = __NR_clock_gettime;
> >> +
> >> +	asm("swi #0" : "=r" (ret) : "r" (clkid), "r" (ts), "r" (nr) : "memory");

Might be worth making this volatile, rather than depend on the use of ret.

Also, placing both _clkid and ret into "r0" worries me slightly -- is GCC
smart enough to realise that writing to ret kills _clkid?

Will

^ permalink raw reply

* [PATCH 2/3] PCI: ARM: add support for virtual PCI host controller
From: Arnd Bergmann @ 2014-02-11 10:42 UTC (permalink / raw)
  To: linux-arm-kernel
In-Reply-To: <20140210173450.GA5554@obsidianresearch.com>

On Monday 10 February 2014 10:34:50 Jason Gunthorpe wrote:

> I noticed this on mvebu as well..
> 
> 3.13 w/ mvebu driver:
> 
> e0001000-e0001fff : /mbus/pex at e0000000/pcie at 1,0/fpga at 0/fpga_sysmon at 1000
> e0006000-e0006fff : /mbus/pex at e0000000/pcie at 1,0/fpga at 0/qdr2p at 6000
> 
> 3.10 w/ old kirkwood driver:
> 
> e0000000-e7ffffff : PCIe 0 MEM
>   e0000000-e001ffff : 0000:00:01.0
>     e0001000-e0001fff : /mbus/pex at e0000000/pcie at 1,0/fpga at 0/fpga_sysmon at 1000
>     e0006000-e0006fff : /mbus/pex at e0000000/pcie at 1,0/fpga at 0/qdr2p at 6000
> 
> The latter is obviously correct and matches x86. I'm not sure where
> the new style host drivers are going wrong, even the resource that
> should be added by the PCI core itself for the BAR is missing..

I looked briefly at the code and found that mach-kirkwood/pcie.c does
both request_resource() and pci_add_resource_offset(), while
drivers/pci/host/pci-mvebu.c only does the latter. Does the patch
below restore the previous behavior?

Since the mvebu_pcie_setup() function seems very generic at this,
we should probably try to factor out that code into a common
helper, at least for arm64, but ideally shared with arm32
as well.

	Arnd

diff --git a/drivers/pci/host/pci-mvebu.c b/drivers/pci/host/pci-mvebu.c
index 13478ec..b55e9a6 100644
--- a/drivers/pci/host/pci-mvebu.c
+++ b/drivers/pci/host/pci-mvebu.c
@@ -680,9 +680,17 @@ static int mvebu_pcie_setup(int nr, struct pci_sys_data *sys)
 	struct mvebu_pcie *pcie = sys_to_pcie(sys);
 	int i;
 
-	if (resource_size(&pcie->realio) != 0)
+	if (request_resource(&iomem_resource, &pcie->mem))
+		return 0;
+
+	if (resource_size(&pcie->realio) != 0) {
+		if (request_resource(&ioport_resource, &pcie->realio)) {
+			release_resource(&pcie->mem);
+			return 0;
+		}
 		pci_add_resource_offset(&sys->resources, &pcie->realio,
 					sys->io_offset);
+	}
 	pci_add_resource_offset(&sys->resources, &pcie->mem, sys->mem_offset);
 	pci_add_resource(&sys->resources, &pcie->busn);
 

^ permalink raw reply related

* [PATCH] ARM: mm: support big-endian page tables
From: Ben Dooks @ 2014-02-11 10:40 UTC (permalink / raw)
  To: linux-arm-kernel
In-Reply-To: <52F9EB40.1030703@huawei.com>

On 11/02/14 09:20, Jianguo Wu wrote:
> When enable LPAE and big-endian in a hisilicon board, while specify
> mem=384M mem=512M at 7680M, will get bad page state:
>
> Freeing unused kernel memory: 180K (c0466000 - c0493000)
> BUG: Bad page state in process init  pfn:fa442
> page:c7749840 count:0 mapcount:-1 mapping:  (null) index:0x0
> page flags: 0x40000400(reserved)
> Modules linked in:
> CPU: 0 PID: 1 Comm: init Not tainted 3.10.27+ #66
> [<c000f5f0>] (unwind_backtrace+0x0/0x11c) from [<c000cbc4>] (show_stack+0x10/0x14)
> [<c000cbc4>] (show_stack+0x10/0x14) from [<c009e448>] (bad_page+0xd4/0x104)
> [<c009e448>] (bad_page+0xd4/0x104) from [<c009e520>] (free_pages_prepare+0xa8/0x14c)
> [<c009e520>] (free_pages_prepare+0xa8/0x14c) from [<c009f8ec>] (free_hot_cold_page+0x18/0xf0)
> [<c009f8ec>] (free_hot_cold_page+0x18/0xf0) from [<c00b5444>] (handle_pte_fault+0xcf4/0xdc8)
> [<c00b5444>] (handle_pte_fault+0xcf4/0xdc8) from [<c00b6458>] (handle_mm_fault+0xf4/0x120)
> [<c00b6458>] (handle_mm_fault+0xf4/0x120) from [<c0013754>] (do_page_fault+0xfc/0x354)
> [<c0013754>] (do_page_fault+0xfc/0x354) from [<c0008400>] (do_DataAbort+0x2c/0x90)
> [<c0008400>] (do_DataAbort+0x2c/0x90) from [<c0008fb4>] (__dabt_usr+0x34/0x40)
>
> The bad pfn:fa442 is not system memory(mem=384M mem=512M at 7680M), after debugging,
> I find in page fault handler, will get wrong pfn from pte just after set pte,
> as follow:
> do_anonymous_page()
> {
> 	...
> 	set_pte_at(mm, address, page_table, entry);
> 	
> 	//debug code
> 	pfn = pte_pfn(entry);
> 	pr_info("pfn:0x%lx, pte:0x%llx\n", pfn, pte_val(entry));
>
> 	//read out the pte just set
> 	new_pte = pte_offset_map(pmd, address);
> 	new_pfn = pte_pfn(*new_pte);
> 	pr_info("new pfn:0x%lx, new pte:0x%llx\n", pfn, pte_val(entry));
> 	...
> }

Thanks, must have missed tickling this one.

>
> pfn:   0x1fa4f5,     pte:0xc00001fa4f575f
> new_pfn:0xfa4f5, new_pte:0xc00000fa4f5f5f	//new pfn/pte is wrong.
>
> The bug is happened in cpu_v7_set_pte_ext(ptep, pte):
> when pte is 64-bit, for little-endian, will store low 32-bit in r2,
> high 32-bit in r3; for big-endian, will store low 32-bit in r3,
> high 32-bit in r2, this will cause wrong pfn stored in pte,
> so we should exchange r2 and r3 for big-endian.
>
> Signed-off-by: Jianguo Wu <wujianguo@huawei.com>
> ---
>   arch/arm/mm/proc-v7-3level.S |   10 ++++++++++
>   1 files changed, 10 insertions(+), 0 deletions(-)
>
> diff --git a/arch/arm/mm/proc-v7-3level.S b/arch/arm/mm/proc-v7-3level.S
> index 6ba4bd9..71b3892 100644
> --- a/arch/arm/mm/proc-v7-3level.S
> +++ b/arch/arm/mm/proc-v7-3level.S
> @@ -65,6 +65,15 @@ ENDPROC(cpu_v7_switch_mm)
>    */
>   ENTRY(cpu_v7_set_pte_ext)
>   #ifdef CONFIG_MMU
> +#ifdef CONFIG_CPU_ENDIAN_BE8
> +	tst	r3, #L_PTE_VALID
> +	beq	1f
> +	tst	r2, #1 << (57 - 32)		@ L_PTE_NONE
> +	bicne	r3, #L_PTE_VALID
> +	bne	1f
> +	tst	r2, #1 << (55 - 32)		@ L_PTE_DIRTY
> +	orreq	r3, #L_PTE_RDONLY
> +#else
>   	tst	r2, #L_PTE_VALID
>   	beq	1f
>   	tst	r3, #1 << (57 - 32)		@ L_PTE_NONE
> @@ -72,6 +81,7 @@ ENTRY(cpu_v7_set_pte_ext)
>   	bne	1f
>   	tst	r3, #1 << (55 - 32)		@ L_PTE_DIRTY
>   	orreq	r2, #L_PTE_RDONLY
> +#endif
>   1:	strd	r2, r3, [r0]
>   	ALT_SMP(W(nop))
>   	ALT_UP (mcr	p15, 0, r0, c7, c10, 1)		@ flush_pte
> -- 1.7.1

If possible can we avoid large #ifdef blocks here?

Two ideas are

ARM_LE(tst r2, #L_PTE_VALID)
ARM_BE(tst r3, #L_PTE_VALID)

or change r2, r3 pair to say rlow, rhi and

#ifdef  CONFIG_CPU_ENDIAN_BE8
#define rlow r3
#define rhi r2
#else
#define rlow r2
#define rhi r3
#endif



-- 
Ben Dooks				http://www.codethink.co.uk/
Senior Engineer				Codethink - Providing Genius

^ permalink raw reply

* [PATCH 1/4] arm64: topology: Implement basic CPU topology support
From: Will Deacon @ 2014-02-11 10:34 UTC (permalink / raw)
  To: linux-arm-kernel
In-Reply-To: <CAKfTPtDih6n5ckhXUgNKrbw5EFt45uuQFFPKB2aN0NGGG96Pmg@mail.gmail.com>

On Tue, Feb 11, 2014 at 08:15:19AM +0000, Vincent Guittot wrote:
> On 10 February 2014 17:46, Mark Brown <broonie@kernel.org> wrote:
> > On Mon, Feb 10, 2014 at 04:22:31PM +0000, Catalin Marinas wrote:
> >> On Mon, Feb 10, 2014 at 01:02:01PM +0000, Mark Brown wrote:
> >
> >> > +           if (cpu != cpuid)
> >> > +                   cpumask_set_cpu(cpu, &cpuid_topo->thread_sibling);
> >> > +   }
> >> > +   smp_wmb();
> >
> >> I now noticed there are a couple of smp_wmb() calls in this patch. What
> >> are they for?
> >
> > To be honest I mostly cargo culted them from the ARM implementation; I
> > did look a bit but didn't fully dig into it - it seemed they were
> > required to ensure that the updates for the new CPU are visible over all
> > CPUs.  Vincent?
> 
> Yes that's it. we must ensure that updates are made visible to other CPUs

In relation to what? The smp_* barriers ensure ordering of observability
between a number of independent accesses, so you must be ensuring
ordering against something else. Also, you need to guarantee ordering on the
read-side too -- how is this achieved? I can't see any smp_rmb calls from a
quick grep, so I assume you're making use of address dependencies?

/confused

Will

^ permalink raw reply

* [PATCH v9 2/4] ehci-platform: Add support for clks and phy passed through devicetree
From: Hans de Goede @ 2014-02-11 10:13 UTC (permalink / raw)
  To: linux-arm-kernel
In-Reply-To: <52F9F4C6.6080201@ti.com>

Hi,

On 02/11/2014 11:00 AM, Roger Quadros wrote:
> On 02/11/2014 11:31 AM, Hans de Goede wrote:
>> Hi,
>>
>> On 02/11/2014 10:12 AM, Roger Quadros wrote:
>>> Hi Hans,
>>>
>>> On 02/07/2014 05:36 PM, Hans de Goede wrote:
>>>> Currently ehci-platform is only used in combination with devicetree when used
>>>> with some Via socs. By extending it to (optionally) get clks and a phy from
>>>> devicetree, and enabling / disabling those on power_on / off, it can be used
>>>> more generically. Specifically after this commit it can be used for the
>>>> ehci controller on Allwinner sunxi SoCs.
>>>>
>>>> Since ehci-platform is intended to handle any generic enough non pci ehci
>>>> device, add a "usb-ehci" compatibility string.
>>>>
>>>> There already is a usb-ehci device-tree bindings document, update this
>>>> with clks and phy bindings info.
>>>>
>>>> Although actually quite generic so far the via,vt8500 compatibilty string
>>>> had its own bindings document. Somehow we even ended up with 2 of them. Since
>>>> these provide no extra information over the generic usb-ehci documentation,
>>>> this patch removes them.
>>>>
>>>> The ehci-ppc-of.c driver also claims the usb-ehci compatibility string,
>>>> even though it mostly is ibm,usb-ehci-440epx specific. ehci-platform.c is
>>>> not needed on ppc platforms, so add a !PPC_OF dependency to it to avoid
>>>> 2 drivers claiming the same compatibility string getting build on ppc.
>>>>
>>>
>>> This breaks all OMAP platforms on linux-next for the exact same reason. see [1].
>>>
>>> ./arch/arm/boot/dts/omap4.dtsi:				compatible = "ti,ehci-omap", "usb-ehci";
>>> ./arch/arm/boot/dts/omap3.dtsi:				compatible = "ti,ehci-omap", "usb-ehci";
>>> ./arch/arm/boot/dts/omap5.dtsi:				compatible = "ti,ehci-omap", "usb-ehci";
>>
>> That should not be the case, the driver core should try to find a driver matching
>> the compatibility string from left to right, or in other words from most specific
>> to least specific. This is part of the whole devicetree design.
>>
>> So as long as the driver claiming "ti,ehci-omap" is available at probe time that
>> one should get used and things should work fine. Now if ehci-platform is built-in
>> and ehci-omap is a module, then I guess one could see the described breakage.
>>
>> If the driver is built-in and things are not working, then we will need to do some
>> debugging as to why the left to right matching is not working as expected.
> 
> Both ehci_platform and ehci_omap were built-in and still the ehci_platform driver got
> probe preference. So it looks like the left to right compatible list priority probing
> feature doesn't work.

Oops, I guess nothing relies on it sofar. Well we could go and debug and fix this but...

> 
>>
>> I must admit I'm not sure what happens if both are a module, the kernel direct
>> module load will likely fail due to lack of a rootfs at that point, and then
>> the module will later get loaded by udev I assume, at which point there are no
>> loading ordering guarantees.
>>
>> The easiest solution to ensure that "ti,ehci-omap" is available at probe time
>> (if enabled) seems to be to change USB_EHCI_HCD_OMAP to a boolean.
> 
> That is a limitation I don't like to have for USB_EHCI_HCD_OMAP.

I completely understand, thinking more about this I'm simply going to change the
compatibility string for ohci- and ehci-platform to be "ohci-platform" resp.
"ehci-platform". I know there are some people who don't like the -platform
suffix, but though luck, as the above clearly shows using the generic "usb-ohci" /
"usb-ehci" they were advocating for leads to a ton of issues, and we already
have a precedent for ?hci-platform in the form of "xhci-platform".

Regards,

Hans

^ permalink raw reply

* [linux-sunxi] Re: [PATCH 1/3] mfd: axp20x: Add mfd driver for axp20x PMIC
From: Lee Jones @ 2014-02-11 10:08 UTC (permalink / raw)
  To: linux-arm-kernel
In-Reply-To: <CAOQ7t2ZWneDDrqpBQTWpmUozK8Pu4Ri97FX4E2R9NK72XECtaw@mail.gmail.com>

> >> >> +     axp20x->i2c_client = i2c;
> >> >> +     i2c_set_clientdata(i2c, axp20x);
> >> >> +
> >> >> +     axp20x->dev = &i2c->dev;
> >> >> +     dev_set_drvdata(axp20x->dev, axp20x);
> >> >
> >> > Do you make use of all this saving of the device container?
> >> >
> >> > If so, where?
> >>
> >> In the drivers for subsystems (input, regulators, gpio, etc..)
> >
> > Can you link me to the patches please?  Any reason why they're not in
> > this set?  By submitting them together you give the Maintainers a good
> > over-view on how the system works together.
> 
> I wasn't sure it was a good idea to submit all the drivers altogether,
> so my idea was to submit one driver at a time.
> Do you think is it better to submit all the subsystems in one patch-set?

Normally.

-- 
Lee Jones
Linaro STMicroelectronics Landing Team Lead
Linaro.org ? Open source software for ARM SoCs
Follow Linaro: Facebook | Twitter | Blog

^ permalink raw reply

* [PATCH V2 2/3] ARM: dts: add dts files for exynos5260 SoC
From: Tomasz Figa @ 2014-02-11 10:04 UTC (permalink / raw)
  To: linux-arm-kernel
In-Reply-To: <CAPdUM4NBwXcnL2KK9Rsi46GWQz_KQsXF0EEeSmCb=wB8WfgUKQ@mail.gmail.com>

Hi Rahul,

On 11.02.2014 06:22, Rahul Sharma wrote:
> Hi Tomasz,
>
> On 6 February 2014 18:51, Tomasz Figa <t.figa@samsung.com> wrote:
>> Hi Rahul, Pankaj, Arun,
>>
>> [adding linux-arm-kernel, devicetree MLs and DT people on Cc]
>>
>> I think it's good time to stop accepting DTS files like this and force new
>> ones to use the proper structure with soc node, labels for every node and
>> node references.
>
> I am unable to find information on SoC node and grouping inside SoC node. Please
> share some pointers.

Well, there is not much information needed about this. Basically all the 
devices built into the SoC should be listed under respective bus nodes 
or a single soc node, instead of root level. Such node should be a 
"simple-bus" and just group the components together to separate 
board-specific devices (which are still at root level) from SoC devices.

Even though it might seem useless, it improves DT readability a bit and 
still most of the platforms use this approach, so for consistency, 
Exynos should use too.

Just for reference, back in April 2013, in his review of S3C64xx DT 
series [1], Rob Herring requested that we don't submit any new device 
trees using flat approach and start using bus hierarchy.

[1] 
http://lists.infradead.org/pipermail/linux-arm-kernel/2013-April/163659.html

>>
>>> +               spi0_bus: spi0-bus {
>>> +                       samsung,pins = "gpa2-0", "gpa2-1", "gpa2-2",
>>> "gpa2-3";
>>
>>
>> What is the reason for SPI0 to have 4 pins, while SPI1 has just 3?
>>
>
> I should align SPI1 with SPI0.
>

Are you sure that SPI0 is the correct one? SPI usually uses four pins - 
SDI, SDO, SCK and nCS, but we always used to treat nCS as a simple GPIO, 
due to the fact that the controller can only support one dedicated chip 
select and with direct GPIO control you can have more.

What is the fourth pin here?

>>
>>> +               cpu at 1 {
>>> +                       device_type = "cpu";
>>> +                       compatible = "arm,cortex-a15";
>>> +                       reg = <1>;
>>> +                       cci-control-port = <&cci_control1>;
>>> +               };
>>> +               cpu at 100 {
>>> +                       device_type = "cpu";
>>> +                       compatible = "arm,cortex-a7";
>>> +                       reg = <0x100>;
>>> +                       cci-control-port = <&cci_control0>;
>>> +               };
>>> +               cpu at 101 {
>>> +                       device_type = "cpu";
>>> +                       compatible = "arm,cortex-a7";
>>> +                       reg = <0x101>;
>>> +                       cci-control-port = <&cci_control0>;
>>> +               };
>>> +               cpu at 102 {
>>> +                       device_type = "cpu";
>>> +                       compatible = "arm,cortex-a7";
>>> +                       reg = <0x102>;
>>> +                       cci-control-port = <&cci_control0>;
>>> +               };
>>> +               cpu at 103 {
>>> +                       device_type = "cpu";
>>> +                       compatible = "arm,cortex-a7";
>>> +                       reg = <0x103>;
>>> +                       cci-control-port = <&cci_control0>;
>>> +               };
>>> +       };
>>> +
>>> +       cmus {
>>> +               #address-cells = <1>;
>>> +               #size-cells = <1>;
>>> +               ranges;
>>> +
>>
>>
>> I don't think there is a need to group these nodes under a parent node that
>> doesn't give any additional information, especially when the CMUs are
>> scattered trough the whole address space, while we'd like to keep the nodes
>> ordered by their addresses, as most platforms do.
>>
>
> This is exactly the same case as "cpus". I mean, "cpus" also doesn't provide
> any common information about child cpu nodes. This looks to me as a logical
> grouping and I have implemented same thing for cmu nodes.
> I am ok with removing this grouping Just want to understand the rational behind
> grouping cpus which seems similar to cmus.

The "cpus" node is a defined standard node that should be present at 
root of device tree and include subnodes for all CPUs. This is a 
standard binding defined for low level code to be able to simply find 
nodes of all CPUs in the system - so they can expect that at /cpus node 
all the subnodes are subsequent CPUs.

> Similarly "soc" is just a logical entity used to group SoC elements which looks
> optional to me. What are we achieving with this? Please help me in understanding
> this better.

Also "soc" has a slightly wider meaning. It is a node grouping all nodes 
from a single address space - the node specifies #address-cells and 
#size-cells of this address space and all the devices under this 
"simple-bus" can be accessed using addresses in this format. In 
addition, it separates board-level devices from generic SoC devices.

Now, in case of "cmus", the only purpose is to group all CMU nodes 
together and, while this improves readability a bit, it doesn't make the 
DT better express the hardware topology, because the CMUs in the 
hardware are in fact scattered through the whole address space, not 
under a contiguous block of it, as the grouping would suggest.

Best regards,
Tomasz

^ permalink raw reply

* [PATCH v9 2/4] ehci-platform: Add support for clks and phy passed through devicetree
From: Roger Quadros @ 2014-02-11 10:00 UTC (permalink / raw)
  To: linux-arm-kernel
In-Reply-To: <52F9EE06.3070003@redhat.com>

On 02/11/2014 11:31 AM, Hans de Goede wrote:
> Hi,
> 
> On 02/11/2014 10:12 AM, Roger Quadros wrote:
>> Hi Hans,
>>
>> On 02/07/2014 05:36 PM, Hans de Goede wrote:
>>> Currently ehci-platform is only used in combination with devicetree when used
>>> with some Via socs. By extending it to (optionally) get clks and a phy from
>>> devicetree, and enabling / disabling those on power_on / off, it can be used
>>> more generically. Specifically after this commit it can be used for the
>>> ehci controller on Allwinner sunxi SoCs.
>>>
>>> Since ehci-platform is intended to handle any generic enough non pci ehci
>>> device, add a "usb-ehci" compatibility string.
>>>
>>> There already is a usb-ehci device-tree bindings document, update this
>>> with clks and phy bindings info.
>>>
>>> Although actually quite generic so far the via,vt8500 compatibilty string
>>> had its own bindings document. Somehow we even ended up with 2 of them. Since
>>> these provide no extra information over the generic usb-ehci documentation,
>>> this patch removes them.
>>>
>>> The ehci-ppc-of.c driver also claims the usb-ehci compatibility string,
>>> even though it mostly is ibm,usb-ehci-440epx specific. ehci-platform.c is
>>> not needed on ppc platforms, so add a !PPC_OF dependency to it to avoid
>>> 2 drivers claiming the same compatibility string getting build on ppc.
>>>
>>
>> This breaks all OMAP platforms on linux-next for the exact same reason. see [1].
>>
>> ./arch/arm/boot/dts/omap4.dtsi:				compatible = "ti,ehci-omap", "usb-ehci";
>> ./arch/arm/boot/dts/omap3.dtsi:				compatible = "ti,ehci-omap", "usb-ehci";
>> ./arch/arm/boot/dts/omap5.dtsi:				compatible = "ti,ehci-omap", "usb-ehci";
> 
> That should not be the case, the driver core should try to find a driver matching
> the compatibility string from left to right, or in other words from most specific
> to least specific. This is part of the whole devicetree design.
> 
> So as long as the driver claiming "ti,ehci-omap" is available at probe time that
> one should get used and things should work fine. Now if ehci-platform is built-in
> and ehci-omap is a module, then I guess one could see the described breakage.
> 
> If the driver is built-in and things are not working, then we will need to do some
> debugging as to why the left to right matching is not working as expected.

Both ehci_platform and ehci_omap were built-in and still the ehci_platform driver got
probe preference. So it looks like the left to right compatible list priority probing
feature doesn't work.

> 
> I must admit I'm not sure what happens if both are a module, the kernel direct
> module load will likely fail due to lack of a rootfs at that point, and then
> the module will later get loaded by udev I assume, at which point there are no
> loading ordering guarantees.
> 
> The easiest solution to ensure that "ti,ehci-omap" is available at probe time
> (if enabled) seems to be to change USB_EHCI_HCD_OMAP to a boolean.

That is a limitation I don't like to have for USB_EHCI_HCD_OMAP.

cheers,
-roger

> 
> 
>>
>>
>> The other platforms that claim compatibility with "usb-ehci" are
>>
>> ARM
>> ./arch/arm/boot/dts/tegra30.dtsi:		compatible = "nvidia,tegra30-ehci", "usb-ehci";
>> ./arch/arm/boot/dts/tegra20.dtsi:		compatible = "nvidia,tegra20-ehci", "usb-ehci";
>> ./arch/arm/boot/dts/spear600.dtsi:			compatible = "st,spear600-ehci", "usb-ehci";
>>
>> ./arch/arm/boot/dts/spear3xx.dtsi:			compatible = "st,spear600-ehci", "usb-ehci";
>> ./arch/arm/boot/dts/sama5d3.dtsi:			compatible = "atmel,at91sam9g45-ehci", "usb-ehci";
>> ./arch/arm/boot/dts/at91sam9g45.dtsi:			compatible = "atmel,at91sam9g45-ehci", "usb-ehci";
>> ./arch/arm/boot/dts/spear13xx.dtsi:			compatible = "st,spear600-ehci", "usb-ehci";
>> ./arch/arm/boot/dts/at91sam9x5.dtsi:			compatible = "atmel,at91sam9g45-ehci", "usb-ehci";
>> ./arch/arm/boot/dts/tegra114.dtsi:		compatible = "nvidia,tegra30-ehci", "usb-ehci";
>>
>>
>> MIPS
>> ./arch/mips/cavium-octeon/octeon_68xx.dts:				compatible = "cavium,octeon-6335-ehci","usb-ehci";
>> ./arch/mips/cavium-octeon/octeon_3xxx.dts:				compatible = "cavium,octeon-6335-ehci","usb-ehci";
>>
>> Do we know that we don't break these platforms as well?
>>
>> cheers,
>> -roger
>>
>> [1] - http://marc.info/?l=linux-usb&m=139204800102167&w=2
>>
>>> Signed-off-by: Hans de Goede <hdegoede@redhat.com>
>>> Acked-by: Alan Stern <stern@rowland.harvard.edu>
>>> ---
>>>  Documentation/devicetree/bindings/usb/usb-ehci.txt |  25 +++-
>>>  .../devicetree/bindings/usb/via,vt8500-ehci.txt    |  15 ---
>>>  .../devicetree/bindings/usb/vt8500-ehci.txt        |  12 --
>>>  drivers/usb/host/Kconfig                           |   1 +
>>>  drivers/usb/host/ehci-platform.c                   | 147 +++++++++++++++++----
>>>  5 files changed, 142 insertions(+), 58 deletions(-)
>>>  delete mode 100644 Documentation/devicetree/bindings/usb/via,vt8500-ehci.txt
>>>  delete mode 100644 Documentation/devicetree/bindings/usb/vt8500-ehci.txt
>>>
>>> diff --git a/Documentation/devicetree/bindings/usb/usb-ehci.txt b/Documentation/devicetree/bindings/usb/usb-ehci.txt
>>> index fa18612..2c1aeeb 100644
>>> --- a/Documentation/devicetree/bindings/usb/usb-ehci.txt
>>> +++ b/Documentation/devicetree/bindings/usb/usb-ehci.txt
>>> @@ -7,13 +7,14 @@ Required properties:
>>>      (debug-port or other) can be also specified here, but only after
>>>      definition of standard EHCI registers.
>>>    - interrupts : one EHCI interrupt should be described here.
>>> -If device registers are implemented in big endian mode, the device
>>> -node should have "big-endian-regs" property.
>>> -If controller implementation operates with big endian descriptors,
>>> -"big-endian-desc" property should be specified.
>>> -If both big endian registers and descriptors are used by the controller
>>> -implementation, "big-endian" property can be specified instead of having
>>> -both "big-endian-regs" and "big-endian-desc".
>>> +
>>> +Optional properties:
>>> + - big-endian-regs : boolean, set this for hcds with big-endian registers
>>> + - big-endian-desc : boolean, set this for hcds with big-endian descriptors
>>> + - big-endian : boolean, for hcds with big-endian-regs + big-endian-desc
>>> + - clocks : a list of phandle + clock specifier pairs
>>> + - phys : phandle + phy specifier pair
>>> + - phy-names : "usb"
>>>  
>>>  Example (Sequoia 440EPx):
>>>      ehci at e0000300 {
>>> @@ -23,3 +24,13 @@ Example (Sequoia 440EPx):
>>>  	   reg = <0 e0000300 90 0 e0000390 70>;
>>>  	   big-endian;
>>>     };
>>> +
>>> +Example (Allwinner sun4i A10 SoC):
>>> +   ehci0: usb at 01c14000 {
>>> +	   compatible = "allwinner,sun4i-a10-ehci", "usb-ehci";
>>> +	   reg = <0x01c14000 0x100>;
>>> +	   interrupts = <39>;
>>> +	   clocks = <&ahb_gates 1>;
>>> +	   phys = <&usbphy 1>;
>>> +	   phy-names = "usb";
>>> +   };
>>> diff --git a/Documentation/devicetree/bindings/usb/via,vt8500-ehci.txt b/Documentation/devicetree/bindings/usb/via,vt8500-ehci.txt
>>> deleted file mode 100644
>>> index 17b3ad1..0000000
>>> --- a/Documentation/devicetree/bindings/usb/via,vt8500-ehci.txt
>>> +++ /dev/null
>>> @@ -1,15 +0,0 @@
>>> -VIA/Wondermedia VT8500 EHCI Controller
>>> ------------------------------------------------------
>>> -
>>> -Required properties:
>>> -- compatible : "via,vt8500-ehci"
>>> -- reg : Should contain 1 register ranges(address and length)
>>> -- interrupts : ehci controller interrupt
>>> -
>>> -Example:
>>> -
>>> -	ehci at d8007900 {
>>> -		compatible = "via,vt8500-ehci";
>>> -		reg = <0xd8007900 0x200>;
>>> -		interrupts = <43>;
>>> -	};
>>> diff --git a/Documentation/devicetree/bindings/usb/vt8500-ehci.txt b/Documentation/devicetree/bindings/usb/vt8500-ehci.txt
>>> deleted file mode 100644
>>> index 5fb8fd6..0000000
>>> --- a/Documentation/devicetree/bindings/usb/vt8500-ehci.txt
>>> +++ /dev/null
>>> @@ -1,12 +0,0 @@
>>> -VIA VT8500 and Wondermedia WM8xxx SoC USB controllers.
>>> -
>>> -Required properties:
>>> - - compatible: Should be "via,vt8500-ehci" or "wm,prizm-ehci".
>>> - - reg: Address range of the ehci registers. size should be 0x200
>>> - - interrupts: Should contain the ehci interrupt.
>>> -
>>> -usb: ehci at D8007100 {
>>> -	compatible = "wm,prizm-ehci", "usb-ehci";
>>> -	reg = <0xD8007100 0x200>;
>>> -	interrupts = <1>;
>>> -};
>>> diff --git a/drivers/usb/host/Kconfig b/drivers/usb/host/Kconfig
>>> index a9707da..e28cbe0 100644
>>> --- a/drivers/usb/host/Kconfig
>>> +++ b/drivers/usb/host/Kconfig
>>> @@ -255,6 +255,7 @@ config USB_EHCI_ATH79
>>>  
>>>  config USB_EHCI_HCD_PLATFORM
>>>  	tristate "Generic EHCI driver for a platform device"
>>> +	depends on !PPC_OF
>>>  	default n
>>>  	---help---
>>>  	  Adds an EHCI host driver for a generic platform device, which
>>> diff --git a/drivers/usb/host/ehci-platform.c b/drivers/usb/host/ehci-platform.c
>>> index 01536cf..5ebd0b7 100644
>>> --- a/drivers/usb/host/ehci-platform.c
>>> +++ b/drivers/usb/host/ehci-platform.c
>>> @@ -3,6 +3,7 @@
>>>   *
>>>   * Copyright 2007 Steven Brown <sbrown@cortland.com>
>>>   * Copyright 2010-2012 Hauke Mehrtens <hauke@hauke-m.de>
>>> + * Copyright 2014 Hans de Goede <hdegoede@redhat.com>
>>>   *
>>>   * Derived from the ohci-ssb driver
>>>   * Copyright 2007 Michael Buesch <m@bues.ch>
>>> @@ -18,6 +19,7 @@
>>>   *
>>>   * Licensed under the GNU/GPL. See COPYING for details.
>>>   */
>>> +#include <linux/clk.h>
>>>  #include <linux/dma-mapping.h>
>>>  #include <linux/err.h>
>>>  #include <linux/kernel.h>
>>> @@ -25,6 +27,7 @@
>>>  #include <linux/io.h>
>>>  #include <linux/module.h>
>>>  #include <linux/of.h>
>>> +#include <linux/phy/phy.h>
>>>  #include <linux/platform_device.h>
>>>  #include <linux/usb.h>
>>>  #include <linux/usb/hcd.h>
>>> @@ -33,6 +36,13 @@
>>>  #include "ehci.h"
>>>  
>>>  #define DRIVER_DESC "EHCI generic platform driver"
>>> +#define EHCI_MAX_CLKS 3
>>> +#define hcd_to_ehci_priv(h) ((struct ehci_platform_priv *)hcd_to_ehci(h)->priv)
>>> +
>>> +struct ehci_platform_priv {
>>> +	struct clk *clks[EHCI_MAX_CLKS];
>>> +	struct phy *phy;
>>> +};
>>>  
>>>  static const char hcd_name[] = "ehci-platform";
>>>  
>>> @@ -64,38 +74,90 @@ static int ehci_platform_reset(struct usb_hcd *hcd)
>>>  	return 0;
>>>  }
>>>  
>>> +static int ehci_platform_power_on(struct platform_device *dev)
>>> +{
>>> +	struct usb_hcd *hcd = platform_get_drvdata(dev);
>>> +	struct ehci_platform_priv *priv = hcd_to_ehci_priv(hcd);
>>> +	int clk, ret;
>>> +
>>> +	for (clk = 0; clk < EHCI_MAX_CLKS && priv->clks[clk]; clk++) {
>>> +		ret = clk_prepare_enable(priv->clks[clk]);
>>> +		if (ret)
>>> +			goto err_disable_clks;
>>> +	}
>>> +
>>> +	if (priv->phy) {
>>> +		ret = phy_init(priv->phy);
>>> +		if (ret)
>>> +			goto err_disable_clks;
>>> +
>>> +		ret = phy_power_on(priv->phy);
>>> +		if (ret)
>>> +			goto err_exit_phy;
>>> +	}
>>> +
>>> +	return 0;
>>> +
>>> +err_exit_phy:
>>> +	phy_exit(priv->phy);
>>> +err_disable_clks:
>>> +	while (--clk >= 0)
>>> +		clk_disable_unprepare(priv->clks[clk]);
>>> +
>>> +	return ret;
>>> +}
>>> +
>>> +static void ehci_platform_power_off(struct platform_device *dev)
>>> +{
>>> +	struct usb_hcd *hcd = platform_get_drvdata(dev);
>>> +	struct ehci_platform_priv *priv = hcd_to_ehci_priv(hcd);
>>> +	int clk;
>>> +
>>> +	if (priv->phy) {
>>> +		phy_power_off(priv->phy);
>>> +		phy_exit(priv->phy);
>>> +	}
>>> +
>>> +	for (clk = EHCI_MAX_CLKS - 1; clk >= 0; clk--)
>>> +		if (priv->clks[clk])
>>> +			clk_disable_unprepare(priv->clks[clk]);
>>> +}
>>> +
>>>  static struct hc_driver __read_mostly ehci_platform_hc_driver;
>>>  
>>>  static const struct ehci_driver_overrides platform_overrides __initconst = {
>>> -	.reset =	ehci_platform_reset,
>>> +	.reset =		ehci_platform_reset,
>>> +	.extra_priv_size =	sizeof(struct ehci_platform_priv),
>>>  };
>>>  
>>> -static struct usb_ehci_pdata ehci_platform_defaults;
>>> +static struct usb_ehci_pdata ehci_platform_defaults = {
>>> +	.power_on =		ehci_platform_power_on,
>>> +	.power_suspend =	ehci_platform_power_off,
>>> +	.power_off =		ehci_platform_power_off,
>>> +};
>>>  
>>>  static int ehci_platform_probe(struct platform_device *dev)
>>>  {
>>>  	struct usb_hcd *hcd;
>>>  	struct resource *res_mem;
>>> -	struct usb_ehci_pdata *pdata;
>>> -	int irq;
>>> -	int err;
>>> +	struct usb_ehci_pdata *pdata = dev_get_platdata(&dev->dev);
>>> +	struct ehci_platform_priv *priv;
>>> +	int err, irq, clk = 0;
>>>  
>>>  	if (usb_disabled())
>>>  		return -ENODEV;
>>>  
>>>  	/*
>>> -	 * use reasonable defaults so platforms don't have to provide these.
>>> -	 * with DT probing on ARM, none of these are set.
>>> +	 * Use reasonable defaults so platforms don't have to provide these
>>> +	 * with DT probing on ARM.
>>>  	 */
>>> -	if (!dev_get_platdata(&dev->dev))
>>> -		dev->dev.platform_data = &ehci_platform_defaults;
>>> +	if (!pdata)
>>> +		pdata = &ehci_platform_defaults;
>>>  
>>>  	err = dma_coerce_mask_and_coherent(&dev->dev, DMA_BIT_MASK(32));
>>>  	if (err)
>>>  		return err;
>>>  
>>> -	pdata = dev_get_platdata(&dev->dev);
>>> -
>>>  	irq = platform_get_irq(dev, 0);
>>>  	if (irq < 0) {
>>>  		dev_err(&dev->dev, "no irq provided");
>>> @@ -107,17 +169,40 @@ static int ehci_platform_probe(struct platform_device *dev)
>>>  		return -ENXIO;
>>>  	}
>>>  
>>> +	hcd = usb_create_hcd(&ehci_platform_hc_driver, &dev->dev,
>>> +			     dev_name(&dev->dev));
>>> +	if (!hcd)
>>> +		return -ENOMEM;
>>> +
>>> +	platform_set_drvdata(dev, hcd);
>>> +	dev->dev.platform_data = pdata;
>>> +	priv = hcd_to_ehci_priv(hcd);
>>> +
>>> +	if (pdata == &ehci_platform_defaults && dev->dev.of_node) {
>>> +		priv->phy = devm_phy_get(&dev->dev, "usb");
>>> +		if (IS_ERR(priv->phy)) {
>>> +			err = PTR_ERR(priv->phy);
>>> +			if (err == -EPROBE_DEFER)
>>> +				goto err_put_hcd;
>>> +			priv->phy = NULL;
>>> +		}
>>> +
>>> +		for (clk = 0; clk < EHCI_MAX_CLKS; clk++) {
>>> +			priv->clks[clk] = of_clk_get(dev->dev.of_node, clk);
>>> +			if (IS_ERR(priv->clks[clk])) {
>>> +				err = PTR_ERR(priv->clks[clk]);
>>> +				if (err == -EPROBE_DEFER)
>>> +					goto err_put_clks;
>>> +				priv->clks[clk] = NULL;
>>> +				break;
>>> +			}
>>> +		}
>>> +	}
>>> +
>>>  	if (pdata->power_on) {
>>>  		err = pdata->power_on(dev);
>>>  		if (err < 0)
>>> -			return err;
>>> -	}
>>> -
>>> -	hcd = usb_create_hcd(&ehci_platform_hc_driver, &dev->dev,
>>> -			     dev_name(&dev->dev));
>>> -	if (!hcd) {
>>> -		err = -ENOMEM;
>>> -		goto err_power;
>>> +			goto err_put_clks;
>>>  	}
>>>  
>>>  	hcd->rsrc_start = res_mem->start;
>>> @@ -126,22 +211,28 @@ static int ehci_platform_probe(struct platform_device *dev)
>>>  	hcd->regs = devm_ioremap_resource(&dev->dev, res_mem);
>>>  	if (IS_ERR(hcd->regs)) {
>>>  		err = PTR_ERR(hcd->regs);
>>> -		goto err_put_hcd;
>>> +		goto err_power;
>>>  	}
>>>  	err = usb_add_hcd(hcd, irq, IRQF_SHARED);
>>>  	if (err)
>>> -		goto err_put_hcd;
>>> +		goto err_power;
>>>  
>>>  	device_wakeup_enable(hcd->self.controller);
>>>  	platform_set_drvdata(dev, hcd);
>>>  
>>>  	return err;
>>>  
>>> -err_put_hcd:
>>> -	usb_put_hcd(hcd);
>>>  err_power:
>>>  	if (pdata->power_off)
>>>  		pdata->power_off(dev);
>>> +err_put_clks:
>>> +	while (--clk >= 0)
>>> +		clk_put(priv->clks[clk]);
>>> +err_put_hcd:
>>> +	if (pdata == &ehci_platform_defaults)
>>> +		dev->dev.platform_data = NULL;
>>> +
>>> +	usb_put_hcd(hcd);
>>>  
>>>  	return err;
>>>  }
>>> @@ -150,13 +241,19 @@ static int ehci_platform_remove(struct platform_device *dev)
>>>  {
>>>  	struct usb_hcd *hcd = platform_get_drvdata(dev);
>>>  	struct usb_ehci_pdata *pdata = dev_get_platdata(&dev->dev);
>>> +	struct ehci_platform_priv *priv = hcd_to_ehci_priv(hcd);
>>> +	int clk;
>>>  
>>>  	usb_remove_hcd(hcd);
>>> -	usb_put_hcd(hcd);
>>>  
>>>  	if (pdata->power_off)
>>>  		pdata->power_off(dev);
>>>  
>>> +	for (clk = 0; clk < EHCI_MAX_CLKS && priv->clks[clk]; clk++)
>>> +		clk_put(priv->clks[clk]);
>>> +
>>> +	usb_put_hcd(hcd);
>>> +
>>>  	if (pdata == &ehci_platform_defaults)
>>>  		dev->dev.platform_data = NULL;
>>>  
>>> @@ -207,8 +304,10 @@ static int ehci_platform_resume(struct device *dev)
>>>  static const struct of_device_id vt8500_ehci_ids[] = {
>>>  	{ .compatible = "via,vt8500-ehci", },
>>>  	{ .compatible = "wm,prizm-ehci", },
>>> +	{ .compatible = "usb-ehci", },
>>>  	{}
>>>  };
>>> +MODULE_DEVICE_TABLE(of, vt8500_ehci_ids);
>>>  
>>>  static const struct platform_device_id ehci_platform_table[] = {
>>>  	{ "ehci-platform", 0 },
>>>
>>

^ permalink raw reply

* [PATCH v3 1/3] net: stmmac:sti: Add STi SOC glue driver.
From: srinivas.kandagatla at st.com @ 2014-02-11  9:59 UTC (permalink / raw)
  To: linux-arm-kernel
In-Reply-To: <1392112716-30803-1-git-send-email-srinivas.kandagatla@st.com>

From: Srinivas Kandagatla <srinivas.kandagatla@st.com>

STi series SOCs have a glue layer on top of the synopsis gmac IP, this
glue layer needs to be configured before the gmac driver starts using
the IP.

This patch adds a support to this glue layer which is configured via
stmmac setup, init, exit callbacks.

Signed-off-by: Srinivas Kandagatla <srinivas.kandagatla@st.com>
---
 .../devicetree/bindings/net/sti-dwmac.txt          |   58 ++++
 drivers/net/ethernet/stmicro/stmmac/Kconfig        |   11 +
 drivers/net/ethernet/stmicro/stmmac/Makefile       |    1 +
 drivers/net/ethernet/stmicro/stmmac/dwmac-sti.c    |  330 ++++++++++++++++++++
 drivers/net/ethernet/stmicro/stmmac/stmmac.h       |    3 +
 .../net/ethernet/stmicro/stmmac/stmmac_platform.c  |    5 +
 6 files changed, 408 insertions(+)
 create mode 100644 Documentation/devicetree/bindings/net/sti-dwmac.txt
 create mode 100644 drivers/net/ethernet/stmicro/stmmac/dwmac-sti.c

diff --git a/Documentation/devicetree/bindings/net/sti-dwmac.txt b/Documentation/devicetree/bindings/net/sti-dwmac.txt
new file mode 100644
index 0000000..3dd3d0b
--- /dev/null
+++ b/Documentation/devicetree/bindings/net/sti-dwmac.txt
@@ -0,0 +1,58 @@
+STMicroelectronics SoC DWMAC glue layer controller
+
+The device node has following properties.
+
+Required properties:
+ - compatible	: Can be "st,stih415-dwmac", "st,stih416-dwmac" or
+   "st,stid127-dwmac".
+ - reg		: Offset of the glue configuration register map in system
+   configuration regmap pointed by st,syscon property and size.
+
+ - reg-names	: Should be "sti-ethconf".
+
+ - st,syscon	: Should be phandle to system configuration node which
+   encompases this glue registers.
+
+ - st,tx-retime-src: On STi Parts for Giga bit speeds, 125Mhz clocks can be
+   wired up in from different sources. One via TXCLK pin and other via CLK_125
+   pin. This wiring is totally board dependent. However the retiming glue
+   logic should be configured accordingly. Possible values for this property
+
+	   "txclk" - if 125Mhz clock is wired up via txclk line.
+	   "clk_125" - if 125Mhz clock is wired up via clk_125 line.
+
+   This property is only valid for Giga bit setup( GMII, RGMII), and it is
+   un-used for non-giga bit (MII and RMII) setups. Also note that internal
+   clockgen can not generate stable 125Mhz clock.
+
+ - st,ext-phyclk: This boolean property indicates who is generating the clock
+  for tx and rx. This property is only valid for RMII case where the clock can
+  be generated from the MAC or PHY.
+
+ - clock-names: should be "sti-ethclk".
+ - clocks: Should point to ethernet clockgen which can generate phyclk.
+
+
+Example:
+
+ethernet0: dwmac at fe810000 {
+	device_type 	= "network";
+	compatible	= "st,stih416-dwmac", "snps,dwmac", "snps,dwmac-3.710";
+	reg 		= <0xfe810000 0x8000>, <0x8bc 0x4>;
+	reg-names	= "stmmaceth", "sti-ethconf";
+	interrupts	= <0 133 0>, <0 134 0>, <0 135 0>;
+	interrupt-names	= "macirq", "eth_wake_irq", "eth_lpi";
+	phy-mode	= "mii";
+
+	st,syscon	= <&syscfg_rear>;
+
+	snps,pbl 	= <32>;
+	snps,mixed-burst;
+
+	resets		= <&softreset STIH416_ETH0_SOFTRESET>;
+	reset-names	= "stmmaceth";
+	pinctrl-0	= <&pinctrl_mii0>;
+	pinctrl-names 	= "default";
+	clocks		= <&CLK_S_GMAC0_PHY>;
+	clock-names	= "stmmaceth";
+};
diff --git a/drivers/net/ethernet/stmicro/stmmac/Kconfig b/drivers/net/ethernet/stmicro/stmmac/Kconfig
index e2f202e..f2d7c70 100644
--- a/drivers/net/ethernet/stmicro/stmmac/Kconfig
+++ b/drivers/net/ethernet/stmicro/stmmac/Kconfig
@@ -37,6 +37,17 @@ config DWMAC_SUNXI
 	  stmmac device driver. This driver is used for A20/A31
 	  GMAC 	  ethernet controller.
 
+config DWMAC_STI
+	bool "STi GMAC support"
+	depends on STMMAC_PLATFORM && ARCH_STI
+	default y
+	---help---
+	  Support for ethernet controller on STi SOCs.
+
+	  This selects STi SoC glue layer support for the stmmac
+	  device driver. This driver is used on for the STi series
+	  SOCs GMAC ethernet controller.
+
 config STMMAC_PCI
 	bool "STMMAC PCI bus support"
 	depends on STMMAC_ETH && PCI
diff --git a/drivers/net/ethernet/stmicro/stmmac/Makefile b/drivers/net/ethernet/stmicro/stmmac/Makefile
index ecadece..dcef287 100644
--- a/drivers/net/ethernet/stmicro/stmmac/Makefile
+++ b/drivers/net/ethernet/stmicro/stmmac/Makefile
@@ -2,6 +2,7 @@ obj-$(CONFIG_STMMAC_ETH) += stmmac.o
 stmmac-$(CONFIG_STMMAC_PLATFORM) += stmmac_platform.o
 stmmac-$(CONFIG_STMMAC_PCI) += stmmac_pci.o
 stmmac-$(CONFIG_DWMAC_SUNXI) += dwmac-sunxi.o
+stmmac-$(CONFIG_DWMAC_STI) += dwmac-sti.o
 stmmac-objs:= stmmac_main.o stmmac_ethtool.o stmmac_mdio.o ring_mode.o	\
 	      chain_mode.o dwmac_lib.o dwmac1000_core.o  dwmac1000_dma.o \
 	      dwmac100_core.o dwmac100_dma.o enh_desc.o  norm_desc.o \
diff --git a/drivers/net/ethernet/stmicro/stmmac/dwmac-sti.c b/drivers/net/ethernet/stmicro/stmmac/dwmac-sti.c
new file mode 100644
index 0000000..552bbc1
--- /dev/null
+++ b/drivers/net/ethernet/stmicro/stmmac/dwmac-sti.c
@@ -0,0 +1,330 @@
+/**
+ * dwmac-sti.c - STMicroelectronics DWMAC Specific Glue layer
+ *
+ * Copyright (C) 2003-2014 STMicroelectronics (R&D) Limited
+ * Author: Srinivas Kandagatla <srinivas.kandagatla@st.com>
+ *
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ */
+
+#include <linux/kernel.h>
+#include <linux/slab.h>
+#include <linux/platform_device.h>
+#include <linux/stmmac.h>
+#include <linux/phy.h>
+#include <linux/mfd/syscon.h>
+#include <linux/regmap.h>
+#include <linux/clk.h>
+#include <linux/of.h>
+#include <linux/of_net.h>
+
+/**
+ *			STi GMAC glue logic.
+ *			--------------------
+ *
+ *		 _
+ *		|  \
+ *	--------|0  \ ETH_SEL_INTERNAL_NOTEXT_PHYCLK
+ * phyclk	|    |___________________________________________
+ *		|    |	|			(phyclk-in)
+ *	--------|1  /	|
+ * int-clk	|_ /	|
+ *			|	 _
+ *			|	|  \
+ *			|_______|1  \ ETH_SEL_TX_RETIME_CLK
+ *				|    |___________________________
+ *				|    |		(tx-retime-clk)
+ *			 _______|0  /
+ *			|	|_ /
+ *		 _	|
+ *		|  \	|
+ *	--------|0  \	|
+ * clk_125	|    |__|
+ *		|    |	ETH_SEL_TXCLK_NOT_CLK125
+ *	--------|1  /
+ * txclk	|_ /
+ *
+ *
+ * ETH_SEL_INTERNAL_NOTEXT_PHYCLK is valid only for RMII where PHY can
+ * generate 50MHz clock or MAC can generate it.
+ * This bit is configured by "st,ext-phyclk" property.
+ *
+ * ETH_SEL_TXCLK_NOT_CLK125 is only valid for gigabit modes, where the 125Mhz
+ * clock either comes from clk-125 pin or txclk pin. This configuration is
+ * totally driven by the board wiring. This bit is configured by
+ * "st,tx-retime-src" property.
+ *
+ * TXCLK configuration is different for different phy interface modes
+ * and changes according to link speed in modes like RGMII.
+ *
+ * Below table summarizes the clock requirement and clock sources for
+ * supported phy interface modes with link speeds.
+ * ________________________________________________
+ *|  PHY_MODE	| 1000 Mbit Link | 100 Mbit Link   |
+ * ------------------------------------------------
+ *|	MII	|	n/a	 |	25Mhz	   |
+ *|		|		 |	txclk	   |
+ * ------------------------------------------------
+ *|	GMII	|     125Mhz	 |	25Mhz	   |
+ *|		|  clk-125/txclk |	txclk	   |
+ * ------------------------------------------------
+ *|	RGMII	|     125Mhz	 |	25Mhz	   |
+ *|		|  clk-125/txclk |	clkgen     |
+ * ------------------------------------------------
+ *|	RMII	|	n/a	 |	25Mhz	   |
+ *|		|		 |clkgen/phyclk-in |
+ * ------------------------------------------------
+ *
+ * TX lines are always retimed with a clk, which can vary depending
+ * on the board configuration. Below is the table of these bits
+ * in eth configuration register depending on source of retime clk.
+ *
+ *---------------------------------------------------------------
+ * src	 | tx_rt_clk	| int_not_ext_phyclk	| txclk_n_clk125|
+ *---------------------------------------------------------------
+ * txclk |	0	|	n/a		|	1	|
+ *---------------------------------------------------------------
+ * ck_125|	0	|	n/a		|	0	|
+ *---------------------------------------------------------------
+ * phyclk|	1	|	0		|	n/a	|
+ *---------------------------------------------------------------
+ * clkgen|	1	|	1		|	n/a	|
+ *---------------------------------------------------------------
+ */
+
+ /* Register definition */
+
+ /* 3 bits [8:6]
+  *  [6:6]      ETH_SEL_TXCLK_NOT_CLK125
+  *  [7:7]      ETH_SEL_INTERNAL_NOTEXT_PHYCLK
+  *  [8:8]      ETH_SEL_TX_RETIME_CLK
+  *
+  */
+
+#define TX_RETIME_SRC_MASK		GENMASK(8, 6)
+#define ETH_SEL_TX_RETIME_CLK		BIT(8)
+#define ETH_SEL_INTERNAL_NOTEXT_PHYCLK	BIT(7)
+#define ETH_SEL_TXCLK_NOT_CLK125	BIT(6)
+
+#define ENMII_MASK			GENMASK(5, 5)
+#define ENMII				BIT(5)
+
+/**
+ * 3 bits [4:2]
+ *	000-GMII/MII
+ *	001-RGMII
+ *	010-SGMII
+ *	100-RMII
+*/
+#define MII_PHY_SEL_MASK		GENMASK(4, 2)
+#define ETH_PHY_SEL_RMII		BIT(4)
+#define ETH_PHY_SEL_SGMII		BIT(3)
+#define ETH_PHY_SEL_RGMII		BIT(2)
+#define ETH_PHY_SEL_GMII		0x0
+#define ETH_PHY_SEL_MII			0x0
+
+#define IS_PHY_IF_MODE_RGMII(iface)	(iface == PHY_INTERFACE_MODE_RGMII || \
+			iface == PHY_INTERFACE_MODE_RGMII_ID || \
+			iface == PHY_INTERFACE_MODE_RGMII_RXID || \
+			iface == PHY_INTERFACE_MODE_RGMII_TXID)
+
+#define IS_PHY_IF_MODE_GBIT(iface)	(IS_PHY_IF_MODE_RGMII(iface) || \
+			iface == PHY_INTERFACE_MODE_GMII)
+
+struct sti_dwmac {
+	int interface;
+	bool ext_phyclk;
+	bool is_tx_retime_src_clk_125;
+	struct clk *clk;
+	int reg;
+	struct device *dev;
+	struct regmap *regmap;
+};
+
+static u32 phy_intf_sels[] = {
+	[PHY_INTERFACE_MODE_MII] = ETH_PHY_SEL_MII,
+	[PHY_INTERFACE_MODE_GMII] = ETH_PHY_SEL_GMII,
+	[PHY_INTERFACE_MODE_RGMII] = ETH_PHY_SEL_RGMII,
+	[PHY_INTERFACE_MODE_RGMII_ID] = ETH_PHY_SEL_RGMII,
+	[PHY_INTERFACE_MODE_SGMII] = ETH_PHY_SEL_SGMII,
+	[PHY_INTERFACE_MODE_RMII] = ETH_PHY_SEL_RMII,
+};
+
+enum {
+	TX_RETIME_SRC_NA = 0,
+	TX_RETIME_SRC_TXCLK = 1,
+	TX_RETIME_SRC_CLK_125,
+	TX_RETIME_SRC_PHYCLK,
+	TX_RETIME_SRC_CLKGEN,
+};
+
+static const char *const tx_retime_srcs[] = {
+	[TX_RETIME_SRC_NA] = "",
+	[TX_RETIME_SRC_TXCLK] = "txclk",
+	[TX_RETIME_SRC_CLK_125] = "clk_125",
+	[TX_RETIME_SRC_PHYCLK] = "phyclk",
+	[TX_RETIME_SRC_CLKGEN] = "clkgen",
+};
+
+static u32 tx_retime_val[] = {
+	[TX_RETIME_SRC_TXCLK] = ETH_SEL_TXCLK_NOT_CLK125,
+	[TX_RETIME_SRC_CLK_125] = 0x0,
+	[TX_RETIME_SRC_PHYCLK] = ETH_SEL_TX_RETIME_CLK,
+	[TX_RETIME_SRC_CLKGEN] = ETH_SEL_TX_RETIME_CLK |
+	    ETH_SEL_INTERNAL_NOTEXT_PHYCLK,
+};
+
+static void setup_retime_src(struct sti_dwmac *dwmac, u32 spd)
+{
+	u32 src = 0, freq = 0;
+
+	if (spd == SPEED_100) {
+		if (dwmac->interface == PHY_INTERFACE_MODE_MII ||
+		    dwmac->interface == PHY_INTERFACE_MODE_GMII) {
+			src = TX_RETIME_SRC_TXCLK;
+		} else if (dwmac->interface == PHY_INTERFACE_MODE_RMII) {
+			if (dwmac->ext_phyclk) {
+				src = TX_RETIME_SRC_PHYCLK;
+			} else {
+				src = TX_RETIME_SRC_CLKGEN;
+				freq = 50000000;
+			}
+
+		} else if (IS_PHY_IF_MODE_RGMII(dwmac->interface)) {
+			src = TX_RETIME_SRC_CLKGEN;
+			freq = 25000000;
+		}
+
+		if (src == TX_RETIME_SRC_CLKGEN && dwmac->clk)
+			clk_set_rate(dwmac->clk, freq);
+
+	} else if (spd == SPEED_1000) {
+		if (dwmac->is_tx_retime_src_clk_125)
+			src = TX_RETIME_SRC_CLK_125;
+		else
+			src = TX_RETIME_SRC_TXCLK;
+	}
+
+	regmap_update_bits(dwmac->regmap, dwmac->reg,
+			   TX_RETIME_SRC_MASK, tx_retime_val[src]);
+}
+
+static void sti_dwmac_exit(struct platform_device *pdev, void *priv)
+{
+	struct sti_dwmac *dwmac = priv;
+
+	if (dwmac->clk)
+		clk_disable_unprepare(dwmac->clk);
+}
+
+static void sti_fix_mac_speed(void *priv, unsigned int spd)
+{
+	struct sti_dwmac *dwmac = priv;
+
+	setup_retime_src(dwmac, spd);
+
+	return;
+}
+
+static int sti_dwmac_parse_data(struct sti_dwmac *dwmac,
+				struct platform_device *pdev)
+{
+	struct resource *res;
+	struct device *dev = &pdev->dev;
+	struct device_node *np = dev->of_node;
+	struct regmap *regmap;
+	int err;
+
+	if (!np)
+		return -EINVAL;
+
+	res = platform_get_resource_byname(pdev, IORESOURCE_MEM, "sti-ethconf");
+	if (!res)
+		return -ENODATA;
+
+	regmap = syscon_regmap_lookup_by_phandle(np, "st,syscon");
+	if (IS_ERR(regmap))
+		return PTR_ERR(regmap);
+
+	dwmac->dev = dev;
+	dwmac->interface = of_get_phy_mode(np);
+	dwmac->regmap = regmap;
+	dwmac->reg = res->start;
+	dwmac->ext_phyclk = of_property_read_bool(np, "st,ext-phyclk");
+	dwmac->is_tx_retime_src_clk_125 = false;
+
+	if (IS_PHY_IF_MODE_GBIT(dwmac->interface)) {
+		const char *rs;
+
+		err = of_property_read_string(np, "st,tx-retime-src", &rs);
+		if (err < 0) {
+			dev_err(dev, "st,tx-retime-src not specified\n");
+			return err;
+		}
+
+		if (!strcasecmp(rs, "clk_125"))
+			dwmac->is_tx_retime_src_clk_125 = true;
+	}
+
+	dwmac->clk = devm_clk_get(dev, "sti-ethclk");
+
+	if (IS_ERR(dwmac->clk))
+		dwmac->clk = NULL;
+
+	return 0;
+}
+
+static int sti_dwmac_init(struct platform_device *pdev, void *priv)
+{
+	struct sti_dwmac *dwmac = priv;
+	struct regmap *regmap = dwmac->regmap;
+	int iface = dwmac->interface;
+	u32 reg = dwmac->reg;
+	u32 val, spd;
+
+	if (dwmac->clk)
+		clk_prepare_enable(dwmac->clk);
+
+	regmap_update_bits(regmap, reg, MII_PHY_SEL_MASK, phy_intf_sels[iface]);
+
+	val = (iface == PHY_INTERFACE_MODE_REVMII) ? 0 : ENMII;
+	regmap_update_bits(regmap, reg, ENMII_MASK, val);
+
+	if (IS_PHY_IF_MODE_GBIT(iface))
+		spd = SPEED_1000;
+	else
+		spd = SPEED_100;
+
+	setup_retime_src(dwmac, spd);
+
+	return 0;
+}
+
+static void *sti_dwmac_setup(struct platform_device *pdev)
+{
+	struct sti_dwmac *dwmac;
+	int ret;
+
+	dwmac = devm_kzalloc(&pdev->dev, sizeof(*dwmac), GFP_KERNEL);
+	if (!dwmac)
+		return ERR_PTR(-ENOMEM);
+
+	ret = sti_dwmac_parse_data(dwmac, pdev);
+	if (ret) {
+		dev_err(&pdev->dev, "Unable to parse OF data\n");
+		return ERR_PTR(ret);
+	}
+
+	return dwmac;
+}
+
+const struct stmmac_of_data sti_gmac_data = {
+	.fix_mac_speed = sti_fix_mac_speed,
+	.setup = sti_dwmac_setup,
+	.init = sti_dwmac_init,
+	.exit = sti_dwmac_exit,
+};
diff --git a/drivers/net/ethernet/stmicro/stmmac/stmmac.h b/drivers/net/ethernet/stmicro/stmmac/stmmac.h
index d9af26e..f9e60d7 100644
--- a/drivers/net/ethernet/stmicro/stmmac/stmmac.h
+++ b/drivers/net/ethernet/stmicro/stmmac/stmmac.h
@@ -133,6 +133,9 @@ bool stmmac_eee_init(struct stmmac_priv *priv);
 #ifdef CONFIG_DWMAC_SUNXI
 extern const struct stmmac_of_data sun7i_gmac_data;
 #endif
+#ifdef CONFIG_DWMAC_STI
+extern const struct stmmac_of_data sti_gmac_data;
+#endif
 extern struct platform_driver stmmac_pltfr_driver;
 static inline int stmmac_register_platform(void)
 {
diff --git a/drivers/net/ethernet/stmicro/stmmac/stmmac_platform.c b/drivers/net/ethernet/stmicro/stmmac/stmmac_platform.c
index 5884a7d..c61bc72b 100644
--- a/drivers/net/ethernet/stmicro/stmmac/stmmac_platform.c
+++ b/drivers/net/ethernet/stmicro/stmmac/stmmac_platform.c
@@ -33,6 +33,11 @@ static const struct of_device_id stmmac_dt_ids[] = {
 #ifdef CONFIG_DWMAC_SUNXI
 	{ .compatible = "allwinner,sun7i-a20-gmac", .data = &sun7i_gmac_data},
 #endif
+#ifdef CONFIG_DWMAC_STI
+	{ .compatible = "st,stih415-dwmac", .data = &sti_gmac_data},
+	{ .compatible = "st,stih416-dwmac", .data = &sti_gmac_data},
+	{ .compatible = "st,stih127-dwmac", .data = &sti_gmac_data},
+#endif
 	/* SoC specific glue layers should come before generic bindings */
 	{ .compatible = "st,spear600-gmac"},
 	{ .compatible = "snps,dwmac-3.610"},
-- 
1.7.9.5

^ permalink raw reply related

* [PATCH v3 0/3] net: stmmac: Add STi GMAC ethernet
From: srinivas.kandagatla at st.com @ 2014-02-11  9:58 UTC (permalink / raw)
  To: linux-arm-kernel
In-Reply-To: <1391770455-24291-1-git-send-email-srinivas.kandagatla@st.com>

From: Srinivas Kandagatla <srinivas.kandagatla@st.com>

Hi All,

This patch series adds Ethernet support to STi series SOCs STiH415 and STiH416.
STi SOC series integrates dwmac IP from synopsis, however there is a hardware
glue on top of this standard IP, this glue needs to configured before the
actual dwmac can be used.  Also the glue logic needs re-configuring when the
link speed changes, This is because the clk source can change as the link
speed changes.

This patch just adds STi specific callbacks into of_data for configuring the
glue layer.

I have rebased my original patches (http://lkml.org/lkml/2013/11/12/243)
to latest stmmac which updates callbacks to suit glue drivers like this.

These patches are tested on b2000 and B2020 with STiH415 and STiH416.

Changes since v1:
 - fixed multi-line function call format as suggested by David Miller.

Changes since v2:
 - fix indenting issues & superfluous empty lines as suggested by David Miller.
 - Run the code through scripts/Lindent.

Dave, Can I request you to take the first patch via net tree for v3.15, I can
request Arnd or Olof to take the DT patches via the arm-soc tree for v3.15.

Thanks,
srini

Srinivas Kandagatla (3):
  net: stmmac:sti: Add STi SOC glue driver.
  ARM: STi: Add STiH415 ethernet support.
  ARM: STi: Add STiH416 ethernet support.

 .../devicetree/bindings/net/sti-dwmac.txt          |   58 ++++
 arch/arm/boot/dts/stih415-clock.dtsi               |   14 +
 arch/arm/boot/dts/stih415-pinctrl.dtsi             |  121 +++++++
 arch/arm/boot/dts/stih415.dtsi                     |   48 +++
 arch/arm/boot/dts/stih416-clock.dtsi               |   14 +
 arch/arm/boot/dts/stih416-pinctrl.dtsi             |  109 +++++++
 arch/arm/boot/dts/stih416.dtsi                     |   44 +++
 arch/arm/boot/dts/stih41x-b2000.dtsi               |   22 ++
 arch/arm/boot/dts/stih41x-b2020.dtsi               |   26 ++
 drivers/net/ethernet/stmicro/stmmac/Kconfig        |   11 +
 drivers/net/ethernet/stmicro/stmmac/Makefile       |    1 +
 drivers/net/ethernet/stmicro/stmmac/dwmac-sti.c    |  330 ++++++++++++++++++++
 drivers/net/ethernet/stmicro/stmmac/stmmac.h       |    3 +
 .../net/ethernet/stmicro/stmmac/stmmac_platform.c  |    5 +
 14 files changed, 806 insertions(+)
 create mode 100644 Documentation/devicetree/bindings/net/sti-dwmac.txt
 create mode 100644 drivers/net/ethernet/stmicro/stmmac/dwmac-sti.c

-- 
1.7.9.5

^ permalink raw reply

* [PATCH v1 0/1] Boot all secondary cores on Exynos SoC's
From: Sachin Kamat @ 2014-02-11  9:57 UTC (permalink / raw)
  To: linux-arm-kernel
In-Reply-To: <000501cf26fa$a69b2a60$f3d17f20$%dakhran@samsung.com>

Hi Tarek,

On 11 February 2014 12:56, Tarek Dakhran <t.dakhran@samsung.com> wrote:
> Hi Sachin,
>
>
>
> Current implementation allow to boot only one secondary core.
>
> This patch makes possible to boot 4 cores on Exynos5420 and Exynos5410 SoC's

I also get 4 cores up with the mainline kernel on SMDK 5420 board
without this patch.
Please see log below:

[    0.000000] Linux version 3.14.0-rc2-00027-gce8ee8a (sachin at linaro)
(gcc version 4.8.2 20130805 (prerelease) (crosstool-NG linaro-1
.13.1-4.8-2013.08 - Linaro GCC 2013.08) ) #76 SMP PREEMPT Tue Feb 11
15:18:30 IST 2014
[    0.000000] CPU: ARMv7 Processor [412fc0f3] revision 3 (ARMv7), cr=10c5387d
[    0.000000] CPU: PIPT / VIPT nonaliasing data cache, PIPT instruction cache
[    0.000000] Machine model: Samsung SMDK5420 board based on EXYNOS5420
[    0.000000] NR_BANKS too low, ignoring high memory
[    0.000000] Memory policy: Data cache writealloc
[    0.000000] CPU EXYNOS5420 (id 0xe5420200)
[    0.000000] On node 0 totalpages: 522240
[    0.000000]   Normal zone: 1520 pages used for memmap
[    0.000000]   Normal zone: 0 pages reserved
[    0.000000]   Normal zone: 194560 pages, LIFO batch:31
[    0.000000]   HighMem zone: 2576 pages used for memmap
[    0.000000]   HighMem zone: 327680 pages, LIFO batch:31
[    0.000000] PERCPU: Embedded 7 pages/cpu @ee795000 s7424 r8192 d13056 u32768
[    0.000000] pcpu-alloc: s7424 r8192 d13056 u32768 alloc=8*4096
[    0.000000] pcpu-alloc: [0] 0 [0] 1 [0] 2 [0] 3 [0] 4 [0] 5 [0] 6 [0] 7
[    0.000000] Built 1 zonelists in Zone order, mobility grouping on.
Total pages: 520720
[    0.000000] Kernel command line: root=/dev/mmcblk1p1 rw rootwait
console=ttySAC2,115200n8 init=/linuxrc earlyprintk loglevel=8 no_c
onsole_suspend
[    0.000000] PID hash table entries: 4096 (order: 2, 16384 bytes)
[    0.000000] Dentry cache hash table entries: 131072 (order: 7, 524288 bytes)
[    0.000000] Inode-cache hash table entries: 65536 (order: 6, 262144 bytes)
[    0.000000] Memory: 2065876K/2088960K available (3705K kernel code,
227K rwdata, 1124K rodata, 223K init, 263K bss, 23084K reserved
, 1310720K highmem)
[    0.000000] Virtual kernel memory layout:
[    0.000000]     vector  : 0xffff0000 - 0xffff1000   (   4 kB)
[    0.000000]     fixmap  : 0xfff00000 - 0xfffe0000   ( 896 kB)
[    0.000000]     vmalloc : 0xf0000000 - 0xff000000   ( 240 MB)
[    0.000000]     lowmem  : 0xc0000000 - 0xef800000   ( 760 MB)
[    0.000000]     pkmap   : 0xbfe00000 - 0xc0000000   (   2 MB)
[    0.000000]     modules : 0xbf000000 - 0xbfe00000   (  14 MB)
[    0.000000]       .text : 0xc0008000 - 0xc04bf6e8   (4830 kB)
[    0.000000]       .init : 0xc04c0000 - 0xc04f7d00   ( 224 kB)
[    0.000000]       .data : 0xc04f8000 - 0xc0530e80   ( 228 kB)
[    0.000000]        .bss : 0xc0530e8c - 0xc0572e34   ( 264 kB)
[    0.000000] SLUB: HWalign=64, Order=0-3, MinObjects=0, CPUs=8, Nodes=1
[    0.000000] Preemptible hierarchical RCU implementation.
[    0.000000] NR_IRQS:16 nr_irqs:16 16
[    0.000000] sched_clock: 32 bits at 200 Hz, resolution 5000000ns,
wraps every 10737418240000000ns
[    0.000000] Console: colour dummy device 80x30
[    0.045000] Calibrating delay loop... 1590.88 BogoMIPS (lpj=3977216)
[    0.045000] pid_max: default: 32768 minimum: 301
[    0.045000] Mount-cache hash table entries: 512
[    0.055000] CPU: Testing write buffer coherency: ok
[    0.055000] CPU0: update cpu_power 1535
[    0.055000] CPU0: thread -1, cpu 0, socket 0, mpidr 80000000
[    0.055000] Setting up static identity map for 0x20387210 - 0x20387268
[    0.075000] CPU1: Booted secondary processor
[    0.125000] CPU1: update cpu_power 1535
[    0.125000] CPU1: thread -1, cpu 1, socket 0, mpidr 80000001
[    0.135000] CPU2: Booted secondary processor
[    0.175000] CPU2: update cpu_power 1535
[    0.175000] CPU2: thread -1, cpu 2, socket 0, mpidr 80000002
[    0.185000] CPU3: Booted secondary processor
[    0.235000] CPU3: update cpu_power 1535
[    0.235000] CPU3: thread -1, cpu 3, socket 0, mpidr 80000003
[    1.245000] CPU4: failed to boot: -38
[    2.245000] CPU5: failed to boot: -38
[    3.255000] CPU6: failed to boot: -38
[    4.255000] CPU7: failed to boot: -38
[    4.255000] Brought up 4 CPUs
[    4.255000] SMP: Total of 4 processors activated.


Regards,
Sachin

>
> On Tue, Feb 11, 2014 at 3:17 PM, Sachin Kamat <sachin.kamat@linaro.org>
> wrote:
>
>>Hi Tarek,
>
>>
> On 11 February 2014 07:45, Tarek Dakhran <t.dakhran@samsung.com> wrote:
>> Due to implementation of exynos_boot_secondary function
>> only one secondary core boots on Exynos SoC's.
>
>>Even without this patch I could boot the secondary CPUs on Exynos4210, 4412
>> and
>>5250 based boards with the latest Linux kernel (v3.14-rc2+). Is this
>>patch required for
>>a specific use case or am I missing something?
>>
>>---
>>With warm regards,
>>Sachin
>
>
>
> Best regards,
>
>                 Tarek Dakhran



-- 
With warm regards,
Sachin

^ permalink raw reply

* [PATCHv2 2/2] arm: Get rid of meminfo
From: Marek Szyprowski @ 2014-02-11  9:47 UTC (permalink / raw)
  To: linux-arm-kernel
In-Reply-To: <1391558551-31395-3-git-send-email-lauraa@codeaurora.org>

Hello,

On 2014-02-05 01:02, Laura Abbott wrote:
> memblock is now fully integrated into the kernel and is the prefered
> method for tracking memory. Rather than reinvent the wheel with
> meminfo, migrate to using memblock directly instead of meminfo as
> an intermediate.
>
> Signed-off-by: Laura Abbott <lauraa@codeaurora.org>

This patch fails with SPARSEMEM enabled (tested with v3.14-rc1, 
exynos4_defconfig + oldnoconfig):

arch/arm/mm/init.c: In function ?free_unused_memmap?:
arch/arm/mm/init.c:442:10: error: ?prev_bank_end? undeclared (first use 
in this function)
arch/arm/mm/init.c:442:10: note: each undeclared identifier is reported 
only once for each function it appears in
make[1]: *** [arch/arm/mm/init.o] Error 1
make[1]: *** Waiting for unfinished jobs....


> ---
>   arch/arm/include/asm/mach/arch.h         |    4 +-
>   arch/arm/include/asm/memblock.h          |    3 +-
>   arch/arm/include/asm/setup.h             |   23 ------
>   arch/arm/kernel/atags_parse.c            |    5 +-
>   arch/arm/kernel/setup.c                  |   30 ++------
>   arch/arm/mach-clps711x/board-clep7312.c  |    7 +-
>   arch/arm/mach-clps711x/board-edb7211.c   |   10 +--
>   arch/arm/mach-clps711x/board-p720t.c     |    2 +-
>   arch/arm/mach-footbridge/cats-hw.c       |    2 +-
>   arch/arm/mach-footbridge/netwinder-hw.c  |    2 +-
>   arch/arm/mach-msm/board-halibut.c        |    6 --
>   arch/arm/mach-msm/board-mahimahi.c       |   13 +---
>   arch/arm/mach-msm/board-msm7x30.c        |    3 +-
>   arch/arm/mach-msm/board-sapphire.c       |   13 ++--
>   arch/arm/mach-msm/board-trout.c          |    8 +--
>   arch/arm/mach-orion5x/common.c           |    3 +-
>   arch/arm/mach-orion5x/common.h           |    3 +-
>   arch/arm/mach-pxa/cm-x300.c              |    3 +-
>   arch/arm/mach-pxa/corgi.c                |   10 +--
>   arch/arm/mach-pxa/eseries.c              |    9 +--
>   arch/arm/mach-pxa/poodle.c               |    8 +--
>   arch/arm/mach-pxa/spitz.c                |    9 +--
>   arch/arm/mach-pxa/tosa.c                 |    8 +--
>   arch/arm/mach-realview/core.c            |   11 +--
>   arch/arm/mach-realview/core.h            |    3 +-
>   arch/arm/mach-realview/realview_pb1176.c |    8 +--
>   arch/arm/mach-realview/realview_pbx.c    |   17 ++---
>   arch/arm/mach-s3c24xx/mach-smdk2413.c    |    8 +--
>   arch/arm/mach-s3c24xx/mach-vstms.c       |    8 +--
>   arch/arm/mach-sa1100/assabet.c           |    2 +-
>   arch/arm/mm/init.c                       |   61 ++++++----------
>   arch/arm/mm/mmu.c                        |  115 +++++++++---------------------
>   32 files changed, 133 insertions(+), 284 deletions(-)

(snipped)

Best regards
-- 
Marek Szyprowski, PhD
Samsung R&D Institute Poland

^ permalink raw reply

* [PATCH v6 01/19] clocksource: orion: Use atomic access for shared registers
From: Ezequiel Garcia @ 2014-02-11  9:47 UTC (permalink / raw)
  To: linux-arm-kernel
In-Reply-To: <52F9E947.5020004@linaro.org>

On Tue, Feb 11, 2014 at 10:11:35AM +0100, Daniel Lezcano wrote:
> On 02/11/2014 09:30 AM, Ezequiel Garcia wrote:
> > On Tue, Feb 11, 2014 at 01:06:43AM +0100, Daniel Lezcano wrote:
> >> On 02/06/2014 06:20 PM, Ezequiel Garcia wrote:
> >>> Replace the driver-specific thread-safe shared register API
> >>> by the recently introduced atomic_io_clear_set().
> >>>
> >>> Cc: Daniel Lezcano <daniel.lezcano@linaro.org>
> >>> Tested-by: Sebastian Hesselbarth <sebastian.hesselbarth@gmail.com>
> >>> Tested-by: Willy Tarreau <w@1wt.eu>
> >>> Acked-by: Jason Cooper <jason@lakedaemon.net>
> >>> Signed-off-by: Ezequiel Garcia <ezequiel.garcia@free-electrons.com>
> >>
> >> The patch looks good for me.
> >>
> >> Acked-by: Daniel Lezcano <daniel.lezcano@linaro.org>
> >>
> >
> > Daniel,
> >
> > Jason acked this patch for you to take it. Or do you prefer that we
> > merge it with the rest of the watchdog series?
> 
> I can pick it, but doesn't the watchdog series depend on it ?
> 

Nope. It's indepedent of it.
-- 
Ezequiel Garc?a, Free Electrons
Embedded Linux, Kernel and Android Engineering
http://free-electrons.com

^ permalink raw reply

* [PATCH v2 0/2] clocksource: sunxi: Change compatibles pattern
From: Daniel Lezcano @ 2014-02-11  9:34 UTC (permalink / raw)
  To: linux-arm-kernel
In-Reply-To: <1391679632-15139-1-git-send-email-maxime.ripard@free-electrons.com>

On 02/06/2014 10:40 AM, Maxime Ripard wrote:
> Hi,
>
> This is the second version of the clocksource compatible changes.
> The only difference with the v1 being that we're now droping the old
> compatibles, instead of keeping them, since the DT maintainers said it was
> fine.

Hi Maxime,

applied to my tree for 3.15

Thanks
   -- Daniel


-- 
  <http://www.linaro.org/> Linaro.org ? Open source software for ARM SoCs

Follow Linaro:  <http://www.facebook.com/pages/Linaro> Facebook |
<http://twitter.com/#!/linaroorg> Twitter |
<http://www.linaro.org/linaro-blog/> Blog

^ permalink raw reply

* [PATCH] reset: Add generic GPIO reset driver.
From: Fuzzey, Martin @ 2014-02-11  9:34 UTC (permalink / raw)
  To: linux-arm-kernel
In-Reply-To: <1392038191.6687.12.camel@pizza.hi.pengutronix.de>

Hi Philipp,

On 10 February 2014 14:16, Philipp Zabel <p.zabel@pengutronix.de> wrote:
> Hi Martin,
>
> Am Montag, den 10.02.2014, 13:54 +0100 schrieb Martin Fuzzey:
>> This driver allows GPIO lines to be used as reset signals.
>> It has two main use cases:
>>
>> 1) Allow drivers to reset their hardware via a GPIO line in a standard fashion
>> as supplied by the reset framework.
>> This allows adhoc driver code requesting GPIOs etc to be replaced with a
>> single call to device_reset().
>
> have you seen the patch at https://lkml.org/lkml/2014/1/8/190:
> "reset: Add GPIO support to reset controller framework" ?
>

Ah no missed that.

> Adding a GPIO reset controller device node to the device tree is the
> wrong approach for devices enumerated in the device tree. Those should
> just declare their reset-gpios directly.
>

Oh well if that was the conclusion.
My use case is 2) anyway - just thought it would be sensible to
implement a reset controller too.
As that simplifies the driver code and makes gpio / vs more complex
reset controller (FPGA, ..) a pure DT change.

I do get the point about having to continue to support the old way
anyway though.


>> 2) Allow hardware on discoverable busses to be rest via a GPIO line
>> without driver modifications.
>>
>> Examples of the second use case include:
>> * SDIO wifi modules
>> * USB hub chips with a reset line
>
> Now this is interesting. But if you export it to userspace anyway, why
> not use the existing gpio sysfs API?
>

In the normal case of reset on boot the userspace interface isn't needed.
Setting the "auto" dt property will make the kernel do the reset by
itself during
early boot. This is the standard use case.

The userspace interface is to let applications deal with special cases.
It is also simpler for userspace than manlually toggling the GPIO line
and keeps the configuration (active high / low, delay) centralised in
the DT and consistent between the automatic on boot reset and the
manually triggered reset.


> I think a proper solution should handle this in the kernel. For SDIO
> wifi modules you usually have a powerdown line that can be implemented
> as an rfkill switch.
>

I think this is too specific. It's not just for SDIO wifi. We also
have the problem
of a USB hub needing to be reset.

Also even for the SDIO wifi case rfkill doesn't ssem the right
abstraction to say "reset me"
(particularly when firmware fails to load on warm boot if you don't).

cheers,

Martin

^ permalink raw reply

* [linux-sunxi] Re: [PATCH 1/3] mfd: axp20x: Add mfd driver for axp20x PMIC
From: Carlo Caione @ 2014-02-11  9:33 UTC (permalink / raw)
  To: linux-arm-kernel
In-Reply-To: <20140211091505.GE32042@lee--X1>

On Tue, Feb 11, 2014 at 10:15 AM, Lee Jones <lee.jones@linaro.org> wrote:
>> >> +const struct of_device_id axp20x_of_match[] = {
>> >> +     { .compatible = "x-powers,axp20x", .data = (void *)AXP20X },
>> >
>> > There's no need to add device IDs if you only support one device.
>>
>> Ok. But what if in the future we want to add a new device?
>
> Then we add support for device identification. Until then, it's just
> meaningless cruft.

Ok, I'll get rid of it in v2.

>> >> +     { },
>> >> +};
>> >> +
>> >> +static struct axp20x_dev *axp20x_pm_power_off;
>> >
>> > This looks pretty unconventional. What's the point of it?
>>
>> On a single board we can have multiple AXPs so I track which one is in
>> charge of powering off the board (and to get the correct device in the
>> axp20x_power_off())
>
> Is it this device's responsibility to shut down the _entire_ board? Or
> does the call below only turn off _this_ device?

AXP shutdowns the entire board

>> >> +static void axp20x_power_off(void)
>> >> +{
>> >> +     regmap_write(axp20x_pm_power_off->regmap, AXP20X_OFF_CTRL, 0x80);
>
> <snip>
>
>> >> +     of_id = of_match_device(axp20x_of_match, &i2c->dev);
>> >> +     if (!of_id) {
>> >> +             dev_err(&i2c->dev, "Unable to setup AXP20X data\n");
>> >> +             return -ENODEV;
>> >> +     }
>> >> +     axp20x->variant = (int) of_id->data;
>> >
>> > Lots of code here surrounding added device support, but only one
>> > device is supported. Why so?
>>
>> Because at the moment I support only axp202 and axp209 but I wanted
>> something future-proof
>
> Nothing is future-proof. :)
>
> You only need to add this functionality when it's going to be
> utilised.

I agree. Fix in v2.

>> >> +     axp20x->i2c_client = i2c;
>> >> +     i2c_set_clientdata(i2c, axp20x);
>> >> +
>> >> +     axp20x->dev = &i2c->dev;
>> >> +     dev_set_drvdata(axp20x->dev, axp20x);
>> >
>> > Do you make use of all this saving of the device container?
>> >
>> > If so, where?
>>
>> In the drivers for subsystems (input, regulators, gpio, etc..)
>
> Can you link me to the patches please?  Any reason why they're not in
> this set?  By submitting them together you give the Maintainers a good
> over-view on how the system works together.

I wasn't sure it was a good idea to submit all the drivers altogether,
so my idea was to submit one driver at a time.
Do you think is it better to submit all the subsystems in one patch-set?

>> > Also:
>> >   i2c_set_clientdata(i2c)
>> >
>> > and:
>> >   dev_set_drvdata(i2c->dev);
>> >
>> > ... do exactly the same thing i.e. set i2c->dev->p->device_data.
>>
>> Right.
>
> Right.  So why are you doing them both?

Right == I'll fix it :)

Thank you,

-- 
Carlo Caione

^ permalink raw reply

* [PATCH v9 2/4] ehci-platform: Add support for clks and phy passed through devicetree
From: Hans de Goede @ 2014-02-11  9:31 UTC (permalink / raw)
  To: linux-arm-kernel
In-Reply-To: <52F9E98B.90407@ti.com>

Hi,

On 02/11/2014 10:12 AM, Roger Quadros wrote:
> Hi Hans,
> 
> On 02/07/2014 05:36 PM, Hans de Goede wrote:
>> Currently ehci-platform is only used in combination with devicetree when used
>> with some Via socs. By extending it to (optionally) get clks and a phy from
>> devicetree, and enabling / disabling those on power_on / off, it can be used
>> more generically. Specifically after this commit it can be used for the
>> ehci controller on Allwinner sunxi SoCs.
>>
>> Since ehci-platform is intended to handle any generic enough non pci ehci
>> device, add a "usb-ehci" compatibility string.
>>
>> There already is a usb-ehci device-tree bindings document, update this
>> with clks and phy bindings info.
>>
>> Although actually quite generic so far the via,vt8500 compatibilty string
>> had its own bindings document. Somehow we even ended up with 2 of them. Since
>> these provide no extra information over the generic usb-ehci documentation,
>> this patch removes them.
>>
>> The ehci-ppc-of.c driver also claims the usb-ehci compatibility string,
>> even though it mostly is ibm,usb-ehci-440epx specific. ehci-platform.c is
>> not needed on ppc platforms, so add a !PPC_OF dependency to it to avoid
>> 2 drivers claiming the same compatibility string getting build on ppc.
>>
> 
> This breaks all OMAP platforms on linux-next for the exact same reason. see [1].
> 
> ./arch/arm/boot/dts/omap4.dtsi:				compatible = "ti,ehci-omap", "usb-ehci";
> ./arch/arm/boot/dts/omap3.dtsi:				compatible = "ti,ehci-omap", "usb-ehci";
> ./arch/arm/boot/dts/omap5.dtsi:				compatible = "ti,ehci-omap", "usb-ehci";

That should not be the case, the driver core should try to find a driver matching
the compatibility string from left to right, or in other words from most specific
to least specific. This is part of the whole devicetree design.

So as long as the driver claiming "ti,ehci-omap" is available at probe time that
one should get used and things should work fine. Now if ehci-platform is built-in
and ehci-omap is a module, then I guess one could see the described breakage.

If the driver is built-in and things are not working, then we will need to do some
debugging as to why the left to right matching is not working as expected.

I must admit I'm not sure what happens if both are a module, the kernel direct
module load will likely fail due to lack of a rootfs at that point, and then
the module will later get loaded by udev I assume, at which point there are no
loading ordering guarantees.

The easiest solution to ensure that "ti,ehci-omap" is available at probe time
(if enabled) seems to be to change USB_EHCI_HCD_OMAP to a boolean.

Regards,

Hans



> 
> 
> The other platforms that claim compatibility with "usb-ehci" are
> 
> ARM
> ./arch/arm/boot/dts/tegra30.dtsi:		compatible = "nvidia,tegra30-ehci", "usb-ehci";
> ./arch/arm/boot/dts/tegra20.dtsi:		compatible = "nvidia,tegra20-ehci", "usb-ehci";
> ./arch/arm/boot/dts/spear600.dtsi:			compatible = "st,spear600-ehci", "usb-ehci";
> 
> ./arch/arm/boot/dts/spear3xx.dtsi:			compatible = "st,spear600-ehci", "usb-ehci";
> ./arch/arm/boot/dts/sama5d3.dtsi:			compatible = "atmel,at91sam9g45-ehci", "usb-ehci";
> ./arch/arm/boot/dts/at91sam9g45.dtsi:			compatible = "atmel,at91sam9g45-ehci", "usb-ehci";
> ./arch/arm/boot/dts/spear13xx.dtsi:			compatible = "st,spear600-ehci", "usb-ehci";
> ./arch/arm/boot/dts/at91sam9x5.dtsi:			compatible = "atmel,at91sam9g45-ehci", "usb-ehci";
> ./arch/arm/boot/dts/tegra114.dtsi:		compatible = "nvidia,tegra30-ehci", "usb-ehci";
> 
> 
> MIPS
> ./arch/mips/cavium-octeon/octeon_68xx.dts:				compatible = "cavium,octeon-6335-ehci","usb-ehci";
> ./arch/mips/cavium-octeon/octeon_3xxx.dts:				compatible = "cavium,octeon-6335-ehci","usb-ehci";
> 
> Do we know that we don't break these platforms as well?
> 
> cheers,
> -roger
> 
> [1] - http://marc.info/?l=linux-usb&m=139204800102167&w=2
> 
>> Signed-off-by: Hans de Goede <hdegoede@redhat.com>
>> Acked-by: Alan Stern <stern@rowland.harvard.edu>
>> ---
>>  Documentation/devicetree/bindings/usb/usb-ehci.txt |  25 +++-
>>  .../devicetree/bindings/usb/via,vt8500-ehci.txt    |  15 ---
>>  .../devicetree/bindings/usb/vt8500-ehci.txt        |  12 --
>>  drivers/usb/host/Kconfig                           |   1 +
>>  drivers/usb/host/ehci-platform.c                   | 147 +++++++++++++++++----
>>  5 files changed, 142 insertions(+), 58 deletions(-)
>>  delete mode 100644 Documentation/devicetree/bindings/usb/via,vt8500-ehci.txt
>>  delete mode 100644 Documentation/devicetree/bindings/usb/vt8500-ehci.txt
>>
>> diff --git a/Documentation/devicetree/bindings/usb/usb-ehci.txt b/Documentation/devicetree/bindings/usb/usb-ehci.txt
>> index fa18612..2c1aeeb 100644
>> --- a/Documentation/devicetree/bindings/usb/usb-ehci.txt
>> +++ b/Documentation/devicetree/bindings/usb/usb-ehci.txt
>> @@ -7,13 +7,14 @@ Required properties:
>>      (debug-port or other) can be also specified here, but only after
>>      definition of standard EHCI registers.
>>    - interrupts : one EHCI interrupt should be described here.
>> -If device registers are implemented in big endian mode, the device
>> -node should have "big-endian-regs" property.
>> -If controller implementation operates with big endian descriptors,
>> -"big-endian-desc" property should be specified.
>> -If both big endian registers and descriptors are used by the controller
>> -implementation, "big-endian" property can be specified instead of having
>> -both "big-endian-regs" and "big-endian-desc".
>> +
>> +Optional properties:
>> + - big-endian-regs : boolean, set this for hcds with big-endian registers
>> + - big-endian-desc : boolean, set this for hcds with big-endian descriptors
>> + - big-endian : boolean, for hcds with big-endian-regs + big-endian-desc
>> + - clocks : a list of phandle + clock specifier pairs
>> + - phys : phandle + phy specifier pair
>> + - phy-names : "usb"
>>  
>>  Example (Sequoia 440EPx):
>>      ehci at e0000300 {
>> @@ -23,3 +24,13 @@ Example (Sequoia 440EPx):
>>  	   reg = <0 e0000300 90 0 e0000390 70>;
>>  	   big-endian;
>>     };
>> +
>> +Example (Allwinner sun4i A10 SoC):
>> +   ehci0: usb at 01c14000 {
>> +	   compatible = "allwinner,sun4i-a10-ehci", "usb-ehci";
>> +	   reg = <0x01c14000 0x100>;
>> +	   interrupts = <39>;
>> +	   clocks = <&ahb_gates 1>;
>> +	   phys = <&usbphy 1>;
>> +	   phy-names = "usb";
>> +   };
>> diff --git a/Documentation/devicetree/bindings/usb/via,vt8500-ehci.txt b/Documentation/devicetree/bindings/usb/via,vt8500-ehci.txt
>> deleted file mode 100644
>> index 17b3ad1..0000000
>> --- a/Documentation/devicetree/bindings/usb/via,vt8500-ehci.txt
>> +++ /dev/null
>> @@ -1,15 +0,0 @@
>> -VIA/Wondermedia VT8500 EHCI Controller
>> ------------------------------------------------------
>> -
>> -Required properties:
>> -- compatible : "via,vt8500-ehci"
>> -- reg : Should contain 1 register ranges(address and length)
>> -- interrupts : ehci controller interrupt
>> -
>> -Example:
>> -
>> -	ehci at d8007900 {
>> -		compatible = "via,vt8500-ehci";
>> -		reg = <0xd8007900 0x200>;
>> -		interrupts = <43>;
>> -	};
>> diff --git a/Documentation/devicetree/bindings/usb/vt8500-ehci.txt b/Documentation/devicetree/bindings/usb/vt8500-ehci.txt
>> deleted file mode 100644
>> index 5fb8fd6..0000000
>> --- a/Documentation/devicetree/bindings/usb/vt8500-ehci.txt
>> +++ /dev/null
>> @@ -1,12 +0,0 @@
>> -VIA VT8500 and Wondermedia WM8xxx SoC USB controllers.
>> -
>> -Required properties:
>> - - compatible: Should be "via,vt8500-ehci" or "wm,prizm-ehci".
>> - - reg: Address range of the ehci registers. size should be 0x200
>> - - interrupts: Should contain the ehci interrupt.
>> -
>> -usb: ehci at D8007100 {
>> -	compatible = "wm,prizm-ehci", "usb-ehci";
>> -	reg = <0xD8007100 0x200>;
>> -	interrupts = <1>;
>> -};
>> diff --git a/drivers/usb/host/Kconfig b/drivers/usb/host/Kconfig
>> index a9707da..e28cbe0 100644
>> --- a/drivers/usb/host/Kconfig
>> +++ b/drivers/usb/host/Kconfig
>> @@ -255,6 +255,7 @@ config USB_EHCI_ATH79
>>  
>>  config USB_EHCI_HCD_PLATFORM
>>  	tristate "Generic EHCI driver for a platform device"
>> +	depends on !PPC_OF
>>  	default n
>>  	---help---
>>  	  Adds an EHCI host driver for a generic platform device, which
>> diff --git a/drivers/usb/host/ehci-platform.c b/drivers/usb/host/ehci-platform.c
>> index 01536cf..5ebd0b7 100644
>> --- a/drivers/usb/host/ehci-platform.c
>> +++ b/drivers/usb/host/ehci-platform.c
>> @@ -3,6 +3,7 @@
>>   *
>>   * Copyright 2007 Steven Brown <sbrown@cortland.com>
>>   * Copyright 2010-2012 Hauke Mehrtens <hauke@hauke-m.de>
>> + * Copyright 2014 Hans de Goede <hdegoede@redhat.com>
>>   *
>>   * Derived from the ohci-ssb driver
>>   * Copyright 2007 Michael Buesch <m@bues.ch>
>> @@ -18,6 +19,7 @@
>>   *
>>   * Licensed under the GNU/GPL. See COPYING for details.
>>   */
>> +#include <linux/clk.h>
>>  #include <linux/dma-mapping.h>
>>  #include <linux/err.h>
>>  #include <linux/kernel.h>
>> @@ -25,6 +27,7 @@
>>  #include <linux/io.h>
>>  #include <linux/module.h>
>>  #include <linux/of.h>
>> +#include <linux/phy/phy.h>
>>  #include <linux/platform_device.h>
>>  #include <linux/usb.h>
>>  #include <linux/usb/hcd.h>
>> @@ -33,6 +36,13 @@
>>  #include "ehci.h"
>>  
>>  #define DRIVER_DESC "EHCI generic platform driver"
>> +#define EHCI_MAX_CLKS 3
>> +#define hcd_to_ehci_priv(h) ((struct ehci_platform_priv *)hcd_to_ehci(h)->priv)
>> +
>> +struct ehci_platform_priv {
>> +	struct clk *clks[EHCI_MAX_CLKS];
>> +	struct phy *phy;
>> +};
>>  
>>  static const char hcd_name[] = "ehci-platform";
>>  
>> @@ -64,38 +74,90 @@ static int ehci_platform_reset(struct usb_hcd *hcd)
>>  	return 0;
>>  }
>>  
>> +static int ehci_platform_power_on(struct platform_device *dev)
>> +{
>> +	struct usb_hcd *hcd = platform_get_drvdata(dev);
>> +	struct ehci_platform_priv *priv = hcd_to_ehci_priv(hcd);
>> +	int clk, ret;
>> +
>> +	for (clk = 0; clk < EHCI_MAX_CLKS && priv->clks[clk]; clk++) {
>> +		ret = clk_prepare_enable(priv->clks[clk]);
>> +		if (ret)
>> +			goto err_disable_clks;
>> +	}
>> +
>> +	if (priv->phy) {
>> +		ret = phy_init(priv->phy);
>> +		if (ret)
>> +			goto err_disable_clks;
>> +
>> +		ret = phy_power_on(priv->phy);
>> +		if (ret)
>> +			goto err_exit_phy;
>> +	}
>> +
>> +	return 0;
>> +
>> +err_exit_phy:
>> +	phy_exit(priv->phy);
>> +err_disable_clks:
>> +	while (--clk >= 0)
>> +		clk_disable_unprepare(priv->clks[clk]);
>> +
>> +	return ret;
>> +}
>> +
>> +static void ehci_platform_power_off(struct platform_device *dev)
>> +{
>> +	struct usb_hcd *hcd = platform_get_drvdata(dev);
>> +	struct ehci_platform_priv *priv = hcd_to_ehci_priv(hcd);
>> +	int clk;
>> +
>> +	if (priv->phy) {
>> +		phy_power_off(priv->phy);
>> +		phy_exit(priv->phy);
>> +	}
>> +
>> +	for (clk = EHCI_MAX_CLKS - 1; clk >= 0; clk--)
>> +		if (priv->clks[clk])
>> +			clk_disable_unprepare(priv->clks[clk]);
>> +}
>> +
>>  static struct hc_driver __read_mostly ehci_platform_hc_driver;
>>  
>>  static const struct ehci_driver_overrides platform_overrides __initconst = {
>> -	.reset =	ehci_platform_reset,
>> +	.reset =		ehci_platform_reset,
>> +	.extra_priv_size =	sizeof(struct ehci_platform_priv),
>>  };
>>  
>> -static struct usb_ehci_pdata ehci_platform_defaults;
>> +static struct usb_ehci_pdata ehci_platform_defaults = {
>> +	.power_on =		ehci_platform_power_on,
>> +	.power_suspend =	ehci_platform_power_off,
>> +	.power_off =		ehci_platform_power_off,
>> +};
>>  
>>  static int ehci_platform_probe(struct platform_device *dev)
>>  {
>>  	struct usb_hcd *hcd;
>>  	struct resource *res_mem;
>> -	struct usb_ehci_pdata *pdata;
>> -	int irq;
>> -	int err;
>> +	struct usb_ehci_pdata *pdata = dev_get_platdata(&dev->dev);
>> +	struct ehci_platform_priv *priv;
>> +	int err, irq, clk = 0;
>>  
>>  	if (usb_disabled())
>>  		return -ENODEV;
>>  
>>  	/*
>> -	 * use reasonable defaults so platforms don't have to provide these.
>> -	 * with DT probing on ARM, none of these are set.
>> +	 * Use reasonable defaults so platforms don't have to provide these
>> +	 * with DT probing on ARM.
>>  	 */
>> -	if (!dev_get_platdata(&dev->dev))
>> -		dev->dev.platform_data = &ehci_platform_defaults;
>> +	if (!pdata)
>> +		pdata = &ehci_platform_defaults;
>>  
>>  	err = dma_coerce_mask_and_coherent(&dev->dev, DMA_BIT_MASK(32));
>>  	if (err)
>>  		return err;
>>  
>> -	pdata = dev_get_platdata(&dev->dev);
>> -
>>  	irq = platform_get_irq(dev, 0);
>>  	if (irq < 0) {
>>  		dev_err(&dev->dev, "no irq provided");
>> @@ -107,17 +169,40 @@ static int ehci_platform_probe(struct platform_device *dev)
>>  		return -ENXIO;
>>  	}
>>  
>> +	hcd = usb_create_hcd(&ehci_platform_hc_driver, &dev->dev,
>> +			     dev_name(&dev->dev));
>> +	if (!hcd)
>> +		return -ENOMEM;
>> +
>> +	platform_set_drvdata(dev, hcd);
>> +	dev->dev.platform_data = pdata;
>> +	priv = hcd_to_ehci_priv(hcd);
>> +
>> +	if (pdata == &ehci_platform_defaults && dev->dev.of_node) {
>> +		priv->phy = devm_phy_get(&dev->dev, "usb");
>> +		if (IS_ERR(priv->phy)) {
>> +			err = PTR_ERR(priv->phy);
>> +			if (err == -EPROBE_DEFER)
>> +				goto err_put_hcd;
>> +			priv->phy = NULL;
>> +		}
>> +
>> +		for (clk = 0; clk < EHCI_MAX_CLKS; clk++) {
>> +			priv->clks[clk] = of_clk_get(dev->dev.of_node, clk);
>> +			if (IS_ERR(priv->clks[clk])) {
>> +				err = PTR_ERR(priv->clks[clk]);
>> +				if (err == -EPROBE_DEFER)
>> +					goto err_put_clks;
>> +				priv->clks[clk] = NULL;
>> +				break;
>> +			}
>> +		}
>> +	}
>> +
>>  	if (pdata->power_on) {
>>  		err = pdata->power_on(dev);
>>  		if (err < 0)
>> -			return err;
>> -	}
>> -
>> -	hcd = usb_create_hcd(&ehci_platform_hc_driver, &dev->dev,
>> -			     dev_name(&dev->dev));
>> -	if (!hcd) {
>> -		err = -ENOMEM;
>> -		goto err_power;
>> +			goto err_put_clks;
>>  	}
>>  
>>  	hcd->rsrc_start = res_mem->start;
>> @@ -126,22 +211,28 @@ static int ehci_platform_probe(struct platform_device *dev)
>>  	hcd->regs = devm_ioremap_resource(&dev->dev, res_mem);
>>  	if (IS_ERR(hcd->regs)) {
>>  		err = PTR_ERR(hcd->regs);
>> -		goto err_put_hcd;
>> +		goto err_power;
>>  	}
>>  	err = usb_add_hcd(hcd, irq, IRQF_SHARED);
>>  	if (err)
>> -		goto err_put_hcd;
>> +		goto err_power;
>>  
>>  	device_wakeup_enable(hcd->self.controller);
>>  	platform_set_drvdata(dev, hcd);
>>  
>>  	return err;
>>  
>> -err_put_hcd:
>> -	usb_put_hcd(hcd);
>>  err_power:
>>  	if (pdata->power_off)
>>  		pdata->power_off(dev);
>> +err_put_clks:
>> +	while (--clk >= 0)
>> +		clk_put(priv->clks[clk]);
>> +err_put_hcd:
>> +	if (pdata == &ehci_platform_defaults)
>> +		dev->dev.platform_data = NULL;
>> +
>> +	usb_put_hcd(hcd);
>>  
>>  	return err;
>>  }
>> @@ -150,13 +241,19 @@ static int ehci_platform_remove(struct platform_device *dev)
>>  {
>>  	struct usb_hcd *hcd = platform_get_drvdata(dev);
>>  	struct usb_ehci_pdata *pdata = dev_get_platdata(&dev->dev);
>> +	struct ehci_platform_priv *priv = hcd_to_ehci_priv(hcd);
>> +	int clk;
>>  
>>  	usb_remove_hcd(hcd);
>> -	usb_put_hcd(hcd);
>>  
>>  	if (pdata->power_off)
>>  		pdata->power_off(dev);
>>  
>> +	for (clk = 0; clk < EHCI_MAX_CLKS && priv->clks[clk]; clk++)
>> +		clk_put(priv->clks[clk]);
>> +
>> +	usb_put_hcd(hcd);
>> +
>>  	if (pdata == &ehci_platform_defaults)
>>  		dev->dev.platform_data = NULL;
>>  
>> @@ -207,8 +304,10 @@ static int ehci_platform_resume(struct device *dev)
>>  static const struct of_device_id vt8500_ehci_ids[] = {
>>  	{ .compatible = "via,vt8500-ehci", },
>>  	{ .compatible = "wm,prizm-ehci", },
>> +	{ .compatible = "usb-ehci", },
>>  	{}
>>  };
>> +MODULE_DEVICE_TABLE(of, vt8500_ehci_ids);
>>  
>>  static const struct platform_device_id ehci_platform_table[] = {
>>  	{ "ehci-platform", 0 },
>>
> 

^ permalink raw reply

* [PATCH V6 11/12] SPEAr13xx: defconfig: Update
From: Mohit Kumar @ 2014-02-11  9:30 UTC (permalink / raw)
  To: linux-arm-kernel
In-Reply-To: <cover.1392109054.git.mohit.kumar@st.com>

Enable PCIe, EABI, VFP and NFS configs in default configuration file for
SPEAr13xx.

Signed-off-by: Mohit Kumar <mohit.kumar@st.com>
Acked-by: Viresh Kumar <viresh.kumar@linaro.org>
Cc: Pratyush Anand <pratyush.anand@st.com>
Cc: Arnd Bergmann <arnd@arndb.de>
Cc: spear-devel at list.st.com
Cc: linux-arm-kernel at lists.infradead.org
---
 arch/arm/configs/spear13xx_defconfig |   16 ++++++++++++++++
 1 files changed, 16 insertions(+), 0 deletions(-)

diff --git a/arch/arm/configs/spear13xx_defconfig b/arch/arm/configs/spear13xx_defconfig
index 82eaa55..d271b26 100644
--- a/arch/arm/configs/spear13xx_defconfig
+++ b/arch/arm/configs/spear13xx_defconfig
@@ -11,13 +11,24 @@ CONFIG_ARCH_SPEAR13XX=y
 CONFIG_MACH_SPEAR1310=y
 CONFIG_MACH_SPEAR1340=y
 # CONFIG_SWP_EMULATE is not set
+CONFIG_PCI=y
+CONFIG_PCI_MSI=y
+CONFIG_PCIE_SPEAR13XX=y
 CONFIG_SMP=y
 # CONFIG_SMP_ON_UP is not set
 # CONFIG_ARM_CPU_TOPOLOGY is not set
+CONFIG_AEABI=y
 CONFIG_ARM_APPENDED_DTB=y
 CONFIG_ARM_ATAG_DTB_COMPAT=y
+CONFIG_VFP=y
 CONFIG_BINFMT_MISC=y
 CONFIG_NET=y
+CONFIG_UNIX=y
+CONFIG_INET=y
+CONFIG_IP_PNP=y
+CONFIG_IP_PNP_DHCP=y
+CONFIG_IP_PNP_BOOTP=y
+CONFIG_NET_IPIP=y
 CONFIG_UEVENT_HELPER_PATH="/sbin/hotplug"
 CONFIG_MTD=y
 CONFIG_MTD_OF_PARTS=y
@@ -27,6 +38,7 @@ CONFIG_MTD_NAND=y
 CONFIG_MTD_NAND_FSMC=y
 CONFIG_BLK_DEV_RAM=y
 CONFIG_BLK_DEV_RAM_SIZE=16384
+CONFIG_BLK_DEV_SD=y
 CONFIG_ATA=y
 # CONFIG_SATA_PMP is not set
 CONFIG_SATA_AHCI_PLATFORM=y
@@ -66,6 +78,7 @@ CONFIG_USB=y
 # CONFIG_USB_DEVICE_CLASS is not set
 CONFIG_USB_EHCI_HCD=y
 CONFIG_USB_OHCI_HCD=y
+CONFIG_USB_STORAGE=y
 CONFIG_MMC=y
 CONFIG_MMC_SDHCI=y
 CONFIG_MMC_SDHCI_SPEAR=y
@@ -79,11 +92,14 @@ CONFIG_EXT2_FS_SECURITY=y
 CONFIG_EXT3_FS=y
 CONFIG_EXT3_FS_SECURITY=y
 CONFIG_AUTOFS4_FS=m
+CONFIG_FUSE_FS=y
 CONFIG_MSDOS_FS=m
 CONFIG_VFAT_FS=m
 CONFIG_FAT_DEFAULT_IOCHARSET="ascii"
 CONFIG_TMPFS=y
 CONFIG_JFFS2_FS=y
+CONFIG_NFS_FS=y
+CONFIG_ROOT_NFS=y
 CONFIG_NLS_DEFAULT="utf8"
 CONFIG_NLS_CODEPAGE_437=y
 CONFIG_NLS_ASCII=m
-- 
1.7.0.1

^ permalink raw reply related

* [PATCH V6 09/12] SPEAr13XX: dts: Add PCIe node information
From: Mohit Kumar @ 2014-02-11  9:30 UTC (permalink / raw)
  To: linux-arm-kernel
In-Reply-To: <cover.1392109054.git.mohit.kumar@st.com>

From: Pratyush Anand <pratyush.anand@st.com>

SPEAr1310 and SPEAr1340 supports 3 and 1 PCIe controller respectively.
These controllers are based on synopsis designware controller.

Signed-off-by: Pratyush Anand <pratyush.anand@st.com>
Cc: Mohit Kumar <mohit.kumar@st.com>
Cc: Arnd Bergmann <arnd@arndb.de>
Cc: Viresh Kumar <viresh.linux@gmail.com>
Cc: spear-devel at list.st.com
Cc: linux-arm-kernel at lists.infradead.org
---
 arch/arm/boot/dts/spear1310.dtsi |   48 ++++++++++++++++++++++++++++++++++++++
 arch/arm/boot/dts/spear1340.dtsi |   16 ++++++++++++
 2 files changed, 64 insertions(+), 0 deletions(-)

diff --git a/arch/arm/boot/dts/spear1310.dtsi b/arch/arm/boot/dts/spear1310.dtsi
index 64e7dd5..136a12d 100644
--- a/arch/arm/boot/dts/spear1310.dtsi
+++ b/arch/arm/boot/dts/spear1310.dtsi
@@ -83,6 +83,54 @@
 			status = "disabled";
 		};
 
+		pcie0: pcie at b1000000 {
+			compatible = "st,spear1340-pcie", "snps,dw-pcie";
+			reg = <0xb1000000 0x4000>;
+			interrupts = <0 68 0x4>;
+			interrupt-map-mask = <0 0 0 0>;
+			interrupt-map = <0x0 0 &gic 68>;
+			num-lanes = <1>;
+			#address-cells = <3>;
+			#size-cells = <2>;
+			device_type = "pci";
+			ranges = <0x00000800 0 0x80000000 0x80000000 0 0x00020000   /* configuration space */
+				0x81000000 0 0	 0x80020000 0 0x00010000   /* downstream I/O */
+				0x82000000 0 0x80030000 0xc0030000 0 0x0ffd0000>; /* non-prefetchable memory */
+			status = "disabled";
+		};
+
+		pcie1: pcie at b1800000 {
+			compatible = "st,spear1340-pcie", "snps,dw-pcie";
+			reg = <0xb1800000 0x4000>;
+			interrupts = <0 69 0x4>;
+			interrupt-map-mask = <0 0 0 0>;
+			interrupt-map = <0x0 0 &gic 69>;
+			num-lanes = <1>;
+			#address-cells = <3>;
+			#size-cells = <2>;
+			device_type = "pci";
+			ranges = <0x00000800 0 0x90000000 0x90000000 0 0x00020000   /* configuration space */
+				0x81000000 0 0  0x90020000 0 0x00010000   /* downstream I/O */
+				0x82000000 0 0x90030000 0x90030000 0 0x0ffd0000>; /* non-prefetchable memory */
+			status = "disabled";
+		};
+
+		pcie2: pcie at b4000000 {
+			compatible = "st,spear1340-pcie", "snps,dw-pcie";
+			reg = <0xb4000000 0x4000>;
+			interrupts = <0 70 0x4>;
+			interrupt-map-mask = <0 0 0 0>;
+			interrupt-map = <0x0 0 &gic 70>;
+			num-lanes = <1>;
+			#address-cells = <3>;
+			#size-cells = <2>;
+			device_type = "pci";
+			ranges = <0x00000800 0 0xc0000000 0xc0000000 0 0x00020000   /* configuration space */
+				0x81000000 0 0	 0xc0020000 0 0x00010000   /* downstream I/O */
+				0x82000000 0 0xc0030000 0xc0030000 0 0x0ffd0000>; /* non-prefetchable memory */
+			status = "disabled";
+		};
+
 		gmac1: eth at 5c400000 {
 			compatible = "st,spear600-gmac";
 			reg = <0x5c400000 0x8000>;
diff --git a/arch/arm/boot/dts/spear1340.dtsi b/arch/arm/boot/dts/spear1340.dtsi
index 7e3a04b..65a689c 100644
--- a/arch/arm/boot/dts/spear1340.dtsi
+++ b/arch/arm/boot/dts/spear1340.dtsi
@@ -49,6 +49,22 @@
 			status = "disabled";
 		};
 
+		pcie0: pcie at b1000000 {
+			compatible = "st,spear1340-pcie", "snps,dw-pcie";
+			reg = <0xb1000000 0x4000>;
+			interrupts = <0 68 0x4>;
+			interrupt-map-mask = <0 0 0 0>;
+			interrupt-map = <0x0 0 &gic 68>;
+			num-lanes = <1>;
+			#address-cells = <3>;
+			#size-cells = <2>;
+			device_type = "pci";
+			ranges = <0x00000800 0 0x80000000 0x80000000 0 0x00020000   /* configuration space */
+				0x81000000 0 0	 0x80020000 0 0x00010000   /* downstream I/O */
+				0x82000000 0 0x80030000 0xc0030000 0 0x0ffd0000>; /* non-prefetchable memory */
+			status = "disabled";
+		};
+
 		i2s-play at b2400000 {
 			compatible = "snps,designware-i2s";
 			reg = <0xb2400000 0x10000>;
-- 
1.7.0.1

^ permalink raw reply related

* [PATCH V6 07/12] phy: st-miphy-40lp: Add SPEAr1310 and SPEAr1340 PCIe phy support
From: Mohit Kumar @ 2014-02-11  9:30 UTC (permalink / raw)
  To: linux-arm-kernel
In-Reply-To: <cover.1392109054.git.mohit.kumar@st.com>

From: Pratyush Anand <pratyush.anand@st.com>

SPEAr1310 and SPEAr1340 uses miphy40lp phy for PCIe. This driver adds
support for the same.

Signed-off-by: Pratyush Anand <pratyush.anand@st.com>
Tested-by: Mohit Kumar <mohit.kumar@st.com>
Cc: Arnd Bergmann <arnd@arndb.de>
Cc: Viresh Kumar <viresh.linux@gmail.com>
Cc: Kishon Vijay Abraham I <kishon@ti.com>
Cc: spear-devel at list.st.com
Cc: linux-arm-kernel at lists.infradead.org
Cc: linux-kernel at vger.kernel.org
---
 drivers/phy/phy-miphy40lp.c |  165 +++++++++++++++++++++++++++++++++++++++++++
 1 files changed, 165 insertions(+), 0 deletions(-)

diff --git a/drivers/phy/phy-miphy40lp.c b/drivers/phy/phy-miphy40lp.c
index 16da55b..dec67ed 100644
--- a/drivers/phy/phy-miphy40lp.c
+++ b/drivers/phy/phy-miphy40lp.c
@@ -9,6 +9,7 @@
  * published by the Free Software Foundation.
  *
  * 04/02/2014: Adding support of SATA mode for SPEAr1340.
+ * 04/02/2014: Adding support of PCIe mode for SPEAr1340 and SPEAr1310
  */
 
 #include <linux/bitops.h>
@@ -74,6 +75,80 @@
 	#define SPEAR1340_PCIE_SATA_MIPHY_CFG_PCIE \
 			(SPEAR1340_MIPHY_OSC_BYPASS_EXT | \
 			SPEAR1340_MIPHY_PLL_RATIO_TOP(25))
+/* SPEAr1310 Registers */
+#define SPEAR1310_PCIE_SATA_CFG			0x3A4
+	#define SPEAR1310_PCIE_SATA2_SEL_PCIE		(0 << 31)
+	#define SPEAR1310_PCIE_SATA1_SEL_PCIE		(0 << 30)
+	#define SPEAR1310_PCIE_SATA0_SEL_PCIE		(0 << 29)
+	#define SPEAR1310_PCIE_SATA2_SEL_SATA		BIT(31)
+	#define SPEAR1310_PCIE_SATA1_SEL_SATA		BIT(30)
+	#define SPEAR1310_PCIE_SATA0_SEL_SATA		BIT(29)
+	#define SPEAR1310_SATA2_CFG_TX_CLK_EN		BIT(27)
+	#define SPEAR1310_SATA2_CFG_RX_CLK_EN		BIT(26)
+	#define SPEAR1310_SATA2_CFG_POWERUP_RESET	BIT(25)
+	#define SPEAR1310_SATA2_CFG_PM_CLK_EN		BIT(24)
+	#define SPEAR1310_SATA1_CFG_TX_CLK_EN		BIT(23)
+	#define SPEAR1310_SATA1_CFG_RX_CLK_EN		BIT(22)
+	#define SPEAR1310_SATA1_CFG_POWERUP_RESET	BIT(21)
+	#define SPEAR1310_SATA1_CFG_PM_CLK_EN		BIT(20)
+	#define SPEAR1310_SATA0_CFG_TX_CLK_EN		BIT(19)
+	#define SPEAR1310_SATA0_CFG_RX_CLK_EN		BIT(18)
+	#define SPEAR1310_SATA0_CFG_POWERUP_RESET	BIT(17)
+	#define SPEAR1310_SATA0_CFG_PM_CLK_EN		BIT(16)
+	#define SPEAR1310_PCIE2_CFG_DEVICE_PRESENT	BIT(11)
+	#define SPEAR1310_PCIE2_CFG_POWERUP_RESET	BIT(10)
+	#define SPEAR1310_PCIE2_CFG_CORE_CLK_EN		BIT(9)
+	#define SPEAR1310_PCIE2_CFG_AUX_CLK_EN		BIT(8)
+	#define SPEAR1310_PCIE1_CFG_DEVICE_PRESENT	BIT(7)
+	#define SPEAR1310_PCIE1_CFG_POWERUP_RESET	BIT(6)
+	#define SPEAR1310_PCIE1_CFG_CORE_CLK_EN		BIT(5)
+	#define SPEAR1310_PCIE1_CFG_AUX_CLK_EN		BIT(4)
+	#define SPEAR1310_PCIE0_CFG_DEVICE_PRESENT	BIT(3)
+	#define SPEAR1310_PCIE0_CFG_POWERUP_RESET	BIT(2)
+	#define SPEAR1310_PCIE0_CFG_CORE_CLK_EN		BIT(1)
+	#define SPEAR1310_PCIE0_CFG_AUX_CLK_EN		BIT(0)
+
+	#define SPEAR1310_PCIE_CFG_MASK(x) ((0xF << (x * 4)) | BIT((x + 29)))
+	#define SPEAR1310_SATA_CFG_MASK(x) ((0xF << (x * 4 + 16)) | \
+			BIT((x + 29)))
+	#define SPEAR1310_PCIE_CFG_VAL(x) \
+			(SPEAR1310_PCIE_SATA##x##_SEL_PCIE | \
+			SPEAR1310_PCIE##x##_CFG_AUX_CLK_EN | \
+			SPEAR1310_PCIE##x##_CFG_CORE_CLK_EN | \
+			SPEAR1310_PCIE##x##_CFG_POWERUP_RESET | \
+			SPEAR1310_PCIE##x##_CFG_DEVICE_PRESENT)
+	#define SPEAR1310_SATA_CFG_VAL(x) \
+			(SPEAR1310_PCIE_SATA##x##_SEL_SATA | \
+			SPEAR1310_SATA##x##_CFG_PM_CLK_EN | \
+			SPEAR1310_SATA##x##_CFG_POWERUP_RESET | \
+			SPEAR1310_SATA##x##_CFG_RX_CLK_EN | \
+			SPEAR1310_SATA##x##_CFG_TX_CLK_EN)
+
+#define SPEAR1310_PCIE_MIPHY_CFG_1		0x3A8
+	#define SPEAR1310_MIPHY_DUAL_OSC_BYPASS_EXT	BIT(31)
+	#define SPEAR1310_MIPHY_DUAL_CLK_REF_DIV2	BIT(28)
+	#define SPEAR1310_MIPHY_DUAL_PLL_RATIO_TOP(x)	(x << 16)
+	#define SPEAR1310_MIPHY_SINGLE_OSC_BYPASS_EXT	BIT(15)
+	#define SPEAR1310_MIPHY_SINGLE_CLK_REF_DIV2	BIT(12)
+	#define SPEAR1310_MIPHY_SINGLE_PLL_RATIO_TOP(x)	(x << 0)
+	#define SPEAR1310_PCIE_SATA_MIPHY_CFG_SATA_MASK (0xFFFF)
+	#define SPEAR1310_PCIE_SATA_MIPHY_CFG_PCIE_MASK (0xFFFF << 16)
+	#define SPEAR1310_PCIE_SATA_MIPHY_CFG_SATA \
+			(SPEAR1310_MIPHY_DUAL_OSC_BYPASS_EXT | \
+			SPEAR1310_MIPHY_DUAL_CLK_REF_DIV2 | \
+			SPEAR1310_MIPHY_DUAL_PLL_RATIO_TOP(60) | \
+			SPEAR1310_MIPHY_SINGLE_OSC_BYPASS_EXT | \
+			SPEAR1310_MIPHY_SINGLE_CLK_REF_DIV2 | \
+			SPEAR1310_MIPHY_SINGLE_PLL_RATIO_TOP(60))
+	#define SPEAR1310_PCIE_SATA_MIPHY_CFG_SATA_25M_CRYSTAL_CLK \
+			(SPEAR1310_MIPHY_SINGLE_PLL_RATIO_TOP(120))
+	#define SPEAR1310_PCIE_SATA_MIPHY_CFG_PCIE \
+			(SPEAR1310_MIPHY_DUAL_OSC_BYPASS_EXT | \
+			SPEAR1310_MIPHY_DUAL_PLL_RATIO_TOP(25) | \
+			SPEAR1310_MIPHY_SINGLE_OSC_BYPASS_EXT | \
+			SPEAR1310_MIPHY_SINGLE_PLL_RATIO_TOP(25))
+
+#define SPEAR1310_PCIE_MIPHY_CFG_2		0x3AC
 
 enum phy_mode {
 	SATA,
@@ -146,12 +221,35 @@ static int miphy40lp_spear1340_sata_exit(struct miphy40lp_priv *priv)
 	return 0;
 }
 
+static int miphy40lp_spear1340_pcie_init(struct miphy40lp_priv *priv)
+{
+	regmap_update_bits(priv->misc, SPEAR1340_PCIE_MIPHY_CFG,
+			SPEAR1340_PCIE_MIPHY_CFG_MASK,
+			SPEAR1340_PCIE_SATA_MIPHY_CFG_PCIE);
+	regmap_update_bits(priv->misc, SPEAR1340_PCIE_SATA_CFG,
+			SPEAR1340_PCIE_SATA_CFG_MASK, SPEAR1340_PCIE_CFG_VAL);
+
+	return 0;
+}
+
+static int miphy40lp_spear1340_pcie_exit(struct miphy40lp_priv *priv)
+{
+	regmap_update_bits(priv->misc, SPEAR1340_PCIE_MIPHY_CFG,
+			SPEAR1340_PCIE_MIPHY_CFG_MASK, 0);
+	regmap_update_bits(priv->misc, SPEAR1340_PCIE_SATA_CFG,
+			SPEAR1340_PCIE_SATA_CFG_MASK, 0);
+
+	return 0;
+}
+
 static int miphy40lp_spear1340_init(struct miphy40lp_priv *priv)
 {
 	int ret = 0;
 
 	if (priv->mode == SATA)
 		ret = miphy40lp_spear1340_sata_init(priv);
+	else if (priv->mode == PCIE)
+		ret = miphy40lp_spear1340_pcie_init(priv);
 
 	return ret;
 }
@@ -162,6 +260,8 @@ static int miphy40lp_spear1340_exit(struct miphy40lp_priv *priv)
 
 	if (priv->mode == SATA)
 		ret = miphy40lp_spear1340_sata_exit(priv);
+	else if (priv->mode == PCIE)
+		ret = miphy40lp_spear1340_pcie_exit(priv);
 
 	return ret;
 }
@@ -193,6 +293,70 @@ static struct miphy40lp_plat_ops spear1340_phy_ops = {
 	.plat_resume = miphy40lp_spear1340_resume,
 };
 
+static int miphy40lp_spear1310_pcie_init(struct miphy40lp_priv *priv)
+{
+	u32 val;
+
+	regmap_update_bits(priv->misc, SPEAR1310_PCIE_MIPHY_CFG_1,
+			SPEAR1310_PCIE_SATA_MIPHY_CFG_PCIE_MASK,
+			SPEAR1310_PCIE_SATA_MIPHY_CFG_PCIE);
+
+	switch (priv->id) {
+	case 0:
+		val = SPEAR1310_PCIE_CFG_VAL(0);
+		break;
+	case 1:
+		val = SPEAR1310_PCIE_CFG_VAL(1);
+		break;
+	case 2:
+		val = SPEAR1310_PCIE_CFG_VAL(2);
+		break;
+	default:
+		return -EINVAL;
+	}
+
+	regmap_update_bits(priv->misc, SPEAR1310_PCIE_SATA_CFG,
+			SPEAR1310_PCIE_CFG_MASK(priv->id), val);
+
+	return 0;
+}
+
+static int miphy40lp_spear1310_pcie_exit(struct miphy40lp_priv *priv)
+{
+	regmap_update_bits(priv->misc, SPEAR1310_PCIE_SATA_CFG,
+			SPEAR1310_PCIE_CFG_MASK(priv->id), 0);
+
+	regmap_update_bits(priv->misc, SPEAR1310_PCIE_MIPHY_CFG_1,
+			SPEAR1310_PCIE_SATA_MIPHY_CFG_PCIE_MASK, 0);
+
+	return 0;
+}
+
+static int miphy40lp_spear1310_init(struct miphy40lp_priv *priv)
+{
+	int ret = 0;
+
+	if (priv->mode == PCIE)
+		ret = miphy40lp_spear1310_pcie_init(priv);
+
+	return ret;
+}
+
+static int miphy40lp_spear1310_exit(struct miphy40lp_priv *priv)
+{
+	int ret = 0;
+
+	if (priv->mode == PCIE)
+		ret = miphy40lp_spear1310_pcie_exit(priv);
+
+	return ret;
+}
+
+static struct miphy40lp_plat_ops spear1310_phy_ops = {
+	.plat_init = miphy40lp_spear1310_init,
+	.plat_exit = miphy40lp_spear1310_exit,
+};
+
 static int miphy40lp_init(struct phy *phy)
 {
 	struct miphy40lp_priv *priv = phy_get_drvdata(phy);
@@ -244,6 +408,7 @@ static int miphy40lp_power_on(struct phy *phy)
 static const struct of_device_id miphy40lp_of_match[] = {
 	{ .compatible = "st,miphy40lp-phy", .data = NULL },
 	{ .compatible = "st,spear1340-miphy", .data = &spear1340_phy_ops },
+	{ .compatible = "st,spear1310-miphy", .data = &spear1310_phy_ops },
 	{ },
 };
 MODULE_DEVICE_TABLE(of, miphy40lp_of_match);
-- 
1.7.0.1

^ permalink raw reply related

* [PATCH V6 06/12] SPEAr13xx: Fixup: Move SPEAr1340 SATA platform code to phy driver
From: Mohit Kumar @ 2014-02-11  9:30 UTC (permalink / raw)
  To: linux-arm-kernel
In-Reply-To: <cover.1392109054.git.mohit.kumar@st.com>

From: Pratyush Anand <pratyush.anand@st.com>

ahci driver needs some platform specific functions which are called at
init, exit, suspend and resume conditions. Till now these functions were
present in a platform driver with a fixme notes.

Similar functions modifying same set of registers will also be needed in
case of PCIe phy init/exit.

So move all these SATA platform code to phy-miphy40lp driver.

Signed-off-by: Pratyush Anand <pratyush.anand@st.com>
Tested-by: Mohit Kumar <mohit.kumar@st.com>
Cc: Arnd Bergmann <arnd@arndb.de>
Cc: Viresh Kumar <viresh.linux@gmail.com>
Cc: Tejun Heo <tj@kernel.org>
Cc: Kishon Vijay Abraham I <kishon@ti.com>
Cc: spear-devel at list.st.com
Cc: linux-arm-kernel at lists.infradead.org
Cc: linux-kernel at vger.kernel.org
---
 arch/arm/boot/dts/spear1310-evb.dts |    4 +
 arch/arm/boot/dts/spear1310.dtsi    |   39 +++++++++-
 arch/arm/boot/dts/spear1340-evb.dts |    4 +
 arch/arm/boot/dts/spear1340.dtsi    |   13 +++-
 arch/arm/boot/dts/spear13xx.dtsi    |    5 +
 arch/arm/mach-spear/Kconfig         |    2 +
 arch/arm/mach-spear/spear1340.c     |  127 +------------------------------
 drivers/phy/phy-miphy40lp.c         |  144 +++++++++++++++++++++++++++++++++++
 8 files changed, 208 insertions(+), 130 deletions(-)

diff --git a/arch/arm/boot/dts/spear1310-evb.dts b/arch/arm/boot/dts/spear1310-evb.dts
index b56a801..d42c84b 100644
--- a/arch/arm/boot/dts/spear1310-evb.dts
+++ b/arch/arm/boot/dts/spear1310-evb.dts
@@ -106,6 +106,10 @@
 			status = "okay";
 		};
 
+		miphy at eb800000 {
+			status = "okay";
+		};
+
 		cf at b2800000 {
 			status = "okay";
 		};
diff --git a/arch/arm/boot/dts/spear1310.dtsi b/arch/arm/boot/dts/spear1310.dtsi
index 122ae94..64e7dd5 100644
--- a/arch/arm/boot/dts/spear1310.dtsi
+++ b/arch/arm/boot/dts/spear1310.dtsi
@@ -29,24 +29,57 @@
 			#gpio-cells = <2>;
 		};
 
-		ahci at b1000000 {
+		miphy0: miphy at eb800000 {
+			compatible = "st,miphy", "st,spear1310-miphy";
+			reg = <0xeb800000 0x4000>;
+			misc = <&misc>;
+			phy-id = <0>;
+			#phy-cells = <1>;
+			status = "disabled";
+		};
+
+		miphy1: miphy at eb804000 {
+			compatible = "st,miphy", "st,spear1310-miphy";
+			reg = <0xeb804000 0x4000>;
+			misc = <&misc>;
+			phy-id = <1>;
+			#phy-cells = <1>;
+			status = "disabled";
+		};
+
+		miphy2: miphy at eb808000 {
+			compatible = "st,miphy", "st,spear1310-miphy";
+			reg = <0xeb808000 0x4000>;
+			misc = <&misc>;
+			phy-id = <2>;
+			#phy-cells = <1>;
+			status = "disabled";
+		};
+
+		ahci0: ahci at b1000000 {
 			compatible = "snps,spear-ahci";
 			reg = <0xb1000000 0x10000>;
 			interrupts = <0 68 0x4>;
+			phys = <&miphy0 0>;
+			phy-names = "sata-phy";
 			status = "disabled";
 		};
 
-		ahci at b1800000 {
+		ahci1: ahci at b1800000 {
 			compatible = "snps,spear-ahci";
 			reg = <0xb1800000 0x10000>;
 			interrupts = <0 69 0x4>;
+			phys = <&miphy1 0>;
+			phy-names = "sata-phy";
 			status = "disabled";
 		};
 
-		ahci at b4000000 {
+		ahci2: ahci at b4000000 {
 			compatible = "snps,spear-ahci";
 			reg = <0xb4000000 0x10000>;
 			interrupts = <0 70 0x4>;
+			phys = <&miphy2 0>;
+			phy-names = "sata-phy";
 			status = "disabled";
 		};
 
diff --git a/arch/arm/boot/dts/spear1340-evb.dts b/arch/arm/boot/dts/spear1340-evb.dts
index d6c30ae..b23e05e 100644
--- a/arch/arm/boot/dts/spear1340-evb.dts
+++ b/arch/arm/boot/dts/spear1340-evb.dts
@@ -122,6 +122,10 @@
 			status = "okay";
 		};
 
+		miphy at eb800000 {
+			status = "okay";
+		};
+
 		dma at ea800000 {
 			status = "okay";
 		};
diff --git a/arch/arm/boot/dts/spear1340.dtsi b/arch/arm/boot/dts/spear1340.dtsi
index 54d128d..7e3a04b 100644
--- a/arch/arm/boot/dts/spear1340.dtsi
+++ b/arch/arm/boot/dts/spear1340.dtsi
@@ -31,10 +31,21 @@
 			status = "disabled";
 		};
 
-		ahci at b1000000 {
+		miphy0: miphy at eb800000 {
+			compatible = "st,miphy", "st,spear1340-miphy";
+			reg = <0xeb800000 0x4000>;
+			misc = <&misc>;
+			phy-id = <0>;
+			#phy-cells = <1>;
+			status = "disabled";
+		};
+
+		ahci0: ahci at b1000000 {
 			compatible = "snps,spear-ahci";
 			reg = <0xb1000000 0x10000>;
 			interrupts = <0 72 0x4>;
+			phys = <&miphy0 0>;
+			phy-names = "sata-phy";
 			status = "disabled";
 		};
 
diff --git a/arch/arm/boot/dts/spear13xx.dtsi b/arch/arm/boot/dts/spear13xx.dtsi
index 4382547..3a72508 100644
--- a/arch/arm/boot/dts/spear13xx.dtsi
+++ b/arch/arm/boot/dts/spear13xx.dtsi
@@ -220,6 +220,11 @@
 				  0xd8000000 0xd8000000 0x01000000
 				  0xe0000000 0xe0000000 0x10000000>;
 
+			misc: syscon at e0700000 {
+				compatible = "st,spear1340-misc", "syscon";
+				reg = <0xe0700000 0x1000>;
+			};
+
 			gpio0: gpio at e0600000 {
 				compatible = "arm,pl061", "arm,primecell";
 				reg = <0xe0600000 0x1000>;
diff --git a/arch/arm/mach-spear/Kconfig b/arch/arm/mach-spear/Kconfig
index ac1710e..7e7f1b0 100644
--- a/arch/arm/mach-spear/Kconfig
+++ b/arch/arm/mach-spear/Kconfig
@@ -26,6 +26,8 @@ config ARCH_SPEAR13XX
 	select MIGHT_HAVE_CACHE_L2X0
 	select PINCTRL
 	select USE_OF
+	select MFD_SYSCON
+	select PHY_ST_MIPHY40LP
 	help
 	  Supports for ARM's SPEAR13XX family
 
diff --git a/arch/arm/mach-spear/spear1340.c b/arch/arm/mach-spear/spear1340.c
index 3fb6834..8e27093 100644
--- a/arch/arm/mach-spear/spear1340.c
+++ b/arch/arm/mach-spear/spear1340.c
@@ -11,138 +11,13 @@
  * warranty of any kind, whether express or implied.
  */
 
-#define pr_fmt(fmt) "SPEAr1340: " fmt
-
-#include <linux/ahci_platform.h>
-#include <linux/amba/serial.h>
-#include <linux/delay.h>
 #include <linux/of_platform.h>
 #include <asm/mach/arch.h>
 #include "generic.h"
-#include <mach/spear.h>
-
-/* FIXME: Move SATA PHY code into a standalone driver */
-
-/* Base addresses */
-#define SPEAR1340_SATA_BASE			UL(0xB1000000)
-
-/* Power Management Registers */
-#define SPEAR1340_PCM_CFG			(VA_MISC_BASE + 0x100)
-#define SPEAR1340_PCM_WKUP_CFG			(VA_MISC_BASE + 0x104)
-#define SPEAR1340_SWITCH_CTR			(VA_MISC_BASE + 0x108)
-
-#define SPEAR1340_PERIP1_SW_RST			(VA_MISC_BASE + 0x318)
-#define SPEAR1340_PERIP2_SW_RST			(VA_MISC_BASE + 0x31C)
-#define SPEAR1340_PERIP3_SW_RST			(VA_MISC_BASE + 0x320)
-
-/* PCIE - SATA configuration registers */
-#define SPEAR1340_PCIE_SATA_CFG			(VA_MISC_BASE + 0x424)
-	/* PCIE CFG MASks */
-	#define SPEAR1340_PCIE_CFG_DEVICE_PRESENT	(1 << 11)
-	#define SPEAR1340_PCIE_CFG_POWERUP_RESET	(1 << 10)
-	#define SPEAR1340_PCIE_CFG_CORE_CLK_EN		(1 << 9)
-	#define SPEAR1340_PCIE_CFG_AUX_CLK_EN		(1 << 8)
-	#define SPEAR1340_SATA_CFG_TX_CLK_EN		(1 << 4)
-	#define SPEAR1340_SATA_CFG_RX_CLK_EN		(1 << 3)
-	#define SPEAR1340_SATA_CFG_POWERUP_RESET	(1 << 2)
-	#define SPEAR1340_SATA_CFG_PM_CLK_EN		(1 << 1)
-	#define SPEAR1340_PCIE_SATA_SEL_PCIE		(0)
-	#define SPEAR1340_PCIE_SATA_SEL_SATA		(1)
-	#define SPEAR1340_SATA_PCIE_CFG_MASK		0xF1F
-	#define SPEAR1340_PCIE_CFG_VAL	(SPEAR1340_PCIE_SATA_SEL_PCIE | \
-			SPEAR1340_PCIE_CFG_AUX_CLK_EN | \
-			SPEAR1340_PCIE_CFG_CORE_CLK_EN | \
-			SPEAR1340_PCIE_CFG_POWERUP_RESET | \
-			SPEAR1340_PCIE_CFG_DEVICE_PRESENT)
-	#define SPEAR1340_SATA_CFG_VAL	(SPEAR1340_PCIE_SATA_SEL_SATA | \
-			SPEAR1340_SATA_CFG_PM_CLK_EN | \
-			SPEAR1340_SATA_CFG_POWERUP_RESET | \
-			SPEAR1340_SATA_CFG_RX_CLK_EN | \
-			SPEAR1340_SATA_CFG_TX_CLK_EN)
-
-#define SPEAR1340_PCIE_MIPHY_CFG		(VA_MISC_BASE + 0x428)
-	#define SPEAR1340_MIPHY_OSC_BYPASS_EXT		(1 << 31)
-	#define SPEAR1340_MIPHY_CLK_REF_DIV2		(1 << 27)
-	#define SPEAR1340_MIPHY_CLK_REF_DIV4		(2 << 27)
-	#define SPEAR1340_MIPHY_CLK_REF_DIV8		(3 << 27)
-	#define SPEAR1340_MIPHY_PLL_RATIO_TOP(x)	(x << 0)
-	#define SPEAR1340_PCIE_SATA_MIPHY_CFG_SATA \
-			(SPEAR1340_MIPHY_OSC_BYPASS_EXT | \
-			SPEAR1340_MIPHY_CLK_REF_DIV2 | \
-			SPEAR1340_MIPHY_PLL_RATIO_TOP(60))
-	#define SPEAR1340_PCIE_SATA_MIPHY_CFG_SATA_25M_CRYSTAL_CLK \
-			(SPEAR1340_MIPHY_PLL_RATIO_TOP(120))
-	#define SPEAR1340_PCIE_SATA_MIPHY_CFG_PCIE \
-			(SPEAR1340_MIPHY_OSC_BYPASS_EXT | \
-			SPEAR1340_MIPHY_PLL_RATIO_TOP(25))
-
-/* SATA device registration */
-static int sata_miphy_init(struct device *dev, void __iomem *addr)
-{
-	writel(SPEAR1340_SATA_CFG_VAL, SPEAR1340_PCIE_SATA_CFG);
-	writel(SPEAR1340_PCIE_SATA_MIPHY_CFG_SATA_25M_CRYSTAL_CLK,
-			SPEAR1340_PCIE_MIPHY_CFG);
-	/* Switch on sata power domain */
-	writel((readl(SPEAR1340_PCM_CFG) | (0x800)), SPEAR1340_PCM_CFG);
-	msleep(20);
-	/* Disable PCIE SATA Controller reset */
-	writel((readl(SPEAR1340_PERIP1_SW_RST) & (~0x1000)),
-			SPEAR1340_PERIP1_SW_RST);
-	msleep(20);
-
-	return 0;
-}
-
-void sata_miphy_exit(struct device *dev)
-{
-	writel(0, SPEAR1340_PCIE_SATA_CFG);
-	writel(0, SPEAR1340_PCIE_MIPHY_CFG);
-
-	/* Enable PCIE SATA Controller reset */
-	writel((readl(SPEAR1340_PERIP1_SW_RST) | (0x1000)),
-			SPEAR1340_PERIP1_SW_RST);
-	msleep(20);
-	/* Switch off sata power domain */
-	writel((readl(SPEAR1340_PCM_CFG) & (~0x800)), SPEAR1340_PCM_CFG);
-	msleep(20);
-}
-
-int sata_suspend(struct device *dev)
-{
-	if (dev->power.power_state.event == PM_EVENT_FREEZE)
-		return 0;
-
-	sata_miphy_exit(dev);
-
-	return 0;
-}
-
-int sata_resume(struct device *dev)
-{
-	if (dev->power.power_state.event == PM_EVENT_THAW)
-		return 0;
-
-	return sata_miphy_init(dev, NULL);
-}
-
-static struct ahci_platform_data sata_pdata = {
-	.init = sata_miphy_init,
-	.exit = sata_miphy_exit,
-	.suspend = sata_suspend,
-	.resume = sata_resume,
-};
-
-/* Add SPEAr1340 auxdata to pass platform data */
-static struct of_dev_auxdata spear1340_auxdata_lookup[] __initdata = {
-	OF_DEV_AUXDATA("snps,spear-ahci", SPEAR1340_SATA_BASE, NULL,
-			&sata_pdata),
-	{}
-};
 
 static void __init spear1340_dt_init(void)
 {
-	of_platform_populate(NULL, of_default_bus_match_table,
-			spear1340_auxdata_lookup, NULL);
+	of_platform_populate(NULL, of_default_bus_match_table, NULL, NULL);
 }
 
 static const char * const spear1340_dt_board_compat[] = {
diff --git a/drivers/phy/phy-miphy40lp.c b/drivers/phy/phy-miphy40lp.c
index 98859ff..16da55b 100644
--- a/drivers/phy/phy-miphy40lp.c
+++ b/drivers/phy/phy-miphy40lp.c
@@ -8,8 +8,10 @@
  * it under the terms of the GNU General Public License version 2 as
  * published by the Free Software Foundation.
  *
+ * 04/02/2014: Adding support of SATA mode for SPEAr1340.
  */
 
+#include <linux/bitops.h>
 #include <linux/delay.h>
 #include <linux/dma-mapping.h>
 #include <linux/kernel.h>
@@ -19,6 +21,60 @@
 #include <linux/phy/phy.h>
 #include <linux/regmap.h>
 
+/* SPEAr1340 Registers */
+/* Power Management Registers */
+#define SPEAR1340_PCM_CFG			0x100
+	#define SPEAR1340_PCM_CFG_SATA_POWER_EN		BIT(11)
+#define SPEAR1340_PCM_WKUP_CFG			0x104
+#define SPEAR1340_SWITCH_CTR			0x108
+
+#define SPEAR1340_PERIP1_SW_RST			0x318
+	#define SPEAR1340_PERIP1_SW_RSATA		BIT(12)
+#define SPEAR1340_PERIP2_SW_RST			0x31C
+#define SPEAR1340_PERIP3_SW_RST			0x320
+
+/* PCIE - SATA configuration registers */
+#define SPEAR1340_PCIE_SATA_CFG			0x424
+	/* PCIE CFG MASks */
+	#define SPEAR1340_PCIE_CFG_DEVICE_PRESENT	BIT(11)
+	#define SPEAR1340_PCIE_CFG_POWERUP_RESET	BIT(10)
+	#define SPEAR1340_PCIE_CFG_CORE_CLK_EN		BIT(9)
+	#define SPEAR1340_PCIE_CFG_AUX_CLK_EN		BIT(8)
+	#define SPEAR1340_SATA_CFG_TX_CLK_EN		BIT(4)
+	#define SPEAR1340_SATA_CFG_RX_CLK_EN		BIT(3)
+	#define SPEAR1340_SATA_CFG_POWERUP_RESET	BIT(2)
+	#define SPEAR1340_SATA_CFG_PM_CLK_EN		BIT(1)
+	#define SPEAR1340_PCIE_SATA_SEL_PCIE		(0)
+	#define SPEAR1340_PCIE_SATA_SEL_SATA		(1)
+	#define SPEAR1340_PCIE_SATA_CFG_MASK		0xF1F
+	#define SPEAR1340_PCIE_CFG_VAL	(SPEAR1340_PCIE_SATA_SEL_PCIE | \
+			SPEAR1340_PCIE_CFG_AUX_CLK_EN | \
+			SPEAR1340_PCIE_CFG_CORE_CLK_EN | \
+			SPEAR1340_PCIE_CFG_POWERUP_RESET | \
+			SPEAR1340_PCIE_CFG_DEVICE_PRESENT)
+	#define SPEAR1340_SATA_CFG_VAL	(SPEAR1340_PCIE_SATA_SEL_SATA | \
+			SPEAR1340_SATA_CFG_PM_CLK_EN | \
+			SPEAR1340_SATA_CFG_POWERUP_RESET | \
+			SPEAR1340_SATA_CFG_RX_CLK_EN | \
+			SPEAR1340_SATA_CFG_TX_CLK_EN)
+
+#define SPEAR1340_PCIE_MIPHY_CFG		0x428
+	#define SPEAR1340_MIPHY_OSC_BYPASS_EXT		BIT(31)
+	#define SPEAR1340_MIPHY_CLK_REF_DIV2		BIT(27)
+	#define SPEAR1340_MIPHY_CLK_REF_DIV4		(2 << 27)
+	#define SPEAR1340_MIPHY_CLK_REF_DIV8		(3 << 27)
+	#define SPEAR1340_MIPHY_PLL_RATIO_TOP(x)	(x << 0)
+	#define SPEAR1340_PCIE_MIPHY_CFG_MASK		0xF80000FF
+	#define SPEAR1340_PCIE_SATA_MIPHY_CFG_SATA \
+			(SPEAR1340_MIPHY_OSC_BYPASS_EXT | \
+			SPEAR1340_MIPHY_CLK_REF_DIV2 | \
+			SPEAR1340_MIPHY_PLL_RATIO_TOP(60))
+	#define SPEAR1340_PCIE_SATA_MIPHY_CFG_SATA_25M_CRYSTAL_CLK \
+			(SPEAR1340_MIPHY_PLL_RATIO_TOP(120))
+	#define SPEAR1340_PCIE_SATA_MIPHY_CFG_PCIE \
+			(SPEAR1340_MIPHY_OSC_BYPASS_EXT | \
+			SPEAR1340_MIPHY_PLL_RATIO_TOP(25))
+
 enum phy_mode {
 	SATA,
 	PCIE,
@@ -50,6 +106,93 @@ struct miphy40lp_priv {
 	const struct miphy40lp_plat_ops	*plat_ops;
 };
 
+static int miphy40lp_spear1340_sata_init(struct miphy40lp_priv *priv)
+{
+	regmap_update_bits(priv->misc, SPEAR1340_PCIE_SATA_CFG,
+			SPEAR1340_PCIE_SATA_CFG_MASK, SPEAR1340_SATA_CFG_VAL);
+	regmap_update_bits(priv->misc, SPEAR1340_PCIE_MIPHY_CFG,
+			SPEAR1340_PCIE_MIPHY_CFG_MASK,
+			SPEAR1340_PCIE_SATA_MIPHY_CFG_SATA_25M_CRYSTAL_CLK);
+	/* Switch on sata power domain */
+	regmap_update_bits(priv->misc, SPEAR1340_PCM_CFG,
+			SPEAR1340_PCM_CFG_SATA_POWER_EN,
+			SPEAR1340_PCM_CFG_SATA_POWER_EN);
+	msleep(20);
+	/* Disable PCIE SATA Controller reset */
+	regmap_update_bits(priv->misc, SPEAR1340_PERIP1_SW_RST,
+			SPEAR1340_PERIP1_SW_RSATA, 0);
+	msleep(20);
+
+	return 0;
+}
+
+static int miphy40lp_spear1340_sata_exit(struct miphy40lp_priv *priv)
+{
+	regmap_update_bits(priv->misc, SPEAR1340_PCIE_SATA_CFG,
+			SPEAR1340_PCIE_SATA_CFG_MASK, 0);
+	regmap_update_bits(priv->misc, SPEAR1340_PCIE_MIPHY_CFG,
+			SPEAR1340_PCIE_MIPHY_CFG_MASK, 0);
+
+	/* Enable PCIE SATA Controller reset */
+	regmap_update_bits(priv->misc, SPEAR1340_PERIP1_SW_RST,
+			SPEAR1340_PERIP1_SW_RSATA,
+			SPEAR1340_PERIP1_SW_RSATA);
+	msleep(20);
+	/* Switch off sata power domain */
+	regmap_update_bits(priv->misc, SPEAR1340_PCM_CFG,
+			SPEAR1340_PCM_CFG_SATA_POWER_EN, 0);
+	msleep(20);
+
+	return 0;
+}
+
+static int miphy40lp_spear1340_init(struct miphy40lp_priv *priv)
+{
+	int ret = 0;
+
+	if (priv->mode == SATA)
+		ret = miphy40lp_spear1340_sata_init(priv);
+
+	return ret;
+}
+
+static int miphy40lp_spear1340_exit(struct miphy40lp_priv *priv)
+{
+	int ret = 0;
+
+	if (priv->mode == SATA)
+		ret = miphy40lp_spear1340_sata_exit(priv);
+
+	return ret;
+}
+
+static int miphy40lp_spear1340_suspend(struct miphy40lp_priv *priv)
+{
+	int ret = 0;
+
+	if (priv->mode == SATA)
+		ret = miphy40lp_spear1340_sata_exit(priv);
+
+	return ret;
+}
+
+static int miphy40lp_spear1340_resume(struct miphy40lp_priv *priv)
+{
+	int ret = 0;
+
+	if (priv->mode == SATA)
+		ret = miphy40lp_spear1340_sata_init(priv);
+
+	return ret;
+}
+
+static struct miphy40lp_plat_ops spear1340_phy_ops = {
+	.plat_init = miphy40lp_spear1340_init,
+	.plat_exit = miphy40lp_spear1340_exit,
+	.plat_suspend = miphy40lp_spear1340_suspend,
+	.plat_resume = miphy40lp_spear1340_resume,
+};
+
 static int miphy40lp_init(struct phy *phy)
 {
 	struct miphy40lp_priv *priv = phy_get_drvdata(phy);
@@ -100,6 +243,7 @@ static int miphy40lp_power_on(struct phy *phy)
 
 static const struct of_device_id miphy40lp_of_match[] = {
 	{ .compatible = "st,miphy40lp-phy", .data = NULL },
+	{ .compatible = "st,spear1340-miphy", .data = &spear1340_phy_ops },
 	{ },
 };
 MODULE_DEVICE_TABLE(of, miphy40lp_of_match);
-- 
1.7.0.1

^ permalink raw reply related

* [PATCH V6 02/12] SPEAr13XX: Fix static mapping table
From: Mohit Kumar @ 2014-02-11  9:29 UTC (permalink / raw)
  To: linux-arm-kernel
In-Reply-To: <cover.1392109054.git.mohit.kumar@st.com>

From: Pratyush Anand <pratyush.anand@st.com>

SPEAr13XX was using virtual address space 0xFE000000 to map physical address
space 0xB3000000. pci_remap_io uses 0xFEE00000 as virtual address. So
change 0xFE000000 to 0xF9000000.

Signed-off-by: Pratyush Anand <pratyush.anand@st.com>
Signed-off-by: Mohit Kumar <mohit.kumar@st.com>
Acked-by: Viresh Kumar <viresh.kumar@linaro.org>
Acked-by: Arnd Bergmann <arnd@arndb.de>
Cc: spear-devel at list.st.com
Cc: stable at vger.kernel.org
Cc: linux-arm-kernel at lists.infradead.org
---
 arch/arm/mach-spear/include/mach/spear.h |    4 ++--
 arch/arm/mach-spear/spear13xx.c          |    2 +-
 2 files changed, 3 insertions(+), 3 deletions(-)

diff --git a/arch/arm/mach-spear/include/mach/spear.h b/arch/arm/mach-spear/include/mach/spear.h
index 5cdc53d..f2d6a01 100644
--- a/arch/arm/mach-spear/include/mach/spear.h
+++ b/arch/arm/mach-spear/include/mach/spear.h
@@ -52,10 +52,10 @@
 #ifdef CONFIG_ARCH_SPEAR13XX
 
 #define PERIP_GRP2_BASE				UL(0xB3000000)
-#define VA_PERIP_GRP2_BASE			IOMEM(0xFE000000)
+#define VA_PERIP_GRP2_BASE			IOMEM(0xF9000000)
 #define MCIF_SDHCI_BASE				UL(0xB3000000)
 #define SYSRAM0_BASE				UL(0xB3800000)
-#define VA_SYSRAM0_BASE				IOMEM(0xFE800000)
+#define VA_SYSRAM0_BASE				IOMEM(0xF9800000)
 #define SYS_LOCATION				(VA_SYSRAM0_BASE + 0x600)
 
 #define PERIP_GRP1_BASE				UL(0xE0000000)
diff --git a/arch/arm/mach-spear/spear13xx.c b/arch/arm/mach-spear/spear13xx.c
index 7aa6e8c..89212ff 100644
--- a/arch/arm/mach-spear/spear13xx.c
+++ b/arch/arm/mach-spear/spear13xx.c
@@ -52,7 +52,7 @@ void __init spear13xx_l2x0_init(void)
 /*
  * Following will create 16MB static virtual/physical mappings
  * PHYSICAL		VIRTUAL
- * 0xB3000000		0xFE000000
+ * 0xB3000000		0xF9000000
  * 0xE0000000		0xFD000000
  * 0xEC000000		0xFC000000
  * 0xED000000		0xFB000000
-- 
1.7.0.1

^ permalink raw reply related

* [PATCH V6 01/12] clk: SPEAr13XX: Fix pcie clock name
From: Mohit Kumar @ 2014-02-11  9:29 UTC (permalink / raw)
  To: linux-arm-kernel
In-Reply-To: <cover.1392109054.git.mohit.kumar@st.com>

From: Pratyush Anand <pratyush.anand@st.com>

Follow dt clock naming convention for PCIe clocks.

Signed-off-by: Pratyush Anand <pratyush.anand@st.com>
Acked-by: Viresh Kumar <viresh.kumar@linaro.org>
Cc: Mohit Kumar <mohit.kumar@st.com>
Cc: Arnd Bergmann <arnd@arndb.de>
Cc: spear-devel at list.st.com
Cc: linux-arm-kernel at lists.infradead.org
---
 drivers/clk/spear/spear1310_clock.c |    6 +++---
 drivers/clk/spear/spear1340_clock.c |    2 +-
 2 files changed, 4 insertions(+), 4 deletions(-)

diff --git a/drivers/clk/spear/spear1310_clock.c b/drivers/clk/spear/spear1310_clock.c
index 65894f7..4daa597 100644
--- a/drivers/clk/spear/spear1310_clock.c
+++ b/drivers/clk/spear/spear1310_clock.c
@@ -742,19 +742,19 @@ void __init spear1310_clk_init(void __iomem *misc_base, void __iomem *ras_base)
 	clk = clk_register_gate(NULL, "pcie_sata_0_clk", "ahb_clk", 0,
 			SPEAR1310_PERIP1_CLK_ENB, SPEAR1310_PCIE_SATA_0_CLK_ENB,
 			0, &_lock);
-	clk_register_clkdev(clk, NULL, "dw_pcie.0");
+	clk_register_clkdev(clk, NULL, "b1000000.pcie");
 	clk_register_clkdev(clk, NULL, "b1000000.ahci");
 
 	clk = clk_register_gate(NULL, "pcie_sata_1_clk", "ahb_clk", 0,
 			SPEAR1310_PERIP1_CLK_ENB, SPEAR1310_PCIE_SATA_1_CLK_ENB,
 			0, &_lock);
-	clk_register_clkdev(clk, NULL, "dw_pcie.1");
+	clk_register_clkdev(clk, NULL, "b1800000.pcie");
 	clk_register_clkdev(clk, NULL, "b1800000.ahci");
 
 	clk = clk_register_gate(NULL, "pcie_sata_2_clk", "ahb_clk", 0,
 			SPEAR1310_PERIP1_CLK_ENB, SPEAR1310_PCIE_SATA_2_CLK_ENB,
 			0, &_lock);
-	clk_register_clkdev(clk, NULL, "dw_pcie.2");
+	clk_register_clkdev(clk, NULL, "b4000000.pcie");
 	clk_register_clkdev(clk, NULL, "b4000000.ahci");
 
 	clk = clk_register_gate(NULL, "sysram0_clk", "ahb_clk", 0,
diff --git a/drivers/clk/spear/spear1340_clock.c b/drivers/clk/spear/spear1340_clock.c
index fe835c1..5a5c664 100644
--- a/drivers/clk/spear/spear1340_clock.c
+++ b/drivers/clk/spear/spear1340_clock.c
@@ -839,7 +839,7 @@ void __init spear1340_clk_init(void __iomem *misc_base)
 	clk = clk_register_gate(NULL, "pcie_sata_clk", "ahb_clk", 0,
 			SPEAR1340_PERIP1_CLK_ENB, SPEAR1340_PCIE_SATA_CLK_ENB,
 			0, &_lock);
-	clk_register_clkdev(clk, NULL, "dw_pcie");
+	clk_register_clkdev(clk, NULL, "b1000000.pcie");
 	clk_register_clkdev(clk, NULL, "b1000000.ahci");
 
 	clk = clk_register_gate(NULL, "sysram0_clk", "ahb_clk", 0,
-- 
1.7.0.1

^ permalink raw reply related


This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox