1 /* 2 * sfc driver for rockchip 3 * 4 * (C) Copyright 2008-2016 Rockchip Electronics 5 * Yifeng.zhao, Software Engineering, <zhao0116@gmail.com>. 6 * 7 * SPDX-License-Identifier: GPL-2.0+ 8 */ 9 10 #include <common.h> 11 #include <clk.h> 12 #include <dm.h> 13 #include <dt-structs.h> 14 #include <errno.h> 15 #include <spi.h> 16 #include <linux/errno.h> 17 #include <asm/io.h> 18 #include <asm/arch/clock.h> 19 #include <asm/arch/periph.h> 20 #include <dm/pinctrl.h> 21 #include "rockchip_sfc.h" 22 23 DECLARE_GLOBAL_DATA_PTR; 24 25 enum rockchip_sfc_if_type { 26 IF_TYPE_STD, 27 IF_TYPE_DUAL, 28 IF_TYPE_QUAD, 29 }; 30 31 struct rockchip_sfc_platdata { 32 s32 frequency; 33 fdt_addr_t base; 34 }; 35 36 struct rockchip_sfc { 37 struct rockchip_sfc_reg *regbase; 38 struct clk clk; 39 unsigned int max_freq; 40 unsigned int mode; 41 unsigned int speed_hz; 42 u32 cmd; 43 u32 addr; 44 }; 45 46 static int rockchip_sfc_ofdata_to_platdata(struct udevice *bus) 47 { 48 struct rockchip_sfc_platdata *plat = dev_get_platdata(bus); 49 struct rockchip_sfc *sfc = dev_get_priv(bus); 50 const void *blob = gd->fdt_blob; 51 int node = dev_of_offset(bus); 52 int subnode; 53 int ret; 54 55 plat->base = devfdt_get_addr(bus); 56 57 ret = clk_get_by_index(bus, 0, &sfc->clk); 58 if (ret < 0) { 59 debug("Could not get clock for %s: %d\n", bus->name, ret); 60 return ret; 61 } 62 63 subnode = fdt_first_subnode(blob, node); 64 if (subnode < 0) { 65 debug("Error: subnode with SPI flash config missing!\n"); 66 return -ENODEV; 67 } 68 69 plat->frequency = fdtdec_get_int(blob, subnode, "spi-max-frequency", 70 100000000); 71 72 return 0; 73 } 74 75 static int rockchip_sfc_probe(struct udevice *bus) 76 { 77 struct rockchip_sfc_platdata *plat = dev_get_platdata(bus); 78 struct rockchip_sfc *sfc = dev_get_priv(bus); 79 int ret; 80 81 sfc->regbase = (struct rockchip_sfc_reg *)plat->base; 82 83 sfc->max_freq = plat->frequency; 84 85 ret = clk_set_rate(&sfc->clk, sfc->max_freq); 86 if (ret < 0) { 87 debug("%s: Failed to set clock: %d\n", __func__, ret); 88 return ret; 89 } 90 91 return 0; 92 } 93 94 static int rockchip_sfc_reset(struct rockchip_sfc *sfc) 95 { 96 struct rockchip_sfc_reg *regs = sfc->regbase; 97 int tbase = get_timer(0); 98 u32 rcvr; 99 int ret = 0; 100 101 writel(SFC_RESET, ®s->rcvr); 102 do { 103 rcvr = readl(®s->rcvr); 104 if (get_timer(tbase) > 1000) { 105 debug("sfc reset timeout\n"); 106 ret = -ETIMEDOUT; 107 break; 108 } 109 udelay(1); 110 } while (rcvr); 111 112 writel(0xFFFFFFFF, ®s->iclr); 113 114 debug("sfc reset\n"); 115 116 return ret; 117 } 118 119 static u8 rockchip_sfc_get_if_type(struct rockchip_sfc *sfc) 120 { 121 int type = IF_TYPE_STD; 122 123 if (sfc->cmd & SFC_WR) { 124 if (sfc->mode & SPI_TX_QUAD) 125 type = IF_TYPE_QUAD; 126 else if (sfc->mode & SPI_TX_DUAL) 127 type = IF_TYPE_DUAL; 128 else 129 type = IF_TYPE_STD; 130 } else { 131 if (sfc->mode & SPI_RX_QUAD) 132 type = IF_TYPE_QUAD; 133 else if (sfc->mode & SPI_RX_DUAL) 134 type = IF_TYPE_DUAL; 135 else 136 type = IF_TYPE_STD; 137 } 138 139 return type; 140 } 141 142 static void rockchip_sfc_setup_xfer(struct rockchip_sfc *sfc) 143 { 144 struct rockchip_sfc_reg *regs = sfc->regbase; 145 u32 val = 0x02; 146 u32 fsr = readl(®s->fsr); 147 u32 sr = readl(®s->sr); 148 u8 data_width = IF_TYPE_STD; 149 150 if (!(fsr & SFC_TX_EMPTY) || !(fsr & SFC_RX_EMPTY) || (sr & SFC_BUSY)) 151 rockchip_sfc_reset(sfc); 152 153 if (sfc->cmd & SFC_ADDR_XBITS) 154 data_width = rockchip_sfc_get_if_type(sfc); 155 156 val |= (data_width << SFC_DATA_WIDTH_SHIFT); 157 158 writel(val, ®s->ctrl); 159 writel(sfc->cmd, ®s->cmd); 160 if (sfc->cmd & SFC_ADDR_XBITS) 161 writel(sfc->addr, ®s->addr); 162 } 163 164 static int rockchip_sfc_do_dma_xfer(struct rockchip_sfc *sfc, u32 *buffer) 165 { 166 struct rockchip_sfc_reg *regs = sfc->regbase; 167 int timeout = 1000; 168 int ret = 0; 169 int risr; 170 unsigned long tbase; 171 172 rockchip_sfc_setup_xfer(sfc); 173 174 writel(0xFFFFFFFF, ®s->iclr); 175 writel((u32)buffer, ®s->dmaaddr); 176 writel(SFC_DMA_START, ®s->dmatr); 177 178 tbase = get_timer(0); 179 do { 180 udelay(1); 181 risr = readl(®s->risr); 182 if (get_timer(tbase) > timeout) { 183 debug("dma timeout\n"); 184 ret = -ETIMEDOUT; 185 break; 186 } 187 } while (!(risr & TRANS_FINISH_INT)); 188 189 writel(0xFFFFFFFF, ®s->iclr); 190 191 return ret; 192 } 193 194 static int rockchip_sfc_dma_xfer(struct rockchip_sfc *sfc, u32 *buf, u32 len) 195 { 196 u32 trb; 197 u32 *p32_data = buf; 198 int ret = 0; 199 200 while (len) { 201 trb = min(len, (u32)SFC_MAX_TRB); 202 sfc->cmd |= (trb << SFC_TRB_SHIFT); 203 ret = rockchip_sfc_do_dma_xfer(sfc, p32_data); 204 if (ret < 0) 205 break; 206 len -= trb; 207 sfc->addr += trb; 208 p32_data += (trb >> 2); 209 } 210 211 return ret; 212 } 213 214 static int rockchip_sfc_wait_fifo_ready(struct rockchip_sfc *sfc, int wr, 215 u32 timeout) 216 { 217 struct rockchip_sfc_reg *regs = sfc->regbase; 218 unsigned long tbase = get_timer(0); 219 u8 level; 220 u32 fsr; 221 222 do { 223 fsr = readl(®s->fsr); 224 if (wr) 225 level = (fsr & SFC_TXLV_MASK) >> SFC_TXLV_SHIFT; 226 else 227 level = (fsr & SFC_RXLV_MASK) >> SFC_RXLV_SHIFT; 228 if (get_timer(tbase) > timeout) 229 return -ETIMEDOUT; 230 udelay(1); 231 } while (!level); 232 233 return level; 234 } 235 236 static int rockchip_sfc_write(struct rockchip_sfc *sfc, u32 *buf, u32 len) 237 { 238 struct rockchip_sfc_reg *regs = sfc->regbase; 239 u32 bytes = len & 0x3; 240 u32 words = len >> 2; 241 u32 tx_level = 0; 242 u32 val = 0; 243 u8 count; 244 245 while (words) { 246 tx_level = rockchip_sfc_wait_fifo_ready(sfc, 1, 1000); 247 if (tx_level <= 0) 248 return tx_level; 249 count = min(words, tx_level); 250 writesl(®s->data, buf, count); 251 buf += count; 252 words -= count; 253 } 254 255 /* handle the last none word aligned bytes */ 256 if (bytes) { 257 tx_level = rockchip_sfc_wait_fifo_ready(sfc, 1, 1000); 258 if (tx_level <= 0) 259 return tx_level; 260 memcpy(&val, buf, bytes); 261 writel(val, ®s->data); 262 } 263 264 return 0; 265 } 266 267 static int rockchip_sfc_read(struct rockchip_sfc *sfc, u32 *buf, u32 len) 268 { 269 struct rockchip_sfc_reg *regs = sfc->regbase; 270 u32 bytes = len & 0x3; 271 u32 words = len >> 2; 272 u32 rx_level = 0; 273 u32 count; 274 u32 val; 275 276 while (words) { 277 rx_level = rockchip_sfc_wait_fifo_ready(sfc, 0, 1000); 278 if (rx_level <= 0) 279 return rx_level; 280 count = min(words, rx_level); 281 readsl(®s->data, buf, count); 282 buf += count; 283 words -= count; 284 } 285 286 /* handle the last none word aligned bytes */ 287 if (bytes) { 288 rx_level = rockchip_sfc_wait_fifo_ready(sfc, 0, 1000); 289 if (rx_level <= 0) 290 return rx_level; 291 val = readl(®s->data); 292 memcpy(buf, &val, bytes); 293 } 294 295 return 0; 296 } 297 298 static int rockchip_sfc_pio_xfer(struct rockchip_sfc *sfc, u32 *buf, u32 len) 299 { 300 int ret = 0; 301 int rw = sfc->cmd & SFC_WR; 302 303 sfc->cmd |= (len << SFC_TRB_SHIFT); 304 rockchip_sfc_setup_xfer(sfc); 305 306 if (len) { 307 if (rw) 308 ret = rockchip_sfc_write(sfc, buf, len); 309 else 310 ret = rockchip_sfc_read(sfc, buf, len); 311 } 312 313 return ret; 314 } 315 316 static int rockchip_sfc_do_xfer(struct rockchip_sfc *sfc, u32 *buf, u32 len) 317 { 318 int ret = 0; 319 320 if (!(len & 0x03) && (len >= 4)) 321 ret = rockchip_sfc_dma_xfer(sfc, buf, len); 322 else 323 ret = rockchip_sfc_pio_xfer(sfc, buf, len); 324 325 return ret; 326 } 327 328 static int rockchip_sfc_xfer(struct udevice *dev, unsigned int bitlen, 329 const void *dout, void *din, unsigned long flags) 330 { 331 struct udevice *bus = dev->parent; 332 struct rockchip_sfc *sfc = dev_get_priv(bus); 333 int len = bitlen >> 3; 334 u8 *pcmd = (u8 *)dout; 335 int ret = 0; 336 337 if (flags & SPI_XFER_BEGIN) { 338 sfc->cmd = pcmd[0]; 339 if (len >= 4) { 340 sfc->cmd |= SFC_ADDR_24BITS | (((len - 4) * 8) << 8); 341 sfc->addr = pcmd[3] | (pcmd[2] << 8) | (pcmd[1] << 16); 342 } 343 } 344 345 if (flags == (SPI_XFER_BEGIN | SPI_XFER_END)) 346 len = 0; 347 348 if (flags & SPI_XFER_END) { 349 if (dout && len) 350 sfc->cmd |= SFC_WR; 351 352 if (din) 353 ret = rockchip_sfc_do_xfer(sfc, (u32 *)din, len); 354 else if (dout) 355 ret = rockchip_sfc_do_xfer(sfc, (u32 *)dout, len); 356 } 357 358 return ret; 359 } 360 361 static int rockchip_sfc_set_speed(struct udevice *bus, uint speed) 362 { 363 struct rockchip_sfc *sfc = dev_get_priv(bus); 364 365 if (speed > sfc->max_freq) 366 speed = sfc->max_freq; 367 368 sfc->speed_hz = speed; 369 370 return 0; 371 } 372 373 static int rockchip_sfc_set_mode(struct udevice *bus, uint mode) 374 { 375 struct rockchip_sfc *sfc = dev_get_priv(bus); 376 377 sfc->mode = mode; 378 379 return 0; 380 } 381 382 static const struct dm_spi_ops rockchip_sfc_ops = { 383 .xfer = rockchip_sfc_xfer, 384 .set_speed = rockchip_sfc_set_speed, 385 .set_mode = rockchip_sfc_set_mode, 386 }; 387 388 static const struct udevice_id rockchip_sfc_ids[] = { 389 { .compatible = "rockchip,sfc" }, 390 { } 391 }; 392 393 U_BOOT_DRIVER(rockchip_sfc_driver) = { 394 .name = "rockchip_sfc", 395 .id = UCLASS_SPI, 396 .of_match = rockchip_sfc_ids, 397 .ops = &rockchip_sfc_ops, 398 .ofdata_to_platdata = rockchip_sfc_ofdata_to_platdata, 399 .platdata_auto_alloc_size = sizeof(struct rockchip_sfc_platdata), 400 .priv_auto_alloc_size = sizeof(struct rockchip_sfc), 401 .probe = rockchip_sfc_probe, 402 }; 403