blob: 368a6bf99f2c9cac72acabf7bd311c9075cbd331 [file] [log] [blame]
Patrick Georgiac959032020-05-05 22:49:26 +02001/* SPDX-License-Identifier: GPL-2.0-only */
Vladimir Serbinenko1b12ef12014-02-21 07:21:00 +01002
Kyösti Mälkki13f66502019-03-03 08:01:05 +02003#include <device/mmio.h>
Vladimir Serbinenko1b12ef12014-02-21 07:21:00 +01004#include <console/console.h>
5#include <delay.h>
6
7#include "i915_reg.h"
8#include "edid.h"
Sebastian "Swift Geek" Grzywna7e516fb2016-09-08 01:50:32 +02009#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 */
Vladimir Serbinenko1b12ef12014-02-21 07:21:00 +010015
Kevin Paul Herbertbde6d302014-12-24 18:43:20 -080016static void wait_rdy(u8 *mmio)
Vladimir Serbinenko1b12ef12014-02-21 07:21:00 +010017{
Martin Roth38ddbfb2019-10-23 21:41:00 -060018 unsigned int try = 100;
Vladimir Serbinenko1b12ef12014-02-21 07:21:00 +010019
20 while (try--) {
Sebastian "Swift Geek" Grzywna7e516fb2016-09-08 01:50:32 +020021 if (read32(GMBUS2_ADDR) & GMBUS_HW_RDY)
Vladimir Serbinenko1b12ef12014-02-21 07:21:00 +010022 return;
23 udelay(10);
24 }
25}
26
Elyes HAOUASb0b0c8c2018-07-08 12:33:47 +020027static void intel_gmbus_stop_bus(u8 *mmio, u8 bus)
Vladimir Serbinenko38cf94b2015-05-13 09:30:09 +020028{
29 wait_rdy(mmio);
Sebastian "Swift Geek" Grzywna7e516fb2016-09-08 01:50:32 +020030 write32(GMBUS0_ADDR, bus);
Vladimir Serbinenko38cf94b2015-05-13 09:30:09 +020031 wait_rdy(mmio);
Sebastian "Swift Geek" Grzywna7e516fb2016-09-08 01:50:32 +020032 write32(GMBUS5_ADDR, 0);
33 write32(GMBUS1_ADDR, GMBUS_SW_RDY | GMBUS_CYCLE_WAIT | GMBUS_CYCLE_INDEX
Elyes HAOUASa342f392018-10-17 10:56:26 +020034 | GMBUS_CYCLE_STOP | (0x4 << GMBUS_BYTE_COUNT_SHIFT)
35 | GMBUS_SLAVE_READ | (AT24_ADDR << 1));
Vladimir Serbinenko38cf94b2015-05-13 09:30:09 +020036 wait_rdy(mmio);
Sebastian "Swift Geek" Grzywna7e516fb2016-09-08 01:50:32 +020037 write32(GMBUS5_ADDR, 0);
38 write32(GMBUS1_ADDR, GMBUS_SW_CLR_INT);
39 write32(GMBUS1_ADDR, 0);
Vladimir Serbinenko38cf94b2015-05-13 09:30:09 +020040 wait_rdy(mmio);
Sebastian "Swift Geek" Grzywna7e516fb2016-09-08 01:50:32 +020041 write32(GMBUS1_ADDR, GMBUS_SW_RDY | GMBUS_CYCLE_STOP | GMBUS_SLAVE_WRITE
Elyes HAOUASa342f392018-10-17 10:56:26 +020042 | (AT24_ADDR << 1));
Vladimir Serbinenko38cf94b2015-05-13 09:30:09 +020043 wait_rdy(mmio);
Sebastian "Swift Geek" Grzywna34e10872016-09-08 02:05:31 +020044 write32(GMBUS1_ADDR, GMBUS_SW_RDY | GMBUS_CYCLE_STOP);
Sebastian "Swift Geek" Grzywna7e516fb2016-09-08 01:50:32 +020045 write32(GMBUS2_ADDR, GMBUS_INUSE);
Vladimir Serbinenko38cf94b2015-05-13 09:30:09 +020046}
47
48void intel_gmbus_stop(u8 *mmio)
49{
50 intel_gmbus_stop_bus(mmio, 6);
51 intel_gmbus_stop_bus(mmio, 2);
52}
53
Kevin Paul Herbertbde6d302014-12-24 18:43:20 -080054void intel_gmbus_read_edid(u8 *mmio, u8 bus, u8 slave, u8 *edid, u32 edid_size)
Vladimir Serbinenko1b12ef12014-02-21 07:21:00 +010055{
56 int i;
57
58 slave &= 0x7f;
59 edid_size &= 0x1fc;
60
61 wait_rdy(mmio);
62 /* 100 KHz, hold 0ns, */
Sebastian "Swift Geek" Grzywna7e516fb2016-09-08 01:50:32 +020063 write32(GMBUS0_ADDR, bus);
Vladimir Serbinenko1b12ef12014-02-21 07:21:00 +010064 wait_rdy(mmio);
65 /* Ensure index bits are disabled. */
Sebastian "Swift Geek" Grzywna7e516fb2016-09-08 01:50:32 +020066 write32(GMBUS5_ADDR, 0);
67 write32(GMBUS1_ADDR, GMBUS_SW_RDY | GMBUS_CYCLE_WAIT | GMBUS_CYCLE_INDEX
Elyes HAOUASa342f392018-10-17 10:56:26 +020068 | (slave << 1));
Vladimir Serbinenko1b12ef12014-02-21 07:21:00 +010069 wait_rdy(mmio);
70 /* Ensure index bits are disabled. */
Sebastian "Swift Geek" Grzywna7e516fb2016-09-08 01:50:32 +020071 write32(GMBUS5_ADDR, 0);
72 write32(GMBUS1_ADDR, GMBUS_SW_RDY | GMBUS_SLAVE_READ | GMBUS_CYCLE_WAIT
73 | GMBUS_CYCLE_STOP
Elyes HAOUASa342f392018-10-17 10:56:26 +020074 | (edid_size << GMBUS_BYTE_COUNT_SHIFT) | (slave << 1));
Vladimir Serbinenko1b12ef12014-02-21 07:21:00 +010075 for (i = 0; i < edid_size / 4; i++) {
76 u32 reg32;
77 wait_rdy(mmio);
Sebastian "Swift Geek" Grzywna7e516fb2016-09-08 01:50:32 +020078 reg32 = read32(GMBUS3_ADDR);
Vladimir Serbinenko1b12ef12014-02-21 07:21:00 +010079 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);
Sebastian "Swift Geek" Grzywna7e516fb2016-09-08 01:50:32 +020085 write32(GMBUS1_ADDR, GMBUS_SW_RDY
86 | GMBUS_SLAVE_WRITE | GMBUS_CYCLE_WAIT | GMBUS_CYCLE_STOP
Elyes HAOUASa342f392018-10-17 10:56:26 +020087 | (128 << GMBUS_BYTE_COUNT_SHIFT) | (slave << 1));
Vladimir Serbinenko1b12ef12014-02-21 07:21:00 +010088 wait_rdy(mmio);
Elyes HAOUASa342f392018-10-17 10:56:26 +020089 write32(GMBUS1_ADDR, GMBUS_SW_RDY | GMBUS_CYCLE_STOP);
Sebastian "Swift Geek" Grzywna7e516fb2016-09-08 01:50:32 +020090 write32(GMBUS2_ADDR, GMBUS_INUSE);
Vladimir Serbinenko1b12ef12014-02-21 07:21:00 +010091
Elyes Haouas34677042023-08-26 16:42:11 +020092 printk(BIOS_SPEW, "EDID:\n");
Vladimir Serbinenko1b12ef12014-02-21 07:21:00 +010093 for (i = 0; i < 128; i++) {
Paul Menzel75c5ead2020-02-15 13:57:41 +010094 printk(BIOS_SPEW, " %02x", edid[i]);
Vladimir Serbinenko1b12ef12014-02-21 07:21:00 +010095 if ((i & 0xf) == 0xf)
96 printk (BIOS_SPEW, "\n");
97 }
98}