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 <drivers/i2c/ptn3460/ptn3460.h> |
| 6 | #include <hwilib.h> |
| 7 | #include <types.h> |
| 8 | |
Jan Samek | 6ea5834 | 2023-01-18 11:59:14 +0100 | [diff] [blame] | 9 | /** \brief This function provides EDID data to the driver for DP2LVDS Bridge (PTN3460). |
| 10 | * @param edid_data pointer to EDID data in driver |
| 11 | * @return CB_SUCCESS on successful EDID data retrieval, CB_ERR otherwise |
| 12 | */ |
Uwe Poeche | 9965885 | 2019-11-05 15:44:42 +0100 | [diff] [blame] | 13 | enum cb_err mb_get_edid(uint8_t edid_data[0x80]) |
| 14 | { |
| 15 | const char *hwi_block = "hwinfo.hex"; |
| 16 | |
| 17 | if (hwilib_find_blocks(hwi_block) != CB_SUCCESS) { |
| 18 | printk(BIOS_ERR, "LCD: Info block \"%s\" not found!\n", hwi_block); |
| 19 | return CB_ERR; |
| 20 | } |
| 21 | |
| 22 | /* Get EDID data from hwinfo block */ |
| 23 | if (hwilib_get_field(Edid, edid_data, PTN_EDID_LEN) != PTN_EDID_LEN) { |
| 24 | printk(BIOS_ERR, "LCD: No EDID data available in %s\n", hwi_block); |
| 25 | return CB_ERR; |
| 26 | } |
| 27 | return CB_SUCCESS; |
| 28 | } |
| 29 | |
| 30 | /** \brief This function provides EDID block [0..6] to the driver for DP2LVDS Bridge (PTN3460) |
| 31 | * which has to be used. |
Jan Samek | 6ea5834 | 2023-01-18 11:59:14 +0100 | [diff] [blame] | 32 | * @return Index of the EDID slot selected for EDID emulation |
| 33 | */ |
Uwe Poeche | 9965885 | 2019-11-05 15:44:42 +0100 | [diff] [blame] | 34 | uint8_t mb_select_edid_table(void) |
| 35 | { |
| 36 | return 6; /* With this mainboard we use EDID block 6 for emulation in PTN3460. */ |
| 37 | } |
| 38 | |
Jan Samek | 6ea5834 | 2023-01-18 11:59:14 +0100 | [diff] [blame] | 39 | /** \brief Function to enable mainboard to adjust the config data of PTN3460. For reference, |
| 40 | * see NXP document AN11128 - PTN3460 Programming guide. |
| 41 | * @param *cfg_ptr Pointer to the PTN config structure to modify |
Jan Samek | 79312af | 2023-01-18 13:28:50 +0100 | [diff] [blame^] | 42 | * @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] | 43 | */ |
Jan Samek | 79312af | 2023-01-18 13:28:50 +0100 | [diff] [blame^] | 44 | enum cb_err mb_adjust_cfg(struct ptn_3460_config *cfg) |
Uwe Poeche | 9965885 | 2019-11-05 15:44:42 +0100 | [diff] [blame] | 45 | { |
| 46 | const char *hwi_block = "hwinfo.hex"; |
| 47 | uint8_t disp_con = 0, color_depth = 0; |
| 48 | |
Jan Samek | 6ea5834 | 2023-01-18 11:59:14 +0100 | [diff] [blame] | 49 | /* Get display-specific configuration from hwinfo. */ |
Uwe Poeche | 9965885 | 2019-11-05 15:44:42 +0100 | [diff] [blame] | 50 | if (hwilib_find_blocks(hwi_block) != CB_SUCCESS) { |
| 51 | printk(BIOS_ERR, "LCD: Info block \"%s\" not found!\n", hwi_block); |
Jan Samek | 79312af | 2023-01-18 13:28:50 +0100 | [diff] [blame^] | 52 | return CB_ERR; |
Uwe Poeche | 9965885 | 2019-11-05 15:44:42 +0100 | [diff] [blame] | 53 | } |
Uwe Poeche | 9965885 | 2019-11-05 15:44:42 +0100 | [diff] [blame] | 54 | if (hwilib_get_field(PF_DisplCon, &disp_con, sizeof(disp_con)) != sizeof(disp_con)) { |
| 55 | printk(BIOS_ERR, "LCD: Missing panel features from %s\n", hwi_block); |
Jan Samek | 79312af | 2023-01-18 13:28:50 +0100 | [diff] [blame^] | 56 | return CB_ERR; |
Uwe Poeche | 9965885 | 2019-11-05 15:44:42 +0100 | [diff] [blame] | 57 | } |
| 58 | if (hwilib_get_field(PF_Color_Depth, &color_depth, |
| 59 | sizeof(color_depth)) != sizeof(color_depth)) { |
| 60 | printk(BIOS_ERR, "LCD: Missing panel features from %s\n", hwi_block); |
Jan Samek | 79312af | 2023-01-18 13:28:50 +0100 | [diff] [blame^] | 61 | return CB_ERR; |
Uwe Poeche | 9965885 | 2019-11-05 15:44:42 +0100 | [diff] [blame] | 62 | } |
Jan Samek | 6ea5834 | 2023-01-18 11:59:14 +0100 | [diff] [blame] | 63 | |
| 64 | /* Set up PTN3460 registers based on hwinfo and fixed board-specific parameters: */ |
| 65 | /* 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] | 66 | cfg->dp_interface_ctrl = 0x00; |
Jan Samek | 6ea5834 | 2023-01-18 11:59:14 +0100 | [diff] [blame] | 67 | /* Use odd bus for LVDS clock distribution only. */ |
Uwe Poeche | 9965885 | 2019-11-05 15:44:42 +0100 | [diff] [blame] | 68 | cfg->lvds_interface_ctrl1 = 0x01; |
| 69 | if (disp_con == PF_DISPLCON_LVDS_DUAL) { |
| 70 | /* Turn on dual LVDS lane and clock. */ |
| 71 | cfg->lvds_interface_ctrl1 |= 0x0b; |
| 72 | } |
| 73 | if (color_depth == PF_COLOR_DEPTH_6BIT) { |
| 74 | /* Use 18 bits per pixel. */ |
| 75 | cfg->lvds_interface_ctrl1 |= 0x20; |
| 76 | } |
Jan Samek | 6ea5834 | 2023-01-18 11:59:14 +0100 | [diff] [blame] | 77 | /* No clock spreading, 300 mV LVDS swing */ |
Uwe Poeche | 9965885 | 2019-11-05 15:44:42 +0100 | [diff] [blame] | 78 | cfg->lvds_interface_ctrl2 = 0x03; |
| 79 | /* Swap LVDS lanes (N vs. P). */ |
| 80 | cfg->lvds_interface_ctrl3 = 0x04; |
Jan Samek | 6ea5834 | 2023-01-18 11:59:14 +0100 | [diff] [blame] | 81 | /* Enable VDD to LVDS active delay. */ |
| 82 | cfg->t2_delay = 0x01; |
| 83 | /* LVDS to backlight active delay: 500 ms */ |
| 84 | cfg->t3_timing = 0x0a; |
| 85 | /* Minimum re-power delay: 1 s */ |
| 86 | cfg->t12_timing = 0x14; |
| 87 | /* Backlight off to LVDS inactive delay: 150 ms */ |
| 88 | cfg->t4_timing = 0x03; |
| 89 | /* Enable LVDS to VDD inactive delay. */ |
| 90 | cfg->t5_delay = 0x01; |
Uwe Poeche | 9965885 | 2019-11-05 15:44:42 +0100 | [diff] [blame] | 91 | /* Enable backlight control. */ |
Jan Samek | 6ea5834 | 2023-01-18 11:59:14 +0100 | [diff] [blame] | 92 | cfg->backlight_ctrl = 0x00; |
Uwe Poeche | 9965885 | 2019-11-05 15:44:42 +0100 | [diff] [blame] | 93 | |
Jan Samek | 79312af | 2023-01-18 13:28:50 +0100 | [diff] [blame^] | 94 | return CB_SUCCESS; |
Uwe Poeche | 9965885 | 2019-11-05 15:44:42 +0100 | [diff] [blame] | 95 | } |