]> git.proxmox.com Git - mirror_ubuntu-bionic-kernel.git/blob - drivers/gpu/drm/amd/display/dc/gpu/display_clock.c
drm/amd/dc: Add dc display driver (v2)
[mirror_ubuntu-bionic-kernel.git] / drivers / gpu / drm / amd / display / dc / gpu / display_clock.c
1 /*
2 * Copyright 2012-15 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 "display_clock.h"
28
29 void dal_display_clock_base_set_dp_ref_clock_source(
30 struct display_clock *disp_clk,
31 enum clock_source_id clk_src)
32 {/*must be implemented in derived*/
33
34 }
35
36 void dal_display_clock_base_set_clock_state(struct display_clock *disp_clk,
37 struct display_clock_state clk_state)
38 {
39 /*Implemented only in DCE81*/
40 }
41 struct display_clock_state dal_display_clock_base_get_clock_state(
42 struct display_clock *disp_clk)
43 {
44 /*Implemented only in DCE81*/
45 struct display_clock_state state = {0};
46 return state;
47 }
48 uint32_t dal_display_clock_base_get_dfs_bypass_threshold(
49 struct display_clock *disp_clk)
50 {
51 /*Implemented only in DCE81*/
52 return 0;
53 }
54
55 bool dal_display_clock_construct_base(
56 struct display_clock *base,
57 struct dc_context *ctx)
58 {
59 base->ctx = ctx;
60 base->id = CLOCK_SOURCE_ID_DCPLL;
61 base->min_display_clk_threshold_khz = 0;
62
63 /* Initially set current min clocks state to invalid since we
64 * cannot make any assumption about PPLIB's initial state. This will be updated
65 * by HWSS via SetMinClocksState() on first mode set prior to programming
66 * state dependent clocks.*/
67 base->cur_min_clks_state = CLOCKS_STATE_INVALID;
68
69 return true;
70 }
71
72 void dal_display_clock_destroy(struct display_clock **disp_clk)
73 {
74 if (!disp_clk || !*disp_clk) {
75 BREAK_TO_DEBUGGER();
76 return;
77 }
78
79 (*disp_clk)->funcs->destroy(disp_clk);
80
81 *disp_clk = NULL;
82 }
83
84 bool dal_display_clock_validate(
85 struct display_clock *disp_clk,
86 struct min_clock_params *params)
87 {
88 return disp_clk->funcs->validate(disp_clk, params);
89 }
90
91 uint32_t dal_display_clock_calculate_min_clock(
92 struct display_clock *disp_clk,
93 uint32_t path_num,
94 struct min_clock_params *params)
95 {
96 return disp_clk->funcs->calculate_min_clock(disp_clk, path_num, params);
97 }
98
99 uint32_t dal_display_clock_get_validation_clock(struct display_clock *disp_clk)
100 {
101 return disp_clk->funcs->get_validation_clock(disp_clk);
102 }
103
104 void dal_display_clock_set_clock(
105 struct display_clock *disp_clk,
106 uint32_t requested_clock_khz)
107 {
108 disp_clk->funcs->set_clock(disp_clk, requested_clock_khz);
109 }
110
111 uint32_t dal_display_clock_get_clock(struct display_clock *disp_clk)
112 {
113 return disp_clk->funcs->get_clock(disp_clk);
114 }
115
116 bool dal_display_clock_get_min_clocks_state(
117 struct display_clock *disp_clk,
118 enum clocks_state *clocks_state)
119 {
120 if (!disp_clk->funcs->get_min_clocks_state)
121 return false;
122
123 *clocks_state = disp_clk->funcs->get_min_clocks_state(disp_clk);
124 return true;
125 }
126
127 bool dal_display_clock_get_required_clocks_state(
128 struct display_clock *disp_clk,
129 struct state_dependent_clocks *req_clocks,
130 enum clocks_state *clocks_state)
131 {
132 if (!disp_clk->funcs->get_required_clocks_state)
133 return false;
134
135 *clocks_state = disp_clk->funcs->get_required_clocks_state(
136 disp_clk, req_clocks);
137 return true;
138 }
139
140 bool dal_display_clock_set_min_clocks_state(
141 struct display_clock *disp_clk,
142 enum clocks_state clocks_state)
143 {
144 if (!disp_clk->funcs->set_min_clocks_state)
145 return false;
146
147 disp_clk->funcs->set_min_clocks_state(disp_clk, clocks_state);
148 return true;
149 }
150
151 uint32_t dal_display_clock_get_dp_ref_clk_frequency(
152 struct display_clock *disp_clk)
153 {
154 return disp_clk->funcs->get_dp_ref_clk_frequency(disp_clk);
155 }
156
157 /*the second parameter of "switchreferenceclock" is
158 * a dummy argument for all pre dce 6.0 versions*/
159
160 void dal_display_clock_switch_reference_clock(
161 struct display_clock *disp_clk,
162 bool use_external_ref_clk,
163 uint32_t requested_clk_khz)
164 {
165 /* TODO: requires Asic Control*/
166 /*
167 struct ac_pixel_clk_params params;
168 struct asic_control *ac =
169 dal_adapter_service_get_asic_control(disp_clk->as);
170 dc_service_memset(&params, 0, sizeof(struct ac_pixel_clk_params));
171
172 params.tgt_pixel_clk_khz = requested_clk_khz;
173 params.flags.SET_EXTERNAL_REF_DIV_SRC = use_external_ref_clk;
174 params.pll_id = disp_clk->id;
175 dal_asic_control_program_display_engine_pll(ac, &params);
176 */
177 }
178
179 void dal_display_clock_set_dp_ref_clock_source(
180 struct display_clock *disp_clk,
181 enum clock_source_id clk_src)
182 {
183 disp_clk->funcs->set_dp_ref_clock_source(disp_clk, clk_src);
184 }
185
186 void dal_display_clock_store_max_clocks_state(
187 struct display_clock *disp_clk,
188 enum clocks_state max_clocks_state)
189 {
190 disp_clk->funcs->store_max_clocks_state(disp_clk, max_clocks_state);
191 }
192
193 void dal_display_clock_set_clock_state(
194 struct display_clock *disp_clk,
195 struct display_clock_state clk_state)
196 {
197 disp_clk->funcs->set_clock_state(disp_clk, clk_state);
198 }
199
200 struct display_clock_state dal_display_clock_get_clock_state(
201 struct display_clock *disp_clk)
202 {
203 return disp_clk->funcs->get_clock_state(disp_clk);
204 }
205
206 uint32_t dal_display_clock_get_dfs_bypass_threshold(
207 struct display_clock *disp_clk)
208 {
209 return disp_clk->funcs->get_dfs_bypass_threshold(disp_clk);
210 }
211
212 void dal_display_clock_invalid_clock_state(
213 struct display_clock *disp_clk)
214 {
215 disp_clk->cur_min_clks_state = CLOCKS_STATE_INVALID;
216 }
217