RE: [PATCH] clk: ppc-corenet: Add support for the FMD clock
Hi Kumar. Regards, Igal Liberman. -Original Message- From: Kumar Gala [mailto:ga...@kernel.crashing.org] Sent: Friday, February 27, 2015 6:02 PM To: Liberman Igal-B31950 Cc: linuxppc-dev@lists.ozlabs.org; Wood Scott-B07421; Medve Emilian- EMMEDVE1 Subject: Re: [PATCH] clk: ppc-corenet: Add support for the FMD clock On Jan 20, 2015, at 6:03 AM, Igal.Liberman igal.liber...@freescale.com wrote: From: Igal Liberman igal.liber...@freescale.com Really should have some commit text Signed-off-by: Igal Liberman igal.liber...@freescale.com This patch is based on https://patchwork.ozlabs.org/patch/430966/ This belongs below the --- --- drivers/clk/clk-ppc-corenet.c | 250 + 1 file changed, 250 insertions(+) Any reason clk maintainers aren't CC'd? Kumar, Can you please proved a list of clk maintainers? I would like to add them for v2 submission. diff --git a/drivers/clk/clk-ppc-corenet.c b/drivers/clk/clk-ppc-corenet.c index ff425e1..dcde0e6 100644 --- a/drivers/clk/clk-ppc-corenet.c +++ b/drivers/clk/clk-ppc-corenet.c @@ -18,6 +18,7 @@ #include linux/of_platform.h #include linux/of.h #include linux/slab.h +#include asm/fsl_guts.h struct cmux_clk { struct clk_hw hw; @@ -144,6 +145,254 @@ err_name: kfree(parent_names); } +/* Table for matching compatible strings, for device tree + * guts node, for QorIQ SOCs. + * fsl,qoriq-device-config-2.0 corresponds to T4 B4 + * SOCs. For the older SOCs fsl,qoriq-device-config-1.0 + * string would be used. + */ + +static const struct of_device_id guts_device_ids[] = { + { .compatible = fsl,qoriq-device-config-1.0, }, + { .compatible = fsl,qoriq-device-config-2.0, }, }; + +/* P2, P3, P4, P5 */ +#define FM1_CLK_SEL_SHIFT 30 +#define FM1_CLK_SELBIT(FM1_CLK_SEL_SHIFT) +#define FM2_CLK_SEL_SHIFT 29 +#define FM2_CLK_SELBIT(FM2_CLK_SEL_SHIFT) +#define HWA_ASYNC_DIV_SHIFT26 +#define HWA_ASYNC_DIV BIT(HWA_ASYNC_DIV_SHIFT) + +/* B4, T2 */ +#define HWA_CGA_M1_CLK_SEL_SHIFT 29 +#define HWA_CGA_M1_CLK_SEL (BIT(HWA_CGA_M1_CLK_SEL_SHIFT + 2) |\ +BIT(HWA_CGA_M1_CLK_SEL_SHIFT + 1) |\ + BIT(HWA_CGA_M1_CLK_SEL_SHIFT)) + +/* T4240 */ +#define HWA_CGB_M1_CLK_SEL_SHIFT 26 +#define HWA_CGB_M1_CLK_SEL (BIT(HWA_CGB_M1_CLK_SEL_SHIFT + 2) |\ +BIT(HWA_CGB_M1_CLK_SEL_SHIFT + 1) |\ +BIT(HWA_CGB_M1_CLK_SEL_SHIFT)) +#define HWA_CGB_M2_CLK_SEL_SHIFT 3 +#define HWA_CGB_M2_CLK_SEL (BIT(HWA_CGB_M2_CLK_SEL_SHIFT + 2) |\ +BIT(HWA_CGB_M2_CLK_SEL_SHIFT + 1) |\ +BIT(HWA_CGB_M2_CLK_SEL_SHIFT)) + +static u8 get_fm_clk_parent(struct clk_hw *hw) { + struct ccsr_guts __iomem *guts_regs = NULL; + struct device_node *guts; + uint32_t reg = 0; + int clk_src = 0; + int fm_clk_select = -EINVAL; + int fm_id = 0; + + guts = of_find_matching_node(NULL, guts_device_ids); + if (!guts) { + pr_err(could not find GUTS node\n); + return -EINVAL; + } + + guts_regs = of_iomap(guts, 0); + of_node_put(guts); + if (!guts_regs) { + pr_err(ioremap of GUTS node failed\n); + return -EINVAL; + } Have you guys looked at using drivers/mfd/syscon.c for GUTS access. + + if (!strcmp(__clk_get_name(hw-clk), fm1-clk)) + fm_id = 1; + + /* The FM clock provider is SoC dependent and it's determened by the +* reset configuration word (RCW). We need to map the RCW options to +* the order of the providers in the device tree. +* This code makes assumptions about the clock provider order: +* In the P family: +* 0 - platform clock/2 +* 1 - PLLx /2 +* 2 - PLLx /4 (if possible). +* In B/T family: +* The same order in which the clock providers are described in +* the Reference Manual, starting from 0. +* +* In a case of only one possible provider, the index is 0. +*/ Does it make sense to do all this parsing every time get_fm_clk_parent, why not do it during the init function once? + + if (of_device_is_compatible(guts, fsl,p1023-guts) || + of_device_is_compatible(guts, fsl,t1040-device-config)) + /* P1023 and T1040 have only one optional clock source */ + fm_clk_select = 0; + else if (of_device_is_compatible(guts, fsl,p2041-device-config) || +of_device_is_compatible(guts, fsl,p3041-device-config) || +of_device_is_compatible(guts, fsl,p4080-device-config)) { + /* Read RCW*/ + reg = in_be32(guts_regs-rcwsr[7
Re: [PATCH] clk: ppc-corenet: Add support for the FMD clock
On Fri, 2015-02-27 at 10:02 -0600, Kumar Gala wrote: On Jan 20, 2015, at 6:03 AM, Igal.Liberman igal.liber...@freescale.com wrote: + guts_regs = of_iomap(guts, 0); + of_node_put(guts); + if (!guts_regs) { + pr_err(ioremap of GUTS node failed\n); + return -EINVAL; + } Have you guys looked at using drivers/mfd/syscon.c for GUTS access. Given the lack of documentation, could you explain what that file offers? Other than a requirement to modify existing device trees to do something other than describe the hardware (that file won't touch anything that isn't compatible with syscon). -Scott ___ Linuxppc-dev mailing list Linuxppc-dev@lists.ozlabs.org https://lists.ozlabs.org/listinfo/linuxppc-dev
Re: [PATCH] clk: ppc-corenet: Add support for the FMD clock
On Jan 20, 2015, at 6:03 AM, Igal.Liberman igal.liber...@freescale.com wrote: From: Igal Liberman igal.liber...@freescale.com Really should have some commit text Signed-off-by: Igal Liberman igal.liber...@freescale.com This patch is based on https://patchwork.ozlabs.org/patch/430966/ This belongs below the --- --- drivers/clk/clk-ppc-corenet.c | 250 + 1 file changed, 250 insertions(+) Any reason clk maintainers aren’t CC’d? diff --git a/drivers/clk/clk-ppc-corenet.c b/drivers/clk/clk-ppc-corenet.c index ff425e1..dcde0e6 100644 --- a/drivers/clk/clk-ppc-corenet.c +++ b/drivers/clk/clk-ppc-corenet.c @@ -18,6 +18,7 @@ #include linux/of_platform.h #include linux/of.h #include linux/slab.h +#include asm/fsl_guts.h struct cmux_clk { struct clk_hw hw; @@ -144,6 +145,254 @@ err_name: kfree(parent_names); } +/* Table for matching compatible strings, for device tree + * guts node, for QorIQ SOCs. + * fsl,qoriq-device-config-2.0 corresponds to T4 B4 + * SOCs. For the older SOCs fsl,qoriq-device-config-1.0 + * string would be used. + */ + +static const struct of_device_id guts_device_ids[] = { + { .compatible = fsl,qoriq-device-config-1.0, }, + { .compatible = fsl,qoriq-device-config-2.0, }, +}; + +/* P2, P3, P4, P5 */ +#define FM1_CLK_SEL_SHIFT30 +#define FM1_CLK_SEL BIT(FM1_CLK_SEL_SHIFT) +#define FM2_CLK_SEL_SHIFT29 +#define FM2_CLK_SEL BIT(FM2_CLK_SEL_SHIFT) +#define HWA_ASYNC_DIV_SHIFT 26 +#define HWA_ASYNC_DIVBIT(HWA_ASYNC_DIV_SHIFT) + +/* B4, T2 */ +#define HWA_CGA_M1_CLK_SEL_SHIFT 29 +#define HWA_CGA_M1_CLK_SEL (BIT(HWA_CGA_M1_CLK_SEL_SHIFT + 2) |\ + BIT(HWA_CGA_M1_CLK_SEL_SHIFT + 1) |\ + BIT(HWA_CGA_M1_CLK_SEL_SHIFT)) + +/* T4240 */ +#define HWA_CGB_M1_CLK_SEL_SHIFT 26 +#define HWA_CGB_M1_CLK_SEL (BIT(HWA_CGB_M1_CLK_SEL_SHIFT + 2) |\ + BIT(HWA_CGB_M1_CLK_SEL_SHIFT + 1) |\ + BIT(HWA_CGB_M1_CLK_SEL_SHIFT)) +#define HWA_CGB_M2_CLK_SEL_SHIFT 3 +#define HWA_CGB_M2_CLK_SEL (BIT(HWA_CGB_M2_CLK_SEL_SHIFT + 2) |\ + BIT(HWA_CGB_M2_CLK_SEL_SHIFT + 1) |\ + BIT(HWA_CGB_M2_CLK_SEL_SHIFT)) + +static u8 get_fm_clk_parent(struct clk_hw *hw) +{ + struct ccsr_guts __iomem *guts_regs = NULL; + struct device_node *guts; + uint32_t reg = 0; + int clk_src = 0; + int fm_clk_select = -EINVAL; + int fm_id = 0; + + guts = of_find_matching_node(NULL, guts_device_ids); + if (!guts) { + pr_err(could not find GUTS node\n); + return -EINVAL; + } + + guts_regs = of_iomap(guts, 0); + of_node_put(guts); + if (!guts_regs) { + pr_err(ioremap of GUTS node failed\n); + return -EINVAL; + } Have you guys looked at using drivers/mfd/syscon.c for GUTS access. + + if (!strcmp(__clk_get_name(hw-clk), fm1-clk)) + fm_id = 1; + + /* The FM clock provider is SoC dependent and it's determened by the + * reset configuration word (RCW). We need to map the RCW options to + * the order of the providers in the device tree. + * This code makes assumptions about the clock provider order: + * In the P family: + * 0 - platform clock/2 + * 1 - PLLx /2 + * 2 - PLLx /4 (if possible). + * In B/T family: + * The same order in which the clock providers are described in + * the Reference Manual, starting from 0. + * + * In a case of only one possible provider, the index is 0. + */ Does it make sense to do all this parsing every time get_fm_clk_parent, why not do it during the init function once? + + if (of_device_is_compatible(guts, fsl,p1023-guts) || + of_device_is_compatible(guts, fsl,t1040-device-config)) + /* P1023 and T1040 have only one optional clock source */ + fm_clk_select = 0; + else if (of_device_is_compatible(guts, fsl,p2041-device-config) || + of_device_is_compatible(guts, fsl,p3041-device-config) || + of_device_is_compatible(guts, fsl,p4080-device-config)) { + /* Read RCW*/ + reg = in_be32(guts_regs-rcwsr[7]); + + /* Check bit 225 or bit 226 (FM2, P4080) + * 0 - The clock source is Platform PLL /2 + * 1 - The clock source is PLL2 /2 (P2, P3) or PLL3 /2 (P4) + * + * Bit 225 represents FM1, Bit 226 represents FM2 + */ + if (fm_id == 0) + fm_clk_select = (reg FM1_CLK_SEL) +
Re: [PATCH] clk: ppc-corenet: Add support for the FMD clock
On Tue, 2015-01-20 at 14:03 +0200, Igal.Liberman wrote: +static u8 get_fm_clk_parent(struct clk_hw *hw) +{ + struct ccsr_guts __iomem *guts_regs = NULL; + struct device_node *guts; + uint32_t reg = 0; + int clk_src = 0; + int fm_clk_select = -EINVAL; + int fm_id = 0; + + guts = of_find_matching_node(NULL, guts_device_ids); + if (!guts) { + pr_err(could not find GUTS node\n); + return -EINVAL; + } Error message lacks context (here and elsewhere). Why are you going this on demand rather than in an init function (specifically, a CLK_OF_DECLARE)? You should not register this clock handler in the first place if the hardware doesn't exist. -EINVAL doesn't fit in u8. Neither would the more appropriate -ENODEV. + guts_regs = of_iomap(guts, 0); + of_node_put(guts); + if (!guts_regs) { + pr_err(ioremap of GUTS node failed\n); + return -EINVAL; + } + + if (!strcmp(__clk_get_name(hw-clk), fm1-clk)) + fm_id = 1; + + /* The FM clock provider is SoC dependent and it's determened by the determined + * reset configuration word (RCW). We need to map the RCW options to + * the order of the providers in the device tree. + * This code makes assumptions about the clock provider order: + * In the P family: + * 0 - platform clock/2 + * 1 - PLLx /2 + * 2 - PLLx /4 (if possible). + * In B/T family: + * The same order in which the clock providers are described in + * the Reference Manual, starting from 0. This belongs in a device tree binding document and should not incorporate portions of the reference manual by reference -- what if a new version of the reference manual changes the order in which clock providers are described? Or do you mean that the order corresponds to a register value? + * + * In a case of only one possible provider, the index is 0. + */ + + if (of_device_is_compatible(guts, fsl,p1023-guts) || + of_device_is_compatible(guts, fsl,t1040-device-config)) + /* P1023 and T1040 have only one optional clock source */ + fm_clk_select = 0; + else if (of_device_is_compatible(guts, fsl,p2041-device-config) || + of_device_is_compatible(guts, fsl,p3041-device-config) || + of_device_is_compatible(guts, fsl,p4080-device-config)) { + /* Read RCW*/ /* Read RCW */ @@ -352,3 +601,4 @@ CLK_OF_DECLARE(qoriq_core_mux_1, fsl,qoriq-core-mux-1.0, core_mux_init); CLK_OF_DECLARE(qoriq_core_mux_2, fsl,qoriq-core-mux-2.0, core_mux_init); CLK_OF_DECLARE(qoriq_pltfrm_pll_1, fsl,qoriq-platform-pll-1.0, pltfrm_pll_init); CLK_OF_DECLARE(qoriq_pltfrm_pll_2, fsl,qoriq-platform-pll-2.0, pltfrm_pll_init); +CLK_OF_DECLARE(qoriq_fm_mux, fsl,fman-clk-mux, fm_mux_init); Where is the binding for this node? -Scott ___ Linuxppc-dev mailing list Linuxppc-dev@lists.ozlabs.org https://lists.ozlabs.org/listinfo/linuxppc-dev
[PATCH] clk: ppc-corenet: Add support for the FMD clock
From: Igal Liberman igal.liber...@freescale.com Signed-off-by: Igal Liberman igal.liber...@freescale.com This patch is based on https://patchwork.ozlabs.org/patch/430966/ --- drivers/clk/clk-ppc-corenet.c | 250 + 1 file changed, 250 insertions(+) diff --git a/drivers/clk/clk-ppc-corenet.c b/drivers/clk/clk-ppc-corenet.c index ff425e1..dcde0e6 100644 --- a/drivers/clk/clk-ppc-corenet.c +++ b/drivers/clk/clk-ppc-corenet.c @@ -18,6 +18,7 @@ #include linux/of_platform.h #include linux/of.h #include linux/slab.h +#include asm/fsl_guts.h struct cmux_clk { struct clk_hw hw; @@ -144,6 +145,254 @@ err_name: kfree(parent_names); } +/* Table for matching compatible strings, for device tree + * guts node, for QorIQ SOCs. + * fsl,qoriq-device-config-2.0 corresponds to T4 B4 + * SOCs. For the older SOCs fsl,qoriq-device-config-1.0 + * string would be used. + */ + +static const struct of_device_id guts_device_ids[] = { + { .compatible = fsl,qoriq-device-config-1.0, }, + { .compatible = fsl,qoriq-device-config-2.0, }, +}; + +/* P2, P3, P4, P5 */ +#define FM1_CLK_SEL_SHIFT 30 +#define FM1_CLK_SELBIT(FM1_CLK_SEL_SHIFT) +#define FM2_CLK_SEL_SHIFT 29 +#define FM2_CLK_SELBIT(FM2_CLK_SEL_SHIFT) +#define HWA_ASYNC_DIV_SHIFT26 +#define HWA_ASYNC_DIV BIT(HWA_ASYNC_DIV_SHIFT) + +/* B4, T2 */ +#define HWA_CGA_M1_CLK_SEL_SHIFT 29 +#define HWA_CGA_M1_CLK_SEL (BIT(HWA_CGA_M1_CLK_SEL_SHIFT + 2) |\ +BIT(HWA_CGA_M1_CLK_SEL_SHIFT + 1) |\ +BIT(HWA_CGA_M1_CLK_SEL_SHIFT)) + +/* T4240 */ +#define HWA_CGB_M1_CLK_SEL_SHIFT 26 +#define HWA_CGB_M1_CLK_SEL (BIT(HWA_CGB_M1_CLK_SEL_SHIFT + 2) |\ +BIT(HWA_CGB_M1_CLK_SEL_SHIFT + 1) |\ +BIT(HWA_CGB_M1_CLK_SEL_SHIFT)) +#define HWA_CGB_M2_CLK_SEL_SHIFT 3 +#define HWA_CGB_M2_CLK_SEL (BIT(HWA_CGB_M2_CLK_SEL_SHIFT + 2) |\ +BIT(HWA_CGB_M2_CLK_SEL_SHIFT + 1) |\ +BIT(HWA_CGB_M2_CLK_SEL_SHIFT)) + +static u8 get_fm_clk_parent(struct clk_hw *hw) +{ + struct ccsr_guts __iomem *guts_regs = NULL; + struct device_node *guts; + uint32_t reg = 0; + int clk_src = 0; + int fm_clk_select = -EINVAL; + int fm_id = 0; + + guts = of_find_matching_node(NULL, guts_device_ids); + if (!guts) { + pr_err(could not find GUTS node\n); + return -EINVAL; + } + + guts_regs = of_iomap(guts, 0); + of_node_put(guts); + if (!guts_regs) { + pr_err(ioremap of GUTS node failed\n); + return -EINVAL; + } + + if (!strcmp(__clk_get_name(hw-clk), fm1-clk)) + fm_id = 1; + + /* The FM clock provider is SoC dependent and it's determened by the +* reset configuration word (RCW). We need to map the RCW options to +* the order of the providers in the device tree. +* This code makes assumptions about the clock provider order: +* In the P family: +* 0 - platform clock/2 +* 1 - PLLx /2 +* 2 - PLLx /4 (if possible). +* In B/T family: +* The same order in which the clock providers are described in +* the Reference Manual, starting from 0. +* +* In a case of only one possible provider, the index is 0. +*/ + + if (of_device_is_compatible(guts, fsl,p1023-guts) || + of_device_is_compatible(guts, fsl,t1040-device-config)) + /* P1023 and T1040 have only one optional clock source */ + fm_clk_select = 0; + else if (of_device_is_compatible(guts, fsl,p2041-device-config) || +of_device_is_compatible(guts, fsl,p3041-device-config) || +of_device_is_compatible(guts, fsl,p4080-device-config)) { + /* Read RCW*/ + reg = in_be32(guts_regs-rcwsr[7]); + + /* Check bit 225 or bit 226 (FM2, P4080) +* 0 - The clock source is Platform PLL /2 +* 1 - The clock source is PLL2 /2 (P2, P3) or PLL3 /2 (P4) +* +* Bit 225 represents FM1, Bit 226 represents FM2 +*/ + if (fm_id == 0) + fm_clk_select = (reg FM1_CLK_SEL) + FM1_CLK_SEL_SHIFT; + else + fm_clk_select = (reg FM2_CLK_SEL) + FM2_CLK_SEL_SHIFT; + } else if (of_device_is_compatible(guts, fsl,p5020-device-config) || + of_device_is_compatible(guts, fsl,p5040-device-config)) { +