6a9b3cf3fdaa420fed6d34e763e17b6e58631716
[muen/linux.git] / drivers / gpu / drm / amd / powerplay / smumgr / tonga_smumgr.c
1 /*
2  * Copyright 2015 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  */
23 #include "pp_debug.h"
24 #include <linux/types.h>
25 #include <linux/kernel.h>
26 #include <linux/slab.h>
27 #include <linux/gfp.h>
28
29 #include "smumgr.h"
30 #include "tonga_smumgr.h"
31 #include "smu_ucode_xfer_vi.h"
32 #include "tonga_ppsmc.h"
33 #include "smu/smu_7_1_2_d.h"
34 #include "smu/smu_7_1_2_sh_mask.h"
35 #include "cgs_common.h"
36 #include "tonga_smc.h"
37 #include "smu7_smumgr.h"
38
39
40 static int tonga_start_in_protection_mode(struct pp_hwmgr *hwmgr)
41 {
42         int result;
43
44         /* Assert reset */
45         SMUM_WRITE_VFPF_INDIRECT_FIELD(hwmgr->device, CGS_IND_REG__SMC,
46                 SMC_SYSCON_RESET_CNTL, rst_reg, 1);
47
48         result = smu7_upload_smu_firmware_image(hwmgr);
49         if (result)
50                 return result;
51
52         /* Clear status */
53         cgs_write_ind_register(hwmgr->device, CGS_IND_REG__SMC,
54                 ixSMU_STATUS, 0);
55
56         /* Enable clock */
57         SMUM_WRITE_VFPF_INDIRECT_FIELD(hwmgr->device, CGS_IND_REG__SMC,
58                 SMC_SYSCON_CLOCK_CNTL_0, ck_disable, 0);
59
60         /* De-assert reset */
61         SMUM_WRITE_VFPF_INDIRECT_FIELD(hwmgr->device, CGS_IND_REG__SMC,
62                 SMC_SYSCON_RESET_CNTL, rst_reg, 0);
63
64         /* Set SMU Auto Start */
65         SMUM_WRITE_VFPF_INDIRECT_FIELD(hwmgr->device, CGS_IND_REG__SMC,
66                 SMU_INPUT_DATA, AUTO_START, 1);
67
68         /* Clear firmware interrupt enable flag */
69         cgs_write_ind_register(hwmgr->device, CGS_IND_REG__SMC,
70                 ixFIRMWARE_FLAGS, 0);
71
72         PHM_WAIT_VFPF_INDIRECT_FIELD(hwmgr, SMC_IND,
73                 RCU_UC_EVENTS, INTERRUPTS_ENABLED, 1);
74
75         /**
76          * Call Test SMU message with 0x20000 offset to trigger SMU start
77          */
78         smu7_send_msg_to_smc_offset(hwmgr);
79
80         /* Wait for done bit to be set */
81         PHM_WAIT_VFPF_INDIRECT_FIELD_UNEQUAL(hwmgr, SMC_IND,
82                 SMU_STATUS, SMU_DONE, 0);
83
84         /* Check pass/failed indicator */
85         if (1 != SMUM_READ_VFPF_INDIRECT_FIELD(hwmgr->device,
86                                 CGS_IND_REG__SMC, SMU_STATUS, SMU_PASS)) {
87                 pr_err("SMU Firmware start failed\n");
88                 return -EINVAL;
89         }
90
91         /* Wait for firmware to initialize */
92         PHM_WAIT_VFPF_INDIRECT_FIELD(hwmgr, SMC_IND,
93                 FIRMWARE_FLAGS, INTERRUPTS_ENABLED, 1);
94
95         return 0;
96 }
97
98
99 static int tonga_start_in_non_protection_mode(struct pp_hwmgr *hwmgr)
100 {
101         int result = 0;
102
103         /* wait for smc boot up */
104         PHM_WAIT_VFPF_INDIRECT_FIELD_UNEQUAL(hwmgr, SMC_IND,
105                 RCU_UC_EVENTS, boot_seq_done, 0);
106
107         /*Clear firmware interrupt enable flag*/
108         cgs_write_ind_register(hwmgr->device, CGS_IND_REG__SMC,
109                 ixFIRMWARE_FLAGS, 0);
110
111
112         SMUM_WRITE_VFPF_INDIRECT_FIELD(hwmgr->device, CGS_IND_REG__SMC,
113                 SMC_SYSCON_RESET_CNTL, rst_reg, 1);
114
115         result = smu7_upload_smu_firmware_image(hwmgr);
116
117         if (result != 0)
118                 return result;
119
120         /* Set smc instruct start point at 0x0 */
121         smu7_program_jump_on_start(hwmgr);
122
123
124         SMUM_WRITE_VFPF_INDIRECT_FIELD(hwmgr->device, CGS_IND_REG__SMC,
125                 SMC_SYSCON_CLOCK_CNTL_0, ck_disable, 0);
126
127         /*De-assert reset*/
128         SMUM_WRITE_VFPF_INDIRECT_FIELD(hwmgr->device, CGS_IND_REG__SMC,
129                 SMC_SYSCON_RESET_CNTL, rst_reg, 0);
130
131         /* Wait for firmware to initialize */
132         PHM_WAIT_VFPF_INDIRECT_FIELD(hwmgr, SMC_IND,
133                 FIRMWARE_FLAGS, INTERRUPTS_ENABLED, 1);
134
135         return result;
136 }
137
138 static int tonga_start_smu(struct pp_hwmgr *hwmgr)
139 {
140         int result;
141
142         /* Only start SMC if SMC RAM is not running */
143         if (!(smu7_is_smc_ram_running(hwmgr) ||
144                 cgs_is_virtualization_enabled(hwmgr->device))) {
145                 /*Check if SMU is running in protected mode*/
146                 if (0 == SMUM_READ_VFPF_INDIRECT_FIELD(hwmgr->device, CGS_IND_REG__SMC,
147                                         SMU_FIRMWARE, SMU_MODE)) {
148                         result = tonga_start_in_non_protection_mode(hwmgr);
149                         if (result)
150                                 return result;
151                 } else {
152                         result = tonga_start_in_protection_mode(hwmgr);
153                         if (result)
154                                 return result;
155                 }
156         }
157
158         result = smu7_request_smu_load_fw(hwmgr);
159
160         return result;
161 }
162
163 /**
164  * Write a 32bit value to the SMC SRAM space.
165  * ALL PARAMETERS ARE IN HOST BYTE ORDER.
166  * @param    smumgr  the address of the powerplay hardware manager.
167  * @param    smcAddress the address in the SMC RAM to access.
168  * @param    value to write to the SMC SRAM.
169  */
170 static int tonga_smu_init(struct pp_hwmgr *hwmgr)
171 {
172         struct tonga_smumgr *tonga_priv = NULL;
173         int  i;
174
175         tonga_priv = kzalloc(sizeof(struct tonga_smumgr), GFP_KERNEL);
176         if (tonga_priv == NULL)
177                 return -ENOMEM;
178
179         hwmgr->smu_backend = tonga_priv;
180
181         if (smu7_init(hwmgr))
182                 return -EINVAL;
183
184         for (i = 0; i < SMU72_MAX_LEVELS_GRAPHICS; i++)
185                 tonga_priv->activity_target[i] = 30;
186
187         return 0;
188 }
189
190 const struct pp_smumgr_func tonga_smu_funcs = {
191         .smu_init = &tonga_smu_init,
192         .smu_fini = &smu7_smu_fini,
193         .start_smu = &tonga_start_smu,
194         .check_fw_load_finish = &smu7_check_fw_load_finish,
195         .request_smu_load_fw = &smu7_request_smu_load_fw,
196         .request_smu_load_specific_fw = NULL,
197         .send_msg_to_smc = &smu7_send_msg_to_smc,
198         .send_msg_to_smc_with_parameter = &smu7_send_msg_to_smc_with_parameter,
199         .download_pptable_settings = NULL,
200         .upload_pptable_settings = NULL,
201         .update_smc_table = tonga_update_smc_table,
202         .get_offsetof = tonga_get_offsetof,
203         .process_firmware_header = tonga_process_firmware_header,
204         .init_smc_table = tonga_init_smc_table,
205         .update_sclk_threshold = tonga_update_sclk_threshold,
206         .thermal_setup_fan_table = tonga_thermal_setup_fan_table,
207         .populate_all_graphic_levels = tonga_populate_all_graphic_levels,
208         .populate_all_memory_levels = tonga_populate_all_memory_levels,
209         .get_mac_definition = tonga_get_mac_definition,
210         .initialize_mc_reg_table = tonga_initialize_mc_reg_table,
211         .is_dpm_running = tonga_is_dpm_running,
212         .populate_requested_graphic_levels = tonga_populate_requested_graphic_levels,
213 };