blob: 15d519a116634b9f88a5af242d5d3dd8dcabbed3 [file] [log] [blame]
Rafal Jaworowskid3a02c32007-07-27 14:43:59 +02001/*
Wolfgang Denkb8539952009-05-16 10:47:43 +02002 * (C) Copyright 2003 - 2009
Rafal Jaworowskid3a02c32007-07-27 14:43:59 +02003 * Wolfgang Denk, DENX Software Engineering, wd@denx.de.
4 *
Wolfgang Denkd79de1d2013-07-08 09:37:19 +02005 * SPDX-License-Identifier: GPL-2.0+
Rafal Jaworowskid3a02c32007-07-27 14:43:59 +02006 *
7 * Based on the MPC5xxx code.
8 */
9
10#include <common.h>
Wolfgang Denkb8539952009-05-16 10:47:43 +020011#include <asm/io.h>
Rafal Jaworowskid3a02c32007-07-27 14:43:59 +020012
13DECLARE_GLOBAL_DATA_PTR;
14
15#ifdef CONFIG_HARD_I2C
16
Rafal Jaworowskid3a02c32007-07-27 14:43:59 +020017#include <i2c.h>
18
Rafal Jaworowskid3a02c32007-07-27 14:43:59 +020019/* by default set I2C bus 0 active */
Stefan Roesee5dc3622009-06-08 09:38:07 +020020static unsigned int bus_num __attribute__ ((section (".data"))) = 0;
Rafal Jaworowskid3a02c32007-07-27 14:43:59 +020021
22#define I2C_TIMEOUT 100
23#define I2C_RETRIES 3
24
25struct mpc512x_i2c_tap {
26 int scl2tap;
27 int tap2tap;
28};
29
30static int mpc_reg_in(volatile u32 *reg);
31static void mpc_reg_out(volatile u32 *reg, int val, int mask);
32static int wait_for_bb(void);
33static int wait_for_pin(int *status);
34static int do_address(uchar chip, char rdwr_flag);
35static int send_bytes(uchar chip, char *buf, int len);
36static int receive_bytes(uchar chip, char *buf, int len);
37static int mpc_get_fdr(int);
38
39static int mpc_reg_in (volatile u32 *reg)
40{
Wolfgang Denkb8539952009-05-16 10:47:43 +020041 int ret = in_be32(reg) >> 24;
42
Rafal Jaworowskid3a02c32007-07-27 14:43:59 +020043 return ret;
44}
45
46static void mpc_reg_out (volatile u32 *reg, int val, int mask)
47{
Rafal Jaworowskid3a02c32007-07-27 14:43:59 +020048 if (!mask) {
Wolfgang Denkb8539952009-05-16 10:47:43 +020049 out_be32(reg, val << 24);
Rafal Jaworowskid3a02c32007-07-27 14:43:59 +020050 } else {
Wolfgang Denkb8539952009-05-16 10:47:43 +020051 clrsetbits_be32(reg, mask << 24, (val & mask) << 24);
Rafal Jaworowskid3a02c32007-07-27 14:43:59 +020052 }
Rafal Jaworowskid3a02c32007-07-27 14:43:59 +020053}
54
55static int wait_for_bb (void)
56{
Wolfgang Denkb8539952009-05-16 10:47:43 +020057 volatile immap_t *im = (immap_t *) CONFIG_SYS_IMMR;
58 volatile i2c512x_dev_t *regs = &im->i2c.dev[bus_num];
Rafal Jaworowskid3a02c32007-07-27 14:43:59 +020059 int timeout = I2C_TIMEOUT;
60 int status;
61
62 status = mpc_reg_in (&regs->msr);
63
64 while (timeout-- && (status & I2C_BB)) {
Rafal Jaworowskid3a02c32007-07-27 14:43:59 +020065 mpc_reg_out (&regs->mcr, I2C_STA, I2C_STA);
Anatolij Gustschinb1cbf462011-11-10 12:21:44 +000066 (void)mpc_reg_in(&regs->mdr);
Rafal Jaworowskid3a02c32007-07-27 14:43:59 +020067 mpc_reg_out (&regs->mcr, 0, I2C_STA);
68 mpc_reg_out (&regs->mcr, 0, 0);
69 mpc_reg_out (&regs->mcr, I2C_EN, 0);
70
71 udelay (1000);
72 status = mpc_reg_in (&regs->msr);
73 }
74
75 return (status & I2C_BB);
76}
77
78static int wait_for_pin (int *status)
79{
Wolfgang Denkb8539952009-05-16 10:47:43 +020080 volatile immap_t *im = (immap_t *) CONFIG_SYS_IMMR;
81 volatile i2c512x_dev_t *regs = &im->i2c.dev[bus_num];
Rafal Jaworowskid3a02c32007-07-27 14:43:59 +020082 int timeout = I2C_TIMEOUT;
83
84 *status = mpc_reg_in (&regs->msr);
85
86 while (timeout-- && !(*status & I2C_IF)) {
87 udelay (1000);
88 *status = mpc_reg_in (&regs->msr);
89 }
90
91 if (!(*status & I2C_IF)) {
92 return -1;
93 }
94
95 mpc_reg_out (&regs->msr, 0, I2C_IF);
96
97 return 0;
98}
99
100static int do_address (uchar chip, char rdwr_flag)
101{
Wolfgang Denkb8539952009-05-16 10:47:43 +0200102 volatile immap_t *im = (immap_t *) CONFIG_SYS_IMMR;
103 volatile i2c512x_dev_t *regs = &im->i2c.dev[bus_num];
Rafal Jaworowskid3a02c32007-07-27 14:43:59 +0200104 int status;
105
106 chip <<= 1;
107
108 if (rdwr_flag) {
109 chip |= 1;
110 }
111
112 mpc_reg_out (&regs->mcr, I2C_TX, I2C_TX);
113 mpc_reg_out (&regs->mdr, chip, 0);
114
115 if (wait_for_pin (&status)) {
116 return -2;
117 }
118
119 if (status & I2C_RXAK) {
120 return -3;
121 }
122
123 return 0;
124}
125
126static int send_bytes (uchar chip, char *buf, int len)
127{
Wolfgang Denkb8539952009-05-16 10:47:43 +0200128 volatile immap_t *im = (immap_t *) CONFIG_SYS_IMMR;
129 volatile i2c512x_dev_t *regs = &im->i2c.dev[bus_num];
Rafal Jaworowskid3a02c32007-07-27 14:43:59 +0200130 int wrcount;
131 int status;
132
133 for (wrcount = 0; wrcount < len; ++wrcount) {
134
135 mpc_reg_out (&regs->mdr, buf[wrcount], 0);
136
137 if (wait_for_pin (&status)) {
138 break;
139 }
140
141 if (status & I2C_RXAK) {
142 break;
143 }
144
145 }
146
147 return !(wrcount == len);
148}
149
150static int receive_bytes (uchar chip, char *buf, int len)
151{
Wolfgang Denkb8539952009-05-16 10:47:43 +0200152 volatile immap_t *im = (immap_t *) CONFIG_SYS_IMMR;
153 volatile i2c512x_dev_t *regs = &im->i2c.dev[bus_num];
Rafal Jaworowskid3a02c32007-07-27 14:43:59 +0200154 int dummy = 1;
155 int rdcount = 0;
156 int status;
157 int i;
158
159 mpc_reg_out (&regs->mcr, 0, I2C_TX);
160
161 for (i = 0; i < len; ++i) {
162 buf[rdcount] = mpc_reg_in (&regs->mdr);
163
164 if (dummy) {
165 dummy = 0;
166 } else {
167 rdcount++;
168 }
169
170 if (wait_for_pin (&status)) {
171 return -4;
172 }
173 }
174
175 mpc_reg_out (&regs->mcr, I2C_TXAK, I2C_TXAK);
176 buf[rdcount++] = mpc_reg_in (&regs->mdr);
177
178 if (wait_for_pin (&status)) {
179 return -5;
180 }
181
182 mpc_reg_out (&regs->mcr, 0, I2C_TXAK);
183
184 return 0;
185}
186
187/**************** I2C API ****************/
188
189void i2c_init (int speed, int saddr)
190{
Wolfgang Denkb8539952009-05-16 10:47:43 +0200191 volatile immap_t *im = (immap_t *) CONFIG_SYS_IMMR;
Rafal Jaworowskid3a02c32007-07-27 14:43:59 +0200192 int i;
Wolfgang Denkb8539952009-05-16 10:47:43 +0200193
194 for (i = 0; i < I2C_BUS_CNT; i++){
195 volatile i2c512x_dev_t *regs = &im->i2c.dev[i];
196
Rafal Jaworowskid3a02c32007-07-27 14:43:59 +0200197 mpc_reg_out (&regs->mcr, 0, 0);
198
199 /* Set clock */
200 mpc_reg_out (&regs->mfdr, mpc_get_fdr (speed), 0);
201 mpc_reg_out (&regs->madr, saddr << 1, 0);
202
203 /* Enable module */
204 mpc_reg_out (&regs->mcr, I2C_EN, I2C_INIT_MASK);
205 mpc_reg_out (&regs->msr, 0, I2C_IF);
206 }
207
208 /* Disable interrupts */
Wolfgang Denkb8539952009-05-16 10:47:43 +0200209 out_be32(&im->i2c.icr, 0);
210
Rafal Jaworowskid3a02c32007-07-27 14:43:59 +0200211 /* Turn off filters */
Wolfgang Denkb8539952009-05-16 10:47:43 +0200212 out_be32(&im->i2c.mifr, 0);
Rafal Jaworowskid3a02c32007-07-27 14:43:59 +0200213}
214
215static int mpc_get_fdr (int speed)
216{
217 static int fdr = -1;
218
219 if (fdr == -1) {
220 ulong best_speed = 0;
221 ulong divider;
Grzegorz Bernacki21305af2008-01-11 12:03:43 +0100222 ulong ips, scl;
Rafal Jaworowskid3a02c32007-07-27 14:43:59 +0200223 ulong bestmatch = 0xffffffffUL;
224 int best_i = 0, best_j = 0, i, j;
225 int SCL_Tap[] = { 9, 10, 12, 15, 5, 6, 7, 8};
226 struct mpc512x_i2c_tap scltap[] = {
227 {4, 1},
228 {4, 2},
229 {6, 4},
230 {6, 8},
231 {14, 16},
232 {30, 32},
233 {62, 64},
234 {126, 128}
235 };
236
Simon Glass6c6cbd12012-12-13 20:48:54 +0000237 ips = gd->arch.ips_clk;
Rafal Jaworowskid3a02c32007-07-27 14:43:59 +0200238 for (i = 7; i >= 0; i--) {
239 for (j = 7; j >= 0; j--) {
240 scl = 2 * (scltap[j].scl2tap +
241 (SCL_Tap[i] - 1) * scltap[j].tap2tap
242 + 2);
Grzegorz Bernacki21305af2008-01-11 12:03:43 +0100243 if (ips <= speed*scl) {
244 if ((speed*scl - ips) < bestmatch) {
245 bestmatch = speed*scl - ips;
Rafal Jaworowskid3a02c32007-07-27 14:43:59 +0200246 best_i = i;
247 best_j = j;
Grzegorz Bernacki21305af2008-01-11 12:03:43 +0100248 best_speed = ips/scl;
Rafal Jaworowskid3a02c32007-07-27 14:43:59 +0200249 }
250 }
251 }
252 }
253 divider = (best_i & 3) | ((best_i & 4) << 3) | (best_j << 2);
254 if (gd->flags & GD_FLG_RELOC) {
255 fdr = divider;
256 } else {
257 debug("%ld kHz, \n", best_speed / 1000);
258 return divider;
259 }
260 }
261
262 return fdr;
263}
264
265int i2c_probe (uchar chip)
266{
Wolfgang Denkb8539952009-05-16 10:47:43 +0200267 volatile immap_t *im = (immap_t *) CONFIG_SYS_IMMR;
268 volatile i2c512x_dev_t *regs = &im->i2c.dev[bus_num];
Rafal Jaworowskid3a02c32007-07-27 14:43:59 +0200269 int i;
270
271 for (i = 0; i < I2C_RETRIES; i++) {
272 mpc_reg_out (&regs->mcr, I2C_STA, I2C_STA);
273
274 if (! do_address (chip, 0)) {
275 mpc_reg_out (&regs->mcr, 0, I2C_STA);
276 udelay (500);
277 break;
278 }
279
280 mpc_reg_out (&regs->mcr, 0, I2C_STA);
281 udelay (500);
282 }
283
284 return (i == I2C_RETRIES);
285}
286
287int i2c_read (uchar chip, uint addr, int alen, uchar *buf, int len)
288{
Wolfgang Denkb8539952009-05-16 10:47:43 +0200289 volatile immap_t *im = (immap_t *) CONFIG_SYS_IMMR;
290 volatile i2c512x_dev_t *regs = &im->i2c.dev[bus_num];
Rafal Jaworowskid3a02c32007-07-27 14:43:59 +0200291 char xaddr[4];
Rafal Jaworowskid3a02c32007-07-27 14:43:59 +0200292 int ret = -1;
293
294 xaddr[0] = (addr >> 24) & 0xFF;
295 xaddr[1] = (addr >> 16) & 0xFF;
296 xaddr[2] = (addr >> 8) & 0xFF;
297 xaddr[3] = addr & 0xFF;
298
299 if (wait_for_bb ()) {
300 printf ("i2c_read: bus is busy\n");
301 goto Done;
302 }
303
304 mpc_reg_out (&regs->mcr, I2C_STA, I2C_STA);
305 if (do_address (chip, 0)) {
306 printf ("i2c_read: failed to address chip\n");
307 goto Done;
308 }
309
310 if (send_bytes (chip, &xaddr[4-alen], alen)) {
311 printf ("i2c_read: send_bytes failed\n");
312 goto Done;
313 }
314
315 mpc_reg_out (&regs->mcr, I2C_RSTA, I2C_RSTA);
316 if (do_address (chip, 1)) {
317 printf ("i2c_read: failed to address chip\n");
318 goto Done;
319 }
320
321 if (receive_bytes (chip, (char *)buf, len)) {
322 printf ("i2c_read: receive_bytes failed\n");
323 goto Done;
324 }
325
326 ret = 0;
327Done:
328 mpc_reg_out (&regs->mcr, 0, I2C_STA);
329 return ret;
330}
331
332int i2c_write (uchar chip, uint addr, int alen, uchar *buf, int len)
333{
Wolfgang Denkb8539952009-05-16 10:47:43 +0200334 volatile immap_t *im = (immap_t *) CONFIG_SYS_IMMR;
335 volatile i2c512x_dev_t *regs = &im->i2c.dev[bus_num];
Rafal Jaworowskid3a02c32007-07-27 14:43:59 +0200336 char xaddr[4];
Rafal Jaworowskid3a02c32007-07-27 14:43:59 +0200337 int ret = -1;
338
339 xaddr[0] = (addr >> 24) & 0xFF;
340 xaddr[1] = (addr >> 16) & 0xFF;
341 xaddr[2] = (addr >> 8) & 0xFF;
342 xaddr[3] = addr & 0xFF;
343
344 if (wait_for_bb ()) {
345 printf ("i2c_write: bus is busy\n");
346 goto Done;
347 }
348
349 mpc_reg_out (&regs->mcr, I2C_STA, I2C_STA);
350 if (do_address (chip, 0)) {
351 printf ("i2c_write: failed to address chip\n");
352 goto Done;
353 }
354
355 if (send_bytes (chip, &xaddr[4-alen], alen)) {
356 printf ("i2c_write: send_bytes failed\n");
357 goto Done;
358 }
359
360 if (send_bytes (chip, (char *)buf, len)) {
361 printf ("i2c_write: send_bytes failed\n");
362 goto Done;
363 }
364
365 ret = 0;
366Done:
367 mpc_reg_out (&regs->mcr, 0, I2C_STA);
368 return ret;
369}
370
Rafal Jaworowskid3a02c32007-07-27 14:43:59 +0200371int i2c_set_bus_num (unsigned int bus)
372{
373 if (bus >= I2C_BUS_CNT) {
374 return -1;
375 }
376 bus_num = bus;
377
378 return 0;
379}
380
381unsigned int i2c_get_bus_num (void)
382{
383 return bus_num;
384}
385
Rafal Jaworowskid3a02c32007-07-27 14:43:59 +0200386#endif /* CONFIG_HARD_I2C */