2 * Copyright 2016 Advanced Micro Devices, Inc.
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:
11 * The above copyright notice and this permission notice shall be included in
12 * all copies or substantial portions of the Software.
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.
26 #include "dce_hwseq.h"
27 #include "reg_helper.h"
28 #include "hw_sequencer.h"
36 #define FN(reg_name, field_name) \
37 hws->shifts->field_name, hws->masks->field_name
39 void dce_enable_fe_clock(struct dce_hwseq
*hws
,
40 unsigned int fe_inst
, bool enable
)
42 REG_UPDATE(DCFE_CLOCK_CONTROL
[fe_inst
],
43 DCFE_CLOCK_ENABLE
, enable
);
46 void dce_pipe_control_lock(struct dce_hwseq
*hws
,
47 unsigned int blnd_inst
,
48 enum pipe_lock_control control_mask
,
51 uint32_t lock_val
= lock
? 1 : 0;
52 uint32_t dcp_grph
, scl
, dcp_grph_surf
, blnd
, update_lock_mode
;
54 uint32_t val
= REG_GET_5(BLND_V_UPDATE_LOCK
[blnd_inst
],
55 BLND_DCP_GRPH_V_UPDATE_LOCK
, &dcp_grph
,
56 BLND_SCL_V_UPDATE_LOCK
, &scl
,
57 BLND_DCP_GRPH_SURF_V_UPDATE_LOCK
, &dcp_grph_surf
,
58 BLND_BLND_V_UPDATE_LOCK
, &blnd
,
59 BLND_V_UPDATE_LOCK_MODE
, &update_lock_mode
);
61 if (control_mask
& PIPE_LOCK_CONTROL_GRAPHICS
)
64 if (control_mask
& PIPE_LOCK_CONTROL_SCL
)
67 if (control_mask
& PIPE_LOCK_CONTROL_SURFACE
)
68 dcp_grph_surf
= lock_val
;
70 if (control_mask
& PIPE_LOCK_CONTROL_BLENDER
)
73 if (control_mask
& PIPE_LOCK_CONTROL_MODE
)
74 update_lock_mode
= lock_val
;
76 REG_SET_5(BLND_V_UPDATE_LOCK
[blnd_inst
], val
,
77 BLND_DCP_GRPH_V_UPDATE_LOCK
, dcp_grph
,
78 BLND_SCL_V_UPDATE_LOCK
, scl
,
79 BLND_DCP_GRPH_SURF_V_UPDATE_LOCK
, dcp_grph_surf
,
80 BLND_BLND_V_UPDATE_LOCK
, blnd
,
81 BLND_V_UPDATE_LOCK_MODE
, update_lock_mode
);
83 if (hws
->wa
.blnd_crtc_trigger
)
84 if (!lock
&& (control_mask
& PIPE_LOCK_CONTROL_BLENDER
)) {
85 uint32_t value
= REG_READ(CRTC_H_BLANK_START_END
[blnd_inst
]);
86 REG_WRITE(CRTC_H_BLANK_START_END
[blnd_inst
], value
);
90 void dce_set_blender_mode(struct dce_hwseq
*hws
,
91 unsigned int blnd_inst
,
94 uint32_t feedthrough
= 1;
95 uint32_t blnd_mode
= 0;
96 uint32_t multiplied_mode
= 0;
97 uint32_t alpha_mode
= 2;
100 case BLND_MODE_OTHER_PIPE
:
105 case BLND_MODE_BLENDING
:
111 case BLND_MODE_CURRENT_PIPE
:
113 if (REG(BLND_CONTROL
[blnd_inst
]) == REG(BLNDV_CONTROL
) ||
119 REG_UPDATE_4(BLND_CONTROL
[blnd_inst
],
120 BLND_FEEDTHROUGH_EN
, feedthrough
,
121 BLND_ALPHA_MODE
, alpha_mode
,
122 BLND_MODE
, blnd_mode
,
123 BLND_MULTIPLIED_MODE
, multiplied_mode
);
127 static void dce_disable_sram_shut_down(struct dce_hwseq
*hws
)
129 if (REG(DC_MEM_GLOBAL_PWR_REQ_CNTL
))
130 REG_UPDATE(DC_MEM_GLOBAL_PWR_REQ_CNTL
,
131 DC_MEM_GLOBAL_PWR_REQ_DIS
, 1);
134 static void dce_underlay_clock_enable(struct dce_hwseq
*hws
)
136 /* todo: why do we need this at boot? is dce_enable_fe_clock enough? */
137 if (REG(DCFEV_CLOCK_CONTROL
))
138 REG_UPDATE(DCFEV_CLOCK_CONTROL
,
139 DCFEV_CLOCK_ENABLE
, 1);
142 static void enable_hw_base_light_sleep(void)
144 /* TODO: implement */
147 static void disable_sw_manual_control_light_sleep(void)
149 /* TODO: implement */
152 void dce_clock_gating_power_up(struct dce_hwseq
*hws
,
156 enable_hw_base_light_sleep();
157 disable_sw_manual_control_light_sleep();
159 dce_disable_sram_shut_down(hws
);
160 dce_underlay_clock_enable(hws
);
164 void dce_crtc_switch_to_clk_src(struct dce_hwseq
*hws
,
165 struct clock_source
*clk_src
,
166 unsigned int tg_inst
)
168 if (clk_src
->id
== CLOCK_SOURCE_ID_DP_DTO
) {
169 REG_UPDATE(PIXEL_RATE_CNTL
[tg_inst
],
172 } else if (clk_src
->id
>= CLOCK_SOURCE_COMBO_PHY_PLL0
) {
173 uint32_t rate_source
= clk_src
->id
- CLOCK_SOURCE_COMBO_PHY_PLL0
;
175 REG_UPDATE_2(PHYPLL_PIXEL_RATE_CNTL
[tg_inst
],
176 PHYPLL_PIXEL_RATE_SOURCE
, rate_source
,
177 PIXEL_RATE_PLL_SOURCE
, 0);
179 REG_UPDATE(PIXEL_RATE_CNTL
[tg_inst
],
182 } else if (clk_src
->id
<= CLOCK_SOURCE_ID_PLL2
) {
183 uint32_t rate_source
= clk_src
->id
- CLOCK_SOURCE_ID_PLL0
;
185 REG_UPDATE_2(PIXEL_RATE_CNTL
[tg_inst
],
186 PIXEL_RATE_SOURCE
, rate_source
,
189 if (REG(PHYPLL_PIXEL_RATE_CNTL
[tg_inst
]))
190 REG_UPDATE(PHYPLL_PIXEL_RATE_CNTL
[tg_inst
],
191 PIXEL_RATE_PLL_SOURCE
, 1);
193 DC_ERR("unknown clock source");