24
24
25
25
#include <mach/map.h>
26
26
#include <mach/regs-clock.h>
27
+ #include <mach/regs-audss.h>
27
28
#include <mach/sysmmu.h>
28
29
29
30
#include "common.h"
@@ -198,6 +199,11 @@ static int exynos4_clk_ip_perir_ctrl(struct clk *clk, int enable)
198
199
return s5p_gatectrl (EXYNOS4_CLKGATE_IP_PERIR , clk , enable );
199
200
}
200
201
202
+ static int exynos4_clk_vpll_ctrl (struct clk * clk , int enable )
203
+ {
204
+ return s5p_gatectrl (EXYNOS4_VPLL_CON0 , clk , enable );
205
+ }
206
+
201
207
int exynos4_clk_ip_dmc_ctrl (struct clk * clk , int enable )
202
208
{
203
209
return s5p_gatectrl (EXYNOS4_CLKGATE_IP_DMC , clk , enable );
@@ -213,6 +219,16 @@ static int exynos4_clk_dac_ctrl(struct clk *clk, int enable)
213
219
return s5p_gatectrl (S5P_DAC_PHY_CONTROL , clk , enable );
214
220
}
215
221
222
+ static int exynos4_clksrc_mask_maudio_ctrl (struct clk * clk , int enable )
223
+ {
224
+ return s5p_gatectrl (EXYNOS4_CLKSRC_MASK_MAUDIO , clk , enable );
225
+ }
226
+
227
+ int exynos4_clk_audss_ctrl (struct clk * clk , int enable )
228
+ {
229
+ return s5p_gatectrl (S5P_CLKGATE_AUDSS , clk , enable );
230
+ }
231
+
216
232
/* Core list of CMU_CPU side */
217
233
218
234
static struct clksrc_clk exynos4_clk_mout_apll = {
@@ -451,6 +467,25 @@ static struct clksrc_sources exynos4_clkset_sclk_vpll = {
451
467
.nr_sources = ARRAY_SIZE (exynos4_clkset_sclk_vpll_list ),
452
468
};
453
469
470
+ static struct clk * exynos4_clkset_mout_audss_list [] = {
471
+ & clk_ext_xtal_mux ,
472
+ & clk_fout_epll ,
473
+ };
474
+
475
+ static struct clksrc_sources clkset_mout_audss = {
476
+ .sources = exynos4_clkset_mout_audss_list ,
477
+ .nr_sources = ARRAY_SIZE (exynos4_clkset_mout_audss_list ),
478
+ };
479
+
480
+ static struct clksrc_clk exynos4_clk_mout_audss = {
481
+ .clk = {
482
+ .name = "mout_audss" ,
483
+ },
484
+ .sources = & clkset_mout_audss ,
485
+ .reg_src = { .reg = S5P_CLKSRC_AUDSS , .shift = 0 , .size = 1 },
486
+ };
487
+
488
+
454
489
static struct clksrc_clk exynos4_clk_sclk_vpll = {
455
490
.clk = {
456
491
.name = "sclk_vpll" ,
@@ -459,6 +494,43 @@ static struct clksrc_clk exynos4_clk_sclk_vpll = {
459
494
.reg_src = { .reg = EXYNOS4_CLKSRC_TOP0 , .shift = 8 , .size = 1 },
460
495
};
461
496
497
+ static struct clksrc_clk exynos4_clk_dout_audss_srp = {
498
+ .clk = {
499
+ .name = "dout_srp" ,
500
+ .parent = & exynos4_clk_mout_audss .clk ,
501
+ },
502
+ .reg_div = { .reg = S5P_CLKDIV_AUDSS , .shift = 0 , .size = 4 },
503
+ };
504
+
505
+ static struct clksrc_clk exynos4_clk_sclk_audss_bus = {
506
+ .clk = {
507
+ .name = "busclk" ,
508
+ .parent = & exynos4_clk_dout_audss_srp .clk ,
509
+ .enable = exynos4_clk_audss_ctrl ,
510
+ .ctrlbit = (1 << 2 ),
511
+ },
512
+ .reg_div = { .reg = S5P_CLKDIV_AUDSS , .shift = 4 , .size = 4 },
513
+ };
514
+
515
+ static struct clk exynos4_init_audss_clocks [] = {
516
+ {
517
+ .name = "srpclk" ,
518
+ .enable = exynos4_clk_audss_ctrl ,
519
+ .parent = & exynos4_clk_dout_audss_srp .clk ,
520
+ .ctrlbit = (1 << 0 ),
521
+ }, {
522
+ .name = "iis" ,
523
+ .devname = "samsung-i2s.0" ,
524
+ .enable = exynos4_clk_audss_ctrl ,
525
+ .ctrlbit = (1 << 3 ) | (1 << 2 ),
526
+ }, {
527
+ .name = "pcm" ,
528
+ .devname = "samsung-pcm.0" ,
529
+ .enable = exynos4_clk_audss_ctrl ,
530
+ .ctrlbit = (1 << 5 ),
531
+ },
532
+ };
533
+
462
534
static struct clk exynos4_init_clocks_off [] = {
463
535
{
464
536
.name = "timers" ,
@@ -599,11 +671,6 @@ static struct clk exynos4_init_clocks_off[] = {
599
671
.devname = "exynos4210-spi.2" ,
600
672
.enable = exynos4_clk_ip_peril_ctrl ,
601
673
.ctrlbit = (1 << 18 ),
602
- }, {
603
- .name = "iis" ,
604
- .devname = "samsung-i2s.0" ,
605
- .enable = exynos4_clk_ip_peril_ctrl ,
606
- .ctrlbit = (1 << 19 ),
607
674
}, {
608
675
.name = "iis" ,
609
676
.devname = "samsung-i2s.1" ,
@@ -728,7 +795,65 @@ static struct clk exynos4_init_clocks_off[] = {
728
795
.devname = SYSMMU_CLOCK_DEVNAME (fimd0 , 10 ),
729
796
.enable = exynos4_clk_ip_lcd0_ctrl ,
730
797
.ctrlbit = (1 << 4 ),
731
- }
798
+ },
799
+ };
800
+
801
+ struct clksrc_clk exynos4_clk_audiocdclk0 = {
802
+ .clk = {
803
+ .name = "audiocdclk" ,
804
+ .rate = 16934400 ,
805
+ },
806
+ };
807
+
808
+ static struct clk * clkset_sclk_audio0_list [] = {
809
+ [0 ] = & exynos4_clk_audiocdclk0 .clk ,
810
+ [1 ] = NULL ,
811
+ [2 ] = & exynos4_clk_sclk_hdmi27m ,
812
+ [3 ] = & exynos4_clk_sclk_usbphy0 ,
813
+ [4 ] = & clk_ext_xtal_mux ,
814
+ [5 ] = & clk_xusbxti ,
815
+ [6 ] = & exynos4_clk_mout_mpll .clk ,
816
+ [7 ] = & exynos4_clk_mout_epll .clk ,
817
+ [8 ] = & exynos4_clk_sclk_vpll .clk ,
818
+ };
819
+
820
+ static struct clksrc_sources exynos4_clkset_sclk_audio0 = {
821
+ .sources = clkset_sclk_audio0_list ,
822
+ .nr_sources = ARRAY_SIZE (clkset_sclk_audio0_list ),
823
+ };
824
+
825
+ static struct clksrc_clk exynos4_clk_sclk_audio0 = {
826
+ .clk = {
827
+ .name = "audio-bus" ,
828
+ .enable = exynos4_clksrc_mask_maudio_ctrl ,
829
+ .ctrlbit = (1 << 0 ),
830
+ },
831
+ .sources = & exynos4_clkset_sclk_audio0 ,
832
+ .reg_src = { .reg = EXYNOS4_CLKSRC_MAUDIO , .shift = 0 , .size = 4 },
833
+ .reg_div = { .reg = EXYNOS4_CLKDIV_MAUDIO , .shift = 0 , .size = 4 },
834
+ };
835
+
836
+ static struct clk * exynos4_clkset_sclk_audss_list [] = {
837
+ & exynos4_clk_mout_audss .clk ,
838
+ & exynos4_clk_audiocdclk0 .clk ,
839
+ & exynos4_clk_sclk_audio0 .clk ,
840
+ };
841
+
842
+ static struct clksrc_sources exynos4_clkset_sclk_audss = {
843
+ .sources = exynos4_clkset_sclk_audss_list ,
844
+ .nr_sources = ARRAY_SIZE (exynos4_clkset_sclk_audss_list ),
845
+ };
846
+
847
+ static struct clksrc_clk exynos4_clk_sclk_audss_i2s = {
848
+ .clk = {
849
+ .name = "i2sclk" ,
850
+ .parent = & exynos4_clk_mout_audss .clk ,
851
+ .enable = exynos4_clk_audss_ctrl ,
852
+ .ctrlbit = (1 << 3 ),
853
+ },
854
+ .sources = & exynos4_clkset_sclk_audss ,
855
+ .reg_src = { .reg = S5P_CLKSRC_AUDSS , .shift = 2 , .size = 2 },
856
+ .reg_div = { .reg = S5P_CLKDIV_AUDSS , .shift = 8 , .size = 4 },
732
857
};
733
858
734
859
static struct clk exynos4_init_clocks_on [] = {
@@ -1102,15 +1227,7 @@ static struct clksrc_clk exynos4_clksrcs[] = {
1102
1227
.sources = & exynos4_clkset_mout_mfc ,
1103
1228
.reg_src = { .reg = EXYNOS4_CLKSRC_MFC , .shift = 8 , .size = 1 },
1104
1229
.reg_div = { .reg = EXYNOS4_CLKDIV_MFC , .shift = 0 , .size = 4 },
1105
- }, {
1106
- .clk = {
1107
- .name = "sclk_dwmmc" ,
1108
- .parent = & exynos4_clk_dout_mmc4 .clk ,
1109
- .enable = exynos4_clksrc_mask_fsys_ctrl ,
1110
- .ctrlbit = (1 << 16 ),
1111
- },
1112
- .reg_div = { .reg = EXYNOS4_CLKDIV_FSYS3 , .shift = 8 , .size = 8 },
1113
- }
1230
+ },
1114
1231
};
1115
1232
1116
1233
static struct clksrc_clk exynos4_clk_sclk_uart0 = {
@@ -1279,6 +1396,14 @@ static struct clksrc_clk exynos4_clk_sclk_spi2 = {
1279
1396
.reg_div = { .reg = EXYNOS4_CLKDIV_PERIL2 , .shift = 8 , .size = 8 },
1280
1397
};
1281
1398
1399
+ static struct clksrc_clk exynos4_clk_sclk_pcm0 = {
1400
+ .clk = {
1401
+ .name = "sclk_pcm" ,
1402
+ .parent = & exynos4_clk_sclk_audio0 .clk ,
1403
+ },
1404
+ .reg_div = { .reg = EXYNOS4_CLKDIV_MAUDIO , .shift = 4 , .size = 8 },
1405
+ };
1406
+
1282
1407
/* Clock initialization code */
1283
1408
static struct clksrc_clk * exynos4_sysclks [] = {
1284
1409
& exynos4_clk_mout_apll ,
@@ -1311,6 +1436,13 @@ static struct clksrc_clk *exynos4_sysclks[] = {
1311
1436
& exynos4_clk_dout_mmc4 ,
1312
1437
& exynos4_clk_mout_mfc0 ,
1313
1438
& exynos4_clk_mout_mfc1 ,
1439
+ & exynos4_clk_audiocdclk0 ,
1440
+ & exynos4_clk_mout_audss ,
1441
+ & exynos4_clk_sclk_audss_bus ,
1442
+ & exynos4_clk_sclk_audss_i2s ,
1443
+ & exynos4_clk_dout_audss_srp ,
1444
+ & exynos4_clk_sclk_audio0 ,
1445
+ & exynos4_clk_sclk_pcm0 ,
1314
1446
};
1315
1447
1316
1448
static struct clk * exynos4_clk_cdev [] = {
@@ -1438,6 +1570,92 @@ static struct clk_ops exynos4_vpll_ops = {
1438
1570
.set_rate = exynos4_vpll_set_rate ,
1439
1571
};
1440
1572
1573
+ static unsigned long exynos4_epll_get_rate (struct clk * clk )
1574
+ {
1575
+ return clk -> rate ;
1576
+ }
1577
+
1578
+ static u32 epll_div [][6 ] = {
1579
+ { 192000000 , 0 , 48 , 3 , 1 , 0 },
1580
+ { 180000000 , 0 , 45 , 3 , 1 , 0 },
1581
+ { 73728000 , 1 , 73 , 3 , 3 , 47710 },
1582
+ { 67737600 , 1 , 90 , 4 , 3 , 20762 },
1583
+ { 49152000 , 0 , 49 , 3 , 3 , 9961 },
1584
+ { 45158400 , 0 , 45 , 3 , 3 , 10381 },
1585
+ { 180633600 , 0 , 45 , 3 , 1 , 10381 },
1586
+ };
1587
+
1588
+ static int exynos4_epll_set_rate (struct clk * clk , unsigned long rate )
1589
+ {
1590
+ unsigned int epll_con , epll_con_k ;
1591
+ unsigned int i ;
1592
+ unsigned int tmp ;
1593
+ unsigned int epll_rate ;
1594
+ unsigned int locktime ;
1595
+ unsigned int lockcnt ;
1596
+
1597
+ /* Return if nothing changed */
1598
+ if (clk -> rate == rate )
1599
+ return 0 ;
1600
+
1601
+ if (clk -> parent )
1602
+ epll_rate = clk_get_rate (clk -> parent );
1603
+ else
1604
+ epll_rate = clk_ext_xtal_mux .rate ;
1605
+
1606
+ if (epll_rate != 24000000 ) {
1607
+ pr_err ("Invalid Clock : recommended clock is 24MHz.\n" );
1608
+ return - EINVAL ;
1609
+ }
1610
+
1611
+
1612
+ epll_con = __raw_readl (EXYNOS4_EPLL_CON0 );
1613
+ epll_con &= ~(0x1 << 27 | \
1614
+ PLL46XX_MDIV_MASK << PLL46XX_MDIV_SHIFT | \
1615
+ PLL46XX_PDIV_MASK << PLL46XX_PDIV_SHIFT | \
1616
+ PLL46XX_SDIV_MASK << PLL46XX_SDIV_SHIFT );
1617
+
1618
+ for (i = 0 ; i < ARRAY_SIZE (epll_div ); i ++ ) {
1619
+ if (epll_div [i ][0 ] == rate ) {
1620
+ epll_con_k = epll_div [i ][5 ] << 0 ;
1621
+ epll_con |= epll_div [i ][1 ] << 27 ;
1622
+ epll_con |= epll_div [i ][2 ] << PLL46XX_MDIV_SHIFT ;
1623
+ epll_con |= epll_div [i ][3 ] << PLL46XX_PDIV_SHIFT ;
1624
+ epll_con |= epll_div [i ][4 ] << PLL46XX_SDIV_SHIFT ;
1625
+ break ;
1626
+ }
1627
+ }
1628
+
1629
+ if (i == ARRAY_SIZE (epll_div )) {
1630
+ pr_err ("%s: Invalid Clock EPLL Frequency\n" , __func__ );
1631
+ return - EINVAL ;
1632
+ }
1633
+
1634
+ epll_rate /= 1000000 ;
1635
+
1636
+ /* 3000 max_cycls : specification data */
1637
+ locktime = 3000 / epll_rate * epll_div [i ][3 ];
1638
+ lockcnt = locktime * 10000 / (10000 / epll_rate );
1639
+
1640
+ __raw_writel (lockcnt , EXYNOS4_EPLL_LOCK );
1641
+
1642
+ __raw_writel (epll_con , EXYNOS4_EPLL_CON0 );
1643
+ __raw_writel (epll_con_k , EXYNOS4_EPLL_CON1 );
1644
+
1645
+ do {
1646
+ tmp = __raw_readl (EXYNOS4_EPLL_CON0 );
1647
+ } while (!(tmp & 0x1 << EXYNOS4_EPLLCON0_LOCKED_SHIFT ));
1648
+
1649
+ clk -> rate = rate ;
1650
+
1651
+ return 0 ;
1652
+ }
1653
+
1654
+ static struct clk_ops exynos4_epll_ops = {
1655
+ .get_rate = exynos4_epll_get_rate ,
1656
+ .set_rate = exynos4_epll_set_rate ,
1657
+ };
1658
+
1441
1659
void __init_or_cpufreq exynos4_setup_clocks (void )
1442
1660
{
1443
1661
struct clk * xtal_clk ;
@@ -1494,6 +1712,7 @@ void __init_or_cpufreq exynos4_setup_clocks(void)
1494
1712
1495
1713
clk_fout_apll .ops = & exynos4_fout_apll_ops ;
1496
1714
clk_fout_mpll .rate = mpll ;
1715
+ clk_fout_epll .ops = & exynos4_epll_ops ;
1497
1716
clk_fout_epll .rate = epll ;
1498
1717
clk_fout_vpll .ops = & exynos4_vpll_ops ;
1499
1718
clk_fout_vpll .rate = vpll ;
@@ -1518,6 +1737,16 @@ void __init_or_cpufreq exynos4_setup_clocks(void)
1518
1737
clk_h .rate = sclk_dmc ;
1519
1738
clk_p .rate = aclk_100 ;
1520
1739
1740
+ clk_set_parent (& exynos4_clk_mout_audss .clk , & clk_fout_epll );
1741
+ clk_set_parent (& exynos4_clk_sclk_audio0 .clk ,
1742
+ & exynos4_clk_mout_epll .clk );
1743
+ clk_set_parent (& exynos4_clk_mout_epll .clk , & clk_fout_epll );
1744
+
1745
+ clk_fout_vpll .enable = exynos4_clk_vpll_ctrl ;
1746
+ clk_fout_vpll .ops = & exynos4_vpll_ops ;
1747
+
1748
+ clk_set_rate (& exynos4_clk_sclk_apll .clk , 100000000 );
1749
+
1521
1750
for (ptr = 0 ; ptr < ARRAY_SIZE (exynos4_clksrcs ); ptr ++ )
1522
1751
s3c_set_clksrc (& exynos4_clksrcs [ptr ], true);
1523
1752
}
@@ -1577,6 +1806,11 @@ void __init exynos4_register_clocks(void)
1577
1806
s3c_disable_clocks (exynos4_init_clocks_off , ARRAY_SIZE (exynos4_init_clocks_off ));
1578
1807
clkdev_add_table (exynos4_clk_lookup , ARRAY_SIZE (exynos4_clk_lookup ));
1579
1808
1809
+ s3c_register_clocks (exynos4_init_audss_clocks ,
1810
+ ARRAY_SIZE (exynos4_init_audss_clocks ));
1811
+ s3c_disable_clocks (exynos4_init_audss_clocks ,
1812
+ ARRAY_SIZE (exynos4_init_audss_clocks ));
1813
+
1580
1814
register_syscore_ops (& exynos4_clock_syscore_ops );
1581
1815
s3c24xx_register_clock (& dummy_apb_pclk );
1582
1816
0 commit comments