1// SPDX-License-Identifier: GPL-2.0+ 2/* 3 * uniphier_spi.c - Socionext UniPhier SPI driver 4 * Copyright 2019 Socionext, Inc. 5 */ 6 7#include <clk.h> 8#include <common.h> 9#include <dm.h> 10#include <log.h> 11#include <time.h> 12#include <asm/global_data.h> 13#include <dm/device_compat.h> 14#include <linux/bitfield.h> 15#include <linux/bitops.h> 16#include <linux/delay.h> 17#include <linux/io.h> 18#include <spi.h> 19#include <wait_bit.h> 20#include <linux/printk.h> 21 22DECLARE_GLOBAL_DATA_PTR; 23 24#define SSI_CTL 0x00 25#define SSI_CTL_EN BIT(0) 26 27#define SSI_CKS 0x04 28#define SSI_CKS_CKRAT_MASK GENMASK(7, 0) 29#define SSI_CKS_CKPHS BIT(14) 30#define SSI_CKS_CKINIT BIT(13) 31#define SSI_CKS_CKDLY BIT(12) 32 33#define SSI_TXWDS 0x08 34#define SSI_TXWDS_WDLEN_MASK GENMASK(13, 8) 35#define SSI_TXWDS_TDTF_MASK GENMASK(7, 6) 36#define SSI_TXWDS_DTLEN_MASK GENMASK(5, 0) 37 38#define SSI_RXWDS 0x0c 39#define SSI_RXWDS_RDTF_MASK GENMASK(7, 6) 40#define SSI_RXWDS_DTLEN_MASK GENMASK(5, 0) 41 42#define SSI_FPS 0x10 43#define SSI_FPS_FSPOL BIT(15) 44#define SSI_FPS_FSTRT BIT(14) 45 46#define SSI_SR 0x14 47#define SSI_SR_BUSY BIT(7) 48#define SSI_SR_TNF BIT(5) 49#define SSI_SR_RNE BIT(0) 50 51#define SSI_IE 0x18 52 53#define SSI_IC 0x1c 54#define SSI_IC_TCIC BIT(4) 55#define SSI_IC_RCIC BIT(3) 56#define SSI_IC_RORIC BIT(0) 57 58#define SSI_FC 0x20 59#define SSI_FC_TXFFL BIT(12) 60#define SSI_FC_TXFTH_MASK GENMASK(11, 8) 61#define SSI_FC_RXFFL BIT(4) 62#define SSI_FC_RXFTH_MASK GENMASK(3, 0) 63 64#define SSI_XDR 0x24 /* TXDR for write, RXDR for read */ 65 66#define SSI_FIFO_DEPTH 8U 67 68#define SSI_REG_TIMEOUT (CONFIG_SYS_HZ / 100) /* 10 ms */ 69#define SSI_XFER_TIMEOUT (CONFIG_SYS_HZ) /* 1 sec */ 70 71#define SSI_CLK 50000000 /* internal I/O clock: 50MHz */ 72 73struct uniphier_spi_plat { 74 void __iomem *base; 75 u32 frequency; /* input frequency */ 76 u32 speed_hz; 77 uint deactivate_delay_us; /* Delay to wait after deactivate */ 78 uint activate_delay_us; /* Delay to wait after activate */ 79}; 80 81struct uniphier_spi_priv { 82 void __iomem *base; 83 u8 mode; 84 u8 fifo_depth; 85 u8 bits_per_word; 86 ulong last_transaction_us; /* Time of last transaction end */ 87}; 88 89static void uniphier_spi_enable(struct uniphier_spi_priv *priv, int enable) 90{ 91 u32 val; 92 93 val = readl(priv->base + SSI_CTL); 94 if (enable) 95 val |= SSI_CTL_EN; 96 else 97 val &= ~SSI_CTL_EN; 98 writel(val, priv->base + SSI_CTL); 99} 100 101static void uniphier_spi_regdump(struct uniphier_spi_priv *priv) 102{ 103 pr_debug("CTL %08x\n", readl(priv->base + SSI_CTL)); 104 pr_debug("CKS %08x\n", readl(priv->base + SSI_CKS)); 105 pr_debug("TXWDS %08x\n", readl(priv->base + SSI_TXWDS)); 106 pr_debug("RXWDS %08x\n", readl(priv->base + SSI_RXWDS)); 107 pr_debug("FPS %08x\n", readl(priv->base + SSI_FPS)); 108 pr_debug("SR %08x\n", readl(priv->base + SSI_SR)); 109 pr_debug("IE %08x\n", readl(priv->base + SSI_IE)); 110 pr_debug("IC %08x\n", readl(priv->base + SSI_IC)); 111 pr_debug("FC %08x\n", readl(priv->base + SSI_FC)); 112 pr_debug("XDR %08x\n", readl(priv->base + SSI_XDR)); 113} 114 115static void spi_cs_activate(struct udevice *dev) 116{ 117 struct udevice *bus = dev->parent; 118 struct uniphier_spi_plat *plat = dev_get_plat(bus); 119 struct uniphier_spi_priv *priv = dev_get_priv(bus); 120 ulong delay_us; /* The delay completed so far */ 121 u32 val; 122 123 /* If it's too soon to do another transaction, wait */ 124 if (plat->deactivate_delay_us && priv->last_transaction_us) { 125 delay_us = timer_get_us() - priv->last_transaction_us; 126 if (delay_us < plat->deactivate_delay_us) 127 udelay(plat->deactivate_delay_us - delay_us); 128 } 129 130 val = readl(priv->base + SSI_FPS); 131 if (priv->mode & SPI_CS_HIGH) 132 val |= SSI_FPS_FSPOL; 133 else 134 val &= ~SSI_FPS_FSPOL; 135 writel(val, priv->base + SSI_FPS); 136 137 if (plat->activate_delay_us) 138 udelay(plat->activate_delay_us); 139} 140 141static void spi_cs_deactivate(struct udevice *dev) 142{ 143 struct udevice *bus = dev->parent; 144 struct uniphier_spi_plat *plat = dev_get_plat(bus); 145 struct uniphier_spi_priv *priv = dev_get_priv(bus); 146 u32 val; 147 148 val = readl(priv->base + SSI_FPS); 149 if (priv->mode & SPI_CS_HIGH) 150 val &= ~SSI_FPS_FSPOL; 151 else 152 val |= SSI_FPS_FSPOL; 153 writel(val, priv->base + SSI_FPS); 154 155 /* Remember time of this transaction so we can honour the bus delay */ 156 if (plat->deactivate_delay_us) 157 priv->last_transaction_us = timer_get_us(); 158} 159 160static int uniphier_spi_claim_bus(struct udevice *dev) 161{ 162 struct udevice *bus = dev->parent; 163 struct uniphier_spi_priv *priv = dev_get_priv(bus); 164 u32 val, size; 165 166 uniphier_spi_enable(priv, false); 167 168 /* disable interrupts */ 169 writel(0, priv->base + SSI_IE); 170 171 /* bits_per_word */ 172 size = priv->bits_per_word; 173 val = readl(priv->base + SSI_TXWDS); 174 val &= ~(SSI_TXWDS_WDLEN_MASK | SSI_TXWDS_DTLEN_MASK); 175 val |= FIELD_PREP(SSI_TXWDS_WDLEN_MASK, size); 176 val |= FIELD_PREP(SSI_TXWDS_DTLEN_MASK, size); 177 writel(val, priv->base + SSI_TXWDS); 178 179 val = readl(priv->base + SSI_RXWDS); 180 val &= ~SSI_RXWDS_DTLEN_MASK; 181 val |= FIELD_PREP(SSI_RXWDS_DTLEN_MASK, size); 182 writel(val, priv->base + SSI_RXWDS); 183 184 /* reset FIFOs */ 185 val = SSI_FC_TXFFL | SSI_FC_RXFFL; 186 writel(val, priv->base + SSI_FC); 187 188 /* FIFO threthold */ 189 val = readl(priv->base + SSI_FC); 190 val &= ~(SSI_FC_TXFTH_MASK | SSI_FC_RXFTH_MASK); 191 val |= FIELD_PREP(SSI_FC_TXFTH_MASK, priv->fifo_depth); 192 val |= FIELD_PREP(SSI_FC_RXFTH_MASK, priv->fifo_depth); 193 writel(val, priv->base + SSI_FC); 194 195 /* clear interrupts */ 196 writel(SSI_IC_TCIC | SSI_IC_RCIC | SSI_IC_RORIC, 197 priv->base + SSI_IC); 198 199 uniphier_spi_enable(priv, true); 200 201 return 0; 202} 203 204static int uniphier_spi_release_bus(struct udevice *dev) 205{ 206 struct udevice *bus = dev->parent; 207 struct uniphier_spi_priv *priv = dev_get_priv(bus); 208 209 uniphier_spi_enable(priv, false); 210 211 return 0; 212} 213 214static int uniphier_spi_xfer(struct udevice *dev, unsigned int bitlen, 215 const void *dout, void *din, unsigned long flags) 216{ 217 struct udevice *bus = dev->parent; 218 struct uniphier_spi_priv *priv = dev_get_priv(bus); 219 const u8 *tx_buf = dout; 220 u8 *rx_buf = din, buf; 221 u32 len = bitlen / 8; 222 u32 tx_len, rx_len; 223 u32 ts, status; 224 int ret = 0; 225 226 if (bitlen % 8) { 227 dev_err(dev, "Non byte aligned SPI transfer\n"); 228 return -EINVAL; 229 } 230 231 if (flags & SPI_XFER_BEGIN) 232 spi_cs_activate(dev); 233 234 uniphier_spi_enable(priv, true); 235 236 ts = get_timer(0); 237 tx_len = len; 238 rx_len = len; 239 240 uniphier_spi_regdump(priv); 241 242 while (tx_len || rx_len) { 243 ret = wait_for_bit_le32(priv->base + SSI_SR, SSI_SR_BUSY, false, 244 SSI_REG_TIMEOUT * 1000, false); 245 if (ret) { 246 if (ret == -ETIMEDOUT) 247 dev_err(dev, "access timeout\n"); 248 break; 249 } 250 251 status = readl(priv->base + SSI_SR); 252 /* write the data into TX */ 253 if (tx_len && (status & SSI_SR_TNF)) { 254 buf = tx_buf ? *tx_buf++ : 0; 255 writel(buf, priv->base + SSI_XDR); 256 tx_len--; 257 } 258 259 /* read the data from RX */ 260 if (rx_len && (status & SSI_SR_RNE)) { 261 buf = readl(priv->base + SSI_XDR); 262 if (rx_buf) 263 *rx_buf++ = buf; 264 rx_len--; 265 } 266 267 if (get_timer(ts) >= SSI_XFER_TIMEOUT) { 268 dev_err(dev, "transfer timeout\n"); 269 ret = -ETIMEDOUT; 270 break; 271 } 272 } 273 274 if (flags & SPI_XFER_END) 275 spi_cs_deactivate(dev); 276 277 uniphier_spi_enable(priv, false); 278 279 return ret; 280} 281 282static int uniphier_spi_set_speed(struct udevice *bus, uint speed) 283{ 284 struct uniphier_spi_plat *plat = dev_get_plat(bus); 285 struct uniphier_spi_priv *priv = dev_get_priv(bus); 286 u32 val, ckdiv; 287 288 if (speed > plat->frequency) 289 speed = plat->frequency; 290 291 /* baudrate */ 292 ckdiv = DIV_ROUND_UP(SSI_CLK, speed); 293 ckdiv = round_up(ckdiv, 2); 294 295 val = readl(priv->base + SSI_CKS); 296 val &= ~SSI_CKS_CKRAT_MASK; 297 val |= ckdiv & SSI_CKS_CKRAT_MASK; 298 writel(val, priv->base + SSI_CKS); 299 300 return 0; 301} 302 303static int uniphier_spi_set_mode(struct udevice *bus, uint mode) 304{ 305 struct uniphier_spi_priv *priv = dev_get_priv(bus); 306 u32 val1, val2; 307 308 /* 309 * clock setting 310 * CKPHS capture timing. 0:rising edge, 1:falling edge 311 * CKINIT clock initial level. 0:low, 1:high 312 * CKDLY clock delay. 0:no delay, 1:delay depending on FSTRT 313 * (FSTRT=0: 1 clock, FSTRT=1: 0.5 clock) 314 * 315 * frame setting 316 * FSPOL frame signal porarity. 0: low, 1: high 317 * FSTRT start frame timing 318 * 0: rising edge of clock, 1: falling edge of clock 319 */ 320 val1 = readl(priv->base + SSI_CKS); 321 val2 = readl(priv->base + SSI_FPS); 322 323 switch (mode & (SPI_CPOL | SPI_CPHA)) { 324 case SPI_MODE_0: 325 /* CKPHS=1, CKINIT=0, CKDLY=1, FSTRT=0 */ 326 val1 |= SSI_CKS_CKPHS | SSI_CKS_CKDLY; 327 val1 &= ~SSI_CKS_CKINIT; 328 val2 &= ~SSI_FPS_FSTRT; 329 break; 330 case SPI_MODE_1: 331 /* CKPHS=0, CKINIT=0, CKDLY=0, FSTRT=1 */ 332 val1 &= ~(SSI_CKS_CKPHS | SSI_CKS_CKINIT | SSI_CKS_CKDLY); 333 val2 |= SSI_FPS_FSTRT; 334 break; 335 case SPI_MODE_2: 336 /* CKPHS=0, CKINIT=1, CKDLY=1, FSTRT=1 */ 337 val1 |= SSI_CKS_CKINIT | SSI_CKS_CKDLY; 338 val1 &= ~SSI_CKS_CKPHS; 339 val2 |= SSI_FPS_FSTRT; 340 break; 341 case SPI_MODE_3: 342 /* CKPHS=1, CKINIT=1, CKDLY=0, FSTRT=0 */ 343 val1 |= SSI_CKS_CKPHS | SSI_CKS_CKINIT; 344 val1 &= ~SSI_CKS_CKDLY; 345 val2 &= ~SSI_FPS_FSTRT; 346 break; 347 } 348 349 writel(val1, priv->base + SSI_CKS); 350 writel(val2, priv->base + SSI_FPS); 351 352 /* format */ 353 val1 = readl(priv->base + SSI_TXWDS); 354 val2 = readl(priv->base + SSI_RXWDS); 355 if (mode & SPI_LSB_FIRST) { 356 val1 |= FIELD_PREP(SSI_TXWDS_TDTF_MASK, 1); 357 val2 |= FIELD_PREP(SSI_RXWDS_RDTF_MASK, 1); 358 } 359 writel(val1, priv->base + SSI_TXWDS); 360 writel(val2, priv->base + SSI_RXWDS); 361 362 priv->mode = mode; 363 364 return 0; 365} 366 367static int uniphier_spi_of_to_plat(struct udevice *bus) 368{ 369 struct uniphier_spi_plat *plat = dev_get_plat(bus); 370 const void *blob = gd->fdt_blob; 371 int node = dev_of_offset(bus); 372 373 plat->base = dev_read_addr_ptr(bus); 374 375 plat->frequency = 376 fdtdec_get_int(blob, node, "spi-max-frequency", 12500000); 377 plat->deactivate_delay_us = 378 fdtdec_get_int(blob, node, "spi-deactivate-delay", 0); 379 plat->activate_delay_us = 380 fdtdec_get_int(blob, node, "spi-activate-delay", 0); 381 plat->speed_hz = plat->frequency / 2; 382 383 return 0; 384} 385 386static int uniphier_spi_probe(struct udevice *bus) 387{ 388 struct uniphier_spi_plat *plat = dev_get_plat(bus); 389 struct uniphier_spi_priv *priv = dev_get_priv(bus); 390 391 priv->base = plat->base; 392 priv->fifo_depth = SSI_FIFO_DEPTH; 393 priv->bits_per_word = 8; 394 395 return 0; 396} 397 398static const struct dm_spi_ops uniphier_spi_ops = { 399 .claim_bus = uniphier_spi_claim_bus, 400 .release_bus = uniphier_spi_release_bus, 401 .xfer = uniphier_spi_xfer, 402 .set_speed = uniphier_spi_set_speed, 403 .set_mode = uniphier_spi_set_mode, 404}; 405 406static const struct udevice_id uniphier_spi_ids[] = { 407 { .compatible = "socionext,uniphier-scssi" }, 408 { /* Sentinel */ } 409}; 410 411U_BOOT_DRIVER(uniphier_spi) = { 412 .name = "uniphier_spi", 413 .id = UCLASS_SPI, 414 .of_match = uniphier_spi_ids, 415 .ops = &uniphier_spi_ops, 416 .of_to_plat = uniphier_spi_of_to_plat, 417 .plat_auto = sizeof(struct uniphier_spi_plat), 418 .priv_auto = sizeof(struct uniphier_spi_priv), 419 .probe = uniphier_spi_probe, 420}; 421