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

Merge tag 'sunxi-clk-fixes-for-6.9-1' of...

Merge tag 'sunxi-clk-fixes-for-6.9-1' of https://git.kernel.org/pub/scm/linux/kernel/git/sunxi/linux into clk-fixes

Pull Allwinner clk driver fixes from Jernej Skrabec:

 - fix H6 CPU rate change via reparenting
 - set A64 MIPI PLL min & max rate

* tag 'sunxi-clk-fixes-for-6.9-1' of https://git.kernel.org/pub/scm/linux/kernel/git/sunxi/linux:
  clk: sunxi-ng: a64: Set minimum and maximum rate for PLL-MIPI
  clk: sunxi-ng: common: Support minimum and maximum rate
  clk: sunxi-ng: h6: Reparent CPUX during PLL CPUX rate change
parents f8981b0d 69f16d9b
Loading
Loading
Loading
Loading
+2 −0
Original line number Diff line number Diff line
@@ -182,6 +182,8 @@ static struct ccu_nkm pll_mipi_clk = {
					      &ccu_nkm_ops,
					      CLK_SET_RATE_UNGATE | CLK_SET_RATE_PARENT),
		.features	= CCU_FEATURE_CLOSEST_RATE,
		.min_rate	= 500000000,
		.max_rate	= 1400000000,
	},
};

+17 −2
Original line number Diff line number Diff line
@@ -1181,11 +1181,18 @@ static const u32 usb2_clk_regs[] = {
	SUN50I_H6_USB3_CLK_REG,
};

static struct ccu_mux_nb sun50i_h6_cpu_nb = {
	.common		= &cpux_clk.common,
	.cm		= &cpux_clk.mux,
	.delay_us       = 1,
	.bypass_index   = 0, /* index of 24 MHz oscillator */
};

static int sun50i_h6_ccu_probe(struct platform_device *pdev)
{
	void __iomem *reg;
	int i, ret;
	u32 val;
	int i;

	reg = devm_platform_ioremap_resource(pdev, 0);
	if (IS_ERR(reg))
@@ -1252,7 +1259,15 @@ static int sun50i_h6_ccu_probe(struct platform_device *pdev)
	val |= BIT(24);
	writel(val, reg + SUN50I_H6_HDMI_CEC_CLK_REG);

	return devm_sunxi_ccu_probe(&pdev->dev, reg, &sun50i_h6_ccu_desc);
	ret = devm_sunxi_ccu_probe(&pdev->dev, reg, &sun50i_h6_ccu_desc);
	if (ret)
		return ret;

	/* Reparent CPU during PLL CPUX rate changes */
	ccu_mux_notifier_register(pll_cpux_clk.common.hw.clk,
				  &sun50i_h6_cpu_nb);

	return 0;
}

static const struct of_device_id sun50i_h6_ccu_ids[] = {
+19 −0
Original line number Diff line number Diff line
@@ -44,6 +44,16 @@ bool ccu_is_better_rate(struct ccu_common *common,
			unsigned long current_rate,
			unsigned long best_rate)
{
	unsigned long min_rate, max_rate;

	clk_hw_get_rate_range(&common->hw, &min_rate, &max_rate);

	if (current_rate > max_rate)
		return false;

	if (current_rate < min_rate)
		return false;

	if (common->features & CCU_FEATURE_CLOSEST_RATE)
		return abs(current_rate - target_rate) < abs(best_rate - target_rate);

@@ -122,6 +132,7 @@ static int sunxi_ccu_probe(struct sunxi_ccu *ccu, struct device *dev,

	for (i = 0; i < desc->hw_clks->num ; i++) {
		struct clk_hw *hw = desc->hw_clks->hws[i];
		struct ccu_common *common = hw_to_ccu_common(hw);
		const char *name;

		if (!hw)
@@ -136,6 +147,14 @@ static int sunxi_ccu_probe(struct sunxi_ccu *ccu, struct device *dev,
			pr_err("Couldn't register clock %d - %s\n", i, name);
			goto err_clk_unreg;
		}

		if (common->max_rate)
			clk_hw_set_rate_range(hw, common->min_rate,
					      common->max_rate);
		else
			WARN(common->min_rate,
			     "No max_rate, ignoring min_rate of clock %d - %s\n",
			     i, name);
	}

	ret = of_clk_add_hw_provider(node, of_clk_hw_onecell_get,
+3 −0
Original line number Diff line number Diff line
@@ -31,6 +31,9 @@ struct ccu_common {
	u16		lock_reg;
	u32		prediv;

	unsigned long	min_rate;
	unsigned long	max_rate;

	unsigned long	features;
	spinlock_t	*lock;
	struct clk_hw	hw;