Commit bb5930d5 authored by Simon Glass's avatar Simon Glass Committed by Minkyu Kang

exynos: video: Convert several boards to driver model for video

Update several boards to use driver model for video. This involves changes
to the EDP and FIMD (frame buffer) drivers. Existing PWM, simple-panel and
pwm-backlight drivers are used. These work without additional configuration
since they use the device tree settings in the same way as Linux.

Boards converted are:
- snow
- spring
- peach-pit
- peach-pi

All have been tested. Not converted:

- MIPI display driver
- s5pc210_universal
- smdk5420
- smdk5250
- trats
- trats2
Signed-off-by: 's avatarSimon Glass <sjg@chromium.org>
Acked-by: 's avatarAnatolij Gustschin <agust@denx.de>
Signed-off-by: 's avatarMinkyu Kang <mk7.kang@samsung.com>
parent 8b449a66
......@@ -72,6 +72,7 @@ struct exynos_dp_priv {
unsigned char dpcd_rev;
/*support enhanced frame cap */
unsigned char dpcd_efc;
struct exynos_dp *regs;
};
enum analog_power_block {
......
......@@ -158,21 +158,6 @@ int board_early_init_f(void)
board_i2c_init(gd->fdt_blob);
#endif
#if defined(CONFIG_EXYNOS_FB)
/*
* board_init_f(arch/arm/lib/board.c) calls lcd_setmem() which needs
* panel_info.vl_col, panel_info.vl_row and panel_info.vl_bpix,
* to reserve frame-buffer memory at a very early stage. So, we need
* to fill panel_info.vl_col, panel_info.vl_row and panel_info.vl_bpix
* before lcd_setmem() is called.
*/
err = exynos_lcd_early_init(gd->fdt_blob);
if (err) {
debug("LCD early init failed\n");
return err;
}
#endif
return exynos_early_init_f();
}
#endif
......
......@@ -47,6 +47,8 @@ CONFIG_DM_PMIC=y
CONFIG_PMIC_TPS65090=y
CONFIG_DM_REGULATOR=y
CONFIG_REGULATOR_TPS65090=y
CONFIG_DM_PWM=y
CONFIG_PWM_EXYNOS=y
CONFIG_SOUND=y
CONFIG_I2S=y
CONFIG_I2S_SAMSUNG=y
......@@ -56,6 +58,8 @@ CONFIG_EXYNOS_SPI=y
CONFIG_TPM_TIS_INFINEON=y
CONFIG_USB=y
CONFIG_DM_USB=y
CONFIG_DM_VIDEO=y
CONFIG_DISPLAY=y
CONFIG_VIDEO_BRIDGE=y
CONFIG_VIDEO_BRIDGE_PARADE_PS862X=y
CONFIG_TPM=y
......
......@@ -47,6 +47,8 @@ CONFIG_DM_PMIC=y
CONFIG_PMIC_TPS65090=y
CONFIG_DM_REGULATOR=y
CONFIG_REGULATOR_TPS65090=y
CONFIG_DM_PWM=y
CONFIG_PWM_EXYNOS=y
CONFIG_SOUND=y
CONFIG_I2S=y
CONFIG_I2S_SAMSUNG=y
......@@ -56,6 +58,8 @@ CONFIG_EXYNOS_SPI=y
CONFIG_TPM_TIS_INFINEON=y
CONFIG_USB=y
CONFIG_DM_USB=y
CONFIG_DM_VIDEO=y
CONFIG_DISPLAY=y
CONFIG_VIDEO_BRIDGE=y
CONFIG_VIDEO_BRIDGE_PARADE_PS862X=y
CONFIG_TPM=y
......
......@@ -52,6 +52,8 @@ CONFIG_DM_REGULATOR=y
CONFIG_DM_REGULATOR_MAX77686=y
CONFIG_REGULATOR_S5M8767=y
CONFIG_REGULATOR_TPS65090=y
CONFIG_DM_PWM=y
CONFIG_PWM_EXYNOS=y
CONFIG_DEBUG_UART=y
CONFIG_DEBUG_UART_S5P=y
CONFIG_DEBUG_UART_BASE=0x12c30000
......@@ -65,6 +67,8 @@ CONFIG_EXYNOS_SPI=y
CONFIG_TPM_TIS_INFINEON=y
CONFIG_USB=y
CONFIG_DM_USB=y
CONFIG_DM_VIDEO=y
CONFIG_DISPLAY=y
CONFIG_VIDEO_BRIDGE=y
CONFIG_VIDEO_BRIDGE_PARADE_PS862X=y
CONFIG_VIDEO_BRIDGE_NXP_PTN3460=y
......
......@@ -52,6 +52,8 @@ CONFIG_DM_REGULATOR=y
CONFIG_DM_REGULATOR_MAX77686=y
CONFIG_REGULATOR_S5M8767=y
CONFIG_REGULATOR_TPS65090=y
CONFIG_DM_PWM=y
CONFIG_PWM_EXYNOS=y
CONFIG_DEBUG_UART=y
CONFIG_DEBUG_UART_S5P=y
CONFIG_DEBUG_UART_BASE=0x12c30000
......@@ -65,6 +67,8 @@ CONFIG_EXYNOS_SPI=y
CONFIG_TPM_TIS_INFINEON=y
CONFIG_USB=y
CONFIG_DM_USB=y
CONFIG_DM_VIDEO=y
CONFIG_DISPLAY=y
CONFIG_VIDEO_BRIDGE=y
CONFIG_VIDEO_BRIDGE_PARADE_PS862X=y
CONFIG_TPM=y
......
......@@ -7,17 +7,21 @@
*/
#include <config.h>
#include <dm.h>
#include <common.h>
#include <display.h>
#include <fdtdec.h>
#include <libfdt.h>
#include <malloc.h>
#include <video_bridge.h>
#include <linux/compat.h>
#include <linux/err.h>
#include <asm/arch/clk.h>
#include <asm/arch/cpu.h>
#include <asm/arch/dp_info.h>
#include <asm/arch/dp.h>
#include <asm/arch/pinmux.h>
#include <asm/arch/power.h>
#include <fdtdec.h>
#include <libfdt.h>
#include "exynos_dp_lowlevel.h"
......@@ -872,15 +876,19 @@ static unsigned int exynos_dp_config_video(struct exynos_dp *regs,
return ret;
}
int exynos_dp_parse_dt(const void *blob, struct exynos_dp_priv *priv)
static int exynos_dp_ofdata_to_platdata(struct udevice *dev)
{
unsigned int node = fdtdec_next_compatible(blob, 0,
COMPAT_SAMSUNG_EXYNOS5_DP);
if (node <= 0) {
debug("exynos_dp: Can't get device node for dp\n");
return -ENODEV;
}
struct exynos_dp_priv *priv = dev_get_priv(dev);
const void *blob = gd->fdt_blob;
unsigned int node = dev->of_offset;
fdt_addr_t addr;
addr = dev_get_addr(dev);
if (addr == FDT_ADDR_T_NONE) {
debug("Can't get the DP base address\n");
return -EINVAL;
}
priv->regs = (struct exynos_dp *)addr;
priv->disp_info.h_res = fdtdec_get_int(blob, node,
"samsung,h-res", 0);
priv->disp_info.h_sync_width = fdtdec_get_int(blob, node,
......@@ -926,34 +934,97 @@ int exynos_dp_parse_dt(const void *blob, struct exynos_dp_priv *priv)
return 0;
}
unsigned int exynos_init_dp(void)
static int exynos_dp_bridge_init(struct udevice *dev)
{
unsigned int ret;
struct exynos_dp_priv *priv;
struct exynos_dp *regs;
int node;
const int max_tries = 10;
int num_tries;
int ret;
priv = kzalloc(sizeof(struct exynos_dp_priv), GFP_KERNEL);
if (!priv) {
debug("failed to allocate edp device object.\n");
return -EFAULT;
debug("%s\n", __func__);
ret = video_bridge_attach(dev);
if (ret) {
debug("video bridge init failed: %d\n", ret);
return ret;
}
if (exynos_dp_parse_dt(gd->fdt_blob, priv))
debug("unable to parse DP DT node\n");
/*
* We need to wait for 90ms after bringing up the bridge since there
* is a phantom "high" on the HPD chip during its bootup. The phantom
* high comes within 7ms of de-asserting PD and persists for at least
* 15ms. The real high comes roughly 50ms after PD is de-asserted. The
* phantom high makes it hard for us to know when the NXP chip is up.
*/
mdelay(90);
node = fdtdec_next_compatible(gd->fdt_blob, 0,
COMPAT_SAMSUNG_EXYNOS5_DP);
if (node <= 0)
debug("exynos_dp: Can't get device node for dp\n");
for (num_tries = 0; num_tries < max_tries; num_tries++) {
/* Check HPD. If it's high, or we don't have it, all is well */
ret = video_bridge_check_attached(dev);
if (!ret || ret == -ENOENT)
return 0;
regs = (struct exynos_dp *)fdtdec_get_addr(gd->fdt_blob, node,
"reg");
if (regs == NULL)
debug("Can't get the DP base address\n");
debug("%s: eDP bridge failed to come up; try %d of %d\n",
__func__, num_tries, max_tries);
}
/* Immediately go into bridge reset if the hp line is not high */
return -EIO;
}
static int exynos_dp_bridge_setup(const void *blob)
{
const int max_tries = 2;
int num_tries;
struct udevice *dev;
int ret;
/* Configure I2C registers for Parade bridge */
ret = uclass_get_device(UCLASS_VIDEO_BRIDGE, 0, &dev);
if (ret) {
debug("video bridge init failed: %d\n", ret);
return ret;
}
if (strncmp(dev->driver->name, "parade", 6)) {
/* Mux HPHPD to the special hotplug detect mode */
exynos_pinmux_config(PERIPH_ID_DPHPD, 0);
}
for (num_tries = 0; num_tries < max_tries; num_tries++) {
ret = exynos_dp_bridge_init(dev);
if (!ret)
return 0;
if (num_tries == max_tries - 1)
break;
/*
* If we're here, the bridge chip failed to initialise.
* Power down the bridge in an attempt to reset.
*/
video_bridge_set_active(dev, false);
/*
* Arbitrarily wait 300ms here with DP_N low. Don't know for
* sure how long we should wait, but we're being paranoid.
*/
mdelay(300);
}
return ret;
}
int exynos_dp_enable(struct udevice *dev, int panel_bpp,
const struct display_timing *timing)
{
struct exynos_dp_priv *priv = dev_get_priv(dev);
struct exynos_dp *regs = priv->regs;
unsigned int ret;
debug("%s: start\n", __func__);
exynos_dp_disp_info(&priv->disp_info);
ret = exynos_dp_bridge_setup(gd->fdt_blob);
if (ret && ret != -ENODEV)
printf("LCD bridge failed to enable: %d\n", ret);
exynos_dp_phy_ctrl(1);
ret = exynos_dp_init_dp(regs);
......@@ -992,3 +1063,22 @@ unsigned int exynos_init_dp(void)
return ret;
}
static const struct dm_display_ops exynos_dp_ops = {
.enable = exynos_dp_enable,
};
static const struct udevice_id exynos_dp_ids[] = {
{ .compatible = "samsung,exynos5-dp" },
{ }
};
U_BOOT_DRIVER(exynos_dp) = {
.name = "eexynos_dp",
.id = UCLASS_DISPLAY,
.of_match = exynos_dp_ids,
.ops = &exynos_dp_ops,
.ofdata_to_platdata = exynos_dp_ofdata_to_platdata,
.priv_auto_alloc_size = sizeof(struct exynos_dp_priv),
};
This diff is collapsed.
......@@ -88,6 +88,8 @@ static const struct panel_ops simple_panel_ops = {
static const struct udevice_id simple_panel_ids[] = {
{ .compatible = "simple-panel" },
{ .compatible = "auo,b133xtn01" },
{ .compatible = "auo,b116xw03" },
{ .compatible = "auo,b133htn01" },
{ }
};
......
......@@ -124,7 +124,6 @@
#define CONFIG_SYS_I2C_S3C24X0
#define CONFIG_SYS_I2C_S3C24X0_SPEED 100000 /* 100 Kbps */
#define CONFIG_SYS_I2C_S3C24X0_SLAVE 0x0
#define CONFIG_I2C_EDID
/* SPI */
#ifdef CONFIG_SPI_FLASH
......
......@@ -13,8 +13,8 @@
#undef EXYNOS_DEVICE_SETTINGS
#define EXYNOS_DEVICE_SETTINGS \
"stdin=serial,cros-ec-keyb\0" \
"stdout=serial,lcd\0" \
"stderr=serial,lcd\0"
"stdout=serial,vidconsole\0" \
"stderr=serial,vidconsole\0"
#define CONFIG_EXYNOS5_DT
......@@ -32,6 +32,7 @@
#define CONFIG_EXYNOS_FB
#define CONFIG_EXYNOS_DP
#define LCD_BPP LCD_COLOR16
#define CONFIG_SYS_WHITE_ON_BLACK
#endif
/* Enable keyboard */
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment