50
50
#include <linux/of_dma.h>
51
51
#include <linux/time.h>
52
52
#include <linux/workqueue.h>
53
+ #include <soc/bcm2835/raspberrypi-firmware.h>
53
54
54
55
#define DRIVER_NAME "sdhost-bcm2835"
55
56
@@ -190,6 +191,8 @@ struct bcm2835_host {
190
191
unsigned int use_sbc :1 ; /* Send CMD23 */
191
192
192
193
unsigned int debug :1 ; /* Enable debug output */
194
+ unsigned int firmware_sets_cdiv :1 ; /* Let the firmware manage the clock */
195
+ unsigned int reset_clock :1 ; /* Reset the clock fore the next request */
193
196
194
197
/*DMA part*/
195
198
struct dma_chan * dma_chan_rxtx ; /* DMA channel for reads and writes */
@@ -437,7 +440,7 @@ static void bcm2835_sdhost_reset_internal(struct bcm2835_host *host)
437
440
host -> clock = 0 ;
438
441
host -> sectors = 0 ;
439
442
bcm2835_sdhost_write (host , host -> hcfg , SDHCFG );
440
- bcm2835_sdhost_write (host , host -> cdiv , SDCDIV );
443
+ bcm2835_sdhost_write (host , SDCDIV_MAX_CDIV , SDCDIV );
441
444
mmiowb ();
442
445
}
443
446
@@ -1510,6 +1513,7 @@ void bcm2835_sdhost_set_clock(struct bcm2835_host *host, unsigned int clock)
1510
1513
{
1511
1514
int div = 0 ; /* Initialized for compiler warning */
1512
1515
unsigned int input_clock = clock ;
1516
+ unsigned long flags ;
1513
1517
1514
1518
if (host -> debug )
1515
1519
pr_info ("%s: set_clock(%d)\n" , mmc_hostname (host -> mmc ), clock );
@@ -1541,62 +1545,84 @@ void bcm2835_sdhost_set_clock(struct bcm2835_host *host, unsigned int clock)
1541
1545
1542
1546
host -> mmc -> actual_clock = 0 ;
1543
1547
1544
- if (clock < 100000 ) {
1545
- /* Can't stop the clock, but make it as slow as possible
1546
- * to show willing
1547
- */
1548
- host -> cdiv = SDCDIV_MAX_CDIV ;
1549
- bcm2835_sdhost_write (host , host -> cdiv , SDCDIV );
1550
- return ;
1551
- }
1548
+ if (host -> firmware_sets_cdiv ) {
1549
+ u32 msg [3 ] = { clock , 0 , 0 };
1552
1550
1553
- div = host -> max_clk / clock ;
1554
- if (div < 2 )
1555
- div = 2 ;
1556
- if ((host -> max_clk / div ) > clock )
1557
- div ++ ;
1558
- div -= 2 ;
1551
+ rpi_firmware_property (rpi_firmware_get (NULL ),
1552
+ RPI_FIRMWARE_SET_SDHOST_CLOCK ,
1553
+ & msg , sizeof (msg ));
1559
1554
1560
- if (div > SDCDIV_MAX_CDIV )
1561
- div = SDCDIV_MAX_CDIV ;
1555
+ clock = max (msg [1 ], msg [2 ]);
1556
+ spin_lock_irqsave (& host -> lock , flags );
1557
+ } else {
1558
+ spin_lock_irqsave (& host -> lock , flags );
1559
+ if (clock < 100000 ) {
1560
+ /* Can't stop the clock, but make it as slow as
1561
+ * possible to show willing
1562
+ */
1563
+ host -> cdiv = SDCDIV_MAX_CDIV ;
1564
+ bcm2835_sdhost_write (host , host -> cdiv , SDCDIV );
1565
+ mmiowb ();
1566
+ spin_unlock_irqrestore (& host -> lock , flags );
1567
+ return ;
1568
+ }
1562
1569
1563
- clock = host -> max_clk / (div + 2 );
1564
- host -> mmc -> actual_clock = clock ;
1570
+ div = host -> max_clk / clock ;
1571
+ if (div < 2 )
1572
+ div = 2 ;
1573
+ if ((host -> max_clk / div ) > clock )
1574
+ div ++ ;
1575
+ div -= 2 ;
1576
+
1577
+ if (div > SDCDIV_MAX_CDIV )
1578
+ div = SDCDIV_MAX_CDIV ;
1579
+
1580
+ clock = host -> max_clk / (div + 2 );
1581
+
1582
+ host -> cdiv = div ;
1583
+ bcm2835_sdhost_write (host , host -> cdiv , SDCDIV );
1584
+
1585
+ if (host -> debug )
1586
+ pr_info ("%s: clock=%d -> max_clk=%d, cdiv=%x "
1587
+ "(actual clock %d)\n" ,
1588
+ mmc_hostname (host -> mmc ), input_clock ,
1589
+ host -> max_clk , host -> cdiv ,
1590
+ clock );
1591
+ }
1565
1592
1566
1593
/* Calibrate some delays */
1567
1594
1568
1595
host -> ns_per_fifo_word = (1000000000 /clock ) *
1569
1596
((host -> mmc -> caps & MMC_CAP_4_BIT_DATA ) ? 8 : 32 );
1570
1597
1571
- if (clock > input_clock ) {
1572
- /* Save the closest value, to make it easier
1573
- to reduce in the event of error */
1574
- host -> overclock_50 = (clock /MHZ );
1598
+ if (input_clock == 50 * MHZ ) {
1599
+ if (clock > input_clock ) {
1600
+ /* Save the closest value, to make it easier
1601
+ to reduce in the event of error */
1602
+ host -> overclock_50 = (clock /MHZ );
1575
1603
1576
- if (clock != host -> overclock ) {
1577
- pr_warn ("%s: overclocking to %dHz\n" ,
1578
- mmc_hostname (host -> mmc ), clock );
1579
- host -> overclock = clock ;
1604
+ if (clock != host -> overclock ) {
1605
+ pr_warn ("%s: overclocking to %dHz\n" ,
1606
+ mmc_hostname (host -> mmc ), clock );
1607
+ host -> overclock = clock ;
1608
+ }
1609
+ } else if (host -> overclock ) {
1610
+ host -> overclock = 0 ;
1611
+ if (clock == 50 * MHZ )
1612
+ pr_warn ("%s: cancelling overclock\n" ,
1613
+ mmc_hostname (host -> mmc ));
1580
1614
}
1581
1615
}
1582
- else if (host -> overclock )
1583
- {
1584
- host -> overclock = 0 ;
1585
- if (clock == 50 * MHZ )
1586
- pr_warn ("%s: cancelling overclock\n" ,
1587
- mmc_hostname (host -> mmc ));
1588
- }
1589
-
1590
- host -> cdiv = div ;
1591
- bcm2835_sdhost_write (host , host -> cdiv , SDCDIV );
1592
1616
1593
1617
/* Set the timeout to 500ms */
1594
- bcm2835_sdhost_write (host , host -> mmc -> actual_clock /2 , SDTOUT );
1618
+ bcm2835_sdhost_write (host , clock /2 , SDTOUT );
1595
1619
1596
- if (host -> debug )
1597
- pr_info ("%s: clock=%d -> max_clk=%d, cdiv=%x (actual clock %d)\n" ,
1598
- mmc_hostname (host -> mmc ), input_clock ,
1599
- host -> max_clk , host -> cdiv , host -> mmc -> actual_clock );
1620
+ host -> mmc -> actual_clock = clock ;
1621
+ host -> clock = input_clock ;
1622
+ host -> reset_clock = 0 ;
1623
+
1624
+ mmiowb ();
1625
+ spin_unlock_irqrestore (& host -> lock , flags );
1600
1626
}
1601
1627
1602
1628
static void bcm2835_sdhost_request (struct mmc_host * mmc , struct mmc_request * mrq )
@@ -1645,6 +1671,9 @@ static void bcm2835_sdhost_request(struct mmc_host *mmc, struct mmc_request *mrq
1645
1671
(mrq -> data -> blocks > host -> pio_limit ))
1646
1672
bcm2835_sdhost_prepare_dma (host , mrq -> data );
1647
1673
1674
+ if (host -> reset_clock )
1675
+ bcm2835_sdhost_set_clock (host , host -> clock );
1676
+
1648
1677
spin_lock_irqsave (& host -> lock , flags );
1649
1678
1650
1679
WARN_ON (host -> mrq != NULL );
@@ -1711,11 +1740,6 @@ static void bcm2835_sdhost_set_ios(struct mmc_host *mmc, struct mmc_ios *ios)
1711
1740
1712
1741
log_event ("IOS<" , ios -> clock , 0 );
1713
1742
1714
- if (!ios -> clock || ios -> clock != host -> clock ) {
1715
- bcm2835_sdhost_set_clock (host , ios -> clock );
1716
- host -> clock = ios -> clock ;
1717
- }
1718
-
1719
1743
/* set bus width */
1720
1744
host -> hcfg &= ~SDHCFG_WIDE_EXT_BUS ;
1721
1745
if (ios -> bus_width == MMC_BUS_WIDTH_4 )
@@ -1731,6 +1755,9 @@ static void bcm2835_sdhost_set_ios(struct mmc_host *mmc, struct mmc_ios *ios)
1731
1755
mmiowb ();
1732
1756
1733
1757
spin_unlock_irqrestore (& host -> lock , flags );
1758
+
1759
+ if (!ios -> clock || ios -> clock != host -> clock )
1760
+ bcm2835_sdhost_set_clock (host , ios -> clock );
1734
1761
}
1735
1762
1736
1763
static struct mmc_host_ops bcm2835_sdhost_ops = {
@@ -1802,7 +1829,7 @@ static void bcm2835_sdhost_tasklet_finish(unsigned long param)
1802
1829
host -> overclock_50 -- ;
1803
1830
pr_warn ("%s: reducing overclock due to errors\n" ,
1804
1831
mmc_hostname (host -> mmc ));
1805
- bcm2835_sdhost_set_clock ( host , 50 * MHZ ) ;
1832
+ host -> reset_clock = 1 ;
1806
1833
mrq -> cmd -> error = - EILSEQ ;
1807
1834
mrq -> cmd -> retries = 1 ;
1808
1835
}
@@ -1959,6 +1986,7 @@ static int bcm2835_sdhost_probe(struct platform_device *pdev)
1959
1986
struct resource * iomem ;
1960
1987
struct bcm2835_host * host ;
1961
1988
struct mmc_host * mmc ;
1989
+ u32 msg [3 ];
1962
1990
int ret ;
1963
1991
1964
1992
pr_debug ("bcm2835_sdhost_probe\n" );
@@ -1970,7 +1998,6 @@ static int bcm2835_sdhost_probe(struct platform_device *pdev)
1970
1998
mmc -> ops = & bcm2835_sdhost_ops ;
1971
1999
host = mmc_priv (mmc );
1972
2000
host -> mmc = mmc ;
1973
- host -> cmd_quick_poll_retries = 0 ;
1974
2001
host -> pio_timeout = msecs_to_jiffies (500 );
1975
2002
host -> pio_limit = 1 ;
1976
2003
host -> max_delay = 1 ; /* Warn if over 1ms */
@@ -2059,6 +2086,16 @@ static int bcm2835_sdhost_probe(struct platform_device *pdev)
2059
2086
else
2060
2087
mmc -> caps |= MMC_CAP_4_BIT_DATA ;
2061
2088
2089
+ msg [0 ] = 0 ;
2090
+ msg [1 ] = ~0 ;
2091
+ msg [2 ] = ~0 ;
2092
+
2093
+ rpi_firmware_property (rpi_firmware_get (NULL ),
2094
+ RPI_FIRMWARE_SET_SDHOST_CLOCK ,
2095
+ & msg , sizeof (msg ));
2096
+
2097
+ host -> firmware_sets_cdiv = (msg [1 ] != ~0 );
2098
+
2062
2099
ret = bcm2835_sdhost_add_host (host );
2063
2100
if (ret )
2064
2101
goto err ;
0 commit comments