55
66#include <linux/clk.h>
77#include <linux/pm_runtime.h>
8+ #include <linux/soc/mediatek/mtk-cmdq.h>
89
910#include <asm/barrier.h>
1011#include <soc/mediatek/smi.h>
@@ -44,6 +45,11 @@ struct mtk_drm_crtc {
4445 bool pending_planes ;
4546 bool pending_async_planes ;
4647
48+ #if IS_REACHABLE (CONFIG_MTK_CMDQ )
49+ struct cmdq_client * cmdq_client ;
50+ u32 cmdq_event ;
51+ #endif
52+
4753 void __iomem * config_regs ;
4854 struct mtk_disp_mutex * mutex ;
4955 unsigned int ddp_comp_nr ;
@@ -234,6 +240,13 @@ struct mtk_ddp_comp *mtk_drm_ddp_comp_for_plane(struct drm_crtc *crtc,
234240 return NULL ;
235241}
236242
243+ #if IS_REACHABLE (CONFIG_MTK_CMDQ )
244+ static void ddp_cmdq_cb (struct cmdq_cb_data data )
245+ {
246+ cmdq_pkt_destroy (data .data );
247+ }
248+ #endif
249+
237250static int mtk_crtc_ddp_hw_init (struct mtk_drm_crtc * mtk_crtc )
238251{
239252 struct drm_crtc * crtc = & mtk_crtc -> base ;
@@ -367,7 +380,8 @@ static void mtk_crtc_ddp_hw_fini(struct mtk_drm_crtc *mtk_crtc)
367380 }
368381}
369382
370- static void mtk_crtc_ddp_config (struct drm_crtc * crtc )
383+ static void mtk_crtc_ddp_config (struct drm_crtc * crtc ,
384+ struct cmdq_pkt * cmdq_handle )
371385{
372386 struct mtk_drm_crtc * mtk_crtc = to_mtk_crtc (crtc );
373387 struct mtk_crtc_state * state = to_mtk_crtc_state (mtk_crtc -> base .state );
@@ -383,7 +397,8 @@ static void mtk_crtc_ddp_config(struct drm_crtc *crtc)
383397 if (state -> pending_config ) {
384398 mtk_ddp_comp_config (comp , state -> pending_width ,
385399 state -> pending_height ,
386- state -> pending_vrefresh , 0 , NULL );
400+ state -> pending_vrefresh , 0 ,
401+ cmdq_handle );
387402
388403 state -> pending_config = false;
389404 }
@@ -403,7 +418,8 @@ static void mtk_crtc_ddp_config(struct drm_crtc *crtc)
403418
404419 if (comp )
405420 mtk_ddp_comp_layer_config (comp , local_layer ,
406- plane_state , NULL );
421+ plane_state ,
422+ cmdq_handle );
407423 plane_state -> pending .config = false;
408424 }
409425 mtk_crtc -> pending_planes = false;
@@ -424,7 +440,8 @@ static void mtk_crtc_ddp_config(struct drm_crtc *crtc)
424440
425441 if (comp )
426442 mtk_ddp_comp_layer_config (comp , local_layer ,
427- plane_state , NULL );
443+ plane_state ,
444+ cmdq_handle );
428445 plane_state -> pending .async_config = false;
429446 }
430447 mtk_crtc -> pending_async_planes = false;
@@ -433,6 +450,9 @@ static void mtk_crtc_ddp_config(struct drm_crtc *crtc)
433450
434451static void mtk_drm_crtc_hw_config (struct mtk_drm_crtc * mtk_crtc )
435452{
453+ #if IS_REACHABLE (CONFIG_MTK_CMDQ )
454+ struct cmdq_pkt * cmdq_handle ;
455+ #endif
436456 struct drm_crtc * crtc = & mtk_crtc -> base ;
437457 struct mtk_drm_private * priv = crtc -> dev -> dev_private ;
438458 unsigned int pending_planes = 0 , pending_async_planes = 0 ;
@@ -461,9 +481,18 @@ static void mtk_drm_crtc_hw_config(struct mtk_drm_crtc *mtk_crtc)
461481
462482 if (priv -> data -> shadow_register ) {
463483 mtk_disp_mutex_acquire (mtk_crtc -> mutex );
464- mtk_crtc_ddp_config (crtc );
484+ mtk_crtc_ddp_config (crtc , NULL );
465485 mtk_disp_mutex_release (mtk_crtc -> mutex );
466486 }
487+ #if IS_REACHABLE (CONFIG_MTK_CMDQ )
488+ if (mtk_crtc -> cmdq_client ) {
489+ cmdq_handle = cmdq_pkt_create (mtk_crtc -> cmdq_client , PAGE_SIZE );
490+ cmdq_pkt_clear_event (cmdq_handle , mtk_crtc -> cmdq_event );
491+ cmdq_pkt_wfe (cmdq_handle , mtk_crtc -> cmdq_event );
492+ mtk_crtc_ddp_config (crtc , cmdq_handle );
493+ cmdq_pkt_flush_async (cmdq_handle , ddp_cmdq_cb , cmdq_handle );
494+ }
495+ #endif
467496 mutex_unlock (& mtk_crtc -> hw_lock );
468497}
469498
@@ -629,8 +658,12 @@ void mtk_crtc_ddp_irq(struct drm_crtc *crtc, struct mtk_ddp_comp *comp)
629658 struct mtk_drm_crtc * mtk_crtc = to_mtk_crtc (crtc );
630659 struct mtk_drm_private * priv = crtc -> dev -> dev_private ;
631660
661+ #if IS_REACHABLE (CONFIG_MTK_CMDQ )
662+ if (!priv -> data -> shadow_register && !mtk_crtc -> cmdq_client )
663+ #else
632664 if (!priv -> data -> shadow_register )
633- mtk_crtc_ddp_config (crtc );
665+ #endif
666+ mtk_crtc_ddp_config (crtc , NULL );
634667
635668 mtk_drm_finish_page_flip (mtk_crtc );
636669}
@@ -772,5 +805,21 @@ int mtk_drm_crtc_create(struct drm_device *drm_dev,
772805 priv -> num_pipes ++ ;
773806 mutex_init (& mtk_crtc -> hw_lock );
774807
808+ #if IS_REACHABLE (CONFIG_MTK_CMDQ )
809+ mtk_crtc -> cmdq_client =
810+ cmdq_mbox_create (dev , drm_crtc_index (& mtk_crtc -> base ),
811+ 2000 );
812+ if (IS_ERR (mtk_crtc -> cmdq_client )) {
813+ dev_dbg (dev , "mtk_crtc %d failed to create mailbox client, writing register by CPU now\n" ,
814+ drm_crtc_index (& mtk_crtc -> base ));
815+ mtk_crtc -> cmdq_client = NULL ;
816+ }
817+ ret = of_property_read_u32_index (dev -> of_node , "mediatek,gce-events" ,
818+ drm_crtc_index (& mtk_crtc -> base ),
819+ & mtk_crtc -> cmdq_event );
820+ if (ret )
821+ dev_dbg (dev , "mtk_crtc %d failed to get mediatek,gce-events property\n" ,
822+ drm_crtc_index (& mtk_crtc -> base ));
823+ #endif
775824 return 0 ;
776825}
0 commit comments