mb/system76/cml-u/dt: Make use of chipset devicetree
[coreboot.git] / src / soc / qualcomm / ipq806x / qup.c
blobe7b45d6eca3ea2760453300aa65f54165a413bf7
1 /* SPDX-License-Identifier: BSD-3-Clause */
3 #include <device/mmio.h>
4 #include <console/console.h>
5 #include <delay.h>
6 #include <timer.h>
7 #include <soc/iomap.h>
8 #include <soc/qup.h>
10 #define TIMEOUT_CNT 100000
12 //TODO: refactor the following array to iomap driver.
13 static unsigned int gsbi_qup_base[] = {
14 (unsigned int)GSBI_QUP1_BASE,
15 (unsigned int)GSBI_QUP2_BASE,
16 (unsigned int)GSBI_QUP3_BASE,
17 (unsigned int)GSBI_QUP4_BASE,
18 (unsigned int)GSBI_QUP5_BASE,
19 (unsigned int)GSBI_QUP6_BASE,
20 (unsigned int)GSBI_QUP7_BASE,
23 #define QUP_ADDR(gsbi_num, reg) ((void *)((gsbi_qup_base[gsbi_num-1]) + (reg)))
25 static qup_return_t qup_i2c_master_status(gsbi_id_t gsbi_id)
27 uint32_t reg_val = read32(QUP_ADDR(gsbi_id, QUP_I2C_MASTER_STATUS));
29 if (read32(QUP_ADDR(gsbi_id, QUP_ERROR_FLAGS)))
30 return QUP_ERR_XFER_FAIL;
31 if (reg_val & QUP_I2C_INVALID_READ_ADDR)
32 return QUP_ERR_I2C_INVALID_SLAVE_ADDR;
33 if (reg_val & QUP_I2C_FAILED_MASK)
34 return QUP_ERR_I2C_FAILED;
35 if (reg_val & QUP_I2C_ARB_LOST)
36 return QUP_ERR_I2C_ARB_LOST;
37 if (reg_val & QUP_I2C_BUS_ERROR)
38 return QUP_ERR_I2C_BUS_ERROR;
39 if (reg_val & QUP_I2C_INVALID_WRITE)
40 return QUP_ERR_I2C_INVALID_WRITE;
41 if (reg_val & QUP_I2C_PACKET_NACK)
42 return QUP_ERR_I2C_NACK;
43 if (reg_val & QUP_I2C_INVALID_TAG)
44 return QUP_ERR_I2C_INVALID_TAG;
46 return QUP_SUCCESS;
49 static int check_bit_state(uint32_t *reg, int wait_for)
51 unsigned int count = TIMEOUT_CNT;
53 while ((read32(reg) & (QUP_STATE_VALID_MASK | QUP_STATE_MASK)) !=
54 (QUP_STATE_VALID | wait_for)) {
55 if (count == 0)
56 return QUP_ERR_TIMEOUT;
57 count--;
58 udelay(1);
61 return QUP_SUCCESS;
65 * Check whether GSBIn_QUP State is valid
67 static qup_return_t qup_wait_for_state(gsbi_id_t gsbi_id, unsigned int wait_for)
69 return check_bit_state(QUP_ADDR(gsbi_id, QUP_STATE), wait_for);
72 qup_return_t qup_reset_i2c_master_status(gsbi_id_t gsbi_id)
75 * Writing a one clears the status bits.
76 * Bit31-25, Bit1 and Bit0 are reserved.
78 //TODO: Define each status bit. OR all status bits in a single macro.
79 write32(QUP_ADDR(gsbi_id, QUP_I2C_MASTER_STATUS), 0x3FFFFFC);
80 return QUP_SUCCESS;
83 static qup_return_t qup_reset_master_status(gsbi_id_t gsbi_id)
85 write32(QUP_ADDR(gsbi_id, QUP_ERROR_FLAGS), 0x7C);
86 write32(QUP_ADDR(gsbi_id, QUP_ERROR_FLAGS_EN), 0x7C);
87 qup_reset_i2c_master_status(gsbi_id);
88 return QUP_SUCCESS;
91 static qup_return_t qup_fifo_wait_for(gsbi_id_t gsbi_id, uint32_t status,
92 struct stopwatch *timeout)
94 qup_return_t ret = QUP_ERR_UNDEFINED;
96 while (!(read32(QUP_ADDR(gsbi_id, QUP_OPERATIONAL)) & status)) {
97 ret = qup_i2c_master_status(gsbi_id);
98 if (ret)
99 return ret;
100 if (stopwatch_expired(timeout))
101 return QUP_ERR_TIMEOUT;
104 return QUP_SUCCESS;
107 static qup_return_t qup_fifo_wait_while(gsbi_id_t gsbi_id, uint32_t status,
108 struct stopwatch *timeout)
110 qup_return_t ret = QUP_ERR_UNDEFINED;
112 while (read32(QUP_ADDR(gsbi_id, QUP_OPERATIONAL)) & status) {
113 ret = qup_i2c_master_status(gsbi_id);
114 if (ret)
115 return ret;
116 if (stopwatch_expired(timeout))
117 return QUP_ERR_TIMEOUT;
120 return QUP_SUCCESS;
123 static qup_return_t qup_i2c_write_fifo(gsbi_id_t gsbi_id, qup_data_t *p_tx_obj,
124 uint8_t stop_seq)
126 qup_return_t ret = QUP_ERR_UNDEFINED;
127 uint8_t addr = p_tx_obj->p.iic.addr;
128 uint8_t *data_ptr = p_tx_obj->p.iic.data;
129 unsigned int data_len = p_tx_obj->p.iic.data_len;
130 unsigned int idx = 0;
131 struct stopwatch timeout;
133 qup_reset_master_status(gsbi_id);
134 qup_set_state(gsbi_id, QUP_STATE_RUN);
136 write32(QUP_ADDR(gsbi_id, QUP_OUTPUT_FIFO),
137 (QUP_I2C_START_SEQ | QUP_I2C_ADDR(addr)));
139 stopwatch_init_usecs_expire(&timeout, CONFIG_I2C_TRANSFER_TIMEOUT_US);
140 while (data_len) {
141 if (data_len == 1 && stop_seq) {
142 write32(QUP_ADDR(gsbi_id, QUP_OUTPUT_FIFO),
143 QUP_I2C_STOP_SEQ | QUP_I2C_DATA(data_ptr[idx]));
144 } else {
145 write32(QUP_ADDR(gsbi_id, QUP_OUTPUT_FIFO),
146 QUP_I2C_DATA_SEQ | QUP_I2C_DATA(data_ptr[idx]));
148 data_len--;
149 idx++;
150 if (data_len) {
151 ret = qup_fifo_wait_while(gsbi_id, OUTPUT_FIFO_FULL,
152 &timeout);
153 if (ret)
154 return ret;
156 /* Hardware sets the OUTPUT_SERVICE_FLAG flag to 1 when
157 OUTPUT_FIFO_NOT_EMPTY flag in the QUP_OPERATIONAL
158 register changes from 1 to 0, indicating that software
159 can write more data to the output FIFO. Software should
160 set OUTPUT_SERVICE_FLAG to 1 to clear it to 0, which
161 means that software knows to return to fill the output
162 FIFO with data.
164 if (read32(QUP_ADDR(gsbi_id, QUP_OPERATIONAL)) &
165 OUTPUT_SERVICE_FLAG) {
166 write32(QUP_ADDR(gsbi_id, QUP_OPERATIONAL),
167 OUTPUT_SERVICE_FLAG);
171 ret = qup_fifo_wait_while(gsbi_id, OUTPUT_FIFO_NOT_EMPTY, &timeout);
172 if (ret)
173 return ret;
175 qup_set_state(gsbi_id, QUP_STATE_PAUSE);
176 return qup_i2c_master_status(gsbi_id);
179 static qup_return_t qup_i2c_write(gsbi_id_t gsbi_id, uint8_t mode,
180 qup_data_t *p_tx_obj, uint8_t stop_seq)
182 qup_return_t ret = QUP_ERR_UNDEFINED;
184 switch (mode) {
185 case QUP_MODE_FIFO:
186 ret = qup_i2c_write_fifo(gsbi_id, p_tx_obj, stop_seq);
187 break;
188 default:
189 ret = QUP_ERR_UNSUPPORTED;
192 if (ret) {
193 qup_set_state(gsbi_id, QUP_STATE_RESET);
194 printk(BIOS_ERR, "%s() failed (%d)\n", __func__, ret);
197 return ret;
200 static qup_return_t qup_i2c_read_fifo(gsbi_id_t gsbi_id, qup_data_t *p_tx_obj)
202 qup_return_t ret = QUP_ERR_UNDEFINED;
203 uint8_t addr = p_tx_obj->p.iic.addr;
204 uint8_t *data_ptr = p_tx_obj->p.iic.data;
205 unsigned int data_len = p_tx_obj->p.iic.data_len;
206 unsigned int idx = 0;
207 struct stopwatch timeout;
209 qup_reset_master_status(gsbi_id);
210 qup_set_state(gsbi_id, QUP_STATE_RUN);
212 write32(QUP_ADDR(gsbi_id, QUP_OUTPUT_FIFO),
213 QUP_I2C_START_SEQ | (QUP_I2C_ADDR(addr) | QUP_I2C_SLAVE_READ));
215 write32(QUP_ADDR(gsbi_id, QUP_OUTPUT_FIFO),
216 QUP_I2C_RECV_SEQ | data_len);
218 stopwatch_init_usecs_expire(&timeout, CONFIG_I2C_TRANSFER_TIMEOUT_US);
219 ret = qup_fifo_wait_while(gsbi_id, OUTPUT_FIFO_NOT_EMPTY, &timeout);
220 if (ret)
221 return ret;
223 write32(QUP_ADDR(gsbi_id, QUP_OPERATIONAL), OUTPUT_SERVICE_FLAG);
225 while (data_len) {
226 uint32_t data;
228 ret = qup_fifo_wait_for(gsbi_id, INPUT_SERVICE_FLAG, &timeout);
229 if (ret)
230 return ret;
232 data = read32(QUP_ADDR(gsbi_id, QUP_INPUT_FIFO));
235 * Process tag and corresponding data value. For I2C master
236 * mini-core, data in FIFO is composed of 16 bits and is divided
237 * into an 8-bit tag for the upper bits and 8-bit data for the
238 * lower bits. The 8-bit tag indicates whether the byte is the
239 * last byte, or if a bus error happened during the receipt of
240 * the byte.
242 if ((QUP_I2C_MI_TAG(data)) == QUP_I2C_MIDATA_SEQ) {
243 /* Tag: MIDATA = Master input data.*/
244 data_ptr[idx] = QUP_I2C_DATA(data);
245 idx++;
246 data_len--;
247 write32(QUP_ADDR(gsbi_id, QUP_OPERATIONAL),
248 INPUT_SERVICE_FLAG);
249 } else if (QUP_I2C_MI_TAG(data) == QUP_I2C_MISTOP_SEQ) {
250 /* Tag: MISTOP: Last byte of master input. */
251 data_ptr[idx] = QUP_I2C_DATA(data);
252 idx++;
253 data_len--;
254 break;
255 } else {
256 /* Tag: MINACK: Invalid master input data.*/
257 break;
261 write32(QUP_ADDR(gsbi_id, QUP_OPERATIONAL), INPUT_SERVICE_FLAG);
262 p_tx_obj->p.iic.data_len = idx;
263 qup_set_state(gsbi_id, QUP_STATE_PAUSE);
265 return QUP_SUCCESS;
268 static qup_return_t qup_i2c_read(gsbi_id_t gsbi_id, uint8_t mode,
269 qup_data_t *p_tx_obj)
271 qup_return_t ret = QUP_ERR_UNDEFINED;
273 switch (mode) {
274 case QUP_MODE_FIFO:
275 ret = qup_i2c_read_fifo(gsbi_id, p_tx_obj);
276 break;
277 default:
278 ret = QUP_ERR_UNSUPPORTED;
281 if (ret) {
282 qup_set_state(gsbi_id, QUP_STATE_RESET);
283 printk(BIOS_ERR, "%s() failed (%d)\n", __func__, ret);
286 return ret;
289 qup_return_t qup_init(gsbi_id_t gsbi_id, const qup_config_t *config_ptr)
291 qup_return_t ret = QUP_ERR_UNDEFINED;
292 uint32_t reg_val;
294 /* Reset the QUP core.*/
295 write32(QUP_ADDR(gsbi_id, QUP_SW_RESET), 0x1);
297 /*Wait till the reset takes effect */
298 ret = qup_wait_for_state(gsbi_id, QUP_STATE_RESET);
299 if (ret)
300 goto bailout;
302 /* Reset the config */
303 write32(QUP_ADDR(gsbi_id, QUP_CONFIG), 0);
305 /*Program the config register*/
306 /*Set N value*/
307 reg_val = 0x0F;
308 /*Set protocol*/
309 switch (config_ptr->protocol) {
310 case QUP_MINICORE_I2C_MASTER:
311 reg_val |= ((config_ptr->protocol &
312 QUP_MINI_CORE_PROTO_MASK) <<
313 QUP_MINI_CORE_PROTO_SHFT);
314 break;
315 default:
316 ret = QUP_ERR_UNSUPPORTED;
317 goto bailout;
319 write32(QUP_ADDR(gsbi_id, QUP_CONFIG), reg_val);
321 /*Reset i2c clk cntl register*/
322 write32(QUP_ADDR(gsbi_id, QUP_I2C_MASTER_CLK_CTL), 0);
324 /*Set QUP IO Mode*/
325 switch (config_ptr->mode) {
326 case QUP_MODE_FIFO:
327 reg_val = QUP_OUTPUT_BIT_SHIFT_EN |
328 ((config_ptr->mode & QUP_MODE_MASK) <<
329 QUP_OUTPUT_MODE_SHFT) |
330 ((config_ptr->mode & QUP_MODE_MASK) <<
331 QUP_INPUT_MODE_SHFT);
332 break;
333 default:
334 ret = QUP_ERR_UNSUPPORTED;
335 goto bailout;
337 write32(QUP_ADDR(gsbi_id, QUP_IO_MODES), reg_val);
339 /*Set i2c clk cntl*/
340 reg_val = (QUP_DIVIDER_MIN_VAL << QUP_HS_DIVIDER_SHFT);
341 reg_val |= ((((config_ptr->src_frequency / config_ptr->clk_frequency)
342 / 2) - QUP_DIVIDER_MIN_VAL) &
343 QUP_FS_DIVIDER_MASK);
344 write32(QUP_ADDR(gsbi_id, QUP_I2C_MASTER_CLK_CTL), reg_val);
346 bailout:
347 if (ret)
348 printk(BIOS_ERR, "failed to init qup (%d)\n", ret);
350 return ret;
353 qup_return_t qup_set_state(gsbi_id_t gsbi_id, uint32_t state)
355 qup_return_t ret = QUP_ERR_UNDEFINED;
356 unsigned int curr_state = read32(QUP_ADDR(gsbi_id, QUP_STATE));
358 if (state <= QUP_STATE_PAUSE && (curr_state & QUP_STATE_VALID_MASK)) {
360 * For PAUSE_STATE to RESET_STATE transition,
361 * two writes of 10[binary]) are required for the
362 * transition to complete.
364 if (QUP_STATE_PAUSE == curr_state && QUP_STATE_RESET == state) {
365 write32(QUP_ADDR(gsbi_id, QUP_STATE), 0x2);
366 write32(QUP_ADDR(gsbi_id, QUP_STATE), 0x2);
367 } else {
368 write32(QUP_ADDR(gsbi_id, QUP_STATE), state);
370 ret = qup_wait_for_state(gsbi_id, state);
373 return ret;
376 static qup_return_t qup_i2c_send_data(gsbi_id_t gsbi_id, qup_data_t *p_tx_obj,
377 uint8_t stop_seq)
379 qup_return_t ret = QUP_ERR_UNDEFINED;
380 uint8_t mode = (read32(QUP_ADDR(gsbi_id, QUP_IO_MODES)) >>
381 QUP_OUTPUT_MODE_SHFT) & QUP_MODE_MASK;
383 ret = qup_i2c_write(gsbi_id, mode, p_tx_obj, stop_seq);
384 if (0) {
385 int i;
386 printk(BIOS_DEBUG, "i2c tx bus %d device %2.2x:",
387 gsbi_id, p_tx_obj->p.iic.addr);
388 for (i = 0; i < p_tx_obj->p.iic.data_len; i++)
389 printk(BIOS_DEBUG, " %2.2x", p_tx_obj->p.iic.data[i]);
390 printk(BIOS_DEBUG, "\n");
393 return ret;
396 qup_return_t qup_send_data(gsbi_id_t gsbi_id, qup_data_t *p_tx_obj,
397 uint8_t stop_seq)
399 qup_return_t ret = QUP_ERR_UNDEFINED;
401 if (p_tx_obj->protocol == ((read32(QUP_ADDR(gsbi_id, QUP_CONFIG)) >>
402 QUP_MINI_CORE_PROTO_SHFT) & QUP_MINI_CORE_PROTO_MASK)) {
403 switch (p_tx_obj->protocol) {
404 case QUP_MINICORE_I2C_MASTER:
405 ret = qup_i2c_send_data(gsbi_id, p_tx_obj, stop_seq);
406 break;
407 default:
408 ret = QUP_ERR_UNSUPPORTED;
412 return ret;
415 static qup_return_t qup_i2c_recv_data(gsbi_id_t gsbi_id, qup_data_t *p_rx_obj)
417 qup_return_t ret = QUP_ERR_UNDEFINED;
418 uint8_t mode = (read32(QUP_ADDR(gsbi_id, QUP_IO_MODES)) >>
419 QUP_INPUT_MODE_SHFT) & QUP_MODE_MASK;
421 ret = qup_i2c_read(gsbi_id, mode, p_rx_obj);
422 if (0) {
423 int i;
424 printk(BIOS_DEBUG, "i2c rxed on bus %d device %2.2x:",
425 gsbi_id, p_rx_obj->p.iic.addr);
426 for (i = 0; i < p_rx_obj->p.iic.data_len; i++)
427 printk(BIOS_DEBUG, " %2.2x", p_rx_obj->p.iic.data[i]);
428 printk(BIOS_DEBUG, "\n");
431 return ret;
434 qup_return_t qup_recv_data(gsbi_id_t gsbi_id, qup_data_t *p_rx_obj)
436 qup_return_t ret = QUP_ERR_UNDEFINED;
438 if (p_rx_obj->protocol == ((read32(QUP_ADDR(gsbi_id, QUP_CONFIG)) >>
439 QUP_MINI_CORE_PROTO_SHFT) & QUP_MINI_CORE_PROTO_MASK)) {
440 switch (p_rx_obj->protocol) {
441 case QUP_MINICORE_I2C_MASTER:
442 ret = qup_i2c_recv_data(gsbi_id, p_rx_obj);
443 break;
444 default:
445 ret = QUP_ERR_UNSUPPORTED;
449 return ret;