root/drivers/gpu/drm/amd/amdgpu/amdgpu_cgs.c

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

DEFINITIONS

This source file includes following definitions.
  1. amdgpu_cgs_read_register
  2. amdgpu_cgs_write_register
  3. amdgpu_cgs_read_ind_register
  4. amdgpu_cgs_write_ind_register
  5. fw_type_convert
  6. amdgpu_get_firmware_version
  7. amdgpu_cgs_get_firmware_info
  8. amdgpu_cgs_create_device
  9. amdgpu_cgs_destroy_device

   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  */
  24 #include <linux/list.h>
  25 #include <linux/pci.h>
  26 #include <linux/slab.h>
  27 
  28 #include <linux/firmware.h>
  29 #include <drm/amdgpu_drm.h>
  30 #include "amdgpu.h"
  31 #include "atom.h"
  32 #include "amdgpu_ucode.h"
  33 
  34 struct amdgpu_cgs_device {
  35         struct cgs_device base;
  36         struct amdgpu_device *adev;
  37 };
  38 
  39 #define CGS_FUNC_ADEV                                                   \
  40         struct amdgpu_device *adev =                                    \
  41                 ((struct amdgpu_cgs_device *)cgs_device)->adev
  42 
  43 
  44 static uint32_t amdgpu_cgs_read_register(struct cgs_device *cgs_device, unsigned offset)
  45 {
  46         CGS_FUNC_ADEV;
  47         return RREG32(offset);
  48 }
  49 
  50 static void amdgpu_cgs_write_register(struct cgs_device *cgs_device, unsigned offset,
  51                                       uint32_t value)
  52 {
  53         CGS_FUNC_ADEV;
  54         WREG32(offset, value);
  55 }
  56 
  57 static uint32_t amdgpu_cgs_read_ind_register(struct cgs_device *cgs_device,
  58                                              enum cgs_ind_reg space,
  59                                              unsigned index)
  60 {
  61         CGS_FUNC_ADEV;
  62         switch (space) {
  63         case CGS_IND_REG__MMIO:
  64                 return RREG32_IDX(index);
  65         case CGS_IND_REG__PCIE:
  66                 return RREG32_PCIE(index);
  67         case CGS_IND_REG__SMC:
  68                 return RREG32_SMC(index);
  69         case CGS_IND_REG__UVD_CTX:
  70                 return RREG32_UVD_CTX(index);
  71         case CGS_IND_REG__DIDT:
  72                 return RREG32_DIDT(index);
  73         case CGS_IND_REG_GC_CAC:
  74                 return RREG32_GC_CAC(index);
  75         case CGS_IND_REG_SE_CAC:
  76                 return RREG32_SE_CAC(index);
  77         case CGS_IND_REG__AUDIO_ENDPT:
  78                 DRM_ERROR("audio endpt register access not implemented.\n");
  79                 return 0;
  80         }
  81         WARN(1, "Invalid indirect register space");
  82         return 0;
  83 }
  84 
  85 static void amdgpu_cgs_write_ind_register(struct cgs_device *cgs_device,
  86                                           enum cgs_ind_reg space,
  87                                           unsigned index, uint32_t value)
  88 {
  89         CGS_FUNC_ADEV;
  90         switch (space) {
  91         case CGS_IND_REG__MMIO:
  92                 return WREG32_IDX(index, value);
  93         case CGS_IND_REG__PCIE:
  94                 return WREG32_PCIE(index, value);
  95         case CGS_IND_REG__SMC:
  96                 return WREG32_SMC(index, value);
  97         case CGS_IND_REG__UVD_CTX:
  98                 return WREG32_UVD_CTX(index, value);
  99         case CGS_IND_REG__DIDT:
 100                 return WREG32_DIDT(index, value);
 101         case CGS_IND_REG_GC_CAC:
 102                 return WREG32_GC_CAC(index, value);
 103         case CGS_IND_REG_SE_CAC:
 104                 return WREG32_SE_CAC(index, value);
 105         case CGS_IND_REG__AUDIO_ENDPT:
 106                 DRM_ERROR("audio endpt register access not implemented.\n");
 107                 return;
 108         }
 109         WARN(1, "Invalid indirect register space");
 110 }
 111 
 112 static uint32_t fw_type_convert(struct cgs_device *cgs_device, uint32_t fw_type)
 113 {
 114         CGS_FUNC_ADEV;
 115         enum AMDGPU_UCODE_ID result = AMDGPU_UCODE_ID_MAXIMUM;
 116 
 117         switch (fw_type) {
 118         case CGS_UCODE_ID_SDMA0:
 119                 result = AMDGPU_UCODE_ID_SDMA0;
 120                 break;
 121         case CGS_UCODE_ID_SDMA1:
 122                 result = AMDGPU_UCODE_ID_SDMA1;
 123                 break;
 124         case CGS_UCODE_ID_CP_CE:
 125                 result = AMDGPU_UCODE_ID_CP_CE;
 126                 break;
 127         case CGS_UCODE_ID_CP_PFP:
 128                 result = AMDGPU_UCODE_ID_CP_PFP;
 129                 break;
 130         case CGS_UCODE_ID_CP_ME:
 131                 result = AMDGPU_UCODE_ID_CP_ME;
 132                 break;
 133         case CGS_UCODE_ID_CP_MEC:
 134         case CGS_UCODE_ID_CP_MEC_JT1:
 135                 result = AMDGPU_UCODE_ID_CP_MEC1;
 136                 break;
 137         case CGS_UCODE_ID_CP_MEC_JT2:
 138                 /* for VI. JT2 should be the same as JT1, because:
 139                         1, MEC2 and MEC1 use exactly same FW.
 140                         2, JT2 is not pached but JT1 is.
 141                 */
 142                 if (adev->asic_type >= CHIP_TOPAZ)
 143                         result = AMDGPU_UCODE_ID_CP_MEC1;
 144                 else
 145                         result = AMDGPU_UCODE_ID_CP_MEC2;
 146                 break;
 147         case CGS_UCODE_ID_RLC_G:
 148                 result = AMDGPU_UCODE_ID_RLC_G;
 149                 break;
 150         case CGS_UCODE_ID_STORAGE:
 151                 result = AMDGPU_UCODE_ID_STORAGE;
 152                 break;
 153         default:
 154                 DRM_ERROR("Firmware type not supported\n");
 155         }
 156         return result;
 157 }
 158 
 159 static uint16_t amdgpu_get_firmware_version(struct cgs_device *cgs_device,
 160                                         enum cgs_ucode_id type)
 161 {
 162         CGS_FUNC_ADEV;
 163         uint16_t fw_version = 0;
 164 
 165         switch (type) {
 166                 case CGS_UCODE_ID_SDMA0:
 167                         fw_version = adev->sdma.instance[0].fw_version;
 168                         break;
 169                 case CGS_UCODE_ID_SDMA1:
 170                         fw_version = adev->sdma.instance[1].fw_version;
 171                         break;
 172                 case CGS_UCODE_ID_CP_CE:
 173                         fw_version = adev->gfx.ce_fw_version;
 174                         break;
 175                 case CGS_UCODE_ID_CP_PFP:
 176                         fw_version = adev->gfx.pfp_fw_version;
 177                         break;
 178                 case CGS_UCODE_ID_CP_ME:
 179                         fw_version = adev->gfx.me_fw_version;
 180                         break;
 181                 case CGS_UCODE_ID_CP_MEC:
 182                         fw_version = adev->gfx.mec_fw_version;
 183                         break;
 184                 case CGS_UCODE_ID_CP_MEC_JT1:
 185                         fw_version = adev->gfx.mec_fw_version;
 186                         break;
 187                 case CGS_UCODE_ID_CP_MEC_JT2:
 188                         fw_version = adev->gfx.mec_fw_version;
 189                         break;
 190                 case CGS_UCODE_ID_RLC_G:
 191                         fw_version = adev->gfx.rlc_fw_version;
 192                         break;
 193                 case CGS_UCODE_ID_STORAGE:
 194                         break;
 195                 default:
 196                         DRM_ERROR("firmware type %d do not have version\n", type);
 197                         break;
 198         }
 199         return fw_version;
 200 }
 201 
 202 static int amdgpu_cgs_get_firmware_info(struct cgs_device *cgs_device,
 203                                         enum cgs_ucode_id type,
 204                                         struct cgs_firmware_info *info)
 205 {
 206         CGS_FUNC_ADEV;
 207 
 208         if ((CGS_UCODE_ID_SMU != type) && (CGS_UCODE_ID_SMU_SK != type)) {
 209                 uint64_t gpu_addr;
 210                 uint32_t data_size;
 211                 const struct gfx_firmware_header_v1_0 *header;
 212                 enum AMDGPU_UCODE_ID id;
 213                 struct amdgpu_firmware_info *ucode;
 214 
 215                 id = fw_type_convert(cgs_device, type);
 216                 ucode = &adev->firmware.ucode[id];
 217                 if (ucode->fw == NULL)
 218                         return -EINVAL;
 219 
 220                 gpu_addr  = ucode->mc_addr;
 221                 header = (const struct gfx_firmware_header_v1_0 *)ucode->fw->data;
 222                 data_size = le32_to_cpu(header->header.ucode_size_bytes);
 223 
 224                 if ((type == CGS_UCODE_ID_CP_MEC_JT1) ||
 225                     (type == CGS_UCODE_ID_CP_MEC_JT2)) {
 226                         gpu_addr += ALIGN(le32_to_cpu(header->header.ucode_size_bytes), PAGE_SIZE);
 227                         data_size = le32_to_cpu(header->jt_size) << 2;
 228                 }
 229 
 230                 info->kptr = ucode->kaddr;
 231                 info->image_size = data_size;
 232                 info->mc_addr = gpu_addr;
 233                 info->version = (uint16_t)le32_to_cpu(header->header.ucode_version);
 234 
 235                 if (CGS_UCODE_ID_CP_MEC == type)
 236                         info->image_size = le32_to_cpu(header->jt_offset) << 2;
 237 
 238                 info->fw_version = amdgpu_get_firmware_version(cgs_device, type);
 239                 info->feature_version = (uint16_t)le32_to_cpu(header->ucode_feature_version);
 240         } else {
 241                 char fw_name[30] = {0};
 242                 int err = 0;
 243                 uint32_t ucode_size;
 244                 uint32_t ucode_start_address;
 245                 const uint8_t *src;
 246                 const struct smc_firmware_header_v1_0 *hdr;
 247                 const struct common_firmware_header *header;
 248                 struct amdgpu_firmware_info *ucode = NULL;
 249 
 250                 if (!adev->pm.fw) {
 251                         switch (adev->asic_type) {
 252                         case CHIP_TAHITI:
 253                                 strcpy(fw_name, "radeon/tahiti_smc.bin");
 254                                 break;
 255                         case CHIP_PITCAIRN:
 256                                 if ((adev->pdev->revision == 0x81) &&
 257                                     ((adev->pdev->device == 0x6810) ||
 258                                     (adev->pdev->device == 0x6811))) {
 259                                         info->is_kicker = true;
 260                                         strcpy(fw_name, "radeon/pitcairn_k_smc.bin");
 261                                 } else {
 262                                         strcpy(fw_name, "radeon/pitcairn_smc.bin");
 263                                 }
 264                                 break;
 265                         case CHIP_VERDE:
 266                                 if (((adev->pdev->device == 0x6820) &&
 267                                         ((adev->pdev->revision == 0x81) ||
 268                                         (adev->pdev->revision == 0x83))) ||
 269                                     ((adev->pdev->device == 0x6821) &&
 270                                         ((adev->pdev->revision == 0x83) ||
 271                                         (adev->pdev->revision == 0x87))) ||
 272                                     ((adev->pdev->revision == 0x87) &&
 273                                         ((adev->pdev->device == 0x6823) ||
 274                                         (adev->pdev->device == 0x682b)))) {
 275                                         info->is_kicker = true;
 276                                         strcpy(fw_name, "radeon/verde_k_smc.bin");
 277                                 } else {
 278                                         strcpy(fw_name, "radeon/verde_smc.bin");
 279                                 }
 280                                 break;
 281                         case CHIP_OLAND:
 282                                 if (((adev->pdev->revision == 0x81) &&
 283                                         ((adev->pdev->device == 0x6600) ||
 284                                         (adev->pdev->device == 0x6604) ||
 285                                         (adev->pdev->device == 0x6605) ||
 286                                         (adev->pdev->device == 0x6610))) ||
 287                                     ((adev->pdev->revision == 0x83) &&
 288                                         (adev->pdev->device == 0x6610))) {
 289                                         info->is_kicker = true;
 290                                         strcpy(fw_name, "radeon/oland_k_smc.bin");
 291                                 } else {
 292                                         strcpy(fw_name, "radeon/oland_smc.bin");
 293                                 }
 294                                 break;
 295                         case CHIP_HAINAN:
 296                                 if (((adev->pdev->revision == 0x81) &&
 297                                         (adev->pdev->device == 0x6660)) ||
 298                                     ((adev->pdev->revision == 0x83) &&
 299                                         ((adev->pdev->device == 0x6660) ||
 300                                         (adev->pdev->device == 0x6663) ||
 301                                         (adev->pdev->device == 0x6665) ||
 302                                          (adev->pdev->device == 0x6667)))) {
 303                                         info->is_kicker = true;
 304                                         strcpy(fw_name, "radeon/hainan_k_smc.bin");
 305                                 } else if ((adev->pdev->revision == 0xc3) &&
 306                                          (adev->pdev->device == 0x6665)) {
 307                                         info->is_kicker = true;
 308                                         strcpy(fw_name, "radeon/banks_k_2_smc.bin");
 309                                 } else {
 310                                         strcpy(fw_name, "radeon/hainan_smc.bin");
 311                                 }
 312                                 break;
 313                         case CHIP_BONAIRE:
 314                                 if ((adev->pdev->revision == 0x80) ||
 315                                         (adev->pdev->revision == 0x81) ||
 316                                         (adev->pdev->device == 0x665f)) {
 317                                         info->is_kicker = true;
 318                                         strcpy(fw_name, "amdgpu/bonaire_k_smc.bin");
 319                                 } else {
 320                                         strcpy(fw_name, "amdgpu/bonaire_smc.bin");
 321                                 }
 322                                 break;
 323                         case CHIP_HAWAII:
 324                                 if (adev->pdev->revision == 0x80) {
 325                                         info->is_kicker = true;
 326                                         strcpy(fw_name, "amdgpu/hawaii_k_smc.bin");
 327                                 } else {
 328                                         strcpy(fw_name, "amdgpu/hawaii_smc.bin");
 329                                 }
 330                                 break;
 331                         case CHIP_TOPAZ:
 332                                 if (((adev->pdev->device == 0x6900) && (adev->pdev->revision == 0x81)) ||
 333                                     ((adev->pdev->device == 0x6900) && (adev->pdev->revision == 0x83)) ||
 334                                     ((adev->pdev->device == 0x6907) && (adev->pdev->revision == 0x87)) ||
 335                                     ((adev->pdev->device == 0x6900) && (adev->pdev->revision == 0xD1)) ||
 336                                     ((adev->pdev->device == 0x6900) && (adev->pdev->revision == 0xD3))) {
 337                                         info->is_kicker = true;
 338                                         strcpy(fw_name, "amdgpu/topaz_k_smc.bin");
 339                                 } else
 340                                         strcpy(fw_name, "amdgpu/topaz_smc.bin");
 341                                 break;
 342                         case CHIP_TONGA:
 343                                 if (((adev->pdev->device == 0x6939) && (adev->pdev->revision == 0xf1)) ||
 344                                     ((adev->pdev->device == 0x6938) && (adev->pdev->revision == 0xf1))) {
 345                                         info->is_kicker = true;
 346                                         strcpy(fw_name, "amdgpu/tonga_k_smc.bin");
 347                                 } else
 348                                         strcpy(fw_name, "amdgpu/tonga_smc.bin");
 349                                 break;
 350                         case CHIP_FIJI:
 351                                 strcpy(fw_name, "amdgpu/fiji_smc.bin");
 352                                 break;
 353                         case CHIP_POLARIS11:
 354                                 if (type == CGS_UCODE_ID_SMU) {
 355                                         if (((adev->pdev->device == 0x67ef) &&
 356                                              ((adev->pdev->revision == 0xe0) ||
 357                                               (adev->pdev->revision == 0xe5))) ||
 358                                             ((adev->pdev->device == 0x67ff) &&
 359                                              ((adev->pdev->revision == 0xcf) ||
 360                                               (adev->pdev->revision == 0xef) ||
 361                                               (adev->pdev->revision == 0xff)))) {
 362                                                 info->is_kicker = true;
 363                                                 strcpy(fw_name, "amdgpu/polaris11_k_smc.bin");
 364                                         } else if ((adev->pdev->device == 0x67ef) &&
 365                                                    (adev->pdev->revision == 0xe2)) {
 366                                                 info->is_kicker = true;
 367                                                 strcpy(fw_name, "amdgpu/polaris11_k2_smc.bin");
 368                                         } else {
 369                                                 strcpy(fw_name, "amdgpu/polaris11_smc.bin");
 370                                         }
 371                                 } else if (type == CGS_UCODE_ID_SMU_SK) {
 372                                         strcpy(fw_name, "amdgpu/polaris11_smc_sk.bin");
 373                                 }
 374                                 break;
 375                         case CHIP_POLARIS10:
 376                                 if (type == CGS_UCODE_ID_SMU) {
 377                                         if (((adev->pdev->device == 0x67df) &&
 378                                              ((adev->pdev->revision == 0xe0) ||
 379                                               (adev->pdev->revision == 0xe3) ||
 380                                               (adev->pdev->revision == 0xe4) ||
 381                                               (adev->pdev->revision == 0xe5) ||
 382                                               (adev->pdev->revision == 0xe7) ||
 383                                               (adev->pdev->revision == 0xef))) ||
 384                                             ((adev->pdev->device == 0x6fdf) &&
 385                                              ((adev->pdev->revision == 0xef) ||
 386                                               (adev->pdev->revision == 0xff)))) {
 387                                                 info->is_kicker = true;
 388                                                 strcpy(fw_name, "amdgpu/polaris10_k_smc.bin");
 389                                         } else if ((adev->pdev->device == 0x67df) &&
 390                                                    ((adev->pdev->revision == 0xe1) ||
 391                                                     (adev->pdev->revision == 0xf7))) {
 392                                                 info->is_kicker = true;
 393                                                 strcpy(fw_name, "amdgpu/polaris10_k2_smc.bin");
 394                                         } else {
 395                                                 strcpy(fw_name, "amdgpu/polaris10_smc.bin");
 396                                         }
 397                                 } else if (type == CGS_UCODE_ID_SMU_SK) {
 398                                         strcpy(fw_name, "amdgpu/polaris10_smc_sk.bin");
 399                                 }
 400                                 break;
 401                         case CHIP_POLARIS12:
 402                                 if (((adev->pdev->device == 0x6987) &&
 403                                      ((adev->pdev->revision == 0xc0) ||
 404                                       (adev->pdev->revision == 0xc3))) ||
 405                                     ((adev->pdev->device == 0x6981) &&
 406                                      ((adev->pdev->revision == 0x00) ||
 407                                       (adev->pdev->revision == 0x01) ||
 408                                       (adev->pdev->revision == 0x10)))) {
 409                                         info->is_kicker = true;
 410                                         strcpy(fw_name, "amdgpu/polaris12_k_smc.bin");
 411                                 } else {
 412                                         strcpy(fw_name, "amdgpu/polaris12_smc.bin");
 413                                 }
 414                                 break;
 415                         case CHIP_VEGAM:
 416                                 strcpy(fw_name, "amdgpu/vegam_smc.bin");
 417                                 break;
 418                         case CHIP_VEGA10:
 419                                 if ((adev->pdev->device == 0x687f) &&
 420                                         ((adev->pdev->revision == 0xc0) ||
 421                                         (adev->pdev->revision == 0xc1) ||
 422                                         (adev->pdev->revision == 0xc3)))
 423                                         strcpy(fw_name, "amdgpu/vega10_acg_smc.bin");
 424                                 else
 425                                         strcpy(fw_name, "amdgpu/vega10_smc.bin");
 426                                 break;
 427                         case CHIP_VEGA12:
 428                                 strcpy(fw_name, "amdgpu/vega12_smc.bin");
 429                                 break;
 430                         case CHIP_VEGA20:
 431                                 strcpy(fw_name, "amdgpu/vega20_smc.bin");
 432                                 break;
 433                         default:
 434                                 DRM_ERROR("SMC firmware not supported\n");
 435                                 return -EINVAL;
 436                         }
 437 
 438                         err = request_firmware(&adev->pm.fw, fw_name, adev->dev);
 439                         if (err) {
 440                                 DRM_ERROR("Failed to request firmware\n");
 441                                 return err;
 442                         }
 443 
 444                         err = amdgpu_ucode_validate(adev->pm.fw);
 445                         if (err) {
 446                                 DRM_ERROR("Failed to load firmware \"%s\"", fw_name);
 447                                 release_firmware(adev->pm.fw);
 448                                 adev->pm.fw = NULL;
 449                                 return err;
 450                         }
 451 
 452                         if (adev->firmware.load_type == AMDGPU_FW_LOAD_PSP) {
 453                                 ucode = &adev->firmware.ucode[AMDGPU_UCODE_ID_SMC];
 454                                 ucode->ucode_id = AMDGPU_UCODE_ID_SMC;
 455                                 ucode->fw = adev->pm.fw;
 456                                 header = (const struct common_firmware_header *)ucode->fw->data;
 457                                 adev->firmware.fw_size +=
 458                                         ALIGN(le32_to_cpu(header->ucode_size_bytes), PAGE_SIZE);
 459                         }
 460                 }
 461 
 462                 hdr = (const struct smc_firmware_header_v1_0 *) adev->pm.fw->data;
 463                 amdgpu_ucode_print_smc_hdr(&hdr->header);
 464                 adev->pm.fw_version = le32_to_cpu(hdr->header.ucode_version);
 465                 ucode_size = le32_to_cpu(hdr->header.ucode_size_bytes);
 466                 ucode_start_address = le32_to_cpu(hdr->ucode_start_addr);
 467                 src = (const uint8_t *)(adev->pm.fw->data +
 468                        le32_to_cpu(hdr->header.ucode_array_offset_bytes));
 469 
 470                 info->version = adev->pm.fw_version;
 471                 info->image_size = ucode_size;
 472                 info->ucode_start_address = ucode_start_address;
 473                 info->kptr = (void *)src;
 474         }
 475         return 0;
 476 }
 477 
 478 static const struct cgs_ops amdgpu_cgs_ops = {
 479         .read_register = amdgpu_cgs_read_register,
 480         .write_register = amdgpu_cgs_write_register,
 481         .read_ind_register = amdgpu_cgs_read_ind_register,
 482         .write_ind_register = amdgpu_cgs_write_ind_register,
 483         .get_firmware_info = amdgpu_cgs_get_firmware_info,
 484 };
 485 
 486 struct cgs_device *amdgpu_cgs_create_device(struct amdgpu_device *adev)
 487 {
 488         struct amdgpu_cgs_device *cgs_device =
 489                 kmalloc(sizeof(*cgs_device), GFP_KERNEL);
 490 
 491         if (!cgs_device) {
 492                 DRM_ERROR("Couldn't allocate CGS device structure\n");
 493                 return NULL;
 494         }
 495 
 496         cgs_device->base.ops = &amdgpu_cgs_ops;
 497         cgs_device->adev = adev;
 498 
 499         return (struct cgs_device *)cgs_device;
 500 }
 501 
 502 void amdgpu_cgs_destroy_device(struct cgs_device *cgs_device)
 503 {
 504         kfree(cgs_device);
 505 }

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