2018-04-23 09:28:28

by Chaotian Jing

[permalink] [raw]
Subject: mmc: mediatek: add 64G DRAM DMA support


Chaotian Jing (1):
mmc: mediatek: add 64G DRAM DMA support

drivers/mmc/host/mtk-sd.c | 44 +++++++++++++++++++++++++++++++++++++++-----
1 file changed, 39 insertions(+), 5 deletions(-)

--
1.8.1.1.dirty



2018-04-23 09:28:40

by Chaotian Jing

[permalink] [raw]
Subject: [PATCH] mmc: mediatek: add 64G DRAM DMA support

MT2712 MSDC supports 64G DRAM DMA access, it needs update
gpd/bd structure.

Signed-off-by: Chaotian Jing <[email protected]>
---
drivers/mmc/host/mtk-sd.c | 44 +++++++++++++++++++++++++++++++++++++++-----
1 file changed, 39 insertions(+), 5 deletions(-)

diff --git a/drivers/mmc/host/mtk-sd.c b/drivers/mmc/host/mtk-sd.c
index d642e11..93269ac 100644
--- a/drivers/mmc/host/mtk-sd.c
+++ b/drivers/mmc/host/mtk-sd.c
@@ -228,6 +228,7 @@

#define MSDC_PATCH_BIT2_CFGRESP (0x1 << 15) /* RW */
#define MSDC_PATCH_BIT2_CFGCRCSTS (0x1 << 28) /* RW */
+#define MSDC_PB2_SUPPORT_64G (0x1 << 1) /* RW */
#define MSDC_PB2_RESPWAIT (0x3 << 2) /* RW */
#define MSDC_PB2_RESPSTSENSEL (0x7 << 16) /* RW */
#define MSDC_PB2_CRCSTSENSEL (0x7 << 29) /* RW */
@@ -281,6 +282,8 @@ struct mt_gpdma_desc {
#define GPDMA_DESC_BDP (0x1 << 1)
#define GPDMA_DESC_CHECKSUM (0xff << 8) /* bit8 ~ bit15 */
#define GPDMA_DESC_INT (0x1 << 16)
+#define GPDMA_DESC_NEXT_H4 (0xf << 24)
+#define GPDMA_DESC_PTR_H4 (0xf << 28)
u32 next;
u32 ptr;
u32 gpd_data_len;
@@ -297,6 +300,8 @@ struct mt_bdma_desc {
#define BDMA_DESC_CHECKSUM (0xff << 8) /* bit8 ~ bit15 */
#define BDMA_DESC_BLKPAD (0x1 << 17)
#define BDMA_DESC_DWPAD (0x1 << 18)
+#define BDMA_DESC_NEXT_H4 (0xf << 24)
+#define BDMA_DESC_PTR_H4 (0xf << 28)
u32 next;
u32 ptr;
u32 bd_data_len;
@@ -335,6 +340,7 @@ struct mtk_mmc_compatible {
bool busy_check;
bool stop_clk_fix;
bool enhance_rx;
+ bool support_64g;
};

struct msdc_tune_para {
@@ -404,6 +410,7 @@ struct msdc_host {
.busy_check = false,
.stop_clk_fix = false,
.enhance_rx = false,
+ .support_64g = false,
};

static const struct mtk_mmc_compatible mt8173_compat = {
@@ -415,6 +422,7 @@ struct msdc_host {
.busy_check = false,
.stop_clk_fix = false,
.enhance_rx = false,
+ .support_64g = false,
};

static const struct mtk_mmc_compatible mt2701_compat = {
@@ -426,6 +434,7 @@ struct msdc_host {
.busy_check = false,
.stop_clk_fix = false,
.enhance_rx = false,
+ .support_64g = false,
};

static const struct mtk_mmc_compatible mt2712_compat = {
@@ -437,6 +446,7 @@ struct msdc_host {
.busy_check = true,
.stop_clk_fix = true,
.enhance_rx = true,
+ .support_64g = true,
};

static const struct mtk_mmc_compatible mt7622_compat = {
@@ -448,6 +458,7 @@ struct msdc_host {
.busy_check = true,
.stop_clk_fix = true,
.enhance_rx = true,
+ .support_64g = false,
};

static const struct of_device_id msdc_of_ids[] = {
@@ -558,6 +569,10 @@ static inline void msdc_dma_setup(struct msdc_host *host, struct msdc_dma *dma,
bd[j].bd_info &= ~BDMA_DESC_BLKPAD;
bd[j].bd_info &= ~BDMA_DESC_DWPAD;
bd[j].ptr = (u32)dma_address;
+ if (host->dev_comp->support_64g) {
+ bd[j].bd_info &= ~BDMA_DESC_PTR_H4;
+ bd[j].bd_info |= ((dma_address >> 32) & 0xf) << 28;
+ }
bd[j].bd_data_len &= ~BDMA_DESC_BUFLEN;
bd[j].bd_data_len |= (dma_len & BDMA_DESC_BUFLEN);

@@ -1367,6 +1382,9 @@ static void msdc_init_hw(struct msdc_host *host)
MSDC_PATCH_BIT2_CFGCRCSTS);
}

+ if (host->dev_comp->support_64g)
+ sdr_set_bits(host->base + MSDC_PATCH_BIT2,
+ MSDC_PB2_SUPPORT_64G);
if (host->dev_comp->data_tune) {
sdr_set_bits(host->base + tune_reg,
MSDC_PAD_TUNE_RD_SEL | MSDC_PAD_TUNE_CMD_SEL);
@@ -1408,19 +1426,32 @@ static void msdc_init_gpd_bd(struct msdc_host *host, struct msdc_dma *dma)
{
struct mt_gpdma_desc *gpd = dma->gpd;
struct mt_bdma_desc *bd = dma->bd;
+ dma_addr_t dma_addr;
int i;

memset(gpd, 0, sizeof(struct mt_gpdma_desc) * 2);

+ dma_addr = dma->gpd_addr + sizeof(struct mt_gpdma_desc);
gpd->gpd_info = GPDMA_DESC_BDP; /* hwo, cs, bd pointer */
- gpd->ptr = (u32)dma->bd_addr; /* physical address */
/* gpd->next is must set for desc DMA
* That's why must alloc 2 gpd structure.
*/
- gpd->next = (u32)dma->gpd_addr + sizeof(struct mt_gpdma_desc);
+ gpd->next = (u32)dma_addr;
+ if (host->dev_comp->support_64g)
+ gpd->gpd_info |= ((dma_addr >> 32) & 0xf) << 24;
+
+ dma_addr = dma->bd_addr;
+ gpd->ptr = (u32)dma->bd_addr; /* physical address */
+ if (host->dev_comp->support_64g)
+ gpd->gpd_info |= ((dma_addr >> 32) & 0xf) << 28;
+
memset(bd, 0, sizeof(struct mt_bdma_desc) * MAX_BD_NUM);
- for (i = 0; i < (MAX_BD_NUM - 1); i++)
- bd[i].next = (u32)dma->bd_addr + sizeof(*bd) * (i + 1);
+ for (i = 0; i < (MAX_BD_NUM - 1); i++) {
+ dma_addr = dma->bd_addr + sizeof(*bd) * (i + 1);
+ bd[i].next = (u32)dma_addr;
+ if (host->dev_comp->support_64g)
+ bd[i].bd_info |= ((dma_addr >> 32) & 0xf) << 24;
+ }
}

static void msdc_ops_set_ios(struct mmc_host *mmc, struct mmc_ios *ios)
@@ -1913,7 +1944,10 @@ static int msdc_drv_probe(struct platform_device *pdev)
mmc->max_blk_size = 2048;
mmc->max_req_size = 512 * 1024;
mmc->max_blk_count = mmc->max_req_size / 512;
- host->dma_mask = DMA_BIT_MASK(32);
+ if (host->dev_comp->support_64g)
+ host->dma_mask = DMA_BIT_MASK(36);
+ else
+ host->dma_mask = DMA_BIT_MASK(32);
mmc_dev(mmc)->dma_mask = &host->dma_mask;

host->timeout_clks = 3 * 1048576;
--
1.8.1.1.dirty


2018-04-24 06:15:19

by kernel test robot

[permalink] [raw]
Subject: Re: [PATCH] mmc: mediatek: add 64G DRAM DMA support

Hi Chaotian,

Thank you for the patch! Perhaps something to improve:

[auto build test WARNING on linus/master]
[also build test WARNING on v4.17-rc2 next-20180423]
[if your patch is applied to the wrong git tree, please drop us a note to help improve the system]

url: https://github.com/0day-ci/linux/commits/Chaotian-Jing/mmc-mediatek-add-64G-DRAM-DMA-support/20180423-231743
config: arm-allmodconfig (attached as .config)
compiler: arm-linux-gnueabi-gcc (Debian 7.2.0-11) 7.2.0
reproduce:
wget https://raw.githubusercontent.com/intel/lkp-tests/master/sbin/make.cross -O ~/bin/make.cross
chmod +x ~/bin/make.cross
# save the attached .config to linux build tree
make.cross ARCH=arm

All warnings (new ones prefixed by >>):

drivers/mmc/host/mtk-sd.c: In function 'msdc_dma_setup':
>> drivers/mmc/host/mtk-sd.c:573:35: warning: right shift count >= width of type [-Wshift-count-overflow]
bd[j].bd_info |= ((dma_address >> 32) & 0xf) << 28;
^~
drivers/mmc/host/mtk-sd.c: In function 'msdc_init_gpd_bd':
drivers/mmc/host/mtk-sd.c:1440:31: warning: right shift count >= width of type [-Wshift-count-overflow]
gpd->gpd_info |= ((dma_addr >> 32) & 0xf) << 24;
^~
drivers/mmc/host/mtk-sd.c:1445:31: warning: right shift count >= width of type [-Wshift-count-overflow]
gpd->gpd_info |= ((dma_addr >> 32) & 0xf) << 28;
^~
drivers/mmc/host/mtk-sd.c:1452:32: warning: right shift count >= width of type [-Wshift-count-overflow]
bd[i].bd_info |= ((dma_addr >> 32) & 0xf) << 24;
^~

vim +573 drivers/mmc/host/mtk-sd.c

539
540 static inline void msdc_dma_setup(struct msdc_host *host, struct msdc_dma *dma,
541 struct mmc_data *data)
542 {
543 unsigned int j, dma_len;
544 dma_addr_t dma_address;
545 u32 dma_ctrl;
546 struct scatterlist *sg;
547 struct mt_gpdma_desc *gpd;
548 struct mt_bdma_desc *bd;
549
550 sg = data->sg;
551
552 gpd = dma->gpd;
553 bd = dma->bd;
554
555 /* modify gpd */
556 gpd->gpd_info |= GPDMA_DESC_HWO;
557 gpd->gpd_info |= GPDMA_DESC_BDP;
558 /* need to clear first. use these bits to calc checksum */
559 gpd->gpd_info &= ~GPDMA_DESC_CHECKSUM;
560 gpd->gpd_info |= msdc_dma_calcs((u8 *) gpd, 16) << 8;
561
562 /* modify bd */
563 for_each_sg(data->sg, sg, data->sg_count, j) {
564 dma_address = sg_dma_address(sg);
565 dma_len = sg_dma_len(sg);
566
567 /* init bd */
568 bd[j].bd_info &= ~BDMA_DESC_BLKPAD;
569 bd[j].bd_info &= ~BDMA_DESC_DWPAD;
570 bd[j].ptr = (u32)dma_address;
571 if (host->dev_comp->support_64g) {
572 bd[j].bd_info &= ~BDMA_DESC_PTR_H4;
> 573 bd[j].bd_info |= ((dma_address >> 32) & 0xf) << 28;
574 }
575 bd[j].bd_data_len &= ~BDMA_DESC_BUFLEN;
576 bd[j].bd_data_len |= (dma_len & BDMA_DESC_BUFLEN);
577
578 if (j == data->sg_count - 1) /* the last bd */
579 bd[j].bd_info |= BDMA_DESC_EOL;
580 else
581 bd[j].bd_info &= ~BDMA_DESC_EOL;
582
583 /* checksume need to clear first */
584 bd[j].bd_info &= ~BDMA_DESC_CHECKSUM;
585 bd[j].bd_info |= msdc_dma_calcs((u8 *)(&bd[j]), 16) << 8;
586 }
587
588 sdr_set_field(host->base + MSDC_DMA_CFG, MSDC_DMA_CFG_DECSEN, 1);
589 dma_ctrl = readl_relaxed(host->base + MSDC_DMA_CTRL);
590 dma_ctrl &= ~(MSDC_DMA_CTRL_BRUSTSZ | MSDC_DMA_CTRL_MODE);
591 dma_ctrl |= (MSDC_BURST_64B << 12 | 1 << 8);
592 writel_relaxed(dma_ctrl, host->base + MSDC_DMA_CTRL);
593 writel((u32)dma->gpd_addr, host->base + MSDC_DMA_SA);
594 }
595

---
0-DAY kernel test infrastructure Open Source Technology Center
https://lists.01.org/pipermail/kbuild-all Intel Corporation


Attachments:
(No filename) (3.93 kB)
.config.gz (63.69 kB)
Download all attachments