summaryrefslogtreecommitdiff
path: root/drivers/gpu/drm/sti
diff options
context:
space:
mode:
authorAndré Fabian Silva Delgado <emulatorman@parabola.nu>2015-09-08 01:01:14 -0300
committerAndré Fabian Silva Delgado <emulatorman@parabola.nu>2015-09-08 01:01:14 -0300
commite5fd91f1ef340da553f7a79da9540c3db711c937 (patch)
treeb11842027dc6641da63f4bcc524f8678263304a3 /drivers/gpu/drm/sti
parent2a9b0348e685a63d97486f6749622b61e9e3292f (diff)
Linux-libre 4.2-gnu
Diffstat (limited to 'drivers/gpu/drm/sti')
-rw-r--r--drivers/gpu/drm/sti/sti_dvo.c4
-rw-r--r--drivers/gpu/drm/sti/sti_hdmi.c4
-rw-r--r--drivers/gpu/drm/sti/sti_vtg.c56
3 files changed, 43 insertions, 21 deletions
diff --git a/drivers/gpu/drm/sti/sti_dvo.c b/drivers/gpu/drm/sti/sti_dvo.c
index a9b678af8..d141d645b 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 ae5424bd6..f28a4d544 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 9564f2568..aa8097137 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;