2b1c6b21b5
As usual these patches were extracted and rebased from the raspberry pi repo: https://github.com/raspberrypi/linux/tree/rpi-4.4.y Also adds support for Raspberry Pi Compute Module 3 (untested). Signed-off-by: Álvaro Fernández Rojas <noltari@gmail.com>
236 lines
9.1 KiB
Diff
236 lines
9.1 KiB
Diff
From 061e3130a957f04af48ff703209096e8a0b5655e 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] 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
|