drm/radeon/kms/hdmi: helper getting ready ACR entry
authorRafał Miłecki <zajec5@gmail.com>
Mon, 30 Apr 2012 13:44:54 +0000 (15:44 +0200)
committerDave Airlie <airlied@redhat.com>
Sun, 13 May 2012 13:19:29 +0000 (14:19 +0100)
Signed-off-by: Rafał Miłecki <zajec5@gmail.com>
Reviewed-by: Alex Deucher <alexdeucher@gmail.com>
Signed-off-by: Dave Airlie <airlied@redhat.com>
drivers/gpu/drm/radeon/r600_hdmi.c
drivers/gpu/drm/radeon/radeon.h

index 7d24753108fa9fe745fcd825f302dfd3efa88b3b..0319619c886bb57cf1fab04eadb85b0829df298d 100644 (file)
@@ -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);
 }
 
 /*
index 60233d7a6f7dd21c8b95628c0d3625945a880b63..143ab0c03907301e103476e83d888c3f223bc13e 100644 (file)
@@ -1827,6 +1827,20 @@ int r600_fmt_get_nblocksy(u32 format, u32 h);
 /*
  * r600 functions used by radeon_encoder.c
  */
+struct radeon_hdmi_acr {
+       u32 clock;
+
+       int n_32khz;
+       int cts_32khz;
+
+       int n_44_1khz;
+       int cts_44_1khz;
+
+       int n_48khz;
+       int cts_48khz;
+
+};
+
 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);