aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--drivers/gpu/drm/vc4/vc4_crtc.c64
-rw-r--r--drivers/gpu/drm/vc4/vc4_drv.h30
-rw-r--r--drivers/gpu/drm/vc4/vc4_gem.c13
-rw-r--r--drivers/gpu/drm/vc4/vc4_hdmi.c231
-rw-r--r--drivers/gpu/drm/vc4/vc4_regs.h19
-rw-r--r--drivers/gpu/drm/vc4/vc4_render_cl.c21
-rw-r--r--drivers/gpu/drm/vc4/vc4_validate.c17
7 files changed, 306 insertions, 89 deletions
diff --git a/drivers/gpu/drm/vc4/vc4_crtc.c b/drivers/gpu/drm/vc4/vc4_crtc.c
index 2682f07d8f1e..7f08d681a74b 100644
--- a/drivers/gpu/drm/vc4/vc4_crtc.c
+++ b/drivers/gpu/drm/vc4/vc4_crtc.c
@@ -229,7 +229,7 @@ int vc4_crtc_get_scanoutpos(struct drm_device *dev, unsigned int crtc_id,
229 * and need to make things up in a approximative but consistent way. 229 * and need to make things up in a approximative but consistent way.
230 */ 230 */
231 ret |= DRM_SCANOUTPOS_IN_VBLANK; 231 ret |= DRM_SCANOUTPOS_IN_VBLANK;
232 vblank_lines = mode->crtc_vtotal - mode->crtc_vdisplay; 232 vblank_lines = mode->vtotal - mode->vdisplay;
233 233
234 if (flags & DRM_CALLED_FROM_VBLIRQ) { 234 if (flags & DRM_CALLED_FROM_VBLIRQ) {
235 /* 235 /*
@@ -378,7 +378,7 @@ static void vc4_crtc_mode_set_nofb(struct drm_crtc *crtc)
378 struct drm_crtc_state *state = crtc->state; 378 struct drm_crtc_state *state = crtc->state;
379 struct drm_display_mode *mode = &state->adjusted_mode; 379 struct drm_display_mode *mode = &state->adjusted_mode;
380 bool interlace = mode->flags & DRM_MODE_FLAG_INTERLACE; 380 bool interlace = mode->flags & DRM_MODE_FLAG_INTERLACE;
381 u32 vactive = (mode->vdisplay >> (interlace ? 1 : 0)); 381 u32 pixel_rep = (mode->flags & DRM_MODE_FLAG_DBLCLK) ? 2 : 1;
382 u32 format = PV_CONTROL_FORMAT_24; 382 u32 format = PV_CONTROL_FORMAT_24;
383 bool debug_dump_regs = false; 383 bool debug_dump_regs = false;
384 int clock_select = vc4_get_clock_select(crtc); 384 int clock_select = vc4_get_clock_select(crtc);
@@ -394,47 +394,65 @@ static void vc4_crtc_mode_set_nofb(struct drm_crtc *crtc)
394 CRTC_WRITE(PV_CONTROL, 0); 394 CRTC_WRITE(PV_CONTROL, 0);
395 395
396 CRTC_WRITE(PV_HORZA, 396 CRTC_WRITE(PV_HORZA,
397 VC4_SET_FIELD(mode->htotal - mode->hsync_end, 397 VC4_SET_FIELD((mode->htotal -
398 mode->hsync_end) * pixel_rep,
398 PV_HORZA_HBP) | 399 PV_HORZA_HBP) |
399 VC4_SET_FIELD(mode->hsync_end - mode->hsync_start, 400 VC4_SET_FIELD((mode->hsync_end -
401 mode->hsync_start) * pixel_rep,
400 PV_HORZA_HSYNC)); 402 PV_HORZA_HSYNC));
401 CRTC_WRITE(PV_HORZB, 403 CRTC_WRITE(PV_HORZB,
402 VC4_SET_FIELD(mode->hsync_start - mode->hdisplay, 404 VC4_SET_FIELD((mode->hsync_start -
405 mode->hdisplay) * pixel_rep,
403 PV_HORZB_HFP) | 406 PV_HORZB_HFP) |
404 VC4_SET_FIELD(mode->hdisplay, PV_HORZB_HACTIVE)); 407 VC4_SET_FIELD(mode->hdisplay * pixel_rep, PV_HORZB_HACTIVE));
405 408
406 CRTC_WRITE(PV_VERTA, 409 CRTC_WRITE(PV_VERTA,
407 VC4_SET_FIELD(mode->vtotal - mode->vsync_end, 410 VC4_SET_FIELD(mode->crtc_vtotal - mode->crtc_vsync_end,
408 PV_VERTA_VBP) | 411 PV_VERTA_VBP) |
409 VC4_SET_FIELD(mode->vsync_end - mode->vsync_start, 412 VC4_SET_FIELD(mode->crtc_vsync_end - mode->crtc_vsync_start,
410 PV_VERTA_VSYNC)); 413 PV_VERTA_VSYNC));
411 CRTC_WRITE(PV_VERTB, 414 CRTC_WRITE(PV_VERTB,
412 VC4_SET_FIELD(mode->vsync_start - mode->vdisplay, 415 VC4_SET_FIELD(mode->crtc_vsync_start - mode->crtc_vdisplay,
413 PV_VERTB_VFP) | 416 PV_VERTB_VFP) |
414 VC4_SET_FIELD(vactive, PV_VERTB_VACTIVE)); 417 VC4_SET_FIELD(mode->crtc_vdisplay, PV_VERTB_VACTIVE));
415 418
416 if (interlace) { 419 if (interlace) {
417 CRTC_WRITE(PV_VERTA_EVEN, 420 CRTC_WRITE(PV_VERTA_EVEN,
418 VC4_SET_FIELD(mode->vtotal - mode->vsync_end - 1, 421 VC4_SET_FIELD(mode->crtc_vtotal -
422 mode->crtc_vsync_end - 1,
419 PV_VERTA_VBP) | 423 PV_VERTA_VBP) |
420 VC4_SET_FIELD(mode->vsync_end - mode->vsync_start, 424 VC4_SET_FIELD(mode->crtc_vsync_end -
425 mode->crtc_vsync_start,
421 PV_VERTA_VSYNC)); 426 PV_VERTA_VSYNC));
422 CRTC_WRITE(PV_VERTB_EVEN, 427 CRTC_WRITE(PV_VERTB_EVEN,
423 VC4_SET_FIELD(mode->vsync_start - mode->vdisplay, 428 VC4_SET_FIELD(mode->crtc_vsync_start -
429 mode->crtc_vdisplay,
424 PV_VERTB_VFP) | 430 PV_VERTB_VFP) |
425 VC4_SET_FIELD(vactive, PV_VERTB_VACTIVE)); 431 VC4_SET_FIELD(mode->crtc_vdisplay, PV_VERTB_VACTIVE));
432
433 /* We set up first field even mode for HDMI. VEC's
434 * NTSC mode would want first field odd instead, once
435 * we support it (to do so, set ODD_FIRST and put the
436 * delay in VSYNCD_EVEN instead).
437 */
438 CRTC_WRITE(PV_V_CONTROL,
439 PV_VCONTROL_CONTINUOUS |
440 PV_VCONTROL_INTERLACE |
441 VC4_SET_FIELD(mode->htotal * pixel_rep / 2,
442 PV_VCONTROL_ODD_DELAY));
443 CRTC_WRITE(PV_VSYNCD_EVEN, 0);
444 } else {
445 CRTC_WRITE(PV_V_CONTROL, PV_VCONTROL_CONTINUOUS);
426 } 446 }
427 447
428 CRTC_WRITE(PV_HACT_ACT, mode->hdisplay); 448 CRTC_WRITE(PV_HACT_ACT, mode->hdisplay * pixel_rep);
429 449
430 CRTC_WRITE(PV_V_CONTROL,
431 PV_VCONTROL_CONTINUOUS |
432 (interlace ? PV_VCONTROL_INTERLACE : 0));
433 450
434 CRTC_WRITE(PV_CONTROL, 451 CRTC_WRITE(PV_CONTROL,
435 VC4_SET_FIELD(format, PV_CONTROL_FORMAT) | 452 VC4_SET_FIELD(format, PV_CONTROL_FORMAT) |
436 VC4_SET_FIELD(vc4_get_fifo_full_level(format), 453 VC4_SET_FIELD(vc4_get_fifo_full_level(format),
437 PV_CONTROL_FIFO_LEVEL) | 454 PV_CONTROL_FIFO_LEVEL) |
455 VC4_SET_FIELD(pixel_rep - 1, PV_CONTROL_PIXEL_REP) |
438 PV_CONTROL_CLR_AT_START | 456 PV_CONTROL_CLR_AT_START |
439 PV_CONTROL_TRIGGER_UNDERFLOW | 457 PV_CONTROL_TRIGGER_UNDERFLOW |
440 PV_CONTROL_WAIT_HSTART | 458 PV_CONTROL_WAIT_HSTART |
@@ -544,16 +562,6 @@ static bool vc4_crtc_mode_fixup(struct drm_crtc *crtc,
544 return false; 562 return false;
545 } 563 }
546 564
547 /*
548 * Interlaced video modes got CRTC_INTERLACE_HALVE_V applied when
549 * coming from user space. We don't want this, as it screws up
550 * vblank timestamping, so fix it up.
551 */
552 drm_mode_set_crtcinfo(adjusted_mode, 0);
553
554 DRM_DEBUG_KMS("[CRTC:%d] adjusted_mode :\n", crtc->base.id);
555 drm_mode_debug_printmodeline(adjusted_mode);
556
557 return true; 565 return true;
558} 566}
559 567
diff --git a/drivers/gpu/drm/vc4/vc4_drv.h b/drivers/gpu/drm/vc4/vc4_drv.h
index 428e24919ef1..7c1e4d97486f 100644
--- a/drivers/gpu/drm/vc4/vc4_drv.h
+++ b/drivers/gpu/drm/vc4/vc4_drv.h
@@ -122,9 +122,16 @@ to_vc4_dev(struct drm_device *dev)
122struct vc4_bo { 122struct vc4_bo {
123 struct drm_gem_cma_object base; 123 struct drm_gem_cma_object base;
124 124
125 /* seqno of the last job to render to this BO. */ 125 /* seqno of the last job to render using this BO. */
126 uint64_t seqno; 126 uint64_t seqno;
127 127
128 /* seqno of the last job to use the RCL to write to this BO.
129 *
130 * Note that this doesn't include binner overflow memory
131 * writes.
132 */
133 uint64_t write_seqno;
134
128 /* List entry for the BO's position in either 135 /* List entry for the BO's position in either
129 * vc4_exec_info->unref_list or vc4_dev->bo_cache.time_list 136 * vc4_exec_info->unref_list or vc4_dev->bo_cache.time_list
130 */ 137 */
@@ -216,6 +223,9 @@ struct vc4_exec_info {
216 /* Sequence number for this bin/render job. */ 223 /* Sequence number for this bin/render job. */
217 uint64_t seqno; 224 uint64_t seqno;
218 225
226 /* Latest write_seqno of any BO that binning depends on. */
227 uint64_t bin_dep_seqno;
228
219 /* Last current addresses the hardware was processing when the 229 /* Last current addresses the hardware was processing when the
220 * hangcheck timer checked on us. 230 * hangcheck timer checked on us.
221 */ 231 */
@@ -230,6 +240,13 @@ struct vc4_exec_info {
230 struct drm_gem_cma_object **bo; 240 struct drm_gem_cma_object **bo;
231 uint32_t bo_count; 241 uint32_t bo_count;
232 242
243 /* List of BOs that are being written by the RCL. Other than
244 * the binner temporary storage, this is all the BOs written
245 * by the job.
246 */
247 struct drm_gem_cma_object *rcl_write_bo[4];
248 uint32_t rcl_write_bo_count;
249
233 /* Pointers for our position in vc4->job_list */ 250 /* Pointers for our position in vc4->job_list */
234 struct list_head head; 251 struct list_head head;
235 252
@@ -307,18 +324,15 @@ struct vc4_exec_info {
307static inline struct vc4_exec_info * 324static inline struct vc4_exec_info *
308vc4_first_bin_job(struct vc4_dev *vc4) 325vc4_first_bin_job(struct vc4_dev *vc4)
309{ 326{
310 if (list_empty(&vc4->bin_job_list)) 327 return list_first_entry_or_null(&vc4->bin_job_list,
311 return NULL; 328 struct vc4_exec_info, head);
312 return list_first_entry(&vc4->bin_job_list, struct vc4_exec_info, head);
313} 329}
314 330
315static inline struct vc4_exec_info * 331static inline struct vc4_exec_info *
316vc4_first_render_job(struct vc4_dev *vc4) 332vc4_first_render_job(struct vc4_dev *vc4)
317{ 333{
318 if (list_empty(&vc4->render_job_list)) 334 return list_first_entry_or_null(&vc4->render_job_list,
319 return NULL; 335 struct vc4_exec_info, head);
320 return list_first_entry(&vc4->render_job_list,
321 struct vc4_exec_info, head);
322} 336}
323 337
324static inline struct vc4_exec_info * 338static inline struct vc4_exec_info *
diff --git a/drivers/gpu/drm/vc4/vc4_gem.c b/drivers/gpu/drm/vc4/vc4_gem.c
index 77daea6cb866..47a095f392f8 100644
--- a/drivers/gpu/drm/vc4/vc4_gem.c
+++ b/drivers/gpu/drm/vc4/vc4_gem.c
@@ -467,6 +467,11 @@ vc4_update_bo_seqnos(struct vc4_exec_info *exec, uint64_t seqno)
467 list_for_each_entry(bo, &exec->unref_list, unref_head) { 467 list_for_each_entry(bo, &exec->unref_list, unref_head) {
468 bo->seqno = seqno; 468 bo->seqno = seqno;
469 } 469 }
470
471 for (i = 0; i < exec->rcl_write_bo_count; i++) {
472 bo = to_vc4_bo(&exec->rcl_write_bo[i]->base);
473 bo->write_seqno = seqno;
474 }
470} 475}
471 476
472/* Queues a struct vc4_exec_info for execution. If no job is 477/* Queues a struct vc4_exec_info for execution. If no job is
@@ -669,6 +674,14 @@ vc4_get_bcl(struct drm_device *dev, struct vc4_exec_info *exec)
669 goto fail; 674 goto fail;
670 675
671 ret = vc4_validate_shader_recs(dev, exec); 676 ret = vc4_validate_shader_recs(dev, exec);
677 if (ret)
678 goto fail;
679
680 /* Block waiting on any previous rendering into the CS's VBO,
681 * IB, or textures, so that pixels are actually written by the
682 * time we try to read them.
683 */
684 ret = vc4_wait_for_seqno(dev, exec->bin_dep_seqno, ~0ull, true);
672 685
673fail: 686fail:
674 drm_free_large(temp); 687 drm_free_large(temp);
diff --git a/drivers/gpu/drm/vc4/vc4_hdmi.c b/drivers/gpu/drm/vc4/vc4_hdmi.c
index 68ad10634b29..c4cb2e26de32 100644
--- a/drivers/gpu/drm/vc4/vc4_hdmi.c
+++ b/drivers/gpu/drm/vc4/vc4_hdmi.c
@@ -62,6 +62,8 @@ struct vc4_hdmi {
62struct vc4_hdmi_encoder { 62struct vc4_hdmi_encoder {
63 struct vc4_encoder base; 63 struct vc4_encoder base;
64 bool hdmi_monitor; 64 bool hdmi_monitor;
65 bool limited_rgb_range;
66 bool rgb_range_selectable;
65}; 67};
66 68
67static inline struct vc4_hdmi_encoder * 69static inline struct vc4_hdmi_encoder *
@@ -174,6 +176,9 @@ vc4_hdmi_connector_detect(struct drm_connector *connector, bool force)
174 return connector_status_disconnected; 176 return connector_status_disconnected;
175 } 177 }
176 178
179 if (drm_probe_ddc(vc4->hdmi->ddc))
180 return connector_status_connected;
181
177 if (HDMI_READ(VC4_HDMI_HOTPLUG) & VC4_HDMI_HOTPLUG_CONNECTED) 182 if (HDMI_READ(VC4_HDMI_HOTPLUG) & VC4_HDMI_HOTPLUG_CONNECTED)
178 return connector_status_connected; 183 return connector_status_connected;
179 else 184 else
@@ -202,41 +207,22 @@ static int vc4_hdmi_connector_get_modes(struct drm_connector *connector)
202 return -ENODEV; 207 return -ENODEV;
203 208
204 vc4_encoder->hdmi_monitor = drm_detect_hdmi_monitor(edid); 209 vc4_encoder->hdmi_monitor = drm_detect_hdmi_monitor(edid);
210
211 if (edid && edid->input & DRM_EDID_INPUT_DIGITAL) {
212 vc4_encoder->rgb_range_selectable =
213 drm_rgb_quant_range_selectable(edid);
214 }
215
205 drm_mode_connector_update_edid_property(connector, edid); 216 drm_mode_connector_update_edid_property(connector, edid);
206 ret = drm_add_edid_modes(connector, edid); 217 ret = drm_add_edid_modes(connector, edid);
207 218
208 return ret; 219 return ret;
209} 220}
210 221
211/*
212 * drm_helper_probe_single_connector_modes() applies drm_mode_set_crtcinfo to
213 * all modes with flag CRTC_INTERLACE_HALVE_V. We don't want this, as it
214 * screws up vblank timestamping for interlaced modes, so fix it up.
215 */
216static int vc4_hdmi_connector_probe_modes(struct drm_connector *connector,
217 uint32_t maxX, uint32_t maxY)
218{
219 struct drm_display_mode *mode;
220 int count;
221
222 count = drm_helper_probe_single_connector_modes(connector, maxX, maxY);
223 if (count == 0)
224 return 0;
225
226 DRM_DEBUG_KMS("[CONNECTOR:%d:%s] probed adapted modes :\n",
227 connector->base.id, connector->name);
228 list_for_each_entry(mode, &connector->modes, head) {
229 drm_mode_set_crtcinfo(mode, 0);
230 drm_mode_debug_printmodeline(mode);
231 }
232
233 return count;
234}
235
236static const struct drm_connector_funcs vc4_hdmi_connector_funcs = { 222static const struct drm_connector_funcs vc4_hdmi_connector_funcs = {
237 .dpms = drm_atomic_helper_connector_dpms, 223 .dpms = drm_atomic_helper_connector_dpms,
238 .detect = vc4_hdmi_connector_detect, 224 .detect = vc4_hdmi_connector_detect,
239 .fill_modes = vc4_hdmi_connector_probe_modes, 225 .fill_modes = drm_helper_probe_single_connector_modes,
240 .destroy = vc4_hdmi_connector_destroy, 226 .destroy = vc4_hdmi_connector_destroy,
241 .reset = drm_atomic_helper_connector_reset, 227 .reset = drm_atomic_helper_connector_reset,
242 .atomic_duplicate_state = drm_atomic_helper_connector_duplicate_state, 228 .atomic_duplicate_state = drm_atomic_helper_connector_duplicate_state,
@@ -294,25 +280,143 @@ static const struct drm_encoder_funcs vc4_hdmi_encoder_funcs = {
294 .destroy = vc4_hdmi_encoder_destroy, 280 .destroy = vc4_hdmi_encoder_destroy,
295}; 281};
296 282
283static int vc4_hdmi_stop_packet(struct drm_encoder *encoder,
284 enum hdmi_infoframe_type type)
285{
286 struct drm_device *dev = encoder->dev;
287 struct vc4_dev *vc4 = to_vc4_dev(dev);
288 u32 packet_id = type - 0x80;
289
290 HDMI_WRITE(VC4_HDMI_RAM_PACKET_CONFIG,
291 HDMI_READ(VC4_HDMI_RAM_PACKET_CONFIG) & ~BIT(packet_id));
292
293 return wait_for(!(HDMI_READ(VC4_HDMI_RAM_PACKET_STATUS) &
294 BIT(packet_id)), 100);
295}
296
297static void vc4_hdmi_write_infoframe(struct drm_encoder *encoder,
298 union hdmi_infoframe *frame)
299{
300 struct drm_device *dev = encoder->dev;
301 struct vc4_dev *vc4 = to_vc4_dev(dev);
302 u32 packet_id = frame->any.type - 0x80;
303 u32 packet_reg = VC4_HDMI_GCP_0 + VC4_HDMI_PACKET_STRIDE * packet_id;
304 uint8_t buffer[VC4_HDMI_PACKET_STRIDE];
305 ssize_t len, i;
306 int ret;
307
308 WARN_ONCE(!(HDMI_READ(VC4_HDMI_RAM_PACKET_CONFIG) &
309 VC4_HDMI_RAM_PACKET_ENABLE),
310 "Packet RAM has to be on to store the packet.");
311
312 len = hdmi_infoframe_pack(frame, buffer, sizeof(buffer));
313 if (len < 0)
314 return;
315
316 ret = vc4_hdmi_stop_packet(encoder, frame->any.type);
317 if (ret) {
318 DRM_ERROR("Failed to wait for infoframe to go idle: %d\n", ret);
319 return;
320 }
321
322 for (i = 0; i < len; i += 7) {
323 HDMI_WRITE(packet_reg,
324 buffer[i + 0] << 0 |
325 buffer[i + 1] << 8 |
326 buffer[i + 2] << 16);
327 packet_reg += 4;
328
329 HDMI_WRITE(packet_reg,
330 buffer[i + 3] << 0 |
331 buffer[i + 4] << 8 |
332 buffer[i + 5] << 16 |
333 buffer[i + 6] << 24);
334 packet_reg += 4;
335 }
336
337 HDMI_WRITE(VC4_HDMI_RAM_PACKET_CONFIG,
338 HDMI_READ(VC4_HDMI_RAM_PACKET_CONFIG) | BIT(packet_id));
339 ret = wait_for((HDMI_READ(VC4_HDMI_RAM_PACKET_STATUS) &
340 BIT(packet_id)), 100);
341 if (ret)
342 DRM_ERROR("Failed to wait for infoframe to start: %d\n", ret);
343}
344
345static void vc4_hdmi_set_avi_infoframe(struct drm_encoder *encoder)
346{
347 struct vc4_hdmi_encoder *vc4_encoder = to_vc4_hdmi_encoder(encoder);
348 struct drm_crtc *crtc = encoder->crtc;
349 const struct drm_display_mode *mode = &crtc->state->adjusted_mode;
350 union hdmi_infoframe frame;
351 int ret;
352
353 ret = drm_hdmi_avi_infoframe_from_display_mode(&frame.avi, mode);
354 if (ret < 0) {
355 DRM_ERROR("couldn't fill AVI infoframe\n");
356 return;
357 }
358
359 if (vc4_encoder->rgb_range_selectable) {
360 if (vc4_encoder->limited_rgb_range) {
361 frame.avi.quantization_range =
362 HDMI_QUANTIZATION_RANGE_LIMITED;
363 } else {
364 frame.avi.quantization_range =
365 HDMI_QUANTIZATION_RANGE_FULL;
366 }
367 }
368
369 vc4_hdmi_write_infoframe(encoder, &frame);
370}
371
372static void vc4_hdmi_set_spd_infoframe(struct drm_encoder *encoder)
373{
374 union hdmi_infoframe frame;
375 int ret;
376
377 ret = hdmi_spd_infoframe_init(&frame.spd, "Broadcom", "Videocore");
378 if (ret < 0) {
379 DRM_ERROR("couldn't fill SPD infoframe\n");
380 return;
381 }
382
383 frame.spd.sdi = HDMI_SPD_SDI_PC;
384
385 vc4_hdmi_write_infoframe(encoder, &frame);
386}
387
388static void vc4_hdmi_set_infoframes(struct drm_encoder *encoder)
389{
390 vc4_hdmi_set_avi_infoframe(encoder);
391 vc4_hdmi_set_spd_infoframe(encoder);
392}
393
297static void vc4_hdmi_encoder_mode_set(struct drm_encoder *encoder, 394static void vc4_hdmi_encoder_mode_set(struct drm_encoder *encoder,
298 struct drm_display_mode *unadjusted_mode, 395 struct drm_display_mode *unadjusted_mode,
299 struct drm_display_mode *mode) 396 struct drm_display_mode *mode)
300{ 397{
398 struct vc4_hdmi_encoder *vc4_encoder = to_vc4_hdmi_encoder(encoder);
301 struct drm_device *dev = encoder->dev; 399 struct drm_device *dev = encoder->dev;
302 struct vc4_dev *vc4 = to_vc4_dev(dev); 400 struct vc4_dev *vc4 = to_vc4_dev(dev);
303 bool debug_dump_regs = false; 401 bool debug_dump_regs = false;
304 bool hsync_pos = mode->flags & DRM_MODE_FLAG_PHSYNC; 402 bool hsync_pos = mode->flags & DRM_MODE_FLAG_PHSYNC;
305 bool vsync_pos = mode->flags & DRM_MODE_FLAG_PVSYNC; 403 bool vsync_pos = mode->flags & DRM_MODE_FLAG_PVSYNC;
306 u32 vactive = (mode->vdisplay >> 404 bool interlaced = mode->flags & DRM_MODE_FLAG_INTERLACE;
307 ((mode->flags & DRM_MODE_FLAG_INTERLACE) ? 1 : 0)); 405 u32 pixel_rep = (mode->flags & DRM_MODE_FLAG_DBLCLK) ? 2 : 1;
308 u32 verta = (VC4_SET_FIELD(mode->vsync_end - mode->vsync_start, 406 u32 verta = (VC4_SET_FIELD(mode->crtc_vsync_end - mode->crtc_vsync_start,
309 VC4_HDMI_VERTA_VSP) | 407 VC4_HDMI_VERTA_VSP) |
310 VC4_SET_FIELD(mode->vsync_start - mode->vdisplay, 408 VC4_SET_FIELD(mode->crtc_vsync_start - mode->crtc_vdisplay,
311 VC4_HDMI_VERTA_VFP) | 409 VC4_HDMI_VERTA_VFP) |
312 VC4_SET_FIELD(vactive, VC4_HDMI_VERTA_VAL)); 410 VC4_SET_FIELD(mode->crtc_vdisplay, VC4_HDMI_VERTA_VAL));
313 u32 vertb = (VC4_SET_FIELD(0, VC4_HDMI_VERTB_VSPO) | 411 u32 vertb = (VC4_SET_FIELD(0, VC4_HDMI_VERTB_VSPO) |
314 VC4_SET_FIELD(mode->vtotal - mode->vsync_end, 412 VC4_SET_FIELD(mode->crtc_vtotal - mode->crtc_vsync_end,
315 VC4_HDMI_VERTB_VBP)); 413 VC4_HDMI_VERTB_VBP));
414 u32 vertb_even = (VC4_SET_FIELD(0, VC4_HDMI_VERTB_VSPO) |
415 VC4_SET_FIELD(mode->crtc_vtotal -
416 mode->crtc_vsync_end -
417 interlaced,
418 VC4_HDMI_VERTB_VBP));
419 u32 csc_ctl;
316 420
317 if (debug_dump_regs) { 421 if (debug_dump_regs) {
318 DRM_INFO("HDMI regs before:\n"); 422 DRM_INFO("HDMI regs before:\n");
@@ -321,7 +425,8 @@ static void vc4_hdmi_encoder_mode_set(struct drm_encoder *encoder,
321 425
322 HD_WRITE(VC4_HD_VID_CTL, 0); 426 HD_WRITE(VC4_HD_VID_CTL, 0);
323 427
324 clk_set_rate(vc4->hdmi->pixel_clock, mode->clock * 1000); 428 clk_set_rate(vc4->hdmi->pixel_clock, mode->clock * 1000 *
429 ((mode->flags & DRM_MODE_FLAG_DBLCLK) ? 2 : 1));
325 430
326 HDMI_WRITE(VC4_HDMI_SCHEDULER_CONTROL, 431 HDMI_WRITE(VC4_HDMI_SCHEDULER_CONTROL,
327 HDMI_READ(VC4_HDMI_SCHEDULER_CONTROL) | 432 HDMI_READ(VC4_HDMI_SCHEDULER_CONTROL) |
@@ -331,29 +436,62 @@ static void vc4_hdmi_encoder_mode_set(struct drm_encoder *encoder,
331 HDMI_WRITE(VC4_HDMI_HORZA, 436 HDMI_WRITE(VC4_HDMI_HORZA,
332 (vsync_pos ? VC4_HDMI_HORZA_VPOS : 0) | 437 (vsync_pos ? VC4_HDMI_HORZA_VPOS : 0) |
333 (hsync_pos ? VC4_HDMI_HORZA_HPOS : 0) | 438 (hsync_pos ? VC4_HDMI_HORZA_HPOS : 0) |
334 VC4_SET_FIELD(mode->hdisplay, VC4_HDMI_HORZA_HAP)); 439 VC4_SET_FIELD(mode->hdisplay * pixel_rep,
440 VC4_HDMI_HORZA_HAP));
335 441
336 HDMI_WRITE(VC4_HDMI_HORZB, 442 HDMI_WRITE(VC4_HDMI_HORZB,
337 VC4_SET_FIELD(mode->htotal - mode->hsync_end, 443 VC4_SET_FIELD((mode->htotal -
444 mode->hsync_end) * pixel_rep,
338 VC4_HDMI_HORZB_HBP) | 445 VC4_HDMI_HORZB_HBP) |
339 VC4_SET_FIELD(mode->hsync_end - mode->hsync_start, 446 VC4_SET_FIELD((mode->hsync_end -
447 mode->hsync_start) * pixel_rep,
340 VC4_HDMI_HORZB_HSP) | 448 VC4_HDMI_HORZB_HSP) |
341 VC4_SET_FIELD(mode->hsync_start - mode->hdisplay, 449 VC4_SET_FIELD((mode->hsync_start -
450 mode->hdisplay) * pixel_rep,
342 VC4_HDMI_HORZB_HFP)); 451 VC4_HDMI_HORZB_HFP));
343 452
344 HDMI_WRITE(VC4_HDMI_VERTA0, verta); 453 HDMI_WRITE(VC4_HDMI_VERTA0, verta);
345 HDMI_WRITE(VC4_HDMI_VERTA1, verta); 454 HDMI_WRITE(VC4_HDMI_VERTA1, verta);
346 455
347 HDMI_WRITE(VC4_HDMI_VERTB0, vertb); 456 HDMI_WRITE(VC4_HDMI_VERTB0, vertb_even);
348 HDMI_WRITE(VC4_HDMI_VERTB1, vertb); 457 HDMI_WRITE(VC4_HDMI_VERTB1, vertb);
349 458
350 HD_WRITE(VC4_HD_VID_CTL, 459 HD_WRITE(VC4_HD_VID_CTL,
351 (vsync_pos ? 0 : VC4_HD_VID_CTL_VSYNC_LOW) | 460 (vsync_pos ? 0 : VC4_HD_VID_CTL_VSYNC_LOW) |
352 (hsync_pos ? 0 : VC4_HD_VID_CTL_HSYNC_LOW)); 461 (hsync_pos ? 0 : VC4_HD_VID_CTL_HSYNC_LOW));
353 462
463 csc_ctl = VC4_SET_FIELD(VC4_HD_CSC_CTL_ORDER_BGR,
464 VC4_HD_CSC_CTL_ORDER);
465
466 if (vc4_encoder->hdmi_monitor && drm_match_cea_mode(mode) > 1) {
467 /* CEA VICs other than #1 requre limited range RGB
468 * output unless overridden by an AVI infoframe.
469 * Apply a colorspace conversion to squash 0-255 down
470 * to 16-235. The matrix here is:
471 *
472 * [ 0 0 0.8594 16]
473 * [ 0 0.8594 0 16]
474 * [ 0.8594 0 0 16]
475 * [ 0 0 0 1]
476 */
477 csc_ctl |= VC4_HD_CSC_CTL_ENABLE;
478 csc_ctl |= VC4_HD_CSC_CTL_RGB2YCC;
479 csc_ctl |= VC4_SET_FIELD(VC4_HD_CSC_CTL_MODE_CUSTOM,
480 VC4_HD_CSC_CTL_MODE);
481
482 HD_WRITE(VC4_HD_CSC_12_11, (0x000 << 16) | 0x000);
483 HD_WRITE(VC4_HD_CSC_14_13, (0x100 << 16) | 0x6e0);
484 HD_WRITE(VC4_HD_CSC_22_21, (0x6e0 << 16) | 0x000);
485 HD_WRITE(VC4_HD_CSC_24_23, (0x100 << 16) | 0x000);
486 HD_WRITE(VC4_HD_CSC_32_31, (0x000 << 16) | 0x6e0);
487 HD_WRITE(VC4_HD_CSC_34_33, (0x100 << 16) | 0x000);
488 vc4_encoder->limited_rgb_range = true;
489 } else {
490 vc4_encoder->limited_rgb_range = false;
491 }
492
354 /* The RGB order applies even when CSC is disabled. */ 493 /* The RGB order applies even when CSC is disabled. */
355 HD_WRITE(VC4_HD_CSC_CTL, VC4_SET_FIELD(VC4_HD_CSC_CTL_ORDER_BGR, 494 HD_WRITE(VC4_HD_CSC_CTL, csc_ctl);
356 VC4_HD_CSC_CTL_ORDER));
357 495
358 HDMI_WRITE(VC4_HDMI_FIFO_CTL, VC4_HDMI_FIFO_CTL_MASTER_SLAVE_N); 496 HDMI_WRITE(VC4_HDMI_FIFO_CTL, VC4_HDMI_FIFO_CTL_MASTER_SLAVE_N);
359 497
@@ -368,6 +506,8 @@ static void vc4_hdmi_encoder_disable(struct drm_encoder *encoder)
368 struct drm_device *dev = encoder->dev; 506 struct drm_device *dev = encoder->dev;
369 struct vc4_dev *vc4 = to_vc4_dev(dev); 507 struct vc4_dev *vc4 = to_vc4_dev(dev);
370 508
509 HDMI_WRITE(VC4_HDMI_RAM_PACKET_CONFIG, 0);
510
371 HDMI_WRITE(VC4_HDMI_TX_PHY_RESET_CTL, 0xf << 16); 511 HDMI_WRITE(VC4_HDMI_TX_PHY_RESET_CTL, 0xf << 16);
372 HD_WRITE(VC4_HD_VID_CTL, 512 HD_WRITE(VC4_HD_VID_CTL,
373 HD_READ(VC4_HD_VID_CTL) & ~VC4_HD_VID_CTL_ENABLE); 513 HD_READ(VC4_HD_VID_CTL) & ~VC4_HD_VID_CTL_ENABLE);
@@ -394,7 +534,7 @@ static void vc4_hdmi_encoder_enable(struct drm_encoder *encoder)
394 VC4_HDMI_SCHEDULER_CONTROL_MODE_HDMI); 534 VC4_HDMI_SCHEDULER_CONTROL_MODE_HDMI);
395 535
396 ret = wait_for(HDMI_READ(VC4_HDMI_SCHEDULER_CONTROL) & 536 ret = wait_for(HDMI_READ(VC4_HDMI_SCHEDULER_CONTROL) &
397 VC4_HDMI_SCHEDULER_CONTROL_HDMI_ACTIVE, 1); 537 VC4_HDMI_SCHEDULER_CONTROL_HDMI_ACTIVE, 1000);
398 WARN_ONCE(ret, "Timeout waiting for " 538 WARN_ONCE(ret, "Timeout waiting for "
399 "VC4_HDMI_SCHEDULER_CONTROL_HDMI_ACTIVE\n"); 539 "VC4_HDMI_SCHEDULER_CONTROL_HDMI_ACTIVE\n");
400 } else { 540 } else {
@@ -406,7 +546,7 @@ static void vc4_hdmi_encoder_enable(struct drm_encoder *encoder)
406 ~VC4_HDMI_SCHEDULER_CONTROL_MODE_HDMI); 546 ~VC4_HDMI_SCHEDULER_CONTROL_MODE_HDMI);
407 547
408 ret = wait_for(!(HDMI_READ(VC4_HDMI_SCHEDULER_CONTROL) & 548 ret = wait_for(!(HDMI_READ(VC4_HDMI_SCHEDULER_CONTROL) &
409 VC4_HDMI_SCHEDULER_CONTROL_HDMI_ACTIVE), 1); 549 VC4_HDMI_SCHEDULER_CONTROL_HDMI_ACTIVE), 1000);
410 WARN_ONCE(ret, "Timeout waiting for " 550 WARN_ONCE(ret, "Timeout waiting for "
411 "!VC4_HDMI_SCHEDULER_CONTROL_HDMI_ACTIVE\n"); 551 "!VC4_HDMI_SCHEDULER_CONTROL_HDMI_ACTIVE\n");
412 } 552 }
@@ -420,9 +560,10 @@ static void vc4_hdmi_encoder_enable(struct drm_encoder *encoder)
420 HDMI_READ(VC4_HDMI_SCHEDULER_CONTROL) | 560 HDMI_READ(VC4_HDMI_SCHEDULER_CONTROL) |
421 VC4_HDMI_SCHEDULER_CONTROL_VERT_ALWAYS_KEEPOUT); 561 VC4_HDMI_SCHEDULER_CONTROL_VERT_ALWAYS_KEEPOUT);
422 562
423 /* XXX: Set HDMI_RAM_PACKET_CONFIG (1 << 16) and set 563 HDMI_WRITE(VC4_HDMI_RAM_PACKET_CONFIG,
424 * up the infoframe. 564 VC4_HDMI_RAM_PACKET_ENABLE);
425 */ 565
566 vc4_hdmi_set_infoframes(encoder);
426 567
427 drift = HDMI_READ(VC4_HDMI_FIFO_CTL); 568 drift = HDMI_READ(VC4_HDMI_FIFO_CTL);
428 drift &= VC4_HDMI_FIFO_VALID_WRITE_MASK; 569 drift &= VC4_HDMI_FIFO_VALID_WRITE_MASK;
diff --git a/drivers/gpu/drm/vc4/vc4_regs.h b/drivers/gpu/drm/vc4/vc4_regs.h
index 160942a9180e..1aa44c2db556 100644
--- a/drivers/gpu/drm/vc4/vc4_regs.h
+++ b/drivers/gpu/drm/vc4/vc4_regs.h
@@ -175,6 +175,8 @@
175# define PV_CONTROL_CLR_AT_START BIT(14) 175# define PV_CONTROL_CLR_AT_START BIT(14)
176# define PV_CONTROL_TRIGGER_UNDERFLOW BIT(13) 176# define PV_CONTROL_TRIGGER_UNDERFLOW BIT(13)
177# define PV_CONTROL_WAIT_HSTART BIT(12) 177# define PV_CONTROL_WAIT_HSTART BIT(12)
178# define PV_CONTROL_PIXEL_REP_MASK VC4_MASK(5, 4)
179# define PV_CONTROL_PIXEL_REP_SHIFT 4
178# define PV_CONTROL_CLK_SELECT_DSI_VEC 0 180# define PV_CONTROL_CLK_SELECT_DSI_VEC 0
179# define PV_CONTROL_CLK_SELECT_DPI_SMI_HDMI 1 181# define PV_CONTROL_CLK_SELECT_DPI_SMI_HDMI 1
180# define PV_CONTROL_CLK_SELECT_MASK VC4_MASK(3, 2) 182# define PV_CONTROL_CLK_SELECT_MASK VC4_MASK(3, 2)
@@ -183,6 +185,9 @@
183# define PV_CONTROL_EN BIT(0) 185# define PV_CONTROL_EN BIT(0)
184 186
185#define PV_V_CONTROL 0x04 187#define PV_V_CONTROL 0x04
188# define PV_VCONTROL_ODD_DELAY_MASK VC4_MASK(22, 6)
189# define PV_VCONTROL_ODD_DELAY_SHIFT 6
190# define PV_VCONTROL_ODD_FIRST BIT(5)
186# define PV_VCONTROL_INTERLACE BIT(4) 191# define PV_VCONTROL_INTERLACE BIT(4)
187# define PV_VCONTROL_CONTINUOUS BIT(1) 192# define PV_VCONTROL_CONTINUOUS BIT(1)
188# define PV_VCONTROL_VIDEN BIT(0) 193# define PV_VCONTROL_VIDEN BIT(0)
@@ -438,6 +443,8 @@
438#define VC4_HDMI_RAM_PACKET_CONFIG 0x0a0 443#define VC4_HDMI_RAM_PACKET_CONFIG 0x0a0
439# define VC4_HDMI_RAM_PACKET_ENABLE BIT(16) 444# define VC4_HDMI_RAM_PACKET_ENABLE BIT(16)
440 445
446#define VC4_HDMI_RAM_PACKET_STATUS 0x0a4
447
441#define VC4_HDMI_HORZA 0x0c4 448#define VC4_HDMI_HORZA 0x0c4
442# define VC4_HDMI_HORZA_VPOS BIT(14) 449# define VC4_HDMI_HORZA_VPOS BIT(14)
443# define VC4_HDMI_HORZA_HPOS BIT(13) 450# define VC4_HDMI_HORZA_HPOS BIT(13)
@@ -499,6 +506,9 @@
499 506
500#define VC4_HDMI_TX_PHY_RESET_CTL 0x2c0 507#define VC4_HDMI_TX_PHY_RESET_CTL 0x2c0
501 508
509#define VC4_HDMI_GCP_0 0x400
510#define VC4_HDMI_PACKET_STRIDE 0x24
511
502#define VC4_HD_M_CTL 0x00c 512#define VC4_HD_M_CTL 0x00c
503# define VC4_HD_M_REGISTER_FILE_STANDBY (3 << 6) 513# define VC4_HD_M_REGISTER_FILE_STANDBY (3 << 6)
504# define VC4_HD_M_RAM_STANDBY (3 << 4) 514# define VC4_HD_M_RAM_STANDBY (3 << 4)
@@ -528,10 +538,17 @@
528# define VC4_HD_CSC_CTL_MODE_SHIFT 2 538# define VC4_HD_CSC_CTL_MODE_SHIFT 2
529# define VC4_HD_CSC_CTL_MODE_RGB_TO_SD_YPRPB 0 539# define VC4_HD_CSC_CTL_MODE_RGB_TO_SD_YPRPB 0
530# define VC4_HD_CSC_CTL_MODE_RGB_TO_HD_YPRPB 1 540# define VC4_HD_CSC_CTL_MODE_RGB_TO_HD_YPRPB 1
531# define VC4_HD_CSC_CTL_MODE_CUSTOM 2 541# define VC4_HD_CSC_CTL_MODE_CUSTOM 3
532# define VC4_HD_CSC_CTL_RGB2YCC BIT(1) 542# define VC4_HD_CSC_CTL_RGB2YCC BIT(1)
533# define VC4_HD_CSC_CTL_ENABLE BIT(0) 543# define VC4_HD_CSC_CTL_ENABLE BIT(0)
534 544
545#define VC4_HD_CSC_12_11 0x044
546#define VC4_HD_CSC_14_13 0x048
547#define VC4_HD_CSC_22_21 0x04c
548#define VC4_HD_CSC_24_23 0x050
549#define VC4_HD_CSC_32_31 0x054
550#define VC4_HD_CSC_34_33 0x058
551
535#define VC4_HD_FRAME_COUNT 0x068 552#define VC4_HD_FRAME_COUNT 0x068
536 553
537/* HVS display list information. */ 554/* HVS display list information. */
diff --git a/drivers/gpu/drm/vc4/vc4_render_cl.c b/drivers/gpu/drm/vc4/vc4_render_cl.c
index 0f12418725e5..08886a309757 100644
--- a/drivers/gpu/drm/vc4/vc4_render_cl.c
+++ b/drivers/gpu/drm/vc4/vc4_render_cl.c
@@ -45,6 +45,8 @@ struct vc4_rcl_setup {
45 45
46 struct drm_gem_cma_object *rcl; 46 struct drm_gem_cma_object *rcl;
47 u32 next_offset; 47 u32 next_offset;
48
49 u32 next_write_bo_index;
48}; 50};
49 51
50static inline void rcl_u8(struct vc4_rcl_setup *setup, u8 val) 52static inline void rcl_u8(struct vc4_rcl_setup *setup, u8 val)
@@ -407,6 +409,8 @@ static int vc4_rcl_msaa_surface_setup(struct vc4_exec_info *exec,
407 if (!*obj) 409 if (!*obj)
408 return -EINVAL; 410 return -EINVAL;
409 411
412 exec->rcl_write_bo[exec->rcl_write_bo_count++] = *obj;
413
410 if (surf->offset & 0xf) { 414 if (surf->offset & 0xf) {
411 DRM_ERROR("MSAA write must be 16b aligned.\n"); 415 DRM_ERROR("MSAA write must be 16b aligned.\n");
412 return -EINVAL; 416 return -EINVAL;
@@ -417,7 +421,8 @@ static int vc4_rcl_msaa_surface_setup(struct vc4_exec_info *exec,
417 421
418static int vc4_rcl_surface_setup(struct vc4_exec_info *exec, 422static int vc4_rcl_surface_setup(struct vc4_exec_info *exec,
419 struct drm_gem_cma_object **obj, 423 struct drm_gem_cma_object **obj,
420 struct drm_vc4_submit_rcl_surface *surf) 424 struct drm_vc4_submit_rcl_surface *surf,
425 bool is_write)
421{ 426{
422 uint8_t tiling = VC4_GET_FIELD(surf->bits, 427 uint8_t tiling = VC4_GET_FIELD(surf->bits,
423 VC4_LOADSTORE_TILE_BUFFER_TILING); 428 VC4_LOADSTORE_TILE_BUFFER_TILING);
@@ -440,6 +445,9 @@ static int vc4_rcl_surface_setup(struct vc4_exec_info *exec,
440 if (!*obj) 445 if (!*obj)
441 return -EINVAL; 446 return -EINVAL;
442 447
448 if (is_write)
449 exec->rcl_write_bo[exec->rcl_write_bo_count++] = *obj;
450
443 if (surf->flags & VC4_SUBMIT_RCL_SURFACE_READ_IS_FULL_RES) { 451 if (surf->flags & VC4_SUBMIT_RCL_SURFACE_READ_IS_FULL_RES) {
444 if (surf == &exec->args->zs_write) { 452 if (surf == &exec->args->zs_write) {
445 DRM_ERROR("general zs write may not be a full-res.\n"); 453 DRM_ERROR("general zs write may not be a full-res.\n");
@@ -542,6 +550,8 @@ vc4_rcl_render_config_surface_setup(struct vc4_exec_info *exec,
542 if (!*obj) 550 if (!*obj)
543 return -EINVAL; 551 return -EINVAL;
544 552
553 exec->rcl_write_bo[exec->rcl_write_bo_count++] = *obj;
554
545 if (tiling > VC4_TILING_FORMAT_LT) { 555 if (tiling > VC4_TILING_FORMAT_LT) {
546 DRM_ERROR("Bad tiling format\n"); 556 DRM_ERROR("Bad tiling format\n");
547 return -EINVAL; 557 return -EINVAL;
@@ -599,15 +609,18 @@ int vc4_get_rcl(struct drm_device *dev, struct vc4_exec_info *exec)
599 if (ret) 609 if (ret)
600 return ret; 610 return ret;
601 611
602 ret = vc4_rcl_surface_setup(exec, &setup.color_read, &args->color_read); 612 ret = vc4_rcl_surface_setup(exec, &setup.color_read, &args->color_read,
613 false);
603 if (ret) 614 if (ret)
604 return ret; 615 return ret;
605 616
606 ret = vc4_rcl_surface_setup(exec, &setup.zs_read, &args->zs_read); 617 ret = vc4_rcl_surface_setup(exec, &setup.zs_read, &args->zs_read,
618 false);
607 if (ret) 619 if (ret)
608 return ret; 620 return ret;
609 621
610 ret = vc4_rcl_surface_setup(exec, &setup.zs_write, &args->zs_write); 622 ret = vc4_rcl_surface_setup(exec, &setup.zs_write, &args->zs_write,
623 true);
611 if (ret) 624 if (ret)
612 return ret; 625 return ret;
613 626
diff --git a/drivers/gpu/drm/vc4/vc4_validate.c b/drivers/gpu/drm/vc4/vc4_validate.c
index 9ce1d0adf882..26503e307438 100644
--- a/drivers/gpu/drm/vc4/vc4_validate.c
+++ b/drivers/gpu/drm/vc4/vc4_validate.c
@@ -267,6 +267,9 @@ validate_indexed_prim_list(VALIDATE_ARGS)
267 if (!ib) 267 if (!ib)
268 return -EINVAL; 268 return -EINVAL;
269 269
270 exec->bin_dep_seqno = max(exec->bin_dep_seqno,
271 to_vc4_bo(&ib->base)->write_seqno);
272
270 if (offset > ib->base.size || 273 if (offset > ib->base.size ||
271 (ib->base.size - offset) / index_size < length) { 274 (ib->base.size - offset) / index_size < length) {
272 DRM_ERROR("IB access overflow (%d + %d*%d > %zd)\n", 275 DRM_ERROR("IB access overflow (%d + %d*%d > %zd)\n",
@@ -555,8 +558,7 @@ static bool
555reloc_tex(struct vc4_exec_info *exec, 558reloc_tex(struct vc4_exec_info *exec,
556 void *uniform_data_u, 559 void *uniform_data_u,
557 struct vc4_texture_sample_info *sample, 560 struct vc4_texture_sample_info *sample,
558 uint32_t texture_handle_index) 561 uint32_t texture_handle_index, bool is_cs)
559
560{ 562{
561 struct drm_gem_cma_object *tex; 563 struct drm_gem_cma_object *tex;
562 uint32_t p0 = *(uint32_t *)(uniform_data_u + sample->p_offset[0]); 564 uint32_t p0 = *(uint32_t *)(uniform_data_u + sample->p_offset[0]);
@@ -714,6 +716,11 @@ reloc_tex(struct vc4_exec_info *exec,
714 716
715 *validated_p0 = tex->paddr + p0; 717 *validated_p0 = tex->paddr + p0;
716 718
719 if (is_cs) {
720 exec->bin_dep_seqno = max(exec->bin_dep_seqno,
721 to_vc4_bo(&tex->base)->write_seqno);
722 }
723
717 return true; 724 return true;
718 fail: 725 fail:
719 DRM_INFO("Texture p0 at %d: 0x%08x\n", sample->p_offset[0], p0); 726 DRM_INFO("Texture p0 at %d: 0x%08x\n", sample->p_offset[0], p0);
@@ -835,7 +842,8 @@ validate_gl_shader_rec(struct drm_device *dev,
835 if (!reloc_tex(exec, 842 if (!reloc_tex(exec,
836 uniform_data_u, 843 uniform_data_u,
837 &validated_shader->texture_samples[tex], 844 &validated_shader->texture_samples[tex],
838 texture_handles_u[tex])) { 845 texture_handles_u[tex],
846 i == 2)) {
839 return -EINVAL; 847 return -EINVAL;
840 } 848 }
841 } 849 }
@@ -867,6 +875,9 @@ validate_gl_shader_rec(struct drm_device *dev,
867 uint32_t stride = *(uint8_t *)(pkt_u + o + 5); 875 uint32_t stride = *(uint8_t *)(pkt_u + o + 5);
868 uint32_t max_index; 876 uint32_t max_index;
869 877
878 exec->bin_dep_seqno = max(exec->bin_dep_seqno,
879 to_vc4_bo(&vbo->base)->write_seqno);
880
870 if (state->addr & 0x8) 881 if (state->addr & 0x8)
871 stride |= (*(uint32_t *)(pkt_u + 100 + i * 4)) & ~0xff; 882 stride |= (*(uint32_t *)(pkt_u + 100 + i * 4)) & ~0xff;
872 883