From ebf689595a0f8e5527a878e210a43a011ae8b691 Mon Sep 17 00:00:00 2001 From: Alex Deucher Date: Tue, 8 Dec 2009 16:49:26 -0500 Subject: [PATCH] drm/radeon/kms: add support for DAC autodetect interrupts Supported on all AVIVO-based asics Signed-off-by: Alex Deucher --- drivers/gpu/drm/radeon/r100.c | 23 ++ drivers/gpu/drm/radeon/r600.c | 306 ++++++++++++++++++++++++++++ drivers/gpu/drm/radeon/r600d.h | 44 ++++- drivers/gpu/drm/radeon/radeon.h | 9 + drivers/gpu/drm/radeon/radeon_asic.h | 55 +++++ drivers/gpu/drm/radeon/radeon_connectors.c | 19 ++ drivers/gpu/drm/radeon/radeon_device.c | 3 + drivers/gpu/drm/radeon/radeon_display.c | 3 + drivers/gpu/drm/radeon/radeon_mode.h | 7 + drivers/gpu/drm/radeon/rs600.c | 165 +++++++++++++++ drivers/gpu/drm/radeon/rs600d.h | 64 ++++++- 11 files changed, 693 insertions(+), 5 deletions(-) diff --git a/drivers/gpu/drm/radeon/r100.c b/drivers/gpu/drm/radeon/r100.c index 036e112..46147a9 100644 --- a/drivers/gpu/drm/radeon/r100.c +++ b/drivers/gpu/drm/radeon/r100.c @@ -154,6 +154,29 @@ void r100_hpd_fini(struct radeon_device *rdev) } } +/* autodetect for analog detect/disconnect */ +bool r100_dac_sense(struct radeon_device *rdev, enum radeon_dac_id dac) +{ + /* no dac autodetect hw on r1xx-r4xx */ + return false; +} + +void r100_dac_set_polarity(struct radeon_device *rdev, + enum radeon_dac_id dac) +{ + /* no dac autodetect hw on r1xx-r4xx */ +} + +void r100_dac_init(struct radeon_device *rdev) +{ + /* no dac autodetect hw on r1xx-r4xx */ +} + +void r100_dac_fini(struct radeon_device *rdev) +{ + /* no dac autodetect hw on r1xx-r4xx */ +} + /* * PCI GART */ diff --git a/drivers/gpu/drm/radeon/r600.c b/drivers/gpu/drm/radeon/r600.c index 404a613..12bd548 100644 --- a/drivers/gpu/drm/radeon/r600.c +++ b/drivers/gpu/drm/radeon/r600.c @@ -349,6 +349,259 @@ void r600_hpd_fini(struct radeon_device *rdev) } } +/* autodetect for analog detect/disconnect */ +bool r600_dac_sense(struct radeon_device *rdev, enum radeon_dac_id dac) +{ + u32 tmp; + bool connected = false; + + if (ASIC_IS_DCE3(rdev)) { + switch (dac) { + case RADEON_DAC_A: + tmp = RREG32(DCE3_DACA_AUTODETECT_STATUS); + DRM_INFO("DACA status 0x%08x\n", tmp); + if (tmp & DACx_AUTODETECT_CONNECT) + connected = true; + break; + case RADEON_DAC_B: + tmp = RREG32(DCE3_DACB_AUTODETECT_STATUS); + DRM_INFO("DACB status 0x%08x\n", tmp); + if (tmp & DACx_AUTODETECT_CONNECT) + connected = true; + break; + default: + break; + } + } else { + switch (dac) { + case RADEON_DAC_A: + tmp = RREG32(DACA_AUTODETECT_STATUS); + DRM_INFO("DACA status 0x%08x\n", tmp); + if (tmp & DACx_AUTODETECT_CONNECT) + connected = true; + break; + case RADEON_DAC_B: + tmp = RREG32(DACB_AUTODETECT_STATUS); + DRM_INFO("DACB status 0x%08x\n", tmp); + if (tmp & DACx_AUTODETECT_CONNECT) + connected = true; + break; + default: + break; + } + } + return connected; +} + +void r600_dac_set_polarity(struct radeon_device *rdev, + enum radeon_dac_id dac) +{ + u32 tmp; + bool connected = r600_dac_sense(rdev, dac); + + if (ASIC_IS_DCE3(rdev)) { + switch (dac) { + case RADEON_DAC_A: + tmp = RREG32(DCE3_DACA_AUTODETECT_CONTROL) & ~DACx_AUTODETECT_MODE(3); + if (connected) + tmp |= DACx_AUTODETECT_MODE(2); + else + tmp |= DACx_AUTODETECT_MODE(1); + WREG32(DCE3_DACA_AUTODETECT_CONTROL, tmp); + udelay(50); + break; + case RADEON_DAC_B: + tmp = RREG32(DCE3_DACB_AUTODETECT_CONTROL) & ~DACx_AUTODETECT_MODE(3); + if (connected) + tmp |= DACx_AUTODETECT_MODE(2); + else + tmp |= DACx_AUTODETECT_MODE(1); + WREG32(DCE3_DACB_AUTODETECT_CONTROL, tmp); + udelay(50); + break; + default: + break; + } + } else { + switch (dac) { + case RADEON_DAC_A: + tmp = RREG32(DACA_AUTODETECT_CONTROL) & ~DACx_AUTODETECT_MODE(3); + if (connected) + tmp |= DACx_AUTODETECT_MODE(2); + else + tmp |= DACx_AUTODETECT_MODE(1); + WREG32(DACA_AUTODETECT_CONTROL, tmp); + udelay(50); + break; + case RADEON_DAC_B: + tmp = RREG32(DACB_AUTODETECT_CONTROL) & ~DACx_AUTODETECT_MODE(3); + if (connected) + tmp |= DACx_AUTODETECT_MODE(2); + else + tmp |= DACx_AUTODETECT_MODE(1); + WREG32(DACB_AUTODETECT_CONTROL, tmp); + udelay(50); + break; + default: + break; + } + } +} + +void r600_dac_init(struct radeon_device *rdev) +{ + struct drm_device *dev = rdev->ddev; + struct drm_connector *connector; + + if (ASIC_IS_DCE3(rdev)) { + list_for_each_entry(connector, &dev->mode_config.connector_list, head) { + struct radeon_connector *radeon_connector = to_radeon_connector(connector); + switch (radeon_connector->dac) { + case RADEON_DAC_A: + WREG32(DCE3_DACA_FORCE_DATA, 0x20); + WREG32(DCE3_DACA_AUTODETECT_INT_CONTROL, DACx_AUTODETECT_ACK); + WREG32(DCE3_DACA_AUTODETECT_CONTROL3, + DACx_AUTODET_COMPARATOR_IN_DELAY(0x19) | + DACx_AUTODET_COMPARATOR_OUT_DELAY(0x5)); + WREG32(DCE3_DACA_AUTODETECT_CONTROL2, + DACx_AUTODETECT_POWERUP_COUNTER(0xB)); + WREG32(DCE3_DACA_AUTODETECT_CONTROL, + DACx_AUTODETECT_FRAME_TIME_COUNTER(0) | + DACx_AUTODETECT_CHECK_MASK(7)); + WREG32(DCE3_DACA_COMPARATOR_ENABLE, (DACx_R_ASYNC_ENABLE | + DACx_G_ASYNC_ENABLE | + DACx_B_ASYNC_ENABLE)); + WREG32(DCE3_DACA_AUTODETECT_CONTROL, + DACx_AUTODETECT_MODE(1) | + DACx_AUTODETECT_FRAME_TIME_COUNTER(0) | + DACx_AUTODETECT_CHECK_MASK(7)); + rdev->irq.dac[0] = true; + break; + case RADEON_DAC_B: + WREG32(DCE3_DACB_FORCE_DATA, 0x20); + WREG32(DCE3_DACB_AUTODETECT_INT_CONTROL, DACx_AUTODETECT_ACK); + WREG32(DCE3_DACB_AUTODETECT_CONTROL3, + DACx_AUTODET_COMPARATOR_IN_DELAY(0x19) | + DACx_AUTODET_COMPARATOR_OUT_DELAY(0x5)); + WREG32(DCE3_DACB_AUTODETECT_CONTROL2, + DACx_AUTODETECT_POWERUP_COUNTER(0xB)); + WREG32(DCE3_DACB_AUTODETECT_CONTROL, + DACx_AUTODETECT_FRAME_TIME_COUNTER(0) | + DACx_AUTODETECT_CHECK_MASK(7)); + WREG32(DCE3_DACB_COMPARATOR_ENABLE, (DACx_R_ASYNC_ENABLE | + DACx_G_ASYNC_ENABLE | + DACx_B_ASYNC_ENABLE)); + WREG32(DCE3_DACB_AUTODETECT_CONTROL, + DACx_AUTODETECT_MODE(1) | + DACx_AUTODETECT_FRAME_TIME_COUNTER(0) | + DACx_AUTODETECT_CHECK_MASK(7)); + rdev->irq.dac[1] = true; + break; + default: + break; + } + } + } else { + list_for_each_entry(connector, &dev->mode_config.connector_list, head) { + struct radeon_connector *radeon_connector = to_radeon_connector(connector); + switch (radeon_connector->dac) { + case RADEON_DAC_A: + WREG32(DACA_FORCE_DATA, 0x20); + WREG32(DACA_AUTODETECT_INT_CONTROL, DACx_AUTODETECT_ACK); + WREG32(DACA_AUTODETECT_CONTROL3, + DACx_AUTODET_COMPARATOR_IN_DELAY(0x19) | + DACx_AUTODET_COMPARATOR_OUT_DELAY(0x5)); + WREG32(DACA_AUTODETECT_CONTROL2, + DACx_AUTODETECT_POWERUP_COUNTER(0xB)); + WREG32(DACA_AUTODETECT_CONTROL, + DACx_AUTODETECT_FRAME_TIME_COUNTER(0) | + DACx_AUTODETECT_CHECK_MASK(7)); + WREG32(DACA_COMPARATOR_ENABLE, (DACx_R_ASYNC_ENABLE | + DACx_G_ASYNC_ENABLE | + DACx_B_ASYNC_ENABLE)); + WREG32(DACA_AUTODETECT_CONTROL, + DACx_AUTODETECT_MODE(1) | + DACx_AUTODETECT_FRAME_TIME_COUNTER(0) | + DACx_AUTODETECT_CHECK_MASK(7)); + rdev->irq.dac[0] = true; + break; + case RADEON_DAC_B: + WREG32(DACB_FORCE_DATA, 0x20); + WREG32(DACB_AUTODETECT_INT_CONTROL, DACx_AUTODETECT_ACK); + WREG32(DACB_AUTODETECT_CONTROL3, + DACx_AUTODET_COMPARATOR_IN_DELAY(0x19) | + DACx_AUTODET_COMPARATOR_OUT_DELAY(0x5)); + WREG32(DACB_AUTODETECT_CONTROL2, + DACx_AUTODETECT_POWERUP_COUNTER(0xB)); + WREG32(DACB_AUTODETECT_CONTROL, + DACx_AUTODETECT_FRAME_TIME_COUNTER(0) | + DACx_AUTODETECT_CHECK_MASK(7)); + WREG32(DACB_COMPARATOR_ENABLE, (DACx_R_ASYNC_ENABLE | + DACx_G_ASYNC_ENABLE | + DACx_B_ASYNC_ENABLE)); + WREG32(DACB_AUTODETECT_CONTROL, + DACx_AUTODETECT_MODE(1) | + DACx_AUTODETECT_FRAME_TIME_COUNTER(0) | + DACx_AUTODETECT_CHECK_MASK(7)); + rdev->irq.dac[1] = true; + break; + default: + break; + } + } + } + udelay(50); + r600_irq_set(rdev); +} + +void r600_dac_fini(struct radeon_device *rdev) +{ + struct drm_device *dev = rdev->ddev; + struct drm_connector *connector; + + if (ASIC_IS_DCE3(rdev)) { + list_for_each_entry(connector, &dev->mode_config.connector_list, head) { + struct radeon_connector *radeon_connector = to_radeon_connector(connector); + switch (radeon_connector->dac) { + case RADEON_DAC_A: + WREG32(DCE3_DACA_AUTODETECT_CONTROL, + DACx_AUTODETECT_MODE(0)); + WREG32(DCE3_DACA_COMPARATOR_ENABLE, 0); + rdev->irq.dac[0] = false; + break; + case RADEON_DAC_B: + WREG32(DCE3_DACB_AUTODETECT_CONTROL, + DACx_AUTODETECT_MODE(0)); + WREG32(DCE3_DACB_COMPARATOR_ENABLE, 0); + rdev->irq.dac[1] = false; + break; + default: + break; + } + } + } else { + list_for_each_entry(connector, &dev->mode_config.connector_list, head) { + struct radeon_connector *radeon_connector = to_radeon_connector(connector); + switch (radeon_connector->dac) { + case RADEON_DAC_A: + WREG32(DACA_AUTODETECT_CONTROL, + DACx_AUTODETECT_MODE(0)); + WREG32(DACA_COMPARATOR_ENABLE, 0); + rdev->irq.dac[0] = false; + break; + case RADEON_DAC_B: + WREG32(DACB_AUTODETECT_CONTROL, + DACx_AUTODETECT_MODE(0)); + WREG32(DACB_COMPARATOR_ENABLE, 0); + rdev->irq.dac[1] = false; + break; + default: + break; + } + } + } +} + /* * R600 PCIE GART */ @@ -2453,6 +2706,7 @@ int r600_irq_set(struct radeon_device *rdev) u32 cp_int_cntl = CNTX_BUSY_INT_ENABLE | CNTX_EMPTY_INT_ENABLE; u32 mode_int = 0; u32 hpd1, hpd2, hpd3, hpd4 = 0, hpd5 = 0, hpd6 = 0; + u32 daca, dacb; /* don't enable anything if the ih is disabled */ if (!rdev->ih.enabled) @@ -2467,10 +2721,14 @@ int r600_irq_set(struct radeon_device *rdev) hpd5 = RREG32(DC_HPD5_INT_CONTROL) & ~DC_HPDx_INT_EN; hpd6 = RREG32(DC_HPD6_INT_CONTROL) & ~DC_HPDx_INT_EN; } + daca = RREG32(DCE3_DACA_AUTODETECT_INT_CONTROL) & ~DACx_AUTODETECT_INT_ENABLE; + dacb = RREG32(DCE3_DACB_AUTODETECT_INT_CONTROL) & ~DACx_AUTODETECT_INT_ENABLE; } else { hpd1 = RREG32(DC_HOT_PLUG_DETECT1_INT_CONTROL) & ~DC_HPDx_INT_EN; hpd2 = RREG32(DC_HOT_PLUG_DETECT2_INT_CONTROL) & ~DC_HPDx_INT_EN; hpd3 = RREG32(DC_HOT_PLUG_DETECT3_INT_CONTROL) & ~DC_HPDx_INT_EN; + daca = RREG32(DACA_AUTODETECT_INT_CONTROL) & ~DACx_AUTODETECT_INT_ENABLE; + dacb = RREG32(DACB_AUTODETECT_INT_CONTROL) & ~DACx_AUTODETECT_INT_ENABLE; } if (rdev->irq.sw_int) { @@ -2509,6 +2767,14 @@ int r600_irq_set(struct radeon_device *rdev) DRM_DEBUG("r600_irq_set: hpd 6\n"); hpd6 |= DC_HPDx_INT_EN; } + if (rdev->irq.dac[0]) { + DRM_DEBUG("r600_irq_set: dac a\n"); + daca |= DACx_AUTODETECT_INT_ENABLE; + } + if (rdev->irq.dac[1]) { + DRM_DEBUG("r600_irq_set: dac b\n"); + dacb |= DACx_AUTODETECT_INT_ENABLE; + } WREG32(CP_INT_CNTL, cp_int_cntl); WREG32(DxMODE_INT_MASK, mode_int); @@ -2521,10 +2787,14 @@ int r600_irq_set(struct radeon_device *rdev) WREG32(DC_HPD5_INT_CONTROL, hpd5); WREG32(DC_HPD6_INT_CONTROL, hpd6); } + WREG32(DCE3_DACA_AUTODETECT_INT_CONTROL, daca); + WREG32(DCE3_DACB_AUTODETECT_INT_CONTROL, dacb); } else { WREG32(DC_HOT_PLUG_DETECT1_INT_CONTROL, hpd1); WREG32(DC_HOT_PLUG_DETECT2_INT_CONTROL, hpd2); WREG32(DC_HOT_PLUG_DETECT3_INT_CONTROL, hpd3); + WREG32(DACA_AUTODETECT_INT_CONTROL, daca); + WREG32(DACB_AUTODETECT_INT_CONTROL, dacb); } return 0; @@ -2605,6 +2875,28 @@ static inline void r600_irq_ack(struct radeon_device *rdev, WREG32(DC_HPD6_INT_CONTROL, tmp); } } + if (*disp_int & DACA_AUTODETECT_INTERRUPT) { + if (ASIC_IS_DCE3(rdev)) { + tmp = RREG32(DCE3_DACA_AUTODETECT_INT_CONTROL); + tmp |= DACx_AUTODETECT_ACK; + WREG32(DCE3_DACA_AUTODETECT_INT_CONTROL, tmp); + } else { + tmp = RREG32(DACA_AUTODETECT_INT_CONTROL); + tmp |= DACx_AUTODETECT_ACK; + WREG32(DACA_AUTODETECT_INT_CONTROL, tmp); + } + } + if (*disp_int & DACB_AUTODETECT_INTERRUPT) { + if (ASIC_IS_DCE3(rdev)) { + tmp = RREG32(DCE3_DACB_AUTODETECT_INT_CONTROL); + tmp |= DACx_AUTODETECT_ACK; + WREG32(DCE3_DACB_AUTODETECT_INT_CONTROL, tmp); + } else { + tmp = RREG32(DACB_AUTODETECT_INT_CONTROL); + tmp |= DACx_AUTODETECT_ACK; + WREG32(DACB_AUTODETECT_INT_CONTROL, tmp); + } + } } void r600_irq_disable(struct radeon_device *rdev) @@ -2757,6 +3049,20 @@ restart_ih: DRM_DEBUG("IH: HPD2\n"); } break; + case 2: + if (disp_int & DACA_AUTODETECT_INTERRUPT) { + disp_int &= ~DACA_AUTODETECT_INTERRUPT; + queue_hotplug = true; + DRM_DEBUG("IH: DACA\n"); + } + break; + case 3: + if (disp_int & DACB_AUTODETECT_INTERRUPT) { + disp_int &= ~DACB_AUTODETECT_INTERRUPT; + queue_hotplug = true; + DRM_DEBUG("IH: DACB\n"); + } + break; case 4: if (disp_int_cont & DC_HPD3_INTERRUPT) { disp_int_cont &= ~DC_HPD3_INTERRUPT; diff --git a/drivers/gpu/drm/radeon/r600d.h b/drivers/gpu/drm/radeon/r600d.h index 05894ed..248e7c5 100644 --- a/drivers/gpu/drm/radeon/r600d.h +++ b/drivers/gpu/drm/radeon/r600d.h @@ -591,10 +591,10 @@ # define DC_HPD6_INTERRUPT (1 << 21) # define DC_HPD6_RX_INTERRUPT (1 << 22) -#define DACA_AUTO_DETECT_CONTROL 0x7828 -#define DACB_AUTO_DETECT_CONTROL 0x7a28 -#define DCE3_DACA_AUTO_DETECT_CONTROL 0x7028 -#define DCE3_DACB_AUTO_DETECT_CONTROL 0x7128 +#define DACA_AUTODETECT_CONTROL 0x7828 +#define DACB_AUTODETECT_CONTROL 0x7a28 +#define DCE3_DACA_AUTODETECT_CONTROL 0x7028 +#define DCE3_DACB_AUTODETECT_CONTROL 0x7128 # define DACx_AUTODETECT_MODE(x) ((x) << 0) # define DACx_AUTODETECT_MODE_NONE 0 # define DACx_AUTODETECT_MODE_CONNECT 1 @@ -603,6 +603,29 @@ /* bit 18 = R/C, 17 = G/Y, 16 = B/Comp */ # define DACx_AUTODETECT_CHECK_MASK(x) ((x) << 16) +#define DACA_AUTODETECT_CONTROL2 0x782c +#define DACB_AUTODETECT_CONTROL2 0x7a2c +#define DCE3_DACA_AUTODETECT_CONTROL2 0x702c +#define DCE3_DACB_AUTODETECT_CONTROL2 0x712c +# define DACx_AUTODETECT_POWERUP_COUNTER(x) ((x) << 0) + +#define DACA_AUTODETECT_CONTROL3 0x7830 +#define DACB_AUTODETECT_CONTROL3 0x7a30 +#define DCE3_DACA_AUTODETECT_CONTROL3 0x7030 +#define DCE3_DACB_AUTODETECT_CONTROL3 0x7130 +# define DACx_AUTODET_COMPARATOR_IN_DELAY(x) ((x) << 0) +# define DACx_AUTODET_COMPARATOR_OUT_DELAY(x) ((x) << 8) + +#define DACA_AUTODETECT_STATUS 0x7834 +#define DACB_AUTODETECT_STATUS 0x7a34 +#define DCE3_DACA_AUTODETECT_STATUS 0x7034 +#define DCE3_DACB_AUTODETECT_STATUS 0x7134 +# define DACx_AUTODETECT_STATUS (1 << 0) +# define DACx_AUTODETECT_CONNECT (1 << 4) +# define DACx_AUTODETECT_RED_SENSE(x) ((x) << 8) +# define DACx_AUTODETECT_GREEN_SENSE(x) ((x) << 16) +# define DACx_AUTODETECT_BLUE_SENSE(x) ((x) << 24) + #define DCE3_DACA_AUTODETECT_INT_CONTROL 0x7038 #define DCE3_DACB_AUTODETECT_INT_CONTROL 0x7138 #define DACA_AUTODETECT_INT_CONTROL 0x7838 @@ -610,6 +633,19 @@ # define DACx_AUTODETECT_ACK (1 << 0) # define DACx_AUTODETECT_INT_ENABLE (1 << 16) +#define DACA_FORCE_DATA 0x7840 +#define DACB_FORCE_DATA 0x7a40 +#define DCE3_DACA_FORCE_DATA 0x7040 +#define DCE3_DACB_FORCE_DATA 0x7140 + +#define DACA_COMPARATOR_ENABLE 0x785c +#define DACB_COMPARATOR_ENABLE 0x7a5c +#define DCE3_DACA_COMPARATOR_ENABLE 0x705c +#define DCE3_DACB_COMPARATOR_ENABLE 0x715c +# define DACx_R_ASYNC_ENABLE (1 << 16) +# define DACx_G_ASYNC_ENABLE (1 << 17) +# define DACx_B_ASYNC_ENABLE (1 << 18) + #define DC_HOT_PLUG_DETECT1_CONTROL 0x7d00 #define DC_HOT_PLUG_DETECT2_CONTROL 0x7d10 #define DC_HOT_PLUG_DETECT3_CONTROL 0x7d24 diff --git a/drivers/gpu/drm/radeon/radeon.h b/drivers/gpu/drm/radeon/radeon.h index 6236c88..a33e379 100644 --- a/drivers/gpu/drm/radeon/radeon.h +++ b/drivers/gpu/drm/radeon/radeon.h @@ -341,6 +341,7 @@ struct radeon_irq { bool crtc_vblank_int[2]; /* FIXME: use defines for max hpd/dacs */ bool hpd[6]; + bool dac[2]; spinlock_t sw_lock; int sw_refcount; }; @@ -653,6 +654,10 @@ struct radeon_asic { void (*hpd_fini)(struct radeon_device *rdev); bool (*hpd_sense)(struct radeon_device *rdev, enum radeon_hpd_id hpd); void (*hpd_set_polarity)(struct radeon_device *rdev, enum radeon_hpd_id hpd); + void (*dac_init)(struct radeon_device *rdev); + void (*dac_fini)(struct radeon_device *rdev); + bool (*dac_sense)(struct radeon_device *rdev, enum radeon_dac_id dac); + void (*dac_set_polarity)(struct radeon_device *rdev, enum radeon_dac_id dac); }; /* @@ -998,6 +1003,10 @@ static inline void radeon_ring_write(struct radeon_device *rdev, uint32_t v) #define radeon_hpd_fini(rdev) (rdev)->asic->hpd_fini((rdev)) #define radeon_hpd_sense(rdev, hpd) (rdev)->asic->hpd_sense((rdev), (hpd)) #define radeon_hpd_set_polarity(rdev, hpd) (rdev)->asic->hpd_set_polarity((rdev), (hpd)) +#define radeon_dac_init(rdev) (rdev)->asic->dac_init((rdev)) +#define radeon_dac_fini(rdev) (rdev)->asic->dac_fini((rdev)) +#define radeon_dac_sense(rdev, dac) (rdev)->asic->dac_sense((rdev), (dac)) +#define radeon_dac_set_polarity(rdev, dac) (rdev)->asic->dac_set_polarity((rdev), (dac)) /* Common functions */ extern int radeon_gart_table_vram_pin(struct radeon_device *rdev); diff --git a/drivers/gpu/drm/radeon/radeon_asic.h b/drivers/gpu/drm/radeon/radeon_asic.h index 636116b..b475b47 100644 --- a/drivers/gpu/drm/radeon/radeon_asic.h +++ b/drivers/gpu/drm/radeon/radeon_asic.h @@ -82,6 +82,11 @@ void r100_hpd_fini(struct radeon_device *rdev); bool r100_hpd_sense(struct radeon_device *rdev, enum radeon_hpd_id hpd); void r100_hpd_set_polarity(struct radeon_device *rdev, enum radeon_hpd_id hpd); +void r100_dac_init(struct radeon_device *rdev); +void r100_dac_fini(struct radeon_device *rdev); +bool r100_dac_sense(struct radeon_device *rdev, enum radeon_dac_id dac); +void r100_dac_set_polarity(struct radeon_device *rdev, + enum radeon_dac_id dac); static struct radeon_asic r100_asic = { .init = &r100_init, @@ -118,6 +123,10 @@ static struct radeon_asic r100_asic = { .hpd_fini = &r100_hpd_fini, .hpd_sense = &r100_hpd_sense, .hpd_set_polarity = &r100_hpd_set_polarity, + .dac_init = &r100_dac_init, + .dac_fini = &r100_dac_fini, + .dac_sense = &r100_dac_sense, + .dac_set_polarity = &r100_dac_set_polarity, }; @@ -178,6 +187,10 @@ static struct radeon_asic r300_asic = { .hpd_fini = &r100_hpd_fini, .hpd_sense = &r100_hpd_sense, .hpd_set_polarity = &r100_hpd_set_polarity, + .dac_init = &r100_dac_init, + .dac_fini = &r100_dac_fini, + .dac_sense = &r100_dac_sense, + .dac_set_polarity = &r100_dac_set_polarity, }; /* @@ -222,6 +235,10 @@ static struct radeon_asic r420_asic = { .hpd_fini = &r100_hpd_fini, .hpd_sense = &r100_hpd_sense, .hpd_set_polarity = &r100_hpd_set_polarity, + .dac_init = &r100_dac_init, + .dac_fini = &r100_dac_fini, + .dac_sense = &r100_dac_sense, + .dac_set_polarity = &r100_dac_set_polarity, }; @@ -271,6 +288,10 @@ static struct radeon_asic rs400_asic = { .hpd_fini = &r100_hpd_fini, .hpd_sense = &r100_hpd_sense, .hpd_set_polarity = &r100_hpd_set_polarity, + .dac_init = &r100_dac_init, + .dac_fini = &r100_dac_fini, + .dac_sense = &r100_dac_sense, + .dac_set_polarity = &r100_dac_set_polarity, }; @@ -294,6 +315,11 @@ void rs600_hpd_fini(struct radeon_device *rdev); bool rs600_hpd_sense(struct radeon_device *rdev, enum radeon_hpd_id hpd); void rs600_hpd_set_polarity(struct radeon_device *rdev, enum radeon_hpd_id hpd); +void rs600_dac_init(struct radeon_device *rdev); +void rs600_dac_fini(struct radeon_device *rdev); +bool rs600_dac_sense(struct radeon_device *rdev, enum radeon_dac_id dac); +void rs600_dac_set_polarity(struct radeon_device *rdev, + enum radeon_dac_id dac); static struct radeon_asic rs600_asic = { .init = &rs600_init, @@ -328,6 +354,10 @@ static struct radeon_asic rs600_asic = { .hpd_fini = &rs600_hpd_fini, .hpd_sense = &rs600_hpd_sense, .hpd_set_polarity = &rs600_hpd_set_polarity, + .dac_init = &rs600_dac_init, + .dac_fini = &rs600_dac_fini, + .dac_sense = &rs600_dac_sense, + .dac_set_polarity = &rs600_dac_set_polarity, }; @@ -376,6 +406,10 @@ static struct radeon_asic rs690_asic = { .hpd_fini = &rs600_hpd_fini, .hpd_sense = &rs600_hpd_sense, .hpd_set_polarity = &rs600_hpd_set_polarity, + .dac_init = &rs600_dac_init, + .dac_fini = &rs600_dac_fini, + .dac_sense = &rs600_dac_sense, + .dac_set_polarity = &rs600_dac_set_polarity, }; @@ -428,6 +462,10 @@ static struct radeon_asic rv515_asic = { .hpd_fini = &rs600_hpd_fini, .hpd_sense = &rs600_hpd_sense, .hpd_set_polarity = &rs600_hpd_set_polarity, + .dac_init = &rs600_dac_init, + .dac_fini = &rs600_dac_fini, + .dac_sense = &rs600_dac_sense, + .dac_set_polarity = &rs600_dac_set_polarity, }; @@ -471,6 +509,10 @@ static struct radeon_asic r520_asic = { .hpd_fini = &rs600_hpd_fini, .hpd_sense = &rs600_hpd_sense, .hpd_set_polarity = &rs600_hpd_set_polarity, + .dac_init = &rs600_dac_init, + .dac_fini = &rs600_dac_fini, + .dac_sense = &rs600_dac_sense, + .dac_set_polarity = &rs600_dac_set_polarity, }; /* @@ -513,6 +555,11 @@ void r600_hpd_fini(struct radeon_device *rdev); bool r600_hpd_sense(struct radeon_device *rdev, enum radeon_hpd_id hpd); void r600_hpd_set_polarity(struct radeon_device *rdev, enum radeon_hpd_id hpd); +void r600_dac_init(struct radeon_device *rdev); +void r600_dac_fini(struct radeon_device *rdev); +bool r600_dac_sense(struct radeon_device *rdev, enum radeon_dac_id dac); +void r600_dac_set_polarity(struct radeon_device *rdev, + enum radeon_dac_id dac); static struct radeon_asic r600_asic = { .init = &r600_init, @@ -548,6 +595,10 @@ static struct radeon_asic r600_asic = { .hpd_fini = &r600_hpd_fini, .hpd_sense = &r600_hpd_sense, .hpd_set_polarity = &r600_hpd_set_polarity, + .dac_init = &r600_dac_init, + .dac_fini = &r600_dac_fini, + .dac_sense = &r600_dac_sense, + .dac_set_polarity = &r600_dac_set_polarity, }; /* @@ -593,6 +644,10 @@ static struct radeon_asic rv770_asic = { .hpd_fini = &r600_hpd_fini, .hpd_sense = &r600_hpd_sense, .hpd_set_polarity = &r600_hpd_set_polarity, + .dac_init = &r600_dac_init, + .dac_fini = &r600_dac_fini, + .dac_sense = &r600_dac_sense, + .dac_set_polarity = &r600_dac_set_polarity, }; #endif diff --git a/drivers/gpu/drm/radeon/radeon_connectors.c b/drivers/gpu/drm/radeon/radeon_connectors.c index cfa2ebb..079a24b 100644 --- a/drivers/gpu/drm/radeon/radeon_connectors.c +++ b/drivers/gpu/drm/radeon/radeon_connectors.c @@ -49,6 +49,9 @@ void radeon_connector_hotplug(struct drm_connector *connector) if (radeon_connector->hpd.hpd != RADEON_HPD_NONE) radeon_hpd_set_polarity(rdev, radeon_connector->hpd.hpd); + if (radeon_connector->dac != RADEON_HPD_NONE) + radeon_dac_set_polarity(rdev, radeon_connector->dac); + if (connector->connector_type == DRM_MODE_CONNECTOR_DisplayPort) { if (radeon_dp_getsinktype(radeon_connector) == CONNECTOR_OBJECT_ID_DISPLAYPORT) { if (radeon_dp_needs_link_train(radeon_connector)) { @@ -1051,6 +1054,20 @@ radeon_add_atom_connector(struct drm_device *dev, radeon_connector->shared_ddc = shared_ddc; radeon_connector->connector_object_id = connector_object_id; radeon_connector->hpd = *hpd; + /* XXX for dac auto detection */ + /* FIXME look up based on encoder */ + if (radeon_connector->devices & ATOM_DEVICE_CRT1_SUPPORT) + radeon_connector->dac = RADEON_DAC_A; + else if (radeon_connector->devices & ATOM_DEVICE_CRT2_SUPPORT) + radeon_connector->dac = RADEON_DAC_B; + else if (radeon_connector->devices & ATOM_DEVICE_TV1_SUPPORT) { + /* XXX */ + if (rdev->flags & RADEON_IS_IGP) + radeon_connector->dac = RADEON_DAC_A; + else + radeon_connector->dac = RADEON_DAC_B; + } else + radeon_connector->dac = RADEON_DAC_NONE; switch (connector_type) { case DRM_MODE_CONNECTOR_VGA: drm_connector_init(dev, &radeon_connector->base, &radeon_vga_connector_funcs, connector_type); @@ -1240,6 +1257,8 @@ radeon_add_legacy_connector(struct drm_device *dev, radeon_connector->devices = supported_device; radeon_connector->connector_object_id = connector_object_id; radeon_connector->hpd = *hpd; + /* for dac auto detection */ + radeon_connector->dac = RADEON_DAC_NONE; switch (connector_type) { case DRM_MODE_CONNECTOR_VGA: drm_connector_init(dev, &radeon_connector->base, &radeon_vga_connector_funcs, connector_type); diff --git a/drivers/gpu/drm/radeon/radeon_device.c b/drivers/gpu/drm/radeon/radeon_device.c index 7e55647..0ab316f 100644 --- a/drivers/gpu/drm/radeon/radeon_device.c +++ b/drivers/gpu/drm/radeon/radeon_device.c @@ -696,6 +696,7 @@ int radeon_suspend_kms(struct drm_device *dev, pm_message_t state) radeon_suspend(rdev); radeon_hpd_fini(rdev); + radeon_dac_fini(rdev); /* evict remaining vram memory */ radeon_bo_evict_vram(rdev); @@ -732,6 +733,8 @@ int radeon_resume_kms(struct drm_device *dev) /* reset hpd state */ radeon_hpd_init(rdev); + /* reset dac autodetect state */ + radeon_dac_init(rdev); /* blat the mode back in */ drm_helper_resume_force_mode(dev); return 0; diff --git a/drivers/gpu/drm/radeon/radeon_display.c b/drivers/gpu/drm/radeon/radeon_display.c index c115f2e..a2d40d8 100644 --- a/drivers/gpu/drm/radeon/radeon_display.c +++ b/drivers/gpu/drm/radeon/radeon_display.c @@ -743,6 +743,8 @@ int radeon_modeset_init(struct radeon_device *rdev) } /* initialize hpd */ radeon_hpd_init(rdev); + /* initialize dac autodetect */ + radeon_dac_init(rdev); drm_helper_initial_config(rdev->ddev); return 0; } @@ -751,6 +753,7 @@ void radeon_modeset_fini(struct radeon_device *rdev) { if (rdev->mode_info.mode_config_initialized) { radeon_hpd_fini(rdev); + radeon_dac_fini(rdev); drm_mode_config_cleanup(rdev->ddev); rdev->mode_info.mode_config_initialized = false; } diff --git a/drivers/gpu/drm/radeon/radeon_mode.h b/drivers/gpu/drm/radeon/radeon_mode.h index 4d48820..42fa3b0 100644 --- a/drivers/gpu/drm/radeon/radeon_mode.h +++ b/drivers/gpu/drm/radeon/radeon_mode.h @@ -370,6 +370,12 @@ struct radeon_hpd { struct radeon_gpio_rec gpio; }; +enum radeon_dac_id { + RADEON_DAC_NONE = 0, + RADEON_DAC_A, + RADEON_DAC_B, +}; + struct radeon_connector { struct drm_connector base; uint32_t connector_id; @@ -385,6 +391,7 @@ struct radeon_connector { bool dac_load_detect; uint16_t connector_object_id; struct radeon_hpd hpd; + enum radeon_dac_id dac; }; struct radeon_framebuffer { diff --git a/drivers/gpu/drm/radeon/rs600.c b/drivers/gpu/drm/radeon/rs600.c index 34279b8..dce77f0 100644 --- a/drivers/gpu/drm/radeon/rs600.c +++ b/drivers/gpu/drm/radeon/rs600.c @@ -145,6 +145,141 @@ void rs600_hpd_fini(struct radeon_device *rdev) } } +/* autodetect for analog detect/disconnect */ +bool rs600_dac_sense(struct radeon_device *rdev, enum radeon_dac_id dac) +{ + u32 tmp; + bool connected = false; + + switch (dac) { + case RADEON_DAC_A: + tmp = RREG32(R_007834_DACA_AUTODETECT_STATUS); + DRM_INFO("DACA status 0x%08x\n", tmp); + if (G_007834_DACA_AUTODETECT_CONNECT(tmp)) + connected = true; + break; + case RADEON_DAC_B: + tmp = RREG32(R_007A34_DACB_AUTODETECT_STATUS); + DRM_INFO("DACB status 0x%08x\n", tmp); + if (G_007A34_DACB_AUTODETECT_CONNECT(tmp)) + connected = true; + break; + default: + break; + } + return connected; +} + +void rs600_dac_set_polarity(struct radeon_device *rdev, + enum radeon_dac_id dac) +{ + u32 tmp; + bool connected = rs600_dac_sense(rdev, dac); + + switch (dac) { + case RADEON_DAC_A: + tmp = RREG32(R_007828_DACA_AUTODETECT_CONTROL) & ~S_007828_DACA_AUTODETECT_MODE(3); + if (connected) + tmp |= S_007828_DACA_AUTODETECT_MODE(2); + else + tmp |= S_007828_DACA_AUTODETECT_MODE(1); + WREG32(R_007828_DACA_AUTODETECT_CONTROL, tmp); + udelay(50); + break; + case RADEON_DAC_B: + tmp = RREG32(R_007A28_DACB_AUTODETECT_CONTROL) & ~S_007A28_DACB_AUTODETECT_MODE(3); + if (connected) + tmp |= S_007A28_DACB_AUTODETECT_MODE(2); + else + tmp |= S_007A28_DACB_AUTODETECT_MODE(1); + WREG32(R_007A28_DACB_AUTODETECT_CONTROL, tmp); + udelay(50); + break; + default: + break; + } +} + +void rs600_dac_init(struct radeon_device *rdev) +{ + struct drm_device *dev = rdev->ddev; + struct drm_connector *connector; + + list_for_each_entry(connector, &dev->mode_config.connector_list, head) { + struct radeon_connector *radeon_connector = to_radeon_connector(connector); + switch (radeon_connector->hpd.hpd) { + case RADEON_DAC_A: + WREG32(R_007840_DACA_FORCE_DATA, 0x20); + WREG32(R_007838_DACA_AUTODETECT_INT_CONTROL, + S_007838_DACA_AUTODETECT_ACK(1)); + WREG32(R_00782C_DACA_AUTODETECT_CONTROL2, + S_00782C_DACA_AUTODETECT_POWERUP_COUNTER(0xB)); + WREG32(R_007828_DACA_AUTODETECT_CONTROL, + S_007828_DACA_AUTODETECT_FRAME_TIME_COUNTER(0) | + S_007828_DACA_AUTODETECT_CHECK_MASK(7)); + WREG32(R_00785C_DACA_COMPARATOR_ENABLE, + (S_00785C_DACA_R_ASYNC_ENABLE(1) | + S_00785C_DACA_G_ASYNC_ENABLE(1) | + S_00785C_DACA_B_ASYNC_ENABLE(1))); + WREG32(R_007828_DACA_AUTODETECT_CONTROL, + S_007828_DACA_AUTODETECT_MODE(1) | + S_007828_DACA_AUTODETECT_FRAME_TIME_COUNTER(0) | + S_007828_DACA_AUTODETECT_CHECK_MASK(7)); + rdev->irq.dac[0] = true; + break; + case RADEON_DAC_B: + WREG32(R_007A40_DACB_FORCE_DATA, 0x20); + WREG32(R_007A38_DACB_AUTODETECT_INT_CONTROL, + S_007A38_DACB_AUTODETECT_ACK(1)); + WREG32(R_007A2C_DACB_AUTODETECT_CONTROL2, + S_007A2C_DACB_AUTODETECT_POWERUP_COUNTER(0xB)); + WREG32(R_007A28_DACB_AUTODETECT_CONTROL, + S_007A28_DACB_AUTODETECT_FRAME_TIME_COUNTER(0) | + S_007A28_DACB_AUTODETECT_CHECK_MASK(7)); + WREG32(R_007A5C_DACB_COMPARATOR_ENABLE, + (S_007A5C_DACB_R_ASYNC_ENABLE(1) | + S_007A5C_DACB_G_ASYNC_ENABLE(1) | + S_007A5C_DACB_B_ASYNC_ENABLE(1))); + WREG32(R_007A28_DACB_AUTODETECT_CONTROL, + S_007A28_DACB_AUTODETECT_MODE(1) | + S_007A28_DACB_AUTODETECT_FRAME_TIME_COUNTER(0) | + S_007A28_DACB_AUTODETECT_CHECK_MASK(7)); + rdev->irq.dac[1] = true; + break; + default: + break; + } + } + udelay(50); + rs600_irq_set(rdev); +} + +void rs600_dac_fini(struct radeon_device *rdev) +{ + struct drm_device *dev = rdev->ddev; + struct drm_connector *connector; + + list_for_each_entry(connector, &dev->mode_config.connector_list, head) { + struct radeon_connector *radeon_connector = to_radeon_connector(connector); + switch (radeon_connector->dac) { + case RADEON_DAC_A: + WREG32(R_007828_DACA_AUTODETECT_CONTROL, + S_007828_DACA_AUTODETECT_MODE(0)); + WREG32(R_00785C_DACA_COMPARATOR_ENABLE, 0); + rdev->irq.dac[0] = false; + break; + case RADEON_DAC_B: + WREG32(R_007A28_DACB_AUTODETECT_CONTROL, + S_007A28_DACB_AUTODETECT_MODE(0)); + WREG32(R_007A5C_DACB_COMPARATOR_ENABLE, 0); + rdev->irq.dac[1] = false; + break; + default: + break; + } + } +} + /* * GART. */ @@ -298,6 +433,10 @@ int rs600_irq_set(struct radeon_device *rdev) ~S_007D08_DC_HOT_PLUG_DETECT1_INT_EN(1); u32 hpd2 = RREG32(R_007D18_DC_HOT_PLUG_DETECT2_INT_CONTROL) & ~S_007D18_DC_HOT_PLUG_DETECT2_INT_EN(1); + u32 daca = RREG32(R_007838_DACA_AUTODETECT_INT_CONTROL) & + ~S_007838_DACA_AUTODETECT_INT_ENABLE(1); + u32 dacb = RREG32(R_007A38_DACB_AUTODETECT_INT_CONTROL) & + ~S_007A38_DACB_AUTODETECT_INT_ENABLE(1); if (rdev->irq.sw_int) { tmp |= S_000040_SW_INT_EN(1); @@ -314,10 +453,18 @@ int rs600_irq_set(struct radeon_device *rdev) if (rdev->irq.hpd[1]) { hpd2 |= S_007D18_DC_HOT_PLUG_DETECT2_INT_EN(1); } + if (rdev->irq.dac[0]) { + daca |= S_007838_DACA_AUTODETECT_INT_ENABLE(1); + } + if (rdev->irq.dac[1]) { + dacb |= S_007A38_DACB_AUTODETECT_INT_ENABLE(1); + } WREG32(R_000040_GEN_INT_CNTL, tmp); WREG32(R_006540_DxMODE_INT_MASK, mode_int); WREG32(R_007D08_DC_HOT_PLUG_DETECT1_INT_CONTROL, hpd1); WREG32(R_007D18_DC_HOT_PLUG_DETECT2_INT_CONTROL, hpd2); + WREG32(R_007838_DACA_AUTODETECT_INT_CONTROL, daca); + WREG32(R_007A38_DACB_AUTODETECT_INT_CONTROL, dacb); return 0; } @@ -347,6 +494,16 @@ static inline uint32_t rs600_irq_ack(struct radeon_device *rdev, u32 *r500_disp_ tmp |= S_007D18_DC_HOT_PLUG_DETECT2_INT_ACK(1); WREG32(R_007D18_DC_HOT_PLUG_DETECT2_INT_CONTROL, tmp); } + if (G_007EDC_DACA_AUTODETECT_INTERRUPT(*r500_disp_int)) { + tmp = RREG32(R_007838_DACA_AUTODETECT_INT_CONTROL); + tmp |= S_007838_DACA_AUTODETECT_ACK(1); + WREG32(R_007838_DACA_AUTODETECT_INT_CONTROL, tmp); + } + if (G_007EDC_DACB_AUTODETECT_INTERRUPT(*r500_disp_int)) { + tmp = RREG32(R_007A38_DACB_AUTODETECT_INT_CONTROL); + tmp |= S_007A38_DACB_AUTODETECT_ACK(1); + WREG32(R_007A38_DACB_AUTODETECT_INT_CONTROL, tmp); + } } else { *r500_disp_int = 0; } @@ -395,6 +552,14 @@ int rs600_irq_process(struct radeon_device *rdev) queue_hotplug = true; DRM_DEBUG("HPD2\n"); } + if (G_007EDC_DACA_AUTODETECT_INTERRUPT(r500_disp_int)) { + queue_hotplug = true; + DRM_DEBUG("DACA\n"); + } + if (G_007EDC_DACB_AUTODETECT_INTERRUPT(r500_disp_int)) { + queue_hotplug = true; + DRM_DEBUG("DACB\n"); + } status = rs600_irq_ack(rdev, &r500_disp_int); } if (queue_hotplug) diff --git a/drivers/gpu/drm/radeon/rs600d.h b/drivers/gpu/drm/radeon/rs600d.h index c1c8f58..08209b7 100644 --- a/drivers/gpu/drm/radeon/rs600d.h +++ b/drivers/gpu/drm/radeon/rs600d.h @@ -377,12 +377,43 @@ #define S_007828_DACA_AUTODETECT_CHECK_MASK(x) (((x) & 0x3) << 16) #define G_007828_DACA_AUTODETECT_CHECK_MASK(x) (((x) >> 16) & 0x3) #define C_007828_DACA_AUTODETECT_CHECK_MASK 0xFFFCFFFF +#define R_00782C_DACA_AUTODETECT_CONTROL2 0x00782C +#define S_00782C_DACA_AUTODETECT_POWERUP_COUNTER(x) (((x) & 0xff) << 0) +#define G_00782C_DACA_AUTODETECT_POWERUP_COUNTER(x) (((x) >> 0) & 0xff) +#define C_00782C_DACA_AUTODETECT_MODE 0xFFFFFF00 +#define R_007834_DACA_AUTODETECT_STATUS 0x007834 +#define S_007834_DACA_AUTODETECT_STATUS(x) (((x) & 0x1) << 0) +#define G_007834_DACA_AUTODETECT_STATUS(x) (((x) >> 0) & 0x1) +#define C_007834_DACA_AUTODETECT_STATUS 0xFFFFFFFE +#define S_007834_DACA_AUTODETECT_CONNECT(x) (((x) & 0x1) << 4) +#define G_007834_DACA_AUTODETECT_CONNECT(x) (((x) >> 4) & 0x1) +#define C_007834_DACA_AUTODETECT_CONNECT 0xFFFFFFEF +#define S_007834_DACA_AUTODETECT_RED_SENSE(x) (((x) & 0x3) << 8) +#define G_007834_DACA_AUTODETECT_RED_SENSE(x) (((x) >> 8) & 0x3) +#define C_007834_DACA_AUTODETECT_RED_SENSE 0xFFFFFCFF +#define S_007834_DACA_AUTODETECT_GREEN_SENSE(x) (((x) & 0x3) << 16) +#define G_007834_DACA_AUTODETECT_GREEN_SENSE(x) (((x) >> 16) & 0x3) +#define C_007834_DACA_AUTODETECT_GREEN_SENSE 0xFFFCFFFF +#define S_007834_DACA_AUTODETECT_BLUE_SENSE(x) (((x) & 0x3) << 24) +#define G_007834_DACA_AUTODETECT_BLUE_SENSE(x) (((x) >> 24) & 0x3) +#define C_007834_DACA_AUTODETECT_BLUE_SENSE 0xFCFFFFFF #define R_007838_DACA_AUTODETECT_INT_CONTROL 0x007838 #define S_007838_DACA_AUTODETECT_ACK(x) (((x) & 0x1) << 0) #define C_007838_DACA_DACA_AUTODETECT_ACK 0xFFFFFFFE #define S_007838_DACA_AUTODETECT_INT_ENABLE(x) (((x) & 0x1) << 16) #define G_007838_DACA_AUTODETECT_INT_ENABLE(x) (((x) >> 16) & 0x1) -#define C_007838_DACA_AUTODETECT_INT_ENABLE 0xFFFCFFFF +#define C_007838_DACA_AUTODETECT_INT_ENABLE 0xFFFEFFFF +#define R_007840_DACA_FORCE_DATA 0x007840 +#define R_00785C_DACA_COMPARATOR_ENABLE 0x00785c +#define S_00785C_DACA_R_ASYNC_ENABLE(x) (((x) & 0x1) << 16) +#define G_00785C_DACA_R_ASYNC_ENABLE(x) (((x) >> 16) & 0x1) +#define C_00785C_DACA_R_ASYNC_ENABLE 0xFFFEFFFF +#define S_00785C_DACA_G_ASYNC_ENABLE(x) (((x) & 0x1) << 17) +#define G_00785C_DACA_G_ASYNC_ENABLE(x) (((x) >> 17) & 0x1) +#define C_00785C_DACA_G_ASYNC_ENABLE 0xFFFDFFFF +#define S_00785C_DACA_B_ASYNC_ENABLE(x) (((x) & 0x1) << 18) +#define G_00785C_DACA_B_ASYNC_ENABLE(x) (((x) >> 18) & 0x1) +#define C_00785C_DACA_B_ASYNC_ENABLE 0xFFFBFFFF #define R_007A28_DACB_AUTODETECT_CONTROL 0x007A28 #define S_007A28_DACB_AUTODETECT_MODE(x) (((x) & 0x3) << 0) #define G_007A28_DACB_AUTODETECT_MODE(x) (((x) >> 0) & 0x3) @@ -393,12 +424,43 @@ #define S_007A28_DACB_AUTODETECT_CHECK_MASK(x) (((x) & 0x3) << 16) #define G_007A28_DACB_AUTODETECT_CHECK_MASK(x) (((x) >> 16) & 0x3) #define C_007A28_DACB_AUTODETECT_CHECK_MASK 0xFFFCFFFF +#define R_007A2C_DACB_AUTODETECT_CONTROL2 0x007A2C +#define S_007A2C_DACB_AUTODETECT_POWERUP_COUNTER(x) (((x) & 0xff) << 0) +#define G_007S2C_DACB_AUTODETECT_POWERUP_COUNTER(x) (((x) >> 0) & 0xff) +#define C_007A2C_DACB_AUTODETECT_MODE 0xFFFFFF00 +#define R_007A34_DACB_AUTODETECT_STATUS 0x007A34 +#define S_007A34_DACB_AUTODETECT_STATUS(x) (((x) & 0x1) << 0) +#define G_007A34_DACB_AUTODETECT_STATUS(x) (((x) >> 0) & 0x1) +#define C_007A34_DACB_AUTODETECT_STATUS 0xFFFFFFFE +#define S_007A34_DACB_AUTODETECT_CONNECT(x) (((x) & 0x1) << 4) +#define G_007A34_DACB_AUTODETECT_CONNECT(x) (((x) >> 4) & 0x1) +#define C_007A34_DACB_AUTODETECT_CONNECT 0xFFFFFFEF +#define S_007A34_DACB_AUTODETECT_RED_SENSE(x) (((x) & 0x3) << 8) +#define G_007A34_DACB_AUTODETECT_RED_SENSE(x) (((x) >> 8) & 0x3) +#define C_007A34_DACB_AUTODETECT_RED_SENSE 0xFFFFFCFF +#define S_007A34_DACB_AUTODETECT_GREEN_SENSE(x) (((x) & 0x3) << 16) +#define G_007A34_DACB_AUTODETECT_GREEN_SENSE(x) (((x) >> 16) & 0x3) +#define C_007A34_DACB_AUTODETECT_GREEN_SENSE 0xFFFCFFFF +#define S_007A34_DACB_AUTODETECT_BLUE_SENSE(x) (((x) & 0x3) << 24) +#define G_007A34_DACB_AUTODETECT_BLUE_SENSE(x) (((x) >> 24) & 0x3) +#define C_007A34_DACB_AUTODETECT_BLUE_SENSE 0xFCFFFFFF #define R_007A38_DACB_AUTODETECT_INT_CONTROL 0x007A38 #define S_007A38_DACB_AUTODETECT_ACK(x) (((x) & 0x1) << 0) #define C_007A38_DACB_DACA_AUTODETECT_ACK 0xFFFFFFFE #define S_007A38_DACB_AUTODETECT_INT_ENABLE(x) (((x) & 0x1) << 16) #define G_007A38_DACB_AUTODETECT_INT_ENABLE(x) (((x) >> 16) & 0x1) #define C_007A38_DACB_AUTODETECT_INT_ENABLE 0xFFFCFFFF +#define R_007A40_DACB_FORCE_DATA 0x007A40 +#define R_007A5C_DACB_COMPARATOR_ENABLE 0x00785c +#define S_007A5C_DACB_R_ASYNC_ENABLE(x) (((x) & 0x1) << 16) +#define G_007A5C_DACB_R_ASYNC_ENABLE(x) (((x) >> 16) & 0x1) +#define C_007A5C_DACB_R_ASYNC_ENABLE 0xFFFEFFFF +#define S_007A5C_DACB_G_ASYNC_ENABLE(x) (((x) & 0x1) << 17) +#define G_007A5C_DACB_G_ASYNC_ENABLE(x) (((x) >> 17) & 0x1) +#define C_007A5C_DACB_G_ASYNC_ENABLE 0xFFFDFFFF +#define S_007A5C_DACB_B_ASYNC_ENABLE(x) (((x) & 0x1) << 18) +#define G_007A5C_DACB_B_ASYNC_ENABLE(x) (((x) >> 18) & 0x1) +#define C_007A5C_DACB_B_ASYNC_ENABLE 0xFFFBFFFF #define R_007D00_DC_HOT_PLUG_DETECT1_CONTROL 0x007D00 #define S_007D00_DC_HOT_PLUG_DETECT1_EN(x) (((x) & 0x1) << 0) #define G_007D00_DC_HOT_PLUG_DETECT1_EN(x) (((x) >> 0) & 0x1) -- 1.5.6.3