Commit 364a609d authored by Stephen Boyd's avatar Stephen Boyd
Browse files

Merge tag 'sunxi-clk-for-6.6-2' of...

Merge tag 'sunxi-clk-for-6.6-2' of https://git.kernel.org/pub/scm/linux/kernel/git/sunxi/linux into clk-allwinner

Pull Allwinner clk driver changes from Chen-Yu Tsai:

 - Parameter name correction for ccu_nkm_round_rate()
 - Implement CLK_SET_RATE_PARENT for NKM clocks, i.e. consider alternative
   parent rates when determining clock rates
 - Set CLK_SET_RATE_PARENT for A64 pll-mipi
 - Support finding closest (as opposed to closest but not higher) clock
   rate for NM, NKM, mux and div type clocks, as use it for A64
   pll-video0
 - Prefer current parent rate if able to generate ideal clock rate for
   NKM clocks

* tag 'sunxi-clk-for-6.6-2' of https://git.kernel.org/pub/scm/linux/kernel/git/sunxi/linux:
  clk: sunxi-ng: nkm: Prefer current parent rate
  clk: sunxi-ng: a64: select closest rate for pll-video0
  clk: sunxi-ng: div: Support finding closest rate
  clk: sunxi-ng: mux: Support finding closest rate
  clk: sunxi-ng: nkm: Support finding closest rate
  clk: sunxi-ng: nm: Support finding closest rate
  clk: sunxi-ng: Add helper function to find closest rate
  clk: sunxi-ng: Add feature to find closest rate
  clk: sunxi-ng: a64: allow pll-mipi to set parent's rate
  clk: sunxi-ng: nkm: consider alternative parent rates when determining rate
  clk: sunxi-ng: nkm: Use correct parameter name for parent HW
parents 7458ea38 a69f9463
Loading
Loading
Loading
Loading
+18 −23
Original line number Diff line number Diff line
@@ -68,7 +68,7 @@ static SUNXI_CCU_NM_WITH_SDM_GATE_LOCK(pll_audio_base_clk, "pll-audio-base",
				       BIT(28),	/* lock */
				       CLK_SET_RATE_UNGATE);

static SUNXI_CCU_NM_WITH_FRAC_GATE_LOCK_MIN_MAX(pll_video0_clk, "pll-video0",
static SUNXI_CCU_NM_WITH_FRAC_GATE_LOCK_MIN_MAX_CLOSEST(pll_video0_clk, "pll-video0",
						"osc24M", 0x010,
						192000000,	/* Minimum rate */
						1008000000,	/* Maximum rate */
@@ -179,7 +179,9 @@ static struct ccu_nkm pll_mipi_clk = {
	.common		= {
		.reg		= 0x040,
		.hw.init	= CLK_HW_INIT("pll-mipi", "pll-video0",
					      &ccu_nkm_ops, CLK_SET_RATE_UNGATE),
					      &ccu_nkm_ops,
					      CLK_SET_RATE_UNGATE | CLK_SET_RATE_PARENT),
		.features	= CCU_FEATURE_CLOSEST_RATE,
	},
};

@@ -536,25 +538,18 @@ static SUNXI_CCU_M_WITH_MUX_GATE(de_clk, "de", de_parents,

static const char * const tcon0_parents[] = { "pll-mipi", "pll-video0-2x" };
static const u8 tcon0_table[] = { 0, 2, };
static SUNXI_CCU_MUX_TABLE_WITH_GATE(tcon0_clk, "tcon0", tcon0_parents,
static SUNXI_CCU_MUX_TABLE_WITH_GATE_CLOSEST(tcon0_clk, "tcon0", tcon0_parents,
					     tcon0_table, 0x118, 24, 3, BIT(31),
				     CLK_SET_RATE_PARENT |
				     CLK_SET_RATE_NO_REPARENT);
					     CLK_SET_RATE_PARENT | CLK_SET_RATE_NO_REPARENT);

static const char * const tcon1_parents[] = { "pll-video0", "pll-video1" };
static const u8 tcon1_table[] = { 0, 2, };
static struct ccu_div tcon1_clk = {
	.enable		= BIT(31),
	.div		= _SUNXI_CCU_DIV(0, 4),
	.mux		= _SUNXI_CCU_MUX_TABLE(24, 2, tcon1_table),
	.common		= {
		.reg		= 0x11c,
		.hw.init	= CLK_HW_INIT_PARENTS("tcon1",
						      tcon1_parents,
						      &ccu_div_ops,
						      CLK_SET_RATE_PARENT),
	},
};
static SUNXI_CCU_M_WITH_MUX_TABLE_GATE_CLOSEST(tcon1_clk, "tcon1", tcon1_parents,
					       tcon1_table, 0x11c,
					       0, 4,	/* M */
					       24, 2,	/* mux */
					       BIT(31),	/* gate */
					       CLK_SET_RATE_PARENT);

static const char * const deinterlace_parents[] = { "pll-periph0", "pll-periph1" };
static SUNXI_CCU_M_WITH_MUX_GATE(deinterlace_clk, "deinterlace", deinterlace_parents,
@@ -584,7 +579,7 @@ static SUNXI_CCU_GATE(avs_clk, "avs", "osc24M",
		      0x144, BIT(31), 0);

static const char * const hdmi_parents[] = { "pll-video0", "pll-video1" };
static SUNXI_CCU_M_WITH_MUX_GATE(hdmi_clk, "hdmi", hdmi_parents,
static SUNXI_CCU_M_WITH_MUX_GATE_CLOSEST(hdmi_clk, "hdmi", hdmi_parents,
					 0x150, 0, 4, 24, 2, BIT(31), CLK_SET_RATE_PARENT);

static SUNXI_CCU_GATE(hdmi_ddc_clk,	"hdmi-ddc",	"osc24M",
@@ -597,7 +592,7 @@ static SUNXI_CCU_M_WITH_MUX_GATE(mbus_clk, "mbus", mbus_parents,

static const char * const dsi_dphy_parents[] = { "pll-video0", "pll-periph0" };
static const u8 dsi_dphy_table[] = { 0, 2, };
static SUNXI_CCU_M_WITH_MUX_TABLE_GATE(dsi_dphy_clk, "dsi-dphy",
static SUNXI_CCU_M_WITH_MUX_TABLE_GATE_CLOSEST(dsi_dphy_clk, "dsi-dphy",
					       dsi_dphy_parents, dsi_dphy_table,
					       0x168, 0, 4, 8, 2, BIT(15), CLK_SET_RATE_PARENT);

+12 −0
Original line number Diff line number Diff line
@@ -39,6 +39,18 @@ void ccu_helper_wait_for_lock(struct ccu_common *common, u32 lock)
}
EXPORT_SYMBOL_NS_GPL(ccu_helper_wait_for_lock, SUNXI_CCU);

bool ccu_is_better_rate(struct ccu_common *common,
			unsigned long target_rate,
			unsigned long current_rate,
			unsigned long best_rate)
{
	if (common->features & CCU_FEATURE_CLOSEST_RATE)
		return abs(current_rate - target_rate) < abs(best_rate - target_rate);

	return current_rate <= target_rate && current_rate > best_rate;
}
EXPORT_SYMBOL_NS_GPL(ccu_is_better_rate, SUNXI_CCU);

/*
 * This clock notifier is called when the frequency of a PLL clock is
 * changed. In common PLL designs, changes to the dividers take effect
+6 −0
Original line number Diff line number Diff line
@@ -18,6 +18,7 @@
#define CCU_FEATURE_MMC_TIMING_SWITCH	BIT(6)
#define CCU_FEATURE_SIGMA_DELTA_MOD	BIT(7)
#define CCU_FEATURE_KEY_FIELD		BIT(8)
#define CCU_FEATURE_CLOSEST_RATE	BIT(9)

/* MMC timing mode switch bit */
#define CCU_MMC_NEW_TIMING_MODE		BIT(30)
@@ -52,6 +53,11 @@ struct sunxi_ccu_desc {

void ccu_helper_wait_for_lock(struct ccu_common *common, u32 lock);

bool ccu_is_better_rate(struct ccu_common *common,
			unsigned long target_rate,
			unsigned long current_rate,
			unsigned long best_rate);

struct ccu_pll_nb {
	struct notifier_block	clk_nb;
	struct ccu_common	*common;
+30 −0
Original line number Diff line number Diff line
@@ -143,6 +143,26 @@ struct ccu_div {
		},							\
	}

#define SUNXI_CCU_M_WITH_MUX_TABLE_GATE_CLOSEST(_struct, _name,		\
						_parents, _table,	\
						_reg,			\
						_mshift, _mwidth,	\
						_muxshift, _muxwidth,	\
						_gate, _flags)		\
	struct ccu_div _struct = {					\
		.enable	= _gate,					\
		.div	= _SUNXI_CCU_DIV_FLAGS(_mshift, _mwidth, CLK_DIVIDER_ROUND_CLOSEST), \
		.mux	= _SUNXI_CCU_MUX_TABLE(_muxshift, _muxwidth, _table), \
		.common	= {						\
			.reg		= _reg,				\
			.hw.init	= CLK_HW_INIT_PARENTS(_name,	\
							      _parents, \
							      &ccu_div_ops, \
							      _flags),	\
			.features	= CCU_FEATURE_CLOSEST_RATE,	\
		},							\
	}

#define SUNXI_CCU_M_WITH_MUX_GATE(_struct, _name, _parents, _reg,	\
				  _mshift, _mwidth, _muxshift, _muxwidth, \
				  _gate, _flags)			\
@@ -152,6 +172,16 @@ struct ccu_div {
					_muxshift, _muxwidth,		\
					_gate, _flags)

#define SUNXI_CCU_M_WITH_MUX_GATE_CLOSEST(_struct, _name, _parents,	\
					  _reg, _mshift, _mwidth,	\
					  _muxshift, _muxwidth,		\
					  _gate, _flags)		\
	SUNXI_CCU_M_WITH_MUX_TABLE_GATE_CLOSEST(_struct, _name,		\
						_parents, NULL,		\
						_reg, _mshift, _mwidth,	\
						_muxshift, _muxwidth,	\
						_gate, _flags)

#define SUNXI_CCU_M_WITH_MUX(_struct, _name, _parents, _reg,		\
			     _mshift, _mwidth, _muxshift, _muxwidth,	\
			     _flags)					\
+13 −2
Original line number Diff line number Diff line
@@ -139,7 +139,7 @@ int ccu_mux_helper_determine_rate(struct ccu_common *common,
			goto out;
		}

		if ((req->rate - tmp_rate) < (req->rate - best_rate)) {
		if (ccu_is_better_rate(common, req->rate, tmp_rate, best_rate)) {
			best_rate = tmp_rate;
			best_parent_rate = parent_rate;
			best_parent = parent;
@@ -242,6 +242,17 @@ static int ccu_mux_set_parent(struct clk_hw *hw, u8 index)
	return ccu_mux_helper_set_parent(&cm->common, &cm->mux, index);
}

static int ccu_mux_determine_rate(struct clk_hw *hw,
				  struct clk_rate_request *req)
{
	struct ccu_mux *cm = hw_to_ccu_mux(hw);

	if (cm->common.features & CCU_FEATURE_CLOSEST_RATE)
		return clk_mux_determine_rate_flags(hw, req, CLK_MUX_ROUND_CLOSEST);

	return clk_mux_determine_rate_flags(hw, req, 0);
}

static unsigned long ccu_mux_recalc_rate(struct clk_hw *hw,
					 unsigned long parent_rate)
{
@@ -259,7 +270,7 @@ const struct clk_ops ccu_mux_ops = {
	.get_parent	= ccu_mux_get_parent,
	.set_parent	= ccu_mux_set_parent,

	.determine_rate	= __clk_mux_determine_rate,
	.determine_rate	= ccu_mux_determine_rate,
	.recalc_rate	= ccu_mux_recalc_rate,
};
EXPORT_SYMBOL_NS_GPL(ccu_mux_ops, SUNXI_CCU);
Loading