diff options
author | Rajesh Patil <rajpat@codeaurora.org> | 2021-06-16 14:13:00 +0530 |
---|---|---|
committer | Shelley Chen <shchen@google.com> | 2021-09-21 19:37:46 +0000 |
commit | 555c2d67a4e70146286c319cf182c6ee4f92ad2e (patch) | |
tree | 22639dc127f5f075a8e842520b690911040ec2ae /src/soc/qualcomm/sc7180 | |
parent | f33d2e4b1dee0164ad25ed7c194d623a3559959e (diff) |
soc/qualcomm/common/i2c: Add support for I2C common driver
copy existing I2C driver from /soc/qualcomm/sc7180 to common folder.
This implements i2c driver for qualcomm chipsets
BUG=b:182963902
TEST=Validated on qualcomm sc7180 and sc7280 development board
Signed-off-by: Rajesh Patil <rajpat@codeaurora.org>
Change-Id: I16e6fc2c1c24b9814d1803bffd5cfbb657201cfb
Reviewed-on: https://review.coreboot.org/c/coreboot/+/55952
Tested-by: build bot (Jenkins) <no-reply@coreboot.org>
Reviewed-by: Shelley Chen <shchen@google.com>
Diffstat (limited to 'src/soc/qualcomm/sc7180')
-rw-r--r-- | src/soc/qualcomm/sc7180/Makefile.inc | 2 | ||||
-rw-r--r-- | src/soc/qualcomm/sc7180/include/soc/qupv3_i2c.h | 10 | ||||
-rw-r--r-- | src/soc/qualcomm/sc7180/qupv3_i2c.c | 153 |
3 files changed, 1 insertions, 164 deletions
diff --git a/src/soc/qualcomm/sc7180/Makefile.inc b/src/soc/qualcomm/sc7180/Makefile.inc index 149d63f4be..0d7e4d62bd 100644 --- a/src/soc/qualcomm/sc7180/Makefile.inc +++ b/src/soc/qualcomm/sc7180/Makefile.inc @@ -8,7 +8,7 @@ all-y += ../common/timer.c all-y += ../common/gpio.c all-y += ../common/spi.c all-$(CONFIG_SC7180_QSPI) += ../common/qspi.c -all-y += qupv3_i2c.c +all-y += ../common/qupv3_i2c.c all-y += qupv3_spi.c all-y += clock.c all-y += ../common/clock.c diff --git a/src/soc/qualcomm/sc7180/include/soc/qupv3_i2c.h b/src/soc/qualcomm/sc7180/include/soc/qupv3_i2c.h deleted file mode 100644 index 71cea0a639..0000000000 --- a/src/soc/qualcomm/sc7180/include/soc/qupv3_i2c.h +++ /dev/null @@ -1,10 +0,0 @@ -/* SPDX-License-Identifier: GPL-2.0-only */ - -#ifndef __I2C_QCOM_HEADER___ -#define __I2C_QCOM_HEADER___ - -#include <device/i2c.h> - -void i2c_init(unsigned int bus, enum i2c_speed speed); - -#endif /* __I2C_QCOM_HEADER */ diff --git a/src/soc/qualcomm/sc7180/qupv3_i2c.c b/src/soc/qualcomm/sc7180/qupv3_i2c.c deleted file mode 100644 index 704a0bc0fb..0000000000 --- a/src/soc/qualcomm/sc7180/qupv3_i2c.c +++ /dev/null @@ -1,153 +0,0 @@ -/* SPDX-License-Identifier: GPL-2.0-only */ - -#include <assert.h> -#include <console/console.h> -#include <device/i2c_simple.h> -#include <gpio.h> -#include <inttypes.h> -#include <lib.h> -#include <soc/clock.h> -#include <soc/qcom_qup_se.h> -#include <soc/qupv3_config_common.h> -#include <soc/qup_se_handlers_common.h> -#include <soc/qupv3_i2c.h> -#include <stdint.h> - -static void i2c_clk_configure(unsigned int bus, enum i2c_speed speed) -{ - int clk_div = 0, t_high = 0, t_low = 0, t_cycle = 0; - struct qup_regs *regs = qup[bus].regs; - - switch (speed) { - case I2C_SPEED_STANDARD: - clk_div = 7; - t_high = 10; - t_low = 11; - t_cycle = 26; - break; - case I2C_SPEED_FAST: - clk_div = 2; - t_high = 5; - t_low = 12; - t_cycle = 24; - break; - case I2C_SPEED_FAST_PLUS: - clk_div = 1; - t_high = 3; - t_low = 9; - t_cycle = 18; - break; - default: - die("Unsupported I2C speed"); - } - - write32(®s->geni_ser_m_clk_cfg, (clk_div << 4) | 1); - /* Serial clock frequency is 19.2 MHz */ - write32(®s->i2c_scl_counters, ((t_high << 20) | (t_low << 10) - | t_cycle)); -} - -void i2c_init(unsigned int bus, enum i2c_speed speed) -{ - uint32_t proto; - struct qup_regs *regs = qup[bus].regs; - - qupv3_se_fw_load_and_init(bus, SE_PROTOCOL_I2C, MIXED); - clock_enable_qup(bus); - i2c_clk_configure(bus, speed); - - proto = ((read32(®s->geni_fw_revision_ro) & - GENI_FW_REVISION_RO_PROTOCOL_MASK) >> - GENI_FW_REVISION_RO_PROTOCOL_SHIFT); - - assert(proto == 3); - - /* Serial engine IO initialization */ - write32(®s->geni_cgc_ctrl, DEFAULT_CGC_EN); - write32(®s->dma_general_cfg, - (AHB_SEC_SLV_CLK_CGC_ON | DMA_AHB_SLV_CFG_ON - | DMA_TX_CLK_CGC_ON | DMA_RX_CLK_CGC_ON)); - write32(®s->geni_output_ctrl, - DEFAULT_IO_OUTPUT_CTRL_MSK); - write32(®s->geni_force_default_reg, FORCE_DEFAULT); - - /* Serial engine IO set mode */ - write32(®s->se_irq_en, (GENI_M_IRQ_EN | - GENI_S_IRQ_EN | DMA_TX_IRQ_EN | DMA_RX_IRQ_EN)); - write32(®s->se_gsi_event_en, 0); - - /* Set RX and RFR watermark */ - write32(®s->geni_rx_watermark_reg, 0); - write32(®s->geni_rx_rfr_watermark_reg, FIFO_DEPTH - 2); - - /* FIFO PACKING CONFIGURATION */ - write32(®s->geni_tx_packing_cfg0, PACK_VECTOR0 - | (PACK_VECTOR1 << 10)); - write32(®s->geni_tx_packing_cfg1, PACK_VECTOR2 - | (PACK_VECTOR3 << 10)); - write32(®s->geni_rx_packing_cfg0, PACK_VECTOR0 - | (PACK_VECTOR1 << 10)); - write32(®s->geni_rx_packing_cfg1, PACK_VECTOR2 - | (PACK_VECTOR3 << 10)); - write32(®s->geni_byte_granularity, (log2(BITS_PER_WORD) - 3)); - - /* GPIO Configuration */ - gpio_configure(qup[bus].pin[0], qup[bus].func[0], GPIO_PULL_UP, - GPIO_2MA, GPIO_OUTPUT); - gpio_configure(qup[bus].pin[1], qup[bus].func[1], GPIO_PULL_UP, - GPIO_2MA, GPIO_OUTPUT); - - /* Select and setup FIFO mode */ - write32(®s->geni_m_irq_clear, 0xFFFFFFFF); - write32(®s->geni_s_irq_clear, 0xFFFFFFFF); - write32(®s->dma_tx_irq_clr, 0xFFFFFFFF); - write32(®s->dma_rx_irq_clr, 0xFFFFFFFF); - write32(®s->geni_m_irq_enable, (M_COMMON_GENI_M_IRQ_EN | - M_CMD_DONE_EN | M_TX_FIFO_WATERMARK_EN | - M_RX_FIFO_WATERMARK_EN | M_RX_FIFO_LAST_EN)); - write32(®s->geni_s_irq_enable, (S_COMMON_GENI_S_IRQ_EN - | S_CMD_DONE_EN)); - clrbits32(®s->geni_dma_mode_en, GENI_DMA_MODE_EN); -} - -static int i2c_do_xfer(unsigned int bus, struct i2c_msg segment, - unsigned int prams) -{ - unsigned int cmd = (segment.flags & I2C_M_RD) ? 2 : 1; - unsigned int master_cmd_reg_val = (cmd << M_OPCODE_SHFT); - struct qup_regs *regs = qup[bus].regs; - void *dout = NULL, *din = NULL; - - if (!(segment.flags & I2C_M_RD)) { - write32(®s->i2c_tx_trans_len, segment.len); - write32(®s->geni_tx_watermark_reg, TX_WATERMARK); - dout = segment.buf; - } else { - write32(®s->i2c_rx_trans_len, segment.len); - din = segment.buf; - } - - master_cmd_reg_val |= (prams & M_PARAMS_MSK); - write32(®s->geni_m_cmd0, master_cmd_reg_val); - - return qup_handle_transfer(bus, dout, din, segment.len); -} - -int platform_i2c_transfer(unsigned int bus, struct i2c_msg *segments, - int seg_count) -{ - struct i2c_msg *seg = segments; - int ret = 0; - - while (!ret && seg_count--) { - /* Stretch means end with repeated start, not stop */ - u32 stretch = (seg_count ? 1 : 0); - u32 m_param = 0; - - m_param |= (stretch << 2); - m_param |= ((seg->slave & 0x7F) << 9); - ret = i2c_do_xfer(bus, *seg, m_param); - seg++; - } - return ret; -} |