mirror of
https://github.com/openbsd/src.git
synced 2026-04-24 14:14:37 +00:00
Add support for RK3576 clocks and resets.
A couple of additional clocks from kevlo@ ok kevlo@
This commit is contained in:
@@ -1,4 +1,4 @@
|
||||
/* $OpenBSD: rkclock.c,v 1.94 2025/12/27 14:55:18 patrick Exp $ */
|
||||
/* $OpenBSD: rkclock.c,v 1.95 2026/03/11 16:32:42 kettenis Exp $ */
|
||||
/*
|
||||
* Copyright (c) 2017, 2018 Mark Kettenis <kettenis@openbsd.org>
|
||||
*
|
||||
@@ -195,6 +195,19 @@
|
||||
#define RK3568_PMUCRU_CLKSEL_CON(i) (0x0100 + (i) * 4)
|
||||
#define RK3568_PMUCRU_GATE_CON(i) (0x0180 + (i) * 4)
|
||||
|
||||
/* RK3576 registers */
|
||||
#define RK3576_CRU_AUPLL_CON(i) (0x00180 + (i) * 4)
|
||||
#define RK3576_CRU_CPLL_CON(i) (0x001a0 + (i) * 4)
|
||||
#define RK3576_CRU_GPLL_CON(i) (0x001c0 + (i) * 4)
|
||||
#define RK3576_CRU_MODE_CON 0x00280
|
||||
#define RK3576_CRU_CLKSEL_CON(i) (0x00300 + (i) * 4)
|
||||
#define RK3576_CRU_GATE_CON(i) (0x00800 + (i) * 4)
|
||||
#define RK3576_CRU_SOFTRST_CON(i) (0x00a00 + (i) * 4)
|
||||
#define RK3576_PHPTOPCRU_PPLL_CON(i) (0x08200 + (i) * 4)
|
||||
#define RK3576_PHPTOPCRU_CLKSEL_CON(i) (0x08300 + (i) * 4)
|
||||
#define RK3576_PHPTOPCRU_GATE_CON(i) (0x08800 + (i) * 4)
|
||||
#define RK3576_PHPTOPCRU_SOFTRST_CON(i) (0x08a00 + (i) * 4)
|
||||
|
||||
/* RK3588 registers */
|
||||
#define RK3588_CRU_AUPLL_CON(i) (0x00180 + (i) * 4)
|
||||
#define RK3588_CRU_CPLL_CON(i) (0x001a0 + (i) * 4)
|
||||
@@ -326,7 +339,16 @@ int rk3568_pmu_set_frequency(void *, uint32_t *, uint32_t);
|
||||
void rk3568_pmu_enable(void *, uint32_t *, int);
|
||||
void rk3568_pmu_reset(void *, uint32_t *, int);
|
||||
|
||||
void rk3576_init(struct rkclock_softc *);
|
||||
uint32_t rk3576_get_frequency(void *, uint32_t *);
|
||||
int rk3576_set_frequency(void *, uint32_t *, uint32_t);
|
||||
int rk3576_set_parent(void *, uint32_t *, uint32_t *);
|
||||
void rk3576_enable(void *, uint32_t *, int);
|
||||
void rk3576_reset(void *, uint32_t *, int);
|
||||
|
||||
void rk3588_init(struct rkclock_softc *);
|
||||
int rk3588_set_pll(struct rkclock_softc *, bus_size_t, uint32_t);
|
||||
uint32_t rk3588_get_pll(struct rkclock_softc *, bus_size_t);
|
||||
uint32_t rk3588_get_frequency(void *, uint32_t *);
|
||||
int rk3588_set_frequency(void *, uint32_t *, uint32_t);
|
||||
void rk3588_enable(void *, uint32_t *, int);
|
||||
@@ -393,6 +415,12 @@ const struct rkclock_compat rkclock_compat[] = {
|
||||
rk3568_pmu_set_frequency, NULL,
|
||||
rk3568_pmu_reset
|
||||
},
|
||||
{
|
||||
"rockchip,rk3576-cru", NULL, 1, rk3576_init,
|
||||
rk3576_enable, rk3576_get_frequency,
|
||||
rk3576_set_frequency, rk3576_set_parent,
|
||||
rk3576_reset
|
||||
},
|
||||
{
|
||||
"rockchip,rk3588-cru", NULL, 1, rk3588_init,
|
||||
rk3588_enable, rk3588_get_frequency,
|
||||
@@ -4116,6 +4144,299 @@ rk3568_pmu_reset(void *cookie, uint32_t *cells, int on)
|
||||
printf("%s: 0x%08x\n", __func__, idx);
|
||||
}
|
||||
|
||||
/*
|
||||
* Rockchip RK3576
|
||||
*/
|
||||
|
||||
const struct rkclock rk3576_clocks[] = {
|
||||
{
|
||||
RK3576_CLK_CPLL_DIV20, RK3576_CRU_CLKSEL_CON(0),
|
||||
SEL(5, 5), DIV(4, 0), { RK3576_PLL_GPLL, RK3576_PLL_CPLL },
|
||||
},
|
||||
{
|
||||
RK3576_CLK_CPLL_DIV10, RK3576_CRU_CLKSEL_CON(0),
|
||||
SEL(11, 11), DIV(10, 6), { RK3576_PLL_GPLL, RK3576_PLL_CPLL },
|
||||
},
|
||||
{
|
||||
RK3576_CLK_GPLL_DIV8, RK3576_CRU_CLKSEL_CON(1),
|
||||
SEL(5, 5), DIV(4, 0), { RK3576_PLL_GPLL, RK3576_PLL_CPLL },
|
||||
},
|
||||
{
|
||||
RK3576_CLK_GPLL_DIV6, RK3576_CRU_CLKSEL_CON(1),
|
||||
SEL(11, 11), DIV(10, 6), { RK3576_PLL_GPLL, RK3576_PLL_CPLL },
|
||||
},
|
||||
{
|
||||
RK3576_CLK_CPLL_DIV4, RK3576_CRU_CLKSEL_CON(2),
|
||||
SEL(5, 5), DIV(4, 0), { RK3576_PLL_GPLL, RK3576_PLL_CPLL },
|
||||
},
|
||||
{
|
||||
RK3576_CLK_CPLL_DIV2, RK3576_CRU_CLKSEL_CON(4),
|
||||
SEL(11, 11), DIV(10, 6), { RK3576_PLL_GPLL, RK3576_PLL_CPLL },
|
||||
},
|
||||
{
|
||||
RK3576_CLK_GMAC0_125M_SRC, RK3576_CRU_CLKSEL_CON(30),
|
||||
0, DIV(14, 10), { RK3576_PLL_CPLL },
|
||||
},
|
||||
{
|
||||
RK3576_CLK_I2C1, RK3576_CRU_CLKSEL_CON(57),
|
||||
SEL(1, 0), 0,
|
||||
{ RK3576_CLK_GPLL_DIV6, RK3576_CLK_CPLL_DIV10,
|
||||
RK3576_CLK_CPLL_DIV20, RK3576_XIN24M },
|
||||
},
|
||||
{
|
||||
RK3576_CLK_I2C2, RK3576_CRU_CLKSEL_CON(57),
|
||||
SEL(3, 2), 0,
|
||||
{ RK3576_CLK_GPLL_DIV6, RK3576_CLK_CPLL_DIV10,
|
||||
RK3576_CLK_CPLL_DIV20, RK3576_XIN24M },
|
||||
},
|
||||
{
|
||||
RK3576_CLK_I2C5, RK3576_CRU_CLKSEL_CON(57),
|
||||
SEL(9, 8), 0,
|
||||
{ RK3576_CLK_GPLL_DIV6, RK3576_CLK_CPLL_DIV10,
|
||||
RK3576_CLK_CPLL_DIV20, RK3576_XIN24M },
|
||||
},
|
||||
{
|
||||
RK3576_SCLK_UART0, RK3576_CRU_CLKSEL_CON(60),
|
||||
SEL(10, 8), DIV(7, 0),
|
||||
{ RK3576_PLL_GPLL, RK3576_PLL_CPLL, RK3576_PLL_AUPLL,
|
||||
RK3576_XIN24M, RK3576_CLK_UART_FRAC_0,
|
||||
RK3576_CLK_UART_FRAC_1, RK3576_CLK_UART_FRAC_2 },
|
||||
},
|
||||
{
|
||||
RK3576_HCLK_DDR_ROOT, RK3576_CRU_CLKSEL_CON(77),
|
||||
SEL(5, 5), DIV(4, 0),
|
||||
{ RK3576_PLL_GPLL, RK3576_PLL_CPLL },
|
||||
},
|
||||
{
|
||||
RK3576_FCLK_DDR_CM0_CORE, 0, 0, 0,
|
||||
{ RK3576_HCLK_DDR_ROOT },
|
||||
},
|
||||
{
|
||||
RK3576_ACLK_PHP_ROOT, RK3576_CRU_CLKSEL_CON(92),
|
||||
SEL(9, 9), DIV(8, 4),
|
||||
{ RK3576_PLL_GPLL, RK3576_PLL_CPLL },
|
||||
},
|
||||
{
|
||||
RK3576_CCLK_SRC_SDMMC0, RK3576_CRU_CLKSEL_CON(105),
|
||||
SEL(14, 13), DIV(12, 7),
|
||||
{ RK3576_PLL_GPLL, RK3576_PLL_CPLL, RK3576_XIN24M },
|
||||
},
|
||||
{
|
||||
RK3576_CLK_REF_PCIE0_PHY, RK3576_PHPTOPCRU_CLKSEL_CON(0),
|
||||
SEL(13, 12), 0,
|
||||
{ RK3576_CLK_PCIE_100M_SRC, RK3576_CLK_PCIE_100M_NDUTY_SRC,
|
||||
RK3576_XIN24M },
|
||||
},
|
||||
{
|
||||
RK3576_CLK_PCIE_100M_SRC, RK3576_PHPTOPCRU_CLKSEL_CON(0),
|
||||
0, DIV(6, 2),
|
||||
{ RK3576_PLL_PPLL },
|
||||
},
|
||||
{
|
||||
RK3576_CLK_PCIE_100M_NDUTY_SRC, RK3576_PHPTOPCRU_CLKSEL_CON(0),
|
||||
0, DIV(11, 7),
|
||||
{ RK3576_PLL_PPLL },
|
||||
},
|
||||
{
|
||||
RK3576_CLK_REF_PCIE1_PHY, RK3576_PHPTOPCRU_CLKSEL_CON(0),
|
||||
SEL(15, 14), 0,
|
||||
{ RK3576_CLK_PCIE_100M_SRC, RK3576_CLK_PCIE_100M_NDUTY_SRC,
|
||||
RK3576_XIN24M },
|
||||
},
|
||||
{
|
||||
RK3576_CLK_AUDIO_FRAC_0_SRC, RK3576_CRU_CLKSEL_CON(13),
|
||||
SEL(1, 0), 0,
|
||||
{ RK3576_PLL_GPLL, RK3576_PLL_CPLL, RK3576_PLL_AUPLL,
|
||||
RK3576_XIN24M },
|
||||
},
|
||||
{
|
||||
RK3576_CLK_AUDIO_FRAC_1_SRC, RK3576_CRU_CLKSEL_CON(15),
|
||||
SEL(1, 0), 0,
|
||||
{ RK3576_PLL_GPLL, RK3576_PLL_CPLL, RK3576_PLL_AUPLL,
|
||||
RK3576_XIN24M },
|
||||
},
|
||||
{
|
||||
RK3576_CLK_UART_FRAC_0_SRC, RK3576_CRU_CLKSEL_CON(22),
|
||||
SEL(1, 0), 0,
|
||||
{ RK3576_PLL_GPLL, RK3576_PLL_CPLL, RK3576_PLL_AUPLL,
|
||||
RK3576_XIN24M },
|
||||
},
|
||||
{
|
||||
RK3576_CLK_UART_FRAC_1_SRC, RK3576_CRU_CLKSEL_CON(24),
|
||||
SEL(1, 0), 0,
|
||||
{ RK3576_PLL_GPLL, RK3576_PLL_CPLL, RK3576_PLL_AUPLL,
|
||||
RK3576_XIN24M },
|
||||
},
|
||||
{
|
||||
RK3576_CLK_UART_FRAC_2_SRC, RK3576_CRU_CLKSEL_CON(26),
|
||||
SEL(1, 0), 0,
|
||||
{ RK3576_PLL_GPLL, RK3576_PLL_CPLL, RK3576_PLL_AUPLL,
|
||||
RK3576_XIN24M },
|
||||
},
|
||||
{
|
||||
/* Sentinel */
|
||||
}
|
||||
};
|
||||
|
||||
/* Certain test clocks are disabled. */
|
||||
const uint32_t rk3576_gates[79] = {
|
||||
[2] = 0x00000b00,
|
||||
};
|
||||
|
||||
void
|
||||
rk3576_init(struct rkclock_softc *sc)
|
||||
{
|
||||
int i;
|
||||
|
||||
/* The code below assumes all clocks are enabled. Check this!. */
|
||||
for (i = 0; i < nitems(rk3576_gates); i++) {
|
||||
if (HREAD4(sc, RK3576_CRU_GATE_CON(i)) != rk3576_gates[i]) {
|
||||
printf("CRU_GATE_CON%d: 0x%08x\n", i,
|
||||
HREAD4(sc, RK3576_CRU_GATE_CON(i)));
|
||||
}
|
||||
}
|
||||
|
||||
sc->sc_clocks = rk3576_clocks;
|
||||
}
|
||||
|
||||
uint32_t
|
||||
rk3576_get_frequency(void *cookie, uint32_t *cells)
|
||||
{
|
||||
struct rkclock_softc *sc = cookie;
|
||||
uint32_t idx = cells[0];
|
||||
|
||||
switch (idx) {
|
||||
case RK3576_PLL_AUPLL:
|
||||
return rk3588_get_pll(sc, RK3576_CRU_AUPLL_CON(0));
|
||||
case RK3576_PLL_CPLL:
|
||||
return rk3588_get_pll(sc, RK3576_CRU_CPLL_CON(0));
|
||||
case RK3576_PLL_GPLL:
|
||||
return rk3588_get_pll(sc, RK3576_CRU_GPLL_CON(0));
|
||||
case RK3576_PLL_PPLL:
|
||||
return 2 * rk3588_get_pll(sc, RK3576_PHPTOPCRU_PPLL_CON(0));
|
||||
case RK3588_XIN24M:
|
||||
return 24000000;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
|
||||
return rkclock_get_frequency(sc, idx);
|
||||
}
|
||||
|
||||
int
|
||||
rk3576_set_frequency(void *cookie, uint32_t *cells, uint32_t freq)
|
||||
{
|
||||
struct rkclock_softc *sc = cookie;
|
||||
uint32_t idx = cells[0];
|
||||
|
||||
switch (idx) {
|
||||
case RK3576_PLL_AUPLL:
|
||||
return rk3588_set_pll(sc, RK3576_CRU_AUPLL_CON(0), freq);
|
||||
case RK3576_PLL_CPLL:
|
||||
if (rk3588_get_pll(sc, RK3576_CRU_CPLL_CON(0)) == freq)
|
||||
return 0;
|
||||
return rk3588_set_pll(sc, RK3576_CRU_CPLL_CON(0), freq);
|
||||
case RK3576_PLL_GPLL:
|
||||
return rk3588_set_pll(sc, RK3576_CRU_GPLL_CON(0), freq);
|
||||
case RK3576_CLK_AUDIO_FRAC_0:
|
||||
return rk3399_set_frac(sc, RK3576_CLK_AUDIO_FRAC_0_SRC,
|
||||
RK3576_CRU_CLKSEL_CON(12), freq);
|
||||
case RK3576_CLK_AUDIO_FRAC_1:
|
||||
return rk3399_set_frac(sc, RK3576_CLK_AUDIO_FRAC_1_SRC,
|
||||
RK3576_CRU_CLKSEL_CON(14), freq);
|
||||
case RK3576_CLK_UART_FRAC_0:
|
||||
return rk3399_set_frac(sc, RK3576_CLK_UART_FRAC_0_SRC,
|
||||
RK3576_CRU_CLKSEL_CON(21), freq);
|
||||
case RK3576_CLK_UART_FRAC_1:
|
||||
return rk3399_set_frac(sc, RK3576_CLK_UART_FRAC_1_SRC,
|
||||
RK3576_CRU_CLKSEL_CON(23), freq);
|
||||
case RK3576_CLK_UART_FRAC_2:
|
||||
return rk3399_set_frac(sc, RK3576_CLK_UART_FRAC_2_SRC,
|
||||
RK3576_CRU_CLKSEL_CON(25), freq);
|
||||
default:
|
||||
break;
|
||||
}
|
||||
|
||||
return rkclock_set_frequency(sc, idx, freq);
|
||||
}
|
||||
|
||||
int
|
||||
rk3576_set_parent(void *cookie, uint32_t *cells, uint32_t *pcells)
|
||||
{
|
||||
struct rkclock_softc *sc = cookie;
|
||||
|
||||
return rkclock_set_parent(sc, cells[0], pcells[1]);
|
||||
}
|
||||
|
||||
void
|
||||
rk3576_enable(void *cookie, uint32_t *cells, int on)
|
||||
{
|
||||
uint32_t idx = cells[0];
|
||||
|
||||
/* All clocks are enabled upon hardware reset. */
|
||||
if (!on) {
|
||||
printf("%s: 0x%08x\n", __func__, idx);
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
void
|
||||
rk3576_reset(void *cookie, uint32_t *cells, int on)
|
||||
{
|
||||
struct rkclock_softc *sc = cookie;
|
||||
uint32_t idx = cells[0];
|
||||
uint32_t bit, mask, reg;
|
||||
|
||||
switch (idx) {
|
||||
case RK3576_SRST_P_PCIE0:
|
||||
reg = RK3576_CRU_SOFTRST_CON(34);
|
||||
bit = 13;
|
||||
break;
|
||||
case RK3576_SRST_PCIE0_POWER_UP:
|
||||
reg = RK3576_CRU_SOFTRST_CON(34);
|
||||
bit = 15;
|
||||
break;
|
||||
case RK3576_SRST_A_USB3OTG1:
|
||||
reg = RK3576_CRU_SOFTRST_CON(35);
|
||||
bit = 3;
|
||||
break;
|
||||
case RK3576_SRST_A_GMAC0:
|
||||
reg = RK3576_CRU_SOFTRST_CON(42);
|
||||
bit = 7;
|
||||
break;
|
||||
case RK3576_SRST_H_SDMMC0:
|
||||
reg = RK3576_CRU_SOFTRST_CON(43);
|
||||
bit = 2;
|
||||
break;
|
||||
case RK3576_SRST_A_USB3OTG0:
|
||||
reg = RK3576_CRU_SOFTRST_CON(47);
|
||||
bit = 5;
|
||||
break;
|
||||
case RK3576_SRST_P_PCIE2_COMBOPHY0:
|
||||
reg = RK3576_PHPTOPCRU_SOFTRST_CON(0);
|
||||
bit = 5;
|
||||
break;
|
||||
case RK3576_SRST_P_PCIE2_COMBOPHY1:
|
||||
reg = RK3576_PHPTOPCRU_SOFTRST_CON(0);
|
||||
bit = 6;
|
||||
break;
|
||||
case RK3576_SRST_PCIE0_PIPE_PHY:
|
||||
reg = RK3576_PHPTOPCRU_SOFTRST_CON(1);
|
||||
bit = 5;
|
||||
break;
|
||||
case RK3576_SRST_PCIE1_PIPE_PHY:
|
||||
reg = RK3576_PHPTOPCRU_SOFTRST_CON(1);
|
||||
bit = 8;
|
||||
break;
|
||||
default:
|
||||
printf("%s: 0x%08x\n", __func__, idx);
|
||||
return;
|
||||
}
|
||||
|
||||
mask = (1 << bit);
|
||||
HWRITE4(sc, reg, mask << 16 | (on ? mask : 0));
|
||||
}
|
||||
|
||||
/*
|
||||
* Rockchip RK3588
|
||||
*/
|
||||
@@ -4614,6 +4935,9 @@ rk3588_set_pll(struct rkclock_softc *sc, bus_size_t base, uint32_t freq)
|
||||
case RK3588_CRU_AUPLL_CON(0):
|
||||
mode_shift = 6;
|
||||
break;
|
||||
case RK3588_CRU_CPLL_CON(0):
|
||||
mode_shift = 8;
|
||||
break;
|
||||
case RK3588_CRU_GPLL_CON(0):
|
||||
mode_shift = 2;
|
||||
break;
|
||||
@@ -4657,7 +4981,7 @@ rk3588_set_pll(struct rkclock_softc *sc, bus_size_t base, uint32_t freq)
|
||||
* adjusting the PLL.
|
||||
*/
|
||||
HWRITE4(sc, RK3588_CRU_MODE_CON,
|
||||
(RK3588_CRU_MODE_MASK << 16 |RK3588_CRU_MODE_SLOW) << mode_shift);
|
||||
(RK3588_CRU_MODE_MASK << 16 | RK3588_CRU_MODE_SLOW) << mode_shift);
|
||||
|
||||
/* Power down PLL. */
|
||||
HWRITE4(sc, base + 0x0004,
|
||||
|
||||
@@ -431,6 +431,58 @@
|
||||
|
||||
#define RK3568_PPLL_PH0 1021
|
||||
|
||||
/*
|
||||
* RK3576 clocks.
|
||||
*/
|
||||
#define RK3576_PLL_AUPLL 3
|
||||
#define RK3576_PLL_CPLL 4
|
||||
#define RK3576_PLL_GPLL 5
|
||||
#define RK3576_PLL_PPLL 6
|
||||
|
||||
#define RK3576_CLK_CPLL_DIV20 9
|
||||
#define RK3576_CLK_CPLL_DIV10 10
|
||||
#define RK3576_CLK_GPLL_DIV8 11
|
||||
#define RK3576_CLK_GPLL_DIV6 12
|
||||
#define RK3576_CLK_CPLL_DIV4 13
|
||||
#define RK3576_CLK_CPLL_DIV2 17
|
||||
#define RK3576_CLK_AUDIO_FRAC_0 23
|
||||
#define RK3576_CLK_AUDIO_FRAC_1 24
|
||||
#define RK3576_CLK_UART_FRAC_0 27
|
||||
#define RK3576_CLK_UART_FRAC_1 28
|
||||
#define RK3576_CLK_UART_FRAC_2 29
|
||||
#define RK3576_CLK_GMAC0_125M_SRC 36
|
||||
#define RK3576_CLK_I2C1 116
|
||||
#define RK3576_CLK_I2C2 117
|
||||
#define RK3576_CLK_I2C5 120
|
||||
#define RK3576_SCLK_UART0 140
|
||||
#define RK3576_HCLK_DDR_ROOT 220
|
||||
#define RK3576_FCLK_DDR_CM0_CORE 221
|
||||
#define RK3576_ACLK_PHP_ROOT 255
|
||||
#define RK3576_CCLK_SRC_SDMMC0 296
|
||||
#define RK3576_CLK_PCIE_100M_SRC 311
|
||||
#define RK3576_CLK_PCIE_100M_NDUTY_SRC 312
|
||||
#define RK3576_CLK_REF_PCIE0_PHY 313
|
||||
#define RK3576_CLK_REF_PCIE1_PHY 314
|
||||
#define RK3576_CLK_AUDIO_FRAC_0_SRC 541
|
||||
#define RK3576_CLK_AUDIO_FRAC_1_SRC 542
|
||||
|
||||
#define RK3576_CLK_UART_FRAC_0_SRC 1020
|
||||
#define RK3576_CLK_UART_FRAC_1_SRC 1021
|
||||
#define RK3576_CLK_UART_FRAC_2_SRC 1022
|
||||
#define RK3576_XIN24M 1023
|
||||
|
||||
#define RK3576_SRST_P_PCIE0 241
|
||||
#define RK3576_SRST_PCIE0_POWER_UP 242
|
||||
#define RK3576_SRST_A_USB3OTG1 243
|
||||
#define RK3576_SRST_A_GMAC0 264
|
||||
#define RK3576_SRST_H_SDMMC0 269
|
||||
#define RK3576_SRST_A_USB3OTG0 285
|
||||
|
||||
#define RK3576_SRST_P_PCIE2_COMBOPHY0 417
|
||||
#define RK3576_SRST_P_PCIE2_COMBOPHY1 419
|
||||
#define RK3576_SRST_PCIE0_PIPE_PHY 421
|
||||
#define RK3576_SRST_PCIE1_PIPE_PHY 422
|
||||
|
||||
/*
|
||||
* RK3588 clocks.
|
||||
*/
|
||||
|
||||
Reference in New Issue
Block a user