@@ -53,6 +53,7 @@ struct mtk_drm_crtc {
5353
5454#if IS_REACHABLE (CONFIG_MTK_CMDQ )
5555 struct cmdq_client cmdq_client ;
56+ struct cmdq_pkt cmdq_handle ;
5657 u32 cmdq_event ;
5758 u32 cmdq_vblank_cnt ;
5859#endif
@@ -107,12 +108,55 @@ static void mtk_drm_finish_page_flip(struct mtk_drm_crtc *mtk_crtc)
107108 }
108109}
109110
111+ #if IS_REACHABLE (CONFIG_MTK_CMDQ )
112+ static int mtk_drm_cmdq_pkt_create (struct cmdq_client * client , struct cmdq_pkt * pkt ,
113+ size_t size )
114+ {
115+ struct device * dev ;
116+ dma_addr_t dma_addr ;
117+
118+ pkt -> va_base = kzalloc (size , GFP_KERNEL );
119+ if (!pkt -> va_base ) {
120+ kfree (pkt );
121+ return - ENOMEM ;
122+ }
123+ pkt -> buf_size = size ;
124+ pkt -> cl = (void * )client ;
125+
126+ dev = client -> chan -> mbox -> dev ;
127+ dma_addr = dma_map_single (dev , pkt -> va_base , pkt -> buf_size ,
128+ DMA_TO_DEVICE );
129+ if (dma_mapping_error (dev , dma_addr )) {
130+ dev_err (dev , "dma map failed, size=%u\n" , (u32 )(u64 )size );
131+ kfree (pkt -> va_base );
132+ kfree (pkt );
133+ return - ENOMEM ;
134+ }
135+
136+ pkt -> pa_base = dma_addr ;
137+
138+ return 0 ;
139+ }
140+
141+ static void mtk_drm_cmdq_pkt_destroy (struct cmdq_pkt * pkt )
142+ {
143+ struct cmdq_client * client = (struct cmdq_client * )pkt -> cl ;
144+
145+ dma_unmap_single (client -> chan -> mbox -> dev , pkt -> pa_base , pkt -> buf_size ,
146+ DMA_TO_DEVICE );
147+ kfree (pkt -> va_base );
148+ kfree (pkt );
149+ }
150+ #endif
151+
110152static void mtk_drm_crtc_destroy (struct drm_crtc * crtc )
111153{
112154 struct mtk_drm_crtc * mtk_crtc = to_mtk_crtc (crtc );
113155
114156 mtk_mutex_put (mtk_crtc -> mutex );
115-
157+ #if IS_REACHABLE (CONFIG_MTK_CMDQ )
158+ mtk_drm_cmdq_pkt_destroy (& mtk_crtc -> cmdq_handle );
159+ #endif
116160 drm_crtc_cleanup (crtc );
117161}
118162
@@ -227,12 +271,10 @@ struct mtk_ddp_comp *mtk_drm_ddp_comp_for_plane(struct drm_crtc *crtc,
227271#if IS_REACHABLE (CONFIG_MTK_CMDQ )
228272static void ddp_cmdq_cb (struct mbox_client * cl , void * mssg )
229273{
230- struct cmdq_cb_data * data = mssg ;
231274 struct cmdq_client * cmdq_cl = container_of (cl , struct cmdq_client , client );
232275 struct mtk_drm_crtc * mtk_crtc = container_of (cmdq_cl , struct mtk_drm_crtc , cmdq_client );
233276
234277 mtk_crtc -> cmdq_vblank_cnt = 0 ;
235- cmdq_pkt_destroy (data -> pkt );
236278}
237279#endif
238280
@@ -438,7 +480,7 @@ static void mtk_drm_crtc_update_config(struct mtk_drm_crtc *mtk_crtc,
438480 bool needs_vblank )
439481{
440482#if IS_REACHABLE (CONFIG_MTK_CMDQ )
441- struct cmdq_pkt * cmdq_handle ;
483+ struct cmdq_pkt * cmdq_handle = & mtk_crtc -> cmdq_handle ;
442484#endif
443485 struct drm_crtc * crtc = & mtk_crtc -> base ;
444486 struct mtk_drm_private * priv = crtc -> dev -> dev_private ;
@@ -478,7 +520,7 @@ static void mtk_drm_crtc_update_config(struct mtk_drm_crtc *mtk_crtc,
478520#if IS_REACHABLE (CONFIG_MTK_CMDQ )
479521 if (mtk_crtc -> cmdq_client .chan ) {
480522 mbox_flush (mtk_crtc -> cmdq_client .chan , 2000 );
481- cmdq_handle = cmdq_pkt_create ( & mtk_crtc -> cmdq_client , PAGE_SIZE ) ;
523+ cmdq_handle -> cmd_buf_size = 0 ;
482524 cmdq_pkt_clear_event (cmdq_handle , mtk_crtc -> cmdq_event );
483525 cmdq_pkt_wfe (cmdq_handle , mtk_crtc -> cmdq_event , false);
484526 mtk_crtc_ddp_config (crtc , cmdq_handle );
@@ -877,6 +919,16 @@ int mtk_drm_crtc_create(struct drm_device *drm_dev,
877919 drm_crtc_index (& mtk_crtc -> base ));
878920 mbox_free_channel (mtk_crtc -> cmdq_client .chan );
879921 mtk_crtc -> cmdq_client .chan = NULL ;
922+ } else {
923+ ret = mtk_drm_cmdq_pkt_create (& mtk_crtc -> cmdq_client ,
924+ & mtk_crtc -> cmdq_handle ,
925+ PAGE_SIZE );
926+ if (ret ) {
927+ dev_dbg (dev , "mtk_crtc %d failed to create cmdq packet\n" ,
928+ drm_crtc_index (& mtk_crtc -> base ));
929+ mbox_free_channel (mtk_crtc -> cmdq_client .chan );
930+ mtk_crtc -> cmdq_client .chan = NULL ;
931+ }
880932 }
881933 }
882934#endif
0 commit comments