From: "Rafał Miłecki" <zajec5@gmail.com>
To: dri-devel@lists.sourceforge.net, Dave Airlie <airlied@gmail.com>
Cc: "Christian König" <deathsimple@vodafone.de>
Subject: [PATCH 2/6] drm/radeon/kms: clean assigning HDMI blocks to encoders
Date: Sat, 6 Mar 2010 14:03:34 +0100 [thread overview]
Message-ID: <1267880618-9909-3-git-send-email-zajec5@gmail.com> (raw)
In-Reply-To: <1267880618-9909-1-git-send-email-zajec5@gmail.com>
We almost always used first HDMI block for first encoder and second for sencod.
Exception was KLDSCP_LVTMA. Analyzing code picking DIG encoder shows the same
behaviour. It shows HDMI block are related to DIGs, which relation we now use.
Signed-off-by: Rafał Miłecki <zajec5@gmail.com>
---
drivers/gpu/drm/radeon/r600_audio.c | 12 +++-
drivers/gpu/drm/radeon/r600_hdmi.c | 114 +++++++++++++-----------------
drivers/gpu/drm/radeon/radeon.h | 3 +-
drivers/gpu/drm/radeon/radeon_encoders.c | 10 ++--
4 files changed, 67 insertions(+), 72 deletions(-)
diff --git a/drivers/gpu/drm/radeon/r600_audio.c b/drivers/gpu/drm/radeon/r600_audio.c
index db92801..2897bd7 100644
--- a/drivers/gpu/drm/radeon/r600_audio.c
+++ b/drivers/gpu/drm/radeon/r600_audio.c
@@ -224,8 +224,14 @@ void r600_audio_set_clock(struct drm_encoder *encoder, int clock)
struct drm_device *dev = encoder->dev;
struct radeon_device *rdev = dev->dev_private;
struct radeon_encoder *radeon_encoder = to_radeon_encoder(encoder);
+ struct radeon_encoder_atom_dig *dig = radeon_encoder->enc_priv;
int base_rate = 48000;
+ if (!dig) {
+ dev_err(rdev->dev, "Setting audio clock on non-dig encoder\n");
+ return;
+ }
+
switch (radeon_encoder->encoder_id) {
case ENCODER_OBJECT_ID_INTERNAL_KLDSCP_TMDS1:
case ENCODER_OBJECT_ID_INTERNAL_LVTM1:
@@ -245,7 +251,7 @@ void r600_audio_set_clock(struct drm_encoder *encoder, int clock)
return;
}
- switch (r600_audio_tmds_index(encoder)) {
+ switch (dig->dig_encoder) {
case 0:
WREG32(R600_AUDIO_PLL1_MUL, base_rate*50);
WREG32(R600_AUDIO_PLL1_DIV, clock*100);
@@ -257,6 +263,10 @@ void r600_audio_set_clock(struct drm_encoder *encoder, int clock)
WREG32(R600_AUDIO_PLL2_DIV, clock*100);
WREG32(R600_AUDIO_CLK_SRCSEL, 1);
break;
+ default:
+ dev_err(rdev->dev, "Unsupported DIG on encoder 0x%02X\n",
+ radeon_encoder->encoder_id);
+ return;
}
}
diff --git a/drivers/gpu/drm/radeon/r600_hdmi.c b/drivers/gpu/drm/radeon/r600_hdmi.c
index 4d09973..5275a81 100644
--- a/drivers/gpu/drm/radeon/r600_hdmi.c
+++ b/drivers/gpu/drm/radeon/r600_hdmi.c
@@ -417,90 +417,74 @@ void r600_hdmi_update_audio_settings(struct drm_encoder *encoder,
WREG32_P(offset+R600_HDMI_CNTL, 0x04000000, ~0x04000000);
}
-/*
- * enable/disable the HDMI engine
- */
-void r600_hdmi_enable(struct drm_encoder *encoder, int enable)
+static void r600_hdmi_assign_block(struct drm_encoder *encoder)
{
struct drm_device *dev = encoder->dev;
struct radeon_device *rdev = dev->dev_private;
struct radeon_encoder *radeon_encoder = to_radeon_encoder(encoder);
- uint32_t offset = to_radeon_encoder(encoder)->hdmi_offset;
+ struct radeon_encoder_atom_dig *dig = radeon_encoder->enc_priv;
- if (!offset)
+ if (!dig) {
+ dev_err(rdev->dev, "Enabling HDMI on non-dig encoder\n");
return;
+ }
- DRM_DEBUG("%s HDMI interface @ 0x%04X\n", enable ? "Enabling" : "Disabling", offset);
-
- /* some version of atombios ignore the enable HDMI flag
- * so enabling/disabling HDMI was moved here for TMDS1+2 */
- switch (radeon_encoder->encoder_id) {
- case ENCODER_OBJECT_ID_INTERNAL_KLDSCP_TMDS1:
- WREG32_P(AVIVO_TMDSA_CNTL, enable ? 0x4 : 0x0, ~0x4);
- WREG32(offset+R600_HDMI_ENABLE, enable ? 0x101 : 0x0);
- break;
-
- case ENCODER_OBJECT_ID_INTERNAL_LVTM1:
- WREG32_P(AVIVO_LVTMA_CNTL, enable ? 0x4 : 0x0, ~0x4);
- WREG32(offset+R600_HDMI_ENABLE, enable ? 0x105 : 0x0);
- break;
-
- case ENCODER_OBJECT_ID_INTERNAL_UNIPHY:
- case ENCODER_OBJECT_ID_INTERNAL_UNIPHY1:
- case ENCODER_OBJECT_ID_INTERNAL_UNIPHY2:
- case ENCODER_OBJECT_ID_INTERNAL_KLDSCP_LVTMA:
- /* This part is doubtfull in my opinion */
- WREG32(offset+R600_HDMI_ENABLE, enable ? 0x110 : 0x0);
- break;
-
- default:
- DRM_ERROR("unknown HDMI output type\n");
- break;
+ if (ASIC_IS_DCE4(rdev)) {
+ /* TODO */
+ } else if (ASIC_IS_DCE3(rdev)) {
+ radeon_encoder->hdmi_offset = dig->dig_encoder ?
+ R600_HDMI_BLOCK3 : R600_HDMI_BLOCK1;
+ if (ASIC_IS_DCE32(rdev))
+ radeon_encoder->hdmi_config_offset = dig->dig_encoder ?
+ R600_HDMI_CONFIG2 : R600_HDMI_CONFIG1;
}
}
/*
- * determin at which register offset the HDMI encoder is
+ * enable the HDMI engine
*/
-void r600_hdmi_init(struct drm_encoder *encoder)
+void r600_hdmi_enable(struct drm_encoder *encoder)
{
+ struct drm_device *dev = encoder->dev;
+ struct radeon_device *rdev = dev->dev_private;
struct radeon_encoder *radeon_encoder = to_radeon_encoder(encoder);
- switch (radeon_encoder->encoder_id) {
- case ENCODER_OBJECT_ID_INTERNAL_KLDSCP_TMDS1:
- case ENCODER_OBJECT_ID_INTERNAL_UNIPHY:
- case ENCODER_OBJECT_ID_INTERNAL_UNIPHY1:
- radeon_encoder->hdmi_offset = R600_HDMI_BLOCK1;
- break;
-
- case ENCODER_OBJECT_ID_INTERNAL_LVTM1:
- switch (r600_audio_tmds_index(encoder)) {
- case 0:
- radeon_encoder->hdmi_offset = R600_HDMI_BLOCK1;
- break;
- case 1:
- radeon_encoder->hdmi_offset = R600_HDMI_BLOCK2;
- break;
- default:
- radeon_encoder->hdmi_offset = 0;
- break;
+ if (!radeon_encoder->hdmi_offset) {
+ r600_hdmi_assign_block(encoder);
+ if (!radeon_encoder->hdmi_offset) {
+ dev_warn(rdev->dev, "Could not find HDMI block for "
+ "0x%x encoder\n", radeon_encoder->encoder_id);
+ return;
}
- case ENCODER_OBJECT_ID_INTERNAL_UNIPHY2:
- radeon_encoder->hdmi_offset = R600_HDMI_BLOCK2;
- break;
+ }
- case ENCODER_OBJECT_ID_INTERNAL_KLDSCP_LVTMA:
- radeon_encoder->hdmi_offset = R600_HDMI_BLOCK3;
- break;
+ if (ASIC_IS_DCE32(rdev) && !ASIC_IS_DCE4(rdev))
+ WREG32_P(radeon_encoder->hdmi_config_offset + 0x4, 0x1, ~0x1);
+
+ DRM_DEBUG("Enabling HDMI interface @ 0x%04X for encoder 0x%x\n",
+ radeon_encoder->hdmi_offset, radeon_encoder->encoder_id);
+}
- default:
- radeon_encoder->hdmi_offset = 0;
- break;
+/*
+ * disable the HDMI engine
+ */
+void r600_hdmi_disable(struct drm_encoder *encoder)
+{
+ struct drm_device *dev = encoder->dev;
+ struct radeon_device *rdev = dev->dev_private;
+ struct radeon_encoder *radeon_encoder = to_radeon_encoder(encoder);
+
+ if (!radeon_encoder->hdmi_offset) {
+ dev_err(rdev->dev, "Disabling not enabled HDMI\n");
+ return;
}
- DRM_DEBUG("using HDMI engine at offset 0x%04X for encoder 0x%x\n",
- radeon_encoder->hdmi_offset, radeon_encoder->encoder_id);
+ DRM_DEBUG("Disabling HDMI interface @ 0x%04X for encoder 0x%x\n",
+ radeon_encoder->hdmi_offset, radeon_encoder->encoder_id);
+
+ if (ASIC_IS_DCE32(rdev) && !ASIC_IS_DCE4(rdev))
+ WREG32_P(radeon_encoder->hdmi_config_offset + 0x4, 0, ~0x1);
- /* TODO: make this configureable */
- radeon_encoder->hdmi_audio_workaround = 0;
+ radeon_encoder->hdmi_offset = 0;
+ radeon_encoder->hdmi_config_offset = 0;
}
diff --git a/drivers/gpu/drm/radeon/radeon.h b/drivers/gpu/drm/radeon/radeon.h
index 0d7caee..b54d4f3 100644
--- a/drivers/gpu/drm/radeon/radeon.h
+++ b/drivers/gpu/drm/radeon/radeon.h
@@ -1323,7 +1323,8 @@ extern int r600_audio_tmds_index(struct drm_encoder *encoder);
extern void r600_audio_set_clock(struct drm_encoder *encoder, int clock);
extern void r600_audio_fini(struct radeon_device *rdev);
extern void r600_hdmi_init(struct drm_encoder *encoder);
-extern void r600_hdmi_enable(struct drm_encoder *encoder, int enable);
+extern void r600_hdmi_enable(struct drm_encoder *encoder);
+extern void r600_hdmi_disable(struct drm_encoder *encoder);
extern void r600_hdmi_setmode(struct drm_encoder *encoder, struct drm_display_mode *mode);
extern int r600_hdmi_buffer_status_changed(struct drm_encoder *encoder);
extern void r600_hdmi_update_audio_settings(struct drm_encoder *encoder,
diff --git a/drivers/gpu/drm/radeon/radeon_encoders.c b/drivers/gpu/drm/radeon/radeon_encoders.c
index bc926ea..7f43476 100644
--- a/drivers/gpu/drm/radeon/radeon_encoders.c
+++ b/drivers/gpu/drm/radeon/radeon_encoders.c
@@ -593,7 +593,6 @@ atombios_digital_setup(struct drm_encoder *encoder, int action)
}
atom_execute_table(rdev->mode_info.atom_context, index, (uint32_t *)&args);
- r600_hdmi_enable(encoder, hdmi_detected);
}
int
@@ -1396,9 +1395,10 @@ radeon_atom_encoder_mode_set(struct drm_encoder *encoder,
}
atombios_apply_encoder_quirks(encoder, adjusted_mode);
- /* XXX */
- if (!ASIC_IS_DCE4(rdev))
+ if (atombios_get_encoder_mode(encoder) == ATOM_ENCODER_MODE_HDMI) {
+ r600_hdmi_enable(encoder);
r600_hdmi_setmode(encoder, adjusted_mode);
+ }
}
static bool
@@ -1509,6 +1509,8 @@ static void radeon_atom_encoder_disable(struct drm_encoder *encoder)
radeon_atom_encoder_dpms(encoder, DRM_MODE_DPMS_OFF);
if (radeon_encoder_is_digital(encoder)) {
+ if (atombios_get_encoder_mode(encoder) == ATOM_ENCODER_MODE_HDMI)
+ r600_hdmi_disable(encoder);
dig = radeon_encoder->enc_priv;
dig->dig_encoder = -1;
}
@@ -1659,6 +1661,4 @@ radeon_add_atom_encoder(struct drm_device *dev, uint32_t encoder_id, uint32_t su
drm_encoder_helper_add(encoder, &radeon_atom_dig_helper_funcs);
break;
}
-
- r600_hdmi_init(encoder);
}
--
1.6.4.2
------------------------------------------------------------------------------
Download Intel® Parallel Studio Eval
Try the new software tools for yourself. Speed compiling, find bugs
proactively, and fine-tune applications for parallel performance.
See why Intel Parallel Studio got high marks during beta.
http://p.sf.net/sfu/intel-sw-dev
--
_______________________________________________
Dri-devel mailing list
Dri-devel@lists.sourceforge.net
https://lists.sourceforge.net/lists/listinfo/dri-devel
next parent reply other threads:[~2010-03-06 13:03 UTC|newest]
Thread overview: 11+ messages / expand[flat|nested] mbox.gz Atom feed top
[not found] <1267880618-9909-1-git-send-email-zajec5@gmail.com>
2010-03-06 13:03 ` Rafał Miłecki [this message]
2010-03-06 16:26 ` [PATCH 2/6] drm/radeon/kms: clean assigning HDMI blocks to encoders Christian König
2010-03-06 16:48 ` Rafał Miłecki
2010-03-07 20:59 ` Christian König
2010-03-06 13:03 ` [PATCH 3/6] drm/radeon/kms: add HDMI code for pre-DCE3 R6xx GPUs Rafał Miłecki
2010-03-06 16:46 ` [PATCH 0/6] HDMI clean & DCE32 support Mike Lothian
2010-03-06 16:49 ` Rafał Miłecki
2010-03-06 17:14 ` Mike Lothian
2010-03-19 0:14 ` Mike Lothian
2010-03-19 0:36 ` Dave Airlie
2010-03-20 16:25 ` Christian König
Reply instructions:
You may reply publicly to this message via plain-text email
using any one of the following methods:
* Save the following mbox file, import it into your mail client,
and reply-to-all from there: mbox
Avoid top-posting and favor interleaved quoting:
https://en.wikipedia.org/wiki/Posting_style#Interleaved_style
* Reply using the --to, --cc, and --in-reply-to
switches of git-send-email(1):
git send-email \
--in-reply-to=1267880618-9909-3-git-send-email-zajec5@gmail.com \
--to=zajec5@gmail.com \
--cc=airlied@gmail.com \
--cc=deathsimple@vodafone.de \
--cc=dri-devel@lists.sourceforge.net \
/path/to/YOUR_REPLY
https://kernel.org/pub/software/scm/git/docs/git-send-email.html
* If your mail client supports setting the In-Reply-To header
via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line
before the message body.
This is an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.