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 "dcn10/rv1_clk_mgr.h"
38 #include "dcn10/rv2_clk_mgr.h"
39 #include "dcn20/dcn20_clk_mgr.h"
40 #include "dcn21/rn_clk_mgr.h"
43 int clk_mgr_helper_get_active_display_cnt(
45 struct dc_state
*context
)
50 for (i
= 0; i
< context
->stream_count
; i
++) {
51 const struct dc_stream_state
*stream
= context
->streams
[i
];
54 * Only notify active stream or virtual stream.
55 * Need to notify virtual stream to work around
56 * headless case. HPD does not fire when system is in
59 if (!stream
->dpms_off
|| stream
->signal
== SIGNAL_TYPE_VIRTUAL
)
66 void clk_mgr_exit_optimized_pwr_state(const struct dc
*dc
, struct clk_mgr
*clk_mgr
)
68 struct dc_link
*edp_link
= get_edp_link(dc
);
70 if (dc
->hwss
.exit_optimized_pwr_state
)
71 dc
->hwss
.exit_optimized_pwr_state(dc
, dc
->current_state
);
74 clk_mgr
->psr_allow_active_cache
= edp_link
->psr_allow_active
;
75 dc_link_set_psr_allow_active(edp_link
, false, false);
80 void clk_mgr_optimize_pwr_state(const struct dc
*dc
, struct clk_mgr
*clk_mgr
)
82 struct dc_link
*edp_link
= get_edp_link(dc
);
85 dc_link_set_psr_allow_active(edp_link
, clk_mgr
->psr_allow_active_cache
, false);
87 if (dc
->hwss
.optimize_pwr_state
)
88 dc
->hwss
.optimize_pwr_state(dc
, dc
->current_state
);
92 struct clk_mgr
*dc_clk_mgr_create(struct dc_context
*ctx
, struct pp_smu_funcs
*pp_smu
, struct dccg
*dccg
)
94 struct hw_asic_id asic_id
= ctx
->asic_id
;
96 struct clk_mgr_internal
*clk_mgr
= kzalloc(sizeof(*clk_mgr
), GFP_KERNEL
);
98 if (clk_mgr
== NULL
) {
103 switch (asic_id
.chip_family
) {
106 dce_clk_mgr_construct(ctx
, clk_mgr
);
109 dce110_clk_mgr_construct(ctx
, clk_mgr
);
112 if (ASIC_REV_IS_TONGA_P(asic_id
.hw_internal_rev
) ||
113 ASIC_REV_IS_FIJI_P(asic_id
.hw_internal_rev
)) {
114 dce_clk_mgr_construct(ctx
, clk_mgr
);
117 if (ASIC_REV_IS_POLARIS10_P(asic_id
.hw_internal_rev
) ||
118 ASIC_REV_IS_POLARIS11_M(asic_id
.hw_internal_rev
) ||
119 ASIC_REV_IS_POLARIS12_V(asic_id
.hw_internal_rev
)) {
120 dce112_clk_mgr_construct(ctx
, clk_mgr
);
123 if (ASIC_REV_IS_VEGAM(asic_id
.hw_internal_rev
)) {
124 dce112_clk_mgr_construct(ctx
, clk_mgr
);
129 if (ASICREV_IS_VEGA20_P(asic_id
.hw_internal_rev
))
130 dce121_clk_mgr_construct(ctx
, clk_mgr
);
132 dce120_clk_mgr_construct(ctx
, clk_mgr
);
135 #if defined(CONFIG_DRM_AMD_DC_DCN)
137 if (ASICREV_IS_DALI(asic_id
.hw_internal_rev
) ||
138 ASICREV_IS_POLLOCK(asic_id
.hw_internal_rev
)) {
139 /* TEMP: this check has to come before ASICREV_IS_RENOIR */
140 /* which also incorrectly returns true for Dali/Pollock*/
141 rv2_clk_mgr_construct(ctx
, clk_mgr
, pp_smu
);
144 if (ASICREV_IS_RENOIR(asic_id
.hw_internal_rev
)) {
145 rn_clk_mgr_construct(ctx
, clk_mgr
, pp_smu
, dccg
);
148 if (ASICREV_IS_RAVEN2(asic_id
.hw_internal_rev
)) {
149 rv2_clk_mgr_construct(ctx
, clk_mgr
, pp_smu
);
152 if (ASICREV_IS_RAVEN(asic_id
.hw_internal_rev
) ||
153 ASICREV_IS_PICASSO(asic_id
.hw_internal_rev
)) {
154 rv1_clk_mgr_construct(ctx
, clk_mgr
, pp_smu
);
160 dcn20_clk_mgr_construct(ctx
, clk_mgr
, pp_smu
, dccg
);
162 #endif /* Family RV and NV*/
165 ASSERT(0); /* Unknown Asic */
169 return &clk_mgr
->base
;
172 void dc_destroy_clk_mgr(struct clk_mgr
*clk_mgr_base
)
174 struct clk_mgr_internal
*clk_mgr
= TO_CLK_MGR_INTERNAL(clk_mgr_base
);