Patrick Georgi | ac95903 | 2020-05-05 22:49:26 +0200 | [diff] [blame] | 1 | /* SPDX-License-Identifier: GPL-2.0-only */ |
Vladimir Serbinenko | 1b12ef1 | 2014-02-21 07:21:00 +0100 | [diff] [blame] | 2 | |
Kyösti Mälkki | 13f6650 | 2019-03-03 08:01:05 +0200 | [diff] [blame] | 3 | #include <device/mmio.h> |
Vladimir Serbinenko | 1b12ef1 | 2014-02-21 07:21:00 +0100 | [diff] [blame] | 4 | #include <console/console.h> |
| 5 | #include <delay.h> |
| 6 | |
| 7 | #include "i915_reg.h" |
| 8 | #include "edid.h" |
Sebastian "Swift Geek" Grzywna | 7e516fb | 2016-09-08 01:50:32 +0200 | [diff] [blame] | 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 */ |
Vladimir Serbinenko | 1b12ef1 | 2014-02-21 07:21:00 +0100 | [diff] [blame] | 15 | |
Kevin Paul Herbert | bde6d30 | 2014-12-24 18:43:20 -0800 | [diff] [blame] | 16 | static void wait_rdy(u8 *mmio) |
Vladimir Serbinenko | 1b12ef1 | 2014-02-21 07:21:00 +0100 | [diff] [blame] | 17 | { |
Martin Roth | 38ddbfb | 2019-10-23 21:41:00 -0600 | [diff] [blame] | 18 | unsigned int try = 100; |
Vladimir Serbinenko | 1b12ef1 | 2014-02-21 07:21:00 +0100 | [diff] [blame] | 19 | |
| 20 | while (try--) { |
Sebastian "Swift Geek" Grzywna | 7e516fb | 2016-09-08 01:50:32 +0200 | [diff] [blame] | 21 | if (read32(GMBUS2_ADDR) & GMBUS_HW_RDY) |
Vladimir Serbinenko | 1b12ef1 | 2014-02-21 07:21:00 +0100 | [diff] [blame] | 22 | return; |
| 23 | udelay(10); |
| 24 | } |
| 25 | } |
| 26 | |
Elyes HAOUAS | b0b0c8c | 2018-07-08 12:33:47 +0200 | [diff] [blame] | 27 | static void intel_gmbus_stop_bus(u8 *mmio, u8 bus) |
Vladimir Serbinenko | 38cf94b | 2015-05-13 09:30:09 +0200 | [diff] [blame] | 28 | { |
| 29 | wait_rdy(mmio); |
Sebastian "Swift Geek" Grzywna | 7e516fb | 2016-09-08 01:50:32 +0200 | [diff] [blame] | 30 | write32(GMBUS0_ADDR, bus); |
Vladimir Serbinenko | 38cf94b | 2015-05-13 09:30:09 +0200 | [diff] [blame] | 31 | wait_rdy(mmio); |
Sebastian "Swift Geek" Grzywna | 7e516fb | 2016-09-08 01:50:32 +0200 | [diff] [blame] | 32 | write32(GMBUS5_ADDR, 0); |
| 33 | write32(GMBUS1_ADDR, GMBUS_SW_RDY | GMBUS_CYCLE_WAIT | GMBUS_CYCLE_INDEX |
Elyes HAOUAS | a342f39 | 2018-10-17 10:56:26 +0200 | [diff] [blame] | 34 | | GMBUS_CYCLE_STOP | (0x4 << GMBUS_BYTE_COUNT_SHIFT) |
| 35 | | GMBUS_SLAVE_READ | (AT24_ADDR << 1)); |
Vladimir Serbinenko | 38cf94b | 2015-05-13 09:30:09 +0200 | [diff] [blame] | 36 | wait_rdy(mmio); |
Sebastian "Swift Geek" Grzywna | 7e516fb | 2016-09-08 01:50:32 +0200 | [diff] [blame] | 37 | write32(GMBUS5_ADDR, 0); |
| 38 | write32(GMBUS1_ADDR, GMBUS_SW_CLR_INT); |
| 39 | write32(GMBUS1_ADDR, 0); |
Vladimir Serbinenko | 38cf94b | 2015-05-13 09:30:09 +0200 | [diff] [blame] | 40 | wait_rdy(mmio); |
Sebastian "Swift Geek" Grzywna | 7e516fb | 2016-09-08 01:50:32 +0200 | [diff] [blame] | 41 | write32(GMBUS1_ADDR, GMBUS_SW_RDY | GMBUS_CYCLE_STOP | GMBUS_SLAVE_WRITE |
Elyes HAOUAS | a342f39 | 2018-10-17 10:56:26 +0200 | [diff] [blame] | 42 | | (AT24_ADDR << 1)); |
Vladimir Serbinenko | 38cf94b | 2015-05-13 09:30:09 +0200 | [diff] [blame] | 43 | wait_rdy(mmio); |
Sebastian "Swift Geek" Grzywna | 34e1087 | 2016-09-08 02:05:31 +0200 | [diff] [blame] | 44 | write32(GMBUS1_ADDR, GMBUS_SW_RDY | GMBUS_CYCLE_STOP); |
Sebastian "Swift Geek" Grzywna | 7e516fb | 2016-09-08 01:50:32 +0200 | [diff] [blame] | 45 | write32(GMBUS2_ADDR, GMBUS_INUSE); |
Vladimir Serbinenko | 38cf94b | 2015-05-13 09:30:09 +0200 | [diff] [blame] | 46 | } |
| 47 | |
| 48 | void intel_gmbus_stop(u8 *mmio) |
| 49 | { |
| 50 | intel_gmbus_stop_bus(mmio, 6); |
| 51 | intel_gmbus_stop_bus(mmio, 2); |
| 52 | } |
| 53 | |
Kevin Paul Herbert | bde6d30 | 2014-12-24 18:43:20 -0800 | [diff] [blame] | 54 | void intel_gmbus_read_edid(u8 *mmio, u8 bus, u8 slave, u8 *edid, u32 edid_size) |
Vladimir Serbinenko | 1b12ef1 | 2014-02-21 07:21:00 +0100 | [diff] [blame] | 55 | { |
| 56 | int i; |
| 57 | |
| 58 | slave &= 0x7f; |
| 59 | edid_size &= 0x1fc; |
| 60 | |
| 61 | wait_rdy(mmio); |
| 62 | /* 100 KHz, hold 0ns, */ |
Sebastian "Swift Geek" Grzywna | 7e516fb | 2016-09-08 01:50:32 +0200 | [diff] [blame] | 63 | write32(GMBUS0_ADDR, bus); |
Vladimir Serbinenko | 1b12ef1 | 2014-02-21 07:21:00 +0100 | [diff] [blame] | 64 | wait_rdy(mmio); |
| 65 | /* Ensure index bits are disabled. */ |
Sebastian "Swift Geek" Grzywna | 7e516fb | 2016-09-08 01:50:32 +0200 | [diff] [blame] | 66 | write32(GMBUS5_ADDR, 0); |
| 67 | write32(GMBUS1_ADDR, GMBUS_SW_RDY | GMBUS_CYCLE_WAIT | GMBUS_CYCLE_INDEX |
Elyes HAOUAS | a342f39 | 2018-10-17 10:56:26 +0200 | [diff] [blame] | 68 | | (slave << 1)); |
Vladimir Serbinenko | 1b12ef1 | 2014-02-21 07:21:00 +0100 | [diff] [blame] | 69 | wait_rdy(mmio); |
| 70 | /* Ensure index bits are disabled. */ |
Sebastian "Swift Geek" Grzywna | 7e516fb | 2016-09-08 01:50:32 +0200 | [diff] [blame] | 71 | write32(GMBUS5_ADDR, 0); |
| 72 | write32(GMBUS1_ADDR, GMBUS_SW_RDY | GMBUS_SLAVE_READ | GMBUS_CYCLE_WAIT |
| 73 | | GMBUS_CYCLE_STOP |
Elyes HAOUAS | a342f39 | 2018-10-17 10:56:26 +0200 | [diff] [blame] | 74 | | (edid_size << GMBUS_BYTE_COUNT_SHIFT) | (slave << 1)); |
Vladimir Serbinenko | 1b12ef1 | 2014-02-21 07:21:00 +0100 | [diff] [blame] | 75 | for (i = 0; i < edid_size / 4; i++) { |
| 76 | u32 reg32; |
| 77 | wait_rdy(mmio); |
Sebastian "Swift Geek" Grzywna | 7e516fb | 2016-09-08 01:50:32 +0200 | [diff] [blame] | 78 | reg32 = read32(GMBUS3_ADDR); |
Vladimir Serbinenko | 1b12ef1 | 2014-02-21 07:21:00 +0100 | [diff] [blame] | 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); |
Sebastian "Swift Geek" Grzywna | 7e516fb | 2016-09-08 01:50:32 +0200 | [diff] [blame] | 85 | write32(GMBUS1_ADDR, GMBUS_SW_RDY |
| 86 | | GMBUS_SLAVE_WRITE | GMBUS_CYCLE_WAIT | GMBUS_CYCLE_STOP |
Elyes HAOUAS | a342f39 | 2018-10-17 10:56:26 +0200 | [diff] [blame] | 87 | | (128 << GMBUS_BYTE_COUNT_SHIFT) | (slave << 1)); |
Vladimir Serbinenko | 1b12ef1 | 2014-02-21 07:21:00 +0100 | [diff] [blame] | 88 | wait_rdy(mmio); |
Elyes HAOUAS | a342f39 | 2018-10-17 10:56:26 +0200 | [diff] [blame] | 89 | write32(GMBUS1_ADDR, GMBUS_SW_RDY | GMBUS_CYCLE_STOP); |
Sebastian "Swift Geek" Grzywna | 7e516fb | 2016-09-08 01:50:32 +0200 | [diff] [blame] | 90 | write32(GMBUS2_ADDR, GMBUS_INUSE); |
Vladimir Serbinenko | 1b12ef1 | 2014-02-21 07:21:00 +0100 | [diff] [blame] | 91 | |
Elyes Haouas | 3467704 | 2023-08-26 16:42:11 +0200 | [diff] [blame^] | 92 | printk(BIOS_SPEW, "EDID:\n"); |
Vladimir Serbinenko | 1b12ef1 | 2014-02-21 07:21:00 +0100 | [diff] [blame] | 93 | for (i = 0; i < 128; i++) { |
Paul Menzel | 75c5ead | 2020-02-15 13:57:41 +0100 | [diff] [blame] | 94 | printk(BIOS_SPEW, " %02x", edid[i]); |
Vladimir Serbinenko | 1b12ef1 | 2014-02-21 07:21:00 +0100 | [diff] [blame] | 95 | if ((i & 0xf) == 0xf) |
| 96 | printk (BIOS_SPEW, "\n"); |
| 97 | } |
| 98 | } |