blob: 91844e36cff2f7a0842cda5b09b45f74d8ac9394 [file] [log] [blame]
Patrick Georgiac959032020-05-05 22:49:26 +02001/* SPDX-License-Identifier: GPL-2.0-only */
satya priya52353d02019-09-19 16:45:18 +05302
3#include <assert.h>
Elyes HAOUAS6aaf7db2020-09-19 09:40:52 +02004#include <console/console.h>
satya priya52353d02019-09-19 16:45:18 +05305#include <device/i2c_simple.h>
6#include <gpio.h>
satya priya52353d02019-09-19 16:45:18 +05307#include <lib.h>
8#include <soc/clock.h>
9#include <soc/qcom_qup_se.h>
Ravi Kumar Bokka34960d42021-07-27 21:02:54 +053010#include <soc/qup_se_handlers_common.h>
Rajesh Patil555c2d62021-06-16 14:13:00 +053011#include <soc/qupv3_config_common.h>
12#include <soc/qupv3_i2c_common.h>
satya priya52353d02019-09-19 16:45:18 +053013#include <stdint.h>
satya priya52353d02019-09-19 16:45:18 +053014
15static void i2c_clk_configure(unsigned int bus, enum i2c_speed speed)
16{
17 int clk_div = 0, t_high = 0, t_low = 0, t_cycle = 0;
18 struct qup_regs *regs = qup[bus].regs;
19
20 switch (speed) {
21 case I2C_SPEED_STANDARD:
22 clk_div = 7;
23 t_high = 10;
24 t_low = 11;
25 t_cycle = 26;
26 break;
27 case I2C_SPEED_FAST:
28 clk_div = 2;
29 t_high = 5;
30 t_low = 12;
31 t_cycle = 24;
32 break;
33 case I2C_SPEED_FAST_PLUS:
34 clk_div = 1;
35 t_high = 3;
36 t_low = 9;
37 t_cycle = 18;
38 break;
39 default:
40 die("Unsupported I2C speed");
41 }
42
43 write32(&regs->geni_ser_m_clk_cfg, (clk_div << 4) | 1);
44 /* Serial clock frequency is 19.2 MHz */
45 write32(&regs->i2c_scl_counters, ((t_high << 20) | (t_low << 10)
46 | t_cycle));
47}
48
49void i2c_init(unsigned int bus, enum i2c_speed speed)
50{
51 uint32_t proto;
52 struct qup_regs *regs = qup[bus].regs;
53
54 qupv3_se_fw_load_and_init(bus, SE_PROTOCOL_I2C, MIXED);
55 clock_enable_qup(bus);
56 i2c_clk_configure(bus, speed);
57
58 proto = ((read32(&regs->geni_fw_revision_ro) &
59 GENI_FW_REVISION_RO_PROTOCOL_MASK) >>
60 GENI_FW_REVISION_RO_PROTOCOL_SHIFT);
61
62 assert(proto == 3);
63
64 /* Serial engine IO initialization */
65 write32(&regs->geni_cgc_ctrl, DEFAULT_CGC_EN);
66 write32(&regs->dma_general_cfg,
67 (AHB_SEC_SLV_CLK_CGC_ON | DMA_AHB_SLV_CFG_ON
68 | DMA_TX_CLK_CGC_ON | DMA_RX_CLK_CGC_ON));
69 write32(&regs->geni_output_ctrl,
70 DEFAULT_IO_OUTPUT_CTRL_MSK);
71 write32(&regs->geni_force_default_reg, FORCE_DEFAULT);
72
73 /* Serial engine IO set mode */
74 write32(&regs->se_irq_en, (GENI_M_IRQ_EN |
75 GENI_S_IRQ_EN | DMA_TX_IRQ_EN | DMA_RX_IRQ_EN));
76 write32(&regs->se_gsi_event_en, 0);
77
78 /* Set RX and RFR watermark */
79 write32(&regs->geni_rx_watermark_reg, 0);
80 write32(&regs->geni_rx_rfr_watermark_reg, FIFO_DEPTH - 2);
81
82 /* FIFO PACKING CONFIGURATION */
83 write32(&regs->geni_tx_packing_cfg0, PACK_VECTOR0
84 | (PACK_VECTOR1 << 10));
85 write32(&regs->geni_tx_packing_cfg1, PACK_VECTOR2
86 | (PACK_VECTOR3 << 10));
87 write32(&regs->geni_rx_packing_cfg0, PACK_VECTOR0
88 | (PACK_VECTOR1 << 10));
89 write32(&regs->geni_rx_packing_cfg1, PACK_VECTOR2
90 | (PACK_VECTOR3 << 10));
91 write32(&regs->geni_byte_granularity, (log2(BITS_PER_WORD) - 3));
92
93 /* GPIO Configuration */
94 gpio_configure(qup[bus].pin[0], qup[bus].func[0], GPIO_PULL_UP,
Ravi Kumar Bokkaa8e9dba2021-07-10 23:54:20 +053095 GPIO_2MA, GPIO_OUTPUT);
satya priya52353d02019-09-19 16:45:18 +053096 gpio_configure(qup[bus].pin[1], qup[bus].func[1], GPIO_PULL_UP,
Ravi Kumar Bokkaa8e9dba2021-07-10 23:54:20 +053097 GPIO_2MA, GPIO_OUTPUT);
satya priya52353d02019-09-19 16:45:18 +053098
99 /* Select and setup FIFO mode */
100 write32(&regs->geni_m_irq_clear, 0xFFFFFFFF);
101 write32(&regs->geni_s_irq_clear, 0xFFFFFFFF);
102 write32(&regs->dma_tx_irq_clr, 0xFFFFFFFF);
103 write32(&regs->dma_rx_irq_clr, 0xFFFFFFFF);
104 write32(&regs->geni_m_irq_enable, (M_COMMON_GENI_M_IRQ_EN |
105 M_CMD_DONE_EN | M_TX_FIFO_WATERMARK_EN |
106 M_RX_FIFO_WATERMARK_EN | M_RX_FIFO_LAST_EN));
107 write32(&regs->geni_s_irq_enable, (S_COMMON_GENI_S_IRQ_EN
108 | S_CMD_DONE_EN));
109 clrbits32(&regs->geni_dma_mode_en, GENI_DMA_MODE_EN);
110}
111
112static int i2c_do_xfer(unsigned int bus, struct i2c_msg segment,
113 unsigned int prams)
114{
115 unsigned int cmd = (segment.flags & I2C_M_RD) ? 2 : 1;
116 unsigned int master_cmd_reg_val = (cmd << M_OPCODE_SHFT);
117 struct qup_regs *regs = qup[bus].regs;
118 void *dout = NULL, *din = NULL;
Jes Klinke19baa9d2022-02-22 16:00:09 -0800119 struct stopwatch timeout;
satya priya52353d02019-09-19 16:45:18 +0530120
121 if (!(segment.flags & I2C_M_RD)) {
122 write32(&regs->i2c_tx_trans_len, segment.len);
123 write32(&regs->geni_tx_watermark_reg, TX_WATERMARK);
124 dout = segment.buf;
125 } else {
126 write32(&regs->i2c_rx_trans_len, segment.len);
127 din = segment.buf;
128 }
129
130 master_cmd_reg_val |= (prams & M_PARAMS_MSK);
131 write32(&regs->geni_m_cmd0, master_cmd_reg_val);
132
Jes Klinke19baa9d2022-02-22 16:00:09 -0800133 stopwatch_init_usecs_expire(&timeout, CONFIG_I2C_TRANSFER_TIMEOUT_US);
134 return qup_handle_transfer(bus, dout, din, segment.len, &timeout);
satya priya52353d02019-09-19 16:45:18 +0530135}
136
137int platform_i2c_transfer(unsigned int bus, struct i2c_msg *segments,
138 int seg_count)
139{
140 struct i2c_msg *seg = segments;
141 int ret = 0;
142
143 while (!ret && seg_count--) {
144 /* Stretch means end with repeated start, not stop */
145 u32 stretch = (seg_count ? 1 : 0);
146 u32 m_param = 0;
147
148 m_param |= (stretch << 2);
149 m_param |= ((seg->slave & 0x7F) << 9);
150 ret = i2c_do_xfer(bus, *seg, m_param);
151 seg++;
152 }
153 return ret;
154}