diff options
author | Rafał Miłecki <zajec5@gmail.com> | 2012-04-30 15:44:54 +0200 |
---|---|---|
committer | Dave Airlie <airlied@redhat.com> | 2012-05-13 15:19:29 +0200 |
commit | 1b688d0814c1962e91e5242469bc95a068e5be87 (patch) | |
tree | 61012ff09ef0fabe0b0f57e66cb414f1c0e938f5 /drivers/gpu/drm/radeon/r600_hdmi.c | |
parent | drm/radeon/kms/hdmi: clean&improve handling HDMI mode (diff) | |
download | linux-1b688d0814c1962e91e5242469bc95a068e5be87.tar.xz linux-1b688d0814c1962e91e5242469bc95a068e5be87.zip |
drm/radeon/kms/hdmi: helper getting ready ACR entry
Signed-off-by: Rafał Miłecki <zajec5@gmail.com>
Reviewed-by: Alex Deucher <alexdeucher@gmail.com>
Signed-off-by: Dave Airlie <airlied@redhat.com>
Diffstat (limited to 'drivers/gpu/drm/radeon/r600_hdmi.c')
-rw-r--r-- | drivers/gpu/drm/radeon/r600_hdmi.c | 65 |
1 files changed, 29 insertions, 36 deletions
diff --git a/drivers/gpu/drm/radeon/r600_hdmi.c b/drivers/gpu/drm/radeon/r600_hdmi.c index 7d24753108fa..0319619c886b 100644 --- a/drivers/gpu/drm/radeon/r600_hdmi.c +++ b/drivers/gpu/drm/radeon/r600_hdmi.c @@ -53,19 +53,7 @@ enum r600_hdmi_iec_status_bits { AUDIO_STATUS_LEVEL = 0x80 }; -struct { - uint32_t Clock; - - int N_32kHz; - int CTS_32kHz; - - int N_44_1kHz; - int CTS_44_1kHz; - - int N_48kHz; - int CTS_48kHz; - -} r600_hdmi_ACR[] = { +struct radeon_hdmi_acr r600_hdmi_predefined_acr[] = { /* 32kHz 44.1kHz 48kHz */ /* Clock N CTS N CTS N CTS */ { 25174, 4576, 28125, 7007, 31250, 6864, 28125 }, /* 25,20/1.001 MHz */ @@ -84,7 +72,7 @@ struct { /* * calculate CTS value if it's not found in the table */ -static void r600_hdmi_calc_CTS(uint32_t clock, int *CTS, int N, int freq) +static void r600_hdmi_calc_cts(uint32_t clock, int *CTS, int N, int freq) { if (*CTS == 0) *CTS = clock * N / (128 * freq) * 1000; @@ -92,6 +80,24 @@ static void r600_hdmi_calc_CTS(uint32_t clock, int *CTS, int N, int freq) N, *CTS, freq); } +struct radeon_hdmi_acr r600_hdmi_acr(uint32_t clock) +{ + struct radeon_hdmi_acr res; + u8 i; + + for (i = 0; r600_hdmi_predefined_acr[i].clock != clock && + r600_hdmi_predefined_acr[i].clock != 0; i++) + ; + res = r600_hdmi_predefined_acr[i]; + + /* In case some CTS are missing */ + r600_hdmi_calc_cts(clock, &res.cts_32khz, res.n_32khz, 32000); + r600_hdmi_calc_cts(clock, &res.cts_44_1khz, res.n_44_1khz, 44100); + r600_hdmi_calc_cts(clock, &res.cts_48khz, res.n_48khz, 48000); + + return res; +} + /* * update the N and CTS parameters for a given pixel clock rate */ @@ -99,30 +105,17 @@ static void r600_hdmi_update_ACR(struct drm_encoder *encoder, uint32_t clock) { struct drm_device *dev = encoder->dev; struct radeon_device *rdev = dev->dev_private; + struct radeon_hdmi_acr acr = r600_hdmi_acr(clock); uint32_t offset = to_radeon_encoder(encoder)->hdmi_offset; - int CTS; - int N; - int i; - for (i = 0; r600_hdmi_ACR[i].Clock != clock && r600_hdmi_ACR[i].Clock != 0; i++); - - CTS = r600_hdmi_ACR[i].CTS_32kHz; - N = r600_hdmi_ACR[i].N_32kHz; - r600_hdmi_calc_CTS(clock, &CTS, N, 32000); - WREG32(HDMI0_ACR_32_0 + offset, HDMI0_ACR_CTS_32(CTS)); - WREG32(HDMI0_ACR_32_1 + offset, N); - - CTS = r600_hdmi_ACR[i].CTS_44_1kHz; - N = r600_hdmi_ACR[i].N_44_1kHz; - r600_hdmi_calc_CTS(clock, &CTS, N, 44100); - WREG32(HDMI0_ACR_44_0 + offset, HDMI0_ACR_CTS_44(CTS)); - WREG32(HDMI0_ACR_44_1 + offset, N); - - CTS = r600_hdmi_ACR[i].CTS_48kHz; - N = r600_hdmi_ACR[i].N_48kHz; - r600_hdmi_calc_CTS(clock, &CTS, N, 48000); - WREG32(HDMI0_ACR_48_0 + offset, HDMI0_ACR_CTS_48(CTS)); - WREG32(HDMI0_ACR_48_1 + offset, N); + WREG32(HDMI0_ACR_32_0 + offset, HDMI0_ACR_CTS_32(acr.cts_32khz)); + WREG32(HDMI0_ACR_32_1 + offset, acr.n_32khz); + + WREG32(HDMI0_ACR_44_0 + offset, HDMI0_ACR_CTS_44(acr.cts_44_1khz)); + WREG32(HDMI0_ACR_44_1 + offset, acr.n_44_1khz); + + WREG32(HDMI0_ACR_48_0 + offset, HDMI0_ACR_CTS_48(acr.cts_48khz)); + WREG32(HDMI0_ACR_48_1 + offset, acr.n_48khz); } /* |