[PATCH v2 3/3] video: sunxi_display: Convert to DM_VIDEO

Michael Nazzareno Trimarchi michael at amarulasolutions.com
Thu Jun 18 19:13:55 CEST 2020


Hi

On Thu, Jun 18, 2020 at 6:07 PM Jagan Teki <jagan at amarulasolutions.com> wrote:
>
> On Thu, Jun 18, 2020 at 12:54 PM Maxime Ripard <maxime at cerno.tech> wrote:
> >
> > On Thu, Jun 18, 2020 at 01:54:37AM +0530, Jagan Teki wrote:
> > > DM_VIDEO migration deadline is already expired, but around
> > > 80 Allwinner boards are still using video in a legacy way.
> > >
> > > ===================== WARNING ======================
> > > This board does not use CONFIG_DM_VIDEO Please update
> > > the board to use CONFIG_DM_VIDEO before the v2019.07 release.
> > > Failure to update by the deadline may result in board removal.
> > > See doc/driver-model/migration.rst for more info.
> > > ====================================================
> > >
> > > So let's live these boards on the tree before the video maintainer
> > > removes it by converting in to DM_VIDEO.
> > >
> > > Tested in Bananapi M1+ Plus 1920x1200 HDMI out.
> > >
> > > Signed-off-by: Jagan Teki <jagan at amarulasolutions.com>
> > > ---
> > > Changes for v2:
> > > - add BMP support
> > >
> > >  arch/arm/mach-sunxi/Kconfig         |   4 +-
> > >  drivers/video/sunxi/sunxi_display.c | 264 ++++++++++++++++------------
> > >  include/configs/sunxi-common.h      |  17 --
> > >  scripts/config_whitelist.txt        |   1 -
> > >  4 files changed, 157 insertions(+), 129 deletions(-)
> > >
> > > diff --git a/arch/arm/mach-sunxi/Kconfig b/arch/arm/mach-sunxi/Kconfig
> > > index be0822bfb7..7d2fb55ff0 100644
> > > --- a/arch/arm/mach-sunxi/Kconfig
> > > +++ b/arch/arm/mach-sunxi/Kconfig
> > > @@ -758,8 +758,10 @@ config VIDEO_SUNXI
> > >       depends on !MACH_SUN9I
> > >       depends on !MACH_SUN50I
> > >       depends on !MACH_SUN50I_H6
> > > -     select VIDEO
> > > +     select DM_VIDEO
> > > +     select DISPLAY
> > >       imply VIDEO_DT_SIMPLEFB
> > > +     imply CMD_BMP
> > >       default y
> > >       ---help---
> > >       Say Y here to add support for using a cfb console on the HDMI, LCD
> > > diff --git a/drivers/video/sunxi/sunxi_display.c b/drivers/video/sunxi/sunxi_display.c
> > > index f52aba4d21..fb51b0c5ba 100644
> > > --- a/drivers/video/sunxi/sunxi_display.c
> > > +++ b/drivers/video/sunxi/sunxi_display.c
> > > @@ -7,6 +7,8 @@
> > >   */
> > >
> > >  #include <common.h>
> > > +#include <display.h>
> > > +#include <dm.h>
> > >  #include <cpu_func.h>
> > >  #include <efi_loader.h>
> > >  #include <init.h>
> > > @@ -28,7 +30,9 @@
> > >  #include <fdt_support.h>
> > >  #include <i2c.h>
> > >  #include <malloc.h>
> > > +#include <video.h>
> > >  #include <video_fb.h>
> > > +#include <dm/uclass-internal.h>
> > >  #include "../videomodes.h"
> > >  #include "../anx9804.h"
> > >  #include "../hitachi_tx18d42vm_lcd.h"
> > > @@ -45,6 +49,13 @@
> > >
> > >  DECLARE_GLOBAL_DATA_PTR;
> > >
> > > +enum {
> > > +     /* Maximum LCD size we support */
> > > +     LCD_MAX_WIDTH           = 3840,
> > > +     LCD_MAX_HEIGHT          = 2160,
> > > +     LCD_MAX_LOG2_BPP        = VIDEO_BPP32,
> > > +};
> >
> > Why is that an enum? Those three values don't have any relationship with
> > each other.
>
> Not sure I understand your question. These are maximum resolution
> followed by maximum bpp supporting. based on these the fbbuffer
> allocation happens, please see sunxi_de_bind on this patch.
>
> >
> > >  enum sunxi_monitor {
> > >       sunxi_monitor_none,
> > >       sunxi_monitor_dvi,
> > > @@ -59,12 +70,11 @@ enum sunxi_monitor {
> > >  #define SUNXI_MONITOR_LAST sunxi_monitor_composite_pal_nc
> > >
> > >  struct sunxi_display {
> > > -     GraphicDevice graphic_device;
> > >       enum sunxi_monitor monitor;
> > >       unsigned int depth;
> > >       unsigned int fb_addr;
> > >       unsigned int fb_size;
> > > -} sunxi_display;
> > > +};
> >
> > This looks unrelated?
> >
> > >  const struct ctfb_res_modes composite_video_modes[2] = {
> > >       /*  x     y  hz  pixclk ps/kHz   le   ri  up  lo   hs vs  s  vmode */
> > > @@ -214,7 +224,8 @@ static int sunxi_hdmi_edid_get_block(int block, u8 *buf)
> > >       return r;
> > >  }
> > >
> > > -static int sunxi_hdmi_edid_get_mode(struct ctfb_res_modes *mode,
> > > +static int sunxi_hdmi_edid_get_mode(struct sunxi_display *sunxi_display,
> > > +                                 struct ctfb_res_modes *mode,
> > >                                   bool verbose_mode)
> > >  {
> > >       struct edid1_info edid1;
> > > @@ -291,14 +302,14 @@ static int sunxi_hdmi_edid_get_mode(struct ctfb_res_modes *mode,
> > >       }
> > >
> > >       /* Check for basic audio support, if found enable hdmi output */
> > > -     sunxi_display.monitor = sunxi_monitor_dvi;
> > > +     sunxi_display->monitor = sunxi_monitor_dvi;
> > >       for (i = 0; i < ext_blocks; i++) {
> > >               if (cea681[i].extension_tag != EDID_CEA861_EXTENSION_TAG ||
> > >                   cea681[i].revision < 2)
> > >                       continue;
> > >
> > >               if (EDID_CEA861_SUPPORTS_BASIC_AUDIO(cea681[i]))
> > > -                     sunxi_display.monitor = sunxi_monitor_hdmi;
> > > +                     sunxi_display->monitor = sunxi_monitor_hdmi;
> > >       }
> > >
> > >       return 0;
> > > @@ -414,9 +425,9 @@ static void sunxi_frontend_mode_set(const struct ctfb_res_modes *mode,
> > >  static void sunxi_frontend_enable(void) {}
> > >  #endif
> > >
> > > -static bool sunxi_is_composite(void)
> > > +static bool sunxi_is_composite(enum sunxi_monitor monitor)
> > >  {
> > > -     switch (sunxi_display.monitor) {
> > > +     switch (monitor) {
> > >       case sunxi_monitor_none:
> > >       case sunxi_monitor_dvi:
> > >       case sunxi_monitor_hdmi:
> > > @@ -473,7 +484,8 @@ static const u32 sunxi_rgb2yuv_coef[12] = {
> > >  };
> > >
> > >  static void sunxi_composer_mode_set(const struct ctfb_res_modes *mode,
> > > -                                 unsigned int address)
> > > +                                 unsigned int address,
> > > +                                 enum sunxi_monitor monitor)
> > >  {
> > >       struct sunxi_de_be_reg * const de_be =
> > >               (struct sunxi_de_be_reg *)SUNXI_DE_BE0_BASE;
> > > @@ -502,7 +514,7 @@ static void sunxi_composer_mode_set(const struct ctfb_res_modes *mode,
> > >  #endif
> > >                            SUNXI_DE_BE_MODE_INTERLACE_ENABLE);
> > >
> > > -     if (sunxi_is_composite()) {
> > > +     if (sunxi_is_composite(monitor)) {
> > >               writel(SUNXI_DE_BE_OUTPUT_COLOR_CTRL_ENABLE,
> > >                      &de_be->output_color_ctrl);
> > >               for (i = 0; i < 12; i++)
> > > @@ -616,7 +628,8 @@ static void sunxi_lcdc_backlight_enable(void)
> > >               gpio_direction_output(pin, PWM_ON);
> > >  }
> > >
> > > -static void sunxi_lcdc_tcon0_mode_set(const struct ctfb_res_modes *mode,
> > > +static void sunxi_lcdc_tcon0_mode_set(struct sunxi_display *sunxi_display,
> > > +                                   const struct ctfb_res_modes *mode,
> > >                                     bool for_ext_vga_dac)
> > >  {
> > >       struct sunxi_lcdc_reg * const lcdc =
> > > @@ -643,17 +656,18 @@ static void sunxi_lcdc_tcon0_mode_set(const struct ctfb_res_modes *mode,
> > >       }
> > >
> > >       lcdc_pll_set(ccm, 0, mode->pixclock_khz, &clk_div, &clk_double,
> > > -                  sunxi_is_composite());
> > > +                  sunxi_is_composite(sunxi_display->monitor));
> > >
> > >       video_ctfb_mode_to_display_timing(mode, &timing);
> > >       lcdc_tcon0_mode_set(lcdc, &timing, clk_div, for_ext_vga_dac,
> > > -                         sunxi_display.depth, CONFIG_VIDEO_LCD_DCLK_PHASE);
> > > +                         sunxi_display->depth, CONFIG_VIDEO_LCD_DCLK_PHASE);
> > >  }
> > >
> > >  #if defined CONFIG_VIDEO_HDMI || defined CONFIG_VIDEO_VGA || defined CONFIG_VIDEO_COMPOSITE
> > >  static void sunxi_lcdc_tcon1_mode_set(const struct ctfb_res_modes *mode,
> > >                                     int *clk_div, int *clk_double,
> > > -                                   bool use_portd_hvsync)
> > > +                                   bool use_portd_hvsync,
> > > +                                   enum sunxi_monitor monitor)
> > >  {
> > >       struct sunxi_lcdc_reg * const lcdc =
> > >               (struct sunxi_lcdc_reg *)SUNXI_LCD0_BASE;
> > > @@ -663,7 +677,7 @@ static void sunxi_lcdc_tcon1_mode_set(const struct ctfb_res_modes *mode,
> > >
> > >       video_ctfb_mode_to_display_timing(mode, &timing);
> > >       lcdc_tcon1_mode_set(lcdc, &timing, use_portd_hvsync,
> > > -                         sunxi_is_composite());
> > > +                         sunxi_is_composite(monitor));
> > >
> > >       if (use_portd_hvsync) {
> > >               sunxi_gpio_set_cfgpin(SUNXI_GPD(26), SUNXI_GPD_LCD0);
> > > @@ -671,7 +685,7 @@ static void sunxi_lcdc_tcon1_mode_set(const struct ctfb_res_modes *mode,
> > >       }
> > >
> > >       lcdc_pll_set(ccm, 1, mode->pixclock_khz, clk_div, clk_double,
> > > -                  sunxi_is_composite());
> > > +                  sunxi_is_composite(monitor));
> > >  }
> > >  #endif /* CONFIG_VIDEO_HDMI || defined CONFIG_VIDEO_VGA || CONFIG_VIDEO_COMPOSITE */
> > >
> > > @@ -725,7 +739,8 @@ static void sunxi_hdmi_setup_info_frames(const struct ctfb_res_modes *mode)
> > >  }
> > >
> > >  static void sunxi_hdmi_mode_set(const struct ctfb_res_modes *mode,
> > > -                             int clk_div, int clk_double)
> > > +                             int clk_div, int clk_double,
> > > +                             enum sunxi_monitor monitor)
> > >  {
> > >       struct sunxi_hdmi_reg * const hdmi =
> > >               (struct sunxi_hdmi_reg *)SUNXI_HDMI_BASE;
> > > @@ -734,7 +749,7 @@ static void sunxi_hdmi_mode_set(const struct ctfb_res_modes *mode,
> > >       /* Write clear interrupt status bits */
> > >       writel(SUNXI_HDMI_IRQ_STATUS_BITS, &hdmi->irq);
> > >
> > > -     if (sunxi_display.monitor == sunxi_monitor_hdmi)
> > > +     if (monitor == sunxi_monitor_hdmi)
> > >               sunxi_hdmi_setup_info_frames(mode);
> > >
> > >       /* Set input sync enable */
> > > @@ -789,7 +804,7 @@ static void sunxi_hdmi_enable(void)
> > >
> > >  #if defined CONFIG_VIDEO_VGA || defined CONFIG_VIDEO_COMPOSITE
> > >
> > > -static void sunxi_tvencoder_mode_set(void)
> > > +static void sunxi_tvencoder_mode_set(enum sunxi_monitor monitor)
> > >  {
> > >       struct sunxi_ccm_reg * const ccm =
> > >               (struct sunxi_ccm_reg *)SUNXI_CCM_BASE;
> > > @@ -801,7 +816,7 @@ static void sunxi_tvencoder_mode_set(void)
> > >       /* Clock on */
> > >       setbits_le32(&ccm->ahb_gate1, 1 << AHB_GATE_OFFSET_TVE0);
> > >
> > > -     switch (sunxi_display.monitor) {
> > > +     switch (monitor) {
> > >       case sunxi_monitor_vga:
> > >               tvencoder_mode_set(tve, tve_mode_vga);
> > >               break;
> > > @@ -896,26 +911,28 @@ static void sunxi_engines_init(void)
> > >       sunxi_drc_init();
> > >  }
> > >
> > > -static void sunxi_mode_set(const struct ctfb_res_modes *mode,
> > > +static void sunxi_mode_set(struct sunxi_display *sunxi_display,
> > > +                        const struct ctfb_res_modes *mode,
> > >                          unsigned int address)
> > >  {
> > > +     enum sunxi_monitor monitor = sunxi_display->monitor;
> > >       int __maybe_unused clk_div, clk_double;
> > >       struct sunxi_lcdc_reg * const lcdc =
> > >               (struct sunxi_lcdc_reg *)SUNXI_LCD0_BASE;
> > >       struct sunxi_tve_reg * __maybe_unused const tve =
> > >               (struct sunxi_tve_reg *)SUNXI_TVE0_BASE;
> > >
> > > -     switch (sunxi_display.monitor) {
> > > +     switch (sunxi_display->monitor) {
> > >       case sunxi_monitor_none:
> > >               break;
> > >       case sunxi_monitor_dvi:
> > >       case sunxi_monitor_hdmi:
> > >  #ifdef CONFIG_VIDEO_HDMI
> > > -             sunxi_composer_mode_set(mode, address);
> > > -             sunxi_lcdc_tcon1_mode_set(mode, &clk_div, &clk_double, 0);
> > > -             sunxi_hdmi_mode_set(mode, clk_div, clk_double);
> > > +             sunxi_composer_mode_set(mode, address, monitor);
> > > +             sunxi_lcdc_tcon1_mode_set(mode, &clk_div, &clk_double, 0, monitor);
> > > +             sunxi_hdmi_mode_set(mode, clk_div, clk_double, monitor);
> > >               sunxi_composer_enable();
> > > -             lcdc_enable(lcdc, sunxi_display.depth);
> > > +             lcdc_enable(lcdc, sunxi_display->depth);
> > >               sunxi_hdmi_enable();
> > >  #endif
> > >               break;
> > > @@ -930,7 +947,7 @@ static void sunxi_mode_set(const struct ctfb_res_modes *mode,
> > >                       axp_set_eldo(3, 1800);
> > >                       anx9804_init(CONFIG_VIDEO_LCD_I2C_BUS, 4,
> > >                                    ANX9804_DATA_RATE_1620M,
> > > -                                  sunxi_display.depth);
> > > +                                  sunxi_display->depth);
> > >               }
> > >               if (IS_ENABLED(CONFIG_VIDEO_LCD_HITACHI_TX18D42VM)) {
> > >                       mdelay(50); /* Wait for lcd controller power on */
> > > @@ -942,10 +959,10 @@ static void sunxi_mode_set(const struct ctfb_res_modes *mode,
> > >                       i2c_reg_write(0x5c, 0x04, 0x42); /* Turn on the LCD */
> > >                       i2c_set_bus_num(orig_i2c_bus);
> > >               }
> > > -             sunxi_composer_mode_set(mode, address);
> > > -             sunxi_lcdc_tcon0_mode_set(mode, false);
> > > +             sunxi_composer_mode_set(mode, address, monitor);
> > > +             sunxi_lcdc_tcon0_mode_set(sunxi_display, mode, false);
> > >               sunxi_composer_enable();
> > > -             lcdc_enable(lcdc, sunxi_display.depth);
> > > +             lcdc_enable(lcdc, sunxi_display->depth);
> > >  #ifdef CONFIG_VIDEO_LCD_SSD2828
> > >               sunxi_ssd2828_init(mode);
> > >  #endif
> > > @@ -953,17 +970,17 @@ static void sunxi_mode_set(const struct ctfb_res_modes *mode,
> > >               break;
> > >       case sunxi_monitor_vga:
> > >  #ifdef CONFIG_VIDEO_VGA
> > > -             sunxi_composer_mode_set(mode, address);
> > > -             sunxi_lcdc_tcon1_mode_set(mode, &clk_div, &clk_double, 1);
> > > -             sunxi_tvencoder_mode_set();
> > > +             sunxi_composer_mode_set(mode, address, monitor);
> > > +             sunxi_lcdc_tcon1_mode_set(mode, &clk_div, &clk_double, 1, monitor);
> > > +             sunxi_tvencoder_mode_set(monitor);
> > >               sunxi_composer_enable();
> > > -             lcdc_enable(lcdc, sunxi_display.depth);
> > > +             lcdc_enable(lcdc, sunxi_display->depth);
> > >               tvencoder_enable(tve);
> > >  #elif defined CONFIG_VIDEO_VGA_VIA_LCD
> > > -             sunxi_composer_mode_set(mode, address);
> > > -             sunxi_lcdc_tcon0_mode_set(mode, true);
> > > +             sunxi_composer_mode_set(mode, address, monitor);
> > > +             sunxi_lcdc_tcon0_mode_set(sunxi_display, mode, true);
> > >               sunxi_composer_enable();
> > > -             lcdc_enable(lcdc, sunxi_display.depth);
> > > +             lcdc_enable(lcdc, sunxi_display->depth);
> > >               sunxi_vga_external_dac_enable();
> > >  #endif
> > >               break;
> > > @@ -972,11 +989,11 @@ static void sunxi_mode_set(const struct ctfb_res_modes *mode,
> > >       case sunxi_monitor_composite_pal_m:
> > >       case sunxi_monitor_composite_pal_nc:
> > >  #ifdef CONFIG_VIDEO_COMPOSITE
> > > -             sunxi_composer_mode_set(mode, address);
> > > -             sunxi_lcdc_tcon1_mode_set(mode, &clk_div, &clk_double, 0);
> > > -             sunxi_tvencoder_mode_set();
> > > +             sunxi_composer_mode_set(mode, address, monitor);
> > > +             sunxi_lcdc_tcon1_mode_set(mode, &clk_div, &clk_double, 0, monitor);
> > > +             sunxi_tvencoder_mode_set(monitor);
> > >               sunxi_composer_enable();
> > > -             lcdc_enable(lcdc, sunxi_display.depth);
> > > +             lcdc_enable(lcdc, sunxi_display->depth);
> > >               tvencoder_enable(tve);
> > >  #endif
> > >               break;
> > > @@ -999,11 +1016,6 @@ static const char *sunxi_get_mon_desc(enum sunxi_monitor monitor)
> > >       }
> > >  }
> > >
> > > -ulong board_get_usable_ram_top(ulong total_size)
> > > -{
> > > -     return gd->ram_top - CONFIG_SUNXI_MAX_FB_SIZE;
> > > -}
> > > -
> >
> > I couldn't find how you're allocating and reserving the video buffer now
> > for simplefb to use later on.
>
> Based on maximum supporting resolutions and bpp as explained above and
> similar like what sunxi_de2 and other platforms like rockchip. via
> plat->size.


DM_VIDEO, take from the relocation - VIDEO_SIZE if I remember based on MAX video
size. Then there is always a logic to inject in the simple_framebuffer
dts the information for
reserved memory. The platform always defines MAX_SIZE of the video. so
HDMI resolutions
that does not fit the size are not handled. Rockchip is not completed
on this implementation, I have
sent a patch some time ago but I was struggling to have a working
persistent framebuffer

Michael

>
> >
> > >  static bool sunxi_has_hdmi(void)
> > >  {
> > >  #ifdef CONFIG_VIDEO_HDMI
> > > @@ -1052,9 +1064,11 @@ static enum sunxi_monitor sunxi_get_default_mon(bool allow_hdmi)
> > >               return sunxi_monitor_none;
> > >  }
> > >
> > > -void *video_hw_init(void)
> > > +static int sunxi_de_probe(struct udevice *dev)
> > >  {
> > > -     static GraphicDevice *graphic_device = &sunxi_display.graphic_device;
> > > +     struct video_priv *uc_priv = dev_get_uclass_priv(dev);
> > > +     struct video_uc_platdata *plat = dev_get_uclass_platdata(dev);
> > > +     struct sunxi_display *sunxi_display = dev_get_priv(dev);
> > >       const struct ctfb_res_modes *mode;
> > >       struct ctfb_res_modes custom;
> > >       const char *options;
> > > @@ -1067,10 +1081,8 @@ void *video_hw_init(void)
> > >       char mon[16];
> > >       char *lcd_mode = CONFIG_VIDEO_LCD_MODE;
> > >
> > > -     memset(&sunxi_display, 0, sizeof(struct sunxi_display));
> > > -
> > >       video_get_ctfb_res_modes(RES_MODE_1024x768, 24, &mode,
> > > -                              &sunxi_display.depth, &options);
> > > +                              &sunxi_display->depth, &options);
> > >  #ifdef CONFIG_VIDEO_HDMI
> > >       hpd = video_get_option_int(options, "hpd", 1);
> > >       hpd_delay = video_get_option_int(options, "hpd_delay", 500);
> > > @@ -1078,35 +1090,35 @@ void *video_hw_init(void)
> > >  #endif
> > >       overscan_x = video_get_option_int(options, "overscan_x", -1);
> > >       overscan_y = video_get_option_int(options, "overscan_y", -1);
> > > -     sunxi_display.monitor = sunxi_get_default_mon(true);
> > > +     sunxi_display->monitor = sunxi_get_default_mon(true);
> > >       video_get_option_string(options, "monitor", mon, sizeof(mon),
> > > -                             sunxi_get_mon_desc(sunxi_display.monitor));
> > > +                             sunxi_get_mon_desc(sunxi_display->monitor));
> > >       for (i = 0; i <= SUNXI_MONITOR_LAST; i++) {
> > >               if (strcmp(mon, sunxi_get_mon_desc(i)) == 0) {
> > > -                     sunxi_display.monitor = i;
> > > +                     sunxi_display->monitor = i;
> > >                       break;
> > >               }
> > >       }
> > >       if (i > SUNXI_MONITOR_LAST)
> > >               printf("Unknown monitor: '%s', falling back to '%s'\n",
> > > -                    mon, sunxi_get_mon_desc(sunxi_display.monitor));
> > > +                    mon, sunxi_get_mon_desc(sunxi_display->monitor));
> > >
> > >  #ifdef CONFIG_VIDEO_HDMI
> > >       /* If HDMI/DVI is selected do HPD & EDID, and handle fallback */
> > > -     if (sunxi_display.monitor == sunxi_monitor_dvi ||
> > > -         sunxi_display.monitor == sunxi_monitor_hdmi) {
> > > +     if (sunxi_display->monitor == sunxi_monitor_dvi ||
> > > +         sunxi_display->monitor == sunxi_monitor_hdmi) {
> > >               /* Always call hdp_detect, as it also enables clocks, etc. */
> > >               hdmi_present = (sunxi_hdmi_hpd_detect(hpd_delay) == 1);
> > >               if (hdmi_present && edid) {
> > >                       printf("HDMI connected: ");
> > > -                     if (sunxi_hdmi_edid_get_mode(&custom, true) == 0)
> > > +                     if (sunxi_hdmi_edid_get_mode(sunxi_display, &custom, true) == 0)
> > >                               mode = &custom;
> > >                       else
> > >                               hdmi_present = false;
> > >               }
> > >               /* Fall back to EDID in case HPD failed */
> > >               if (edid && !hdmi_present) {
> > > -                     if (sunxi_hdmi_edid_get_mode(&custom, false) == 0) {
> > > +                     if (sunxi_hdmi_edid_get_mode(sunxi_display, &custom, false) == 0) {
> > >                               mode = &custom;
> > >                               hdmi_present = true;
> > >                       }
> > > @@ -1114,38 +1126,39 @@ void *video_hw_init(void)
> > >               /* Shut down when display was not found */
> > >               if ((hpd || edid) && !hdmi_present) {
> > >                       sunxi_hdmi_shutdown();
> > > -                     sunxi_display.monitor = sunxi_get_default_mon(false);
> > > +                     sunxi_display->monitor = sunxi_get_default_mon(false);
> > >               } /* else continue with hdmi/dvi without a cable connected */
> > >       }
> > >  #endif
> > >
> > > -     switch (sunxi_display.monitor) {
> > > +     switch (sunxi_display->monitor) {
> > >       case sunxi_monitor_none:
> > > -             return NULL;
> > > +             printf("Unknown monitor\n");
> > > +             return -EINVAL;
> > >       case sunxi_monitor_dvi:
> > >       case sunxi_monitor_hdmi:
> > >               if (!sunxi_has_hdmi()) {
> > >                       printf("HDMI/DVI not supported on this board\n");
> > > -                     sunxi_display.monitor = sunxi_monitor_none;
> > > -                     return NULL;
> > > +                     sunxi_display->monitor = sunxi_monitor_none;
> > > +                     return -EINVAL;
> > >               }
> > >               break;
> > >       case sunxi_monitor_lcd:
> > >               if (!sunxi_has_lcd()) {
> > >                       printf("LCD not supported on this board\n");
> > > -                     sunxi_display.monitor = sunxi_monitor_none;
> > > -                     return NULL;
> > > +                     sunxi_display->monitor = sunxi_monitor_none;
> > > +                     return -EINVAL;
> > >               }
> > > -             sunxi_display.depth = video_get_params(&custom, lcd_mode);
> > > +             sunxi_display->depth = video_get_params(&custom, lcd_mode);
> > >               mode = &custom;
> > >               break;
> > >       case sunxi_monitor_vga:
> > >               if (!sunxi_has_vga()) {
> > >                       printf("VGA not supported on this board\n");
> > > -                     sunxi_display.monitor = sunxi_monitor_none;
> > > -                     return NULL;
> > > +                     sunxi_display->monitor = sunxi_monitor_none;
> > > +                     return -EINVAL;
> > >               }
> > > -             sunxi_display.depth = 18;
> > > +             sunxi_display->depth = 18;
> > >               break;
> > >       case sunxi_monitor_composite_pal:
> > >       case sunxi_monitor_composite_ntsc:
> > > @@ -1153,85 +1166,103 @@ void *video_hw_init(void)
> > >       case sunxi_monitor_composite_pal_nc:
> > >               if (!sunxi_has_composite()) {
> > >                       printf("Composite video not supported on this board\n");
> > > -                     sunxi_display.monitor = sunxi_monitor_none;
> > > -                     return NULL;
> > > +                     sunxi_display->monitor = sunxi_monitor_none;
> > > +                     return -EINVAL;
> > >               }
> > > -             if (sunxi_display.monitor == sunxi_monitor_composite_pal ||
> > > -                 sunxi_display.monitor == sunxi_monitor_composite_pal_nc)
> > > +             if (sunxi_display->monitor == sunxi_monitor_composite_pal ||
> > > +                 sunxi_display->monitor == sunxi_monitor_composite_pal_nc)
> > >                       mode = &composite_video_modes[0];
> > >               else
> > >                       mode = &composite_video_modes[1];
> > > -             sunxi_display.depth = 24;
> > > +             sunxi_display->depth = 24;
> > >               break;
> > >       }
> > >
> > >       /* Yes these defaults are quite high, overscan on composite sucks... */
> > >       if (overscan_x == -1)
> > > -             overscan_x = sunxi_is_composite() ? 32 : 0;
> > > +             overscan_x = sunxi_is_composite(sunxi_display->monitor) ? 32 : 0;
> > >       if (overscan_y == -1)
> > > -             overscan_y = sunxi_is_composite() ? 20 : 0;
> > > +             overscan_y = sunxi_is_composite(sunxi_display->monitor) ? 20 : 0;
> > >
> > > -     sunxi_display.fb_size =
> > > -             (mode->xres * mode->yres * 4 + 0xfff) & ~0xfff;
> > > +     sunxi_display->fb_size = plat->size;
> > >       overscan_offset = (overscan_y * mode->xres + overscan_x) * 4;
> > >       /* We want to keep the fb_base for simplefb page aligned, where as
> > >        * the sunxi dma engines will happily accept an unaligned address. */
> > >       if (overscan_offset)
> > > -             sunxi_display.fb_size += 0x1000;
> > > -
> > > -     if (sunxi_display.fb_size > CONFIG_SUNXI_MAX_FB_SIZE) {
> > > -             printf("Error need %dkB for fb, but only %dkB is reserved\n",
> > > -                    sunxi_display.fb_size >> 10,
> > > -                    CONFIG_SUNXI_MAX_FB_SIZE >> 10);
> > > -             return NULL;
> > > -     }
> > > +             sunxi_display->fb_size += 0x1000;
> > >
> > >       printf("Setting up a %dx%d%s %s console (overscan %dx%d)\n",
> > >              mode->xres, mode->yres,
> > >              (mode->vmode == FB_VMODE_INTERLACED) ? "i" : "",
> > > -            sunxi_get_mon_desc(sunxi_display.monitor),
> > > +            sunxi_get_mon_desc(sunxi_display->monitor),
> > >              overscan_x, overscan_y);
> > >
> > > -     gd->fb_base = gd->bd->bi_dram[0].start +
> > > -                   gd->bd->bi_dram[0].size - sunxi_display.fb_size;
> > > +     sunxi_display->fb_addr = plat->base;
> > >       sunxi_engines_init();
> > >
> > >  #ifdef CONFIG_EFI_LOADER
> > > -     efi_add_memory_map(gd->fb_base, sunxi_display.fb_size,
> > > +     efi_add_memory_map(sunxi_display->fb_addr, sunxi_display->fb_size,
> > >                          EFI_RESERVED_MEMORY_TYPE);
> > >  #endif
> > >
> > > -     fb_dma_addr = gd->fb_base - CONFIG_SYS_SDRAM_BASE;
> > > -     sunxi_display.fb_addr = gd->fb_base;
> > > +     fb_dma_addr = sunxi_display->fb_addr - CONFIG_SYS_SDRAM_BASE;
> > >       if (overscan_offset) {
> > >               fb_dma_addr += 0x1000 - (overscan_offset & 0xfff);
> > > -             sunxi_display.fb_addr += (overscan_offset + 0xfff) & ~0xfff;
> > > -             memset((void *)gd->fb_base, 0, sunxi_display.fb_size);
> > > -             flush_cache(gd->fb_base, sunxi_display.fb_size);
> > > +             sunxi_display->fb_addr += (overscan_offset + 0xfff) & ~0xfff;
> > > +             memset((void *)sunxi_display->fb_addr, 0, sunxi_display->fb_size);
> > > +             flush_cache(sunxi_display->fb_addr, sunxi_display->fb_size);
> > >       }
> > > -     sunxi_mode_set(mode, fb_dma_addr);
> > > +     sunxi_mode_set(sunxi_display, mode, fb_dma_addr);
> > >
> > >       /*
> > >        * These are the only members of this structure that are used. All the
> > >        * others are driver specific. The pitch is stored in plnSizeX.
> > >        */
> > > -     graphic_device->frameAdrs = sunxi_display.fb_addr;
> > > -     graphic_device->gdfIndex = GDF_32BIT_X888RGB;
> > > -     graphic_device->gdfBytesPP = 4;
> > > -     graphic_device->winSizeX = mode->xres - 2 * overscan_x;
> > > -     graphic_device->winSizeY = mode->yres - 2 * overscan_y;
> > > -     graphic_device->plnSizeX = mode->xres * graphic_device->gdfBytesPP;
> > > -
> > > -     return graphic_device;
> > > +     uc_priv->bpix = VIDEO_BPP32;
> > > +     uc_priv->xsize = mode->xres;
> > > +     uc_priv->ysize = mode->yres;
> > > +
> > > +     video_set_flush_dcache(dev, 1);
> >
> > This is new. You should explain in a separate patch why the flush_cache
> > above isn't enough.
>
> This is new and but required when for DM_VIDEO conversion.
> video-uclass has a common way to flush video via video_sync so the
> driver has to trigger this flush and without this, the vidconsole
> shows inconsistent characters.
>
> Jagan.
>
>


-- 
| Michael Nazzareno Trimarchi                     Amarula Solutions BV |
| COO  -  Founder                                      Cruquiuskade 47 |
| +31(0)851119172                                 Amsterdam 1018 AM NL |
|                  [`as] http://www.amarulasolutions.com               |


More information about the U-Boot mailing list