Skip to content

Commit 36c6aad

Browse files
wanahmadzainiestorulf
authored andcommitted
mmc: sdhci-of-arasan: Add support for Intel Keem Bay
Intel Keem Bay SoC eMMC/SD/SDIO controller is based on Arasan SD 3.0 / eMMC 5.1 host controller IP. However, it does not support 64-bit access as its AXI interface has 32-bit address ports. Signed-off-by: Wan Ahmad Zainie <[email protected]> Reviewed-by: Adrian Hunter <[email protected]> Link: https://lore.kernel.org/r/[email protected] Signed-off-by: Ulf Hansson <[email protected]>
1 parent ce3fefa commit 36c6aad

File tree

1 file changed

+123
-0
lines changed

1 file changed

+123
-0
lines changed

drivers/mmc/host/sdhci-of-arasan.c

Lines changed: 123 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -75,6 +75,7 @@ struct sdhci_arasan_soc_ctl_field {
7575
*
7676
* @baseclkfreq: Where to find corecfg_baseclkfreq
7777
* @clockmultiplier: Where to find corecfg_clockmultiplier
78+
* @support64b: Where to find SUPPORT64B bit
7879
* @hiword_update: If true, use HIWORD_UPDATE to access the syscon
7980
*
8081
* It's up to the licensee of the Arsan IP block to make these available
@@ -84,6 +85,7 @@ struct sdhci_arasan_soc_ctl_field {
8485
struct sdhci_arasan_soc_ctl_map {
8586
struct sdhci_arasan_soc_ctl_field baseclkfreq;
8687
struct sdhci_arasan_soc_ctl_field clockmultiplier;
88+
struct sdhci_arasan_soc_ctl_field support64b;
8789
bool hiword_update;
8890
};
8991

@@ -184,6 +186,13 @@ static const struct sdhci_arasan_soc_ctl_map intel_lgm_sdxc_soc_ctl_map = {
184186
.hiword_update = false,
185187
};
186188

189+
static const struct sdhci_arasan_soc_ctl_map intel_keembay_soc_ctl_map = {
190+
.baseclkfreq = { .reg = 0x0, .width = 8, .shift = 14 },
191+
.clockmultiplier = { .reg = 0x4, .width = 8, .shift = 14 },
192+
.support64b = { .reg = 0x4, .width = 1, .shift = 24 },
193+
.hiword_update = false,
194+
};
195+
187196
/**
188197
* sdhci_arasan_syscon_write - Write to a field in soc_ctl registers
189198
*
@@ -1113,6 +1122,50 @@ static struct sdhci_arasan_of_data sdhci_arasan_generic_data = {
11131122
.clk_ops = &arasan_clk_ops,
11141123
};
11151124

1125+
static const struct sdhci_pltfm_data sdhci_keembay_emmc_pdata = {
1126+
.ops = &sdhci_arasan_cqe_ops,
1127+
.quirks = SDHCI_QUIRK_CAP_CLOCK_BASE_BROKEN |
1128+
SDHCI_QUIRK_NO_ENDATTR_IN_NOPDESC |
1129+
SDHCI_QUIRK_NO_LED |
1130+
SDHCI_QUIRK_32BIT_DMA_ADDR |
1131+
SDHCI_QUIRK_32BIT_DMA_SIZE |
1132+
SDHCI_QUIRK_32BIT_ADMA_SIZE,
1133+
.quirks2 = SDHCI_QUIRK2_PRESET_VALUE_BROKEN |
1134+
SDHCI_QUIRK2_CLOCK_DIV_ZERO_BROKEN |
1135+
SDHCI_QUIRK2_CAPS_BIT63_FOR_HS400 |
1136+
SDHCI_QUIRK2_STOP_WITH_TC |
1137+
SDHCI_QUIRK2_BROKEN_64_BIT_DMA,
1138+
};
1139+
1140+
static const struct sdhci_pltfm_data sdhci_keembay_sd_pdata = {
1141+
.ops = &sdhci_arasan_ops,
1142+
.quirks = SDHCI_QUIRK_CAP_CLOCK_BASE_BROKEN |
1143+
SDHCI_QUIRK_NO_ENDATTR_IN_NOPDESC |
1144+
SDHCI_QUIRK_NO_LED |
1145+
SDHCI_QUIRK_32BIT_DMA_ADDR |
1146+
SDHCI_QUIRK_32BIT_DMA_SIZE |
1147+
SDHCI_QUIRK_32BIT_ADMA_SIZE,
1148+
.quirks2 = SDHCI_QUIRK2_PRESET_VALUE_BROKEN |
1149+
SDHCI_QUIRK2_CLOCK_DIV_ZERO_BROKEN |
1150+
SDHCI_QUIRK2_CARD_ON_NEEDS_BUS_ON |
1151+
SDHCI_QUIRK2_STOP_WITH_TC |
1152+
SDHCI_QUIRK2_BROKEN_64_BIT_DMA,
1153+
};
1154+
1155+
static const struct sdhci_pltfm_data sdhci_keembay_sdio_pdata = {
1156+
.ops = &sdhci_arasan_ops,
1157+
.quirks = SDHCI_QUIRK_CAP_CLOCK_BASE_BROKEN |
1158+
SDHCI_QUIRK_NO_ENDATTR_IN_NOPDESC |
1159+
SDHCI_QUIRK_NO_LED |
1160+
SDHCI_QUIRK_32BIT_DMA_ADDR |
1161+
SDHCI_QUIRK_32BIT_DMA_SIZE |
1162+
SDHCI_QUIRK_32BIT_ADMA_SIZE,
1163+
.quirks2 = SDHCI_QUIRK2_PRESET_VALUE_BROKEN |
1164+
SDHCI_QUIRK2_CLOCK_DIV_ZERO_BROKEN |
1165+
SDHCI_QUIRK2_HOST_OFF_CARD_ON |
1166+
SDHCI_QUIRK2_BROKEN_64_BIT_DMA,
1167+
};
1168+
11161169
static struct sdhci_arasan_of_data sdhci_arasan_rk3399_data = {
11171170
.soc_ctl_map = &rk3399_soc_ctl_map,
11181171
.pdata = &sdhci_arasan_cqe_pdata,
@@ -1158,6 +1211,21 @@ static struct sdhci_arasan_of_data sdhci_arasan_versal_data = {
11581211
.clk_ops = &versal_clk_ops,
11591212
};
11601213

1214+
static struct sdhci_arasan_of_data intel_keembay_emmc_data = {
1215+
.soc_ctl_map = &intel_keembay_soc_ctl_map,
1216+
.pdata = &sdhci_keembay_emmc_pdata,
1217+
};
1218+
1219+
static struct sdhci_arasan_of_data intel_keembay_sd_data = {
1220+
.soc_ctl_map = &intel_keembay_soc_ctl_map,
1221+
.pdata = &sdhci_keembay_sd_pdata,
1222+
};
1223+
1224+
static struct sdhci_arasan_of_data intel_keembay_sdio_data = {
1225+
.soc_ctl_map = &intel_keembay_soc_ctl_map,
1226+
.pdata = &sdhci_keembay_sdio_pdata,
1227+
};
1228+
11611229
static const struct of_device_id sdhci_arasan_of_match[] = {
11621230
/* SoC-specific compatible strings w/ soc_ctl_map */
11631231
{
@@ -1172,6 +1240,18 @@ static const struct of_device_id sdhci_arasan_of_match[] = {
11721240
.compatible = "intel,lgm-sdhci-5.1-sdxc",
11731241
.data = &intel_lgm_sdxc_data,
11741242
},
1243+
{
1244+
.compatible = "intel,keembay-sdhci-5.1-emmc",
1245+
.data = &intel_keembay_emmc_data,
1246+
},
1247+
{
1248+
.compatible = "intel,keembay-sdhci-5.1-sd",
1249+
.data = &intel_keembay_sd_data,
1250+
},
1251+
{
1252+
.compatible = "intel,keembay-sdhci-5.1-sdio",
1253+
.data = &intel_keembay_sdio_data,
1254+
},
11751255
/* Generic compatible below here */
11761256
{
11771257
.compatible = "arasan,sdhci-8.9a",
@@ -1315,6 +1395,40 @@ static void sdhci_arasan_unregister_sdclk(struct device *dev)
13151395
of_clk_del_provider(dev->of_node);
13161396
}
13171397

1398+
/**
1399+
* sdhci_arasan_update_support64b - Set SUPPORT_64B (64-bit System Bus Support)
1400+
*
1401+
* This should be set based on the System Address Bus.
1402+
* 0: the Core supports only 32-bit System Address Bus.
1403+
* 1: the Core supports 64-bit System Address Bus.
1404+
*
1405+
* NOTES:
1406+
* - For Keem Bay, it is required to clear this bit. Its default value is 1'b1.
1407+
* Keem Bay does not support 64-bit access.
1408+
*
1409+
* @host The sdhci_host
1410+
*/
1411+
static void sdhci_arasan_update_support64b(struct sdhci_host *host, u32 value)
1412+
{
1413+
struct sdhci_pltfm_host *pltfm_host = sdhci_priv(host);
1414+
struct sdhci_arasan_data *sdhci_arasan = sdhci_pltfm_priv(pltfm_host);
1415+
const struct sdhci_arasan_soc_ctl_map *soc_ctl_map =
1416+
sdhci_arasan->soc_ctl_map;
1417+
1418+
/* Having a map is optional */
1419+
if (!soc_ctl_map)
1420+
return;
1421+
1422+
/* If we have a map, we expect to have a syscon */
1423+
if (!sdhci_arasan->soc_ctl_base) {
1424+
pr_warn("%s: Have regmap, but no soc-ctl-syscon\n",
1425+
mmc_hostname(host->mmc));
1426+
return;
1427+
}
1428+
1429+
sdhci_arasan_syscon_write(host, &soc_ctl_map->support64b, value);
1430+
}
1431+
13181432
/**
13191433
* sdhci_arasan_register_sdclk - Register the sdcardclk for a PHY to use
13201434
*
@@ -1487,6 +1601,15 @@ static int sdhci_arasan_probe(struct platform_device *pdev)
14871601
"rockchip,rk3399-sdhci-5.1"))
14881602
sdhci_arasan_update_clockmultiplier(host, 0x0);
14891603

1604+
if (of_device_is_compatible(np, "intel,keembay-sdhci-5.1-emmc") ||
1605+
of_device_is_compatible(np, "intel,keembay-sdhci-5.1-sd") ||
1606+
of_device_is_compatible(np, "intel,keembay-sdhci-5.1-sdio")) {
1607+
sdhci_arasan_update_clockmultiplier(host, 0x0);
1608+
sdhci_arasan_update_support64b(host, 0x0);
1609+
1610+
host->mmc->caps |= MMC_CAP_WAIT_WHILE_BUSY;
1611+
}
1612+
14901613
sdhci_arasan_update_baseclkfreq(host);
14911614

14921615
ret = sdhci_arasan_register_sdclk(sdhci_arasan, clk_xin, &pdev->dev);

0 commit comments

Comments
 (0)