Message ID | Pine.LNX.4.64.1308051514350.22479@axis700.grange (mailing list archive) |
---|---|
State | RFC |
Headers | show |
Hi Guennadi, On Mon, Aug 05 2013, Guennadi Liakhovetski wrote: > Add compatibility strings to configure MMCIF revision-specific features. > MMCIF blocks are always integrated into SoCs, so, we use SoC model to > distinguish between MMCIF versions. > > Signed-off-by: Guennadi Liakhovetski <g.liakhovetski+renesas@gmail.com> > --- > > Hi Chris, > I marked this as RFC, because having no access to the MMC standard I'm not > certain about VccQ requirements for MMC DDR. On the one hand a comment in > mmc.c says > * EXT_CSD_CARD_TYPE_DDR_1_8V means 3.3V or 1.8V vccq. > which suggests, that DDR (DDR50?) can be used with VccQ = 3.3V, 1.8V and > 1.2V at least. But in mmc_init_card() DDR50 is only requested from the > driver if either MMC_CAP_1_8V_DDR or MMC_CAP_1_2V_DDR is specified in > host's capabilities. So, I'm actually not sure whether MMC_CAP_UHS_DDR50 > alone without 1_8V or 1_2V makes sense. That's also what I implemented in > this patch - DDR50 is only enabled in combination with either 1.2 or 1.8V > capability. Is this correct? OLPC's using DDR50 at 3.3V in production. Honestly, I don't know whether it's spec compliant (I think the spec claims that 1.8V is required) but it happens to work on these parts. The host controller does support 1.8V, there's just no hardware capable of supplying 1.8V to MMC on the board. Thanks, - Chris.
Hi Chris On Mon, 5 Aug 2013, Chris Ball wrote: > Hi Guennadi, > > On Mon, Aug 05 2013, Guennadi Liakhovetski wrote: > > Add compatibility strings to configure MMCIF revision-specific features. > > MMCIF blocks are always integrated into SoCs, so, we use SoC model to > > distinguish between MMCIF versions. > > > > Signed-off-by: Guennadi Liakhovetski <g.liakhovetski+renesas@gmail.com> > > --- > > > > Hi Chris, > > I marked this as RFC, because having no access to the MMC standard I'm not > > certain about VccQ requirements for MMC DDR. On the one hand a comment in > > mmc.c says > > * EXT_CSD_CARD_TYPE_DDR_1_8V means 3.3V or 1.8V vccq. > > which suggests, that DDR (DDR50?) can be used with VccQ = 3.3V, 1.8V and > > 1.2V at least. But in mmc_init_card() DDR50 is only requested from the > > driver if either MMC_CAP_1_8V_DDR or MMC_CAP_1_2V_DDR is specified in > > host's capabilities. So, I'm actually not sure whether MMC_CAP_UHS_DDR50 > > alone without 1_8V or 1_2V makes sense. That's also what I implemented in > > this patch - DDR50 is only enabled in combination with either 1.2 or 1.8V > > capability. Is this correct? > > OLPC's using DDR50 at 3.3V in production. Honestly, I don't know > whether it's spec compliant (I think the spec claims that 1.8V is > required) but it happens to work on these parts. The host controller > does support 1.8V, there's just no hardware capable of supplying 1.8V > to MMC on the board. Thanks for the example. So, I think, for now it should be ok to just act in a way, compatible with the mmc core, i.e. always set one of MMC_CAP_1_8V_DDR or MMC_CAP_1_2V_DDR, when aiming at MMC_CAP_UHS_DDR50. So, the patch should be ok then. Thanks Guennadi --- Guennadi Liakhovetski, Ph.D. Freelance Open-Source Software Developer http://www.open-technology.de/ -- To unsubscribe from this list: send the line "unsubscribe linux-sh" in the body of a message to majordomo@vger.kernel.org More majordomo info at http://vger.kernel.org/majordomo-info.html
diff --git a/Documentation/devicetree/bindings/mmc/sh_mmcif.txt b/Documentation/devicetree/bindings/mmc/sh_mmcif.txt new file mode 100644 index 0000000..a0e7fee --- /dev/null +++ b/Documentation/devicetree/bindings/mmc/sh_mmcif.txt @@ -0,0 +1,15 @@ +* Renesas MMCIF MMC controller + +The MMCIF driver uses the standard mmc DT parser to evaluate all standard MMC DT +properties. Additionally the following properties must or can be used: + +Compulsory properties: +- compatible: must be one of + "renesas,sh-mmcif" for generic MMCIF blocks + "renesas,sh-mmcif-r8a73a4" for MMCIF on R8A73A4 (APE6) + "renesas,sh-mmcif-r8a7740" for MMCIF on R8A7740 (A1) + "renesas,sh-mmcif-r8a7790" for MMCIF on R8A7790 (H2) + "renesas,sh-mmcif-sh73a0" for MMCIF on SH73A0 (AG5) + "renesas,sh-mmcif-sh7372" for MMCIF on SH7372 (AP4) + +Further, any standard MMC DT properties from mmc.txt can be used. diff --git a/drivers/mmc/host/sh_mmcif.c b/drivers/mmc/host/sh_mmcif.c index 444f83b..a4bd784 100644 --- a/drivers/mmc/host/sh_mmcif.c +++ b/drivers/mmc/host/sh_mmcif.c @@ -57,6 +57,7 @@ #include <linux/mmc/slot-gpio.h> #include <linux/mod_devicetable.h> #include <linux/mutex.h> +#include <linux/of_device.h> #include <linux/pagemap.h> #include <linux/platform_device.h> #include <linux/pm_qos.h> @@ -257,6 +258,39 @@ struct sh_mmcif_host { bool dma_active; }; +struct sh_mmcif_of_data { + unsigned int ccs_enable : 1; + unsigned int clk_ctrl2_enable : 1; + unsigned int uhs_ddr_1v8 : 1; + unsigned int uhs_ddr_1v2 : 1; +}; + +enum { + R8A73A4, + R8A7740, + R8A7790, + SH7372, + SH73A0, +}; + +static const struct sh_mmcif_of_data sh_mmcif_of_cfg[] = { + [R8A73A4] = { + .uhs_ddr_1v8 = 1, + }, + [R8A7740] = { + /* all disabled */ + }, + [R8A7790] = { + .clk_ctrl2_enable = 1, + }, + [SH73A0] = { + .uhs_ddr_1v8 = 1, + }, + [SH7372] = { + .ccs_enable = 1, + }, +}; + static inline void sh_mmcif_bitset(struct sh_mmcif_host *host, unsigned int reg, u32 val) { @@ -1362,8 +1396,21 @@ static void sh_mmcif_init_ocr(struct sh_mmcif_host *host) dev_warn(mmc_dev(mmc), "Platform OCR mask is ignored\n"); } +static const struct of_device_id mmcif_of_match[] = { + {.compatible = "renesas,sh-mmcif"}, + {.compatible = "renesas,sh-mmcif-r8a73a4", .data = &sh_mmcif_of_cfg[R8A73A4]}, + {.compatible = "renesas,sh-mmcif-r8a7740", .data = &sh_mmcif_of_cfg[R8A7740]}, + {.compatible = "renesas,sh-mmcif-r8a7790", .data = &sh_mmcif_of_cfg[R8A7790]}, + {.compatible = "renesas,sh-mmcif-sh73a0", .data = &sh_mmcif_of_cfg[SH73A0]}, + {.compatible = "renesas,sh-mmcif-sh7372", .data = &sh_mmcif_of_cfg[SH7372]}, + {} +}; +MODULE_DEVICE_TABLE(of, mmcif_of_match); + static int sh_mmcif_probe(struct platform_device *pdev) { + const struct of_device_id *of_id = + of_match_device(mmcif_of_match, &pdev->dev); int ret = 0, irq[2]; struct mmc_host *mmc; struct sh_mmcif_host *host; @@ -1403,8 +1450,19 @@ static int sh_mmcif_probe(struct platform_device *pdev) host->mmc = mmc; host->addr = reg; host->timeout = msecs_to_jiffies(1000); - host->ccs_enable = !pd || !pd->ccs_unsupported; - host->clk_ctrl2_enable = pd && pd->clk_ctrl2_present; + + if (of_id && of_id->data) { + const struct sh_mmcif_of_data *of_data = of_id->data; + host->ccs_enable = of_data->ccs_enable; + host->clk_ctrl2_enable = of_data->clk_ctrl2_enable; + if (of_data->uhs_ddr_1v8) + mmc->caps |= MMC_CAP_UHS_DDR50 | MMC_CAP_1_8V_DDR; + if (of_data->uhs_ddr_1v2) + mmc->caps |= MMC_CAP_UHS_DDR50 | MMC_CAP_1_2V_DDR; + } else { + host->ccs_enable = !pd || !pd->ccs_unsupported; + host->clk_ctrl2_enable = pd && pd->clk_ctrl2_present; + } host->pd = pdev; @@ -1564,12 +1622,6 @@ static int sh_mmcif_resume(struct device *dev) #define sh_mmcif_resume NULL #endif /* CONFIG_PM */ -static const struct of_device_id mmcif_of_match[] = { - { .compatible = "renesas,sh-mmcif" }, - { } -}; -MODULE_DEVICE_TABLE(of, mmcif_of_match); - static const struct dev_pm_ops sh_mmcif_dev_pm_ops = { .suspend = sh_mmcif_suspend, .resume = sh_mmcif_resume,
Add compatibility strings to configure MMCIF revision-specific features. MMCIF blocks are always integrated into SoCs, so, we use SoC model to distinguish between MMCIF versions. Signed-off-by: Guennadi Liakhovetski <g.liakhovetski+renesas@gmail.com> --- Hi Chris, I marked this as RFC, because having no access to the MMC standard I'm not certain about VccQ requirements for MMC DDR. On the one hand a comment in mmc.c says * EXT_CSD_CARD_TYPE_DDR_1_8V means 3.3V or 1.8V vccq. which suggests, that DDR (DDR50?) can be used with VccQ = 3.3V, 1.8V and 1.2V at least. But in mmc_init_card() DDR50 is only requested from the driver if either MMC_CAP_1_8V_DDR or MMC_CAP_1_2V_DDR is specified in host's capabilities. So, I'm actually not sure whether MMC_CAP_UHS_DDR50 alone without 1_8V or 1_2V makes sense. That's also what I implemented in this patch - DDR50 is only enabled in combination with either 1.2 or 1.8V capability. Is this correct? Documentation/devicetree/bindings/mmc/sh_mmcif.txt | 15 ++++ drivers/mmc/host/sh_mmcif.c | 68 +++++++++++++++++-- 2 files changed, 75 insertions(+), 8 deletions(-) create mode 100644 Documentation/devicetree/bindings/mmc/sh_mmcif.txt