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
2983a58b20SKalyan Thota #define   CTL_DSC_ACTIVE                0x0E8
306d084806SAbhinav Kumar #define   CTL_WB_ACTIVE                 0x0EC
3173bfb790SKalyan Thota #define   CTL_INTF_ACTIVE               0x0F4
3283a58b20SKalyan 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
3883a58b20SKalyan 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
4883a58b20SKalyan 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,
54*ba7a94eaSJonathan Marek 	1, 2, 3, 4, 5};
5525fdd593SJeykumar Sankaran 
_mixer_stages(const struct dpu_lm_cfg * mixer,int count,enum dpu_lm lm)5625fdd593SJeykumar Sankaran static int _mixer_stages(const struct dpu_lm_cfg *mixer, int count,
5725fdd593SJeykumar Sankaran 		enum dpu_lm lm)
5825fdd593SJeykumar Sankaran {
5925fdd593SJeykumar Sankaran 	int i;
6025fdd593SJeykumar Sankaran 	int stages = -EINVAL;
6125fdd593SJeykumar Sankaran 
6225fdd593SJeykumar Sankaran 	for (i = 0; i < count; i++) {
6325fdd593SJeykumar Sankaran 		if (lm == mixer[i].id) {
6425fdd593SJeykumar Sankaran 			stages = mixer[i].sblk->maxblendstages;
6525fdd593SJeykumar Sankaran 			break;
6625fdd593SJeykumar Sankaran 		}
6725fdd593SJeykumar Sankaran 	}
6825fdd593SJeykumar Sankaran 
6925fdd593SJeykumar Sankaran 	return stages;
7025fdd593SJeykumar Sankaran }
7125fdd593SJeykumar Sankaran 
dpu_hw_ctl_get_flush_register(struct dpu_hw_ctl * ctx)72812eeeb6SSean Paul static inline u32 dpu_hw_ctl_get_flush_register(struct dpu_hw_ctl *ctx)
73812eeeb6SSean Paul {
74812eeeb6SSean Paul 	struct dpu_hw_blk_reg_map *c = &ctx->hw;
75812eeeb6SSean Paul 
76812eeeb6SSean Paul 	return DPU_REG_READ(c, CTL_FLUSH);
77812eeeb6SSean Paul }
78812eeeb6SSean Paul 
dpu_hw_ctl_trigger_start(struct dpu_hw_ctl * ctx)7925fdd593SJeykumar Sankaran static inline void dpu_hw_ctl_trigger_start(struct dpu_hw_ctl *ctx)
8025fdd593SJeykumar Sankaran {
81812eeeb6SSean Paul 	trace_dpu_hw_ctl_trigger_start(ctx->pending_flush_mask,
82812eeeb6SSean Paul 				       dpu_hw_ctl_get_flush_register(ctx));
8325fdd593SJeykumar Sankaran 	DPU_REG_WRITE(&ctx->hw, CTL_START, 0x1);
8425fdd593SJeykumar Sankaran }
8525fdd593SJeykumar Sankaran 
dpu_hw_ctl_is_started(struct dpu_hw_ctl * ctx)8678706798SAngeloGioacchino Del Regno static inline bool dpu_hw_ctl_is_started(struct dpu_hw_ctl *ctx)
8778706798SAngeloGioacchino Del Regno {
8878706798SAngeloGioacchino Del Regno 	return !!(DPU_REG_READ(&ctx->hw, CTL_START) & BIT(0));
8978706798SAngeloGioacchino Del Regno }
9078706798SAngeloGioacchino Del Regno 
dpu_hw_ctl_trigger_pending(struct dpu_hw_ctl * ctx)9125fdd593SJeykumar Sankaran static inline void dpu_hw_ctl_trigger_pending(struct dpu_hw_ctl *ctx)
9225fdd593SJeykumar Sankaran {
93812eeeb6SSean Paul 	trace_dpu_hw_ctl_trigger_prepare(ctx->pending_flush_mask,
94812eeeb6SSean Paul 					 dpu_hw_ctl_get_flush_register(ctx));
9525fdd593SJeykumar Sankaran 	DPU_REG_WRITE(&ctx->hw, CTL_PREPARE, 0x1);
9625fdd593SJeykumar Sankaran }
9725fdd593SJeykumar Sankaran 
dpu_hw_ctl_clear_pending_flush(struct dpu_hw_ctl * ctx)9825fdd593SJeykumar Sankaran static inline void dpu_hw_ctl_clear_pending_flush(struct dpu_hw_ctl *ctx)
9925fdd593SJeykumar Sankaran {
100812eeeb6SSean Paul 	trace_dpu_hw_ctl_clear_pending_flush(ctx->pending_flush_mask,
101812eeeb6SSean Paul 				     dpu_hw_ctl_get_flush_register(ctx));
10225fdd593SJeykumar Sankaran 	ctx->pending_flush_mask = 0x0;
103625cbb07SKuogee Hsieh 	ctx->pending_intf_flush_mask = 0;
104625cbb07SKuogee Hsieh 	ctx->pending_wb_flush_mask = 0;
105625cbb07SKuogee Hsieh 	ctx->pending_merge_3d_flush_mask = 0;
106761c629dSKuogee Hsieh 	ctx->pending_dsc_flush_mask = 0;
10783a58b20SKalyan Thota 
10883a58b20SKalyan Thota 	memset(ctx->pending_dspp_flush_mask, 0,
10983a58b20SKalyan Thota 		sizeof(ctx->pending_dspp_flush_mask));
11025fdd593SJeykumar Sankaran }
11125fdd593SJeykumar Sankaran 
dpu_hw_ctl_update_pending_flush(struct dpu_hw_ctl * ctx,u32 flushbits)11225fdd593SJeykumar Sankaran static inline void dpu_hw_ctl_update_pending_flush(struct dpu_hw_ctl *ctx,
11325fdd593SJeykumar Sankaran 		u32 flushbits)
11425fdd593SJeykumar Sankaran {
115812eeeb6SSean Paul 	trace_dpu_hw_ctl_update_pending_flush(flushbits,
116812eeeb6SSean Paul 					      ctx->pending_flush_mask);
11725fdd593SJeykumar Sankaran 	ctx->pending_flush_mask |= flushbits;
11825fdd593SJeykumar Sankaran }
11925fdd593SJeykumar Sankaran 
dpu_hw_ctl_get_pending_flush(struct dpu_hw_ctl * ctx)12025fdd593SJeykumar Sankaran static u32 dpu_hw_ctl_get_pending_flush(struct dpu_hw_ctl *ctx)
12125fdd593SJeykumar Sankaran {
12225fdd593SJeykumar Sankaran 	return ctx->pending_flush_mask;
12325fdd593SJeykumar Sankaran }
12425fdd593SJeykumar Sankaran 
dpu_hw_ctl_trigger_flush_v1(struct dpu_hw_ctl * ctx)12573bfb790SKalyan Thota static inline void dpu_hw_ctl_trigger_flush_v1(struct dpu_hw_ctl *ctx)
12673bfb790SKalyan Thota {
12783a58b20SKalyan Thota 	int dspp;
12883a58b20SKalyan Thota 
129c40e6c67SDmitry Baryshkov 	if (ctx->pending_flush_mask & BIT(MERGE_3D_IDX))
130c40e6c67SDmitry Baryshkov 		DPU_REG_WRITE(&ctx->hw, CTL_MERGE_3D_FLUSH,
131c40e6c67SDmitry Baryshkov 				ctx->pending_merge_3d_flush_mask);
13273bfb790SKalyan Thota 	if (ctx->pending_flush_mask & BIT(INTF_IDX))
13373bfb790SKalyan Thota 		DPU_REG_WRITE(&ctx->hw, CTL_INTF_FLUSH,
13473bfb790SKalyan Thota 				ctx->pending_intf_flush_mask);
1356d084806SAbhinav Kumar 	if (ctx->pending_flush_mask & BIT(WB_IDX))
1366d084806SAbhinav Kumar 		DPU_REG_WRITE(&ctx->hw, CTL_WB_FLUSH,
1376d084806SAbhinav Kumar 				ctx->pending_wb_flush_mask);
13873bfb790SKalyan Thota 
13983a58b20SKalyan Thota 	if (ctx->pending_flush_mask & BIT(DSPP_IDX))
14083a58b20SKalyan Thota 		for (dspp = DSPP_0; dspp < DSPP_MAX; dspp++) {
14183a58b20SKalyan Thota 			if (ctx->pending_dspp_flush_mask[dspp - DSPP_0])
14283a58b20SKalyan Thota 				DPU_REG_WRITE(&ctx->hw,
14383a58b20SKalyan Thota 				CTL_DSPP_n_FLUSH(dspp - DSPP_0),
14483a58b20SKalyan Thota 				ctx->pending_dspp_flush_mask[dspp - DSPP_0]);
14583a58b20SKalyan Thota 		}
146761c629dSKuogee Hsieh 
147761c629dSKuogee Hsieh 	if (ctx->pending_flush_mask & BIT(DSC_IDX))
148761c629dSKuogee Hsieh 		DPU_REG_WRITE(&ctx->hw, CTL_DSC_FLUSH,
149761c629dSKuogee Hsieh 			      ctx->pending_dsc_flush_mask);
150761c629dSKuogee Hsieh 
15173bfb790SKalyan Thota 	DPU_REG_WRITE(&ctx->hw, CTL_FLUSH, ctx->pending_flush_mask);
15273bfb790SKalyan Thota }
15373bfb790SKalyan Thota 
dpu_hw_ctl_trigger_flush(struct dpu_hw_ctl * ctx)15425fdd593SJeykumar Sankaran static inline void dpu_hw_ctl_trigger_flush(struct dpu_hw_ctl *ctx)
15525fdd593SJeykumar Sankaran {
156812eeeb6SSean Paul 	trace_dpu_hw_ctl_trigger_pending_flush(ctx->pending_flush_mask,
157812eeeb6SSean Paul 				     dpu_hw_ctl_get_flush_register(ctx));
15825fdd593SJeykumar Sankaran 	DPU_REG_WRITE(&ctx->hw, CTL_FLUSH, ctx->pending_flush_mask);
15925fdd593SJeykumar Sankaran }
16025fdd593SJeykumar Sankaran 
dpu_hw_ctl_update_pending_flush_sspp(struct dpu_hw_ctl * ctx,enum dpu_sspp sspp)1613cde792aSDmitry Baryshkov static void dpu_hw_ctl_update_pending_flush_sspp(struct dpu_hw_ctl *ctx,
16225fdd593SJeykumar Sankaran 	enum dpu_sspp sspp)
16325fdd593SJeykumar Sankaran {
16425fdd593SJeykumar Sankaran 	switch (sspp) {
16525fdd593SJeykumar Sankaran 	case SSPP_VIG0:
1663cde792aSDmitry Baryshkov 		ctx->pending_flush_mask |=  BIT(0);
16725fdd593SJeykumar Sankaran 		break;
16825fdd593SJeykumar Sankaran 	case SSPP_VIG1:
1693cde792aSDmitry Baryshkov 		ctx->pending_flush_mask |= BIT(1);
17025fdd593SJeykumar Sankaran 		break;
17125fdd593SJeykumar Sankaran 	case SSPP_VIG2:
1723cde792aSDmitry Baryshkov 		ctx->pending_flush_mask |= BIT(2);
17325fdd593SJeykumar Sankaran 		break;
17425fdd593SJeykumar Sankaran 	case SSPP_VIG3:
1753cde792aSDmitry Baryshkov 		ctx->pending_flush_mask |= BIT(18);
17625fdd593SJeykumar Sankaran 		break;
17725fdd593SJeykumar Sankaran 	case SSPP_RGB0:
1783cde792aSDmitry Baryshkov 		ctx->pending_flush_mask |= BIT(3);
17925fdd593SJeykumar Sankaran 		break;
18025fdd593SJeykumar Sankaran 	case SSPP_RGB1:
1813cde792aSDmitry Baryshkov 		ctx->pending_flush_mask |= BIT(4);
18225fdd593SJeykumar Sankaran 		break;
18325fdd593SJeykumar Sankaran 	case SSPP_RGB2:
1843cde792aSDmitry Baryshkov 		ctx->pending_flush_mask |= BIT(5);
18525fdd593SJeykumar Sankaran 		break;
18625fdd593SJeykumar Sankaran 	case SSPP_RGB3:
1873cde792aSDmitry Baryshkov 		ctx->pending_flush_mask |= BIT(19);
18825fdd593SJeykumar Sankaran 		break;
18925fdd593SJeykumar Sankaran 	case SSPP_DMA0:
1903cde792aSDmitry Baryshkov 		ctx->pending_flush_mask |= BIT(11);
19125fdd593SJeykumar Sankaran 		break;
19225fdd593SJeykumar Sankaran 	case SSPP_DMA1:
1933cde792aSDmitry Baryshkov 		ctx->pending_flush_mask |= BIT(12);
19425fdd593SJeykumar Sankaran 		break;
19525fdd593SJeykumar Sankaran 	case SSPP_DMA2:
1963cde792aSDmitry Baryshkov 		ctx->pending_flush_mask |= BIT(24);
19725fdd593SJeykumar Sankaran 		break;
19825fdd593SJeykumar Sankaran 	case SSPP_DMA3:
1993cde792aSDmitry Baryshkov 		ctx->pending_flush_mask |= BIT(25);
20025fdd593SJeykumar Sankaran 		break;
201*ba7a94eaSJonathan Marek 	case SSPP_DMA4:
202*ba7a94eaSJonathan Marek 		ctx->pending_flush_mask |= BIT(13);
203*ba7a94eaSJonathan Marek 		break;
204*ba7a94eaSJonathan Marek 	case SSPP_DMA5:
205*ba7a94eaSJonathan Marek 		ctx->pending_flush_mask |= BIT(14);
206*ba7a94eaSJonathan Marek 		break;
20725fdd593SJeykumar Sankaran 	case SSPP_CURSOR0:
2083cde792aSDmitry Baryshkov 		ctx->pending_flush_mask |= BIT(22);
20925fdd593SJeykumar Sankaran 		break;
21025fdd593SJeykumar Sankaran 	case SSPP_CURSOR1:
2113cde792aSDmitry Baryshkov 		ctx->pending_flush_mask |= BIT(23);
21225fdd593SJeykumar Sankaran 		break;
21325fdd593SJeykumar Sankaran 	default:
21425fdd593SJeykumar Sankaran 		break;
21525fdd593SJeykumar Sankaran 	}
21625fdd593SJeykumar Sankaran }
21725fdd593SJeykumar Sankaran 
dpu_hw_ctl_update_pending_flush_mixer(struct dpu_hw_ctl * ctx,enum dpu_lm lm)2183cde792aSDmitry Baryshkov static void dpu_hw_ctl_update_pending_flush_mixer(struct dpu_hw_ctl *ctx,
21925fdd593SJeykumar Sankaran 	enum dpu_lm lm)
22025fdd593SJeykumar Sankaran {
22125fdd593SJeykumar Sankaran 	switch (lm) {
22225fdd593SJeykumar Sankaran 	case LM_0:
2233cde792aSDmitry Baryshkov 		ctx->pending_flush_mask |= BIT(6);
22425fdd593SJeykumar Sankaran 		break;
22525fdd593SJeykumar Sankaran 	case LM_1:
2263cde792aSDmitry Baryshkov 		ctx->pending_flush_mask |= BIT(7);
22725fdd593SJeykumar Sankaran 		break;
22825fdd593SJeykumar Sankaran 	case LM_2:
2293cde792aSDmitry Baryshkov 		ctx->pending_flush_mask |= BIT(8);
23025fdd593SJeykumar Sankaran 		break;
23125fdd593SJeykumar Sankaran 	case LM_3:
2323cde792aSDmitry Baryshkov 		ctx->pending_flush_mask |= BIT(9);
23325fdd593SJeykumar Sankaran 		break;
23425fdd593SJeykumar Sankaran 	case LM_4:
2353cde792aSDmitry Baryshkov 		ctx->pending_flush_mask |= BIT(10);
23625fdd593SJeykumar Sankaran 		break;
23725fdd593SJeykumar Sankaran 	case LM_5:
2383cde792aSDmitry Baryshkov 		ctx->pending_flush_mask |= BIT(20);
23925fdd593SJeykumar Sankaran 		break;
24025fdd593SJeykumar Sankaran 	default:
2413cde792aSDmitry Baryshkov 		break;
24225fdd593SJeykumar Sankaran 	}
24325fdd593SJeykumar Sankaran 
2443cde792aSDmitry Baryshkov 	ctx->pending_flush_mask |= CTL_FLUSH_MASK_CTL;
24525fdd593SJeykumar Sankaran }
24625fdd593SJeykumar Sankaran 
dpu_hw_ctl_update_pending_flush_intf(struct dpu_hw_ctl * ctx,enum dpu_intf intf)247d8199c85SDmitry Baryshkov static void dpu_hw_ctl_update_pending_flush_intf(struct dpu_hw_ctl *ctx,
248d8199c85SDmitry Baryshkov 		enum dpu_intf intf)
24925fdd593SJeykumar Sankaran {
25025fdd593SJeykumar Sankaran 	switch (intf) {
25125fdd593SJeykumar Sankaran 	case INTF_0:
252d8199c85SDmitry Baryshkov 		ctx->pending_flush_mask |= BIT(31);
25325fdd593SJeykumar Sankaran 		break;
25425fdd593SJeykumar Sankaran 	case INTF_1:
255d8199c85SDmitry Baryshkov 		ctx->pending_flush_mask |= BIT(30);
25625fdd593SJeykumar Sankaran 		break;
25725fdd593SJeykumar Sankaran 	case INTF_2:
258d8199c85SDmitry Baryshkov 		ctx->pending_flush_mask |= BIT(29);
25925fdd593SJeykumar Sankaran 		break;
26025fdd593SJeykumar Sankaran 	case INTF_3:
261d8199c85SDmitry Baryshkov 		ctx->pending_flush_mask |= BIT(28);
26225fdd593SJeykumar Sankaran 		break;
26325fdd593SJeykumar Sankaran 	default:
264d8199c85SDmitry Baryshkov 		break;
26525fdd593SJeykumar Sankaran 	}
26625fdd593SJeykumar Sankaran }
26725fdd593SJeykumar Sankaran 
dpu_hw_ctl_update_pending_flush_wb(struct dpu_hw_ctl * ctx,enum dpu_wb wb)2686d084806SAbhinav Kumar static void dpu_hw_ctl_update_pending_flush_wb(struct dpu_hw_ctl *ctx,
2696d084806SAbhinav Kumar 		enum dpu_wb wb)
2706d084806SAbhinav Kumar {
2716d084806SAbhinav Kumar 	switch (wb) {
2726d084806SAbhinav Kumar 	case WB_0:
2736d084806SAbhinav Kumar 	case WB_1:
2746d084806SAbhinav Kumar 	case WB_2:
2756d084806SAbhinav Kumar 		ctx->pending_flush_mask |= BIT(WB_IDX);
27688334f8cSAbhinav Kumar 		break;
2776d084806SAbhinav Kumar 	default:
2786d084806SAbhinav Kumar 		break;
2796d084806SAbhinav Kumar 	}
2806d084806SAbhinav Kumar }
2816d084806SAbhinav Kumar 
dpu_hw_ctl_update_pending_flush_wb_v1(struct dpu_hw_ctl * ctx,enum dpu_wb wb)2826d084806SAbhinav Kumar static void dpu_hw_ctl_update_pending_flush_wb_v1(struct dpu_hw_ctl *ctx,
2836d084806SAbhinav Kumar 		enum dpu_wb wb)
2846d084806SAbhinav Kumar {
2856d084806SAbhinav Kumar 	ctx->pending_wb_flush_mask |= BIT(wb - WB_0);
2866d084806SAbhinav Kumar 	ctx->pending_flush_mask |= BIT(WB_IDX);
2876d084806SAbhinav Kumar }
2886d084806SAbhinav Kumar 
dpu_hw_ctl_update_pending_flush_intf_v1(struct dpu_hw_ctl * ctx,enum dpu_intf intf)289d8199c85SDmitry Baryshkov static void dpu_hw_ctl_update_pending_flush_intf_v1(struct dpu_hw_ctl *ctx,
290d8199c85SDmitry Baryshkov 		enum dpu_intf intf)
29173bfb790SKalyan Thota {
292d8199c85SDmitry Baryshkov 	ctx->pending_intf_flush_mask |= BIT(intf - INTF_0);
293d8199c85SDmitry Baryshkov 	ctx->pending_flush_mask |= BIT(INTF_IDX);
29473bfb790SKalyan Thota }
29573bfb790SKalyan Thota 
dpu_hw_ctl_update_pending_flush_merge_3d_v1(struct dpu_hw_ctl * ctx,enum dpu_merge_3d merge_3d)296c40e6c67SDmitry Baryshkov static void dpu_hw_ctl_update_pending_flush_merge_3d_v1(struct dpu_hw_ctl *ctx,
297c40e6c67SDmitry Baryshkov 		enum dpu_merge_3d merge_3d)
298c40e6c67SDmitry Baryshkov {
299c40e6c67SDmitry Baryshkov 	ctx->pending_merge_3d_flush_mask |= BIT(merge_3d - MERGE_3D_0);
300c40e6c67SDmitry Baryshkov 	ctx->pending_flush_mask |= BIT(MERGE_3D_IDX);
301c40e6c67SDmitry Baryshkov }
302c40e6c67SDmitry Baryshkov 
dpu_hw_ctl_update_pending_flush_dsc_v1(struct dpu_hw_ctl * ctx,enum dpu_dsc dsc_num)303761c629dSKuogee Hsieh static void dpu_hw_ctl_update_pending_flush_dsc_v1(struct dpu_hw_ctl *ctx,
304761c629dSKuogee Hsieh 						   enum dpu_dsc dsc_num)
305761c629dSKuogee Hsieh {
306761c629dSKuogee Hsieh 	ctx->pending_dsc_flush_mask |= BIT(dsc_num - DSC_0);
307761c629dSKuogee Hsieh 	ctx->pending_flush_mask |= BIT(DSC_IDX);
308761c629dSKuogee Hsieh }
309761c629dSKuogee Hsieh 
dpu_hw_ctl_update_pending_flush_dspp(struct dpu_hw_ctl * ctx,enum dpu_dspp dspp,u32 dspp_sub_blk)3103cde792aSDmitry Baryshkov static void dpu_hw_ctl_update_pending_flush_dspp(struct dpu_hw_ctl *ctx,
31183a58b20SKalyan Thota 	enum dpu_dspp dspp, u32 dspp_sub_blk)
312e47616dfSKalyan Thota {
313e47616dfSKalyan Thota 	switch (dspp) {
314e47616dfSKalyan Thota 	case DSPP_0:
3153cde792aSDmitry Baryshkov 		ctx->pending_flush_mask |= BIT(13);
316e47616dfSKalyan Thota 		break;
317e47616dfSKalyan Thota 	case DSPP_1:
3183cde792aSDmitry Baryshkov 		ctx->pending_flush_mask |= BIT(14);
319e47616dfSKalyan Thota 		break;
320e47616dfSKalyan Thota 	case DSPP_2:
3213cde792aSDmitry Baryshkov 		ctx->pending_flush_mask |= BIT(15);
322e47616dfSKalyan Thota 		break;
323e47616dfSKalyan Thota 	case DSPP_3:
3243cde792aSDmitry Baryshkov 		ctx->pending_flush_mask |= BIT(21);
325e47616dfSKalyan Thota 		break;
326e47616dfSKalyan Thota 	default:
3273cde792aSDmitry Baryshkov 		break;
328e47616dfSKalyan Thota 	}
329e47616dfSKalyan Thota }
330e47616dfSKalyan Thota 
dpu_hw_ctl_update_pending_flush_dspp_sub_blocks(struct dpu_hw_ctl * ctx,enum dpu_dspp dspp,u32 dspp_sub_blk)33183a58b20SKalyan Thota static void dpu_hw_ctl_update_pending_flush_dspp_sub_blocks(
33283a58b20SKalyan Thota 	struct dpu_hw_ctl *ctx,	enum dpu_dspp dspp, u32 dspp_sub_blk)
33383a58b20SKalyan Thota {
33483a58b20SKalyan Thota 	if (dspp >= DSPP_MAX)
33583a58b20SKalyan Thota 		return;
33683a58b20SKalyan Thota 
33783a58b20SKalyan Thota 	switch (dspp_sub_blk) {
33883a58b20SKalyan Thota 	case DPU_DSPP_PCC:
33983a58b20SKalyan Thota 		ctx->pending_dspp_flush_mask[dspp - DSPP_0] |= BIT(4);
34083a58b20SKalyan Thota 		break;
34183a58b20SKalyan Thota 	default:
34283a58b20SKalyan Thota 		return;
34383a58b20SKalyan Thota 	}
34483a58b20SKalyan Thota 
34583a58b20SKalyan Thota 	ctx->pending_flush_mask |= BIT(DSPP_IDX);
34683a58b20SKalyan Thota }
34783a58b20SKalyan Thota 
dpu_hw_ctl_poll_reset_status(struct dpu_hw_ctl * ctx,u32 timeout_us)34825fdd593SJeykumar Sankaran static u32 dpu_hw_ctl_poll_reset_status(struct dpu_hw_ctl *ctx, u32 timeout_us)
34925fdd593SJeykumar Sankaran {
35025fdd593SJeykumar Sankaran 	struct dpu_hw_blk_reg_map *c = &ctx->hw;
35125fdd593SJeykumar Sankaran 	ktime_t timeout;
35225fdd593SJeykumar Sankaran 	u32 status;
35325fdd593SJeykumar Sankaran 
35425fdd593SJeykumar Sankaran 	timeout = ktime_add_us(ktime_get(), timeout_us);
35525fdd593SJeykumar Sankaran 
35625fdd593SJeykumar Sankaran 	/*
35725fdd593SJeykumar Sankaran 	 * it takes around 30us to have mdp finish resetting its ctl path
35825fdd593SJeykumar Sankaran 	 * poll every 50us so that reset should be completed at 1st poll
35925fdd593SJeykumar Sankaran 	 */
36025fdd593SJeykumar Sankaran 	do {
36125fdd593SJeykumar Sankaran 		status = DPU_REG_READ(c, CTL_SW_RESET);
36225fdd593SJeykumar Sankaran 		status &= 0x1;
36325fdd593SJeykumar Sankaran 		if (status)
36425fdd593SJeykumar Sankaran 			usleep_range(20, 50);
36525fdd593SJeykumar Sankaran 	} while (status && ktime_compare_safe(ktime_get(), timeout) < 0);
36625fdd593SJeykumar Sankaran 
36725fdd593SJeykumar Sankaran 	return status;
36825fdd593SJeykumar Sankaran }
36925fdd593SJeykumar Sankaran 
dpu_hw_ctl_reset_control(struct dpu_hw_ctl * ctx)37025fdd593SJeykumar Sankaran static int dpu_hw_ctl_reset_control(struct dpu_hw_ctl *ctx)
37125fdd593SJeykumar Sankaran {
37225fdd593SJeykumar Sankaran 	struct dpu_hw_blk_reg_map *c = &ctx->hw;
37325fdd593SJeykumar Sankaran 
37425fdd593SJeykumar Sankaran 	pr_debug("issuing hw ctl reset for ctl:%d\n", ctx->idx);
37525fdd593SJeykumar Sankaran 	DPU_REG_WRITE(c, CTL_SW_RESET, 0x1);
37625fdd593SJeykumar Sankaran 	if (dpu_hw_ctl_poll_reset_status(ctx, DPU_REG_RESET_TIMEOUT_US))
37725fdd593SJeykumar Sankaran 		return -EINVAL;
37825fdd593SJeykumar Sankaran 
37925fdd593SJeykumar Sankaran 	return 0;
38025fdd593SJeykumar Sankaran }
38125fdd593SJeykumar Sankaran 
dpu_hw_ctl_wait_reset_status(struct dpu_hw_ctl * ctx)38225fdd593SJeykumar Sankaran static int dpu_hw_ctl_wait_reset_status(struct dpu_hw_ctl *ctx)
38325fdd593SJeykumar Sankaran {
38425fdd593SJeykumar Sankaran 	struct dpu_hw_blk_reg_map *c = &ctx->hw;
38525fdd593SJeykumar Sankaran 	u32 status;
38625fdd593SJeykumar Sankaran 
38725fdd593SJeykumar Sankaran 	status = DPU_REG_READ(c, CTL_SW_RESET);
38825fdd593SJeykumar Sankaran 	status &= 0x01;
38925fdd593SJeykumar Sankaran 	if (!status)
39025fdd593SJeykumar Sankaran 		return 0;
39125fdd593SJeykumar Sankaran 
39225fdd593SJeykumar Sankaran 	pr_debug("hw ctl reset is set for ctl:%d\n", ctx->idx);
39325fdd593SJeykumar Sankaran 	if (dpu_hw_ctl_poll_reset_status(ctx, DPU_REG_RESET_TIMEOUT_US)) {
39425fdd593SJeykumar Sankaran 		pr_err("hw recovery is not complete for ctl:%d\n", ctx->idx);
39525fdd593SJeykumar Sankaran 		return -EINVAL;
39625fdd593SJeykumar Sankaran 	}
39725fdd593SJeykumar Sankaran 
39825fdd593SJeykumar Sankaran 	return 0;
39925fdd593SJeykumar Sankaran }
40025fdd593SJeykumar Sankaran 
dpu_hw_ctl_clear_all_blendstages(struct dpu_hw_ctl * ctx)40125fdd593SJeykumar Sankaran static void dpu_hw_ctl_clear_all_blendstages(struct dpu_hw_ctl *ctx)
40225fdd593SJeykumar Sankaran {
40325fdd593SJeykumar Sankaran 	struct dpu_hw_blk_reg_map *c = &ctx->hw;
40425fdd593SJeykumar Sankaran 	int i;
40525fdd593SJeykumar Sankaran 
40625fdd593SJeykumar Sankaran 	for (i = 0; i < ctx->mixer_count; i++) {
407a41cdb69SDmitry Baryshkov 		enum dpu_lm mixer_id = ctx->mixer_hw_caps[i].id;
408a41cdb69SDmitry Baryshkov 
409a41cdb69SDmitry Baryshkov 		DPU_REG_WRITE(c, CTL_LAYER(mixer_id), 0);
410a41cdb69SDmitry Baryshkov 		DPU_REG_WRITE(c, CTL_LAYER_EXT(mixer_id), 0);
411a41cdb69SDmitry Baryshkov 		DPU_REG_WRITE(c, CTL_LAYER_EXT2(mixer_id), 0);
412a41cdb69SDmitry Baryshkov 		DPU_REG_WRITE(c, CTL_LAYER_EXT3(mixer_id), 0);
41325fdd593SJeykumar Sankaran 	}
414b3652e87SKrishna Manikandan 
415b3652e87SKrishna Manikandan 	DPU_REG_WRITE(c, CTL_FETCH_PIPE_ACTIVE, 0);
41625fdd593SJeykumar Sankaran }
41725fdd593SJeykumar Sankaran 
4184488f71fSDmitry Baryshkov struct ctl_blend_config {
4194488f71fSDmitry Baryshkov 	int idx, shift, ext_shift;
4204488f71fSDmitry Baryshkov };
4214488f71fSDmitry Baryshkov 
4224488f71fSDmitry Baryshkov static const struct ctl_blend_config ctl_blend_config[][2] = {
4234488f71fSDmitry Baryshkov 	[SSPP_NONE] = { { -1 }, { -1 } },
4244488f71fSDmitry Baryshkov 	[SSPP_MAX] =  { { -1 }, { -1 } },
4254488f71fSDmitry Baryshkov 	[SSPP_VIG0] = { { 0, 0,  0  }, { 3, 0 } },
4264488f71fSDmitry Baryshkov 	[SSPP_VIG1] = { { 0, 3,  2  }, { 3, 4 } },
4274488f71fSDmitry Baryshkov 	[SSPP_VIG2] = { { 0, 6,  4  }, { 3, 8 } },
4284488f71fSDmitry Baryshkov 	[SSPP_VIG3] = { { 0, 26, 6  }, { 3, 12 } },
4294488f71fSDmitry Baryshkov 	[SSPP_RGB0] = { { 0, 9,  8  }, { -1 } },
4304488f71fSDmitry Baryshkov 	[SSPP_RGB1] = { { 0, 12, 10 }, { -1 } },
4314488f71fSDmitry Baryshkov 	[SSPP_RGB2] = { { 0, 15, 12 }, { -1 } },
4324488f71fSDmitry Baryshkov 	[SSPP_RGB3] = { { 0, 29, 14 }, { -1 } },
4334488f71fSDmitry Baryshkov 	[SSPP_DMA0] = { { 0, 18, 16 }, { 2, 8 } },
4344488f71fSDmitry Baryshkov 	[SSPP_DMA1] = { { 0, 21, 18 }, { 2, 12 } },
4354488f71fSDmitry Baryshkov 	[SSPP_DMA2] = { { 2, 0      }, { 2, 16 } },
4364488f71fSDmitry Baryshkov 	[SSPP_DMA3] = { { 2, 4      }, { 2, 20 } },
4374488f71fSDmitry Baryshkov 	[SSPP_DMA4] = { { 4, 0      }, { 4, 8 } },
4384488f71fSDmitry Baryshkov 	[SSPP_DMA5] = { { 4, 4      }, { 4, 12 } },
4394488f71fSDmitry Baryshkov 	[SSPP_CURSOR0] =  { { 1, 20 }, { -1 } },
4404488f71fSDmitry Baryshkov 	[SSPP_CURSOR1] =  { { 1, 26 }, { -1 } },
4414488f71fSDmitry Baryshkov };
4424488f71fSDmitry Baryshkov 
dpu_hw_ctl_setup_blendstage(struct dpu_hw_ctl * ctx,enum dpu_lm lm,struct dpu_hw_stage_cfg * stage_cfg)44325fdd593SJeykumar Sankaran static void dpu_hw_ctl_setup_blendstage(struct dpu_hw_ctl *ctx,
44425fdd593SJeykumar Sankaran 	enum dpu_lm lm, struct dpu_hw_stage_cfg *stage_cfg)
44525fdd593SJeykumar Sankaran {
44625fdd593SJeykumar Sankaran 	struct dpu_hw_blk_reg_map *c = &ctx->hw;
4472c36dc91SDmitry Baryshkov 	u32 mix, ext, mix_ext;
4484488f71fSDmitry Baryshkov 	u32 mixercfg[5] = { 0 };
44925fdd593SJeykumar Sankaran 	int i, j;
450dfdb3be4SColin Ian King 	int stages;
45125fdd593SJeykumar Sankaran 	int pipes_per_stage;
45225fdd593SJeykumar Sankaran 
45325fdd593SJeykumar Sankaran 	stages = _mixer_stages(ctx->mixer_hw_caps, ctx->mixer_count, lm);
45425fdd593SJeykumar Sankaran 	if (stages < 0)
45525fdd593SJeykumar Sankaran 		return;
45625fdd593SJeykumar Sankaran 
45725fdd593SJeykumar Sankaran 	if (test_bit(DPU_MIXER_SOURCESPLIT,
45825fdd593SJeykumar Sankaran 		&ctx->mixer_hw_caps->features))
45925fdd593SJeykumar Sankaran 		pipes_per_stage = PIPES_PER_STAGE;
46025fdd593SJeykumar Sankaran 	else
46125fdd593SJeykumar Sankaran 		pipes_per_stage = 1;
46225fdd593SJeykumar Sankaran 
4634488f71fSDmitry Baryshkov 	mixercfg[0] = CTL_MIXER_BORDER_OUT; /* always set BORDER_OUT */
46425fdd593SJeykumar Sankaran 
46525fdd593SJeykumar Sankaran 	if (!stage_cfg)
46625fdd593SJeykumar Sankaran 		goto exit;
46725fdd593SJeykumar Sankaran 
46825fdd593SJeykumar Sankaran 	for (i = 0; i <= stages; i++) {
46925fdd593SJeykumar Sankaran 		/* overflow to ext register if 'i + 1 > 7' */
47025fdd593SJeykumar Sankaran 		mix = (i + 1) & 0x7;
47125fdd593SJeykumar Sankaran 		ext = i >= 7;
4722c36dc91SDmitry Baryshkov 		mix_ext = (i + 1) & 0xf;
47325fdd593SJeykumar Sankaran 
47425fdd593SJeykumar Sankaran 		for (j = 0 ; j < pipes_per_stage; j++) {
47525fdd593SJeykumar Sankaran 			enum dpu_sspp_multirect_index rect_index =
47625fdd593SJeykumar Sankaran 				stage_cfg->multirect_index[i][j];
4774488f71fSDmitry Baryshkov 			enum dpu_sspp pipe = stage_cfg->stage[i][j];
4784488f71fSDmitry Baryshkov 			const struct ctl_blend_config *cfg =
4794488f71fSDmitry Baryshkov 				&ctl_blend_config[pipe][rect_index == DPU_SSPP_RECT_1];
48025fdd593SJeykumar Sankaran 
4814488f71fSDmitry Baryshkov 			/*
4824488f71fSDmitry Baryshkov 			 * CTL_LAYER has 3-bit field (and extra bits in EXT register),
4834488f71fSDmitry Baryshkov 			 * all EXT registers has 4-bit fields.
4844488f71fSDmitry Baryshkov 			 */
4851c1ded39SDmitry Baryshkov 			if (cfg->idx == -1) {
4861c1ded39SDmitry Baryshkov 				continue;
4871c1ded39SDmitry Baryshkov 			} else if (cfg->idx == 0) {
4884488f71fSDmitry Baryshkov 				mixercfg[0] |= mix << cfg->shift;
4894488f71fSDmitry Baryshkov 				mixercfg[1] |= ext << cfg->ext_shift;
49025fdd593SJeykumar Sankaran 			} else {
4914488f71fSDmitry Baryshkov 				mixercfg[cfg->idx] |= mix_ext << cfg->shift;
49225fdd593SJeykumar Sankaran 			}
49325fdd593SJeykumar Sankaran 		}
49425fdd593SJeykumar Sankaran 	}
49525fdd593SJeykumar Sankaran 
49625fdd593SJeykumar Sankaran exit:
4974488f71fSDmitry Baryshkov 	DPU_REG_WRITE(c, CTL_LAYER(lm), mixercfg[0]);
4984488f71fSDmitry Baryshkov 	DPU_REG_WRITE(c, CTL_LAYER_EXT(lm), mixercfg[1]);
4994488f71fSDmitry Baryshkov 	DPU_REG_WRITE(c, CTL_LAYER_EXT2(lm), mixercfg[2]);
5004488f71fSDmitry Baryshkov 	DPU_REG_WRITE(c, CTL_LAYER_EXT3(lm), mixercfg[3]);
501e92a4ae1SDmitry Baryshkov 	if ((test_bit(DPU_CTL_HAS_LAYER_EXT4, &ctx->caps->features)))
5024488f71fSDmitry Baryshkov 		DPU_REG_WRITE(c, CTL_LAYER_EXT4(lm), mixercfg[4]);
50325fdd593SJeykumar Sankaran }
50425fdd593SJeykumar Sankaran 
50573bfb790SKalyan Thota 
dpu_hw_ctl_intf_cfg_v1(struct dpu_hw_ctl * ctx,struct dpu_hw_intf_cfg * cfg)50673bfb790SKalyan Thota static void dpu_hw_ctl_intf_cfg_v1(struct dpu_hw_ctl *ctx,
50773bfb790SKalyan Thota 		struct dpu_hw_intf_cfg *cfg)
50873bfb790SKalyan Thota {
50973bfb790SKalyan Thota 	struct dpu_hw_blk_reg_map *c = &ctx->hw;
51073bfb790SKalyan Thota 	u32 intf_active = 0;
5116d084806SAbhinav Kumar 	u32 wb_active = 0;
51273bfb790SKalyan Thota 	u32 mode_sel = 0;
51373bfb790SKalyan Thota 
51444bf8704SKalyan Thota 	/* CTL_TOP[31:28] carries group_id to collate CTL paths
51544bf8704SKalyan Thota 	 * per VM. Explicitly disable it until VM support is
51644bf8704SKalyan Thota 	 * added in SW. Power on reset value is not disable.
51744bf8704SKalyan Thota 	 */
51844bf8704SKalyan Thota 	if ((test_bit(DPU_CTL_VM_CFG, &ctx->caps->features)))
51944bf8704SKalyan Thota 		mode_sel = CTL_DEFAULT_GROUP_ID  << 28;
52044bf8704SKalyan Thota 
52173bfb790SKalyan Thota 	if (cfg->intf_mode_sel == DPU_CTL_MODE_SEL_CMD)
52273bfb790SKalyan Thota 		mode_sel |= BIT(17);
52373bfb790SKalyan Thota 
52473bfb790SKalyan Thota 	intf_active = DPU_REG_READ(c, CTL_INTF_ACTIVE);
5256d084806SAbhinav Kumar 	wb_active = DPU_REG_READ(c, CTL_WB_ACTIVE);
5266d084806SAbhinav Kumar 
5276d084806SAbhinav Kumar 	if (cfg->intf)
52873bfb790SKalyan Thota 		intf_active |= BIT(cfg->intf - INTF_0);
52973bfb790SKalyan Thota 
5306d084806SAbhinav Kumar 	if (cfg->wb)
5316d084806SAbhinav Kumar 		wb_active |= BIT(cfg->wb - WB_0);
5326d084806SAbhinav Kumar 
53373bfb790SKalyan Thota 	DPU_REG_WRITE(c, CTL_TOP, mode_sel);
53473bfb790SKalyan Thota 	DPU_REG_WRITE(c, CTL_INTF_ACTIVE, intf_active);
5356d084806SAbhinav Kumar 	DPU_REG_WRITE(c, CTL_WB_ACTIVE, wb_active);
5366d084806SAbhinav Kumar 
53712aca1ceSKalyan Thota 	if (cfg->merge_3d)
53812aca1ceSKalyan Thota 		DPU_REG_WRITE(c, CTL_MERGE_3D_ACTIVE,
53912aca1ceSKalyan Thota 			      BIT(cfg->merge_3d - MERGE_3D_0));
540761c629dSKuogee Hsieh 
541761c629dSKuogee Hsieh 	if (cfg->dsc)
54277f6da90SVinod Koul 		DPU_REG_WRITE(c, CTL_DSC_ACTIVE, cfg->dsc);
54377f6da90SVinod Koul }
54473bfb790SKalyan Thota 
dpu_hw_ctl_intf_cfg(struct dpu_hw_ctl * ctx,struct dpu_hw_intf_cfg * cfg)54525fdd593SJeykumar Sankaran static void dpu_hw_ctl_intf_cfg(struct dpu_hw_ctl *ctx,
54625fdd593SJeykumar Sankaran 		struct dpu_hw_intf_cfg *cfg)
54725fdd593SJeykumar Sankaran {
54825fdd593SJeykumar Sankaran 	struct dpu_hw_blk_reg_map *c = &ctx->hw;
54925fdd593SJeykumar Sankaran 	u32 intf_cfg = 0;
55025fdd593SJeykumar Sankaran 
55125fdd593SJeykumar Sankaran 	intf_cfg |= (cfg->intf & 0xF) << 4;
55225fdd593SJeykumar Sankaran 
55325fdd593SJeykumar Sankaran 	if (cfg->mode_3d) {
55425fdd593SJeykumar Sankaran 		intf_cfg |= BIT(19);
55525fdd593SJeykumar Sankaran 		intf_cfg |= (cfg->mode_3d - 0x1) << 20;
55625fdd593SJeykumar Sankaran 	}
55725fdd593SJeykumar Sankaran 
5586d084806SAbhinav Kumar 	if (cfg->wb)
5596d084806SAbhinav Kumar 		intf_cfg |= (cfg->wb & 0x3) + 2;
5606d084806SAbhinav Kumar 
56125fdd593SJeykumar Sankaran 	switch (cfg->intf_mode_sel) {
56225fdd593SJeykumar Sankaran 	case DPU_CTL_MODE_SEL_VID:
56325fdd593SJeykumar Sankaran 		intf_cfg &= ~BIT(17);
56425fdd593SJeykumar Sankaran 		intf_cfg &= ~(0x3 << 15);
56525fdd593SJeykumar Sankaran 		break;
56625fdd593SJeykumar Sankaran 	case DPU_CTL_MODE_SEL_CMD:
56725fdd593SJeykumar Sankaran 		intf_cfg |= BIT(17);
56825fdd593SJeykumar Sankaran 		intf_cfg |= ((cfg->stream_sel & 0x3) << 15);
56925fdd593SJeykumar Sankaran 		break;
57025fdd593SJeykumar Sankaran 	default:
57125fdd593SJeykumar Sankaran 		pr_err("unknown interface type %d\n", cfg->intf_mode_sel);
57225fdd593SJeykumar Sankaran 		return;
57325fdd593SJeykumar Sankaran 	}
57425fdd593SJeykumar Sankaran 
57525fdd593SJeykumar Sankaran 	DPU_REG_WRITE(c, CTL_TOP, intf_cfg);
57625fdd593SJeykumar Sankaran }
57725fdd593SJeykumar Sankaran 
dpu_hw_ctl_reset_intf_cfg_v1(struct dpu_hw_ctl * ctx,struct dpu_hw_intf_cfg * cfg)578e1a950eeSAbhinav Kumar static void dpu_hw_ctl_reset_intf_cfg_v1(struct dpu_hw_ctl *ctx,
579e1a950eeSAbhinav Kumar 		struct dpu_hw_intf_cfg *cfg)
580e1a950eeSAbhinav Kumar {
581e1a950eeSAbhinav Kumar 	struct dpu_hw_blk_reg_map *c = &ctx->hw;
582e1a950eeSAbhinav Kumar 	u32 intf_active = 0;
5836d084806SAbhinav Kumar 	u32 wb_active = 0;
584e1a950eeSAbhinav Kumar 	u32 merge3d_active = 0;
585997ed53dSKuogee Hsieh 	u32 dsc_active;
586e1a950eeSAbhinav Kumar 
587e1a950eeSAbhinav Kumar 	/*
588e1a950eeSAbhinav Kumar 	 * This API resets each portion of the CTL path namely,
589e1a950eeSAbhinav Kumar 	 * clearing the sspps staged on the lm, merge_3d block,
5906d084806SAbhinav Kumar 	 * interfaces , writeback etc to ensure clean teardown of the pipeline.
591e1a950eeSAbhinav Kumar 	 * This will be used for writeback to begin with to have a
592e1a950eeSAbhinav Kumar 	 * proper teardown of the writeback session but upon further
593e1a950eeSAbhinav Kumar 	 * validation, this can be extended to all interfaces.
594e1a950eeSAbhinav Kumar 	 */
595e1a950eeSAbhinav Kumar 	if (cfg->merge_3d) {
596e1a950eeSAbhinav Kumar 		merge3d_active = DPU_REG_READ(c, CTL_MERGE_3D_ACTIVE);
597e1a950eeSAbhinav Kumar 		merge3d_active &= ~BIT(cfg->merge_3d - MERGE_3D_0);
598e1a950eeSAbhinav Kumar 		DPU_REG_WRITE(c, CTL_MERGE_3D_ACTIVE,
599e1a950eeSAbhinav Kumar 				merge3d_active);
600e1a950eeSAbhinav Kumar 	}
601e1a950eeSAbhinav Kumar 
602e1a950eeSAbhinav Kumar 	dpu_hw_ctl_clear_all_blendstages(ctx);
603e1a950eeSAbhinav Kumar 
604e1a950eeSAbhinav Kumar 	if (cfg->intf) {
605e1a950eeSAbhinav Kumar 		intf_active = DPU_REG_READ(c, CTL_INTF_ACTIVE);
606e1a950eeSAbhinav Kumar 		intf_active &= ~BIT(cfg->intf - INTF_0);
607e1a950eeSAbhinav Kumar 		DPU_REG_WRITE(c, CTL_INTF_ACTIVE, intf_active);
608e1a950eeSAbhinav Kumar 	}
6096d084806SAbhinav Kumar 
6106d084806SAbhinav Kumar 	if (cfg->wb) {
6116d084806SAbhinav Kumar 		wb_active = DPU_REG_READ(c, CTL_WB_ACTIVE);
6126d084806SAbhinav Kumar 		wb_active &= ~BIT(cfg->wb - WB_0);
6136d084806SAbhinav Kumar 		DPU_REG_WRITE(c, CTL_WB_ACTIVE, wb_active);
6146d084806SAbhinav Kumar 	}
615997ed53dSKuogee Hsieh 
616997ed53dSKuogee Hsieh 	if (cfg->dsc) {
617997ed53dSKuogee Hsieh 		dsc_active = DPU_REG_READ(c, CTL_DSC_ACTIVE);
618997ed53dSKuogee Hsieh 		dsc_active &= ~cfg->dsc;
619997ed53dSKuogee Hsieh 		DPU_REG_WRITE(c, CTL_DSC_ACTIVE, dsc_active);
620997ed53dSKuogee Hsieh 	}
621e1a950eeSAbhinav Kumar }
622e1a950eeSAbhinav Kumar 
dpu_hw_ctl_set_fetch_pipe_active(struct dpu_hw_ctl * ctx,unsigned long * fetch_active)623b3652e87SKrishna Manikandan static void dpu_hw_ctl_set_fetch_pipe_active(struct dpu_hw_ctl *ctx,
624b3652e87SKrishna Manikandan 	unsigned long *fetch_active)
625b3652e87SKrishna Manikandan {
626b3652e87SKrishna Manikandan 	int i;
627b3652e87SKrishna Manikandan 	u32 val = 0;
628b3652e87SKrishna Manikandan 
629b3652e87SKrishna Manikandan 	if (fetch_active) {
630b3652e87SKrishna Manikandan 		for (i = 0; i < SSPP_MAX; i++) {
631b3652e87SKrishna Manikandan 			if (test_bit(i, fetch_active) &&
632b3652e87SKrishna Manikandan 				fetch_tbl[i] != CTL_INVALID_BIT)
633b3652e87SKrishna Manikandan 				val |= BIT(fetch_tbl[i]);
634b3652e87SKrishna Manikandan 		}
635b3652e87SKrishna Manikandan 	}
636b3652e87SKrishna Manikandan 
637b3652e87SKrishna Manikandan 	DPU_REG_WRITE(&ctx->hw, CTL_FETCH_PIPE_ACTIVE, val);
638b3652e87SKrishna Manikandan }
639b3652e87SKrishna Manikandan 
_setup_ctl_ops(struct dpu_hw_ctl_ops * ops,unsigned long cap)64025fdd593SJeykumar Sankaran static void _setup_ctl_ops(struct dpu_hw_ctl_ops *ops,
64125fdd593SJeykumar Sankaran 		unsigned long cap)
64225fdd593SJeykumar Sankaran {
64373bfb790SKalyan Thota 	if (cap & BIT(DPU_CTL_ACTIVE_CFG)) {
64473bfb790SKalyan Thota 		ops->trigger_flush = dpu_hw_ctl_trigger_flush_v1;
64573bfb790SKalyan Thota 		ops->setup_intf_cfg = dpu_hw_ctl_intf_cfg_v1;
646e1a950eeSAbhinav Kumar 		ops->reset_intf_cfg = dpu_hw_ctl_reset_intf_cfg_v1;
647d8199c85SDmitry Baryshkov 		ops->update_pending_flush_intf =
648d8199c85SDmitry Baryshkov 			dpu_hw_ctl_update_pending_flush_intf_v1;
649c40e6c67SDmitry Baryshkov 		ops->update_pending_flush_merge_3d =
650c40e6c67SDmitry Baryshkov 			dpu_hw_ctl_update_pending_flush_merge_3d_v1;
6516d084806SAbhinav Kumar 		ops->update_pending_flush_wb = dpu_hw_ctl_update_pending_flush_wb_v1;
652761c629dSKuogee Hsieh 		ops->update_pending_flush_dsc =
653761c629dSKuogee Hsieh 			dpu_hw_ctl_update_pending_flush_dsc_v1;
65473bfb790SKalyan Thota 	} else {
65573bfb790SKalyan Thota 		ops->trigger_flush = dpu_hw_ctl_trigger_flush;
65673bfb790SKalyan Thota 		ops->setup_intf_cfg = dpu_hw_ctl_intf_cfg;
657d8199c85SDmitry Baryshkov 		ops->update_pending_flush_intf =
658d8199c85SDmitry Baryshkov 			dpu_hw_ctl_update_pending_flush_intf;
6596d084806SAbhinav Kumar 		ops->update_pending_flush_wb = dpu_hw_ctl_update_pending_flush_wb;
66073bfb790SKalyan Thota 	}
66125fdd593SJeykumar Sankaran 	ops->clear_pending_flush = dpu_hw_ctl_clear_pending_flush;
66225fdd593SJeykumar Sankaran 	ops->update_pending_flush = dpu_hw_ctl_update_pending_flush;
66325fdd593SJeykumar Sankaran 	ops->get_pending_flush = dpu_hw_ctl_get_pending_flush;
66425fdd593SJeykumar Sankaran 	ops->get_flush_register = dpu_hw_ctl_get_flush_register;
66525fdd593SJeykumar Sankaran 	ops->trigger_start = dpu_hw_ctl_trigger_start;
66678706798SAngeloGioacchino Del Regno 	ops->is_started = dpu_hw_ctl_is_started;
66725fdd593SJeykumar Sankaran 	ops->trigger_pending = dpu_hw_ctl_trigger_pending;
66825fdd593SJeykumar Sankaran 	ops->reset = dpu_hw_ctl_reset_control;
66925fdd593SJeykumar Sankaran 	ops->wait_reset_status = dpu_hw_ctl_wait_reset_status;
67025fdd593SJeykumar Sankaran 	ops->clear_all_blendstages = dpu_hw_ctl_clear_all_blendstages;
67125fdd593SJeykumar Sankaran 	ops->setup_blendstage = dpu_hw_ctl_setup_blendstage;
6723cde792aSDmitry Baryshkov 	ops->update_pending_flush_sspp = dpu_hw_ctl_update_pending_flush_sspp;
6733cde792aSDmitry Baryshkov 	ops->update_pending_flush_mixer = dpu_hw_ctl_update_pending_flush_mixer;
67483a58b20SKalyan Thota 	if (cap & BIT(DPU_CTL_DSPP_SUB_BLOCK_FLUSH))
67583a58b20SKalyan Thota 		ops->update_pending_flush_dspp = dpu_hw_ctl_update_pending_flush_dspp_sub_blocks;
67683a58b20SKalyan Thota 	else
6773cde792aSDmitry Baryshkov 		ops->update_pending_flush_dspp = dpu_hw_ctl_update_pending_flush_dspp;
67883a58b20SKalyan Thota 
679b3652e87SKrishna Manikandan 	if (cap & BIT(DPU_CTL_FETCH_ACTIVE))
680b3652e87SKrishna Manikandan 		ops->set_active_pipes = dpu_hw_ctl_set_fetch_pipe_active;
68125fdd593SJeykumar Sankaran };
68225fdd593SJeykumar Sankaran 
dpu_hw_ctl_init(const struct dpu_ctl_cfg * cfg,void __iomem * addr,u32 mixer_count,const struct dpu_lm_cfg * mixer)683babdb815SMarijn Suijten struct dpu_hw_ctl *dpu_hw_ctl_init(const struct dpu_ctl_cfg *cfg,
68425fdd593SJeykumar Sankaran 		void __iomem *addr,
685babdb815SMarijn Suijten 		u32 mixer_count,
686babdb815SMarijn Suijten 		const struct dpu_lm_cfg *mixer)
68725fdd593SJeykumar Sankaran {
68825fdd593SJeykumar Sankaran 	struct dpu_hw_ctl *c;
68925fdd593SJeykumar Sankaran 
69025fdd593SJeykumar Sankaran 	c = kzalloc(sizeof(*c), GFP_KERNEL);
69125fdd593SJeykumar Sankaran 	if (!c)
69225fdd593SJeykumar Sankaran 		return ERR_PTR(-ENOMEM);
69325fdd593SJeykumar Sankaran 
694babdb815SMarijn Suijten 	c->hw.blk_addr = addr + cfg->base;
695babdb815SMarijn Suijten 	c->hw.log_mask = DPU_DBG_MASK_CTL;
69625fdd593SJeykumar Sankaran 
69725fdd593SJeykumar Sankaran 	c->caps = cfg;
69825fdd593SJeykumar Sankaran 	_setup_ctl_ops(&c->ops, c->caps->features);
699babdb815SMarijn Suijten 	c->idx = cfg->id;
700babdb815SMarijn Suijten 	c->mixer_count = mixer_count;
701babdb815SMarijn Suijten 	c->mixer_hw_caps = mixer;
70225fdd593SJeykumar Sankaran 
70325fdd593SJeykumar Sankaran 	return c;
70425fdd593SJeykumar Sankaran }
70525fdd593SJeykumar Sankaran 
dpu_hw_ctl_destroy(struct dpu_hw_ctl * ctx)70625fdd593SJeykumar Sankaran void dpu_hw_ctl_destroy(struct dpu_hw_ctl *ctx)
70725fdd593SJeykumar Sankaran {
70825fdd593SJeykumar Sankaran 	kfree(ctx);
70925fdd593SJeykumar Sankaran }
710