linux/drivers/gpu/drm/amd/amdgpu/tonga_smc.c
<<
>>
Prefs
   1/*
   2 * Copyright 2014 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
  24#include <linux/firmware.h>
  25#include "drmP.h"
  26#include "amdgpu.h"
  27#include "tonga_ppsmc.h"
  28#include "tonga_smumgr.h"
  29#include "smu_ucode_xfer_vi.h"
  30#include "amdgpu_ucode.h"
  31
  32#include "smu/smu_7_1_2_d.h"
  33#include "smu/smu_7_1_2_sh_mask.h"
  34
  35#define TONGA_SMC_SIZE 0x20000
  36
  37static int tonga_set_smc_sram_address(struct amdgpu_device *adev, uint32_t smc_address, uint32_t limit)
  38{
  39        uint32_t val;
  40
  41        if (smc_address & 3)
  42                return -EINVAL;
  43
  44        if ((smc_address + 3) > limit)
  45                return -EINVAL;
  46
  47        WREG32(mmSMC_IND_INDEX_0, smc_address);
  48
  49        val = RREG32(mmSMC_IND_ACCESS_CNTL);
  50        val = REG_SET_FIELD(val, SMC_IND_ACCESS_CNTL, AUTO_INCREMENT_IND_0, 0);
  51        WREG32(mmSMC_IND_ACCESS_CNTL, val);
  52
  53        return 0;
  54}
  55
  56static int tonga_copy_bytes_to_smc(struct amdgpu_device *adev, uint32_t smc_start_address, const uint8_t *src, uint32_t byte_count, uint32_t limit)
  57{
  58        uint32_t addr;
  59        uint32_t data, orig_data;
  60        int result = 0;
  61        uint32_t extra_shift;
  62        unsigned long flags;
  63
  64        if (smc_start_address & 3)
  65                return -EINVAL;
  66
  67        if ((smc_start_address + byte_count) > limit)
  68                return -EINVAL;
  69
  70        addr = smc_start_address;
  71
  72        spin_lock_irqsave(&adev->smc_idx_lock, flags);
  73        while (byte_count >= 4) {
  74                /* Bytes are written into the SMC addres space with the MSB first */
  75                data = (src[0] << 24) + (src[1] << 16) + (src[2] << 8) + src[3];
  76
  77                result = tonga_set_smc_sram_address(adev, addr, limit);
  78
  79                if (result)
  80                        goto out;
  81
  82                WREG32(mmSMC_IND_DATA_0, data);
  83
  84                src += 4;
  85                byte_count -= 4;
  86                addr += 4;
  87        }
  88
  89        if (0 != byte_count) {
  90                /* Now write odd bytes left, do a read modify write cycle */
  91                data = 0;
  92
  93                result = tonga_set_smc_sram_address(adev, addr, limit);
  94                if (result)
  95                        goto out;
  96
  97                orig_data = RREG32(mmSMC_IND_DATA_0);
  98                extra_shift = 8 * (4 - byte_count);
  99
 100                while (byte_count > 0) {
 101                        data = (data << 8) + *src++;
 102                        byte_count--;
 103                }
 104
 105                data <<= extra_shift;
 106                data |= (orig_data & ~((~0UL) << extra_shift));
 107
 108                result = tonga_set_smc_sram_address(adev, addr, limit);
 109                if (result)
 110                        goto out;
 111
 112                WREG32(mmSMC_IND_DATA_0, data);
 113        }
 114
 115out:
 116        spin_unlock_irqrestore(&adev->smc_idx_lock, flags);
 117        return result;
 118}
 119
 120static int tonga_program_jump_on_start(struct amdgpu_device *adev)
 121{
 122        static unsigned char data[] = {0xE0, 0x00, 0x80, 0x40};
 123        tonga_copy_bytes_to_smc(adev, 0x0, data, 4, sizeof(data)+1);
 124
 125        return 0;
 126}
 127
 128static bool tonga_is_smc_ram_running(struct amdgpu_device *adev)
 129{
 130        uint32_t val = RREG32_SMC(ixSMC_SYSCON_CLOCK_CNTL_0);
 131        val = REG_GET_FIELD(val, SMC_SYSCON_CLOCK_CNTL_0, ck_disable);
 132
 133        return ((0 == val) && (0x20100 <= RREG32_SMC(ixSMC_PC_C)));
 134}
 135
 136static int wait_smu_response(struct amdgpu_device *adev)
 137{
 138        int i;
 139        uint32_t val;
 140
 141        for (i = 0; i < adev->usec_timeout; i++) {
 142                val = RREG32(mmSMC_RESP_0);
 143                if (REG_GET_FIELD(val, SMC_RESP_0, SMC_RESP))
 144                        break;
 145                udelay(1);
 146        }
 147
 148        if (i == adev->usec_timeout)
 149                return -EINVAL;
 150
 151        return 0;
 152}
 153
 154static int tonga_send_msg_to_smc_offset(struct amdgpu_device *adev)
 155{
 156        if (wait_smu_response(adev)) {
 157                DRM_ERROR("Failed to send previous message\n");
 158                return -EINVAL;
 159        }
 160
 161        WREG32(mmSMC_MSG_ARG_0, 0x20000);
 162        WREG32(mmSMC_MESSAGE_0, PPSMC_MSG_Test);
 163
 164        if (wait_smu_response(adev)) {
 165                DRM_ERROR("Failed to send message\n");
 166                return -EINVAL;
 167        }
 168
 169        return 0;
 170}
 171
 172static int tonga_send_msg_to_smc(struct amdgpu_device *adev, PPSMC_Msg msg)
 173{
 174        if (!tonga_is_smc_ram_running(adev))
 175        {
 176                return -EINVAL;;
 177        }
 178
 179        if (wait_smu_response(adev)) {
 180                DRM_ERROR("Failed to send previous message\n");
 181                return -EINVAL;
 182        }
 183
 184        WREG32(mmSMC_MESSAGE_0, msg);
 185
 186        if (wait_smu_response(adev)) {
 187                DRM_ERROR("Failed to send message\n");
 188                return -EINVAL;
 189        }
 190
 191        return 0;
 192}
 193
 194static int tonga_send_msg_to_smc_without_waiting(struct amdgpu_device *adev,
 195                                                PPSMC_Msg msg)
 196{
 197        if (wait_smu_response(adev)) {
 198                DRM_ERROR("Failed to send previous message\n");
 199                return -EINVAL;
 200        }
 201
 202        WREG32(mmSMC_MESSAGE_0, msg);
 203
 204        return 0;
 205}
 206
 207static int tonga_send_msg_to_smc_with_parameter(struct amdgpu_device *adev,
 208                                                PPSMC_Msg msg,
 209                                                uint32_t parameter)
 210{
 211        if (!tonga_is_smc_ram_running(adev))
 212                return -EINVAL;
 213
 214        if (wait_smu_response(adev)) {
 215                DRM_ERROR("Failed to send previous message\n");
 216                return -EINVAL;
 217        }
 218
 219        WREG32(mmSMC_MSG_ARG_0, parameter);
 220
 221        return tonga_send_msg_to_smc(adev, msg);
 222}
 223
 224static int tonga_send_msg_to_smc_with_parameter_without_waiting(
 225                                        struct amdgpu_device *adev,
 226                                        PPSMC_Msg msg, uint32_t parameter)
 227{
 228        if (wait_smu_response(adev)) {
 229                DRM_ERROR("Failed to send previous message\n");
 230                return -EINVAL;
 231        }
 232
 233        WREG32(mmSMC_MSG_ARG_0, parameter);
 234
 235        return tonga_send_msg_to_smc_without_waiting(adev, msg);
 236}
 237
 238#if 0 /* not used yet */
 239static int tonga_wait_for_smc_inactive(struct amdgpu_device *adev)
 240{
 241        int i;
 242        uint32_t val;
 243
 244        if (!tonga_is_smc_ram_running(adev))
 245                return -EINVAL;
 246
 247        for (i = 0; i < adev->usec_timeout; i++) {
 248                val = RREG32_SMC(ixSMC_SYSCON_CLOCK_CNTL_0);
 249                if (REG_GET_FIELD(val, SMC_SYSCON_CLOCK_CNTL_0, cken) == 0)
 250                        break;
 251                udelay(1);
 252        }
 253
 254        if (i == adev->usec_timeout)
 255                return -EINVAL;
 256
 257        return 0;
 258}
 259#endif
 260
 261static int tonga_smu_upload_firmware_image(struct amdgpu_device *adev)
 262{
 263        const struct smc_firmware_header_v1_0 *hdr;
 264        uint32_t ucode_size;
 265        uint32_t ucode_start_address;
 266        const uint8_t *src;
 267        uint32_t val;
 268        uint32_t byte_count;
 269        uint32_t *data;
 270        unsigned long flags;
 271
 272        if (!adev->pm.fw)
 273                return -EINVAL;
 274
 275        hdr = (const struct smc_firmware_header_v1_0 *)adev->pm.fw->data;
 276        amdgpu_ucode_print_smc_hdr(&hdr->header);
 277
 278        adev->pm.fw_version = le32_to_cpu(hdr->header.ucode_version);
 279        ucode_size = le32_to_cpu(hdr->header.ucode_size_bytes);
 280        ucode_start_address = le32_to_cpu(hdr->ucode_start_addr);
 281        src = (const uint8_t *)
 282                (adev->pm.fw->data + le32_to_cpu(hdr->header.ucode_array_offset_bytes));
 283
 284        if (ucode_size & 3) {
 285                DRM_ERROR("SMC ucode is not 4 bytes aligned\n");
 286                return -EINVAL;
 287        }
 288
 289        if (ucode_size > TONGA_SMC_SIZE) {
 290                DRM_ERROR("SMC address is beyond the SMC RAM area\n");
 291                return -EINVAL;
 292        }
 293
 294        spin_lock_irqsave(&adev->smc_idx_lock, flags);
 295        WREG32(mmSMC_IND_INDEX_0, ucode_start_address);
 296
 297        val = RREG32(mmSMC_IND_ACCESS_CNTL);
 298        val = REG_SET_FIELD(val, SMC_IND_ACCESS_CNTL, AUTO_INCREMENT_IND_0, 1);
 299        WREG32(mmSMC_IND_ACCESS_CNTL, val);
 300
 301        byte_count = ucode_size;
 302        data = (uint32_t *)src;
 303        for (; byte_count >= 4; data++, byte_count -= 4)
 304                WREG32(mmSMC_IND_DATA_0, data[0]);
 305
 306        val = RREG32(mmSMC_IND_ACCESS_CNTL);
 307        val = REG_SET_FIELD(val, SMC_IND_ACCESS_CNTL, AUTO_INCREMENT_IND_0, 0);
 308        WREG32(mmSMC_IND_ACCESS_CNTL, val);
 309        spin_unlock_irqrestore(&adev->smc_idx_lock, flags);
 310
 311        return 0;
 312}
 313
 314#if 0 /* not used yet */
 315static int tonga_read_smc_sram_dword(struct amdgpu_device *adev,
 316                                uint32_t smc_address,
 317                                uint32_t *value,
 318                                uint32_t limit)
 319{
 320        int result;
 321        unsigned long flags;
 322
 323        spin_lock_irqsave(&adev->smc_idx_lock, flags);
 324        result = tonga_set_smc_sram_address(adev, smc_address, limit);
 325        if (result == 0)
 326                *value = RREG32(mmSMC_IND_DATA_0);
 327        spin_unlock_irqrestore(&adev->smc_idx_lock, flags);
 328        return result;
 329}
 330
 331static int tonga_write_smc_sram_dword(struct amdgpu_device *adev,
 332                                uint32_t smc_address,
 333                                uint32_t value,
 334                                uint32_t limit)
 335{
 336        int result;
 337        unsigned long flags;
 338
 339        spin_lock_irqsave(&adev->smc_idx_lock, flags);
 340        result = tonga_set_smc_sram_address(adev, smc_address, limit);
 341        if (result == 0)
 342                WREG32(mmSMC_IND_DATA_0, value);
 343        spin_unlock_irqrestore(&adev->smc_idx_lock, flags);
 344        return result;
 345}
 346
 347static int tonga_smu_stop_smc(struct amdgpu_device *adev)
 348{
 349        uint32_t val = RREG32_SMC(ixSMC_SYSCON_RESET_CNTL);
 350        val = REG_SET_FIELD(val, SMC_SYSCON_RESET_CNTL, rst_reg, 1);
 351        WREG32_SMC(ixSMC_SYSCON_RESET_CNTL, val);
 352
 353        val = RREG32_SMC(ixSMC_SYSCON_CLOCK_CNTL_0);
 354        val = REG_SET_FIELD(val, SMC_SYSCON_CLOCK_CNTL_0, ck_disable, 1);
 355        WREG32_SMC(ixSMC_SYSCON_CLOCK_CNTL_0, val);
 356
 357        return 0;
 358}
 359#endif
 360
 361static enum AMDGPU_UCODE_ID tonga_convert_fw_type(uint32_t fw_type)
 362{
 363        switch (fw_type) {
 364                case UCODE_ID_SDMA0:
 365                        return AMDGPU_UCODE_ID_SDMA0;
 366                case UCODE_ID_SDMA1:
 367                        return AMDGPU_UCODE_ID_SDMA1;
 368                case UCODE_ID_CP_CE:
 369                        return AMDGPU_UCODE_ID_CP_CE;
 370                case UCODE_ID_CP_PFP:
 371                        return AMDGPU_UCODE_ID_CP_PFP;
 372                case UCODE_ID_CP_ME:
 373                        return AMDGPU_UCODE_ID_CP_ME;
 374                case UCODE_ID_CP_MEC:
 375                case UCODE_ID_CP_MEC_JT1:
 376                        return AMDGPU_UCODE_ID_CP_MEC1;
 377                case UCODE_ID_CP_MEC_JT2:
 378                        return AMDGPU_UCODE_ID_CP_MEC2;
 379                case UCODE_ID_RLC_G:
 380                        return AMDGPU_UCODE_ID_RLC_G;
 381                default:
 382                        DRM_ERROR("ucode type is out of range!\n");
 383                        return AMDGPU_UCODE_ID_MAXIMUM;
 384        }
 385}
 386
 387static int tonga_smu_populate_single_firmware_entry(struct amdgpu_device *adev,
 388                                                uint32_t fw_type,
 389                                                struct SMU_Entry *entry)
 390{
 391        enum AMDGPU_UCODE_ID id = tonga_convert_fw_type(fw_type);
 392        struct amdgpu_firmware_info *ucode = &adev->firmware.ucode[id];
 393        const struct gfx_firmware_header_v1_0 *header = NULL;
 394        uint64_t gpu_addr;
 395        uint32_t data_size;
 396
 397        if (ucode->fw == NULL)
 398                return -EINVAL;
 399
 400        gpu_addr  = ucode->mc_addr;
 401        header = (const struct gfx_firmware_header_v1_0 *)ucode->fw->data;
 402        data_size = le32_to_cpu(header->header.ucode_size_bytes);
 403
 404        if ((fw_type == UCODE_ID_CP_MEC_JT1) ||
 405                (fw_type == UCODE_ID_CP_MEC_JT2)) {
 406                gpu_addr += le32_to_cpu(header->jt_offset) << 2;
 407                data_size = le32_to_cpu(header->jt_size) << 2;
 408        }
 409
 410        entry->version = (uint16_t)le32_to_cpu(header->header.ucode_version);
 411        entry->id = (uint16_t)fw_type;
 412        entry->image_addr_high = upper_32_bits(gpu_addr);
 413        entry->image_addr_low = lower_32_bits(gpu_addr);
 414        entry->meta_data_addr_high = 0;
 415        entry->meta_data_addr_low = 0;
 416        entry->data_size_byte = data_size;
 417        entry->num_register_entries = 0;
 418
 419        if (fw_type == UCODE_ID_RLC_G)
 420                entry->flags = 1;
 421        else
 422                entry->flags = 0;
 423
 424        return 0;
 425}
 426
 427static int tonga_smu_request_load_fw(struct amdgpu_device *adev)
 428{
 429        struct tonga_smu_private_data *private = (struct tonga_smu_private_data *)adev->smu.priv;
 430        struct SMU_DRAMData_TOC *toc;
 431        uint32_t fw_to_load;
 432
 433        WREG32_SMC(ixSOFT_REGISTERS_TABLE_28, 0);
 434
 435        tonga_send_msg_to_smc_with_parameter(adev, PPSMC_MSG_SMU_DRAM_ADDR_HI, private->smu_buffer_addr_high);
 436        tonga_send_msg_to_smc_with_parameter(adev, PPSMC_MSG_SMU_DRAM_ADDR_LO, private->smu_buffer_addr_low);
 437
 438        toc = (struct SMU_DRAMData_TOC *)private->header;
 439        toc->num_entries = 0;
 440        toc->structure_version = 1;
 441
 442        if (!adev->firmware.smu_load)
 443                return 0;
 444
 445        if (tonga_smu_populate_single_firmware_entry(adev, UCODE_ID_RLC_G,
 446                        &toc->entry[toc->num_entries++])) {
 447                DRM_ERROR("Failed to get firmware entry for RLC\n");
 448                return -EINVAL;
 449        }
 450
 451        if (tonga_smu_populate_single_firmware_entry(adev, UCODE_ID_CP_CE,
 452                        &toc->entry[toc->num_entries++])) {
 453                DRM_ERROR("Failed to get firmware entry for CE\n");
 454                return -EINVAL;
 455        }
 456
 457        if (tonga_smu_populate_single_firmware_entry(adev, UCODE_ID_CP_PFP,
 458                        &toc->entry[toc->num_entries++])) {
 459                DRM_ERROR("Failed to get firmware entry for PFP\n");
 460                return -EINVAL;
 461        }
 462
 463        if (tonga_smu_populate_single_firmware_entry(adev, UCODE_ID_CP_ME,
 464                        &toc->entry[toc->num_entries++])) {
 465                DRM_ERROR("Failed to get firmware entry for ME\n");
 466                return -EINVAL;
 467        }
 468
 469        if (tonga_smu_populate_single_firmware_entry(adev, UCODE_ID_CP_MEC,
 470                        &toc->entry[toc->num_entries++])) {
 471                DRM_ERROR("Failed to get firmware entry for MEC\n");
 472                return -EINVAL;
 473        }
 474
 475        if (tonga_smu_populate_single_firmware_entry(adev, UCODE_ID_CP_MEC_JT1,
 476                        &toc->entry[toc->num_entries++])) {
 477                DRM_ERROR("Failed to get firmware entry for MEC_JT1\n");
 478                return -EINVAL;
 479        }
 480
 481        if (tonga_smu_populate_single_firmware_entry(adev, UCODE_ID_CP_MEC_JT2,
 482                        &toc->entry[toc->num_entries++])) {
 483                DRM_ERROR("Failed to get firmware entry for MEC_JT2\n");
 484                return -EINVAL;
 485        }
 486
 487        if (tonga_smu_populate_single_firmware_entry(adev, UCODE_ID_SDMA0,
 488                        &toc->entry[toc->num_entries++])) {
 489                DRM_ERROR("Failed to get firmware entry for SDMA0\n");
 490                return -EINVAL;
 491        }
 492
 493        if (tonga_smu_populate_single_firmware_entry(adev, UCODE_ID_SDMA1,
 494                        &toc->entry[toc->num_entries++])) {
 495                DRM_ERROR("Failed to get firmware entry for SDMA1\n");
 496                return -EINVAL;
 497        }
 498
 499        tonga_send_msg_to_smc_with_parameter(adev, PPSMC_MSG_DRV_DRAM_ADDR_HI, private->header_addr_high);
 500        tonga_send_msg_to_smc_with_parameter(adev, PPSMC_MSG_DRV_DRAM_ADDR_LO, private->header_addr_low);
 501
 502        fw_to_load = UCODE_ID_RLC_G_MASK |
 503                        UCODE_ID_SDMA0_MASK |
 504                        UCODE_ID_SDMA1_MASK |
 505                        UCODE_ID_CP_CE_MASK |
 506                        UCODE_ID_CP_ME_MASK |
 507                        UCODE_ID_CP_PFP_MASK |
 508                        UCODE_ID_CP_MEC_MASK;
 509
 510        if (tonga_send_msg_to_smc_with_parameter_without_waiting(adev, PPSMC_MSG_LoadUcodes, fw_to_load)) {
 511                DRM_ERROR("Fail to request SMU load ucode\n");
 512                return -EINVAL;
 513        }
 514
 515        return 0;
 516}
 517
 518static uint32_t tonga_smu_get_mask_for_fw_type(uint32_t fw_type)
 519{
 520        switch (fw_type) {
 521                case AMDGPU_UCODE_ID_SDMA0:
 522                        return UCODE_ID_SDMA0_MASK;
 523                case AMDGPU_UCODE_ID_SDMA1:
 524                        return UCODE_ID_SDMA1_MASK;
 525                case AMDGPU_UCODE_ID_CP_CE:
 526                        return UCODE_ID_CP_CE_MASK;
 527                case AMDGPU_UCODE_ID_CP_PFP:
 528                        return UCODE_ID_CP_PFP_MASK;
 529                case AMDGPU_UCODE_ID_CP_ME:
 530                        return UCODE_ID_CP_ME_MASK;
 531                case AMDGPU_UCODE_ID_CP_MEC1:
 532                        return UCODE_ID_CP_MEC_MASK;
 533                case AMDGPU_UCODE_ID_CP_MEC2:
 534                        return UCODE_ID_CP_MEC_MASK;
 535                case AMDGPU_UCODE_ID_RLC_G:
 536                        return UCODE_ID_RLC_G_MASK;
 537                default:
 538                        DRM_ERROR("ucode type is out of range!\n");
 539                        return 0;
 540        }
 541}
 542
 543static int tonga_smu_check_fw_load_finish(struct amdgpu_device *adev,
 544                                        uint32_t fw_type)
 545{
 546        uint32_t fw_mask = tonga_smu_get_mask_for_fw_type(fw_type);
 547        int i;
 548
 549        for (i = 0; i < adev->usec_timeout; i++) {
 550                if (fw_mask == (RREG32_SMC(ixSOFT_REGISTERS_TABLE_28) & fw_mask))
 551                        break;
 552                udelay(1);
 553        }
 554
 555        if (i == adev->usec_timeout) {
 556                DRM_ERROR("check firmware loading failed\n");
 557                return -EINVAL;
 558        }
 559
 560        return 0;
 561}
 562
 563static int tonga_smu_start_in_protection_mode(struct amdgpu_device *adev)
 564{
 565        int result;
 566        uint32_t val;
 567        int i;
 568
 569        /* Assert reset */
 570        val = RREG32_SMC(ixSMC_SYSCON_RESET_CNTL);
 571        val = REG_SET_FIELD(val, SMC_SYSCON_RESET_CNTL, rst_reg, 1);
 572        WREG32_SMC(ixSMC_SYSCON_RESET_CNTL, val);
 573
 574        result = tonga_smu_upload_firmware_image(adev);
 575        if (result)
 576                return result;
 577
 578        /* Clear status */
 579        WREG32_SMC(ixSMU_STATUS, 0);
 580
 581        /* Enable clock */
 582        val = RREG32_SMC(ixSMC_SYSCON_CLOCK_CNTL_0);
 583        val = REG_SET_FIELD(val, SMC_SYSCON_CLOCK_CNTL_0, ck_disable, 0);
 584        WREG32_SMC(ixSMC_SYSCON_CLOCK_CNTL_0, val);
 585
 586        /* De-assert reset */
 587        val = RREG32_SMC(ixSMC_SYSCON_RESET_CNTL);
 588        val = REG_SET_FIELD(val, SMC_SYSCON_RESET_CNTL, rst_reg, 0);
 589        WREG32_SMC(ixSMC_SYSCON_RESET_CNTL, val);
 590
 591        /* Set SMU Auto Start */
 592        val = RREG32_SMC(ixSMU_INPUT_DATA);
 593        val = REG_SET_FIELD(val, SMU_INPUT_DATA, AUTO_START, 1);
 594        WREG32_SMC(ixSMU_INPUT_DATA, val);
 595
 596        /* Clear firmware interrupt enable flag */
 597        WREG32_SMC(ixFIRMWARE_FLAGS, 0);
 598
 599        for (i = 0; i < adev->usec_timeout; i++) {
 600                val = RREG32_SMC(ixRCU_UC_EVENTS);
 601                if (REG_GET_FIELD(val, RCU_UC_EVENTS, INTERRUPTS_ENABLED))
 602                        break;
 603                udelay(1);
 604        }
 605
 606        if (i == adev->usec_timeout) {
 607                DRM_ERROR("Interrupt is not enabled by firmware\n");
 608                return -EINVAL;
 609        }
 610
 611        /* Call Test SMU message with 0x20000 offset
 612         * to trigger SMU start
 613         */
 614        tonga_send_msg_to_smc_offset(adev);
 615
 616        /* Wait for done bit to be set */
 617        for (i = 0; i < adev->usec_timeout; i++) {
 618                val = RREG32_SMC(ixSMU_STATUS);
 619                if (REG_GET_FIELD(val, SMU_STATUS, SMU_DONE))
 620                        break;
 621                udelay(1);
 622        }
 623
 624        if (i == adev->usec_timeout) {
 625                DRM_ERROR("Timeout for SMU start\n");
 626                return -EINVAL;
 627        }
 628
 629        /* Check pass/failed indicator */
 630        val = RREG32_SMC(ixSMU_STATUS);
 631        if (!REG_GET_FIELD(val, SMU_STATUS, SMU_PASS)) {
 632                DRM_ERROR("SMU Firmware start failed\n");
 633                return -EINVAL;
 634        }
 635
 636        /* Wait for firmware to initialize */
 637        for (i = 0; i < adev->usec_timeout; i++) {
 638                val = RREG32_SMC(ixFIRMWARE_FLAGS);
 639                if(REG_GET_FIELD(val, FIRMWARE_FLAGS, INTERRUPTS_ENABLED))
 640                        break;
 641                udelay(1);
 642        }
 643
 644        if (i == adev->usec_timeout) {
 645                DRM_ERROR("SMU firmware initialization failed\n");
 646                return -EINVAL;
 647        }
 648
 649        return 0;
 650}
 651
 652static int tonga_smu_start_in_non_protection_mode(struct amdgpu_device *adev)
 653{
 654        int i, result;
 655        uint32_t val;
 656
 657        /* wait for smc boot up */
 658        for (i = 0; i < adev->usec_timeout; i++) {
 659                val = RREG32_SMC(ixRCU_UC_EVENTS);
 660                val = REG_GET_FIELD(val, RCU_UC_EVENTS, boot_seq_done);
 661                if (val)
 662                        break;
 663                udelay(1);
 664        }
 665
 666        if (i == adev->usec_timeout) {
 667                DRM_ERROR("SMC boot sequence is not completed\n");
 668                return -EINVAL;
 669        }
 670
 671        /* Clear firmware interrupt enable flag */
 672        WREG32_SMC(ixFIRMWARE_FLAGS, 0);
 673
 674        /* Assert reset */
 675        val = RREG32_SMC(ixSMC_SYSCON_RESET_CNTL);
 676        val = REG_SET_FIELD(val, SMC_SYSCON_RESET_CNTL, rst_reg, 1);
 677        WREG32_SMC(ixSMC_SYSCON_RESET_CNTL, val);
 678
 679        result = tonga_smu_upload_firmware_image(adev);
 680        if (result)
 681                return result;
 682
 683        /* Set smc instruct start point at 0x0 */
 684        tonga_program_jump_on_start(adev);
 685
 686        /* Enable clock */
 687        val = RREG32_SMC(ixSMC_SYSCON_CLOCK_CNTL_0);
 688        val = REG_SET_FIELD(val, SMC_SYSCON_CLOCK_CNTL_0, ck_disable, 0);
 689        WREG32_SMC(ixSMC_SYSCON_CLOCK_CNTL_0, val);
 690
 691        /* De-assert reset */
 692        val = RREG32_SMC(ixSMC_SYSCON_RESET_CNTL);
 693        val = REG_SET_FIELD(val, SMC_SYSCON_RESET_CNTL, rst_reg, 0);
 694        WREG32_SMC(ixSMC_SYSCON_RESET_CNTL, val);
 695
 696        /* Wait for firmware to initialize */
 697        for (i = 0; i < adev->usec_timeout; i++) {
 698                val = RREG32_SMC(ixFIRMWARE_FLAGS);
 699                if (REG_GET_FIELD(val, FIRMWARE_FLAGS, INTERRUPTS_ENABLED))
 700                        break;
 701                udelay(1);
 702        }
 703
 704        if (i == adev->usec_timeout) {
 705                DRM_ERROR("Timeout for SMC firmware initialization\n");
 706                return -EINVAL;
 707        }
 708
 709        return 0;
 710}
 711
 712int tonga_smu_start(struct amdgpu_device *adev)
 713{
 714        int result;
 715        uint32_t val;
 716
 717        if (!tonga_is_smc_ram_running(adev)) {
 718                val = RREG32_SMC(ixSMU_FIRMWARE);
 719                if (!REG_GET_FIELD(val, SMU_FIRMWARE, SMU_MODE)) {
 720                        result = tonga_smu_start_in_non_protection_mode(adev);
 721                        if (result)
 722                                return result;
 723                } else {
 724                        result = tonga_smu_start_in_protection_mode(adev);
 725                        if (result)
 726                                return result;
 727                }
 728        }
 729
 730        return tonga_smu_request_load_fw(adev);
 731}
 732
 733static const struct amdgpu_smumgr_funcs tonga_smumgr_funcs = {
 734        .check_fw_load_finish = tonga_smu_check_fw_load_finish,
 735        .request_smu_load_fw = NULL,
 736        .request_smu_specific_fw = NULL,
 737};
 738
 739int tonga_smu_init(struct amdgpu_device *adev)
 740{
 741        struct tonga_smu_private_data *private;
 742        uint32_t image_size = ((sizeof(struct SMU_DRAMData_TOC) / 4096) + 1) * 4096;
 743        uint32_t smu_internal_buffer_size = 200*4096;
 744        struct amdgpu_bo **toc_buf = &adev->smu.toc_buf;
 745        struct amdgpu_bo **smu_buf = &adev->smu.smu_buf;
 746        uint64_t mc_addr;
 747        void *toc_buf_ptr;
 748        void *smu_buf_ptr;
 749        int ret;
 750
 751        private = kzalloc(sizeof(struct tonga_smu_private_data), GFP_KERNEL);
 752        if (NULL == private)
 753                return -ENOMEM;
 754
 755        /* allocate firmware buffers */
 756        if (adev->firmware.smu_load)
 757                amdgpu_ucode_init_bo(adev);
 758
 759        adev->smu.priv = private;
 760        adev->smu.fw_flags = 0;
 761
 762        /* Allocate FW image data structure and header buffer */
 763        ret = amdgpu_bo_create(adev, image_size, PAGE_SIZE,
 764                               true, AMDGPU_GEM_DOMAIN_VRAM,
 765                               AMDGPU_GEM_CREATE_CPU_ACCESS_REQUIRED,
 766                               NULL, NULL, toc_buf);
 767        if (ret) {
 768                DRM_ERROR("Failed to allocate memory for TOC buffer\n");
 769                return -ENOMEM;
 770        }
 771
 772        /* Allocate buffer for SMU internal buffer */
 773        ret = amdgpu_bo_create(adev, smu_internal_buffer_size, PAGE_SIZE,
 774                               true, AMDGPU_GEM_DOMAIN_VRAM,
 775                               AMDGPU_GEM_CREATE_CPU_ACCESS_REQUIRED,
 776                               NULL, NULL, smu_buf);
 777        if (ret) {
 778                DRM_ERROR("Failed to allocate memory for SMU internal buffer\n");
 779                return -ENOMEM;
 780        }
 781
 782        /* Retrieve GPU address for header buffer and internal buffer */
 783        ret = amdgpu_bo_reserve(adev->smu.toc_buf, false);
 784        if (ret) {
 785                amdgpu_bo_unref(&adev->smu.toc_buf);
 786                DRM_ERROR("Failed to reserve the TOC buffer\n");
 787                return -EINVAL;
 788        }
 789
 790        ret = amdgpu_bo_pin(adev->smu.toc_buf, AMDGPU_GEM_DOMAIN_VRAM, &mc_addr);
 791        if (ret) {
 792                amdgpu_bo_unreserve(adev->smu.toc_buf);
 793                amdgpu_bo_unref(&adev->smu.toc_buf);
 794                DRM_ERROR("Failed to pin the TOC buffer\n");
 795                return -EINVAL;
 796        }
 797
 798        ret = amdgpu_bo_kmap(*toc_buf, &toc_buf_ptr);
 799        if (ret) {
 800                amdgpu_bo_unreserve(adev->smu.toc_buf);
 801                amdgpu_bo_unref(&adev->smu.toc_buf);
 802                DRM_ERROR("Failed to map the TOC buffer\n");
 803                return -EINVAL;
 804        }
 805
 806        amdgpu_bo_unreserve(adev->smu.toc_buf);
 807        private->header_addr_low = lower_32_bits(mc_addr);
 808        private->header_addr_high = upper_32_bits(mc_addr);
 809        private->header = toc_buf_ptr;
 810
 811        ret = amdgpu_bo_reserve(adev->smu.smu_buf, false);
 812        if (ret) {
 813                amdgpu_bo_unref(&adev->smu.smu_buf);
 814                amdgpu_bo_unref(&adev->smu.toc_buf);
 815                DRM_ERROR("Failed to reserve the SMU internal buffer\n");
 816                return -EINVAL;
 817        }
 818
 819        ret = amdgpu_bo_pin(adev->smu.smu_buf, AMDGPU_GEM_DOMAIN_VRAM, &mc_addr);
 820        if (ret) {
 821                amdgpu_bo_unreserve(adev->smu.smu_buf);
 822                amdgpu_bo_unref(&adev->smu.smu_buf);
 823                amdgpu_bo_unref(&adev->smu.toc_buf);
 824                DRM_ERROR("Failed to pin the SMU internal buffer\n");
 825                return -EINVAL;
 826        }
 827
 828        ret = amdgpu_bo_kmap(*smu_buf, &smu_buf_ptr);
 829        if (ret) {
 830                amdgpu_bo_unreserve(adev->smu.smu_buf);
 831                amdgpu_bo_unref(&adev->smu.smu_buf);
 832                amdgpu_bo_unref(&adev->smu.toc_buf);
 833                DRM_ERROR("Failed to map the SMU internal buffer\n");
 834                return -EINVAL;
 835        }
 836
 837        amdgpu_bo_unreserve(adev->smu.smu_buf);
 838        private->smu_buffer_addr_low = lower_32_bits(mc_addr);
 839        private->smu_buffer_addr_high = upper_32_bits(mc_addr);
 840
 841        adev->smu.smumgr_funcs = &tonga_smumgr_funcs;
 842
 843        return 0;
 844}
 845
 846int tonga_smu_fini(struct amdgpu_device *adev)
 847{
 848        amdgpu_bo_unref(&adev->smu.toc_buf);
 849        amdgpu_bo_unref(&adev->smu.smu_buf);
 850        kfree(adev->smu.priv);
 851        adev->smu.priv = NULL;
 852        if (adev->firmware.fw_buf)
 853                amdgpu_ucode_fini_bo(adev);
 854
 855        return 0;
 856}
 857