Donate to e Foundation | Murena handsets with /e/OS | Own a part of Murena! Learn more

Commit cf657bb9 authored by Stephen Boyd's avatar Stephen Boyd
Browse files

Merge tag 'v4.14-rockchip-clk1' of...

Merge tag 'v4.14-rockchip-clk1' of git://git.kernel.org/pub/scm/linux/kernel/git/mmind/linux-rockchip into clk-next

Pull Rockchip clk driver updates from Heiko Stuebner:

The biggest change is fixing the jitter on the fractional clock-type
Rockchip socs experience with the default approximation. For that we
introduce the ability to override it with a clock-specific approximation
and use that to create the needed rate settings as described in the
Rockchip soc manuals (same for all Rockchip socs).

Apart from that we have support for the rk3126 clock controller
which is similar to the rk3128 with some minimal differences
and a lot of improvements and fixes for the rv1108 clock controller
(missing clocks, some clock-ids, naming fixes, register fixes).

* tag 'v4.14-rockchip-clk1' of git://git.kernel.org/pub/scm/linux/kernel/git/mmind/linux-rockchip:
  clk: rockchip: fix the rv1108 clk_mac sel register description
  clk: rockchip: rename rv1108 macphy clock to mac
  clk: rockchip: add rv1108 ACLK_GMAC and PCLK_GMAC clocks
  clk: rockchip: add rk3228 SCLK_SDIO_SRC clk id
  clk: rockchip: add rv1108 ACLK_GAMC and PCLK_GMAC ID
  clk: rockchip: add rk3228 sclk_sdio_src ID
  clk: rockchip: add special approximation to fix up fractional clk's jitter
  clk: fractional-divider: allow overriding of approximation
  clk: rockchip: modify rk3128 clk driver to also support rk3126
  dt-bindings: add documentation for rk3126 clock
  clk: rockchip: add some critical clocks for rv1108 SoC
  clk: rockchip: rename some of clks for rv1108 SoC
  clk: rockchip: fix up some clks describe error for rv1108 SoC
  clk: rockchip: support more clks for rv1108
  clk: rockchip: fix up the pll clks error for rv1108 SoC
  clk: rockchip: support more rates for rv1108 cpuclk
  clk: rockchip: fix up indentation of some RV1108 clock-ids
  clk: rockchip: rename the clk id for HCLK_I2S1_2CH
  clk: rockchip: add more clk ids for rv1108
parents 1fea70bc 64a1644b
Loading
Loading
Loading
Loading
+5 −3
Original line number Original line Diff line number Diff line
* Rockchip RK3128 Clock and Reset Unit
* Rockchip RK3126/RK3128 Clock and Reset Unit


The RK3128 clock controller generates and supplies clock to various
The RK3126/RK3128 clock controller generates and supplies clock to various
controllers within the SoC and also implements a reset controller for SoC
controllers within the SoC and also implements a reset controller for SoC
peripherals.
peripherals.


Required Properties:
Required Properties:


- compatible: should be "rockchip,rk3128-cru"
- compatible: should be "rockchip,rk3126-cru" or "rockchip,rk3128-cru"
  "rockchip,rk3126-cru" - controller compatible with RK3126 SoC.
  "rockchip,rk3128-cru" - controller compatible with RK3128 SoC.
- reg: physical base address of the controller and length of memory mapped
- reg: physical base address of the controller and length of memory mapped
  region.
  region.
- #clock-cells: should be 1.
- #clock-cells: should be 1.
+20 −8
Original line number Original line Diff line number Diff line
@@ -49,16 +49,12 @@ static unsigned long clk_fd_recalc_rate(struct clk_hw *hw,
	return ret;
	return ret;
}
}


static long clk_fd_round_rate(struct clk_hw *hw, unsigned long rate,
static void clk_fd_general_approximation(struct clk_hw *hw, unsigned long rate,
			      unsigned long *parent_rate)
					 unsigned long *parent_rate,
					 unsigned long *m, unsigned long *n)
{
{
	struct clk_fractional_divider *fd = to_clk_fd(hw);
	struct clk_fractional_divider *fd = to_clk_fd(hw);
	unsigned long scale;
	unsigned long scale;
	unsigned long m, n;
	u64 ret;

	if (!rate || rate >= *parent_rate)
		return *parent_rate;


	/*
	/*
	 * Get rate closer to *parent_rate to guarantee there is no overflow
	 * Get rate closer to *parent_rate to guarantee there is no overflow
@@ -71,7 +67,23 @@ static long clk_fd_round_rate(struct clk_hw *hw, unsigned long rate,


	rational_best_approximation(rate, *parent_rate,
	rational_best_approximation(rate, *parent_rate,
			GENMASK(fd->mwidth - 1, 0), GENMASK(fd->nwidth - 1, 0),
			GENMASK(fd->mwidth - 1, 0), GENMASK(fd->nwidth - 1, 0),
			&m, &n);
			m, n);
}

static long clk_fd_round_rate(struct clk_hw *hw, unsigned long rate,
			      unsigned long *parent_rate)
{
	struct clk_fractional_divider *fd = to_clk_fd(hw);
	unsigned long m, n;
	u64 ret;

	if (!rate || rate >= *parent_rate)
		return *parent_rate;

	if (fd->approximation)
		fd->approximation(hw, rate, parent_rate, &m, &n);
	else
		clk_fd_general_approximation(hw, rate, parent_rate, &m, &n);


	ret = (u64)*parent_rate * m;
	ret = (u64)*parent_rate * m;
	do_div(ret, n);
	do_div(ret, n);
+55 −14
Original line number Original line Diff line number Diff line
@@ -201,7 +201,7 @@ static struct rockchip_clk_branch rk3128_uart2_fracmux __initdata =
	MUX(SCLK_UART2, "sclk_uart2", mux_uart2_p, CLK_SET_RATE_PARENT,
	MUX(SCLK_UART2, "sclk_uart2", mux_uart2_p, CLK_SET_RATE_PARENT,
			RK2928_CLKSEL_CON(15), 8, 2, MFLAGS);
			RK2928_CLKSEL_CON(15), 8, 2, MFLAGS);


static struct rockchip_clk_branch rk3128_clk_branches[] __initdata = {
static struct rockchip_clk_branch common_clk_branches[] __initdata = {
	/*
	/*
	 * Clock-Architecture Diagram 1
	 * Clock-Architecture Diagram 1
	 */
	 */
@@ -459,10 +459,6 @@ static struct rockchip_clk_branch rk3128_clk_branches[] __initdata = {
			RK2928_CLKSEL_CON(2), 14, 2, MFLAGS, 8, 5, DFLAGS,
			RK2928_CLKSEL_CON(2), 14, 2, MFLAGS, 8, 5, DFLAGS,
			RK2928_CLKGATE_CON(10), 15, GFLAGS),
			RK2928_CLKGATE_CON(10), 15, GFLAGS),


	COMPOSITE(SCLK_SFC, "sclk_sfc", mux_sclk_sfc_src_p, 0,
			RK2928_CLKSEL_CON(11), 14, 2, MFLAGS, 8, 5, DFLAGS,
			RK2928_CLKGATE_CON(3), 15, GFLAGS),

	COMPOSITE_NOMUX(PCLK_PMU_PRE, "pclk_pmu_pre", "cpll", 0,
	COMPOSITE_NOMUX(PCLK_PMU_PRE, "pclk_pmu_pre", "cpll", 0,
			RK2928_CLKSEL_CON(29), 8, 6, DFLAGS,
			RK2928_CLKSEL_CON(29), 8, 6, DFLAGS,
			RK2928_CLKGATE_CON(1), 0, GFLAGS),
			RK2928_CLKGATE_CON(1), 0, GFLAGS),
@@ -495,7 +491,6 @@ static struct rockchip_clk_branch rk3128_clk_branches[] __initdata = {
	GATE(ACLK_DMAC, "aclk_dmac", "aclk_peri", 0, RK2928_CLKGATE_CON(5), 1, GFLAGS),
	GATE(ACLK_DMAC, "aclk_dmac", "aclk_peri", 0, RK2928_CLKGATE_CON(5), 1, GFLAGS),
	GATE(0, "aclk_peri_niu", "aclk_peri", CLK_IGNORE_UNUSED, RK2928_CLKGATE_CON(9), 15, GFLAGS),
	GATE(0, "aclk_peri_niu", "aclk_peri", CLK_IGNORE_UNUSED, RK2928_CLKGATE_CON(9), 15, GFLAGS),
	GATE(0, "aclk_cpu_to_peri", "aclk_peri", CLK_IGNORE_UNUSED, RK2928_CLKGATE_CON(4), 2, GFLAGS),
	GATE(0, "aclk_cpu_to_peri", "aclk_peri", CLK_IGNORE_UNUSED, RK2928_CLKGATE_CON(4), 2, GFLAGS),
	GATE(HCLK_GPS, "hclk_gps", "aclk_peri", 0, RK2928_CLKGATE_CON(3), 14, GFLAGS),


	GATE(HCLK_I2S_8CH, "hclk_i2s_8ch", "hclk_peri", 0, RK2928_CLKGATE_CON(7), 4, GFLAGS),
	GATE(HCLK_I2S_8CH, "hclk_i2s_8ch", "hclk_peri", 0, RK2928_CLKGATE_CON(7), 4, GFLAGS),
	GATE(0, "hclk_peri_matrix", "hclk_peri", CLK_IGNORE_UNUSED, RK2928_CLKGATE_CON(4), 0, GFLAGS),
	GATE(0, "hclk_peri_matrix", "hclk_peri", CLK_IGNORE_UNUSED, RK2928_CLKGATE_CON(4), 0, GFLAGS),
@@ -541,7 +536,6 @@ static struct rockchip_clk_branch rk3128_clk_branches[] __initdata = {
	GATE(0, "hclk_rom", "hclk_cpu", CLK_IGNORE_UNUSED, RK2928_CLKGATE_CON(5), 6, GFLAGS),
	GATE(0, "hclk_rom", "hclk_cpu", CLK_IGNORE_UNUSED, RK2928_CLKGATE_CON(5), 6, GFLAGS),
	GATE(HCLK_CRYPTO, "hclk_crypto", "hclk_cpu", 0, RK2928_CLKGATE_CON(3), 5, GFLAGS),
	GATE(HCLK_CRYPTO, "hclk_crypto", "hclk_cpu", 0, RK2928_CLKGATE_CON(3), 5, GFLAGS),


	GATE(PCLK_HDMI, "pclk_hdmi", "pclk_cpu", 0, RK2928_CLKGATE_CON(3), 8, GFLAGS),
	GATE(PCLK_ACODEC, "pclk_acodec", "pclk_cpu", 0, RK2928_CLKGATE_CON(5), 14, GFLAGS),
	GATE(PCLK_ACODEC, "pclk_acodec", "pclk_cpu", 0, RK2928_CLKGATE_CON(5), 14, GFLAGS),
	GATE(0, "pclk_ddrupctl", "pclk_cpu", CLK_IGNORE_UNUSED, RK2928_CLKGATE_CON(5), 7, GFLAGS),
	GATE(0, "pclk_ddrupctl", "pclk_cpu", CLK_IGNORE_UNUSED, RK2928_CLKGATE_CON(5), 7, GFLAGS),
	GATE(0, "pclk_grf", "pclk_cpu", CLK_IGNORE_UNUSED, RK2928_CLKGATE_CON(5), 4, GFLAGS),
	GATE(0, "pclk_grf", "pclk_cpu", CLK_IGNORE_UNUSED, RK2928_CLKGATE_CON(5), 4, GFLAGS),
@@ -561,6 +555,21 @@ static struct rockchip_clk_branch rk3128_clk_branches[] __initdata = {
	MMC(SCLK_EMMC_SAMPLE,  "emmc_sample",  "sclk_emmc",  RK3228_EMMC_CON1,  0),
	MMC(SCLK_EMMC_SAMPLE,  "emmc_sample",  "sclk_emmc",  RK3228_EMMC_CON1,  0),
};
};


static struct rockchip_clk_branch rk3126_clk_branches[] __initdata = {
	GATE(0, "pclk_stimer", "pclk_cpu", CLK_IGNORE_UNUSED, RK2928_CLKGATE_CON(3), 15, GFLAGS),
	GATE(0, "pclk_s_efuse", "pclk_cpu", CLK_IGNORE_UNUSED, RK2928_CLKGATE_CON(3), 14, GFLAGS),
	GATE(0, "pclk_sgrf", "pclk_cpu", CLK_IGNORE_UNUSED, RK2928_CLKGATE_CON(3), 8, GFLAGS),
};

static struct rockchip_clk_branch rk3128_clk_branches[] __initdata = {
	COMPOSITE(SCLK_SFC, "sclk_sfc", mux_sclk_sfc_src_p, 0,
			RK2928_CLKSEL_CON(11), 14, 2, MFLAGS, 8, 5, DFLAGS,
			RK2928_CLKGATE_CON(3), 15, GFLAGS),

	GATE(HCLK_GPS, "hclk_gps", "aclk_peri", 0, RK2928_CLKGATE_CON(3), 14, GFLAGS),
	GATE(PCLK_HDMI, "pclk_hdmi", "pclk_cpu", 0, RK2928_CLKGATE_CON(3), 8, GFLAGS),
};

static const char *const rk3128_critical_clocks[] __initconst = {
static const char *const rk3128_critical_clocks[] __initconst = {
	"aclk_cpu",
	"aclk_cpu",
	"hclk_cpu",
	"hclk_cpu",
@@ -570,7 +579,7 @@ static const char *const rk3128_critical_clocks[] __initconst = {
	"pclk_peri",
	"pclk_peri",
};
};


static void __init rk3128_clk_init(struct device_node *np)
static struct rockchip_clk_provider *__init rk3128_common_clk_init(struct device_node *np)
{
{
	struct rockchip_clk_provider *ctx;
	struct rockchip_clk_provider *ctx;
	void __iomem *reg_base;
	void __iomem *reg_base;
@@ -578,23 +587,21 @@ static void __init rk3128_clk_init(struct device_node *np)
	reg_base = of_iomap(np, 0);
	reg_base = of_iomap(np, 0);
	if (!reg_base) {
	if (!reg_base) {
		pr_err("%s: could not map cru region\n", __func__);
		pr_err("%s: could not map cru region\n", __func__);
		return;
		return ERR_PTR(-ENOMEM);
	}
	}


	ctx = rockchip_clk_init(np, reg_base, CLK_NR_CLKS);
	ctx = rockchip_clk_init(np, reg_base, CLK_NR_CLKS);
	if (IS_ERR(ctx)) {
	if (IS_ERR(ctx)) {
		pr_err("%s: rockchip clk init failed\n", __func__);
		pr_err("%s: rockchip clk init failed\n", __func__);
		iounmap(reg_base);
		iounmap(reg_base);
		return;
		return ERR_PTR(-ENOMEM);
	}
	}


	rockchip_clk_register_plls(ctx, rk3128_pll_clks,
	rockchip_clk_register_plls(ctx, rk3128_pll_clks,
				   ARRAY_SIZE(rk3128_pll_clks),
				   ARRAY_SIZE(rk3128_pll_clks),
				   RK3128_GRF_SOC_STATUS0);
				   RK3128_GRF_SOC_STATUS0);
	rockchip_clk_register_branches(ctx, rk3128_clk_branches,
	rockchip_clk_register_branches(ctx, common_clk_branches,
				  ARRAY_SIZE(rk3128_clk_branches));
				  ARRAY_SIZE(common_clk_branches));
	rockchip_clk_protect_critical(rk3128_critical_clocks,
				      ARRAY_SIZE(rk3128_critical_clocks));


	rockchip_clk_register_armclk(ctx, ARMCLK, "armclk",
	rockchip_clk_register_armclk(ctx, ARMCLK, "armclk",
			mux_armclk_p, ARRAY_SIZE(mux_armclk_p),
			mux_armclk_p, ARRAY_SIZE(mux_armclk_p),
@@ -606,6 +613,40 @@ static void __init rk3128_clk_init(struct device_node *np)


	rockchip_register_restart_notifier(ctx, RK2928_GLB_SRST_FST, NULL);
	rockchip_register_restart_notifier(ctx, RK2928_GLB_SRST_FST, NULL);


	return ctx;
}

static void __init rk3126_clk_init(struct device_node *np)
{
	struct rockchip_clk_provider *ctx;

	ctx = rk3128_common_clk_init(np);
	if (IS_ERR(ctx))
		return;

	rockchip_clk_register_branches(ctx, rk3126_clk_branches,
				       ARRAY_SIZE(rk3126_clk_branches));
	rockchip_clk_protect_critical(rk3128_critical_clocks,
				      ARRAY_SIZE(rk3128_critical_clocks));

	rockchip_clk_of_add_provider(np, ctx);
}

CLK_OF_DECLARE(rk3126_cru, "rockchip,rk3126-cru", rk3126_clk_init);

static void __init rk3128_clk_init(struct device_node *np)
{
	struct rockchip_clk_provider *ctx;

	ctx = rk3128_common_clk_init(np);
	if (IS_ERR(ctx))
		return;

	rockchip_clk_register_branches(ctx, rk3128_clk_branches,
				       ARRAY_SIZE(rk3128_clk_branches));
	rockchip_clk_protect_critical(rk3128_critical_clocks,
				      ARRAY_SIZE(rk3128_critical_clocks));

	rockchip_clk_of_add_provider(np, ctx);
	rockchip_clk_of_add_provider(np, ctx);
}
}


+1 −1
Original line number Original line Diff line number Diff line
@@ -391,7 +391,7 @@ static struct rockchip_clk_branch rk3228_clk_branches[] __initdata = {
			RK2928_CLKSEL_CON(11), 8, 2, MFLAGS, 0, 8, DFLAGS,
			RK2928_CLKSEL_CON(11), 8, 2, MFLAGS, 0, 8, DFLAGS,
			RK2928_CLKGATE_CON(2), 11, GFLAGS),
			RK2928_CLKGATE_CON(2), 11, GFLAGS),


	COMPOSITE_NODIV(0, "sclk_sdio_src", mux_mmc_src_p, 0,
	COMPOSITE_NODIV(SCLK_SDIO_SRC, "sclk_sdio_src", mux_mmc_src_p, 0,
			RK2928_CLKSEL_CON(11), 10, 2, MFLAGS,
			RK2928_CLKSEL_CON(11), 10, 2, MFLAGS,
			RK2928_CLKGATE_CON(2), 13, GFLAGS),
			RK2928_CLKGATE_CON(2), 13, GFLAGS),
	DIV(SCLK_SDIO, "sclk_sdio", "sclk_sdio_src", 0,
	DIV(SCLK_SDIO, "sclk_sdio", "sclk_sdio_src", 0,
+381 −81

File changed.

Preview size limit exceeded, changes collapsed.

Loading