root/drivers/gpu/drm/amd/display/dc/inc/hw/clk_mgr.h

/* [<][>][^][v][top][bottom][index][help] */

INCLUDED FROM


   1 /*
   2  * Copyright 2012-16 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 #ifndef __DAL_CLK_MGR_H__
  27 #define __DAL_CLK_MGR_H__
  28 
  29 #include "dc.h"
  30 
  31 #define DCN_MINIMUM_DISPCLK_Khz 100000
  32 #define DCN_MINIMUM_DPPCLK_Khz 100000
  33 
  34 #ifdef CONFIG_DRM_AMD_DC_DCN2_1
  35 /* Constants */
  36 #define DDR4_DRAM_WIDTH   64
  37 #define WM_A 0
  38 #define WM_B 1
  39 #define WM_C 2
  40 #define WM_D 3
  41 #define WM_SET_COUNT 4
  42 #endif
  43 
  44 #define DCN_MINIMUM_DISPCLK_Khz 100000
  45 #define DCN_MINIMUM_DPPCLK_Khz 100000
  46 
  47 #ifdef CONFIG_DRM_AMD_DC_DCN2_1
  48 /* Will these bw structures be ASIC specific? */
  49 
  50 #define MAX_NUM_DPM_LVL         4
  51 #define WM_SET_COUNT            4
  52 
  53 
  54 struct clk_limit_table_entry {
  55         unsigned int voltage; /* milivolts withh 2 fractional bits */
  56         unsigned int dcfclk_mhz;
  57         unsigned int fclk_mhz;
  58         unsigned int memclk_mhz;
  59         unsigned int socclk_mhz;
  60 };
  61 
  62 /* This table is contiguous */
  63 struct clk_limit_table {
  64         struct clk_limit_table_entry entries[MAX_NUM_DPM_LVL];
  65         unsigned int num_entries;
  66 };
  67 
  68 struct wm_range_table_entry {
  69         unsigned int wm_inst;
  70         unsigned int wm_type;
  71         double pstate_latency_us;
  72         bool valid;
  73 };
  74 
  75 
  76 struct clk_log_info {
  77         bool enabled;
  78         char *pBuf;
  79         unsigned int bufSize;
  80         unsigned int *sum_chars_printed;
  81 };
  82 
  83 struct clk_state_registers_and_bypass {
  84         uint32_t dcfclk;
  85         uint32_t dcf_deep_sleep_divider;
  86         uint32_t dcf_deep_sleep_allow;
  87         uint32_t dprefclk;
  88         uint32_t dispclk;
  89         uint32_t dppclk;
  90 
  91         uint32_t dppclk_bypass;
  92         uint32_t dcfclk_bypass;
  93         uint32_t dprefclk_bypass;
  94         uint32_t dispclk_bypass;
  95 };
  96 
  97 struct rv1_clk_internal {
  98         uint32_t CLK0_CLK8_CURRENT_CNT;  //dcfclk
  99         uint32_t CLK0_CLK8_DS_CNTL;              //dcf_deep_sleep_divider
 100         uint32_t CLK0_CLK8_ALLOW_DS;     //dcf_deep_sleep_allow
 101         uint32_t CLK0_CLK10_CURRENT_CNT; //dprefclk
 102         uint32_t CLK0_CLK11_CURRENT_CNT; //dispclk
 103 
 104         uint32_t CLK0_CLK8_BYPASS_CNTL;  //dcfclk bypass
 105         uint32_t CLK0_CLK10_BYPASS_CNTL; //dprefclk bypass
 106         uint32_t CLK0_CLK11_BYPASS_CNTL; //dispclk bypass
 107 };
 108 
 109 struct rn_clk_internal {
 110         uint32_t CLK1_CLK0_CURRENT_CNT; //dispclk
 111         uint32_t CLK1_CLK1_CURRENT_CNT; //dppclk
 112         uint32_t CLK1_CLK2_CURRENT_CNT; //dprefclk
 113         uint32_t CLK1_CLK3_CURRENT_CNT; //dcfclk
 114         uint32_t CLK1_CLK3_DS_CNTL;             //dcf_deep_sleep_divider
 115         uint32_t CLK1_CLK3_ALLOW_DS;    //dcf_deep_sleep_allow
 116 
 117         uint32_t CLK1_CLK0_BYPASS_CNTL; //dispclk bypass
 118         uint32_t CLK1_CLK1_BYPASS_CNTL; //dppclk bypass
 119         uint32_t CLK1_CLK2_BYPASS_CNTL; //dprefclk bypass
 120         uint32_t CLK1_CLK3_BYPASS_CNTL; //dcfclk bypass
 121 
 122 };
 123 
 124 /* For dtn logging and debugging */
 125 struct clk_state_registers {
 126                 uint32_t CLK0_CLK8_CURRENT_CNT;  //dcfclk
 127                 uint32_t CLK0_CLK8_DS_CNTL;              //dcf_deep_sleep_divider
 128                 uint32_t CLK0_CLK8_ALLOW_DS;     //dcf_deep_sleep_allow
 129                 uint32_t CLK0_CLK10_CURRENT_CNT; //dprefclk
 130                 uint32_t CLK0_CLK11_CURRENT_CNT; //dispclk
 131 };
 132 
 133 /* TODO: combine this with the above */
 134 struct clk_bypass {
 135         uint32_t dcfclk_bypass;
 136         uint32_t dispclk_pypass;
 137         uint32_t dprefclk_bypass;
 138 };
 139 /*
 140  * This table is not contiguous, can have holes, each
 141  * entry correspond to one set of WM. For example if
 142  * we have 2 DPM and LPDDR, we will WM set A, B and
 143  * D occupied, C will be emptry.
 144  */
 145 struct wm_table {
 146         struct wm_range_table_entry entries[WM_SET_COUNT];
 147 };
 148 
 149 struct clk_bw_params {
 150         unsigned int vram_type;
 151         unsigned int num_channels;
 152         struct clk_limit_table clk_table;
 153         struct wm_table wm_table;
 154 };
 155 #endif
 156 /* Public interfaces */
 157 
 158 struct clk_states {
 159         uint32_t dprefclk_khz;
 160 };
 161 
 162 struct clk_mgr_funcs {
 163         /*
 164          * This function should set new clocks based on the input "safe_to_lower".
 165          * If safe_to_lower == false, then only clocks which are to be increased
 166          * should changed.
 167          * If safe_to_lower == true, then only clocks which are to be decreased
 168          * should be changed.
 169          */
 170         void (*update_clocks)(struct clk_mgr *clk_mgr,
 171                         struct dc_state *context,
 172                         bool safe_to_lower);
 173 
 174         int (*get_dp_ref_clk_frequency)(struct clk_mgr *clk_mgr);
 175 
 176         void (*init_clocks)(struct clk_mgr *clk_mgr);
 177 
 178         void (*enable_pme_wa) (struct clk_mgr *clk_mgr);
 179         void (*get_clock)(struct clk_mgr *clk_mgr,
 180                         struct dc_state *context,
 181                         enum dc_clock_type clock_type,
 182                         struct dc_clock_config *clock_cfg);
 183 };
 184 
 185 struct clk_mgr {
 186         struct dc_context *ctx;
 187         struct clk_mgr_funcs *funcs;
 188         struct dc_clocks clks;
 189         int dprefclk_khz; // Used by program pixel clock in clock source funcs, need to figureout where this goes
 190 #ifdef CONFIG_DRM_AMD_DC_DCN2_1
 191         struct clk_bw_params *bw_params;
 192 #endif
 193 };
 194 
 195 /* forward declarations */
 196 struct dccg;
 197 
 198 struct clk_mgr *dc_clk_mgr_create(struct dc_context *ctx, struct pp_smu_funcs *pp_smu, struct dccg *dccg);
 199 
 200 void dc_destroy_clk_mgr(struct clk_mgr *clk_mgr);
 201 
 202 #endif /* __DAL_CLK_MGR_H__ */

/* [<][>][^][v][top][bottom][index][help] */