Merge branch '2015-06-08-st-drm-next' of http://git.linaro.org/people/benjamin.gaignard/kernel into drm-next
Mainly it is fixing timing on HDMI to be compliant with CEA-861E spec. * '2015-06-08-st-drm-next' of http://git.linaro.org/people/benjamin.gaignard/kernel: drm/sti: vtg fix CEA-861E video format timing error drm/sti: hdmi fix CEA-861E video format timing error drm/sti: VTG interrupt names are badly displayed drm/sti: missing first pixel column on HDMI display drm/sti: correctly test devm_ioremap() return
This commit is contained in:
commit
7207d559e4
|
@ -499,8 +499,8 @@ static int sti_dvo_probe(struct platform_device *pdev)
|
|||
}
|
||||
dvo->regs = devm_ioremap_nocache(dev, res->start,
|
||||
resource_size(res));
|
||||
if (IS_ERR(dvo->regs))
|
||||
return PTR_ERR(dvo->regs);
|
||||
if (!dvo->regs)
|
||||
return -ENOMEM;
|
||||
|
||||
dvo->clk_pix = devm_clk_get(dev, "dvo_pix");
|
||||
if (IS_ERR(dvo->clk_pix)) {
|
||||
|
|
|
@ -192,8 +192,8 @@ static void hdmi_active_area(struct sti_hdmi *hdmi)
|
|||
u32 xmin, xmax;
|
||||
u32 ymin, ymax;
|
||||
|
||||
xmin = sti_vtg_get_pixel_number(hdmi->mode, 0);
|
||||
xmax = sti_vtg_get_pixel_number(hdmi->mode, hdmi->mode.hdisplay - 1);
|
||||
xmin = sti_vtg_get_pixel_number(hdmi->mode, 1);
|
||||
xmax = sti_vtg_get_pixel_number(hdmi->mode, hdmi->mode.hdisplay);
|
||||
ymin = sti_vtg_get_line_number(hdmi->mode, 0);
|
||||
ymax = sti_vtg_get_line_number(hdmi->mode, hdmi->mode.vdisplay - 1);
|
||||
|
||||
|
|
|
@ -62,7 +62,7 @@
|
|||
#define VTG_IRQ_MASK (VTG_IRQ_TOP | VTG_IRQ_BOTTOM)
|
||||
|
||||
/* Delay introduced by the HDMI in nb of pixel */
|
||||
#define HDMI_DELAY (6)
|
||||
#define HDMI_DELAY (5)
|
||||
|
||||
/* delay introduced by the Arbitrary Waveform Generator in nb of pixels */
|
||||
#define AWG_DELAY_HD (-9)
|
||||
|
@ -121,6 +121,32 @@ static void vtg_reset(struct sti_vtg *vtg)
|
|||
writel(1, vtg->regs + VTG_DRST_AUTOC);
|
||||
}
|
||||
|
||||
static void vtg_set_output_window(void __iomem *regs,
|
||||
const struct drm_display_mode *mode)
|
||||
{
|
||||
u32 video_top_field_start;
|
||||
u32 video_top_field_stop;
|
||||
u32 video_bottom_field_start;
|
||||
u32 video_bottom_field_stop;
|
||||
u32 xstart = sti_vtg_get_pixel_number(*mode, 0);
|
||||
u32 ystart = sti_vtg_get_line_number(*mode, 0);
|
||||
u32 xstop = sti_vtg_get_pixel_number(*mode, mode->hdisplay - 1);
|
||||
u32 ystop = sti_vtg_get_line_number(*mode, mode->vdisplay - 1);
|
||||
|
||||
/* Set output window to fit the display mode selected */
|
||||
video_top_field_start = (ystart << 16) | xstart;
|
||||
video_top_field_stop = (ystop << 16) | xstop;
|
||||
|
||||
/* Only progressive supported for now */
|
||||
video_bottom_field_start = video_top_field_start;
|
||||
video_bottom_field_stop = video_top_field_stop;
|
||||
|
||||
writel(video_top_field_start, regs + VTG_VID_TFO);
|
||||
writel(video_top_field_stop, regs + VTG_VID_TFS);
|
||||
writel(video_bottom_field_start, regs + VTG_VID_BFO);
|
||||
writel(video_bottom_field_stop, regs + VTG_VID_BFS);
|
||||
}
|
||||
|
||||
static void vtg_set_mode(struct sti_vtg *vtg,
|
||||
int type, const struct drm_display_mode *mode)
|
||||
{
|
||||
|
@ -129,18 +155,14 @@ static void vtg_set_mode(struct sti_vtg *vtg,
|
|||
if (vtg->slave)
|
||||
vtg_set_mode(vtg->slave, VTG_TYPE_SLAVE_BY_EXT0, mode);
|
||||
|
||||
/* Set the number of clock cycles per line */
|
||||
writel(mode->htotal, vtg->regs + VTG_CLKLN);
|
||||
|
||||
/* Set Half Line Per Field (only progressive supported for now) */
|
||||
writel(mode->vtotal * 2, vtg->regs + VTG_HLFLN);
|
||||
|
||||
tmp = (mode->vtotal - mode->vsync_start + 1) << 16;
|
||||
tmp |= mode->htotal - mode->hsync_start;
|
||||
writel(tmp, vtg->regs + VTG_VID_TFO);
|
||||
writel(tmp, vtg->regs + VTG_VID_BFO);
|
||||
|
||||
tmp = (mode->vdisplay + mode->vtotal - mode->vsync_start + 1) << 16;
|
||||
tmp |= mode->hdisplay + mode->htotal - mode->hsync_start;
|
||||
writel(tmp, vtg->regs + VTG_VID_TFS);
|
||||
writel(tmp, vtg->regs + VTG_VID_BFS);
|
||||
/* Program output window */
|
||||
vtg_set_output_window(vtg->regs, mode);
|
||||
|
||||
/* prepare VTG set 1 for HDMI */
|
||||
tmp = (mode->hsync_end - mode->hsync_start + HDMI_DELAY) << 16;
|
||||
|
@ -151,8 +173,11 @@ static void vtg_set_mode(struct sti_vtg *vtg,
|
|||
tmp |= 1;
|
||||
writel(tmp, vtg->regs + VTG_TOP_V_VD_1);
|
||||
writel(tmp, vtg->regs + VTG_BOT_V_VD_1);
|
||||
writel(0, vtg->regs + VTG_TOP_V_HD_1);
|
||||
writel(0, vtg->regs + VTG_BOT_V_HD_1);
|
||||
|
||||
tmp = HDMI_DELAY << 16;
|
||||
tmp |= HDMI_DELAY;
|
||||
writel(tmp, vtg->regs + VTG_TOP_V_HD_1);
|
||||
writel(tmp, vtg->regs + VTG_BOT_V_HD_1);
|
||||
|
||||
/* prepare VTG set 2 for for HD DCS */
|
||||
tmp = (mode->hsync_end - mode->hsync_start) << 16;
|
||||
|
@ -311,7 +336,6 @@ static int vtg_probe(struct platform_device *pdev)
|
|||
struct device_node *np;
|
||||
struct sti_vtg *vtg;
|
||||
struct resource *res;
|
||||
char irq_name[32];
|
||||
int ret;
|
||||
|
||||
vtg = devm_kzalloc(dev, sizeof(*vtg), GFP_KERNEL);
|
||||
|
@ -342,13 +366,11 @@ static int vtg_probe(struct platform_device *pdev)
|
|||
return vtg->irq;
|
||||
}
|
||||
|
||||
snprintf(irq_name, sizeof(irq_name), "vsync-%s",
|
||||
dev_name(vtg->dev));
|
||||
|
||||
RAW_INIT_NOTIFIER_HEAD(&vtg->notifier_list);
|
||||
|
||||
ret = devm_request_threaded_irq(dev, vtg->irq, vtg_irq,
|
||||
vtg_irq_thread, IRQF_ONESHOT, irq_name, vtg);
|
||||
vtg_irq_thread, IRQF_ONESHOT,
|
||||
dev_name(dev), vtg);
|
||||
if (IS_ERR_VALUE(ret)) {
|
||||
DRM_ERROR("Failed to register VTG interrupt\n");
|
||||
return ret;
|
||||
|
|
Loading…
Reference in a new issue