diff options
Diffstat (limited to 'drivers/mmc/host/sdhci.c')
-rw-r--r-- | drivers/mmc/host/sdhci.c | 125 |
1 files changed, 102 insertions, 23 deletions
diff --git a/drivers/mmc/host/sdhci.c b/drivers/mmc/host/sdhci.c index f1a488ee432f..0ad412a4876f 100644 --- a/drivers/mmc/host/sdhci.c +++ b/drivers/mmc/host/sdhci.c | |||
@@ -53,6 +53,9 @@ static void sdhci_finish_command(struct sdhci_host *); | |||
53 | static int sdhci_execute_tuning(struct mmc_host *mmc, u32 opcode); | 53 | static int sdhci_execute_tuning(struct mmc_host *mmc, u32 opcode); |
54 | static void sdhci_tuning_timer(unsigned long data); | 54 | static void sdhci_tuning_timer(unsigned long data); |
55 | static void sdhci_enable_preset_value(struct sdhci_host *host, bool enable); | 55 | static void sdhci_enable_preset_value(struct sdhci_host *host, bool enable); |
56 | static int sdhci_pre_dma_transfer(struct sdhci_host *host, | ||
57 | struct mmc_data *data, | ||
58 | struct sdhci_host_next *next); | ||
56 | 59 | ||
57 | #ifdef CONFIG_PM | 60 | #ifdef CONFIG_PM |
58 | static int sdhci_runtime_pm_get(struct sdhci_host *host); | 61 | static int sdhci_runtime_pm_get(struct sdhci_host *host); |
@@ -505,9 +508,8 @@ static int sdhci_adma_table_pre(struct sdhci_host *host, | |||
505 | goto fail; | 508 | goto fail; |
506 | BUG_ON(host->align_addr & host->align_mask); | 509 | BUG_ON(host->align_addr & host->align_mask); |
507 | 510 | ||
508 | host->sg_count = dma_map_sg(mmc_dev(host->mmc), | 511 | host->sg_count = sdhci_pre_dma_transfer(host, data, NULL); |
509 | data->sg, data->sg_len, direction); | 512 | if (host->sg_count < 0) |
510 | if (host->sg_count == 0) | ||
511 | goto unmap_align; | 513 | goto unmap_align; |
512 | 514 | ||
513 | desc = host->adma_table; | 515 | desc = host->adma_table; |
@@ -531,8 +533,6 @@ static int sdhci_adma_table_pre(struct sdhci_host *host, | |||
531 | if (offset) { | 533 | if (offset) { |
532 | if (data->flags & MMC_DATA_WRITE) { | 534 | if (data->flags & MMC_DATA_WRITE) { |
533 | buffer = sdhci_kmap_atomic(sg, &flags); | 535 | buffer = sdhci_kmap_atomic(sg, &flags); |
534 | WARN_ON(((long)buffer & (PAGE_SIZE - 1)) > | ||
535 | (PAGE_SIZE - offset)); | ||
536 | memcpy(align, buffer, offset); | 536 | memcpy(align, buffer, offset); |
537 | sdhci_kunmap_atomic(buffer, &flags); | 537 | sdhci_kunmap_atomic(buffer, &flags); |
538 | } | 538 | } |
@@ -639,8 +639,6 @@ static void sdhci_adma_table_post(struct sdhci_host *host, | |||
639 | (sg_dma_address(sg) & host->align_mask); | 639 | (sg_dma_address(sg) & host->align_mask); |
640 | 640 | ||
641 | buffer = sdhci_kmap_atomic(sg, &flags); | 641 | buffer = sdhci_kmap_atomic(sg, &flags); |
642 | WARN_ON(((long)buffer & (PAGE_SIZE - 1)) > | ||
643 | (PAGE_SIZE - size)); | ||
644 | memcpy(buffer, align, size); | 642 | memcpy(buffer, align, size); |
645 | sdhci_kunmap_atomic(buffer, &flags); | 643 | sdhci_kunmap_atomic(buffer, &flags); |
646 | 644 | ||
@@ -649,8 +647,9 @@ static void sdhci_adma_table_post(struct sdhci_host *host, | |||
649 | } | 647 | } |
650 | } | 648 | } |
651 | 649 | ||
652 | dma_unmap_sg(mmc_dev(host->mmc), data->sg, | 650 | if (!data->host_cookie) |
653 | data->sg_len, direction); | 651 | dma_unmap_sg(mmc_dev(host->mmc), data->sg, |
652 | data->sg_len, direction); | ||
654 | } | 653 | } |
655 | 654 | ||
656 | static u8 sdhci_calc_timeout(struct sdhci_host *host, struct mmc_command *cmd) | 655 | static u8 sdhci_calc_timeout(struct sdhci_host *host, struct mmc_command *cmd) |
@@ -846,11 +845,7 @@ static void sdhci_prepare_data(struct sdhci_host *host, struct mmc_command *cmd) | |||
846 | } else { | 845 | } else { |
847 | int sg_cnt; | 846 | int sg_cnt; |
848 | 847 | ||
849 | sg_cnt = dma_map_sg(mmc_dev(host->mmc), | 848 | sg_cnt = sdhci_pre_dma_transfer(host, data, NULL); |
850 | data->sg, data->sg_len, | ||
851 | (data->flags & MMC_DATA_READ) ? | ||
852 | DMA_FROM_DEVICE : | ||
853 | DMA_TO_DEVICE); | ||
854 | if (sg_cnt == 0) { | 849 | if (sg_cnt == 0) { |
855 | /* | 850 | /* |
856 | * This only happens when someone fed | 851 | * This only happens when someone fed |
@@ -909,7 +904,7 @@ static void sdhci_prepare_data(struct sdhci_host *host, struct mmc_command *cmd) | |||
909 | static void sdhci_set_transfer_mode(struct sdhci_host *host, | 904 | static void sdhci_set_transfer_mode(struct sdhci_host *host, |
910 | struct mmc_command *cmd) | 905 | struct mmc_command *cmd) |
911 | { | 906 | { |
912 | u16 mode; | 907 | u16 mode = 0; |
913 | struct mmc_data *data = cmd->data; | 908 | struct mmc_data *data = cmd->data; |
914 | 909 | ||
915 | if (data == NULL) { | 910 | if (data == NULL) { |
@@ -927,9 +922,11 @@ static void sdhci_set_transfer_mode(struct sdhci_host *host, | |||
927 | 922 | ||
928 | WARN_ON(!host->data); | 923 | WARN_ON(!host->data); |
929 | 924 | ||
930 | mode = SDHCI_TRNS_BLK_CNT_EN; | 925 | if (!(host->quirks2 & SDHCI_QUIRK2_SUPPORT_SINGLE)) |
926 | mode = SDHCI_TRNS_BLK_CNT_EN; | ||
927 | |||
931 | if (mmc_op_multi(cmd->opcode) || data->blocks > 1) { | 928 | if (mmc_op_multi(cmd->opcode) || data->blocks > 1) { |
932 | mode |= SDHCI_TRNS_MULTI; | 929 | mode = SDHCI_TRNS_BLK_CNT_EN | SDHCI_TRNS_MULTI; |
933 | /* | 930 | /* |
934 | * If we are sending CMD23, CMD12 never gets sent | 931 | * If we are sending CMD23, CMD12 never gets sent |
935 | * on successful completion (so no Auto-CMD12). | 932 | * on successful completion (so no Auto-CMD12). |
@@ -963,8 +960,10 @@ static void sdhci_finish_data(struct sdhci_host *host) | |||
963 | if (host->flags & SDHCI_USE_ADMA) | 960 | if (host->flags & SDHCI_USE_ADMA) |
964 | sdhci_adma_table_post(host, data); | 961 | sdhci_adma_table_post(host, data); |
965 | else { | 962 | else { |
966 | dma_unmap_sg(mmc_dev(host->mmc), data->sg, | 963 | if (!data->host_cookie) |
967 | data->sg_len, (data->flags & MMC_DATA_READ) ? | 964 | dma_unmap_sg(mmc_dev(host->mmc), |
965 | data->sg, data->sg_len, | ||
966 | (data->flags & MMC_DATA_READ) ? | ||
968 | DMA_FROM_DEVICE : DMA_TO_DEVICE); | 967 | DMA_FROM_DEVICE : DMA_TO_DEVICE); |
969 | } | 968 | } |
970 | } | 969 | } |
@@ -1630,7 +1629,7 @@ static void sdhci_do_set_ios(struct sdhci_host *host, struct mmc_ios *ios) | |||
1630 | * signalling timeout and CRC errors even on CMD0. Resetting | 1629 | * signalling timeout and CRC errors even on CMD0. Resetting |
1631 | * it on each ios seems to solve the problem. | 1630 | * it on each ios seems to solve the problem. |
1632 | */ | 1631 | */ |
1633 | if(host->quirks & SDHCI_QUIRK_RESET_CMD_DATA_ON_IOS) | 1632 | if (host->quirks & SDHCI_QUIRK_RESET_CMD_DATA_ON_IOS) |
1634 | sdhci_do_reset(host, SDHCI_RESET_CMD | SDHCI_RESET_DATA); | 1633 | sdhci_do_reset(host, SDHCI_RESET_CMD | SDHCI_RESET_DATA); |
1635 | 1634 | ||
1636 | mmiowb(); | 1635 | mmiowb(); |
@@ -1832,6 +1831,10 @@ static int sdhci_do_start_signal_voltage_switch(struct sdhci_host *host, | |||
1832 | ctrl |= SDHCI_CTRL_VDD_180; | 1831 | ctrl |= SDHCI_CTRL_VDD_180; |
1833 | sdhci_writew(host, ctrl, SDHCI_HOST_CONTROL2); | 1832 | sdhci_writew(host, ctrl, SDHCI_HOST_CONTROL2); |
1834 | 1833 | ||
1834 | /* Some controller need to do more when switching */ | ||
1835 | if (host->ops->voltage_switch) | ||
1836 | host->ops->voltage_switch(host); | ||
1837 | |||
1835 | /* 1.8V regulator output should be stable within 5 ms */ | 1838 | /* 1.8V regulator output should be stable within 5 ms */ |
1836 | ctrl = sdhci_readw(host, SDHCI_HOST_CONTROL2); | 1839 | ctrl = sdhci_readw(host, SDHCI_HOST_CONTROL2); |
1837 | if (ctrl & SDHCI_CTRL_VDD_180) | 1840 | if (ctrl & SDHCI_CTRL_VDD_180) |
@@ -1960,6 +1963,8 @@ static int sdhci_execute_tuning(struct mmc_host *mmc, u32 opcode) | |||
1960 | 1963 | ||
1961 | ctrl = sdhci_readw(host, SDHCI_HOST_CONTROL2); | 1964 | ctrl = sdhci_readw(host, SDHCI_HOST_CONTROL2); |
1962 | ctrl |= SDHCI_CTRL_EXEC_TUNING; | 1965 | ctrl |= SDHCI_CTRL_EXEC_TUNING; |
1966 | if (host->quirks2 & SDHCI_QUIRK2_TUNING_WORK_AROUND) | ||
1967 | ctrl |= SDHCI_CTRL_TUNED_CLK; | ||
1963 | sdhci_writew(host, ctrl, SDHCI_HOST_CONTROL2); | 1968 | sdhci_writew(host, ctrl, SDHCI_HOST_CONTROL2); |
1964 | 1969 | ||
1965 | /* | 1970 | /* |
@@ -2129,6 +2134,77 @@ static void sdhci_enable_preset_value(struct sdhci_host *host, bool enable) | |||
2129 | } | 2134 | } |
2130 | } | 2135 | } |
2131 | 2136 | ||
2137 | static void sdhci_post_req(struct mmc_host *mmc, struct mmc_request *mrq, | ||
2138 | int err) | ||
2139 | { | ||
2140 | struct sdhci_host *host = mmc_priv(mmc); | ||
2141 | struct mmc_data *data = mrq->data; | ||
2142 | |||
2143 | if (host->flags & SDHCI_REQ_USE_DMA) { | ||
2144 | if (data->host_cookie) | ||
2145 | dma_unmap_sg(mmc_dev(host->mmc), data->sg, data->sg_len, | ||
2146 | data->flags & MMC_DATA_WRITE ? | ||
2147 | DMA_TO_DEVICE : DMA_FROM_DEVICE); | ||
2148 | mrq->data->host_cookie = 0; | ||
2149 | } | ||
2150 | } | ||
2151 | |||
2152 | static int sdhci_pre_dma_transfer(struct sdhci_host *host, | ||
2153 | struct mmc_data *data, | ||
2154 | struct sdhci_host_next *next) | ||
2155 | { | ||
2156 | int sg_count; | ||
2157 | |||
2158 | if (!next && data->host_cookie && | ||
2159 | data->host_cookie != host->next_data.cookie) { | ||
2160 | pr_debug(DRIVER_NAME "[%s] invalid cookie: %d, next-cookie %d\n", | ||
2161 | __func__, data->host_cookie, host->next_data.cookie); | ||
2162 | data->host_cookie = 0; | ||
2163 | } | ||
2164 | |||
2165 | /* Check if next job is already prepared */ | ||
2166 | if (next || | ||
2167 | (!next && data->host_cookie != host->next_data.cookie)) { | ||
2168 | sg_count = dma_map_sg(mmc_dev(host->mmc), data->sg, | ||
2169 | data->sg_len, | ||
2170 | data->flags & MMC_DATA_WRITE ? | ||
2171 | DMA_TO_DEVICE : DMA_FROM_DEVICE); | ||
2172 | |||
2173 | } else { | ||
2174 | sg_count = host->next_data.sg_count; | ||
2175 | host->next_data.sg_count = 0; | ||
2176 | } | ||
2177 | |||
2178 | |||
2179 | if (sg_count == 0) | ||
2180 | return -EINVAL; | ||
2181 | |||
2182 | if (next) { | ||
2183 | next->sg_count = sg_count; | ||
2184 | data->host_cookie = ++next->cookie < 0 ? 1 : next->cookie; | ||
2185 | } else | ||
2186 | host->sg_count = sg_count; | ||
2187 | |||
2188 | return sg_count; | ||
2189 | } | ||
2190 | |||
2191 | static void sdhci_pre_req(struct mmc_host *mmc, struct mmc_request *mrq, | ||
2192 | bool is_first_req) | ||
2193 | { | ||
2194 | struct sdhci_host *host = mmc_priv(mmc); | ||
2195 | |||
2196 | if (mrq->data->host_cookie) { | ||
2197 | mrq->data->host_cookie = 0; | ||
2198 | return; | ||
2199 | } | ||
2200 | |||
2201 | if (host->flags & SDHCI_REQ_USE_DMA) | ||
2202 | if (sdhci_pre_dma_transfer(host, | ||
2203 | mrq->data, | ||
2204 | &host->next_data) < 0) | ||
2205 | mrq->data->host_cookie = 0; | ||
2206 | } | ||
2207 | |||
2132 | static void sdhci_card_event(struct mmc_host *mmc) | 2208 | static void sdhci_card_event(struct mmc_host *mmc) |
2133 | { | 2209 | { |
2134 | struct sdhci_host *host = mmc_priv(mmc); | 2210 | struct sdhci_host *host = mmc_priv(mmc); |
@@ -2162,6 +2238,8 @@ static void sdhci_card_event(struct mmc_host *mmc) | |||
2162 | 2238 | ||
2163 | static const struct mmc_host_ops sdhci_ops = { | 2239 | static const struct mmc_host_ops sdhci_ops = { |
2164 | .request = sdhci_request, | 2240 | .request = sdhci_request, |
2241 | .post_req = sdhci_post_req, | ||
2242 | .pre_req = sdhci_pre_req, | ||
2165 | .set_ios = sdhci_set_ios, | 2243 | .set_ios = sdhci_set_ios, |
2166 | .get_cd = sdhci_get_cd, | 2244 | .get_cd = sdhci_get_cd, |
2167 | .get_ro = sdhci_get_ro, | 2245 | .get_ro = sdhci_get_ro, |
@@ -2793,9 +2871,9 @@ int sdhci_runtime_resume_host(struct sdhci_host *host) | |||
2793 | /* Force clock and power re-program */ | 2871 | /* Force clock and power re-program */ |
2794 | host->pwr = 0; | 2872 | host->pwr = 0; |
2795 | host->clock = 0; | 2873 | host->clock = 0; |
2874 | sdhci_do_start_signal_voltage_switch(host, &host->mmc->ios); | ||
2796 | sdhci_do_set_ios(host, &host->mmc->ios); | 2875 | sdhci_do_set_ios(host, &host->mmc->ios); |
2797 | 2876 | ||
2798 | sdhci_do_start_signal_voltage_switch(host, &host->mmc->ios); | ||
2799 | if ((host_flags & SDHCI_PV_ENABLED) && | 2877 | if ((host_flags & SDHCI_PV_ENABLED) && |
2800 | !(host->quirks2 & SDHCI_QUIRK2_PRESET_VALUE_BROKEN)) { | 2878 | !(host->quirks2 & SDHCI_QUIRK2_PRESET_VALUE_BROKEN)) { |
2801 | spin_lock_irqsave(&host->lock, flags); | 2879 | spin_lock_irqsave(&host->lock, flags); |
@@ -3019,6 +3097,7 @@ int sdhci_add_host(struct sdhci_host *host) | |||
3019 | host->max_clk = host->ops->get_max_clock(host); | 3097 | host->max_clk = host->ops->get_max_clock(host); |
3020 | } | 3098 | } |
3021 | 3099 | ||
3100 | host->next_data.cookie = 1; | ||
3022 | /* | 3101 | /* |
3023 | * In case of Host Controller v3.00, find out whether clock | 3102 | * In case of Host Controller v3.00, find out whether clock |
3024 | * multiplier is supported. | 3103 | * multiplier is supported. |
@@ -3338,9 +3417,9 @@ int sdhci_add_host(struct sdhci_host *host) | |||
3338 | 3417 | ||
3339 | setup_timer(&host->timer, sdhci_timeout_timer, (unsigned long)host); | 3418 | setup_timer(&host->timer, sdhci_timeout_timer, (unsigned long)host); |
3340 | 3419 | ||
3341 | if (host->version >= SDHCI_SPEC_300) { | 3420 | init_waitqueue_head(&host->buf_ready_int); |
3342 | init_waitqueue_head(&host->buf_ready_int); | ||
3343 | 3421 | ||
3422 | if (host->version >= SDHCI_SPEC_300) { | ||
3344 | /* Initialize re-tuning timer */ | 3423 | /* Initialize re-tuning timer */ |
3345 | init_timer(&host->tuning_timer); | 3424 | init_timer(&host->tuning_timer); |
3346 | host->tuning_timer.data = (unsigned long)host; | 3425 | host->tuning_timer.data = (unsigned long)host; |