cachepc-linux

Fork of AMDESE/linux with modifications for CachePC side-channel attack
git clone https://git.sinitax.com/sinitax/cachepc-linux
Log | Files | Refs | README | LICENSE | sfeed.txt

sprd-mcdt.c (24055B)


      1// SPDX-License-Identifier: GPL-2.0
      2// Copyright (C) 2019 Spreadtrum Communications Inc.
      3
      4#include <linux/errno.h>
      5#include <linux/interrupt.h>
      6#include <linux/io.h>
      7#include <linux/kernel.h>
      8#include <linux/module.h>
      9#include <linux/mutex.h>
     10#include <linux/of.h>
     11#include <linux/platform_device.h>
     12#include <linux/spinlock.h>
     13
     14#include "sprd-mcdt.h"
     15
     16/* MCDT registers definition */
     17#define MCDT_CH0_TXD		0x0
     18#define MCDT_CH0_RXD		0x28
     19#define MCDT_DAC0_WTMK		0x60
     20#define MCDT_ADC0_WTMK		0x88
     21#define MCDT_DMA_EN		0xb0
     22
     23#define MCDT_INT_EN0		0xb4
     24#define MCDT_INT_EN1		0xb8
     25#define MCDT_INT_EN2		0xbc
     26
     27#define MCDT_INT_CLR0		0xc0
     28#define MCDT_INT_CLR1		0xc4
     29#define MCDT_INT_CLR2		0xc8
     30
     31#define MCDT_INT_RAW1		0xcc
     32#define MCDT_INT_RAW2		0xd0
     33#define MCDT_INT_RAW3		0xd4
     34
     35#define MCDT_INT_MSK1		0xd8
     36#define MCDT_INT_MSK2		0xdc
     37#define MCDT_INT_MSK3		0xe0
     38
     39#define MCDT_DAC0_FIFO_ADDR_ST	0xe4
     40#define MCDT_ADC0_FIFO_ADDR_ST	0xe8
     41
     42#define MCDT_CH_FIFO_ST0	0x134
     43#define MCDT_CH_FIFO_ST1	0x138
     44#define MCDT_CH_FIFO_ST2	0x13c
     45
     46#define MCDT_INT_MSK_CFG0	0x140
     47#define MCDT_INT_MSK_CFG1	0x144
     48
     49#define MCDT_DMA_CFG0		0x148
     50#define MCDT_FIFO_CLR		0x14c
     51#define MCDT_DMA_CFG1		0x150
     52#define MCDT_DMA_CFG2		0x154
     53#define MCDT_DMA_CFG3		0x158
     54#define MCDT_DMA_CFG4		0x15c
     55#define MCDT_DMA_CFG5		0x160
     56
     57/* Channel water mark definition */
     58#define MCDT_CH_FIFO_AE_SHIFT	16
     59#define MCDT_CH_FIFO_AE_MASK	GENMASK(24, 16)
     60#define MCDT_CH_FIFO_AF_MASK	GENMASK(8, 0)
     61
     62/* DMA channel select definition */
     63#define MCDT_DMA_CH0_SEL_MASK	GENMASK(3, 0)
     64#define MCDT_DMA_CH0_SEL_SHIFT	0
     65#define MCDT_DMA_CH1_SEL_MASK	GENMASK(7, 4)
     66#define MCDT_DMA_CH1_SEL_SHIFT	4
     67#define MCDT_DMA_CH2_SEL_MASK	GENMASK(11, 8)
     68#define MCDT_DMA_CH2_SEL_SHIFT	8
     69#define MCDT_DMA_CH3_SEL_MASK	GENMASK(15, 12)
     70#define MCDT_DMA_CH3_SEL_SHIFT	12
     71#define MCDT_DMA_CH4_SEL_MASK	GENMASK(19, 16)
     72#define MCDT_DMA_CH4_SEL_SHIFT	16
     73#define MCDT_DAC_DMA_SHIFT	16
     74
     75/* DMA channel ACK select definition */
     76#define MCDT_DMA_ACK_SEL_MASK	GENMASK(3, 0)
     77
     78/* Channel FIFO definition */
     79#define MCDT_CH_FIFO_ADDR_SHIFT	16
     80#define MCDT_CH_FIFO_ADDR_MASK	GENMASK(9, 0)
     81#define MCDT_ADC_FIFO_SHIFT	16
     82#define MCDT_FIFO_LENGTH	512
     83
     84#define MCDT_ADC_CHANNEL_NUM	10
     85#define MCDT_DAC_CHANNEL_NUM	10
     86#define MCDT_CHANNEL_NUM	(MCDT_ADC_CHANNEL_NUM + MCDT_DAC_CHANNEL_NUM)
     87
     88enum sprd_mcdt_fifo_int {
     89	MCDT_ADC_FIFO_AE_INT,
     90	MCDT_ADC_FIFO_AF_INT,
     91	MCDT_DAC_FIFO_AE_INT,
     92	MCDT_DAC_FIFO_AF_INT,
     93	MCDT_ADC_FIFO_OV_INT,
     94	MCDT_DAC_FIFO_OV_INT
     95};
     96
     97enum sprd_mcdt_fifo_sts {
     98	MCDT_ADC_FIFO_REAL_FULL,
     99	MCDT_ADC_FIFO_REAL_EMPTY,
    100	MCDT_ADC_FIFO_AF,
    101	MCDT_ADC_FIFO_AE,
    102	MCDT_DAC_FIFO_REAL_FULL,
    103	MCDT_DAC_FIFO_REAL_EMPTY,
    104	MCDT_DAC_FIFO_AF,
    105	MCDT_DAC_FIFO_AE
    106};
    107
    108struct sprd_mcdt_dev {
    109	struct device *dev;
    110	void __iomem *base;
    111	spinlock_t lock;
    112	struct sprd_mcdt_chan chan[MCDT_CHANNEL_NUM];
    113};
    114
    115static LIST_HEAD(sprd_mcdt_chan_list);
    116static DEFINE_MUTEX(sprd_mcdt_list_mutex);
    117
    118static void sprd_mcdt_update(struct sprd_mcdt_dev *mcdt, u32 reg, u32 val,
    119			     u32 mask)
    120{
    121	u32 orig = readl_relaxed(mcdt->base + reg);
    122	u32 tmp;
    123
    124	tmp = (orig & ~mask) | val;
    125	writel_relaxed(tmp, mcdt->base + reg);
    126}
    127
    128static void sprd_mcdt_dac_set_watermark(struct sprd_mcdt_dev *mcdt, u8 channel,
    129					u32 full, u32 empty)
    130{
    131	u32 reg = MCDT_DAC0_WTMK + channel * 4;
    132	u32 water_mark =
    133		(empty << MCDT_CH_FIFO_AE_SHIFT) & MCDT_CH_FIFO_AE_MASK;
    134
    135	water_mark |= full & MCDT_CH_FIFO_AF_MASK;
    136	sprd_mcdt_update(mcdt, reg, water_mark,
    137			 MCDT_CH_FIFO_AE_MASK | MCDT_CH_FIFO_AF_MASK);
    138}
    139
    140static void sprd_mcdt_adc_set_watermark(struct sprd_mcdt_dev *mcdt, u8 channel,
    141					u32 full, u32 empty)
    142{
    143	u32 reg = MCDT_ADC0_WTMK + channel * 4;
    144	u32 water_mark =
    145		(empty << MCDT_CH_FIFO_AE_SHIFT) & MCDT_CH_FIFO_AE_MASK;
    146
    147	water_mark |= full & MCDT_CH_FIFO_AF_MASK;
    148	sprd_mcdt_update(mcdt, reg, water_mark,
    149			 MCDT_CH_FIFO_AE_MASK | MCDT_CH_FIFO_AF_MASK);
    150}
    151
    152static void sprd_mcdt_dac_dma_enable(struct sprd_mcdt_dev *mcdt, u8 channel,
    153				     bool enable)
    154{
    155	u32 shift = MCDT_DAC_DMA_SHIFT + channel;
    156
    157	if (enable)
    158		sprd_mcdt_update(mcdt, MCDT_DMA_EN, BIT(shift), BIT(shift));
    159	else
    160		sprd_mcdt_update(mcdt, MCDT_DMA_EN, 0, BIT(shift));
    161}
    162
    163static void sprd_mcdt_adc_dma_enable(struct sprd_mcdt_dev *mcdt, u8 channel,
    164				     bool enable)
    165{
    166	if (enable)
    167		sprd_mcdt_update(mcdt, MCDT_DMA_EN, BIT(channel), BIT(channel));
    168	else
    169		sprd_mcdt_update(mcdt, MCDT_DMA_EN, 0, BIT(channel));
    170}
    171
    172static void sprd_mcdt_ap_int_enable(struct sprd_mcdt_dev *mcdt, u8 channel,
    173				    bool enable)
    174{
    175	if (enable)
    176		sprd_mcdt_update(mcdt, MCDT_INT_MSK_CFG0, BIT(channel),
    177				 BIT(channel));
    178	else
    179		sprd_mcdt_update(mcdt, MCDT_INT_MSK_CFG0, 0, BIT(channel));
    180}
    181
    182static void sprd_mcdt_dac_write_fifo(struct sprd_mcdt_dev *mcdt, u8 channel,
    183				     u32 val)
    184{
    185	u32 reg = MCDT_CH0_TXD + channel * 4;
    186
    187	writel_relaxed(val, mcdt->base + reg);
    188}
    189
    190static void sprd_mcdt_adc_read_fifo(struct sprd_mcdt_dev *mcdt, u8 channel,
    191				    u32 *val)
    192{
    193	u32 reg = MCDT_CH0_RXD + channel * 4;
    194
    195	*val = readl_relaxed(mcdt->base + reg);
    196}
    197
    198static void sprd_mcdt_dac_dma_chn_select(struct sprd_mcdt_dev *mcdt, u8 channel,
    199					 enum sprd_mcdt_dma_chan dma_chan)
    200{
    201	switch (dma_chan) {
    202	case SPRD_MCDT_DMA_CH0:
    203		sprd_mcdt_update(mcdt, MCDT_DMA_CFG0,
    204				 channel << MCDT_DMA_CH0_SEL_SHIFT,
    205				 MCDT_DMA_CH0_SEL_MASK);
    206		break;
    207
    208	case SPRD_MCDT_DMA_CH1:
    209		sprd_mcdt_update(mcdt, MCDT_DMA_CFG0,
    210				 channel << MCDT_DMA_CH1_SEL_SHIFT,
    211				 MCDT_DMA_CH1_SEL_MASK);
    212		break;
    213
    214	case SPRD_MCDT_DMA_CH2:
    215		sprd_mcdt_update(mcdt, MCDT_DMA_CFG0,
    216				 channel << MCDT_DMA_CH2_SEL_SHIFT,
    217				 MCDT_DMA_CH2_SEL_MASK);
    218		break;
    219
    220	case SPRD_MCDT_DMA_CH3:
    221		sprd_mcdt_update(mcdt, MCDT_DMA_CFG0,
    222				 channel << MCDT_DMA_CH3_SEL_SHIFT,
    223				 MCDT_DMA_CH3_SEL_MASK);
    224		break;
    225
    226	case SPRD_MCDT_DMA_CH4:
    227		sprd_mcdt_update(mcdt, MCDT_DMA_CFG0,
    228				 channel << MCDT_DMA_CH4_SEL_SHIFT,
    229				 MCDT_DMA_CH4_SEL_MASK);
    230		break;
    231	}
    232}
    233
    234static void sprd_mcdt_adc_dma_chn_select(struct sprd_mcdt_dev *mcdt, u8 channel,
    235					 enum sprd_mcdt_dma_chan dma_chan)
    236{
    237	switch (dma_chan) {
    238	case SPRD_MCDT_DMA_CH0:
    239		sprd_mcdt_update(mcdt, MCDT_DMA_CFG1,
    240				 channel << MCDT_DMA_CH0_SEL_SHIFT,
    241				 MCDT_DMA_CH0_SEL_MASK);
    242		break;
    243
    244	case SPRD_MCDT_DMA_CH1:
    245		sprd_mcdt_update(mcdt, MCDT_DMA_CFG1,
    246				 channel << MCDT_DMA_CH1_SEL_SHIFT,
    247				 MCDT_DMA_CH1_SEL_MASK);
    248		break;
    249
    250	case SPRD_MCDT_DMA_CH2:
    251		sprd_mcdt_update(mcdt, MCDT_DMA_CFG1,
    252				 channel << MCDT_DMA_CH2_SEL_SHIFT,
    253				 MCDT_DMA_CH2_SEL_MASK);
    254		break;
    255
    256	case SPRD_MCDT_DMA_CH3:
    257		sprd_mcdt_update(mcdt, MCDT_DMA_CFG1,
    258				 channel << MCDT_DMA_CH3_SEL_SHIFT,
    259				 MCDT_DMA_CH3_SEL_MASK);
    260		break;
    261
    262	case SPRD_MCDT_DMA_CH4:
    263		sprd_mcdt_update(mcdt, MCDT_DMA_CFG1,
    264				 channel << MCDT_DMA_CH4_SEL_SHIFT,
    265				 MCDT_DMA_CH4_SEL_MASK);
    266		break;
    267	}
    268}
    269
    270static u32 sprd_mcdt_dma_ack_shift(u8 channel)
    271{
    272	switch (channel) {
    273	default:
    274	case 0:
    275	case 8:
    276		return 0;
    277	case 1:
    278	case 9:
    279		return 4;
    280	case 2:
    281		return 8;
    282	case 3:
    283		return 12;
    284	case 4:
    285		return 16;
    286	case 5:
    287		return 20;
    288	case 6:
    289		return 24;
    290	case 7:
    291		return 28;
    292	}
    293}
    294
    295static void sprd_mcdt_dac_dma_ack_select(struct sprd_mcdt_dev *mcdt, u8 channel,
    296					 enum sprd_mcdt_dma_chan dma_chan)
    297{
    298	u32 reg, shift = sprd_mcdt_dma_ack_shift(channel), ack = dma_chan;
    299
    300	switch (channel) {
    301	case 0 ... 7:
    302		reg = MCDT_DMA_CFG2;
    303		break;
    304
    305	case 8 ... 9:
    306		reg = MCDT_DMA_CFG3;
    307		break;
    308
    309	default:
    310		return;
    311	}
    312
    313	sprd_mcdt_update(mcdt, reg, ack << shift,
    314			 MCDT_DMA_ACK_SEL_MASK << shift);
    315}
    316
    317static void sprd_mcdt_adc_dma_ack_select(struct sprd_mcdt_dev *mcdt, u8 channel,
    318					 enum sprd_mcdt_dma_chan dma_chan)
    319{
    320	u32 reg, shift = sprd_mcdt_dma_ack_shift(channel), ack = dma_chan;
    321
    322	switch (channel) {
    323	case 0 ... 7:
    324		reg = MCDT_DMA_CFG4;
    325		break;
    326
    327	case 8 ... 9:
    328		reg = MCDT_DMA_CFG5;
    329		break;
    330
    331	default:
    332		return;
    333	}
    334
    335	sprd_mcdt_update(mcdt, reg, ack << shift,
    336			 MCDT_DMA_ACK_SEL_MASK << shift);
    337}
    338
    339static bool sprd_mcdt_chan_fifo_sts(struct sprd_mcdt_dev *mcdt, u8 channel,
    340				    enum sprd_mcdt_fifo_sts fifo_sts)
    341{
    342	u32 reg, shift;
    343
    344	switch (channel) {
    345	case 0 ... 3:
    346		reg = MCDT_CH_FIFO_ST0;
    347		break;
    348	case 4 ... 7:
    349		reg = MCDT_CH_FIFO_ST1;
    350		break;
    351	case 8 ... 9:
    352		reg = MCDT_CH_FIFO_ST2;
    353		break;
    354	default:
    355		return false;
    356	}
    357
    358	switch (channel) {
    359	case 0:
    360	case 4:
    361	case 8:
    362		shift = fifo_sts;
    363		break;
    364
    365	case 1:
    366	case 5:
    367	case 9:
    368		shift = 8 + fifo_sts;
    369		break;
    370
    371	case 2:
    372	case 6:
    373		shift = 16 + fifo_sts;
    374		break;
    375
    376	case 3:
    377	case 7:
    378		shift = 24 + fifo_sts;
    379		break;
    380
    381	default:
    382		return false;
    383	}
    384
    385	return !!(readl_relaxed(mcdt->base + reg) & BIT(shift));
    386}
    387
    388static void sprd_mcdt_dac_fifo_clear(struct sprd_mcdt_dev *mcdt, u8 channel)
    389{
    390	sprd_mcdt_update(mcdt, MCDT_FIFO_CLR, BIT(channel), BIT(channel));
    391}
    392
    393static void sprd_mcdt_adc_fifo_clear(struct sprd_mcdt_dev *mcdt, u8 channel)
    394{
    395	u32 shift = MCDT_ADC_FIFO_SHIFT + channel;
    396
    397	sprd_mcdt_update(mcdt, MCDT_FIFO_CLR, BIT(shift), BIT(shift));
    398}
    399
    400static u32 sprd_mcdt_dac_fifo_avail(struct sprd_mcdt_dev *mcdt, u8 channel)
    401{
    402	u32 reg = MCDT_DAC0_FIFO_ADDR_ST + channel * 8;
    403	u32 r_addr = (readl_relaxed(mcdt->base + reg) >>
    404		      MCDT_CH_FIFO_ADDR_SHIFT) & MCDT_CH_FIFO_ADDR_MASK;
    405	u32 w_addr = readl_relaxed(mcdt->base + reg) & MCDT_CH_FIFO_ADDR_MASK;
    406
    407	if (w_addr >= r_addr)
    408		return 4 * (MCDT_FIFO_LENGTH - w_addr + r_addr);
    409	else
    410		return 4 * (r_addr - w_addr);
    411}
    412
    413static u32 sprd_mcdt_adc_fifo_avail(struct sprd_mcdt_dev *mcdt, u8 channel)
    414{
    415	u32 reg = MCDT_ADC0_FIFO_ADDR_ST + channel * 8;
    416	u32 r_addr = (readl_relaxed(mcdt->base + reg) >>
    417		      MCDT_CH_FIFO_ADDR_SHIFT) & MCDT_CH_FIFO_ADDR_MASK;
    418	u32 w_addr = readl_relaxed(mcdt->base + reg) & MCDT_CH_FIFO_ADDR_MASK;
    419
    420	if (w_addr >= r_addr)
    421		return 4 * (w_addr - r_addr);
    422	else
    423		return 4 * (MCDT_FIFO_LENGTH - r_addr + w_addr);
    424}
    425
    426static u32 sprd_mcdt_int_type_shift(u8 channel,
    427				    enum sprd_mcdt_fifo_int int_type)
    428{
    429	switch (channel) {
    430	case 0:
    431	case 4:
    432	case 8:
    433		return int_type;
    434
    435	case 1:
    436	case 5:
    437	case 9:
    438		return  8 + int_type;
    439
    440	case 2:
    441	case 6:
    442		return 16 + int_type;
    443
    444	case 3:
    445	case 7:
    446		return 24 + int_type;
    447
    448	default:
    449		return 0;
    450	}
    451}
    452
    453static void sprd_mcdt_chan_int_en(struct sprd_mcdt_dev *mcdt, u8 channel,
    454				  enum sprd_mcdt_fifo_int int_type, bool enable)
    455{
    456	u32 reg, shift = sprd_mcdt_int_type_shift(channel, int_type);
    457
    458	switch (channel) {
    459	case 0 ... 3:
    460		reg = MCDT_INT_EN0;
    461		break;
    462	case 4 ... 7:
    463		reg = MCDT_INT_EN1;
    464		break;
    465	case 8 ... 9:
    466		reg = MCDT_INT_EN2;
    467		break;
    468	default:
    469		return;
    470	}
    471
    472	if (enable)
    473		sprd_mcdt_update(mcdt, reg, BIT(shift), BIT(shift));
    474	else
    475		sprd_mcdt_update(mcdt, reg, 0, BIT(shift));
    476}
    477
    478static void sprd_mcdt_chan_int_clear(struct sprd_mcdt_dev *mcdt, u8 channel,
    479				     enum sprd_mcdt_fifo_int int_type)
    480{
    481	u32 reg, shift = sprd_mcdt_int_type_shift(channel, int_type);
    482
    483	switch (channel) {
    484	case 0 ... 3:
    485		reg = MCDT_INT_CLR0;
    486		break;
    487	case 4 ... 7:
    488		reg = MCDT_INT_CLR1;
    489		break;
    490	case 8 ... 9:
    491		reg = MCDT_INT_CLR2;
    492		break;
    493	default:
    494		return;
    495	}
    496
    497	sprd_mcdt_update(mcdt, reg, BIT(shift), BIT(shift));
    498}
    499
    500static bool sprd_mcdt_chan_int_sts(struct sprd_mcdt_dev *mcdt, u8 channel,
    501				   enum sprd_mcdt_fifo_int int_type)
    502{
    503	u32 reg, shift = sprd_mcdt_int_type_shift(channel, int_type);
    504
    505	switch (channel) {
    506	case 0 ... 3:
    507		reg = MCDT_INT_MSK1;
    508		break;
    509	case 4 ... 7:
    510		reg = MCDT_INT_MSK2;
    511		break;
    512	case 8 ... 9:
    513		reg = MCDT_INT_MSK3;
    514		break;
    515	default:
    516		return false;
    517	}
    518
    519	return !!(readl_relaxed(mcdt->base + reg) & BIT(shift));
    520}
    521
    522static irqreturn_t sprd_mcdt_irq_handler(int irq, void *dev_id)
    523{
    524	struct sprd_mcdt_dev *mcdt = (struct sprd_mcdt_dev *)dev_id;
    525	int i;
    526
    527	spin_lock(&mcdt->lock);
    528
    529	for (i = 0; i < MCDT_ADC_CHANNEL_NUM; i++) {
    530		if (sprd_mcdt_chan_int_sts(mcdt, i, MCDT_ADC_FIFO_AF_INT)) {
    531			struct sprd_mcdt_chan *chan = &mcdt->chan[i];
    532
    533			sprd_mcdt_chan_int_clear(mcdt, i, MCDT_ADC_FIFO_AF_INT);
    534			if (chan->cb)
    535				chan->cb->notify(chan->cb->data);
    536		}
    537	}
    538
    539	for (i = 0; i < MCDT_DAC_CHANNEL_NUM; i++) {
    540		if (sprd_mcdt_chan_int_sts(mcdt, i, MCDT_DAC_FIFO_AE_INT)) {
    541			struct sprd_mcdt_chan *chan =
    542				&mcdt->chan[i + MCDT_ADC_CHANNEL_NUM];
    543
    544			sprd_mcdt_chan_int_clear(mcdt, i, MCDT_DAC_FIFO_AE_INT);
    545			if (chan->cb)
    546				chan->cb->notify(chan->cb->data);
    547		}
    548	}
    549
    550	spin_unlock(&mcdt->lock);
    551
    552	return IRQ_HANDLED;
    553}
    554
    555/**
    556 * sprd_mcdt_chan_write - write data to the MCDT channel's fifo
    557 * @chan: the MCDT channel
    558 * @tx_buf: send buffer
    559 * @size: data size
    560 *
    561 * Note: We can not write data to the channel fifo when enabling the DMA mode,
    562 * otherwise the channel fifo data will be invalid.
    563 *
    564 * If there are not enough space of the channel fifo, it will return errors
    565 * to users.
    566 *
    567 * Returns 0 on success, or an appropriate error code on failure.
    568 */
    569int sprd_mcdt_chan_write(struct sprd_mcdt_chan *chan, char *tx_buf, u32 size)
    570{
    571	struct sprd_mcdt_dev *mcdt = chan->mcdt;
    572	unsigned long flags;
    573	int avail, i = 0, words = size / 4;
    574	u32 *buf = (u32 *)tx_buf;
    575
    576	spin_lock_irqsave(&mcdt->lock, flags);
    577
    578	if (chan->dma_enable) {
    579		dev_err(mcdt->dev,
    580			"Can not write data when DMA mode enabled\n");
    581		spin_unlock_irqrestore(&mcdt->lock, flags);
    582		return -EINVAL;
    583	}
    584
    585	if (sprd_mcdt_chan_fifo_sts(mcdt, chan->id, MCDT_DAC_FIFO_REAL_FULL)) {
    586		dev_err(mcdt->dev, "Channel fifo is full now\n");
    587		spin_unlock_irqrestore(&mcdt->lock, flags);
    588		return -EBUSY;
    589	}
    590
    591	avail = sprd_mcdt_dac_fifo_avail(mcdt, chan->id);
    592	if (size > avail) {
    593		dev_err(mcdt->dev,
    594			"Data size is larger than the available fifo size\n");
    595		spin_unlock_irqrestore(&mcdt->lock, flags);
    596		return -EBUSY;
    597	}
    598
    599	while (i++ < words)
    600		sprd_mcdt_dac_write_fifo(mcdt, chan->id, *buf++);
    601
    602	spin_unlock_irqrestore(&mcdt->lock, flags);
    603	return 0;
    604}
    605EXPORT_SYMBOL_GPL(sprd_mcdt_chan_write);
    606
    607/**
    608 * sprd_mcdt_chan_read - read data from the MCDT channel's fifo
    609 * @chan: the MCDT channel
    610 * @rx_buf: receive buffer
    611 * @size: data size
    612 *
    613 * Note: We can not read data from the channel fifo when enabling the DMA mode,
    614 * otherwise the reading data will be invalid.
    615 *
    616 * Usually user need start to read data once receiving the fifo full interrupt.
    617 *
    618 * Returns data size of reading successfully, or an error code on failure.
    619 */
    620int sprd_mcdt_chan_read(struct sprd_mcdt_chan *chan, char *rx_buf, u32 size)
    621{
    622	struct sprd_mcdt_dev *mcdt = chan->mcdt;
    623	unsigned long flags;
    624	int i = 0, avail, words = size / 4;
    625	u32 *buf = (u32 *)rx_buf;
    626
    627	spin_lock_irqsave(&mcdt->lock, flags);
    628
    629	if (chan->dma_enable) {
    630		dev_err(mcdt->dev, "Can not read data when DMA mode enabled\n");
    631		spin_unlock_irqrestore(&mcdt->lock, flags);
    632		return -EINVAL;
    633	}
    634
    635	if (sprd_mcdt_chan_fifo_sts(mcdt, chan->id, MCDT_ADC_FIFO_REAL_EMPTY)) {
    636		dev_err(mcdt->dev, "Channel fifo is empty\n");
    637		spin_unlock_irqrestore(&mcdt->lock, flags);
    638		return -EBUSY;
    639	}
    640
    641	avail = sprd_mcdt_adc_fifo_avail(mcdt, chan->id);
    642	if (size > avail)
    643		words = avail / 4;
    644
    645	while (i++ < words)
    646		sprd_mcdt_adc_read_fifo(mcdt, chan->id, buf++);
    647
    648	spin_unlock_irqrestore(&mcdt->lock, flags);
    649	return words * 4;
    650}
    651EXPORT_SYMBOL_GPL(sprd_mcdt_chan_read);
    652
    653/**
    654 * sprd_mcdt_chan_int_enable - enable the interrupt mode for the MCDT channel
    655 * @chan: the MCDT channel
    656 * @water_mark: water mark to trigger a interrupt
    657 * @cb: callback when a interrupt happened
    658 *
    659 * Now it only can enable fifo almost full interrupt for ADC channel and fifo
    660 * almost empty interrupt for DAC channel. Morevoer for interrupt mode, user
    661 * should use sprd_mcdt_chan_read() or sprd_mcdt_chan_write() to read or write
    662 * data manually.
    663 *
    664 * For ADC channel, user can start to read data once receiving one fifo full
    665 * interrupt. For DAC channel, user can start to write data once receiving one
    666 * fifo empty interrupt or just call sprd_mcdt_chan_write() to write data
    667 * directly.
    668 *
    669 * Returns 0 on success, or an error code on failure.
    670 */
    671int sprd_mcdt_chan_int_enable(struct sprd_mcdt_chan *chan, u32 water_mark,
    672			      struct sprd_mcdt_chan_callback *cb)
    673{
    674	struct sprd_mcdt_dev *mcdt = chan->mcdt;
    675	unsigned long flags;
    676	int ret = 0;
    677
    678	spin_lock_irqsave(&mcdt->lock, flags);
    679
    680	if (chan->dma_enable || chan->int_enable) {
    681		dev_err(mcdt->dev, "Failed to set interrupt mode.\n");
    682		spin_unlock_irqrestore(&mcdt->lock, flags);
    683		return -EINVAL;
    684	}
    685
    686	switch (chan->type) {
    687	case SPRD_MCDT_ADC_CHAN:
    688		sprd_mcdt_adc_fifo_clear(mcdt, chan->id);
    689		sprd_mcdt_adc_set_watermark(mcdt, chan->id, water_mark,
    690					    MCDT_FIFO_LENGTH - 1);
    691		sprd_mcdt_chan_int_en(mcdt, chan->id,
    692				      MCDT_ADC_FIFO_AF_INT, true);
    693		sprd_mcdt_ap_int_enable(mcdt, chan->id, true);
    694		break;
    695
    696	case SPRD_MCDT_DAC_CHAN:
    697		sprd_mcdt_dac_fifo_clear(mcdt, chan->id);
    698		sprd_mcdt_dac_set_watermark(mcdt, chan->id,
    699					    MCDT_FIFO_LENGTH - 1, water_mark);
    700		sprd_mcdt_chan_int_en(mcdt, chan->id,
    701				      MCDT_DAC_FIFO_AE_INT, true);
    702		sprd_mcdt_ap_int_enable(mcdt, chan->id, true);
    703		break;
    704
    705	default:
    706		dev_err(mcdt->dev, "Unsupported channel type\n");
    707		ret = -EINVAL;
    708	}
    709
    710	if (!ret) {
    711		chan->cb = cb;
    712		chan->int_enable = true;
    713	}
    714
    715	spin_unlock_irqrestore(&mcdt->lock, flags);
    716
    717	return ret;
    718}
    719EXPORT_SYMBOL_GPL(sprd_mcdt_chan_int_enable);
    720
    721/**
    722 * sprd_mcdt_chan_int_disable - disable the interrupt mode for the MCDT channel
    723 * @chan: the MCDT channel
    724 */
    725void sprd_mcdt_chan_int_disable(struct sprd_mcdt_chan *chan)
    726{
    727	struct sprd_mcdt_dev *mcdt = chan->mcdt;
    728	unsigned long flags;
    729
    730	spin_lock_irqsave(&mcdt->lock, flags);
    731
    732	if (!chan->int_enable) {
    733		spin_unlock_irqrestore(&mcdt->lock, flags);
    734		return;
    735	}
    736
    737	switch (chan->type) {
    738	case SPRD_MCDT_ADC_CHAN:
    739		sprd_mcdt_chan_int_en(mcdt, chan->id,
    740				      MCDT_ADC_FIFO_AF_INT, false);
    741		sprd_mcdt_chan_int_clear(mcdt, chan->id, MCDT_ADC_FIFO_AF_INT);
    742		sprd_mcdt_ap_int_enable(mcdt, chan->id, false);
    743		break;
    744
    745	case SPRD_MCDT_DAC_CHAN:
    746		sprd_mcdt_chan_int_en(mcdt, chan->id,
    747				      MCDT_DAC_FIFO_AE_INT, false);
    748		sprd_mcdt_chan_int_clear(mcdt, chan->id, MCDT_DAC_FIFO_AE_INT);
    749		sprd_mcdt_ap_int_enable(mcdt, chan->id, false);
    750		break;
    751
    752	default:
    753		break;
    754	}
    755
    756	chan->int_enable = false;
    757	spin_unlock_irqrestore(&mcdt->lock, flags);
    758}
    759EXPORT_SYMBOL_GPL(sprd_mcdt_chan_int_disable);
    760
    761/**
    762 * sprd_mcdt_chan_dma_enable - enable the DMA mode for the MCDT channel
    763 * @chan: the MCDT channel
    764 * @dma_chan: specify which DMA channel will be used for this MCDT channel
    765 * @water_mark: water mark to trigger a DMA request
    766 *
    767 * Enable the DMA mode for the MCDT channel, that means we can use DMA to
    768 * transfer data to the channel fifo and do not need reading/writing data
    769 * manually.
    770 *
    771 * Returns 0 on success, or an error code on failure.
    772 */
    773int sprd_mcdt_chan_dma_enable(struct sprd_mcdt_chan *chan,
    774			      enum sprd_mcdt_dma_chan dma_chan,
    775			      u32 water_mark)
    776{
    777	struct sprd_mcdt_dev *mcdt = chan->mcdt;
    778	unsigned long flags;
    779	int ret = 0;
    780
    781	spin_lock_irqsave(&mcdt->lock, flags);
    782
    783	if (chan->dma_enable || chan->int_enable ||
    784	    dma_chan > SPRD_MCDT_DMA_CH4) {
    785		dev_err(mcdt->dev, "Failed to set DMA mode\n");
    786		spin_unlock_irqrestore(&mcdt->lock, flags);
    787		return -EINVAL;
    788	}
    789
    790	switch (chan->type) {
    791	case SPRD_MCDT_ADC_CHAN:
    792		sprd_mcdt_adc_fifo_clear(mcdt, chan->id);
    793		sprd_mcdt_adc_set_watermark(mcdt, chan->id,
    794					    water_mark, MCDT_FIFO_LENGTH - 1);
    795		sprd_mcdt_adc_dma_enable(mcdt, chan->id, true);
    796		sprd_mcdt_adc_dma_chn_select(mcdt, chan->id, dma_chan);
    797		sprd_mcdt_adc_dma_ack_select(mcdt, chan->id, dma_chan);
    798		break;
    799
    800	case SPRD_MCDT_DAC_CHAN:
    801		sprd_mcdt_dac_fifo_clear(mcdt, chan->id);
    802		sprd_mcdt_dac_set_watermark(mcdt, chan->id,
    803					    MCDT_FIFO_LENGTH - 1, water_mark);
    804		sprd_mcdt_dac_dma_enable(mcdt, chan->id, true);
    805		sprd_mcdt_dac_dma_chn_select(mcdt, chan->id, dma_chan);
    806		sprd_mcdt_dac_dma_ack_select(mcdt, chan->id, dma_chan);
    807		break;
    808
    809	default:
    810		dev_err(mcdt->dev, "Unsupported channel type\n");
    811		ret = -EINVAL;
    812	}
    813
    814	if (!ret)
    815		chan->dma_enable = true;
    816
    817	spin_unlock_irqrestore(&mcdt->lock, flags);
    818
    819	return ret;
    820}
    821EXPORT_SYMBOL_GPL(sprd_mcdt_chan_dma_enable);
    822
    823/**
    824 * sprd_mcdt_chan_dma_disable - disable the DMA mode for the MCDT channel
    825 * @chan: the MCDT channel
    826 */
    827void sprd_mcdt_chan_dma_disable(struct sprd_mcdt_chan *chan)
    828{
    829	struct sprd_mcdt_dev *mcdt = chan->mcdt;
    830	unsigned long flags;
    831
    832	spin_lock_irqsave(&mcdt->lock, flags);
    833
    834	if (!chan->dma_enable) {
    835		spin_unlock_irqrestore(&mcdt->lock, flags);
    836		return;
    837	}
    838
    839	switch (chan->type) {
    840	case SPRD_MCDT_ADC_CHAN:
    841		sprd_mcdt_adc_dma_enable(mcdt, chan->id, false);
    842		sprd_mcdt_adc_fifo_clear(mcdt, chan->id);
    843		break;
    844
    845	case SPRD_MCDT_DAC_CHAN:
    846		sprd_mcdt_dac_dma_enable(mcdt, chan->id, false);
    847		sprd_mcdt_dac_fifo_clear(mcdt, chan->id);
    848		break;
    849
    850	default:
    851		break;
    852	}
    853
    854	chan->dma_enable = false;
    855	spin_unlock_irqrestore(&mcdt->lock, flags);
    856}
    857EXPORT_SYMBOL_GPL(sprd_mcdt_chan_dma_disable);
    858
    859/**
    860 * sprd_mcdt_request_chan - request one MCDT channel
    861 * @channel: channel id
    862 * @type: channel type, it can be one ADC channel or DAC channel
    863 *
    864 * Rreturn NULL if no available channel.
    865 */
    866struct sprd_mcdt_chan *sprd_mcdt_request_chan(u8 channel,
    867					      enum sprd_mcdt_channel_type type)
    868{
    869	struct sprd_mcdt_chan *temp;
    870
    871	mutex_lock(&sprd_mcdt_list_mutex);
    872
    873	list_for_each_entry(temp, &sprd_mcdt_chan_list, list) {
    874		if (temp->type == type && temp->id == channel) {
    875			list_del_init(&temp->list);
    876			break;
    877		}
    878	}
    879
    880	if (list_entry_is_head(temp, &sprd_mcdt_chan_list, list))
    881		temp = NULL;
    882
    883	mutex_unlock(&sprd_mcdt_list_mutex);
    884
    885	return temp;
    886}
    887EXPORT_SYMBOL_GPL(sprd_mcdt_request_chan);
    888
    889/**
    890 * sprd_mcdt_free_chan - free one MCDT channel
    891 * @chan: the channel to be freed
    892 */
    893void sprd_mcdt_free_chan(struct sprd_mcdt_chan *chan)
    894{
    895	struct sprd_mcdt_chan *temp;
    896
    897	sprd_mcdt_chan_dma_disable(chan);
    898	sprd_mcdt_chan_int_disable(chan);
    899
    900	mutex_lock(&sprd_mcdt_list_mutex);
    901
    902	list_for_each_entry(temp, &sprd_mcdt_chan_list, list) {
    903		if (temp == chan) {
    904			mutex_unlock(&sprd_mcdt_list_mutex);
    905			return;
    906		}
    907	}
    908
    909	list_add_tail(&chan->list, &sprd_mcdt_chan_list);
    910	mutex_unlock(&sprd_mcdt_list_mutex);
    911}
    912EXPORT_SYMBOL_GPL(sprd_mcdt_free_chan);
    913
    914static void sprd_mcdt_init_chans(struct sprd_mcdt_dev *mcdt,
    915				 struct resource *res)
    916{
    917	int i;
    918
    919	for (i = 0; i < MCDT_CHANNEL_NUM; i++) {
    920		struct sprd_mcdt_chan *chan = &mcdt->chan[i];
    921
    922		if (i < MCDT_ADC_CHANNEL_NUM) {
    923			chan->id = i;
    924			chan->type = SPRD_MCDT_ADC_CHAN;
    925			chan->fifo_phys = res->start + MCDT_CH0_RXD + i * 4;
    926		} else {
    927			chan->id = i - MCDT_ADC_CHANNEL_NUM;
    928			chan->type = SPRD_MCDT_DAC_CHAN;
    929			chan->fifo_phys = res->start + MCDT_CH0_TXD +
    930				(i - MCDT_ADC_CHANNEL_NUM) * 4;
    931		}
    932
    933		chan->mcdt = mcdt;
    934		INIT_LIST_HEAD(&chan->list);
    935
    936		mutex_lock(&sprd_mcdt_list_mutex);
    937		list_add_tail(&chan->list, &sprd_mcdt_chan_list);
    938		mutex_unlock(&sprd_mcdt_list_mutex);
    939	}
    940}
    941
    942static int sprd_mcdt_probe(struct platform_device *pdev)
    943{
    944	struct sprd_mcdt_dev *mcdt;
    945	struct resource *res;
    946	int ret, irq;
    947
    948	mcdt = devm_kzalloc(&pdev->dev, sizeof(*mcdt), GFP_KERNEL);
    949	if (!mcdt)
    950		return -ENOMEM;
    951
    952	mcdt->base = devm_platform_get_and_ioremap_resource(pdev, 0, &res);
    953	if (IS_ERR(mcdt->base))
    954		return PTR_ERR(mcdt->base);
    955
    956	mcdt->dev = &pdev->dev;
    957	spin_lock_init(&mcdt->lock);
    958	platform_set_drvdata(pdev, mcdt);
    959
    960	irq = platform_get_irq(pdev, 0);
    961	if (irq < 0)
    962		return irq;
    963
    964	ret = devm_request_irq(&pdev->dev, irq, sprd_mcdt_irq_handler,
    965			       0, "sprd-mcdt", mcdt);
    966	if (ret) {
    967		dev_err(&pdev->dev, "Failed to request MCDT IRQ\n");
    968		return ret;
    969	}
    970
    971	sprd_mcdt_init_chans(mcdt, res);
    972
    973	return 0;
    974}
    975
    976static int sprd_mcdt_remove(struct platform_device *pdev)
    977{
    978	struct sprd_mcdt_chan *chan, *temp;
    979
    980	mutex_lock(&sprd_mcdt_list_mutex);
    981
    982	list_for_each_entry_safe(chan, temp, &sprd_mcdt_chan_list, list)
    983		list_del(&chan->list);
    984
    985	mutex_unlock(&sprd_mcdt_list_mutex);
    986
    987	return 0;
    988}
    989
    990static const struct of_device_id sprd_mcdt_of_match[] = {
    991	{ .compatible = "sprd,sc9860-mcdt", },
    992	{ }
    993};
    994MODULE_DEVICE_TABLE(of, sprd_mcdt_of_match);
    995
    996static struct platform_driver sprd_mcdt_driver = {
    997	.probe = sprd_mcdt_probe,
    998	.remove = sprd_mcdt_remove,
    999	.driver = {
   1000		.name = "sprd-mcdt",
   1001		.of_match_table = sprd_mcdt_of_match,
   1002	},
   1003};
   1004
   1005module_platform_driver(sprd_mcdt_driver);
   1006
   1007MODULE_DESCRIPTION("Spreadtrum Multi-Channel Data Transfer Driver");
   1008MODULE_LICENSE("GPL v2");