| .. | .. |
|---|
| 1 | +// SPDX-License-Identifier: GPL-2.0 |
|---|
| 1 | 2 | /* |
|---|
| 2 | 3 | * DMA support use of SYS DMAC with SDHI SD/SDIO controller |
|---|
| 3 | 4 | * |
|---|
| 4 | | - * Copyright (C) 2016-17 Renesas Electronics Corporation |
|---|
| 5 | | - * Copyright (C) 2016-17 Sang Engineering, Wolfram Sang |
|---|
| 5 | + * Copyright (C) 2016-19 Renesas Electronics Corporation |
|---|
| 6 | + * Copyright (C) 2016-19 Sang Engineering, Wolfram Sang |
|---|
| 6 | 7 | * Copyright (C) 2017 Horms Solutions, Simon Horman |
|---|
| 7 | 8 | * Copyright (C) 2010-2011 Guennadi Liakhovetski |
|---|
| 8 | | - * |
|---|
| 9 | | - * This program is free software; you can redistribute it and/or modify |
|---|
| 10 | | - * it under the terms of the GNU General Public License version 2 as |
|---|
| 11 | | - * published by the Free Software Foundation. |
|---|
| 12 | 9 | */ |
|---|
| 13 | 10 | |
|---|
| 14 | 11 | #include <linux/device.h> |
|---|
| .. | .. |
|---|
| 68 | 65 | .scc_offset = 0x0300, |
|---|
| 69 | 66 | .taps = rcar_gen2_scc_taps, |
|---|
| 70 | 67 | .taps_num = ARRAY_SIZE(rcar_gen2_scc_taps), |
|---|
| 71 | | - .max_blk_count = 0xffffffff, |
|---|
| 72 | | -}; |
|---|
| 73 | | - |
|---|
| 74 | | -/* Definitions for sampling clocks */ |
|---|
| 75 | | -static struct renesas_sdhi_scc rcar_gen3_scc_taps[] = { |
|---|
| 76 | | - { |
|---|
| 77 | | - .clk_rate = 0, |
|---|
| 78 | | - .tap = 0x00000300, |
|---|
| 79 | | - }, |
|---|
| 80 | | -}; |
|---|
| 81 | | - |
|---|
| 82 | | -static const struct renesas_sdhi_of_data of_rcar_r8a7795_compatible = { |
|---|
| 83 | | - .tmio_flags = TMIO_MMC_HAS_IDLE_WAIT | TMIO_MMC_CLK_ACTUAL | |
|---|
| 84 | | - TMIO_MMC_HAVE_CBSY | TMIO_MMC_MIN_RCAR2 | |
|---|
| 85 | | - TMIO_MMC_HAVE_4TAP_HS400, |
|---|
| 86 | | - .capabilities = MMC_CAP_SD_HIGHSPEED | MMC_CAP_SDIO_IRQ | |
|---|
| 87 | | - MMC_CAP_CMD23, |
|---|
| 88 | | - .capabilities2 = MMC_CAP2_NO_WRITE_PROTECT, |
|---|
| 89 | | - .bus_shift = 2, |
|---|
| 90 | | - .scc_offset = 0x1000, |
|---|
| 91 | | - .taps = rcar_gen3_scc_taps, |
|---|
| 92 | | - .taps_num = ARRAY_SIZE(rcar_gen3_scc_taps), |
|---|
| 93 | | -}; |
|---|
| 94 | | - |
|---|
| 95 | | -static const struct renesas_sdhi_of_data of_rcar_gen3_compatible = { |
|---|
| 96 | | - .tmio_flags = TMIO_MMC_HAS_IDLE_WAIT | TMIO_MMC_CLK_ACTUAL | |
|---|
| 97 | | - TMIO_MMC_HAVE_CBSY | TMIO_MMC_MIN_RCAR2, |
|---|
| 98 | | - .capabilities = MMC_CAP_SD_HIGHSPEED | MMC_CAP_SDIO_IRQ | |
|---|
| 99 | | - MMC_CAP_CMD23, |
|---|
| 100 | | - .capabilities2 = MMC_CAP2_NO_WRITE_PROTECT, |
|---|
| 101 | | - .bus_shift = 2, |
|---|
| 102 | | - .scc_offset = 0x1000, |
|---|
| 103 | | - .taps = rcar_gen3_scc_taps, |
|---|
| 104 | | - .taps_num = ARRAY_SIZE(rcar_gen3_scc_taps), |
|---|
| 68 | + .max_blk_count = UINT_MAX / TMIO_MAX_BLK_SIZE, |
|---|
| 105 | 69 | }; |
|---|
| 106 | 70 | |
|---|
| 107 | 71 | static const struct of_device_id renesas_sdhi_sys_dmac_of_match[] = { |
|---|
| .. | .. |
|---|
| 118 | 82 | { .compatible = "renesas,sdhi-r8a7792", .data = &of_rcar_gen2_compatible, }, |
|---|
| 119 | 83 | { .compatible = "renesas,sdhi-r8a7793", .data = &of_rcar_gen2_compatible, }, |
|---|
| 120 | 84 | { .compatible = "renesas,sdhi-r8a7794", .data = &of_rcar_gen2_compatible, }, |
|---|
| 121 | | - { .compatible = "renesas,sdhi-r8a7795", .data = &of_rcar_r8a7795_compatible, }, |
|---|
| 122 | | - { .compatible = "renesas,sdhi-r8a7796", .data = &of_rcar_r8a7795_compatible, }, |
|---|
| 123 | 85 | { .compatible = "renesas,rcar-gen1-sdhi", .data = &of_rcar_gen1_compatible, }, |
|---|
| 124 | 86 | { .compatible = "renesas,rcar-gen2-sdhi", .data = &of_rcar_gen2_compatible, }, |
|---|
| 125 | | - { .compatible = "renesas,rcar-gen3-sdhi", .data = &of_rcar_gen3_compatible, }, |
|---|
| 126 | 87 | { .compatible = "renesas,sdhi-shmobile" }, |
|---|
| 127 | 88 | {}, |
|---|
| 128 | 89 | }; |
|---|
| .. | .. |
|---|
| 214 | 175 | goto pio; |
|---|
| 215 | 176 | } |
|---|
| 216 | 177 | |
|---|
| 217 | | - if (sg->length < TMIO_MMC_MIN_DMA_LEN) { |
|---|
| 218 | | - host->force_pio = true; |
|---|
| 178 | + if (sg->length < TMIO_MMC_MIN_DMA_LEN) |
|---|
| 219 | 179 | return; |
|---|
| 220 | | - } |
|---|
| 221 | 180 | |
|---|
| 222 | 181 | /* The only sg element can be unaligned, use our bounce buffer then */ |
|---|
| 223 | 182 | if (!aligned) { |
|---|
| .. | .. |
|---|
| 241 | 200 | desc = NULL; |
|---|
| 242 | 201 | ret = cookie; |
|---|
| 243 | 202 | } |
|---|
| 203 | + host->dma_on = true; |
|---|
| 244 | 204 | } |
|---|
| 245 | 205 | pio: |
|---|
| 246 | 206 | if (!desc) { |
|---|
| .. | .. |
|---|
| 287 | 247 | goto pio; |
|---|
| 288 | 248 | } |
|---|
| 289 | 249 | |
|---|
| 290 | | - if (sg->length < TMIO_MMC_MIN_DMA_LEN) { |
|---|
| 291 | | - host->force_pio = true; |
|---|
| 250 | + if (sg->length < TMIO_MMC_MIN_DMA_LEN) |
|---|
| 292 | 251 | return; |
|---|
| 293 | | - } |
|---|
| 294 | 252 | |
|---|
| 295 | 253 | /* The only sg element can be unaligned, use our bounce buffer then */ |
|---|
| 296 | 254 | if (!aligned) { |
|---|
| .. | .. |
|---|
| 319 | 277 | desc = NULL; |
|---|
| 320 | 278 | ret = cookie; |
|---|
| 321 | 279 | } |
|---|
| 280 | + host->dma_on = true; |
|---|
| 322 | 281 | } |
|---|
| 323 | 282 | pio: |
|---|
| 324 | 283 | if (!desc) { |
|---|
| .. | .. |
|---|
| 488 | 447 | .dataend = renesas_sdhi_sys_dmac_dataend_dma, |
|---|
| 489 | 448 | }; |
|---|
| 490 | 449 | |
|---|
| 491 | | -/* |
|---|
| 492 | | - * Whitelist of specific R-Car Gen3 SoC ES versions to use this DMAC |
|---|
| 493 | | - * implementation. Currently empty as all supported ES versions use |
|---|
| 494 | | - * the internal DMAC. |
|---|
| 495 | | - */ |
|---|
| 496 | | -static const struct soc_device_attribute gen3_soc_whitelist[] = { |
|---|
| 497 | | - { /* sentinel */ } |
|---|
| 498 | | -}; |
|---|
| 499 | | - |
|---|
| 500 | 450 | static int renesas_sdhi_sys_dmac_probe(struct platform_device *pdev) |
|---|
| 501 | 451 | { |
|---|
| 502 | | - if ((of_device_get_match_data(&pdev->dev) == &of_rcar_gen3_compatible || |
|---|
| 503 | | - of_device_get_match_data(&pdev->dev) == &of_rcar_r8a7795_compatible) && |
|---|
| 504 | | - !soc_device_match(gen3_soc_whitelist)) |
|---|
| 505 | | - return -ENODEV; |
|---|
| 506 | | - |
|---|
| 507 | 452 | return renesas_sdhi_probe(pdev, &renesas_sdhi_sys_dmac_dma_ops); |
|---|
| 508 | 453 | } |
|---|
| 509 | 454 | |
|---|
| .. | .. |
|---|
| 518 | 463 | static struct platform_driver renesas_sys_dmac_sdhi_driver = { |
|---|
| 519 | 464 | .driver = { |
|---|
| 520 | 465 | .name = "sh_mobile_sdhi", |
|---|
| 466 | + .probe_type = PROBE_PREFER_ASYNCHRONOUS, |
|---|
| 521 | 467 | .pm = &renesas_sdhi_sys_dmac_dev_pm_ops, |
|---|
| 522 | 468 | .of_match_table = renesas_sdhi_sys_dmac_of_match, |
|---|
| 523 | 469 | }, |
|---|