• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 /* SPDX-License-Identifier: GPL-2.0-only */
2 
3 #include <device/mmio.h>
4 #include <console/console.h>
5 #include <delay.h>
6 
7 #include "i915_reg.h"
8 #include "edid.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 */
15 
wait_rdy(u8 * mmio)16 static void wait_rdy(u8 *mmio)
17 {
18 	unsigned int try = 100;
19 
20 	while (try--) {
21 		if (read32(GMBUS2_ADDR) & GMBUS_HW_RDY)
22 			return;
23 		udelay(10);
24 	}
25 }
26 
intel_gmbus_stop_bus(u8 * mmio,u8 bus)27 static void intel_gmbus_stop_bus(u8 *mmio, u8 bus)
28 {
29 	wait_rdy(mmio);
30 	write32(GMBUS0_ADDR, bus);
31 	wait_rdy(mmio);
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));
36 	wait_rdy(mmio);
37 	write32(GMBUS5_ADDR, 0);
38 	write32(GMBUS1_ADDR, GMBUS_SW_CLR_INT);
39 	write32(GMBUS1_ADDR, 0);
40 	wait_rdy(mmio);
41 	write32(GMBUS1_ADDR, GMBUS_SW_RDY | GMBUS_CYCLE_STOP | GMBUS_SLAVE_WRITE
42 		| (AT24_ADDR << 1));
43 	wait_rdy(mmio);
44 	write32(GMBUS1_ADDR, GMBUS_SW_RDY | GMBUS_CYCLE_STOP);
45 	write32(GMBUS2_ADDR, GMBUS_INUSE);
46 }
47 
intel_gmbus_stop(u8 * mmio)48 void intel_gmbus_stop(u8 *mmio)
49 {
50 	intel_gmbus_stop_bus(mmio, 6);
51 	intel_gmbus_stop_bus(mmio, 2);
52 }
53 
intel_gmbus_read_edid(u8 * mmio,u8 bus,u8 slave,u8 * edid,u32 edid_size)54 void intel_gmbus_read_edid(u8 *mmio, u8 bus, u8 slave, u8 *edid, u32 edid_size)
55 {
56 	int i;
57 
58 	slave &= 0x7f;
59 	edid_size &= 0x1fc;
60 
61 	wait_rdy(mmio);
62 	/* 100 KHz, hold 0ns,  */
63 	write32(GMBUS0_ADDR, bus);
64 	wait_rdy(mmio);
65 	/* Ensure index bits are disabled.  */
66 	write32(GMBUS5_ADDR, 0);
67 	write32(GMBUS1_ADDR, GMBUS_SW_RDY | GMBUS_CYCLE_WAIT | GMBUS_CYCLE_INDEX
68 		| (slave << 1));
69 	wait_rdy(mmio);
70 	/* Ensure index bits are disabled.  */
71 	write32(GMBUS5_ADDR, 0);
72 	write32(GMBUS1_ADDR, GMBUS_SW_RDY | GMBUS_SLAVE_READ | GMBUS_CYCLE_WAIT
73 		| GMBUS_CYCLE_STOP
74 		| (edid_size << GMBUS_BYTE_COUNT_SHIFT) | (slave << 1));
75 	for (i = 0; i < edid_size / 4; i++) {
76 		u32 reg32;
77 		wait_rdy(mmio);
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;
83 	}
84 	wait_rdy(mmio);
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));
88 	wait_rdy(mmio);
89 	write32(GMBUS1_ADDR, GMBUS_SW_RDY | GMBUS_CYCLE_STOP);
90 	write32(GMBUS2_ADDR, GMBUS_INUSE);
91 
92 	printk(BIOS_SPEW, "EDID:\n");
93 	for (i = 0; i < 128; i++) {
94 		printk(BIOS_SPEW, " %02x", edid[i]);
95 		if ((i & 0xf) == 0xf)
96 			printk(BIOS_SPEW, "\n");
97 	}
98 }
99