aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorDave Airlie <airlied@redhat.com>2015-06-11 20:14:00 -0400
committerDave Airlie <airlied@redhat.com>2015-06-11 20:14:00 -0400
commit7207d559e4851372c00344fa52778d73a0098627 (patch)
tree72cce8655a862a82d3759af3188bbdebc500e6af
parent3f05eb4e3fc56df678f83925ced78bc97166b052 (diff)
parentc58d6d1b6652b0a8db4aef7e93fb21ee869b5387 (diff)
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
-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 a9b678af85a6..d141d645bd13 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)
499 } 499 }
500 dvo->regs = devm_ioremap_nocache(dev, res->start, 500 dvo->regs = devm_ioremap_nocache(dev, res->start,
501 resource_size(res)); 501 resource_size(res));
502 if (IS_ERR(dvo->regs)) 502 if (!dvo->regs)
503 return PTR_ERR(dvo->regs); 503 return -ENOMEM;
504 504
505 dvo->clk_pix = devm_clk_get(dev, "dvo_pix"); 505 dvo->clk_pix = devm_clk_get(dev, "dvo_pix");
506 if (IS_ERR(dvo->clk_pix)) { 506 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 ae5424bd6b4c..f28a4d54487c 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)
192 u32 xmin, xmax; 192 u32 xmin, xmax;
193 u32 ymin, ymax; 193 u32 ymin, ymax;
194 194
195 xmin = sti_vtg_get_pixel_number(hdmi->mode, 0); 195 xmin = sti_vtg_get_pixel_number(hdmi->mode, 1);
196 xmax = sti_vtg_get_pixel_number(hdmi->mode, hdmi->mode.hdisplay - 1); 196 xmax = sti_vtg_get_pixel_number(hdmi->mode, hdmi->mode.hdisplay);
197 ymin = sti_vtg_get_line_number(hdmi->mode, 0); 197 ymin = sti_vtg_get_line_number(hdmi->mode, 0);
198 ymax = sti_vtg_get_line_number(hdmi->mode, hdmi->mode.vdisplay - 1); 198 ymax = sti_vtg_get_line_number(hdmi->mode, hdmi->mode.vdisplay - 1);
199 199
diff --git a/drivers/gpu/drm/sti/sti_vtg.c b/drivers/gpu/drm/sti/sti_vtg.c
index 9564f2568e2c..aa8097137701 100644
--- a/drivers/gpu/drm/sti/sti_vtg.c
+++ b/drivers/gpu/drm/sti/sti_vtg.c
@@ -62,7 +62,7 @@
62#define VTG_IRQ_MASK (VTG_IRQ_TOP | VTG_IRQ_BOTTOM) 62#define VTG_IRQ_MASK (VTG_IRQ_TOP | VTG_IRQ_BOTTOM)
63 63
64/* Delay introduced by the HDMI in nb of pixel */ 64/* Delay introduced by the HDMI in nb of pixel */
65#define HDMI_DELAY (6) 65#define HDMI_DELAY (5)
66 66
67/* delay introduced by the Arbitrary Waveform Generator in nb of pixels */ 67/* delay introduced by the Arbitrary Waveform Generator in nb of pixels */
68#define AWG_DELAY_HD (-9) 68#define AWG_DELAY_HD (-9)
@@ -121,6 +121,32 @@ static void vtg_reset(struct sti_vtg *vtg)
121 writel(1, vtg->regs + VTG_DRST_AUTOC); 121 writel(1, vtg->regs + VTG_DRST_AUTOC);
122} 122}
123 123
124static void vtg_set_output_window(void __iomem *regs,
125 const struct drm_display_mode *mode)
126{
127 u32 video_top_field_start;
128 u32 video_top_field_stop;
129 u32 video_bottom_field_start;
130 u32 video_bottom_field_stop;
131 u32 xstart = sti_vtg_get_pixel_number(*mode, 0);
132 u32 ystart = sti_vtg_get_line_number(*mode, 0);
133 u32 xstop = sti_vtg_get_pixel_number(*mode, mode->hdisplay - 1);
134 u32 ystop = sti_vtg_get_line_number(*mode, mode->vdisplay - 1);
135
136 /* Set output window to fit the display mode selected */
137 video_top_field_start = (ystart << 16) | xstart;
138 video_top_field_stop = (ystop << 16) | xstop;
139
140 /* Only progressive supported for now */
141 video_bottom_field_start = video_top_field_start;
142 video_bottom_field_stop = video_top_field_stop;
143
144 writel(video_top_field_start, regs + VTG_VID_TFO);
145 writel(video_top_field_stop, regs + VTG_VID_TFS);
146 writel(video_bottom_field_start, regs + VTG_VID_BFO);
147 writel(video_bottom_field_stop, regs + VTG_VID_BFS);
148}
149
124static void vtg_set_mode(struct sti_vtg *vtg, 150static void vtg_set_mode(struct sti_vtg *vtg,
125 int type, const struct drm_display_mode *mode) 151 int type, const struct drm_display_mode *mode)
126{ 152{
@@ -129,18 +155,14 @@ static void vtg_set_mode(struct sti_vtg *vtg,
129 if (vtg->slave) 155 if (vtg->slave)
130 vtg_set_mode(vtg->slave, VTG_TYPE_SLAVE_BY_EXT0, mode); 156 vtg_set_mode(vtg->slave, VTG_TYPE_SLAVE_BY_EXT0, mode);
131 157
158 /* Set the number of clock cycles per line */
132 writel(mode->htotal, vtg->regs + VTG_CLKLN); 159 writel(mode->htotal, vtg->regs + VTG_CLKLN);
133 writel(mode->vtotal * 2, vtg->regs + VTG_HLFLN);
134 160
135 tmp = (mode->vtotal - mode->vsync_start + 1) << 16; 161 /* Set Half Line Per Field (only progressive supported for now) */
136 tmp |= mode->htotal - mode->hsync_start; 162 writel(mode->vtotal * 2, vtg->regs + VTG_HLFLN);
137 writel(tmp, vtg->regs + VTG_VID_TFO);
138 writel(tmp, vtg->regs + VTG_VID_BFO);
139 163
140 tmp = (mode->vdisplay + mode->vtotal - mode->vsync_start + 1) << 16; 164 /* Program output window */
141 tmp |= mode->hdisplay + mode->htotal - mode->hsync_start; 165 vtg_set_output_window(vtg->regs, mode);
142 writel(tmp, vtg->regs + VTG_VID_TFS);
143 writel(tmp, vtg->regs + VTG_VID_BFS);
144 166
145 /* prepare VTG set 1 for HDMI */ 167 /* prepare VTG set 1 for HDMI */
146 tmp = (mode->hsync_end - mode->hsync_start + HDMI_DELAY) << 16; 168 tmp = (mode->hsync_end - mode->hsync_start + HDMI_DELAY) << 16;
@@ -151,8 +173,11 @@ static void vtg_set_mode(struct sti_vtg *vtg,
151 tmp |= 1; 173 tmp |= 1;
152 writel(tmp, vtg->regs + VTG_TOP_V_VD_1); 174 writel(tmp, vtg->regs + VTG_TOP_V_VD_1);
153 writel(tmp, vtg->regs + VTG_BOT_V_VD_1); 175 writel(tmp, vtg->regs + VTG_BOT_V_VD_1);
154 writel(0, vtg->regs + VTG_TOP_V_HD_1); 176
155 writel(0, vtg->regs + VTG_BOT_V_HD_1); 177 tmp = HDMI_DELAY << 16;
178 tmp |= HDMI_DELAY;
179 writel(tmp, vtg->regs + VTG_TOP_V_HD_1);
180 writel(tmp, vtg->regs + VTG_BOT_V_HD_1);
156 181
157 /* prepare VTG set 2 for for HD DCS */ 182 /* prepare VTG set 2 for for HD DCS */
158 tmp = (mode->hsync_end - mode->hsync_start) << 16; 183 tmp = (mode->hsync_end - mode->hsync_start) << 16;
@@ -311,7 +336,6 @@ static int vtg_probe(struct platform_device *pdev)
311 struct device_node *np; 336 struct device_node *np;
312 struct sti_vtg *vtg; 337 struct sti_vtg *vtg;
313 struct resource *res; 338 struct resource *res;
314 char irq_name[32];
315 int ret; 339 int ret;
316 340
317 vtg = devm_kzalloc(dev, sizeof(*vtg), GFP_KERNEL); 341 vtg = devm_kzalloc(dev, sizeof(*vtg), GFP_KERNEL);
@@ -342,13 +366,11 @@ static int vtg_probe(struct platform_device *pdev)
342 return vtg->irq; 366 return vtg->irq;
343 } 367 }
344 368
345 snprintf(irq_name, sizeof(irq_name), "vsync-%s",
346 dev_name(vtg->dev));
347
348 RAW_INIT_NOTIFIER_HEAD(&vtg->notifier_list); 369 RAW_INIT_NOTIFIER_HEAD(&vtg->notifier_list);
349 370
350 ret = devm_request_threaded_irq(dev, vtg->irq, vtg_irq, 371 ret = devm_request_threaded_irq(dev, vtg->irq, vtg_irq,
351 vtg_irq_thread, IRQF_ONESHOT, irq_name, vtg); 372 vtg_irq_thread, IRQF_ONESHOT,
373 dev_name(dev), vtg);
352 if (IS_ERR_VALUE(ret)) { 374 if (IS_ERR_VALUE(ret)) {
353 DRM_ERROR("Failed to register VTG interrupt\n"); 375 DRM_ERROR("Failed to register VTG interrupt\n");
354 return ret; 376 return ret;