tegra124: Initialize display panel by EDID.
Tegra124 family products may want to use many different display panels with various timing settings. To support them, we should initialize display panel by EDID instead of hard-coded values. BUG=none TEST=emerge-nyan coreboot chromeos-bootimage BRANCH=none Original-Change-Id: Ib125a7f9cb1e6c8cf2d79e0baab525acfd1b7a6e Original-Signed-off-by: Hung-Te Lin <hungte@chromium.org> Original-Reviewed-on: https://chromium-review.googlesource.com/192730 Original-Reviewed-by: Tom Warren <twarren@nvidia.com> Original-Reviewed-by: Jimmy Zhang <jimmzhang@nvidia.com> Original-Reviewed-by: Gabe Black <gabeblack@chromium.org> (cherry picked from commit 43ecd473419aa0fbdd22487416b0b6cfea6a20d1) Signed-off-by: Marc Jones <marc.jones@se-eng.com> Change-Id: I6af47db113035e9440e663a769318776c7b6b70b Reviewed-on: http://review.coreboot.org/7764 Reviewed-by: Stefan Reinauer <stefan.reinauer@coreboot.org> Tested-by: build bot (Jenkins)
This commit is contained in:
parent
be71ee5dec
commit
3af0d310c1
|
@ -222,17 +222,18 @@ void display_startup(device_t dev)
|
||||||
struct pwm_controller *pwm = (void *)TEGRA_PWM_BASE;
|
struct pwm_controller *pwm = (void *)TEGRA_PWM_BASE;
|
||||||
struct tegra_dc *dc = &dc_data;
|
struct tegra_dc *dc = &dc_data;
|
||||||
|
|
||||||
/* should probably just make it all MiB ... in future */
|
|
||||||
u32 framebuffer_size_mb = config->framebuffer_size / MiB;
|
|
||||||
u32 framebuffer_base_mb= config->framebuffer_base / MiB;
|
|
||||||
|
|
||||||
/* init dc */
|
/* init dc */
|
||||||
dc->base = (void *)TEGRA_ARM_DISPLAYA;
|
dc->base = (void *)TEGRA_ARM_DISPLAYA;
|
||||||
dc->config = config;
|
dc->config = config;
|
||||||
config->dc_data = dc;
|
config->dc_data = dc;
|
||||||
|
|
||||||
|
/* Note dp_init may read EDID and change some config values. */
|
||||||
dp_init(config);
|
dp_init(config);
|
||||||
|
|
||||||
|
/* should probably just make it all MiB ... in future */
|
||||||
|
u32 framebuffer_size_mb = config->framebuffer_size / MiB;
|
||||||
|
u32 framebuffer_base_mb= config->framebuffer_base / MiB;
|
||||||
|
|
||||||
/* light it all up */
|
/* light it all up */
|
||||||
/* This one may have been done in romstage but that's ok for now. */
|
/* This one may have been done in romstage but that's ok for now. */
|
||||||
if (config->panel_vdd_gpio){
|
if (config->panel_vdd_gpio){
|
||||||
|
|
|
@ -19,6 +19,7 @@
|
||||||
#include <console/console.h>
|
#include <console/console.h>
|
||||||
#include <device/device.h>
|
#include <device/device.h>
|
||||||
#include <device/i2c.h>
|
#include <device/i2c.h>
|
||||||
|
#include <edid.h>
|
||||||
#include <stdlib.h>
|
#include <stdlib.h>
|
||||||
#include <string.h>
|
#include <string.h>
|
||||||
#include <delay.h>
|
#include <delay.h>
|
||||||
|
@ -323,11 +324,8 @@ static int tegra_dc_dp_dpcd_write(struct tegra_dc_dp_data *dp, u32 cmd,
|
||||||
return ret;
|
return ret;
|
||||||
}
|
}
|
||||||
|
|
||||||
/* TODO(hungte) Change this to static when EDID parsing functions are ready. */
|
static int tegra_dc_i2c_aux_read(struct tegra_dc_dp_data *dp, u32 i2c_addr,
|
||||||
int tegra_dc_i2c_aux_read(struct tegra_dc_dp_data *dp, u32 i2c_addr,
|
u8 addr, u8 *data, u32 *size, u32 *aux_stat)
|
||||||
u8 addr, u8 *data, u32 *size, u32 *aux_stat);
|
|
||||||
int tegra_dc_i2c_aux_read(struct tegra_dc_dp_data *dp, u32 i2c_addr,
|
|
||||||
u8 addr, u8 *data, u32 *size, u32 *aux_stat)
|
|
||||||
{
|
{
|
||||||
u32 finished = 0;
|
u32 finished = 0;
|
||||||
int ret = 0;
|
int ret = 0;
|
||||||
|
@ -620,6 +618,53 @@ static int tegra_dc_dp_init_link_cfg(
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static void tegra_dp_update_config(struct tegra_dc_dp_data *dp,
|
||||||
|
struct soc_nvidia_tegra124_config *config)
|
||||||
|
{
|
||||||
|
struct edid edid;
|
||||||
|
u8 buf[128] = {0};
|
||||||
|
u32 size = sizeof(buf), aux_stat = 0;
|
||||||
|
|
||||||
|
tegra_dc_dpaux_enable(dp);
|
||||||
|
if (tegra_dc_i2c_aux_read(dp, TEGRA_EDID_I2C_ADDRESS, 0, buf, &size,
|
||||||
|
&aux_stat)) {
|
||||||
|
printk(BIOS_ERR, "%s: Failed to read EDID. Use defaults.\n",
|
||||||
|
__func__);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (decode_edid(buf, sizeof(buf), &edid)) {
|
||||||
|
printk(BIOS_ERR, "%s: Failed to decode EDID. Use defaults.\n",
|
||||||
|
__func__);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
config->xres = edid.ha;
|
||||||
|
config->yres = edid.va;
|
||||||
|
config->pixel_clock = edid.pixel_clock * 1000;
|
||||||
|
|
||||||
|
config->hfront_porch = edid.hso;
|
||||||
|
config->hsync_width = edid.hspw;
|
||||||
|
config->hback_porch = edid.hbl - edid.hso - edid.hspw;
|
||||||
|
|
||||||
|
config->vfront_porch = edid.vso;
|
||||||
|
config->vsync_width = edid.vspw;
|
||||||
|
config->vback_porch = edid.vbl - edid.vso - edid.vspw;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Note edid->framebuffer_bits_per_pixel is currently hard-coded as 32,
|
||||||
|
* so we should keep the default value in device config.
|
||||||
|
*
|
||||||
|
* EDID v1.3 panels may not have color depth info, so we need to check
|
||||||
|
* if these values are zero before updating config.
|
||||||
|
*/
|
||||||
|
if (edid.panel_bits_per_pixel)
|
||||||
|
config->panel_bits_per_pixel = edid.panel_bits_per_pixel;
|
||||||
|
if (edid.panel_bits_per_color)
|
||||||
|
config->color_depth = edid.panel_bits_per_color;
|
||||||
|
printk(BIOS_SPEW, "%s: configuration updated by EDID.\n", __func__);
|
||||||
|
}
|
||||||
|
|
||||||
void dp_init(void * _config)
|
void dp_init(void * _config)
|
||||||
{
|
{
|
||||||
struct soc_nvidia_tegra124_config *config = (void *)_config;
|
struct soc_nvidia_tegra124_config *config = (void *)_config;
|
||||||
|
@ -639,6 +684,8 @@ void dp_init(void * _config)
|
||||||
dp->aux_base = (void *)TEGRA_ARM_DPAUX;
|
dp->aux_base = (void *)TEGRA_ARM_DPAUX;
|
||||||
dp->link_cfg.is_valid = 0;
|
dp->link_cfg.is_valid = 0;
|
||||||
dp->enabled = 0;
|
dp->enabled = 0;
|
||||||
|
|
||||||
|
tegra_dp_update_config(dp, config);
|
||||||
}
|
}
|
||||||
|
|
||||||
static void tegra_dp_hpd_config(struct tegra_dc_dp_data *dp,
|
static void tegra_dp_hpd_config(struct tegra_dc_dp_data *dp,
|
||||||
|
|
|
@ -79,6 +79,7 @@ enum {
|
||||||
|
|
||||||
enum {
|
enum {
|
||||||
TEGRA_I2C_BASE_COUNT = 6,
|
TEGRA_I2C_BASE_COUNT = 6,
|
||||||
|
TEGRA_EDID_I2C_ADDRESS = 0x50,
|
||||||
};
|
};
|
||||||
|
|
||||||
#endif /* __SOC_NVIDIA_TEGRA124_INCLUDE_SOC_ADDRESS_MAP_H__ */
|
#endif /* __SOC_NVIDIA_TEGRA124_INCLUDE_SOC_ADDRESS_MAP_H__ */
|
||||||
|
|
Loading…
Reference in New Issue