coreboot
coreboot is an Open Source project aimed at replacing the proprietary BIOS found in most computers.
qup.c
Go to the documentation of this file.
1 /* SPDX-License-Identifier: BSD-3-Clause */
2 
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>
9 
10 #define TIMEOUT_CNT 100000
11 
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,
21 };
22 
23 #define QUP_ADDR(gsbi_num, reg) ((void *)((gsbi_qup_base[gsbi_num-1]) + (reg)))
24 
26 {
27  uint32_t reg_val = read32(QUP_ADDR(gsbi_id, QUP_I2C_MASTER_STATUS));
28 
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)
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)
41  if (reg_val & QUP_I2C_PACKET_NACK)
42  return QUP_ERR_I2C_NACK;
43  if (reg_val & QUP_I2C_INVALID_TAG)
45 
46  return QUP_SUCCESS;
47 }
48 
49 static int check_bit_state(uint32_t *reg, int wait_for)
50 {
51  unsigned int count = TIMEOUT_CNT;
52 
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);
59  }
60 
61  return QUP_SUCCESS;
62 }
63 
64 /*
65  * Check whether GSBIn_QUP State is valid
66  */
67 static qup_return_t qup_wait_for_state(gsbi_id_t gsbi_id, unsigned int wait_for)
68 {
69  return check_bit_state(QUP_ADDR(gsbi_id, QUP_STATE), wait_for);
70 }
71 
73 {
74  /*
75  * Writing a one clears the status bits.
76  * Bit31-25, Bit1 and Bit0 are reserved.
77  */
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;
81 }
82 
84 {
85  write32(QUP_ADDR(gsbi_id, QUP_ERROR_FLAGS), 0x7C);
86  write32(QUP_ADDR(gsbi_id, QUP_ERROR_FLAGS_EN), 0x7C);
88  return QUP_SUCCESS;
89 }
90 
92  struct stopwatch *timeout)
93 {
95 
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;
102  }
103 
104  return QUP_SUCCESS;
105 }
106 
108  struct stopwatch *timeout)
109 {
111 
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;
118  }
119 
120  return QUP_SUCCESS;
121 }
122 
124  uint8_t stop_seq)
125 {
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;
132 
133  qup_reset_master_status(gsbi_id);
134  qup_set_state(gsbi_id, QUP_STATE_RUN);
135 
136  write32(QUP_ADDR(gsbi_id, QUP_OUTPUT_FIFO),
138 
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]));
147  }
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;
155  }
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.
163  */
164  if (read32(QUP_ADDR(gsbi_id, QUP_OPERATIONAL)) &
166  write32(QUP_ADDR(gsbi_id, QUP_OPERATIONAL),
168  }
169  }
170 
171  ret = qup_fifo_wait_while(gsbi_id, OUTPUT_FIFO_NOT_EMPTY, &timeout);
172  if (ret)
173  return ret;
174 
175  qup_set_state(gsbi_id, QUP_STATE_PAUSE);
176  return qup_i2c_master_status(gsbi_id);
177 }
178 
180  qup_data_t *p_tx_obj, uint8_t stop_seq)
181 {
183 
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;
190  }
191 
192  if (ret) {
193  qup_set_state(gsbi_id, QUP_STATE_RESET);
194  printk(BIOS_ERR, "%s() failed (%d)\n", __func__, ret);
195  }
196 
197  return ret;
198 }
199 
201 {
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;
208 
209  qup_reset_master_status(gsbi_id);
210  qup_set_state(gsbi_id, QUP_STATE_RUN);
211 
212  write32(QUP_ADDR(gsbi_id, QUP_OUTPUT_FIFO),
214 
215  write32(QUP_ADDR(gsbi_id, QUP_OUTPUT_FIFO),
216  QUP_I2C_RECV_SEQ | data_len);
217 
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;
222 
224 
225  while (data_len) {
226  uint32_t data;
227 
228  ret = qup_fifo_wait_for(gsbi_id, INPUT_SERVICE_FLAG, &timeout);
229  if (ret)
230  return ret;
231 
232  data = read32(QUP_ADDR(gsbi_id, QUP_INPUT_FIFO));
233 
234  /*
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.
241  */
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),
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;
258  }
259  }
260 
262  p_tx_obj->p.iic.data_len = idx;
263  qup_set_state(gsbi_id, QUP_STATE_PAUSE);
264 
265  return QUP_SUCCESS;
266 }
267 
269  qup_data_t *p_tx_obj)
270 {
272 
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;
279  }
280 
281  if (ret) {
282  qup_set_state(gsbi_id, QUP_STATE_RESET);
283  printk(BIOS_ERR, "%s() failed (%d)\n", __func__, ret);
284  }
285 
286  return ret;
287 }
288 
289 qup_return_t qup_init(gsbi_id_t gsbi_id, const qup_config_t *config_ptr)
290 {
292  uint32_t reg_val;
293 
294  /* Reset the QUP core.*/
295  write32(QUP_ADDR(gsbi_id, QUP_SW_RESET), 0x1);
296 
297  /*Wait till the reset takes effect */
298  ret = qup_wait_for_state(gsbi_id, QUP_STATE_RESET);
299  if (ret)
300  goto bailout;
301 
302  /* Reset the config */
303  write32(QUP_ADDR(gsbi_id, QUP_CONFIG), 0);
304 
305  /*Program the config register*/
306  /*Set N value*/
307  reg_val = 0x0F;
308  /*Set protocol*/
309  switch (config_ptr->protocol) {
311  reg_val |= ((config_ptr->protocol &
314  break;
315  default:
316  ret = QUP_ERR_UNSUPPORTED;
317  goto bailout;
318  }
319  write32(QUP_ADDR(gsbi_id, QUP_CONFIG), reg_val);
320 
321  /*Reset i2c clk cntl register*/
323 
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) <<
330  ((config_ptr->mode & QUP_MODE_MASK) <<
332  break;
333  default:
334  ret = QUP_ERR_UNSUPPORTED;
335  goto bailout;
336  }
337  write32(QUP_ADDR(gsbi_id, QUP_IO_MODES), reg_val);
338 
339  /*Set i2c clk cntl*/
341  reg_val |= ((((config_ptr->src_frequency / config_ptr->clk_frequency)
342  / 2) - QUP_DIVIDER_MIN_VAL) &
344  write32(QUP_ADDR(gsbi_id, QUP_I2C_MASTER_CLK_CTL), reg_val);
345 
346 bailout:
347  if (ret)
348  printk(BIOS_ERR, "failed to init qup (%d)\n", ret);
349 
350  return ret;
351 }
352 
354 {
356  unsigned int curr_state = read32(QUP_ADDR(gsbi_id, QUP_STATE));
357 
358  if (state <= QUP_STATE_PAUSE && (curr_state & QUP_STATE_VALID_MASK)) {
359  /*
360  * For PAUSE_STATE to RESET_STATE transition,
361  * two writes of 10[binary]) are required for the
362  * transition to complete.
363  */
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);
369  }
370  ret = qup_wait_for_state(gsbi_id, state);
371  }
372 
373  return ret;
374 }
375 
377  uint8_t stop_seq)
378 {
380  uint8_t mode = (read32(QUP_ADDR(gsbi_id, QUP_IO_MODES)) >>
382 
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");
391  }
392 
393  return ret;
394 }
395 
397  uint8_t stop_seq)
398 {
400 
401  if (p_tx_obj->protocol == ((read32(QUP_ADDR(gsbi_id, QUP_CONFIG)) >>
403  switch (p_tx_obj->protocol) {
405  ret = qup_i2c_send_data(gsbi_id, p_tx_obj, stop_seq);
406  break;
407  default:
408  ret = QUP_ERR_UNSUPPORTED;
409  }
410  }
411 
412  return ret;
413 }
414 
416 {
418  uint8_t mode = (read32(QUP_ADDR(gsbi_id, QUP_IO_MODES)) >>
420 
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");
429  }
430 
431  return ret;
432 }
433 
435 {
437 
438  if (p_rx_obj->protocol == ((read32(QUP_ADDR(gsbi_id, QUP_CONFIG)) >>
440  switch (p_rx_obj->protocol) {
442  ret = qup_i2c_recv_data(gsbi_id, p_rx_obj);
443  break;
444  default:
445  ret = QUP_ERR_UNSUPPORTED;
446  }
447  }
448 
449  return ret;
450 }
static void write32(void *addr, uint32_t val)
Definition: mmio.h:40
static uint32_t read32(const void *addr)
Definition: mmio.h:22
static u32 addr
Definition: cirrus.c:14
#define printk(level,...)
Definition: stdlib.h:16
gsbi_id_t
Definition: gsbi.h:18
static int stopwatch_expired(struct stopwatch *sw)
Definition: timer.h:152
static void stopwatch_init_usecs_expire(struct stopwatch *sw, long us)
Definition: timer.h:127
#define QUP_STATE
Definition: qup.h:10
#define QUP_I2C_INVALID_READ_ADDR
Definition: qup.h:94
#define QUP_ERROR_FLAGS
Definition: qup.h:15
#define QUP_OUTPUT_FIFO
Definition: qup.h:24
#define QUP_I2C_STOP_SEQ
Definition: qup.h:75
#define QUP_I2C_MISTOP_SEQ
Definition: qup.h:80
#define QUP_MINI_CORE_PROTO_MASK
Definition: qup.h:61
#define QUP_I2C_BUS_ERROR
Definition: qup.h:100
#define QUP_I2C_FAILED_MASK
Definition: qup.h:96
#define OUTPUT_FIFO_FULL
Definition: qup.h:43
#define QUP_ERROR_FLAGS_EN
Definition: qup.h:16
#define OUTPUT_SERVICE_FLAG
Definition: qup.h:47
#define QUP_I2C_MIDATA_SEQ
Definition: qup.h:79
#define QUP_I2C_INVALID_TAG
Definition: qup.h:95
#define QUP_MINI_CORE_PROTO_SHFT
Definition: qup.h:60
#define QUP_SW_RESET
Definition: qup.h:12
#define QUP_I2C_SLAVE_READ
Definition: qup.h:86
#define QUP_I2C_ARB_LOST
Definition: qup.h:98
#define QUP_I2C_MASTER_CLK_CTL
Definition: qup.h:36
@ QUP_MINICORE_I2C_MASTER
Definition: qup.h:121
#define QUP_STATE_VALID_MASK
Definition: qup.h:69
#define QUP_STATE_VALID
Definition: qup.h:67
#define QUP_I2C_MASTER_STATUS
Definition: qup.h:37
#define QUP_FS_DIVIDER_MASK
Definition: qup.h:56
#define QUP_DIVIDER_MIN_VAL
Definition: qup.h:90
#define QUP_I2C_DATA(x)
Definition: qup.h:84
#define QUP_IO_MODES
Definition: qup.h:11
#define QUP_HS_DIVIDER_SHFT
Definition: qup.h:89
#define QUP_I2C_PACKET_NACK
Definition: qup.h:99
#define QUP_STATE_RESET
Definition: qup.h:64
qup_return_t
Definition: qup.h:102
@ QUP_ERR_I2C_INVALID_SLAVE_ADDR
Definition: qup.h:111
@ QUP_ERR_TIMEOUT
Definition: qup.h:106
@ QUP_ERR_UNSUPPORTED
Definition: qup.h:107
@ QUP_ERR_I2C_ARB_LOST
Definition: qup.h:109
@ QUP_ERR_UNDEFINED
Definition: qup.h:116
@ QUP_ERR_I2C_BUS_ERROR
Definition: qup.h:110
@ QUP_ERR_I2C_INVALID_WRITE
Definition: qup.h:114
@ QUP_ERR_I2C_NACK
Definition: qup.h:113
@ QUP_ERR_I2C_INVALID_TAG
Definition: qup.h:115
@ QUP_SUCCESS
Definition: qup.h:103
@ QUP_ERR_XFER_FAIL
Definition: qup.h:112
@ QUP_ERR_I2C_FAILED
Definition: qup.h:108
#define QUP_I2C_DATA_SEQ
Definition: qup.h:74
#define QUP_I2C_RECV_SEQ
Definition: qup.h:76
#define QUP_OUTPUT_BIT_SHIFT_EN
Definition: qup.h:50
#define QUP_MODE_MASK
Definition: qup.h:52
#define QUP_OPERATIONAL
Definition: qup.h:14
#define QUP_I2C_MI_TAG(x)
Definition: qup.h:85
#define INPUT_SERVICE_FLAG
Definition: qup.h:46
#define QUP_INPUT_FIFO
Definition: qup.h:34
#define QUP_OUTPUT_MODE_SHFT
Definition: qup.h:53
#define QUP_INPUT_MODE_SHFT
Definition: qup.h:54
#define QUP_STATE_PAUSE
Definition: qup.h:66
#define QUP_STATE_RUN
Definition: qup.h:65
@ QUP_MODE_FIFO
Definition: qup.h:126
#define QUP_I2C_INVALID_WRITE
Definition: qup.h:97
#define OUTPUT_FIFO_NOT_EMPTY
Definition: qup.h:45
#define QUP_I2C_START_SEQ
Definition: qup.h:73
#define QUP_CONFIG
Definition: qup.h:9
#define QUP_STATE_MASK
Definition: qup.h:68
#define QUP_I2C_ADDR(x)
Definition: qup.h:83
qup_return_t qup_recv_data(blsp_qup_id_t id, qup_data_t *p_rx_obj)
Definition: qup.c:533
qup_return_t qup_set_state(blsp_qup_id_t id, uint32_t state)
Definition: qup.c:450
qup_return_t qup_send_data(blsp_qup_id_t id, qup_data_t *p_tx_obj, uint8_t stop_seq)
Definition: qup.c:494
qup_return_t qup_reset_i2c_master_status(blsp_qup_id_t id)
Definition: qup.c:79
qup_return_t qup_init(blsp_qup_id_t id, const qup_config_t *config_ptr)
Definition: qup.c:380
static qup_return_t qup_fifo_wait_for(gsbi_id_t gsbi_id, uint32_t status, struct stopwatch *timeout)
Definition: qup.c:91
static qup_return_t qup_i2c_read_fifo(gsbi_id_t gsbi_id, qup_data_t *p_tx_obj)
Definition: qup.c:200
static qup_return_t qup_i2c_write_fifo(gsbi_id_t gsbi_id, qup_data_t *p_tx_obj, uint8_t stop_seq)
Definition: qup.c:123
static qup_return_t qup_wait_for_state(gsbi_id_t gsbi_id, unsigned int wait_for)
Definition: qup.c:67
static qup_return_t qup_reset_master_status(gsbi_id_t gsbi_id)
Definition: qup.c:83
#define TIMEOUT_CNT
Definition: qup.c:10
static qup_return_t qup_i2c_send_data(gsbi_id_t gsbi_id, qup_data_t *p_tx_obj, uint8_t stop_seq)
Definition: qup.c:376
#define QUP_ADDR(gsbi_num, reg)
Definition: qup.c:23
static qup_return_t qup_i2c_write(gsbi_id_t gsbi_id, uint8_t mode, qup_data_t *p_tx_obj, uint8_t stop_seq)
Definition: qup.c:179
static int check_bit_state(uint32_t *reg, int wait_for)
Definition: qup.c:49
static qup_return_t qup_fifo_wait_while(gsbi_id_t gsbi_id, uint32_t status, struct stopwatch *timeout)
Definition: qup.c:107
static unsigned int gsbi_qup_base[]
Definition: qup.c:13
static qup_return_t qup_i2c_read(gsbi_id_t gsbi_id, uint8_t mode, qup_data_t *p_tx_obj)
Definition: qup.c:268
static qup_return_t qup_i2c_recv_data(gsbi_id_t gsbi_id, qup_data_t *p_rx_obj)
Definition: qup.c:415
static qup_return_t qup_i2c_master_status(gsbi_id_t gsbi_id)
Definition: qup.c:25
#define BIOS_DEBUG
BIOS_DEBUG - Verbose output.
Definition: loglevel.h:128
#define BIOS_ERR
BIOS_ERR - System in incomplete state.
Definition: loglevel.h:72
state
Definition: raminit.c:1787
#define GSBI_QUP2_BASE
Definition: iomap.h:98
#define GSBI_QUP6_BASE
Definition: iomap.h:102
#define GSBI_QUP5_BASE
Definition: iomap.h:101
#define GSBI_QUP4_BASE
Definition: iomap.h:100
#define GSBI_QUP3_BASE
Definition: iomap.h:99
#define GSBI_QUP7_BASE
Definition: iomap.h:103
#define GSBI_QUP1_BASE
Definition: iomap.h:97
unsigned int uint32_t
Definition: stdint.h:14
unsigned char uint8_t
Definition: stdint.h:8
qup_protocol_t protocol
Definition: qup.h:132
unsigned int src_frequency
Definition: qup.h:134
qup_mode_t mode
Definition: qup.h:135
unsigned int clk_frequency
Definition: qup.h:133
struct qup_data_t::@1401::@1402 iic
qup_protocol_t protocol
Definition: qup.h:140
union qup_data_t::@1401 p
void udelay(uint32_t us)
Definition: udelay.c:15
#define count