Angel Pons | 6ad9176 | 2020-04-03 01:23:24 +0200 | [diff] [blame] | 1 | /* SPDX-License-Identifier: GPL-2.0-only */ |
Uwe Poeche | 9965885 | 2019-11-05 15:44:42 +0100 | [diff] [blame] | 2 | |
| 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 | |
| 11 | static 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 Samek | 6ea5834 | 2023-01-18 11:59:14 +0100 | [diff] [blame] | 32 | /** \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 Samek | 671cd1d | 2023-01-27 11:02:20 +0100 | [diff] [blame^] | 36 | enum cb_err mb_get_edid(uint8_t edid_data[PTN_EDID_LEN]) |
Uwe Poeche | 9965885 | 2019-11-05 15:44:42 +0100 | [diff] [blame] | 37 | { |
| 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 Samek | 6ea5834 | 2023-01-18 11:59:14 +0100 | [diff] [blame] | 57 | * @return Index of the EDID slot selected for EDID emulation |
| 58 | */ |
Uwe Poeche | 9965885 | 2019-11-05 15:44:42 +0100 | [diff] [blame] | 59 | uint8_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 Samek | 6ea5834 | 2023-01-18 11:59:14 +0100 | [diff] [blame] | 64 | /** \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 Samek | 79312af | 2023-01-18 13:28:50 +0100 | [diff] [blame] | 67 | * @return CB_SUCCESS if data was modified and needs to be updated; CB_ERR on error |
Jan Samek | 6ea5834 | 2023-01-18 11:59:14 +0100 | [diff] [blame] | 68 | */ |
Jan Samek | 79312af | 2023-01-18 13:28:50 +0100 | [diff] [blame] | 69 | enum cb_err mb_adjust_cfg(struct ptn_3460_config *cfg) |
Uwe Poeche | 9965885 | 2019-11-05 15:44:42 +0100 | [diff] [blame] | 70 | { |
| 71 | const char *hwi_block = "hwinfo.hex"; |
| 72 | uint8_t disp_con = 0, color_depth = 0; |
| 73 | |
Jan Samek | 6ea5834 | 2023-01-18 11:59:14 +0100 | [diff] [blame] | 74 | /* Get display-specific configuration from hwinfo. */ |
Uwe Poeche | 9965885 | 2019-11-05 15:44:42 +0100 | [diff] [blame] | 75 | if (hwilib_find_blocks(hwi_block) != CB_SUCCESS) { |
| 76 | printk(BIOS_ERR, "LCD: Info block \"%s\" not found!\n", hwi_block); |
Jan Samek | 79312af | 2023-01-18 13:28:50 +0100 | [diff] [blame] | 77 | return CB_ERR; |
Uwe Poeche | 9965885 | 2019-11-05 15:44:42 +0100 | [diff] [blame] | 78 | } |
Uwe Poeche | 9965885 | 2019-11-05 15:44:42 +0100 | [diff] [blame] | 79 | 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 Samek | 79312af | 2023-01-18 13:28:50 +0100 | [diff] [blame] | 81 | return CB_ERR; |
Uwe Poeche | 9965885 | 2019-11-05 15:44:42 +0100 | [diff] [blame] | 82 | } |
| 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 Samek | 79312af | 2023-01-18 13:28:50 +0100 | [diff] [blame] | 86 | return CB_ERR; |
Uwe Poeche | 9965885 | 2019-11-05 15:44:42 +0100 | [diff] [blame] | 87 | } |
Jan Samek | 6ea5834 | 2023-01-18 11:59:14 +0100 | [diff] [blame] | 88 | |
| 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 Poeche | 9965885 | 2019-11-05 15:44:42 +0100 | [diff] [blame] | 91 | cfg->dp_interface_ctrl = 0x00; |
Jan Samek | 6ea5834 | 2023-01-18 11:59:14 +0100 | [diff] [blame] | 92 | /* Use odd bus for LVDS clock distribution only. */ |
Uwe Poeche | 9965885 | 2019-11-05 15:44:42 +0100 | [diff] [blame] | 93 | 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 Samek | 6ea5834 | 2023-01-18 11:59:14 +0100 | [diff] [blame] | 102 | /* 1% clock spreading, 300 mV LVDS swing */ |
Uwe Poeche | 9965885 | 2019-11-05 15:44:42 +0100 | [diff] [blame] | 103 | cfg->lvds_interface_ctrl2 = 0x13; |
Jan Samek | 6ea5834 | 2023-01-18 11:59:14 +0100 | [diff] [blame] | 104 | /* No LVDS lane/channel swapping */ |
Uwe Poeche | 9965885 | 2019-11-05 15:44:42 +0100 | [diff] [blame] | 105 | cfg->lvds_interface_ctrl3 = 0x00; |
Jan Samek | 6ea5834 | 2023-01-18 11:59:14 +0100 | [diff] [blame] | 106 | /* 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 Poeche | 9965885 | 2019-11-05 15:44:42 +0100 | [diff] [blame] | 116 | /* Enable backlight control. */ |
Jan Samek | 6ea5834 | 2023-01-18 11:59:14 +0100 | [diff] [blame] | 117 | cfg->backlight_ctrl = 0x00; |
Uwe Poeche | 9965885 | 2019-11-05 15:44:42 +0100 | [diff] [blame] | 118 | |
Jan Samek | 79312af | 2023-01-18 13:28:50 +0100 | [diff] [blame] | 119 | return CB_SUCCESS; |
Uwe Poeche | 9965885 | 2019-11-05 15:44:42 +0100 | [diff] [blame] | 120 | } |