aboutsummaryrefslogtreecommitdiff
path: root/linux-core/atombios_crtc.c
diff options
context:
space:
mode:
authorAlex Deucher <alexdeucher@gmail.com>2008-09-25 18:45:07 -0400
committerAlex Deucher <alexdeucher@gmail.com>2008-09-25 18:45:07 -0400
commitd883347f087eb1ce410392a379dfa6a44b2d14d1 (patch)
tree7d4b119901a62eb115adc5137eb1a63737dda195 /linux-core/atombios_crtc.c
parent35e379ce5a0d23f4c812739f89e02703900cd91b (diff)
radeon: first pass at using atombios on r4xx hw
Diffstat (limited to 'linux-core/atombios_crtc.c')
-rw-r--r--linux-core/atombios_crtc.c71
1 files changed, 64 insertions, 7 deletions
diff --git a/linux-core/atombios_crtc.c b/linux-core/atombios_crtc.c
index 16bcbe87..922cc7e0 100644
--- a/linux-core/atombios_crtc.c
+++ b/linux-core/atombios_crtc.c
@@ -121,6 +121,29 @@ void atombios_crtc_dpms(struct drm_crtc *crtc, int mode)
}
}
+static void
+atombios_set_crtc_dtd_timing(struct drm_crtc *crtc, SET_CRTC_USING_DTD_TIMING_PARAMETERS *crtc_param)
+{
+ struct radeon_crtc *radeon_crtc = to_radeon_crtc(crtc);
+ struct drm_device *dev = crtc->dev;
+ struct drm_radeon_private *dev_priv = dev->dev_private;
+ SET_CRTC_USING_DTD_TIMING_PARAMETERS conv_param;
+ int index = GetIndexIntoMasterTable(COMMAND, SetCRTC_UsingDTDTiming);
+
+ conv_param.usH_Size = cpu_to_le16(crtc_param->usH_Size);
+ conv_param.usH_Blanking_Time = cpu_to_le16(crtc_param->usH_Blanking_Time);
+ conv_param.usV_Size = cpu_to_le16(crtc_param->usV_Size);
+ conv_param.usV_Blanking_Time = cpu_to_le16(crtc_param->usV_Blanking_Time);
+ conv_param.usH_SyncOffset = cpu_to_le16(crtc_param->usH_SyncOffset);
+ conv_param.usH_SyncWidth = cpu_to_le16(crtc_param->usH_SyncWidth);
+ conv_param.usV_SyncOffset = cpu_to_le16(crtc_param->usV_SyncOffset);
+ conv_param.usV_SyncWidth = cpu_to_le16(crtc_param->usV_SyncWidth);
+ conv_param.susModeMiscInfo.usAccess = cpu_to_le16(crtc_param->susModeMiscInfo.usAccess);
+ conv_param.ucCRTC = crtc_param->ucCRTC;
+
+ printk("executing set crtc dtd timing\n");
+ atom_execute_table(dev_priv->mode_info.atom_context, index, (uint32_t *)&conv_param);
+}
void atombios_crtc_set_timing(struct drm_crtc *crtc, SET_CRTC_TIMING_PARAMETERS_PS_ALLOCATION *crtc_param)
{
@@ -170,7 +193,7 @@ void atombios_crtc_set_pll(struct drm_crtc *crtc, struct drm_display_mode *mode)
if (!radeon_is_avivo(dev_priv))
pll_flags |= RADEON_PLL_LEGACY;
- if (mode->clock > 120000) /* range limits??? */
+ if (mode->clock > 200000) /* range limits??? */
pll_flags |= RADEON_PLL_PREFER_HIGH_FB_DIV;
else
pll_flags |= RADEON_PLL_PREFER_LOW_REF_DIV;
@@ -319,8 +342,8 @@ void atombios_crtc_mode_set(struct drm_crtc *crtc,
struct drm_radeon_private *dev_priv = dev->dev_private;
struct drm_encoder *encoder;
SET_CRTC_TIMING_PARAMETERS_PS_ALLOCATION crtc_timing;
- /* TODO color tiling */
+ /* TODO color tiling */
memset(&crtc_timing, 0, sizeof(crtc_timing));
list_for_each_entry(encoder, &dev->mode_config.encoder_list, head) {
@@ -355,14 +378,48 @@ void atombios_crtc_mode_set(struct drm_crtc *crtc,
if (adjusted_mode->flags & DRM_MODE_FLAG_DBLSCAN)
crtc_timing.susModeMiscInfo.usAccess |= ATOM_DOUBLE_CLOCK_MODE;
+ atombios_crtc_set_pll(crtc, adjusted_mode);
+ atombios_crtc_set_timing(crtc, &crtc_timing);
+
if (radeon_is_avivo(dev_priv))
atombios_crtc_set_base(crtc, x, y);
- else
+ else {
+ if (radeon_crtc->crtc_id == 0) {
+ SET_CRTC_USING_DTD_TIMING_PARAMETERS crtc_dtd_timing;
+ memset(&crtc_dtd_timing, 0, sizeof(crtc_dtd_timing));
+
+ /* setup FP shadow regs on R4xx */
+ crtc_dtd_timing.ucCRTC = radeon_crtc->crtc_id;
+ crtc_dtd_timing.usH_Size = adjusted_mode->crtc_hdisplay;
+ crtc_dtd_timing.usV_Size = adjusted_mode->crtc_vdisplay;
+ crtc_dtd_timing.usH_Blanking_Time = adjusted_mode->crtc_hblank_end - adjusted_mode->crtc_hdisplay;
+ crtc_dtd_timing.usV_Blanking_Time = adjusted_mode->crtc_vblank_end - adjusted_mode->crtc_vdisplay;
+ crtc_dtd_timing.usH_SyncOffset = adjusted_mode->crtc_hsync_start - adjusted_mode->crtc_hdisplay;
+ crtc_dtd_timing.usV_SyncOffset = adjusted_mode->crtc_vsync_start - adjusted_mode->crtc_vdisplay;
+ crtc_dtd_timing.usH_SyncWidth = adjusted_mode->crtc_hsync_end - adjusted_mode->crtc_hsync_start;
+ crtc_dtd_timing.usV_SyncWidth = adjusted_mode->crtc_vsync_end - adjusted_mode->crtc_vsync_start;
+ //crtc_dtd_timing.ucH_Border = adjusted_mode->crtc_hborder;
+ //crtc_dtd_timing.ucV_Border = adjusted_mode->crtc_vborder;
+
+ if (adjusted_mode->flags & DRM_MODE_FLAG_NVSYNC)
+ crtc_dtd_timing.susModeMiscInfo.usAccess |= ATOM_VSYNC_POLARITY;
+
+ if (adjusted_mode->flags & DRM_MODE_FLAG_NHSYNC)
+ crtc_dtd_timing.susModeMiscInfo.usAccess |= ATOM_HSYNC_POLARITY;
+
+ if (adjusted_mode->flags & DRM_MODE_FLAG_CSYNC)
+ crtc_dtd_timing.susModeMiscInfo.usAccess |= ATOM_COMPOSITESYNC;
+
+ if (adjusted_mode->flags & DRM_MODE_FLAG_INTERLACE)
+ crtc_dtd_timing.susModeMiscInfo.usAccess |= ATOM_INTERLACE;
+
+ if (adjusted_mode->flags & DRM_MODE_FLAG_DBLSCAN)
+ crtc_dtd_timing.susModeMiscInfo.usAccess |= ATOM_DOUBLE_CLOCK_MODE;
+
+ atombios_set_crtc_dtd_timing(crtc, &crtc_dtd_timing);
+ }
radeon_crtc_set_base(crtc, x, y);
-
- atombios_crtc_set_pll(crtc, adjusted_mode);
-
- atombios_crtc_set_timing(crtc, &crtc_timing);
+ }
}