* Re: [3/4] powerpc/85xx: Add C293PCIE board support
From: Scott Wood @ 2013-07-22 22:58 UTC (permalink / raw)
To: Po Liu; +Cc: linuxppc-dev, Mingkai Hu
In-Reply-To: <1366854857-22791-3-git-send-email-Po.Liu@freescale.com>
On Thu, Apr 25, 2013 at 09:54:16AM +0800, Po Liu wrote:
> From: Mingkai Hu <Mingkai.Hu@freescale.com>
>
> C293PCIE board is a series of Freescale PCIe add-in cards to perform
> as public key crypto accelerator or secure key management module.
>
> - 512KB platform SRAM in addition to 512K L2 Cache/SRAM
> - 512MB soldered DDR3 32bit memory
> - CPLD System Logic
> - 64MB x16 NOR flash and 4GB x8 NAND flash
> - 16MB SPI flash
>
> Signed-off-by: Mingkai Hu <Mingkai.Hu@freescale.com>
> Singed-off-by: Po Liu <Po.Liu@freescale.com>
Signed
> + partition@900000 {
> + /* 33MB for rootfs */
> + reg = <0x00900000 0x02100000>;
> + label = "NOR Rootfs Image";
> + };
> +
> + partition@2a00000 {
> + /* 20MB for JFFS2 based Root file System */
> + reg = <0x02a00000 0x01400000>;
> + label = "NOR JFFS2 Root File System";
> + };
Don't specify JFFS2. Combine these two partitions into one.
> + partition@600000 {
> + /* 4MB for Compressed Root file System Image */
> + reg = <0x00600000 0x00400000>;
> + label = "NAND Compressed RFS Image";
> + };
> +
> + partition@a00000 {
> + /* 15MB for JFFS2 based Root file System */
> + reg = <0x00a00000 0x00f00000>;
> + label = "NAND JFFS2 Root File System";
> + };
Likewise.
> + partition@1900000 {
> + /* 7MB for User Area */
> + reg = <0x01900000 0x00700000>;
> + label = "NAND User area";
> + };
Above you say there's 4 GiB of NAND, but here you define partitions that
only cover 32 MiB.
> + };
> +
> + cpld@2,0 {
> + #address-cells = <1>;
> + #size-cells = <1>;
> + compatible = "fsl,c293pcie-cpld";
> + reg = <0x2 0x0 0x0000020>;
> + bank-width = <1>;
> + device-width = <1>;
> + };
What do bank-width and device-width mean here?
Why all the leading zeroes in 0x0000020?
> + partition@580000 {
> + /* 4MB for Compressed RFS Image */
> + reg = <0x00580000 0x00400000>;
> + label = "SPI Flash Compressed RFSImage";
> + };
> +
> + partition@980000 {
> + /* 6.5MB for JFFS2 based RFS */
> + reg = <0x00980000 0x00680000>;
> + label = "SPI Flash JFFS2 RFS";
> + };
Again, merge these two and don't specify JFFS2.
> diff --git a/arch/powerpc/platforms/85xx/Kconfig b/arch/powerpc/platforms/85xx/Kconfig
> index a0dcd57..df26b21 100644
> --- a/arch/powerpc/platforms/85xx/Kconfig
> +++ b/arch/powerpc/platforms/85xx/Kconfig
> @@ -32,6 +32,13 @@ config BSC9131_RDB
> StarCore SC3850 DSP
> Manufacturer : Freescale Semiconductor, Inc
>
> +config C293_PCIE
> + bool "Freescale C293PCIE"
> + select DEFAULT_UIMAGE
> + select SWIOTLB
> + help
> + This option enables support for the C293PCIE board
Why do you need SWIOTLB if the board has 512 MiB soldered RAM?
> diff --git a/arch/powerpc/platforms/85xx/c293pcie.c b/arch/powerpc/platforms/85xx/c293pcie.c
> new file mode 100644
> index 0000000..75dda12
> --- /dev/null
> +++ b/arch/powerpc/platforms/85xx/c293pcie.c
> @@ -0,0 +1,82 @@
> +/*
> + * C293PCIE Board Setup
> + *
> + * Copyright 2013 Freescale Semiconductor Inc.
> + *
> + * 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/stddef.h>
> +#include <linux/kernel.h>
> +#include <linux/pci.h>
> +#include <linux/delay.h>
> +#include <linux/interrupt.h>
> +#include <linux/of_platform.h>
> +
> +#include <asm/time.h>
> +#include <asm/machdep.h>
> +#include <asm/pci-bridge.h>
> +#include <mm/mmu_decl.h>
> +#include <asm/prom.h>
> +#include <asm/udbg.h>
> +#include <asm/mpic.h>
> +
> +#include <sysdev/fsl_soc.h>
> +#include <sysdev/fsl_pci.h>
> +
> +#include "mpc85xx.h"
Are you sure you need all of these? I don't see any delays, for example.
-Scott
^ permalink raw reply
* Re: [1/4] powerpc/85xx: Add SEC6.0 device tree
From: Scott Wood @ 2013-07-22 22:41 UTC (permalink / raw)
To: Po Liu; +Cc: linuxppc-dev, Mingkai Hu
In-Reply-To: <1366854857-22791-1-git-send-email-Po.Liu@freescale.com>
On Thu, Apr 25, 2013 at 09:54:14AM +0800, Po Liu wrote:
> From: Mingkai Hu <Mingkai.Hu@freescale.com>
>
> Add device tree for SEC 6.0 used on C29x silicon.
>
> Signed-off-by: Mingkai Hu <Mingkai.Hu@freescale.com>
> Singed-off-by: Po Liu <Po.Liu@freescale.com>
I've heard of patches being flamed, but here we want signing, not
singeing. :-)
Don't forget that you can use the -s option to have git add the signoff
for you.
> ---
> Base on git://git.am.freescale.net/gitolite/mirrors/linux-2.6.git
This URL is not accessible outside Freescale, so don't reference it when
posting patches publicly.
If your patch is against the latest upstream code, you don't need to say
anything special about that. You only need to make a note when it's
against some other yet-to-be-merged tree or patch.
> + compatible = "fsl,sec-v6.0", "fsl,sec-v5.2",
> + "fsl,sec-v5.0", "fsl,sec-v4.4",
> + "fsl,sec-v4.0";
> + fsl,sec-era = <6>;
> + #address-cells = <1>;
> + #size-cells = <1>;
> +
> + jr@1000 {
> + compatible = "fsl,sec-v6.0-job-ring",
> + "fsl,sec-v5.2-job-ring",
> + "fsl,sec-v5.0-job-ring",
> + "fsl,sec-v4.4-job-ring",
> + "fsl,sec-v4.0-job-ring";
> + reg = <0x1000 0x1000>;
> + };
> +
> + jr@2000 {
> + compatible = "fsl,sec-v6.0-job-ring",
> + "fsl,sec-v5.2-job-ring",
> + "fsl,sec-v5.0-job-ring",
> + "fsl,sec-v4.4-job-ring",
> + "fsl,sec-v4.0-job-ring";
> + reg = <0x2000 0x1000>;
> + };
You claim compatibility with a bunch of prior SECs, but sec-v5.2 has four
job rings and an rtic node. Likewise for the previous compatibles
listed. This has two job rings and no rtic.
Can you point to where in the SEC v4.0 binding (I don't see a binding for
the subsequent versions), it says that these are optional?
-Scott
^ permalink raw reply
* Re: PPC: Don't sync timebase when inside VM
From: Scott Wood @ 2013-07-22 22:19 UTC (permalink / raw)
To: Alexander Graf; +Cc: linuxppc-dev, kvm, kvm-ppc
In-Reply-To: <1330697553-27156-1-git-send-email-agraf@suse.de>
On Fri, Mar 02, 2012 at 03:12:33PM +0100, Alexander Graf wrote:
> When running inside a virtual machine, we can not modify timebase, so
> let's just not call the functions for it then.
>
> This resolves hangs when booting e500 SMP guests on overcommitted hosts.
>
> Reported-by: Stuart Yoder <B08248@freescale.com>
> Signed-off-by: Alexander Graf <agraf@suse.de>
>
> ---
> arch/powerpc/platforms/85xx/smp.c | 7 +++++++
> 1 files changed, 7 insertions(+), 0 deletions(-)
>
> diff --git a/arch/powerpc/platforms/85xx/smp.c b/arch/powerpc/platforms/85xx/smp.c
> index ff42490..d4b6c1f 100644
> --- a/arch/powerpc/platforms/85xx/smp.c
> +++ b/arch/powerpc/platforms/85xx/smp.c
> @@ -249,6 +249,13 @@ void __init mpc85xx_smp_init(void)
> smp_85xx_ops.cause_ipi = doorbell_cause_ipi;
> }
>
> + /* When running under a hypervisor, we can not modify tb */
> + np = of_find_node_by_path("/hypervisor");
> + if (np) {
> + smp_85xx_ops.give_timebase = NULL;
> + smp_85xx_ops.take_timebase = NULL;
> + }
I'm marking this superseded as we now only set give/take_timebase if a
guts node is present that corresponds to an SMP SoC. QEMU currently
advertises an mpc8544 guts (which is not SMP) and will eventually move to
a paravirt device with no guts at all.
-Scott
^ permalink raw reply
* Re: Enable CONFIG_DEVTMPFS_MOUNT to ensure /dev can be mounted correctly
From: Scott Wood @ 2013-07-22 22:04 UTC (permalink / raw)
To: Zhenhua Luo; +Cc: linuxppc-dev
In-Reply-To: <1365688591-5323-1-git-send-email-zhenhua.luo@freescale.com>
On Thu, Apr 11, 2013 at 09:56:30PM +0800, Zhenhua Luo wrote:
> When using recent udev, the /dev node mount requires CONFIG_DEVTMPFS_MOUNT
> is enabled in Kernel. The patch enables the option in defconfig of Freescale
> QorIQ targets.
>
> Changed defconfig list:
> arch/powerpc/configs/85xx/p1023rds_defconfig
> arch/powerpc/configs/corenet32_smp_defconfig
> arch/powerpc/configs/corenet64_smp_defconfig
> arch/powerpc/configs/mpc85xx_smp_defconfig
What about mpc83xx and mpc85xx (non-smp)?
It'd be nice if non-hardware-specific things that are required for a
typical Linux system were "default y". Even nicer if we could have
config fragments for various usage profiles that are separate from
hardware config.
-Scott
^ permalink raw reply
* Re: [PATCH v4 1/3] DMA: Freescale: revise device tree binding document
From: Scott Wood @ 2013-07-22 17:53 UTC (permalink / raw)
To: hongbo.zhang
Cc: vinod.koul, devicetree-discuss, linux-kernel, vakul, Hongbo Zhang,
djbw, linuxppc-dev
In-Reply-To: <1374472540-21177-2-git-send-email-hongbo.zhang@freescale.com>
On 07/22/2013 12:55:38 AM, hongbo.zhang@freescale.com wrote:
> From: Hongbo Zhang <hongbo.zhang@freescale.com>
>=20
> This updates the discription of each type of DMA controller and its =20
> channels,
> it is preparation for adding another new DMA controller binding, also =20
> fixes
> some defects of indent for text alignment at the same time.
>=20
> Signed-off-by: Hongbo Zhang <hongbo.zhang@freescale.com>
> ---
> .../devicetree/bindings/powerpc/fsl/dma.txt | 56 =20
> +++++++++++---------
> 1 file changed, 30 insertions(+), 26 deletions(-)
>=20
> diff --git a/Documentation/devicetree/bindings/powerpc/fsl/dma.txt =20
> b/Documentation/devicetree/bindings/powerpc/fsl/dma.txt
> index 2a4b4bc..0650171 100644
> --- a/Documentation/devicetree/bindings/powerpc/fsl/dma.txt
> +++ b/Documentation/devicetree/bindings/powerpc/fsl/dma.txt
> @@ -1,33 +1,33 @@
> -* Freescale 83xx DMA Controller
> +* Freescale DMA Controllers
>=20
> -Freescale PowerPC 83xx have on chip general purpose DMA controllers.
> +** Freescale ELO DMA Controller
> + This is a little-endian DMA controller.
> + Used in Freescale PowerPC 83xx series, such as:
> + mpc8313, mpc8315, mpc8323, mpc8347, mpc8349, mpc8360, mpc8377, =20
> mpc8378, mpc8379.
You don't need to list every single chip... What happens when new =20
chips come out (not so likely with mpc83xx, but more likely for =20
eloplus/elo3)? Do we keep updating this, or have a list that looks =20
complete but isn't?
My point in suggesting that some examples be given is just so that the =20
reader knows where to find a manual that documents a particular version =20
of "elo", and to give a rough idea of what product families use it.
> -Freescale PowerPC 85xx/86xx have on chip general purpose DMA =20
> controllers.
> +** Freescale ELOPLUS DMA Controller
> + This is DMA controller with extended addresses and chaining.
> + Used in Freescale PowerPC 85xx/86xx and pxxx series chips, such =20
> as:
> + [1] mpc8540, mpc8541, mpc8555, mpc8560, mpc8610, mpc8641,
> + [2] mpc8536, mpc8544, mpc8548, mpc8568, mpc8569, mpc8572, p1010, =20
> p1020, p1021,
> + p1022, p1023, p2020, p2041, p3041, p4080, p5020, p5040, and =20
> also bsc9131.
What do [1] and [2] signify here?
Oh, I see. It's weird for footnotes to come before the place they're =20
referenced...
> Required properties:
>=20
> -- compatible : compatible list, contains 2 entries, first is
> - "fsl,CHIP-dma", where CHIP is the processor
> - (mpc8540, mpc8540, etc.) and the second is
> - "fsl,eloplus-dma"
> +- compatible : compatible list, contains 2 entries for chips =20
> in above
> + list[1], the first is "fsl,CHIP-dma", where =20
> CHIP is the
> + processor and the second is "fsl,eloplus-dma". =20
> contains
> + only one "fsl,eloplus-dma" for chips in above =20
> list[2]
Don't encode this difference in the binding document. It wasn't on =20
purpose, but rather an artifact of factoring things out into dtsi =20
files. Just make it optional.
Why can't we just talk about what compatible must include, as I =20
suggested earlier, rather than what it must *be*?
> - reg : <registers mapping for DMA general status reg>
> - cell-index : controller index. 0 for controller @ 0x21000,
> 1 for controller @ 0xc000
> -- ranges : Should be defined as specified in 1) to =20
> describe the
> - DMA controller channels.
> +- ranges : physical address range of DMA controller =20
> channels
ranges will not have physical addresses at this level. They'll only =20
become physical addresses when translated by the ccsr node's ranges.
-Scott=
^ permalink raw reply
* Re: [PATCH 2/2] mmc: esdhc: get voltage from dts file
From: Scott Wood @ 2013-07-22 17:40 UTC (permalink / raw)
To: Haijun Zhang
Cc: linux-mmc, AFLEMING, cbouatmailru, cjb, linuxppc-dev,
Haijun Zhang
In-Reply-To: <1374479636-9254-2-git-send-email-Haijun.Zhang@freescale.com>
On 07/22/2013 02:53:56 AM, Haijun Zhang wrote:
> Add voltage-range support in esdhc of T4, So we can choose
> to read voltages from dts file as one optional.
> If we can get a valid voltage-range from device node, we use
> this voltage as the final voltage support. Else we still read
> from capacity or from other provider.
>=20
> Signed-off-by: Haijun Zhang <haijun.zhang@freescale.com>
> Signed-off-by: Anton Vorontsov <cbouatmailru@gmail.com>
> ---
> drivers/mmc/host/sdhci-of-esdhc.c | 31 =20
> +++++++++++++++++++++++++++++++
> drivers/mmc/host/sdhci.c | 3 +++
> include/linux/mmc/sdhci.h | 1 +
> 3 files changed, 35 insertions(+)
>=20
> diff --git a/drivers/mmc/host/sdhci-of-esdhc.c =20
> b/drivers/mmc/host/sdhci-of-esdhc.c
> index 15039e2..8b4b27a 100644
> --- a/drivers/mmc/host/sdhci-of-esdhc.c
> +++ b/drivers/mmc/host/sdhci-of-esdhc.c
> @@ -262,6 +262,35 @@ static int esdhc_pltfm_bus_width(struct =20
> sdhci_host *host, int width)
> return 0;
> }
>=20
> +static void esdhc_get_voltage(struct sdhci_host *host,
> + struct platform_device *pdev)
> +{
> + const u32 *voltage_ranges;
> + int num_ranges, i;
> + struct device_node *np;
> + np =3D pdev->dev.of_node;
> +
> + voltage_ranges =3D of_get_property(np, "voltage-ranges", =20
> &num_ranges);
> + num_ranges =3D num_ranges / sizeof(*voltage_ranges) / 2;
> + if (!voltage_ranges || !num_ranges) {
> + dev_info(&pdev->dev, "OF: voltage-ranges =20
> unspecified\n");
> + return;
> + }
> +
> + for (i =3D 0; i < num_ranges; i++) {
> + const int j =3D i * 2;
> + u32 mask;
> + mask =3D =20
> mmc_vddrange_to_ocrmask(be32_to_cpu(voltage_ranges[j]),
> + be32_to_cpu(voltage_ranges[j + 1]));
> + if (!mask) {
> + dev_info(&pdev->dev,
> + "OF: false voltage-ranges specified\n");
> + return;
> + }
> + host->ocr_mask |=3D mask;
> + }
> +}
Don't duplicate this code. Move it somewhere common and share it.
Why did you remove the range index from the error string, and why did =20
you change it from dev_err to dev_info?
-Scott=
^ permalink raw reply
* Re: [PATCH v2] of: Specify initrd location using 64-bit
From: Jean-Christophe PLAGNIOL-VILLARD @ 2013-07-22 15:01 UTC (permalink / raw)
To: Santosh Shilimkar
Cc: Nicolas Pitre, linux-mips, Aurelien Jacquiot, Catalin Marinas,
Sebastian Andrzej Siewior, Will Deacon, Max Filippov,
Paul Mackerras, Jonas Bonn, Russell King, linux-c6x-dev, x86, arm,
Geert Uytterhoeven, Mark Salter, grant.likely, robherring2,
linux-xtensa, James Hogan, devicetree-discuss, Rob Herring,
linux-arm-kernel, Chris Zankel, Michal Simek, Vineet Gupta,
Ralf Baechle, linuxppc-dev
In-Reply-To: <1372702835-5333-1-git-send-email-santosh.shilimkar@ti.com>
On 14:20 Mon 01 Jul , Santosh Shilimkar wrote:
> On some PAE architectures, the entire range of physical memory could reside
> outside the 32-bit limit. These systems need the ability to specify the
> initrd location using 64-bit numbers.
>
> This patch globally modifies the early_init_dt_setup_initrd_arch() function to
> use 64-bit numbers instead of the current unsigned long.
>
> There has been quite a bit of debate about whether to use u64 or phys_addr_t.
> It was concluded to stick to u64 to be consistent with rest of the device
> tree code. As summarized by Geert, "The address to load the initrd is decided
> by the bootloader/user and set at that point later in time. The dtb should not
> be tied to the kernel you are booting"
>
> More details on the discussion can be found here:
> https://lkml.org/lkml/2013/6/20/690
> https://lkml.org/lkml/2012/9/13/544
>
> Cc: Grant Likely <grant.likely@linaro.org>
> Cc: Rob Herring <rob.herring@calxeda.com>
> Cc: Geert Uytterhoeven <geert@linux-m68k.org>
> Cc: Sebastian Andrzej Siewior <bigeasy@linutronix.de>
> Cc: Jean-Christophe PLAGNIOL-VILLARD <plagnioj@jcrosoft.com>
> Cc: Vineet Gupta <vgupta@synopsys.com>
> Cc: Russell King <linux@arm.linux.org.uk>
> Cc: Catalin Marinas <catalin.marinas@arm.com>
> Cc: Will Deacon <will.deacon@arm.com>
> Cc: Mark Salter <msalter@redhat.com>
> Cc: Aurelien Jacquiot <a-jacquiot@ti.com>
> Cc: James Hogan <james.hogan@imgtec.com>
> Cc: Michal Simek <monstr@monstr.eu>
> Cc: Ralf Baechle <ralf@linux-mips.org>
> Cc: Jonas Bonn <jonas@southpole.se>
> Cc: Benjamin Herrenschmidt <benh@kernel.crashing.org>
> Cc: Paul Mackerras <paulus@samba.org>
> Cc: x86@kernel.org
> Cc: arm@kernel.org
> Cc: Chris Zankel <chris@zankel.net>
> Cc: Max Filippov <jcmvbkbc@gmail.com>
> Cc: bigeasy@linutronix.de
> Cc: robherring2@gmail.com
> Cc: Nicolas Pitre <nicolas.pitre@linaro.org>
Acked-by: Jean-Christophe PLAGNIOL-VILLARD <plagnioj@jcrosoft.com>
>
> Cc: linux-arm-kernel@lists.infradead.org
> Cc: linux-c6x-dev@linux-c6x.org
> Cc: linux-mips@linux-mips.org
> Cc: linuxppc-dev@lists.ozlabs.org
> Cc: linux-xtensa@linux-xtensa.org
> Cc: devicetree-discuss@lists.ozlabs.org
>
> Signed-off-by: Santosh Shilimkar <santosh.shilimkar@ti.com>
> ---
> arch/arc/mm/init.c | 5 ++---
> arch/arm/mm/init.c | 2 +-
> arch/arm64/mm/init.c | 3 +--
> arch/c6x/kernel/devicetree.c | 3 +--
> arch/metag/mm/init.c | 5 ++---
> arch/microblaze/kernel/prom.c | 3 +--
> arch/mips/kernel/prom.c | 3 +--
> arch/openrisc/kernel/prom.c | 3 +--
> arch/powerpc/kernel/prom.c | 3 +--
> arch/x86/kernel/devicetree.c | 3 +--
> arch/xtensa/kernel/setup.c | 3 +--
> drivers/of/fdt.c | 10 ++++++----
> include/linux/of_fdt.h | 3 +--
> 13 files changed, 20 insertions(+), 29 deletions(-)
>
> diff --git a/arch/arc/mm/init.c b/arch/arc/mm/init.c
> index 4a17736..7991e08 100644
> --- a/arch/arc/mm/init.c
> +++ b/arch/arc/mm/init.c
> @@ -157,9 +157,8 @@ void __init free_initrd_mem(unsigned long start, unsigned long end)
> #endif
>
> #ifdef CONFIG_OF_FLATTREE
> -void __init early_init_dt_setup_initrd_arch(unsigned long start,
> - unsigned long end)
> +void __init early_init_dt_setup_initrd_arch(u64 start, u64 end)
> {
> - pr_err("%s(%lx, %lx)\n", __func__, start, end);
> + pr_err("%s(%llx, %llx)\n", __func__, start, end);
> }
> #endif /* CONFIG_OF_FLATTREE */
> diff --git a/arch/arm/mm/init.c b/arch/arm/mm/init.c
> index 9a5cdc0..afeaef7 100644
> --- a/arch/arm/mm/init.c
> +++ b/arch/arm/mm/init.c
> @@ -76,7 +76,7 @@ static int __init parse_tag_initrd2(const struct tag *tag)
> __tagtable(ATAG_INITRD2, parse_tag_initrd2);
>
> #ifdef CONFIG_OF_FLATTREE
> -void __init early_init_dt_setup_initrd_arch(unsigned long start, unsigned long end)
> +void __init early_init_dt_setup_initrd_arch(u64 start, u64 end)
> {
> phys_initrd_start = start;
> phys_initrd_size = end - start;
> diff --git a/arch/arm64/mm/init.c b/arch/arm64/mm/init.c
> index f497ca7..7047708 100644
> --- a/arch/arm64/mm/init.c
> +++ b/arch/arm64/mm/init.c
> @@ -44,8 +44,7 @@ static unsigned long phys_initrd_size __initdata = 0;
>
> phys_addr_t memstart_addr __read_mostly = 0;
>
> -void __init early_init_dt_setup_initrd_arch(unsigned long start,
> - unsigned long end)
> +void __init early_init_dt_setup_initrd_arch(u64 start, u64 end)
> {
> phys_initrd_start = start;
> phys_initrd_size = end - start;
> diff --git a/arch/c6x/kernel/devicetree.c b/arch/c6x/kernel/devicetree.c
> index bdb56f0..287d0e6 100644
> --- a/arch/c6x/kernel/devicetree.c
> +++ b/arch/c6x/kernel/devicetree.c
> @@ -33,8 +33,7 @@ void __init early_init_devtree(void *params)
>
>
> #ifdef CONFIG_BLK_DEV_INITRD
> -void __init early_init_dt_setup_initrd_arch(unsigned long start,
> - unsigned long end)
> +void __init early_init_dt_setup_initrd_arch(u64 start, u64 end)
> {
> initrd_start = (unsigned long)__va(start);
> initrd_end = (unsigned long)__va(end);
> diff --git a/arch/metag/mm/init.c b/arch/metag/mm/init.c
> index d05b845..bdc4811 100644
> --- a/arch/metag/mm/init.c
> +++ b/arch/metag/mm/init.c
> @@ -419,10 +419,9 @@ void free_initrd_mem(unsigned long start, unsigned long end)
> #endif
>
> #ifdef CONFIG_OF_FLATTREE
> -void __init early_init_dt_setup_initrd_arch(unsigned long start,
> - unsigned long end)
> +void __init early_init_dt_setup_initrd_arch(u64 start, u64 end)
> {
> - pr_err("%s(%lx, %lx)\n",
> + pr_err("%s(%llx, %llx)\n",
> __func__, start, end);
> }
> #endif /* CONFIG_OF_FLATTREE */
> diff --git a/arch/microblaze/kernel/prom.c b/arch/microblaze/kernel/prom.c
> index 0a2c68f..62e2e8f 100644
> --- a/arch/microblaze/kernel/prom.c
> +++ b/arch/microblaze/kernel/prom.c
> @@ -136,8 +136,7 @@ void __init early_init_devtree(void *params)
> }
>
> #ifdef CONFIG_BLK_DEV_INITRD
> -void __init early_init_dt_setup_initrd_arch(unsigned long start,
> - unsigned long end)
> +void __init early_init_dt_setup_initrd_arch(u64 start, u64 end)
> {
> initrd_start = (unsigned long)__va(start);
> initrd_end = (unsigned long)__va(end);
> diff --git a/arch/mips/kernel/prom.c b/arch/mips/kernel/prom.c
> index 5712bb5..32b8788 100644
> --- a/arch/mips/kernel/prom.c
> +++ b/arch/mips/kernel/prom.c
> @@ -58,8 +58,7 @@ void * __init early_init_dt_alloc_memory_arch(u64 size, u64 align)
> }
>
> #ifdef CONFIG_BLK_DEV_INITRD
> -void __init early_init_dt_setup_initrd_arch(unsigned long start,
> - unsigned long end)
> +void __init early_init_dt_setup_initrd_arch(u64 start, u64 end)
> {
> initrd_start = (unsigned long)__va(start);
> initrd_end = (unsigned long)__va(end);
> diff --git a/arch/openrisc/kernel/prom.c b/arch/openrisc/kernel/prom.c
> index 5869e3f..150215a 100644
> --- a/arch/openrisc/kernel/prom.c
> +++ b/arch/openrisc/kernel/prom.c
> @@ -96,8 +96,7 @@ void __init early_init_devtree(void *params)
> }
>
> #ifdef CONFIG_BLK_DEV_INITRD
> -void __init early_init_dt_setup_initrd_arch(unsigned long start,
> - unsigned long end)
> +void __init early_init_dt_setup_initrd_arch(u64 start, u64 end)
> {
> initrd_start = (unsigned long)__va(start);
> initrd_end = (unsigned long)__va(end);
> diff --git a/arch/powerpc/kernel/prom.c b/arch/powerpc/kernel/prom.c
> index 8b6f7a9..2f3e252 100644
> --- a/arch/powerpc/kernel/prom.c
> +++ b/arch/powerpc/kernel/prom.c
> @@ -550,8 +550,7 @@ void * __init early_init_dt_alloc_memory_arch(u64 size, u64 align)
> }
>
> #ifdef CONFIG_BLK_DEV_INITRD
> -void __init early_init_dt_setup_initrd_arch(unsigned long start,
> - unsigned long end)
> +void __init early_init_dt_setup_initrd_arch(u64 start, u64 end)
> {
> initrd_start = (unsigned long)__va(start);
> initrd_end = (unsigned long)__va(end);
> diff --git a/arch/x86/kernel/devicetree.c b/arch/x86/kernel/devicetree.c
> index b158152..2fbad6b 100644
> --- a/arch/x86/kernel/devicetree.c
> +++ b/arch/x86/kernel/devicetree.c
> @@ -52,8 +52,7 @@ void * __init early_init_dt_alloc_memory_arch(u64 size, u64 align)
> }
>
> #ifdef CONFIG_BLK_DEV_INITRD
> -void __init early_init_dt_setup_initrd_arch(unsigned long start,
> - unsigned long end)
> +void __init early_init_dt_setup_initrd_arch(u64 start, u64 end)
> {
> initrd_start = (unsigned long)__va(start);
> initrd_end = (unsigned long)__va(end);
> diff --git a/arch/xtensa/kernel/setup.c b/arch/xtensa/kernel/setup.c
> index 6dd25ec..d45e602 100644
> --- a/arch/xtensa/kernel/setup.c
> +++ b/arch/xtensa/kernel/setup.c
> @@ -170,8 +170,7 @@ static int __init parse_tag_fdt(const bp_tag_t *tag)
>
> __tagtable(BP_TAG_FDT, parse_tag_fdt);
>
> -void __init early_init_dt_setup_initrd_arch(unsigned long start,
> - unsigned long end)
> +void __init early_init_dt_setup_initrd_arch(u64 start, u64 end)
> {
> initrd_start = (void *)__va(start);
> initrd_end = (void *)__va(end);
> diff --git a/drivers/of/fdt.c b/drivers/of/fdt.c
> index 808be06..21123b8 100644
> --- a/drivers/of/fdt.c
> +++ b/drivers/of/fdt.c
> @@ -550,7 +550,8 @@ int __init of_flat_dt_match(unsigned long node, const char *const *compat)
> */
> void __init early_init_dt_check_for_initrd(unsigned long node)
> {
> - unsigned long start, end, len;
> + u64 start, end;
> + unsigned long len;
> __be32 *prop;
>
> pr_debug("Looking for initrd properties... ");
> @@ -558,15 +559,16 @@ void __init early_init_dt_check_for_initrd(unsigned long node)
> prop = of_get_flat_dt_prop(node, "linux,initrd-start", &len);
> if (!prop)
> return;
> - start = of_read_ulong(prop, len/4);
> + start = of_read_number(prop, len/4);
>
> prop = of_get_flat_dt_prop(node, "linux,initrd-end", &len);
> if (!prop)
> return;
> - end = of_read_ulong(prop, len/4);
> + end = of_read_number(prop, len/4);
>
> early_init_dt_setup_initrd_arch(start, end);
> - pr_debug("initrd_start=0x%lx initrd_end=0x%lx\n", start, end);
> + pr_debug("initrd_start=0x%llx initrd_end=0x%llx\n",
> + (unsigned long long)start, (unsigned long long)end);
> }
> #else
> inline void early_init_dt_check_for_initrd(unsigned long node)
> diff --git a/include/linux/of_fdt.h b/include/linux/of_fdt.h
> index ed136ad..4a17939 100644
> --- a/include/linux/of_fdt.h
> +++ b/include/linux/of_fdt.h
> @@ -106,8 +106,7 @@ extern u64 dt_mem_next_cell(int s, __be32 **cellp);
> * physical addresses.
> */
> #ifdef CONFIG_BLK_DEV_INITRD
> -extern void early_init_dt_setup_initrd_arch(unsigned long start,
> - unsigned long end);
> +extern void early_init_dt_setup_initrd_arch(u64 start, u64 end);
> #endif
>
> /* Early flat tree scan hooks */
> --
> 1.7.9.5
>
^ permalink raw reply
* Re: [PATCH 1/2] powerpc: split the math emulation into two parts
From: Scott Wood @ 2013-07-22 17:25 UTC (permalink / raw)
To: Kumar Gala; +Cc: Kevin Hao, linuxppc
In-Reply-To: <4E35EEC3-D4D8-4C03-B22E-5574584539AE@kernel.crashing.org>
On 07/22/2013 09:36:05 AM, Kumar Gala wrote:
>=20
> On Jul 16, 2013, at 6:57 AM, Kevin Hao wrote:
>=20
> > For some SoC (such as the FSL BookE) even though there does have
> > a hardware FPU, but not all floating point instructions are
> > implemented. Unfortunately some versions of gcc do use these
> > unimplemented instructions. Then we have to enable the math =20
> emulation
> > to workaround this issue. It seems a little redundant to have the
> > support to emulate all the floating point instructions in this case.
> > So split the math emulation into two parts. One is for the SoC which
> > doesn't have FPU at all and the other for the SoC which does have =20
> the
> > hardware FPU and only need some special floating point instructions =20
> to
> > be emulated.
> >
> > Signed-off-by: Kevin Hao <haokexin@gmail.com>
> > ---
> > arch/powerpc/Kconfig | 20 ++++++++++++++++++++
> > arch/powerpc/math-emu/Makefile | 24 ++++++++++++------------
> > arch/powerpc/math-emu/math.c | 20 ++++++++++++++------
> > 3 files changed, 46 insertions(+), 18 deletions(-)
>=20
> why make the split, what harm is there in just turning on the full =20
> emulation code to handle the unimplemented cases?
My main motivation in requesting it was to contain the increase in =20
build time -- math-emu always stuck out to me as something that took a =20
noticeable amount of time to build. It also reduces the increase in =20
kernel image size.
> who says what some other implementation doesn't need something that =20
> you have in CONFIG_MATH_EMULATION_FULL?
The point is to include any instructions that are known to be missing =20
in any chip's FPU (excluding chips that don't have an FPU at all). If =20
it is discovered that some chip is missing an instruction that we =20
didn't account for, then we'd move that instruction from one list to =20
the other.
> Is the kernel code size really an issue?
It can be when you're storing it on flash -- especially when the growth =20
is out of control because of the need to justify pruning low-hanging =20
fruit such as this.
-Scott=
^ permalink raw reply
* Re: [PATCH] powerpc/msi: Fix compile error on mpc83xx
From: Scott Wood @ 2013-07-22 17:18 UTC (permalink / raw)
To: Jia Hongtao-B38951
Cc: Wood Scott-B07421, Jia Hongtao-B38951,
linuxppc-dev@lists.ozlabs.org, Li Yang-R58472
In-Reply-To: <412C8208B4A0464FA894C5F0C278CD5D01CF8676@039-SN1MPN1-004.039d.mgd.msft.net>
On 07/21/2013 09:00:51 PM, Jia Hongtao-B38951 wrote:
> Hi Scott,
>=20
> The fsl_msi.c build error on MPC83xx platform is fixed by this patch.
>=20
> Could you please have a review?
>=20
> Thanks.
> -Hongtao
I will apply it when I apply the patch that depends on it. I hope to =20
resume applying patches soon.
-Scott=
^ permalink raw reply
* Re: [PATCH] Fix a typo in pSeries_lpar_hpte_insert()
From: Aneesh Kumar K.V @ 2013-07-22 15:24 UTC (permalink / raw)
To: Denis Kirjanov; +Cc: Denis Kirjanov, linuxppc-dev
In-Reply-To: <1374470630-2106-1-git-send-email-kda@linux-powerpc.org>
Denis Kirjanov <kda@linux-powerpc.org> writes:
> Fix a typo in pSeries_lpar_hpte_insert()
>
> Signed-off-by: Denis Kirjanov <kda@linux-powerpc.org>
looks good
Reviewed-by: Aneesh Kumar K.V <aneesh.kumar@linux.vnet.ibm.com>
We may want to add the commit that introduced the change ?
801eb73f45371accc78ca9d6d22d647eeb722c11
> ---
> arch/powerpc/platforms/pseries/lpar.c | 2 +-
> 1 file changed, 1 insertion(+), 1 deletion(-)
>
> diff --git a/arch/powerpc/platforms/pseries/lpar.c b/arch/powerpc/platforms/pseries/lpar.c
> index 0da39fe..c4112ed 100644
> --- a/arch/powerpc/platforms/pseries/lpar.c
> +++ b/arch/powerpc/platforms/pseries/lpar.c
> @@ -136,7 +136,7 @@ static long pSeries_lpar_hpte_insert(unsigned long hpte_group,
> flags = 0;
>
> /* Make pHyp happy */
> - if ((rflags & _PAGE_NO_CACHE) & !(rflags & _PAGE_WRITETHRU))
> + if ((rflags & _PAGE_NO_CACHE) && !(rflags & _PAGE_WRITETHRU))
> hpte_r &= ~_PAGE_COHERENT;
> if (firmware_has_feature(FW_FEATURE_XCMO) && !(hpte_r & HPTE_R_N))
> flags |= H_COALESCE_CAND;
> --
> 1.8.0.2
^ permalink raw reply
* Re: [PATCH v2] of: Specify initrd location using 64-bit
From: Santosh Shilimkar @ 2013-07-22 14:50 UTC (permalink / raw)
To: Grant Likely
Cc: Nicolas Pitre, linux-mips, Aurelien Jacquiot, Catalin Marinas,
Sebastian Andrzej Siewior, Will Deacon, Max Filippov,
Paul Mackerras, Jonas Bonn, Russell King, linux-c6x-dev, x86, arm,
Geert Uytterhoeven, Mark Salter, Rob Herring,
Jean-Christophe PLAGNIOL-VILLARD, linux-xtensa, James Hogan,
devicetree-discuss, Rob Herring, linux-arm-kernel, Chris Zankel,
Michal Simek, Vineet Gupta, Ralf Baechle, linuxppc-dev
In-Reply-To: <20130720053945.C7AC63E0C52@localhost>
On Saturday 20 July 2013 01:39 AM, Grant Likely wrote:
> On Mon, 01 Jul 2013 16:34:26 -0500, Rob Herring <robherring2@gmail.com> wrote:
>> On 07/01/2013 01:20 PM, Santosh Shilimkar wrote:
>>> On some PAE architectures, the entire range of physical memory could reside
>>> outside the 32-bit limit. These systems need the ability to specify the
>>> initrd location using 64-bit numbers.
>>>
>>> This patch globally modifies the early_init_dt_setup_initrd_arch() function to
>>> use 64-bit numbers instead of the current unsigned long.
>>>
>>> There has been quite a bit of debate about whether to use u64 or phys_addr_t.
>>> It was concluded to stick to u64 to be consistent with rest of the device
>>> tree code. As summarized by Geert, "The address to load the initrd is decided
>>> by the bootloader/user and set at that point later in time. The dtb should not
>>> be tied to the kernel you are booting"
>>
>> That was quoting me. Otherwise:
>>
>> Acked-by: Rob Herring <rob.herring@calxeda.com>
>>
>> Unless Grant feels compelled to pick this up for 3.11, I think it has to
>> wait for 3.12.
>
> Nope, 3.12 is fine. Applied.
>
Thanks Grant.
Regards,
Santosh
^ permalink raw reply
* Re: [PATCH 1/2] Powerpc: Add voltage ranges support for T4
From: Kumar Gala @ 2013-07-22 14:39 UTC (permalink / raw)
To: Wrobel Heinz-R39252
Cc: Wood Scott-B07421, linux-mmc@vger.kernel.org, Zhang Haijun-B42677,
Fleming Andy-AFLEMING, cbouatmailru@gmail.com, cjb@laptop.org,
linuxppc-dev@lists.ozlabs.org
In-Reply-To: <192298D25D96A042975E372855100DB70A1A93DC@039-SN2MPN1-012.039d.mgd.msft.net>
On Jul 22, 2013, at 4:47 AM, Wrobel Heinz-R39252 wrote:
>> Subject: [PATCH 1/2] Powerpc: Add voltage ranges support for T4
>>=20
>> Special voltages that can be support by eSDHC of T4 in esdhc node.
>>=20
>> Signed-off-by: Haijun Zhang <haijun.zhang@freescale.com>
>> Signed-off-by: Anton Vorontsov <cbouatmailru@gmail.com>
>=20
>> --- a/Documentation/devicetree/bindings/mmc/fsl-esdhc.txt
>> +++ b/Documentation/devicetree/bindings/mmc/fsl-esdhc.txt
>> @@ -19,6 +19,8 @@ Optional properties:
>> "bus-width =3D <1>" property.
>> - sdhci,auto-cmd12: specifies that a controller can only handle =
auto
>> CMD12.
>> + - 3300 3300: specifies that eSDHC controller can support voltages
>> ranges
>> + from 3300 to 3300. This is an optional.
>=20
> "This is an optional." is an unclear statement.
>=20
>> +++ b/arch/powerpc/boot/dts/fsl/t4240si-post.dtsi
>> @@ -399,6 +399,7 @@
>> sdhc@114000 {
>> compatible =3D "fsl,t4240-esdhc", "fsl,esdhc";
>> sdhci,auto-cmd12;
>> + voltage-ranges =3D <1800 1800 3300 3300>;
>=20
> This is IMHO incorrect and potentially dangerous.
> The T4 silicon will only support 1.8V on SDHC pins per hardware =
specification.
> The Freescale T4240QDS reference board has extra voltage shifters =
added to allow 3.3V operation, but that is _not_ a silicon feature. It =
is a specific board feature that may or may not translate to other =
boards, depending on how SD spec conformant a board builder wants to be.
>=20
> If the intent is to state that a physical SDHC interface on a board =
has to be built to support 3.3V operation to be SD spec conformant for =
off-the-shelf cards because a reset would change the signal voltage to =
3.3V, then I am not sure that putting this down as silicon "feature" =
without further explanation about the background anywhere is the right =
way to go.
> IMHO silicon features are really just silicon features and not =
technically optional external circuitry additions implied by common use.
>=20
> Best regards,
>=20
> Heinz
I'd say that the t4240si-post.dtsi should be:
voltage-ranges =3D <1800 1800>;
Than have the t4240qds.dts do:
voltage-ranges =3D <1800 1800 3300 3300>;
As the 3.3V sounds like a board specific feature.
[ send this as 2 patches, on for the t4240si-post.dtsi and another for =
the t4240qds.dts ]
- k
=09=
^ permalink raw reply
* Re: [PATCH 1/2] powerpc: split the math emulation into two parts
From: Kumar Gala @ 2013-07-22 14:36 UTC (permalink / raw)
To: Kevin Hao; +Cc: Scott Wood, linuxppc
In-Reply-To: <1373975836-11928-2-git-send-email-haokexin@gmail.com>
On Jul 16, 2013, at 6:57 AM, Kevin Hao wrote:
> For some SoC (such as the FSL BookE) even though there does have
> a hardware FPU, but not all floating point instructions are
> implemented. Unfortunately some versions of gcc do use these
> unimplemented instructions. Then we have to enable the math emulation
> to workaround this issue. It seems a little redundant to have the
> support to emulate all the floating point instructions in this case.
> So split the math emulation into two parts. One is for the SoC which
> doesn't have FPU at all and the other for the SoC which does have the
> hardware FPU and only need some special floating point instructions to
> be emulated.
>=20
> Signed-off-by: Kevin Hao <haokexin@gmail.com>
> ---
> arch/powerpc/Kconfig | 20 ++++++++++++++++++++
> arch/powerpc/math-emu/Makefile | 24 ++++++++++++------------
> arch/powerpc/math-emu/math.c | 20 ++++++++++++++------
> 3 files changed, 46 insertions(+), 18 deletions(-)
why make the split, what harm is there in just turning on the full =
emulation code to handle the unimplemented cases?
who says what some other implementation doesn't need something that you =
have in CONFIG_MATH_EMULATION_FULL?
Is the kernel code size really an issue?
- k=
^ permalink raw reply
* Re: [PATCH 3/4 V2] mmc: esdhc: Correct host version of T4240-R1.0
From: Kumar Gala @ 2013-07-22 14:30 UTC (permalink / raw)
To: Haijun Zhang
Cc: linux-mmc, AFLEMING, cbouatmailru, scottwood, cjb, linuxppc-dev
In-Reply-To: <1374055891-20703-2-git-send-email-Haijun.Zhang@freescale.com>
On Jul 17, 2013, at 5:11 AM, Haijun Zhang wrote:
> Vender version and sdhc spec version of T4240-R1.0 is incorrect.
> The right value should be VVN=3D0x13, SVN =3D 0x1. The wrong version
> number will break down the ADMA data transfer.
> This defect only exist in T4240-R1.0. Will be fixed in T4240-R2.0.
> Also share vvn and svr for public use.
>=20
> Signed-off-by: Haijun Zhang <haijun.zhang@freescale.com>
> ---
> changes for V2:
> - Remove broken ADMA quirk.
> - Rebuild patch of Add quirks to support T4240 board
>=20
> drivers/mmc/host/sdhci-of-esdhc.c | 29 +++++++++++++----------------
> 1 file changed, 13 insertions(+), 16 deletions(-)
>=20
> diff --git a/drivers/mmc/host/sdhci-of-esdhc.c =
b/drivers/mmc/host/sdhci-of-esdhc.c
> index adfaadd..570bca8 100644
> --- a/drivers/mmc/host/sdhci-of-esdhc.c
> +++ b/drivers/mmc/host/sdhci-of-esdhc.c
> @@ -26,7 +26,7 @@
> #define VENDOR_V_22 0x12
> #define VENDOR_V_23 0x13
>=20
> -static u32 svr;
> +static u32 svr, vvn;
>=20
> static u32 esdhc_readl(struct sdhci_host *host, int reg)
> {
> @@ -43,11 +43,9 @@ static u32 esdhc_readl(struct sdhci_host *host, int =
reg)
> * For FSL eSDHC, must aligned 4-byte, so use 0xFC to read the
> * the verdor version number, oxFE is SDHCI_HOST_VERSION.
> */
> - if ((reg =3D=3D SDHCI_CAPABILITIES) && (ret & =
SDHCI_CAN_DO_ADMA1)) {
> - u32 tmp =3D in_be32(host->ioaddr + =
SDHCI_SLOT_INT_STATUS);
> - tmp =3D (tmp & SDHCI_VENDOR_VER_MASK) >> =
SDHCI_VENDOR_VER_SHIFT;
> - if (tmp > VENDOR_V_22)
> - ret |=3D SDHCI_CAN_DO_ADMA2;
> + if ((reg =3D=3D SDHCI_CAPABILITIES) && (ret & =
SDHCI_CAN_DO_ADMA1) &&
> + (vvn > VENDOR_V_22)) {
> + ret |=3D SDHCI_CAN_DO_ADMA2;
> }
>=20
> return ret;
> @@ -63,6 +61,12 @@ static u16 esdhc_readw(struct sdhci_host *host, int =
reg)
> ret =3D in_be32(host->ioaddr + base) & 0xffff;
> else
> ret =3D (in_be32(host->ioaddr + base) >> shift) & =
0xffff;
> +
> + /* T4240-R1.0 had a incorrect vendor version and spec version */
> + if ((reg =3D=3D SDHCI_HOST_VERSION) &&
> + ((SVR_SOC_VER(svr) =3D=3D SVR_T4240) && (SVR_REV(svr) =3D=3D=
0x10)))
> + ret =3D (VENDOR_V_23 << SDHCI_VENDOR_VER_SHIFT) | =
SDHCI_SPEC_200;
> +
is this check correct if this is on v2.0 Si as well?
- k
> return ret;
> }
>=20
> @@ -175,17 +179,12 @@ static void esdhc_reset(struct sdhci_host *host, =
u8 mask)
> */
> static void esdhci_of_adma_workaround(struct sdhci_host *host, u32 =
intmask)
> {
> - u32 tmp;
> bool applicable;
> dma_addr_t dmastart;
> dma_addr_t dmanow;
>=20
> - tmp =3D esdhc_readl(host, SDHCI_SLOT_INT_STATUS);
> - tmp =3D (tmp & SDHCI_VENDOR_VER_MASK) >> SDHCI_VENDOR_VER_SHIFT;
> -
> applicable =3D (intmask & SDHCI_INT_DATA_END) &&
> - (intmask & SDHCI_INT_BLK_GAP) &&
> - (tmp =3D=3D VENDOR_V_23);
> + (intmask & SDHCI_INT_BLK_GAP) && (vvn =3D=3D =
VENDOR_V_23);
> if (applicable) {
>=20
> esdhc_reset(host, SDHCI_RESET_DATA);
> @@ -318,10 +317,9 @@ static void esdhc_of_resume(struct sdhci_host =
*host)
>=20
> static void esdhc_of_platform_init(struct sdhci_host *host)
> {
> - u32 vvn;
> + svr =3D mfspr(SPRN_SVR);
> + vvn =3D esdhc_readw(host, SDHCI_HOST_VERSION);
>=20
> - vvn =3D in_be32(host->ioaddr + SDHCI_SLOT_INT_STATUS);
> - vvn =3D (vvn & SDHCI_VENDOR_VER_MASK) >> SDHCI_VENDOR_VER_SHIFT;
> if (vvn =3D=3D VENDOR_V_22)
> host->quirks2 |=3D SDHCI_QUIRK2_HOST_NO_CMD23;
>=20
> @@ -390,7 +388,6 @@ static int sdhci_esdhc_probe(struct =
platform_device *pdev)
> struct device_node *np;
> int ret;
>=20
> - svr =3D mfspr(SPRN_SVR);
> host =3D sdhci_pltfm_init(pdev, &sdhci_esdhc_pdata, 0);
> if (IS_ERR(host))
> return PTR_ERR(host);
> --=20
> 1.8.0
>=20
>=20
> _______________________________________________
> Linuxppc-dev mailing list
> Linuxppc-dev@lists.ozlabs.org
> https://lists.ozlabs.org/listinfo/linuxppc-dev
^ permalink raw reply
* Re: [PATCH v3 01/31] spi: mpc512x: cleanup clock API use
From: Mark Brown @ 2013-07-22 14:09 UTC (permalink / raw)
To: Gerhard Sittig
Cc: Mike Turquette, Detlev Zundel, Wolfram Sang, David Woodhouse,
devicetree-discuss, Greg Kroah-Hartman, Rob Herring,
Marc Kleine-Budde, Wolfgang Grandegger, Anatolij Gustschin,
linuxppc-dev, linux-arm-kernel, Mauro Carvalho Chehab
In-Reply-To: <1374495298-22019-2-git-send-email-gsi@denx.de>
[-- Attachment #1: Type: text/plain, Size: 278 bytes --]
On Mon, Jul 22, 2013 at 02:14:28PM +0200, Gerhard Sittig wrote:
> + ret = clk_prepare_enable(clk);
> + if (ret) {
> + devm_clk_put(dev, clk);
> + goto free_irq;
The main point of the devm_ APIs is to avoid the need for explicit
freeing so you should just remove these puts.
[-- Attachment #2: Digital signature --]
[-- Type: application/pgp-signature, Size: 836 bytes --]
^ permalink raw reply
* Re: [PATCH v3 27/31] net: can: mscan: add common clock support for mpc512x
From: Marc Kleine-Budde @ 2013-07-22 13:04 UTC (permalink / raw)
To: Gerhard Sittig
Cc: Mike Turquette, Detlev Zundel, Wolfram Sang, David Woodhouse,
devicetree-discuss, Greg Kroah-Hartman, Rob Herring, Mark Brown,
Wolfgang Grandegger, Anatolij Gustschin, linuxppc-dev,
linux-arm-kernel, Mauro Carvalho Chehab
In-Reply-To: <1374495298-22019-28-git-send-email-gsi@denx.de>
[-- Attachment #1: Type: text/plain, Size: 8266 bytes --]
On 07/22/2013 02:14 PM, Gerhard Sittig wrote:
> implement a .get_clock() callback for the MPC512x platform which uses
> the common clock infrastructure (eliminating direct access to the clock
> control registers from within the CAN network driver), and provide the
> corresponding .put_clock() callback to release resources after use
>
> keep the previous implementation of MPC512x support in place during
> migration, since common clock support is optional
>
> this change is neutral to the MPC5200 platform
>
> Signed-off-by: Gerhard Sittig <gsi@denx.de>
> ---
> drivers/net/can/mscan/mpc5xxx_can.c | 169 +++++++++++++++++++++++++++++++++++
> 1 file changed, 169 insertions(+)
>
> diff --git a/drivers/net/can/mscan/mpc5xxx_can.c b/drivers/net/can/mscan/mpc5xxx_can.c
> index e59b3a3..4897929 100644
> --- a/drivers/net/can/mscan/mpc5xxx_can.c
> +++ b/drivers/net/can/mscan/mpc5xxx_can.c
> @@ -109,6 +109,167 @@ static u32 mpc52xx_can_get_clock(struct platform_device *ofdev,
> #endif /* CONFIG_PPC_MPC52xx */
>
> #ifdef CONFIG_PPC_MPC512x
> +
> +#if IS_ENABLED(CONFIG_COMMON_CLK)
> +
> +static u32 mpc512x_can_get_clock(struct platform_device *ofdev,
> + const char *clock_source, int *mscan_clksrc)
> +{
> + struct device_node *np;
> + u32 clockdiv;
> + enum {
> + CLK_FROM_AUTO,
> + CLK_FROM_IPS,
> + CLK_FROM_SYS,
> + CLK_FROM_REF,
> + } clk_from;
> + struct clk *clk_in, *clk_can;
> + unsigned long freq_calc;
> + struct mscan_priv *priv;
> +
> + /* the caller passed in the clock source spec that was read from
> + * the device tree, get the optional clock divider as well
> + */
> + np = ofdev->dev.of_node;
> + clockdiv = 1;
> + of_property_read_u32(np, "fsl,mscan-clock-divider", &clockdiv);
> + dev_dbg(&ofdev->dev, "device tree specs: clk src[%s] div[%d]\n",
> + clock_source ? clock_source : "<NULL>", clockdiv);
> +
> + /* when clock-source is 'ip', the CANCTL1[CLKSRC] bit needs to
> + * get set, and the 'ips' clock is the input to the MSCAN
> + * component
> + *
> + * for clock-source values of 'ref' or 'sys' the CANCTL1[CLKSRC]
> + * bit needs to get cleared, an optional clock-divider may have
> + * been specified (the default value is 1), the appropriate
> + * MSCAN related MCLK is the input to the MSCAN component
> + *
> + * in the absence of a clock-source spec, first an optimal clock
> + * gets determined based on the 'sys' clock, if that fails the
> + * 'ref' clock is used
> + */
> + clk_from = CLK_FROM_AUTO;
> + if (clock_source) {
> + /* interpret the device tree's spec for the clock source */
> + if (!strcmp(clock_source, "ip"))
> + clk_from = CLK_FROM_IPS;
> + else if (!strcmp(clock_source, "sys"))
> + clk_from = CLK_FROM_SYS;
> + else if (!strcmp(clock_source, "ref"))
> + clk_from = CLK_FROM_REF;
> + else
> + goto err_invalid;
> + dev_dbg(&ofdev->dev, "got a clk source spec[%d]\n", clk_from);
> + }
> + if (clk_from == CLK_FROM_AUTO) {
> + /* no spec so far, try the 'sys' clock; round to the
> + * next MHz and see if we can get a multiple of 16MHz
> + */
> + dev_dbg(&ofdev->dev, "no clk source spec, trying SYS\n");
> + clk_in = devm_clk_get(&ofdev->dev, "sys");
> + if (IS_ERR(clk_in))
> + goto err_notavail;
> + freq_calc = clk_get_rate(clk_in);
> + freq_calc += 499999;
> + freq_calc /= 1000000;
> + freq_calc *= 1000000;
> + if ((freq_calc % 16000000) == 0) {
> + clk_from = CLK_FROM_SYS;
> + clockdiv = freq_calc / 16000000;
> + dev_dbg(&ofdev->dev,
> + "clk fit, sys[%lu] div[%d] freq[%lu]\n",
> + freq_calc, clockdiv, freq_calc / clockdiv);
> + }
> + }
> + if (clk_from == CLK_FROM_AUTO) {
> + /* no spec so far, use the 'ref' clock */
> + dev_dbg(&ofdev->dev, "no clk source spec, trying REF\n");
> + clk_in = devm_clk_get(&ofdev->dev, "ref");
> + if (IS_ERR(clk_in))
> + goto err_notavail;
> + clk_from = CLK_FROM_REF;
> + freq_calc = clk_get_rate(clk_in);
> + dev_dbg(&ofdev->dev,
> + "clk fit, ref[%lu] (no div) freq[%lu]\n",
> + freq_calc, freq_calc);
> + }
> +
> + /* select IPS or MCLK as the MSCAN input (returned to the caller),
> + * setup the MCLK mux source and rate if applicable, apply the
> + * optionally specified or derived above divider, and determine
> + * the actual resulting clock rate to return to the caller
> + */
> + switch (clk_from) {
> + case CLK_FROM_IPS:
> + clk_can = devm_clk_get(&ofdev->dev, "ips");
> + if (IS_ERR(clk_can))
> + goto err_notavail;
> + if (clk_prepare(clk_can)) {
I would just call prepare_enable in the main mscan driver, then we don't
need a special "clock is prepared but not enabled" contract.
> + devm_clk_put(&ofdev->dev, clk_can);
not needed, as this driver instance will fail, doesn't it?
> + goto err_notavail;
> + }
> + priv = netdev_priv(dev_get_drvdata(&ofdev->dev));
> + priv->clk_can = clk_can;
> + freq_calc = clk_get_rate(clk_can);
> + *mscan_clksrc = MSCAN_CLKSRC_IPS;
> + dev_dbg(&ofdev->dev, "clk from IPS, clksrc[%d] freq[%lu]\n",
> + *mscan_clksrc, freq_calc);
> + break;
> + case CLK_FROM_SYS:
> + case CLK_FROM_REF:
> + clk_can = devm_clk_get(&ofdev->dev, "mclk");
> + if (IS_ERR(clk_can))
> + goto err_notavail;
> + if (clk_prepare(clk_can)) {
> + devm_clk_put(&ofdev->dev, clk_can);
same here
> + goto err_notavail;
> + }
> + priv = netdev_priv(dev_get_drvdata(&ofdev->dev));
> + priv->clk_can = clk_can;
> + if (clk_from == CLK_FROM_SYS)
> + clk_in = devm_clk_get(&ofdev->dev, "sys");
> + if (clk_from == CLK_FROM_REF)
> + clk_in = devm_clk_get(&ofdev->dev, "ref");
> + if (IS_ERR(clk_in))
> + goto err_notavail;
> + clk_set_parent(clk_can, clk_in);
> + freq_calc = clk_get_rate(clk_in);
> + freq_calc /= clockdiv;
> + clk_set_rate(clk_can, freq_calc);
> + freq_calc = clk_get_rate(clk_can);
> + *mscan_clksrc = MSCAN_CLKSRC_BUS;
> + dev_dbg(&ofdev->dev, "clk from MCLK, clksrc[%d] freq[%lu]\n",
> + *mscan_clksrc, freq_calc);
> + break;
> + default:
> + goto err_invalid;
> + }
> +
> + return freq_calc;
> +
> +err_invalid:
> + dev_err(&ofdev->dev, "invalid clock source specification\n");
> + return 0;
return 0 in case of error? Please add a comment what this 0 means here.
> +
> +err_notavail:
> + dev_err(&ofdev->dev, "cannot acquire or setup clock source\n");
> + return 0;
> +}
> +
> +static void mpc512x_can_put_clock(struct platform_device *ofdev)
> +{
> + struct mscan_priv *priv;
> +
> + priv = netdev_priv(dev_get_drvdata(&ofdev->dev));
> + if (priv->clk_can) {
> + clk_unprepare(priv->clk_can);
> + devm_clk_put(&ofdev->dev, priv->clk_can);
devm_clk_put can be removed, it's called automatically.
> + }
> +}
> +
> +#else /* COMMON_CLK */
> +
> struct mpc512x_clockctl {
> u32 spmr; /* System PLL Mode Reg */
> u32 sccr[2]; /* System Clk Ctrl Reg 1 & 2 */
> @@ -239,12 +400,18 @@ exit_put:
> of_node_put(np_clock);
> return freq;
> }
> +
> +#define mpc512x_can_put_clock NULL
> +
> +#endif /* COMMON_CLK */
> +
> #else /* !CONFIG_PPC_MPC512x */
> static u32 mpc512x_can_get_clock(struct platform_device *ofdev,
> const char *clock_name, int *mscan_clksrc)
> {
> return 0;
> }
> +#define mpc512x_can_put_clock NULL
> #endif /* CONFIG_PPC_MPC512x */
>
> static const struct of_device_id mpc5xxx_can_table[];
> @@ -386,11 +553,13 @@ static int mpc5xxx_can_resume(struct platform_device *ofdev)
> static const struct mpc5xxx_can_data mpc5200_can_data = {
> .type = MSCAN_TYPE_MPC5200,
> .get_clock = mpc52xx_can_get_clock,
> + /* .put_clock not applicable */
> };
>
> static const struct mpc5xxx_can_data mpc5121_can_data = {
> .type = MSCAN_TYPE_MPC5121,
> .get_clock = mpc512x_can_get_clock,
> + .put_clock = mpc512x_can_put_clock,
> };
>
> static const struct of_device_id mpc5xxx_can_table[] = {
>
Marc
--
Pengutronix e.K. | Marc Kleine-Budde |
Industrial Linux Solutions | Phone: +49-231-2826-924 |
Vertretung West/Dortmund | Fax: +49-5121-206917-5555 |
Amtsgericht Hildesheim, HRA 2686 | http://www.pengutronix.de |
[-- Attachment #2: OpenPGP digital signature --]
[-- Type: application/pgp-signature, Size: 259 bytes --]
^ permalink raw reply
* Re: [PATCH v3 00/31] add COMMON_CLK support for PowerPC MPC512x
From: Gerhard Sittig @ 2013-07-22 12:33 UTC (permalink / raw)
To: linuxppc-dev, Anatolij Gustschin, Mike Turquette,
linux-arm-kernel, devicetree
Cc: Detlev Zundel, Wolfram Sang, Greg Kroah-Hartman, Rob Herring,
Mark Brown, Marc Kleine-Budde, David Woodhouse,
Wolfgang Grandegger, Mauro Carvalho Chehab
In-Reply-To: <1374495298-22019-1-git-send-email-gsi@denx.de>
[ manually added devicetree at vger now ]
On Mon, Jul 22, 2013 at 14:14 +0200, Gerhard Sittig wrote:
>
> this series
> - fixes several drivers that are used in the MPC512x platform (UART,
> SPI, ethernet, PCI, USB, CAN, NAND flash, video capture) in how they
> handle clocks (appropriately acquire and setup them, hold references
> during use, release clocks after use)
> - introduces support for the common clock framework (CCF, COMMON_CLK
> Kconfig option) in the PowerPC based MPC512x platform, which brings
> device tree based clock lookup as well
Haven't noticed before that the ozlabs device tree list started
actively rejecting reception. And the scope of the series has
widened to include clock related fixes in many more drivers while
the initial submission only introduced CCF for MPC512x.
Shall I resend (with vger devicetree included and more subsystems
lists added)? Which other lists to include without spamming too
many channels? Poor moderators have to ACK messages for lists
that I'm not subscribed to.
virtually yours
Gerhard Sittig
--
DENX Software Engineering GmbH, MD: Wolfgang Denk & Detlev Zundel
HRB 165235 Munich, Office: Kirchenstr. 5, D-82194 Groebenzell, Germany
Phone: +49-8142-66989-0 Fax: +49-8142-66989-80 Email: office@denx.de
^ permalink raw reply
* Re: [PATCH v3 11/31] net: can: mscan: improve clock API use
From: Marc Kleine-Budde @ 2013-07-22 12:31 UTC (permalink / raw)
To: Gerhard Sittig
Cc: Mike Turquette, Detlev Zundel, Wolfram Sang, David Woodhouse,
devicetree-discuss, Greg Kroah-Hartman, Rob Herring, Mark Brown,
Wolfgang Grandegger, Anatolij Gustschin, linuxppc-dev,
linux-arm-kernel, Mauro Carvalho Chehab
In-Reply-To: <1374495298-22019-12-git-send-email-gsi@denx.de>
[-- Attachment #1: Type: text/plain, Size: 944 bytes --]
On 07/22/2013 02:14 PM, Gerhard Sittig wrote:
> the .get_clock() callback is run from probe() and might allocate
> resources, introduce a .put_clock() callback that is run from remove()
> to undo any allocation activities
looks good
> use devm_get_clk() upon lookup (for SYS and REF) to have the clocks put
> upon driver unload
fine
> assume that resources get prepared but not necessarily enabled in the
> setup phase, make the open() and close() callbacks of the CAN network
> device enable and disable a previously acquired and prepared clock
I think you should call prepare_enable and disable_unprepare in the
open/close functions.
Marc
--
Pengutronix e.K. | Marc Kleine-Budde |
Industrial Linux Solutions | Phone: +49-231-2826-924 |
Vertretung West/Dortmund | Fax: +49-5121-206917-5555 |
Amtsgericht Hildesheim, HRA 2686 | http://www.pengutronix.de |
[-- Attachment #2: OpenPGP digital signature --]
[-- Type: application/pgp-signature, Size: 259 bytes --]
^ permalink raw reply
* Re: [PATCH v3 08/31] fs_enet: cleanup clock API use
From: Marc Kleine-Budde @ 2013-07-22 12:28 UTC (permalink / raw)
To: Gerhard Sittig
Cc: Mike Turquette, Detlev Zundel, Wolfram Sang, David Woodhouse,
devicetree-discuss, Greg Kroah-Hartman, Rob Herring, Mark Brown,
Wolfgang Grandegger, Anatolij Gustschin, linuxppc-dev,
linux-arm-kernel, Mauro Carvalho Chehab
In-Reply-To: <1374495298-22019-9-git-send-email-gsi@denx.de>
[-- Attachment #1: Type: text/plain, Size: 629 bytes --]
On 07/22/2013 02:14 PM, Gerhard Sittig wrote:
> make the Freescale ethernet driver get, prepare and enable the FEC clock
> during probe(); disable, unprepare and put the clock upon remove(); hold
> a reference to the clock over the period of use; use devm_{get,put}_clk()
There's no need for devm_clk_put(), devm will take care of this.
Marc
--
Pengutronix e.K. | Marc Kleine-Budde |
Industrial Linux Solutions | Phone: +49-231-2826-924 |
Vertretung West/Dortmund | Fax: +49-5121-206917-5555 |
Amtsgericht Hildesheim, HRA 2686 | http://www.pengutronix.de |
[-- Attachment #2: OpenPGP digital signature --]
[-- Type: application/pgp-signature, Size: 259 bytes --]
^ permalink raw reply
* [PATCH v3 31/31] clk: mpc512x: remove clkdev registration (sys/ref, header)
From: Gerhard Sittig @ 2013-07-22 12:14 UTC (permalink / raw)
To: linuxppc-dev, Anatolij Gustschin, Mike Turquette,
linux-arm-kernel, devicetree-discuss
Cc: Detlev Zundel, Wolfram Sang, Greg Kroah-Hartman, Gerhard Sittig,
Rob Herring, Mark Brown, Marc Kleine-Budde, David Woodhouse,
Wolfgang Grandegger, Mauro Carvalho Chehab
In-Reply-To: <1374495298-22019-1-git-send-email-gsi@denx.de>
remove the last clkdev registration call ("sys_clk" and "ref_clk"
for mscan), as well as the clkdev header inclusion and the "compat
registration" comment
all client lookups for clock items are device tree based now, no
compatibility alias names need to get provided any longer
Signed-off-by: Gerhard Sittig <gsi@denx.de>
---
arch/powerpc/platforms/512x/clock-commonclk.c | 5 -----
1 file changed, 5 deletions(-)
diff --git a/arch/powerpc/platforms/512x/clock-commonclk.c b/arch/powerpc/platforms/512x/clock-commonclk.c
index 893fbe5..e9451a7 100644
--- a/arch/powerpc/platforms/512x/clock-commonclk.c
+++ b/arch/powerpc/platforms/512x/clock-commonclk.c
@@ -12,7 +12,6 @@
*/
#include <linux/clk-provider.h>
-#include <linux/clkdev.h>
#include <linux/device.h>
#include <linux/errno.h>
#include <linux/io.h>
@@ -673,10 +672,6 @@ static void mpc512x_clk_setup_clock_tree(int busfreq)
/* fixed frequency for AC97, always 24.567MHz */
clks[MPC512x_CLK_AC97] = mpc512x_clk_fixed("ac97", 24567000);
- /* clkdev registration for compatibility reasons */
- clk_register_clkdev(clks[MPC512x_CLK_REF], "ref_clk", NULL);
- clk_register_clkdev(clks[MPC512x_CLK_SYS], "sys_clk", NULL);
-
pr_debug("clock tree setup complete\n");
freq = clk_get_rate(clks[MPC512x_CLK_E300]);
pr_debug("derived PPC freq [%d]\n", freq);
--
1.7.10.4
^ permalink raw reply related
* [PATCH v3 30/31] net: can: mscan: remove non-common_clock code for MPC512x
From: Gerhard Sittig @ 2013-07-22 12:14 UTC (permalink / raw)
To: linuxppc-dev, Anatolij Gustschin, Mike Turquette,
linux-arm-kernel, devicetree-discuss
Cc: Detlev Zundel, Wolfram Sang, Greg Kroah-Hartman, Gerhard Sittig,
Rob Herring, Mark Brown, Marc Kleine-Budde, David Woodhouse,
Wolfgang Grandegger, Mauro Carvalho Chehab
In-Reply-To: <1374495298-22019-1-git-send-email-gsi@denx.de>
transition to the common clock framework has completed and the PPC_CLOCK
is no longer available for the MPC512x platform, remove the now obsolete
code path of the mpc5xxx mscan driver which accessed clock control
module registers directly
Signed-off-by: Gerhard Sittig <gsi@denx.de>
---
drivers/net/can/mscan/mpc5xxx_can.c | 141 -----------------------------------
1 file changed, 141 deletions(-)
diff --git a/drivers/net/can/mscan/mpc5xxx_can.c b/drivers/net/can/mscan/mpc5xxx_can.c
index 4897929..dd6bdaa 100644
--- a/drivers/net/can/mscan/mpc5xxx_can.c
+++ b/drivers/net/can/mscan/mpc5xxx_can.c
@@ -109,9 +109,6 @@ static u32 mpc52xx_can_get_clock(struct platform_device *ofdev,
#endif /* CONFIG_PPC_MPC52xx */
#ifdef CONFIG_PPC_MPC512x
-
-#if IS_ENABLED(CONFIG_COMMON_CLK)
-
static u32 mpc512x_can_get_clock(struct platform_device *ofdev,
const char *clock_source, int *mscan_clksrc)
{
@@ -267,144 +264,6 @@ static void mpc512x_can_put_clock(struct platform_device *ofdev)
devm_clk_put(&ofdev->dev, priv->clk_can);
}
}
-
-#else /* COMMON_CLK */
-
-struct mpc512x_clockctl {
- u32 spmr; /* System PLL Mode Reg */
- u32 sccr[2]; /* System Clk Ctrl Reg 1 & 2 */
- u32 scfr1; /* System Clk Freq Reg 1 */
- u32 scfr2; /* System Clk Freq Reg 2 */
- u32 reserved;
- u32 bcr; /* Bread Crumb Reg */
- u32 pccr[12]; /* PSC Clk Ctrl Reg 0-11 */
- u32 spccr; /* SPDIF Clk Ctrl Reg */
- u32 cccr; /* CFM Clk Ctrl Reg */
- u32 dccr; /* DIU Clk Cnfg Reg */
- u32 mccr[4]; /* MSCAN Clk Ctrl Reg 1-3 */
-};
-
-static struct of_device_id mpc512x_clock_ids[] = {
- { .compatible = "fsl,mpc5121-clock", },
- {}
-};
-
-static u32 mpc512x_can_get_clock(struct platform_device *ofdev,
- const char *clock_name, int *mscan_clksrc)
-{
- struct mpc512x_clockctl __iomem *clockctl;
- struct device_node *np_clock;
- struct clk *sys_clk, *ref_clk;
- int plen, clockidx, clocksrc = -1;
- u32 sys_freq, val, clockdiv = 1, freq = 0;
- const u32 *pval;
-
- np_clock = of_find_matching_node(NULL, mpc512x_clock_ids);
- if (!np_clock) {
- dev_err(&ofdev->dev, "couldn't find clock node\n");
- return 0;
- }
- clockctl = of_iomap(np_clock, 0);
- if (!clockctl) {
- dev_err(&ofdev->dev, "couldn't map clock registers\n");
- goto exit_put;
- }
-
- /* Determine the MSCAN device index from the peripheral's
- * physical address. Register address offsets against the
- * IMMR base are: 0x1300, 0x1380, 0x2300, 0x2380
- */
- pval = of_get_property(ofdev->dev.of_node, "reg", &plen);
- BUG_ON(!pval || plen < sizeof(*pval));
- clockidx = (*pval & 0x80) ? 1 : 0;
- if (*pval & 0x2000)
- clockidx += 2;
-
- /*
- * Clock source and divider selection: 3 different clock sources
- * can be selected: "ip", "ref" or "sys". For the latter two, a
- * clock divider can be defined as well. If the clock source is
- * not specified by the device tree, we first try to find an
- * optimal CAN source clock based on the system clock. If that
- * is not posslible, the reference clock will be used.
- */
- if (clock_name && !strcmp(clock_name, "ip")) {
- *mscan_clksrc = MSCAN_CLKSRC_IPS;
- freq = mpc5xxx_get_bus_frequency(ofdev->dev.of_node);
- } else {
- *mscan_clksrc = MSCAN_CLKSRC_BUS;
-
- pval = of_get_property(ofdev->dev.of_node,
- "fsl,mscan-clock-divider", &plen);
- if (pval && plen == sizeof(*pval))
- clockdiv = *pval;
- if (!clockdiv)
- clockdiv = 1;
-
- if (!clock_name || !strcmp(clock_name, "sys")) {
- sys_clk = devm_clk_get(&ofdev->dev, "sys_clk");
- if (IS_ERR(sys_clk)) {
- dev_err(&ofdev->dev, "couldn't get sys_clk\n");
- goto exit_unmap;
- }
- /* Get and round up/down sys clock rate */
- sys_freq = 1000000 *
- ((clk_get_rate(sys_clk) + 499999) / 1000000);
-
- if (!clock_name) {
- /* A multiple of 16 MHz would be optimal */
- if ((sys_freq % 16000000) == 0) {
- clocksrc = 0;
- clockdiv = sys_freq / 16000000;
- freq = sys_freq / clockdiv;
- }
- } else {
- clocksrc = 0;
- freq = sys_freq / clockdiv;
- }
- }
-
- if (clocksrc < 0) {
- ref_clk = devm_clk_get(&ofdev->dev, "ref_clk");
- if (IS_ERR(ref_clk)) {
- dev_err(&ofdev->dev, "couldn't get ref_clk\n");
- goto exit_unmap;
- }
- clocksrc = 1;
- freq = clk_get_rate(ref_clk) / clockdiv;
- }
- }
-
- /* Disable clock */
- out_be32(&clockctl->mccr[clockidx], 0x0);
- if (clocksrc >= 0) {
- /* Set source and divider */
- val = (clocksrc << 14) | ((clockdiv - 1) << 17);
- out_be32(&clockctl->mccr[clockidx], val);
- /* Enable clock */
- out_be32(&clockctl->mccr[clockidx], val | 0x10000);
- }
-
- /* Enable MSCAN clock domain */
- val = in_be32(&clockctl->sccr[1]);
- if (!(val & (1 << 25)))
- out_be32(&clockctl->sccr[1], val | (1 << 25));
-
- dev_dbg(&ofdev->dev, "using '%s' with frequency divider %d\n",
- *mscan_clksrc == MSCAN_CLKSRC_IPS ? "ips_clk" :
- clocksrc == 1 ? "ref_clk" : "sys_clk", clockdiv);
-
-exit_unmap:
- iounmap(clockctl);
-exit_put:
- of_node_put(np_clock);
- return freq;
-}
-
-#define mpc512x_can_put_clock NULL
-
-#endif /* COMMON_CLK */
-
#else /* !CONFIG_PPC_MPC512x */
static u32 mpc512x_can_get_clock(struct platform_device *ofdev,
const char *clock_name, int *mscan_clksrc)
--
1.7.10.4
^ permalink raw reply related
* [PATCH v3 29/31] clk: mpc512x: switch to COMMON_CLK, remove PPC_CLOCK
From: Gerhard Sittig @ 2013-07-22 12:14 UTC (permalink / raw)
To: linuxppc-dev, Anatolij Gustschin, Mike Turquette,
linux-arm-kernel, devicetree-discuss
Cc: Detlev Zundel, Wolfram Sang, Greg Kroah-Hartman, Gerhard Sittig,
Rob Herring, Mark Brown, Marc Kleine-Budde, David Woodhouse,
Wolfgang Grandegger, Mauro Carvalho Chehab
In-Reply-To: <1374495298-22019-1-git-send-email-gsi@denx.de>
completely switch to, i.e. unconditionally use COMMON_CLK for the
MPC512x platform, and retire the PPC_CLOCK implementation for that
platform after the transition has completed
Signed-off-by: Gerhard Sittig <gsi@denx.de>
---
arch/powerpc/platforms/512x/Kconfig | 14 +-
arch/powerpc/platforms/512x/Makefile | 3 +-
arch/powerpc/platforms/512x/clock.c | 753 ----------------------------------
3 files changed, 2 insertions(+), 768 deletions(-)
delete mode 100644 arch/powerpc/platforms/512x/clock.c
diff --git a/arch/powerpc/platforms/512x/Kconfig b/arch/powerpc/platforms/512x/Kconfig
index c5fcdd0..5aa3f4b 100644
--- a/arch/powerpc/platforms/512x/Kconfig
+++ b/arch/powerpc/platforms/512x/Kconfig
@@ -1,21 +1,9 @@
-config MPC512x_COMMON_CLK
- bool "MPC512x platform uses COMMON_CLK"
- default y
- depends on PPC_MPC512x
- help
- This option is only here to support tests and comparison
- during development and migration. This option will get
- removed after the COMMON_CLK support for MPC512x has become
- fully operational and all drivers were adjusted to explicitly
- acquire their required clocks.
-
config PPC_MPC512x
bool "512x-based boards"
depends on 6xx
+ select COMMON_CLK
select FSL_SOC
select IPIC
- select PPC_CLOCK if !MPC512x_COMMON_CLK
- select COMMON_CLK if MPC512x_COMMON_CLK
select PPC_PCI_CHOICE
select FSL_PCI if PCI
select ARCH_WANT_OPTIONAL_GPIOLIB
diff --git a/arch/powerpc/platforms/512x/Makefile b/arch/powerpc/platforms/512x/Makefile
index 1e05f9d..bb20116 100644
--- a/arch/powerpc/platforms/512x/Makefile
+++ b/arch/powerpc/platforms/512x/Makefile
@@ -1,8 +1,7 @@
#
# Makefile for the Freescale PowerPC 512x linux kernel.
#
-obj-$(CONFIG_PPC_CLOCK) += clock.o
-obj-$(CONFIG_COMMON_CLK) += clock-commonclk.o
+obj-y += clock-commonclk.o
obj-y += mpc512x_shared.o
obj-$(CONFIG_MPC5121_ADS) += mpc5121_ads.o mpc5121_ads_cpld.o
obj-$(CONFIG_MPC512x_GENERIC) += mpc512x_generic.o
diff --git a/arch/powerpc/platforms/512x/clock.c b/arch/powerpc/platforms/512x/clock.c
deleted file mode 100644
index e504166..0000000
--- a/arch/powerpc/platforms/512x/clock.c
+++ /dev/null
@@ -1,753 +0,0 @@
-/*
- * Copyright (C) 2007,2008 Freescale Semiconductor, Inc. All rights reserved.
- *
- * Author: John Rigby <jrigby@freescale.com>
- *
- * Implements the clk api defined in include/linux/clk.h
- *
- * Original based on linux/arch/arm/mach-integrator/clock.c
- *
- * Copyright (C) 2004 ARM Limited.
- * Written by Deep Blue Solutions Limited.
- *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License version 2 as
- * published by the Free Software Foundation.
- */
-#include <linux/kernel.h>
-#include <linux/list.h>
-#include <linux/errno.h>
-#include <linux/err.h>
-#include <linux/module.h>
-#include <linux/string.h>
-#include <linux/clk.h>
-#include <linux/mutex.h>
-#include <linux/io.h>
-
-#include <linux/of_platform.h>
-#include <asm/mpc5xxx.h>
-#include <asm/mpc5121.h>
-#include <asm/clk_interface.h>
-
-#include "mpc512x.h"
-
-#undef CLK_DEBUG
-
-static int clocks_initialized;
-
-#define CLK_HAS_RATE 0x1 /* has rate in MHz */
-#define CLK_HAS_CTRL 0x2 /* has control reg and bit */
-
-struct clk {
- struct list_head node;
- char name[32];
- int flags;
- struct device *dev;
- unsigned long rate;
- struct module *owner;
- void (*calc) (struct clk *);
- struct clk *parent;
- int reg, bit; /* CLK_HAS_CTRL */
- int div_shift; /* only used by generic_div_clk_calc */
-};
-
-static LIST_HEAD(clocks);
-static DEFINE_MUTEX(clocks_mutex);
-
-static struct clk *mpc5121_clk_get(struct device *dev, const char *id)
-{
- struct clk *p, *clk = ERR_PTR(-ENOENT);
- int dev_match;
- int id_match;
-
- if (dev == NULL || id == NULL)
- return clk;
-
- mutex_lock(&clocks_mutex);
- list_for_each_entry(p, &clocks, node) {
- dev_match = id_match = 0;
-
- if (dev == p->dev)
- dev_match++;
- if (strcmp(id, p->name) == 0)
- id_match++;
- if ((dev_match || id_match) && try_module_get(p->owner)) {
- clk = p;
- break;
- }
- }
- mutex_unlock(&clocks_mutex);
-
- return clk;
-}
-
-#ifdef CLK_DEBUG
-static void dump_clocks(void)
-{
- struct clk *p;
-
- mutex_lock(&clocks_mutex);
- printk(KERN_INFO "CLOCKS:\n");
- list_for_each_entry(p, &clocks, node) {
- pr_info(" %s=%ld", p->name, p->rate);
- if (p->parent)
- pr_cont(" %s=%ld", p->parent->name,
- p->parent->rate);
- if (p->flags & CLK_HAS_CTRL)
- pr_cont(" reg/bit=%d/%d", p->reg, p->bit);
- pr_cont("\n");
- }
- mutex_unlock(&clocks_mutex);
-}
-#define DEBUG_CLK_DUMP() dump_clocks()
-#else
-#define DEBUG_CLK_DUMP()
-#endif
-
-
-static void mpc5121_clk_put(struct clk *clk)
-{
- module_put(clk->owner);
-}
-
-#define NRPSC 12
-
-struct mpc512x_clockctl {
- u32 spmr; /* System PLL Mode Reg */
- u32 sccr[2]; /* System Clk Ctrl Reg 1 & 2 */
- u32 scfr1; /* System Clk Freq Reg 1 */
- u32 scfr2; /* System Clk Freq Reg 2 */
- u32 reserved;
- u32 bcr; /* Bread Crumb Reg */
- u32 pccr[NRPSC]; /* PSC Clk Ctrl Reg 0-11 */
- u32 spccr; /* SPDIF Clk Ctrl Reg */
- u32 cccr; /* CFM Clk Ctrl Reg */
- u32 dccr; /* DIU Clk Cnfg Reg */
-};
-
-static struct mpc512x_clockctl __iomem *clockctl;
-
-static int mpc5121_clk_enable(struct clk *clk)
-{
- unsigned int mask;
-
- if (clk->flags & CLK_HAS_CTRL) {
- mask = in_be32(&clockctl->sccr[clk->reg]);
- mask |= 1 << clk->bit;
- out_be32(&clockctl->sccr[clk->reg], mask);
- }
- return 0;
-}
-
-static void mpc5121_clk_disable(struct clk *clk)
-{
- unsigned int mask;
-
- if (clk->flags & CLK_HAS_CTRL) {
- mask = in_be32(&clockctl->sccr[clk->reg]);
- mask &= ~(1 << clk->bit);
- out_be32(&clockctl->sccr[clk->reg], mask);
- }
-}
-
-static unsigned long mpc5121_clk_get_rate(struct clk *clk)
-{
- if (clk->flags & CLK_HAS_RATE)
- return clk->rate;
- else
- return 0;
-}
-
-static long mpc5121_clk_round_rate(struct clk *clk, unsigned long rate)
-{
- return rate;
-}
-
-static int mpc5121_clk_set_rate(struct clk *clk, unsigned long rate)
-{
- return 0;
-}
-
-static int clk_register(struct clk *clk)
-{
- mutex_lock(&clocks_mutex);
- list_add(&clk->node, &clocks);
- mutex_unlock(&clocks_mutex);
- return 0;
-}
-
-static unsigned long spmf_mult(void)
-{
- /*
- * Convert spmf to multiplier
- */
- static int spmf_to_mult[] = {
- 68, 1, 12, 16,
- 20, 24, 28, 32,
- 36, 40, 44, 48,
- 52, 56, 60, 64
- };
- int spmf = (in_be32(&clockctl->spmr) >> 24) & 0xf;
- return spmf_to_mult[spmf];
-}
-
-static unsigned long sysdiv_div_x_2(void)
-{
- /*
- * Convert sysdiv to divisor x 2
- * Some divisors have fractional parts so
- * multiply by 2 then divide by this value
- */
- static int sysdiv_to_div_x_2[] = {
- 4, 5, 6, 7,
- 8, 9, 10, 14,
- 12, 16, 18, 22,
- 20, 24, 26, 30,
- 28, 32, 34, 38,
- 36, 40, 42, 46,
- 44, 48, 50, 54,
- 52, 56, 58, 62,
- 60, 64, 66,
- };
- int sysdiv = (in_be32(&clockctl->scfr2) >> 26) & 0x3f;
- return sysdiv_to_div_x_2[sysdiv];
-}
-
-static unsigned long ref_to_sys(unsigned long rate)
-{
- rate *= spmf_mult();
- rate *= 2;
- rate /= sysdiv_div_x_2();
-
- return rate;
-}
-
-static unsigned long sys_to_ref(unsigned long rate)
-{
- rate *= sysdiv_div_x_2();
- rate /= 2;
- rate /= spmf_mult();
-
- return rate;
-}
-
-static long ips_to_ref(unsigned long rate)
-{
- int ips_div = (in_be32(&clockctl->scfr1) >> 23) & 0x7;
-
- rate *= ips_div; /* csb_clk = ips_clk * ips_div */
- rate *= 2; /* sys_clk = csb_clk * 2 */
- return sys_to_ref(rate);
-}
-
-static unsigned long devtree_getfreq(char *clockname)
-{
- struct device_node *np;
- const unsigned int *prop;
- unsigned int val = 0;
-
- np = of_find_compatible_node(NULL, NULL, "fsl,mpc5121-immr");
- if (np) {
- prop = of_get_property(np, clockname, NULL);
- if (prop)
- val = *prop;
- of_node_put(np);
- }
- return val;
-}
-
-static void ref_clk_calc(struct clk *clk)
-{
- unsigned long rate;
-
- rate = devtree_getfreq("bus-frequency");
- if (rate == 0) {
- printk(KERN_ERR "No bus-frequency in dev tree\n");
- clk->rate = 0;
- return;
- }
- clk->rate = ips_to_ref(rate);
-}
-
-static struct clk ref_clk = {
- .name = "ref_clk",
- .calc = ref_clk_calc,
-};
-
-
-static void sys_clk_calc(struct clk *clk)
-{
- clk->rate = ref_to_sys(ref_clk.rate);
-}
-
-static struct clk sys_clk = {
- .name = "sys_clk",
- .calc = sys_clk_calc,
-};
-
-static void diu_clk_calc(struct clk *clk)
-{
- int diudiv_x_2 = in_be32(&clockctl->scfr1) & 0xff;
- unsigned long rate;
-
- rate = sys_clk.rate;
-
- rate *= 2;
- rate /= diudiv_x_2;
-
- clk->rate = rate;
-}
-
-static void viu_clk_calc(struct clk *clk)
-{
- unsigned long rate;
-
- rate = sys_clk.rate;
- rate /= 2;
- clk->rate = rate;
-}
-
-static void half_clk_calc(struct clk *clk)
-{
- clk->rate = clk->parent->rate / 2;
-}
-
-static void generic_div_clk_calc(struct clk *clk)
-{
- int div = (in_be32(&clockctl->scfr1) >> clk->div_shift) & 0x7;
-
- clk->rate = clk->parent->rate / div;
-}
-
-static void unity_clk_calc(struct clk *clk)
-{
- clk->rate = clk->parent->rate;
-}
-
-static struct clk csb_clk = {
- .name = "csb_clk",
- .calc = half_clk_calc,
- .parent = &sys_clk,
-};
-
-static void e300_clk_calc(struct clk *clk)
-{
- int spmf = (in_be32(&clockctl->spmr) >> 16) & 0xf;
- int ratex2 = clk->parent->rate * spmf;
-
- clk->rate = ratex2 / 2;
-}
-
-static struct clk e300_clk = {
- .name = "e300_clk",
- .calc = e300_clk_calc,
- .parent = &csb_clk,
-};
-
-static struct clk ips_clk = {
- .name = "ips_clk",
- .calc = generic_div_clk_calc,
- .parent = &csb_clk,
- .div_shift = 23,
-};
-
-/*
- * Clocks controlled by SCCR1 (.reg = 0)
- */
-static struct clk lpc_clk = {
- .name = "lpc_clk",
- .flags = CLK_HAS_CTRL,
- .reg = 0,
- .bit = 30,
- .calc = generic_div_clk_calc,
- .parent = &ips_clk,
- .div_shift = 11,
-};
-
-static struct clk nfc_clk = {
- .name = "nfc_clk",
- .flags = CLK_HAS_CTRL,
- .reg = 0,
- .bit = 29,
- .calc = generic_div_clk_calc,
- .parent = &ips_clk,
- .div_shift = 8,
-};
-
-static struct clk pata_clk = {
- .name = "pata_clk",
- .flags = CLK_HAS_CTRL,
- .reg = 0,
- .bit = 28,
- .calc = unity_clk_calc,
- .parent = &ips_clk,
-};
-
-/*
- * PSC clocks (bits 27 - 16)
- * are setup elsewhere
- */
-
-static struct clk sata_clk = {
- .name = "sata_clk",
- .flags = CLK_HAS_CTRL,
- .reg = 0,
- .bit = 14,
- .calc = unity_clk_calc,
- .parent = &ips_clk,
-};
-
-static struct clk fec_clk = {
- .name = "fec_clk",
- .flags = CLK_HAS_CTRL,
- .reg = 0,
- .bit = 13,
- .calc = unity_clk_calc,
- .parent = &ips_clk,
-};
-
-static struct clk pci_clk = {
- .name = "pci_clk",
- .flags = CLK_HAS_CTRL,
- .reg = 0,
- .bit = 11,
- .calc = generic_div_clk_calc,
- .parent = &csb_clk,
- .div_shift = 20,
-};
-
-/*
- * Clocks controlled by SCCR2 (.reg = 1)
- */
-static struct clk diu_clk = {
- .name = "diu_clk",
- .flags = CLK_HAS_CTRL,
- .reg = 1,
- .bit = 31,
- .calc = diu_clk_calc,
-};
-
-static struct clk viu_clk = {
- .name = "viu_clk",
- .flags = CLK_HAS_CTRL,
- .reg = 1,
- .bit = 18,
- .calc = viu_clk_calc,
-};
-
-static struct clk axe_clk = {
- .name = "axe_clk",
- .flags = CLK_HAS_CTRL,
- .reg = 1,
- .bit = 30,
- .calc = unity_clk_calc,
- .parent = &csb_clk,
-};
-
-static struct clk usb1_clk = {
- .name = "usb1_clk",
- .flags = CLK_HAS_CTRL,
- .reg = 1,
- .bit = 28,
- .calc = unity_clk_calc,
- .parent = &csb_clk,
-};
-
-static struct clk usb2_clk = {
- .name = "usb2_clk",
- .flags = CLK_HAS_CTRL,
- .reg = 1,
- .bit = 27,
- .calc = unity_clk_calc,
- .parent = &csb_clk,
-};
-
-static struct clk i2c_clk = {
- .name = "i2c_clk",
- .flags = CLK_HAS_CTRL,
- .reg = 1,
- .bit = 26,
- .calc = unity_clk_calc,
- .parent = &ips_clk,
-};
-
-static struct clk mscan_clk = {
- .name = "mscan_clk",
- .flags = CLK_HAS_CTRL,
- .reg = 1,
- .bit = 25,
- .calc = unity_clk_calc,
- .parent = &ips_clk,
-};
-
-static struct clk sdhc_clk = {
- .name = "sdhc_clk",
- .flags = CLK_HAS_CTRL,
- .reg = 1,
- .bit = 24,
- .calc = unity_clk_calc,
- .parent = &ips_clk,
-};
-
-static struct clk mbx_bus_clk = {
- .name = "mbx_bus_clk",
- .flags = CLK_HAS_CTRL,
- .reg = 1,
- .bit = 22,
- .calc = half_clk_calc,
- .parent = &csb_clk,
-};
-
-static struct clk mbx_clk = {
- .name = "mbx_clk",
- .flags = CLK_HAS_CTRL,
- .reg = 1,
- .bit = 21,
- .calc = unity_clk_calc,
- .parent = &csb_clk,
-};
-
-static struct clk mbx_3d_clk = {
- .name = "mbx_3d_clk",
- .flags = CLK_HAS_CTRL,
- .reg = 1,
- .bit = 20,
- .calc = generic_div_clk_calc,
- .parent = &mbx_bus_clk,
- .div_shift = 14,
-};
-
-static void psc_mclk_in_calc(struct clk *clk)
-{
- clk->rate = devtree_getfreq("psc_mclk_in");
- if (!clk->rate)
- clk->rate = 25000000;
-}
-
-static struct clk psc_mclk_in = {
- .name = "psc_mclk_in",
- .calc = psc_mclk_in_calc,
-};
-
-static struct clk spdif_txclk = {
- .name = "spdif_txclk",
- .flags = CLK_HAS_CTRL,
- .reg = 1,
- .bit = 23,
-};
-
-static struct clk spdif_rxclk = {
- .name = "spdif_rxclk",
- .flags = CLK_HAS_CTRL,
- .reg = 1,
- .bit = 23,
-};
-
-static void ac97_clk_calc(struct clk *clk)
-{
- /* ac97 bit clock is always 24.567 MHz */
- clk->rate = 24567000;
-}
-
-static struct clk ac97_clk = {
- .name = "ac97_clk_in",
- .calc = ac97_clk_calc,
-};
-
-static struct clk *rate_clks[] = {
- &ref_clk,
- &sys_clk,
- &diu_clk,
- &viu_clk,
- &csb_clk,
- &e300_clk,
- &ips_clk,
- &fec_clk,
- &sata_clk,
- &pata_clk,
- &nfc_clk,
- &lpc_clk,
- &mbx_bus_clk,
- &mbx_clk,
- &mbx_3d_clk,
- &axe_clk,
- &usb1_clk,
- &usb2_clk,
- &i2c_clk,
- &mscan_clk,
- &sdhc_clk,
- &pci_clk,
- &psc_mclk_in,
- &spdif_txclk,
- &spdif_rxclk,
- &ac97_clk,
- NULL
-};
-
-static void rate_clk_init(struct clk *clk)
-{
- if (clk->calc) {
- clk->calc(clk);
- clk->flags |= CLK_HAS_RATE;
- clk_register(clk);
- } else {
- printk(KERN_WARNING
- "Could not initialize clk %s without a calc routine\n",
- clk->name);
- }
-}
-
-static void rate_clks_init(void)
-{
- struct clk **cpp, *clk;
-
- cpp = rate_clks;
- while ((clk = *cpp++))
- rate_clk_init(clk);
-}
-
-/*
- * There are two clk enable registers with 32 enable bits each
- * psc clocks and device clocks are all stored in dev_clks
- */
-static struct clk dev_clks[2][32];
-
-/*
- * Given a psc number return the dev_clk
- * associated with it
- */
-static struct clk *psc_dev_clk(int pscnum)
-{
- int reg, bit;
- struct clk *clk;
-
- reg = 0;
- bit = 27 - pscnum;
-
- clk = &dev_clks[reg][bit];
- clk->reg = 0;
- clk->bit = bit;
- return clk;
-}
-
-/*
- * PSC clock rate calculation
- */
-static void psc_calc_rate(struct clk *clk, int pscnum, struct device_node *np)
-{
- unsigned long mclk_src = sys_clk.rate;
- unsigned long mclk_div;
-
- /*
- * Can only change value of mclk divider
- * when the divider is disabled.
- *
- * Zero is not a valid divider so minimum
- * divider is 1
- *
- * disable/set divider/enable
- */
- out_be32(&clockctl->pccr[pscnum], 0);
- out_be32(&clockctl->pccr[pscnum], 0x00020000);
- out_be32(&clockctl->pccr[pscnum], 0x00030000);
-
- if (in_be32(&clockctl->pccr[pscnum]) & 0x80) {
- clk->rate = spdif_rxclk.rate;
- return;
- }
-
- switch ((in_be32(&clockctl->pccr[pscnum]) >> 14) & 0x3) {
- case 0:
- mclk_src = sys_clk.rate;
- break;
- case 1:
- mclk_src = ref_clk.rate;
- break;
- case 2:
- mclk_src = psc_mclk_in.rate;
- break;
- case 3:
- mclk_src = spdif_txclk.rate;
- break;
- }
-
- mclk_div = ((in_be32(&clockctl->pccr[pscnum]) >> 17) & 0x7fff) + 1;
- clk->rate = mclk_src / mclk_div;
-}
-
-/*
- * Find all psc nodes in device tree and assign a clock
- * with name "psc%d_mclk" and dev pointing at the device
- * returned from of_find_device_by_node
- */
-static void psc_clks_init(void)
-{
- struct device_node *np;
- struct platform_device *ofdev;
- u32 reg;
- const char *psc_compat;
-
- psc_compat = mpc512x_select_psc_compat();
- if (!psc_compat)
- return;
-
- for_each_compatible_node(np, NULL, psc_compat) {
- if (!of_property_read_u32(np, "reg", ®)) {
- int pscnum = (reg & 0xf00) >> 8;
- struct clk *clk = psc_dev_clk(pscnum);
-
- clk->flags = CLK_HAS_RATE | CLK_HAS_CTRL;
- ofdev = of_find_device_by_node(np);
- clk->dev = &ofdev->dev;
- /*
- * AC97 is special rate clock does
- * not go through normal path
- */
- if (of_device_is_compatible(np, "fsl,mpc5121-psc-ac97"))
- clk->rate = ac97_clk.rate;
- else
- psc_calc_rate(clk, pscnum, np);
- sprintf(clk->name, "psc%d_mclk", pscnum);
- clk_register(clk);
- clk_enable(clk);
- }
- }
-}
-
-static struct clk_interface mpc5121_clk_functions = {
- .clk_get = mpc5121_clk_get,
- .clk_enable = mpc5121_clk_enable,
- .clk_disable = mpc5121_clk_disable,
- .clk_get_rate = mpc5121_clk_get_rate,
- .clk_put = mpc5121_clk_put,
- .clk_round_rate = mpc5121_clk_round_rate,
- .clk_set_rate = mpc5121_clk_set_rate,
- .clk_set_parent = NULL,
- .clk_get_parent = NULL,
-};
-
-int __init mpc5121_clk_init(void)
-{
- struct device_node *np;
-
- np = of_find_compatible_node(NULL, NULL, "fsl,mpc5121-clock");
- if (np) {
- clockctl = of_iomap(np, 0);
- of_node_put(np);
- }
-
- if (!clockctl) {
- printk(KERN_ERR "Could not map clock control registers\n");
- return 0;
- }
-
- rate_clks_init();
- psc_clks_init();
-
- /* leave clockctl mapped forever */
- /*iounmap(clockctl); */
- DEBUG_CLK_DUMP();
- clocks_initialized++;
- clk_functions = mpc5121_clk_functions;
- return 0;
-}
--
1.7.10.4
^ permalink raw reply related
* [PATCH v3 28/31] powerpc/mpc512x: improve DIU related clock setup
From: Gerhard Sittig @ 2013-07-22 12:14 UTC (permalink / raw)
To: linuxppc-dev, Anatolij Gustschin, Mike Turquette,
linux-arm-kernel, devicetree-discuss
Cc: Detlev Zundel, Wolfram Sang, Greg Kroah-Hartman, Gerhard Sittig,
Rob Herring, Mark Brown, Marc Kleine-Budde, David Woodhouse,
Wolfgang Grandegger, Mauro Carvalho Chehab
In-Reply-To: <1374495298-22019-1-git-send-email-gsi@denx.de>
adapt the DIU clock initialization to the COMMON_CLK approach: device
tree based clock lookup, prepare and unprepare for clocks, work with
frequencies not dividers, call the appropriate clk_*() routines and
don't access CCM registers, remove the pre-enable workaround in the
platform's clock driver
the "best clock" determination now completely relies on the platform's
clock driver to pick a frequency close to what the caller requests, and
merely checks whether the desired frequency was met (is acceptable since
it meets the tolerance of the monitor) -- this approach shall succeed
upon first try in the usual case, will test a few less desirable yet
acceptable frequencies in edge cases, and will fallback to "best effort"
if none of the previously tried frequencies pass the test
Signed-off-by: Gerhard Sittig <gsi@denx.de>
---
arch/powerpc/platforms/512x/clock-commonclk.c | 1 -
arch/powerpc/platforms/512x/mpc512x_shared.c | 165 +++++++++++++------------
2 files changed, 88 insertions(+), 78 deletions(-)
diff --git a/arch/powerpc/platforms/512x/clock-commonclk.c b/arch/powerpc/platforms/512x/clock-commonclk.c
index f047d4c..893fbe5 100644
--- a/arch/powerpc/platforms/512x/clock-commonclk.c
+++ b/arch/powerpc/platforms/512x/clock-commonclk.c
@@ -696,7 +696,6 @@ static void mpc512x_clk_setup_clock_tree(int busfreq)
clk_prepare_enable(clks[MPC512x_CLK_LPC]); /* boot media */
/* some are not yet acquired by their respective drivers */
clk_prepare_enable(clks[MPC512x_CLK_PSC3_MCLK]);/* serial console */
- clk_prepare_enable(clks[MPC512x_CLK_DIU]); /* display */
/*
* some have their individual clock subtree with separate clock
* items and their individual enable counters, yet share a
diff --git a/arch/powerpc/platforms/512x/mpc512x_shared.c b/arch/powerpc/platforms/512x/mpc512x_shared.c
index a82a41b..3381eea 100644
--- a/arch/powerpc/platforms/512x/mpc512x_shared.c
+++ b/arch/powerpc/platforms/512x/mpc512x_shared.c
@@ -12,6 +12,7 @@
* (at your option) any later version.
*/
+#include <linux/clk.h>
#include <linux/kernel.h>
#include <linux/io.h>
#include <linux/irq.h>
@@ -70,98 +71,108 @@ struct fsl_diu_shared_fb {
bool in_use;
};
-#define DIU_DIV_MASK 0x000000ff
+/* receives a pixel clock spec in pico seconds, adjusts the DIU clock rate */
void mpc512x_set_pixel_clock(unsigned int pixclock)
{
- unsigned long bestval, bestfreq, speed, busfreq;
- unsigned long minpixclock, maxpixclock, pixval;
- struct mpc512x_ccm __iomem *ccm;
struct device_node *np;
- u32 temp;
- long err;
- int i;
+ struct clk *clk_diu;
+ unsigned long epsilon, minpixclock, maxpixclock;
+ unsigned long offset, want, got, delta;
- np = of_find_compatible_node(NULL, NULL, "fsl,mpc5121-clock");
+ /* lookup and enable the DIU clock */
+ np = of_find_compatible_node(NULL, NULL, "fsl,mpc5121-diu");
if (!np) {
- pr_err("Can't find clock control module.\n");
+ pr_err("Could not find DIU device tree node.\n");
return;
}
-
- ccm = of_iomap(np, 0);
+ clk_diu = of_clk_get_by_name(np, "per");
of_node_put(np);
- if (!ccm) {
- pr_err("Can't map clock control module reg.\n");
+ if (IS_ERR(clk_diu)) {
+ pr_err("Could not lookup DIU clock.\n");
return;
}
-
- np = of_find_node_by_type(NULL, "cpu");
- if (np) {
- const unsigned int *prop =
- of_get_property(np, "bus-frequency", NULL);
-
- of_node_put(np);
- if (prop) {
- busfreq = *prop;
- } else {
- pr_err("Can't get bus-frequency property\n");
- return;
- }
- } else {
- pr_err("Can't find 'cpu' node.\n");
+ if (clk_prepare_enable(clk_diu)) {
+ pr_err("Could not enable DIU clock.\n");
return;
}
- /* Pixel Clock configuration */
- pr_debug("DIU: Bus Frequency = %lu\n", busfreq);
- speed = busfreq * 4; /* DIU_DIV ratio is 4 * CSB_CLK / DIU_CLK */
-
- /* Calculate the pixel clock with the smallest error */
- /* calculate the following in steps to avoid overflow */
- pr_debug("DIU pixclock in ps - %d\n", pixclock);
- temp = (1000000000 / pixclock) * 1000;
- pixclock = temp;
- pr_debug("DIU pixclock freq - %u\n", pixclock);
-
- temp = temp / 20; /* pixclock * 0.05 */
- pr_debug("deviation = %d\n", temp);
- minpixclock = pixclock - temp;
- maxpixclock = pixclock + temp;
- pr_debug("DIU minpixclock - %lu\n", minpixclock);
- pr_debug("DIU maxpixclock - %lu\n", maxpixclock);
- pixval = speed/pixclock;
- pr_debug("DIU pixval = %lu\n", pixval);
-
- err = LONG_MAX;
- bestval = pixval;
- pr_debug("DIU bestval = %lu\n", bestval);
-
- bestfreq = 0;
- for (i = -1; i <= 1; i++) {
- temp = speed / (pixval+i);
- pr_debug("DIU test pixval i=%d, pixval=%lu, temp freq. = %u\n",
- i, pixval, temp);
- if ((temp < minpixclock) || (temp > maxpixclock))
- pr_debug("DIU exceeds monitor range (%lu to %lu)\n",
- minpixclock, maxpixclock);
- else if (abs(temp - pixclock) < err) {
- pr_debug("Entered the else if block %d\n", i);
- err = abs(temp - pixclock);
- bestval = pixval + i;
- bestfreq = temp;
- }
+ /*
+ * convert the picoseconds spec into the desired clock rate,
+ * determine the acceptable clock range for the monitor (+/- 5%),
+ * do the calculation in steps to avoid integer overflow
+ */
+ pr_debug("DIU pixclock in ps - %u\n", pixclock);
+ pixclock = (1000000000 / pixclock) * 1000;
+ pr_debug("DIU pixclock freq - %u\n", pixclock);
+ epsilon = pixclock / 20; /* pixclock * 0.05 */
+ pr_debug("DIU deviation - %lu\n", epsilon);
+ minpixclock = pixclock - epsilon;
+ maxpixclock = pixclock + epsilon;
+ pr_debug("DIU minpixclock - %lu\n", minpixclock);
+ pr_debug("DIU maxpixclock - %lu\n", maxpixclock);
+
+ /*
+ * check whether the DIU supports the desired pixel clock
+ *
+ * - simply request the desired clock and see what the
+ * platform's clock driver will make of it, assuming that it
+ * will setup the best approximation of the requested value
+ * - try other candidate frequencies in the order of decreasing
+ * preference (i.e. with increasing distance from the desired
+ * pixel clock, and checking the lower frequency before the
+ * higher frequency to not overload the hardware) until the
+ * first match is found -- any potential subsequent match
+ * would only be as good as the former match or typically
+ * would be less preferrable
+ *
+ * the offset increment of pixelclock divided by 64 is an
+ * arbitrary choice -- it's simple to calculate, in the typical
+ * case we expect the first check to succeed already, in the
+ * worst case seven frequencies get tested (the exact center and
+ * three more values each to the left and to the right) before
+ * the 5% tolerance window is exceeded, resulting in fast enough
+ * execution yet high enough probability of finding a suitable
+ * value, while the error rate will be in the order of single
+ * percents
+ */
+ for (offset = 0; offset <= epsilon; offset += pixclock / 64) {
+ want = pixclock - offset;
+ pr_debug("DIU checking clock - %lu\n", want);
+ clk_set_rate(clk_diu, want);
+ got = clk_get_rate(clk_diu);
+ delta = abs(pixclock - got);
+ if (delta < epsilon)
+ break;
+ if (!offset)
+ continue;
+ want = pixclock + offset;
+ pr_debug("DIU checking clock - %lu\n", want);
+ clk_set_rate(clk_diu, want);
+ got = clk_get_rate(clk_diu);
+ delta = abs(pixclock - got);
+ if (delta < epsilon)
+ break;
}
+ if (offset <= epsilon) {
+ pr_debug("DIU clock accepted - %lu\n", want);
+ pr_debug("DIU pixclock want %u, got %lu, delta %lu, eps %lu\n",
+ pixclock, got, delta, epsilon);
+ return;
+ }
+ pr_warn("DIU pixclock auto search unsuccessful\n");
- pr_debug("DIU chose = %lx\n", bestval);
- pr_debug("DIU error = %ld\n NomPixClk ", err);
- pr_debug("DIU: Best Freq = %lx\n", bestfreq);
- /* Modify DIU_DIV in CCM SCFR1 */
- temp = in_be32(&ccm->scfr1);
- pr_debug("DIU: Current value of SCFR1: 0x%08x\n", temp);
- temp &= ~DIU_DIV_MASK;
- temp |= (bestval & DIU_DIV_MASK);
- out_be32(&ccm->scfr1, temp);
- pr_debug("DIU: Modified value of SCFR1: 0x%08x\n", temp);
- iounmap(ccm);
+ /*
+ * what is the most appropriate action to take when the search
+ * for an available pixel clock which is acceptable to the
+ * monitor has failed? disable the DIU (clock) or just provide
+ * a "best effort"? we go with the latter
+ */
+ pr_warn("DIU pixclock best effort fallback (backend's choice)\n");
+ clk_set_rate(clk_diu, pixclock);
+ got = clk_get_rate(clk_diu);
+ delta = abs(pixclock - got);
+ pr_debug("DIU pixclock want %u, got %lu, delta %lu, eps %lu\n",
+ pixclock, got, delta, epsilon);
}
enum fsl_diu_monitor_port
--
1.7.10.4
^ permalink raw reply related
* [PATCH v3 27/31] net: can: mscan: add common clock support for mpc512x
From: Gerhard Sittig @ 2013-07-22 12:14 UTC (permalink / raw)
To: linuxppc-dev, Anatolij Gustschin, Mike Turquette,
linux-arm-kernel, devicetree-discuss
Cc: Detlev Zundel, Wolfram Sang, Greg Kroah-Hartman, Gerhard Sittig,
Rob Herring, Mark Brown, Marc Kleine-Budde, David Woodhouse,
Wolfgang Grandegger, Mauro Carvalho Chehab
In-Reply-To: <1374495298-22019-1-git-send-email-gsi@denx.de>
implement a .get_clock() callback for the MPC512x platform which uses
the common clock infrastructure (eliminating direct access to the clock
control registers from within the CAN network driver), and provide the
corresponding .put_clock() callback to release resources after use
keep the previous implementation of MPC512x support in place during
migration, since common clock support is optional
this change is neutral to the MPC5200 platform
Signed-off-by: Gerhard Sittig <gsi@denx.de>
---
drivers/net/can/mscan/mpc5xxx_can.c | 169 +++++++++++++++++++++++++++++++++++
1 file changed, 169 insertions(+)
diff --git a/drivers/net/can/mscan/mpc5xxx_can.c b/drivers/net/can/mscan/mpc5xxx_can.c
index e59b3a3..4897929 100644
--- a/drivers/net/can/mscan/mpc5xxx_can.c
+++ b/drivers/net/can/mscan/mpc5xxx_can.c
@@ -109,6 +109,167 @@ static u32 mpc52xx_can_get_clock(struct platform_device *ofdev,
#endif /* CONFIG_PPC_MPC52xx */
#ifdef CONFIG_PPC_MPC512x
+
+#if IS_ENABLED(CONFIG_COMMON_CLK)
+
+static u32 mpc512x_can_get_clock(struct platform_device *ofdev,
+ const char *clock_source, int *mscan_clksrc)
+{
+ struct device_node *np;
+ u32 clockdiv;
+ enum {
+ CLK_FROM_AUTO,
+ CLK_FROM_IPS,
+ CLK_FROM_SYS,
+ CLK_FROM_REF,
+ } clk_from;
+ struct clk *clk_in, *clk_can;
+ unsigned long freq_calc;
+ struct mscan_priv *priv;
+
+ /* the caller passed in the clock source spec that was read from
+ * the device tree, get the optional clock divider as well
+ */
+ np = ofdev->dev.of_node;
+ clockdiv = 1;
+ of_property_read_u32(np, "fsl,mscan-clock-divider", &clockdiv);
+ dev_dbg(&ofdev->dev, "device tree specs: clk src[%s] div[%d]\n",
+ clock_source ? clock_source : "<NULL>", clockdiv);
+
+ /* when clock-source is 'ip', the CANCTL1[CLKSRC] bit needs to
+ * get set, and the 'ips' clock is the input to the MSCAN
+ * component
+ *
+ * for clock-source values of 'ref' or 'sys' the CANCTL1[CLKSRC]
+ * bit needs to get cleared, an optional clock-divider may have
+ * been specified (the default value is 1), the appropriate
+ * MSCAN related MCLK is the input to the MSCAN component
+ *
+ * in the absence of a clock-source spec, first an optimal clock
+ * gets determined based on the 'sys' clock, if that fails the
+ * 'ref' clock is used
+ */
+ clk_from = CLK_FROM_AUTO;
+ if (clock_source) {
+ /* interpret the device tree's spec for the clock source */
+ if (!strcmp(clock_source, "ip"))
+ clk_from = CLK_FROM_IPS;
+ else if (!strcmp(clock_source, "sys"))
+ clk_from = CLK_FROM_SYS;
+ else if (!strcmp(clock_source, "ref"))
+ clk_from = CLK_FROM_REF;
+ else
+ goto err_invalid;
+ dev_dbg(&ofdev->dev, "got a clk source spec[%d]\n", clk_from);
+ }
+ if (clk_from == CLK_FROM_AUTO) {
+ /* no spec so far, try the 'sys' clock; round to the
+ * next MHz and see if we can get a multiple of 16MHz
+ */
+ dev_dbg(&ofdev->dev, "no clk source spec, trying SYS\n");
+ clk_in = devm_clk_get(&ofdev->dev, "sys");
+ if (IS_ERR(clk_in))
+ goto err_notavail;
+ freq_calc = clk_get_rate(clk_in);
+ freq_calc += 499999;
+ freq_calc /= 1000000;
+ freq_calc *= 1000000;
+ if ((freq_calc % 16000000) == 0) {
+ clk_from = CLK_FROM_SYS;
+ clockdiv = freq_calc / 16000000;
+ dev_dbg(&ofdev->dev,
+ "clk fit, sys[%lu] div[%d] freq[%lu]\n",
+ freq_calc, clockdiv, freq_calc / clockdiv);
+ }
+ }
+ if (clk_from == CLK_FROM_AUTO) {
+ /* no spec so far, use the 'ref' clock */
+ dev_dbg(&ofdev->dev, "no clk source spec, trying REF\n");
+ clk_in = devm_clk_get(&ofdev->dev, "ref");
+ if (IS_ERR(clk_in))
+ goto err_notavail;
+ clk_from = CLK_FROM_REF;
+ freq_calc = clk_get_rate(clk_in);
+ dev_dbg(&ofdev->dev,
+ "clk fit, ref[%lu] (no div) freq[%lu]\n",
+ freq_calc, freq_calc);
+ }
+
+ /* select IPS or MCLK as the MSCAN input (returned to the caller),
+ * setup the MCLK mux source and rate if applicable, apply the
+ * optionally specified or derived above divider, and determine
+ * the actual resulting clock rate to return to the caller
+ */
+ switch (clk_from) {
+ case CLK_FROM_IPS:
+ clk_can = devm_clk_get(&ofdev->dev, "ips");
+ if (IS_ERR(clk_can))
+ goto err_notavail;
+ if (clk_prepare(clk_can)) {
+ devm_clk_put(&ofdev->dev, clk_can);
+ goto err_notavail;
+ }
+ priv = netdev_priv(dev_get_drvdata(&ofdev->dev));
+ priv->clk_can = clk_can;
+ freq_calc = clk_get_rate(clk_can);
+ *mscan_clksrc = MSCAN_CLKSRC_IPS;
+ dev_dbg(&ofdev->dev, "clk from IPS, clksrc[%d] freq[%lu]\n",
+ *mscan_clksrc, freq_calc);
+ break;
+ case CLK_FROM_SYS:
+ case CLK_FROM_REF:
+ clk_can = devm_clk_get(&ofdev->dev, "mclk");
+ if (IS_ERR(clk_can))
+ goto err_notavail;
+ if (clk_prepare(clk_can)) {
+ devm_clk_put(&ofdev->dev, clk_can);
+ goto err_notavail;
+ }
+ priv = netdev_priv(dev_get_drvdata(&ofdev->dev));
+ priv->clk_can = clk_can;
+ if (clk_from == CLK_FROM_SYS)
+ clk_in = devm_clk_get(&ofdev->dev, "sys");
+ if (clk_from == CLK_FROM_REF)
+ clk_in = devm_clk_get(&ofdev->dev, "ref");
+ if (IS_ERR(clk_in))
+ goto err_notavail;
+ clk_set_parent(clk_can, clk_in);
+ freq_calc = clk_get_rate(clk_in);
+ freq_calc /= clockdiv;
+ clk_set_rate(clk_can, freq_calc);
+ freq_calc = clk_get_rate(clk_can);
+ *mscan_clksrc = MSCAN_CLKSRC_BUS;
+ dev_dbg(&ofdev->dev, "clk from MCLK, clksrc[%d] freq[%lu]\n",
+ *mscan_clksrc, freq_calc);
+ break;
+ default:
+ goto err_invalid;
+ }
+
+ return freq_calc;
+
+err_invalid:
+ dev_err(&ofdev->dev, "invalid clock source specification\n");
+ return 0;
+
+err_notavail:
+ dev_err(&ofdev->dev, "cannot acquire or setup clock source\n");
+ return 0;
+}
+
+static void mpc512x_can_put_clock(struct platform_device *ofdev)
+{
+ struct mscan_priv *priv;
+
+ priv = netdev_priv(dev_get_drvdata(&ofdev->dev));
+ if (priv->clk_can) {
+ clk_unprepare(priv->clk_can);
+ devm_clk_put(&ofdev->dev, priv->clk_can);
+ }
+}
+
+#else /* COMMON_CLK */
+
struct mpc512x_clockctl {
u32 spmr; /* System PLL Mode Reg */
u32 sccr[2]; /* System Clk Ctrl Reg 1 & 2 */
@@ -239,12 +400,18 @@ exit_put:
of_node_put(np_clock);
return freq;
}
+
+#define mpc512x_can_put_clock NULL
+
+#endif /* COMMON_CLK */
+
#else /* !CONFIG_PPC_MPC512x */
static u32 mpc512x_can_get_clock(struct platform_device *ofdev,
const char *clock_name, int *mscan_clksrc)
{
return 0;
}
+#define mpc512x_can_put_clock NULL
#endif /* CONFIG_PPC_MPC512x */
static const struct of_device_id mpc5xxx_can_table[];
@@ -386,11 +553,13 @@ static int mpc5xxx_can_resume(struct platform_device *ofdev)
static const struct mpc5xxx_can_data mpc5200_can_data = {
.type = MSCAN_TYPE_MPC5200,
.get_clock = mpc52xx_can_get_clock,
+ /* .put_clock not applicable */
};
static const struct mpc5xxx_can_data mpc5121_can_data = {
.type = MSCAN_TYPE_MPC5121,
.get_clock = mpc512x_can_get_clock,
+ .put_clock = mpc512x_can_put_clock,
};
static const struct of_device_id mpc5xxx_can_table[] = {
--
1.7.10.4
^ permalink raw reply related
* [PATCH v3 26/31] [media] fsl-viu: remove now obsolete clock lookup name
From: Gerhard Sittig @ 2013-07-22 12:14 UTC (permalink / raw)
To: linuxppc-dev, Anatolij Gustschin, Mike Turquette,
linux-arm-kernel, devicetree-discuss
Cc: Detlev Zundel, Wolfram Sang, Greg Kroah-Hartman, Gerhard Sittig,
Rob Herring, Mark Brown, Marc Kleine-Budde, David Woodhouse,
Wolfgang Grandegger, Mauro Carvalho Chehab
In-Reply-To: <1374495298-22019-1-git-send-email-gsi@denx.de>
after device tree based clock lookup became available, the VIU driver
need no longer use the previous "viu_clk" name but can switch to the
fixed "per" clock name -- adjust the peripheral driver and remove the
clock driver's clkdev registration
Signed-off-by: Gerhard Sittig <gsi@denx.de>
---
arch/powerpc/platforms/512x/clock-commonclk.c | 1 -
drivers/media/platform/fsl-viu.c | 2 +-
2 files changed, 1 insertion(+), 2 deletions(-)
diff --git a/arch/powerpc/platforms/512x/clock-commonclk.c b/arch/powerpc/platforms/512x/clock-commonclk.c
index 24e1706..f047d4c 100644
--- a/arch/powerpc/platforms/512x/clock-commonclk.c
+++ b/arch/powerpc/platforms/512x/clock-commonclk.c
@@ -676,7 +676,6 @@ static void mpc512x_clk_setup_clock_tree(int busfreq)
/* clkdev registration for compatibility reasons */
clk_register_clkdev(clks[MPC512x_CLK_REF], "ref_clk", NULL);
clk_register_clkdev(clks[MPC512x_CLK_SYS], "sys_clk", NULL);
- clk_register_clkdev(clks[MPC512x_CLK_VIU], "viu_clk", NULL);
pr_debug("clock tree setup complete\n");
freq = clk_get_rate(clks[MPC512x_CLK_E300]);
diff --git a/drivers/media/platform/fsl-viu.c b/drivers/media/platform/fsl-viu.c
index 48fced4..8a17433 100644
--- a/drivers/media/platform/fsl-viu.c
+++ b/drivers/media/platform/fsl-viu.c
@@ -1578,7 +1578,7 @@ static int viu_of_probe(struct platform_device *op)
}
/* enable VIU clock */
- clk = devm_clk_get(&op->dev, "viu_clk");
+ clk = devm_clk_get(&op->dev, "per");
if (IS_ERR(clk)) {
dev_err(&op->dev, "failed to lookup the clock!\n");
ret = PTR_ERR(clk);
--
1.7.10.4
^ permalink raw reply related
page: next (older) | prev (newer) | latest
- recent:[subjects (threaded)|topics (new)|topics (active)]
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox