1251881Speter/* 2251881Speter * Copyright 2007-8 Advanced Micro Devices, Inc. 3251881Speter * Copyright 2008 Red Hat Inc. 4251881Speter * 5251881Speter * Permission is hereby granted, free of charge, to any person obtaining a 6251881Speter * copy of this software and associated documentation files (the "Software"), 7251881Speter * to deal in the Software without restriction, including without limitation 8251881Speter * the rights to use, copy, modify, merge, publish, distribute, sublicense, 9251881Speter * and/or sell copies of the Software, and to permit persons to whom the 10251881Speter * Software is furnished to do so, subject to the following conditions: 11251881Speter * 12251881Speter * The above copyright notice and this permission notice shall be included in 13251881Speter * all copies or substantial portions of the Software. 14251881Speter * 15251881Speter * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 16251881Speter * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 17251881Speter * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL 18251881Speter * THE COPYRIGHT HOLDER(S) OR AUTHOR(S) BE LIABLE FOR ANY CLAIM, DAMAGES OR 19251881Speter * OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, 20251881Speter * ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR 21251881Speter * OTHER DEALINGS IN THE SOFTWARE. 22251881Speter * 23251881Speter * Authors: Dave Airlie 24251881Speter * Alex Deucher 25251881Speter */ 26251881Speter 27251881Speter#include <sys/cdefs.h> 28251881Speter__FBSDID("$FreeBSD$"); 29251881Speter 30251881Speter#include <dev/drm2/drmP.h> 31251881Speter#include <dev/drm2/drm_crtc_helper.h> 32251881Speter#include <dev/drm2/radeon/radeon_drm.h> 33251881Speter#include "radeon.h" 34251881Speter#include "radeon_asic.h" 35251881Speter#include "atom.h" 36251881Speter 37251881Speterstatic void radeon_legacy_encoder_disable(struct drm_encoder *encoder) 38251881Speter{ 39251881Speter struct radeon_encoder *radeon_encoder = to_radeon_encoder(encoder); 40251881Speter struct drm_encoder_helper_funcs *encoder_funcs; 41251881Speter 42251881Speter encoder_funcs = encoder->helper_private; 43251881Speter encoder_funcs->dpms(encoder, DRM_MODE_DPMS_OFF); 44251881Speter radeon_encoder->active_device = 0; 45251881Speter} 46251881Speter 47251881Speterstatic void radeon_legacy_lvds_update(struct drm_encoder *encoder, int mode) 48251881Speter{ 49251881Speter struct drm_device *dev = encoder->dev; 50251881Speter struct radeon_device *rdev = dev->dev_private; 51251881Speter struct radeon_encoder *radeon_encoder = to_radeon_encoder(encoder); 52251881Speter uint32_t lvds_gen_cntl, lvds_pll_cntl, pixclks_cntl, disp_pwr_man; 53251881Speter int panel_pwr_delay = 2000; 54251881Speter bool is_mac = false; 55251881Speter uint8_t backlight_level; 56251881Speter DRM_DEBUG_KMS("\n"); 57251881Speter 58251881Speter lvds_gen_cntl = RREG32(RADEON_LVDS_GEN_CNTL); 59251881Speter backlight_level = (lvds_gen_cntl >> RADEON_LVDS_BL_MOD_LEVEL_SHIFT) & 0xff; 60251881Speter 61251881Speter if (radeon_encoder->enc_priv) { 62251881Speter if (rdev->is_atom_bios) { 63251881Speter struct radeon_encoder_atom_dig *lvds = radeon_encoder->enc_priv; 64251881Speter panel_pwr_delay = lvds->panel_pwr_delay; 65251881Speter if (lvds->bl_dev) 66251881Speter backlight_level = lvds->backlight_level; 67251881Speter } else { 68251881Speter struct radeon_encoder_lvds *lvds = radeon_encoder->enc_priv; 69251881Speter panel_pwr_delay = lvds->panel_pwr_delay; 70251881Speter if (lvds->bl_dev) 71251881Speter backlight_level = lvds->backlight_level; 72251881Speter } 73251881Speter } 74251881Speter 75251881Speter /* macs (and possibly some x86 oem systems?) wire up LVDS strangely 76251881Speter * Taken from radeonfb. 77251881Speter */ 78251881Speter if ((rdev->mode_info.connector_table == CT_IBOOK) || 79251881Speter (rdev->mode_info.connector_table == CT_POWERBOOK_EXTERNAL) || 80251881Speter (rdev->mode_info.connector_table == CT_POWERBOOK_INTERNAL) || 81251881Speter (rdev->mode_info.connector_table == CT_POWERBOOK_VGA)) 82251881Speter is_mac = true; 83251881Speter 84251881Speter switch (mode) { 85251881Speter case DRM_MODE_DPMS_ON: 86251881Speter disp_pwr_man = RREG32(RADEON_DISP_PWR_MAN); 87251881Speter disp_pwr_man |= RADEON_AUTO_PWRUP_EN; 88251881Speter WREG32(RADEON_DISP_PWR_MAN, disp_pwr_man); 89251881Speter lvds_pll_cntl = RREG32(RADEON_LVDS_PLL_CNTL); 90251881Speter lvds_pll_cntl |= RADEON_LVDS_PLL_EN; 91251881Speter WREG32(RADEON_LVDS_PLL_CNTL, lvds_pll_cntl); 92251881Speter mdelay(1); 93251881Speter 94251881Speter lvds_pll_cntl = RREG32(RADEON_LVDS_PLL_CNTL); 95251881Speter lvds_pll_cntl &= ~RADEON_LVDS_PLL_RESET; 96251881Speter WREG32(RADEON_LVDS_PLL_CNTL, lvds_pll_cntl); 97251881Speter 98251881Speter lvds_gen_cntl &= ~(RADEON_LVDS_DISPLAY_DIS | 99251881Speter RADEON_LVDS_BL_MOD_LEVEL_MASK); 100251881Speter lvds_gen_cntl |= (RADEON_LVDS_ON | RADEON_LVDS_EN | 101251881Speter RADEON_LVDS_DIGON | RADEON_LVDS_BLON | 102251881Speter (backlight_level << RADEON_LVDS_BL_MOD_LEVEL_SHIFT)); 103251881Speter if (is_mac) 104251881Speter lvds_gen_cntl |= RADEON_LVDS_BL_MOD_EN; 105251881Speter mdelay(panel_pwr_delay); 106251881Speter WREG32(RADEON_LVDS_GEN_CNTL, lvds_gen_cntl); 107251881Speter break; 108251881Speter case DRM_MODE_DPMS_STANDBY: 109251881Speter case DRM_MODE_DPMS_SUSPEND: 110251881Speter case DRM_MODE_DPMS_OFF: 111251881Speter pixclks_cntl = RREG32_PLL(RADEON_PIXCLKS_CNTL); 112251881Speter WREG32_PLL_P(RADEON_PIXCLKS_CNTL, 0, ~RADEON_PIXCLK_LVDS_ALWAYS_ONb); 113251881Speter lvds_gen_cntl |= RADEON_LVDS_DISPLAY_DIS; 114251881Speter if (is_mac) { 115251881Speter lvds_gen_cntl &= ~RADEON_LVDS_BL_MOD_EN; 116251881Speter WREG32(RADEON_LVDS_GEN_CNTL, lvds_gen_cntl); 117251881Speter lvds_gen_cntl &= ~(RADEON_LVDS_ON | RADEON_LVDS_EN); 118251881Speter } else { 119251881Speter WREG32(RADEON_LVDS_GEN_CNTL, lvds_gen_cntl); 120251881Speter lvds_gen_cntl &= ~(RADEON_LVDS_ON | RADEON_LVDS_BLON | RADEON_LVDS_EN | RADEON_LVDS_DIGON); 121251881Speter } 122251881Speter mdelay(panel_pwr_delay); 123251881Speter WREG32(RADEON_LVDS_GEN_CNTL, lvds_gen_cntl); 124251881Speter WREG32_PLL(RADEON_PIXCLKS_CNTL, pixclks_cntl); 125251881Speter mdelay(panel_pwr_delay); 126251881Speter break; 127251881Speter } 128251881Speter 129251881Speter if (rdev->is_atom_bios) 130251881Speter radeon_atombios_encoder_dpms_scratch_regs(encoder, (mode == DRM_MODE_DPMS_ON) ? true : false); 131251881Speter else 132251881Speter radeon_combios_encoder_dpms_scratch_regs(encoder, (mode == DRM_MODE_DPMS_ON) ? true : false); 133251881Speter 134251881Speter} 135251881Speter 136251881Speterstatic void radeon_legacy_lvds_dpms(struct drm_encoder *encoder, int mode) 137251881Speter{ 138251881Speter struct radeon_device *rdev = encoder->dev->dev_private; 139251881Speter struct radeon_encoder *radeon_encoder = to_radeon_encoder(encoder); 140251881Speter DRM_DEBUG("\n"); 141251881Speter 142251881Speter if (radeon_encoder->enc_priv) { 143251881Speter if (rdev->is_atom_bios) { 144251881Speter struct radeon_encoder_atom_dig *lvds = radeon_encoder->enc_priv; 145251881Speter lvds->dpms_mode = mode; 146251881Speter } else { 147251881Speter struct radeon_encoder_lvds *lvds = radeon_encoder->enc_priv; 148251881Speter lvds->dpms_mode = mode; 149251881Speter } 150251881Speter } 151251881Speter 152251881Speter radeon_legacy_lvds_update(encoder, mode); 153251881Speter} 154251881Speter 155251881Speterstatic void radeon_legacy_lvds_prepare(struct drm_encoder *encoder) 156251881Speter{ 157251881Speter struct radeon_device *rdev = encoder->dev->dev_private; 158251881Speter 159251881Speter if (rdev->is_atom_bios) 160251881Speter radeon_atom_output_lock(encoder, true); 161251881Speter else 162251881Speter radeon_combios_output_lock(encoder, true); 163251881Speter radeon_legacy_lvds_dpms(encoder, DRM_MODE_DPMS_OFF); 164251881Speter} 165251881Speter 166251881Speterstatic void radeon_legacy_lvds_commit(struct drm_encoder *encoder) 167251881Speter{ 168251881Speter struct radeon_device *rdev = encoder->dev->dev_private; 169251881Speter 170251881Speter radeon_legacy_lvds_dpms(encoder, DRM_MODE_DPMS_ON); 171251881Speter if (rdev->is_atom_bios) 172251881Speter radeon_atom_output_lock(encoder, false); 173251881Speter else 174251881Speter radeon_combios_output_lock(encoder, false); 175251881Speter} 176251881Speter 177251881Speterstatic void radeon_legacy_lvds_mode_set(struct drm_encoder *encoder, 178251881Speter struct drm_display_mode *mode, 179251881Speter struct drm_display_mode *adjusted_mode) 180251881Speter{ 181251881Speter struct drm_device *dev = encoder->dev; 182251881Speter struct radeon_device *rdev = dev->dev_private; 183251881Speter struct radeon_crtc *radeon_crtc = to_radeon_crtc(encoder->crtc); 184251881Speter struct radeon_encoder *radeon_encoder = to_radeon_encoder(encoder); 185251881Speter uint32_t lvds_pll_cntl, lvds_gen_cntl, lvds_ss_gen_cntl; 186251881Speter 187251881Speter DRM_DEBUG_KMS("\n"); 188251881Speter 189251881Speter lvds_pll_cntl = RREG32(RADEON_LVDS_PLL_CNTL); 190251881Speter lvds_pll_cntl &= ~RADEON_LVDS_PLL_EN; 191251881Speter 192251881Speter lvds_ss_gen_cntl = RREG32(RADEON_LVDS_SS_GEN_CNTL); 193251881Speter if (rdev->is_atom_bios) { 194251881Speter /* LVDS_GEN_CNTL parameters are computed in LVDSEncoderControl 195251881Speter * need to call that on resume to set up the reg properly. 196251881Speter */ 197251881Speter radeon_encoder->pixel_clock = adjusted_mode->clock; 198251881Speter atombios_digital_setup(encoder, PANEL_ENCODER_ACTION_ENABLE); 199251881Speter lvds_gen_cntl = RREG32(RADEON_LVDS_GEN_CNTL); 200251881Speter } else { 201251881Speter struct radeon_encoder_lvds *lvds = (struct radeon_encoder_lvds *)radeon_encoder->enc_priv; 202251881Speter if (lvds) { 203251881Speter DRM_DEBUG_KMS("bios LVDS_GEN_CNTL: 0x%x\n", lvds->lvds_gen_cntl); 204251881Speter lvds_gen_cntl = lvds->lvds_gen_cntl; 205251881Speter lvds_ss_gen_cntl &= ~((0xf << RADEON_LVDS_PWRSEQ_DELAY1_SHIFT) | 206251881Speter (0xf << RADEON_LVDS_PWRSEQ_DELAY2_SHIFT)); 207251881Speter lvds_ss_gen_cntl |= ((lvds->panel_digon_delay << RADEON_LVDS_PWRSEQ_DELAY1_SHIFT) | 208251881Speter (lvds->panel_blon_delay << RADEON_LVDS_PWRSEQ_DELAY2_SHIFT)); 209251881Speter } else 210251881Speter lvds_gen_cntl = RREG32(RADEON_LVDS_GEN_CNTL); 211251881Speter } 212251881Speter lvds_gen_cntl |= RADEON_LVDS_DISPLAY_DIS; 213251881Speter lvds_gen_cntl &= ~(RADEON_LVDS_ON | 214251881Speter RADEON_LVDS_BLON | 215251881Speter RADEON_LVDS_EN | 216251881Speter RADEON_LVDS_RST_FM); 217251881Speter 218251881Speter if (ASIC_IS_R300(rdev)) 219251881Speter lvds_pll_cntl &= ~(R300_LVDS_SRC_SEL_MASK); 220251881Speter 221251881Speter if (radeon_crtc->crtc_id == 0) { 222251881Speter if (ASIC_IS_R300(rdev)) { 223251881Speter if (radeon_encoder->rmx_type != RMX_OFF) 224251881Speter lvds_pll_cntl |= R300_LVDS_SRC_SEL_RMX; 225251881Speter } else 226251881Speter lvds_gen_cntl &= ~RADEON_LVDS_SEL_CRTC2; 227251881Speter } else { 228251881Speter if (ASIC_IS_R300(rdev)) 229251881Speter lvds_pll_cntl |= R300_LVDS_SRC_SEL_CRTC2; 230251881Speter else 231251881Speter lvds_gen_cntl |= RADEON_LVDS_SEL_CRTC2; 232251881Speter } 233251881Speter 234251881Speter WREG32(RADEON_LVDS_GEN_CNTL, lvds_gen_cntl); 235251881Speter WREG32(RADEON_LVDS_PLL_CNTL, lvds_pll_cntl); 236251881Speter WREG32(RADEON_LVDS_SS_GEN_CNTL, lvds_ss_gen_cntl); 237251881Speter 238251881Speter if (rdev->family == CHIP_RV410) 239251881Speter WREG32(RADEON_CLOCK_CNTL_INDEX, 0); 240251881Speter 241251881Speter if (rdev->is_atom_bios) 242251881Speter radeon_atombios_encoder_crtc_scratch_regs(encoder, radeon_crtc->crtc_id); 243251881Speter else 244251881Speter radeon_combios_encoder_crtc_scratch_regs(encoder, radeon_crtc->crtc_id); 245251881Speter} 246251881Speter 247251881Speterstatic bool radeon_legacy_mode_fixup(struct drm_encoder *encoder, 248251881Speter const struct drm_display_mode *mode, 249251881Speter struct drm_display_mode *adjusted_mode) 250251881Speter{ 251251881Speter struct radeon_encoder *radeon_encoder = to_radeon_encoder(encoder); 252251881Speter 253251881Speter /* set the active encoder to connector routing */ 254251881Speter radeon_encoder_set_active_device(encoder); 255251881Speter drm_mode_set_crtcinfo(adjusted_mode, 0); 256251881Speter 257251881Speter /* get the native mode for LVDS */ 258251881Speter if (radeon_encoder->active_device & (ATOM_DEVICE_LCD_SUPPORT)) 259251881Speter radeon_panel_mode_fixup(encoder, adjusted_mode); 260251881Speter 261251881Speter return true; 262251881Speter} 263251881Speter 264251881Speterstatic const struct drm_encoder_helper_funcs radeon_legacy_lvds_helper_funcs = { 265251881Speter .dpms = radeon_legacy_lvds_dpms, 266251881Speter .mode_fixup = radeon_legacy_mode_fixup, 267251881Speter .prepare = radeon_legacy_lvds_prepare, 268251881Speter .mode_set = radeon_legacy_lvds_mode_set, 269251881Speter .commit = radeon_legacy_lvds_commit, 270251881Speter .disable = radeon_legacy_encoder_disable, 271251881Speter}; 272251881Speter 273251881Speteru8 274251881Speterradeon_legacy_get_backlight_level(struct radeon_encoder *radeon_encoder) 275251881Speter{ 276251881Speter struct drm_device *dev = radeon_encoder->base.dev; 277251881Speter struct radeon_device *rdev = dev->dev_private; 278251881Speter u8 backlight_level; 279251881Speter 280251881Speter backlight_level = (RREG32(RADEON_LVDS_GEN_CNTL) >> 281251881Speter RADEON_LVDS_BL_MOD_LEVEL_SHIFT) & 0xff; 282251881Speter 283251881Speter return backlight_level; 284251881Speter} 285251881Speter 286251881Spetervoid 287251881Speterradeon_legacy_set_backlight_level(struct radeon_encoder *radeon_encoder, u8 level) 288251881Speter{ 289251881Speter struct drm_device *dev = radeon_encoder->base.dev; 290251881Speter struct radeon_device *rdev = dev->dev_private; 291251881Speter int dpms_mode = DRM_MODE_DPMS_ON; 292251881Speter 293251881Speter if (radeon_encoder->enc_priv) { 294251881Speter if (rdev->is_atom_bios) { 295251881Speter struct radeon_encoder_atom_dig *lvds = radeon_encoder->enc_priv; 296251881Speter if (lvds->backlight_level > 0) 297251881Speter dpms_mode = lvds->dpms_mode; 298251881Speter else 299251881Speter dpms_mode = DRM_MODE_DPMS_OFF; 300251881Speter lvds->backlight_level = level; 301251881Speter } else { 302251881Speter struct radeon_encoder_lvds *lvds = radeon_encoder->enc_priv; 303251881Speter if (lvds->backlight_level > 0) 304251881Speter dpms_mode = lvds->dpms_mode; 305251881Speter else 306251881Speter dpms_mode = DRM_MODE_DPMS_OFF; 307251881Speter lvds->backlight_level = level; 308251881Speter } 309251881Speter } 310251881Speter 311251881Speter radeon_legacy_lvds_update(&radeon_encoder->base, dpms_mode); 312251881Speter} 313251881Speter 314251881Speter#if defined(CONFIG_BACKLIGHT_CLASS_DEVICE) || defined(CONFIG_BACKLIGHT_CLASS_DEVICE_MODULE) 315251881Speter 316251881Speterstatic uint8_t radeon_legacy_lvds_level(struct backlight_device *bd) 317251881Speter{ 318251881Speter struct radeon_backlight_privdata *pdata = bl_get_data(bd); 319251881Speter uint8_t level; 320251881Speter 321251881Speter /* Convert brightness to hardware level */ 322251881Speter if (bd->props.brightness < 0) 323251881Speter level = 0; 324251881Speter else if (bd->props.brightness > RADEON_MAX_BL_LEVEL) 325251881Speter level = RADEON_MAX_BL_LEVEL; 326251881Speter else 327251881Speter level = bd->props.brightness; 328251881Speter 329251881Speter if (pdata->negative) 330251881Speter level = RADEON_MAX_BL_LEVEL - level; 331251881Speter 332251881Speter return level; 333251881Speter} 334251881Speter 335251881Speterstatic int radeon_legacy_backlight_update_status(struct backlight_device *bd) 336251881Speter{ 337251881Speter struct radeon_backlight_privdata *pdata = bl_get_data(bd); 338251881Speter struct radeon_encoder *radeon_encoder = pdata->encoder; 339251881Speter 340251881Speter radeon_legacy_set_backlight_level(radeon_encoder, 341251881Speter radeon_legacy_lvds_level(bd)); 342251881Speter 343251881Speter return 0; 344251881Speter} 345251881Speter 346251881Speterstatic int radeon_legacy_backlight_get_brightness(struct backlight_device *bd) 347251881Speter{ 348251881Speter struct radeon_backlight_privdata *pdata = bl_get_data(bd); 349251881Speter struct radeon_encoder *radeon_encoder = pdata->encoder; 350251881Speter struct drm_device *dev = radeon_encoder->base.dev; 351251881Speter struct radeon_device *rdev = dev->dev_private; 352251881Speter uint8_t backlight_level; 353251881Speter 354251881Speter backlight_level = (RREG32(RADEON_LVDS_GEN_CNTL) >> 355251881Speter RADEON_LVDS_BL_MOD_LEVEL_SHIFT) & 0xff; 356251881Speter 357251881Speter return pdata->negative ? RADEON_MAX_BL_LEVEL - backlight_level : backlight_level; 358251881Speter} 359251881Speter 360251881Speterstatic const struct backlight_ops radeon_backlight_ops = { 361251881Speter .get_brightness = radeon_legacy_backlight_get_brightness, 362251881Speter .update_status = radeon_legacy_backlight_update_status, 363251881Speter}; 364251881Speter 365251881Spetervoid radeon_legacy_backlight_init(struct radeon_encoder *radeon_encoder, 366251881Speter struct drm_connector *drm_connector) 367251881Speter{ 368251881Speter struct drm_device *dev = radeon_encoder->base.dev; 369251881Speter struct radeon_device *rdev = dev->dev_private; 370251881Speter struct backlight_device *bd; 371251881Speter struct backlight_properties props; 372251881Speter struct radeon_backlight_privdata *pdata; 373251881Speter uint8_t backlight_level; 374251881Speter char bl_name[16]; 375251881Speter 376251881Speter if (!radeon_encoder->enc_priv) 377251881Speter return; 378251881Speter 379251881Speter#ifdef CONFIG_PMAC_BACKLIGHT 380251881Speter if (!pmac_has_backlight_type("ati") && 381251881Speter !pmac_has_backlight_type("mnca")) 382251881Speter return; 383251881Speter#endif 384251881Speter 385251881Speter pdata = malloc(sizeof(struct radeon_backlight_privdata), 386251881Speter DRM_MEM_DRIVER, M_NOWAIT); 387251881Speter if (!pdata) { 388251881Speter DRM_ERROR("Memory allocation failed\n"); 389251881Speter goto error; 390251881Speter } 391251881Speter 392251881Speter memset(&props, 0, sizeof(props)); 393251881Speter props.max_brightness = RADEON_MAX_BL_LEVEL; 394251881Speter props.type = BACKLIGHT_RAW; 395251881Speter snprintf(bl_name, sizeof(bl_name), 396251881Speter "radeon_bl%d", dev->primary->index); 397251881Speter bd = backlight_device_register(bl_name, &drm_connector->kdev, 398251881Speter pdata, &radeon_backlight_ops, &props); 399251881Speter if (IS_ERR(bd)) { 400251881Speter DRM_ERROR("Backlight registration failed\n"); 401251881Speter goto error; 402251881Speter } 403251881Speter 404251881Speter pdata->encoder = radeon_encoder; 405251881Speter 406251881Speter backlight_level = (RREG32(RADEON_LVDS_GEN_CNTL) >> 407251881Speter RADEON_LVDS_BL_MOD_LEVEL_SHIFT) & 0xff; 408251881Speter 409251881Speter /* First, try to detect backlight level sense based on the assumption 410251881Speter * that firmware set it up at full brightness 411251881Speter */ 412251881Speter if (backlight_level == 0) 413251881Speter pdata->negative = true; 414251881Speter else if (backlight_level == 0xff) 415251881Speter pdata->negative = false; 416251881Speter else { 417251881Speter /* XXX hack... maybe some day we can figure out in what direction 418251881Speter * backlight should work on a given panel? 419251881Speter */ 420251881Speter pdata->negative = (rdev->family != CHIP_RV200 && 421251881Speter rdev->family != CHIP_RV250 && 422251881Speter rdev->family != CHIP_RV280 && 423251881Speter rdev->family != CHIP_RV350); 424251881Speter 425251881Speter#ifdef CONFIG_PMAC_BACKLIGHT 426251881Speter pdata->negative = (pdata->negative || 427251881Speter of_machine_is_compatible("PowerBook4,3") || 428251881Speter of_machine_is_compatible("PowerBook6,3") || 429251881Speter of_machine_is_compatible("PowerBook6,5")); 430251881Speter#endif 431251881Speter } 432251881Speter 433251881Speter if (rdev->is_atom_bios) { 434251881Speter struct radeon_encoder_atom_dig *lvds = radeon_encoder->enc_priv; 435251881Speter lvds->bl_dev = bd; 436251881Speter } else { 437251881Speter struct radeon_encoder_lvds *lvds = radeon_encoder->enc_priv; 438251881Speter lvds->bl_dev = bd; 439251881Speter } 440251881Speter 441251881Speter bd->props.brightness = radeon_legacy_backlight_get_brightness(bd); 442251881Speter bd->props.power = FB_BLANK_UNBLANK; 443251881Speter backlight_update_status(bd); 444251881Speter 445251881Speter DRM_INFO("radeon legacy LVDS backlight initialized\n"); 446251881Speter 447251881Speter return; 448251881Speter 449251881Spetererror: 450251881Speter free(pdata, DRM_MEM_DRIVER); 451251881Speter return; 452251881Speter} 453251881Speter 454251881Speterstatic void radeon_legacy_backlight_exit(struct radeon_encoder *radeon_encoder) 455251881Speter{ 456251881Speter struct drm_device *dev = radeon_encoder->base.dev; 457251881Speter struct radeon_device *rdev = dev->dev_private; 458251881Speter struct backlight_device *bd = NULL; 459251881Speter 460251881Speter if (!radeon_encoder->enc_priv) 461251881Speter return; 462251881Speter 463251881Speter if (rdev->is_atom_bios) { 464251881Speter struct radeon_encoder_atom_dig *lvds = radeon_encoder->enc_priv; 465251881Speter bd = lvds->bl_dev; 466251881Speter lvds->bl_dev = NULL; 467251881Speter } else { 468251881Speter struct radeon_encoder_lvds *lvds = radeon_encoder->enc_priv; 469251881Speter bd = lvds->bl_dev; 470251881Speter lvds->bl_dev = NULL; 471251881Speter } 472251881Speter 473251881Speter if (bd) { 474251881Speter struct radeon_backlight_privdata *pdata; 475251881Speter 476251881Speter pdata = bl_get_data(bd); 477251881Speter backlight_device_unregister(bd); 478251881Speter free(pdata, DRM_MEM_DRIVER); 479251881Speter 480251881Speter DRM_INFO("radeon legacy LVDS backlight unloaded\n"); 481251881Speter } 482251881Speter} 483251881Speter 484251881Speter#else /* !CONFIG_BACKLIGHT_CLASS_DEVICE */ 485251881Speter 486251881Spetervoid radeon_legacy_backlight_init(struct radeon_encoder *encoder, 487251881Speter struct drm_connector *drm_connector) 488251881Speter{ 489251881Speter} 490251881Speter 491251881Speterstatic void radeon_legacy_backlight_exit(struct radeon_encoder *encoder) 492251881Speter{ 493251881Speter} 494251881Speter 495251881Speter#endif 496251881Speter 497251881Speter 498251881Speterstatic void radeon_lvds_enc_destroy(struct drm_encoder *encoder) 499251881Speter{ 500251881Speter struct radeon_encoder *radeon_encoder = to_radeon_encoder(encoder); 501251881Speter 502251881Speter if (radeon_encoder->enc_priv) { 503251881Speter radeon_legacy_backlight_exit(radeon_encoder); 504251881Speter free(radeon_encoder->enc_priv, DRM_MEM_DRIVER); 505251881Speter } 506251881Speter drm_encoder_cleanup(encoder); 507251881Speter free(radeon_encoder, DRM_MEM_DRIVER); 508251881Speter} 509251881Speter 510251881Speterstatic const struct drm_encoder_funcs radeon_legacy_lvds_enc_funcs = { 511251881Speter .destroy = radeon_lvds_enc_destroy, 512251881Speter}; 513251881Speter 514251881Speterstatic void radeon_legacy_primary_dac_dpms(struct drm_encoder *encoder, int mode) 515251881Speter{ 516251881Speter struct drm_device *dev = encoder->dev; 517251881Speter struct radeon_device *rdev = dev->dev_private; 518251881Speter uint32_t crtc_ext_cntl = RREG32(RADEON_CRTC_EXT_CNTL); 519251881Speter uint32_t dac_cntl = RREG32(RADEON_DAC_CNTL); 520251881Speter uint32_t dac_macro_cntl = RREG32(RADEON_DAC_MACRO_CNTL); 521251881Speter 522251881Speter DRM_DEBUG_KMS("\n"); 523251881Speter 524251881Speter switch (mode) { 525251881Speter case DRM_MODE_DPMS_ON: 526251881Speter crtc_ext_cntl |= RADEON_CRTC_CRT_ON; 527251881Speter dac_cntl &= ~RADEON_DAC_PDWN; 528251881Speter dac_macro_cntl &= ~(RADEON_DAC_PDWN_R | 529251881Speter RADEON_DAC_PDWN_G | 530251881Speter RADEON_DAC_PDWN_B); 531251881Speter break; 532251881Speter case DRM_MODE_DPMS_STANDBY: 533251881Speter case DRM_MODE_DPMS_SUSPEND: 534251881Speter case DRM_MODE_DPMS_OFF: 535251881Speter crtc_ext_cntl &= ~RADEON_CRTC_CRT_ON; 536251881Speter dac_cntl |= RADEON_DAC_PDWN; 537251881Speter dac_macro_cntl |= (RADEON_DAC_PDWN_R | 538251881Speter RADEON_DAC_PDWN_G | 539251881Speter RADEON_DAC_PDWN_B); 540251881Speter break; 541251881Speter } 542251881Speter 543251881Speter /* handled in radeon_crtc_dpms() */ 544251881Speter if (!(rdev->flags & RADEON_SINGLE_CRTC)) 545251881Speter WREG32(RADEON_CRTC_EXT_CNTL, crtc_ext_cntl); 546251881Speter WREG32(RADEON_DAC_CNTL, dac_cntl); 547251881Speter WREG32(RADEON_DAC_MACRO_CNTL, dac_macro_cntl); 548251881Speter 549251881Speter if (rdev->is_atom_bios) 550251881Speter radeon_atombios_encoder_dpms_scratch_regs(encoder, (mode == DRM_MODE_DPMS_ON) ? true : false); 551251881Speter else 552251881Speter radeon_combios_encoder_dpms_scratch_regs(encoder, (mode == DRM_MODE_DPMS_ON) ? true : false); 553251881Speter 554251881Speter} 555251881Speter 556251881Speterstatic void radeon_legacy_primary_dac_prepare(struct drm_encoder *encoder) 557251881Speter{ 558251881Speter struct radeon_device *rdev = encoder->dev->dev_private; 559251881Speter 560251881Speter if (rdev->is_atom_bios) 561251881Speter radeon_atom_output_lock(encoder, true); 562251881Speter else 563251881Speter radeon_combios_output_lock(encoder, true); 564251881Speter radeon_legacy_primary_dac_dpms(encoder, DRM_MODE_DPMS_OFF); 565251881Speter} 566251881Speter 567251881Speterstatic void radeon_legacy_primary_dac_commit(struct drm_encoder *encoder) 568251881Speter{ 569251881Speter struct radeon_device *rdev = encoder->dev->dev_private; 570251881Speter 571251881Speter radeon_legacy_primary_dac_dpms(encoder, DRM_MODE_DPMS_ON); 572251881Speter 573251881Speter if (rdev->is_atom_bios) 574251881Speter radeon_atom_output_lock(encoder, false); 575251881Speter else 576251881Speter radeon_combios_output_lock(encoder, false); 577251881Speter} 578251881Speter 579251881Speterstatic void radeon_legacy_primary_dac_mode_set(struct drm_encoder *encoder, 580251881Speter struct drm_display_mode *mode, 581251881Speter struct drm_display_mode *adjusted_mode) 582251881Speter{ 583251881Speter struct drm_device *dev = encoder->dev; 584251881Speter struct radeon_device *rdev = dev->dev_private; 585251881Speter struct radeon_crtc *radeon_crtc = to_radeon_crtc(encoder->crtc); 586251881Speter struct radeon_encoder *radeon_encoder = to_radeon_encoder(encoder); 587251881Speter uint32_t disp_output_cntl, dac_cntl, dac2_cntl, dac_macro_cntl; 588251881Speter 589251881Speter DRM_DEBUG_KMS("\n"); 590251881Speter 591251881Speter if (radeon_crtc->crtc_id == 0) { 592251881Speter if (rdev->family == CHIP_R200 || ASIC_IS_R300(rdev)) { 593251881Speter disp_output_cntl = RREG32(RADEON_DISP_OUTPUT_CNTL) & 594251881Speter ~(RADEON_DISP_DAC_SOURCE_MASK); 595251881Speter WREG32(RADEON_DISP_OUTPUT_CNTL, disp_output_cntl); 596251881Speter } else { 597251881Speter dac2_cntl = RREG32(RADEON_DAC_CNTL2) & ~(RADEON_DAC2_DAC_CLK_SEL); 598251881Speter WREG32(RADEON_DAC_CNTL2, dac2_cntl); 599251881Speter } 600251881Speter } else { 601251881Speter if (rdev->family == CHIP_R200 || ASIC_IS_R300(rdev)) { 602251881Speter disp_output_cntl = RREG32(RADEON_DISP_OUTPUT_CNTL) & 603251881Speter ~(RADEON_DISP_DAC_SOURCE_MASK); 604251881Speter disp_output_cntl |= RADEON_DISP_DAC_SOURCE_CRTC2; 605251881Speter WREG32(RADEON_DISP_OUTPUT_CNTL, disp_output_cntl); 606251881Speter } else { 607251881Speter dac2_cntl = RREG32(RADEON_DAC_CNTL2) | RADEON_DAC2_DAC_CLK_SEL; 608251881Speter WREG32(RADEON_DAC_CNTL2, dac2_cntl); 609251881Speter } 610251881Speter } 611251881Speter 612251881Speter dac_cntl = (RADEON_DAC_MASK_ALL | 613251881Speter RADEON_DAC_VGA_ADR_EN | 614251881Speter /* TODO 6-bits */ 615251881Speter RADEON_DAC_8BIT_EN); 616251881Speter 617251881Speter WREG32_P(RADEON_DAC_CNTL, 618251881Speter dac_cntl, 619251881Speter RADEON_DAC_RANGE_CNTL | 620251881Speter RADEON_DAC_BLANKING); 621251881Speter 622251881Speter if (radeon_encoder->enc_priv) { 623251881Speter struct radeon_encoder_primary_dac *p_dac = (struct radeon_encoder_primary_dac *)radeon_encoder->enc_priv; 624251881Speter dac_macro_cntl = p_dac->ps2_pdac_adj; 625251881Speter } else 626251881Speter dac_macro_cntl = RREG32(RADEON_DAC_MACRO_CNTL); 627251881Speter dac_macro_cntl |= RADEON_DAC_PDWN_R | RADEON_DAC_PDWN_G | RADEON_DAC_PDWN_B; 628251881Speter WREG32(RADEON_DAC_MACRO_CNTL, dac_macro_cntl); 629251881Speter 630251881Speter if (rdev->is_atom_bios) 631251881Speter radeon_atombios_encoder_crtc_scratch_regs(encoder, radeon_crtc->crtc_id); 632251881Speter else 633251881Speter radeon_combios_encoder_crtc_scratch_regs(encoder, radeon_crtc->crtc_id); 634251881Speter} 635251881Speter 636251881Speterstatic enum drm_connector_status radeon_legacy_primary_dac_detect(struct drm_encoder *encoder, 637251881Speter struct drm_connector *connector) 638251881Speter{ 639251881Speter struct drm_device *dev = encoder->dev; 640251881Speter struct radeon_device *rdev = dev->dev_private; 641251881Speter uint32_t vclk_ecp_cntl, crtc_ext_cntl; 642251881Speter uint32_t dac_ext_cntl, dac_cntl, dac_macro_cntl, tmp; 643251881Speter enum drm_connector_status found = connector_status_disconnected; 644251881Speter bool color = true; 645251881Speter 646251881Speter /* just don't bother on RN50 those chip are often connected to remoting 647251881Speter * console hw and often we get failure to load detect those. So to make 648251881Speter * everyone happy report the encoder as always connected. 649251881Speter */ 650251881Speter if (ASIC_IS_RN50(rdev)) { 651251881Speter return connector_status_connected; 652251881Speter } 653251881Speter 654251881Speter /* save the regs we need */ 655251881Speter vclk_ecp_cntl = RREG32_PLL(RADEON_VCLK_ECP_CNTL); 656251881Speter crtc_ext_cntl = RREG32(RADEON_CRTC_EXT_CNTL); 657251881Speter dac_ext_cntl = RREG32(RADEON_DAC_EXT_CNTL); 658251881Speter dac_cntl = RREG32(RADEON_DAC_CNTL); 659251881Speter dac_macro_cntl = RREG32(RADEON_DAC_MACRO_CNTL); 660251881Speter 661251881Speter tmp = vclk_ecp_cntl & 662251881Speter ~(RADEON_PIXCLK_ALWAYS_ONb | RADEON_PIXCLK_DAC_ALWAYS_ONb); 663251881Speter WREG32_PLL(RADEON_VCLK_ECP_CNTL, tmp); 664251881Speter 665251881Speter tmp = crtc_ext_cntl | RADEON_CRTC_CRT_ON; 666251881Speter WREG32(RADEON_CRTC_EXT_CNTL, tmp); 667251881Speter 668251881Speter tmp = RADEON_DAC_FORCE_BLANK_OFF_EN | 669251881Speter RADEON_DAC_FORCE_DATA_EN; 670251881Speter 671251881Speter if (color) 672251881Speter tmp |= RADEON_DAC_FORCE_DATA_SEL_RGB; 673251881Speter else 674251881Speter tmp |= RADEON_DAC_FORCE_DATA_SEL_G; 675251881Speter 676251881Speter if (ASIC_IS_R300(rdev)) 677251881Speter tmp |= (0x1b6 << RADEON_DAC_FORCE_DATA_SHIFT); 678251881Speter else if (ASIC_IS_RV100(rdev)) 679251881Speter tmp |= (0x1ac << RADEON_DAC_FORCE_DATA_SHIFT); 680251881Speter else 681251881Speter tmp |= (0x180 << RADEON_DAC_FORCE_DATA_SHIFT); 682251881Speter 683251881Speter WREG32(RADEON_DAC_EXT_CNTL, tmp); 684251881Speter 685251881Speter tmp = dac_cntl & ~(RADEON_DAC_RANGE_CNTL_MASK | RADEON_DAC_PDWN); 686251881Speter tmp |= RADEON_DAC_RANGE_CNTL_PS2 | RADEON_DAC_CMP_EN; 687251881Speter WREG32(RADEON_DAC_CNTL, tmp); 688251881Speter 689251881Speter tmp = dac_macro_cntl; 690251881Speter tmp &= ~(RADEON_DAC_PDWN_R | 691251881Speter RADEON_DAC_PDWN_G | 692251881Speter RADEON_DAC_PDWN_B); 693251881Speter 694251881Speter WREG32(RADEON_DAC_MACRO_CNTL, tmp); 695251881Speter 696251881Speter mdelay(2); 697251881Speter 698251881Speter if (RREG32(RADEON_DAC_CNTL) & RADEON_DAC_CMP_OUTPUT) 699251881Speter found = connector_status_connected; 700251881Speter 701251881Speter /* restore the regs we used */ 702251881Speter WREG32(RADEON_DAC_CNTL, dac_cntl); 703251881Speter WREG32(RADEON_DAC_MACRO_CNTL, dac_macro_cntl); 704251881Speter WREG32(RADEON_DAC_EXT_CNTL, dac_ext_cntl); 705251881Speter WREG32(RADEON_CRTC_EXT_CNTL, crtc_ext_cntl); 706251881Speter WREG32_PLL(RADEON_VCLK_ECP_CNTL, vclk_ecp_cntl); 707251881Speter 708251881Speter return found; 709251881Speter} 710251881Speter 711251881Speterstatic const struct drm_encoder_helper_funcs radeon_legacy_primary_dac_helper_funcs = { 712251881Speter .dpms = radeon_legacy_primary_dac_dpms, 713251881Speter .mode_fixup = radeon_legacy_mode_fixup, 714251881Speter .prepare = radeon_legacy_primary_dac_prepare, 715251881Speter .mode_set = radeon_legacy_primary_dac_mode_set, 716251881Speter .commit = radeon_legacy_primary_dac_commit, 717251881Speter .detect = radeon_legacy_primary_dac_detect, 718251881Speter .disable = radeon_legacy_encoder_disable, 719251881Speter}; 720251881Speter 721251881Speter 722251881Speterstatic const struct drm_encoder_funcs radeon_legacy_primary_dac_enc_funcs = { 723251881Speter .destroy = radeon_enc_destroy, 724251881Speter}; 725251881Speter 726251881Speterstatic void radeon_legacy_tmds_int_dpms(struct drm_encoder *encoder, int mode) 727251881Speter{ 728251881Speter struct drm_device *dev = encoder->dev; 729251881Speter struct radeon_device *rdev = dev->dev_private; 730251881Speter uint32_t fp_gen_cntl = RREG32(RADEON_FP_GEN_CNTL); 731251881Speter DRM_DEBUG_KMS("\n"); 732251881Speter 733251881Speter switch (mode) { 734251881Speter case DRM_MODE_DPMS_ON: 735251881Speter fp_gen_cntl |= (RADEON_FP_FPON | RADEON_FP_TMDS_EN); 736251881Speter break; 737251881Speter case DRM_MODE_DPMS_STANDBY: 738251881Speter case DRM_MODE_DPMS_SUSPEND: 739251881Speter case DRM_MODE_DPMS_OFF: 740251881Speter fp_gen_cntl &= ~(RADEON_FP_FPON | RADEON_FP_TMDS_EN); 741251881Speter break; 742251881Speter } 743251881Speter 744251881Speter WREG32(RADEON_FP_GEN_CNTL, fp_gen_cntl); 745251881Speter 746251881Speter if (rdev->is_atom_bios) 747251881Speter radeon_atombios_encoder_dpms_scratch_regs(encoder, (mode == DRM_MODE_DPMS_ON) ? true : false); 748251881Speter else 749251881Speter radeon_combios_encoder_dpms_scratch_regs(encoder, (mode == DRM_MODE_DPMS_ON) ? true : false); 750251881Speter 751251881Speter} 752251881Speter 753251881Speterstatic void radeon_legacy_tmds_int_prepare(struct drm_encoder *encoder) 754251881Speter{ 755251881Speter struct radeon_device *rdev = encoder->dev->dev_private; 756251881Speter 757251881Speter if (rdev->is_atom_bios) 758251881Speter radeon_atom_output_lock(encoder, true); 759251881Speter else 760251881Speter radeon_combios_output_lock(encoder, true); 761251881Speter radeon_legacy_tmds_int_dpms(encoder, DRM_MODE_DPMS_OFF); 762251881Speter} 763251881Speter 764251881Speterstatic void radeon_legacy_tmds_int_commit(struct drm_encoder *encoder) 765251881Speter{ 766251881Speter struct radeon_device *rdev = encoder->dev->dev_private; 767251881Speter 768251881Speter radeon_legacy_tmds_int_dpms(encoder, DRM_MODE_DPMS_ON); 769251881Speter 770251881Speter if (rdev->is_atom_bios) 771251881Speter radeon_atom_output_lock(encoder, true); 772251881Speter else 773251881Speter radeon_combios_output_lock(encoder, true); 774251881Speter} 775251881Speter 776251881Speterstatic void radeon_legacy_tmds_int_mode_set(struct drm_encoder *encoder, 777251881Speter struct drm_display_mode *mode, 778251881Speter struct drm_display_mode *adjusted_mode) 779251881Speter{ 780251881Speter struct drm_device *dev = encoder->dev; 781251881Speter struct radeon_device *rdev = dev->dev_private; 782251881Speter struct radeon_crtc *radeon_crtc = to_radeon_crtc(encoder->crtc); 783251881Speter struct radeon_encoder *radeon_encoder = to_radeon_encoder(encoder); 784251881Speter uint32_t tmp, tmds_pll_cntl, tmds_transmitter_cntl, fp_gen_cntl; 785251881Speter int i; 786251881Speter 787251881Speter DRM_DEBUG_KMS("\n"); 788251881Speter 789251881Speter tmp = tmds_pll_cntl = RREG32(RADEON_TMDS_PLL_CNTL); 790251881Speter tmp &= 0xfffff; 791251881Speter if (rdev->family == CHIP_RV280) { 792251881Speter /* bit 22 of TMDS_PLL_CNTL is read-back inverted */ 793251881Speter tmp ^= (1 << 22); 794251881Speter tmds_pll_cntl ^= (1 << 22); 795251881Speter } 796251881Speter 797251881Speter if (radeon_encoder->enc_priv) { 798251881Speter struct radeon_encoder_int_tmds *tmds = (struct radeon_encoder_int_tmds *)radeon_encoder->enc_priv; 799251881Speter 800251881Speter for (i = 0; i < 4; i++) { 801251881Speter if (tmds->tmds_pll[i].freq == 0) 802251881Speter break; 803251881Speter if ((uint32_t)(mode->clock / 10) < tmds->tmds_pll[i].freq) { 804251881Speter tmp = tmds->tmds_pll[i].value ; 805251881Speter break; 806251881Speter } 807251881Speter } 808251881Speter } 809251881Speter 810251881Speter if (ASIC_IS_R300(rdev) || (rdev->family == CHIP_RV280)) { 811251881Speter if (tmp & 0xfff00000) 812251881Speter tmds_pll_cntl = tmp; 813251881Speter else { 814251881Speter tmds_pll_cntl &= 0xfff00000; 815251881Speter tmds_pll_cntl |= tmp; 816251881Speter } 817251881Speter } else 818251881Speter tmds_pll_cntl = tmp; 819251881Speter 820251881Speter tmds_transmitter_cntl = RREG32(RADEON_TMDS_TRANSMITTER_CNTL) & 821251881Speter ~(RADEON_TMDS_TRANSMITTER_PLLRST); 822251881Speter 823251881Speter if (rdev->family == CHIP_R200 || 824251881Speter rdev->family == CHIP_R100 || 825251881Speter ASIC_IS_R300(rdev)) 826251881Speter tmds_transmitter_cntl &= ~(RADEON_TMDS_TRANSMITTER_PLLEN); 827251881Speter else /* RV chips got this bit reversed */ 828251881Speter tmds_transmitter_cntl |= RADEON_TMDS_TRANSMITTER_PLLEN; 829251881Speter 830251881Speter fp_gen_cntl = (RREG32(RADEON_FP_GEN_CNTL) | 831251881Speter (RADEON_FP_CRTC_DONT_SHADOW_VPAR | 832251881Speter RADEON_FP_CRTC_DONT_SHADOW_HEND)); 833251881Speter 834251881Speter fp_gen_cntl &= ~(RADEON_FP_FPON | RADEON_FP_TMDS_EN); 835251881Speter 836251881Speter fp_gen_cntl &= ~(RADEON_FP_RMX_HVSYNC_CONTROL_EN | 837251881Speter RADEON_FP_DFP_SYNC_SEL | 838251881Speter RADEON_FP_CRT_SYNC_SEL | 839251881Speter RADEON_FP_CRTC_LOCK_8DOT | 840251881Speter RADEON_FP_USE_SHADOW_EN | 841251881Speter RADEON_FP_CRTC_USE_SHADOW_VEND | 842251881Speter RADEON_FP_CRT_SYNC_ALT); 843251881Speter 844251881Speter if (1) /* FIXME rgbBits == 8 */ 845251881Speter fp_gen_cntl |= RADEON_FP_PANEL_FORMAT; /* 24 bit format */ 846251881Speter else 847251881Speter fp_gen_cntl &= ~RADEON_FP_PANEL_FORMAT;/* 18 bit format */ 848251881Speter 849251881Speter if (radeon_crtc->crtc_id == 0) { 850251881Speter if (ASIC_IS_R300(rdev) || rdev->family == CHIP_R200) { 851251881Speter fp_gen_cntl &= ~R200_FP_SOURCE_SEL_MASK; 852251881Speter if (radeon_encoder->rmx_type != RMX_OFF) 853251881Speter fp_gen_cntl |= R200_FP_SOURCE_SEL_RMX; 854251881Speter else 855251881Speter fp_gen_cntl |= R200_FP_SOURCE_SEL_CRTC1; 856251881Speter } else 857251881Speter fp_gen_cntl &= ~RADEON_FP_SEL_CRTC2; 858251881Speter } else { 859251881Speter if (ASIC_IS_R300(rdev) || rdev->family == CHIP_R200) { 860251881Speter fp_gen_cntl &= ~R200_FP_SOURCE_SEL_MASK; 861251881Speter fp_gen_cntl |= R200_FP_SOURCE_SEL_CRTC2; 862251881Speter } else 863251881Speter fp_gen_cntl |= RADEON_FP_SEL_CRTC2; 864251881Speter } 865251881Speter 866251881Speter WREG32(RADEON_TMDS_PLL_CNTL, tmds_pll_cntl); 867251881Speter WREG32(RADEON_TMDS_TRANSMITTER_CNTL, tmds_transmitter_cntl); 868251881Speter WREG32(RADEON_FP_GEN_CNTL, fp_gen_cntl); 869251881Speter 870251881Speter if (rdev->is_atom_bios) 871251881Speter radeon_atombios_encoder_crtc_scratch_regs(encoder, radeon_crtc->crtc_id); 872251881Speter else 873251881Speter radeon_combios_encoder_crtc_scratch_regs(encoder, radeon_crtc->crtc_id); 874251881Speter} 875251881Speter 876251881Speterstatic const struct drm_encoder_helper_funcs radeon_legacy_tmds_int_helper_funcs = { 877251881Speter .dpms = radeon_legacy_tmds_int_dpms, 878251881Speter .mode_fixup = radeon_legacy_mode_fixup, 879251881Speter .prepare = radeon_legacy_tmds_int_prepare, 880251881Speter .mode_set = radeon_legacy_tmds_int_mode_set, 881251881Speter .commit = radeon_legacy_tmds_int_commit, 882251881Speter .disable = radeon_legacy_encoder_disable, 883251881Speter}; 884251881Speter 885251881Speter 886251881Speterstatic const struct drm_encoder_funcs radeon_legacy_tmds_int_enc_funcs = { 887251881Speter .destroy = radeon_enc_destroy, 888251881Speter}; 889251881Speter 890251881Speterstatic void radeon_legacy_tmds_ext_dpms(struct drm_encoder *encoder, int mode) 891251881Speter{ 892251881Speter struct drm_device *dev = encoder->dev; 893251881Speter struct radeon_device *rdev = dev->dev_private; 894251881Speter uint32_t fp2_gen_cntl = RREG32(RADEON_FP2_GEN_CNTL); 895251881Speter DRM_DEBUG_KMS("\n"); 896251881Speter 897251881Speter switch (mode) { 898251881Speter case DRM_MODE_DPMS_ON: 899251881Speter fp2_gen_cntl &= ~RADEON_FP2_BLANK_EN; 900251881Speter fp2_gen_cntl |= (RADEON_FP2_ON | RADEON_FP2_DVO_EN); 901251881Speter break; 902251881Speter case DRM_MODE_DPMS_STANDBY: 903251881Speter case DRM_MODE_DPMS_SUSPEND: 904251881Speter case DRM_MODE_DPMS_OFF: 905251881Speter fp2_gen_cntl |= RADEON_FP2_BLANK_EN; 906251881Speter fp2_gen_cntl &= ~(RADEON_FP2_ON | RADEON_FP2_DVO_EN); 907251881Speter break; 908251881Speter } 909251881Speter 910251881Speter WREG32(RADEON_FP2_GEN_CNTL, fp2_gen_cntl); 911251881Speter 912251881Speter if (rdev->is_atom_bios) 913251881Speter radeon_atombios_encoder_dpms_scratch_regs(encoder, (mode == DRM_MODE_DPMS_ON) ? true : false); 914251881Speter else 915251881Speter radeon_combios_encoder_dpms_scratch_regs(encoder, (mode == DRM_MODE_DPMS_ON) ? true : false); 916251881Speter 917251881Speter} 918251881Speter 919251881Speterstatic void radeon_legacy_tmds_ext_prepare(struct drm_encoder *encoder) 920251881Speter{ 921251881Speter struct radeon_device *rdev = encoder->dev->dev_private; 922251881Speter 923251881Speter if (rdev->is_atom_bios) 924251881Speter radeon_atom_output_lock(encoder, true); 925251881Speter else 926251881Speter radeon_combios_output_lock(encoder, true); 927251881Speter radeon_legacy_tmds_ext_dpms(encoder, DRM_MODE_DPMS_OFF); 928251881Speter} 929251881Speter 930251881Speterstatic void radeon_legacy_tmds_ext_commit(struct drm_encoder *encoder) 931251881Speter{ 932251881Speter struct radeon_device *rdev = encoder->dev->dev_private; 933251881Speter radeon_legacy_tmds_ext_dpms(encoder, DRM_MODE_DPMS_ON); 934251881Speter 935251881Speter if (rdev->is_atom_bios) 936251881Speter radeon_atom_output_lock(encoder, false); 937251881Speter else 938251881Speter radeon_combios_output_lock(encoder, false); 939251881Speter} 940251881Speter 941251881Speterstatic void radeon_legacy_tmds_ext_mode_set(struct drm_encoder *encoder, 942251881Speter struct drm_display_mode *mode, 943251881Speter struct drm_display_mode *adjusted_mode) 944251881Speter{ 945251881Speter struct drm_device *dev = encoder->dev; 946251881Speter struct radeon_device *rdev = dev->dev_private; 947251881Speter struct radeon_crtc *radeon_crtc = to_radeon_crtc(encoder->crtc); 948251881Speter struct radeon_encoder *radeon_encoder = to_radeon_encoder(encoder); 949251881Speter uint32_t fp2_gen_cntl; 950251881Speter 951251881Speter DRM_DEBUG_KMS("\n"); 952251881Speter 953251881Speter if (rdev->is_atom_bios) { 954251881Speter radeon_encoder->pixel_clock = adjusted_mode->clock; 955251881Speter atombios_dvo_setup(encoder, ATOM_ENABLE); 956251881Speter fp2_gen_cntl = RREG32(RADEON_FP2_GEN_CNTL); 957251881Speter } else { 958251881Speter fp2_gen_cntl = RREG32(RADEON_FP2_GEN_CNTL); 959251881Speter 960251881Speter if (1) /* FIXME rgbBits == 8 */ 961251881Speter fp2_gen_cntl |= RADEON_FP2_PANEL_FORMAT; /* 24 bit format, */ 962251881Speter else 963251881Speter fp2_gen_cntl &= ~RADEON_FP2_PANEL_FORMAT;/* 18 bit format, */ 964251881Speter 965251881Speter fp2_gen_cntl &= ~(RADEON_FP2_ON | 966251881Speter RADEON_FP2_DVO_EN | 967251881Speter RADEON_FP2_DVO_RATE_SEL_SDR); 968251881Speter 969251881Speter /* XXX: these are oem specific */ 970251881Speter if (ASIC_IS_R300(rdev)) { 971251881Speter if ((dev->pci_device == 0x4850) && 972251881Speter (dev->pci_subvendor == 0x1028) && 973251881Speter (dev->pci_subdevice == 0x2001)) /* Dell Inspiron 8600 */ 974251881Speter fp2_gen_cntl |= R300_FP2_DVO_CLOCK_MODE_SINGLE; 975251881Speter else 976251881Speter fp2_gen_cntl |= RADEON_FP2_PAD_FLOP_EN | R300_FP2_DVO_CLOCK_MODE_SINGLE; 977251881Speter 978251881Speter /*if (mode->clock > 165000) 979251881Speter fp2_gen_cntl |= R300_FP2_DVO_DUAL_CHANNEL_EN;*/ 980251881Speter } 981251881Speter if (!radeon_combios_external_tmds_setup(encoder)) 982251881Speter radeon_external_tmds_setup(encoder); 983251881Speter } 984251881Speter 985251881Speter if (radeon_crtc->crtc_id == 0) { 986251881Speter if ((rdev->family == CHIP_R200) || ASIC_IS_R300(rdev)) { 987251881Speter fp2_gen_cntl &= ~R200_FP2_SOURCE_SEL_MASK; 988251881Speter if (radeon_encoder->rmx_type != RMX_OFF) 989251881Speter fp2_gen_cntl |= R200_FP2_SOURCE_SEL_RMX; 990251881Speter else 991251881Speter fp2_gen_cntl |= R200_FP2_SOURCE_SEL_CRTC1; 992251881Speter } else 993251881Speter fp2_gen_cntl &= ~RADEON_FP2_SRC_SEL_CRTC2; 994251881Speter } else { 995251881Speter if ((rdev->family == CHIP_R200) || ASIC_IS_R300(rdev)) { 996251881Speter fp2_gen_cntl &= ~R200_FP2_SOURCE_SEL_MASK; 997251881Speter fp2_gen_cntl |= R200_FP2_SOURCE_SEL_CRTC2; 998251881Speter } else 999251881Speter fp2_gen_cntl |= RADEON_FP2_SRC_SEL_CRTC2; 1000251881Speter } 1001251881Speter 1002251881Speter WREG32(RADEON_FP2_GEN_CNTL, fp2_gen_cntl); 1003251881Speter 1004251881Speter if (rdev->is_atom_bios) 1005251881Speter radeon_atombios_encoder_crtc_scratch_regs(encoder, radeon_crtc->crtc_id); 1006251881Speter else 1007251881Speter radeon_combios_encoder_crtc_scratch_regs(encoder, radeon_crtc->crtc_id); 1008251881Speter} 1009251881Speter 1010251881Speterstatic void radeon_ext_tmds_enc_destroy(struct drm_encoder *encoder) 1011251881Speter{ 1012251881Speter struct radeon_encoder *radeon_encoder = to_radeon_encoder(encoder); 1013251881Speter /* don't destroy the i2c bus record here, this will be done in radeon_i2c_fini */ 1014251881Speter free(radeon_encoder->enc_priv, DRM_MEM_DRIVER); 1015251881Speter drm_encoder_cleanup(encoder); 1016251881Speter free(radeon_encoder, DRM_MEM_DRIVER); 1017251881Speter} 1018251881Speter 1019251881Speterstatic const struct drm_encoder_helper_funcs radeon_legacy_tmds_ext_helper_funcs = { 1020251881Speter .dpms = radeon_legacy_tmds_ext_dpms, 1021251881Speter .mode_fixup = radeon_legacy_mode_fixup, 1022251881Speter .prepare = radeon_legacy_tmds_ext_prepare, 1023251881Speter .mode_set = radeon_legacy_tmds_ext_mode_set, 1024251881Speter .commit = radeon_legacy_tmds_ext_commit, 1025251881Speter .disable = radeon_legacy_encoder_disable, 1026251881Speter}; 1027251881Speter 1028251881Speter 1029251881Speterstatic const struct drm_encoder_funcs radeon_legacy_tmds_ext_enc_funcs = { 1030251881Speter .destroy = radeon_ext_tmds_enc_destroy, 1031251881Speter}; 1032251881Speter 1033251881Speterstatic void radeon_legacy_tv_dac_dpms(struct drm_encoder *encoder, int mode) 1034251881Speter{ 1035251881Speter struct drm_device *dev = encoder->dev; 1036251881Speter struct radeon_device *rdev = dev->dev_private; 1037251881Speter struct radeon_encoder *radeon_encoder = to_radeon_encoder(encoder); 1038251881Speter uint32_t fp2_gen_cntl = 0, crtc2_gen_cntl = 0, tv_dac_cntl = 0; 1039251881Speter uint32_t tv_master_cntl = 0; 1040251881Speter bool is_tv; 1041251881Speter DRM_DEBUG_KMS("\n"); 1042251881Speter 1043251881Speter is_tv = radeon_encoder->active_device & ATOM_DEVICE_TV_SUPPORT ? true : false; 1044251881Speter 1045251881Speter if (rdev->family == CHIP_R200) 1046251881Speter fp2_gen_cntl = RREG32(RADEON_FP2_GEN_CNTL); 1047251881Speter else { 1048251881Speter if (is_tv) 1049251881Speter tv_master_cntl = RREG32(RADEON_TV_MASTER_CNTL); 1050251881Speter else 1051251881Speter crtc2_gen_cntl = RREG32(RADEON_CRTC2_GEN_CNTL); 1052251881Speter tv_dac_cntl = RREG32(RADEON_TV_DAC_CNTL); 1053251881Speter } 1054251881Speter 1055251881Speter switch (mode) { 1056251881Speter case DRM_MODE_DPMS_ON: 1057251881Speter if (rdev->family == CHIP_R200) { 1058251881Speter fp2_gen_cntl |= (RADEON_FP2_ON | RADEON_FP2_DVO_EN); 1059251881Speter } else { 1060251881Speter if (is_tv) 1061251881Speter tv_master_cntl |= RADEON_TV_ON; 1062251881Speter else 1063251881Speter crtc2_gen_cntl |= RADEON_CRTC2_CRT2_ON; 1064251881Speter 1065251881Speter if (rdev->family == CHIP_R420 || 1066251881Speter rdev->family == CHIP_R423 || 1067251881Speter rdev->family == CHIP_RV410) 1068251881Speter tv_dac_cntl &= ~(R420_TV_DAC_RDACPD | 1069251881Speter R420_TV_DAC_GDACPD | 1070251881Speter R420_TV_DAC_BDACPD | 1071251881Speter RADEON_TV_DAC_BGSLEEP); 1072251881Speter else 1073251881Speter tv_dac_cntl &= ~(RADEON_TV_DAC_RDACPD | 1074251881Speter RADEON_TV_DAC_GDACPD | 1075251881Speter RADEON_TV_DAC_BDACPD | 1076251881Speter RADEON_TV_DAC_BGSLEEP); 1077251881Speter } 1078251881Speter break; 1079251881Speter case DRM_MODE_DPMS_STANDBY: 1080251881Speter case DRM_MODE_DPMS_SUSPEND: 1081251881Speter case DRM_MODE_DPMS_OFF: 1082251881Speter if (rdev->family == CHIP_R200) 1083251881Speter fp2_gen_cntl &= ~(RADEON_FP2_ON | RADEON_FP2_DVO_EN); 1084251881Speter else { 1085251881Speter if (is_tv) 1086251881Speter tv_master_cntl &= ~RADEON_TV_ON; 1087251881Speter else 1088251881Speter crtc2_gen_cntl &= ~RADEON_CRTC2_CRT2_ON; 1089251881Speter 1090251881Speter if (rdev->family == CHIP_R420 || 1091251881Speter rdev->family == CHIP_R423 || 1092251881Speter rdev->family == CHIP_RV410) 1093251881Speter tv_dac_cntl |= (R420_TV_DAC_RDACPD | 1094251881Speter R420_TV_DAC_GDACPD | 1095251881Speter R420_TV_DAC_BDACPD | 1096251881Speter RADEON_TV_DAC_BGSLEEP); 1097251881Speter else 1098251881Speter tv_dac_cntl |= (RADEON_TV_DAC_RDACPD | 1099251881Speter RADEON_TV_DAC_GDACPD | 1100251881Speter RADEON_TV_DAC_BDACPD | 1101251881Speter RADEON_TV_DAC_BGSLEEP); 1102251881Speter } 1103251881Speter break; 1104251881Speter } 1105251881Speter 1106251881Speter if (rdev->family == CHIP_R200) { 1107251881Speter WREG32(RADEON_FP2_GEN_CNTL, fp2_gen_cntl); 1108251881Speter } else { 1109251881Speter if (is_tv) 1110251881Speter WREG32(RADEON_TV_MASTER_CNTL, tv_master_cntl); 1111251881Speter /* handled in radeon_crtc_dpms() */ 1112251881Speter else if (!(rdev->flags & RADEON_SINGLE_CRTC)) 1113251881Speter WREG32(RADEON_CRTC2_GEN_CNTL, crtc2_gen_cntl); 1114251881Speter WREG32(RADEON_TV_DAC_CNTL, tv_dac_cntl); 1115251881Speter } 1116251881Speter 1117251881Speter if (rdev->is_atom_bios) 1118251881Speter radeon_atombios_encoder_dpms_scratch_regs(encoder, (mode == DRM_MODE_DPMS_ON) ? true : false); 1119251881Speter else 1120251881Speter radeon_combios_encoder_dpms_scratch_regs(encoder, (mode == DRM_MODE_DPMS_ON) ? true : false); 1121251881Speter 1122251881Speter} 1123251881Speter 1124251881Speterstatic void radeon_legacy_tv_dac_prepare(struct drm_encoder *encoder) 1125251881Speter{ 1126251881Speter struct radeon_device *rdev = encoder->dev->dev_private; 1127251881Speter 1128251881Speter if (rdev->is_atom_bios) 1129251881Speter radeon_atom_output_lock(encoder, true); 1130251881Speter else 1131251881Speter radeon_combios_output_lock(encoder, true); 1132251881Speter radeon_legacy_tv_dac_dpms(encoder, DRM_MODE_DPMS_OFF); 1133251881Speter} 1134251881Speter 1135251881Speterstatic void radeon_legacy_tv_dac_commit(struct drm_encoder *encoder) 1136251881Speter{ 1137251881Speter struct radeon_device *rdev = encoder->dev->dev_private; 1138251881Speter 1139251881Speter radeon_legacy_tv_dac_dpms(encoder, DRM_MODE_DPMS_ON); 1140251881Speter 1141251881Speter if (rdev->is_atom_bios) 1142251881Speter radeon_atom_output_lock(encoder, true); 1143251881Speter else 1144251881Speter radeon_combios_output_lock(encoder, true); 1145251881Speter} 1146251881Speter 1147251881Speterstatic void radeon_legacy_tv_dac_mode_set(struct drm_encoder *encoder, 1148251881Speter struct drm_display_mode *mode, 1149251881Speter struct drm_display_mode *adjusted_mode) 1150251881Speter{ 1151251881Speter struct drm_device *dev = encoder->dev; 1152251881Speter struct radeon_device *rdev = dev->dev_private; 1153251881Speter struct radeon_crtc *radeon_crtc = to_radeon_crtc(encoder->crtc); 1154251881Speter struct radeon_encoder *radeon_encoder = to_radeon_encoder(encoder); 1155251881Speter struct radeon_encoder_tv_dac *tv_dac = radeon_encoder->enc_priv; 1156251881Speter uint32_t tv_dac_cntl, gpiopad_a = 0, dac2_cntl, disp_output_cntl = 0; 1157251881Speter uint32_t disp_hw_debug = 0, fp2_gen_cntl = 0, disp_tv_out_cntl = 0; 1158251881Speter bool is_tv = false; 1159251881Speter 1160251881Speter DRM_DEBUG_KMS("\n"); 1161251881Speter 1162251881Speter is_tv = radeon_encoder->active_device & ATOM_DEVICE_TV_SUPPORT ? true : false; 1163251881Speter 1164251881Speter if (rdev->family != CHIP_R200) { 1165251881Speter tv_dac_cntl = RREG32(RADEON_TV_DAC_CNTL); 1166251881Speter if (rdev->family == CHIP_R420 || 1167251881Speter rdev->family == CHIP_R423 || 1168251881Speter rdev->family == CHIP_RV410) { 1169251881Speter tv_dac_cntl &= ~(RADEON_TV_DAC_STD_MASK | 1170251881Speter RADEON_TV_DAC_BGADJ_MASK | 1171251881Speter R420_TV_DAC_DACADJ_MASK | 1172251881Speter R420_TV_DAC_RDACPD | 1173251881Speter R420_TV_DAC_GDACPD | 1174251881Speter R420_TV_DAC_BDACPD | 1175251881Speter R420_TV_DAC_TVENABLE); 1176251881Speter } else { 1177251881Speter tv_dac_cntl &= ~(RADEON_TV_DAC_STD_MASK | 1178251881Speter RADEON_TV_DAC_BGADJ_MASK | 1179251881Speter RADEON_TV_DAC_DACADJ_MASK | 1180251881Speter RADEON_TV_DAC_RDACPD | 1181251881Speter RADEON_TV_DAC_GDACPD | 1182251881Speter RADEON_TV_DAC_BDACPD); 1183251881Speter } 1184251881Speter 1185251881Speter tv_dac_cntl |= RADEON_TV_DAC_NBLANK | RADEON_TV_DAC_NHOLD; 1186251881Speter 1187251881Speter if (is_tv) { 1188251881Speter if (tv_dac->tv_std == TV_STD_NTSC || 1189251881Speter tv_dac->tv_std == TV_STD_NTSC_J || 1190251881Speter tv_dac->tv_std == TV_STD_PAL_M || 1191251881Speter tv_dac->tv_std == TV_STD_PAL_60) 1192251881Speter tv_dac_cntl |= tv_dac->ntsc_tvdac_adj; 1193251881Speter else 1194251881Speter tv_dac_cntl |= tv_dac->pal_tvdac_adj; 1195251881Speter 1196251881Speter if (tv_dac->tv_std == TV_STD_NTSC || 1197251881Speter tv_dac->tv_std == TV_STD_NTSC_J) 1198251881Speter tv_dac_cntl |= RADEON_TV_DAC_STD_NTSC; 1199251881Speter else 1200251881Speter tv_dac_cntl |= RADEON_TV_DAC_STD_PAL; 1201251881Speter } else 1202251881Speter tv_dac_cntl |= (RADEON_TV_DAC_STD_PS2 | 1203251881Speter tv_dac->ps2_tvdac_adj); 1204251881Speter 1205251881Speter WREG32(RADEON_TV_DAC_CNTL, tv_dac_cntl); 1206251881Speter } 1207251881Speter 1208251881Speter if (ASIC_IS_R300(rdev)) { 1209251881Speter gpiopad_a = RREG32(RADEON_GPIOPAD_A) | 1; 1210251881Speter disp_output_cntl = RREG32(RADEON_DISP_OUTPUT_CNTL); 1211251881Speter } else if (rdev->family != CHIP_R200) 1212251881Speter disp_hw_debug = RREG32(RADEON_DISP_HW_DEBUG); 1213251881Speter else if (rdev->family == CHIP_R200) 1214251881Speter fp2_gen_cntl = RREG32(RADEON_FP2_GEN_CNTL); 1215251881Speter 1216251881Speter if (rdev->family >= CHIP_R200) 1217251881Speter disp_tv_out_cntl = RREG32(RADEON_DISP_TV_OUT_CNTL); 1218251881Speter 1219251881Speter if (is_tv) { 1220251881Speter uint32_t dac_cntl; 1221251881Speter 1222251881Speter dac_cntl = RREG32(RADEON_DAC_CNTL); 1223251881Speter dac_cntl &= ~RADEON_DAC_TVO_EN; 1224251881Speter WREG32(RADEON_DAC_CNTL, dac_cntl); 1225251881Speter 1226251881Speter if (ASIC_IS_R300(rdev)) 1227251881Speter gpiopad_a = RREG32(RADEON_GPIOPAD_A) & ~1; 1228251881Speter 1229251881Speter dac2_cntl = RREG32(RADEON_DAC_CNTL2) & ~RADEON_DAC2_DAC2_CLK_SEL; 1230251881Speter if (radeon_crtc->crtc_id == 0) { 1231251881Speter if (ASIC_IS_R300(rdev)) { 1232251881Speter disp_output_cntl &= ~RADEON_DISP_TVDAC_SOURCE_MASK; 1233251881Speter disp_output_cntl |= (RADEON_DISP_TVDAC_SOURCE_CRTC | 1234251881Speter RADEON_DISP_TV_SOURCE_CRTC); 1235251881Speter } 1236251881Speter if (rdev->family >= CHIP_R200) { 1237251881Speter disp_tv_out_cntl &= ~RADEON_DISP_TV_PATH_SRC_CRTC2; 1238251881Speter } else { 1239251881Speter disp_hw_debug |= RADEON_CRT2_DISP1_SEL; 1240251881Speter } 1241251881Speter } else { 1242251881Speter if (ASIC_IS_R300(rdev)) { 1243251881Speter disp_output_cntl &= ~RADEON_DISP_TVDAC_SOURCE_MASK; 1244251881Speter disp_output_cntl |= RADEON_DISP_TV_SOURCE_CRTC; 1245251881Speter } 1246251881Speter if (rdev->family >= CHIP_R200) { 1247251881Speter disp_tv_out_cntl |= RADEON_DISP_TV_PATH_SRC_CRTC2; 1248251881Speter } else { 1249251881Speter disp_hw_debug &= ~RADEON_CRT2_DISP1_SEL; 1250251881Speter } 1251251881Speter } 1252251881Speter WREG32(RADEON_DAC_CNTL2, dac2_cntl); 1253251881Speter } else { 1254251881Speter 1255251881Speter dac2_cntl = RREG32(RADEON_DAC_CNTL2) | RADEON_DAC2_DAC2_CLK_SEL; 1256251881Speter 1257251881Speter if (radeon_crtc->crtc_id == 0) { 1258251881Speter if (ASIC_IS_R300(rdev)) { 1259251881Speter disp_output_cntl &= ~RADEON_DISP_TVDAC_SOURCE_MASK; 1260251881Speter disp_output_cntl |= RADEON_DISP_TVDAC_SOURCE_CRTC; 1261251881Speter } else if (rdev->family == CHIP_R200) { 1262251881Speter fp2_gen_cntl &= ~(R200_FP2_SOURCE_SEL_MASK | 1263251881Speter RADEON_FP2_DVO_RATE_SEL_SDR); 1264251881Speter } else 1265251881Speter disp_hw_debug |= RADEON_CRT2_DISP1_SEL; 1266251881Speter } else { 1267251881Speter if (ASIC_IS_R300(rdev)) { 1268251881Speter disp_output_cntl &= ~RADEON_DISP_TVDAC_SOURCE_MASK; 1269251881Speter disp_output_cntl |= RADEON_DISP_TVDAC_SOURCE_CRTC2; 1270251881Speter } else if (rdev->family == CHIP_R200) { 1271251881Speter fp2_gen_cntl &= ~(R200_FP2_SOURCE_SEL_MASK | 1272251881Speter RADEON_FP2_DVO_RATE_SEL_SDR); 1273251881Speter fp2_gen_cntl |= R200_FP2_SOURCE_SEL_CRTC2; 1274251881Speter } else 1275251881Speter disp_hw_debug &= ~RADEON_CRT2_DISP1_SEL; 1276251881Speter } 1277251881Speter WREG32(RADEON_DAC_CNTL2, dac2_cntl); 1278251881Speter } 1279251881Speter 1280251881Speter if (ASIC_IS_R300(rdev)) { 1281251881Speter WREG32_P(RADEON_GPIOPAD_A, gpiopad_a, ~1); 1282251881Speter WREG32(RADEON_DISP_OUTPUT_CNTL, disp_output_cntl); 1283251881Speter } else if (rdev->family != CHIP_R200) 1284251881Speter WREG32(RADEON_DISP_HW_DEBUG, disp_hw_debug); 1285251881Speter else if (rdev->family == CHIP_R200) 1286251881Speter WREG32(RADEON_FP2_GEN_CNTL, fp2_gen_cntl); 1287251881Speter 1288251881Speter if (rdev->family >= CHIP_R200) 1289251881Speter WREG32(RADEON_DISP_TV_OUT_CNTL, disp_tv_out_cntl); 1290251881Speter 1291251881Speter if (is_tv) 1292251881Speter radeon_legacy_tv_mode_set(encoder, mode, adjusted_mode); 1293251881Speter 1294251881Speter if (rdev->is_atom_bios) 1295251881Speter radeon_atombios_encoder_crtc_scratch_regs(encoder, radeon_crtc->crtc_id); 1296251881Speter else 1297251881Speter radeon_combios_encoder_crtc_scratch_regs(encoder, radeon_crtc->crtc_id); 1298251881Speter 1299251881Speter} 1300251881Speter 1301251881Speterstatic bool r300_legacy_tv_detect(struct drm_encoder *encoder, 1302251881Speter struct drm_connector *connector) 1303251881Speter{ 1304251881Speter struct drm_device *dev = encoder->dev; 1305251881Speter struct radeon_device *rdev = dev->dev_private; 1306251881Speter uint32_t crtc2_gen_cntl, tv_dac_cntl, dac_cntl2, dac_ext_cntl; 1307251881Speter uint32_t disp_output_cntl, gpiopad_a, tmp; 1308251881Speter bool found = false; 1309251881Speter 1310251881Speter /* save regs needed */ 1311251881Speter gpiopad_a = RREG32(RADEON_GPIOPAD_A); 1312251881Speter dac_cntl2 = RREG32(RADEON_DAC_CNTL2); 1313251881Speter crtc2_gen_cntl = RREG32(RADEON_CRTC2_GEN_CNTL); 1314251881Speter dac_ext_cntl = RREG32(RADEON_DAC_EXT_CNTL); 1315251881Speter tv_dac_cntl = RREG32(RADEON_TV_DAC_CNTL); 1316251881Speter disp_output_cntl = RREG32(RADEON_DISP_OUTPUT_CNTL); 1317251881Speter 1318251881Speter WREG32_P(RADEON_GPIOPAD_A, 0, ~1); 1319251881Speter 1320251881Speter WREG32(RADEON_DAC_CNTL2, RADEON_DAC2_DAC2_CLK_SEL); 1321251881Speter 1322251881Speter WREG32(RADEON_CRTC2_GEN_CNTL, 1323251881Speter RADEON_CRTC2_CRT2_ON | RADEON_CRTC2_VSYNC_TRISTAT); 1324251881Speter 1325251881Speter tmp = disp_output_cntl & ~RADEON_DISP_TVDAC_SOURCE_MASK; 1326251881Speter tmp |= RADEON_DISP_TVDAC_SOURCE_CRTC2; 1327251881Speter WREG32(RADEON_DISP_OUTPUT_CNTL, tmp); 1328251881Speter 1329251881Speter WREG32(RADEON_DAC_EXT_CNTL, 1330251881Speter RADEON_DAC2_FORCE_BLANK_OFF_EN | 1331251881Speter RADEON_DAC2_FORCE_DATA_EN | 1332251881Speter RADEON_DAC_FORCE_DATA_SEL_RGB | 1333251881Speter (0xec << RADEON_DAC_FORCE_DATA_SHIFT)); 1334251881Speter 1335251881Speter WREG32(RADEON_TV_DAC_CNTL, 1336251881Speter RADEON_TV_DAC_STD_NTSC | 1337251881Speter (8 << RADEON_TV_DAC_BGADJ_SHIFT) | 1338251881Speter (6 << RADEON_TV_DAC_DACADJ_SHIFT)); 1339251881Speter 1340251881Speter RREG32(RADEON_TV_DAC_CNTL); 1341251881Speter mdelay(4); 1342 1343 WREG32(RADEON_TV_DAC_CNTL, 1344 RADEON_TV_DAC_NBLANK | 1345 RADEON_TV_DAC_NHOLD | 1346 RADEON_TV_MONITOR_DETECT_EN | 1347 RADEON_TV_DAC_STD_NTSC | 1348 (8 << RADEON_TV_DAC_BGADJ_SHIFT) | 1349 (6 << RADEON_TV_DAC_DACADJ_SHIFT)); 1350 1351 RREG32(RADEON_TV_DAC_CNTL); 1352 mdelay(6); 1353 1354 tmp = RREG32(RADEON_TV_DAC_CNTL); 1355 if ((tmp & RADEON_TV_DAC_GDACDET) != 0) { 1356 found = true; 1357 DRM_DEBUG_KMS("S-video TV connection detected\n"); 1358 } else if ((tmp & RADEON_TV_DAC_BDACDET) != 0) { 1359 found = true; 1360 DRM_DEBUG_KMS("Composite TV connection detected\n"); 1361 } 1362 1363 WREG32(RADEON_TV_DAC_CNTL, tv_dac_cntl); 1364 WREG32(RADEON_DAC_EXT_CNTL, dac_ext_cntl); 1365 WREG32(RADEON_CRTC2_GEN_CNTL, crtc2_gen_cntl); 1366 WREG32(RADEON_DISP_OUTPUT_CNTL, disp_output_cntl); 1367 WREG32(RADEON_DAC_CNTL2, dac_cntl2); 1368 WREG32_P(RADEON_GPIOPAD_A, gpiopad_a, ~1); 1369 return found; 1370} 1371 1372static bool radeon_legacy_tv_detect(struct drm_encoder *encoder, 1373 struct drm_connector *connector) 1374{ 1375 struct drm_device *dev = encoder->dev; 1376 struct radeon_device *rdev = dev->dev_private; 1377 uint32_t tv_dac_cntl, dac_cntl2; 1378 uint32_t config_cntl, tv_pre_dac_mux_cntl, tv_master_cntl, tmp; 1379 bool found = false; 1380 1381 if (ASIC_IS_R300(rdev)) 1382 return r300_legacy_tv_detect(encoder, connector); 1383 1384 dac_cntl2 = RREG32(RADEON_DAC_CNTL2); 1385 tv_master_cntl = RREG32(RADEON_TV_MASTER_CNTL); 1386 tv_dac_cntl = RREG32(RADEON_TV_DAC_CNTL); 1387 config_cntl = RREG32(RADEON_CONFIG_CNTL); 1388 tv_pre_dac_mux_cntl = RREG32(RADEON_TV_PRE_DAC_MUX_CNTL); 1389 1390 tmp = dac_cntl2 & ~RADEON_DAC2_DAC2_CLK_SEL; 1391 WREG32(RADEON_DAC_CNTL2, tmp); 1392 1393 tmp = tv_master_cntl | RADEON_TV_ON; 1394 tmp &= ~(RADEON_TV_ASYNC_RST | 1395 RADEON_RESTART_PHASE_FIX | 1396 RADEON_CRT_FIFO_CE_EN | 1397 RADEON_TV_FIFO_CE_EN | 1398 RADEON_RE_SYNC_NOW_SEL_MASK); 1399 tmp |= RADEON_TV_FIFO_ASYNC_RST | RADEON_CRT_ASYNC_RST; 1400 WREG32(RADEON_TV_MASTER_CNTL, tmp); 1401 1402 tmp = RADEON_TV_DAC_NBLANK | RADEON_TV_DAC_NHOLD | 1403 RADEON_TV_MONITOR_DETECT_EN | RADEON_TV_DAC_STD_NTSC | 1404 (8 << RADEON_TV_DAC_BGADJ_SHIFT); 1405 1406 if (config_cntl & RADEON_CFG_ATI_REV_ID_MASK) 1407 tmp |= (4 << RADEON_TV_DAC_DACADJ_SHIFT); 1408 else 1409 tmp |= (8 << RADEON_TV_DAC_DACADJ_SHIFT); 1410 WREG32(RADEON_TV_DAC_CNTL, tmp); 1411 1412 tmp = RADEON_C_GRN_EN | RADEON_CMP_BLU_EN | 1413 RADEON_RED_MX_FORCE_DAC_DATA | 1414 RADEON_GRN_MX_FORCE_DAC_DATA | 1415 RADEON_BLU_MX_FORCE_DAC_DATA | 1416 (0x109 << RADEON_TV_FORCE_DAC_DATA_SHIFT); 1417 WREG32(RADEON_TV_PRE_DAC_MUX_CNTL, tmp); 1418 1419 mdelay(3); 1420 tmp = RREG32(RADEON_TV_DAC_CNTL); 1421 if (tmp & RADEON_TV_DAC_GDACDET) { 1422 found = true; 1423 DRM_DEBUG_KMS("S-video TV connection detected\n"); 1424 } else if ((tmp & RADEON_TV_DAC_BDACDET) != 0) { 1425 found = true; 1426 DRM_DEBUG_KMS("Composite TV connection detected\n"); 1427 } 1428 1429 WREG32(RADEON_TV_PRE_DAC_MUX_CNTL, tv_pre_dac_mux_cntl); 1430 WREG32(RADEON_TV_DAC_CNTL, tv_dac_cntl); 1431 WREG32(RADEON_TV_MASTER_CNTL, tv_master_cntl); 1432 WREG32(RADEON_DAC_CNTL2, dac_cntl2); 1433 return found; 1434} 1435 1436static bool radeon_legacy_ext_dac_detect(struct drm_encoder *encoder, 1437 struct drm_connector *connector) 1438{ 1439 struct drm_device *dev = encoder->dev; 1440 struct radeon_device *rdev = dev->dev_private; 1441 uint32_t gpio_monid, fp2_gen_cntl, disp_output_cntl, crtc2_gen_cntl; 1442 uint32_t disp_lin_trans_grph_a, disp_lin_trans_grph_b, disp_lin_trans_grph_c; 1443 uint32_t disp_lin_trans_grph_d, disp_lin_trans_grph_e, disp_lin_trans_grph_f; 1444 uint32_t tmp, crtc2_h_total_disp, crtc2_v_total_disp; 1445 uint32_t crtc2_h_sync_strt_wid, crtc2_v_sync_strt_wid; 1446 bool found = false; 1447 int i; 1448 1449 /* save the regs we need */ 1450 gpio_monid = RREG32(RADEON_GPIO_MONID); 1451 fp2_gen_cntl = RREG32(RADEON_FP2_GEN_CNTL); 1452 disp_output_cntl = RREG32(RADEON_DISP_OUTPUT_CNTL); 1453 crtc2_gen_cntl = RREG32(RADEON_CRTC2_GEN_CNTL); 1454 disp_lin_trans_grph_a = RREG32(RADEON_DISP_LIN_TRANS_GRPH_A); 1455 disp_lin_trans_grph_b = RREG32(RADEON_DISP_LIN_TRANS_GRPH_B); 1456 disp_lin_trans_grph_c = RREG32(RADEON_DISP_LIN_TRANS_GRPH_C); 1457 disp_lin_trans_grph_d = RREG32(RADEON_DISP_LIN_TRANS_GRPH_D); 1458 disp_lin_trans_grph_e = RREG32(RADEON_DISP_LIN_TRANS_GRPH_E); 1459 disp_lin_trans_grph_f = RREG32(RADEON_DISP_LIN_TRANS_GRPH_F); 1460 crtc2_h_total_disp = RREG32(RADEON_CRTC2_H_TOTAL_DISP); 1461 crtc2_v_total_disp = RREG32(RADEON_CRTC2_V_TOTAL_DISP); 1462 crtc2_h_sync_strt_wid = RREG32(RADEON_CRTC2_H_SYNC_STRT_WID); 1463 crtc2_v_sync_strt_wid = RREG32(RADEON_CRTC2_V_SYNC_STRT_WID); 1464 1465 tmp = RREG32(RADEON_GPIO_MONID); 1466 tmp &= ~RADEON_GPIO_A_0; 1467 WREG32(RADEON_GPIO_MONID, tmp); 1468 1469 WREG32(RADEON_FP2_GEN_CNTL, (RADEON_FP2_ON | 1470 RADEON_FP2_PANEL_FORMAT | 1471 R200_FP2_SOURCE_SEL_TRANS_UNIT | 1472 RADEON_FP2_DVO_EN | 1473 R200_FP2_DVO_RATE_SEL_SDR)); 1474 1475 WREG32(RADEON_DISP_OUTPUT_CNTL, (RADEON_DISP_DAC_SOURCE_RMX | 1476 RADEON_DISP_TRANS_MATRIX_GRAPHICS)); 1477 1478 WREG32(RADEON_CRTC2_GEN_CNTL, (RADEON_CRTC2_EN | 1479 RADEON_CRTC2_DISP_REQ_EN_B)); 1480 1481 WREG32(RADEON_DISP_LIN_TRANS_GRPH_A, 0x00000000); 1482 WREG32(RADEON_DISP_LIN_TRANS_GRPH_B, 0x000003f0); 1483 WREG32(RADEON_DISP_LIN_TRANS_GRPH_C, 0x00000000); 1484 WREG32(RADEON_DISP_LIN_TRANS_GRPH_D, 0x000003f0); 1485 WREG32(RADEON_DISP_LIN_TRANS_GRPH_E, 0x00000000); 1486 WREG32(RADEON_DISP_LIN_TRANS_GRPH_F, 0x000003f0); 1487 1488 WREG32(RADEON_CRTC2_H_TOTAL_DISP, 0x01000008); 1489 WREG32(RADEON_CRTC2_H_SYNC_STRT_WID, 0x00000800); 1490 WREG32(RADEON_CRTC2_V_TOTAL_DISP, 0x00080001); 1491 WREG32(RADEON_CRTC2_V_SYNC_STRT_WID, 0x00000080); 1492 1493 for (i = 0; i < 200; i++) { 1494 tmp = RREG32(RADEON_GPIO_MONID); 1495 if (tmp & RADEON_GPIO_Y_0) 1496 found = true; 1497 1498 if (found) 1499 break; 1500 1501 if (!drm_can_sleep()) 1502 mdelay(1); 1503 else 1504 DRM_MSLEEP(1); 1505 } 1506 1507 /* restore the regs we used */ 1508 WREG32(RADEON_DISP_LIN_TRANS_GRPH_A, disp_lin_trans_grph_a); 1509 WREG32(RADEON_DISP_LIN_TRANS_GRPH_B, disp_lin_trans_grph_b); 1510 WREG32(RADEON_DISP_LIN_TRANS_GRPH_C, disp_lin_trans_grph_c); 1511 WREG32(RADEON_DISP_LIN_TRANS_GRPH_D, disp_lin_trans_grph_d); 1512 WREG32(RADEON_DISP_LIN_TRANS_GRPH_E, disp_lin_trans_grph_e); 1513 WREG32(RADEON_DISP_LIN_TRANS_GRPH_F, disp_lin_trans_grph_f); 1514 WREG32(RADEON_CRTC2_H_TOTAL_DISP, crtc2_h_total_disp); 1515 WREG32(RADEON_CRTC2_V_TOTAL_DISP, crtc2_v_total_disp); 1516 WREG32(RADEON_CRTC2_H_SYNC_STRT_WID, crtc2_h_sync_strt_wid); 1517 WREG32(RADEON_CRTC2_V_SYNC_STRT_WID, crtc2_v_sync_strt_wid); 1518 WREG32(RADEON_CRTC2_GEN_CNTL, crtc2_gen_cntl); 1519 WREG32(RADEON_DISP_OUTPUT_CNTL, disp_output_cntl); 1520 WREG32(RADEON_FP2_GEN_CNTL, fp2_gen_cntl); 1521 WREG32(RADEON_GPIO_MONID, gpio_monid); 1522 1523 return found; 1524} 1525 1526static enum drm_connector_status radeon_legacy_tv_dac_detect(struct drm_encoder *encoder, 1527 struct drm_connector *connector) 1528{ 1529 struct drm_device *dev = encoder->dev; 1530 struct radeon_device *rdev = dev->dev_private; 1531 uint32_t crtc2_gen_cntl = 0, tv_dac_cntl, dac_cntl2, dac_ext_cntl; 1532 uint32_t gpiopad_a = 0, pixclks_cntl, tmp; 1533 uint32_t disp_output_cntl = 0, disp_hw_debug = 0, crtc_ext_cntl = 0; 1534 enum drm_connector_status found = connector_status_disconnected; 1535 struct radeon_encoder *radeon_encoder = to_radeon_encoder(encoder); 1536 struct radeon_encoder_tv_dac *tv_dac = radeon_encoder->enc_priv; 1537 bool color = true; 1538 struct drm_crtc *crtc; 1539 1540 /* find out if crtc2 is in use or if this encoder is using it */ 1541 list_for_each_entry(crtc, &dev->mode_config.crtc_list, head) { 1542 struct radeon_crtc *radeon_crtc = to_radeon_crtc(crtc); 1543 if ((radeon_crtc->crtc_id == 1) && crtc->enabled) { 1544 if (encoder->crtc != crtc) { 1545 return connector_status_disconnected; 1546 } 1547 } 1548 } 1549 1550 if (connector->connector_type == DRM_MODE_CONNECTOR_SVIDEO || 1551 connector->connector_type == DRM_MODE_CONNECTOR_Composite || 1552 connector->connector_type == DRM_MODE_CONNECTOR_9PinDIN) { 1553 bool tv_detect; 1554 1555 if (radeon_encoder->active_device && !(radeon_encoder->active_device & ATOM_DEVICE_TV_SUPPORT)) 1556 return connector_status_disconnected; 1557 1558 tv_detect = radeon_legacy_tv_detect(encoder, connector); 1559 if (tv_detect && tv_dac) 1560 found = connector_status_connected; 1561 return found; 1562 } 1563 1564 /* don't probe if the encoder is being used for something else not CRT related */ 1565 if (radeon_encoder->active_device && !(radeon_encoder->active_device & ATOM_DEVICE_CRT_SUPPORT)) { 1566 DRM_INFO("not detecting due to %08x\n", radeon_encoder->active_device); 1567 return connector_status_disconnected; 1568 } 1569 1570 /* R200 uses an external DAC for secondary DAC */ 1571 if (rdev->family == CHIP_R200) { 1572 if (radeon_legacy_ext_dac_detect(encoder, connector)) 1573 found = connector_status_connected; 1574 return found; 1575 } 1576 1577 /* save the regs we need */ 1578 pixclks_cntl = RREG32_PLL(RADEON_PIXCLKS_CNTL); 1579 1580 if (rdev->flags & RADEON_SINGLE_CRTC) { 1581 crtc_ext_cntl = RREG32(RADEON_CRTC_EXT_CNTL); 1582 } else { 1583 if (ASIC_IS_R300(rdev)) { 1584 gpiopad_a = RREG32(RADEON_GPIOPAD_A); 1585 disp_output_cntl = RREG32(RADEON_DISP_OUTPUT_CNTL); 1586 } else { 1587 disp_hw_debug = RREG32(RADEON_DISP_HW_DEBUG); 1588 } 1589 crtc2_gen_cntl = RREG32(RADEON_CRTC2_GEN_CNTL); 1590 } 1591 tv_dac_cntl = RREG32(RADEON_TV_DAC_CNTL); 1592 dac_ext_cntl = RREG32(RADEON_DAC_EXT_CNTL); 1593 dac_cntl2 = RREG32(RADEON_DAC_CNTL2); 1594 1595 tmp = pixclks_cntl & ~(RADEON_PIX2CLK_ALWAYS_ONb 1596 | RADEON_PIX2CLK_DAC_ALWAYS_ONb); 1597 WREG32_PLL(RADEON_PIXCLKS_CNTL, tmp); 1598 1599 if (rdev->flags & RADEON_SINGLE_CRTC) { 1600 tmp = crtc_ext_cntl | RADEON_CRTC_CRT_ON; 1601 WREG32(RADEON_CRTC_EXT_CNTL, tmp); 1602 } else { 1603 tmp = crtc2_gen_cntl & ~RADEON_CRTC2_PIX_WIDTH_MASK; 1604 tmp |= RADEON_CRTC2_CRT2_ON | 1605 (2 << RADEON_CRTC2_PIX_WIDTH_SHIFT); 1606 WREG32(RADEON_CRTC2_GEN_CNTL, tmp); 1607 1608 if (ASIC_IS_R300(rdev)) { 1609 WREG32_P(RADEON_GPIOPAD_A, 1, ~1); 1610 tmp = disp_output_cntl & ~RADEON_DISP_TVDAC_SOURCE_MASK; 1611 tmp |= RADEON_DISP_TVDAC_SOURCE_CRTC2; 1612 WREG32(RADEON_DISP_OUTPUT_CNTL, tmp); 1613 } else { 1614 tmp = disp_hw_debug & ~RADEON_CRT2_DISP1_SEL; 1615 WREG32(RADEON_DISP_HW_DEBUG, tmp); 1616 } 1617 } 1618 1619 tmp = RADEON_TV_DAC_NBLANK | 1620 RADEON_TV_DAC_NHOLD | 1621 RADEON_TV_MONITOR_DETECT_EN | 1622 RADEON_TV_DAC_STD_PS2; 1623 1624 WREG32(RADEON_TV_DAC_CNTL, tmp); 1625 1626 tmp = RADEON_DAC2_FORCE_BLANK_OFF_EN | 1627 RADEON_DAC2_FORCE_DATA_EN; 1628 1629 if (color) 1630 tmp |= RADEON_DAC_FORCE_DATA_SEL_RGB; 1631 else 1632 tmp |= RADEON_DAC_FORCE_DATA_SEL_G; 1633 1634 if (ASIC_IS_R300(rdev)) 1635 tmp |= (0x1b6 << RADEON_DAC_FORCE_DATA_SHIFT); 1636 else 1637 tmp |= (0x180 << RADEON_DAC_FORCE_DATA_SHIFT); 1638 1639 WREG32(RADEON_DAC_EXT_CNTL, tmp); 1640 1641 tmp = dac_cntl2 | RADEON_DAC2_DAC2_CLK_SEL | RADEON_DAC2_CMP_EN; 1642 WREG32(RADEON_DAC_CNTL2, tmp); 1643 1644 mdelay(10); 1645 1646 if (ASIC_IS_R300(rdev)) { 1647 if (RREG32(RADEON_DAC_CNTL2) & RADEON_DAC2_CMP_OUT_B) 1648 found = connector_status_connected; 1649 } else { 1650 if (RREG32(RADEON_DAC_CNTL2) & RADEON_DAC2_CMP_OUTPUT) 1651 found = connector_status_connected; 1652 } 1653 1654 /* restore regs we used */ 1655 WREG32(RADEON_DAC_CNTL2, dac_cntl2); 1656 WREG32(RADEON_DAC_EXT_CNTL, dac_ext_cntl); 1657 WREG32(RADEON_TV_DAC_CNTL, tv_dac_cntl); 1658 1659 if (rdev->flags & RADEON_SINGLE_CRTC) { 1660 WREG32(RADEON_CRTC_EXT_CNTL, crtc_ext_cntl); 1661 } else { 1662 WREG32(RADEON_CRTC2_GEN_CNTL, crtc2_gen_cntl); 1663 if (ASIC_IS_R300(rdev)) { 1664 WREG32(RADEON_DISP_OUTPUT_CNTL, disp_output_cntl); 1665 WREG32_P(RADEON_GPIOPAD_A, gpiopad_a, ~1); 1666 } else { 1667 WREG32(RADEON_DISP_HW_DEBUG, disp_hw_debug); 1668 } 1669 } 1670 1671 WREG32_PLL(RADEON_PIXCLKS_CNTL, pixclks_cntl); 1672 1673 return found; 1674 1675} 1676 1677static const struct drm_encoder_helper_funcs radeon_legacy_tv_dac_helper_funcs = { 1678 .dpms = radeon_legacy_tv_dac_dpms, 1679 .mode_fixup = radeon_legacy_mode_fixup, 1680 .prepare = radeon_legacy_tv_dac_prepare, 1681 .mode_set = radeon_legacy_tv_dac_mode_set, 1682 .commit = radeon_legacy_tv_dac_commit, 1683 .detect = radeon_legacy_tv_dac_detect, 1684 .disable = radeon_legacy_encoder_disable, 1685}; 1686 1687 1688static const struct drm_encoder_funcs radeon_legacy_tv_dac_enc_funcs = { 1689 .destroy = radeon_enc_destroy, 1690}; 1691 1692 1693static struct radeon_encoder_int_tmds *radeon_legacy_get_tmds_info(struct radeon_encoder *encoder) 1694{ 1695 struct drm_device *dev = encoder->base.dev; 1696 struct radeon_device *rdev = dev->dev_private; 1697 struct radeon_encoder_int_tmds *tmds = NULL; 1698 bool ret; 1699 1700 tmds = malloc(sizeof(struct radeon_encoder_int_tmds), 1701 DRM_MEM_DRIVER, M_NOWAIT | M_ZERO); 1702 1703 if (!tmds) 1704 return NULL; 1705 1706 if (rdev->is_atom_bios) 1707 ret = radeon_atombios_get_tmds_info(encoder, tmds); 1708 else 1709 ret = radeon_legacy_get_tmds_info_from_combios(encoder, tmds); 1710 1711 if (ret == false) 1712 radeon_legacy_get_tmds_info_from_table(encoder, tmds); 1713 1714 return tmds; 1715} 1716 1717static struct radeon_encoder_ext_tmds *radeon_legacy_get_ext_tmds_info(struct radeon_encoder *encoder) 1718{ 1719 struct drm_device *dev = encoder->base.dev; 1720 struct radeon_device *rdev = dev->dev_private; 1721 struct radeon_encoder_ext_tmds *tmds = NULL; 1722 bool ret; 1723 1724 if (rdev->is_atom_bios) 1725 return NULL; 1726 1727 tmds = malloc(sizeof(struct radeon_encoder_ext_tmds), 1728 DRM_MEM_DRIVER, M_NOWAIT | M_ZERO); 1729 1730 if (!tmds) 1731 return NULL; 1732 1733 ret = radeon_legacy_get_ext_tmds_info_from_combios(encoder, tmds); 1734 1735 if (ret == false) 1736 radeon_legacy_get_ext_tmds_info_from_table(encoder, tmds); 1737 1738 return tmds; 1739} 1740 1741void 1742radeon_add_legacy_encoder(struct drm_device *dev, uint32_t encoder_enum, uint32_t supported_device) 1743{ 1744 struct radeon_device *rdev = dev->dev_private; 1745 struct drm_encoder *encoder; 1746 struct radeon_encoder *radeon_encoder; 1747 1748 /* see if we already added it */ 1749 list_for_each_entry(encoder, &dev->mode_config.encoder_list, head) { 1750 radeon_encoder = to_radeon_encoder(encoder); 1751 if (radeon_encoder->encoder_enum == encoder_enum) { 1752 radeon_encoder->devices |= supported_device; 1753 return; 1754 } 1755 1756 } 1757 1758 /* add a new one */ 1759 radeon_encoder = malloc(sizeof(struct radeon_encoder), 1760 DRM_MEM_DRIVER, M_NOWAIT | M_ZERO); 1761 if (!radeon_encoder) 1762 return; 1763 1764 encoder = &radeon_encoder->base; 1765 if (rdev->flags & RADEON_SINGLE_CRTC) 1766 encoder->possible_crtcs = 0x1; 1767 else 1768 encoder->possible_crtcs = 0x3; 1769 1770 radeon_encoder->enc_priv = NULL; 1771 1772 radeon_encoder->encoder_enum = encoder_enum; 1773 radeon_encoder->encoder_id = (encoder_enum & OBJECT_ID_MASK) >> OBJECT_ID_SHIFT; 1774 radeon_encoder->devices = supported_device; 1775 radeon_encoder->rmx_type = RMX_OFF; 1776 1777 switch (radeon_encoder->encoder_id) { 1778 case ENCODER_OBJECT_ID_INTERNAL_LVDS: 1779 encoder->possible_crtcs = 0x1; 1780 drm_encoder_init(dev, encoder, &radeon_legacy_lvds_enc_funcs, DRM_MODE_ENCODER_LVDS); 1781 drm_encoder_helper_add(encoder, &radeon_legacy_lvds_helper_funcs); 1782 if (rdev->is_atom_bios) 1783 radeon_encoder->enc_priv = radeon_atombios_get_lvds_info(radeon_encoder); 1784 else 1785 radeon_encoder->enc_priv = radeon_combios_get_lvds_info(radeon_encoder); 1786 radeon_encoder->rmx_type = RMX_FULL; 1787 break; 1788 case ENCODER_OBJECT_ID_INTERNAL_TMDS1: 1789 drm_encoder_init(dev, encoder, &radeon_legacy_tmds_int_enc_funcs, DRM_MODE_ENCODER_TMDS); 1790 drm_encoder_helper_add(encoder, &radeon_legacy_tmds_int_helper_funcs); 1791 radeon_encoder->enc_priv = radeon_legacy_get_tmds_info(radeon_encoder); 1792 break; 1793 case ENCODER_OBJECT_ID_INTERNAL_DAC1: 1794 drm_encoder_init(dev, encoder, &radeon_legacy_primary_dac_enc_funcs, DRM_MODE_ENCODER_DAC); 1795 drm_encoder_helper_add(encoder, &radeon_legacy_primary_dac_helper_funcs); 1796 if (rdev->is_atom_bios) 1797 radeon_encoder->enc_priv = radeon_atombios_get_primary_dac_info(radeon_encoder); 1798 else 1799 radeon_encoder->enc_priv = radeon_combios_get_primary_dac_info(radeon_encoder); 1800 break; 1801 case ENCODER_OBJECT_ID_INTERNAL_DAC2: 1802 drm_encoder_init(dev, encoder, &radeon_legacy_tv_dac_enc_funcs, DRM_MODE_ENCODER_TVDAC); 1803 drm_encoder_helper_add(encoder, &radeon_legacy_tv_dac_helper_funcs); 1804 if (rdev->is_atom_bios) 1805 radeon_encoder->enc_priv = radeon_atombios_get_tv_dac_info(radeon_encoder); 1806 else 1807 radeon_encoder->enc_priv = radeon_combios_get_tv_dac_info(radeon_encoder); 1808 break; 1809 case ENCODER_OBJECT_ID_INTERNAL_DVO1: 1810 drm_encoder_init(dev, encoder, &radeon_legacy_tmds_ext_enc_funcs, DRM_MODE_ENCODER_TMDS); 1811 drm_encoder_helper_add(encoder, &radeon_legacy_tmds_ext_helper_funcs); 1812 if (!rdev->is_atom_bios) 1813 radeon_encoder->enc_priv = radeon_legacy_get_ext_tmds_info(radeon_encoder); 1814 break; 1815 } 1816} 1817