File Index
Files and directories
Sign in
FILE

dcn401_hubp.c

File preview with syntax highlighting.

linux-6.19.14/drivers/gpu/drm/amd/display/dc/hubp/dcn401/dcn401_hubp.c C
   1/*
   2 * Copyright 2023 Advanced Micro Devices, Inc.
   3 *
   4 * Permission is hereby granted, free of charge, to any person obtaining a
   5 * copy of this software and associated documentation files (the "Software"),
   6 * to deal in the Software without restriction, including without limitation
   7 * the rights to use, copy, modify, merge, publish, distribute, sublicense,
   8 * and/or sell copies of the Software, and to permit persons to whom the
   9 * Software is furnished to do so, subject to the following conditions:
  10 *
  11 * The above copyright notice and this permission notice shall be included in
  12 * all copies or substantial portions of the Software.
  13 *
  14 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
  15 * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
  16 * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.  IN NO EVENT SHALL
  17 * THE COPYRIGHT HOLDER(S) OR AUTHOR(S) BE LIABLE FOR ANY CLAIM, DAMAGES OR
  18 * OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE,
  19 * ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
  20 * OTHER DEALINGS IN THE SOFTWARE.
  21 *
  22 * Authors: AMD
  23 *
  24 */
  25
  26#include "dm_services.h"
  27#include "dce_calcs.h"
  28#include "reg_helper.h"
  29#include "basics/conversion.h"
  30#include "dcn401_hubp.h"
  31#include "dal_asic_id.h"
  32
  33#define REG(reg)\
  34	hubp2->hubp_regs->reg
  35
  36#define CTX \
  37	hubp2->base.ctx
  38
  39#undef FN
  40#define FN(reg_name, field_name) \
  41	hubp2->hubp_shift->field_name, hubp2->hubp_mask->field_name
  42
  43void hubp401_program_3dlut_fl_addr(struct hubp *hubp,
  44	const struct dc_plane_address address)
  45{
  46	struct dcn20_hubp *hubp2 = TO_DCN20_HUBP(hubp);
  47
  48	REG_UPDATE(HUBP_3DLUT_ADDRESS_HIGH, HUBP_3DLUT_ADDRESS_HIGH, address.lut3d.addr.high_part);
  49	REG_WRITE(HUBP_3DLUT_ADDRESS_LOW, address.lut3d.addr.low_part);
  50}
  51
  52void hubp401_program_3dlut_fl_dlg_param(struct hubp *hubp, int refcyc_per_3dlut_group)
  53{
  54	struct dcn20_hubp *hubp2 = TO_DCN20_HUBP(hubp);
  55
  56	REG_UPDATE(HUBP_3DLUT_DLG_PARAM, REFCYC_PER_3DLUT_GROUP, refcyc_per_3dlut_group);
  57}
  58
  59void hubp401_enable_3dlut_fl(struct hubp *hubp, bool enable)
  60{
  61	struct dcn20_hubp *hubp2 = TO_DCN20_HUBP(hubp);
  62
  63	REG_UPDATE(HUBP_3DLUT_CONTROL, HUBP_3DLUT_ENABLE, enable ? 1 : 0);
  64}
  65
  66int hubp401_get_3dlut_fl_done(struct hubp *hubp)
  67{
  68	struct dcn20_hubp *hubp2 = TO_DCN20_HUBP(hubp);
  69	int ret;
  70
  71	REG_GET(HUBP_3DLUT_CONTROL, HUBP_3DLUT_DONE, &ret);
  72	return ret;
  73}
  74
  75void hubp401_program_3dlut_fl_addressing_mode(struct hubp *hubp, enum hubp_3dlut_fl_addressing_mode addr_mode)
  76{
  77	struct dcn20_hubp *hubp2 = TO_DCN20_HUBP(hubp);
  78
  79	REG_UPDATE(HUBP_3DLUT_CONTROL, HUBP_3DLUT_ADDRESSING_MODE, addr_mode);
  80}
  81
  82void hubp401_program_3dlut_fl_width(struct hubp *hubp, enum hubp_3dlut_fl_width width)
  83{
  84	struct dcn20_hubp *hubp2 = TO_DCN20_HUBP(hubp);
  85
  86	REG_UPDATE(HUBP_3DLUT_CONTROL, HUBP_3DLUT_WIDTH, width);
  87}
  88
  89void hubp401_program_3dlut_fl_tmz_protected(struct hubp *hubp, uint8_t protection_bits)
  90{
  91	struct dcn20_hubp *hubp2 = TO_DCN20_HUBP(hubp);
  92
  93	REG_UPDATE(HUBP_3DLUT_CONTROL, HUBP_3DLUT_TMZ, protection_bits);
  94}
  95
  96void hubp401_program_3dlut_fl_crossbar(struct hubp *hubp,
  97			enum hubp_3dlut_fl_crossbar_bit_slice bit_slice_y_g,
  98			enum hubp_3dlut_fl_crossbar_bit_slice bit_slice_cb_b,
  99			enum hubp_3dlut_fl_crossbar_bit_slice bit_slice_cr_r)
 100{
 101	struct dcn20_hubp *hubp2 = TO_DCN20_HUBP(hubp);
 102
 103	REG_UPDATE_3(HUBP_3DLUT_CONTROL,
 104			HUBP_3DLUT_CROSSBAR_SELECT_Y_G, bit_slice_y_g,
 105			HUBP_3DLUT_CROSSBAR_SELECT_CB_B, bit_slice_cb_b,
 106			HUBP_3DLUT_CROSSBAR_SELECT_CR_R, bit_slice_cr_r);
 107}
 108
 109void hubp401_update_3dlut_fl_bias_scale(struct hubp *hubp, uint16_t bias, uint16_t scale)
 110{
 111	struct dcn20_hubp *hubp2 = TO_DCN20_HUBP(hubp);
 112
 113	REG_UPDATE_2(_3DLUT_FL_BIAS_SCALE, HUBP0_3DLUT_FL_BIAS, bias, HUBP0_3DLUT_FL_SCALE, scale);
 114}
 115
 116void hubp401_program_3dlut_fl_mode(struct hubp *hubp, enum hubp_3dlut_fl_mode mode)
 117{
 118	struct dcn20_hubp *hubp2 = TO_DCN20_HUBP(hubp);
 119
 120	REG_UPDATE(_3DLUT_FL_CONFIG, HUBP0_3DLUT_FL_MODE, mode);
 121}
 122
 123void hubp401_program_3dlut_fl_format(struct hubp *hubp, enum hubp_3dlut_fl_format format)
 124{
 125	struct dcn20_hubp *hubp2 = TO_DCN20_HUBP(hubp);
 126
 127	REG_UPDATE(_3DLUT_FL_CONFIG, HUBP0_3DLUT_FL_FORMAT, format);
 128}
 129
 130void hubp401_program_3dlut_fl_config(
 131	struct hubp *hubp,
 132	struct hubp_fl_3dlut_config *cfg)
 133{
 134	struct dcn20_hubp *hubp2 = TO_DCN20_HUBP(hubp);
 135
 136	uint32_t mpc_width = {(cfg->width == 17) ? 0 : 1};
 137	uint32_t width = {cfg->width};
 138
 139	if (cfg->layout == DC_CM2_GPU_MEM_LAYOUT_1D_PACKED_LINEAR)
 140		width = (cfg->width == 17) ? 4916 : 35940;
 141
 142	REG_UPDATE_2(_3DLUT_FL_CONFIG,
 143		HUBP0_3DLUT_FL_MODE, cfg->mode,
 144		HUBP0_3DLUT_FL_FORMAT, cfg->format);
 145
 146	REG_UPDATE_2(_3DLUT_FL_BIAS_SCALE,
 147		HUBP0_3DLUT_FL_BIAS, cfg->bias,
 148		HUBP0_3DLUT_FL_SCALE, cfg->scale);
 149
 150	REG_UPDATE(HUBP_3DLUT_ADDRESS_HIGH,
 151		HUBP_3DLUT_ADDRESS_HIGH, cfg->address.lut3d.addr.high_part);
 152	REG_UPDATE(HUBP_3DLUT_ADDRESS_LOW,
 153		HUBP_3DLUT_ADDRESS_LOW, cfg->address.lut3d.addr.low_part);
 154
 155	//cross bar
 156	REG_UPDATE_8(HUBP_3DLUT_CONTROL,
 157		HUBP_3DLUT_MPC_WIDTH, mpc_width,
 158		HUBP_3DLUT_WIDTH, width,
 159		HUBP_3DLUT_CROSSBAR_SELECT_CR_R, cfg->crossbar_bit_slice_cr_r,
 160		HUBP_3DLUT_CROSSBAR_SELECT_Y_G, cfg->crossbar_bit_slice_y_g,
 161		HUBP_3DLUT_CROSSBAR_SELECT_CB_B, cfg->crossbar_bit_slice_cb_b,
 162		HUBP_3DLUT_ADDRESSING_MODE, cfg->addr_mode,
 163		HUBP_3DLUT_TMZ, cfg->protection_bits,
 164		HUBP_3DLUT_ENABLE, cfg->enabled ? 1 : 0);
 165}
 166
 167void hubp401_update_mall_sel(struct hubp *hubp, uint32_t mall_sel, bool c_cursor)
 168{
 169	struct dcn20_hubp *hubp2 = TO_DCN20_HUBP(hubp);
 170
 171	// Also cache cursor in MALL if using MALL for SS
 172	REG_UPDATE_2(DCHUBP_MALL_CONFIG, USE_MALL_SEL, mall_sel,
 173			USE_MALL_FOR_CURSOR, c_cursor);
 174
 175	REG_UPDATE_2(DCHUBP_MALL_CONFIG, MALL_PREF_CMD_TYPE, 1, MALL_PREF_MODE, 0);
 176}
 177
 178
 179void hubp401_init(struct hubp *hubp)
 180{
 181	hubp_reset(hubp);
 182}
 183
 184void hubp401_vready_at_or_After_vsync(struct hubp *hubp,
 185	union dml2_global_sync_programming *pipe_global_sync,
 186	struct dc_crtc_timing *timing)
 187{
 188	unsigned int vstartup_lines = pipe_global_sync->dcn4x.vstartup_lines;
 189	unsigned int vupdate_offset_pixels = pipe_global_sync->dcn4x.vupdate_offset_pixels;
 190	unsigned int vupdate_width_pixels = pipe_global_sync->dcn4x.vupdate_vupdate_width_pixels;
 191	unsigned int vready_offset_pixels = pipe_global_sync->dcn4x.vready_offset_pixels;
 192	unsigned int htotal = timing->h_total;
 193	unsigned int vblank_start = 0;
 194	unsigned int vblank_end = 0;
 195	unsigned int pixel_width = 0;
 196	uint32_t reg_value = 0;
 197	bool is_vready_at_or_after_vsync = false;
 198	struct dcn20_hubp *hubp2 = TO_DCN20_HUBP(hubp);
 199
 200	/*
 201	 * if (VSTARTUP_START - (VREADY_OFFSET+VUPDATE_WIDTH+VUPDATE_OFFSET)/htotal) <= OTG_V_BLANK_END
 202	 *	Set HUBP_VREADY_AT_OR_AFTER_VSYNC = 1
 203	 * else
 204	 *	Set HUBP_VREADY_AT_OR_AFTER_VSYNC = 0
 205	 */
 206	if (htotal != 0) {
 207		vblank_start = timing->v_total - timing->v_front_porch;
 208		vblank_end = vblank_start - timing->v_addressable - timing->v_border_top - timing->v_border_bottom;
 209		pixel_width = vready_offset_pixels + vupdate_width_pixels + vupdate_offset_pixels;
 210
 211		is_vready_at_or_after_vsync = (vstartup_lines - pixel_width / htotal) <= vblank_end;
 212
 213		if (is_vready_at_or_after_vsync)
 214			reg_value = 1;
 215	}
 216
 217	REG_UPDATE(DCHUBP_CNTL, HUBP_VREADY_AT_OR_AFTER_VSYNC, reg_value);
 218}
 219
 220void hubp401_program_requestor(
 221		struct hubp *hubp,
 222		struct dml2_display_rq_regs *rq_regs)
 223{
 224	struct dcn20_hubp *hubp2 = TO_DCN20_HUBP(hubp);
 225
 226	REG_UPDATE(HUBPRET_CONTROL,
 227			DET_BUF_PLANE1_BASE_ADDRESS, rq_regs->plane1_base_address);
 228	REG_SET_4(DCN_EXPANSION_MODE, 0,
 229			DRQ_EXPANSION_MODE, rq_regs->drq_expansion_mode,
 230			PRQ_EXPANSION_MODE, rq_regs->prq_expansion_mode,
 231			MRQ_EXPANSION_MODE, rq_regs->mrq_expansion_mode,
 232			CRQ_EXPANSION_MODE, rq_regs->crq_expansion_mode);
 233	REG_SET_6(DCHUBP_REQ_SIZE_CONFIG, 0,
 234		CHUNK_SIZE, rq_regs->rq_regs_l.chunk_size,
 235		MIN_CHUNK_SIZE, rq_regs->rq_regs_l.min_chunk_size,
 236		DPTE_GROUP_SIZE, rq_regs->rq_regs_l.dpte_group_size,
 237		VM_GROUP_SIZE, rq_regs->rq_regs_l.mpte_group_size,
 238		SWATH_HEIGHT, rq_regs->rq_regs_l.swath_height,
 239		PTE_ROW_HEIGHT_LINEAR, rq_regs->rq_regs_l.pte_row_height_linear);
 240	REG_SET_5(DCHUBP_REQ_SIZE_CONFIG_C, 0,
 241		CHUNK_SIZE_C, rq_regs->rq_regs_c.chunk_size,
 242		MIN_CHUNK_SIZE_C, rq_regs->rq_regs_c.min_chunk_size,
 243		DPTE_GROUP_SIZE_C, rq_regs->rq_regs_c.dpte_group_size,
 244		SWATH_HEIGHT_C, rq_regs->rq_regs_c.swath_height,
 245		PTE_ROW_HEIGHT_LINEAR_C, rq_regs->rq_regs_c.pte_row_height_linear);
 246}
 247
 248void hubp401_program_deadline(
 249		struct hubp *hubp,
 250		struct dml2_display_dlg_regs *dlg_attr,
 251		struct dml2_display_ttu_regs *ttu_attr)
 252{
 253	struct dcn20_hubp *hubp2 = TO_DCN20_HUBP(hubp);
 254
 255	/* put DLG in mission mode */
 256	REG_WRITE(HUBPREQ_DEBUG_DB, 1 << 8);
 257
 258	/* DLG - Per hubp */
 259	REG_SET_2(BLANK_OFFSET_0, 0,
 260		REFCYC_H_BLANK_END, dlg_attr->refcyc_h_blank_end,
 261		DLG_V_BLANK_END, dlg_attr->dlg_vblank_end);
 262
 263	REG_SET(BLANK_OFFSET_1, 0,
 264		MIN_DST_Y_NEXT_START, dlg_attr->min_dst_y_next_start);
 265
 266	REG_SET(DST_DIMENSIONS, 0,
 267		REFCYC_PER_HTOTAL, dlg_attr->refcyc_per_htotal);
 268
 269	REG_SET_2(DST_AFTER_SCALER, 0,
 270		REFCYC_X_AFTER_SCALER, dlg_attr->refcyc_x_after_scaler,
 271		DST_Y_AFTER_SCALER, dlg_attr->dst_y_after_scaler);
 272
 273	REG_SET(REF_FREQ_TO_PIX_FREQ, 0,
 274		REF_FREQ_TO_PIX_FREQ, dlg_attr->ref_freq_to_pix_freq);
 275
 276	/* DLG - Per luma/chroma */
 277	REG_SET(VBLANK_PARAMETERS_1, 0,
 278		REFCYC_PER_PTE_GROUP_VBLANK_L, dlg_attr->refcyc_per_pte_group_vblank_l);
 279
 280	if (REG(NOM_PARAMETERS_0))
 281		REG_SET(NOM_PARAMETERS_0, 0,
 282			DST_Y_PER_PTE_ROW_NOM_L, dlg_attr->dst_y_per_pte_row_nom_l);
 283
 284	if (REG(NOM_PARAMETERS_1))
 285		REG_SET(NOM_PARAMETERS_1, 0,
 286			REFCYC_PER_PTE_GROUP_NOM_L, dlg_attr->refcyc_per_pte_group_nom_l);
 287
 288	REG_SET(NOM_PARAMETERS_4, 0,
 289		DST_Y_PER_META_ROW_NOM_L, dlg_attr->dst_y_per_meta_row_nom_l);
 290
 291	REG_SET(NOM_PARAMETERS_5, 0,
 292		REFCYC_PER_META_CHUNK_NOM_L, dlg_attr->refcyc_per_meta_chunk_nom_l);
 293
 294	REG_SET_2(PER_LINE_DELIVERY, 0,
 295		REFCYC_PER_LINE_DELIVERY_L, dlg_attr->refcyc_per_line_delivery_l,
 296		REFCYC_PER_LINE_DELIVERY_C, dlg_attr->refcyc_per_line_delivery_c);
 297
 298	REG_SET(VBLANK_PARAMETERS_2, 0,
 299		REFCYC_PER_PTE_GROUP_VBLANK_C, dlg_attr->refcyc_per_pte_group_vblank_c);
 300
 301	if (REG(NOM_PARAMETERS_2))
 302		REG_SET(NOM_PARAMETERS_2, 0,
 303			DST_Y_PER_PTE_ROW_NOM_C, dlg_attr->dst_y_per_pte_row_nom_c);
 304
 305	if (REG(NOM_PARAMETERS_3))
 306		REG_SET(NOM_PARAMETERS_3, 0,
 307			REFCYC_PER_PTE_GROUP_NOM_C, dlg_attr->refcyc_per_pte_group_nom_c);
 308
 309	REG_SET(NOM_PARAMETERS_6, 0,
 310		DST_Y_PER_META_ROW_NOM_C, dlg_attr->dst_y_per_meta_row_nom_c);
 311
 312	REG_SET(NOM_PARAMETERS_7, 0,
 313		REFCYC_PER_META_CHUNK_NOM_C, dlg_attr->refcyc_per_meta_chunk_nom_c);
 314
 315	/* TTU - per hubp */
 316	REG_SET_2(DCN_TTU_QOS_WM, 0,
 317		QoS_LEVEL_LOW_WM, ttu_attr->qos_level_low_wm,
 318		QoS_LEVEL_HIGH_WM, ttu_attr->qos_level_high_wm);
 319
 320	/* TTU - per luma/chroma */
 321	/* Assumed surf0 is luma and 1 is chroma */
 322
 323	REG_SET_3(DCN_SURF0_TTU_CNTL0, 0,
 324		REFCYC_PER_REQ_DELIVERY, ttu_attr->refcyc_per_req_delivery_l,
 325		QoS_LEVEL_FIXED, ttu_attr->qos_level_fixed_l,
 326		QoS_RAMP_DISABLE, ttu_attr->qos_ramp_disable_l);
 327
 328	REG_SET_3(DCN_SURF1_TTU_CNTL0, 0,
 329		REFCYC_PER_REQ_DELIVERY, ttu_attr->refcyc_per_req_delivery_c,
 330		QoS_LEVEL_FIXED, ttu_attr->qos_level_fixed_c,
 331		QoS_RAMP_DISABLE, ttu_attr->qos_ramp_disable_c);
 332
 333	REG_SET_3(DCN_CUR0_TTU_CNTL0, 0,
 334		REFCYC_PER_REQ_DELIVERY, ttu_attr->refcyc_per_req_delivery_cur0,
 335		QoS_LEVEL_FIXED, ttu_attr->qos_level_fixed_cur0,
 336		QoS_RAMP_DISABLE, ttu_attr->qos_ramp_disable_cur0);
 337
 338	REG_SET(FLIP_PARAMETERS_1, 0,
 339		REFCYC_PER_PTE_GROUP_FLIP_L, dlg_attr->refcyc_per_pte_group_flip_l);
 340	REG_SET(HUBP_3DLUT_DLG_PARAM, 0, REFCYC_PER_3DLUT_GROUP, dlg_attr->refcyc_per_tdlut_group);
 341
 342	REG_UPDATE(DCN_DMDATA_VM_CNTL,
 343			REFCYC_PER_VM_DMDATA, dlg_attr->refcyc_per_vm_dmdata);
 344}
 345
 346void hubp401_setup(
 347		struct hubp *hubp,
 348	    struct dml2_dchub_per_pipe_register_set *pipe_regs,
 349		union dml2_global_sync_programming *pipe_global_sync,
 350		struct dc_crtc_timing *timing)
 351{
 352	/* otg is locked when this func is called. Register are double buffered.
 353	 * disable the requestors is not needed
 354	 */
 355	hubp401_vready_at_or_After_vsync(hubp, pipe_global_sync, timing);
 356	hubp401_program_requestor(hubp, &pipe_regs->rq_regs);
 357	hubp401_program_deadline(hubp, &pipe_regs->dlg_regs, &pipe_regs->ttu_regs);
 358}
 359
 360void hubp401_setup_interdependent(
 361		struct hubp *hubp,
 362		struct dml2_dchub_per_pipe_register_set *pipe_regs)
 363{
 364	struct dcn20_hubp *hubp2 = TO_DCN20_HUBP(hubp);
 365
 366	REG_SET_2(PREFETCH_SETTINGS, 0,
 367			DST_Y_PREFETCH, pipe_regs->dlg_regs.dst_y_prefetch,
 368			VRATIO_PREFETCH, pipe_regs->dlg_regs.vratio_prefetch);
 369
 370	REG_SET(PREFETCH_SETTINGS_C, 0,
 371			VRATIO_PREFETCH_C, pipe_regs->dlg_regs.vratio_prefetch_c);
 372
 373	REG_SET_2(VBLANK_PARAMETERS_0, 0,
 374		DST_Y_PER_VM_VBLANK, pipe_regs->dlg_regs.dst_y_per_vm_vblank,
 375		DST_Y_PER_ROW_VBLANK, pipe_regs->dlg_regs.dst_y_per_row_vblank);
 376
 377	REG_SET_2(FLIP_PARAMETERS_0, 0,
 378		DST_Y_PER_VM_FLIP, pipe_regs->dlg_regs.dst_y_per_vm_flip,
 379		DST_Y_PER_ROW_FLIP, pipe_regs->dlg_regs.dst_y_per_row_flip);
 380
 381	REG_SET(VBLANK_PARAMETERS_3, 0,
 382		REFCYC_PER_META_CHUNK_VBLANK_L, pipe_regs->dlg_regs.refcyc_per_meta_chunk_vblank_l);
 383
 384	REG_SET(VBLANK_PARAMETERS_4, 0,
 385		REFCYC_PER_META_CHUNK_VBLANK_C, pipe_regs->dlg_regs.refcyc_per_meta_chunk_vblank_c);
 386
 387	REG_SET(FLIP_PARAMETERS_2, 0,
 388		REFCYC_PER_META_CHUNK_FLIP_L, pipe_regs->dlg_regs.refcyc_per_meta_chunk_flip_l);
 389
 390	REG_SET_2(PER_LINE_DELIVERY_PRE, 0,
 391		REFCYC_PER_LINE_DELIVERY_PRE_L, pipe_regs->dlg_regs.refcyc_per_line_delivery_pre_l,
 392		REFCYC_PER_LINE_DELIVERY_PRE_C, pipe_regs->dlg_regs.refcyc_per_line_delivery_pre_c);
 393
 394	REG_SET(DCN_SURF0_TTU_CNTL1, 0,
 395		REFCYC_PER_REQ_DELIVERY_PRE,
 396		pipe_regs->ttu_regs.refcyc_per_req_delivery_pre_l);
 397	REG_SET(DCN_SURF1_TTU_CNTL1, 0,
 398		REFCYC_PER_REQ_DELIVERY_PRE,
 399		pipe_regs->ttu_regs.refcyc_per_req_delivery_pre_c);
 400	REG_SET(DCN_CUR0_TTU_CNTL1, 0,
 401		REFCYC_PER_REQ_DELIVERY_PRE, pipe_regs->ttu_regs.refcyc_per_req_delivery_pre_cur0);
 402
 403	REG_SET_2(DCN_GLOBAL_TTU_CNTL, 0,
 404		MIN_TTU_VBLANK, pipe_regs->ttu_regs.min_ttu_vblank,
 405		QoS_LEVEL_FLIP, pipe_regs->ttu_regs.qos_level_flip);
 406}
 407
 408
 409bool hubp401_program_surface_flip_and_addr(
 410	struct hubp *hubp,
 411	const struct dc_plane_address *address,
 412	bool flip_immediate)
 413{
 414	struct dcn20_hubp *hubp2 = TO_DCN20_HUBP(hubp);
 415
 416	//program flip type
 417	REG_UPDATE(DCSURF_FLIP_CONTROL,
 418			SURFACE_FLIP_TYPE, flip_immediate);
 419
 420	// Program VMID reg
 421	if (flip_immediate == 0)
 422		REG_UPDATE(VMID_SETTINGS_0,
 423			VMID, address->vmid);
 424
 425	if (address->type == PLN_ADDR_TYPE_GRPH_STEREO) {
 426		REG_UPDATE(DCSURF_FLIP_CONTROL, SURFACE_FLIP_MODE_FOR_STEREOSYNC, 0);
 427		REG_UPDATE(DCSURF_FLIP_CONTROL, SURFACE_FLIP_IN_STEREOSYNC, 0x1);
 428
 429	} else {
 430		// turn off stereo if not in stereo
 431		REG_UPDATE(DCSURF_FLIP_CONTROL, SURFACE_FLIP_MODE_FOR_STEREOSYNC, 0x0);
 432		REG_UPDATE(DCSURF_FLIP_CONTROL, SURFACE_FLIP_IN_STEREOSYNC, 0x0);
 433	}
 434
 435	/* HW automatically latch rest of address register on write to
 436	 * DCSURF_PRIMARY_SURFACE_ADDRESS if SURFACE_UPDATE_LOCK is not used
 437	 *
 438	 * program high first and then the low addr, order matters!
 439	 */
 440	switch (address->type) {
 441	case PLN_ADDR_TYPE_GRAPHICS:
 442		if (address->grph.addr.quad_part == 0)
 443			break;
 444
 445		REG_UPDATE(DCSURF_SURFACE_CONTROL,
 446				PRIMARY_SURFACE_TMZ, address->tmz_surface);
 447
 448		REG_SET(DCSURF_PRIMARY_SURFACE_ADDRESS_HIGH, 0,
 449				PRIMARY_SURFACE_ADDRESS_HIGH,
 450				address->grph.addr.high_part);
 451
 452		REG_SET(DCSURF_PRIMARY_SURFACE_ADDRESS, 0,
 453				PRIMARY_SURFACE_ADDRESS,
 454				address->grph.addr.low_part);
 455		break;
 456	case PLN_ADDR_TYPE_VIDEO_PROGRESSIVE:
 457		if (address->video_progressive.luma_addr.quad_part == 0
 458				|| address->video_progressive.chroma_addr.quad_part == 0)
 459			break;
 460
 461		REG_UPDATE_2(DCSURF_SURFACE_CONTROL,
 462				PRIMARY_SURFACE_TMZ, address->tmz_surface,
 463				PRIMARY_SURFACE_TMZ_C, address->tmz_surface);
 464
 465		REG_SET(DCSURF_PRIMARY_SURFACE_ADDRESS_HIGH_C, 0,
 466				PRIMARY_SURFACE_ADDRESS_HIGH_C,
 467				address->video_progressive.chroma_addr.high_part);
 468
 469		REG_SET(DCSURF_PRIMARY_SURFACE_ADDRESS_C, 0,
 470				PRIMARY_SURFACE_ADDRESS_C,
 471				address->video_progressive.chroma_addr.low_part);
 472
 473		REG_SET(DCSURF_PRIMARY_SURFACE_ADDRESS_HIGH, 0,
 474				PRIMARY_SURFACE_ADDRESS_HIGH,
 475				address->video_progressive.luma_addr.high_part);
 476
 477		REG_SET(DCSURF_PRIMARY_SURFACE_ADDRESS, 0,
 478				PRIMARY_SURFACE_ADDRESS,
 479				address->video_progressive.luma_addr.low_part);
 480		break;
 481	case PLN_ADDR_TYPE_GRPH_STEREO:
 482		if (address->grph_stereo.left_addr.quad_part == 0)
 483			break;
 484		if (address->grph_stereo.right_addr.quad_part == 0)
 485			break;
 486
 487		REG_UPDATE_4(DCSURF_SURFACE_CONTROL,
 488				PRIMARY_SURFACE_TMZ, address->tmz_surface,
 489				PRIMARY_SURFACE_TMZ_C, address->tmz_surface,
 490				SECONDARY_SURFACE_TMZ, address->tmz_surface,
 491				SECONDARY_SURFACE_TMZ_C, address->tmz_surface);
 492
 493		REG_SET(DCSURF_SECONDARY_SURFACE_ADDRESS_HIGH_C, 0,
 494				SECONDARY_SURFACE_ADDRESS_HIGH_C,
 495				address->grph_stereo.right_alpha_addr.high_part);
 496
 497		REG_SET(DCSURF_SECONDARY_SURFACE_ADDRESS_C, 0,
 498				SECONDARY_SURFACE_ADDRESS_C,
 499				address->grph_stereo.right_alpha_addr.low_part);
 500
 501		REG_SET(DCSURF_SECONDARY_SURFACE_ADDRESS_HIGH, 0,
 502				SECONDARY_SURFACE_ADDRESS_HIGH,
 503				address->grph_stereo.right_addr.high_part);
 504
 505		REG_SET(DCSURF_SECONDARY_SURFACE_ADDRESS, 0,
 506				SECONDARY_SURFACE_ADDRESS,
 507				address->grph_stereo.right_addr.low_part);
 508
 509		REG_SET(DCSURF_PRIMARY_SURFACE_ADDRESS_HIGH_C, 0,
 510				PRIMARY_SURFACE_ADDRESS_HIGH_C,
 511				address->grph_stereo.left_alpha_addr.high_part);
 512
 513		REG_SET(DCSURF_PRIMARY_SURFACE_ADDRESS_C, 0,
 514				PRIMARY_SURFACE_ADDRESS_C,
 515				address->grph_stereo.left_alpha_addr.low_part);
 516
 517		REG_SET(DCSURF_PRIMARY_SURFACE_ADDRESS_HIGH, 0,
 518				PRIMARY_SURFACE_ADDRESS_HIGH,
 519				address->grph_stereo.left_addr.high_part);
 520
 521		REG_SET(DCSURF_PRIMARY_SURFACE_ADDRESS, 0,
 522				PRIMARY_SURFACE_ADDRESS,
 523				address->grph_stereo.left_addr.low_part);
 524		break;
 525	case PLN_ADDR_TYPE_RGBEA:
 526		if (address->rgbea.addr.quad_part == 0
 527				|| address->rgbea.alpha_addr.quad_part == 0)
 528			break;
 529
 530		REG_UPDATE_2(DCSURF_SURFACE_CONTROL,
 531				PRIMARY_SURFACE_TMZ, address->tmz_surface,
 532				PRIMARY_SURFACE_TMZ_C, address->tmz_surface);
 533
 534		REG_SET(DCSURF_PRIMARY_SURFACE_ADDRESS_HIGH_C, 0,
 535				PRIMARY_SURFACE_ADDRESS_HIGH_C,
 536				address->rgbea.alpha_addr.high_part);
 537
 538		REG_SET(DCSURF_PRIMARY_SURFACE_ADDRESS_C, 0,
 539				PRIMARY_SURFACE_ADDRESS_C,
 540				address->rgbea.alpha_addr.low_part);
 541
 542		REG_SET(DCSURF_PRIMARY_SURFACE_ADDRESS_HIGH, 0,
 543				PRIMARY_SURFACE_ADDRESS_HIGH,
 544				address->rgbea.addr.high_part);
 545
 546		REG_SET(DCSURF_PRIMARY_SURFACE_ADDRESS, 0,
 547				PRIMARY_SURFACE_ADDRESS,
 548				address->rgbea.addr.low_part);
 549		break;
 550	default:
 551		BREAK_TO_DEBUGGER();
 552		break;
 553	}
 554
 555	hubp->request_address = *address;
 556
 557	return true;
 558}
 559
 560void hubp401_clear_tiling(struct hubp *hubp)
 561{
 562	struct dcn20_hubp *hubp2 = TO_DCN20_HUBP(hubp);
 563
 564	REG_UPDATE(DCHUBP_REQ_SIZE_CONFIG, SWATH_HEIGHT, 0);
 565	REG_UPDATE(DCSURF_TILING_CONFIG, SW_MODE, DC_SW_LINEAR);
 566
 567	REG_UPDATE_2(DCSURF_SURFACE_CONTROL,
 568		     PRIMARY_SURFACE_DCC_EN, 0,
 569		     SECONDARY_SURFACE_DCC_EN, 0);
 570}
 571
 572void hubp401_dcc_control(struct hubp *hubp,
 573		struct dc_plane_dcc_param *dcc)
 574{
 575	struct dcn20_hubp *hubp2 = TO_DCN20_HUBP(hubp);
 576
 577	REG_UPDATE_2(DCSURF_SURFACE_CONTROL,
 578		PRIMARY_SURFACE_DCC_EN, dcc->enable,
 579		SECONDARY_SURFACE_DCC_EN, dcc->enable);
 580}
 581
 582void hubp401_program_tiling(
 583	struct dcn20_hubp *hubp2,
 584	const struct dc_tiling_info *info,
 585	const enum surface_pixel_format pixel_format)
 586{
 587	/* DCSURF_ADDR_CONFIG still shows up in reg spec, but does not need to be programmed for DCN4x
 588	 * All 4 fields NUM_PIPES, PIPE_INTERLEAVE, MAX_COMPRESSED_FRAGS and NUM_PKRS are irrelevant.
 589	 *
 590	 * DIM_TYPE field in DCSURF_TILING for Display is always 1 (2D dimension) which is HW default.
 591	 */
 592	 REG_UPDATE(DCSURF_TILING_CONFIG, SW_MODE, info->gfx_addr3.swizzle);
 593}
 594
 595void hubp401_program_size(
 596	struct hubp *hubp,
 597	enum surface_pixel_format format,
 598	const struct plane_size *plane_size,
 599	struct dc_plane_dcc_param *dcc)
 600{
 601	struct dcn20_hubp *hubp2 = TO_DCN20_HUBP(hubp);
 602	uint32_t pitch, pitch_c;
 603	bool use_pitch_c = false;
 604
 605	/* Program data pitch (calculation from addrlib)
 606	 * 444 or 420 luma
 607	 */
 608	use_pitch_c = format >= SURFACE_PIXEL_FORMAT_VIDEO_BEGIN
 609		&& format < SURFACE_PIXEL_FORMAT_SUBSAMPLE_END;
 610	use_pitch_c = use_pitch_c
 611		|| (format == SURFACE_PIXEL_FORMAT_GRPH_RGBE_ALPHA);
 612	if (use_pitch_c) {
 613		ASSERT(plane_size->chroma_pitch != 0);
 614		/* Chroma pitch zero can cause system hang! */
 615
 616		pitch = plane_size->surface_pitch - 1;
 617		pitch_c = plane_size->chroma_pitch - 1;
 618	} else {
 619		pitch = plane_size->surface_pitch - 1;
 620		pitch_c = 0;
 621	}
 622
 623	REG_UPDATE(DCSURF_SURFACE_PITCH, PITCH, pitch);
 624
 625	if (use_pitch_c)
 626		REG_UPDATE(DCSURF_SURFACE_PITCH_C, PITCH_C, pitch_c);
 627}
 628
 629void hubp401_program_surface_config(
 630	struct hubp *hubp,
 631	enum surface_pixel_format format,
 632	struct dc_tiling_info *tiling_info,
 633	struct plane_size *plane_size,
 634	enum dc_rotation_angle rotation,
 635	struct dc_plane_dcc_param *dcc,
 636	bool horizontal_mirror,
 637	unsigned int compat_level)
 638{
 639	struct dcn20_hubp *hubp2 = TO_DCN20_HUBP(hubp);
 640
 641	hubp401_dcc_control(hubp, dcc);
 642	hubp401_program_tiling(hubp2, tiling_info, format);
 643	hubp401_program_size(hubp, format, plane_size, dcc);
 644	hubp2_program_rotation(hubp, rotation, horizontal_mirror);
 645	hubp2_program_pixel_format(hubp, format);
 646}
 647
 648void hubp401_set_viewport(
 649	struct hubp *hubp,
 650	const struct rect *viewport,
 651	const struct rect *viewport_c)
 652{
 653	struct dcn20_hubp *hubp2 = TO_DCN20_HUBP(hubp);
 654
 655	REG_SET_2(DCSURF_PRI_VIEWPORT_DIMENSION, 0,
 656		  PRI_VIEWPORT_WIDTH, viewport->width,
 657		  PRI_VIEWPORT_HEIGHT, viewport->height);
 658
 659	REG_SET_2(DCSURF_PRI_VIEWPORT_START, 0,
 660		  PRI_VIEWPORT_X_START, viewport->x,
 661		  PRI_VIEWPORT_Y_START, viewport->y);
 662
 663	/*for stereo*/
 664	REG_SET_2(DCSURF_SEC_VIEWPORT_DIMENSION, 0,
 665		  SEC_VIEWPORT_WIDTH, viewport->width,
 666		  SEC_VIEWPORT_HEIGHT, viewport->height);
 667
 668	REG_SET_2(DCSURF_SEC_VIEWPORT_START, 0,
 669		  SEC_VIEWPORT_X_START, viewport->x,
 670		  SEC_VIEWPORT_Y_START, viewport->y);
 671
 672	/* DC supports NV12 only at the moment */
 673	REG_SET_2(DCSURF_PRI_VIEWPORT_DIMENSION_C, 0,
 674		  PRI_VIEWPORT_WIDTH_C, viewport_c->width,
 675		  PRI_VIEWPORT_HEIGHT_C, viewport_c->height);
 676
 677	REG_SET_2(DCSURF_PRI_VIEWPORT_START_C, 0,
 678		  PRI_VIEWPORT_X_START_C, viewport_c->x,
 679		  PRI_VIEWPORT_Y_START_C, viewport_c->y);
 680
 681	REG_SET_2(DCSURF_SEC_VIEWPORT_DIMENSION_C, 0,
 682		  SEC_VIEWPORT_WIDTH_C, viewport_c->width,
 683		  SEC_VIEWPORT_HEIGHT_C, viewport_c->height);
 684
 685	REG_SET_2(DCSURF_SEC_VIEWPORT_START_C, 0,
 686		  SEC_VIEWPORT_X_START_C, viewport_c->x,
 687		  SEC_VIEWPORT_Y_START_C, viewport_c->y);
 688}
 689
 690void hubp401_program_mcache_id_and_split_coordinate(
 691	struct hubp *hubp,
 692	struct dml2_hubp_pipe_mcache_regs *mcache_regs)
 693{
 694	struct dcn20_hubp *hubp2 = TO_DCN20_HUBP(hubp);
 695
 696	REG_SET_8(DCHUBP_MCACHEID_CONFIG, 0,
 697		MCACHEID_REG_READ_1H_P0, mcache_regs->main.p0.mcache_id_first,
 698		MCACHEID_REG_READ_2H_P0, mcache_regs->main.p0.mcache_id_second,
 699		MCACHEID_REG_READ_1H_P1, mcache_regs->main.p1.mcache_id_first,
 700		MCACHEID_REG_READ_2H_P1, mcache_regs->main.p1.mcache_id_second,
 701		MCACHEID_MALL_PREF_1H_P0, mcache_regs->mall.p0.mcache_id_first,
 702		MCACHEID_MALL_PREF_2H_P0, mcache_regs->mall.p0.mcache_id_second,
 703		MCACHEID_MALL_PREF_1H_P1, mcache_regs->mall.p1.mcache_id_first,
 704		MCACHEID_MALL_PREF_2H_P1, mcache_regs->mall.p1.mcache_id_second);
 705
 706	REG_SET_2(DCSURF_VIEWPORT_MCACHE_SPLIT_COORDINATE, 0,
 707		VIEWPORT_MCACHE_SPLIT_COORDINATE, mcache_regs->main.p0.split_location,
 708		VIEWPORT_MCACHE_SPLIT_COORDINATE_C, mcache_regs->main.p1.split_location);
 709}
 710void hubp401_set_flip_int(struct hubp *hubp)
 711{
 712	struct dcn20_hubp *hubp2 = TO_DCN20_HUBP(hubp);
 713
 714	REG_UPDATE(DCSURF_SURFACE_FLIP_INTERRUPT,
 715		SURFACE_FLIP_INT_MASK, 1);
 716
 717	return;
 718}
 719
 720bool hubp401_in_blank(struct hubp *hubp)
 721{
 722	struct dcn20_hubp *hubp2 = TO_DCN20_HUBP(hubp);
 723	uint32_t in_blank;
 724
 725	REG_GET(DCHUBP_CNTL, HUBP_IN_BLANK, &in_blank);
 726	return in_blank ? true : false;
 727}
 728
 729
 730void hubp401_cursor_set_position(
 731	struct hubp *hubp,
 732	const struct dc_cursor_position *pos,
 733	const struct dc_cursor_mi_param *param)
 734{
 735	struct dcn20_hubp *hubp2 = TO_DCN20_HUBP(hubp);
 736	int rec_x_offset = pos->x - pos->x_hotspot;
 737	int rec_y_offset = pos->y - pos->y_hotspot;
 738	int dst_x_offset;
 739	int x_pos_viewport = 0;
 740	int x_hot_viewport = 0;
 741	uint32_t cur_en = pos->enable ? 1 : 0;
 742
 743	hubp->curs_pos = *pos;
 744
 745	/* Recout is zero for pipes if the entire dst_rect is contained
 746	 * within preceeding ODM slices.
 747	 */
 748	if (param->recout.width) {
 749		x_pos_viewport = pos->x * param->viewport.width / param->recout.width;
 750		x_hot_viewport = pos->x_hotspot * param->viewport.width / param->recout.width;
 751	} else {
 752		ASSERT(!cur_en || pos->x == 0);
 753		ASSERT(!cur_en || pos->x_hotspot == 0);
 754	}
 755
 756	/*
 757	 * Guard aganst cursor_set_position() from being called with invalid
 758	 * attributes
 759	 */
 760	if (hubp->curs_attr.address.quad_part == 0)
 761		return;
 762
 763	/* Translate the x position of the cursor from rect
 764	 * space into viewport space. CURSOR_DST_X_OFFSET
 765	 * is the offset relative to viewport start position.
 766	 */
 767	dst_x_offset = x_pos_viewport - x_hot_viewport *
 768			(1 + hubp->curs_attr.attribute_flags.bits.ENABLE_MAGNIFICATION);
 769	dst_x_offset = (dst_x_offset >= 0) ? dst_x_offset : 0;
 770	dst_x_offset *= param->ref_clk_khz;
 771	dst_x_offset /= param->pixel_clk_khz;
 772
 773	ASSERT(param->h_scale_ratio.value);
 774
 775	if (param->h_scale_ratio.value)
 776		dst_x_offset = dc_fixpt_floor(dc_fixpt_div(
 777			dc_fixpt_from_int(dst_x_offset),
 778			param->h_scale_ratio));
 779
 780	if (hubp->pos.cur_ctl.bits.cur_enable != cur_en) {
 781		if (cur_en && REG_READ(CURSOR_SURFACE_ADDRESS) == 0)
 782			hubp->funcs->set_cursor_attributes(hubp, &hubp->curs_attr);
 783
 784		if (!hubp->cursor_offload)
 785			REG_UPDATE(CURSOR_CONTROL,
 786				CURSOR_ENABLE, cur_en);
 787	}
 788
 789	if (!hubp->cursor_offload) {
 790		REG_SET_2(CURSOR_POSITION, 0,
 791			CURSOR_X_POSITION, pos->x,
 792			CURSOR_Y_POSITION, pos->y);
 793
 794		REG_SET_2(CURSOR_HOT_SPOT, 0,
 795			CURSOR_HOT_SPOT_X, pos->x_hotspot,
 796			CURSOR_HOT_SPOT_Y, pos->y_hotspot);
 797
 798		REG_SET(CURSOR_DST_OFFSET, 0,
 799			CURSOR_DST_X_OFFSET, dst_x_offset);
 800	}
 801	/* Cursor Position Register Config */
 802	hubp->pos.cur_ctl.bits.cur_enable = cur_en;
 803	hubp->pos.position.bits.x_pos = pos->x;
 804	hubp->pos.position.bits.y_pos = pos->y;
 805	hubp->pos.hot_spot.bits.x_hot = pos->x_hotspot;
 806	hubp->pos.hot_spot.bits.y_hot = pos->y_hotspot;
 807	hubp->pos.dst_offset.bits.dst_x_offset = dst_x_offset;
 808	/* Cursor Rectangle Cache
 809	 * Cursor bitmaps have different hotspot values
 810	 * There's a possibility that the above logic returns a negative value,
 811	 * so we clamp them to 0
 812	 */
 813	if (rec_x_offset < 0)
 814		rec_x_offset = 0;
 815	if (rec_y_offset < 0)
 816		rec_y_offset = 0;
 817	/* Save necessary cursor info x, y position. w, h is saved in attribute func. */
 818	hubp->cur_rect.x = rec_x_offset + param->recout.x;
 819	hubp->cur_rect.y = rec_y_offset + param->recout.y;
 820}
 821
 822void hubp401_read_state(struct hubp *hubp)
 823{
 824	struct dcn20_hubp *hubp2 = TO_DCN20_HUBP(hubp);
 825	struct dcn_hubp_state *s = &hubp2->state;
 826	struct _vcs_dpi_display_dlg_regs_st *dlg_attr = &s->dlg_attr;
 827	struct _vcs_dpi_display_ttu_regs_st *ttu_attr = &s->ttu_attr;
 828	struct _vcs_dpi_display_rq_regs_st *rq_regs = &s->rq_regs;
 829
 830	/* Requester */
 831	REG_GET(HUBPRET_CONTROL,
 832			DET_BUF_PLANE1_BASE_ADDRESS, &rq_regs->plane1_base_address);
 833	REG_GET_4(DCN_EXPANSION_MODE,
 834			DRQ_EXPANSION_MODE, &rq_regs->drq_expansion_mode,
 835			PRQ_EXPANSION_MODE, &rq_regs->prq_expansion_mode,
 836			MRQ_EXPANSION_MODE, &rq_regs->mrq_expansion_mode,
 837			CRQ_EXPANSION_MODE, &rq_regs->crq_expansion_mode);
 838
 839	REG_GET_5(DCHUBP_REQ_SIZE_CONFIG,
 840		CHUNK_SIZE, &rq_regs->rq_regs_l.chunk_size,
 841		MIN_CHUNK_SIZE, &rq_regs->rq_regs_l.min_chunk_size,
 842		DPTE_GROUP_SIZE, &rq_regs->rq_regs_l.dpte_group_size,
 843		SWATH_HEIGHT, &rq_regs->rq_regs_l.swath_height,
 844		PTE_ROW_HEIGHT_LINEAR, &rq_regs->rq_regs_l.pte_row_height_linear);
 845
 846	REG_GET_5(DCHUBP_REQ_SIZE_CONFIG_C,
 847		CHUNK_SIZE_C, &rq_regs->rq_regs_c.chunk_size,
 848		MIN_CHUNK_SIZE_C, &rq_regs->rq_regs_c.min_chunk_size,
 849		DPTE_GROUP_SIZE_C, &rq_regs->rq_regs_c.dpte_group_size,
 850		SWATH_HEIGHT_C, &rq_regs->rq_regs_c.swath_height,
 851		PTE_ROW_HEIGHT_LINEAR_C, &rq_regs->rq_regs_c.pte_row_height_linear);
 852
 853	REG_GET(DCN_VM_SYSTEM_APERTURE_HIGH_ADDR,
 854			MC_VM_SYSTEM_APERTURE_HIGH_ADDR, &rq_regs->aperture_high_addr);
 855
 856	REG_GET(DCN_VM_SYSTEM_APERTURE_LOW_ADDR,
 857			MC_VM_SYSTEM_APERTURE_LOW_ADDR, &rq_regs->aperture_low_addr);
 858
 859	/* DLG - Per hubp */
 860	REG_GET_2(BLANK_OFFSET_0,
 861		REFCYC_H_BLANK_END, &dlg_attr->refcyc_h_blank_end,
 862		DLG_V_BLANK_END, &dlg_attr->dlg_vblank_end);
 863
 864	REG_GET(BLANK_OFFSET_1,
 865		MIN_DST_Y_NEXT_START, &dlg_attr->min_dst_y_next_start);
 866
 867	REG_GET(DST_DIMENSIONS,
 868		REFCYC_PER_HTOTAL, &dlg_attr->refcyc_per_htotal);
 869
 870	REG_GET_2(DST_AFTER_SCALER,
 871		REFCYC_X_AFTER_SCALER, &dlg_attr->refcyc_x_after_scaler,
 872		DST_Y_AFTER_SCALER, &dlg_attr->dst_y_after_scaler);
 873
 874	REG_GET_2(PREFETCH_SETTINGS,
 875		DST_Y_PREFETCH, &dlg_attr->dst_y_prefetch,
 876		VRATIO_PREFETCH, &dlg_attr->vratio_prefetch);
 877
 878	REG_GET_2(VBLANK_PARAMETERS_0,
 879		DST_Y_PER_VM_VBLANK, &dlg_attr->dst_y_per_vm_vblank,
 880		DST_Y_PER_ROW_VBLANK, &dlg_attr->dst_y_per_row_vblank);
 881
 882	REG_GET(REF_FREQ_TO_PIX_FREQ,
 883		REF_FREQ_TO_PIX_FREQ, &dlg_attr->ref_freq_to_pix_freq);
 884
 885	/* DLG - Per luma/chroma */
 886	REG_GET(VBLANK_PARAMETERS_1,
 887		REFCYC_PER_PTE_GROUP_VBLANK_L, &dlg_attr->refcyc_per_pte_group_vblank_l);
 888
 889	REG_GET(VBLANK_PARAMETERS_3,
 890		REFCYC_PER_META_CHUNK_VBLANK_L, &dlg_attr->refcyc_per_meta_chunk_vblank_l);
 891
 892	REG_GET(NOM_PARAMETERS_0,
 893		DST_Y_PER_PTE_ROW_NOM_L, &dlg_attr->dst_y_per_pte_row_nom_l);
 894
 895	REG_GET(NOM_PARAMETERS_1,
 896		REFCYC_PER_PTE_GROUP_NOM_L, &dlg_attr->refcyc_per_pte_group_nom_l);
 897
 898	REG_GET(NOM_PARAMETERS_4,
 899		DST_Y_PER_META_ROW_NOM_L, &dlg_attr->dst_y_per_meta_row_nom_l);
 900
 901	REG_GET(NOM_PARAMETERS_5,
 902		REFCYC_PER_META_CHUNK_NOM_L, &dlg_attr->refcyc_per_meta_chunk_nom_l);
 903
 904	REG_GET_2(PER_LINE_DELIVERY_PRE,
 905		REFCYC_PER_LINE_DELIVERY_PRE_L, &dlg_attr->refcyc_per_line_delivery_pre_l,
 906		REFCYC_PER_LINE_DELIVERY_PRE_C, &dlg_attr->refcyc_per_line_delivery_pre_c);
 907
 908	REG_GET_2(PER_LINE_DELIVERY,
 909		REFCYC_PER_LINE_DELIVERY_L, &dlg_attr->refcyc_per_line_delivery_l,
 910		REFCYC_PER_LINE_DELIVERY_C, &dlg_attr->refcyc_per_line_delivery_c);
 911
 912	REG_GET(PREFETCH_SETTINGS_C,
 913		VRATIO_PREFETCH_C, &dlg_attr->vratio_prefetch_c);
 914
 915	REG_GET(VBLANK_PARAMETERS_2,
 916		REFCYC_PER_PTE_GROUP_VBLANK_C, &dlg_attr->refcyc_per_pte_group_vblank_c);
 917
 918	REG_GET(VBLANK_PARAMETERS_4,
 919		REFCYC_PER_META_CHUNK_VBLANK_C, &dlg_attr->refcyc_per_meta_chunk_vblank_c);
 920
 921	REG_GET(NOM_PARAMETERS_2,
 922		DST_Y_PER_PTE_ROW_NOM_C, &dlg_attr->dst_y_per_pte_row_nom_c);
 923
 924	REG_GET(NOM_PARAMETERS_3,
 925		REFCYC_PER_PTE_GROUP_NOM_C, &dlg_attr->refcyc_per_pte_group_nom_c);
 926
 927	REG_GET(NOM_PARAMETERS_6,
 928		DST_Y_PER_META_ROW_NOM_C, &dlg_attr->dst_y_per_meta_row_nom_c);
 929
 930	REG_GET(NOM_PARAMETERS_7,
 931		REFCYC_PER_META_CHUNK_NOM_C, &dlg_attr->refcyc_per_meta_chunk_nom_c);
 932
 933	/* TTU - per hubp */
 934	REG_GET_2(DCN_TTU_QOS_WM,
 935		QoS_LEVEL_LOW_WM, &ttu_attr->qos_level_low_wm,
 936		QoS_LEVEL_HIGH_WM, &ttu_attr->qos_level_high_wm);
 937
 938	REG_GET_2(DCN_GLOBAL_TTU_CNTL,
 939		MIN_TTU_VBLANK, &ttu_attr->min_ttu_vblank,
 940		QoS_LEVEL_FLIP, &ttu_attr->qos_level_flip);
 941
 942	/* TTU - per luma/chroma */
 943	/* Assumed surf0 is luma and 1 is chroma */
 944
 945	REG_GET_3(DCN_SURF0_TTU_CNTL0,
 946		REFCYC_PER_REQ_DELIVERY, &ttu_attr->refcyc_per_req_delivery_l,
 947		QoS_LEVEL_FIXED, &ttu_attr->qos_level_fixed_l,
 948		QoS_RAMP_DISABLE, &ttu_attr->qos_ramp_disable_l);
 949
 950	REG_GET(DCN_SURF0_TTU_CNTL1,
 951		REFCYC_PER_REQ_DELIVERY_PRE,
 952		&ttu_attr->refcyc_per_req_delivery_pre_l);
 953
 954	REG_GET_3(DCN_SURF1_TTU_CNTL0,
 955		REFCYC_PER_REQ_DELIVERY, &ttu_attr->refcyc_per_req_delivery_c,
 956		QoS_LEVEL_FIXED, &ttu_attr->qos_level_fixed_c,
 957		QoS_RAMP_DISABLE, &ttu_attr->qos_ramp_disable_c);
 958
 959	REG_GET(DCN_SURF1_TTU_CNTL1,
 960		REFCYC_PER_REQ_DELIVERY_PRE,
 961		&ttu_attr->refcyc_per_req_delivery_pre_c);
 962
 963	/* Rest of hubp */
 964	REG_GET(DCSURF_SURFACE_CONFIG,
 965			SURFACE_PIXEL_FORMAT, &s->pixel_format);
 966
 967	REG_GET(DCSURF_SURFACE_EARLIEST_INUSE_HIGH,
 968			SURFACE_EARLIEST_INUSE_ADDRESS_HIGH, &s->inuse_addr_hi);
 969
 970	REG_GET(DCSURF_SURFACE_EARLIEST_INUSE,
 971			SURFACE_EARLIEST_INUSE_ADDRESS, &s->inuse_addr_lo);
 972
 973	REG_GET_2(DCSURF_PRI_VIEWPORT_DIMENSION,
 974			PRI_VIEWPORT_WIDTH, &s->viewport_width,
 975			PRI_VIEWPORT_HEIGHT, &s->viewport_height);
 976
 977	REG_GET_2(DCSURF_SURFACE_CONFIG,
 978			ROTATION_ANGLE, &s->rotation_angle,
 979			H_MIRROR_EN, &s->h_mirror_en);
 980
 981	REG_GET(DCSURF_TILING_CONFIG,
 982			SW_MODE, &s->sw_mode);
 983
 984	REG_GET(DCSURF_SURFACE_CONTROL,
 985			PRIMARY_SURFACE_DCC_EN, &s->dcc_en);
 986
 987	REG_GET_3(DCHUBP_CNTL,
 988			HUBP_BLANK_EN, &s->blank_en,
 989			HUBP_TTU_DISABLE, &s->ttu_disable,
 990			HUBP_UNDERFLOW_STATUS, &s->underflow_status);
 991
 992	REG_GET(HUBP_CLK_CNTL,
 993			HUBP_CLOCK_ENABLE, &s->clock_en);
 994
 995	REG_GET(DCN_GLOBAL_TTU_CNTL,
 996			MIN_TTU_VBLANK, &s->min_ttu_vblank);
 997
 998	REG_GET_2(DCN_TTU_QOS_WM,
 999			QoS_LEVEL_LOW_WM, &s->qos_level_low_wm,
1000			QoS_LEVEL_HIGH_WM, &s->qos_level_high_wm);
1001
1002	REG_GET(DCSURF_PRIMARY_SURFACE_ADDRESS,
1003			PRIMARY_SURFACE_ADDRESS, &s->primary_surface_addr_lo);
1004
1005	REG_GET(DCSURF_PRIMARY_SURFACE_ADDRESS_HIGH,
1006			PRIMARY_SURFACE_ADDRESS, &s->primary_surface_addr_hi);
1007
1008	s->uclk_pstate_force = REG_READ(UCLK_PSTATE_FORCE);
1009
1010	s->hubp_cntl = REG_READ(DCHUBP_CNTL);
1011	s->flip_control = REG_READ(DCSURF_FLIP_CONTROL);
1012}
1013
1014void hubp401_set_unbounded_requesting(struct hubp *hubp, bool enable)
1015{
1016	struct dcn20_hubp *hubp2 = TO_DCN20_HUBP(hubp);
1017
1018	REG_UPDATE(DCHUBP_CNTL, HUBP_UNBOUNDED_REQ_MODE, enable);
1019
1020	/* To ensure that cursor fetching starts as early as possible in
1021	 * the display prefetch, set CURSOR_REQ_MODE = 1 always.
1022	 * The setting of CURSOR_REQ_MODE = 0 is no longer supported in
1023	 * DCN4x as a fall back to legacy behavior of fetching cursor
1024	 * just before it appears on the screen.
1025	 */
1026	REG_UPDATE(CURSOR_CONTROL, CURSOR_REQ_MODE, 1);
1027}
1028
1029static struct hubp_funcs dcn401_hubp_funcs = {
1030	.hubp_enable_tripleBuffer = hubp2_enable_triplebuffer,
1031	.hubp_is_triplebuffer_enabled = hubp2_is_triplebuffer_enabled,
1032	.hubp_program_surface_flip_and_addr = hubp401_program_surface_flip_and_addr,
1033	.hubp_program_surface_config = hubp401_program_surface_config,
1034	.hubp_is_flip_pending = hubp2_is_flip_pending,
1035	.hubp_setup2 = hubp401_setup,
1036	.hubp_setup_interdependent2 = hubp401_setup_interdependent,
1037	.hubp_set_vm_system_aperture_settings = hubp3_set_vm_system_aperture_settings,
1038	.set_blank = hubp2_set_blank,
1039	.set_blank_regs = hubp2_set_blank_regs,
1040	.hubp_reset = hubp_reset,
1041	.mem_program_viewport = hubp401_set_viewport,
1042	.set_cursor_attributes	= hubp32_cursor_set_attributes,
1043	.set_cursor_position	= hubp401_cursor_set_position,
1044	.hubp_clk_cntl = hubp2_clk_cntl,
1045	.hubp_vtg_sel = hubp2_vtg_sel,
1046	.dmdata_set_attributes = hubp3_dmdata_set_attributes,
1047	.dmdata_load = hubp2_dmdata_load,
1048	.dmdata_status_done = hubp2_dmdata_status_done,
1049	.hubp_read_state = hubp401_read_state,
1050	.hubp_clear_underflow = hubp2_clear_underflow,
1051	.hubp_set_flip_control_surface_gsl = hubp2_set_flip_control_surface_gsl,
1052	.hubp_init = hubp401_init,
1053	.set_unbounded_requesting = hubp401_set_unbounded_requesting,
1054	.hubp_soft_reset = hubp31_soft_reset,
1055	.hubp_set_flip_int = hubp401_set_flip_int,
1056	.hubp_in_blank = hubp401_in_blank,
1057	.phantom_hubp_post_enable = hubp32_phantom_hubp_post_enable,
1058	.hubp_update_mall_sel = hubp401_update_mall_sel,
1059	.hubp_prepare_subvp_buffering = hubp32_prepare_subvp_buffering,
1060	.hubp_program_mcache_id_and_split_coordinate = hubp401_program_mcache_id_and_split_coordinate,
1061	.hubp_update_3dlut_fl_bias_scale = hubp401_update_3dlut_fl_bias_scale,
1062	.hubp_program_3dlut_fl_mode = hubp401_program_3dlut_fl_mode,
1063	.hubp_program_3dlut_fl_format = hubp401_program_3dlut_fl_format,
1064	.hubp_program_3dlut_fl_addr = hubp401_program_3dlut_fl_addr,
1065	.hubp_program_3dlut_fl_dlg_param = hubp401_program_3dlut_fl_dlg_param,
1066	.hubp_enable_3dlut_fl = hubp401_enable_3dlut_fl,
1067	.hubp_program_3dlut_fl_addressing_mode = hubp401_program_3dlut_fl_addressing_mode,
1068	.hubp_program_3dlut_fl_width = hubp401_program_3dlut_fl_width,
1069	.hubp_program_3dlut_fl_tmz_protected = hubp401_program_3dlut_fl_tmz_protected,
1070	.hubp_program_3dlut_fl_crossbar = hubp401_program_3dlut_fl_crossbar,
1071	.hubp_get_3dlut_fl_done = hubp401_get_3dlut_fl_done,
1072	.hubp_clear_tiling = hubp401_clear_tiling,
1073	.hubp_program_3dlut_fl_config = hubp401_program_3dlut_fl_config,
1074	.hubp_read_reg_state = hubp3_read_reg_state
1075};
1076
1077bool hubp401_construct(
1078	struct dcn20_hubp *hubp2,
1079	struct dc_context *ctx,
1080	uint32_t inst,
1081	const struct dcn_hubp2_registers *hubp_regs,
1082	const struct dcn_hubp2_shift *hubp_shift,
1083	const struct dcn_hubp2_mask *hubp_mask)
1084{
1085	hubp2->base.funcs = &dcn401_hubp_funcs;
1086	hubp2->base.ctx = ctx;
1087	hubp2->hubp_regs = hubp_regs;
1088	hubp2->hubp_shift = hubp_shift;
1089	hubp2->hubp_mask = hubp_mask;
1090	hubp2->base.inst = inst;
1091	hubp2->base.opp_id = OPP_ID_INVALID;
1092	hubp2->base.mpcc_id = 0xf;
1093
1094	return true;
1095}
~/ Read-only file preview.