4444#define LOONGSON2_MMC_REG_DATA 0x40 /* Data Register */
4545#define LOONGSON2_MMC_REG_IEN 0x64 /* Interrupt Enable Register */
4646
47+ /* EMMC DLL Mode Registers */
48+ #define LOONGSON2_MMC_REG_DLLVAL 0xf0 /* DLL Master Lock-value Register */
49+ #define LOONGSON2_MMC_REG_DLLCTL 0xf4 /* DLL Control Register */
50+ #define LOONGSON2_MMC_REG_DELAY 0xf8 /* DLL Delayed Parameter Register */
51+ #define LOONGSON2_MMC_REG_SEL 0xfc /* Bus Mode Selection Register */
52+
53+ /* Exclusive DMA R/W Registers */
54+ #define LOONGSON2_MMC_REG_WDMA_LO 0x400
55+ #define LOONGSON2_MMC_REG_WDMA_HI 0x404
56+ #define LOONGSON2_MMC_REG_RDMA_LO 0x800
57+ #define LOONGSON2_MMC_REG_RDMA_HI 0x804
58+
4759/* Bitfields of control register */
4860#define LOONGSON2_MMC_CTL_ENCLK BIT(0)
4961#define LOONGSON2_MMC_CTL_EXTCLK BIT(1)
109121#define LOONGSON2_MMC_DSTS_RESUME BIT(15)
110122#define LOONGSON2_MMC_DSTS_SUSPEND BIT(16)
111123
124+ /* Bitfields of FIFO Status Register */
125+ #define LOONGSON2_MMC_FSTS_TXFULL BIT(11)
126+
112127/* Bitfields of interrupt register */
113128#define LOONGSON2_MMC_INT_DFIN BIT(0)
114129#define LOONGSON2_MMC_INT_DTIMEOUT BIT(1)
136151#define LOONGSON2_MMC_IEN_ALL GENMASK(9, 0)
137152#define LOONGSON2_MMC_INT_CLEAR GENMASK(9, 0)
138153
154+ /* Bitfields of DLL master lock-value register */
155+ #define LOONGSON2_MMC_DLLVAL_DONE BIT(8)
156+
157+ /* Bitfields of DLL control register */
158+ #define LOONGSON2_MMC_DLLCTL_TIME GENMASK(7, 0)
159+ #define LOONGSON2_MMC_DLLCTL_INCRE GENMASK(15, 8)
160+ #define LOONGSON2_MMC_DLLCTL_START GENMASK(23, 16)
161+ #define LOONGSON2_MMC_DLLCTL_CLK_MODE BIT(24)
162+ #define LOONGSON2_MMC_DLLCTL_START_BIT BIT(25)
163+ #define LOONGSON2_MMC_DLLCTL_TIME_BPASS GENMASK(29, 26)
164+
165+ #define LOONGSON2_MMC_DELAY_PAD GENMASK(7, 0)
166+ #define LOONGSON2_MMC_DELAY_RD GENMASK(15, 8)
167+
168+ #define LOONGSON2_MMC_SEL_DATA BIT(0) /* 0: SDR, 1: DDR */
169+ #define LOONGSON2_MMC_SEL_BUS BIT(0) /* 0: EMMC, 1: SDIO */
170+
171+ /* Internal dma controller registers */
172+
173+ /* Bitfields of Global Configuration Register */
174+ #define LOONGSON2_MMC_DMA_64BIT_EN BIT(0) /* 1: 64 bit support */
175+ #define LOONGSON2_MMC_DMA_UNCOHERENT_EN BIT(1) /* 0: cache, 1: uncache */
176+ #define LOONGSON2_MMC_DMA_ASK_VALID BIT(2)
177+ #define LOONGSON2_MMC_DMA_START BIT(3) /* DMA start operation */
178+ #define LOONGSON2_MMC_DMA_STOP BIT(4) /* DMA stop operation */
179+ #define LOONGSON2_MMC_DMA_CONFIG_MASK GENMASK_ULL(4, 0) /* DMA controller config bits mask */
180+
181+ /* Bitfields of ndesc_addr field of HW descriptor */
182+ #define LOONGSON2_MMC_DMA_DESC_EN BIT(0) /*1: The next descriptor is valid */
183+ #define LOONGSON2_MMC_DMA_DESC_ADDR_LOW GENMASK(31, 1)
184+
185+ /* Bitfields of cmd field of HW descriptor */
186+ #define LOONGSON2_MMC_DMA_INT BIT(1) /* Enable DMA interrupts */
187+ #define LOONGSON2_MMC_DMA_DATA_DIR BIT(12) /* 1: write to device, 0: read from device */
188+
189+ #define LOONGSON2_MMC_DLLVAL_TIMEOUT_US 4000
190+ #define LOONGSON2_MMC_TXFULL_TIMEOUT_US 500
191+
139192/* Loongson-2K1000 SDIO2 DMA routing register */
140193#define LS2K1000_SDIO_DMA_MASK GENMASK(17, 15)
141194#define LS2K1000_DMA0_CONF 0x0
@@ -159,13 +212,29 @@ enum loongson2_mmc_state {
159212 STATE_XFERFINISH_RSPFIN ,
160213};
161214
215+ struct loongson2_dma_desc {
216+ u32 ndesc_addr ;
217+ u32 mem_addr ;
218+ u32 apb_addr ;
219+ u32 len ;
220+ u32 step_len ;
221+ u32 step_times ;
222+ u32 cmd ;
223+ u32 stats ;
224+ u32 high_ndesc_addr ;
225+ u32 high_mem_addr ;
226+ u32 reserved [2 ];
227+ } __packed ;
228+
162229struct loongson2_mmc_host {
163230 struct device * dev ;
164231 struct mmc_request * mrq ;
165232 struct regmap * regmap ;
166233 struct resource * res ;
167234 struct clk * clk ;
168235 u32 current_clk ;
236+ void * sg_cpu ;
237+ dma_addr_t sg_dma ;
169238 int dma_complete ;
170239 struct dma_chan * chan ;
171240 int cmd_is_stop ;
@@ -178,6 +247,7 @@ struct loongson2_mmc_host {
178247struct loongson2_mmc_pdata {
179248 const struct regmap_config * regmap_config ;
180249 void (* reorder_cmd_data )(struct loongson2_mmc_host * host , struct mmc_command * cmd );
250+ void (* fix_data_timeout )(struct loongson2_mmc_host * host , struct mmc_command * cmd );
181251 int (* setting_dma )(struct loongson2_mmc_host * host , struct platform_device * pdev );
182252 int (* prepare_dma )(struct loongson2_mmc_host * host , struct mmc_data * data );
183253 void (* release_dma )(struct loongson2_mmc_host * host , struct device * dev );
@@ -268,6 +338,9 @@ static void loongson2_mmc_send_request(struct mmc_host *mmc)
268338 return ;
269339 }
270340
341+ if (host -> pdata -> fix_data_timeout )
342+ host -> pdata -> fix_data_timeout (host , cmd );
343+
271344 loongson2_mmc_send_command (host , cmd );
272345
273346 /* Fix deselect card */
@@ -410,6 +483,37 @@ static irqreturn_t loongson2_mmc_irq(int irq, void *devid)
410483 return IRQ_WAKE_THREAD ;
411484}
412485
486+ static void loongson2_mmc_dll_mode_init (struct loongson2_mmc_host * host )
487+ {
488+ u32 val , pad_delay , delay , ret ;
489+
490+ regmap_update_bits (host -> regmap , LOONGSON2_MMC_REG_SEL ,
491+ LOONGSON2_MMC_SEL_DATA , LOONGSON2_MMC_SEL_DATA );
492+
493+ val = FIELD_PREP (LOONGSON2_MMC_DLLCTL_TIME , 0xc8 )
494+ | FIELD_PREP (LOONGSON2_MMC_DLLCTL_INCRE , 0x1 )
495+ | FIELD_PREP (LOONGSON2_MMC_DLLCTL_START , 0x1 )
496+ | FIELD_PREP (LOONGSON2_MMC_DLLCTL_CLK_MODE , 0x1 )
497+ | FIELD_PREP (LOONGSON2_MMC_DLLCTL_START_BIT , 0x1 )
498+ | FIELD_PREP (LOONGSON2_MMC_DLLCTL_TIME_BPASS , 0xf );
499+
500+ regmap_write (host -> regmap , LOONGSON2_MMC_REG_DLLCTL , val );
501+
502+ ret = regmap_read_poll_timeout (host -> regmap , LOONGSON2_MMC_REG_DLLVAL , val ,
503+ (val & LOONGSON2_MMC_DLLVAL_DONE ), 0 ,
504+ LOONGSON2_MMC_DLLVAL_TIMEOUT_US );
505+ if (ret < 0 )
506+ return ;
507+
508+ regmap_read (host -> regmap , LOONGSON2_MMC_REG_DLLVAL , & val );
509+ pad_delay = FIELD_GET (GENMASK (7 , 1 ), val );
510+
511+ delay = FIELD_PREP (LOONGSON2_MMC_DELAY_PAD , pad_delay )
512+ | FIELD_PREP (LOONGSON2_MMC_DELAY_RD , pad_delay + 1 );
513+
514+ regmap_write (host -> regmap , LOONGSON2_MMC_REG_DELAY , delay );
515+ }
516+
413517static void loongson2_mmc_set_clk (struct loongson2_mmc_host * host , struct mmc_ios * ios )
414518{
415519 u32 pre ;
@@ -422,6 +526,10 @@ static void loongson2_mmc_set_clk(struct loongson2_mmc_host *host, struct mmc_io
422526
423527 regmap_update_bits (host -> regmap , LOONGSON2_MMC_REG_CTL ,
424528 LOONGSON2_MMC_CTL_ENCLK , LOONGSON2_MMC_CTL_ENCLK );
529+
530+ /* EMMC DLL mode setting */
531+ if (ios -> timing == MMC_TIMING_UHS_DDR50 || ios -> timing == MMC_TIMING_MMC_DDR52 )
532+ loongson2_mmc_dll_mode_init (host );
425533}
426534
427535static void loongson2_mmc_set_ios (struct mmc_host * mmc , struct mmc_ios * ios )
@@ -634,6 +742,128 @@ static struct loongson2_mmc_pdata ls2k1000_mmc_pdata = {
634742 .release_dma = loongson2_mmc_release_external_dma ,
635743};
636744
745+ static const struct regmap_config ls2k2000_mmc_regmap_config = {
746+ .reg_bits = 32 ,
747+ .val_bits = 32 ,
748+ .reg_stride = 4 ,
749+ .max_register = LOONGSON2_MMC_REG_RDMA_HI ,
750+ };
751+
752+ static void ls2k2000_mmc_reorder_cmd_data (struct loongson2_mmc_host * host ,
753+ struct mmc_command * cmd )
754+ {
755+ struct scatterlist * sg ;
756+ u32 * data ;
757+ int i , j ;
758+
759+ if (cmd -> opcode != SD_SWITCH || mmc_cmd_type (cmd ) != MMC_CMD_ADTC )
760+ return ;
761+
762+ for_each_sg (cmd -> data -> sg , sg , cmd -> data -> sg_len , i ) {
763+ data = sg_virt (& sg [i ]);
764+ for (j = 0 ; j < (sg_dma_len (& sg [i ]) / 4 ); j ++ )
765+ data [j ] = bitrev8x4 (data [j ]);
766+ }
767+ }
768+
769+ /*
770+ * This is a controller hardware defect. Single/multiple block write commands
771+ * must be sent after the TX FULL flag is set, otherwise a data timeout interrupt
772+ * will occur.
773+ */
774+ static void ls2k2000_mmc_fix_data_timeout (struct loongson2_mmc_host * host ,
775+ struct mmc_command * cmd )
776+ {
777+ int val ;
778+
779+ if (cmd -> opcode != MMC_WRITE_BLOCK && cmd -> opcode != MMC_WRITE_MULTIPLE_BLOCK )
780+ return ;
781+
782+ regmap_read_poll_timeout (host -> regmap , LOONGSON2_MMC_REG_FSTS , val ,
783+ (val & LOONGSON2_MMC_FSTS_TXFULL ), 0 ,
784+ LOONGSON2_MMC_TXFULL_TIMEOUT_US );
785+ }
786+
787+ static int loongson2_mmc_prepare_internal_dma (struct loongson2_mmc_host * host ,
788+ struct mmc_data * data )
789+ {
790+ struct loongson2_dma_desc * pdes = (struct loongson2_dma_desc * )host -> sg_cpu ;
791+ struct mmc_host * mmc = mmc_from_priv (host );
792+ dma_addr_t next_desc = host -> sg_dma ;
793+ struct scatterlist * sg ;
794+ int reg_lo , reg_hi ;
795+ u64 dma_order ;
796+ int i , ret ;
797+
798+ ret = dma_map_sg (mmc_dev (mmc ), data -> sg , data -> sg_len ,
799+ mmc_get_dma_dir (data ));
800+ if (!ret )
801+ return - ENOMEM ;
802+
803+ for_each_sg (data -> sg , sg , data -> sg_len , i ) {
804+ pdes [i ].len = sg_dma_len (& sg [i ]) / 4 ;
805+ pdes [i ].step_len = 0 ;
806+ pdes [i ].step_times = 1 ;
807+ pdes [i ].mem_addr = lower_32_bits (sg_dma_address (& sg [i ]));
808+ pdes [i ].high_mem_addr = upper_32_bits (sg_dma_address (& sg [i ]));
809+ pdes [i ].apb_addr = host -> res -> start + LOONGSON2_MMC_REG_DATA ;
810+ pdes [i ].cmd = LOONGSON2_MMC_DMA_INT ;
811+
812+ if (data -> flags & MMC_DATA_READ ) {
813+ reg_lo = LOONGSON2_MMC_REG_RDMA_LO ;
814+ reg_hi = LOONGSON2_MMC_REG_RDMA_HI ;
815+ } else {
816+ pdes [i ].cmd |= LOONGSON2_MMC_DMA_DATA_DIR ;
817+ reg_lo = LOONGSON2_MMC_REG_WDMA_LO ;
818+ reg_hi = LOONGSON2_MMC_REG_WDMA_HI ;
819+ }
820+
821+ next_desc += sizeof (struct loongson2_dma_desc );
822+ pdes [i ].ndesc_addr = lower_32_bits (next_desc ) |
823+ LOONGSON2_MMC_DMA_DESC_EN ;
824+ pdes [i ].high_ndesc_addr = upper_32_bits (next_desc );
825+ }
826+
827+ /* Setting the last descriptor enable bit */
828+ pdes [i - 1 ].ndesc_addr &= ~LOONGSON2_MMC_DMA_DESC_EN ;
829+
830+ dma_order = (host -> sg_dma & ~LOONGSON2_MMC_DMA_CONFIG_MASK ) |
831+ LOONGSON2_MMC_DMA_64BIT_EN |
832+ LOONGSON2_MMC_DMA_START ;
833+
834+ regmap_write (host -> regmap , reg_hi , upper_32_bits (dma_order ));
835+ regmap_write (host -> regmap , reg_lo , lower_32_bits (dma_order ));
836+
837+ return 0 ;
838+ }
839+
840+ static int loongson2_mmc_set_internal_dma (struct loongson2_mmc_host * host ,
841+ struct platform_device * pdev )
842+ {
843+ host -> sg_cpu = dma_alloc_coherent (& pdev -> dev , PAGE_SIZE ,
844+ & host -> sg_dma , GFP_KERNEL );
845+ if (!host -> sg_cpu )
846+ return - ENOMEM ;
847+
848+ memset (host -> sg_cpu , 0 , PAGE_SIZE );
849+ return 0 ;
850+ }
851+
852+ static void loongson2_mmc_release_internal_dma (struct loongson2_mmc_host * host ,
853+ struct device * dev )
854+ {
855+ dma_free_coherent (dev , PAGE_SIZE , host -> sg_cpu , host -> sg_dma );
856+ }
857+
858+ static struct loongson2_mmc_pdata ls2k2000_mmc_pdata = {
859+ .regmap_config = & ls2k2000_mmc_regmap_config ,
860+ .reorder_cmd_data = ls2k2000_mmc_reorder_cmd_data ,
861+ .fix_data_timeout = ls2k2000_mmc_fix_data_timeout ,
862+ .setting_dma = loongson2_mmc_set_internal_dma ,
863+ .prepare_dma = loongson2_mmc_prepare_internal_dma ,
864+ .release_dma = loongson2_mmc_release_internal_dma ,
865+ };
866+
637867static int loongson2_mmc_resource_request (struct platform_device * pdev ,
638868 struct loongson2_mmc_host * host )
639869{
@@ -756,6 +986,7 @@ static void loongson2_mmc_remove(struct platform_device *pdev)
756986static const struct of_device_id loongson2_mmc_of_ids [] = {
757987 { .compatible = "loongson,ls2k0500-mmc" , .data = & ls2k0500_mmc_pdata },
758988 { .compatible = "loongson,ls2k1000-mmc" , .data = & ls2k1000_mmc_pdata },
989+ { .compatible = "loongson,ls2k2000-mmc" , .data = & ls2k2000_mmc_pdata },
759990 { },
760991};
761992MODULE_DEVICE_TABLE (of , loongson2_mmc_of_ids );
0 commit comments