1 /* SPDX-License-Identifier: GPL-2.0-only */
3 #include <device/mmio.h>
4 #include <console/console.h>
9 #define GMBUS0_ADDR (mmio + 4 * 0)
10 #define GMBUS1_ADDR (mmio + 4 * 1)
11 #define GMBUS2_ADDR (mmio + 4 * 2)
12 #define GMBUS3_ADDR (mmio + 4 * 3)
13 #define GMBUS5_ADDR (mmio + 4 * 8)
14 #define AT24_ADDR 0x50 /* EDID EEPROM */
16 static void wait_rdy(u8
*mmio
)
18 unsigned int try = 100;
21 if (read32(GMBUS2_ADDR
) & GMBUS_HW_RDY
)
27 static void intel_gmbus_stop_bus(u8
*mmio
, u8 bus
)
30 write32(GMBUS0_ADDR
, bus
);
32 write32(GMBUS5_ADDR
, 0);
33 write32(GMBUS1_ADDR
, GMBUS_SW_RDY
| GMBUS_CYCLE_WAIT
| GMBUS_CYCLE_INDEX
34 | GMBUS_CYCLE_STOP
| (0x4 << GMBUS_BYTE_COUNT_SHIFT
)
35 | GMBUS_SLAVE_READ
| (AT24_ADDR
<< 1));
37 write32(GMBUS5_ADDR
, 0);
38 write32(GMBUS1_ADDR
, GMBUS_SW_CLR_INT
);
39 write32(GMBUS1_ADDR
, 0);
41 write32(GMBUS1_ADDR
, GMBUS_SW_RDY
| GMBUS_CYCLE_STOP
| GMBUS_SLAVE_WRITE
44 write32(GMBUS1_ADDR
, GMBUS_SW_RDY
| GMBUS_CYCLE_STOP
);
45 write32(GMBUS2_ADDR
, GMBUS_INUSE
);
48 void intel_gmbus_stop(u8
*mmio
)
50 intel_gmbus_stop_bus(mmio
, 6);
51 intel_gmbus_stop_bus(mmio
, 2);
54 void intel_gmbus_read_edid(u8
*mmio
, u8 bus
, u8 slave
, u8
*edid
, u32 edid_size
)
62 /* 100 KHz, hold 0ns, */
63 write32(GMBUS0_ADDR
, bus
);
65 /* Ensure index bits are disabled. */
66 write32(GMBUS5_ADDR
, 0);
67 write32(GMBUS1_ADDR
, GMBUS_SW_RDY
| GMBUS_CYCLE_WAIT
| GMBUS_CYCLE_INDEX
70 /* Ensure index bits are disabled. */
71 write32(GMBUS5_ADDR
, 0);
72 write32(GMBUS1_ADDR
, GMBUS_SW_RDY
| GMBUS_SLAVE_READ
| GMBUS_CYCLE_WAIT
74 | (edid_size
<< GMBUS_BYTE_COUNT_SHIFT
) | (slave
<< 1));
75 for (i
= 0; i
< edid_size
/ 4; i
++) {
78 reg32
= read32(GMBUS3_ADDR
);
79 edid
[4 * i
] = reg32
& 0xff;
80 edid
[4 * i
+ 1] = (reg32
>> 8) & 0xff;
81 edid
[4 * i
+ 2] = (reg32
>> 16) & 0xff;
82 edid
[4 * i
+ 3] = (reg32
>> 24) & 0xff;
85 write32(GMBUS1_ADDR
, GMBUS_SW_RDY
86 | GMBUS_SLAVE_WRITE
| GMBUS_CYCLE_WAIT
| GMBUS_CYCLE_STOP
87 | (128 << GMBUS_BYTE_COUNT_SHIFT
) | (slave
<< 1));
89 write32(GMBUS1_ADDR
, GMBUS_SW_RDY
| GMBUS_CYCLE_STOP
);
90 write32(GMBUS2_ADDR
, GMBUS_INUSE
);
92 printk(BIOS_SPEW
, "EDID:\n");
93 for (i
= 0; i
< 128; i
++) {
94 printk(BIOS_SPEW
, " %02x", edid
[i
]);
96 printk(BIOS_SPEW
, "\n");