Module Name: src
Committed By: jmcneill
Date: Fri Nov 12 22:02:08 UTC 2021
Modified Files:
src/sys/arch/arm/rockchip: files.rockchip rk3328_cru.c rk3399_cru.c
rk_cru.h rk_cru_composite.c rk_cru_pll.c rk_gmac.c rk_i2c.c
rk_platform.c
src/sys/arch/evbarm/conf: GENERIC files.generic
Added Files:
src/sys/arch/arm/rockchip: rk3066_smp.c rk3288_cru.c rk3288_cru.h
rk3288_iomux.c rk3288_platform.h rk3288_usb.c
Log Message:
arm: rockchip: Add support for RK3288 SoC.
The Rockchip RK3288 is a quad core Cortex-A17 SoC.
To generate a diff of this commit:
cvs rdiff -u -r1.24 -r1.25 src/sys/arch/arm/rockchip/files.rockchip
cvs rdiff -u -r0 -r1.1 src/sys/arch/arm/rockchip/rk3066_smp.c \
src/sys/arch/arm/rockchip/rk3288_cru.c \
src/sys/arch/arm/rockchip/rk3288_cru.h \
src/sys/arch/arm/rockchip/rk3288_iomux.c \
src/sys/arch/arm/rockchip/rk3288_platform.h \
src/sys/arch/arm/rockchip/rk3288_usb.c
cvs rdiff -u -r1.8 -r1.9 src/sys/arch/arm/rockchip/rk3328_cru.c
cvs rdiff -u -r1.22 -r1.23 src/sys/arch/arm/rockchip/rk3399_cru.c
cvs rdiff -u -r1.7 -r1.8 src/sys/arch/arm/rockchip/rk_cru.h
cvs rdiff -u -r1.6 -r1.7 src/sys/arch/arm/rockchip/rk_cru_composite.c
cvs rdiff -u -r1.4 -r1.5 src/sys/arch/arm/rockchip/rk_cru_pll.c
cvs rdiff -u -r1.20 -r1.21 src/sys/arch/arm/rockchip/rk_gmac.c
cvs rdiff -u -r1.10 -r1.11 src/sys/arch/arm/rockchip/rk_i2c.c
cvs rdiff -u -r1.14 -r1.15 src/sys/arch/arm/rockchip/rk_platform.c
cvs rdiff -u -r1.100 -r1.101 src/sys/arch/evbarm/conf/GENERIC
cvs rdiff -u -r1.11 -r1.12 src/sys/arch/evbarm/conf/files.generic
Please note that diffs are not public domain; they are subject to the
copyright notices on the relevant files.
Modified files:
Index: src/sys/arch/arm/rockchip/files.rockchip
diff -u src/sys/arch/arm/rockchip/files.rockchip:1.24 src/sys/arch/arm/rockchip/files.rockchip:1.25
--- src/sys/arch/arm/rockchip/files.rockchip:1.24 Sun May 17 19:57:25 2020
+++ src/sys/arch/arm/rockchip/files.rockchip Fri Nov 12 22:02:08 2021
@@ -1,4 +1,4 @@
-# $NetBSD: files.rockchip,v 1.24 2020/05/17 19:57:25 riastradh Exp $
+# $NetBSD: files.rockchip,v 1.25 2021/11/12 22:02:08 jmcneill Exp $
#
# Configuration info for Rockchip family SoCs
#
@@ -6,6 +6,8 @@
file arch/arm/rockchip/rk_platform.c soc_rockchip
+file arch/arm/rockchip/rk3066_smp.c soc_rk3288
+
# Clock and reset unit (CRU)
device rkcru: rk_cru
file arch/arm/rockchip/rk_cru.c rk_cru
@@ -15,6 +17,14 @@ file arch/arm/rockchip/rk_cru_gate.c rk
file arch/arm/rockchip/rk_cru_mux.c rk_cru
file arch/arm/rockchip/rk_cru_pll.c rk_cru
+ifdef arm
+
+# RK3288 clock and reset unit
+attach rkcru at fdt with rk3288_cru
+file arch/arm/rockchip/rk3288_cru.c rk3288_cru & soc_rk3288
+
+else
+
# RK3328 clock and reset unit
attach rkcru at fdt with rk3328_cru
file arch/arm/rockchip/rk3328_cru.c rk3328_cru & soc_rk3328
@@ -25,13 +35,25 @@ file arch/arm/rockchip/rk3399_cru.c rk3
attach rkcru at fdt with rk3399_pmucru
file arch/arm/rockchip/rk3399_pmucru.c rk3399_pmucru & soc_rk3399
+endif
+
# IOMUX control
device rkiomux { }
+
+ifdef arm
+
+attach rkiomux at fdt with rk3288_iomux
+file arch/arm/rockchip/rk3288_iomux.c rk3288_iomux & soc_rk3288
+
+else
+
attach rkiomux at fdt with rk3328_iomux
file arch/arm/rockchip/rk3328_iomux.c rk3328_iomux & soc_rk3328
attach rkiomux at fdt with rk3399_iomux
file arch/arm/rockchip/rk3399_iomux.c rk3399_iomux & soc_rk3399
+endif
+
# GPIO
device rkgpio: gpiobus
attach rkgpio at rkiomux with rk_gpio
@@ -54,6 +76,12 @@ device rkusbphy
attach rkusbphy at rkusb with rk_usbphy
file arch/arm/rockchip/rk_usb.c rk_usb | rk_usbphy
+device rk3288usb { }
+attach rk3288usb at fdt with rk3288_usb
+device rk3288usbphy
+attach rk3288usbphy at rk3288usb with rk3288_usbphy
+file arch/arm/rockchip/rk3288_usb.c rk3288_usb | rk3288_usbphy
+
# GMAC
attach awge at fdt with rk_gmac
file arch/arm/rockchip/rk_gmac.c rk_gmac
@@ -119,5 +147,6 @@ file arch/arm/rockchip/rk_v1crypto.c rk
# SOC parameters
defflag opt_soc.h SOC_ROCKCHIP
+defflag opt_soc.h SOC_RK3288: SOC_ROCKCHIP
defflag opt_soc.h SOC_RK3328: SOC_ROCKCHIP
defflag opt_soc.h SOC_RK3399: SOC_ROCKCHIP
Index: src/sys/arch/arm/rockchip/rk3328_cru.c
diff -u src/sys/arch/arm/rockchip/rk3328_cru.c:1.8 src/sys/arch/arm/rockchip/rk3328_cru.c:1.9
--- src/sys/arch/arm/rockchip/rk3328_cru.c:1.8 Sat May 15 08:46:00 2021
+++ src/sys/arch/arm/rockchip/rk3328_cru.c Fri Nov 12 22:02:08 2021
@@ -1,4 +1,4 @@
-/* $NetBSD: rk3328_cru.c,v 1.8 2021/05/15 08:46:00 mrg Exp $ */
+/* $NetBSD: rk3328_cru.c,v 1.9 2021/11/12 22:02:08 jmcneill Exp $ */
/*-
* Copyright (c) 2018 Jared McNeill <[email protected]>
@@ -28,7 +28,7 @@
#include <sys/cdefs.h>
-__KERNEL_RCSID(1, "$NetBSD: rk3328_cru.c,v 1.8 2021/05/15 08:46:00 mrg Exp $");
+__KERNEL_RCSID(1, "$NetBSD: rk3328_cru.c,v 1.9 2021/11/12 22:02:08 jmcneill Exp $");
#include <sys/param.h>
#include <sys/bus.h>
@@ -501,6 +501,7 @@ rk3328_cru_attach(device_t parent, devic
sc->sc_clks = rk3328_cru_clks;
sc->sc_nclks = __arraycount(rk3328_cru_clks);
+ sc->sc_grf_soc_status = 0x0480;
sc->sc_softrst_base = SOFTRST_CON(0);
if (rk_cru_attach(sc) != 0)
Index: src/sys/arch/arm/rockchip/rk3399_cru.c
diff -u src/sys/arch/arm/rockchip/rk3399_cru.c:1.22 src/sys/arch/arm/rockchip/rk3399_cru.c:1.23
--- src/sys/arch/arm/rockchip/rk3399_cru.c:1.22 Thu May 20 01:07:24 2021
+++ src/sys/arch/arm/rockchip/rk3399_cru.c Fri Nov 12 22:02:08 2021
@@ -1,4 +1,4 @@
-/* $NetBSD: rk3399_cru.c,v 1.22 2021/05/20 01:07:24 msaitoh Exp $ */
+/* $NetBSD: rk3399_cru.c,v 1.23 2021/11/12 22:02:08 jmcneill Exp $ */
/*-
* Copyright (c) 2018 Jared McNeill <[email protected]>
@@ -28,7 +28,7 @@
#include <sys/cdefs.h>
-__KERNEL_RCSID(1, "$NetBSD: rk3399_cru.c,v 1.22 2021/05/20 01:07:24 msaitoh Exp $");
+__KERNEL_RCSID(1, "$NetBSD: rk3399_cru.c,v 1.23 2021/11/12 22:02:08 jmcneill Exp $");
#include <sys/param.h>
#include <sys/bus.h>
@@ -1126,6 +1126,7 @@ rk3399_cru_attach(device_t parent, devic
sc->sc_clks = rk3399_cru_clks;
sc->sc_nclks = __arraycount(rk3399_cru_clks);
+ sc->sc_grf_soc_status = 0x0480;
sc->sc_softrst_base = SOFTRST_CON(0);
if (rk_cru_attach(sc) != 0)
Index: src/sys/arch/arm/rockchip/rk_cru.h
diff -u src/sys/arch/arm/rockchip/rk_cru.h:1.7 src/sys/arch/arm/rockchip/rk_cru.h:1.8
--- src/sys/arch/arm/rockchip/rk_cru.h:1.7 Sat Nov 16 13:23:13 2019
+++ src/sys/arch/arm/rockchip/rk_cru.h Fri Nov 12 22:02:08 2021
@@ -1,4 +1,4 @@
-/* $NetBSD: rk_cru.h,v 1.7 2019/11/16 13:23:13 jmcneill Exp $ */
+/* $NetBSD: rk_cru.h,v 1.8 2021/11/12 22:02:08 jmcneill Exp $ */
/*-
* Copyright (c) 2018 Jared McNeill <[email protected]>
@@ -80,6 +80,8 @@ struct rk_cru_pll {
u_int nrates;
const char **parents;
u_int nparents;
+ u_int flags;
+#define RK_PLL_RK3288 0x01
};
u_int rk_cru_pll_get_rate(struct rk_cru_softc *, struct rk_cru_clk *);
@@ -100,6 +102,27 @@ const char *rk_cru_pll_get_parent(struct
.u.pll.lock_mask = (_lock_mask), \
.u.pll.rates = (_rates), \
.u.pll.nrates = __arraycount(_rates), \
+ .u.pll.flags = 0, \
+ .get_rate = rk_cru_pll_get_rate, \
+ .set_rate = rk_cru_pll_set_rate, \
+ .get_parent = rk_cru_pll_get_parent, \
+ }
+
+#define RK3288_PLL(_id, _name, _parents, _con_base, _mode_reg, _mode_mask, _lock_mask, _rates) \
+ { \
+ .id = (_id), \
+ .type = RK_CRU_PLL, \
+ .base.name = (_name), \
+ .base.flags = 0, \
+ .u.pll.parents = (_parents), \
+ .u.pll.nparents = __arraycount(_parents), \
+ .u.pll.con_base = (_con_base), \
+ .u.pll.mode_reg = (_mode_reg), \
+ .u.pll.mode_mask = (_mode_mask), \
+ .u.pll.lock_mask = (_lock_mask), \
+ .u.pll.rates = (_rates), \
+ .u.pll.nrates = __arraycount(_rates), \
+ .u.pll.flags = RK_PLL_RK3288, \
.get_rate = rk_cru_pll_get_rate, \
.set_rate = rk_cru_pll_set_rate, \
.get_parent = rk_cru_pll_get_parent, \
@@ -207,6 +230,7 @@ struct rk_cru_composite {
#define RK_COMPOSITE_ROUND_DOWN 0x01
#define RK_COMPOSITE_SET_RATE_PARENT 0x02
#define RK_COMPOSITE_FRACDIV 0x04
+#define RK_COMPOSITE_POW2 0x08
};
int rk_cru_composite_enable(struct rk_cru_softc *, struct rk_cru_clk *, int);
@@ -367,6 +391,7 @@ struct rk_cru_softc {
struct rk_cru_clk *sc_clks;
u_int sc_nclks;
+ bus_size_t sc_grf_soc_status; /* for PLL lock */
bus_size_t sc_softrst_base;
};
Index: src/sys/arch/arm/rockchip/rk_cru_composite.c
diff -u src/sys/arch/arm/rockchip/rk_cru_composite.c:1.6 src/sys/arch/arm/rockchip/rk_cru_composite.c:1.7
--- src/sys/arch/arm/rockchip/rk_cru_composite.c:1.6 Thu May 20 01:41:55 2021
+++ src/sys/arch/arm/rockchip/rk_cru_composite.c Fri Nov 12 22:02:08 2021
@@ -1,4 +1,4 @@
-/* $NetBSD: rk_cru_composite.c,v 1.6 2021/05/20 01:41:55 msaitoh Exp $ */
+/* $NetBSD: rk_cru_composite.c,v 1.7 2021/11/12 22:02:08 jmcneill Exp $ */
/*-
* Copyright (c) 2018 Jared McNeill <[email protected]>
@@ -27,7 +27,7 @@
*/
#include <sys/cdefs.h>
-__KERNEL_RCSID(0, "$NetBSD: rk_cru_composite.c,v 1.6 2021/05/20 01:41:55 msaitoh Exp $");
+__KERNEL_RCSID(0, "$NetBSD: rk_cru_composite.c,v 1.7 2021/11/12 22:02:08 jmcneill Exp $");
#include <sys/param.h>
#include <sys/bus.h>
@@ -83,9 +83,14 @@ rk_cru_composite_get_rate(struct rk_cru_
return (u_int)((uint64_t)prate * num / den);
} else {
const uint32_t val = CRU_READ(sc, composite->muxdiv_reg);
- const u_int div = (composite->div_mask != 0)
- ? __SHIFTOUT(val, composite->div_mask) + 1 : 1;
+ u_int div;
+ if (composite->flags & RK_COMPOSITE_POW2) {
+ div = 1U << __SHIFTOUT(val, composite->div_mask);
+ } else {
+ div = (composite->div_mask != 0)
+ ? __SHIFTOUT(val, composite->div_mask) + 1 : 1;
+ }
return prate / div;
}
}
@@ -149,6 +154,10 @@ rk_cru_composite_set_rate(struct rk_cru_
return rk_cru_composite_set_rate_frac(sc, clk, rate);
}
+ if (composite->flags & RK_COMPOSITE_POW2) {
+ return ENXIO; /* TODO */
+ }
+
best_div = 0;
best_mux = 0;
best_diff = INT_MAX;
Index: src/sys/arch/arm/rockchip/rk_cru_pll.c
diff -u src/sys/arch/arm/rockchip/rk_cru_pll.c:1.4 src/sys/arch/arm/rockchip/rk_cru_pll.c:1.5
--- src/sys/arch/arm/rockchip/rk_cru_pll.c:1.4 Sun Aug 12 16:48:05 2018
+++ src/sys/arch/arm/rockchip/rk_cru_pll.c Fri Nov 12 22:02:08 2021
@@ -1,4 +1,4 @@
-/* $NetBSD: rk_cru_pll.c,v 1.4 2018/08/12 16:48:05 jmcneill Exp $ */
+/* $NetBSD: rk_cru_pll.c,v 1.5 2021/11/12 22:02:08 jmcneill Exp $ */
/*-
* Copyright (c) 2018 Jared McNeill <[email protected]>
@@ -27,7 +27,7 @@
*/
#include <sys/cdefs.h>
-__KERNEL_RCSID(0, "$NetBSD: rk_cru_pll.c,v 1.4 2018/08/12 16:48:05 jmcneill Exp $");
+__KERNEL_RCSID(0, "$NetBSD: rk_cru_pll.c,v 1.5 2021/11/12 22:02:08 jmcneill Exp $");
#include <sys/param.h>
#include <sys/bus.h>
@@ -57,9 +57,20 @@ __KERNEL_RCSID(0, "$NetBSD: rk_cru_pll.c
#define PLL_DACPD __BIT(24)
#define PLL_FRACDIV __BITS(23,0)
+#define PLL_CON3 0x0c
+
#define PLL_WRITE_MASK 0xffff0000 /* for CON0 and CON1 */
-#define GRF_SOC_STATUS0 0x0480
+/* RK3288 CON0 */
+#define RK3288_CLKR __BITS(13,8)
+#define RK3288_CLKOD __BITS(3,0)
+/* RK3288 CON1 */
+#define RK3288_LOCK __BIT(31)
+#define RK3288_CLKF __BITS(12,0)
+/* RK3288 CON2 */
+#define RK3288_BWADJ __BITS(11,0)
+/* RK3288 CON3 */
+#define RK3288_BYPASS __BIT(0)
u_int
rk_cru_pll_get_rate(struct rk_cru_softc *sc,
@@ -83,24 +94,39 @@ rk_cru_pll_get_rate(struct rk_cru_softc
const uint32_t con0 = CRU_READ(sc, pll->con_base + PLL_CON0);
const uint32_t con1 = CRU_READ(sc, pll->con_base + PLL_CON1);
const uint32_t con2 = CRU_READ(sc, pll->con_base + PLL_CON2);
+ const uint32_t con3 = CRU_READ(sc, pll->con_base + PLL_CON3);
+
+ if ((pll->flags & RK_PLL_RK3288) != 0) {
+ if ((con3 & RK3288_BYPASS) != 0) {
+ return fref;
+ }
+
+ const u_int nr = __SHIFTOUT(con0, RK3288_CLKR) + 1;
+ const u_int no = __SHIFTOUT(con0, RK3288_CLKOD) + 1;
+ const u_int nf = __SHIFTOUT(con1, RK3288_CLKF) + 1;
+
+ const uint64_t tmp = (uint64_t)fref * nf / nr / no;
- const u_int postdiv1 = __SHIFTOUT(con0, PLL_POSTDIV1);
- const u_int fbdiv = __SHIFTOUT(con0, PLL_FBDIV);
- const u_int dsmpd = __SHIFTOUT(con1, PLL_DSMPD);
- const u_int refdiv = __SHIFTOUT(con1, PLL_REFDIV);
- const u_int postdiv2 = __SHIFTOUT(con1, PLL_POSTDIV2);
- const u_int fracdiv = __SHIFTOUT(con2, PLL_FRACDIV);
-
- if (dsmpd == 1) {
- /* integer mode */
- foutvco = fref / refdiv * fbdiv;
+ return (u_int)tmp;
} else {
- /* fractional mode */
- foutvco = fref / refdiv * fbdiv + ((fref * fracdiv) >> 24);
- }
- foutpostdiv = foutvco / postdiv1 / postdiv2;
+ const u_int postdiv1 = __SHIFTOUT(con0, PLL_POSTDIV1);
+ const u_int fbdiv = __SHIFTOUT(con0, PLL_FBDIV);
+ const u_int dsmpd = __SHIFTOUT(con1, PLL_DSMPD);
+ const u_int refdiv = __SHIFTOUT(con1, PLL_REFDIV);
+ const u_int postdiv2 = __SHIFTOUT(con1, PLL_POSTDIV2);
+ const u_int fracdiv = __SHIFTOUT(con2, PLL_FRACDIV);
+
+ if (dsmpd == 1) {
+ /* integer mode */
+ foutvco = fref / refdiv * fbdiv;
+ } else {
+ /* fractional mode */
+ foutvco = fref / refdiv * fbdiv + ((fref * fracdiv) >> 24);
+ }
+ foutpostdiv = foutvco / postdiv1 / postdiv2;
- return foutpostdiv;
+ return foutpostdiv;
+ }
}
int
@@ -125,6 +151,8 @@ rk_cru_pll_set_rate(struct rk_cru_softc
if (pll_rate == NULL)
return EINVAL;
+ KASSERT((pll->flags & RK_PLL_RK3288) == 0); /* XXX TODO */
+
CRU_WRITE(sc, pll->con_base + PLL_CON0,
__SHIFTIN(pll_rate->postdiv1, PLL_POSTDIV1) |
__SHIFTIN(pll_rate->fbdiv, PLL_FBDIV) |
@@ -148,7 +176,7 @@ rk_cru_pll_set_rate(struct rk_cru_softc
syscon_lock(sc->sc_grf);
for (retry = 1000; retry > 0; retry--) {
- if (syscon_read_4(sc->sc_grf, GRF_SOC_STATUS0) & pll->lock_mask)
+ if (syscon_read_4(sc->sc_grf, sc->sc_grf_soc_status) & pll->lock_mask)
break;
delay(1);
}
Index: src/sys/arch/arm/rockchip/rk_gmac.c
diff -u src/sys/arch/arm/rockchip/rk_gmac.c:1.20 src/sys/arch/arm/rockchip/rk_gmac.c:1.21
--- src/sys/arch/arm/rockchip/rk_gmac.c:1.20 Sun Nov 7 19:21:33 2021
+++ src/sys/arch/arm/rockchip/rk_gmac.c Fri Nov 12 22:02:08 2021
@@ -1,4 +1,4 @@
-/* $NetBSD: rk_gmac.c,v 1.20 2021/11/07 19:21:33 jmcneill Exp $ */
+/* $NetBSD: rk_gmac.c,v 1.21 2021/11/12 22:02:08 jmcneill Exp $ */
/*-
* Copyright (c) 2018 Jared McNeill <[email protected]>
@@ -28,7 +28,7 @@
#include <sys/cdefs.h>
-__KERNEL_RCSID(0, "$NetBSD: rk_gmac.c,v 1.20 2021/11/07 19:21:33 jmcneill Exp $");
+__KERNEL_RCSID(0, "$NetBSD: rk_gmac.c,v 1.21 2021/11/12 22:02:08 jmcneill Exp $");
#include <sys/param.h>
#include <sys/bus.h>
@@ -54,11 +54,13 @@ __KERNEL_RCSID(0, "$NetBSD: rk_gmac.c,v
#define RK_GMAC_RXDLY_DEFAULT 0x10
enum rk_gmac_type {
- GMAC_RK3328 = 1,
+ GMAC_RK3288 = 1,
+ GMAC_RK3328,
GMAC_RK3399
};
static const struct device_compatible_entry compat_data[] = {
+ { .compat = "rockchip,rk3288-gmac", .value = GMAC_RK3288 },
{ .compat = "rockchip,rk3328-gmac", .value = GMAC_RK3328 },
{ .compat = "rockchip,rk3399-gmac", .value = GMAC_RK3399 },
DEVICE_COMPAT_EOL
@@ -71,6 +73,98 @@ struct rk_gmac_softc {
};
/*
+ * RK3288 specific
+ */
+
+#define RK3288_GRF_SOC_CON1 0x0248
+#define RK3288_GRF_SOC_CON1_RMII_MODE __BIT(14)
+#define RK3288_GRF_SOC_CON1_GMAC_CLK_SEL __BITS(13,12)
+#define RK3288_GRF_SOC_CON1_GMAC_CLK_SEL_125M 0
+#define RK3288_GRF_SOC_CON1_GMAC_CLK_SEL_2_5M 2
+#define RK3288_GRF_SOC_CON1_GMAC_CLK_SEL_25M 3
+#define RK3288_GRF_SOC_CON1_RMII_CLK_SEL __BIT(11)
+#define RK3288_GRF_SOC_CON1_RMII_CLK_SEL_25M 1
+#define RK3288_GRF_SOC_CON1_RMII_CLK_SEL_2_5M 0
+#define RK3288_GRF_SOC_CON1_GMAC_SPEED __BIT(10)
+#define RK3288_GRF_SOC_CON1_GMAC_SPEED_10M 0
+#define RK3288_GRF_SOC_CON1_GMAC_SPEED_100M 1
+#define RK3288_GRF_SOC_CON1_GMAC_FLOWCTRL __BIT(9)
+#define RK3288_GRF_SOC_CON1_GMAC_PHY_INTF_SEL __BITS(8,6)
+#define RK3288_GRF_SOC_CON1_GMAC_PHY_INTF_SEL_RGMII 1
+#define RK3288_GRF_SOC_CON1_GMAC_PHY_INTF_SEL_RMII 4
+
+#define RK3288_GRF_SOC_CON3 0x0250
+#define RK3288_GRF_SOC_CON3_RXCLK_DLY_ENA_GMAC __BIT(15)
+#define RK3288_GRF_SOC_CON3_TXCLK_DLY_ENA_GMAC __BIT(14)
+#define RK3288_GRF_SOC_CON3_CLK_RX_DL_CFG_GMAC __BITS(13,7)
+#define RK3288_GRF_SOC_CON3_CLK_TX_DL_CFG_GMAC __BITS(6,0)
+
+static void
+rk3288_gmac_set_mode_rgmii(struct dwc_gmac_softc *sc, u_int tx_delay, u_int rx_delay, bool set_delay)
+{
+ struct rk_gmac_softc * const rk_sc = (struct rk_gmac_softc *)sc;
+ uint32_t write_mask, write_val;
+
+ syscon_lock(rk_sc->sc_syscon);
+
+ write_mask = (RK3288_GRF_SOC_CON1_RMII_MODE |
+ RK3288_GRF_SOC_CON1_GMAC_PHY_INTF_SEL) << 16;
+ write_val = __SHIFTIN(RK3288_GRF_SOC_CON1_GMAC_PHY_INTF_SEL_RGMII,
+ RK3288_GRF_SOC_CON1_GMAC_PHY_INTF_SEL);
+ syscon_write_4(rk_sc->sc_syscon, RK3288_GRF_SOC_CON1,
+ write_mask | write_val);
+
+ if (set_delay) {
+ write_mask = (RK3288_GRF_SOC_CON3_RXCLK_DLY_ENA_GMAC |
+ RK3288_GRF_SOC_CON3_TXCLK_DLY_ENA_GMAC |
+ RK3288_GRF_SOC_CON3_CLK_RX_DL_CFG_GMAC |
+ RK3288_GRF_SOC_CON3_CLK_TX_DL_CFG_GMAC) << 16;
+ write_val = 0;
+ if (tx_delay) {
+ write_mask |= RK3288_GRF_SOC_CON3_TXCLK_DLY_ENA_GMAC |
+ __SHIFTIN(tx_delay,
+ RK3288_GRF_SOC_CON3_CLK_TX_DL_CFG_GMAC);
+ }
+ if (rx_delay) {
+ write_mask |= RK3288_GRF_SOC_CON3_RXCLK_DLY_ENA_GMAC |
+ __SHIFTIN(rx_delay,
+ RK3288_GRF_SOC_CON3_CLK_RX_DL_CFG_GMAC);
+ }
+ syscon_write_4(rk_sc->sc_syscon, RK3288_GRF_SOC_CON3,
+ write_mask | write_val);
+ }
+
+ syscon_unlock(rk_sc->sc_syscon);
+}
+
+static void
+rk3288_gmac_set_speed_rgmii(struct dwc_gmac_softc *sc, int speed)
+{
+ struct rk_gmac_softc * const rk_sc = (struct rk_gmac_softc *)sc;
+ uint32_t write_mask, write_val;
+
+ syscon_lock(rk_sc->sc_syscon);
+
+ write_mask = (RK3288_GRF_SOC_CON1_GMAC_CLK_SEL) << 16;
+ switch (speed) {
+ case IFM_10_T:
+ write_val = RK3288_GRF_SOC_CON1_GMAC_CLK_SEL_2_5M;
+ break;
+ case IFM_100_TX:
+ write_val = RK3288_GRF_SOC_CON1_GMAC_CLK_SEL_25M;
+ break;
+ case IFM_1000_T:
+ default:
+ write_val = RK3288_GRF_SOC_CON1_GMAC_CLK_SEL_125M;
+ break;
+ }
+ syscon_write_4(rk_sc->sc_syscon, RK3288_GRF_SOC_CON1,
+ write_mask | write_val);
+
+ syscon_unlock(rk_sc->sc_syscon);
+}
+
+/*
* RK3328 specific
*/
@@ -415,6 +509,17 @@ rk_gmac_attach(device_t parent, device_t
}
switch (rk_sc->sc_type) {
+ case GMAC_RK3288:
+ if (strncmp(phy_mode, "rgmii", 5) == 0) {
+ rk3288_gmac_set_mode_rgmii(sc, tx_delay, rx_delay,
+ set_delay);
+
+ sc->sc_set_speed = rk3288_gmac_set_speed_rgmii;
+ } else {
+ aprint_error(": unsupported phy-mode '%s'\n", phy_mode);
+ return;
+ }
+ break;
case GMAC_RK3328:
if (strncmp(phy_mode, "rgmii", 5) == 0) {
rk3328_gmac_set_mode_rgmii(sc, tx_delay, rx_delay,
Index: src/sys/arch/arm/rockchip/rk_i2c.c
diff -u src/sys/arch/arm/rockchip/rk_i2c.c:1.10 src/sys/arch/arm/rockchip/rk_i2c.c:1.11
--- src/sys/arch/arm/rockchip/rk_i2c.c:1.10 Wed Jan 27 03:10:19 2021
+++ src/sys/arch/arm/rockchip/rk_i2c.c Fri Nov 12 22:02:08 2021
@@ -1,4 +1,4 @@
-/* $NetBSD: rk_i2c.c,v 1.10 2021/01/27 03:10:19 thorpej Exp $ */
+/* $NetBSD: rk_i2c.c,v 1.11 2021/11/12 22:02:08 jmcneill Exp $ */
/*-
* Copyright (c) 2018 Jared McNeill <[email protected]>
@@ -28,7 +28,7 @@
#include <sys/cdefs.h>
-__KERNEL_RCSID(0, "$NetBSD: rk_i2c.c,v 1.10 2021/01/27 03:10:19 thorpej Exp $");
+__KERNEL_RCSID(0, "$NetBSD: rk_i2c.c,v 1.11 2021/11/12 22:02:08 jmcneill Exp $");
#include <sys/param.h>
#include <sys/bus.h>
@@ -100,8 +100,14 @@ __KERNEL_RCSID(0, "$NetBSD: rk_i2c.c,v 1
#define RKI2C_TXDATA(n) (0x100 + (n) * 4)
#define RKI2C_RXDATA(n) (0x200 + (n) * 4)
+/* Compat data flags */
+#define RKI2C_HAS_PCLK __BIT(0)
+
static const struct device_compatible_entry compat_data[] = {
- { .compat = "rockchip,rk3399-i2c" },
+#if notyet
+ { .compat = "rockchip,rk3288-i2c", .value = 0 },
+#endif
+ { .compat = "rockchip,rk3399-i2c", .value = RKI2C_HAS_PCLK },
DEVICE_COMPAT_EOL
};
@@ -377,22 +383,27 @@ rk_i2c_attach(device_t parent, device_t
const int phandle = faa->faa_phandle;
bus_addr_t addr;
bus_size_t size;
+ u_int flags;
if (fdtbus_get_reg(phandle, 0, &addr, &size) != 0) {
aprint_error(": couldn't get registers\n");
return;
}
+ flags = of_compatible_lookup(phandle, compat_data)->value;
+
sc->sc_sclk = fdtbus_clock_get(phandle, "i2c");
if (sc->sc_sclk == NULL || clk_enable(sc->sc_sclk) != 0) {
aprint_error(": couldn't enable sclk\n");
return;
}
- sc->sc_pclk = fdtbus_clock_get(phandle, "pclk");
- if (sc->sc_pclk == NULL || clk_enable(sc->sc_pclk) != 0) {
- aprint_error(": couldn't enable pclk\n");
- return;
+ if (ISSET(flags, RKI2C_HAS_PCLK)) {
+ sc->sc_pclk = fdtbus_clock_get(phandle, "pclk");
+ if (sc->sc_pclk == NULL || clk_enable(sc->sc_pclk) != 0) {
+ aprint_error(": couldn't enable pclk\n");
+ return;
+ }
}
if (of_getprop_uint32(phandle, "clock-frequency", &sc->sc_clkfreq))
Index: src/sys/arch/arm/rockchip/rk_platform.c
diff -u src/sys/arch/arm/rockchip/rk_platform.c:1.14 src/sys/arch/arm/rockchip/rk_platform.c:1.15
--- src/sys/arch/arm/rockchip/rk_platform.c:1.14 Fri Sep 3 01:23:33 2021
+++ src/sys/arch/arm/rockchip/rk_platform.c Fri Nov 12 22:02:08 2021
@@ -1,7 +1,7 @@
-/* $NetBSD: rk_platform.c,v 1.14 2021/09/03 01:23:33 mrg Exp $ */
+/* $NetBSD: rk_platform.c,v 1.15 2021/11/12 22:02:08 jmcneill Exp $ */
/*-
- * Copyright (c) 2018 Jared McNeill <[email protected]>
+ * Copyright (c) 2018,2021 Jared McNeill <[email protected]>
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
@@ -31,7 +31,7 @@
#include "opt_console.h"
#include <sys/cdefs.h>
-__KERNEL_RCSID(0, "$NetBSD: rk_platform.c,v 1.14 2021/09/03 01:23:33 mrg Exp $");
+__KERNEL_RCSID(0, "$NetBSD: rk_platform.c,v 1.15 2021/11/12 22:02:08 jmcneill Exp $");
#include <sys/param.h>
#include <sys/bus.h>
@@ -101,6 +101,95 @@ rk_platform_bootstrap(void)
}
}
+#ifdef SOC_RK3288
+
+#define RK3288_WDT_BASE 0xff800000
+#define RK3288_WDT_SIZE 0x10000
+
+#define RK3288_WDT_CR 0x0000
+#define RK3288_WDT_CR_WDT_EN __BIT(0)
+#define RK3288_WDT_TORR 0x0004
+#define RK3288_WDT_CRR 0x000c
+#define RK3288_WDT_MAGIC 0x76
+
+static bus_space_handle_t rk3288_wdt_bsh;
+
+#include <arm/rockchip/rk3288_platform.h>
+
+static const struct pmap_devmap *
+rk3288_platform_devmap(void)
+{
+ static const struct pmap_devmap devmap[] = {
+ DEVMAP_ENTRY(RK3288_CORE_VBASE,
+ RK3288_CORE_PBASE,
+ RK3288_CORE_SIZE),
+ DEVMAP_ENTRY_END
+ };
+
+ return devmap;
+}
+
+void rk3288_platform_early_putchar(char);
+
+void __noasan
+rk3288_platform_early_putchar(char c)
+{
+#ifdef CONSADDR
+#define CONSADDR_VA ((CONSADDR - RK3288_CORE_PBASE) + RK3288_CORE_VBASE)
+ volatile uint32_t *uartaddr = cpu_earlydevice_va_p() ?
+ (volatile uint32_t *)CONSADDR_VA :
+ (volatile uint32_t *)CONSADDR;
+
+ while ((le32toh(uartaddr[com_lsr]) & LSR_TXRDY) == 0)
+ ;
+
+ uartaddr[com_data] = htole32(c);
+#undef CONSADDR_VA
+#endif
+}
+
+static void
+rk3288_platform_bootstrap(void)
+{
+ bus_space_tag_t bst = &arm_generic_bs_tag;
+
+ rk_platform_bootstrap();
+ bus_space_map(bst, RK3288_WDT_BASE, RK3288_WDT_SIZE, 0, &rk3288_wdt_bsh);
+}
+
+static void
+rk3288_platform_reset(void)
+{
+ bus_space_tag_t bst = &arm_generic_bs_tag;
+
+ bus_space_write_4(bst, rk3288_wdt_bsh, RK3288_WDT_TORR, 0);
+ bus_space_write_4(bst, rk3288_wdt_bsh, RK3288_WDT_CRR, RK3288_WDT_MAGIC);
+ for (;;) {
+ bus_space_write_4(bst, rk3288_wdt_bsh, RK3288_WDT_CR, RK3288_WDT_CR_WDT_EN);
+ }
+}
+
+static u_int
+rk3288_platform_uart_freq(void)
+{
+ return RK3288_UART_FREQ;
+}
+
+static const struct arm_platform rk3288_platform = {
+ .ap_devmap = rk3288_platform_devmap,
+ .ap_bootstrap = rk3288_platform_bootstrap,
+ .ap_init_attach_args = rk_platform_init_attach_args,
+ .ap_device_register = rk_platform_device_register,
+ .ap_reset = rk3288_platform_reset,
+ .ap_delay = gtmr_delay,
+ .ap_uart_freq = rk3288_platform_uart_freq,
+ .ap_mpstart = arm_fdt_cpu_mpstart,
+};
+
+ARM_PLATFORM(rk3288, "rockchip,rk3288", &rk3288_platform);
+#endif /* SOC_RK3288 */
+
+
#ifdef SOC_RK3328
#include <arm/rockchip/rk3328_platform.h>
Index: src/sys/arch/evbarm/conf/GENERIC
diff -u src/sys/arch/evbarm/conf/GENERIC:1.100 src/sys/arch/evbarm/conf/GENERIC:1.101
--- src/sys/arch/evbarm/conf/GENERIC:1.100 Thu Aug 26 17:08:34 2021
+++ src/sys/arch/evbarm/conf/GENERIC Fri Nov 12 22:02:08 2021
@@ -1,5 +1,5 @@
#
-# $NetBSD: GENERIC,v 1.100 2021/08/26 17:08:34 thorpej Exp $
+# $NetBSD: GENERIC,v 1.101 2021/11/12 22:02:08 jmcneill Exp $
#
# GENERIC ARM (aarch32) kernel
#
@@ -19,6 +19,7 @@ options SOC_IMX6QDL
options SOC_IMX7D
options SOC_MESON8B
options SOC_OMAP3
+options SOC_RK3288
options SOC_SUN4I_A10
options SOC_SUN5I_A13
options SOC_SUN6I_A31
@@ -79,6 +80,7 @@ options MSGBUFSIZE=32768
#options EARLYCONS=vexpress, CONSADDR=0x1c090000
#options EARLYCONS=virt, CONSADDR=0x09000000
#options EARLYCONS=zynq, CONSADDR=0xe0001000
+#options EARLYCONS=rk3288, CONSADDR=0xff690000
# Kernel Undefined Behavior Sanitizer (kUBSan). Use UBSAN_ALWAYS_FATAL
# if you want panics instead of warnings.
@@ -134,6 +136,7 @@ meson8bclkc* at fdt? pass 2 # Amlogic
mesonresets* at fdt? pass 2 # Amlogic Meson misc. clock resets
omap3cm* at fdt? pass 1 # TI OMAP3 CM
omap3prm* at fdt? pass 1 # TI OMAP3 PRM
+rkcru* at fdt? pass 2 # Rockchip RK3288 CRU
sun4ia10ccu* at fdt? pass 2 # Allwinner A10/A20 CCU
sun5ia13ccu* at fdt? pass 2 # Allwinner A13 CCU
sun6ia31ccu* at fdt? pass 2 # Allwinner A31 CCU
@@ -258,6 +261,7 @@ imxgpio* at fdt? pass 3 # i.MX GPIO
mesonpinctrl* at fdt? pass 2 # Amlogic Meson GPIO
plgpio* at fdt? # ARM PrimeCell GPIO
sunxigpio* at fdt? pass 3 # Allwinner GPIO
+rkgpio* at rkiomux? # Rockchip GPIO
tegragpio* at fdt? pass 2 # NVIDIA Tegra GPIO
tigpio* at fdt? pass 2 # TI GPIO
gpio* at gpiobus?
@@ -265,6 +269,7 @@ gpio* at gpiobus?
# IOMUX / MPIO / Pinmux
pinctrl* at fdt? pass 2 # Generic pinctrl driver
imxiomux* at fdt? pass 2 # i.MX IOMUX
+rkiomux* at fdt? pass 3 # Rockchip IOMUX
tegrapinmux* at fdt? # NVIDIA Tegra MPIO
# PWM controller
@@ -349,6 +354,7 @@ options I2C_MAX_ADDR=0xfff
bsciic* at fdt? # Broadcom BCM283x Serial Control
exyoi2c* at fdt? # Samsung Exynos I2C
imxi2c* at fdt? pass 4 # i.MX I2C
+rkiic* at fdt? pass 4 # Rockchip I2C
sunxirsb* at fdt? pass 4 # Allwinner RSB
sunxitwi* at fdt? # Allwinner TWI
tegrai2c* at fdt? pass 4 # NVIDIA Tegra I2C
@@ -370,6 +376,7 @@ em3027rtc* at iic?
max77620pmic* at iic?
pcaiicmux* at iic? # PCA954x / PCA984x I2C switch / mux
pcf8563rtc* at iic? # PCF8563 RTC
+rkpmic* at iic? # Rockchip Power Management IC
seeprom* at iic? # AT24Cxx Serial EEPROM
sy8106a* at iic? # Silergy SY81061 regulator
tcakp* at iic? # TI TCA8418 Keypad Scan IC
@@ -549,6 +556,8 @@ exusbphy* at fdt? pass 9 # Samsung Exy
exusbdrdphy* at fdt? pass 9 # Samsung Exynos USB3 DRD PHY
imxusbphy* at fdt? pass 9 # i.MX USB PHY
mesonusbphy* at fdt? pass 9 # Amlogic Meson USB2 PHY
+rk3288usb* at fdt? pass 9 # Rockchip USB PHY
+rk3288usbphy* at rk3288usb?
sun9iusbphy* at fdt? pass 9 # Allwinner A80 USB PHY
sunxiusbphy* at fdt? pass 9 # Allwinner USB PHY
sunxiusb3phy* at fdt? pass 9 # Allwinner USB3 PHY
Index: src/sys/arch/evbarm/conf/files.generic
diff -u src/sys/arch/evbarm/conf/files.generic:1.11 src/sys/arch/evbarm/conf/files.generic:1.12
--- src/sys/arch/evbarm/conf/files.generic:1.11 Wed Dec 23 14:42:38 2020
+++ src/sys/arch/evbarm/conf/files.generic Fri Nov 12 22:02:08 2021
@@ -1,4 +1,4 @@
-# $NetBSD: files.generic,v 1.11 2020/12/23 14:42:38 skrll Exp $
+# $NetBSD: files.generic,v 1.12 2021/11/12 22:02:08 jmcneill Exp $
#
# A generic (aarch32) kernel configuration info
#
@@ -22,6 +22,7 @@ include "arch/arm/amlogic/files.meson"
include "arch/arm/broadcom/files.bcm2835"
include "arch/arm/nvidia/files.tegra"
include "arch/arm/nxp/files.imx"
+include "arch/arm/rockchip/files.rockchip"
include "arch/arm/samsung/files.exynos"
include "arch/arm/sunxi/files.sunxi"
include "arch/arm/ti/files.ti"
Added files:
Index: src/sys/arch/arm/rockchip/rk3066_smp.c
diff -u /dev/null src/sys/arch/arm/rockchip/rk3066_smp.c:1.1
--- /dev/null Fri Nov 12 22:02:08 2021
+++ src/sys/arch/arm/rockchip/rk3066_smp.c Fri Nov 12 22:02:08 2021
@@ -0,0 +1,166 @@
+/* $NetBSD: rk3066_smp.c,v 1.1 2021/11/12 22:02:08 jmcneill Exp $ */
+
+/*-
+ * Copyright (c) 2021 Jared McNeill <[email protected]>
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
+ * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
+ * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
+ * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
+ * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
+ * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
+ * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED
+ * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
+ * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ */
+
+#include "opt_soc.h"
+#include "opt_multiprocessor.h"
+
+#include <sys/cdefs.h>
+__KERNEL_RCSID(0, "$NetBSD: rk3066_smp.c,v 1.1 2021/11/12 22:02:08 jmcneill Exp $");
+
+#include <sys/param.h>
+#include <sys/bus.h>
+#include <sys/cpu.h>
+#include <sys/device.h>
+
+#include <dev/fdt/fdtvar.h>
+#include <arm/fdt/arm_fdtvar.h>
+
+#include <uvm/uvm_extern.h>
+
+#define PMU_PWRDN_CON 0x0008
+#define PMU_PWRDN_ST 0x000c
+
+#define SRAM_ENTRY_PA 0x0008
+#define SRAM_DOORBELL 0x0004
+#define SRAM_DOORBELL_MAGIC 0xdeadbeaf
+
+extern struct bus_space arm_generic_bs_tag;
+
+static uint32_t
+rk3066_mpstart_pa(void)
+{
+ bool ok __diagused;
+ paddr_t pa;
+
+ ok = pmap_extract(pmap_kernel(), (vaddr_t)cpu_mpstart, &pa);
+ KASSERT(ok);
+
+ return (uint32_t)pa;
+}
+
+static int
+rk3066_map(int phandle, bus_space_tag_t bst, bus_space_handle_t *pbsh,
+ bus_size_t *psize)
+{
+ bus_addr_t addr;
+ int error;
+
+ error = fdtbus_get_reg(phandle, 0, &addr, psize);
+ if (error != 0) {
+ return error;
+ }
+
+ return bus_space_map(bst, addr, *psize, 0, pbsh);
+}
+
+static int
+rk3066_smp_enable(int cpus_phandle, u_int cpuno)
+{
+ bus_space_tag_t bst = &arm_generic_bs_tag;
+ bus_space_handle_t bsh_sram, bsh_pmu;
+ bus_size_t sz_sram, sz_pmu;
+ uint32_t val;
+ int error;
+
+ const int sram_phandle =
+ of_find_bycompat(OF_peer(0), "rockchip,rk3066-smp-sram");
+ if (sram_phandle == -1) {
+ printf("%s: missing rockchip,rk3066-smp-sram node\n",
+ __func__);
+ return ENXIO;
+ }
+
+ const int pmu_phandle = fdtbus_get_phandle(cpus_phandle,
+ "rockchip,pmu");
+ if (pmu_phandle == -1) {
+ printf("%s: missing rockchip,pmu xref\n", __func__);
+ return ENXIO;
+ }
+
+ error = rk3066_map(sram_phandle, bst, &bsh_sram, &sz_sram);
+ if (error != 0) {
+ return error;
+ }
+
+ error = rk3066_map(pmu_phandle, bst, &bsh_pmu, &sz_pmu);
+ if (error != 0) {
+ bus_space_unmap(bst, bsh_pmu, sz_pmu);
+ return error;
+ }
+
+ /* Enable the A17 core's power domain */
+ val = bus_space_read_4(bst, bsh_pmu, PMU_PWRDN_CON);
+ val &= ~__BIT(cpuno);
+ bus_space_write_4(bst, bsh_pmu, PMU_PWRDN_CON, val);
+
+ /* Wait for the A17 core to power on */
+ do {
+ val = bus_space_read_4(bst, bsh_pmu, PMU_PWRDN_ST);
+ } while ((val & __BIT(cpuno)) != 0);
+
+ delay(2000);
+
+ /* Set wake vector */
+ bus_space_write_4(bst, bsh_sram, SRAM_ENTRY_PA, rk3066_mpstart_pa());
+ /* Notify boot rom that we are ready to start */
+ bus_space_write_4(bst, bsh_sram, SRAM_DOORBELL, SRAM_DOORBELL_MAGIC);
+ dsb();
+ sev();
+
+ bus_space_unmap(bst, bsh_pmu, sz_pmu);
+ bus_space_unmap(bst, bsh_sram, sz_sram);
+
+ return 0;
+}
+
+static int
+cpu_enable_rk3066(int phandle)
+{
+ static uint32_t enabled;
+ uint64_t mpidr;
+ int error = 0;
+
+ fdtbus_get_reg64(phandle, 0, &mpidr, NULL);
+
+ const u_int cpuno = __SHIFTOUT(mpidr, MPIDR_AFF0);
+ const bool is_enabled = enabled & __BIT(cpuno);
+
+ if (!is_enabled) {
+ error = rk3066_smp_enable(OF_parent(phandle), cpuno);
+ if (error == 0) {
+ enabled |= __BIT(cpuno);
+ }
+ } else {
+ printf("WARNING: CPU enable called more than once for CPU %u\n",
+ cpuno);
+ }
+
+ return error;
+}
+
+ARM_CPU_METHOD(rk3066, "rockchip,rk3066-smp", cpu_enable_rk3066);
Index: src/sys/arch/arm/rockchip/rk3288_cru.c
diff -u /dev/null src/sys/arch/arm/rockchip/rk3288_cru.c:1.1
--- /dev/null Fri Nov 12 22:02:08 2021
+++ src/sys/arch/arm/rockchip/rk3288_cru.c Fri Nov 12 22:02:08 2021
@@ -0,0 +1,309 @@
+/* $NetBSD: rk3288_cru.c,v 1.1 2021/11/12 22:02:08 jmcneill Exp $ */
+
+/*-
+ * Copyright (c) 2021 Jared McNeill <[email protected]>
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
+ * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
+ * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
+ * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
+ * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
+ * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
+ * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED
+ * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
+ * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ */
+
+#include <sys/cdefs.h>
+
+__KERNEL_RCSID(1, "$NetBSD: rk3288_cru.c,v 1.1 2021/11/12 22:02:08 jmcneill Exp $");
+
+#include <sys/param.h>
+#include <sys/bus.h>
+#include <sys/device.h>
+#include <sys/systm.h>
+
+#include <dev/fdt/fdtvar.h>
+
+#include <arm/rockchip/rk_cru.h>
+#include <arm/rockchip/rk3288_cru.h>
+
+#define PLL_CON(n) (0x0000 + (n) * 4)
+#define MODE_CON 0x0050
+#define CLKSEL_CON(n) (0x0060 + (n) * 4)
+#define CLKGATE_CON(n) (0x0160 + (n) * 4)
+#define SOFTRST_CON(n) (0x01b8 + (n) * 4)
+
+#define GRF_SOC_CON4 0x0410
+#define GRF_MAC_CON1 0x0904
+
+static int rk3288_cru_match(device_t, cfdata_t, void *);
+static void rk3288_cru_attach(device_t, device_t, void *);
+
+static const struct device_compatible_entry compat_data[] = {
+ { .compat = "rockchip,rk3288-cru" },
+ DEVICE_COMPAT_EOL
+};
+
+CFATTACH_DECL_NEW(rk3288_cru, sizeof(struct rk_cru_softc),
+ rk3288_cru_match, rk3288_cru_attach, NULL, NULL);
+
+static const char * pll_parents[] = { "xin24m" };
+static const char * aclk_cpu_src_parents[] = { "cpll_aclk_cpu", "gpll_aclk_cpu" };
+static const char * uart0_parents[] = { "clk_uart0_div", "clk_uart0_frac", "xin24m" };
+static const char * uart1_parents[] = { "clk_uart1_div", "clk_uart1_frac", "xin24m" };
+static const char * uart2_parents[] = { "clk_uart2_div", "clk_uart2_frac", "xin24m" };
+static const char * uart3_parents[] = { "clk_uart3_div", "clk_uart3_frac", "xin24m" };
+static const char * uart4_parents[] = { "clk_uart4_div", "clk_uart4_frac", "xin24m" };
+static const char * mmc_parents[] = { "cpll", "gpll", "xin24m", "xin24m" };
+static const char * mac_parents[] = { "mac_pll_src", "ext_gmac" };
+static const char * mux_2plls_parents[] = { "cpll", "gpll" };
+static const char * mux_npll_cpll_gpll_parents[] = { "npll", "cpll", "gpll" };
+static const char * mux_3plls_usb_parents[] = { "cpll", "gpll", "usbphy480m_src", "npll" };
+
+static struct rk_cru_pll_rate rk3288_pll_rates[] = {
+ /* TODO */
+};
+
+static struct rk_cru_clk rk3288_cru_clks[] = {
+ RK3288_PLL(RK3288_PLL_CPLL, "cpll", pll_parents,
+ PLL_CON(8), /* con_base */
+ MODE_CON, /* mode_reg */
+ __BIT(8), /* mode_mask */
+ __BIT(2), /* lock_mask */
+ rk3288_pll_rates),
+ RK3288_PLL(RK3288_PLL_GPLL, "gpll", pll_parents,
+ PLL_CON(12), /* con_base */
+ MODE_CON, /* mode_reg */
+ __BIT(12), /* mode_mask */
+ __BIT(3), /* lock_mask */
+ rk3288_pll_rates),
+ RK3288_PLL(RK3288_PLL_NPLL, "npll", pll_parents,
+ PLL_CON(16), /* con_base */
+ MODE_CON, /* mode_reg */
+ __BIT(14), /* mode_mask */
+ __BIT(4), /* lock_mask */
+ rk3288_pll_rates),
+
+ RK_COMPOSITE_NOGATE(0, "aclk_cpu_src", aclk_cpu_src_parents,
+ CLKSEL_CON(1), /* muxdiv_reg */
+ __BIT(15), /* mux_mask */
+ __BITS(7,3), /* div_mask */
+ 0),
+ RK_COMPOSITE_NOMUX(RK3288_PCLK_CPU, "pclk_cpu", "aclk_cpu_pre",
+ CLKSEL_CON(1), /* div_reg */
+ __BITS(14,12), /* div_mask */
+ CLKGATE_CON(0), /* gate_reg */
+ __BIT(5), /* gate_mask */
+ 0),
+ RK_COMPOSITE_NOMUX(RK3288_HCLK_PERI, "hclk_peri", "aclk_peri_src",
+ CLKSEL_CON(10), /* div_reg */
+ __BITS(9,8), /* div_mask */
+ CLKGATE_CON(2), /* gate_reg */
+ __BIT(2), /* gate_mask */
+ RK_COMPOSITE_POW2),
+ RK_COMPOSITE(0, "aclk_peri_src", mux_2plls_parents,
+ CLKSEL_CON(10), /* muxdiv_reg */
+ __BIT(15), /* mux_mask */
+ __BITS(4,0), /* div_mask */
+ CLKGATE_CON(2), /* gate_reg */
+ __BIT(0), /* gate_mask */
+ 0),
+ RK_COMPOSITE_NOMUX(0, "pclk_pd_pmu", "gpll",
+ CLKSEL_CON(33), /* div_reg */
+ __BITS(4,0), /* div_mask */
+ CLKGATE_CON(5), /* gate_reg */
+ __BIT(8), /* gate_mask */
+ 0),
+ RK_COMPOSITE_NOMUX(RK3288_PCLK_PERI, "pclk_peri", "aclk_peri_src",
+ CLKSEL_CON(10), /* div_reg */
+ __BITS(13,12), /* div_mask */
+ CLKGATE_CON(2), /* gate_reg */
+ __BIT(3), /* gate_mask */
+ 0),
+
+ /* UARTs */
+ RK_COMPOSITE(0, "clk_uart0_div", mux_3plls_usb_parents,
+ CLKSEL_CON(13), /* muxdiv_reg */
+ __BITS(14,13), /* mux_mask */
+ __BITS(6,0), /* div_mask */
+ CLKGATE_CON(1), /* gate_reg */
+ __BIT(8), /* gate_mask */
+ 0),
+ /* XXX TODO: CRU_CLKGATE1_CON bit 9 (clk_uart0_frac_src_gate_en) */
+ RK_COMPOSITE_FRAC(0, "clk_uart0_frac", "clk_uart0_div",
+ CLKSEL_CON(17), /* fracdiv_reg */
+ 0),
+ RK_COMPOSITE_NOMUX(0, "clk_uart1_div", "uart_src",
+ CLKSEL_CON(14), /* div_reg */
+ __BITS(6,0), /* div_mask */
+ CLKGATE_CON(1), /* gate_reg */
+ __BIT(10), /* gate_mask */
+ 0),
+ /* XXX TODO: CRU_CLKGATE1_CON bit 11 (clk_uart1_frac_src_gate_en) */
+ RK_COMPOSITE_FRAC(0, "clk_uart1_frac", "clk_uart1_div",
+ CLKSEL_CON(18), /* fracdiv_reg */
+ 0),
+ RK_COMPOSITE_NOMUX(0, "clk_uart2_div", "uart_src",
+ CLKSEL_CON(15), /* div_reg */
+ __BITS(6,0), /* div_mask */
+ CLKGATE_CON(1), /* gate_reg */
+ __BIT(12), /* gate_mask */
+ 0),
+ /* XXX TODO: CRU_CLKGATE1_CON bit 13 (clk_uart2_frac_src_gate_en) */
+ RK_COMPOSITE_FRAC(0, "clk_uart2_frac", "clk_uart2_div",
+ CLKSEL_CON(19), /* fracdiv_reg */
+ 0),
+ RK_COMPOSITE_NOMUX(0, "clk_uart3_div", "uart_src",
+ CLKSEL_CON(16), /* div_reg */
+ __BITS(6,0), /* div_mask */
+ CLKGATE_CON(1), /* gate_reg */
+ __BIT(14), /* gate_mask */
+ 0),
+ /* XXX TODO: CRU_CLKGATE1_CON bit 15 (clk_uart3_frac_src_gate_en) */
+ RK_COMPOSITE_FRAC(0, "clk_uart3_frac", "clk_uart3_div",
+ CLKSEL_CON(20), /* fracdiv_reg */
+ 0),
+ RK_COMPOSITE_NOMUX(0, "clk_uart4_div", "uart_src",
+ CLKSEL_CON(3), /* div_reg */
+ __BITS(6,0), /* div_mask */
+ CLKGATE_CON(2), /* gate_reg */
+ __BIT(12), /* gate_mask */
+ 0),
+ /* XXX TODO: CRU_CLKGATE2_CON bit 13 (clk_uart4_frac_src_gate_en) */
+ RK_COMPOSITE_FRAC(0, "clk_uart4_frac", "clk_uart4_div",
+ CLKSEL_CON(7), /* fracdiv_reg */
+ 0),
+
+ /* SD/eMMC/SDIO */
+ RK_COMPOSITE(RK3288_SCLK_SDMMC, "sclk_sdmmc", mmc_parents,
+ CLKSEL_CON(11), /* muxdiv_reg */
+ __BITS(7,6), /* mux_mask */
+ __BITS(5,0), /* div_mask */
+ CLKGATE_CON(13), /* gate_reg */
+ __BIT(0), /* gate_mask */
+ 0),
+ RK_COMPOSITE(RK3288_SCLK_SDIO0, "sclk_sdio0", mmc_parents,
+ CLKSEL_CON(12), /* muxdiv_reg */
+ __BITS(7,6), /* mux_mask */
+ __BITS(5,0), /* div_mask */
+ CLKGATE_CON(13), /* gate_reg */
+ __BIT(1), /* gate_mask */
+ 0),
+ RK_COMPOSITE(RK3288_SCLK_SDIO1, "sclk_sdio1", mmc_parents,
+ CLKSEL_CON(34), /* muxdiv_reg */
+ __BITS(15,14), /* mux_mask */
+ __BITS(13,8), /* div_mask */
+ CLKGATE_CON(13), /* gate_reg */
+ __BIT(2), /* gate_mask */
+ 0),
+ RK_COMPOSITE(RK3288_SCLK_EMMC, "sclk_emmc", mmc_parents,
+ CLKSEL_CON(12), /* muxdiv_reg */
+ __BITS(15,14), /* mux_mask */
+ __BITS(13,8), /* div_mask */
+ CLKGATE_CON(13), /* gate_reg */
+ __BIT(3), /* gate_mask */
+ 0),
+
+ /* MAC */
+ RK_COMPOSITE(0, "mac_pll_src", mux_npll_cpll_gpll_parents,
+ CLKSEL_CON(21), /* muxdiv_reg */
+ __BITS(1,0), /* mux_mask */
+ __BITS(12,8), /* div_mask */
+ CLKGATE_CON(2), /* gate_reg */
+ __BIT(5), /* gate_mask */
+ 0),
+
+ RK_DIV(0, "aclk_cpu_pre", "aclk_cpu_src", CLKSEL_CON(1), __BITS(3,0), 0),
+ RK_DIV(0, "clk_24m", "xin24m", CLKSEL_CON(2), __BITS(12,8), 0),
+ RK_DIV(0, "pclk_pd_alive", "gpll", CLKSEL_CON(33), __BITS(12,8), 0),
+
+ RK_MUX(RK3288_SCLK_UART0, "sclk_uart0", uart0_parents, CLKSEL_CON(13), __BITS(9,8)),
+ RK_MUX(RK3288_SCLK_UART1, "sclk_uart1", uart1_parents, CLKSEL_CON(14), __BITS(9,8)),
+ RK_MUX(RK3288_SCLK_UART2, "sclk_uart2", uart2_parents, CLKSEL_CON(15), __BITS(9,8)),
+ RK_MUX(RK3288_SCLK_UART3, "sclk_uart3", uart3_parents, CLKSEL_CON(16), __BITS(9,8)),
+ RK_MUX(RK3288_SCLK_UART4, "sclk_uart4", uart4_parents, CLKSEL_CON(3), __BITS(9,8)),
+ RK_MUX(0, "uart_src", mux_2plls_parents, CLKSEL_CON(15), __BIT(15)),
+ RK_MUX(RK3288_SCLK_MAC, "mac_clk", mac_parents, CLKSEL_CON(21), __BIT(4)),
+
+ RK_GATE(0, "gpll_aclk_cpu", "gpll", CLKGATE_CON(0), 10),
+ RK_GATE(0, "cpll_aclk_cpu", "cpll", CLKGATE_CON(0), 11),
+ RK_GATE(RK3288_ACLK_PERI, "aclk_peri", "aclk_peri_src", CLKGATE_CON(2), 1),
+ RK_GATE(RK3288_SCLK_MAC_RX, "sclk_mac_rx", "mac_clk", CLKGATE_CON(5), 0),
+ RK_GATE(RK3288_SCLK_MAC_TX, "sclk_mac_tx", "mac_clk", CLKGATE_CON(5), 1),
+ RK_GATE(RK3288_SCLK_MACREF, "sclk_macref", "mac_clk", CLKGATE_CON(5), 2),
+ RK_GATE(RK3288_SCLK_MACREF_OUT, "sclk_macref_out", "mac_clk", CLKGATE_CON(5), 3),
+ RK_GATE(RK3288_PCLK_I2C1, "pclk_i2c1", "pclk_peri", CLKGATE_CON(6), 13),
+ RK_GATE(RK3288_PCLK_I2C3, "pclk_i2c3", "pclk_peri", CLKGATE_CON(6), 14),
+ RK_GATE(RK3288_PCLK_I2C4, "pclk_i2c4", "pclk_peri", CLKGATE_CON(6), 15),
+ RK_GATE(RK3288_PCLK_I2C5, "pclk_i2c5", "pclk_peri", CLKGATE_CON(7), 0),
+ RK_GATE(RK3288_HCLK_USBHOST0, "hclk_host0", "hclk_peri", CLKGATE_CON(7), 6),
+ RK_GATE(RK3288_HCLK_USBHOST1, "hclk_host1", "hclk_peri", CLKGATE_CON(7), 7),
+ RK_GATE(RK3288_HCLK_HSIC, "hclk_hsic", "hclk_peri", CLKGATE_CON(7), 8),
+ RK_GATE(RK3288_PCLK_GMAC, "pclk_gmac", "pclk_peri", CLKGATE_CON(8), 1),
+ RK_GATE(RK3288_HCLK_SDMMC, "hclk_sdmmc", "hclk_peri", CLKGATE_CON(8), 3),
+ RK_GATE(RK3288_HCLK_SDIO0, "hclk_sdio0", "hclk_peri", CLKGATE_CON(8), 4),
+ RK_GATE(RK3288_HCLK_SDIO1, "hclk_sdio1", "hclk_peri", CLKGATE_CON(8), 5),
+ RK_GATE(RK3288_ACLK_GMAC, "aclk_gmac", "aclk_peri", CLKGATE_CON(8), 0),
+ RK_GATE(RK3288_HCLK_EMMC, "hclk_emmc", "hclk_peri", CLKGATE_CON(8), 6),
+ RK_GATE(RK3288_PCLK_I2C0, "pclk_i2c0", "pclk_cpu", CLKGATE_CON(10), 2),
+ RK_GATE(RK3288_PCLK_I2C2, "pclk_i2c2", "pclk_cpu", CLKGATE_CON(10), 3),
+ RK_GATE(RK3288_PCLK_UART2, "pclk_uart2", "pclk_cpu", CLKGATE_CON(11), 9),
+ RK_GATE(RK3288_SCLK_OTGPHY0, "sclk_otgphy0", "xin24m", CLKGATE_CON(13), 4),
+ RK_GATE(RK3288_SCLK_OTGPHY1, "sclk_otgphy1", "xin24m", CLKGATE_CON(13), 5),
+ RK_GATE(RK3288_SCLK_OTGPHY2, "sclk_otgphy2", "xin24m", CLKGATE_CON(13), 6),
+ RK_GATE(RK3288_PCLK_GPIO1, "pclk_gpio1", "pclk_pd_alive", CLKGATE_CON(14), 1),
+ RK_GATE(RK3288_PCLK_GPIO2, "pclk_gpio2", "pclk_pd_alive", CLKGATE_CON(14), 2),
+ RK_GATE(RK3288_PCLK_GPIO3, "pclk_gpio3", "pclk_pd_alive", CLKGATE_CON(14), 3),
+ RK_GATE(RK3288_PCLK_GPIO4, "pclk_gpio4", "pclk_pd_alive", CLKGATE_CON(14), 4),
+ RK_GATE(RK3288_PCLK_GPIO5, "pclk_gpio5", "pclk_pd_alive", CLKGATE_CON(14), 5),
+ RK_GATE(RK3288_PCLK_GPIO6, "pclk_gpio6", "pclk_pd_alive", CLKGATE_CON(14), 6),
+ RK_GATE(RK3288_PCLK_GPIO7, "pclk_gpio7", "pclk_pd_alive", CLKGATE_CON(14), 7),
+ RK_GATE(RK3288_PCLK_GPIO8, "pclk_gpio8", "pclk_pd_alive", CLKGATE_CON(14), 8),
+ RK_GATE(RK3288_PCLK_GPIO0, "pclk_gpio0", "pclk_pd_pmu", CLKGATE_CON(17), 4),
+};
+
+static int
+rk3288_cru_match(device_t parent, cfdata_t cf, void *aux)
+{
+ struct fdt_attach_args * const faa = aux;
+
+ return of_compatible_match(faa->faa_phandle, compat_data);
+}
+
+static void
+rk3288_cru_attach(device_t parent, device_t self, void *aux)
+{
+ struct rk_cru_softc * const sc = device_private(self);
+ struct fdt_attach_args * const faa = aux;
+
+ sc->sc_dev = self;
+ sc->sc_phandle = faa->faa_phandle;
+ sc->sc_bst = faa->faa_bst;
+
+ sc->sc_clks = rk3288_cru_clks;
+ sc->sc_nclks = __arraycount(rk3288_cru_clks);
+
+ sc->sc_grf_soc_status = 0x0284;
+ sc->sc_softrst_base = SOFTRST_CON(0);
+
+ if (rk_cru_attach(sc) != 0)
+ return;
+
+ aprint_naive("\n");
+ aprint_normal(": RK3288 CRU\n");
+
+ rk_cru_print(sc);
+}
Index: src/sys/arch/arm/rockchip/rk3288_cru.h
diff -u /dev/null src/sys/arch/arm/rockchip/rk3288_cru.h:1.1
--- /dev/null Fri Nov 12 22:02:08 2021
+++ src/sys/arch/arm/rockchip/rk3288_cru.h Fri Nov 12 22:02:08 2021
@@ -0,0 +1,209 @@
+/* $NetBSD: rk3288_cru.h,v 1.1 2021/11/12 22:02:08 jmcneill Exp $ */
+
+/*-
+ * Copyright (c) 2021 Jared McNeill <[email protected]>
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
+ * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
+ * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
+ * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
+ * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
+ * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
+ * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED
+ * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
+ * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ */
+
+#ifndef _RK3328_CRU_H
+#define _RK3328_CRU_H
+
+#define RK3288_PLL_APLL 1
+#define RK3288_PLL_DPLL 2
+#define RK3288_PLL_CPLL 3
+#define RK3288_PLL_GPLL 4
+#define RK3288_PLL_NPLL 5
+#define RK3288_ARMCLK 6
+#define RK3288_SCLK_GPU 64
+#define RK3288_SCLK_SPI0 65
+#define RK3288_SCLK_SPI1 66
+#define RK3288_SCLK_SPI2 67
+#define RK3288_SCLK_SDMMC 68
+#define RK3288_SCLK_SDIO0 69
+#define RK3288_SCLK_SDIO1 70
+#define RK3288_SCLK_EMMC 71
+#define RK3288_SCLK_TSADC 72
+#define RK3288_SCLK_SARADC 73
+#define RK3288_SCLK_PS2C 74
+#define RK3288_SCLK_NANDC0 75
+#define RK3288_SCLK_NANDC1 76
+#define RK3288_SCLK_UART0 77
+#define RK3288_SCLK_UART1 78
+#define RK3288_SCLK_UART2 79
+#define RK3288_SCLK_UART3 80
+#define RK3288_SCLK_UART4 81
+#define RK3288_SCLK_I2S0 82
+#define RK3288_SCLK_SPDIF 83
+#define RK3288_SCLK_SPDIF8CH 84
+#define RK3288_SCLK_TIMER0 85
+#define RK3288_SCLK_TIMER1 86
+#define RK3288_SCLK_TIMER2 87
+#define RK3288_SCLK_TIMER3 88
+#define RK3288_SCLK_TIMER4 89
+#define RK3288_SCLK_TIMER5 90
+#define RK3288_SCLK_TIMER6 91
+#define RK3288_SCLK_HSADC 92
+#define RK3288_SCLK_OTGPHY0 93
+#define RK3288_SCLK_OTGPHY1 94
+#define RK3288_SCLK_OTGPHY2 95
+#define RK3288_SCLK_OTG_ADP 96
+#define RK3288_SCLK_HSICPHY480M 97
+#define RK3288_SCLK_HSICPHY12M 98
+#define RK3288_SCLK_MACREF 99
+#define RK3288_SCLK_LCDC_PWM0 100
+#define RK3288_SCLK_LCDC_PWM1 101
+#define RK3288_SCLK_MAC_RX 102
+#define RK3288_SCLK_MAC_TX 103
+#define RK3288_SCLK_EDP_24M 104
+#define RK3288_SCLK_EDP 105
+#define RK3288_SCLK_RGA 106
+#define RK3288_SCLK_ISP 107
+#define RK3288_SCLK_ISP_JPE 108
+#define RK3288_SCLK_HDMI_HDCP 109
+#define RK3288_SCLK_HDMI_CEC 110
+#define RK3288_SCLK_HEVC_CABAC 111
+#define RK3288_SCLK_HEVC_CORE 112
+#define RK3288_SCLK_I2S0_OUT 113
+#define RK3288_SCLK_SDMMC_DRV 114
+#define RK3288_SCLK_SDIO0_DRV 115
+#define RK3288_SCLK_SDIO1_DRV 116
+#define RK3288_SCLK_EMMC_DRV 117
+#define RK3288_SCLK_SDMMC_SAMPLE 118
+#define RK3288_SCLK_SDIO0_SAMPLE 119
+#define RK3288_SCLK_SDIO1_SAMPLE 120
+#define RK3288_SCLK_EMMC_SAMPLE 121
+#define RK3288_SCLK_USBPHY480M_SRC 122
+#define RK3288_SCLK_PVTM_CORE 123
+#define RK3288_SCLK_PVTM_GPU 124
+#define RK3288_SCLK_CRYPTO 125
+#define RK3288_SCLK_MIPIDSI_24M 126
+#define RK3288_SCLK_VIP_OUT 127
+#define RK3288_SCLK_MAC 151
+#define RK3288_SCLK_MACREF_OUT 152
+#define RK3288_DCLK_VOP0 190
+#define RK3288_DCLK_VOP1 191
+#define RK3288_ACLK_GPU 192
+#define RK3288_ACLK_DMAC1 193
+#define RK3288_ACLK_DMAC2 194
+#define RK3288_ACLK_MMU 195
+#define RK3288_ACLK_GMAC 196
+#define RK3288_ACLK_VOP0 197
+#define RK3288_ACLK_VOP1 198
+#define RK3288_ACLK_CRYPTO 199
+#define RK3288_ACLK_RGA 200
+#define RK3288_ACLK_RGA_NIU 201
+#define RK3288_ACLK_IEP 202
+#define RK3288_ACLK_VIO0_NIU 203
+#define RK3288_ACLK_VIP 204
+#define RK3288_ACLK_ISP 205
+#define RK3288_ACLK_VIO1_NIU 206
+#define RK3288_ACLK_HEVC 207
+#define RK3288_ACLK_VCODEC 208
+#define RK3288_ACLK_CPU 209
+#define RK3288_ACLK_PERI 210
+#define RK3288_PCLK_GPIO0 320
+#define RK3288_PCLK_GPIO1 321
+#define RK3288_PCLK_GPIO2 322
+#define RK3288_PCLK_GPIO3 323
+#define RK3288_PCLK_GPIO4 324
+#define RK3288_PCLK_GPIO5 325
+#define RK3288_PCLK_GPIO6 326
+#define RK3288_PCLK_GPIO7 327
+#define RK3288_PCLK_GPIO8 328
+#define RK3288_PCLK_GRF 329
+#define RK3288_PCLK_SGRF 330
+#define RK3288_PCLK_PMU 331
+#define RK3288_PCLK_I2C0 332
+#define RK3288_PCLK_I2C1 333
+#define RK3288_PCLK_I2C2 334
+#define RK3288_PCLK_I2C3 335
+#define RK3288_PCLK_I2C4 336
+#define RK3288_PCLK_I2C5 337
+#define RK3288_PCLK_SPI0 338
+#define RK3288_PCLK_SPI1 339
+#define RK3288_PCLK_SPI2 340
+#define RK3288_PCLK_UART0 341
+#define RK3288_PCLK_UART1 342
+#define RK3288_PCLK_UART2 343
+#define RK3288_PCLK_UART3 344
+#define RK3288_PCLK_UART4 345
+#define RK3288_PCLK_TSADC 346
+#define RK3288_PCLK_SARADC 347
+#define RK3288_PCLK_SIM 348
+#define RK3288_PCLK_GMAC 349
+#define RK3288_PCLK_PWM 350
+#define RK3288_PCLK_RKPWM 351
+#define RK3288_PCLK_PS2C 352
+#define RK3288_PCLK_TIMER 353
+#define RK3288_PCLK_TZPC 354
+#define RK3288_PCLK_EDP_CTRL 355
+#define RK3288_PCLK_MIPI_DSI0 356
+#define RK3288_PCLK_MIPI_DSI1 357
+#define RK3288_PCLK_MIPI_CSI 358
+#define RK3288_PCLK_LVDS_PHY 359
+#define RK3288_PCLK_HDMI_CTRL 360
+#define RK3288_PCLK_VIO2_H2P 361
+#define RK3288_PCLK_CPU 362
+#define RK3288_PCLK_PERI 363
+#define RK3288_PCLK_DDRUPCTL0 364
+#define RK3288_PCLK_PUBL0 365
+#define RK3288_PCLK_DDRUPCTL1 366
+#define RK3288_PCLK_PUBL1 367
+#define RK3288_PCLK_WDT 368
+#define RK3288_PCLK_EFUSE256 369
+#define RK3288_PCLK_EFUSE1024 370
+#define RK3288_PCLK_ISP_IN 371
+#define RK3288_HCLK_GPS 448
+#define RK3288_HCLK_OTG0 449
+#define RK3288_HCLK_USBHOST0 450
+#define RK3288_HCLK_USBHOST1 451
+#define RK3288_HCLK_HSIC 452
+#define RK3288_HCLK_NANDC0 453
+#define RK3288_HCLK_NANDC1 454
+#define RK3288_HCLK_TSP 455
+#define RK3288_HCLK_SDMMC 456
+#define RK3288_HCLK_SDIO0 457
+#define RK3288_HCLK_SDIO1 458
+#define RK3288_HCLK_EMMC 459
+#define RK3288_HCLK_HSADC 460
+#define RK3288_HCLK_CRYPTO 461
+#define RK3288_HCLK_I2S0 462
+#define RK3288_HCLK_SPDIF 463
+#define RK3288_HCLK_SPDIF8CH 464
+#define RK3288_HCLK_VOP0 465
+#define RK3288_HCLK_VOP1 466
+#define RK3288_HCLK_ROM 467
+#define RK3288_HCLK_IEP 468
+#define RK3288_HCLK_ISP 469
+#define RK3288_HCLK_RGA 470
+#define RK3288_HCLK_VIO_AHB_ARBI 471
+#define RK3288_HCLK_VIO_NIU 472
+#define RK3288_HCLK_VIP 473
+#define RK3288_HCLK_VIO2_H2P 474
+#define RK3288_HCLK_HEVC 475
+#define RK3288_HCLK_VCODEC 476
+#define RK3288_HCLK_CPU 477
+#define RK3288_HCLK_PERI 478
+
+#endif /* !_RK3328_CRU_H */
Index: src/sys/arch/arm/rockchip/rk3288_iomux.c
diff -u /dev/null src/sys/arch/arm/rockchip/rk3288_iomux.c:1.1
--- /dev/null Fri Nov 12 22:02:08 2021
+++ src/sys/arch/arm/rockchip/rk3288_iomux.c Fri Nov 12 22:02:08 2021
@@ -0,0 +1,367 @@
+/* $NetBSD: rk3288_iomux.c,v 1.1 2021/11/12 22:02:08 jmcneill Exp $ */
+
+/*-
+ * Copyright (c) 2018 Jared McNeill <[email protected]>
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
+ * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
+ * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
+ * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
+ * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
+ * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
+ * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED
+ * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
+ * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ */
+
+#include <sys/cdefs.h>
+__KERNEL_RCSID(0, "$NetBSD: rk3288_iomux.c,v 1.1 2021/11/12 22:02:08 jmcneill Exp $");
+
+#include <sys/param.h>
+#include <sys/bus.h>
+#include <sys/device.h>
+#include <sys/intr.h>
+#include <sys/systm.h>
+#include <sys/mutex.h>
+#include <sys/kmem.h>
+#include <sys/lwp.h>
+
+#include <dev/fdt/fdtvar.h>
+#include <dev/fdt/syscon.h>
+
+#define GPIO_P_CTL_Z 0
+#define GPIO_P_CTL_PULLUP 1
+#define GPIO_P_CTL_PULLDOWN 2
+#define GPIO_P_CTL_MASK 0x3U
+
+#define GPIO_E_CTL_2MA 0
+#define GPIO_E_CTL_4MA 1
+#define GPIO_E_CTL_8MA 2
+#define GPIO_E_CTL_12MA 3
+#define GPIO_E_CTL_MASK 0x3U
+
+static const struct device_compatible_entry compat_data[] = {
+ { .compat = "rockchip,rk3288-pinctrl" },
+ DEVICE_COMPAT_EOL
+};
+
+struct rk3288_iomux_softc {
+ device_t sc_dev;
+ struct syscon *sc_grf;
+ struct syscon *sc_pmu;
+};
+
+struct rk3288_iomux_reg {
+ struct syscon *syscon;
+ int mux_reg;
+ uint32_t mux_bit;
+ int pull_reg;
+ uint32_t pull_bit;
+ int drv_reg;
+ uint32_t drv_bit;
+ uint32_t flags;
+#define IOMUX_NOROUTE __BIT(0)
+#define IOMUX_4BIT __BIT(1)
+};
+
+#define LOCK(reg) \
+ syscon_lock((reg)->syscon)
+#define UNLOCK(reg) \
+ syscon_unlock((reg)->syscon)
+#define RD4(reg, off) \
+ syscon_read_4((reg)->syscon, (off))
+#define WR4(reg, off, val) \
+ syscon_write_4((reg)->syscon, (off), (val))
+
+static int rk3288_iomux_match(device_t, cfdata_t, void *);
+static void rk3288_iomux_attach(device_t, device_t, void *);
+
+CFATTACH_DECL_NEW(rk3288_iomux, sizeof(struct rk3288_iomux_softc),
+ rk3288_iomux_match, rk3288_iomux_attach, NULL, NULL);
+
+#define NBANKS 9
+#define NPINSPERBANK 32
+
+static uint32_t rk3288_iomux_flags[NBANKS][NPINSPERBANK / 8] = {
+ [0] = { 0, 0, 0, IOMUX_NOROUTE },
+ [1] = { IOMUX_NOROUTE, IOMUX_NOROUTE, IOMUX_NOROUTE, 0 },
+ [2] = { 0, 0, 0, IOMUX_NOROUTE },
+ [3] = { 0, 0, 0, IOMUX_4BIT },
+ [4] = { IOMUX_4BIT, IOMUX_4BIT, 0, 0 },
+ [5] = { IOMUX_NOROUTE, 0, 0, IOMUX_NOROUTE },
+ [6] = { 0, 0, 0, IOMUX_NOROUTE },
+ [7] = { 0, 0, IOMUX_4BIT, IOMUX_NOROUTE },
+ [8] = { 0, 0, IOMUX_NOROUTE, IOMUX_NOROUTE }
+};
+
+static int rk3288_iomux_offset[NBANKS][NPINSPERBANK / 8] = {
+ /* PMU offsets */
+ [0] = { 0x84, 0x88, 0x8c, -1 },
+ /* GRF offsets */
+ [1] = { -1, -1, -1, 0x0c },
+ [2] = { 0x10, 0x14, 0x18, -1 },
+ [3] = { 0x20, 0x24, 0x28, 0x2c },
+ [4] = { 0x34, 0x3c, 0x44, 0x48 },
+ [5] = { -1, 0x50, 0x54, -1 },
+ [6] = { 0x5c, 0x60, 0x64, -1 },
+ [7] = { 0x6c, 0x70, 0x74, -1 },
+ [8] = { 0x80, 0x84, -1, -1 },
+};
+
+static bool
+rk3288_iomux_get_reg(struct rk3288_iomux_softc *sc, u_int bank, u_int idx,
+ struct rk3288_iomux_reg *reg)
+{
+ if (bank >= NBANKS || idx >= NPINSPERBANK) {
+ return false;
+ }
+
+ if (bank == 0) {
+ reg->syscon = sc->sc_pmu;
+ reg->pull_reg = 0x64 + (idx / 8) * 4;
+ reg->pull_bit = idx % 8 * 2;
+ reg->drv_reg = 0x70 + (idx / 8) * 4;
+ reg->drv_bit = idx % 8 * 2;
+ } else {
+ reg->syscon = sc->sc_grf;
+ reg->pull_reg = 0x130 + (bank * 0x10) + (idx / 8) * 4;
+ reg->pull_bit = idx % 8 * 2;
+ reg->drv_reg = 0x1b0 + (bank * 0x10) + (idx / 8) * 4;
+ reg->drv_bit = idx % 8 * 2;
+ }
+ reg->flags = rk3288_iomux_flags[bank][idx / 8];
+ reg->mux_reg = rk3288_iomux_offset[bank][idx / 8];
+ if (reg->mux_reg != -1) {
+ if ((reg->flags & IOMUX_4BIT) == 0) {
+ reg->mux_bit = idx % 8 * 2;
+ } else {
+ reg->mux_bit = idx % 4 * 4;
+ if ((idx % 8) >= 4) {
+ reg->mux_reg += 0x4;
+ }
+ }
+ }
+
+ return true;
+}
+
+static void
+rk3288_iomux_set_bias(struct rk3288_iomux_softc *sc, struct rk3288_iomux_reg *reg,
+ int bias)
+{
+ uint32_t val;
+ u_int p;
+
+ switch (bias) {
+ case 0:
+ p = GPIO_P_CTL_Z;
+ break;
+ case GPIO_PIN_PULLUP:
+ p = GPIO_P_CTL_PULLUP;
+ break;
+ case GPIO_PIN_PULLDOWN:
+ p = GPIO_P_CTL_PULLDOWN;
+ break;
+ default:
+ return;
+ }
+
+ val = GPIO_P_CTL_MASK << (reg->pull_bit + 16);
+ val |= p << reg->pull_bit;
+
+#ifdef RK3288_IOMUX_DEBUG
+ const uint32_t oval = RD4(reg, reg->pull_reg);
+ printf("%s: wr %#x -> %#x (%#x)\n", __func__,
+ oval & (GPIO_P_CTL_MASK << reg->pull_bit),
+ val & 0xffff,
+ GPIO_P_CTL_MASK << reg->pull_bit);
+#endif
+
+ WR4(reg, reg->pull_reg, val);
+}
+
+static void
+rk3288_iomux_set_drive_strength(struct rk3288_iomux_softc *sc,
+ struct rk3288_iomux_reg *reg, int drv)
+{
+ uint32_t val;
+ u_int e;
+
+ switch (drv) {
+ case 2:
+ e = GPIO_E_CTL_2MA;
+ break;
+ case 4:
+ e = GPIO_E_CTL_4MA;
+ break;
+ case 8:
+ e = GPIO_E_CTL_8MA;
+ break;
+ case 12:
+ e = GPIO_E_CTL_12MA;
+ break;
+ default:
+ return;
+ }
+
+ val = GPIO_E_CTL_MASK << (reg->drv_bit + 16);
+ val |= e << reg->drv_bit;
+ WR4(reg, reg->drv_reg, val);
+}
+
+static void
+rk3288_iomux_set_mux(struct rk3288_iomux_softc *sc,
+ struct rk3288_iomux_reg *reg, u_int mux)
+{
+ uint32_t val;
+
+ KASSERT(reg->mux_reg != -1);
+
+ val = ((reg->flags & IOMUX_4BIT) ? 0xf : 0x3) << (reg->mux_bit + 16);
+ val |= mux << reg->mux_bit;
+
+ WR4(reg, reg->mux_reg, val);
+}
+
+static void
+rk3288_iomux_config(struct rk3288_iomux_softc *sc, struct rk3288_iomux_reg *reg,
+ u_int mux, const int phandle)
+{
+ int bias, drv;
+
+ bias = fdtbus_pinctrl_parse_bias(phandle, NULL);
+ drv = fdtbus_pinctrl_parse_drive_strength(phandle);
+
+#ifdef RK3288_IOMUX_DEBUG
+ printf(" -> %s mux %#x/%d, pull %#x/%d, drv %#x/%d, flags %#x\n",
+ reg->syscon == sc->sc_pmu ? "pmu" : "grf",
+ reg->mux_reg, reg->mux_bit,
+ reg->pull_reg, reg->pull_bit,
+ reg->drv_reg, reg->drv_bit,
+ reg->flags);
+ printf(" bias %d drv %d mux %u\n", bias, drv, mux);
+#endif
+
+ /* XXX
+ * ASUS Tinkerboard goes nuts if we update any PMU bias fields.
+ * Skip them until we figure out why.
+ */
+ if (reg->syscon == sc->sc_pmu) {
+ bias = -1;
+ }
+
+ LOCK(reg);
+
+ if (bias != -1) {
+ rk3288_iomux_set_bias(sc, reg, bias);
+ }
+ if (drv != -1) {
+ rk3288_iomux_set_drive_strength(sc, reg, drv);
+ }
+ if ((reg->flags & IOMUX_NOROUTE) == 0) {
+ rk3288_iomux_set_mux(sc, reg, mux);
+ }
+
+ UNLOCK(reg);
+}
+
+static int
+rk3288_iomux_pinctrl_set_config(device_t dev, const void *data, size_t len)
+{
+ struct rk3288_iomux_softc * const sc = device_private(dev);
+ int pins_len = 0;
+
+ if (len != 4) {
+ return -1;
+ }
+
+ const int phandle = fdtbus_get_phandle_from_native(be32dec(data));
+ const u_int *pins = fdtbus_get_prop(phandle, "rockchip,pins", &pins_len);
+
+ while (pins_len >= 16) {
+ const u_int bank = be32toh(pins[0]);
+ const u_int idx = be32toh(pins[1]);
+ const u_int mux = be32toh(pins[2]);
+ const int cfg = fdtbus_get_phandle_from_native(be32toh(pins[3]));
+ struct rk3288_iomux_reg regdef = {};
+
+ if (rk3288_iomux_get_reg(sc, bank, idx, ®def)) {
+#ifdef RK3288_IOMUX_DEBUG
+ printf(" -> gpio%u P%c%u (%u)\n", bank, 'A' + (idx / 8), idx % 8, idx);
+#endif
+ rk3288_iomux_config(sc, ®def, mux, cfg);
+ } else {
+ aprint_error_dev(dev, "unsupported iomux bank %u idx %u\n",
+ bank, mux);
+ }
+
+ pins_len -= 16;
+ pins += 4;
+ }
+
+ return 0;
+}
+
+static struct fdtbus_pinctrl_controller_func rk3288_iomux_pinctrl_funcs = {
+ .set_config = rk3288_iomux_pinctrl_set_config,
+};
+
+static int
+rk3288_iomux_match(device_t parent, cfdata_t cf, void *aux)
+{
+ struct fdt_attach_args * const faa = aux;
+
+ return of_compatible_match(faa->faa_phandle, compat_data);
+}
+
+static void
+rk3288_iomux_attach(device_t parent, device_t self, void *aux)
+{
+ struct rk3288_iomux_softc * const sc = device_private(self);
+ struct fdt_attach_args * const faa = aux;
+ const int phandle = faa->faa_phandle;
+
+ sc->sc_dev = self;
+ sc->sc_grf = fdtbus_syscon_acquire(phandle, "rockchip,grf");
+ if (sc->sc_grf == NULL) {
+ aprint_error(": couldn't acquire grf syscon\n");
+ return;
+ }
+ sc->sc_pmu = fdtbus_syscon_acquire(phandle, "rockchip,pmu");
+ if (sc->sc_pmu == NULL) {
+ aprint_error(": couldn't acquire pmu syscon\n");
+ return;
+ }
+
+ aprint_naive("\n");
+ aprint_normal(": RK3288 IOMUX control\n");
+
+ for (int child = OF_child(phandle); child; child = OF_peer(child)) {
+ for (int sub = OF_child(child); sub; sub = OF_peer(sub)) {
+ if (!of_hasprop(sub, "rockchip,pins"))
+ continue;
+ fdtbus_register_pinctrl_config(self, sub, &rk3288_iomux_pinctrl_funcs);
+ }
+ }
+
+ for (int child = OF_child(phandle); child; child = OF_peer(child)) {
+ struct fdt_attach_args cfaa = *faa;
+ cfaa.faa_phandle = child;
+ cfaa.faa_name = fdtbus_get_string(child, "name");
+ cfaa.faa_quiet = false;
+
+ config_found(self, &cfaa, NULL, CFARGS_NONE);
+ }
+}
Index: src/sys/arch/arm/rockchip/rk3288_platform.h
diff -u /dev/null src/sys/arch/arm/rockchip/rk3288_platform.h:1.1
--- /dev/null Fri Nov 12 22:02:08 2021
+++ src/sys/arch/arm/rockchip/rk3288_platform.h Fri Nov 12 22:02:08 2021
@@ -0,0 +1,40 @@
+/* $NetBSD: rk3288_platform.h,v 1.1 2021/11/12 22:02:08 jmcneill Exp $ */
+
+/*-
+ * Copyright (c) 2021 Jared McNeill <[email protected]>
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
+ * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
+ * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
+ * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
+ * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
+ * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
+ * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED
+ * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
+ * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ */
+
+#ifndef _ARM_RK3288_PLATFORM_H
+#define _ARM_RK3288_PLATFORM_H
+
+#include <arch/evbarm/fdt/platform.h>
+
+#define RK3288_CORE_VBASE KERNEL_IO_VBASE
+#define RK3288_CORE_PBASE 0xff000000
+#define RK3288_CORE_SIZE 0x01000000
+
+#define RK3288_UART_FREQ 24000000
+
+#endif /* _ARM_RK3288_PLATFORM_H */
Index: src/sys/arch/arm/rockchip/rk3288_usb.c
diff -u /dev/null src/sys/arch/arm/rockchip/rk3288_usb.c:1.1
--- /dev/null Fri Nov 12 22:02:08 2021
+++ src/sys/arch/arm/rockchip/rk3288_usb.c Fri Nov 12 22:02:08 2021
@@ -0,0 +1,183 @@
+/* $NetBSD: rk3288_usb.c,v 1.1 2021/11/12 22:02:08 jmcneill Exp $ */
+
+/*-
+ * Copyright (c) 2021 Jared McNeill <[email protected]>
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE NETBSD FOUNDATION, INC. AND CONTRIBUTORS
+ * ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED
+ * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
+ * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE FOUNDATION OR CONTRIBUTORS
+ * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+ * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+ * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+ * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
+ * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+ * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
+ * POSSIBILITY OF SUCH DAMAGE.
+ */
+
+#include <sys/cdefs.h>
+
+__KERNEL_RCSID(0, "$NetBSD: rk3288_usb.c,v 1.1 2021/11/12 22:02:08 jmcneill Exp $");
+
+#include <sys/param.h>
+#include <sys/bus.h>
+#include <sys/device.h>
+#include <sys/intr.h>
+#include <sys/systm.h>
+#include <sys/time.h>
+#include <sys/kmem.h>
+
+#include <dev/fdt/fdtvar.h>
+#include <dev/fdt/syscon.h>
+
+#define GRF_UOCn_CON0_SIDDQ __BIT(13)
+
+static int rk3288_usb_match(device_t, cfdata_t, void *);
+static void rk3288_usb_attach(device_t, device_t, void *);
+
+static const struct device_compatible_entry compat_data[] = {
+ { .compat = "rockchip,rk3288-usb-phy" },
+ DEVICE_COMPAT_EOL
+};
+
+CFATTACH_DECL_NEW(rk3288_usb, 0,
+ rk3288_usb_match, rk3288_usb_attach, NULL, NULL);
+
+static int
+rk3288_usb_match(device_t parent, cfdata_t cf, void *aux)
+{
+ struct fdt_attach_args * const faa = aux;
+
+ return of_compatible_match(faa->faa_phandle, compat_data);
+}
+
+static void
+rk3288_usb_attach(device_t parent, device_t self, void *aux)
+{
+ struct fdt_attach_args * const faa = aux;
+ const int phandle = faa->faa_phandle;
+ int child;
+
+ aprint_naive("\n");
+ aprint_normal(": USB PHY\n");
+
+ for (child = OF_child(phandle); child; child = OF_peer(child)) {
+ if (!fdtbus_status_okay(child))
+ continue;
+
+ struct fdt_attach_args cfaa = *faa;
+ cfaa.faa_phandle = child;
+ cfaa.faa_name = fdtbus_get_string(child, "name");
+ cfaa.faa_quiet = false;
+
+ config_found(self, &cfaa, NULL, CFARGS_NONE);
+ }
+}
+
+/*
+ * USB PHY
+ */
+
+static int rk3288_usbphy_match(device_t, cfdata_t, void *);
+static void rk3288_usbphy_attach(device_t, device_t, void *);
+
+struct rk3288_usbphy_softc {
+ device_t sc_dev;
+ int sc_phandle;
+ struct syscon *sc_syscon;
+ bus_addr_t sc_reg;
+};
+
+CFATTACH_DECL_NEW(rk3288_usbphy, sizeof(struct rk3288_usbphy_softc),
+ rk3288_usbphy_match, rk3288_usbphy_attach, NULL, NULL);
+
+static void *
+rk3288_usbphy_acquire(device_t dev, const void *data, size_t len)
+{
+ struct rk3288_usbphy_softc * const sc = device_private(dev);
+
+ if (len != 0)
+ return NULL;
+
+ return sc;
+}
+
+static void
+rk3288_usbphy_release(device_t dev, void *priv)
+{
+}
+
+static int
+rk3288_usbphy_enable(device_t dev, void *priv, bool enable)
+{
+ struct rk3288_usbphy_softc * const sc = device_private(dev);
+ uint32_t write_mask, write_val;
+
+ write_mask = GRF_UOCn_CON0_SIDDQ << 16;
+ write_val = enable ? 0 : GRF_UOCn_CON0_SIDDQ;
+
+ syscon_lock(sc->sc_syscon);
+ syscon_write_4(sc->sc_syscon, sc->sc_reg, write_mask | write_val);
+ syscon_unlock(sc->sc_syscon);
+
+ return 0;
+}
+
+const struct fdtbus_phy_controller_func rk3288_usbphy_funcs = {
+ .acquire = rk3288_usbphy_acquire,
+ .release = rk3288_usbphy_release,
+ .enable = rk3288_usbphy_enable,
+};
+
+static int
+rk3288_usbphy_match(device_t parent, cfdata_t cf, void *aux)
+{
+ return 1;
+}
+
+static void
+rk3288_usbphy_attach(device_t parent, device_t self, void *aux)
+{
+ struct rk3288_usbphy_softc * const sc = device_private(self);
+ struct fdt_attach_args * const faa = aux;
+ const int phandle = faa->faa_phandle;
+ struct fdtbus_reset *rst;
+
+ sc->sc_dev = self;
+ sc->sc_phandle = phandle;
+ sc->sc_syscon = fdtbus_syscon_lookup(OF_parent(OF_parent(phandle)));
+ if (sc->sc_syscon == NULL) {
+ aprint_error(": couldn't find syscon\n");
+ return;
+ }
+ if (fdtbus_get_reg(phandle, 0, &sc->sc_reg, NULL) != 0) {
+ aprint_error(": couldn't find registers\n");
+ return;
+ }
+
+ rst = fdtbus_reset_get(phandle, "phy-reset");
+ if (rst == NULL || fdtbus_reset_deassert(rst) != 0) {
+ aprint_error(": couldn't de-assert reset\n");
+ return;
+ }
+ if (fdtbus_clock_enable(phandle, "phyclk", true) != 0) {
+ aprint_error(": couildn't enable clock\n");
+ return;
+ }
+
+ aprint_naive("\n");
+ aprint_normal(": USB port\n");
+
+ fdtbus_register_phy_controller(self, phandle, &rk3288_usbphy_funcs);
+}