Changeset View
Changeset View
Standalone View
Standalone View
sys/dev/sdhci/sdhci_fsl_fdt.c
Show First 20 Lines • Show All 64 Lines • ▼ Show 20 Lines | |||||
#define SDHCI_FSL_PROT_CTRL_WIDTH_1BIT (0 << 1) | #define SDHCI_FSL_PROT_CTRL_WIDTH_1BIT (0 << 1) | ||||
#define SDHCI_FSL_PROT_CTRL_WIDTH_4BIT (1 << 1) | #define SDHCI_FSL_PROT_CTRL_WIDTH_4BIT (1 << 1) | ||||
#define SDHCI_FSL_PROT_CTRL_WIDTH_8BIT (2 << 1) | #define SDHCI_FSL_PROT_CTRL_WIDTH_8BIT (2 << 1) | ||||
#define SDHCI_FSL_PROT_CTRL_WIDTH_MASK (3 << 1) | #define SDHCI_FSL_PROT_CTRL_WIDTH_MASK (3 << 1) | ||||
#define SDHCI_FSL_PROT_CTRL_BYTE_SWAP (0 << 4) | #define SDHCI_FSL_PROT_CTRL_BYTE_SWAP (0 << 4) | ||||
#define SDHCI_FSL_PROT_CTRL_BYTE_NATIVE (2 << 4) | #define SDHCI_FSL_PROT_CTRL_BYTE_NATIVE (2 << 4) | ||||
#define SDHCI_FSL_PROT_CTRL_BYTE_MASK (3 << 4) | #define SDHCI_FSL_PROT_CTRL_BYTE_MASK (3 << 4) | ||||
#define SDHCI_FSL_PROT_CTRL_DMA_MASK (3 << 8) | #define SDHCI_FSL_PROT_CTRL_DMA_MASK (3 << 8) | ||||
#define SDHCI_FSL_PROT_CTRL_VOLT_SEL (1 << 10) | |||||
#define SDHCI_FSL_SYS_CTRL 0x2c | #define SDHCI_FSL_SYS_CTRL 0x2c | ||||
#define SDHCI_FSL_CLK_IPGEN (1 << 0) | #define SDHCI_FSL_CLK_IPGEN (1 << 0) | ||||
#define SDHCI_FSL_CLK_SDCLKEN (1 << 3) | #define SDHCI_FSL_CLK_SDCLKEN (1 << 3) | ||||
#define SDHCI_FSL_CLK_DIVIDER_MASK 0x000000f0 | #define SDHCI_FSL_CLK_DIVIDER_MASK 0x000000f0 | ||||
#define SDHCI_FSL_CLK_DIVIDER_SHIFT 4 | #define SDHCI_FSL_CLK_DIVIDER_SHIFT 4 | ||||
#define SDHCI_FSL_CLK_PRESCALE_MASK 0x0000ff00 | #define SDHCI_FSL_CLK_PRESCALE_MASK 0x0000ff00 | ||||
#define SDHCI_FSL_CLK_PRESCALE_SHIFT 8 | #define SDHCI_FSL_CLK_PRESCALE_SHIFT 8 | ||||
Show All 16 Lines | |||||
#define SDHCI_FSL_ESDHC_CTRL_SNOOP (1 << 6) | #define SDHCI_FSL_ESDHC_CTRL_SNOOP (1 << 6) | ||||
#define SDHCI_FSL_ESDHC_CTRL_CLK_DIV2 (1 << 19) | #define SDHCI_FSL_ESDHC_CTRL_CLK_DIV2 (1 << 19) | ||||
#define SDHCI_FSL_CAN_VDD_MASK \ | #define SDHCI_FSL_CAN_VDD_MASK \ | ||||
(SDHCI_CAN_VDD_180 | SDHCI_CAN_VDD_300 | SDHCI_CAN_VDD_330) | (SDHCI_CAN_VDD_180 | SDHCI_CAN_VDD_300 | SDHCI_CAN_VDD_330) | ||||
/* Some platforms do not detect pulse width correctly. */ | /* Some platforms do not detect pulse width correctly. */ | ||||
#define SDHCI_FSL_UNRELIABLE_PULSE_DET (1 << 0) | #define SDHCI_FSL_UNRELIABLE_PULSE_DET (1 << 0) | ||||
/* On some platforms switching voltage to 1.8V is not supported */ | |||||
#define SDHCI_FSL_UNSUPP_1_8V (1 << 1) | |||||
struct sdhci_fsl_fdt_softc { | struct sdhci_fsl_fdt_softc { | ||||
device_t dev; | device_t dev; | ||||
const struct sdhci_fsl_fdt_soc_data *soc_data; | const struct sdhci_fsl_fdt_soc_data *soc_data; | ||||
struct resource *mem_res; | struct resource *mem_res; | ||||
struct resource *irq_res; | struct resource *irq_res; | ||||
void *irq_cookie; | void *irq_cookie; | ||||
uint32_t baseclk_hz; | uint32_t baseclk_hz; | ||||
Show All 14 Lines | struct sdhci_fsl_fdt_soc_data { | ||||
int quirks; | int quirks; | ||||
int baseclk_div; | int baseclk_div; | ||||
uint8_t errata; | uint8_t errata; | ||||
}; | }; | ||||
static const struct sdhci_fsl_fdt_soc_data sdhci_fsl_fdt_ls1012a_soc_data = { | static const struct sdhci_fsl_fdt_soc_data sdhci_fsl_fdt_ls1012a_soc_data = { | ||||
.quirks = 0, | .quirks = 0, | ||||
.baseclk_div = 1, | .baseclk_div = 1, | ||||
.errata = 0 | .errata = SDHCI_FSL_UNSUPP_1_8V, | ||||
}; | }; | ||||
static const struct sdhci_fsl_fdt_soc_data sdhci_fsl_fdt_ls1028a_soc_data = { | static const struct sdhci_fsl_fdt_soc_data sdhci_fsl_fdt_ls1028a_soc_data = { | ||||
.quirks = SDHCI_QUIRK_DONT_SET_HISPD_BIT | | .quirks = SDHCI_QUIRK_DONT_SET_HISPD_BIT | | ||||
SDHCI_QUIRK_BROKEN_AUTO_STOP | SDHCI_QUIRK_DATA_TIMEOUT_USES_SDCLK, | SDHCI_QUIRK_BROKEN_AUTO_STOP | SDHCI_QUIRK_DATA_TIMEOUT_USES_SDCLK, | ||||
.baseclk_div = 2, | .baseclk_div = 2, | ||||
.errata = SDHCI_FSL_UNRELIABLE_PULSE_DET, | .errata = SDHCI_FSL_UNRELIABLE_PULSE_DET, | ||||
}; | }; | ||||
static const struct sdhci_fsl_fdt_soc_data sdhci_fsl_fdt_ls1046a_soc_data = { | static const struct sdhci_fsl_fdt_soc_data sdhci_fsl_fdt_ls1046a_soc_data = { | ||||
.quirks = SDHCI_QUIRK_DONT_SET_HISPD_BIT | SDHCI_QUIRK_BROKEN_AUTO_STOP, | .quirks = SDHCI_QUIRK_DONT_SET_HISPD_BIT | SDHCI_QUIRK_BROKEN_AUTO_STOP, | ||||
.baseclk_div = 2, | .baseclk_div = 2, | ||||
.errata = SDHCI_FSL_UNSUPP_1_8V, | |||||
}; | }; | ||||
static const struct sdhci_fsl_fdt_soc_data sdhci_fsl_fdt_gen_data = { | static const struct sdhci_fsl_fdt_soc_data sdhci_fsl_fdt_gen_data = { | ||||
.quirks = 0, | .quirks = 0, | ||||
.baseclk_div = 1, | .baseclk_div = 1, | ||||
}; | }; | ||||
static const struct ofw_compat_data sdhci_fsl_fdt_compat_data[] = { | static const struct ofw_compat_data sdhci_fsl_fdt_compat_data[] = { | ||||
▲ Show 20 Lines • Show All 356 Lines • ▼ Show 20 Lines | sdhci_fsl_fdt_update_ios(device_t brdev, device_t reqdev) | ||||
return (0); | return (0); | ||||
} | } | ||||
static int | static int | ||||
sdhci_fsl_fdt_switch_vccq(device_t brdev, device_t reqdev) | sdhci_fsl_fdt_switch_vccq(device_t brdev, device_t reqdev) | ||||
{ | { | ||||
struct sdhci_fsl_fdt_softc *sc; | struct sdhci_fsl_fdt_softc *sc; | ||||
struct sdhci_slot *slot; | struct sdhci_slot *slot; | ||||
regulator_t vqmmc_supply; | |||||
manu: You don't need this variable. | |||||
uint32_t val_old, val; | |||||
int uvolt, err; | int uvolt, err; | ||||
sc = device_get_softc(brdev); | sc = device_get_softc(brdev); | ||||
slot = device_get_ivars(reqdev); | |||||
if (sc->fdt_helper.vqmmc_supply == NULL) | val_old = val = RD4(sc, SDHCI_FSL_PROT_CTRL); | ||||
return EOPNOTSUPP; | |||||
err = sdhci_generic_switch_vccq(brdev, reqdev); | |||||
if (err != 0) | |||||
return (err); | |||||
slot = device_get_ivars(reqdev); | |||||
switch (slot->host.ios.vccq) { | switch (slot->host.ios.vccq) { | ||||
case vccq_180: | case vccq_180: | ||||
if (sc->soc_data->errata & SDHCI_FSL_UNSUPP_1_8V) | |||||
return (EOPNOTSUPP); | |||||
val |= SDHCI_FSL_PROT_CTRL_VOLT_SEL; | |||||
uvolt = 1800000; | uvolt = 1800000; | ||||
break; | break; | ||||
case vccq_330: | case vccq_330: | ||||
val &= ~SDHCI_FSL_PROT_CTRL_VOLT_SEL; | |||||
uvolt = 3300000; | uvolt = 3300000; | ||||
break; | break; | ||||
default: | default: | ||||
return EINVAL; | return (EOPNOTSUPP); | ||||
} | } | ||||
err = regulator_set_voltage(sc->fdt_helper.vqmmc_supply, uvolt, uvolt); | WR4(sc, SDHCI_FSL_PROT_CTRL, val); | ||||
vqmmc_supply = sc->fdt_helper.vqmmc_supply; | |||||
/* | |||||
* Even though we expect to find a fixed regulator in this controller | |||||
* family, let's play safe. | |||||
*/ | |||||
if (vqmmc_supply != NULL) { | |||||
err = regulator_set_voltage(vqmmc_supply, uvolt, uvolt); | |||||
if (err != 0) { | if (err != 0) { | ||||
device_printf(sc->dev, | device_printf(sc->dev, | ||||
"Cannot set vqmmc to %d<->%d\n", uvolt, uvolt); | "Cannot set vqmmc to %d<->%d\n", uvolt, uvolt); | ||||
WR4(sc, SDHCI_FSL_PROT_CTRL, val_old); | |||||
return (err); | return (err); | ||||
} | |||||
} | } | ||||
return (0); | return (0); | ||||
} | } | ||||
static int | static int | ||||
sdhci_fsl_fdt_get_ro(device_t bus, device_t child) | sdhci_fsl_fdt_get_ro(device_t bus, device_t child) | ||||
{ | { | ||||
▲ Show 20 Lines • Show All 382 Lines • Show Last 20 Lines |
You don't need this variable.