2 *-----------------------------------------------------------------------------
3 * Filename: i2c_gmbus_tnc.c
5 *-----------------------------------------------------------------------------
6 * Copyright (c) 2002-2010, Intel Corporation.
8 * Permission is hereby granted, free of charge, to any person obtaining a copy
9 * of this software and associated documentation files (the "Software"), to deal
10 * in the Software without restriction, including without limitation the rights
11 * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
12 * copies of the Software, and to permit persons to whom the Software is
13 * furnished to do so, subject to the following conditions:
15 * The above copyright notice and this permission notice shall be included in
16 * all copies or substantial portions of the Software.
18 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
19 * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
20 * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
21 * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
22 * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
23 * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
26 *-----------------------------------------------------------------------------
29 *-----------------------------------------------------------------------------
32 #define MODULE_NAME hal.dpd
47 #include "../cmn/i2c_dispatch.h"
50 * @addtogroup display_group
54 /*......................................................................... */
55 extern igd_display_port_t dvob_port_tnc;
57 /*......................................................................... */
58 static int i2c_read_regs_tnc(
59 igd_context_t *context,
60 unsigned long i2c_bus,
61 unsigned long i2c_speed,
64 unsigned char FAR *buffer,
65 unsigned long num_bytes,
68 static int i2c_write_reg_list_tnc(
69 igd_context_t *context,
70 unsigned long i2c_bus,
71 unsigned long i2c_speed,
76 i2c_dispatch_t i2c_dispatch_tnc = {
78 i2c_write_reg_list_tnc,
82 /*.......................................................................... */
85 GMBUS_SPEED_50K = 0x0100,
86 GMBUS_SPEED_100K = 0x0000,
87 GMBUS_SPEED_400K = 0x0200,
88 GMBUS_SPEED_1000K = 0x0300,
108 GMBUS_PINS_DEDICATED = 1, /* Dedicated Control/GMBUS Pins */
109 GMBUS_PINS_SDVO = 5, /* SDVO Registers, DDC, PROM */
121 /*.......................................................................... */
124 SDVO_BUS_PROM = BIT(0),
125 SDVO_BUS_DDC1 = BIT(1),
126 SDVO_BUS_DDC2 = BIT(2),
130 #define SDVO_OPCODE_BUS_SWITCH 0x7A
132 #define SDVO_INDEX_PARAM_1 0x07
133 #define SDVO_INDEX_OPCODE 0x08
134 #define SDVO_INDEX_STATUS 0x09
136 #define SDVO_STATUS_SUCCESS 0x01
137 #define SDVO_STATUS_PENDING 0x04
139 /*.......................................................................... */
141 * In 16-bit, the mmio is a 16-bit pointer, the watcom 1.2 compiler will have
142 * error if directly convert it to unsigned long. Normally, have to cast it to
143 * unsigned short first then cast again to unsigned long; then, it will be
144 * correct. But this type of casting may cause some error in the 32 and 64 bit
145 * code. Since mmio will be equal to zero for 16-bit code. Add the checking
146 * for MICRO definition code to correct the macro by remove mmio.
148 #define READ_GMCH_REG(reg) READ_MMIO_REG_TNC(IGD_PORT_SDVO, reg)
149 #define WRITE_GMCH_REG(reg, data) WRITE_MMIO_REG_TNC(IGD_PORT_SDVO, reg, data)
151 static int gmbus_init(unsigned long i2c_bus,
152 unsigned long i2c_speed);
154 static int gmbus_read_edid(unsigned long ddc_addr,
155 unsigned long slave_addr,
157 unsigned long num_bytes,
158 unsigned char FAR *buffer);
160 static int gmbus_read_reg(unsigned long slave_addr,
162 unsigned char FAR *data);
164 static int gmbus_write_reg(unsigned long slave_addr,
168 static int gmbus_set_control_bus_switch(unsigned long slave_addr,
169 gmbus_ddc_addr_t ddc_addr);
171 static int gmbus_wait_event_one(unsigned long bit);
172 static int gmbus_wait_event_zero(unsigned long bit);
173 static int gmbus_error_handler(void);
175 /*.......................................................................... */
176 extern int i2c_read_regs_gpio(
177 igd_context_t *context,
178 unsigned long i2c_bus,
179 unsigned long i2c_speed,
182 unsigned char FAR *buffer,
183 unsigned long num_bytes,
184 unsigned long flags);
186 extern int i2c_write_reg_list_gpio(
187 igd_context_t *context,
188 unsigned long i2c_bus,
189 unsigned long i2c_speed,
192 unsigned long flags);
196 * i2c_read_regs_tnc is called to read Edid or a single sDVO register
199 * @param i2c_bus port->ddc_reg, port->i2c_reg
200 * @param i2c_speed 50, 100, 400, 1000 (Khz)
201 * @param dab 0x70/0x72 (sDVO Regs), 0xA0/0xA2 (sDVO/Analog DDC)
202 * @param reg I2C Reg Index
203 * @param num_bytes <= 508
204 * @param buffer Data read
206 * @return 0 on success
207 * @return 1 on failure
209 static int i2c_read_regs_tnc(igd_context_t *context,
210 unsigned long i2c_bus,
211 unsigned long i2c_speed,
214 unsigned char FAR *buffer,
215 unsigned long num_bytes,
218 unsigned long slave_addr = 0;
220 if(i2c_bus == I2C_INT_LVDS_DDC){
222 * Atom E6xx LVDS does not have GMBUS support. To read DDC register, we bit bash.
223 * The i2c_speed is necessary to calculate the hold time. But i2c_bus is not needed.
226 EMGD_DEBUG("i2c_read_regs_tnc : Using GPIO to read DDC");
227 return i2c_read_regs_gpio(context, i2c_bus, i2c_speed, dab, reg, buffer, num_bytes, flags);
231 if (! gmbus_init(i2c_bus, i2c_speed)) {
232 EMGD_DEBUG("Error ! i2c_read_regs_tnc : gmbus_init() failed");
236 /* If the request is to read Edid from sDVO display, find out the */
237 /* i2c addres of the sDVO device */
238 if (i2c_bus == GMBUS_DVOB_DDC) {
239 slave_addr = dvob_port_tnc.dab;
243 case GMBUS_DVOB_DDC :
244 if (! gmbus_read_edid(dab, slave_addr, reg, num_bytes, buffer)) {
246 EMGD_DEBUG("Error ! i2c_read_regs_tnc : gmbus_read_edid() failed");
252 if (! gmbus_read_reg(dab, reg, buffer)) {
254 EMGD_DEBUG("Error ! i2c_read_regs_tnc : gmbus_read_reg() failed");
260 EMGD_ERROR("Error ! i2c_read_regs_tnc : Invalid i2c_bus=0x%lx",
270 * i2c_write_reg_list_tnc is called to write a list of i2c registers to sDVO
274 * @param i2c_bus NAP_GMBUS_DVOB_DDC/NAP_GMBUS_DVOC_DDC
275 * @param i2c_speed 1000 Khz
276 * @param dab 0x70/0x72
277 * @param reg_list List of i2c indexes and data, terminated with register index
278 * set to PD_REG_LIST_END
280 * @return 0 on success
281 * @return 1 on failure
283 static int i2c_write_reg_list_tnc(igd_context_t *context,
284 unsigned long i2c_bus,
285 unsigned long i2c_speed,
290 unsigned long reg_num = 0, ddc_addr = 0, slave_addr = 0;
292 if(i2c_bus == I2C_INT_LVDS_DDC){
293 /* There are no GMBUS pins for internal LVDS on Atom E6xx.
294 * Forcing us to use bit bashing */
295 /* FIXME: determine which GPIO pin is used for bit bashing
296 * i2c_bus is not defined
298 EMGD_DEBUG("i2c_write_reg_list_tnc : Using GPIO to write DDC");
299 return i2c_write_reg_list_gpio(context, i2c_bus, i2c_speed, dab, reg_list, flags);
303 if (! gmbus_init(i2c_bus, i2c_speed)) {
305 EMGD_DEBUG("Error ! i2c_write_reg_list_tnc : gmbus_init() failed");
308 /*If it is SDVO Make sure we issue SDVO command to enable DDC access*/
309 if (i2c_bus == GMBUS_DVOB_DDC) {
310 slave_addr = dvob_port_tnc.dab;
313 if (! gmbus_set_control_bus_switch(slave_addr, ddc_addr)) {
314 EMGD_DEBUG("Error ! i2c_write_reg_list_tnc : gmbus_set_control_bus_switch()"
318 while (reg_list[reg_num].reg != PD_REG_LIST_END) {
320 if (! gmbus_write_reg(dab, reg_list[reg_num].reg,
321 (unsigned char)reg_list[reg_num].value)) {
323 EMGD_DEBUG("Error ! i2c_write_reg_list_tnc : gmbus_write_reg() failed, reg_num=%lu",
330 /*...................................................................... */
331 /* Issue a Stop Command */
332 gmbus_wait_event_one(HW_WAIT);
333 WRITE_GMCH_REG(GMBUS1, STO | SW_RDY | ddc_addr);
334 gmbus_wait_event_one(HW_RDY);
335 gmbus_wait_event_zero(GA);
336 gmbus_error_handler();
337 WRITE_GMCH_REG(GMBUS1, SW_RDY);
338 WRITE_GMCH_REG(GMBUS1, SW_CLR_INT);
339 WRITE_GMCH_REG(GMBUS1, 0);
340 WRITE_GMCH_REG(GMBUS5, 0);
341 WRITE_GMCH_REG(GMBUS0, 0);
342 /*...................................................................... */
345 while (reg_list[reg_num].reg != PD_REG_LIST_END) {
347 if (! gmbus_write_reg(dab, reg_list[reg_num].reg,
348 (unsigned char)reg_list[reg_num].value)) {
350 EMGD_DEBUG("Error ! i2c_write_reg_list_tnc : gmbus_write_reg() failed, reg_num=%lu",
364 * gmbus_init initializes the GMBUS controller with specified bus and speed
366 * @param i2c_bus sDVO B/C Reg/DDC or Analog DDC
367 * @param i2c_speed 50/100/400/1000 Khz
369 * @return TRUE(1) on success
370 * @return FALSE(0) on failure
372 static int gmbus_init(unsigned long i2c_bus,
373 unsigned long i2c_speed)
375 gmbus_pins_pair_t pin_pair;
376 gmbus_speed_t bus_speed;
381 case GMBUS_DVOB_DDC :
382 pin_pair = GMBUS_PINS_SDVO;
386 EMGD_ERROR("Error ! gmbus_init : Invalid i2c_bus=0x%lx", i2c_bus);
392 case 50 : /* Slow speed */
393 bus_speed = GMBUS_SPEED_50K;
397 bus_speed = GMBUS_SPEED_400K;
400 case 1000 : /* sDVO Registers */
401 //bus_speed = GMBUS_SPEED_1000K;
402 bus_speed = GMBUS_SPEED_400K;
407 bus_speed = GMBUS_SPEED_100K;
411 WRITE_GMCH_REG(GMBUS5, 0); /* Clear the word index reg */
412 WRITE_GMCH_REG(GMBUS0, pin_pair | bus_speed);
418 * gmbus_wait_event_zero waits for specified GMBUS2 register bit to be deasserted
422 * @return TRUE(1) on success. The bit was deasserted in the specified timeout period
423 * @return FALSE(0) on failure
425 static int gmbus_wait_event_zero(unsigned long bit)
428 unsigned long status;
430 for (i = 0; i < 0x1000; i++) {
432 status = READ_GMCH_REG(GMBUS2);
434 if ((status & bit) == 0) {
440 EMGD_DEBUG("Error ! gmbus_wait_event_zero : Failed : bit=0x%lx, status=0x%lx",
447 * gmbus_wait_event_one wait for specified GMBUS2 register bits to be asserted
451 * @return TRUE(1) on success. The bit was asserted in the specified timeout period
452 * @return FALSE(0) on failure
454 static int gmbus_wait_event_one(unsigned long bit)
457 unsigned long status;
459 for (i = 0; i < 0x10000; i++) {
461 status = READ_GMCH_REG(GMBUS2);
462 if ((status & bit) != 0) {
468 EMGD_DEBUG("Error ! gmbus_wait_event_one : Failed : bit=0x%lx, status=0x%lx",
475 * gmbus_error_handler attempts to recover from timeout error
478 * @return TRUE(1) error was detected and handled
479 * @return FALSE(0) there was no error
481 static int gmbus_error_handler(void)
483 unsigned long status = READ_GMCH_REG(GMBUS2);
485 /* Clear the SW_INT, wait for HWRDY and GMBus active (GA) */
486 if ((status & HW_BUS_ERR) || (status & HW_TMOUT)) {
488 EMGD_DEBUG("Error ! gmbus_error_handler : Resolving error=0x%lx",
491 WRITE_GMCH_REG(GMBUS1, SW_RDY);
492 WRITE_GMCH_REG(GMBUS1, SW_CLR_INT);
493 WRITE_GMCH_REG(GMBUS1, 0);
495 gmbus_wait_event_zero(GA);
497 return 1; /* Handled the error */
500 return 0; /* There was no error */
504 * Assemble 32 bit GMBUS1 command
506 * @param slave_addr 0x70/0x72
507 * @param index 0 - 256
508 * @param num_bytes Bytes to transfer
509 * @param flags Bits 25-31 of GMBUS1
510 * @param i2c_dir I2C_READ / I2C_WRITE
512 * @return The assembled command
514 static unsigned long gmbus_assemble_command(unsigned long slave_addr, unsigned long index,
515 unsigned long num_bytes, unsigned long flags,
516 i2c_bus_dir_t i2c_dir)
518 unsigned long cmd = flags | ENIDX | ENT | (num_bytes << 16) | (index << 8) |
519 slave_addr | i2c_dir;
525 * gmbus_send_pkt transmits a block a data to specified i2c slave device
527 * @param slave_addr I2C device address
528 * @param index Starting i2c register index
529 * @param pkt_size 1 - 508 bytes
530 * @param pkt Bytes to send
532 * @return TRUE(1) if successful in sending the specified number of bytes
533 * @return FALSE(0) on failure
535 static int gmbus_send_pkt(unsigned long slave_addr, unsigned long index,
536 unsigned long pkt_size, void *pkt)
538 unsigned long gmbus1_cmd;
539 unsigned long bytes_sent;
542 if ((pkt_size == 0) || (pkt == NULL) || (pkt_size > 508)) {
547 data = (unsigned long *)pkt;
549 /*...................................................................... */
550 gmbus_error_handler();
552 gmbus1_cmd = gmbus_assemble_command(slave_addr, index, pkt_size,
556 gmbus1_cmd |= SW_RDY;
559 /*...................................................................... */
564 WRITE_GMCH_REG(GMBUS3, *data);
566 if (bytes_sent == 0) {
568 WRITE_GMCH_REG(GMBUS1, gmbus1_cmd);
571 if (! gmbus_wait_event_one(HW_RDY)) {
573 EMGD_DEBUG("Error ! gmbus_send_pkt : Failed to get HW_RDY, bytes_sent=%ld",
579 if (gmbus_error_handler()) {
581 EMGD_DEBUG("Error ! gmbus_send_pkt : gmbus error, bytes_sent=%ld",
593 bytes_sent += pkt_size;
596 } while (bytes_sent < pkt_size);
598 /*...................................................................... */
599 if (bytes_sent != pkt_size) {
610 * gmbus_recv_pkt reads a block of data from specified i2c slave device
612 * @param slave_addr I2C device address
613 * @param index Starting i2c register index
614 * @param pkt_size 1 - 508 bytes
615 * @param pkt Bytes to send
617 * @return TRUE(1) if successful in receiving specified number of bytes
618 * @return FALSE(0) on failure
620 static int gmbus_recv_pkt(unsigned long slave_addr, unsigned long index,
621 unsigned long pkt_size, void FAR *pkt)
623 unsigned long gmbus1_cmd;
624 unsigned long bytes_rcvd;
625 unsigned long FAR *data;
627 if ((pkt_size == 0) || (pkt == NULL) || (pkt_size > 508)) {
632 data = (unsigned long FAR *)pkt;
634 /*...................................................................... */
635 gmbus_error_handler();
637 /* Program the command */
638 gmbus1_cmd = gmbus_assemble_command(slave_addr, index, pkt_size,
639 STA | SW_RDY, I2C_READ);
640 WRITE_GMCH_REG(GMBUS1, gmbus1_cmd);
642 /*...................................................................... */
646 unsigned long gmbus3_data;
647 unsigned long bytes_left = pkt_size - bytes_rcvd;
649 if (! gmbus_wait_event_one(HW_RDY)) {
651 EMGD_DEBUG("Error ! gmbus_recv_pkt : Failed to get HW_RDY, "
652 "bytes_rcvd=%ld", bytes_rcvd);
656 if (gmbus_error_handler()) {
658 EMGD_DEBUG("Error ! gmbus_recv_pkt : gmbus error, bytes_rcvd=%ld",
663 gmbus3_data = READ_GMCH_REG(GMBUS3);
665 switch (bytes_left) {
668 *(unsigned char *)data = (unsigned char)gmbus3_data;
672 *(unsigned short *)data = (unsigned short)gmbus3_data;
677 unsigned char *dest = (unsigned char *)data;
678 unsigned char *src = (unsigned char *)&(gmbus3_data);
691 if (bytes_left > 4) {
696 bytes_rcvd += bytes_left;
700 } while (bytes_rcvd < pkt_size);
702 /*...................................................................... */
703 if (bytes_rcvd < pkt_size) {
712 * gmbus_set_control_bus_switch sends sDVO command to switch i2c bus to read EDID
715 * @param slave_addr sDVO device address (0x70/0x72)
716 * @param ddc_addr DDC1_ADDR/DDC2_ADDR
718 * @return TRUE(1) if successful in sending the opcode
719 * @return FALSE(0) on failure
721 static int gmbus_set_control_bus_switch(unsigned long slave_addr,
722 gmbus_ddc_addr_t ddc_addr)
725 sdvo_bus_switch_t bus_switch;
728 bus_switch = SDVO_BUS_DDC1;
730 /*...................................................................... */
731 /* Transmit the Arguments */
732 if (! gmbus_send_pkt(slave_addr, SDVO_INDEX_PARAM_1, 1, &bus_switch)) {
734 EMGD_DEBUG("Error ! gmbus_set_control_bus_switch : gmbus_send_pkt() failed");
739 /*...................................................................... */
740 /* Generate I2C stop cycle */
741 gmbus_wait_event_one(HW_WAIT);
742 WRITE_GMCH_REG(GMBUS1, STO | SW_RDY | slave_addr);
743 gmbus_wait_event_one(HW_RDY);
744 gmbus_wait_event_zero(GA);
746 /*...................................................................... */
747 /* Transmit the Opcode */
748 data = SDVO_OPCODE_BUS_SWITCH;
749 if (! gmbus_send_pkt(slave_addr, SDVO_INDEX_OPCODE, 1, &data)) {
751 EMGD_DEBUG("Error ! gmbus_set_control_bus_switch : gmbus_send_pkt(Opcode)"
757 /*...................................................................... */
759 for (retry = 0; retry < 3; retry++) {
760 if (! gmbus_recv_pkt(slave_addr, SDVO_INDEX_STATUS, 1, &data)) {
765 if (data != SDVO_STATUS_PENDING) {
771 /*...................................................................... */
773 gmbus_wait_event_one(HW_WAIT);
774 WRITE_GMCH_REG(GMBUS1, STO | SW_RDY | slave_addr);
775 gmbus_wait_event_one(HW_RDY);
776 gmbus_wait_event_zero(GA);
778 /*...................................................................... */
779 if (data != SDVO_STATUS_SUCCESS) {
781 EMGD_DEBUG("Error ! gmbus_set_control_bus_switch : Opcode Bus Switch failed");
790 * gmbus_read_edid reads specified number of Edid data bytes
792 * @param ddc_addr 0xA0/0xA2 (DDC1/DDC2)
793 * @param slave_addr 0x70/0x72 (sDVOB, sDVOC), 0 Analog
794 * @param index i2c register index
795 * @param num_bytes <= 508
796 * @param buffer Edid data read from the display
798 * @return TRUE(1) if successful in reading Edid
799 * @return FALSE(0) on failure
801 static int gmbus_read_edid(unsigned long ddc_addr,
802 unsigned long slave_addr,
804 unsigned long num_bytes,
805 unsigned char FAR *buffer)
809 if (slave_addr == SDVOB_ADDR) {
811 if (! gmbus_set_control_bus_switch(slave_addr, ddc_addr)) {
813 EMGD_DEBUG("Error ! gmbus_read_edid : gmbus_set_control_bus_switch()"
820 gmbus_recv_pkt(ddc_addr, 0, 1, buffer);
823 status = gmbus_recv_pkt(ddc_addr, index, num_bytes, buffer);
826 EMGD_DEBUG("Error ! gmbus_read_edid : gmbus_recv_pkt() failed");
829 /*...................................................................... */
830 /* Issue a Stop Command */
832 gmbus_wait_event_one(HW_WAIT);
833 WRITE_GMCH_REG(GMBUS1, STO | SW_RDY | ddc_addr);
834 gmbus_wait_event_one(HW_RDY);
836 gmbus_wait_event_zero(GA);
838 gmbus_error_handler();
839 WRITE_GMCH_REG(GMBUS1, SW_RDY);
840 WRITE_GMCH_REG(GMBUS1, SW_CLR_INT);
841 WRITE_GMCH_REG(GMBUS1, 0);
842 WRITE_GMCH_REG(GMBUS5, 0);
843 WRITE_GMCH_REG(GMBUS0, 0);
845 /*...................................................................... */
850 * gmbus_read_reg reads one i2c register
852 * @param slave_addr 0x70/0x72 (sDVOB, sDVOC)
853 * @param index i2c register index
854 * @param data register data
856 * @return TRUE(1) if successful in reading the i2c register
857 * @return FALSE(0) on failure
859 static int gmbus_read_reg(unsigned long slave_addr,
861 unsigned char FAR *data)
863 unsigned long gmbus1_cmd;
865 WRITE_GMCH_REG(GMBUS5, 0x0); /* Clear Word Index register */
867 if (! gmbus_wait_event_zero(GA)) {
869 EMGD_DEBUG("Error ! gmbus_read_reg : Failed to get GA(1)");
874 gmbus1_cmd = gmbus_assemble_command(slave_addr, index, 1,
875 STO | STA, I2C_READ);
876 WRITE_GMCH_REG(GMBUS1, gmbus1_cmd);
878 if (! gmbus_wait_event_zero(GA)) {
880 EMGD_DEBUG("Error ! gmbus_read_reg : Failed to get GA(2)");
885 *data = (unsigned char)READ_GMCH_REG(GMBUS3);
891 * gmbus_write_reg writes one i2c register
893 * @param slave_addr 0x70/0x72 (sDVOB, sDVOC)
894 * @param index i2c register index
895 * @param data register data
897 * @return TRUE(1) if successful in updating the i2c register
898 * @return FALSE(0) if failed to update the register
900 static int gmbus_write_reg(unsigned long slave_addr,
904 unsigned long gmbus1_cmd;
906 WRITE_GMCH_REG(GMBUS5, 0x0); /* Clear Word Index register */
908 if (! gmbus_wait_event_zero(GA)) {
910 EMGD_DEBUG("Error ! gmbus_write_reg : Failed to get GA(1)");
915 WRITE_GMCH_REG(GMBUS3, data);
917 gmbus1_cmd = gmbus_assemble_command(slave_addr, index, 1,
918 STO | STA, I2C_WRITE);
919 WRITE_GMCH_REG(GMBUS1, gmbus1_cmd);
921 if (! gmbus_wait_event_zero(GA)) {
923 EMGD_DEBUG("Error ! gmbus_write_reg : Failed to get GA(2)");