blob: 723d3b4b1dc1a52e8923f59a36111bf0ef5fbe23 [file] [log] [blame]
Ruilin Haode4defb2015-11-10 00:18:59 -08001/*
2 * This file is part of the coreboot project.
3 *
4 * Copyright 2015 Marvell Inc.
5 *
6 * This program is free software; you can redistribute it and/or modify
7 * it under the terms of the GNU General Public License as published by
8 * the Free Software Foundation; version 2 of the License.
9 *
10 * This program is distributed in the hope that it will be useful,
11 * but WITHOUT ANY WARRANTY; without even the implied warranty of
12 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
13 * GNU General Public License for more details.
14 */
15
16#include <arch/io.h>
17#include <arch/cpu.h>
18#include <console/console.h>
19#include <delay.h>
20#include <device/i2c.h>
21#include <soc/common.h>
22#include <soc/i2c.h>
23#include <soc/clock.h>
24#include <helpers.h>
25
26#undef MV_DEBUG
27//#define MV_DEBUG
28#ifdef MV_DEBUG
29#define DB(x) x
30#else
31#define DB(x)
32#endif
33#define mv_os_printf(args...) printk(BIOS_INFO, args)
34
35/* The TWSI interface supports both 7-bit and 10-bit addressing. */
36/* This enumerator describes addressing type. */
37typedef enum _mv_twsi_addr_type {
38 ADDR7_BIT, /* 7 bit address */
39 ADDR10_BIT /* 10 bit address */
40} MV_TWSI_ADDR_TYPE;
41
42/* This structure describes TWSI address. */
43typedef struct _mv_twsi_addr {
44 uint32_t address; /* address */
45 MV_TWSI_ADDR_TYPE type; /* Address type */
46} MV_TWSI_ADDR;
47
48/* This structure describes a TWSI slave. */
49typedef struct _mv_twsi_slave {
50 MV_TWSI_ADDR slave_addr;
51 int valid_offset; /* whether the slave has offset (i.e. Eeprom etc.) */
52 uint32_t offset; /* offset in the slave. */
53 int more_than256; /* whether the ofset is bigger then 256 */
54} MV_TWSI_SLAVE;
55
56/* This enumerator describes TWSI protocol commands. */
57typedef enum _mv_twsi_cmd {
58 MV_TWSI_WRITE, /* TWSI write command - 0 according to spec */
59 MV_TWSI_READ /* TWSI read command - 1 according to spec */
60} MV_TWSI_CMD;
61
62static void twsi_int_flg_clr(uint8_t chan_num);
63static uint8_t twsi_main_int_get(uint8_t chan_num);
64static void twsi_ack_bit_set(uint8_t chan_num);
65static uint32_t twsi_sts_get(uint8_t chan_num);
66static void twsi_reset(uint8_t chan_num);
67static int twsi_addr7_bit_set(uint8_t chan_num,
68 uint32_t device_address,
69 MV_TWSI_CMD command);
70static int twsi_addr10_bit_set(uint8_t chan_num,
71 uint32_t device_address,
72 MV_TWSI_CMD command);
73static int twsi_data_transmit(uint8_t chan_num,
74 uint8_t *p_block,
75 uint32_t block_size);
76static int twsi_data_receive(uint8_t chan_num,
77 uint8_t *p_block,
78 uint32_t block_size);
79static int twsi_target_offs_set(uint8_t chan_num,
80 uint32_t offset,
81 uint8_t more_than256);
82static int mv_twsi_start_bit_set(uint8_t chan_num);
83static int mv_twsi_stop_bit_set(uint8_t chan_num);
84static int mv_twsi_addr_set(uint8_t chan_num,
85 MV_TWSI_ADDR *twsi_addr,
86 MV_TWSI_CMD command);
87static uint32_t mv_twsi_init(uint8_t chan_num,
88 uint32_t frequency,
89 uint32_t Tclk,
90 MV_TWSI_ADDR *twsi_addr,
91 uint8_t general_call_enable);
92static int mv_twsi_read(uint8_t chan_num,
93 MV_TWSI_SLAVE *twsi_slave,
94 uint8_t *p_block,
95 uint32_t block_size);
96static int mv_twsi_write(uint8_t chan_num,
97 MV_TWSI_SLAVE *twsi_slave,
98 uint8_t *p_block,
99 uint32_t block_size);
100static uint32_t who_am_i(void);
101static int i2c_init(unsigned bus);
102static void i2c_reset(unsigned bus);
103
104static int m_initialized[MAX_I2C_NUM] = {0, 0};
105
106static uint8_t twsi_timeout_chk(uint32_t timeout, const char *p_string)
107{
108 if (timeout >= TWSI_TIMEOUT_VALUE) {
109 DB(mv_os_printf("%s", p_string));
110 return MV_TRUE;
111 }
112 return MV_FALSE;
113}
114
115/*******************************************************************************
116* mv_twsi_start_bit_set - Set start bit on the bus
117*
118* DESCRIPTION:
119* This routine sets the start bit on the TWSI bus.
120* The routine first checks for interrupt flag condition, then it sets
121* the start bit in the TWSI Control register.
122* If the interrupt flag condition check previously was set, the function
123* will clear it.
124* The function then wait for the start bit to be cleared by the HW.
125* Then it waits for the interrupt flag to be set and eventually, the
126* TWSI status is checked to be 0x8 or 0x10(repeated start bit).
127*
128* INPUT:
129* chan_num - TWSI channel.
130*
131* OUTPUT:
132* None.
133*
134* RETURN:
135* MV_OK if start bit was set successfuly on the bus.
136* MV_FAIL if start_bit not set or status does not indicate start
137* condition trasmitted.
138*
139*******************************************************************************/
140static int mv_twsi_start_bit_set(uint8_t chan_num)
141{
142 uint8_t is_int_flag = MV_FALSE;
143 uint32_t timeout, temp;
144
145 DB(mv_os_printf("TWSI: mv_twsi_start_bit_set\n"));
146 /* check Int flag */
147 if (twsi_main_int_get(chan_num))
148 is_int_flag = MV_TRUE;
149 /* set start Bit */
150 mrvl_reg_bit_set(TWSI_CONTROL_REG(chan_num), TWSI_CONTROL_START_BIT);
151
152 /* in case that the int flag was set before i.e. repeated start bit */
153 if (is_int_flag) {
154 DB(mv_os_printf(
155 "TWSI: mv_twsi_start_bit_set repeated start Bit\n"));
156 twsi_int_flg_clr(chan_num);
157 }
158
159 /* wait for interrupt */
160 timeout = 0;
161 while (!twsi_main_int_get(chan_num) && (timeout++ < TWSI_TIMEOUT_VALUE))
162 ;
163
164 /* check for timeout */
165 if (MV_TRUE ==
166 twsi_timeout_chk(timeout,
167 (const char *)"TWSI: Start Clear bit time_out.\n"))
168 return MV_TIMEOUT;
169
170 /* check that start bit went down */
171 if ((mrvl_reg_read(TWSI_CONTROL_REG(chan_num)) &
172 TWSI_CONTROL_START_BIT) != 0) {
173 mv_os_printf("TWSI: start bit didn't go down\n");
174 return MV_FAIL;
175 }
176
177 /* check the status */
178 temp = twsi_sts_get(chan_num);
179 if ((TWSI_M_LOST_ARB_DUR_AD_OR_DATA_TRA == temp) ||
180 (TWSI_M_LOST_ARB_DUR_AD_TRA_GNL_CALL_AD_REC_ACK_TRA == temp)) {
181 DB(mv_os_printf("TWSI: Lost Arb, status %x\n", temp));
182 return MV_RETRY;
183 } else if ((temp != TWSI_START_CON_TRA) &&
184 (temp != TWSI_REPEATED_START_CON_TRA)) {
185 mv_os_printf("TWSI: status %x after Set Start Bit.\n", temp);
186 return MV_FAIL;
187 }
188
189 return MV_OK;
190}
191
192/*******************************************************************************
193* mv_twsi_stop_bit_set - Set stop bit on the bus
194*
195* DESCRIPTION:
196* This routine set the stop bit on the TWSI bus.
197* The function then wait for the stop bit to be cleared by the HW.
198* Finally the function checks for status of 0xF8.
199*
200* INPUT:
201* chan_num - TWSI channel
202*
203* OUTPUT:
204* None.
205*
206* RETURN:
207* MV_TRUE is stop bit was set successfuly on the bus.
208*
209*******************************************************************************/
210static int mv_twsi_stop_bit_set(uint8_t chan_num)
211{
212 uint32_t timeout, temp;
213
214 /* Generate stop bit */
215 mrvl_reg_bit_set(TWSI_CONTROL_REG(chan_num), TWSI_CONTROL_STOP_BIT);
216
217 twsi_int_flg_clr(chan_num);
218
219 /* wait for stop bit to come down */
220 timeout = 0;
221 while (((mrvl_reg_read(TWSI_CONTROL_REG(chan_num)) &
222 TWSI_CONTROL_STOP_BIT) != 0) &&
223 (timeout++ < TWSI_TIMEOUT_VALUE))
224 ;
225
226 /* check for timeout */
227 if (MV_TRUE ==
228 twsi_timeout_chk(timeout,
229 (const char *)"TWSI: ERROR - Stop bit timeout\n"))
230 return MV_TIMEOUT;
231
232 /* check that the stop bit went down */
233 if ((mrvl_reg_read(TWSI_CONTROL_REG(chan_num)) &
234 TWSI_CONTROL_STOP_BIT) != 0) {
235 mv_os_printf(
236 "TWSI: ERROR - stop bit not went down\n");
237 return MV_FAIL;
238 }
239
240 /* check the status */
241 temp = twsi_sts_get(chan_num);
242 if ((TWSI_M_LOST_ARB_DUR_AD_OR_DATA_TRA == temp) ||
243 (TWSI_M_LOST_ARB_DUR_AD_TRA_GNL_CALL_AD_REC_ACK_TRA == temp)) {
244 DB(mv_os_printf("TWSI: Lost Arb, status %x\n", temp));
245 return MV_RETRY;
246 } else if (temp != TWSI_NO_REL_STS_INT_FLAG_IS_KEPT_0) {
247 mv_os_printf(
248 "TWSI: ERROR - status %x after Stop Bit\n",
249 temp);
250 return MV_FAIL;
251 }
252
253 return MV_OK;
254}
255
256/*******************************************************************************
257* twsi_main_int_get - Get twsi bit from main Interrupt cause.
258*
259* DESCRIPTION:
260* This routine returns the twsi interrupt flag value.
261*
262* INPUT:
263* None.
264*
265* OUTPUT:
266* None.
267*
268* RETURN:
269* MV_TRUE is interrupt flag is set, MV_FALSE otherwise.
270*
271*******************************************************************************/
272static uint32_t who_am_i(void)
273{
274 return (read_mpidr() & 0x1);
275}
276
277static uint8_t twsi_main_int_get(uint8_t chan_num)
278{
279 uint32_t temp;
280
281 /* get the int flag bit */
282 temp = mrvl_reg_read(MV_TWSI_CPU_MAIN_INT_CAUSE(chan_num, who_am_i()));
283 if (temp & (1 << CPU_MAIN_INT_TWSI_OFFS(chan_num)))
284 return MV_TRUE;
285
286 return MV_FALSE;
287}
288
289/*******************************************************************************
290* twsi_int_flg_clr - Clear Interrupt flag.
291*
292* DESCRIPTION:
293* This routine clears the interrupt flag. It does NOT poll the interrupt
294* to make sure the clear. After clearing the interrupt, it waits for at
295* least 1 miliseconds.
296*
297* INPUT:
298* chan_num - TWSI channel
299*
300* OUTPUT:
301* None.
302*
303* RETURN:
304* None.
305*
306*******************************************************************************/
307static void twsi_int_flg_clr(uint8_t chan_num)
308{
309 /* wait for 1ms to prevent TWSI register write after write problems */
310 mdelay(1);
311 /* clear the int flag bit */
312 mrvl_reg_bit_reset(
313 TWSI_CONTROL_REG(chan_num), TWSI_CONTROL_INT_FLAG_SET);
314 /* wait for 1 mili sec for the clear to take effect */
315 mdelay(1);
316}
317
318/*******************************************************************************
319* twsi_ack_bit_set - Set acknowledge bit on the bus
320*
321* DESCRIPTION:
322* This routine set the acknowledge bit on the TWSI bus.
323*
324* INPUT:
325* None.
326*
327* OUTPUT:
328* None.
329*
330* RETURN:
331* None.
332*
333*******************************************************************************/
334static void twsi_ack_bit_set(uint8_t chan_num)
335{
336 /*Set the Ack bit */
337 mrvl_reg_bit_set(TWSI_CONTROL_REG(chan_num), TWSI_CONTROL_ACK);
338 /* Add delay of 1ms */
339 mdelay(1);
340}
341
342/*******************************************************************************
343* twsi_init - Initialize TWSI interface
344*
345* DESCRIPTION:
346* This routine:
347* -Reset the TWSI.
348* -Initialize the TWSI clock baud rate according to given frequency
349* parameter based on Tclk frequency and enables TWSI slave.
350* -Set the ack bit.
351* -Assign the TWSI slave address according to the TWSI address Type.
352*
353* INPUT:
354* chan_num - TWSI channel
355* frequency - TWSI frequency in KHz. (up to 100_kHZ)
356*
357* OUTPUT:
358* None.
359*
360* RETURN:
361* Actual frequency.
362*
363*******************************************************************************/
364static uint32_t mv_twsi_init(uint8_t chan_num,
365 uint32_t frequency,
366 uint32_t Tclk,
367 MV_TWSI_ADDR *p_twsi_addr,
368 uint8_t general_call_enable)
369{
370 uint32_t n, m, freq, margin, min_margin = 0xffffffff;
371 uint32_t power;
372 uint32_t actual_freq = 0, actual_n = 0, actual_m = 0, val;
373
374 if (frequency > 100000)
375 die("TWSI frequency is too high!");
376
377 DB(mv_os_printf("TWSI: mv_twsi_init - Tclk = %d freq = %d\n", Tclk,
378 frequency));
379 /* Calucalte N and M for the TWSI clock baud rate */
380 for (n = 0; n < 8; n++) {
381 for (m = 0; m < 16; m++) {
382 power = 2 << n; /* power = 2^(n+1) */
383 freq = Tclk / (10 * (m + 1) * power);
384 margin = ABS(frequency - freq);
385
386 if ((freq <= frequency) && (margin < min_margin)) {
387 min_margin = margin;
388 actual_freq = freq;
389 actual_n = n;
390 actual_m = m;
391 }
392 }
393 }
394 DB(mv_os_printf("TWSI: mv_twsi_init - act_n %u act_m %u act_freq %u\n",
395 actual_n, actual_m, actual_freq));
396 /* Reset the TWSI logic */
397 twsi_reset(chan_num);
398
399 /* Set the baud rate */
400 val = ((actual_m << TWSI_BAUD_RATE_M_OFFS) |
401 actual_n << TWSI_BAUD_RATE_N_OFFS);
402 mrvl_reg_write(TWSI_STATUS_BAUDE_RATE_REG(chan_num), val);
403
404 /* Enable the TWSI and slave */
405 mrvl_reg_write(TWSI_CONTROL_REG(chan_num),
406 TWSI_CONTROL_ENA | TWSI_CONTROL_ACK);
407
408 /* set the TWSI slave address */
409 if (p_twsi_addr->type == ADDR10_BIT) {
410 /* writing the 2 most significant bits of the 10 bit address */
411 val = ((p_twsi_addr->address & TWSI_SLAVE_ADDR_10_BIT_MASK) >>
412 TWSI_SLAVE_ADDR_10_BIT_OFFS);
413 /* bits 7:3 must be 0x11110 */
414 val |= TWSI_SLAVE_ADDR_10_BIT_CONST;
415 /* set GCE bit */
416 if (general_call_enable)
417 val |= TWSI_SLAVE_ADDR_GCE_ENA;
418 /* write slave address */
419 mrvl_reg_write(TWSI_SLAVE_ADDR_REG(chan_num), val);
420
421 /* writing the 8 least significant bits of the 10 bit address */
422 val = (p_twsi_addr->address << TWSI_EXTENDED_SLAVE_OFFS) &
423 TWSI_EXTENDED_SLAVE_MASK;
424 mrvl_reg_write(TWSI_EXTENDED_SLAVE_ADDR_REG(chan_num), val);
425 } else {
426 /* set the 7 Bits address */
427 mrvl_reg_write(TWSI_EXTENDED_SLAVE_ADDR_REG(chan_num), 0x0);
428 val = (p_twsi_addr->address << TWSI_SLAVE_ADDR_7_BIT_OFFS) &
429 TWSI_SLAVE_ADDR_7_BIT_MASK;
430 mrvl_reg_write(TWSI_SLAVE_ADDR_REG(chan_num), val);
431 }
432
433 /* unmask twsi int */
434 mrvl_reg_bit_set(TWSI_CONTROL_REG(chan_num), TWSI_CONTROL_INT_ENA);
435
436 /* unmask twsi int in Interrupt source control register */
437 mrvl_reg_bit_set(CPU_INT_SOURCE_CONTROL_REG(
438 CPU_MAIN_INT_CAUSE_TWSI(chan_num)), (
439 1 << CPU_INT_SOURCE_CONTROL_IRQ_OFFS));
440
441 /* Add delay of 1ms */
442 mdelay(1);
443
444 return actual_freq;
445}
446
447/*******************************************************************************
448* twsi_sts_get - Get the TWSI status value.
449*
450* DESCRIPTION:
451* This routine returns the TWSI status value.
452*
453* INPUT:
454* chan_num - TWSI channel
455*
456* OUTPUT:
457* None.
458*
459* RETURN:
460* uint32_t - the TWSI status.
461*
462*******************************************************************************/
463static uint32_t twsi_sts_get(uint8_t chan_num)
464{
465 return mrvl_reg_read(TWSI_STATUS_BAUDE_RATE_REG(chan_num));
466}
467
468/*******************************************************************************
469* twsi_reset - Reset the TWSI.
470*
471* DESCRIPTION:
472* Resets the TWSI logic and sets all TWSI registers to their reset values.
473*
474* INPUT:
475* chan_num - TWSI channel
476*
477* OUTPUT:
478* None.
479*
480* RETURN:
481* None
482*
483*******************************************************************************/
484static void twsi_reset(uint8_t chan_num)
485{
486 /* Reset the TWSI logic */
487 mrvl_reg_write(TWSI_SOFT_RESET_REG(chan_num), 0);
488
489 /* wait for 2 mili sec */
490 mdelay(2);
491}
492
493/*******************************************************************************
494* mv_twsi_addr_set - Set address on TWSI bus.
495*
496* DESCRIPTION:
497* This function Set address (7 or 10 Bit address) on the Twsi Bus.
498*
499* INPUT:
500* chan_num - TWSI channel
501* p_twsi_addr - twsi address.
502* command - read / write .
503*
504* OUTPUT:
505* None.
506*
507* RETURN:
508* MV_OK - if setting the address completed successfully.
509* MV_FAIL otherwmise.
510*
511*******************************************************************************/
512static int mv_twsi_addr_set(uint8_t chan_num,
513 MV_TWSI_ADDR *p_twsi_addr,
514 MV_TWSI_CMD command)
515{
516 DB(mv_os_printf(
517 "TWSI: mv_twsi_addr7_bit_set addr %x , type %d, cmd is %s\n",
518 p_twsi_addr->address, p_twsi_addr->type,
519 ((command == MV_TWSI_WRITE) ? "Write" : "Read")));
520 /* 10 Bit address */
521 if (p_twsi_addr->type == ADDR10_BIT)
522 return twsi_addr10_bit_set(chan_num, p_twsi_addr->address,
523 command);
524 /* 7 Bit address */
525 else
526 return twsi_addr7_bit_set(chan_num, p_twsi_addr->address,
527 command);
528}
529
530/*******************************************************************************
531* twsi_addr10_bit_set - Set 10 Bit address on TWSI bus.
532*
533* DESCRIPTION:
534* There are two address phases:
535* 1) Write '11110' to data register bits [7:3] and 10-bit address MSB
536* (bits [9:8]) to data register bits [2:1] plus a write(0) or read(1)
537*bit
538* to the Data register. Then it clears interrupt flag which drive
539* the address on the TWSI bus. The function then waits for interrupt
540* flag to be active and status 0x18 (write) or 0x40 (read) to be set.
541* 2) write the rest of 10-bit address to data register and clears
542* interrupt flag which drive the address on the TWSI bus. The
543* function then waits for interrupt flag to be active and status
544* 0xD0 (write) or 0xE0 (read) to be set.
545*
546* INPUT:
547* chan_num - TWSI channel
548* device_address - twsi address.
549* command - read / write .
550*
551* OUTPUT:
552* None.
553*
554* RETURN:
555* MV_OK - if setting the address completed successfully.
556* MV_FAIL otherwmise.
557*
558*******************************************************************************/
559static int twsi_addr10_bit_set(uint8_t chan_num,
560 uint32_t device_address,
561 MV_TWSI_CMD command)
562{
563 uint32_t val, timeout;
564
565 /* writing the 2 most significant bits of the 10 bit address */
566 val = ((device_address & TWSI_DATA_ADDR_10_BIT_MASK) >>
567 TWSI_DATA_ADDR_10_BIT_OFFS);
568 /* bits 7:3 must be 0x11110 */
569 val |= TWSI_DATA_ADDR_10_BIT_CONST;
570 /* set command */
571 val |= command;
572 mrvl_reg_write(TWSI_DATA_REG(chan_num), val);
573 /* WA add a delay */
574 mdelay(1);
575
576 /* clear Int flag */
577 twsi_int_flg_clr(chan_num);
578
579 /* wait for Int to be Set */
580 timeout = 0;
581 while (!twsi_main_int_get(chan_num) && (timeout++ < TWSI_TIMEOUT_VALUE))
582 ;
583
584 /* check for timeout */
585 if (MV_TRUE ==
586 twsi_timeout_chk(
587 timeout, (const char *)"TWSI: addr (10_bit) Int time_out.\n"))
588 return MV_TIMEOUT;
589
590 /* check the status */
591 val = twsi_sts_get(chan_num);
592 if ((TWSI_M_LOST_ARB_DUR_AD_OR_DATA_TRA == val) ||
593 (TWSI_M_LOST_ARB_DUR_AD_TRA_GNL_CALL_AD_REC_ACK_TRA == val)) {
594 DB(mv_os_printf("TWSI: Lost Arb, status %x\n", val));
595 return MV_RETRY;
596 } else if (((val != TWSI_AD_PLS_RD_BIT_TRA_ACK_REC) &&
597 (command == MV_TWSI_READ)) ||
598 ((val != TWSI_AD_PLS_WR_BIT_TRA_ACK_REC) &&
599 (command == MV_TWSI_WRITE))) {
600 mv_os_printf("TWSI: status %x 1st addr (10 Bit) in %s mode.\n",
601 val,
602 ((command == MV_TWSI_WRITE) ? "Write" : "Read"));
603 return MV_FAIL;
604 }
605
606 /* set 8 LSB of the address */
607 val = (device_address << TWSI_DATA_ADDR_7_BIT_OFFS) &
608 TWSI_DATA_ADDR_7_BIT_MASK;
609 mrvl_reg_write(TWSI_DATA_REG(chan_num), val);
610
611 /* clear Int flag */
612 twsi_int_flg_clr(chan_num);
613
614 /* wait for Int to be Set */
615 timeout = 0;
616 while (!twsi_main_int_get(chan_num) && (timeout++ < TWSI_TIMEOUT_VALUE))
617 ;
618
619 /* check for timeout */
620 if (MV_TRUE ==
621 twsi_timeout_chk(timeout,
622 (const char *)"TWSI: 2nd (10 Bit) Int tim_out.\n"))
623 return MV_TIMEOUT;
624
625 /* check the status */
626 val = twsi_sts_get(chan_num);
627 if ((TWSI_M_LOST_ARB_DUR_AD_OR_DATA_TRA == val) ||
628 (TWSI_M_LOST_ARB_DUR_AD_TRA_GNL_CALL_AD_REC_ACK_TRA == val)) {
629 DB(mv_os_printf("TWSI: Lost Arb, status %x\n", val));
630 return MV_RETRY;
631 } else if (((val != TWSI_SEC_AD_PLS_RD_BIT_TRA_ACK_REC) &&
632 (command == MV_TWSI_READ)) ||
633 ((val != TWSI_SEC_AD_PLS_WR_BIT_TRA_ACK_REC) &&
634 (command == MV_TWSI_WRITE))) {
635 mv_os_printf("TWSI: status %x 2nd addr(10 Bit) in %s mode.\n",
636 val,
637 ((command == MV_TWSI_WRITE) ? "Write" : "Read"));
638 return MV_FAIL;
639 }
640
641 return MV_OK;
642}
643
644/*******************************************************************************
645* twsi_addr7_bit_set - Set 7 Bit address on TWSI bus.
646*
647* DESCRIPTION:
648* This function writes 7 bit address plus a write or read bit to the
649* Data register. Then it clears interrupt flag which drive the address on
650* the TWSI bus. The function then waits for interrupt flag to be active
651* and status 0x18 (write) or 0x40 (read) to be set.
652*
653* INPUT:
654* chan_num - TWSI channel
655* device_address - twsi address.
656* command - read / write .
657*
658* OUTPUT:
659* None.
660*
661* RETURN:
662* MV_OK - if setting the address completed successfully.
663* MV_FAIL otherwmise.
664*
665*******************************************************************************/
666static int twsi_addr7_bit_set(uint8_t chan_num,
667 uint32_t device_address,
668 MV_TWSI_CMD command)
669{
670 uint32_t val, timeout;
671
672 /* set the address */
673 val = (device_address << TWSI_DATA_ADDR_7_BIT_OFFS) &
674 TWSI_DATA_ADDR_7_BIT_MASK;
675 /* set command */
676 val |= command;
677 mrvl_reg_write(TWSI_DATA_REG(chan_num), val);
678 /* WA add a delay */
679 mdelay(1);
680
681 /* clear Int flag */
682 twsi_int_flg_clr(chan_num);
683
684 /* wait for Int to be Set */
685 timeout = 0;
686 while (!twsi_main_int_get(chan_num) && (timeout++ < TWSI_TIMEOUT_VALUE))
687 ;
688
689 /* check for timeout */
690 if (MV_TRUE ==
691 twsi_timeout_chk(
692 timeout, (const char *)"TWSI: Addr (7 Bit) int time_out.\n"))
693 return MV_TIMEOUT;
694
695 /* check the status */
696 val = twsi_sts_get(chan_num);
697 if ((TWSI_M_LOST_ARB_DUR_AD_OR_DATA_TRA == val) ||
698 (TWSI_M_LOST_ARB_DUR_AD_TRA_GNL_CALL_AD_REC_ACK_TRA == val)) {
699 DB(mv_os_printf("TWSI: Lost Arb, status %x\n", val));
700 return MV_RETRY;
701 } else if (((val != TWSI_AD_PLS_RD_BIT_TRA_ACK_REC) &&
702 (command == MV_TWSI_READ)) ||
703 ((val != TWSI_AD_PLS_WR_BIT_TRA_ACK_REC) &&
704 (command == MV_TWSI_WRITE))) {
705 /* only in debug, since in boot we try to read the SPD of both
706 DRAM, and we don't
707 want error messeges in case DIMM doesn't exist. */
708 DB(mv_os_printf(
709 "TWSI: status %x addr (7 Bit) in %s mode.\n", val,
710 ((command == MV_TWSI_WRITE) ? "Write" : "Read")));
711 return MV_FAIL;
712 }
713
714 return MV_OK;
715}
716
717/*******************************************************************************
718* twsi_data_write - Trnasmit a data block over TWSI bus.
719*
720* DESCRIPTION:
721* This function writes a given data block to TWSI bus in 8 bit
722* granularity.
723* first The function waits for interrupt flag to be active then
724* For each 8-bit data:
725* The function writes data to data register. It then clears
726* interrupt flag which drives the data on the TWSI bus.
727* The function then waits for interrupt flag to be active and status
728* 0x28 to be set.
729*
730*
731* INPUT:
732* chan_num - TWSI channel
733* p_block - Data block.
734* block_size - number of chars in p_block.
735*
736* OUTPUT:
737* None.
738*
739* RETURN:
740* MV_OK - if transmiting the block completed successfully,
741* MV_BAD_PARAM - if p_block is NULL,
742* MV_FAIL otherwmise.
743*
744*******************************************************************************/
745static int twsi_data_transmit(uint8_t chan_num,
746 uint8_t *p_block,
747 uint32_t block_size)
748{
749 uint32_t timeout, temp, block_size_wr = block_size;
750
751 if (NULL == p_block)
752 return MV_BAD_PARAM;
753
754 /* wait for Int to be Set */
755 timeout = 0;
756 while (!twsi_main_int_get(chan_num) && (timeout++ < TWSI_TIMEOUT_VALUE))
757 ;
758
759 /* check for timeout */
760 if (MV_TRUE ==
761 twsi_timeout_chk(timeout,
762 (const char *)"TWSI: Read Data Int time_out.\n"))
763 return MV_TIMEOUT;
764
765 while (block_size_wr) {
766 /* write the data */
767 mrvl_reg_write(TWSI_DATA_REG(chan_num), (uint32_t)*p_block);
768 DB(mv_os_printf(
769 "TWSI: twsi_data_transmit place = %d write %x\n",
770 block_size - block_size_wr, *p_block));
771 p_block++;
772 block_size_wr--;
773
774 twsi_int_flg_clr(chan_num);
775
776 /* wait for Int to be Set */
777 timeout = 0;
778 while (!twsi_main_int_get(chan_num) &&
779 (timeout++ < TWSI_TIMEOUT_VALUE))
780 ;
781
782 /* check for timeout */
783 if (MV_TRUE == twsi_timeout_chk(
784 timeout, (const char *)"TWSI: time_out.\n"))
785 return MV_TIMEOUT;
786
787 /* check the status */
788 temp = twsi_sts_get(chan_num);
789 if ((TWSI_M_LOST_ARB_DUR_AD_OR_DATA_TRA == temp) ||
790 (TWSI_M_LOST_ARB_DUR_AD_TRA_GNL_CALL_AD_REC_ACK_TRA ==
791 temp)) {
792 DB(mv_os_printf("TWSI: Lost Arb, status %x\n", temp));
793 return MV_RETRY;
794 } else if (temp != TWSI_M_TRAN_DATA_BYTE_ACK_REC) {
795 mv_os_printf("TWSI: status %x in write trans\n", temp);
796 return MV_FAIL;
797 }
798 }
799
800 return MV_OK;
801}
802
803/*******************************************************************************
804* twsi_data_receive - Receive data block from TWSI bus.
805*
806* DESCRIPTION:
807* This function receive data block from TWSI bus in 8bit granularity
808* into p_block buffer.
809* first The function waits for interrupt flag to be active then
810* For each 8-bit data:
811* It clears the interrupt flag which allows the next data to be
812* received from TWSI bus.
813* The function waits for interrupt flag to be active,
814* and status reg is 0x50.
815* Then the function reads data from data register, and copies it to
816* the given buffer.
817*
818* INPUT:
819* chan_num - TWSI channel
820* block_size - number of bytes to read.
821*
822* OUTPUT:
823* p_block - Data block.
824*
825* RETURN:
826* MV_OK - if receive transaction completed successfully,
827* MV_BAD_PARAM - if p_block is NULL,
828* MV_FAIL otherwmise.
829*
830*******************************************************************************/
831static int twsi_data_receive(uint8_t chan_num,
832 uint8_t *p_block,
833 uint32_t block_size)
834{
835 uint32_t timeout, temp, block_size_rd = block_size;
836
837 if (NULL == p_block)
838 return MV_BAD_PARAM;
839
840 /* wait for Int to be Set */
841 timeout = 0;
842 while (!twsi_main_int_get(chan_num) && (timeout++ < TWSI_TIMEOUT_VALUE))
843 ;
844
845 /* check for timeout */
846 if (MV_TRUE ==
847 twsi_timeout_chk(timeout,
848 (const char *)"TWSI: Read Data int Time out .\n"))
849 return MV_TIMEOUT;
850
851 while (block_size_rd) {
852 if (block_size_rd == 1)
853 /* clear ack and Int flag */
854 mrvl_reg_bit_reset(
855 TWSI_CONTROL_REG(chan_num), TWSI_CONTROL_ACK);
856
857 twsi_int_flg_clr(chan_num);
858 /* wait for Int to be Set */
859 timeout = 0;
860 while ((!twsi_main_int_get(chan_num)) &&
861 (timeout++ < TWSI_TIMEOUT_VALUE))
862 ;
863
864 /* check for timeout */
865 if (MV_TRUE ==
866 twsi_timeout_chk(timeout, (const char *)"TWSI: Timeout.\n"))
867 return MV_TIMEOUT;
868
869 /* check the status */
870 temp = twsi_sts_get(chan_num);
871 if ((TWSI_M_LOST_ARB_DUR_AD_OR_DATA_TRA == temp) ||
872 (TWSI_M_LOST_ARB_DUR_AD_TRA_GNL_CALL_AD_REC_ACK_TRA ==
873 temp)) {
874 DB(mv_os_printf("TWSI: Lost Arb, status %x\n", temp));
875 return MV_RETRY;
876 } else if ((temp != TWSI_M_REC_RD_DATA_ACK_TRA) &&
877 (block_size_rd != 1)) {
878 mv_os_printf("TWSI: status %x in read trans\n", temp);
879 return MV_FAIL;
880 } else if ((temp != TWSI_M_REC_RD_DATA_ACK_NOT_TRA) &&
881 (block_size_rd == 1)) {
882 mv_os_printf("TWSI: status %x in Rd Terminate\n", temp);
883 return MV_FAIL;
884 }
885
886 /* read the data */
887 *p_block = (uint8_t)mrvl_reg_read(TWSI_DATA_REG(chan_num));
888 DB(mv_os_printf("TWSI: twsi_data_receive place %d read %x\n",
889 block_size - block_size_rd, *p_block));
890 p_block++;
891 block_size_rd--;
892 }
893
894 return MV_OK;
895}
896
897/*******************************************************************************
898* twsi_target_offs_set - Set TWST target offset on TWSI bus.
899*
900* DESCRIPTION:
901* The function support TWSI targets that have inside address space (for
902* example EEPROMs). The function:
903* 1) Convert the given offset into p_block and size.
904* in case the offset should be set to a TWSI slave which support
905* more then 256 bytes offset, the offset setting will be done
906* in 2 transactions.
907* 2) Use twsi_data_transmit to place those on the bus.
908*
909* INPUT:
910* chan_num - TWSI channel
911* offset - offset to be set on the EEPROM device.
912* more_than256 - whether the EEPROM device support more then 256 byte
913*offset.
914*
915* OUTPUT:
916* None.
917*
918* RETURN:
919* MV_OK - if setting the offset completed successfully.
920* MV_FAIL otherwmise.
921*
922*******************************************************************************/
923static int twsi_target_offs_set(uint8_t chan_num,
924 uint32_t offset,
925 uint8_t more_than256)
926{
927 uint8_t off_block[2];
928 uint32_t off_size;
929
930 if (more_than256 == MV_TRUE) {
931 off_block[0] = (offset >> 8) & 0xff;
932 off_block[1] = offset & 0xff;
933 off_size = 2;
934 } else {
935 off_block[0] = offset & 0xff;
936 off_size = 1;
937 }
938 DB(mv_os_printf(
939 "TWSI: twsi_target_offs_set off_size = %x addr1 = %x addr2 = %x\n",
940 off_size, off_block[0], off_block[1]));
941 return twsi_data_transmit(chan_num, off_block, off_size);
942}
943
944/*******************************************************************************
945* mv_twsi_read - Read data block from a TWSI Slave.
946*
947* DESCRIPTION:
948* The function calls the following functions:
949* -) mv_twsi_start_bit_set();
950* if (EEPROM device)
951* -) mv_twsi_addr_set(w);
952* -) twsi_target_offs_set();
953* -) mv_twsi_start_bit_set();
954* -) mv_twsi_addr_set(r);
955* -) twsi_data_receive();
956* -) mv_twsi_stop_bit_set();
957*
958* INPUT:
959* chan_num - TWSI channel
960* p_twsi_slave - Twsi Slave structure.
961* block_size - number of bytes to read.
962*
963* OUTPUT:
964* p_block - Data block.
965*
966* RETURN:
967* MV_OK - if EEPROM read transaction completed successfully,
968* MV_BAD_PARAM - if p_block is NULL,
969* MV_FAIL otherwmise.
970*
971*******************************************************************************/
972static int mv_twsi_read(uint8_t chan_num,
973 MV_TWSI_SLAVE *p_twsi_slave,
974 uint8_t *p_block,
975 uint32_t block_size)
976{
977 int rc;
978 int ret = MV_FAIL;
979 uint32_t counter = 0;
980
981 if ((NULL == p_block) || (NULL == p_twsi_slave))
982 return MV_BAD_PARAM;
983
984 do {
985 /* wait for 1 mili sec for the clear to take effect */
986 if (counter > 0)
987 mdelay(1);
988 ret = mv_twsi_start_bit_set(chan_num);
989
990 if (MV_RETRY == ret)
991 continue;
992 else if (MV_OK != ret) {
993 mv_twsi_stop_bit_set(chan_num);
994 DB(mv_os_printf(
995 "mv_twsi_read:mv_twsi_start_bit_set failed\n"));
996 return MV_FAIL;
997 }
998
999 DB(mv_os_printf(
1000 "TWSI: mv_twsi_eeprom_read after mv_twsi_start_bit_set\n"));
1001
1002 /* in case offset exsist (i.e. eeprom ) */
1003 if (MV_TRUE == p_twsi_slave->valid_offset) {
1004 rc = mv_twsi_addr_set(chan_num,
1005 &(p_twsi_slave->slave_addr),
1006 MV_TWSI_WRITE);
1007 if (MV_RETRY == rc)
1008 continue;
1009 else if (MV_OK != rc) {
1010 mv_twsi_stop_bit_set(chan_num);
1011 DB(mv_os_printf(
1012 "mv_twsi_addr_set(%d,0x%x,%d) rc=%d\n",
1013 chan_num,
1014 (uint32_t) &(p_twsi_slave->slave_addr),
1015 MV_TWSI_WRITE, rc));
1016 return MV_FAIL;
1017 }
1018
1019 ret =
1020 twsi_target_offs_set(chan_num, p_twsi_slave->offset,
1021 p_twsi_slave->more_than256);
1022 if (MV_RETRY == ret)
1023 continue;
1024 else if (MV_OK != ret) {
1025 mv_twsi_stop_bit_set(chan_num);
1026 DB(mv_os_printf(
1027 "TWSI: twsi_target_offs_set Failed\n"));
1028 return MV_FAIL;
1029 }
1030 DB(mv_os_printf("TWSI: after twsi_target_offs_set\n"));
1031 ret = mv_twsi_start_bit_set(chan_num);
1032 if (MV_RETRY == ret)
1033 continue;
1034 else if (MV_OK != ret) {
1035 mv_twsi_stop_bit_set(chan_num);
1036 DB(mv_os_printf(
1037 "TWSI: mv_twsi_start_bit_set failed\n"));
1038 return MV_FAIL;
1039 }
1040 DB(mv_os_printf("TWSI: after mv_twsi_start_bit_set\n"));
1041 }
1042 ret = mv_twsi_addr_set(chan_num, &(p_twsi_slave->slave_addr),
1043 MV_TWSI_READ);
1044 if (MV_RETRY == ret)
1045 continue;
1046 else if (MV_OK != ret) {
1047 mv_twsi_stop_bit_set(chan_num);
1048 DB(mv_os_printf(
1049 "mv_twsi_read: mv_twsi_addr_set 2 Failed\n"));
1050 return MV_FAIL;
1051 }
1052 DB(mv_os_printf(
1053 "TWSI: mv_twsi_eeprom_read after mv_twsi_addr_set\n"));
1054
1055 ret = twsi_data_receive(chan_num, p_block, block_size);
1056 if (MV_RETRY == ret)
1057 continue;
1058 else if (MV_OK != ret) {
1059 mv_twsi_stop_bit_set(chan_num);
1060 DB(mv_os_printf(
1061 "mv_twsi_read: twsi_data_receive Failed\n"));
1062 return MV_FAIL;
1063 }
1064 DB(mv_os_printf(
1065 "TWSI: mv_twsi_eeprom_read after twsi_data_receive\n"));
1066
1067 ret = mv_twsi_stop_bit_set(chan_num);
1068 if (MV_RETRY == ret)
1069 continue;
1070 else if (MV_OK != ret) {
1071 DB(mv_os_printf(
1072 "mv_twsi_read: mv_twsi_stop_bit_set 3 Failed\n"));
1073 return MV_FAIL;
1074 }
1075 counter++;
1076 } while ((MV_RETRY == ret) && (counter < MAX_RETRY_CNT));
1077
1078 if (counter == MAX_RETRY_CNT)
1079 DB(mv_os_printf("mv_twsi_write: Retry Expire\n"));
1080
1081 twsi_ack_bit_set(chan_num);
1082
1083 DB(mv_os_printf(
1084 "TWSI: mv_twsi_eeprom_read after mv_twsi_stop_bit_set\n"));
1085
1086 return MV_OK;
1087}
1088
1089/*******************************************************************************
1090* mv_twsi_write - Write data block to a TWSI Slave.
1091*
1092* DESCRIPTION:
1093* The function calls the following functions:
1094* -) mv_twsi_start_bit_set();
1095* -) mv_twsi_addr_set();
1096* -)if (EEPROM device)
1097* -) twsi_target_offs_set();
1098* -) twsi_data_transmit();
1099* -) mv_twsi_stop_bit_set();
1100*
1101* INPUT:
1102* chan_num - TWSI channel
1103* eeprom_address - eeprom address.
1104* block_size - number of bytes to write.
1105* p_block - Data block.
1106*
1107* OUTPUT:
1108* None
1109*
1110* RETURN:
1111* MV_OK - if EEPROM read transaction completed successfully.
1112* MV_BAD_PARAM - if p_block is NULL,
1113* MV_FAIL otherwmise.
1114*
1115* NOTE: Part of the EEPROM, required that the offset will be aligned to the
1116* max write burst supported.
1117*******************************************************************************/
1118static int mv_twsi_write(uint8_t chan_num,
1119 MV_TWSI_SLAVE *p_twsi_slave,
1120 uint8_t *p_block,
1121 uint32_t block_size)
1122{
1123 int ret = MV_FAIL;
1124 uint32_t counter = 0;
1125
1126 if ((NULL == p_block) || (NULL == p_twsi_slave))
1127 return MV_BAD_PARAM;
1128
1129 do {
1130 if (counter >
1131 0) /* wait for 1 mili sec for the clear to take effect */
1132 mdelay(1);
1133 ret = mv_twsi_start_bit_set(chan_num);
1134
1135 if (MV_RETRY == ret)
1136 continue;
1137
1138 else if (MV_OK != ret) {
1139 mv_twsi_stop_bit_set(chan_num);
1140 DB(mv_os_printf(
1141 "mv_twsi_write: mv_twsi_start_bit_set failed\n"));
1142 return MV_FAIL;
1143 }
1144
1145 ret = mv_twsi_addr_set(chan_num, &(p_twsi_slave->slave_addr),
1146 MV_TWSI_WRITE);
1147 if (MV_RETRY == ret)
1148 continue;
1149 else if (MV_OK != ret) {
1150 mv_twsi_stop_bit_set(chan_num);
1151 DB(mv_os_printf(
1152 "mv_twsi_write: mv_twsi_addr_set failed\n"));
1153 return MV_FAIL;
1154 }
1155
1156 /* in case offset exsist (i.e. eeprom ) */
1157 if (MV_TRUE == p_twsi_slave->valid_offset) {
1158 ret =
1159 twsi_target_offs_set(chan_num, p_twsi_slave->offset,
1160 p_twsi_slave->more_than256);
1161 if (MV_RETRY == ret)
1162 continue;
1163 else if (MV_OK != ret) {
1164 mv_twsi_stop_bit_set(chan_num);
1165 DB(mv_os_printf(
1166 "TWSI: twsi_target_offs_set failed\n"));
1167 return MV_FAIL;
1168 }
1169 }
1170
1171 ret = twsi_data_transmit(chan_num, p_block, block_size);
1172 if (MV_RETRY == ret)
1173 continue;
1174 else if (MV_OK != ret) {
1175 mv_twsi_stop_bit_set(chan_num);
1176 DB(mv_os_printf(
1177 "mv_twsi_write: twsi_data_transmit failed\n"));
1178 return MV_FAIL;
1179 }
1180 ret = mv_twsi_stop_bit_set(chan_num);
1181 if (MV_RETRY == ret)
1182 continue;
1183 else if (MV_OK != ret) {
1184 DB(mv_os_printf(
1185 "mv_twsi_write: failed to set stopbit\n"));
1186 return MV_FAIL;
1187 }
1188 counter++;
1189 } while ((MV_RETRY == ret) && (counter < MAX_RETRY_CNT));
1190
1191 if (counter == MAX_RETRY_CNT)
1192 DB(mv_os_printf("mv_twsi_write: Retry Expire\n"));
1193
1194 return MV_OK;
1195}
1196
1197static int i2c_init(unsigned bus)
1198{
1199 if (bus >= MAX_I2C_NUM)
1200 return 1;
1201
1202 if (!m_initialized[bus]) {
1203 /* TWSI init */
1204 MV_TWSI_ADDR slave;
1205
1206 slave.type = ADDR7_BIT;
1207 slave.address = 0;
1208 mv_twsi_init(bus, TWSI_SPEED, mv_tclk_get(), &slave, 0);
1209 m_initialized[bus] = 1;
1210 }
1211
1212 return 0;
1213}
1214
1215static void i2c_reset(unsigned bus)
1216{
1217 if (bus < MAX_I2C_NUM)
1218 m_initialized[bus] = 0;
1219}
1220
1221int platform_i2c_transfer(unsigned bus, struct i2c_seg *segments, int seg_count)
1222{
1223 struct i2c_seg *seg = segments;
1224 int ret = 0;
1225 MV_TWSI_SLAVE twsi_slave;
1226
1227 if (i2c_init(bus))
1228 return 1;
1229
1230 while (!ret && seg_count--) {
1231 twsi_slave.slave_addr.address = seg->chip;
1232 twsi_slave.slave_addr.type = ADDR7_BIT;
1233 twsi_slave.more_than256 = MV_FALSE;
1234 twsi_slave.valid_offset = MV_FALSE;
1235 if (seg->read)
1236 ret =
1237 mv_twsi_read(bus, &twsi_slave, seg->buf, seg->len);
1238 else
1239 ret =
1240 mv_twsi_write(bus, &twsi_slave, seg->buf, seg->len);
1241 seg++;
1242 }
1243
1244 if (ret) {
1245 i2c_reset(bus);
1246 DB(mv_os_printf("mv_twsi_read/mv_twsi_write failed\n"));
1247 return 1;
1248 }
1249
1250 return 0;
1251}