xref: /linux/drivers/gpu/drm/amd/display/dc/dcn31/dcn31_vpg.c (revision 151ebcf0797b1a3ba53c8843dc21748c80e098c7)
1 /*
2  * Copyright 2019 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 "dc_bios_types.h"
27 #include "dcn30/dcn30_vpg.h"
28 #include "dcn31_vpg.h"
29 #include "reg_helper.h"
30 #include "dc/dc.h"
31 
32 #define DC_LOGGER \
33 		vpg31->base.ctx->logger
34 
35 #define REG(reg)\
36 	(vpg31->regs->reg)
37 
38 #undef FN
39 #define FN(reg_name, field_name) \
40 	vpg31->vpg_shift->field_name, vpg31->vpg_mask->field_name
41 
42 
43 #define CTX \
44 	vpg31->base.ctx
45 
46 static struct vpg_funcs dcn31_vpg_funcs = {
47 	.update_generic_info_packet	= vpg3_update_generic_info_packet,
48 	.vpg_poweron = vpg31_poweron,
49 	.vpg_powerdown = vpg31_powerdown,
50 };
51 
52 void vpg31_powerdown(struct vpg *vpg)
53 {
54 	struct dcn31_vpg *vpg31 = DCN31_VPG_FROM_VPG(vpg);
55 
56 	if (vpg->ctx->dc->debug.enable_mem_low_power.bits.vpg == false)
57 		return;
58 
59 	REG_UPDATE_2(VPG_MEM_PWR, VPG_GSP_MEM_LIGHT_SLEEP_DIS, 0, VPG_GSP_LIGHT_SLEEP_FORCE, 1);
60 }
61 
62 void vpg31_poweron(struct vpg *vpg)
63 {
64 	struct dcn31_vpg *vpg31 = DCN31_VPG_FROM_VPG(vpg);
65 
66 	uint32_t vpg_gsp_mem_pwr_state;
67 
68 	REG_GET(VPG_MEM_PWR, VPG_GSP_MEM_PWR_STATE, &vpg_gsp_mem_pwr_state);
69 
70 	if (vpg->ctx->dc->debug.enable_mem_low_power.bits.vpg == false &&
71 			vpg_gsp_mem_pwr_state == 0)
72 		return;
73 
74 	REG_UPDATE_2(VPG_MEM_PWR, VPG_GSP_MEM_LIGHT_SLEEP_DIS, 1, VPG_GSP_LIGHT_SLEEP_FORCE, 0);
75 }
76 
77 void vpg31_construct(struct dcn31_vpg *vpg31,
78 	struct dc_context *ctx,
79 	uint32_t inst,
80 	const struct dcn31_vpg_registers *vpg_regs,
81 	const struct dcn31_vpg_shift *vpg_shift,
82 	const struct dcn31_vpg_mask *vpg_mask)
83 {
84 	vpg31->base.ctx = ctx;
85 
86 	vpg31->base.inst = inst;
87 	vpg31->base.funcs = &dcn31_vpg_funcs;
88 
89 	vpg31->regs = vpg_regs;
90 	vpg31->vpg_shift = vpg_shift;
91 	vpg31->vpg_mask = vpg_mask;
92 }
93