xref: /optee_os/core/drivers/ls_dspi.c (revision 3513f2697ad48668328c6a74621d3acf05b33fd3)
1*3513f269SManish Tomar // SPDX-License-Identifier: BSD-2-Clause
2*3513f269SManish Tomar /*
3*3513f269SManish Tomar  * Copyright 2021 NXP
4*3513f269SManish Tomar  *
5*3513f269SManish Tomar  * Driver for DSPI Controller
6*3513f269SManish Tomar  *
7*3513f269SManish Tomar  */
8*3513f269SManish Tomar 
9*3513f269SManish Tomar #include <assert.h>
10*3513f269SManish Tomar #include <drivers/ls_dspi.h>
11*3513f269SManish Tomar #include <io.h>
12*3513f269SManish Tomar #include <kernel/boot.h>
13*3513f269SManish Tomar #include <kernel/delay.h>
14*3513f269SManish Tomar #include <kernel/dt.h>
15*3513f269SManish Tomar #include <libfdt.h>
16*3513f269SManish Tomar #include <mm/core_memprot.h>
17*3513f269SManish Tomar #include <platform_config.h>
18*3513f269SManish Tomar #include <util.h>
19*3513f269SManish Tomar 
20*3513f269SManish Tomar /* SPI register offset */
21*3513f269SManish Tomar #define DSPI_MCR	0x0 /* Module Configuration Register */
22*3513f269SManish Tomar #define DSPI_TCR	0x8 /* Transfer Count Register */
23*3513f269SManish Tomar #define DSPI_CTAR0 \
24*3513f269SManish Tomar 	0xC /* Clock and Transfer Attributes Register (in Master mode) */
25*3513f269SManish Tomar #define DSPI_CTAR1 \
26*3513f269SManish Tomar 	0x10 /* Clock and Transfer Attributes Register (in Master mode) */
27*3513f269SManish Tomar #define DSPI_SR     0x2C  /* Status Register */
28*3513f269SManish Tomar #define DSPI_RSER   0x30  /* DMA/Interrupt Request Select and Enable Register */
29*3513f269SManish Tomar #define DSPI_PUSHR  0x34  /* PUSH TX FIFO Register In Master Mode */
30*3513f269SManish Tomar #define DSPI_POPR   0x38  /* POP RX FIFO Register */
31*3513f269SManish Tomar #define DSPI_TXFR0  0x3C  /* Transmit FIFO Registers */
32*3513f269SManish Tomar #define DSPI_TXFR1  0x40  /* Transmit FIFO Registers */
33*3513f269SManish Tomar #define DSPI_TXFR2  0x44  /* Transmit FIFO Registers */
34*3513f269SManish Tomar #define DSPI_TXFR3  0x48  /* Transmit FIFO Registers */
35*3513f269SManish Tomar #define DSPI_RXFR0  0x7C  /* Receive FIFO Registers */
36*3513f269SManish Tomar #define DSPI_RXFR1  0x80  /* Receive FIFO Registers */
37*3513f269SManish Tomar #define DSPI_RXFR2  0x84  /* Receive FIFO Registers */
38*3513f269SManish Tomar #define DSPI_RXFR3  0x88  /* Receive FIFO Registers */
39*3513f269SManish Tomar #define DSPI_CTARE0 0x11C /* Clock and Transfer Attributes Register Extended */
40*3513f269SManish Tomar #define DSPI_CTARE1 0x120 /* Clock and Transfer Attributes Register Extended */
41*3513f269SManish Tomar #define DSPI_SREX   0x13C /* Status Register Extended */
42*3513f269SManish Tomar 
43*3513f269SManish Tomar /* Module configuration */
44*3513f269SManish Tomar #define DSPI_MCR_MSTR	0x80000000         /* Master/Slave Mode Select [0] */
45*3513f269SManish Tomar #define DSPI_MCR_CSCK	0x40000000         /* Continuous SCK Enable [1] */
46*3513f269SManish Tomar #define DSPI_MCR_DCONF(x) (((x) & 0x03) << 28) /* SPI Configuration [2-3] */
47*3513f269SManish Tomar #define DSPI_MCR_ROOE	\
48*3513f269SManish Tomar 	0x01000000 /* Receive FIFO Overflow Overwrite Enable[7] */
49*3513f269SManish Tomar #define DSPI_MCR_PCSIS(x) \
50*3513f269SManish Tomar 	(1 << (16 + (x))) /* Peripheral Chip Select x Inactive State [12-15] */
51*3513f269SManish Tomar #define DSPI_MCR_PCSIS_MASK (0xff << 16)
52*3513f269SManish Tomar #define DSPI_MCR_MDIS       0x00004000 /* Module Disable [17] */
53*3513f269SManish Tomar #define DSPI_MCR_DTXF       0x00002000 /* Disable Transmit FIFO [18] */
54*3513f269SManish Tomar #define DSPI_MCR_DRXF       0x00001000 /* Disable Receive FIFO [19] */
55*3513f269SManish Tomar #define DSPI_MCR_CTXF       0x00000800 /* Clear TX FIFO [20] */
56*3513f269SManish Tomar #define DSPI_MCR_CRXF       0x00000400 /* Clear RX FIFO [21] */
57*3513f269SManish Tomar #define DPSI_XSPI           0x00000008 /* Extended SPI Mode [28] */
58*3513f269SManish Tomar #define DSPI_MCR_PES        0x00000002 /* Parity Error Stop [30] */
59*3513f269SManish Tomar #define DSPI_MCR_HALT       0x00000001 /* Halt [31] */
60*3513f269SManish Tomar #define DPSI_ENABLE         0x0
61*3513f269SManish Tomar #define DSPI_DISABLE        0x1
62*3513f269SManish Tomar 
63*3513f269SManish Tomar /* Transfer count */
64*3513f269SManish Tomar #define DSPI_TCR_SPI_TCNT(x) (((x) & 0x0000FFFF) << 16)
65*3513f269SManish Tomar 
66*3513f269SManish Tomar /* Status */
67*3513f269SManish Tomar #define DSPI_SR_TXRXS    0x40000000               /* TX and RX Status [1] */
68*3513f269SManish Tomar #define DSPI_SR_TXCTR(x) \
69*3513f269SManish Tomar 	(((x) & 0x0000F000) >> 12) /* TX FIFO Counter [16-19] */
70*3513f269SManish Tomar #define DSPI_SR_RXCTR(x) \
71*3513f269SManish Tomar 	(((x) & 0x000000F0) >> 4)  /* RX FIFO Counter [24-27] */
72*3513f269SManish Tomar 
73*3513f269SManish Tomar #define DSPI_DATA_8BIT  SHIFT_U32(8, 0)
74*3513f269SManish Tomar #define DSPI_DATA_16BIT SHIFT_U32(0xF, 0)
75*3513f269SManish Tomar 
76*3513f269SManish Tomar #define DSPI_TFR_CONT    (0x80000000)
77*3513f269SManish Tomar #define DSPI_TFR_CTAS(x) (((x) & 0x07) << 12)
78*3513f269SManish Tomar #define DSPI_TFR_PCS(x)  (((1 << (x)) & 0x0000003f) << 16)
79*3513f269SManish Tomar #define DSPI_IDLE_DATA   0x0
80*3513f269SManish Tomar 
81*3513f269SManish Tomar /* tx/rx data wait timeout value, unit: us */
82*3513f269SManish Tomar #define DSPI_TXRX_WAIT_TIMEOUT 1000000
83*3513f269SManish Tomar 
84*3513f269SManish Tomar /* Transfer Fifo */
85*3513f269SManish Tomar #define DSPI_TFR_TXDATA(x) (((x) & 0x0000FFFF))
86*3513f269SManish Tomar 
87*3513f269SManish Tomar /* Bit definitions and macros for DRFR */
88*3513f269SManish Tomar #define DSPI_RFR_RXDATA(x) (((x) & 0x0000FFFF))
89*3513f269SManish Tomar 
90*3513f269SManish Tomar /* CTAR register pre-configure mask */
91*3513f269SManish Tomar #define DSPI_CTAR_SET_MODE_MASK \
92*3513f269SManish Tomar 	(DSPI_CTAR_FMSZ(15) | DSPI_CTAR_PCS_SCK(3) | DSPI_CTAR_PA_SCK(3) | \
93*3513f269SManish Tomar 	 DSPI_CTAR_P_DT(3) | DSPI_CTAR_CS_SCK(15) | DSPI_CTAR_A_SCK(15) | \
94*3513f269SManish Tomar 	 DSPI_CTAR_A_DT(15))
95*3513f269SManish Tomar 
96*3513f269SManish Tomar /* SPI mode flags */
97*3513f269SManish Tomar #define SPI_CPHA      BIT(0) /* clock phase */
98*3513f269SManish Tomar #define SPI_CPOL      BIT(1) /* clock polarity */
99*3513f269SManish Tomar #define SPI_CS_HIGH   BIT(2) /* CS active high */
100*3513f269SManish Tomar #define SPI_LSB_FIRST BIT(3) /* per-word bits-on-wire */
101*3513f269SManish Tomar #define SPI_CONT      BIT(4) /* Continuous CS mode */
102*3513f269SManish Tomar 
103*3513f269SManish Tomar /* default SCK frequency, unit: HZ */
104*3513f269SManish Tomar #define PLATFORM_CLK          650000000
105*3513f269SManish Tomar #define DSPI_DEFAULT_SCK_FREQ 10000000
106*3513f269SManish Tomar #define DSPI_CLK_DIV          4 /* prescaler divisor */
107*3513f269SManish Tomar #define DSPI_CLK              (PLATFORM_CLK / DSPI_CLK_DIV) /* DSPI clock */
108*3513f269SManish Tomar #define CS_SPEED_MAX_HZ       1000000   /* Slave max speed */
109*3513f269SManish Tomar 
110*3513f269SManish Tomar /*
111*3513f269SManish Tomar  * Calculate the divide scaler value between expected SCK frequency
112*3513f269SManish Tomar  * and input clk frequency
113*3513f269SManish Tomar  * req_pbr:	pre-scaler value of baud rate for slave
114*3513f269SManish Tomar  * req_br:	scaler value of baud rate for slave
115*3513f269SManish Tomar  * speed_hz:	speed value of slave
116*3513f269SManish Tomar  * clkrate:	clock value of slave
117*3513f269SManish Tomar  */
118*3513f269SManish Tomar static TEE_Result dspi_convert_hz_to_baud(unsigned int *req_pbr,
119*3513f269SManish Tomar 					  unsigned int *req_br,
120*3513f269SManish Tomar 					  unsigned int speed_hz,
121*3513f269SManish Tomar 					  unsigned int clkrate)
122*3513f269SManish Tomar {
123*3513f269SManish Tomar 	/* Valid pre-scaler values for baud rate*/
124*3513f269SManish Tomar 	static const unsigned int pbr_val[4] = { 2, 3, 5, 7 };
125*3513f269SManish Tomar 	/* Valid baud rate scaler values*/
126*3513f269SManish Tomar 	static const unsigned int brs_val[16] = { 2, 4, 6, 8,
127*3513f269SManish Tomar 						16, 32, 64, 128,
128*3513f269SManish Tomar 						256, 512, 1024, 2048,
129*3513f269SManish Tomar 						4096, 8192, 16384, 32768 };
130*3513f269SManish Tomar 	unsigned int tmp_val = 0;
131*3513f269SManish Tomar 	unsigned int curr_val = 0;
132*3513f269SManish Tomar 	unsigned int i = 0;
133*3513f269SManish Tomar 	unsigned int j = 0;
134*3513f269SManish Tomar 
135*3513f269SManish Tomar 	tmp_val = clkrate / speed_hz;
136*3513f269SManish Tomar 
137*3513f269SManish Tomar 	for (i = 0; i < ARRAY_SIZE(pbr_val); i++) {
138*3513f269SManish Tomar 		for (j = 0; j < ARRAY_SIZE(brs_val); j++) {
139*3513f269SManish Tomar 			curr_val = pbr_val[i] * brs_val[j];
140*3513f269SManish Tomar 			if (curr_val >= tmp_val) {
141*3513f269SManish Tomar 				*req_pbr = i;
142*3513f269SManish Tomar 				*req_br = j;
143*3513f269SManish Tomar 				return TEE_SUCCESS;
144*3513f269SManish Tomar 			}
145*3513f269SManish Tomar 		}
146*3513f269SManish Tomar 	}
147*3513f269SManish Tomar 
148*3513f269SManish Tomar 	EMSG("Can not find valid baud rate, speed_hz is %d, ", speed_hz);
149*3513f269SManish Tomar 	EMSG("clkrate is %d, using max prescaler value", clkrate);
150*3513f269SManish Tomar 
151*3513f269SManish Tomar 	return TEE_ERROR_ITEM_NOT_FOUND;
152*3513f269SManish Tomar }
153*3513f269SManish Tomar 
154*3513f269SManish Tomar /*
155*3513f269SManish Tomar  * Configure speed of slave
156*3513f269SManish Tomar  * dspi_data:	DSPI controller chip instance
157*3513f269SManish Tomar  * speed:	speed of slave
158*3513f269SManish Tomar  */
159*3513f269SManish Tomar static void dspi_setup_speed(struct ls_dspi_data *dspi_data,
160*3513f269SManish Tomar 			     unsigned int speed)
161*3513f269SManish Tomar {
162*3513f269SManish Tomar 	TEE_Result status = TEE_ERROR_GENERIC;
163*3513f269SManish Tomar 	unsigned int bus_setup = 0;
164*3513f269SManish Tomar 	unsigned int bus_clock = 0;
165*3513f269SManish Tomar 	unsigned int req_i = 0;
166*3513f269SManish Tomar 	unsigned int req_j = 0;
167*3513f269SManish Tomar 
168*3513f269SManish Tomar 	bus_clock = dspi_data->bus_clk_hz;
169*3513f269SManish Tomar 
170*3513f269SManish Tomar 	DMSG("DSPI set_speed: expected SCK speed %u, bus_clk %u", speed,
171*3513f269SManish Tomar 	     bus_clock);
172*3513f269SManish Tomar 
173*3513f269SManish Tomar 	bus_setup = io_read32(dspi_data->base + DSPI_CTAR0);
174*3513f269SManish Tomar 	bus_setup &= ~(DSPI_CTAR_BRD | DSPI_CTAR_BRP(0x3) | DSPI_CTAR_BR(0xf));
175*3513f269SManish Tomar 
176*3513f269SManish Tomar 	status = dspi_convert_hz_to_baud(&req_i, &req_j, speed, bus_clock);
177*3513f269SManish Tomar 
178*3513f269SManish Tomar 	/* In case of failure scenario with max speed, setting default speed */
179*3513f269SManish Tomar 	if (status == TEE_ERROR_ITEM_NOT_FOUND) {
180*3513f269SManish Tomar 		speed = dspi_data->speed_hz;
181*3513f269SManish Tomar 		status = dspi_convert_hz_to_baud(&req_i, &req_j,
182*3513f269SManish Tomar 						 speed, bus_clock);
183*3513f269SManish Tomar 	}
184*3513f269SManish Tomar 
185*3513f269SManish Tomar 	if (status == TEE_SUCCESS) {
186*3513f269SManish Tomar 		bus_setup |= (DSPI_CTAR_BRP(req_i) | DSPI_CTAR_BR(req_j));
187*3513f269SManish Tomar 		io_write32(dspi_data->base + DSPI_CTAR0, bus_setup);
188*3513f269SManish Tomar 		dspi_data->speed_hz = speed;
189*3513f269SManish Tomar 	} else {
190*3513f269SManish Tomar 		EMSG("Unable to set speed");
191*3513f269SManish Tomar 	}
192*3513f269SManish Tomar }
193*3513f269SManish Tomar 
194*3513f269SManish Tomar /*
195*3513f269SManish Tomar  * Transferred data to TX FIFO
196*3513f269SManish Tomar  * dspi_data:	DSPI controller chip instance
197*3513f269SManish Tomar  */
198*3513f269SManish Tomar static void dspi_tx(struct ls_dspi_data *dspi_data, uint32_t ctrl,
199*3513f269SManish Tomar 		    uint16_t data)
200*3513f269SManish Tomar {
201*3513f269SManish Tomar 	int timeout = DSPI_TXRX_WAIT_TIMEOUT;
202*3513f269SManish Tomar 	uint32_t dspi_val_addr = dspi_data->base + DSPI_PUSHR;
203*3513f269SManish Tomar 	uint32_t dspi_val = ctrl | data;
204*3513f269SManish Tomar 
205*3513f269SManish Tomar 	/* wait for empty entries in TXFIFO or timeout */
206*3513f269SManish Tomar 	while (DSPI_SR_TXCTR(io_read32(dspi_data->base + DSPI_SR)) >= 4 &&
207*3513f269SManish Tomar 	       timeout--)
208*3513f269SManish Tomar 		udelay(1);
209*3513f269SManish Tomar 
210*3513f269SManish Tomar 	if (timeout >= 0)
211*3513f269SManish Tomar 		io_write32(dspi_val_addr, dspi_val);
212*3513f269SManish Tomar 	else
213*3513f269SManish Tomar 		EMSG("waiting timeout!");
214*3513f269SManish Tomar }
215*3513f269SManish Tomar 
216*3513f269SManish Tomar /*
217*3513f269SManish Tomar  * Read data from RX FIFO
218*3513f269SManish Tomar  * dspi_data:	DSPI controller chip instance
219*3513f269SManish Tomar  */
220*3513f269SManish Tomar static uint16_t dspi_rx(struct ls_dspi_data *dspi_data)
221*3513f269SManish Tomar {
222*3513f269SManish Tomar 	int timeout = DSPI_TXRX_WAIT_TIMEOUT;
223*3513f269SManish Tomar 	uint32_t dspi_val_addr = dspi_data->base + DSPI_POPR;
224*3513f269SManish Tomar 
225*3513f269SManish Tomar 	/* wait for valid entries in RXFIFO or timeout */
226*3513f269SManish Tomar 	while (DSPI_SR_RXCTR(io_read32(dspi_data->base + DSPI_SR)) == 0 &&
227*3513f269SManish Tomar 	       timeout--)
228*3513f269SManish Tomar 		udelay(1);
229*3513f269SManish Tomar 
230*3513f269SManish Tomar 	if (timeout >= 0)
231*3513f269SManish Tomar 		return (uint16_t)DSPI_RFR_RXDATA(io_read32(dspi_val_addr));
232*3513f269SManish Tomar 
233*3513f269SManish Tomar 	EMSG("waiting timeout!");
234*3513f269SManish Tomar 
235*3513f269SManish Tomar 	return 0xFFFF;
236*3513f269SManish Tomar }
237*3513f269SManish Tomar 
238*3513f269SManish Tomar /*
239*3513f269SManish Tomar  * Transfer and Receive 8-bit data
240*3513f269SManish Tomar  * chip:	spi_chip instance
241*3513f269SManish Tomar  * wdata:	TX data queue
242*3513f269SManish Tomar  * rdata:	RX data queue
243*3513f269SManish Tomar  * num_pkts:	number of data packets
244*3513f269SManish Tomar  */
245*3513f269SManish Tomar static enum spi_result ls_dspi_txrx8(struct spi_chip *chip, uint8_t *wdata,
246*3513f269SManish Tomar 				     uint8_t *rdata, size_t num_pkts)
247*3513f269SManish Tomar {
248*3513f269SManish Tomar 	uint8_t *spi_rd = NULL;
249*3513f269SManish Tomar 	uint8_t *spi_wr = NULL;
250*3513f269SManish Tomar 	uint32_t ctrl = 0;
251*3513f269SManish Tomar 	struct ls_dspi_data *data = container_of(chip, struct ls_dspi_data,
252*3513f269SManish Tomar 						  chip);
253*3513f269SManish Tomar 	unsigned int cs = data->slave_cs;
254*3513f269SManish Tomar 
255*3513f269SManish Tomar 	spi_wr = wdata;
256*3513f269SManish Tomar 	spi_rd = rdata;
257*3513f269SManish Tomar 
258*3513f269SManish Tomar 	/*
259*3513f269SManish Tomar 	 * Assert PCSn signals between transfers
260*3513f269SManish Tomar 	 * select which CTAR register and slave to be used for TX
261*3513f269SManish Tomar 	 * CTAS selects which CTAR to be used, here we are using CTAR0
262*3513f269SManish Tomar 	 * PCS (peripheral chip select) is selecting the slave.
263*3513f269SManish Tomar 	 */
264*3513f269SManish Tomar 	ctrl = DSPI_TFR_CTAS(data->ctar_sel) | DSPI_TFR_PCS(cs);
265*3513f269SManish Tomar 	if (data->slave_mode & SPI_CONT)
266*3513f269SManish Tomar 		ctrl |= DSPI_TFR_CONT;
267*3513f269SManish Tomar 
268*3513f269SManish Tomar 	if (data->slave_data_size_bits != 8) {
269*3513f269SManish Tomar 		EMSG("data_size_bits should be 8, not %u",
270*3513f269SManish Tomar 		     data->slave_data_size_bits);
271*3513f269SManish Tomar 		return SPI_ERR_CFG;
272*3513f269SManish Tomar 	}
273*3513f269SManish Tomar 
274*3513f269SManish Tomar 	while (num_pkts) {
275*3513f269SManish Tomar 		if (wdata && rdata) {
276*3513f269SManish Tomar 			dspi_tx(data, ctrl, *spi_wr++);
277*3513f269SManish Tomar 			*spi_rd++ = dspi_rx(data);
278*3513f269SManish Tomar 		} else if (wdata) {
279*3513f269SManish Tomar 			dspi_tx(data, ctrl, *spi_wr++);
280*3513f269SManish Tomar 			dspi_rx(data);
281*3513f269SManish Tomar 		} else if (rdata) {
282*3513f269SManish Tomar 			dspi_tx(data, ctrl, DSPI_IDLE_DATA);
283*3513f269SManish Tomar 			*spi_rd++ = dspi_rx(data);
284*3513f269SManish Tomar 		}
285*3513f269SManish Tomar 		num_pkts = num_pkts - 1;
286*3513f269SManish Tomar 	}
287*3513f269SManish Tomar 
288*3513f269SManish Tomar 	return SPI_OK;
289*3513f269SManish Tomar }
290*3513f269SManish Tomar 
291*3513f269SManish Tomar /*
292*3513f269SManish Tomar  * Transfer and Receive 16-bit data
293*3513f269SManish Tomar  * chip:        spi_chip instance
294*3513f269SManish Tomar  * wdata:	TX data queue
295*3513f269SManish Tomar  * rdata:	RX data queue
296*3513f269SManish Tomar  * num_pkts:	number of data packets
297*3513f269SManish Tomar  */
298*3513f269SManish Tomar static enum spi_result ls_dspi_txrx16(struct spi_chip *chip, uint16_t *wdata,
299*3513f269SManish Tomar 				      uint16_t *rdata, size_t num_pkts)
300*3513f269SManish Tomar {
301*3513f269SManish Tomar 	uint32_t ctrl = 0;
302*3513f269SManish Tomar 	uint16_t *spi_rd = NULL;
303*3513f269SManish Tomar 	uint16_t *spi_wr = NULL;
304*3513f269SManish Tomar 	struct ls_dspi_data *data = container_of(chip, struct ls_dspi_data,
305*3513f269SManish Tomar 						  chip);
306*3513f269SManish Tomar 	unsigned int cs = data->slave_cs;
307*3513f269SManish Tomar 
308*3513f269SManish Tomar 	spi_wr = wdata;
309*3513f269SManish Tomar 	spi_rd = rdata;
310*3513f269SManish Tomar 
311*3513f269SManish Tomar 	/*
312*3513f269SManish Tomar 	 * Assert PCSn signals between transfers
313*3513f269SManish Tomar 	 * select which CTAR register and slave to be used for TX
314*3513f269SManish Tomar 	 * CTAS selects which CTAR to be used, here we are using CTAR0
315*3513f269SManish Tomar 	 * PCS (peripheral chip select) is selecting the slave.
316*3513f269SManish Tomar 	 */
317*3513f269SManish Tomar 	ctrl = DSPI_TFR_CTAS(data->ctar_sel) | DSPI_TFR_PCS(cs);
318*3513f269SManish Tomar 	if (data->slave_mode & SPI_CONT)
319*3513f269SManish Tomar 		ctrl |= DSPI_TFR_CONT;
320*3513f269SManish Tomar 
321*3513f269SManish Tomar 	if (data->slave_data_size_bits != 16) {
322*3513f269SManish Tomar 		EMSG("data_size_bits should be 16, not %u",
323*3513f269SManish Tomar 		     data->slave_data_size_bits);
324*3513f269SManish Tomar 		return SPI_ERR_CFG;
325*3513f269SManish Tomar 	}
326*3513f269SManish Tomar 
327*3513f269SManish Tomar 	while (num_pkts) {
328*3513f269SManish Tomar 		if (wdata && rdata) {
329*3513f269SManish Tomar 			dspi_tx(data, ctrl, *spi_wr++);
330*3513f269SManish Tomar 			*spi_rd++ = dspi_rx(data);
331*3513f269SManish Tomar 		} else if (wdata) {
332*3513f269SManish Tomar 			dspi_tx(data, ctrl, *spi_wr++);
333*3513f269SManish Tomar 			dspi_rx(data);
334*3513f269SManish Tomar 		} else if (rdata) {
335*3513f269SManish Tomar 			dspi_tx(data, ctrl, DSPI_IDLE_DATA);
336*3513f269SManish Tomar 			*spi_rd++ = dspi_rx(data);
337*3513f269SManish Tomar 		}
338*3513f269SManish Tomar 		num_pkts = num_pkts - 1;
339*3513f269SManish Tomar 	}
340*3513f269SManish Tomar 
341*3513f269SManish Tomar 	return SPI_OK;
342*3513f269SManish Tomar }
343*3513f269SManish Tomar 
344*3513f269SManish Tomar /*
345*3513f269SManish Tomar  * Statrt DSPI module
346*3513f269SManish Tomar  * chip:	spi_chip instance
347*3513f269SManish Tomar  */
348*3513f269SManish Tomar static void ls_dspi_start(struct spi_chip *chip)
349*3513f269SManish Tomar {
350*3513f269SManish Tomar 	struct ls_dspi_data *data = container_of(chip, struct ls_dspi_data,
351*3513f269SManish Tomar 						  chip);
352*3513f269SManish Tomar 
353*3513f269SManish Tomar 	DMSG("Start DSPI Module");
354*3513f269SManish Tomar 	io_clrbits32(data->base + DSPI_MCR, DSPI_MCR_HALT);
355*3513f269SManish Tomar }
356*3513f269SManish Tomar 
357*3513f269SManish Tomar /*
358*3513f269SManish Tomar  * Stop DSPI module
359*3513f269SManish Tomar  * chip:	spi_chip instance
360*3513f269SManish Tomar  */
361*3513f269SManish Tomar static void ls_dspi_end(struct spi_chip *chip)
362*3513f269SManish Tomar {
363*3513f269SManish Tomar 	struct ls_dspi_data *data = container_of(chip, struct ls_dspi_data,
364*3513f269SManish Tomar 						  chip);
365*3513f269SManish Tomar 
366*3513f269SManish Tomar 	/* De-assert PCSn if in CONT mode */
367*3513f269SManish Tomar 	if (data->slave_mode & SPI_CONT) {
368*3513f269SManish Tomar 		unsigned int cs = data->slave_cs;
369*3513f269SManish Tomar 		unsigned int ctrl = DSPI_TFR_CTAS(data->ctar_sel) |
370*3513f269SManish Tomar 				    DSPI_TFR_PCS(cs);
371*3513f269SManish Tomar 
372*3513f269SManish Tomar 		/* Dummy read to deassert */
373*3513f269SManish Tomar 		dspi_tx(data, ctrl, DSPI_IDLE_DATA);
374*3513f269SManish Tomar 		dspi_rx(data);
375*3513f269SManish Tomar 	}
376*3513f269SManish Tomar 
377*3513f269SManish Tomar 	DMSG("Stop DSPI Module");
378*3513f269SManish Tomar 	io_setbits32(data->base + DSPI_MCR, DSPI_MCR_HALT);
379*3513f269SManish Tomar }
380*3513f269SManish Tomar 
381*3513f269SManish Tomar /*
382*3513f269SManish Tomar  * Clear RX and TX FIFO
383*3513f269SManish Tomar  * dspi_data:   DSPI controller chip instance
384*3513f269SManish Tomar  */
385*3513f269SManish Tomar void dspi_flush_fifo(struct ls_dspi_data *dspi_data)
386*3513f269SManish Tomar {
387*3513f269SManish Tomar 	unsigned int mcr_val = 0;
388*3513f269SManish Tomar 
389*3513f269SManish Tomar 	mcr_val = io_read32(dspi_data->base + DSPI_MCR);
390*3513f269SManish Tomar 	/* flush RX and TX FIFO */
391*3513f269SManish Tomar 	mcr_val |= (DSPI_MCR_CTXF | DSPI_MCR_CRXF);
392*3513f269SManish Tomar 
393*3513f269SManish Tomar 	io_write32(dspi_data->base + DSPI_MCR, mcr_val);
394*3513f269SManish Tomar }
395*3513f269SManish Tomar 
396*3513f269SManish Tomar /*
397*3513f269SManish Tomar  * Configure active state of slave
398*3513f269SManish Tomar  * dspi_data:   DSPI controller chip instance
399*3513f269SManish Tomar  * cs:		chip select value of slave
400*3513f269SManish Tomar  * state:	slave mode
401*3513f269SManish Tomar  */
402*3513f269SManish Tomar static void dspi_set_cs_active_state(struct ls_dspi_data *dspi_data,
403*3513f269SManish Tomar 				     unsigned int cs, unsigned int state)
404*3513f269SManish Tomar {
405*3513f269SManish Tomar 	DMSG("Set CS active state cs=%d state=%d", cs, state);
406*3513f269SManish Tomar 
407*3513f269SManish Tomar 	if (state & SPI_CS_HIGH)
408*3513f269SManish Tomar 		/* CSx inactive state is low */
409*3513f269SManish Tomar 		io_clrbits32(dspi_data->base + DSPI_MCR, DSPI_MCR_PCSIS(cs));
410*3513f269SManish Tomar 	else
411*3513f269SManish Tomar 		/* CSx inactive state is high */
412*3513f269SManish Tomar 		io_setbits32(dspi_data->base + DSPI_MCR, DSPI_MCR_PCSIS(cs));
413*3513f269SManish Tomar }
414*3513f269SManish Tomar 
415*3513f269SManish Tomar /*
416*3513f269SManish Tomar  * Configure transfer state of slave
417*3513f269SManish Tomar  * dspi_data:   DSPI controller chip instance
418*3513f269SManish Tomar  * state:	slave mode
419*3513f269SManish Tomar  */
420*3513f269SManish Tomar static void dspi_set_transfer_state(struct ls_dspi_data *dspi_data,
421*3513f269SManish Tomar 				    unsigned int state)
422*3513f269SManish Tomar {
423*3513f269SManish Tomar 	unsigned int bus_setup = 0;
424*3513f269SManish Tomar 
425*3513f269SManish Tomar 	DMSG("Set transfer state=%d bits=%d", state,
426*3513f269SManish Tomar 	     dspi_data->slave_data_size_bits);
427*3513f269SManish Tomar 
428*3513f269SManish Tomar 	bus_setup = io_read32(dspi_data->base + DSPI_CTAR0);
429*3513f269SManish Tomar 	bus_setup &= ~DSPI_CTAR_SET_MODE_MASK;
430*3513f269SManish Tomar 	bus_setup |= dspi_data->ctar_val;
431*3513f269SManish Tomar 	bus_setup &= ~(DSPI_CTAR_CPOL | DSPI_CTAR_CPHA | DSPI_CTAR_LSBFE);
432*3513f269SManish Tomar 
433*3513f269SManish Tomar 	if (state & SPI_CPOL)
434*3513f269SManish Tomar 		bus_setup |= DSPI_CTAR_CPOL;
435*3513f269SManish Tomar 	if (state & SPI_CPHA)
436*3513f269SManish Tomar 		bus_setup |= DSPI_CTAR_CPHA;
437*3513f269SManish Tomar 	if (state & SPI_LSB_FIRST)
438*3513f269SManish Tomar 		bus_setup |= DSPI_CTAR_LSBFE;
439*3513f269SManish Tomar 
440*3513f269SManish Tomar 	if (dspi_data->slave_data_size_bits == 8)
441*3513f269SManish Tomar 		bus_setup |= DSPI_CTAR_FMSZ(7);
442*3513f269SManish Tomar 	else if (dspi_data->slave_data_size_bits == 16)
443*3513f269SManish Tomar 		bus_setup |= DSPI_CTAR_FMSZ(15);
444*3513f269SManish Tomar 
445*3513f269SManish Tomar 	if (dspi_data->ctar_sel == 0)
446*3513f269SManish Tomar 		io_write32(dspi_data->base + DSPI_CTAR0, bus_setup);
447*3513f269SManish Tomar 	else
448*3513f269SManish Tomar 		io_write32(dspi_data->base + DSPI_CTAR1, bus_setup);
449*3513f269SManish Tomar }
450*3513f269SManish Tomar 
451*3513f269SManish Tomar /*
452*3513f269SManish Tomar  * Configure speed of slave
453*3513f269SManish Tomar  * dspi_data:   DSPI controller chip instance
454*3513f269SManish Tomar  * speed_max_hz:        maximum speed for slave
455*3513f269SManish Tomar  */
456*3513f269SManish Tomar static void dspi_set_speed(struct ls_dspi_data *dspi_data,
457*3513f269SManish Tomar 			   unsigned int speed_max_hz)
458*3513f269SManish Tomar {
459*3513f269SManish Tomar 	dspi_setup_speed(dspi_data, speed_max_hz);
460*3513f269SManish Tomar }
461*3513f269SManish Tomar 
462*3513f269SManish Tomar /*
463*3513f269SManish Tomar  * Configure slave for DSPI controller
464*3513f269SManish Tomar  * dspi_data:		DSPI controller chip instance
465*3513f269SManish Tomar  * cs:			chip select value of slave
466*3513f269SManish Tomar  * speed_max_hz:	maximum speed of slave
467*3513f269SManish Tomar  * state:		slave mode
468*3513f269SManish Tomar  */
469*3513f269SManish Tomar static void dspi_config_slave_state(struct ls_dspi_data *dspi_data,
470*3513f269SManish Tomar 				    unsigned int cs, unsigned int speed_max_hz,
471*3513f269SManish Tomar 				    unsigned int state)
472*3513f269SManish Tomar {
473*3513f269SManish Tomar 	unsigned int sr_val = 0;
474*3513f269SManish Tomar 
475*3513f269SManish Tomar 	/* configure speed */
476*3513f269SManish Tomar 	dspi_set_speed(dspi_data, speed_max_hz);
477*3513f269SManish Tomar 
478*3513f269SManish Tomar 	/* configure transfer state */
479*3513f269SManish Tomar 	dspi_set_transfer_state(dspi_data, state);
480*3513f269SManish Tomar 
481*3513f269SManish Tomar 	/* configure active state of CSX */
482*3513f269SManish Tomar 	dspi_set_cs_active_state(dspi_data, cs, state);
483*3513f269SManish Tomar 
484*3513f269SManish Tomar 	/* clear FIFO */
485*3513f269SManish Tomar 	dspi_flush_fifo(dspi_data);
486*3513f269SManish Tomar 
487*3513f269SManish Tomar 	/* check module TX and RX status */
488*3513f269SManish Tomar 	sr_val = io_read32(dspi_data->base + DSPI_SR);
489*3513f269SManish Tomar 	if ((sr_val & DSPI_SR_TXRXS) != DSPI_SR_TXRXS)
490*3513f269SManish Tomar 		EMSG("DSPI RX/TX not ready");
491*3513f269SManish Tomar }
492*3513f269SManish Tomar 
493*3513f269SManish Tomar /*
494*3513f269SManish Tomar  * Configure master for DSPI controller
495*3513f269SManish Tomar  * dspi_data: DSPI controller chip instance
496*3513f269SManish Tomar  * mcr_val: value of master configuration register
497*3513f269SManish Tomar  */
498*3513f269SManish Tomar static void dspi_set_master_state(struct ls_dspi_data *dspi_data,
499*3513f269SManish Tomar 				  unsigned int mcr_val)
500*3513f269SManish Tomar {
501*3513f269SManish Tomar 	DMSG("Set master state val=0x%x", mcr_val);
502*3513f269SManish Tomar 	io_write32(dspi_data->base + DSPI_MCR, mcr_val);
503*3513f269SManish Tomar }
504*3513f269SManish Tomar 
505*3513f269SManish Tomar /*
506*3513f269SManish Tomar  * Configure DSPI controller
507*3513f269SManish Tomar  * chip: spi_chip instance
508*3513f269SManish Tomar  */
509*3513f269SManish Tomar static void ls_dspi_configure(struct spi_chip *chip)
510*3513f269SManish Tomar {
511*3513f269SManish Tomar 	struct ls_dspi_data *data = container_of(chip, struct ls_dspi_data,
512*3513f269SManish Tomar 						  chip);
513*3513f269SManish Tomar 	unsigned int mcr_cfg_val = 0;
514*3513f269SManish Tomar 
515*3513f269SManish Tomar 	mcr_cfg_val = DSPI_MCR_MSTR | DSPI_MCR_PCSIS_MASK | DSPI_MCR_CRXF |
516*3513f269SManish Tomar 		      DSPI_MCR_CTXF;
517*3513f269SManish Tomar 
518*3513f269SManish Tomar 	/* Configure Master */
519*3513f269SManish Tomar 	dspi_set_master_state(data, mcr_cfg_val);
520*3513f269SManish Tomar 
521*3513f269SManish Tomar 	/* Configure DSPI slave */
522*3513f269SManish Tomar 	dspi_config_slave_state(data, data->slave_cs, data->slave_speed_max_hz,
523*3513f269SManish Tomar 				data->slave_mode);
524*3513f269SManish Tomar }
525*3513f269SManish Tomar 
526*3513f269SManish Tomar /*
527*3513f269SManish Tomar  * Extract information for DSPI Controller from the DTB
528*3513f269SManish Tomar  * dspi_data: DSPI controller chip instance
529*3513f269SManish Tomar  */
530*3513f269SManish Tomar static TEE_Result get_info_from_device_tree(struct ls_dspi_data *dspi_data)
531*3513f269SManish Tomar {
532*3513f269SManish Tomar 	const fdt32_t *bus_num = NULL;
533*3513f269SManish Tomar 	const fdt32_t *chip_select_num = NULL;
534*3513f269SManish Tomar 	size_t size = 0;
535*3513f269SManish Tomar 	int node = 0;
536*3513f269SManish Tomar 	vaddr_t ctrl_base = 0;
537*3513f269SManish Tomar 	void *fdt = NULL;
538*3513f269SManish Tomar 
539*3513f269SManish Tomar 	/*
540*3513f269SManish Tomar 	 * First get the DSPI Controller base address from the DTB
541*3513f269SManish Tomar 	 * if DTB present and if the DSPI Controller defined in it.
542*3513f269SManish Tomar 	 */
543*3513f269SManish Tomar 	fdt = get_dt();
544*3513f269SManish Tomar 	if (!fdt) {
545*3513f269SManish Tomar 		EMSG("Unable to get DTB, DSPI init failed\n");
546*3513f269SManish Tomar 		return TEE_ERROR_ITEM_NOT_FOUND;
547*3513f269SManish Tomar 	}
548*3513f269SManish Tomar 
549*3513f269SManish Tomar 	node = 0;
550*3513f269SManish Tomar 	while (node != -FDT_ERR_NOTFOUND) {
551*3513f269SManish Tomar 		node = fdt_node_offset_by_compatible(fdt, node,
552*3513f269SManish Tomar 						     "fsl,lx2160a-dspi");
553*3513f269SManish Tomar 		if (!(_fdt_get_status(fdt, node) & DT_STATUS_OK_SEC))
554*3513f269SManish Tomar 			continue;
555*3513f269SManish Tomar 
556*3513f269SManish Tomar 		bus_num = fdt_getprop(fdt, node, "bus-num", NULL);
557*3513f269SManish Tomar 		if (bus_num && dspi_data->slave_bus ==
558*3513f269SManish Tomar 			(unsigned int)fdt32_to_cpu(*bus_num)) {
559*3513f269SManish Tomar 			if (dt_map_dev(fdt, node, &ctrl_base, &size) < 0) {
560*3513f269SManish Tomar 				EMSG("Unable to get virtual address");
561*3513f269SManish Tomar 				return TEE_ERROR_GENERIC;
562*3513f269SManish Tomar 			}
563*3513f269SManish Tomar 			break;
564*3513f269SManish Tomar 		}
565*3513f269SManish Tomar 	}
566*3513f269SManish Tomar 
567*3513f269SManish Tomar 	dspi_data->base = ctrl_base;
568*3513f269SManish Tomar 	dspi_data->bus_clk_hz = DSPI_CLK;
569*3513f269SManish Tomar 
570*3513f269SManish Tomar 	chip_select_num = fdt_getprop(fdt, node, "spi-num-chipselects", NULL);
571*3513f269SManish Tomar 	if (chip_select_num)
572*3513f269SManish Tomar 		dspi_data->num_chipselect = (int)fdt32_to_cpu(*chip_select_num);
573*3513f269SManish Tomar 	else
574*3513f269SManish Tomar 		return TEE_ERROR_ITEM_NOT_FOUND;
575*3513f269SManish Tomar 
576*3513f269SManish Tomar 	dspi_data->speed_hz = DSPI_DEFAULT_SCK_FREQ;
577*3513f269SManish Tomar 
578*3513f269SManish Tomar 	return TEE_SUCCESS;
579*3513f269SManish Tomar }
580*3513f269SManish Tomar 
581*3513f269SManish Tomar static const struct spi_ops ls_dspi_ops = {
582*3513f269SManish Tomar 	.configure = ls_dspi_configure,
583*3513f269SManish Tomar 	.start = ls_dspi_start,
584*3513f269SManish Tomar 	.txrx8 = ls_dspi_txrx8,
585*3513f269SManish Tomar 	.txrx16 = ls_dspi_txrx16,
586*3513f269SManish Tomar 	.end = ls_dspi_end,
587*3513f269SManish Tomar };
588*3513f269SManish Tomar DECLARE_KEEP_PAGER(ls_dspi_ops);
589*3513f269SManish Tomar 
590*3513f269SManish Tomar TEE_Result ls_dspi_init(struct ls_dspi_data *dspi_data)
591*3513f269SManish Tomar {
592*3513f269SManish Tomar 	TEE_Result status = TEE_ERROR_GENERIC;
593*3513f269SManish Tomar 
594*3513f269SManish Tomar 	/*
595*3513f269SManish Tomar 	 * First get the DSPI Controller base address from the DTB,
596*3513f269SManish Tomar 	 * if DTB present and if the DSPI Controller defined in it.
597*3513f269SManish Tomar 	 */
598*3513f269SManish Tomar 	if (dspi_data)
599*3513f269SManish Tomar 		status = get_info_from_device_tree(dspi_data);
600*3513f269SManish Tomar 	if (status == TEE_SUCCESS)
601*3513f269SManish Tomar 		/* generic DSPI chip handle */
602*3513f269SManish Tomar 		dspi_data->chip.ops = &ls_dspi_ops;
603*3513f269SManish Tomar 	else
604*3513f269SManish Tomar 		EMSG("Unable to get info from device tree");
605*3513f269SManish Tomar 
606*3513f269SManish Tomar 	return status;
607*3513f269SManish Tomar }
608