aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/mmc/host/sunxi-mmc.c
diff options
context:
space:
mode:
Diffstat (limited to 'drivers/mmc/host/sunxi-mmc.c')
-rw-r--r--drivers/mmc/host/sunxi-mmc.c63
1 files changed, 48 insertions, 15 deletions
diff --git a/drivers/mmc/host/sunxi-mmc.c b/drivers/mmc/host/sunxi-mmc.c
index 6af0a28ba37d..e8a4218b5726 100644
--- a/drivers/mmc/host/sunxi-mmc.c
+++ b/drivers/mmc/host/sunxi-mmc.c
@@ -21,8 +21,6 @@
21#include <linux/err.h> 21#include <linux/err.h>
22 22
23#include <linux/clk.h> 23#include <linux/clk.h>
24#include <linux/clk/sunxi.h>
25
26#include <linux/gpio.h> 24#include <linux/gpio.h>
27#include <linux/platform_device.h> 25#include <linux/platform_device.h>
28#include <linux/spinlock.h> 26#include <linux/spinlock.h>
@@ -229,6 +227,8 @@ struct sunxi_mmc_host {
229 /* clock management */ 227 /* clock management */
230 struct clk *clk_ahb; 228 struct clk *clk_ahb;
231 struct clk *clk_mmc; 229 struct clk *clk_mmc;
230 struct clk *clk_sample;
231 struct clk *clk_output;
232 232
233 /* irq */ 233 /* irq */
234 spinlock_t lock; 234 spinlock_t lock;
@@ -653,26 +653,31 @@ static int sunxi_mmc_clk_set_rate(struct sunxi_mmc_host *host,
653 653
654 /* determine delays */ 654 /* determine delays */
655 if (rate <= 400000) { 655 if (rate <= 400000) {
656 oclk_dly = 0; 656 oclk_dly = 180;
657 sclk_dly = 7; 657 sclk_dly = 42;
658 } else if (rate <= 25000000) { 658 } else if (rate <= 25000000) {
659 oclk_dly = 0; 659 oclk_dly = 180;
660 sclk_dly = 5; 660 sclk_dly = 75;
661 } else if (rate <= 50000000) { 661 } else if (rate <= 50000000) {
662 if (ios->timing == MMC_TIMING_UHS_DDR50) { 662 if (ios->timing == MMC_TIMING_UHS_DDR50) {
663 oclk_dly = 2; 663 oclk_dly = 60;
664 sclk_dly = 4; 664 sclk_dly = 120;
665 } else { 665 } else {
666 oclk_dly = 3; 666 oclk_dly = 90;
667 sclk_dly = 5; 667 sclk_dly = 150;
668 } 668 }
669 } else if (rate <= 100000000) {
670 oclk_dly = 6;
671 sclk_dly = 24;
672 } else if (rate <= 200000000) {
673 oclk_dly = 3;
674 sclk_dly = 12;
669 } else { 675 } else {
670 /* rate > 50000000 */ 676 return -EINVAL;
671 oclk_dly = 2;
672 sclk_dly = 4;
673 } 677 }
674 678
675 clk_sunxi_mmc_phase_control(host->clk_mmc, sclk_dly, oclk_dly); 679 clk_set_phase(host->clk_sample, sclk_dly);
680 clk_set_phase(host->clk_output, oclk_dly);
676 681
677 return sunxi_mmc_oclk_onoff(host, 1); 682 return sunxi_mmc_oclk_onoff(host, 1);
678} 683}
@@ -913,6 +918,18 @@ static int sunxi_mmc_resource_request(struct sunxi_mmc_host *host,
913 return PTR_ERR(host->clk_mmc); 918 return PTR_ERR(host->clk_mmc);
914 } 919 }
915 920
921 host->clk_output = devm_clk_get(&pdev->dev, "output");
922 if (IS_ERR(host->clk_output)) {
923 dev_err(&pdev->dev, "Could not get output clock\n");
924 return PTR_ERR(host->clk_output);
925 }
926
927 host->clk_sample = devm_clk_get(&pdev->dev, "sample");
928 if (IS_ERR(host->clk_sample)) {
929 dev_err(&pdev->dev, "Could not get sample clock\n");
930 return PTR_ERR(host->clk_sample);
931 }
932
916 host->reset = devm_reset_control_get(&pdev->dev, "ahb"); 933 host->reset = devm_reset_control_get(&pdev->dev, "ahb");
917 934
918 ret = clk_prepare_enable(host->clk_ahb); 935 ret = clk_prepare_enable(host->clk_ahb);
@@ -927,11 +944,23 @@ static int sunxi_mmc_resource_request(struct sunxi_mmc_host *host,
927 goto error_disable_clk_ahb; 944 goto error_disable_clk_ahb;
928 } 945 }
929 946
947 ret = clk_prepare_enable(host->clk_output);
948 if (ret) {
949 dev_err(&pdev->dev, "Enable output clk err %d\n", ret);
950 goto error_disable_clk_mmc;
951 }
952
953 ret = clk_prepare_enable(host->clk_sample);
954 if (ret) {
955 dev_err(&pdev->dev, "Enable sample clk err %d\n", ret);
956 goto error_disable_clk_output;
957 }
958
930 if (!IS_ERR(host->reset)) { 959 if (!IS_ERR(host->reset)) {
931 ret = reset_control_deassert(host->reset); 960 ret = reset_control_deassert(host->reset);
932 if (ret) { 961 if (ret) {
933 dev_err(&pdev->dev, "reset err %d\n", ret); 962 dev_err(&pdev->dev, "reset err %d\n", ret);
934 goto error_disable_clk_mmc; 963 goto error_disable_clk_sample;
935 } 964 }
936 } 965 }
937 966
@@ -950,6 +979,10 @@ static int sunxi_mmc_resource_request(struct sunxi_mmc_host *host,
950error_assert_reset: 979error_assert_reset:
951 if (!IS_ERR(host->reset)) 980 if (!IS_ERR(host->reset))
952 reset_control_assert(host->reset); 981 reset_control_assert(host->reset);
982error_disable_clk_sample:
983 clk_disable_unprepare(host->clk_sample);
984error_disable_clk_output:
985 clk_disable_unprepare(host->clk_output);
953error_disable_clk_mmc: 986error_disable_clk_mmc:
954 clk_disable_unprepare(host->clk_mmc); 987 clk_disable_unprepare(host->clk_mmc);
955error_disable_clk_ahb: 988error_disable_clk_ahb: