blob: 0a834f172067bb13130808f009beafc7f992944b [file] [log] [blame]
Shashank Mittalc69512e2010-09-22 16:40:48 -07001/* Copyright (c) 2010, Code Aurora Forum. All rights reserved.
2 *
3 * Redistribution and use in source and binary forms, with or without
4 * modification, are permitted provided that the following conditions are
5 * met:
6 * * Redistributions of source code must retain the above copyright
7 * notice, this list of conditions and the following disclaimer.
8 * * Redistributions in binary form must reproduce the above
9 * copyright notice, this list of conditions and the following
10 * disclaimer in the documentation and/or other materials provided
11 * with the distribution.
12 * * Neither the name of Code Aurora Forum, Inc. nor the names of its
13 * contributors may be used to endorse or promote products derived
14 * from this software without specific prior written permission.
15 *
16 * THIS SOFTWARE IS PROVIDED "AS IS" AND ANY EXPRESS OR IMPLIED
17 * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
18 * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT
19 * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS
20 * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
21 * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
22 * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR
23 * BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
24 * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE
25 * OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN
26 * IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
27 */
28
29/*
30 * QUP driver for Qualcomm MSM platforms
31 *
32 */
33
34#include <debug.h>
35#include <arch/arm.h>
36#include <reg.h>
37#include <kernel/thread.h>
Greg Griscod2471ef2011-07-14 13:00:42 -070038#include <dev/gpio.h>
39#include <stdlib.h>
40#include <string.h>
Shashank Mittalc69512e2010-09-22 16:40:48 -070041
Amol Jadic52c8a32011-07-12 11:27:04 -070042#include <gsbi.h>
Shashank Mittalc69512e2010-09-22 16:40:48 -070043#include <i2c_qup.h>
44#include <platform/irqs.h>
45#include <platform/iomap.h>
Amol Jadic52c8a32011-07-12 11:27:04 -070046#include <platform/gpio.h>
47#include <platform/clock.h>
Greg Griscod2471ef2011-07-14 13:00:42 -070048#include <platform/timer.h>
49#include <platform/interrupts.h>
50
Shashank Mittalc69512e2010-09-22 16:40:48 -070051static struct qup_i2c_dev *dev_addr = NULL;
52
53/* QUP Registers */
54enum {
Ajay Dudanib01e5062011-12-03 23:23:42 -080055 QUP_CONFIG = 0x0,
56 QUP_STATE = 0x4,
57 QUP_IO_MODE = 0x8,
58 QUP_SW_RESET = 0xC,
59 QUP_OPERATIONAL = 0x18,
60 QUP_ERROR_FLAGS = 0x1C,
61 QUP_ERROR_FLAGS_EN = 0x20,
62 QUP_MX_READ_CNT = 0x208,
63 QUP_MX_INPUT_CNT = 0x200,
64 QUP_MX_WR_CNT = 0x100,
65 QUP_OUT_DEBUG = 0x108,
66 QUP_OUT_FIFO_CNT = 0x10C,
67 QUP_OUT_FIFO_BASE = 0x110,
68 QUP_IN_READ_CUR = 0x20C,
69 QUP_IN_DEBUG = 0x210,
70 QUP_IN_FIFO_CNT = 0x214,
71 QUP_IN_FIFO_BASE = 0x218,
72 QUP_I2C_CLK_CTL = 0x400,
73 QUP_I2C_STATUS = 0x404,
Shashank Mittalc69512e2010-09-22 16:40:48 -070074};
75
76/* QUP States and reset values */
77enum {
Ajay Dudanib01e5062011-12-03 23:23:42 -080078 QUP_RESET_STATE = 0,
79 QUP_RUN_STATE = 1U,
80 QUP_STATE_MASK = 3U,
81 QUP_PAUSE_STATE = 3U,
82 QUP_STATE_VALID = 1U << 2,
83 QUP_I2C_MAST_GEN = 1U << 4,
84 QUP_OPERATIONAL_RESET = 0xFF0,
85 QUP_I2C_STATUS_RESET = 0xFFFFFC,
Shashank Mittalc69512e2010-09-22 16:40:48 -070086};
87
88/* QUP OPERATIONAL FLAGS */
89enum {
Ajay Dudanib01e5062011-12-03 23:23:42 -080090 QUP_OUT_SVC_FLAG = 1U << 8,
91 QUP_IN_SVC_FLAG = 1U << 9,
92 QUP_MX_INPUT_DONE = 1U << 11,
Shashank Mittalc69512e2010-09-22 16:40:48 -070093};
94
95/* I2C mini core related values */
96enum {
Ajay Dudanib01e5062011-12-03 23:23:42 -080097 I2C_MINI_CORE = 2U << 8,
98 I2C_N_VAL = 0xF,
Shashank Mittalc69512e2010-09-22 16:40:48 -070099
100};
101
102/* Packing Unpacking words in FIFOs , and IO modes*/
103enum {
Ajay Dudanib01e5062011-12-03 23:23:42 -0800104 QUP_WR_BLK_MODE = 1U << 10,
105 QUP_RD_BLK_MODE = 1U << 12,
106 QUP_UNPACK_EN = 1U << 14,
107 QUP_PACK_EN = 1U << 15,
Shashank Mittalc69512e2010-09-22 16:40:48 -0700108};
109
110/* QUP tags */
111enum {
Ajay Dudanib01e5062011-12-03 23:23:42 -0800112 QUP_OUT_NOP = 0,
113 QUP_OUT_START = 1U << 8,
114 QUP_OUT_DATA = 2U << 8,
115 QUP_OUT_STOP = 3U << 8,
116 QUP_OUT_REC = 4U << 8,
117 QUP_IN_DATA = 5U << 8,
118 QUP_IN_STOP = 6U << 8,
119 QUP_IN_NACK = 7U << 8,
Shashank Mittalc69512e2010-09-22 16:40:48 -0700120};
121
122/* Status, Error flags */
123enum {
Ajay Dudanib01e5062011-12-03 23:23:42 -0800124 I2C_STATUS_WR_BUFFER_FULL = 1U << 0,
125 I2C_STATUS_BUS_ACTIVE = 1U << 8,
126 I2C_STATUS_ERROR_MASK = 0x38000FC,
127 QUP_I2C_NACK_FLAG = 1U << 3,
128 QUP_IN_NOT_EMPTY = 1U << 5,
129 QUP_STATUS_ERROR_FLAGS = 0x7C,
Shashank Mittalc69512e2010-09-22 16:40:48 -0700130};
131
Subbaraman Narayanamurthydcc8e932011-05-25 18:13:37 -0700132#ifdef DEBUG_QUP
Shashank Mittalc69512e2010-09-22 16:40:48 -0700133static void qup_print_status(struct qup_i2c_dev *dev)
134{
Ajay Dudanib01e5062011-12-03 23:23:42 -0800135 unsigned val;
136 val = readl(dev->qup_base + QUP_CONFIG);
137 dprintf(INFO, "Qup config is :0x%x\n", val);
138 val = readl(dev->qup_base + QUP_STATE);
139 dprintf(INFO, "Qup state is :0x%x\n", val);
140 val = readl(dev->qup_base + QUP_IO_MODE);
141 dprintf(INFO, "Qup mode is :0x%x\n", val);
Shashank Mittalc69512e2010-09-22 16:40:48 -0700142}
143#else
144static inline void qup_print_status(struct qup_i2c_dev *dev)
145{
146}
147#endif
148
Shashank Mittalc69512e2010-09-22 16:40:48 -0700149static irqreturn_t qup_i2c_interrupt(void)
150{
Ajay Dudanib01e5062011-12-03 23:23:42 -0800151 struct qup_i2c_dev *dev = dev_addr;
152 if (!dev) {
153 dprintf(CRITICAL,
154 "dev_addr is NULL, that means i2c_qup_init failed...\n");
155 return IRQ_FAIL;
156 }
157 unsigned status = readl(dev->qup_base + QUP_I2C_STATUS);
158 unsigned status1 = readl(dev->qup_base + QUP_ERROR_FLAGS);
159 unsigned op_flgs = readl(dev->qup_base + QUP_OPERATIONAL);
160 int err = 0;
Shashank Mittalc69512e2010-09-22 16:40:48 -0700161
Ajay Dudanib01e5062011-12-03 23:23:42 -0800162 if (!dev->msg)
163 return IRQ_HANDLED;
Shashank Mittalc69512e2010-09-22 16:40:48 -0700164
Ajay Dudanib01e5062011-12-03 23:23:42 -0800165 if (status & I2C_STATUS_ERROR_MASK) {
166 dprintf(CRITICAL, "QUP: I2C status flags :0x%x \n", status);
167 err = -status;
168 /* Clear Error interrupt if it's a level triggered interrupt */
169 if (dev->num_irqs == 1) {
170 writel(QUP_RESET_STATE, dev->qup_base + QUP_STATE);
171 }
172 goto intr_done;
173 }
Shashank Mittalc69512e2010-09-22 16:40:48 -0700174
Ajay Dudanib01e5062011-12-03 23:23:42 -0800175 if (status1 & 0x7F) {
176 dprintf(CRITICAL, "QUP: QUP status flags :0x%x\n", status1);
177 err = -status1;
178 /* Clear Error interrupt if it's a level triggered interrupt */
179 if (dev->num_irqs == 1)
180 writel((status1 & QUP_STATUS_ERROR_FLAGS),
181 dev->qup_base + QUP_ERROR_FLAGS);
182 goto intr_done;
183 }
Shashank Mittalc69512e2010-09-22 16:40:48 -0700184
Ajay Dudanib01e5062011-12-03 23:23:42 -0800185 if (op_flgs & QUP_OUT_SVC_FLAG)
186 writel(QUP_OUT_SVC_FLAG, dev->qup_base + QUP_OPERATIONAL);
187 if (dev->msg->flags == I2C_M_RD) {
188 if ((op_flgs & QUP_MX_INPUT_DONE)
189 || (op_flgs & QUP_IN_SVC_FLAG))
190 writel(QUP_IN_SVC_FLAG,
191 dev->qup_base + QUP_OPERATIONAL);
192 else
193 return IRQ_HANDLED;
194 }
Shashank Mittalc69512e2010-09-22 16:40:48 -0700195
Ajay Dudanib01e5062011-12-03 23:23:42 -0800196 intr_done:
197 dev->err = err;
198 return IRQ_HANDLED;
Shashank Mittalc69512e2010-09-22 16:40:48 -0700199}
200
201static int qup_i2c_poll_writeready(struct qup_i2c_dev *dev)
202{
Ajay Dudanib01e5062011-12-03 23:23:42 -0800203 unsigned retries = 0;
Shashank Mittalc69512e2010-09-22 16:40:48 -0700204
Ajay Dudanib01e5062011-12-03 23:23:42 -0800205 while (retries != 2000) {
206 unsigned status = readl(dev->qup_base + QUP_I2C_STATUS);
Shashank Mittalc69512e2010-09-22 16:40:48 -0700207
Ajay Dudanib01e5062011-12-03 23:23:42 -0800208 if (!(status & I2C_STATUS_WR_BUFFER_FULL)) {
209 if (!(status & I2C_STATUS_BUS_ACTIVE))
210 return 0;
211 else /* 1-bit delay before we check for bus busy */
212 udelay(dev->one_bit_t);
213 }
214 if (retries++ == 1000)
215 udelay(100);
216 }
217 qup_print_status(dev);
218 return -ETIMEDOUT;
Shashank Mittalc69512e2010-09-22 16:40:48 -0700219}
220
221static int qup_i2c_poll_state(struct qup_i2c_dev *dev, unsigned state)
222{
Ajay Dudanib01e5062011-12-03 23:23:42 -0800223 unsigned retries = 0;
Shashank Mittalc69512e2010-09-22 16:40:48 -0700224
Ajay Dudanib01e5062011-12-03 23:23:42 -0800225 dprintf(INFO, "Polling Status for state:0x%x\n", state);
Shashank Mittalc69512e2010-09-22 16:40:48 -0700226
Ajay Dudanib01e5062011-12-03 23:23:42 -0800227 while (retries != 2000) {
228 unsigned status = readl(dev->qup_base + QUP_STATE);
Shashank Mittalc69512e2010-09-22 16:40:48 -0700229
Ajay Dudanib01e5062011-12-03 23:23:42 -0800230 if ((status & (QUP_STATE_VALID | state)) ==
231 (QUP_STATE_VALID | state))
232 return 0;
233 else if (retries++ == 1000)
234 udelay(100);
235 }
236 return -ETIMEDOUT;
Shashank Mittalc69512e2010-09-22 16:40:48 -0700237}
238
239#ifdef DEBUG
Ajay Dudanib01e5062011-12-03 23:23:42 -0800240static void
241qup_verify_fifo(struct qup_i2c_dev *dev, unsigned val, unsigned addr, int rdwr)
Shashank Mittalc69512e2010-09-22 16:40:48 -0700242{
Ajay Dudanib01e5062011-12-03 23:23:42 -0800243 if (rdwr)
244 dprintf(INFO, "RD:Wrote 0x%x to out_ff:0x%x\n", val, addr);
245 else
246 dprintf(INFO, "WR:Wrote 0x%x to out_ff:0x%x\n", val, addr);
Shashank Mittalc69512e2010-09-22 16:40:48 -0700247}
248#else
Ajay Dudanib01e5062011-12-03 23:23:42 -0800249static inline void
250qup_verify_fifo(struct qup_i2c_dev *dev, unsigned val, unsigned addr, int rdwr)
Shashank Mittalc69512e2010-09-22 16:40:48 -0700251{
252}
253#endif
254
255static void
256qup_issue_read(struct qup_i2c_dev *dev, struct i2c_msg *msg, int *idx,
Ajay Dudanib01e5062011-12-03 23:23:42 -0800257 unsigned carry_over)
Shashank Mittalc69512e2010-09-22 16:40:48 -0700258{
Ajay Dudanib01e5062011-12-03 23:23:42 -0800259 uint16_t addr = (msg->addr << 1) | 1;
260 /* QUP limit 256 bytes per read. By HW design, 0 in the 8-bit field is
261 treated as 256 byte read. */
262 uint16_t rd_len = ((dev->cnt == 256) ? 0 : dev->cnt);
Shashank Mittalc69512e2010-09-22 16:40:48 -0700263
Ajay Dudanib01e5062011-12-03 23:23:42 -0800264 if (*idx % 4) {
265 writel(carry_over | ((QUP_OUT_START | addr) << 16),
266 dev->qup_base + QUP_OUT_FIFO_BASE);
Shashank Mittalc69512e2010-09-22 16:40:48 -0700267
Ajay Dudanib01e5062011-12-03 23:23:42 -0800268 qup_verify_fifo(dev, carry_over |
269 ((QUP_OUT_START | addr) << 16),
270 (unsigned)dev->qup_base + QUP_OUT_FIFO_BASE +
271 (*idx - 2), 1);
272 writel((QUP_OUT_REC | rd_len),
273 dev->qup_base + QUP_OUT_FIFO_BASE);
Shashank Mittalc69512e2010-09-22 16:40:48 -0700274
Ajay Dudanib01e5062011-12-03 23:23:42 -0800275 qup_verify_fifo(dev, (QUP_OUT_REC | rd_len),
276 (unsigned)dev->qup_base + QUP_OUT_FIFO_BASE +
277 (*idx + 2), 1);
278 } else {
279 writel(((QUP_OUT_REC | rd_len) << 16) |
280 QUP_OUT_START | addr, dev->qup_base + QUP_OUT_FIFO_BASE);
Shashank Mittalc69512e2010-09-22 16:40:48 -0700281
Ajay Dudanib01e5062011-12-03 23:23:42 -0800282 qup_verify_fifo(dev, QUP_OUT_REC << 16 | rd_len << 16 |
283 QUP_OUT_START | addr,
284 (unsigned)dev->qup_base + QUP_OUT_FIFO_BASE +
285 (*idx), 1);
286 }
287 *idx += 4;
Shashank Mittalc69512e2010-09-22 16:40:48 -0700288}
289
290static void
291qup_issue_write(struct qup_i2c_dev *dev, struct i2c_msg *msg, int rem,
Ajay Dudanib01e5062011-12-03 23:23:42 -0800292 int *idx, unsigned *carry_over)
Shashank Mittalc69512e2010-09-22 16:40:48 -0700293{
Ajay Dudanib01e5062011-12-03 23:23:42 -0800294 int entries = dev->cnt;
295 int empty_sl = dev->wr_sz - ((*idx) >> 1);
296 int i = 0;
297 unsigned val = 0;
298 unsigned last_entry = 0;
299 uint16_t addr = msg->addr << 1;
Shashank Mittalc69512e2010-09-22 16:40:48 -0700300
Ajay Dudanib01e5062011-12-03 23:23:42 -0800301 if (dev->pos == 0) {
302 if (*idx % 4) {
303 writel(*carry_over | ((QUP_OUT_START | addr) << 16),
304 dev->qup_base + QUP_OUT_FIFO_BASE);
Shashank Mittalc69512e2010-09-22 16:40:48 -0700305
Ajay Dudanib01e5062011-12-03 23:23:42 -0800306 qup_verify_fifo(dev, *carry_over | QUP_OUT_DATA << 16 |
307 addr << 16, (unsigned)dev->qup_base +
308 QUP_OUT_FIFO_BASE + (*idx) - 2, 0);
309 } else
310 val = QUP_OUT_START | addr;
311 *idx += 2;
312 i++;
313 entries++;
314 } else {
315 /* Avoid setp time issue by adding 1 NOP when number of bytes are more
316 than FIFO/BLOCK size. setup time issue can't appear otherwise since
317 next byte to be written will always be ready */
318 val = (QUP_OUT_NOP | 1);
319 *idx += 2;
320 i++;
321 entries++;
322 }
323 if (entries > empty_sl)
324 entries = empty_sl;
Shashank Mittalc69512e2010-09-22 16:40:48 -0700325
Ajay Dudanib01e5062011-12-03 23:23:42 -0800326 for (; i < (entries - 1); i++) {
327 if (*idx % 4) {
328 writel(val | ((QUP_OUT_DATA |
329 msg->buf[dev->pos]) << 16),
330 dev->qup_base + QUP_OUT_FIFO_BASE);
Shashank Mittalc69512e2010-09-22 16:40:48 -0700331
Ajay Dudanib01e5062011-12-03 23:23:42 -0800332 qup_verify_fifo(dev, val | QUP_OUT_DATA << 16 |
333 msg->buf[dev->pos] << 16,
334 (unsigned)dev->qup_base +
335 QUP_OUT_FIFO_BASE + (*idx) - 2, 0);
336 } else
337 val = QUP_OUT_DATA | msg->buf[dev->pos];
338 (*idx) += 2;
339 dev->pos++;
340 }
341 if (dev->pos < (msg->len - 1))
342 last_entry = QUP_OUT_DATA;
343 else if (rem > 1) /* not last array entry */
344 last_entry = QUP_OUT_DATA;
345 else
346 last_entry = QUP_OUT_STOP;
347 if ((*idx % 4) == 0) {
348 /*
349 * If read-start and read-command end up in different fifos, it
350 * may result in extra-byte being read due to extra-read cycle.
351 * Avoid that by inserting NOP as the last entry of fifo only
352 * if write command(s) leave 1 space in fifo.
353 */
354 if (rem > 1) {
355 struct i2c_msg *next = msg + 1;
Amol Jadi34a21952012-04-26 15:25:22 -0700356 if (next->addr == msg->addr && (next->flags & I2C_M_RD)
Ajay Dudanib01e5062011-12-03 23:23:42 -0800357 && *idx == ((dev->wr_sz * 2) - 4)) {
358 writel(((last_entry | msg->buf[dev->pos]) |
359 ((1 | QUP_OUT_NOP) << 16)),
360 dev->qup_base + QUP_OUT_FIFO_BASE);
361 *idx += 2;
362 } else
363 *carry_over = (last_entry | msg->buf[dev->pos]);
364 } else {
365 writel((last_entry | msg->buf[dev->pos]),
366 dev->qup_base + QUP_OUT_FIFO_BASE);
Shashank Mittalc69512e2010-09-22 16:40:48 -0700367
Ajay Dudanib01e5062011-12-03 23:23:42 -0800368 qup_verify_fifo(dev, last_entry | msg->buf[dev->pos],
369 (unsigned)dev->qup_base +
370 QUP_OUT_FIFO_BASE + (*idx), 0);
371 }
372 } else {
373 writel(val | ((last_entry | msg->buf[dev->pos]) << 16),
374 dev->qup_base + QUP_OUT_FIFO_BASE);
Shashank Mittalc69512e2010-09-22 16:40:48 -0700375
Ajay Dudanib01e5062011-12-03 23:23:42 -0800376 qup_verify_fifo(dev, val | (last_entry << 16) |
377 (msg->buf[dev->pos] << 16),
378 (unsigned)dev->qup_base + QUP_OUT_FIFO_BASE +
379 (*idx) - 2, 0);
380 }
Shashank Mittalc69512e2010-09-22 16:40:48 -0700381
Ajay Dudanib01e5062011-12-03 23:23:42 -0800382 *idx += 2;
383 dev->pos++;
384 dev->cnt = msg->len - dev->pos;
Shashank Mittalc69512e2010-09-22 16:40:48 -0700385}
386
387static int qup_update_state(struct qup_i2c_dev *dev, unsigned state)
388{
Ajay Dudanib01e5062011-12-03 23:23:42 -0800389 if (qup_i2c_poll_state(dev, 0) != 0)
390 return -EIO;
391 writel(state, dev->qup_base + QUP_STATE);
392 if (qup_i2c_poll_state(dev, state) != 0)
393 return -EIO;
394 return 0;
Shashank Mittalc69512e2010-09-22 16:40:48 -0700395}
396
397static int qup_set_read_mode(struct qup_i2c_dev *dev, int rd_len)
398{
Ajay Dudanib01e5062011-12-03 23:23:42 -0800399 unsigned wr_mode =
400 (dev->wr_sz < dev->out_fifo_sz) ? QUP_WR_BLK_MODE : 0;
401 if (rd_len > 256) {
402 dprintf(INFO, "HW doesn't support READs > 256 bytes\n");
403 return -EPROTONOSUPPORT;
404 }
405 if (rd_len <= dev->in_fifo_sz) {
406 writel(wr_mode | QUP_PACK_EN | QUP_UNPACK_EN,
407 dev->qup_base + QUP_IO_MODE);
408 writel(rd_len, dev->qup_base + QUP_MX_READ_CNT);
409 } else {
410 writel(wr_mode | QUP_RD_BLK_MODE |
411 QUP_PACK_EN | QUP_UNPACK_EN,
412 dev->qup_base + QUP_IO_MODE);
413 writel(rd_len, dev->qup_base + QUP_MX_INPUT_CNT);
414 }
415 return 0;
Shashank Mittalc69512e2010-09-22 16:40:48 -0700416}
417
418static int qup_set_wr_mode(struct qup_i2c_dev *dev, int rem)
419{
Ajay Dudanib01e5062011-12-03 23:23:42 -0800420 int total_len = 0;
421 int ret = 0;
422 if (dev->msg->len >= (dev->out_fifo_sz - 1)) {
423 total_len =
424 dev->msg->len + 1 + (dev->msg->len / (dev->out_blk_sz - 1));
425 writel(QUP_WR_BLK_MODE | QUP_PACK_EN | QUP_UNPACK_EN,
426 dev->qup_base + QUP_IO_MODE);
427 dev->wr_sz = dev->out_blk_sz;
428 } else
429 writel(QUP_PACK_EN | QUP_UNPACK_EN,
430 dev->qup_base + QUP_IO_MODE);
Shashank Mittalc69512e2010-09-22 16:40:48 -0700431
Ajay Dudanib01e5062011-12-03 23:23:42 -0800432 if (rem > 1) {
433 struct i2c_msg *next = dev->msg + 1;
434 if (next->addr == dev->msg->addr && next->flags == I2C_M_RD) {
435 ret = qup_set_read_mode(dev, next->len);
436 /* make sure read start & read command are in 1 blk */
437 if ((total_len % dev->out_blk_sz) ==
438 (dev->out_blk_sz - 1))
439 total_len += 3;
440 else
441 total_len += 2;
442 }
443 }
444 /* WRITE COUNT register valid/used only in block mode */
445 if (dev->wr_sz == dev->out_blk_sz)
446 writel(total_len, dev->qup_base + QUP_MX_WR_CNT);
447 return ret;
Shashank Mittalc69512e2010-09-22 16:40:48 -0700448}
449
450int qup_i2c_xfer(struct qup_i2c_dev *dev, struct i2c_msg msgs[], int num)
451{
Ajay Dudanib01e5062011-12-03 23:23:42 -0800452 int ret;
453 int rem = num;
454 int err;
Shashank Mittalc69512e2010-09-22 16:40:48 -0700455
Ajay Dudanib01e5062011-12-03 23:23:42 -0800456 if (dev->suspended) {
457 return -EIO;
458 }
Shashank Mittalc69512e2010-09-22 16:40:48 -0700459
Ajay Dudanib01e5062011-12-03 23:23:42 -0800460 /* Set the GSBIn_QUP_APPS_CLK to 24MHz, then below figure out what speed to
461 run I2C_MASTER_CORE at. */
462 if (dev->clk_state == 0) {
463 if (dev->clk_ctl == 0) {
464 clock_config_i2c(dev->gsbi_number, dev->src_clk_freq);
465 }
466 }
467 /* Initialize QUP registers during first transfer */
468 if (dev->clk_ctl == 0) {
469 int fs_div;
470 int hs_div;
471 unsigned fifo_reg;
472 /* Configure the GSBI Protocol Code for i2c */
473 writel((GSBI_PROTOCOL_CODE_I2C <<
474 GSBI_CTRL_REG_PROTOCOL_CODE_S),
475 GSBI_CTRL_REG(dev->gsbi_base));
Shashank Mittalc69512e2010-09-22 16:40:48 -0700476
Ajay Dudanib01e5062011-12-03 23:23:42 -0800477 fs_div = ((dev->src_clk_freq / dev->clk_freq) / 2) - 3;
478 hs_div = 3;
479 dev->clk_ctl = ((hs_div & 0x7) << 8) | (fs_div & 0xff);
480 fifo_reg = readl(dev->qup_base + QUP_IO_MODE);
481 if (fifo_reg & 0x3)
482 dev->out_blk_sz = (fifo_reg & 0x3) * 16;
483 else
484 dev->out_blk_sz = 16;
485 if (fifo_reg & 0x60)
486 dev->in_blk_sz = ((fifo_reg & 0x60) >> 5) * 16;
487 else
488 dev->in_blk_sz = 16;
489 /*
490 * The block/fifo size w.r.t. 'actual data' is 1/2 due to 'tag'
491 * associated with each byte written/received
492 */
493 dev->out_blk_sz /= 2;
494 dev->in_blk_sz /= 2;
495 dev->out_fifo_sz =
496 dev->out_blk_sz * (2 << ((fifo_reg & 0x1C) >> 2));
497 dev->in_fifo_sz =
498 dev->in_blk_sz * (2 << ((fifo_reg & 0x380) >> 7));
499 dprintf(INFO, "QUP IN:bl:%d, ff:%d, OUT:bl:%d, ff:%d\n",
500 dev->in_blk_sz, dev->in_fifo_sz, dev->out_blk_sz,
501 dev->out_fifo_sz);
502 }
Shashank Mittalc69512e2010-09-22 16:40:48 -0700503
Ajay Dudanib01e5062011-12-03 23:23:42 -0800504 unmask_interrupt(dev->qup_irq);
505 writel(1, dev->qup_base + QUP_SW_RESET);
506 ret = qup_i2c_poll_state(dev, QUP_RESET_STATE);
507 if (ret) {
508 dprintf(INFO, "QUP Busy:Trying to recover\n");
509 goto out_err;
510 }
Shashank Mittalc69512e2010-09-22 16:40:48 -0700511
Ajay Dudanib01e5062011-12-03 23:23:42 -0800512 /* Initialize QUP registers */
513 writel(0, dev->qup_base + QUP_CONFIG);
514 writel(QUP_OPERATIONAL_RESET, dev->qup_base + QUP_OPERATIONAL);
515 writel(QUP_STATUS_ERROR_FLAGS, dev->qup_base + QUP_ERROR_FLAGS_EN);
Shashank Mittalc69512e2010-09-22 16:40:48 -0700516
Ajay Dudanib01e5062011-12-03 23:23:42 -0800517 writel(I2C_MINI_CORE | I2C_N_VAL, dev->qup_base + QUP_CONFIG);
Shashank Mittalc69512e2010-09-22 16:40:48 -0700518
Ajay Dudanib01e5062011-12-03 23:23:42 -0800519 /* Initialize I2C mini core registers */
520 writel(0, dev->qup_base + QUP_I2C_CLK_CTL);
521 writel(QUP_I2C_STATUS_RESET, dev->qup_base + QUP_I2C_STATUS);
Shashank Mittalc69512e2010-09-22 16:40:48 -0700522
Ajay Dudanib01e5062011-12-03 23:23:42 -0800523 dev->cnt = msgs->len;
524 dev->pos = 0;
525 dev->msg = msgs;
526 while (rem) {
527 int filled = FALSE;
Shashank Mittalc69512e2010-09-22 16:40:48 -0700528
Ajay Dudanib01e5062011-12-03 23:23:42 -0800529 dev->wr_sz = dev->out_fifo_sz;
530 dev->err = 0;
Shashank Mittalc69512e2010-09-22 16:40:48 -0700531
Ajay Dudanib01e5062011-12-03 23:23:42 -0800532 if (qup_i2c_poll_state(dev, QUP_I2C_MAST_GEN) != 0) {
533 ret = -EIO;
534 goto out_err;
535 }
Shashank Mittalc69512e2010-09-22 16:40:48 -0700536
Ajay Dudanib01e5062011-12-03 23:23:42 -0800537 qup_print_status(dev);
538 /* HW limits Read upto 256 bytes in 1 read without stop */
539 if (dev->msg->flags & I2C_M_RD) {
540 ret = qup_set_read_mode(dev, dev->cnt);
541 if (ret != 0)
542 goto out_err;
543 } else {
544 ret = qup_set_wr_mode(dev, rem);
545 if (ret != 0)
546 goto out_err;
547 /* Don't fill block till we get interrupt */
548 if (dev->wr_sz == dev->out_blk_sz)
549 filled = TRUE;
550 }
Shashank Mittalc69512e2010-09-22 16:40:48 -0700551
Ajay Dudanib01e5062011-12-03 23:23:42 -0800552 err = qup_update_state(dev, QUP_RUN_STATE);
553 if (err < 0) {
554 ret = err;
555 goto out_err;
556 }
Shashank Mittalc69512e2010-09-22 16:40:48 -0700557
Ajay Dudanib01e5062011-12-03 23:23:42 -0800558 qup_print_status(dev);
559 writel(dev->clk_ctl, dev->qup_base + QUP_I2C_CLK_CTL);
Shashank Mittalc69512e2010-09-22 16:40:48 -0700560
Ajay Dudanib01e5062011-12-03 23:23:42 -0800561 do {
562 int idx = 0;
563 unsigned carry_over = 0;
Shashank Mittalc69512e2010-09-22 16:40:48 -0700564
Ajay Dudanib01e5062011-12-03 23:23:42 -0800565 /* Transition to PAUSE state only possible from RUN */
566 err = qup_update_state(dev, QUP_PAUSE_STATE);
567 if (err < 0) {
568 ret = err;
569 goto out_err;
570 }
Shashank Mittalc69512e2010-09-22 16:40:48 -0700571
Ajay Dudanib01e5062011-12-03 23:23:42 -0800572 qup_print_status(dev);
573 /* This operation is Write, check the next operation and decide
574 mode */
575 while (filled == FALSE) {
576 if ((msgs->flags & I2C_M_RD)
577 && (dev->cnt == msgs->len))
578 qup_issue_read(dev, msgs, &idx,
579 carry_over);
580 else if (!(msgs->flags & I2C_M_RD))
581 qup_issue_write(dev, msgs, rem, &idx,
582 &carry_over);
583 if (idx >= (dev->wr_sz << 1))
584 filled = TRUE;
585 /* Start new message */
586 if (filled == FALSE) {
587 if (msgs->flags & I2C_M_RD)
588 filled = TRUE;
589 else if (rem > 1) {
590 /* Only combine operations with same address */
591 struct i2c_msg *next = msgs + 1;
592 if (next->addr != msgs->addr
593 || next->flags == 0)
594 filled = TRUE;
595 else {
596 rem--;
597 msgs++;
598 dev->msg = msgs;
599 dev->pos = 0;
600 dev->cnt = msgs->len;
601 }
602 } else
603 filled = TRUE;
604 }
605 }
606 err = qup_update_state(dev, QUP_RUN_STATE);
607 if (err < 0) {
608 ret = err;
609 goto out_err;
610 }
611 dprintf(INFO, "idx:%d, rem:%d, num:%d, mode:%d\n",
612 idx, rem, num, dev->mode);
Shashank Mittalc69512e2010-09-22 16:40:48 -0700613
Ajay Dudanib01e5062011-12-03 23:23:42 -0800614 qup_print_status(dev);
615 if (dev->err) {
616 if (dev->err & QUP_I2C_NACK_FLAG) {
617 dprintf(CRITICAL,
618 "I2C slave addr:0x%x not connected\n",
619 dev->msg->addr);
620 } else {
621 dprintf(INFO,
622 "QUP data xfer error %d\n",
623 dev->err);
624 }
625 ret = dev->err;
626 goto out_err;
627 }
628 if (dev->msg->flags & I2C_M_RD) {
629 int i;
630 unsigned dval = 0;
631 for (i = 0; dev->pos < dev->msg->len;
632 i++, dev->pos++) {
633 unsigned rd_status =
634 readl(dev->qup_base +
635 QUP_OPERATIONAL);
636 if (i % 2 == 0) {
637 if ((rd_status &
638 QUP_IN_NOT_EMPTY) == 0)
639 break;
640 dval =
641 readl(dev->qup_base +
642 QUP_IN_FIFO_BASE);
643 dev->msg->buf[dev->pos] =
644 dval & 0xFF;
645 } else
646 dev->msg->buf[dev->pos] =
647 ((dval & 0xFF0000) >> 16);
648 }
649 dev->cnt -= i;
650 } else
651 filled = FALSE; /* refill output FIFO */
652 }
653 while (dev->cnt > 0);
654 if (dev->cnt == 0) {
655 rem--;
656 msgs++;
657 if (rem) {
658 dev->pos = 0;
659 dev->cnt = msgs->len;
660 dev->msg = msgs;
661 }
662 }
663 /* Wait for I2C bus to be idle */
664 ret = qup_i2c_poll_writeready(dev);
665 if (ret) {
666 dprintf(INFO, "Error waiting for write ready\n");
667 goto out_err;
668 }
669 }
Shashank Mittalc69512e2010-09-22 16:40:48 -0700670
Ajay Dudanib01e5062011-12-03 23:23:42 -0800671 ret = num;
672 out_err:
673 dev->msg = NULL;
674 dev->pos = 0;
675 dev->err = 0;
676 dev->cnt = 0;
677 mask_interrupt(dev->qup_irq);
678 return ret;
Shashank Mittalc69512e2010-09-22 16:40:48 -0700679}
680
Ajay Dudanib01e5062011-12-03 23:23:42 -0800681struct qup_i2c_dev *qup_i2c_init(uint8_t gsbi_id, unsigned clk_freq,
682 unsigned src_clk_freq)
Shashank Mittalc69512e2010-09-22 16:40:48 -0700683{
Ajay Dudanib01e5062011-12-03 23:23:42 -0800684 struct qup_i2c_dev *dev;
685 if (dev_addr != NULL) {
686 return dev_addr;
687 }
Shashank Mittalc69512e2010-09-22 16:40:48 -0700688
Ajay Dudanib01e5062011-12-03 23:23:42 -0800689 dev = malloc(sizeof(struct qup_i2c_dev));
690 if (!dev) {
691 return NULL;
692 }
693 dev = memset(dev, 0, sizeof(struct qup_i2c_dev));
Shashank Mittalc69512e2010-09-22 16:40:48 -0700694
Ajay Dudanib01e5062011-12-03 23:23:42 -0800695 /* Setup base addresses and irq based on gsbi_id */
696 dev->qup_irq = GSBI_QUP_IRQ(gsbi_id);
697 dev->qup_base = QUP_BASE(gsbi_id);
698 dev->gsbi_base = GSBI_BASE(gsbi_id);
699 dev->gsbi_number = gsbi_id;
Amol Jadic52c8a32011-07-12 11:27:04 -0700700
Ajay Dudanib01e5062011-12-03 23:23:42 -0800701 /* This must be done for qup_i2c_interrupt to work. */
702 dev_addr = dev;
Shashank Mittalc69512e2010-09-22 16:40:48 -0700703
Ajay Dudanib01e5062011-12-03 23:23:42 -0800704 /* Initialize the GPIO for GSBIn as i2c */
705 gpio_config_i2c(dev->gsbi_number);
Shashank Mittalc69512e2010-09-22 16:40:48 -0700706
Ajay Dudanib01e5062011-12-03 23:23:42 -0800707 /* Configure the GSBI Protocol Code for i2c */
708 writel((GSBI_PROTOCOL_CODE_I2C <<
709 GSBI_CTRL_REG_PROTOCOL_CODE_S), GSBI_CTRL_REG(dev->gsbi_base));
Shashank Mittalc69512e2010-09-22 16:40:48 -0700710
Ajay Dudanib01e5062011-12-03 23:23:42 -0800711 /* Set clk_freq and src_clk_freq for i2c. */
712 dev->clk_freq = clk_freq;
713 dev->src_clk_freq = src_clk_freq;
Shashank Mittalc69512e2010-09-22 16:40:48 -0700714
Ajay Dudanib01e5062011-12-03 23:23:42 -0800715 dev->num_irqs = 1;
Shashank Mittalc69512e2010-09-22 16:40:48 -0700716
Ajay Dudanib01e5062011-12-03 23:23:42 -0800717 dev->one_bit_t = USEC_PER_SEC / dev->clk_freq;
718 dev->clk_ctl = 0;
Shashank Mittalc69512e2010-09-22 16:40:48 -0700719
Ajay Dudanib01e5062011-12-03 23:23:42 -0800720 /* Register the GSBIn QUP IRQ */
721 register_int_handler(dev->qup_irq, (int_handler) qup_i2c_interrupt, 0);
Shashank Mittalc69512e2010-09-22 16:40:48 -0700722
Ajay Dudanib01e5062011-12-03 23:23:42 -0800723 /* Then disable it */
724 mask_interrupt(dev->qup_irq);
Shashank Mittalc69512e2010-09-22 16:40:48 -0700725
Ajay Dudanib01e5062011-12-03 23:23:42 -0800726 return dev;
Shashank Mittalc69512e2010-09-22 16:40:48 -0700727}
728
729int qup_i2c_deinit(struct qup_i2c_dev *dev)
730{
Ajay Dudanib01e5062011-12-03 23:23:42 -0800731 /* Disable the qup_irq */
732 mask_interrupt(dev->qup_irq);
733 /* Free the memory used for dev */
734 free(dev);
735 return 0;
Shashank Mittalc69512e2010-09-22 16:40:48 -0700736}