Hello

The correct timings are detected by X (cf below), so I checked the existing gma_ivybridge init and I thought it may calculate clocks wrong.
Then I found about https://review.coreboot.org/#/c/16504/ addressing just this, so I tried to port it to gma_ivybridge
Unfortunately I must I have done something really wrong, because I now get no display at all.
Before:
Data M1=10108272, N1=8388608
Link frequency 270000 kHz
Link M1=280785, N1=524288
Pixel N=7, M1=22, M2=8, P1=2
Pixel clock 144489 kHz

After:
Data M1=10108272, N1=8388608
Link frequency 270000 kHz
Link M1=280785, N1=524288
Pixel N=2, M1=13, M2=4, P1=2
Pixel clock 144642 kHz


My patch:
--- gma_ivybridge_lvds.c 2016-11-20 14:24:57.944308878 -0500
+++ gma_ivybridge_lvds.c.orig 2016-11-20 12:51:24.273120162 -0500
@@ -29,9 +29,6 @@
#include <pc80/vga_io.h>
#include <device/pci_def.h>
#include <device/pci_rom.h>
-#include <commonlib/helpers.h>
-
-#define BASE_FREQUENCY 100000

static void link_train(u8 *mmio)
{
@@ -142,7 +139,6 @@
int i;
u8 edid_data[128];
struct edid edid;
- u32 target_frequency;

if (!IS_ENABLED(CONFIG_MAINBOARD_DO_NATIVE_VGA_INIT))
return 0;
@@ -209,19 +205,17 @@
u32 hfront_porch = edid.mode.hso;
u32 vfront_porch = edid.mode.vso;

- u32 smallest_err = 0xffffffff;
+ u32 candp1, candn;
+ u32 best_delta = 0xffffffff;

+ u32 target_frequency = (
+ edid.mode.lvds_dual_channel ? edid.mode.pixel_clock
+ : (2 * edid.mode.pixel_clock));
u32 pixel_p1 = 1;
- u32 pixel_p2;
u32 pixel_n = 1;
u32 pixel_m1 = 1;
u32 pixel_m2 = 1;

- /* p2 divisor must 7 for dual channel LVDS */
- /* and 14 for single channel LVDS */
- pixel_p2 = edid.mode.lvds_dual_channel ? 7 : 14;
- target_frequency = edid.mode.pixel_clock;
-
vga_textmode_init();
if (IS_ENABLED(CONFIG_FRAMEBUFFER_KEEP_VESA_MODE)) {
vga_sr_write(1, 1);
@@ -249,34 +243,40 @@
write32(mmio + LGC_PALETTE(0) + 4 * i, i * 0x010101);
}

- /* Find suitable divisors, m1, m2, p1, n. */
- /* refclock * (5 * (m1 + 2) + (m1 + 2)) / (n + 2) / p1 / p2 */
- /* should be closest to target frequency as possible */
- u32 candn, candm1, candm2, candp1;
- for (candm1 = 8; candm1 <= 18; candm1++) {
- for (candm2 = 3; candm2 <= 7; candm2++) {
- for (candn = 1; candn <= 6; candn++) {
- for (candp1 = 1; candp1 <= 8; candp1++) {
- u32 m = 5 * (candm1 + 2) + (candm2 + 2);
- u32 p = candp1 * pixel_p2;
- u32 vco = DIV_ROUND_CLOSEST(BASE_FREQUENCY * m, candn + 2);
- u32 dot = DIV_ROUND_CLOSEST(vco, p);
- u32 this_err = ABS(dot - target_frequency);
- if ((m < 70) || (m > 120))
- continue;
- if (this_err < smallest_err) {
- smallest_err = this_err;
- pixel_n = candn;
- pixel_m1 = candm1;
- pixel_m2 = candm2;
- pixel_p1 = candp1;
- }
- }
+ /* Find suitable divisors. */
+ for (candp1 = 1; candp1 <= 8; candp1++) {
+ for (candn = 5; candn <= 10; candn++) {
+ u32 cur_frequency;
+ u32 m; /* 77 - 131. */
+ u32 denom; /* 35 - 560. */
+ u32 current_delta;
+
+ denom = candn * candp1 * 7;
+ /* Doesnt overflow for up to
+ 5000000 kHz = 5 GHz. */
+ m = (target_frequency * denom + 60000) / 120000;
+
+ if (m < 77 || m > 131)
+ continue;
+
+ cur_frequency = (120000 * m) / denom;
+ if (target_frequency > cur_frequency)
+ current_delta = target_frequency - cur_frequency;
+ else
+ current_delta = cur_frequency - target_frequency;
+
+
+ if (best_delta > current_delta) {
+ best_delta = current_delta;
+ pixel_n = candn;
+ pixel_p1 = candp1;
+ pixel_m2 = ((m + 3) % 5) + 7;
+ pixel_m1 = (m - pixel_m2) / 5;
}
}
}

- if (smallest_err == 0xffffffff) {
+ if (best_delta == 0xffffffff) {
printk (BIOS_ERR, "Couldn't find GFX clock divisors\n");
return 0;
}
@@ -317,8 +317,8 @@
printk(BIOS_DEBUG, "Pixel N=%d, M1=%d, M2=%d, P1=%d\n",
pixel_n, pixel_m1, pixel_m2, pixel_p1);
printk(BIOS_DEBUG, "Pixel clock %d kHz\n",
- BASE_FREQUENCY * (5 * (pixel_m1 + 2) + (pixel_m2 + 2)) /
- (pixel_n + 2) / (pixel_p1 * pixel_p2));
+ 120000 * (5 * pixel_m1 + pixel_m2) / pixel_n
+ / (pixel_p1 * 7));

write32(mmio + PCH_LVDS,
(hpolarity << 20) | (vpolarity << 21)
@@ -333,14 +333,15 @@
write32(mmio + PCH_PP_CONTROL, PANEL_UNLOCK_REGS
| (read32(mmio + PCH_PP_CONTROL) & ~PANEL_UNLOCK_MASK));
write32(mmio + _PCH_FP0(0),
- (pixel_n << 16)
- | (pixel_m1 << 8) | pixel_m2);
+ ((pixel_n - 2) << 16)
+ | ((pixel_m1 - 2) << 8) | pixel_m2);
write32(mmio + _PCH_DPLL(0),
DPLL_VCO_ENABLE | DPLLB_MODE_LVDS
| (edid.mode.lvds_dual_channel ? DPLLB_LVDS_P2_CLOCK_DIV_7
: DPLLB_LVDS_P2_CLOCK_DIV_14)
+ | (0x10000 << (pixel_p1 - 1))
| ((info->use_spread_spectrum_clock ? 3 : 0) << 13)
- | (0x10000 << (pixel_p1 - 1)));
+ | (0x1 << (pixel_p1 - 1)));

mdelay(1);
write32(mmio + 0xc7000, 0x8);
@@ -350,9 +351,9 @@
DPLL_VCO_ENABLE | DPLLB_MODE_LVDS
| (edid.mode.lvds_dual_channel ? DPLLB_LVDS_P2_CLOCK_DIV_7
: DPLLB_LVDS_P2_CLOCK_DIV_14)
+ | (0x10000 << (pixel_p1 - 1))
| ((info->use_spread_spectrum_clock ? 3 : 0) << 13)
- | (0x10000 << (pixel_p1 - 1)));
-
+ | (0x1 << (pixel_p1 - 1)));
/* Re-lock the registers. */
write32(mmio + PCH_PP_CONTROL,
(read32(mmio + PCH_PP_CONTROL) & ~PANEL_UNLOCK_MASK));

Xorg:
[     6.889] (II) intel(0): EDID for output LVDS1
[ 6.889] (II) intel(0): Manufacturer: AUO Model: 11ed Serial#: 0
[ 6.889] (II) intel(0): Year: 2012 Week: 0
[ 6.889] (II) intel(0): EDID Version: 1.4
[ 6.889] (II) intel(0): Digital Display Input
[ 6.889] (II) intel(0): 6 bits per channel
[ 6.889] (II) intel(0): Digital interface is undefined
[ 6.889] (II) intel(0): Max Image Size [cm]: horiz.: 34 vert.: 19
[ 6.889] (II) intel(0): Gamma: 2.20
[ 6.889] (II) intel(0): No DPMS capabilities specified
[ 6.889] (II) intel(0): Supported color encodings: RGB 4:4:4
[ 6.889] (II) intel(0): First detailed timing is preferred mode
[ 6.889] (II) intel(0): Preferred mode is native pixel format and refresh rate
[ 6.889] (II) intel(0): redX: 0.676 redY: 0.314 greenX: 0.215 greenY: 0.665
[ 6.889] (II) intel(0): blueX: 0.141 blueY: 0.069 whiteX: 0.313 whiteY: 0.329
[ 6.889] (II) intel(0): Manufacturer's mask: 0
[ 6.889] (II) intel(0): Supported detailed timing:
[ 6.889] (II) intel(0): clock: 144.6 MHz Image Size: 344 x 193 mm
[ 6.889] (II) intel(0): h_active: 1920 h_sync: 1980 h_sync_end 2028 h_blank_end 2132 h_b
order: 0
[ 6.889] (II) intel(0): v_active: 1080 v_sync: 1090 v_sync_end 1100 v_blanking: 1130 v_b
order: 0
[ 6.889] (II) intel(0): Supported detailed timing:
[ 6.889] (II) intel(0): clock: 144.6 MHz Image Size: 344 x 193 mm
[ 6.889] (II) intel(0): h_active: 1920 h_sync: 1980 h_sync_end 2028 h_blank_end 2558 h_b
order: 0
[ 6.889] (II) intel(0): v_active: 1080 v_sync: 1090 v_sync_end 1100 v_blanking: 1130 v_b
order: 0
[ 6.889] (II) intel(0): AUO
[ 6.889] (II) intel(0): B156HTN01.1
[ 6.889] (II) intel(0): EDID (in hex):
[ 6.889] (II) intel(0): 00ffffffffffff0006afed1100000000
[ 6.889] (II) intel(0): 0016010490221378022135ad5037aa24
[ 6.889] (II) intel(0): 11505400000001010101010101010101
[ 6.889] (II) intel(0): 0101010101017c3880d4703832403c30
[ 6.889] (II) intel(0): aa0058c1100000187c38807e72383240
[ 6.889] (II) intel(0): 3c30aa0058c110000018000000fe0041
[ 6.889] (II) intel(0): 554f0a202020202020202020000000fe
[ 6.889] (II) intel(0): 004231353648544e30312e31200a0081
[ 6.889] (II) intel(0): EDID vendor "AUO", prod id 4589
[ 6.889] (II) intel(0): Printing DDC gathered Modelines:
[ 6.889] (II) intel(0): Modeline "1920x1080"x0.0 144.60 1920 1980 2028 2132 1080 1090 1
100 1130 -hsync -vsync (67.8 kHz eP)
[ 6.889] (II) intel(0): Modeline "1920x1080"x0.0 144.60 1920 1980 2028 2558 1080 1090 1
100 1130 -hsync -vsync (56.5 kHz e)
[ 6.889] (II) intel(0): Printing probed modes for output LVDS1
[ 6.889] (II) intel(0): Modeline "1920x1080"x60.0 144.60 1920 1980 2028 2132 1080 1090
1100 1130 -hsync -vsync (67.8 kHz eP)
[ 6.889] (II) intel(0): Modeline "1920x1080"x50.0 144.60 1920 1980 2028 2558 1080 1090
1100 1130 -hsync -vsync (56.5 kHz e)
[ 6.889] (II) intel(0): Modeline "1920x1080"x59.9 138.50 1920 1968 2000 2080 1080 1083
1088 1111 +hsync -vsync (66.6 kHz d)
[ 6.889] (II) intel(0): Modeline "1680x1050"x60.0 146.25 1680 1784 1960 2240 1050 1053
1059 1089 -hsync +vsync (65.3 kHz d)
[ 6.889] (II) intel(0): Modeline "1680x1050"x59.9 119.00 1680 1728 1760 1840 1050 1053
1059 1080 +hsync -vsync (64.7 kHz d)
[ 6.889] (II) intel(0): Modeline "1600x1024"x60.2 103.12 1600 1600 1656 1664 1024 1024
1029 1030 +hsync +vsync (62.0 kHz d)
[ 6.889] (II) intel(0): Modeline "1400x1050"x60.0 122.00 1400 1488 1640 1880 1050 1052
1064 1082 +hsync +vsync (64.9 kHz d)
[ 6.889] (II) intel(0): Modeline "1600x900"x60.0 119.00 1600 1696 1864 2128 900 901 904
932 -hsync +vsync (55.9 kHz)
[ 6.889] (II) intel(0): Modeline "1280x1024"x60.0 108.00 1280 1328 1440 1688 1024 1025
1028 1066 +hsync +vsync (64.0 kHz d)
[ 6.889] (II) intel(0): Modeline "1440x900"x59.9 106.50 1440 1520 1672 1904 900 903 909
934 -hsync +vsync (55.9 kHz d)
[ 6.889] (II) intel(0): Modeline "1280x960"x60.0 108.00 1280 1376 1488 1800 960 961 964
1000 +hsync +vsync (60.0 kHz d)
[ 6.889] (II) intel(0): Modeline "1368x768"x60.0 85.86 1368 1440 1584 1800 768 769 772
795 -hsync +vsync (47.7 kHz)
[ 6.889] (II) intel(0): Modeline "1360x768"x59.8 84.75 1360 1432 1568 1776 768 771 781
798 -hsync +vsync (47.7 kHz d)
[ 6.889] (II) intel(0): Modeline "1360x768"x60.0 72.00 1360 1408 1440 1520 768 771 781
790 +hsync -vsync (47.4 kHz d)
[ 6.889] (II) intel(0): Modeline "1152x864"x60.0 81.62 1152 1216 1336 1520 864 865 868
895 -hsync +vsync (53.7 kHz d)
[ 6.889] (II) intel(0): Modeline "1280x720"x60.0 74.48 1280 1336 1472 1664 720 721 724
746 -hsync +vsync (44.8 kHz)
[ 6.889] (II) intel(0): Modeline "1024x768"x60.0 65.00 1024 1048 1184 1344 768 771 777
806 -hsync -vsync (48.4 kHz d)
[ 6.889] (II) intel(0): Modeline "1024x576"x60.0 46.99 1024 1064 1168 1312 576 577 580
597 -hsync +vsync (35.8 kHz)
[ 6.889] (II) intel(0): Modeline "960x540"x60.0 40.78 960 992 1088 1216 540 541 544 55
9 -hsync +vsync (33.5 kHz)
[ 6.889] (II) intel(0): Modeline "800x600"x60.3 40.00 800 840 968 1056 600 601 605 628
+hsync +vsync (37.9 kHz d)
[ 6.889] (II) intel(0): Modeline "800x600"x56.2 36.00 800 824 896 1024 600 601 603 625
+hsync +vsync (35.2 kHz d)
[ 6.889] (II) intel(0): Modeline "864x486"x60.0 32.90 864 888 976 1088 486 487 490 504
-hsync +vsync (30.2 kHz)
[ 6.889] (II) intel(0): Modeline "640x480"x59.9 25.18 640 656 752 800 480 490 492 525
-hsync -vsync (31.5 kHz d)
[ 6.889] (II) intel(0): Modeline "720x405"x60.0 22.18 720 728 800 880 405 406 409 420
-hsync +vsync (25.2 kHz)
[ 6.889] (II) intel(0): Modeline "640x360"x60.0 17.19 640 640 704 768 360 361 364 373
-hsync +vsync (22.4 kHz)

Complete information:

Initializing VGA without OPROM.
EDID:
00 ff ff ff ff ff ff 00 06 af ed 11 00 00 00 00
00 16 01 04 90 22 13 78 02 21 35 ad 50 37 aa 24
11 50 54 00 00 00 01 01 01 01 01 01 01 01 01 01
01 01 01 01 01 01 7c 38 80 d4 70 38 32 40 3c 30
aa 00 58 c1 10 00 00 18 7c 38 80 7e 72 38 32 40
3c 30 aa 00 58 c1 10 00 00 18 00 00 00 fe 00 41
55 4f 0a 20 20 20 20 20 20 20 20 20 00 00 00 fe
00 42 31 35 36 48 54 4e 30 31 2e 31 20 0a 00 81
Extracted contents:
header: 00 ff ff ff ff ff ff 00
serial number: 06 af ed 11 00 00 00 00 00 16
version: 01 04
basic params: 90 22 13 78 02
chroma info: 21 35 ad 50 37 aa 24 11 50 54
established: 00 00 00
standard: 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01
descriptor 1: 7c 38 80 d4 70 38 32 40 3c 30 aa 00 58 c1 10 00 00 18
descriptor 2: 7c 38 80 7e 72 38 32 40 3c 30 aa 00 58 c1 10 00 00 18
descriptor 3: 00 00 00 fe 00 41 55 4f 0a 20 20 20 20 20 20 20 20 20
descriptor 4: 00 00 00 fe 00 42 31 35 36 48 54 4e 30 31 2e 31 20 0a
extensions: 00
checksum: 81

Manufacturer: AUO Model 11ed Serial Number 0
Made week 0 of 2012
EDID version: 1.4
Digital display
6 bits per primary color channel
Digital interface is not defined
Maximum image size: 34 cm x 19 cm
Gamma: 220%
Check DPMS levels
Supported color formats: RGB 4:4:4
First detailed timing is preferred timing
Established timings supported:
Standard timings supported:
Detailed timings
Hex of detail: 7c3880d4703832403c30aa0058c110000018
Detailed mode (IN HEX): Clock 144600 KHz, 158 mm x c1 mm
0780 07bc 07ec 0854 hborder 0
0438 0442 044c 046a vborder 0
-hsync -vsync
Did detailed timing
Hex of detail: 7c38807e723832403c30aa0058c110000018
Detailed mode (IN HEX): Clock 144600 KHz, 158 mm x c1 mm
0780 07bc 07ec 09fe hborder 0
0438 0442 044c 046a vborder 0
-hsync -vsync
Hex of detail: 000000fe0041554f0a202020202020202020
ASCII string: AUO
Hex of detail: 000000fe004231353648544e30312e31200a
ASCII string: B156HTN01.1
Checksum
Checksum: 0x81 (valid)
bringing up panel at resolution 1920 x 1080
Borders 0 x 0
Blank 212 x 50
Sync 48 x 10
Front porch 60 x 10
Spread spectrum clock
Dual channel
Polarities 1, 1
Data M1=10108272, N1=8388608
Link frequency 270000 kHz
Link M1=280785, N1=524288
Pixel N=2, M1=13, M2=4, P1=2
Pixel clock 144642 kHz
waiting for panel powerup
panel powered up