3131#define SDHCI_GLI_9750_ALL_RST (BIT(24)|BIT(25)|BIT(28)|BIT(30))
3232
3333#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)
3437#define SDHCI_GLI_9750_PLL_TX2_INV BIT(23)
3538#define SDHCI_GLI_9750_PLL_TX2_DLY GENMASK(22, 20)
3639#define GLI_9750_PLL_TX2_INV_VALUE 0x1
3740#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)
3846
3947#define SDHCI_GLI_9750_SW_CTRL 0x874
4048#define SDHCI_GLI_9750_SW_CTRL_4 GENMASK(7, 6)
7684#define PCIE_GLI_9763E_SCR 0x8E0
7785#define GLI_9763E_SCR_AXI_REQ BIT(9)
7886
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+
79102#define GLI_MAX_TUNING_LOOP 40
80103
81104/* Genesys Logic chipset */
@@ -280,6 +303,84 @@ static int gl9750_execute_tuning(struct sdhci_host *host, u32 opcode)
280303 return 0 ;
281304}
282305
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+
283384static void gli_pcie_enable_msi (struct sdhci_pci_slot * slot )
284385{
285386 int ret ;
@@ -295,6 +396,121 @@ static void gli_pcie_enable_msi(struct sdhci_pci_slot *slot)
295396 slot -> host -> irq = pci_irq_vector (slot -> chip -> pdev , 0 );
296397}
297398
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+
298514static int gli_probe_slot_gl9750 (struct sdhci_pci_slot * slot )
299515{
300516 struct sdhci_host * host = slot -> host ;
@@ -440,7 +656,7 @@ static int gli_probe_slot_gl9763e(struct sdhci_pci_slot *slot)
440656}
441657
442658static const struct sdhci_ops sdhci_gl9755_ops = {
443- .set_clock = sdhci_set_clock ,
659+ .set_clock = sdhci_gl9755_set_clock ,
444660 .enable_dma = sdhci_pci_enable_dma ,
445661 .set_bus_width = sdhci_set_bus_width ,
446662 .reset = sdhci_reset ,
@@ -460,7 +676,7 @@ const struct sdhci_pci_fixes sdhci_gl9755 = {
460676
461677static const struct sdhci_ops sdhci_gl9750_ops = {
462678 .read_l = sdhci_gl9750_readl ,
463- .set_clock = sdhci_set_clock ,
679+ .set_clock = sdhci_gl9750_set_clock ,
464680 .enable_dma = sdhci_pci_enable_dma ,
465681 .set_bus_width = sdhci_set_bus_width ,
466682 .reset = sdhci_gl9750_reset ,
0 commit comments