126,6 → 126,23 |
} |
} |
|
void radeon_encoder_set_active_device(struct drm_encoder *encoder) |
{ |
struct drm_device *dev = encoder->dev; |
struct radeon_encoder *radeon_encoder = to_radeon_encoder(encoder); |
struct drm_connector *connector; |
|
list_for_each_entry(connector, &dev->mode_config.connector_list, head) { |
if (connector->encoder == encoder) { |
struct radeon_connector *radeon_connector = to_radeon_connector(connector); |
radeon_encoder->active_device = radeon_encoder->devices & radeon_connector->devices; |
DRM_DEBUG("setting active device to %08x from %08x %08x for encoder %d\n", |
radeon_encoder->active_device, radeon_encoder->devices, |
radeon_connector->devices, encoder->encoder_type); |
} |
} |
} |
|
static struct drm_connector * |
radeon_get_connector_for_encoder(struct drm_encoder *encoder) |
{ |
154,7 → 171,6 |
|
if (mode->hdisplay < native_mode->panel_xres || |
mode->vdisplay < native_mode->panel_yres) { |
radeon_encoder->flags |= RADEON_USE_RMX; |
if (ASIC_IS_AVIVO(rdev)) { |
adjusted_mode->hdisplay = native_mode->panel_xres; |
adjusted_mode->vdisplay = native_mode->panel_yres; |
201,11 → 217,8 |
struct drm_display_mode *mode, |
struct drm_display_mode *adjusted_mode) |
{ |
|
struct radeon_encoder *radeon_encoder = to_radeon_encoder(encoder); |
|
radeon_encoder->flags &= ~RADEON_USE_RMX; |
|
drm_mode_set_crtcinfo(adjusted_mode, 0); |
|
if (radeon_encoder->rmx_type != RMX_OFF) |
227,9 → 240,12 |
struct radeon_encoder *radeon_encoder = to_radeon_encoder(encoder); |
DAC_ENCODER_CONTROL_PS_ALLOCATION args; |
int index = 0, num = 0; |
/* fixme - fill in enc_priv for atom dac */ |
struct radeon_encoder_atom_dac *dac_info = radeon_encoder->enc_priv; |
enum radeon_tv_std tv_std = TV_STD_NTSC; |
|
if (dac_info->tv_std) |
tv_std = dac_info->tv_std; |
|
memset(&args, 0, sizeof(args)); |
|
switch (radeon_encoder->encoder_id) { |
247,9 → 263,9 |
|
args.ucAction = action; |
|
if (radeon_encoder->devices & (ATOM_DEVICE_CRT_SUPPORT)) |
if (radeon_encoder->active_device & (ATOM_DEVICE_CRT_SUPPORT)) |
args.ucDacStandard = ATOM_DAC1_PS2; |
else if (radeon_encoder->devices & (ATOM_DEVICE_CV_SUPPORT)) |
else if (radeon_encoder->active_device & (ATOM_DEVICE_CV_SUPPORT)) |
args.ucDacStandard = ATOM_DAC1_CV; |
else { |
switch (tv_std) { |
282,9 → 298,12 |
struct radeon_encoder *radeon_encoder = to_radeon_encoder(encoder); |
TV_ENCODER_CONTROL_PS_ALLOCATION args; |
int index = 0; |
/* fixme - fill in enc_priv for atom dac */ |
struct radeon_encoder_atom_dac *dac_info = radeon_encoder->enc_priv; |
enum radeon_tv_std tv_std = TV_STD_NTSC; |
|
if (dac_info->tv_std) |
tv_std = dac_info->tv_std; |
|
memset(&args, 0, sizeof(args)); |
|
index = GetIndexIntoMasterTable(COMMAND, TVEncoderControl); |
291,7 → 310,7 |
|
args.sTVEncoder.ucAction = action; |
|
if (radeon_encoder->devices & (ATOM_DEVICE_CV_SUPPORT)) |
if (radeon_encoder->active_device & (ATOM_DEVICE_CV_SUPPORT)) |
args.sTVEncoder.ucTvStandard = ATOM_TV_CV; |
else { |
switch (tv_std) { |
523,6 → 542,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)) |
return ATOM_ENCODER_MODE_HDMI; |
else if (radeon_connector->use_digital) |
532,7 → 552,6 |
break; |
case DRM_MODE_CONNECTOR_DVID: |
case DRM_MODE_CONNECTOR_HDMIA: |
case DRM_MODE_CONNECTOR_HDMIB: |
default: |
if (drm_detect_hdmi_monitor((struct edid *)connector->edid_blob_ptr)) |
return ATOM_ENCODER_MODE_HDMI; |
808,234 → 827,6 |
|
} |
|
static void atom_rv515_force_tv_scaler(struct radeon_device *rdev) |
{ |
|
WREG32(0x659C, 0x0); |
WREG32(0x6594, 0x705); |
WREG32(0x65A4, 0x10001); |
WREG32(0x65D8, 0x0); |
WREG32(0x65B0, 0x0); |
WREG32(0x65C0, 0x0); |
WREG32(0x65D4, 0x0); |
WREG32(0x6578, 0x0); |
WREG32(0x657C, 0x841880A8); |
WREG32(0x6578, 0x1); |
WREG32(0x657C, 0x84208680); |
WREG32(0x6578, 0x2); |
WREG32(0x657C, 0xBFF880B0); |
WREG32(0x6578, 0x100); |
WREG32(0x657C, 0x83D88088); |
WREG32(0x6578, 0x101); |
WREG32(0x657C, 0x84608680); |
WREG32(0x6578, 0x102); |
WREG32(0x657C, 0xBFF080D0); |
WREG32(0x6578, 0x200); |
WREG32(0x657C, 0x83988068); |
WREG32(0x6578, 0x201); |
WREG32(0x657C, 0x84A08680); |
WREG32(0x6578, 0x202); |
WREG32(0x657C, 0xBFF080F8); |
WREG32(0x6578, 0x300); |
WREG32(0x657C, 0x83588058); |
WREG32(0x6578, 0x301); |
WREG32(0x657C, 0x84E08660); |
WREG32(0x6578, 0x302); |
WREG32(0x657C, 0xBFF88120); |
WREG32(0x6578, 0x400); |
WREG32(0x657C, 0x83188040); |
WREG32(0x6578, 0x401); |
WREG32(0x657C, 0x85008660); |
WREG32(0x6578, 0x402); |
WREG32(0x657C, 0xBFF88150); |
WREG32(0x6578, 0x500); |
WREG32(0x657C, 0x82D88030); |
WREG32(0x6578, 0x501); |
WREG32(0x657C, 0x85408640); |
WREG32(0x6578, 0x502); |
WREG32(0x657C, 0xBFF88180); |
WREG32(0x6578, 0x600); |
WREG32(0x657C, 0x82A08018); |
WREG32(0x6578, 0x601); |
WREG32(0x657C, 0x85808620); |
WREG32(0x6578, 0x602); |
WREG32(0x657C, 0xBFF081B8); |
WREG32(0x6578, 0x700); |
WREG32(0x657C, 0x82608010); |
WREG32(0x6578, 0x701); |
WREG32(0x657C, 0x85A08600); |
WREG32(0x6578, 0x702); |
WREG32(0x657C, 0x800081F0); |
WREG32(0x6578, 0x800); |
WREG32(0x657C, 0x8228BFF8); |
WREG32(0x6578, 0x801); |
WREG32(0x657C, 0x85E085E0); |
WREG32(0x6578, 0x802); |
WREG32(0x657C, 0xBFF88228); |
WREG32(0x6578, 0x10000); |
WREG32(0x657C, 0x82A8BF00); |
WREG32(0x6578, 0x10001); |
WREG32(0x657C, 0x82A08CC0); |
WREG32(0x6578, 0x10002); |
WREG32(0x657C, 0x8008BEF8); |
WREG32(0x6578, 0x10100); |
WREG32(0x657C, 0x81F0BF28); |
WREG32(0x6578, 0x10101); |
WREG32(0x657C, 0x83608CA0); |
WREG32(0x6578, 0x10102); |
WREG32(0x657C, 0x8018BED0); |
WREG32(0x6578, 0x10200); |
WREG32(0x657C, 0x8148BF38); |
WREG32(0x6578, 0x10201); |
WREG32(0x657C, 0x84408C80); |
WREG32(0x6578, 0x10202); |
WREG32(0x657C, 0x8008BEB8); |
WREG32(0x6578, 0x10300); |
WREG32(0x657C, 0x80B0BF78); |
WREG32(0x6578, 0x10301); |
WREG32(0x657C, 0x85008C20); |
WREG32(0x6578, 0x10302); |
WREG32(0x657C, 0x8020BEA0); |
WREG32(0x6578, 0x10400); |
WREG32(0x657C, 0x8028BF90); |
WREG32(0x6578, 0x10401); |
WREG32(0x657C, 0x85E08BC0); |
WREG32(0x6578, 0x10402); |
WREG32(0x657C, 0x8018BE90); |
WREG32(0x6578, 0x10500); |
WREG32(0x657C, 0xBFB8BFB0); |
WREG32(0x6578, 0x10501); |
WREG32(0x657C, 0x86C08B40); |
WREG32(0x6578, 0x10502); |
WREG32(0x657C, 0x8010BE90); |
WREG32(0x6578, 0x10600); |
WREG32(0x657C, 0xBF58BFC8); |
WREG32(0x6578, 0x10601); |
WREG32(0x657C, 0x87A08AA0); |
WREG32(0x6578, 0x10602); |
WREG32(0x657C, 0x8010BE98); |
WREG32(0x6578, 0x10700); |
WREG32(0x657C, 0xBF10BFF0); |
WREG32(0x6578, 0x10701); |
WREG32(0x657C, 0x886089E0); |
WREG32(0x6578, 0x10702); |
WREG32(0x657C, 0x8018BEB0); |
WREG32(0x6578, 0x10800); |
WREG32(0x657C, 0xBED8BFE8); |
WREG32(0x6578, 0x10801); |
WREG32(0x657C, 0x89408940); |
WREG32(0x6578, 0x10802); |
WREG32(0x657C, 0xBFE8BED8); |
WREG32(0x6578, 0x20000); |
WREG32(0x657C, 0x80008000); |
WREG32(0x6578, 0x20001); |
WREG32(0x657C, 0x90008000); |
WREG32(0x6578, 0x20002); |
WREG32(0x657C, 0x80008000); |
WREG32(0x6578, 0x20003); |
WREG32(0x657C, 0x80008000); |
WREG32(0x6578, 0x20100); |
WREG32(0x657C, 0x80108000); |
WREG32(0x6578, 0x20101); |
WREG32(0x657C, 0x8FE0BF70); |
WREG32(0x6578, 0x20102); |
WREG32(0x657C, 0xBFE880C0); |
WREG32(0x6578, 0x20103); |
WREG32(0x657C, 0x80008000); |
WREG32(0x6578, 0x20200); |
WREG32(0x657C, 0x8018BFF8); |
WREG32(0x6578, 0x20201); |
WREG32(0x657C, 0x8F80BF08); |
WREG32(0x6578, 0x20202); |
WREG32(0x657C, 0xBFD081A0); |
WREG32(0x6578, 0x20203); |
WREG32(0x657C, 0xBFF88000); |
WREG32(0x6578, 0x20300); |
WREG32(0x657C, 0x80188000); |
WREG32(0x6578, 0x20301); |
WREG32(0x657C, 0x8EE0BEC0); |
WREG32(0x6578, 0x20302); |
WREG32(0x657C, 0xBFB082A0); |
WREG32(0x6578, 0x20303); |
WREG32(0x657C, 0x80008000); |
WREG32(0x6578, 0x20400); |
WREG32(0x657C, 0x80188000); |
WREG32(0x6578, 0x20401); |
WREG32(0x657C, 0x8E00BEA0); |
WREG32(0x6578, 0x20402); |
WREG32(0x657C, 0xBF8883C0); |
WREG32(0x6578, 0x20403); |
WREG32(0x657C, 0x80008000); |
WREG32(0x6578, 0x20500); |
WREG32(0x657C, 0x80188000); |
WREG32(0x6578, 0x20501); |
WREG32(0x657C, 0x8D00BE90); |
WREG32(0x6578, 0x20502); |
WREG32(0x657C, 0xBF588500); |
WREG32(0x6578, 0x20503); |
WREG32(0x657C, 0x80008008); |
WREG32(0x6578, 0x20600); |
WREG32(0x657C, 0x80188000); |
WREG32(0x6578, 0x20601); |
WREG32(0x657C, 0x8BC0BE98); |
WREG32(0x6578, 0x20602); |
WREG32(0x657C, 0xBF308660); |
WREG32(0x6578, 0x20603); |
WREG32(0x657C, 0x80008008); |
WREG32(0x6578, 0x20700); |
WREG32(0x657C, 0x80108000); |
WREG32(0x6578, 0x20701); |
WREG32(0x657C, 0x8A80BEB0); |
WREG32(0x6578, 0x20702); |
WREG32(0x657C, 0xBF0087C0); |
WREG32(0x6578, 0x20703); |
WREG32(0x657C, 0x80008008); |
WREG32(0x6578, 0x20800); |
WREG32(0x657C, 0x80108000); |
WREG32(0x6578, 0x20801); |
WREG32(0x657C, 0x8920BED0); |
WREG32(0x6578, 0x20802); |
WREG32(0x657C, 0xBED08920); |
WREG32(0x6578, 0x20803); |
WREG32(0x657C, 0x80008010); |
WREG32(0x6578, 0x30000); |
WREG32(0x657C, 0x90008000); |
WREG32(0x6578, 0x30001); |
WREG32(0x657C, 0x80008000); |
WREG32(0x6578, 0x30100); |
WREG32(0x657C, 0x8FE0BF90); |
WREG32(0x6578, 0x30101); |
WREG32(0x657C, 0xBFF880A0); |
WREG32(0x6578, 0x30200); |
WREG32(0x657C, 0x8F60BF40); |
WREG32(0x6578, 0x30201); |
WREG32(0x657C, 0xBFE88180); |
WREG32(0x6578, 0x30300); |
WREG32(0x657C, 0x8EC0BF00); |
WREG32(0x6578, 0x30301); |
WREG32(0x657C, 0xBFC88280); |
WREG32(0x6578, 0x30400); |
WREG32(0x657C, 0x8DE0BEE0); |
WREG32(0x6578, 0x30401); |
WREG32(0x657C, 0xBFA083A0); |
WREG32(0x6578, 0x30500); |
WREG32(0x657C, 0x8CE0BED0); |
WREG32(0x6578, 0x30501); |
WREG32(0x657C, 0xBF7884E0); |
WREG32(0x6578, 0x30600); |
WREG32(0x657C, 0x8BA0BED8); |
WREG32(0x6578, 0x30601); |
WREG32(0x657C, 0xBF508640); |
WREG32(0x6578, 0x30700); |
WREG32(0x657C, 0x8A60BEE8); |
WREG32(0x6578, 0x30701); |
WREG32(0x657C, 0xBF2087A0); |
WREG32(0x6578, 0x30800); |
WREG32(0x657C, 0x8900BF00); |
WREG32(0x6578, 0x30801); |
WREG32(0x657C, 0xBF008900); |
} |
|
static void |
atombios_yuv_setup(struct drm_encoder *encoder, bool enable) |
{ |
1056,10 → 847,10 |
|
/* XXX: fix up scratch reg handling */ |
temp = RREG32(reg); |
if (radeon_encoder->devices & (ATOM_DEVICE_TV_SUPPORT)) |
if (radeon_encoder->active_device & (ATOM_DEVICE_TV_SUPPORT)) |
WREG32(reg, (ATOM_S3_TV1_ACTIVE | |
(radeon_crtc->crtc_id << 18))); |
else if (radeon_encoder->devices & (ATOM_DEVICE_CV_SUPPORT)) |
else if (radeon_encoder->active_device & (ATOM_DEVICE_CV_SUPPORT)) |
WREG32(reg, (ATOM_S3_CV_ACTIVE | (radeon_crtc->crtc_id << 24))); |
else |
WREG32(reg, 0); |
1074,129 → 865,6 |
} |
|
static void |
atombios_overscan_setup(struct drm_encoder *encoder, |
struct drm_display_mode *mode, |
struct drm_display_mode *adjusted_mode) |
{ |
struct drm_device *dev = encoder->dev; |
struct radeon_device *rdev = dev->dev_private; |
struct radeon_encoder *radeon_encoder = to_radeon_encoder(encoder); |
struct radeon_crtc *radeon_crtc = to_radeon_crtc(encoder->crtc); |
SET_CRTC_OVERSCAN_PS_ALLOCATION args; |
int index = GetIndexIntoMasterTable(COMMAND, SetCRTC_OverScan); |
|
memset(&args, 0, sizeof(args)); |
|
args.usOverscanRight = 0; |
args.usOverscanLeft = 0; |
args.usOverscanBottom = 0; |
args.usOverscanTop = 0; |
args.ucCRTC = radeon_crtc->crtc_id; |
|
if (radeon_encoder->flags & RADEON_USE_RMX) { |
if (radeon_encoder->rmx_type == RMX_FULL) { |
args.usOverscanRight = 0; |
args.usOverscanLeft = 0; |
args.usOverscanBottom = 0; |
args.usOverscanTop = 0; |
} else if (radeon_encoder->rmx_type == RMX_CENTER) { |
args.usOverscanTop = (adjusted_mode->crtc_vdisplay - mode->crtc_vdisplay) / 2; |
args.usOverscanBottom = (adjusted_mode->crtc_vdisplay - mode->crtc_vdisplay) / 2; |
args.usOverscanLeft = (adjusted_mode->crtc_hdisplay - mode->crtc_hdisplay) / 2; |
args.usOverscanRight = (adjusted_mode->crtc_hdisplay - mode->crtc_hdisplay) / 2; |
} else if (radeon_encoder->rmx_type == RMX_ASPECT) { |
int a1 = mode->crtc_vdisplay * adjusted_mode->crtc_hdisplay; |
int a2 = adjusted_mode->crtc_vdisplay * mode->crtc_hdisplay; |
|
if (a1 > a2) { |
args.usOverscanLeft = (adjusted_mode->crtc_hdisplay - (a2 / mode->crtc_vdisplay)) / 2; |
args.usOverscanRight = (adjusted_mode->crtc_hdisplay - (a2 / mode->crtc_vdisplay)) / 2; |
} else if (a2 > a1) { |
args.usOverscanLeft = (adjusted_mode->crtc_vdisplay - (a1 / mode->crtc_hdisplay)) / 2; |
args.usOverscanRight = (adjusted_mode->crtc_vdisplay - (a1 / mode->crtc_hdisplay)) / 2; |
} |
} |
} |
|
atom_execute_table(rdev->mode_info.atom_context, index, (uint32_t *)&args); |
|
} |
|
static void |
atombios_scaler_setup(struct drm_encoder *encoder) |
{ |
struct drm_device *dev = encoder->dev; |
struct radeon_device *rdev = dev->dev_private; |
struct radeon_encoder *radeon_encoder = to_radeon_encoder(encoder); |
struct radeon_crtc *radeon_crtc = to_radeon_crtc(encoder->crtc); |
ENABLE_SCALER_PS_ALLOCATION args; |
int index = GetIndexIntoMasterTable(COMMAND, EnableScaler); |
/* fixme - fill in enc_priv for atom dac */ |
enum radeon_tv_std tv_std = TV_STD_NTSC; |
|
if (!ASIC_IS_AVIVO(rdev) && radeon_crtc->crtc_id) |
return; |
|
memset(&args, 0, sizeof(args)); |
|
args.ucScaler = radeon_crtc->crtc_id; |
|
if (radeon_encoder->devices & (ATOM_DEVICE_TV_SUPPORT)) { |
switch (tv_std) { |
case TV_STD_NTSC: |
default: |
args.ucTVStandard = ATOM_TV_NTSC; |
break; |
case TV_STD_PAL: |
args.ucTVStandard = ATOM_TV_PAL; |
break; |
case TV_STD_PAL_M: |
args.ucTVStandard = ATOM_TV_PALM; |
break; |
case TV_STD_PAL_60: |
args.ucTVStandard = ATOM_TV_PAL60; |
break; |
case TV_STD_NTSC_J: |
args.ucTVStandard = ATOM_TV_NTSCJ; |
break; |
case TV_STD_SCART_PAL: |
args.ucTVStandard = ATOM_TV_PAL; /* ??? */ |
break; |
case TV_STD_SECAM: |
args.ucTVStandard = ATOM_TV_SECAM; |
break; |
case TV_STD_PAL_CN: |
args.ucTVStandard = ATOM_TV_PALCN; |
break; |
} |
args.ucEnable = SCALER_ENABLE_MULTITAP_MODE; |
} else if (radeon_encoder->devices & (ATOM_DEVICE_CV_SUPPORT)) { |
args.ucTVStandard = ATOM_TV_CV; |
args.ucEnable = SCALER_ENABLE_MULTITAP_MODE; |
} else if (radeon_encoder->flags & RADEON_USE_RMX) { |
if (radeon_encoder->rmx_type == RMX_FULL) |
args.ucEnable = ATOM_SCALER_EXPANSION; |
else if (radeon_encoder->rmx_type == RMX_CENTER) |
args.ucEnable = ATOM_SCALER_CENTER; |
else if (radeon_encoder->rmx_type == RMX_ASPECT) |
args.ucEnable = ATOM_SCALER_EXPANSION; |
} else { |
if (ASIC_IS_AVIVO(rdev)) |
args.ucEnable = ATOM_SCALER_DISABLE; |
else |
args.ucEnable = ATOM_SCALER_CENTER; |
} |
|
atom_execute_table(rdev->mode_info.atom_context, index, (uint32_t *)&args); |
|
if (radeon_encoder->devices & (ATOM_DEVICE_CV_SUPPORT | ATOM_DEVICE_TV_SUPPORT) |
&& rdev->family >= CHIP_RV515 && rdev->family <= CHIP_RV570) { |
atom_rv515_force_tv_scaler(rdev); |
} |
|
} |
|
static void |
radeon_atom_encoder_dpms(struct drm_encoder *encoder, int mode) |
{ |
struct drm_device *dev = encoder->dev; |
1205,9 → 873,19 |
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); |
switch (radeon_encoder->encoder_id) { |
case ENCODER_OBJECT_ID_INTERNAL_TMDS1: |
case ENCODER_OBJECT_ID_INTERNAL_KLDSCP_TMDS1: |
1235,9 → 913,9 |
break; |
case ENCODER_OBJECT_ID_INTERNAL_DAC1: |
case ENCODER_OBJECT_ID_INTERNAL_KLDSCP_DAC1: |
if (radeon_encoder->devices & (ATOM_DEVICE_TV_SUPPORT)) |
if (devices & (ATOM_DEVICE_TV_SUPPORT)) |
index = GetIndexIntoMasterTable(COMMAND, TV1OutputControl); |
else if (radeon_encoder->devices & (ATOM_DEVICE_CV_SUPPORT)) |
else if (devices & (ATOM_DEVICE_CV_SUPPORT)) |
index = GetIndexIntoMasterTable(COMMAND, CV1OutputControl); |
else |
index = GetIndexIntoMasterTable(COMMAND, DAC1OutputControl); |
1244,9 → 922,9 |
break; |
case ENCODER_OBJECT_ID_INTERNAL_DAC2: |
case ENCODER_OBJECT_ID_INTERNAL_KLDSCP_DAC2: |
if (radeon_encoder->devices & (ATOM_DEVICE_TV_SUPPORT)) |
if (devices & (ATOM_DEVICE_TV_SUPPORT)) |
index = GetIndexIntoMasterTable(COMMAND, TV1OutputControl); |
else if (radeon_encoder->devices & (ATOM_DEVICE_CV_SUPPORT)) |
else if (devices & (ATOM_DEVICE_CV_SUPPORT)) |
index = GetIndexIntoMasterTable(COMMAND, CV1OutputControl); |
else |
index = GetIndexIntoMasterTable(COMMAND, DAC2OutputControl); |
1333,9 → 1011,9 |
break; |
case ENCODER_OBJECT_ID_INTERNAL_DAC1: |
case ENCODER_OBJECT_ID_INTERNAL_KLDSCP_DAC1: |
if (radeon_encoder->devices & (ATOM_DEVICE_TV_SUPPORT)) |
if (radeon_encoder->active_device & (ATOM_DEVICE_TV_SUPPORT)) |
args.v1.ucDevice = ATOM_DEVICE_TV1_INDEX; |
else if (radeon_encoder->devices & (ATOM_DEVICE_CV_SUPPORT)) |
else if (radeon_encoder->active_device & (ATOM_DEVICE_CV_SUPPORT)) |
args.v1.ucDevice = ATOM_DEVICE_CV_INDEX; |
else |
args.v1.ucDevice = ATOM_DEVICE_CRT1_INDEX; |
1342,9 → 1020,9 |
break; |
case ENCODER_OBJECT_ID_INTERNAL_DAC2: |
case ENCODER_OBJECT_ID_INTERNAL_KLDSCP_DAC2: |
if (radeon_encoder->devices & (ATOM_DEVICE_TV_SUPPORT)) |
if (radeon_encoder->active_device & (ATOM_DEVICE_TV_SUPPORT)) |
args.v1.ucDevice = ATOM_DEVICE_TV1_INDEX; |
else if (radeon_encoder->devices & (ATOM_DEVICE_CV_SUPPORT)) |
else if (radeon_encoder->active_device & (ATOM_DEVICE_CV_SUPPORT)) |
args.v1.ucDevice = ATOM_DEVICE_CV_INDEX; |
else |
args.v1.ucDevice = ATOM_DEVICE_CRT2_INDEX; |
1373,17 → 1051,17 |
args.v2.ucEncoderID = ASIC_INT_DIG2_ENCODER_ID; |
break; |
case ENCODER_OBJECT_ID_INTERNAL_KLDSCP_DAC1: |
if (radeon_encoder->devices & (ATOM_DEVICE_TV_SUPPORT)) |
if (radeon_encoder->active_device & (ATOM_DEVICE_TV_SUPPORT)) |
args.v2.ucEncoderID = ASIC_INT_TV_ENCODER_ID; |
else if (radeon_encoder->devices & (ATOM_DEVICE_CV_SUPPORT)) |
else if (radeon_encoder->active_device & (ATOM_DEVICE_CV_SUPPORT)) |
args.v2.ucEncoderID = ASIC_INT_TV_ENCODER_ID; |
else |
args.v2.ucEncoderID = ASIC_INT_DAC1_ENCODER_ID; |
break; |
case ENCODER_OBJECT_ID_INTERNAL_KLDSCP_DAC2: |
if (radeon_encoder->devices & (ATOM_DEVICE_TV_SUPPORT)) |
if (radeon_encoder->active_device & (ATOM_DEVICE_TV_SUPPORT)) |
args.v2.ucEncoderID = ASIC_INT_TV_ENCODER_ID; |
else if (radeon_encoder->devices & (ATOM_DEVICE_CV_SUPPORT)) |
else if (radeon_encoder->active_device & (ATOM_DEVICE_CV_SUPPORT)) |
args.v2.ucEncoderID = ASIC_INT_TV_ENCODER_ID; |
else |
args.v2.ucEncoderID = ASIC_INT_DAC2_ENCODER_ID; |
1448,12 → 1126,10 |
radeon_encoder->pixel_clock = adjusted_mode->clock; |
|
radeon_atombios_encoder_crtc_scratch_regs(encoder, radeon_crtc->crtc_id); |
atombios_overscan_setup(encoder, mode, adjusted_mode); |
atombios_scaler_setup(encoder); |
atombios_set_encoder_crtc_source(encoder); |
|
if (ASIC_IS_AVIVO(rdev)) { |
if (radeon_encoder->devices & (ATOM_DEVICE_CV_SUPPORT | ATOM_DEVICE_TV_SUPPORT)) |
if (radeon_encoder->active_device & (ATOM_DEVICE_CV_SUPPORT | ATOM_DEVICE_TV_SUPPORT)) |
atombios_yuv_setup(encoder, true); |
else |
atombios_yuv_setup(encoder, false); |
1491,7 → 1167,7 |
case ENCODER_OBJECT_ID_INTERNAL_DAC2: |
case ENCODER_OBJECT_ID_INTERNAL_KLDSCP_DAC2: |
atombios_dac_setup(encoder, ATOM_ENABLE); |
if (radeon_encoder->devices & (ATOM_DEVICE_TV_SUPPORT | ATOM_DEVICE_CV_SUPPORT)) |
if (radeon_encoder->active_device & (ATOM_DEVICE_TV_SUPPORT | ATOM_DEVICE_CV_SUPPORT)) |
atombios_tv_setup(encoder, ATOM_ENABLE); |
break; |
} |
1499,11 → 1175,12 |
} |
|
static bool |
atombios_dac_load_detect(struct drm_encoder *encoder) |
atombios_dac_load_detect(struct drm_encoder *encoder, struct drm_connector *connector) |
{ |
struct drm_device *dev = encoder->dev; |
struct radeon_device *rdev = dev->dev_private; |
struct radeon_encoder *radeon_encoder = to_radeon_encoder(encoder); |
struct radeon_connector *radeon_connector = to_radeon_connector(connector); |
|
if (radeon_encoder->devices & (ATOM_DEVICE_TV_SUPPORT | |
ATOM_DEVICE_CV_SUPPORT | |
1524,15 → 1201,15 |
else |
args.sDacload.ucDacType = ATOM_DAC_B; |
|
if (radeon_encoder->devices & ATOM_DEVICE_CRT1_SUPPORT) |
if (radeon_connector->devices & ATOM_DEVICE_CRT1_SUPPORT) |
args.sDacload.usDeviceID = cpu_to_le16(ATOM_DEVICE_CRT1_SUPPORT); |
else if (radeon_encoder->devices & ATOM_DEVICE_CRT2_SUPPORT) |
else if (radeon_connector->devices & ATOM_DEVICE_CRT2_SUPPORT) |
args.sDacload.usDeviceID = cpu_to_le16(ATOM_DEVICE_CRT2_SUPPORT); |
else if (radeon_encoder->devices & ATOM_DEVICE_CV_SUPPORT) { |
else if (radeon_connector->devices & ATOM_DEVICE_CV_SUPPORT) { |
args.sDacload.usDeviceID = cpu_to_le16(ATOM_DEVICE_CV_SUPPORT); |
if (crev >= 3) |
args.sDacload.ucMisc = DAC_LOAD_MISC_YPrPb; |
} else if (radeon_encoder->devices & ATOM_DEVICE_TV1_SUPPORT) { |
} else if (radeon_connector->devices & ATOM_DEVICE_TV1_SUPPORT) { |
args.sDacload.usDeviceID = cpu_to_le16(ATOM_DEVICE_TV1_SUPPORT); |
if (crev >= 3) |
args.sDacload.ucMisc = DAC_LOAD_MISC_YPrPb; |
1551,9 → 1228,10 |
struct drm_device *dev = encoder->dev; |
struct radeon_device *rdev = dev->dev_private; |
struct radeon_encoder *radeon_encoder = to_radeon_encoder(encoder); |
struct radeon_connector *radeon_connector = to_radeon_connector(connector); |
uint32_t bios_0_scratch; |
|
if (!atombios_dac_load_detect(encoder)) { |
if (!atombios_dac_load_detect(encoder, connector)) { |
DRM_DEBUG("detect returned false \n"); |
return connector_status_unknown; |
} |
1563,17 → 1241,20 |
else |
bios_0_scratch = RREG32(RADEON_BIOS_0_SCRATCH); |
|
DRM_DEBUG("Bios 0 scratch %x\n", bios_0_scratch); |
if (radeon_encoder->devices & ATOM_DEVICE_CRT1_SUPPORT) { |
DRM_DEBUG("Bios 0 scratch %x %08x\n", bios_0_scratch, radeon_encoder->devices); |
if (radeon_connector->devices & ATOM_DEVICE_CRT1_SUPPORT) { |
if (bios_0_scratch & ATOM_S0_CRT1_MASK) |
return connector_status_connected; |
} else if (radeon_encoder->devices & ATOM_DEVICE_CRT2_SUPPORT) { |
} |
if (radeon_connector->devices & ATOM_DEVICE_CRT2_SUPPORT) { |
if (bios_0_scratch & ATOM_S0_CRT2_MASK) |
return connector_status_connected; |
} else if (radeon_encoder->devices & ATOM_DEVICE_CV_SUPPORT) { |
} |
if (radeon_connector->devices & ATOM_DEVICE_CV_SUPPORT) { |
if (bios_0_scratch & (ATOM_S0_CV_MASK|ATOM_S0_CV_MASK_A)) |
return connector_status_connected; |
} else if (radeon_encoder->devices & ATOM_DEVICE_TV1_SUPPORT) { |
} |
if (radeon_connector->devices & ATOM_DEVICE_TV1_SUPPORT) { |
if (bios_0_scratch & (ATOM_S0_TV1_COMPOSITE | ATOM_S0_TV1_COMPOSITE_A)) |
return connector_status_connected; /* CTV */ |
else if (bios_0_scratch & (ATOM_S0_TV1_SVIDEO | ATOM_S0_TV1_SVIDEO_A)) |
1586,6 → 1267,8 |
{ |
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) |
1594,6 → 1277,13 |
radeon_atom_output_lock(encoder, false); |
} |
|
static void radeon_atom_encoder_disable(struct drm_encoder *encoder) |
{ |
struct radeon_encoder *radeon_encoder = to_radeon_encoder(encoder); |
radeon_atom_encoder_dpms(encoder, DRM_MODE_DPMS_OFF); |
radeon_encoder->active_device = 0; |
} |
|
static const struct drm_encoder_helper_funcs radeon_atom_dig_helper_funcs = { |
.dpms = radeon_atom_encoder_dpms, |
.mode_fixup = radeon_atom_mode_fixup, |
1600,6 → 1290,7 |
.prepare = radeon_atom_encoder_prepare, |
.mode_set = radeon_atom_encoder_mode_set, |
.commit = radeon_atom_encoder_commit, |
.disable = radeon_atom_encoder_disable, |
/* no detect for TMDS/LVDS yet */ |
}; |
|
1624,6 → 1315,18 |
.destroy = radeon_enc_destroy, |
}; |
|
struct radeon_encoder_atom_dac * |
radeon_atombios_set_dac_info(struct radeon_encoder *radeon_encoder) |
{ |
struct radeon_encoder_atom_dac *dac = kzalloc(sizeof(struct radeon_encoder_atom_dac), GFP_KERNEL); |
|
if (!dac) |
return NULL; |
|
dac->tv_std = TV_STD_NTSC; |
return dac; |
} |
|
struct radeon_encoder_atom_dig * |
radeon_atombios_set_dig_info(struct radeon_encoder *radeon_encoder) |
{ |
1667,6 → 1370,7 |
|
radeon_encoder->encoder_id = encoder_id; |
radeon_encoder->devices = supported_device; |
radeon_encoder->rmx_type = RMX_OFF; |
|
switch (radeon_encoder->encoder_id) { |
case ENCODER_OBJECT_ID_INTERNAL_LVDS: |
1691,6 → 1395,7 |
case ENCODER_OBJECT_ID_INTERNAL_KLDSCP_DAC1: |
case ENCODER_OBJECT_ID_INTERNAL_KLDSCP_DAC2: |
drm_encoder_init(dev, encoder, &radeon_atom_enc_funcs, DRM_MODE_ENCODER_TVDAC); |
radeon_encoder->enc_priv = radeon_atombios_set_dac_info(radeon_encoder); |
drm_encoder_helper_add(encoder, &radeon_atom_dac_helper_funcs); |
break; |
case ENCODER_OBJECT_ID_INTERNAL_DVO1: |
1700,8 → 1405,14 |
case ENCODER_OBJECT_ID_INTERNAL_KLDSCP_LVTMA: |
case ENCODER_OBJECT_ID_INTERNAL_UNIPHY1: |
case ENCODER_OBJECT_ID_INTERNAL_UNIPHY2: |
if (radeon_encoder->devices & (ATOM_DEVICE_LCD_SUPPORT)) { |
radeon_encoder->rmx_type = RMX_FULL; |
drm_encoder_init(dev, encoder, &radeon_atom_enc_funcs, DRM_MODE_ENCODER_LVDS); |
radeon_encoder->enc_priv = radeon_atombios_get_lvds_info(radeon_encoder); |
} else { |
drm_encoder_init(dev, encoder, &radeon_atom_enc_funcs, DRM_MODE_ENCODER_TMDS); |
radeon_encoder->enc_priv = radeon_atombios_set_dig_info(radeon_encoder); |
} |
drm_encoder_helper_add(encoder, &radeon_atom_dig_helper_funcs); |
break; |
} |