1 // SPDX-License-Identifier: BSD-2-Clause 2 /* 3 * Copyright (c) 2016, Linaro Limited 4 * All rights reserved. 5 * 6 * Redistribution and use in source and binary forms, with or without 7 * modification, are permitted provided that the following conditions are met: 8 * 9 * 1. Redistributions of source code must retain the above copyright notice, 10 * this list of conditions and the following disclaimer. 11 * 12 * 2. Redistributions in binary form must reproduce the above copyright notice, 13 * this list of conditions and the following disclaimer in the documentation 14 * and/or other materials provided with the distribution. 15 * 16 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" 17 * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE 18 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE 19 * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE 20 * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR 21 * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF 22 * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS 23 * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN 24 * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) 25 * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE 26 * POSSIBILITY OF SUCH DAMAGE. 27 * 28 */ 29 30 #include <assert.h> 31 #include <drivers/pl022_spi.h> 32 #include <initcall.h> 33 #include <io.h> 34 #include <kernel/panic.h> 35 #include <kernel/tee_time.h> 36 #include <platform_config.h> 37 #include <trace.h> 38 #include <util.h> 39 40 /* SPI register offsets */ 41 #define SSPCR0 0x000 42 #define SSPCR1 0x004 43 #define SSPDR 0x008 44 #define SSPSR 0x00C 45 #define SSPCPSR 0x010 46 #define SSPIMSC 0x014 47 #define SSPRIS 0x018 48 #define SSPMIS 0x01C 49 #define SSPICR 0x020 50 #define SSPDMACR 0x024 51 52 #ifdef PLATFORM_hikey 53 /* HiKey extensions */ 54 #define SSPTXFIFOCR 0x028 55 #define SSPRXFIFOCR 0x02C 56 #define SSPB2BTRANS 0x030 57 #endif 58 59 /* test registers */ 60 #define SSPTCR 0x080 61 #define SSPITIP 0x084 62 #define SSPITOP 0x088 63 #define SSPTDR 0x08C 64 65 #define SSPPeriphID0 0xFE0 66 #define SSPPeriphID1 0xFE4 67 #define SSPPeriphID2 0xFE8 68 #define SSPPeriphID3 0xFEC 69 70 #define SSPPCellID0 0xFF0 71 #define SSPPCellID1 0xFF4 72 #define SSPPCellID2 0xFF8 73 #define SSPPCellID3 0xFFC 74 75 /* SPI register masks */ 76 #define SSPCR0_SCR SHIFT_U32(0xFF, 8) 77 #define SSPCR0_SPH SHIFT_U32(1, 7) 78 #define SSPCR0_SPH1 SHIFT_U32(1, 7) 79 #define SSPCR0_SPH0 SHIFT_U32(0, 7) 80 #define SSPCR0_SPO SHIFT_U32(1, 6) 81 #define SSPCR0_SPO1 SHIFT_U32(1, 6) 82 #define SSPCR0_SPO0 SHIFT_U32(0, 6) 83 #define SSPCR0_FRF SHIFT_U32(3, 4) 84 #define SSPCR0_FRF_SPI SHIFT_U32(0, 4) 85 #define SSPCR0_DSS SHIFT_U32(0xFF, 0) 86 #define SSPCR0_DSS_16BIT SHIFT_U32(0xF, 0) 87 #define SSPCR0_DSS_8BIT SHIFT_U32(7, 0) 88 89 #define SSPCR1_SOD SHIFT_U32(1, 3) 90 #define SSPCR1_SOD_ENABLE SHIFT_U32(1, 3) 91 #define SSPCR1_SOD_DISABLE SHIFT_U32(0, 3) 92 #define SSPCR1_MS SHIFT_U32(1, 2) 93 #define SSPCR1_MS_SLAVE SHIFT_U32(1, 2) 94 #define SSPCR1_MS_MASTER SHIFT_U32(0, 2) 95 #define SSPCR1_SSE SHIFT_U32(1, 1) 96 #define SSPCR1_SSE_ENABLE SHIFT_U32(1, 1) 97 #define SSPCR1_SSE_DISABLE SHIFT_U32(0, 1) 98 #define SSPCR1_LBM SHIFT_U32(1, 0) 99 #define SSPCR1_LBM_YES SHIFT_U32(1, 0) 100 #define SSPCR1_LBM_NO SHIFT_U32(0, 0) 101 102 #define SSPDR_DATA SHIFT_U32(0xFFFF, 0) 103 104 #define SSPSR_BSY SHIFT_U32(1, 4) 105 #define SSPSR_RNF SHIFT_U32(1, 3) 106 #define SSPSR_RNE SHIFT_U32(1, 2) 107 #define SSPSR_TNF SHIFT_U32(1, 1) 108 #define SSPSR_TFE SHIFT_U32(1, 0) 109 110 #define SSPCPSR_CPSDVR SHIFT_U32(0xFF, 0) 111 112 #define SSPIMSC_TXIM SHIFT_U32(1, 3) 113 #define SSPIMSC_RXIM SHIFT_U32(1, 2) 114 #define SSPIMSC_RTIM SHIFT_U32(1, 1) 115 #define SSPIMSC_RORIM SHIFT_U32(1, 0) 116 117 #define SSPRIS_TXRIS SHIFT_U32(1, 3) 118 #define SSPRIS_RXRIS SHIFT_U32(1, 2) 119 #define SSPRIS_RTRIS SHIFT_U32(1, 1) 120 #define SSPRIS_RORRIS SHIFT_U32(1, 0) 121 122 #define SSPMIS_TXMIS SHIFT_U32(1, 3) 123 #define SSPMIS_RXMIS SHIFT_U32(1, 2) 124 #define SSPMIS_RTMIS SHIFT_U32(1, 1) 125 #define SSPMIS_RORMIS SHIFT_U32(1, 0) 126 127 #define SSPICR_RTIC SHIFT_U32(1, 1) 128 #define SSPICR_RORIC SHIFT_U32(1, 0) 129 130 #define SSPDMACR_TXDMAE SHIFT_U32(1, 1) 131 #define SSPDMACR_RXDMAE SHIFT_U32(1, 0) 132 133 #define SSPPeriphID0_PartNumber0 SHIFT_U32(0xFF, 0) /* 0x22 */ 134 #define SSPPeriphID1_Designer0 SHIFT_U32(0xF, 4) /* 0x1 */ 135 #define SSPPeriphID1_PartNumber1 SHIFT_U32(0xF, 0) /* 0x0 */ 136 #define SSPPeriphID2_Revision SHIFT_U32(0xF, 4) 137 #define SSPPeriphID2_Designer1 SHIFT_U32(0xF, 0) /* 0x4 */ 138 #define SSPPeriphID3_Configuration SHIFT_U32(0xFF, 0) /* 0x00 */ 139 140 #define SSPPCellID_0 SHIFT_U32(0xFF, 0) /* 0x0D */ 141 #define SSPPCellID_1 SHIFT_U32(0xFF, 0) /* 0xF0 */ 142 #define SSPPPCellID_2 SHIFT_U32(0xFF, 0) /* 0x05 */ 143 #define SSPPPCellID_3 SHIFT_U32(0xFF, 0) /* 0xB1 */ 144 145 #define MASK_32 0xFFFFFFFF 146 #define MASK_28 0xFFFFFFF 147 #define MASK_24 0xFFFFFF 148 #define MASK_20 0xFFFFF 149 #define MASK_16 0xFFFF 150 #define MASK_12 0xFFF 151 #define MASK_8 0xFF 152 #define MASK_4 0xF 153 /* SPI register masks */ 154 155 #define SSP_CPSDVR_MAX 254 156 #define SSP_CPSDVR_MIN 2 157 #define SSP_SCR_MAX 255 158 #define SSP_SCR_MIN 0 159 #define SSP_DATASIZE_MAX 16 160 161 static enum spi_result pl022_txrx8(struct spi_chip *chip, uint8_t *wdat, 162 uint8_t *rdat, size_t num_pkts) 163 { 164 size_t i = 0; 165 size_t j = 0; 166 struct pl022_data *pd = container_of(chip, struct pl022_data, chip); 167 168 169 if (pd->data_size_bits != 8) { 170 EMSG("data_size_bits should be 8, not %u", 171 pd->data_size_bits); 172 return SPI_ERR_CFG; 173 } 174 175 if (wdat) 176 while (i < num_pkts) { 177 if (read8(pd->base + SSPSR) & SSPSR_TNF) { 178 /* tx 1 packet */ 179 write8(wdat[i++], pd->base + SSPDR); 180 } 181 182 if (rdat) 183 if (read8(pd->base + SSPSR) & SSPSR_RNE) { 184 /* rx 1 packet */ 185 rdat[j++] = read8(pd->base + SSPDR); 186 } 187 } 188 189 /* Capture remaining rdat not read above */ 190 if (rdat) { 191 while ((j < num_pkts) && 192 (read8(pd->base + SSPSR) & SSPSR_BSY)) 193 if (read8(pd->base + SSPSR) & SSPSR_RNE) { 194 /* rx 1 packet */ 195 rdat[j++] = read8(pd->base + SSPDR); 196 } 197 198 if (j < num_pkts) { 199 EMSG("Packets requested %zu, received %zu", 200 num_pkts, j); 201 return SPI_ERR_PKTCNT; 202 } 203 } 204 205 return SPI_OK; 206 } 207 208 static enum spi_result pl022_txrx16(struct spi_chip *chip, uint16_t *wdat, 209 uint16_t *rdat, size_t num_pkts) 210 { 211 size_t i = 0; 212 size_t j = 0; 213 struct pl022_data *pd = container_of(chip, struct pl022_data, chip); 214 215 if (pd->data_size_bits != 16) { 216 EMSG("data_size_bits should be 16, not %u", 217 pd->data_size_bits); 218 return SPI_ERR_CFG; 219 } 220 221 if (wdat) 222 while (i < num_pkts) { 223 if (read8(pd->base + SSPSR) & SSPSR_TNF) { 224 /* tx 1 packet */ 225 write16(wdat[i++], pd->base + SSPDR); 226 } 227 228 if (rdat) 229 if (read8(pd->base + SSPSR) & SSPSR_RNE) { 230 /* rx 1 packet */ 231 rdat[j++] = read16(pd->base + SSPDR); 232 } 233 } 234 235 /* Capture remaining rdat not read above */ 236 if (rdat) { 237 while ((j < num_pkts) && 238 (read8(pd->base + SSPSR) & SSPSR_BSY)) 239 if (read8(pd->base + SSPSR) & SSPSR_RNE) { 240 /* rx 1 packet */ 241 rdat[j++] = read16(pd->base + SSPDR); 242 } 243 244 if (j < num_pkts) { 245 EMSG("Packets requested %zu, received %zu", 246 num_pkts, j); 247 return SPI_ERR_PKTCNT; 248 } 249 } 250 251 return SPI_OK; 252 } 253 254 static void pl022_print_peri_id(struct pl022_data *pd __maybe_unused) 255 { 256 DMSG("Expected: 0x 22 10 ?4 00"); 257 DMSG("Read: 0x %02x %02x %02x %02x", 258 read32(pd->base + SSPPeriphID0), 259 read32(pd->base + SSPPeriphID1), 260 read32(pd->base + SSPPeriphID2), 261 read32(pd->base + SSPPeriphID3)); 262 } 263 264 static void pl022_print_cell_id(struct pl022_data *pd __maybe_unused) 265 { 266 DMSG("Expected: 0x 0d f0 05 b1"); 267 DMSG("Read: 0x %02x %02x %02x %02x", 268 read32(pd->base + SSPPCellID0), 269 read32(pd->base + SSPPCellID1), 270 read32(pd->base + SSPPCellID2), 271 read32(pd->base + SSPPCellID3)); 272 } 273 274 static void pl022_sanity_check(struct pl022_data *pd) 275 { 276 assert(pd); 277 assert(pd->chip.ops); 278 assert(pd->cs_control <= PL022_CS_CTRL_MANUAL); 279 switch (pd->cs_control) { 280 case PL022_CS_CTRL_AUTO_GPIO: 281 assert(pd->cs_data.gpio_data.chip); 282 assert(pd->cs_data.gpio_data.chip->ops); 283 break; 284 case PL022_CS_CTRL_CB: 285 assert(pd->cs_data.cs_cb); 286 break; 287 default: 288 break; 289 } 290 assert(pd->clk_hz); 291 assert(pd->speed_hz && pd->speed_hz <= pd->clk_hz/2); 292 assert(pd->mode <= SPI_MODE3); 293 assert(pd->data_size_bits == 8 || pd->data_size_bits == 16); 294 295 #ifdef PLATFORM_hikey 296 DMSG("SSPB2BTRANS: Expected: 0x2. Read: 0x%x", 297 read32(pd->base + SSPB2BTRANS)); 298 #endif 299 pl022_print_peri_id(pd); 300 pl022_print_cell_id(pd); 301 } 302 303 static inline uint32_t pl022_calc_freq(struct pl022_data *pd, 304 uint8_t cpsdvr, uint8_t scr) 305 { 306 return pd->clk_hz / (cpsdvr * (1 + scr)); 307 } 308 309 static void pl022_control_cs(struct spi_chip *chip, enum gpio_level value) 310 { 311 struct pl022_data *pd = container_of(chip, struct pl022_data, chip); 312 313 switch (pd->cs_control) { 314 case PL022_CS_CTRL_AUTO_GPIO: 315 if (read8(pd->base + SSPSR) & SSPSR_BSY) 316 DMSG("pl022 busy - do NOT set CS!"); 317 while (read8(pd->base + SSPSR) & SSPSR_BSY) 318 ; 319 DMSG("pl022 done - set CS!"); 320 321 pd->cs_data.gpio_data.chip->ops->set_value( 322 pd->cs_data.gpio_data.pin_num, value); 323 break; 324 case PL022_CS_CTRL_CB: 325 pd->cs_data.cs_cb(value); 326 break; 327 default: 328 break; 329 } 330 } 331 332 static void pl022_calc_clk_divisors(struct pl022_data *pd, 333 uint8_t *cpsdvr, uint8_t *scr) 334 { 335 unsigned int freq1 = 0; 336 unsigned int freq2 = 0; 337 uint8_t tmp_cpsdvr1; 338 uint8_t tmp_scr1; 339 uint8_t tmp_cpsdvr2 = 0; 340 uint8_t tmp_scr2 = 0; 341 342 for (tmp_scr1 = SSP_SCR_MIN; tmp_scr1 < SSP_SCR_MAX; tmp_scr1++) { 343 for (tmp_cpsdvr1 = SSP_CPSDVR_MIN; tmp_cpsdvr1 < SSP_CPSDVR_MAX; 344 tmp_cpsdvr1++) { 345 freq1 = pl022_calc_freq(pd, tmp_cpsdvr1, tmp_scr1); 346 if (freq1 == pd->speed_hz) 347 goto done; 348 else if (freq1 < pd->speed_hz) 349 goto stage2; 350 } 351 } 352 353 stage2: 354 for (tmp_cpsdvr2 = SSP_CPSDVR_MIN; tmp_cpsdvr2 < SSP_CPSDVR_MAX; 355 tmp_cpsdvr2++) { 356 for (tmp_scr2 = SSP_SCR_MIN; tmp_scr2 < SSP_SCR_MAX; 357 tmp_scr2++) { 358 freq2 = pl022_calc_freq(pd, tmp_cpsdvr2, tmp_scr2); 359 if (freq2 <= pd->speed_hz) 360 goto done; 361 } 362 } 363 364 done: 365 if (freq1 >= freq2) { 366 *cpsdvr = tmp_cpsdvr1; 367 *scr = tmp_scr1; 368 DMSG("speed: requested: %u, closest1: %u", 369 pd->speed_hz, freq1); 370 } else { 371 *cpsdvr = tmp_cpsdvr2; 372 *scr = tmp_scr2; 373 DMSG("speed: requested: %u, closest2: %u", 374 pd->speed_hz, freq2); 375 } 376 DMSG("CPSDVR: %u (0x%x), SCR: %u (0x%x)", 377 *cpsdvr, *cpsdvr, *scr, *scr); 378 } 379 380 static void pl022_flush_fifo(struct pl022_data *pd) 381 { 382 uint32_t __maybe_unused rdat; 383 384 do { 385 while (read32(pd->base + SSPSR) & SSPSR_RNE) { 386 rdat = read32(pd->base + SSPDR); 387 DMSG("rdat: 0x%x", rdat); 388 } 389 } while (read32(pd->base + SSPSR) & SSPSR_BSY); 390 } 391 392 static void pl022_configure(struct spi_chip *chip) 393 { 394 uint16_t mode; 395 uint16_t data_size; 396 uint8_t cpsdvr; 397 uint8_t scr; 398 uint8_t lbm; 399 struct pl022_data *pd = container_of(chip, struct pl022_data, chip); 400 401 pl022_sanity_check(pd); 402 403 switch (pd->cs_control) { 404 case PL022_CS_CTRL_AUTO_GPIO: 405 DMSG("Use auto GPIO CS control"); 406 DMSG("Mask/disable interrupt for CS GPIO"); 407 pd->cs_data.gpio_data.chip->ops->set_interrupt( 408 pd->cs_data.gpio_data.pin_num, 409 GPIO_INTERRUPT_DISABLE); 410 DMSG("Set CS GPIO dir to out"); 411 pd->cs_data.gpio_data.chip->ops->set_direction( 412 pd->cs_data.gpio_data.pin_num, 413 GPIO_DIR_OUT); 414 break; 415 case PL022_CS_CTRL_CB: 416 DMSG("Use registered CS callback"); 417 break; 418 case PL022_CS_CTRL_MANUAL: 419 DMSG("Use manual CS control"); 420 break; 421 default: 422 EMSG("Invalid CS control type: %d", pd->cs_control); 423 panic(); 424 } 425 426 DMSG("Pull CS high"); 427 pl022_control_cs(chip, GPIO_LEVEL_HIGH); 428 429 pl022_calc_clk_divisors(pd, &cpsdvr, &scr); 430 431 /* configure ssp based on platform settings */ 432 switch (pd->mode) { 433 case SPI_MODE0: 434 DMSG("SPI mode 0"); 435 mode = SSPCR0_SPO0 | SSPCR0_SPH0; 436 break; 437 case SPI_MODE1: 438 DMSG("SPI mode 1"); 439 mode = SSPCR0_SPO0 | SSPCR0_SPH1; 440 break; 441 case SPI_MODE2: 442 DMSG("SPI mode 2"); 443 mode = SSPCR0_SPO1 | SSPCR0_SPH0; 444 break; 445 case SPI_MODE3: 446 DMSG("SPI mode 3"); 447 mode = SSPCR0_SPO1 | SSPCR0_SPH1; 448 break; 449 default: 450 EMSG("Invalid SPI mode: %u", pd->mode); 451 panic(); 452 } 453 454 switch (pd->data_size_bits) { 455 case 8: 456 DMSG("Data size: 8"); 457 data_size = SSPCR0_DSS_8BIT; 458 break; 459 case 16: 460 DMSG("Data size: 16"); 461 data_size = SSPCR0_DSS_16BIT; 462 break; 463 default: 464 EMSG("Unsupported data size: %u bits", pd->data_size_bits); 465 panic(); 466 } 467 468 if (pd->loopback) { 469 DMSG("Starting in loopback mode!"); 470 lbm = SSPCR1_LBM_YES; 471 } else { 472 DMSG("Starting in regular (non-loopback) mode!"); 473 lbm = SSPCR1_LBM_NO; 474 } 475 476 DMSG("Set Serial Clock Rate (SCR), SPI mode (phase and clock)"); 477 DMSG("Set frame format (SPI) and data size (8- or 16-bit)"); 478 io_mask16(pd->base + SSPCR0, SHIFT_U32(scr, 8) | mode | SSPCR0_FRF_SPI | 479 data_size, MASK_16); 480 481 DMSG("Set master mode, disable SSP, set loopback mode"); 482 io_mask8(pd->base + SSPCR1, SSPCR1_SOD_DISABLE | SSPCR1_MS_MASTER | 483 SSPCR1_SSE_DISABLE | lbm, MASK_4); 484 485 DMSG("Set clock prescale"); 486 io_mask8(pd->base + SSPCPSR, cpsdvr, SSPCPSR_CPSDVR); 487 488 DMSG("Disable interrupts"); 489 io_mask8(pd->base + SSPIMSC, 0, MASK_4); 490 491 DMSG("Clear interrupts"); 492 io_mask8(pd->base + SSPICR, SSPICR_RORIC | SSPICR_RTIC, 493 SSPICR_RORIC | SSPICR_RTIC); 494 495 DMSG("Empty FIFO before starting"); 496 pl022_flush_fifo(pd); 497 } 498 499 static void pl022_start(struct spi_chip *chip) 500 { 501 struct pl022_data *pd = container_of(chip, struct pl022_data, chip); 502 503 DMSG("Enable SSP"); 504 io_mask8(pd->base + SSPCR1, SSPCR1_SSE_ENABLE, SSPCR1_SSE); 505 506 pl022_control_cs(chip, GPIO_LEVEL_LOW); 507 } 508 509 static void pl022_end(struct spi_chip *chip) 510 { 511 struct pl022_data *pd = container_of(chip, struct pl022_data, chip); 512 513 pl022_control_cs(chip, GPIO_LEVEL_HIGH); 514 515 DMSG("Disable SSP"); 516 io_mask8(pd->base + SSPCR1, SSPCR1_SSE_DISABLE, SSPCR1_SSE); 517 } 518 519 static const struct spi_ops pl022_ops = { 520 .configure = pl022_configure, 521 .start = pl022_start, 522 .txrx8 = pl022_txrx8, 523 .txrx16 = pl022_txrx16, 524 .end = pl022_end, 525 }; 526 527 void pl022_init(struct pl022_data *pd) 528 { 529 assert(pd); 530 pd->chip.ops = &pl022_ops; 531 } 532