nsekar@codeaurora.org has uploaded this change for review.

View Change

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,
};

To view, visit change 31177. To unsubscribe, or for help writing mail filters, visit settings.

Gerrit-Project: coreboot
Gerrit-Branch: master
Gerrit-Change-Id: Ib8fce5f1890ed3693ee0620cbc0e665d82ce3204
Gerrit-Change-Number: 31177
Gerrit-PatchSet: 1
Gerrit-Owner: nsekar@codeaurora.org
Gerrit-MessageType: newchange