[U-Boot] [linux-sunxi] Re: [PATCH 3/3] sunxi: video: Add H3/H5 TV out driver

Chen-Yu Tsai wens at csie.org
Sat May 13 15:14:00 UTC 2017


On Sat, May 13, 2017 at 11:02 PM,  <icenowy at aosc.io> wrote:
> 在 2017-05-13 00:06,Maxime Ripard 写道:
>>
>> Hi Jernej,
>>
>> The patch content looks fine, but there's a few things that would need
>> to be addressed.
>>
>> On Wed, May 10, 2017 at 06:46:30PM +0200, Jernej Skrabec wrote:
>>>
>>> This commit adds support for TV (composite) output.
>>>
>>> Signed-off-by: Jernej Skrabec <jernej.skrabec at siol.net>
>>> ---
>>>
>>>  arch/arm/include/asm/arch-sunxi/cpu_sun4i.h |  10 ++
>>>  arch/arm/include/asm/arch-sunxi/display2.h  |  17 +++
>>>  arch/arm/include/asm/arch-sunxi/tve.h       |  17 ++-
>>>  drivers/video/sunxi/Makefile                |   2 +-
>>>  drivers/video/sunxi/sunxi_de2.c             |  60 ++++++++---
>>>  drivers/video/sunxi/sunxi_tve.c             | 156
>>> ++++++++++++++++++++++++++++
>>>  drivers/video/sunxi/tve.c                   |   6 +-
>>
>>
>> The difference between sunxi_tve and tve is not really obvious. What
>> about calling sunxi_tve tve-uclass, or something like that?
>>
>>>  7 files changed, 251 insertions(+), 17 deletions(-)
>>>  create mode 100644 drivers/video/sunxi/sunxi_tve.c
>>>
>>> diff --git a/arch/arm/include/asm/arch-sunxi/cpu_sun4i.h
>>> b/arch/arm/include/asm/arch-sunxi/cpu_sun4i.h
>>> index 6aa5e91ada..2419062d45 100644
>>> --- a/arch/arm/include/asm/arch-sunxi/cpu_sun4i.h
>>> +++ b/arch/arm/include/asm/arch-sunxi/cpu_sun4i.h
>>> @@ -34,7 +34,9 @@
>>>  #define SUNXI_MS_BASE                  0x01c07000
>>>  #define SUNXI_TVD_BASE                 0x01c08000
>>>  #define SUNXI_CSI0_BASE                        0x01c09000
>>> +#ifndef CONFIG_MACH_SUNXI_H3_H5
>>>  #define SUNXI_TVE0_BASE                        0x01c0a000
>>> +#endif
>>
>>
>> This should be part of a seperate patch.
>>
>>>  #define SUNXI_EMAC_BASE                        0x01c0b000
>>>  #define SUNXI_LCD0_BASE                        0x01c0C000
>>>  #define SUNXI_LCD1_BASE                        0x01c0d000
>>> @@ -161,10 +163,18 @@ defined(CONFIG_MACH_SUN50I)
>>>  /* module sram */
>>>  #define SUNXI_SRAM_C_BASE              0x01d00000
>>>
>>> +#ifndef CONFIG_MACH_SUN8I_H3
>>>  #define SUNXI_DE_FE0_BASE              0x01e00000
>>> +#else
>>> +#define SUNXI_TVE0_BASE                        0x01e00000
>>> +#endif
>>
>>
>> This one should be in that other patch
>>
>>>  #define SUNXI_DE_FE1_BASE              0x01e20000
>>>  #define SUNXI_DE_BE0_BASE              0x01e60000
>>> +#ifndef CONFIG_MACH_SUN50I_H5
>>>  #define SUNXI_DE_BE1_BASE              0x01e40000
>>> +#else
>>> +#define SUNXI_TVE0_BASE                        0x01e40000
>>> +#endif
>>
>>
>> And that one too.
>>
>>>  #define SUNXI_MP_BASE                  0x01e80000
>>>  #define SUNXI_AVG_BASE                 0x01ea0000
>>>
>>> diff --git a/arch/arm/include/asm/arch-sunxi/display2.h
>>> b/arch/arm/include/asm/arch-sunxi/display2.h
>>> index b5875f9605..359cacd90b 100644
>>> --- a/arch/arm/include/asm/arch-sunxi/display2.h
>>> +++ b/arch/arm/include/asm/arch-sunxi/display2.h
>>> @@ -90,6 +90,23 @@ struct de_ui {
>>>         u32 ovl_size;
>>>  };
>>>
>>> +struct de_csc {
>>> +       u32 csc_ctl;
>>> +       u8 res[0xc];
>>> +       u32 coef11;
>>> +       u32 coef12;
>>> +       u32 coef13;
>>> +       u32 coef14;
>>> +       u32 coef21;
>>> +       u32 coef22;
>>> +       u32 coef23;
>>> +       u32 coef24;
>>> +       u32 coef31;
>>> +       u32 coef32;
>>> +       u32 coef33;
>>> +       u32 coef34;
>>> +};
>>> +
>>
>>
>> This should be in another patch (let's call it patch 2)
>>
>>>  /*
>>>   * DE register constants.
>>>   */
>>> diff --git a/arch/arm/include/asm/arch-sunxi/tve.h
>>> b/arch/arm/include/asm/arch-sunxi/tve.h
>>> index 41a14a68e4..ff34bbbc12 100644
>>> --- a/arch/arm/include/asm/arch-sunxi/tve.h
>>> +++ b/arch/arm/include/asm/arch-sunxi/tve.h
>>> @@ -45,7 +45,9 @@ struct sunxi_tve_reg {
>>>         u32 csc_reg1;                   /* 0x044 */
>>>         u32 csc_reg2;                   /* 0x048 */
>>>         u32 csc_reg3;                   /* 0x04c */
>>> -       u8 res1[0xb0];                  /* 0x050 */
>>> +       u8 res1[0xa8];                  /* 0x050 */
>>> +       u32 auto_detect_cfg0;           /* 0x0f8 */
>>> +       u32 auto_detect_cfg1;           /* 0x0fc */
>>>         u32 color_burst;                /* 0x100 */
>>>         u32 vsync_num;                  /* 0x104 */
>>>         u32 notch_freq;                 /* 0x108 */
>>> @@ -62,6 +64,10 @@ struct sunxi_tve_reg {
>>>         u32 slave_para;                 /* 0x134 */
>>>         u32 cfg1;                       /* 0x138 */
>>>         u32 cfg2;                       /* 0x13c */
>>> +       u8 res2[0x1c4];                 /* 0x140 */
>>> +       u32 calibration;                /* 0x304 */
>>> +       u8 res3[0x4];                   /* 0x308 */
>>> +       u32 unknown3;                   /* 0x30c */
>>
>>
>> And these yet another one (patch 3)
>>
>>>  };
>>>
>>>  /*
>>> @@ -79,12 +85,14 @@ struct sunxi_tve_reg {
>>>  #define SUNXI_TVE_CFG0_PAL                     0x07030001
>>>  #define SUNXI_TVE_CFG0_NTSC                    0x07030000
>>>  #define SUNXI_TVE_DAC_CFG0_VGA                 0x403e1ac7
>>> -#ifdef CONFIG_MACH_SUN5I
>>> +#if defined(CONFIG_MACH_SUN5I) || defined(CONFIG_MACH_SUNXI_H3_H5)
>>>  #define SUNXI_TVE_DAC_CFG0_COMPOSITE           0x433f0009
>>>  #else
>>>  #define SUNXI_TVE_DAC_CFG0_COMPOSITE           0x403f0008
>>>  #endif
>>> +#define SUNXI_TVE_DAC_CFG0_DETECTION           0x433f0289
>>>  #define SUNXI_TVE_FILTER_COMPOSITE             0x00000120
>>> +#define SUNXI_TVE_CHROMA_FREQ_PAL              0x2a098acb
>>>  #define SUNXI_TVE_CHROMA_FREQ_PAL_M            0x21e6efe3
>>>  #define SUNXI_TVE_CHROMA_FREQ_PAL_NC           0x21f69446
>>>  #define SUNXI_TVE_PORCH_NUM_PAL                        0x008a0018
>>> @@ -105,6 +113,8 @@ struct sunxi_tve_reg {
>>>  #define SUNXI_TVE_AUTO_DETECT_STATUS_SHORT_GND 3
>>>  #define SUNXI_TVE_AUTO_DETECT_DEBOUNCE_SHIFT(d)        ((d) * 8)
>>>  #define SUNXI_TVE_AUTO_DETECT_DEBOUNCE_MASK(d) (0xf << ((d) * 8))
>>> +#define SUNXI_TVE_AUTO_DETECT_CFG0             0x00000280
>>> +#define SUNXI_TVE_AUTO_DETECT_CFG1             0x028F00FF
>>>  #define SUNXI_TVE_CSC_REG0_ENABLE              (1 << 31)
>>>  #define SUNXI_TVE_CSC_REG0                     0x08440832
>>>  #define SUNXI_TVE_CSC_REG1                     0x3b6dace1
>>> @@ -124,6 +134,9 @@ struct sunxi_tve_reg {
>>>  #define SUNXI_TVE_RESYNC_NUM_PAL               0x800d000c
>>>  #define SUNXI_TVE_RESYNC_NUM_NTSC              0x000e000c
>>>  #define SUNXI_TVE_SLAVE_PARA_COMPOSITE         0x00000000
>>> +#define SUNXI_TVE_CALIBRATION_H3               0x02000c00
>>> +#define SUNXI_TVE_CALIBRATION_H5               0x02850000
>>> +#define SUNXI_TVE_UNKNOWN3_H5                  0x00101110
>>
>>
>> patch 3
>>
>>>
>>>  void tvencoder_mode_set(struct sunxi_tve_reg * const tve, enum tve_mode
>>> mode);
>>>  void tvencoder_enable(struct sunxi_tve_reg * const tve);
>>> diff --git a/drivers/video/sunxi/Makefile b/drivers/video/sunxi/Makefile
>>> index dbaab61b59..1db82c53f0 100644
>>> --- a/drivers/video/sunxi/Makefile
>>> +++ b/drivers/video/sunxi/Makefile
>>> @@ -6,4 +6,4 @@
>>>  #
>>>
>>>  obj-$(CONFIG_VIDEO_SUNXI) += sunxi_display.o lcdc.o tve.o
>>> ../videomodes.o
>>> -obj-$(CONFIG_VIDEO_DE2) += sunxi_de2.o sunxi_dw_hdmi.o lcdc.o
>>> ../dw_hdmi.o
>>> +obj-$(CONFIG_VIDEO_DE2) += sunxi_de2.o sunxi_dw_hdmi.o sunxi_tve.o tve.o
>>> lcdc.o ../dw_hdmi.o
>>> diff --git a/drivers/video/sunxi/sunxi_de2.c
>>> b/drivers/video/sunxi/sunxi_de2.c
>>> index 9a32c3a020..ee67764ac5 100644
>>> --- a/drivers/video/sunxi/sunxi_de2.c
>>> +++ b/drivers/video/sunxi/sunxi_de2.c
>>> @@ -56,7 +56,7 @@ static void sunxi_de2_composer_init(void)
>>>  }
>>>
>>>  static void sunxi_de2_mode_set(int mux, const struct display_timing
>>> *mode,
>>> -                              int bpp, ulong address)
>>> +                              int bpp, ulong address, bool is_composite)
>>>  {
>>>         ulong de_mux_base = (mux == 0) ?
>>>                             SUNXI_DE2_MUX0_BASE : SUNXI_DE2_MUX1_BASE;
>>
>>
>> patch 2
>>
>>> @@ -72,6 +72,9 @@ static void sunxi_de2_mode_set(int mux, const struct
>>> display_timing *mode,
>>>                 (struct de_ui *)(de_mux_base +
>>>                                  SUNXI_DE2_MUX_CHAN_REGS +
>>>                                  SUNXI_DE2_MUX_CHAN_SZ * 1);
>>> +       struct de_csc * const de_csc_regs =
>>> +               (struct de_csc *)(de_mux_base +
>>> +                                 SUNXI_DE2_MUX_DCSC_REGS);
>>
>>
>> patch 2
>>
>>>         u32 size = SUNXI_DE2_WH(mode->hactive.typ, mode->vactive.typ);
>>>         int channel;
>>>         u32 format;
>>> @@ -128,7 +131,27 @@ static void sunxi_de2_mode_set(int mux, const struct
>>> display_timing *mode,
>>>         writel(0, de_mux_base + SUNXI_DE2_MUX_PEAK_REGS);
>>>         writel(0, de_mux_base + SUNXI_DE2_MUX_ASE_REGS);
>>>         writel(0, de_mux_base + SUNXI_DE2_MUX_FCC_REGS);
>>> -       writel(0, de_mux_base + SUNXI_DE2_MUX_DCSC_REGS);
>>> +
>>> +       if (is_composite) {
>>> +               /* set CSC coefficients */
>>> +               writel(0x107, &de_csc_regs->coef11);
>>> +               writel(0x204, &de_csc_regs->coef12);
>>> +               writel(0x64, &de_csc_regs->coef13);
>>> +               writel(0x4200, &de_csc_regs->coef14);
>>> +               writel(0x1f68, &de_csc_regs->coef21);
>>> +               writel(0x1ed6, &de_csc_regs->coef22);
>>> +               writel(0x1c2, &de_csc_regs->coef23);
>>> +               writel(0x20200, &de_csc_regs->coef24);
>>> +               writel(0x1c2, &de_csc_regs->coef31);
>>> +               writel(0x1e87, &de_csc_regs->coef32);
>>> +               writel(0x1fb7, &de_csc_regs->coef33);
>>> +               writel(0x20200, &de_csc_regs->coef34);
>>> +
>>> +               /* enable CSC unit */
>>> +               writel(1, &de_csc_regs->csc_ctl);
>>> +       } else {
>>> +               writel(0, &de_csc_regs->csc_ctl);
>>> +       }
>>
>>
>> patch 2
>>
>>>
>>>         switch (bpp) {
>>>         case 16:
>>> @@ -153,7 +176,7 @@ static void sunxi_de2_mode_set(int mux, const struct
>>> display_timing *mode,
>>>
>>>  static int sunxi_de2_init(struct udevice *dev, ulong fbbase,
>>>                           enum video_log2_bpp l2bpp,
>>> -                         struct udevice *disp, int mux)
>>> +                         struct udevice *disp, int mux, bool
>>> is_composite)
>>>  {
>>>         struct video_priv *uc_priv = dev_get_uclass_priv(dev);
>>>         struct display_timing timing;
>>> @@ -183,7 +206,7 @@ static int sunxi_de2_init(struct udevice *dev, ulong
>>> fbbase,
>>>         }
>>>
>>>         sunxi_de2_composer_init();
>>> -       sunxi_de2_mode_set(mux, &timing, 1 << l2bpp, fbbase);
>>> +       sunxi_de2_mode_set(mux, &timing, 1 << l2bpp, fbbase,
>>> is_composite);
>>>
>>>         ret = display_enable(disp, 1 << l2bpp, &timing);
>>>         if (ret) {
>>> @@ -204,7 +227,6 @@ static int sunxi_de2_probe(struct udevice *dev)
>>>         struct video_uc_platdata *plat = dev_get_uclass_platdata(dev);
>>>         struct udevice *disp;
>>>         int ret;
>>> -       int mux;
>>>
>>>         /* Before relocation we don't need to do anything */
>>>         if (!(gd->flags & GD_FLG_RELOC))
>>> @@ -212,17 +234,31 @@ static int sunxi_de2_probe(struct udevice *dev)
>>>
>>>         ret = uclass_find_device_by_name(UCLASS_DISPLAY,
>>>                                          "sunxi_dw_hdmi", &disp);
>>> +       if (!ret) {
>>> +               int mux;
>>> +               if (IS_ENABLED(CONFIG_MACH_SUNXI_H3_H5))
>>> +                       mux = 0;
>>> +               else
>>> +                       mux = 1;
>>> +
>>> +               ret = sunxi_de2_init(dev, plat->base, VIDEO_BPP32, disp,
>>> mux,
>>> +                                    false);
>>> +               if (!ret) {
>>> +                       video_set_flush_dcache(dev, 1);
>>> +                       return 0;
>>> +               }
>>> +       }
>>> +
>>> +       debug("%s: hdmi display not found (ret=%d)\n", __func__, ret);
>>> +
>>> +       ret = uclass_find_device_by_name(UCLASS_DISPLAY,
>>> +                                       "sunxi_tve", &disp);
>>>         if (ret) {
>>> -               debug("%s: hdmi display not found (ret=%d)\n", __func__,
>>> ret);
>>> +               debug("%s: tv not found (ret=%d)\n", __func__, ret);
>>>                 return ret;
>>>         }
>>>
>>> -       if (IS_ENABLED(CONFIG_MACH_SUNXI_H3_H5))
>>> -               mux = 0;
>>> -       else
>>> -               mux = 1;
>>> -
>>> -       ret = sunxi_de2_init(dev, plat->base, VIDEO_BPP32, disp, mux);
>>> +       ret = sunxi_de2_init(dev, plat->base, VIDEO_BPP32, disp, 1,
>>> true);
>>
>>
>> patch 2
>>
>>>         if (ret)
>>>                 return ret;
>>>
>>> diff --git a/drivers/video/sunxi/sunxi_tve.c
>>> b/drivers/video/sunxi/sunxi_tve.c
>>> new file mode 100644
>>> index 0000000000..95f54bbaf7
>>> --- /dev/null
>>> +++ b/drivers/video/sunxi/sunxi_tve.c
>>> @@ -0,0 +1,156 @@
>>> +/*
>>> + * Allwinner TVE driver
>>> + *
>>> + * (C) Copyright 2017 Jernej Skrabec <jernej.skrabec at siol.net>
>>> + *
>>> + * SPDX-License-Identifier:    GPL-2.0+
>>> + */
>>> +
>>> +#include <common.h>
>>> +#include <display.h>
>>> +#include <dm.h>
>>> +#include <asm/io.h>
>>> +#include <asm/arch/clock.h>
>>> +#include <asm/arch/lcdc.h>
>>> +#include <asm/arch/tve.h>
>>> +
>>> +static int sunxi_tve_get_plug_in_status(void)
>>> +{
>>> +       struct sunxi_tve_reg * const tve =
>>> +               (struct sunxi_tve_reg *)SUNXI_TVE0_BASE;
>>> +       u32 status;
>>> +
>>> +       status = readl(&tve->auto_detect_status) &
>>> +               SUNXI_TVE_AUTO_DETECT_STATUS_MASK(0);
>>> +
>>> +       return status == SUNXI_TVE_AUTO_DETECT_STATUS_CONNECTED;
>
>
> So TVE is now capable of hpd checking, right?
>
> Is is a feature that exists in A10/A13/A20 or is it new in H3?

AFAIK this is also available in the earlier SoCs.
Maxime mentioned that it was unreliable though.

ChenYu

>
>>> +}
>>> +
>>> +static int sunxi_tve_wait_for_hpd(void)
>>> +{
>>> +       struct sunxi_tve_reg * const tve =
>>> +               (struct sunxi_tve_reg *)SUNXI_TVE0_BASE;
>>> +       ulong start;
>>> +
>>> +       /* enable auto detection */
>>> +       writel(SUNXI_TVE_DAC_CFG0_DETECTION, &tve->dac_cfg0);
>>> +       writel(SUNXI_TVE_AUTO_DETECT_CFG0, &tve->auto_detect_cfg0);
>>> +       writel(SUNXI_TVE_AUTO_DETECT_CFG1, &tve->auto_detect_cfg1);
>>> +       writel(9 << SUNXI_TVE_AUTO_DETECT_DEBOUNCE_SHIFT(0),
>>> +              &tve->auto_detect_debounce);
>>> +       writel(SUNXI_TVE_AUTO_DETECT_EN_DET_EN(0), &tve->auto_detect_en);
>>> +
>>> +       start = get_timer(0);
>>> +       do {
>>> +               if (sunxi_tve_get_plug_in_status())
>>> +                       return 0;
>>> +               udelay(100);
>>> +       } while (get_timer(start) < 300);
>>> +
>>> +       return -1;
>>> +}
>>> +
>>> +static void sunxi_tve_lcdc_init(const struct display_timing *edid, int
>>> bpp)
>>> +{
>>> +       struct sunxi_ccm_reg * const ccm =
>>> +               (struct sunxi_ccm_reg *)SUNXI_CCM_BASE;
>>> +       struct sunxi_lcdc_reg * const lcdc =
>>> +               (struct sunxi_lcdc_reg *)SUNXI_LCD1_BASE;
>>> +
>>> +       /* Reset off */
>>> +       setbits_le32(&ccm->ahb_reset1_cfg, 1 << AHB_RESET_OFFSET_LCD1);
>>> +
>>> +       /* Clock on */
>>> +       setbits_le32(&ccm->ahb_gate1, 1 << AHB_GATE_OFFSET_LCD1);
>>> +
>>> +       lcdc_init(lcdc);
>>> +       lcdc_tcon1_mode_set(lcdc, edid, false, true);
>>> +       lcdc_enable(lcdc, bpp);
>>> +}
>>> +
>>> +static int sunxi_tve_read_timing(struct udevice *dev,
>>> +                                struct display_timing *timing)
>>> +{
>>> +       /* PAL resolution */
>>> +       timing->pixelclock.typ = 27000000;
>>> +
>>> +       timing->hactive.typ = 720;
>>> +       timing->hfront_porch.typ = 5;
>>> +       timing->hback_porch.typ = 137;
>>> +       timing->hsync_len.typ = 2;
>>> +
>>> +       timing->vactive.typ = 576;
>>> +       timing->vfront_porch.typ = 27;
>>> +       timing->vback_porch.typ = 20;
>>> +       timing->vsync_len.typ = 2;
>>> +
>>> +       timing->flags = DISPLAY_FLAGS_INTERLACED;
>>> +
>>> +       return 0;
>>> +}
>>> +
>>> +static int sunxi_tve_enable(struct udevice *dev, int panel_bpp,
>>> +                           const struct display_timing *edid)
>>> +{
>>> +       struct sunxi_tve_reg * const tve =
>>> +               (struct sunxi_tve_reg *)SUNXI_TVE0_BASE;
>>> +
>>> +       sunxi_tve_lcdc_init(edid, panel_bpp);
>>> +
>>> +       tvencoder_mode_set(tve, tve_mode_composite_pal);
>>> +       tvencoder_enable(tve);
>>> +
>>> +       return 0;
>>> +}
>>> +
>>> +static int sunxi_tve_probe(struct udevice *dev)
>>> +{
>>> +       struct sunxi_ccm_reg * const ccm =
>>> +               (struct sunxi_ccm_reg *)SUNXI_CCM_BASE;
>>> +       struct sunxi_tve_reg * const tve =
>>> +               (struct sunxi_tve_reg *)SUNXI_TVE0_BASE;
>>> +       int ret;
>>> +
>>> +       /* make sure that clock is active */
>>> +       clock_set_pll10(432000000);
>>> +
>>> +       /* Reset off */
>>> +       setbits_le32(&ccm->ahb_reset1_cfg, 1 << AHB_RESET_OFFSET_TVE);
>>> +
>>> +       /* Clock on */
>>> +       setbits_le32(&ccm->ahb_gate1, 1 << AHB_GATE_OFFSET_TVE);
>>> +       writel(CCM_TVE_CTRL_GATE | CCM_TVE_CTRL_M(2), &ccm->tve_clk_cfg);
>>> +
>>> +#ifdef CONFIG_MACH_SUN50I_H5
>>> +       writel(SUNXI_TVE_CALIBRATION_H5, &tve->calibration);
>>> +       writel(SUNXI_TVE_UNKNOWN3_H5, &tve->unknown3);
>>> +#else
>>> +       writel(SUNXI_TVE_CALIBRATION_H3, &tve->calibration);
>>> +#endif
>>> +
>>> +       ret = sunxi_tve_wait_for_hpd();
>>> +       if (ret < 0) {
>>> +               debug("tve can not get hpd signal\n");
>>> +               return -1;
>>> +       }
>>> +
>>> +       return 0;
>>> +}
>>> +
>>> +static const struct dm_display_ops sunxi_tve_ops = {
>>> +       .read_timing = sunxi_tve_read_timing,
>>> +       .enable = sunxi_tve_enable,
>>> +};
>>> +
>>> +U_BOOT_DRIVER(sunxi_tve) = {
>>> +       .name   = "sunxi_tve",
>>> +       .id     = UCLASS_DISPLAY,
>>> +       .ops    = &sunxi_tve_ops,
>>> +       .probe  = sunxi_tve_probe,
>>> +};
>>> +
>>> +#ifdef CONFIG_MACH_SUNXI_H3_H5
>>> +U_BOOT_DEVICE(sunxi_tve) = {
>>> +       .name = "sunxi_tve"
>>> +};
>>> +#endif
>>
>>
>> patch 3
>>
>>> diff --git a/drivers/video/sunxi/tve.c b/drivers/video/sunxi/tve.c
>>> index adea78a69a..ef99c111e3 100644
>>> --- a/drivers/video/sunxi/tve.c
>>> +++ b/drivers/video/sunxi/tve.c
>>> @@ -25,8 +25,6 @@ void tvencoder_mode_set(struct sunxi_tve_reg * const
>>> tve, enum tve_mode mode)
>>>                 writel(SUNXI_TVE_UNKNOWN1_VGA, &tve->unknown1);
>>>                 break;
>>>         case tve_mode_composite_pal_nc:
>>> -               writel(SUNXI_TVE_CHROMA_FREQ_PAL_NC, &tve->chroma_freq);
>>> -               /* Fall through */
>>>         case tve_mode_composite_pal:
>>>                 writel(SUNXI_TVE_GCTRL_DAC_INPUT(0, 1) |
>>>                        SUNXI_TVE_GCTRL_DAC_INPUT(1, 2) |
>>> @@ -35,6 +33,10 @@ void tvencoder_mode_set(struct sunxi_tve_reg * const
>>> tve, enum tve_mode mode)
>>>                 writel(SUNXI_TVE_CFG0_PAL, &tve->cfg0);
>>>                 writel(SUNXI_TVE_DAC_CFG0_COMPOSITE, &tve->dac_cfg0);
>>>                 writel(SUNXI_TVE_FILTER_COMPOSITE, &tve->filter);
>>> +               if (mode == tve_mode_composite_pal)
>>> +                       writel(SUNXI_TVE_CHROMA_FREQ_PAL,
>>> &tve->chroma_freq);
>>> +               else
>>> +                       writel(SUNXI_TVE_CHROMA_FREQ_PAL_NC,
>>> &tve->chroma_freq);
>>>                 writel(SUNXI_TVE_PORCH_NUM_PAL, &tve->porch_num);
>>>                 writel(SUNXI_TVE_LINE_NUM_PAL, &tve->line_num);
>>>                 writel(SUNXI_TVE_BLANK_BLACK_LEVEL_PAL,
>>
>>
>> And patch 3 as well.
>>
>> Thanks!
>> Maxime
>>
>> --
>> Maxime Ripard, Free Electrons
>> Embedded Linux and Kernel engineering
>> http://free-electrons.com
>
>
> --
> You received this message because you are subscribed to the Google Groups
> "linux-sunxi" group.
> To unsubscribe from this group and stop receiving emails from it, send an
> email to linux-sunxi+unsubscribe at googlegroups.com.
> For more options, visit https://groups.google.com/d/optout.


More information about the U-Boot mailing list