提交 1b688d08 编写于 作者: R Rafał Miłecki 提交者: Dave Airlie

drm/radeon/kms/hdmi: helper getting ready ACR entry

Signed-off-by: NRafał Miłecki <zajec5@gmail.com>
Reviewed-by: NAlex Deucher <alexdeucher@gmail.com>
Signed-off-by: NDave Airlie <airlied@redhat.com>
上级 64fb4fb0
...@@ -53,19 +53,7 @@ enum r600_hdmi_iec_status_bits { ...@@ -53,19 +53,7 @@ enum r600_hdmi_iec_status_bits {
AUDIO_STATUS_LEVEL = 0x80 AUDIO_STATUS_LEVEL = 0x80
}; };
struct { struct radeon_hdmi_acr r600_hdmi_predefined_acr[] = {
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[] = {
/* 32kHz 44.1kHz 48kHz */ /* 32kHz 44.1kHz 48kHz */
/* Clock N CTS N CTS N CTS */ /* Clock N CTS N CTS N CTS */
{ 25174, 4576, 28125, 7007, 31250, 6864, 28125 }, /* 25,20/1.001 MHz */ { 25174, 4576, 28125, 7007, 31250, 6864, 28125 }, /* 25,20/1.001 MHz */
...@@ -84,7 +72,7 @@ struct { ...@@ -84,7 +72,7 @@ struct {
/* /*
* calculate CTS value if it's not found in the table * 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) if (*CTS == 0)
*CTS = clock * N / (128 * freq) * 1000; *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) ...@@ -92,6 +80,24 @@ static void r600_hdmi_calc_CTS(uint32_t clock, int *CTS, int N, int freq)
N, *CTS, 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 * 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) ...@@ -99,30 +105,17 @@ static void r600_hdmi_update_ACR(struct drm_encoder *encoder, uint32_t clock)
{ {
struct drm_device *dev = encoder->dev; struct drm_device *dev = encoder->dev;
struct radeon_device *rdev = dev->dev_private; 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; 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++); WREG32(HDMI0_ACR_32_0 + offset, HDMI0_ACR_CTS_32(acr.cts_32khz));
WREG32(HDMI0_ACR_32_1 + offset, acr.n_32khz);
CTS = r600_hdmi_ACR[i].CTS_32kHz;
N = r600_hdmi_ACR[i].N_32kHz; WREG32(HDMI0_ACR_44_0 + offset, HDMI0_ACR_CTS_44(acr.cts_44_1khz));
r600_hdmi_calc_CTS(clock, &CTS, N, 32000); WREG32(HDMI0_ACR_44_1 + offset, acr.n_44_1khz);
WREG32(HDMI0_ACR_32_0 + offset, HDMI0_ACR_CTS_32(CTS));
WREG32(HDMI0_ACR_32_1 + offset, N); WREG32(HDMI0_ACR_48_0 + offset, HDMI0_ACR_CTS_48(acr.cts_48khz));
WREG32(HDMI0_ACR_48_1 + offset, acr.n_48khz);
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);
} }
/* /*
......
...@@ -1827,6 +1827,20 @@ int r600_fmt_get_nblocksy(u32 format, u32 h); ...@@ -1827,6 +1827,20 @@ int r600_fmt_get_nblocksy(u32 format, u32 h);
/* /*
* r600 functions used by radeon_encoder.c * 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_enable(struct drm_encoder *encoder);
extern void r600_hdmi_disable(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 void r600_hdmi_setmode(struct drm_encoder *encoder, struct drm_display_mode *mode);
......
Markdown is supported
0% .
You are about to add 0 people to the discussion. Proceed with caution.
先完成此消息的编辑!
想要评论请 注册