treewide: Move "is part of the coreboot project" line in its own comment
[coreboot.git] / src / soc / qualcomm / ipq40xx / qup.c
blobd02f9a8d4fff1711873ac3c878141dd5d6046e8c
1 /* This file is part of the coreboot project. */
2 /*
4 * Redistribution and use in source and binary forms, with or without
5 * modification, are permitted provided that the following conditions are
6 * met:
7 * * Redistributions of source code must retain the above copyright
8 * notice, this list of conditions and the following disclaimer.
9 * * Redistributions in binary form must reproduce the above
10 * copyright notice, this list of conditions and the following
11 * disclaimer in the documentation and/or other materials provided
12 * with the distribution.
13 * * Neither the name of The Linux Foundation nor the names of its
14 * contributors may be used to endorse or promote products derived
15 * from this software without specific prior written permission.
17 * THIS SOFTWARE IS PROVIDED "AS IS" AND ANY EXPRESS OR IMPLIED
18 * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
19 * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT
20 * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS
21 * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
22 * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
23 * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR
24 * BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
25 * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE
26 * OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN
27 * IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
30 #include <device/mmio.h>
31 #include <console/console.h>
32 #include <delay.h>
33 #include <soc/iomap.h>
34 #include <soc/qup.h>
36 #define TIMEOUT_CNT 100
38 #define QUP_ADDR(id, reg) (blsp_qup_base(id) + (reg))
40 #define QUP_DEBUG 0
42 #define QUPDBG BIOS_ERR, "\t-> "
44 #if QUP_DEBUG
45 #define qup_write32(a, v) do { \
46 write32(a, v); \
47 printk(QUPDBG "%s(%d): write32(%p, 0x%x)\n", \
48 __func__, __LINE__, a, v); \
49 } while (0)
50 #else
51 #define qup_write32 write32
52 #endif
54 static qup_return_t qup_i2c_master_status(blsp_qup_id_t id)
56 uint32_t reg_val = read32(QUP_ADDR(id, QUP_I2C_MASTER_STATUS));
58 if (read32(QUP_ADDR(id, QUP_ERROR_FLAGS)))
59 return QUP_ERR_XFER_FAIL;
61 #if QUP_DEBUG
62 printk(QUPDBG "%s: 0x%x\n", __func__, reg_val);
63 #endif
65 if (reg_val & QUP_I2C_INVALID_READ_ADDR)
66 return QUP_ERR_I2C_INVALID_SLAVE_ADDR;
67 if (reg_val & QUP_I2C_FAILED_MASK)
68 return QUP_ERR_I2C_FAILED;
69 if (reg_val & QUP_I2C_ARB_LOST)
70 return QUP_ERR_I2C_ARB_LOST;
71 if (reg_val & QUP_I2C_BUS_ERROR)
72 return QUP_ERR_I2C_BUS_ERROR;
73 if (reg_val & QUP_I2C_INVALID_WRITE)
74 return QUP_ERR_I2C_INVALID_WRITE;
75 if (reg_val & QUP_I2C_PACKET_NACK)
76 return QUP_ERR_I2C_NACK;
77 if (reg_val & QUP_I2C_INVALID_TAG)
78 return QUP_ERR_I2C_INVALID_TAG;
80 return QUP_SUCCESS;
83 static int check_bit_state(uint32_t *reg, int wait_for)
85 unsigned int count = TIMEOUT_CNT;
87 while ((read32(reg) & (QUP_STATE_VALID_MASK | QUP_STATE_MASK)) !=
88 (QUP_STATE_VALID | wait_for)) {
89 if (count == 0)
90 return QUP_ERR_TIMEOUT;
91 count--;
94 return QUP_SUCCESS;
98 * Check whether GSBIn_QUP State is valid
100 static qup_return_t qup_wait_for_state(blsp_qup_id_t id, unsigned int wait_for)
102 return check_bit_state(QUP_ADDR(id, QUP_STATE), wait_for);
105 qup_return_t qup_reset_i2c_master_status(blsp_qup_id_t id)
108 * The I2C_STATUS is a status register.
109 * Writing any value clears the status bits.
111 qup_write32(QUP_ADDR(id, QUP_I2C_MASTER_STATUS), 0);
112 return QUP_SUCCESS;
115 static qup_return_t qup_reset_master_status(blsp_qup_id_t id)
117 qup_write32(QUP_ADDR(id, QUP_ERROR_FLAGS), 0x3C);
118 qup_write32(QUP_ADDR(id, QUP_ERROR_FLAGS_EN), 0x3C);
119 qup_reset_i2c_master_status(id);
120 return QUP_SUCCESS;
123 static qup_return_t qup_fifo_wait_for(blsp_qup_id_t id, uint32_t status)
125 qup_return_t ret = QUP_ERR_UNDEFINED;
126 unsigned int count = TIMEOUT_CNT;
128 while (!(read32(QUP_ADDR(id, QUP_OPERATIONAL)) & status)) {
129 ret = qup_i2c_master_status(id);
130 if (ret)
131 return ret;
132 if (count == 0)
133 return QUP_ERR_TIMEOUT;
134 count--;
137 return QUP_SUCCESS;
140 static qup_return_t qup_fifo_wait_while(blsp_qup_id_t id, uint32_t status)
142 qup_return_t ret = QUP_ERR_UNDEFINED;
143 unsigned int count = TIMEOUT_CNT;
145 while (read32(QUP_ADDR(id, QUP_OPERATIONAL)) & status) {
146 ret = qup_i2c_master_status(id);
147 if (ret)
148 return ret;
149 if (count == 0)
150 return QUP_ERR_TIMEOUT;
151 count--;
154 return QUP_SUCCESS;
157 static inline uint32_t qup_i2c_create_output_tag(int stop, u8 data)
159 uint32_t tag;
161 if (stop)
162 tag = QUP_I2C_STOP_SEQ | QUP_I2C_DATA(data);
163 else
164 tag = QUP_I2C_DATA_SEQ | QUP_I2C_DATA(data);
166 return tag;
169 static inline qup_return_t qup_i2c_write_fifo_flush(blsp_qup_id_t id)
171 qup_return_t ret = QUP_ERR_UNDEFINED;
173 qup_write32(QUP_ADDR(id, QUP_OPERATIONAL), OUTPUT_SERVICE_FLAG);
175 mdelay(4); /* TPM seems to need this */
177 ret = qup_fifo_wait_while(id, OUTPUT_FIFO_NOT_EMPTY);
178 if (ret)
179 return ret;
181 ret = qup_i2c_master_status(id);
183 if (ret)
184 printk(BIOS_DEBUG, "%s: error\n", __func__);
186 return ret;
189 static qup_return_t qup_i2c_write_fifo(blsp_qup_id_t id, qup_data_t *p_tx_obj,
190 uint8_t stop_seq)
192 qup_return_t ret = QUP_ERR_UNDEFINED;
193 uint8_t addr = p_tx_obj->p.iic.addr;
194 uint8_t *data_ptr = p_tx_obj->p.iic.data;
195 unsigned int data_len = p_tx_obj->p.iic.data_len;
196 unsigned int idx = 0;
197 uint32_t tag, *fifo = QUP_ADDR(id, QUP_OUTPUT_FIFO);
199 qup_reset_master_status(id);
201 qup_write32(QUP_ADDR(id, QUP_MX_OUTPUT_COUNT), data_len + 1);
203 qup_set_state(id, QUP_STATE_RUN);
206 * Since UNPACK enable is set in io mode register, populate 2 tags
207 * for each fifo register.
209 * Create the first tag as follows, with the start tag and first byte
210 * of the data to be written
211 * +--------+--------+--------+--------+
212 * | STOP / | data | START | ADDR |
213 * |DATA tag| byte | tag | << 1 |
214 * +--------+--------+--------+--------+
215 * rest will be created in the following while loop.
217 tag = qup_i2c_create_output_tag(data_len == 1 && stop_seq,
218 data_ptr[idx]);
219 tag = ((tag << 16) & 0xffff0000) |
220 (QUP_I2C_START_SEQ | QUP_I2C_ADDR(addr));
221 data_len--;
222 idx++;
224 qup_write32(fifo, tag);
226 while (data_len) {
228 tag = qup_i2c_create_output_tag(data_len == 1 && stop_seq,
229 data_ptr[idx]);
230 data_len--;
231 idx++;
233 if (data_len) {
234 tag |= qup_i2c_create_output_tag(
235 data_len == 1 && stop_seq,
236 data_ptr[idx]) << 16;
237 data_len--;
238 idx++;
241 qup_write32(fifo, tag);
243 ret = qup_i2c_write_fifo_flush(id);
245 if (ret) {
246 printk(QUPDBG "%s: error\n", __func__);
247 return ret;
251 ret = qup_i2c_write_fifo_flush(id);
253 qup_set_state(id, QUP_STATE_RESET);
255 return ret;
258 static qup_return_t qup_i2c_write(blsp_qup_id_t id, uint8_t mode,
259 qup_data_t *p_tx_obj, uint8_t stop_seq)
261 qup_return_t ret = QUP_ERR_UNDEFINED;
263 switch (mode) {
264 case QUP_MODE_FIFO:
265 case QUP_MODE_BLOCK:
266 ret = qup_i2c_write_fifo(id, p_tx_obj, stop_seq);
267 break;
268 default:
269 ret = QUP_ERR_UNSUPPORTED;
272 if (ret) {
273 qup_set_state(id, QUP_STATE_RESET);
274 printk(QUPDBG "%s() failed (%d)\n", __func__, ret);
277 return ret;
280 static int qup_i2c_parse_tag(uint32_t data, uint8_t *data_ptr, uint32_t len)
282 int i, idx = 0;
283 int max = (len > 2) ? 2 : len;
285 for (i = 0; i < max; i++) {
286 switch (QUP_I2C_MI_TAG(data)) {
287 case QUP_I2C_MIDATA_SEQ:
288 data_ptr[idx] = QUP_I2C_DATA(data);
289 idx++;
290 break;
291 case QUP_I2C_MISTOP_SEQ:
292 data_ptr[idx] = QUP_I2C_DATA(data);
293 idx++;
294 return idx;
295 default:
296 printk(QUPDBG "%s: Unexpected tag (0x%x)\n", __func__,
297 QUP_I2C_MI_TAG(data));
298 return -1;
301 data = (data >> 16);
304 return idx;
307 static qup_return_t qup_i2c_read_fifo(blsp_qup_id_t id, qup_data_t *p_tx_obj)
309 qup_return_t ret = QUP_ERR_UNDEFINED;
310 uint8_t addr = p_tx_obj->p.iic.addr;
311 uint8_t *data_ptr = p_tx_obj->p.iic.data;
312 unsigned int data_len = p_tx_obj->p.iic.data_len;
313 unsigned int idx = 0;
314 uint32_t *fifo = QUP_ADDR(id, QUP_OUTPUT_FIFO);
316 qup_reset_master_status(id);
318 qup_write32(QUP_ADDR(id, QUP_IO_MODES),
319 QUP_UNPACK_EN | QUP_PACK_EN |
320 ((QUP_MODE_BLOCK & QUP_MODE_MASK) <<
321 QUP_OUTPUT_MODE_SHFT) |
322 ((QUP_MODE_BLOCK & QUP_MODE_MASK) <<
323 QUP_INPUT_MODE_SHFT));
325 qup_write32(QUP_ADDR(id, QUP_MX_INPUT_COUNT), data_len);
327 qup_set_state(id, QUP_STATE_RUN);
329 qup_write32(fifo, (QUP_I2C_START_SEQ |
330 (QUP_I2C_ADDR(addr) | QUP_I2C_SLAVE_READ)) |
331 ((QUP_I2C_RECV_SEQ | data_len) << 16));
333 ret = qup_i2c_write_fifo_flush(id);
334 if (ret) {
335 printk(QUPDBG "%s: OUTPUT_FIFO_NOT_EMPTY\n", __func__);
336 return ret;
339 ret = qup_fifo_wait_for(id, INPUT_SERVICE_FLAG);
340 if (ret) {
341 printk(QUPDBG "%s: INPUT_SERVICE_FLAG\n", __func__);
342 return ret;
345 fifo = QUP_ADDR(id, QUP_INPUT_FIFO);
347 while (data_len) {
348 uint32_t data;
349 int count;
351 data = read32(fifo);
352 mdelay(1);
354 count = qup_i2c_parse_tag(data, data_ptr + idx, data_len);
356 if (count < 0) {
357 printk(QUPDBG "%s: Cannot parse tag 0x%x\n",
358 __func__, data);
359 qup_set_state(id, QUP_STATE_PAUSE);
361 return QUP_ERR_I2C_INVALID_TAG;
364 idx += count;
365 data_len -= count;
367 qup_write32(QUP_ADDR(id, QUP_OPERATIONAL), INPUT_SERVICE_FLAG);
370 p_tx_obj->p.iic.data_len = idx;
372 qup_write32(QUP_ADDR(id, QUP_MX_READ_COUNT), 0);
374 qup_set_state(id, QUP_STATE_RESET);
376 return QUP_SUCCESS;
379 static qup_return_t qup_i2c_read(blsp_qup_id_t id, uint8_t mode,
380 qup_data_t *p_tx_obj)
382 qup_return_t ret = QUP_ERR_UNDEFINED;
384 qup_set_state(id, QUP_STATE_RESET);
386 switch (mode) {
387 case QUP_MODE_FIFO:
388 case QUP_MODE_BLOCK:
389 ret = qup_i2c_read_fifo(id, p_tx_obj);
390 break;
391 default:
392 ret = QUP_ERR_UNSUPPORTED;
395 if (ret) {
396 qup_set_state(id, QUP_STATE_RESET);
397 printk(QUPDBG "%s() failed (%d)\n", __func__, ret);
400 return ret;
403 qup_return_t qup_init(blsp_qup_id_t id, const qup_config_t *config_ptr)
405 qup_return_t ret = QUP_ERR_UNDEFINED;
406 uint32_t reg_val;
408 /* Reset the QUP core.*/
409 qup_write32(QUP_ADDR(id, QUP_SW_RESET), 0x1);
411 /* Wait till the reset takes effect */
412 ret = qup_wait_for_state(id, QUP_STATE_RESET);
413 if (ret)
414 goto bailout;
416 /* Reset the config */
417 qup_write32(QUP_ADDR(id, QUP_CONFIG), 0);
419 /* Program the config register */
420 /* Set N value */
421 reg_val = 0x0F;
422 /* Set protocol */
423 switch (config_ptr->protocol) {
424 case QUP_MINICORE_I2C_MASTER:
425 reg_val |= ((config_ptr->protocol &
426 QUP_MINI_CORE_PROTO_MASK) <<
427 QUP_MINI_CORE_PROTO_SHFT);
428 break;
429 default:
430 ret = QUP_ERR_UNSUPPORTED;
431 goto bailout;
433 reg_val |= QUP_APP_CLK_ON_EN | QUP_CORE_CLK_ON_EN;
434 qup_write32(QUP_ADDR(id, QUP_CONFIG), reg_val);
436 /* Choose version 1 tag */
437 qup_write32(QUP_ADDR(id, QUP_I2C_MASTER_CONFIG), 0);
439 /* Reset i2c clk cntl register */
440 qup_write32(QUP_ADDR(id, QUP_I2C_MASTER_CLK_CTL), 0);
442 /* Set QUP IO Mode */
443 switch (config_ptr->mode) {
444 case QUP_MODE_FIFO:
445 case QUP_MODE_BLOCK:
446 reg_val = QUP_UNPACK_EN | QUP_PACK_EN |
447 ((config_ptr->mode & QUP_MODE_MASK) <<
448 QUP_OUTPUT_MODE_SHFT) |
449 ((config_ptr->mode & QUP_MODE_MASK) <<
450 QUP_INPUT_MODE_SHFT);
451 break;
452 default:
453 ret = QUP_ERR_UNSUPPORTED;
454 goto bailout;
456 qup_write32(QUP_ADDR(id, QUP_IO_MODES), reg_val);
458 /*Set i2c clk cntl*/
459 reg_val = (QUP_DIVIDER_MIN_VAL << QUP_HS_DIVIDER_SHFT);
460 reg_val |= ((((config_ptr->src_frequency / config_ptr->clk_frequency)
461 / 2) - QUP_DIVIDER_MIN_VAL) &
462 QUP_FS_DIVIDER_MASK);
463 qup_write32(QUP_ADDR(id, QUP_I2C_MASTER_CLK_CTL), reg_val);
465 qup_set_state(id, QUP_STATE_RESET);
466 bailout:
467 if (ret)
468 printk(QUPDBG "failed to init qup (%d)\n", ret);
470 return ret;
473 qup_return_t qup_set_state(blsp_qup_id_t id, uint32_t state)
475 qup_return_t ret = QUP_ERR_UNDEFINED;
476 unsigned int curr_state = read32(QUP_ADDR(id, QUP_STATE));
478 if (state <= QUP_STATE_PAUSE && (curr_state & QUP_STATE_VALID_MASK)) {
480 * For PAUSE_STATE to RESET_STATE transition,
481 * two writes of 10[binary]) are required for the
482 * transition to complete.
484 if (QUP_STATE_PAUSE == curr_state && QUP_STATE_RESET == state) {
485 qup_write32(QUP_ADDR(id, QUP_STATE), 0x2);
486 qup_write32(QUP_ADDR(id, QUP_STATE), 0x2);
487 } else {
488 qup_write32(QUP_ADDR(id, QUP_STATE), state);
490 ret = qup_wait_for_state(id, state);
493 return ret;
496 static qup_return_t qup_i2c_send_data(blsp_qup_id_t id, qup_data_t *p_tx_obj,
497 uint8_t stop_seq)
499 qup_return_t ret = QUP_ERR_UNDEFINED;
500 uint8_t mode = (read32(QUP_ADDR(id, QUP_IO_MODES)) >>
501 QUP_OUTPUT_MODE_SHFT) & QUP_MODE_MASK;
503 ret = qup_i2c_write(id, mode, p_tx_obj, stop_seq);
504 if (QUP_DEBUG) {
505 int i;
507 printk(BIOS_DEBUG, "i2c tx bus %d device %2.2x:",
508 id, p_tx_obj->p.iic.addr);
509 for (i = 0; i < p_tx_obj->p.iic.data_len; i++)
510 printk(BIOS_DEBUG, " %2.2x", p_tx_obj->p.iic.data[i]);
511 printk(BIOS_DEBUG, "\n");
514 return ret;
517 qup_return_t qup_send_data(blsp_qup_id_t id, qup_data_t *p_tx_obj,
518 uint8_t stop_seq)
520 qup_return_t ret = QUP_ERR_UNDEFINED;
522 if (p_tx_obj->protocol == ((read32(QUP_ADDR(id, QUP_CONFIG)) >>
523 QUP_MINI_CORE_PROTO_SHFT) & QUP_MINI_CORE_PROTO_MASK)) {
524 switch (p_tx_obj->protocol) {
525 case QUP_MINICORE_I2C_MASTER:
526 ret = qup_i2c_send_data(id, p_tx_obj, stop_seq);
527 break;
528 default:
529 ret = QUP_ERR_UNSUPPORTED;
533 return ret;
536 static qup_return_t qup_i2c_recv_data(blsp_qup_id_t id, qup_data_t *p_rx_obj)
538 qup_return_t ret = QUP_ERR_UNDEFINED;
539 uint8_t mode = (read32(QUP_ADDR(id, QUP_IO_MODES)) >>
540 QUP_INPUT_MODE_SHFT) & QUP_MODE_MASK;
542 ret = qup_i2c_read(id, mode, p_rx_obj);
543 if (QUP_DEBUG) {
544 int i;
546 printk(BIOS_DEBUG, "i2c rxed on bus %d device %2.2x:",
547 id, p_rx_obj->p.iic.addr);
548 for (i = 0; i < p_rx_obj->p.iic.data_len; i++)
549 printk(BIOS_DEBUG, " %2.2x", p_rx_obj->p.iic.data[i]);
550 printk(BIOS_DEBUG, "\n");
553 return ret;
556 qup_return_t qup_recv_data(blsp_qup_id_t id, qup_data_t *p_rx_obj)
558 qup_return_t ret = QUP_ERR_UNDEFINED;
560 if (p_rx_obj->protocol == ((read32(QUP_ADDR(id, QUP_CONFIG)) >>
561 QUP_MINI_CORE_PROTO_SHFT) & QUP_MINI_CORE_PROTO_MASK)) {
562 switch (p_rx_obj->protocol) {
563 case QUP_MINICORE_I2C_MASTER:
564 ret = qup_i2c_recv_data(id, p_rx_obj);
565 break;
566 default:
567 ret = QUP_ERR_UNSUPPORTED;
571 return ret;