]> Git Repo - linux.git/blob - drivers/gpu/drm/amd/display/dc/dce/dce_hwseq.c
Merge tag 'trace-v5.13-2' of git://git.kernel.org/pub/scm/linux/kernel/git/rostedt...
[linux.git] / drivers / gpu / drm / amd / display / dc / dce / dce_hwseq.c
1 /*
2  * Copyright 2016 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 "dce_hwseq.h"
27 #include "reg_helper.h"
28 #include "hw_sequencer_private.h"
29 #include "core_types.h"
30
31 #define CTX \
32         hws->ctx
33 #define REG(reg)\
34         hws->regs->reg
35
36 #undef FN
37 #define FN(reg_name, field_name) \
38         hws->shifts->field_name, hws->masks->field_name
39
40 void dce_enable_fe_clock(struct dce_hwseq *hws,
41                 unsigned int fe_inst, bool enable)
42 {
43         REG_UPDATE(DCFE_CLOCK_CONTROL[fe_inst],
44                         DCFE_CLOCK_ENABLE, enable);
45 }
46
47 void dce_pipe_control_lock(struct dc *dc,
48                 struct pipe_ctx *pipe,
49                 bool lock)
50 {
51         uint32_t lock_val = lock ? 1 : 0;
52         uint32_t dcp_grph, scl, blnd, update_lock_mode, val;
53         struct dce_hwseq *hws = dc->hwseq;
54
55         /* Not lock pipe when blank */
56         if (lock && pipe->stream_res.tg->funcs->is_blanked &&
57             pipe->stream_res.tg->funcs->is_blanked(pipe->stream_res.tg))
58                 return;
59
60         val = REG_GET_4(BLND_V_UPDATE_LOCK[pipe->stream_res.tg->inst],
61                         BLND_DCP_GRPH_V_UPDATE_LOCK, &dcp_grph,
62                         BLND_SCL_V_UPDATE_LOCK, &scl,
63                         BLND_BLND_V_UPDATE_LOCK, &blnd,
64                         BLND_V_UPDATE_LOCK_MODE, &update_lock_mode);
65
66         dcp_grph = lock_val;
67         scl = lock_val;
68         blnd = lock_val;
69         update_lock_mode = lock_val;
70
71         REG_SET_2(BLND_V_UPDATE_LOCK[pipe->stream_res.tg->inst], val,
72                         BLND_DCP_GRPH_V_UPDATE_LOCK, dcp_grph,
73                         BLND_SCL_V_UPDATE_LOCK, scl);
74
75         if (hws->masks->BLND_BLND_V_UPDATE_LOCK != 0)
76                 REG_SET_2(BLND_V_UPDATE_LOCK[pipe->stream_res.tg->inst], val,
77                                 BLND_BLND_V_UPDATE_LOCK, blnd,
78                                 BLND_V_UPDATE_LOCK_MODE, update_lock_mode);
79
80         if (hws->wa.blnd_crtc_trigger) {
81                 if (!lock) {
82                         uint32_t value = REG_READ(CRTC_H_BLANK_START_END[pipe->stream_res.tg->inst]);
83                         REG_WRITE(CRTC_H_BLANK_START_END[pipe->stream_res.tg->inst], value);
84                 }
85         }
86 }
87
88 #if defined(CONFIG_DRM_AMD_DC_SI)
89 void dce60_pipe_control_lock(struct dc *dc,
90                 struct pipe_ctx *pipe,
91                 bool lock)
92 {
93         /* DCE6 has no BLND_V_UPDATE_LOCK register */
94 }
95 #endif
96
97 void dce_set_blender_mode(struct dce_hwseq *hws,
98         unsigned int blnd_inst,
99         enum blnd_mode mode)
100 {
101         uint32_t feedthrough = 1;
102         uint32_t blnd_mode = 0;
103         uint32_t multiplied_mode = 0;
104         uint32_t alpha_mode = 2;
105
106         switch (mode) {
107         case BLND_MODE_OTHER_PIPE:
108                 feedthrough = 0;
109                 blnd_mode = 1;
110                 alpha_mode = 0;
111                 break;
112         case BLND_MODE_BLENDING:
113                 feedthrough = 0;
114                 blnd_mode = 2;
115                 alpha_mode = 0;
116                 multiplied_mode = 1;
117                 break;
118         case BLND_MODE_CURRENT_PIPE:
119         default:
120                 if (REG(BLND_CONTROL[blnd_inst]) == REG(BLNDV_CONTROL) ||
121                                 blnd_inst == 0)
122                         feedthrough = 0;
123                 break;
124         }
125
126         REG_UPDATE(BLND_CONTROL[blnd_inst],
127                 BLND_MODE, blnd_mode);
128
129         if (hws->masks->BLND_ALPHA_MODE != 0) {
130                 REG_UPDATE_3(BLND_CONTROL[blnd_inst],
131                         BLND_FEEDTHROUGH_EN, feedthrough,
132                         BLND_ALPHA_MODE, alpha_mode,
133                         BLND_MULTIPLIED_MODE, multiplied_mode);
134         }
135 }
136
137
138 static void dce_disable_sram_shut_down(struct dce_hwseq *hws)
139 {
140         if (REG(DC_MEM_GLOBAL_PWR_REQ_CNTL))
141                 REG_UPDATE(DC_MEM_GLOBAL_PWR_REQ_CNTL,
142                                 DC_MEM_GLOBAL_PWR_REQ_DIS, 1);
143 }
144
145 static void dce_underlay_clock_enable(struct dce_hwseq *hws)
146 {
147         /* todo: why do we need this at boot? is dce_enable_fe_clock enough? */
148         if (REG(DCFEV_CLOCK_CONTROL))
149                 REG_UPDATE(DCFEV_CLOCK_CONTROL,
150                                 DCFEV_CLOCK_ENABLE, 1);
151 }
152
153 static void enable_hw_base_light_sleep(void)
154 {
155         /* TODO: implement */
156 }
157
158 static void disable_sw_manual_control_light_sleep(void)
159 {
160         /* TODO: implement */
161 }
162
163 void dce_clock_gating_power_up(struct dce_hwseq *hws,
164                 bool enable)
165 {
166         if (enable) {
167                 enable_hw_base_light_sleep();
168                 disable_sw_manual_control_light_sleep();
169         } else {
170                 dce_disable_sram_shut_down(hws);
171                 dce_underlay_clock_enable(hws);
172         }
173 }
174
175 void dce_crtc_switch_to_clk_src(struct dce_hwseq *hws,
176                 struct clock_source *clk_src,
177                 unsigned int tg_inst)
178 {
179         if (clk_src->id == CLOCK_SOURCE_ID_DP_DTO || clk_src->dp_clk_src) {
180                 REG_UPDATE(PIXEL_RATE_CNTL[tg_inst],
181                                 DP_DTO0_ENABLE, 1);
182
183         } else if (clk_src->id >= CLOCK_SOURCE_COMBO_PHY_PLL0) {
184                 uint32_t rate_source = clk_src->id - CLOCK_SOURCE_COMBO_PHY_PLL0;
185
186                 REG_UPDATE_2(PHYPLL_PIXEL_RATE_CNTL[tg_inst],
187                                 PHYPLL_PIXEL_RATE_SOURCE, rate_source,
188                                 PIXEL_RATE_PLL_SOURCE, 0);
189
190                 REG_UPDATE(PIXEL_RATE_CNTL[tg_inst],
191                                 DP_DTO0_ENABLE, 0);
192
193         } else if (clk_src->id <= CLOCK_SOURCE_ID_PLL2) {
194                 uint32_t rate_source = clk_src->id - CLOCK_SOURCE_ID_PLL0;
195
196                 REG_UPDATE_2(PIXEL_RATE_CNTL[tg_inst],
197                                 PIXEL_RATE_SOURCE, rate_source,
198                                 DP_DTO0_ENABLE, 0);
199
200                 if (REG(PHYPLL_PIXEL_RATE_CNTL[tg_inst]))
201                         REG_UPDATE(PHYPLL_PIXEL_RATE_CNTL[tg_inst],
202                                         PIXEL_RATE_PLL_SOURCE, 1);
203         } else {
204                 DC_ERR("Unknown clock source. clk_src id: %d, TG_inst: %d",
205                        clk_src->id, tg_inst);
206         }
207 }
208
209 /* Only use LUT for 8 bit formats */
210 bool dce_use_lut(enum surface_pixel_format format)
211 {
212         switch (format) {
213         case SURFACE_PIXEL_FORMAT_GRPH_ARGB8888:
214         case SURFACE_PIXEL_FORMAT_GRPH_ABGR8888:
215                 return true;
216         default:
217                 return false;
218         }
219 }
This page took 0.043188 seconds and 4 git commands to generate.