197fb5e8dSThomas Gleixner // SPDX-License-Identifier: GPL-2.0-only 225fdd593SJeykumar Sankaran /* Copyright (c) 2015-2018, The Linux Foundation. All rights reserved. 36d084806SAbhinav Kumar * Copyright (c) 2022 Qualcomm Innovation Center, Inc. All rights reserved. 425fdd593SJeykumar Sankaran */ 525fdd593SJeykumar Sankaran 625fdd593SJeykumar Sankaran #include <linux/delay.h> 725fdd593SJeykumar Sankaran #include "dpu_hwio.h" 825fdd593SJeykumar Sankaran #include "dpu_hw_ctl.h" 925fdd593SJeykumar Sankaran #include "dpu_kms.h" 10812eeeb6SSean Paul #include "dpu_trace.h" 1125fdd593SJeykumar Sankaran 1225fdd593SJeykumar Sankaran #define CTL_LAYER(lm) \ 1325fdd593SJeykumar Sankaran (((lm) == LM_5) ? (0x024) : (((lm) - LM_0) * 0x004)) 1425fdd593SJeykumar Sankaran #define CTL_LAYER_EXT(lm) \ 1525fdd593SJeykumar Sankaran (0x40 + (((lm) - LM_0) * 0x004)) 1625fdd593SJeykumar Sankaran #define CTL_LAYER_EXT2(lm) \ 1725fdd593SJeykumar Sankaran (0x70 + (((lm) - LM_0) * 0x004)) 1825fdd593SJeykumar Sankaran #define CTL_LAYER_EXT3(lm) \ 1925fdd593SJeykumar Sankaran (0xA0 + (((lm) - LM_0) * 0x004)) 20e92a4ae1SDmitry Baryshkov #define CTL_LAYER_EXT4(lm) \ 21e92a4ae1SDmitry Baryshkov (0xB8 + (((lm) - LM_0) * 0x004)) 2225fdd593SJeykumar Sankaran #define CTL_TOP 0x014 2325fdd593SJeykumar Sankaran #define CTL_FLUSH 0x018 2425fdd593SJeykumar Sankaran #define CTL_START 0x01C 2525fdd593SJeykumar Sankaran #define CTL_PREPARE 0x0d0 2625fdd593SJeykumar Sankaran #define CTL_SW_RESET 0x030 2725fdd593SJeykumar Sankaran #define CTL_LAYER_EXTN_OFFSET 0x40 28c40e6c67SDmitry Baryshkov #define CTL_MERGE_3D_ACTIVE 0x0E4 29*83a58b20SKalyan Thota #define CTL_DSC_ACTIVE 0x0E8 306d084806SAbhinav Kumar #define CTL_WB_ACTIVE 0x0EC 3173bfb790SKalyan Thota #define CTL_INTF_ACTIVE 0x0F4 32*83a58b20SKalyan Thota #define CTL_FETCH_PIPE_ACTIVE 0x0FC 33c40e6c67SDmitry Baryshkov #define CTL_MERGE_3D_FLUSH 0x100 3477f6da90SVinod Koul #define CTL_DSC_FLUSH 0x104 356d084806SAbhinav Kumar #define CTL_WB_FLUSH 0x108 3673bfb790SKalyan Thota #define CTL_INTF_FLUSH 0x110 3773bfb790SKalyan Thota #define CTL_INTF_MASTER 0x134 38*83a58b20SKalyan Thota #define CTL_DSPP_n_FLUSH(n) ((0x13C) + ((n) * 4)) 3925fdd593SJeykumar Sankaran 4025fdd593SJeykumar Sankaran #define CTL_MIXER_BORDER_OUT BIT(24) 4125fdd593SJeykumar Sankaran #define CTL_FLUSH_MASK_CTL BIT(17) 4225fdd593SJeykumar Sankaran 4325fdd593SJeykumar Sankaran #define DPU_REG_RESET_TIMEOUT_US 2000 44c40e6c67SDmitry Baryshkov #define MERGE_3D_IDX 23 4577f6da90SVinod Koul #define DSC_IDX 22 4673bfb790SKalyan Thota #define INTF_IDX 31 476d084806SAbhinav Kumar #define WB_IDX 16 48*83a58b20SKalyan Thota #define DSPP_IDX 29 /* From DPU hw rev 7.x.x */ 49b3652e87SKrishna Manikandan #define CTL_INVALID_BIT 0xffff 5044bf8704SKalyan Thota #define CTL_DEFAULT_GROUP_ID 0xf 51b3652e87SKrishna Manikandan 52b3652e87SKrishna Manikandan static const u32 fetch_tbl[SSPP_MAX] = {CTL_INVALID_BIT, 16, 17, 18, 19, 53b3652e87SKrishna Manikandan CTL_INVALID_BIT, CTL_INVALID_BIT, CTL_INVALID_BIT, CTL_INVALID_BIT, 0, 54b3652e87SKrishna Manikandan 1, 2, 3, CTL_INVALID_BIT, CTL_INVALID_BIT}; 5525fdd593SJeykumar Sankaran 56abda0d92SStephen Boyd static const struct dpu_ctl_cfg *_ctl_offset(enum dpu_ctl ctl, 57abda0d92SStephen Boyd const struct dpu_mdss_cfg *m, 5825fdd593SJeykumar Sankaran void __iomem *addr, 5925fdd593SJeykumar Sankaran struct dpu_hw_blk_reg_map *b) 6025fdd593SJeykumar Sankaran { 6125fdd593SJeykumar Sankaran int i; 6225fdd593SJeykumar Sankaran 6325fdd593SJeykumar Sankaran for (i = 0; i < m->ctl_count; i++) { 6425fdd593SJeykumar Sankaran if (ctl == m->ctl[i].id) { 659403f9a4SDmitry Baryshkov b->blk_addr = addr + m->ctl[i].base; 6625fdd593SJeykumar Sankaran b->log_mask = DPU_DBG_MASK_CTL; 6725fdd593SJeykumar Sankaran return &m->ctl[i]; 6825fdd593SJeykumar Sankaran } 6925fdd593SJeykumar Sankaran } 7025fdd593SJeykumar Sankaran return ERR_PTR(-ENOMEM); 7125fdd593SJeykumar Sankaran } 7225fdd593SJeykumar Sankaran 7325fdd593SJeykumar Sankaran static int _mixer_stages(const struct dpu_lm_cfg *mixer, int count, 7425fdd593SJeykumar Sankaran enum dpu_lm lm) 7525fdd593SJeykumar Sankaran { 7625fdd593SJeykumar Sankaran int i; 7725fdd593SJeykumar Sankaran int stages = -EINVAL; 7825fdd593SJeykumar Sankaran 7925fdd593SJeykumar Sankaran for (i = 0; i < count; i++) { 8025fdd593SJeykumar Sankaran if (lm == mixer[i].id) { 8125fdd593SJeykumar Sankaran stages = mixer[i].sblk->maxblendstages; 8225fdd593SJeykumar Sankaran break; 8325fdd593SJeykumar Sankaran } 8425fdd593SJeykumar Sankaran } 8525fdd593SJeykumar Sankaran 8625fdd593SJeykumar Sankaran return stages; 8725fdd593SJeykumar Sankaran } 8825fdd593SJeykumar Sankaran 89812eeeb6SSean Paul static inline u32 dpu_hw_ctl_get_flush_register(struct dpu_hw_ctl *ctx) 90812eeeb6SSean Paul { 91812eeeb6SSean Paul struct dpu_hw_blk_reg_map *c = &ctx->hw; 92812eeeb6SSean Paul 93812eeeb6SSean Paul return DPU_REG_READ(c, CTL_FLUSH); 94812eeeb6SSean Paul } 95812eeeb6SSean Paul 9625fdd593SJeykumar Sankaran static inline void dpu_hw_ctl_trigger_start(struct dpu_hw_ctl *ctx) 9725fdd593SJeykumar Sankaran { 98812eeeb6SSean Paul trace_dpu_hw_ctl_trigger_start(ctx->pending_flush_mask, 99812eeeb6SSean Paul dpu_hw_ctl_get_flush_register(ctx)); 10025fdd593SJeykumar Sankaran DPU_REG_WRITE(&ctx->hw, CTL_START, 0x1); 10125fdd593SJeykumar Sankaran } 10225fdd593SJeykumar Sankaran 10378706798SAngeloGioacchino Del Regno static inline bool dpu_hw_ctl_is_started(struct dpu_hw_ctl *ctx) 10478706798SAngeloGioacchino Del Regno { 10578706798SAngeloGioacchino Del Regno return !!(DPU_REG_READ(&ctx->hw, CTL_START) & BIT(0)); 10678706798SAngeloGioacchino Del Regno } 10778706798SAngeloGioacchino Del Regno 10825fdd593SJeykumar Sankaran static inline void dpu_hw_ctl_trigger_pending(struct dpu_hw_ctl *ctx) 10925fdd593SJeykumar Sankaran { 110812eeeb6SSean Paul trace_dpu_hw_ctl_trigger_prepare(ctx->pending_flush_mask, 111812eeeb6SSean Paul dpu_hw_ctl_get_flush_register(ctx)); 11225fdd593SJeykumar Sankaran DPU_REG_WRITE(&ctx->hw, CTL_PREPARE, 0x1); 11325fdd593SJeykumar Sankaran } 11425fdd593SJeykumar Sankaran 11525fdd593SJeykumar Sankaran static inline void dpu_hw_ctl_clear_pending_flush(struct dpu_hw_ctl *ctx) 11625fdd593SJeykumar Sankaran { 117812eeeb6SSean Paul trace_dpu_hw_ctl_clear_pending_flush(ctx->pending_flush_mask, 118812eeeb6SSean Paul dpu_hw_ctl_get_flush_register(ctx)); 11925fdd593SJeykumar Sankaran ctx->pending_flush_mask = 0x0; 120*83a58b20SKalyan Thota 121*83a58b20SKalyan Thota memset(ctx->pending_dspp_flush_mask, 0, 122*83a58b20SKalyan Thota sizeof(ctx->pending_dspp_flush_mask)); 12325fdd593SJeykumar Sankaran } 12425fdd593SJeykumar Sankaran 12525fdd593SJeykumar Sankaran static inline void dpu_hw_ctl_update_pending_flush(struct dpu_hw_ctl *ctx, 12625fdd593SJeykumar Sankaran u32 flushbits) 12725fdd593SJeykumar Sankaran { 128812eeeb6SSean Paul trace_dpu_hw_ctl_update_pending_flush(flushbits, 129812eeeb6SSean Paul ctx->pending_flush_mask); 13025fdd593SJeykumar Sankaran ctx->pending_flush_mask |= flushbits; 13125fdd593SJeykumar Sankaran } 13225fdd593SJeykumar Sankaran 13325fdd593SJeykumar Sankaran static u32 dpu_hw_ctl_get_pending_flush(struct dpu_hw_ctl *ctx) 13425fdd593SJeykumar Sankaran { 13525fdd593SJeykumar Sankaran return ctx->pending_flush_mask; 13625fdd593SJeykumar Sankaran } 13725fdd593SJeykumar Sankaran 13873bfb790SKalyan Thota static inline void dpu_hw_ctl_trigger_flush_v1(struct dpu_hw_ctl *ctx) 13973bfb790SKalyan Thota { 140*83a58b20SKalyan Thota int dspp; 141*83a58b20SKalyan Thota 142c40e6c67SDmitry Baryshkov if (ctx->pending_flush_mask & BIT(MERGE_3D_IDX)) 143c40e6c67SDmitry Baryshkov DPU_REG_WRITE(&ctx->hw, CTL_MERGE_3D_FLUSH, 144c40e6c67SDmitry Baryshkov ctx->pending_merge_3d_flush_mask); 14573bfb790SKalyan Thota if (ctx->pending_flush_mask & BIT(INTF_IDX)) 14673bfb790SKalyan Thota DPU_REG_WRITE(&ctx->hw, CTL_INTF_FLUSH, 14773bfb790SKalyan Thota ctx->pending_intf_flush_mask); 1486d084806SAbhinav Kumar if (ctx->pending_flush_mask & BIT(WB_IDX)) 1496d084806SAbhinav Kumar DPU_REG_WRITE(&ctx->hw, CTL_WB_FLUSH, 1506d084806SAbhinav Kumar ctx->pending_wb_flush_mask); 15173bfb790SKalyan Thota 152*83a58b20SKalyan Thota if (ctx->pending_flush_mask & BIT(DSPP_IDX)) 153*83a58b20SKalyan Thota for (dspp = DSPP_0; dspp < DSPP_MAX; dspp++) { 154*83a58b20SKalyan Thota if (ctx->pending_dspp_flush_mask[dspp - DSPP_0]) 155*83a58b20SKalyan Thota DPU_REG_WRITE(&ctx->hw, 156*83a58b20SKalyan Thota CTL_DSPP_n_FLUSH(dspp - DSPP_0), 157*83a58b20SKalyan Thota ctx->pending_dspp_flush_mask[dspp - DSPP_0]); 158*83a58b20SKalyan Thota } 15973bfb790SKalyan Thota DPU_REG_WRITE(&ctx->hw, CTL_FLUSH, ctx->pending_flush_mask); 16073bfb790SKalyan Thota } 16173bfb790SKalyan Thota 16225fdd593SJeykumar Sankaran static inline void dpu_hw_ctl_trigger_flush(struct dpu_hw_ctl *ctx) 16325fdd593SJeykumar Sankaran { 164812eeeb6SSean Paul trace_dpu_hw_ctl_trigger_pending_flush(ctx->pending_flush_mask, 165812eeeb6SSean Paul dpu_hw_ctl_get_flush_register(ctx)); 16625fdd593SJeykumar Sankaran DPU_REG_WRITE(&ctx->hw, CTL_FLUSH, ctx->pending_flush_mask); 16725fdd593SJeykumar Sankaran } 16825fdd593SJeykumar Sankaran 1693cde792aSDmitry Baryshkov static void dpu_hw_ctl_update_pending_flush_sspp(struct dpu_hw_ctl *ctx, 17025fdd593SJeykumar Sankaran enum dpu_sspp sspp) 17125fdd593SJeykumar Sankaran { 17225fdd593SJeykumar Sankaran switch (sspp) { 17325fdd593SJeykumar Sankaran case SSPP_VIG0: 1743cde792aSDmitry Baryshkov ctx->pending_flush_mask |= BIT(0); 17525fdd593SJeykumar Sankaran break; 17625fdd593SJeykumar Sankaran case SSPP_VIG1: 1773cde792aSDmitry Baryshkov ctx->pending_flush_mask |= BIT(1); 17825fdd593SJeykumar Sankaran break; 17925fdd593SJeykumar Sankaran case SSPP_VIG2: 1803cde792aSDmitry Baryshkov ctx->pending_flush_mask |= BIT(2); 18125fdd593SJeykumar Sankaran break; 18225fdd593SJeykumar Sankaran case SSPP_VIG3: 1833cde792aSDmitry Baryshkov ctx->pending_flush_mask |= BIT(18); 18425fdd593SJeykumar Sankaran break; 18525fdd593SJeykumar Sankaran case SSPP_RGB0: 1863cde792aSDmitry Baryshkov ctx->pending_flush_mask |= BIT(3); 18725fdd593SJeykumar Sankaran break; 18825fdd593SJeykumar Sankaran case SSPP_RGB1: 1893cde792aSDmitry Baryshkov ctx->pending_flush_mask |= BIT(4); 19025fdd593SJeykumar Sankaran break; 19125fdd593SJeykumar Sankaran case SSPP_RGB2: 1923cde792aSDmitry Baryshkov ctx->pending_flush_mask |= BIT(5); 19325fdd593SJeykumar Sankaran break; 19425fdd593SJeykumar Sankaran case SSPP_RGB3: 1953cde792aSDmitry Baryshkov ctx->pending_flush_mask |= BIT(19); 19625fdd593SJeykumar Sankaran break; 19725fdd593SJeykumar Sankaran case SSPP_DMA0: 1983cde792aSDmitry Baryshkov ctx->pending_flush_mask |= BIT(11); 19925fdd593SJeykumar Sankaran break; 20025fdd593SJeykumar Sankaran case SSPP_DMA1: 2013cde792aSDmitry Baryshkov ctx->pending_flush_mask |= BIT(12); 20225fdd593SJeykumar Sankaran break; 20325fdd593SJeykumar Sankaran case SSPP_DMA2: 2043cde792aSDmitry Baryshkov ctx->pending_flush_mask |= BIT(24); 20525fdd593SJeykumar Sankaran break; 20625fdd593SJeykumar Sankaran case SSPP_DMA3: 2073cde792aSDmitry Baryshkov ctx->pending_flush_mask |= BIT(25); 20825fdd593SJeykumar Sankaran break; 20925fdd593SJeykumar Sankaran case SSPP_CURSOR0: 2103cde792aSDmitry Baryshkov ctx->pending_flush_mask |= BIT(22); 21125fdd593SJeykumar Sankaran break; 21225fdd593SJeykumar Sankaran case SSPP_CURSOR1: 2133cde792aSDmitry Baryshkov ctx->pending_flush_mask |= BIT(23); 21425fdd593SJeykumar Sankaran break; 21525fdd593SJeykumar Sankaran default: 21625fdd593SJeykumar Sankaran break; 21725fdd593SJeykumar Sankaran } 21825fdd593SJeykumar Sankaran } 21925fdd593SJeykumar Sankaran 2203cde792aSDmitry Baryshkov static void dpu_hw_ctl_update_pending_flush_mixer(struct dpu_hw_ctl *ctx, 22125fdd593SJeykumar Sankaran enum dpu_lm lm) 22225fdd593SJeykumar Sankaran { 22325fdd593SJeykumar Sankaran switch (lm) { 22425fdd593SJeykumar Sankaran case LM_0: 2253cde792aSDmitry Baryshkov ctx->pending_flush_mask |= BIT(6); 22625fdd593SJeykumar Sankaran break; 22725fdd593SJeykumar Sankaran case LM_1: 2283cde792aSDmitry Baryshkov ctx->pending_flush_mask |= BIT(7); 22925fdd593SJeykumar Sankaran break; 23025fdd593SJeykumar Sankaran case LM_2: 2313cde792aSDmitry Baryshkov ctx->pending_flush_mask |= BIT(8); 23225fdd593SJeykumar Sankaran break; 23325fdd593SJeykumar Sankaran case LM_3: 2343cde792aSDmitry Baryshkov ctx->pending_flush_mask |= BIT(9); 23525fdd593SJeykumar Sankaran break; 23625fdd593SJeykumar Sankaran case LM_4: 2373cde792aSDmitry Baryshkov ctx->pending_flush_mask |= BIT(10); 23825fdd593SJeykumar Sankaran break; 23925fdd593SJeykumar Sankaran case LM_5: 2403cde792aSDmitry Baryshkov ctx->pending_flush_mask |= BIT(20); 24125fdd593SJeykumar Sankaran break; 24225fdd593SJeykumar Sankaran default: 2433cde792aSDmitry Baryshkov break; 24425fdd593SJeykumar Sankaran } 24525fdd593SJeykumar Sankaran 2463cde792aSDmitry Baryshkov ctx->pending_flush_mask |= CTL_FLUSH_MASK_CTL; 24725fdd593SJeykumar Sankaran } 24825fdd593SJeykumar Sankaran 249d8199c85SDmitry Baryshkov static void dpu_hw_ctl_update_pending_flush_intf(struct dpu_hw_ctl *ctx, 250d8199c85SDmitry Baryshkov enum dpu_intf intf) 25125fdd593SJeykumar Sankaran { 25225fdd593SJeykumar Sankaran switch (intf) { 25325fdd593SJeykumar Sankaran case INTF_0: 254d8199c85SDmitry Baryshkov ctx->pending_flush_mask |= BIT(31); 25525fdd593SJeykumar Sankaran break; 25625fdd593SJeykumar Sankaran case INTF_1: 257d8199c85SDmitry Baryshkov ctx->pending_flush_mask |= BIT(30); 25825fdd593SJeykumar Sankaran break; 25925fdd593SJeykumar Sankaran case INTF_2: 260d8199c85SDmitry Baryshkov ctx->pending_flush_mask |= BIT(29); 26125fdd593SJeykumar Sankaran break; 26225fdd593SJeykumar Sankaran case INTF_3: 263d8199c85SDmitry Baryshkov ctx->pending_flush_mask |= BIT(28); 26425fdd593SJeykumar Sankaran break; 26525fdd593SJeykumar Sankaran default: 266d8199c85SDmitry Baryshkov break; 26725fdd593SJeykumar Sankaran } 26825fdd593SJeykumar Sankaran } 26925fdd593SJeykumar Sankaran 2706d084806SAbhinav Kumar static void dpu_hw_ctl_update_pending_flush_wb(struct dpu_hw_ctl *ctx, 2716d084806SAbhinav Kumar enum dpu_wb wb) 2726d084806SAbhinav Kumar { 2736d084806SAbhinav Kumar switch (wb) { 2746d084806SAbhinav Kumar case WB_0: 2756d084806SAbhinav Kumar case WB_1: 2766d084806SAbhinav Kumar case WB_2: 2776d084806SAbhinav Kumar ctx->pending_flush_mask |= BIT(WB_IDX); 27888334f8cSAbhinav Kumar break; 2796d084806SAbhinav Kumar default: 2806d084806SAbhinav Kumar break; 2816d084806SAbhinav Kumar } 2826d084806SAbhinav Kumar } 2836d084806SAbhinav Kumar 2846d084806SAbhinav Kumar static void dpu_hw_ctl_update_pending_flush_wb_v1(struct dpu_hw_ctl *ctx, 2856d084806SAbhinav Kumar enum dpu_wb wb) 2866d084806SAbhinav Kumar { 2876d084806SAbhinav Kumar ctx->pending_wb_flush_mask |= BIT(wb - WB_0); 2886d084806SAbhinav Kumar ctx->pending_flush_mask |= BIT(WB_IDX); 2896d084806SAbhinav Kumar } 2906d084806SAbhinav Kumar 291d8199c85SDmitry Baryshkov static void dpu_hw_ctl_update_pending_flush_intf_v1(struct dpu_hw_ctl *ctx, 292d8199c85SDmitry Baryshkov enum dpu_intf intf) 29373bfb790SKalyan Thota { 294d8199c85SDmitry Baryshkov ctx->pending_intf_flush_mask |= BIT(intf - INTF_0); 295d8199c85SDmitry Baryshkov ctx->pending_flush_mask |= BIT(INTF_IDX); 29673bfb790SKalyan Thota } 29773bfb790SKalyan Thota 298c40e6c67SDmitry Baryshkov static void dpu_hw_ctl_update_pending_flush_merge_3d_v1(struct dpu_hw_ctl *ctx, 299c40e6c67SDmitry Baryshkov enum dpu_merge_3d merge_3d) 300c40e6c67SDmitry Baryshkov { 301c40e6c67SDmitry Baryshkov ctx->pending_merge_3d_flush_mask |= BIT(merge_3d - MERGE_3D_0); 302c40e6c67SDmitry Baryshkov ctx->pending_flush_mask |= BIT(MERGE_3D_IDX); 303c40e6c67SDmitry Baryshkov } 304c40e6c67SDmitry Baryshkov 3053cde792aSDmitry Baryshkov static void dpu_hw_ctl_update_pending_flush_dspp(struct dpu_hw_ctl *ctx, 306*83a58b20SKalyan Thota enum dpu_dspp dspp, u32 dspp_sub_blk) 307e47616dfSKalyan Thota { 308e47616dfSKalyan Thota switch (dspp) { 309e47616dfSKalyan Thota case DSPP_0: 3103cde792aSDmitry Baryshkov ctx->pending_flush_mask |= BIT(13); 311e47616dfSKalyan Thota break; 312e47616dfSKalyan Thota case DSPP_1: 3133cde792aSDmitry Baryshkov ctx->pending_flush_mask |= BIT(14); 314e47616dfSKalyan Thota break; 315e47616dfSKalyan Thota case DSPP_2: 3163cde792aSDmitry Baryshkov ctx->pending_flush_mask |= BIT(15); 317e47616dfSKalyan Thota break; 318e47616dfSKalyan Thota case DSPP_3: 3193cde792aSDmitry Baryshkov ctx->pending_flush_mask |= BIT(21); 320e47616dfSKalyan Thota break; 321e47616dfSKalyan Thota default: 3223cde792aSDmitry Baryshkov break; 323e47616dfSKalyan Thota } 324e47616dfSKalyan Thota } 325e47616dfSKalyan Thota 326*83a58b20SKalyan Thota static void dpu_hw_ctl_update_pending_flush_dspp_sub_blocks( 327*83a58b20SKalyan Thota struct dpu_hw_ctl *ctx, enum dpu_dspp dspp, u32 dspp_sub_blk) 328*83a58b20SKalyan Thota { 329*83a58b20SKalyan Thota if (dspp >= DSPP_MAX) 330*83a58b20SKalyan Thota return; 331*83a58b20SKalyan Thota 332*83a58b20SKalyan Thota switch (dspp_sub_blk) { 333*83a58b20SKalyan Thota case DPU_DSPP_IGC: 334*83a58b20SKalyan Thota ctx->pending_dspp_flush_mask[dspp - DSPP_0] |= BIT(2); 335*83a58b20SKalyan Thota break; 336*83a58b20SKalyan Thota case DPU_DSPP_PCC: 337*83a58b20SKalyan Thota ctx->pending_dspp_flush_mask[dspp - DSPP_0] |= BIT(4); 338*83a58b20SKalyan Thota break; 339*83a58b20SKalyan Thota case DPU_DSPP_GC: 340*83a58b20SKalyan Thota ctx->pending_dspp_flush_mask[dspp - DSPP_0] |= BIT(5); 341*83a58b20SKalyan Thota break; 342*83a58b20SKalyan Thota default: 343*83a58b20SKalyan Thota return; 344*83a58b20SKalyan Thota } 345*83a58b20SKalyan Thota 346*83a58b20SKalyan Thota ctx->pending_flush_mask |= BIT(DSPP_IDX); 347*83a58b20SKalyan Thota } 348*83a58b20SKalyan Thota 34925fdd593SJeykumar Sankaran static u32 dpu_hw_ctl_poll_reset_status(struct dpu_hw_ctl *ctx, u32 timeout_us) 35025fdd593SJeykumar Sankaran { 35125fdd593SJeykumar Sankaran struct dpu_hw_blk_reg_map *c = &ctx->hw; 35225fdd593SJeykumar Sankaran ktime_t timeout; 35325fdd593SJeykumar Sankaran u32 status; 35425fdd593SJeykumar Sankaran 35525fdd593SJeykumar Sankaran timeout = ktime_add_us(ktime_get(), timeout_us); 35625fdd593SJeykumar Sankaran 35725fdd593SJeykumar Sankaran /* 35825fdd593SJeykumar Sankaran * it takes around 30us to have mdp finish resetting its ctl path 35925fdd593SJeykumar Sankaran * poll every 50us so that reset should be completed at 1st poll 36025fdd593SJeykumar Sankaran */ 36125fdd593SJeykumar Sankaran do { 36225fdd593SJeykumar Sankaran status = DPU_REG_READ(c, CTL_SW_RESET); 36325fdd593SJeykumar Sankaran status &= 0x1; 36425fdd593SJeykumar Sankaran if (status) 36525fdd593SJeykumar Sankaran usleep_range(20, 50); 36625fdd593SJeykumar Sankaran } while (status && ktime_compare_safe(ktime_get(), timeout) < 0); 36725fdd593SJeykumar Sankaran 36825fdd593SJeykumar Sankaran return status; 36925fdd593SJeykumar Sankaran } 37025fdd593SJeykumar Sankaran 37125fdd593SJeykumar Sankaran static int dpu_hw_ctl_reset_control(struct dpu_hw_ctl *ctx) 37225fdd593SJeykumar Sankaran { 37325fdd593SJeykumar Sankaran struct dpu_hw_blk_reg_map *c = &ctx->hw; 37425fdd593SJeykumar Sankaran 37525fdd593SJeykumar Sankaran pr_debug("issuing hw ctl reset for ctl:%d\n", ctx->idx); 37625fdd593SJeykumar Sankaran DPU_REG_WRITE(c, CTL_SW_RESET, 0x1); 37725fdd593SJeykumar Sankaran if (dpu_hw_ctl_poll_reset_status(ctx, DPU_REG_RESET_TIMEOUT_US)) 37825fdd593SJeykumar Sankaran return -EINVAL; 37925fdd593SJeykumar Sankaran 38025fdd593SJeykumar Sankaran return 0; 38125fdd593SJeykumar Sankaran } 38225fdd593SJeykumar Sankaran 38325fdd593SJeykumar Sankaran static int dpu_hw_ctl_wait_reset_status(struct dpu_hw_ctl *ctx) 38425fdd593SJeykumar Sankaran { 38525fdd593SJeykumar Sankaran struct dpu_hw_blk_reg_map *c = &ctx->hw; 38625fdd593SJeykumar Sankaran u32 status; 38725fdd593SJeykumar Sankaran 38825fdd593SJeykumar Sankaran status = DPU_REG_READ(c, CTL_SW_RESET); 38925fdd593SJeykumar Sankaran status &= 0x01; 39025fdd593SJeykumar Sankaran if (!status) 39125fdd593SJeykumar Sankaran return 0; 39225fdd593SJeykumar Sankaran 39325fdd593SJeykumar Sankaran pr_debug("hw ctl reset is set for ctl:%d\n", ctx->idx); 39425fdd593SJeykumar Sankaran if (dpu_hw_ctl_poll_reset_status(ctx, DPU_REG_RESET_TIMEOUT_US)) { 39525fdd593SJeykumar Sankaran pr_err("hw recovery is not complete for ctl:%d\n", ctx->idx); 39625fdd593SJeykumar Sankaran return -EINVAL; 39725fdd593SJeykumar Sankaran } 39825fdd593SJeykumar Sankaran 39925fdd593SJeykumar Sankaran return 0; 40025fdd593SJeykumar Sankaran } 40125fdd593SJeykumar Sankaran 40225fdd593SJeykumar Sankaran static void dpu_hw_ctl_clear_all_blendstages(struct dpu_hw_ctl *ctx) 40325fdd593SJeykumar Sankaran { 40425fdd593SJeykumar Sankaran struct dpu_hw_blk_reg_map *c = &ctx->hw; 40525fdd593SJeykumar Sankaran int i; 40625fdd593SJeykumar Sankaran 40725fdd593SJeykumar Sankaran for (i = 0; i < ctx->mixer_count; i++) { 408a41cdb69SDmitry Baryshkov enum dpu_lm mixer_id = ctx->mixer_hw_caps[i].id; 409a41cdb69SDmitry Baryshkov 410a41cdb69SDmitry Baryshkov DPU_REG_WRITE(c, CTL_LAYER(mixer_id), 0); 411a41cdb69SDmitry Baryshkov DPU_REG_WRITE(c, CTL_LAYER_EXT(mixer_id), 0); 412a41cdb69SDmitry Baryshkov DPU_REG_WRITE(c, CTL_LAYER_EXT2(mixer_id), 0); 413a41cdb69SDmitry Baryshkov DPU_REG_WRITE(c, CTL_LAYER_EXT3(mixer_id), 0); 41425fdd593SJeykumar Sankaran } 415b3652e87SKrishna Manikandan 416b3652e87SKrishna Manikandan DPU_REG_WRITE(c, CTL_FETCH_PIPE_ACTIVE, 0); 41725fdd593SJeykumar Sankaran } 41825fdd593SJeykumar Sankaran 4194488f71fSDmitry Baryshkov struct ctl_blend_config { 4204488f71fSDmitry Baryshkov int idx, shift, ext_shift; 4214488f71fSDmitry Baryshkov }; 4224488f71fSDmitry Baryshkov 4234488f71fSDmitry Baryshkov static const struct ctl_blend_config ctl_blend_config[][2] = { 4244488f71fSDmitry Baryshkov [SSPP_NONE] = { { -1 }, { -1 } }, 4254488f71fSDmitry Baryshkov [SSPP_MAX] = { { -1 }, { -1 } }, 4264488f71fSDmitry Baryshkov [SSPP_VIG0] = { { 0, 0, 0 }, { 3, 0 } }, 4274488f71fSDmitry Baryshkov [SSPP_VIG1] = { { 0, 3, 2 }, { 3, 4 } }, 4284488f71fSDmitry Baryshkov [SSPP_VIG2] = { { 0, 6, 4 }, { 3, 8 } }, 4294488f71fSDmitry Baryshkov [SSPP_VIG3] = { { 0, 26, 6 }, { 3, 12 } }, 4304488f71fSDmitry Baryshkov [SSPP_RGB0] = { { 0, 9, 8 }, { -1 } }, 4314488f71fSDmitry Baryshkov [SSPP_RGB1] = { { 0, 12, 10 }, { -1 } }, 4324488f71fSDmitry Baryshkov [SSPP_RGB2] = { { 0, 15, 12 }, { -1 } }, 4334488f71fSDmitry Baryshkov [SSPP_RGB3] = { { 0, 29, 14 }, { -1 } }, 4344488f71fSDmitry Baryshkov [SSPP_DMA0] = { { 0, 18, 16 }, { 2, 8 } }, 4354488f71fSDmitry Baryshkov [SSPP_DMA1] = { { 0, 21, 18 }, { 2, 12 } }, 4364488f71fSDmitry Baryshkov [SSPP_DMA2] = { { 2, 0 }, { 2, 16 } }, 4374488f71fSDmitry Baryshkov [SSPP_DMA3] = { { 2, 4 }, { 2, 20 } }, 4384488f71fSDmitry Baryshkov [SSPP_DMA4] = { { 4, 0 }, { 4, 8 } }, 4394488f71fSDmitry Baryshkov [SSPP_DMA5] = { { 4, 4 }, { 4, 12 } }, 4404488f71fSDmitry Baryshkov [SSPP_CURSOR0] = { { 1, 20 }, { -1 } }, 4414488f71fSDmitry Baryshkov [SSPP_CURSOR1] = { { 1, 26 }, { -1 } }, 4424488f71fSDmitry Baryshkov }; 4434488f71fSDmitry Baryshkov 44425fdd593SJeykumar Sankaran static void dpu_hw_ctl_setup_blendstage(struct dpu_hw_ctl *ctx, 44525fdd593SJeykumar Sankaran enum dpu_lm lm, struct dpu_hw_stage_cfg *stage_cfg) 44625fdd593SJeykumar Sankaran { 44725fdd593SJeykumar Sankaran struct dpu_hw_blk_reg_map *c = &ctx->hw; 4482c36dc91SDmitry Baryshkov u32 mix, ext, mix_ext; 4494488f71fSDmitry Baryshkov u32 mixercfg[5] = { 0 }; 45025fdd593SJeykumar Sankaran int i, j; 451dfdb3be4SColin Ian King int stages; 45225fdd593SJeykumar Sankaran int pipes_per_stage; 45325fdd593SJeykumar Sankaran 45425fdd593SJeykumar Sankaran stages = _mixer_stages(ctx->mixer_hw_caps, ctx->mixer_count, lm); 45525fdd593SJeykumar Sankaran if (stages < 0) 45625fdd593SJeykumar Sankaran return; 45725fdd593SJeykumar Sankaran 45825fdd593SJeykumar Sankaran if (test_bit(DPU_MIXER_SOURCESPLIT, 45925fdd593SJeykumar Sankaran &ctx->mixer_hw_caps->features)) 46025fdd593SJeykumar Sankaran pipes_per_stage = PIPES_PER_STAGE; 46125fdd593SJeykumar Sankaran else 46225fdd593SJeykumar Sankaran pipes_per_stage = 1; 46325fdd593SJeykumar Sankaran 4644488f71fSDmitry Baryshkov mixercfg[0] = CTL_MIXER_BORDER_OUT; /* always set BORDER_OUT */ 46525fdd593SJeykumar Sankaran 46625fdd593SJeykumar Sankaran if (!stage_cfg) 46725fdd593SJeykumar Sankaran goto exit; 46825fdd593SJeykumar Sankaran 46925fdd593SJeykumar Sankaran for (i = 0; i <= stages; i++) { 47025fdd593SJeykumar Sankaran /* overflow to ext register if 'i + 1 > 7' */ 47125fdd593SJeykumar Sankaran mix = (i + 1) & 0x7; 47225fdd593SJeykumar Sankaran ext = i >= 7; 4732c36dc91SDmitry Baryshkov mix_ext = (i + 1) & 0xf; 47425fdd593SJeykumar Sankaran 47525fdd593SJeykumar Sankaran for (j = 0 ; j < pipes_per_stage; j++) { 47625fdd593SJeykumar Sankaran enum dpu_sspp_multirect_index rect_index = 47725fdd593SJeykumar Sankaran stage_cfg->multirect_index[i][j]; 4784488f71fSDmitry Baryshkov enum dpu_sspp pipe = stage_cfg->stage[i][j]; 4794488f71fSDmitry Baryshkov const struct ctl_blend_config *cfg = 4804488f71fSDmitry Baryshkov &ctl_blend_config[pipe][rect_index == DPU_SSPP_RECT_1]; 48125fdd593SJeykumar Sankaran 4824488f71fSDmitry Baryshkov /* 4834488f71fSDmitry Baryshkov * CTL_LAYER has 3-bit field (and extra bits in EXT register), 4844488f71fSDmitry Baryshkov * all EXT registers has 4-bit fields. 4854488f71fSDmitry Baryshkov */ 4861c1ded39SDmitry Baryshkov if (cfg->idx == -1) { 4871c1ded39SDmitry Baryshkov continue; 4881c1ded39SDmitry Baryshkov } else if (cfg->idx == 0) { 4894488f71fSDmitry Baryshkov mixercfg[0] |= mix << cfg->shift; 4904488f71fSDmitry Baryshkov mixercfg[1] |= ext << cfg->ext_shift; 49125fdd593SJeykumar Sankaran } else { 4924488f71fSDmitry Baryshkov mixercfg[cfg->idx] |= mix_ext << cfg->shift; 49325fdd593SJeykumar Sankaran } 49425fdd593SJeykumar Sankaran } 49525fdd593SJeykumar Sankaran } 49625fdd593SJeykumar Sankaran 49725fdd593SJeykumar Sankaran exit: 4984488f71fSDmitry Baryshkov DPU_REG_WRITE(c, CTL_LAYER(lm), mixercfg[0]); 4994488f71fSDmitry Baryshkov DPU_REG_WRITE(c, CTL_LAYER_EXT(lm), mixercfg[1]); 5004488f71fSDmitry Baryshkov DPU_REG_WRITE(c, CTL_LAYER_EXT2(lm), mixercfg[2]); 5014488f71fSDmitry Baryshkov DPU_REG_WRITE(c, CTL_LAYER_EXT3(lm), mixercfg[3]); 502e92a4ae1SDmitry Baryshkov if ((test_bit(DPU_CTL_HAS_LAYER_EXT4, &ctx->caps->features))) 5034488f71fSDmitry Baryshkov DPU_REG_WRITE(c, CTL_LAYER_EXT4(lm), mixercfg[4]); 50425fdd593SJeykumar Sankaran } 50525fdd593SJeykumar Sankaran 50673bfb790SKalyan Thota 50773bfb790SKalyan Thota static void dpu_hw_ctl_intf_cfg_v1(struct dpu_hw_ctl *ctx, 50873bfb790SKalyan Thota struct dpu_hw_intf_cfg *cfg) 50973bfb790SKalyan Thota { 51073bfb790SKalyan Thota struct dpu_hw_blk_reg_map *c = &ctx->hw; 51173bfb790SKalyan Thota u32 intf_active = 0; 5126d084806SAbhinav Kumar u32 wb_active = 0; 51373bfb790SKalyan Thota u32 mode_sel = 0; 51473bfb790SKalyan Thota 51544bf8704SKalyan Thota /* CTL_TOP[31:28] carries group_id to collate CTL paths 51644bf8704SKalyan Thota * per VM. Explicitly disable it until VM support is 51744bf8704SKalyan Thota * added in SW. Power on reset value is not disable. 51844bf8704SKalyan Thota */ 51944bf8704SKalyan Thota if ((test_bit(DPU_CTL_VM_CFG, &ctx->caps->features))) 52044bf8704SKalyan Thota mode_sel = CTL_DEFAULT_GROUP_ID << 28; 52144bf8704SKalyan Thota 52277f6da90SVinod Koul if (cfg->dsc) 52377f6da90SVinod Koul DPU_REG_WRITE(&ctx->hw, CTL_DSC_FLUSH, cfg->dsc); 52477f6da90SVinod Koul 52573bfb790SKalyan Thota if (cfg->intf_mode_sel == DPU_CTL_MODE_SEL_CMD) 52673bfb790SKalyan Thota mode_sel |= BIT(17); 52773bfb790SKalyan Thota 52873bfb790SKalyan Thota intf_active = DPU_REG_READ(c, CTL_INTF_ACTIVE); 5296d084806SAbhinav Kumar wb_active = DPU_REG_READ(c, CTL_WB_ACTIVE); 5306d084806SAbhinav Kumar 5316d084806SAbhinav Kumar if (cfg->intf) 53273bfb790SKalyan Thota intf_active |= BIT(cfg->intf - INTF_0); 53373bfb790SKalyan Thota 5346d084806SAbhinav Kumar if (cfg->wb) 5356d084806SAbhinav Kumar wb_active |= BIT(cfg->wb - WB_0); 5366d084806SAbhinav Kumar 53773bfb790SKalyan Thota DPU_REG_WRITE(c, CTL_TOP, mode_sel); 53873bfb790SKalyan Thota DPU_REG_WRITE(c, CTL_INTF_ACTIVE, intf_active); 5396d084806SAbhinav Kumar DPU_REG_WRITE(c, CTL_WB_ACTIVE, wb_active); 5406d084806SAbhinav Kumar 54112aca1ceSKalyan Thota if (cfg->merge_3d) 54212aca1ceSKalyan Thota DPU_REG_WRITE(c, CTL_MERGE_3D_ACTIVE, 54312aca1ceSKalyan Thota BIT(cfg->merge_3d - MERGE_3D_0)); 54477f6da90SVinod Koul if (cfg->dsc) { 54577f6da90SVinod Koul DPU_REG_WRITE(&ctx->hw, CTL_FLUSH, DSC_IDX); 54677f6da90SVinod Koul DPU_REG_WRITE(c, CTL_DSC_ACTIVE, cfg->dsc); 54777f6da90SVinod Koul } 54873bfb790SKalyan Thota } 54973bfb790SKalyan Thota 55025fdd593SJeykumar Sankaran static void dpu_hw_ctl_intf_cfg(struct dpu_hw_ctl *ctx, 55125fdd593SJeykumar Sankaran struct dpu_hw_intf_cfg *cfg) 55225fdd593SJeykumar Sankaran { 55325fdd593SJeykumar Sankaran struct dpu_hw_blk_reg_map *c = &ctx->hw; 55425fdd593SJeykumar Sankaran u32 intf_cfg = 0; 55525fdd593SJeykumar Sankaran 55625fdd593SJeykumar Sankaran intf_cfg |= (cfg->intf & 0xF) << 4; 55725fdd593SJeykumar Sankaran 55825fdd593SJeykumar Sankaran if (cfg->mode_3d) { 55925fdd593SJeykumar Sankaran intf_cfg |= BIT(19); 56025fdd593SJeykumar Sankaran intf_cfg |= (cfg->mode_3d - 0x1) << 20; 56125fdd593SJeykumar Sankaran } 56225fdd593SJeykumar Sankaran 5636d084806SAbhinav Kumar if (cfg->wb) 5646d084806SAbhinav Kumar intf_cfg |= (cfg->wb & 0x3) + 2; 5656d084806SAbhinav Kumar 56625fdd593SJeykumar Sankaran switch (cfg->intf_mode_sel) { 56725fdd593SJeykumar Sankaran case DPU_CTL_MODE_SEL_VID: 56825fdd593SJeykumar Sankaran intf_cfg &= ~BIT(17); 56925fdd593SJeykumar Sankaran intf_cfg &= ~(0x3 << 15); 57025fdd593SJeykumar Sankaran break; 57125fdd593SJeykumar Sankaran case DPU_CTL_MODE_SEL_CMD: 57225fdd593SJeykumar Sankaran intf_cfg |= BIT(17); 57325fdd593SJeykumar Sankaran intf_cfg |= ((cfg->stream_sel & 0x3) << 15); 57425fdd593SJeykumar Sankaran break; 57525fdd593SJeykumar Sankaran default: 57625fdd593SJeykumar Sankaran pr_err("unknown interface type %d\n", cfg->intf_mode_sel); 57725fdd593SJeykumar Sankaran return; 57825fdd593SJeykumar Sankaran } 57925fdd593SJeykumar Sankaran 58025fdd593SJeykumar Sankaran DPU_REG_WRITE(c, CTL_TOP, intf_cfg); 58125fdd593SJeykumar Sankaran } 58225fdd593SJeykumar Sankaran 583e1a950eeSAbhinav Kumar static void dpu_hw_ctl_reset_intf_cfg_v1(struct dpu_hw_ctl *ctx, 584e1a950eeSAbhinav Kumar struct dpu_hw_intf_cfg *cfg) 585e1a950eeSAbhinav Kumar { 586e1a950eeSAbhinav Kumar struct dpu_hw_blk_reg_map *c = &ctx->hw; 587e1a950eeSAbhinav Kumar u32 intf_active = 0; 5886d084806SAbhinav Kumar u32 wb_active = 0; 589e1a950eeSAbhinav Kumar u32 merge3d_active = 0; 590e1a950eeSAbhinav Kumar 591e1a950eeSAbhinav Kumar /* 592e1a950eeSAbhinav Kumar * This API resets each portion of the CTL path namely, 593e1a950eeSAbhinav Kumar * clearing the sspps staged on the lm, merge_3d block, 5946d084806SAbhinav Kumar * interfaces , writeback etc to ensure clean teardown of the pipeline. 595e1a950eeSAbhinav Kumar * This will be used for writeback to begin with to have a 596e1a950eeSAbhinav Kumar * proper teardown of the writeback session but upon further 597e1a950eeSAbhinav Kumar * validation, this can be extended to all interfaces. 598e1a950eeSAbhinav Kumar */ 599e1a950eeSAbhinav Kumar if (cfg->merge_3d) { 600e1a950eeSAbhinav Kumar merge3d_active = DPU_REG_READ(c, CTL_MERGE_3D_ACTIVE); 601e1a950eeSAbhinav Kumar merge3d_active &= ~BIT(cfg->merge_3d - MERGE_3D_0); 602e1a950eeSAbhinav Kumar DPU_REG_WRITE(c, CTL_MERGE_3D_ACTIVE, 603e1a950eeSAbhinav Kumar merge3d_active); 604e1a950eeSAbhinav Kumar } 605e1a950eeSAbhinav Kumar 606e1a950eeSAbhinav Kumar dpu_hw_ctl_clear_all_blendstages(ctx); 607e1a950eeSAbhinav Kumar 608e1a950eeSAbhinav Kumar if (cfg->intf) { 609e1a950eeSAbhinav Kumar intf_active = DPU_REG_READ(c, CTL_INTF_ACTIVE); 610e1a950eeSAbhinav Kumar intf_active &= ~BIT(cfg->intf - INTF_0); 611e1a950eeSAbhinav Kumar DPU_REG_WRITE(c, CTL_INTF_ACTIVE, intf_active); 612e1a950eeSAbhinav Kumar } 6136d084806SAbhinav Kumar 6146d084806SAbhinav Kumar if (cfg->wb) { 6156d084806SAbhinav Kumar wb_active = DPU_REG_READ(c, CTL_WB_ACTIVE); 6166d084806SAbhinav Kumar wb_active &= ~BIT(cfg->wb - WB_0); 6176d084806SAbhinav Kumar DPU_REG_WRITE(c, CTL_WB_ACTIVE, wb_active); 6186d084806SAbhinav Kumar } 619e1a950eeSAbhinav Kumar } 620e1a950eeSAbhinav Kumar 621b3652e87SKrishna Manikandan static void dpu_hw_ctl_set_fetch_pipe_active(struct dpu_hw_ctl *ctx, 622b3652e87SKrishna Manikandan unsigned long *fetch_active) 623b3652e87SKrishna Manikandan { 624b3652e87SKrishna Manikandan int i; 625b3652e87SKrishna Manikandan u32 val = 0; 626b3652e87SKrishna Manikandan 627b3652e87SKrishna Manikandan if (fetch_active) { 628b3652e87SKrishna Manikandan for (i = 0; i < SSPP_MAX; i++) { 629b3652e87SKrishna Manikandan if (test_bit(i, fetch_active) && 630b3652e87SKrishna Manikandan fetch_tbl[i] != CTL_INVALID_BIT) 631b3652e87SKrishna Manikandan val |= BIT(fetch_tbl[i]); 632b3652e87SKrishna Manikandan } 633b3652e87SKrishna Manikandan } 634b3652e87SKrishna Manikandan 635b3652e87SKrishna Manikandan DPU_REG_WRITE(&ctx->hw, CTL_FETCH_PIPE_ACTIVE, val); 636b3652e87SKrishna Manikandan } 637b3652e87SKrishna Manikandan 63825fdd593SJeykumar Sankaran static void _setup_ctl_ops(struct dpu_hw_ctl_ops *ops, 63925fdd593SJeykumar Sankaran unsigned long cap) 64025fdd593SJeykumar Sankaran { 64173bfb790SKalyan Thota if (cap & BIT(DPU_CTL_ACTIVE_CFG)) { 64273bfb790SKalyan Thota ops->trigger_flush = dpu_hw_ctl_trigger_flush_v1; 64373bfb790SKalyan Thota ops->setup_intf_cfg = dpu_hw_ctl_intf_cfg_v1; 644e1a950eeSAbhinav Kumar ops->reset_intf_cfg = dpu_hw_ctl_reset_intf_cfg_v1; 645d8199c85SDmitry Baryshkov ops->update_pending_flush_intf = 646d8199c85SDmitry Baryshkov dpu_hw_ctl_update_pending_flush_intf_v1; 647c40e6c67SDmitry Baryshkov ops->update_pending_flush_merge_3d = 648c40e6c67SDmitry Baryshkov dpu_hw_ctl_update_pending_flush_merge_3d_v1; 6496d084806SAbhinav Kumar ops->update_pending_flush_wb = dpu_hw_ctl_update_pending_flush_wb_v1; 65073bfb790SKalyan Thota } else { 65173bfb790SKalyan Thota ops->trigger_flush = dpu_hw_ctl_trigger_flush; 65273bfb790SKalyan Thota ops->setup_intf_cfg = dpu_hw_ctl_intf_cfg; 653d8199c85SDmitry Baryshkov ops->update_pending_flush_intf = 654d8199c85SDmitry Baryshkov dpu_hw_ctl_update_pending_flush_intf; 6556d084806SAbhinav Kumar ops->update_pending_flush_wb = dpu_hw_ctl_update_pending_flush_wb; 65673bfb790SKalyan Thota } 65725fdd593SJeykumar Sankaran ops->clear_pending_flush = dpu_hw_ctl_clear_pending_flush; 65825fdd593SJeykumar Sankaran ops->update_pending_flush = dpu_hw_ctl_update_pending_flush; 65925fdd593SJeykumar Sankaran ops->get_pending_flush = dpu_hw_ctl_get_pending_flush; 66025fdd593SJeykumar Sankaran ops->get_flush_register = dpu_hw_ctl_get_flush_register; 66125fdd593SJeykumar Sankaran ops->trigger_start = dpu_hw_ctl_trigger_start; 66278706798SAngeloGioacchino Del Regno ops->is_started = dpu_hw_ctl_is_started; 66325fdd593SJeykumar Sankaran ops->trigger_pending = dpu_hw_ctl_trigger_pending; 66425fdd593SJeykumar Sankaran ops->reset = dpu_hw_ctl_reset_control; 66525fdd593SJeykumar Sankaran ops->wait_reset_status = dpu_hw_ctl_wait_reset_status; 66625fdd593SJeykumar Sankaran ops->clear_all_blendstages = dpu_hw_ctl_clear_all_blendstages; 66725fdd593SJeykumar Sankaran ops->setup_blendstage = dpu_hw_ctl_setup_blendstage; 6683cde792aSDmitry Baryshkov ops->update_pending_flush_sspp = dpu_hw_ctl_update_pending_flush_sspp; 6693cde792aSDmitry Baryshkov ops->update_pending_flush_mixer = dpu_hw_ctl_update_pending_flush_mixer; 670*83a58b20SKalyan Thota if (cap & BIT(DPU_CTL_DSPP_SUB_BLOCK_FLUSH)) 671*83a58b20SKalyan Thota ops->update_pending_flush_dspp = dpu_hw_ctl_update_pending_flush_dspp_sub_blocks; 672*83a58b20SKalyan Thota else 6733cde792aSDmitry Baryshkov ops->update_pending_flush_dspp = dpu_hw_ctl_update_pending_flush_dspp; 674*83a58b20SKalyan Thota 675b3652e87SKrishna Manikandan if (cap & BIT(DPU_CTL_FETCH_ACTIVE)) 676b3652e87SKrishna Manikandan ops->set_active_pipes = dpu_hw_ctl_set_fetch_pipe_active; 67725fdd593SJeykumar Sankaran }; 67825fdd593SJeykumar Sankaran 67925fdd593SJeykumar Sankaran struct dpu_hw_ctl *dpu_hw_ctl_init(enum dpu_ctl idx, 68025fdd593SJeykumar Sankaran void __iomem *addr, 681abda0d92SStephen Boyd const struct dpu_mdss_cfg *m) 68225fdd593SJeykumar Sankaran { 68325fdd593SJeykumar Sankaran struct dpu_hw_ctl *c; 684abda0d92SStephen Boyd const struct dpu_ctl_cfg *cfg; 68525fdd593SJeykumar Sankaran 68625fdd593SJeykumar Sankaran c = kzalloc(sizeof(*c), GFP_KERNEL); 68725fdd593SJeykumar Sankaran if (!c) 68825fdd593SJeykumar Sankaran return ERR_PTR(-ENOMEM); 68925fdd593SJeykumar Sankaran 69025fdd593SJeykumar Sankaran cfg = _ctl_offset(idx, m, addr, &c->hw); 69125fdd593SJeykumar Sankaran if (IS_ERR_OR_NULL(cfg)) { 69225fdd593SJeykumar Sankaran kfree(c); 69325fdd593SJeykumar Sankaran pr_err("failed to create dpu_hw_ctl %d\n", idx); 69425fdd593SJeykumar Sankaran return ERR_PTR(-EINVAL); 69525fdd593SJeykumar Sankaran } 69625fdd593SJeykumar Sankaran 69725fdd593SJeykumar Sankaran c->caps = cfg; 69825fdd593SJeykumar Sankaran _setup_ctl_ops(&c->ops, c->caps->features); 69925fdd593SJeykumar Sankaran c->idx = idx; 70025fdd593SJeykumar Sankaran c->mixer_count = m->mixer_count; 70125fdd593SJeykumar Sankaran c->mixer_hw_caps = m->mixer; 70225fdd593SJeykumar Sankaran 70325fdd593SJeykumar Sankaran return c; 70425fdd593SJeykumar Sankaran } 70525fdd593SJeykumar Sankaran 70625fdd593SJeykumar Sankaran void dpu_hw_ctl_destroy(struct dpu_hw_ctl *ctx) 70725fdd593SJeykumar Sankaran { 70825fdd593SJeykumar Sankaran kfree(ctx); 70925fdd593SJeykumar Sankaran } 710