Move the drivers to a separate sub-directory
[profile/ivi/intel-emgd-kmod.git] / drivers / emgd / display / pi / plb / i2c_plb.c
1 /*
2  *-----------------------------------------------------------------------------
3  * Filename: i2c_plb.c
4  * $Revision: 1.14 $
5  *-----------------------------------------------------------------------------
6  * Copyright (c) 2002-2010, Intel Corporation.
7  *
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:
14  *
15  * The above copyright notice and this permission notice shall be included in
16  * all copies or substantial portions of the Software.
17  *
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
24  * THE SOFTWARE.
25  *
26  *-----------------------------------------------------------------------------
27  * Description:
28  *
29  *-----------------------------------------------------------------------------
30  */
31
32 #define MODULE_NAME hal.dpd
33
34 #include <io.h>
35 #include <memory.h>
36 #include <sched.h>
37
38 #include <igd_pwr.h>
39
40 #include <general.h>
41 #include <context.h>
42 #include <mode.h>
43 #include <utils.h>
44
45 #include <plb/regs.h>
46
47 #include "../cmn/i2c_dispatch.h"
48
49 /*!
50  * @addtogroup display_group
51  * @{
52  */
53
54 /*......................................................................... */
55 extern igd_display_port_t dvob_port_plb;
56
57 /*......................................................................... */
58 static int i2c_read_regs_plb(
59         igd_context_t *context,
60         unsigned long i2c_bus,
61         unsigned long i2c_speed,
62         unsigned long dab,
63         unsigned char reg,
64         unsigned char FAR *buffer,
65         unsigned long num_bytes,
66         unsigned long flags);
67
68 static int i2c_write_reg_list_plb(
69         igd_context_t *context,
70         unsigned long i2c_bus,
71         unsigned long i2c_speed,
72         unsigned long dab,
73         pd_reg_t *reg_list,
74         unsigned long flags);
75
76 i2c_dispatch_t i2c_dispatch_plb = {
77         i2c_read_regs_plb,
78         i2c_write_reg_list_plb,
79 };
80
81
82 /*.......................................................................... */
83 typedef enum {
84
85         GMBUS_SPEED_50K     = 0x0100,
86         GMBUS_SPEED_100K        = 0x0000,
87         GMBUS_SPEED_400K        = 0x0200,
88         GMBUS_SPEED_1000K       = 0x0300,
89
90 } gmbus_speed_t;
91
92 typedef enum {
93
94         SDVOB_ADDR      = 0x70,
95         SDVOC_ADDR      = 0x72,
96
97 } sdvo_dev_addr_t;
98
99 typedef enum {
100
101         DDC1_ADDR = 0xA0,
102         DDC2_ADDR = 0xA2,
103
104 } gmbus_ddc_addr_t;
105
106
107 typedef enum {
108
109         GMBUS_PINS_DEDICATED = 1, /* Dedicated Control/GMBUS Pins */
110         /* LCTRCLKA, LCTRLCLKB SSC Clock Device */
111         GMBUS_PINS_ANALOG       = 2,  /* Analog DDC */
112         GMBUS_PINS_INT_LVDS = 3,  /* Alviso : Integrated Digital Panel */
113         GMBUS_PINS_SDVO     = 5,  /* SDVO Registers, DDC, PROM */
114
115 } gmbus_pins_pair_t;
116
117
118 typedef enum {
119
120         I2C_WRITE = 0,
121         I2C_READ  = 1,
122
123 } i2c_bus_dir_t;
124
125 /*.......................................................................... */
126 typedef enum {
127
128         SDVO_BUS_PROM = BIT(0),
129         SDVO_BUS_DDC1 = BIT(1),
130         SDVO_BUS_DDC2 = BIT(2),
131
132 } sdvo_bus_switch_t;
133
134 #define SDVO_OPCODE_BUS_SWITCH  0x7A
135
136 #define SDVO_INDEX_PARAM_1              0x07
137 #define SDVO_INDEX_OPCODE               0x08
138 #define SDVO_INDEX_STATUS               0x09
139
140 #define SDVO_STATUS_SUCCESS     0x01
141 #define SDVO_STATUS_PENDING     0x04
142
143 /*.......................................................................... */
144 /*
145  * In 16-bit, the mmio is a 16-bit pointer, the watcom 1.2 compiler will have
146  * error if directly convert it to unsigned long.  Normally, have to cast it to
147  * unsigned short first then cast again to unsigned long; then, it will be
148  * correct.  But this type of casting may cause some error in the 32 and 64 bit
149  * code.  Since mmio will be equal to zero for 16-bit code.  Add the checking
150  * for MICRO definition code to correct the macro by remove mmio.
151  */
152 #define READ_GMCH_REG(reg)                      EMGD_READ32(EMGD_MMIO(mmio) + reg)
153 #define WRITE_GMCH_REG(reg, data)       EMGD_WRITE32(data, EMGD_MMIO(mmio) + reg)
154
155 static int gmbus_init(unsigned char *mmio, unsigned long i2c_bus,
156         unsigned long i2c_speed);
157
158 static int gmbus_read_edid(unsigned char *mmio,
159         unsigned long ddc_addr,
160         unsigned long slave_addr,
161         unsigned long index,
162         unsigned long num_bytes,
163         unsigned char FAR *buffer);
164
165 static int gmbus_read_reg(unsigned char *mmio,
166         unsigned long slave_addr,
167         unsigned long index,
168         unsigned char FAR *data);
169
170 static int gmbus_write_reg(unsigned char *mmio,
171         unsigned long slave_addr,
172         unsigned long index,
173         unsigned char data);
174
175 static int gmbus_set_control_bus_switch(unsigned char *mmio,
176         unsigned long slave_addr,
177         gmbus_ddc_addr_t ddc_addr);
178
179 static int gmbus_wait_event_one(unsigned char *mmio, unsigned long bit);
180 static int gmbus_wait_event_zero(unsigned char *mmio, unsigned long bit);
181 static int gmbus_error_handler(unsigned char *mmio);
182
183 /*!
184  * i2c_read_regs_plb is called to read Edid or a single sDVO register
185  *
186  * @param context
187  * @param i2c_bus port->ddc_reg, port->i2c_reg
188  * @param i2c_speed 50, 100, 400, 1000 (Khz)
189  * @param dab 0x70/0x72 (sDVO Regs), 0xA0/0xA2 (sDVO/Analog DDC)
190  * @param reg I2C Reg Index
191  * @param num_bytes <= 508
192  * @param buffer Data read
193  * @param flags unused, put in to match TNC func signature
194  *
195  * @return 0 on success
196  * @return 1 on failure
197  */
198 static int i2c_read_regs_plb(igd_context_t *context,
199         unsigned long i2c_bus,
200         unsigned long i2c_speed,
201         unsigned long dab,
202         unsigned char reg,
203         unsigned char FAR *buffer,
204         unsigned long num_bytes,
205         unsigned long flags)
206 {
207         unsigned char *mmio = EMGD_MMIO(context->device_context.virt_mmadr);
208         unsigned long slave_addr;
209
210         if (! gmbus_init(mmio, i2c_bus, i2c_speed)) {
211                 EMGD_DEBUG("Error ! i2c_read_regs_plb : gmbus_init() failed");
212                 return 1;
213         }
214
215         /*      If the request is to read Edid from sDVO display, find out the */
216         /*      i2c addres of the sDVO device */
217         if (i2c_bus == GMBUS_DVOB_DDC) {
218                 slave_addr = dvob_port_plb.dab;
219
220         } else {
221                 slave_addr = 0;
222
223         }
224
225         switch (i2c_bus) {
226         case GMBUS_ANALOG_DDC :
227         case GMBUS_INT_LVDS_DDC :
228         case GMBUS_DVOB_DDC :
229         case GMBUS_DVOC_DDC :
230                 if (! gmbus_read_edid(mmio, dab, slave_addr, reg, num_bytes, buffer)) {
231
232                         EMGD_DEBUG("Error ! i2c_read_regs_plb : gmbus_read_edid() failed");
233                         return 1;
234                 }
235                 break;
236
237         case GMBUS_DVO_REG :
238                 if (! gmbus_read_reg(mmio, dab, reg, buffer)) {
239
240                         EMGD_DEBUG("Error ! i2c_read_regs_plb : gmbus_read_reg() failed");
241                         return 1;
242                 }
243                 break;
244
245         default :
246                 EMGD_ERROR("Error ! i2c_read_regs_plb : Invalid i2c_bus=0x%lx",
247                         i2c_bus);
248                 return 1;
249         }
250
251         return 0;
252 }
253
254 /*!
255  * i2c_write_reg_list_plb is called to write a list of i2c registers to sDVO
256  * device
257  *
258  * @param context
259  * @param i2c_bus NAP_GMBUS_DVOB_DDC/NAP_GMBUS_DVOC_DDC
260  * @param i2c_speed 1000 Khz
261  * @param dab 0x70/0x72
262  * @param reg_list List of i2c indexes and data, terminated with register index
263  *  set to PD_REG_LIST_END
264  *
265  * @return 0 on success
266  * @return 1 on failure
267  */
268 static int i2c_write_reg_list_plb(igd_context_t *context,
269         unsigned long i2c_bus,
270         unsigned long i2c_speed,
271         unsigned long dab,
272         pd_reg_t *reg_list,
273         unsigned long flags)
274 {
275         unsigned char *mmio = EMGD_MMIO(context->device_context.virt_mmadr);
276         unsigned long reg_num = 0, ddc_addr = 0, slave_addr = 0;
277
278         if (! gmbus_init(mmio, i2c_bus, i2c_speed)) {
279
280                 EMGD_DEBUG("Error ! i2c_write_reg_list_plb : gmbus_init() failed");
281                 return 1;
282         }
283         /*If it is SDVO Make sure we issue SDVO command to enable DDC access*/
284         if ((i2c_bus == GMBUS_DVOB_DDC) || (i2c_bus == GMBUS_DVOC_DDC)) {
285                 if (i2c_bus == GMBUS_DVOB_DDC) {
286                         slave_addr = dvob_port_plb.dab;
287                 }else if (i2c_bus == GMBUS_DVOC_DDC) {
288                         /* Is DVOC available in PLB? */
289                         //slave_addr = dvoc_port_plb.dab;
290                         slave_addr = 0;
291                 }
292                 ddc_addr = 0;
293                 if (! gmbus_set_control_bus_switch(mmio, slave_addr, ddc_addr)) {
294                         EMGD_DEBUG("Error ! i2c_write_reg_list_plb : gmbus_set_control_bus_switch()"
295                                          " failed");
296                         return 1;
297                 }
298                 while (reg_list[reg_num].reg != PD_REG_LIST_END) {
299
300                         if (! gmbus_write_reg(mmio, dab, reg_list[reg_num].reg,
301                                           (unsigned char)reg_list[reg_num].value)) {
302
303                                 EMGD_DEBUG("Error ! i2c_write_reg_list_plb : gmbus_write_reg() failed, reg_num=%lu",
304                                         reg_num);
305
306                                 return 1;
307                         }
308                 reg_num++;
309                 }
310                 /*...................................................................... */
311                 /* Issue a Stop Command */
312                 gmbus_wait_event_one(mmio, HW_WAIT);
313                 WRITE_GMCH_REG(GMBUS1, STO | SW_RDY | ddc_addr);
314                 gmbus_wait_event_one(mmio, HW_RDY);
315                 gmbus_wait_event_zero(mmio, GA);
316                 gmbus_error_handler(mmio);
317                 WRITE_GMCH_REG(GMBUS1, SW_RDY);
318                 WRITE_GMCH_REG(GMBUS1, SW_CLR_INT);
319                 WRITE_GMCH_REG(GMBUS1, 0);
320                 WRITE_GMCH_REG(GMBUS5, 0);
321                 WRITE_GMCH_REG(GMBUS0, 0);
322                 /*...................................................................... */
323                 return 0;
324         }
325         while (reg_list[reg_num].reg != PD_REG_LIST_END) {
326
327                 if (! gmbus_write_reg(mmio, dab, reg_list[reg_num].reg,
328                                 (unsigned char)reg_list[reg_num].value)) {
329
330                         EMGD_DEBUG("Error ! i2c_write_reg_list_plb : gmbus_write_reg() failed, reg_num=%lu",
331                                 reg_num);
332
333                         return 1;
334                 }
335
336                 reg_num++;
337         }
338
339         return 0;
340 }
341
342 /*!
343  * gmbus_init initializes the GMBUS controller with specified bus and speed
344  *
345  * @param mmio
346  * @param i2c_bus sDVO B/C Reg/DDC or Analog DDC
347  * @param i2c_speed 50/100/400/1000 Khz
348  *
349  * @return TRUE(1) on success
350  * @return FALSE(0) on failure
351  */
352 static int gmbus_init(unsigned char *mmio, unsigned long i2c_bus,
353         unsigned long i2c_speed)
354 {
355         gmbus_pins_pair_t pin_pair;
356         gmbus_speed_t bus_speed;
357
358         switch (i2c_bus) {
359
360         case GMBUS_DVO_REG :
361         case GMBUS_DVOB_DDC :
362         case GMBUS_DVOC_DDC :
363                 pin_pair = GMBUS_PINS_SDVO;
364                 break;
365
366         case GMBUS_ANALOG_DDC :
367                 pin_pair = GMBUS_PINS_ANALOG;
368                 break;
369
370         case GMBUS_INT_LVDS_DDC :
371                 pin_pair = GMBUS_PINS_INT_LVDS;
372                 break;
373
374         default :
375                 EMGD_ERROR("Error ! gmbus_init : Invalid i2c_bus=0x%lx", i2c_bus);
376                 return 0;
377         }
378
379         switch (i2c_speed) {
380
381         case 50 :               /* Slow speed */
382                 bus_speed = GMBUS_SPEED_50K;
383                 break;
384
385         case 400 :              /* SPD */
386                 bus_speed = GMBUS_SPEED_400K;
387                 break;
388
389         case 1000 :     /* sDVO Registers */
390                 bus_speed = GMBUS_SPEED_1000K;
391                 break;
392
393         case 100 :      /* DDC */
394         default :
395                 bus_speed = GMBUS_SPEED_100K;
396                 break;
397         }
398
399         WRITE_GMCH_REG(GMBUS5, 0);   /* Clear the word index reg */
400         WRITE_GMCH_REG(GMBUS0, pin_pair | bus_speed);
401
402         return 1;
403 }
404
405 /*!
406  * gmbus_wait_event_zero waits for specified GMBUS2 register bit to be deasserted
407  *
408  * @param mmio
409  * @param bit
410  *
411  * @return TRUE(1) on success. The bit was deasserted in the specified timeout period
412  * @return FALSE(0) on failure
413  */
414 static int gmbus_wait_event_zero(unsigned char *mmio, unsigned long bit)
415 {
416         unsigned long i;
417         unsigned long status;
418
419         for (i = 0; i < 0x1000; i++) {
420
421                 status = READ_GMCH_REG(GMBUS2);
422
423                 if ((status & bit) == 0) {
424
425                         return 1;
426                 }
427         }
428
429         EMGD_DEBUG("Error ! gmbus_wait_event_zero : Failed : bit=0x%lx, status=0x%lx, forcing reset",
430                 bit, status);
431
432         /* If we are here, that means that the GBMUS is busy or in a bad
433          * state, the situation was observed
434          * that the GMBUS never becomes available (idle state) after S3.
435          * This results in the driver never being able to set the display.
436          *
437          * To fix this, we force force a reset of the GMBUS.
438          */
439         WRITE_GMCH_REG(GMBUS1, SW_RDY);
440         WRITE_GMCH_REG(GMBUS1, SW_CLR_INT);
441         WRITE_GMCH_REG(GMBUS1, 0);
442
443         return 1;
444 }
445
446 /*!
447  * gmbus_wait_event_one wait for specified GMBUS2 register bits to be asserted
448  *
449  * @param mmio
450  * @param bit
451  *
452  * @return TRUE(1) on success. The bit was asserted in the specified timeout period
453  * @return FALSE(0) on failure
454  */
455 static int gmbus_wait_event_one(unsigned char *mmio, unsigned long bit)
456 {
457         unsigned long i;
458         unsigned long status;
459
460         for (i = 0; i < 0x10000; i++) {
461
462                 status = READ_GMCH_REG(GMBUS2);
463                 if ((status & bit) != 0) {
464
465                         return 1;
466                 }
467         }
468
469         EMGD_DEBUG("Error ! gmbus_wait_event_one : Failed : bit=0x%lx, status=0x%lx",
470                 bit, status);
471
472         return 0;
473 }
474
475 /*!
476  * gmbus_error_handler attempts to recover from timeout error
477  *
478  * @param mmio
479  *
480  * @return TRUE(1) error was detected and handled
481  * @return FALSE(0) there was no error
482  */
483 static int gmbus_error_handler(unsigned char *mmio)
484 {
485         unsigned long status = READ_GMCH_REG(GMBUS2);
486
487         /* Clear the SW_INT, wait for HWRDY and GMBus active (GA) */
488         if ((status & HW_BUS_ERR) || (status & HW_TMOUT)) {
489
490                 EMGD_DEBUG("Error ! gmbus_error_handler : Resolving error=0x%lx",
491                         status);
492
493                 WRITE_GMCH_REG(GMBUS1, SW_RDY);
494                 WRITE_GMCH_REG(GMBUS1, SW_CLR_INT);
495                 WRITE_GMCH_REG(GMBUS1, 0);
496
497                 gmbus_wait_event_zero(mmio, GA);
498
499                 return 1;       /* Handled the error */
500         }
501
502         return 0;       /* There was no error */
503 }
504
505 /*!
506  * Assemble 32 bit GMBUS1 command
507  *
508  * @param slave_addr 0x70/0x72
509  * @param index 0 - 256
510  * @param num_bytes Bytes to transfer
511  * @param flags Bits 25-31 of GMBUS1
512  * @param i2c_dir I2C_READ / I2C_WRITE
513  *
514  * @return The assembled command
515  */
516 static unsigned long gmbus_assemble_command(unsigned long slave_addr, unsigned long index,
517         unsigned long num_bytes, unsigned long flags,
518         i2c_bus_dir_t i2c_dir)
519 {
520         unsigned long cmd = flags | ENIDX | ENT | (num_bytes << 16) | (index << 8) |
521                                                 slave_addr | i2c_dir;
522
523         return cmd;
524 }
525
526 /*!
527  * gmbus_send_pkt transmits a block a data to specified i2c slave device
528  *
529  * @param mmio
530  * @param slave_addr I2C device address
531  * @param index Starting i2c register index
532  * @param pkt_size 1 - 508 bytes
533  * @param pkt Bytes to send
534  *
535  * @return TRUE(1) if successful in sending the specified number of bytes
536  * @return FALSE(0) on failure
537  */
538 static int gmbus_send_pkt(unsigned char *mmio,
539         unsigned long slave_addr, unsigned long index,
540         unsigned long pkt_size, void *pkt)
541 {
542         unsigned long gmbus1_cmd;
543         unsigned long bytes_sent;
544         unsigned long *data;
545
546         if ((pkt_size == 0) || (pkt == NULL) || (pkt_size > 508)) {
547
548                 return 0;
549         }
550
551         data = (unsigned long *)pkt;
552
553         /*...................................................................... */
554         gmbus_error_handler(mmio);
555
556         gmbus1_cmd = gmbus_assemble_command(slave_addr, index, pkt_size,
557                                                                                 STA, I2C_WRITE);
558         if (pkt_size <= 4) {
559
560                 gmbus1_cmd |= SW_RDY;
561         }
562
563         /*...................................................................... */
564         bytes_sent = 0;
565
566         do {
567
568                 WRITE_GMCH_REG(GMBUS3, *data);
569
570                 if (bytes_sent == 0) {
571
572                         WRITE_GMCH_REG(GMBUS1, gmbus1_cmd);
573                 }
574
575                 if (! gmbus_wait_event_one(mmio, HW_RDY)) {
576
577                         EMGD_DEBUG("Error ! gmbus_send_pkt : Failed to get HW_RDY, bytes_sent=%ld",
578                                 bytes_sent);
579
580                         return 0;
581                 }
582
583                 if (gmbus_error_handler(mmio)) {
584
585                         EMGD_DEBUG("Error ! gmbus_send_pkt : gmbus error, bytes_sent=%ld",
586                                 bytes_sent);
587
588                         return 0;
589                 }
590
591                 data++;
592
593                 if (pkt_size >= 4) {
594                         bytes_sent += 4;
595
596                 } else {
597                         bytes_sent += pkt_size;
598                 }
599
600         } while (bytes_sent < pkt_size);
601
602         /*...................................................................... */
603         if (bytes_sent != pkt_size) {
604
605                 return 0;
606
607         } else {
608
609                 return 1;
610         }
611 }
612
613 /*!
614  * gmbus_recv_pkt reads a block of data from specified i2c slave device
615  *
616  * @param mmio
617  * @param slave_addr I2C device address
618  * @param index Starting i2c register index
619  * @param pkt_size 1 - 508 bytes
620  * @param pkt Bytes to send
621  *
622  * @return TRUE(1) if successful in receiving specified number of bytes
623  * @return FALSE(0) on failure
624  */
625 static int gmbus_recv_pkt(unsigned char *mmio,
626         unsigned long slave_addr, unsigned long index,
627         unsigned long pkt_size, void FAR *pkt)
628 {
629         unsigned long gmbus1_cmd;
630         unsigned long bytes_rcvd;
631         unsigned long FAR *data;
632
633         if ((pkt_size == 0) || (pkt == NULL) || (pkt_size > 508)) {
634
635                 return 0;
636         }
637
638         data = (unsigned long FAR *)pkt;
639
640         /*...................................................................... */
641         gmbus_error_handler(mmio);
642
643         /* Program the command */
644         gmbus1_cmd = gmbus_assemble_command(slave_addr, index, pkt_size,
645                                                                                 STA | SW_RDY, I2C_READ);
646         WRITE_GMCH_REG(GMBUS1, gmbus1_cmd);
647
648         /*...................................................................... */
649         bytes_rcvd = 0;
650         do {
651
652                 unsigned long gmbus3_data;
653                 unsigned long bytes_left = pkt_size - bytes_rcvd;
654
655                 if (! gmbus_wait_event_one(mmio, HW_RDY)) {
656
657                         EMGD_DEBUG("Error ! gmbus_recv_pkt : Failed to get HW_RDY, "
658                                 "bytes_rcvd=%ld", bytes_rcvd);
659                         break;
660                 }
661
662                 if (gmbus_error_handler(mmio)) {
663
664                         EMGD_DEBUG("Error ! gmbus_recv_pkt : gmbus error, bytes_rcvd=%ld",
665                                 bytes_rcvd);
666                         break;
667                 }
668
669                 gmbus3_data = READ_GMCH_REG(GMBUS3);
670
671                 switch (bytes_left) {
672
673                 case 1 :
674                         *(unsigned char *)data = (unsigned char)gmbus3_data;
675                         break;
676
677                 case 2 :
678                         *(unsigned short *)data = (unsigned short)gmbus3_data;
679                         break;
680
681                 case 3 :
682                 {
683                         unsigned char *dest = (unsigned char *)data;
684                          unsigned char *src  = (unsigned char *)&(gmbus3_data);
685                         dest[0] = src[0];
686                         dest[1] = src[1];
687                         dest[2] = src[2];
688
689                         break;
690                 }
691
692                 default :       /* >= 4 */
693                         *data = gmbus3_data;
694                         break;
695                 }
696
697                 if (bytes_left > 4) {
698                         bytes_rcvd += 4;
699                         data++;
700
701                 } else {
702                         bytes_rcvd += bytes_left;
703
704                 }
705
706         } while (bytes_rcvd < pkt_size);
707
708         /*...................................................................... */
709         if (bytes_rcvd < pkt_size) {
710                 return 0;
711
712         } else {
713                 return 1;
714         }
715 }
716
717 /*!
718  * gmbus_set_control_bus_switch sends sDVO command to switch i2c bus to read EDID
719  * or SPD data
720  *
721  * @param mmio
722  * @param slave_addr sDVO device address (0x70/0x72)
723  * @param ddc_addr DDC1_ADDR/DDC2_ADDR
724  *
725  * @return TRUE(1) if successful in sending the opcode
726  * @return FALSE(0) on failure
727  */
728 static int gmbus_set_control_bus_switch(unsigned char *mmio,
729         unsigned long slave_addr,
730         gmbus_ddc_addr_t ddc_addr)
731 {
732         unsigned char data;
733         sdvo_bus_switch_t bus_switch;
734         int retry;
735
736         bus_switch = SDVO_BUS_DDC1;
737
738         /*...................................................................... */
739         /*      Transmit the Arguments */
740         if (! gmbus_send_pkt(mmio, slave_addr, SDVO_INDEX_PARAM_1, 1, &bus_switch)) {
741
742                 EMGD_DEBUG("Error ! gmbus_set_control_bus_switch : gmbus_send_pkt() failed");
743
744                 return 0;
745         }
746
747         /*...................................................................... */
748         /* Generate I2C stop cycle */
749         gmbus_wait_event_one(mmio, HW_WAIT);
750         WRITE_GMCH_REG(GMBUS1, STO | SW_RDY | slave_addr);
751         gmbus_wait_event_one(mmio, HW_RDY);
752         gmbus_wait_event_zero(mmio, GA);
753
754         /*...................................................................... */
755         /* Transmit the Opcode */
756         data = SDVO_OPCODE_BUS_SWITCH;
757         if (! gmbus_send_pkt(mmio, slave_addr, SDVO_INDEX_OPCODE, 1, &data)) {
758
759                 EMGD_DEBUG("Error ! gmbus_set_control_bus_switch : gmbus_send_pkt(Opcode)"
760                                  " failed");
761
762                 return 0;
763         }
764
765         /*...................................................................... */
766         /* Read Status */
767         for (retry = 0; retry < 3; retry++) {
768                 if (! gmbus_recv_pkt(mmio, slave_addr, SDVO_INDEX_STATUS, 1, &data)) {
769
770                         continue;
771                 }
772
773                 if (data != SDVO_STATUS_PENDING) {
774
775                         break;
776                 }
777         }
778
779         /*...................................................................... */
780         /* Send Stop */
781         gmbus_wait_event_one(mmio, HW_WAIT);
782         WRITE_GMCH_REG(GMBUS1, STO | SW_RDY | slave_addr);
783         gmbus_wait_event_one(mmio, HW_RDY);
784         gmbus_wait_event_zero(mmio, GA);
785
786         /*...................................................................... */
787         if (data != SDVO_STATUS_SUCCESS) {
788
789                 EMGD_DEBUG("Error ! gmbus_set_control_bus_switch : Opcode Bus Switch failed");
790
791                 return 0;
792         }
793
794         return 1;
795 }
796
797 /*!
798  * gmbus_read_edid reads specified number of Edid data bytes
799  *
800  * @param mmio
801  * @param ddc_addr 0xA0/0xA2 (DDC1/DDC2)
802  * @param slave_addr 0x70/0x72 (sDVOB, sDVOC), 0 Analog
803  * @param index i2c register index
804  * @param num_bytes <= 508
805  * @param buffer Edid data read from the display
806  *
807  * @return TRUE(1) if successful in reading Edid
808  * @return FALSE(0) on failure
809  */
810 static int gmbus_read_edid(unsigned char *mmio,
811         unsigned long ddc_addr,
812         unsigned long slave_addr,
813         unsigned long index,
814         unsigned long num_bytes,
815         unsigned char FAR *buffer)
816 {
817         int status;
818
819         if ((slave_addr == SDVOB_ADDR) || (slave_addr == SDVOC_ADDR)) {
820
821                 if (! gmbus_set_control_bus_switch(mmio, slave_addr, ddc_addr)) {
822
823                         EMGD_DEBUG("Error ! gmbus_read_edid : gmbus_set_control_bus_switch()"
824                                          " failed");
825
826                         return 0;
827                 }
828         } else {
829                 /*      Reset the bus */
830                 gmbus_recv_pkt(mmio, ddc_addr, 0, 1, buffer);
831         }
832
833         status = gmbus_recv_pkt(mmio, ddc_addr, index, num_bytes, buffer);
834         if (! status) {
835
836                 EMGD_DEBUG("Error ! gmbus_read_edid : gmbus_recv_pkt() failed");
837         }
838
839         /*...................................................................... */
840         /* Issue a Stop Command */
841
842         gmbus_wait_event_one(mmio, HW_WAIT);
843         WRITE_GMCH_REG(GMBUS1, STO | SW_RDY | ddc_addr);
844         gmbus_wait_event_one(mmio, HW_RDY);
845
846         gmbus_wait_event_zero(mmio, GA);
847
848         gmbus_error_handler(mmio);
849         WRITE_GMCH_REG(GMBUS1, SW_RDY);
850         WRITE_GMCH_REG(GMBUS1, SW_CLR_INT);
851         WRITE_GMCH_REG(GMBUS1, 0);
852         WRITE_GMCH_REG(GMBUS5, 0);
853         WRITE_GMCH_REG(GMBUS0, 0);
854
855         /*...................................................................... */
856         return status;
857 }
858
859 /*!
860  * gmbus_read_reg reads one i2c register
861  *
862  * @param mmio
863  * @param slave_addr 0x70/0x72 (sDVOB, sDVOC)
864  * @param index i2c register index
865  * @param data register data
866  *
867  * @return TRUE(1) if successful in reading the i2c register
868  * @return FALSE(0) on failure
869  */
870 static int gmbus_read_reg(unsigned char *mmio,
871         unsigned long slave_addr,
872         unsigned long index,
873         unsigned char FAR *data)
874 {
875         unsigned long gmbus1_cmd;
876
877         WRITE_GMCH_REG(GMBUS5, 0x0);            /* Clear Word Index register */
878
879         if (! gmbus_wait_event_zero(mmio, GA)) {
880
881                 EMGD_DEBUG("Error ! gmbus_read_reg : Failed to get GA(1)");
882
883                 return 0;
884         }
885
886         gmbus1_cmd = gmbus_assemble_command(slave_addr, index, 1,
887                                                                                 STO | STA, I2C_READ);
888         WRITE_GMCH_REG(GMBUS1, gmbus1_cmd);
889
890         if (! gmbus_wait_event_zero(mmio, GA)) {
891
892                 EMGD_DEBUG("Error ! gmbus_read_reg : Failed to get GA(2)");
893
894                 return 0;
895         }
896
897         *data = (unsigned char)READ_GMCH_REG(GMBUS3);
898
899         return 1;
900 }
901
902 /*!
903  * gmbus_write_reg writes one i2c register
904  *
905  * @param mmio
906  * @param slave_addr 0x70/0x72 (sDVOB, sDVOC)
907  * @param index i2c register index
908  * @param data register data
909  *
910  * @return TRUE(1) if successful in updating the i2c register
911  * @return FALSE(0) if failed to update the register
912  */
913 static int gmbus_write_reg(unsigned char *mmio,
914         unsigned long slave_addr,
915         unsigned long index,
916         unsigned char data)
917 {
918         unsigned long gmbus1_cmd;
919
920         WRITE_GMCH_REG(GMBUS5, 0x0);            /* Clear Word Index register */
921
922         if (! gmbus_wait_event_zero(mmio, GA)) {
923
924                 EMGD_DEBUG("Error ! gmbus_write_reg : Failed to get GA(1)");
925
926                 return 0;
927         }
928
929         WRITE_GMCH_REG(GMBUS3, data);
930
931         gmbus1_cmd = gmbus_assemble_command(slave_addr, index, 1,
932                                                                                 STO | STA, I2C_WRITE);
933         WRITE_GMCH_REG(GMBUS1, gmbus1_cmd);
934
935         if (! gmbus_wait_event_zero(mmio, GA)) {
936
937                 EMGD_DEBUG("Error ! gmbus_write_reg : Failed to get GA(2)");
938                 return 0;
939         }
940
941         return 1;
942 }
943