1 // SPDX-License-Identifier: GPL-2.0-or-later
3 * eSPI controller driver.
5 * Copyright (c) 2022 Matthias Schiffer <mschiffer@universe-factory.net>
7 * Based on U-Boot code:
9 * Copyright 2010-2011 Freescale Semiconductor, Inc.
11 * Author: Mingkai Hu (Mingkai.hu@freescale.com)
12 * Chuanhua Han (chuanhua.han@nxp.com)
20 typedef struct ccsr_espi
{
21 uint32_t mode
; /* eSPI mode */
22 uint32_t event
; /* eSPI event */
23 uint32_t mask
; /* eSPI mask */
24 uint32_t com
; /* eSPI command */
25 uint32_t tx
; /* eSPI transmit FIFO access */
26 uint32_t rx
; /* eSPI receive FIFO access */
27 uint8_t res1
[8]; /* reserved */
28 uint32_t csmode
[4]; /* 0x2c: sSPI CS0/1/2/3 mode */
29 uint8_t res2
[4048]; /* fill up to 0x1000 */
40 #define ESPI_MAX_CS_NUM 4
41 #define ESPI_FIFO_WIDTH_BIT 32
43 #define ESPI_EV_RNE BIT(9)
44 #define ESPI_EV_TNF BIT(8)
45 #define ESPI_EV_DON BIT(14)
46 #define ESPI_EV_TXE BIT(15)
47 #define ESPI_EV_RFCNT_SHIFT 24
48 #define ESPI_EV_RFCNT_MASK (0x3f << ESPI_EV_RFCNT_SHIFT)
50 #define ESPI_MODE_EN BIT(31) /* Enable interface */
51 #define ESPI_MODE_TXTHR(x) ((x) << 8) /* Tx FIFO threshold */
52 #define ESPI_MODE_RXTHR(x) ((x) << 0) /* Rx FIFO threshold */
54 #define ESPI_COM_CS(x) ((x) << 30)
55 #define ESPI_COM_TRANLEN(x) ((x) << 0)
57 #define ESPI_CSMODE_CI_INACTIVEHIGH BIT(31)
58 #define ESPI_CSMODE_CP_BEGIN_EDGCLK BIT(30)
59 #define ESPI_CSMODE_REV_MSB_FIRST BIT(29)
60 #define ESPI_CSMODE_DIV16 BIT(28)
61 #define ESPI_CSMODE_PM(x) ((x) << 24)
62 #define ESPI_CSMODE_POL_ASSERTED_LOW BIT(20)
63 #define ESPI_CSMODE_LEN(x) ((x) << 16)
64 #define ESPI_CSMODE_CSBEF(x) ((x) << 12)
65 #define ESPI_CSMODE_CSAFT(x) ((x) << 8)
66 #define ESPI_CSMODE_CSCG(x) ((x) << 3)
68 #define ESPI_CSMODE_INIT_VAL (ESPI_CSMODE_POL_ASSERTED_LOW | \
69 ESPI_CSMODE_CSBEF(0) | ESPI_CSMODE_CSAFT(0) | \
72 #define ESPI_MAX_DATA_TRANSFER_LEN 0x10000
74 static int espi_xfer(struct fsl_spi
*fsl
, const struct spi_transfer
*msg
, int n
)
76 ccsr_espi_t
*espi
= fsl
->espi
;
77 size_t len
= spi_message_len(msg
, n
);
79 if (len
> ESPI_MAX_DATA_TRANSFER_LEN
)
82 /* clear the RXCNT and TXCNT */
83 out_be32(&espi
->mode
, in_be32(&espi
->mode
) & (~ESPI_MODE_EN
));
84 out_be32(&espi
->mode
, in_be32(&espi
->mode
) | ESPI_MODE_EN
);
85 out_be32(&espi
->com
, ESPI_COM_CS(fsl
->cs
) | ESPI_COM_TRANLEN(len
- 1));
88 int tx_msg
= -1, rx_msg
= -1;
89 size_t tx_len
= 0, rx_len
= 0, tx_pos
= 0, rx_pos
= 0;
92 if (tx_pos
== tx_len
&& tx_msg
< last_msg
) {
95 tx_len
= msg
[tx_msg
].len
;
97 if (rx_pos
== rx_len
&& rx_msg
< last_msg
) {
100 rx_len
= msg
[rx_msg
].len
;
102 if (rx_pos
== rx_len
)
105 const uint8_t *tx_buf
= msg
[tx_msg
].tx_buf
;
106 uint8_t *rx_buf
= msg
[rx_msg
].rx_buf
;
108 uint32_t event
= in_be32(&espi
->event
);
111 if ((event
& ESPI_EV_TNF
) && tx_len
> 0) {
115 out_8((uint8_t *)&espi
->tx
, v
);
120 if (event
& ESPI_EV_RNE
) {
121 uint8_t v
= in_8((uint8_t *)&espi
->rx
);
131 static void espi_claim_bus(struct fsl_spi
*fsl
)
133 ccsr_espi_t
*espi
= fsl
->espi
;
137 /* Enable eSPI interface */
138 out_be32(&espi
->mode
, ESPI_MODE_RXTHR(3)
139 | ESPI_MODE_TXTHR(4) | ESPI_MODE_EN
);
141 out_be32(&espi
->mask
, 0x00000000); /* Mask all eSPI interrupts */
143 /* Init CS mode interface */
144 for (i
= 0; i
< ESPI_MAX_CS_NUM
; i
++)
145 out_be32(&espi
->csmode
[i
], ESPI_CSMODE_INIT_VAL
);
147 csmode
= ESPI_CSMODE_INIT_VAL
;
149 /* Set eSPI BRG clock source */
150 csmode
|= ESPI_CSMODE_PM(fsl
->pm
) | fsl
->div16
;
153 if (fsl
->mode
& SPI_CPHA
)
154 csmode
|= ESPI_CSMODE_CP_BEGIN_EDGCLK
;
155 if (fsl
->mode
& SPI_CPOL
)
156 csmode
|= ESPI_CSMODE_CI_INACTIVEHIGH
;
158 /* Character bit order: msb first */
159 csmode
|= ESPI_CSMODE_REV_MSB_FIRST
;
161 /* Character length in bits, between 0x3~0xf, i.e. 4bits~16bits */
162 csmode
|= ESPI_CSMODE_LEN(7);
164 out_be32(&espi
->csmode
[fsl
->cs
], csmode
);
167 static void espi_release_bus(struct fsl_spi
*fsl
)
169 /* Disable the SPI hardware */
170 out_be32(&fsl
->espi
->mode
,
171 in_be32(&fsl
->espi
->mode
) & (~ESPI_MODE_EN
));
174 static void espi_setup_spi(struct fsl_spi
*fsl
, unsigned int max_hz
)
176 unsigned long spibrg
;
179 spibrg
= CONFIG_FREQ_SYSTEMBUS
/ 2;
181 if ((spibrg
/ max_hz
) > 32) {
182 fsl
->div16
= ESPI_CSMODE_DIV16
;
183 pm
= spibrg
/ (max_hz
* 16 * 2);
189 pm
= spibrg
/ (max_hz
* 2);
196 static struct fsl_spi spi
;
198 int spi_init(unsigned int cs
, unsigned int max_hz
, unsigned int mode
)
200 if (cs
>= ESPI_MAX_CS_NUM
)
203 spi
.espi
= (ccsr_espi_t
*)CONFIG_SPI_FSL_ESPI_REG_BASE
;
207 espi_setup_spi(&spi
, max_hz
);
212 int spi_claim_bus(void)
214 espi_claim_bus(&spi
);
219 void spi_release_bus(void)
221 espi_release_bus(&spi
);
224 int spi_xfer(const struct spi_transfer
*msg
, int n
)
226 return espi_xfer(&spi
, msg
, n
);
229 size_t spi_max_xfer(void)
231 return ESPI_MAX_DATA_TRANSFER_LEN
;