blob: e25b5cbedd460faccccd05809af44769987e794f [file] [log] [blame]
Bo-Chen Chen49465162022-11-30 14:47:41 +08001/* SPDX-License-Identifier: GPL-2.0-only */
2
3#include <boardid.h>
4#include <cbfs.h>
5#include <console/console.h>
6#include <edid.h>
7#include <gpio.h>
Ruihai Zhoud3089a32023-11-07 16:29:50 +08008#include <identity.h>
Bo-Chen Chen49465162022-11-30 14:47:41 +08009#include <soc/gpio_common.h>
10#include <string.h>
11
12#include "gpio.h"
13#include "panel.h"
14
15static void get_mipi_cmd_from_cbfs(struct panel_description *desc)
16{
17 /*
18 * The CBFS file name is panel-{MANUFACTURER}-${PANEL_NAME}, where MANUFACTURER is 3
19 * characters and PANEL_NAME is usually 13 characters.
20 */
21 char cbfs_name[64];
22 static union {
23 u8 raw[4 * 1024]; /* Most panels only need < 2K. */
24 struct panel_serializable_data s;
25 } buffer;
26
27 if (!desc->name) {
28 printk(BIOS_ERR, "Missing panel CBFS file name.\n");
29 return;
30 }
31
32 snprintf(cbfs_name, sizeof(cbfs_name), "panel-%s", desc->name);
33 if (cbfs_load(cbfs_name, buffer.raw, sizeof(buffer)))
34 desc->s = &buffer.s;
35 else
36 printk(BIOS_ERR, "Missing %s in CBFS.\n", cbfs_name);
37}
38
Ruihai Zhoud3089a32023-11-07 16:29:50 +080039struct panel_description __weak *get_panel_description(uint32_t panel_id)
40{
41 printk(BIOS_WARNING, "%s: %s: the panel configuration is not ready\n",
42 __func__, mainboard_part_number);
43 return NULL;
44}
45
Bo-Chen Chen49465162022-11-30 14:47:41 +080046struct panel_description *get_active_panel(void)
47{
48 uint32_t active_panel_id = panel_id();
49
50 struct panel_description *panel = get_panel_description(active_panel_id);
51 if (!panel || panel->disp_path == DISP_PATH_NONE) {
52 printk(BIOS_ERR, "%s: Panel %u is not supported.\n", __func__, active_panel_id);
53 return NULL;
54 }
55
56 /* For eDP, we will get edid after eDP initialization is done, so we return directly. */
57 if (panel->disp_path == DISP_PATH_EDP) {
58 printk(BIOS_INFO, "%s: Use eDP as the display\n", __func__);
59 return panel;
60 }
61
62 /* We need to find init cmds for MIPI panel from CBFS */
63 get_mipi_cmd_from_cbfs(panel);
Bo-Chen Chen1fd7d9d2023-01-10 15:41:08 +080064 if (!panel->s)
65 return NULL;
Bo-Chen Chen49465162022-11-30 14:47:41 +080066
67 const struct edid *edid = &panel->s->edid;
68 const char *name = edid->ascii_string;
69 if (name[0] == '\0') {
70 name = "unknown name";
71 printk(BIOS_INFO, "%s: Found ID %u: '%s %s' %dx%d@%dHz\n", __func__,
72 active_panel_id, edid->manufacturer_name, name, edid->mode.ha,
73 edid->mode.va, edid->mode.refresh);
74 }
75 return panel;
76}
Ruihai Zhoud3089a32023-11-07 16:29:50 +080077
78void configure_mipi_pwm_backlight(void)
79{
80 gpio_output(GPIO_AP_DISP_BKLTEN, 0);
81 gpio_output(GPIO_MIPI_BL_PWM_1V8, 0);
82}
83
84void fill_lp_backlight_gpios(struct lb_gpios *gpios)
85{
86 struct panel_description *panel = get_active_panel();
87 if (!panel || panel->disp_path == DISP_PATH_NONE)
88 return;
89
90 struct lb_gpio mipi_pwm_gpios[] = {
91 {GPIO_MIPI_BL_PWM_1V8.id, ACTIVE_HIGH, -1, "PWM control"},
92 };
93
94 struct lb_gpio edp_pwm_gpios[] = {
95 {GPIO_EDP_BL_PWM_1V8.id, ACTIVE_HIGH, -1, "PWM control"},
96 };
97
98 if (panel->pwm_ctrl_gpio) {
99 /* PWM control for typical eDP and MIPI panels */
100 if (panel->disp_path == DISP_PATH_MIPI)
101 lb_add_gpios(gpios, mipi_pwm_gpios, ARRAY_SIZE(mipi_pwm_gpios));
102 else
103 lb_add_gpios(gpios, edp_pwm_gpios, ARRAY_SIZE(edp_pwm_gpios));
104 }
105
106 struct lb_gpio backlight_gpios[] = {
107 {GPIO_AP_DISP_BKLTEN.id, ACTIVE_HIGH, -1, "backlight enable"},
108 };
109
110 lb_add_gpios(gpios, backlight_gpios, ARRAY_SIZE(backlight_gpios));
111}