Commit 9ace42b1 authored by Dave Airlie's avatar Dave Airlie

Merge branch 'drm-dwhdmi-devel' of git://ftp.arm.linux.org.uk/~rmk/linux-arm into drm-next

This series:
* adds support for interlaced video modes to the ipu-v3 driver
  and dw_hdmi bridge.
* reworks the dw_hdmi connector enable/disable support, to ensure that
  when DRM disables the output, it stays disabled irrespective of the
  hotplug state.
* adds support for connector forcing, so we can force the hotplug state
  for this connector.
* adds the ALSA AHB audio driver to the bridge: Iwai has acked the
  audio driver.
* a few fixes to the ACR calculations to allow more modes to work with
  audio on iMX6.

Fabio has independently tested this series, so all patches here carry
his tested-by tag.

* 'drm-dwhdmi-devel' of git://ftp.arm.linux.org.uk/~rmk/linux-arm:
  drm: bridge/dw_hdmi: replace CTS calculation for the ACR
  drm: bridge/dw_hdmi: remove ratio support from ACR code
  drm: bridge/dw_hdmi: adjust pixel clock values in N calculation
  drm: bridge/dw_hdmi: avoid being recursive in N calculation
  drm: bridge/dw_hdmi-ahb-audio: allow larger buffer sizes
  drm: bridge/dw_hdmi-ahb-audio: basic support for multi-channel PCM audio
  drm: bridge/dw_hdmi-ahb-audio: parse ELD from HDMI driver
  drm: bridge/dw_hdmi-ahb-audio: add audio driver
  drm: bridge/dw_hdmi: improve HDMI enable/disable handling
  drm: bridge/dw_hdmi: add connector mode forcing
  drm: bridge/dw_hdmi: add support for interlaced video modes
  gpu: imx: fix support for interlaced modes
  gpu: imx: simplify sync polarity setting
parents 48f87dd1 dfbdaf50
......@@ -11,6 +11,18 @@ config DRM_DW_HDMI
tristate
select DRM_KMS_HELPER
config DRM_DW_HDMI_AHB_AUDIO
tristate "Synopsis Designware AHB Audio interface"
depends on DRM_DW_HDMI && SND
select SND_PCM
select SND_PCM_ELD
select SND_PCM_IEC958
help
Support the AHB Audio interface which is part of the Synopsis
Designware HDMI block. This is used in conjunction with
the i.MX6 HDMI driver.
config DRM_NXP_PTN3460
tristate "NXP PTN3460 DP/LVDS bridge"
depends on OF
......
ccflags-y := -Iinclude/drm
obj-$(CONFIG_DRM_DW_HDMI) += dw_hdmi.o
obj-$(CONFIG_DRM_DW_HDMI_AHB_AUDIO) += dw_hdmi-ahb-audio.o
obj-$(CONFIG_DRM_NXP_PTN3460) += nxp-ptn3460.o
obj-$(CONFIG_DRM_PARADE_PS8622) += parade-ps8622.o
This diff is collapsed.
#ifndef DW_HDMI_AUDIO_H
#define DW_HDMI_AUDIO_H
struct dw_hdmi;
struct dw_hdmi_audio_data {
phys_addr_t phys;
void __iomem *base;
int irq;
struct dw_hdmi *hdmi;
u8 *eld;
};
#endif
This diff is collapsed.
......@@ -545,6 +545,9 @@
#define HDMI_I2CM_FS_SCL_LCNT_0_ADDR 0x7E12
enum {
/* CONFIG1_ID field values */
HDMI_CONFIG1_AHB = 0x01,
/* IH_FC_INT2 field values */
HDMI_IH_FC_INT2_OVERFLOW_MASK = 0x03,
HDMI_IH_FC_INT2_LOW_PRIORITY_OVERFLOW = 0x02,
......
......@@ -183,12 +183,19 @@ int ipu_dc_init_sync(struct ipu_dc *dc, struct ipu_di *di, bool interlaced,
}
if (interlaced) {
dc_link_event(dc, DC_EVT_NL, 0, 3);
dc_link_event(dc, DC_EVT_EOL, 0, 2);
dc_link_event(dc, DC_EVT_NEW_DATA, 0, 1);
int addr;
if (dc->di)
addr = 1;
else
addr = 0;
dc_link_event(dc, DC_EVT_NL, addr, 3);
dc_link_event(dc, DC_EVT_EOL, addr, 2);
dc_link_event(dc, DC_EVT_NEW_DATA, addr, 1);
/* Init template microcode */
dc_write_tmpl(dc, 0, WROD(0), 0, map, SYNC_WAVE, 0, 8, 1);
dc_write_tmpl(dc, addr, WROD(0), 0, map, SYNC_WAVE, 0, 6, 1);
} else {
if (dc->di) {
dc_link_event(dc, DC_EVT_NL, 2, 3);
......
......@@ -71,6 +71,10 @@ enum di_sync_wave {
DI_SYNC_HSYNC = 3,
DI_SYNC_VSYNC = 4,
DI_SYNC_DE = 6,
DI_SYNC_CNT1 = 2, /* counter >= 2 only */
DI_SYNC_CNT4 = 5, /* counter >= 5 only */
DI_SYNC_CNT5 = 6, /* counter >= 6 only */
};
#define SYNC_WAVE 0
......@@ -211,66 +215,59 @@ static void ipu_di_sync_config_interlaced(struct ipu_di *di,
sig->mode.hback_porch + sig->mode.hfront_porch;
u32 v_total = sig->mode.vactive + sig->mode.vsync_len +
sig->mode.vback_porch + sig->mode.vfront_porch;
u32 reg;
struct di_sync_config cfg[] = {
{
.run_count = h_total / 2 - 1,
.run_src = DI_SYNC_CLK,
/* 1: internal VSYNC for each frame */
.run_count = v_total * 2 - 1,
.run_src = 3, /* == counter 7 */
}, {
.run_count = h_total - 11,
/* PIN2: HSYNC waveform */
.run_count = h_total - 1,
.run_src = DI_SYNC_CLK,
.cnt_down = 4,
.cnt_polarity_gen_en = 1,
.cnt_polarity_trigger_src = DI_SYNC_CLK,
.cnt_down = sig->mode.hsync_len * 2,
}, {
.run_count = v_total * 2 - 1,
.run_src = DI_SYNC_INT_HSYNC,
.offset_count = 1,
.offset_src = DI_SYNC_INT_HSYNC,
.cnt_down = 4,
/* PIN3: VSYNC waveform */
.run_count = v_total - 1,
.run_src = 4, /* == counter 7 */
.cnt_polarity_gen_en = 1,
.cnt_polarity_trigger_src = 4, /* == counter 7 */
.cnt_down = sig->mode.vsync_len * 2,
.cnt_clr_src = DI_SYNC_CNT1,
}, {
.run_count = v_total / 2 - 1,
/* 4: Field */
.run_count = v_total / 2,
.run_src = DI_SYNC_HSYNC,
.offset_count = sig->mode.vback_porch,
.offset_src = DI_SYNC_HSYNC,
.offset_count = h_total / 2,
.offset_src = DI_SYNC_CLK,
.repeat_count = 2,
.cnt_clr_src = DI_SYNC_VSYNC,
}, {
.run_src = DI_SYNC_HSYNC,
.repeat_count = sig->mode.vactive / 2,
.cnt_clr_src = 4,
}, {
.run_count = v_total - 1,
.run_src = DI_SYNC_HSYNC,
.cnt_clr_src = DI_SYNC_CNT1,
}, {
.run_count = v_total / 2 - 1,
/* 5: Active lines */
.run_src = DI_SYNC_HSYNC,
.offset_count = 9,
.offset_count = (sig->mode.vsync_len +
sig->mode.vback_porch) / 2,
.offset_src = DI_SYNC_HSYNC,
.repeat_count = 2,
.cnt_clr_src = DI_SYNC_VSYNC,
.repeat_count = sig->mode.vactive / 2,
.cnt_clr_src = DI_SYNC_CNT4,
}, {
/* 6: Active pixel, referenced by DC */
.run_src = DI_SYNC_CLK,
.offset_count = sig->mode.hback_porch,
.offset_count = sig->mode.hsync_len +
sig->mode.hback_porch,
.offset_src = DI_SYNC_CLK,
.repeat_count = sig->mode.hactive,
.cnt_clr_src = 5,
.cnt_clr_src = DI_SYNC_CNT5,
}, {
.run_count = v_total - 1,
.run_src = DI_SYNC_INT_HSYNC,
.offset_count = v_total / 2,
.offset_src = DI_SYNC_INT_HSYNC,
.cnt_clr_src = DI_SYNC_HSYNC,
.cnt_down = 4,
/* 7: Half line HSYNC */
.run_count = h_total / 2 - 1,
.run_src = DI_SYNC_CLK,
}
};
ipu_di_sync_config(di, cfg, 0, ARRAY_SIZE(cfg));
/* set gentime select and tag sel */
reg = ipu_di_read(di, DI_SW_GEN1(9));
reg &= 0x1FFFFFFF;
reg |= (3 - 1) << 29 | 0x00008000;
ipu_di_write(di, reg, DI_SW_GEN1(9));
ipu_di_write(di, v_total / 2 - 1, DI_SCR_CONF);
}
......@@ -543,6 +540,29 @@ int ipu_di_adjust_videomode(struct ipu_di *di, struct videomode *mode)
}
EXPORT_SYMBOL_GPL(ipu_di_adjust_videomode);
static u32 ipu_di_gen_polarity(int pin)
{
switch (pin) {
case 1:
return DI_GEN_POLARITY_1;
case 2:
return DI_GEN_POLARITY_2;
case 3:
return DI_GEN_POLARITY_3;
case 4:
return DI_GEN_POLARITY_4;
case 5:
return DI_GEN_POLARITY_5;
case 6:
return DI_GEN_POLARITY_6;
case 7:
return DI_GEN_POLARITY_7;
case 8:
return DI_GEN_POLARITY_8;
}
return 0;
}
int ipu_di_init_sync_panel(struct ipu_di *di, struct ipu_di_signal_cfg *sig)
{
u32 reg;
......@@ -582,15 +602,8 @@ int ipu_di_init_sync_panel(struct ipu_di *di, struct ipu_di_signal_cfg *sig)
/* set y_sel = 1 */
di_gen |= 0x10000000;
di_gen |= DI_GEN_POLARITY_5;
di_gen |= DI_GEN_POLARITY_8;
vsync_cnt = 7;
if (sig->mode.flags & DISPLAY_FLAGS_HSYNC_HIGH)
di_gen |= DI_GEN_POLARITY_3;
if (sig->mode.flags & DISPLAY_FLAGS_VSYNC_HIGH)
di_gen |= DI_GEN_POLARITY_2;
vsync_cnt = 3;
} else {
ipu_di_sync_config_noninterlaced(di, sig, div);
......@@ -602,25 +615,13 @@ int ipu_di_init_sync_panel(struct ipu_di *di, struct ipu_di_signal_cfg *sig)
*/
if (!(sig->hsync_pin == 2 && sig->vsync_pin == 3))
vsync_cnt = 6;
if (sig->mode.flags & DISPLAY_FLAGS_HSYNC_HIGH) {
if (sig->hsync_pin == 2)
di_gen |= DI_GEN_POLARITY_2;
else if (sig->hsync_pin == 4)
di_gen |= DI_GEN_POLARITY_4;
else if (sig->hsync_pin == 7)
di_gen |= DI_GEN_POLARITY_7;
}
if (sig->mode.flags & DISPLAY_FLAGS_VSYNC_HIGH) {
if (sig->vsync_pin == 3)
di_gen |= DI_GEN_POLARITY_3;
else if (sig->vsync_pin == 6)
di_gen |= DI_GEN_POLARITY_6;
else if (sig->vsync_pin == 8)
di_gen |= DI_GEN_POLARITY_8;
}
}
if (sig->mode.flags & DISPLAY_FLAGS_HSYNC_HIGH)
di_gen |= ipu_di_gen_polarity(sig->hsync_pin);
if (sig->mode.flags & DISPLAY_FLAGS_VSYNC_HIGH)
di_gen |= ipu_di_gen_polarity(sig->vsync_pin);
if (sig->clk_pol)
di_gen |= DI_GEN_POLARITY_DISP_CLK;
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment