Module Name: src
Committed By: jmcneill
Date: Mon Feb 25 19:30:17 UTC 2019
Modified Files:
src/sys/arch/arm/amlogic: files.meson meson8b_clkc.c meson_clk.c
meson_clk.h meson_clk_div.c meson_clk_gate.c meson_clk_mpll.c
meson_clk_mux.c meson_clk_pll.c meson_dwmac.c meson_pinctrl.c
meson_pinctrl.h meson_platform.c meson_resets.c meson_usbphy.c
src/sys/arch/evbarm/conf: GENERIC GENERIC64 files.generic64
src/sys/external/gpl2/dts/dist/arch/arm64/boot/dts/amlogic:
meson-gxbb.dtsi
Added Files:
src/sys/arch/arm/amlogic: mesongx_mmc.c mesongxbb_aoclkc.c
mesongxbb_aoclkc.h mesongxbb_clkc.c mesongxbb_clkc.h
mesongxbb_pinctrl.c
Log Message:
Add support for Amlogic S905 (Meson GXBB) SoCs.
To generate a diff of this commit:
cvs rdiff -u -r1.4 -r1.5 src/sys/arch/arm/amlogic/files.meson \
src/sys/arch/arm/amlogic/meson_platform.c
cvs rdiff -u -r1.2 -r1.3 src/sys/arch/arm/amlogic/meson8b_clkc.c \
src/sys/arch/arm/amlogic/meson_clk.h \
src/sys/arch/arm/amlogic/meson_clk_div.c \
src/sys/arch/arm/amlogic/meson_dwmac.c \
src/sys/arch/arm/amlogic/meson_pinctrl.c
cvs rdiff -u -r1.1 -r1.2 src/sys/arch/arm/amlogic/meson_clk.c \
src/sys/arch/arm/amlogic/meson_clk_gate.c \
src/sys/arch/arm/amlogic/meson_clk_mpll.c \
src/sys/arch/arm/amlogic/meson_clk_mux.c \
src/sys/arch/arm/amlogic/meson_clk_pll.c \
src/sys/arch/arm/amlogic/meson_pinctrl.h \
src/sys/arch/arm/amlogic/meson_resets.c \
src/sys/arch/arm/amlogic/meson_usbphy.c
cvs rdiff -u -r0 -r1.1 src/sys/arch/arm/amlogic/mesongx_mmc.c \
src/sys/arch/arm/amlogic/mesongxbb_aoclkc.c \
src/sys/arch/arm/amlogic/mesongxbb_aoclkc.h \
src/sys/arch/arm/amlogic/mesongxbb_clkc.c \
src/sys/arch/arm/amlogic/mesongxbb_clkc.h \
src/sys/arch/arm/amlogic/mesongxbb_pinctrl.c
cvs rdiff -u -r1.22 -r1.23 src/sys/arch/evbarm/conf/GENERIC
cvs rdiff -u -r1.79 -r1.80 src/sys/arch/evbarm/conf/GENERIC64
cvs rdiff -u -r1.10 -r1.11 src/sys/arch/evbarm/conf/files.generic64
cvs rdiff -u -r1.1.1.7 -r1.2 \
src/sys/external/gpl2/dts/dist/arch/arm64/boot/dts/amlogic/meson-gxbb.dtsi
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/amlogic/files.meson
diff -u src/sys/arch/arm/amlogic/files.meson:1.4 src/sys/arch/arm/amlogic/files.meson:1.5
--- src/sys/arch/arm/amlogic/files.meson:1.4 Sun Jan 20 17:58:22 2019
+++ src/sys/arch/arm/amlogic/files.meson Mon Feb 25 19:30:17 2019
@@ -1,4 +1,4 @@
-# $NetBSD: files.meson,v 1.4 2019/01/20 17:58:22 jmcneill Exp $
+# $NetBSD: files.meson,v 1.5 2019/02/25 19:30:17 jmcneill Exp $
#
# Configuration info for Amlogic Meson family SoCs
#
@@ -22,6 +22,16 @@ device meson8bclkc: meson_clk
attach meson8bclkc at fdt with meson8b_clkc
file arch/arm/amlogic/meson8b_clkc.c meson8b_clkc
+# Meson GXBB clock controller
+device gxbbclkc: meson_clk
+attach gxbbclkc at fdt with mesongxbb_clkc
+file arch/arm/amlogic/mesongxbb_clkc.c mesongxbb_clkc
+
+# Meson GXBB AO clock controller
+device gxbbaoclkc: meson_clk
+attach gxbbaoclkc at fdt with mesongxbb_aoclkc
+file arch/arm/amlogic/mesongxbb_aoclkc.c mesongxbb_aoclkc
+
# Meson reset controller
device mesonresets
attach mesonresets at fdt with meson_resets
@@ -33,7 +43,8 @@ attach mesonuart at fdt with meson_uart
file arch/arm/amlogic/meson_uart.c meson_uart
# Framebuffer console
-attach genfb at fdt with meson_genfb
+device mesonfb
+attach mesonfb at fdt with meson_genfb
file arch/arm/amlogic/meson_genfb.c meson_genfb & soc_meson
# GPIO
@@ -41,17 +52,23 @@ device mesonpinctrl: gpiobus
attach mesonpinctrl at fdt with meson_pinctrl
file arch/arm/amlogic/meson_pinctrl.c meson_pinctrl
file arch/arm/amlogic/meson8b_pinctrl.c meson_pinctrl & soc_meson8b
+file arch/arm/amlogic/mesongxbb_pinctrl.c meson_pinctrl & soc_mesongxbb
-# SDHC
+# Meson8b SDHC
device mesonsdhc: sdmmcbus
attach mesonsdhc at fdt with meson_sdhc
file arch/arm/amlogic/meson_sdhc.c meson_sdhc
-# SDIO
+# Meson8b SDIO
device mesonsdio: sdmmcbus
attach mesonsdio at fdt with meson_sdio
file arch/arm/amlogic/meson_sdio.c meson_sdio
+# Meson GX MMC
+device mesongxmmc: sdmmcbus
+attach mesongxmmc at fdt with mesongx_mmc
+file arch/arm/amlogic/mesongx_mmc.c mesongx_mmc
+
# USB PHY
device mesonusbphy
attach mesonusbphy at fdt with meson_usbphy
@@ -79,3 +96,4 @@ file arch/arm/amlogic/meson_wdt.c meson
# SOC parameters
defflag opt_soc.h SOC_MESON
defflag opt_soc.h SOC_MESON8B: SOC_MESON
+defflag opt_soc.h SOC_MESONGXBB: SOC_MESON
Index: src/sys/arch/arm/amlogic/meson_platform.c
diff -u src/sys/arch/arm/amlogic/meson_platform.c:1.4 src/sys/arch/arm/amlogic/meson_platform.c:1.5
--- src/sys/arch/arm/amlogic/meson_platform.c:1.4 Thu Jan 31 13:06:10 2019
+++ src/sys/arch/arm/amlogic/meson_platform.c Mon Feb 25 19:30:17 2019
@@ -1,4 +1,4 @@
-/* $NetBSD: meson_platform.c,v 1.4 2019/01/31 13:06:10 skrll Exp $ */
+/* $NetBSD: meson_platform.c,v 1.5 2019/02/25 19:30:17 jmcneill Exp $ */
/*-
* Copyright (c) 2019 Jared McNeill <[email protected]>
@@ -33,7 +33,7 @@
#include "arml2cc.h"
#include <sys/cdefs.h>
-__KERNEL_RCSID(0, "$NetBSD: meson_platform.c,v 1.4 2019/01/31 13:06:10 skrll Exp $");
+__KERNEL_RCSID(0, "$NetBSD: meson_platform.c,v 1.5 2019/02/25 19:30:17 jmcneill Exp $");
#include <sys/param.h>
#include <sys/bus.h>
@@ -50,6 +50,7 @@ __KERNEL_RCSID(0, "$NetBSD: meson_platfo
#include <arm/cpufunc.h>
#include <arm/cortex/a9tmr_var.h>
+#include <arm/cortex/gtmr_var.h>
#include <arm/cortex/pl310_var.h>
#include <arm/cortex/scu_reg.h>
@@ -64,7 +65,7 @@ __KERNEL_RCSID(0, "$NetBSD: meson_platfo
#define MESON_CORE_APB3_VBASE KERNEL_IO_VBASE
#define MESON_CORE_APB3_PBASE 0xc0000000
-#define MESON_CORE_APB3_SIZE 0x01300000
+#define MESON_CORE_APB3_SIZE 0x01400000
#define MESON_CBUS_OFFSET 0x01100000
@@ -84,8 +85,8 @@ __KERNEL_RCSID(0, "$NetBSD: meson_platfo
#define MESON8B_ARM_SCU_BASE 0x00100000
#define MESON8B_AOBUS_VBASE (MESON8B_ARM_VBASE + MESON8B_ARM_SIZE)
-#define MESON8B_AOBUS_PBASE 0xc8100000
-#define MESON8B_AOBUS_SIZE 0x00100000
+#define MESON8B_AOBUS_PBASE 0xc8000000
+#define MESON8B_AOBUS_SIZE 0x00200000
#define MESON_AOBUS_PWR_CTRL0_REG 0xe0
#define MESON_AOBUS_PWR_CTRL1_REG 0xe4
@@ -96,7 +97,7 @@ __KERNEL_RCSID(0, "$NetBSD: meson_platfo
#define MESON8B_SRAM_VBASE (MESON8B_AOBUS_VBASE + MESON8B_AOBUS_SIZE)
#define MESON8B_SRAM_PBASE 0xd9000000
-#define MESON8B_SRAM_SIZE 0x00010000 /* 0x10000 rounded up */
+#define MESON8B_SRAM_SIZE 0x00200000 /* 0x10000 rounded up */
#define MESON8B_SRAM_CPUCONF_OFFSET 0x1ff80
#define MESON8B_SRAM_CPUCONF_CTRL_REG 0x00
@@ -183,7 +184,7 @@ meson_platform_device_register(device_t
}
}
- if (device_is_a(self, "genfb")) {
+ if (device_is_a(self, "mesonfb")) {
int scale, depth;
if (get_bootconf_option(boot_args, "fb.scale",
@@ -312,7 +313,7 @@ meson_platform_reset(void)
}
}
-#if defined(MULTIPROCESSOR)
+#if defined(SOC_MESON8B)
static void
meson8b_mpinit_delay(u_int n)
{
@@ -395,13 +396,11 @@ cpu_enable_meson8b(int phandle)
}
ARM_CPU_METHOD(meson8b, "amlogic,meson8b-smp", cpu_enable_meson8b);
-#endif
static int
-meson_mpstart(void)
+meson8b_mpstart(void)
{
int ret = 0;
-#ifdef MULTIPROCESSOR
const bus_addr_t cbar = armreg_cbar_read();
bus_space_tag_t bst = &arm_generic_bs_tag;
@@ -429,12 +428,9 @@ meson_mpstart(void)
armv7_dcache_wbinv_all();
ret = arm_fdt_cpu_mpstart();
-#endif
return ret;
}
-
-#if defined(SOC_MESON8B)
static const struct arm_platform meson8b_platform = {
.ap_devmap = meson_platform_devmap,
.ap_bootstrap = meson8b_platform_bootstrap,
@@ -443,8 +439,23 @@ static const struct arm_platform meson8b
.ap_reset = meson_platform_reset,
.ap_delay = a9tmr_delay,
.ap_uart_freq = meson_platform_uart_freq,
- .ap_mpstart = meson_mpstart,
+ .ap_mpstart = meson8b_mpstart,
};
ARM_PLATFORM(meson8b, "amlogic,meson8b", &meson8b_platform);
+#endif /* SOC_MESON8B */
+
+#if defined(SOC_MESONGXBB)
+static const struct arm_platform mesongxbb_platform = {
+ .ap_devmap = meson_platform_devmap,
+ .ap_bootstrap = meson_platform_bootstrap,
+ .ap_init_attach_args = meson_platform_init_attach_args,
+ .ap_device_register = meson_platform_device_register,
+ .ap_reset = meson_platform_reset,
+ .ap_delay = gtmr_delay,
+ .ap_uart_freq = meson_platform_uart_freq,
+ .ap_mpstart = arm_fdt_cpu_mpstart,
+};
+
+ARM_PLATFORM(mesongxbb, "amlogic,meson-gxbb", &mesongxbb_platform);
#endif
Index: src/sys/arch/arm/amlogic/meson8b_clkc.c
diff -u src/sys/arch/arm/amlogic/meson8b_clkc.c:1.2 src/sys/arch/arm/amlogic/meson8b_clkc.c:1.3
--- src/sys/arch/arm/amlogic/meson8b_clkc.c:1.2 Sun Jan 20 17:28:34 2019
+++ src/sys/arch/arm/amlogic/meson8b_clkc.c Mon Feb 25 19:30:17 2019
@@ -1,4 +1,4 @@
-/* $NetBSD: meson8b_clkc.c,v 1.2 2019/01/20 17:28:34 jmcneill Exp $ */
+/* $NetBSD: meson8b_clkc.c,v 1.3 2019/02/25 19:30:17 jmcneill Exp $ */
/*-
* Copyright (c) 2019 Jared McNeill <[email protected]>
@@ -28,7 +28,7 @@
#include <sys/cdefs.h>
-__KERNEL_RCSID(1, "$NetBSD: meson8b_clkc.c,v 1.2 2019/01/20 17:28:34 jmcneill Exp $");
+__KERNEL_RCSID(1, "$NetBSD: meson8b_clkc.c,v 1.3 2019/02/25 19:30:17 jmcneill Exp $");
#include <sys/param.h>
#include <sys/bus.h>
@@ -99,6 +99,7 @@ meson8b_clkc_pll_sys_set_rate(struct mes
struct meson_clk_clk *clk, u_int rate)
{
struct clk *clkp, *clkp_parent;
+ int error;
KASSERT(clk->type == MESON_CLK_PLL);
@@ -115,6 +116,8 @@ meson8b_clkc_pll_sys_set_rate(struct mes
if (parent_rate == 0)
return EIO;
+ CLK_LOCK(sc);
+
uint32_t cntl0 = CLK_READ(sc, HHI_SYS_CPU_CLK_CNTL0);
uint32_t cntl = CLK_READ(sc, HHI_SYS_PLL_CNTL);
@@ -130,12 +133,18 @@ meson8b_clkc_pll_sys_set_rate(struct mes
new_mul *= 2;
}
- if ((cntl0 & HHI_SYS_CPU_CLK_CNTL0_CLKSEL) == 0)
- return EIO;
- if (__SHIFTOUT(cntl0, HHI_SYS_CPU_CLK_CNTL0_PLLSEL) != 1)
- return EIO;
- if (__SHIFTOUT(cntl0, HHI_SYS_CPU_CLK_CNTL0_SOUTSEL) != 0)
- return EIO;
+ if ((cntl0 & HHI_SYS_CPU_CLK_CNTL0_CLKSEL) == 0) {
+ error = EIO;
+ goto done;
+ }
+ if (__SHIFTOUT(cntl0, HHI_SYS_CPU_CLK_CNTL0_PLLSEL) != 1) {
+ error = EIO;
+ goto done;
+ }
+ if (__SHIFTOUT(cntl0, HHI_SYS_CPU_CLK_CNTL0_SOUTSEL) != 0) {
+ error = EIO;
+ goto done;
+ }
cntl &= ~HHI_SYS_PLL_CNTL_MUL;
cntl |= __SHIFTIN(new_mul, HHI_SYS_PLL_CNTL_MUL);
@@ -159,7 +168,12 @@ meson8b_clkc_pll_sys_set_rate(struct mes
CLK_WRITE(sc, HHI_SYS_CPU_CLK_CNTL0, cntl0);
} while ((CLK_READ(sc, HHI_SYS_PLL_CNTL) & HHI_SYS_PLL_CNTL_LOCK) == 0);
- return 0;
+ error = 0;
+
+done:
+ CLK_UNLOCK(sc);
+
+ return error;
}
static struct meson_clk_clk meson8b_clkc_clks[] = {
@@ -319,10 +333,20 @@ meson8b_clkc_attach(device_t parent, dev
{
struct meson_clk_softc * const sc = device_private(self);
struct fdt_attach_args * const faa = aux;
+ bus_addr_t addr;
+ bus_size_t size;
sc->sc_dev = self;
sc->sc_phandle = faa->faa_phandle;
sc->sc_bst = faa->faa_bst;
+ if (fdtbus_get_reg(sc->sc_phandle, MESON8B_CLKC_REG_INDEX, &addr, &size) != 0) {
+ aprint_error(": couldn't get registers\n");
+ return;
+ }
+ if (bus_space_map(sc->sc_bst, addr, size, 0, &sc->sc_bsh) != 0) {
+ aprint_error(": couldn't map registers\n");
+ return;
+ }
sc->sc_resets = meson8b_clkc_resets;
sc->sc_nresets = __arraycount(meson8b_clkc_resets);
@@ -330,8 +354,7 @@ meson8b_clkc_attach(device_t parent, dev
sc->sc_clks = meson8b_clkc_clks;
sc->sc_nclks = __arraycount(meson8b_clkc_clks);
- if (meson_clk_attach(sc, MESON8B_CLKC_REG_INDEX) != 0)
- return;
+ meson_clk_attach(sc);
aprint_naive("\n");
aprint_normal(": Meson8b clock controller\n");
Index: src/sys/arch/arm/amlogic/meson_clk.h
diff -u src/sys/arch/arm/amlogic/meson_clk.h:1.2 src/sys/arch/arm/amlogic/meson_clk.h:1.3
--- src/sys/arch/arm/amlogic/meson_clk.h:1.2 Sun Jan 20 17:28:00 2019
+++ src/sys/arch/arm/amlogic/meson_clk.h Mon Feb 25 19:30:17 2019
@@ -1,4 +1,4 @@
-/* $NetBSD: meson_clk.h,v 1.2 2019/01/20 17:28:00 jmcneill Exp $ */
+/* $NetBSD: meson_clk.h,v 1.3 2019/02/25 19:30:17 jmcneill Exp $ */
/*-
* Copyright (c) 2017-2019 Jared McNeill <[email protected]>
@@ -30,6 +30,7 @@
#define _ARM_MESON_CLK_H
#include <dev/clk/clk_backend.h>
+#include <dev/fdt/syscon.h>
struct meson_clk_softc;
struct meson_clk_clk;
@@ -338,9 +339,12 @@ struct meson_clk_clk {
struct meson_clk_softc {
device_t sc_dev;
int sc_phandle;
+
bus_space_tag_t sc_bst;
bus_space_handle_t sc_bsh;
+ struct syscon *sc_syscon;
+
struct clk_domain sc_clkdom;
struct meson_clk_reset *sc_resets;
@@ -350,14 +354,19 @@ struct meson_clk_softc {
u_int sc_nclks;
};
-int meson_clk_attach(struct meson_clk_softc *, u_int);
+void meson_clk_attach(struct meson_clk_softc *);
struct meson_clk_clk *meson_clk_clock_find(struct meson_clk_softc *,
const char *);
void meson_clk_print(struct meson_clk_softc *);
-#define CLK_READ(sc, reg) \
- bus_space_read_4((sc)->sc_bst, (sc)->sc_bsh, (reg))
-#define CLK_WRITE(sc, reg, val) \
- bus_space_write_4((sc)->sc_bst, (sc)->sc_bsh, (reg), (val))
+void meson_clk_lock(struct meson_clk_softc *);
+void meson_clk_unlock(struct meson_clk_softc *);
+uint32_t meson_clk_read(struct meson_clk_softc *, bus_size_t);
+void meson_clk_write(struct meson_clk_softc *, bus_size_t, uint32_t);
+
+#define CLK_LOCK meson_clk_lock
+#define CLK_UNLOCK meson_clk_unlock
+#define CLK_READ meson_clk_read
+#define CLK_WRITE meson_clk_write
#endif /* _ARM_MESON_CLK_H */
Index: src/sys/arch/arm/amlogic/meson_clk_div.c
diff -u src/sys/arch/arm/amlogic/meson_clk_div.c:1.2 src/sys/arch/arm/amlogic/meson_clk_div.c:1.3
--- src/sys/arch/arm/amlogic/meson_clk_div.c:1.2 Sun Jan 20 17:27:30 2019
+++ src/sys/arch/arm/amlogic/meson_clk_div.c Mon Feb 25 19:30:17 2019
@@ -1,4 +1,4 @@
-/* $NetBSD: meson_clk_div.c,v 1.2 2019/01/20 17:27:30 jmcneill Exp $ */
+/* $NetBSD: meson_clk_div.c,v 1.3 2019/02/25 19:30:17 jmcneill Exp $ */
/*-
* Copyright (c) 2017-2019 Jared McNeill <[email protected]>
@@ -27,7 +27,7 @@
*/
#include <sys/cdefs.h>
-__KERNEL_RCSID(0, "$NetBSD: meson_clk_div.c,v 1.2 2019/01/20 17:27:30 jmcneill Exp $");
+__KERNEL_RCSID(0, "$NetBSD: meson_clk_div.c,v 1.3 2019/02/25 19:30:17 jmcneill Exp $");
#include <sys/param.h>
#include <sys/bus.h>
@@ -56,7 +56,10 @@ meson_clk_div_get_rate(struct meson_clk_
if (rate == 0)
return 0;
+ CLK_LOCK(sc);
val = CLK_READ(sc, div->reg);
+ CLK_UNLOCK(sc);
+
if (div->div)
ratio = __SHIFTOUT(val, div->div);
else
@@ -81,7 +84,7 @@ meson_clk_div_set_rate(struct meson_clk_
struct clk *clkp, *clkp_parent;
int parent_rate;
uint32_t val, raw_div;
- int ratio;
+ int ratio, error;
KASSERT(clk->type == MESON_CLK_DIV);
@@ -96,28 +99,41 @@ meson_clk_div_set_rate(struct meson_clk_
if (div->div == 0)
return ENXIO;
+ CLK_LOCK(sc);
+
val = CLK_READ(sc, div->reg);
parent_rate = clk_get_rate(clkp_parent);
- if (parent_rate == 0)
- return (new_rate == 0) ? 0 : ERANGE;
+ if (parent_rate == 0) {
+ error = (new_rate == 0) ? 0 : ERANGE;
+ goto done;
+ }
ratio = howmany(parent_rate, new_rate);
if ((div->flags & MESON_CLK_DIV_POWER_OF_TWO) != 0) {
- return EINVAL;
+ error = EINVAL;
+ goto done;
} else if ((div->flags & MESON_CLK_DIV_CPU_SCALE_TABLE) != 0) {
- return EINVAL;
+ error = EINVAL;
+ goto done;
} else {
raw_div = (ratio > 0) ? ratio - 1 : 0;
}
- if (raw_div > __SHIFTOUT_MASK(div->div))
- return ERANGE;
+ if (raw_div > __SHIFTOUT_MASK(div->div)) {
+ error = ERANGE;
+ goto done;
+ }
val &= ~div->div;
val |= __SHIFTIN(raw_div, div->div);
CLK_WRITE(sc, div->reg, val);
- return 0;
+ error = 0;
+
+done:
+ CLK_UNLOCK(sc);
+
+ return error;
}
const char *
Index: src/sys/arch/arm/amlogic/meson_dwmac.c
diff -u src/sys/arch/arm/amlogic/meson_dwmac.c:1.2 src/sys/arch/arm/amlogic/meson_dwmac.c:1.3
--- src/sys/arch/arm/amlogic/meson_dwmac.c:1.2 Sat Feb 23 17:18:38 2019
+++ src/sys/arch/arm/amlogic/meson_dwmac.c Mon Feb 25 19:30:17 2019
@@ -1,4 +1,4 @@
-/* $NetBSD: meson_dwmac.c,v 1.2 2019/02/23 17:18:38 martin Exp $ */
+/* $NetBSD: meson_dwmac.c,v 1.3 2019/02/25 19:30:17 jmcneill Exp $ */
/*-
* Copyright (c) 2017 Jared McNeill <[email protected]>
@@ -28,7 +28,7 @@
#include <sys/cdefs.h>
-__KERNEL_RCSID(0, "$NetBSD: meson_dwmac.c,v 1.2 2019/02/23 17:18:38 martin Exp $");
+__KERNEL_RCSID(0, "$NetBSD: meson_dwmac.c,v 1.3 2019/02/25 19:30:17 jmcneill Exp $");
#include <sys/param.h>
#include <sys/bus.h>
@@ -53,13 +53,13 @@ __KERNEL_RCSID(0, "$NetBSD: meson_dwmac.
static const char * compatible[] = {
"amlogic,meson8b-dwmac",
+ "amlogic,meson-gx-dwmac",
NULL
};
static int
meson_dwmac_reset(const int phandle)
{
-#if notyet
struct fdtbus_gpio_pin *pin_reset;
const u_int *reset_delay_us;
bool reset_active_low;
@@ -83,7 +83,6 @@ meson_dwmac_reset(const int phandle)
delay(be32toh(reset_delay_us[1]));
fdtbus_gpio_write(pin_reset, val);
delay(be32toh(reset_delay_us[2]));
-#endif
return 0;
}
Index: src/sys/arch/arm/amlogic/meson_pinctrl.c
diff -u src/sys/arch/arm/amlogic/meson_pinctrl.c:1.2 src/sys/arch/arm/amlogic/meson_pinctrl.c:1.3
--- src/sys/arch/arm/amlogic/meson_pinctrl.c:1.2 Wed Jan 23 04:21:54 2019
+++ src/sys/arch/arm/amlogic/meson_pinctrl.c Mon Feb 25 19:30:17 2019
@@ -1,4 +1,4 @@
-/* $NetBSD: meson_pinctrl.c,v 1.2 2019/01/23 04:21:54 thorpej Exp $ */
+/* $NetBSD: meson_pinctrl.c,v 1.3 2019/02/25 19:30:17 jmcneill Exp $ */
/*-
* Copyright (c) 2019 Jared D. McNeill <[email protected]>
@@ -29,7 +29,7 @@
#include "opt_soc.h"
#include <sys/cdefs.h>
-__KERNEL_RCSID(0, "$NetBSD: meson_pinctrl.c,v 1.2 2019/01/23 04:21:54 thorpej Exp $");
+__KERNEL_RCSID(0, "$NetBSD: meson_pinctrl.c,v 1.3 2019/02/25 19:30:17 jmcneill Exp $");
#include <sys/param.h>
#include <sys/bus.h>
@@ -76,6 +76,10 @@ static const struct of_compat_data compa
{ "amlogic,meson8b-aobus-pinctrl", (uintptr_t)&meson8b_aobus_pinctrl_config },
{ "amlogic,meson8b-cbus-pinctrl", (uintptr_t)&meson8b_cbus_pinctrl_config },
#endif
+#ifdef SOC_MESONGXBB
+ { "amlogic,meson-gxbb-aobus-pinctrl", (uintptr_t)&mesongxbb_aobus_pinctrl_config },
+ { "amlogic,meson-gxbb-periphs-pinctrl", (uintptr_t)&mesongxbb_periphs_pinctrl_config },
+#endif
{ NULL, 0 }
};
Index: src/sys/arch/arm/amlogic/meson_clk.c
diff -u src/sys/arch/arm/amlogic/meson_clk.c:1.1 src/sys/arch/arm/amlogic/meson_clk.c:1.2
--- src/sys/arch/arm/amlogic/meson_clk.c:1.1 Sat Jan 19 20:56:03 2019
+++ src/sys/arch/arm/amlogic/meson_clk.c Mon Feb 25 19:30:17 2019
@@ -1,4 +1,4 @@
-/* $NetBSD: meson_clk.c,v 1.1 2019/01/19 20:56:03 jmcneill Exp $ */
+/* $NetBSD: meson_clk.c,v 1.2 2019/02/25 19:30:17 jmcneill Exp $ */
/*-
* Copyright (c) 2017-2019 Jared McNeill <[email protected]>
@@ -27,7 +27,7 @@
*/
#include <sys/cdefs.h>
-__KERNEL_RCSID(0, "$NetBSD: meson_clk.c,v 1.1 2019/01/19 20:56:03 jmcneill Exp $");
+__KERNEL_RCSID(0, "$NetBSD: meson_clk.c,v 1.2 2019/02/25 19:30:17 jmcneill Exp $");
#include <sys/param.h>
#include <sys/bus.h>
@@ -35,6 +35,7 @@ __KERNEL_RCSID(0, "$NetBSD: meson_clk.c,
#include <sys/device.h>
#include <dev/fdt/fdtvar.h>
+#include <dev/fdt/syscon.h>
#include <dev/clk/clk_backend.h>
@@ -72,8 +73,10 @@ meson_clk_reset_assert(device_t dev, voi
struct meson_clk_softc * const sc = device_private(dev);
struct meson_clk_reset * const reset = priv;
+ CLK_LOCK(sc);
const uint32_t val = CLK_READ(sc, reset->reg);
CLK_WRITE(sc, reset->reg, val | reset->mask);
+ CLK_UNLOCK(sc);
return 0;
}
@@ -84,8 +87,10 @@ meson_clk_reset_deassert(device_t dev, v
struct meson_clk_softc * const sc = device_private(dev);
struct meson_clk_reset * const reset = priv;
+ CLK_LOCK(sc);
const uint32_t val = CLK_READ(sc, reset->reg);
CLK_WRITE(sc, reset->reg, val & ~reset->mask);
+ CLK_UNLOCK(sc);
return 0;
}
@@ -298,22 +303,11 @@ meson_clk_clock_find(struct meson_clk_so
return NULL;
}
-int
-meson_clk_attach(struct meson_clk_softc *sc, u_int reg_index)
+void
+meson_clk_attach(struct meson_clk_softc *sc)
{
- bus_addr_t addr;
- bus_size_t size;
int i;
- if (fdtbus_get_reg(sc->sc_phandle, reg_index, &addr, &size) != 0) {
- aprint_error(": couldn't get registers\n");
- return ENXIO;
- }
- if (bus_space_map(sc->sc_bst, addr, size, 0, &sc->sc_bsh) != 0) {
- aprint_error(": couldn't map registers\n");
- return ENXIO;
- }
-
sc->sc_clkdom.name = device_xname(sc->sc_dev);
sc->sc_clkdom.funcs = &meson_clk_clock_funcs;
sc->sc_clkdom.priv = sc;
@@ -322,13 +316,13 @@ meson_clk_attach(struct meson_clk_softc
clk_attach(&sc->sc_clks[i].base);
}
- fdtbus_register_clock_controller(sc->sc_dev, sc->sc_phandle,
- &meson_clk_fdtclock_funcs);
-
- fdtbus_register_reset_controller(sc->sc_dev, sc->sc_phandle,
- &meson_clk_fdtreset_funcs);
-
- return 0;
+ if (sc->sc_nclks > 0)
+ fdtbus_register_clock_controller(sc->sc_dev, sc->sc_phandle,
+ &meson_clk_fdtclock_funcs);
+
+ if (sc->sc_nresets > 0)
+ fdtbus_register_reset_controller(sc->sc_dev, sc->sc_phandle,
+ &meson_clk_fdtreset_funcs);
}
void
@@ -367,3 +361,35 @@ meson_clk_print(struct meson_clk_softc *
aprint_debug("%10u Hz\n", clk_get_rate(&clk->base));
}
}
+
+void
+meson_clk_lock(struct meson_clk_softc *sc)
+{
+ if (sc->sc_syscon != NULL)
+ syscon_lock(sc->sc_syscon);
+}
+
+void
+meson_clk_unlock(struct meson_clk_softc *sc)
+{
+ if (sc->sc_syscon != NULL)
+ syscon_unlock(sc->sc_syscon);
+}
+
+uint32_t
+meson_clk_read(struct meson_clk_softc *sc, bus_size_t reg)
+{
+ if (sc->sc_syscon != NULL)
+ return syscon_read_4(sc->sc_syscon, reg);
+ else
+ return bus_space_read_4(sc->sc_bst, sc->sc_bsh, reg);
+}
+
+void
+meson_clk_write(struct meson_clk_softc *sc, bus_size_t reg, uint32_t val)
+{
+ if (sc->sc_syscon != NULL)
+ syscon_write_4(sc->sc_syscon, reg, val);
+ else
+ bus_space_write_4(sc->sc_bst, sc->sc_bsh, reg, val);
+}
Index: src/sys/arch/arm/amlogic/meson_clk_gate.c
diff -u src/sys/arch/arm/amlogic/meson_clk_gate.c:1.1 src/sys/arch/arm/amlogic/meson_clk_gate.c:1.2
--- src/sys/arch/arm/amlogic/meson_clk_gate.c:1.1 Sat Jan 19 20:56:03 2019
+++ src/sys/arch/arm/amlogic/meson_clk_gate.c Mon Feb 25 19:30:17 2019
@@ -1,4 +1,4 @@
-/* $NetBSD: meson_clk_gate.c,v 1.1 2019/01/19 20:56:03 jmcneill Exp $ */
+/* $NetBSD: meson_clk_gate.c,v 1.2 2019/02/25 19:30:17 jmcneill Exp $ */
/*-
* Copyright (c) 2017-2019 Jared McNeill <[email protected]>
@@ -27,7 +27,7 @@
*/
#include <sys/cdefs.h>
-__KERNEL_RCSID(0, "$NetBSD: meson_clk_gate.c,v 1.1 2019/01/19 20:56:03 jmcneill Exp $");
+__KERNEL_RCSID(0, "$NetBSD: meson_clk_gate.c,v 1.2 2019/02/25 19:30:17 jmcneill Exp $");
#include <sys/param.h>
#include <sys/bus.h>
@@ -48,6 +48,8 @@ meson_clk_gate_enable(struct meson_clk_s
set = (gate->flags & MESON_CLK_GATE_SET_TO_DISABLE) ? !enable : enable;
+ CLK_LOCK(sc);
+
val = CLK_READ(sc, gate->reg);
if (set)
val |= gate->mask;
@@ -55,6 +57,8 @@ meson_clk_gate_enable(struct meson_clk_s
val &= ~gate->mask;
CLK_WRITE(sc, gate->reg, val);
+ CLK_UNLOCK(sc);
+
return 0;
}
Index: src/sys/arch/arm/amlogic/meson_clk_mpll.c
diff -u src/sys/arch/arm/amlogic/meson_clk_mpll.c:1.1 src/sys/arch/arm/amlogic/meson_clk_mpll.c:1.2
--- src/sys/arch/arm/amlogic/meson_clk_mpll.c:1.1 Sat Jan 19 20:56:03 2019
+++ src/sys/arch/arm/amlogic/meson_clk_mpll.c Mon Feb 25 19:30:17 2019
@@ -1,4 +1,4 @@
-/* $NetBSD: meson_clk_mpll.c,v 1.1 2019/01/19 20:56:03 jmcneill Exp $ */
+/* $NetBSD: meson_clk_mpll.c,v 1.2 2019/02/25 19:30:17 jmcneill Exp $ */
/*-
* Copyright (c) 2019 Jared McNeill <[email protected]>
@@ -27,7 +27,7 @@
*/
#include <sys/cdefs.h>
-__KERNEL_RCSID(0, "$NetBSD: meson_clk_mpll.c,v 1.1 2019/01/19 20:56:03 jmcneill Exp $");
+__KERNEL_RCSID(0, "$NetBSD: meson_clk_mpll.c,v 1.2 2019/02/25 19:30:17 jmcneill Exp $");
#include <sys/param.h>
#include <sys/bus.h>
@@ -58,12 +58,16 @@ meson_clk_mpll_get_rate(struct meson_clk
if (parent_rate == 0)
return 0;
+ CLK_LOCK(sc);
+
val = CLK_READ(sc, mpll->sdm.reg);
sdm = __SHIFTOUT(val, mpll->sdm.mask);
val = CLK_READ(sc, mpll->n2.reg);
n2 = __SHIFTOUT(val, mpll->n2.mask);
+ CLK_UNLOCK(sc);
+
const uint64_t div = (SDM_DEN * n2) + sdm;
if (div == 0)
return 0;
Index: src/sys/arch/arm/amlogic/meson_clk_mux.c
diff -u src/sys/arch/arm/amlogic/meson_clk_mux.c:1.1 src/sys/arch/arm/amlogic/meson_clk_mux.c:1.2
--- src/sys/arch/arm/amlogic/meson_clk_mux.c:1.1 Sat Jan 19 20:56:03 2019
+++ src/sys/arch/arm/amlogic/meson_clk_mux.c Mon Feb 25 19:30:17 2019
@@ -1,4 +1,4 @@
-/* $NetBSD: meson_clk_mux.c,v 1.1 2019/01/19 20:56:03 jmcneill Exp $ */
+/* $NetBSD: meson_clk_mux.c,v 1.2 2019/02/25 19:30:17 jmcneill Exp $ */
/*-
* Copyright (c) 2017-2019 Jared McNeill <[email protected]>
@@ -27,7 +27,7 @@
*/
#include <sys/cdefs.h>
-__KERNEL_RCSID(0, "$NetBSD: meson_clk_mux.c,v 1.1 2019/01/19 20:56:03 jmcneill Exp $");
+__KERNEL_RCSID(0, "$NetBSD: meson_clk_mux.c,v 1.2 2019/02/25 19:30:17 jmcneill Exp $");
#include <sys/param.h>
#include <sys/bus.h>
@@ -45,7 +45,10 @@ meson_clk_mux_get_parent(struct meson_cl
KASSERT(clk->type == MESON_CLK_MUX);
+ CLK_LOCK(sc);
val = CLK_READ(sc, mux->reg);
+ CLK_UNLOCK(sc);
+
sel = __SHIFTOUT(val, mux->sel);
if (sel >= mux->nparents)
return NULL;
Index: src/sys/arch/arm/amlogic/meson_clk_pll.c
diff -u src/sys/arch/arm/amlogic/meson_clk_pll.c:1.1 src/sys/arch/arm/amlogic/meson_clk_pll.c:1.2
--- src/sys/arch/arm/amlogic/meson_clk_pll.c:1.1 Sat Jan 19 20:56:03 2019
+++ src/sys/arch/arm/amlogic/meson_clk_pll.c Mon Feb 25 19:30:17 2019
@@ -1,4 +1,4 @@
-/* $NetBSD: meson_clk_pll.c,v 1.1 2019/01/19 20:56:03 jmcneill Exp $ */
+/* $NetBSD: meson_clk_pll.c,v 1.2 2019/02/25 19:30:17 jmcneill Exp $ */
/*-
* Copyright (c) 2019 Jared McNeill <[email protected]>
@@ -27,7 +27,7 @@
*/
#include <sys/cdefs.h>
-__KERNEL_RCSID(0, "$NetBSD: meson_clk_pll.c,v 1.1 2019/01/19 20:56:03 jmcneill Exp $");
+__KERNEL_RCSID(0, "$NetBSD: meson_clk_pll.c,v 1.2 2019/02/25 19:30:17 jmcneill Exp $");
#include <sys/param.h>
#include <sys/bus.h>
@@ -57,6 +57,8 @@ meson_clk_pll_get_rate(struct meson_clk_
if (parent_rate == 0)
return 0;
+ CLK_LOCK(sc);
+
val = CLK_READ(sc, pll->n.reg);
n = __SHIFTOUT(val, pll->n.mask);
@@ -70,6 +72,8 @@ meson_clk_pll_get_rate(struct meson_clk_
frac = 0;
}
+ CLK_UNLOCK(sc);
+
rate = parent_rate * m;
if (frac) {
uint64_t frac_rate = parent_rate * frac;
Index: src/sys/arch/arm/amlogic/meson_pinctrl.h
diff -u src/sys/arch/arm/amlogic/meson_pinctrl.h:1.1 src/sys/arch/arm/amlogic/meson_pinctrl.h:1.2
--- src/sys/arch/arm/amlogic/meson_pinctrl.h:1.1 Sat Jan 19 20:56:03 2019
+++ src/sys/arch/arm/amlogic/meson_pinctrl.h Mon Feb 25 19:30:17 2019
@@ -1,4 +1,4 @@
-/* $NetBSD: meson_pinctrl.h,v 1.1 2019/01/19 20:56:03 jmcneill Exp $ */
+/* $NetBSD: meson_pinctrl.h,v 1.2 2019/02/25 19:30:17 jmcneill Exp $ */
/*-
* Copyright (c) 2019 Jared McNeill <[email protected]>
@@ -78,4 +78,9 @@ extern const struct meson_pinctrl_config
extern const struct meson_pinctrl_config meson8b_cbus_pinctrl_config;
#endif
+#ifdef SOC_MESONGXBB
+extern const struct meson_pinctrl_config mesongxbb_aobus_pinctrl_config;
+extern const struct meson_pinctrl_config mesongxbb_periphs_pinctrl_config;
+#endif
+
#endif /* !_MESON_PINCTRL_H */
Index: src/sys/arch/arm/amlogic/meson_resets.c
diff -u src/sys/arch/arm/amlogic/meson_resets.c:1.1 src/sys/arch/arm/amlogic/meson_resets.c:1.2
--- src/sys/arch/arm/amlogic/meson_resets.c:1.1 Sat Jan 19 20:56:03 2019
+++ src/sys/arch/arm/amlogic/meson_resets.c Mon Feb 25 19:30:17 2019
@@ -1,4 +1,4 @@
-/* $NetBSD: meson_resets.c,v 1.1 2019/01/19 20:56:03 jmcneill Exp $ */
+/* $NetBSD: meson_resets.c,v 1.2 2019/02/25 19:30:17 jmcneill Exp $ */
/*-
* Copyright (c) 2017-2019 Jared McNeill <[email protected]>
@@ -27,7 +27,7 @@
*/
#include <sys/cdefs.h>
-__KERNEL_RCSID(0, "$NetBSD: meson_resets.c,v 1.1 2019/01/19 20:56:03 jmcneill Exp $");
+__KERNEL_RCSID(0, "$NetBSD: meson_resets.c,v 1.2 2019/02/25 19:30:17 jmcneill Exp $");
#include <sys/param.h>
#include <sys/bus.h>
@@ -45,6 +45,7 @@ __KERNEL_RCSID(0, "$NetBSD: meson_resets
static const char * compatible[] = {
"amlogic,meson8b-reset",
+ "amlogic,meson-gxbb-reset",
NULL
};
Index: src/sys/arch/arm/amlogic/meson_usbphy.c
diff -u src/sys/arch/arm/amlogic/meson_usbphy.c:1.1 src/sys/arch/arm/amlogic/meson_usbphy.c:1.2
--- src/sys/arch/arm/amlogic/meson_usbphy.c:1.1 Sat Jan 19 20:56:03 2019
+++ src/sys/arch/arm/amlogic/meson_usbphy.c Mon Feb 25 19:30:17 2019
@@ -1,4 +1,4 @@
-/* $NetBSD: meson_usbphy.c,v 1.1 2019/01/19 20:56:03 jmcneill Exp $ */
+/* $NetBSD: meson_usbphy.c,v 1.2 2019/02/25 19:30:17 jmcneill Exp $ */
/*-
* Copyright (c) 2019 Jared McNeill <[email protected]>
@@ -28,7 +28,7 @@
#include <sys/cdefs.h>
-__KERNEL_RCSID(0, "$NetBSD: meson_usbphy.c,v 1.1 2019/01/19 20:56:03 jmcneill Exp $");
+__KERNEL_RCSID(0, "$NetBSD: meson_usbphy.c,v 1.2 2019/02/25 19:30:17 jmcneill Exp $");
#include <sys/param.h>
#include <sys/bus.h>
@@ -61,6 +61,7 @@ enum meson_usbphy_type {
static const struct of_compat_data compat_data[] = {
{ "amlogic,meson8b-usb2-phy", USBPHY_MESON8B },
+ { "amlogic,meson-gxbb-usb2-phy", USBPHY_MESON8B },
{ NULL }
};
@@ -115,9 +116,22 @@ static int
meson_usbphy_enable(device_t dev, void *priv, bool enable)
{
struct meson_usbphy_softc * const sc = device_private(dev);
+ struct fdtbus_regulator *reg;
uint32_t val;
+ int error;
if (enable) {
+ if (of_hasprop(sc->sc_phandle, "phy-supply")) {
+ reg = fdtbus_regulator_acquire(sc->sc_phandle, "phy-supply");
+ if (reg != NULL) {
+ error = fdtbus_regulator_enable(reg);
+ if (error != 0)
+ device_printf(dev, "WARNING: couldn't enable phy-supply: %d\n", error);
+ } else {
+ device_printf(dev, "WARNING: couldn't acquire phy-supply\n");
+ }
+ }
+
delay(1000);
val = PHY_READ(sc, PREI_USB_PHY_CFG_REG);
Index: src/sys/arch/evbarm/conf/GENERIC
diff -u src/sys/arch/evbarm/conf/GENERIC:1.22 src/sys/arch/evbarm/conf/GENERIC:1.23
--- src/sys/arch/evbarm/conf/GENERIC:1.22 Sun Jan 20 17:58:37 2019
+++ src/sys/arch/evbarm/conf/GENERIC Mon Feb 25 19:30:17 2019
@@ -1,5 +1,5 @@
#
-# $NetBSD: GENERIC,v 1.22 2019/01/20 17:58:37 jmcneill Exp $
+# $NetBSD: GENERIC,v 1.23 2019/02/25 19:30:17 jmcneill Exp $
#
# GENERIC ARM (aarch32) kernel
#
@@ -549,7 +549,8 @@ hdmicec* at hdmicecbus?
#tegradrm* at fdt? # NVIDIA Tegra Display
#tegrafb* at tegrafbbus?
genfb* at fdt? # Simple Framebuffer
-wsdisplay* at genfb?
+mesonfb* at fdt? # Amlogic Meson Framebuffer
+wsdisplay* at wsemuldisplaydev?
sunxidebe* at fdt? pass 4 # Display Backend
genfb* at sunxidebe?
sunxitcon* at fdt? pass 4 # LCD LVDS/RGB controller
Index: src/sys/arch/evbarm/conf/GENERIC64
diff -u src/sys/arch/evbarm/conf/GENERIC64:1.79 src/sys/arch/evbarm/conf/GENERIC64:1.80
--- src/sys/arch/evbarm/conf/GENERIC64:1.79 Fri Feb 8 00:19:57 2019
+++ src/sys/arch/evbarm/conf/GENERIC64 Mon Feb 25 19:30:17 2019
@@ -1,5 +1,5 @@
#
-# $NetBSD: GENERIC64,v 1.79 2019/02/08 00:19:57 macallan Exp $
+# $NetBSD: GENERIC64,v 1.80 2019/02/25 19:30:17 jmcneill Exp $
#
# GENERIC ARM (aarch64) kernel
#
@@ -14,11 +14,22 @@ include "arch/evbarm/conf/GENERIC.common
#
makeoptions DTSARCH="arm aarch64"
makeoptions DTSGNUARCH="arm arm64"
-makeoptions DTSSUBDIR="allwinner broadcom nvidia rockchip"
+makeoptions DTSSUBDIR="allwinner amlogic broadcom nvidia rockchip"
makeoptions DTS="
bcm2837-rpi-3-b.dts
bcm2837-rpi-3-b-plus.dts
+ meson-gxbb-nanopi-k2.dts
+ meson-gxbb-nexbox-a95x.dts
+ meson-gxbb-odroidc2.dts
+ meson-gxbb-p200.dts
+ meson-gxbb-p201.dts
+ meson-gxbb-vega-s95-meta.dts
+ meson-gxbb-vega-s95-pro.dts
+ meson-gxbb-vega-s95-telos.dts
+ meson-gxbb-wetek-hub.dts
+ meson-gxbb-wetek-play2.dts
+
rk3328-evb.dts
rk3328-roc-cc.dts
rk3328-rock64.dts
@@ -60,6 +71,7 @@ options CPU_CORTEXA53
options CPU_CORTEXA57
options CPU_THUNDERX
options SOC_BCM2837
+options SOC_MESONGXBB
options SOC_RK3328
options SOC_RK3399
options SOC_SUN50I_A64
@@ -80,6 +92,7 @@ options VERBOSE_INIT_ARM # verbose boot
options INCLUDE_CONFIG_FILE
# EARLYCONS is required for early init messages from VERBOSE_INIT_ARM.
#options EARLYCONS=bcm2837
+#options EARLYCONS=meson, CONSADDR=0xc81004c0
#options EARLYCONS=rk3328, CONSADDR=0xff130000
#options EARLYCONS=rk3399, CONSADDR=0xff1a0000
#options EARLYCONS=sunxi, CONSADDR=0x01c28000
@@ -185,6 +198,9 @@ tegrapmc* at fdt? pass 4 # NVIDIA Tegra
# Clock and Reset controller
bcmcprman* at fdt? pass 1 # Broadcom BCM283x Clock Manager
bcmaux* at fdt? pass 1 # Broadcom BCM283x Aux Periph Clocks
+gxbbaoclkc* at fdt? pass 2 # Amlogic Meson GXBB AO clock controller
+gxbbclkc* at fdt? pass 2 # Amlogic Meson GXBB EE clock controller
+mesonresets* at fdt? pass 2 # Amlogic Meson misc. clock resets
rkcru* at fdt? pass 2 # Rockchip RK3328 CRU
sun8ih3ccu* at fdt? pass 2 # Allwinner H3/H5 CCU
sun8ih3rccu* at fdt? pass 2 # Allwinner H3/H5 CCU (PRCM)
@@ -200,6 +216,7 @@ tegra210car* at fdt? pass 3 # NVIDIA Te
# GPIO controller
bcmgpio* at fdt? # Broadcom BCM283x GPIO
+mesonpinctrl* at fdt? pass 2 # Amlogic Meson GPIO
plgpio* at fdt? # ARM PrimeCell PL061 GPIO
plgpio* at acpi?
sunxigpio* at fdt? pass 3 # Allwinner GPIO
@@ -268,6 +285,7 @@ ukphy* at mii? phy ? # generic unknown
# UART
com* at fdt? pass 4 # UART
com* at acpi?
+mesonuart* at fdt? pass 4 # Amlogic Meson UART
plcom* at fdt? pass 4 # ARM PL011 UART
plcom* at acpi?
puc* at pci? dev ? function ? # PCI "universal" comm. cards
@@ -310,6 +328,7 @@ tegrartc* at fdt? # NVIDIA Tegra RTC
# SDMMC
dwcmmc* at fdt? # Designware SD/MMC
+mesongxmmc* at fdt? # Amlogic Meson GX eMMC/SD/SDIO controller
mmcpwrseq* at fdt? # Simple MMC power sequence provider
sdhc* at fdt? # SD Host Controller Interface
sdhost* at fdt? # Broadcom BCM283x SD Host Interface
@@ -398,6 +417,7 @@ sunxithermal* at fdt? # Allwinner ther
tegrasoctherm* at fdt? # NVIDIA Tegra SOC_THERM
# USB
+mesonusbphy* at fdt? pass 9 # Amlogic Meson USB2 PHY
rkusb* at fdt? pass 9 # Rockchip USB PHY
rkusbphy* at rkusb?
sunxiusbphy* at fdt? pass 9 # Allwinner USB PHY
Index: src/sys/arch/evbarm/conf/files.generic64
diff -u src/sys/arch/evbarm/conf/files.generic64:1.10 src/sys/arch/evbarm/conf/files.generic64:1.11
--- src/sys/arch/evbarm/conf/files.generic64:1.10 Sun Jan 27 02:08:38 2019
+++ src/sys/arch/evbarm/conf/files.generic64 Mon Feb 25 19:30:17 2019
@@ -1,4 +1,4 @@
-# $NetBSD: files.generic64,v 1.10 2019/01/27 02:08:38 pgoyette Exp $
+# $NetBSD: files.generic64,v 1.11 2019/02/25 19:30:17 jmcneill Exp $
#
# A generic (aarch64) kernel configuration info
#
@@ -11,6 +11,7 @@ include "arch/evbarm/conf/files.fdt"
# Add other board files here
#
include "arch/arm/acpi/files.acpi"
+include "arch/arm/amlogic/files.meson"
include "arch/arm/broadcom/files.bcm2835"
include "arch/arm/cavium/files.thunderx"
include "arch/arm/nvidia/files.tegra"
Index: src/sys/external/gpl2/dts/dist/arch/arm64/boot/dts/amlogic/meson-gxbb.dtsi
diff -u src/sys/external/gpl2/dts/dist/arch/arm64/boot/dts/amlogic/meson-gxbb.dtsi:1.1.1.7 src/sys/external/gpl2/dts/dist/arch/arm64/boot/dts/amlogic/meson-gxbb.dtsi:1.2
--- src/sys/external/gpl2/dts/dist/arch/arm64/boot/dts/amlogic/meson-gxbb.dtsi:1.1.1.7 Tue Jan 22 14:57:03 2019
+++ src/sys/external/gpl2/dts/dist/arch/arm64/boot/dts/amlogic/meson-gxbb.dtsi Mon Feb 25 19:30:17 2019
@@ -280,6 +280,8 @@
&clkc_AO {
compatible = "amlogic,meson-gxbb-aoclkc", "amlogic,meson-gx-aoclkc";
+ clocks = <&xtal>, <&clkc CLKID_CLK81>;
+ clock-names = "xtal", "mpeg-clk";
};
ðmac {
@@ -311,6 +313,8 @@
clkc: clock-controller {
compatible = "amlogic,gxbb-clkc";
#clock-cells = <1>;
+ clocks = <&xtal>;
+ clock-names = "xtal";
};
};
Added files:
Index: src/sys/arch/arm/amlogic/mesongx_mmc.c
diff -u /dev/null src/sys/arch/arm/amlogic/mesongx_mmc.c:1.1
--- /dev/null Mon Feb 25 19:30:17 2019
+++ src/sys/arch/arm/amlogic/mesongx_mmc.c Mon Feb 25 19:30:17 2019
@@ -0,0 +1,1044 @@
+/* $NetBSD: mesongx_mmc.c,v 1.1 2019/02/25 19:30:17 jmcneill Exp $ */
+
+/*-
+ * Copyright (c) 2019 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: mesongx_mmc.c,v 1.1 2019/02/25 19:30:17 jmcneill Exp $");
+
+#include <sys/param.h>
+#include <sys/bus.h>
+#include <sys/device.h>
+#include <sys/intr.h>
+#include <sys/systm.h>
+#include <sys/kernel.h>
+#include <sys/bitops.h>
+#include <sys/gpio.h>
+
+#include <dev/sdmmc/sdmmcvar.h>
+#include <dev/sdmmc/sdmmcchip.h>
+#include <dev/sdmmc/sdmmc_ioreg.h>
+
+#include <dev/fdt/fdtvar.h>
+
+#define SD_EMMC_CLOCK 0x00
+#define CLOCK_CFG_IRQ_SDIO_SLEEP __BIT(25)
+#define CLOCK_CFG_ALWAYS_ON __BIT(24)
+#define CLOCK_CFG_RX_DELAY __BITS(23,20)
+#define CLOCK_CFG_TX_DELAY __BITS(19,16)
+#define CLOCK_CFG_SRAM_PD __BITS(15,14)
+#define CLOCK_CFG_RX_PHASE __BITS(13,12)
+#define CLOCK_CFG_TX_PHASE __BITS(11,10)
+#define CLOCK_CFG_CO_PHASE __BITS(9,8)
+#define CLOCK_CFG_SRC __BITS(7,6)
+#define CLOCK_CFG_DIV __BITS(5,0)
+#define SD_EMMC_DELAY 0x04
+#define SD_EMMC_ADJUST 0x08
+#define ADJUST_ADJ_DELAY __BITS(21,16)
+#define ADJUST_CALI_RISE __BIT(14)
+#define ADJUST_ADJ_ENABLE __BIT(13)
+#define ADJUST_CALI_ENABLE __BIT(12)
+#define ADJUST_CALI_SEL __BITS(11,8)
+#define SD_EMMC_CALOUT 0x10
+#define CALOUT_CALI_SETUP __BITS(15,8)
+#define CALOUT_CALI_VLD __BIT(7)
+#define CALOUT_CALI_IDX __BITS(5,0)
+#define SD_EMMC_START 0x40
+#define START_DESC_ADDR __BITS(31,2)
+#define START_DESC_BUSY __BIT(1)
+#define START_DESC_INT __BIT(0)
+#define SD_EMMC_CFG 0x44
+#define CFG_IP_TXD_ADJ __BITS(31,28)
+#define CFG_ERR_ABORT __BIT(27)
+#define CFG_IRQ_DS __BIT(26)
+#define CFG_TXD_RETRY __BIT(25)
+#define CFG_TXD_ADD_ERR __BIT(24)
+#define CFG_AUTO_CLK __BIT(23)
+#define CFG_STOP_CLK __BIT(22)
+#define CFG_CMD_LOW __BIT(21)
+#define CFG_CHK_DS __BIT(20)
+#define CFG_IGNORE_OWNER __BIT(19)
+#define CFG_SDCLK_ALWAYS_ON __BIT(18)
+#define CFG_BLK_GAP_IP __BIT(17)
+#define CFG_OUT_FALL __BIT(16)
+#define CFG_RC_CC __BITS(15,12)
+#define CFG_RESP_TIMEOUT __BIT(11,8)
+#define CFG_BL_LEN __BITS(7,4)
+#define CFG_DC_UGT __BIT(3)
+#define CFG_DDR __BIT(2)
+#define CFG_BUS_WIDTH __BITS(1,0)
+#define CFG_BUS_WIDTH_1 0
+#define CFG_BUS_WIDTH_4 1
+#define CFG_BUS_WIDTH_8 2
+#define SD_EMMC_STATUS 0x48
+#define STATUS_CORE_BUSY __BIT(31)
+#define STATUS_DESC_BUSY __BIT(30)
+#define STATUS_BUS_FSM __BIT(29,26)
+#define STATUS_DS __BIT(25)
+#define STATUS_CMD_I __BIT(24)
+#define STATUS_DAT_I __BITS(23,16)
+#define STATUS_IRQ_SDIO __BIT(15)
+#define STATUS_RESP_STATUS __BIT(14)
+#define STATUS_END_OF_CHAIN __BIT(13)
+#define STATUS_DESC_TIMEOUT __BIT(12)
+#define STATUS_RESP_TIMEOUT __BIT(11)
+#define STATUS_RESP_ERR __BIT(10)
+#define STATUS_DESC_ERR __BIT(9)
+#define STATUS_TXD_ERR __BIT(8)
+#define STATUS_RXD_ERR __BITS(7,0)
+#define STATUS_TIMEOUT (STATUS_DESC_TIMEOUT | STATUS_RESP_TIMEOUT)
+#define STATUS_ERROR (STATUS_RESP_ERR | STATUS_DESC_ERR | STATUS_RXD_ERR | STATUS_TXD_ERR)
+#define SD_EMMC_IRQ_EN 0x4c
+#define IRQ_EN_CFG_SECURE __BIT(16)
+#define IRQ_EN_IRQ_SDIO __BIT(15)
+#define IRQ_EN_RESP_STATUS __BIT(14)
+#define IRQ_EN_END_OF_CHAIN __BIT(13)
+#define IRQ_EN_DESC_TIMEOUT __BIT(12)
+#define IRQ_EN_RESP_TIMEOUT __BIT(11)
+#define IRQ_EN_RESP_ERR __BIT(10)
+#define IRQ_EN_DESC_ERR __BIT(9)
+#define IRQ_EN_TXD_ERR __BIT(8)
+#define IRQ_EN_RXD_ERR __BITS(7,0)
+#define SD_EMMC_CMD_CFG 0x50
+#define SD_EMMC_CMD_ARG 0x54
+#define SD_EMMC_CMD_DAT 0x58
+#define SD_EMMC_CMD_RSP 0x5c
+#define SD_EMMC_CMD_RSP1 0x60
+#define SD_EMMC_CMD_RSP2 0x64
+#define SD_EMMC_CMD_RSP3 0x68
+
+struct mesongx_mmc_desc {
+ uint32_t flags;
+#define MESONGX_MMC_FLAGS_OWNER __BIT(31)
+#define MESONGX_MMC_FLAGS_ERROR __BIT(30)
+#define MESONGX_MMC_FLAGS_CMD_INDEX __BITS(29,24)
+#define MESONGX_MMC_FLAGS_DATA_NUM __BIT(23)
+#define MESONGX_MMC_FLAGS_RESP_NUM __BIT(22)
+#define MESONGX_MMC_FLAGS_RESP_128 __BIT(21)
+#define MESONGX_MMC_FLAGS_RESP_NOCRC __BIT(20)
+#define MESONGX_MMC_FLAGS_DATA_WR __BIT(19)
+#define MESONGX_MMC_FLAGS_DATA_IO __BIT(18)
+#define MESONGX_MMC_FLAGS_NO_CMD __BIT(17)
+#define MESONGX_MMC_FLAGS_NO_RESP __BIT(16)
+#define MESONGX_MMC_FLAGS_TIMEOUT __BITS(15,12)
+#define MESONGX_MMC_FLAGS_END_OF_CHAIN __BIT(11)
+#define MESONGX_MMC_FLAGS_R1B __BIT(10)
+#define MESONGX_MMC_FLAGS_BLOCK_MODE __BIT(9)
+#define MESONGX_MMC_FLAGS_LENGTH __BITS(8,0)
+ uint32_t arg;
+ uint32_t data;
+#define MESONGX_MMC_DATA_BIG_ENDIAN __BIT(1)
+#define MESONGX_MMC_DATA_SRAM __BIT(0)
+ uint32_t resp;
+#define MESONGX_MMC_RESP_SRAM __BIT(0)
+} __packed;
+
+#define MESONGX_MMC_NDESC 256
+
+struct mesongx_mmc_softc;
+
+static int mesongx_mmc_match(device_t, cfdata_t, void *);
+static void mesongx_mmc_attach(device_t, device_t, void *);
+static void mesongx_mmc_attach_i(device_t);
+
+static int mesongx_mmc_intr(void *);
+static int mesongx_mmc_dma_setup(struct mesongx_mmc_softc *);
+static int mesongx_mmc_dmabounce_setup(struct mesongx_mmc_softc *);
+
+static int mesongx_mmc_host_reset(sdmmc_chipset_handle_t);
+static uint32_t mesongx_mmc_host_ocr(sdmmc_chipset_handle_t);
+static int mesongx_mmc_host_maxblklen(sdmmc_chipset_handle_t);
+static int mesongx_mmc_card_detect(sdmmc_chipset_handle_t);
+static int mesongx_mmc_write_protect(sdmmc_chipset_handle_t);
+static int mesongx_mmc_bus_power(sdmmc_chipset_handle_t, uint32_t);
+static int mesongx_mmc_bus_clock(sdmmc_chipset_handle_t, int, bool);
+static int mesongx_mmc_bus_width(sdmmc_chipset_handle_t, int);
+static int mesongx_mmc_bus_rod(sdmmc_chipset_handle_t, int);
+static int mesongx_mmc_signal_voltage(sdmmc_chipset_handle_t, int);
+static int mesongx_mmc_execute_tuning(sdmmc_chipset_handle_t, int);
+static void mesongx_mmc_exec_command(sdmmc_chipset_handle_t,
+ struct sdmmc_command *);
+static void mesongx_mmc_card_enable_intr(sdmmc_chipset_handle_t, int);
+static void mesongx_mmc_card_intr_ack(sdmmc_chipset_handle_t);
+
+static struct sdmmc_chip_functions mesongx_mmc_chip_functions = {
+ .host_reset = mesongx_mmc_host_reset,
+ .host_ocr = mesongx_mmc_host_ocr,
+ .host_maxblklen = mesongx_mmc_host_maxblklen,
+ .card_detect = mesongx_mmc_card_detect,
+ .write_protect = mesongx_mmc_write_protect,
+ .bus_power = mesongx_mmc_bus_power,
+ .bus_clock_ddr = mesongx_mmc_bus_clock,
+ .bus_width = mesongx_mmc_bus_width,
+ .bus_rod = mesongx_mmc_bus_rod,
+ .signal_voltage = mesongx_mmc_signal_voltage,
+ .execute_tuning = mesongx_mmc_execute_tuning,
+ .exec_command = mesongx_mmc_exec_command,
+ .card_enable_intr = mesongx_mmc_card_enable_intr,
+ .card_intr_ack = mesongx_mmc_card_intr_ack,
+};
+
+struct mesongx_mmc_softc {
+ device_t sc_dev;
+ bus_space_tag_t sc_bst;
+ bus_space_handle_t sc_bsh;
+ bus_dma_tag_t sc_dmat;
+ int sc_phandle;
+
+ void *sc_ih;
+ kmutex_t sc_intr_lock;
+ kcondvar_t sc_intr_cv;
+
+ device_t sc_sdmmc_dev;
+ uint32_t sc_host_ocr;
+
+ struct sdmmc_command *sc_cmd;
+
+ bus_dma_segment_t sc_desc_segs[1];
+ int sc_desc_nsegs;
+ bus_size_t sc_desc_size;
+ bus_dmamap_t sc_desc_map;
+ int sc_desc_ndesc;
+ void *sc_desc_desc;
+
+ bus_dmamap_t sc_dmabounce_map;
+ void *sc_dmabounce_buf;
+ size_t sc_dmabounce_buflen;
+
+ struct clk *sc_clk_core;
+ struct clk *sc_clk_clkin[2];
+
+ struct fdtbus_reset *sc_rst;
+
+ struct fdtbus_gpio_pin *sc_gpio_cd;
+ int sc_gpio_cd_inverted;
+ struct fdtbus_gpio_pin *sc_gpio_wp;
+ int sc_gpio_wp_inverted;
+
+ struct fdtbus_regulator *sc_reg_vmmc;
+ struct fdtbus_regulator *sc_reg_vqmmc;
+
+ struct fdtbus_mmc_pwrseq *sc_pwrseq;
+
+ u_int sc_max_frequency;
+ bool sc_non_removable;
+ bool sc_broken_cd;
+};
+
+CFATTACH_DECL_NEW(mesongx_mmc, sizeof(struct mesongx_mmc_softc),
+ mesongx_mmc_match, mesongx_mmc_attach, NULL, NULL);
+
+#define MMC_WRITE(sc, reg, val) \
+ bus_space_write_4((sc)->sc_bst, (sc)->sc_bsh, (reg), (val))
+#define MMC_READ(sc, reg) \
+ bus_space_read_4((sc)->sc_bst, (sc)->sc_bsh, (reg))
+
+static const struct of_compat_data compat_data[] = {
+ { "amlogic,meson-gx-mmc", 1 },
+ { "amlogic,meson-gxbb-mmc", 1 },
+ { NULL }
+};
+
+static int
+mesongx_mmc_match(device_t parent, cfdata_t cf, void *aux)
+{
+ struct fdt_attach_args * const faa = aux;
+
+ return of_match_compat_data(faa->faa_phandle, compat_data);
+}
+
+static void
+mesongx_mmc_attach(device_t parent, device_t self, void *aux)
+{
+ struct mesongx_mmc_softc * const sc = device_private(self);
+ struct fdt_attach_args * const faa = aux;
+ const int phandle = faa->faa_phandle;
+ char intrstr[128];
+ bus_addr_t addr;
+ bus_size_t size;
+
+ if (fdtbus_get_reg(phandle, 0, &addr, &size) != 0) {
+ aprint_error(": couldn't get registers\n");
+ return;
+ }
+
+ sc->sc_clk_core = fdtbus_clock_get(phandle, "core");
+ sc->sc_clk_clkin[0] = fdtbus_clock_get(phandle, "clkin0");
+ sc->sc_clk_clkin[1] = fdtbus_clock_get(phandle, "clkin1");
+
+ if (sc->sc_clk_core == NULL || sc->sc_clk_clkin[0] == NULL ||
+ sc->sc_clk_clkin[1] == NULL) {
+ aprint_error(": couldn't get clocks\n");
+ return;
+ }
+
+ sc->sc_rst = fdtbus_reset_get_index(phandle, 0);
+ if (sc->sc_rst == NULL) {
+ aprint_error(": couldn't get reset\n");
+ return;
+ }
+
+ sc->sc_pwrseq = fdtbus_mmc_pwrseq_get(phandle);
+
+ if (clk_enable(sc->sc_clk_core) != 0) {
+ aprint_error(": couldn't enable core clock\n");
+ return;
+ }
+ if (clk_enable(sc->sc_clk_clkin[0]) != 0 ||
+ clk_enable(sc->sc_clk_clkin[1]) != 0) {
+ aprint_error(": couldn't enable clkin clocks\n");
+ return;
+ }
+
+ if (fdtbus_reset_deassert(sc->sc_rst) != 0) {
+ aprint_error(": couldn't de-assert reset\n");
+ return;
+ }
+
+ sc->sc_dev = self;
+ sc->sc_phandle = phandle;
+ sc->sc_bst = faa->faa_bst;
+ sc->sc_dmat = faa->faa_dmat;
+ mutex_init(&sc->sc_intr_lock, MUTEX_DEFAULT, IPL_BIO);
+ cv_init(&sc->sc_intr_cv, "gxmmcirq");
+
+ if (bus_space_map(sc->sc_bst, addr, size, 0, &sc->sc_bsh) != 0) {
+ aprint_error(": couldn't map registers\n");
+ return;
+ }
+
+ aprint_naive("\n");
+ aprint_normal(": eMMC/SD/SDIO controller\n");
+
+ sc->sc_reg_vmmc = fdtbus_regulator_acquire(phandle, "vmmc-supply");
+ sc->sc_reg_vqmmc = fdtbus_regulator_acquire(phandle, "vqmmc-supply");
+
+ sc->sc_gpio_cd = fdtbus_gpio_acquire(phandle, "cd-gpios",
+ GPIO_PIN_INPUT);
+ sc->sc_gpio_wp = fdtbus_gpio_acquire(phandle, "wp-gpios",
+ GPIO_PIN_INPUT);
+
+ sc->sc_gpio_cd_inverted = of_hasprop(phandle, "cd-inverted") ? 1 : 0;
+ sc->sc_gpio_wp_inverted = of_hasprop(phandle, "wp-inverted") ? 1 : 0;
+
+ sc->sc_non_removable = of_hasprop(phandle, "non-removable");
+ sc->sc_broken_cd = of_hasprop(phandle, "broken-cd");
+
+ if (of_getprop_uint32(phandle, "max-frequency", &sc->sc_max_frequency))
+ sc->sc_max_frequency = 52000000;
+
+ if (mesongx_mmc_dma_setup(sc) != 0 ||
+ mesongx_mmc_dmabounce_setup(sc) != 0) {
+ aprint_error_dev(self, "failed to setup DMA\n");
+ return;
+ }
+
+ if (!fdtbus_intr_str(phandle, 0, intrstr, sizeof(intrstr))) {
+ aprint_error_dev(self, "failed to decode interrupt\n");
+ return;
+ }
+
+ sc->sc_ih = fdtbus_intr_establish(phandle, 0, IPL_BIO, FDT_INTR_MPSAFE,
+ mesongx_mmc_intr, sc);
+ if (sc->sc_ih == NULL) {
+ aprint_error_dev(self, "failed to establish interrupt on %s\n",
+ intrstr);
+ return;
+ }
+ aprint_normal_dev(self, "interrupting on %s\n", intrstr);
+
+ config_interrupts(self, mesongx_mmc_attach_i);
+}
+
+static int
+mesongx_mmc_dma_setup(struct mesongx_mmc_softc *sc)
+{
+ int error;
+
+ sc->sc_desc_ndesc = MESONGX_MMC_NDESC;
+ sc->sc_desc_size = sizeof(struct mesongx_mmc_desc) *
+ sc->sc_desc_ndesc;
+ error = bus_dmamem_alloc(sc->sc_dmat, sc->sc_desc_size,
+ sizeof(struct mesongx_mmc_desc),
+ sc->sc_desc_size, sc->sc_desc_segs, 1,
+ &sc->sc_desc_nsegs, BUS_DMA_WAITOK);
+ if (error)
+ return error;
+ error = bus_dmamem_map(sc->sc_dmat, sc->sc_desc_segs,
+ sc->sc_desc_nsegs, sc->sc_desc_size,
+ &sc->sc_desc_desc, BUS_DMA_WAITOK);
+ if (error)
+ goto free;
+ error = bus_dmamap_create(sc->sc_dmat, sc->sc_desc_size, 1,
+ sc->sc_desc_size, 0, BUS_DMA_WAITOK, &sc->sc_desc_map);
+ if (error)
+ goto unmap;
+ error = bus_dmamap_load(sc->sc_dmat, sc->sc_desc_map,
+ sc->sc_desc_desc, sc->sc_desc_size, NULL, BUS_DMA_WAITOK);
+ if (error)
+ goto destroy;
+ return 0;
+
+destroy:
+ bus_dmamap_destroy(sc->sc_dmat, sc->sc_desc_map);
+unmap:
+ bus_dmamem_unmap(sc->sc_dmat, sc->sc_desc_desc, sc->sc_desc_size);
+free:
+ bus_dmamem_free(sc->sc_dmat, sc->sc_desc_segs, sc->sc_desc_nsegs);
+ return error;
+}
+
+static int
+mesongx_mmc_dmabounce_setup(struct mesongx_mmc_softc *sc)
+{
+ bus_dma_segment_t ds[1];
+ int error, rseg;
+
+ sc->sc_dmabounce_buflen = MAXPHYS;
+ error = bus_dmamem_alloc(sc->sc_dmat, sc->sc_dmabounce_buflen, 0,
+ sc->sc_dmabounce_buflen, ds, 1, &rseg, BUS_DMA_WAITOK);
+ if (error)
+ return error;
+ error = bus_dmamem_map(sc->sc_dmat, ds, 1, sc->sc_dmabounce_buflen,
+ &sc->sc_dmabounce_buf, BUS_DMA_WAITOK);
+ if (error)
+ goto free;
+ error = bus_dmamap_create(sc->sc_dmat, sc->sc_dmabounce_buflen, 1,
+ sc->sc_dmabounce_buflen, 0, BUS_DMA_WAITOK, &sc->sc_dmabounce_map);
+ if (error)
+ goto unmap;
+ error = bus_dmamap_load(sc->sc_dmat, sc->sc_dmabounce_map,
+ sc->sc_dmabounce_buf, sc->sc_dmabounce_buflen, NULL,
+ BUS_DMA_WAITOK);
+ if (error)
+ goto destroy;
+ return 0;
+
+destroy:
+ bus_dmamap_destroy(sc->sc_dmat, sc->sc_dmabounce_map);
+unmap:
+ bus_dmamem_unmap(sc->sc_dmat, sc->sc_dmabounce_buf,
+ sc->sc_dmabounce_buflen);
+free:
+ bus_dmamem_free(sc->sc_dmat, ds, rseg);
+ return error;
+}
+
+static int
+mesongx_mmc_set_clock(struct mesongx_mmc_softc *sc, u_int freq, bool ddr)
+{
+ int best_diff, best_sel, best_div, sel, div;
+ uint32_t val;
+
+ if (freq == 0)
+ freq = SDMMC_SDCLK_400K;
+
+ best_diff = INT_MAX;
+ best_sel = 0;
+ best_div = 0;
+
+ const u_int target_rate = (freq * 1000) >> ddr;
+ for (sel = 0; sel <= 1; sel++) {
+ const u_int parent_rate = clk_get_rate(sc->sc_clk_clkin[sel]);
+ for (div = 1; div <= 63; div++) {
+ const u_int rate = parent_rate / div;
+ if (rate > target_rate)
+ continue;
+ const int diff = target_rate - rate;
+ if (diff < best_diff) {
+ best_diff = diff;
+ best_sel = sel;
+ best_div = div;
+ }
+ }
+ }
+
+ if (best_diff == INT_MAX)
+ return ERANGE;
+
+ val = MMC_READ(sc, SD_EMMC_CLOCK);
+ val |= CLOCK_CFG_ALWAYS_ON;
+ val &= ~CLOCK_CFG_RX_PHASE;
+ val |= __SHIFTIN(0, CLOCK_CFG_RX_PHASE);
+ val &= ~CLOCK_CFG_TX_PHASE;
+ val |= __SHIFTIN(2, CLOCK_CFG_TX_PHASE);
+ val &= ~CLOCK_CFG_CO_PHASE;
+ val |= __SHIFTIN(3, CLOCK_CFG_CO_PHASE);
+ val &= ~CLOCK_CFG_SRC;
+ val |= __SHIFTIN(best_sel, CLOCK_CFG_SRC);
+ val &= ~CLOCK_CFG_DIV;
+ val |= __SHIFTIN(best_div, CLOCK_CFG_DIV);
+ MMC_WRITE(sc, SD_EMMC_CLOCK, val);
+
+ return 0;
+}
+
+static void
+mesongx_mmc_attach_i(device_t self)
+{
+ struct mesongx_mmc_softc * const sc = device_private(self);
+ struct sdmmcbus_attach_args saa;
+ uint32_t width;
+
+ if (sc->sc_pwrseq)
+ fdtbus_mmc_pwrseq_pre_power_on(sc->sc_pwrseq);
+
+ mesongx_mmc_bus_clock(sc, SDMMC_SDCLK_400K, false);
+ mesongx_mmc_host_reset(sc);
+ mesongx_mmc_bus_width(sc, 1);
+
+ if (sc->sc_pwrseq)
+ fdtbus_mmc_pwrseq_post_power_on(sc->sc_pwrseq);
+
+ if (of_getprop_uint32(sc->sc_phandle, "bus-width", &width) != 0)
+ width = 4;
+
+ memset(&saa, 0, sizeof(saa));
+ saa.saa_busname = "sdmmc";
+ saa.saa_sct = &mesongx_mmc_chip_functions;
+ saa.saa_sch = sc;
+ saa.saa_dmat = sc->sc_dmat;
+ saa.saa_clkmin = SDMMC_SDCLK_400K;
+ saa.saa_clkmax = sc->sc_max_frequency / 1000;
+ saa.saa_caps = SMC_CAPS_DMA |
+ SMC_CAPS_MULTI_SEG_DMA;
+
+ sc->sc_host_ocr = MMC_OCR_3_2V_3_3V | MMC_OCR_3_3V_3_4V;
+
+ if (of_getprop_bool(sc->sc_phandle, "cap-sd-highspeed")) {
+ saa.saa_caps |= SMC_CAPS_SD_HIGHSPEED;
+ sc->sc_host_ocr |= MMC_OCR_HCS;
+ }
+ if (of_getprop_bool(sc->sc_phandle, "cap-mmc-highspeed"))
+ saa.saa_caps |= SMC_CAPS_MMC_HIGHSPEED;
+
+ if (sc->sc_reg_vqmmc != NULL) {
+ if (of_getprop_bool(sc->sc_phandle, "mmc-ddr-1_8v")) {
+ saa.saa_caps |= SMC_CAPS_MMC_DDR52;
+ sc->sc_host_ocr |= MMC_OCR_S18A;
+ }
+ if (of_getprop_bool(sc->sc_phandle, "mmc-hs200-1_8v")) {
+ saa.saa_caps |= SMC_CAPS_MMC_HS200;
+ sc->sc_host_ocr |= MMC_OCR_S18A;
+ }
+ }
+
+ if (width == 4)
+ saa.saa_caps |= SMC_CAPS_4BIT_MODE;
+ if (width == 8)
+ saa.saa_caps |= SMC_CAPS_8BIT_MODE;
+
+ if (sc->sc_gpio_cd)
+ saa.saa_caps |= SMC_CAPS_POLL_CARD_DET;
+
+ sc->sc_sdmmc_dev = config_found(self, &saa, NULL);
+}
+
+static int
+mesongx_mmc_intr(void *priv)
+{
+ struct mesongx_mmc_softc * const sc = priv;
+ struct sdmmc_command *cmd;
+ int rv = 0;
+
+ mutex_enter(&sc->sc_intr_lock);
+
+ const uint32_t irq_en = MMC_READ(sc, SD_EMMC_IRQ_EN);
+ const uint32_t status = MMC_READ(sc, SD_EMMC_STATUS) & irq_en;
+
+ if ((status & STATUS_IRQ_SDIO) != 0) {
+ rv = 1;
+ sdmmc_card_intr(sc->sc_sdmmc_dev);
+ }
+
+ cmd = sc->sc_cmd;
+ if (cmd == NULL) {
+ device_printf(sc->sc_dev, "WARNING: IRQ with no active command, status %#x\n", status);
+ goto done;
+ }
+
+ if ((status & STATUS_TIMEOUT) != 0) {
+ rv = 1;
+ cmd->c_error = ETIMEDOUT;
+ goto done;
+ }
+
+ if ((status & STATUS_ERROR) != 0) {
+ rv = 1;
+ cmd->c_error = EIO;
+ goto done;
+ }
+
+ if ((status & STATUS_END_OF_CHAIN) != 0 && (cmd->c_flags & SCF_ITSDONE) == 0) {
+ rv = 1;
+ if ((cmd->c_flags & SCF_RSP_PRESENT) != 0) {
+ if (cmd->c_flags & SCF_RSP_136) {
+ cmd->c_resp[0] = MMC_READ(sc, SD_EMMC_CMD_RSP);
+ cmd->c_resp[1] = MMC_READ(sc, SD_EMMC_CMD_RSP1);
+ cmd->c_resp[2] = MMC_READ(sc, SD_EMMC_CMD_RSP2);
+ cmd->c_resp[3] = MMC_READ(sc, SD_EMMC_CMD_RSP3);
+ if (cmd->c_flags & SCF_RSP_CRC) {
+ cmd->c_resp[0] = (cmd->c_resp[0] >> 8) |
+ (cmd->c_resp[1] << 24);
+ cmd->c_resp[1] = (cmd->c_resp[1] >> 8) |
+ (cmd->c_resp[2] << 24);
+ cmd->c_resp[2] = (cmd->c_resp[2] >> 8) |
+ (cmd->c_resp[3] << 24);
+ cmd->c_resp[3] = (cmd->c_resp[3] >> 8);
+ }
+ } else {
+ cmd->c_resp[0] = MMC_READ(sc, SD_EMMC_CMD_RSP);
+ }
+ }
+ cmd->c_flags |= SCF_ITSDONE;
+ cmd->c_error = 0;
+ goto done;
+ }
+
+done:
+ if (rv) {
+ cv_broadcast(&sc->sc_intr_cv);
+ MMC_WRITE(sc, SD_EMMC_STATUS, irq_en);
+ }
+
+ mutex_exit(&sc->sc_intr_lock);
+
+ return rv;
+}
+
+static int
+mesongx_mmc_host_reset(sdmmc_chipset_handle_t sch)
+{
+ struct mesongx_mmc_softc * const sc = sch;
+ uint32_t val;
+
+ MMC_WRITE(sc, SD_EMMC_START, 0);
+
+ val = MMC_READ(sc, SD_EMMC_CFG);
+ val &= ~CFG_RC_CC;
+ val |= __SHIFTIN(ilog2(16), CFG_RC_CC);
+ val |= CFG_SDCLK_ALWAYS_ON;
+ MMC_WRITE(sc, SD_EMMC_CFG, val);
+
+ return 0;
+}
+
+static uint32_t
+mesongx_mmc_host_ocr(sdmmc_chipset_handle_t sch)
+{
+ struct mesongx_mmc_softc * const sc = sch;
+
+ return sc->sc_host_ocr;
+}
+
+static int
+mesongx_mmc_host_maxblklen(sdmmc_chipset_handle_t sch)
+{
+ return 512;
+}
+
+static int
+mesongx_mmc_card_detect(sdmmc_chipset_handle_t sch)
+{
+ struct mesongx_mmc_softc * const sc = sch;
+ int val;
+
+ if (sc->sc_non_removable || sc->sc_broken_cd) {
+ /*
+ * Non-removable or broken card detect flag set in
+ * DT, assume always present
+ */
+ return 1;
+ } else if (sc->sc_gpio_cd != NULL) {
+ val = fdtbus_gpio_read(sc->sc_gpio_cd);
+ if (sc->sc_gpio_cd_inverted)
+ val = !val;
+ return val;
+ } else {
+ return 1;
+ }
+}
+
+static int
+mesongx_mmc_write_protect(sdmmc_chipset_handle_t sch)
+{
+ struct mesongx_mmc_softc * const sc = sch;
+ int val;
+
+ if (sc->sc_gpio_wp != NULL) {
+ val = fdtbus_gpio_read(sc->sc_gpio_wp);
+ if (sc->sc_gpio_wp_inverted)
+ val = !val;
+ return val;
+ }
+
+ return 0;
+}
+
+static int
+mesongx_mmc_bus_power(sdmmc_chipset_handle_t sch, uint32_t ocr)
+{
+ return 0;
+}
+
+static int
+mesongx_mmc_bus_clock(sdmmc_chipset_handle_t sch, int freq, bool ddr)
+{
+ struct mesongx_mmc_softc * const sc = sch;
+ uint32_t val;
+ int error;
+
+ error = mesongx_mmc_set_clock(sc, freq, ddr);
+ if (error != 0)
+ return error;
+
+ val = MMC_READ(sc, SD_EMMC_CFG);
+ if (ddr)
+ val |= CFG_DDR;
+ else
+ val &= ~CFG_DDR;
+ MMC_WRITE(sc, SD_EMMC_CFG, val);
+
+ return 0;
+}
+
+static int
+mesongx_mmc_bus_width(sdmmc_chipset_handle_t sch, int width)
+{
+ struct mesongx_mmc_softc *sc = sch;
+ uint32_t val;
+
+ val = MMC_READ(sc, SD_EMMC_CFG);
+ val &= ~CFG_BUS_WIDTH;
+
+ switch (width) {
+ case 1:
+ val |= __SHIFTIN(CFG_BUS_WIDTH_1, CFG_BUS_WIDTH);
+ break;
+ case 4:
+ val |= __SHIFTIN(CFG_BUS_WIDTH_4, CFG_BUS_WIDTH);
+ break;
+ case 8:
+ val |= __SHIFTIN(CFG_BUS_WIDTH_8, CFG_BUS_WIDTH);
+ break;
+ default:
+ return EINVAL;
+ }
+
+ MMC_WRITE(sc, SD_EMMC_CFG, val);
+
+ return 0;
+}
+
+static int
+mesongx_mmc_bus_rod(sdmmc_chipset_handle_t sch, int on)
+{
+ return -1;
+}
+
+static int
+mesongx_mmc_signal_voltage(sdmmc_chipset_handle_t sch, int signal_voltage)
+{
+ struct mesongx_mmc_softc *sc = sch;
+ u_int uvol;
+ int error;
+
+ if (sc->sc_reg_vqmmc == NULL)
+ return 0;
+
+ switch (signal_voltage) {
+ case SDMMC_SIGNAL_VOLTAGE_330:
+ uvol = 3300000;
+ break;
+ case SDMMC_SIGNAL_VOLTAGE_180:
+ uvol = 1800000;
+ break;
+ default:
+ return EINVAL;
+ }
+
+ error = fdtbus_regulator_supports_voltage(sc->sc_reg_vqmmc, uvol, uvol);
+ if (error != 0)
+ return 0;
+
+ error = fdtbus_regulator_set_voltage(sc->sc_reg_vqmmc, uvol, uvol);
+ if (error != 0)
+ return error;
+
+ return fdtbus_regulator_enable(sc->sc_reg_vqmmc);
+}
+
+static int
+mesongx_mmc_execute_tuning(sdmmc_chipset_handle_t sch, int timing)
+{
+ switch (timing) {
+ case SDMMC_TIMING_MMC_HS200:
+ break;
+ default:
+ return EINVAL;
+ }
+
+ return 0;
+}
+
+static int
+mesongx_mmc_dma_prepare(struct mesongx_mmc_softc *sc, struct sdmmc_command *cmd, uint32_t cmdflags)
+{
+ struct mesongx_mmc_desc *dma = sc->sc_desc_desc;
+ bus_dmamap_t map = cmd->c_dmamap;
+ u_int xferlen, blen, resid;
+ bus_size_t off;
+ uint32_t flags;
+ int desc, seg;
+
+ if (cmd->c_blklen > 512) {
+ device_printf(sc->sc_dev, "block length %d not supported\n", cmd->c_blklen);
+ return EINVAL;
+ }
+
+ for (seg = 0; seg < map->dm_nsegs; seg++) {
+ if (map->dm_segs[seg].ds_len % cmd->c_blklen != 0) {
+ /* Force DMA bounce for unaligned transfers */
+ map = NULL;
+ break;
+ }
+ }
+
+ if (map == NULL) {
+ map = sc->sc_dmabounce_map;
+ cmd->c_flags |= SCF_NEED_BOUNCE;
+
+ if ((cmd->c_flags & SCF_CMD_READ) != 0) {
+ memset(sc->sc_dmabounce_buf, 0, cmd->c_datalen);
+ bus_dmamap_sync(sc->sc_dmat, sc->sc_dmabounce_map,
+ 0, cmd->c_datalen, BUS_DMASYNC_PREREAD);
+ } else {
+ memcpy(sc->sc_dmabounce_buf, cmd->c_data, cmd->c_datalen);
+ bus_dmamap_sync(sc->sc_dmat, sc->sc_dmabounce_map,
+ 0, cmd->c_datalen, BUS_DMASYNC_PREWRITE);
+ }
+ }
+
+ desc = 0;
+ for (seg = 0; seg < map->dm_nsegs; seg++) {
+ bus_addr_t paddr = map->dm_segs[seg].ds_addr;
+ bus_size_t len = map->dm_segs[seg].ds_len;
+ resid = uimin(len, cmd->c_resid);
+ off = 0;
+ while (resid > 0) {
+ if (desc == sc->sc_desc_ndesc)
+ break;
+
+ flags = cmdflags;
+
+ if (resid >= cmd->c_blklen) {
+ xferlen = (resid / cmd->c_blklen) * cmd->c_blklen;
+ blen = xferlen / cmd->c_blklen;
+ flags |= MESONGX_MMC_FLAGS_BLOCK_MODE;
+ } else {
+ blen = xferlen = resid;
+ }
+ KASSERT(xferlen > 0);
+ KASSERT(blen <= 512);
+
+ flags |= __SHIFTIN(blen % 512, MESONGX_MMC_FLAGS_LENGTH);
+ if (desc > 0)
+ flags |= MESONGX_MMC_FLAGS_NO_CMD;
+ if (cmd->c_resid == xferlen)
+ flags |= MESONGX_MMC_FLAGS_END_OF_CHAIN;
+
+ dma[desc].flags = htole32(flags);
+ dma[desc].arg = htole32(cmd->c_arg);
+ dma[desc].data = htole32(paddr + off);
+ dma[desc].resp = 0;
+
+ cmd->c_resid -= xferlen;
+ resid -= xferlen;
+ off += xferlen;
+
+ if (cmd->c_resid == 0)
+ break;
+
+ ++desc;
+ }
+ }
+ if (desc == sc->sc_desc_ndesc) {
+ device_printf(sc->sc_dev,
+ "not enough descriptors for %d byte transfer (%d segs)!\n",
+ cmd->c_datalen, map->dm_nsegs);
+ return EIO;
+ }
+
+ bus_dmamap_sync(sc->sc_dmat, sc->sc_desc_map, 0,
+ sc->sc_desc_size, BUS_DMASYNC_PREWRITE);
+
+ return 0;
+}
+
+static void
+mesongx_mmc_dma_complete(struct mesongx_mmc_softc *sc, struct sdmmc_command *cmd)
+{
+ bus_dmamap_sync(sc->sc_dmat, sc->sc_desc_map, 0,
+ sc->sc_desc_size, BUS_DMASYNC_POSTWRITE);
+
+ if ((cmd->c_flags & SCF_NEED_BOUNCE) != 0) {
+ if ((cmd->c_flags & SCF_CMD_READ) != 0) {
+ bus_dmamap_sync(sc->sc_dmat, sc->sc_dmabounce_map,
+ 0, cmd->c_datalen, BUS_DMASYNC_POSTREAD);
+ memcpy(cmd->c_data, sc->sc_dmabounce_buf, cmd->c_datalen);
+ } else {
+ bus_dmamap_sync(sc->sc_dmat, sc->sc_dmabounce_map,
+ 0, cmd->c_datalen, BUS_DMASYNC_POSTWRITE);
+ }
+ }
+}
+
+static void
+mesongx_mmc_exec_command(sdmmc_chipset_handle_t sch, struct sdmmc_command *cmd)
+{
+ struct mesongx_mmc_softc *sc = sch;
+ uint32_t cmdflags, val;
+ int error;
+
+ const uint32_t irq_mask = IRQ_EN_RESP_STATUS |
+ IRQ_EN_END_OF_CHAIN |
+ IRQ_EN_DESC_TIMEOUT |
+ IRQ_EN_RESP_TIMEOUT |
+ IRQ_EN_RESP_ERR |
+ IRQ_EN_DESC_ERR |
+ IRQ_EN_TXD_ERR |
+ IRQ_EN_RXD_ERR;
+
+ mutex_enter(&sc->sc_intr_lock);
+
+ while (sc->sc_cmd != NULL)
+ cv_wait(&sc->sc_intr_cv, &sc->sc_intr_lock);
+ sc->sc_cmd = cmd;
+
+ MMC_WRITE(sc, SD_EMMC_START, 0);
+ MMC_WRITE(sc, SD_EMMC_STATUS, MMC_READ(sc, SD_EMMC_STATUS));
+
+ val = MMC_READ(sc, SD_EMMC_IRQ_EN);
+ MMC_WRITE(sc, SD_EMMC_IRQ_EN, val | irq_mask);
+
+ cmdflags = MESONGX_MMC_FLAGS_OWNER;
+ cmdflags |= __SHIFTIN(12, MESONGX_MMC_FLAGS_TIMEOUT); /* 2^12 = 4096 ms timeout */
+ cmdflags |= __SHIFTIN(cmd->c_opcode, MESONGX_MMC_FLAGS_CMD_INDEX);
+
+ if ((cmd->c_flags & SCF_RSP_PRESENT) == 0) {
+ cmdflags |= MESONGX_MMC_FLAGS_NO_RESP;
+ } else {
+ cmdflags |= MESONGX_MMC_FLAGS_RESP_NUM;
+ if ((cmd->c_flags & SCF_RSP_136) != 0)
+ cmdflags |= MESONGX_MMC_FLAGS_RESP_128;
+ if ((cmd->c_flags & SCF_RSP_CRC) == 0)
+ cmdflags |= MESONGX_MMC_FLAGS_RESP_NOCRC;
+ if (__SHIFTOUT(cmd->c_flags, SCF_RSP_MASK) == SCF_RSP_R1B)
+ cmdflags |= MESONGX_MMC_FLAGS_R1B;
+ }
+
+ if (cmd->c_datalen > 0) {
+ cmdflags |= MESONGX_MMC_FLAGS_DATA_IO;
+ if ((cmd->c_flags & SCF_CMD_READ) == 0)
+ cmdflags |= MESONGX_MMC_FLAGS_DATA_WR;
+
+ val = MMC_READ(sc, SD_EMMC_CFG);
+ val &= ~CFG_BL_LEN;
+ val |= __SHIFTIN(ilog2(cmd->c_blklen), CFG_BL_LEN);
+ MMC_WRITE(sc, SD_EMMC_CFG, val);
+
+ cmd->c_resid = cmd->c_datalen;
+ cmd->c_error = mesongx_mmc_dma_prepare(sc, cmd, cmdflags);
+ if (cmd->c_error != 0)
+ goto done;
+
+ const bus_addr_t desc_paddr = sc->sc_desc_map->dm_segs[0].ds_addr;
+ MMC_WRITE(sc, SD_EMMC_START, desc_paddr | START_DESC_BUSY); /* starts transfer */
+ } else {
+ MMC_WRITE(sc, SD_EMMC_CMD_CFG, cmdflags | MESONGX_MMC_FLAGS_END_OF_CHAIN);
+ MMC_WRITE(sc, SD_EMMC_CMD_DAT, 0);
+ MMC_WRITE(sc, SD_EMMC_CMD_ARG, cmd->c_arg); /* starts transfer */
+ }
+
+ struct bintime timeout = { .sec = 5, .frac = 0 };
+ const struct bintime epsilon = { .sec = 1, .frac = 0 };
+
+ while ((cmd->c_flags & SCF_ITSDONE) == 0 && cmd->c_error == 0) {
+ error = cv_timedwaitbt(&sc->sc_intr_cv, &sc->sc_intr_lock, &timeout, &epsilon);
+ if (error != 0) {
+ cmd->c_error = error;
+ goto done;
+ }
+ }
+
+ if (cmd->c_error == 0 && cmd->c_datalen > 0)
+ mesongx_mmc_dma_complete(sc, cmd);
+
+done:
+ MMC_WRITE(sc, SD_EMMC_START, 0);
+
+ val = MMC_READ(sc, SD_EMMC_IRQ_EN);
+ MMC_WRITE(sc, SD_EMMC_IRQ_EN, val & ~irq_mask);
+
+ sc->sc_cmd = NULL;
+ cv_broadcast(&sc->sc_intr_cv);
+
+#ifdef MESONGX_MMC_DEBUG
+ if (cmd->c_error != 0) {
+ for (u_int reg = 0x00; reg < 0x100; reg += 0x10) {
+ device_printf(sc->sc_dev, " %02x: %08x %08x %08x %08x\n", reg,
+ MMC_READ(sc, reg + 0),
+ MMC_READ(sc, reg + 4),
+ MMC_READ(sc, reg + 8),
+ MMC_READ(sc, reg + 12));
+ }
+ }
+#endif
+
+ mutex_exit(&sc->sc_intr_lock);
+}
+
+static void
+mesongx_mmc_card_enable_intr(sdmmc_chipset_handle_t sch, int enable)
+{
+ struct mesongx_mmc_softc * const sc = sch;
+ uint32_t val;
+
+ mutex_enter(&sc->sc_intr_lock);
+
+ val = MMC_READ(sc, SD_EMMC_IRQ_EN);
+ MMC_WRITE(sc, SD_EMMC_IRQ_EN, val | IRQ_EN_IRQ_SDIO);
+
+ mutex_exit(&sc->sc_intr_lock);
+}
+
+static void
+mesongx_mmc_card_intr_ack(sdmmc_chipset_handle_t sch)
+{
+ struct mesongx_mmc_softc *sc = sch;
+
+ MMC_WRITE(sc, SD_EMMC_STATUS, STATUS_IRQ_SDIO);
+}
Index: src/sys/arch/arm/amlogic/mesongxbb_aoclkc.c
diff -u /dev/null src/sys/arch/arm/amlogic/mesongxbb_aoclkc.c:1.1
--- /dev/null Mon Feb 25 19:30:17 2019
+++ src/sys/arch/arm/amlogic/mesongxbb_aoclkc.c Mon Feb 25 19:30:17 2019
@@ -0,0 +1,110 @@
+/* $NetBSD: mesongxbb_aoclkc.c,v 1.1 2019/02/25 19:30:17 jmcneill Exp $ */
+
+/*-
+ * Copyright (c) 2019 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: mesongxbb_aoclkc.c,v 1.1 2019/02/25 19:30:17 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/amlogic/meson_clk.h>
+#include <arm/amlogic/mesongxbb_aoclkc.h>
+
+#define AO_RTI_GEN_CTNL_REG0 0x40
+
+#define GATE_PARENT "mpeg-clk"
+
+static int mesongxbb_aoclkc_match(device_t, cfdata_t, void *);
+static void mesongxbb_aoclkc_attach(device_t, device_t, void *);
+
+static const char * const compatible[] = {
+ "amlogic,meson-gxbb-aoclkc",
+ NULL
+};
+
+CFATTACH_DECL_NEW(mesongxbb_aoclkc, sizeof(struct meson_clk_softc),
+ mesongxbb_aoclkc_match, mesongxbb_aoclkc_attach, NULL, NULL);
+
+static struct meson_clk_reset mesongxbb_aoclkc_resets[] = {
+ MESON_CLK_RESET(MESONGXBB_RESET_AO_REMOTE, AO_RTI_GEN_CTNL_REG0, 16),
+ MESON_CLK_RESET(MESONGXBB_RESET_AO_UART1, AO_RTI_GEN_CTNL_REG0, 17),
+ MESON_CLK_RESET(MESONGXBB_RESET_AO_I2C_MASTER, AO_RTI_GEN_CTNL_REG0, 18),
+ MESON_CLK_RESET(MESONGXBB_RESET_AO_I2C_SLAVE, AO_RTI_GEN_CTNL_REG0, 19),
+ MESON_CLK_RESET(MESONGXBB_RESET_AO_UART2, AO_RTI_GEN_CTNL_REG0, 22),
+ MESON_CLK_RESET(MESONGXBB_RESET_AO_IR_BLASTER, AO_RTI_GEN_CTNL_REG0, 23),
+};
+
+static struct meson_clk_clk mesongxbb_aoclkc_clks[] = {
+ MESON_CLK_GATE(MESONGXBB_CLOCK_AO_REMOTE, "remote_ao", GATE_PARENT, AO_RTI_GEN_CTNL_REG0, 0),
+ MESON_CLK_GATE(MESONGXBB_CLOCK_AO_I2C_MASTER, "i2c_master_ao", GATE_PARENT, AO_RTI_GEN_CTNL_REG0, 1),
+ MESON_CLK_GATE(MESONGXBB_CLOCK_AO_I2C_SLAVE, "i2c_slave_ao", GATE_PARENT, AO_RTI_GEN_CTNL_REG0, 2),
+ MESON_CLK_GATE(MESONGXBB_CLOCK_AO_UART1, "uart1_ao", GATE_PARENT, AO_RTI_GEN_CTNL_REG0, 3),
+ MESON_CLK_GATE(MESONGXBB_CLOCK_AO_UART2, "uart2_ao", GATE_PARENT, AO_RTI_GEN_CTNL_REG0, 5),
+ MESON_CLK_GATE(MESONGXBB_CLOCK_AO_IR_BLASTER, "ir_blaster_ao", GATE_PARENT, AO_RTI_GEN_CTNL_REG0, 6),
+};
+
+static int
+mesongxbb_aoclkc_match(device_t parent, cfdata_t cf, void *aux)
+{
+ struct fdt_attach_args * const faa = aux;
+
+ return of_match_compatible(faa->faa_phandle, compatible);
+}
+
+static void
+mesongxbb_aoclkc_attach(device_t parent, device_t self, void *aux)
+{
+ struct meson_clk_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_syscon = fdtbus_syscon_lookup(OF_parent(sc->sc_phandle));
+ if (sc->sc_syscon == NULL) {
+ aprint_error(": couldn't get syscon registers\n");
+ return;
+ }
+
+ sc->sc_resets = mesongxbb_aoclkc_resets;
+ sc->sc_nresets = __arraycount(mesongxbb_aoclkc_resets);
+
+ sc->sc_clks = mesongxbb_aoclkc_clks;
+ sc->sc_nclks = __arraycount(mesongxbb_aoclkc_clks);
+
+ meson_clk_attach(sc);
+
+ aprint_naive("\n");
+ aprint_normal(": Meson GXBB AO clock controller\n");
+
+ meson_clk_print(sc);
+}
Index: src/sys/arch/arm/amlogic/mesongxbb_aoclkc.h
diff -u /dev/null src/sys/arch/arm/amlogic/mesongxbb_aoclkc.h:1.1
--- /dev/null Mon Feb 25 19:30:17 2019
+++ src/sys/arch/arm/amlogic/mesongxbb_aoclkc.h Mon Feb 25 19:30:17 2019
@@ -0,0 +1,47 @@
+/* $NetBSD: mesongxbb_aoclkc.h,v 1.1 2019/02/25 19:30:17 jmcneill Exp $ */
+
+/*-
+ * Copyright (c) 2019 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 _MESONGXBB_AOCLKC_H
+#define _MESONGXBB_AOCLKC_H
+
+#define MESONGXBB_RESET_AO_REMOTE 0
+#define MESONGXBB_RESET_AO_I2C_MASTER 1
+#define MESONGXBB_RESET_AO_I2C_SLAVE 2
+#define MESONGXBB_RESET_AO_UART1 3
+#define MESONGXBB_RESET_AO_UART2 4
+#define MESONGXBB_RESET_AO_IR_BLASTER 5
+
+#define MESONGXBB_CLOCK_AO_REMOTE 0
+#define MESONGXBB_CLOCK_AO_I2C_MASTER 1
+#define MESONGXBB_CLOCK_AO_I2C_SLAVE 2
+#define MESONGXBB_CLOCK_AO_UART1 3
+#define MESONGXBB_CLOCK_AO_UART2 4
+#define MESONGXBB_CLOCK_AO_IR_BLASTER 5
+#define MESONGXBB_CLOCK_CEC_32K 6
+
+#endif /* _MESONGXBB_AOCLKC_H */
Index: src/sys/arch/arm/amlogic/mesongxbb_clkc.c
diff -u /dev/null src/sys/arch/arm/amlogic/mesongxbb_clkc.c:1.1
--- /dev/null Mon Feb 25 19:30:17 2019
+++ src/sys/arch/arm/amlogic/mesongxbb_clkc.c Mon Feb 25 19:30:17 2019
@@ -0,0 +1,244 @@
+/* $NetBSD: mesongxbb_clkc.c,v 1.1 2019/02/25 19:30:17 jmcneill Exp $ */
+
+/*-
+ * Copyright (c) 2019 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: mesongxbb_clkc.c,v 1.1 2019/02/25 19:30:17 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/amlogic/meson_clk.h>
+#include <arm/amlogic/mesongxbb_clkc.h>
+
+#define CBUS_REG(x) ((x) << 2)
+
+#define HHI_GCLK_MPEG0 CBUS_REG(0x50)
+#define HHI_GCLK_MPEG1 CBUS_REG(0x51)
+#define HHI_GCLK_MPEG2 CBUS_REG(0x52)
+#define HHI_GCLK_OTHER CBUS_REG(0x54)
+#define HHI_SYS_CPU_CLK_CNTL1 CBUS_REG(0x57)
+#define HHI_MPEG_CLK_CNTL CBUS_REG(0x5d)
+#define HHI_NAND_CLK_CNTL CBUS_REG(0x97)
+#define HHI_SD_EMMC_CLK_CNTL CBUS_REG(0x99)
+#define HHI_MPLL_CNTL CBUS_REG(0xa0)
+#define HHI_MPLL_CNTL2 CBUS_REG(0xa1)
+#define HHI_MPLL_CNTL5 CBUS_REG(0xa4)
+#define HHI_MPLL_CNTL6 CBUS_REG(0xa5)
+#define HHI_MPLL_CNTL7 CBUS_REG(0xa6)
+#define HHI_MPLL_CNTL8 CBUS_REG(0xa7)
+#define HHI_MPLL_CNTL9 CBUS_REG(0xa8)
+#define HHI_SYS_PLL_CNTL CBUS_REG(0xc0)
+#define HHI_SYS_PLL_CNTL_LOCK __BIT(31)
+#define HHI_SYS_PLL_CNTL_OD __BITS(17,16)
+#define HHI_SYS_PLL_CNTL_DIV __BITS(14,9)
+#define HHI_SYS_PLL_CNTL_MUL __BITS(8,0)
+
+static int mesongxbb_clkc_match(device_t, cfdata_t, void *);
+static void mesongxbb_clkc_attach(device_t, device_t, void *);
+
+static const char * const compatible[] = {
+ "amlogic,gxbb-clkc",
+ NULL
+};
+
+CFATTACH_DECL_NEW(mesongxbb_clkc, sizeof(struct meson_clk_softc),
+ mesongxbb_clkc_match, mesongxbb_clkc_attach, NULL, NULL);
+
+static const char *mpeg_sel_parents[] = { "xtal", NULL, "fclk_div7", "mpll1", "mpll2", "fclk_div4", "fclk_div3", "fclk_div5" };
+static const char *sd_emmc_clk0_sel_parents[] = { "xtal", "fclk_div2", "fclk_div3", "fclk_div5", "fclk_div7" };
+
+static struct meson_clk_clk mesongxbb_clkc_clks[] = {
+
+ MESON_CLK_PLL(MESONGXBB_CLOCK_SYS_PLL_DCO, "pll_sys_dco", "xtal",
+ MESON_CLK_PLL_REG(HHI_SYS_PLL_CNTL, __BIT(30)), /* enable */
+ MESON_CLK_PLL_REG(HHI_SYS_PLL_CNTL, __BITS(8,0)), /* m */
+ MESON_CLK_PLL_REG(HHI_SYS_PLL_CNTL, __BITS(13,9)), /* n */
+ MESON_CLK_PLL_REG_INVALID, /* frac */
+ MESON_CLK_PLL_REG(HHI_SYS_PLL_CNTL, __BIT(31)), /* l */
+ MESON_CLK_PLL_REG(HHI_SYS_PLL_CNTL, __BIT(29)), /* reset */
+ 0),
+
+ MESON_CLK_DIV(MESONGXBB_CLOCK_SYS_PLL, "sys_pll", "pll_sys_dco",
+ HHI_SYS_PLL_CNTL, /* reg */
+ __BITS(17,16), /* div */
+ MESON_CLK_DIV_POWER_OF_TWO | MESON_CLK_DIV_SET_RATE_PARENT),
+
+ MESON_CLK_PLL(MESONGXBB_CLOCK_FIXED_PLL_DCO, "pll_fixed_dco", "xtal",
+ MESON_CLK_PLL_REG(HHI_MPLL_CNTL, __BIT(30)), /* enable */
+ MESON_CLK_PLL_REG(HHI_MPLL_CNTL, __BITS(8,0)), /* m */
+ MESON_CLK_PLL_REG(HHI_MPLL_CNTL, __BITS(13,9)), /* n */
+ MESON_CLK_PLL_REG(HHI_MPLL_CNTL2, __BITS(11,0)), /* frac */
+ MESON_CLK_PLL_REG(HHI_MPLL_CNTL, __BIT(31)), /* l */
+ MESON_CLK_PLL_REG(HHI_MPLL_CNTL, __BIT(29)), /* reset */
+ 0),
+
+ MESON_CLK_DIV(MESONGXBB_CLOCK_FIXED_PLL, "pll_fixed", "pll_fixed_dco",
+ HHI_MPLL_CNTL, /* reg */
+ __BITS(17,16), /* div */
+ MESON_CLK_DIV_POWER_OF_TWO),
+
+ MESON_CLK_DIV(MESONGXBB_CLOCK_MPLL_PREDIV, "mpll_prediv", "pll_fixed",
+ HHI_MPLL_CNTL5, /* reg */
+ __BIT(12), /* div */
+ 0),
+
+ MESON_CLK_MPLL(MESONGXBB_CLOCK_MPLL0_DIV, "mpll0_div", "mpll_prediv",
+ MESON_CLK_PLL_REG(HHI_MPLL_CNTL7, __BITS(13,0)), /* sdm */
+ MESON_CLK_PLL_REG(HHI_MPLL_CNTL7, __BIT(15)), /* sdm_enable */
+ MESON_CLK_PLL_REG(HHI_MPLL_CNTL7, __BITS(24,16)), /* n2 */
+ MESON_CLK_PLL_REG(HHI_MPLL_CNTL, __BIT(25)), /* ssen */
+ 0),
+ MESON_CLK_MPLL(MESONGXBB_CLOCK_MPLL1_DIV, "mpll1_div", "mpll_prediv",
+ MESON_CLK_PLL_REG(HHI_MPLL_CNTL8, __BITS(13,0)), /* sdm */
+ MESON_CLK_PLL_REG(HHI_MPLL_CNTL8, __BIT(15)), /* sdm_enable */
+ MESON_CLK_PLL_REG(HHI_MPLL_CNTL8, __BITS(24,16)), /* n2 */
+ MESON_CLK_PLL_REG_INVALID, /* ssen */
+ 0),
+ MESON_CLK_MPLL(MESONGXBB_CLOCK_MPLL2_DIV, "mpll2_div", "mpll_prediv",
+ MESON_CLK_PLL_REG(HHI_MPLL_CNTL8, __BITS(13,0)), /* sdm */
+ MESON_CLK_PLL_REG(HHI_MPLL_CNTL8, __BIT(15)), /* sdm_enable */
+ MESON_CLK_PLL_REG(HHI_MPLL_CNTL8, __BITS(24,16)), /* n2 */
+ MESON_CLK_PLL_REG_INVALID, /* ssen */
+ 0),
+
+ MESON_CLK_GATE(MESONGXBB_CLOCK_MPLL0, "mpll0", "mpll0_div", HHI_MPLL_CNTL7, 14),
+ MESON_CLK_GATE(MESONGXBB_CLOCK_MPLL1, "mpll1", "mpll1_div", HHI_MPLL_CNTL8, 14),
+ MESON_CLK_GATE(MESONGXBB_CLOCK_MPLL2, "mpll2", "mpll2_div", HHI_MPLL_CNTL9, 14),
+
+ MESON_CLK_FIXED_FACTOR(MESONGXBB_CLOCK_FCLK_DIV2_DIV, "fclk_div2_div", "pll_fixed", 2, 1),
+ MESON_CLK_FIXED_FACTOR(MESONGXBB_CLOCK_FCLK_DIV3_DIV, "fclk_div3_div", "pll_fixed", 3, 1),
+ MESON_CLK_FIXED_FACTOR(MESONGXBB_CLOCK_FCLK_DIV4_DIV, "fclk_div4_div", "pll_fixed", 4, 1),
+ MESON_CLK_FIXED_FACTOR(MESONGXBB_CLOCK_FCLK_DIV5_DIV, "fclk_div5_div", "pll_fixed", 5, 1),
+ MESON_CLK_FIXED_FACTOR(MESONGXBB_CLOCK_FCLK_DIV7_DIV, "fclk_div7_div", "pll_fixed", 7, 1),
+
+ MESON_CLK_GATE(MESONGXBB_CLOCK_FCLK_DIV2, "fclk_div2", "fclk_div2_div", HHI_MPLL_CNTL6, 27),
+ MESON_CLK_GATE(MESONGXBB_CLOCK_FCLK_DIV3, "fclk_div3", "fclk_div3_div", HHI_MPLL_CNTL6, 28),
+ MESON_CLK_GATE(MESONGXBB_CLOCK_FCLK_DIV4, "fclk_div4", "fclk_div4_div", HHI_MPLL_CNTL6, 29),
+ MESON_CLK_GATE(MESONGXBB_CLOCK_FCLK_DIV5, "fclk_div5", "fclk_div5_div", HHI_MPLL_CNTL6, 30),
+ MESON_CLK_GATE(MESONGXBB_CLOCK_FCLK_DIV7, "fclk_div7", "fclk_div7_div", HHI_MPLL_CNTL6, 31),
+ MESON_CLK_MUX(MESONGXBB_CLOCK_MPEG_SEL, "mpeg_sel", mpeg_sel_parents,
+ HHI_MPEG_CLK_CNTL, /* reg */
+ __BITS(14,12), /* sel */
+ 0),
+
+ MESON_CLK_DIV(MESONGXBB_CLOCK_MPEG_DIV, "mpeg_div", "mpeg_sel",
+ HHI_MPEG_CLK_CNTL, /* reg */
+ __BITS(6,0), /* div */
+ 0),
+
+ MESON_CLK_MUX(MESONGXBB_CLOCK_SD_EMMC_A_CLK0_SEL, "sd_emmc_a_clk0_sel", sd_emmc_clk0_sel_parents,
+ HHI_SD_EMMC_CLK_CNTL, /* reg */
+ __BITS(11,9), /* sel */
+ 0),
+ MESON_CLK_MUX(MESONGXBB_CLOCK_SD_EMMC_B_CLK0_SEL, "sd_emmc_b_clk0_sel", sd_emmc_clk0_sel_parents,
+ HHI_SD_EMMC_CLK_CNTL, /* reg */
+ __BITS(27,25), /* sel */
+ 0),
+ MESON_CLK_MUX(MESONGXBB_CLOCK_SD_EMMC_C_CLK0_SEL, "sd_emmc_c_clk0_sel", sd_emmc_clk0_sel_parents,
+ HHI_NAND_CLK_CNTL, /* reg */
+ __BITS(11,9), /* sel */
+ 0),
+
+ MESON_CLK_DIV(MESONGXBB_CLOCK_SD_EMMC_A_CLK0_DIV, "sd_emmc_a_clk0_div", "sd_emmc_a_clk0_sel",
+ HHI_SD_EMMC_CLK_CNTL, /* reg */
+ __BITS(6,0), /* div */
+ 0),
+ MESON_CLK_DIV(MESONGXBB_CLOCK_SD_EMMC_B_CLK0_DIV, "sd_emmc_b_clk0_div", "sd_emmc_b_clk0_sel",
+ HHI_SD_EMMC_CLK_CNTL, /* reg */
+ __BITS(22,16), /* div */
+ 0),
+ MESON_CLK_DIV(MESONGXBB_CLOCK_SD_EMMC_C_CLK0_DIV, "sd_emmc_c_clk0_div", "sd_emmc_c_clk0_sel",
+ HHI_NAND_CLK_CNTL, /* reg */
+ __BITS(6,0), /* div */
+ 0),
+
+ MESON_CLK_GATE(MESONGXBB_CLOCK_SD_EMMC_A_CLK0, "sd_emmc_a_clk0", "sd_emmc_a_clk0_div", HHI_SD_EMMC_CLK_CNTL, 7),
+ MESON_CLK_GATE(MESONGXBB_CLOCK_SD_EMMC_B_CLK0, "sd_emmc_b_clk0", "sd_emmc_b_clk0_div", HHI_SD_EMMC_CLK_CNTL, 23),
+ MESON_CLK_GATE(MESONGXBB_CLOCK_SD_EMMC_C_CLK0, "sd_emmc_c_clk0", "sd_emmc_c_clk0_div", HHI_NAND_CLK_CNTL, 7),
+
+ MESON_CLK_GATE(MESONGXBB_CLOCK_CLK81, "clk81", "mpeg_div", HHI_MPEG_CLK_CNTL, 7),
+
+ MESON_CLK_GATE(MESONGXBB_CLOCK_I2C, "i2c", "clk81", HHI_GCLK_MPEG0, 9),
+ MESON_CLK_GATE(MESONGXBB_CLOCK_SAR_ADC, "sar_adc", "clk81", HHI_GCLK_MPEG0, 10),
+ MESON_CLK_GATE(MESONGXBB_CLOCK_RNG0, "rng0", "clk81", HHI_GCLK_MPEG0, 12),
+ MESON_CLK_GATE(MESONGXBB_CLOCK_UART0, "uart0", "clk81", HHI_GCLK_MPEG0, 13),
+ MESON_CLK_GATE(MESONGXBB_CLOCK_SDHC, "sdhc", "clk81", HHI_GCLK_MPEG0, 14),
+ MESON_CLK_GATE(MESONGXBB_CLOCK_SDIO, "sdio", "clk81", HHI_GCLK_MPEG0, 17),
+ MESON_CLK_GATE(MESONGXBB_CLOCK_SD_EMMC_A, "sd_emmc_a", "clk81", HHI_GCLK_MPEG0, 24),
+ MESON_CLK_GATE(MESONGXBB_CLOCK_SD_EMMC_B, "sd_emmc_b", "clk81", HHI_GCLK_MPEG0, 25),
+ MESON_CLK_GATE(MESONGXBB_CLOCK_SD_EMMC_C, "sd_emmc_c", "clk81", HHI_GCLK_MPEG0, 26),
+
+ MESON_CLK_GATE(MESONGXBB_CLOCK_ETH, "eth", "clk81", HHI_GCLK_MPEG1, 3),
+ MESON_CLK_GATE(MESONGXBB_CLOCK_UART1, "uart1", "clk81", HHI_GCLK_MPEG1, 16),
+ MESON_CLK_GATE(MESONGXBB_CLOCK_USB0, "usb0", "clk81", HHI_GCLK_MPEG1, 21),
+ MESON_CLK_GATE(MESONGXBB_CLOCK_USB1, "usb1", "clk81", HHI_GCLK_MPEG1, 22),
+ MESON_CLK_GATE(MESONGXBB_CLOCK_USB, "usb", "clk81", HHI_GCLK_MPEG1, 26),
+ MESON_CLK_GATE(MESONGXBB_CLOCK_EFUSE, "efuse", "clk81", HHI_GCLK_MPEG1, 30),
+
+ MESON_CLK_GATE(MESONGXBB_CLOCK_USB1_DDR_BRIDGE, "usb1_ddr_bridge", "clk81", HHI_GCLK_MPEG2, 8),
+ MESON_CLK_GATE(MESONGXBB_CLOCK_USB0_DDR_BRIDGE, "usb0_ddr_bridge", "clk81", HHI_GCLK_MPEG2, 9),
+ MESON_CLK_GATE(MESONGXBB_CLOCK_UART2, "uart2", "clk81", HHI_GCLK_MPEG2, 15),
+};
+
+static int
+mesongxbb_clkc_match(device_t parent, cfdata_t cf, void *aux)
+{
+ struct fdt_attach_args * const faa = aux;
+
+ return of_match_compatible(faa->faa_phandle, compatible);
+}
+
+static void
+mesongxbb_clkc_attach(device_t parent, device_t self, void *aux)
+{
+ struct meson_clk_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_syscon = fdtbus_syscon_lookup(OF_parent(sc->sc_phandle));
+ if (sc->sc_syscon == NULL) {
+ aprint_error(": couldn't get syscon registers\n");
+ return;
+ }
+
+ sc->sc_clks = mesongxbb_clkc_clks;
+ sc->sc_nclks = __arraycount(mesongxbb_clkc_clks);
+
+ meson_clk_attach(sc);
+
+ aprint_naive("\n");
+ aprint_normal(": Meson GXBB clock controller\n");
+
+ meson_clk_print(sc);
+}
Index: src/sys/arch/arm/amlogic/mesongxbb_clkc.h
diff -u /dev/null src/sys/arch/arm/amlogic/mesongxbb_clkc.h:1.1
--- /dev/null Mon Feb 25 19:30:17 2019
+++ src/sys/arch/arm/amlogic/mesongxbb_clkc.h Mon Feb 25 19:30:17 2019
@@ -0,0 +1,198 @@
+/* $NetBSD: mesongxbb_clkc.h,v 1.1 2019/02/25 19:30:17 jmcneill Exp $ */
+
+/*-
+ * Copyright (c) 2019 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 _MESONGXBB_CLKC_H
+#define _MESONGXBB_CLKC_H
+
+#define MESONGXBB_CLOCK_SYS_PLL 0
+#define MESONGXBB_CLOCK_HDMI_PLL 2
+#define MESONGXBB_CLOCK_FIXED_PLL 3
+#define MESONGXBB_CLOCK_FCLK_DIV2 4
+#define MESONGXBB_CLOCK_FCLK_DIV3 5
+#define MESONGXBB_CLOCK_FCLK_DIV4 6
+#define MESONGXBB_CLOCK_FCLK_DIV5 7
+#define MESONGXBB_CLOCK_FCLK_DIV7 8
+#define MESONGXBB_CLOCK_GP0_PLL 9
+#define MESONGXBB_CLOCK_MPEG_SEL 10
+#define MESONGXBB_CLOCK_MPEG_DIV 11
+#define MESONGXBB_CLOCK_CLK81 12
+#define MESONGXBB_CLOCK_MPLL0 13
+#define MESONGXBB_CLOCK_MPLL1 14
+#define MESONGXBB_CLOCK_MPLL2 15
+#define MESONGXBB_CLOCK_DDR 16
+#define MESONGXBB_CLOCK_DOS 17
+#define MESONGXBB_CLOCK_ISA 18
+#define MESONGXBB_CLOCK_PL301 19
+#define MESONGXBB_CLOCK_PERIPHS 20
+#define MESONGXBB_CLOCK_SPICC 21
+#define MESONGXBB_CLOCK_I2C 22
+#define MESONGXBB_CLOCK_SAR_ADC 23
+#define MESONGXBB_CLOCK_SMART_CARD 24
+#define MESONGXBB_CLOCK_RNG0 25
+#define MESONGXBB_CLOCK_UART0 26
+#define MESONGXBB_CLOCK_SDHC 27
+#define MESONGXBB_CLOCK_STREAM 28
+#define MESONGXBB_CLOCK_ASYNC_FIFO 29
+#define MESONGXBB_CLOCK_SDIO 30
+#define MESONGXBB_CLOCK_ABUF 31
+#define MESONGXBB_CLOCK_HIU_IFACE 32
+#define MESONGXBB_CLOCK_ASSIST_MISC 33
+#define MESONGXBB_CLOCK_SPI 34
+#define MESONGXBB_CLOCK_I2S_SPDIF 35
+#define MESONGXBB_CLOCK_ETH 36
+#define MESONGXBB_CLOCK_DEMUX 37
+#define MESONGXBB_CLOCK_AIU_GLUE 38
+#define MESONGXBB_CLOCK_IEC958 39
+#define MESONGXBB_CLOCK_I2S_OUT 40
+#define MESONGXBB_CLOCK_AMCLK 41
+#define MESONGXBB_CLOCK_AIFIFO2 42
+#define MESONGXBB_CLOCK_MIXER 43
+#define MESONGXBB_CLOCK_MIXER_IFACE 44
+#define MESONGXBB_CLOCK_ADC 45
+#define MESONGXBB_CLOCK_BLKMV 46
+#define MESONGXBB_CLOCK_AIU 47
+#define MESONGXBB_CLOCK_UART1 48
+#define MESONGXBB_CLOCK_G2D 49
+#define MESONGXBB_CLOCK_USB0 50
+#define MESONGXBB_CLOCK_USB1 51
+#define MESONGXBB_CLOCK_RESET 52
+#define MESONGXBB_CLOCK_NAND 53
+#define MESONGXBB_CLOCK_DOS_PARSER 54
+#define MESONGXBB_CLOCK_USB 55
+#define MESONGXBB_CLOCK_VDIN1 56
+#define MESONGXBB_CLOCK_AHB_ARB0 57
+#define MESONGXBB_CLOCK_EFUSE 58
+#define MESONGXBB_CLOCK_BOOT_ROM 59
+#define MESONGXBB_CLOCK_AHB_DATA_BUS 60
+#define MESONGXBB_CLOCK_AHB_CTRL_BUS 61
+#define MESONGXBB_CLOCK_HDMI_INTR_SYNC 62
+#define MESONGXBB_CLOCK_HDMI_PCLK 63
+#define MESONGXBB_CLOCK_USB1_DDR_BRIDGE 64
+#define MESONGXBB_CLOCK_USB0_DDR_BRIDGE 65
+#define MESONGXBB_CLOCK_MMC_PCLK 66
+#define MESONGXBB_CLOCK_DVIN 67
+#define MESONGXBB_CLOCK_UART2 68
+#define MESONGXBB_CLOCK_SANA 69
+#define MESONGXBB_CLOCK_VPU_INTR 70
+#define MESONGXBB_CLOCK_SEC_AHB_AHB3_BRIDGE 71
+#define MESONGXBB_CLOCK_CLK81_A53 72
+#define MESONGXBB_CLOCK_VCLK2_VENCI0 73
+#define MESONGXBB_CLOCK_VCLK2_VENCI1 74
+#define MESONGXBB_CLOCK_VCLK2_VENCP0 75
+#define MESONGXBB_CLOCK_VCLK2_VENCP1 76
+#define MESONGXBB_CLOCK_GCLK_VENCI_INT0 77
+#define MESONGXBB_CLOCK_GCLK_VENCI_INT 78
+#define MESONGXBB_CLOCK_DAC_CLK 79
+#define MESONGXBB_CLOCK_AOCLK_GATE 80
+#define MESONGXBB_CLOCK_IEC958_GATE 81
+#define MESONGXBB_CLOCK_ENC480P 82
+#define MESONGXBB_CLOCK_RNG1 83
+#define MESONGXBB_CLOCK_GCLK_VENCI_INT1 84
+#define MESONGXBB_CLOCK_VCLK2_VENCLMCC 85
+#define MESONGXBB_CLOCK_VCLK2_VENCL 86
+#define MESONGXBB_CLOCK_VCLK_OTHER 87
+#define MESONGXBB_CLOCK_EDP 88
+#define MESONGXBB_CLOCK_AO_MEDIA_CPU 89
+#define MESONGXBB_CLOCK_AO_AHB_SRAM 90
+#define MESONGXBB_CLOCK_AO_AHB_BUS 91
+#define MESONGXBB_CLOCK_AO_IFACE 92
+#define MESONGXBB_CLOCK_AO_I2C 93
+#define MESONGXBB_CLOCK_SD_EMMC_A 94
+#define MESONGXBB_CLOCK_SD_EMMC_B 95
+#define MESONGXBB_CLOCK_SD_EMMC_C 96
+#define MESONGXBB_CLOCK_SAR_ADC_CLK 97
+#define MESONGXBB_CLOCK_SAR_ADC_SEL 98
+#define MESONGXBB_CLOCK_SAR_ADC_DIV 99
+#define MESONGXBB_CLOCK_MALI_0_SEL 100
+#define MESONGXBB_CLOCK_MALI_0_DIV 101
+#define MESONGXBB_CLOCK_MALI_0 102
+#define MESONGXBB_CLOCK_MALI_1_SEL 103
+#define MESONGXBB_CLOCK_MALI_1_DIV 104
+#define MESONGXBB_CLOCK_MALI_1 105
+#define MESONGXBB_CLOCK_MALI 106
+#define MESONGXBB_CLOCK_CTS_AMCLK 107
+#define MESONGXBB_CLOCK_CTS_AMCLK_SEL 108
+#define MESONGXBB_CLOCK_CTS_AMCLK_DIV 109
+#define MESONGXBB_CLOCK_CTS_MCLK_I958 110
+#define MESONGXBB_CLOCK_CTS_MCLK_I958_SEL 111
+#define MESONGXBB_CLOCK_CTS_MCLK_I958_DIV 112
+#define MESONGXBB_CLOCK_CTS_I958 113
+#define MESONGXBB_CLOCK_32K_CLK 114
+#define MESONGXBB_CLOCK_32K_CLK_SEL 115
+#define MESONGXBB_CLOCK_32K_CLK_DIV 116
+#define MESONGXBB_CLOCK_SD_EMMC_A_CLK0_SEL 117
+#define MESONGXBB_CLOCK_SD_EMMC_A_CLK0_DIV 118
+#define MESONGXBB_CLOCK_SD_EMMC_A_CLK0 119
+#define MESONGXBB_CLOCK_SD_EMMC_B_CLK0_SEL 120
+#define MESONGXBB_CLOCK_SD_EMMC_B_CLK0_DIV 121
+#define MESONGXBB_CLOCK_SD_EMMC_B_CLK0 122
+#define MESONGXBB_CLOCK_SD_EMMC_C_CLK0_SEL 123
+#define MESONGXBB_CLOCK_SD_EMMC_C_CLK0_DIV 124
+#define MESONGXBB_CLOCK_SD_EMMC_C_CLK0 125
+#define MESONGXBB_CLOCK_VPU_0_SEL 126
+#define MESONGXBB_CLOCK_VPU_0_DIV 127
+#define MESONGXBB_CLOCK_VPU_0 128
+#define MESONGXBB_CLOCK_VPU_1_SEL 129
+#define MESONGXBB_CLOCK_VPU_1_DIV 130
+#define MESONGXBB_CLOCK_VPU_1 131
+#define MESONGXBB_CLOCK_VPU 132
+#define MESONGXBB_CLOCK_VAPB_0_SEL 133
+#define MESONGXBB_CLOCK_VAPB_0_DIV 134
+#define MESONGXBB_CLOCK_VAPB_0 135
+#define MESONGXBB_CLOCK_VAPB_1_SEL 136
+#define MESONGXBB_CLOCK_VAPB_1_DIV 137
+#define MESONGXBB_CLOCK_VAPB_1 138
+#define MESONGXBB_CLOCK_VAPB_SEL 139
+#define MESONGXBB_CLOCK_VAPB 140
+#define MESONGXBB_CLOCK_HDMI_PLL_PRE_MULT 141
+#define MESONGXBB_CLOCK_MPLL0_DIV 142
+#define MESONGXBB_CLOCK_MPLL1_DIV 143
+#define MESONGXBB_CLOCK_MPLL2_DIV 144
+#define MESONGXBB_CLOCK_MPLL_PREDIV 145
+#define MESONGXBB_CLOCK_FCLK_DIV2_DIV 146
+#define MESONGXBB_CLOCK_FCLK_DIV3_DIV 147
+#define MESONGXBB_CLOCK_FCLK_DIV4_DIV 148
+#define MESONGXBB_CLOCK_FCLK_DIV5_DIV 149
+#define MESONGXBB_CLOCK_FCLK_DIV7_DIV 150
+#define MESONGXBB_CLOCK_VDEC_1_SEL 151
+#define MESONGXBB_CLOCK_VDEC_1_DIV 152
+#define MESONGXBB_CLOCK_VDEC_1 153
+#define MESONGXBB_CLOCK_VDEC_HEVC_SEL 154
+#define MESONGXBB_CLOCK_VDEC_HEVC_DIV 155
+#define MESONGXBB_CLOCK_VDEC_HEVC 156
+#define MESONGXBB_CLOCK_GEN_CLK_SEL 157
+#define MESONGXBB_CLOCK_GEN_CLK_DIV 158
+#define MESONGXBB_CLOCK_GEN_CLK 159
+#define MESONGXBB_CLOCK_FIXED_PLL_DCO 160
+#define MESONGXBB_CLOCK_HDMI_PLL_DCO 161
+#define MESONGXBB_CLOCK_HDMI_PLL_OD 162
+#define MESONGXBB_CLOCK_HDMI_PLL_OD2 163
+#define MESONGXBB_CLOCK_SYS_PLL_DCO 164
+#define MESONGXBB_CLOCK_GP0_PLL_DCO 165
+
+#endif /* _MESONGXBB_CLKC_H */
Index: src/sys/arch/arm/amlogic/mesongxbb_pinctrl.c
diff -u /dev/null src/sys/arch/arm/amlogic/mesongxbb_pinctrl.c:1.1
--- /dev/null Mon Feb 25 19:30:17 2019
+++ src/sys/arch/arm/amlogic/mesongxbb_pinctrl.c Mon Feb 25 19:30:17 2019
@@ -0,0 +1,519 @@
+/* $NetBSD: mesongxbb_pinctrl.c,v 1.1 2019/02/25 19:30:17 jmcneill Exp $ */
+
+/*-
+ * Copyright (c) 2019 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: mesongxbb_pinctrl.c,v 1.1 2019/02/25 19:30:17 jmcneill Exp $");
+
+#include <sys/param.h>
+
+#include <arm/amlogic/meson_pinctrl.h>
+
+/* CBUS pinmux registers */
+#define CBUS_REG(n) ((n) << 2)
+#define REG0 CBUS_REG(0)
+#define REG1 CBUS_REG(1)
+#define REG2 CBUS_REG(2)
+#define REG3 CBUS_REG(3)
+#define REG4 CBUS_REG(4)
+#define REG5 CBUS_REG(5)
+#define REG6 CBUS_REG(6)
+#define REG7 CBUS_REG(7)
+#define REG8 CBUS_REG(8)
+#define REG9 CBUS_REG(9)
+
+/* AO pinmux registers */
+#define AOREG0 0x00
+#define AOREG1 0x04
+
+/*
+ * GPIO banks. The values must match those in dt-bindings/gpio/meson-gxbb-gpio.h
+ */
+enum {
+ GPIOZ_0 = 0,
+ GPIOZ_1,
+ GPIOZ_2,
+ GPIOZ_3,
+ GPIOZ_4,
+ GPIOZ_5,
+ GPIOZ_6,
+ GPIOZ_7,
+ GPIOZ_8,
+ GPIOZ_9,
+ GPIOZ_10,
+ GPIOZ_11,
+ GPIOZ_12,
+ GPIOZ_13,
+ GPIOZ_14,
+ GPIOZ_15,
+
+ GPIOH_0 = 16,
+ GPIOH_1,
+ GPIOH_2,
+ GPIOH_3,
+
+ BOOT_0 = 20,
+ BOOT_1,
+ BOOT_2,
+ BOOT_3,
+ BOOT_4,
+ BOOT_5,
+ BOOT_6,
+ BOOT_7,
+ BOOT_8,
+ BOOT_9,
+ BOOT_10,
+ BOOT_11,
+ BOOT_12,
+ BOOT_13,
+ BOOT_14,
+ BOOT_15,
+ BOOT_16,
+ BOOT_17,
+
+ CARD_0 = 38,
+ CARD_1,
+ CARD_2,
+ CARD_3,
+ CARD_4,
+ CARD_5,
+ CARD_6,
+
+ GPIODV_0 = 45,
+ GPIODV_1,
+ GPIODV_2,
+ GPIODV_3,
+ GPIODV_4,
+ GPIODV_5,
+ GPIODV_6,
+ GPIODV_7,
+ GPIODV_8,
+ GPIODV_9,
+ GPIODV_10,
+ GPIODV_11,
+ GPIODV_12,
+ GPIODV_13,
+ GPIODV_14,
+ GPIODV_15,
+ GPIODV_16,
+ GPIODV_17,
+ GPIODV_18,
+ GPIODV_19,
+ GPIODV_20,
+ GPIODV_21,
+ GPIODV_22,
+ GPIODV_23,
+ GPIODV_24,
+ GPIODV_25,
+ GPIODV_26,
+ GPIODV_27,
+ GPIODV_28,
+ GPIODV_29,
+
+ GPIOY_0 = 75,
+ GPIOY_1,
+ GPIOY_2,
+ GPIOY_3,
+ GPIOY_4,
+ GPIOY_5,
+ GPIOY_6,
+ GPIOY_7,
+ GPIOY_8,
+ GPIOY_9,
+ GPIOY_10,
+ GPIOY_11,
+ GPIOY_12,
+ GPIOY_13,
+ GPIOY_14,
+ GPIOY_15,
+ GPIOY_16,
+
+ GPIOX_0 = 92,
+ GPIOX_1,
+ GPIOX_2,
+ GPIOX_3,
+ GPIOX_4,
+ GPIOX_5,
+ GPIOX_6,
+ GPIOX_7,
+ GPIOX_8,
+ GPIOX_9,
+ GPIOX_10,
+ GPIOX_11,
+ GPIOX_12,
+ GPIOX_13,
+ GPIOX_14,
+ GPIOX_15,
+ GPIOX_16,
+ GPIOX_17,
+ GPIOX_18,
+ GPIOX_19,
+ GPIOX_20,
+ GPIOX_21,
+ GPIOX_22,
+
+ GPIOCLK_0 = 115,
+ GPIOCLK_1,
+ GPIOCLK_2,
+ GPIOCLK_3,
+
+ GPIOAO_0 = 0,
+ GPIOAO_1,
+ GPIOAO_2,
+ GPIOAO_3,
+ GPIOAO_4,
+ GPIOAO_5,
+ GPIOAO_6,
+ GPIOAO_7,
+ GPIOAO_8,
+ GPIOAO_9,
+ GPIOAO_10,
+ GPIOAO_11,
+ GPIOAO_12,
+ GPIOAO_13,
+ GPIO_TEST_N,
+};
+
+#define CBUS_GPIO(_id, _off, _bit) \
+ [_id] = { \
+ .id = (_id), \
+ .name = __STRING(_id), \
+ .oen = { \
+ .type = MESON_PINCTRL_REGTYPE_GPIO, \
+ .reg = CBUS_REG((_off) * 3 + 0), \
+ .mask = __BIT(_bit) \
+ }, \
+ .out = { \
+ .type = MESON_PINCTRL_REGTYPE_GPIO, \
+ .reg = CBUS_REG((_off) * 3 + 1), \
+ .mask = __BIT(_bit) \
+ }, \
+ .in = { \
+ .type = MESON_PINCTRL_REGTYPE_GPIO, \
+ .reg = CBUS_REG((_off) * 3 + 2), \
+ .mask = __BIT(_bit) \
+ }, \
+ .pupden = { \
+ .type = MESON_PINCTRL_REGTYPE_PULL_ENABLE, \
+ .reg = CBUS_REG(_off), \
+ .mask = __BIT(_bit) \
+ }, \
+ .pupd = { \
+ .type = MESON_PINCTRL_REGTYPE_PULL, \
+ .reg = CBUS_REG(_off), \
+ .mask = __BIT(_bit) \
+ }, \
+ }
+
+static const struct meson_pinctrl_gpio mesongxbb_periphs_gpios[] = {
+ /* GPIODV */
+ CBUS_GPIO(GPIODV_0, 0, 0),
+ CBUS_GPIO(GPIODV_1, 0, 1),
+ CBUS_GPIO(GPIODV_2, 0, 2),
+ CBUS_GPIO(GPIODV_3, 0, 3),
+ CBUS_GPIO(GPIODV_4, 0, 4),
+ CBUS_GPIO(GPIODV_5, 0, 5),
+ CBUS_GPIO(GPIODV_6, 0, 6),
+ CBUS_GPIO(GPIODV_7, 0, 7),
+ CBUS_GPIO(GPIODV_8, 0, 8),
+ CBUS_GPIO(GPIODV_9, 0, 9),
+ CBUS_GPIO(GPIODV_10, 0, 10),
+ CBUS_GPIO(GPIODV_11, 0, 11),
+ CBUS_GPIO(GPIODV_12, 0, 12),
+ CBUS_GPIO(GPIODV_13, 0, 13),
+ CBUS_GPIO(GPIODV_14, 0, 14),
+ CBUS_GPIO(GPIODV_15, 0, 15),
+ CBUS_GPIO(GPIODV_16, 0, 16),
+ CBUS_GPIO(GPIODV_17, 0, 17),
+ CBUS_GPIO(GPIODV_18, 0, 18),
+ CBUS_GPIO(GPIODV_19, 0, 19),
+ CBUS_GPIO(GPIODV_20, 0, 20),
+ CBUS_GPIO(GPIODV_21, 0, 21),
+ CBUS_GPIO(GPIODV_22, 0, 22),
+
+ /* GPIOH */
+ CBUS_GPIO(GPIOH_0, 1, 0),
+ CBUS_GPIO(GPIOH_1, 1, 1),
+ CBUS_GPIO(GPIOH_2, 1, 2),
+ CBUS_GPIO(GPIOH_3, 1, 3),
+
+ /* BOOT */
+ CBUS_GPIO(BOOT_0, 2, 0),
+ CBUS_GPIO(BOOT_1, 2, 1),
+ CBUS_GPIO(BOOT_2, 2, 2),
+ CBUS_GPIO(BOOT_3, 2, 3),
+ CBUS_GPIO(BOOT_4, 2, 4),
+ CBUS_GPIO(BOOT_5, 2, 5),
+ CBUS_GPIO(BOOT_6, 2, 6),
+ CBUS_GPIO(BOOT_7, 2, 7),
+ CBUS_GPIO(BOOT_8, 2, 8),
+ CBUS_GPIO(BOOT_9, 2, 9),
+ CBUS_GPIO(BOOT_10, 2, 10),
+ CBUS_GPIO(BOOT_11, 2, 11),
+ CBUS_GPIO(BOOT_12, 2, 12),
+ CBUS_GPIO(BOOT_13, 2, 13),
+ CBUS_GPIO(BOOT_14, 2, 14),
+ CBUS_GPIO(BOOT_15, 2, 15),
+ CBUS_GPIO(BOOT_16, 2, 16),
+ CBUS_GPIO(BOOT_17, 2, 17),
+
+ /* CARD */
+ CBUS_GPIO(CARD_0, 2, 20),
+ CBUS_GPIO(CARD_1, 2, 21),
+ CBUS_GPIO(CARD_2, 2, 22),
+ CBUS_GPIO(CARD_3, 2, 23),
+ CBUS_GPIO(CARD_4, 2, 24),
+ CBUS_GPIO(CARD_5, 2, 25),
+ CBUS_GPIO(CARD_6, 2, 26),
+
+ /* CARD */
+ CBUS_GPIO(GPIOCLK_0, 3, 28),
+ CBUS_GPIO(GPIOCLK_1, 3, 29),
+ CBUS_GPIO(GPIOCLK_2, 3, 30),
+ CBUS_GPIO(GPIOCLK_3, 3, 31),
+
+ /* GPIOX */
+ CBUS_GPIO(GPIOX_0, 4, 0),
+ CBUS_GPIO(GPIOX_1, 4, 1),
+ CBUS_GPIO(GPIOX_2, 4, 2),
+ CBUS_GPIO(GPIOX_3, 4, 3),
+ CBUS_GPIO(GPIOX_4, 4, 4),
+ CBUS_GPIO(GPIOX_5, 4, 5),
+ CBUS_GPIO(GPIOX_6, 4, 6),
+ CBUS_GPIO(GPIOX_7, 4, 7),
+ CBUS_GPIO(GPIOX_8, 4, 8),
+ CBUS_GPIO(GPIOX_9, 4, 9),
+ CBUS_GPIO(GPIOX_10, 4, 10),
+ CBUS_GPIO(GPIOX_11, 4, 11),
+ CBUS_GPIO(GPIOX_12, 4, 12),
+ CBUS_GPIO(GPIOX_13, 4, 13),
+ CBUS_GPIO(GPIOX_14, 4, 14),
+ CBUS_GPIO(GPIOX_15, 4, 15),
+ CBUS_GPIO(GPIOX_16, 4, 16),
+ CBUS_GPIO(GPIOX_17, 4, 17),
+ CBUS_GPIO(GPIOX_18, 4, 18),
+ CBUS_GPIO(GPIOX_19, 4, 19),
+ CBUS_GPIO(GPIOX_20, 4, 20),
+ CBUS_GPIO(GPIOX_21, 4, 21),
+ CBUS_GPIO(GPIOX_22, 4, 22),
+};
+
+#define AO_GPIO(_id, _bit) \
+ [_id] = { \
+ .id = (_id), \
+ .name = __STRING(_id), \
+ .oen = { \
+ .type = MESON_PINCTRL_REGTYPE_GPIO, \
+ .reg = 0, \
+ .mask = __BIT(_bit) \
+ }, \
+ .out = { \
+ .type = MESON_PINCTRL_REGTYPE_GPIO, \
+ .reg = 0, \
+ .mask = __BIT(_bit + 16) \
+ }, \
+ .in = { \
+ .type = MESON_PINCTRL_REGTYPE_GPIO, \
+ .reg = 4, \
+ .mask = __BIT(_bit) \
+ }, \
+ .pupden = { \
+ .type = MESON_PINCTRL_REGTYPE_PULL, \
+ .reg = 0, \
+ .mask = __BIT(_bit) \
+ }, \
+ .pupd = { \
+ .type = MESON_PINCTRL_REGTYPE_PULL, \
+ .reg = 0, \
+ .mask = __BIT(_bit + 16) \
+ }, \
+ }
+
+static const struct meson_pinctrl_gpio mesongxbb_aobus_gpios[] = {
+ /* GPIOAO */
+ AO_GPIO(GPIOAO_0, 0),
+ AO_GPIO(GPIOAO_1, 1),
+ AO_GPIO(GPIOAO_2, 2),
+ AO_GPIO(GPIOAO_3, 3),
+ AO_GPIO(GPIOAO_4, 4),
+ AO_GPIO(GPIOAO_5, 5),
+ AO_GPIO(GPIOAO_6, 6),
+ AO_GPIO(GPIOAO_7, 7),
+ AO_GPIO(GPIOAO_8, 8),
+ AO_GPIO(GPIOAO_9, 9),
+ AO_GPIO(GPIOAO_10, 10),
+ AO_GPIO(GPIOAO_11, 11),
+ AO_GPIO(GPIOAO_12, 12),
+ AO_GPIO(GPIOAO_13, 13),
+};
+
+static const struct meson_pinctrl_group mesongxbb_periphs_groups[] = {
+ /* GPIOX */
+ { "sdio_d0", REG8, 5, { GPIOX_0 }, 1 },
+ { "sdio_d1", REG8, 4, { GPIOX_1 }, 1 },
+ { "sdio_d2", REG8, 3, { GPIOX_2 }, 1 },
+ { "sdio_d3", REG8, 2, { GPIOX_3 }, 1 },
+ { "sdio_cmd", REG8, 1, { GPIOX_4 }, 1 },
+ { "sdio_clk", REG8, 0, { GPIOX_5 }, 1 },
+ { "sdio_irq", REG8, 11, { GPIOX_7 }, 1 },
+ { "uart_tx_a", REG4, 13, { GPIOX_12 }, 1 },
+ { "uart_rx_a", REG4, 12, { GPIOX_13 }, 1 },
+ { "uart_cts_a", REG4, 11, { GPIOX_14 }, 1 },
+ { "uart_rts_a", REG4, 10, { GPIOX_15 }, 1 },
+ { "pwm_a_x", REG3, 17, { GPIOX_6 }, 1 },
+ { "pwm_e", REG2, 30, { GPIOX_19 }, 1 },
+ { "pwm_f_x", REG3, 18, { GPIOX_7 }, 1 },
+
+ /* GPIOY */
+ { "uart_cts_c", REG1, 19, { GPIOY_11 }, 1 },
+ { "uart_rts_c", REG1, 18, { GPIOY_12 }, 1 },
+ { "uart_tx_c", REG1, 17, { GPIOY_13 }, 1 },
+ { "uart_rx_c", REG1, 16, { GPIOY_14 }, 1 },
+ { "pwm_a_y", REG1, 21, { GPIOY_16 }, 1 },
+ { "pwm_f_y", REG1, 20, { GPIOY_15 }, 1 },
+ { "i2s_out_ch23_y", REG1, 5, { GPIOY_8 }, 1 },
+ { "i2s_out_ch45_y", REG1, 6, { GPIOY_9 }, 1 },
+ { "i2s_out_ch67_y", REG1, 7, { GPIOY_10 }, 1 },
+ { "spdif_out_y", REG1, 9, { GPIOY_12 }, 1 },
+ { "gen_clk_out", REG6, 15, { GPIOY_15 }, 1 },
+
+ /* GPIOZ */
+ { "eth_mdio", REG6, 1, { GPIOZ_0 }, 1 },
+ { "eth_mdc", REG6, 0, { GPIOZ_1 }, 1 },
+ { "eth_clk_rx_clk", REG6, 13, { GPIOZ_2 }, 1 },
+ { "eth_rx_dv", REG6, 12, { GPIOZ_3 }, 1 },
+ { "eth_rxd0", REG6, 11, { GPIOZ_4 }, 1 },
+ { "eth_rxd1", REG6, 10, { GPIOZ_5 }, 1 },
+ { "eth_rxd2", REG6, 9, { GPIOZ_6 }, 1 },
+ { "eth_rxd3", REG6, 8, { GPIOZ_7 }, 1 },
+ { "eth_rgmii_tx_clk", REG6, 7, { GPIOZ_8 }, 1 },
+ { "eth_tx_en", REG6, 6, { GPIOZ_9 }, 1 },
+ { "eth_txd0", REG6, 5, { GPIOZ_10 }, 1 },
+ { "eth_txd1", REG6, 4, { GPIOZ_11 }, 1 },
+ { "eth_txd2", REG6, 3, { GPIOZ_12 }, 1 },
+ { "eth_txd3", REG6, 2, { GPIOZ_13 }, 1 },
+ { "spi_ss0", REG5, 26, { GPIOZ_7 }, 1 },
+ { "spi_sclk", REG5, 27, { GPIOZ_6 }, 1 },
+ { "spi_miso", REG5, 28, { GPIOZ_12 }, 1 },
+ { "spi_mosi", REG5, 29, { GPIOZ_13 }, 1 },
+
+ /* GPIOH */
+ { "hdmi_hpd", REG1, 26, { GPIOH_0 }, 1 },
+ { "hdmi_sda", REG1, 25, { GPIOH_1 }, 1 },
+ { "hdmi_scl", REG1, 24, { GPIOH_2 }, 1 },
+
+ /* GPIODV */
+ { "uart_tx_b", REG2, 29, { GPIODV_24 }, 1 },
+ { "uart_rx_b", REG2, 28, { GPIODV_25 }, 1 },
+ { "uart_cts_b", REG2, 27, { GPIODV_26 }, 1 },
+ { "uart_rts_b", REG2, 26, { GPIODV_27 }, 1 },
+ { "pwm_b", REG3, 21, { GPIODV_29 }, 1 },
+ { "pwm_d", REG3, 20, { GPIODV_28 }, 1 },
+ { "i2c_sck_a", REG7, 27, { GPIODV_25 }, 1 },
+ { "i2c_sda_a", REG7, 26, { GPIODV_24 }, 1 },
+ { "i2c_sck_b", REG7, 25, { GPIODV_27 }, 1 },
+ { "i2c_sda_b", REG7, 24, { GPIODV_26 }, 1 },
+ { "i2c_sck_c", REG7, 23, { GPIODV_29 }, 1 },
+ { "i2c_sda_c", REG7, 22, { GPIODV_28 }, 1 },
+
+ /* BOOT */
+ { "emmc_nand_d07", REG4, 30, { BOOT_0, BOOT_1, BOOT_2, BOOT_3, BOOT_4, BOOT_5, BOOT_6, BOOT_7 }, 8 },
+ { "emmc_clk", REG4, 18, { BOOT_8 }, 1 },
+ { "emmc_cmd", REG4, 19, { BOOT_10 }, 1 },
+ { "emmc_ds", REG4, 31, { BOOT_15 }, 1 },
+ { "nor_d", REG5, 1, { BOOT_11 }, 1 },
+ { "nor_q", REG5, 3, { BOOT_12 }, 1 },
+ { "nor_c", REG5, 2, { BOOT_13 }, 1 },
+ { "nor_cs", REG5, 0, { BOOT_15 }, 1 },
+ { "nand_ce0", REG4, 26, { BOOT_8 }, 1 },
+ { "nand_ce1", REG4, 27, { BOOT_9 }, 1 },
+ { "nand_rb0", REG4, 25, { BOOT_10 }, 1 },
+ { "nand_ale", REG4, 24, { BOOT_11 }, 1 },
+ { "nand_cle", REG4, 23, { BOOT_12 }, 1 },
+ { "nand_wen_clk", REG4, 22, { BOOT_13 }, 1 },
+ { "nand_ren_wr", REG4, 21, { BOOT_14 }, 1 },
+ { "nand_dqs", REG4, 20, { BOOT_15 }, 1 },
+
+ /* CARD */
+ { "sdcard_d1", REG2, 14, { CARD_0 }, 1 },
+ { "sdcard_d0", REG2, 15, { CARD_1 }, 1 },
+ { "sdcard_d3", REG2, 12, { CARD_4 }, 1 },
+ { "sdcard_d2", REG2, 13, { CARD_5 }, 1 },
+ { "sdcard_cmd", REG2, 10, { CARD_3 }, 1 },
+ { "sdcard_clk", REG2, 11, { CARD_2 }, 1 },
+};
+
+static const struct meson_pinctrl_group mesongxbb_aobus_groups[] = {
+ /* GPIOAO */
+ { "uart_tx_ao_b", AOREG0, 24, { GPIOAO_4 }, 1 },
+ { "uart_rx_ao_b", AOREG0, 25, { GPIOAO_5 }, 1 },
+ { "uart_tx_ao_a", AOREG0, 12, { GPIOAO_0 }, 1 },
+ { "uart_rx_ao_a", AOREG0, 11, { GPIOAO_1 }, 1 },
+ { "uart_cts_ao_a", AOREG0, 10, { GPIOAO_2 }, 1 },
+ { "uart_rts_ao_a", AOREG0, 9, { GPIOAO_3 }, 1 },
+ { "uart_cts_ao_b", AOREG0, 8, { GPIOAO_2 }, 1 },
+ { "uart_rts_ao_b", AOREG0, 7, { GPIOAO_3 }, 1 },
+ { "i2c_sck_ao", AOREG0, 6, { GPIOAO_4 }, 1 },
+ { "i2c_sda_ao", AOREG0, 5, { GPIOAO_5 }, 1 },
+ { "i2c_slave_sck_ao", AOREG0, 2, { GPIOAO_4 }, 1 },
+ { "i2c_slave_sda_ao", AOREG0, 1, { GPIOAO_5 }, 1 },
+ { "remote_input_ao", AOREG0, 0, { GPIOAO_7 }, 1 },
+ { "pwm_ao_a_3", AOREG0, 22, { GPIOAO_3 }, 1 },
+ { "pwm_ao_a_6", AOREG0, 18, { GPIOAO_6 }, 1 },
+ { "pwm_ao_a_12", AOREG0, 17, { GPIOAO_12 }, 1 },
+ { "pwm_ao_b", AOREG0, 3, { GPIOAO_13 }, 1 },
+ { "i2s_am_clk", AOREG0, 30, { GPIOAO_8 }, 1 },
+ { "i2s_out_ao_clk", AOREG0, 29, { GPIOAO_9 }, 1 },
+ { "i2s_out_lr_clk", AOREG0, 28, { GPIOAO_10 }, 1 },
+ { "i2s_out_ch01_ao", AOREG0, 27, { GPIOAO_11 }, 1 },
+ { "i2s_out_ch23_ao", AOREG1, 0, { GPIOAO_12 }, 1 },
+ { "i2s_out_ch45_ao", AOREG1, 1, { GPIOAO_13 }, 1 },
+ { "spdif_out_ao_6", AOREG0, 16, { GPIOAO_6 }, 1 },
+ { "spdif_out_ao_13", AOREG0, 4, { GPIOAO_13 }, 1 },
+ { "ao_cec", AOREG0, 15, { GPIOAO_12 }, 1 },
+ { "ee_cec", AOREG0, 14, { GPIOAO_12 }, 1 },
+
+ /* TEST_N */
+ { "i2s_out_ch67_ao", AOREG1, 2, { GPIO_TEST_N }, 1 },
+
+};
+
+const struct meson_pinctrl_config mesongxbb_periphs_pinctrl_config = {
+ .name = "Meson GXBB periphs GPIO",
+ .groups = mesongxbb_periphs_groups,
+ .ngroups = __arraycount(mesongxbb_periphs_groups),
+ .gpios = mesongxbb_periphs_gpios,
+ .ngpios = __arraycount(mesongxbb_periphs_gpios),
+};
+
+const struct meson_pinctrl_config mesongxbb_aobus_pinctrl_config = {
+ .name = "Meson GXBB AO GPIO",
+ .groups = mesongxbb_aobus_groups,
+ .ngroups = __arraycount(mesongxbb_aobus_groups),
+ .gpios = mesongxbb_aobus_gpios,
+ .ngpios = __arraycount(mesongxbb_aobus_gpios),
+};