diff options
author | Vadim Bendebury <vbendeb@chromium.org> | 2014-04-30 13:25:12 -0700 |
---|---|---|
committer | Marc Jones <marc.jones@se-eng.com> | 2014-12-31 21:05:50 +0100 |
commit | dffd892e47bb8bbfb920447275a2d6b00be904ce (patch) | |
tree | e6feb2423e193c9dcd392a9c9fe3717f3e2ce29c /src/soc/qualcomm/ipq806x/include | |
parent | 11c4c92d918df878f052a501ce22b3eee2199cef (diff) | |
download | coreboot-dffd892e47bb8bbfb920447275a2d6b00be904ce.tar.xz |
ipq8064: modify SPI controller driver to work in coreboot
A typical SPI operation consists of two phases - command and data
transfers. Command transfer is always from the host to the chip (i.e.
is going in the 'write' direction), data transfer could be either read
or write.
We don't want the receive FIFO to be operating while the command phase
is in progress. A simple way to keep the receive FIFO shut down is to
not to enable it until the command phase is completed.
Selective control of the receive FIFO allows to consolidate the
receive and transmit functions in a single spi_xfer() function, as it
happens in other SPI controller drivers.
The FIFO FULL and FIFO NOT EMPTY conditions are used to decide if the
next byte can be written or received, respectively. While data is
being received the 0xFF bytes are transmitted per each received byte,
to keep the SPI bus clocking.
The data structure describing the three GSBI ports is moved from the
.h file into .c file. A version of the clrsetbits macro is added to
work with integer addresses instead of pointers.
BUG=chrome-os-partner:27784
TEST=not yet, but with the res of the changes the bootblock loads and
starts the rombase section successfully.
Original-Change-Id: I78cd0054f1a8f5e1d7213f38ef8de31486238aba
Original-Signed-off-by: Vadim Bendebury <vbendeb@chromium.org>
Original-Reviewed-on: https://chromium-review.googlesource.com/197779
Original-Reviewed-by: Stefan Reinauer <reinauer@chromium.org>
Original-Reviewed-by: David Hendricks <dhendrix@chromium.org>
(cherry picked from commit c101ae306d182bbe14935ee139a25968388d745a)
Signed-off-by: Marc Jones <marc.jones@se-eng.com>
Change-Id: I7f3fd0524ec6c10008ff514e8a8f1d14a700732f
Reviewed-on: http://review.coreboot.org/7983
Reviewed-by: David Hendricks <dhendrix@chromium.org>
Tested-by: build bot (Jenkins)
Diffstat (limited to 'src/soc/qualcomm/ipq806x/include')
-rw-r--r-- | src/soc/qualcomm/ipq806x/include/iomap.h | 7 | ||||
-rw-r--r-- | src/soc/qualcomm/ipq806x/include/spi.h | 90 |
2 files changed, 25 insertions, 72 deletions
diff --git a/src/soc/qualcomm/ipq806x/include/iomap.h b/src/soc/qualcomm/ipq806x/include/iomap.h index 8a4155ce6b..be523a65cd 100644 --- a/src/soc/qualcomm/ipq806x/include/iomap.h +++ b/src/soc/qualcomm/ipq806x/include/iomap.h @@ -36,6 +36,9 @@ #ifndef __SOC_QUALCOMM_IPQ806X_IOMAP_H_ #define __SOC_QUALCOMM_IPQ806X_IOMAP_H_ +#include <arch/io.h> +#include <cdp.h> + /* Typecast to allow integers being passed as address This needs to be included because vendor code is not compliant with our macros for read/write. Hence, special macros for readl_i and writel_i are @@ -43,8 +46,8 @@ */ #define readl_i(a) read32((const void *)(a)) #define writel_i(v,a) write32(v,(void *)a) -#include <arch/io.h> -#include <cdp.h> +#define clrsetbits_le32_i(addr, clear, set) \ + clrsetbits_le32(((void *)(addr)), (clear), (set)) #define MSM_CLK_CTL_BASE 0x00900000 diff --git a/src/soc/qualcomm/ipq806x/include/spi.h b/src/soc/qualcomm/ipq806x/include/spi.h index 2020043c6c..48073fadd0 100644 --- a/src/soc/qualcomm/ipq806x/include/spi.h +++ b/src/soc/qualcomm/ipq806x/include/spi.h @@ -3,8 +3,10 @@ * Copyright (c) 2012 The Linux Foundation. All rights reserved. */ -#ifndef _IPQ_SPI_H_ -#define _IPQ_SPI_H_ +#ifndef _IPQ806X_SPI_H_ +#define _IPQ806X_SPI_H_ + +#include <spi_flash.h> #define QUP5_BASE 0x1a280000 #define QUP6_BASE 0x16580000 @@ -70,6 +72,14 @@ #define GSBI6_QUP_STATE_REG (GSBI6_QUP6_REG_BASE + 0x00000004) #define GSBI7_QUP_STATE_REG (GSBI7_QUP7_REG_BASE + 0x00000004) +#define GSBI5_QUP_OUT_FIFO_WORD_CNT_REG (GSBI5_QUP5_REG_BASE + 0x0000010c) +#define GSBI6_QUP_OUT_FIFO_WORD_CNT_REG (GSBI6_QUP6_REG_BASE + 0x0000010c) +#define GSBI7_QUP_OUT_FIFO_WORD_CNT_REG (GSBI7_QUP7_REG_BASE + 0x0000010c) + +#define GSBI5_QUP_IN_FIFO_WORD_CNT_REG (GSBI5_QUP5_REG_BASE + 0x00000214) +#define GSBI6_QUP_IN_FIFO_WORD_CNT_REG (GSBI6_QUP6_REG_BASE + 0x00000214) +#define GSBI7_QUP_IN_FIFO_WORD_CNT_REG (GSBI7_QUP7_REG_BASE + 0x00000214) + #define GSBI5_QUP_INPUT_FIFOc_REG(c) \ (GSBI5_QUP5_REG_BASE + 0x00000218 + 4 * (c)) #define GSBI6_QUP_INPUT_FIFOc_REG(c) \ @@ -144,10 +154,14 @@ #define QUP_CONFIG_MINI_CORE_SPI (1 << 8) #define SPI_QUP_CONF_INPUT_MSK (1 << 7) #define SPI_QUP_CONF_INPUT_ENA (0 << 7) +#define SPI_QUP_CONF_NO_INPUT (1 << 7) #define SPI_QUP_CONF_OUTPUT_MSK (1 << 6) #define SPI_QUP_CONF_OUTPUT_ENA (0 << 6) -#define QUP_STATE_RUN_STATE 0x1 +#define SPI_QUP_CONF_NO_OUTPUT (1 << 6) +#define SPI_QUP_CONF_OUTPUT_ENA (0 << 6) #define QUP_STATE_RESET_STATE 0x0 +#define QUP_STATE_RUN_STATE 0x1 +#define QUP_STATE_PAUSE_STATE 0x3 #define SPI_BIT_WORD_MSK 0x1F #define SPI_8_BIT_WORD 0x07 #define PROTOCOL_CODE_MSK (0x07 << 4) @@ -196,6 +210,7 @@ #define OUTPUT_SERVICE_FLAG (1 << 8) #define INPUT_SERVICE_FLAG (1 << 9) #define QUP_OUTPUT_FIFO_FULL (1 << 6) +#define QUP_INPUT_FIFO_NOT_EMPTY (1 << 5) #define SPI_INPUT_BLOCK_SIZE 4 #define SPI_OUTPUT_BLOCK_SIZE 4 #define GSBI5_SPI_CLK 21 @@ -226,6 +241,7 @@ #define SPI_RESET_STATE 0 #define SPI_RUN_STATE 1 +#define SPI_PAUSE_STATE 3 #define SPI_CORE_RESET 0 #define SPI_CORE_RUNNING 1 #define GSBI_SPI_MODE_0 0 @@ -257,79 +273,13 @@ struct gsbi_spi { unsigned int qup_md_reg; }; -static const struct gsbi_spi spi_reg[] = { - /* GSBI5 registers for SPI interface */ - { - GSBI5_SPI_CONFIG_REG, - GSBI5_SPI_IO_CONTROL_REG, - GSBI5_SPI_ERROR_FLAGS_REG, - GSBI5_SPI_ERROR_FLAGS_EN_REG, - GSBI5_GSBI_CTRL_REG_REG, - GSBI5_QUP_CONFIG_REG, - GSBI5_QUP_ERROR_FLAGS_REG, - GSBI5_QUP_ERROR_FLAGS_EN_REG, - GSBI5_QUP_OPERATIONAL_REG, - GSBI5_QUP_IO_MODES_REG, - GSBI5_QUP_STATE_REG, - GSBI5_QUP_INPUT_FIFOc_REG(0), - GSBI5_QUP_OUTPUT_FIFOc_REG(0), - GSBI5_QUP_MX_INPUT_COUNT_REG, - GSBI5_QUP_MX_OUTPUT_COUNT_REG, - GSBI5_QUP_SW_RESET_REG, - GSBIn_QUP_APPS_NS_REG(5), - GSBIn_QUP_APPS_MD_REG(5) - }, - /* GSBI6 registers for SPI interface */ - { - GSBI6_SPI_CONFIG_REG, - GSBI6_SPI_IO_CONTROL_REG, - GSBI6_SPI_ERROR_FLAGS_REG, - GSBI6_SPI_ERROR_FLAGS_EN_REG, - GSBI6_GSBI_CTRL_REG_REG, - GSBI6_QUP_CONFIG_REG, - GSBI6_QUP_ERROR_FLAGS_REG, - GSBI6_QUP_ERROR_FLAGS_EN_REG, - GSBI6_QUP_OPERATIONAL_REG, - GSBI6_QUP_IO_MODES_REG, - GSBI6_QUP_STATE_REG, - GSBI6_QUP_INPUT_FIFOc_REG(0), - GSBI6_QUP_OUTPUT_FIFOc_REG(0), - GSBI6_QUP_MX_INPUT_COUNT_REG, - GSBI6_QUP_MX_OUTPUT_COUNT_REG, - GSBI6_QUP_SW_RESET_REG, - GSBIn_QUP_APPS_NS_REG(6), - GSBIn_QUP_APPS_MD_REG(6) - }, - /* GSBI7 registers for SPI interface */ - { - GSBI7_SPI_CONFIG_REG, - GSBI7_SPI_IO_CONTROL_REG, - GSBI7_SPI_ERROR_FLAGS_REG, - GSBI7_SPI_ERROR_FLAGS_EN_REG, - GSBI7_GSBI_CTRL_REG_REG, - GSBI7_QUP_CONFIG_REG, - GSBI7_QUP_ERROR_FLAGS_REG, - GSBI7_QUP_ERROR_FLAGS_EN_REG, - GSBI7_QUP_OPERATIONAL_REG, - GSBI7_QUP_IO_MODES_REG, - GSBI7_QUP_STATE_REG, - GSBI7_QUP_INPUT_FIFOc_REG(0), - GSBI7_QUP_OUTPUT_FIFOc_REG(0), - GSBI7_QUP_MX_INPUT_COUNT_REG, - GSBI7_QUP_MX_OUTPUT_COUNT_REG, - GSBI7_QUP_SW_RESET_REG, - GSBIn_QUP_APPS_NS_REG(7), - GSBIn_QUP_APPS_MD_REG(7) - } -}; - struct ipq_spi_slave { struct spi_slave slave; const struct gsbi_spi *regs; - unsigned int core_state; unsigned int mode; unsigned int initialized; unsigned long freq; + int allocated; }; static inline struct ipq_spi_slave *to_ipq_spi(struct spi_slave *slave) |