[PATCH r128] Split up flat panel register functions

Alex Deucher alexdeucher at gmail.com
Tue Jul 8 07:00:04 PDT 2014


On Tue, Jul 8, 2014 at 6:03 AM, Connor Behan <connor.behan at gmail.com> wrote:
> On 07/07/14 01:36 PM, Alex Deucher wrote:
>> On Fri, Jul 4, 2014 at 1:59 AM, Connor Behan <connor.behan at gmail.com>
>> wrote:
>>> The old code was writing registers more often than it needed to. TMDS
>>> writes were triggered by changing the mode for an LVDS panel and RMX
>>> writes were triggered by changing the mode for CRTC2. This splits TMDS,
>>> LVDS and RMX calls into their own functions.
>> A couple of comments below about some of the encoder routing and
>> enable bits.  You can probably address them in a follow on patch if
>> you are interested in clean things up further.  Other than that, the
>> patch is:
>>
>> Reviewed-by: Alex Deucher <alexander.deucher at amd.com>
>>
>>> Signed-off-by: Connor Behan <connor.behan at gmail.com>
>>> ---
>>>  src/r128.h        |   6 +-
>>>  src/r128_crtc.c   |  20 -------
>>>  src/r128_driver.c | 169 +++++++++++++++++++++++++-----------------------------
>>>  src/r128_output.c |  26 ++++++++-
>>>  src/r128_probe.h  |   2 +
>>>  5 files changed, 111 insertions(+), 112 deletions(-)
>>>
>>> diff --git a/src/r128.h b/src/r128.h
>>> index fe757f8..13d629f 100644
>>> --- a/src/r128.h
>>> +++ b/src/r128.h
>>> @@ -554,7 +554,9 @@ extern int         R128MinBits(int val);
>>>  extern void        R128InitVideo(ScreenPtr pScreen);
>>>
>>>  extern void        R128InitCommonRegisters(R128SavePtr save, R128InfoPtr info);
>>> -extern void        R128InitFPRegisters(R128SavePtr orig, R128SavePtr save, DisplayModePtr mode, R128InfoPtr info);
>>> +extern void        R128InitRMXRegisters(R128SavePtr orig, R128SavePtr save, R128OutputPrivatePtr r128_output, DisplayModePtr mode);
>>> +extern void        R128InitFPRegisters(R128SavePtr orig, R128SavePtr save);
>>> +extern void        R128InitLVDSRegisters(R128SavePtr orig, R128SavePtr save);
>>>  extern Bool        R128InitCrtcBase(xf86CrtcPtr crtc, R128SavePtr save, int x, int y);
>>>  extern Bool        R128InitCrtcRegisters(ScrnInfoPtr pScrn, R128SavePtr save, DisplayModePtr mode, R128InfoPtr info);
>>>  extern void        R128InitPLLRegisters(ScrnInfoPtr pScrn, R128SavePtr save, R128PLLPtr pll, double dot_clock);
>>> @@ -564,7 +566,9 @@ extern Bool        R128InitCrtc2Registers(ScrnInfoPtr pScrn, R128SavePtr save, D
>>>  extern void        R128InitPLL2Registers(ScrnInfoPtr pScrn, R128SavePtr save, R128PLLPtr pll, double dot_clock);
>>>  extern Bool        R128InitDDA2Registers(ScrnInfoPtr pScrn, R128SavePtr save, R128PLLPtr pll, R128InfoPtr info, DisplayModePtr mode);
>>>  extern void        R128RestoreCommonRegisters(ScrnInfoPtr pScrn, R128SavePtr restore);
>>> +extern void        R128RestoreRMXRegisters(ScrnInfoPtr pScrn, R128SavePtr restore);
>>>  extern void        R128RestoreFPRegisters(ScrnInfoPtr pScrn, R128SavePtr restore);
>>> +extern void        R128RestoreLVDSRegisters(ScrnInfoPtr pScrn, R128SavePtr restore);
>>>  extern void        R128RestoreCrtcRegisters(ScrnInfoPtr pScrn, R128SavePtr restore);
>>>  extern void        R128RestorePLLRegisters(ScrnInfoPtr pScrn, R128SavePtr restore);
>>>  extern void        R128RestoreDDARegisters(ScrnInfoPtr pScrn, R128SavePtr restore);
>>> diff --git a/src/r128_crtc.c b/src/r128_crtc.c
>>> index 35e1fee..882f01f 100644
>>> --- a/src/r128_crtc.c
>>> +++ b/src/r128_crtc.c
>>> @@ -119,26 +119,14 @@ static void r128_crtc_mode_prepare(xf86CrtcPtr crtc)
>>>  static void r128_crtc_mode_set(xf86CrtcPtr crtc, DisplayModePtr mode, DisplayModePtr adjusted_mode, int x, int y)
>>>  {
>>>      ScrnInfoPtr pScrn = crtc->scrn;
>>> -    xf86CrtcConfigPtr xf86_config = XF86_CRTC_CONFIG_PTR(pScrn);
>>>      R128CrtcPrivatePtr r128_crtc = crtc->driver_private;
>>>      R128InfoPtr info = R128PTR(pScrn);
>>> -    R128OutputType otype = OUTPUT_NONE;
>>> -
>>>      double dot_clock = adjusted_mode->Clock / 1000.0;
>>> -    int i;
>>>
>>>      if (r128_crtc->cursor_offset) r128_crtc_hide_cursor(crtc);
>>>      xf86PrintModeline(pScrn->scrnIndex, adjusted_mode);
>>>      R128InitCommonRegisters(&info->ModeReg, info);
>>>
>>> -    for (i = 0; i < xf86_config->num_output; i++) {
>>> -        xf86OutputPtr output = xf86_config->output[i];
>>> -        R128OutputPrivatePtr r128_output = output->driver_private;
>>> -
>>> -        if (output->crtc == crtc)
>>> -            otype = r128_output->type;
>>> -    }
>>> -
>>>      switch (r128_crtc->crtc_id) {
>>>      case 0:
>>>          R128InitCrtcRegisters(pScrn, &info->ModeReg, adjusted_mode, info);
>>> @@ -164,8 +152,6 @@ static void r128_crtc_mode_set(xf86CrtcPtr crtc, DisplayModePtr mode, DisplayMod
>>>          break;
>>>      }
>>>
>>> -    if (otype == OUTPUT_DVI || otype == OUTPUT_LVDS)
>>> -        R128InitFPRegisters(&info->SavedReg, &info->ModeReg, adjusted_mode, info);
>>>      R128RestoreCommonRegisters(pScrn, &info->ModeReg);
>>>
>>>      switch (r128_crtc->crtc_id) {
>>> @@ -181,12 +167,6 @@ static void r128_crtc_mode_set(xf86CrtcPtr crtc, DisplayModePtr mode, DisplayMod
>>>         break;
>>>      }
>>>
>>> -    if (otype == OUTPUT_DVI || otype == OUTPUT_LVDS)
>>> -        R128RestoreFPRegisters(pScrn, &info->ModeReg);
>>> -
>>> -    /* XXX: InitFPRegisters looks similar to radeon's InitRMXRegisters so
>>> -     * maybe it should be called from mode_set in the output code.
>>> -     */
>>>      if (r128_crtc->cursor_offset) r128_crtc_show_cursor(crtc);
>>>  }
>>>
>>> diff --git a/src/r128_driver.c b/src/r128_driver.c
>>> index 9205328..1e3491c 100644
>>> --- a/src/r128_driver.c
>>> +++ b/src/r128_driver.c
>>> @@ -2408,26 +2408,38 @@ void R128RestoreCrtc2Registers(ScrnInfoPtr pScrn,
>>>      OUTREG(R128_CRTC2_PITCH,           restore->crtc2_pitch);
>>>  }
>>>
>>> -/* Write flat panel registers */
>>> -void R128RestoreFPRegisters(ScrnInfoPtr pScrn, R128SavePtr restore)
>>> +/* Write RMX registers */
>>> +void R128RestoreRMXRegisters(ScrnInfoPtr pScrn, R128SavePtr restore)
>>>  {
>>>      R128InfoPtr   info      = R128PTR(pScrn);
>>>      unsigned char *R128MMIO = info->MMIO;
>>> -    CARD32        tmp;
>>>
>>> -    if (info->BIOSDisplay != R128_DUALHEAD)
>>> -        OUTREG(R128_CRTC2_GEN_CNTL,       restore->crtc2_gen_cntl);
>>>      OUTREG(R128_FP_HORZ_STRETCH,      restore->fp_horz_stretch);
>>>      OUTREG(R128_FP_VERT_STRETCH,      restore->fp_vert_stretch);
>>>      OUTREG(R128_FP_CRTC_H_TOTAL_DISP, restore->fp_crtc_h_total_disp);
>>>      OUTREG(R128_FP_CRTC_V_TOTAL_DISP, restore->fp_crtc_v_total_disp);
>>>      OUTREG(R128_FP_H_SYNC_STRT_WID,   restore->fp_h_sync_strt_wid);
>>>      OUTREG(R128_FP_V_SYNC_STRT_WID,   restore->fp_v_sync_strt_wid);
>>> -    OUTREG(R128_TMDS_CRC,             restore->tmds_crc);
>>> -    OUTREG(R128_FP_PANEL_CNTL,        restore->fp_panel_cntl);
>>> +}
>>> +
>>> +/* Write flat panel registers */
>>> +void R128RestoreFPRegisters(ScrnInfoPtr pScrn, R128SavePtr restore)
>>> +{
>>> +    R128InfoPtr   info      = R128PTR(pScrn);
>>> +    unsigned char *R128MMIO = info->MMIO;
>>> +
>>> +    OUTREG(R128_TMDS_CRC,              restore->tmds_crc);
>>> +    OUTREG(R128_TMDS_TRANSMITTER_CNTL, restore->tmds_transmitter_cntl);
>>> +    OUTREG(R128_FP_PANEL_CNTL,         restore->fp_panel_cntl);
>>>      OUTREG(R128_FP_GEN_CNTL, restore->fp_gen_cntl & ~(CARD32)R128_FP_BLANK_DIS);
>>> +}
>>>
>>> -    if(info->isDFP) return;
>>> +/* Write LVDS registers */
>>> +void R128RestoreLVDSRegisters(ScrnInfoPtr pScrn, R128SavePtr restore)
>>> +{
>>> +    R128InfoPtr   info      = R128PTR(pScrn);
>>> +    unsigned char *R128MMIO = info->MMIO;
>>> +    CARD32        tmp;
>>>
>>>      tmp = INREG(R128_LVDS_GEN_CNTL);
>>>      if ((tmp & (R128_LVDS_ON | R128_LVDS_BLON)) ==
>>> @@ -2886,7 +2898,9 @@ static void R128Restore(ScrnInfoPtr pScrn)
>>>          R128RestoreDDARegisters(pScrn, restore);
>>>          R128RestoreCrtcRegisters(pScrn, restore);
>>>          R128RestorePLLRegisters(pScrn, restore);
>>> +        R128RestoreRMXRegisters(pScrn, restore);
>>>          R128RestoreFPRegisters(pScrn, restore);
>>> +        R128RestoreLVDSRegisters(pScrn, restore);
>>>      }
>>>
>>>  #ifdef WITH_VGAHW
>>> @@ -3059,18 +3073,18 @@ Bool R128InitCrtcRegisters(ScrnInfoPtr pScrn, R128SavePtr save,
>>>      if((info->DisplayType == MT_DFP) ||
>>>         (info->DisplayType == MT_LCD))
>>>      {
>>> -        save->crtc_ext_cntl = R128_VGA_ATI_LINEAR |
>>> -                                 R128_XCRT_CNT_EN;
>>>          save->crtc_gen_cntl &= ~(R128_CRTC_DBL_SCAN_EN |
>>>                                    R128_CRTC_INTERLACE_EN);
>>>      }
>>> -    else
>>> -        save->crtc_ext_cntl = R128_VGA_ATI_LINEAR |
>>> +
>>> +    save->crtc_ext_cntl = R128_VGA_ATI_LINEAR |
>>>                               R128_XCRT_CNT_EN |
>>>                               R128_CRTC_CRT_ON;
>> FWIW, the R128_CRTC_CRT_ON bit is the enable bit for the DAC.  You may
>> want to toggle this bit in the dpms control for the DAC encoder.
>> E.g., turn it off when you aren't using the DAC to save power.
>>
>>>      save->dac_cntl      = (R128_DAC_MASK_ALL
>>>                            | R128_DAC_VGA_ADR_EN
>>> +                           | R128_DAC_CRT_SEL_CRTC2
>> R128_DAC_CRT_SEL_CRTC2 is the routing bit for which crtc drives the
>> DAC.  You probably want to check which crtc is being used for the DAC
>> and set this bit appropriately. (clear = crtc1, set = crtc2)
> Let me check if I understand this.
>
> The above would be bad on a single head (VGA) card because RMX and maybe
> the overlay only work on crtc1.
>
> The above would be bad on a dualhead (VGA + LVDS) card if I also set
> R128_LVDS_SEL_CRTC2. Because then crtc2 would drive both outputs and
> everything would be cloned.
>
> So each output should use whatever r128_crtc->crtc_id tells it to use?

Right.  It's a little unclear in the ddx since the ddxes were not
originally designed with complex display topologies in mind.  See my
blog post about radeons displays for more background:
http://www.botchco.com/agd5f/?p=51
Basically, crtcs can driver any encoder.  There is a crossbar that
lets you select which crtc drives which encoder.  Your display
pipeline looks like:
framebuffer -> crtc -> encoder -> transmitter -> connector -> monitor

Either crtc can driver any encoder.  In teh r128 case, you can treat
encoders and transmitters as one entity since they are a single hw
block.  However, only the first crtc has a scaler (RMX), so you
generally want to use that for LVDS if you want to support non-native
panel modes.  You can also drive several encoders with the same crtc
(true clone mode), however, in that case, both encoders will be
getting the same timing so that's only possible if both displays
request the same modeline.  You can enforce certain restrictions in
software by telling randr that LVDS can only be driven by the first
crtc (crtc_mask IIRC).  The xrandr core code in the xserver (or the
xrandr utility if you want to select manually) will determine what
crtcs are routed to which encoders.

LVDS and TMDS also have crtc routing bits.  You can follow the logic
in the radeon driver as the display hardware is pretty much the same
as the early radeons.

For LVDS:
LVDS_GEN_CNTL.LVDS_SEL_CRTC2

For TMDS:
FP_GEN_CNTL.FP_SEL_CRTC2

For DAC:
DAC_CNTL.DAC_CRT_SEL_CRTC2

Alex

>>
>>> +                           | R128_DAC_PALETTE2_SNOOP_EN
>> I think the PALETTE2_SNOOP_EN bit auto populates the secondary LUT
>> from the first.  I think you may need to clear this if you want to
>> program the LUTs independently.
> I think I'll commit the patch with this change already made.
>>
>>>                            | (info->dac6bits ? 0 : R128_DAC_8BIT_EN));
>>>
>>>
>>> @@ -3225,36 +3239,35 @@ Bool R128InitCrtc2Registers(ScrnInfoPtr pScrn, R128SavePtr save,
>>>      return TRUE;
>>>  }
>>>
>>> -/* Define CRTC registers for requested video mode. */
>>> -void R128InitFPRegisters(R128SavePtr orig, R128SavePtr save,
>>> -                               DisplayModePtr mode, R128InfoPtr info)
>>> +/* Define RMX registers for the requested video mode. */
>>> +void R128InitRMXRegisters(R128SavePtr orig, R128SavePtr save,
>>> +                          R128OutputPrivatePtr r128_output, DisplayModePtr mode)
>>>  {
>>>      int   xres = mode->CrtcHDisplay;
>>>      int   yres = mode->CrtcVDisplay;
>>>      float Hratio, Vratio;
>>>
>>> -    if (info->BIOSDisplay == R128_BIOS_DISPLAY_CRT) {
>>> -        save->crtc_ext_cntl  |= R128_CRTC_CRT_ON;
>>> -        save->crtc2_gen_cntl  = 0;
>>> -        save->fp_gen_cntl     = orig->fp_gen_cntl;
>>> -        save->fp_gen_cntl    &= ~(R128_FP_FPON |
>>> -            R128_FP_CRTC_USE_SHADOW_VEND |
>>> -            R128_FP_CRTC_HORZ_DIV2_EN |
>>> -            R128_FP_CRTC_HOR_CRT_DIV2_DIS |
>>> -            R128_FP_USE_SHADOW_EN);
>>> -        save->fp_gen_cntl    |= (R128_FP_SEL_CRTC2 |
>>> -                                 R128_FP_CRTC_DONT_SHADOW_VPAR);
>>> -        save->fp_panel_cntl   = orig->fp_panel_cntl & (CARD32)~R128_FP_DIGON;
>>> -        save->lvds_gen_cntl   = orig->lvds_gen_cntl &
>>> -                                   (CARD32)~(R128_LVDS_ON | R128_LVDS_BLON);
>>> +    save->fp_crtc_h_total_disp = save->crtc_h_total_disp;
>>> +    save->fp_crtc_v_total_disp = save->crtc_v_total_disp;
>>> +    save->fp_h_sync_strt_wid   = save->crtc_h_sync_strt_wid;
>>> +    save->fp_v_sync_strt_wid   = save->crtc_v_sync_strt_wid;
>>> +
>>> +    if (r128_output->type != OUTPUT_DVI && r128_output->type != OUTPUT_LVDS)
>>>          return;
>>> -    }
>>>
>>> -    if (xres > info->PanelXRes) xres = info->PanelXRes;
>>> -    if (yres > info->PanelYRes) yres = info->PanelYRes;
>>> +    if (r128_output->PanelXRes == 0 || r128_output->PanelYRes == 0) {
>>> +        xres = r128_output->PanelXRes;
>>> +        yres = r128_output->PanelYRes;
>>>
>>> -    Hratio = (float)xres/(float)info->PanelXRes;
>>> -    Vratio = (float)yres/(float)info->PanelYRes;
>>> +        Hratio = 1.0;
>>> +        Vratio = 1.0;
>>> +    } else {
>>> +        if (xres > r128_output->PanelXRes) xres = r128_output->PanelXRes;
>>> +        if (yres > r128_output->PanelYRes) yres = r128_output->PanelYRes;
>>> +
>>> +        Hratio = (float)xres/(float)r128_output->PanelXRes;
>>> +        Vratio = (float)yres/(float)r128_output->PanelYRes;
>>> +    }
>>>
>>>      save->fp_horz_stretch =
>>>         (((((int)(Hratio * R128_HORZ_STRETCH_RATIO_MAX + 0.5))
>>> @@ -3264,7 +3277,7 @@ void R128InitFPRegisters(R128SavePtr orig, R128SavePtr save,
>>>                                   R128_HORZ_STRETCH_RESERVED)));
>>>      save->fp_horz_stretch &= ~R128_HORZ_AUTO_RATIO_FIX_EN;
>>>      save->fp_horz_stretch &= ~R128_AUTO_HORZ_RATIO;
>>> -    if (xres == info->PanelXRes)
>>> +    if (xres == r128_output->PanelXRes)
>>>           save->fp_horz_stretch &= ~(R128_HORZ_STRETCH_BLEND | R128_HORZ_STRETCH_ENABLE);
>>>      else
>>>           save->fp_horz_stretch |=  (R128_HORZ_STRETCH_BLEND | R128_HORZ_STRETCH_ENABLE);
>>> @@ -3275,67 +3288,43 @@ void R128InitFPRegisters(R128SavePtr orig, R128SavePtr save,
>>>          (orig->fp_vert_stretch & (R128_VERT_PANEL_SIZE |
>>>                                    R128_VERT_STRETCH_RESERVED)));
>>>      save->fp_vert_stretch &= ~R128_VERT_AUTO_RATIO_EN;
>>> -    if (yres == info->PanelYRes)
>>> +    if (yres == r128_output->PanelYRes)
>>>          save->fp_vert_stretch &= ~(R128_VERT_STRETCH_ENABLE | R128_VERT_STRETCH_BLEND);
>>>      else
>>>          save->fp_vert_stretch |=  (R128_VERT_STRETCH_ENABLE | R128_VERT_STRETCH_BLEND);
>>> +}
>>>
>>> -    save->fp_gen_cntl = (orig->fp_gen_cntl &
>>> -                        (CARD32)~(R128_FP_SEL_CRTC2 |
>>> -                                  R128_FP_CRTC_USE_SHADOW_VEND |
>>> -                                  R128_FP_CRTC_HORZ_DIV2_EN |
>>> -                                  R128_FP_CRTC_HOR_CRT_DIV2_DIS |
>>> -                                  R128_FP_USE_SHADOW_EN));
>>> -
>>> -    save->fp_panel_cntl        = orig->fp_panel_cntl;
>>> -    save->lvds_gen_cntl        = orig->lvds_gen_cntl;
>>> -    save->tmds_crc             = orig->tmds_crc;
>>> -
>>> -    /* Disable CRT output by disabling CRT output and setting the CRT
>>> -       DAC to use CRTC2, which we set to 0's.  In the future, we will
>>> -       want to use the dual CRTC capabilities of the R128 to allow both
>>> -       the flat panel and external CRT to either simultaneously display
>>> -       the same image or display two different images. */
>>> -
>>> -
>>> -    if(!info->isDFP){
>>> -        if (info->BIOSDisplay == R128_BIOS_DISPLAY_FP_CRT) {
>>> -               save->crtc_ext_cntl  |= R128_CRTC_CRT_ON;
>>> -       } else if (info->BIOSDisplay == R128_DUALHEAD) {
>>> -               save->crtc_ext_cntl  |= R128_CRTC_CRT_ON;
>>> -               save->dac_cntl       |= R128_DAC_CRT_SEL_CRTC2;
>>> -               save->dac_cntl       |= R128_DAC_PALETTE2_SNOOP_EN;
>>> -        } else {
>>> -               save->crtc_ext_cntl  &= ~R128_CRTC_CRT_ON;
>>> -               save->dac_cntl       |= R128_DAC_CRT_SEL_CRTC2;
>>> -               save->crtc2_gen_cntl  = 0;
>>> -        }
>>> -    }
>>> -
>>> +/* Define flat panel registers for the requested video mode. */
>>> +void R128InitFPRegisters(R128SavePtr orig, R128SavePtr save)
>>> +{
>>>      /* WARNING: Be careful about turning on the flat panel */
>>> -    if(info->isDFP){
>>> -        save->fp_gen_cntl = orig->fp_gen_cntl;
>>> -
>>> -        save->fp_gen_cntl &= ~(R128_FP_CRTC_USE_SHADOW_VEND |
>>> -                               R128_FP_CRTC_USE_SHADOW_ROWCUR |
>>> -                               R128_FP_CRTC_HORZ_DIV2_EN |
>>> -                               R128_FP_CRTC_HOR_CRT_DIV2_DIS |
>>> -                               R128_FP_CRT_SYNC_SEL |
>>> -                               R128_FP_USE_SHADOW_EN);
>>> -
>>> -        save->fp_panel_cntl  |= (R128_FP_DIGON | R128_FP_BLON);
>>> -        save->fp_gen_cntl    |= (R128_FP_FPON | R128_FP_TDMS_EN |
>>> -             R128_FP_CRTC_DONT_SHADOW_VPAR | R128_FP_CRTC_DONT_SHADOW_HEND);
>>> -        save->tmds_transmitter_cntl = (orig->tmds_transmitter_cntl
>>> -            & ~(CARD32)R128_TMDS_PLLRST) | R128_TMDS_PLLEN;
>>> -    }
>>> -    else
>>> -        save->lvds_gen_cntl  |= (R128_LVDS_ON | R128_LVDS_BLON);
>>> +    save->fp_gen_cntl            = orig->fp_gen_cntl;
>>> +    save->fp_panel_cntl          = orig->fp_panel_cntl;
>>> +    save->tmds_transmitter_cntl  = orig->tmds_transmitter_cntl;
>>> +    save->tmds_crc               = orig->tmds_crc;
>>>
>>> -    save->fp_crtc_h_total_disp = save->crtc_h_total_disp;
>>> -    save->fp_crtc_v_total_disp = save->crtc_v_total_disp;
>>> -    save->fp_h_sync_strt_wid   = save->crtc_h_sync_strt_wid;
>>> -    save->fp_v_sync_strt_wid   = save->crtc_v_sync_strt_wid;
>>> +    save->fp_gen_cntl           &= ~(R128_FP_CRTC_USE_SHADOW_VEND |
>>> +                                     R128_FP_CRTC_USE_SHADOW_ROWCUR |
>>> +                                     R128_FP_CRTC_HORZ_DIV2_EN |
>>> +                                     R128_FP_CRTC_HOR_CRT_DIV2_DIS |
>>> +                                     R128_FP_CRT_SYNC_SEL |
>>> +                                     R128_FP_USE_SHADOW_EN);
>>> +
>>> +    save->fp_gen_cntl           |=  (R128_FP_FPON |
>>> +                                     R128_FP_TDMS_EN |
>>> +                                     R128_FP_CRTC_DONT_SHADOW_VPAR |
>>> +                                     R128_FP_CRTC_DONT_SHADOW_HEND);
>> The FP_FPON and TMDS_EN bits are the enable bits for the TMDS encoder,
>> you may want to program these in the dpms callback for the TMDS
>> encoder.
>>
>>> +
>>> +    save->fp_panel_cntl         |=  (R128_FP_DIGON | R128_FP_BLON);
>>> +    save->tmds_transmitter_cntl &=  ~R128_TMDS_PLLRST;
>>> +    save->tmds_transmitter_cntl |=   R128_TMDS_PLLEN;
>>> +}
>>> +
>>> +/* Define LVDS registers for the requested video mode. */
>>> +void R128InitLVDSRegisters(R128SavePtr orig, R128SavePtr save)
>>> +{
>>> +    save->lvds_gen_cntl  = orig->lvds_gen_cntl;
>>> +    save->lvds_gen_cntl |= (R128_LVDS_ON | R128_LVDS_BLON);
>> Same as the above comment only for LVDS.
> I'll write a follow up patch that moves these enable bits to the dpms part.
>>>  }
>>>
>>>  /* Define PLL registers for requested video mode. */
>>> diff --git a/src/r128_output.c b/src/r128_output.c
>>> index 89a2958..9e0d410 100644
>>> --- a/src/r128_output.c
>>> +++ b/src/r128_output.c
>>> @@ -81,6 +81,27 @@ static void r128_mode_prepare(xf86OutputPtr output)
>>>
>>>  static void r128_mode_set(xf86OutputPtr output, DisplayModePtr mode, DisplayModePtr adjusted_mode)
>>>  {
>>> +    ScrnInfoPtr pScrn = output->scrn;
>>> +    R128InfoPtr info = R128PTR(pScrn);
>>> +    R128OutputPrivatePtr r128_output = output->driver_private;
>>> +    xf86CrtcPtr crtc = output->crtc;
>>> +    R128CrtcPrivatePtr r128_crtc = crtc->driver_private;
>>> +
>>> +    if (r128_crtc->crtc_id == 0)
>>> +        R128InitRMXRegisters(&info->SavedReg, &info->ModeReg, r128_output, adjusted_mode);
>>> +
>>> +    if (r128_output->type == OUTPUT_DVI)
>>> +        R128InitFPRegisters(&info->SavedReg, &info->ModeReg);
>>> +    else if (r128_output->type == OUTPUT_LVDS)
>>> +        R128InitLVDSRegisters(&info->SavedReg, &info->ModeReg);
>>> +
>>> +    if (r128_crtc->crtc_id == 0)
>>> +        R128RestoreRMXRegisters(pScrn, &info->ModeReg);
>>> +
>>> +    if (r128_output->type == OUTPUT_DVI)
>>> +        R128RestoreFPRegisters(pScrn, &info->ModeReg);
>>> +    else if (r128_output->type == OUTPUT_LVDS)
>>> +        R128RestoreLVDSRegisters(pScrn, &info->ModeReg);
>>>  }
>>>
>>>  static void r128_mode_commit(xf86OutputPtr output)
>>> @@ -455,7 +476,10 @@ Bool R128SetupConnectors(ScrnInfoPtr pScrn)
>>>                 }
>>>                 r128_output->ddc_i2c = i2c;
>>>                 R128I2CInit(output, &r128_output->pI2CBus, output->name);
>>> -           }
>>> +           } else if (conntype == CONNECTOR_LVDS) {
>>> +                r128_output->PanelXRes = info->PanelXRes;
>>> +                r128_output->PanelYRes = info->PanelYRes;
>>> +            }
>>>
>>>              R128SetOutputType(pScrn, r128_output);
>>>          }
>>> diff --git a/src/r128_probe.h b/src/r128_probe.h
>>> index f521a13..95988ec 100644
>>> --- a/src/r128_probe.h
>>> +++ b/src/r128_probe.h
>>> @@ -161,6 +161,8 @@ typedef struct _R128OutputPrivateRec {
>>>      R128MonitorType MonType;
>>>      I2CBusPtr pI2CBus;
>>>      R128I2CBusRec ddc_i2c;
>>> +    int PanelXRes;
>>> +    int PanelYRes;
>>>  } R128OutputPrivateRec, *R128OutputPrivatePtr;
>>>
>>>  #define R128_MAX_CRTC 2
>>> --
>>> 2.0.0
>>>
>>> _______________________________________________
>>> xorg-driver-ati mailing list
>>> xorg-driver-ati at lists.x.org
>>> http://lists.x.org/mailman/listinfo/xorg-driver-ati
>
>


More information about the xorg-driver-ati mailing list