nsekar@codeaurora.org has uploaded this change for review. ( https://review.coreboot.org/c/coreboot/+/31177
Change subject: Qcs405: Add SPI chip select assert/de-assert in claim/release bus ......................................................................
Qcs405: Add SPI chip select assert/de-assert in claim/release bus
Add SPI chip select assert/de-assert in claim/release bus. Configure IO in SPI write function and the keep QUP into run state. Add timeout condition in both SPI write and read functions.
Change-Id: Ib8fce5f1890ed3693ee0620cbc0e665d82ce3204 Signed-off-by: Prudhvi Yarlagadda pyarlaga@codeaurora.org --- M src/soc/qualcomm/qcs405/clock.c M src/soc/qualcomm/qcs405/include/soc/qup.h M src/soc/qualcomm/qcs405/spi.c 3 files changed, 97 insertions(+), 51 deletions(-)
git pull ssh://review.coreboot.org:29418/coreboot refs/changes/77/31177/1
diff --git a/src/soc/qualcomm/qcs405/clock.c b/src/soc/qualcomm/qcs405/clock.c index 41f74be..bccefa7 100644 --- a/src/soc/qualcomm/qcs405/clock.c +++ b/src/soc/qualcomm/qcs405/clock.c @@ -63,6 +63,16 @@ };
struct clock_config spi_cfg[] = { + { + .hz = 1000000, + .hw_ctl = 0x0, + .src = SRC_XO_19_2MHZ, + .div = DIV(48), + //.m = 1, + //.n = 2, + //.d_2 = 4, + }, + { .hz = 19200000, .hw_ctl = 0x0, @@ -210,7 +220,7 @@ REG(GCC_APCS_CLOCK_BRANCH_ENA_VOTE), BLSP1_AHB_CLK_ENA);
- clock_configure(blsp1_qup4_spi_clk, spi_cfg, 50000000, + clock_configure(blsp1_qup4_spi_clk, spi_cfg, 1000000, ARRAY_SIZE(spi_cfg)); clock_enable(REG(GCC_BLSP1_QUP4_SPI_APPS_CBCR)); clock_enable_vote(REG(GCC_BLSP1_AHB_CBCR), diff --git a/src/soc/qualcomm/qcs405/include/soc/qup.h b/src/soc/qualcomm/qcs405/include/soc/qup.h index 211b44e..5c1c429 100644 --- a/src/soc/qualcomm/qcs405/include/soc/qup.h +++ b/src/soc/qualcomm/qcs405/include/soc/qup.h @@ -71,6 +71,8 @@ #define OUTPUT_FIFO_FULL (1<<6) #define INPUT_FIFO_NOT_EMPTY (1<<5) #define OUTPUT_FIFO_NOT_EMPTY (1<<4) +#define MAX_OUTPUT_DONE_FLAG (1<<10) +#define MAX_INPUT_DONE_FLAG (1<<11) #define INPUT_SERVICE_FLAG (1<<9) #define OUTPUT_SERVICE_FLAG (1<<8) #define QUP_UNPACK_EN (1<<14) diff --git a/src/soc/qualcomm/qcs405/spi.c b/src/soc/qualcomm/qcs405/spi.c index bd88462..1038881 100644 --- a/src/soc/qualcomm/qcs405/spi.c +++ b/src/soc/qualcomm/qcs405/spi.c @@ -36,6 +36,7 @@ #include <stdlib.h> #include <string.h> #include <spi_flash.h> +#include <timer.h>
static const struct blsp_spi spi_reg[] = { /* BLSP0 registers for SPI interface */ @@ -320,47 +321,6 @@ return SUCCESS; }
-static int spi_ctrlr_claim_bus(const struct spi_slave *slave) -{ - struct ipq_spi_slave *ds = to_ipq_spi(slave); - unsigned int ret; - - ret = spi_hw_init(ds); - if (ret) - return -EIO; - switch(slave->bus) { - case 5: - - gpio_configure(GPIO(26), 3, GPIO_NO_PULL, GPIO_16MA, GPIO_INPUT); - gpio_configure(GPIO(27), 3, GPIO_NO_PULL, GPIO_16MA, GPIO_INPUT); - gpio_configure(GPIO(28), 4, GPIO_PULL_UP, GPIO_16MA, GPIO_INPUT); - gpio_configure(GPIO(29), 4, GPIO_NO_PULL, GPIO_16MA, GPIO_INPUT); - - break; - case 4: - gpio_configure(GPIO(37), 2, GPIO_NO_PULL, GPIO_16MA, GPIO_INPUT); - gpio_configure(GPIO(38), 2, GPIO_NO_PULL, GPIO_16MA, GPIO_INPUT); - gpio_configure(GPIO(117), 2, GPIO_PULL_UP, GPIO_16MA, GPIO_INPUT); - gpio_configure(GPIO(118), 2, GPIO_NO_PULL, GPIO_16MA, GPIO_INPUT); - break; - default: - printk(BIOS_ERR, "SPI error: unsupported bus %d (Supported busses 0, 1, 2, 3, 4, 5) ", slave->bus); - break; - } - - - return SUCCESS; -} - -static void spi_ctrlr_release_bus(const struct spi_slave *slave) -{ - struct ipq_spi_slave *ds = to_ipq_spi(slave); - - /* Reset the SPI hardware */ - spi_reset(ds); - ds->initialized = 0; -} - static void write_force_cs(const struct spi_slave *slave, int assert) { struct ipq_spi_slave *ds = to_ipq_spi(slave); @@ -380,6 +340,56 @@ return; }
+ +static int spi_ctrlr_claim_bus(const struct spi_slave *slave) +{ + struct ipq_spi_slave *ds = to_ipq_spi(slave); + unsigned int ret; + + ret = spi_hw_init(ds); + if (ret) + return -EIO; + switch(slave->bus) { + case 4: + gpio_configure(GPIO(37), 2, + GPIO_PULL_DOWN, GPIO_6MA, GPIO_INPUT); //MISO - IN + gpio_configure(GPIO(38), 2, + GPIO_PULL_DOWN, GPIO_6MA, GPIO_OUTPUT); //MOSI - Out + gpio_configure(GPIO(117), 2, + GPIO_NO_PULL, GPIO_6MA, GPIO_OUTPUT); //SCLK - out + gpio_configure(GPIO(118), 2, + GPIO_PULL_DOWN, GPIO_6MA, GPIO_OUTPUT); //CS_0 - out + + break; + case 5: + + gpio_configure(GPIO(26), 3, GPIO_NO_PULL, GPIO_16MA, GPIO_INPUT); + gpio_configure(GPIO(27), 3, GPIO_NO_PULL, GPIO_16MA, GPIO_INPUT); + gpio_configure(GPIO(28), 4, GPIO_PULL_UP, GPIO_16MA, GPIO_INPUT); + gpio_configure(GPIO(29), 4, GPIO_NO_PULL, GPIO_16MA, GPIO_INPUT); + + break; + default: + printk(BIOS_ERR, "SPI error: unsupported bus %d (Supported busses 0, 1, 2, 3, 4, 5) ", slave->bus); + break; + } + + write_force_cs(slave, 1); + + + return SUCCESS; +} + +static void spi_ctrlr_release_bus(const struct spi_slave *slave) +{ + struct ipq_spi_slave *ds = to_ipq_spi(slave); + + /* Reset the SPI hardware */ + write_force_cs(slave, 0); + spi_reset(ds); + ds->initialized = 0; +} + /* * Function to write data to OUTPUT FIFO */ @@ -465,6 +475,7 @@ unsigned int fifo_count; int ret = SUCCESS; int state_config; + struct stopwatch sw;
/* Configure no of bytes to read */ state_config = config_spi_state(ds, QUP_STATE_RESET); @@ -505,6 +516,18 @@ } }
+ stopwatch_init_msecs_expire(&sw, 10); + + do { + val = read32(ds->regs->qup_operational); + if (stopwatch_expired(&sw)) { + printk(BIOS_ERR, "SPI FIFO read timeout \n"); + ret = -ETIMEDOUT; + goto out; + } + + }while(!(val & MAX_INPUT_DONE_FLAG)); + out: /* * Put the SPI Core back in the Reset State @@ -542,15 +565,18 @@ uint32_t val; unsigned int i; unsigned int write_len = bytes; - unsigned int read_len = 3; //bytes; hack for now + unsigned int read_len = bytes; //hack for now unsigned int fifo_count; int ret = SUCCESS; int state_config; + struct stopwatch sw;
state_config = config_spi_state(ds, QUP_STATE_RESET); if (state_config) return state_config;
+ /* Configure input and output enable */ + enable_io_config(ds, write_len, read_len); /* No of bytes to be written in Output FIFO */ write32(ds->regs->qup_mx_output_count, bytes); write32(ds->regs->qup_mx_input_count, bytes); @@ -558,9 +584,6 @@ if (state_config) return state_config;
- /* Configure input and output enable */ - enable_io_config(ds, write_len, read_len); - /* * read_len considered to ensure that we read the dummy data for the * write we performed. This is needed to ensure with WR-RD transaction @@ -620,6 +643,18 @@ } }
+ stopwatch_init_msecs_expire(&sw, 10); + + do { + val = read32(ds->regs->qup_operational); + if (stopwatch_expired(&sw)) { + printk(BIOS_ERR, "SPI FIFO write timeout \n"); + ret = -ETIMEDOUT; + goto out; + } + + }while(!(val & MAX_OUTPUT_DONE_FLAG)); + out: /* * Put the SPI Core back in the Reset State @@ -639,8 +674,10 @@ length = (bytes < MAX_COUNT_SIZE) ? bytes : MAX_COUNT_SIZE;
ret = __blsp_spi_write(ds, cmd_buffer, length); - if (ret != SUCCESS) + if (ret != SUCCESS) { + printk(BIOS_ERR, "SPI:DBG write not success \n"); return ret; + }
cmd_buffer += length; bytes -= length; @@ -670,8 +707,6 @@ if (ret != SUCCESS) return ret;
- write_force_cs(slave, 1); - if (dout != NULL) { ret = blsp_spi_write(ds, txp, (unsigned int) out_bytes); if (ret != SUCCESS) @@ -685,7 +720,6 @@ }
out: - write_force_cs(slave, 0);
/* * Put the SPI Core back in the Reset State @@ -750,7 +784,7 @@ .setup = spi_ctrlr_setup, .claim_bus = spi_ctrlr_claim_bus, .release_bus = spi_ctrlr_release_bus, - //.xfer = spi_ctrlr_xfer, + .xfer = spi_ctrlr_xfer, .xfer_vector = xfer_vectors, .max_xfer_size = MAX_PACKET_COUNT, };