diff options
Diffstat (limited to 'drivers/mmc/host/mmci_qcom_dml.c')
| -rw-r--r-- | drivers/mmc/host/mmci_qcom_dml.c | 53 |
1 files changed, 39 insertions, 14 deletions
diff --git a/drivers/mmc/host/mmci_qcom_dml.c b/drivers/mmc/host/mmci_qcom_dml.c index 00750c9d3514..3da6112fbe39 100644 --- a/drivers/mmc/host/mmci_qcom_dml.c +++ b/drivers/mmc/host/mmci_qcom_dml.c @@ -1,16 +1,7 @@ +// SPDX-License-Identifier: GPL-2.0-only /* * * Copyright (c) 2011, The Linux Foundation. All rights reserved. - * - * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License version 2 and - * only version 2 as published by the Free Software Foundation. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * */ #include <linux/of.h> #include <linux/of_dma.h> @@ -54,10 +45,15 @@ #define DML_OFFSET 0x800 -void dml_start_xfer(struct mmci_host *host, struct mmc_data *data) +static int qcom_dma_start(struct mmci_host *host, unsigned int *datactrl) { u32 config; void __iomem *base = host->base + DML_OFFSET; + struct mmc_data *data = host->data; + int ret = mmci_dmae_start(host, datactrl); + + if (ret) + return ret; if (data->flags & MMC_DATA_READ) { /* Read operation: configure DML for producer operation */ @@ -96,6 +92,7 @@ void dml_start_xfer(struct mmci_host *host, struct mmc_data *data) /* make sure the dml is configured before dma is triggered */ wmb(); + return 0; } static int of_get_dml_pipe_index(struct device_node *np, const char *name) @@ -119,17 +116,23 @@ static int of_get_dml_pipe_index(struct device_node *np, const char *name) } /* Initialize the dml hardware connected to SD Card controller */ -int dml_hw_init(struct mmci_host *host, struct device_node *np) +static int qcom_dma_setup(struct mmci_host *host) { u32 config; void __iomem *base; int consumer_id, producer_id; + struct device_node *np = host->mmc->parent->of_node; + + if (mmci_dmae_setup(host)) + return -EINVAL; consumer_id = of_get_dml_pipe_index(np, "tx"); producer_id = of_get_dml_pipe_index(np, "rx"); - if (producer_id < 0 || consumer_id < 0) - return -ENODEV; + if (producer_id < 0 || consumer_id < 0) { + mmci_dmae_release(host); + return -EINVAL; + } base = host->base + DML_OFFSET; @@ -175,3 +178,25 @@ int dml_hw_init(struct mmci_host *host, struct device_node *np) return 0; } + +static u32 qcom_get_dctrl_cfg(struct mmci_host *host) +{ + return MCI_DPSM_ENABLE | (host->data->blksz << 4); +} + +static struct mmci_host_ops qcom_variant_ops = { + .prep_data = mmci_dmae_prep_data, + .unprep_data = mmci_dmae_unprep_data, + .get_datactrl_cfg = qcom_get_dctrl_cfg, + .get_next_data = mmci_dmae_get_next_data, + .dma_setup = qcom_dma_setup, + .dma_release = mmci_dmae_release, + .dma_start = qcom_dma_start, + .dma_finalize = mmci_dmae_finalize, + .dma_error = mmci_dmae_error, +}; + +void qcom_variant_init(struct mmci_host *host) +{ + host->ops = &qcom_variant_ops; +} |
