Merge remote-tracking branch 'lightnvm/for-next'
[deliverable/linux.git] / drivers / gpu / drm / amd / powerplay / smumgr / iceland_smumgr.c
1 /*
2 * Copyright 2016 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 * Author: Huang Rui <ray.huang@amd.com>
23 *
24 */
25 #include <linux/types.h>
26 #include <linux/kernel.h>
27 #include <linux/slab.h>
28 #include <linux/gfp.h>
29
30 #include "smumgr.h"
31 #include "iceland_smumgr.h"
32 #include "pp_debug.h"
33 #include "smu_ucode_xfer_vi.h"
34 #include "ppsmc.h"
35 #include "smu/smu_7_1_1_d.h"
36 #include "smu/smu_7_1_1_sh_mask.h"
37 #include "cgs_common.h"
38
39 #define ICELAND_SMC_SIZE 0x20000
40 #define BUFFER_SIZE 80000
41 #define MAX_STRING_SIZE 15
42 #define BUFFER_SIZETWO 131072 /*128 *1024*/
43
44 /**
45 * Set the address for reading/writing the SMC SRAM space.
46 * @param smumgr the address of the powerplay hardware manager.
47 * @param smcAddress the address in the SMC RAM to access.
48 */
49 static int iceland_set_smc_sram_address(struct pp_smumgr *smumgr,
50 uint32_t smcAddress, uint32_t limit)
51 {
52 if (smumgr == NULL || smumgr->device == NULL)
53 return -EINVAL;
54 PP_ASSERT_WITH_CODE((0 == (3 & smcAddress)),
55 "SMC address must be 4 byte aligned.",
56 return -1;);
57
58 PP_ASSERT_WITH_CODE((limit > (smcAddress + 3)),
59 "SMC address is beyond the SMC RAM area.",
60 return -1;);
61
62 cgs_write_register(smumgr->device, mmSMC_IND_INDEX_0, smcAddress);
63 SMUM_WRITE_FIELD(smumgr->device, SMC_IND_ACCESS_CNTL, AUTO_INCREMENT_IND_0, 0);
64
65 return 0;
66 }
67
68 /**
69 * Copy bytes from an array into the SMC RAM space.
70 *
71 * @param smumgr the address of the powerplay SMU manager.
72 * @param smcStartAddress the start address in the SMC RAM to copy bytes to.
73 * @param src the byte array to copy the bytes from.
74 * @param byteCount the number of bytes to copy.
75 */
76 int iceland_copy_bytes_to_smc(struct pp_smumgr *smumgr,
77 uint32_t smcStartAddress, const uint8_t *src,
78 uint32_t byteCount, uint32_t limit)
79 {
80 uint32_t addr;
81 uint32_t data, orig_data;
82 int result = 0;
83 uint32_t extra_shift;
84
85 if (smumgr == NULL || smumgr->device == NULL)
86 return -EINVAL;
87 PP_ASSERT_WITH_CODE((0 == (3 & smcStartAddress)),
88 "SMC address must be 4 byte aligned.",
89 return 0;);
90
91 PP_ASSERT_WITH_CODE((limit > (smcStartAddress + byteCount)),
92 "SMC address is beyond the SMC RAM area.",
93 return 0;);
94
95 addr = smcStartAddress;
96
97 while (byteCount >= 4) {
98 /*
99 * Bytes are written into the
100 * SMC address space with the MSB first
101 */
102 data = (src[0] << 24) + (src[1] << 16) + (src[2] << 8) + src[3];
103
104 result = iceland_set_smc_sram_address(smumgr, addr, limit);
105
106 if (result)
107 goto out;
108
109 cgs_write_register(smumgr->device, mmSMC_IND_DATA_0, data);
110
111 src += 4;
112 byteCount -= 4;
113 addr += 4;
114 }
115
116 if (0 != byteCount) {
117 /* Now write odd bytes left, do a read modify write cycle */
118 data = 0;
119
120 result = iceland_set_smc_sram_address(smumgr, addr, limit);
121 if (result)
122 goto out;
123
124 orig_data = cgs_read_register(smumgr->device,
125 mmSMC_IND_DATA_0);
126 extra_shift = 8 * (4 - byteCount);
127
128 while (byteCount > 0) {
129 data = (data << 8) + *src++;
130 byteCount--;
131 }
132
133 data <<= extra_shift;
134 data |= (orig_data & ~((~0UL) << extra_shift));
135
136 result = iceland_set_smc_sram_address(smumgr, addr, limit);
137 if (result)
138 goto out;
139
140 cgs_write_register(smumgr->device, mmSMC_IND_DATA_0, data);
141 }
142
143 out:
144 return result;
145 }
146
147 /**
148 * Deassert the reset'pin' (set it to high).
149 *
150 * @param smumgr the address of the powerplay hardware manager.
151 */
152 static int iceland_start_smc(struct pp_smumgr *smumgr)
153 {
154 SMUM_WRITE_INDIRECT_FIELD(smumgr->device, CGS_IND_REG__SMC,
155 SMC_SYSCON_RESET_CNTL, rst_reg, 0);
156
157 return 0;
158 }
159
160 static void iceland_pp_reset_smc(struct pp_smumgr *smumgr)
161 {
162 SMUM_WRITE_INDIRECT_FIELD(smumgr->device, CGS_IND_REG__SMC,
163 SMC_SYSCON_RESET_CNTL,
164 rst_reg, 1);
165 }
166
167 int iceland_program_jump_on_start(struct pp_smumgr *smumgr)
168 {
169 static const unsigned char pData[] = { 0xE0, 0x00, 0x80, 0x40 };
170
171 iceland_copy_bytes_to_smc(smumgr, 0x0, pData, 4, sizeof(pData)+1);
172
173 return 0;
174 }
175
176 /**
177 * Return if the SMC is currently running.
178 *
179 * @param smumgr the address of the powerplay hardware manager.
180 */
181 bool iceland_is_smc_ram_running(struct pp_smumgr *smumgr)
182 {
183 uint32_t val1, val2;
184
185 val1 = SMUM_READ_INDIRECT_FIELD(smumgr->device, CGS_IND_REG__SMC,
186 SMC_SYSCON_CLOCK_CNTL_0, ck_disable);
187 val2 = cgs_read_ind_register(smumgr->device, CGS_IND_REG__SMC,
188 ixSMC_PC_C);
189
190 return ((0 == val1) && (0x20100 <= val2));
191 }
192
193 /**
194 * Send a message to the SMC, and wait for its response.
195 *
196 * @param smumgr the address of the powerplay hardware manager.
197 * @param msg the message to send.
198 * @return The response that came from the SMC.
199 */
200 static int iceland_send_msg_to_smc(struct pp_smumgr *smumgr, uint16_t msg)
201 {
202 if (smumgr == NULL || smumgr->device == NULL)
203 return -EINVAL;
204
205 if (!iceland_is_smc_ram_running(smumgr))
206 return -EINVAL;
207
208 SMUM_WAIT_FIELD_UNEQUAL(smumgr, SMC_RESP_0, SMC_RESP, 0);
209 PP_ASSERT_WITH_CODE(
210 1 == SMUM_READ_FIELD(smumgr->device, SMC_RESP_0, SMC_RESP),
211 "Failed to send Previous Message.",
212 );
213
214 cgs_write_register(smumgr->device, mmSMC_MESSAGE_0, msg);
215
216 SMUM_WAIT_FIELD_UNEQUAL(smumgr, SMC_RESP_0, SMC_RESP, 0);
217 PP_ASSERT_WITH_CODE(
218 1 == SMUM_READ_FIELD(smumgr->device, SMC_RESP_0, SMC_RESP),
219 "Failed to send Message.",
220 );
221
222 return 0;
223 }
224
225 /**
226 * Send a message to the SMC with parameter
227 *
228 * @param smumgr: the address of the powerplay hardware manager.
229 * @param msg: the message to send.
230 * @param parameter: the parameter to send
231 * @return The response that came from the SMC.
232 */
233 static int iceland_send_msg_to_smc_with_parameter(struct pp_smumgr *smumgr,
234 uint16_t msg, uint32_t parameter)
235 {
236 if (smumgr == NULL || smumgr->device == NULL)
237 return -EINVAL;
238
239 cgs_write_register(smumgr->device, mmSMC_MSG_ARG_0, parameter);
240
241 return iceland_send_msg_to_smc(smumgr, msg);
242 }
243
244 /*
245 * Read a 32bit value from the SMC SRAM space.
246 * ALL PARAMETERS ARE IN HOST BYTE ORDER.
247 * @param smumgr the address of the powerplay hardware manager.
248 * @param smcAddress the address in the SMC RAM to access.
249 * @param value and output parameter for the data read from the SMC SRAM.
250 */
251 int iceland_read_smc_sram_dword(struct pp_smumgr *smumgr,
252 uint32_t smcAddress, uint32_t *value,
253 uint32_t limit)
254 {
255 int result;
256
257 result = iceland_set_smc_sram_address(smumgr, smcAddress, limit);
258
259 if (0 != result)
260 return result;
261
262 *value = cgs_read_register(smumgr->device, mmSMC_IND_DATA_0);
263
264 return 0;
265 }
266
267 /*
268 * Write a 32bit value to the SMC SRAM space.
269 * ALL PARAMETERS ARE IN HOST BYTE ORDER.
270 * @param smumgr the address of the powerplay hardware manager.
271 * @param smcAddress the address in the SMC RAM to access.
272 * @param value to write to the SMC SRAM.
273 */
274 int iceland_write_smc_sram_dword(struct pp_smumgr *smumgr,
275 uint32_t smcAddress, uint32_t value,
276 uint32_t limit)
277 {
278 int result;
279
280 result = iceland_set_smc_sram_address(smumgr, smcAddress, limit);
281
282 if (0 != result)
283 return result;
284
285 cgs_write_register(smumgr->device, mmSMC_IND_DATA_0, value);
286
287 return 0;
288 }
289
290 static int iceland_smu_fini(struct pp_smumgr *smumgr)
291 {
292 struct iceland_smumgr *priv = (struct iceland_smumgr *)(smumgr->backend);
293
294 smu_free_memory(smumgr->device, (void *)priv->header_buffer.handle);
295
296 if (smumgr->backend != NULL) {
297 kfree(smumgr->backend);
298 smumgr->backend = NULL;
299 }
300
301 cgs_rel_firmware(smumgr->device, CGS_UCODE_ID_SMU);
302 return 0;
303 }
304
305 static enum cgs_ucode_id iceland_convert_fw_type_to_cgs(uint32_t fw_type)
306 {
307 enum cgs_ucode_id result = CGS_UCODE_ID_MAXIMUM;
308
309 switch (fw_type) {
310 case UCODE_ID_SMU:
311 result = CGS_UCODE_ID_SMU;
312 break;
313 case UCODE_ID_SDMA0:
314 result = CGS_UCODE_ID_SDMA0;
315 break;
316 case UCODE_ID_SDMA1:
317 result = CGS_UCODE_ID_SDMA1;
318 break;
319 case UCODE_ID_CP_CE:
320 result = CGS_UCODE_ID_CP_CE;
321 break;
322 case UCODE_ID_CP_PFP:
323 result = CGS_UCODE_ID_CP_PFP;
324 break;
325 case UCODE_ID_CP_ME:
326 result = CGS_UCODE_ID_CP_ME;
327 break;
328 case UCODE_ID_CP_MEC:
329 result = CGS_UCODE_ID_CP_MEC;
330 break;
331 case UCODE_ID_CP_MEC_JT1:
332 result = CGS_UCODE_ID_CP_MEC_JT1;
333 break;
334 case UCODE_ID_CP_MEC_JT2:
335 result = CGS_UCODE_ID_CP_MEC_JT2;
336 break;
337 case UCODE_ID_RLC_G:
338 result = CGS_UCODE_ID_RLC_G;
339 break;
340 default:
341 break;
342 }
343
344 return result;
345 }
346
347 /**
348 * Convert the PPIRI firmware type to SMU type mask.
349 * For MEC, we need to check all MEC related type
350 */
351 static uint16_t iceland_get_mask_for_firmware_type(uint16_t firmwareType)
352 {
353 uint16_t result = 0;
354
355 switch (firmwareType) {
356 case UCODE_ID_SDMA0:
357 result = UCODE_ID_SDMA0_MASK;
358 break;
359 case UCODE_ID_SDMA1:
360 result = UCODE_ID_SDMA1_MASK;
361 break;
362 case UCODE_ID_CP_CE:
363 result = UCODE_ID_CP_CE_MASK;
364 break;
365 case UCODE_ID_CP_PFP:
366 result = UCODE_ID_CP_PFP_MASK;
367 break;
368 case UCODE_ID_CP_ME:
369 result = UCODE_ID_CP_ME_MASK;
370 break;
371 case UCODE_ID_CP_MEC:
372 case UCODE_ID_CP_MEC_JT1:
373 case UCODE_ID_CP_MEC_JT2:
374 result = UCODE_ID_CP_MEC_MASK;
375 break;
376 case UCODE_ID_RLC_G:
377 result = UCODE_ID_RLC_G_MASK;
378 break;
379 default:
380 break;
381 }
382
383 return result;
384 }
385
386 /**
387 * Check if the FW has been loaded,
388 * SMU will not return if loading has not finished.
389 */
390 static int iceland_check_fw_load_finish(struct pp_smumgr *smumgr, uint32_t fwType)
391 {
392 uint16_t fwMask = iceland_get_mask_for_firmware_type(fwType);
393
394 if (0 != SMUM_WAIT_VFPF_INDIRECT_REGISTER(smumgr, SMC_IND,
395 SOFT_REGISTERS_TABLE_27, fwMask, fwMask)) {
396 pr_err("[ powerplay ] check firmware loading failed\n");
397 return -EINVAL;
398 }
399
400 return 0;
401 }
402
403 /* Populate one firmware image to the data structure */
404 static int iceland_populate_single_firmware_entry(struct pp_smumgr *smumgr,
405 uint16_t firmware_type,
406 struct SMU_Entry *pentry)
407 {
408 int result;
409 struct cgs_firmware_info info = {0};
410
411 result = cgs_get_firmware_info(
412 smumgr->device,
413 iceland_convert_fw_type_to_cgs(firmware_type),
414 &info);
415
416 if (result == 0) {
417 pentry->version = 0;
418 pentry->id = (uint16_t)firmware_type;
419 pentry->image_addr_high = smu_upper_32_bits(info.mc_addr);
420 pentry->image_addr_low = smu_lower_32_bits(info.mc_addr);
421 pentry->meta_data_addr_high = 0;
422 pentry->meta_data_addr_low = 0;
423 pentry->data_size_byte = info.image_size;
424 pentry->num_register_entries = 0;
425
426 if (firmware_type == UCODE_ID_RLC_G)
427 pentry->flags = 1;
428 else
429 pentry->flags = 0;
430 } else {
431 return result;
432 }
433
434 return result;
435 }
436
437 static void iceland_pp_stop_smc_clock(struct pp_smumgr *smumgr)
438 {
439 SMUM_WRITE_INDIRECT_FIELD(smumgr->device, CGS_IND_REG__SMC,
440 SMC_SYSCON_CLOCK_CNTL_0,
441 ck_disable, 1);
442 }
443
444 static void iceland_start_smc_clock(struct pp_smumgr *smumgr)
445 {
446 SMUM_WRITE_INDIRECT_FIELD(smumgr->device, CGS_IND_REG__SMC,
447 SMC_SYSCON_CLOCK_CNTL_0,
448 ck_disable, 0);
449 }
450
451 int iceland_smu_start_smc(struct pp_smumgr *smumgr)
452 {
453 /* set smc instruct start point at 0x0 */
454 iceland_program_jump_on_start(smumgr);
455
456 /* enable smc clock */
457 iceland_start_smc_clock(smumgr);
458
459 /* de-assert reset */
460 iceland_start_smc(smumgr);
461
462 SMUM_WAIT_INDIRECT_FIELD(smumgr, SMC_IND, FIRMWARE_FLAGS,
463 INTERRUPTS_ENABLED, 1);
464
465 return 0;
466 }
467
468 /**
469 * Upload the SMC firmware to the SMC microcontroller.
470 *
471 * @param smumgr the address of the powerplay hardware manager.
472 * @param pFirmware the data structure containing the various sections of the firmware.
473 */
474 int iceland_smu_upload_firmware_image(struct pp_smumgr *smumgr)
475 {
476 const uint8_t *src;
477 uint32_t byte_count, val;
478 uint32_t data;
479 struct cgs_firmware_info info = {0};
480
481 if (smumgr == NULL || smumgr->device == NULL)
482 return -EINVAL;
483
484 /* load SMC firmware */
485 cgs_get_firmware_info(smumgr->device,
486 iceland_convert_fw_type_to_cgs(UCODE_ID_SMU), &info);
487
488 if (info.image_size & 3) {
489 pr_err("[ powerplay ] SMC ucode is not 4 bytes aligned\n");
490 return -EINVAL;
491 }
492
493 if (info.image_size > ICELAND_SMC_SIZE) {
494 pr_err("[ powerplay ] SMC address is beyond the SMC RAM area\n");
495 return -EINVAL;
496 }
497
498 /* wait for smc boot up */
499 SMUM_WAIT_INDIRECT_FIELD_UNEQUAL(smumgr, SMC_IND,
500 RCU_UC_EVENTS, boot_seq_done, 0);
501
502 /* clear firmware interrupt enable flag */
503 val = cgs_read_ind_register(smumgr->device, CGS_IND_REG__SMC,
504 ixSMC_SYSCON_MISC_CNTL);
505 cgs_write_ind_register(smumgr->device, CGS_IND_REG__SMC,
506 ixSMC_SYSCON_MISC_CNTL, val | 1);
507
508 /* stop smc clock */
509 iceland_pp_stop_smc_clock(smumgr);
510
511 /* reset smc */
512 iceland_pp_reset_smc(smumgr);
513
514 cgs_write_register(smumgr->device, mmSMC_IND_INDEX_0,
515 info.ucode_start_address);
516
517 SMUM_WRITE_FIELD(smumgr->device, SMC_IND_ACCESS_CNTL,
518 AUTO_INCREMENT_IND_0, 1);
519
520 byte_count = info.image_size;
521 src = (const uint8_t *)info.kptr;
522
523 while (byte_count >= 4) {
524 data = (src[0] << 24) + (src[1] << 16) + (src[2] << 8) + src[3];
525 cgs_write_register(smumgr->device, mmSMC_IND_DATA_0, data);
526 src += 4;
527 byte_count -= 4;
528 }
529
530 SMUM_WRITE_FIELD(smumgr->device, SMC_IND_ACCESS_CNTL,
531 AUTO_INCREMENT_IND_0, 0);
532
533 return 0;
534 }
535
536 static int iceland_request_smu_reload_fw(struct pp_smumgr *smumgr)
537 {
538 struct iceland_smumgr *iceland_smu =
539 (struct iceland_smumgr *)(smumgr->backend);
540 uint16_t fw_to_load;
541 int result = 0;
542 struct SMU_DRAMData_TOC *toc;
543
544 toc = (struct SMU_DRAMData_TOC *)iceland_smu->pHeader;
545 toc->num_entries = 0;
546 toc->structure_version = 1;
547
548 PP_ASSERT_WITH_CODE(
549 0 == iceland_populate_single_firmware_entry(smumgr,
550 UCODE_ID_RLC_G,
551 &toc->entry[toc->num_entries++]),
552 "Failed to Get Firmware Entry.\n",
553 return -1);
554 PP_ASSERT_WITH_CODE(
555 0 == iceland_populate_single_firmware_entry(smumgr,
556 UCODE_ID_CP_CE,
557 &toc->entry[toc->num_entries++]),
558 "Failed to Get Firmware Entry.\n",
559 return -1);
560 PP_ASSERT_WITH_CODE(
561 0 == iceland_populate_single_firmware_entry
562 (smumgr, UCODE_ID_CP_PFP, &toc->entry[toc->num_entries++]),
563 "Failed to Get Firmware Entry.\n", return -1);
564 PP_ASSERT_WITH_CODE(
565 0 == iceland_populate_single_firmware_entry
566 (smumgr, UCODE_ID_CP_ME, &toc->entry[toc->num_entries++]),
567 "Failed to Get Firmware Entry.\n", return -1);
568 PP_ASSERT_WITH_CODE(
569 0 == iceland_populate_single_firmware_entry
570 (smumgr, UCODE_ID_CP_MEC, &toc->entry[toc->num_entries++]),
571 "Failed to Get Firmware Entry.\n", return -1);
572 PP_ASSERT_WITH_CODE(
573 0 == iceland_populate_single_firmware_entry
574 (smumgr, UCODE_ID_CP_MEC_JT1, &toc->entry[toc->num_entries++]),
575 "Failed to Get Firmware Entry.\n", return -1);
576 PP_ASSERT_WITH_CODE(
577 0 == iceland_populate_single_firmware_entry
578 (smumgr, UCODE_ID_CP_MEC_JT2, &toc->entry[toc->num_entries++]),
579 "Failed to Get Firmware Entry.\n", return -1);
580 PP_ASSERT_WITH_CODE(
581 0 == iceland_populate_single_firmware_entry
582 (smumgr, UCODE_ID_SDMA0, &toc->entry[toc->num_entries++]),
583 "Failed to Get Firmware Entry.\n", return -1);
584 PP_ASSERT_WITH_CODE(
585 0 == iceland_populate_single_firmware_entry
586 (smumgr, UCODE_ID_SDMA1, &toc->entry[toc->num_entries++]),
587 "Failed to Get Firmware Entry.\n", return -1);
588
589 if (!iceland_is_smc_ram_running(smumgr)) {
590 result = iceland_smu_upload_firmware_image(smumgr);
591 if (result)
592 return result;
593
594 result = iceland_smu_start_smc(smumgr);
595 if (result)
596 return result;
597 }
598
599 iceland_send_msg_to_smc_with_parameter(smumgr,
600 PPSMC_MSG_DRV_DRAM_ADDR_HI,
601 iceland_smu->header_buffer.mc_addr_high);
602
603 iceland_send_msg_to_smc_with_parameter(smumgr,
604 PPSMC_MSG_DRV_DRAM_ADDR_LO,
605 iceland_smu->header_buffer.mc_addr_low);
606
607 fw_to_load = UCODE_ID_RLC_G_MASK
608 + UCODE_ID_SDMA0_MASK
609 + UCODE_ID_SDMA1_MASK
610 + UCODE_ID_CP_CE_MASK
611 + UCODE_ID_CP_ME_MASK
612 + UCODE_ID_CP_PFP_MASK
613 + UCODE_ID_CP_MEC_MASK
614 + UCODE_ID_CP_MEC_JT1_MASK
615 + UCODE_ID_CP_MEC_JT2_MASK;
616
617 PP_ASSERT_WITH_CODE(
618 0 == iceland_send_msg_to_smc_with_parameter(
619 smumgr, PPSMC_MSG_LoadUcodes, fw_to_load),
620 "Fail to Request SMU Load uCode", return 0);
621
622 return result;
623 }
624
625 static int iceland_request_smu_load_specific_fw(struct pp_smumgr *smumgr,
626 uint32_t firmwareType)
627 {
628 return 0;
629 }
630
631 static int iceland_start_smu(struct pp_smumgr *smumgr)
632 {
633 int result;
634
635 result = iceland_smu_upload_firmware_image(smumgr);
636 if (result)
637 return result;
638
639 result = iceland_smu_start_smc(smumgr);
640 if (result)
641 return result;
642
643 result = iceland_request_smu_reload_fw(smumgr);
644
645 return result;
646 }
647
648 /**
649 * Write a 32bit value to the SMC SRAM space.
650 * ALL PARAMETERS ARE IN HOST BYTE ORDER.
651 * @param smumgr the address of the powerplay hardware manager.
652 * @param smcAddress the address in the SMC RAM to access.
653 * @param value to write to the SMC SRAM.
654 */
655 static int iceland_smu_init(struct pp_smumgr *smumgr)
656 {
657 struct iceland_smumgr *iceland_smu;
658 uint64_t mc_addr = 0;
659
660 /* Allocate memory for backend private data */
661 iceland_smu = (struct iceland_smumgr *)(smumgr->backend);
662 iceland_smu->header_buffer.data_size =
663 ((sizeof(struct SMU_DRAMData_TOC) / 4096) + 1) * 4096;
664
665 smu_allocate_memory(smumgr->device,
666 iceland_smu->header_buffer.data_size,
667 CGS_GPU_MEM_TYPE__VISIBLE_CONTIG_FB,
668 PAGE_SIZE,
669 &mc_addr,
670 &iceland_smu->header_buffer.kaddr,
671 &iceland_smu->header_buffer.handle);
672
673 iceland_smu->pHeader = iceland_smu->header_buffer.kaddr;
674 iceland_smu->header_buffer.mc_addr_high = smu_upper_32_bits(mc_addr);
675 iceland_smu->header_buffer.mc_addr_low = smu_lower_32_bits(mc_addr);
676
677 PP_ASSERT_WITH_CODE((NULL != iceland_smu->pHeader),
678 "Out of memory.",
679 kfree(smumgr->backend);
680 cgs_free_gpu_mem(smumgr->device,
681 (cgs_handle_t)iceland_smu->header_buffer.handle);
682 return -1);
683
684 return 0;
685 }
686
687 static const struct pp_smumgr_func iceland_smu_funcs = {
688 .smu_init = &iceland_smu_init,
689 .smu_fini = &iceland_smu_fini,
690 .start_smu = &iceland_start_smu,
691 .check_fw_load_finish = &iceland_check_fw_load_finish,
692 .request_smu_load_fw = &iceland_request_smu_reload_fw,
693 .request_smu_load_specific_fw = &iceland_request_smu_load_specific_fw,
694 .send_msg_to_smc = &iceland_send_msg_to_smc,
695 .send_msg_to_smc_with_parameter = &iceland_send_msg_to_smc_with_parameter,
696 .download_pptable_settings = NULL,
697 .upload_pptable_settings = NULL,
698 };
699
700 int iceland_smum_init(struct pp_smumgr *smumgr)
701 {
702 struct iceland_smumgr *iceland_smu = NULL;
703
704 iceland_smu = kzalloc(sizeof(struct iceland_smumgr), GFP_KERNEL);
705
706 if (iceland_smu == NULL)
707 return -ENOMEM;
708
709 smumgr->backend = iceland_smu;
710 smumgr->smumgr_funcs = &iceland_smu_funcs;
711
712 return 0;
713 }
This page took 0.047301 seconds and 5 git commands to generate.