summaryrefslogtreecommitdiff
path: root/drivers
diff options
context:
space:
mode:
authorPhil Elwell <phil@raspberrypi.org>2015-05-14 11:48:40 +0100
committerpopcornmix <popcornmix@gmail.com>2015-05-18 14:13:22 +0100
commit628d654d5aa2d845926402a1b83fa2822a83cee7 (patch)
treee56c6f94d264812029a9914cd003ba026d052332 /drivers
parent6e2339c634adc32971915ec4e4daf24f99398f8d (diff)
downloadlinux-628d654d5aa2d845926402a1b83fa2822a83cee7.tar.gz
bcm2835-sdhost: Adding overclocking option
Allow a different clock speed to be substitued for a requested 50MHz. This option is exposed using the "overclock_50" DT parameter. Note that the sdhost interface is restricted to integer divisions of core_freq, and the highest sensible option for a core_freq of 250MHz is 84 (250/3 = 83.3MHz), the next being 125 (250/2) which is much too high. Use at your own risk.
Diffstat (limited to 'drivers')
-rw-r--r--drivers/mmc/host/bcm2835-sdhost.c17
1 files changed, 15 insertions, 2 deletions
diff --git a/drivers/mmc/host/bcm2835-sdhost.c b/drivers/mmc/host/bcm2835-sdhost.c
index 542ae120b812..2a9eb9f7f87d 100644
--- a/drivers/mmc/host/bcm2835-sdhost.c
+++ b/drivers/mmc/host/bcm2835-sdhost.c
@@ -184,6 +184,7 @@ struct bcm2835_host {
int max_delay; /* maximum length of time spent waiting */
struct timeval stop_time; /* when the last stop was issued */
u32 delay_after_stop; /* minimum time between stop and subsequent data transfer */
+ u32 overclock_50; /* frequency to use when 50MHz is requested (in MHz) */
};
@@ -1223,6 +1224,10 @@ static irqreturn_t bcm2835_sdhost_thread_irq(int irq, void *dev_id)
void bcm2835_sdhost_set_clock(struct bcm2835_host *host, unsigned int clock)
{
int div = 0; /* Initialized for compiler warning */
+ unsigned int input_clock = clock;
+
+ if (host->overclock_50 && (clock == 50000000))
+ clock = host->overclock_50 * 1000000;
/* The SDCDIV register has 11 bits, and holds (div - 2).
But in data mode the max is 50MHz wihout a minimum, and only the
@@ -1266,13 +1271,18 @@ void bcm2835_sdhost_set_clock(struct bcm2835_host *host, unsigned int clock)
if (div > SDCDIV_MAX_CDIV)
div = SDCDIV_MAX_CDIV;
- host->mmc->actual_clock = host->max_clk / (div + 2);
+ clock = host->max_clk / (div + 2);
+ host->mmc->actual_clock = clock;
+
+ if (clock > input_clock)
+ pr_warn("%s: Overclocking to %dHz\n",
+ mmc_hostname(host->mmc), clock);
host->cdiv = div;
bcm2835_sdhost_write(host, host->cdiv, SDCDIV);
pr_debug(DRIVER_NAME ": clock=%d -> max_clk=%d, cdiv=%x (actual clock %d)\n",
- clock, host->max_clk, host->cdiv, host->mmc->actual_clock);
+ input_clock, host->max_clk, host->cdiv, host->mmc->actual_clock);
}
static void bcm2835_sdhost_request(struct mmc_host *mmc, struct mmc_request *mrq)
@@ -1572,6 +1582,9 @@ static int bcm2835_sdhost_probe(struct platform_device *pdev)
of_property_read_u32(node,
"brcm,delay-after-stop",
&host->delay_after_stop);
+ of_property_read_u32(node,
+ "brcm,overclock-50",
+ &host->overclock_50);
host->allow_dma = ALLOW_DMA &&
!of_property_read_bool(node, "brcm,force-pio");
}