Skip to content

Commit fae80a9

Browse files
bijudasstorulf
authored andcommitted
mmc: renesas_sdhi: Add support for RZ/G3E SoC
The SDHI/eMMC IPs in the RZ/G3E SoC are similar to those in R-Car Gen3. However, the RZ/G3E SD0 channel has Voltage level control and PWEN pin support via SD_STATUS register. internal regulator support is added to control the voltage levels of the SD pins via sd_iovs/sd_pwen bits in SD_STATUS register by populating vqmmc-regulator child node. SD1 and SD2 channels have gpio regulator support and internal regulator support. Selection of the regulator is based on the regulator phandle. Similar case for SD0 fixed voltage (eMMC) that uses fixed regulator and SD0 non-fixed voltage (SD0) that uses internal regulator. Reviewed-by: Wolfram Sang <[email protected]> Signed-off-by: Biju Das <[email protected]> Link: https://lore.kernel.org/r/[email protected] Signed-off-by: Ulf Hansson <[email protected]>
1 parent 9374528 commit fae80a9

File tree

3 files changed

+141
-0
lines changed

3 files changed

+141
-0
lines changed

drivers/mmc/host/renesas_sdhi.h

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -95,6 +95,7 @@ struct renesas_sdhi {
9595

9696
struct reset_control *rstc;
9797
struct tmio_mmc_host *host;
98+
struct regulator_dev *rdev;
9899
};
99100

100101
#define host_to_priv(host) \

drivers/mmc/host/renesas_sdhi_core.c

Lines changed: 130 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -32,6 +32,8 @@
3232
#include <linux/platform_device.h>
3333
#include <linux/pm_domain.h>
3434
#include <linux/regulator/consumer.h>
35+
#include <linux/regulator/driver.h>
36+
#include <linux/regulator/of_regulator.h>
3537
#include <linux/reset.h>
3638
#include <linux/sh_dma.h>
3739
#include <linux/slab.h>
@@ -581,12 +583,24 @@ static void renesas_sdhi_reset(struct tmio_mmc_host *host, bool preserve)
581583

582584
if (!preserve) {
583585
if (priv->rstc) {
586+
u32 sd_status;
587+
/*
588+
* HW reset might have toggled the regulator state in
589+
* HW which regulator core might be unaware of so save
590+
* and restore the regulator state during HW reset.
591+
*/
592+
if (priv->rdev)
593+
sd_status = sd_ctrl_read32(host, CTL_SD_STATUS);
594+
584595
reset_control_reset(priv->rstc);
585596
/* Unknown why but without polling reset status, it will hang */
586597
read_poll_timeout(reset_control_status, ret, ret == 0, 1, 100,
587598
false, priv->rstc);
588599
/* At least SDHI_VER_GEN2_SDR50 needs manual release of reset */
589600
sd_ctrl_write16(host, CTL_RESET_SD, 0x0001);
601+
if (priv->rdev)
602+
sd_ctrl_write32(host, CTL_SD_STATUS, sd_status);
603+
590604
priv->needs_adjust_hs400 = false;
591605
renesas_sdhi_set_clock(host, host->clk_cache);
592606

@@ -904,14 +918,113 @@ static void renesas_sdhi_enable_dma(struct tmio_mmc_host *host, bool enable)
904918
renesas_sdhi_sdbuf_width(host, enable ? width : 16);
905919
}
906920

921+
static const unsigned int renesas_sdhi_vqmmc_voltages[] = {
922+
3300000, 1800000
923+
};
924+
925+
static int renesas_sdhi_regulator_disable(struct regulator_dev *rdev)
926+
{
927+
struct tmio_mmc_host *host = rdev_get_drvdata(rdev);
928+
u32 sd_status;
929+
930+
sd_status = sd_ctrl_read32(host, CTL_SD_STATUS);
931+
sd_status &= ~SD_STATUS_PWEN;
932+
sd_ctrl_write32(host, CTL_SD_STATUS, sd_status);
933+
934+
return 0;
935+
}
936+
937+
static int renesas_sdhi_regulator_enable(struct regulator_dev *rdev)
938+
{
939+
struct tmio_mmc_host *host = rdev_get_drvdata(rdev);
940+
u32 sd_status;
941+
942+
sd_status = sd_ctrl_read32(host, CTL_SD_STATUS);
943+
sd_status |= SD_STATUS_PWEN;
944+
sd_ctrl_write32(host, CTL_SD_STATUS, sd_status);
945+
946+
return 0;
947+
}
948+
949+
static int renesas_sdhi_regulator_is_enabled(struct regulator_dev *rdev)
950+
{
951+
struct tmio_mmc_host *host = rdev_get_drvdata(rdev);
952+
u32 sd_status;
953+
954+
sd_status = sd_ctrl_read32(host, CTL_SD_STATUS);
955+
956+
return (sd_status & SD_STATUS_PWEN) ? 1 : 0;
957+
}
958+
959+
static int renesas_sdhi_regulator_get_voltage(struct regulator_dev *rdev)
960+
{
961+
struct tmio_mmc_host *host = rdev_get_drvdata(rdev);
962+
u32 sd_status;
963+
964+
sd_status = sd_ctrl_read32(host, CTL_SD_STATUS);
965+
966+
return (sd_status & SD_STATUS_IOVS) ? 1800000 : 3300000;
967+
}
968+
969+
static int renesas_sdhi_regulator_set_voltage(struct regulator_dev *rdev,
970+
int min_uV, int max_uV,
971+
unsigned int *selector)
972+
{
973+
struct tmio_mmc_host *host = rdev_get_drvdata(rdev);
974+
u32 sd_status;
975+
976+
sd_status = sd_ctrl_read32(host, CTL_SD_STATUS);
977+
if (min_uV >= 1700000 && max_uV <= 1950000) {
978+
sd_status |= SD_STATUS_IOVS;
979+
*selector = 1;
980+
} else {
981+
sd_status &= ~SD_STATUS_IOVS;
982+
*selector = 0;
983+
}
984+
sd_ctrl_write32(host, CTL_SD_STATUS, sd_status);
985+
986+
return 0;
987+
}
988+
989+
static int renesas_sdhi_regulator_list_voltage(struct regulator_dev *rdev,
990+
unsigned int selector)
991+
{
992+
if (selector >= ARRAY_SIZE(renesas_sdhi_vqmmc_voltages))
993+
return -EINVAL;
994+
995+
return renesas_sdhi_vqmmc_voltages[selector];
996+
}
997+
998+
static const struct regulator_ops renesas_sdhi_regulator_voltage_ops = {
999+
.enable = renesas_sdhi_regulator_enable,
1000+
.disable = renesas_sdhi_regulator_disable,
1001+
.is_enabled = renesas_sdhi_regulator_is_enabled,
1002+
.list_voltage = renesas_sdhi_regulator_list_voltage,
1003+
.get_voltage = renesas_sdhi_regulator_get_voltage,
1004+
.set_voltage = renesas_sdhi_regulator_set_voltage,
1005+
};
1006+
1007+
static const struct regulator_desc renesas_sdhi_vqmmc_regulator = {
1008+
.name = "sdhi-vqmmc-regulator",
1009+
.of_match = of_match_ptr("vqmmc-regulator"),
1010+
.type = REGULATOR_VOLTAGE,
1011+
.owner = THIS_MODULE,
1012+
.ops = &renesas_sdhi_regulator_voltage_ops,
1013+
.volt_table = renesas_sdhi_vqmmc_voltages,
1014+
.n_voltages = ARRAY_SIZE(renesas_sdhi_vqmmc_voltages),
1015+
};
1016+
9071017
int renesas_sdhi_probe(struct platform_device *pdev,
9081018
const struct tmio_mmc_dma_ops *dma_ops,
9091019
const struct renesas_sdhi_of_data *of_data,
9101020
const struct renesas_sdhi_quirks *quirks)
9111021
{
9121022
struct tmio_mmc_data *mmd = pdev->dev.platform_data;
9131023
struct tmio_mmc_data *mmc_data;
1024+
struct regulator_config rcfg = { .dev = &pdev->dev, };
1025+
struct regulator_dev *rdev;
9141026
struct renesas_sdhi_dma *dma_priv;
1027+
struct device *dev = &pdev->dev;
9151028
struct tmio_mmc_host *host;
9161029
struct renesas_sdhi *priv;
9171030
int num_irqs, irq, ret, i;
@@ -1053,6 +1166,23 @@ int renesas_sdhi_probe(struct platform_device *pdev,
10531166
if (ret)
10541167
goto efree;
10551168

1169+
rcfg.of_node = of_get_child_by_name(dev->of_node, "vqmmc-regulator");
1170+
if (!of_device_is_available(rcfg.of_node)) {
1171+
of_node_put(rcfg.of_node);
1172+
rcfg.of_node = NULL;
1173+
}
1174+
1175+
if (rcfg.of_node) {
1176+
rcfg.driver_data = priv->host;
1177+
rdev = devm_regulator_register(dev, &renesas_sdhi_vqmmc_regulator, &rcfg);
1178+
of_node_put(rcfg.of_node);
1179+
if (IS_ERR(rdev)) {
1180+
dev_err(dev, "regulator register failed err=%ld", PTR_ERR(rdev));
1181+
goto efree;
1182+
}
1183+
priv->rdev = rdev;
1184+
}
1185+
10561186
ver = sd_ctrl_read16(host, CTL_VERSION);
10571187
/* GEN2_SDR104 is first known SDHI to use 32bit block count */
10581188
if (ver < SDHI_VER_GEN2_SDR104 && mmc_data->max_blk_count > U16_MAX)

drivers/mmc/host/tmio_mmc.h

Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -44,6 +44,7 @@
4444
#define CTL_RESET_SD 0xe0
4545
#define CTL_VERSION 0xe2
4646
#define CTL_SDIF_MODE 0xe6 /* only known on R-Car 2+ */
47+
#define CTL_SD_STATUS 0xf2 /* only known on RZ/{G2L,G3E,V2H} */
4748

4849
/* Definitions for values the CTL_STOP_INTERNAL_ACTION register can take */
4950
#define TMIO_STOP_STP BIT(0)
@@ -103,6 +104,10 @@
103104
/* Definitions for values the CTL_SDIF_MODE register can take */
104105
#define SDIF_MODE_HS400 BIT(0) /* only known on R-Car 2+ */
105106

107+
/* Definitions for values the CTL_SD_STATUS register can take */
108+
#define SD_STATUS_PWEN BIT(0) /* only known on RZ/{G3E,V2H} */
109+
#define SD_STATUS_IOVS BIT(16) /* only known on RZ/{G3E,V2H} */
110+
106111
/* Define some IRQ masks */
107112
/* This is the mask used at reset by the chip */
108113
#define TMIO_MASK_ALL 0x837f031d
@@ -226,6 +231,11 @@ static inline u32 sd_ctrl_read16_and_16_as_32(struct tmio_mmc_host *host,
226231
ioread16(host->ctl + ((addr + 2) << host->bus_shift)) << 16;
227232
}
228233

234+
static inline u32 sd_ctrl_read32(struct tmio_mmc_host *host, int addr)
235+
{
236+
return ioread32(host->ctl + (addr << host->bus_shift));
237+
}
238+
229239
static inline void sd_ctrl_read32_rep(struct tmio_mmc_host *host, int addr,
230240
u32 *buf, int count)
231241
{

0 commit comments

Comments
 (0)