25
25
#include <linux/of_device.h>
26
26
#include <linux/phy/phy.h>
27
27
#include <linux/regmap.h>
28
- #include "sdhci-pltfm.h"
29
28
#include <linux/of.h>
30
29
31
- #define SDHCI_ARASAN_VENDOR_REGISTER 0x78
30
+ #include "cqhci.h"
31
+ #include "sdhci-pltfm.h"
32
32
33
+ #define SDHCI_ARASAN_VENDOR_REGISTER 0x78
34
+ #define SDHCI_ARASAN_CQE_BASE_ADDR 0x200
33
35
#define VENDOR_ENHANCED_STROBE BIT(0)
34
36
35
37
#define PHY_CLK_TOO_SLOW_HZ 400000
@@ -90,6 +92,7 @@ struct sdhci_arasan_data {
90
92
struct phy * phy ;
91
93
bool is_phy_on ;
92
94
95
+ bool has_cqe ;
93
96
struct clk_hw sdcardclk_hw ;
94
97
struct clk * sdcardclk ;
95
98
@@ -290,6 +293,62 @@ static const struct sdhci_pltfm_data sdhci_arasan_pdata = {
290
293
SDHCI_QUIRK2_CLOCK_DIV_ZERO_BROKEN ,
291
294
};
292
295
296
+ static u32 sdhci_arasan_cqhci_irq (struct sdhci_host * host , u32 intmask )
297
+ {
298
+ int cmd_error = 0 ;
299
+ int data_error = 0 ;
300
+
301
+ if (!sdhci_cqe_irq (host , intmask , & cmd_error , & data_error ))
302
+ return intmask ;
303
+
304
+ cqhci_irq (host -> mmc , intmask , cmd_error , data_error );
305
+
306
+ return 0 ;
307
+ }
308
+
309
+ static void sdhci_arasan_dumpregs (struct mmc_host * mmc )
310
+ {
311
+ sdhci_dumpregs (mmc_priv (mmc ));
312
+ }
313
+
314
+ static void sdhci_arasan_cqe_enable (struct mmc_host * mmc )
315
+ {
316
+ struct sdhci_host * host = mmc_priv (mmc );
317
+ u32 reg ;
318
+
319
+ reg = sdhci_readl (host , SDHCI_PRESENT_STATE );
320
+ while (reg & SDHCI_DATA_AVAILABLE ) {
321
+ sdhci_readl (host , SDHCI_BUFFER );
322
+ reg = sdhci_readl (host , SDHCI_PRESENT_STATE );
323
+ }
324
+
325
+ sdhci_cqe_enable (mmc );
326
+ }
327
+
328
+ static const struct cqhci_host_ops sdhci_arasan_cqhci_ops = {
329
+ .enable = sdhci_arasan_cqe_enable ,
330
+ .disable = sdhci_cqe_disable ,
331
+ .dumpregs = sdhci_arasan_dumpregs ,
332
+ };
333
+
334
+ static const struct sdhci_ops sdhci_arasan_cqe_ops = {
335
+ .set_clock = sdhci_arasan_set_clock ,
336
+ .get_max_clock = sdhci_pltfm_clk_get_max_clock ,
337
+ .get_timeout_clock = sdhci_pltfm_clk_get_max_clock ,
338
+ .set_bus_width = sdhci_set_bus_width ,
339
+ .reset = sdhci_arasan_reset ,
340
+ .set_uhs_signaling = sdhci_set_uhs_signaling ,
341
+ .set_power = sdhci_arasan_set_power ,
342
+ .irq = sdhci_arasan_cqhci_irq ,
343
+ };
344
+
345
+ static const struct sdhci_pltfm_data sdhci_arasan_cqe_pdata = {
346
+ .ops = & sdhci_arasan_cqe_ops ,
347
+ .quirks = SDHCI_QUIRK_CAP_CLOCK_BASE_BROKEN ,
348
+ .quirks2 = SDHCI_QUIRK2_PRESET_VALUE_BROKEN |
349
+ SDHCI_QUIRK2_CLOCK_DIV_ZERO_BROKEN ,
350
+ };
351
+
293
352
#ifdef CONFIG_PM_SLEEP
294
353
/**
295
354
* sdhci_arasan_suspend - Suspend method for the driver
@@ -309,6 +368,12 @@ static int sdhci_arasan_suspend(struct device *dev)
309
368
if (host -> tuning_mode != SDHCI_TUNING_MODE_3 )
310
369
mmc_retune_needed (host -> mmc );
311
370
371
+ if (sdhci_arasan -> has_cqe ) {
372
+ ret = cqhci_suspend (host -> mmc );
373
+ if (ret )
374
+ return ret ;
375
+ }
376
+
312
377
ret = sdhci_suspend_host (host );
313
378
if (ret )
314
379
return ret ;
@@ -365,7 +430,16 @@ static int sdhci_arasan_resume(struct device *dev)
365
430
sdhci_arasan -> is_phy_on = true;
366
431
}
367
432
368
- return sdhci_resume_host (host );
433
+ ret = sdhci_resume_host (host );
434
+ if (ret ) {
435
+ dev_err (dev , "Cannot resume host.\n" );
436
+ return ret ;
437
+ }
438
+
439
+ if (sdhci_arasan -> has_cqe )
440
+ return cqhci_resume (host -> mmc );
441
+
442
+ return 0 ;
369
443
}
370
444
#endif /* ! CONFIG_PM_SLEEP */
371
445
@@ -568,6 +642,49 @@ static void sdhci_arasan_unregister_sdclk(struct device *dev)
568
642
of_clk_del_provider (dev -> of_node );
569
643
}
570
644
645
+ static int sdhci_arasan_add_host (struct sdhci_arasan_data * sdhci_arasan )
646
+ {
647
+ struct sdhci_host * host = sdhci_arasan -> host ;
648
+ struct cqhci_host * cq_host ;
649
+ bool dma64 ;
650
+ int ret ;
651
+
652
+ if (!sdhci_arasan -> has_cqe )
653
+ return sdhci_add_host (host );
654
+
655
+ ret = sdhci_setup_host (host );
656
+ if (ret )
657
+ return ret ;
658
+
659
+ cq_host = devm_kzalloc (host -> mmc -> parent ,
660
+ sizeof (* cq_host ), GFP_KERNEL );
661
+ if (!cq_host ) {
662
+ ret = - ENOMEM ;
663
+ goto cleanup ;
664
+ }
665
+
666
+ cq_host -> mmio = host -> ioaddr + SDHCI_ARASAN_CQE_BASE_ADDR ;
667
+ cq_host -> ops = & sdhci_arasan_cqhci_ops ;
668
+
669
+ dma64 = host -> flags & SDHCI_USE_64_BIT_DMA ;
670
+ if (dma64 )
671
+ cq_host -> caps |= CQHCI_TASK_DESC_SZ_128 ;
672
+
673
+ ret = cqhci_init (cq_host , host -> mmc , dma64 );
674
+ if (ret )
675
+ goto cleanup ;
676
+
677
+ ret = __sdhci_add_host (host );
678
+ if (ret )
679
+ goto cleanup ;
680
+
681
+ return 0 ;
682
+
683
+ cleanup :
684
+ sdhci_cleanup_host (host );
685
+ return ret ;
686
+ }
687
+
571
688
static int sdhci_arasan_probe (struct platform_device * pdev )
572
689
{
573
690
int ret ;
@@ -578,9 +695,15 @@ static int sdhci_arasan_probe(struct platform_device *pdev)
578
695
struct sdhci_pltfm_host * pltfm_host ;
579
696
struct sdhci_arasan_data * sdhci_arasan ;
580
697
struct device_node * np = pdev -> dev .of_node ;
698
+ const struct sdhci_pltfm_data * pdata ;
699
+
700
+ if (of_device_is_compatible (pdev -> dev .of_node , "arasan,sdhci-5.1" ))
701
+ pdata = & sdhci_arasan_cqe_pdata ;
702
+ else
703
+ pdata = & sdhci_arasan_pdata ;
704
+
705
+ host = sdhci_pltfm_init (pdev , pdata , sizeof (* sdhci_arasan ));
581
706
582
- host = sdhci_pltfm_init (pdev , & sdhci_arasan_pdata ,
583
- sizeof (* sdhci_arasan ));
584
707
if (IS_ERR (host ))
585
708
return PTR_ERR (host );
586
709
@@ -675,9 +798,11 @@ static int sdhci_arasan_probe(struct platform_device *pdev)
675
798
sdhci_arasan_hs400_enhanced_strobe ;
676
799
host -> mmc_host_ops .start_signal_voltage_switch =
677
800
sdhci_arasan_voltage_switch ;
801
+ sdhci_arasan -> has_cqe = true;
802
+ host -> mmc -> caps2 |= MMC_CAP2_CQE | MMC_CAP2_CQE_DCMD ;
678
803
}
679
804
680
- ret = sdhci_add_host ( host );
805
+ ret = sdhci_arasan_add_host ( sdhci_arasan );
681
806
if (ret )
682
807
goto err_add_host ;
683
808
0 commit comments