From 6fe4e5e34c584f7f4ad2c071b311e6b6a878b623 Mon Sep 17 00:00:00 2001 From: Vadim Bendebury Date: Sat, 6 Dec 2014 10:44:58 -0800 Subject: ipq806x: add i2c driver this change ports i2c and other relevant drivers from depthcharge for ipq806x. BUG=chrome-os-partner:33647 BRANCH=ToT TEST=Booted storm using vboot2 Change-Id: I3d9a431aa8adb9b91dbccdf031647dfadbafc24c Signed-off-by: Patrick Georgi Original-Commit-Id: a0c615d0a49fd9c0ffa231353800882fff6ab90b Original-Signed-off-by: Daisuke Nojiri Original-Change-Id: Id7cc3932ed4ae54f46336aaebde35e84125ebebd Original-Reviewed-on: https://chromium-review.googlesource.com/229428 Original-Reviewed-by: Vadim Bendebury Original-Tested-by: Vadim Bendebury Original-Commit-Queue: Vadim Bendebury Reviewed-on: http://review.coreboot.org/9685 Tested-by: build bot (Jenkins) Reviewed-by: Stefan Reinauer --- src/soc/qualcomm/ipq806x/include/soc/gsbi.h | 30 +++- src/soc/qualcomm/ipq806x/include/soc/iomap.h | 7 + src/soc/qualcomm/ipq806x/include/soc/qup.h | 211 +++++++++++++++++++++++++++ 3 files changed, 247 insertions(+), 1 deletion(-) create mode 100644 src/soc/qualcomm/ipq806x/include/soc/qup.h (limited to 'src/soc/qualcomm/ipq806x/include') diff --git a/src/soc/qualcomm/ipq806x/include/soc/gsbi.h b/src/soc/qualcomm/ipq806x/include/soc/gsbi.h index c12d6fd7b4..00c257c4b8 100644 --- a/src/soc/qualcomm/ipq806x/include/soc/gsbi.h +++ b/src/soc/qualcomm/ipq806x/include/soc/gsbi.h @@ -31,5 +31,33 @@ #define GSBI_HCLK_CTL_S 4 #define GSBI_HCLK_CTL_CLK_ENA 0x1 -#endif +typedef enum { + GSBI_ID_1 = 1, + GSBI_ID_2, + GSBI_ID_3, + GSBI_ID_4, + GSBI_ID_5, + GSBI_ID_6, + GSBI_ID_7, +} gsbi_id_t; + +typedef enum { + GSBI_SUCCESS = 0, + GSBI_ID_ERROR, + GSBI_ERROR, + GSBI_UNSUPPORTED +} gsbi_return_t; + +typedef enum { + GSBI_PROTO_I2C_UIM = 1, + GSBI_PROTO_I2C_ONLY, + GSBI_PROTO_SPI_ONLY, + GSBI_PROTO_UART_FLOW_CTL, + GSBI_PROTO_UIM, + GSBI_PROTO_I2C_UART, +} gsbi_protocol_t; +gsbi_return_t gsbi_init(gsbi_id_t gsbi_id, gsbi_protocol_t protocol); +int gsbi_init_board(gsbi_id_t gsbi_id); + +#endif diff --git a/src/soc/qualcomm/ipq806x/include/soc/iomap.h b/src/soc/qualcomm/ipq806x/include/soc/iomap.h index ad7056e0fe..333e2615eb 100644 --- a/src/soc/qualcomm/ipq806x/include/soc/iomap.h +++ b/src/soc/qualcomm/ipq806x/include/soc/iomap.h @@ -107,4 +107,11 @@ #define UART2_DM_BASE 0x12490000 #define UART_GSBI2_BASE 0x12480000 +#define GSBI_QUP1_BASE 0x12460000 +#define GSBI_QUP2_BASE 0x124A0000 +#define GSBI_QUP3_BASE 0x16280000 +#define GSBI_QUP4_BASE 0x16380000 +#define GSBI_QUP5_BASE 0x1A280000 +#define GSBI_QUP6_BASE 0x16580000 +#define GSBI_QUP7_BASE 0x16680000 #endif // __SOC_QUALCOMM_IPQ806X_IOMAP_H_ diff --git a/src/soc/qualcomm/ipq806x/include/soc/qup.h b/src/soc/qualcomm/ipq806x/include/soc/qup.h new file mode 100644 index 0000000000..8f6f6bcca9 --- /dev/null +++ b/src/soc/qualcomm/ipq806x/include/soc/qup.h @@ -0,0 +1,211 @@ +/* + * This file is part of the coreboot project. + * + * Copyright (C) 2014 The Linux Foundation. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * 3. The name of the author may not be used to endorse or promote products + * derived from this software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY + * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + * SUCH DAMAGE. + */ + +#ifndef __QUP_H__ +#define __QUP_H__ + +#include + +/* QUP block registers */ +#define QUP_CONFIG 0x0 +#define QUP_STATE 0x4 +#define QUP_IO_MODES 0x8 +#define QUP_SW_RESET 0xc +#define QUP_TIME_OUT 0x10 +#define QUP_TIME_OUT_CURRENT 0x14 +#define QUP_OPERATIONAL 0x18 +#define QUP_ERROR_FLAGS 0x1c +#define QUP_ERROR_FLAGS_EN 0x20 +#define QUP_TEST_CTRL 0x24 +#define QUP_MX_OUTPUT_COUNT 0x100 +#define QUP_MX_OUTPUT_CNT_CURRENT 0x104 +#define QUP_OUTPUT_DEBUG 0x108 +#define QUP_OUTPUT_FIFO_WORD_CNT 0x10c +#define QUP_OUTPUT_FIFO 0x110 +#define QUP_MX_WRITE_COUNT 0x150 +#define QUP_WRITE_CNT_CURRENT 0x154 +#define QUP_MX_INPUT_COUNT 0x200 +#define QUP_READ_COUNT 0x208 +#define QUP_MX_READ_CNT_CURRENT 0x20c +#define QUP_INPUT_DEBUG 0x210 +#define QUP_INPUT_FIFO_WORD_CNT 0x214 +#define QUP_INPUT_FIFO 0x218 +#define QUP_I2C_MASTER_CLK_CTL 0x400 +#define QUP_I2C_MASTER_STATUS 0x404 + +#define OUTPUT_FIFO_FULL (1<<6) +#define INPUT_FIFO_NOT_EMPTY (1<<5) +#define OUTPUT_FIFO_NOT_EMPTY (1<<4) +#define INPUT_SERVICE_FLAG (1<<9) +#define OUTPUT_SERVICE_FLAG (1<<8) +#define QUP_OUTPUT_BIT_SHIFT_EN (1<<16) + +#define QUP_MODE_MASK (0x03) +#define QUP_OUTPUT_MODE_SHFT (10) +#define QUP_INPUT_MODE_SHFT (12) + +#define QUP_FS_DIVIDER_MASK (0xFF) + +#define QUP_MINI_CORE_PROTO_SHFT (8) +#define QUP_MINI_CORE_PROTO_MASK (0x0F) + +/* Mini-core states */ +#define QUP_STATE_RESET 0x0 +#define QUP_STATE_RUN 0x1 +#define QUP_STATE_PAUSE 0x3 +#define QUP_STATE_VALID (1<<2) +#define QUP_STATE_MASK 0x3 +#define QUP_STATE_VALID_MASK (1<<2) + +/* Tags for output FIFO */ +#define QUP_I2C_1CLK_NOOP_SEQ 0x1 /*MSB 8-bit NOP, LSB 8-bits 1 clk.*/ +#define QUP_I2C_START_SEQ (0x1 << 8) +#define QUP_I2C_DATA_SEQ (0x2 << 8) +#define QUP_I2C_STOP_SEQ (0x3 << 8) +#define QUP_I2C_RECV_SEQ (0x4 << 8) + +/* Tags for input FIFO */ +#define QUP_I2C_MIDATA_SEQ (0x5 << 8) +#define QUP_I2C_MISTOP_SEQ (0x6 << 8) +#define QUP_I2C_MINACK_SEQ (0x7 << 8) + +#define QUP_I2C_ADDR(x) ((x & 0xFF) << 1) +#define QUP_I2C_DATA(x) (x & 0xFF) +#define QUP_I2C_MI_TAG(x) (x & 0xFF00) +#define QUP_I2C_SLAVE_READ (0x1) + +/*Bit vals for I2C_MASTER_CLK_CTL register */ +#define QUP_HS_DIVIDER_SHFT (8) +#define QUP_DIVIDER_MIN_VAL (0x3) + +/* Bit masks for I2C_MASTER_STATUS register */ +#define QUP_I2C_INVALID_READ_SEQ (1 << 25) +#define QUP_I2C_INVALID_READ_ADDR (1 << 24) +#define QUP_I2C_INVALID_TAG (1 << 23) +#define QUP_I2C_FAILED_MASK (0x3 << 6) +#define QUP_I2C_ARB_LOST (1 << 4) +#define QUP_I2C_BUS_ERROR (1 << 2) + +typedef enum { + QUP_SUCCESS = 0, + QUP_ERR_BAD_PARAM, + QUP_ERR_STATE_SET, + QUP_ERR_TIMEOUT, + QUP_ERR_UNSUPPORTED, + QUP_ERR_I2C_FAILED, + QUP_ERR_I2C_ARB_LOST, + QUP_ERR_I2C_BUS_ERROR, + QUP_ERR_I2C_INVALID_SLAVE_ADDR, + QUP_ERR_XFER_FAIL, + QUP_ERR_UNDEFINED, +} qup_return_t; + +typedef enum { + QUP_MINICORE_SPI = 1, + QUP_MINICORE_I2C_MASTER, + QUP_MINICORE_I2C_SLAVE +} qup_protocol_t; + +typedef enum { + QUP_MODE_FIFO = 0, + QUP_MODE_BLOCK, + QUP_MODE_DATAMOVER, +} qup_mode_t; + +typedef struct { + qup_protocol_t protocol; + unsigned clk_frequency; + unsigned src_frequency; + qup_mode_t mode; +} qup_config_t; + +typedef struct { + qup_protocol_t protocol; + union { + struct { + uint8_t addr; + uint8_t *data; + unsigned data_len; + } iic; + struct { + void *in; + void *out; + unsigned size; + } spi; + } p; +} qup_data_t; + +/* + * Initialize GSBI QUP block for FIFO I2C transfers. + * gsbi_id[IN]: GSBI for which QUP is to be initialized. + * config_ptr[IN]: configurations parameters for the QUP. + * + * return: QUP_SUCCESS, if initialization succeeds. + */ +qup_return_t qup_init(gsbi_id_t gsbi_id, const qup_config_t *config_ptr); + +/* + * Set QUP state to run, pause, reset. + * gsbi_id[IN]: GSBI block for which QUP state is to be set. + * state[IN]: New state to transition to. + * + * return: QUP_SUCCESS, if state transition succeeds. + */ +qup_return_t qup_set_state(gsbi_id_t gsbi_id, uint32_t state); + +/* + * Reset the status bits set during an i2c transfer. + * gsbi_id[IN]: GSBI block for which i2c status bits are to be cleared. + * + * return: QUP_SUCCESS, if status bits are cleared successfully. + */ +qup_return_t qup_reset_i2c_master_status(gsbi_id_t gsbi_id); + +/* + * Send data to the peripheral on the bus. + * gsbi_id[IN]: GSBI block for which data is to be sent. + * p_tx_obj[IN]: Data to be sent to the slave on the bus. + * stop_seq[IN]: When set to non-zero QUP engine sends i2c stop sequnce. + * + * return: QUP_SUCCESS, when data is sent successfully to the peripheral. + */ +qup_return_t qup_send_data(gsbi_id_t gsbi_id, qup_data_t *p_tx_obj, + uint8_t stop_seq); + +/* + * Receive data from peripheral on the bus. + * gsbi_id[IN]: GSBI block from which data is to be received. + * p_tx_obj[IN]: length of data to be received, slave address. + * [OUT]: buffer filled with data from slave. + * + * return: QUP_SUCCESS, when data is received successfully. + */ +qup_return_t qup_recv_data(gsbi_id_t gsbi_id, qup_data_t *p_tx_obj); + +#endif //__QUP_H__ -- cgit v1.2.3