@@ -413,6 +413,246 @@ static int sti_hqvdp_get_curr_cmd(struct sti_hqvdp *hqvdp)
413
413
return -1 ;
414
414
}
415
415
416
+ /**
417
+ * sti_hqvdp_get_next_cmd
418
+ * @hqvdp: hqvdp structure
419
+ *
420
+ * Look for the next hqvdp_cmd that will be used by the FW.
421
+ *
422
+ * RETURNS:
423
+ * the offset of the next command that will be used.
424
+ * -1 in error cases
425
+ */
426
+ static int sti_hqvdp_get_next_cmd (struct sti_hqvdp * hqvdp )
427
+ {
428
+ int next_cmd ;
429
+ dma_addr_t cmd = hqvdp -> hqvdp_cmd_paddr ;
430
+ unsigned int i ;
431
+
432
+ next_cmd = readl (hqvdp -> regs + HQVDP_MBX_NEXT_CMD );
433
+
434
+ for (i = 0 ; i < NB_VDP_CMD ; i ++ ) {
435
+ if (cmd == next_cmd )
436
+ return i * sizeof (struct sti_hqvdp_cmd );
437
+
438
+ cmd += sizeof (struct sti_hqvdp_cmd );
439
+ }
440
+
441
+ return -1 ;
442
+ }
443
+
444
+ #define DBGFS_DUMP (reg ) seq_printf(s, "\n %-25s 0x%08X", #reg, \
445
+ readl(hqvdp->regs + reg))
446
+
447
+ static const char * hqvdp_dbg_get_lut (u32 * coef )
448
+ {
449
+ if (!memcmp (coef , coef_lut_a_legacy , 16 ))
450
+ return "LUT A" ;
451
+ if (!memcmp (coef , coef_lut_b , 16 ))
452
+ return "LUT B" ;
453
+ if (!memcmp (coef , coef_lut_c_y_legacy , 16 ))
454
+ return "LUT C Y" ;
455
+ if (!memcmp (coef , coef_lut_c_c_legacy , 16 ))
456
+ return "LUT C C" ;
457
+ if (!memcmp (coef , coef_lut_d_y_legacy , 16 ))
458
+ return "LUT D Y" ;
459
+ if (!memcmp (coef , coef_lut_d_c_legacy , 16 ))
460
+ return "LUT D C" ;
461
+ if (!memcmp (coef , coef_lut_e_y_legacy , 16 ))
462
+ return "LUT E Y" ;
463
+ if (!memcmp (coef , coef_lut_e_c_legacy , 16 ))
464
+ return "LUT E C" ;
465
+ if (!memcmp (coef , coef_lut_f_y_legacy , 16 ))
466
+ return "LUT F Y" ;
467
+ if (!memcmp (coef , coef_lut_f_c_legacy , 16 ))
468
+ return "LUT F C" ;
469
+ return "<UNKNOWN>" ;
470
+ }
471
+
472
+ static void hqvdp_dbg_dump_cmd (struct seq_file * s , struct sti_hqvdp_cmd * c )
473
+ {
474
+ int src_w , src_h , dst_w , dst_h ;
475
+
476
+ seq_puts (s , "\n\tTOP:" );
477
+ seq_printf (s , "\n\t %-20s 0x%08X" , "Config" , c -> top .config );
478
+ switch (c -> top .config ) {
479
+ case TOP_CONFIG_PROGRESSIVE :
480
+ seq_puts (s , "\tProgressive" );
481
+ break ;
482
+ case TOP_CONFIG_INTER_TOP :
483
+ seq_puts (s , "\tInterlaced, top field" );
484
+ break ;
485
+ case TOP_CONFIG_INTER_BTM :
486
+ seq_puts (s , "\tInterlaced, bottom field" );
487
+ break ;
488
+ default :
489
+ seq_puts (s , "\t<UNKNOWN>" );
490
+ break ;
491
+ }
492
+
493
+ seq_printf (s , "\n\t %-20s 0x%08X" , "MemFormat" , c -> top .mem_format );
494
+ seq_printf (s , "\n\t %-20s 0x%08X" , "CurrentY" , c -> top .current_luma );
495
+ seq_printf (s , "\n\t %-20s 0x%08X" , "CurrentC" , c -> top .current_chroma );
496
+ seq_printf (s , "\n\t %-20s 0x%08X" , "YSrcPitch" , c -> top .luma_src_pitch );
497
+ seq_printf (s , "\n\t %-20s 0x%08X" , "CSrcPitch" ,
498
+ c -> top .chroma_src_pitch );
499
+ seq_printf (s , "\n\t %-20s 0x%08X" , "InputFrameSize" ,
500
+ c -> top .input_frame_size );
501
+ seq_printf (s , "\t%dx%d" ,
502
+ c -> top .input_frame_size & 0x0000FFFF ,
503
+ c -> top .input_frame_size >> 16 );
504
+ seq_printf (s , "\n\t %-20s 0x%08X" , "InputViewportSize" ,
505
+ c -> top .input_viewport_size );
506
+ src_w = c -> top .input_viewport_size & 0x0000FFFF ;
507
+ src_h = c -> top .input_viewport_size >> 16 ;
508
+ seq_printf (s , "\t%dx%d" , src_w , src_h );
509
+
510
+ seq_puts (s , "\n\tHVSRC:" );
511
+ seq_printf (s , "\n\t %-20s 0x%08X" , "OutputPictureSize" ,
512
+ c -> hvsrc .output_picture_size );
513
+ dst_w = c -> hvsrc .output_picture_size & 0x0000FFFF ;
514
+ dst_h = c -> hvsrc .output_picture_size >> 16 ;
515
+ seq_printf (s , "\t%dx%d" , dst_w , dst_h );
516
+ seq_printf (s , "\n\t %-20s 0x%08X" , "ParamCtrl" , c -> hvsrc .param_ctrl );
517
+
518
+ seq_printf (s , "\n\t %-20s %s" , "yh_coef" ,
519
+ hqvdp_dbg_get_lut (c -> hvsrc .yh_coef ));
520
+ seq_printf (s , "\n\t %-20s %s" , "ch_coef" ,
521
+ hqvdp_dbg_get_lut (c -> hvsrc .ch_coef ));
522
+ seq_printf (s , "\n\t %-20s %s" , "yv_coef" ,
523
+ hqvdp_dbg_get_lut (c -> hvsrc .yv_coef ));
524
+ seq_printf (s , "\n\t %-20s %s" , "cv_coef" ,
525
+ hqvdp_dbg_get_lut (c -> hvsrc .cv_coef ));
526
+
527
+ seq_printf (s , "\n\t %-20s" , "ScaleH" );
528
+ if (dst_w > src_w )
529
+ seq_printf (s , " %d/1" , dst_w / src_w );
530
+ else
531
+ seq_printf (s , " 1/%d" , src_w / dst_w );
532
+
533
+ seq_printf (s , "\n\t %-20s" , "tScaleV" );
534
+ if (dst_h > src_h )
535
+ seq_printf (s , " %d/1" , dst_h / src_h );
536
+ else
537
+ seq_printf (s , " 1/%d" , src_h / dst_h );
538
+
539
+ seq_puts (s , "\n\tCSDI:" );
540
+ seq_printf (s , "\n\t %-20s 0x%08X\t" , "Config" , c -> csdi .config );
541
+ switch (c -> csdi .config ) {
542
+ case CSDI_CONFIG_PROG :
543
+ seq_puts (s , "Bypass" );
544
+ break ;
545
+ case CSDI_CONFIG_INTER_DIR :
546
+ seq_puts (s , "Deinterlace, directional" );
547
+ break ;
548
+ default :
549
+ seq_puts (s , "<UNKNOWN>" );
550
+ break ;
551
+ }
552
+
553
+ seq_printf (s , "\n\t %-20s 0x%08X" , "Config2" , c -> csdi .config2 );
554
+ seq_printf (s , "\n\t %-20s 0x%08X" , "DcdiConfig" , c -> csdi .dcdi_config );
555
+ }
556
+
557
+ static int hqvdp_dbg_show (struct seq_file * s , void * data )
558
+ {
559
+ struct drm_info_node * node = s -> private ;
560
+ struct sti_hqvdp * hqvdp = (struct sti_hqvdp * )node -> info_ent -> data ;
561
+ struct drm_device * dev = node -> minor -> dev ;
562
+ int cmd , cmd_offset , infoxp70 ;
563
+ void * virt ;
564
+ int ret ;
565
+
566
+ ret = mutex_lock_interruptible (& dev -> struct_mutex );
567
+ if (ret )
568
+ return ret ;
569
+
570
+ seq_printf (s , "%s: (vaddr = 0x%p)" ,
571
+ sti_plane_to_str (& hqvdp -> plane ), hqvdp -> regs );
572
+
573
+ DBGFS_DUMP (HQVDP_MBX_IRQ_TO_XP70 );
574
+ DBGFS_DUMP (HQVDP_MBX_INFO_HOST );
575
+ DBGFS_DUMP (HQVDP_MBX_IRQ_TO_HOST );
576
+ DBGFS_DUMP (HQVDP_MBX_INFO_XP70 );
577
+ infoxp70 = readl (hqvdp -> regs + HQVDP_MBX_INFO_XP70 );
578
+ seq_puts (s , "\tFirmware state: " );
579
+ if (infoxp70 & INFO_XP70_FW_READY )
580
+ seq_puts (s , "idle and ready" );
581
+ else if (infoxp70 & INFO_XP70_FW_PROCESSING )
582
+ seq_puts (s , "processing a picture" );
583
+ else if (infoxp70 & INFO_XP70_FW_INITQUEUES )
584
+ seq_puts (s , "programming queues" );
585
+ else
586
+ seq_puts (s , "NOT READY" );
587
+
588
+ DBGFS_DUMP (HQVDP_MBX_SW_RESET_CTRL );
589
+ DBGFS_DUMP (HQVDP_MBX_STARTUP_CTRL1 );
590
+ if (readl (hqvdp -> regs + HQVDP_MBX_STARTUP_CTRL1 )
591
+ & STARTUP_CTRL1_RST_DONE )
592
+ seq_puts (s , "\tReset is done" );
593
+ else
594
+ seq_puts (s , "\tReset is NOT done" );
595
+ DBGFS_DUMP (HQVDP_MBX_STARTUP_CTRL2 );
596
+ if (readl (hqvdp -> regs + HQVDP_MBX_STARTUP_CTRL2 )
597
+ & STARTUP_CTRL2_FETCH_EN )
598
+ seq_puts (s , "\tFetch is enabled" );
599
+ else
600
+ seq_puts (s , "\tFetch is NOT enabled" );
601
+ DBGFS_DUMP (HQVDP_MBX_GP_STATUS );
602
+ DBGFS_DUMP (HQVDP_MBX_NEXT_CMD );
603
+ DBGFS_DUMP (HQVDP_MBX_CURRENT_CMD );
604
+ DBGFS_DUMP (HQVDP_MBX_SOFT_VSYNC );
605
+ if (!(readl (hqvdp -> regs + HQVDP_MBX_SOFT_VSYNC ) & 3 ))
606
+ seq_puts (s , "\tHW Vsync" );
607
+ else
608
+ seq_puts (s , "\tSW Vsync ?!?!" );
609
+
610
+ /* Last command */
611
+ cmd = readl (hqvdp -> regs + HQVDP_MBX_CURRENT_CMD );
612
+ cmd_offset = sti_hqvdp_get_curr_cmd (hqvdp );
613
+ if (cmd_offset == -1 ) {
614
+ seq_puts (s , "\n\n Last command: unknown" );
615
+ } else {
616
+ virt = hqvdp -> hqvdp_cmd + cmd_offset ;
617
+ seq_printf (s , "\n\n Last command: address @ 0x%x (0x%p)" ,
618
+ cmd , virt );
619
+ hqvdp_dbg_dump_cmd (s , (struct sti_hqvdp_cmd * )virt );
620
+ }
621
+
622
+ /* Next command */
623
+ cmd = readl (hqvdp -> regs + HQVDP_MBX_NEXT_CMD );
624
+ cmd_offset = sti_hqvdp_get_next_cmd (hqvdp );
625
+ if (cmd_offset == -1 ) {
626
+ seq_puts (s , "\n\n Next command: unknown" );
627
+ } else {
628
+ virt = hqvdp -> hqvdp_cmd + cmd_offset ;
629
+ seq_printf (s , "\n\n Next command address: @ 0x%x (0x%p)" ,
630
+ cmd , virt );
631
+ hqvdp_dbg_dump_cmd (s , (struct sti_hqvdp_cmd * )virt );
632
+ }
633
+
634
+ seq_puts (s , "\n" );
635
+
636
+ mutex_unlock (& dev -> struct_mutex );
637
+ return 0 ;
638
+ }
639
+
640
+ static struct drm_info_list hqvdp_debugfs_files [] = {
641
+ { "hqvdp" , hqvdp_dbg_show , 0 , NULL },
642
+ };
643
+
644
+ static int hqvdp_debugfs_init (struct sti_hqvdp * hqvdp , struct drm_minor * minor )
645
+ {
646
+ unsigned int i ;
647
+
648
+ for (i = 0 ; i < ARRAY_SIZE (hqvdp_debugfs_files ); i ++ )
649
+ hqvdp_debugfs_files [i ].data = hqvdp ;
650
+
651
+ return drm_debugfs_create_files (hqvdp_debugfs_files ,
652
+ ARRAY_SIZE (hqvdp_debugfs_files ),
653
+ minor -> debugfs_root , minor );
654
+ }
655
+
416
656
/**
417
657
* sti_hqvdp_update_hvsrc
418
658
* @orient: horizontal or vertical
@@ -1026,6 +1266,9 @@ static struct drm_plane *sti_hqvdp_create(struct drm_device *drm_dev,
1026
1266
1027
1267
sti_plane_init_property (& hqvdp -> plane , DRM_PLANE_TYPE_OVERLAY );
1028
1268
1269
+ if (hqvdp_debugfs_init (hqvdp , drm_dev -> primary ))
1270
+ DRM_ERROR ("HQVDP debugfs setup failed\n" );
1271
+
1029
1272
return & hqvdp -> plane .drm_plane ;
1030
1273
}
1031
1274
0 commit comments