Merge i.MX and PowerPC SDHCI drivers
Summary: i.MX5 and PowerPC use a very similar eSDHC controller, which is also similar to the uSDHC controller used by i.MX6. The imx_sdhci driver works almost completely with PowerPC, with some minor tweaks. There is one caveat with this: reset currently does not work on PowerPC, so has been #ifdef'd out until this can be tracked down and fixed. If resets are done the controller will timeout all data transactions. Without a reset, it appears to work just fine. This is part 3, following up r308186 and r308187. Test Plan: This has been tested on a PowerPC QorIQ P1022 board. It has not been tested on i.MX, but no regressions are expected. Reviewed By: imp Differential Revision: https://reviews.freebsd.org/D8407
This commit is contained in:
parent
2b96b955e9
commit
eecaab5275
Notes:
svn2git
2020-12-20 02:59:44 +00:00
svn path=/head/; revision=308188
@ -63,6 +63,7 @@ dev/ofw/ofw_subr.c optional aim powerpc
|
||||
dev/powermac_nvram/powermac_nvram.c optional powermac_nvram powermac
|
||||
dev/quicc/quicc_bfe_fdt.c optional quicc mpc85xx
|
||||
dev/scc/scc_bfe_macio.c optional scc powermac
|
||||
dev/sdhci/fsl_sdhci.c optional mpc85xx sdhci
|
||||
dev/sec/sec.c optional sec mpc85xx
|
||||
dev/sound/macio/aoa.c optional snd_davbus | snd_ai2s powermac
|
||||
dev/sound/macio/davbus.c optional snd_davbus powermac
|
||||
@ -137,7 +138,6 @@ powerpc/mpc85xx/atpic.c optional mpc85xx isa
|
||||
powerpc/mpc85xx/ds1553_bus_fdt.c optional ds1553 fdt
|
||||
powerpc/mpc85xx/ds1553_core.c optional ds1553
|
||||
powerpc/mpc85xx/fsl_diu.c optional mpc85xx diu
|
||||
powerpc/mpc85xx/fsl_sdhc.c optional mpc85xx sdhc
|
||||
powerpc/mpc85xx/i2c.c optional iicbus fdt
|
||||
powerpc/mpc85xx/isa.c optional mpc85xx isa
|
||||
powerpc/mpc85xx/lbc.c optional mpc85xx
|
||||
|
@ -28,7 +28,7 @@
|
||||
__FBSDID("$FreeBSD$");
|
||||
|
||||
/*
|
||||
* SDHCI driver glue for Freescale i.MX SoC family.
|
||||
* SDHCI driver glue for Freescale i.MX SoC and QorIQ families.
|
||||
*
|
||||
* This supports both eSDHC (earlier SoCs) and uSDHC (more recent SoCs).
|
||||
*/
|
||||
@ -38,6 +38,7 @@ __FBSDID("$FreeBSD$");
|
||||
#include <sys/types.h>
|
||||
#include <sys/bus.h>
|
||||
#include <sys/callout.h>
|
||||
#include <sys/endian.h>
|
||||
#include <sys/kernel.h>
|
||||
#include <sys/libkern.h>
|
||||
#include <sys/lock.h>
|
||||
@ -52,9 +53,11 @@ __FBSDID("$FreeBSD$");
|
||||
|
||||
#include <machine/bus.h>
|
||||
#include <machine/resource.h>
|
||||
#ifdef __arm__
|
||||
#include <machine/intr.h>
|
||||
|
||||
#include <arm/freescale/imx/imx_ccmvar.h>
|
||||
#endif
|
||||
|
||||
#include <dev/ofw/ofw_bus.h>
|
||||
#include <dev/ofw/ofw_bus_subr.h>
|
||||
@ -146,7 +149,6 @@ struct fsl_sdhci_softc {
|
||||
#define SDHC_PROT_CDSS (1 << 7)
|
||||
|
||||
#define SDHC_SYS_CTRL 0x2c
|
||||
#define SDHC_INT_STATUS 0x30
|
||||
|
||||
/*
|
||||
* The clock enable bits exist in different registers for ESDHC vs USDHC, but
|
||||
@ -169,6 +171,7 @@ static struct ofw_compat_data compat_data[] = {
|
||||
{"fsl,imx6sl-usdhc", HWTYPE_USDHC},
|
||||
{"fsl,imx53-esdhc", HWTYPE_ESDHC},
|
||||
{"fsl,imx51-esdhc", HWTYPE_ESDHC},
|
||||
{"fsl,esdhc", HWTYPE_ESDHC},
|
||||
{NULL, HWTYPE_NONE},
|
||||
};
|
||||
|
||||
@ -397,6 +400,11 @@ fsl_sdhci_write_1(device_t dev, struct sdhci_slot *slot, bus_size_t off, uint8_t
|
||||
if (off == SDHCI_POWER_CONTROL) {
|
||||
return;
|
||||
}
|
||||
#ifdef __powerpc__
|
||||
/* XXX Reset doesn't seem to work as expected. Do nothing for now. */
|
||||
if (off == SDHCI_SOFTWARE_RESET)
|
||||
return;
|
||||
#endif
|
||||
|
||||
val32 = RD4(sc, off & ~3);
|
||||
val32 &= ~(0xff << (off & 3) * 8);
|
||||
@ -531,17 +539,20 @@ fsl_sdhc_get_clock(struct fsl_sdhci_softc *sc)
|
||||
val |= SDHCI_CLOCK_INT_STABLE;
|
||||
|
||||
/*
|
||||
* On ESDHC hardware the card bus clock enable is in the usual sdhci
|
||||
* register but it's a different bit, so transcribe it (note the
|
||||
* On i.MX ESDHC hardware the card bus clock enable is in the usual
|
||||
* sdhci register but it's a different bit, so transcribe it (note the
|
||||
* difference between standard SDHCI_ and Freescale SDHC_ prefixes
|
||||
* here). On USDHC hardware there is a force-on bit, but no force-off
|
||||
* for the card bus clock (the hardware runs the clock when transfers
|
||||
* are active no matter what), so we always say the clock is on.
|
||||
* here). On USDHC and QorIQ ESDHC hardware there is a force-on bit, but
|
||||
* no force-off for the card bus clock (the hardware runs the clock when
|
||||
* transfers are active no matter what), so we always say the clock is
|
||||
* on.
|
||||
* XXX Maybe we should say it's in whatever state the sdhci driver last
|
||||
* set it to.
|
||||
*/
|
||||
if (sc->hwtype == HWTYPE_ESDHC) {
|
||||
#ifdef __arm__
|
||||
if (RD4(sc, SDHC_SYS_CTRL) & SDHC_CLK_SDCLKEN)
|
||||
#endif
|
||||
val |= SDHCI_CLOCK_CARD_EN;
|
||||
} else {
|
||||
val |= SDHCI_CLOCK_CARD_EN;
|
||||
@ -565,15 +576,18 @@ fsl_sdhc_set_clock(struct fsl_sdhci_softc *sc, uint16_t val)
|
||||
sc->sdclockreg_freq_bits = val & SDHCI_DIVIDERS_MASK;
|
||||
if (sc->hwtype == HWTYPE_ESDHC) {
|
||||
/*
|
||||
* The ESDHC hardware requires the driver to manually start and
|
||||
* stop the sd bus clock. If the enable bit is not set, turn
|
||||
* off the clock in hardware and we're done, otherwise decode
|
||||
* the requested frequency. ESDHC hardware is sdhci 2.0; the
|
||||
* sdhci driver will use the original 8-bit divisor field and
|
||||
* the "base / 2^N" divisor scheme.
|
||||
* The i.MX5 ESDHC hardware requires the driver to manually
|
||||
* start and stop the sd bus clock. If the enable bit is not
|
||||
* set, turn off the clock in hardware and we're done, otherwise
|
||||
* decode the requested frequency. ESDHC hardware is sdhci 2.0;
|
||||
* the sdhci driver will use the original 8-bit divisor field
|
||||
* and the "base / 2^N" divisor scheme.
|
||||
*/
|
||||
if ((val & SDHCI_CLOCK_CARD_EN) == 0) {
|
||||
#ifdef __arm__
|
||||
/* On QorIQ, this is a reserved bit. */
|
||||
WR4(sc, SDHCI_CLOCK_CONTROL, val32 & ~SDHC_CLK_SDCLKEN);
|
||||
#endif
|
||||
return;
|
||||
|
||||
}
|
||||
@ -625,6 +639,7 @@ fsl_sdhc_set_clock(struct fsl_sdhci_softc *sc, uint16_t val)
|
||||
val32 &= ~(SDHC_CLK_DIVISOR_MASK | SDHC_CLK_PRESCALE_MASK);
|
||||
val32 |= divisor << SDHC_CLK_DIVISOR_SHIFT;
|
||||
val32 |= prescale << SDHC_CLK_PRESCALE_SHIFT;
|
||||
val32 |= SDHC_CLK_IPGEN;
|
||||
WR4(sc, SDHCI_CLOCK_CONTROL, val32);
|
||||
}
|
||||
|
||||
@ -710,10 +725,10 @@ fsl_sdhci_intr(void *arg)
|
||||
*/
|
||||
switch (sc->r1bfix_type) {
|
||||
case R1BFIX_NODATA:
|
||||
intmask = RD4(sc, SDHC_INT_STATUS) & SDHCI_INT_RESPONSE;
|
||||
intmask = RD4(sc, SDHCI_INT_STATUS) & SDHCI_INT_RESPONSE;
|
||||
break;
|
||||
case R1BFIX_AC12:
|
||||
intmask = RD4(sc, SDHC_INT_STATUS) & SDHCI_INT_DATA_END;
|
||||
intmask = RD4(sc, SDHCI_INT_STATUS) & SDHCI_INT_DATA_END;
|
||||
break;
|
||||
default:
|
||||
intmask = 0;
|
||||
@ -722,8 +737,8 @@ fsl_sdhci_intr(void *arg)
|
||||
if (intmask) {
|
||||
sc->r1bfix_timeout_at = getsbinuptime() + 250 * SBT_1MS;
|
||||
if (!fsl_sdhci_r1bfix_is_wait_done(sc)) {
|
||||
WR4(sc, SDHC_INT_STATUS, intmask);
|
||||
bus_barrier(sc->mem_res, SDHC_INT_STATUS, 4,
|
||||
WR4(sc, SDHCI_INT_STATUS, intmask);
|
||||
bus_barrier(sc->mem_res, SDHCI_INT_STATUS, 4,
|
||||
BUS_SPACE_BARRIER_WRITE);
|
||||
}
|
||||
}
|
||||
@ -735,10 +750,54 @@ fsl_sdhci_intr(void *arg)
|
||||
static int
|
||||
fsl_sdhci_get_ro(device_t bus, device_t child)
|
||||
{
|
||||
struct fsl_sdhci_softc *sc = device_get_softc(bus);
|
||||
|
||||
return (false);
|
||||
if (RD4(sc, SDHCI_PRESENT_STATE) & SDHC_PRES_WPSPL)
|
||||
return (false);
|
||||
return (true);
|
||||
}
|
||||
|
||||
#ifdef __powerpc__
|
||||
static uint32_t
|
||||
fsl_sdhci_get_platform_clock(device_t dev)
|
||||
{
|
||||
device_t parent;
|
||||
phandle_t node;
|
||||
uint32_t clock;
|
||||
|
||||
node = ofw_bus_get_node(dev);
|
||||
|
||||
/* Get sdhci node properties */
|
||||
if((OF_getprop(node, "clock-frequency", (void *)&clock,
|
||||
sizeof(clock)) <= 0) || (clock == 0)) {
|
||||
|
||||
/*
|
||||
* Trying to get clock from parent device (soc) if correct
|
||||
* clock cannot be acquired from sdhci node.
|
||||
*/
|
||||
parent = device_get_parent(dev);
|
||||
node = ofw_bus_get_node(parent);
|
||||
|
||||
/* Get soc properties */
|
||||
if ((OF_getprop(node, "bus-frequency", (void *)&clock,
|
||||
sizeof(clock)) <= 0) || (clock == 0)) {
|
||||
device_printf(dev,"Cannot acquire correct sdhci "
|
||||
"frequency from DTS.\n");
|
||||
|
||||
return (0);
|
||||
}
|
||||
/* eSDHC clock is 1/2 platform clock. */
|
||||
clock /= 2;
|
||||
}
|
||||
|
||||
if (bootverbose)
|
||||
device_printf(dev, "Acquired clock: %d from DTS\n", clock);
|
||||
|
||||
return (clock);
|
||||
}
|
||||
#endif
|
||||
|
||||
|
||||
static int
|
||||
fsl_sdhci_detach(device_t dev)
|
||||
{
|
||||
@ -752,6 +811,7 @@ fsl_sdhci_attach(device_t dev)
|
||||
struct fsl_sdhci_softc *sc = device_get_softc(dev);
|
||||
int rid, err;
|
||||
phandle_t node;
|
||||
uint32_t protctl;
|
||||
|
||||
sc->dev = dev;
|
||||
|
||||
@ -807,9 +867,23 @@ fsl_sdhci_attach(device_t dev)
|
||||
*
|
||||
* XXX need named constants for this stuff.
|
||||
*/
|
||||
WR4(sc, SDHC_WTMK_LVL, 0x08800880);
|
||||
#ifdef __powerpc__
|
||||
/* P1022 has the '*_BRST_LEN' fields as reserved, always reading 0x10 */
|
||||
if ((SVR_VER(mfspr(SPR_SVR)) & 0xfff6) == SVR_P1022 )
|
||||
WR4(sc, SDHC_WTMK_LVL, 0x10801080);
|
||||
else
|
||||
#endif
|
||||
WR4(sc, SDHC_WTMK_LVL, 0x08800880);
|
||||
|
||||
/*
|
||||
* We read in native byte order in the main driver, but the register
|
||||
* defaults to little endian.
|
||||
*/
|
||||
#ifdef __powerpc__
|
||||
sc->baseclk_hz = fsl_sdhci_get_platform_clock(dev);
|
||||
#else
|
||||
sc->baseclk_hz = imx_ccm_sdhci_hz();
|
||||
#endif
|
||||
sc->slot.max_clk = sc->baseclk_hz;
|
||||
|
||||
/*
|
||||
@ -830,6 +904,16 @@ fsl_sdhci_attach(device_t dev)
|
||||
/* XXX put real gpio hookup here. */
|
||||
sc->force_card_present = true;
|
||||
}
|
||||
#ifdef __powerpc__
|
||||
/* Default to big-endian on powerpc */
|
||||
protctl = RD4(sc, SDHC_PROT_CTRL);
|
||||
protctl &= ~SDHC_PROT_EMODE_MASK;
|
||||
if (OF_hasprop(node, "little-endian"))
|
||||
protctl |= SDHC_PROT_EMODE_LITTLE;
|
||||
else
|
||||
protctl |= SDHC_PROT_EMODE_BIG;
|
||||
WR4(sc, SDHC_PROT_CTRL, protctl);
|
||||
#endif
|
||||
|
||||
callout_init(&sc->r1bfix_callout, 1);
|
||||
sdhci_init_slot(dev, &sc->slot, 0);
|
||||
|
File diff suppressed because it is too large
Load Diff
@ -1,297 +0,0 @@
|
||||
/*-
|
||||
* Copyright (c) 2011-2012 Semihalf
|
||||
* 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 FSL_SDHC_H_
|
||||
#define FSL_SDHC_H_
|
||||
|
||||
#include <sys/cdefs.h>
|
||||
|
||||
#include <sys/param.h>
|
||||
#include <sys/bus.h>
|
||||
#include <sys/kernel.h>
|
||||
#include <sys/lock.h>
|
||||
#include <sys/module.h>
|
||||
#include <sys/mutex.h>
|
||||
#include <sys/rman.h>
|
||||
#include <sys/sysctl.h>
|
||||
#include <sys/systm.h>
|
||||
#include <sys/taskqueue.h>
|
||||
|
||||
#include <machine/bus.h>
|
||||
|
||||
#include <dev/mmc/bridge.h>
|
||||
#include <dev/mmc/mmcreg.h>
|
||||
#include <dev/mmc/mmcvar.h>
|
||||
#include <dev/mmc/mmcbrvar.h>
|
||||
|
||||
#include "mmcbr_if.h"
|
||||
|
||||
|
||||
/*****************************************************************************
|
||||
* Private defines
|
||||
*****************************************************************************/
|
||||
struct slot {
|
||||
uint32_t clock;
|
||||
};
|
||||
|
||||
struct fsl_sdhc_softc {
|
||||
device_t self;
|
||||
device_t child;
|
||||
|
||||
bus_space_handle_t bsh;
|
||||
bus_space_tag_t bst;
|
||||
|
||||
struct resource *mem_resource;
|
||||
int mem_rid;
|
||||
struct resource *irq_resource;
|
||||
int irq_rid;
|
||||
void *ihl;
|
||||
|
||||
bus_dma_tag_t dma_tag;
|
||||
bus_dmamap_t dma_map;
|
||||
uint32_t* dma_mem;
|
||||
bus_addr_t dma_phys;
|
||||
|
||||
struct mtx mtx;
|
||||
|
||||
struct task card_detect_task;
|
||||
struct callout card_detect_callout;
|
||||
|
||||
struct mmc_host mmc_host;
|
||||
|
||||
struct slot slot;
|
||||
uint32_t bus_busy;
|
||||
uint32_t platform_clock;
|
||||
|
||||
struct mmc_request *request;
|
||||
int data_done;
|
||||
int command_done;
|
||||
int use_dma;
|
||||
uint32_t* data_ptr;
|
||||
uint32_t data_offset;
|
||||
};
|
||||
|
||||
#define FSL_SDHC_RESET_DELAY 50
|
||||
|
||||
#define FSL_SDHC_BASE_CLOCK_DIV (2)
|
||||
#define FSL_SDHC_MAX_DIV (FSL_SDHC_BASE_CLOCK_DIV * 256 * 16)
|
||||
#define FSL_SDHC_MIN_DIV (FSL_SDHC_BASE_CLOCK_DIV * 2)
|
||||
#define FSL_SDHC_MAX_CLOCK (50000000)
|
||||
|
||||
#define FSL_SDHC_MAX_BLOCK_COUNT (65535)
|
||||
#define FSL_SDHC_MAX_BLOCK_SIZE (4096)
|
||||
|
||||
#define FSL_SDHC_FIFO_BUF_SIZE (64) /* Water-mark level. */
|
||||
#define FSL_SDHC_FIFO_BUF_WORDS (FSL_SDHC_FIFO_BUF_SIZE / 4)
|
||||
|
||||
#define FSL_SDHC_DMA_SEGMENT_SIZE (1024)
|
||||
#define FSL_SDHC_DMA_ALIGNMENT (4)
|
||||
#define FSL_SDHC_DMA_BLOCK_SIZE FSL_SDHC_MAX_BLOCK_SIZE
|
||||
|
||||
|
||||
/*
|
||||
* Offsets of SD HC registers
|
||||
*/
|
||||
enum sdhc_reg_off {
|
||||
SDHC_DSADDR = 0x000,
|
||||
SDHC_BLKATTR = 0x004,
|
||||
SDHC_CMDARG = 0x008,
|
||||
SDHC_XFERTYP = 0x00c,
|
||||
SDHC_CMDRSP0 = 0x010,
|
||||
SDHC_CMDRSP1 = 0x014,
|
||||
SDHC_CMDRSP2 = 0x018,
|
||||
SDHC_CMDRSP3 = 0x01c,
|
||||
SDHC_DATPORT = 0x020,
|
||||
SDHC_PRSSTAT = 0x024,
|
||||
SDHC_PROCTL = 0x028,
|
||||
SDHC_SYSCTL = 0x02c,
|
||||
SDHC_IRQSTAT = 0x030,
|
||||
SDHC_IRQSTATEN = 0x034,
|
||||
SDHC_IRQSIGEN = 0x038,
|
||||
SDHC_AUTOC12ERR = 0x03c,
|
||||
SDHC_HOSTCAPBLT = 0x040,
|
||||
SDHC_WML = 0x044,
|
||||
SDHC_FEVT = 0x050,
|
||||
SDHC_HOSTVER = 0x0fc,
|
||||
SDHC_DCR = 0x40c
|
||||
};
|
||||
|
||||
enum sysctl_bit {
|
||||
SYSCTL_INITA = 0x08000000,
|
||||
SYSCTL_RSTD = 0x04000000,
|
||||
SYSCTL_RSTC = 0x02000000,
|
||||
SYSCTL_RSTA = 0x01000000,
|
||||
SYSCTL_DTOCV = 0x000f0000,
|
||||
SYSCTL_SDCLKFS = 0x0000ff00,
|
||||
SYSCTL_DVS = 0x000000f0,
|
||||
SYSCTL_PEREN = 0x00000004,
|
||||
SYSCTL_HCKEN = 0x00000002,
|
||||
SYSCTL_IPGEN = 0x00000001
|
||||
};
|
||||
|
||||
#define HEX_LEFT_SHIFT(x) (4 * x)
|
||||
enum sysctl_shift {
|
||||
SHIFT_DTOCV = HEX_LEFT_SHIFT(4),
|
||||
SHIFT_SDCLKFS = HEX_LEFT_SHIFT(2),
|
||||
SHIFT_DVS = HEX_LEFT_SHIFT(1)
|
||||
};
|
||||
|
||||
enum proctl_bit {
|
||||
PROCTL_WECRM = 0x04000000,
|
||||
PROCTL_WECINS = 0x02000000,
|
||||
PROCTL_WECINT = 0x01000000,
|
||||
PROCTL_RWCTL = 0x00040000,
|
||||
PROCTL_CREQ = 0x00020000,
|
||||
PROCTL_SABGREQ = 0x00010000,
|
||||
PROCTL_CDSS = 0x00000080,
|
||||
PROCTL_CDTL = 0x00000040,
|
||||
PROCTL_EMODE = 0x00000030,
|
||||
PROCTL_D3CD = 0x00000008,
|
||||
PROCTL_DTW = 0x00000006
|
||||
};
|
||||
|
||||
enum dtw {
|
||||
DTW_1 = 0x00000000,
|
||||
DTW_4 = 0x00000002,
|
||||
DTW_8 = 0x00000004
|
||||
};
|
||||
|
||||
enum prsstat_bit {
|
||||
PRSSTAT_DLSL = 0xff000000,
|
||||
PRSSTAT_CLSL = 0x00800000,
|
||||
PRSSTAT_WPSPL = 0x00080000,
|
||||
PRSSTAT_CDPL = 0x00040000,
|
||||
PRSSTAT_CINS = 0x00010000,
|
||||
PRSSTAT_BREN = 0x00000800,
|
||||
PRSSTAT_BWEN = 0x00000400,
|
||||
PRSSTAT_RTA = 0x00000200,
|
||||
PRSSTAT_WTA = 0x00000100,
|
||||
PRSSTAT_SDOFF = 0x00000080,
|
||||
PRSSTAT_PEROFF = 0x00000040,
|
||||
PRSSTAT_HCKOFF = 0x00000020,
|
||||
PRSSTAT_IPGOFF = 0x00000010,
|
||||
PRSSTAT_DLA = 0x00000004,
|
||||
PRSSTAT_CDIHB = 0x00000002,
|
||||
PRSSTAT_CIHB = 0x00000001
|
||||
|
||||
};
|
||||
|
||||
enum irq_bits {
|
||||
IRQ_DMAE = 0x10000000,
|
||||
IRQ_AC12E = 0x01000000,
|
||||
IRQ_DEBE = 0x00400000,
|
||||
IRQ_DCE = 0x00200000,
|
||||
IRQ_DTOE = 0x00100000,
|
||||
IRQ_CIE = 0x00080000,
|
||||
IRQ_CEBE = 0x00040000,
|
||||
IRQ_CCE = 0x00020000,
|
||||
IRQ_CTOE = 0x00010000,
|
||||
IRQ_CINT = 0x00000100,
|
||||
IRQ_CRM = 0x00000080,
|
||||
IRQ_CINS = 0x00000040,
|
||||
IRQ_BRR = 0x00000020,
|
||||
IRQ_BWR = 0x00000010,
|
||||
IRQ_DINT = 0x00000008,
|
||||
IRQ_BGE = 0x00000004,
|
||||
IRQ_TC = 0x00000002,
|
||||
IRQ_CC = 0x00000001
|
||||
};
|
||||
|
||||
enum irq_masks {
|
||||
IRQ_ERROR_DATA_MASK = IRQ_DMAE | IRQ_DEBE | IRQ_DCE | IRQ_DTOE,
|
||||
IRQ_ERROR_CMD_MASK = IRQ_AC12E | IRQ_CIE | IRQ_CTOE | IRQ_CCE |
|
||||
IRQ_CEBE
|
||||
};
|
||||
|
||||
enum dcr_bits {
|
||||
DCR_PRI = 0x0000c000,
|
||||
DCR_SNOOP = 0x00000040,
|
||||
DCR_AHB2MAG_BYPASS = 0x00000020,
|
||||
DCR_RD_SAFE = 0x00000004,
|
||||
DCR_RD_PFE = 0x00000002,
|
||||
DCR_RD_PF_SIZE = 0x00000001
|
||||
};
|
||||
|
||||
#define DCR_PRI_SHIFT (14)
|
||||
|
||||
enum xfertyp_bits {
|
||||
XFERTYP_CMDINX = 0x3f000000,
|
||||
XFERTYP_CMDTYP = 0x00c00000,
|
||||
XFERTYP_DPSEL = 0x00200000,
|
||||
XFERTYP_CICEN = 0x00100000,
|
||||
XFERTYP_CCCEN = 0x00080000,
|
||||
XFERTYP_RSPTYP = 0x00030000,
|
||||
XFERTYP_MSBSEL = 0x00000020,
|
||||
XFERTYP_DTDSEL = 0x00000010,
|
||||
XFERTYP_AC12EN = 0x00000004,
|
||||
XFERTYP_BCEN = 0x00000002,
|
||||
XFERTYP_DMAEN = 0x00000001
|
||||
};
|
||||
|
||||
#define CMDINX_SHIFT (24)
|
||||
|
||||
enum xfertyp_cmdtyp {
|
||||
CMDTYP_NORMAL = 0x00000000,
|
||||
CMDYTP_SUSPEND = 0x00400000,
|
||||
CMDTYP_RESUME = 0x00800000,
|
||||
CMDTYP_ABORT = 0x00c00000
|
||||
};
|
||||
|
||||
enum xfertyp_rsptyp {
|
||||
RSPTYP_NONE = 0x00000000,
|
||||
RSPTYP_136 = 0x00010000,
|
||||
RSPTYP_48 = 0x00020000,
|
||||
RSPTYP_48_BUSY = 0x00030000
|
||||
};
|
||||
|
||||
enum blkattr_bits {
|
||||
BLKATTR_BLKSZE = 0x00001fff,
|
||||
BLKATTR_BLKCNT = 0xffff0000
|
||||
};
|
||||
#define BLKATTR_BLOCK_COUNT(x) (x << 16)
|
||||
|
||||
enum wml_bits {
|
||||
WR_WML = 0x00ff0000,
|
||||
RD_WML = 0x000000ff,
|
||||
};
|
||||
|
||||
enum sdhc_bit_mask {
|
||||
MASK_CLOCK_CONTROL = 0x0000ffff,
|
||||
MASK_IRQ_ALL = IRQ_DMAE | IRQ_AC12E | IRQ_DEBE | IRQ_DCE |
|
||||
IRQ_DTOE | IRQ_CIE | IRQ_CEBE | IRQ_CCE |
|
||||
IRQ_CTOE | IRQ_CINT | IRQ_CRM | IRQ_CINS |
|
||||
IRQ_BRR | IRQ_BWR | IRQ_DINT | IRQ_BGE |
|
||||
IRQ_TC | IRQ_CC,
|
||||
};
|
||||
|
||||
enum sdhc_line {
|
||||
SDHC_DAT_LINE = 0x2,
|
||||
SDHC_CMD_LINE = 0x1
|
||||
};
|
||||
|
||||
#endif /* FSL_SDHC_H_ */
|
Loading…
Reference in New Issue
Block a user