MAINTAINERS: Add Yuchi and Vasiliy for Intel Atom Snow Ridge SoC
[coreboot.git] / src / soc / qualcomm / ipq806x / spi.c
blobdd478c4020efb0b83c332ab47870832329dfba3d
1 /* SPDX-License-Identifier: GPL-2.0-only */
3 #include <device/mmio.h>
4 #include <console/console.h>
5 #include <delay.h>
6 #include <gpio.h>
7 #include <soc/iomap.h>
8 #include <soc/spi.h>
9 #include <types.h>
11 #define SUCCESS 0
13 #define DUMMY_DATA_VAL 0
14 #define TIMEOUT_CNT 100
15 #define CS_ASSERT 1
16 #define CS_DEASSERT 0
17 #define NUM_PORTS 3
18 #define NUM_GSBI_PINS 3
19 #define TLMM_ARGS 6
20 #define NUM_CS 4
21 #define GSBI_PIN_IDX 0
22 #define FUNC_SEL_IDX 1
23 #define GPIO_DIR_IDX 2
24 #define PULL_CONF_IDX 3
25 #define DRV_STR_IDX 4
26 #define GPIO_EN_IDX 5
28 /* Arbitrarily assigned error code values */
29 #define ETIMEDOUT -10
30 #define EINVAL -11
31 #define EIO -12
33 #define GSBI_IDX_TO_GSBI(idx) (idx + 5)
35 /* MX_INPUT_COUNT and MX_OUTPUT_COUNT are 16-bits. Zero has a special meaning
36 * (count function disabled) and does not hold significance in the count. */
37 #define MAX_PACKET_COUNT ((64 * KiB) - 1)
40 * TLMM Configuration for SPI NOR
41 * gsbi_pin_conf[bus_num][GPIO_NUM, FUNC_SEL, I/O,
42 * PULL UP/DOWN, DRV_STR, GPIO_FUNC]
43 * gsbi_pin_conf[0][x][y] -- GSBI5
44 * gsbi_pin_conf[1][x][y] -- GSBI6
45 * gsbi_pin_conf[2][x][y] -- GSBI7
47 static unsigned int gsbi_pin_conf[NUM_PORTS][NUM_GSBI_PINS][TLMM_ARGS] = {
49 /* GSBI5 CLK */
51 GSBI5_SPI_CLK, FUNC_SEL_1, GPIO_INPUT,
52 GPIO_PULL_DOWN, GPIO_DRV_STR_11MA, GPIO_FUNC_DISABLE
54 /* GSBI5 MISO */
56 GSBI5_SPI_MISO, FUNC_SEL_1, GPIO_INPUT,
57 GPIO_PULL_DOWN, GPIO_DRV_STR_10MA, GPIO_FUNC_DISABLE
59 /* GSBI5 MOSI */
61 GSBI5_SPI_MOSI, FUNC_SEL_1, GPIO_INPUT,
62 GPIO_PULL_DOWN, GPIO_DRV_STR_10MA, GPIO_FUNC_DISABLE
66 /* GSBI6 CLK */
68 GSBI6_SPI_CLK, FUNC_SEL_3, GPIO_INPUT,
69 GPIO_PULL_DOWN, GPIO_DRV_STR_11MA, GPIO_FUNC_DISABLE
71 /* GSBI6 MISO */
73 GSBI6_SPI_MISO, FUNC_SEL_3, GPIO_INPUT,
74 GPIO_PULL_DOWN, GPIO_DRV_STR_10MA, GPIO_FUNC_DISABLE
76 /* GSBI6 MOSI */
78 GSBI6_SPI_MOSI, FUNC_SEL_3, GPIO_INPUT,
79 GPIO_PULL_DOWN, GPIO_DRV_STR_10MA, GPIO_FUNC_DISABLE
83 /* GSBI7 CLK */
85 GSBI7_SPI_CLK, FUNC_SEL_1, GPIO_INPUT,
86 GPIO_PULL_DOWN, GPIO_DRV_STR_11MA, GPIO_FUNC_DISABLE
88 /* GSBI7 MISO */
90 GSBI7_SPI_MISO, FUNC_SEL_1, GPIO_INPUT,
91 GPIO_PULL_DOWN, GPIO_DRV_STR_10MA, GPIO_FUNC_DISABLE
93 /* GSBI7 MOSI */
95 GSBI7_SPI_MOSI, FUNC_SEL_1, GPIO_INPUT,
96 GPIO_PULL_DOWN, GPIO_DRV_STR_10MA, GPIO_FUNC_DISABLE
102 * CS GPIO number array cs_gpio_array[port_num][cs_num]
103 * cs_gpio_array[0][x] -- GSBI5
104 * cs_gpio_array[1][x] -- GSBI6
105 * cs_gpio_array[2][x] -- GSBI7
107 static unsigned int cs_gpio_array[NUM_PORTS][NUM_CS] = {
109 GSBI5_SPI_CS_0, GSBI5_SPI_CS_1, GSBI5_SPI_CS_2, GSBI5_SPI_CS_3
112 GSBI6_SPI_CS_0, 0, 0, 0
115 GSBI7_SPI_CS_0, 0, 0, 0
120 * GSBI HCLK state register bit
121 * hclk_state[0] -- GSBI5
122 * hclk_state[1] -- GSBI6
123 * hclk_state[2] -- GSBI7
125 static unsigned int hclk_state[NUM_PORTS] = {
126 GSBI5_HCLK,
127 GSBI6_HCLK,
128 GSBI7_HCLK
132 * GSBI QUP_APPS_CLK state register bit
133 * qup_apps_clk_state[0] -- GSBI5
134 * qup_apps_clk_state[1] -- GSBI6
135 * qup_apps_clk_state[2] -- GSBI7
137 static unsigned int qup_apps_clk_state[NUM_PORTS] = {
138 GSBI5_QUP_APPS_CLK,
139 GSBI6_QUP_APPS_CLK,
140 GSBI7_QUP_APPS_CLK
143 static int check_bit_state(uint32_t reg_addr, int bit_num, int val, int us_delay)
145 unsigned int count = TIMEOUT_CNT;
146 unsigned int bit_val = ((readl_i(reg_addr) >> bit_num) & 0x01);
148 while (bit_val != val) {
149 count--;
150 if (count == 0)
151 return -ETIMEDOUT;
152 udelay(us_delay);
153 bit_val = ((readl_i(reg_addr) >> bit_num) & 0x01);
156 return SUCCESS;
160 * Check whether GSBIn_QUP State is valid
162 static int check_qup_state_valid(struct ipq_spi_slave *ds)
164 return check_bit_state(ds->regs->qup_state, QUP_STATE_VALID_BIT,
165 QUP_STATE_VALID, 1);
169 * Configure GSBIn Core state
171 static int config_spi_state(struct ipq_spi_slave *ds, unsigned int state)
173 uint32_t val;
174 int ret;
175 uint32_t new_state;
177 ret = check_qup_state_valid(ds);
178 if (ret != SUCCESS)
179 return ret;
181 switch (state) {
182 case SPI_RUN_STATE:
183 new_state = QUP_STATE_RUN_STATE;
184 break;
186 case SPI_RESET_STATE:
187 new_state = QUP_STATE_RESET_STATE;
188 break;
190 case SPI_PAUSE_STATE:
191 new_state = QUP_STATE_PAUSE_STATE;
192 break;
194 default:
195 printk(BIOS_ERR,
196 "err: unsupported GSBI SPI state : %d\n", state);
197 return -EINVAL;
200 /* Set the state as requested */
201 val = (readl_i(ds->regs->qup_state) & ~QUP_STATE_MASK)
202 | new_state;
203 writel_i(val, ds->regs->qup_state);
204 return check_qup_state_valid(ds);
208 * Set GSBIn SPI Mode
210 static void spi_set_mode(struct ipq_spi_slave *ds, unsigned int mode)
212 unsigned int clk_idle_state;
213 unsigned int input_first_mode;
214 uint32_t val;
216 switch (mode) {
217 case GSBI_SPI_MODE_0:
218 clk_idle_state = 0;
219 input_first_mode = SPI_INPUT_FIRST_MODE;
220 break;
221 case GSBI_SPI_MODE_1:
222 clk_idle_state = 0;
223 input_first_mode = 0;
224 break;
225 case GSBI_SPI_MODE_2:
226 clk_idle_state = 1;
227 input_first_mode = SPI_INPUT_FIRST_MODE;
228 break;
229 case GSBI_SPI_MODE_3:
230 clk_idle_state = 1;
231 input_first_mode = 0;
232 break;
233 default:
234 printk(BIOS_ERR,
235 "err : unsupported spi mode : %d\n", mode);
236 return;
239 val = readl_i(ds->regs->spi_config);
240 val |= input_first_mode;
241 writel_i(val, ds->regs->spi_config);
243 val = readl_i(ds->regs->io_control);
244 if (clk_idle_state)
245 val |= SPI_IO_CONTROL_CLOCK_IDLE_HIGH;
246 else
247 val &= ~SPI_IO_CONTROL_CLOCK_IDLE_HIGH;
249 writel_i(val, ds->regs->io_control);
253 * Check for HCLK state
255 static int check_hclk_state(unsigned int core_num, int enable)
257 return check_bit_state(CLK_HALT_CFPB_STATEB_REG,
258 hclk_state[core_num], enable, 5);
262 * Check for QUP APPS CLK state
264 static int check_qup_clk_state(unsigned int core_num, int enable)
266 return check_bit_state(CLK_HALT_CFPB_STATEB_REG,
267 qup_apps_clk_state[core_num], enable, 5);
271 * Function to assert and De-assert chip select
273 static void CS_change(int port_num, int cs_num, int enable)
275 unsigned int cs_gpio = cs_gpio_array[port_num][cs_num];
276 void *addr = GPIO_IN_OUT_ADDR(cs_gpio);
277 uint32_t val = readl_i(addr);
279 val &= (~(1 << GPIO_OUTPUT));
280 if (!enable)
281 val |= (1 << GPIO_OUTPUT);
282 write32(addr, val);
286 * GSBIn TLMM configuration
288 static void gsbi_pin_config(unsigned int port_num, int cs_num)
290 unsigned int gpio;
291 unsigned int i;
292 /* Hold the GSBIn (core_num) core in reset */
293 clrsetbits32_i(GSBIn_RESET_REG(GSBI_IDX_TO_GSBI(port_num)),
294 GSBI1_RESET_MSK, GSBI1_RESET);
297 * Configure SPI_CLK, SPI_MISO and SPI_MOSI
299 for (i = 0; i < NUM_GSBI_PINS; i++) {
300 unsigned int func_sel;
301 unsigned int io_config;
302 unsigned int pull_config;
303 unsigned int drv_strength;
304 unsigned int gpio_en;
305 unsigned int *ptr;
307 ptr = gsbi_pin_conf[port_num][i];
308 gpio = *(ptr + GSBI_PIN_IDX);
309 func_sel = *(ptr + FUNC_SEL_IDX);
310 io_config = *(ptr + GPIO_DIR_IDX);
311 pull_config = *(ptr + PULL_CONF_IDX);
312 drv_strength = *(ptr + DRV_STR_IDX);
313 gpio_en = *(ptr + GPIO_EN_IDX);
315 gpio_tlmm_config(gpio, func_sel, io_config,
316 pull_config, drv_strength, gpio_en);
319 gpio = cs_gpio_array[port_num][cs_num];
320 /* configure CS */
321 gpio_tlmm_config(gpio, FUNC_SEL_GPIO, GPIO_OUTPUT, GPIO_PULL_UP,
322 GPIO_DRV_STR_10MA, GPIO_FUNC_ENABLE);
323 CS_change(port_num, cs_num, CS_DEASSERT);
327 * Clock configuration for GSBIn Core
329 static int gsbi_clock_init(struct ipq_spi_slave *ds)
331 int ret;
333 /* Hold the GSBIn (core_num) core in reset */
334 clrsetbits32_i(GSBIn_RESET_REG(GSBI_IDX_TO_GSBI(ds->slave.bus)),
335 GSBI1_RESET_MSK, GSBI1_RESET);
337 /* Disable GSBIn (core_num) QUP core clock branch */
338 clrsetbits32_i(ds->regs->qup_ns_reg, QUP_CLK_BRANCH_ENA_MSK,
339 QUP_CLK_BRANCH_DIS);
341 ret = check_qup_clk_state(ds->slave.bus, 1);
342 if (ret) {
343 printk(BIOS_ERR,
344 "QUP Clock Halt For GSBI%d failed!\n", ds->slave.bus);
345 return ret;
348 /* Disable M/N:D counter and hold M/N:D counter in reset */
349 clrsetbits32_i(ds->regs->qup_ns_reg, (MNCNTR_MSK | MNCNTR_RST_MSK),
350 (MNCNTR_RST_ENA | MNCNTR_DIS));
352 /* Disable GSBIn (core_num) QUP core clock root */
353 clrsetbits32_i(ds->regs->qup_ns_reg, CLK_ROOT_ENA_MSK, CLK_ROOT_DIS);
355 clrsetbits32_i(ds->regs->qup_ns_reg, GSBIn_PLL_SRC_MSK,
356 GSBIn_PLL_SRC_PLL8);
357 clrsetbits32_i(ds->regs->qup_ns_reg, GSBIn_PRE_DIV_SEL_MSK,
358 (0 << GSBI_PRE_DIV_SEL_SHFT));
360 /* Program M/N:D values for GSBIn_QUP_APPS_CLK @50MHz */
361 clrsetbits32_i(ds->regs->qup_md_reg, GSBIn_M_VAL_MSK,
362 (0x01 << GSBI_M_VAL_SHFT));
363 clrsetbits32_i(ds->regs->qup_md_reg, GSBIn_D_VAL_MSK,
364 (0xF7 << GSBI_D_VAL_SHFT));
365 clrsetbits32_i(ds->regs->qup_ns_reg, GSBIn_N_VAL_MSK,
366 (0xF8 << GSBI_N_VAL_SHFT));
368 /* Set MNCNTR_MODE = 0: Bypass mode */
369 clrsetbits32_i(ds->regs->qup_ns_reg, MNCNTR_MODE_MSK,
370 MNCNTR_MODE_DUAL_EDGE);
372 /* De-assert the M/N:D counter reset */
373 clrsetbits32_i(ds->regs->qup_ns_reg, MNCNTR_RST_MSK, MNCNTR_RST_DIS);
374 clrsetbits32_i(ds->regs->qup_ns_reg, MNCNTR_MSK, MNCNTR_EN);
377 * Enable the GSBIn (core_num) QUP core clock root.
378 * Keep MND counter disabled
380 clrsetbits32_i(ds->regs->qup_ns_reg, CLK_ROOT_ENA_MSK, CLK_ROOT_ENA);
382 /* Enable GSBIn (core_num) QUP core clock branch */
383 clrsetbits32_i(ds->regs->qup_ns_reg, QUP_CLK_BRANCH_ENA_MSK,
384 QUP_CLK_BRANCH_ENA);
386 ret = check_qup_clk_state(ds->slave.bus, 0);
387 if (ret) {
388 printk(BIOS_ERR,
389 "QUP Clock Enable For GSBI%d"
390 " failed!\n", ds->slave.bus);
391 return ret;
394 /* Enable GSBIn (core_num) core clock branch */
395 clrsetbits32_i(GSBIn_HCLK_CTL_REG(GSBI_IDX_TO_GSBI(ds->slave.bus)),
396 GSBI_CLK_BRANCH_ENA_MSK, GSBI_CLK_BRANCH_ENA);
398 ret = check_hclk_state(ds->slave.bus, 0);
399 if (ret) {
400 printk(BIOS_ERR,
401 "HCLK Enable For GSBI%d failed!\n", ds->slave.bus);
402 return ret;
405 /* Release GSBIn (core_num) core from reset */
406 clrsetbits32_i(GSBIn_RESET_REG(GSBI_IDX_TO_GSBI(ds->slave.bus)),
407 GSBI1_RESET_MSK, 0);
408 udelay(50);
410 return SUCCESS;
414 * Reset entire QUP and all mini cores
416 static void spi_reset(struct ipq_spi_slave *ds)
418 writel_i(0x1, ds->regs->qup_sw_reset);
419 udelay(5);
422 static const struct gsbi_spi spi_reg[] = {
423 /* GSBI5 registers for SPI interface */
425 GSBI5_SPI_CONFIG_REG,
426 GSBI5_SPI_IO_CONTROL_REG,
427 GSBI5_SPI_ERROR_FLAGS_REG,
428 GSBI5_SPI_ERROR_FLAGS_EN_REG,
429 GSBI5_GSBI_CTRL_REG_REG,
430 GSBI5_QUP_CONFIG_REG,
431 GSBI5_QUP_ERROR_FLAGS_REG,
432 GSBI5_QUP_ERROR_FLAGS_EN_REG,
433 GSBI5_QUP_OPERATIONAL_REG,
434 GSBI5_QUP_IO_MODES_REG,
435 GSBI5_QUP_STATE_REG,
436 GSBI5_QUP_INPUT_FIFOc_REG(0),
437 GSBI5_QUP_OUTPUT_FIFOc_REG(0),
438 GSBI5_QUP_MX_INPUT_COUNT_REG,
439 GSBI5_QUP_MX_OUTPUT_COUNT_REG,
440 GSBI5_QUP_SW_RESET_REG,
441 GSBIn_QUP_APPS_NS_REG(5),
442 GSBIn_QUP_APPS_MD_REG(5),
444 /* GSBI6 registers for SPI interface */
446 GSBI6_SPI_CONFIG_REG,
447 GSBI6_SPI_IO_CONTROL_REG,
448 GSBI6_SPI_ERROR_FLAGS_REG,
449 GSBI6_SPI_ERROR_FLAGS_EN_REG,
450 GSBI6_GSBI_CTRL_REG_REG,
451 GSBI6_QUP_CONFIG_REG,
452 GSBI6_QUP_ERROR_FLAGS_REG,
453 GSBI6_QUP_ERROR_FLAGS_EN_REG,
454 GSBI6_QUP_OPERATIONAL_REG,
455 GSBI6_QUP_IO_MODES_REG,
456 GSBI6_QUP_STATE_REG,
457 GSBI6_QUP_INPUT_FIFOc_REG(0),
458 GSBI6_QUP_OUTPUT_FIFOc_REG(0),
459 GSBI6_QUP_MX_INPUT_COUNT_REG,
460 GSBI6_QUP_MX_OUTPUT_COUNT_REG,
461 GSBI6_QUP_SW_RESET_REG,
462 GSBIn_QUP_APPS_NS_REG(6),
463 GSBIn_QUP_APPS_MD_REG(6),
465 /* GSBI7 registers for SPI interface */
467 GSBI7_SPI_CONFIG_REG,
468 GSBI7_SPI_IO_CONTROL_REG,
469 GSBI7_SPI_ERROR_FLAGS_REG,
470 GSBI7_SPI_ERROR_FLAGS_EN_REG,
471 GSBI7_GSBI_CTRL_REG_REG,
472 GSBI7_QUP_CONFIG_REG,
473 GSBI7_QUP_ERROR_FLAGS_REG,
474 GSBI7_QUP_ERROR_FLAGS_EN_REG,
475 GSBI7_QUP_OPERATIONAL_REG,
476 GSBI7_QUP_IO_MODES_REG,
477 GSBI7_QUP_STATE_REG,
478 GSBI7_QUP_INPUT_FIFOc_REG(0),
479 GSBI7_QUP_OUTPUT_FIFOc_REG(0),
480 GSBI7_QUP_MX_INPUT_COUNT_REG,
481 GSBI7_QUP_MX_OUTPUT_COUNT_REG,
482 GSBI7_QUP_SW_RESET_REG,
483 GSBIn_QUP_APPS_NS_REG(7),
484 GSBIn_QUP_APPS_MD_REG(7),
487 static struct ipq_spi_slave spi_slave_pool[2];
489 static struct ipq_spi_slave *to_ipq_spi(const struct spi_slave *slave)
491 struct ipq_spi_slave *ds;
492 size_t i;
494 for (i = 0; i < ARRAY_SIZE(spi_slave_pool); i++) {
495 ds = spi_slave_pool + i;
497 if (!ds->allocated)
498 continue;
500 if ((ds->slave.bus == slave->bus) &&
501 (ds->slave.cs == slave->cs))
502 return ds;
505 return NULL;
509 * GSBIn SPI Hardware Initialisation
511 static int spi_hw_init(struct ipq_spi_slave *ds)
513 int ret;
515 if (ds->initialized)
516 return 0;
518 /* GSBI module configuration */
519 spi_reset(ds);
521 /* Set the GSBIn QUP state */
522 ret = config_spi_state(ds, SPI_RESET_STATE);
523 if (ret)
524 return ret;
526 /* Configure GSBI_CTRL register to set protocol_mode to SPI:011 */
527 clrsetbits32_i(ds->regs->gsbi_ctrl, PROTOCOL_CODE_MSK,
528 PROTOCOL_CODE_SPI);
531 * Configure Mini core to SPI core with Input Output enabled,
532 * SPI master, N = 8 bits
534 clrsetbits32_i(ds->regs->qup_config, (QUP_CONFIG_MINI_CORE_MSK |
535 SPI_QUP_CONF_INPUT_MSK |
536 SPI_QUP_CONF_OUTPUT_MSK |
537 SPI_BIT_WORD_MSK),
538 (QUP_CONFIG_MINI_CORE_SPI |
539 SPI_QUP_CONF_NO_INPUT |
540 SPI_QUP_CONF_NO_OUTPUT |
541 SPI_8_BIT_WORD));
544 * Configure Input first SPI protocol,
545 * SPI master mode and no loopback
547 clrsetbits32_i(ds->regs->spi_config, (LOOP_BACK_MSK |
548 SLAVE_OPERATION_MSK),
549 (NO_LOOP_BACK |
550 SLAVE_OPERATION));
553 * Configure SPI IO Control Register
554 * CLK_ALWAYS_ON = 0
555 * MX_CS_MODE = 0
556 * NO_TRI_STATE = 1
558 writel_i((CLK_ALWAYS_ON | MX_CS_MODE | NO_TRI_STATE),
559 ds->regs->io_control);
562 * Configure SPI IO Modes.
563 * OUTPUT_BIT_SHIFT_EN = 1
564 * INPUT_MODE = Block Mode
565 * OUTPUT MODE = Block Mode
567 clrsetbits32_i(ds->regs->qup_io_modes, (OUTPUT_BIT_SHIFT_MSK |
568 INPUT_BLOCK_MODE_MSK |
569 OUTPUT_BLOCK_MODE_MSK),
570 (OUTPUT_BIT_SHIFT_EN |
571 INPUT_BLOCK_MODE |
572 OUTPUT_BLOCK_MODE));
574 spi_set_mode(ds, ds->mode);
576 /* Disable Error mask */
577 writel_i(0, ds->regs->error_flags_en);
578 writel_i(0, ds->regs->qup_error_flags_en);
580 ds->initialized = 1;
582 return SUCCESS;
585 static int spi_ctrlr_claim_bus(const struct spi_slave *slave)
587 struct ipq_spi_slave *ds = to_ipq_spi(slave);
588 unsigned int ret;
590 if (ds->initialized)
591 return SUCCESS;
593 /* GPIO Configuration for SPI port */
594 gsbi_pin_config(ds->slave.bus, ds->slave.cs);
596 /* Clock configuration */
597 ret = gsbi_clock_init(ds);
598 if (ret)
599 return ret;
601 ret = spi_hw_init(ds);
602 if (ret)
603 return -EIO;
605 return SUCCESS;
608 static void spi_ctrlr_release_bus(const struct spi_slave *slave)
610 struct ipq_spi_slave *ds = to_ipq_spi(slave);
612 /* Reset the SPI hardware */
613 spi_reset(ds);
614 ds->initialized = 0;
617 static int spi_xfer_tx_packet(struct ipq_spi_slave *ds,
618 const uint8_t *dout, unsigned int out_bytes)
620 int ret;
622 writel_i(out_bytes, ds->regs->qup_mx_output_count);
624 ret = config_spi_state(ds, SPI_RUN_STATE);
625 if (ret)
626 return ret;
628 while (out_bytes) {
629 if (readl_i(ds->regs->qup_operational) & QUP_OUTPUT_FIFO_FULL)
630 continue;
632 writel_i(*dout++, ds->regs->qup_output_fifo);
633 out_bytes--;
635 /* Wait for output FIFO to drain. */
636 if (!out_bytes)
637 while (readl_i(ds->regs->qup_operational) &
638 QUP_OUTPUT_FIFO_NOT_EMPTY)
642 return config_spi_state(ds, SPI_RESET_STATE);
645 static int spi_xfer_rx_packet(struct ipq_spi_slave *ds,
646 uint8_t *din, unsigned int in_bytes)
648 int ret;
650 writel_i(in_bytes, ds->regs->qup_mx_input_count);
651 writel_i(in_bytes, ds->regs->qup_mx_output_count);
653 ret = config_spi_state(ds, SPI_RUN_STATE);
654 if (ret)
655 return ret;
657 /* Seed clocking */
658 writel_i(0xff, ds->regs->qup_output_fifo);
659 while (in_bytes) {
660 if (!(readl_i(ds->regs->qup_operational) &
661 QUP_INPUT_FIFO_NOT_EMPTY))
662 continue;
663 /* Keep it clocking */
664 writel_i(0xff, ds->regs->qup_output_fifo);
666 *din++ = readl_i(ds->regs->qup_input_fifo) & 0xff;
667 in_bytes--;
670 return config_spi_state(ds, SPI_RESET_STATE);
673 static int spi_ctrlr_xfer(const struct spi_slave *slave, const void *dout,
674 size_t out_bytes, void *din, size_t in_bytes)
676 int ret;
677 struct ipq_spi_slave *ds = to_ipq_spi(slave);
679 /* Assert the chip select */
680 CS_change(ds->slave.bus, ds->slave.cs, CS_ASSERT);
682 ret = config_spi_state(ds, SPI_RESET_STATE);
683 if (ret)
684 goto out;
686 if (!out_bytes)
687 goto spi_receive;
690 * Let's do the write side of the transaction first. Enable output
691 * FIFO.
693 clrsetbits32_i(ds->regs->qup_config, SPI_QUP_CONF_OUTPUT_MSK,
694 SPI_QUP_CONF_OUTPUT_ENA);
696 while (out_bytes) {
697 unsigned int todo = MIN(out_bytes, MAX_PACKET_COUNT);
699 ret = spi_xfer_tx_packet(ds, dout, todo);
700 if (ret)
701 break;
703 out_bytes -= todo;
704 dout += todo;
707 if (ret)
708 goto out;
710 spi_receive:
711 if (!in_bytes) /* Nothing to read. */
712 goto out;
714 /* Enable input FIFO */
715 clrsetbits32_i(ds->regs->qup_config, SPI_QUP_CONF_INPUT_MSK,
716 SPI_QUP_CONF_INPUT_ENA);
718 while (in_bytes) {
719 unsigned int todo = MIN(in_bytes, MAX_PACKET_COUNT);
721 ret = spi_xfer_rx_packet(ds, din, todo);
722 if (ret)
723 break;
725 in_bytes -= todo;
726 din += todo;
729 out:
730 /* Deassert CS */
731 CS_change(ds->slave.bus, ds->slave.cs, CS_DEASSERT);
734 * Put the SPI Core back in the Reset State
735 * to end the transfer
737 (void)config_spi_state(ds, SPI_RESET_STATE);
739 return ret;
742 static int spi_ctrlr_setup(const struct spi_slave *slave)
744 struct ipq_spi_slave *ds = NULL;
745 int i;
746 int bus = slave->bus;
747 int cs = slave->cs;
750 * IPQ GSBI (Generic Serial Bus Interface) supports SPI Flash
751 * on different GSBI5, GSBI6 and GSBI7
752 * with different number of chip selects (CS, channels):
754 if ((bus < GSBI5_SPI) || (bus > GSBI7_SPI)
755 || ((bus == GSBI5_SPI) && (cs > 3))
756 || ((bus == GSBI6_SPI) && (cs > 0))
757 || ((bus == GSBI7_SPI) && (cs > 0))) {
758 printk(BIOS_ERR, "SPI error: unsupported bus %d "
759 "(Supported buses 0,1 and 2) or chipselect\n", bus);
762 for (i = 0; i < ARRAY_SIZE(spi_slave_pool); i++) {
763 if (spi_slave_pool[i].allocated)
764 continue;
765 ds = spi_slave_pool + i;
767 ds->slave.bus = bus;
768 ds->slave.cs = cs;
769 ds->regs = &spi_reg[bus];
772 * TODO(vbendeb):
773 * hardcoded frequency and mode - we might need to find a way
774 * to configure this
776 ds->freq = 10000000;
777 ds->mode = GSBI_SPI_MODE_0;
778 ds->allocated = 1;
780 return 0;
783 printk(BIOS_ERR, "SPI error: all %d pools busy\n", i);
784 return -1;
787 static const struct spi_ctrlr spi_ctrlr = {
788 .setup = spi_ctrlr_setup,
789 .claim_bus = spi_ctrlr_claim_bus,
790 .release_bus = spi_ctrlr_release_bus,
791 .xfer = spi_ctrlr_xfer,
792 .max_xfer_size = MAX_PACKET_COUNT,
795 const struct spi_ctrlr_buses spi_ctrlr_bus_map[] = {
797 .ctrlr = &spi_ctrlr,
798 .bus_start = GSBI5_SPI,
799 .bus_end = GSBI7_SPI,
803 const size_t spi_ctrlr_bus_map_count = ARRAY_SIZE(spi_ctrlr_bus_map);