Commit e15d598b authored by Stephen Boyd's avatar Stephen Boyd

Merge tag 'sunxi-clk-for-4.20' of...

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

Pull allwinner clock changes from Maxime Ripard:

Our usual set of changes for the Allwinner SoCs clock support.

The most notable changes are:
  - A bunch of changes and fixes to support the A64 display engine
  - Some fixes to support the A83t display engine

* tag 'sunxi-clk-for-4.20' of https://git.kernel.org/pub/scm/linux/kernel/git/sunxi/linux:
  dt-bindings: clock: sun50i-a64-ccu: Add PLL_VIDEO0 macro
  clk: sunxi-ng: a64: Add max. rate constraint to video PLLs
  clk: sunxi-ng: a64: Add minimal rate for video PLLs
  clk: sunxi-ng: sun50i: h6: Add 2x fixed post-divider to MMC module clocks
  clk: sunxi-ng: a83t: Add max. rate constraint to video PLLs
  clk: sunxi-ng: nkmp: Add constraint for maximum rate
  clk: sunxi-ng: r40: Add max. rate constraint to video PLLs
  clk: sunxi-ng: h3/h5: Add max. rate constraint to pll-video
  clk: sunxi-ng: Add maximum rate constraint to NM PLLs
  clk: sunxi-ng: h6: fix PWM gate/reset offset
  clk: sunxi-ng: h6: fix bus clocks' divider position
parents 5b394b2d 8b2a3787
...@@ -64,17 +64,19 @@ static SUNXI_CCU_NM_WITH_GATE_LOCK(pll_audio_base_clk, "pll-audio-base", ...@@ -64,17 +64,19 @@ static SUNXI_CCU_NM_WITH_GATE_LOCK(pll_audio_base_clk, "pll-audio-base",
BIT(28), /* lock */ BIT(28), /* lock */
CLK_SET_RATE_UNGATE); CLK_SET_RATE_UNGATE);
static SUNXI_CCU_NM_WITH_FRAC_GATE_LOCK(pll_video0_clk, "pll-video0", static SUNXI_CCU_NM_WITH_FRAC_GATE_LOCK_MIN_MAX(pll_video0_clk, "pll-video0",
"osc24M", 0x010, "osc24M", 0x010,
8, 7, /* N */ 192000000, /* Minimum rate */
0, 4, /* M */ 1008000000, /* Maximum rate */
BIT(24), /* frac enable */ 8, 7, /* N */
BIT(25), /* frac select */ 0, 4, /* M */
270000000, /* frac rate 0 */ BIT(24), /* frac enable */
297000000, /* frac rate 1 */ BIT(25), /* frac select */
BIT(31), /* gate */ 270000000, /* frac rate 0 */
BIT(28), /* lock */ 297000000, /* frac rate 1 */
CLK_SET_RATE_UNGATE); BIT(31), /* gate */
BIT(28), /* lock */
CLK_SET_RATE_UNGATE);
static SUNXI_CCU_NM_WITH_FRAC_GATE_LOCK(pll_ve_clk, "pll-ve", static SUNXI_CCU_NM_WITH_FRAC_GATE_LOCK(pll_ve_clk, "pll-ve",
"osc24M", 0x018, "osc24M", 0x018,
...@@ -125,17 +127,19 @@ static struct ccu_nk pll_periph1_clk = { ...@@ -125,17 +127,19 @@ static struct ccu_nk pll_periph1_clk = {
}, },
}; };
static SUNXI_CCU_NM_WITH_FRAC_GATE_LOCK(pll_video1_clk, "pll-video1", static SUNXI_CCU_NM_WITH_FRAC_GATE_LOCK_MIN_MAX(pll_video1_clk, "pll-video1",
"osc24M", 0x030, "osc24M", 0x030,
8, 7, /* N */ 192000000, /* Minimum rate */
0, 4, /* M */ 1008000000, /* Maximum rate */
BIT(24), /* frac enable */ 8, 7, /* N */
BIT(25), /* frac select */ 0, 4, /* M */
270000000, /* frac rate 0 */ BIT(24), /* frac enable */
297000000, /* frac rate 1 */ BIT(25), /* frac select */
BIT(31), /* gate */ 270000000, /* frac rate 0 */
BIT(28), /* lock */ 297000000, /* frac rate 1 */
CLK_SET_RATE_UNGATE); BIT(31), /* gate */
BIT(28), /* lock */
CLK_SET_RATE_UNGATE);
static SUNXI_CCU_NM_WITH_FRAC_GATE_LOCK(pll_gpu_clk, "pll-gpu", static SUNXI_CCU_NM_WITH_FRAC_GATE_LOCK(pll_gpu_clk, "pll-gpu",
"osc24M", 0x038, "osc24M", 0x038,
......
...@@ -27,7 +27,9 @@ ...@@ -27,7 +27,9 @@
#define CLK_PLL_AUDIO_2X 4 #define CLK_PLL_AUDIO_2X 4
#define CLK_PLL_AUDIO_4X 5 #define CLK_PLL_AUDIO_4X 5
#define CLK_PLL_AUDIO_8X 6 #define CLK_PLL_AUDIO_8X 6
#define CLK_PLL_VIDEO0 7
/* PLL_VIDEO0 exported for HDMI PHY */
#define CLK_PLL_VIDEO0_2X 8 #define CLK_PLL_VIDEO0_2X 8
#define CLK_PLL_VE 9 #define CLK_PLL_VE 9
#define CLK_PLL_DDR0 10 #define CLK_PLL_DDR0 10
......
...@@ -224,7 +224,7 @@ static SUNXI_CCU_MP_WITH_MUX(psi_ahb1_ahb2_clk, "psi-ahb1-ahb2", ...@@ -224,7 +224,7 @@ static SUNXI_CCU_MP_WITH_MUX(psi_ahb1_ahb2_clk, "psi-ahb1-ahb2",
psi_ahb1_ahb2_parents, psi_ahb1_ahb2_parents,
0x510, 0x510,
0, 5, /* M */ 0, 5, /* M */
16, 2, /* P */ 8, 2, /* P */
24, 2, /* mux */ 24, 2, /* mux */
0); 0);
...@@ -233,19 +233,19 @@ static const char * const ahb3_apb1_apb2_parents[] = { "osc24M", "osc32k", ...@@ -233,19 +233,19 @@ static const char * const ahb3_apb1_apb2_parents[] = { "osc24M", "osc32k",
"pll-periph0" }; "pll-periph0" };
static SUNXI_CCU_MP_WITH_MUX(ahb3_clk, "ahb3", ahb3_apb1_apb2_parents, 0x51c, static SUNXI_CCU_MP_WITH_MUX(ahb3_clk, "ahb3", ahb3_apb1_apb2_parents, 0x51c,
0, 5, /* M */ 0, 5, /* M */
16, 2, /* P */ 8, 2, /* P */
24, 2, /* mux */ 24, 2, /* mux */
0); 0);
static SUNXI_CCU_MP_WITH_MUX(apb1_clk, "apb1", ahb3_apb1_apb2_parents, 0x520, static SUNXI_CCU_MP_WITH_MUX(apb1_clk, "apb1", ahb3_apb1_apb2_parents, 0x520,
0, 5, /* M */ 0, 5, /* M */
16, 2, /* P */ 8, 2, /* P */
24, 2, /* mux */ 24, 2, /* mux */
0); 0);
static SUNXI_CCU_MP_WITH_MUX(apb2_clk, "apb2", ahb3_apb1_apb2_parents, 0x524, static SUNXI_CCU_MP_WITH_MUX(apb2_clk, "apb2", ahb3_apb1_apb2_parents, 0x524,
0, 5, /* M */ 0, 5, /* M */
16, 2, /* P */ 8, 2, /* P */
24, 2, /* mux */ 24, 2, /* mux */
0); 0);
...@@ -352,7 +352,7 @@ static SUNXI_CCU_GATE(bus_dbg_clk, "bus-dbg", "psi-ahb1-ahb2", ...@@ -352,7 +352,7 @@ static SUNXI_CCU_GATE(bus_dbg_clk, "bus-dbg", "psi-ahb1-ahb2",
static SUNXI_CCU_GATE(bus_psi_clk, "bus-psi", "psi-ahb1-ahb2", static SUNXI_CCU_GATE(bus_psi_clk, "bus-psi", "psi-ahb1-ahb2",
0x79c, BIT(0), 0); 0x79c, BIT(0), 0);
static SUNXI_CCU_GATE(bus_pwm_clk, "bus-pwm", "apb1", 0x79c, BIT(0), 0); static SUNXI_CCU_GATE(bus_pwm_clk, "bus-pwm", "apb1", 0x7ac, BIT(0), 0);
static SUNXI_CCU_GATE(bus_iommu_clk, "bus-iommu", "apb1", 0x7bc, BIT(0), 0); static SUNXI_CCU_GATE(bus_iommu_clk, "bus-iommu", "apb1", 0x7bc, BIT(0), 0);
...@@ -408,26 +408,29 @@ static SUNXI_CCU_GATE(bus_nand_clk, "bus-nand", "ahb3", 0x82c, BIT(0), 0); ...@@ -408,26 +408,29 @@ static SUNXI_CCU_GATE(bus_nand_clk, "bus-nand", "ahb3", 0x82c, BIT(0), 0);
static const char * const mmc_parents[] = { "osc24M", "pll-periph0-2x", static const char * const mmc_parents[] = { "osc24M", "pll-periph0-2x",
"pll-periph1-2x" }; "pll-periph1-2x" };
static SUNXI_CCU_MP_WITH_MUX_GATE(mmc0_clk, "mmc0", mmc_parents, 0x830, static SUNXI_CCU_MP_WITH_MUX_GATE_POSTDIV(mmc0_clk, "mmc0", mmc_parents, 0x830,
0, 4, /* M */ 0, 4, /* M */
8, 2, /* N */ 8, 2, /* N */
24, 3, /* mux */ 24, 3, /* mux */
BIT(31),/* gate */ BIT(31), /* gate */
0); 2, /* post-div */
0);
static SUNXI_CCU_MP_WITH_MUX_GATE(mmc1_clk, "mmc1", mmc_parents, 0x834,
0, 4, /* M */ static SUNXI_CCU_MP_WITH_MUX_GATE_POSTDIV(mmc1_clk, "mmc1", mmc_parents, 0x834,
8, 2, /* N */ 0, 4, /* M */
24, 3, /* mux */ 8, 2, /* N */
BIT(31),/* gate */ 24, 3, /* mux */
0); BIT(31), /* gate */
2, /* post-div */
static SUNXI_CCU_MP_WITH_MUX_GATE(mmc2_clk, "mmc2", mmc_parents, 0x838, 0);
0, 4, /* M */
8, 2, /* N */ static SUNXI_CCU_MP_WITH_MUX_GATE_POSTDIV(mmc2_clk, "mmc2", mmc_parents, 0x838,
24, 3, /* mux */ 0, 4, /* M */
BIT(31),/* gate */ 8, 2, /* N */
0); 24, 3, /* mux */
BIT(31), /* gate */
2, /* post-div */
0);
static SUNXI_CCU_GATE(bus_mmc0_clk, "bus-mmc0", "ahb3", 0x84c, BIT(0), 0); static SUNXI_CCU_GATE(bus_mmc0_clk, "bus-mmc0", "ahb3", 0x84c, BIT(0), 0);
static SUNXI_CCU_GATE(bus_mmc1_clk, "bus-mmc1", "ahb3", 0x84c, BIT(1), 0); static SUNXI_CCU_GATE(bus_mmc1_clk, "bus-mmc1", "ahb3", 0x84c, BIT(1), 0);
......
...@@ -108,6 +108,7 @@ static struct ccu_nkmp pll_video0_clk = { ...@@ -108,6 +108,7 @@ static struct ccu_nkmp pll_video0_clk = {
.n = _SUNXI_CCU_MULT_OFFSET_MIN_MAX(8, 8, 0, 12, 0), .n = _SUNXI_CCU_MULT_OFFSET_MIN_MAX(8, 8, 0, 12, 0),
.m = _SUNXI_CCU_DIV(16, 1), /* input divider */ .m = _SUNXI_CCU_DIV(16, 1), /* input divider */
.p = _SUNXI_CCU_DIV(0, 2), /* output divider */ .p = _SUNXI_CCU_DIV(0, 2), /* output divider */
.max_rate = 3000000000UL,
.common = { .common = {
.reg = 0x010, .reg = 0x010,
.lock_reg = CCU_SUN8I_A83T_LOCK_REG, .lock_reg = CCU_SUN8I_A83T_LOCK_REG,
...@@ -220,6 +221,7 @@ static struct ccu_nkmp pll_video1_clk = { ...@@ -220,6 +221,7 @@ static struct ccu_nkmp pll_video1_clk = {
.n = _SUNXI_CCU_MULT_OFFSET_MIN_MAX(8, 8, 0, 12, 0), .n = _SUNXI_CCU_MULT_OFFSET_MIN_MAX(8, 8, 0, 12, 0),
.m = _SUNXI_CCU_DIV(16, 1), /* input divider */ .m = _SUNXI_CCU_DIV(16, 1), /* input divider */
.p = _SUNXI_CCU_DIV(0, 2), /* external divider p */ .p = _SUNXI_CCU_DIV(0, 2), /* external divider p */
.max_rate = 3000000000UL,
.common = { .common = {
.reg = 0x04c, .reg = 0x04c,
.lock_reg = CCU_SUN8I_A83T_LOCK_REG, .lock_reg = CCU_SUN8I_A83T_LOCK_REG,
......
...@@ -69,18 +69,19 @@ static SUNXI_CCU_NM_WITH_SDM_GATE_LOCK(pll_audio_base_clk, "pll-audio-base", ...@@ -69,18 +69,19 @@ static SUNXI_CCU_NM_WITH_SDM_GATE_LOCK(pll_audio_base_clk, "pll-audio-base",
BIT(28), /* lock */ BIT(28), /* lock */
CLK_SET_RATE_UNGATE); CLK_SET_RATE_UNGATE);
static SUNXI_CCU_NM_WITH_FRAC_GATE_LOCK_MIN(pll_video_clk, "pll-video", static SUNXI_CCU_NM_WITH_FRAC_GATE_LOCK_MIN_MAX(pll_video_clk, "pll-video",
"osc24M", 0x0010, "osc24M", 0x0010,
192000000, /* Minimum rate */ 192000000, /* Minimum rate */
8, 7, /* N */ 912000000, /* Maximum rate */
0, 4, /* M */ 8, 7, /* N */
BIT(24), /* frac enable */ 0, 4, /* M */
BIT(25), /* frac select */ BIT(24), /* frac enable */
270000000, /* frac rate 0 */ BIT(25), /* frac select */
297000000, /* frac rate 1 */ 270000000, /* frac rate 0 */
BIT(31), /* gate */ 297000000, /* frac rate 1 */
BIT(28), /* lock */ BIT(31), /* gate */
CLK_SET_RATE_UNGATE); BIT(28), /* lock */
CLK_SET_RATE_UNGATE);
static SUNXI_CCU_NM_WITH_FRAC_GATE_LOCK(pll_ve_clk, "pll-ve", static SUNXI_CCU_NM_WITH_FRAC_GATE_LOCK(pll_ve_clk, "pll-ve",
"osc24M", 0x0018, "osc24M", 0x0018,
......
...@@ -65,19 +65,19 @@ static SUNXI_CCU_NM_WITH_GATE_LOCK(pll_audio_base_clk, "pll-audio-base", ...@@ -65,19 +65,19 @@ static SUNXI_CCU_NM_WITH_GATE_LOCK(pll_audio_base_clk, "pll-audio-base",
BIT(28), /* lock */ BIT(28), /* lock */
CLK_SET_RATE_UNGATE); CLK_SET_RATE_UNGATE);
/* TODO: The result of N/M is required to be in [8, 25] range. */ static SUNXI_CCU_NM_WITH_FRAC_GATE_LOCK_MIN_MAX(pll_video0_clk, "pll-video0",
static SUNXI_CCU_NM_WITH_FRAC_GATE_LOCK_MIN(pll_video0_clk, "pll-video0", "osc24M", 0x0010,
"osc24M", 0x0010, 192000000, /* Minimum rate */
192000000, /* Minimum rate */ 1008000000, /* Maximum rate */
8, 7, /* N */ 8, 7, /* N */
0, 4, /* M */ 0, 4, /* M */
BIT(24), /* frac enable */ BIT(24), /* frac enable */
BIT(25), /* frac select */ BIT(25), /* frac select */
270000000, /* frac rate 0 */ 270000000, /* frac rate 0 */
297000000, /* frac rate 1 */ 297000000, /* frac rate 1 */
BIT(31), /* gate */ BIT(31), /* gate */
BIT(28), /* lock */ BIT(28), /* lock */
CLK_SET_RATE_UNGATE); CLK_SET_RATE_UNGATE);
/* TODO: The result of N/M is required to be in [8, 25] range. */ /* TODO: The result of N/M is required to be in [8, 25] range. */
static SUNXI_CCU_NM_WITH_FRAC_GATE_LOCK(pll_ve_clk, "pll-ve", static SUNXI_CCU_NM_WITH_FRAC_GATE_LOCK(pll_ve_clk, "pll-ve",
...@@ -152,19 +152,19 @@ static struct ccu_nk pll_periph1_clk = { ...@@ -152,19 +152,19 @@ static struct ccu_nk pll_periph1_clk = {
}, },
}; };
/* TODO: The result of N/M is required to be in [8, 25] range. */ static SUNXI_CCU_NM_WITH_FRAC_GATE_LOCK_MIN_MAX(pll_video1_clk, "pll-video1",
static SUNXI_CCU_NM_WITH_FRAC_GATE_LOCK_MIN(pll_video1_clk, "pll-video1", "osc24M", 0x030,
"osc24M", 0x030, 192000000, /* Minimum rate */
192000000, /* Minimum rate */ 1008000000, /* Maximum rate */
8, 7, /* N */ 8, 7, /* N */
0, 4, /* M */ 0, 4, /* M */
BIT(24), /* frac enable */ BIT(24), /* frac enable */
BIT(25), /* frac select */ BIT(25), /* frac select */
270000000, /* frac rate 0 */ 270000000, /* frac rate 0 */
297000000, /* frac rate 1 */ 297000000, /* frac rate 1 */
BIT(31), /* gate */ BIT(31), /* gate */
BIT(28), /* lock */ BIT(28), /* lock */
CLK_SET_RATE_UNGATE); CLK_SET_RATE_UNGATE);
static struct ccu_nkm pll_sata_clk = { static struct ccu_nkm pll_sata_clk = {
.enable = BIT(31), .enable = BIT(31),
......
...@@ -137,6 +137,13 @@ static long ccu_nkmp_round_rate(struct clk_hw *hw, unsigned long rate, ...@@ -137,6 +137,13 @@ static long ccu_nkmp_round_rate(struct clk_hw *hw, unsigned long rate,
if (nkmp->common.features & CCU_FEATURE_FIXED_POSTDIV) if (nkmp->common.features & CCU_FEATURE_FIXED_POSTDIV)
rate *= nkmp->fixed_post_div; rate *= nkmp->fixed_post_div;
if (nkmp->max_rate && rate > nkmp->max_rate) {
rate = nkmp->max_rate;
if (nkmp->common.features & CCU_FEATURE_FIXED_POSTDIV)
rate /= nkmp->fixed_post_div;
return rate;
}
_nkmp.min_n = nkmp->n.min ?: 1; _nkmp.min_n = nkmp->n.min ?: 1;
_nkmp.max_n = nkmp->n.max ?: 1 << nkmp->n.width; _nkmp.max_n = nkmp->n.max ?: 1 << nkmp->n.width;
_nkmp.min_k = nkmp->k.min ?: 1; _nkmp.min_k = nkmp->k.min ?: 1;
......
...@@ -35,6 +35,7 @@ struct ccu_nkmp { ...@@ -35,6 +35,7 @@ struct ccu_nkmp {
struct ccu_div_internal p; struct ccu_div_internal p;
unsigned int fixed_post_div; unsigned int fixed_post_div;
unsigned int max_rate;
struct ccu_common common; struct ccu_common common;
}; };
......
...@@ -124,6 +124,13 @@ static long ccu_nm_round_rate(struct clk_hw *hw, unsigned long rate, ...@@ -124,6 +124,13 @@ static long ccu_nm_round_rate(struct clk_hw *hw, unsigned long rate,
return rate; return rate;
} }
if (nm->max_rate && rate > nm->max_rate) {
rate = nm->max_rate;
if (nm->common.features & CCU_FEATURE_FIXED_POSTDIV)
rate /= nm->fixed_post_div;
return rate;
}
if (ccu_frac_helper_has_rate(&nm->common, &nm->frac, rate)) { if (ccu_frac_helper_has_rate(&nm->common, &nm->frac, rate)) {
if (nm->common.features & CCU_FEATURE_FIXED_POSTDIV) if (nm->common.features & CCU_FEATURE_FIXED_POSTDIV)
rate /= nm->fixed_post_div; rate /= nm->fixed_post_div;
......
...@@ -38,6 +38,7 @@ struct ccu_nm { ...@@ -38,6 +38,7 @@ struct ccu_nm {
unsigned int fixed_post_div; unsigned int fixed_post_div;
unsigned int min_rate; unsigned int min_rate;
unsigned int max_rate;
struct ccu_common common; struct ccu_common common;
}; };
...@@ -115,6 +116,35 @@ struct ccu_nm { ...@@ -115,6 +116,35 @@ struct ccu_nm {
}, \ }, \
} }
#define SUNXI_CCU_NM_WITH_FRAC_GATE_LOCK_MIN_MAX(_struct, _name, \
_parent, _reg, \
_min_rate, _max_rate, \
_nshift, _nwidth, \
_mshift, _mwidth, \
_frac_en, _frac_sel, \
_frac_rate_0, \
_frac_rate_1, \
_gate, _lock, _flags) \
struct ccu_nm _struct = { \
.enable = _gate, \
.lock = _lock, \
.n = _SUNXI_CCU_MULT(_nshift, _nwidth), \
.m = _SUNXI_CCU_DIV(_mshift, _mwidth), \
.frac = _SUNXI_CCU_FRAC(_frac_en, _frac_sel, \
_frac_rate_0, \
_frac_rate_1), \
.min_rate = _min_rate, \
.max_rate = _max_rate, \
.common = { \
.reg = _reg, \
.features = CCU_FEATURE_FRACTIONAL, \
.hw.init = CLK_HW_INIT(_name, \
_parent, \
&ccu_nm_ops, \
_flags), \
}, \
}
#define SUNXI_CCU_NM_WITH_GATE_LOCK(_struct, _name, _parent, _reg, \ #define SUNXI_CCU_NM_WITH_GATE_LOCK(_struct, _name, _parent, _reg, \
_nshift, _nwidth, \ _nshift, _nwidth, \
_mshift, _mwidth, \ _mshift, _mwidth, \
......
...@@ -43,6 +43,7 @@ ...@@ -43,6 +43,7 @@
#ifndef _DT_BINDINGS_CLK_SUN50I_A64_H_ #ifndef _DT_BINDINGS_CLK_SUN50I_A64_H_
#define _DT_BINDINGS_CLK_SUN50I_A64_H_ #define _DT_BINDINGS_CLK_SUN50I_A64_H_
#define CLK_PLL_VIDEO0 7
#define CLK_PLL_PERIPH0 11 #define CLK_PLL_PERIPH0 11
#define CLK_BUS_MIPI_DSI 28 #define CLK_BUS_MIPI_DSI 28
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment