Page Menu
Home
FreeBSD
Search
Configure Global Search
Log In
Files
F136750204
D5280.diff
No One
Temporary
Actions
View File
Edit File
Delete File
View Transforms
Subscribe
Mute Notifications
Flag For Later
Award Token
Size
125 KB
Referenced Files
None
Subscribers
None
D5280.diff
View Options
Index: sys/arm/allwinner/a10/a10_ahci.c
===================================================================
--- sys/arm/allwinner/a10/a10_ahci.c
+++ sys/arm/allwinner/a10/a10_ahci.c
@@ -48,7 +48,7 @@
#include <dev/ofw/ofw_bus_subr.h>
#include <dev/ahci/ahci.h>
-#include <arm/allwinner/a10_clk.h>
+#include <arm/allwinner/a10/a10_clk.h>
#include "gpio_if.h"
/*
Index: sys/arm/allwinner/a10/a10_timer.c
===================================================================
--- sys/arm/allwinner/a10/a10_timer.c
+++ sys/arm/allwinner/a10/a10_timer.c
@@ -50,7 +50,7 @@
#include <sys/kdb.h>
-#include <arm/allwinner/allwinner_machdep.h>
+#include <arm/allwinner/aw_machdep.h>
/**
* Timer registers addr
Index: sys/arm/allwinner/a10/files.a10
===================================================================
--- /dev/null
+++ sys/arm/allwinner/a10/files.a10
@@ -0,0 +1,4 @@
+# $FreeBSD$
+
+arm/allwinner/a10/a10_intc.c standard
+arm/allwinner/a10/a10_timer.c standard
Index: sys/arm/allwinner/a10/std.a10
===================================================================
--- sys/arm/allwinner/a10/std.a10
+++ sys/arm/allwinner/a10/std.a10
@@ -11,4 +11,4 @@
options ARM_L2_PIPT
files "../allwinner/files.allwinner"
-files "../allwinner/files.a10"
+files "../allwinner/a10/files.a10"
Index: sys/arm/allwinner/a10_clk.h
===================================================================
--- /dev/null
+++ sys/arm/allwinner/a10_clk.h
@@ -1,176 +0,0 @@
-/*-
- * Copyright (c) 2013 Ganbold Tsagaankhuu <ganbold@freebsd.org>
- * 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 AND CONTRIBUTORS ``AS IS'' AND
- * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
- * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
- * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
- * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
- * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
- * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
- * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
- * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
- * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
- * SUCH DAMAGE.
- *
- * $FreeBSD$
- */
-
-#ifndef _A10_CLK_H_
-#define _A10_CLK_H_
-
-#define CCM_PLL1_CFG 0x0000
-#define CCM_PLL1_TUN 0x0004
-#define CCM_PLL2_CFG 0x0008
-#define CCM_PLL2_TUN 0x000c
-#define CCM_PLL3_CFG 0x0010
-#define CCM_PLL3_TUN 0x0014
-#define CCM_PLL4_CFG 0x0018
-#define CCM_PLL4_TUN 0x001c
-#define CCM_PLL5_CFG 0x0020
-#define CCM_PLL5_TUN 0x0024
-#define CCM_PLL6_CFG 0x0028
-#define CCM_PLL6_TUN 0x002c
-#define CCM_PLL7_CFG 0x0030
-#define CCM_PLL7_TUN 0x0034
-#define CCM_PLL1_TUN2 0x0038
-#define CCM_PLL5_TUN2 0x003c
-#define CCM_PLL_LOCK_DBG 0x004c
-#define CCM_OSC24M_CFG 0x0050
-#define CCM_CPU_AHB_APB0_CFG 0x0054
-#define CCM_APB1_CLK_DIV 0x0058
-#define CCM_AXI_GATING 0x005c
-#define CCM_AHB_GATING0 0x0060
-#define CCM_AHB_GATING1 0x0064
-#define CCM_APB0_GATING 0x0068
-#define CCM_APB1_GATING 0x006c
-#define CCM_NAND_SCLK_CFG 0x0080
-#define CCM_MS_SCLK_CFG 0x0084
-#define CCM_MMC0_SCLK_CFG 0x0088
-#define CCM_MMC1_SCLK_CFG 0x008c
-#define CCM_MMC2_SCLK_CFG 0x0090
-#define CCM_MMC3_SCLK_CFG 0x0094
-#define CCM_TS_CLK 0x0098
-#define CCM_SS_CLK 0x009c
-#define CCM_SPI0_CLK 0x00a0
-#define CCM_SPI1_CLK 0x00a4
-#define CCM_SPI2_CLK 0x00a8
-#define CCM_PATA_CLK 0x00ac
-#define CCM_IR0_CLK 0x00b0
-#define CCM_IR1_CLK 0x00b4
-#define CCM_IIS_CLK 0x00b8
-#define CCM_AC97_CLK 0x00bc
-#define CCM_SPDIF_CLK 0x00c0
-#define CCM_KEYPAD_CLK 0x00c4
-#define CCM_SATA_CLK 0x00c8
-#define CCM_USB_CLK 0x00cc
-#define CCM_GPS_CLK 0x00d0
-#define CCM_SPI3_CLK 0x00d4
-#define CCM_DRAM_CLK 0x0100
-#define CCM_BE0_SCLK 0x0104
-#define CCM_BE1_SCLK 0x0108
-#define CCM_FE0_CLK 0x010c
-#define CCM_FE1_CLK 0x0110
-#define CCM_MP_CLK 0x0114
-#define CCM_LCD0_CH0_CLK 0x0118
-#define CCM_LCD1_CH0_CLK 0x011c
-#define CCM_CSI_ISP_CLK 0x0120
-#define CCM_TVD_CLK 0x0128
-#define CCM_LCD0_CH1_CLK 0x012c
-#define CCM_LCD1_CH1_CLK 0x0130
-#define CCM_CS0_CLK 0x0134
-#define CCM_CS1_CLK 0x0138
-#define CCM_VE_CLK 0x013c
-#define CCM_AUDIO_CODEC_CLK 0x0140
-#define CCM_AVS_CLK 0x0144
-#define CCM_ACE_CLK 0x0148
-#define CCM_LVDS_CLK 0x014c
-#define CCM_HDMI_CLK 0x0150
-#define CCM_MALI400_CLK 0x0154
-#define CCM_GMAC_CLK 0x0164
-
-#define CCM_GMAC_CLK_DELAY_SHIFT 10
-#define CCM_GMAC_CLK_MODE_MASK 0x7
-#define CCM_GMAC_MODE_RGMII (1 << 2)
-#define CCM_GMAC_CLK_MII 0x0
-#define CCM_GMAC_CLK_EXT_RGMII 0x1
-#define CCM_GMAC_CLK_RGMII 0x2
-
-/* APB0_GATING */
-#define CCM_APB0_GATING_ADDA (1 << 0)
-
-/* AHB_GATING_REG0 */
-#define CCM_AHB_GATING_USB0 (1 << 0)
-#define CCM_AHB_GATING_EHCI0 (1 << 1)
-#define CCM_AHB_GATING_EHCI1 (1 << 3)
-#define CCM_AHB_GATING_DMA (1 << 6)
-#define CCM_AHB_GATING_SDMMC0 (1 << 8)
-#define CCM_AHB_GATING_EMAC (1 << 17)
-#define CCM_AHB_GATING_SATA (1 << 25)
-
-/* AHB_GATING_REG1 */
-#define CCM_AHB_GATING_GMAC (1 << 17)
-
-/* APB1_GATING_REG */
-#define CCM_APB1_GATING_TWI (1 << 0)
-
-#define CCM_USB_PHY (1 << 8)
-#define CCM_USB0_RESET (1 << 0)
-#define CCM_USB1_RESET (1 << 1)
-#define CCM_USB2_RESET (1 << 2)
-
-#define CCM_PLL_CFG_ENABLE (1U << 31)
-#define CCM_PLL_CFG_BYPASS (1U << 30)
-#define CCM_PLL_CFG_PLL5 (1U << 25)
-#define CCM_PLL_CFG_PLL6 (1U << 24)
-#define CCM_PLL_CFG_FACTOR_N 0x1f00
-#define CCM_PLL_CFG_FACTOR_N_SHIFT 8
-#define CCM_PLL_CFG_FACTOR_K 0x30
-#define CCM_PLL_CFG_FACTOR_K_SHIFT 4
-#define CCM_PLL_CFG_FACTOR_M 0x3
-
-#define CCM_PLL2_CFG_POSTDIV 0x3c000000
-#define CCM_PLL2_CFG_POSTDIV_SHIFT 26
-#define CCM_PLL2_CFG_PREDIV 0x1f
-#define CCM_PLL2_CFG_PREDIV_SHIFT 0
-
-#define CCM_PLL6_CFG_SATA_CLKEN (1U << 14)
-
-#define CCM_SD_CLK_SRC_SEL 0x3000000
-#define CCM_SD_CLK_SRC_SEL_SHIFT 24
-#define CCM_SD_CLK_SRC_SEL_OSC24M 0
-#define CCM_SD_CLK_SRC_SEL_PLL6 1
-#define CCM_SD_CLK_PHASE_CTR 0x700000
-#define CCM_SD_CLK_PHASE_CTR_SHIFT 20
-#define CCM_SD_CLK_DIV_RATIO_N 0x30000
-#define CCM_SD_CLK_DIV_RATIO_N_SHIFT 16
-#define CCM_SD_CLK_OPHASE_CTR 0x700
-#define CCM_SD_CLK_OPHASE_CTR_SHIFT 8
-#define CCM_SD_CLK_DIV_RATIO_M 0xf
-
-#define CCM_AUDIO_CODEC_ENABLE (1U << 31)
-
-#define CCM_CLK_REF_FREQ 24000000U
-
-int a10_clk_usb_activate(void);
-int a10_clk_usb_deactivate(void);
-int a10_clk_emac_activate(void);
-int a10_clk_gmac_activate(phandle_t);
-int a10_clk_ahci_activate(void);
-int a10_clk_mmc_activate(int);
-int a10_clk_mmc_cfg(int, int);
-int a10_clk_i2c_activate(int);
-int a10_clk_dmac_activate(void);
-int a10_clk_codec_activate(unsigned int);
-
-#endif /* _A10_CLK_H_ */
Index: sys/arm/allwinner/a10_clk.c
===================================================================
--- /dev/null
+++ sys/arm/allwinner/a10_clk.c
@@ -1,467 +0,0 @@
-/*-
- * Copyright (c) 2013 Ganbold Tsagaankhuu <ganbold@freebsd.org>
- * 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 AND CONTRIBUTORS ``AS IS'' AND
- * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
- * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
- * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
- * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
- * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
- * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
- * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
- * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
- * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
- * SUCH DAMAGE.
- */
-
-/* Simple clock driver for Allwinner A10 */
-
-#include <sys/cdefs.h>
-__FBSDID("$FreeBSD$");
-
-#include <sys/param.h>
-#include <sys/systm.h>
-#include <sys/bus.h>
-#include <sys/kernel.h>
-#include <sys/module.h>
-#include <sys/malloc.h>
-#include <sys/rman.h>
-#include <machine/bus.h>
-
-#include <dev/ofw/openfirm.h>
-#include <dev/ofw/ofw_bus_subr.h>
-
-#include "a10_clk.h"
-
-struct a10_ccm_softc {
- struct resource *res;
- bus_space_tag_t bst;
- bus_space_handle_t bsh;
- int pll6_enabled;
-};
-
-static struct a10_ccm_softc *a10_ccm_sc = NULL;
-
-#define ccm_read_4(sc, reg) \
- bus_space_read_4((sc)->bst, (sc)->bsh, (reg))
-#define ccm_write_4(sc, reg, val) \
- bus_space_write_4((sc)->bst, (sc)->bsh, (reg), (val))
-
-static int
-a10_ccm_probe(device_t dev)
-{
-
- if (!ofw_bus_status_okay(dev))
- return (ENXIO);
-
- if (ofw_bus_is_compatible(dev, "allwinner,sun4i-ccm")) {
- device_set_desc(dev, "Allwinner Clock Control Module");
- return(BUS_PROBE_DEFAULT);
- }
-
- return (ENXIO);
-}
-
-static int
-a10_ccm_attach(device_t dev)
-{
- struct a10_ccm_softc *sc = device_get_softc(dev);
- int rid = 0;
-
- if (a10_ccm_sc)
- return (ENXIO);
-
- sc->res = bus_alloc_resource_any(dev, SYS_RES_MEMORY, &rid, RF_ACTIVE);
- if (!sc->res) {
- device_printf(dev, "could not allocate resource\n");
- return (ENXIO);
- }
-
- sc->bst = rman_get_bustag(sc->res);
- sc->bsh = rman_get_bushandle(sc->res);
-
- a10_ccm_sc = sc;
-
- return (0);
-}
-
-static device_method_t a10_ccm_methods[] = {
- DEVMETHOD(device_probe, a10_ccm_probe),
- DEVMETHOD(device_attach, a10_ccm_attach),
- { 0, 0 }
-};
-
-static driver_t a10_ccm_driver = {
- "a10_ccm",
- a10_ccm_methods,
- sizeof(struct a10_ccm_softc),
-};
-
-static devclass_t a10_ccm_devclass;
-
-EARLY_DRIVER_MODULE(a10_ccm, simplebus, a10_ccm_driver, a10_ccm_devclass, 0, 0,
- BUS_PASS_TIMER + BUS_PASS_ORDER_MIDDLE);
-
-int
-a10_clk_usb_activate(void)
-{
- struct a10_ccm_softc *sc = a10_ccm_sc;
- uint32_t reg_value;
-
- if (sc == NULL)
- return (ENXIO);
-
- /* Gating AHB clock for USB */
- reg_value = ccm_read_4(sc, CCM_AHB_GATING0);
- reg_value |= CCM_AHB_GATING_USB0; /* AHB clock gate usb0 */
- reg_value |= CCM_AHB_GATING_EHCI0; /* AHB clock gate ehci0 */
- reg_value |= CCM_AHB_GATING_EHCI1; /* AHB clock gate ehci1 */
- ccm_write_4(sc, CCM_AHB_GATING0, reg_value);
-
- /* Enable clock for USB */
- reg_value = ccm_read_4(sc, CCM_USB_CLK);
- reg_value |= CCM_USB_PHY; /* USBPHY */
- reg_value |= CCM_USB0_RESET; /* disable reset for USB0 */
- reg_value |= CCM_USB1_RESET; /* disable reset for USB1 */
- reg_value |= CCM_USB2_RESET; /* disable reset for USB2 */
- ccm_write_4(sc, CCM_USB_CLK, reg_value);
-
- return (0);
-}
-
-int
-a10_clk_usb_deactivate(void)
-{
- struct a10_ccm_softc *sc = a10_ccm_sc;
- uint32_t reg_value;
-
- if (sc == NULL)
- return (ENXIO);
-
- /* Disable clock for USB */
- reg_value = ccm_read_4(sc, CCM_USB_CLK);
- reg_value &= ~CCM_USB_PHY; /* USBPHY */
- reg_value &= ~CCM_USB0_RESET; /* reset for USB0 */
- reg_value &= ~CCM_USB1_RESET; /* reset for USB1 */
- reg_value &= ~CCM_USB2_RESET; /* reset for USB2 */
- ccm_write_4(sc, CCM_USB_CLK, reg_value);
-
- /* Disable gating AHB clock for USB */
- reg_value = ccm_read_4(sc, CCM_AHB_GATING0);
- reg_value &= ~CCM_AHB_GATING_USB0; /* disable AHB clock gate usb0 */
- reg_value &= ~CCM_AHB_GATING_EHCI0; /* disable AHB clock gate ehci0 */
- reg_value &= ~CCM_AHB_GATING_EHCI1; /* disable AHB clock gate ehci1 */
- ccm_write_4(sc, CCM_AHB_GATING0, reg_value);
-
- return (0);
-}
-
-int
-a10_clk_emac_activate(void)
-{
- struct a10_ccm_softc *sc = a10_ccm_sc;
- uint32_t reg_value;
-
- if (sc == NULL)
- return (ENXIO);
-
- /* Gating AHB clock for EMAC */
- reg_value = ccm_read_4(sc, CCM_AHB_GATING0);
- reg_value |= CCM_AHB_GATING_EMAC;
- ccm_write_4(sc, CCM_AHB_GATING0, reg_value);
-
- return (0);
-}
-
-int
-a10_clk_gmac_activate(phandle_t node)
-{
- char *phy_type;
- struct a10_ccm_softc *sc;
- uint32_t reg_value;
-
- sc = a10_ccm_sc;
- if (sc == NULL)
- return (ENXIO);
-
- /* Gating AHB clock for GMAC */
- reg_value = ccm_read_4(sc, CCM_AHB_GATING1);
- reg_value |= CCM_AHB_GATING_GMAC;
- ccm_write_4(sc, CCM_AHB_GATING1, reg_value);
-
- /* Set GMAC mode. */
- reg_value = CCM_GMAC_CLK_MII;
- if (OF_getprop_alloc(node, "phy-mode", 1, (void **)&phy_type) > 0) {
- if (strcasecmp(phy_type, "rgmii") == 0)
- reg_value = CCM_GMAC_CLK_RGMII | CCM_GMAC_MODE_RGMII;
- else if (strcasecmp(phy_type, "rgmii-bpi") == 0) {
- reg_value = CCM_GMAC_CLK_RGMII | CCM_GMAC_MODE_RGMII;
- reg_value |= (3 << CCM_GMAC_CLK_DELAY_SHIFT);
- }
- free(phy_type, M_OFWPROP);
- }
- ccm_write_4(sc, CCM_GMAC_CLK, reg_value);
-
- return (0);
-}
-
-static void
-a10_clk_pll6_enable(void)
-{
- struct a10_ccm_softc *sc;
- uint32_t reg_value;
-
- /*
- * SATA needs PLL6 to be a 100MHz clock.
- * The SATA output frequency is 24MHz * n * k / m / 6.
- * To get to 100MHz, k & m must be equal and n must be 25.
- * For other uses the output frequency is 24MHz * n * k / 2.
- */
- sc = a10_ccm_sc;
- if (sc->pll6_enabled)
- return;
- reg_value = ccm_read_4(sc, CCM_PLL6_CFG);
- reg_value &= ~CCM_PLL_CFG_BYPASS;
- reg_value &= ~(CCM_PLL_CFG_FACTOR_K | CCM_PLL_CFG_FACTOR_M |
- CCM_PLL_CFG_FACTOR_N);
- reg_value |= (25 << CCM_PLL_CFG_FACTOR_N_SHIFT);
- reg_value |= CCM_PLL6_CFG_SATA_CLKEN;
- reg_value |= CCM_PLL_CFG_ENABLE;
- ccm_write_4(sc, CCM_PLL6_CFG, reg_value);
- sc->pll6_enabled = 1;
-}
-
-static unsigned int
-a10_clk_pll6_get_rate(void)
-{
- struct a10_ccm_softc *sc;
- uint32_t k, n, reg_value;
-
- sc = a10_ccm_sc;
- reg_value = ccm_read_4(sc, CCM_PLL6_CFG);
- n = ((reg_value & CCM_PLL_CFG_FACTOR_N) >> CCM_PLL_CFG_FACTOR_N_SHIFT);
- k = ((reg_value & CCM_PLL_CFG_FACTOR_K) >> CCM_PLL_CFG_FACTOR_K_SHIFT) +
- 1;
-
- return ((CCM_CLK_REF_FREQ * n * k) / 2);
-}
-
-static int
-a10_clk_pll2_set_rate(unsigned int freq)
-{
- struct a10_ccm_softc *sc;
- uint32_t reg_value;
- unsigned int prediv, postdiv, n;
-
- sc = a10_ccm_sc;
- if (sc == NULL)
- return (ENXIO);
-
- reg_value = ccm_read_4(sc, CCM_PLL2_CFG);
- reg_value &= ~(CCM_PLL2_CFG_PREDIV | CCM_PLL2_CFG_POSTDIV |
- CCM_PLL_CFG_FACTOR_N);
-
- /*
- * Audio Codec needs PLL2 to be either 24576000 Hz or 22579200 Hz
- *
- * PLL2 output frequency is 24MHz * n / prediv / postdiv.
- * To get as close as possible to the desired rate, we use a
- * pre-divider of 21 and a post-divider of 4. With these values,
- * a multiplier of 86 or 79 gets us close to the target rates.
- */
- prediv = 21;
- postdiv = 4;
-
- switch (freq) {
- case 24576000:
- n = 86;
- reg_value |= CCM_PLL_CFG_ENABLE;
- break;
- case 22579200:
- n = 79;
- reg_value |= CCM_PLL_CFG_ENABLE;
- break;
- case 0:
- n = 1;
- reg_value &= ~CCM_PLL_CFG_ENABLE;
- break;
- default:
- return (EINVAL);
- }
-
- reg_value |= (prediv << CCM_PLL2_CFG_PREDIV_SHIFT);
- reg_value |= (postdiv << CCM_PLL2_CFG_POSTDIV_SHIFT);
- reg_value |= (n << CCM_PLL_CFG_FACTOR_N_SHIFT);
- ccm_write_4(sc, CCM_PLL2_CFG, reg_value);
-
- return (0);
-}
-
-int
-a10_clk_ahci_activate(void)
-{
- struct a10_ccm_softc *sc;
- uint32_t reg_value;
-
- sc = a10_ccm_sc;
- if (sc == NULL)
- return (ENXIO);
-
- a10_clk_pll6_enable();
-
- /* Gating AHB clock for SATA */
- reg_value = ccm_read_4(sc, CCM_AHB_GATING0);
- reg_value |= CCM_AHB_GATING_SATA;
- ccm_write_4(sc, CCM_AHB_GATING0, reg_value);
- DELAY(1000);
-
- ccm_write_4(sc, CCM_SATA_CLK, CCM_PLL_CFG_ENABLE);
-
- return (0);
-}
-
-int
-a10_clk_mmc_activate(int devid)
-{
- struct a10_ccm_softc *sc;
- uint32_t reg_value;
-
- sc = a10_ccm_sc;
- if (sc == NULL)
- return (ENXIO);
-
- a10_clk_pll6_enable();
-
- /* Gating AHB clock for SD/MMC */
- reg_value = ccm_read_4(sc, CCM_AHB_GATING0);
- reg_value |= CCM_AHB_GATING_SDMMC0 << devid;
- ccm_write_4(sc, CCM_AHB_GATING0, reg_value);
-
- return (0);
-}
-
-int
-a10_clk_mmc_cfg(int devid, int freq)
-{
- struct a10_ccm_softc *sc;
- uint32_t clksrc, m, n, ophase, phase, reg_value;
- unsigned int pll_freq;
-
- sc = a10_ccm_sc;
- if (sc == NULL)
- return (ENXIO);
-
- freq /= 1000;
- if (freq <= 400) {
- pll_freq = CCM_CLK_REF_FREQ / 1000;
- clksrc = CCM_SD_CLK_SRC_SEL_OSC24M;
- ophase = 0;
- phase = 0;
- n = 2;
- } else if (freq <= 25000) {
- pll_freq = a10_clk_pll6_get_rate() / 1000;
- clksrc = CCM_SD_CLK_SRC_SEL_PLL6;
- ophase = 0;
- phase = 5;
- n = 2;
- } else if (freq <= 50000) {
- pll_freq = a10_clk_pll6_get_rate() / 1000;
- clksrc = CCM_SD_CLK_SRC_SEL_PLL6;
- ophase = 3;
- phase = 5;
- n = 0;
- } else
- return (EINVAL);
- m = ((pll_freq / (1 << n)) / (freq)) - 1;
- reg_value = ccm_read_4(sc, CCM_MMC0_SCLK_CFG + (devid * 4));
- reg_value &= ~CCM_SD_CLK_SRC_SEL;
- reg_value |= (clksrc << CCM_SD_CLK_SRC_SEL_SHIFT);
- reg_value &= ~CCM_SD_CLK_PHASE_CTR;
- reg_value |= (phase << CCM_SD_CLK_PHASE_CTR_SHIFT);
- reg_value &= ~CCM_SD_CLK_DIV_RATIO_N;
- reg_value |= (n << CCM_SD_CLK_DIV_RATIO_N_SHIFT);
- reg_value &= ~CCM_SD_CLK_OPHASE_CTR;
- reg_value |= (ophase << CCM_SD_CLK_OPHASE_CTR_SHIFT);
- reg_value &= ~CCM_SD_CLK_DIV_RATIO_M;
- reg_value |= m;
- reg_value |= CCM_PLL_CFG_ENABLE;
- ccm_write_4(sc, CCM_MMC0_SCLK_CFG + (devid * 4), reg_value);
-
- return (0);
-}
-
-int
-a10_clk_i2c_activate(int devid)
-{
- struct a10_ccm_softc *sc;
- uint32_t reg_value;
-
- sc = a10_ccm_sc;
- if (sc == NULL)
- return (ENXIO);
-
- a10_clk_pll6_enable();
-
- /* Gating APB clock for I2C/TWI */
- reg_value = ccm_read_4(sc, CCM_APB1_GATING);
- if (devid == 4)
- reg_value |= CCM_APB1_GATING_TWI << 15;
- else
- reg_value |= CCM_APB1_GATING_TWI << devid;
- ccm_write_4(sc, CCM_APB1_GATING, reg_value);
-
- return (0);
-}
-
-int
-a10_clk_dmac_activate(void)
-{
- struct a10_ccm_softc *sc;
- uint32_t reg_value;
-
- sc = a10_ccm_sc;
- if (sc == NULL)
- return (ENXIO);
-
- /* Gating AHB clock for DMA controller */
- reg_value = ccm_read_4(sc, CCM_AHB_GATING0);
- reg_value |= CCM_AHB_GATING_DMA;
- ccm_write_4(sc, CCM_AHB_GATING0, reg_value);
-
- return (0);
-}
-
-int
-a10_clk_codec_activate(unsigned int freq)
-{
- struct a10_ccm_softc *sc;
- uint32_t reg_value;
-
- sc = a10_ccm_sc;
- if (sc == NULL)
- return (ENXIO);
-
- a10_clk_pll2_set_rate(freq);
-
- /* Gating APB clock for ADDA */
- reg_value = ccm_read_4(sc, CCM_APB0_GATING);
- reg_value |= CCM_APB0_GATING_ADDA;
- ccm_write_4(sc, CCM_APB0_GATING, reg_value);
-
- /* Enable audio codec clock */
- reg_value = ccm_read_4(sc, CCM_AUDIO_CODEC_CLK);
- reg_value |= CCM_AUDIO_CODEC_ENABLE;
- ccm_write_4(sc, CCM_AUDIO_CODEC_CLK, reg_value);
-
- return (0);
-}
Index: sys/arm/allwinner/a10_common.c
===================================================================
--- /dev/null
+++ sys/arm/allwinner/a10_common.c
@@ -1,72 +0,0 @@
-/*-
- * Copyright (c) 2012 Ganbold Tsagaankhuu <ganbold@freebsd.org>
- * 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 AND CONTRIBUTORS ``AS IS'' AND
- * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
- * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
- * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
- * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
- * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
- * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
- * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
- * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
- * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
- * SUCH DAMAGE.
- */
-
-#include <sys/cdefs.h>
-__FBSDID("$FreeBSD$");
-
-#include <sys/param.h>
-#include <sys/systm.h>
-#include <sys/bus.h>
-#include <sys/kernel.h>
-
-#include <dev/fdt/fdt_common.h>
-#include <dev/ofw/openfirm.h>
-
-#include <machine/bus.h>
-#include <machine/vmparam.h>
-
-struct fdt_fixup_entry fdt_fixup_table[] = {
- { NULL, NULL }
-};
-
-#ifndef ARM_INTRNG
-
-static int
-fdt_aintc_decode_ic(phandle_t node, pcell_t *intr, int *interrupt, int *trig,
- int *pol)
-{
- int offset;
-
- if (fdt_is_compatible(node, "allwinner,sun4i-a10-ic"))
- offset = 0;
- else if (fdt_is_compatible(node, "arm,gic"))
- offset = 32;
- else
- return (ENXIO);
-
- *interrupt = fdt32_to_cpu(intr[0]) + offset;
- *trig = INTR_TRIGGER_CONFORM;
- *pol = INTR_POLARITY_CONFORM;
-
- return (0);
-}
-
-fdt_pic_decode_t fdt_pic_table[] = {
- &fdt_aintc_decode_ic,
- NULL
-};
-
-#endif /* ARM_INTRNG */
Index: sys/arm/allwinner/a10_mmc.h
===================================================================
--- sys/arm/allwinner/a10_mmc.h
+++ /dev/null
@@ -1,198 +0,0 @@
-/*-
- * Copyright (c) 2013 Alexander Fedorov <alexander.fedorov@rtlservice.com>
- * 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 AND CONTRIBUTORS ``AS IS'' AND
- * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
- * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
- * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
- * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
- * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
- * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
- * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
- * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
- * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
- * SUCH DAMAGE.
- *
- * $FreeBSD$
- */
-
-#ifndef _A10_MMC_H_
-#define _A10_MMC_H_
-
-#define A10_MMC_GCTRL 0x00 /* Global Control Register */
-#define A10_MMC_CLKCR 0x04 /* Clock Control Register */
-#define A10_MMC_TIMEOUT 0x08 /* Timeout Register */
-#define A10_MMC_WIDTH 0x0C /* Bus Width Register */
-#define A10_MMC_BLKSZ 0x10 /* Block Size Register */
-#define A10_MMC_BCNTR 0x14 /* Byte Count Register */
-#define A10_MMC_CMDR 0x18 /* Command Register */
-#define A10_MMC_CARG 0x1C /* Argument Register */
-#define A10_MMC_RESP0 0x20 /* Response Register 0 */
-#define A10_MMC_RESP1 0x24 /* Response Register 1 */
-#define A10_MMC_RESP2 0x28 /* Response Register 2 */
-#define A10_MMC_RESP3 0x2C /* Response Register 3 */
-#define A10_MMC_IMASK 0x30 /* Interrupt Mask Register */
-#define A10_MMC_MISTA 0x34 /* Masked Interrupt Status Register */
-#define A10_MMC_RINTR 0x38 /* Raw Interrupt Status Register */
-#define A10_MMC_STAS 0x3C /* Status Register */
-#define A10_MMC_FTRGL 0x40 /* FIFO Threshold Watermark Register */
-#define A10_MMC_FUNS 0x44 /* Function Select Register */
-#define A10_MMC_CBCR 0x48 /* CIU Byte Count Register */
-#define A10_MMC_BBCR 0x4C /* BIU Byte Count Register */
-#define A10_MMC_DBGC 0x50 /* Debug Enable Register */
-#define A10_MMC_DMAC 0x80 /* IDMAC Control Register */
-#define A10_MMC_DLBA 0x84 /* IDMAC Desc List Base Address Reg */
-#define A10_MMC_IDST 0x88 /* IDMAC Status Register */
-#define A10_MMC_IDIE 0x8C /* IDMAC Interrupt Enable Register */
-#define A10_MMC_CHDA 0x90
-#define A10_MMC_CBDA 0x94
-#define A10_MMC_FIFO 0x100 /* FIFO Access Address */
-
-/* A10_MMC_GCTRL */
-#define A10_MMC_SOFT_RESET (1U << 0)
-#define A10_MMC_FIFO_RESET (1U << 1)
-#define A10_MMC_DMA_RESET (1U << 2)
-#define A10_MMC_INT_ENABLE (1U << 4)
-#define A10_MMC_DMA_ENABLE (1U << 5)
-#define A10_MMC_DEBOUNCE_ENABLE (1U << 8)
-#define A10_MMC_DDR_MODE (1U << 10)
-#define A10_MMC_ACCESS_BY_AHB (1U << 31)
-#define A10_MMC_RESET \
- (A10_MMC_SOFT_RESET | A10_MMC_FIFO_RESET | A10_MMC_DMA_RESET)
-
-/* A10_MMC_CLKCR */
-#define A10_MMC_CARD_CLK_ON (1U << 16)
-#define A10_MMC_LOW_POWER_ON (1U << 17)
-#define A10_MMC_CLKCR_DIV 0xff
-
-/* A10_MMC_WIDTH */
-#define A10_MMC_WIDTH1 0
-#define A10_MMC_WIDTH4 1
-#define A10_MMC_WIDTH8 2
-
-/* A10_MMC_CMDR */
-#define A10_MMC_RESP_EXP (1U << 6)
-#define A10_MMC_LONG_RESP (1U << 7)
-#define A10_MMC_CHECK_RESP_CRC (1U << 8)
-#define A10_MMC_DATA_EXP (1U << 9)
-#define A10_MMC_WRITE (1U << 10)
-#define A10_MMC_SEQ_MODE (1U << 11)
-#define A10_MMC_SEND_AUTOSTOP (1U << 12)
-#define A10_MMC_WAIT_PREOVER (1U << 13)
-#define A10_MMC_STOP_ABORT_CMD (1U << 14)
-#define A10_MMC_SEND_INIT_SEQ (1U << 15)
-#define A10_MMC_UPCLK_ONLY (1U << 21)
-#define A10_MMC_RDCEATADEV (1U << 22)
-#define A10_MMC_CCS_EXP (1U << 23)
-#define A10_MMC_ENB_BOOT (1U << 24)
-#define A10_MMC_ALT_BOOT_OPT (1U << 25)
-#define A10_MMC_BOOT_ACK_EXP (1U << 26)
-#define A10_MMC_DISABLE_BOOT (1U << 27)
-#define A10_MMC_VOL_SWITCH (1U << 28)
-#define A10_MMC_START (1U << 31)
-
-/* A10_MMC_IMASK and A10_MMC_RINTR */
-#define A10_MMC_RESP_ERR (1U << 1)
-#define A10_MMC_CMD_DONE (1U << 2)
-#define A10_MMC_DATA_OVER (1U << 3)
-#define A10_MMC_TX_DATA_REQ (1U << 4)
-#define A10_MMC_RX_DATA_REQ (1U << 5)
-#define A10_MMC_RESP_CRC_ERR (1U << 6)
-#define A10_MMC_DATA_CRC_ERR (1U << 7)
-#define A10_MMC_RESP_TIMEOUT (1U << 8)
-#define A10_MMC_ACK_RECV (1U << 8)
-#define A10_MMC_DATA_TIMEOUT (1U << 9)
-#define A10_MMC_BOOT_START (1U << 9)
-#define A10_MMC_DATA_STARVE (1U << 10)
-#define A10_MMC_VOL_CHG_DONE (1U << 10)
-#define A10_MMC_FIFO_RUN_ERR (1U << 11)
-#define A10_MMC_HARDW_LOCKED (1U << 12)
-#define A10_MMC_START_BIT_ERR (1U << 13)
-#define A10_MMC_AUTOCMD_DONE (1U << 14)
-#define A10_MMC_END_BIT_ERR (1U << 15)
-#define A10_MMC_SDIO_INT (1U << 16)
-#define A10_MMC_CARD_INSERT (1U << 30)
-#define A10_MMC_CARD_REMOVE (1U << 31)
-#define A10_MMC_INT_ERR_BIT \
- (A10_MMC_RESP_ERR | A10_MMC_RESP_CRC_ERR | \
- A10_MMC_DATA_CRC_ERR | A10_MMC_RESP_TIMEOUT | \
- A10_MMC_FIFO_RUN_ERR | A10_MMC_HARDW_LOCKED | \
- A10_MMC_START_BIT_ERR | A10_MMC_END_BIT_ERR)
-
-/* A10_MMC_STAS */
-#define A10_MMC_RX_WLFLAG (1U << 0)
-#define A10_MMC_TX_WLFLAG (1U << 1)
-#define A10_MMC_FIFO_EMPTY (1U << 2)
-#define A10_MMC_FIFO_FULL (1U << 3)
-#define A10_MMC_CARD_PRESENT (1U << 8)
-#define A10_MMC_CARD_DATA_BUSY (1U << 9)
-#define A10_MMC_DATA_FSM_BUSY (1U << 10)
-#define A10_MMC_DMA_REQ (1U << 31)
-#define A10_MMC_FIFO_SIZE 16
-
-/* A10_MMC_FUNS */
-#define A10_MMC_CE_ATA_ON (0xceaaU << 16)
-#define A10_MMC_SEND_IRQ_RESP (1U << 0)
-#define A10_MMC_SDIO_RD_WAIT (1U << 1)
-#define A10_MMC_ABT_RD_DATA (1U << 2)
-#define A10_MMC_SEND_CC_SD (1U << 8)
-#define A10_MMC_SEND_AUTOSTOP_CC_SD (1U << 9)
-#define A10_MMC_CE_ATA_DEV_INT_ENB (1U << 10)
-
-/* IDMA CONTROLLER BUS MOD BIT FIELD */
-#define A10_MMC_IDMAC_SOFT_RST (1U << 0)
-#define A10_MMC_IDMAC_FIX_BURST (1U << 1)
-#define A10_MMC_IDMAC_IDMA_ON (1U << 7)
-#define A10_MMC_IDMAC_REFETCH_DES (1U << 31)
-
-/* A10_MMC_IDST */
-#define A10_MMC_IDMAC_TRANSMIT_INT (1U << 0)
-#define A10_MMC_IDMAC_RECEIVE_INT (1U << 1)
-#define A10_MMC_IDMAC_FATAL_BUS_ERR (1U << 2)
-#define A10_MMC_IDMAC_DES_INVALID (1U << 4)
-#define A10_MMC_IDMAC_CARD_ERR_SUM (1U << 5)
-#define A10_MMC_IDMAC_NORMAL_INT_SUM (1U << 8)
-#define A10_MMC_IDMAC_ABNORMAL_INT_SUM (1U << 9)
-#define A10_MMC_IDMAC_HOST_ABT_INTX (1U << 10)
-#define A10_MMC_IDMAC_HOST_ABT_INRX (1U << 10)
-#define A10_MMC_IDMAC_IDLE (0U << 13)
-#define A10_MMC_IDMAC_SUSPEND (1U << 13)
-#define A10_MMC_IDMAC_DESC_RD (2U << 13)
-#define A10_MMC_IDMAC_DESC_CHECK (3U << 13)
-#define A10_MMC_IDMAC_RD_REQ_WAIT (4U << 13)
-#define A10_MMC_IDMAC_WR_REQ_WAIT (5U << 13)
-#define A10_MMC_IDMAC_RD (6U << 13)
-#define A10_MMC_IDMAC_WR (7U << 13)
-#define A10_MMC_IDMAC_DESC_CLOSE (8U << 13)
-#define A10_MMC_IDMAC_ERROR \
- (A10_MMC_IDMAC_FATAL_BUS_ERR | A10_MMC_IDMAC_CARD_ERR_SUM | \
- A10_MMC_IDMAC_DES_INVALID | A10_MMC_IDMAC_ABNORMAL_INT_SUM)
-#define A10_MMC_IDMAC_COMPLETE \
- (A10_MMC_IDMAC_TRANSMIT_INT | A10_MMC_IDMAC_RECEIVE_INT)
-
-/* The DMA descriptor table. */
-struct a10_mmc_dma_desc {
- uint32_t config;
-#define A10_MMC_DMA_CONFIG_DIC (1U << 1)
-#define A10_MMC_DMA_CONFIG_LD (1U << 2)
-#define A10_MMC_DMA_CONFIG_FD (1U << 3)
-#define A10_MMC_DMA_CONFIG_CH (1U << 4)
-#define A10_MMC_DMA_CONFIG_ER (1U << 5)
-#define A10_MMC_DMA_CONFIG_CES (1U << 30)
-#define A10_MMC_DMA_CONFIG_OWN (1U << 31)
- uint32_t buf_size;
- uint32_t buf_addr;
- uint32_t next;
-};
-
-#endif /* _A10_MMC_H_ */
Index: sys/arm/allwinner/a10_mmc.c
===================================================================
--- sys/arm/allwinner/a10_mmc.c
+++ /dev/null
@@ -1,893 +0,0 @@
-/*-
- * Copyright (c) 2013 Alexander Fedorov
- * 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 AND CONTRIBUTORS ``AS IS'' AND
- * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
- * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
- * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
- * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
- * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
- * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
- * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
- * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
- * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
- * SUCH DAMAGE.
- */
-
-#include <sys/cdefs.h>
-__FBSDID("$FreeBSD$");
-
-#include <sys/param.h>
-#include <sys/systm.h>
-#include <sys/bus.h>
-#include <sys/kernel.h>
-#include <sys/lock.h>
-#include <sys/malloc.h>
-#include <sys/module.h>
-#include <sys/mutex.h>
-#include <sys/resource.h>
-#include <sys/rman.h>
-#include <sys/sysctl.h>
-
-#include <machine/bus.h>
-
-#include <dev/ofw/ofw_bus.h>
-#include <dev/ofw/ofw_bus_subr.h>
-
-#include <dev/mmc/bridge.h>
-#include <dev/mmc/mmcreg.h>
-#include <dev/mmc/mmcbrvar.h>
-
-#include <arm/allwinner/a10_clk.h>
-#include <arm/allwinner/a10_mmc.h>
-
-#define A10_MMC_MEMRES 0
-#define A10_MMC_IRQRES 1
-#define A10_MMC_RESSZ 2
-#define A10_MMC_DMA_SEGS 16
-#define A10_MMC_DMA_MAX_SIZE 0x2000
-#define A10_MMC_DMA_FTRGLEVEL 0x20070008
-
-static int a10_mmc_pio_mode = 0;
-
-TUNABLE_INT("hw.a10.mmc.pio_mode", &a10_mmc_pio_mode);
-
-static struct ofw_compat_data compat_data[] = {
- {"allwinner,sun4i-a10-mmc", 1},
- {"allwinner,sun5i-a13-mmc", 1},
- {NULL, 0}
-};
-
-struct a10_mmc_softc {
- bus_space_handle_t a10_bsh;
- bus_space_tag_t a10_bst;
- device_t a10_dev;
- int a10_bus_busy;
- int a10_id;
- int a10_resid;
- int a10_timeout;
- struct callout a10_timeoutc;
- struct mmc_host a10_host;
- struct mmc_request * a10_req;
- struct mtx a10_mtx;
- struct resource * a10_res[A10_MMC_RESSZ];
- uint32_t a10_intr;
- uint32_t a10_intr_wait;
- void * a10_intrhand;
-
- /* Fields required for DMA access. */
- bus_addr_t a10_dma_desc_phys;
- bus_dmamap_t a10_dma_map;
- bus_dma_tag_t a10_dma_tag;
- void * a10_dma_desc;
- bus_dmamap_t a10_dma_buf_map;
- bus_dma_tag_t a10_dma_buf_tag;
- int a10_dma_inuse;
- int a10_dma_map_err;
-};
-
-static struct resource_spec a10_mmc_res_spec[] = {
- { SYS_RES_MEMORY, 0, RF_ACTIVE },
- { SYS_RES_IRQ, 0, RF_ACTIVE | RF_SHAREABLE },
- { -1, 0, 0 }
-};
-
-static int a10_mmc_probe(device_t);
-static int a10_mmc_attach(device_t);
-static int a10_mmc_detach(device_t);
-static int a10_mmc_setup_dma(struct a10_mmc_softc *);
-static int a10_mmc_reset(struct a10_mmc_softc *);
-static void a10_mmc_intr(void *);
-static int a10_mmc_update_clock(struct a10_mmc_softc *);
-
-static int a10_mmc_update_ios(device_t, device_t);
-static int a10_mmc_request(device_t, device_t, struct mmc_request *);
-static int a10_mmc_get_ro(device_t, device_t);
-static int a10_mmc_acquire_host(device_t, device_t);
-static int a10_mmc_release_host(device_t, device_t);
-
-#define A10_MMC_LOCK(_sc) mtx_lock(&(_sc)->a10_mtx)
-#define A10_MMC_UNLOCK(_sc) mtx_unlock(&(_sc)->a10_mtx)
-#define A10_MMC_READ_4(_sc, _reg) \
- bus_space_read_4((_sc)->a10_bst, (_sc)->a10_bsh, _reg)
-#define A10_MMC_WRITE_4(_sc, _reg, _value) \
- bus_space_write_4((_sc)->a10_bst, (_sc)->a10_bsh, _reg, _value)
-
-static int
-a10_mmc_probe(device_t dev)
-{
-
- if (!ofw_bus_status_okay(dev))
- return (ENXIO);
- if (ofw_bus_search_compatible(dev, compat_data)->ocd_data == 0)
- return (ENXIO);
-
- device_set_desc(dev, "Allwinner Integrated MMC/SD controller");
-
- return (BUS_PROBE_DEFAULT);
-}
-
-static int
-a10_mmc_attach(device_t dev)
-{
- device_t child;
- struct a10_mmc_softc *sc;
- struct sysctl_ctx_list *ctx;
- struct sysctl_oid_list *tree;
-
- sc = device_get_softc(dev);
- sc->a10_dev = dev;
- sc->a10_req = NULL;
- sc->a10_id = device_get_unit(dev);
- if (sc->a10_id > 3) {
- device_printf(dev, "only 4 hosts are supported (0-3)\n");
- return (ENXIO);
- }
- if (bus_alloc_resources(dev, a10_mmc_res_spec, sc->a10_res) != 0) {
- device_printf(dev, "cannot allocate device resources\n");
- return (ENXIO);
- }
- sc->a10_bst = rman_get_bustag(sc->a10_res[A10_MMC_MEMRES]);
- sc->a10_bsh = rman_get_bushandle(sc->a10_res[A10_MMC_MEMRES]);
- if (bus_setup_intr(dev, sc->a10_res[A10_MMC_IRQRES],
- INTR_TYPE_MISC | INTR_MPSAFE, NULL, a10_mmc_intr, sc,
- &sc->a10_intrhand)) {
- bus_release_resources(dev, a10_mmc_res_spec, sc->a10_res);
- device_printf(dev, "cannot setup interrupt handler\n");
- return (ENXIO);
- }
-
- /* Activate the module clock. */
- if (a10_clk_mmc_activate(sc->a10_id) != 0) {
- bus_teardown_intr(dev, sc->a10_res[A10_MMC_IRQRES],
- sc->a10_intrhand);
- bus_release_resources(dev, a10_mmc_res_spec, sc->a10_res);
- device_printf(dev, "cannot activate mmc clock\n");
- return (ENXIO);
- }
-
- sc->a10_timeout = 10;
- ctx = device_get_sysctl_ctx(dev);
- tree = SYSCTL_CHILDREN(device_get_sysctl_tree(dev));
- SYSCTL_ADD_INT(ctx, tree, OID_AUTO, "req_timeout", CTLFLAG_RW,
- &sc->a10_timeout, 0, "Request timeout in seconds");
- mtx_init(&sc->a10_mtx, device_get_nameunit(sc->a10_dev), "a10_mmc",
- MTX_DEF);
- callout_init_mtx(&sc->a10_timeoutc, &sc->a10_mtx, 0);
-
- /* Reset controller. */
- if (a10_mmc_reset(sc) != 0) {
- device_printf(dev, "cannot reset the controller\n");
- goto fail;
- }
-
- if (a10_mmc_pio_mode == 0 && a10_mmc_setup_dma(sc) != 0) {
- device_printf(sc->a10_dev, "Couldn't setup DMA!\n");
- a10_mmc_pio_mode = 1;
- }
- if (bootverbose)
- device_printf(sc->a10_dev, "DMA status: %s\n",
- a10_mmc_pio_mode ? "disabled" : "enabled");
-
- sc->a10_host.f_min = 400000;
- sc->a10_host.f_max = 52000000;
- sc->a10_host.host_ocr = MMC_OCR_320_330 | MMC_OCR_330_340;
- sc->a10_host.caps = MMC_CAP_4_BIT_DATA | MMC_CAP_HSPEED;
- sc->a10_host.mode = mode_sd;
-
- child = device_add_child(dev, "mmc", -1);
- if (child == NULL) {
- device_printf(dev, "attaching MMC bus failed!\n");
- goto fail;
- }
- if (device_probe_and_attach(child) != 0) {
- device_printf(dev, "attaching MMC child failed!\n");
- device_delete_child(dev, child);
- goto fail;
- }
-
- return (0);
-
-fail:
- callout_drain(&sc->a10_timeoutc);
- mtx_destroy(&sc->a10_mtx);
- bus_teardown_intr(dev, sc->a10_res[A10_MMC_IRQRES], sc->a10_intrhand);
- bus_release_resources(dev, a10_mmc_res_spec, sc->a10_res);
-
- return (ENXIO);
-}
-
-static int
-a10_mmc_detach(device_t dev)
-{
-
- return (EBUSY);
-}
-
-static void
-a10_dma_desc_cb(void *arg, bus_dma_segment_t *segs, int nsegs, int err)
-{
- struct a10_mmc_softc *sc;
-
- sc = (struct a10_mmc_softc *)arg;
- if (err) {
- sc->a10_dma_map_err = err;
- return;
- }
- sc->a10_dma_desc_phys = segs[0].ds_addr;
-}
-
-static int
-a10_mmc_setup_dma(struct a10_mmc_softc *sc)
-{
- int dma_desc_size, error;
-
- /* Allocate the DMA descriptor memory. */
- dma_desc_size = sizeof(struct a10_mmc_dma_desc) * A10_MMC_DMA_SEGS;
- error = bus_dma_tag_create(bus_get_dma_tag(sc->a10_dev), 1, 0,
- BUS_SPACE_MAXADDR_32BIT, BUS_SPACE_MAXADDR, NULL, NULL,
- dma_desc_size, 1, dma_desc_size, 0, NULL, NULL, &sc->a10_dma_tag);
- if (error)
- return (error);
- error = bus_dmamem_alloc(sc->a10_dma_tag, &sc->a10_dma_desc,
- BUS_DMA_WAITOK | BUS_DMA_ZERO, &sc->a10_dma_map);
- if (error)
- return (error);
-
- error = bus_dmamap_load(sc->a10_dma_tag, sc->a10_dma_map,
- sc->a10_dma_desc, dma_desc_size, a10_dma_desc_cb, sc, 0);
- if (error)
- return (error);
- if (sc->a10_dma_map_err)
- return (sc->a10_dma_map_err);
-
- /* Create the DMA map for data transfers. */
- error = bus_dma_tag_create(bus_get_dma_tag(sc->a10_dev), 1, 0,
- BUS_SPACE_MAXADDR_32BIT, BUS_SPACE_MAXADDR, NULL, NULL,
- A10_MMC_DMA_MAX_SIZE * A10_MMC_DMA_SEGS, A10_MMC_DMA_SEGS,
- A10_MMC_DMA_MAX_SIZE, BUS_DMA_ALLOCNOW, NULL, NULL,
- &sc->a10_dma_buf_tag);
- if (error)
- return (error);
- error = bus_dmamap_create(sc->a10_dma_buf_tag, 0,
- &sc->a10_dma_buf_map);
- if (error)
- return (error);
-
- return (0);
-}
-
-static void
-a10_dma_cb(void *arg, bus_dma_segment_t *segs, int nsegs, int err)
-{
- int i;
- struct a10_mmc_dma_desc *dma_desc;
- struct a10_mmc_softc *sc;
-
- sc = (struct a10_mmc_softc *)arg;
- sc->a10_dma_map_err = err;
- dma_desc = sc->a10_dma_desc;
- /* Note nsegs is guaranteed to be zero if err is non-zero. */
- for (i = 0; i < nsegs; i++) {
- dma_desc[i].buf_size = segs[i].ds_len;
- dma_desc[i].buf_addr = segs[i].ds_addr;
- dma_desc[i].config = A10_MMC_DMA_CONFIG_CH |
- A10_MMC_DMA_CONFIG_OWN;
- if (i == 0)
- dma_desc[i].config |= A10_MMC_DMA_CONFIG_FD;
- if (i < (nsegs - 1)) {
- dma_desc[i].config |= A10_MMC_DMA_CONFIG_DIC;
- dma_desc[i].next = sc->a10_dma_desc_phys +
- ((i + 1) * sizeof(struct a10_mmc_dma_desc));
- } else {
- dma_desc[i].config |= A10_MMC_DMA_CONFIG_LD |
- A10_MMC_DMA_CONFIG_ER;
- dma_desc[i].next = 0;
- }
- }
-}
-
-static int
-a10_mmc_prepare_dma(struct a10_mmc_softc *sc)
-{
- bus_dmasync_op_t sync_op;
- int error;
- struct mmc_command *cmd;
- uint32_t val;
-
- cmd = sc->a10_req->cmd;
- if (cmd->data->len > A10_MMC_DMA_MAX_SIZE * A10_MMC_DMA_SEGS)
- return (EFBIG);
- error = bus_dmamap_load(sc->a10_dma_buf_tag, sc->a10_dma_buf_map,
- cmd->data->data, cmd->data->len, a10_dma_cb, sc, BUS_DMA_NOWAIT);
- if (error)
- return (error);
- if (sc->a10_dma_map_err)
- return (sc->a10_dma_map_err);
-
- sc->a10_dma_inuse = 1;
- if (cmd->data->flags & MMC_DATA_WRITE)
- sync_op = BUS_DMASYNC_PREWRITE;
- else
- sync_op = BUS_DMASYNC_PREREAD;
- bus_dmamap_sync(sc->a10_dma_buf_tag, sc->a10_dma_buf_map, sync_op);
- bus_dmamap_sync(sc->a10_dma_tag, sc->a10_dma_map, BUS_DMASYNC_PREWRITE);
-
- val = A10_MMC_READ_4(sc, A10_MMC_IMASK);
- val &= ~(A10_MMC_RX_DATA_REQ | A10_MMC_TX_DATA_REQ);
- A10_MMC_WRITE_4(sc, A10_MMC_IMASK, val);
- val = A10_MMC_READ_4(sc, A10_MMC_GCTRL);
- val &= ~A10_MMC_ACCESS_BY_AHB;
- val |= A10_MMC_DMA_ENABLE;
- A10_MMC_WRITE_4(sc, A10_MMC_GCTRL, val);
- val |= A10_MMC_DMA_RESET;
- A10_MMC_WRITE_4(sc, A10_MMC_GCTRL, val);
- A10_MMC_WRITE_4(sc, A10_MMC_DMAC, A10_MMC_IDMAC_SOFT_RST);
- A10_MMC_WRITE_4(sc, A10_MMC_DMAC,
- A10_MMC_IDMAC_IDMA_ON | A10_MMC_IDMAC_FIX_BURST);
- val = A10_MMC_READ_4(sc, A10_MMC_IDIE);
- val &= ~(A10_MMC_IDMAC_RECEIVE_INT | A10_MMC_IDMAC_TRANSMIT_INT);
- if (cmd->data->flags & MMC_DATA_WRITE)
- val |= A10_MMC_IDMAC_TRANSMIT_INT;
- else
- val |= A10_MMC_IDMAC_RECEIVE_INT;
- A10_MMC_WRITE_4(sc, A10_MMC_IDIE, val);
- A10_MMC_WRITE_4(sc, A10_MMC_DLBA, sc->a10_dma_desc_phys);
- A10_MMC_WRITE_4(sc, A10_MMC_FTRGL, A10_MMC_DMA_FTRGLEVEL);
-
- return (0);
-}
-
-static int
-a10_mmc_reset(struct a10_mmc_softc *sc)
-{
- int timeout;
-
- A10_MMC_WRITE_4(sc, A10_MMC_GCTRL,
- A10_MMC_READ_4(sc, A10_MMC_GCTRL) | A10_MMC_RESET);
- timeout = 1000;
- while (--timeout > 0) {
- if ((A10_MMC_READ_4(sc, A10_MMC_GCTRL) & A10_MMC_RESET) == 0)
- break;
- DELAY(100);
- }
- if (timeout == 0)
- return (ETIMEDOUT);
-
- /* Set the timeout. */
- A10_MMC_WRITE_4(sc, A10_MMC_TIMEOUT, 0xffffffff);
-
- /* Clear pending interrupts. */
- A10_MMC_WRITE_4(sc, A10_MMC_RINTR, 0xffffffff);
- A10_MMC_WRITE_4(sc, A10_MMC_IDST, 0xffffffff);
- /* Unmask interrupts. */
- A10_MMC_WRITE_4(sc, A10_MMC_IMASK,
- A10_MMC_CMD_DONE | A10_MMC_INT_ERR_BIT |
- A10_MMC_DATA_OVER | A10_MMC_AUTOCMD_DONE);
- /* Enable interrupts and AHB access. */
- A10_MMC_WRITE_4(sc, A10_MMC_GCTRL,
- A10_MMC_READ_4(sc, A10_MMC_GCTRL) | A10_MMC_INT_ENABLE);
-
- return (0);
-}
-
-static void
-a10_mmc_req_done(struct a10_mmc_softc *sc)
-{
- struct mmc_command *cmd;
- struct mmc_request *req;
-
- cmd = sc->a10_req->cmd;
- if (cmd->error != MMC_ERR_NONE) {
- /* Reset the controller. */
- a10_mmc_reset(sc);
- a10_mmc_update_clock(sc);
- }
- if (sc->a10_dma_inuse == 0) {
- /* Reset the FIFO. */
- A10_MMC_WRITE_4(sc, A10_MMC_GCTRL,
- A10_MMC_READ_4(sc, A10_MMC_GCTRL) | A10_MMC_FIFO_RESET);
- }
-
- req = sc->a10_req;
- callout_stop(&sc->a10_timeoutc);
- sc->a10_req = NULL;
- sc->a10_intr = 0;
- sc->a10_resid = 0;
- sc->a10_dma_inuse = 0;
- sc->a10_dma_map_err = 0;
- sc->a10_intr_wait = 0;
- req->done(req);
-}
-
-static void
-a10_mmc_req_ok(struct a10_mmc_softc *sc)
-{
- int timeout;
- struct mmc_command *cmd;
- uint32_t status;
-
- timeout = 1000;
- while (--timeout > 0) {
- status = A10_MMC_READ_4(sc, A10_MMC_STAS);
- if ((status & A10_MMC_CARD_DATA_BUSY) == 0)
- break;
- DELAY(1000);
- }
- cmd = sc->a10_req->cmd;
- if (timeout == 0) {
- cmd->error = MMC_ERR_FAILED;
- a10_mmc_req_done(sc);
- return;
- }
- if (cmd->flags & MMC_RSP_PRESENT) {
- if (cmd->flags & MMC_RSP_136) {
- cmd->resp[0] = A10_MMC_READ_4(sc, A10_MMC_RESP3);
- cmd->resp[1] = A10_MMC_READ_4(sc, A10_MMC_RESP2);
- cmd->resp[2] = A10_MMC_READ_4(sc, A10_MMC_RESP1);
- cmd->resp[3] = A10_MMC_READ_4(sc, A10_MMC_RESP0);
- } else
- cmd->resp[0] = A10_MMC_READ_4(sc, A10_MMC_RESP0);
- }
- /* All data has been transferred ? */
- if (cmd->data != NULL && (sc->a10_resid << 2) < cmd->data->len)
- cmd->error = MMC_ERR_FAILED;
- a10_mmc_req_done(sc);
-}
-
-static void
-a10_mmc_timeout(void *arg)
-{
- struct a10_mmc_softc *sc;
-
- sc = (struct a10_mmc_softc *)arg;
- if (sc->a10_req != NULL) {
- device_printf(sc->a10_dev, "controller timeout\n");
- sc->a10_req->cmd->error = MMC_ERR_TIMEOUT;
- a10_mmc_req_done(sc);
- } else
- device_printf(sc->a10_dev,
- "Spurious timeout - no active request\n");
-}
-
-static int
-a10_mmc_pio_transfer(struct a10_mmc_softc *sc, struct mmc_data *data)
-{
- int i, write;
- uint32_t bit, *buf;
-
- buf = (uint32_t *)data->data;
- write = (data->flags & MMC_DATA_WRITE) ? 1 : 0;
- bit = write ? A10_MMC_FIFO_FULL : A10_MMC_FIFO_EMPTY;
- for (i = sc->a10_resid; i < (data->len >> 2); i++) {
- if ((A10_MMC_READ_4(sc, A10_MMC_STAS) & bit))
- return (1);
- if (write)
- A10_MMC_WRITE_4(sc, A10_MMC_FIFO, buf[i]);
- else
- buf[i] = A10_MMC_READ_4(sc, A10_MMC_FIFO);
- sc->a10_resid = i + 1;
- }
-
- return (0);
-}
-
-static void
-a10_mmc_intr(void *arg)
-{
- bus_dmasync_op_t sync_op;
- struct a10_mmc_softc *sc;
- struct mmc_data *data;
- uint32_t idst, imask, rint;
-
- sc = (struct a10_mmc_softc *)arg;
- A10_MMC_LOCK(sc);
- rint = A10_MMC_READ_4(sc, A10_MMC_RINTR);
- idst = A10_MMC_READ_4(sc, A10_MMC_IDST);
- imask = A10_MMC_READ_4(sc, A10_MMC_IMASK);
- if (idst == 0 && imask == 0 && rint == 0) {
- A10_MMC_UNLOCK(sc);
- return;
- }
-#ifdef DEBUG
- device_printf(sc->a10_dev, "idst: %#x, imask: %#x, rint: %#x\n",
- idst, imask, rint);
-#endif
- if (sc->a10_req == NULL) {
- device_printf(sc->a10_dev,
- "Spurious interrupt - no active request, rint: 0x%08X\n",
- rint);
- goto end;
- }
- if (rint & A10_MMC_INT_ERR_BIT) {
- device_printf(sc->a10_dev, "error rint: 0x%08X\n", rint);
- if (rint & A10_MMC_RESP_TIMEOUT)
- sc->a10_req->cmd->error = MMC_ERR_TIMEOUT;
- else
- sc->a10_req->cmd->error = MMC_ERR_FAILED;
- a10_mmc_req_done(sc);
- goto end;
- }
- if (idst & A10_MMC_IDMAC_ERROR) {
- device_printf(sc->a10_dev, "error idst: 0x%08x\n", idst);
- sc->a10_req->cmd->error = MMC_ERR_FAILED;
- a10_mmc_req_done(sc);
- goto end;
- }
-
- sc->a10_intr |= rint;
- data = sc->a10_req->cmd->data;
- if (data != NULL && sc->a10_dma_inuse == 1 &&
- (idst & A10_MMC_IDMAC_COMPLETE)) {
- if (data->flags & MMC_DATA_WRITE)
- sync_op = BUS_DMASYNC_POSTWRITE;
- else
- sync_op = BUS_DMASYNC_POSTREAD;
- bus_dmamap_sync(sc->a10_dma_buf_tag, sc->a10_dma_buf_map,
- sync_op);
- bus_dmamap_sync(sc->a10_dma_tag, sc->a10_dma_map,
- BUS_DMASYNC_POSTWRITE);
- bus_dmamap_unload(sc->a10_dma_buf_tag, sc->a10_dma_buf_map);
- sc->a10_resid = data->len >> 2;
- } else if (data != NULL && sc->a10_dma_inuse == 0 &&
- (rint & (A10_MMC_DATA_OVER | A10_MMC_RX_DATA_REQ |
- A10_MMC_TX_DATA_REQ)) != 0)
- a10_mmc_pio_transfer(sc, data);
- if ((sc->a10_intr & sc->a10_intr_wait) == sc->a10_intr_wait)
- a10_mmc_req_ok(sc);
-
-end:
- A10_MMC_WRITE_4(sc, A10_MMC_IDST, idst);
- A10_MMC_WRITE_4(sc, A10_MMC_RINTR, rint);
- A10_MMC_UNLOCK(sc);
-}
-
-static int
-a10_mmc_request(device_t bus, device_t child, struct mmc_request *req)
-{
- int blksz;
- struct a10_mmc_softc *sc;
- struct mmc_command *cmd;
- uint32_t cmdreg, val;
-
- sc = device_get_softc(bus);
- A10_MMC_LOCK(sc);
- if (sc->a10_req) {
- A10_MMC_UNLOCK(sc);
- return (EBUSY);
- }
- sc->a10_req = req;
- cmd = req->cmd;
- cmdreg = A10_MMC_START;
- if (cmd->opcode == MMC_GO_IDLE_STATE)
- cmdreg |= A10_MMC_SEND_INIT_SEQ;
- if (cmd->flags & MMC_RSP_PRESENT)
- cmdreg |= A10_MMC_RESP_EXP;
- if (cmd->flags & MMC_RSP_136)
- cmdreg |= A10_MMC_LONG_RESP;
- if (cmd->flags & MMC_RSP_CRC)
- cmdreg |= A10_MMC_CHECK_RESP_CRC;
-
- sc->a10_intr = 0;
- sc->a10_resid = 0;
- sc->a10_intr_wait = A10_MMC_CMD_DONE;
- cmd->error = MMC_ERR_NONE;
- if (cmd->data != NULL) {
- sc->a10_intr_wait |= A10_MMC_DATA_OVER;
- cmdreg |= A10_MMC_DATA_EXP | A10_MMC_WAIT_PREOVER;
- if (cmd->data->flags & MMC_DATA_MULTI) {
- cmdreg |= A10_MMC_SEND_AUTOSTOP;
- sc->a10_intr_wait |= A10_MMC_AUTOCMD_DONE;
- }
- if (cmd->data->flags & MMC_DATA_WRITE)
- cmdreg |= A10_MMC_WRITE;
- blksz = min(cmd->data->len, MMC_SECTOR_SIZE);
- A10_MMC_WRITE_4(sc, A10_MMC_BLKSZ, blksz);
- A10_MMC_WRITE_4(sc, A10_MMC_BCNTR, cmd->data->len);
-
- if (a10_mmc_pio_mode == 0)
- a10_mmc_prepare_dma(sc);
- /* Enable PIO access if sc->a10_dma_inuse is not set. */
- if (sc->a10_dma_inuse == 0) {
- val = A10_MMC_READ_4(sc, A10_MMC_GCTRL);
- val &= ~A10_MMC_DMA_ENABLE;
- val |= A10_MMC_ACCESS_BY_AHB;
- A10_MMC_WRITE_4(sc, A10_MMC_GCTRL, val);
- val = A10_MMC_READ_4(sc, A10_MMC_IMASK);
- val |= A10_MMC_RX_DATA_REQ | A10_MMC_TX_DATA_REQ;
- A10_MMC_WRITE_4(sc, A10_MMC_IMASK, val);
- }
- }
-
- A10_MMC_WRITE_4(sc, A10_MMC_CARG, cmd->arg);
- A10_MMC_WRITE_4(sc, A10_MMC_CMDR, cmdreg | cmd->opcode);
- callout_reset(&sc->a10_timeoutc, sc->a10_timeout * hz,
- a10_mmc_timeout, sc);
- A10_MMC_UNLOCK(sc);
-
- return (0);
-}
-
-static int
-a10_mmc_read_ivar(device_t bus, device_t child, int which,
- uintptr_t *result)
-{
- struct a10_mmc_softc *sc;
-
- sc = device_get_softc(bus);
- switch (which) {
- default:
- return (EINVAL);
- case MMCBR_IVAR_BUS_MODE:
- *(int *)result = sc->a10_host.ios.bus_mode;
- break;
- case MMCBR_IVAR_BUS_WIDTH:
- *(int *)result = sc->a10_host.ios.bus_width;
- break;
- case MMCBR_IVAR_CHIP_SELECT:
- *(int *)result = sc->a10_host.ios.chip_select;
- break;
- case MMCBR_IVAR_CLOCK:
- *(int *)result = sc->a10_host.ios.clock;
- break;
- case MMCBR_IVAR_F_MIN:
- *(int *)result = sc->a10_host.f_min;
- break;
- case MMCBR_IVAR_F_MAX:
- *(int *)result = sc->a10_host.f_max;
- break;
- case MMCBR_IVAR_HOST_OCR:
- *(int *)result = sc->a10_host.host_ocr;
- break;
- case MMCBR_IVAR_MODE:
- *(int *)result = sc->a10_host.mode;
- break;
- case MMCBR_IVAR_OCR:
- *(int *)result = sc->a10_host.ocr;
- break;
- case MMCBR_IVAR_POWER_MODE:
- *(int *)result = sc->a10_host.ios.power_mode;
- break;
- case MMCBR_IVAR_VDD:
- *(int *)result = sc->a10_host.ios.vdd;
- break;
- case MMCBR_IVAR_CAPS:
- *(int *)result = sc->a10_host.caps;
- break;
- case MMCBR_IVAR_MAX_DATA:
- *(int *)result = 65535;
- break;
- }
-
- return (0);
-}
-
-static int
-a10_mmc_write_ivar(device_t bus, device_t child, int which,
- uintptr_t value)
-{
- struct a10_mmc_softc *sc;
-
- sc = device_get_softc(bus);
- switch (which) {
- default:
- return (EINVAL);
- case MMCBR_IVAR_BUS_MODE:
- sc->a10_host.ios.bus_mode = value;
- break;
- case MMCBR_IVAR_BUS_WIDTH:
- sc->a10_host.ios.bus_width = value;
- break;
- case MMCBR_IVAR_CHIP_SELECT:
- sc->a10_host.ios.chip_select = value;
- break;
- case MMCBR_IVAR_CLOCK:
- sc->a10_host.ios.clock = value;
- break;
- case MMCBR_IVAR_MODE:
- sc->a10_host.mode = value;
- break;
- case MMCBR_IVAR_OCR:
- sc->a10_host.ocr = value;
- break;
- case MMCBR_IVAR_POWER_MODE:
- sc->a10_host.ios.power_mode = value;
- break;
- case MMCBR_IVAR_VDD:
- sc->a10_host.ios.vdd = value;
- break;
- /* These are read-only */
- case MMCBR_IVAR_CAPS:
- case MMCBR_IVAR_HOST_OCR:
- case MMCBR_IVAR_F_MIN:
- case MMCBR_IVAR_F_MAX:
- case MMCBR_IVAR_MAX_DATA:
- return (EINVAL);
- }
-
- return (0);
-}
-
-static int
-a10_mmc_update_clock(struct a10_mmc_softc *sc)
-{
- uint32_t cmdreg;
- int retry;
-
- cmdreg = A10_MMC_START | A10_MMC_UPCLK_ONLY |
- A10_MMC_WAIT_PREOVER;
- A10_MMC_WRITE_4(sc, A10_MMC_CMDR, cmdreg);
- retry = 0xfffff;
- while (--retry > 0) {
- if ((A10_MMC_READ_4(sc, A10_MMC_CMDR) & A10_MMC_START) == 0) {
- A10_MMC_WRITE_4(sc, A10_MMC_RINTR, 0xffffffff);
- return (0);
- }
- DELAY(10);
- }
- A10_MMC_WRITE_4(sc, A10_MMC_RINTR, 0xffffffff);
- device_printf(sc->a10_dev, "timeout updating clock\n");
-
- return (ETIMEDOUT);
-}
-
-static int
-a10_mmc_update_ios(device_t bus, device_t child)
-{
- int error;
- struct a10_mmc_softc *sc;
- struct mmc_ios *ios;
- uint32_t clkcr;
-
- sc = device_get_softc(bus);
- clkcr = A10_MMC_READ_4(sc, A10_MMC_CLKCR);
- if (clkcr & A10_MMC_CARD_CLK_ON) {
- /* Disable clock. */
- clkcr &= ~A10_MMC_CARD_CLK_ON;
- A10_MMC_WRITE_4(sc, A10_MMC_CLKCR, clkcr);
- error = a10_mmc_update_clock(sc);
- if (error != 0)
- return (error);
- }
-
- ios = &sc->a10_host.ios;
- if (ios->clock) {
- /* Reset the divider. */
- clkcr &= ~A10_MMC_CLKCR_DIV;
- A10_MMC_WRITE_4(sc, A10_MMC_CLKCR, clkcr);
- error = a10_mmc_update_clock(sc);
- if (error != 0)
- return (error);
-
- /* Set the MMC clock. */
- error = a10_clk_mmc_cfg(sc->a10_id, ios->clock);
- if (error != 0)
- return (error);
-
- /* Enable clock. */
- clkcr |= A10_MMC_CARD_CLK_ON;
- A10_MMC_WRITE_4(sc, A10_MMC_CLKCR, clkcr);
- error = a10_mmc_update_clock(sc);
- if (error != 0)
- return (error);
- }
-
- /* Set the bus width. */
- switch (ios->bus_width) {
- case bus_width_1:
- A10_MMC_WRITE_4(sc, A10_MMC_WIDTH, A10_MMC_WIDTH1);
- break;
- case bus_width_4:
- A10_MMC_WRITE_4(sc, A10_MMC_WIDTH, A10_MMC_WIDTH4);
- break;
- case bus_width_8:
- A10_MMC_WRITE_4(sc, A10_MMC_WIDTH, A10_MMC_WIDTH8);
- break;
- }
-
- return (0);
-}
-
-static int
-a10_mmc_get_ro(device_t bus, device_t child)
-{
-
- return (0);
-}
-
-static int
-a10_mmc_acquire_host(device_t bus, device_t child)
-{
- struct a10_mmc_softc *sc;
- int error;
-
- sc = device_get_softc(bus);
- A10_MMC_LOCK(sc);
- while (sc->a10_bus_busy) {
- error = msleep(sc, &sc->a10_mtx, PCATCH, "mmchw", 0);
- if (error != 0) {
- A10_MMC_UNLOCK(sc);
- return (error);
- }
- }
- sc->a10_bus_busy++;
- A10_MMC_UNLOCK(sc);
-
- return (0);
-}
-
-static int
-a10_mmc_release_host(device_t bus, device_t child)
-{
- struct a10_mmc_softc *sc;
-
- sc = device_get_softc(bus);
- A10_MMC_LOCK(sc);
- sc->a10_bus_busy--;
- wakeup(sc);
- A10_MMC_UNLOCK(sc);
-
- return (0);
-}
-
-static device_method_t a10_mmc_methods[] = {
- /* Device interface */
- DEVMETHOD(device_probe, a10_mmc_probe),
- DEVMETHOD(device_attach, a10_mmc_attach),
- DEVMETHOD(device_detach, a10_mmc_detach),
-
- /* Bus interface */
- DEVMETHOD(bus_read_ivar, a10_mmc_read_ivar),
- DEVMETHOD(bus_write_ivar, a10_mmc_write_ivar),
- DEVMETHOD(bus_print_child, bus_generic_print_child),
-
- /* MMC bridge interface */
- DEVMETHOD(mmcbr_update_ios, a10_mmc_update_ios),
- DEVMETHOD(mmcbr_request, a10_mmc_request),
- DEVMETHOD(mmcbr_get_ro, a10_mmc_get_ro),
- DEVMETHOD(mmcbr_acquire_host, a10_mmc_acquire_host),
- DEVMETHOD(mmcbr_release_host, a10_mmc_release_host),
-
- DEVMETHOD_END
-};
-
-static devclass_t a10_mmc_devclass;
-
-static driver_t a10_mmc_driver = {
- "a10_mmc",
- a10_mmc_methods,
- sizeof(struct a10_mmc_softc),
-};
-
-DRIVER_MODULE(a10_mmc, simplebus, a10_mmc_driver, a10_mmc_devclass, 0, 0);
-DRIVER_MODULE(mmc, a10_mmc, mmc_driver, mmc_devclass, NULL, NULL);
Index: sys/arm/allwinner/a10_sramc.h
===================================================================
--- /dev/null
+++ sys/arm/allwinner/a10_sramc.h
@@ -1,34 +0,0 @@
-/*-
- * Copyright (c) 2013 Ganbold Tsagaankhuu <ganbold@freebsd.org>
- * 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 AND CONTRIBUTORS ``AS IS'' AND
- * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
- * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
- * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
- * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
- * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
- * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION
- * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
- * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE ARISING IN ANY WAY
- * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
- * SUCH DAMAGE.
- *
- * $FreeBSD$
- */
-
-#ifndef _A10_SRAMC_H_
-#define _A10_SRAMC_H_
-
-int a10_map_to_emac(void);
-
-#endif
Index: sys/arm/allwinner/a10_sramc.c
===================================================================
--- /dev/null
+++ sys/arm/allwinner/a10_sramc.c
@@ -1,133 +0,0 @@
-/*-
- * Copyright (c) 2013 Ganbold Tsagaankhuu <ganbold@freebsd.org>
- * 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 AND CONTRIBUTORS ``AS IS'' AND
- * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
- * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
- * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
- * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
- * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
- * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION
- * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
- * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE ARISING IN ANY WAY
- * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
- * SUCH DAMAGE.
- *
- * $FreeBSD$
- */
-
-#include <sys/cdefs.h>
-__FBSDID("$FreeBSD$");
-
-#include <sys/param.h>
-#include <sys/systm.h>
-#include <sys/bus.h>
-#include <sys/kernel.h>
-#include <sys/module.h>
-#include <sys/malloc.h>
-#include <sys/rman.h>
-#include <sys/timeet.h>
-#include <sys/timetc.h>
-#include <sys/watchdog.h>
-#include <machine/bus.h>
-#include <machine/cpu.h>
-#include <machine/frame.h>
-#include <machine/intr.h>
-
-#include <dev/fdt/fdt_common.h>
-#include <dev/ofw/openfirm.h>
-#include <dev/ofw/ofw_bus.h>
-#include <dev/ofw/ofw_bus_subr.h>
-
-#include "a10_sramc.h"
-
-#define SRAM_CTL1_CFG 0x04
-
-struct a10_sramc_softc {
- struct resource *res;
- bus_space_tag_t bst;
- bus_space_handle_t bsh;
-};
-
-static struct a10_sramc_softc *a10_sramc_sc;
-
-#define sramc_read_4(sc, reg) \
- bus_space_read_4((sc)->bst, (sc)->bsh, (reg))
-#define sramc_write_4(sc, reg, val) \
- bus_space_write_4((sc)->bst, (sc)->bsh, (reg), (val))
-
-
-static int
-a10_sramc_probe(device_t dev)
-{
-
- if (ofw_bus_is_compatible(dev, "allwinner,sun4i-sramc")) {
- device_set_desc(dev, "Allwinner sramc module");
- return (BUS_PROBE_DEFAULT);
- }
-
- return (ENXIO);
-}
-
-static int
-a10_sramc_attach(device_t dev)
-{
- struct a10_sramc_softc *sc = device_get_softc(dev);
- int rid = 0;
-
- sc->res = bus_alloc_resource_any(dev, SYS_RES_MEMORY, &rid, RF_ACTIVE);
- if (!sc->res) {
- device_printf(dev, "could not allocate resource\n");
- return (ENXIO);
- }
-
- sc->bst = rman_get_bustag(sc->res);
- sc->bsh = rman_get_bushandle(sc->res);
-
- a10_sramc_sc = sc;
-
- return (0);
-}
-
-static device_method_t a10_sramc_methods[] = {
- DEVMETHOD(device_probe, a10_sramc_probe),
- DEVMETHOD(device_attach, a10_sramc_attach),
- { 0, 0 }
-};
-
-static driver_t a10_sramc_driver = {
- "a10_sramc",
- a10_sramc_methods,
- sizeof(struct a10_sramc_softc),
-};
-
-static devclass_t a10_sramc_devclass;
-
-DRIVER_MODULE(a10_sramc, simplebus, a10_sramc_driver, a10_sramc_devclass, 0, 0);
-
-int
-a10_map_to_emac(void)
-{
- struct a10_sramc_softc *sc = a10_sramc_sc;
- uint32_t reg_value;
-
- if (sc == NULL)
- return (ENXIO);
-
- /* Map SRAM to EMAC, set bit 2 and 4. */
- reg_value = sramc_read_4(sc, SRAM_CTL1_CFG);
- reg_value |= 0x5 << 2;
- sramc_write_4(sc, SRAM_CTL1_CFG, reg_value);
-
- return (0);
-}
Index: sys/arm/allwinner/a20/files.a20
===================================================================
--- sys/arm/allwinner/a20/files.a20
+++ sys/arm/allwinner/a20/files.a20
@@ -1,4 +1,3 @@
# $FreeBSD$
arm/allwinner/a20/a20_mp.c optional smp
-arm/allwinner/a20/a20_if_dwc.c optional dwc
Index: sys/arm/allwinner/aintc.c
===================================================================
--- /dev/null
+++ sys/arm/allwinner/aintc.c
@@ -1,222 +0,0 @@
-/*-
- * Copyright (c) 2012 Ganbold Tsagaankhuu <ganbold@freebsd.org>
- * 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 AND CONTRIBUTORS ``AS IS'' AND
- * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
- * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
- * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
- * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
- * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
- * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
- * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
- * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
- * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
- * SUCH DAMAGE.
- */
-
-#include <sys/cdefs.h>
-__FBSDID("$FreeBSD$");
-
-#include <sys/param.h>
-#include <sys/systm.h>
-#include <sys/bus.h>
-#include <sys/kernel.h>
-#include <sys/ktr.h>
-#include <sys/module.h>
-#include <sys/rman.h>
-#include <machine/bus.h>
-#include <machine/intr.h>
-
-#include <dev/fdt/fdt_common.h>
-#include <dev/ofw/openfirm.h>
-#include <dev/ofw/ofw_bus.h>
-#include <dev/ofw/ofw_bus_subr.h>
-
-/**
- * Interrupt controller registers
- *
- */
-#define SW_INT_VECTOR_REG 0x00
-#define SW_INT_BASE_ADR_REG 0x04
-#define SW_INT_PROTECTION_REG 0x08
-#define SW_INT_NMI_CTRL_REG 0x0c
-
-#define SW_INT_IRQ_PENDING_REG0 0x10
-#define SW_INT_IRQ_PENDING_REG1 0x14
-#define SW_INT_IRQ_PENDING_REG2 0x18
-
-#define SW_INT_FIQ_PENDING_REG0 0x20
-#define SW_INT_FIQ_PENDING_REG1 0x24
-#define SW_INT_FIQ_PENDING_REG2 0x28
-
-#define SW_INT_SELECT_REG0 0x30
-#define SW_INT_SELECT_REG1 0x34
-#define SW_INT_SELECT_REG2 0x38
-
-#define SW_INT_ENABLE_REG0 0x40
-#define SW_INT_ENABLE_REG1 0x44
-#define SW_INT_ENABLE_REG2 0x48
-
-#define SW_INT_MASK_REG0 0x50
-#define SW_INT_MASK_REG1 0x54
-#define SW_INT_MASK_REG2 0x58
-
-#define SW_INT_IRQNO_ENMI 0
-
-#define SW_INT_IRQ_PENDING_REG(_b) (0x10 + ((_b) * 4))
-#define SW_INT_FIQ_PENDING_REG(_b) (0x20 + ((_b) * 4))
-#define SW_INT_SELECT_REG(_b) (0x30 + ((_b) * 4))
-#define SW_INT_ENABLE_REG(_b) (0x40 + ((_b) * 4))
-#define SW_INT_MASK_REG(_b) (0x50 + ((_b) * 4))
-
-static struct ofw_compat_data compat_data[] = {
- {"allwinner,sun4i-a10-ic", 1},
- {"allwinner,sun7i-a20-sc-nmi", 1},
- {NULL, 0}
-};
-
-struct a10_aintc_softc {
- device_t sc_dev;
- struct resource * aintc_res;
- bus_space_tag_t aintc_bst;
- bus_space_handle_t aintc_bsh;
- uint8_t ver;
-};
-
-static struct a10_aintc_softc *a10_aintc_sc = NULL;
-
-#define aintc_read_4(reg) \
- bus_space_read_4(a10_aintc_sc->aintc_bst, a10_aintc_sc->aintc_bsh, reg)
-#define aintc_write_4(reg, val) \
- bus_space_write_4(a10_aintc_sc->aintc_bst, a10_aintc_sc->aintc_bsh, reg, val)
-
-static int
-a10_aintc_probe(device_t dev)
-{
-
- if (!ofw_bus_status_okay(dev))
- return (ENXIO);
-
- if (ofw_bus_search_compatible(dev, compat_data)->ocd_data == 0)
- return (ENXIO);
- device_set_desc(dev, "A10 AINTC Interrupt Controller");
- return (BUS_PROBE_DEFAULT);
-}
-
-static int
-a10_aintc_attach(device_t dev)
-{
- struct a10_aintc_softc *sc = device_get_softc(dev);
- int rid = 0;
- int i;
-
- sc->sc_dev = dev;
-
- if (a10_aintc_sc)
- return (ENXIO);
-
- sc->aintc_res = bus_alloc_resource_any(dev, SYS_RES_MEMORY, &rid, RF_ACTIVE);
- if (!sc->aintc_res) {
- device_printf(dev, "could not allocate resource\n");
- return (ENXIO);
- }
-
- sc->aintc_bst = rman_get_bustag(sc->aintc_res);
- sc->aintc_bsh = rman_get_bushandle(sc->aintc_res);
-
- a10_aintc_sc = sc;
-
- /* Disable & clear all interrupts */
- for (i = 0; i < 3; i++) {
- aintc_write_4(SW_INT_ENABLE_REG(i), 0);
- aintc_write_4(SW_INT_MASK_REG(i), 0xffffffff);
- }
- /* enable protection mode*/
- aintc_write_4(SW_INT_PROTECTION_REG, 0x01);
-
- /* config the external interrupt source type*/
- aintc_write_4(SW_INT_NMI_CTRL_REG, 0x00);
-
- return (0);
-}
-
-static device_method_t a10_aintc_methods[] = {
- DEVMETHOD(device_probe, a10_aintc_probe),
- DEVMETHOD(device_attach, a10_aintc_attach),
- { 0, 0 }
-};
-
-static driver_t a10_aintc_driver = {
- "aintc",
- a10_aintc_methods,
- sizeof(struct a10_aintc_softc),
-};
-
-static devclass_t a10_aintc_devclass;
-
-EARLY_DRIVER_MODULE(aintc, simplebus, a10_aintc_driver, a10_aintc_devclass, 0, 0,
- BUS_PASS_INTERRUPT + BUS_PASS_ORDER_FIRST);
-
-int
-arm_get_next_irq(int last_irq)
-{
- uint32_t value;
- int i, b;
-
- for (i = 0; i < 3; i++) {
- value = aintc_read_4(SW_INT_IRQ_PENDING_REG(i));
- for (b = 0; b < 32; b++)
- if (value & (1 << b)) {
- return (i * 32 + b);
- }
- }
-
- return (-1);
-}
-
-void
-arm_mask_irq(uintptr_t nb)
-{
- uint32_t bit, block, value;
-
- bit = (nb % 32);
- block = (nb / 32);
-
- value = aintc_read_4(SW_INT_ENABLE_REG(block));
- value &= ~(1 << bit);
- aintc_write_4(SW_INT_ENABLE_REG(block), value);
-
- value = aintc_read_4(SW_INT_MASK_REG(block));
- value |= (1 << bit);
- aintc_write_4(SW_INT_MASK_REG(block), value);
-}
-
-void
-arm_unmask_irq(uintptr_t nb)
-{
- uint32_t bit, block, value;
-
- bit = (nb % 32);
- block = (nb / 32);
-
- value = aintc_read_4(SW_INT_ENABLE_REG(block));
- value |= (1 << bit);
- aintc_write_4(SW_INT_ENABLE_REG(block), value);
-
- value = aintc_read_4(SW_INT_MASK_REG(block));
- value &= ~(1 << bit);
- aintc_write_4(SW_INT_MASK_REG(block), value);
-
- if(nb == SW_INT_IRQNO_ENMI) /* must clear pending bit when enabled */
- aintc_write_4(SW_INT_IRQ_PENDING_REG(0), (1 << SW_INT_IRQNO_ENMI));
-}
Index: sys/arm/allwinner/allwinner_machdep.h
===================================================================
--- /dev/null
+++ sys/arm/allwinner/allwinner_machdep.h
@@ -1,45 +0,0 @@
-/*-
- * Copyright (c) 2015 Emmanuel Vadot <manu@bidouilliste.com>
- * 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 AND CONTRIBUTORS ``AS IS'' AND
- * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
- * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
- * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
- * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
- * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
- * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
- * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
- * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
- * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
- * SUCH DAMAGE.
- *
- * $FreeBSD$
- *
- */
-
-#ifndef AW_MACHDEP_H
-#define AW_MACHDEP_H
-
-#define ALLWINNERSOC_A10 0x10000000
-#define ALLWINNERSOC_A13 0x13000000
-#define ALLWINNERSOC_A10S 0x10000001
-#define ALLWINNERSOC_A20 0x20000000
-
-#define ALLWINNERSOC_SUN4I 0x40000000
-#define ALLWINNERSOC_SUN5I 0x50000000
-#define ALLWINNERSOC_SUN7I 0x70000000
-
-u_int allwinner_soc_type(void);
-u_int allwinner_soc_family(void);
-
-#endif /* AW_MACHDEP_H */
Index: sys/arm/allwinner/aw_ehci.c
===================================================================
--- sys/arm/allwinner/aw_ehci.c
+++ sys/arm/allwinner/aw_ehci.c
@@ -59,9 +59,9 @@
#include <dev/usb/controller/ehci.h>
#include <dev/usb/controller/ehcireg.h>
-#include "gpio_if.h"
+#include <arm/allwinner/a10/a10_clk.h>
-#include "a10_clk.h"
+#include "gpio_if.h"
#define EHCI_HC_DEVSTR "Allwinner Integrated USB 2.0 controller"
@@ -78,14 +78,14 @@
#define GPIO_USB1_PWR 230
#define GPIO_USB2_PWR 227
-#define A10_READ_4(sc, reg) \
+#define AW_READ_4(sc, reg) \
bus_space_read_4((sc)->sc_io_tag, (sc)->sc_io_hdl, reg)
-#define A10_WRITE_4(sc, reg, data) \
+#define AW_WRITE_4(sc, reg, data) \
bus_space_write_4((sc)->sc_io_tag, (sc)->sc_io_hdl, reg, data)
-static device_attach_t a10_ehci_attach;
-static device_detach_t a10_ehci_detach;
+static device_attach_t aw_ehci_attach;
+static device_detach_t aw_ehci_detach;
bs_r_1_proto(reversed);
bs_w_1_proto(reversed);
@@ -97,7 +97,7 @@
};
static int
-a10_ehci_probe(device_t self)
+aw_ehci_probe(device_t self)
{
if (!ofw_bus_status_okay(self))
@@ -112,7 +112,7 @@
}
static int
-a10_ehci_attach(device_t self)
+aw_ehci_attach(device_t self)
{
ehci_softc_t *sc = device_get_softc(self);
bus_space_handle_t bsh;
@@ -199,17 +199,17 @@
GPIO_PIN_SET(sc_gpio_dev, GPIO_USB1_PWR, GPIO_PIN_HIGH);
/* Enable passby */
- reg_value = A10_READ_4(sc, SW_USB_PMU_IRQ_ENABLE);
+ reg_value = AW_READ_4(sc, SW_USB_PMU_IRQ_ENABLE);
reg_value |= SW_AHB_INCR8; /* AHB INCR8 enable */
reg_value |= SW_AHB_INCR4; /* AHB burst type INCR4 enable */
reg_value |= SW_AHB_INCRX_ALIGN; /* AHB INCRX align enable */
reg_value |= SW_ULPI_BYPASS; /* ULPI bypass enable */
- A10_WRITE_4(sc, SW_USB_PMU_IRQ_ENABLE, reg_value);
+ AW_WRITE_4(sc, SW_USB_PMU_IRQ_ENABLE, reg_value);
/* Configure port */
- reg_value = A10_READ_4(sc, SW_SDRAM_REG_HPCR_USB2);
+ reg_value = AW_READ_4(sc, SW_SDRAM_REG_HPCR_USB2);
reg_value |= SW_SDRAM_BP_HPCR_ACCESS;
- A10_WRITE_4(sc, SW_SDRAM_REG_HPCR_USB2, reg_value);
+ AW_WRITE_4(sc, SW_SDRAM_REG_HPCR_USB2, reg_value);
err = ehci_init(sc);
if (!err) {
@@ -222,12 +222,12 @@
return (0);
error:
- a10_ehci_detach(self);
+ aw_ehci_detach(self);
return (ENXIO);
}
static int
-a10_ehci_detach(device_t self)
+aw_ehci_detach(device_t self)
{
ehci_softc_t *sc = device_get_softc(self);
device_t bdev;
@@ -269,17 +269,17 @@
usb_bus_mem_free_all(&sc->sc_bus, &ehci_iterate_hw_softc);
/* Disable configure port */
- reg_value = A10_READ_4(sc, SW_SDRAM_REG_HPCR_USB2);
+ reg_value = AW_READ_4(sc, SW_SDRAM_REG_HPCR_USB2);
reg_value &= ~SW_SDRAM_BP_HPCR_ACCESS;
- A10_WRITE_4(sc, SW_SDRAM_REG_HPCR_USB2, reg_value);
+ AW_WRITE_4(sc, SW_SDRAM_REG_HPCR_USB2, reg_value);
/* Disable passby */
- reg_value = A10_READ_4(sc, SW_USB_PMU_IRQ_ENABLE);
+ reg_value = AW_READ_4(sc, SW_USB_PMU_IRQ_ENABLE);
reg_value &= ~SW_AHB_INCR8; /* AHB INCR8 disable */
reg_value &= ~SW_AHB_INCR4; /* AHB burst type INCR4 disable */
reg_value &= ~SW_AHB_INCRX_ALIGN; /* AHB INCRX align disable */
reg_value &= ~SW_ULPI_BYPASS; /* ULPI bypass disable */
- A10_WRITE_4(sc, SW_USB_PMU_IRQ_ENABLE, reg_value);
+ AW_WRITE_4(sc, SW_USB_PMU_IRQ_ENABLE, reg_value);
/* Disable clock for USB */
a10_clk_usb_deactivate();
@@ -289,9 +289,9 @@
static device_method_t ehci_methods[] = {
/* Device interface */
- DEVMETHOD(device_probe, a10_ehci_probe),
- DEVMETHOD(device_attach, a10_ehci_attach),
- DEVMETHOD(device_detach, a10_ehci_detach),
+ DEVMETHOD(device_probe, aw_ehci_probe),
+ DEVMETHOD(device_attach, aw_ehci_attach),
+ DEVMETHOD(device_detach, aw_ehci_detach),
DEVMETHOD(device_suspend, bus_generic_suspend),
DEVMETHOD(device_resume, bus_generic_resume),
DEVMETHOD(device_shutdown, bus_generic_shutdown),
Index: sys/arm/allwinner/aw_gpio.h
===================================================================
--- sys/arm/allwinner/aw_gpio.h
+++ sys/arm/allwinner/aw_gpio.h
@@ -26,12 +26,12 @@
* $FreeBSD$
*/
-#ifndef _A10_GPIO_H_
-#define _A10_GPIO_H_
+#ifndef _AW_GPIO_H_
+#define _AW_GPIO_H_
-#define A10_GPIO_FUNC_MII 2
-#define A10_GPIO_FUNC_RGMII 5
+#define AW_GPIO_FUNC_MII 2
+#define AW_GPIO_FUNC_RGMII 5
-int a10_gpio_ethernet_activate(uint32_t);
+int aw_gpio_ethernet_activate(uint32_t);
#endif
Index: sys/arm/allwinner/aw_gpio.c
===================================================================
--- sys/arm/allwinner/aw_gpio.c
+++ sys/arm/allwinner/aw_gpio.c
@@ -52,7 +52,7 @@
#include <dev/ofw/ofw_bus_subr.h>
#include "gpio_if.h"
-#include "a10_gpio.h"
+#include "aw_gpio.h"
/*
* A10 have 9 banks of gpio.
@@ -62,16 +62,16 @@
* PG0 - PG9 | PH0 - PH27 | PI0 - PI12
*/
-#define A10_GPIO_PINS 288
-#define A10_GPIO_DEFAULT_CAPS (GPIO_PIN_INPUT | GPIO_PIN_OUTPUT | \
+#define AW_GPIO_PINS 288
+#define AW_GPIO_DEFAULT_CAPS (GPIO_PIN_INPUT | GPIO_PIN_OUTPUT | \
GPIO_PIN_PULLUP | GPIO_PIN_PULLDOWN)
-#define A10_GPIO_NONE 0
-#define A10_GPIO_PULLUP 1
-#define A10_GPIO_PULLDOWN 2
+#define AW_GPIO_NONE 0
+#define AW_GPIO_PULLUP 1
+#define AW_GPIO_PULLDOWN 2
-#define A10_GPIO_INPUT 0
-#define A10_GPIO_OUTPUT 1
+#define AW_GPIO_INPUT 0
+#define AW_GPIO_OUTPUT 1
static struct ofw_compat_data compat_data[] = {
{"allwinner,sun4i-a10-pinctrl", 1},
@@ -79,7 +79,7 @@
{NULL, 0}
};
-struct a10_gpio_softc {
+struct aw_gpio_softc {
device_t sc_dev;
device_t sc_busdev;
struct mtx sc_mtx;
@@ -90,48 +90,48 @@
void * sc_intrhand;
};
-#define A10_GPIO_LOCK(_sc) mtx_lock_spin(&(_sc)->sc_mtx)
-#define A10_GPIO_UNLOCK(_sc) mtx_unlock_spin(&(_sc)->sc_mtx)
-#define A10_GPIO_LOCK_ASSERT(_sc) mtx_assert(&(_sc)->sc_mtx, MA_OWNED)
+#define AW_GPIO_LOCK(_sc) mtx_lock_spin(&(_sc)->sc_mtx)
+#define AW_GPIO_UNLOCK(_sc) mtx_unlock_spin(&(_sc)->sc_mtx)
+#define AW_GPIO_LOCK_ASSERT(_sc) mtx_assert(&(_sc)->sc_mtx, MA_OWNED)
-#define A10_GPIO_GP_CFG(_bank, _idx) 0x00 + ((_bank) * 0x24) + ((_idx) << 2)
-#define A10_GPIO_GP_DAT(_bank) 0x10 + ((_bank) * 0x24)
-#define A10_GPIO_GP_DRV(_bank, _idx) 0x14 + ((_bank) * 0x24) + ((_idx) << 2)
-#define A10_GPIO_GP_PUL(_bank, _idx) 0x1c + ((_bank) * 0x24) + ((_idx) << 2)
+#define AW_GPIO_GP_CFG(_bank, _idx) 0x00 + ((_bank) * 0x24) + ((_idx) << 2)
+#define AW_GPIO_GP_DAT(_bank) 0x10 + ((_bank) * 0x24)
+#define AW_GPIO_GP_DRV(_bank, _idx) 0x14 + ((_bank) * 0x24) + ((_idx) << 2)
+#define AW_GPIO_GP_PUL(_bank, _idx) 0x1c + ((_bank) * 0x24) + ((_idx) << 2)
-#define A10_GPIO_GP_INT_CFG0 0x200
-#define A10_GPIO_GP_INT_CFG1 0x204
-#define A10_GPIO_GP_INT_CFG2 0x208
-#define A10_GPIO_GP_INT_CFG3 0x20c
+#define AW_GPIO_GP_INT_CFG0 0x200
+#define AW_GPIO_GP_INT_CFG1 0x204
+#define AW_GPIO_GP_INT_CFG2 0x208
+#define AW_GPIO_GP_INT_CFG3 0x20c
-#define A10_GPIO_GP_INT_CTL 0x210
-#define A10_GPIO_GP_INT_STA 0x214
-#define A10_GPIO_GP_INT_DEB 0x218
+#define AW_GPIO_GP_INT_CTL 0x210
+#define AW_GPIO_GP_INT_STA 0x214
+#define AW_GPIO_GP_INT_DEB 0x218
-static struct a10_gpio_softc *a10_gpio_sc;
+static struct aw_gpio_softc *aw_gpio_sc;
-#define A10_GPIO_WRITE(_sc, _off, _val) \
+#define AW_GPIO_WRITE(_sc, _off, _val) \
bus_space_write_4(_sc->sc_bst, _sc->sc_bsh, _off, _val)
-#define A10_GPIO_READ(_sc, _off) \
+#define AW_GPIO_READ(_sc, _off) \
bus_space_read_4(_sc->sc_bst, _sc->sc_bsh, _off)
static uint32_t
-a10_gpio_get_function(struct a10_gpio_softc *sc, uint32_t pin)
+aw_gpio_get_function(struct aw_gpio_softc *sc, uint32_t pin)
{
uint32_t bank, func, offset;
/* Must be called with lock held. */
- A10_GPIO_LOCK_ASSERT(sc);
+ AW_GPIO_LOCK_ASSERT(sc);
bank = pin / 32;
pin = pin % 32;
offset = ((pin & 0x07) << 2);
- func = A10_GPIO_READ(sc, A10_GPIO_GP_CFG(bank, pin >> 3));
+ func = AW_GPIO_READ(sc, AW_GPIO_GP_CFG(bank, pin >> 3));
switch ((func >> offset) & 0x7) {
- case A10_GPIO_INPUT:
+ case AW_GPIO_INPUT:
return (GPIO_PIN_INPUT);
- case A10_GPIO_OUTPUT:
+ case AW_GPIO_OUTPUT:
return (GPIO_PIN_OUTPUT);
}
@@ -139,40 +139,40 @@
}
static void
-a10_gpio_set_function(struct a10_gpio_softc *sc, uint32_t pin, uint32_t f)
+aw_gpio_set_function(struct aw_gpio_softc *sc, uint32_t pin, uint32_t f)
{
uint32_t bank, data, offset;
/* Must be called with lock held. */
- A10_GPIO_LOCK_ASSERT(sc);
+ AW_GPIO_LOCK_ASSERT(sc);
bank = pin / 32;
pin = pin % 32;
offset = ((pin & 0x07) << 2);
- data = A10_GPIO_READ(sc, A10_GPIO_GP_CFG(bank, pin >> 3));
+ data = AW_GPIO_READ(sc, AW_GPIO_GP_CFG(bank, pin >> 3));
data &= ~(7 << offset);
data |= (f << offset);
- A10_GPIO_WRITE(sc, A10_GPIO_GP_CFG(bank, pin >> 3), data);
+ AW_GPIO_WRITE(sc, AW_GPIO_GP_CFG(bank, pin >> 3), data);
}
static uint32_t
-a10_gpio_get_pud(struct a10_gpio_softc *sc, uint32_t pin)
+aw_gpio_get_pud(struct aw_gpio_softc *sc, uint32_t pin)
{
uint32_t bank, offset, val;
/* Must be called with lock held. */
- A10_GPIO_LOCK_ASSERT(sc);
+ AW_GPIO_LOCK_ASSERT(sc);
bank = pin / 32;
pin = pin % 32;
offset = ((pin & 0x0f) << 1);
- val = A10_GPIO_READ(sc, A10_GPIO_GP_PUL(bank, pin >> 4));
+ val = AW_GPIO_READ(sc, AW_GPIO_GP_PUL(bank, pin >> 4));
switch ((val >> offset) & 0x3) {
- case A10_GPIO_PULLDOWN:
+ case AW_GPIO_PULLDOWN:
return (GPIO_PIN_PULLDOWN);
- case A10_GPIO_PULLUP:
+ case AW_GPIO_PULLUP:
return (GPIO_PIN_PULLUP);
}
@@ -180,52 +180,52 @@
}
static void
-a10_gpio_set_pud(struct a10_gpio_softc *sc, uint32_t pin, uint32_t state)
+aw_gpio_set_pud(struct aw_gpio_softc *sc, uint32_t pin, uint32_t state)
{
uint32_t bank, offset, val;
/* Must be called with lock held. */
- A10_GPIO_LOCK_ASSERT(sc);
+ AW_GPIO_LOCK_ASSERT(sc);
bank = pin / 32;
pin = pin % 32;
offset = ((pin & 0x0f) << 1);
- val = A10_GPIO_READ(sc, A10_GPIO_GP_PUL(bank, pin >> 4));
+ val = AW_GPIO_READ(sc, AW_GPIO_GP_PUL(bank, pin >> 4));
val &= ~(0x03 << offset);
val |= (state << offset);
- A10_GPIO_WRITE(sc, A10_GPIO_GP_PUL(bank, pin >> 4), val);
+ AW_GPIO_WRITE(sc, AW_GPIO_GP_PUL(bank, pin >> 4), val);
}
static void
-a10_gpio_pin_configure(struct a10_gpio_softc *sc, uint32_t pin, uint32_t flags)
+aw_gpio_pin_configure(struct aw_gpio_softc *sc, uint32_t pin, uint32_t flags)
{
/* Must be called with lock held. */
- A10_GPIO_LOCK_ASSERT(sc);
+ AW_GPIO_LOCK_ASSERT(sc);
/* Manage input/output. */
if (flags & (GPIO_PIN_INPUT | GPIO_PIN_OUTPUT)) {
if (flags & GPIO_PIN_OUTPUT)
- a10_gpio_set_function(sc, pin, A10_GPIO_OUTPUT);
+ aw_gpio_set_function(sc, pin, AW_GPIO_OUTPUT);
else
- a10_gpio_set_function(sc, pin, A10_GPIO_INPUT);
+ aw_gpio_set_function(sc, pin, AW_GPIO_INPUT);
}
/* Manage Pull-up/pull-down. */
if (flags & (GPIO_PIN_PULLUP | GPIO_PIN_PULLDOWN)) {
if (flags & GPIO_PIN_PULLUP)
- a10_gpio_set_pud(sc, pin, A10_GPIO_PULLUP);
+ aw_gpio_set_pud(sc, pin, AW_GPIO_PULLUP);
else
- a10_gpio_set_pud(sc, pin, A10_GPIO_PULLDOWN);
+ aw_gpio_set_pud(sc, pin, AW_GPIO_PULLDOWN);
} else
- a10_gpio_set_pud(sc, pin, A10_GPIO_NONE);
+ aw_gpio_set_pud(sc, pin, AW_GPIO_NONE);
}
static device_t
-a10_gpio_get_bus(device_t dev)
+aw_gpio_get_bus(device_t dev)
{
- struct a10_gpio_softc *sc;
+ struct aw_gpio_softc *sc;
sc = device_get_softc(dev);
@@ -233,48 +233,48 @@
}
static int
-a10_gpio_pin_max(device_t dev, int *maxpin)
+aw_gpio_pin_max(device_t dev, int *maxpin)
{
- *maxpin = A10_GPIO_PINS - 1;
+ *maxpin = AW_GPIO_PINS - 1;
return (0);
}
static int
-a10_gpio_pin_getcaps(device_t dev, uint32_t pin, uint32_t *caps)
+aw_gpio_pin_getcaps(device_t dev, uint32_t pin, uint32_t *caps)
{
- if (pin >= A10_GPIO_PINS)
+ if (pin >= AW_GPIO_PINS)
return (EINVAL);
- *caps = A10_GPIO_DEFAULT_CAPS;
+ *caps = AW_GPIO_DEFAULT_CAPS;
return (0);
}
static int
-a10_gpio_pin_getflags(device_t dev, uint32_t pin, uint32_t *flags)
+aw_gpio_pin_getflags(device_t dev, uint32_t pin, uint32_t *flags)
{
- struct a10_gpio_softc *sc;
+ struct aw_gpio_softc *sc;
- if (pin >= A10_GPIO_PINS)
+ if (pin >= AW_GPIO_PINS)
return (EINVAL);
sc = device_get_softc(dev);
- A10_GPIO_LOCK(sc);
- *flags = a10_gpio_get_function(sc, pin);
- *flags |= a10_gpio_get_pud(sc, pin);
- A10_GPIO_UNLOCK(sc);
+ AW_GPIO_LOCK(sc);
+ *flags = aw_gpio_get_function(sc, pin);
+ *flags |= aw_gpio_get_pud(sc, pin);
+ AW_GPIO_UNLOCK(sc);
return (0);
}
static int
-a10_gpio_pin_getname(device_t dev, uint32_t pin, char *name)
+aw_gpio_pin_getname(device_t dev, uint32_t pin, char *name)
{
uint32_t bank;
- if (pin >= A10_GPIO_PINS)
+ if (pin >= AW_GPIO_PINS)
return (EINVAL);
bank = pin / 32;
@@ -286,94 +286,94 @@
}
static int
-a10_gpio_pin_setflags(device_t dev, uint32_t pin, uint32_t flags)
+aw_gpio_pin_setflags(device_t dev, uint32_t pin, uint32_t flags)
{
- struct a10_gpio_softc *sc;
+ struct aw_gpio_softc *sc;
- if (pin >= A10_GPIO_PINS)
+ if (pin >= AW_GPIO_PINS)
return (EINVAL);
sc = device_get_softc(dev);
- A10_GPIO_LOCK(sc);
- a10_gpio_pin_configure(sc, pin, flags);
- A10_GPIO_UNLOCK(sc);
+ AW_GPIO_LOCK(sc);
+ aw_gpio_pin_configure(sc, pin, flags);
+ AW_GPIO_UNLOCK(sc);
return (0);
}
static int
-a10_gpio_pin_set(device_t dev, uint32_t pin, unsigned int value)
+aw_gpio_pin_set(device_t dev, uint32_t pin, unsigned int value)
{
- struct a10_gpio_softc *sc;
+ struct aw_gpio_softc *sc;
uint32_t bank, data;
- if (pin >= A10_GPIO_PINS)
+ if (pin >= AW_GPIO_PINS)
return (EINVAL);
bank = pin / 32;
pin = pin % 32;
sc = device_get_softc(dev);
- A10_GPIO_LOCK(sc);
- data = A10_GPIO_READ(sc, A10_GPIO_GP_DAT(bank));
+ AW_GPIO_LOCK(sc);
+ data = AW_GPIO_READ(sc, AW_GPIO_GP_DAT(bank));
if (value)
data |= (1 << pin);
else
data &= ~(1 << pin);
- A10_GPIO_WRITE(sc, A10_GPIO_GP_DAT(bank), data);
- A10_GPIO_UNLOCK(sc);
+ AW_GPIO_WRITE(sc, AW_GPIO_GP_DAT(bank), data);
+ AW_GPIO_UNLOCK(sc);
return (0);
}
static int
-a10_gpio_pin_get(device_t dev, uint32_t pin, unsigned int *val)
+aw_gpio_pin_get(device_t dev, uint32_t pin, unsigned int *val)
{
- struct a10_gpio_softc *sc;
+ struct aw_gpio_softc *sc;
uint32_t bank, reg_data;
- if (pin >= A10_GPIO_PINS)
+ if (pin >= AW_GPIO_PINS)
return (EINVAL);
bank = pin / 32;
pin = pin % 32;
sc = device_get_softc(dev);
- A10_GPIO_LOCK(sc);
- reg_data = A10_GPIO_READ(sc, A10_GPIO_GP_DAT(bank));
- A10_GPIO_UNLOCK(sc);
+ AW_GPIO_LOCK(sc);
+ reg_data = AW_GPIO_READ(sc, AW_GPIO_GP_DAT(bank));
+ AW_GPIO_UNLOCK(sc);
*val = (reg_data & (1 << pin)) ? 1 : 0;
return (0);
}
static int
-a10_gpio_pin_toggle(device_t dev, uint32_t pin)
+aw_gpio_pin_toggle(device_t dev, uint32_t pin)
{
- struct a10_gpio_softc *sc;
+ struct aw_gpio_softc *sc;
uint32_t bank, data;
- if (pin >= A10_GPIO_PINS)
+ if (pin >= AW_GPIO_PINS)
return (EINVAL);
bank = pin / 32;
pin = pin % 32;
sc = device_get_softc(dev);
- A10_GPIO_LOCK(sc);
- data = A10_GPIO_READ(sc, A10_GPIO_GP_DAT(bank));
+ AW_GPIO_LOCK(sc);
+ data = AW_GPIO_READ(sc, AW_GPIO_GP_DAT(bank));
if (data & (1 << pin))
data &= ~(1 << pin);
else
data |= (1 << pin);
- A10_GPIO_WRITE(sc, A10_GPIO_GP_DAT(bank), data);
- A10_GPIO_UNLOCK(sc);
+ AW_GPIO_WRITE(sc, AW_GPIO_GP_DAT(bank), data);
+ AW_GPIO_UNLOCK(sc);
return (0);
}
static int
-a10_gpio_probe(device_t dev)
+aw_gpio_probe(device_t dev)
{
if (!ofw_bus_status_okay(dev))
@@ -387,11 +387,11 @@
}
static int
-a10_gpio_attach(device_t dev)
+aw_gpio_attach(device_t dev)
{
int rid;
phandle_t gpio;
- struct a10_gpio_softc *sc;
+ struct aw_gpio_softc *sc;
sc = device_get_softc(dev);
sc->sc_dev = dev;
@@ -423,7 +423,7 @@
/* Node is not a GPIO controller. */
goto fail;
- a10_gpio_sc = sc;
+ aw_gpio_sc = sc;
sc->sc_busdev = gpiobus_attach_bus(dev);
if (sc->sc_busdev == NULL)
goto fail;
@@ -441,14 +441,14 @@
}
static int
-a10_gpio_detach(device_t dev)
+aw_gpio_detach(device_t dev)
{
return (EBUSY);
}
static phandle_t
-a10_gpio_get_node(device_t dev, device_t bus)
+aw_gpio_get_node(device_t dev, device_t bus)
{
/* We only have one child, the GPIO bus, which needs our own node. */
@@ -456,7 +456,7 @@
}
static int
-a10_gpio_map_gpios(device_t bus, phandle_t dev, phandle_t gparent, int gcells,
+aw_gpio_map_gpios(device_t bus, phandle_t dev, phandle_t gparent, int gcells,
pcell_t *gpios, uint32_t *pin, uint32_t *flags)
{
@@ -467,56 +467,56 @@
return (0);
}
-static device_method_t a10_gpio_methods[] = {
+static device_method_t aw_gpio_methods[] = {
/* Device interface */
- DEVMETHOD(device_probe, a10_gpio_probe),
- DEVMETHOD(device_attach, a10_gpio_attach),
- DEVMETHOD(device_detach, a10_gpio_detach),
+ DEVMETHOD(device_probe, aw_gpio_probe),
+ DEVMETHOD(device_attach, aw_gpio_attach),
+ DEVMETHOD(device_detach, aw_gpio_detach),
/* GPIO protocol */
- DEVMETHOD(gpio_get_bus, a10_gpio_get_bus),
- DEVMETHOD(gpio_pin_max, a10_gpio_pin_max),
- DEVMETHOD(gpio_pin_getname, a10_gpio_pin_getname),
- DEVMETHOD(gpio_pin_getflags, a10_gpio_pin_getflags),
- DEVMETHOD(gpio_pin_getcaps, a10_gpio_pin_getcaps),
- DEVMETHOD(gpio_pin_setflags, a10_gpio_pin_setflags),
- DEVMETHOD(gpio_pin_get, a10_gpio_pin_get),
- DEVMETHOD(gpio_pin_set, a10_gpio_pin_set),
- DEVMETHOD(gpio_pin_toggle, a10_gpio_pin_toggle),
- DEVMETHOD(gpio_map_gpios, a10_gpio_map_gpios),
+ DEVMETHOD(gpio_get_bus, aw_gpio_get_bus),
+ DEVMETHOD(gpio_pin_max, aw_gpio_pin_max),
+ DEVMETHOD(gpio_pin_getname, aw_gpio_pin_getname),
+ DEVMETHOD(gpio_pin_getflags, aw_gpio_pin_getflags),
+ DEVMETHOD(gpio_pin_getcaps, aw_gpio_pin_getcaps),
+ DEVMETHOD(gpio_pin_setflags, aw_gpio_pin_setflags),
+ DEVMETHOD(gpio_pin_get, aw_gpio_pin_get),
+ DEVMETHOD(gpio_pin_set, aw_gpio_pin_set),
+ DEVMETHOD(gpio_pin_toggle, aw_gpio_pin_toggle),
+ DEVMETHOD(gpio_map_gpios, aw_gpio_map_gpios),
/* ofw_bus interface */
- DEVMETHOD(ofw_bus_get_node, a10_gpio_get_node),
+ DEVMETHOD(ofw_bus_get_node, aw_gpio_get_node),
DEVMETHOD_END
};
-static devclass_t a10_gpio_devclass;
+static devclass_t aw_gpio_devclass;
-static driver_t a10_gpio_driver = {
+static driver_t aw_gpio_driver = {
"gpio",
- a10_gpio_methods,
- sizeof(struct a10_gpio_softc),
+ aw_gpio_methods,
+ sizeof(struct aw_gpio_softc),
};
-EARLY_DRIVER_MODULE(a10_gpio, simplebus, a10_gpio_driver, a10_gpio_devclass, 0, 0,
+EARLY_DRIVER_MODULE(aw_gpio, simplebus, aw_gpio_driver, aw_gpio_devclass, 0, 0,
BUS_PASS_INTERRUPT + BUS_PASS_ORDER_MIDDLE);
int
-a10_gpio_ethernet_activate(uint32_t func)
+aw_gpio_ethernet_activate(uint32_t func)
{
int i;
- struct a10_gpio_softc *sc = a10_gpio_sc;
+ struct aw_gpio_softc *sc = aw_gpio_sc;
if (sc == NULL)
return (ENXIO);
/* Configure pin mux settings for MII. */
- A10_GPIO_LOCK(sc);
+ AW_GPIO_LOCK(sc);
for (i = 0; i <= 17; i++)
- a10_gpio_set_function(sc, i, func);
- A10_GPIO_UNLOCK(sc);
+ aw_gpio_set_function(sc, i, func);
+ AW_GPIO_UNLOCK(sc);
return (0);
}
Index: sys/arm/allwinner/aw_if_dwc.c
===================================================================
--- sys/arm/allwinner/aw_if_dwc.c
+++ sys/arm/allwinner/aw_if_dwc.c
@@ -40,8 +40,8 @@
#include <dev/ofw/ofw_bus.h>
#include <dev/ofw/ofw_bus_subr.h>
-#include <arm/allwinner/a10_clk.h>
-#include <arm/allwinner/a10_gpio.h>
+#include <arm/allwinner/a10/a10_clk.h>
+#include <arm/allwinner/aw_gpio.h>
#include "if_dwc_if.h"
@@ -64,7 +64,7 @@
/* Activate GMAC clock and set the pin mux to rgmii. */
if (a10_clk_gmac_activate(ofw_bus_get_node(dev)) != 0 ||
- a10_gpio_ethernet_activate(A10_GPIO_FUNC_RGMII)) {
+ aw_gpio_ethernet_activate(AW_GPIO_FUNC_RGMII)) {
device_printf(dev, "could not activate gmac module\n");
return (ENXIO);
}
Index: sys/arm/allwinner/aw_machdep.c
===================================================================
--- sys/arm/allwinner/aw_machdep.c
+++ sys/arm/allwinner/aw_machdep.c
@@ -50,8 +50,8 @@
#include <dev/fdt/fdt_common.h>
-#include <arm/allwinner/a10_wdog.h>
-#include <arm/allwinner/allwinner_machdep.h>
+#include <arm/allwinner/aw_wdog.h>
+#include <arm/allwinner/aw_machdep.h>
#include "platform_if.h"
@@ -117,7 +117,7 @@
void
cpu_reset()
{
- a10wd_watchdog_reset();
+ aw_watchdog_reset();
printf("Reset failed!\n");
while (1);
}
Index: sys/arm/allwinner/aw_mmc.h
===================================================================
--- /dev/null
+++ sys/arm/allwinner/aw_mmc.h
@@ -0,0 +1,198 @@
+/*-
+ * Copyright (c) 2013 Alexander Fedorov <alexander.fedorov@rtlservice.com>
+ * 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 AND CONTRIBUTORS ``AS IS'' AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+ * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ *
+ * $FreeBSD$
+ */
+
+#ifndef _AW_MMC_H_
+#define _AW_MMC_H_
+
+#define AW_MMC_GCTRL 0x00 /* Global Control Register */
+#define AW_MMC_CLKCR 0x04 /* Clock Control Register */
+#define AW_MMC_TIMEOUT 0x08 /* Timeout Register */
+#define AW_MMC_WIDTH 0x0C /* Bus Width Register */
+#define AW_MMC_BLKSZ 0x10 /* Block Size Register */
+#define AW_MMC_BCNTR 0x14 /* Byte Count Register */
+#define AW_MMC_CMDR 0x18 /* Command Register */
+#define AW_MMC_CARG 0x1C /* Argument Register */
+#define AW_MMC_RESP0 0x20 /* Response Register 0 */
+#define AW_MMC_RESP1 0x24 /* Response Register 1 */
+#define AW_MMC_RESP2 0x28 /* Response Register 2 */
+#define AW_MMC_RESP3 0x2C /* Response Register 3 */
+#define AW_MMC_IMASK 0x30 /* Interrupt Mask Register */
+#define AW_MMC_MISTA 0x34 /* Masked Interrupt Status Register */
+#define AW_MMC_RINTR 0x38 /* Raw Interrupt Status Register */
+#define AW_MMC_STAS 0x3C /* Status Register */
+#define AW_MMC_FTRGL 0x40 /* FIFO Threshold Watermark Register */
+#define AW_MMC_FUNS 0x44 /* Function Select Register */
+#define AW_MMC_CBCR 0x48 /* CIU Byte Count Register */
+#define AW_MMC_BBCR 0x4C /* BIU Byte Count Register */
+#define AW_MMC_DBGC 0x50 /* Debug Enable Register */
+#define AW_MMC_DMAC 0x80 /* IDMAC Control Register */
+#define AW_MMC_DLBA 0x84 /* IDMAC Desc List Base Address Reg */
+#define AW_MMC_IDST 0x88 /* IDMAC Status Register */
+#define AW_MMC_IDIE 0x8C /* IDMAC Interrupt Enable Register */
+#define AW_MMC_CHDA 0x90
+#define AW_MMC_CBDA 0x94
+#define AW_MMC_FIFO 0x100 /* FIFO Access Address */
+
+/* AW_MMC_GCTRL */
+#define AW_MMC_SOFT_RESET (1U << 0)
+#define AW_MMC_FIFO_RESET (1U << 1)
+#define AW_MMC_DMA_RESET (1U << 2)
+#define AW_MMC_INT_ENABLE (1U << 4)
+#define AW_MMC_DMA_ENABLE (1U << 5)
+#define AW_MMC_DEBOUNCE_ENABLE (1U << 8)
+#define AW_MMC_DDR_MODE (1U << 10)
+#define AW_MMC_ACCESS_BY_AHB (1U << 31)
+#define AW_MMC_RESET \
+ (AW_MMC_SOFT_RESET | AW_MMC_FIFO_RESET | AW_MMC_DMA_RESET)
+
+/* AW_MMC_CLKCR */
+#define AW_MMC_CARD_CLK_ON (1U << 16)
+#define AW_MMC_LOW_POWER_ON (1U << 17)
+#define AW_MMC_CLKCR_DIV 0xff
+
+/* AW_MMC_WIDTH */
+#define AW_MMC_WIDTH1 0
+#define AW_MMC_WIDTH4 1
+#define AW_MMC_WIDTH8 2
+
+/* AW_MMC_CMDR */
+#define AW_MMC_RESP_EXP (1U << 6)
+#define AW_MMC_LONG_RESP (1U << 7)
+#define AW_MMC_CHECK_RESP_CRC (1U << 8)
+#define AW_MMC_DATA_EXP (1U << 9)
+#define AW_MMC_WRITE (1U << 10)
+#define AW_MMC_SEQ_MODE (1U << 11)
+#define AW_MMC_SEND_AUTOSTOP (1U << 12)
+#define AW_MMC_WAIT_PREOVER (1U << 13)
+#define AW_MMC_STOP_ABORT_CMD (1U << 14)
+#define AW_MMC_SEND_INIT_SEQ (1U << 15)
+#define AW_MMC_UPCLK_ONLY (1U << 21)
+#define AW_MMC_RDCEATADEV (1U << 22)
+#define AW_MMC_CCS_EXP (1U << 23)
+#define AW_MMC_ENB_BOOT (1U << 24)
+#define AW_MMC_ALT_BOOT_OPT (1U << 25)
+#define AW_MMC_BOOT_ACK_EXP (1U << 26)
+#define AW_MMC_DISABLE_BOOT (1U << 27)
+#define AW_MMC_VOL_SWITCH (1U << 28)
+#define AW_MMC_START (1U << 31)
+
+/* AW_MMC_IMASK and AW_MMC_RINTR */
+#define AW_MMC_RESP_ERR (1U << 1)
+#define AW_MMC_CMD_DONE (1U << 2)
+#define AW_MMC_DATA_OVER (1U << 3)
+#define AW_MMC_TX_DATA_REQ (1U << 4)
+#define AW_MMC_RX_DATA_REQ (1U << 5)
+#define AW_MMC_RESP_CRC_ERR (1U << 6)
+#define AW_MMC_DATA_CRC_ERR (1U << 7)
+#define AW_MMC_RESP_TIMEOUT (1U << 8)
+#define AW_MMC_ACK_RECV (1U << 8)
+#define AW_MMC_DATA_TIMEOUT (1U << 9)
+#define AW_MMC_BOOT_START (1U << 9)
+#define AW_MMC_DATA_STARVE (1U << 10)
+#define AW_MMC_VOL_CHG_DONE (1U << 10)
+#define AW_MMC_FIFO_RUN_ERR (1U << 11)
+#define AW_MMC_HARDW_LOCKED (1U << 12)
+#define AW_MMC_START_BIT_ERR (1U << 13)
+#define AW_MMC_AUTOCMD_DONE (1U << 14)
+#define AW_MMC_END_BIT_ERR (1U << 15)
+#define AW_MMC_SDIO_INT (1U << 16)
+#define AW_MMC_CARD_INSERT (1U << 30)
+#define AW_MMC_CARD_REMOVE (1U << 31)
+#define AW_MMC_INT_ERR_BIT \
+ (AW_MMC_RESP_ERR | AW_MMC_RESP_CRC_ERR | \
+ AW_MMC_DATA_CRC_ERR | AW_MMC_RESP_TIMEOUT | \
+ AW_MMC_FIFO_RUN_ERR | AW_MMC_HARDW_LOCKED | \
+ AW_MMC_START_BIT_ERR | AW_MMC_END_BIT_ERR)
+
+/* AW_MMC_STAS */
+#define AW_MMC_RX_WLFLAG (1U << 0)
+#define AW_MMC_TX_WLFLAG (1U << 1)
+#define AW_MMC_FIFO_EMPTY (1U << 2)
+#define AW_MMC_FIFO_FULL (1U << 3)
+#define AW_MMC_CARD_PRESENT (1U << 8)
+#define AW_MMC_CARD_DATA_BUSY (1U << 9)
+#define AW_MMC_DATA_FSM_BUSY (1U << 10)
+#define AW_MMC_DMA_REQ (1U << 31)
+#define AW_MMC_FIFO_SIZE 16
+
+/* AW_MMC_FUNS */
+#define AW_MMC_CE_ATA_ON (0xceaaU << 16)
+#define AW_MMC_SEND_IRQ_RESP (1U << 0)
+#define AW_MMC_SDIO_RD_WAIT (1U << 1)
+#define AW_MMC_ABT_RD_DATA (1U << 2)
+#define AW_MMC_SEND_CC_SD (1U << 8)
+#define AW_MMC_SEND_AUTOSTOP_CC_SD (1U << 9)
+#define AW_MMC_CE_ATA_DEV_INT_ENB (1U << 10)
+
+/* IDMA CONTROLLER BUS MOD BIT FIELD */
+#define AW_MMC_IDMAC_SOFT_RST (1U << 0)
+#define AW_MMC_IDMAC_FIX_BURST (1U << 1)
+#define AW_MMC_IDMAC_IDMA_ON (1U << 7)
+#define AW_MMC_IDMAC_REFETCH_DES (1U << 31)
+
+/* AW_MMC_IDST */
+#define AW_MMC_IDMAC_TRANSMIT_INT (1U << 0)
+#define AW_MMC_IDMAC_RECEIVE_INT (1U << 1)
+#define AW_MMC_IDMAC_FATAL_BUS_ERR (1U << 2)
+#define AW_MMC_IDMAC_DES_INVALID (1U << 4)
+#define AW_MMC_IDMAC_CARD_ERR_SUM (1U << 5)
+#define AW_MMC_IDMAC_NORMAL_INT_SUM (1U << 8)
+#define AW_MMC_IDMAC_ABNORMAL_INT_SUM (1U << 9)
+#define AW_MMC_IDMAC_HOST_ABT_INTX (1U << 10)
+#define AW_MMC_IDMAC_HOST_ABT_INRX (1U << 10)
+#define AW_MMC_IDMAC_IDLE (0U << 13)
+#define AW_MMC_IDMAC_SUSPEND (1U << 13)
+#define AW_MMC_IDMAC_DESC_RD (2U << 13)
+#define AW_MMC_IDMAC_DESC_CHECK (3U << 13)
+#define AW_MMC_IDMAC_RD_REQ_WAIT (4U << 13)
+#define AW_MMC_IDMAC_WR_REQ_WAIT (5U << 13)
+#define AW_MMC_IDMAC_RD (6U << 13)
+#define AW_MMC_IDMAC_WR (7U << 13)
+#define AW_MMC_IDMAC_DESC_CLOSE (8U << 13)
+#define AW_MMC_IDMAC_ERROR \
+ (AW_MMC_IDMAC_FATAL_BUS_ERR | AW_MMC_IDMAC_CARD_ERR_SUM | \
+ AW_MMC_IDMAC_DES_INVALID | AW_MMC_IDMAC_ABNORMAL_INT_SUM)
+#define AW_MMC_IDMAC_COMPLETE \
+ (AW_MMC_IDMAC_TRANSMIT_INT | AW_MMC_IDMAC_RECEIVE_INT)
+
+/* The DMA descriptor table. */
+struct aw_mmc_dma_desc {
+ uint32_t config;
+#define AW_MMC_DMA_CONFIG_DIC (1U << 1)
+#define AW_MMC_DMA_CONFIG_LD (1U << 2)
+#define AW_MMC_DMA_CONFIG_FD (1U << 3)
+#define AW_MMC_DMA_CONFIG_CH (1U << 4)
+#define AW_MMC_DMA_CONFIG_ER (1U << 5)
+#define AW_MMC_DMA_CONFIG_CES (1U << 30)
+#define AW_MMC_DMA_CONFIG_OWN (1U << 31)
+ uint32_t buf_size;
+ uint32_t buf_addr;
+ uint32_t next;
+};
+
+#endif /* _AW_MMC_H_ */
Index: sys/arm/allwinner/aw_mmc.c
===================================================================
--- /dev/null
+++ sys/arm/allwinner/aw_mmc.c
@@ -0,0 +1,893 @@
+/*-
+ * Copyright (c) 2013 Alexander Fedorov
+ * 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 AND CONTRIBUTORS ``AS IS'' AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+ * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ */
+
+#include <sys/cdefs.h>
+__FBSDID("$FreeBSD$");
+
+#include <sys/param.h>
+#include <sys/systm.h>
+#include <sys/bus.h>
+#include <sys/kernel.h>
+#include <sys/lock.h>
+#include <sys/malloc.h>
+#include <sys/module.h>
+#include <sys/mutex.h>
+#include <sys/resource.h>
+#include <sys/rman.h>
+#include <sys/sysctl.h>
+
+#include <machine/bus.h>
+
+#include <dev/ofw/ofw_bus.h>
+#include <dev/ofw/ofw_bus_subr.h>
+
+#include <dev/mmc/bridge.h>
+#include <dev/mmc/mmcreg.h>
+#include <dev/mmc/mmcbrvar.h>
+
+#include <arm/allwinner/a10/a10_clk.h>
+#include <arm/allwinner/aw_mmc.h>
+
+#define AW_MMC_MEMRES 0
+#define AW_MMC_IRQRES 1
+#define AW_MMC_RESSZ 2
+#define AW_MMC_DMA_SEGS 16
+#define AW_MMC_DMA_MAX_SIZE 0x2000
+#define AW_MMC_DMA_FTRGLEVEL 0x20070008
+
+static int aw_mmc_pio_mode = 0;
+
+TUNABLE_INT("hw.a10.mmc.pio_mode", &aw_mmc_pio_mode);
+
+static struct ofw_compat_data compat_data[] = {
+ {"allwinner,sun4i-a10-mmc", 1},
+ {"allwinner,sun5i-a13-mmc", 1},
+ {NULL, 0}
+};
+
+struct aw_mmc_softc {
+ bus_space_handle_t aw_bsh;
+ bus_space_tag_t aw_bst;
+ device_t aw_dev;
+ int aw_bus_busy;
+ int aw_id;
+ int aw_resid;
+ int aw_timeout;
+ struct callout aw_timeoutc;
+ struct mmc_host aw_host;
+ struct mmc_request * aw_req;
+ struct mtx aw_mtx;
+ struct resource * aw_res[AW_MMC_RESSZ];
+ uint32_t aw_intr;
+ uint32_t aw_intr_wait;
+ void * aw_intrhand;
+
+ /* Fields required for DMA access. */
+ bus_addr_t aw_dma_desc_phys;
+ bus_dmamap_t aw_dma_map;
+ bus_dma_tag_t aw_dma_tag;
+ void * aw_dma_desc;
+ bus_dmamap_t aw_dma_buf_map;
+ bus_dma_tag_t aw_dma_buf_tag;
+ int aw_dma_inuse;
+ int aw_dma_map_err;
+};
+
+static struct resource_spec aw_mmc_res_spec[] = {
+ { SYS_RES_MEMORY, 0, RF_ACTIVE },
+ { SYS_RES_IRQ, 0, RF_ACTIVE | RF_SHAREABLE },
+ { -1, 0, 0 }
+};
+
+static int aw_mmc_probe(device_t);
+static int aw_mmc_attach(device_t);
+static int aw_mmc_detach(device_t);
+static int aw_mmc_setup_dma(struct aw_mmc_softc *);
+static int aw_mmc_reset(struct aw_mmc_softc *);
+static void aw_mmc_intr(void *);
+static int aw_mmc_update_clock(struct aw_mmc_softc *);
+
+static int aw_mmc_update_ios(device_t, device_t);
+static int aw_mmc_request(device_t, device_t, struct mmc_request *);
+static int aw_mmc_get_ro(device_t, device_t);
+static int aw_mmc_acquire_host(device_t, device_t);
+static int aw_mmc_release_host(device_t, device_t);
+
+#define AW_MMC_LOCK(_sc) mtx_lock(&(_sc)->aw_mtx)
+#define AW_MMC_UNLOCK(_sc) mtx_unlock(&(_sc)->aw_mtx)
+#define AW_MMC_READ_4(_sc, _reg) \
+ bus_space_read_4((_sc)->aw_bst, (_sc)->aw_bsh, _reg)
+#define AW_MMC_WRITE_4(_sc, _reg, _value) \
+ bus_space_write_4((_sc)->aw_bst, (_sc)->aw_bsh, _reg, _value)
+
+static int
+aw_mmc_probe(device_t dev)
+{
+
+ if (!ofw_bus_status_okay(dev))
+ return (ENXIO);
+ if (ofw_bus_search_compatible(dev, compat_data)->ocd_data == 0)
+ return (ENXIO);
+
+ device_set_desc(dev, "Allwinner Integrated MMC/SD controller");
+
+ return (BUS_PROBE_DEFAULT);
+}
+
+static int
+aw_mmc_attach(device_t dev)
+{
+ device_t child;
+ struct aw_mmc_softc *sc;
+ struct sysctl_ctx_list *ctx;
+ struct sysctl_oid_list *tree;
+
+ sc = device_get_softc(dev);
+ sc->aw_dev = dev;
+ sc->aw_req = NULL;
+ sc->aw_id = device_get_unit(dev);
+ if (sc->aw_id > 3) {
+ device_printf(dev, "only 4 hosts are supported (0-3)\n");
+ return (ENXIO);
+ }
+ if (bus_alloc_resources(dev, aw_mmc_res_spec, sc->aw_res) != 0) {
+ device_printf(dev, "cannot allocate device resources\n");
+ return (ENXIO);
+ }
+ sc->aw_bst = rman_get_bustag(sc->aw_res[AW_MMC_MEMRES]);
+ sc->aw_bsh = rman_get_bushandle(sc->aw_res[AW_MMC_MEMRES]);
+ if (bus_setup_intr(dev, sc->aw_res[AW_MMC_IRQRES],
+ INTR_TYPE_MISC | INTR_MPSAFE, NULL, aw_mmc_intr, sc,
+ &sc->aw_intrhand)) {
+ bus_release_resources(dev, aw_mmc_res_spec, sc->aw_res);
+ device_printf(dev, "cannot setup interrupt handler\n");
+ return (ENXIO);
+ }
+
+ /* Activate the module clock. */
+ if (a10_clk_mmc_activate(sc->aw_id) != 0) {
+ bus_teardown_intr(dev, sc->aw_res[AW_MMC_IRQRES],
+ sc->aw_intrhand);
+ bus_release_resources(dev, aw_mmc_res_spec, sc->aw_res);
+ device_printf(dev, "cannot activate mmc clock\n");
+ return (ENXIO);
+ }
+
+ sc->aw_timeout = 10;
+ ctx = device_get_sysctl_ctx(dev);
+ tree = SYSCTL_CHILDREN(device_get_sysctl_tree(dev));
+ SYSCTL_ADD_INT(ctx, tree, OID_AUTO, "req_timeout", CTLFLAG_RW,
+ &sc->aw_timeout, 0, "Request timeout in seconds");
+ mtx_init(&sc->aw_mtx, device_get_nameunit(sc->aw_dev), "aw_mmc",
+ MTX_DEF);
+ callout_init_mtx(&sc->aw_timeoutc, &sc->aw_mtx, 0);
+
+ /* Reset controller. */
+ if (aw_mmc_reset(sc) != 0) {
+ device_printf(dev, "cannot reset the controller\n");
+ goto fail;
+ }
+
+ if (aw_mmc_pio_mode == 0 && aw_mmc_setup_dma(sc) != 0) {
+ device_printf(sc->aw_dev, "Couldn't setup DMA!\n");
+ aw_mmc_pio_mode = 1;
+ }
+ if (bootverbose)
+ device_printf(sc->aw_dev, "DMA status: %s\n",
+ aw_mmc_pio_mode ? "disabled" : "enabled");
+
+ sc->aw_host.f_min = 400000;
+ sc->aw_host.f_max = 52000000;
+ sc->aw_host.host_ocr = MMC_OCR_320_330 | MMC_OCR_330_340;
+ sc->aw_host.caps = MMC_CAP_4_BIT_DATA | MMC_CAP_HSPEED;
+ sc->aw_host.mode = mode_sd;
+
+ child = device_add_child(dev, "mmc", -1);
+ if (child == NULL) {
+ device_printf(dev, "attaching MMC bus failed!\n");
+ goto fail;
+ }
+ if (device_probe_and_attach(child) != 0) {
+ device_printf(dev, "attaching MMC child failed!\n");
+ device_delete_child(dev, child);
+ goto fail;
+ }
+
+ return (0);
+
+fail:
+ callout_drain(&sc->aw_timeoutc);
+ mtx_destroy(&sc->aw_mtx);
+ bus_teardown_intr(dev, sc->aw_res[AW_MMC_IRQRES], sc->aw_intrhand);
+ bus_release_resources(dev, aw_mmc_res_spec, sc->aw_res);
+
+ return (ENXIO);
+}
+
+static int
+aw_mmc_detach(device_t dev)
+{
+
+ return (EBUSY);
+}
+
+static void
+aw_dma_desc_cb(void *arg, bus_dma_segment_t *segs, int nsegs, int err)
+{
+ struct aw_mmc_softc *sc;
+
+ sc = (struct aw_mmc_softc *)arg;
+ if (err) {
+ sc->aw_dma_map_err = err;
+ return;
+ }
+ sc->aw_dma_desc_phys = segs[0].ds_addr;
+}
+
+static int
+aw_mmc_setup_dma(struct aw_mmc_softc *sc)
+{
+ int dma_desc_size, error;
+
+ /* Allocate the DMA descriptor memory. */
+ dma_desc_size = sizeof(struct aw_mmc_dma_desc) * AW_MMC_DMA_SEGS;
+ error = bus_dma_tag_create(bus_get_dma_tag(sc->aw_dev), 1, 0,
+ BUS_SPACE_MAXADDR_32BIT, BUS_SPACE_MAXADDR, NULL, NULL,
+ dma_desc_size, 1, dma_desc_size, 0, NULL, NULL, &sc->aw_dma_tag);
+ if (error)
+ return (error);
+ error = bus_dmamem_alloc(sc->aw_dma_tag, &sc->aw_dma_desc,
+ BUS_DMA_WAITOK | BUS_DMA_ZERO, &sc->aw_dma_map);
+ if (error)
+ return (error);
+
+ error = bus_dmamap_load(sc->aw_dma_tag, sc->aw_dma_map,
+ sc->aw_dma_desc, dma_desc_size, aw_dma_desc_cb, sc, 0);
+ if (error)
+ return (error);
+ if (sc->aw_dma_map_err)
+ return (sc->aw_dma_map_err);
+
+ /* Create the DMA map for data transfers. */
+ error = bus_dma_tag_create(bus_get_dma_tag(sc->aw_dev), 1, 0,
+ BUS_SPACE_MAXADDR_32BIT, BUS_SPACE_MAXADDR, NULL, NULL,
+ AW_MMC_DMA_MAX_SIZE * AW_MMC_DMA_SEGS, AW_MMC_DMA_SEGS,
+ AW_MMC_DMA_MAX_SIZE, BUS_DMA_ALLOCNOW, NULL, NULL,
+ &sc->aw_dma_buf_tag);
+ if (error)
+ return (error);
+ error = bus_dmamap_create(sc->aw_dma_buf_tag, 0,
+ &sc->aw_dma_buf_map);
+ if (error)
+ return (error);
+
+ return (0);
+}
+
+static void
+aw_dma_cb(void *arg, bus_dma_segment_t *segs, int nsegs, int err)
+{
+ int i;
+ struct aw_mmc_dma_desc *dma_desc;
+ struct aw_mmc_softc *sc;
+
+ sc = (struct aw_mmc_softc *)arg;
+ sc->aw_dma_map_err = err;
+ dma_desc = sc->aw_dma_desc;
+ /* Note nsegs is guaranteed to be zero if err is non-zero. */
+ for (i = 0; i < nsegs; i++) {
+ dma_desc[i].buf_size = segs[i].ds_len;
+ dma_desc[i].buf_addr = segs[i].ds_addr;
+ dma_desc[i].config = AW_MMC_DMA_CONFIG_CH |
+ AW_MMC_DMA_CONFIG_OWN;
+ if (i == 0)
+ dma_desc[i].config |= AW_MMC_DMA_CONFIG_FD;
+ if (i < (nsegs - 1)) {
+ dma_desc[i].config |= AW_MMC_DMA_CONFIG_DIC;
+ dma_desc[i].next = sc->aw_dma_desc_phys +
+ ((i + 1) * sizeof(struct aw_mmc_dma_desc));
+ } else {
+ dma_desc[i].config |= AW_MMC_DMA_CONFIG_LD |
+ AW_MMC_DMA_CONFIG_ER;
+ dma_desc[i].next = 0;
+ }
+ }
+}
+
+static int
+aw_mmc_prepare_dma(struct aw_mmc_softc *sc)
+{
+ bus_dmasync_op_t sync_op;
+ int error;
+ struct mmc_command *cmd;
+ uint32_t val;
+
+ cmd = sc->aw_req->cmd;
+ if (cmd->data->len > AW_MMC_DMA_MAX_SIZE * AW_MMC_DMA_SEGS)
+ return (EFBIG);
+ error = bus_dmamap_load(sc->aw_dma_buf_tag, sc->aw_dma_buf_map,
+ cmd->data->data, cmd->data->len, aw_dma_cb, sc, BUS_DMA_NOWAIT);
+ if (error)
+ return (error);
+ if (sc->aw_dma_map_err)
+ return (sc->aw_dma_map_err);
+
+ sc->aw_dma_inuse = 1;
+ if (cmd->data->flags & MMC_DATA_WRITE)
+ sync_op = BUS_DMASYNC_PREWRITE;
+ else
+ sync_op = BUS_DMASYNC_PREREAD;
+ bus_dmamap_sync(sc->aw_dma_buf_tag, sc->aw_dma_buf_map, sync_op);
+ bus_dmamap_sync(sc->aw_dma_tag, sc->aw_dma_map, BUS_DMASYNC_PREWRITE);
+
+ val = AW_MMC_READ_4(sc, AW_MMC_IMASK);
+ val &= ~(AW_MMC_RX_DATA_REQ | AW_MMC_TX_DATA_REQ);
+ AW_MMC_WRITE_4(sc, AW_MMC_IMASK, val);
+ val = AW_MMC_READ_4(sc, AW_MMC_GCTRL);
+ val &= ~AW_MMC_ACCESS_BY_AHB;
+ val |= AW_MMC_DMA_ENABLE;
+ AW_MMC_WRITE_4(sc, AW_MMC_GCTRL, val);
+ val |= AW_MMC_DMA_RESET;
+ AW_MMC_WRITE_4(sc, AW_MMC_GCTRL, val);
+ AW_MMC_WRITE_4(sc, AW_MMC_DMAC, AW_MMC_IDMAC_SOFT_RST);
+ AW_MMC_WRITE_4(sc, AW_MMC_DMAC,
+ AW_MMC_IDMAC_IDMA_ON | AW_MMC_IDMAC_FIX_BURST);
+ val = AW_MMC_READ_4(sc, AW_MMC_IDIE);
+ val &= ~(AW_MMC_IDMAC_RECEIVE_INT | AW_MMC_IDMAC_TRANSMIT_INT);
+ if (cmd->data->flags & MMC_DATA_WRITE)
+ val |= AW_MMC_IDMAC_TRANSMIT_INT;
+ else
+ val |= AW_MMC_IDMAC_RECEIVE_INT;
+ AW_MMC_WRITE_4(sc, AW_MMC_IDIE, val);
+ AW_MMC_WRITE_4(sc, AW_MMC_DLBA, sc->aw_dma_desc_phys);
+ AW_MMC_WRITE_4(sc, AW_MMC_FTRGL, AW_MMC_DMA_FTRGLEVEL);
+
+ return (0);
+}
+
+static int
+aw_mmc_reset(struct aw_mmc_softc *sc)
+{
+ int timeout;
+
+ AW_MMC_WRITE_4(sc, AW_MMC_GCTRL,
+ AW_MMC_READ_4(sc, AW_MMC_GCTRL) | AW_MMC_RESET);
+ timeout = 1000;
+ while (--timeout > 0) {
+ if ((AW_MMC_READ_4(sc, AW_MMC_GCTRL) & AW_MMC_RESET) == 0)
+ break;
+ DELAY(100);
+ }
+ if (timeout == 0)
+ return (ETIMEDOUT);
+
+ /* Set the timeout. */
+ AW_MMC_WRITE_4(sc, AW_MMC_TIMEOUT, 0xffffffff);
+
+ /* Clear pending interrupts. */
+ AW_MMC_WRITE_4(sc, AW_MMC_RINTR, 0xffffffff);
+ AW_MMC_WRITE_4(sc, AW_MMC_IDST, 0xffffffff);
+ /* Unmask interrupts. */
+ AW_MMC_WRITE_4(sc, AW_MMC_IMASK,
+ AW_MMC_CMD_DONE | AW_MMC_INT_ERR_BIT |
+ AW_MMC_DATA_OVER | AW_MMC_AUTOCMD_DONE);
+ /* Enable interrupts and AHB access. */
+ AW_MMC_WRITE_4(sc, AW_MMC_GCTRL,
+ AW_MMC_READ_4(sc, AW_MMC_GCTRL) | AW_MMC_INT_ENABLE);
+
+ return (0);
+}
+
+static void
+aw_mmc_req_done(struct aw_mmc_softc *sc)
+{
+ struct mmc_command *cmd;
+ struct mmc_request *req;
+
+ cmd = sc->aw_req->cmd;
+ if (cmd->error != MMC_ERR_NONE) {
+ /* Reset the controller. */
+ aw_mmc_reset(sc);
+ aw_mmc_update_clock(sc);
+ }
+ if (sc->aw_dma_inuse == 0) {
+ /* Reset the FIFO. */
+ AW_MMC_WRITE_4(sc, AW_MMC_GCTRL,
+ AW_MMC_READ_4(sc, AW_MMC_GCTRL) | AW_MMC_FIFO_RESET);
+ }
+
+ req = sc->aw_req;
+ callout_stop(&sc->aw_timeoutc);
+ sc->aw_req = NULL;
+ sc->aw_intr = 0;
+ sc->aw_resid = 0;
+ sc->aw_dma_inuse = 0;
+ sc->aw_dma_map_err = 0;
+ sc->aw_intr_wait = 0;
+ req->done(req);
+}
+
+static void
+aw_mmc_req_ok(struct aw_mmc_softc *sc)
+{
+ int timeout;
+ struct mmc_command *cmd;
+ uint32_t status;
+
+ timeout = 1000;
+ while (--timeout > 0) {
+ status = AW_MMC_READ_4(sc, AW_MMC_STAS);
+ if ((status & AW_MMC_CARD_DATA_BUSY) == 0)
+ break;
+ DELAY(1000);
+ }
+ cmd = sc->aw_req->cmd;
+ if (timeout == 0) {
+ cmd->error = MMC_ERR_FAILED;
+ aw_mmc_req_done(sc);
+ return;
+ }
+ if (cmd->flags & MMC_RSP_PRESENT) {
+ if (cmd->flags & MMC_RSP_136) {
+ cmd->resp[0] = AW_MMC_READ_4(sc, AW_MMC_RESP3);
+ cmd->resp[1] = AW_MMC_READ_4(sc, AW_MMC_RESP2);
+ cmd->resp[2] = AW_MMC_READ_4(sc, AW_MMC_RESP1);
+ cmd->resp[3] = AW_MMC_READ_4(sc, AW_MMC_RESP0);
+ } else
+ cmd->resp[0] = AW_MMC_READ_4(sc, AW_MMC_RESP0);
+ }
+ /* All data has been transferred ? */
+ if (cmd->data != NULL && (sc->aw_resid << 2) < cmd->data->len)
+ cmd->error = MMC_ERR_FAILED;
+ aw_mmc_req_done(sc);
+}
+
+static void
+aw_mmc_timeout(void *arg)
+{
+ struct aw_mmc_softc *sc;
+
+ sc = (struct aw_mmc_softc *)arg;
+ if (sc->aw_req != NULL) {
+ device_printf(sc->aw_dev, "controller timeout\n");
+ sc->aw_req->cmd->error = MMC_ERR_TIMEOUT;
+ aw_mmc_req_done(sc);
+ } else
+ device_printf(sc->aw_dev,
+ "Spurious timeout - no active request\n");
+}
+
+static int
+aw_mmc_pio_transfer(struct aw_mmc_softc *sc, struct mmc_data *data)
+{
+ int i, write;
+ uint32_t bit, *buf;
+
+ buf = (uint32_t *)data->data;
+ write = (data->flags & MMC_DATA_WRITE) ? 1 : 0;
+ bit = write ? AW_MMC_FIFO_FULL : AW_MMC_FIFO_EMPTY;
+ for (i = sc->aw_resid; i < (data->len >> 2); i++) {
+ if ((AW_MMC_READ_4(sc, AW_MMC_STAS) & bit))
+ return (1);
+ if (write)
+ AW_MMC_WRITE_4(sc, AW_MMC_FIFO, buf[i]);
+ else
+ buf[i] = AW_MMC_READ_4(sc, AW_MMC_FIFO);
+ sc->aw_resid = i + 1;
+ }
+
+ return (0);
+}
+
+static void
+aw_mmc_intr(void *arg)
+{
+ bus_dmasync_op_t sync_op;
+ struct aw_mmc_softc *sc;
+ struct mmc_data *data;
+ uint32_t idst, imask, rint;
+
+ sc = (struct aw_mmc_softc *)arg;
+ AW_MMC_LOCK(sc);
+ rint = AW_MMC_READ_4(sc, AW_MMC_RINTR);
+ idst = AW_MMC_READ_4(sc, AW_MMC_IDST);
+ imask = AW_MMC_READ_4(sc, AW_MMC_IMASK);
+ if (idst == 0 && imask == 0 && rint == 0) {
+ AW_MMC_UNLOCK(sc);
+ return;
+ }
+#ifdef DEBUG
+ device_printf(sc->aw_dev, "idst: %#x, imask: %#x, rint: %#x\n",
+ idst, imask, rint);
+#endif
+ if (sc->aw_req == NULL) {
+ device_printf(sc->aw_dev,
+ "Spurious interrupt - no active request, rint: 0x%08X\n",
+ rint);
+ goto end;
+ }
+ if (rint & AW_MMC_INT_ERR_BIT) {
+ device_printf(sc->aw_dev, "error rint: 0x%08X\n", rint);
+ if (rint & AW_MMC_RESP_TIMEOUT)
+ sc->aw_req->cmd->error = MMC_ERR_TIMEOUT;
+ else
+ sc->aw_req->cmd->error = MMC_ERR_FAILED;
+ aw_mmc_req_done(sc);
+ goto end;
+ }
+ if (idst & AW_MMC_IDMAC_ERROR) {
+ device_printf(sc->aw_dev, "error idst: 0x%08x\n", idst);
+ sc->aw_req->cmd->error = MMC_ERR_FAILED;
+ aw_mmc_req_done(sc);
+ goto end;
+ }
+
+ sc->aw_intr |= rint;
+ data = sc->aw_req->cmd->data;
+ if (data != NULL && sc->aw_dma_inuse == 1 &&
+ (idst & AW_MMC_IDMAC_COMPLETE)) {
+ if (data->flags & MMC_DATA_WRITE)
+ sync_op = BUS_DMASYNC_POSTWRITE;
+ else
+ sync_op = BUS_DMASYNC_POSTREAD;
+ bus_dmamap_sync(sc->aw_dma_buf_tag, sc->aw_dma_buf_map,
+ sync_op);
+ bus_dmamap_sync(sc->aw_dma_tag, sc->aw_dma_map,
+ BUS_DMASYNC_POSTWRITE);
+ bus_dmamap_unload(sc->aw_dma_buf_tag, sc->aw_dma_buf_map);
+ sc->aw_resid = data->len >> 2;
+ } else if (data != NULL && sc->aw_dma_inuse == 0 &&
+ (rint & (AW_MMC_DATA_OVER | AW_MMC_RX_DATA_REQ |
+ AW_MMC_TX_DATA_REQ)) != 0)
+ aw_mmc_pio_transfer(sc, data);
+ if ((sc->aw_intr & sc->aw_intr_wait) == sc->aw_intr_wait)
+ aw_mmc_req_ok(sc);
+
+end:
+ AW_MMC_WRITE_4(sc, AW_MMC_IDST, idst);
+ AW_MMC_WRITE_4(sc, AW_MMC_RINTR, rint);
+ AW_MMC_UNLOCK(sc);
+}
+
+static int
+aw_mmc_request(device_t bus, device_t child, struct mmc_request *req)
+{
+ int blksz;
+ struct aw_mmc_softc *sc;
+ struct mmc_command *cmd;
+ uint32_t cmdreg, val;
+
+ sc = device_get_softc(bus);
+ AW_MMC_LOCK(sc);
+ if (sc->aw_req) {
+ AW_MMC_UNLOCK(sc);
+ return (EBUSY);
+ }
+ sc->aw_req = req;
+ cmd = req->cmd;
+ cmdreg = AW_MMC_START;
+ if (cmd->opcode == MMC_GO_IDLE_STATE)
+ cmdreg |= AW_MMC_SEND_INIT_SEQ;
+ if (cmd->flags & MMC_RSP_PRESENT)
+ cmdreg |= AW_MMC_RESP_EXP;
+ if (cmd->flags & MMC_RSP_136)
+ cmdreg |= AW_MMC_LONG_RESP;
+ if (cmd->flags & MMC_RSP_CRC)
+ cmdreg |= AW_MMC_CHECK_RESP_CRC;
+
+ sc->aw_intr = 0;
+ sc->aw_resid = 0;
+ sc->aw_intr_wait = AW_MMC_CMD_DONE;
+ cmd->error = MMC_ERR_NONE;
+ if (cmd->data != NULL) {
+ sc->aw_intr_wait |= AW_MMC_DATA_OVER;
+ cmdreg |= AW_MMC_DATA_EXP | AW_MMC_WAIT_PREOVER;
+ if (cmd->data->flags & MMC_DATA_MULTI) {
+ cmdreg |= AW_MMC_SEND_AUTOSTOP;
+ sc->aw_intr_wait |= AW_MMC_AUTOCMD_DONE;
+ }
+ if (cmd->data->flags & MMC_DATA_WRITE)
+ cmdreg |= AW_MMC_WRITE;
+ blksz = min(cmd->data->len, MMC_SECTOR_SIZE);
+ AW_MMC_WRITE_4(sc, AW_MMC_BLKSZ, blksz);
+ AW_MMC_WRITE_4(sc, AW_MMC_BCNTR, cmd->data->len);
+
+ if (aw_mmc_pio_mode == 0)
+ aw_mmc_prepare_dma(sc);
+ /* Enable PIO access if sc->aw_dma_inuse is not set. */
+ if (sc->aw_dma_inuse == 0) {
+ val = AW_MMC_READ_4(sc, AW_MMC_GCTRL);
+ val &= ~AW_MMC_DMA_ENABLE;
+ val |= AW_MMC_ACCESS_BY_AHB;
+ AW_MMC_WRITE_4(sc, AW_MMC_GCTRL, val);
+ val = AW_MMC_READ_4(sc, AW_MMC_IMASK);
+ val |= AW_MMC_RX_DATA_REQ | AW_MMC_TX_DATA_REQ;
+ AW_MMC_WRITE_4(sc, AW_MMC_IMASK, val);
+ }
+ }
+
+ AW_MMC_WRITE_4(sc, AW_MMC_CARG, cmd->arg);
+ AW_MMC_WRITE_4(sc, AW_MMC_CMDR, cmdreg | cmd->opcode);
+ callout_reset(&sc->aw_timeoutc, sc->aw_timeout * hz,
+ aw_mmc_timeout, sc);
+ AW_MMC_UNLOCK(sc);
+
+ return (0);
+}
+
+static int
+aw_mmc_read_ivar(device_t bus, device_t child, int which,
+ uintptr_t *result)
+{
+ struct aw_mmc_softc *sc;
+
+ sc = device_get_softc(bus);
+ switch (which) {
+ default:
+ return (EINVAL);
+ case MMCBR_IVAR_BUS_MODE:
+ *(int *)result = sc->aw_host.ios.bus_mode;
+ break;
+ case MMCBR_IVAR_BUS_WIDTH:
+ *(int *)result = sc->aw_host.ios.bus_width;
+ break;
+ case MMCBR_IVAR_CHIP_SELECT:
+ *(int *)result = sc->aw_host.ios.chip_select;
+ break;
+ case MMCBR_IVAR_CLOCK:
+ *(int *)result = sc->aw_host.ios.clock;
+ break;
+ case MMCBR_IVAR_F_MIN:
+ *(int *)result = sc->aw_host.f_min;
+ break;
+ case MMCBR_IVAR_F_MAX:
+ *(int *)result = sc->aw_host.f_max;
+ break;
+ case MMCBR_IVAR_HOST_OCR:
+ *(int *)result = sc->aw_host.host_ocr;
+ break;
+ case MMCBR_IVAR_MODE:
+ *(int *)result = sc->aw_host.mode;
+ break;
+ case MMCBR_IVAR_OCR:
+ *(int *)result = sc->aw_host.ocr;
+ break;
+ case MMCBR_IVAR_POWER_MODE:
+ *(int *)result = sc->aw_host.ios.power_mode;
+ break;
+ case MMCBR_IVAR_VDD:
+ *(int *)result = sc->aw_host.ios.vdd;
+ break;
+ case MMCBR_IVAR_CAPS:
+ *(int *)result = sc->aw_host.caps;
+ break;
+ case MMCBR_IVAR_MAX_DATA:
+ *(int *)result = 65535;
+ break;
+ }
+
+ return (0);
+}
+
+static int
+aw_mmc_write_ivar(device_t bus, device_t child, int which,
+ uintptr_t value)
+{
+ struct aw_mmc_softc *sc;
+
+ sc = device_get_softc(bus);
+ switch (which) {
+ default:
+ return (EINVAL);
+ case MMCBR_IVAR_BUS_MODE:
+ sc->aw_host.ios.bus_mode = value;
+ break;
+ case MMCBR_IVAR_BUS_WIDTH:
+ sc->aw_host.ios.bus_width = value;
+ break;
+ case MMCBR_IVAR_CHIP_SELECT:
+ sc->aw_host.ios.chip_select = value;
+ break;
+ case MMCBR_IVAR_CLOCK:
+ sc->aw_host.ios.clock = value;
+ break;
+ case MMCBR_IVAR_MODE:
+ sc->aw_host.mode = value;
+ break;
+ case MMCBR_IVAR_OCR:
+ sc->aw_host.ocr = value;
+ break;
+ case MMCBR_IVAR_POWER_MODE:
+ sc->aw_host.ios.power_mode = value;
+ break;
+ case MMCBR_IVAR_VDD:
+ sc->aw_host.ios.vdd = value;
+ break;
+ /* These are read-only */
+ case MMCBR_IVAR_CAPS:
+ case MMCBR_IVAR_HOST_OCR:
+ case MMCBR_IVAR_F_MIN:
+ case MMCBR_IVAR_F_MAX:
+ case MMCBR_IVAR_MAX_DATA:
+ return (EINVAL);
+ }
+
+ return (0);
+}
+
+static int
+aw_mmc_update_clock(struct aw_mmc_softc *sc)
+{
+ uint32_t cmdreg;
+ int retry;
+
+ cmdreg = AW_MMC_START | AW_MMC_UPCLK_ONLY |
+ AW_MMC_WAIT_PREOVER;
+ AW_MMC_WRITE_4(sc, AW_MMC_CMDR, cmdreg);
+ retry = 0xfffff;
+ while (--retry > 0) {
+ if ((AW_MMC_READ_4(sc, AW_MMC_CMDR) & AW_MMC_START) == 0) {
+ AW_MMC_WRITE_4(sc, AW_MMC_RINTR, 0xffffffff);
+ return (0);
+ }
+ DELAY(10);
+ }
+ AW_MMC_WRITE_4(sc, AW_MMC_RINTR, 0xffffffff);
+ device_printf(sc->aw_dev, "timeout updating clock\n");
+
+ return (ETIMEDOUT);
+}
+
+static int
+aw_mmc_update_ios(device_t bus, device_t child)
+{
+ int error;
+ struct aw_mmc_softc *sc;
+ struct mmc_ios *ios;
+ uint32_t clkcr;
+
+ sc = device_get_softc(bus);
+ clkcr = AW_MMC_READ_4(sc, AW_MMC_CLKCR);
+ if (clkcr & AW_MMC_CARD_CLK_ON) {
+ /* Disable clock. */
+ clkcr &= ~AW_MMC_CARD_CLK_ON;
+ AW_MMC_WRITE_4(sc, AW_MMC_CLKCR, clkcr);
+ error = aw_mmc_update_clock(sc);
+ if (error != 0)
+ return (error);
+ }
+
+ ios = &sc->aw_host.ios;
+ if (ios->clock) {
+ /* Reset the divider. */
+ clkcr &= ~AW_MMC_CLKCR_DIV;
+ AW_MMC_WRITE_4(sc, AW_MMC_CLKCR, clkcr);
+ error = aw_mmc_update_clock(sc);
+ if (error != 0)
+ return (error);
+
+ /* Set the MMC clock. */
+ error = a10_clk_mmc_cfg(sc->aw_id, ios->clock);
+ if (error != 0)
+ return (error);
+
+ /* Enable clock. */
+ clkcr |= AW_MMC_CARD_CLK_ON;
+ AW_MMC_WRITE_4(sc, AW_MMC_CLKCR, clkcr);
+ error = aw_mmc_update_clock(sc);
+ if (error != 0)
+ return (error);
+ }
+
+ /* Set the bus width. */
+ switch (ios->bus_width) {
+ case bus_width_1:
+ AW_MMC_WRITE_4(sc, AW_MMC_WIDTH, AW_MMC_WIDTH1);
+ break;
+ case bus_width_4:
+ AW_MMC_WRITE_4(sc, AW_MMC_WIDTH, AW_MMC_WIDTH4);
+ break;
+ case bus_width_8:
+ AW_MMC_WRITE_4(sc, AW_MMC_WIDTH, AW_MMC_WIDTH8);
+ break;
+ }
+
+ return (0);
+}
+
+static int
+aw_mmc_get_ro(device_t bus, device_t child)
+{
+
+ return (0);
+}
+
+static int
+aw_mmc_acquire_host(device_t bus, device_t child)
+{
+ struct aw_mmc_softc *sc;
+ int error;
+
+ sc = device_get_softc(bus);
+ AW_MMC_LOCK(sc);
+ while (sc->aw_bus_busy) {
+ error = msleep(sc, &sc->aw_mtx, PCATCH, "mmchw", 0);
+ if (error != 0) {
+ AW_MMC_UNLOCK(sc);
+ return (error);
+ }
+ }
+ sc->aw_bus_busy++;
+ AW_MMC_UNLOCK(sc);
+
+ return (0);
+}
+
+static int
+aw_mmc_release_host(device_t bus, device_t child)
+{
+ struct aw_mmc_softc *sc;
+
+ sc = device_get_softc(bus);
+ AW_MMC_LOCK(sc);
+ sc->aw_bus_busy--;
+ wakeup(sc);
+ AW_MMC_UNLOCK(sc);
+
+ return (0);
+}
+
+static device_method_t aw_mmc_methods[] = {
+ /* Device interface */
+ DEVMETHOD(device_probe, aw_mmc_probe),
+ DEVMETHOD(device_attach, aw_mmc_attach),
+ DEVMETHOD(device_detach, aw_mmc_detach),
+
+ /* Bus interface */
+ DEVMETHOD(bus_read_ivar, aw_mmc_read_ivar),
+ DEVMETHOD(bus_write_ivar, aw_mmc_write_ivar),
+ DEVMETHOD(bus_print_child, bus_generic_print_child),
+
+ /* MMC bridge interface */
+ DEVMETHOD(mmcbr_update_ios, aw_mmc_update_ios),
+ DEVMETHOD(mmcbr_request, aw_mmc_request),
+ DEVMETHOD(mmcbr_get_ro, aw_mmc_get_ro),
+ DEVMETHOD(mmcbr_acquire_host, aw_mmc_acquire_host),
+ DEVMETHOD(mmcbr_release_host, aw_mmc_release_host),
+
+ DEVMETHOD_END
+};
+
+static devclass_t aw_mmc_devclass;
+
+static driver_t aw_mmc_driver = {
+ "aw_mmc",
+ aw_mmc_methods,
+ sizeof(struct aw_mmc_softc),
+};
+
+DRIVER_MODULE(aw_mmc, simplebus, aw_mmc_driver, aw_mmc_devclass, 0, 0);
+DRIVER_MODULE(mmc, aw_mmc, mmc_driver, mmc_devclass, NULL, NULL);
Index: sys/arm/allwinner/aw_wdog.h
===================================================================
--- sys/arm/allwinner/aw_wdog.h
+++ sys/arm/allwinner/aw_wdog.h
@@ -26,10 +26,10 @@
* $FreeBSD$
*
*/
-#ifndef __A10_WDOG_H__
-#define __A10_WDOG_H__
+#ifndef __AW_WDOG_H__
+#define __AW_WDOG_H__
-void a10wd_watchdog_reset(void);
+void aw_watchdog_reset(void);
-#endif /*__A10_WDOG_H__*/
+#endif /*__AW_WDOG_H__*/
Index: sys/arm/allwinner/aw_wdog.c
===================================================================
--- sys/arm/allwinner/aw_wdog.c
+++ sys/arm/allwinner/aw_wdog.c
@@ -45,7 +45,7 @@
#include <machine/cpufunc.h>
#include <machine/machdep.h>
-#include <arm/allwinner/a10_wdog.h>
+#include <arm/allwinner/aw_wdog.h>
#define READ(_sc, _r) bus_read_4((_sc)->res, (_r))
#define WRITE(_sc, _r, _v) bus_write_4((_sc)->res, (_r), (_v))
@@ -57,12 +57,12 @@
#define WDOG_MODE_RST_EN (1 << 1)
#define WDOG_MODE_EN (1 << 0)
-struct a10wd_interval {
+struct aw_wdog_interval {
uint64_t milliseconds;
unsigned int value;
};
-struct a10wd_interval wd_intervals[] = {
+struct aw_wdog_interval wd_intervals[] = {
{ 500, 0 },
{ 1000, 1 },
{ 2000, 2 },
@@ -78,18 +78,18 @@
{ 0, 0 } /* sentinel */
};
-static struct a10wd_softc *a10wd_sc = NULL;
+static struct aw_wdog_softc *aw_wdog_sc = NULL;
-struct a10wd_softc {
+struct aw_wdog_softc {
device_t dev;
struct resource * res;
struct mtx mtx;
};
-static void a10wd_watchdog_fn(void *private, u_int cmd, int *error);
+static void aw_wdog_watchdog_fn(void *private, u_int cmd, int *error);
static int
-a10wd_probe(device_t dev)
+aw_wdog_probe(device_t dev)
{
if (!ofw_bus_status_okay(dev))
@@ -104,12 +104,12 @@
}
static int
-a10wd_attach(device_t dev)
+aw_wdog_attach(device_t dev)
{
- struct a10wd_softc *sc;
+ struct aw_wdog_softc *sc;
int rid;
- if (a10wd_sc != NULL)
+ if (aw_wdog_sc != NULL)
return (ENXIO);
sc = device_get_softc(dev);
@@ -122,17 +122,17 @@
return (ENXIO);
}
- a10wd_sc = sc;
+ aw_wdog_sc = sc;
mtx_init(&sc->mtx, "A10 Watchdog", "a10wd", MTX_DEF);
- EVENTHANDLER_REGISTER(watchdog_list, a10wd_watchdog_fn, sc, 0);
+ EVENTHANDLER_REGISTER(watchdog_list, aw_wdog_watchdog_fn, sc, 0);
return (0);
}
static void
-a10wd_watchdog_fn(void *private, u_int cmd, int *error)
+aw_wdog_watchdog_fn(void *private, u_int cmd, int *error)
{
- struct a10wd_softc *sc;
+ struct aw_wdog_softc *sc;
uint64_t ms;
int i;
@@ -173,15 +173,15 @@
}
void
-a10wd_watchdog_reset()
+aw_watchdog_reset()
{
- if (a10wd_sc == NULL) {
+ if (aw_wdog_sc == NULL) {
printf("Reset: watchdog device has not been initialized\n");
return;
}
- WRITE(a10wd_sc, WDOG_MODE,
+ WRITE(aw_wdog_sc, WDOG_MODE,
(wd_intervals[0].value << WDOG_MODE_INTVL_SHIFT) |
WDOG_MODE_EN | WDOG_MODE_RST_EN);
@@ -190,18 +190,18 @@
}
-static device_method_t a10wd_methods[] = {
- DEVMETHOD(device_probe, a10wd_probe),
- DEVMETHOD(device_attach, a10wd_attach),
+static device_method_t aw_wdog_methods[] = {
+ DEVMETHOD(device_probe, aw_wdog_probe),
+ DEVMETHOD(device_attach, aw_wdog_attach),
DEVMETHOD_END
};
-static driver_t a10wd_driver = {
+static driver_t aw_wdog_driver = {
"a10wd",
- a10wd_methods,
- sizeof(struct a10wd_softc),
+ aw_wdog_methods,
+ sizeof(struct aw_wdog_softc),
};
-static devclass_t a10wd_devclass;
+static devclass_t aw_wdog_devclass;
-DRIVER_MODULE(a10wd, simplebus, a10wd_driver, a10wd_devclass, 0, 0);
+DRIVER_MODULE(a10wd, simplebus, aw_wdog_driver, aw_wdog_devclass, 0, 0);
Index: sys/arm/allwinner/files.a10
===================================================================
--- sys/arm/allwinner/files.a10
+++ /dev/null
@@ -1,4 +0,0 @@
-# $FreeBSD$
-
-arm/allwinner/aintc.c standard
-arm/allwinner/timer.c standard
Index: sys/arm/allwinner/files.allwinner
===================================================================
--- sys/arm/allwinner/files.allwinner
+++ sys/arm/allwinner/files.allwinner
@@ -1,16 +1,17 @@
# $FreeBSD$
kern/kern_clocksource.c standard
-arm/allwinner/a10_ahci.c optional ahci
-arm/allwinner/a10_clk.c standard
-arm/allwinner/a10_common.c standard
-arm/allwinner/a10_ehci.c optional ehci
-arm/allwinner/a10_gpio.c optional gpio
-arm/allwinner/a10_mmc.c optional mmc
-arm/allwinner/a10_sramc.c standard
-arm/allwinner/a10_wdog.c standard
+arm/allwinner/a10/a10_ahci.c optional ahci
+arm/allwinner/a10/a10_clk.c standard
+arm/allwinner/a10/a10_sramc.c standard
arm/allwinner/a20/a20_cpu_cfg.c standard
-arm/allwinner/allwinner_machdep.c standard
+arm/allwinner/aw_common.c standard
+arm/allwinner/aw_ehci.c optional ehci
+arm/allwinner/aw_if_dwc.c optional dwc
+arm/allwinner/aw_gpio.c optional gpio
+arm/allwinner/aw_machdep.c standard
+arm/allwinner/aw_mmc.c optional mmc
+arm/allwinner/aw_wdog.c standard
arm/allwinner/if_emac.c optional emac
dev/iicbus/twsi/a10_twsi.c optional twsi
#arm/allwinner/console.c standard
Index: sys/arm/allwinner/if_emac.c
===================================================================
--- sys/arm/allwinner/if_emac.c
+++ sys/arm/allwinner/if_emac.c
@@ -76,16 +76,15 @@
#include <dev/mii/mii.h>
#include <dev/mii/miivar.h>
+#include <arm/allwinner/a10/a10_clk.h>
+#include <arm/allwinner/a10/a10_sramc.h>
#include <arm/allwinner/if_emacreg.h>
+#include <arm/allwinner/aw_gpio.h>
#include "miibus_if.h"
#include "gpio_if.h"
-#include "a10_clk.h"
-#include "a10_sramc.h"
-#include "a10_gpio.h"
-
struct emac_softc {
struct ifnet *emac_ifp;
device_t emac_dev;
@@ -146,7 +145,7 @@
/* Activate EMAC clock. */
a10_clk_emac_activate();
/* Set the pin mux to EMAC (mii). */
- a10_gpio_ethernet_activate(A10_GPIO_FUNC_MII);
+ aw_gpio_ethernet_activate(AW_GPIO_FUNC_MII);
/* Map sram. */
a10_map_to_emac();
}
Index: sys/arm/conf/A10
===================================================================
--- sys/arm/conf/A10
+++ sys/arm/conf/A10
@@ -21,7 +21,7 @@
ident A10
include "std.armv6"
-include "../allwinner/std.a10"
+include "../allwinner/a10/std.a10"
options HZ=100
options SCHED_4BSD # 4BSD scheduler
Index: sys/arm/conf/CUBIEBOARD
===================================================================
--- sys/arm/conf/CUBIEBOARD
+++ sys/arm/conf/CUBIEBOARD
@@ -22,7 +22,7 @@
ident CUBIEBOARD
include "std.armv6"
-include "../allwinner/std.a10"
+include "../allwinner/a10/std.a10"
options HZ=100
options SCHED_4BSD # 4BSD scheduler
Index: sys/dev/iicbus/twsi/a10_twsi.c
===================================================================
--- sys/dev/iicbus/twsi/a10_twsi.c
+++ sys/dev/iicbus/twsi/a10_twsi.c
@@ -48,7 +48,7 @@
#include <dev/ofw/ofw_bus.h>
#include <dev/ofw/ofw_bus_subr.h>
-#include <arm/allwinner/a10_clk.h>
+#include <arm/allwinner/a10/a10_clk.h>
#include "iicbus_if.h"
File Metadata
Details
Attached
Mime Type
text/plain
Expires
Thu, Nov 20, 6:28 AM (3 h, 53 m)
Storage Engine
blob
Storage Format
Raw Data
Storage Handle
25712046
Default Alt Text
D5280.diff (125 KB)
Attached To
Mode
D5280: Allwinner source tree cleanup
Attached
Detach File
Event Timeline
Log In to Comment