]> rtime.felk.cvut.cz Git - sojka/nv-tegra/linux-3.10.git/commitdiff
video: tegra: dc: detect bootloader initialization
authorXia Yang <xiay@nvidia.com>
Thu, 16 Jan 2014 03:03:32 +0000 (19:03 -0800)
committerJon Mayo <jmayo@nvidia.com>
Mon, 17 Mar 2014 18:24:33 +0000 (11:24 -0700)
Use disp_params commandline parameter to determine if bootloader has
initialized display controller. Then set TEGRA_DC_OUT_INITIALIZED_MODE
accordingly to skip things that causes display resets.

Bug 1401958
Bug 1425201

Change-Id: I8860f5c637760227726a3242a457e300a1538e22
Signed-off-by: Xia Yang <xiay@nvidia.com>
Signed-off-by: Jon Mayo <jmayo@nvidia.com>
Reviewed-on: http://git-master/r/355340

drivers/video/tegra/dc/dc.c
drivers/video/tegra/dc/dc_priv_defs.h

index 4704307e54a2c59cade752906cde01f30ae24b28..d4852f77b347fd860a01f90d85e88f50571ba4ef 100644 (file)
@@ -1373,9 +1373,21 @@ static int tegra_dc_set_out(struct tegra_dc *dc, struct tegra_dc_out *out)
        dc->out = out;
        mode = tegra_dc_get_override_mode(dc);
 
-       if (mode)
+       if (mode) {
                tegra_dc_set_mode(dc, mode);
-       else if (out->n_modes > 0)
+
+               /*
+                * Bootloader should and should only pass disp_params if
+                * it has initialized display controller.  Whenever we see
+                * override modes, we should skip things cause display resets.
+                */
+               dev_info(&dc->ndev->dev, "Bootloader disp_param detected. "
+                               "Detected mode: %dx%d (on %dx%dmm) pclk=%d\n",
+                               dc->mode.h_active, dc->mode.v_active,
+                               dc->out->h_size, dc->out->v_size,
+                               dc->mode.pclk);
+               dc->initialized = true;
+       } else if (out->n_modes > 0)
                tegra_dc_set_mode(dc, &dc->out->modes[0]);
 
        switch (out->type) {
@@ -2171,9 +2183,14 @@ static int tegra_dc_init(struct tegra_dc *dc)
        trace_display_mode(dc, &dc->mode);
 
        if (dc->mode.pclk) {
-               if (tegra_dc_program_mode(dc, &dc->mode)) {
-                       tegra_dc_io_end(dc);
-                       return -EINVAL;
+               if (!dc->initialized) {
+                       if (tegra_dc_program_mode(dc, &dc->mode)) {
+                               tegra_dc_io_end(dc);
+                               return -EINVAL;
+                       }
+               } else {
+                       dev_info(&dc->ndev->dev, "DC initialized, "
+                                       "skipping tegra_dc_program_mode.\n");
                }
        }
 
@@ -2336,9 +2353,11 @@ static int _tegra_dc_set_default_videomode(struct tegra_dc *dc)
        if (dc->mode.pclk == 0) {
                switch (dc->out->type) {
                case TEGRA_DC_OUT_HDMI:
-               /* DC enable called but no videomode is loaded.
-                    Check if HDMI is connected, then set fallback mdoe */
-               if (tegra_dc_hpd(dc)) {
+               /* If DC is enable called, and HDMI is connected,
+                * but DC is not initialized by bootloader and no
+                * mode is set up, then set a fallback mode.
+                */
+               if (tegra_dc_hpd(dc) && (!dc->initialized)) {
                        return tegra_dc_set_fb_mode(dc, &tegra_dc_vga_mode, 0);
                } else
                        return false;
index 6856f48ddcb1799f9fe7876477aa78489e5d81bf..629fd0d4d91bb98159672ba40bb444631ae4d9bd 100644 (file)
@@ -142,6 +142,13 @@ struct tegra_dc {
        bool                            enabled;
        bool                            suspended;
 
+       /* Some of the setup code could reset display even if
+        * DC is already by bootloader.  This one-time mark is
+        * used to suppress such code blocks during system boot,
+        * a.k.a the call stack above tegra_dc_probe().
+        */
+       bool                            initialized;
+
        struct tegra_dc_out             *out;
        struct tegra_dc_out_ops         *out_ops;
        void                            *out_data;