2 * Copyright 2012-16 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 <linux/slab.h>
28 #include "dal_asic_id.h"
31 #include "clk_mgr_internal.h"
33 #include "dce100/dce_clk_mgr.h"
34 #include "dce110/dce110_clk_mgr.h"
35 #include "dce112/dce112_clk_mgr.h"
36 #include "dce120/dce120_clk_mgr.h"
37 #include "dce60/dce60_clk_mgr.h"
38 #include "dcn10/rv1_clk_mgr.h"
39 #include "dcn10/rv2_clk_mgr.h"
40 #include "dcn20/dcn20_clk_mgr.h"
41 #include "dcn21/rn_clk_mgr.h"
42 #include "dcn30/dcn30_clk_mgr.h"
43 #include "dcn301/vg_clk_mgr.h"
46 int clk_mgr_helper_get_active_display_cnt(
48 struct dc_state
*context
)
53 for (i
= 0; i
< context
->stream_count
; i
++) {
54 const struct dc_stream_state
*stream
= context
->streams
[i
];
57 * Only notify active stream or virtual stream.
58 * Need to notify virtual stream to work around
59 * headless case. HPD does not fire when system is in
62 if (!stream
->dpms_off
|| stream
->signal
== SIGNAL_TYPE_VIRTUAL
)
69 int clk_mgr_helper_get_active_plane_cnt(
71 struct dc_state
*context
)
73 int i
, total_plane_count
;
75 total_plane_count
= 0;
76 for (i
= 0; i
< context
->stream_count
; i
++) {
77 const struct dc_stream_status stream_status
= context
->stream_status
[i
];
80 * Sum up plane_count for all streams ( active and virtual ).
82 total_plane_count
+= stream_status
.plane_count
;
85 return total_plane_count
;
88 void clk_mgr_exit_optimized_pwr_state(const struct dc
*dc
, struct clk_mgr
*clk_mgr
)
90 struct dc_link
*edp_link
= get_edp_link(dc
);
92 if (dc
->hwss
.exit_optimized_pwr_state
)
93 dc
->hwss
.exit_optimized_pwr_state(dc
, dc
->current_state
);
96 clk_mgr
->psr_allow_active_cache
= edp_link
->psr_settings
.psr_allow_active
;
97 dc_link_set_psr_allow_active(edp_link
, false, false, false);
102 void clk_mgr_optimize_pwr_state(const struct dc
*dc
, struct clk_mgr
*clk_mgr
)
104 struct dc_link
*edp_link
= get_edp_link(dc
);
107 dc_link_set_psr_allow_active(edp_link
,
108 clk_mgr
->psr_allow_active_cache
, false, false);
110 if (dc
->hwss
.optimize_pwr_state
)
111 dc
->hwss
.optimize_pwr_state(dc
, dc
->current_state
);
115 struct clk_mgr
*dc_clk_mgr_create(struct dc_context
*ctx
, struct pp_smu_funcs
*pp_smu
, struct dccg
*dccg
)
117 struct hw_asic_id asic_id
= ctx
->asic_id
;
119 struct clk_mgr_internal
*clk_mgr
= kzalloc(sizeof(*clk_mgr
), GFP_KERNEL
);
121 if (clk_mgr
== NULL
) {
126 switch (asic_id
.chip_family
) {
127 #if defined(CONFIG_DRM_AMD_DC_SI)
129 dce60_clk_mgr_construct(ctx
, clk_mgr
);
134 dce_clk_mgr_construct(ctx
, clk_mgr
);
137 dce110_clk_mgr_construct(ctx
, clk_mgr
);
140 if (ASIC_REV_IS_TONGA_P(asic_id
.hw_internal_rev
) ||
141 ASIC_REV_IS_FIJI_P(asic_id
.hw_internal_rev
)) {
142 dce_clk_mgr_construct(ctx
, clk_mgr
);
145 if (ASIC_REV_IS_POLARIS10_P(asic_id
.hw_internal_rev
) ||
146 ASIC_REV_IS_POLARIS11_M(asic_id
.hw_internal_rev
) ||
147 ASIC_REV_IS_POLARIS12_V(asic_id
.hw_internal_rev
)) {
148 dce112_clk_mgr_construct(ctx
, clk_mgr
);
151 if (ASIC_REV_IS_VEGAM(asic_id
.hw_internal_rev
)) {
152 dce112_clk_mgr_construct(ctx
, clk_mgr
);
157 if (ASICREV_IS_VEGA20_P(asic_id
.hw_internal_rev
))
158 dce121_clk_mgr_construct(ctx
, clk_mgr
);
160 dce120_clk_mgr_construct(ctx
, clk_mgr
);
163 #if defined(CONFIG_DRM_AMD_DC_DCN)
165 if (ASICREV_IS_RENOIR(asic_id
.hw_internal_rev
)) {
166 rn_clk_mgr_construct(ctx
, clk_mgr
, pp_smu
, dccg
);
170 if (ASICREV_IS_GREEN_SARDINE(asic_id
.hw_internal_rev
)) {
171 rn_clk_mgr_construct(ctx
, clk_mgr
, pp_smu
, dccg
);
174 if (ASICREV_IS_RAVEN2(asic_id
.hw_internal_rev
)) {
175 rv2_clk_mgr_construct(ctx
, clk_mgr
, pp_smu
);
178 if (ASICREV_IS_RAVEN(asic_id
.hw_internal_rev
) ||
179 ASICREV_IS_PICASSO(asic_id
.hw_internal_rev
)) {
180 rv1_clk_mgr_construct(ctx
, clk_mgr
, pp_smu
);
186 if (ASICREV_IS_SIENNA_CICHLID_P(asic_id
.hw_internal_rev
)) {
187 dcn3_clk_mgr_construct(ctx
, clk_mgr
, pp_smu
, dccg
);
190 if (ASICREV_IS_DIMGREY_CAVEFISH_P(asic_id
.hw_internal_rev
)) {
191 dcn3_clk_mgr_construct(ctx
, clk_mgr
, pp_smu
, dccg
);
194 dcn20_clk_mgr_construct(ctx
, clk_mgr
, pp_smu
, dccg
);
198 if (ASICREV_IS_VANGOGH(asic_id
.hw_internal_rev
))
199 vg_clk_mgr_construct(ctx
, clk_mgr
, pp_smu
, dccg
);
203 ASSERT(0); /* Unknown Asic */
207 return &clk_mgr
->base
;
210 void dc_destroy_clk_mgr(struct clk_mgr
*clk_mgr_base
)
212 struct clk_mgr_internal
*clk_mgr
= TO_CLK_MGR_INTERNAL(clk_mgr_base
);
214 #ifdef CONFIG_DRM_AMD_DC_DCN
215 switch (clk_mgr_base
->ctx
->asic_id
.chip_family
) {
217 if (ASICREV_IS_SIENNA_CICHLID_P(clk_mgr_base
->ctx
->asic_id
.hw_internal_rev
)) {
218 dcn3_clk_mgr_destroy(clk_mgr
);
223 if (ASICREV_IS_VANGOGH(clk_mgr_base
->ctx
->asic_id
.hw_internal_rev
))
224 vg_clk_mgr_destroy(clk_mgr
);