blob: c74e90ab6125ef2df498bb6257fe8609c6d94301 [file] [log] [blame]
Angel Pons6ad91762020-04-03 01:23:24 +02001/* SPDX-License-Identifier: GPL-2.0-only */
Uwe Poeche99658852019-11-05 15:44:42 +01002
3#include <console/console.h>
4#include <device/device.h>
5#include <device/pci_ops.h>
6#include <drivers/i2c/ptn3460/ptn3460.h>
7#include <hwilib.h>
8#include <soc/pci_devs.h>
9#include <types.h>
10
11static void igd_disable(void)
12{
13 struct device *root_dev = pcidev_path_on_root(SA_DEVFN_ROOT);
14 uint8_t deven;
15 uint16_t ggc;
16
17 /* GMCH Graphics Control Register */
18 ggc = pci_read_config16(root_dev, 0x50);
19 /* Set size of Graphics Translation Table Memory (GGMS) [7:6]
20 * to 0 and select 0 MB for Graphics Memory (GMS) [15:8]. */
21 ggc &= ~(0xffc0);
22 /* Disable IGD VGA (IVD). */
23 ggc |= 0x2;
24 pci_write_config16(root_dev, 0x50, ggc);
25 /* Device Enable Register */
26 deven = pci_read_config8(root_dev, 0x54);
27 /* Disable IGD device (D2F0EN). */
28 deven &= ~(0x10);
29 pci_write_config8(root_dev, 0x54, deven);
30}
31
Jan Samek6ea58342023-01-18 11:59:14 +010032/** \brief This function provides EDID data to the driver for DP2LVDS Bridge (PTN3460).
33 * @param edid_data pointer to EDID data in driver
34 * @return CB_SUCCESS on successful EDID data retrieval, CB_ERR otherwise
35 */
Jan Samek671cd1d2023-01-27 11:02:20 +010036enum cb_err mb_get_edid(uint8_t edid_data[PTN_EDID_LEN])
Uwe Poeche99658852019-11-05 15:44:42 +010037{
38 const char *hwi_block = "hwinfo.hex";
39
40 if (hwilib_find_blocks(hwi_block) != CB_SUCCESS) {
41 printk(BIOS_ERR, "LCD: Info block \"%s\" not found!\n", hwi_block);
42 return CB_ERR;
43 }
44
45 /* Get EDID data from hwinfo block */
46 if (hwilib_get_field(Edid, edid_data, PTN_EDID_LEN) != PTN_EDID_LEN) {
47 /* Disable IGD to avoid panel failures. */
48 igd_disable();
49 printk(BIOS_ERR, "LCD: No EDID data available in %s\n", hwi_block);
50 return CB_ERR;
51 }
52 return CB_SUCCESS;
53}
54
55/** \brief This function provides EDID block [0..6] to the driver for DP2LVDS Bridge (PTN3460)
56 * which has to be used.
Jan Samek6ea58342023-01-18 11:59:14 +010057 * @return Index of the EDID slot selected for EDID emulation
58 */
Uwe Poeche99658852019-11-05 15:44:42 +010059uint8_t mb_select_edid_table(void)
60{
61 return 6; /* With this mainboard we use EDID block 6 for emulation in PTN3460. */
62}
63
Jan Samek6ea58342023-01-18 11:59:14 +010064/** \brief Function to enable mainboard to adjust the config data of PTN3460. For reference,
65 * see NXP document AN11128 - PTN3460 Programming guide.
66 * @param *cfg_ptr Pointer to the PTN config structure to modify
Jan Samek79312af2023-01-18 13:28:50 +010067 * @return CB_SUCCESS if data was modified and needs to be updated; CB_ERR on error
Jan Samek6ea58342023-01-18 11:59:14 +010068 */
Jan Samek79312af2023-01-18 13:28:50 +010069enum cb_err mb_adjust_cfg(struct ptn_3460_config *cfg)
Uwe Poeche99658852019-11-05 15:44:42 +010070{
71 const char *hwi_block = "hwinfo.hex";
72 uint8_t disp_con = 0, color_depth = 0;
73
Jan Samek6ea58342023-01-18 11:59:14 +010074 /* Get display-specific configuration from hwinfo. */
Uwe Poeche99658852019-11-05 15:44:42 +010075 if (hwilib_find_blocks(hwi_block) != CB_SUCCESS) {
76 printk(BIOS_ERR, "LCD: Info block \"%s\" not found!\n", hwi_block);
Jan Samek79312af2023-01-18 13:28:50 +010077 return CB_ERR;
Uwe Poeche99658852019-11-05 15:44:42 +010078 }
Uwe Poeche99658852019-11-05 15:44:42 +010079 if (hwilib_get_field(PF_DisplCon, &disp_con, sizeof(disp_con)) != sizeof(disp_con)) {
80 printk(BIOS_ERR, "LCD: Missing panel features from %s\n", hwi_block);
Jan Samek79312af2023-01-18 13:28:50 +010081 return CB_ERR;
Uwe Poeche99658852019-11-05 15:44:42 +010082 }
83 if (hwilib_get_field(PF_Color_Depth, &color_depth,
84 sizeof(color_depth)) != sizeof(color_depth)) {
85 printk(BIOS_ERR, "LCD: Missing panel features from %s\n", hwi_block);
Jan Samek79312af2023-01-18 13:28:50 +010086 return CB_ERR;
Uwe Poeche99658852019-11-05 15:44:42 +010087 }
Jan Samek6ea58342023-01-18 11:59:14 +010088
89 /* Set up PTN3460 registers based on hwinfo and fixed board-specific parameters: */
90 /* Use 2 lanes for eDP, no P/N swapping, no ASSR, allow both HBR and RBR modes. */
Uwe Poeche99658852019-11-05 15:44:42 +010091 cfg->dp_interface_ctrl = 0x00;
Jan Samek6ea58342023-01-18 11:59:14 +010092 /* Use odd bus for LVDS clock distribution only. */
Uwe Poeche99658852019-11-05 15:44:42 +010093 cfg->lvds_interface_ctrl1 = 0x01;
94 if (disp_con == PF_DISPLCON_LVDS_DUAL) {
95 /* Turn on dual LVDS lane and clock. */
96 cfg->lvds_interface_ctrl1 |= 0x0b;
97 }
98 if (color_depth == PF_COLOR_DEPTH_6BIT) {
99 /* Use 18 bits per pixel. */
100 cfg->lvds_interface_ctrl1 |= 0x20;
101 }
Jan Samek6ea58342023-01-18 11:59:14 +0100102 /* 1% clock spreading, 300 mV LVDS swing */
Uwe Poeche99658852019-11-05 15:44:42 +0100103 cfg->lvds_interface_ctrl2 = 0x13;
Jan Samek6ea58342023-01-18 11:59:14 +0100104 /* No LVDS lane/channel swapping */
Uwe Poeche99658852019-11-05 15:44:42 +0100105 cfg->lvds_interface_ctrl3 = 0x00;
Jan Samek6ea58342023-01-18 11:59:14 +0100106 /* Enable VDD to LVDS active delay. */
107 cfg->t2_delay = 0x01;
108 /* LVDS to backlight active delay: 500 ms */
109 cfg->t3_timing = 0x0a;
110 /* Minimum re-power delay: 1 s */
111 cfg->t12_timing = 0x14;
112 /* Backlight off to LVDS inactive delay: 150 ms */
113 cfg->t4_timing = 0x03;
114 /* Enable LVDS to VDD inactive delay. */
115 cfg->t5_delay = 0x01;
Uwe Poeche99658852019-11-05 15:44:42 +0100116 /* Enable backlight control. */
Jan Samek6ea58342023-01-18 11:59:14 +0100117 cfg->backlight_ctrl = 0x00;
Uwe Poeche99658852019-11-05 15:44:42 +0100118
Jan Samek79312af2023-01-18 13:28:50 +0100119 return CB_SUCCESS;
Uwe Poeche99658852019-11-05 15:44:42 +0100120}