drivers/mmc/host/mmci_qcom_dml.c

Source file repositories/reference/linux-study-clean/drivers/mmc/host/mmci_qcom_dml.c

File Facts

System
Linux kernel
Corpus path
drivers/mmc/host/mmci_qcom_dml.c
Extension
.c
Size
5826 bytes
Lines
204
Domain
Driver Families
Bucket
drivers/mmc
Inferred role
Driver Families: implementation source
Status
source implementation candidate

Why This File Exists

Repeatable hardware-adapter layer. Deep compatibility for every driver is out of scope; this atlas records patterns, probe lifecycles, bus glue, IRQ/DMA usage, and links back to core abstractions.

Dependency Surface

Detected Declarations

Annotated Snippet

// SPDX-License-Identifier: GPL-2.0-only
/*
 *
 * Copyright (c) 2011, The Linux Foundation. All rights reserved.
 */
#include <linux/of.h>
#include <linux/of_dma.h>
#include <linux/bitops.h>
#include <linux/mmc/host.h>
#include <linux/mmc/card.h>
#include "mmci.h"

/* Registers */
#define DML_CONFIG			0x00
#define PRODUCER_CRCI_MSK		GENMASK(1, 0)
#define PRODUCER_CRCI_DISABLE		0
#define PRODUCER_CRCI_X_SEL		BIT(0)
#define PRODUCER_CRCI_Y_SEL		BIT(1)
#define CONSUMER_CRCI_MSK		GENMASK(3, 2)
#define CONSUMER_CRCI_DISABLE		0
#define CONSUMER_CRCI_X_SEL		BIT(2)
#define CONSUMER_CRCI_Y_SEL		BIT(3)
#define PRODUCER_TRANS_END_EN		BIT(4)
#define BYPASS				BIT(16)
#define DIRECT_MODE			BIT(17)
#define INFINITE_CONS_TRANS		BIT(18)

#define DML_SW_RESET			0x08
#define DML_PRODUCER_START		0x0c
#define DML_CONSUMER_START		0x10
#define DML_PRODUCER_PIPE_LOGICAL_SIZE	0x14
#define DML_CONSUMER_PIPE_LOGICAL_SIZE	0x18
#define DML_PIPE_ID			0x1c
#define PRODUCER_PIPE_ID_SHFT		0
#define PRODUCER_PIPE_ID_MSK		GENMASK(4, 0)
#define CONSUMER_PIPE_ID_SHFT		16
#define CONSUMER_PIPE_ID_MSK		GENMASK(20, 16)

#define DML_PRODUCER_BAM_BLOCK_SIZE	0x24
#define DML_PRODUCER_BAM_TRANS_SIZE	0x28

/* other definitions */
#define PRODUCER_PIPE_LOGICAL_SIZE	4096
#define CONSUMER_PIPE_LOGICAL_SIZE	4096

#define DML_OFFSET			0x800

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 */
		/* Set producer CRCI-x and disable consumer CRCI */
		config = readl_relaxed(base + DML_CONFIG);
		config = (config & ~PRODUCER_CRCI_MSK) | PRODUCER_CRCI_X_SEL;
		config = (config & ~CONSUMER_CRCI_MSK) | CONSUMER_CRCI_DISABLE;
		writel_relaxed(config, base + DML_CONFIG);

		/* Set the Producer BAM block size */
		writel_relaxed(data->blksz, base + DML_PRODUCER_BAM_BLOCK_SIZE);

		/* Set Producer BAM Transaction size */
		writel_relaxed(data->blocks * data->blksz,
			       base + DML_PRODUCER_BAM_TRANS_SIZE);
		/* Set Producer Transaction End bit */
		config = readl_relaxed(base + DML_CONFIG);
		config |= PRODUCER_TRANS_END_EN;
		writel_relaxed(config, base + DML_CONFIG);
		/* Trigger producer */
		writel_relaxed(1, base + DML_PRODUCER_START);
	} else {
		/* Write operation: configure DML for consumer operation */
		/* Set consumer CRCI-x and disable producer CRCI*/
		config = readl_relaxed(base + DML_CONFIG);
		config = (config & ~CONSUMER_CRCI_MSK) | CONSUMER_CRCI_X_SEL;
		config = (config & ~PRODUCER_CRCI_MSK) | PRODUCER_CRCI_DISABLE;
		writel_relaxed(config, base + DML_CONFIG);
		/* Clear Producer Transaction End bit */
		config = readl_relaxed(base + DML_CONFIG);
		config &= ~PRODUCER_TRANS_END_EN;
		writel_relaxed(config, base + DML_CONFIG);
		/* Trigger consumer */
		writel_relaxed(1, base + DML_CONSUMER_START);

Annotation

Implementation Notes