31
31
#define SDHCI_GLI_9750_ALL_RST (BIT(24)|BIT(25)|BIT(28)|BIT(30))
32
32
33
33
#define SDHCI_GLI_9750_PLL 0x864
34
+ #define SDHCI_GLI_9750_PLL_LDIV GENMASK(9, 0)
35
+ #define SDHCI_GLI_9750_PLL_PDIV GENMASK(14, 12)
36
+ #define SDHCI_GLI_9750_PLL_DIR BIT(15)
34
37
#define SDHCI_GLI_9750_PLL_TX2_INV BIT(23)
35
38
#define SDHCI_GLI_9750_PLL_TX2_DLY GENMASK(22, 20)
36
39
#define GLI_9750_PLL_TX2_INV_VALUE 0x1
37
40
#define GLI_9750_PLL_TX2_DLY_VALUE 0x0
41
+ #define SDHCI_GLI_9750_PLLSSC_STEP GENMASK(28, 24)
42
+ #define SDHCI_GLI_9750_PLLSSC_EN BIT(31)
43
+
44
+ #define SDHCI_GLI_9750_PLLSSC 0x86C
45
+ #define SDHCI_GLI_9750_PLLSSC_PPM GENMASK(31, 16)
38
46
39
47
#define SDHCI_GLI_9750_SW_CTRL 0x874
40
48
#define SDHCI_GLI_9750_SW_CTRL_4 GENMASK(7, 6)
76
84
#define PCIE_GLI_9763E_SCR 0x8E0
77
85
#define GLI_9763E_SCR_AXI_REQ BIT(9)
78
86
87
+ #define PCI_GLI_9755_WT 0x800
88
+ #define PCI_GLI_9755_WT_EN BIT(0)
89
+ #define GLI_9755_WT_EN_ON 0x1
90
+ #define GLI_9755_WT_EN_OFF 0x0
91
+
92
+ #define PCI_GLI_9755_PLL 0x64
93
+ #define PCI_GLI_9755_PLL_LDIV GENMASK(9, 0)
94
+ #define PCI_GLI_9755_PLL_PDIV GENMASK(14, 12)
95
+ #define PCI_GLI_9755_PLL_DIR BIT(15)
96
+ #define PCI_GLI_9755_PLLSSC_STEP GENMASK(28, 24)
97
+ #define PCI_GLI_9755_PLLSSC_EN BIT(31)
98
+
99
+ #define PCI_GLI_9755_PLLSSC 0x68
100
+ #define PCI_GLI_9755_PLLSSC_PPM GENMASK(15, 0)
101
+
79
102
#define GLI_MAX_TUNING_LOOP 40
80
103
81
104
/* Genesys Logic chipset */
@@ -280,6 +303,84 @@ static int gl9750_execute_tuning(struct sdhci_host *host, u32 opcode)
280
303
return 0 ;
281
304
}
282
305
306
+ static void gl9750_disable_ssc_pll (struct sdhci_host * host )
307
+ {
308
+ u32 pll ;
309
+
310
+ gl9750_wt_on (host );
311
+ pll = sdhci_readl (host , SDHCI_GLI_9750_PLL );
312
+ pll &= ~(SDHCI_GLI_9750_PLL_DIR | SDHCI_GLI_9750_PLLSSC_EN );
313
+ sdhci_writel (host , pll , SDHCI_GLI_9750_PLL );
314
+ gl9750_wt_off (host );
315
+ }
316
+
317
+ static void gl9750_set_pll (struct sdhci_host * host , u8 dir , u16 ldiv , u8 pdiv )
318
+ {
319
+ u32 pll ;
320
+
321
+ gl9750_wt_on (host );
322
+ pll = sdhci_readl (host , SDHCI_GLI_9750_PLL );
323
+ pll &= ~(SDHCI_GLI_9750_PLL_LDIV |
324
+ SDHCI_GLI_9750_PLL_PDIV |
325
+ SDHCI_GLI_9750_PLL_DIR );
326
+ pll |= FIELD_PREP (SDHCI_GLI_9750_PLL_LDIV , ldiv ) |
327
+ FIELD_PREP (SDHCI_GLI_9750_PLL_PDIV , pdiv ) |
328
+ FIELD_PREP (SDHCI_GLI_9750_PLL_DIR , dir );
329
+ sdhci_writel (host , pll , SDHCI_GLI_9750_PLL );
330
+ gl9750_wt_off (host );
331
+
332
+ /* wait for pll stable */
333
+ mdelay (1 );
334
+ }
335
+
336
+ static void gl9750_set_ssc (struct sdhci_host * host , u8 enable , u8 step , u16 ppm )
337
+ {
338
+ u32 pll ;
339
+ u32 ssc ;
340
+
341
+ gl9750_wt_on (host );
342
+ pll = sdhci_readl (host , SDHCI_GLI_9750_PLL );
343
+ ssc = sdhci_readl (host , SDHCI_GLI_9750_PLLSSC );
344
+ pll &= ~(SDHCI_GLI_9750_PLLSSC_STEP |
345
+ SDHCI_GLI_9750_PLLSSC_EN );
346
+ ssc &= ~SDHCI_GLI_9750_PLLSSC_PPM ;
347
+ pll |= FIELD_PREP (SDHCI_GLI_9750_PLLSSC_STEP , step ) |
348
+ FIELD_PREP (SDHCI_GLI_9750_PLLSSC_EN , enable );
349
+ ssc |= FIELD_PREP (SDHCI_GLI_9750_PLLSSC_PPM , ppm );
350
+ sdhci_writel (host , ssc , SDHCI_GLI_9750_PLLSSC );
351
+ sdhci_writel (host , pll , SDHCI_GLI_9750_PLL );
352
+ gl9750_wt_off (host );
353
+ }
354
+
355
+ static void gl9750_set_ssc_pll_205mhz (struct sdhci_host * host )
356
+ {
357
+ /* set pll to 205MHz and enable ssc */
358
+ gl9750_set_ssc (host , 0x1 , 0x1F , 0xFFE7 );
359
+ gl9750_set_pll (host , 0x1 , 0x246 , 0x0 );
360
+ }
361
+
362
+ static void sdhci_gl9750_set_clock (struct sdhci_host * host , unsigned int clock )
363
+ {
364
+ struct mmc_ios * ios = & host -> mmc -> ios ;
365
+ u16 clk ;
366
+
367
+ host -> mmc -> actual_clock = 0 ;
368
+
369
+ gl9750_disable_ssc_pll (host );
370
+ sdhci_writew (host , 0 , SDHCI_CLOCK_CONTROL );
371
+
372
+ if (clock == 0 )
373
+ return ;
374
+
375
+ clk = sdhci_calc_clk (host , clock , & host -> mmc -> actual_clock );
376
+ if (clock == 200000000 && ios -> timing == MMC_TIMING_UHS_SDR104 ) {
377
+ host -> mmc -> actual_clock = 205000000 ;
378
+ gl9750_set_ssc_pll_205mhz (host );
379
+ }
380
+
381
+ sdhci_enable_clk (host , clk );
382
+ }
383
+
283
384
static void gli_pcie_enable_msi (struct sdhci_pci_slot * slot )
284
385
{
285
386
int ret ;
@@ -295,6 +396,121 @@ static void gli_pcie_enable_msi(struct sdhci_pci_slot *slot)
295
396
slot -> host -> irq = pci_irq_vector (slot -> chip -> pdev , 0 );
296
397
}
297
398
399
+ static inline void gl9755_wt_on (struct pci_dev * pdev )
400
+ {
401
+ u32 wt_value ;
402
+ u32 wt_enable ;
403
+
404
+ pci_read_config_dword (pdev , PCI_GLI_9755_WT , & wt_value );
405
+ wt_enable = FIELD_GET (PCI_GLI_9755_WT_EN , wt_value );
406
+
407
+ if (wt_enable == GLI_9755_WT_EN_ON )
408
+ return ;
409
+
410
+ wt_value &= ~PCI_GLI_9755_WT_EN ;
411
+ wt_value |= FIELD_PREP (PCI_GLI_9755_WT_EN , GLI_9755_WT_EN_ON );
412
+
413
+ pci_write_config_dword (pdev , PCI_GLI_9755_WT , wt_value );
414
+ }
415
+
416
+ static inline void gl9755_wt_off (struct pci_dev * pdev )
417
+ {
418
+ u32 wt_value ;
419
+ u32 wt_enable ;
420
+
421
+ pci_read_config_dword (pdev , PCI_GLI_9755_WT , & wt_value );
422
+ wt_enable = FIELD_GET (PCI_GLI_9755_WT_EN , wt_value );
423
+
424
+ if (wt_enable == GLI_9755_WT_EN_OFF )
425
+ return ;
426
+
427
+ wt_value &= ~PCI_GLI_9755_WT_EN ;
428
+ wt_value |= FIELD_PREP (PCI_GLI_9755_WT_EN , GLI_9755_WT_EN_OFF );
429
+
430
+ pci_write_config_dword (pdev , PCI_GLI_9755_WT , wt_value );
431
+ }
432
+
433
+ static void gl9755_disable_ssc_pll (struct pci_dev * pdev )
434
+ {
435
+ u32 pll ;
436
+
437
+ gl9755_wt_on (pdev );
438
+ pci_read_config_dword (pdev , PCI_GLI_9755_PLL , & pll );
439
+ pll &= ~(PCI_GLI_9755_PLL_DIR | PCI_GLI_9755_PLLSSC_EN );
440
+ pci_write_config_dword (pdev , PCI_GLI_9755_PLL , pll );
441
+ gl9755_wt_off (pdev );
442
+ }
443
+
444
+ static void gl9755_set_pll (struct pci_dev * pdev , u8 dir , u16 ldiv , u8 pdiv )
445
+ {
446
+ u32 pll ;
447
+
448
+ gl9755_wt_on (pdev );
449
+ pci_read_config_dword (pdev , PCI_GLI_9755_PLL , & pll );
450
+ pll &= ~(PCI_GLI_9755_PLL_LDIV |
451
+ PCI_GLI_9755_PLL_PDIV |
452
+ PCI_GLI_9755_PLL_DIR );
453
+ pll |= FIELD_PREP (PCI_GLI_9755_PLL_LDIV , ldiv ) |
454
+ FIELD_PREP (PCI_GLI_9755_PLL_PDIV , pdiv ) |
455
+ FIELD_PREP (PCI_GLI_9755_PLL_DIR , dir );
456
+ pci_write_config_dword (pdev , PCI_GLI_9755_PLL , pll );
457
+ gl9755_wt_off (pdev );
458
+
459
+ /* wait for pll stable */
460
+ mdelay (1 );
461
+ }
462
+
463
+ static void gl9755_set_ssc (struct pci_dev * pdev , u8 enable , u8 step , u16 ppm )
464
+ {
465
+ u32 pll ;
466
+ u32 ssc ;
467
+
468
+ gl9755_wt_on (pdev );
469
+ pci_read_config_dword (pdev , PCI_GLI_9755_PLL , & pll );
470
+ pci_read_config_dword (pdev , PCI_GLI_9755_PLLSSC , & ssc );
471
+ pll &= ~(PCI_GLI_9755_PLLSSC_STEP |
472
+ PCI_GLI_9755_PLLSSC_EN );
473
+ ssc &= ~PCI_GLI_9755_PLLSSC_PPM ;
474
+ pll |= FIELD_PREP (PCI_GLI_9755_PLLSSC_STEP , step ) |
475
+ FIELD_PREP (PCI_GLI_9755_PLLSSC_EN , enable );
476
+ ssc |= FIELD_PREP (PCI_GLI_9755_PLLSSC_PPM , ppm );
477
+ pci_write_config_dword (pdev , PCI_GLI_9755_PLLSSC , ssc );
478
+ pci_write_config_dword (pdev , PCI_GLI_9755_PLL , pll );
479
+ gl9755_wt_off (pdev );
480
+ }
481
+
482
+ static void gl9755_set_ssc_pll_205mhz (struct pci_dev * pdev )
483
+ {
484
+ /* set pll to 205MHz and enable ssc */
485
+ gl9755_set_ssc (pdev , 0x1 , 0x1F , 0xFFE7 );
486
+ gl9755_set_pll (pdev , 0x1 , 0x246 , 0x0 );
487
+ }
488
+
489
+ static void sdhci_gl9755_set_clock (struct sdhci_host * host , unsigned int clock )
490
+ {
491
+ struct sdhci_pci_slot * slot = sdhci_priv (host );
492
+ struct mmc_ios * ios = & host -> mmc -> ios ;
493
+ struct pci_dev * pdev ;
494
+ u16 clk ;
495
+
496
+ pdev = slot -> chip -> pdev ;
497
+ host -> mmc -> actual_clock = 0 ;
498
+
499
+ gl9755_disable_ssc_pll (pdev );
500
+ sdhci_writew (host , 0 , SDHCI_CLOCK_CONTROL );
501
+
502
+ if (clock == 0 )
503
+ return ;
504
+
505
+ clk = sdhci_calc_clk (host , clock , & host -> mmc -> actual_clock );
506
+ if (clock == 200000000 && ios -> timing == MMC_TIMING_UHS_SDR104 ) {
507
+ host -> mmc -> actual_clock = 205000000 ;
508
+ gl9755_set_ssc_pll_205mhz (pdev );
509
+ }
510
+
511
+ sdhci_enable_clk (host , clk );
512
+ }
513
+
298
514
static int gli_probe_slot_gl9750 (struct sdhci_pci_slot * slot )
299
515
{
300
516
struct sdhci_host * host = slot -> host ;
@@ -440,7 +656,7 @@ static int gli_probe_slot_gl9763e(struct sdhci_pci_slot *slot)
440
656
}
441
657
442
658
static const struct sdhci_ops sdhci_gl9755_ops = {
443
- .set_clock = sdhci_set_clock ,
659
+ .set_clock = sdhci_gl9755_set_clock ,
444
660
.enable_dma = sdhci_pci_enable_dma ,
445
661
.set_bus_width = sdhci_set_bus_width ,
446
662
.reset = sdhci_reset ,
@@ -460,7 +676,7 @@ const struct sdhci_pci_fixes sdhci_gl9755 = {
460
676
461
677
static const struct sdhci_ops sdhci_gl9750_ops = {
462
678
.read_l = sdhci_gl9750_readl ,
463
- .set_clock = sdhci_set_clock ,
679
+ .set_clock = sdhci_gl9750_set_clock ,
464
680
.enable_dma = sdhci_pci_enable_dma ,
465
681
.set_bus_width = sdhci_set_bus_width ,
466
682
.reset = sdhci_gl9750_reset ,
0 commit comments