Source-Changes-HG archive
[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index][Old Index]
[src/trunk]: src/sys/arch A80 MMC support. Works for SD card slot on Cubie4, ...
details: https://anonhg.NetBSD.org/src/rev/8439a3b4cc3e
branches: trunk
changeset: 804896:8439a3b4cc3e
user: jmcneill <jmcneill%NetBSD.org@localhost>
date: Fri Dec 05 14:36:44 2014 +0000
description:
A80 MMC support. Works for SD card slot on Cubie4, but not eMMC yet.
diffstat:
sys/arch/arm/allwinner/awin_board.c | 32 ++++++-
sys/arch/arm/allwinner/awin_io.c | 20 +++-
sys/arch/arm/allwinner/awin_mmc.c | 155 +++++++++++++++++++++++++++++------
sys/arch/arm/allwinner/awin_reg.h | 77 ++++++++++++++++-
sys/arch/arm/allwinner/awin_var.h | 3 +-
sys/arch/evbarm/conf/ALLWINNER_A80 | 12 +-
6 files changed, 251 insertions(+), 48 deletions(-)
diffs (truncated from 566 to 300 lines):
diff -r 57358a2dff63 -r 8439a3b4cc3e sys/arch/arm/allwinner/awin_board.c
--- a/sys/arch/arm/allwinner/awin_board.c Fri Dec 05 11:53:43 2014 +0000
+++ b/sys/arch/arm/allwinner/awin_board.c Fri Dec 05 14:36:44 2014 +0000
@@ -1,4 +1,4 @@
-/* $NetBSD: awin_board.c,v 1.30 2014/12/05 01:13:11 jmcneill Exp $ */
+/* $NetBSD: awin_board.c,v 1.31 2014/12/05 14:36:44 jmcneill Exp $ */
/*-
* Copyright (c) 2012 The NetBSD Foundation, Inc.
* All rights reserved.
@@ -36,7 +36,7 @@
#include <sys/cdefs.h>
-__KERNEL_RCSID(1, "$NetBSD: awin_board.c,v 1.30 2014/12/05 01:13:11 jmcneill Exp $");
+__KERNEL_RCSID(1, "$NetBSD: awin_board.c,v 1.31 2014/12/05 14:36:44 jmcneill Exp $");
#include <sys/param.h>
#include <sys/bus.h>
@@ -128,8 +128,8 @@
#if defined(ALLWINNER_A80)
const uint32_t c0cpux = bus_space_read_4(&awin_bs_tag, awin_core_bsh,
AWIN_A80_CCU_OFFSET + AWIN_A80_CCU_PLL_C0CPUX_CTRL_REG);
- const u_int p = (c0cpux & AWIN_A80_CCU_PLL_OUT_EXT_DIVP) ? 4 : 1;
- const u_int n = __SHIFTOUT(c0cpux, AWIN_A80_CCU_PLL_FACTOR_N);
+ const u_int p = (c0cpux & AWIN_A80_CCU_PLL_CxCPUX_OUT_EXT_DIVP) ? 4 : 1;
+ const u_int n = __SHIFTOUT(c0cpux, AWIN_A80_CCU_PLL_CxCPUX_FACTOR_N);
ci->ci_data.cpu_cc_freq = ((uint64_t)AWIN_REF_FREQ * n) / p;
#else
@@ -333,6 +333,8 @@
bus_space_tag_t bst = &awin_bs_tag;
bus_space_handle_t bsh = awin_core_bsh;
+ KASSERT(awin_chip_id() != AWIN_CHIP_ID_A80);
+
/*
* SATA needs PLL6 to be a 100MHz clock.
*/
@@ -549,6 +551,7 @@
unsigned int n, k, p;
KASSERT(awin_chip_id() != AWIN_CHIP_ID_A31);
+ KASSERT(awin_chip_id() != AWIN_CHIP_ID_A80);
const uint32_t cfg = bus_space_read_4(bst, bsh,
AWIN_CCM_OFFSET + AWIN_PLL5_CFG_REG);
@@ -567,6 +570,8 @@
bus_space_handle_t bsh = awin_core_bsh;
unsigned int n, k, m;
+ KASSERT(awin_chip_id() != AWIN_CHIP_ID_A80);
+
const uint32_t cfg = bus_space_read_4(bst, bsh,
AWIN_CCM_OFFSET + AWIN_PLL6_CFG_REG);
@@ -582,3 +587,22 @@
return (AWIN_REF_FREQ * n * k) / m;
}
+
+uint32_t
+awin_periph0_get_rate(void)
+{
+ bus_space_tag_t bst = &awin_bs_tag;
+ bus_space_handle_t bsh = awin_core_bsh;
+ unsigned int n, idiv, odiv;
+
+ KASSERT(awin_chip_id() == AWIN_CHIP_ID_A80);
+
+ const uint32_t cfg = bus_space_read_4(bst, bsh,
+ AWIN_A80_CCU_OFFSET + AWIN_A80_CCU_PLL_PERIPH0_CTRL_REG);
+
+ n = __SHIFTOUT(cfg, AWIN_A80_CCU_PLL_PERIPH0_FACTOR_N);
+ idiv = __SHIFTOUT(cfg, AWIN_A80_CCU_PLL_PERIPH0_INPUT_DIV) + 1;
+ odiv = __SHIFTOUT(cfg, AWIN_A80_CCU_PLL_PERIPH0_OUTPUT_DIV) + 1;
+
+ return ((AWIN_REF_FREQ * n) / idiv) / odiv;
+}
diff -r 57358a2dff63 -r 8439a3b4cc3e sys/arch/arm/allwinner/awin_io.c
--- a/sys/arch/arm/allwinner/awin_io.c Fri Dec 05 11:53:43 2014 +0000
+++ b/sys/arch/arm/allwinner/awin_io.c Fri Dec 05 14:36:44 2014 +0000
@@ -31,7 +31,7 @@
#include <sys/cdefs.h>
-__KERNEL_RCSID(1, "$NetBSD: awin_io.c,v 1.31 2014/12/05 11:53:43 jmcneill Exp $");
+__KERNEL_RCSID(1, "$NetBSD: awin_io.c,v 1.32 2014/12/05 14:36:44 jmcneill Exp $");
#include <sys/param.h>
#include <sys/bus.h>
@@ -204,11 +204,23 @@
sc->sc_dmat = &awin_dma_tag;
sc->sc_coherent_dmat = &awin_coherent_dma_tag;
- bus_space_subregion(sc->sc_bst, sc->sc_bsh, AWIN_CCM_OFFSET, 0x1000,
- &sc->sc_ccm_bsh);
+ switch (awin_chip_id()) {
+ case AWIN_CHIP_ID_A80:
+ bus_space_subregion(sc->sc_bst, sc->sc_bsh,
+ AWIN_A80_CCU_SCLK_OFFSET, 0x1000, &sc->sc_ccm_bsh);
+ break;
+ default:
+ bus_space_subregion(sc->sc_bst, sc->sc_bsh, AWIN_CCM_OFFSET,
+ 0x1000, &sc->sc_ccm_bsh);
+ break;
+ }
aprint_naive("\n");
- aprint_normal(": %s (0x%04x)\n", chip_name, chip_id);
+ aprint_normal(": %s", chip_name);
+ if ((chip_id & 0xff00) != 0xff00) {
+ aprint_normal(" (0x%04x)\n", chip_id);
+ }
+ aprint_normal("\n");
const struct awin_locators * const eloc =
awin_locators + __arraycount(awin_locators);
diff -r 57358a2dff63 -r 8439a3b4cc3e sys/arch/arm/allwinner/awin_mmc.c
--- a/sys/arch/arm/allwinner/awin_mmc.c Fri Dec 05 11:53:43 2014 +0000
+++ b/sys/arch/arm/allwinner/awin_mmc.c Fri Dec 05 14:36:44 2014 +0000
@@ -1,4 +1,4 @@
-/* $NetBSD: awin_mmc.c,v 1.16 2014/12/04 03:03:44 jmcneill Exp $ */
+/* $NetBSD: awin_mmc.c,v 1.17 2014/12/05 14:36:44 jmcneill Exp $ */
/*-
* Copyright (c) 2014 Jared D. McNeill <jmcneill%invisible.ca@localhost>
@@ -29,7 +29,7 @@
#include "locators.h"
#include <sys/cdefs.h>
-__KERNEL_RCSID(0, "$NetBSD: awin_mmc.c,v 1.16 2014/12/04 03:03:44 jmcneill Exp $");
+__KERNEL_RCSID(0, "$NetBSD: awin_mmc.c,v 1.17 2014/12/05 14:36:44 jmcneill Exp $");
#include <sys/param.h>
#include <sys/bus.h>
@@ -46,7 +46,14 @@
#include <arm/allwinner/awin_var.h>
#define AWIN_MMC_NDESC 16
-#define AWIN_MMC_DMA_FTRGLEVEL 0x20070008
+#define AWIN_MMC_DMA_FTRGLEVEL_A20 0x20070008
+#define AWIN_MMC_DMA_FTRGLEVEL_A80 0x200f0010
+
+static const struct awin_gpio_pinset awin_mmc_pinsets_a80[4] = {
+ [0] = { 'F', AWIN_A80_PIO_PF_SDMMC0_FUNC, AWIN_A80_PIO_PF_SDMMC0_PINS },
+ [1] = { 'G', AWIN_A80_PIO_PG_SDMMC1_FUNC, AWIN_A80_PIO_PG_SDMMC1_PINS },
+ [2] = { 'C', AWIN_A80_PIO_PC_SDMMC2_FUNC, AWIN_A80_PIO_PC_SDMMC2_PINS },
+};
static int awin_mmc_match(device_t, cfdata_t, void *);
static void awin_mmc_attach(device_t, device_t, void *);
@@ -88,6 +95,7 @@
bus_space_tag_t sc_bst;
bus_space_handle_t sc_bsh;
bus_space_handle_t sc_clk_bsh;
+ bus_space_handle_t sc_comm_bsh;
bus_dma_tag_t sc_dmat;
bool sc_use_dma;
@@ -99,10 +107,12 @@
int sc_mmc_width;
int sc_mmc_present;
+ int sc_mmc_port;
device_t sc_sdmmc_dev;
uint32_t sc_fifo_reg;
+ uint32_t sc_dma_ftrglevel;
uint32_t sc_idma_xferlen;
bus_dma_segment_t sc_idma_segs[1];
@@ -203,13 +213,12 @@
sc->sc_dev = self;
sc->sc_bst = aio->aio_core_bst;
sc->sc_dmat = aio->aio_dmat;
+ sc->sc_mmc_port = loc->loc_port;
mutex_init(&sc->sc_intr_lock, MUTEX_DEFAULT, IPL_BIO);
cv_init(&sc->sc_intr_cv, "awinmmcirq");
cv_init(&sc->sc_idst_cv, "awinmmcdma");
bus_space_subregion(sc->sc_bst, aio->aio_core_bsh,
loc->loc_offset, loc->loc_size, &sc->sc_bsh);
- bus_space_subregion(sc->sc_bst, aio->aio_ccm_bsh,
- AWIN_SD0_CLK_REG + (loc->loc_port * 4), 0, &sc->sc_clk_bsh);
sc->sc_use_dma = true;
prop_dictionary_get_bool(cfg, "dma", &sc->sc_use_dma);
@@ -217,15 +226,47 @@
aprint_naive("\n");
aprint_normal(": SD3.0 (%s)\n", sc->sc_use_dma ? "DMA" : "PIO");
- awin_pll6_enable();
+ if (awin_chip_id() == AWIN_CHIP_ID_A80) {
+
+ if (awin_mmc_pinsets_a80[loc->loc_port].pinset_group) {
+ awin_gpio_pinset_acquire(
+ &awin_mmc_pinsets_a80[loc->loc_port]);
+ }
+
+ bus_space_subregion(sc->sc_bst, aio->aio_ccm_bsh,
+ AWIN_A80_CCU_SCLK_SDMMC0_CLK_REG + (loc->loc_port * 4), 4,
+ &sc->sc_clk_bsh);
+ bus_space_subregion(sc->sc_bst, aio->aio_core_bsh,
+ AWIN_A80_SDMMC_COMM_OFFSET + (loc->loc_port * 4), 4,
+ &sc->sc_comm_bsh);
+ awin_reg_set_clear(aio->aio_core_bst, aio->aio_ccm_bsh,
+ AWIN_A80_CCU_SCLK_BUS_CLK_GATING0_REG,
+ AWIN_A80_CCU_SCLK_BUS_CLK_GATING0_SD, 0);
+ awin_reg_set_clear(aio->aio_core_bst, aio->aio_ccm_bsh,
+ AWIN_A80_CCU_SCLK_BUS_SOFT_RST0_REG,
+ AWIN_A80_CCU_SCLK_BUS_SOFT_RST0_SD, 0);
- awin_reg_set_clear(aio->aio_core_bst, aio->aio_ccm_bsh,
- AWIN_AHB_GATING0_REG,
- AWIN_AHB_GATING0_SDMMC0 << loc->loc_port, 0);
- if (awin_chip_id() == AWIN_CHIP_ID_A31) {
+ const uint32_t comm = bus_space_read_4(sc->sc_bst,
+ sc->sc_comm_bsh, 0);
+ bus_space_write_4(sc->sc_bst, sc->sc_comm_bsh, 0,
+ comm |
+ AWIN_A80_SDMMC_COMM_SDC_RESET_SW |
+ AWIN_A80_SDMMC_COMM_SDC_CLOCK_SW);
+ delay(1000);
+ } else {
+ bus_space_subregion(sc->sc_bst, aio->aio_ccm_bsh,
+ AWIN_SD0_CLK_REG + (loc->loc_port * 4), 4, &sc->sc_clk_bsh);
+
+ awin_pll6_enable();
+
awin_reg_set_clear(aio->aio_core_bst, aio->aio_ccm_bsh,
- AWIN_A31_AHB_RESET0_REG,
- AWIN_A31_AHB_RESET0_SD0_RST << loc->loc_port, 0);
+ AWIN_AHB_GATING0_REG,
+ AWIN_AHB_GATING0_SDMMC0 << loc->loc_port, 0);
+ if (awin_chip_id() == AWIN_CHIP_ID_A31) {
+ awin_reg_set_clear(aio->aio_core_bst, aio->aio_ccm_bsh,
+ AWIN_A31_AHB_RESET0_REG,
+ AWIN_A31_AHB_RESET0_SD0_RST << loc->loc_port, 0);
+ }
}
if (prop_dictionary_get_cstring_nocopy(cfg, "detect-gpio", &pin_name)) {
@@ -253,10 +294,19 @@
}
}
- if (awin_chip_id() == AWIN_CHIP_ID_A31) {
+ switch (awin_chip_id()) {
+ case AWIN_CHIP_ID_A80:
+ sc->sc_fifo_reg = AWIN_A31_MMC_FIFO;
+ sc->sc_dma_ftrglevel = AWIN_MMC_DMA_FTRGLEVEL_A80;
+ break;
+ case AWIN_CHIP_ID_A31:
sc->sc_fifo_reg = AWIN_A31_MMC_FIFO;
- } else {
+ sc->sc_dma_ftrglevel = AWIN_MMC_DMA_FTRGLEVEL_A20;
+ break;
+ default:
sc->sc_fifo_reg = AWIN_MMC_FIFO;
+ sc->sc_dma_ftrglevel = AWIN_MMC_DMA_FTRGLEVEL_A20;
+ break;
}
if (sc->sc_use_dma) {
@@ -293,7 +343,7 @@
saa.saa_sct = &awin_mmc_chip_functions;
saa.saa_sch = sc;
saa.saa_clkmin = 400;
- saa.saa_clkmax = 50000;
+ saa.saa_clkmax = awin_chip_id() == AWIN_CHIP_ID_A80 ? 48000 : 50000;
saa.saa_caps = SMC_CAPS_4BIT_MODE|
SMC_CAPS_8BIT_MODE|
SMC_CAPS_SD_HIGHSPEED|
@@ -394,13 +444,28 @@
awin_mmc_host_reset(sdmmc_chipset_handle_t sch)
{
struct awin_mmc_softc *sc = sch;
+ int retry = 1000;
#ifdef AWIN_MMC_DEBUG
aprint_normal_dev(sc->sc_dev, "host reset\n");
#endif
+ if (awin_chip_id() == AWIN_CHIP_ID_A80) {
+ if (sc->sc_mmc_port == 2 || sc->sc_mmc_port == 3) {
+ MMC_WRITE(sc, AWIN_MMC_HWRST, 0);
+ delay(10);
+ MMC_WRITE(sc, AWIN_MMC_HWRST, 1);
+ delay(300);
+ }
+ }
+
MMC_WRITE(sc, AWIN_MMC_GCTRL,
MMC_READ(sc, AWIN_MMC_GCTRL) | AWIN_MMC_GCTRL_RESET);
+ while (--retry > 0) {
+ if (!(MMC_READ(sc, AWIN_MMC_GCTRL) & AWIN_MMC_GCTRL_RESET))
+ break;
+ delay(100);
+ }
Home |
Main Index |
Thread Index |
Old Index