diff options
Diffstat (limited to 'target/linux/brcm2708/patches-4.4/0259-clk-bcm2835-remove-use-of-BCM2835_CLOCK_COUNT-in-dri.patch')
-rw-r--r-- | target/linux/brcm2708/patches-4.4/0259-clk-bcm2835-remove-use-of-BCM2835_CLOCK_COUNT-in-dri.patch | 237 |
1 files changed, 237 insertions, 0 deletions
diff --git a/target/linux/brcm2708/patches-4.4/0259-clk-bcm2835-remove-use-of-BCM2835_CLOCK_COUNT-in-dri.patch b/target/linux/brcm2708/patches-4.4/0259-clk-bcm2835-remove-use-of-BCM2835_CLOCK_COUNT-in-dri.patch new file mode 100644 index 0000000000..fca8c89567 --- /dev/null +++ b/target/linux/brcm2708/patches-4.4/0259-clk-bcm2835-remove-use-of-BCM2835_CLOCK_COUNT-in-dri.patch @@ -0,0 +1,237 @@ +From 6cf07099604e362169932d82444a0f234cc8cbe0 Mon Sep 17 00:00:00 2001 +From: Martin Sperl <kernel@martin.sperl.org> +Date: Mon, 29 Feb 2016 12:51:41 +0000 +Subject: [PATCH 259/423] clk: bcm2835: remove use of BCM2835_CLOCK_COUNT in + driver + +As the use of BCM2835_CLOCK_COUNT in +include/dt-bindings/clock/bcm2835.h is frowned upon as +it needs to get modified every time a new clock gets introduced +this patch changes the clk-bcm2835 driver to use a different +scheme for registration of clocks and pll, so that there +is no more need for BCM2835_CLOCK_COUNT to be defined. + +Signed-off-by: Martin Sperl <kernel@martin.sperl.org> +Signed-off-by: Eric Anholt <eric@anholt.net> +Reviewed-by: Eric Anholt <eric@anholt.net> +(cherry picked from commit 56eb3a2ed9726961e1bcfa69d4a3f86d68f0eb52) +--- + drivers/clk/bcm/clk-bcm2835.c | 167 ++++++++++++++++++++---------------- + include/dt-bindings/clock/bcm2835.h | 2 - + 2 files changed, 94 insertions(+), 75 deletions(-) + +--- a/drivers/clk/bcm/clk-bcm2835.c ++++ b/drivers/clk/bcm/clk-bcm2835.c +@@ -301,7 +301,7 @@ struct bcm2835_cprman { + const char *osc_name; + + struct clk_onecell_data onecell; +- struct clk *clks[BCM2835_CLOCK_COUNT]; ++ struct clk *clks[]; + }; + + static inline void cprman_write(struct bcm2835_cprman *cprman, u32 reg, u32 val) +@@ -853,6 +853,25 @@ static const struct bcm2835_clock_data b + .is_mash_clock = true, + }; + ++struct bcm2835_gate_data { ++ const char *name; ++ const char *parent; ++ ++ u32 ctl_reg; ++}; ++ ++/* ++ * CM_PERIICTL (and CM_PERIACTL, CM_SYSCTL and CM_VPUCTL if ++ * you have the debug bit set in the power manager, which we ++ * don't bother exposing) are individual gates off of the ++ * non-stop vpu clock. ++ */ ++static const struct bcm2835_gate_data bcm2835_clock_peri_image_data = { ++ .name = "peri_image", ++ .parent = "vpu", ++ .ctl_reg = CM_PERIICTL, ++}; ++ + struct bcm2835_pll { + struct clk_hw hw; + struct bcm2835_cprman *cprman; +@@ -1658,14 +1677,81 @@ static struct clk *bcm2835_register_cloc + return devm_clk_register(cprman->dev, &clock->hw); + } + ++static struct clk *bcm2835_register_gate(struct bcm2835_cprman *cprman, ++ const struct bcm2835_gate_data *data) ++{ ++ return clk_register_gate(cprman->dev, data->name, data->parent, ++ CLK_IGNORE_UNUSED | CLK_SET_RATE_GATE, ++ cprman->regs + data->ctl_reg, ++ CM_GATE_BIT, 0, &cprman->regs_lock); ++} ++ ++typedef struct clk *(*bcm2835_clk_register)(struct bcm2835_cprman *cprman, ++ const void *data); ++struct bcm2835_clk_desc { ++ bcm2835_clk_register clk_register; ++ const void *data; ++}; ++ ++#define _REGISTER(f, d) { .clk_register = (bcm2835_clk_register)f, \ ++ .data = d } ++#define REGISTER_PLL(d) _REGISTER(&bcm2835_register_pll, d) ++#define REGISTER_PLL_DIV(d) _REGISTER(&bcm2835_register_pll_divider, d) ++#define REGISTER_CLK(d) _REGISTER(&bcm2835_register_clock, d) ++#define REGISTER_GATE(d) _REGISTER(&bcm2835_register_gate, d) ++ ++static const struct bcm2835_clk_desc clk_desc_array[] = { ++ /* register PLL */ ++ [BCM2835_PLLA] = REGISTER_PLL(&bcm2835_plla_data), ++ [BCM2835_PLLB] = REGISTER_PLL(&bcm2835_pllb_data), ++ [BCM2835_PLLC] = REGISTER_PLL(&bcm2835_pllc_data), ++ [BCM2835_PLLD] = REGISTER_PLL(&bcm2835_plld_data), ++ [BCM2835_PLLH] = REGISTER_PLL(&bcm2835_pllh_data), ++ /* the PLL dividers */ ++ [BCM2835_PLLA_CORE] = REGISTER_PLL_DIV(&bcm2835_plla_core_data), ++ [BCM2835_PLLA_PER] = REGISTER_PLL_DIV(&bcm2835_plla_per_data), ++ [BCM2835_PLLC_CORE0] = REGISTER_PLL_DIV(&bcm2835_pllc_core0_data), ++ [BCM2835_PLLC_CORE1] = REGISTER_PLL_DIV(&bcm2835_pllc_core1_data), ++ [BCM2835_PLLC_CORE2] = REGISTER_PLL_DIV(&bcm2835_pllc_core2_data), ++ [BCM2835_PLLC_PER] = REGISTER_PLL_DIV(&bcm2835_pllc_per_data), ++ [BCM2835_PLLD_CORE] = REGISTER_PLL_DIV(&bcm2835_plld_core_data), ++ [BCM2835_PLLD_PER] = REGISTER_PLL_DIV(&bcm2835_plld_per_data), ++ [BCM2835_PLLH_RCAL] = REGISTER_PLL_DIV(&bcm2835_pllh_rcal_data), ++ [BCM2835_PLLH_AUX] = REGISTER_PLL_DIV(&bcm2835_pllh_aux_data), ++ [BCM2835_PLLH_PIX] = REGISTER_PLL_DIV(&bcm2835_pllh_pix_data), ++ /* the clocks */ ++ [BCM2835_CLOCK_TIMER] = REGISTER_CLK(&bcm2835_clock_timer_data), ++ [BCM2835_CLOCK_OTP] = REGISTER_CLK(&bcm2835_clock_otp_data), ++ [BCM2835_CLOCK_TSENS] = REGISTER_CLK(&bcm2835_clock_tsens_data), ++ [BCM2835_CLOCK_VPU] = REGISTER_CLK(&bcm2835_clock_vpu_data), ++ [BCM2835_CLOCK_V3D] = REGISTER_CLK(&bcm2835_clock_v3d_data), ++ [BCM2835_CLOCK_ISP] = REGISTER_CLK(&bcm2835_clock_isp_data), ++ [BCM2835_CLOCK_H264] = REGISTER_CLK(&bcm2835_clock_h264_data), ++ [BCM2835_CLOCK_V3D] = REGISTER_CLK(&bcm2835_clock_v3d_data), ++ [BCM2835_CLOCK_SDRAM] = REGISTER_CLK(&bcm2835_clock_sdram_data), ++ [BCM2835_CLOCK_UART] = REGISTER_CLK(&bcm2835_clock_uart_data), ++ [BCM2835_CLOCK_VEC] = REGISTER_CLK(&bcm2835_clock_vec_data), ++ [BCM2835_CLOCK_HSM] = REGISTER_CLK(&bcm2835_clock_hsm_data), ++ [BCM2835_CLOCK_EMMC] = REGISTER_CLK(&bcm2835_clock_emmc_data), ++ [BCM2835_CLOCK_PWM] = REGISTER_CLK(&bcm2835_clock_pwm_data), ++ /* the gates */ ++ [BCM2835_CLOCK_PERI_IMAGE] = REGISTER_GATE( ++ &bcm2835_clock_peri_image_data), ++}; ++ + static int bcm2835_clk_probe(struct platform_device *pdev) + { + struct device *dev = &pdev->dev; + struct clk **clks; + struct bcm2835_cprman *cprman; + struct resource *res; ++ const struct bcm2835_clk_desc *desc; ++ const size_t asize = ARRAY_SIZE(clk_desc_array); ++ size_t i; + +- cprman = devm_kzalloc(dev, sizeof(*cprman), GFP_KERNEL); ++ cprman = devm_kzalloc(dev, ++ sizeof(*cprman) + asize * sizeof(*clks), ++ GFP_KERNEL); + if (!cprman) + return -ENOMEM; + +@@ -1682,80 +1768,15 @@ static int bcm2835_clk_probe(struct plat + + platform_set_drvdata(pdev, cprman); + +- cprman->onecell.clk_num = BCM2835_CLOCK_COUNT; ++ cprman->onecell.clk_num = asize; + cprman->onecell.clks = cprman->clks; + clks = cprman->clks; + +- clks[BCM2835_PLLA] = bcm2835_register_pll(cprman, &bcm2835_plla_data); +- clks[BCM2835_PLLB] = bcm2835_register_pll(cprman, &bcm2835_pllb_data); +- clks[BCM2835_PLLC] = bcm2835_register_pll(cprman, &bcm2835_pllc_data); +- clks[BCM2835_PLLD] = bcm2835_register_pll(cprman, &bcm2835_plld_data); +- clks[BCM2835_PLLH] = bcm2835_register_pll(cprman, &bcm2835_pllh_data); +- +- clks[BCM2835_PLLA_CORE] = +- bcm2835_register_pll_divider(cprman, &bcm2835_plla_core_data); +- clks[BCM2835_PLLA_PER] = +- bcm2835_register_pll_divider(cprman, &bcm2835_plla_per_data); +- clks[BCM2835_PLLC_CORE0] = +- bcm2835_register_pll_divider(cprman, &bcm2835_pllc_core0_data); +- clks[BCM2835_PLLC_CORE1] = +- bcm2835_register_pll_divider(cprman, &bcm2835_pllc_core1_data); +- clks[BCM2835_PLLC_CORE2] = +- bcm2835_register_pll_divider(cprman, &bcm2835_pllc_core2_data); +- clks[BCM2835_PLLC_PER] = +- bcm2835_register_pll_divider(cprman, &bcm2835_pllc_per_data); +- clks[BCM2835_PLLD_CORE] = +- bcm2835_register_pll_divider(cprman, &bcm2835_plld_core_data); +- clks[BCM2835_PLLD_PER] = +- bcm2835_register_pll_divider(cprman, &bcm2835_plld_per_data); +- clks[BCM2835_PLLH_RCAL] = +- bcm2835_register_pll_divider(cprman, &bcm2835_pllh_rcal_data); +- clks[BCM2835_PLLH_AUX] = +- bcm2835_register_pll_divider(cprman, &bcm2835_pllh_aux_data); +- clks[BCM2835_PLLH_PIX] = +- bcm2835_register_pll_divider(cprman, &bcm2835_pllh_pix_data); +- +- clks[BCM2835_CLOCK_TIMER] = +- bcm2835_register_clock(cprman, &bcm2835_clock_timer_data); +- clks[BCM2835_CLOCK_OTP] = +- bcm2835_register_clock(cprman, &bcm2835_clock_otp_data); +- clks[BCM2835_CLOCK_TSENS] = +- bcm2835_register_clock(cprman, &bcm2835_clock_tsens_data); +- clks[BCM2835_CLOCK_VPU] = +- bcm2835_register_clock(cprman, &bcm2835_clock_vpu_data); +- clks[BCM2835_CLOCK_V3D] = +- bcm2835_register_clock(cprman, &bcm2835_clock_v3d_data); +- clks[BCM2835_CLOCK_ISP] = +- bcm2835_register_clock(cprman, &bcm2835_clock_isp_data); +- clks[BCM2835_CLOCK_H264] = +- bcm2835_register_clock(cprman, &bcm2835_clock_h264_data); +- clks[BCM2835_CLOCK_V3D] = +- bcm2835_register_clock(cprman, &bcm2835_clock_v3d_data); +- clks[BCM2835_CLOCK_SDRAM] = +- bcm2835_register_clock(cprman, &bcm2835_clock_sdram_data); +- clks[BCM2835_CLOCK_UART] = +- bcm2835_register_clock(cprman, &bcm2835_clock_uart_data); +- clks[BCM2835_CLOCK_VEC] = +- bcm2835_register_clock(cprman, &bcm2835_clock_vec_data); +- clks[BCM2835_CLOCK_HSM] = +- bcm2835_register_clock(cprman, &bcm2835_clock_hsm_data); +- clks[BCM2835_CLOCK_EMMC] = +- bcm2835_register_clock(cprman, &bcm2835_clock_emmc_data); +- +- /* +- * CM_PERIICTL (and CM_PERIACTL, CM_SYSCTL and CM_VPUCTL if +- * you have the debug bit set in the power manager, which we +- * don't bother exposing) are individual gates off of the +- * non-stop vpu clock. +- */ +- clks[BCM2835_CLOCK_PERI_IMAGE] = +- clk_register_gate(dev, "peri_image", "vpu", +- CLK_IGNORE_UNUSED | CLK_SET_RATE_GATE, +- cprman->regs + CM_PERIICTL, CM_GATE_BIT, +- 0, &cprman->regs_lock); +- +- clks[BCM2835_CLOCK_PWM] = +- bcm2835_register_clock(cprman, &bcm2835_clock_pwm_data); ++ for (i = 0; i < asize; i++) { ++ desc = &clk_desc_array[i]; ++ if (desc->clk_register && desc->data) ++ clks[i] = desc->clk_register(cprman, desc->data); ++ } + + return of_clk_add_provider(dev->of_node, of_clk_src_onecell_get, + &cprman->onecell); +--- a/include/dt-bindings/clock/bcm2835.h ++++ b/include/dt-bindings/clock/bcm2835.h +@@ -44,5 +44,3 @@ + #define BCM2835_CLOCK_EMMC 28 + #define BCM2835_CLOCK_PERI_IMAGE 29 + #define BCM2835_CLOCK_PWM 30 +- +-#define BCM2835_CLOCK_COUNT 31 |