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