/drivers/video/drm/drm_crtc_helper.c |
---|
331,6 → 331,7 |
cmdline_mode->refresh_specified ? cmdline_mode->refresh : 60, |
cmdline_mode->rb, cmdline_mode->interlace, |
cmdline_mode->margins); |
drm_mode_set_crtcinfo(mode, CRTC_INTERLACE_HALVE_V); |
list_add(&mode->head, &connector->modes); |
return mode; |
} |
/drivers/video/drm/drm_fb_helper.c |
---|
493,7 → 493,7 |
if (crtc->fb == fb_helper->crtc_info[i].mode_set.fb) { |
mutex_lock(&dev->mode_config.mutex); |
ret = crtc->funcs->set_config(&fb_helper->crtc_info->mode_set); |
ret = crtc->funcs->set_config(&fb_helper->crtc_info[i].mode_set); |
mutex_unlock(&dev->mode_config.mutex); |
if (ret) |
return ret; |
/drivers/video/drm/radeon/atombios.h |
---|
2314,7 → 2314,7 |
UCHAR ucSS_Step; |
UCHAR ucSS_Delay; |
UCHAR ucSS_Id; |
UCHAR ucRecommandedRef_Div; |
UCHAR ucRecommendedRef_Div; |
UCHAR ucSS_Range; /* it was reserved for V11 */ |
} ATOM_SPREAD_SPECTRUM_ASSIGNMENT; |
/drivers/video/drm/radeon/atombios_crtc.c |
---|
31,10 → 31,6 |
#include "atom.h" |
#include "atom-bits.h" |
/* evil but including atombios.h is much worse */ |
bool radeon_atom_get_tv_timings(struct radeon_device *rdev, int index, |
SET_CRTC_TIMING_PARAMETERS_PS_ALLOCATION *crtc_timing, |
int32_t *pixel_clock); |
static void atombios_overscan_setup(struct drm_crtc *crtc, |
struct drm_display_mode *mode, |
struct drm_display_mode *adjusted_mode) |
248,9 → 244,9 |
switch (mode) { |
case DRM_MODE_DPMS_ON: |
atombios_enable_crtc(crtc, 1); |
if (ASIC_IS_DCE3(rdev)) |
atombios_enable_crtc_memreq(crtc, 1); |
atombios_enable_crtc(crtc, 1); |
atombios_blank_crtc(crtc, 0); |
break; |
case DRM_MODE_DPMS_STANDBY: |
257,9 → 253,9 |
case DRM_MODE_DPMS_SUSPEND: |
case DRM_MODE_DPMS_OFF: |
atombios_blank_crtc(crtc, 1); |
atombios_enable_crtc(crtc, 0); |
if (ASIC_IS_DCE3(rdev)) |
atombios_enable_crtc_memreq(crtc, 0); |
atombios_enable_crtc(crtc, 0); |
break; |
} |
270,61 → 266,149 |
static void |
atombios_set_crtc_dtd_timing(struct drm_crtc *crtc, |
SET_CRTC_USING_DTD_TIMING_PARAMETERS * crtc_param) |
struct drm_display_mode *mode) |
{ |
struct radeon_crtc *radeon_crtc = to_radeon_crtc(crtc); |
struct drm_device *dev = crtc->dev; |
struct radeon_device *rdev = dev->dev_private; |
SET_CRTC_USING_DTD_TIMING_PARAMETERS conv_param; |
SET_CRTC_USING_DTD_TIMING_PARAMETERS args; |
int index = GetIndexIntoMasterTable(COMMAND, SetCRTC_UsingDTDTiming); |
u16 misc = 0; |
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; |
memset(&args, 0, sizeof(args)); |
args.usH_Size = cpu_to_le16(mode->crtc_hdisplay); |
args.usH_Blanking_Time = |
cpu_to_le16(mode->crtc_hblank_end - mode->crtc_hdisplay); |
args.usV_Size = cpu_to_le16(mode->crtc_vdisplay); |
args.usV_Blanking_Time = |
cpu_to_le16(mode->crtc_vblank_end - mode->crtc_vdisplay); |
args.usH_SyncOffset = |
cpu_to_le16(mode->crtc_hsync_start - mode->crtc_hdisplay); |
args.usH_SyncWidth = |
cpu_to_le16(mode->crtc_hsync_end - mode->crtc_hsync_start); |
args.usV_SyncOffset = |
cpu_to_le16(mode->crtc_vsync_start - mode->crtc_vdisplay); |
args.usV_SyncWidth = |
cpu_to_le16(mode->crtc_vsync_end - mode->crtc_vsync_start); |
/*args.ucH_Border = mode->hborder;*/ |
/*args.ucV_Border = mode->vborder;*/ |
if (mode->flags & DRM_MODE_FLAG_NVSYNC) |
misc |= ATOM_VSYNC_POLARITY; |
if (mode->flags & DRM_MODE_FLAG_NHSYNC) |
misc |= ATOM_HSYNC_POLARITY; |
if (mode->flags & DRM_MODE_FLAG_CSYNC) |
misc |= ATOM_COMPOSITESYNC; |
if (mode->flags & DRM_MODE_FLAG_INTERLACE) |
misc |= ATOM_INTERLACE; |
if (mode->flags & DRM_MODE_FLAG_DBLSCAN) |
misc |= ATOM_DOUBLE_CLOCK_MODE; |
args.susModeMiscInfo.usAccess = cpu_to_le16(misc); |
args.ucCRTC = radeon_crtc->crtc_id; |
printk("executing set crtc dtd timing\n"); |
atom_execute_table(rdev->mode_info.atom_context, index, (uint32_t *)&conv_param); |
atom_execute_table(rdev->mode_info.atom_context, index, (uint32_t *)&args); |
} |
void atombios_crtc_set_timing(struct drm_crtc *crtc, |
SET_CRTC_TIMING_PARAMETERS_PS_ALLOCATION * |
crtc_param) |
static void atombios_crtc_set_timing(struct drm_crtc *crtc, |
struct drm_display_mode *mode) |
{ |
struct radeon_crtc *radeon_crtc = to_radeon_crtc(crtc); |
struct drm_device *dev = crtc->dev; |
struct radeon_device *rdev = dev->dev_private; |
SET_CRTC_TIMING_PARAMETERS_PS_ALLOCATION conv_param; |
SET_CRTC_TIMING_PARAMETERS_PS_ALLOCATION args; |
int index = GetIndexIntoMasterTable(COMMAND, SetCRTC_Timing); |
u16 misc = 0; |
conv_param.usH_Total = cpu_to_le16(crtc_param->usH_Total); |
conv_param.usH_Disp = cpu_to_le16(crtc_param->usH_Disp); |
conv_param.usH_SyncStart = cpu_to_le16(crtc_param->usH_SyncStart); |
conv_param.usH_SyncWidth = cpu_to_le16(crtc_param->usH_SyncWidth); |
conv_param.usV_Total = cpu_to_le16(crtc_param->usV_Total); |
conv_param.usV_Disp = cpu_to_le16(crtc_param->usV_Disp); |
conv_param.usV_SyncStart = cpu_to_le16(crtc_param->usV_SyncStart); |
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; |
conv_param.ucOverscanRight = crtc_param->ucOverscanRight; |
conv_param.ucOverscanLeft = crtc_param->ucOverscanLeft; |
conv_param.ucOverscanBottom = crtc_param->ucOverscanBottom; |
conv_param.ucOverscanTop = crtc_param->ucOverscanTop; |
conv_param.ucReserved = crtc_param->ucReserved; |
memset(&args, 0, sizeof(args)); |
args.usH_Total = cpu_to_le16(mode->crtc_htotal); |
args.usH_Disp = cpu_to_le16(mode->crtc_hdisplay); |
args.usH_SyncStart = cpu_to_le16(mode->crtc_hsync_start); |
args.usH_SyncWidth = |
cpu_to_le16(mode->crtc_hsync_end - mode->crtc_hsync_start); |
args.usV_Total = cpu_to_le16(mode->crtc_vtotal); |
args.usV_Disp = cpu_to_le16(mode->crtc_vdisplay); |
args.usV_SyncStart = cpu_to_le16(mode->crtc_vsync_start); |
args.usV_SyncWidth = |
cpu_to_le16(mode->crtc_vsync_end - mode->crtc_vsync_start); |
if (mode->flags & DRM_MODE_FLAG_NVSYNC) |
misc |= ATOM_VSYNC_POLARITY; |
if (mode->flags & DRM_MODE_FLAG_NHSYNC) |
misc |= ATOM_HSYNC_POLARITY; |
if (mode->flags & DRM_MODE_FLAG_CSYNC) |
misc |= ATOM_COMPOSITESYNC; |
if (mode->flags & DRM_MODE_FLAG_INTERLACE) |
misc |= ATOM_INTERLACE; |
if (mode->flags & DRM_MODE_FLAG_DBLSCAN) |
misc |= ATOM_DOUBLE_CLOCK_MODE; |
args.susModeMiscInfo.usAccess = cpu_to_le16(misc); |
args.ucCRTC = radeon_crtc->crtc_id; |
printk("executing set crtc timing\n"); |
atom_execute_table(rdev->mode_info.atom_context, index, (uint32_t *)&conv_param); |
atom_execute_table(rdev->mode_info.atom_context, index, (uint32_t *)&args); |
} |
static void atombios_set_ss(struct drm_crtc *crtc, int enable) |
{ |
struct radeon_crtc *radeon_crtc = to_radeon_crtc(crtc); |
struct drm_device *dev = crtc->dev; |
struct radeon_device *rdev = dev->dev_private; |
struct drm_encoder *encoder = NULL; |
struct radeon_encoder *radeon_encoder = NULL; |
struct radeon_encoder_atom_dig *dig = NULL; |
int index = GetIndexIntoMasterTable(COMMAND, EnableSpreadSpectrumOnPPLL); |
ENABLE_SPREAD_SPECTRUM_ON_PPLL_PS_ALLOCATION args; |
ENABLE_LVDS_SS_PARAMETERS legacy_args; |
uint16_t percentage = 0; |
uint8_t type = 0, step = 0, delay = 0, range = 0; |
list_for_each_entry(encoder, &dev->mode_config.encoder_list, head) { |
if (encoder->crtc == crtc) { |
radeon_encoder = to_radeon_encoder(encoder); |
/* only enable spread spectrum on LVDS */ |
if (radeon_encoder->devices & (ATOM_DEVICE_LCD_SUPPORT)) { |
dig = radeon_encoder->enc_priv; |
if (dig && dig->ss) { |
percentage = dig->ss->percentage; |
type = dig->ss->type; |
step = dig->ss->step; |
delay = dig->ss->delay; |
range = dig->ss->range; |
} else if (enable) |
return; |
} else if (enable) |
return; |
break; |
} |
} |
if (!radeon_encoder) |
return; |
if (ASIC_IS_AVIVO(rdev)) { |
memset(&args, 0, sizeof(args)); |
args.usSpreadSpectrumPercentage = cpu_to_le16(percentage); |
args.ucSpreadSpectrumType = type; |
args.ucSpreadSpectrumStep = step; |
args.ucSpreadSpectrumDelay = delay; |
args.ucSpreadSpectrumRange = range; |
args.ucPpll = radeon_crtc->crtc_id ? ATOM_PPLL2 : ATOM_PPLL1; |
args.ucEnable = enable; |
atom_execute_table(rdev->mode_info.atom_context, index, (uint32_t *)&args); |
} else { |
memset(&legacy_args, 0, sizeof(legacy_args)); |
legacy_args.usSpreadSpectrumPercentage = cpu_to_le16(percentage); |
legacy_args.ucSpreadSpectrumType = type; |
legacy_args.ucSpreadSpectrumStepSize_Delay = (step & 3) << 2; |
legacy_args.ucSpreadSpectrumStepSize_Delay |= (delay & 7) << 4; |
legacy_args.ucEnable = enable; |
atom_execute_table(rdev->mode_info.atom_context, index, (uint32_t *)&legacy_args); |
} |
} |
void atombios_crtc_set_pll(struct drm_crtc *crtc, struct drm_display_mode *mode) |
{ |
struct radeon_crtc *radeon_crtc = to_radeon_crtc(crtc); |
333,12 → 417,13 |
struct drm_encoder *encoder = NULL; |
struct radeon_encoder *radeon_encoder = NULL; |
uint8_t frev, crev; |
int index = GetIndexIntoMasterTable(COMMAND, SetPixelClock); |
int index; |
SET_PIXEL_CLOCK_PS_ALLOCATION args; |
PIXEL_CLOCK_PARAMETERS *spc1_ptr; |
PIXEL_CLOCK_PARAMETERS_V2 *spc2_ptr; |
PIXEL_CLOCK_PARAMETERS_V3 *spc3_ptr; |
uint32_t sclock = mode->clock; |
uint32_t pll_clock = mode->clock; |
uint32_t adjusted_clock; |
uint32_t ref_div = 0, fb_div = 0, frac_fb_div = 0, post_div = 0; |
struct radeon_pll *pll; |
int pll_flags = 0; |
346,8 → 431,6 |
memset(&args, 0, sizeof(args)); |
if (ASIC_IS_AVIVO(rdev)) { |
uint32_t ss_cntl; |
if ((rdev->family == CHIP_RS600) || |
(rdev->family == CHIP_RS690) || |
(rdev->family == CHIP_RS740)) |
358,16 → 441,7 |
pll_flags |= RADEON_PLL_PREFER_HIGH_FB_DIV; |
else |
pll_flags |= RADEON_PLL_PREFER_LOW_REF_DIV; |
/* disable spread spectrum clocking for now -- thanks Hedy Lamarr */ |
if (radeon_crtc->crtc_id == 0) { |
ss_cntl = RREG32(AVIVO_P1PLL_INT_SS_CNTL); |
WREG32(AVIVO_P1PLL_INT_SS_CNTL, ss_cntl & ~1); |
} else { |
ss_cntl = RREG32(AVIVO_P2PLL_INT_SS_CNTL); |
WREG32(AVIVO_P2PLL_INT_SS_CNTL, ss_cntl & ~1); |
} |
} else { |
pll_flags |= RADEON_PLL_LEGACY; |
if (mode->clock > 200000) /* range limits??? */ |
393,14 → 467,43 |
} |
} |
/* DCE3+ has an AdjustDisplayPll that will adjust the pixel clock |
* accordingly based on the encoder/transmitter to work around |
* special hw requirements. |
*/ |
if (ASIC_IS_DCE3(rdev)) { |
ADJUST_DISPLAY_PLL_PS_ALLOCATION adjust_pll_args; |
if (!encoder) |
return; |
memset(&adjust_pll_args, 0, sizeof(adjust_pll_args)); |
adjust_pll_args.usPixelClock = cpu_to_le16(mode->clock / 10); |
adjust_pll_args.ucTransmitterID = radeon_encoder->encoder_id; |
adjust_pll_args.ucEncodeMode = atombios_get_encoder_mode(encoder); |
index = GetIndexIntoMasterTable(COMMAND, AdjustDisplayPll); |
atom_execute_table(rdev->mode_info.atom_context, |
index, (uint32_t *)&adjust_pll_args); |
adjusted_clock = le16_to_cpu(adjust_pll_args.usPixelClock) * 10; |
} else { |
/* DVO wants 2x pixel clock if the DVO chip is in 12 bit mode */ |
if (ASIC_IS_AVIVO(rdev) && |
(radeon_encoder->encoder_id == ENCODER_OBJECT_ID_INTERNAL_KLDSCP_DVO1)) |
adjusted_clock = mode->clock * 2; |
else |
adjusted_clock = mode->clock; |
} |
if (radeon_crtc->crtc_id == 0) |
pll = &rdev->clock.p1pll; |
else |
pll = &rdev->clock.p2pll; |
radeon_compute_pll(pll, mode->clock, &sclock, &fb_div, &frac_fb_div, |
radeon_compute_pll(pll, adjusted_clock, &pll_clock, &fb_div, &frac_fb_div, |
&ref_div, &post_div, pll_flags); |
index = GetIndexIntoMasterTable(COMMAND, SetPixelClock); |
atom_parse_cmd_header(rdev->mode_info.atom_context, index, &frev, |
&crev); |
409,7 → 512,7 |
switch (crev) { |
case 1: |
spc1_ptr = (PIXEL_CLOCK_PARAMETERS *) & args.sPCLKInput; |
spc1_ptr->usPixelClock = cpu_to_le16(sclock); |
spc1_ptr->usPixelClock = cpu_to_le16(mode->clock / 10); |
spc1_ptr->usRefDiv = cpu_to_le16(ref_div); |
spc1_ptr->usFbDiv = cpu_to_le16(fb_div); |
spc1_ptr->ucFracFbDiv = frac_fb_div; |
422,7 → 525,7 |
case 2: |
spc2_ptr = |
(PIXEL_CLOCK_PARAMETERS_V2 *) & args.sPCLKInput; |
spc2_ptr->usPixelClock = cpu_to_le16(sclock); |
spc2_ptr->usPixelClock = cpu_to_le16(mode->clock / 10); |
spc2_ptr->usRefDiv = cpu_to_le16(ref_div); |
spc2_ptr->usFbDiv = cpu_to_le16(fb_div); |
spc2_ptr->ucFracFbDiv = frac_fb_div; |
437,7 → 540,7 |
return; |
spc3_ptr = |
(PIXEL_CLOCK_PARAMETERS_V3 *) & args.sPCLKInput; |
spc3_ptr->usPixelClock = cpu_to_le16(sclock); |
spc3_ptr->usPixelClock = cpu_to_le16(mode->clock / 10); |
spc3_ptr->usRefDiv = cpu_to_le16(ref_div); |
spc3_ptr->usFbDiv = cpu_to_le16(fb_div); |
spc3_ptr->ucFracFbDiv = frac_fb_div; |
531,6 → 634,16 |
WREG32(AVIVO_D1VGA_CONTROL, 0); |
else |
WREG32(AVIVO_D2VGA_CONTROL, 0); |
if (rdev->family >= CHIP_RV770) { |
if (radeon_crtc->crtc_id) { |
WREG32(R700_D2GRPH_PRIMARY_SURFACE_ADDRESS_HIGH, 0); |
WREG32(R700_D2GRPH_SECONDARY_SURFACE_ADDRESS_HIGH, 0); |
} else { |
WREG32(R700_D1GRPH_PRIMARY_SURFACE_ADDRESS_HIGH, 0); |
WREG32(R700_D1GRPH_SECONDARY_SURFACE_ADDRESS_HIGH, 0); |
} |
} |
WREG32(AVIVO_D1GRPH_PRIMARY_SURFACE_ADDRESS + radeon_crtc->crtc_offset, |
(u32) fb_location); |
WREG32(AVIVO_D1GRPH_SECONDARY_SURFACE_ADDRESS + |
568,6 → 681,9 |
// radeon_gem_object_unpin(radeon_fb->obj); |
// } |
/* Bytes per pixel may have changed */ |
radeon_bandwidth_update(rdev); |
LEAVE(); |
return 0; |
581,134 → 697,24 |
struct radeon_crtc *radeon_crtc = to_radeon_crtc(crtc); |
struct drm_device *dev = crtc->dev; |
struct radeon_device *rdev = dev->dev_private; |
struct drm_encoder *encoder; |
SET_CRTC_TIMING_PARAMETERS_PS_ALLOCATION crtc_timing; |
int need_tv_timings = 0; |
bool ret; |
/* TODO color tiling */ |
memset(&crtc_timing, 0, sizeof(crtc_timing)); |
list_for_each_entry(encoder, &dev->mode_config.encoder_list, head) { |
/* find tv std */ |
if (encoder->crtc == crtc) { |
struct radeon_encoder *radeon_encoder = to_radeon_encoder(encoder); |
if (radeon_encoder->active_device & ATOM_DEVICE_TV_SUPPORT) { |
struct radeon_encoder_atom_dac *tv_dac = radeon_encoder->enc_priv; |
if (tv_dac) { |
if (tv_dac->tv_std == TV_STD_NTSC || |
tv_dac->tv_std == TV_STD_NTSC_J || |
tv_dac->tv_std == TV_STD_PAL_M) |
need_tv_timings = 1; |
else |
need_tv_timings = 2; |
break; |
} |
} |
} |
} |
crtc_timing.ucCRTC = radeon_crtc->crtc_id; |
if (need_tv_timings) { |
ret = radeon_atom_get_tv_timings(rdev, need_tv_timings - 1, |
&crtc_timing, &adjusted_mode->clock); |
if (ret == false) |
need_tv_timings = 0; |
} |
if (!need_tv_timings) { |
crtc_timing.usH_Total = adjusted_mode->crtc_htotal; |
crtc_timing.usH_Disp = adjusted_mode->crtc_hdisplay; |
crtc_timing.usH_SyncStart = adjusted_mode->crtc_hsync_start; |
crtc_timing.usH_SyncWidth = |
adjusted_mode->crtc_hsync_end - adjusted_mode->crtc_hsync_start; |
crtc_timing.usV_Total = adjusted_mode->crtc_vtotal; |
crtc_timing.usV_Disp = adjusted_mode->crtc_vdisplay; |
crtc_timing.usV_SyncStart = adjusted_mode->crtc_vsync_start; |
crtc_timing.usV_SyncWidth = |
adjusted_mode->crtc_vsync_end - adjusted_mode->crtc_vsync_start; |
if (adjusted_mode->flags & DRM_MODE_FLAG_NVSYNC) |
crtc_timing.susModeMiscInfo.usAccess |= ATOM_VSYNC_POLARITY; |
if (adjusted_mode->flags & DRM_MODE_FLAG_NHSYNC) |
crtc_timing.susModeMiscInfo.usAccess |= ATOM_HSYNC_POLARITY; |
if (adjusted_mode->flags & DRM_MODE_FLAG_CSYNC) |
crtc_timing.susModeMiscInfo.usAccess |= ATOM_COMPOSITESYNC; |
if (adjusted_mode->flags & DRM_MODE_FLAG_INTERLACE) |
crtc_timing.susModeMiscInfo.usAccess |= ATOM_INTERLACE; |
if (adjusted_mode->flags & DRM_MODE_FLAG_DBLSCAN) |
crtc_timing.susModeMiscInfo.usAccess |= ATOM_DOUBLE_CLOCK_MODE; |
} |
atombios_set_ss(crtc, 0); |
atombios_crtc_set_pll(crtc, adjusted_mode); |
atombios_crtc_set_timing(crtc, &crtc_timing); |
atombios_set_ss(crtc, 1); |
atombios_crtc_set_timing(crtc, adjusted_mode); |
if (ASIC_IS_AVIVO(rdev)) |
atombios_crtc_set_base(crtc, x, y, old_fb); |
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); |
} |
if (radeon_crtc->crtc_id == 0) |
atombios_set_crtc_dtd_timing(crtc, adjusted_mode); |
radeon_crtc_set_base(crtc, x, y, old_fb); |
radeon_legacy_atom_set_surface(crtc); |
} |
atombios_overscan_setup(crtc, mode, adjusted_mode); |
atombios_scaler_setup(crtc); |
radeon_bandwidth_update(rdev); |
return 0; |
} |
/drivers/video/drm/radeon/blit_mask_ps_1.psh |
---|
0,0 → 1,8 |
ps_1_2 |
def c1, -1.0, -1.0, -1.0, -1.0 |
tex t0 |
tex t1 |
tex t2 |
sub r0 , t0, v0 |
dp3 r1, r0, r0 |
cmp r0, -r1, t1, t2 |
/drivers/video/drm/radeon/blit_mask_ps_2.psh |
---|
0,0 → 1,20 |
ps_2_0 |
dcl_2d s0 |
dcl_2d s1 |
dcl v0 |
dcl t0 |
dcl t1 |
texld r0, t0, s0 |
sub r0.x, r0.x, v0.x |
abs r0.x, r0.x |
mov r0.xyzw, -r0.x |
texkill r0 |
texld r0, t1, s1 |
mov oC0, r0 |
/drivers/video/drm/radeon/blit_mask_ps_3.psh |
---|
0,0 → 1,21 |
ps_3_0 |
dcl_2d s0 |
dcl_2d s1 |
dcl_2d s2 |
dcl_color v1 |
dcl_texcoord0 v0.xy |
dcl_texcoord1 v0.zw |
texld r0.x, v0.xy, s0 |
sub r0.x, r0.x, v1.x |
abs r0.x, r0.x |
mov r0.xyzw, -r0.x |
texkill r0.x |
texld oC0, v0.zw, s1 |
/drivers/video/drm/radeon/makefile |
---|
72,6 → 72,7 |
radeon_fb.c \ |
rdisplay.c \ |
rdisplay_kms.c \ |
radeon_pm.c \ |
cmdline.c |
/drivers/video/drm/radeon/r100.c |
---|
192,7 → 192,7 |
int r; |
if (rdev->wb.wb_obj == NULL) { |
r = radeon_object_create(rdev, NULL, 4096, |
r = radeon_object_create(rdev, NULL, RADEON_GPU_PAGE_SIZE, |
true, |
RADEON_GEM_DOMAIN_GTT, |
false, &rdev->wb.wb_obj); |
532,19 → 532,19 |
indirect1_start = 16; |
/* cp setup */ |
WREG32(0x718, pre_write_timer | (pre_write_limit << 28)); |
WREG32(RADEON_CP_RB_CNTL, |
#ifdef __BIG_ENDIAN |
RADEON_BUF_SWAP_32BIT | |
#endif |
REG_SET(RADEON_RB_BUFSZ, rb_bufsz) | |
tmp = (REG_SET(RADEON_RB_BUFSZ, rb_bufsz) | |
REG_SET(RADEON_RB_BLKSZ, rb_blksz) | |
REG_SET(RADEON_MAX_FETCH, max_fetch) | |
RADEON_RB_NO_UPDATE); |
#ifdef __BIG_ENDIAN |
tmp |= RADEON_BUF_SWAP_32BIT; |
#endif |
WREG32(RADEON_CP_RB_CNTL, tmp); |
/* Set ring address */ |
DRM_INFO("radeon: ring at 0x%016lX\n", (unsigned long)rdev->cp.gpu_addr); |
WREG32(RADEON_CP_RB_BASE, rdev->cp.gpu_addr); |
/* Force read & write ptr to 0 */ |
tmp = RREG32(RADEON_CP_RB_CNTL); |
WREG32(RADEON_CP_RB_CNTL, tmp | RADEON_RB_RPTR_WR_ENA); |
WREG32(RADEON_CP_RB_RPTR_WR, 0); |
WREG32(RADEON_CP_RB_WPTR, 0); |
2341,7 → 2341,7 |
/* |
Find the total latency for the display data. |
*/ |
disp_latency_overhead.full = rfixed_const(80); |
disp_latency_overhead.full = rfixed_const(8); |
disp_latency_overhead.full = rfixed_div(disp_latency_overhead, sclk_ff); |
mc_latency_mclk.full += disp_latency_overhead.full + cur_latency_mclk.full; |
mc_latency_sclk.full += disp_latency_overhead.full + cur_latency_sclk.full; |
/drivers/video/drm/radeon/r300.c |
---|
113,7 → 113,7 |
tmp = RADEON_PCIE_TX_GART_UNMAPPED_ACCESS_DISCARD; |
WREG32_PCIE(RADEON_PCIE_TX_GART_CNTL, tmp); |
WREG32_PCIE(RADEON_PCIE_TX_GART_START_LO, rdev->mc.gtt_location); |
tmp = rdev->mc.gtt_location + rdev->mc.gtt_size - 4096; |
tmp = rdev->mc.gtt_location + rdev->mc.gtt_size - RADEON_GPU_PAGE_SIZE; |
WREG32_PCIE(RADEON_PCIE_TX_GART_END_LO, tmp); |
WREG32_PCIE(RADEON_PCIE_TX_GART_START_HI, 0); |
WREG32_PCIE(RADEON_PCIE_TX_GART_END_HI, 0); |
/drivers/video/drm/radeon/r420.c |
---|
278,6 → 278,8 |
} |
/* Initialize clocks */ |
radeon_get_clock_info(rdev->ddev); |
/* Initialize power management */ |
radeon_pm_init(rdev); |
/* Get vram informations */ |
r300_vram_info(rdev); |
/* Initialize memory controller (also test AGP) */ |
/drivers/video/drm/radeon/r500_reg.h |
---|
384,9 → 384,16 |
# define AVIVO_D1GRPH_TILED (1 << 20) |
# define AVIVO_D1GRPH_MACRO_ADDRESS_MODE (1 << 21) |
/* The R7xx *_HIGH surface regs are backwards; the D1 regs are in the D2 |
* block and vice versa. This applies to GRPH, CUR, etc. |
*/ |
#define AVIVO_D1GRPH_LUT_SEL 0x6108 |
#define AVIVO_D1GRPH_PRIMARY_SURFACE_ADDRESS 0x6110 |
#define R700_D1GRPH_PRIMARY_SURFACE_ADDRESS_HIGH 0x6914 |
#define R700_D2GRPH_PRIMARY_SURFACE_ADDRESS_HIGH 0x6114 |
#define AVIVO_D1GRPH_SECONDARY_SURFACE_ADDRESS 0x6118 |
#define R700_D1GRPH_SECONDARY_SURFACE_ADDRESS_HIGH 0x691c |
#define R700_D2GRPH_SECONDARY_SURFACE_ADDRESS_HIGH 0x611c |
#define AVIVO_D1GRPH_PITCH 0x6120 |
#define AVIVO_D1GRPH_SURFACE_OFFSET_X 0x6124 |
#define AVIVO_D1GRPH_SURFACE_OFFSET_Y 0x6128 |
404,6 → 411,8 |
# define AVIVO_D1CURSOR_MODE_MASK (3 << 8) |
# define AVIVO_D1CURSOR_MODE_24BPP 2 |
#define AVIVO_D1CUR_SURFACE_ADDRESS 0x6408 |
#define R700_D1CUR_SURFACE_ADDRESS_HIGH 0x6c0c |
#define R700_D2CUR_SURFACE_ADDRESS_HIGH 0x640c |
#define AVIVO_D1CUR_SIZE 0x6410 |
#define AVIVO_D1CUR_POSITION 0x6414 |
#define AVIVO_D1CUR_HOT_SPOT 0x6418 |
/drivers/video/drm/radeon/r520.c |
---|
246,6 → 246,8 |
} |
/* Initialize clocks */ |
radeon_get_clock_info(rdev->ddev); |
/* Initialize power management */ |
radeon_pm_init(rdev); |
/* Get vram informations */ |
r520_vram_info(rdev); |
/* Initialize memory controller (also test AGP) */ |
/drivers/video/drm/radeon/r600.c |
---|
338,11 → 338,10 |
{ |
fixed20_12 a; |
u32 tmp; |
int chansize; |
int chansize, numchan; |
int r; |
/* Get VRAM informations */ |
rdev->mc.vram_width = 128; |
rdev->mc.vram_is_ddr = true; |
tmp = RREG32(RAMCFG); |
if (tmp & CHANSIZE_OVERRIDE) { |
352,17 → 351,23 |
} else { |
chansize = 32; |
} |
if (rdev->family == CHIP_R600) { |
rdev->mc.vram_width = 8 * chansize; |
} else if (rdev->family == CHIP_RV670) { |
rdev->mc.vram_width = 4 * chansize; |
} else if ((rdev->family == CHIP_RV610) || |
(rdev->family == CHIP_RV620)) { |
rdev->mc.vram_width = chansize; |
} else if ((rdev->family == CHIP_RV630) || |
(rdev->family == CHIP_RV635)) { |
rdev->mc.vram_width = 2 * chansize; |
tmp = RREG32(CHMAP); |
switch ((tmp & NOOFCHAN_MASK) >> NOOFCHAN_SHIFT) { |
case 0: |
default: |
numchan = 1; |
break; |
case 1: |
numchan = 2; |
break; |
case 2: |
numchan = 4; |
break; |
case 3: |
numchan = 8; |
break; |
} |
rdev->mc.vram_width = numchan * chansize; |
/* Could aper size report 0 ? */ |
rdev->mc.aper_base = drm_get_resource_start(rdev->ddev, 0); |
rdev->mc.aper_size = drm_get_resource_len(rdev->ddev, 0); |
403,10 → 408,9 |
rdev->mc.gtt_location = rdev->mc.mc_vram_size; |
} |
} else { |
if (rdev->family == CHIP_RS780 || rdev->family == CHIP_RS880) { |
rdev->mc.gtt_size = radeon_gart_size * 1024 * 1024; |
rdev->mc.vram_location = (RREG32(MC_VM_FB_LOCATION) & |
0xFFFF) << 24; |
rdev->mc.gtt_size = radeon_gart_size * 1024 * 1024; |
tmp = rdev->mc.vram_location + rdev->mc.mc_vram_size; |
if ((0xFFFFFFFFUL - tmp) >= rdev->mc.gtt_size) { |
/* Enough place after vram */ |
427,12 → 431,7 |
} |
} |
rdev->mc.gtt_location = rdev->mc.mc_vram_size; |
} else { |
rdev->mc.vram_location = 0x00000000UL; |
rdev->mc.gtt_location = rdev->mc.mc_vram_size; |
rdev->mc.gtt_size = radeon_gart_size * 1024 * 1024; |
} |
} |
rdev->mc.vram_start = rdev->mc.vram_location; |
rdev->mc.vram_end = rdev->mc.vram_location + rdev->mc.mc_vram_size - 1; |
rdev->mc.gtt_start = rdev->mc.gtt_location; |
858,7 → 857,8 |
((rdev->family) == CHIP_RV630) || |
((rdev->family) == CHIP_RV610) || |
((rdev->family) == CHIP_RV620) || |
((rdev->family) == CHIP_RS780)) { |
((rdev->family) == CHIP_RS780) || |
((rdev->family) == CHIP_RS880)) { |
WREG32(DB_DEBUG, PREZ_MUST_WAIT_FOR_POSTZ_DONE); |
} else { |
WREG32(DB_DEBUG, 0); |
875,7 → 875,8 |
tmp = RREG32(SQ_MS_FIFO_SIZES); |
if (((rdev->family) == CHIP_RV610) || |
((rdev->family) == CHIP_RV620) || |
((rdev->family) == CHIP_RS780)) { |
((rdev->family) == CHIP_RS780) || |
((rdev->family) == CHIP_RS880)) { |
tmp = (CACHE_FIFO_SIZE(0xa) | |
FETCH_FIFO_HIWATER(0xa) | |
DONE_FIFO_HIWATER(0xe0) | |
918,7 → 919,8 |
NUM_ES_STACK_ENTRIES(0)); |
} else if (((rdev->family) == CHIP_RV610) || |
((rdev->family) == CHIP_RV620) || |
((rdev->family) == CHIP_RS780)) { |
((rdev->family) == CHIP_RS780) || |
((rdev->family) == CHIP_RS880)) { |
/* no vertex cache */ |
sq_config &= ~VC_ENABLE; |
975,7 → 977,8 |
if (((rdev->family) == CHIP_RV610) || |
((rdev->family) == CHIP_RV620) || |
((rdev->family) == CHIP_RS780)) { |
((rdev->family) == CHIP_RS780) || |
((rdev->family) == CHIP_RS880)) { |
WREG32(VGT_CACHE_INVALIDATION, CACHE_INVALIDATION(TC_ONLY)); |
} else { |
WREG32(VGT_CACHE_INVALIDATION, CACHE_INVALIDATION(VC_AND_TC)); |
1001,8 → 1004,9 |
tmp = rdev->config.r600.max_pipes * 16; |
switch (rdev->family) { |
case CHIP_RV610: |
case CHIP_RV620: |
case CHIP_RS780: |
case CHIP_RV620: |
case CHIP_RS880: |
tmp += 32; |
break; |
case CHIP_RV670: |
1043,8 → 1047,9 |
switch (rdev->family) { |
case CHIP_RV610: |
case CHIP_RV620: |
case CHIP_RS780: |
case CHIP_RV620: |
case CHIP_RS880: |
tmp = TC_L2_SIZE(8); |
break; |
case CHIP_RV630: |
1288,10 → 1293,13 |
r600_scratch_init(rdev); |
/* Initialize surface registers */ |
radeon_surface_init(rdev); |
/* Initialize clocks */ |
radeon_get_clock_info(rdev->ddev); |
r = radeon_clocks_init(rdev); |
if (r) |
return r; |
/* Initialize power management */ |
radeon_pm_init(rdev); |
/* Fence driver */ |
// r = radeon_fence_driver_init(rdev); |
// if (r) |
/drivers/video/drm/radeon/r600d.h |
---|
119,6 → 119,7 |
#define DB_DEBUG 0x9830 |
#define PREZ_MUST_WAIT_FOR_POSTZ_DONE (1 << 31) |
#define DB_DEPTH_BASE 0x2800C |
#define DB_HTILE_DATA_BASE 0x28014 |
#define DB_WATERMARKS 0x9838 |
#define DEPTH_FREE(x) ((x) << 0) |
#define DEPTH_FLUSH(x) ((x) << 5) |
171,6 → 172,14 |
#define SQ_STACK_RESOURCE_MGMT_2 0x8c14 |
# define NUM_GS_STACK_ENTRIES(x) ((x) << 0) |
# define NUM_ES_STACK_ENTRIES(x) ((x) << 16) |
#define SQ_ESGS_RING_BASE 0x8c40 |
#define SQ_GSVS_RING_BASE 0x8c48 |
#define SQ_ESTMP_RING_BASE 0x8c50 |
#define SQ_GSTMP_RING_BASE 0x8c58 |
#define SQ_VSTMP_RING_BASE 0x8c60 |
#define SQ_PSTMP_RING_BASE 0x8c68 |
#define SQ_FBUF_RING_BASE 0x8c70 |
#define SQ_REDUC_RING_BASE 0x8c78 |
#define GRBM_CNTL 0x8000 |
# define GRBM_READ_TIMEOUT(x) ((x) << 0) |
271,6 → 280,10 |
#define PCIE_PORT_INDEX 0x0038 |
#define PCIE_PORT_DATA 0x003C |
#define CHMAP 0x2004 |
#define NOOFCHAN_SHIFT 12 |
#define NOOFCHAN_MASK 0x00003000 |
#define RAMCFG 0x2408 |
#define NOOFBANK_SHIFT 0 |
#define NOOFBANK_MASK 0x00000001 |
352,6 → 365,7 |
#define SX_MISC 0x28350 |
#define SX_MEMORY_EXPORT_BASE 0x9010 |
#define SX_DEBUG_1 0x9054 |
#define SMX_EVENT_RELEASE (1 << 0) |
#define ENABLE_NEW_SMX_ADDRESS (1 << 16) |
/drivers/video/drm/radeon/radeon.h |
---|
202,6 → 202,10 |
uint32_t default_sclk; |
}; |
/* |
* Power management |
*/ |
int radeon_pm_init(struct radeon_device *rdev); |
/* |
* Fences. |
313,6 → 317,8 |
struct radeon_gart_table_vram vram; |
}; |
#define RADEON_GPU_PAGE_SIZE 4096 |
struct radeon_gart { |
dma_addr_t table_addr; |
unsigned num_gpu_pages; |
634,7 → 640,9 |
uint64_t dst_offset, |
unsigned num_pages, |
struct radeon_fence *fence); |
uint32_t (*get_engine_clock)(struct radeon_device *rdev); |
void (*set_engine_clock)(struct radeon_device *rdev, uint32_t eng_clock); |
uint32_t (*get_memory_clock)(struct radeon_device *rdev); |
void (*set_memory_clock)(struct radeon_device *rdev, uint32_t mem_clock); |
void (*set_pcie_lanes)(struct radeon_device *rdev, int lanes); |
void (*set_clock_gating)(struct radeon_device *rdev, int enable); |
772,6 → 780,7 |
const struct firmware *me_fw; /* all family ME firmware */ |
const struct firmware *pfp_fw; /* r6/700 PFP firmware */ |
struct r600_blit r600_blit; |
int msi_enabled; /* msi enabled */ |
}; |
int radeon_device_init(struct radeon_device *rdev, |
939,7 → 948,9 |
#define radeon_copy_blit(rdev, s, d, np, f) (rdev)->asic->copy_blit((rdev), (s), (d), (np), (f)) |
#define radeon_copy_dma(rdev, s, d, np, f) (rdev)->asic->copy_dma((rdev), (s), (d), (np), (f)) |
#define radeon_copy(rdev, s, d, np, f) (rdev)->asic->copy((rdev), (s), (d), (np), (f)) |
#define radeon_get_engine_clock(rdev) (rdev)->asic->get_engine_clock((rdev)) |
#define radeon_set_engine_clock(rdev, e) (rdev)->asic->set_engine_clock((rdev), (e)) |
#define radeon_get_memory_clock(rdev) (rdev)->asic->get_memory_clock((rdev)) |
#define radeon_set_memory_clock(rdev, e) (rdev)->asic->set_engine_clock((rdev), (e)) |
#define radeon_set_pcie_lanes(rdev, l) (rdev)->asic->set_pcie_lanes((rdev), (l)) |
#define radeon_set_clock_gating(rdev, e) (rdev)->asic->set_clock_gating((rdev), (e)) |
/drivers/video/drm/radeon/radeon_asic.h |
---|
31,10 → 31,13 |
/* |
* common functions |
*/ |
uint32_t radeon_legacy_get_engine_clock(struct radeon_device *rdev); |
void radeon_legacy_set_engine_clock(struct radeon_device *rdev, uint32_t eng_clock); |
void radeon_legacy_set_clock_gating(struct radeon_device *rdev, int enable); |
uint32_t radeon_atom_get_engine_clock(struct radeon_device *rdev); |
void radeon_atom_set_engine_clock(struct radeon_device *rdev, uint32_t eng_clock); |
uint32_t radeon_atom_get_memory_clock(struct radeon_device *rdev); |
void radeon_atom_set_memory_clock(struct radeon_device *rdev, uint32_t mem_clock); |
void radeon_atom_set_clock_gating(struct radeon_device *rdev, int enable); |
95,7 → 98,9 |
// .copy_blit = &r100_copy_blit, |
// .copy_dma = NULL, |
// .copy = &r100_copy_blit, |
.get_engine_clock = &radeon_legacy_get_engine_clock, |
.set_engine_clock = &radeon_legacy_set_engine_clock, |
.get_memory_clock = NULL, |
.set_memory_clock = NULL, |
.set_pcie_lanes = NULL, |
.set_clock_gating = &radeon_legacy_set_clock_gating, |
148,7 → 153,9 |
// .copy_blit = &r100_copy_blit, |
// .copy_dma = &r300_copy_dma, |
// .copy = &r100_copy_blit, |
.get_engine_clock = &radeon_legacy_get_engine_clock, |
.set_engine_clock = &radeon_legacy_set_engine_clock, |
.get_memory_clock = NULL, |
.set_memory_clock = NULL, |
.set_pcie_lanes = &rv370_set_pcie_lanes, |
.set_clock_gating = &radeon_legacy_set_clock_gating, |
185,7 → 192,9 |
// .copy_blit = &r100_copy_blit, |
// .copy_dma = &r300_copy_dma, |
// .copy = &r100_copy_blit, |
.get_engine_clock = &radeon_atom_get_engine_clock, |
.set_engine_clock = &radeon_atom_set_engine_clock, |
.get_memory_clock = &radeon_atom_get_memory_clock, |
.set_memory_clock = &radeon_atom_set_memory_clock, |
.set_pcie_lanes = &rv370_set_pcie_lanes, |
.set_clock_gating = &radeon_atom_set_clock_gating, |
227,7 → 236,9 |
// .copy_blit = &r100_copy_blit, |
// .copy_dma = &r300_copy_dma, |
// .copy = &r100_copy_blit, |
.get_engine_clock = &radeon_legacy_get_engine_clock, |
.set_engine_clock = &radeon_legacy_set_engine_clock, |
.get_memory_clock = NULL, |
.set_memory_clock = NULL, |
.set_pcie_lanes = NULL, |
.set_clock_gating = &radeon_legacy_set_clock_gating, |
273,7 → 284,9 |
// .copy_blit = &r100_copy_blit, |
// .copy_dma = &r300_copy_dma, |
// .copy = &r100_copy_blit, |
.get_engine_clock = &radeon_atom_get_engine_clock, |
.set_engine_clock = &radeon_atom_set_engine_clock, |
.get_memory_clock = &radeon_atom_get_memory_clock, |
.set_memory_clock = &radeon_atom_set_memory_clock, |
.set_pcie_lanes = NULL, |
.set_clock_gating = &radeon_atom_set_clock_gating, |
312,7 → 325,9 |
// .copy_blit = &r100_copy_blit, |
// .copy_dma = &r300_copy_dma, |
// .copy = &r300_copy_dma, |
.get_engine_clock = &radeon_atom_get_engine_clock, |
.set_engine_clock = &radeon_atom_set_engine_clock, |
.get_memory_clock = &radeon_atom_get_memory_clock, |
.set_memory_clock = &radeon_atom_set_memory_clock, |
.set_pcie_lanes = NULL, |
.set_clock_gating = &radeon_atom_set_clock_gating, |
357,7 → 372,9 |
// .copy_blit = &r100_copy_blit, |
// .copy_dma = &r300_copy_dma, |
// .copy = &r100_copy_blit, |
.get_engine_clock = &radeon_atom_get_engine_clock, |
.set_engine_clock = &radeon_atom_set_engine_clock, |
.get_memory_clock = &radeon_atom_get_memory_clock, |
.set_memory_clock = &radeon_atom_set_memory_clock, |
.set_pcie_lanes = &rv370_set_pcie_lanes, |
.set_clock_gating = &radeon_atom_set_clock_gating, |
393,7 → 410,9 |
// .copy_blit = &r100_copy_blit, |
// .copy_dma = &r300_copy_dma, |
// .copy = &r100_copy_blit, |
.get_engine_clock = &radeon_atom_get_engine_clock, |
.set_engine_clock = &radeon_atom_set_engine_clock, |
.get_memory_clock = &radeon_atom_get_memory_clock, |
.set_memory_clock = &radeon_atom_set_memory_clock, |
.set_pcie_lanes = &rv370_set_pcie_lanes, |
.set_clock_gating = &radeon_atom_set_clock_gating, |
456,7 → 475,9 |
// .copy_blit = &r600_copy_blit, |
// .copy_dma = &r600_copy_blit, |
// .copy = &r600_copy_blit, |
.get_engine_clock = &radeon_atom_get_engine_clock, |
.set_engine_clock = &radeon_atom_set_engine_clock, |
.get_memory_clock = &radeon_atom_get_memory_clock, |
.set_memory_clock = &radeon_atom_set_memory_clock, |
.set_pcie_lanes = NULL, |
.set_clock_gating = &radeon_atom_set_clock_gating, |
493,7 → 514,9 |
// .copy_blit = &r600_copy_blit, |
// .copy_dma = &r600_copy_blit, |
// .copy = &r600_copy_blit, |
.get_engine_clock = &radeon_atom_get_engine_clock, |
.set_engine_clock = &radeon_atom_set_engine_clock, |
.get_memory_clock = &radeon_atom_get_memory_clock, |
.set_memory_clock = &radeon_atom_set_memory_clock, |
.set_pcie_lanes = NULL, |
.set_clock_gating = &radeon_atom_set_clock_gating, |
/drivers/video/drm/radeon/radeon_atombios.c |
---|
46,7 → 46,8 |
uint32_t supported_device, |
int connector_type, |
struct radeon_i2c_bus_rec *i2c_bus, |
bool linkb, uint32_t igp_lane_info); |
bool linkb, uint32_t igp_lane_info, |
uint16_t connector_object_id); |
/* from radeon_legacy_encoder.c */ |
extern void |
193,6 → 194,23 |
DRM_MODE_CONNECTOR_DisplayPort |
}; |
const uint16_t supported_devices_connector_object_id_convert[] = { |
CONNECTOR_OBJECT_ID_NONE, |
CONNECTOR_OBJECT_ID_VGA, |
CONNECTOR_OBJECT_ID_DUAL_LINK_DVI_I, /* not all boards support DL */ |
CONNECTOR_OBJECT_ID_DUAL_LINK_DVI_D, /* not all boards support DL */ |
CONNECTOR_OBJECT_ID_VGA, /* technically DVI-A */ |
CONNECTOR_OBJECT_ID_COMPOSITE, |
CONNECTOR_OBJECT_ID_SVIDEO, |
CONNECTOR_OBJECT_ID_LVDS, |
CONNECTOR_OBJECT_ID_9PIN_DIN, |
CONNECTOR_OBJECT_ID_9PIN_DIN, |
CONNECTOR_OBJECT_ID_DISPLAYPORT, |
CONNECTOR_OBJECT_ID_HDMI_TYPE_A, |
CONNECTOR_OBJECT_ID_HDMI_TYPE_B, |
CONNECTOR_OBJECT_ID_SVIDEO |
}; |
const int object_connector_convert[] = { |
DRM_MODE_CONNECTOR_Unknown, |
DRM_MODE_CONNECTOR_DVII, |
229,7 → 247,7 |
ATOM_OBJECT_HEADER *obj_header; |
int i, j, path_size, device_support; |
int connector_type; |
uint16_t igp_lane_info, conn_id; |
uint16_t igp_lane_info, conn_id, connector_object_id; |
bool linkb; |
struct radeon_i2c_bus_rec ddc_bus; |
277,7 → 295,8 |
ATOM_DEVICE_CV_SUPPORT) |
continue; |
if ((rdev->family == CHIP_RS780) && |
/* IGP chips */ |
if ((rdev->flags & RADEON_IS_IGP) && |
(con_obj_id == |
CONNECTOR_OBJECT_ID_PCIE_CONNECTOR)) { |
uint16_t igp_offset = 0; |
311,6 → 330,7 |
connector_type = |
object_connector_convert |
[ct]; |
connector_object_id = ct; |
igp_lane_info = |
slot_config & 0xffff; |
} else |
321,6 → 341,7 |
igp_lane_info = 0; |
connector_type = |
object_connector_convert[con_obj_id]; |
connector_object_id = con_obj_id; |
} |
if (connector_type == DRM_MODE_CONNECTOR_Unknown) |
425,7 → 446,8 |
le16_to_cpu(path-> |
usDeviceTag), |
connector_type, &ddc_bus, |
linkb, igp_lane_info); |
linkb, igp_lane_info, |
connector_object_id); |
} |
} |
435,6 → 457,45 |
return true; |
} |
static uint16_t atombios_get_connector_object_id(struct drm_device *dev, |
int connector_type, |
uint16_t devices) |
{ |
struct radeon_device *rdev = dev->dev_private; |
if (rdev->flags & RADEON_IS_IGP) { |
return supported_devices_connector_object_id_convert |
[connector_type]; |
} else if (((connector_type == DRM_MODE_CONNECTOR_DVII) || |
(connector_type == DRM_MODE_CONNECTOR_DVID)) && |
(devices & ATOM_DEVICE_DFP2_SUPPORT)) { |
struct radeon_mode_info *mode_info = &rdev->mode_info; |
struct atom_context *ctx = mode_info->atom_context; |
int index = GetIndexIntoMasterTable(DATA, XTMDS_Info); |
uint16_t size, data_offset; |
uint8_t frev, crev; |
ATOM_XTMDS_INFO *xtmds; |
atom_parse_data_header(ctx, index, &size, &frev, &crev, &data_offset); |
xtmds = (ATOM_XTMDS_INFO *)(ctx->bios + data_offset); |
if (xtmds->ucSupportedLink & ATOM_XTMDS_SUPPORTED_DUALLINK) { |
if (connector_type == DRM_MODE_CONNECTOR_DVII) |
return CONNECTOR_OBJECT_ID_DUAL_LINK_DVI_I; |
else |
return CONNECTOR_OBJECT_ID_DUAL_LINK_DVI_D; |
} else { |
if (connector_type == DRM_MODE_CONNECTOR_DVII) |
return CONNECTOR_OBJECT_ID_SINGLE_LINK_DVI_I; |
else |
return CONNECTOR_OBJECT_ID_SINGLE_LINK_DVI_D; |
} |
} else { |
return supported_devices_connector_object_id_convert |
[connector_type]; |
} |
} |
struct bios_connector { |
bool valid; |
uint16_t line_mux; |
593,7 → 654,11 |
/* add the connectors */ |
for (i = 0; i < ATOM_MAX_SUPPORTED_DEVICE; i++) { |
if (bios_connectors[i].valid) |
if (bios_connectors[i].valid) { |
uint16_t connector_object_id = |
atombios_get_connector_object_id(dev, |
bios_connectors[i].connector_type, |
bios_connectors[i].devices); |
radeon_add_atom_connector(dev, |
bios_connectors[i].line_mux, |
bios_connectors[i].devices, |
600,8 → 665,10 |
bios_connectors[i]. |
connector_type, |
&bios_connectors[i].ddc_bus, |
false, 0); |
false, 0, |
connector_object_id); |
} |
} |
radeon_link_encoder_connector(dev); |
641,8 → 708,12 |
le16_to_cpu(firmware_info->info.usReferenceClock); |
p1pll->reference_div = 0; |
if (crev < 2) |
p1pll->pll_out_min = |
le16_to_cpu(firmware_info->info.usMinPixelClockPLL_Output); |
else |
p1pll->pll_out_min = |
le32_to_cpu(firmware_info->info_12.ulMinPixelClockPLL_Output); |
p1pll->pll_out_max = |
le32_to_cpu(firmware_info->info.ulMaxPixelClockPLL_Output); |
651,6 → 722,16 |
p1pll->pll_out_min = 64800; |
else |
p1pll->pll_out_min = 20000; |
} else if (p1pll->pll_out_min > 64800) { |
/* Limiting the pll output range is a good thing generally as |
* it limits the number of possible pll combinations for a given |
* frequency presumably to the ones that work best on each card. |
* However, certain duallink DVI monitors seem to like |
* pll combinations that would be limited by this at least on |
* pre-DCE 3.0 r6xx hardware. This might need to be adjusted per |
* family. |
*/ |
p1pll->pll_out_min = 64800; |
} |
p1pll->pll_in_min = |
767,6 → 848,46 |
return false; |
} |
static struct radeon_atom_ss *radeon_atombios_get_ss_info(struct |
radeon_encoder |
*encoder, |
int id) |
{ |
struct drm_device *dev = encoder->base.dev; |
struct radeon_device *rdev = dev->dev_private; |
struct radeon_mode_info *mode_info = &rdev->mode_info; |
int index = GetIndexIntoMasterTable(DATA, PPLL_SS_Info); |
uint16_t data_offset; |
struct _ATOM_SPREAD_SPECTRUM_INFO *ss_info; |
uint8_t frev, crev; |
struct radeon_atom_ss *ss = NULL; |
if (id > ATOM_MAX_SS_ENTRY) |
return NULL; |
atom_parse_data_header(mode_info->atom_context, index, NULL, &frev, |
&crev, &data_offset); |
ss_info = |
(struct _ATOM_SPREAD_SPECTRUM_INFO *)(mode_info->atom_context->bios + data_offset); |
if (ss_info) { |
ss = |
kzalloc(sizeof(struct radeon_atom_ss), GFP_KERNEL); |
if (!ss) |
return NULL; |
ss->percentage = le16_to_cpu(ss_info->asSS_Info[id].usSpreadSpectrumPercentage); |
ss->type = ss_info->asSS_Info[id].ucSpreadSpectrumType; |
ss->step = ss_info->asSS_Info[id].ucSS_Step; |
ss->delay = ss_info->asSS_Info[id].ucSS_Delay; |
ss->range = ss_info->asSS_Info[id].ucSS_Range; |
ss->refdiv = ss_info->asSS_Info[id].ucRecommendedRef_Div; |
} |
return ss; |
} |
union lvds_info { |
struct _ATOM_LVDS_INFO info; |
struct _ATOM_LVDS_INFO_V12 info_12; |
798,28 → 919,32 |
if (!lvds) |
return NULL; |
lvds->native_mode.dotclock = |
lvds->native_mode.clock = |
le16_to_cpu(lvds_info->info.sLCDTiming.usPixClk) * 10; |
lvds->native_mode.panel_xres = |
lvds->native_mode.hdisplay = |
le16_to_cpu(lvds_info->info.sLCDTiming.usHActive); |
lvds->native_mode.panel_yres = |
lvds->native_mode.vdisplay = |
le16_to_cpu(lvds_info->info.sLCDTiming.usVActive); |
lvds->native_mode.hblank = |
lvds->native_mode.htotal = lvds->native_mode.hdisplay + |
le16_to_cpu(lvds_info->info.sLCDTiming.usHBlanking_Time); |
lvds->native_mode.hoverplus = |
lvds->native_mode.hsync_start = lvds->native_mode.hdisplay + |
le16_to_cpu(lvds_info->info.sLCDTiming.usHSyncOffset); |
lvds->native_mode.hsync_width = |
lvds->native_mode.hsync_end = lvds->native_mode.hsync_start + |
le16_to_cpu(lvds_info->info.sLCDTiming.usHSyncWidth); |
lvds->native_mode.vblank = |
lvds->native_mode.vtotal = lvds->native_mode.vdisplay + |
le16_to_cpu(lvds_info->info.sLCDTiming.usVBlanking_Time); |
lvds->native_mode.voverplus = |
le16_to_cpu(lvds_info->info.sLCDTiming.usVSyncOffset); |
lvds->native_mode.vsync_width = |
lvds->native_mode.vsync_start = lvds->native_mode.vdisplay + |
le16_to_cpu(lvds_info->info.sLCDTiming.usVSyncWidth); |
lvds->native_mode.vsync_end = lvds->native_mode.vsync_start + |
le16_to_cpu(lvds_info->info.sLCDTiming.usVSyncWidth); |
lvds->panel_pwr_delay = |
le16_to_cpu(lvds_info->info.usOffDelayInMs); |
lvds->lvds_misc = lvds_info->info.ucLVDS_Misc; |
/* set crtc values */ |
drm_mode_set_crtcinfo(&lvds->native_mode, CRTC_INTERLACE_HALVE_V); |
lvds->ss = radeon_atombios_get_ss_info(encoder, lvds_info->info.ucSS_Id); |
encoder->native_mode = lvds->native_mode; |
} |
return lvds; |
857,8 → 982,7 |
} |
bool radeon_atom_get_tv_timings(struct radeon_device *rdev, int index, |
SET_CRTC_TIMING_PARAMETERS_PS_ALLOCATION *crtc_timing, |
int32_t *pixel_clock) |
struct drm_display_mode *mode) |
{ |
struct radeon_mode_info *mode_info = &rdev->mode_info; |
ATOM_ANALOG_TV_INFO *tv_info; |
866,7 → 990,7 |
ATOM_DTD_FORMAT *dtd_timings; |
int data_index = GetIndexIntoMasterTable(DATA, AnalogTV_Info); |
u8 frev, crev; |
uint16_t data_offset; |
u16 data_offset, misc; |
atom_parse_data_header(mode_info->atom_context, data_index, NULL, &frev, &crev, &data_offset); |
876,28 → 1000,37 |
if (index > MAX_SUPPORTED_TV_TIMING) |
return false; |
crtc_timing->usH_Total = le16_to_cpu(tv_info->aModeTimings[index].usCRTC_H_Total); |
crtc_timing->usH_Disp = le16_to_cpu(tv_info->aModeTimings[index].usCRTC_H_Disp); |
crtc_timing->usH_SyncStart = le16_to_cpu(tv_info->aModeTimings[index].usCRTC_H_SyncStart); |
crtc_timing->usH_SyncWidth = le16_to_cpu(tv_info->aModeTimings[index].usCRTC_H_SyncWidth); |
mode->crtc_htotal = le16_to_cpu(tv_info->aModeTimings[index].usCRTC_H_Total); |
mode->crtc_hdisplay = le16_to_cpu(tv_info->aModeTimings[index].usCRTC_H_Disp); |
mode->crtc_hsync_start = le16_to_cpu(tv_info->aModeTimings[index].usCRTC_H_SyncStart); |
mode->crtc_hsync_end = le16_to_cpu(tv_info->aModeTimings[index].usCRTC_H_SyncStart) + |
le16_to_cpu(tv_info->aModeTimings[index].usCRTC_H_SyncWidth); |
crtc_timing->usV_Total = le16_to_cpu(tv_info->aModeTimings[index].usCRTC_V_Total); |
crtc_timing->usV_Disp = le16_to_cpu(tv_info->aModeTimings[index].usCRTC_V_Disp); |
crtc_timing->usV_SyncStart = le16_to_cpu(tv_info->aModeTimings[index].usCRTC_V_SyncStart); |
crtc_timing->usV_SyncWidth = le16_to_cpu(tv_info->aModeTimings[index].usCRTC_V_SyncWidth); |
mode->crtc_vtotal = le16_to_cpu(tv_info->aModeTimings[index].usCRTC_V_Total); |
mode->crtc_vdisplay = le16_to_cpu(tv_info->aModeTimings[index].usCRTC_V_Disp); |
mode->crtc_vsync_start = le16_to_cpu(tv_info->aModeTimings[index].usCRTC_V_SyncStart); |
mode->crtc_vsync_end = le16_to_cpu(tv_info->aModeTimings[index].usCRTC_V_SyncStart) + |
le16_to_cpu(tv_info->aModeTimings[index].usCRTC_V_SyncWidth); |
crtc_timing->susModeMiscInfo = tv_info->aModeTimings[index].susModeMiscInfo; |
mode->flags = 0; |
misc = le16_to_cpu(tv_info->aModeTimings[index].susModeMiscInfo.usAccess); |
if (misc & ATOM_VSYNC_POLARITY) |
mode->flags |= DRM_MODE_FLAG_NVSYNC; |
if (misc & ATOM_HSYNC_POLARITY) |
mode->flags |= DRM_MODE_FLAG_NHSYNC; |
if (misc & ATOM_COMPOSITESYNC) |
mode->flags |= DRM_MODE_FLAG_CSYNC; |
if (misc & ATOM_INTERLACE) |
mode->flags |= DRM_MODE_FLAG_INTERLACE; |
if (misc & ATOM_DOUBLE_CLOCK_MODE) |
mode->flags |= DRM_MODE_FLAG_DBLSCAN; |
crtc_timing->ucOverscanRight = le16_to_cpu(tv_info->aModeTimings[index].usCRTC_OverscanRight); |
crtc_timing->ucOverscanLeft = le16_to_cpu(tv_info->aModeTimings[index].usCRTC_OverscanLeft); |
crtc_timing->ucOverscanBottom = le16_to_cpu(tv_info->aModeTimings[index].usCRTC_OverscanBottom); |
crtc_timing->ucOverscanTop = le16_to_cpu(tv_info->aModeTimings[index].usCRTC_OverscanTop); |
*pixel_clock = le16_to_cpu(tv_info->aModeTimings[index].usPixelClock) * 10; |
mode->clock = le16_to_cpu(tv_info->aModeTimings[index].usPixelClock) * 10; |
if (index == 1) { |
/* PAL timings appear to have wrong values for totals */ |
crtc_timing->usH_Total -= 1; |
crtc_timing->usV_Total -= 1; |
mode->crtc_htotal -= 1; |
mode->crtc_vtotal -= 1; |
} |
break; |
case 2: |
906,17 → 1039,36 |
return false; |
dtd_timings = &tv_info_v1_2->aModeTimings[index]; |
crtc_timing->usH_Total = le16_to_cpu(dtd_timings->usHActive) + le16_to_cpu(dtd_timings->usHBlanking_Time); |
crtc_timing->usH_Disp = le16_to_cpu(dtd_timings->usHActive); |
crtc_timing->usH_SyncStart = le16_to_cpu(dtd_timings->usHActive) + le16_to_cpu(dtd_timings->usHSyncOffset); |
crtc_timing->usH_SyncWidth = le16_to_cpu(dtd_timings->usHSyncWidth); |
crtc_timing->usV_Total = le16_to_cpu(dtd_timings->usVActive) + le16_to_cpu(dtd_timings->usVBlanking_Time); |
crtc_timing->usV_Disp = le16_to_cpu(dtd_timings->usVActive); |
crtc_timing->usV_SyncStart = le16_to_cpu(dtd_timings->usVActive) + le16_to_cpu(dtd_timings->usVSyncOffset); |
crtc_timing->usV_SyncWidth = le16_to_cpu(dtd_timings->usVSyncWidth); |
mode->crtc_htotal = le16_to_cpu(dtd_timings->usHActive) + |
le16_to_cpu(dtd_timings->usHBlanking_Time); |
mode->crtc_hdisplay = le16_to_cpu(dtd_timings->usHActive); |
mode->crtc_hsync_start = le16_to_cpu(dtd_timings->usHActive) + |
le16_to_cpu(dtd_timings->usHSyncOffset); |
mode->crtc_hsync_end = mode->crtc_hsync_start + |
le16_to_cpu(dtd_timings->usHSyncWidth); |
crtc_timing->susModeMiscInfo.usAccess = le16_to_cpu(dtd_timings->susModeMiscInfo.usAccess); |
*pixel_clock = le16_to_cpu(dtd_timings->usPixClk) * 10; |
mode->crtc_vtotal = le16_to_cpu(dtd_timings->usVActive) + |
le16_to_cpu(dtd_timings->usVBlanking_Time); |
mode->crtc_vdisplay = le16_to_cpu(dtd_timings->usVActive); |
mode->crtc_vsync_start = le16_to_cpu(dtd_timings->usVActive) + |
le16_to_cpu(dtd_timings->usVSyncOffset); |
mode->crtc_vsync_end = mode->crtc_vsync_start + |
le16_to_cpu(dtd_timings->usVSyncWidth); |
mode->flags = 0; |
misc = le16_to_cpu(dtd_timings->susModeMiscInfo.usAccess); |
if (misc & ATOM_VSYNC_POLARITY) |
mode->flags |= DRM_MODE_FLAG_NVSYNC; |
if (misc & ATOM_HSYNC_POLARITY) |
mode->flags |= DRM_MODE_FLAG_NHSYNC; |
if (misc & ATOM_COMPOSITESYNC) |
mode->flags |= DRM_MODE_FLAG_CSYNC; |
if (misc & ATOM_INTERLACE) |
mode->flags |= DRM_MODE_FLAG_INTERLACE; |
if (misc & ATOM_DOUBLE_CLOCK_MODE) |
mode->flags |= DRM_MODE_FLAG_DBLSCAN; |
mode->clock = le16_to_cpu(dtd_timings->usPixClk) * 10; |
break; |
} |
return true; |
981,6 → 1133,24 |
atom_execute_table(rdev->mode_info.atom_context, index, (uint32_t *)&args); |
} |
uint32_t radeon_atom_get_engine_clock(struct radeon_device *rdev) |
{ |
GET_ENGINE_CLOCK_PS_ALLOCATION args; |
int index = GetIndexIntoMasterTable(COMMAND, GetEngineClock); |
atom_execute_table(rdev->mode_info.atom_context, index, (uint32_t *)&args); |
return args.ulReturnEngineClock; |
} |
uint32_t radeon_atom_get_memory_clock(struct radeon_device *rdev) |
{ |
GET_MEMORY_CLOCK_PS_ALLOCATION args; |
int index = GetIndexIntoMasterTable(COMMAND, GetMemoryClock); |
atom_execute_table(rdev->mode_info.atom_context, index, (uint32_t *)&args); |
return args.ulReturnMemoryClock; |
} |
void radeon_atom_set_engine_clock(struct radeon_device *rdev, |
uint32_t eng_clock) |
{ |
/drivers/video/drm/radeon/radeon_bios.c |
---|
50,19 → 50,16 |
vram_base = drm_get_resource_start(rdev->ddev, 0); |
bios = ioremap(vram_base, size); |
if (!bios) { |
DRM_ERROR("Unable to mmap vram\n"); |
return false; |
} |
if (size == 0 || bios[0] != 0x55 || bios[1] != 0xaa) { |
iounmap(bios); |
DRM_ERROR("bad rom signature\n"); |
return false; |
} |
rdev->bios = kmalloc(size, GFP_KERNEL); |
if (rdev->bios == NULL) { |
iounmap(bios); |
DRM_ERROR("kmalloc failed\n"); |
return false; |
} |
memcpy(rdev->bios, bios, size); |
/drivers/video/drm/radeon/radeon_clocks.c |
---|
32,7 → 32,7 |
#include "atom.h" |
/* 10 khz */ |
static uint32_t radeon_legacy_get_engine_clock(struct radeon_device *rdev) |
uint32_t radeon_legacy_get_engine_clock(struct radeon_device *rdev) |
{ |
struct radeon_pll *spll = &rdev->clock.spll; |
uint32_t fb_div, ref_div, post_div, sclk; |
/drivers/video/drm/radeon/radeon_combios.c |
---|
49,7 → 49,8 |
uint32_t connector_id, |
uint32_t supported_device, |
int connector_type, |
struct radeon_i2c_bus_rec *i2c_bus); |
struct radeon_i2c_bus_rec *i2c_bus, |
uint16_t connector_object_id); |
/* from radeon_legacy_encoder.c */ |
extern void |
808,25 → 809,25 |
lvds->panel_blon_delay = (lvds_ss_gen_cntl >> RADEON_LVDS_PWRSEQ_DELAY2_SHIFT) & 0xf; |
if (fp_vert_stretch & RADEON_VERT_STRETCH_ENABLE) |
lvds->native_mode.panel_yres = |
lvds->native_mode.vdisplay = |
((fp_vert_stretch & RADEON_VERT_PANEL_SIZE) >> |
RADEON_VERT_PANEL_SHIFT) + 1; |
else |
lvds->native_mode.panel_yres = |
lvds->native_mode.vdisplay = |
(RREG32(RADEON_CRTC_V_TOTAL_DISP) >> 16) + 1; |
if (fp_horz_stretch & RADEON_HORZ_STRETCH_ENABLE) |
lvds->native_mode.panel_xres = |
lvds->native_mode.hdisplay = |
(((fp_horz_stretch & RADEON_HORZ_PANEL_SIZE) >> |
RADEON_HORZ_PANEL_SHIFT) + 1) * 8; |
else |
lvds->native_mode.panel_xres = |
lvds->native_mode.hdisplay = |
((RREG32(RADEON_CRTC_H_TOTAL_DISP) >> 16) + 1) * 8; |
if ((lvds->native_mode.panel_xres < 640) || |
(lvds->native_mode.panel_yres < 480)) { |
lvds->native_mode.panel_xres = 640; |
lvds->native_mode.panel_yres = 480; |
if ((lvds->native_mode.hdisplay < 640) || |
(lvds->native_mode.vdisplay < 480)) { |
lvds->native_mode.hdisplay = 640; |
lvds->native_mode.vdisplay = 480; |
} |
ppll_div_sel = RREG8(RADEON_CLOCK_CNTL_INDEX + 1) & 0x3; |
846,8 → 847,8 |
lvds->panel_vcc_delay = 200; |
DRM_INFO("Panel info derived from registers\n"); |
DRM_INFO("Panel Size %dx%d\n", lvds->native_mode.panel_xres, |
lvds->native_mode.panel_yres); |
DRM_INFO("Panel Size %dx%d\n", lvds->native_mode.hdisplay, |
lvds->native_mode.vdisplay); |
return lvds; |
} |
882,11 → 883,11 |
DRM_INFO("Panel ID String: %s\n", stmp); |
lvds->native_mode.panel_xres = RBIOS16(lcd_info + 0x19); |
lvds->native_mode.panel_yres = RBIOS16(lcd_info + 0x1b); |
lvds->native_mode.hdisplay = RBIOS16(lcd_info + 0x19); |
lvds->native_mode.vdisplay = RBIOS16(lcd_info + 0x1b); |
DRM_INFO("Panel Size %dx%d\n", lvds->native_mode.panel_xres, |
lvds->native_mode.panel_yres); |
DRM_INFO("Panel Size %dx%d\n", lvds->native_mode.hdisplay, |
lvds->native_mode.vdisplay); |
lvds->panel_vcc_delay = RBIOS16(lcd_info + 0x2c); |
if (lvds->panel_vcc_delay > 2000 || lvds->panel_vcc_delay < 0) |
944,27 → 945,25 |
if (tmp == 0) |
break; |
if ((RBIOS16(tmp) == lvds->native_mode.panel_xres) && |
if ((RBIOS16(tmp) == lvds->native_mode.hdisplay) && |
(RBIOS16(tmp + 2) == |
lvds->native_mode.panel_yres)) { |
lvds->native_mode.hblank = |
(RBIOS16(tmp + 17) - RBIOS16(tmp + 19)) * 8; |
lvds->native_mode.hoverplus = |
(RBIOS16(tmp + 21) - RBIOS16(tmp + 19) - |
1) * 8; |
lvds->native_mode.hsync_width = |
RBIOS8(tmp + 23) * 8; |
lvds->native_mode.vdisplay)) { |
lvds->native_mode.htotal = RBIOS16(tmp + 17) * 8; |
lvds->native_mode.hsync_start = RBIOS16(tmp + 21) * 8; |
lvds->native_mode.hsync_end = (RBIOS8(tmp + 23) + |
RBIOS16(tmp + 21)) * 8; |
lvds->native_mode.vblank = (RBIOS16(tmp + 24) - |
RBIOS16(tmp + 26)); |
lvds->native_mode.voverplus = |
((RBIOS16(tmp + 28) & 0x7ff) - |
RBIOS16(tmp + 26)); |
lvds->native_mode.vsync_width = |
((RBIOS16(tmp + 28) & 0xf800) >> 11); |
lvds->native_mode.dotclock = |
RBIOS16(tmp + 9) * 10; |
lvds->native_mode.vtotal = RBIOS16(tmp + 24); |
lvds->native_mode.vsync_start = RBIOS16(tmp + 28) & 0x7ff; |
lvds->native_mode.vsync_end = |
((RBIOS16(tmp + 28) & 0xf800) >> 11) + |
(RBIOS16(tmp + 28) & 0x7ff); |
lvds->native_mode.clock = RBIOS16(tmp + 9) * 10; |
lvds->native_mode.flags = 0; |
/* set crtc values */ |
drm_mode_set_crtcinfo(&lvds->native_mode, CRTC_INTERLACE_HALVE_V); |
} |
} |
} else { |
1178,7 → 1177,8 |
radeon_add_legacy_connector(dev, 0, |
ATOM_DEVICE_CRT1_SUPPORT, |
DRM_MODE_CONNECTOR_VGA, |
&ddc_i2c); |
&ddc_i2c, |
CONNECTOR_OBJECT_ID_VGA); |
} else if (rdev->flags & RADEON_IS_MOBILITY) { |
/* LVDS */ |
ddc_i2c = combios_setup_i2c_bus(RADEON_LCD_GPIO_MASK); |
1190,7 → 1190,8 |
radeon_add_legacy_connector(dev, 0, |
ATOM_DEVICE_LCD1_SUPPORT, |
DRM_MODE_CONNECTOR_LVDS, |
&ddc_i2c); |
&ddc_i2c, |
CONNECTOR_OBJECT_ID_LVDS); |
/* VGA - primary dac */ |
ddc_i2c = combios_setup_i2c_bus(RADEON_GPIO_VGA_DDC); |
1202,7 → 1203,8 |
radeon_add_legacy_connector(dev, 1, |
ATOM_DEVICE_CRT1_SUPPORT, |
DRM_MODE_CONNECTOR_VGA, |
&ddc_i2c); |
&ddc_i2c, |
CONNECTOR_OBJECT_ID_VGA); |
} else { |
/* DVI-I - tv dac, int tmds */ |
ddc_i2c = combios_setup_i2c_bus(RADEON_GPIO_DVI_DDC); |
1220,7 → 1222,8 |
ATOM_DEVICE_DFP1_SUPPORT | |
ATOM_DEVICE_CRT2_SUPPORT, |
DRM_MODE_CONNECTOR_DVII, |
&ddc_i2c); |
&ddc_i2c, |
CONNECTOR_OBJECT_ID_SINGLE_LINK_DVI_I); |
/* VGA - primary dac */ |
ddc_i2c = combios_setup_i2c_bus(RADEON_GPIO_VGA_DDC); |
1232,7 → 1235,8 |
radeon_add_legacy_connector(dev, 1, |
ATOM_DEVICE_CRT1_SUPPORT, |
DRM_MODE_CONNECTOR_VGA, |
&ddc_i2c); |
&ddc_i2c, |
CONNECTOR_OBJECT_ID_VGA); |
} |
if (rdev->family != CHIP_R100 && rdev->family != CHIP_R200) { |
1245,7 → 1249,8 |
radeon_add_legacy_connector(dev, 2, |
ATOM_DEVICE_TV1_SUPPORT, |
DRM_MODE_CONNECTOR_SVIDEO, |
&ddc_i2c); |
&ddc_i2c, |
CONNECTOR_OBJECT_ID_SVIDEO); |
} |
break; |
case CT_IBOOK: |
1259,7 → 1264,8 |
0), |
ATOM_DEVICE_LCD1_SUPPORT); |
radeon_add_legacy_connector(dev, 0, ATOM_DEVICE_LCD1_SUPPORT, |
DRM_MODE_CONNECTOR_LVDS, &ddc_i2c); |
DRM_MODE_CONNECTOR_LVDS, &ddc_i2c, |
CONNECTOR_OBJECT_ID_LVDS); |
/* VGA - TV DAC */ |
ddc_i2c = combios_setup_i2c_bus(RADEON_GPIO_VGA_DDC); |
radeon_add_legacy_encoder(dev, |
1268,7 → 1274,8 |
2), |
ATOM_DEVICE_CRT2_SUPPORT); |
radeon_add_legacy_connector(dev, 1, ATOM_DEVICE_CRT2_SUPPORT, |
DRM_MODE_CONNECTOR_VGA, &ddc_i2c); |
DRM_MODE_CONNECTOR_VGA, &ddc_i2c, |
CONNECTOR_OBJECT_ID_VGA); |
/* TV - TV DAC */ |
radeon_add_legacy_encoder(dev, |
radeon_get_encoder_id(dev, |
1277,7 → 1284,8 |
ATOM_DEVICE_TV1_SUPPORT); |
radeon_add_legacy_connector(dev, 2, ATOM_DEVICE_TV1_SUPPORT, |
DRM_MODE_CONNECTOR_SVIDEO, |
&ddc_i2c); |
&ddc_i2c, |
CONNECTOR_OBJECT_ID_SVIDEO); |
break; |
case CT_POWERBOOK_EXTERNAL: |
DRM_INFO("Connector Table: %d (powerbook external tmds)\n", |
1290,7 → 1298,8 |
0), |
ATOM_DEVICE_LCD1_SUPPORT); |
radeon_add_legacy_connector(dev, 0, ATOM_DEVICE_LCD1_SUPPORT, |
DRM_MODE_CONNECTOR_LVDS, &ddc_i2c); |
DRM_MODE_CONNECTOR_LVDS, &ddc_i2c, |
CONNECTOR_OBJECT_ID_LVDS); |
/* DVI-I - primary dac, ext tmds */ |
ddc_i2c = combios_setup_i2c_bus(RADEON_GPIO_VGA_DDC); |
radeon_add_legacy_encoder(dev, |
1303,10 → 1312,12 |
ATOM_DEVICE_CRT1_SUPPORT, |
1), |
ATOM_DEVICE_CRT1_SUPPORT); |
/* XXX some are SL */ |
radeon_add_legacy_connector(dev, 1, |
ATOM_DEVICE_DFP2_SUPPORT | |
ATOM_DEVICE_CRT1_SUPPORT, |
DRM_MODE_CONNECTOR_DVII, &ddc_i2c); |
DRM_MODE_CONNECTOR_DVII, &ddc_i2c, |
CONNECTOR_OBJECT_ID_DUAL_LINK_DVI_I); |
/* TV - TV DAC */ |
radeon_add_legacy_encoder(dev, |
radeon_get_encoder_id(dev, |
1315,7 → 1326,8 |
ATOM_DEVICE_TV1_SUPPORT); |
radeon_add_legacy_connector(dev, 2, ATOM_DEVICE_TV1_SUPPORT, |
DRM_MODE_CONNECTOR_SVIDEO, |
&ddc_i2c); |
&ddc_i2c, |
CONNECTOR_OBJECT_ID_SVIDEO); |
break; |
case CT_POWERBOOK_INTERNAL: |
DRM_INFO("Connector Table: %d (powerbook internal tmds)\n", |
1328,7 → 1340,8 |
0), |
ATOM_DEVICE_LCD1_SUPPORT); |
radeon_add_legacy_connector(dev, 0, ATOM_DEVICE_LCD1_SUPPORT, |
DRM_MODE_CONNECTOR_LVDS, &ddc_i2c); |
DRM_MODE_CONNECTOR_LVDS, &ddc_i2c, |
CONNECTOR_OBJECT_ID_LVDS); |
/* DVI-I - primary dac, int tmds */ |
ddc_i2c = combios_setup_i2c_bus(RADEON_GPIO_VGA_DDC); |
radeon_add_legacy_encoder(dev, |
1344,7 → 1357,8 |
radeon_add_legacy_connector(dev, 1, |
ATOM_DEVICE_DFP1_SUPPORT | |
ATOM_DEVICE_CRT1_SUPPORT, |
DRM_MODE_CONNECTOR_DVII, &ddc_i2c); |
DRM_MODE_CONNECTOR_DVII, &ddc_i2c, |
CONNECTOR_OBJECT_ID_SINGLE_LINK_DVI_I); |
/* TV - TV DAC */ |
radeon_add_legacy_encoder(dev, |
radeon_get_encoder_id(dev, |
1353,7 → 1367,8 |
ATOM_DEVICE_TV1_SUPPORT); |
radeon_add_legacy_connector(dev, 2, ATOM_DEVICE_TV1_SUPPORT, |
DRM_MODE_CONNECTOR_SVIDEO, |
&ddc_i2c); |
&ddc_i2c, |
CONNECTOR_OBJECT_ID_SVIDEO); |
break; |
case CT_POWERBOOK_VGA: |
DRM_INFO("Connector Table: %d (powerbook vga)\n", |
1366,7 → 1381,8 |
0), |
ATOM_DEVICE_LCD1_SUPPORT); |
radeon_add_legacy_connector(dev, 0, ATOM_DEVICE_LCD1_SUPPORT, |
DRM_MODE_CONNECTOR_LVDS, &ddc_i2c); |
DRM_MODE_CONNECTOR_LVDS, &ddc_i2c, |
CONNECTOR_OBJECT_ID_LVDS); |
/* VGA - primary dac */ |
ddc_i2c = combios_setup_i2c_bus(RADEON_GPIO_VGA_DDC); |
radeon_add_legacy_encoder(dev, |
1375,7 → 1391,8 |
1), |
ATOM_DEVICE_CRT1_SUPPORT); |
radeon_add_legacy_connector(dev, 1, ATOM_DEVICE_CRT1_SUPPORT, |
DRM_MODE_CONNECTOR_VGA, &ddc_i2c); |
DRM_MODE_CONNECTOR_VGA, &ddc_i2c, |
CONNECTOR_OBJECT_ID_VGA); |
/* TV - TV DAC */ |
radeon_add_legacy_encoder(dev, |
radeon_get_encoder_id(dev, |
1384,7 → 1401,8 |
ATOM_DEVICE_TV1_SUPPORT); |
radeon_add_legacy_connector(dev, 2, ATOM_DEVICE_TV1_SUPPORT, |
DRM_MODE_CONNECTOR_SVIDEO, |
&ddc_i2c); |
&ddc_i2c, |
CONNECTOR_OBJECT_ID_SVIDEO); |
break; |
case CT_MINI_EXTERNAL: |
DRM_INFO("Connector Table: %d (mini external tmds)\n", |
1401,10 → 1419,12 |
ATOM_DEVICE_CRT2_SUPPORT, |
2), |
ATOM_DEVICE_CRT2_SUPPORT); |
/* XXX are any DL? */ |
radeon_add_legacy_connector(dev, 0, |
ATOM_DEVICE_DFP2_SUPPORT | |
ATOM_DEVICE_CRT2_SUPPORT, |
DRM_MODE_CONNECTOR_DVII, &ddc_i2c); |
DRM_MODE_CONNECTOR_DVII, &ddc_i2c, |
CONNECTOR_OBJECT_ID_SINGLE_LINK_DVI_I); |
/* TV - TV DAC */ |
radeon_add_legacy_encoder(dev, |
radeon_get_encoder_id(dev, |
1413,7 → 1433,8 |
ATOM_DEVICE_TV1_SUPPORT); |
radeon_add_legacy_connector(dev, 1, ATOM_DEVICE_TV1_SUPPORT, |
DRM_MODE_CONNECTOR_SVIDEO, |
&ddc_i2c); |
&ddc_i2c, |
CONNECTOR_OBJECT_ID_SVIDEO); |
break; |
case CT_MINI_INTERNAL: |
DRM_INFO("Connector Table: %d (mini internal tmds)\n", |
1433,7 → 1454,8 |
radeon_add_legacy_connector(dev, 0, |
ATOM_DEVICE_DFP1_SUPPORT | |
ATOM_DEVICE_CRT2_SUPPORT, |
DRM_MODE_CONNECTOR_DVII, &ddc_i2c); |
DRM_MODE_CONNECTOR_DVII, &ddc_i2c, |
CONNECTOR_OBJECT_ID_SINGLE_LINK_DVI_I); |
/* TV - TV DAC */ |
radeon_add_legacy_encoder(dev, |
radeon_get_encoder_id(dev, |
1442,7 → 1464,8 |
ATOM_DEVICE_TV1_SUPPORT); |
radeon_add_legacy_connector(dev, 1, ATOM_DEVICE_TV1_SUPPORT, |
DRM_MODE_CONNECTOR_SVIDEO, |
&ddc_i2c); |
&ddc_i2c, |
CONNECTOR_OBJECT_ID_SVIDEO); |
break; |
case CT_IMAC_G5_ISIGHT: |
DRM_INFO("Connector Table: %d (imac g5 isight)\n", |
1455,7 → 1478,8 |
0), |
ATOM_DEVICE_DFP1_SUPPORT); |
radeon_add_legacy_connector(dev, 0, ATOM_DEVICE_DFP1_SUPPORT, |
DRM_MODE_CONNECTOR_DVID, &ddc_i2c); |
DRM_MODE_CONNECTOR_DVID, &ddc_i2c, |
CONNECTOR_OBJECT_ID_SINGLE_LINK_DVI_D); |
/* VGA - tv dac */ |
ddc_i2c = combios_setup_i2c_bus(RADEON_GPIO_DVI_DDC); |
radeon_add_legacy_encoder(dev, |
1464,7 → 1488,8 |
2), |
ATOM_DEVICE_CRT2_SUPPORT); |
radeon_add_legacy_connector(dev, 1, ATOM_DEVICE_CRT2_SUPPORT, |
DRM_MODE_CONNECTOR_VGA, &ddc_i2c); |
DRM_MODE_CONNECTOR_VGA, &ddc_i2c, |
CONNECTOR_OBJECT_ID_VGA); |
/* TV - TV DAC */ |
radeon_add_legacy_encoder(dev, |
radeon_get_encoder_id(dev, |
1473,7 → 1498,8 |
ATOM_DEVICE_TV1_SUPPORT); |
radeon_add_legacy_connector(dev, 2, ATOM_DEVICE_TV1_SUPPORT, |
DRM_MODE_CONNECTOR_SVIDEO, |
&ddc_i2c); |
&ddc_i2c, |
CONNECTOR_OBJECT_ID_SVIDEO); |
break; |
case CT_EMAC: |
DRM_INFO("Connector Table: %d (emac)\n", |
1486,7 → 1512,8 |
1), |
ATOM_DEVICE_CRT1_SUPPORT); |
radeon_add_legacy_connector(dev, 0, ATOM_DEVICE_CRT1_SUPPORT, |
DRM_MODE_CONNECTOR_VGA, &ddc_i2c); |
DRM_MODE_CONNECTOR_VGA, &ddc_i2c, |
CONNECTOR_OBJECT_ID_VGA); |
/* VGA - tv dac */ |
ddc_i2c = combios_setup_i2c_bus(RADEON_GPIO_CRT2_DDC); |
radeon_add_legacy_encoder(dev, |
1495,7 → 1522,8 |
2), |
ATOM_DEVICE_CRT2_SUPPORT); |
radeon_add_legacy_connector(dev, 1, ATOM_DEVICE_CRT2_SUPPORT, |
DRM_MODE_CONNECTOR_VGA, &ddc_i2c); |
DRM_MODE_CONNECTOR_VGA, &ddc_i2c, |
CONNECTOR_OBJECT_ID_VGA); |
/* TV - TV DAC */ |
radeon_add_legacy_encoder(dev, |
radeon_get_encoder_id(dev, |
1504,7 → 1532,8 |
ATOM_DEVICE_TV1_SUPPORT); |
radeon_add_legacy_connector(dev, 2, ATOM_DEVICE_TV1_SUPPORT, |
DRM_MODE_CONNECTOR_SVIDEO, |
&ddc_i2c); |
&ddc_i2c, |
CONNECTOR_OBJECT_ID_SVIDEO); |
break; |
default: |
DRM_INFO("Connector table: %d (invalid)\n", |
1581,11 → 1610,63 |
return true; |
} |
static bool radeon_apply_legacy_tv_quirks(struct drm_device *dev) |
{ |
/* Acer 5102 has non-existent TV port */ |
if (dev->pdev->device == 0x5975 && |
dev->pdev->subsystem_vendor == 0x1025 && |
dev->pdev->subsystem_device == 0x009f) |
return false; |
/* HP dc5750 has non-existent TV port */ |
if (dev->pdev->device == 0x5974 && |
dev->pdev->subsystem_vendor == 0x103c && |
dev->pdev->subsystem_device == 0x280a) |
return false; |
return true; |
} |
static uint16_t combios_check_dl_dvi(struct drm_device *dev, int is_dvi_d) |
{ |
struct radeon_device *rdev = dev->dev_private; |
uint32_t ext_tmds_info; |
if (rdev->flags & RADEON_IS_IGP) { |
if (is_dvi_d) |
return CONNECTOR_OBJECT_ID_SINGLE_LINK_DVI_D; |
else |
return CONNECTOR_OBJECT_ID_SINGLE_LINK_DVI_I; |
} |
ext_tmds_info = combios_get_table_offset(dev, COMBIOS_EXT_TMDS_INFO_TABLE); |
if (ext_tmds_info) { |
uint8_t rev = RBIOS8(ext_tmds_info); |
uint8_t flags = RBIOS8(ext_tmds_info + 4 + 5); |
if (rev >= 3) { |
if (is_dvi_d) |
return CONNECTOR_OBJECT_ID_DUAL_LINK_DVI_D; |
else |
return CONNECTOR_OBJECT_ID_DUAL_LINK_DVI_I; |
} else { |
if (flags & 1) { |
if (is_dvi_d) |
return CONNECTOR_OBJECT_ID_DUAL_LINK_DVI_D; |
else |
return CONNECTOR_OBJECT_ID_DUAL_LINK_DVI_I; |
} |
} |
} |
if (is_dvi_d) |
return CONNECTOR_OBJECT_ID_SINGLE_LINK_DVI_D; |
else |
return CONNECTOR_OBJECT_ID_SINGLE_LINK_DVI_I; |
} |
bool radeon_get_legacy_connector_info_from_bios(struct drm_device *dev) |
{ |
struct radeon_device *rdev = dev->dev_private; |
uint32_t conn_info, entry, devices; |
uint16_t tmp; |
uint16_t tmp, connector_object_id; |
enum radeon_combios_ddc ddc_type; |
enum radeon_combios_connector connector; |
int i = 0; |
1628,8 → 1709,9 |
break; |
} |
radeon_apply_legacy_quirks(dev, i, &connector, |
&ddc_i2c); |
if (!radeon_apply_legacy_quirks(dev, i, &connector, |
&ddc_i2c)) |
continue; |
switch (connector) { |
case CONNECTOR_PROPRIETARY_LEGACY: |
1644,7 → 1726,8 |
radeon_add_legacy_connector(dev, i, devices, |
legacy_connector_convert |
[connector], |
&ddc_i2c); |
&ddc_i2c, |
CONNECTOR_OBJECT_ID_SINGLE_LINK_DVI_D); |
break; |
case CONNECTOR_CRT_LEGACY: |
if (tmp & 0x1) { |
1669,7 → 1752,8 |
devices, |
legacy_connector_convert |
[connector], |
&ddc_i2c); |
&ddc_i2c, |
CONNECTOR_OBJECT_ID_VGA); |
break; |
case CONNECTOR_DVI_I_LEGACY: |
devices = 0; |
1698,6 → 1782,7 |
ATOM_DEVICE_DFP2_SUPPORT, |
0), |
ATOM_DEVICE_DFP2_SUPPORT); |
connector_object_id = combios_check_dl_dvi(dev, 0); |
} else { |
devices |= ATOM_DEVICE_DFP1_SUPPORT; |
radeon_add_legacy_encoder(dev, |
1706,6 → 1791,7 |
ATOM_DEVICE_DFP1_SUPPORT, |
0), |
ATOM_DEVICE_DFP1_SUPPORT); |
connector_object_id = CONNECTOR_OBJECT_ID_SINGLE_LINK_DVI_I; |
} |
radeon_add_legacy_connector(dev, |
i, |
1712,13 → 1798,17 |
devices, |
legacy_connector_convert |
[connector], |
&ddc_i2c); |
&ddc_i2c, |
connector_object_id); |
break; |
case CONNECTOR_DVI_D_LEGACY: |
if ((tmp >> 4) & 0x1) |
if ((tmp >> 4) & 0x1) { |
devices = ATOM_DEVICE_DFP2_SUPPORT; |
else |
connector_object_id = combios_check_dl_dvi(dev, 1); |
} else { |
devices = ATOM_DEVICE_DFP1_SUPPORT; |
connector_object_id = CONNECTOR_OBJECT_ID_SINGLE_LINK_DVI_I; |
} |
radeon_add_legacy_encoder(dev, |
radeon_get_encoder_id |
(dev, devices, 0), |
1726,7 → 1816,8 |
radeon_add_legacy_connector(dev, i, devices, |
legacy_connector_convert |
[connector], |
&ddc_i2c); |
&ddc_i2c, |
connector_object_id); |
break; |
case CONNECTOR_CTV_LEGACY: |
case CONNECTOR_STV_LEGACY: |
1740,7 → 1831,8 |
ATOM_DEVICE_TV1_SUPPORT, |
legacy_connector_convert |
[connector], |
&ddc_i2c); |
&ddc_i2c, |
CONNECTOR_OBJECT_ID_SVIDEO); |
break; |
default: |
DRM_ERROR("Unknown connector type: %d\n", |
1772,12 → 1864,31 |
ATOM_DEVICE_CRT1_SUPPORT | |
ATOM_DEVICE_DFP1_SUPPORT, |
DRM_MODE_CONNECTOR_DVII, |
&ddc_i2c); |
&ddc_i2c, |
CONNECTOR_OBJECT_ID_SINGLE_LINK_DVI_I); |
} else { |
uint16_t crt_info = |
combios_get_table_offset(dev, COMBIOS_CRT_INFO_TABLE); |
DRM_DEBUG("Found CRT table, assuming VGA connector\n"); |
if (crt_info) { |
radeon_add_legacy_encoder(dev, |
radeon_get_encoder_id(dev, |
ATOM_DEVICE_CRT1_SUPPORT, |
1), |
ATOM_DEVICE_CRT1_SUPPORT); |
ddc_i2c = combios_setup_i2c_bus(RADEON_GPIO_VGA_DDC); |
radeon_add_legacy_connector(dev, |
0, |
ATOM_DEVICE_CRT1_SUPPORT, |
DRM_MODE_CONNECTOR_VGA, |
&ddc_i2c, |
CONNECTOR_OBJECT_ID_VGA); |
} else { |
DRM_DEBUG("No connector info found\n"); |
return false; |
} |
} |
} |
if (rdev->flags & RADEON_IS_MOBILITY || rdev->flags & RADEON_IS_IGP) { |
uint16_t lcd_info = |
1870,7 → 1981,8 |
5, |
ATOM_DEVICE_LCD1_SUPPORT, |
DRM_MODE_CONNECTOR_LVDS, |
&ddc_i2c); |
&ddc_i2c, |
CONNECTOR_OBJECT_ID_LVDS); |
} |
} |
1880,6 → 1992,7 |
combios_get_table_offset(dev, COMBIOS_TV_INFO_TABLE); |
if (tv_info) { |
if (RBIOS8(tv_info + 6) == 'T') { |
if (radeon_apply_legacy_tv_quirks(dev)) { |
radeon_add_legacy_encoder(dev, |
radeon_get_encoder_id |
(dev, |
1889,10 → 2002,12 |
radeon_add_legacy_connector(dev, 6, |
ATOM_DEVICE_TV1_SUPPORT, |
DRM_MODE_CONNECTOR_SVIDEO, |
&ddc_i2c); |
&ddc_i2c, |
CONNECTOR_OBJECT_ID_SVIDEO); |
} |
} |
} |
} |
radeon_link_encoder_connector(dev); |
/drivers/video/drm/radeon/radeon_connectors.c |
---|
178,25 → 178,12 |
struct drm_device *dev = encoder->dev; |
struct radeon_encoder *radeon_encoder = to_radeon_encoder(encoder); |
struct drm_display_mode *mode = NULL; |
struct radeon_native_mode *native_mode = &radeon_encoder->native_mode; |
struct drm_display_mode *native_mode = &radeon_encoder->native_mode; |
if (native_mode->panel_xres != 0 && |
native_mode->panel_yres != 0 && |
native_mode->dotclock != 0) { |
mode = drm_mode_create(dev); |
mode->hdisplay = native_mode->panel_xres; |
mode->vdisplay = native_mode->panel_yres; |
mode->htotal = mode->hdisplay + native_mode->hblank; |
mode->hsync_start = mode->hdisplay + native_mode->hoverplus; |
mode->hsync_end = mode->hsync_start + native_mode->hsync_width; |
mode->vtotal = mode->vdisplay + native_mode->vblank; |
mode->vsync_start = mode->vdisplay + native_mode->voverplus; |
mode->vsync_end = mode->vsync_start + native_mode->vsync_width; |
mode->clock = native_mode->dotclock; |
mode->flags = 0; |
if (native_mode->hdisplay != 0 && |
native_mode->vdisplay != 0 && |
native_mode->clock != 0) { |
mode = drm_mode_duplicate(dev, native_mode); |
mode->type = DRM_MODE_TYPE_PREFERRED | DRM_MODE_TYPE_DRIVER; |
drm_mode_set_name(mode); |
210,7 → 197,7 |
struct drm_device *dev = encoder->dev; |
struct radeon_encoder *radeon_encoder = to_radeon_encoder(encoder); |
struct drm_display_mode *mode = NULL; |
struct radeon_native_mode *native_mode = &radeon_encoder->native_mode; |
struct drm_display_mode *native_mode = &radeon_encoder->native_mode; |
int i; |
struct mode_size { |
int w; |
236,11 → 223,16 |
}; |
for (i = 0; i < 17; i++) { |
if (radeon_encoder->devices & (ATOM_DEVICE_TV_SUPPORT)) { |
if (common_modes[i].w > 1024 || |
common_modes[i].h > 768) |
continue; |
} |
if (radeon_encoder->devices & (ATOM_DEVICE_LCD_SUPPORT)) { |
if (common_modes[i].w > native_mode->panel_xres || |
common_modes[i].h > native_mode->panel_yres || |
(common_modes[i].w == native_mode->panel_xres && |
common_modes[i].h == native_mode->panel_yres)) |
if (common_modes[i].w > native_mode->hdisplay || |
common_modes[i].h > native_mode->vdisplay || |
(common_modes[i].w == native_mode->hdisplay && |
common_modes[i].h == native_mode->vdisplay)) |
continue; |
} |
if (common_modes[i].w < 320 || common_modes[i].h < 200) |
344,28 → 336,23 |
struct drm_connector *connector) |
{ |
struct radeon_encoder *radeon_encoder = to_radeon_encoder(encoder); |
struct radeon_native_mode *native_mode = &radeon_encoder->native_mode; |
struct drm_display_mode *native_mode = &radeon_encoder->native_mode; |
/* Try to get native mode details from EDID if necessary */ |
if (!native_mode->dotclock) { |
if (!native_mode->clock) { |
struct drm_display_mode *t, *mode; |
list_for_each_entry_safe(mode, t, &connector->probed_modes, head) { |
if (mode->hdisplay == native_mode->panel_xres && |
mode->vdisplay == native_mode->panel_yres) { |
native_mode->hblank = mode->htotal - mode->hdisplay; |
native_mode->hoverplus = mode->hsync_start - mode->hdisplay; |
native_mode->hsync_width = mode->hsync_end - mode->hsync_start; |
native_mode->vblank = mode->vtotal - mode->vdisplay; |
native_mode->voverplus = mode->vsync_start - mode->vdisplay; |
native_mode->vsync_width = mode->vsync_end - mode->vsync_start; |
native_mode->dotclock = mode->clock; |
if (mode->hdisplay == native_mode->hdisplay && |
mode->vdisplay == native_mode->vdisplay) { |
*native_mode = *mode; |
drm_mode_set_crtcinfo(native_mode, CRTC_INTERLACE_HALVE_V); |
DRM_INFO("Determined LVDS native mode details from EDID\n"); |
break; |
} |
} |
} |
if (!native_mode->dotclock) { |
if (!native_mode->clock) { |
DRM_INFO("No LVDS native mode details, disabling RMX\n"); |
radeon_encoder->rmx_type = RMX_OFF; |
} |
410,13 → 397,64 |
static int radeon_lvds_mode_valid(struct drm_connector *connector, |
struct drm_display_mode *mode) |
{ |
struct drm_encoder *encoder = radeon_best_single_encoder(connector); |
if ((mode->hdisplay < 320) || (mode->vdisplay < 240)) |
return MODE_PANEL; |
if (encoder) { |
struct radeon_encoder *radeon_encoder = to_radeon_encoder(encoder); |
struct drm_display_mode *native_mode = &radeon_encoder->native_mode; |
/* AVIVO hardware supports downscaling modes larger than the panel |
* to the panel size, but I'm not sure this is desirable. |
*/ |
if ((mode->hdisplay > native_mode->hdisplay) || |
(mode->vdisplay > native_mode->vdisplay)) |
return MODE_PANEL; |
/* if scaling is disabled, block non-native modes */ |
if (radeon_encoder->rmx_type == RMX_OFF) { |
if ((mode->hdisplay != native_mode->hdisplay) || |
(mode->vdisplay != native_mode->vdisplay)) |
return MODE_PANEL; |
} |
} |
return MODE_OK; |
} |
static enum drm_connector_status radeon_lvds_detect(struct drm_connector *connector) |
{ |
enum drm_connector_status ret = connector_status_connected; |
struct radeon_connector *radeon_connector = to_radeon_connector(connector); |
struct drm_encoder *encoder = radeon_best_single_encoder(connector); |
enum drm_connector_status ret = connector_status_disconnected; |
if (encoder) { |
struct radeon_encoder *radeon_encoder = to_radeon_encoder(encoder); |
struct drm_display_mode *native_mode = &radeon_encoder->native_mode; |
/* check if panel is valid */ |
if (native_mode->hdisplay >= 320 && native_mode->vdisplay >= 240) |
ret = connector_status_connected; |
} |
/* check for edid as well */ |
if (radeon_connector->edid) |
ret = connector_status_connected; |
else { |
if (radeon_connector->ddc_bus) { |
radeon_i2c_do_lock(radeon_connector, 1); |
radeon_connector->edid = drm_get_edid(&radeon_connector->base, |
&radeon_connector->ddc_bus->adapter); |
radeon_i2c_do_lock(radeon_connector, 0); |
if (radeon_connector->edid) |
ret = connector_status_connected; |
} |
} |
/* check acpi lid status ??? */ |
radeon_connector_update_scratch_regs(connector, ret); |
return ret; |
} |
427,6 → 465,8 |
if (radeon_connector->ddc_bus) |
radeon_i2c_destroy(radeon_connector->ddc_bus); |
if (radeon_connector->edid) |
kfree(radeon_connector->edid); |
kfree(radeon_connector->con_priv); |
drm_sysfs_connector_remove(connector); |
drm_connector_cleanup(connector); |
496,6 → 536,8 |
static int radeon_vga_mode_valid(struct drm_connector *connector, |
struct drm_display_mode *mode) |
{ |
/* XXX check mode bandwidth */ |
/* XXX verify against max DAC output frequency */ |
return MODE_OK; |
} |
514,9 → 556,32 |
radeon_i2c_do_lock(radeon_connector, 1); |
dret = radeon_ddc_probe(radeon_connector); |
radeon_i2c_do_lock(radeon_connector, 0); |
if (dret) |
if (dret) { |
if (radeon_connector->edid) { |
kfree(radeon_connector->edid); |
radeon_connector->edid = NULL; |
} |
radeon_i2c_do_lock(radeon_connector, 1); |
radeon_connector->edid = drm_get_edid(&radeon_connector->base, &radeon_connector->ddc_bus->adapter); |
radeon_i2c_do_lock(radeon_connector, 0); |
if (!radeon_connector->edid) { |
DRM_ERROR("DDC responded but not EDID found for %s\n", |
drm_get_connector_name(connector)); |
} else { |
radeon_connector->use_digital = !!(radeon_connector->edid->input & DRM_EDID_INPUT_DIGITAL); |
/* some oems have boards with separate digital and analog connectors |
* with a shared ddc line (often vga + hdmi) |
*/ |
if (radeon_connector->use_digital && radeon_connector->shared_ddc) { |
kfree(radeon_connector->edid); |
radeon_connector->edid = NULL; |
ret = connector_status_disconnected; |
} else |
ret = connector_status_connected; |
else { |
} |
} else { |
if (radeon_connector->dac_load_detect) { |
encoder_funcs = encoder->helper_private; |
ret = encoder_funcs->detect(encoder, connector); |
570,6 → 635,8 |
static int radeon_tv_mode_valid(struct drm_connector *connector, |
struct drm_display_mode *mode) |
{ |
if ((mode->hdisplay > 1024) || (mode->vdisplay > 768)) |
return MODE_CLOCK_RANGE; |
return MODE_OK; |
} |
644,6 → 711,10 |
dret = radeon_ddc_probe(radeon_connector); |
radeon_i2c_do_lock(radeon_connector, 0); |
if (dret) { |
if (radeon_connector->edid) { |
kfree(radeon_connector->edid); |
radeon_connector->edid = NULL; |
} |
radeon_i2c_do_lock(radeon_connector, 1); |
radeon_connector->edid = drm_get_edid(&radeon_connector->base, &radeon_connector->ddc_bus->adapter); |
radeon_i2c_do_lock(radeon_connector, 0); |
654,9 → 725,14 |
} else { |
radeon_connector->use_digital = !!(radeon_connector->edid->input & DRM_EDID_INPUT_DIGITAL); |
/* if this isn't a digital monitor |
then we need to make sure we don't have any |
TV conflicts */ |
/* some oems have boards with separate digital and analog connectors |
* with a shared ddc line (often vga + hdmi) |
*/ |
if ((!radeon_connector->use_digital) && radeon_connector->shared_ddc) { |
kfree(radeon_connector->edid); |
radeon_connector->edid = NULL; |
ret = connector_status_disconnected; |
} else |
ret = connector_status_connected; |
} |
} |
753,9 → 829,27 |
radeon_connector->use_digital = true; |
} |
static int radeon_dvi_mode_valid(struct drm_connector *connector, |
struct drm_display_mode *mode) |
{ |
struct radeon_connector *radeon_connector = to_radeon_connector(connector); |
/* XXX check mode bandwidth */ |
if (radeon_connector->use_digital && (mode->clock > 165000)) { |
if ((radeon_connector->connector_object_id == CONNECTOR_OBJECT_ID_DUAL_LINK_DVI_I) || |
(radeon_connector->connector_object_id == CONNECTOR_OBJECT_ID_DUAL_LINK_DVI_D) || |
(radeon_connector->connector_object_id == CONNECTOR_OBJECT_ID_HDMI_TYPE_B)) |
return MODE_OK; |
else |
return MODE_CLOCK_HIGH; |
} |
return MODE_OK; |
} |
struct drm_connector_helper_funcs radeon_dvi_connector_helper_funcs = { |
.get_modes = radeon_dvi_get_modes, |
.mode_valid = radeon_vga_mode_valid, |
.mode_valid = radeon_dvi_mode_valid, |
.best_encoder = radeon_dvi_encoder, |
}; |
775,7 → 869,8 |
int connector_type, |
struct radeon_i2c_bus_rec *i2c_bus, |
bool linkb, |
uint32_t igp_lane_info) |
uint32_t igp_lane_info, |
uint16_t connector_object_id) |
{ |
struct radeon_device *rdev = dev->dev_private; |
struct drm_connector *connector; |
782,6 → 877,7 |
struct radeon_connector *radeon_connector; |
struct radeon_connector_atom_dig *radeon_dig_connector; |
uint32_t subpixel_order = SubPixelNone; |
bool shared_ddc = false; |
int ret; |
/* fixme - tv/cv/din */ |
795,7 → 891,14 |
radeon_connector->devices |= supported_device; |
return; |
} |
if (radeon_connector->ddc_bus && i2c_bus->valid) { |
if (memcmp(&radeon_connector->ddc_bus->rec, i2c_bus, |
sizeof(struct radeon_i2c_bus_rec)) == 0) { |
radeon_connector->shared_ddc = true; |
shared_ddc = true; |
} |
} |
} |
radeon_connector = kzalloc(sizeof(struct radeon_connector), GFP_KERNEL); |
if (!radeon_connector) |
805,6 → 908,8 |
radeon_connector->connector_id = connector_id; |
radeon_connector->devices = supported_device; |
radeon_connector->shared_ddc = shared_ddc; |
radeon_connector->connector_object_id = connector_object_id; |
switch (connector_type) { |
case DRM_MODE_CONNECTOR_VGA: |
drm_connector_init(dev, &radeon_connector->base, &radeon_vga_connector_funcs, connector_type); |
956,7 → 1061,8 |
uint32_t connector_id, |
uint32_t supported_device, |
int connector_type, |
struct radeon_i2c_bus_rec *i2c_bus) |
struct radeon_i2c_bus_rec *i2c_bus, |
uint16_t connector_object_id) |
{ |
struct radeon_device *rdev = dev->dev_private; |
struct drm_connector *connector; |
990,6 → 1096,7 |
radeon_connector->connector_id = connector_id; |
radeon_connector->devices = supported_device; |
radeon_connector->connector_object_id = connector_object_id; |
switch (connector_type) { |
case DRM_MODE_CONNECTOR_VGA: |
drm_connector_init(dev, &radeon_connector->base, &radeon_vga_connector_funcs, connector_type); |
/drivers/video/drm/radeon/radeon_device.c |
---|
47,7 → 47,7 |
int radeon_tv = 0; |
int radeon_modeset = 1; |
void parse_cmdline(char *cmdline, mode_t *mode, char *log); |
void parse_cmdline(char *cmdline, mode_t *mode, char *log, int *kms); |
int init_display(struct radeon_device *rdev, mode_t *mode); |
int init_display_kms(struct radeon_device *rdev, mode_t *mode); |
478,22 → 478,24 |
return r; |
} |
static struct card_info atom_card_info = { |
.dev = NULL, |
.reg_read = cail_reg_read, |
.reg_write = cail_reg_write, |
.mc_read = cail_mc_read, |
.mc_write = cail_mc_write, |
.pll_read = cail_pll_read, |
.pll_write = cail_pll_write, |
}; |
int radeon_atombios_init(struct radeon_device *rdev) |
{ |
ENTER(); |
struct card_info *atom_card_info = |
kzalloc(sizeof(struct card_info), GFP_KERNEL); |
atom_card_info.dev = rdev->ddev; |
rdev->mode_info.atom_context = atom_parse(&atom_card_info, rdev->bios); |
if (!atom_card_info) |
return -ENOMEM; |
rdev->mode_info.atom_card_info = atom_card_info; |
atom_card_info->dev = rdev->ddev; |
atom_card_info->reg_read = cail_reg_read; |
atom_card_info->reg_write = cail_reg_write; |
atom_card_info->mc_read = cail_mc_read; |
atom_card_info->mc_write = cail_mc_write; |
atom_card_info->pll_read = cail_pll_read; |
atom_card_info->pll_write = cail_pll_write; |
rdev->mode_info.atom_context = atom_parse(atom_card_info, rdev->bios); |
radeon_atom_initialize_bios_scratch_regs(rdev->ddev); |
return 0; |
} |
501,6 → 503,7 |
void radeon_atombios_fini(struct radeon_device *rdev) |
{ |
kfree(rdev->mode_info.atom_context); |
kfree(rdev->mode_info.atom_card_info); |
} |
int radeon_combios_init(struct radeon_device *rdev) |
886,7 → 889,7 |
return 0; |
if( cmdline && *cmdline ) |
parse_cmdline(cmdline, &usermode, log); |
parse_cmdline(cmdline, &usermode, log, &radeon_modeset); |
if(!dbg_open(log)) |
{ |
898,7 → 901,7 |
return 0; |
}; |
} |
dbgprintf("Radeon RC05 cmdline %s\n", cmdline); |
dbgprintf("Radeon RC06 cmdline %s\n", cmdline); |
enum_pci_devices(); |
/drivers/video/drm/radeon/radeon_display.c |
---|
137,9 → 137,6 |
if (size != 256) { |
return; |
} |
if (crtc->fb == NULL) { |
return; |
} |
/* userspace palettes are always correct as is */ |
for (i = 0; i < 256; i++) { |
147,7 → 144,6 |
radeon_crtc->lut_g[i] = green[i] >> 6; |
radeon_crtc->lut_b[i] = blue[i] >> 6; |
} |
radeon_crtc_load_lut(crtc); |
} |
338,7 → 334,6 |
int radeon_ddc_get_modes(struct radeon_connector *radeon_connector) |
{ |
struct edid *edid; |
int ret = 0; |
if (!radeon_connector->ddc_bus) |
345,20 → 340,13 |
return -1; |
if (!radeon_connector->edid) { |
radeon_i2c_do_lock(radeon_connector, 1); |
edid = drm_get_edid(&radeon_connector->base, &radeon_connector->ddc_bus->adapter); |
radeon_connector->edid = drm_get_edid(&radeon_connector->base, &radeon_connector->ddc_bus->adapter); |
radeon_i2c_do_lock(radeon_connector, 0); |
} else |
edid = radeon_connector->edid; |
} |
if (edid) { |
/* update digital bits here */ |
if (edid->input & DRM_EDID_INPUT_DIGITAL) |
radeon_connector->use_digital = 1; |
else |
radeon_connector->use_digital = 0; |
drm_mode_connector_update_edid_property(&radeon_connector->base, edid); |
ret = drm_add_edid_modes(&radeon_connector->base, edid); |
kfree(edid); |
if (radeon_connector->edid) { |
drm_mode_connector_update_edid_property(&radeon_connector->base, radeon_connector->edid); |
ret = drm_add_edid_modes(&radeon_connector->base, radeon_connector->edid); |
return ret; |
} |
drm_mode_connector_update_edid_property(&radeon_connector->base, NULL); |
760,8 → 748,6 |
struct radeon_encoder *radeon_encoder; |
bool first = true; |
ENTER(); |
list_for_each_entry(encoder, &dev->mode_config.encoder_list, head) { |
radeon_encoder = to_radeon_encoder(encoder); |
if (encoder->crtc != crtc) |
770,7 → 756,7 |
radeon_crtc->rmx_type = radeon_encoder->rmx_type; |
memcpy(&radeon_crtc->native_mode, |
&radeon_encoder->native_mode, |
sizeof(struct radeon_native_mode)); |
sizeof(struct drm_display_mode)); |
first = false; |
} else { |
if (radeon_crtc->rmx_type != radeon_encoder->rmx_type) { |
786,24 → 772,16 |
} |
} |
if (radeon_crtc->rmx_type != RMX_OFF) { |
dbgprintf("\nset scaler panel_xres %d panel_yres %d\n", |
radeon_crtc->native_mode.panel_xres, |
radeon_crtc->native_mode.panel_yres); |
fixed20_12 a, b; |
a.full = rfixed_const(crtc->mode.vdisplay); |
b.full = rfixed_const(radeon_crtc->native_mode.panel_xres); |
b.full = rfixed_const(radeon_crtc->native_mode.hdisplay); |
radeon_crtc->vsc.full = rfixed_div(a, b); |
a.full = rfixed_const(crtc->mode.hdisplay); |
b.full = rfixed_const(radeon_crtc->native_mode.panel_yres); |
b.full = rfixed_const(radeon_crtc->native_mode.vdisplay); |
radeon_crtc->hsc.full = rfixed_div(a, b); |
} else { |
radeon_crtc->vsc.full = rfixed_const(1); |
radeon_crtc->hsc.full = rfixed_const(1); |
} |
LEAVE(); |
return true; |
} |
/drivers/video/drm/radeon/radeon_encoders.c |
---|
31,6 → 31,10 |
extern int atom_debug; |
/* evil but including atombios.h is much worse */ |
bool radeon_atom_get_tv_timings(struct radeon_device *rdev, int index, |
struct drm_display_mode *mode); |
uint32_t |
radeon_get_encoder_id(struct drm_device *dev, uint32_t supported_device, uint8_t dac) |
{ |
167,49 → 171,17 |
struct radeon_encoder *radeon_encoder = to_radeon_encoder(encoder); |
struct drm_device *dev = encoder->dev; |
struct radeon_device *rdev = dev->dev_private; |
struct radeon_native_mode *native_mode = &radeon_encoder->native_mode; |
struct drm_display_mode *native_mode = &radeon_encoder->native_mode; |
if (mode->hdisplay < native_mode->panel_xres || |
mode->vdisplay < native_mode->panel_yres) { |
if (ASIC_IS_AVIVO(rdev)) { |
adjusted_mode->hdisplay = native_mode->panel_xres; |
adjusted_mode->vdisplay = native_mode->panel_yres; |
adjusted_mode->htotal = native_mode->panel_xres + native_mode->hblank; |
adjusted_mode->hsync_start = native_mode->panel_xres + native_mode->hoverplus; |
adjusted_mode->hsync_end = adjusted_mode->hsync_start + native_mode->hsync_width; |
adjusted_mode->vtotal = native_mode->panel_yres + native_mode->vblank; |
adjusted_mode->vsync_start = native_mode->panel_yres + native_mode->voverplus; |
adjusted_mode->vsync_end = adjusted_mode->vsync_start + native_mode->vsync_width; |
/* update crtc values */ |
drm_mode_set_crtcinfo(adjusted_mode, CRTC_INTERLACE_HALVE_V); |
/* adjust crtc values */ |
adjusted_mode->crtc_hdisplay = native_mode->panel_xres; |
adjusted_mode->crtc_vdisplay = native_mode->panel_yres; |
adjusted_mode->crtc_htotal = adjusted_mode->crtc_hdisplay + native_mode->hblank; |
adjusted_mode->crtc_hsync_start = adjusted_mode->crtc_hdisplay + native_mode->hoverplus; |
adjusted_mode->crtc_hsync_end = adjusted_mode->crtc_hsync_start + native_mode->hsync_width; |
adjusted_mode->crtc_vtotal = adjusted_mode->crtc_vdisplay + native_mode->vblank; |
adjusted_mode->crtc_vsync_start = adjusted_mode->crtc_vdisplay + native_mode->voverplus; |
adjusted_mode->crtc_vsync_end = adjusted_mode->crtc_vsync_start + native_mode->vsync_width; |
} else { |
adjusted_mode->htotal = native_mode->panel_xres + native_mode->hblank; |
adjusted_mode->hsync_start = native_mode->panel_xres + native_mode->hoverplus; |
adjusted_mode->hsync_end = adjusted_mode->hsync_start + native_mode->hsync_width; |
adjusted_mode->vtotal = native_mode->panel_yres + native_mode->vblank; |
adjusted_mode->vsync_start = native_mode->panel_yres + native_mode->voverplus; |
adjusted_mode->vsync_end = adjusted_mode->vsync_start + native_mode->vsync_width; |
/* update crtc values */ |
drm_mode_set_crtcinfo(adjusted_mode, CRTC_INTERLACE_HALVE_V); |
/* adjust crtc values */ |
adjusted_mode->crtc_htotal = adjusted_mode->crtc_hdisplay + native_mode->hblank; |
adjusted_mode->crtc_hsync_start = adjusted_mode->crtc_hdisplay + native_mode->hoverplus; |
adjusted_mode->crtc_hsync_end = adjusted_mode->crtc_hsync_start + native_mode->hsync_width; |
adjusted_mode->crtc_vtotal = adjusted_mode->crtc_vdisplay + native_mode->vblank; |
adjusted_mode->crtc_vsync_start = adjusted_mode->crtc_vdisplay + native_mode->voverplus; |
adjusted_mode->crtc_vsync_end = adjusted_mode->crtc_vsync_start + native_mode->vsync_width; |
if (mode->hdisplay < native_mode->hdisplay || |
mode->vdisplay < native_mode->vdisplay) { |
int mode_id = adjusted_mode->base.id; |
*adjusted_mode = *native_mode; |
if (!ASIC_IS_AVIVO(rdev)) { |
adjusted_mode->hdisplay = mode->hdisplay; |
adjusted_mode->vdisplay = mode->vdisplay; |
} |
adjusted_mode->flags = native_mode->flags; |
adjusted_mode->clock = native_mode->dotclock; |
adjusted_mode->base.id = mode_id; |
} |
} |
219,7 → 191,11 |
struct drm_display_mode *adjusted_mode) |
{ |
struct radeon_encoder *radeon_encoder = to_radeon_encoder(encoder); |
struct drm_device *dev = encoder->dev; |
struct radeon_device *rdev = dev->dev_private; |
/* set the active encoder to connector routing */ |
radeon_encoder_set_active_device(encoder); |
drm_mode_set_crtcinfo(adjusted_mode, 0); |
if (radeon_encoder->rmx_type != RMX_OFF) |
230,6 → 206,18 |
&& (mode->crtc_vsync_start < (mode->crtc_vdisplay + 2))) |
adjusted_mode->crtc_vsync_start = adjusted_mode->crtc_vdisplay + 2; |
if (radeon_encoder->active_device & (ATOM_DEVICE_TV_SUPPORT)) { |
struct radeon_encoder_atom_dac *tv_dac = radeon_encoder->enc_priv; |
if (tv_dac) { |
if (tv_dac->tv_std == TV_STD_NTSC || |
tv_dac->tv_std == TV_STD_NTSC_J || |
tv_dac->tv_std == TV_STD_PAL_M) |
radeon_atom_get_tv_timings(rdev, 0, adjusted_mode); |
else |
radeon_atom_get_tv_timings(rdev, 1, adjusted_mode); |
} |
} |
return true; |
} |
461,7 → 449,7 |
case 1: |
args.v1.ucMisc = 0; |
args.v1.ucAction = action; |
if (drm_detect_hdmi_monitor((struct edid *)connector->edid_blob_ptr)) |
if (drm_detect_hdmi_monitor(radeon_connector->edid)) |
args.v1.ucMisc |= PANEL_ENCODER_MISC_HDMI_TYPE; |
args.v1.usPixelClock = cpu_to_le16(radeon_encoder->pixel_clock / 10); |
if (radeon_encoder->devices & (ATOM_DEVICE_LCD_SUPPORT)) { |
486,7 → 474,7 |
if (dig->coherent_mode) |
args.v2.ucMisc |= PANEL_ENCODER_MISC_COHERENT; |
} |
if (drm_detect_hdmi_monitor((struct edid *)connector->edid_blob_ptr)) |
if (drm_detect_hdmi_monitor(radeon_connector->edid)) |
args.v2.ucMisc |= PANEL_ENCODER_MISC_HDMI_TYPE; |
args.v2.usPixelClock = cpu_to_le16(radeon_encoder->pixel_clock / 10); |
args.v2.ucTruncate = 0; |
544,7 → 532,7 |
switch (connector->connector_type) { |
case DRM_MODE_CONNECTOR_DVII: |
case DRM_MODE_CONNECTOR_HDMIB: /* HDMI-B is basically DL-DVI; analog works fine */ |
if (drm_detect_hdmi_monitor((struct edid *)connector->edid_blob_ptr)) |
if (drm_detect_hdmi_monitor(radeon_connector->edid)) |
return ATOM_ENCODER_MODE_HDMI; |
else if (radeon_connector->use_digital) |
return ATOM_ENCODER_MODE_DVI; |
554,7 → 542,7 |
case DRM_MODE_CONNECTOR_DVID: |
case DRM_MODE_CONNECTOR_HDMIA: |
default: |
if (drm_detect_hdmi_monitor((struct edid *)connector->edid_blob_ptr)) |
if (drm_detect_hdmi_monitor(radeon_connector->edid)) |
return ATOM_ENCODER_MODE_HDMI; |
else |
return ATOM_ENCODER_MODE_DVI; |
566,7 → 554,7 |
/*if (radeon_output->MonType == MT_DP) |
return ATOM_ENCODER_MODE_DP; |
else*/ |
if (drm_detect_hdmi_monitor((struct edid *)connector->edid_blob_ptr)) |
if (drm_detect_hdmi_monitor(radeon_connector->edid)) |
return ATOM_ENCODER_MODE_HDMI; |
else |
return ATOM_ENCODER_MODE_DVI; |
734,14 → 722,17 |
atom_parse_cmd_header(rdev->mode_info.atom_context, index, &frev, &crev); |
args.v1.ucAction = action; |
if (ASIC_IS_DCE32(rdev)) { |
if (radeon_encoder->pixel_clock > 165000) { |
args.v2.usPixelClock = cpu_to_le16((radeon_encoder->pixel_clock * 10 * 2) / 100); |
args.v2.acConfig.fDualLinkConnector = 1; |
if (action == ATOM_TRANSMITTER_ACTION_INIT) { |
args.v1.usInitInfo = radeon_connector->connector_object_id; |
} else { |
args.v2.usPixelClock = cpu_to_le16((radeon_encoder->pixel_clock * 10 * 4) / 100); |
if (radeon_encoder->pixel_clock > 165000) |
args.v1.usPixelClock = cpu_to_le16((radeon_encoder->pixel_clock / 2) / 10); |
else |
args.v1.usPixelClock = cpu_to_le16(radeon_encoder->pixel_clock / 10); |
} |
if (ASIC_IS_DCE32(rdev)) { |
if (radeon_encoder->pixel_clock > 165000) |
args.v2.usPixelClock = cpu_to_le16((radeon_encoder->pixel_clock / 2) / 10); |
if (dig->dig_block) |
args.v2.acConfig.ucEncoderSel = 1; |
766,7 → 757,6 |
} |
} else { |
args.v1.ucConfig = ATOM_TRANSMITTER_CONFIG_CLKSRC_PPLL; |
args.v1.usPixelClock = cpu_to_le16((radeon_encoder->pixel_clock) / 10); |
switch (radeon_encoder->encoder_id) { |
case ENCODER_OBJECT_ID_INTERNAL_UNIPHY: |
874,16 → 864,9 |
DISPLAY_DEVICE_OUTPUT_CONTROL_PS_ALLOCATION args; |
int index = 0; |
bool is_dig = false; |
int devices; |
memset(&args, 0, sizeof(args)); |
/* on DPMS off we have no idea if active device is meaningful */ |
if (mode != DRM_MODE_DPMS_ON && !radeon_encoder->active_device) |
devices = radeon_encoder->devices; |
else |
devices = radeon_encoder->active_device; |
DRM_DEBUG("encoder dpms %d to mode %d, devices %08x, active_devices %08x\n", |
radeon_encoder->encoder_id, mode, radeon_encoder->devices, |
radeon_encoder->active_device); |
914,9 → 897,9 |
break; |
case ENCODER_OBJECT_ID_INTERNAL_DAC1: |
case ENCODER_OBJECT_ID_INTERNAL_KLDSCP_DAC1: |
if (devices & (ATOM_DEVICE_TV_SUPPORT)) |
if (radeon_encoder->active_device & (ATOM_DEVICE_TV_SUPPORT)) |
index = GetIndexIntoMasterTable(COMMAND, TV1OutputControl); |
else if (devices & (ATOM_DEVICE_CV_SUPPORT)) |
else if (radeon_encoder->active_device & (ATOM_DEVICE_CV_SUPPORT)) |
index = GetIndexIntoMasterTable(COMMAND, CV1OutputControl); |
else |
index = GetIndexIntoMasterTable(COMMAND, DAC1OutputControl); |
923,9 → 906,9 |
break; |
case ENCODER_OBJECT_ID_INTERNAL_DAC2: |
case ENCODER_OBJECT_ID_INTERNAL_KLDSCP_DAC2: |
if (devices & (ATOM_DEVICE_TV_SUPPORT)) |
if (radeon_encoder->active_device & (ATOM_DEVICE_TV_SUPPORT)) |
index = GetIndexIntoMasterTable(COMMAND, TV1OutputControl); |
else if (devices & (ATOM_DEVICE_CV_SUPPORT)) |
else if (radeon_encoder->active_device & (ATOM_DEVICE_CV_SUPPORT)) |
index = GetIndexIntoMasterTable(COMMAND, CV1OutputControl); |
else |
index = GetIndexIntoMasterTable(COMMAND, DAC2OutputControl); |
1104,9 → 1087,12 |
} |
/* set scaler clears this on some chips */ |
if (!(radeon_encoder->active_device & (ATOM_DEVICE_TV_SUPPORT))) { |
if (ASIC_IS_AVIVO(rdev) && (mode->flags & DRM_MODE_FLAG_INTERLACE)) |
WREG32(AVIVO_D1MODE_DATA_FORMAT + radeon_crtc->crtc_offset, AVIVO_D1MODE_INTERLEAVE_EN); |
WREG32(AVIVO_D1MODE_DATA_FORMAT + radeon_crtc->crtc_offset, |
AVIVO_D1MODE_INTERLEAVE_EN); |
} |
} |
static void |
radeon_atom_encoder_mode_set(struct drm_encoder *encoder, |
1153,6 → 1139,7 |
/* setup and enable the encoder and transmitter */ |
atombios_dig_encoder_setup(encoder, ATOM_ENABLE); |
atombios_dig_transmitter_setup(encoder, ATOM_TRANSMITTER_ACTION_INIT); |
atombios_dig_transmitter_setup(encoder, ATOM_TRANSMITTER_ACTION_SETUP); |
atombios_dig_transmitter_setup(encoder, ATOM_TRANSMITTER_ACTION_ENABLE); |
break; |
1268,8 → 1255,6 |
{ |
radeon_atom_output_lock(encoder, true); |
radeon_atom_encoder_dpms(encoder, DRM_MODE_DPMS_OFF); |
radeon_encoder_set_active_device(encoder); |
} |
static void radeon_atom_encoder_commit(struct drm_encoder *encoder) |
/drivers/video/drm/radeon/radeon_gart.c |
---|
157,8 → 157,8 |
// WARN(1, "trying to unbind memory to unitialized GART !\n"); |
return; |
} |
t = offset / 4096; |
p = t / (PAGE_SIZE / 4096); |
t = offset / RADEON_GPU_PAGE_SIZE; |
p = t / (PAGE_SIZE / RADEON_GPU_PAGE_SIZE); |
for (i = 0; i < pages; i++, p++) { |
if (rdev->gart.pages[p]) { |
// pci_unmap_page(rdev->pdev, rdev->gart.pages_addr[p], |
165,7 → 165,7 |
// PAGE_SIZE, PCI_DMA_BIDIRECTIONAL); |
rdev->gart.pages[p] = NULL; |
rdev->gart.pages_addr[p] = 0; |
for (j = 0; j < (PAGE_SIZE / 4096); j++, t++) { |
for (j = 0; j < (PAGE_SIZE / RADEON_GPU_PAGE_SIZE); j++, t++) { |
radeon_gart_set_page(rdev, t, 0); |
} |
} |
191,8 → 191,8 |
DRM_ERROR("trying to bind memory to unitialized GART !\n"); |
return -EINVAL; |
} |
t = offset / 4096; |
p = t / (PAGE_SIZE / 4096); |
t = offset / RADEON_GPU_PAGE_SIZE; |
p = t / (PAGE_SIZE / RADEON_GPU_PAGE_SIZE); |
for (i = 0; i < pages; i++, p++) { |
/* we need to support large memory configurations */ |
206,10 → 206,10 |
// return -ENOMEM; |
//} |
rdev->gart.pages[p] = pagelist[i]; |
page_base = (uint32_t)rdev->gart.pages_addr[p]; |
for (j = 0; j < (PAGE_SIZE / 4096); j++, t++) { |
page_base = rdev->gart.pages_addr[p]; |
for (j = 0; j < (PAGE_SIZE / RADEON_GPU_PAGE_SIZE); j++, t++) { |
radeon_gart_set_page(rdev, t, page_base); |
page_base += 4096; |
page_base += RADEON_GPU_PAGE_SIZE; |
} |
} |
mb(); |
228,14 → 228,14 |
if (rdev->gart.pages) { |
return 0; |
} |
/* We need PAGE_SIZE >= 4096 */ |
if (PAGE_SIZE < 4096) { |
/* We need PAGE_SIZE >= RADEON_GPU_PAGE_SIZE */ |
if (PAGE_SIZE < RADEON_GPU_PAGE_SIZE) { |
DRM_ERROR("Page size is smaller than GPU page size!\n"); |
return -EINVAL; |
} |
/* Compute table size */ |
rdev->gart.num_cpu_pages = rdev->mc.gtt_size / PAGE_SIZE; |
rdev->gart.num_gpu_pages = rdev->mc.gtt_size / 4096; |
rdev->gart.num_gpu_pages = rdev->mc.gtt_size / RADEON_GPU_PAGE_SIZE; |
DRM_INFO("GART: num cpu pages %u, num gpu pages %u\n", |
rdev->gart.num_cpu_pages, rdev->gart.num_gpu_pages); |
/* Allocate pages table */ |
/drivers/video/drm/radeon/radeon_legacy_crtc.c |
---|
48,7 → 48,7 |
u32 fp_horz_stretch, fp_vert_stretch, fp_horz_vert_active; |
u32 fp_h_sync_strt_wid, fp_crtc_h_total_disp; |
u32 fp_v_sync_strt_wid, fp_crtc_v_total_disp; |
struct radeon_native_mode *native_mode = &radeon_crtc->native_mode; |
struct drm_display_mode *native_mode = &radeon_crtc->native_mode; |
fp_vert_stretch = RREG32(RADEON_FP_VERT_STRETCH) & |
(RADEON_VERT_STRETCH_RESERVED | |
95,19 → 95,19 |
fp_horz_vert_active = 0; |
if (native_mode->panel_xres == 0 || |
native_mode->panel_yres == 0) { |
if (native_mode->hdisplay == 0 || |
native_mode->vdisplay == 0) { |
hscale = false; |
vscale = false; |
} else { |
if (xres > native_mode->panel_xres) |
xres = native_mode->panel_xres; |
if (yres > native_mode->panel_yres) |
yres = native_mode->panel_yres; |
if (xres > native_mode->hdisplay) |
xres = native_mode->hdisplay; |
if (yres > native_mode->vdisplay) |
yres = native_mode->vdisplay; |
if (xres == native_mode->panel_xres) |
if (xres == native_mode->hdisplay) |
hscale = false; |
if (yres == native_mode->panel_yres) |
if (yres == native_mode->vdisplay) |
vscale = false; |
} |
119,11 → 119,11 |
else { |
inc = (fp_horz_stretch & RADEON_HORZ_AUTO_RATIO_INC) ? 1 : 0; |
scale = ((xres + inc) * RADEON_HORZ_STRETCH_RATIO_MAX) |
/ native_mode->panel_xres + 1; |
/ native_mode->hdisplay + 1; |
fp_horz_stretch |= (((scale) & RADEON_HORZ_STRETCH_RATIO_MASK) | |
RADEON_HORZ_STRETCH_BLEND | |
RADEON_HORZ_STRETCH_ENABLE | |
((native_mode->panel_xres/8-1) << 16)); |
((native_mode->hdisplay/8-1) << 16)); |
} |
if (!vscale) |
131,11 → 131,11 |
else { |
inc = (fp_vert_stretch & RADEON_VERT_AUTO_RATIO_INC) ? 1 : 0; |
scale = ((yres + inc) * RADEON_VERT_STRETCH_RATIO_MAX) |
/ native_mode->panel_yres + 1; |
/ native_mode->vdisplay + 1; |
fp_vert_stretch |= (((scale) & RADEON_VERT_STRETCH_RATIO_MASK) | |
RADEON_VERT_STRETCH_ENABLE | |
RADEON_VERT_STRETCH_BLEND | |
((native_mode->panel_yres-1) << 12)); |
((native_mode->vdisplay-1) << 12)); |
} |
break; |
case RMX_CENTER: |
175,8 → 175,8 |
? RADEON_CRTC_V_SYNC_POL |
: 0))); |
fp_horz_vert_active = (((native_mode->panel_yres) & 0xfff) | |
(((native_mode->panel_xres / 8) & 0x1ff) << 16)); |
fp_horz_vert_active = (((native_mode->vdisplay) & 0xfff) | |
(((native_mode->hdisplay / 8) & 0x1ff) << 16)); |
break; |
case RMX_OFF: |
default: |
534,6 → 534,10 |
radeon_fb = to_radeon_framebuffer(old_fb); |
// radeon_gem_object_unpin(radeon_fb->obj); |
} |
/* Bytes per pixel may have changed */ |
radeon_bandwidth_update(rdev); |
return 0; |
} |
666,6 → 670,9 |
WREG32(RADEON_DISP2_MERGE_CNTL, disp2_merge_cntl); |
WREG32(RADEON_CRTC2_GEN_CNTL, crtc2_gen_cntl); |
WREG32(RADEON_FP_H2_SYNC_STRT_WID, crtc_h_sync_strt_wid); |
WREG32(RADEON_FP_V2_SYNC_STRT_WID, crtc_v_sync_strt_wid); |
} else { |
uint32_t crtc_gen_cntl; |
uint32_t crtc_ext_cntl; |
1017,14 → 1024,11 |
int x, int y, struct drm_framebuffer *old_fb) |
{ |
struct radeon_crtc *radeon_crtc = to_radeon_crtc(crtc); |
struct drm_device *dev = crtc->dev; |
struct radeon_device *rdev = dev->dev_private; |
/* TODO TV */ |
radeon_crtc_set_base(crtc, x, y, old_fb); |
radeon_set_crtc_timing(crtc, adjusted_mode); |
radeon_set_pll(crtc, adjusted_mode); |
radeon_bandwidth_update(rdev); |
if (radeon_crtc->crtc_id == 0) { |
radeon_legacy_rmx_mode_set(crtc, mode, adjusted_mode); |
} else { |
/drivers/video/drm/radeon/radeon_legacy_encoders.c |
---|
107,8 → 107,6 |
else |
radeon_combios_output_lock(encoder, true); |
radeon_legacy_lvds_dpms(encoder, DRM_MODE_DPMS_OFF); |
radeon_encoder_set_active_device(encoder); |
} |
static void radeon_legacy_lvds_commit(struct drm_encoder *encoder) |
192,6 → 190,8 |
{ |
struct radeon_encoder *radeon_encoder = to_radeon_encoder(encoder); |
/* set the active encoder to connector routing */ |
radeon_encoder_set_active_device(encoder); |
drm_mode_set_crtcinfo(adjusted_mode, 0); |
if (radeon_encoder->rmx_type != RMX_OFF) |
218,7 → 218,8 |
struct drm_display_mode *mode, |
struct drm_display_mode *adjusted_mode) |
{ |
/* set the active encoder to connector routing */ |
radeon_encoder_set_active_device(encoder); |
drm_mode_set_crtcinfo(adjusted_mode, 0); |
return true; |
272,7 → 273,6 |
else |
radeon_combios_output_lock(encoder, true); |
radeon_legacy_primary_dac_dpms(encoder, DRM_MODE_DPMS_OFF); |
radeon_encoder_set_active_device(encoder); |
} |
static void radeon_legacy_primary_dac_commit(struct drm_encoder *encoder) |
468,7 → 468,6 |
else |
radeon_combios_output_lock(encoder, true); |
radeon_legacy_tmds_int_dpms(encoder, DRM_MODE_DPMS_OFF); |
radeon_encoder_set_active_device(encoder); |
} |
static void radeon_legacy_tmds_int_commit(struct drm_encoder *encoder) |
543,6 → 542,14 |
fp_gen_cntl &= ~(RADEON_FP_FPON | RADEON_FP_TMDS_EN); |
fp_gen_cntl &= ~(RADEON_FP_RMX_HVSYNC_CONTROL_EN | |
RADEON_FP_DFP_SYNC_SEL | |
RADEON_FP_CRT_SYNC_SEL | |
RADEON_FP_CRTC_LOCK_8DOT | |
RADEON_FP_USE_SHADOW_EN | |
RADEON_FP_CRTC_USE_SHADOW_VEND | |
RADEON_FP_CRT_SYNC_ALT); |
if (1) /* FIXME rgbBits == 8 */ |
fp_gen_cntl |= RADEON_FP_PANEL_FORMAT; /* 24 bit format */ |
else |
556,7 → 563,7 |
else |
fp_gen_cntl |= R200_FP_SOURCE_SEL_CRTC1; |
} else |
fp_gen_cntl |= RADEON_FP_SEL_CRTC1; |
fp_gen_cntl &= ~RADEON_FP_SEL_CRTC2; |
} else { |
if (ASIC_IS_R300(rdev) || rdev->family == CHIP_R200) { |
fp_gen_cntl &= ~R200_FP_SOURCE_SEL_MASK; |
593,7 → 600,8 |
struct drm_display_mode *mode, |
struct drm_display_mode *adjusted_mode) |
{ |
/* set the active encoder to connector routing */ |
radeon_encoder_set_active_device(encoder); |
drm_mode_set_crtcinfo(adjusted_mode, 0); |
return true; |
636,7 → 644,6 |
else |
radeon_combios_output_lock(encoder, true); |
radeon_legacy_tmds_ext_dpms(encoder, DRM_MODE_DPMS_OFF); |
radeon_encoder_set_active_device(encoder); |
} |
static void radeon_legacy_tmds_ext_commit(struct drm_encoder *encoder) |
735,7 → 742,8 |
struct drm_display_mode *mode, |
struct drm_display_mode *adjusted_mode) |
{ |
/* set the active encoder to connector routing */ |
radeon_encoder_set_active_device(encoder); |
drm_mode_set_crtcinfo(adjusted_mode, 0); |
return true; |
839,7 → 847,6 |
else |
radeon_combios_output_lock(encoder, true); |
radeon_legacy_tv_dac_dpms(encoder, DRM_MODE_DPMS_OFF); |
radeon_encoder_set_active_device(encoder); |
} |
static void radeon_legacy_tv_dac_commit(struct drm_encoder *encoder) |
/drivers/video/drm/radeon/radeon_mode.h |
---|
172,6 → 172,7 |
struct radeon_mode_info { |
struct atom_context *atom_context; |
struct card_info *atom_card_info; |
enum radeon_connector_table connector_table; |
bool mode_config_initialized; |
struct radeon_crtc *crtcs[2]; |
186,17 → 187,6 |
}; |
struct radeon_native_mode { |
/* preferred mode */ |
uint32_t panel_xres, panel_yres; |
uint32_t hoverplus, hsync_width; |
uint32_t hblank; |
uint32_t voverplus, vsync_width; |
uint32_t vblank; |
uint32_t dotclock; |
uint32_t flags; |
}; |
#define MAX_H_CODE_TIMING_LEN 32 |
#define MAX_V_CODE_TIMING_LEN 32 |
228,7 → 218,7 |
enum radeon_rmx_type rmx_type; |
fixed20_12 vsc; |
fixed20_12 hsc; |
struct radeon_native_mode native_mode; |
struct drm_display_mode native_mode; |
}; |
struct radeon_encoder_primary_dac { |
248,7 → 238,7 |
bool use_bios_dividers; |
uint32_t lvds_gen_cntl; |
/* panel mode */ |
struct radeon_native_mode native_mode; |
struct drm_display_mode native_mode; |
}; |
struct radeon_encoder_tv_dac { |
271,6 → 261,16 |
struct radeon_tmds_pll tmds_pll[4]; |
}; |
/* spread spectrum */ |
struct radeon_atom_ss { |
uint16_t percentage; |
uint8_t type; |
uint8_t step; |
uint8_t delay; |
uint8_t range; |
uint8_t refdiv; |
}; |
struct radeon_encoder_atom_dig { |
/* atom dig */ |
bool coherent_mode; |
278,8 → 278,9 |
/* atom lvds */ |
uint32_t lvds_misc; |
uint16_t panel_pwr_delay; |
struct radeon_atom_ss *ss; |
/* panel mode */ |
struct radeon_native_mode native_mode; |
struct drm_display_mode native_mode; |
}; |
struct radeon_encoder_atom_dac { |
294,7 → 295,7 |
uint32_t flags; |
uint32_t pixel_clock; |
enum radeon_rmx_type rmx_type; |
struct radeon_native_mode native_mode; |
struct drm_display_mode native_mode; |
void *enc_priv; |
}; |
308,6 → 309,8 |
uint32_t connector_id; |
uint32_t devices; |
struct radeon_i2c_chan *ddc_bus; |
/* some systems have a an hdmi and vga port with a shared ddc line */ |
bool shared_ddc; |
bool use_digital; |
/* we need to mind the EDID between detect |
and get modes due to analog/digital/tvencoder */ |
314,6 → 317,7 |
struct edid *edid; |
void *con_priv; |
bool dac_load_detect; |
uint16_t connector_object_id; |
}; |
struct radeon_framebuffer { |
/drivers/video/drm/radeon/radeon_object.c |
---|
152,8 → 152,8 |
robj->vm_addr = ((uint32_t)robj->mm_node->start); |
dbgprintf("alloc vram: base %x size %x\n", |
robj->vm_addr << PAGE_SHIFT, num_pages << PAGE_SHIFT); |
// dbgprintf("alloc vram: base %x size %x\n", |
// robj->vm_addr << PAGE_SHIFT, num_pages << PAGE_SHIFT); |
}; |
190,8 → 190,8 |
robj->vm_addr = ((uint32_t)robj->mm_node->start) ; |
dbgprintf("alloc gtt: base %x size %x\n", |
robj->vm_addr << PAGE_SHIFT, num_pages << PAGE_SHIFT); |
// dbgprintf("alloc gtt: base %x size %x\n", |
// robj->vm_addr << PAGE_SHIFT, num_pages << PAGE_SHIFT); |
}; |
// r = ttm_buffer_object_init(&rdev->mman.bdev, &robj->tobj, size, type, flags, |
297,7 → 297,7 |
(robj->vm_addr << PAGE_SHIFT); |
robj->kptr = (void*)MapIoMem(robj->cpu_addr, |
robj->mm_node->size << 12, PG_SW); |
dbgprintf("map io mem %x at %x\n", robj->cpu_addr, robj->kptr); |
// dbgprintf("map io mem %x at %x\n", robj->cpu_addr, robj->kptr); |
} |
else |
/drivers/video/drm/radeon/radeon_pm.c |
---|
0,0 → 1,65 |
/* |
* Permission is hereby granted, free of charge, to any person obtaining a |
* copy of this software and associated documentation files (the "Software"), |
* to deal in the Software without restriction, including without limitation |
* the rights to use, copy, modify, merge, publish, distribute, sublicense, |
* and/or sell copies of the Software, and to permit persons to whom the |
* Software is furnished to do so, subject to the following conditions: |
* |
* The above copyright notice and this permission notice shall be included in |
* all copies or substantial portions of the Software. |
* |
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR |
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, |
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL |
* THE COPYRIGHT HOLDER(S) OR AUTHOR(S) BE LIABLE FOR ANY CLAIM, DAMAGES OR |
* OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, |
* ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR |
* OTHER DEALINGS IN THE SOFTWARE. |
* |
* Authors: Rafał Miłecki <zajec5@gmail.com> |
*/ |
#include "drmP.h" |
#include "radeon.h" |
int radeon_debugfs_pm_init(struct radeon_device *rdev); |
int radeon_pm_init(struct radeon_device *rdev) |
{ |
if (radeon_debugfs_pm_init(rdev)) { |
DRM_ERROR("Failed to register debugfs file for CP !\n"); |
} |
return 0; |
} |
/* |
* Debugfs info |
*/ |
#if defined(CONFIG_DEBUG_FS) |
static int radeon_debugfs_pm_info(struct seq_file *m, void *data) |
{ |
struct drm_info_node *node = (struct drm_info_node *) m->private; |
struct drm_device *dev = node->minor->dev; |
struct radeon_device *rdev = dev->dev_private; |
seq_printf(m, "engine clock: %u0 Hz\n", radeon_get_engine_clock(rdev)); |
seq_printf(m, "memory clock: %u0 Hz\n", radeon_get_memory_clock(rdev)); |
return 0; |
} |
static struct drm_info_list radeon_pm_info_list[] = { |
{"radeon_pm_info", radeon_debugfs_pm_info, 0, NULL}, |
}; |
#endif |
int radeon_debugfs_pm_init(struct radeon_device *rdev) |
{ |
#if defined(CONFIG_DEBUG_FS) |
return radeon_debugfs_add_files(rdev, radeon_pm_info_list, ARRAY_SIZE(radeon_pm_info_list)); |
#else |
return 0; |
#endif |
} |
/drivers/video/drm/radeon/radeon_reg.h |
---|
290,6 → 290,8 |
#define RADEON_BUS_CNTL 0x0030 |
# define RADEON_BUS_MASTER_DIS (1 << 6) |
# define RADEON_BUS_BIOS_DIS_ROM (1 << 12) |
# define RS600_BUS_MASTER_DIS (1 << 14) |
# define RS600_MSI_REARM (1 << 20) /* rs600/rs690/rs740 */ |
# define RADEON_BUS_RD_DISCARD_EN (1 << 24) |
# define RADEON_BUS_RD_ABORT_EN (1 << 25) |
# define RADEON_BUS_MSTR_DISCONNECT_EN (1 << 28) |
297,6 → 299,9 |
# define RADEON_BUS_READ_BURST (1 << 30) |
#define RADEON_BUS_CNTL1 0x0034 |
# define RADEON_BUS_WAIT_ON_LOCK_EN (1 << 4) |
/* rv370/rv380, rv410, r423/r430/r480, r5xx */ |
#define RADEON_MSI_REARM_EN 0x0160 |
# define RV370_MSI_REARM_EN (1 << 0) |
/* #define RADEON_PCIE_INDEX 0x0030 */ |
/* #define RADEON_PCIE_DATA 0x0034 */ |
3311,6 → 3316,7 |
#define RADEON_AIC_CNTL 0x01d0 |
# define RADEON_PCIGART_TRANSLATE_EN (1 << 0) |
# define RADEON_DIS_OUT_OF_PCI_GART_ACCESS (1 << 1) |
# define RS400_MSI_REARM (1 << 3) /* rs400/rs480 */ |
#define RADEON_AIC_LO_ADDR 0x01dc |
#define RADEON_AIC_PT_BASE 0x01d8 |
#define RADEON_AIC_HI_ADDR 0x01e0 |
/drivers/video/drm/radeon/rdisplay.c |
---|
166,7 → 166,7 |
struct drm_device *dev; |
cursor_t *cursor; |
bool retval = false; |
bool retval = true; |
u32_t ifl; |
ENTER(); |
181,11 → 181,7 |
{ |
init_cursor(cursor); |
}; |
}; |
safe_sti(ifl); |
ifl = safe_cli(); |
{ |
rdisplay->restore_cursor(0,0); |
rdisplay->init_cursor = init_cursor; |
rdisplay->select_cursor = select_cursor; |
/drivers/video/drm/radeon/rdisplay_kms.c |
---|
344,9 → 344,13 |
}; |
rdisplay->crtc = rdisplay->connector->encoder->crtc; |
rdisplay->supported_modes = count_connector_modes(rdisplay->connector); |
dbgprintf("current mode %d x %d x %d\n", |
rdisplay->width, rdisplay->height, rdisplay->vrefresh); |
dbgprintf("user mode mode %d x %d x %d\n", |
usermode->width, usermode->height, usermode->freq); |
if( (usermode->width != 0) && |
(usermode->height != 0) && |
( (usermode->width != rdisplay->width) || |
365,6 → 369,8 |
rdisplay->show_cursor = NULL; |
rdisplay->move_cursor = move_cursor_kms; |
rdisplay->restore_cursor = restore_cursor; |
select_cursor_kms(rdisplay->cursor); |
radeon_show_cursor_kms(rdisplay->crtc); |
}; |
safe_sti(ifl); |
/drivers/video/drm/radeon/rs600.c |
---|
391,6 → 391,8 |
} |
/* Initialize clocks */ |
radeon_get_clock_info(rdev->ddev); |
/* Initialize power management */ |
radeon_pm_init(rdev); |
/* Get vram informations */ |
rs600_vram_info(rdev); |
/* Initialize memory controller (also test AGP) */ |
/drivers/video/drm/radeon/rs690.c |
---|
665,6 → 665,8 |
} |
/* Initialize clocks */ |
radeon_get_clock_info(rdev->ddev); |
/* Initialize power management */ |
radeon_pm_init(rdev); |
/* Get vram informations */ |
rs690_vram_info(rdev); |
/* Initialize memory controller (also test AGP) */ |
/drivers/video/drm/radeon/rv515.c |
---|
142,6 → 142,8 |
void rv515_vga_render_disable(struct radeon_device *rdev) |
{ |
WREG32(R_000330_D1VGA_CONTROL, 0); |
WREG32(R_000338_D2VGA_CONTROL, 0); |
WREG32(R_000300_VGA_RENDER_CONTROL, |
RREG32(R_000300_VGA_RENDER_CONTROL) & C_000300_VGA_VSTATUS_CNTL); |
} |
548,6 → 550,8 |
} |
/* Initialize clocks */ |
radeon_get_clock_info(rdev->ddev); |
/* Initialize power management */ |
radeon_pm_init(rdev); |
/* Get vram informations */ |
rv515_vram_info(rdev); |
/* Initialize memory controller (also test AGP) */ |
/drivers/video/drm/radeon/rv770.c |
---|
531,11 → 531,11 |
if (rdev->family == CHIP_RV770) |
gb_tiling_config |= BANK_TILING(1); |
else |
gb_tiling_config |= BANK_TILING((mc_arb_ramcfg & NOOFBANK_SHIFT) >> NOOFBANK_MASK); |
gb_tiling_config |= BANK_TILING((mc_arb_ramcfg & NOOFBANK_MASK) >> NOOFBANK_SHIFT); |
gb_tiling_config |= GROUP_SIZE(0); |
if (((mc_arb_ramcfg & NOOFROWS_MASK) & NOOFROWS_SHIFT) > 3) { |
if (((mc_arb_ramcfg & NOOFROWS_MASK) >> NOOFROWS_SHIFT) > 3) { |
gb_tiling_config |= ROW_TILING(3); |
gb_tiling_config |= SAMPLE_SPLIT(3); |
} else { |
776,14 → 776,36 |
{ |
fixed20_12 a; |
u32 tmp; |
int chansize, numchan; |
int r; |
/* Get VRAM informations */ |
/* FIXME: Don't know how to determine vram width, need to check |
* vram_width usage |
*/ |
rdev->mc.vram_width = 128; |
rdev->mc.vram_is_ddr = true; |
tmp = RREG32(MC_ARB_RAMCFG); |
if (tmp & CHANSIZE_OVERRIDE) { |
chansize = 16; |
} else if (tmp & CHANSIZE_MASK) { |
chansize = 64; |
} else { |
chansize = 32; |
} |
tmp = RREG32(MC_SHARED_CHMAP); |
switch ((tmp & NOOFCHAN_MASK) >> NOOFCHAN_SHIFT) { |
case 0: |
default: |
numchan = 1; |
break; |
case 1: |
numchan = 2; |
break; |
case 2: |
numchan = 4; |
break; |
case 3: |
numchan = 8; |
break; |
} |
rdev->mc.vram_width = numchan * chansize; |
/* Could aper size report 0 ? */ |
rdev->mc.aper_base = drm_get_resource_start(rdev->ddev, 0); |
rdev->mc.aper_size = drm_get_resource_len(rdev->ddev, 0); |
921,10 → 943,13 |
r600_scratch_init(rdev); |
/* Initialize surface registers */ |
radeon_surface_init(rdev); |
/* Initialize clocks */ |
radeon_get_clock_info(rdev->ddev); |
r = radeon_clocks_init(rdev); |
if (r) |
return r; |
/* Initialize power management */ |
radeon_pm_init(rdev); |
/* Fence driver */ |
// r = radeon_fence_driver_init(rdev); |
// if (r) |
/drivers/video/drm/radeon/rv770d.h |
---|
129,6 → 129,10 |
#define HDP_REG_COHERENCY_FLUSH_CNTL 0x54A0 |
#define HDP_TILING_CONFIG 0x2F3C |
#define MC_SHARED_CHMAP 0x2004 |
#define NOOFCHAN_SHIFT 12 |
#define NOOFCHAN_MASK 0x00003000 |
#define MC_ARB_RAMCFG 0x2760 |
#define NOOFBANK_SHIFT 0 |
#define NOOFBANK_MASK 0x00000003 |
142,6 → 146,7 |
#define CHANSIZE_MASK 0x00000100 |
#define BURSTLENGTH_SHIFT 9 |
#define BURSTLENGTH_MASK 0x00000200 |
#define CHANSIZE_OVERRIDE (1 << 11) |
#define MC_VM_AGP_TOP 0x2028 |
#define MC_VM_AGP_BOT 0x202C |
#define MC_VM_AGP_BASE 0x2030 |