11// SPDX-License-Identifier: GPL-2.0-only
22/* Copyright (c) 2015-2018, The Linux Foundation. All rights reserved.
3+ * Copyright (c) 2022 Qualcomm Innovation Center, Inc. All rights reserved.
34 */
45
56#include <linux/delay.h>
2324#define CTL_SW_RESET 0x030
2425#define CTL_LAYER_EXTN_OFFSET 0x40
2526#define CTL_MERGE_3D_ACTIVE 0x0E4
27+ #define CTL_WB_ACTIVE 0x0EC
2628#define CTL_INTF_ACTIVE 0x0F4
2729#define CTL_MERGE_3D_FLUSH 0x100
2830#define CTL_DSC_ACTIVE 0x0E8
2931#define CTL_DSC_FLUSH 0x104
32+ #define CTL_WB_FLUSH 0x108
3033#define CTL_INTF_FLUSH 0x110
3134#define CTL_INTF_MASTER 0x134
3235#define CTL_FETCH_PIPE_ACTIVE 0x0FC
3841#define MERGE_3D_IDX 23
3942#define DSC_IDX 22
4043#define INTF_IDX 31
44+ #define WB_IDX 16
4145#define CTL_INVALID_BIT 0xffff
4246#define CTL_DEFAULT_GROUP_ID 0xf
4347
@@ -135,6 +139,9 @@ static inline void dpu_hw_ctl_trigger_flush_v1(struct dpu_hw_ctl *ctx)
135139 if (ctx -> pending_flush_mask & BIT (INTF_IDX ))
136140 DPU_REG_WRITE (& ctx -> hw , CTL_INTF_FLUSH ,
137141 ctx -> pending_intf_flush_mask );
142+ if (ctx -> pending_flush_mask & BIT (WB_IDX ))
143+ DPU_REG_WRITE (& ctx -> hw , CTL_WB_FLUSH ,
144+ ctx -> pending_wb_flush_mask );
138145
139146 DPU_REG_WRITE (& ctx -> hw , CTL_FLUSH , ctx -> pending_flush_mask );
140147}
@@ -255,6 +262,26 @@ static void dpu_hw_ctl_update_pending_flush_intf(struct dpu_hw_ctl *ctx,
255262 }
256263}
257264
265+ static void dpu_hw_ctl_update_pending_flush_wb (struct dpu_hw_ctl * ctx ,
266+ enum dpu_wb wb )
267+ {
268+ switch (wb ) {
269+ case WB_0 :
270+ case WB_1 :
271+ case WB_2 :
272+ ctx -> pending_flush_mask |= BIT (WB_IDX );
273+ default :
274+ break ;
275+ }
276+ }
277+
278+ static void dpu_hw_ctl_update_pending_flush_wb_v1 (struct dpu_hw_ctl * ctx ,
279+ enum dpu_wb wb )
280+ {
281+ ctx -> pending_wb_flush_mask |= BIT (wb - WB_0 );
282+ ctx -> pending_flush_mask |= BIT (WB_IDX );
283+ }
284+
258285static void dpu_hw_ctl_update_pending_flush_intf_v1 (struct dpu_hw_ctl * ctx ,
259286 enum dpu_intf intf )
260287{
@@ -504,6 +531,7 @@ static void dpu_hw_ctl_intf_cfg_v1(struct dpu_hw_ctl *ctx,
504531{
505532 struct dpu_hw_blk_reg_map * c = & ctx -> hw ;
506533 u32 intf_active = 0 ;
534+ u32 wb_active = 0 ;
507535 u32 mode_sel = 0 ;
508536
509537 /* CTL_TOP[31:28] carries group_id to collate CTL paths
@@ -520,10 +548,18 @@ static void dpu_hw_ctl_intf_cfg_v1(struct dpu_hw_ctl *ctx,
520548 mode_sel |= BIT (17 );
521549
522550 intf_active = DPU_REG_READ (c , CTL_INTF_ACTIVE );
523- intf_active |= BIT (cfg -> intf - INTF_0 );
551+ wb_active = DPU_REG_READ (c , CTL_WB_ACTIVE );
552+
553+ if (cfg -> intf )
554+ intf_active |= BIT (cfg -> intf - INTF_0 );
555+
556+ if (cfg -> wb )
557+ wb_active |= BIT (cfg -> wb - WB_0 );
524558
525559 DPU_REG_WRITE (c , CTL_TOP , mode_sel );
526560 DPU_REG_WRITE (c , CTL_INTF_ACTIVE , intf_active );
561+ DPU_REG_WRITE (c , CTL_WB_ACTIVE , wb_active );
562+
527563 if (cfg -> merge_3d )
528564 DPU_REG_WRITE (c , CTL_MERGE_3D_ACTIVE ,
529565 BIT (cfg -> merge_3d - MERGE_3D_0 ));
@@ -546,6 +582,9 @@ static void dpu_hw_ctl_intf_cfg(struct dpu_hw_ctl *ctx,
546582 intf_cfg |= (cfg -> mode_3d - 0x1 ) << 20 ;
547583 }
548584
585+ if (cfg -> wb )
586+ intf_cfg |= (cfg -> wb & 0x3 ) + 2 ;
587+
549588 switch (cfg -> intf_mode_sel ) {
550589 case DPU_CTL_MODE_SEL_VID :
551590 intf_cfg &= ~BIT (17 );
@@ -568,12 +607,13 @@ static void dpu_hw_ctl_reset_intf_cfg_v1(struct dpu_hw_ctl *ctx,
568607{
569608 struct dpu_hw_blk_reg_map * c = & ctx -> hw ;
570609 u32 intf_active = 0 ;
610+ u32 wb_active = 0 ;
571611 u32 merge3d_active = 0 ;
572612
573613 /*
574614 * This API resets each portion of the CTL path namely,
575615 * clearing the sspps staged on the lm, merge_3d block,
576- * interfaces etc to ensure clean teardown of the pipeline.
616+ * interfaces , writeback etc to ensure clean teardown of the pipeline.
577617 * This will be used for writeback to begin with to have a
578618 * proper teardown of the writeback session but upon further
579619 * validation, this can be extended to all interfaces.
@@ -592,6 +632,12 @@ static void dpu_hw_ctl_reset_intf_cfg_v1(struct dpu_hw_ctl *ctx,
592632 intf_active &= ~BIT (cfg -> intf - INTF_0 );
593633 DPU_REG_WRITE (c , CTL_INTF_ACTIVE , intf_active );
594634 }
635+
636+ if (cfg -> wb ) {
637+ wb_active = DPU_REG_READ (c , CTL_WB_ACTIVE );
638+ wb_active &= ~BIT (cfg -> wb - WB_0 );
639+ DPU_REG_WRITE (c , CTL_WB_ACTIVE , wb_active );
640+ }
595641}
596642
597643static void dpu_hw_ctl_set_fetch_pipe_active (struct dpu_hw_ctl * ctx ,
@@ -622,11 +668,13 @@ static void _setup_ctl_ops(struct dpu_hw_ctl_ops *ops,
622668 dpu_hw_ctl_update_pending_flush_intf_v1 ;
623669 ops -> update_pending_flush_merge_3d =
624670 dpu_hw_ctl_update_pending_flush_merge_3d_v1 ;
671+ ops -> update_pending_flush_wb = dpu_hw_ctl_update_pending_flush_wb_v1 ;
625672 } else {
626673 ops -> trigger_flush = dpu_hw_ctl_trigger_flush ;
627674 ops -> setup_intf_cfg = dpu_hw_ctl_intf_cfg ;
628675 ops -> update_pending_flush_intf =
629676 dpu_hw_ctl_update_pending_flush_intf ;
677+ ops -> update_pending_flush_wb = dpu_hw_ctl_update_pending_flush_wb ;
630678 }
631679 ops -> clear_pending_flush = dpu_hw_ctl_clear_pending_flush ;
632680 ops -> update_pending_flush = dpu_hw_ctl_update_pending_flush ;
0 commit comments