44
44
#define LOONGSON2_MMC_REG_DATA 0x40 /* Data Register */
45
45
#define LOONGSON2_MMC_REG_IEN 0x64 /* Interrupt Enable Register */
46
46
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
+
47
59
/* Bitfields of control register */
48
60
#define LOONGSON2_MMC_CTL_ENCLK BIT(0)
49
61
#define LOONGSON2_MMC_CTL_EXTCLK BIT(1)
109
121
#define LOONGSON2_MMC_DSTS_RESUME BIT(15)
110
122
#define LOONGSON2_MMC_DSTS_SUSPEND BIT(16)
111
123
124
+ /* Bitfields of FIFO Status Register */
125
+ #define LOONGSON2_MMC_FSTS_TXFULL BIT(11)
126
+
112
127
/* Bitfields of interrupt register */
113
128
#define LOONGSON2_MMC_INT_DFIN BIT(0)
114
129
#define LOONGSON2_MMC_INT_DTIMEOUT BIT(1)
136
151
#define LOONGSON2_MMC_IEN_ALL GENMASK(9, 0)
137
152
#define LOONGSON2_MMC_INT_CLEAR GENMASK(9, 0)
138
153
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
+
139
192
/* Loongson-2K1000 SDIO2 DMA routing register */
140
193
#define LS2K1000_SDIO_DMA_MASK GENMASK(17, 15)
141
194
#define LS2K1000_DMA0_CONF 0x0
@@ -159,13 +212,29 @@ enum loongson2_mmc_state {
159
212
STATE_XFERFINISH_RSPFIN ,
160
213
};
161
214
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
+
162
229
struct loongson2_mmc_host {
163
230
struct device * dev ;
164
231
struct mmc_request * mrq ;
165
232
struct regmap * regmap ;
166
233
struct resource * res ;
167
234
struct clk * clk ;
168
235
u32 current_clk ;
236
+ void * sg_cpu ;
237
+ dma_addr_t sg_dma ;
169
238
int dma_complete ;
170
239
struct dma_chan * chan ;
171
240
int cmd_is_stop ;
@@ -178,6 +247,7 @@ struct loongson2_mmc_host {
178
247
struct loongson2_mmc_pdata {
179
248
const struct regmap_config * regmap_config ;
180
249
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 );
181
251
int (* setting_dma )(struct loongson2_mmc_host * host , struct platform_device * pdev );
182
252
int (* prepare_dma )(struct loongson2_mmc_host * host , struct mmc_data * data );
183
253
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)
268
338
return ;
269
339
}
270
340
341
+ if (host -> pdata -> fix_data_timeout )
342
+ host -> pdata -> fix_data_timeout (host , cmd );
343
+
271
344
loongson2_mmc_send_command (host , cmd );
272
345
273
346
/* Fix deselect card */
@@ -410,6 +483,37 @@ static irqreturn_t loongson2_mmc_irq(int irq, void *devid)
410
483
return IRQ_WAKE_THREAD ;
411
484
}
412
485
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
+
413
517
static void loongson2_mmc_set_clk (struct loongson2_mmc_host * host , struct mmc_ios * ios )
414
518
{
415
519
u32 pre ;
@@ -422,6 +526,10 @@ static void loongson2_mmc_set_clk(struct loongson2_mmc_host *host, struct mmc_io
422
526
423
527
regmap_update_bits (host -> regmap , LOONGSON2_MMC_REG_CTL ,
424
528
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 );
425
533
}
426
534
427
535
static 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 = {
634
742
.release_dma = loongson2_mmc_release_external_dma ,
635
743
};
636
744
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
+
637
867
static int loongson2_mmc_resource_request (struct platform_device * pdev ,
638
868
struct loongson2_mmc_host * host )
639
869
{
@@ -756,6 +986,7 @@ static void loongson2_mmc_remove(struct platform_device *pdev)
756
986
static const struct of_device_id loongson2_mmc_of_ids [] = {
757
987
{ .compatible = "loongson,ls2k0500-mmc" , .data = & ls2k0500_mmc_pdata },
758
988
{ .compatible = "loongson,ls2k1000-mmc" , .data = & ls2k1000_mmc_pdata },
989
+ { .compatible = "loongson,ls2k2000-mmc" , .data = & ls2k2000_mmc_pdata },
759
990
{ },
760
991
};
761
992
MODULE_DEVICE_TABLE (of , loongson2_mmc_of_ids );
0 commit comments