summaryrefslogtreecommitdiffstats
path: root/drivers/video/tegra124/display.c
diff options
context:
space:
mode:
authorSimon Glass <sjg@chromium.org>2016-01-30 16:37:50 -0700
committerTom Warren <twarren@nvidia.com>2016-02-16 09:17:51 -0700
commitd76592122b347473f09a440702cc3be03e368511 (patch)
treeb826b9e3566253e8a3f326bd0e46200a841f5f70 /drivers/video/tegra124/display.c
parent135a87ef43566cdd592fa9fd899bf435aa14aaa3 (diff)
downloadtalos-obmc-uboot-d76592122b347473f09a440702cc3be03e368511.tar.gz
talos-obmc-uboot-d76592122b347473f09a440702cc3be03e368511.zip
tegra: nyan-big: Move the LCD driver to driver model
Adjust the driver to use driver model. The SOR becomes a bridge device. We use the normal simple_panel driver to handle the display itself. We also need to enable some options such as regulators, PWMs and DM_VIDEO itself. Signed-off-by: Simon Glass <sjg@chromium.org> Acked-by: Anatolij Gustschin <agust@denx.de> Signed-off-by: Tom Warren <twarren@nvidia.com>
Diffstat (limited to 'drivers/video/tegra124/display.c')
-rw-r--r--drivers/video/tegra124/display.c169
1 files changed, 69 insertions, 100 deletions
diff --git a/drivers/video/tegra124/display.c b/drivers/video/tegra124/display.c
index b4c4093694..2f1f0df20e 100644
--- a/drivers/video/tegra124/display.c
+++ b/drivers/video/tegra124/display.c
@@ -14,11 +14,13 @@
#include <edid.h>
#include <fdtdec.h>
#include <lcd.h>
+#include <video.h>
#include <asm/gpio.h>
#include <asm/io.h>
#include <asm/arch/clock.h>
#include <asm/arch/pwm.h>
#include <asm/arch-tegra/dc.h>
+#include <dm/uclass-internal.h>
#include "displayport.h"
DECLARE_GLOBAL_DATA_PTR;
@@ -333,73 +335,46 @@ static int display_update_config_from_edid(struct udevice *dp_dev,
return 0;
}
-/* Somewhat torturous method */
-static int get_backlight_info(const void *blob, struct gpio_desc *vdd,
- struct gpio_desc *enable, int *pwmp)
-{
- int sor, panel, backlight, power;
- const u32 *prop;
- int len;
- int ret;
-
- *pwmp = 0;
- sor = fdtdec_next_compatible(blob, 0, COMPAT_NVIDIA_TEGRA124_SOR);
- if (sor < 0)
- return -ENOENT;
- panel = fdtdec_lookup_phandle(blob, sor, "nvidia,panel");
- if (panel < 0)
- return -ENOENT;
- backlight = fdtdec_lookup_phandle(blob, panel, "backlight");
- if (backlight < 0)
- return -ENOENT;
- ret = gpio_request_by_name_nodev(blob, backlight, "enable-gpios", 0,
- enable, GPIOD_IS_OUT);
- if (ret)
- return ret;
- prop = fdt_getprop(blob, backlight, "pwms", &len);
- if (!prop || len != 3 * sizeof(u32))
- return -EINVAL;
- *pwmp = fdt32_to_cpu(prop[1]);
-
- power = fdtdec_lookup_phandle(blob, backlight, "power-supply");
- if (power < 0)
- return -ENOENT;
- ret = gpio_request_by_name_nodev(blob, power, "gpio", 0, vdd,
- GPIOD_IS_OUT);
- if (ret)
- goto err;
-
- return 0;
-
-err:
- dm_gpio_free(NULL, enable);
- return ret;
-}
-
-static int display_init(void *lcdbase, int fb_bits_per_pixel,
- struct display_timing *timing)
+static int display_init(struct udevice *dev, void *lcdbase,
+ int fb_bits_per_pixel, struct display_timing *timing)
{
+ struct display_plat *disp_uc_plat;
struct dc_ctlr *dc_ctlr;
const void *blob = gd->fdt_blob;
struct udevice *dp_dev;
const int href_to_sync = 1, vref_to_sync = 1;
int panel_bpp = 18; /* default 18 bits per pixel */
u32 plld_rate;
- struct gpio_desc vdd_gpio, enable_gpio;
- int pwm;
- int node;
int ret;
+ /*
+ * Before we probe the display device (eDP), tell it that this device
+ * is are the source of the display data.
+ */
+ ret = uclass_find_first_device(UCLASS_DISPLAY, &dp_dev);
+ if (ret) {
+ debug("%s: device '%s' display not found (ret=%d)\n", __func__,
+ dev->name, ret);
+ return ret;
+ }
+
+ disp_uc_plat = dev_get_uclass_platdata(dp_dev);
+ debug("Found device '%s', disp_uc_priv=%p\n", dp_dev->name,
+ disp_uc_plat);
+ disp_uc_plat->src_dev = dev;
+
ret = uclass_get_device(UCLASS_DISPLAY, 0, &dp_dev);
- if (ret)
+ if (ret) {
+ debug("%s: Failed to probe eDP, ret=%d\n", __func__, ret);
return ret;
+ }
- node = fdtdec_next_compatible(blob, 0, COMPAT_NVIDIA_TEGRA124_DC);
- if (node < 0)
- return -ENOENT;
- dc_ctlr = (struct dc_ctlr *)fdtdec_get_addr(blob, node, "reg");
- if (fdtdec_decode_display_timing(blob, node, 0, timing))
+ dc_ctlr = (struct dc_ctlr *)fdtdec_get_addr(blob, dev->of_offset,
+ "reg");
+ if (fdtdec_decode_display_timing(blob, dev->of_offset, 0, timing)) {
+ debug("%s: Failed to decode display timing\n", __func__);
return -EINVAL;
+ }
ret = display_update_config_from_edid(dp_dev, &panel_bpp, timing);
if (ret) {
@@ -407,12 +382,6 @@ static int display_init(void *lcdbase, int fb_bits_per_pixel,
dump_config(panel_bpp, timing);
}
- if (!get_backlight_info(blob, &vdd_gpio, &enable_gpio, &pwm)) {
- dm_gpio_set_value(&vdd_gpio, 1);
- debug("%s: backlight vdd setting gpio %08x to %d\n",
- __func__, gpio_get_number(&vdd_gpio), 1);
- }
-
/*
* The plld is programmed with the assumption of the SHIFT_CLK_DIVIDER
* and PIXEL_CLK_DIVIDER are zero (divide by 1). See the
@@ -443,21 +412,15 @@ static int display_init(void *lcdbase, int fb_bits_per_pixel,
/* Enable dp */
ret = display_enable(dp_dev, panel_bpp, timing);
- if (ret)
+ if (ret) {
+ debug("dc: failed to enable display: ret=%d\n", ret);
return ret;
+ }
ret = update_window(dc_ctlr, (ulong)lcdbase, fb_bits_per_pixel, timing);
- if (ret)
+ if (ret) {
+ debug("dc: failed to update window\n");
return ret;
-
- /* Set up Tegra PWM to drive the panel backlight */
- pwm_enable(pwm, 0, 220, 0x2e);
- udelay(10 * 1000);
-
- if (dm_gpio_is_valid(&enable_gpio)) {
- dm_gpio_set_value(&enable_gpio, 1);
- debug("%s: backlight enable setting gpio %08x to %d\n",
- __func__, gpio_get_number(&enable_gpio), 1);
}
return 0;
@@ -470,29 +433,10 @@ enum {
LCD_MAX_LOG2_BPP = 4, /* 2^4 = 16 bpp */
};
-vidinfo_t panel_info = {
- /* Insert a value here so that we don't end up in the BSS */
- .vl_col = -1,
-};
-
-int tegra_lcd_check_next_stage(const void *blob, int wait)
-{
- return 0;
-}
-
-void tegra_lcd_early_init(const void *blob)
-{
- /*
- * Go with the maximum size for now. We will fix this up after
- * relocation. These values are only used for memory alocation.
- */
- panel_info.vl_col = LCD_MAX_WIDTH;
- panel_info.vl_row = LCD_MAX_HEIGHT;
- panel_info.vl_bpix = LCD_MAX_LOG2_BPP;
-}
-
-static int tegra124_lcd_init(void *lcdbase)
+static int tegra124_lcd_init(struct udevice *dev, void *lcdbase,
+ enum video_log2_bpp l2bpp)
{
+ struct video_priv *uc_priv = dev_get_uclass_priv(dev);
struct display_timing timing;
int ret;
@@ -512,30 +456,55 @@ static int tegra124_lcd_init(void *lcdbase)
reset_set_enable(PERIPH_ID_DPAUX, 0);
reset_set_enable(PERIPH_ID_SOR0, 0);
- ret = display_init(lcdbase, 1 << LCD_BPP, &timing);
+ ret = display_init(dev, lcdbase, 1 << l2bpp, &timing);
if (ret)
return ret;
- panel_info.vl_col = roundup(timing.hactive.typ, 16);
- panel_info.vl_row = timing.vactive.typ;
+ uc_priv->xsize = roundup(timing.hactive.typ, 16);
+ uc_priv->ysize = timing.vactive.typ;
+ uc_priv->bpix = l2bpp;
- lcd_set_flush_dcache(1);
+ video_set_flush_dcache(dev, 1);
+ debug("%s: done\n", __func__);
return 0;
}
-void lcd_ctrl_init(void *lcdbase)
+static int tegra124_lcd_probe(struct udevice *dev)
{
+ struct video_uc_platdata *plat = dev_get_uclass_platdata(dev);
ulong start;
int ret;
start = get_timer(0);
- ret = tegra124_lcd_init(lcdbase);
+ ret = tegra124_lcd_init(dev, (void *)plat->base, VIDEO_BPP16);
debug("LCD init took %lu ms\n", get_timer(start));
if (ret)
printf("%s: Error %d\n", __func__, ret);
+
+ return 0;
}
-void lcd_enable(void)
+static int tegra124_lcd_bind(struct udevice *dev)
{
+ struct video_uc_platdata *uc_plat = dev_get_uclass_platdata(dev);
+
+ uc_plat->size = LCD_MAX_WIDTH * LCD_MAX_HEIGHT *
+ (1 << VIDEO_BPP16) / 8;
+ debug("%s: Frame buffer size %x\n", __func__, uc_plat->size);
+
+ return 0;
}
+
+static const struct udevice_id tegra124_lcd_ids[] = {
+ { .compatible = "nvidia,tegra124-dc" },
+ { }
+};
+
+U_BOOT_DRIVER(tegra124_dc) = {
+ .name = "tegra124-dc",
+ .id = UCLASS_VIDEO,
+ .of_match = tegra124_lcd_ids,
+ .bind = tegra124_lcd_bind,
+ .probe = tegra124_lcd_probe,
+};
OpenPOWER on IntegriCloud