diff options
-rw-r--r-- | drivers/clk/mxs/Makefile | 2 | ||||
-rw-r--r-- | drivers/clk/mxs/clk-ssp.c | 62 | ||||
-rw-r--r-- | drivers/mmc/host/mxs-mmc.c | 39 | ||||
-rw-r--r-- | include/linux/spi/mxs-spi.h | 2 |
4 files changed, 66 insertions, 39 deletions
diff --git a/drivers/clk/mxs/Makefile b/drivers/clk/mxs/Makefile index 7bedeec0852..a6a22237e86 100644 --- a/drivers/clk/mxs/Makefile +++ b/drivers/clk/mxs/Makefile | |||
@@ -2,7 +2,7 @@ | |||
2 | # Makefile for mxs specific clk | 2 | # Makefile for mxs specific clk |
3 | # | 3 | # |
4 | 4 | ||
5 | obj-y += clk.o clk-pll.o clk-ref.o clk-div.o clk-frac.o | 5 | obj-y += clk.o clk-pll.o clk-ref.o clk-div.o clk-frac.o clk-ssp.o |
6 | 6 | ||
7 | obj-$(CONFIG_SOC_IMX23) += clk-imx23.o | 7 | obj-$(CONFIG_SOC_IMX23) += clk-imx23.o |
8 | obj-$(CONFIG_SOC_IMX28) += clk-imx28.o | 8 | obj-$(CONFIG_SOC_IMX28) += clk-imx28.o |
diff --git a/drivers/clk/mxs/clk-ssp.c b/drivers/clk/mxs/clk-ssp.c new file mode 100644 index 00000000000..af7bdbf9ebd --- /dev/null +++ b/drivers/clk/mxs/clk-ssp.c | |||
@@ -0,0 +1,62 @@ | |||
1 | /* | ||
2 | * Copyright 2012 DENX Software Engineering, GmbH | ||
3 | * | ||
4 | * Pulled from code: | ||
5 | * Portions copyright (C) 2003 Russell King, PXA MMCI Driver | ||
6 | * Portions copyright (C) 2004-2005 Pierre Ossman, W83L51xD SD/MMC driver | ||
7 | * | ||
8 | * Copyright 2008 Embedded Alley Solutions, Inc. | ||
9 | * Copyright 2009-2011 Freescale Semiconductor, Inc. | ||
10 | * | ||
11 | * The code contained herein is licensed under the GNU General Public | ||
12 | * License. You may obtain a copy of the GNU General Public License | ||
13 | * Version 2 or later at the following locations: | ||
14 | * | ||
15 | * http://www.opensource.org/licenses/gpl-license.html | ||
16 | * http://www.gnu.org/copyleft/gpl.html | ||
17 | */ | ||
18 | |||
19 | #include <linux/kernel.h> | ||
20 | #include <linux/init.h> | ||
21 | #include <linux/clk.h> | ||
22 | #include <linux/module.h> | ||
23 | #include <linux/device.h> | ||
24 | #include <linux/io.h> | ||
25 | #include <linux/spi/mxs-spi.h> | ||
26 | |||
27 | void mxs_ssp_set_clk_rate(struct mxs_ssp *ssp, unsigned int rate) | ||
28 | { | ||
29 | unsigned int ssp_clk, ssp_sck; | ||
30 | u32 clock_divide, clock_rate; | ||
31 | u32 val; | ||
32 | |||
33 | ssp_clk = clk_get_rate(ssp->clk); | ||
34 | |||
35 | for (clock_divide = 2; clock_divide <= 254; clock_divide += 2) { | ||
36 | clock_rate = DIV_ROUND_UP(ssp_clk, rate * clock_divide); | ||
37 | clock_rate = (clock_rate > 0) ? clock_rate - 1 : 0; | ||
38 | if (clock_rate <= 255) | ||
39 | break; | ||
40 | } | ||
41 | |||
42 | if (clock_divide > 254) { | ||
43 | dev_err(ssp->dev, | ||
44 | "%s: cannot set clock to %d\n", __func__, rate); | ||
45 | return; | ||
46 | } | ||
47 | |||
48 | ssp_sck = ssp_clk / clock_divide / (1 + clock_rate); | ||
49 | |||
50 | val = readl(ssp->base + HW_SSP_TIMING(ssp)); | ||
51 | val &= ~(BM_SSP_TIMING_CLOCK_DIVIDE | BM_SSP_TIMING_CLOCK_RATE); | ||
52 | val |= BF_SSP(clock_divide, TIMING_CLOCK_DIVIDE); | ||
53 | val |= BF_SSP(clock_rate, TIMING_CLOCK_RATE); | ||
54 | writel(val, ssp->base + HW_SSP_TIMING(ssp)); | ||
55 | |||
56 | ssp->clk_rate = ssp_sck; | ||
57 | |||
58 | dev_dbg(ssp->dev, | ||
59 | "%s: clock_divide %d, clock_rate %d, ssp_clk %d, rate_actual %d, rate_requested %d\n", | ||
60 | __func__, clock_divide, clock_rate, ssp_clk, ssp_sck, rate); | ||
61 | } | ||
62 | EXPORT_SYMBOL_GPL(mxs_ssp_set_clk_rate); | ||
diff --git a/drivers/mmc/host/mxs-mmc.c b/drivers/mmc/host/mxs-mmc.c index 7b85e035a4c..0813340fa29 100644 --- a/drivers/mmc/host/mxs-mmc.c +++ b/drivers/mmc/host/mxs-mmc.c | |||
@@ -501,43 +501,6 @@ static void mxs_mmc_request(struct mmc_host *mmc, struct mmc_request *mrq) | |||
501 | mxs_mmc_start_cmd(host, mrq->cmd); | 501 | mxs_mmc_start_cmd(host, mrq->cmd); |
502 | } | 502 | } |
503 | 503 | ||
504 | static void mxs_mmc_set_clk_rate(struct mxs_mmc_host *host, unsigned int rate) | ||
505 | { | ||
506 | struct mxs_ssp *ssp = &host->ssp; | ||
507 | unsigned int ssp_clk, ssp_sck; | ||
508 | u32 clock_divide, clock_rate; | ||
509 | u32 val; | ||
510 | |||
511 | ssp_clk = clk_get_rate(ssp->clk); | ||
512 | |||
513 | for (clock_divide = 2; clock_divide <= 254; clock_divide += 2) { | ||
514 | clock_rate = DIV_ROUND_UP(ssp_clk, rate * clock_divide); | ||
515 | clock_rate = (clock_rate > 0) ? clock_rate - 1 : 0; | ||
516 | if (clock_rate <= 255) | ||
517 | break; | ||
518 | } | ||
519 | |||
520 | if (clock_divide > 254) { | ||
521 | dev_err(mmc_dev(host->mmc), | ||
522 | "%s: cannot set clock to %d\n", __func__, rate); | ||
523 | return; | ||
524 | } | ||
525 | |||
526 | ssp_sck = ssp_clk / clock_divide / (1 + clock_rate); | ||
527 | |||
528 | val = readl(ssp->base + HW_SSP_TIMING(ssp)); | ||
529 | val &= ~(BM_SSP_TIMING_CLOCK_DIVIDE | BM_SSP_TIMING_CLOCK_RATE); | ||
530 | val |= BF_SSP(clock_divide, TIMING_CLOCK_DIVIDE); | ||
531 | val |= BF_SSP(clock_rate, TIMING_CLOCK_RATE); | ||
532 | writel(val, ssp->base + HW_SSP_TIMING(ssp)); | ||
533 | |||
534 | ssp->clk_rate = ssp_sck; | ||
535 | |||
536 | dev_dbg(mmc_dev(host->mmc), | ||
537 | "%s: clock_divide %d, clock_rate %d, ssp_clk %d, rate_actual %d, rate_requested %d\n", | ||
538 | __func__, clock_divide, clock_rate, ssp_clk, ssp_sck, rate); | ||
539 | } | ||
540 | |||
541 | static void mxs_mmc_set_ios(struct mmc_host *mmc, struct mmc_ios *ios) | 504 | static void mxs_mmc_set_ios(struct mmc_host *mmc, struct mmc_ios *ios) |
542 | { | 505 | { |
543 | struct mxs_mmc_host *host = mmc_priv(mmc); | 506 | struct mxs_mmc_host *host = mmc_priv(mmc); |
@@ -550,7 +513,7 @@ static void mxs_mmc_set_ios(struct mmc_host *mmc, struct mmc_ios *ios) | |||
550 | host->bus_width = 0; | 513 | host->bus_width = 0; |
551 | 514 | ||
552 | if (ios->clock) | 515 | if (ios->clock) |
553 | mxs_mmc_set_clk_rate(host, ios->clock); | 516 | mxs_ssp_set_clk_rate(&host->ssp, ios->clock); |
554 | } | 517 | } |
555 | 518 | ||
556 | static void mxs_mmc_enable_sdio_irq(struct mmc_host *mmc, int enable) | 519 | static void mxs_mmc_enable_sdio_irq(struct mmc_host *mmc, int enable) |
diff --git a/include/linux/spi/mxs-spi.h b/include/linux/spi/mxs-spi.h index 475f69fb896..d07f8dc7fdd 100644 --- a/include/linux/spi/mxs-spi.h +++ b/include/linux/spi/mxs-spi.h | |||
@@ -136,4 +136,6 @@ struct mxs_ssp { | |||
136 | enum mxs_ssp_id devid; | 136 | enum mxs_ssp_id devid; |
137 | }; | 137 | }; |
138 | 138 | ||
139 | void mxs_ssp_set_clk_rate(struct mxs_ssp *ssp, unsigned int rate); | ||
140 | |||
139 | #endif /* __LINUX_SPI_MXS_SPI_H__ */ | 141 | #endif /* __LINUX_SPI_MXS_SPI_H__ */ |