diff --git a/drivers/gpu/drm/sti/sti_dvo.c b/drivers/gpu/drm/sti/sti_dvo.c index a9b678af85a6f315716fa82871674519e017b9f3..d141d645bd13acd47c99b9c6b1de839e442fc280 100644 --- a/drivers/gpu/drm/sti/sti_dvo.c +++ b/drivers/gpu/drm/sti/sti_dvo.c @@ -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)) { diff --git a/drivers/gpu/drm/sti/sti_hdmi.c b/drivers/gpu/drm/sti/sti_hdmi.c index ae5424bd6b4cbd00d1ffc5b4fd35f11cb56a11cd..f28a4d54487c7636fee9e1a4f5ca80ecf73adcc6 100644 --- a/drivers/gpu/drm/sti/sti_hdmi.c +++ b/drivers/gpu/drm/sti/sti_hdmi.c @@ -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); diff --git a/drivers/gpu/drm/sti/sti_vtg.c b/drivers/gpu/drm/sti/sti_vtg.c index 9564f2568e2c01abaf975985b571431bdc9b3349..aa809713770166537db8f124dff3a2934e7492c9 100644 --- a/drivers/gpu/drm/sti/sti_vtg.c +++ b/drivers/gpu/drm/sti/sti_vtg.c @@ -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); - 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); + /* Set Half Line Per Field (only progressive supported for now) */ + writel(mode->vtotal * 2, vtg->regs + VTG_HLFLN); - 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;