[PATCH RFC 00/12] Add Qualcomm SD Card Controller support.
From: Srinivas Kandagatla srinivas.kandaga...@linaro.org This patch series adds Qualcomm SD Card Controller support in pl180 mmci driver. QCom SDCC is basically a pl180, but bit more customized, some of the register layouts and offsets are different to the ones mentioned in pl180 datasheet. The plan is to totally remove the standalone SDCC driver drivers/mmc/host/msm_sdcc.* and start using generic mmci driver for all Qualcomm parts, as we get chance to test on other Qcom boards. To start using the existing mmci driver, a fake amba id for Qualcomm is added in patches: ARM: amba: Add Qualcomm vendor ID. mmc: mmci: Add Qualcomm Id to amba id table. Second change is, adding a 3 clock cycle delay for register writes on QCOM SDCC registers, which is done in patches: mmc: mmci: Add register read/write wrappers. mmc: mmci: Add write delay to variant structure. mmc: mmci: Qcomm: Add 3 clock cycle delay after each register write Third change was to accommodate DATCTRL and MMCICLK register layout changes in Qcom SDCC. Which is done in patches: mmc: mmci: Add Qcom datactrl register variant mmc: mmci: Add Qcom variations to MCICommand register. mmc: mmci: Qcom fix MCICLK register settings. mmc: mmci: Add clock support for Qualcomm. Fourth major change was to add qcom specfic pio read function, the need for this is because the way MCIFIFOCNT register behaved in QCOM SDCC is very different to the one in pl180. This change is done in patch: mmc: mmci: Add Qcom specific pio_read function. Last some Qcom unrelated changes to support Qcom are done in patches: mmc: mmci: use NSEC_PER_SEC macro mmc: mmci: move ST specific register extensions access under condition. This patches are tested in PIO mode on IFC8064 board with both eMMC and external SD card. I would appreciate any feedback/suggestions on the overall approach. Thanks, srini Srinivas Kandagatla (12): ARM: amba: Add Qualcomm vendor ID. mmc: mmci: Add Qualcomm Id to amba id table mmc: mmci: Add Qcom datactrl register variant mmc: mmci: Add register read/write wrappers. mmc: mmci: use NSEC_PER_SEC macro mmc: mmci: Add write delay to variant structure. mmc: mmci: Qcomm: Add 3 clock cycle delay after each register write mmc: mmci: move ST specific register extensions access under condition. mmc: mmci: Qcom fix MCICLK register settings. mmc: mmci: Add clock support for Qualcomm. mmc: mmci: Add Qcom variations to MCICommand register. mmc: mmci: Add Qcom specific pio_read function. drivers/mmc/host/mmci.c | 239 +- drivers/mmc/host/mmci.h | 28 ++ include/linux/amba/bus.h |1 + 3 files changed, 202 insertions(+), 66 deletions(-) -- 1.7.9.5 -- To unsubscribe from this list: send the line unsubscribe linux-arm-msm in the body of a message to majord...@vger.kernel.org More majordomo info at http://vger.kernel.org/majordomo-info.html
[PATCH RFC 03/12] mmc: mmci: Add Qcom datactrl register variant
From: Srinivas Kandagatla srinivas.kandaga...@linaro.org Instance of this IP on Qualcomm's SOCs has bit different layout for datactrl register. Bit postion datactrl[16:4] hold the true block size instead of power of 2. Signed-off-by: Srinivas Kandagatla srinivas.kandaga...@linaro.org --- drivers/mmc/host/mmci.c |6 ++ 1 file changed, 6 insertions(+) diff --git a/drivers/mmc/host/mmci.c b/drivers/mmc/host/mmci.c index 391e8d4..19d6b6f 100644 --- a/drivers/mmc/host/mmci.c +++ b/drivers/mmc/host/mmci.c @@ -58,6 +58,8 @@ static unsigned int fmax = 515633; * @sdio: variant supports SDIO * @st_clkdiv: true if using a ST-specific clock divider algorithm * @blksz_datactrl16: true if Block size is at b16..b30 position in datactrl register + * @blksz_datactrl4: true if Block size is at b4..b16 position in datactrl + * register * @pwrreg_powerup: power up value for MMCIPOWER register * @signal_direction: input/out direction of bus signals can be indicated * @pwrreg_clkgate: MMCIPOWER register must be used to gate the clock @@ -73,6 +75,7 @@ struct variant_data { boolsdio; boolst_clkdiv; boolblksz_datactrl16; + boolblksz_datactrl4; u32 pwrreg_powerup; boolsignal_direction; boolpwrreg_clkgate; @@ -162,6 +165,7 @@ static struct variant_data variant_qcom = { .fifosize = 16 * 4, .fifohalfsize = 8 * 4, .clkreg = MCI_CLK_ENABLE, + .blksz_datactrl4= true, .datalength_bits= 24, .blksz_datactrl4= true, .pwrreg_powerup = MCI_PWR_UP, @@ -760,6 +764,8 @@ static void mmci_start_data(struct mmci_host *host, struct mmc_data *data) if (variant-blksz_datactrl16) datactrl = MCI_DPSM_ENABLE | (data-blksz 16); + else if (variant-blksz_datactrl4) + datactrl = MCI_DPSM_ENABLE | (data-blksz 4); else datactrl = MCI_DPSM_ENABLE | blksz_bits 4; -- 1.7.9.5 -- To unsubscribe from this list: send the line unsubscribe linux-arm-msm in the body of a message to majord...@vger.kernel.org More majordomo info at http://vger.kernel.org/majordomo-info.html
[PATCH RFC 06/12] mmc: mmci: Add write delay to variant structure.
From: Srinivas Kandagatla srinivas.kandaga...@linaro.org This patch adds write delay parameter required after each write to controller registers on some of the SOCs like Qualcomm ones. The delay parameter will provide information on how many clock cycle delay required after each write. Signed-off-by: Srinivas Kandagatla srinivas.kandaga...@linaro.org --- drivers/mmc/host/mmci.c |8 1 file changed, 8 insertions(+) diff --git a/drivers/mmc/host/mmci.c b/drivers/mmc/host/mmci.c index 4f8d0ba..86bf330 100644 --- a/drivers/mmc/host/mmci.c +++ b/drivers/mmc/host/mmci.c @@ -55,6 +55,8 @@ static unsigned int fmax = 515633; * is asserted (likewise for RX) * @fifohalfsize: number of bytes that can be written when MCI_TXFIFOHALFEMPTY * is asserted (likewise for RX) + * @reg_write_delay: delay in number of clock cycles required after each write + * to controller registers. * @sdio: variant supports SDIO * @st_clkdiv: true if using a ST-specific clock divider algorithm * @blksz_datactrl16: true if Block size is at b16..b30 position in datactrl register @@ -72,6 +74,7 @@ struct variant_data { unsigned intdatalength_bits; unsigned intfifosize; unsigned intfifohalfsize; + unsigned intreg_write_delay; boolsdio; boolst_clkdiv; boolblksz_datactrl16; @@ -178,7 +181,12 @@ static inline u32 mmci_readl(struct mmci_host *host, u32 off) static inline void mmci_writel(struct mmci_host *host, u32 data, u32 off) { + struct variant_data *var = host-variant; + writel(data, host-base + off); + + if (var-reg_write_delay host-mclk) + udelay(1 + ((var-reg_write_delay * USEC_PER_SEC)/host-mclk)); } static int mmci_card_busy(struct mmc_host *mmc) -- 1.7.9.5 -- To unsubscribe from this list: send the line unsubscribe linux-arm-msm in the body of a message to majord...@vger.kernel.org More majordomo info at http://vger.kernel.org/majordomo-info.html
[PATCH RFC 04/12] mmc: mmci: Add register read/write wrappers.
From: Srinivas Kandagatla srinivas.kandaga...@linaro.org This patch adds wrappers for readl/writel functions used in the driver. The reason for this wrappers is to accommodate SOCs like Qualcomm which has requirement for delaying the write for few cycles when writing to its SD Card Controller registers. Signed-off-by: Srinivas Kandagatla srinivas.kandaga...@linaro.org --- drivers/mmc/host/mmci.c | 114 +-- 1 file changed, 61 insertions(+), 53 deletions(-) diff --git a/drivers/mmc/host/mmci.c b/drivers/mmc/host/mmci.c index 19d6b6f..36db31e 100644 --- a/drivers/mmc/host/mmci.c +++ b/drivers/mmc/host/mmci.c @@ -171,6 +171,16 @@ static struct variant_data variant_qcom = { .pwrreg_powerup = MCI_PWR_UP, }; +static inline u32 mmci_readl(struct mmci_host *host, u32 off) +{ + return readl(host-base + off); +} + +static inline void mmci_writel(struct mmci_host *host, u32 data, u32 off) +{ + writel(data, host-base + off); +} + static int mmci_card_busy(struct mmc_host *mmc) { struct mmci_host *host = mmc_priv(mmc); @@ -180,7 +190,7 @@ static int mmci_card_busy(struct mmc_host *mmc) pm_runtime_get_sync(mmc_dev(mmc)); spin_lock_irqsave(host-lock, flags); - if (readl(host-base + MMCISTATUS) MCI_ST_CARDBUSY) + if (mmci_readl(host, MMCISTATUS) MCI_ST_CARDBUSY) busy = 1; spin_unlock_irqrestore(host-lock, flags); @@ -230,7 +240,7 @@ static void mmci_write_clkreg(struct mmci_host *host, u32 clk) { if (host-clk_reg != clk) { host-clk_reg = clk; - writel(clk, host-base + MMCICLOCK); + mmci_writel(host, clk, MMCICLOCK); } } @@ -241,7 +251,7 @@ static void mmci_write_pwrreg(struct mmci_host *host, u32 pwr) { if (host-pwr_reg != pwr) { host-pwr_reg = pwr; - writel(pwr, host-base + MMCIPOWER); + mmci_writel(host, pwr, MMCIPOWER); } } @@ -255,7 +265,7 @@ static void mmci_write_datactrlreg(struct mmci_host *host, u32 datactrl) if (host-datactrl_reg != datactrl) { host-datactrl_reg = datactrl; - writel(datactrl, host-base + MMCIDATACTRL); + mmci_writel(host, datactrl, MMCIDATACTRL); } } @@ -321,7 +331,7 @@ static void mmci_set_clkreg(struct mmci_host *host, unsigned int desired) static void mmci_request_end(struct mmci_host *host, struct mmc_request *mrq) { - writel(0, host-base + MMCICOMMAND); + mmci_writel(host, 0, MMCICOMMAND); BUG_ON(host-data); @@ -336,18 +346,16 @@ mmci_request_end(struct mmci_host *host, struct mmc_request *mrq) static void mmci_set_mask1(struct mmci_host *host, unsigned int mask) { - void __iomem *base = host-base; - if (host-singleirq) { - unsigned int mask0 = readl(base + MMCIMASK0); + unsigned int mask0 = mmci_readl(host, MMCIMASK0); mask0 = ~MCI_IRQ1MASK; mask0 |= mask; - writel(mask0, base + MMCIMASK0); + mmci_writel(host, mask0, MMCIMASK0); } - writel(mask, base + MMCIMASK1); + mmci_writel(host, mask, MMCIMASK1); } static void mmci_stop_data(struct mmci_host *host) @@ -498,7 +506,7 @@ static void mmci_dma_finalize(struct mmci_host *host, struct mmc_data *data) /* Wait up to 1ms for the DMA to complete */ for (i = 0; ; i++) { - status = readl(host-base + MMCISTATUS); + status = mmci_readl(host, MMCISTATUS); if (!(status MCI_RXDATAAVLBLMASK) || i = 100) break; udelay(10); @@ -637,8 +645,8 @@ static int mmci_dma_start_data(struct mmci_host *host, unsigned int datactrl) * to fire next DMA request. When that happens, MMCI will * call mmci_data_end() */ - writel(readl(host-base + MMCIMASK0) | MCI_DATAENDMASK, - host-base + MMCIMASK0); + mmci_writel(host, mmci_readl(host, MMCIMASK0) | MCI_DATAENDMASK, + MMCIMASK0); return 0; } @@ -756,8 +764,8 @@ static void mmci_start_data(struct mmci_host *host, struct mmc_data *data) timeout = data-timeout_clks + (unsigned int)clks; base = host-base; - writel(timeout, base + MMCIDATATIMER); - writel(host-size, base + MMCIDATALENGTH); + mmci_writel(host, timeout, MMCIDATATIMER); + mmci_writel(host, host-size, MMCIDATALENGTH); blksz_bits = ffs(data-blksz) - 1; BUG_ON(1 blksz_bits != data-blksz); @@ -831,20 +839,19 @@ static void mmci_start_data(struct mmci_host *host, struct mmc_data *data) } mmci_write_datactrlreg(host, datactrl); - writel(readl(base + MMCIMASK0) ~MCI_DATAENDMASK, base + MMCIMASK0); + mmci_writel(host, mmci_readl(host, MMCIMASK0) ~MCI_DATAENDMASK, + MMCIMASK0
[PATCH RFC 10/12] mmc: mmci: Add clock support for Qualcomm.
From: Srinivas Kandagatla srinivas.kandaga...@linaro.org MCICLK going to card bus is directly driven by the clock controller, so the driver has to set the required rates depending on the state of the card. This bit of support is very much similar to bypass mode but there is no such thing called bypass mode in MCICLK register of Qcom SD card controller. By default the clock is directly driven by the clk controller. This patch adds clock support for Qualcomm SDCC in the driver. This bit of code is conditioned on hw designer. Signed-off-by: Srinivas Kandagatla srinivas.kandaga...@linaro.org --- drivers/mmc/host/mmci.c | 16 ++-- 1 file changed, 14 insertions(+), 2 deletions(-) diff --git a/drivers/mmc/host/mmci.c b/drivers/mmc/host/mmci.c index f465eb5..2cd3a8f 100644 --- a/drivers/mmc/host/mmci.c +++ b/drivers/mmc/host/mmci.c @@ -291,7 +291,18 @@ static void mmci_set_clkreg(struct mmci_host *host, unsigned int desired) host-cclk = 0; if (desired) { - if (desired = host-mclk) { + if (desired != host-mclk + host-hw_designer == AMBA_VENDOR_QCOM) { + /* Qcom MCLKCLK register does not define bypass bits */ + int rc = clk_set_rate(host-clk, desired); + if (rc 0) { + dev_err(mmc_dev(host-mmc), + Error setting clock rate (%d)\n, rc); + } else { + host-mclk = clk_get_rate(host-clk); + host-cclk = host-mclk; + } + } else if (desired = host-mclk) { clk = MCI_CLK_BYPASS; if (variant-st_clkdiv) clk |= MCI_ST_UX500_NEG_EDGE; @@ -1612,7 +1623,8 @@ static int mmci_probe(struct amba_device *dev, * of course. */ if (plat-f_max) - mmc-f_max = min(host-mclk, plat-f_max); + mmc-f_max = (host-hw_designer == AMBA_VENDOR_QCOM) ? + plat-f_max : min(host-mclk, plat-f_max); else mmc-f_max = min(host-mclk, fmax); dev_dbg(mmc_dev(mmc), clocking block at %u Hz\n, mmc-f_max); -- 1.7.9.5 -- To unsubscribe from this list: send the line unsubscribe linux-arm-msm in the body of a message to majord...@vger.kernel.org More majordomo info at http://vger.kernel.org/majordomo-info.html
[PATCH RFC 12/12] mmc: mmci: Add Qcom specific pio_read function.
From: Srinivas Kandagatla srinivas.kandaga...@linaro.org MCIFIFOCNT register behaviour on Qcom chips is very different than the other pl180 integrations. MCIFIFOCNT register contains the number of words that are still waiting to be transferred through the FIFO. It keeps decrementing once the host CPU reads the MCIFIFO. With the existing logic and the MCIFIFOCNT behaviour, mmci_pio_read will loop forever, as the FIFOCNT register will always return transfer size before reading the FIFO. This patch implements qcom_pio_read function so as existing mmci_pio_read is not suitable for Qcom SOCs. Signed-off-by: Srinivas Kandagatla srinivas.kandaga...@linaro.org --- drivers/mmc/host/mmci.c | 31 +-- 1 file changed, 29 insertions(+), 2 deletions(-) diff --git a/drivers/mmc/host/mmci.c b/drivers/mmc/host/mmci.c index 8fcd8ef..585888e 100644 --- a/drivers/mmc/host/mmci.c +++ b/drivers/mmc/host/mmci.c @@ -1047,6 +1047,29 @@ mmci_cmd_irq(struct mmci_host *host, struct mmc_command *cmd, } } +static int mmci_qcom_pio_read(struct mmci_host *host, char *buffer, +unsigned int remain) +{ + uint32_t*ptr = (uint32_t *) buffer; + int count = 0; + struct variant_data *variant = host-variant; + int fifo_size = variant-fifosize; + + if (remain % 4) + remain = ((remain 2) + 1) 2; + + while (readl(host-base + MMCISTATUS) MCI_RXDATAAVLBL) { + *ptr = readl(host-base + MMCIFIFO + (count % fifo_size)); + ptr++; + count += sizeof(uint32_t); + + remain -= sizeof(uint32_t); + if (remain == 0) + break; + } + return count; +} + static int mmci_pio_read(struct mmci_host *host, char *buffer, unsigned int remain) { void __iomem *base = host-base; @@ -1168,8 +1191,12 @@ static irqreturn_t mmci_pio_irq(int irq, void *dev_id) remain = sg_miter-length; len = 0; - if (status MCI_RXACTIVE) - len = mmci_pio_read(host, buffer, remain); + if (status MCI_RXACTIVE) { + if (host-hw_designer == AMBA_VENDOR_QCOM) + len = mmci_qcom_pio_read(host, buffer, remain); + else + len = mmci_pio_read(host, buffer, remain); + } if (status MCI_TXACTIVE) len = mmci_pio_write(host, buffer, remain, status); -- 1.7.9.5 -- To unsubscribe from this list: send the line unsubscribe linux-arm-msm in the body of a message to majord...@vger.kernel.org More majordomo info at http://vger.kernel.org/majordomo-info.html
[PATCH RFC 09/12] mmc: mmci: Qcom fix MCICLK register settings.
From: Srinivas Kandagatla srinivas.kandaga...@linaro.org MCICLK register layout is bit different to the standard pl180 register layout. Qcom SDCC controller some setup in MCICLK register to get it going. So this patch adds new setup and makes it specific to Qcom hw designer. Signed-off-by: Srinivas Kandagatla srinivas.kandaga...@linaro.org --- drivers/mmc/host/mmci.c | 36 ++-- drivers/mmc/host/mmci.h | 21 + 2 files changed, 51 insertions(+), 6 deletions(-) diff --git a/drivers/mmc/host/mmci.c b/drivers/mmc/host/mmci.c index 179abfb..f465eb5 100644 --- a/drivers/mmc/host/mmci.c +++ b/drivers/mmc/host/mmci.c @@ -327,13 +327,37 @@ static void mmci_set_clkreg(struct mmci_host *host, unsigned int desired) /* Set actual clock for debug */ host-mmc-actual_clock = host-cclk; - if (host-mmc-ios.bus_width == MMC_BUS_WIDTH_4) - clk |= MCI_4BIT_BUS; - if (host-mmc-ios.bus_width == MMC_BUS_WIDTH_8) - clk |= MCI_ST_8BIT_BUS; + if (host-hw_designer == AMBA_VENDOR_QCOM) { + clk |= MCI_CLK_QCOM_FLOWENA; + clk |= (MCI_CLK_QCOM_SEL_FEEDBACK_CLK + MCI_CLK_QCOM_SEL_IN_SHIFT); /* feedback clk */ + if (host-mmc-ios.bus_width == MMC_BUS_WIDTH_8) + clk |= MCI_CLK_QCOM_WIDEBUS_8; + else if (host-mmc-ios.bus_width == MMC_BUS_WIDTH_4) + clk |= MCI_CLK_QCOM_WIDEBUS_4; + else + clk |= MCI_CLK_QCOM_WIDEBUS_1; + + if (host-mmc-ios.timing == MMC_TIMING_UHS_DDR50) { + /* clear SELECT_IN field */ + clk = ~(MCI_CLK_QCOM_SEL_MASK + MCI_CLK_QCOM_SEL_IN_SHIFT); + /* set DDR timing mode */ + clk |= (MCI_CLK_QCOM_SEL_DDR_MODE + MCI_CLK_QCOM_SEL_IN_SHIFT); + } + clk |= (MCI_CLK_SDC4_MCLK_SEL_MCLK + MCI_CLK_SDC4_MCLK_SEL_SHIFT); - if (host-mmc-ios.timing == MMC_TIMING_UHS_DDR50) - clk |= MCI_ST_UX500_NEG_EDGE; + } else { + if (host-mmc-ios.bus_width == MMC_BUS_WIDTH_4) + clk |= MCI_4BIT_BUS; + if (host-mmc-ios.bus_width == MMC_BUS_WIDTH_8) + clk |= MCI_ST_8BIT_BUS; + + if (host-mmc-ios.timing == MMC_TIMING_UHS_DDR50) + clk |= MCI_ST_UX500_NEG_EDGE; + } mmci_write_clkreg(host, clk); } diff --git a/drivers/mmc/host/mmci.h b/drivers/mmc/host/mmci.h index 58b1b88..0a6de1c 100644 --- a/drivers/mmc/host/mmci.h +++ b/drivers/mmc/host/mmci.h @@ -31,6 +31,27 @@ /* Modified PL180 on Versatile Express platform */ #define MCI_ARM_HWFCEN (1 12) +/* Modified on Qualcomm Integrations */ +#define MCI_CLK_QCOM_WIDEBUS_1 (0 10) +#define MCI_CLK_QCOM_WIDEBUS_4 (2 10) +#define MCI_CLK_QCOM_WIDEBUS_8 (3 10) +#define MCI_CLK_QCOM_FLOWENA (1 12) +#define MCI_CLK_QCOM_INVERTOUT (1 13) + +/* select in latch data and command */ +#define MCI_CLK_QCOM_SEL_IN_SHIFT (14) +#define MCI_CLK_QCOM_SEL_MASK (0x3) +#define MCI_CLK_QCOM_SEL_RISING_EDGE (1) +#define MCI_CLK_QCOM_SEL_FEEDBACK_CLK (2) +#define MCI_CLK_QCOM_SEL_DDR_MODE (3) + +/* mclk selection */ +#define MCI_CLK_SDC4_MCLK_SEL_SHIFT(23) +#define MCI_CLK_SDC4_MCLK_SEL_MASK (0x3) +#define MCI_CLK_SDC4_MCLK_SEL_FB_CLK (1) +#define MCI_CLK_SDC4_MCLK_SEL_MCLK (2) + + #define MMCIARGUMENT 0x008 #define MMCICOMMAND0x00c #define MCI_CPSM_RESPONSE (1 6) -- 1.7.9.5 -- To unsubscribe from this list: send the line unsubscribe linux-arm-msm in the body of a message to majord...@vger.kernel.org More majordomo info at http://vger.kernel.org/majordomo-info.html
[PATCH RFC 11/12] mmc: mmci: Add Qcom variations to MCICommand register.
From: Srinivas Kandagatla srinivas.kandaga...@linaro.org Some bits which control Command Path State Machine (CPSM) are new in Qcom integration, so this patch adds support to those bits. Signed-off-by: Srinivas Kandagatla srinivas.kandaga...@linaro.org --- drivers/mmc/host/mmci.c |4 drivers/mmc/host/mmci.h |7 +++ 2 files changed, 11 insertions(+) diff --git a/drivers/mmc/host/mmci.c b/drivers/mmc/host/mmci.c index 2cd3a8f..8fcd8ef 100644 --- a/drivers/mmc/host/mmci.c +++ b/drivers/mmc/host/mmci.c @@ -910,6 +910,10 @@ mmci_start_command(struct mmci_host *host, struct mmc_command *cmd, u32 c) if (/*interrupt*/0) c |= MCI_CPSM_INTERRUPT; + if (host-hw_designer == AMBA_VENDOR_QCOM + mmc_cmd_type(cmd) == MMC_CMD_ADTC) + c |= MCI_CSPM_QCOM_DATCMD; + host-cmd = cmd; mmci_writel(host, cmd-arg, MMCIARGUMENT); diff --git a/drivers/mmc/host/mmci.h b/drivers/mmc/host/mmci.h index 0a6de1c..2ba0834 100644 --- a/drivers/mmc/host/mmci.h +++ b/drivers/mmc/host/mmci.h @@ -64,6 +64,13 @@ #define MCI_ST_ENCMD_COMPL (1 12) #define MCI_ST_NIEN(1 13) #define MCI_ST_CE_ATACMD (1 14) +/* Modified on Qualcomm Integrations */ +#define MCI_CSPM_QCOM_DATCMD (1 12) +#define MCI_CSPM_QCOM_MCIABORT (1 13) +#define MCI_CSPM_QCOM_CCSENABLE(1 14) +#define MCI_CSPM_QCOM_CCSDISABLE (1 15) +#define MCI_CSPM_QCOM_AUTO_CMD19 (1 16) +#define MCI_CSPM_QCOM_AUTO_CMD21 (1 21) #define MMCIRESPCMD0x010 #define MMCIRESPONSE0 0x014 -- 1.7.9.5 -- To unsubscribe from this list: send the line unsubscribe linux-arm-msm in the body of a message to majord...@vger.kernel.org More majordomo info at http://vger.kernel.org/majordomo-info.html
[PATCH RFC 05/12] mmc: mmci: use NSEC_PER_SEC macro
From: Srinivas Kandagatla srinivas.kandaga...@linaro.org This patch replaces a constant used in calculating timeout with a proper macro. This is make code more readable. Signed-off-by: Srinivas Kandagatla srinivas.kandaga...@linaro.org --- drivers/mmc/host/mmci.c |2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/drivers/mmc/host/mmci.c b/drivers/mmc/host/mmci.c index 36db31e..4f8d0ba 100644 --- a/drivers/mmc/host/mmci.c +++ b/drivers/mmc/host/mmci.c @@ -759,7 +759,7 @@ static void mmci_start_data(struct mmci_host *host, struct mmc_data *data) data-bytes_xfered = 0; clks = (unsigned long long)data-timeout_ns * host-cclk; - do_div(clks, 10UL); + do_div(clks, NSEC_PER_SEC); timeout = data-timeout_clks + (unsigned int)clks; -- 1.7.9.5 -- To unsubscribe from this list: send the line unsubscribe linux-arm-msm in the body of a message to majord...@vger.kernel.org More majordomo info at http://vger.kernel.org/majordomo-info.html
Re: [PATCH RFC 06/12] mmc: mmci: Add write delay to variant structure.
Thanks Felipe, On 21/04/14 23:08, Felipe Balbi wrote: + if (var-reg_write_delay host-mclk) + udelay(1 + ((var-reg_write_delay * USEC_PER_SEC)/host-mclk)); looks like this should be quirk flag instead of a write delay... No strong feelings though, but it looks like the following would be better, perhaps: if (host_is_qualcom(host)) udelay(1 + ((3 * USEC_PER_SEC)/host-mclk)); Am ok with your proposal. I was wondering if someone else might need it in future. If not I could change it as you suggested. Thanks, srini -- -- To unsubscribe from this list: send the line unsubscribe linux-arm-msm in the body of a message to majord...@vger.kernel.org More majordomo info at http://vger.kernel.org/majordomo-info.html
Re: [PATCH RFC 00/12] Add Qualcomm SD Card Controller support.
Hi Christopher, On 22/04/14 13:58, Christopher Covington wrote: Hi Srini, On 04/21/2014 05:43 PM, srinivas.kandaga...@linaro.org wrote: This patches are tested in PIO mode on IFC8064 board with both eMMC and external SD card. I would appreciate any feedback/suggestions on the overall approach. I pushed a temporary tag mmci-pio-srini-wip for you on my git tree git://git.linaro.org/landing-teams/working/qualcomm/kernel.git Is a non-upstream device tree needed to reproduce your test setup? If so could you please point to or post it? You will need to use multi_v7_defconfig. Thanks, srini Thanks, Christopher -- To unsubscribe from this list: send the line unsubscribe linux-arm-msm in the body of a message to majord...@vger.kernel.org More majordomo info at http://vger.kernel.org/majordomo-info.html
Re: [PATCH v6 04/19] usb: phy: msm: Migrate to Managed Device Resource allocation
On 22/04/14 10:20, Ivan T. Ivanov wrote: From: Ivan T. Ivanov iiva...@mm-sol.com Move memory, regulators, clocks and irq allocation to devm_* variants. Properly check for valid clk handles. -module_platform_driver_probe(msm_otg_driver, msm_otg_probe); +module_platform_driver(msm_otg_driver); This change doesn’t match the log. MODULE_LICENSE(GPL v2); MODULE_DESCRIPTION(MSM USB transceiver driver); -- 1.8.3.2 -- To unsubscribe from this list: send the line unsubscribe linux-arm-msm in the body of a message to majord...@vger.kernel.org More majordomo info at http://vger.kernel.org/majordomo-info.html -- To unsubscribe from this list: send the line unsubscribe linux-arm-msm in the body of a message to majord...@vger.kernel.org More majordomo info at http://vger.kernel.org/majordomo-info.html
Re: [PATCH v6 06/19] usb: phy: msm: Fix checkpatch.pl warnings
On 22/04/14 10:20, Ivan T. Ivanov wrote: @@ -79,8 +78,7 @@ static int msm_hsusb_init_vddcx(struct msm_otg *motg, int init) ret = regulator_set_voltage(motg-vddcx, 0, USB_PHY_VDD_DIG_VOL_MAX); if (ret) - dev_err(motg-phy.dev, unable to set the voltage - for hsusb vddcx\n); + dev_err(motg-phy.dev, Cannot set vddcx voltage\n); @@ -137,15 +133,13 @@ static int msm_hsusb_ldo_set_mode(struct msm_otg *motg, int on) ret = regulator_set_optimum_mode(motg-v1p8, USB_PHY_1P8_HPM_LOAD); if (ret 0) { - pr_err(%s: Unable to set HPM of the regulator - HSUSB_1p8\n, __func__); + pr_err(Could not set HPM for v1p8\n); return ret; } @@ -390,8 +382,7 @@ static int msm_hsusb_config_vddcx(struct msm_otg *motg, int high) ret = regulator_set_voltage(motg-vddcx, min_vol, max_vol); if (ret) { - pr_err(%s: unable to set the voltage for regulator - HSUSB_VDDCX\n, __func__); + dev_err(motg-phy.dev, Cannot set vddcx voltage\n); return ret; } I see some of pr_err not moved to dev_err?, while others have been moved. Also noticed that the error messages are changed as part of this fix. IMHO, changing an error message would have a side-effects on logging tools, anyway Am not sure if its true in this case. Thanks, srini -- To unsubscribe from this list: send the line unsubscribe linux-arm-msm in the body of a message to majord...@vger.kernel.org More majordomo info at http://vger.kernel.org/majordomo-info.html
Re: [PATCH v6 11/19] usb: phy: msm: Add device tree support and binding information
Hi Ivan, On 22/04/14 10:20, Ivan T. Ivanov wrote: From: Ivan T. Ivanoviiva...@mm-sol.com Allows MSM OTG controller to be specified via device tree. Signed-off-by: Ivan T. Ivanoviiva...@mm-sol.com --- .../devicetree/bindings/usb/msm-hsusb.txt | 67 + drivers/usb/phy/phy-msm-usb.c | 108 + include/linux/usb/msm_hsusb.h | 6 +- 3 files changed, 159 insertions(+), 22 deletions(-) diff --git a/Documentation/devicetree/bindings/usb/msm-hsusb.txt b/Documentation/devicetree/bindings/usb/msm-hsusb.txt index 5ea26c6..ee4123d 100644 --- a/Documentation/devicetree/bindings/usb/msm-hsusb.txt +++ b/Documentation/devicetree/bindings/usb/msm-hsusb.txt @@ -15,3 +15,70 @@ Example EHCI controller device node: usb-phy = usb_otg; }; +USB PHY with optional OTG: + +Required properties: +- compatible: Should contain: + qcom,usb-otg-ci for chipsets with ChipIdea 45nm PHY + qcom,usb-otg-snps for chipsets with Synopsys 28nm PHY + +- regs: Offset and length of the register set in the memory map +- interrupts: interrupt-specifier for the OTG interrupt. + +- clocks: A list of phandle + clock-specifier pairs for the +clocks listed in clock-names +- clock-names: Should contain the following: + phy USB PHY reference clock + coreProtocol engine clock + iface Interface bus clock + alt_coreProtocol engine clock for targets with asynchronous +reset methodology. (optional) + +- vdccx-supply: phandle to the regulator for the vdd supply for +digital circuit operation. +- v1p8-supply: phandle to the regulator for the 1.8V supply +- v3p3-supply: phandle to the regulator for the 3.3V supply + +- resets: A list of phandle + reset-specifier pairs for the +resets listed in reset-names +- reset-names: Should contain the following: + phy USB PHY controller reset + linkUSB LINK controller reset + +- qcom,otg-control: OTG control (VBUS and ID notifications) can be one of +1 - PHY control +2 - PMIC control + +Optional properties: +- dr_mode: One of host, peripheral or otg. Defaults to otg + +- qcom,phy-init-sequence: PHY configuration sequence values. This is related to Device +Mode Eye Diagram test. Start address at which these values will be +written is ULPI_EXT_VENDOR_SPECIFIC. Value of -1 is reserved as +do not overwrite default value at this address. +For example: qcom,phy-init-sequence = -1 0x63 ; +Will update only value at address ULPI_EXT_VENDOR_SPECIFIC + 1. I don’t think DT maintainers will like the sound of it. Sorry If I missed some old discussion on this. But I don't this this is the correct way. DT should describe the system hardware layout rather than initialization sequence. The initialization code with magic values should go directly into the driver and depending on the dt-compatible driver should select the right sequence. /phy-msm-usb.c +++ b/drivers/usb/phy/phy-msm-usb.c @@ -30,9 +30,12 @@ #include linux/debugfs.h #include linux/seq_file.h #include linux/pm_runtime.h +#include linux/of.h +#include linux/of_device.h #include linux/usb.h #include linux/usb/otg.h +#include linux/usb/of.h #include linux/usb/ulpi.h #include linux/usb/gadget.h #include linux/usb/hcd.h @@ -217,16 +220,16 @@ static struct usb_phy_io_ops msm_otg_io_ops = { static void ulpi_init(struct msm_otg *motg) { struct msm_otg_platform_data *pdata = motg-pdata; - int *seq = pdata-phy_init_seq; + int *seq = pdata-phy_init_seq, idx; + u32 addr = ULPI_EXT_VENDOR_SPECIFIC; - if (!seq) - return; + for (idx = 0; idx pdata-phy_init_sz; idx++) { + if (seq[idx] == -1) + continue; - while (seq[0] = 0) { dev_vdbg(motg-phy.dev, ulpi: write 0x%02x to 0x%02x\n, - seq[0], seq[1]); - ulpi_write(motg-phy, seq[0], seq[1]); - seq += 2; + seq[idx], addr + idx); + ulpi_write(motg-phy, seq[idx], addr + idx); } } How is above change related to device trees? @@ -1343,25 +1346,87 @@ static void msm_otg_debugfs_cleanup(void) debugfs_remove(msm_otg_dbg_root); } +static struct of_device_id msm_otg_dt_match[] = { + { + .compatible = qcom,usb-otg-ci, + .data = (void *) CI_45NM_INTEGRATED_PHY + }, { + .compatible = qcom,usb-otg-snps, + .data = (void *) SNPS_28NM_INTEGRATED_PHY + }, {} +}; + +static int msm_otg_read_dt(struct platform_device *pdev, struct msm_otg *motg) +{ + struct msm_otg_platform_data *pdata; + const struct of_device_id *id; + struct device_node
[PATCH v1 00/11] Add Qualcomm SD Card Controller support.
From: Srinivas Kandagatla srinivas.kandaga...@linaro.org Hi Russell, This patch series adds Qualcomm SD Card Controller support in pl180 mmci driver. QCom SDCC is basically a pl180, but bit more customized, some of the register layouts and offsets are different to the ones mentioned in pl180 datasheet. The plan is to totally remove the standalone SDCC driver drivers/mmc/host/msm_sdcc.* and start using generic mmci driver for all Qualcomm parts, as we get chance to test on other Qcom boards. To start using the existing mmci driver, a fake amba id for Qualcomm is added in patches: ARM: amba: Add Qualcomm vendor ID. mmc: mmci: Add Qualcomm Id to amba id table. Second change is, adding a 3 clock cycle delay for register writes on QCOM SDCC registers, which is done in patches: mmc: mmci: Add register read/write wrappers. mmc: mmci: Qcomm: Add 3 clock cycle delay after each register write Third change was to accommodate DATCTRL and MMCICLK register layout changes in Qcom SDCC. Which is done in patches: mmc: mmci: Add Qcom datactrl register variant mmc: mmci: Add Qcom variations to MCICommand register. mmc: mmci: Qcom fix MCICLK register settings. mmc: mmci: Add clock support for Qualcomm. Fourth major change was to add qcom specfic pio read function, the need for this is because the way MCIFIFOCNT register behaved in QCOM SDCC is very different to the one in pl180. This change is done in patch: mmc: mmci: Add Qcom specific pio_read function. Last some Qcom unrelated changes to support Qcom are done in patches: mmc: mmci: use NSEC_PER_SEC macro mmc: mmci: move ST specific register extensions access under condition. This patches are tested v3.15-rc3 in PIO mode on IFC6410 board with both eMMC and external SD card. I would appreciate any feedback on the patches. I would like to get this for v3.16. Thanks, srini Srinivas Kandagatla (11): ARM: amba: Add Qualcomm vendor ID. mmc: mmci: Add Qualcomm Id to amba id table mmc: mmci: Add Qcom datactrl register variant mmc: mmci: Add register read/write wrappers. mmc: mmci: use NSEC_PER_SEC macro mmc: mmci: Qcomm: Add 3 clock cycle delay after register write mmc: mmci: move ST specific register extensions access under condition. mmc: mmci: Qcom fix MCICLK register settings. mmc: mmci: Add clock support for Qualcomm. mmc: mmci: Add Qcom variations to MCICommand register. mmc: mmci: Add Qcom specific pio_read function. drivers/mmc/host/mmci.c | 243 +- drivers/mmc/host/mmci.h | 28 ++ include/linux/amba/bus.h |1 + 3 files changed, 206 insertions(+), 66 deletions(-) -- 1.7.9.5 -- To unsubscribe from this list: send the line unsubscribe linux-arm-msm in the body of a message to majord...@vger.kernel.org More majordomo info at http://vger.kernel.org/majordomo-info.html
[PATCH v1 02/11] mmc: mmci: Add Qualcomm Id to amba id table
From: Srinivas Kandagatla srinivas.kandaga...@linaro.org This patch adds a fake Qualcomm ID 0x00051180 to the amba_ids, as Qualcomm SDCC controller is pl180, but amba id registers read 0x0's. The plan is to remove SDCC driver totally and use mmci as the main SD controller driver for Qualcomm SOCs. Signed-off-by: Srinivas Kandagatla srinivas.kandaga...@linaro.org --- drivers/mmc/host/mmci.c | 15 +++ 1 file changed, 15 insertions(+) diff --git a/drivers/mmc/host/mmci.c b/drivers/mmc/host/mmci.c index 771c60a..391e8d4 100644 --- a/drivers/mmc/host/mmci.c +++ b/drivers/mmc/host/mmci.c @@ -158,6 +158,15 @@ static struct variant_data variant_ux500v2 = { .pwrreg_nopower = true, }; +static struct variant_data variant_qcom = { + .fifosize = 16 * 4, + .fifohalfsize = 8 * 4, + .clkreg = MCI_CLK_ENABLE, + .datalength_bits= 24, + .blksz_datactrl4= true, + .pwrreg_powerup = MCI_PWR_UP, +}; + static int mmci_card_busy(struct mmc_host *mmc) { struct mmci_host *host = mmc_priv(mmc); @@ -1908,6 +1917,12 @@ static struct amba_id mmci_ids[] = { .mask = 0xf0ff, .data = variant_ux500v2, }, + /* Qualcomm variants */ + { + .id = 0x00051180, + .mask = 0x000f, + .data = variant_qcom, + }, { 0, 0 }, }; -- 1.7.9.5 -- To unsubscribe from this list: send the line unsubscribe linux-arm-msm in the body of a message to majord...@vger.kernel.org More majordomo info at http://vger.kernel.org/majordomo-info.html
[PATCH v1 01/11] ARM: amba: Add Qualcomm vendor ID.
From: Srinivas Kandagatla srinivas.kandaga...@linaro.org This patch adds Qualcomm amba vendor Id to the list. This ID is used in mmci driver. Signed-off-by: Srinivas Kandagatla srinivas.kandaga...@linaro.org --- include/linux/amba/bus.h |1 + 1 file changed, 1 insertion(+) diff --git a/include/linux/amba/bus.h b/include/linux/amba/bus.h index 63b5eff..fdd7e1b 100644 --- a/include/linux/amba/bus.h +++ b/include/linux/amba/bus.h @@ -47,6 +47,7 @@ struct amba_driver { enum amba_vendor { AMBA_VENDOR_ARM = 0x41, AMBA_VENDOR_ST = 0x80, + AMBA_VENDOR_QCOM = 0x51, }; extern struct bus_type amba_bustype; -- 1.7.9.5 -- To unsubscribe from this list: send the line unsubscribe linux-arm-msm in the body of a message to majord...@vger.kernel.org More majordomo info at http://vger.kernel.org/majordomo-info.html
[PATCH v1 06/11] mmc: mmci: Qcomm: Add 3 clock cycle delay after register write
From: Srinivas Kandagatla srinivas.kandaga...@linaro.org Most of the Qcomm SD card controller registers must be updated to the MCLK domain so subsequent writes to registers will be ignored until 3 clock cycles have passed. This patch adds a 3 clock cycle delay required after writing to controller registers on Qualcomm SOCs. Without this delay all the register writes are not successfull, resulting in not detecting cards. Signed-off-by: Srinivas Kandagatla srinivas.kandaga...@linaro.org --- drivers/mmc/host/mmci.c |8 1 file changed, 8 insertions(+) diff --git a/drivers/mmc/host/mmci.c b/drivers/mmc/host/mmci.c index 4f8d0ba..f73dc48 100644 --- a/drivers/mmc/host/mmci.c +++ b/drivers/mmc/host/mmci.c @@ -179,6 +179,14 @@ static inline u32 mmci_readl(struct mmci_host *host, u32 off) static inline void mmci_writel(struct mmci_host *host, u32 data, u32 off) { writel(data, host-base + off); + + /* +* On QCom SD card controller, registers must be updated to the +* MCLK domain so subsequent writes to this register will be ignored +* for 3 clk cycles. +*/ + if (host-hw_designer == AMBA_VENDOR_QCOM) + udelay(1 + ((3 * USEC_PER_SEC)/host-mclk)); } static int mmci_card_busy(struct mmc_host *mmc) -- 1.7.9.5 -- To unsubscribe from this list: send the line unsubscribe linux-arm-msm in the body of a message to majord...@vger.kernel.org More majordomo info at http://vger.kernel.org/majordomo-info.html
[PATCH v1 11/11] mmc: mmci: Add Qcom specific pio_read function.
From: Srinivas Kandagatla srinivas.kandaga...@linaro.org MCIFIFOCNT register behaviour on Qcom chips is very different than the other pl180 integrations. MCIFIFOCNT register contains the number of words that are still waiting to be transferred through the FIFO. It keeps decrementing once the host CPU reads the MCIFIFO. With the existing logic and the MCIFIFOCNT behaviour, mmci_pio_read will loop forever, as the FIFOCNT register will always return transfer size before reading the FIFO. Also the data sheet states that This register is only useful for debug purposes and should not be used for normal operation since it does not reflect data which may or may not be in the pipeline. This patch implements qcom_pio_read function so as existing mmci_pio_read is not suitable for Qcom SOCs. Signed-off-by: Srinivas Kandagatla srinivas.kandaga...@linaro.org --- drivers/mmc/host/mmci.c | 31 +-- 1 file changed, 29 insertions(+), 2 deletions(-) diff --git a/drivers/mmc/host/mmci.c b/drivers/mmc/host/mmci.c index def1b19..45198b6 100644 --- a/drivers/mmc/host/mmci.c +++ b/drivers/mmc/host/mmci.c @@ -1038,6 +1038,29 @@ mmci_cmd_irq(struct mmci_host *host, struct mmc_command *cmd, } } +static int mmci_qcom_pio_read(struct mmci_host *host, char *buffer, +unsigned int remain) +{ + uint32_t*ptr = (uint32_t *) buffer; + int count = 0; + struct variant_data *variant = host-variant; + int fifo_size = variant-fifosize; + + if (remain % 4) + remain = ((remain 2) + 1) 2; + + while (readl(host-base + MMCISTATUS) MCI_RXDATAAVLBL) { + *ptr = readl(host-base + MMCIFIFO + (count % fifo_size)); + ptr++; + count += sizeof(uint32_t); + + remain -= sizeof(uint32_t); + if (remain == 0) + break; + } + return count; +} + static int mmci_pio_read(struct mmci_host *host, char *buffer, unsigned int remain) { void __iomem *base = host-base; @@ -1159,8 +1182,12 @@ static irqreturn_t mmci_pio_irq(int irq, void *dev_id) remain = sg_miter-length; len = 0; - if (status MCI_RXACTIVE) - len = mmci_pio_read(host, buffer, remain); + if (status MCI_RXACTIVE) { + if (host-hw_designer == AMBA_VENDOR_QCOM) + len = mmci_qcom_pio_read(host, buffer, remain); + else + len = mmci_pio_read(host, buffer, remain); + } if (status MCI_TXACTIVE) len = mmci_pio_write(host, buffer, remain, status); -- 1.7.9.5 -- To unsubscribe from this list: send the line unsubscribe linux-arm-msm in the body of a message to majord...@vger.kernel.org More majordomo info at http://vger.kernel.org/majordomo-info.html
[PATCH v1 10/11] mmc: mmci: Add Qcom variations to MCICommand register.
From: Srinivas Kandagatla srinivas.kandaga...@linaro.org Some bits which control Command Path State Machine (CPSM) are new in Qcom integration, so this patch adds support to those bits. Signed-off-by: Srinivas Kandagatla srinivas.kandaga...@linaro.org --- drivers/mmc/host/mmci.c |4 drivers/mmc/host/mmci.h |7 +++ 2 files changed, 11 insertions(+) diff --git a/drivers/mmc/host/mmci.c b/drivers/mmc/host/mmci.c index da135c0..def1b19 100644 --- a/drivers/mmc/host/mmci.c +++ b/drivers/mmc/host/mmci.c @@ -901,6 +901,10 @@ mmci_start_command(struct mmci_host *host, struct mmc_command *cmd, u32 c) if (/*interrupt*/0) c |= MCI_CPSM_INTERRUPT; + if (host-hw_designer == AMBA_VENDOR_QCOM + mmc_cmd_type(cmd) == MMC_CMD_ADTC) + c |= MCI_CSPM_QCOM_DATCMD; + host-cmd = cmd; mmci_writel(host, cmd-arg, MMCIARGUMENT); diff --git a/drivers/mmc/host/mmci.h b/drivers/mmc/host/mmci.h index 0a6de1c..2ba0834 100644 --- a/drivers/mmc/host/mmci.h +++ b/drivers/mmc/host/mmci.h @@ -64,6 +64,13 @@ #define MCI_ST_ENCMD_COMPL (1 12) #define MCI_ST_NIEN(1 13) #define MCI_ST_CE_ATACMD (1 14) +/* Modified on Qualcomm Integrations */ +#define MCI_CSPM_QCOM_DATCMD (1 12) +#define MCI_CSPM_QCOM_MCIABORT (1 13) +#define MCI_CSPM_QCOM_CCSENABLE(1 14) +#define MCI_CSPM_QCOM_CCSDISABLE (1 15) +#define MCI_CSPM_QCOM_AUTO_CMD19 (1 16) +#define MCI_CSPM_QCOM_AUTO_CMD21 (1 21) #define MMCIRESPCMD0x010 #define MMCIRESPONSE0 0x014 -- 1.7.9.5 -- To unsubscribe from this list: send the line unsubscribe linux-arm-msm in the body of a message to majord...@vger.kernel.org More majordomo info at http://vger.kernel.org/majordomo-info.html
[PATCH v1 08/11] mmc: mmci: Qcom fix MCICLK register settings.
From: Srinivas Kandagatla srinivas.kandaga...@linaro.org MCICLK register layout is bit different to the standard pl180 register layout. Qcom SDCC controller some setup in MCICLK register to get it going. So this patch adds new setup and makes it specific to Qcom hw designer. Signed-off-by: Srinivas Kandagatla srinivas.kandaga...@linaro.org --- drivers/mmc/host/mmci.c | 36 ++-- drivers/mmc/host/mmci.h | 21 + 2 files changed, 51 insertions(+), 6 deletions(-) diff --git a/drivers/mmc/host/mmci.c b/drivers/mmc/host/mmci.c index 306e0c8..35aed38 100644 --- a/drivers/mmc/host/mmci.c +++ b/drivers/mmc/host/mmci.c @@ -326,13 +326,37 @@ static void mmci_set_clkreg(struct mmci_host *host, unsigned int desired) /* Set actual clock for debug */ host-mmc-actual_clock = host-cclk; - if (host-mmc-ios.bus_width == MMC_BUS_WIDTH_4) - clk |= MCI_4BIT_BUS; - if (host-mmc-ios.bus_width == MMC_BUS_WIDTH_8) - clk |= MCI_ST_8BIT_BUS; + if (host-hw_designer == AMBA_VENDOR_QCOM) { + clk |= MCI_CLK_QCOM_FLOWENA; + clk |= (MCI_CLK_QCOM_SEL_FEEDBACK_CLK + MCI_CLK_QCOM_SEL_IN_SHIFT); /* feedback clk */ + if (host-mmc-ios.bus_width == MMC_BUS_WIDTH_8) + clk |= MCI_CLK_QCOM_WIDEBUS_8; + else if (host-mmc-ios.bus_width == MMC_BUS_WIDTH_4) + clk |= MCI_CLK_QCOM_WIDEBUS_4; + else + clk |= MCI_CLK_QCOM_WIDEBUS_1; + + if (host-mmc-ios.timing == MMC_TIMING_UHS_DDR50) { + /* clear SELECT_IN field */ + clk = ~(MCI_CLK_QCOM_SEL_MASK + MCI_CLK_QCOM_SEL_IN_SHIFT); + /* set DDR timing mode */ + clk |= (MCI_CLK_QCOM_SEL_DDR_MODE + MCI_CLK_QCOM_SEL_IN_SHIFT); + } + clk |= (MCI_CLK_SDC4_MCLK_SEL_MCLK + MCI_CLK_SDC4_MCLK_SEL_SHIFT); - if (host-mmc-ios.timing == MMC_TIMING_UHS_DDR50) - clk |= MCI_ST_UX500_NEG_EDGE; + } else { + if (host-mmc-ios.bus_width == MMC_BUS_WIDTH_4) + clk |= MCI_4BIT_BUS; + if (host-mmc-ios.bus_width == MMC_BUS_WIDTH_8) + clk |= MCI_ST_8BIT_BUS; + + if (host-mmc-ios.timing == MMC_TIMING_UHS_DDR50) + clk |= MCI_ST_UX500_NEG_EDGE; + } mmci_write_clkreg(host, clk); } diff --git a/drivers/mmc/host/mmci.h b/drivers/mmc/host/mmci.h index 58b1b88..0a6de1c 100644 --- a/drivers/mmc/host/mmci.h +++ b/drivers/mmc/host/mmci.h @@ -31,6 +31,27 @@ /* Modified PL180 on Versatile Express platform */ #define MCI_ARM_HWFCEN (1 12) +/* Modified on Qualcomm Integrations */ +#define MCI_CLK_QCOM_WIDEBUS_1 (0 10) +#define MCI_CLK_QCOM_WIDEBUS_4 (2 10) +#define MCI_CLK_QCOM_WIDEBUS_8 (3 10) +#define MCI_CLK_QCOM_FLOWENA (1 12) +#define MCI_CLK_QCOM_INVERTOUT (1 13) + +/* select in latch data and command */ +#define MCI_CLK_QCOM_SEL_IN_SHIFT (14) +#define MCI_CLK_QCOM_SEL_MASK (0x3) +#define MCI_CLK_QCOM_SEL_RISING_EDGE (1) +#define MCI_CLK_QCOM_SEL_FEEDBACK_CLK (2) +#define MCI_CLK_QCOM_SEL_DDR_MODE (3) + +/* mclk selection */ +#define MCI_CLK_SDC4_MCLK_SEL_SHIFT(23) +#define MCI_CLK_SDC4_MCLK_SEL_MASK (0x3) +#define MCI_CLK_SDC4_MCLK_SEL_FB_CLK (1) +#define MCI_CLK_SDC4_MCLK_SEL_MCLK (2) + + #define MMCIARGUMENT 0x008 #define MMCICOMMAND0x00c #define MCI_CPSM_RESPONSE (1 6) -- 1.7.9.5 -- To unsubscribe from this list: send the line unsubscribe linux-arm-msm in the body of a message to majord...@vger.kernel.org More majordomo info at http://vger.kernel.org/majordomo-info.html
[PATCH v1 07/11] mmc: mmci: move ST specific register extensions access under condition.
From: Srinivas Kandagatla srinivas.kandaga...@linaro.org This patch moves some of the ST specific register extensions access under condition, so that other SOCs like Qualcomm or ARM would not a side effect of writing to those reserved/different purpose bits. Signed-off-by: Srinivas Kandagatla srinivas.kandaga...@linaro.org --- drivers/mmc/host/mmci.c |6 -- 1 file changed, 4 insertions(+), 2 deletions(-) diff --git a/drivers/mmc/host/mmci.c b/drivers/mmc/host/mmci.c index f73dc48..306e0c8 100644 --- a/drivers/mmc/host/mmci.c +++ b/drivers/mmc/host/mmci.c @@ -269,7 +269,8 @@ static void mmci_write_pwrreg(struct mmci_host *host, u32 pwr) static void mmci_write_datactrlreg(struct mmci_host *host, u32 datactrl) { /* Keep ST Micro busy mode if enabled */ - datactrl |= host-datactrl_reg MCI_ST_DPSM_BUSYMODE; + if (host-hw_designer == AMBA_VENDOR_ST) + datactrl |= host-datactrl_reg MCI_ST_DPSM_BUSYMODE; if (host-datactrl_reg != datactrl) { host-datactrl_reg = datactrl; @@ -815,7 +816,8 @@ static void mmci_start_data(struct mmci_host *host, struct mmc_data *data) mmci_write_clkreg(host, clk); } - if (host-mmc-ios.timing == MMC_TIMING_UHS_DDR50) + if (host-mmc-ios.timing == MMC_TIMING_UHS_DDR50 + host-hw_designer == AMBA_VENDOR_ST) datactrl |= MCI_ST_DPSM_DDRMODE; /* -- 1.7.9.5 -- To unsubscribe from this list: send the line unsubscribe linux-arm-msm in the body of a message to majord...@vger.kernel.org More majordomo info at http://vger.kernel.org/majordomo-info.html
[PATCH v1 05/11] mmc: mmci: use NSEC_PER_SEC macro
From: Srinivas Kandagatla srinivas.kandaga...@linaro.org This patch replaces a constant used in calculating timeout with a proper macro. This is make code more readable. Signed-off-by: Srinivas Kandagatla srinivas.kandaga...@linaro.org --- drivers/mmc/host/mmci.c |2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/drivers/mmc/host/mmci.c b/drivers/mmc/host/mmci.c index 36db31e..4f8d0ba 100644 --- a/drivers/mmc/host/mmci.c +++ b/drivers/mmc/host/mmci.c @@ -759,7 +759,7 @@ static void mmci_start_data(struct mmci_host *host, struct mmc_data *data) data-bytes_xfered = 0; clks = (unsigned long long)data-timeout_ns * host-cclk; - do_div(clks, 10UL); + do_div(clks, NSEC_PER_SEC); timeout = data-timeout_clks + (unsigned int)clks; -- 1.7.9.5 -- To unsubscribe from this list: send the line unsubscribe linux-arm-msm in the body of a message to majord...@vger.kernel.org More majordomo info at http://vger.kernel.org/majordomo-info.html
[PATCH v1 04/11] mmc: mmci: Add register read/write wrappers.
From: Srinivas Kandagatla srinivas.kandaga...@linaro.org This patch adds wrappers for readl/writel functions used in the driver. The reason for this wrappers is to accommodate SOCs like Qualcomm which has requirement for delaying the write for few cycles when writing to its SD Card Controller registers. Signed-off-by: Srinivas Kandagatla srinivas.kandaga...@linaro.org --- drivers/mmc/host/mmci.c | 114 +-- 1 file changed, 61 insertions(+), 53 deletions(-) diff --git a/drivers/mmc/host/mmci.c b/drivers/mmc/host/mmci.c index 19d6b6f..36db31e 100644 --- a/drivers/mmc/host/mmci.c +++ b/drivers/mmc/host/mmci.c @@ -171,6 +171,16 @@ static struct variant_data variant_qcom = { .pwrreg_powerup = MCI_PWR_UP, }; +static inline u32 mmci_readl(struct mmci_host *host, u32 off) +{ + return readl(host-base + off); +} + +static inline void mmci_writel(struct mmci_host *host, u32 data, u32 off) +{ + writel(data, host-base + off); +} + static int mmci_card_busy(struct mmc_host *mmc) { struct mmci_host *host = mmc_priv(mmc); @@ -180,7 +190,7 @@ static int mmci_card_busy(struct mmc_host *mmc) pm_runtime_get_sync(mmc_dev(mmc)); spin_lock_irqsave(host-lock, flags); - if (readl(host-base + MMCISTATUS) MCI_ST_CARDBUSY) + if (mmci_readl(host, MMCISTATUS) MCI_ST_CARDBUSY) busy = 1; spin_unlock_irqrestore(host-lock, flags); @@ -230,7 +240,7 @@ static void mmci_write_clkreg(struct mmci_host *host, u32 clk) { if (host-clk_reg != clk) { host-clk_reg = clk; - writel(clk, host-base + MMCICLOCK); + mmci_writel(host, clk, MMCICLOCK); } } @@ -241,7 +251,7 @@ static void mmci_write_pwrreg(struct mmci_host *host, u32 pwr) { if (host-pwr_reg != pwr) { host-pwr_reg = pwr; - writel(pwr, host-base + MMCIPOWER); + mmci_writel(host, pwr, MMCIPOWER); } } @@ -255,7 +265,7 @@ static void mmci_write_datactrlreg(struct mmci_host *host, u32 datactrl) if (host-datactrl_reg != datactrl) { host-datactrl_reg = datactrl; - writel(datactrl, host-base + MMCIDATACTRL); + mmci_writel(host, datactrl, MMCIDATACTRL); } } @@ -321,7 +331,7 @@ static void mmci_set_clkreg(struct mmci_host *host, unsigned int desired) static void mmci_request_end(struct mmci_host *host, struct mmc_request *mrq) { - writel(0, host-base + MMCICOMMAND); + mmci_writel(host, 0, MMCICOMMAND); BUG_ON(host-data); @@ -336,18 +346,16 @@ mmci_request_end(struct mmci_host *host, struct mmc_request *mrq) static void mmci_set_mask1(struct mmci_host *host, unsigned int mask) { - void __iomem *base = host-base; - if (host-singleirq) { - unsigned int mask0 = readl(base + MMCIMASK0); + unsigned int mask0 = mmci_readl(host, MMCIMASK0); mask0 = ~MCI_IRQ1MASK; mask0 |= mask; - writel(mask0, base + MMCIMASK0); + mmci_writel(host, mask0, MMCIMASK0); } - writel(mask, base + MMCIMASK1); + mmci_writel(host, mask, MMCIMASK1); } static void mmci_stop_data(struct mmci_host *host) @@ -498,7 +506,7 @@ static void mmci_dma_finalize(struct mmci_host *host, struct mmc_data *data) /* Wait up to 1ms for the DMA to complete */ for (i = 0; ; i++) { - status = readl(host-base + MMCISTATUS); + status = mmci_readl(host, MMCISTATUS); if (!(status MCI_RXDATAAVLBLMASK) || i = 100) break; udelay(10); @@ -637,8 +645,8 @@ static int mmci_dma_start_data(struct mmci_host *host, unsigned int datactrl) * to fire next DMA request. When that happens, MMCI will * call mmci_data_end() */ - writel(readl(host-base + MMCIMASK0) | MCI_DATAENDMASK, - host-base + MMCIMASK0); + mmci_writel(host, mmci_readl(host, MMCIMASK0) | MCI_DATAENDMASK, + MMCIMASK0); return 0; } @@ -756,8 +764,8 @@ static void mmci_start_data(struct mmci_host *host, struct mmc_data *data) timeout = data-timeout_clks + (unsigned int)clks; base = host-base; - writel(timeout, base + MMCIDATATIMER); - writel(host-size, base + MMCIDATALENGTH); + mmci_writel(host, timeout, MMCIDATATIMER); + mmci_writel(host, host-size, MMCIDATALENGTH); blksz_bits = ffs(data-blksz) - 1; BUG_ON(1 blksz_bits != data-blksz); @@ -831,20 +839,19 @@ static void mmci_start_data(struct mmci_host *host, struct mmc_data *data) } mmci_write_datactrlreg(host, datactrl); - writel(readl(base + MMCIMASK0) ~MCI_DATAENDMASK, base + MMCIMASK0); + mmci_writel(host, mmci_readl(host, MMCIMASK0) ~MCI_DATAENDMASK, + MMCIMASK0
[PATCH v1 03/11] mmc: mmci: Add Qcom datactrl register variant
From: Srinivas Kandagatla srinivas.kandaga...@linaro.org Instance of this IP on Qualcomm's SOCs has bit different layout for datactrl register. Bit postion datactrl[16:4] hold the true block size instead of power of 2. Signed-off-by: Srinivas Kandagatla srinivas.kandaga...@linaro.org --- drivers/mmc/host/mmci.c |6 ++ 1 file changed, 6 insertions(+) diff --git a/drivers/mmc/host/mmci.c b/drivers/mmc/host/mmci.c index 391e8d4..19d6b6f 100644 --- a/drivers/mmc/host/mmci.c +++ b/drivers/mmc/host/mmci.c @@ -58,6 +58,8 @@ static unsigned int fmax = 515633; * @sdio: variant supports SDIO * @st_clkdiv: true if using a ST-specific clock divider algorithm * @blksz_datactrl16: true if Block size is at b16..b30 position in datactrl register + * @blksz_datactrl4: true if Block size is at b4..b16 position in datactrl + * register * @pwrreg_powerup: power up value for MMCIPOWER register * @signal_direction: input/out direction of bus signals can be indicated * @pwrreg_clkgate: MMCIPOWER register must be used to gate the clock @@ -73,6 +75,7 @@ struct variant_data { boolsdio; boolst_clkdiv; boolblksz_datactrl16; + boolblksz_datactrl4; u32 pwrreg_powerup; boolsignal_direction; boolpwrreg_clkgate; @@ -162,6 +165,7 @@ static struct variant_data variant_qcom = { .fifosize = 16 * 4, .fifohalfsize = 8 * 4, .clkreg = MCI_CLK_ENABLE, + .blksz_datactrl4= true, .datalength_bits= 24, .blksz_datactrl4= true, .pwrreg_powerup = MCI_PWR_UP, @@ -760,6 +764,8 @@ static void mmci_start_data(struct mmci_host *host, struct mmc_data *data) if (variant-blksz_datactrl16) datactrl = MCI_DPSM_ENABLE | (data-blksz 16); + else if (variant-blksz_datactrl4) + datactrl = MCI_DPSM_ENABLE | (data-blksz 4); else datactrl = MCI_DPSM_ENABLE | blksz_bits 4; -- 1.7.9.5 -- To unsubscribe from this list: send the line unsubscribe linux-arm-msm in the body of a message to majord...@vger.kernel.org More majordomo info at http://vger.kernel.org/majordomo-info.html
Re: [PATCH v1 00/11] Add Qualcomm SD Card Controller support.
Thanks Bjorn for testing it on msm8960 SOC. On 09/05/14 10:56, Bjorn Andersson wrote: On Tue, Apr 29, 2014 at 1:18 AM, srinivas.kandaga...@linaro.org wrote: [...] This patch series adds Qualcomm SD Card Controller support in pl180 mmci driver. QCom SDCC is basically a pl180, but bit more customized, some of the register layouts and offsets are different to the ones mentioned in pl180 datasheet. The plan is to totally remove the standalone SDCC driver drivers/mmc/host/msm_sdcc.* and start using generic mmci driver for all Qualcomm parts, as we get chance to test on other Qcom boards. Hi Srinivas, I think your series looks good, so I pulled it into my tree and combined with some input from [1] I got this up and running on Sony Xperia T (msm8960 based). I do get below prints in dmesg during probe, mount and some initial accesses; but the code seems to retry the operations and things work out nicely. Great.. Could I add your Ack on these series? [ 193.556540] mmcblk0: response CRC error sending r/w cmd command, card status 0xb00 I could not reproduce this issue with APQ8064 based IFC6410 board. I will keep testing on other boards as on when they are available. Am hoping that we could get this support for v3.16 PS. please send the patch enabling AMBA to Kumar as well. Sure I will send this patch to Kumar. [1] https://git.linaro.org/landing-teams/working/qualcomm/kernel.git/commitdiff/14ea2f1dc5bb719dbfb943e2c700ac166a8c125a Regards, Bjorn thanks, srini -- To unsubscribe from this list: send the line unsubscribe linux-arm-msm in the body of a message to majord...@vger.kernel.org More majordomo info at http://vger.kernel.org/majordomo-info.html
[PATCH] clk: qcom: add clocks necessary for apq8064 sdcc
From: Srinivas Kandagatla srinivas.kandaga...@linaro.org This patch adds clocks necessary for SD card controller on apq8064 SOC. Without this patch the clocks are visible to the sdcc driver. Signed-off-by: Srinivas Kandagatla srinivas.kandaga...@linaro.org --- drivers/clk/qcom/gcc-msm8960.c | 10 ++ 1 file changed, 10 insertions(+) diff --git a/drivers/clk/qcom/gcc-msm8960.c b/drivers/clk/qcom/gcc-msm8960.c index f4ffd91..9bd3238 100644 --- a/drivers/clk/qcom/gcc-msm8960.c +++ b/drivers/clk/qcom/gcc-msm8960.c @@ -2876,6 +2876,16 @@ static struct clk_regmap *gcc_apq8064_clks[] = { [GSBI7_QUP_SRC] = gsbi7_qup_src.clkr, [GSBI7_QUP_CLK] = gsbi7_qup_clk.clkr, [GSBI7_H_CLK] = gsbi7_h_clk.clkr, + [SDC1_SRC] = sdc1_src.clkr, + [SDC1_CLK] = sdc1_clk.clkr, + [SDC2_SRC] = sdc2_src.clkr, + [SDC2_CLK] = sdc2_clk.clkr, + [SDC3_SRC] = sdc3_src.clkr, + [SDC3_CLK] = sdc3_clk.clkr, + [SDC4_SRC] = sdc4_src.clkr, + [SDC4_CLK] = sdc4_clk.clkr, + [SDC5_SRC] = sdc5_src.clkr, + [SDC5_CLK] = sdc5_clk.clkr, }; static const struct regmap_config gcc_msm8960_regmap_config = { -- 1.9.1 -- To unsubscribe from this list: send the line unsubscribe linux-arm-msm in the body of a message to majord...@vger.kernel.org More majordomo info at http://vger.kernel.org/majordomo-info.html
[PATCH] ARM: DT: apq8064: Add sdcc support via mcci driver.
From: Srinivas Kandagatla srinivas.kandaga...@linaro.org This patch adds support to SD card controller using generic pl180 mmci driver. This patch also adds temporary fixed regulator to get it going till the actual regulator is mainlined. Signed-off-by: Srinivas Kandagatla srinivas.kandaga...@linaro.org --- arch/arm/boot/dts/qcom-apq8064-ifc6410.dts | 16 ++ arch/arm/boot/dts/qcom-apq8064.dtsi| 50 ++ 2 files changed, 66 insertions(+) diff --git a/arch/arm/boot/dts/qcom-apq8064-ifc6410.dts b/arch/arm/boot/dts/qcom-apq8064-ifc6410.dts index c5fda40..ea386bd 100644 --- a/arch/arm/boot/dts/qcom-apq8064-ifc6410.dts +++ b/arch/arm/boot/dts/qcom-apq8064-ifc6410.dts @@ -4,9 +4,25 @@ model = Qualcomm APQ8064/IFC6410; compatible = qcom,apq8064-ifc6410, qcom,apq8064; + aliases { + sdcc1 = sdcc1; + sdcc3 = sdcc3; + }; + soc { serial@1664 { status = ok; }; + amba { + /* eMMC */ + sdcc1: sdcc@1240 { + status = okay; + }; + + /* External micro SD card */ + sdcc3: sdcc@1218 { + status = okay; + }; + }; }; }; diff --git a/arch/arm/boot/dts/qcom-apq8064.dtsi b/arch/arm/boot/dts/qcom-apq8064.dtsi index 60b89e5..640fb1d 100644 --- a/arch/arm/boot/dts/qcom-apq8064.dtsi +++ b/arch/arm/boot/dts/qcom-apq8064.dtsi @@ -2,6 +2,7 @@ /include/ skeleton.dtsi +#include dt-bindings/interrupt-controller/arm-gic.h #include dt-bindings/clock/qcom,gcc-msm8960.h / { @@ -147,5 +148,54 @@ #clock-cells = 1; #reset-cells = 1; }; + + /* Temporary fixed regulator */ + vsdcc_fixed: vsdcc-regulator { + compatible = regulator-fixed; + regulator-name = SDCC Power; + regulator-min-microvolt = 270; + regulator-max-microvolt = 270; + regulator-always-on; + }; + + amba { + compatible = arm,amba-bus; + #address-cells = 1; + #size-cells = 1; + ranges; + sdcc1: sdcc@1240 { + status = disabled; + compatible = arm,pl18x, arm,primecell; + arm,primecell-periphid = 0x00051180; + reg = 0x1240 0x8000; + interrupts = GIC_SPI 104 IRQ_TYPE_LEVEL_HIGH; + interrupt-names = cmd_irq; + clocks = gcc SDC1_CLK, gcc SDC1_H_CLK; + clock-names = mclk, apb_pclk; + bus-width = 8; + max-frequency = 9600; + non-removable; + cap-sd-highspeed; + cap-mmc-highspeed; + vmmc-supply = vsdcc_fixed; + }; + + sdcc3: sdcc@1218 { + compatible = arm,pl18x, arm,primecell; + arm,primecell-periphid = 0x00051180; + status = disabled; + reg = 0x1218 0x8000; + interrupts = GIC_SPI 102 IRQ_TYPE_LEVEL_HIGH; + interrupt-names = cmd_irq; + clocks = gcc SDC3_CLK, gcc SDC3_H_CLK; + clock-names = mclk, apb_pclk; + bus-width = 4; + cap-sd-highspeed; + cap-mmc-highspeed; + max-frequency = 19200; + no-1-8-v; + vmmc-supply = vsdcc_fixed; + }; + }; }; }; -- 1.9.1 -- To unsubscribe from this list: send the line unsubscribe linux-arm-msm in the body of a message to majord...@vger.kernel.org More majordomo info at http://vger.kernel.org/majordomo-info.html
Re: [PATCH] clk: qcom: add clocks necessary for apq8064 sdcc
On 09/05/14 12:21, Kumar Gala wrote: There are only 4 SDCs on APQ8064 You are right.. Will fix it in next version. thanks, srini -- To unsubscribe from this list: send the line unsubscribe linux-arm-msm in the body of a message to majord...@vger.kernel.org More majordomo info at http://vger.kernel.org/majordomo-info.html
[PATCH v2] clk: qcom: add clocks necessary for apq8064 sdcc
From: Srinivas Kandagatla srinivas.kandaga...@linaro.org This patch adds clocks necessary for SD card controller on apq8064 SOC. Without this patch the clocks are visible to the sdcc driver. Signed-off-by: Srinivas Kandagatla srinivas.kandaga...@linaro.org --- drivers/clk/qcom/gcc-msm8960.c | 8 1 file changed, 8 insertions(+) diff --git a/drivers/clk/qcom/gcc-msm8960.c b/drivers/clk/qcom/gcc-msm8960.c index f4ffd91..c47a758 100644 --- a/drivers/clk/qcom/gcc-msm8960.c +++ b/drivers/clk/qcom/gcc-msm8960.c @@ -2876,6 +2876,14 @@ static struct clk_regmap *gcc_apq8064_clks[] = { [GSBI7_QUP_SRC] = gsbi7_qup_src.clkr, [GSBI7_QUP_CLK] = gsbi7_qup_clk.clkr, [GSBI7_H_CLK] = gsbi7_h_clk.clkr, + [SDC1_SRC] = sdc1_src.clkr, + [SDC1_CLK] = sdc1_clk.clkr, + [SDC2_SRC] = sdc2_src.clkr, + [SDC2_CLK] = sdc2_clk.clkr, + [SDC3_SRC] = sdc3_src.clkr, + [SDC3_CLK] = sdc3_clk.clkr, + [SDC4_SRC] = sdc4_src.clkr, + [SDC4_CLK] = sdc4_clk.clkr, }; static const struct regmap_config gcc_msm8960_regmap_config = { -- 1.9.1 -- To unsubscribe from this list: send the line unsubscribe linux-arm-msm in the body of a message to majord...@vger.kernel.org More majordomo info at http://vger.kernel.org/majordomo-info.html
Re: [PATCH v1 02/11] mmc: mmci: Add Qualcomm Id to amba id table
Thanks Linus W. On 13/05/14 08:17, Linus Walleij wrote: On Tue, Apr 29, 2014 at 10:19 AM, srinivas.kandaga...@linaro.org wrote: From: Srinivas Kandagatla srinivas.kandaga...@linaro.org This patch adds a fake Qualcomm ID 0x00051180 to the amba_ids, as Qualcomm SDCC controller is pl180, but amba id registers read 0x0's. The plan is to remove SDCC driver totally and use mmci as the main SD controller driver for Qualcomm SOCs. Signed-off-by: Srinivas Kandagatla srinivas.kandaga...@linaro.org Reviewed-by: Linus Walleij linus.wall...@linaro.org -- To unsubscribe from this list: send the line unsubscribe linux-arm-msm in the body of a message to majord...@vger.kernel.org More majordomo info at http://vger.kernel.org/majordomo-info.html
Re: [PATCH v1 05/11] mmc: mmci: use NSEC_PER_SEC macro
On 13/05/14 08:20, Linus Walleij wrote: On Tue, Apr 29, 2014 at 10:20 AM, srinivas.kandaga...@linaro.org wrote: From: Srinivas Kandagatla srinivas.kandaga...@linaro.org This patch replaces a constant used in calculating timeout with a proper macro. This is make code more readable. Signed-off-by: Srinivas Kandagatla srinivas.kandaga...@linaro.org Reviewed-by: Linus Walleij linus.wall...@linaro.org This can be merged out-of-order just as-is. Agreed, I can take this patch out of this series. thanks, srini Yours, Linus Walleij -- To unsubscribe from this list: send the line unsubscribe linux-arm-msm in the body of a message to majord...@vger.kernel.org More majordomo info at http://vger.kernel.org/majordomo-info.html
Re: [PATCH v1 06/11] mmc: mmci: Qcomm: Add 3 clock cycle delay after register write
Thanks Linus W for reviewing the patches. On 13/05/14 08:29, Linus Walleij wrote: On Tue, Apr 29, 2014 at 10:20 AM, srinivas.kandaga...@linaro.org wrote: From: Srinivas Kandagatla srinivas.kandaga...@linaro.org Most of the Qcomm SD card controller registers must be updated to the MCLK domain so subsequent writes to registers will be ignored until 3 clock cycles have passed. This patch adds a 3 clock cycle delay required after writing to controller registers on Qualcomm SOCs. Without this delay all the register writes are not successfull, resulting in not detecting cards. Signed-off-by: Srinivas Kandagatla srinivas.kandaga...@linaro.org Sounds like someone decided to clock the internal state machine in the MMCI using MCLK instead of PCLK :-( A bit nasty if this ends up in the fastpath (irq) though. Which it invariably does, right? yes, Its going to for Qcom SOC. + /* +* On QCom SD card controller, registers must be updated to the +* MCLK domain so subsequent writes to this register will be ignored +* for 3 clk cycles. +*/ + if (host-hw_designer == AMBA_VENDOR_QCOM) + udelay(1 + ((3 * USEC_PER_SEC)/host-mclk)); Add a new field in vendor data instead, and use DIV_ROUND_UP(): yes, that makes sense.. static struct variant_data variant_qcom = { .mclk_delayed_writes = true, (...) if (host-vendor-mclk_delayed_writes) udelay(DIV_ROUND_UP((3 * USEC_PER_SEC), host-mclk)); You get the idea. Got it. Yours, Linus Walleij -- To unsubscribe from this list: send the line unsubscribe linux-arm-msm in the body of a message to majord...@vger.kernel.org More majordomo info at http://vger.kernel.org/majordomo-info.html
Re: [PATCH v1 07/11] mmc: mmci: move ST specific register extensions access under condition.
On 13/05/14 09:08, Linus Walleij wrote: /* Keep ST Micro busy mode if enabled */ - datactrl |= host-datactrl_reg MCI_ST_DPSM_BUSYMODE; + if (host-hw_designer == AMBA_VENDOR_ST) + datactrl |= host-datactrl_reg MCI_ST_DPSM_BUSYMODE; Do not hard-check the hw_designer everywhere, follow the pattern if storing special stuff in the variant data. Got it, I will fix this across other patches too. struct variant_data { u32 datactrl_mask_busymode; (...) static struct variant_data variant_u300 = { .datactrl_mask_busymode = MCI_ST_DPSM_BUSYMODE, (...) static struct variant_data variant_nomadik = { -- To unsubscribe from this list: send the line unsubscribe linux-arm-msm in the body of a message to majord...@vger.kernel.org More majordomo info at http://vger.kernel.org/majordomo-info.html
Re: [PATCH v1 09/11] mmc: mmci: Add clock support for Qualcomm.
Thanks Linus W, On 13/05/14 09:28, Linus Walleij wrote: code is conditioned on hw designer. Signed-off-by: Srinivas Kandagatla srinivas.kandaga...@linaro.org (...) + if (host-hw_designer == AMBA_VENDOR_QCOM) { + host-cclk = host-mclk; + } else if (desired = host-mclk) { Again refrain from hard-checking the vendor everywhere. struct variant_data { boolqcom_cclk_is_mclk; (...) Got it.. Will fix it in next version. As per example from st_clkdiv... Then if (host-vendor-qcom_cclk_is_mclk) { (...) } + if (ios-clock != host-mclk + host-hw_designer == AMBA_VENDOR_QCOM) { + /* Qcom MCLKCLK register does not define bypass bits */ + int rc = clk_set_rate(host-clk, ios-clock); + if (rc 0) { + dev_err(mmc_dev(host-mmc), + Error setting clock rate (%d)\n, rc); + } else { + host-mclk = clk_get_rate(host-clk); + host-cclk = host-mclk; + } + } For this I would define a vendor data like: struct variant_data { boolexplicit_mclk_control; (...) This looks good. Or something. It explains what is actually going on. if (plat-f_max) - mmc-f_max = min(host-mclk, plat-f_max); + mmc-f_max = (host-hw_designer == AMBA_VENDOR_QCOM) ? + plat-f_max : min(host-mclk, plat-f_max); So rewrite like that: if (host-vendor-explicit_mclk_control) mmc-f_max = plat-f_max; else mmc-f_max = min(host-mclk, plat-f_max); This looks much clean Yours, Linus Walleij -- To unsubscribe from this list: send the line unsubscribe linux-arm-msm in the body of a message to majord...@vger.kernel.org More majordomo info at http://vger.kernel.org/majordomo-info.html
Re: [PATCH v1 01/11] ARM: amba: Add Qualcomm vendor ID.
Thanks Linus W, On 13/05/14 08:16, Linus Walleij wrote: On Tue, Apr 29, 2014 at 10:19 AM, srinivas.kandaga...@linaro.org wrote: From: Srinivas Kandagatla srinivas.kandaga...@linaro.org This patch adds Qualcomm amba vendor Id to the list. This ID is used in mmci driver. Signed-off-by: Srinivas Kandagatla srinivas.kandaga...@linaro.org (...) + AMBA_VENDOR_QCOM = 0x51, Yeah it's a Q, like 0x41 is A for ARM. You could as well mention this in the commit message. Sounds good, I will fix it in next version and send it to Russell's patch tracker. --srini And you can probably just put this patch into Russell's patch tracker already. Acked-by: Linus Walleij linus.wall...@linaro.org Yours, Linus Walleij -- To unsubscribe from this list: send the line unsubscribe linux-arm-msm in the body of a message to majord...@vger.kernel.org More majordomo info at http://vger.kernel.org/majordomo-info.html
Re: [PATCH v1 00/11] Add Qualcomm SD Card Controller support.
On 13/05/14 11:04, Ulf Hansson wrote: On 29 April 2014 10:18, srinivas.kandaga...@linaro.org wrote: From: Srinivas Kandagatla srinivas.kandaga...@linaro.org Hi Russell, This patch series adds Qualcomm SD Card Controller support in pl180 mmci driver. QCom SDCC is basically a pl180, but bit more customized, some of the register layouts and offsets are different to the ones mentioned in pl180 datasheet. The plan is to totally remove the standalone SDCC driver drivers/mmc/host/msm_sdcc.* and start using generic mmci driver for all Qualcomm parts, as we get chance to test on other Qcom boards. To start using the existing mmci driver, a fake amba id for Qualcomm is added in patches: ARM: amba: Add Qualcomm vendor ID. mmc: mmci: Add Qualcomm Id to amba id table. Second change is, adding a 3 clock cycle delay for register writes on QCOM SDCC registers, which is done in patches: mmc: mmci: Add register read/write wrappers. mmc: mmci: Qcomm: Add 3 clock cycle delay after each register write Third change was to accommodate DATCTRL and MMCICLK register layout changes in Qcom SDCC. Which is done in patches: mmc: mmci: Add Qcom datactrl register variant mmc: mmci: Add Qcom variations to MCICommand register. mmc: mmci: Qcom fix MCICLK register settings. mmc: mmci: Add clock support for Qualcomm. Fourth major change was to add qcom specfic pio read function, the need for this is because the way MCIFIFOCNT register behaved in QCOM SDCC is very different to the one in pl180. This change is done in patch: mmc: mmci: Add Qcom specific pio_read function. Last some Qcom unrelated changes to support Qcom are done in patches: mmc: mmci: use NSEC_PER_SEC macro mmc: mmci: move ST specific register extensions access under condition. This patches are tested v3.15-rc3 in PIO mode on IFC6410 board with both eMMC and external SD card. I would appreciate any feedback on the patches. I would like to get this for v3.16. Thanks, srini Hi Srinivas, Hi Ulf, Thanks for working on this patchset, much appreciated! I intend to review them as soon as I can. Thats Great. For your information, currently there are one patch queued via Chris' mmc tree for mmci and recently I have added my quite extensive patchset, via mine mmc tree, all to be tested in Linux next. I suppose the best approach to not hit conflicts would be if you base your patches upon my tree. Potentially we could merge them this way, unless of course Russell have other opinions. git://git.linaro.org/people/ulf.hansson/mmc.git next Makes sense, I will rebase my next version of patches on top of your mmc git tree, if Russell has no issues with this approach. Thanks, srini Kind regards Ulf Hansson -- To unsubscribe from this list: send the line unsubscribe linux-arm-msm in the body of a message to majord...@vger.kernel.org More majordomo info at http://vger.kernel.org/majordomo-info.html
Re: [PATCH v1 01/11] ARM: amba: Add Qualcomm vendor ID.
On 13/05/14 23:13, Stephen Boyd wrote: On 05/13, Srinivas Kandagatla wrote: Thanks Linus W, On 13/05/14 08:16, Linus Walleij wrote: On Tue, Apr 29, 2014 at 10:19 AM, srinivas.kandaga...@linaro.org wrote: From: Srinivas Kandagatla srinivas.kandaga...@linaro.org This patch adds Qualcomm amba vendor Id to the list. This ID is used in mmci driver. Signed-off-by: Srinivas Kandagatla srinivas.kandaga...@linaro.org (...) + AMBA_VENDOR_QCOM = 0x51, Yeah it's a Q, like 0x41 is A for ARM. You could as well mention this in the commit message. Sounds good, I will fix it in next version and send it to Russell's patch tracker. Please add a note that this id is fake in the commit text or in the code as well. Sure, I will add it in commit text. -- To unsubscribe from this list: send the line unsubscribe linux-arm-msm in the body of a message to majord...@vger.kernel.org More majordomo info at http://vger.kernel.org/majordomo-info.html
[PATCH v2 01/14] mmc: mmci: use NSEC_PER_SEC macro
From: Srinivas Kandagatla srinivas.kandaga...@linaro.org This patch replaces a constant used in calculating timeout with a proper macro. This is make code more readable. Signed-off-by: Srinivas Kandagatla srinivas.kandaga...@linaro.org Reviewed-by: Linus Walleij linus.wall...@linaro.org --- drivers/mmc/host/mmci.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/drivers/mmc/host/mmci.c b/drivers/mmc/host/mmci.c index a084edd..a38e714 100644 --- a/drivers/mmc/host/mmci.c +++ b/drivers/mmc/host/mmci.c @@ -718,7 +718,7 @@ static void mmci_start_data(struct mmci_host *host, struct mmc_data *data) data-bytes_xfered = 0; clks = (unsigned long long)data-timeout_ns * host-cclk; - do_div(clks, 10UL); + do_div(clks, NSEC_PER_SEC); timeout = data-timeout_clks + (unsigned int)clks; -- 1.9.1 -- To unsubscribe from this list: send the line unsubscribe linux-arm-msm in the body of a message to majord...@vger.kernel.org More majordomo info at http://vger.kernel.org/majordomo-info.html
[PATCH v2 14/14] mmc: mmci: Add Qcom specific pio_read function.
From: Srinivas Kandagatla srinivas.kandaga...@linaro.org MCIFIFOCNT register behaviour on Qcom chips is very different than the other pl180 integrations. MCIFIFOCNT register contains the number of words that are still waiting to be transferred through the FIFO. It keeps decrementing once the host CPU reads the MCIFIFO. With the existing logic and the MCIFIFOCNT behaviour, mmci_pio_read will loop forever, as the FIFOCNT register will always return transfer size before reading the FIFO. Also the data sheet states that This register is only useful for debug purposes and should not be used for normal operation since it does not reflect data which may or may not be in the pipeline. This patch implements qcom_pio_read function so as existing mmci_pio_read is not suitable for Qcom SOCs. qcom_pio_read function is only selected based on qcom_fifo flag in variant data structure. Signed-off-by: Srinivas Kandagatla srinivas.kandaga...@linaro.org --- drivers/mmc/host/mmci.c | 35 +-- 1 file changed, 33 insertions(+), 2 deletions(-) diff --git a/drivers/mmc/host/mmci.c b/drivers/mmc/host/mmci.c index cf58fec1..94b99d6 100644 --- a/drivers/mmc/host/mmci.c +++ b/drivers/mmc/host/mmci.c @@ -77,6 +77,7 @@ static unsigned int fmax = 515633; * are not ignored. * @explicit_mclk_control: enable explicit mclk control in driver. * @qcom_cclk_is_mclk: enable iff card clock is multimedia card adapter clock. + * @qcom_fifo: enables qcom specific fifo pio read function. */ struct variant_data { unsigned intclkreg; @@ -101,6 +102,7 @@ struct variant_data { boolmclk_delayed_writes; boolexplicit_mclk_control; boolqcom_cclk_is_mclk; + boolqcom_fifo; }; static struct variant_data variant_arm = { @@ -211,6 +213,7 @@ static struct variant_data variant_qcom = { .mclk_delayed_writes= true, .explicit_mclk_control = true, .qcom_cclk_is_mclk = true, + .qcom_fifo = true, }; static inline u32 mmci_readl(struct mmci_host *host, u32 off) @@ -1026,6 +1029,29 @@ mmci_cmd_irq(struct mmci_host *host, struct mmc_command *cmd, } } +static int mmci_qcom_pio_read(struct mmci_host *host, char *buffer, +unsigned int remain) +{ + uint32_t*ptr = (uint32_t *) buffer; + int count = 0; + struct variant_data *variant = host-variant; + int fifo_size = variant-fifosize; + + if (remain % 4) + remain = ((remain 2) + 1) 2; + + while (readl(host-base + MMCISTATUS) MCI_RXDATAAVLBL) { + *ptr = readl(host-base + MMCIFIFO + (count % fifo_size)); + ptr++; + count += sizeof(uint32_t); + + remain -= sizeof(uint32_t); + if (remain == 0) + break; + } + return count; +} + static int mmci_pio_read(struct mmci_host *host, char *buffer, unsigned int remain) { void __iomem *base = host-base; @@ -1147,8 +1173,13 @@ static irqreturn_t mmci_pio_irq(int irq, void *dev_id) remain = sg_miter-length; len = 0; - if (status MCI_RXACTIVE) - len = mmci_pio_read(host, buffer, remain); + if (status MCI_RXACTIVE) { + if (variant-qcom_fifo) + len = mmci_qcom_pio_read(host, buffer, remain); + else + len = mmci_pio_read(host, buffer, remain); + } + if (status MCI_TXACTIVE) len = mmci_pio_write(host, buffer, remain, status); -- 1.9.1 -- To unsubscribe from this list: send the line unsubscribe linux-arm-msm in the body of a message to majord...@vger.kernel.org More majordomo info at http://vger.kernel.org/majordomo-info.html
[PATCH v2 13/14] mmc: mmci: add qcom specific clk control
From: Srinivas Kandagatla srinivas.kandaga...@linaro.org On Qcom SD card controller, cclk is mclk and mclk should be directly controlled by the driver. This patch adds support to control mclk directly in the driver, and also adds explicit_mclk_control and cclk_is_mclk flags in variant structure giving more flexibility to the driver. Signed-off-by: Srinivas Kandagatla srinivas.kandaga...@linaro.org --- drivers/mmc/host/mmci.c | 30 +- 1 file changed, 25 insertions(+), 5 deletions(-) diff --git a/drivers/mmc/host/mmci.c b/drivers/mmc/host/mmci.c index bc7b80d..cf58fec1 100644 --- a/drivers/mmc/host/mmci.c +++ b/drivers/mmc/host/mmci.c @@ -75,6 +75,8 @@ static unsigned int fmax = 515633; * @pwrreg_nopower: bits in MMCIPOWER don't controls ext. power supply * @mclk_delayed_writes: enable delayed writes to ensure, subsequent updates * are not ignored. + * @explicit_mclk_control: enable explicit mclk control in driver. + * @qcom_cclk_is_mclk: enable iff card clock is multimedia card adapter clock. */ struct variant_data { unsigned intclkreg; @@ -97,6 +99,8 @@ struct variant_data { boolbusy_detect; boolpwrreg_nopower; boolmclk_delayed_writes; + boolexplicit_mclk_control; + boolqcom_cclk_is_mclk; }; static struct variant_data variant_arm = { @@ -205,6 +209,8 @@ static struct variant_data variant_qcom = { * for 3 clk cycles. */ .mclk_delayed_writes= true, + .explicit_mclk_control = true, + .qcom_cclk_is_mclk = true, }; static inline u32 mmci_readl(struct mmci_host *host, u32 off) @@ -320,7 +326,9 @@ static void mmci_set_clkreg(struct mmci_host *host, unsigned int desired) host-cclk = 0; if (desired) { - if (desired = host-mclk) { + if (variant-qcom_cclk_is_mclk) { + host-cclk = host-mclk; + } else if (desired = host-mclk) { clk = MCI_CLK_BYPASS; if (variant-st_clkdiv) clk |= MCI_ST_UX500_NEG_EDGE; @@ -1358,6 +1366,16 @@ static void mmci_set_ios(struct mmc_host *mmc, struct mmc_ios *ios) if (!ios-clock variant-pwrreg_clkgate) pwr = ~MCI_PWR_ON; + if (ios-clock != host-mclk host-variant-explicit_mclk_control) { + int rc = clk_set_rate(host-clk, ios-clock); + if (rc 0) { + dev_err(mmc_dev(host-mmc), + Error setting clock rate (%d)\n, rc); + } else { + host-mclk = clk_get_rate(host-clk); + } + } + spin_lock_irqsave(host-lock, flags); mmci_set_clkreg(host, ios-clock); @@ -1544,10 +1562,12 @@ static int mmci_probe(struct amba_device *dev, * is not specified. Either value must not exceed the clock rate into * the block, of course. */ - if (mmc-f_max) - mmc-f_max = min(host-mclk, mmc-f_max); - else - mmc-f_max = min(host-mclk, fmax); + if (!host-variant-explicit_mclk_control) { + if (mmc-f_max) + mmc-f_max = min(host-mclk, mmc-f_max); + else + mmc-f_max = min(host-mclk, fmax); + } dev_dbg(mmc_dev(mmc), clocking block at %u Hz\n, mmc-f_max); /* Get regulators and the supported OCR mask */ -- 1.9.1 -- To unsubscribe from this list: send the line unsubscribe linux-arm-msm in the body of a message to majord...@vger.kernel.org More majordomo info at http://vger.kernel.org/majordomo-info.html
[PATCH v2 08/14] mmc: mmci: add 8bit bus support in variant data
From: Srinivas Kandagatla srinivas.kandaga...@linaro.org This patch adds 8bit bus enable to variant structure giving more flexibility to the driver to support more SOCs which have different clock register layout. Without this patch other new SOCs like Qcom will have to add more code to special case them. Signed-off-by: Srinivas Kandagatla srinivas.kandaga...@linaro.org --- drivers/mmc/host/mmci.c | 7 ++- 1 file changed, 6 insertions(+), 1 deletion(-) diff --git a/drivers/mmc/host/mmci.c b/drivers/mmc/host/mmci.c index dec70d2..a81f303 100644 --- a/drivers/mmc/host/mmci.c +++ b/drivers/mmc/host/mmci.c @@ -52,6 +52,7 @@ static unsigned int fmax = 515633; * struct variant_data - MMCI variant-specific quirks * @clkreg: default value for MCICLOCK register * @clkreg_enable: enable value for MMCICLOCK register + * @clkreg_8bit_bus_enable: enable value for 8 bit bus * @datalength_bits: number of bits in the MMCIDATALENGTH register * @fifosize: number of bytes that can be written when MMCI_TXFIFOEMPTY * is asserted (likewise for RX) @@ -74,6 +75,7 @@ static unsigned int fmax = 515633; struct variant_data { unsigned intclkreg; unsigned intclkreg_enable; + unsigned intclkreg_8bit_bus_enable; unsigned intdatalength_bits; unsigned intfifosize; unsigned intfifohalfsize; @@ -116,6 +118,7 @@ static struct variant_data variant_u300 = { .fifosize = 16 * 4, .fifohalfsize = 8 * 4, .clkreg_enable = MCI_ST_U300_HWFCEN, + .clkreg_8bit_bus_enable = MCI_ST_8BIT_BUS, .datactrl_mask_ddrmode = MCI_ST_DPSM_DDRMODE, .datalength_bits= 16, .sdio = true, @@ -144,6 +147,7 @@ static struct variant_data variant_ux500 = { .fifohalfsize = 8 * 4, .clkreg = MCI_CLK_ENABLE, .clkreg_enable = MCI_ST_UX500_HWFCEN, + .clkreg_8bit_bus_enable = MCI_ST_8BIT_BUS, .datactrl_mask_ddrmode = MCI_ST_DPSM_DDRMODE, .datalength_bits= 24, .sdio = true, @@ -160,6 +164,7 @@ static struct variant_data variant_ux500v2 = { .fifohalfsize = 8 * 4, .clkreg = MCI_CLK_ENABLE, .clkreg_enable = MCI_ST_UX500_HWFCEN, + .clkreg_8bit_bus_enable = MCI_ST_8BIT_BUS, .datactrl_mask_ddrmode = MCI_ST_DPSM_DDRMODE, .datalength_bits= 24, .sdio = true, @@ -340,7 +345,7 @@ static void mmci_set_clkreg(struct mmci_host *host, unsigned int desired) if (host-mmc-ios.bus_width == MMC_BUS_WIDTH_4) clk |= MCI_4BIT_BUS; if (host-mmc-ios.bus_width == MMC_BUS_WIDTH_8) - clk |= MCI_ST_8BIT_BUS; + clk |= variant-clkreg_8bit_bus_enable; if (host-mmc-ios.timing == MMC_TIMING_UHS_DDR50) clk |= MCI_ST_UX500_NEG_EDGE; -- 1.9.1 -- To unsubscribe from this list: send the line unsubscribe linux-arm-msm in the body of a message to majord...@vger.kernel.org More majordomo info at http://vger.kernel.org/majordomo-info.html
[PATCH v2 12/14] mmc: mmci: add support for fbclk to latch data and cmd.
From: Srinivas Kandagatla srinivas.kandaga...@linaro.org This patch adds support to fbclk that is used to latch data and cmd on some controllers like SD Card controller in Qcom SOC. Signed-off-by: Srinivas Kandagatla srinivas.kandaga...@linaro.org --- drivers/mmc/host/mmci.c | 5 + 1 file changed, 5 insertions(+) diff --git a/drivers/mmc/host/mmci.c b/drivers/mmc/host/mmci.c index 05ae654..bc7b80d 100644 --- a/drivers/mmc/host/mmci.c +++ b/drivers/mmc/host/mmci.c @@ -54,6 +54,8 @@ static unsigned int fmax = 515633; * @clkreg_enable: enable value for MMCICLOCK register * @clkreg_8bit_bus_enable: enable value for 8 bit bus * @clkreg_neg_edge_enable: enable value for inverted data/cmd output + * @clkreg_fbclk_latch: enable value to select feedback clock to + * latch data and command comming in. * @datalength_bits: number of bits in the MMCIDATALENGTH register * @fifosize: number of bytes that can be written when MMCI_TXFIFOEMPTY * is asserted (likewise for RX) @@ -79,6 +81,7 @@ struct variant_data { unsigned intclkreg_enable; unsigned intclkreg_8bit_bus_enable; unsigned intclkreg_neg_edge_enable; + unsigned intclkreg_fbclk_latch; unsigned intdatalength_bits; unsigned intfifosize; unsigned intfifohalfsize; @@ -189,6 +192,7 @@ static struct variant_data variant_qcom = { .clkreg = MCI_CLK_ENABLE, .clkreg_enable = MCI_QCOM_CLK_FLOWENA, .clkreg_8bit_bus_enable = MCI_QCOM_CLK_WIDEBUS_8, + .clkreg_fbclk_latch = MCI_QCOM_CLK_FEEDBACK_CLK, .datactrl_mask_ddrmode = MCI_QCOM_CLK_DDR_MODE, .data_cmd_enable= MCI_QCOM_CSPM_DATCMD, .blksz_datactrl4= true, @@ -343,6 +347,7 @@ static void mmci_set_clkreg(struct mmci_host *host, unsigned int desired) host-cclk = host-mclk / (2 * (clk + 1)); } + clk |= variant-clkreg_fbclk_latch; clk |= variant-clkreg_enable; clk |= MCI_CLK_ENABLE; /* This hasn't proven to be worthwhile */ -- 1.9.1 -- To unsubscribe from this list: send the line unsubscribe linux-arm-msm in the body of a message to majord...@vger.kernel.org More majordomo info at http://vger.kernel.org/majordomo-info.html
[PATCH v2 10/14] mmc: mmci: add Qcom specifics of clk and datactrl registers.
From: Srinivas Kandagatla srinivas.kandaga...@linaro.org This patch adds specifics of clk and datactrl register on Qualcomm SD Card controller. This patch also populates the Qcom variant data with these new values specific to Qualcomm SD Card Controller. Signed-off-by: Srinivas Kandagatla srinivas.kandaga...@linaro.org --- drivers/mmc/host/mmci.c | 3 +++ drivers/mmc/host/mmci.h | 24 2 files changed, 27 insertions(+) diff --git a/drivers/mmc/host/mmci.c b/drivers/mmc/host/mmci.c index 17e7f6a..0a0fc22 100644 --- a/drivers/mmc/host/mmci.c +++ b/drivers/mmc/host/mmci.c @@ -185,6 +185,9 @@ static struct variant_data variant_qcom = { .fifosize = 16 * 4, .fifohalfsize = 8 * 4, .clkreg = MCI_CLK_ENABLE, + .clkreg_enable = MCI_QCOM_CLK_FLOWENA, + .clkreg_8bit_bus_enable = MCI_QCOM_CLK_WIDEBUS_8, + .datactrl_mask_ddrmode = MCI_QCOM_CLK_DDR_MODE, .blksz_datactrl4= true, .datalength_bits= 24, .blksz_datactrl4= true, diff --git a/drivers/mmc/host/mmci.h b/drivers/mmc/host/mmci.h index cd83ca3..1b93ae7 100644 --- a/drivers/mmc/host/mmci.h +++ b/drivers/mmc/host/mmci.h @@ -41,6 +41,22 @@ /* Modified PL180 on Versatile Express platform */ #define MCI_ARM_HWFCEN BIT(12) +/* Modified on Qualcomm Integrations */ +#define MCI_QCOM_CLK_WIDEBUS_4 (2 10) +#define MCI_QCOM_CLK_WIDEBUS_8 (3 10) +#define MCI_QCOM_CLK_FLOWENA BIT(12) +#define MCI_QCOM_CLK_INVERTOUT BIT(13) + +/* select in latch data and command */ +#define MCI_QCOM_CLK_SEL_IN_SHIFT (14) +#define MCI_QCOM_CLK_SEL_MASK (0x3) +#define MCI_QCOM_CLK_SEL_RISING_EDGE (1) +#define MCI_QCOM_CLK_FEEDBACK_CLK (2 14) +#define MCI_QCOM_CLK_DDR_MODE (3 14) + +/* mclk selection */ +#define MCI_QCOM_CLK_SEL_MCLK (2 23) + #define MMCIARGUMENT 0x008 #define MMCICOMMAND0x00c #define MCI_CPSM_RESPONSE BIT(6) @@ -54,6 +70,14 @@ #define MCI_ST_NIENBIT(13) #define MCI_ST_CE_ATACMD BIT(14) +/* Modified on Qualcomm Integrations */ +#define MCI_QCOM_CSPM_DATCMD BIT(12) +#define MCI_QCOM_CSPM_MCIABORT BIT(13) +#define MCI_QCOM_CSPM_CCSENABLEBIT(14) +#define MCI_QCOM_CSPM_CCSDISABLE BIT(15) +#define MCI_QCOM_CSPM_AUTO_CMD19 BIT(16) +#define MCI_QCOM_CSPM_AUTO_CMD21 BIT(21) + #define MMCIRESPCMD0x010 #define MMCIRESPONSE0 0x014 #define MMCIRESPONSE1 0x018 -- 1.9.1 -- To unsubscribe from this list: send the line unsubscribe linux-arm-msm in the body of a message to majord...@vger.kernel.org More majordomo info at http://vger.kernel.org/majordomo-info.html
[PATCH v2 07/14] mmc: mmci: add ddrmode mask to variant data
From: Srinivas Kandagatla srinivas.kandaga...@linaro.org This patch adds ddrmode mask to variant structure giving more flexibility to the driver to support more SOCs which have different datactrl register layout. Without this patch datactrl register is updated with wrong ddrmode mask on non ST SOCs, resulting in card detection failures. Signed-off-by: Srinivas Kandagatla srinivas.kandaga...@linaro.org --- drivers/mmc/host/mmci.c | 8 +++- 1 file changed, 7 insertions(+), 1 deletion(-) diff --git a/drivers/mmc/host/mmci.c b/drivers/mmc/host/mmci.c index 1385554..dec70d2 100644 --- a/drivers/mmc/host/mmci.c +++ b/drivers/mmc/host/mmci.c @@ -59,6 +59,7 @@ static unsigned int fmax = 515633; * is asserted (likewise for RX) * @sdio: variant supports SDIO * @st_clkdiv: true if using a ST-specific clock divider algorithm + * @datactrl_mask_ddrmode: ddr mode mask in datactrl register. * @blksz_datactrl16: true if Block size is at b16..b30 position in datactrl register * @blksz_datactrl4: true if Block size is at b4..b16 position in datactrl * register @@ -76,6 +77,7 @@ struct variant_data { unsigned intdatalength_bits; unsigned intfifosize; unsigned intfifohalfsize; + unsigned intdatactrl_mask_ddrmode; boolsdio; boolst_clkdiv; boolblksz_datactrl16; @@ -114,6 +116,7 @@ static struct variant_data variant_u300 = { .fifosize = 16 * 4, .fifohalfsize = 8 * 4, .clkreg_enable = MCI_ST_U300_HWFCEN, + .datactrl_mask_ddrmode = MCI_ST_DPSM_DDRMODE, .datalength_bits= 16, .sdio = true, .pwrreg_powerup = MCI_PWR_ON, @@ -126,6 +129,7 @@ static struct variant_data variant_nomadik = { .fifosize = 16 * 4, .fifohalfsize = 8 * 4, .clkreg = MCI_CLK_ENABLE, + .datactrl_mask_ddrmode = MCI_ST_DPSM_DDRMODE, .datalength_bits= 24, .sdio = true, .st_clkdiv = true, @@ -140,6 +144,7 @@ static struct variant_data variant_ux500 = { .fifohalfsize = 8 * 4, .clkreg = MCI_CLK_ENABLE, .clkreg_enable = MCI_ST_UX500_HWFCEN, + .datactrl_mask_ddrmode = MCI_ST_DPSM_DDRMODE, .datalength_bits= 24, .sdio = true, .st_clkdiv = true, @@ -155,6 +160,7 @@ static struct variant_data variant_ux500v2 = { .fifohalfsize = 8 * 4, .clkreg = MCI_CLK_ENABLE, .clkreg_enable = MCI_ST_UX500_HWFCEN, + .datactrl_mask_ddrmode = MCI_ST_DPSM_DDRMODE, .datalength_bits= 24, .sdio = true, .st_clkdiv = true, @@ -800,7 +806,7 @@ static void mmci_start_data(struct mmci_host *host, struct mmc_data *data) } if (host-mmc-ios.timing == MMC_TIMING_UHS_DDR50) - datactrl |= MCI_ST_DPSM_DDRMODE; + datactrl |= variant-datactrl_mask_ddrmode; /* * Attempt to use DMA operation mode, if this -- 1.9.1 -- To unsubscribe from this list: send the line unsubscribe linux-arm-msm in the body of a message to majord...@vger.kernel.org More majordomo info at http://vger.kernel.org/majordomo-info.html
[PATCH v2 09/14] mmc: mmci: add edge support to data and command out in variant data.
From: Srinivas Kandagatla srinivas.kandaga...@linaro.org This patch adds edge support for data and command out to variant structure giving more flexibility to the driver to support more SOCs which have different clock register layout. Without this patch other new SOCs like Qcom will have to add more code to special case them Signed-off-by: Srinivas Kandagatla srinivas.kandaga...@linaro.org --- drivers/mmc/host/mmci.c | 6 +- 1 file changed, 5 insertions(+), 1 deletion(-) diff --git a/drivers/mmc/host/mmci.c b/drivers/mmc/host/mmci.c index a81f303..17e7f6a 100644 --- a/drivers/mmc/host/mmci.c +++ b/drivers/mmc/host/mmci.c @@ -53,6 +53,7 @@ static unsigned int fmax = 515633; * @clkreg: default value for MCICLOCK register * @clkreg_enable: enable value for MMCICLOCK register * @clkreg_8bit_bus_enable: enable value for 8 bit bus + * @clkreg_neg_edge_enable: enable value for inverted data/cmd output * @datalength_bits: number of bits in the MMCIDATALENGTH register * @fifosize: number of bytes that can be written when MMCI_TXFIFOEMPTY * is asserted (likewise for RX) @@ -76,6 +77,7 @@ struct variant_data { unsigned intclkreg; unsigned intclkreg_enable; unsigned intclkreg_8bit_bus_enable; + unsigned intclkreg_neg_edge_enable; unsigned intdatalength_bits; unsigned intfifosize; unsigned intfifohalfsize; @@ -148,6 +150,7 @@ static struct variant_data variant_ux500 = { .clkreg = MCI_CLK_ENABLE, .clkreg_enable = MCI_ST_UX500_HWFCEN, .clkreg_8bit_bus_enable = MCI_ST_8BIT_BUS, + .clkreg_neg_edge_enable = MCI_ST_UX500_NEG_EDGE, .datactrl_mask_ddrmode = MCI_ST_DPSM_DDRMODE, .datalength_bits= 24, .sdio = true, @@ -165,6 +168,7 @@ static struct variant_data variant_ux500v2 = { .clkreg = MCI_CLK_ENABLE, .clkreg_enable = MCI_ST_UX500_HWFCEN, .clkreg_8bit_bus_enable = MCI_ST_8BIT_BUS, + .clkreg_neg_edge_enable = MCI_ST_UX500_NEG_EDGE, .datactrl_mask_ddrmode = MCI_ST_DPSM_DDRMODE, .datalength_bits= 24, .sdio = true, @@ -348,7 +352,7 @@ static void mmci_set_clkreg(struct mmci_host *host, unsigned int desired) clk |= variant-clkreg_8bit_bus_enable; if (host-mmc-ios.timing == MMC_TIMING_UHS_DDR50) - clk |= MCI_ST_UX500_NEG_EDGE; + clk |= variant-clkreg_neg_edge_enable; mmci_write_clkreg(host, clk); } -- 1.9.1 -- To unsubscribe from this list: send the line unsubscribe linux-arm-msm in the body of a message to majord...@vger.kernel.org More majordomo info at http://vger.kernel.org/majordomo-info.html
[PATCH v2 06/14] mmc: mmci: Qcomm: Add 3 clock cycle delay after register write
From: Srinivas Kandagatla srinivas.kandaga...@linaro.org Most of the Qcomm SD card controller registers must be updated to the MCLK domain so subsequent writes to registers will be ignored until 3 clock cycles have passed. This patch adds a 3 clock cycle delay required after writing to controller registers on Qualcomm SOCs. Without this delay all the register writes are not successful, resulting in not detecting cards. The write clock delay is activated by setting up mclk_delayed_writes variable in variant data. Signed-off-by: Srinivas Kandagatla srinivas.kandaga...@linaro.org --- drivers/mmc/host/mmci.c | 12 1 file changed, 12 insertions(+) diff --git a/drivers/mmc/host/mmci.c b/drivers/mmc/host/mmci.c index 881bb24..1385554 100644 --- a/drivers/mmc/host/mmci.c +++ b/drivers/mmc/host/mmci.c @@ -67,6 +67,8 @@ static unsigned int fmax = 515633; * @pwrreg_clkgate: MMCIPOWER register must be used to gate the clock * @busy_detect: true if busy detection on dat0 is supported * @pwrreg_nopower: bits in MMCIPOWER don't controls ext. power supply + * @mclk_delayed_writes: enable delayed writes to ensure, subsequent updates + * are not ignored. */ struct variant_data { unsigned intclkreg; @@ -83,6 +85,7 @@ struct variant_data { boolpwrreg_clkgate; boolbusy_detect; boolpwrreg_nopower; + boolmclk_delayed_writes; }; static struct variant_data variant_arm = { @@ -171,6 +174,12 @@ static struct variant_data variant_qcom = { .datalength_bits= 24, .blksz_datactrl4= true, .pwrreg_powerup = MCI_PWR_UP, + /* +* On QCom SD card controller, registers must be updated to the +* MCLK domain so subsequent writes to this register will be ignored +* for 3 clk cycles. +*/ + .mclk_delayed_writes= true, }; static inline u32 mmci_readl(struct mmci_host *host, u32 off) @@ -181,6 +190,9 @@ static inline u32 mmci_readl(struct mmci_host *host, u32 off) static inline void mmci_writel(struct mmci_host *host, u32 data, u32 off) { writel(data, host-base + off); + + if (host-variant-mclk_delayed_writes) + udelay(DIV_ROUND_UP((3 * USEC_PER_SEC), host-mclk)); } static int mmci_card_busy(struct mmc_host *mmc) -- 1.9.1 -- To unsubscribe from this list: send the line unsubscribe linux-arm-msm in the body of a message to majord...@vger.kernel.org More majordomo info at http://vger.kernel.org/majordomo-info.html
[PATCH v2 03/14] mmc: mmci: Add Qualcomm Id to amba id table
From: Srinivas Kandagatla srinivas.kandaga...@linaro.org This patch adds a fake Qualcomm ID 0x00051180 to the amba_ids, as Qualcomm SDCC controller is pl180, but amba id registers read 0x0's. The plan is to remove SDCC driver totally and use mmci as the main SD controller driver for Qualcomm SOCs. Signed-off-by: Srinivas Kandagatla srinivas.kandaga...@linaro.org Reviewed-by: Linus Walleij linus.wall...@linaro.org --- drivers/mmc/host/mmci.c | 15 +++ 1 file changed, 15 insertions(+) diff --git a/drivers/mmc/host/mmci.c b/drivers/mmc/host/mmci.c index a38e714..7bdf4d3 100644 --- a/drivers/mmc/host/mmci.c +++ b/drivers/mmc/host/mmci.c @@ -160,6 +160,15 @@ static struct variant_data variant_ux500v2 = { .pwrreg_nopower = true, }; +static struct variant_data variant_qcom = { + .fifosize = 16 * 4, + .fifohalfsize = 8 * 4, + .clkreg = MCI_CLK_ENABLE, + .datalength_bits= 24, + .blksz_datactrl4= true, + .pwrreg_powerup = MCI_PWR_UP, +}; + static int mmci_card_busy(struct mmc_host *mmc) { struct mmci_host *host = mmc_priv(mmc); @@ -1750,6 +1759,12 @@ static struct amba_id mmci_ids[] = { .mask = 0xf0ff, .data = variant_ux500v2, }, + /* Qualcomm variants */ + { + .id = 0x00051180, + .mask = 0x000f, + .data = variant_qcom, + }, { 0, 0 }, }; -- 1.9.1 -- To unsubscribe from this list: send the line unsubscribe linux-arm-msm in the body of a message to majord...@vger.kernel.org More majordomo info at http://vger.kernel.org/majordomo-info.html
[PATCH v2 02/14] mmc: mmci: convert register bits to use BIT() macro.
From: Srinivas Kandagatla srinivas.kandaga...@linaro.org This patch converts the register bits in the header file to use BIT(() macro, which looks much neater. No functional changes done. Signed-off-by: Srinivas Kandagatla srinivas.kandaga...@linaro.org --- drivers/mmc/host/mmci.h | 208 1 file changed, 104 insertions(+), 104 deletions(-) diff --git a/drivers/mmc/host/mmci.h b/drivers/mmc/host/mmci.h index 347d942..cd83ca3 100644 --- a/drivers/mmc/host/mmci.h +++ b/drivers/mmc/host/mmci.h @@ -11,48 +11,48 @@ #define MCI_PWR_OFF0x00 #define MCI_PWR_UP 0x02 #define MCI_PWR_ON 0x03 -#define MCI_OD (1 6) -#define MCI_ROD(1 7) +#define MCI_OD BIT(6) +#define MCI_RODBIT(7) /* * The ST Micro version does not have ROD and reuse the voltage registers for * direction settings. */ -#define MCI_ST_DATA2DIREN (1 2) -#define MCI_ST_CMDDIREN(1 3) -#define MCI_ST_DATA0DIREN (1 4) -#define MCI_ST_DATA31DIREN (1 5) -#define MCI_ST_FBCLKEN (1 7) -#define MCI_ST_DATA74DIREN (1 8) +#define MCI_ST_DATA2DIREN BIT(2) +#define MCI_ST_CMDDIRENBIT(3) +#define MCI_ST_DATA0DIREN BIT(4) +#define MCI_ST_DATA31DIREN BIT(5) +#define MCI_ST_FBCLKEN BIT(7) +#define MCI_ST_DATA74DIREN BIT(8) #define MMCICLOCK 0x004 -#define MCI_CLK_ENABLE (1 8) -#define MCI_CLK_PWRSAVE(1 9) -#define MCI_CLK_BYPASS (1 10) -#define MCI_4BIT_BUS (1 11) +#define MCI_CLK_ENABLE BIT(8) +#define MCI_CLK_PWRSAVEBIT(9) +#define MCI_CLK_BYPASS BIT(10) +#define MCI_4BIT_BUS BIT(11) /* * 8bit wide buses, hardware flow contronl, negative edges and clock inversion * supported in ST Micro U300 and Ux500 versions */ -#define MCI_ST_8BIT_BUS(1 12) -#define MCI_ST_U300_HWFCEN (1 13) -#define MCI_ST_UX500_NEG_EDGE (1 13) -#define MCI_ST_UX500_HWFCEN(1 14) -#define MCI_ST_UX500_CLK_INV (1 15) +#define MCI_ST_8BIT_BUSBIT(12) +#define MCI_ST_U300_HWFCEN BIT(13) +#define MCI_ST_UX500_NEG_EDGE BIT(13) +#define MCI_ST_UX500_HWFCENBIT(14) +#define MCI_ST_UX500_CLK_INV BIT(15) /* Modified PL180 on Versatile Express platform */ -#define MCI_ARM_HWFCEN (1 12) +#define MCI_ARM_HWFCEN BIT(12) #define MMCIARGUMENT 0x008 #define MMCICOMMAND0x00c -#define MCI_CPSM_RESPONSE (1 6) -#define MCI_CPSM_LONGRSP (1 7) -#define MCI_CPSM_INTERRUPT (1 8) -#define MCI_CPSM_PENDING (1 9) -#define MCI_CPSM_ENABLE(1 10) +#define MCI_CPSM_RESPONSE BIT(6) +#define MCI_CPSM_LONGRSP BIT(7) +#define MCI_CPSM_INTERRUPT BIT(8) +#define MCI_CPSM_PENDING BIT(9) +#define MCI_CPSM_ENABLEBIT(10) /* Argument flag extenstions in the ST Micro versions */ -#define MCI_ST_SDIO_SUSP (1 11) -#define MCI_ST_ENCMD_COMPL (1 12) -#define MCI_ST_NIEN(1 13) -#define MCI_ST_CE_ATACMD (1 14) +#define MCI_ST_SDIO_SUSP BIT(11) +#define MCI_ST_ENCMD_COMPL BIT(12) +#define MCI_ST_NIENBIT(13) +#define MCI_ST_CE_ATACMD BIT(14) #define MMCIRESPCMD0x010 #define MMCIRESPONSE0 0x014 @@ -62,95 +62,95 @@ #define MMCIDATATIMER 0x024 #define MMCIDATALENGTH 0x028 #define MMCIDATACTRL 0x02c -#define MCI_DPSM_ENABLE(1 0) -#define MCI_DPSM_DIRECTION (1 1) -#define MCI_DPSM_MODE (1 2) -#define MCI_DPSM_DMAENABLE (1 3) -#define MCI_DPSM_BLOCKSIZE (1 4) +#define MCI_DPSM_ENABLEBIT(0) +#define MCI_DPSM_DIRECTION BIT(1) +#define MCI_DPSM_MODE BIT(2) +#define MCI_DPSM_DMAENABLE BIT(3) +#define MCI_DPSM_BLOCKSIZE BIT(4) /* Control register extensions in the ST Micro U300 and Ux500 versions */ -#define MCI_ST_DPSM_RWSTART(1 8) -#define MCI_ST_DPSM_RWSTOP (1 9) -#define MCI_ST_DPSM_RWMOD (1 10) -#define MCI_ST_DPSM_SDIOEN (1 11) +#define MCI_ST_DPSM_RWSTARTBIT(8) +#define MCI_ST_DPSM_RWSTOP BIT(9) +#define MCI_ST_DPSM_RWMOD BIT(10) +#define MCI_ST_DPSM_SDIOEN BIT(11) /* Control register extensions in the ST Micro Ux500 versions */ -#define MCI_ST_DPSM_DMAREQCTL (1 12) -#define MCI_ST_DPSM_DBOOTMODEEN(1 13) -#define MCI_ST_DPSM_BUSYMODE (1 14) -#define MCI_ST_DPSM_DDRMODE(1 15) +#define MCI_ST_DPSM_DMAREQCTL BIT(12) +#define MCI_ST_DPSM_DBOOTMODEENBIT(13) +#define MCI_ST_DPSM_BUSYMODE BIT(14) +#define MCI_ST_DPSM_DDRMODEBIT(15) #define MMCIDATACNT0x030 #define MMCISTATUS 0x034 -#define MCI_CMDCRCFAIL (1 0) -#define MCI_DATACRCFAIL(1 1) -#define MCI_CMDTIMEOUT (1 2) -#define
[PATCH v2 04/14] mmc: mmci: Add Qcom datactrl register variant
From: Srinivas Kandagatla srinivas.kandaga...@linaro.org Instance of this IP on Qualcomm's SOCs has bit different layout for datactrl register. Bit position datactrl[16:4] hold the true block size instead of power of 2. Signed-off-by: Srinivas Kandagatla srinivas.kandaga...@linaro.org Reviewed-by: Linus Walleij linus.wall...@linaro.org --- drivers/mmc/host/mmci.c | 6 ++ 1 file changed, 6 insertions(+) diff --git a/drivers/mmc/host/mmci.c b/drivers/mmc/host/mmci.c index 7bdf4d3..324a886 100644 --- a/drivers/mmc/host/mmci.c +++ b/drivers/mmc/host/mmci.c @@ -60,6 +60,8 @@ static unsigned int fmax = 515633; * @sdio: variant supports SDIO * @st_clkdiv: true if using a ST-specific clock divider algorithm * @blksz_datactrl16: true if Block size is at b16..b30 position in datactrl register + * @blksz_datactrl4: true if Block size is at b4..b16 position in datactrl + * register * @pwrreg_powerup: power up value for MMCIPOWER register * @signal_direction: input/out direction of bus signals can be indicated * @pwrreg_clkgate: MMCIPOWER register must be used to gate the clock @@ -75,6 +77,7 @@ struct variant_data { boolsdio; boolst_clkdiv; boolblksz_datactrl16; + boolblksz_datactrl4; u32 pwrreg_powerup; boolsignal_direction; boolpwrreg_clkgate; @@ -164,6 +167,7 @@ static struct variant_data variant_qcom = { .fifosize = 16 * 4, .fifohalfsize = 8 * 4, .clkreg = MCI_CLK_ENABLE, + .blksz_datactrl4= true, .datalength_bits= 24, .blksz_datactrl4= true, .pwrreg_powerup = MCI_PWR_UP, @@ -740,6 +744,8 @@ static void mmci_start_data(struct mmci_host *host, struct mmc_data *data) if (variant-blksz_datactrl16) datactrl = MCI_DPSM_ENABLE | (data-blksz 16); + else if (variant-blksz_datactrl4) + datactrl = MCI_DPSM_ENABLE | (data-blksz 4); else datactrl = MCI_DPSM_ENABLE | blksz_bits 4; -- 1.9.1 -- To unsubscribe from this list: send the line unsubscribe linux-arm-msm in the body of a message to majord...@vger.kernel.org More majordomo info at http://vger.kernel.org/majordomo-info.html
Re: [PATCH] ARM: QCOM: Enable ARM_AMBA option for Qcom SOCS.
Hi Kumar, On 15/05/14 15:31, Kumar Gala wrote: I’d rather have the driver have the select of ARM_AMBA and not the core support. We clearly don’t need to build ARM_AMBA in to function. Shouldn’t driver depend on it rather than selecting it? Suggested approach will end up changing the way its done on other SOCs, Currently all the SOCs select ARM_AMBA at there machine level Kconfig rather than each individual driver selecting it. Am open to do it either way but doing it the way it exists is the something more acceptable I thought. thanks, srini -- To unsubscribe from this list: send the line unsubscribe linux-arm-msm in the body of a message to majord...@vger.kernel.org More majordomo info at http://vger.kernel.org/majordomo-info.html
Re: [PATCH] dmaengine: qcom_bam_dma: Add descriptor flag APIs
Hi Andy, On 15/05/14 18:32, Andy Gross wrote: On Fri, May 02, 2014 at 01:08:27PM -0500, Andy Gross wrote: On Fri, May 02, 2014 at 09:58:41PM +0530, Vinod Koul wrote: On Thu, Apr 17, 2014 at 05:04:02PM -0500, Andy Gross wrote: This patch adds APIs that allow for BAM hardware flags to be set per descriptor. Each one of the new flags informs the attached peripheral of a special behavior that is required. The EOT flag requests that the peripheral assert an end of transaction interrupt when that descriptor is complete. It also results in special signaling protocol that is used between the attached peripheral and the core using the DMA controller. DMA_PREP_INTERRUPT ?? I have 3 different IRQs that can be asserted based on the bit I set in the hardware descriptor. The normal IRQ is the INT bit. However, in some cases the peripheral protocol requires the use of the EOT or EOB interrupt instead. The DMA_PREP_INTERRUPT would only work if I had only 2 choices. Thinking about this more, I could use the DMA_PREP_INTERRUPT to cover the EOT flag. However, I might get in a bind later if I need to support the EOB (end of block) interrupt. This is good start, mapping EOT to DMA_PREP_INTERRUPT seems to be much appropriate. This will also provide mmci driver with much more generic interface than the bam specific function calls. Only way forward is to tie up this descriptor specific flags to more generic flags. Having specific callbacks would introduce limitations in using generic device drivers. Not really sure how we can map EOB/NWD flags without really defining new flags. Mapping to other generic flags might be totally confusing to people using/interpreting those flags. Needs more discussion on this. --srini The NWD flag requests that the peripheral wait until the data has been fully processed before signaling an interrupt. interrupt for transaction complete or DMA request? This is a special signaling mechanism that holds off the DMA interrupt until the peripheral actually acks that the data has been processed completely. This is required in many cases by the peripheral. One example is the SPI controller. At the end of a transaction you are supposed to set the NWD so that the chip select is de-asserted. I'm not sure what flag I could map this to... maybe DMA_CTRL_ACK? or maybe the DMA_PREP_FENCE? I don't generally like overloading the flags and slightly twisting their intent. Could we add a flag to denote device ACK? -- To unsubscribe from this list: send the line unsubscribe linux-arm-msm in the body of a message to majord...@vger.kernel.org More majordomo info at http://vger.kernel.org/majordomo-info.html
[PATCH RFC 3/4] mmc: mmci: Add qcom dml support to the driver.
From: Srinivas Kandagatla srinivas.kandaga...@linaro.org On Qualcomm APQ8064 SOCs, SD card controller has an additional glue called DML (Data Mover Local/Lite) to do dma transfers between Controller and DMA engine. This hardware needs to be setup before any dma transfer is requested. This patch adds the code necessary to intialize the hardware and setup before doing any dma transfers. Please Note: this is a just a first version of the patch, so there is a scope of improvement on this. Signed-off-by: Srinivas Kandagatla srinivas.kandaga...@linaro.org --- drivers/mmc/host/Kconfig| 11 +++ drivers/mmc/host/Makefile | 1 + drivers/mmc/host/mmci.c | 12 drivers/mmc/host/qcom_dml.c | 170 drivers/mmc/host/qcom_dml.h | 17 + 5 files changed, 211 insertions(+) create mode 100644 drivers/mmc/host/qcom_dml.c create mode 100644 drivers/mmc/host/qcom_dml.h diff --git a/drivers/mmc/host/Kconfig b/drivers/mmc/host/Kconfig index 8aaf8c1..55cb57b 100644 --- a/drivers/mmc/host/Kconfig +++ b/drivers/mmc/host/Kconfig @@ -14,6 +14,17 @@ config MMC_ARMMMCI If unsure, say N. +config MMC_QCOM_DML + tristate Qualcomm Data Mover for SD Card Controller + depends on MMC_ARMMMCI + default y + help + This selects the Qualcomm Data Mover lite/local on SD Card controller. + This option will enable the dma to work correctly, if you are using + Qcom SOCs and MMC, you would probably need this option to get DMA working. + + if unsure, say N. + config MMC_PXA tristate Intel PXA25x/26x/27x Multimedia Card Interface support depends on ARCH_PXA diff --git a/drivers/mmc/host/Makefile b/drivers/mmc/host/Makefile index 0c8aa5e..07ea02a 100644 --- a/drivers/mmc/host/Makefile +++ b/drivers/mmc/host/Makefile @@ -3,6 +3,7 @@ # obj-$(CONFIG_MMC_ARMMMCI) += mmci.o +obj-$(CONFIG_MMC_QCOM_DML) += qcom_dml.o obj-$(CONFIG_MMC_PXA) += pxamci.o obj-$(CONFIG_MMC_MXC) += mxcmmc.o obj-$(CONFIG_MMC_MXS) += mxs-mmc.o diff --git a/drivers/mmc/host/mmci.c b/drivers/mmc/host/mmci.c index 94b99d6..847a4ba 100644 --- a/drivers/mmc/host/mmci.c +++ b/drivers/mmc/host/mmci.c @@ -43,6 +43,7 @@ #include asm/sizes.h #include mmci.h +#include qcom_dml.h #define DRIVER_NAME mmci-pl18x @@ -78,6 +79,7 @@ static unsigned int fmax = 515633; * @explicit_mclk_control: enable explicit mclk control in driver. * @qcom_cclk_is_mclk: enable iff card clock is multimedia card adapter clock. * @qcom_fifo: enables qcom specific fifo pio read function. + * @qcom_dml: enables qcom specific dml glue for dma transfers. */ struct variant_data { unsigned intclkreg; @@ -103,6 +105,7 @@ struct variant_data { boolexplicit_mclk_control; boolqcom_cclk_is_mclk; boolqcom_fifo; + boolqcom_dml; }; static struct variant_data variant_arm = { @@ -214,6 +217,7 @@ static struct variant_data variant_qcom = { .explicit_mclk_control = true, .qcom_cclk_is_mclk = true, .qcom_fifo = true, + .qcom_dml = true, }; static inline u32 mmci_readl(struct mmci_host *host, u32 off) @@ -664,6 +668,9 @@ static int mmci_dma_start_data(struct mmci_host *host, unsigned int datactrl) dmaengine_submit(host-dma_desc_current); dma_async_issue_pending(host-dma_current); + if (host-variant-qcom_dml) + dml_start_xfer(host, data); + datactrl |= MCI_DPSM_DMAENABLE; /* Trigger the DMA transfer */ @@ -1702,6 +1709,11 @@ static int mmci_probe(struct amba_device *dev, mmci_dma_setup(host); + if (variant-qcom_dml host-dma_rx_channel host-dma_tx_channel) { + if (dml_hw_init(host, np)) + variant-qcom_dml = false; + } + pm_runtime_set_autosuspend_delay(dev-dev, 50); pm_runtime_use_autosuspend(dev-dev); pm_runtime_put(dev-dev); diff --git a/drivers/mmc/host/qcom_dml.c b/drivers/mmc/host/qcom_dml.c new file mode 100644 index 000..5d61e4c --- /dev/null +++ b/drivers/mmc/host/qcom_dml.c @@ -0,0 +1,170 @@ +#include linux/of.h +#include linux/of_dma.h +#include linux/mmc/host.h +#include linux/mmc/card.h +#include mmci.h + +/* DML config register defination */ +#define DML_CONFIG 0x00 +#define PRODUCER_CRCI_DIS 0x00 +#define PRODUCER_CRCI_X_SEL0x01 +#define PRODUCER_CRCI_Y_SEL0x02 +#define PRODUCER_CRCI_MSK 0x3 +#define CONSUMER_CRCI_DIS (0x00 2) +#define CONSUMER_CRCI_X_SEL(0x01 2) +#define CONSUMER_CRCI_Y_SEL(0x02 2) +#define CONSUMER_CRCI_MSK (0x3 2) +#define PRODUCER_TRANS_END_EN (1 4) +#define BYPASS (1 16) +#define DIRECT_MODE
[PATCH RFC 2/4] ARM: DT: QCOM: apq8064: Add dma support for sdcc node
From: Srinivas Kandagatla srinivas.kandaga...@linaro.org This patch adds dma support in both sdcc1 and sdcc3 device node. Signed-off-by: Srinivas Kandagatla srinivas.kandaga...@linaro.org --- arch/arm/boot/dts/qcom-apq8064.dtsi | 26 ++ 1 file changed, 26 insertions(+) diff --git a/arch/arm/boot/dts/qcom-apq8064.dtsi b/arch/arm/boot/dts/qcom-apq8064.dtsi index 2a6cd09..24d6dd7 100644 --- a/arch/arm/boot/dts/qcom-apq8064.dtsi +++ b/arch/arm/boot/dts/qcom-apq8064.dtsi @@ -158,6 +158,28 @@ regulator-always-on; }; + sdcc1bam:dma@12402000{ + compatible = qcom,bam-v1.3.0; + reg = 0x12402000 0x8000, 0x12400800 0x800; + reg-names = bam, dml; + interrupts = 0 98 0; + clocks = gcc SDC1_H_CLK; + clock-names = bam_clk; + #dma-cells = 1; + qcom,ee = 0; + }; + + sdcc3bam:dma@12182000{ + compatible = qcom,bam-v1.3.0; + reg = 0x12182000 0x8000, 0x12180800 0x800; + reg-names = bam, dml; + interrupts = 0 96 0; + clocks = gcc SDC3_H_CLK; + clock-names = bam_clk; + #dma-cells = 1; + qcom,ee = 0; + }; + amba { compatible = arm,amba-bus; #address-cells = 1; @@ -178,6 +200,8 @@ cap-sd-highspeed; cap-mmc-highspeed; vmmc-supply = vsdcc_fixed; + dmas = sdcc1bam 2, sdcc1bam 1; + dma-names = tx, rx; }; sdcc3: sdcc@1218 { @@ -195,6 +219,8 @@ max-frequency = 19200; no-1-8-v; vmmc-supply = vsdcc_fixed; + dmas = sdcc3bam 2, sdcc3bam 1; + dma-names = tx, rx; }; }; }; -- 1.9.1 -- To unsubscribe from this list: send the line unsubscribe linux-arm-msm in the body of a message to majord...@vger.kernel.org More majordomo info at http://vger.kernel.org/majordomo-info.html
[PATCH RFC 0/4] Add QCOM DML support to MMCI driver.
From: Srinivas Kandagatla srinivas.kandaga...@linaro.org DML hardware is a glue in between SD Card Controller and DMA engine, this hardware needs to be setup before and during any dma transfers. This patchset adds DML support to the mmci driver. This patchset is a very early version of adding Qualcomm DMA support to generic mmci driver. There are two bits of changes which are done in a bit of hacky way. First one: Is DML code as part of MMCI driver? Second one: Accessing BAM specific functions from generic mmci driver. Ideally BAM descriptor flags need to be exposed in more generic way so that generic drivers could use it without much dependency on SOC specifics. Having said this, these patches are published on request by Andy Gross for testing purpose only. This patches are tested on IFC8064 board with both eMMC and external SD card. I would appreciate any feedback/suggestions on the overall approach. Srinivas Kandagatla (4): ARM: DT: QCOM: apq8064: fix the memory range for sdcc node. ARM: DT: QCOM: apq8064: Add dma support for sdcc node mmc: mmci: Add qcom dml support to the driver. mmc: mmci: do an EOT for write DMA requests. arch/arm/boot/dts/qcom-apq8064.dtsi | 30 ++- drivers/mmc/host/Kconfig| 11 +++ drivers/mmc/host/Makefile | 1 + drivers/mmc/host/mmci.c | 16 drivers/mmc/host/qcom_dml.c | 170 drivers/mmc/host/qcom_dml.h | 17 6 files changed, 243 insertions(+), 2 deletions(-) create mode 100644 drivers/mmc/host/qcom_dml.c create mode 100644 drivers/mmc/host/qcom_dml.h -- 1.9.1 -- To unsubscribe from this list: send the line unsubscribe linux-arm-msm in the body of a message to majord...@vger.kernel.org More majordomo info at http://vger.kernel.org/majordomo-info.html
[PATCH RFC 1/4] ARM: DT: QCOM: apq8064: fix the memory range for sdcc node.
From: Srinivas Kandagatla srinivas.kandaga...@linaro.org This patch fixes the range of iomemory for sdcc controller, it is now set to 0x2000 so that the mmci driver could talk to dml hardware as well. Signed-off-by: Srinivas Kandagatla srinivas.kandaga...@linaro.org --- arch/arm/boot/dts/qcom-apq8064.dtsi | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/arch/arm/boot/dts/qcom-apq8064.dtsi b/arch/arm/boot/dts/qcom-apq8064.dtsi index 640fb1d..2a6cd09 100644 --- a/arch/arm/boot/dts/qcom-apq8064.dtsi +++ b/arch/arm/boot/dts/qcom-apq8064.dtsi @@ -167,7 +167,7 @@ status = disabled; compatible = arm,pl18x, arm,primecell; arm,primecell-periphid = 0x00051180; - reg = 0x1240 0x8000; + reg = 0x1240 0x2000; interrupts = GIC_SPI 104 IRQ_TYPE_LEVEL_HIGH; interrupt-names = cmd_irq; clocks = gcc SDC1_CLK, gcc SDC1_H_CLK; @@ -184,7 +184,7 @@ compatible = arm,pl18x, arm,primecell; arm,primecell-periphid = 0x00051180; status = disabled; - reg = 0x1218 0x8000; + reg = 0x1218 0x2000; interrupts = GIC_SPI 102 IRQ_TYPE_LEVEL_HIGH; interrupt-names = cmd_irq; clocks = gcc SDC3_CLK, gcc SDC3_H_CLK; -- 1.9.1 -- To unsubscribe from this list: send the line unsubscribe linux-arm-msm in the body of a message to majord...@vger.kernel.org More majordomo info at http://vger.kernel.org/majordomo-info.html
Re: [PATCH RFC 00/12] Add Qualcomm SD Card Controller support.
Thanks Bjorn for testing this series. On 19/05/14 23:08, Bjorn Andersson wrote: On Mon, Apr 21, 2014 at 2:43 PM,srinivas.kandaga...@linaro.org wrote: From: Srinivas Kandagatlasrinivas.kandaga...@linaro.org [snip] This patches are tested in PIO mode on IFC8064 board with both eMMC and external SD card. I would appreciate any feedback/suggestions on the overall approach. Hi Srini, I finally got around to give this series a spin on our APQ8064 based devices as well. I had a few reported CRC issues on our msm8960 based devices, but thinks seems functionally ok. On APQ8064, the kernel finds the onboard eMMC and when mounting it I get the following: [1.624118] mmc0: new high speed MMC card at address 0001 [1.627521] mmcblk0: mmc0:0001 MAG2GA 14.5 GiB [1.632714] mmcblk0boot0: mmc0:0001 MAG2GA partition 1 2.00 MiB [1.636989] mmcblk0boot1: mmc0:0001 MAG2GA partition 2 2.00 MiB [1.637393] Freeing unused kernel memory: 332K (c09c6000 - c0a19000) [1.663379] mmcblk0: response CRC error sending r/w cmd command, [2.292914] mmcblk0: response CRC error sending r/w cmd command, card status 0xb00 [2.300985] mmcblk0: response CRC error sending r/w cmd command, Any suggestions of what I could do to help you debug this? There might be couple of reasons why this might happen, First is the regluators. currently the upstream kernel does not have support for regulators. So, does the eMMC on your board work perfectly fine with the default 2.7v? secondly it could be eMMC vendor specific quirks. I stress tested eMMC on IFC6410 and I did not hit any issues as you mentioned. Are you aware of any such quirks specific to the eMMC on your board? thanks, srini Regards, Bjorn -- To unsubscribe from this list: send the line unsubscribe linux-arm-msm in the body of a message to majord...@vger.kernel.org More majordomo info at http://vger.kernel.org/majordomo-info.html
Re: [PATCH] dmaengine: qcom_bam_dma: Add descriptor flag APIs
On 22/05/14 16:09, Andy Gross wrote: On Thu, May 22, 2014 at 11:40:49AM +0530, Vinod Koul wrote: snip I have 3 different IRQs that can be asserted based on the bit I set in the hardware descriptor. The normal IRQ is the INT bit. However, in some cases the peripheral protocol requires the use of the EOT or EOB interrupt instead. The DMA_PREP_INTERRUPT would only work if I had only 2 choices. Thinking about this more, I could use the DMA_PREP_INTERRUPT to cover the EOT flag. However, I might get in a bind later if I need to support the EOB (end of block) interrupt. Sorry for delay in this. I think it would make sense to use DMA_PREP_INTERRUPT for EOB interrupt. The EOT should always be enabled for the cases where it is applicable instead of nomral irq. That should genrically ocvery your cases, or did we miss anything here The EOT is not used for every transaction. It is part of a handshaking protocol with the attached peripheral, much like the NWD (notify when done). As near as I can tell today, no peripheral depends on the EOB, so we could drop it for now until it is needed and cross this bridge when we need to. As EOT behaviour is totally dependent on the attached peripheral(or channel), Can't we make this specific to channel by passing additional flags in the DT dma channel descriptors? This will be better abstraction for drivers as well. I know that EOT flag is part of descriptor but still some channels *must* have EOT to run there state-machine correctly. So making it optional for those channels might be wrong. Are there any use cases for particular *channel* where EOT requirement changes dynamically? --srini The NWD flag requests that the peripheral wait until the data has been fully processed before signaling an interrupt. interrupt for transaction complete or DMA request? This is a special signaling mechanism that holds off the DMA interrupt until the peripheral actually acks that the data has been processed completely. This is required in many cases by the peripheral. One example is the SPI controller. At the end of a transaction you are supposed to set the NWD so that the chip select is de-asserted. I'm not sure what flag I could map this to... maybe DMA_CTRL_ACK? or maybe the DMA_PREP_FENCE? I don't generally like overloading the flags and slightly twisting their intent. Could we add a flag to denote device ACK? Nope lets not override these... Then I need to add a flag. Something like DMA_PREP_DEVICE_ACK that denotes that the attached device needs to ACK the transfer. Also, one thing I forgot. For crypto and some of the other blocks, we have something called command descriptors that can be transferred to the blocks to provide programming or direction. The DMA controller has a flag that tells the attached peripheral that the incoming DMA contains command descriptors. The dma descriptors still point to a memory region to transfer, but the contents are interpreted differently. This is yet another flag in the descriptor flag section. I'd need another flag for this as well. Something like DMA_PREP_CMD. We are actively working on upstreaming our crypto block and this will be required for that to work properly. -- To unsubscribe from this list: send the line unsubscribe linux-arm-msm in the body of a message to majord...@vger.kernel.org More majordomo info at http://vger.kernel.org/majordomo-info.html
Re: [PATCH] dmaengine: qcom_bam_dma: Add descriptor flag APIs
On 22/05/14 16:32, Andy Gross wrote: On Thu, May 22, 2014 at 04:27:05PM +0100, Srinivas Kandagatla wrote: snip The EOT is not used for every transaction. It is part of a handshaking protocol with the attached peripheral, much like the NWD (notify when done). As near as I can tell today, no peripheral depends on the EOB, so we could drop it for now until it is needed and cross this bridge when we need to. As EOT behaviour is totally dependent on the attached peripheral(or channel), Can't we make this specific to channel by passing additional flags in the DT dma channel descriptors? This will be better abstraction for drivers as well. Even for channels where you want to use EOT, you don't use it for every transaction. So a global channel flag isn't going to work. This is the same for NWD. It is a per descriptor choice. Thanks Andy for explaining, I got it now. I know that EOT flag is part of descriptor but still some channels *must* have EOT to run there state-machine correctly. So making it optional for those channels might be wrong. Are there any use cases for particular *channel* where EOT requirement changes dynamically? I2C is one example. You place EOT on the last transaction that makes up a write/read transaction. You may have multiple descriptors to send data, but the last one has EOT. And for read transactions, you place NWD on the last read transaction. snip -- To unsubscribe from this list: send the line unsubscribe linux-arm-msm in the body of a message to majord...@vger.kernel.org More majordomo info at http://vger.kernel.org/majordomo-info.html
Re: [PATCH v2 00/14] Add Qualcomm SD Card Controller support
On 23/05/14 08:50, Ulf Hansson wrote: On 23 May 2014 09:13, Srinivas Kandagatla srinivas.kandaga...@linaro.org wrote: Hi Ulf, I like to get this patches for v3.16, any chance of considering these patches to v3.16 ? I promise to have them properly reviewed early next week, sorry for taking so long. Let's see where this leads us. Thankyou. It seems like you had some CRC issues during read/write? Did you manage to resolve that issue? Bjorn is using different SOC and board than the IFC6410 Am testing on, so its completely different setup. on IFC6410 we did lot of stress testing and no issues seen. so suspecting the issues are very specific to that board or the eMMC Bjorn is using. We are suspecting that the CRC issues are due to the fact that there is no code to manage regulators. My test setup uses dummy regulator, and the eMMC and external SD cards seems to be Ok with default voltages. Am not sure if thats the same with Bjorn's board. Thanks, srini Kind regards Ulf Hansson -- To unsubscribe from this list: send the line unsubscribe linux-arm-msm in the body of a message to majord...@vger.kernel.org More majordomo info at http://vger.kernel.org/majordomo-info.html
Re: [PATCH v2 11/14] mmc: mmci: Add support to data commands via variant structure.
Thanks Linus W. On 23/05/14 10:09, Linus Walleij wrote: On Thu, May 15, 2014 at 11:37 AM, srinivas.kandaga...@linaro.org wrote: From: Srinivas Kandagatla srinivas.kandaga...@linaro.org On some SOCs like Qcom there are explicit bits in the command register to specify if its a data transfer command or not. So this patch adds support to such bits in variant data, giving more flexibility to the driver. Signed-off-by: Srinivas Kandagatla srinivas.kandaga...@linaro.org Reviewed-by: Linus Walleij linus.wall...@linaro.org Yours, Linus Walleij -- To unsubscribe from this list: send the line unsubscribe linux-arm-msm in the body of a message to majord...@vger.kernel.org More majordomo info at http://vger.kernel.org/majordomo-info.html
Re: [PATCH v2 12/14] mmc: mmci: add support for fbclk to latch data and cmd.
On 23/05/14 10:12, Linus Walleij wrote: On Thu, May 15, 2014 at 11:37 AM, srinivas.kandaga...@linaro.org wrote: From: Srinivas Kandagatla srinivas.kandaga...@linaro.org This patch adds support to fbclk that is used to latch data and cmd on some controllers like SD Card controller in Qcom SOC. Signed-off-by: Srinivas Kandagatla srinivas.kandaga...@linaro.org (...) Isn't this overkill? I totally agree. Initially I did do it the way you suggested, but wanted to be more explicit in what its actually doing and I was also not sure if its Ok to add more than one flag in clkreg_enable. @@ -189,6 +192,7 @@ static struct variant_data variant_qcom = { .clkreg = MCI_CLK_ENABLE, -.clkreg_enable = MCI_QCOM_CLK_FLOWENA, + .clkreg_enable = MCI_QCOM_CLK_FLOWENA | MCI_QCOM_CLK_FEEDBACK_CLK, .clkreg_8bit_bus_enable = MCI_QCOM_CLK_WIDEBUS_8, Isn't this achieveing exactly the same thing without the extra fields? You unconditionally do it at every enable anyway, don't you? I will fix it and send a new version. Thanks, srini Yours, Linus Walleij -- To unsubscribe from this list: send the line unsubscribe linux-arm-msm in the body of a message to majord...@vger.kernel.org More majordomo info at http://vger.kernel.org/majordomo-info.html
Re: [PATCH v2 14/14] mmc: mmci: Add Qcom specific pio_read function.
On 23/05/14 10:31, Linus Walleij wrote: On Thu, May 15, 2014 at 11:38 AM, srinivas.kandaga...@linaro.org wrote: From: Srinivas Kandagatla srinivas.kandaga...@linaro.org MCIFIFOCNT register behaviour on Qcom chips is very different than the other pl180 integrations. MCIFIFOCNT register contains the number of words that are still waiting to be transferred through the FIFO. It keeps decrementing once the host CPU reads the MCIFIFO. With the existing logic and the MCIFIFOCNT behaviour, mmci_pio_read will loop forever, as the FIFOCNT register will always return transfer size before reading the FIFO. Also the data sheet states that This register is only useful for debug purposes and should not be used for normal operation since it does not reflect data which may or may not be in the pipeline. This patch implements qcom_pio_read function so as existing mmci_pio_read is not suitable for Qcom SOCs. qcom_pio_read function is only selected based on qcom_fifo flag in variant data structure. Signed-off-by: Srinivas Kandagatla srinivas.kandaga...@linaro.org (...) +static int mmci_qcom_pio_read(struct mmci_host *host, char *buffer, +unsigned int remain) +{ + uint32_t*ptr = (uint32_t *) buffer; Oops.. Sorry Linus, I think this change-set got something different than what I did. I remember your comments in the last review, I did take care of them but some how It got missed... I will fix these and send a new version. Just use u32 like the rest of the driver does. + int fifo_size = variant-fifosize; + + if (remain % 4) And another variant is to count the *number or words* to read from the FIFO rather than the number of bytes! I would do it like this: static int mmci_qcom_pio_read(struct mmci_host *host, char *buffer, unsigned int remain) { u32 *ptr = (u32*) buffer; unsigned int count = 0; unsigned int words; unsigned int fifo_size = host-variant-fifosize; words = DIV_ROUND_UP(remain, 4); while (readl(host-base + MMCISTATUS) MCI_RXDATAAVLBL) { *ptr = readl(host-base + MMCIFIFO + (count % fifo_size)); ptr++; count += 4; remain--; if (!remain) break; } return count; } I guess you will run into additional problems when you come to doing SDIO. This function can return *more* bytes than asked for, as it rounds up. It won't happen with MMC/SD transfers since these are always divisible by 8, but it *will* happen on SDIO! If you look carefully at the comments in mmci_pio_read() you will see how this is handled. Are you sure this function cannot be augmented to handle the qcom variant as well so you don't get this problem further down the road? I did try to customize the mmci_pio_read function but I failed all the time. The reason being the behaviour of MCI_FIFOCNT register which is totally different to the way the function is written. I will give a try again. Thanks, srini Yours, Linus Walleij -- To unsubscribe from this list: send the line unsubscribe linux-arm-msm in the body of a message to majord...@vger.kernel.org More majordomo info at http://vger.kernel.org/majordomo-info.html
Re: [PATCH v2 14/14] mmc: mmci: Add Qcom specific pio_read function.
Hi Linus W, On 23/05/14 10:31, Linus Walleij wrote: static int mmci_qcom_pio_read(struct mmci_host *host, char *buffer, unsigned int remain) { u32 *ptr = (u32*) buffer; unsigned int count = 0; unsigned int words; unsigned int fifo_size = host-variant-fifosize; words = DIV_ROUND_UP(remain, 4); while (readl(host-base + MMCISTATUS) MCI_RXDATAAVLBL) { *ptr = readl(host-base + MMCIFIFO + (count % fifo_size)); ptr++; count += 4; remain--; if (!remain) break; } return count; } I guess you will run into additional problems when you come to doing SDIO. This function can return*more* bytes than asked for, as it rounds up. It won't happen with MMC/SD transfers since these are always divisible by 8, but it*will* happen on SDIO! That's a good point, Qualcomm will need SDIO support in future, so I have slightly modified the code to address this. Other thing I tried was to fit in this in mmci_pio_read, It became very ugly, as the FIFOCNT register behaviour is totally different and there is no way to tell how many bytes are ready to be consumed. So finally I think having a separate pio read for qualcomm looks much neater. final mmci_qcom_pio_read looks like: static int mmci_qcom_pio_read(struct mmci_host *host, char *buffer, unsigned int remain) { u32 *ptr = (u32*) buffer; unsigned int count = 0; unsigned int words, bytes; unsigned int fifo_size = host-variant-fifosize; words = remain 2; bytes = remain % 4; /* read full words followed by leftover bytes */ if (words) { while (readl(host-base + MMCISTATUS) MCI_RXDATAAVLBL) { *ptr = readl(host-base + MMCIFIFO + (count % fifo_size)); ptr++; count += 4; words--; if (!words) break; } } /* read leftover bytes */ if (unlikely(bytes)) { unsigned char buf[4]; if (readl(host-base + MMCISTATUS) MCI_RXDATAAVLBL) { *buf = readl(host-base + MMCIFIFO + (count % fifo_size)); memcpy(ptr, buf, bytes); count += bytes; } } return count; } Thanks, srini -- To unsubscribe from this list: send the line unsubscribe linux-arm-msm in the body of a message to majord...@vger.kernel.org More majordomo info at http://vger.kernel.org/majordomo-info.html
[PATCH v3 00/13] Add Qualcomm SD Card Controller support
From: Srinivas Kandagatla srinivas.kandaga...@linaro.org Thankyou Linus W and everyone for reviewing RFC to v3 patches. This patch series adds Qualcomm SD Card Controller support in pl180 mmci driver. QCom SDCC is basically a pl180, but bit more customized, some of the register layouts and offsets are different to the ones mentioned in pl180 datasheet. The plan is to totally remove the standalone SDCC driver drivers/mmc/host/msm_sdcc.* and start using generic mmci driver for all Qualcomm parts, as we get chance to test on other Qcom boards. To start using the existing mmci driver, a fake amba id for Qualcomm is added in patches: mmc: mmci: Add Qualcomm Id to amba id table. Second change is, adding a 3 clock cycle delay for register writes on QCOM SDCC registers, which is done in patches: mmc: mmci: Add register read/write wrappers. mmc: mmci: Qcomm: Add 3 clock cycle delay after register write Third change is to accommodate CLK, DATCTRL and MMCICLK register layout changes in Qcom SDCC and provide more flexibity in driver to specify these changes via variant datastructure. Which are done in patches: mmc: mmci: Add Qcom datactrl register variant mmc: mmci: add ddrmode mask to variant data mmc: mmci: add 8bit bus support in variant data mmc: mmci: add edge support to data and command out in variant data. mmc: mmci: add Qcom specifics of clk and datactrl registers. mmc: mmci: Add support to data commands via variant structure. mmc: mmci: add explicit clk control Fourth major change was to add qcom specfic pio read function, the need for this is because the way MCIFIFOCNT register behaved in QCOM SDCC is very different to the one in pl180. This change is done in patch: mmc: mmci: Add Qcom specific pio_read function. Last some Qcom unrelated changes/cleanup to driver are done in patches: mmc: mmci: use NSEC_PER_SEC macro mmc: mmci: convert register bits to use BIT() macro. This patches are tested in PIO mode on IFC8064 board with both eMMC and external SD card. I would like to get this support in v3.16. Changes from v2: - merged fbclk latch patch with clkreg_enable patch as suggested by Linus W. - remove qcom prefix for explicit clk control pointed by Linus W. - cleaned up mmci_qcom_pio_read and consider SDIO as suggested by Linus W. Changes from v1: - moved most of the SOC specifics to variant parameters as suggested by Linus W. - renamed registers as suggested by Linus W. - Added comments in the code as suggested by Linus W. - moved out AMBA ID addition patch from this series. - rebased the patches to git://git.linaro.org/people/ulf.hansson/mmc.git next as suggested by Ulf H. Changes from RFC: - moved out clk setup out of spinlock as pointed by Stephen B. Am hoping to get this for v3.16. All these patches are tested on IF6410 board on both eMMC and external SD card. Thanks, srini Srinivas Kandagatla (13): mmc: mmci: use NSEC_PER_SEC macro mmc: mmci: convert register bits to use BIT() macro. mmc: mmci: Add Qualcomm Id to amba id table mmc: mmci: Add Qcom datactrl register variant mmc: mmci: Add register read/write wrappers. mmc: mmci: Qcomm: Add 3 clock cycle delay after register write mmc: mmci: add ddrmode mask to variant data mmc: mmci: add 8bit bus support in variant data mmc: mmci: add edge support to data and command out in variant data. mmc: mmci: add Qcom specifics of clk and datactrl registers. mmc: mmci: Add support to data commands via variant structure. mmc: mmci: add explicit clk control mmc: mmci: Add Qcom specific pio_read function. drivers/mmc/host/mmci.c | 252 drivers/mmc/host/mmci.h | 232 2 files changed, 318 insertions(+), 166 deletions(-) -- 1.9.1 -- To unsubscribe from this list: send the line unsubscribe linux-arm-msm in the body of a message to majord...@vger.kernel.org More majordomo info at http://vger.kernel.org/majordomo-info.html
[PATCH v3 02/13] mmc: mmci: convert register bits to use BIT() macro.
From: Srinivas Kandagatla srinivas.kandaga...@linaro.org This patch converts the register bits in the header file to use BIT(() macro, which looks much neater. No functional changes done. Signed-off-by: Srinivas Kandagatla srinivas.kandaga...@linaro.org --- drivers/mmc/host/mmci.h | 208 1 file changed, 104 insertions(+), 104 deletions(-) diff --git a/drivers/mmc/host/mmci.h b/drivers/mmc/host/mmci.h index 347d942..cd83ca3 100644 --- a/drivers/mmc/host/mmci.h +++ b/drivers/mmc/host/mmci.h @@ -11,48 +11,48 @@ #define MCI_PWR_OFF0x00 #define MCI_PWR_UP 0x02 #define MCI_PWR_ON 0x03 -#define MCI_OD (1 6) -#define MCI_ROD(1 7) +#define MCI_OD BIT(6) +#define MCI_RODBIT(7) /* * The ST Micro version does not have ROD and reuse the voltage registers for * direction settings. */ -#define MCI_ST_DATA2DIREN (1 2) -#define MCI_ST_CMDDIREN(1 3) -#define MCI_ST_DATA0DIREN (1 4) -#define MCI_ST_DATA31DIREN (1 5) -#define MCI_ST_FBCLKEN (1 7) -#define MCI_ST_DATA74DIREN (1 8) +#define MCI_ST_DATA2DIREN BIT(2) +#define MCI_ST_CMDDIRENBIT(3) +#define MCI_ST_DATA0DIREN BIT(4) +#define MCI_ST_DATA31DIREN BIT(5) +#define MCI_ST_FBCLKEN BIT(7) +#define MCI_ST_DATA74DIREN BIT(8) #define MMCICLOCK 0x004 -#define MCI_CLK_ENABLE (1 8) -#define MCI_CLK_PWRSAVE(1 9) -#define MCI_CLK_BYPASS (1 10) -#define MCI_4BIT_BUS (1 11) +#define MCI_CLK_ENABLE BIT(8) +#define MCI_CLK_PWRSAVEBIT(9) +#define MCI_CLK_BYPASS BIT(10) +#define MCI_4BIT_BUS BIT(11) /* * 8bit wide buses, hardware flow contronl, negative edges and clock inversion * supported in ST Micro U300 and Ux500 versions */ -#define MCI_ST_8BIT_BUS(1 12) -#define MCI_ST_U300_HWFCEN (1 13) -#define MCI_ST_UX500_NEG_EDGE (1 13) -#define MCI_ST_UX500_HWFCEN(1 14) -#define MCI_ST_UX500_CLK_INV (1 15) +#define MCI_ST_8BIT_BUSBIT(12) +#define MCI_ST_U300_HWFCEN BIT(13) +#define MCI_ST_UX500_NEG_EDGE BIT(13) +#define MCI_ST_UX500_HWFCENBIT(14) +#define MCI_ST_UX500_CLK_INV BIT(15) /* Modified PL180 on Versatile Express platform */ -#define MCI_ARM_HWFCEN (1 12) +#define MCI_ARM_HWFCEN BIT(12) #define MMCIARGUMENT 0x008 #define MMCICOMMAND0x00c -#define MCI_CPSM_RESPONSE (1 6) -#define MCI_CPSM_LONGRSP (1 7) -#define MCI_CPSM_INTERRUPT (1 8) -#define MCI_CPSM_PENDING (1 9) -#define MCI_CPSM_ENABLE(1 10) +#define MCI_CPSM_RESPONSE BIT(6) +#define MCI_CPSM_LONGRSP BIT(7) +#define MCI_CPSM_INTERRUPT BIT(8) +#define MCI_CPSM_PENDING BIT(9) +#define MCI_CPSM_ENABLEBIT(10) /* Argument flag extenstions in the ST Micro versions */ -#define MCI_ST_SDIO_SUSP (1 11) -#define MCI_ST_ENCMD_COMPL (1 12) -#define MCI_ST_NIEN(1 13) -#define MCI_ST_CE_ATACMD (1 14) +#define MCI_ST_SDIO_SUSP BIT(11) +#define MCI_ST_ENCMD_COMPL BIT(12) +#define MCI_ST_NIENBIT(13) +#define MCI_ST_CE_ATACMD BIT(14) #define MMCIRESPCMD0x010 #define MMCIRESPONSE0 0x014 @@ -62,95 +62,95 @@ #define MMCIDATATIMER 0x024 #define MMCIDATALENGTH 0x028 #define MMCIDATACTRL 0x02c -#define MCI_DPSM_ENABLE(1 0) -#define MCI_DPSM_DIRECTION (1 1) -#define MCI_DPSM_MODE (1 2) -#define MCI_DPSM_DMAENABLE (1 3) -#define MCI_DPSM_BLOCKSIZE (1 4) +#define MCI_DPSM_ENABLEBIT(0) +#define MCI_DPSM_DIRECTION BIT(1) +#define MCI_DPSM_MODE BIT(2) +#define MCI_DPSM_DMAENABLE BIT(3) +#define MCI_DPSM_BLOCKSIZE BIT(4) /* Control register extensions in the ST Micro U300 and Ux500 versions */ -#define MCI_ST_DPSM_RWSTART(1 8) -#define MCI_ST_DPSM_RWSTOP (1 9) -#define MCI_ST_DPSM_RWMOD (1 10) -#define MCI_ST_DPSM_SDIOEN (1 11) +#define MCI_ST_DPSM_RWSTARTBIT(8) +#define MCI_ST_DPSM_RWSTOP BIT(9) +#define MCI_ST_DPSM_RWMOD BIT(10) +#define MCI_ST_DPSM_SDIOEN BIT(11) /* Control register extensions in the ST Micro Ux500 versions */ -#define MCI_ST_DPSM_DMAREQCTL (1 12) -#define MCI_ST_DPSM_DBOOTMODEEN(1 13) -#define MCI_ST_DPSM_BUSYMODE (1 14) -#define MCI_ST_DPSM_DDRMODE(1 15) +#define MCI_ST_DPSM_DMAREQCTL BIT(12) +#define MCI_ST_DPSM_DBOOTMODEENBIT(13) +#define MCI_ST_DPSM_BUSYMODE BIT(14) +#define MCI_ST_DPSM_DDRMODEBIT(15) #define MMCIDATACNT0x030 #define MMCISTATUS 0x034 -#define MCI_CMDCRCFAIL (1 0) -#define MCI_DATACRCFAIL(1 1) -#define MCI_CMDTIMEOUT (1 2) -#define
[PATCH v3 03/13] mmc: mmci: Add Qualcomm Id to amba id table
From: Srinivas Kandagatla srinivas.kandaga...@linaro.org This patch adds a fake Qualcomm ID 0x00051180 to the amba_ids, as Qualcomm SDCC controller is pl180, but amba id registers read 0x0's. The plan is to remove SDCC driver totally and use mmci as the main SD controller driver for Qualcomm SOCs. Signed-off-by: Srinivas Kandagatla srinivas.kandaga...@linaro.org Reviewed-by: Linus Walleij linus.wall...@linaro.org --- drivers/mmc/host/mmci.c | 15 +++ 1 file changed, 15 insertions(+) diff --git a/drivers/mmc/host/mmci.c b/drivers/mmc/host/mmci.c index a38e714..7bdf4d3 100644 --- a/drivers/mmc/host/mmci.c +++ b/drivers/mmc/host/mmci.c @@ -160,6 +160,15 @@ static struct variant_data variant_ux500v2 = { .pwrreg_nopower = true, }; +static struct variant_data variant_qcom = { + .fifosize = 16 * 4, + .fifohalfsize = 8 * 4, + .clkreg = MCI_CLK_ENABLE, + .datalength_bits= 24, + .blksz_datactrl4= true, + .pwrreg_powerup = MCI_PWR_UP, +}; + static int mmci_card_busy(struct mmc_host *mmc) { struct mmci_host *host = mmc_priv(mmc); @@ -1750,6 +1759,12 @@ static struct amba_id mmci_ids[] = { .mask = 0xf0ff, .data = variant_ux500v2, }, + /* Qualcomm variants */ + { + .id = 0x00051180, + .mask = 0x000f, + .data = variant_qcom, + }, { 0, 0 }, }; -- 1.9.1 -- To unsubscribe from this list: send the line unsubscribe linux-arm-msm in the body of a message to majord...@vger.kernel.org More majordomo info at http://vger.kernel.org/majordomo-info.html
[PATCH v3 07/13] mmc: mmci: add ddrmode mask to variant data
From: Srinivas Kandagatla srinivas.kandaga...@linaro.org This patch adds ddrmode mask to variant structure giving more flexibility to the driver to support more SOCs which have different datactrl register layout. Without this patch datactrl register is updated with wrong ddrmode mask on non ST SOCs, resulting in card detection failures. Signed-off-by: Srinivas Kandagatla srinivas.kandaga...@linaro.org Reviewed-by: Linus Walleij linus.wall...@linaro.org --- drivers/mmc/host/mmci.c | 8 +++- 1 file changed, 7 insertions(+), 1 deletion(-) diff --git a/drivers/mmc/host/mmci.c b/drivers/mmc/host/mmci.c index 1385554..dec70d2 100644 --- a/drivers/mmc/host/mmci.c +++ b/drivers/mmc/host/mmci.c @@ -59,6 +59,7 @@ static unsigned int fmax = 515633; * is asserted (likewise for RX) * @sdio: variant supports SDIO * @st_clkdiv: true if using a ST-specific clock divider algorithm + * @datactrl_mask_ddrmode: ddr mode mask in datactrl register. * @blksz_datactrl16: true if Block size is at b16..b30 position in datactrl register * @blksz_datactrl4: true if Block size is at b4..b16 position in datactrl * register @@ -76,6 +77,7 @@ struct variant_data { unsigned intdatalength_bits; unsigned intfifosize; unsigned intfifohalfsize; + unsigned intdatactrl_mask_ddrmode; boolsdio; boolst_clkdiv; boolblksz_datactrl16; @@ -114,6 +116,7 @@ static struct variant_data variant_u300 = { .fifosize = 16 * 4, .fifohalfsize = 8 * 4, .clkreg_enable = MCI_ST_U300_HWFCEN, + .datactrl_mask_ddrmode = MCI_ST_DPSM_DDRMODE, .datalength_bits= 16, .sdio = true, .pwrreg_powerup = MCI_PWR_ON, @@ -126,6 +129,7 @@ static struct variant_data variant_nomadik = { .fifosize = 16 * 4, .fifohalfsize = 8 * 4, .clkreg = MCI_CLK_ENABLE, + .datactrl_mask_ddrmode = MCI_ST_DPSM_DDRMODE, .datalength_bits= 24, .sdio = true, .st_clkdiv = true, @@ -140,6 +144,7 @@ static struct variant_data variant_ux500 = { .fifohalfsize = 8 * 4, .clkreg = MCI_CLK_ENABLE, .clkreg_enable = MCI_ST_UX500_HWFCEN, + .datactrl_mask_ddrmode = MCI_ST_DPSM_DDRMODE, .datalength_bits= 24, .sdio = true, .st_clkdiv = true, @@ -155,6 +160,7 @@ static struct variant_data variant_ux500v2 = { .fifohalfsize = 8 * 4, .clkreg = MCI_CLK_ENABLE, .clkreg_enable = MCI_ST_UX500_HWFCEN, + .datactrl_mask_ddrmode = MCI_ST_DPSM_DDRMODE, .datalength_bits= 24, .sdio = true, .st_clkdiv = true, @@ -800,7 +806,7 @@ static void mmci_start_data(struct mmci_host *host, struct mmc_data *data) } if (host-mmc-ios.timing == MMC_TIMING_UHS_DDR50) - datactrl |= MCI_ST_DPSM_DDRMODE; + datactrl |= variant-datactrl_mask_ddrmode; /* * Attempt to use DMA operation mode, if this -- 1.9.1 -- To unsubscribe from this list: send the line unsubscribe linux-arm-msm in the body of a message to majord...@vger.kernel.org More majordomo info at http://vger.kernel.org/majordomo-info.html
[PATCH v3 13/13] mmc: mmci: Add Qcom specific pio_read function.
From: Srinivas Kandagatla srinivas.kandaga...@linaro.org MCIFIFOCNT register behaviour on Qcom chips is very different than the other pl180 integrations. MCIFIFOCNT register contains the number of words that are still waiting to be transferred through the FIFO. It keeps decrementing once the host CPU reads the MCIFIFO. With the existing logic and the MCIFIFOCNT behaviour, mmci_pio_read will loop forever, as the FIFOCNT register will always return transfer size before reading the FIFO. Also the data sheet states that This register is only useful for debug purposes and should not be used for normal operation since it does not reflect data which may or may not be in the pipeline. This patch implements qcom_pio_read function so as existing mmci_pio_read is not suitable for Qcom SOCs. qcom_pio_read function is only selected based on qcom_fifo flag in variant data structure. Signed-off-by: Srinivas Kandagatla srinivas.kandaga...@linaro.org --- drivers/mmc/host/mmci.c | 46 -- 1 file changed, 44 insertions(+), 2 deletions(-) diff --git a/drivers/mmc/host/mmci.c b/drivers/mmc/host/mmci.c index f6dfd24..51ce493 100644 --- a/drivers/mmc/host/mmci.c +++ b/drivers/mmc/host/mmci.c @@ -75,6 +75,7 @@ static unsigned int fmax = 515633; * are not ignored. * @explicit_mclk_control: enable explicit mclk control in driver. * @cclk_is_mclk: enable iff card clock is multimedia card adapter clock. + * @qcom_fifo: enables qcom specific fifo pio read function. */ struct variant_data { unsigned intclkreg; @@ -98,6 +99,7 @@ struct variant_data { boolmclk_delayed_writes; boolexplicit_mclk_control; boolcclk_is_mclk; + boolqcom_fifo; }; static struct variant_data variant_arm = { @@ -208,6 +210,7 @@ static struct variant_data variant_qcom = { .mclk_delayed_writes= true, .explicit_mclk_control = true, .cclk_is_mclk = true, + .qcom_fifo = true, }; static inline u32 mmci_readl(struct mmci_host *host, u32 off) @@ -1022,6 +1025,40 @@ mmci_cmd_irq(struct mmci_host *host, struct mmc_command *cmd, } } +static int mmci_qcom_pio_read(struct mmci_host *host, char *buffer, + unsigned int remain) +{ + u32 *ptr = (u32 *) buffer; + unsigned int count = 0; + unsigned int words, bytes; + unsigned int fsize = host-variant-fifosize; + + words = remain 2; + bytes = remain % 4; + /* read full words followed by leftover bytes */ + if (words) { + while (readl(host-base + MMCISTATUS) MCI_RXDATAAVLBL) { + *ptr = readl(host-base + MMCIFIFO + (count % fsize)); + ptr++; + count += 4; + words--; + if (!words) + break; + } + } + + if (unlikely(bytes)) { + unsigned char buf[4]; + if (readl(host-base + MMCISTATUS) MCI_RXDATAAVLBL) { + *buf = readl(host-base + MMCIFIFO + (count % fsize)); + memcpy(ptr, buf, bytes); + count += bytes; + } + } + + return count; +} + static int mmci_pio_read(struct mmci_host *host, char *buffer, unsigned int remain) { void __iomem *base = host-base; @@ -1143,8 +1180,13 @@ static irqreturn_t mmci_pio_irq(int irq, void *dev_id) remain = sg_miter-length; len = 0; - if (status MCI_RXACTIVE) - len = mmci_pio_read(host, buffer, remain); + if (status MCI_RXACTIVE) { + if (variant-qcom_fifo) + len = mmci_qcom_pio_read(host, buffer, remain); + else + len = mmci_pio_read(host, buffer, remain); + } + if (status MCI_TXACTIVE) len = mmci_pio_write(host, buffer, remain, status); -- 1.9.1 -- To unsubscribe from this list: send the line unsubscribe linux-arm-msm in the body of a message to majord...@vger.kernel.org More majordomo info at http://vger.kernel.org/majordomo-info.html
[PATCH v3 11/13] mmc: mmci: Add support to data commands via variant structure.
From: Srinivas Kandagatla srinivas.kandaga...@linaro.org On some SOCs like Qcom there are explicit bits in the command register to specify if its a data transfer command or not. So this patch adds support to such bits in variant data, giving more flexibility to the driver. Signed-off-by: Srinivas Kandagatla srinivas.kandaga...@linaro.org Reviewed-by: Linus Walleij linus.wall...@linaro.org --- drivers/mmc/host/mmci.c | 6 ++ 1 file changed, 6 insertions(+) diff --git a/drivers/mmc/host/mmci.c b/drivers/mmc/host/mmci.c index 6434f5b1..5cbf644 100644 --- a/drivers/mmc/host/mmci.c +++ b/drivers/mmc/host/mmci.c @@ -59,6 +59,7 @@ static unsigned int fmax = 515633; * is asserted (likewise for RX) * @fifohalfsize: number of bytes that can be written when MCI_TXFIFOHALFEMPTY * is asserted (likewise for RX) + * @data_cmd_enable: enable value for data commands. * @sdio: variant supports SDIO * @st_clkdiv: true if using a ST-specific clock divider algorithm * @datactrl_mask_ddrmode: ddr mode mask in datactrl register. @@ -81,6 +82,7 @@ struct variant_data { unsigned intdatalength_bits; unsigned intfifosize; unsigned intfifohalfsize; + unsigned intdata_cmd_enable; unsigned intdatactrl_mask_ddrmode; boolsdio; boolst_clkdiv; @@ -189,6 +191,7 @@ static struct variant_data variant_qcom = { MCI_QCOM_CLK_FEEDBACK_CLK, .clkreg_8bit_bus_enable = MCI_QCOM_CLK_WIDEBUS_8, .datactrl_mask_ddrmode = MCI_QCOM_CLK_DDR_MODE, + .data_cmd_enable= MCI_QCOM_CSPM_DATCMD, .blksz_datactrl4= true, .datalength_bits= 24, .blksz_datactrl4= true, @@ -875,6 +878,9 @@ mmci_start_command(struct mmci_host *host, struct mmc_command *cmd, u32 c) if (/*interrupt*/0) c |= MCI_CPSM_INTERRUPT; + if (mmc_cmd_type(cmd) == MMC_CMD_ADTC) + c |= host-variant-data_cmd_enable; + host-cmd = cmd; mmci_writel(host, cmd-arg, MMCIARGUMENT); -- 1.9.1 -- To unsubscribe from this list: send the line unsubscribe linux-arm-msm in the body of a message to majord...@vger.kernel.org More majordomo info at http://vger.kernel.org/majordomo-info.html
[PATCH v3 12/13] mmc: mmci: add explicit clk control
From: Srinivas Kandagatla srinivas.kandaga...@linaro.org On Controllers like Qcom SD card controller where cclk is mclk and mclk should be directly controlled by the driver. This patch adds support to control mclk directly in the driver, and also adds explicit_mclk_control and cclk_is_mclk flags in variant structure giving more flexibility to the driver. Signed-off-by: Srinivas Kandagatla srinivas.kandaga...@linaro.org Reviewed-by: Linus Walleij linus.wall...@linaro.org --- drivers/mmc/host/mmci.c | 30 +- 1 file changed, 25 insertions(+), 5 deletions(-) diff --git a/drivers/mmc/host/mmci.c b/drivers/mmc/host/mmci.c index 5cbf644..f6dfd24 100644 --- a/drivers/mmc/host/mmci.c +++ b/drivers/mmc/host/mmci.c @@ -73,6 +73,8 @@ static unsigned int fmax = 515633; * @pwrreg_nopower: bits in MMCIPOWER don't controls ext. power supply * @mclk_delayed_writes: enable delayed writes to ensure, subsequent updates * are not ignored. + * @explicit_mclk_control: enable explicit mclk control in driver. + * @cclk_is_mclk: enable iff card clock is multimedia card adapter clock. */ struct variant_data { unsigned intclkreg; @@ -94,6 +96,8 @@ struct variant_data { boolbusy_detect; boolpwrreg_nopower; boolmclk_delayed_writes; + boolexplicit_mclk_control; + boolcclk_is_mclk; }; static struct variant_data variant_arm = { @@ -202,6 +206,8 @@ static struct variant_data variant_qcom = { * for 3 clk cycles. */ .mclk_delayed_writes= true, + .explicit_mclk_control = true, + .cclk_is_mclk = true, }; static inline u32 mmci_readl(struct mmci_host *host, u32 off) @@ -317,7 +323,9 @@ static void mmci_set_clkreg(struct mmci_host *host, unsigned int desired) host-cclk = 0; if (desired) { - if (desired = host-mclk) { + if (variant-cclk_is_mclk) { + host-cclk = host-mclk; + } else if (desired = host-mclk) { clk = MCI_CLK_BYPASS; if (variant-st_clkdiv) clk |= MCI_ST_UX500_NEG_EDGE; @@ -1354,6 +1362,16 @@ static void mmci_set_ios(struct mmc_host *mmc, struct mmc_ios *ios) if (!ios-clock variant-pwrreg_clkgate) pwr = ~MCI_PWR_ON; + if (ios-clock != host-mclk host-variant-explicit_mclk_control) { + int rc = clk_set_rate(host-clk, ios-clock); + if (rc 0) { + dev_err(mmc_dev(host-mmc), + Error setting clock rate (%d)\n, rc); + } else { + host-mclk = clk_get_rate(host-clk); + } + } + spin_lock_irqsave(host-lock, flags); mmci_set_clkreg(host, ios-clock); @@ -1540,10 +1558,12 @@ static int mmci_probe(struct amba_device *dev, * is not specified. Either value must not exceed the clock rate into * the block, of course. */ - if (mmc-f_max) - mmc-f_max = min(host-mclk, mmc-f_max); - else - mmc-f_max = min(host-mclk, fmax); + if (!host-variant-explicit_mclk_control) { + if (mmc-f_max) + mmc-f_max = min(host-mclk, mmc-f_max); + else + mmc-f_max = min(host-mclk, fmax); + } dev_dbg(mmc_dev(mmc), clocking block at %u Hz\n, mmc-f_max); /* Get regulators and the supported OCR mask */ -- 1.9.1 -- To unsubscribe from this list: send the line unsubscribe linux-arm-msm in the body of a message to majord...@vger.kernel.org More majordomo info at http://vger.kernel.org/majordomo-info.html
[PATCH v3 10/13] mmc: mmci: add Qcom specifics of clk and datactrl registers.
From: Srinivas Kandagatla srinivas.kandaga...@linaro.org This patch adds specifics of clk and datactrl register on Qualcomm SD Card controller. This patch also populates the Qcom variant data with these new values specific to Qualcomm SD Card Controller. Signed-off-by: Srinivas Kandagatla srinivas.kandaga...@linaro.org Reviewed-by: Linus Walleij linus.wall...@linaro.org --- drivers/mmc/host/mmci.c | 4 drivers/mmc/host/mmci.h | 24 2 files changed, 28 insertions(+) diff --git a/drivers/mmc/host/mmci.c b/drivers/mmc/host/mmci.c index 17e7f6a..6434f5b1 100644 --- a/drivers/mmc/host/mmci.c +++ b/drivers/mmc/host/mmci.c @@ -185,6 +185,10 @@ static struct variant_data variant_qcom = { .fifosize = 16 * 4, .fifohalfsize = 8 * 4, .clkreg = MCI_CLK_ENABLE, + .clkreg_enable = MCI_QCOM_CLK_FLOWENA | + MCI_QCOM_CLK_FEEDBACK_CLK, + .clkreg_8bit_bus_enable = MCI_QCOM_CLK_WIDEBUS_8, + .datactrl_mask_ddrmode = MCI_QCOM_CLK_DDR_MODE, .blksz_datactrl4= true, .datalength_bits= 24, .blksz_datactrl4= true, diff --git a/drivers/mmc/host/mmci.h b/drivers/mmc/host/mmci.h index cd83ca3..1b93ae7 100644 --- a/drivers/mmc/host/mmci.h +++ b/drivers/mmc/host/mmci.h @@ -41,6 +41,22 @@ /* Modified PL180 on Versatile Express platform */ #define MCI_ARM_HWFCEN BIT(12) +/* Modified on Qualcomm Integrations */ +#define MCI_QCOM_CLK_WIDEBUS_4 (2 10) +#define MCI_QCOM_CLK_WIDEBUS_8 (3 10) +#define MCI_QCOM_CLK_FLOWENA BIT(12) +#define MCI_QCOM_CLK_INVERTOUT BIT(13) + +/* select in latch data and command */ +#define MCI_QCOM_CLK_SEL_IN_SHIFT (14) +#define MCI_QCOM_CLK_SEL_MASK (0x3) +#define MCI_QCOM_CLK_SEL_RISING_EDGE (1) +#define MCI_QCOM_CLK_FEEDBACK_CLK (2 14) +#define MCI_QCOM_CLK_DDR_MODE (3 14) + +/* mclk selection */ +#define MCI_QCOM_CLK_SEL_MCLK (2 23) + #define MMCIARGUMENT 0x008 #define MMCICOMMAND0x00c #define MCI_CPSM_RESPONSE BIT(6) @@ -54,6 +70,14 @@ #define MCI_ST_NIENBIT(13) #define MCI_ST_CE_ATACMD BIT(14) +/* Modified on Qualcomm Integrations */ +#define MCI_QCOM_CSPM_DATCMD BIT(12) +#define MCI_QCOM_CSPM_MCIABORT BIT(13) +#define MCI_QCOM_CSPM_CCSENABLEBIT(14) +#define MCI_QCOM_CSPM_CCSDISABLE BIT(15) +#define MCI_QCOM_CSPM_AUTO_CMD19 BIT(16) +#define MCI_QCOM_CSPM_AUTO_CMD21 BIT(21) + #define MMCIRESPCMD0x010 #define MMCIRESPONSE0 0x014 #define MMCIRESPONSE1 0x018 -- 1.9.1 -- To unsubscribe from this list: send the line unsubscribe linux-arm-msm in the body of a message to majord...@vger.kernel.org More majordomo info at http://vger.kernel.org/majordomo-info.html
[PATCH v3 05/13] mmc: mmci: Add register read/write wrappers.
From: Srinivas Kandagatla srinivas.kandaga...@linaro.org This patch adds wrappers for readl/writel functions used in the driver. The reason for this wrappers is to accommodate SOCs like Qualcomm which has requirement for delaying the write for few cycles when writing to its SD Card Controller registers. Signed-off-by: Srinivas Kandagatla srinivas.kandaga...@linaro.org Reviewed-by: Linus Walleij linus.wall...@linaro.org --- drivers/mmc/host/mmci.c | 110 ++-- 1 file changed, 59 insertions(+), 51 deletions(-) diff --git a/drivers/mmc/host/mmci.c b/drivers/mmc/host/mmci.c index 324a886..881bb24 100644 --- a/drivers/mmc/host/mmci.c +++ b/drivers/mmc/host/mmci.c @@ -173,6 +173,16 @@ static struct variant_data variant_qcom = { .pwrreg_powerup = MCI_PWR_UP, }; +static inline u32 mmci_readl(struct mmci_host *host, u32 off) +{ + return readl(host-base + off); +} + +static inline void mmci_writel(struct mmci_host *host, u32 data, u32 off) +{ + writel(data, host-base + off); +} + static int mmci_card_busy(struct mmc_host *mmc) { struct mmci_host *host = mmc_priv(mmc); @@ -182,7 +192,7 @@ static int mmci_card_busy(struct mmc_host *mmc) pm_runtime_get_sync(mmc_dev(mmc)); spin_lock_irqsave(host-lock, flags); - if (readl(host-base + MMCISTATUS) MCI_ST_CARDBUSY) + if (mmci_readl(host, MMCISTATUS) MCI_ST_CARDBUSY) busy = 1; spin_unlock_irqrestore(host-lock, flags); @@ -232,7 +242,7 @@ static void mmci_write_clkreg(struct mmci_host *host, u32 clk) { if (host-clk_reg != clk) { host-clk_reg = clk; - writel(clk, host-base + MMCICLOCK); + mmci_writel(host, clk, MMCICLOCK); } } @@ -243,7 +253,7 @@ static void mmci_write_pwrreg(struct mmci_host *host, u32 pwr) { if (host-pwr_reg != pwr) { host-pwr_reg = pwr; - writel(pwr, host-base + MMCIPOWER); + mmci_writel(host, pwr, MMCIPOWER); } } @@ -257,7 +267,7 @@ static void mmci_write_datactrlreg(struct mmci_host *host, u32 datactrl) if (host-datactrl_reg != datactrl) { host-datactrl_reg = datactrl; - writel(datactrl, host-base + MMCIDATACTRL); + mmci_writel(host, datactrl, MMCIDATACTRL); } } @@ -323,7 +333,7 @@ static void mmci_set_clkreg(struct mmci_host *host, unsigned int desired) static void mmci_request_end(struct mmci_host *host, struct mmc_request *mrq) { - writel(0, host-base + MMCICOMMAND); + mmci_writel(host, 0, MMCICOMMAND); BUG_ON(host-data); @@ -338,18 +348,16 @@ mmci_request_end(struct mmci_host *host, struct mmc_request *mrq) static void mmci_set_mask1(struct mmci_host *host, unsigned int mask) { - void __iomem *base = host-base; - if (host-singleirq) { - unsigned int mask0 = readl(base + MMCIMASK0); + unsigned int mask0 = mmci_readl(host, MMCIMASK0); mask0 = ~MCI_IRQ1MASK; mask0 |= mask; - writel(mask0, base + MMCIMASK0); + mmci_writel(host, mask0, MMCIMASK0); } - writel(mask, base + MMCIMASK1); + mmci_writel(host, mask, MMCIMASK1); } static void mmci_stop_data(struct mmci_host *host) @@ -478,7 +486,7 @@ static void mmci_dma_finalize(struct mmci_host *host, struct mmc_data *data) /* Wait up to 1ms for the DMA to complete */ for (i = 0; ; i++) { - status = readl(host-base + MMCISTATUS); + status = mmci_readl(host, MMCISTATUS); if (!(status MCI_RXDATAAVLBLMASK) || i = 100) break; udelay(10); @@ -617,8 +625,8 @@ static int mmci_dma_start_data(struct mmci_host *host, unsigned int datactrl) * to fire next DMA request. When that happens, MMCI will * call mmci_data_end() */ - writel(readl(host-base + MMCIMASK0) | MCI_DATAENDMASK, - host-base + MMCIMASK0); + mmci_writel(host, mmci_readl(host, MMCIMASK0) | MCI_DATAENDMASK, + MMCIMASK0); return 0; } @@ -736,8 +744,8 @@ static void mmci_start_data(struct mmci_host *host, struct mmc_data *data) timeout = data-timeout_clks + (unsigned int)clks; base = host-base; - writel(timeout, base + MMCIDATATIMER); - writel(host-size, base + MMCIDATALENGTH); + mmci_writel(host, timeout, MMCIDATATIMER); + mmci_writel(host, host-size, MMCIDATALENGTH); blksz_bits = ffs(data-blksz) - 1; BUG_ON(1 blksz_bits != data-blksz); @@ -811,20 +819,19 @@ static void mmci_start_data(struct mmci_host *host, struct mmc_data *data) } mmci_write_datactrlreg(host, datactrl); - writel(readl(base + MMCIMASK0) ~MCI_DATAENDMASK, base + MMCIMASK0); + mmci_writel(host, mmci_readl(host, MMCIMASK0
[PATCH v3 09/13] mmc: mmci: add edge support to data and command out in variant data.
From: Srinivas Kandagatla srinivas.kandaga...@linaro.org This patch adds edge support for data and command out to variant structure giving more flexibility to the driver to support more SOCs which have different clock register layout. Without this patch other new SOCs like Qcom will have to add more code to special case them Signed-off-by: Srinivas Kandagatla srinivas.kandaga...@linaro.org Reviewed-by: Linus Walleij linus.wall...@linaro.org --- drivers/mmc/host/mmci.c | 6 +- 1 file changed, 5 insertions(+), 1 deletion(-) diff --git a/drivers/mmc/host/mmci.c b/drivers/mmc/host/mmci.c index a81f303..17e7f6a 100644 --- a/drivers/mmc/host/mmci.c +++ b/drivers/mmc/host/mmci.c @@ -53,6 +53,7 @@ static unsigned int fmax = 515633; * @clkreg: default value for MCICLOCK register * @clkreg_enable: enable value for MMCICLOCK register * @clkreg_8bit_bus_enable: enable value for 8 bit bus + * @clkreg_neg_edge_enable: enable value for inverted data/cmd output * @datalength_bits: number of bits in the MMCIDATALENGTH register * @fifosize: number of bytes that can be written when MMCI_TXFIFOEMPTY * is asserted (likewise for RX) @@ -76,6 +77,7 @@ struct variant_data { unsigned intclkreg; unsigned intclkreg_enable; unsigned intclkreg_8bit_bus_enable; + unsigned intclkreg_neg_edge_enable; unsigned intdatalength_bits; unsigned intfifosize; unsigned intfifohalfsize; @@ -148,6 +150,7 @@ static struct variant_data variant_ux500 = { .clkreg = MCI_CLK_ENABLE, .clkreg_enable = MCI_ST_UX500_HWFCEN, .clkreg_8bit_bus_enable = MCI_ST_8BIT_BUS, + .clkreg_neg_edge_enable = MCI_ST_UX500_NEG_EDGE, .datactrl_mask_ddrmode = MCI_ST_DPSM_DDRMODE, .datalength_bits= 24, .sdio = true, @@ -165,6 +168,7 @@ static struct variant_data variant_ux500v2 = { .clkreg = MCI_CLK_ENABLE, .clkreg_enable = MCI_ST_UX500_HWFCEN, .clkreg_8bit_bus_enable = MCI_ST_8BIT_BUS, + .clkreg_neg_edge_enable = MCI_ST_UX500_NEG_EDGE, .datactrl_mask_ddrmode = MCI_ST_DPSM_DDRMODE, .datalength_bits= 24, .sdio = true, @@ -348,7 +352,7 @@ static void mmci_set_clkreg(struct mmci_host *host, unsigned int desired) clk |= variant-clkreg_8bit_bus_enable; if (host-mmc-ios.timing == MMC_TIMING_UHS_DDR50) - clk |= MCI_ST_UX500_NEG_EDGE; + clk |= variant-clkreg_neg_edge_enable; mmci_write_clkreg(host, clk); } -- 1.9.1 -- To unsubscribe from this list: send the line unsubscribe linux-arm-msm in the body of a message to majord...@vger.kernel.org More majordomo info at http://vger.kernel.org/majordomo-info.html
[PATCH v3 08/13] mmc: mmci: add 8bit bus support in variant data
From: Srinivas Kandagatla srinivas.kandaga...@linaro.org This patch adds 8bit bus enable to variant structure giving more flexibility to the driver to support more SOCs which have different clock register layout. Without this patch other new SOCs like Qcom will have to add more code to special case them. Signed-off-by: Srinivas Kandagatla srinivas.kandaga...@linaro.org Reviewed-by: Linus Walleij linus.wall...@linaro.org --- drivers/mmc/host/mmci.c | 7 ++- 1 file changed, 6 insertions(+), 1 deletion(-) diff --git a/drivers/mmc/host/mmci.c b/drivers/mmc/host/mmci.c index dec70d2..a81f303 100644 --- a/drivers/mmc/host/mmci.c +++ b/drivers/mmc/host/mmci.c @@ -52,6 +52,7 @@ static unsigned int fmax = 515633; * struct variant_data - MMCI variant-specific quirks * @clkreg: default value for MCICLOCK register * @clkreg_enable: enable value for MMCICLOCK register + * @clkreg_8bit_bus_enable: enable value for 8 bit bus * @datalength_bits: number of bits in the MMCIDATALENGTH register * @fifosize: number of bytes that can be written when MMCI_TXFIFOEMPTY * is asserted (likewise for RX) @@ -74,6 +75,7 @@ static unsigned int fmax = 515633; struct variant_data { unsigned intclkreg; unsigned intclkreg_enable; + unsigned intclkreg_8bit_bus_enable; unsigned intdatalength_bits; unsigned intfifosize; unsigned intfifohalfsize; @@ -116,6 +118,7 @@ static struct variant_data variant_u300 = { .fifosize = 16 * 4, .fifohalfsize = 8 * 4, .clkreg_enable = MCI_ST_U300_HWFCEN, + .clkreg_8bit_bus_enable = MCI_ST_8BIT_BUS, .datactrl_mask_ddrmode = MCI_ST_DPSM_DDRMODE, .datalength_bits= 16, .sdio = true, @@ -144,6 +147,7 @@ static struct variant_data variant_ux500 = { .fifohalfsize = 8 * 4, .clkreg = MCI_CLK_ENABLE, .clkreg_enable = MCI_ST_UX500_HWFCEN, + .clkreg_8bit_bus_enable = MCI_ST_8BIT_BUS, .datactrl_mask_ddrmode = MCI_ST_DPSM_DDRMODE, .datalength_bits= 24, .sdio = true, @@ -160,6 +164,7 @@ static struct variant_data variant_ux500v2 = { .fifohalfsize = 8 * 4, .clkreg = MCI_CLK_ENABLE, .clkreg_enable = MCI_ST_UX500_HWFCEN, + .clkreg_8bit_bus_enable = MCI_ST_8BIT_BUS, .datactrl_mask_ddrmode = MCI_ST_DPSM_DDRMODE, .datalength_bits= 24, .sdio = true, @@ -340,7 +345,7 @@ static void mmci_set_clkreg(struct mmci_host *host, unsigned int desired) if (host-mmc-ios.bus_width == MMC_BUS_WIDTH_4) clk |= MCI_4BIT_BUS; if (host-mmc-ios.bus_width == MMC_BUS_WIDTH_8) - clk |= MCI_ST_8BIT_BUS; + clk |= variant-clkreg_8bit_bus_enable; if (host-mmc-ios.timing == MMC_TIMING_UHS_DDR50) clk |= MCI_ST_UX500_NEG_EDGE; -- 1.9.1 -- To unsubscribe from this list: send the line unsubscribe linux-arm-msm in the body of a message to majord...@vger.kernel.org More majordomo info at http://vger.kernel.org/majordomo-info.html
[PATCH v3 04/13] mmc: mmci: Add Qcom datactrl register variant
From: Srinivas Kandagatla srinivas.kandaga...@linaro.org Instance of this IP on Qualcomm's SOCs has bit different layout for datactrl register. Bit position datactrl[16:4] hold the true block size instead of power of 2. Signed-off-by: Srinivas Kandagatla srinivas.kandaga...@linaro.org Reviewed-by: Linus Walleij linus.wall...@linaro.org --- drivers/mmc/host/mmci.c | 6 ++ 1 file changed, 6 insertions(+) diff --git a/drivers/mmc/host/mmci.c b/drivers/mmc/host/mmci.c index 7bdf4d3..324a886 100644 --- a/drivers/mmc/host/mmci.c +++ b/drivers/mmc/host/mmci.c @@ -60,6 +60,8 @@ static unsigned int fmax = 515633; * @sdio: variant supports SDIO * @st_clkdiv: true if using a ST-specific clock divider algorithm * @blksz_datactrl16: true if Block size is at b16..b30 position in datactrl register + * @blksz_datactrl4: true if Block size is at b4..b16 position in datactrl + * register * @pwrreg_powerup: power up value for MMCIPOWER register * @signal_direction: input/out direction of bus signals can be indicated * @pwrreg_clkgate: MMCIPOWER register must be used to gate the clock @@ -75,6 +77,7 @@ struct variant_data { boolsdio; boolst_clkdiv; boolblksz_datactrl16; + boolblksz_datactrl4; u32 pwrreg_powerup; boolsignal_direction; boolpwrreg_clkgate; @@ -164,6 +167,7 @@ static struct variant_data variant_qcom = { .fifosize = 16 * 4, .fifohalfsize = 8 * 4, .clkreg = MCI_CLK_ENABLE, + .blksz_datactrl4= true, .datalength_bits= 24, .blksz_datactrl4= true, .pwrreg_powerup = MCI_PWR_UP, @@ -740,6 +744,8 @@ static void mmci_start_data(struct mmci_host *host, struct mmc_data *data) if (variant-blksz_datactrl16) datactrl = MCI_DPSM_ENABLE | (data-blksz 16); + else if (variant-blksz_datactrl4) + datactrl = MCI_DPSM_ENABLE | (data-blksz 4); else datactrl = MCI_DPSM_ENABLE | blksz_bits 4; -- 1.9.1 -- To unsubscribe from this list: send the line unsubscribe linux-arm-msm in the body of a message to majord...@vger.kernel.org More majordomo info at http://vger.kernel.org/majordomo-info.html
Re: [PATCH v3 03/13] mmc: mmci: Add Qualcomm Id to amba id table
Hi Ulf, On 26/05/14 10:10, Ulf Hansson wrote: Hi Srinivas, +static struct variant_data variant_qcom = { + .fifosize = 16 * 4, + .fifohalfsize = 8 * 4, + .clkreg = MCI_CLK_ENABLE, + .datalength_bits= 24, + .blksz_datactrl4= true, You get compile error here. yes, You are right, I will reorder this patch after the mmc: mmci: Add Qcom datactrl register variant Thanks, srini Kind regards Ulf Hansson -- To unsubscribe from this list: send the line unsubscribe linux-arm-msm in the body of a message to majord...@vger.kernel.org More majordomo info at http://vger.kernel.org/majordomo-info.html
Re: [PATCH v3 06/13] mmc: mmci: Qcomm: Add 3 clock cycle delay after register write
I am not sure I like this approach. For each and every writel (including pio_writes) you will add a few cpu cycles, since you need to check for mclk_delayed_writes no matter of variant. How about, adding a new function pointer in the struct mmci_host, for writel operations which you could set up in probe phase instead? Yes, this is an additional check for other variants. I will try the function pointer method that you suggested. Thanks, srini Kind regards Ulf Hansson -- To unsubscribe from this list: send the line unsubscribe linux-arm-msm in the body of a message to majord...@vger.kernel.org More majordomo info at http://vger.kernel.org/majordomo-info.html
Re: [PATCH v3 07/13] mmc: mmci: add ddrmode mask to variant data
On 26/05/14 10:53, Ulf Hansson wrote: On 23 May 2014 14:51, srinivas.kandaga...@linaro.org wrote: From: Srinivas Kandagatla srinivas.kandaga...@linaro.org This patch adds ddrmode mask to variant structure giving more flexibility to the driver to support more SOCs which have different datactrl register layout. Without this patch datactrl register is updated with wrong ddrmode mask on non ST SOCs, resulting in card detection failures. Signed-off-by: Srinivas Kandagatla srinivas.kandaga...@linaro.org Reviewed-by: Linus Walleij linus.wall...@linaro.org --- drivers/mmc/host/mmci.c | 8 +++- 1 file changed, 7 insertions(+), 1 deletion(-) diff --git a/drivers/mmc/host/mmci.c b/drivers/mmc/host/mmci.c index 1385554..dec70d2 100644 --- a/drivers/mmc/host/mmci.c +++ b/drivers/mmc/host/mmci.c @@ -59,6 +59,7 @@ static unsigned int fmax = 515633; * is asserted (likewise for RX) * @sdio: variant supports SDIO * @st_clkdiv: true if using a ST-specific clock divider algorithm + * @datactrl_mask_ddrmode: ddr mode mask in datactrl register. * @blksz_datactrl16: true if Block size is at b16..b30 position in datactrl register * @blksz_datactrl4: true if Block size is at b4..b16 position in datactrl * register @@ -76,6 +77,7 @@ struct variant_data { unsigned intdatalength_bits; unsigned intfifosize; unsigned intfifohalfsize; + unsigned intdatactrl_mask_ddrmode; boolsdio; boolst_clkdiv; boolblksz_datactrl16; @@ -114,6 +116,7 @@ static struct variant_data variant_u300 = { .fifosize = 16 * 4, .fifohalfsize = 8 * 4, .clkreg_enable = MCI_ST_U300_HWFCEN, + .datactrl_mask_ddrmode = MCI_ST_DPSM_DDRMODE, .datalength_bits= 16, .sdio = true, .pwrreg_powerup = MCI_PWR_ON, @@ -126,6 +129,7 @@ static struct variant_data variant_nomadik = { .fifosize = 16 * 4, .fifohalfsize = 8 * 4, .clkreg = MCI_CLK_ENABLE, + .datactrl_mask_ddrmode = MCI_ST_DPSM_DDRMODE, .datalength_bits= 24, .sdio = true, .st_clkdiv = true, @@ -140,6 +144,7 @@ static struct variant_data variant_ux500 = { .fifohalfsize = 8 * 4, .clkreg = MCI_CLK_ENABLE, .clkreg_enable = MCI_ST_UX500_HWFCEN, + .datactrl_mask_ddrmode = MCI_ST_DPSM_DDRMODE, .datalength_bits= 24, .sdio = true, .st_clkdiv = true, @@ -155,6 +160,7 @@ static struct variant_data variant_ux500v2 = { .fifohalfsize = 8 * 4, .clkreg = MCI_CLK_ENABLE, .clkreg_enable = MCI_ST_UX500_HWFCEN, + .datactrl_mask_ddrmode = MCI_ST_DPSM_DDRMODE, Only the ux500v2 supports DDR mode, using the MCI_ST_DPSM_DDRMODE bit. Thanks for pointing this out, I was not sure which variants actually used this bit, so just replicated what was there before this change. I will add this flag to only ux500v2 in next version. Thanks, srini .datalength_bits= 24, .sdio = true, .st_clkdiv = true, @@ -800,7 +806,7 @@ static void mmci_start_data(struct mmci_host *host, struct mmc_data *data) } if (host-mmc-ios.timing == MMC_TIMING_UHS_DDR50) - datactrl |= MCI_ST_DPSM_DDRMODE; + datactrl |= variant-datactrl_mask_ddrmode; /* * Attempt to use DMA operation mode, if this -- 1.9.1 Kind regards Ulf Hansson -- To unsubscribe from this list: send the line unsubscribe linux-arm-msm in the body of a message to majord...@vger.kernel.org More majordomo info at http://vger.kernel.org/majordomo-info.html
Re: [PATCH v3 13/13] mmc: mmci: Add Qcom specific pio_read function.
On 26/05/14 15:34, Ulf Hansson wrote: This is hot path. As I suggested for the readl and writel wrapper functions, I think it would be better to use a function pointer in the struct mmci host, which you set up in the probe phase. That means the variant data don't need to be checked each an every time this function gets invoked. + if (status MCI_TXACTIVE) len = mmci_pio_write(host, buffer, remain, status); So no changes needed for pio_write at this point? Or those will come later? Yes, that sounds like more sensible approach to me. I will do this change in next version. Thanks, srini -- -- To unsubscribe from this list: send the line unsubscribe linux-arm-msm in the body of a message to majord...@vger.kernel.org More majordomo info at http://vger.kernel.org/majordomo-info.html
Re: [PATCH v3 10/13] mmc: mmci: add Qcom specifics of clk and datactrl registers.
Hi Ulf, Thanks for the comments. On 26/05/14 14:05, Ulf Hansson wrote: On 23 May 2014 14:52, srinivas.kandaga...@linaro.org wrote: From: Srinivas Kandagatla srinivas.kandaga...@linaro.org This patch adds specifics of clk and datactrl register on Qualcomm SD Card controller. This patch also populates the Qcom variant data with these new values specific to Qualcomm SD Card Controller. Signed-off-by: Srinivas Kandagatla srinivas.kandaga...@linaro.org Reviewed-by: Linus Walleij linus.wall...@linaro.org --- drivers/mmc/host/mmci.c | 4 drivers/mmc/host/mmci.h | 24 2 files changed, 28 insertions(+) diff --git a/drivers/mmc/host/mmci.c b/drivers/mmc/host/mmci.c index 17e7f6a..6434f5b1 100644 --- a/drivers/mmc/host/mmci.c +++ b/drivers/mmc/host/mmci.c @@ -185,6 +185,10 @@ static struct variant_data variant_qcom = { .fifosize = 16 * 4, .fifohalfsize = 8 * 4, .clkreg = MCI_CLK_ENABLE, + .clkreg_enable = MCI_QCOM_CLK_FLOWENA | + MCI_QCOM_CLK_FEEDBACK_CLK, Obviously I don't have the in-depth knowledge about the Qcom variant, but comparing the ST variant here made me think. Using the feeback clock internal logic in the ST variant, requires the corresponding feedback clock pin signal on the board, to be routed/connected. Typically we used this for SD cards, which involved using an external level shifter circuit. Is it correct to enable this bit for all cases, including eMMC? You are correct, FBCLK should specific to the board, and I will try to do something on the same lines as ST variant in next version. If it is board specific configurations, you should add a DT binding for it - like there are for the ST variant. + .clkreg_8bit_bus_enable = MCI_QCOM_CLK_WIDEBUS_8, + .datactrl_mask_ddrmode = MCI_QCOM_CLK_DDR_MODE, .blksz_datactrl4= true, .datalength_bits= 24, .blksz_datactrl4= true, diff --git a/drivers/mmc/host/mmci.h b/drivers/mmc/host/mmci.h index cd83ca3..1b93ae7 100644 --- a/drivers/mmc/host/mmci.h +++ b/drivers/mmc/host/mmci.h @@ -41,6 +41,22 @@ /* Modified PL180 on Versatile Express platform */ #define MCI_ARM_HWFCEN BIT(12) +/* Modified on Qualcomm Integrations */ +#define MCI_QCOM_CLK_WIDEBUS_4 (2 10) This is the same as BIT(11), please use MCI_4BIT_BUS instead. This is not used in the code, I will clean it up as you suggested, just to be more consistent. +#define MCI_QCOM_CLK_WIDEBUS_8 (3 10) Since you converted to use the BIT macro a few patches ago, I suggest we should stick to it. How about something below: #define MCI_QCOM_CLK_WIDEBUS_8 BIT (BIT(10) | BIT(11)) Sounds good, I will fix all such instances in next version. Please adopt all defines added in this patch to use the BIT macro. +#define MCI_QCOM_CLK_FLOWENA BIT(12) +#define MCI_QCOM_CLK_INVERTOUT BIT(13) + +/* select in latch data and command */ +#define MCI_QCOM_CLK_SEL_IN_SHIFT (14) BIT (14)? +#define MCI_QCOM_CLK_SEL_MASK (0x3) +#define MCI_QCOM_CLK_SEL_RISING_EDGE (1) BIT(1)? +#define MCI_QCOM_CLK_FEEDBACK_CLK (2 14) +#define MCI_QCOM_CLK_DDR_MODE (3 14) + +/* mclk selection */ +#define MCI_QCOM_CLK_SEL_MCLK (2 23) Does this correspond to MCI_CLK_BYPASS? If so, we should maybe state this in a comment? No, this is not same as MCI_CLK_BYPASS, its selection between FBCLK/gated MCLK/freerunning MCLK. Thanks, srini -- To unsubscribe from this list: send the line unsubscribe linux-arm-msm in the body of a message to majord...@vger.kernel.org More majordomo info at http://vger.kernel.org/majordomo-info.html
Re: [PATCH v3 12/13] mmc: mmci: add explicit clk control
Hi Ulf, Thankyou for the comments. On 26/05/14 15:21, Ulf Hansson wrote: On 23 May 2014 14:52, srinivas.kandaga...@linaro.org wrote: From: Srinivas Kandagatla srinivas.kandaga...@linaro.org On Controllers like Qcom SD card controller where cclk is mclk and mclk should be directly controlled by the driver. This patch adds support to control mclk directly in the driver, and also adds explicit_mclk_control and cclk_is_mclk flags in variant structure giving more flexibility to the driver. Signed-off-by: Srinivas Kandagatla srinivas.kandaga...@linaro.org Reviewed-by: Linus Walleij linus.wall...@linaro.org --- drivers/mmc/host/mmci.c | 30 +- 1 file changed, 25 insertions(+), 5 deletions(-) diff --git a/drivers/mmc/host/mmci.c b/drivers/mmc/host/mmci.c index 5cbf644..f6dfd24 100644 --- a/drivers/mmc/host/mmci.c +++ b/drivers/mmc/host/mmci.c @@ -73,6 +73,8 @@ static unsigned int fmax = 515633; * @pwrreg_nopower: bits in MMCIPOWER don't controls ext. power supply * @mclk_delayed_writes: enable delayed writes to ensure, subsequent updates * are not ignored. + * @explicit_mclk_control: enable explicit mclk control in driver. + * @cclk_is_mclk: enable iff card clock is multimedia card adapter clock. */ struct variant_data { unsigned intclkreg; @@ -94,6 +96,8 @@ struct variant_data { boolbusy_detect; boolpwrreg_nopower; boolmclk_delayed_writes; + boolexplicit_mclk_control; + boolcclk_is_mclk; I can't see why you need to have both these new configurations. Aren't cclk_is_mclk just a fact when you use explicit_mclk_control. I also believe I would prefer something like qcom_clkdiv instead. There is a subtle difference between both the flags. Am happy to change it to qcom_clkdiv. }; static struct variant_data variant_arm = { @@ -202,6 +206,8 @@ static struct variant_data variant_qcom = { * for 3 clk cycles. */ .mclk_delayed_writes= true, + .explicit_mclk_control = true, + .cclk_is_mclk = true, }; static inline u32 mmci_readl(struct mmci_host *host, u32 off) @@ -317,7 +323,9 @@ static void mmci_set_clkreg(struct mmci_host *host, unsigned int desired) host-cclk = 0; if (desired) { - if (desired = host-mclk) { + if (variant-cclk_is_mclk) { + host-cclk = host-mclk; + } else if (desired = host-mclk) { clk = MCI_CLK_BYPASS; if (variant-st_clkdiv) clk |= MCI_ST_UX500_NEG_EDGE; @@ -1354,6 +1362,16 @@ static void mmci_set_ios(struct mmc_host *mmc, struct mmc_ios *ios) if (!ios-clock variant-pwrreg_clkgate) pwr = ~MCI_PWR_ON; + if (ios-clock != host-mclk host-variant-explicit_mclk_control) { I suggest you should clarify the statement by adding a pair of extra parentheses. Additionally it seems like a good idea to reverse the order of the statements, to clarify this is for qcom clock handling only. Yes, sure Will fix this in next version. More important, what I think you really want to do is to compare ios-clock with it's previous value it had when -set_ios were invoked. Then let a changed value act as the trigger to set a new clk rate. Obvoiusly you need to cache the clock rate in the struct mmci host to handle this. host-mclk already has this cached value. + int rc = clk_set_rate(host-clk, ios-clock); + if (rc 0) { + dev_err(mmc_dev(host-mmc), + Error setting clock rate (%d)\n, rc); + } else { + host-mclk = clk_get_rate(host-clk); So here you actually find out the new clk rate, but shouldn't you update host-mclk within the spin_lock? Or it might not matter? I think it does not matter in this case, as this is the only place mclk gets modified. + } + } + spin_lock_irqsave(host-lock, flags); mmci_set_clkreg(host, ios-clock); @@ -1540,10 +1558,12 @@ static int mmci_probe(struct amba_device *dev, * is not specified. Either value must not exceed the clock rate into * the block, of course. */ - if (mmc-f_max) - mmc-f_max = min(host-mclk, mmc-f_max); - else - mmc-f_max = min(host-mclk, fmax); + if (!host-variant-explicit_mclk_control) { + if (mmc-f_max) + mmc-f_max = min(host-mclk, mmc-f_max); + else + mmc-f_max = min(host-mclk, fmax); + } This means your mmc-f_max value will either be zero or the one you provided through DT. And since zero won't work, that means you _require_ to get the value from DT. According
Re: [PATCH v3 12/13] mmc: mmci: add explicit clk control
On 27/05/14 10:32, Ulf Hansson wrote: On 27 May 2014 00:39, Srinivas Kandagatla srinivas.kandaga...@linaro.org wrote: Hi Ulf, Thankyou for the comments. On 26/05/14 15:21, Ulf Hansson wrote: On 23 May 2014 14:52, srinivas.kandaga...@linaro.org wrote: From: Srinivas Kandagatla srinivas.kandaga...@linaro.org On Controllers like Qcom SD card controller where cclk is mclk and mclk should be directly controlled by the driver. ... * for 3 clk cycles. */ .mclk_delayed_writes= true, + .explicit_mclk_control = true, + .cclk_is_mclk = true, }; static inline u32 mmci_readl(struct mmci_host *host, u32 off) @@ -317,7 +323,9 @@ static void mmci_set_clkreg(struct mmci_host *host, unsigned int desired) host-cclk = 0; if (desired) { - if (desired = host-mclk) { + if (variant-cclk_is_mclk) { + host-cclk = host-mclk; + } else if (desired = host-mclk) { clk = MCI_CLK_BYPASS; if (variant-st_clkdiv) clk |= MCI_ST_UX500_NEG_EDGE; @@ -1354,6 +1362,16 @@ static void mmci_set_ios(struct mmc_host *mmc, struct mmc_ios *ios) if (!ios-clock variant-pwrreg_clkgate) pwr = ~MCI_PWR_ON; + if (ios-clock != host-mclk host-variant-explicit_mclk_control) { I suggest you should clarify the statement by adding a pair of extra parentheses. Additionally it seems like a good idea to reverse the order of the statements, to clarify this is for qcom clock handling only. Yes, sure Will fix this in next version. More important, what I think you really want to do is to compare ios-clock with it's previous value it had when -set_ios were invoked. Then let a changed value act as the trigger to set a new clk rate. Obvoiusly you need to cache the clock rate in the struct mmci host to handle this. host-mclk already has this cached value. There are no guarantees clk_set_rate() will manage to set the exact requested rate as ios-clock. At least if you follow the clk API documentation. Yes, I agree. caching ios-clock looks like the best option. ... + } + } + spin_lock_irqsave(host-lock, flags); mmci_set_clkreg(host, ios-clock); @@ -1540,10 +1558,12 @@ static int mmci_probe(struct amba_device *dev, * is not specified. Either value must not exceed the clock rate into * the block, of course. */ - if (mmc-f_max) - mmc-f_max = min(host-mclk, mmc-f_max); - else - mmc-f_max = min(host-mclk, fmax); + if (!host-variant-explicit_mclk_control) { + if (mmc-f_max) + mmc-f_max = min(host-mclk, mmc-f_max); + else + mmc-f_max = min(host-mclk, fmax); + } This means your mmc-f_max value will either be zero or the one you provided through DT. And since zero won't work, that means you _require_ to get the value from DT. According to the documentation of this DT binding, f_max is optional. So unless you fine another way of dynamically at runtime figure out the value of f_max (using the clk API), you need to update the DT documentation for mmci. You are right there is a possibility of f_max to be zero. This logic could fix it. if (host-variant-explicit_mclk_control) { if (mmc-f_max) mmc-f_max = max(host-mclk, mmc-f_max); else mmc-f_max = max(host-mclk, fmax); } else { if (mmc-f_max) mmc-f_max = min(host-mclk, mmc-f_max); else mmc-f_max = min(host-mclk, fmax); } Hmm. Looking a bit deeper into this, we have some additional related code to fixup. :-) In -probe(), we do clk_set_rate(100MHz), if the mclk 100MHz. That's due to the current variants don't support higher frequency than this. It seems like the Qcom variant may support up to 208MHz? Now, if that's the case, we need to add f_max to the struct variant_data to store this information, so we can respect different values while doing clk_set_rate() at -probe(). Yes, qcom SOCs support more than 100Hhz clock. Probe and clk_set_rate/set_ios should respect this. On the other thought, Should probe actually care about clocks which are explicitly controlled? It should not even attempt to set any frequency to start with. mmc-core would set the right frequency depending on the mmc state-machine respecting f_min and f_max. I think for qcom, probe should just check the if f_max and f_min are valid and set them to defaults if any in the same lines as existing code. While updating mmc-f_max for host-variant-explicit_mclk_control, we shouldn't care about using the host-mclk as a limiter, instead, use min(mmc-f_max, host-variant-f_max) and fallback to fmax. Yes, that's correct, mclk should not be used as limiter. Adding
Re: [PATCH v3 03/13] mmc: mmci: Add Qualcomm Id to amba id table
On 26/05/14 18:00, Srinivas Kandagatla wrote: Hi Ulf, On 26/05/14 10:10, Ulf Hansson wrote: Hi Srinivas, +static struct variant_data variant_qcom = { + .fifosize = 16 * 4, + .fifohalfsize = 8 * 4, + .clkreg = MCI_CLK_ENABLE, + .datalength_bits= 24, + .blksz_datactrl4= true, You get compile error here. yes, You are right, I will reorder this patch after the mmc: mmci: Add Qcom datactrl register variant Actually, blksz_datactrl4 should not be in this patch. it is part of mmc: mmci: Add Qcom datactrl register variant will remove it from this patch in next version. --srini Thanks, srini Kind regards Ulf Hansson -- To unsubscribe from this list: send the line unsubscribe linux-arm-msm in the body of a message to majord...@vger.kernel.org More majordomo info at http://vger.kernel.org/majordomo-info.html
Re: [PATCH v3 12/13] mmc: mmci: add explicit clk control
On 27/05/14 15:07, Ulf Hansson wrote: Hmm. Looking a bit deeper into this, we have some additional related code to fixup. :-) In -probe(), we do clk_set_rate(100MHz), if the mclk 100MHz. That's due to the current variants don't support higher frequency than this. It seems like the Qcom variant may support up to 208MHz? Now, if that's the case, we need to add f_max to the struct variant_data to store this information, so we can respect different values while doing clk_set_rate() at -probe(). Yes, qcom SOCs support more than 100Hhz clock. Probe and clk_set_rate/set_ios should respect this. On the other thought, Should probe actually care about clocks which are explicitly controlled? It should not even attempt to set any frequency to start with. The 100 MHz is related to constraints set by the specification of the IP block, not the MMC/SD/SDIO spec. Thus at -probe() we must perform the clk_set_rate(). I agree its valid for controllers which have this constraints. mmc-core would set the right frequency depending on the mmc state-machine respecting f_min and f_max. I think for qcom, probe should just check the if f_max and f_min are valid and set them to defaults if any in the same lines as existing code. While updating mmc-f_max for host-variant-explicit_mclk_control, we shouldn't care about using the host-mclk as a limiter, instead, use min(mmc-f_max, host-variant-f_max) and fallback to fmax. Yes, that's correct, mclk should not be used as limiter. Adding f_max to the variant looks useful. Not sure how that will affect the logic. :-) Additionally, this makes me wonder about f_min. I haven't seen anywhere in this patch were that value is being set to proper value, right? f_min should be 40 for qcom, I think with the default mclk frequency and a divider of 512 used for calculating the f_min is bringing down the f_min to lessthan 400Kz. Which is why its working fine. I think the possibility of mclk default frequency being greater than 208Mhz is very less. so I could either leave it as it is Or force this to 40 all the time for qcom chips. No, this seems like a wrong approach. I think you would like to do use the clk_round_rate() find out the lowest possible rate. Or just use a fixed fallback value somehow. clk_round_rate(mclk, 0) might be more generic, instead of fixed fallback. Let the mmc-core figure out what frequency would be best from its table starting from f_min. Agree! clk_round_rate(mclk, 100KHz), might be better though - since that is actually the lowest request frequency whatsoever. Perfect. --srini Kind regards Ulf Hansson -- To unsubscribe from this list: send the line unsubscribe linux-arm-msm in the body of a message to majord...@vger.kernel.org More majordomo info at http://vger.kernel.org/majordomo-info.html
Re: [PATCH v3 08/13] mmc: mmci: add 8bit bus support in variant data
Hi Linus W, On 26/05/14 11:07, Ulf Hansson wrote: unsigned intfifosize; unsigned intfifohalfsize; @@ -116,6 +118,7 @@ static struct variant_data variant_u300 = { .fifosize = 16 * 4, .fifohalfsize = 8 * 4, .clkreg_enable = MCI_ST_U300_HWFCEN, + .clkreg_8bit_bus_enable = MCI_ST_8BIT_BUS, Linus, will have to confirm this. I don't know if the u300 variant support 8-bit. Do you know if u300 supports 8BIT bus? thanks, srini Kind regards Ulf Hansson -- To unsubscribe from this list: send the line unsubscribe linux-arm-msm in the body of a message to majord...@vger.kernel.org More majordomo info at http://vger.kernel.org/majordomo-info.html
Re: [PATCH v3 12/13] mmc: mmci: add explicit clk control
On 28/05/14 09:02, Linus Walleij wrote: On Tue, May 27, 2014 at 12:39 AM, Srinivas Kandagatla srinivas.kandaga...@linaro.org wrote: On 26/05/14 15:21, Ulf Hansson wrote: On 23 May 2014 14:52, srinivas.kandaga...@linaro.org wrote: + boolexplicit_mclk_control; + boolcclk_is_mclk; I can't see why you need to have both these new configurations. Aren't cclk_is_mclk just a fact when you use explicit_mclk_control. I also believe I would prefer something like qcom_clkdiv instead. There is a subtle difference between both the flags. Am happy to change it to qcom_clkdiv. I think this was due to me wanting the variant variables to be more about the actual technical difference they indicate rather than pointing to a certain vendor or variant where that difference occurs. Yes, that's correct, I think having these two variables seems to be more generic than qcom_clkdiv. I will keep it as it is and fix other comments from Ulf in next version. It's a very minor thing though, if you prefer it this way, go for it. Thanks, sirni Yours, Linus Walleij -- To unsubscribe from this list: send the line unsubscribe linux-arm-msm in the body of a message to majord...@vger.kernel.org More majordomo info at http://vger.kernel.org/majordomo-info.html
Re: [PATCH v3 13/13] mmc: mmci: Add Qcom specific pio_read function.
On 28/05/14 09:08, Linus Walleij wrote: On Fri, May 23, 2014 at 2:53 PM, srinivas.kandaga...@linaro.org wrote: + if (unlikely(bytes)) { + unsigned char buf[4]; (...) Please think twice about this. http://lwn.net/Articles/70473/ http://lwn.net/Articles/420019/ http://lwn.net/Articles/182369/ Thanks for the warning. You are right. I think having likely/unlikely is not always right here. thanks, srini Yours, Linus Walleij -- To unsubscribe from this list: send the line unsubscribe linux-arm-msm in the body of a message to majord...@vger.kernel.org More majordomo info at http://vger.kernel.org/majordomo-info.html
Re: [PATCH v3 10/13] mmc: mmci: add Qcom specifics of clk and datactrl registers.
Hi Ulf, On 26/05/14 22:38, Srinivas Kandagatla wrote: 2 files changed, 28 insertions(+) diff --git a/drivers/mmc/host/mmci.c b/drivers/mmc/host/mmci.c index 17e7f6a..6434f5b1 100644 --- a/drivers/mmc/host/mmci.c +++ b/drivers/mmc/host/mmci.c @@ -185,6 +185,10 @@ static struct variant_data variant_qcom = { .fifosize = 16 * 4, .fifohalfsize = 8 * 4, .clkreg = MCI_CLK_ENABLE, + .clkreg_enable = MCI_QCOM_CLK_FLOWENA | + MCI_QCOM_CLK_FEEDBACK_CLK, Obviously I don't have the in-depth knowledge about the Qcom variant, but comparing the ST variant here made me think. Using the feeback clock internal logic in the ST variant, requires the corresponding feedback clock pin signal on the board, to be routed/connected. Typically we used this for SD cards, which involved using an external level shifter circuit. Is it correct to enable this bit for all cases, including eMMC? You are correct, FBCLK should specific to the board, and I will try to do something on the same lines as ST variant in next version. I get lot of I/O errors when I remove this flag for test. I rechecked schematics and datasheet, the feedback clk that we refer here is the the feedback clk from CLK pad, there is no separate input pad for fbclk. So I think this is internally feedbacked clk. This selection is configuring bits to latch data and command coming in using feedback clock from CLK pad. I will make sure that the macro is named more appropriately to reflect the same. thanks, srini -- To unsubscribe from this list: send the line unsubscribe linux-arm-msm in the body of a message to majord...@vger.kernel.org More majordomo info at http://vger.kernel.org/majordomo-info.html
[PATCH v4 00/13] Add Qualcomm SD Card Controller support
From: Srinivas Kandagatla srinivas.kandaga...@linaro.org Thankyou Linus W, Ulf H and everyone for reviewing RFC to v3 patches. This patch series adds Qualcomm SD Card Controller support in pl180 mmci driver. QCom SDCC is basically a pl180, but bit more customized, some of the register layouts and offsets are different to the ones mentioned in pl180 datasheet. The plan is to totally remove the standalone SDCC driver drivers/mmc/host/msm_sdcc.* and start using generic mmci driver for all Qualcomm parts, as we get chance to test on other Qcom boards. To start using the existing mmci driver, a fake amba id for Qualcomm is added in patches: mmc: mmci: Add Qualcomm Id to amba id table. Second change is, adding a 3 clock cycle delay in between writes to CLKCTRL/POWER/DATACTRL/COMMAND registers. Most of the delays are taken care with the existing driver except delay for the COMMAND register was too small. This patch fixes it. mmc: mmci: Add enough delay between writes to CMD register. Third change is to accommodate CLK, DATCTRL and MMCICLK register layout changes in Qcom SDCC and provide more flexibity in driver to specify these changes via variant datastructure. Which are done in patches: mmc: mmci: Add Qcom datactrl register variant mmc: mmci: add ddrmode mask to variant data mmc: mmci: add 8bit bus support in variant data mmc: mmci: add edge support to data and command out in variant data. mmc: mmci: add Qcom specifics of clk and datactrl registers. mmc: mmci: Add support to data commands via variant structure. mmc: mmci: add f_max to variant structure mmc: mmci: add explicit clk control Fourth major change was to add qcom specfic pio read function, the need for this is because the way MCIFIFOCNT register behaved in QCOM SDCC is very different to the one in pl180. This change is done in patch: mmc: mmci: Add Qcom specific pio_read function. Last some Qcom unrelated changes/cleanup to driver are done in patches: mmc: mmci: use NSEC_PER_SEC macro mmc: mmci: convert register bits to use BIT() macro. This patches are tested in PIO mode on IFC8064 board with both eMMC and external SD card. I would like to get this support in v3.16. Bjorn also confirmed that there are no more CRC errors seen on sony platform. Changes from v3: - moved pio_read to a function pointer so as to reduce additional cycles in hot-path, suggested by Ulf. - simplify the flags used for explicit mclk control, suggested by Ulf. - fixed issues in cacluating f_max and f_min pointed and suggested by Ulf. - removed unessary DDR flags on un-supported STE variants. - used BIT macros as suggested by Ulf. - removed the read/write wrappers with delays, and used most optimal way to introduce the delays to the only registers that require delays. Changes from v2: - merged fbclk latch patch with clkreg_enable patch as suggested by Linus W. - remove qcom prefix for explicit clk control pointed by Linus W. - cleaned up mmci_qcom_pio_read and consider SDIO as suggested by Linus W. Changes from v1: - moved most of the SOC specifics to variant parameters as suggested by Linus W. - renamed registers as suggested by Linus W. - Added comments in the code as suggested by Linus W. - moved out AMBA ID addition patch from this series. - rebased the patches to git://git.linaro.org/people/ulf.hansson/mmc.git next as suggested by Ulf H. Changes from RFC: - moved out clk setup out of spinlock as pointed by Stephen B. If its not too late, Am hoping to get this for v3.16. All these patches are tested on IF6410 board on both eMMC and external SD card. Thanks, srini Srinivas Kandagatla (13): mmc: mmci: use NSEC_PER_SEC macro mmc: mmci: convert register bits to use BIT() macro. mmc: mmci: Add Qualcomm Id to amba id table mmc: mmci: Add enough delay between writes to CMD register. mmc: mmci: Add Qcom datactrl register variant mmc: mmci: add ddrmode mask to variant data mmc: mmci: add 8bit bus support in variant data mmc: mmci: add edge support to data and command out in variant data. mmc: mmci: add Qcom specifics of clk and datactrl registers. mmc: mmci: Add support to data commands via variant structure. mmc: mmci: add f_max to variant structure mmc: mmci: add explicit clk control mmc: mmci: Add Qcom specific pio_read function. drivers/mmc/host/mmci.c | 203 +- drivers/mmc/host/mmci.h | 228 ++-- 2 files changed, 288 insertions(+), 143 deletions(-) -- 1.9.1 -- To unsubscribe from this list: send the line unsubscribe linux-arm-msm in the body of a message to majord...@vger.kernel.org More majordomo info at http://vger.kernel.org/majordomo-info.html
[PATCH v4 01/13] mmc: mmci: use NSEC_PER_SEC macro
From: Srinivas Kandagatla srinivas.kandaga...@linaro.org This patch replaces a constant used in calculating timeout with a proper macro. This is make code more readable. Signed-off-by: Srinivas Kandagatla srinivas.kandaga...@linaro.org Reviewed-by: Linus Walleij linus.wall...@linaro.org --- drivers/mmc/host/mmci.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/drivers/mmc/host/mmci.c b/drivers/mmc/host/mmci.c index a084edd..a38e714 100644 --- a/drivers/mmc/host/mmci.c +++ b/drivers/mmc/host/mmci.c @@ -718,7 +718,7 @@ static void mmci_start_data(struct mmci_host *host, struct mmc_data *data) data-bytes_xfered = 0; clks = (unsigned long long)data-timeout_ns * host-cclk; - do_div(clks, 10UL); + do_div(clks, NSEC_PER_SEC); timeout = data-timeout_clks + (unsigned int)clks; -- 1.9.1 -- To unsubscribe from this list: send the line unsubscribe linux-arm-msm in the body of a message to majord...@vger.kernel.org More majordomo info at http://vger.kernel.org/majordomo-info.html
[PATCH v4 05/13] mmc: mmci: Add Qcom datactrl register variant
From: Srinivas Kandagatla srinivas.kandaga...@linaro.org Instance of this IP on Qualcomm's SOCs has bit different layout for datactrl register. Bit position datactrl[16:4] hold the true block size instead of power of 2. Signed-off-by: Srinivas Kandagatla srinivas.kandaga...@linaro.org Reviewed-by: Linus Walleij linus.wall...@linaro.org --- drivers/mmc/host/mmci.c | 6 ++ 1 file changed, 6 insertions(+) diff --git a/drivers/mmc/host/mmci.c b/drivers/mmc/host/mmci.c index aa2d381..23401b0 100644 --- a/drivers/mmc/host/mmci.c +++ b/drivers/mmc/host/mmci.c @@ -60,6 +60,8 @@ static unsigned int fmax = 515633; * @sdio: variant supports SDIO * @st_clkdiv: true if using a ST-specific clock divider algorithm * @blksz_datactrl16: true if Block size is at b16..b30 position in datactrl register + * @blksz_datactrl4: true if Block size is at b4..b16 position in datactrl + * register * @pwrreg_powerup: power up value for MMCIPOWER register * @signal_direction: input/out direction of bus signals can be indicated * @pwrreg_clkgate: MMCIPOWER register must be used to gate the clock @@ -75,6 +77,7 @@ struct variant_data { boolsdio; boolst_clkdiv; boolblksz_datactrl16; + boolblksz_datactrl4; u32 pwrreg_powerup; boolsignal_direction; boolpwrreg_clkgate; @@ -164,6 +167,7 @@ static struct variant_data variant_qcom = { .fifosize = 16 * 4, .fifohalfsize = 8 * 4, .clkreg = MCI_CLK_ENABLE, + .blksz_datactrl4= true, .datalength_bits= 24, .pwrreg_powerup = MCI_PWR_UP, }; @@ -739,6 +743,8 @@ static void mmci_start_data(struct mmci_host *host, struct mmc_data *data) if (variant-blksz_datactrl16) datactrl = MCI_DPSM_ENABLE | (data-blksz 16); + else if (variant-blksz_datactrl4) + datactrl = MCI_DPSM_ENABLE | (data-blksz 4); else datactrl = MCI_DPSM_ENABLE | blksz_bits 4; -- 1.9.1 -- To unsubscribe from this list: send the line unsubscribe linux-arm-msm in the body of a message to majord...@vger.kernel.org More majordomo info at http://vger.kernel.org/majordomo-info.html
[PATCH v4 12/13] mmc: mmci: add explicit clk control
From: Srinivas Kandagatla srinivas.kandaga...@linaro.org On Controllers like Qcom SD card controller where cclk is mclk and mclk should be directly controlled by the driver. This patch adds support to control mclk directly in the driver, and also adds explicit_mclk_control flag in variant structure giving more flexibility to the driver. Signed-off-by: Srinivas Kandagatla srinivas.kandaga...@linaro.org --- drivers/mmc/host/mmci.c | 96 - drivers/mmc/host/mmci.h | 2 ++ 2 files changed, 65 insertions(+), 33 deletions(-) diff --git a/drivers/mmc/host/mmci.c b/drivers/mmc/host/mmci.c index 202f2d5..6eb0a29 100644 --- a/drivers/mmc/host/mmci.c +++ b/drivers/mmc/host/mmci.c @@ -72,6 +72,7 @@ static unsigned int fmax = 515633; * @pwrreg_clkgate: MMCIPOWER register must be used to gate the clock * @busy_detect: true if busy detection on dat0 is supported * @pwrreg_nopower: bits in MMCIPOWER don't controls ext. power supply + * @explicit_mclk_control: enable explicit mclk control in driver. */ struct variant_data { unsigned intclkreg; @@ -93,6 +94,7 @@ struct variant_data { boolpwrreg_clkgate; boolbusy_detect; boolpwrreg_nopower; + boolexplicit_mclk_control; }; static struct variant_data variant_arm = { @@ -199,6 +201,7 @@ static struct variant_data variant_qcom = { .datalength_bits= 24, .pwrreg_powerup = MCI_PWR_UP, .f_max = 20800, + .explicit_mclk_control = true, }; static int mmci_card_busy(struct mmc_host *mmc) @@ -301,7 +304,9 @@ static void mmci_set_clkreg(struct mmci_host *host, unsigned int desired) host-cclk = 0; if (desired) { - if (desired = host-mclk) { + if (variant-explicit_mclk_control) { + host-cclk = host-mclk; + } else if (desired = host-mclk) { clk = MCI_CLK_BYPASS; if (variant-st_clkdiv) clk |= MCI_ST_UX500_NEG_EDGE; @@ -1340,6 +1345,18 @@ static void mmci_set_ios(struct mmc_host *mmc, struct mmc_ios *ios) if (!ios-clock variant-pwrreg_clkgate) pwr = ~MCI_PWR_ON; + if ((host-variant-explicit_mclk_control) + (ios-clock != host-mclk_req)) { + int rc = clk_set_rate(host-clk, ios-clock); + if (rc 0) { + dev_err(mmc_dev(host-mmc), + Error setting clock rate (%d)\n, rc); + } else { + host-mclk = clk_get_rate(host-clk); + host-mclk_req = ios-clock; + } + } + spin_lock_irqsave(host-lock, flags); mmci_set_clkreg(host, ios-clock); @@ -1490,19 +1507,6 @@ static int mmci_probe(struct amba_device *dev, host-plat = plat; host-variant = variant; host-mclk = clk_get_rate(host-clk); - /* -* According to the spec, mclk is max 100 MHz, -* so we try to adjust the clock down to this, -* (if possible). -*/ - if (host-mclk host-variant-f_max) { - ret = clk_set_rate(host-clk, host-variant-f_max); - if (ret 0) - goto clk_disable; - host-mclk = clk_get_rate(host-clk); - dev_dbg(mmc_dev(mmc), eventual mclk rate: %u Hz\n, - host-mclk); - } host-phybase = dev-res.start; host-base = devm_ioremap_resource(dev-dev, dev-res); @@ -1511,25 +1515,51 @@ static int mmci_probe(struct amba_device *dev, goto clk_disable; } - /* -* The ARM and ST versions of the block have slightly different -* clock divider equations which means that the minimum divider -* differs too. -*/ - if (variant-st_clkdiv) - mmc-f_min = DIV_ROUND_UP(host-mclk, 257); - else - mmc-f_min = DIV_ROUND_UP(host-mclk, 512); - /* -* If no maximum operating frequency is supplied, fall back to use -* the module parameter, which has a (low) default value in case it -* is not specified. Either value must not exceed the clock rate into -* the block, of course. -*/ - if (mmc-f_max) - mmc-f_max = min(host-mclk, mmc-f_max); - else - mmc-f_max = min(host-mclk, fmax); + if (variant-explicit_mclk_control) { + /* get the nearest minimum clock to 100Khz */ + mmc-f_min = clk_round_rate(host-clk, 10); + + if (mmc-f_max) + mmc-f_max = min(host-variant-f_max, mmc-f_max); + else + mmc-f_max = min(host-variant-f_max, fmax); + + } else
[PATCH v4 11/13] mmc: mmci: add f_max to variant structure
From: Srinivas Kandagatla srinivas.kandaga...@linaro.org Some of the controller have maximum supported frequency, This patch adds support in variant data structure to specify such restrictions. This gives more flexibility in calculating the f_max before passing it to mmc-core. Signed-off-by: Srinivas Kandagatla srinivas.kandaga...@linaro.org --- drivers/mmc/host/mmci.c | 14 -- 1 file changed, 12 insertions(+), 2 deletions(-) diff --git a/drivers/mmc/host/mmci.c b/drivers/mmc/host/mmci.c index fd40f9a..202f2d5 100644 --- a/drivers/mmc/host/mmci.c +++ b/drivers/mmc/host/mmci.c @@ -67,6 +67,7 @@ static unsigned int fmax = 515633; * @blksz_datactrl4: true if Block size is at b4..b16 position in datactrl * register * @pwrreg_powerup: power up value for MMCIPOWER register + * @f_max: maximum clk frequency supported by the controller. * @signal_direction: input/out direction of bus signals can be indicated * @pwrreg_clkgate: MMCIPOWER register must be used to gate the clock * @busy_detect: true if busy detection on dat0 is supported @@ -87,6 +88,7 @@ struct variant_data { boolblksz_datactrl16; boolblksz_datactrl4; u32 pwrreg_powerup; + u32 f_max; boolsignal_direction; boolpwrreg_clkgate; boolbusy_detect; @@ -98,6 +100,7 @@ static struct variant_data variant_arm = { .fifohalfsize = 8 * 4, .datalength_bits= 16, .pwrreg_powerup = MCI_PWR_UP, + .f_max = 1, }; static struct variant_data variant_arm_extended_fifo = { @@ -105,6 +108,7 @@ static struct variant_data variant_arm_extended_fifo = { .fifohalfsize = 64 * 4, .datalength_bits= 16, .pwrreg_powerup = MCI_PWR_UP, + .f_max = 1, }; static struct variant_data variant_arm_extended_fifo_hwfc = { @@ -113,6 +117,7 @@ static struct variant_data variant_arm_extended_fifo_hwfc = { .clkreg_enable = MCI_ARM_HWFCEN, .datalength_bits= 16, .pwrreg_powerup = MCI_PWR_UP, + .f_max = 1, }; static struct variant_data variant_u300 = { @@ -123,6 +128,7 @@ static struct variant_data variant_u300 = { .datalength_bits= 16, .sdio = true, .pwrreg_powerup = MCI_PWR_ON, + .f_max = 1, .signal_direction = true, .pwrreg_clkgate = true, .pwrreg_nopower = true, @@ -136,6 +142,7 @@ static struct variant_data variant_nomadik = { .sdio = true, .st_clkdiv = true, .pwrreg_powerup = MCI_PWR_ON, + .f_max = 1, .signal_direction = true, .pwrreg_clkgate = true, .pwrreg_nopower = true, @@ -152,6 +159,7 @@ static struct variant_data variant_ux500 = { .sdio = true, .st_clkdiv = true, .pwrreg_powerup = MCI_PWR_ON, + .f_max = 1, .signal_direction = true, .pwrreg_clkgate = true, .busy_detect= true, @@ -171,6 +179,7 @@ static struct variant_data variant_ux500v2 = { .st_clkdiv = true, .blksz_datactrl16 = true, .pwrreg_powerup = MCI_PWR_ON, + .f_max = 1, .signal_direction = true, .pwrreg_clkgate = true, .busy_detect= true, @@ -189,6 +198,7 @@ static struct variant_data variant_qcom = { .blksz_datactrl4= true, .datalength_bits= 24, .pwrreg_powerup = MCI_PWR_UP, + .f_max = 20800, }; static int mmci_card_busy(struct mmc_host *mmc) @@ -1485,8 +1495,8 @@ static int mmci_probe(struct amba_device *dev, * so we try to adjust the clock down to this, * (if possible). */ - if (host-mclk 1) { - ret = clk_set_rate(host-clk, 1); + if (host-mclk host-variant-f_max) { + ret = clk_set_rate(host-clk, host-variant-f_max); if (ret 0) goto clk_disable; host-mclk = clk_get_rate(host-clk); -- 1.9.1 -- To unsubscribe from this list: send the line unsubscribe linux-arm-msm in the body of a message to majord...@vger.kernel.org More majordomo info at http://vger.kernel.org/majordomo-info.html
[PATCH v4 08/13] mmc: mmci: add edge support to data and command out in variant data.
From: Srinivas Kandagatla srinivas.kandaga...@linaro.org This patch adds edge support for data and command out to variant structure giving more flexibility to the driver to support more SOCs which have different clock register layout. Without this patch other new SOCs like Qcom will have to add more code to special case them Signed-off-by: Srinivas Kandagatla srinivas.kandaga...@linaro.org Reviewed-by: Linus Walleij linus.wall...@linaro.org --- drivers/mmc/host/mmci.c | 6 +- 1 file changed, 5 insertions(+), 1 deletion(-) diff --git a/drivers/mmc/host/mmci.c b/drivers/mmc/host/mmci.c index 2f4cdf3..8deea4a 100644 --- a/drivers/mmc/host/mmci.c +++ b/drivers/mmc/host/mmci.c @@ -53,6 +53,7 @@ static unsigned int fmax = 515633; * @clkreg: default value for MCICLOCK register * @clkreg_enable: enable value for MMCICLOCK register * @clkreg_8bit_bus_enable: enable value for 8 bit bus + * @clkreg_neg_edge_enable: enable value for inverted data/cmd output * @datalength_bits: number of bits in the MMCIDATALENGTH register * @fifosize: number of bytes that can be written when MMCI_TXFIFOEMPTY * is asserted (likewise for RX) @@ -74,6 +75,7 @@ struct variant_data { unsigned intclkreg; unsigned intclkreg_enable; unsigned intclkreg_8bit_bus_enable; + unsigned intclkreg_neg_edge_enable; unsigned intdatalength_bits; unsigned intfifosize; unsigned intfifohalfsize; @@ -143,6 +145,7 @@ static struct variant_data variant_ux500 = { .clkreg = MCI_CLK_ENABLE, .clkreg_enable = MCI_ST_UX500_HWFCEN, .clkreg_8bit_bus_enable = MCI_ST_8BIT_BUS, + .clkreg_neg_edge_enable = MCI_ST_UX500_NEG_EDGE, .datalength_bits= 24, .sdio = true, .st_clkdiv = true, @@ -159,6 +162,7 @@ static struct variant_data variant_ux500v2 = { .clkreg = MCI_CLK_ENABLE, .clkreg_enable = MCI_ST_UX500_HWFCEN, .clkreg_8bit_bus_enable = MCI_ST_8BIT_BUS, + .clkreg_neg_edge_enable = MCI_ST_UX500_NEG_EDGE, .datactrl_mask_ddrmode = MCI_ST_DPSM_DDRMODE, .datalength_bits= 24, .sdio = true, @@ -322,7 +326,7 @@ static void mmci_set_clkreg(struct mmci_host *host, unsigned int desired) clk |= variant-clkreg_8bit_bus_enable; if (host-mmc-ios.timing == MMC_TIMING_UHS_DDR50) - clk |= MCI_ST_UX500_NEG_EDGE; + clk |= variant-clkreg_neg_edge_enable; mmci_write_clkreg(host, clk); } -- 1.9.1 -- To unsubscribe from this list: send the line unsubscribe linux-arm-msm in the body of a message to majord...@vger.kernel.org More majordomo info at http://vger.kernel.org/majordomo-info.html
[PATCH v4 09/13] mmc: mmci: add Qcom specifics of clk and datactrl registers.
From: Srinivas Kandagatla srinivas.kandaga...@linaro.org This patch adds specifics of clk and datactrl register on Qualcomm SD Card controller. This patch also populates the Qcom variant data with these new values specific to Qualcomm SD Card Controller. Signed-off-by: Srinivas Kandagatla srinivas.kandaga...@linaro.org Reviewed-by: Linus Walleij linus.wall...@linaro.org --- drivers/mmc/host/mmci.c | 4 drivers/mmc/host/mmci.h | 17 + 2 files changed, 21 insertions(+) diff --git a/drivers/mmc/host/mmci.c b/drivers/mmc/host/mmci.c index 8deea4a..dbcb952 100644 --- a/drivers/mmc/host/mmci.c +++ b/drivers/mmc/host/mmci.c @@ -179,6 +179,10 @@ static struct variant_data variant_qcom = { .fifosize = 16 * 4, .fifohalfsize = 8 * 4, .clkreg = MCI_CLK_ENABLE, + .clkreg_enable = MCI_QCOM_CLK_FLOWENA | + MCI_QCOM_CLK_SELECT_IN_FBCLK, + .clkreg_8bit_bus_enable = MCI_QCOM_CLK_WIDEBUS_8, + .datactrl_mask_ddrmode = MCI_QCOM_CLK_SELECT_IN_DDR_MODE, .blksz_datactrl4= true, .datalength_bits= 24, .pwrreg_powerup = MCI_PWR_UP, diff --git a/drivers/mmc/host/mmci.h b/drivers/mmc/host/mmci.h index cd83ca3..706eb513 100644 --- a/drivers/mmc/host/mmci.h +++ b/drivers/mmc/host/mmci.h @@ -41,6 +41,15 @@ /* Modified PL180 on Versatile Express platform */ #define MCI_ARM_HWFCEN BIT(12) +/* Modified on Qualcomm Integrations */ +#define MCI_QCOM_CLK_WIDEBUS_8 (BIT(10) | BIT(11)) +#define MCI_QCOM_CLK_FLOWENA BIT(12) +#define MCI_QCOM_CLK_INVERTOUT BIT(13) + +/* select in latch data and command in */ +#define MCI_QCOM_CLK_SELECT_IN_FBCLK BIT(15) +#define MCI_QCOM_CLK_SELECT_IN_DDR_MODE(BIT(14) | BIT(15)) + #define MMCIARGUMENT 0x008 #define MMCICOMMAND0x00c #define MCI_CPSM_RESPONSE BIT(6) @@ -54,6 +63,14 @@ #define MCI_ST_NIENBIT(13) #define MCI_ST_CE_ATACMD BIT(14) +/* Modified on Qualcomm Integrations */ +#define MCI_QCOM_CSPM_DATCMD BIT(12) +#define MCI_QCOM_CSPM_MCIABORT BIT(13) +#define MCI_QCOM_CSPM_CCSENABLEBIT(14) +#define MCI_QCOM_CSPM_CCSDISABLE BIT(15) +#define MCI_QCOM_CSPM_AUTO_CMD19 BIT(16) +#define MCI_QCOM_CSPM_AUTO_CMD21 BIT(21) + #define MMCIRESPCMD0x010 #define MMCIRESPONSE0 0x014 #define MMCIRESPONSE1 0x018 -- 1.9.1 -- To unsubscribe from this list: send the line unsubscribe linux-arm-msm in the body of a message to majord...@vger.kernel.org More majordomo info at http://vger.kernel.org/majordomo-info.html
[PATCH v4 10/13] mmc: mmci: Add support to data commands via variant structure.
From: Srinivas Kandagatla srinivas.kandaga...@linaro.org On some SOCs like Qcom there are explicit bits in the command register to specify if its a data transfer command or not. So this patch adds support to such bits in variant data, giving more flexibility to the driver. Signed-off-by: Srinivas Kandagatla srinivas.kandaga...@linaro.org Reviewed-by: Linus Walleij linus.wall...@linaro.org --- drivers/mmc/host/mmci.c | 6 ++ 1 file changed, 6 insertions(+) diff --git a/drivers/mmc/host/mmci.c b/drivers/mmc/host/mmci.c index dbcb952..fd40f9a 100644 --- a/drivers/mmc/host/mmci.c +++ b/drivers/mmc/host/mmci.c @@ -59,6 +59,7 @@ static unsigned int fmax = 515633; * is asserted (likewise for RX) * @fifohalfsize: number of bytes that can be written when MCI_TXFIFOHALFEMPTY * is asserted (likewise for RX) + * @data_cmd_enable: enable value for data commands. * @sdio: variant supports SDIO * @st_clkdiv: true if using a ST-specific clock divider algorithm * @datactrl_mask_ddrmode: ddr mode mask in datactrl register. @@ -79,6 +80,7 @@ struct variant_data { unsigned intdatalength_bits; unsigned intfifosize; unsigned intfifohalfsize; + unsigned intdata_cmd_enable; unsigned intdatactrl_mask_ddrmode; boolsdio; boolst_clkdiv; @@ -183,6 +185,7 @@ static struct variant_data variant_qcom = { MCI_QCOM_CLK_SELECT_IN_FBCLK, .clkreg_8bit_bus_enable = MCI_QCOM_CLK_WIDEBUS_8, .datactrl_mask_ddrmode = MCI_QCOM_CLK_SELECT_IN_DDR_MODE, + .data_cmd_enable= MCI_QCOM_CSPM_DATCMD, .blksz_datactrl4= true, .datalength_bits= 24, .pwrreg_powerup = MCI_PWR_UP, @@ -852,6 +855,9 @@ mmci_start_command(struct mmci_host *host, struct mmc_command *cmd, u32 c) if (/*interrupt*/0) c |= MCI_CPSM_INTERRUPT; + if (mmc_cmd_type(cmd) == MMC_CMD_ADTC) + c |= host-variant-data_cmd_enable; + host-cmd = cmd; writel(cmd-arg, base + MMCIARGUMENT); -- 1.9.1 -- To unsubscribe from this list: send the line unsubscribe linux-arm-msm in the body of a message to majord...@vger.kernel.org More majordomo info at http://vger.kernel.org/majordomo-info.html
[PATCH v4 07/13] mmc: mmci: add 8bit bus support in variant data
From: Srinivas Kandagatla srinivas.kandaga...@linaro.org This patch adds 8bit bus enable to variant structure giving more flexibility to the driver to support more SOCs which have different clock register layout. Without this patch other new SOCs like Qcom will have to add more code to special case them. Signed-off-by: Srinivas Kandagatla srinivas.kandaga...@linaro.org Reviewed-by: Linus Walleij linus.wall...@linaro.org --- drivers/mmc/host/mmci.c | 7 ++- 1 file changed, 6 insertions(+), 1 deletion(-) diff --git a/drivers/mmc/host/mmci.c b/drivers/mmc/host/mmci.c index 729105b..2f4cdf3 100644 --- a/drivers/mmc/host/mmci.c +++ b/drivers/mmc/host/mmci.c @@ -52,6 +52,7 @@ static unsigned int fmax = 515633; * struct variant_data - MMCI variant-specific quirks * @clkreg: default value for MCICLOCK register * @clkreg_enable: enable value for MMCICLOCK register + * @clkreg_8bit_bus_enable: enable value for 8 bit bus * @datalength_bits: number of bits in the MMCIDATALENGTH register * @fifosize: number of bytes that can be written when MMCI_TXFIFOEMPTY * is asserted (likewise for RX) @@ -72,6 +73,7 @@ static unsigned int fmax = 515633; struct variant_data { unsigned intclkreg; unsigned intclkreg_enable; + unsigned intclkreg_8bit_bus_enable; unsigned intdatalength_bits; unsigned intfifosize; unsigned intfifohalfsize; @@ -113,6 +115,7 @@ static struct variant_data variant_u300 = { .fifosize = 16 * 4, .fifohalfsize = 8 * 4, .clkreg_enable = MCI_ST_U300_HWFCEN, + .clkreg_8bit_bus_enable = MCI_ST_8BIT_BUS, .datalength_bits= 16, .sdio = true, .pwrreg_powerup = MCI_PWR_ON, @@ -139,6 +142,7 @@ static struct variant_data variant_ux500 = { .fifohalfsize = 8 * 4, .clkreg = MCI_CLK_ENABLE, .clkreg_enable = MCI_ST_UX500_HWFCEN, + .clkreg_8bit_bus_enable = MCI_ST_8BIT_BUS, .datalength_bits= 24, .sdio = true, .st_clkdiv = true, @@ -154,6 +158,7 @@ static struct variant_data variant_ux500v2 = { .fifohalfsize = 8 * 4, .clkreg = MCI_CLK_ENABLE, .clkreg_enable = MCI_ST_UX500_HWFCEN, + .clkreg_8bit_bus_enable = MCI_ST_8BIT_BUS, .datactrl_mask_ddrmode = MCI_ST_DPSM_DDRMODE, .datalength_bits= 24, .sdio = true, @@ -314,7 +319,7 @@ static void mmci_set_clkreg(struct mmci_host *host, unsigned int desired) if (host-mmc-ios.bus_width == MMC_BUS_WIDTH_4) clk |= MCI_4BIT_BUS; if (host-mmc-ios.bus_width == MMC_BUS_WIDTH_8) - clk |= MCI_ST_8BIT_BUS; + clk |= variant-clkreg_8bit_bus_enable; if (host-mmc-ios.timing == MMC_TIMING_UHS_DDR50) clk |= MCI_ST_UX500_NEG_EDGE; -- 1.9.1 -- To unsubscribe from this list: send the line unsubscribe linux-arm-msm in the body of a message to majord...@vger.kernel.org More majordomo info at http://vger.kernel.org/majordomo-info.html
[PATCH v4 03/13] mmc: mmci: Add Qualcomm Id to amba id table
From: Srinivas Kandagatla srinivas.kandaga...@linaro.org This patch adds a fake Qualcomm ID 0x00051180 to the amba_ids, as Qualcomm SDCC controller is pl180, but amba id registers read 0x0's. The plan is to remove SDCC driver totally and use mmci as the main SD controller driver for Qualcomm SOCs. Signed-off-by: Srinivas Kandagatla srinivas.kandaga...@linaro.org Reviewed-by: Linus Walleij linus.wall...@linaro.org --- drivers/mmc/host/mmci.c | 14 ++ 1 file changed, 14 insertions(+) diff --git a/drivers/mmc/host/mmci.c b/drivers/mmc/host/mmci.c index a38e714..86f25a9 100644 --- a/drivers/mmc/host/mmci.c +++ b/drivers/mmc/host/mmci.c @@ -160,6 +160,14 @@ static struct variant_data variant_ux500v2 = { .pwrreg_nopower = true, }; +static struct variant_data variant_qcom = { + .fifosize = 16 * 4, + .fifohalfsize = 8 * 4, + .clkreg = MCI_CLK_ENABLE, + .datalength_bits= 24, + .pwrreg_powerup = MCI_PWR_UP, +}; + static int mmci_card_busy(struct mmc_host *mmc) { struct mmci_host *host = mmc_priv(mmc); @@ -1750,6 +1758,12 @@ static struct amba_id mmci_ids[] = { .mask = 0xf0ff, .data = variant_ux500v2, }, + /* Qualcomm variants */ + { + .id = 0x00051180, + .mask = 0x000f, + .data = variant_qcom, + }, { 0, 0 }, }; -- 1.9.1 -- To unsubscribe from this list: send the line unsubscribe linux-arm-msm in the body of a message to majord...@vger.kernel.org More majordomo info at http://vger.kernel.org/majordomo-info.html
[PATCH v4 02/13] mmc: mmci: convert register bits to use BIT() macro.
From: Srinivas Kandagatla srinivas.kandaga...@linaro.org This patch converts the register bits in the header file to use BIT(() macro, which looks much neater. No functional changes done. Signed-off-by: Srinivas Kandagatla srinivas.kandaga...@linaro.org --- drivers/mmc/host/mmci.h | 208 1 file changed, 104 insertions(+), 104 deletions(-) diff --git a/drivers/mmc/host/mmci.h b/drivers/mmc/host/mmci.h index 347d942..cd83ca3 100644 --- a/drivers/mmc/host/mmci.h +++ b/drivers/mmc/host/mmci.h @@ -11,48 +11,48 @@ #define MCI_PWR_OFF0x00 #define MCI_PWR_UP 0x02 #define MCI_PWR_ON 0x03 -#define MCI_OD (1 6) -#define MCI_ROD(1 7) +#define MCI_OD BIT(6) +#define MCI_RODBIT(7) /* * The ST Micro version does not have ROD and reuse the voltage registers for * direction settings. */ -#define MCI_ST_DATA2DIREN (1 2) -#define MCI_ST_CMDDIREN(1 3) -#define MCI_ST_DATA0DIREN (1 4) -#define MCI_ST_DATA31DIREN (1 5) -#define MCI_ST_FBCLKEN (1 7) -#define MCI_ST_DATA74DIREN (1 8) +#define MCI_ST_DATA2DIREN BIT(2) +#define MCI_ST_CMDDIRENBIT(3) +#define MCI_ST_DATA0DIREN BIT(4) +#define MCI_ST_DATA31DIREN BIT(5) +#define MCI_ST_FBCLKEN BIT(7) +#define MCI_ST_DATA74DIREN BIT(8) #define MMCICLOCK 0x004 -#define MCI_CLK_ENABLE (1 8) -#define MCI_CLK_PWRSAVE(1 9) -#define MCI_CLK_BYPASS (1 10) -#define MCI_4BIT_BUS (1 11) +#define MCI_CLK_ENABLE BIT(8) +#define MCI_CLK_PWRSAVEBIT(9) +#define MCI_CLK_BYPASS BIT(10) +#define MCI_4BIT_BUS BIT(11) /* * 8bit wide buses, hardware flow contronl, negative edges and clock inversion * supported in ST Micro U300 and Ux500 versions */ -#define MCI_ST_8BIT_BUS(1 12) -#define MCI_ST_U300_HWFCEN (1 13) -#define MCI_ST_UX500_NEG_EDGE (1 13) -#define MCI_ST_UX500_HWFCEN(1 14) -#define MCI_ST_UX500_CLK_INV (1 15) +#define MCI_ST_8BIT_BUSBIT(12) +#define MCI_ST_U300_HWFCEN BIT(13) +#define MCI_ST_UX500_NEG_EDGE BIT(13) +#define MCI_ST_UX500_HWFCENBIT(14) +#define MCI_ST_UX500_CLK_INV BIT(15) /* Modified PL180 on Versatile Express platform */ -#define MCI_ARM_HWFCEN (1 12) +#define MCI_ARM_HWFCEN BIT(12) #define MMCIARGUMENT 0x008 #define MMCICOMMAND0x00c -#define MCI_CPSM_RESPONSE (1 6) -#define MCI_CPSM_LONGRSP (1 7) -#define MCI_CPSM_INTERRUPT (1 8) -#define MCI_CPSM_PENDING (1 9) -#define MCI_CPSM_ENABLE(1 10) +#define MCI_CPSM_RESPONSE BIT(6) +#define MCI_CPSM_LONGRSP BIT(7) +#define MCI_CPSM_INTERRUPT BIT(8) +#define MCI_CPSM_PENDING BIT(9) +#define MCI_CPSM_ENABLEBIT(10) /* Argument flag extenstions in the ST Micro versions */ -#define MCI_ST_SDIO_SUSP (1 11) -#define MCI_ST_ENCMD_COMPL (1 12) -#define MCI_ST_NIEN(1 13) -#define MCI_ST_CE_ATACMD (1 14) +#define MCI_ST_SDIO_SUSP BIT(11) +#define MCI_ST_ENCMD_COMPL BIT(12) +#define MCI_ST_NIENBIT(13) +#define MCI_ST_CE_ATACMD BIT(14) #define MMCIRESPCMD0x010 #define MMCIRESPONSE0 0x014 @@ -62,95 +62,95 @@ #define MMCIDATATIMER 0x024 #define MMCIDATALENGTH 0x028 #define MMCIDATACTRL 0x02c -#define MCI_DPSM_ENABLE(1 0) -#define MCI_DPSM_DIRECTION (1 1) -#define MCI_DPSM_MODE (1 2) -#define MCI_DPSM_DMAENABLE (1 3) -#define MCI_DPSM_BLOCKSIZE (1 4) +#define MCI_DPSM_ENABLEBIT(0) +#define MCI_DPSM_DIRECTION BIT(1) +#define MCI_DPSM_MODE BIT(2) +#define MCI_DPSM_DMAENABLE BIT(3) +#define MCI_DPSM_BLOCKSIZE BIT(4) /* Control register extensions in the ST Micro U300 and Ux500 versions */ -#define MCI_ST_DPSM_RWSTART(1 8) -#define MCI_ST_DPSM_RWSTOP (1 9) -#define MCI_ST_DPSM_RWMOD (1 10) -#define MCI_ST_DPSM_SDIOEN (1 11) +#define MCI_ST_DPSM_RWSTARTBIT(8) +#define MCI_ST_DPSM_RWSTOP BIT(9) +#define MCI_ST_DPSM_RWMOD BIT(10) +#define MCI_ST_DPSM_SDIOEN BIT(11) /* Control register extensions in the ST Micro Ux500 versions */ -#define MCI_ST_DPSM_DMAREQCTL (1 12) -#define MCI_ST_DPSM_DBOOTMODEEN(1 13) -#define MCI_ST_DPSM_BUSYMODE (1 14) -#define MCI_ST_DPSM_DDRMODE(1 15) +#define MCI_ST_DPSM_DMAREQCTL BIT(12) +#define MCI_ST_DPSM_DBOOTMODEENBIT(13) +#define MCI_ST_DPSM_BUSYMODE BIT(14) +#define MCI_ST_DPSM_DDRMODEBIT(15) #define MMCIDATACNT0x030 #define MMCISTATUS 0x034 -#define MCI_CMDCRCFAIL (1 0) -#define MCI_DATACRCFAIL(1 1) -#define MCI_CMDTIMEOUT (1 2) -#define