summaryrefslogtreecommitdiff
path: root/sys
diff options
context:
space:
mode:
authorMark Kettenis <kettenis@cvs.openbsd.org>2017-08-27 09:51:15 +0000
committerMark Kettenis <kettenis@cvs.openbsd.org>2017-08-27 09:51:15 +0000
commitfc34becd68895dcb35a8c06b3af1aea2d48c221c (patch)
treef461eab78224ec385806f0676239fbc050d23771 /sys
parent9f10c55363edd65cc18c5fd3ef747516e444b9e6 (diff)
Add RK3399 i2c-related clocks and fix a typo.
Diffstat (limited to 'sys')
-rw-r--r--sys/dev/fdt/rkclock.c108
-rw-r--r--sys/dev/fdt/rkclock_clocks.h24
2 files changed, 126 insertions, 6 deletions
diff --git a/sys/dev/fdt/rkclock.c b/sys/dev/fdt/rkclock.c
index 5180d25b0af..74cb158db7a 100644
--- a/sys/dev/fdt/rkclock.c
+++ b/sys/dev/fdt/rkclock.c
@@ -1,4 +1,4 @@
-/* $OpenBSD: rkclock.c,v 1.14 2017/08/26 16:24:27 kettenis Exp $ */
+/* $OpenBSD: rkclock.c,v 1.15 2017/08/27 09:51:14 kettenis Exp $ */
/*
* Copyright (c) 2017 Mark Kettenis <kettenis@openbsd.org>
*
@@ -68,6 +68,9 @@
#define RK3399_CRU_SOFTRST_CON(i) (0x0400 + (i) * 4)
#define RK3399_CRU_SDMMC_CON(i) (0x0580 + (i) * 4)
+#define RK3399_PMUCRU_PPLL_CON(i) (0x0000 + (i) * 4)
+#define RK3399_PMUCRU_CLKSEL_CON(i) (0x0080 + (i) * 4)
+
#include "rkclock_clocks.h"
#define HREAD4(sc, reg) \
@@ -113,6 +116,7 @@ void rk3399_enable(void *, uint32_t *, int);
void rk3399_reset(void *, uint32_t *, int);
int rk3399_cpuspeed(int *);
+void rk3399_pmu_init(struct rkclock_softc *);
uint32_t rk3399_pmu_get_frequency(void *, uint32_t *);
int rk3399_pmu_set_frequency(void *, uint32_t *, uint32_t);
void rk3399_pmu_enable(void *, uint32_t *, int);
@@ -139,7 +143,7 @@ struct rkclock_compat rkclock_compat[] = {
rk3399_set_frequency, rk3399_reset,
},
{
- "rockchip,rk3399-pmucru", NULL,
+ "rockchip,rk3399-pmucru", rk3399_pmu_init,
rk3399_pmu_enable, rk3399_pmu_get_frequency,
rk3399_pmu_set_frequency, rk3399_pmu_reset
}
@@ -345,6 +349,9 @@ rk3288_reset(void *cookie, uint32_t *cells, int on)
* Rockchip RK3399
*/
+/* Some of our parent clocks live in the PMUCRU. */
+struct rkclock_softc *rk3399_pmucru_sc;
+
void
rk3399_init(struct rkclock_softc *sc)
{
@@ -353,6 +360,9 @@ rk3399_init(struct rkclock_softc *sc)
rkclock_cpuspeed_sc = sc;
cpu_cpuspeed = rk3399_cpuspeed;
+ /* PMUCRU instance should attach before us. */
+ KASSERT(rk3399_pmucru_sc != NULL);
+
/*
* Since the hardware comes up with a really conservative CPU
* clock frequency, and U-Boot doesn't set it to a more
@@ -580,6 +590,26 @@ rk3399_set_armclk(struct rkclock_softc *sc, bus_size_t clksel, uint32_t freq)
}
uint32_t
+rk3399_get_i2c(struct rkclock_softc *sc, size_t base, int shift)
+{
+ uint32_t reg, mux, div_con;
+ uint32_t idx, freq;
+
+ reg = HREAD4(sc, base);
+ mux = (reg >> (7 + shift)) & 0x1;
+ div_con = (reg >> shift) & 0x7f;
+ if (mux == 1) {
+ idx = RK3399_PLL_PPLL;
+ freq = rk3399_pmu_get_frequency(rk3399_pmucru_sc, &idx);
+ } else {
+ idx = RK3399_PLL_CPLL;
+ freq = rk3399_get_frequency(sc, &idx);
+ }
+
+ return freq / (div_con + 1);
+}
+
+uint32_t
rk3399_get_frequency(void *cookie, uint32_t *cells)
{
struct rkclock_softc *sc = cookie;
@@ -601,10 +631,20 @@ rk3399_get_frequency(void *cookie, uint32_t *cells)
return rk3399_get_pll(sc, RK3399_CRU_NPLL_CON(0));
case RK3399_ARMCLKL:
return rk3399_get_armclk(sc, RK3399_CRU_CLKSEL_CON(0));
- break;
case RK3399_ARMCLKB:
return rk3399_get_armclk(sc, RK3399_CRU_CLKSEL_CON(2));
- break;
+ case RK3399_CLK_I2C1:
+ return rk3399_get_i2c(sc, RK3399_CRU_CLKSEL_CON(61), 0);
+ case RK3399_CLK_I2C2:
+ return rk3399_get_i2c(sc, RK3399_CRU_CLKSEL_CON(62), 0);
+ case RK3399_CLK_I2C3:
+ return rk3399_get_i2c(sc, RK3399_CRU_CLKSEL_CON(63), 0);
+ case RK3399_CLK_I2C5:
+ return rk3399_get_i2c(sc, RK3399_CRU_CLKSEL_CON(61), 8);
+ case RK3399_CLK_I2C6:
+ return rk3399_get_i2c(sc, RK3399_CRU_CLKSEL_CON(61), 8);
+ case RK3399_CLK_I2C7:
+ return rk3399_get_i2c(sc, RK3399_CRU_CLKSEL_CON(61), 8);
case RK3399_CLK_SDMMC:
reg = HREAD4(sc, RK3399_CRU_CLKSEL_CON(16));
mux = (reg >> 8) & 0x7;
@@ -666,7 +706,7 @@ rk3399_get_frequency(void *cookie, uint32_t *cells)
reg = HREAD4(sc, RK3399_CRU_CLKSEL_CON(13));
mux = (reg >> 15) & 0x1;
div_con = (reg >> 8) & 0x1f;
- idx = mux ? RK3399_PLL_GPLL : RK3399_PLL_GPLL;
+ idx = mux ? RK3399_PLL_CPLL : RK3399_PLL_GPLL;
return rk3399_get_frequency(sc, &idx) / (div_con + 1);
default:
break;
@@ -703,6 +743,12 @@ rk3399_enable(void *cookie, uint32_t *cells, int on)
uint32_t idx = cells[0];
switch (idx) {
+ case RK3399_CLK_I2C1:
+ case RK3399_CLK_I2C2:
+ case RK3399_CLK_I2C3:
+ case RK3399_CLK_I2C5:
+ case RK3399_CLK_I2C6:
+ case RK3399_CLK_I2C7:
case RK3399_CLK_SDMMC:
case RK3399_CLK_EMMC:
case RK3399_CLK_TSADC:
@@ -724,6 +770,12 @@ rk3399_enable(void *cookie, uint32_t *cells, int on)
case RK3399_ACLK_USB3OTG0:
case RK3399_ACLK_USB3OTG1:
case RK3399_ACLK_USB3_GRF:
+ case RK3399_PCLK_I2C1:
+ case RK3399_PCLK_I2C2:
+ case RK3399_PCLK_I2C3:
+ case RK3399_PCLK_I2C5:
+ case RK3399_PCLK_I2C6:
+ case RK3399_PCLK_I2C7:
case RK3399_PCLK_TSADC:
case RK3399_PCLK_GMAC:
case RK3399_HCLK_HOST0:
@@ -761,11 +813,43 @@ rk3399_cpuspeed(int *freq)
/* PMUCRU */
+void
+rk3399_pmu_init(struct rkclock_softc *sc)
+{
+ rk3399_pmucru_sc = sc;
+}
+
+uint32_t
+rk3399_pmu_get_i2c(struct rkclock_softc *sc, size_t base, int shift)
+{
+ uint32_t reg, div_con;
+ uint32_t idx;
+
+ reg = HREAD4(sc, base);
+ div_con = (reg >> shift) & 0x7f;
+ idx = RK3399_PLL_PPLL;
+ return rk3399_get_frequency(sc, &idx) / (div_con + 1);
+}
+
uint32_t
rk3399_pmu_get_frequency(void *cookie, uint32_t *cells)
{
+ struct rkclock_softc *sc = cookie;
uint32_t idx = cells[0];
+ switch (idx) {
+ case RK3399_PLL_PPLL:
+ return rk3399_get_pll(sc, RK3399_PMUCRU_PPLL_CON(0));
+ case RK3399_CLK_I2C0:
+ return rk3399_pmu_get_i2c(sc, RK3399_PMUCRU_CLKSEL_CON(2), 0);
+ case RK3399_CLK_I2C4:
+ return rk3399_pmu_get_i2c(sc, RK3399_PMUCRU_CLKSEL_CON(3), 0);
+ case RK3399_CLK_I2C8:
+ return rk3399_pmu_get_i2c(sc, RK3399_PMUCRU_CLKSEL_CON(2), 8);
+ default:
+ break;
+ }
+
printf("%s: 0x%08x\n", __func__, idx);
return 0;
}
@@ -784,7 +868,19 @@ rk3399_pmu_enable(void *cookie, uint32_t *cells, int on)
{
uint32_t idx = cells[0];
- printf("%s: 0x%08x\n", __func__, idx);
+ switch (idx) {
+ case RK3399_CLK_I2C0:
+ case RK3399_CLK_I2C4:
+ case RK3399_CLK_I2C8:
+ case RK3399_PCLK_I2C0:
+ case RK3399_PCLK_I2C4:
+ case RK3399_PCLK_I2C8:
+ /* Enabled by default. */
+ break;
+ default:
+ printf("%s: 0x%08x\n", __func__, idx);
+ break;
+ }
}
void
diff --git a/sys/dev/fdt/rkclock_clocks.h b/sys/dev/fdt/rkclock_clocks.h
index 5d2a37f7400..167ff78108b 100644
--- a/sys/dev/fdt/rkclock_clocks.h
+++ b/sys/dev/fdt/rkclock_clocks.h
@@ -39,6 +39,12 @@
#define RK3399_ARMCLKL 8
#define RK3399_ARMCLKB 9
+#define RK3399_CLK_I2C1 65
+#define RK3399_CLK_I2C2 66
+#define RK3399_CLK_I2C3 67
+#define RK3399_CLK_I2C5 68
+#define RK3399_CLK_I2C6 69
+#define RK3399_CLK_I2C7 70
#define RK3399_CLK_SDMMC 76
#define RK3399_CLK_EMMC 78
#define RK3399_CLK_TSADC 79
@@ -62,6 +68,12 @@
#define RK3399_ACLK_USB3OTG1 247
#define RK3399_ACLK_USB3_GRF 249
+#define RK3399_PCLK_I2C1 341
+#define RK3399_PCLK_I2C2 342
+#define RK3399_PCLK_I2C3 343
+#define RK3399_PCLK_I2C5 344
+#define RK3399_PCLK_I2C6 345
+#define RK3399_PCLK_I2C7 346
#define RK3399_PCLK_TSADC 356
#define RK3399_PCLK_GMAC 358
@@ -70,3 +82,15 @@
#define RK3399_HCLK_HOST1 458
#define RK3399_HCLK_HOST1_ARB 459
#define RK3399_HCLK_SDMMC 462
+
+/* PMUCRU */
+
+#define RK3399_PLL_PPLL 1
+
+#define RK3399_CLK_I2C0 9
+#define RK3399_CLK_I2C4 10
+#define RK3399_CLK_I2C8 11
+
+#define RK3399_PCLK_I2C0 27
+#define RK3399_PCLK_I2C4 28
+#define RK3399_PCLK_I2C8 29