[PATCH] cpufreq: qoriq: clean up unused code
From: Tang Yuantian This snip code is not needed anymore since its user get_hard_smp_processor_id() has been removed. Signed-off-by: Tang Yuantian --- drivers/cpufreq/qoriq-cpufreq.c | 4 1 file changed, 4 deletions(-) diff --git a/drivers/cpufreq/qoriq-cpufreq.c b/drivers/cpufreq/qoriq-cpufreq.c index 53d8c3f..02031a3 100644 --- a/drivers/cpufreq/qoriq-cpufreq.c +++ b/drivers/cpufreq/qoriq-cpufreq.c @@ -22,10 +22,6 @@ #include #include -#if !defined(CONFIG_ARM) -#include/* for get_hard_smp_processor_id() in UP configs */ -#endif - /** * struct cpu_data * @pclk: the parent clock of cpu -- 2.1.0.27.g96db324
[PATCH 2/2] clk: qoriq: Separate root input clock for core PLLs on ls1012a
From: Tang Yuantian ls1012a has separate input root clocks for core PLLs versus the platform PLL, with the latter described as sysclk in the hw docs. If a second input clock, named "coreclk", is present, this clock will be used for the core PLLs. Signed-off-by: Scott Wood Signed-off-by: Tang Yuantian --- drivers/clk/clk-qoriq.c | 91 + 1 file changed, 77 insertions(+), 14 deletions(-) diff --git a/drivers/clk/clk-qoriq.c b/drivers/clk/clk-qoriq.c index d0bf8b1..f3931e3 100644 --- a/drivers/clk/clk-qoriq.c +++ b/drivers/clk/clk-qoriq.c @@ -87,7 +87,7 @@ struct clockgen { struct device_node *node; void __iomem *regs; struct clockgen_chipinfo info; /* mutable copy */ - struct clk *sysclk; + struct clk *sysclk, *coreclk; struct clockgen_pll pll[6]; struct clk *cmux[NUM_CMUX]; struct clk *hwaccel[NUM_HWACCEL]; @@ -904,7 +904,12 @@ static void __init create_muxes(struct clockgen *cg) static void __init clockgen_init(struct device_node *np); -/* Legacy nodes may get probed before the parent clockgen node */ +/* + * Legacy nodes may get probed before the parent clockgen node. + * It is assumed that device trees with legacy nodes will not + * contain a "clocks" property -- otherwise the input clocks may + * not be initialized at this point. + */ static void __init legacy_init_clockgen(struct device_node *np) { if (!clockgen.node) @@ -945,18 +950,13 @@ static struct clk __init return clk_register_fixed_rate(NULL, name, NULL, 0, rate); } -static struct clk *sysclk_from_parent(const char *name) +static struct clk __init *input_clock(const char *name, struct clk *clk) { - struct clk *clk; - const char *parent_name; - - clk = of_clk_get(clockgen.node, 0); - if (IS_ERR(clk)) - return clk; + const char *input_name; /* Register the input clock under the desired name. */ - parent_name = __clk_get_name(clk); - clk = clk_register_fixed_factor(NULL, name, parent_name, + input_name = __clk_get_name(clk); + clk = clk_register_fixed_factor(NULL, name, input_name, 0, 1, 1); if (IS_ERR(clk)) pr_err("%s: Couldn't register %s: %ld\n", __func__, name, @@ -965,6 +965,29 @@ static struct clk *sysclk_from_parent(const char *name) return clk; } +static struct clk __init *input_clock_by_name(const char *name, + const char *dtname) +{ + struct clk *clk; + + clk = of_clk_get_by_name(clockgen.node, dtname); + if (IS_ERR(clk)) + return clk; + + return input_clock(name, clk); +} + +static struct clk __init *input_clock_by_index(const char *name, int idx) +{ + struct clk *clk; + + clk = of_clk_get(clockgen.node, 0); + if (IS_ERR(clk)) + return clk; + + return input_clock(name, clk); +} + static struct clk * __init create_sysclk(const char *name) { struct device_node *sysclk; @@ -974,7 +997,11 @@ static struct clk * __init create_sysclk(const char *name) if (!IS_ERR(clk)) return clk; - clk = sysclk_from_parent(name); + clk = input_clock_by_name(name, "sysclk"); + if (!IS_ERR(clk)) + return clk; + + clk = input_clock_by_index(name, 0); if (!IS_ERR(clk)) return clk; @@ -985,7 +1012,27 @@ static struct clk * __init create_sysclk(const char *name) return clk; } - pr_err("%s: No input clock\n", __func__); + pr_err("%s: No input sysclk\n", __func__); + return NULL; +} + +static struct clk * __init create_coreclk(const char *name) +{ + struct clk *clk; + + clk = input_clock_by_name(name, "coreclk"); + if (!IS_ERR(clk)) + return clk; + + /* +* This indicates a mix of legacy nodes with the new coreclk +* mechanism, which should never happen. If this error occurs, +* don't use the wrong input clock just because coreclk isn't +* ready yet. +*/ + if (WARN_ON(PTR_ERR(clk) == -EPROBE_DEFER)) + return clk; + return NULL; } @@ -1008,11 +1055,19 @@ static void __init create_one_pll(struct clockgen *cg, int idx) u32 __iomem *reg; u32 mult; struct clockgen_pll *pll = &cg->pll[idx]; + const char *input = "cg-sysclk"; int i; if (!(cg->info.pll_mask & (1 << idx))) return; + if (cg->coreclk && idx != PLATFORM_PLL) { + if (IS_ERR(cg->coreclk)) + return; + + input = "cg-coreclk"; + } + if (cg->info.flags & CG_VER3) { switch (idx) { case PLATFORM_PLL: @@ -1063,7 +1118,7 @@ static void __init create_one_pll(struct clockgen *cg, int idx)
[PATCH 1/2] dt-bindings: qoriq-clock: Add coreclk
From: Tang Yuantian ls1012a has separate input root clocks for core PLLs versus the platform PLL, with the latter described as sysclk in the hw docs. Update the qoriq-clock binding to allow a second input clock, named "coreclk". If present, this clock will be used for the core PLLs. Signed-off-by: Scott Wood Signed-off-by: Tang Yuantian --- Documentation/devicetree/bindings/clock/qoriq-clock.txt | 6 ++ 1 file changed, 6 insertions(+) diff --git a/Documentation/devicetree/bindings/clock/qoriq-clock.txt b/Documentation/devicetree/bindings/clock/qoriq-clock.txt index df9cb5a..97a9666 100644 --- a/Documentation/devicetree/bindings/clock/qoriq-clock.txt +++ b/Documentation/devicetree/bindings/clock/qoriq-clock.txt @@ -55,6 +55,11 @@ Optional properties: - clocks: If clock-frequency is not specified, sysclk may be provided as an input clock. Either clock-frequency or clocks must be provided. + A second input clock, called "coreclk", may be provided if + core PLLs are based on a different input clock from the + platform PLL. +- clock-names: Required if a coreclk is present. Valid names are + "sysclk" and "coreclk". 2. Clock Provider @@ -71,6 +76,7 @@ second cell is the clock index for the specified type. 2 hwaccel index (n in CLKCGnHWACSR) 3 fman0 for fm1, 1 for fm2 4 platform pll0=pll, 1=pll/2, 2=pll/3, 3=pll/4 + 5 coreclk must be 0 3. Example -- 2.1.0.27.g96db324
[PATCH 2/2 v4] cpufreq: qoriq: Don't look at clock implementation details
From: Tang Yuantian Get the CPU clock's potential parent clocks from the clock interface itself, rather than manually parsing the clocks property to find a phandle, looking at the clock-names property of that, and assuming that those are valid parent clocks for the cpu clock. This is necessary now that the clocks are generated based on the clock driver's knowledge of the chip rather than a fragile device-tree description of the mux options. We can now rely on the clock driver to ensure that the mux only exposes options that are valid. The cpufreq driver was currently being overly conservative in some cases -- for example, the "min_cpufreq = get_bus_freq()" restriction only applies to chips with erratum A-004510, and whether the freq_mask used on p5020 is needed depends on the actual frequencies of the PLLs (FWIW, p5040 has a similar limitation but its .freq_mask was zero) -- and the frequency mask mechanism made assumptions about particular parent clock indices that are no longer valid. Signed-off-by: Scott Wood Signed-off-by: Tang Yuantian Acked-by: Viresh Kumar --- v2: added more soc compatible strings v3: Remove the now-unused pnode and the call to of_node_put() v4: fixed warning: >> [-Werror=implicit-function-declaration] > return get_hard_smp_processor_id(cpu); drivers/cpufreq/qoriq-cpufreq.c | 152 +--- 1 file changed, 49 insertions(+), 103 deletions(-) diff --git a/drivers/cpufreq/qoriq-cpufreq.c b/drivers/cpufreq/qoriq-cpufreq.c index 53d8c3f..bfec1bc 100644 --- a/drivers/cpufreq/qoriq-cpufreq.c +++ b/drivers/cpufreq/qoriq-cpufreq.c @@ -11,6 +11,7 @@ #define pr_fmt(fmt)KBUILD_MODNAME ": " fmt #include +#include #include #include #include @@ -22,10 +23,6 @@ #include #include -#if !defined(CONFIG_ARM) -#include/* for get_hard_smp_processor_id() in UP configs */ -#endif - /** * struct cpu_data * @pclk: the parent clock of cpu @@ -37,53 +34,20 @@ struct cpu_data { struct thermal_cooling_device *cdev; }; +/* + * Don't use cpufreq on this SoC -- used when the SoC would have otherwise + * matched a more generic compatible. + */ +#define SOC_BLACKLIST 1 + /** * struct soc_data - SoC specific data - * @freq_mask: mask the disallowed frequencies - * @flag: unique flags + * @flags: SOC_xxx */ struct soc_data { - u32 freq_mask[4]; - u32 flag; + u32 flags; }; -#define FREQ_MASK 1 -/* see hardware specification for the allowed frqeuencies */ -static const struct soc_data sdata[] = { - { /* used by p2041 and p3041 */ - .freq_mask = {0x8, 0x8, 0x2, 0x2}, - .flag = FREQ_MASK, - }, - { /* used by p5020 */ - .freq_mask = {0x8, 0x2}, - .flag = FREQ_MASK, - }, - { /* used by p4080, p5040 */ - .freq_mask = {0}, - .flag = 0, - }, -}; - -/* - * the minimum allowed core frequency, in Hz - * for chassis v1.0, >= platform frequency - * for chassis v2.0, >= platform frequency / 2 - */ -static u32 min_cpufreq; -static const u32 *fmask; - -#if defined(CONFIG_ARM) -static int get_cpu_physical_id(int cpu) -{ - return topology_core_id(cpu); -} -#else -static int get_cpu_physical_id(int cpu) -{ - return get_hard_smp_processor_id(cpu); -} -#endif - static u32 get_bus_freq(void) { struct device_node *soc; @@ -101,9 +65,10 @@ static u32 get_bus_freq(void) return sysfreq; } -static struct device_node *cpu_to_clk_node(int cpu) +static struct clk *cpu_to_clk(int cpu) { - struct device_node *np, *clk_np; + struct device_node *np; + struct clk *clk; if (!cpu_present(cpu)) return NULL; @@ -112,37 +77,28 @@ static struct device_node *cpu_to_clk_node(int cpu) if (!np) return NULL; - clk_np = of_parse_phandle(np, "clocks", 0); - if (!clk_np) - return NULL; - + clk = of_clk_get(np, 0); of_node_put(np); - - return clk_np; + return clk; } /* traverse cpu nodes to get cpu mask of sharing clock wire */ static void set_affected_cpus(struct cpufreq_policy *policy) { - struct device_node *np, *clk_np; struct cpumask *dstp = policy->cpus; + struct clk *clk; int i; - np = cpu_to_clk_node(policy->cpu); - if (!np) - return; - for_each_present_cpu(i) { - clk_np = cpu_to_clk_node(i); - if (!clk_np) + clk = cpu_to_clk(i); + if (IS_ERR(clk)) { + pr_err("%s: no clock for cpu %d\n", __func__, i); continue; + } - if (clk_np == np) + if (clk_is_match(policy->clk, clk)) cpumask_set_cpu(i, dstp); - - of_node_put(clk_np); } - of_node_put(np); } /* reduce the duplicated frequencie
[PATCH 1/2 v4] cpufreq: qoriq: added arm64 socs support
From: Tang Yuantian Add arm64 config to Kconfig to enable cpu frequency feature on nxp arm64 socs. Signed-off-by: Tang Yuantian --- v2-v4: no change drivers/cpufreq/Kconfig | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/drivers/cpufreq/Kconfig b/drivers/cpufreq/Kconfig index 15adef4..3964383 100644 --- a/drivers/cpufreq/Kconfig +++ b/drivers/cpufreq/Kconfig @@ -324,7 +324,7 @@ endif config QORIQ_CPUFREQ tristate "CPU frequency scaling driver for Freescale QorIQ SoCs" - depends on OF && COMMON_CLK && (PPC_E500MC || ARM) + depends on OF && COMMON_CLK && (PPC_E500MC || ARM || ARM64) depends on !CPU_THERMAL || THERMAL select CLK_QORIQ help -- 2.1.0.27.g96db324
[PATCH 1/2 v3] cpufreq: qoriq: added arm64 socs support
From: Tang Yuantian Add arm64 config to Kconfig to enable cpu frequency feature on nxp arm64 socs. Signed-off-by: Tang Yuantian --- v3: no change v2: no change drivers/cpufreq/Kconfig | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/drivers/cpufreq/Kconfig b/drivers/cpufreq/Kconfig index 15adef4..3964383 100644 --- a/drivers/cpufreq/Kconfig +++ b/drivers/cpufreq/Kconfig @@ -324,7 +324,7 @@ endif config QORIQ_CPUFREQ tristate "CPU frequency scaling driver for Freescale QorIQ SoCs" - depends on OF && COMMON_CLK && (PPC_E500MC || ARM) + depends on OF && COMMON_CLK && (PPC_E500MC || ARM || ARM64) depends on !CPU_THERMAL || THERMAL select CLK_QORIQ help -- 2.1.0.27.g96db324
[PATCH 2/2 v3] cpufreq: qoriq: Don't look at clock implementation details
From: Tang Yuantian Get the CPU clock's potential parent clocks from the clock interface itself, rather than manually parsing the clocks property to find a phandle, looking at the clock-names property of that, and assuming that those are valid parent clocks for the cpu clock. This is necessary now that the clocks are generated based on the clock driver's knowledge of the chip rather than a fragile device-tree description of the mux options. We can now rely on the clock driver to ensure that the mux only exposes options that are valid. The cpufreq driver was currently being overly conservative in some cases -- for example, the "min_cpufreq = get_bus_freq()" restriction only applies to chips with erratum A-004510, and whether the freq_mask used on p5020 is needed depends on the actual frequencies of the PLLs (FWIW, p5040 has a similar limitation but its .freq_mask was zero) -- and the frequency mask mechanism made assumptions about particular parent clock indices that are no longer valid. Signed-off-by: Scott Wood Signed-off-by: Tang Yuantian Acked-by: Viresh Kumar --- v2: - added more soc compatible strings v3: - Remove the now-unused pnode and the call to of_node_put() drivers/cpufreq/qoriq-cpufreq.c | 148 +--- 1 file changed, 49 insertions(+), 99 deletions(-) diff --git a/drivers/cpufreq/qoriq-cpufreq.c b/drivers/cpufreq/qoriq-cpufreq.c index 53d8c3f..a6fefac 100644 --- a/drivers/cpufreq/qoriq-cpufreq.c +++ b/drivers/cpufreq/qoriq-cpufreq.c @@ -11,6 +11,7 @@ #define pr_fmt(fmt)KBUILD_MODNAME ": " fmt #include +#include #include #include #include @@ -37,53 +38,20 @@ struct cpu_data { struct thermal_cooling_device *cdev; }; +/* + * Don't use cpufreq on this SoC -- used when the SoC would have otherwise + * matched a more generic compatible. + */ +#define SOC_BLACKLIST 1 + /** * struct soc_data - SoC specific data - * @freq_mask: mask the disallowed frequencies - * @flag: unique flags + * @flags: SOC_xxx */ struct soc_data { - u32 freq_mask[4]; - u32 flag; -}; - -#define FREQ_MASK 1 -/* see hardware specification for the allowed frqeuencies */ -static const struct soc_data sdata[] = { - { /* used by p2041 and p3041 */ - .freq_mask = {0x8, 0x8, 0x2, 0x2}, - .flag = FREQ_MASK, - }, - { /* used by p5020 */ - .freq_mask = {0x8, 0x2}, - .flag = FREQ_MASK, - }, - { /* used by p4080, p5040 */ - .freq_mask = {0}, - .flag = 0, - }, + u32 flags; }; -/* - * the minimum allowed core frequency, in Hz - * for chassis v1.0, >= platform frequency - * for chassis v2.0, >= platform frequency / 2 - */ -static u32 min_cpufreq; -static const u32 *fmask; - -#if defined(CONFIG_ARM) -static int get_cpu_physical_id(int cpu) -{ - return topology_core_id(cpu); -} -#else -static int get_cpu_physical_id(int cpu) -{ - return get_hard_smp_processor_id(cpu); -} -#endif - static u32 get_bus_freq(void) { struct device_node *soc; @@ -101,9 +69,10 @@ static u32 get_bus_freq(void) return sysfreq; } -static struct device_node *cpu_to_clk_node(int cpu) +static struct clk *cpu_to_clk(int cpu) { - struct device_node *np, *clk_np; + struct device_node *np; + struct clk *clk; if (!cpu_present(cpu)) return NULL; @@ -112,37 +81,28 @@ static struct device_node *cpu_to_clk_node(int cpu) if (!np) return NULL; - clk_np = of_parse_phandle(np, "clocks", 0); - if (!clk_np) - return NULL; - + clk = of_clk_get(np, 0); of_node_put(np); - - return clk_np; + return clk; } /* traverse cpu nodes to get cpu mask of sharing clock wire */ static void set_affected_cpus(struct cpufreq_policy *policy) { - struct device_node *np, *clk_np; struct cpumask *dstp = policy->cpus; + struct clk *clk; int i; - np = cpu_to_clk_node(policy->cpu); - if (!np) - return; - for_each_present_cpu(i) { - clk_np = cpu_to_clk_node(i); - if (!clk_np) + clk = cpu_to_clk(i); + if (IS_ERR(clk)) { + pr_err("%s: no clock for cpu %d\n", __func__, i); continue; + } - if (clk_np == np) + if (clk_is_match(policy->clk, clk)) cpumask_set_cpu(i, dstp); - - of_node_put(clk_np); } - of_node_put(np); } /* reduce the duplicated frequencies in frequency table */ @@ -198,10 +158,11 @@ static void freq_table_sort(struct cpufreq_frequency_table *freq_table, static int qoriq_cpufreq_cpu_init(struct cpufreq_policy *policy) { - struct device_node *np, *pnode; + struct device_node *np; int i, count, ret; - u32 freq, mask; +
[PATCH 1/2 v2] cpufreq: qoriq: added arm64 socs support
From: Tang Yuantian Add arm64 config to Kconfig to enable cpu frequency feature on nxp arm64 socs. Signed-off-by: Tang Yuantian --- v2: - no change drivers/cpufreq/Kconfig | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/drivers/cpufreq/Kconfig b/drivers/cpufreq/Kconfig index 15adef4..3964383 100644 --- a/drivers/cpufreq/Kconfig +++ b/drivers/cpufreq/Kconfig @@ -324,7 +324,7 @@ endif config QORIQ_CPUFREQ tristate "CPU frequency scaling driver for Freescale QorIQ SoCs" - depends on OF && COMMON_CLK && (PPC_E500MC || ARM) + depends on OF && COMMON_CLK && (PPC_E500MC || ARM || ARM64) depends on !CPU_THERMAL || THERMAL select CLK_QORIQ help -- 2.1.0.27.g96db324
[PATCH 2/2 v2] cpufreq: qoriq: Don't look at clock implementation details
From: Tang Yuantian Get the CPU clock's potential parent clocks from the clock interface itself, rather than manually parsing the clocks property to find a phandle, looking at the clock-names property of that, and assuming that those are valid parent clocks for the cpu clock. This is necessary now that the clocks are generated based on the clock driver's knowledge of the chip rather than a fragile device-tree description of the mux options. We can now rely on the clock driver to ensure that the mux only exposes options that are valid. The cpufreq driver was currently being overly conservative in some cases -- for example, the "min_cpufreq = get_bus_freq()" restriction only applies to chips with erratum A-004510, and whether the freq_mask used on p5020 is needed depends on the actual frequencies of the PLLs (FWIW, p5040 has a similar limitation but its .freq_mask was zero) -- and the frequency mask mechanism made assumptions about particular parent clock indices that are no longer valid. Signed-off-by: Scott Wood Signed-off-by: Tang Yuantian Acked-by: Viresh Kumar --- v2: - added more soc compatible strings drivers/cpufreq/qoriq-cpufreq.c | 145 +--- 1 file changed, 48 insertions(+), 97 deletions(-) diff --git a/drivers/cpufreq/qoriq-cpufreq.c b/drivers/cpufreq/qoriq-cpufreq.c index 53d8c3f..eee83c1 100644 --- a/drivers/cpufreq/qoriq-cpufreq.c +++ b/drivers/cpufreq/qoriq-cpufreq.c @@ -11,6 +11,7 @@ #define pr_fmt(fmt)KBUILD_MODNAME ": " fmt #include +#include #include #include #include @@ -37,53 +38,20 @@ struct cpu_data { struct thermal_cooling_device *cdev; }; +/* + * Don't use cpufreq on this SoC -- used when the SoC would have otherwise + * matched a more generic compatible. + */ +#define SOC_BLACKLIST 1 + /** * struct soc_data - SoC specific data - * @freq_mask: mask the disallowed frequencies - * @flag: unique flags + * @flags: SOC_xxx */ struct soc_data { - u32 freq_mask[4]; - u32 flag; -}; - -#define FREQ_MASK 1 -/* see hardware specification for the allowed frqeuencies */ -static const struct soc_data sdata[] = { - { /* used by p2041 and p3041 */ - .freq_mask = {0x8, 0x8, 0x2, 0x2}, - .flag = FREQ_MASK, - }, - { /* used by p5020 */ - .freq_mask = {0x8, 0x2}, - .flag = FREQ_MASK, - }, - { /* used by p4080, p5040 */ - .freq_mask = {0}, - .flag = 0, - }, + u32 flags; }; -/* - * the minimum allowed core frequency, in Hz - * for chassis v1.0, >= platform frequency - * for chassis v2.0, >= platform frequency / 2 - */ -static u32 min_cpufreq; -static const u32 *fmask; - -#if defined(CONFIG_ARM) -static int get_cpu_physical_id(int cpu) -{ - return topology_core_id(cpu); -} -#else -static int get_cpu_physical_id(int cpu) -{ - return get_hard_smp_processor_id(cpu); -} -#endif - static u32 get_bus_freq(void) { struct device_node *soc; @@ -101,9 +69,10 @@ static u32 get_bus_freq(void) return sysfreq; } -static struct device_node *cpu_to_clk_node(int cpu) +static struct clk *cpu_to_clk(int cpu) { - struct device_node *np, *clk_np; + struct device_node *np; + struct clk *clk; if (!cpu_present(cpu)) return NULL; @@ -112,37 +81,28 @@ static struct device_node *cpu_to_clk_node(int cpu) if (!np) return NULL; - clk_np = of_parse_phandle(np, "clocks", 0); - if (!clk_np) - return NULL; - + clk = of_clk_get(np, 0); of_node_put(np); - - return clk_np; + return clk; } /* traverse cpu nodes to get cpu mask of sharing clock wire */ static void set_affected_cpus(struct cpufreq_policy *policy) { - struct device_node *np, *clk_np; struct cpumask *dstp = policy->cpus; + struct clk *clk; int i; - np = cpu_to_clk_node(policy->cpu); - if (!np) - return; - for_each_present_cpu(i) { - clk_np = cpu_to_clk_node(i); - if (!clk_np) + clk = cpu_to_clk(i); + if (IS_ERR(clk)) { + pr_err("%s: no clock for cpu %d\n", __func__, i); continue; + } - if (clk_np == np) + if (clk_is_match(policy->clk, clk)) cpumask_set_cpu(i, dstp); - - of_node_put(clk_np); } - of_node_put(np); } /* reduce the duplicated frequencies in frequency table */ @@ -200,8 +160,9 @@ static int qoriq_cpufreq_cpu_init(struct cpufreq_policy *policy) { struct device_node *np, *pnode; int i, count, ret; - u32 freq, mask; + u32 freq; struct clk *clk; + const struct clk_hw *hwclk; struct cpufreq_frequency_table *table; struct cpu_data *data; unsigned int cpu =
[PATCH 1/3 v2] ahci: qoriq: added a condition to enable dma coherence
From: Tang Yuantian Enable DMA coherence in SATA controller on condition that dma-coherent property exists in sata node in DTS. Signed-off-by: Tang Yuantian --- v2: - use of_dma_is_coherent() instead of open-coding. drivers/ata/ahci_qoriq.c | 15 +++ 1 file changed, 11 insertions(+), 4 deletions(-) diff --git a/drivers/ata/ahci_qoriq.c b/drivers/ata/ahci_qoriq.c index 9884c8c..01ef662 100644 --- a/drivers/ata/ahci_qoriq.c +++ b/drivers/ata/ahci_qoriq.c @@ -59,6 +59,7 @@ struct ahci_qoriq_priv { struct ccsr_ahci *reg_base; enum ahci_qoriq_type type; void __iomem *ecc_addr; + bool is_dmacoherent; }; static const struct of_device_id ahci_qoriq_of_match[] = { @@ -164,26 +165,31 @@ static int ahci_qoriq_phy_init(struct ahci_host_priv *hpriv) writel(LS1021A_PORT_PHY4, reg_base + PORT_PHY4); writel(LS1021A_PORT_PHY5, reg_base + PORT_PHY5); writel(AHCI_PORT_TRANS_CFG, reg_base + PORT_TRANS); - writel(AHCI_PORT_AXICC_CFG, reg_base + LS1021A_AXICC_ADDR); + if (qpriv->is_dmacoherent) + writel(AHCI_PORT_AXICC_CFG, + reg_base + LS1021A_AXICC_ADDR); break; case AHCI_LS1043A: writel(AHCI_PORT_PHY_1_CFG, reg_base + PORT_PHY1); writel(AHCI_PORT_TRANS_CFG, reg_base + PORT_TRANS); - writel(AHCI_PORT_AXICC_CFG, reg_base + PORT_AXICC); + if (qpriv->is_dmacoherent) + writel(AHCI_PORT_AXICC_CFG, reg_base + PORT_AXICC); break; case AHCI_LS2080A: writel(AHCI_PORT_PHY_1_CFG, reg_base + PORT_PHY1); writel(AHCI_PORT_TRANS_CFG, reg_base + PORT_TRANS); - writel(AHCI_PORT_AXICC_CFG, reg_base + PORT_AXICC); + if (qpriv->is_dmacoherent) + writel(AHCI_PORT_AXICC_CFG, reg_base + PORT_AXICC); break; case AHCI_LS1046A: writel(LS1046A_SATA_ECC_DIS, qpriv->ecc_addr); writel(AHCI_PORT_PHY_1_CFG, reg_base + PORT_PHY1); writel(AHCI_PORT_TRANS_CFG, reg_base + PORT_TRANS); - writel(AHCI_PORT_AXICC_CFG, reg_base + PORT_AXICC); + if (qpriv->is_dmacoherent) + writel(AHCI_PORT_AXICC_CFG, reg_base + PORT_AXICC); break; } @@ -221,6 +227,7 @@ static int ahci_qoriq_probe(struct platform_device *pdev) if (IS_ERR(qoriq_priv->ecc_addr)) return PTR_ERR(qoriq_priv->ecc_addr); } + qoriq_priv->is_dmacoherent = of_dma_is_coherent(np); rc = ahci_platform_enable_resources(hpriv); if (rc) -- 2.1.0.27.g96db324
[PATCH 2/3 v2] ahci: qoriq: report error when ecc register address is missing in dts
From: Tang Yuantian For ls1021a, and armv8 chasis 2 socs, sata ecc must be disabled. If ecc register is not found in sata node in dts, report error. This is a chip erratum described as bellow: The Read DMA operations get early termination indication from the controller. This issue is observed as CRC error in the status registers. The issue is due to address collision at address 0 in the dual port memory. The read is a dummy read to flush out the header, but due to collision the controller logs the mbit error reported by the ECC check logic. This results in the early termination of the Read DMA operation by the controller. The issue happens to all the interface speeds(GEN1/2/3) for all the products. Workaround: Disable ECC feature on those platforms. Signed-off-by: Tang Yuantian --- v2: - refine the title and description - change reporting warning to reporting error drivers/ata/ahci_qoriq.c | 11 +-- 1 file changed, 9 insertions(+), 2 deletions(-) diff --git a/drivers/ata/ahci_qoriq.c b/drivers/ata/ahci_qoriq.c index 01ef662..137b1c7 100644 --- a/drivers/ata/ahci_qoriq.c +++ b/drivers/ata/ahci_qoriq.c @@ -46,7 +46,7 @@ #define LS1021A_AXICC_ADDR 0xC0 #define SATA_ECC_DISABLE 0x0002 -#define LS1046A_SATA_ECC_DIS 0x8000 +#define ECC_DIS_ARMV8_CH2 0x8000 enum ahci_qoriq_type { AHCI_LS1021A, @@ -158,6 +158,8 @@ static int ahci_qoriq_phy_init(struct ahci_host_priv *hpriv) switch (qpriv->type) { case AHCI_LS1021A: + if (!qpriv->ecc_addr) + return -EINVAL; writel(SATA_ECC_DISABLE, qpriv->ecc_addr); writel(AHCI_PORT_PHY_1_CFG, reg_base + PORT_PHY1); writel(LS1021A_PORT_PHY2, reg_base + PORT_PHY2); @@ -171,6 +173,9 @@ static int ahci_qoriq_phy_init(struct ahci_host_priv *hpriv) break; case AHCI_LS1043A: + if (!qpriv->ecc_addr) + return -EINVAL; + writel(ECC_DIS_ARMV8_CH2, qpriv->ecc_addr); writel(AHCI_PORT_PHY_1_CFG, reg_base + PORT_PHY1); writel(AHCI_PORT_TRANS_CFG, reg_base + PORT_TRANS); if (qpriv->is_dmacoherent) @@ -185,7 +190,9 @@ static int ahci_qoriq_phy_init(struct ahci_host_priv *hpriv) break; case AHCI_LS1046A: - writel(LS1046A_SATA_ECC_DIS, qpriv->ecc_addr); + if (!qpriv->ecc_addr) + return -EINVAL; + writel(ECC_DIS_ARMV8_CH2, qpriv->ecc_addr); writel(AHCI_PORT_PHY_1_CFG, reg_base + PORT_PHY1); writel(AHCI_PORT_TRANS_CFG, reg_base + PORT_TRANS); if (qpriv->is_dmacoherent) -- 2.1.0.27.g96db324
[PATCH 3/3 v2] ahci: qoriq: added ls2088a platforms support
From: Tang Yuantian Ls2088a is new introduced arm-based soc with sata support with following features: 1. Complies with the serial ATA 3.0 specification and the AHCI 1.3.1 specification 2. Contains a high-speed descriptor-based DMA controller 3. Supports the following: a. Speeds of 1.5 Gb/s (first-generation SATA), 3 Gb/s (second-generation SATA), and 6 Gb/s (third-generation SATA) b. FIS-based switching c. Native command queuing (NCQ) commands d. Port multiplier operation e. Asynchronous notification f. SATA BIST mode Signed-off-by: Tang Yuantian --- v2: - no change drivers/ata/ahci_qoriq.c | 9 + 1 file changed, 9 insertions(+) diff --git a/drivers/ata/ahci_qoriq.c b/drivers/ata/ahci_qoriq.c index 137b1c7..85d8332 100644 --- a/drivers/ata/ahci_qoriq.c +++ b/drivers/ata/ahci_qoriq.c @@ -53,6 +53,7 @@ enum ahci_qoriq_type { AHCI_LS1043A, AHCI_LS2080A, AHCI_LS1046A, + AHCI_LS2088A, }; struct ahci_qoriq_priv { @@ -67,6 +68,7 @@ static const struct of_device_id ahci_qoriq_of_match[] = { { .compatible = "fsl,ls1043a-ahci", .data = (void *)AHCI_LS1043A}, { .compatible = "fsl,ls2080a-ahci", .data = (void *)AHCI_LS2080A}, { .compatible = "fsl,ls1046a-ahci", .data = (void *)AHCI_LS1046A}, + { .compatible = "fsl,ls2088a-ahci", .data = (void *)AHCI_LS2088A}, {}, }; MODULE_DEVICE_TABLE(of, ahci_qoriq_of_match); @@ -198,6 +200,13 @@ static int ahci_qoriq_phy_init(struct ahci_host_priv *hpriv) if (qpriv->is_dmacoherent) writel(AHCI_PORT_AXICC_CFG, reg_base + PORT_AXICC); break; + + case AHCI_LS2088A: + writel(AHCI_PORT_PHY_1_CFG, reg_base + PORT_PHY1); + writel(AHCI_PORT_TRANS_CFG, reg_base + PORT_TRANS); + if (qpriv->is_dmacoherent) + writel(AHCI_PORT_AXICC_CFG, reg_base + PORT_AXICC); + break; } return 0; -- 2.1.0.27.g96db324
[PATCH] ahci: qoriq: added ls2088a platforms support
From: Tang Yuantian Ls2088a is new introduced arm-based soc with sata support with following features: 1. Complies with the serial ATA 3.0 specification and the AHCI 1.3.1 specification 2. Contains a high-speed descriptor-based DMA controller 3. Supports the following: a. Speeds of 1.5 Gb/s (first-generation SATA), 3 Gb/s (second-generation SATA), and 6 Gb/s (third-generation SATA) b. FIS-based switching c. Native command queuing (NCQ) commands d. Port multiplier operation e. Asynchronous notification f. SATA BIST mode Signed-off-by: Tang Yuantian --- Documentation/devicetree/bindings/ata/ahci-fsl-qoriq.txt | 2 +- drivers/ata/ahci_qoriq.c | 9 + 2 files changed, 10 insertions(+), 1 deletion(-) diff --git a/Documentation/devicetree/bindings/ata/ahci-fsl-qoriq.txt b/Documentation/devicetree/bindings/ata/ahci-fsl-qoriq.txt index fc33ca0..ed87c6f 100644 --- a/Documentation/devicetree/bindings/ata/ahci-fsl-qoriq.txt +++ b/Documentation/devicetree/bindings/ata/ahci-fsl-qoriq.txt @@ -3,7 +3,7 @@ Binding for Freescale QorIQ AHCI SATA Controller Required properties: - reg: Physical base address and size of the controller's register area. - compatible: Compatibility string. Must be 'fsl,-ahci', where -chip could be ls1021a, ls1043a, ls1046a, ls2080a etc. +chip could be ls1021a, ls1043a, ls1046a, ls2080a, ls2088a etc. - clocks: Input clock specifier. Refer to common clock bindings. - interrupts: Interrupt specifier. Refer to interrupt binding. diff --git a/drivers/ata/ahci_qoriq.c b/drivers/ata/ahci_qoriq.c index 66eb4b5..912fe32 100644 --- a/drivers/ata/ahci_qoriq.c +++ b/drivers/ata/ahci_qoriq.c @@ -53,6 +53,7 @@ enum ahci_qoriq_type { AHCI_LS1043A, AHCI_LS2080A, AHCI_LS1046A, + AHCI_LS2088A, }; struct ahci_qoriq_priv { @@ -67,6 +68,7 @@ static const struct of_device_id ahci_qoriq_of_match[] = { { .compatible = "fsl,ls1043a-ahci", .data = (void *)AHCI_LS1043A}, { .compatible = "fsl,ls2080a-ahci", .data = (void *)AHCI_LS2080A}, { .compatible = "fsl,ls1046a-ahci", .data = (void *)AHCI_LS1046A}, + { .compatible = "fsl,ls2088a-ahci", .data = (void *)AHCI_LS2088A}, {}, }; MODULE_DEVICE_TABLE(of, ahci_qoriq_of_match); @@ -193,6 +195,13 @@ static int ahci_qoriq_phy_init(struct ahci_host_priv *hpriv) if (qpriv->is_dmacoherent) writel(AHCI_PORT_AXICC_CFG, reg_base + PORT_AXICC); break; + + case AHCI_LS2088A: + writel(AHCI_PORT_PHY_1_CFG, reg_base + PORT_PHY1); + writel(AHCI_PORT_TRANS_CFG, reg_base + PORT_TRANS); + if (qpriv->is_dmacoherent) + writel(AHCI_PORT_AXICC_CFG, reg_base + PORT_AXICC); + break; } return 0; -- 2.1.0.27.g96db324
[PATCH v3] clk: qoriq: added ls1012a clock configuration
From: Tang Yuantian Signed-off-by: Tang Yuantian --- v3: - rebased to latest kernel and re-sorted the code v2: - remove commit message as it is duplicated to title drivers/clk/clk-qoriq.c | 19 +++ 1 file changed, 19 insertions(+) diff --git a/drivers/clk/clk-qoriq.c b/drivers/clk/clk-qoriq.c index 7dd4351..697310e 100644 --- a/drivers/clk/clk-qoriq.c +++ b/drivers/clk/clk-qoriq.c @@ -291,6 +291,14 @@ static const struct clockgen_muxinfo ls1046a_hwa2 = { }, }; +static const struct clockgen_muxinfo ls1012a_cmux = { + { + [0] = { CLKSEL_VALID, CGA_PLL1, PLL_DIV1 }, + {}, + [2] = { CLKSEL_VALID, CGA_PLL1, PLL_DIV2 }, + } +}; + static const struct clockgen_muxinfo t1023_hwa1 = { { {}, @@ -529,6 +537,16 @@ static const struct clockgen_chipinfo chipinfo[] = { .flags = CG_PLL_8BIT, }, { + .compat = "fsl,ls1012a-clockgen", + .cmux_groups = { + &ls1012a_cmux + }, + .cmux_to_group = { + 0, -1 + }, + .pll_mask = 0x03, + }, + { .compat = "fsl,ls2080a-clockgen", .cmux_groups = { &clockgen2_cmux_cga12, &clockgen2_cmux_cgb @@ -1316,6 +1334,7 @@ CLK_OF_DECLARE(qoriq_clockgen_2, "fsl,qoriq-clockgen-2.0", clockgen_init); CLK_OF_DECLARE(qoriq_clockgen_ls1021a, "fsl,ls1021a-clockgen", clockgen_init); CLK_OF_DECLARE(qoriq_clockgen_ls1043a, "fsl,ls1043a-clockgen", clockgen_init); CLK_OF_DECLARE(qoriq_clockgen_ls1046a, "fsl,ls1046a-clockgen", clockgen_init); +CLK_OF_DECLARE(qoriq_clockgen_ls1012a, "fsl,ls1012a-clockgen", clockgen_init); CLK_OF_DECLARE(qoriq_clockgen_ls2080a, "fsl,ls2080a-clockgen", clockgen_init); /* Legacy nodes */ -- 2.1.0.27.g96db324
[PATCH v2] clk: qoriq: added ls1012a clock configuration
From: Tang Yuantian Signed-off-by: Tang Yuantian --- v2: - remove commit message as it is duplicated to title drivers/clk/clk-qoriq.c | 19 +++ 1 file changed, 19 insertions(+) diff --git a/drivers/clk/clk-qoriq.c b/drivers/clk/clk-qoriq.c index 1bece0f..65c21d7 100644 --- a/drivers/clk/clk-qoriq.c +++ b/drivers/clk/clk-qoriq.c @@ -202,6 +202,14 @@ static const struct clockgen_muxinfo ls1021a_cmux = { } }; +static const struct clockgen_muxinfo ls1012a_cmux = { + { + [0] = { CLKSEL_VALID, CGA_PLL1, PLL_DIV1 }, + {}, + [2] = { CLKSEL_VALID, CGA_PLL1, PLL_DIV2 }, + } +}; + static const struct clockgen_muxinfo t1040_cmux = { { [0] = { CLKSEL_VALID, CGA_PLL1, PLL_DIV1 }, @@ -482,6 +490,16 @@ static const struct clockgen_chipinfo chipinfo[] = { .pll_mask = 0x03, }, { + .compat = "fsl,ls1012a-clockgen", + .cmux_groups = { + &ls1012a_cmux + }, + .cmux_to_group = { + 0, -1 + }, + .pll_mask = 0x03, + }, + { .compat = "fsl,ls1043a-clockgen", .init_periph = t2080_init_periph, .cmux_groups = { @@ -1282,6 +1300,7 @@ static void __init clockgen_init(struct device_node *np) CLK_OF_DECLARE(qoriq_clockgen_1, "fsl,qoriq-clockgen-1.0", clockgen_init); CLK_OF_DECLARE(qoriq_clockgen_2, "fsl,qoriq-clockgen-2.0", clockgen_init); CLK_OF_DECLARE(qoriq_clockgen_ls1021a, "fsl,ls1021a-clockgen", clockgen_init); +CLK_OF_DECLARE(qoriq_clockgen_ls1012a, "fsl,ls1012a-clockgen", clockgen_init); CLK_OF_DECLARE(qoriq_clockgen_ls1043a, "fsl,ls1043a-clockgen", clockgen_init); CLK_OF_DECLARE(qoriq_clockgen_ls2080a, "fsl,ls2080a-clockgen", clockgen_init); -- 2.1.0.27.g96db324
[PATCH 2/2] arm64: dts: updated sata node on ls1046a dts
From: Tang Yuantian On ls1046a soc, sata ecc should be disabled. So added sata ecc register address so that driver can get this information. Signed-off-by: Tang Yuantian --- arch/arm64/boot/dts/freescale/fsl-ls1046a.dtsi | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/arch/arm64/boot/dts/freescale/fsl-ls1046a.dtsi b/arch/arm64/boot/dts/freescale/fsl-ls1046a.dtsi index 38806ca..88aaaf1 100644 --- a/arch/arm64/boot/dts/freescale/fsl-ls1046a.dtsi +++ b/arch/arm64/boot/dts/freescale/fsl-ls1046a.dtsi @@ -507,7 +507,9 @@ sata: sata@320 { compatible = "fsl,ls1046a-ahci"; - reg = <0x0 0x320 0x0 0x1>; + reg = <0x0 0x320 0x0 0x1>, + <0x0 0x20140520 0x0 0x4>; + reg-names = "ahci", "sata-ecc"; interrupts = ; clocks = <&clockgen 4 1>; }; -- 2.1.0.27.g96db324
[PATCH 1/2] dt-bindings: ahci-fsl-qoriq: added explanation for reg-names
From: Tang Yuantian Added explanation for reg-names to make it more clear. Signed-off-by: Tang Yuantian --- Documentation/devicetree/bindings/ata/ahci-fsl-qoriq.txt | 2 ++ 1 file changed, 2 insertions(+) diff --git a/Documentation/devicetree/bindings/ata/ahci-fsl-qoriq.txt b/Documentation/devicetree/bindings/ata/ahci-fsl-qoriq.txt index fc33ca0..80cf10c 100644 --- a/Documentation/devicetree/bindings/ata/ahci-fsl-qoriq.txt +++ b/Documentation/devicetree/bindings/ata/ahci-fsl-qoriq.txt @@ -10,6 +10,8 @@ Required properties: Optional properties: - dma-coherent: Enable AHCI coherent DMA operation. - reg-names: register area names when there are more than 1 register area. + example: 'ahci' is for sata controller register. +'sata-ecc' is for sata ecc register. Examples: sata@320 { -- 2.1.0.27.g96db324
[PATCH] clk: qoriq: added ls1012a clock configuration
From: Tang Yuantian Added ls1012a clock configuation information. Signed-off-by: Tang Yuantian --- drivers/clk/clk-qoriq.c | 19 +++ 1 file changed, 19 insertions(+) diff --git a/drivers/clk/clk-qoriq.c b/drivers/clk/clk-qoriq.c index 1bece0f..563d874 100644 --- a/drivers/clk/clk-qoriq.c +++ b/drivers/clk/clk-qoriq.c @@ -202,6 +202,14 @@ static const struct clockgen_muxinfo ls1021a_cmux = { } }; +static const struct clockgen_muxinfo ls1012a_cmux = { + { + [0] = { CLKSEL_VALID, CGA_PLL1, PLL_DIV1 }, + {}, + [2] = { CLKSEL_VALID, CGA_PLL1, PLL_DIV2 }, + } +}; + static const struct clockgen_muxinfo t1040_cmux = { { [0] = { CLKSEL_VALID, CGA_PLL1, PLL_DIV1 }, @@ -482,6 +490,16 @@ static const struct clockgen_chipinfo chipinfo[] = { .pll_mask = 0x03, }, { + .compat = "fsl,ls1012a-clockgen", + .cmux_groups = { + &ls1012a_cmux + }, + .cmux_to_group = { + 0, -1 + }, + .pll_mask = 0x03, + }, + { .compat = "fsl,ls1043a-clockgen", .init_periph = t2080_init_periph, .cmux_groups = { @@ -1284,6 +1302,7 @@ CLK_OF_DECLARE(qoriq_clockgen_2, "fsl,qoriq-clockgen-2.0", clockgen_init); CLK_OF_DECLARE(qoriq_clockgen_ls1021a, "fsl,ls1021a-clockgen", clockgen_init); CLK_OF_DECLARE(qoriq_clockgen_ls1043a, "fsl,ls1043a-clockgen", clockgen_init); CLK_OF_DECLARE(qoriq_clockgen_ls2080a, "fsl,ls2080a-clockgen", clockgen_init); +CLK_OF_DECLARE(qoriq_clockgen_ls1012a, "fsl,ls1012a-clockgen", clockgen_init); /* Legacy nodes */ CLK_OF_DECLARE(qoriq_sysclk_1, "fsl,qoriq-sysclk-1.0", sysclk_init); -- 2.1.0.27.g96db324
[PATCH 2/2] ahci: qoriq: report warning when ecc register is missing
From: Tang Yuantian For ls1021a and ls1046a socs, sata ecc must be disabled. If ecc register is not found in sata node in dts, report a warning. Signed-off-by: Tang Yuantian --- drivers/ata/ahci_qoriq.c | 2 ++ 1 file changed, 2 insertions(+) diff --git a/drivers/ata/ahci_qoriq.c b/drivers/ata/ahci_qoriq.c index 45c88de..66eb4b5 100644 --- a/drivers/ata/ahci_qoriq.c +++ b/drivers/ata/ahci_qoriq.c @@ -158,6 +158,7 @@ static int ahci_qoriq_phy_init(struct ahci_host_priv *hpriv) switch (qpriv->type) { case AHCI_LS1021A: + WARN_ON(!qpriv->ecc_addr); writel(SATA_ECC_DISABLE, qpriv->ecc_addr); writel(AHCI_PORT_PHY_1_CFG, reg_base + PORT_PHY1); writel(LS1021A_PORT_PHY2, reg_base + PORT_PHY2); @@ -185,6 +186,7 @@ static int ahci_qoriq_phy_init(struct ahci_host_priv *hpriv) break; case AHCI_LS1046A: + WARN_ON(!qpriv->ecc_addr); writel(LS1046A_SATA_ECC_DIS, qpriv->ecc_addr); writel(AHCI_PORT_PHY_1_CFG, reg_base + PORT_PHY1); writel(AHCI_PORT_TRANS_CFG, reg_base + PORT_TRANS); -- 2.1.0.27.g96db324
[PATCH 1/2] ahci: qoriq: added a condition to enable dma coherence
From: Tang Yuantian Enable DMA coherence in SATA controller on condition that dma-coherent property exists in sata node in DTS. Signed-off-by: Tang Yuantian --- drivers/ata/ahci_qoriq.c | 15 +++ 1 file changed, 11 insertions(+), 4 deletions(-) diff --git a/drivers/ata/ahci_qoriq.c b/drivers/ata/ahci_qoriq.c index 9884c8c..45c88de 100644 --- a/drivers/ata/ahci_qoriq.c +++ b/drivers/ata/ahci_qoriq.c @@ -59,6 +59,7 @@ struct ahci_qoriq_priv { struct ccsr_ahci *reg_base; enum ahci_qoriq_type type; void __iomem *ecc_addr; + bool is_dmacoherent; }; static const struct of_device_id ahci_qoriq_of_match[] = { @@ -164,26 +165,31 @@ static int ahci_qoriq_phy_init(struct ahci_host_priv *hpriv) writel(LS1021A_PORT_PHY4, reg_base + PORT_PHY4); writel(LS1021A_PORT_PHY5, reg_base + PORT_PHY5); writel(AHCI_PORT_TRANS_CFG, reg_base + PORT_TRANS); - writel(AHCI_PORT_AXICC_CFG, reg_base + LS1021A_AXICC_ADDR); + if (qpriv->is_dmacoherent) + writel(AHCI_PORT_AXICC_CFG, + reg_base + LS1021A_AXICC_ADDR); break; case AHCI_LS1043A: writel(AHCI_PORT_PHY_1_CFG, reg_base + PORT_PHY1); writel(AHCI_PORT_TRANS_CFG, reg_base + PORT_TRANS); - writel(AHCI_PORT_AXICC_CFG, reg_base + PORT_AXICC); + if (qpriv->is_dmacoherent) + writel(AHCI_PORT_AXICC_CFG, reg_base + PORT_AXICC); break; case AHCI_LS2080A: writel(AHCI_PORT_PHY_1_CFG, reg_base + PORT_PHY1); writel(AHCI_PORT_TRANS_CFG, reg_base + PORT_TRANS); - writel(AHCI_PORT_AXICC_CFG, reg_base + PORT_AXICC); + if (qpriv->is_dmacoherent) + writel(AHCI_PORT_AXICC_CFG, reg_base + PORT_AXICC); break; case AHCI_LS1046A: writel(LS1046A_SATA_ECC_DIS, qpriv->ecc_addr); writel(AHCI_PORT_PHY_1_CFG, reg_base + PORT_PHY1); writel(AHCI_PORT_TRANS_CFG, reg_base + PORT_TRANS); - writel(AHCI_PORT_AXICC_CFG, reg_base + PORT_AXICC); + if (qpriv->is_dmacoherent) + writel(AHCI_PORT_AXICC_CFG, reg_base + PORT_AXICC); break; } @@ -221,6 +227,7 @@ static int ahci_qoriq_probe(struct platform_device *pdev) if (IS_ERR(qoriq_priv->ecc_addr)) return PTR_ERR(qoriq_priv->ecc_addr); } + qoriq_priv->is_dmacoherent = of_property_read_bool(np, "dma-coherent"); rc = ahci_platform_enable_resources(hpriv); if (rc) -- 2.1.0.27.g96db324
[PATCH] ahci: qoriq: added ls1046a platform support
From: Tang Yuantian Ls1046a is a new introduced soc which supports ATA3.0. Signed-off-by: Tang Yuantian --- drivers/ata/ahci_qoriq.c | 16 +--- 1 file changed, 13 insertions(+), 3 deletions(-) diff --git a/drivers/ata/ahci_qoriq.c b/drivers/ata/ahci_qoriq.c index 1eba8df..9884c8c 100644 --- a/drivers/ata/ahci_qoriq.c +++ b/drivers/ata/ahci_qoriq.c @@ -46,11 +46,13 @@ #define LS1021A_AXICC_ADDR 0xC0 #define SATA_ECC_DISABLE 0x0002 +#define LS1046A_SATA_ECC_DIS 0x8000 enum ahci_qoriq_type { AHCI_LS1021A, AHCI_LS1043A, AHCI_LS2080A, + AHCI_LS1046A, }; struct ahci_qoriq_priv { @@ -63,6 +65,7 @@ static const struct of_device_id ahci_qoriq_of_match[] = { { .compatible = "fsl,ls1021a-ahci", .data = (void *)AHCI_LS1021A}, { .compatible = "fsl,ls1043a-ahci", .data = (void *)AHCI_LS1043A}, { .compatible = "fsl,ls2080a-ahci", .data = (void *)AHCI_LS2080A}, + { .compatible = "fsl,ls1046a-ahci", .data = (void *)AHCI_LS1046A}, {}, }; MODULE_DEVICE_TABLE(of, ahci_qoriq_of_match); @@ -175,6 +178,13 @@ static int ahci_qoriq_phy_init(struct ahci_host_priv *hpriv) writel(AHCI_PORT_TRANS_CFG, reg_base + PORT_TRANS); writel(AHCI_PORT_AXICC_CFG, reg_base + PORT_AXICC); break; + + case AHCI_LS1046A: + writel(LS1046A_SATA_ECC_DIS, qpriv->ecc_addr); + writel(AHCI_PORT_PHY_1_CFG, reg_base + PORT_PHY1); + writel(AHCI_PORT_TRANS_CFG, reg_base + PORT_TRANS); + writel(AHCI_PORT_AXICC_CFG, reg_base + PORT_AXICC); + break; } return 0; @@ -204,9 +214,9 @@ static int ahci_qoriq_probe(struct platform_device *pdev) qoriq_priv->type = (enum ahci_qoriq_type)of_id->data; - if (qoriq_priv->type == AHCI_LS1021A) { - res = platform_get_resource_byname(pdev, IORESOURCE_MEM, - "sata-ecc"); + res = platform_get_resource_byname(pdev, IORESOURCE_MEM, + "sata-ecc"); + if (res) { qoriq_priv->ecc_addr = devm_ioremap_resource(dev, res); if (IS_ERR(qoriq_priv->ecc_addr)) return PTR_ERR(qoriq_priv->ecc_addr); -- 2.1.0.27.g96db324
[PATCH] clk: qoriq: fix a register offset error
From: Tang Yuantian The offset of Core Cluster clock control/status register on cluster group V3 version is different from others, and should be plus 0x7. Signed-off-by: Tang Yuantian --- drivers/clk/clk-qoriq.c | 6 +- 1 file changed, 5 insertions(+), 1 deletion(-) diff --git a/drivers/clk/clk-qoriq.c b/drivers/clk/clk-qoriq.c index f4c455a..05e416c 100644 --- a/drivers/clk/clk-qoriq.c +++ b/drivers/clk/clk-qoriq.c @@ -774,7 +774,11 @@ static struct clk * __init create_one_cmux(struct clockgen *cg, int idx) if (!hwc) return NULL; - hwc->reg = cg->regs + 0x20 * idx; + if (cg->info.flags & CG_VER3) + hwc->reg = cg->regs + 0x7 + 0x20 * idx; + else + hwc->reg = cg->regs + 0x20 * idx; + hwc->info = cg->info.cmux_groups[cg->info.cmux_to_group[idx]]; /* -- 2.1.0.27.g96db324
[PATCH] clk: qoriq: added the third frequency support on ls1021a
From: Tang Yuantian ls1021a CPU can work on three different clock frequency. Currently, the third one is missing. This patch added it. Signed-off-by: Tang Yuantian --- drivers/clk/clk-qoriq.c | 10 +- 1 file changed, 9 insertions(+), 1 deletion(-) diff --git a/drivers/clk/clk-qoriq.c b/drivers/clk/clk-qoriq.c index 7bc1c45..2a9d952 100644 --- a/drivers/clk/clk-qoriq.c +++ b/drivers/clk/clk-qoriq.c @@ -194,6 +194,14 @@ static const struct clockgen_muxinfo t1023_cmux = { } }; +static const struct clockgen_muxinfo ls1021a_cmux = { + { + [0] = { CLKSEL_VALID, CGA_PLL1, PLL_DIV1 }, + [1] = { CLKSEL_VALID, CGA_PLL1, PLL_DIV2 }, + [2] = { CLKSEL_VALID, CGA_PLL1, PLL_DIV4 }, + } +}; + static const struct clockgen_muxinfo t1040_cmux = { { [0] = { CLKSEL_VALID, CGA_PLL1, PLL_DIV1 }, @@ -466,7 +474,7 @@ static const struct clockgen_chipinfo chipinfo[] = { { .compat = "fsl,ls1021a-clockgen", .cmux_groups = { - &t1023_cmux + &ls1021a_cmux }, .cmux_to_group = { 0, -1 -- 2.1.0.27.g96db324
[PATCH] ahci: qoriq: Adjust the default register values on ls1021a
From: Tang Yuantian Updated the registers' values to enhance SATA performance and reliability on ls1021a soc. Signed-off-by: Tang Yuantian --- drivers/ata/ahci_qoriq.c | 24 ++-- 1 file changed, 14 insertions(+), 10 deletions(-) diff --git a/drivers/ata/ahci_qoriq.c b/drivers/ata/ahci_qoriq.c index 256d911..7bdee9b 100644 --- a/drivers/ata/ahci_qoriq.c +++ b/drivers/ata/ahci_qoriq.c @@ -34,16 +34,20 @@ /* port register default value */ #define AHCI_PORT_PHY_1_CFG0xa003fffe -#define AHCI_PORT_PHY_2_CFG0x28183411 -#define AHCI_PORT_PHY_3_CFG0x0e081004 -#define AHCI_PORT_PHY_4_CFG0x00480811 -#define AHCI_PORT_PHY_5_CFG0x192c96a4 #define AHCI_PORT_TRANS_CFG0x0829 -#define LS1043A_PORT_PHY2 0x28184d1f -#define LS1043A_PORT_PHY3 0x0e081509 + +/* for ls1021a */ +#define LS1021A_PORT_PHY2 0x28183414 +#define LS1021A_PORT_PHY3 0x0e080e06 +#define LS1021A_PORT_PHY4 0x064a080b +#define LS1021A_PORT_PHY5 0x2aa86470 #define SATA_ECC_DISABLE 0x0002 +/* for ls1043a */ +#define LS1043A_PORT_PHY2 0x28184d1f +#define LS1043A_PORT_PHY3 0x0e081509 + enum ahci_qoriq_type { AHCI_LS1021A, AHCI_LS1043A, @@ -153,10 +157,10 @@ static int ahci_qoriq_phy_init(struct ahci_host_priv *hpriv) case AHCI_LS1021A: writel(SATA_ECC_DISABLE, qpriv->ecc_addr); writel(AHCI_PORT_PHY_1_CFG, reg_base + PORT_PHY1); - writel(AHCI_PORT_PHY_2_CFG, reg_base + PORT_PHY2); - writel(AHCI_PORT_PHY_3_CFG, reg_base + PORT_PHY3); - writel(AHCI_PORT_PHY_4_CFG, reg_base + PORT_PHY4); - writel(AHCI_PORT_PHY_5_CFG, reg_base + PORT_PHY5); + writel(LS1021A_PORT_PHY2, reg_base + PORT_PHY2); + writel(LS1021A_PORT_PHY3, reg_base + PORT_PHY3); + writel(LS1021A_PORT_PHY4, reg_base + PORT_PHY4); + writel(LS1021A_PORT_PHY5, reg_base + PORT_PHY5); writel(AHCI_PORT_TRANS_CFG, reg_base + PORT_TRANS); break; -- 2.1.0.27.g96db324 -- To unsubscribe from this list: send the line "unsubscribe linux-kernel" in the body of a message to majord...@vger.kernel.org More majordomo info at http://vger.kernel.org/majordomo-info.html Please read the FAQ at http://www.tux.org/lkml/
[PATCH 2/2] ahci: qoriq: Update the default Rx watermark value
From: Tang Yuantian The PTC[RXWM] sets the watermark value for Rx FIFO. The default value 0x20 might be insufficient for some hard drives. If the watermark value is too small, a single-cycle overflow may occur and is reported as a CRC or internal error in the PxSERR register. Updated the value to 0x29 according to the validation test. All LS platforms are affected. Signed-off-by: Tang Yuantian --- drivers/ata/ahci_qoriq.c | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/drivers/ata/ahci_qoriq.c b/drivers/ata/ahci_qoriq.c index 4d613f8..256d911 100644 --- a/drivers/ata/ahci_qoriq.c +++ b/drivers/ata/ahci_qoriq.c @@ -38,7 +38,7 @@ #define AHCI_PORT_PHY_3_CFG0x0e081004 #define AHCI_PORT_PHY_4_CFG0x00480811 #define AHCI_PORT_PHY_5_CFG0x192c96a4 -#define AHCI_PORT_TRANS_CFG0x0825 +#define AHCI_PORT_TRANS_CFG0x0829 #define LS1043A_PORT_PHY2 0x28184d1f #define LS1043A_PORT_PHY3 0x0e081509 @@ -169,6 +169,7 @@ static int ahci_qoriq_phy_init(struct ahci_host_priv *hpriv) case AHCI_LS2080A: writel(AHCI_PORT_PHY_1_CFG, reg_base + PORT_PHY1); + writel(AHCI_PORT_TRANS_CFG, reg_base + PORT_TRANS); break; } -- 2.1.0.27.g96db324 -- To unsubscribe from this list: send the line "unsubscribe linux-kernel" in the body of a message to majord...@vger.kernel.org More majordomo info at http://vger.kernel.org/majordomo-info.html Please read the FAQ at http://www.tux.org/lkml/
[PATCH 1/2] ahci: qoriq: Adjust the default register values on ls1043a
From: Tang Yuantian Updated the registers' values to enhance SATA performance and reliability. Signed-off-by: Tang Yuantian --- drivers/ata/ahci_qoriq.c | 8 1 file changed, 8 insertions(+) diff --git a/drivers/ata/ahci_qoriq.c b/drivers/ata/ahci_qoriq.c index d0f9de9..4d613f8 100644 --- a/drivers/ata/ahci_qoriq.c +++ b/drivers/ata/ahci_qoriq.c @@ -39,6 +39,8 @@ #define AHCI_PORT_PHY_4_CFG0x00480811 #define AHCI_PORT_PHY_5_CFG0x192c96a4 #define AHCI_PORT_TRANS_CFG0x0825 +#define LS1043A_PORT_PHY2 0x28184d1f +#define LS1043A_PORT_PHY3 0x0e081509 #define SATA_ECC_DISABLE 0x0002 @@ -159,6 +161,12 @@ static int ahci_qoriq_phy_init(struct ahci_host_priv *hpriv) break; case AHCI_LS1043A: + writel(AHCI_PORT_PHY_1_CFG, reg_base + PORT_PHY1); + writel(LS1043A_PORT_PHY2, reg_base + PORT_PHY2); + writel(LS1043A_PORT_PHY3, reg_base + PORT_PHY3); + writel(AHCI_PORT_TRANS_CFG, reg_base + PORT_TRANS); + break; + case AHCI_LS2080A: writel(AHCI_PORT_PHY_1_CFG, reg_base + PORT_PHY1); break; -- 2.1.0.27.g96db324 -- To unsubscribe from this list: send the line "unsubscribe linux-kernel" in the body of a message to majord...@vger.kernel.org More majordomo info at http://vger.kernel.org/majordomo-info.html Please read the FAQ at http://www.tux.org/lkml/
[PATCH v3] ahci: qoriq: fixed using uninitialized variable warnings
From: Tang Yuantian kbuild test robot reports the warnings: drivers/ata/ahci_qoriq.c: In function 'ahci_qoriq_hardreset': >> include/asm-generic/io.h:163:2: warning: 'px_is' may be used >> uninitialized in this function [-Wuninitialized] drivers/ata/ahci_qoriq.c:70:14: note: 'px_is' was declared here >> include/asm-generic/io.h:163:2: warning: 'px_cmd' may be used >> uninitialized in this function [-Wuninitialized] drivers/ata/ahci_qoriq.c:70:6: note: 'px_cmd' was declared here This is caused by openrisc arch's compiler. This driver is for QorIQ ARM platforms. So add the dependency on ARM to remove these warnings. Signed-off-by: Tang Yuantian --- v3: - fix it by in a new way v2: - try another way to fix the warnings - remove clean up code drivers/ata/Kconfig | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/drivers/ata/Kconfig b/drivers/ata/Kconfig index 6aaa3f8..a830344 100644 --- a/drivers/ata/Kconfig +++ b/drivers/ata/Kconfig @@ -177,7 +177,7 @@ config AHCI_XGENE config AHCI_QORIQ tristate "Freescale QorIQ AHCI SATA support" - depends on OF + depends on OF && ARM help This option enables support for the Freescale QorIQ AHCI SoC's onboard AHCI SATA. -- 2.1.0.27.g96db324 -- To unsubscribe from this list: send the line "unsubscribe linux-kernel" in the body of a message to majord...@vger.kernel.org More majordomo info at http://vger.kernel.org/majordomo-info.html Please read the FAQ at http://www.tux.org/lkml/
[PATCH v2] ahci: qoriq: fixed using uninitialized variable warnings
From: Tang Yuantian kbuild test robot reports the warnings: drivers/ata/ahci_qoriq.c: In function 'ahci_qoriq_hardreset': >> include/asm-generic/io.h:163:2: warning: 'px_is' may be used >> uninitialized in this function [-Wuninitialized] drivers/ata/ahci_qoriq.c:70:14: note: 'px_is' was declared here >> include/asm-generic/io.h:163:2: warning: 'px_cmd' may be used >> uninitialized in this function [-Wuninitialized] drivers/ata/ahci_qoriq.c:70:6: note: 'px_cmd' was declared here This patch fixed it by making type as a local variable. Signed-off-by: Tang Yuantian --- v2: - try another way to fix the warnings - remove clean up code drivers/ata/ahci_qoriq.c | 13 ++--- 1 file changed, 6 insertions(+), 7 deletions(-) diff --git a/drivers/ata/ahci_qoriq.c b/drivers/ata/ahci_qoriq.c index e5e4988..0d06e76 100644 --- a/drivers/ata/ahci_qoriq.c +++ b/drivers/ata/ahci_qoriq.c @@ -48,9 +48,9 @@ enum ahci_qoriq_type { AHCI_LS2085A, }; +enum ahci_qoriq_type type; struct ahci_qoriq_priv { struct ccsr_ahci *reg_base; - enum ahci_qoriq_type type; void __iomem *ecc_addr; }; @@ -71,7 +71,6 @@ static int ahci_qoriq_hardreset(struct ata_link *link, unsigned int *class, struct ata_port *ap = link->ap; struct ahci_port_priv *pp = ap->private_data; struct ahci_host_priv *hpriv = ap->host->private_data; - struct ahci_qoriq_priv *qoriq_priv = hpriv->plat_data; u8 *d2h_fis = pp->rx_fis + RX_FIS_D2H_REG; struct ata_taskfile tf; bool online; @@ -92,7 +91,7 @@ static int ahci_qoriq_hardreset(struct ata_link *link, unsigned int *class, * After the sequence is complete, software should restore the * PxCMD and PxIS with the stored values. */ - if (qoriq_priv->type == AHCI_LS1021A) { + if (type == AHCI_LS1021A) { px_cmd = readl(port_mmio + PORT_CMD); px_is = readl(port_mmio + PORT_IRQ_STAT); } @@ -106,7 +105,7 @@ static int ahci_qoriq_hardreset(struct ata_link *link, unsigned int *class, ahci_check_ready); /* restore the PxCMD and PxIS on ls1021 */ - if (qoriq_priv->type == AHCI_LS1021A) { + if (type == AHCI_LS1021A) { px_val = readl(port_mmio + PORT_CMD); if (px_val != px_cmd) writel(px_cmd, port_mmio + PORT_CMD); @@ -146,7 +145,7 @@ static int ahci_qoriq_phy_init(struct ahci_host_priv *hpriv) struct ahci_qoriq_priv *qpriv = hpriv->plat_data; void __iomem *reg_base = hpriv->mmio; - switch (qpriv->type) { + switch (type) { case AHCI_LS1021A: writel(SATA_ECC_DISABLE, qpriv->ecc_addr); writel(AHCI_PORT_PHY_1_CFG, reg_base + PORT_PHY1); @@ -188,9 +187,9 @@ static int ahci_qoriq_probe(struct platform_device *pdev) if (!qoriq_priv) return -ENOMEM; - qoriq_priv->type = (enum ahci_qoriq_type)of_id->data; + type = (enum ahci_qoriq_type)of_id->data; - if (qoriq_priv->type == AHCI_LS1021A) { + if (type == AHCI_LS1021A) { res = platform_get_resource_byname(pdev, IORESOURCE_MEM, "sata-ecc"); qoriq_priv->ecc_addr = devm_ioremap_resource(dev, res); -- 2.1.0.27.g96db324 -- To unsubscribe from this list: send the line "unsubscribe linux-kernel" in the body of a message to majord...@vger.kernel.org More majordomo info at http://vger.kernel.org/majordomo-info.html Please read the FAQ at http://www.tux.org/lkml/
[PATCH] ahci: qoriq: fixed using uninitialized variable warnings
From: Tang Yuantian kbuild test robot reports the warnings: drivers/ata/ahci_qoriq.c: In function 'ahci_qoriq_hardreset': >> include/asm-generic/io.h:163:2: warning: 'px_is' may be used >> uninitialized in this function [-Wuninitialized] drivers/ata/ahci_qoriq.c:70:14: note: 'px_is' was declared here >> include/asm-generic/io.h:163:2: warning: 'px_cmd' may be used >> uninitialized in this function [-Wuninitialized] drivers/ata/ahci_qoriq.c:70:6: note: 'px_cmd' was declared here This patch fixed it by assigning 0 to px_is and px_cmd variables. This patch also remove line 'struct ccsr_ahci *reg_base' which is not referred by any other codes and thus a dead one. Signed-off-by: Tang Yuantian --- drivers/ata/ahci_qoriq.c | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/drivers/ata/ahci_qoriq.c b/drivers/ata/ahci_qoriq.c index e5e4988..f790852 100644 --- a/drivers/ata/ahci_qoriq.c +++ b/drivers/ata/ahci_qoriq.c @@ -49,7 +49,6 @@ enum ahci_qoriq_type { }; struct ahci_qoriq_priv { - struct ccsr_ahci *reg_base; enum ahci_qoriq_type type; void __iomem *ecc_addr; }; @@ -67,7 +66,7 @@ static int ahci_qoriq_hardreset(struct ata_link *link, unsigned int *class, { const unsigned long *timing = sata_ehc_deb_timing(&link->eh_context); void __iomem *port_mmio = ahci_port_base(link->ap); - u32 px_cmd, px_is, px_val; + u32 px_cmd = 0, px_is = 0, px_val; struct ata_port *ap = link->ap; struct ahci_port_priv *pp = ap->private_data; struct ahci_host_priv *hpriv = ap->host->private_data; -- 2.1.0.27.g96db324 -- To unsubscribe from this list: send the line "unsubscribe linux-kernel" in the body of a message to majord...@vger.kernel.org More majordomo info at http://vger.kernel.org/majordomo-info.html Please read the FAQ at http://www.tux.org/lkml/
[PATCH 1/3] Revert "ahci: added support for Freescale AHCI sata"
From: Tang Yuantian This reverts commit 5163fb62541e ("ahci: added support for Freescale AHCI sata") The reverted patch added Freescale QorIQ AHCI sata support to ahci_platform driver though, but it left SoC specific settings to uboot. It leads to QorIQ sata heavily depending on uboot. In order to removing the dependency we first revert the old patch and then will add a new driver for QorIQ SATA. Since there are no LS* platforms that have been upstreamed, So the revert would not break anything exists. Signed-off-by: Tang Yuantian --- Documentation/devicetree/bindings/ata/ahci-platform.txt | 2 -- drivers/ata/ahci_platform.c | 1 - 2 files changed, 3 deletions(-) diff --git a/Documentation/devicetree/bindings/ata/ahci-platform.txt b/Documentation/devicetree/bindings/ata/ahci-platform.txt index a232181..c2340ee 100644 --- a/Documentation/devicetree/bindings/ata/ahci-platform.txt +++ b/Documentation/devicetree/bindings/ata/ahci-platform.txt @@ -16,8 +16,6 @@ Required properties: - "snps,dwc-ahci" - "snps,exynos5440-ahci" - "snps,spear-ahci" - - "fsl,qoriq-ahci" : for qoriq series socs which include ls1021, ls2085, etc. - - "fsl,-ahci" : chip could be ls1021, ls2085 etc. - "generic-ahci" - interrupts: - reg : diff --git a/drivers/ata/ahci_platform.c b/drivers/ata/ahci_platform.c index 1befb11..04975b8 100644 --- a/drivers/ata/ahci_platform.c +++ b/drivers/ata/ahci_platform.c @@ -76,7 +76,6 @@ static const struct of_device_id ahci_of_match[] = { { .compatible = "ibm,476gtr-ahci", }, { .compatible = "snps,dwc-ahci", }, { .compatible = "hisilicon,hisi-ahci", }, - { .compatible = "fsl,qoriq-ahci", }, {}, }; MODULE_DEVICE_TABLE(of, ahci_of_match); -- 2.1.0.27.g96db324 -- To unsubscribe from this list: send the line "unsubscribe linux-kernel" in the body of a message to majord...@vger.kernel.org More majordomo info at http://vger.kernel.org/majordomo-info.html Please read the FAQ at http://www.tux.org/lkml/
[PATCH 3/3 v2] ahci: added a new driver for supporting Freescale AHCI sata
From: Tang Yuantian Currently Freescale QorIQ series SATA is supported by ahci_platform driver. Some SoC specific settings have been put in uboot. So whether SATA works or not heavily depends on uboot. This patch will add a new driver to support QorIQ sata which removes the dependency on any other boot loader. Freescale QorIQ series sata, like ls1021a ls2085a ls1043a, is compatible with serial ATA 3.0 and AHCI 1.3 specification. Signed-off-by: Yuantian Tang --- v2: - address Hans' comments drivers/ata/Kconfig | 9 ++ drivers/ata/Makefile | 1 + drivers/ata/ahci_qoriq.c | 272 +++ 3 files changed, 282 insertions(+) create mode 100644 drivers/ata/ahci_qoriq.c diff --git a/drivers/ata/Kconfig b/drivers/ata/Kconfig index 15e40ee..6aaa3f8 100644 --- a/drivers/ata/Kconfig +++ b/drivers/ata/Kconfig @@ -175,6 +175,15 @@ config AHCI_XGENE help This option enables support for APM X-Gene SoC SATA host controller. +config AHCI_QORIQ + tristate "Freescale QorIQ AHCI SATA support" + depends on OF + help + This option enables support for the Freescale QorIQ AHCI SoC's + onboard AHCI SATA. + + If unsure, say N. + config SATA_FSL tristate "Freescale 3.0Gbps SATA support" depends on FSL_SOC diff --git a/drivers/ata/Makefile b/drivers/ata/Makefile index af70919..af45eff 100644 --- a/drivers/ata/Makefile +++ b/drivers/ata/Makefile @@ -19,6 +19,7 @@ obj-$(CONFIG_AHCI_SUNXI) += ahci_sunxi.o libahci.o libahci_platform.o obj-$(CONFIG_AHCI_ST) += ahci_st.o libahci.o libahci_platform.o obj-$(CONFIG_AHCI_TEGRA) += ahci_tegra.o libahci.o libahci_platform.o obj-$(CONFIG_AHCI_XGENE) += ahci_xgene.o libahci.o libahci_platform.o +obj-$(CONFIG_AHCI_QORIQ) += ahci_qoriq.o libahci.o libahci_platform.o # SFF w/ custom DMA obj-$(CONFIG_PDC_ADMA) += pdc_adma.o diff --git a/drivers/ata/ahci_qoriq.c b/drivers/ata/ahci_qoriq.c new file mode 100644 index 000..e5e4988 --- /dev/null +++ b/drivers/ata/ahci_qoriq.c @@ -0,0 +1,272 @@ +/* + * Freescale QorIQ AHCI SATA platform driver + * + * Copyright 2015 Freescale, Inc. + * Tang Yuantian + * + * 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, or (at your option) + * any later version. + */ + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include "ahci.h" + +#define DRV_NAME "ahci-qoriq" + +/* port register definition */ +#define PORT_PHY1 0xA8 +#define PORT_PHY2 0xAC +#define PORT_PHY3 0xB0 +#define PORT_PHY4 0xB4 +#define PORT_PHY5 0xB8 +#define PORT_TRANS 0xC8 + +/* port register default value */ +#define AHCI_PORT_PHY_1_CFG0xa003fffe +#define AHCI_PORT_PHY_2_CFG0x28183411 +#define AHCI_PORT_PHY_3_CFG0x0e081004 +#define AHCI_PORT_PHY_4_CFG0x00480811 +#define AHCI_PORT_PHY_5_CFG0x192c96a4 +#define AHCI_PORT_TRANS_CFG0x0825 + +#define SATA_ECC_DISABLE 0x0002 + +enum ahci_qoriq_type { + AHCI_LS1021A, + AHCI_LS1043A, + AHCI_LS2085A, +}; + +struct ahci_qoriq_priv { + struct ccsr_ahci *reg_base; + enum ahci_qoriq_type type; + void __iomem *ecc_addr; +}; + +static const struct of_device_id ahci_qoriq_of_match[] = { + { .compatible = "fsl,ls1021a-ahci", .data = (void *)AHCI_LS1021A}, + { .compatible = "fsl,ls1043a-ahci", .data = (void *)AHCI_LS1043A}, + { .compatible = "fsl,ls2085a-ahci", .data = (void *)AHCI_LS2085A}, + {}, +}; +MODULE_DEVICE_TABLE(of, ahci_qoriq_of_match); + +static int ahci_qoriq_hardreset(struct ata_link *link, unsigned int *class, + unsigned long deadline) +{ + const unsigned long *timing = sata_ehc_deb_timing(&link->eh_context); + void __iomem *port_mmio = ahci_port_base(link->ap); + u32 px_cmd, px_is, px_val; + struct ata_port *ap = link->ap; + struct ahci_port_priv *pp = ap->private_data; + struct ahci_host_priv *hpriv = ap->host->private_data; + struct ahci_qoriq_priv *qoriq_priv = hpriv->plat_data; + u8 *d2h_fis = pp->rx_fis + RX_FIS_D2H_REG; + struct ata_taskfile tf; + bool online; + int rc; + + DPRINTK("ENTER\n"); + + ahci_stop_engine(ap); + + /* +* There is a errata on ls1021a Rev1.0 and Rev2.0 which is: +* A-009042: The device detection initialization sequence +* mistakenly resets some registers. +* +* Workaround for this is: +* The software should read and store PxCMD and PxIS values +* before issuing the device detection initialization sequence. +* After the sequence is complete, software should restore the +* PxCMD and PxIS with the stored values. +*/ +
[PATCH 2/3] devicetree:bindings: add devicetree bindings for Freescale AHCI
From: Tang Yuantian adds bindings for Freescale QorIQ AHCI SATA controller. Signed-off-by: Tang Yuantian --- .../devicetree/bindings/ata/ahci-fsl-qoriq.txt | 21 + 1 file changed, 21 insertions(+) create mode 100644 Documentation/devicetree/bindings/ata/ahci-fsl-qoriq.txt diff --git a/Documentation/devicetree/bindings/ata/ahci-fsl-qoriq.txt b/Documentation/devicetree/bindings/ata/ahci-fsl-qoriq.txt new file mode 100644 index 000..b614e3b --- /dev/null +++ b/Documentation/devicetree/bindings/ata/ahci-fsl-qoriq.txt @@ -0,0 +1,21 @@ +Binding for Freescale QorIQ AHCI SATA Controller + +Required properties: + - reg: Physical base address and size of the controller's register area. + - compatible: Compatibility string. Must be 'fsl,-ahci', where +chip could be ls1021a, ls2085a, ls1043a etc. + - clocks: Input clock specifier. Refer to common clock bindings. + - interrupts: Interrupt specifier. Refer to interrupt binding. + +Optional properties: + - dma-coherent: Enable ACHI coherency DMA operation. + - reg-names: register area names when there are more then 1 regster area. + +Examples: + sata@320 { + compatible = "fsl,ls1021a-ahci"; + reg = <0x0 0x320 0x0 0x1>; + interrupts = ; + clocks = <&platform_clk 1>; + dma-coherent; + }; -- 2.1.0.27.g96db324 -- To unsubscribe from this list: send the line "unsubscribe linux-kernel" in the body of a message to majord...@vger.kernel.org More majordomo info at http://vger.kernel.org/majordomo-info.html Please read the FAQ at http://www.tux.org/lkml/
[PATCH] ahci: added a new driver for supporting Freescale AHCI sata
From: Tang Yuantian Currently Freescale QorIQ series SATA is supported by ahci_platform driver. Some SoC specific settings have been put in uboot. So whether SATA works or not heavily depends on uboot. This patch will add a new driver to support QorIQ sata which removes the dependency on any other boot loader. Freescale QorIQ series sata, like ls1021a ls2085a ls1043a, is compatible with serial ATA 3.0 and AHCI 1.3 specification. Signed-off-by: Yuantian Tang --- drivers/ata/Kconfig | 9 ++ drivers/ata/Makefile| 1 + drivers/ata/ahci_platform.c | 1 - drivers/ata/ahci_qoriq.c| 308 4 files changed, 318 insertions(+), 1 deletion(-) create mode 100644 drivers/ata/ahci_qoriq.c diff --git a/drivers/ata/Kconfig b/drivers/ata/Kconfig index 15e40ee..6aaa3f8 100644 --- a/drivers/ata/Kconfig +++ b/drivers/ata/Kconfig @@ -175,6 +175,15 @@ config AHCI_XGENE help This option enables support for APM X-Gene SoC SATA host controller. +config AHCI_QORIQ + tristate "Freescale QorIQ AHCI SATA support" + depends on OF + help + This option enables support for the Freescale QorIQ AHCI SoC's + onboard AHCI SATA. + + If unsure, say N. + config SATA_FSL tristate "Freescale 3.0Gbps SATA support" depends on FSL_SOC diff --git a/drivers/ata/Makefile b/drivers/ata/Makefile index af70919..af45eff 100644 --- a/drivers/ata/Makefile +++ b/drivers/ata/Makefile @@ -19,6 +19,7 @@ obj-$(CONFIG_AHCI_SUNXI) += ahci_sunxi.o libahci.o libahci_platform.o obj-$(CONFIG_AHCI_ST) += ahci_st.o libahci.o libahci_platform.o obj-$(CONFIG_AHCI_TEGRA) += ahci_tegra.o libahci.o libahci_platform.o obj-$(CONFIG_AHCI_XGENE) += ahci_xgene.o libahci.o libahci_platform.o +obj-$(CONFIG_AHCI_QORIQ) += ahci_qoriq.o libahci.o libahci_platform.o # SFF w/ custom DMA obj-$(CONFIG_PDC_ADMA) += pdc_adma.o diff --git a/drivers/ata/ahci_platform.c b/drivers/ata/ahci_platform.c index 1befb11..04975b8 100644 --- a/drivers/ata/ahci_platform.c +++ b/drivers/ata/ahci_platform.c @@ -76,7 +76,6 @@ static const struct of_device_id ahci_of_match[] = { { .compatible = "ibm,476gtr-ahci", }, { .compatible = "snps,dwc-ahci", }, { .compatible = "hisilicon,hisi-ahci", }, - { .compatible = "fsl,qoriq-ahci", }, {}, }; MODULE_DEVICE_TABLE(of, ahci_of_match); diff --git a/drivers/ata/ahci_qoriq.c b/drivers/ata/ahci_qoriq.c new file mode 100644 index 000..943b783 --- /dev/null +++ b/drivers/ata/ahci_qoriq.c @@ -0,0 +1,308 @@ +/* + * Freescale QorIQ AHCI SATA platform driver + * + * Copyright 2015 Freescale, Inc. + * Tang Yuantian + * + * 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, or (at your option) + * any later version. + */ + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include "ahci.h" + +#define DRV_NAME "ahci-qoriq" + +#define AHCI_PORT_PHY_1_CFG0xa003fffe +#define AHCI_PORT_PHY_2_CFG0x28183411 +#define AHCI_PORT_PHY_3_CFG0x0e081004 +#define AHCI_PORT_PHY_4_CFG0x00480811 +#define AHCI_PORT_PHY_5_CFG0x192c96a4 +#define AHCI_PORT_TRANS_CFG0x0825 + +#define SATA_ECC_REG_ADDR 0x20220520 +#define SATA_ECC_DISABLE 0x0002 + +enum ahci_qoriq_type { + AHCI_LS1021A, + AHCI_LS1043A, + AHCI_LS2085A, +}; + +struct ahci_qoriq_priv { + struct ccsr_ahci *reg_base; + enum ahci_qoriq_type type; + void __iomem *ecc_addr; +}; + +/* AHCI (sata) register map */ +struct ccsr_ahci { + u32 res1[0xa4/4]; /* 0x0 - 0xa4 */ + u32 pcfg; /* port config */ + u32 ppcfg; /* port phy1 config */ + u32 pp2c; /* port phy2 config */ + u32 pp3c; /* port phy3 config */ + u32 pp4c; /* port phy4 config */ + u32 pp5c; /* port phy5 config */ + u32 paxic; /* port AXI config */ + u32 axicc; /* AXI cache control */ + u32 axipc; /* AXI PROT control */ + u32 ptc;/* port Trans Config */ + u32 pts;/* port Trans Status */ + u32 plc;/* port link config */ + u32 plc1; /* port link config1 */ + u32 plc2; /* port link config2 */ + u32 pls;/* port link status */ + u32 pls1; /* port link status1 */ + u32 pcmdc; /* port CMD config */ + u32 ppcs; /* port phy control status */ + u32 pberr; /* port 0/1 BIST error */ + u32 cmds; /* port 0/1 CMD status error */ +}; + +static const struct of_device_id ahci_qoriq_of_match[] = { + { .compatible = "fsl,ls1021a-ahci", .data = (void *)AHCI_LS1021A}, + { .compatible = "fsl,ls1043a-ahci", .data = (void *)AHCI_LS1
[PATCH] arm: ls1021a: added SATA node in dts
From: Tang Yuantian Added SATA device node and enabled AHCI config by default. Signed-off-by: Shaohui Xie Signed-off-by: Tang Yuantian --- depends on patch: https://patchwork.kernel.org/patch/6851311/ arch/arm/boot/dts/ls1021a.dtsi | 7 +++ arch/arm/configs/ls1021a_defconfig | 2 ++ 2 files changed, 9 insertions(+) diff --git a/arch/arm/boot/dts/ls1021a.dtsi b/arch/arm/boot/dts/ls1021a.dtsi index c70bb27..1ee2a79 100644 --- a/arch/arm/boot/dts/ls1021a.dtsi +++ b/arch/arm/boot/dts/ls1021a.dtsi @@ -139,6 +139,13 @@ status = "disabled"; }; + sata: sata@320 { + compatible = "fsl,qoriq-ahci"; + reg = <0x0 0x320 0x0 0x1>; + interrupts = ; + clocks = <&platform_clk 1>; + }; + scfg: scfg@157 { compatible = "fsl,ls1021a-scfg", "syscon"; reg = <0x0 0x157 0x0 0x1>; diff --git a/arch/arm/configs/ls1021a_defconfig b/arch/arm/configs/ls1021a_defconfig index 079c48f..f502910 100644 --- a/arch/arm/configs/ls1021a_defconfig +++ b/arch/arm/configs/ls1021a_defconfig @@ -70,6 +70,8 @@ CONFIG_BLK_DEV_RAM_SIZE=256000 CONFIG_BLK_DEV_SD=y CONFIG_CHR_DEV_SG=y CONFIG_ATA=y +CONFIG_SATA_AHCI=y +CONFIG_SATA_AHCI_PLATFORM=y CONFIG_NETDEVICES=y CONFIG_GIANFAR=y CONFIG_VITESSE_PHY=y -- 2.1.0.27.g96db324 -- To unsubscribe from this list: send the line "unsubscribe linux-kernel" in the body of a message to majord...@vger.kernel.org More majordomo info at http://vger.kernel.org/majordomo-info.html Please read the FAQ at http://www.tux.org/lkml/
[PATCH v4] powerpc/rcpm: add RCPM driver
From: Tang Yuantian There is a RCPM (Run Control/Power Management) in Freescale QorIQ series processors. The device performs tasks associated with device run control and power management. The driver implements some features: mask/unmask irq, enter/exit low power states, freeze time base, etc. Signed-off-by: Chenhui Zhao Signed-off-by: Tang Yuantian --- v4: - refine bindings document v3: - added static and __init modifier to fsl_rcpm_init v2: - fix code style issues - refine compatible string match part Documentation/devicetree/bindings/soc/fsl/rcpm.txt | 42 +++ arch/powerpc/include/asm/fsl_guts.h| 105 +++ arch/powerpc/include/asm/fsl_pm.h | 48 +++ arch/powerpc/platforms/85xx/Kconfig| 1 + arch/powerpc/sysdev/Kconfig| 5 + arch/powerpc/sysdev/Makefile | 1 + arch/powerpc/sysdev/fsl_rcpm.c | 338 + 7 files changed, 540 insertions(+) create mode 100644 Documentation/devicetree/bindings/soc/fsl/rcpm.txt create mode 100644 arch/powerpc/include/asm/fsl_pm.h create mode 100644 arch/powerpc/sysdev/fsl_rcpm.c diff --git a/Documentation/devicetree/bindings/soc/fsl/rcpm.txt b/Documentation/devicetree/bindings/soc/fsl/rcpm.txt new file mode 100644 index 000..1f58018 --- /dev/null +++ b/Documentation/devicetree/bindings/soc/fsl/rcpm.txt @@ -0,0 +1,42 @@ +* Run Control and Power Management + +The RCPM performs all device-level tasks associated with device run control +and power management. + +Required properites: + - reg : Offset and length of the register set of RCPM block. + - compatible : Sould contain a chip-specific RCPM block compatible string + and (if applicable) may contain a chassis-version RCPM compatible string. + Chip-specific strings are of the form "fsl,-rcpm", such as: + * "fsl,p2041-rcpm" + * "fsl,p3041-rcpm" + * "fsl,p4080-rcpm" + * "fsl,p5020-rcpm" + * "fsl,p5040-rcpm" + * "fsl,t4240-rcpm" + * "fsl,b4420-rcpm" + * "fsl,b4860-rcpm" + + Chassis-version RCPM strings include: + * "fsl,qoriq-rcpm-1.0": for chassis 1.0 rcpm + * "fsl,qoriq-rcpm-2.0": for chassis 2.0 rcpm + +All references to "1.0" and "2.0" refer to the QorIQ chassis version to +which the chip complies. +Chassis VersionExample Chips +------ +1.0p4080, p5020, p5040, p2041, p3041 +2.0t4240, b4860, t1040, b4420 + +Example: +The RCPM node for T4240: + rcpm: global-utilities@e2000 { + compatible = "fsl,t4240-rcpm", "fsl,qoriq-rcpm-2.0"; + reg = <0xe2000 0x1000>; + }; + +The RCPM node for P4080: + rcpm: global-utilities@e2000 { + compatible = "fsl,qoriq-rcpm-1.0"; + reg = <0xe2000 0x1000>; + }; diff --git a/arch/powerpc/include/asm/fsl_guts.h b/arch/powerpc/include/asm/fsl_guts.h index 43b6bb1..a67413c 100644 --- a/arch/powerpc/include/asm/fsl_guts.h +++ b/arch/powerpc/include/asm/fsl_guts.h @@ -188,5 +188,110 @@ static inline void guts_set_pmuxcr_dma(struct ccsr_guts __iomem *guts, #endif +struct ccsr_rcpm_v1 { + u8 res[4]; + __be32 cdozsr; /* 0x0004 Core Doze Status Register */ + u8 res0008[4]; + __be32 cdozcr; /* 0x000c Core Doze Control Register */ + u8 res0010[4]; + __be32 cnapsr; /* 0x0014 Core Nap Status Register */ + u8 res0018[4]; + __be32 cnapcr; /* 0x001c Core Nap Control Register */ + u8 res0020[4]; + __be32 cdozpsr;/* 0x0024 Core Doze Previous Status Register */ + u8 res0028[4]; + __be32 cnappsr;/* 0x002c Core Nap Previous Status Register */ + u8 res0030[4]; + __be32 cwaitsr;/* 0x0034 Core Wait Status Register */ + u8 res0038[4]; + __be32 cwdtdsr;/* 0x003c Core Watchdog Detect Status Register */ + __be32 powmgtcsr; /* 0x0040 PM Control&Status Register */ +#define RCPM_POWMGTCSR_SLP 0x0002 + u8 res0044[12]; + __be32 ippdexpcr; /* 0x0050 IP Powerdown Exception Control Register */ + u8 res0054[16]; + __be32 cpmimr; /* 0x0064 Core PM IRQ Mask Register */ + u8 res0068[4]; + __be32 cpmcimr;/* 0x006c Core PM Critical IRQ Mask Register */ + u8 res0070[4]; + __be32 cpmmcmr;/* 0x0074 Core PM Machine Check Mask Register */ + u8 res0078[4]; + __be32 cpmnmimr; /* 0x007c Core PM NMI Mask Register */ + u8 res0080[4]; + __be32 ctbenr; /* 0x0084 Core Time Base Enable Register */ + u8 res0088[4]; + __be32 ctbckselr; /* 0x008c Core Time Base Clock Select Register */ + u8 res0090[4]; + __be32 ctbhltc
[PATCH v3] powerpc/rcpm: add RCPM driver
From: Tang Yuantian There is a RCPM (Run Control/Power Management) in Freescale QorIQ series processors. The device performs tasks associated with device run control and power management. The driver implements some features: mask/unmask irq, enter/exit low power states, freeze time base, etc. Signed-off-by: Chenhui Zhao Signed-off-by: Tang Yuantian --- v3: - added static and __init modifier to fsl_rcpm_init v2: - fix code style issues - refine compatible string match part Documentation/devicetree/bindings/soc/fsl/rcpm.txt | 22 ++ arch/powerpc/include/asm/fsl_guts.h| 105 +++ arch/powerpc/include/asm/fsl_pm.h | 48 +++ arch/powerpc/platforms/85xx/Kconfig| 1 + arch/powerpc/sysdev/Kconfig| 5 + arch/powerpc/sysdev/Makefile | 1 + arch/powerpc/sysdev/fsl_rcpm.c | 338 + 7 files changed, 520 insertions(+) create mode 100644 Documentation/devicetree/bindings/soc/fsl/rcpm.txt create mode 100644 arch/powerpc/include/asm/fsl_pm.h create mode 100644 arch/powerpc/sysdev/fsl_rcpm.c diff --git a/Documentation/devicetree/bindings/soc/fsl/rcpm.txt b/Documentation/devicetree/bindings/soc/fsl/rcpm.txt new file mode 100644 index 000..5318999 --- /dev/null +++ b/Documentation/devicetree/bindings/soc/fsl/rcpm.txt @@ -0,0 +1,22 @@ +* Run Control and Power Management + +The RCPM performs all device-level tasks associated with device run control +and power management. + +Required properites: + - reg : Offset and length of the register set of RCPM block. + - compatible : Specifies the compatibility list for the RCPM. The type +should be string, such as "fsl,qoriq-rcpm-1.0", "fsl,qoriq-rcpm-2.0". + +Example: +The RCPM node for T4240: + rcpm: global-utilities@e2000 { + compatible = "fsl,t4240-rcpm", "fsl,qoriq-rcpm-2.0"; + reg = <0xe2000 0x1000>; + }; + +The RCPM node for P4080: + rcpm: global-utilities@e2000 { + compatible = "fsl,qoriq-rcpm-1.0"; + reg = <0xe2000 0x1000>; + }; diff --git a/arch/powerpc/include/asm/fsl_guts.h b/arch/powerpc/include/asm/fsl_guts.h index 43b6bb1..a67413c 100644 --- a/arch/powerpc/include/asm/fsl_guts.h +++ b/arch/powerpc/include/asm/fsl_guts.h @@ -188,5 +188,110 @@ static inline void guts_set_pmuxcr_dma(struct ccsr_guts __iomem *guts, #endif +struct ccsr_rcpm_v1 { + u8 res[4]; + __be32 cdozsr; /* 0x0004 Core Doze Status Register */ + u8 res0008[4]; + __be32 cdozcr; /* 0x000c Core Doze Control Register */ + u8 res0010[4]; + __be32 cnapsr; /* 0x0014 Core Nap Status Register */ + u8 res0018[4]; + __be32 cnapcr; /* 0x001c Core Nap Control Register */ + u8 res0020[4]; + __be32 cdozpsr;/* 0x0024 Core Doze Previous Status Register */ + u8 res0028[4]; + __be32 cnappsr;/* 0x002c Core Nap Previous Status Register */ + u8 res0030[4]; + __be32 cwaitsr;/* 0x0034 Core Wait Status Register */ + u8 res0038[4]; + __be32 cwdtdsr;/* 0x003c Core Watchdog Detect Status Register */ + __be32 powmgtcsr; /* 0x0040 PM Control&Status Register */ +#define RCPM_POWMGTCSR_SLP 0x0002 + u8 res0044[12]; + __be32 ippdexpcr; /* 0x0050 IP Powerdown Exception Control Register */ + u8 res0054[16]; + __be32 cpmimr; /* 0x0064 Core PM IRQ Mask Register */ + u8 res0068[4]; + __be32 cpmcimr;/* 0x006c Core PM Critical IRQ Mask Register */ + u8 res0070[4]; + __be32 cpmmcmr;/* 0x0074 Core PM Machine Check Mask Register */ + u8 res0078[4]; + __be32 cpmnmimr; /* 0x007c Core PM NMI Mask Register */ + u8 res0080[4]; + __be32 ctbenr; /* 0x0084 Core Time Base Enable Register */ + u8 res0088[4]; + __be32 ctbckselr; /* 0x008c Core Time Base Clock Select Register */ + u8 res0090[4]; + __be32 ctbhltcr; /* 0x0094 Core Time Base Halt Control Register */ + u8 res0098[4]; + __be32 cmcpmaskcr; /* 0x00a4 Core Machine Check Mask Register */ +}; + +struct ccsr_rcpm_v2 { + u8 res_00[12]; + __be32 tph10sr0; /* Thread PH10 Status Register */ + u8 res_10[12]; + __be32 tph10setr0; /* Thread PH10 Set Control Register */ + u8 res_20[12]; + __be32 tph10clrr0; /* Thread PH10 Clear Control Register */ + u8 res_30[12]; + __be32 tph10psr0; /* Thread PH10 Previous Status Register */ + u8 res_40[12]; + __be32 twaitsr0; /* Thread Wait Status Register */ + u8 res_50[96]; + __be32 pcph15sr; /* Physical Core PH15 Status Register */ + __be32 pcph15setr; /* Physical Core PH15 Set Contr
[PATCH v2] powerpc/rcpm: add RCPM driver
From: Tang Yuantian There is a RCPM (Run Control/Power Management) in Freescale QorIQ series processors. The device performs tasks associated with device run control and power management. The driver implements some features: mask/unmask irq, enter/exit low power states, freeze time base, etc. Signed-off-by: Chenhui Zhao Signed-off-by: Tang Yuantian --- v2: - fix code style issues - refine compatible string match part Documentation/devicetree/bindings/soc/fsl/rcpm.txt | 22 ++ arch/powerpc/include/asm/fsl_guts.h| 105 +++ arch/powerpc/include/asm/fsl_pm.h | 48 +++ arch/powerpc/platforms/85xx/Kconfig| 1 + arch/powerpc/sysdev/Kconfig| 5 + arch/powerpc/sysdev/Makefile | 1 + arch/powerpc/sysdev/fsl_rcpm.c | 338 + 7 files changed, 520 insertions(+) create mode 100644 Documentation/devicetree/bindings/soc/fsl/rcpm.txt create mode 100644 arch/powerpc/include/asm/fsl_pm.h create mode 100644 arch/powerpc/sysdev/fsl_rcpm.c diff --git a/Documentation/devicetree/bindings/soc/fsl/rcpm.txt b/Documentation/devicetree/bindings/soc/fsl/rcpm.txt new file mode 100644 index 000..5318999 --- /dev/null +++ b/Documentation/devicetree/bindings/soc/fsl/rcpm.txt @@ -0,0 +1,22 @@ +* Run Control and Power Management + +The RCPM performs all device-level tasks associated with device run control +and power management. + +Required properites: + - reg : Offset and length of the register set of RCPM block. + - compatible : Specifies the compatibility list for the RCPM. The type +should be string, such as "fsl,qoriq-rcpm-1.0", "fsl,qoriq-rcpm-2.0". + +Example: +The RCPM node for T4240: + rcpm: global-utilities@e2000 { + compatible = "fsl,t4240-rcpm", "fsl,qoriq-rcpm-2.0"; + reg = <0xe2000 0x1000>; + }; + +The RCPM node for P4080: + rcpm: global-utilities@e2000 { + compatible = "fsl,qoriq-rcpm-1.0"; + reg = <0xe2000 0x1000>; + }; diff --git a/arch/powerpc/include/asm/fsl_guts.h b/arch/powerpc/include/asm/fsl_guts.h index 43b6bb1..a67413c 100644 --- a/arch/powerpc/include/asm/fsl_guts.h +++ b/arch/powerpc/include/asm/fsl_guts.h @@ -188,5 +188,110 @@ static inline void guts_set_pmuxcr_dma(struct ccsr_guts __iomem *guts, #endif +struct ccsr_rcpm_v1 { + u8 res[4]; + __be32 cdozsr; /* 0x0004 Core Doze Status Register */ + u8 res0008[4]; + __be32 cdozcr; /* 0x000c Core Doze Control Register */ + u8 res0010[4]; + __be32 cnapsr; /* 0x0014 Core Nap Status Register */ + u8 res0018[4]; + __be32 cnapcr; /* 0x001c Core Nap Control Register */ + u8 res0020[4]; + __be32 cdozpsr;/* 0x0024 Core Doze Previous Status Register */ + u8 res0028[4]; + __be32 cnappsr;/* 0x002c Core Nap Previous Status Register */ + u8 res0030[4]; + __be32 cwaitsr;/* 0x0034 Core Wait Status Register */ + u8 res0038[4]; + __be32 cwdtdsr;/* 0x003c Core Watchdog Detect Status Register */ + __be32 powmgtcsr; /* 0x0040 PM Control&Status Register */ +#define RCPM_POWMGTCSR_SLP 0x0002 + u8 res0044[12]; + __be32 ippdexpcr; /* 0x0050 IP Powerdown Exception Control Register */ + u8 res0054[16]; + __be32 cpmimr; /* 0x0064 Core PM IRQ Mask Register */ + u8 res0068[4]; + __be32 cpmcimr;/* 0x006c Core PM Critical IRQ Mask Register */ + u8 res0070[4]; + __be32 cpmmcmr;/* 0x0074 Core PM Machine Check Mask Register */ + u8 res0078[4]; + __be32 cpmnmimr; /* 0x007c Core PM NMI Mask Register */ + u8 res0080[4]; + __be32 ctbenr; /* 0x0084 Core Time Base Enable Register */ + u8 res0088[4]; + __be32 ctbckselr; /* 0x008c Core Time Base Clock Select Register */ + u8 res0090[4]; + __be32 ctbhltcr; /* 0x0094 Core Time Base Halt Control Register */ + u8 res0098[4]; + __be32 cmcpmaskcr; /* 0x00a4 Core Machine Check Mask Register */ +}; + +struct ccsr_rcpm_v2 { + u8 res_00[12]; + __be32 tph10sr0; /* Thread PH10 Status Register */ + u8 res_10[12]; + __be32 tph10setr0; /* Thread PH10 Set Control Register */ + u8 res_20[12]; + __be32 tph10clrr0; /* Thread PH10 Clear Control Register */ + u8 res_30[12]; + __be32 tph10psr0; /* Thread PH10 Previous Status Register */ + u8 res_40[12]; + __be32 twaitsr0; /* Thread Wait Status Register */ + u8 res_50[96]; + __be32 pcph15sr; /* Physical Core PH15 Status Register */ + __be32 pcph15setr; /* Physical Core PH15 Set Control Register */ + __be32 pcph15clrr; /* Physical Core
[PATCH v4] powerpc/cache: add cache flush operation for various e500
From: Tang Yuantian Various e500 core have different cache architecture, so they need different cache flush operations. Therefore, add a callback function cpu_flush_caches to the struct cpu_spec. The cache flush operation for the specific kind of e500 is selected at init time. The callback function will flush all caches inside the current cpu. Signed-off-by: Chenhui Zhao Signed-off-by: Tang Yuantian --- v4: - line up cpu_down_flush* v3: - change all flush_caches to cpu_down_flush - replace whitespace with tab v2: - remove some function's prefix "__" - remove redundent CONFIG_PPC_E500MC micro arch/powerpc/include/asm/cacheflush.h | 2 - arch/powerpc/include/asm/cputable.h | 11 +++ arch/powerpc/kernel/asm-offsets.c | 3 + arch/powerpc/kernel/cpu_setup_fsl_booke.S | 112 ++ arch/powerpc/kernel/cputable.c| 4 ++ arch/powerpc/kernel/head_fsl_booke.S | 74 arch/powerpc/platforms/85xx/smp.c | 3 +- 7 files changed, 132 insertions(+), 77 deletions(-) diff --git a/arch/powerpc/include/asm/cacheflush.h b/arch/powerpc/include/asm/cacheflush.h index 30b35ff..729fde4 100644 --- a/arch/powerpc/include/asm/cacheflush.h +++ b/arch/powerpc/include/asm/cacheflush.h @@ -30,8 +30,6 @@ extern void flush_dcache_page(struct page *page); #define flush_dcache_mmap_lock(mapping)do { } while (0) #define flush_dcache_mmap_unlock(mapping) do { } while (0) -extern void __flush_disable_L1(void); - extern void flush_icache_range(unsigned long, unsigned long); extern void flush_icache_user_range(struct vm_area_struct *vma, struct page *page, unsigned long addr, diff --git a/arch/powerpc/include/asm/cputable.h b/arch/powerpc/include/asm/cputable.h index 6367b83..069 100644 --- a/arch/powerpc/include/asm/cputable.h +++ b/arch/powerpc/include/asm/cputable.h @@ -43,6 +43,13 @@ extern int machine_check_e500(struct pt_regs *regs); extern int machine_check_e200(struct pt_regs *regs); extern int machine_check_47x(struct pt_regs *regs); +#if defined(CONFIG_E500) +extern void cpu_down_flush_e500v2(void); +extern void cpu_down_flush_e500mc(void); +extern void cpu_down_flush_e5500(void); +extern void cpu_down_flush_e6500(void); +#endif + /* NOTE WELL: Update identify_cpu() if fields are added or removed! */ struct cpu_spec { /* CPU is matched via (PVR & pvr_mask) == pvr_value */ @@ -59,6 +66,10 @@ struct cpu_spec { unsigned inticache_bsize; unsigned intdcache_bsize; +#if defined(CONFIG_E500) + /* flush caches inside the current cpu */ + void (*cpu_down_flush)(void); +#endif /* number of performance monitor counters */ unsigned intnum_pmcs; enum powerpc_pmc_type pmc_type; diff --git a/arch/powerpc/kernel/asm-offsets.c b/arch/powerpc/kernel/asm-offsets.c index 0034b6b..52efca9 100644 --- a/arch/powerpc/kernel/asm-offsets.c +++ b/arch/powerpc/kernel/asm-offsets.c @@ -373,6 +373,9 @@ int main(void) DEFINE(CPU_SPEC_FEATURES, offsetof(struct cpu_spec, cpu_features)); DEFINE(CPU_SPEC_SETUP, offsetof(struct cpu_spec, cpu_setup)); DEFINE(CPU_SPEC_RESTORE, offsetof(struct cpu_spec, cpu_restore)); +#if defined(CONFIG_E500) + DEFINE(CPU_DOWN_FLUSH, offsetof(struct cpu_spec, cpu_down_flush)); +#endif DEFINE(pbe_address, offsetof(struct pbe, address)); DEFINE(pbe_orig_address, offsetof(struct pbe, orig_address)); diff --git a/arch/powerpc/kernel/cpu_setup_fsl_booke.S b/arch/powerpc/kernel/cpu_setup_fsl_booke.S index dddba3e..462aed9 100644 --- a/arch/powerpc/kernel/cpu_setup_fsl_booke.S +++ b/arch/powerpc/kernel/cpu_setup_fsl_booke.S @@ -13,11 +13,13 @@ * */ +#include #include #include #include #include #include +#include _GLOBAL(__e500_icache_setup) mfspr r0, SPRN_L1CSR1 @@ -233,3 +235,113 @@ _GLOBAL(__setup_cpu_e5500) mtlrr5 blr #endif + +/* flush L1 date cache, it can apply to e500v2, e500mc and e5500 */ +_GLOBAL(flush_dcache_L1) + mfmsr r10 + wrteei 0 + + mfspr r3,SPRN_L1CFG0 + rlwinm r5,r3,9,3 /* Extract cache block size */ + twlgti r5,1/* Only 32 and 64 byte cache blocks +* are currently defined. +*/ + li r4,32 + subfic r6,r5,2 /* r6 = log2(1KiB / cache block size) - +* log2(number of ways) +*/ + slw r5,r4,r5/* r5 = cache block size */ + + rlwinm r7,r3,0,0xff/* Extract number of KiB in the cache */ + mulli r7,r7,13/* An 8-way cache will require 13 +* loads per set. +*/ + slw r7,r7,r6 + + /* save off HID0 and set DCFA */ + mfs
[PATCH v3] powerpc/cache: add cache flush operation for various e500
From: Tang Yuantian Various e500 core have different cache architecture, so they need different cache flush operations. Therefore, add a callback function cpu_flush_caches to the struct cpu_spec. The cache flush operation for the specific kind of e500 is selected at init time. The callback function will flush all caches inside the current cpu. Signed-off-by: Chenhui Zhao Signed-off-by: Tang Yuantian --- v3: - change all flush_caches to cpu_down_flush - replace whitespace with tab v2: - remove some function's prefix "__" - remove redundent CONFIG_PPC_E500MC micro arch/powerpc/include/asm/cacheflush.h | 2 - arch/powerpc/include/asm/cputable.h | 11 +++ arch/powerpc/kernel/asm-offsets.c | 3 + arch/powerpc/kernel/cpu_setup_fsl_booke.S | 112 ++ arch/powerpc/kernel/cputable.c| 4 ++ arch/powerpc/kernel/head_fsl_booke.S | 74 arch/powerpc/platforms/85xx/smp.c | 3 +- 7 files changed, 132 insertions(+), 77 deletions(-) diff --git a/arch/powerpc/include/asm/cacheflush.h b/arch/powerpc/include/asm/cacheflush.h index 30b35ff..729fde4 100644 --- a/arch/powerpc/include/asm/cacheflush.h +++ b/arch/powerpc/include/asm/cacheflush.h @@ -30,8 +30,6 @@ extern void flush_dcache_page(struct page *page); #define flush_dcache_mmap_lock(mapping)do { } while (0) #define flush_dcache_mmap_unlock(mapping) do { } while (0) -extern void __flush_disable_L1(void); - extern void flush_icache_range(unsigned long, unsigned long); extern void flush_icache_user_range(struct vm_area_struct *vma, struct page *page, unsigned long addr, diff --git a/arch/powerpc/include/asm/cputable.h b/arch/powerpc/include/asm/cputable.h index 6367b83..069 100644 --- a/arch/powerpc/include/asm/cputable.h +++ b/arch/powerpc/include/asm/cputable.h @@ -43,6 +43,13 @@ extern int machine_check_e500(struct pt_regs *regs); extern int machine_check_e200(struct pt_regs *regs); extern int machine_check_47x(struct pt_regs *regs); +#if defined(CONFIG_E500) +extern void cpu_down_flush_e500v2(void); +extern void cpu_down_flush_e500mc(void); +extern void cpu_down_flush_e5500(void); +extern void cpu_down_flush_e6500(void); +#endif + /* NOTE WELL: Update identify_cpu() if fields are added or removed! */ struct cpu_spec { /* CPU is matched via (PVR & pvr_mask) == pvr_value */ @@ -59,6 +66,10 @@ struct cpu_spec { unsigned inticache_bsize; unsigned intdcache_bsize; +#if defined(CONFIG_E500) + /* flush caches inside the current cpu */ + void (*cpu_down_flush)(void); +#endif /* number of performance monitor counters */ unsigned intnum_pmcs; enum powerpc_pmc_type pmc_type; diff --git a/arch/powerpc/kernel/asm-offsets.c b/arch/powerpc/kernel/asm-offsets.c index 0034b6b..52efca9 100644 --- a/arch/powerpc/kernel/asm-offsets.c +++ b/arch/powerpc/kernel/asm-offsets.c @@ -373,6 +373,9 @@ int main(void) DEFINE(CPU_SPEC_FEATURES, offsetof(struct cpu_spec, cpu_features)); DEFINE(CPU_SPEC_SETUP, offsetof(struct cpu_spec, cpu_setup)); DEFINE(CPU_SPEC_RESTORE, offsetof(struct cpu_spec, cpu_restore)); +#if defined(CONFIG_E500) + DEFINE(CPU_DOWN_FLUSH, offsetof(struct cpu_spec, cpu_down_flush)); +#endif DEFINE(pbe_address, offsetof(struct pbe, address)); DEFINE(pbe_orig_address, offsetof(struct pbe, orig_address)); diff --git a/arch/powerpc/kernel/cpu_setup_fsl_booke.S b/arch/powerpc/kernel/cpu_setup_fsl_booke.S index dddba3e..462aed9 100644 --- a/arch/powerpc/kernel/cpu_setup_fsl_booke.S +++ b/arch/powerpc/kernel/cpu_setup_fsl_booke.S @@ -13,11 +13,13 @@ * */ +#include #include #include #include #include #include +#include _GLOBAL(__e500_icache_setup) mfspr r0, SPRN_L1CSR1 @@ -233,3 +235,113 @@ _GLOBAL(__setup_cpu_e5500) mtlrr5 blr #endif + +/* flush L1 date cache, it can apply to e500v2, e500mc and e5500 */ +_GLOBAL(flush_dcache_L1) + mfmsr r10 + wrteei 0 + + mfspr r3,SPRN_L1CFG0 + rlwinm r5,r3,9,3 /* Extract cache block size */ + twlgti r5,1/* Only 32 and 64 byte cache blocks +* are currently defined. +*/ + li r4,32 + subfic r6,r5,2 /* r6 = log2(1KiB / cache block size) - +* log2(number of ways) +*/ + slw r5,r4,r5/* r5 = cache block size */ + + rlwinm r7,r3,0,0xff/* Extract number of KiB in the cache */ + mulli r7,r7,13/* An 8-way cache will require 13 +* loads per set. +*/ + slw r7,r7,r6 + + /* save off HID0 and set DCFA */ + mfspr r8,SPRN_HID0 + ori r9,r
[PATCH v2] powerpc/cache: add cache flush operation for various e500
From: Tang Yuantian Various e500 core have different cache architecture, so they need different cache flush operations. Therefore, add a callback function cpu_flush_caches to the struct cpu_spec. The cache flush operation for the specific kind of e500 is selected at init time. The callback function will flush all caches inside the current cpu. Signed-off-by: Chenhui Zhao Signed-off-by: Tang Yuantian --- v2: - remove some function's prefix "__" - remove redundent CONFIG_PPC_E500MC micro arch/powerpc/include/asm/cacheflush.h | 2 - arch/powerpc/include/asm/cputable.h | 11 +++ arch/powerpc/kernel/asm-offsets.c | 3 + arch/powerpc/kernel/cpu_setup_fsl_booke.S | 114 +- arch/powerpc/kernel/cputable.c| 4 ++ arch/powerpc/kernel/head_fsl_booke.S | 74 --- arch/powerpc/platforms/85xx/smp.c | 3 +- 7 files changed, 133 insertions(+), 78 deletions(-) diff --git a/arch/powerpc/include/asm/cacheflush.h b/arch/powerpc/include/asm/cacheflush.h index 30b35ff..729fde4 100644 --- a/arch/powerpc/include/asm/cacheflush.h +++ b/arch/powerpc/include/asm/cacheflush.h @@ -30,8 +30,6 @@ extern void flush_dcache_page(struct page *page); #define flush_dcache_mmap_lock(mapping)do { } while (0) #define flush_dcache_mmap_unlock(mapping) do { } while (0) -extern void __flush_disable_L1(void); - extern void flush_icache_range(unsigned long, unsigned long); extern void flush_icache_user_range(struct vm_area_struct *vma, struct page *page, unsigned long addr, diff --git a/arch/powerpc/include/asm/cputable.h b/arch/powerpc/include/asm/cputable.h index 6367b83..43fffef 100644 --- a/arch/powerpc/include/asm/cputable.h +++ b/arch/powerpc/include/asm/cputable.h @@ -43,6 +43,13 @@ extern int machine_check_e500(struct pt_regs *regs); extern int machine_check_e200(struct pt_regs *regs); extern int machine_check_47x(struct pt_regs *regs); +#if defined(CONFIG_E500) +extern void flush_caches_e500v2(void); +extern void flush_caches_e500mc(void); +extern void flush_caches_e5500(void); +extern void flush_caches_e6500(void); +#endif + /* NOTE WELL: Update identify_cpu() if fields are added or removed! */ struct cpu_spec { /* CPU is matched via (PVR & pvr_mask) == pvr_value */ @@ -59,6 +66,10 @@ struct cpu_spec { unsigned inticache_bsize; unsigned intdcache_bsize; +#if defined(CONFIG_E500) + /* flush caches inside the current cpu */ + void (*cpu_down_flush)(void); +#endif /* number of performance monitor counters */ unsigned intnum_pmcs; enum powerpc_pmc_type pmc_type; diff --git a/arch/powerpc/kernel/asm-offsets.c b/arch/powerpc/kernel/asm-offsets.c index 0034b6b..52efca9 100644 --- a/arch/powerpc/kernel/asm-offsets.c +++ b/arch/powerpc/kernel/asm-offsets.c @@ -373,6 +373,9 @@ int main(void) DEFINE(CPU_SPEC_FEATURES, offsetof(struct cpu_spec, cpu_features)); DEFINE(CPU_SPEC_SETUP, offsetof(struct cpu_spec, cpu_setup)); DEFINE(CPU_SPEC_RESTORE, offsetof(struct cpu_spec, cpu_restore)); +#if defined(CONFIG_E500) + DEFINE(CPU_DOWN_FLUSH, offsetof(struct cpu_spec, cpu_down_flush)); +#endif DEFINE(pbe_address, offsetof(struct pbe, address)); DEFINE(pbe_orig_address, offsetof(struct pbe, orig_address)); diff --git a/arch/powerpc/kernel/cpu_setup_fsl_booke.S b/arch/powerpc/kernel/cpu_setup_fsl_booke.S index dddba3e..4c857a6a 100644 --- a/arch/powerpc/kernel/cpu_setup_fsl_booke.S +++ b/arch/powerpc/kernel/cpu_setup_fsl_booke.S @@ -1,7 +1,7 @@ /* * This file contains low level CPU setup functions. * Kumar Gala - * Copyright 2009 Freescale Semiconductor, Inc. + * Copyright 2009, 2015 Freescale Semiconductor, Inc. * * Based on cpu_setup_6xx code by * Benjamin Herrenschmidt @@ -13,11 +13,13 @@ * */ +#include #include #include #include #include #include +#include _GLOBAL(__e500_icache_setup) mfspr r0, SPRN_L1CSR1 @@ -233,3 +235,113 @@ _GLOBAL(__setup_cpu_e5500) mtlrr5 blr #endif + +/* flush L1 date cache, it can apply to e500v2, e500mc and e5500 */ +_GLOBAL(flush_dcache_L1) + mfmsr r10 + wrteei 0 + + mfspr r3,SPRN_L1CFG0 + rlwinm r5,r3,9,3 /* Extract cache block size */ + twlgti r5,1/* Only 32 and 64 byte cache blocks +* are currently defined. +*/ + li r4,32 + subfic r6,r5,2 /* r6 = log2(1KiB / cache block size) - +* log2(number of ways) +*/ + slw r5,r4,r5/* r5 = cache block size */ + + rlwinm r7,r3,0,0xff/* Extract number of KiB in the cache */ + mulli r7,r7,13/* An 8-way cache will require 13 +* loads per
[PATCH v2] of/base: release the node correctly in of_parse_phandle_with_args()
From: Tang Yuantian Call of_node_put() only when the out_args is NULL on success, or the node's reference count will not be correct because the caller will call of_node_put() again. Signed-off-by: Tang Yuantian --- v2: - modified the title and description. the 1st patch title is: of: remove the unnecessary of_node_put for of_parse_phandle_with_args() the 1st patch is not good enough. drivers/of/base.c | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/drivers/of/base.c b/drivers/of/base.c index 321d3ef..ee94f64 100644 --- a/drivers/of/base.c +++ b/drivers/of/base.c @@ -1158,6 +1158,7 @@ static int __of_parse_phandle_with_args(const struct device_node *np, if (!phandle) goto err; + /* Found it! return success */ if (out_args) { int i; if (WARN_ON(count > MAX_PHANDLE_ARGS)) @@ -1166,11 +1167,10 @@ static int __of_parse_phandle_with_args(const struct device_node *np, out_args->args_count = count; for (i = 0; i < count; i++) out_args->args[i] = be32_to_cpup(list++); + } else if (node) { + of_node_put(node); } - /* Found it! return success */ - if (node) - of_node_put(node); return 0; } -- 1.8.0 -- To unsubscribe from this list: send the line "unsubscribe linux-kernel" in the body of a message to majord...@vger.kernel.org More majordomo info at http://vger.kernel.org/majordomo-info.html Please read the FAQ at http://www.tux.org/lkml/
[PATCH v3] clk: add PowerPC corenet clock driver support
From: Tang Yuantian This adds the clock driver for Freescale PowerPC corenet series SoCs using common clock infrastructure. Signed-off-by: Tang Yuantian Signed-off-by: Li Yang --- v3: - remove the module author and description v2: - add the document for device tree clock bindings arch/powerpc/platforms/Kconfig.cputype | 1 + drivers/clk/Kconfig| 7 + drivers/clk/Makefile | 1 + drivers/clk/clk-ppc-corenet.c | 280 + 4 files changed, 289 insertions(+) create mode 100644 drivers/clk/clk-ppc-corenet.c diff --git a/arch/powerpc/platforms/Kconfig.cputype b/arch/powerpc/platforms/Kconfig.cputype index 18e3b76..cf065b8 100644 --- a/arch/powerpc/platforms/Kconfig.cputype +++ b/arch/powerpc/platforms/Kconfig.cputype @@ -158,6 +158,7 @@ config E500 config PPC_E500MC bool "e500mc Support" select PPC_FPU + select COMMON_CLK depends on E500 help This must be enabled for running on e500mc (and derivatives diff --git a/drivers/clk/Kconfig b/drivers/clk/Kconfig index a47e6ee..6e2fd9c 100644 --- a/drivers/clk/Kconfig +++ b/drivers/clk/Kconfig @@ -63,6 +63,13 @@ config CLK_TWL6040 McPDM. McPDM module is using the external bit clock on the McPDM bus as functional clock. +config CLK_PPC_CORENET + bool "Clock driver for PowerPC corenet platforms" + depends on PPC_E500MC && OF + ---help--- + This adds the clock driver support for Freescale PowerPC corenet + platforms using common clock framework. + endmenu source "drivers/clk/mvebu/Kconfig" diff --git a/drivers/clk/Makefile b/drivers/clk/Makefile index 300d477..6720319 100644 --- a/drivers/clk/Makefile +++ b/drivers/clk/Makefile @@ -34,3 +34,4 @@ obj-$(CONFIG_X86) += x86/ obj-$(CONFIG_COMMON_CLK_WM831X) += clk-wm831x.o obj-$(CONFIG_COMMON_CLK_MAX77686) += clk-max77686.o obj-$(CONFIG_CLK_TWL6040) += clk-twl6040.o +obj-$(CONFIG_CLK_PPC_CORENET) += clk-ppc-corenet.o diff --git a/drivers/clk/clk-ppc-corenet.c b/drivers/clk/clk-ppc-corenet.c new file mode 100644 index 000..a2d483f --- /dev/null +++ b/drivers/clk/clk-ppc-corenet.c @@ -0,0 +1,280 @@ +/* + * 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 version 2 as + * published by the Free Software Foundation. + * + * clock driver for Freescale PowerPC corenet SoCs. + */ +#include +#include +#include +#include +#include +#include +#include + +struct cmux_clk { + struct clk_hw hw; + void __iomem *reg; + u32 flags; +}; + +#define PLL_KILL BIT(31) +#defineCLKSEL_SHIFT27 +#define CLKSEL_ADJUST BIT(0) +#define to_cmux_clk(p) container_of(p, struct cmux_clk, hw) + +static void __iomem *base; +static unsigned int clocks_per_pll; + +static int cmux_set_parent(struct clk_hw *hw, u8 idx) +{ + struct cmux_clk *clk = to_cmux_clk(hw); + u32 clksel; + + clksel = ((idx / clocks_per_pll) << 2) + idx % clocks_per_pll; + if (clk->flags & CLKSEL_ADJUST) + clksel += 8; + clksel = (clksel & 0xf) << CLKSEL_SHIFT; + iowrite32be(clksel, clk->reg); + + return 0; +} + +static u8 cmux_get_parent(struct clk_hw *hw) +{ + struct cmux_clk *clk = to_cmux_clk(hw); + u32 clksel; + + clksel = ioread32be(clk->reg); + clksel = (clksel >> CLKSEL_SHIFT) & 0xf; + if (clk->flags & CLKSEL_ADJUST) + clksel -= 8; + clksel = (clksel >> 2) * clocks_per_pll + clksel % 4; + + return clksel; +} + +const struct clk_ops cmux_ops = { + .get_parent = cmux_get_parent, + .set_parent = cmux_set_parent, +}; + +static void __init core_mux_init(struct device_node *np) +{ + struct clk *clk; + struct clk_init_data init; + struct cmux_clk *cmux_clk; + struct device_node *node; + int rc, count, i; + u32 offset; + const char *clk_name; + const char **parent_names; + + rc = of_property_read_u32(np, "reg", &offset); + if (rc) { + pr_err("%s: could not get reg property\n", np->name); + return; + } + + /* get the input clock source count */ + count = of_property_count_strings(np, "clock-names"); + if (count < 0) { + pr_err("%s: get clock count error\n", np->name); + return; + } + parent_names = kzalloc((sizeof(char *) * count), GFP_KERNEL); + if (!parent_names) { + pr_err("%s: could not allocate parent_names\n", __func__); + return; + } + + for (i = 0; i < count; i++) + parent_names[i] = of_clk_get_parent_name(np, i); + + cmux_clk = kzalloc(sizeof(struct cmux_clk), GFP_KERNEL); + if (!cmux_clk) { +
[PATCH] powerpc/mpc85xx: Update the clock device tree nodes
From: Tang Yuantian The following SoCs will be affected: p2041, p3041, p4080, p5020, p5040 Signed-off-by: Tang Yuantian Signed-off-by: Li Yang --- * resend for review arch/powerpc/boot/dts/fsl/p2041si-post.dtsi | 62 - arch/powerpc/boot/dts/fsl/p2041si-pre.dtsi | 4 ++ arch/powerpc/boot/dts/fsl/p3041si-post.dtsi | 62 - arch/powerpc/boot/dts/fsl/p3041si-pre.dtsi | 4 ++ arch/powerpc/boot/dts/fsl/p4080si-post.dtsi | 100 +++- arch/powerpc/boot/dts/fsl/p4080si-pre.dtsi | 8 +++ arch/powerpc/boot/dts/fsl/p5020si-post.dtsi | 42 +++- arch/powerpc/boot/dts/fsl/p5020si-pre.dtsi | 2 + arch/powerpc/boot/dts/fsl/p5040si-post.dtsi | 54 ++- arch/powerpc/boot/dts/fsl/p5040si-pre.dtsi | 4 ++ 10 files changed, 337 insertions(+), 5 deletions(-) diff --git a/arch/powerpc/boot/dts/fsl/p2041si-post.dtsi b/arch/powerpc/boot/dts/fsl/p2041si-post.dtsi index 69ac1ac..d83de62 100644 --- a/arch/powerpc/boot/dts/fsl/p2041si-post.dtsi +++ b/arch/powerpc/boot/dts/fsl/p2041si-post.dtsi @@ -305,9 +305,69 @@ }; clockgen: global-utilities@e1000 { - compatible = "fsl,p2041-clockgen", "fsl,qoriq-clockgen-1.0"; + compatible = "fsl,p2041-clockgen", "fsl,qoriq-clockgen-1.0", + "fixed-clock"; reg = <0xe1000 0x1000>; clock-frequency = <0>; + clock-output-names = "sysclk"; + #clock-cells = <0>; + + #address-cells = <1>; + #size-cells = <0>; + pll0: pll0@800 { + #clock-cells = <1>; + reg = <0x800>; + compatible = "fsl,core-pll-clock"; + clocks = <&clockgen>; + clock-output-names = "pll0", "pll0-div2", "pll0-div4"; + }; + pll1: pll1@820 { + #clock-cells = <1>; + reg = <0x820>; + compatible = "fsl,core-pll-clock"; + clocks = <&clockgen>; + clock-output-names = "pll1", "pll1-div2", "pll1-div4"; + }; + mux0: mux0@0 { + #clock-cells = <0>; + reg = <0x0>; + compatible = "fsl,core-mux-clock"; + clocks = <&pll0 0>, <&pll0 1>, <&pll0 2>, + <&pll1 0>, <&pll1 1>, <&pll1 2>; + clock-names = "pll0_0", "pll0_1", "pll0_2", + "pll1_0", "pll1_1", "pll1_2"; + clock-output-names = "cmux0"; + }; + mux1: mux1@20 { + #clock-cells = <0>; + reg = <0x20>; + compatible = "fsl,core-mux-clock"; + clocks = <&pll0 0>, <&pll0 1>, <&pll0 2>, + <&pll1 0>, <&pll1 1>, <&pll1 2>; + clock-names = "pll0_0", "pll0_1", "pll0_2", + "pll1_0", "pll1_1", "pll1_2"; + clock-output-names = "cmux1"; + }; + mux2: mux2@40 { + #clock-cells = <0>; + reg = <0x40>; + compatible = "fsl,core-mux-clock"; + clocks = <&pll0 0>, <&pll0 1>, <&pll0 2>, + <&pll1 0>, <&pll1 1>, <&pll1 2>; + clock-names = "pll0_0", "pll0_1", "pll0_2", + "pll1_0", "pll1_1", "pll1_2"; + clock-output-names = "cmux2"; + }; + mux3: mux3@60 { + #clock-cells = <0>; + reg = <0x60>; + compatible = "fsl,core-mux-clock"; + clocks = <&pll0 0>, <&pll0 1>, <&pll0 2>, + <&pll1 0>, <&pll1 1>, <&pll1 2>; + clock-names = "pll0_0", "pll0_1", "pll0_2", + "pll1_0", "pll1_1", "pll1_2"; + clock-output-names = "cmux3"; + }; }; rcpm: global-utilities@e2000 { diff --git a/arch/powerpc/boot/dts/fsl/p2041si-pre.dtsi b/arch/powerpc/boot/dts/fsl/p2041si-pre.dtsi index 7a2697d..22f3b14 100644 --- a/arch/powerpc/boot/dts/fsl/p2041si-pre.dtsi +++ b/arch/powerpc/boot/dts/fsl/p2041si-pre.dtsi @@ -81,6 +81,7 @@ cpu0: PowerPC,e500mc@0 { device_type = "cpu"; reg = <0>; + clocks = <&mux0>; next-level-cache = <&L2_0>; L2_0: l2-cache { next-level-cache = <&cpc>; @@ -89,6 +90,7 @@ cpu1: PowerPC,e500mc@1 { device_type = "cpu";
[PATCH v4] cpufreq: powerpc: Add cpufreq driver for Freescale e500mc SoCs
From: Tang Yuantian Add cpufreq driver for Freescale e500mc, e5500 and e6500 SoCs which are capable of changing the CPU frequency dynamically Signed-off-by: Tang Yuantian Signed-off-by: Li Yang --- v4: - rebase on bleeding-edge branch of Rafael's linux-pm.git - #define pr_fmt() for better debug prints - use newest cpufreq_notify_transition() - support CPU hotplug - remove table[i].index as it is not used - remove cpus_per_cluster v3: - change sizeof(struct name).. to sizeof(*p) - remove the struct cpufreq_data, use global variable instead - resolve setting policy->cpus incorrectly - add CPUFREQ_POSTCHANGE notifier when setting frequency error v2: - add depends on OF and COMMON_CLK in Kconfig - use clk.h instead of clk-provider.h - change per_cpu variable from struct to pointer drivers/cpufreq/Kconfig.powerpc | 10 ++ drivers/cpufreq/Makefile | 1 + drivers/cpufreq/ppc-corenet-cpufreq.c | 254 ++ 3 files changed, 265 insertions(+) create mode 100644 drivers/cpufreq/ppc-corenet-cpufreq.c diff --git a/drivers/cpufreq/Kconfig.powerpc b/drivers/cpufreq/Kconfig.powerpc index 9c926ca..88f629e 100644 --- a/drivers/cpufreq/Kconfig.powerpc +++ b/drivers/cpufreq/Kconfig.powerpc @@ -23,3 +23,13 @@ config CPU_FREQ_MAPLE help This adds support for frequency switching on Maple 970FX Evaluation Board and compatible boards (IBM JS2x blades). + +config PPC_CORENET_CPUFREQ + tristate "CPU frequency scaling driver for Freescale E500MC SoCs" + depends on PPC_E500MC && OF && COMMON_CLK + select CPU_FREQ_TABLE + select CLK_PPC_CORENET + help + This adds the CPUFreq driver support for Freescale e500mc, + e5500 and e6500 series SoCs which are capable of changing + the CPU's frequency dynamically. diff --git a/drivers/cpufreq/Makefile b/drivers/cpufreq/Makefile index 6ad0b91..5125034 100644 --- a/drivers/cpufreq/Makefile +++ b/drivers/cpufreq/Makefile @@ -84,6 +84,7 @@ obj-$(CONFIG_CPU_FREQ_CBE)+= ppc-cbe-cpufreq.o ppc-cbe-cpufreq-y += ppc_cbe_cpufreq_pervasive.o ppc_cbe_cpufreq.o obj-$(CONFIG_CPU_FREQ_CBE_PMI) += ppc_cbe_cpufreq_pmi.o obj-$(CONFIG_CPU_FREQ_MAPLE) += maple-cpufreq.o +obj-$(CONFIG_PPC_CORENET_CPUFREQ) += ppc-corenet-cpufreq.o ## # Other platform drivers diff --git a/drivers/cpufreq/ppc-corenet-cpufreq.c b/drivers/cpufreq/ppc-corenet-cpufreq.c new file mode 100644 index 000..e230282 --- /dev/null +++ b/drivers/cpufreq/ppc-corenet-cpufreq.c @@ -0,0 +1,254 @@ +/* + * Copyright 2013 Freescale Semiconductor, Inc. + * + * CPU Frequency Scaling driver for Freescale PowerPC corenet SoCs. + * + * 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. + */ + +#define pr_fmt(fmt)KBUILD_MODNAME ": " fmt + +#include +#include +#include +#include +#include +#include +#include +#include +#include + +/** + * struct cpu_data - per CPU data struct + * @clk: the clk of CPU + * @parent: the parent node of cpu clock + * @table: frequency table + */ +struct cpu_data { + struct clk *clk; + struct device_node *parent; + struct cpufreq_frequency_table *table; +}; + +/* serialize frequency changes */ +static DEFINE_MUTEX(cpufreq_lock); +static DEFINE_PER_CPU(struct cpu_data *, cpu_data); + +static unsigned int corenet_cpufreq_get_speed(unsigned int cpu) +{ + struct cpu_data *data = per_cpu(cpu_data, cpu); + + return clk_get_rate(data->clk) / 1000; +} + +/* reduce the duplicated frequency in frequency table */ +static void freq_table_redup(struct cpufreq_frequency_table *freq_table, + int count) +{ + int i, j; + + for (i = 1; i < count; i++) { + for (j = 0; j < i; j++) { + if (freq_table[j].frequency == CPUFREQ_ENTRY_INVALID || + freq_table[j].frequency != + freq_table[i].frequency) + continue; + + freq_table[i].frequency = CPUFREQ_ENTRY_INVALID; + break; + } + } +} + +static int corenet_cpufreq_cpu_init(struct cpufreq_policy *policy) +{ + struct device_node *np; + int i, count, ret; + struct clk *clk; + struct cpufreq_frequency_table *table; + struct cpu_data *data; + unsigned int cpu = policy->cpu; + + np = of_get_cpu_node(cpu, NULL); + if (!np) + return -ENODEV; + + data = kzalloc(sizeof(*data), GFP_KERNEL); + if (!data) { + pr_err("%s: no memory\n", __func__); +
[PATCH] of: remove the unnecessary of_node_put for of_parse_phandle_with_args()
From: Tang Yuantian As the function itself says it is caller's responsibility to call the of_node_put(). So, remove it on success to keep the reference count correct. Signed-off-by: Tang Yuantian --- drivers/of/base.c | 3 --- 1 file changed, 3 deletions(-) diff --git a/drivers/of/base.c b/drivers/of/base.c index 321d3ef..e8b4c28 100644 --- a/drivers/of/base.c +++ b/drivers/of/base.c @@ -1168,9 +1168,6 @@ static int __of_parse_phandle_with_args(const struct device_node *np, out_args->args[i] = be32_to_cpup(list++); } - /* Found it! return success */ - if (node) - of_node_put(node); return 0; } -- 1.8.0 -- To unsubscribe from this list: send the line "unsubscribe linux-kernel" in the body of a message to majord...@vger.kernel.org More majordomo info at http://vger.kernel.org/majordomo-info.html Please read the FAQ at http://www.tux.org/lkml/