Back to home page

OSCL-LXR

 
 

    


0001 /*
0002  * Copyright 2011 Advanced Micro Devices, Inc.
0003  *
0004  * Permission is hereby granted, free of charge, to any person obtaining a
0005  * copy of this software and associated documentation files (the "Software"),
0006  * to deal in the Software without restriction, including without limitation
0007  * the rights to use, copy, modify, merge, publish, distribute, sublicense,
0008  * and/or sell copies of the Software, and to permit persons to whom the
0009  * Software is furnished to do so, subject to the following conditions:
0010  *
0011  * The above copyright notice and this permission notice shall be included in
0012  * all copies or substantial portions of the Software.
0013  *
0014  * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
0015  * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
0016  * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.  IN NO EVENT SHALL
0017  * THE COPYRIGHT HOLDER(S) OR AUTHOR(S) BE LIABLE FOR ANY CLAIM, DAMAGES OR
0018  * OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE,
0019  * ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
0020  * OTHER DEALINGS IN THE SOFTWARE.
0021  *
0022  * Authors: Alex Deucher
0023  */
0024 
0025 #include <linux/firmware.h>
0026 
0027 #include "radeon.h"
0028 #include "sid.h"
0029 #include "ppsmc.h"
0030 #include "radeon_ucode.h"
0031 #include "sislands_smc.h"
0032 
0033 static int si_set_smc_sram_address(struct radeon_device *rdev,
0034                    u32 smc_address, u32 limit)
0035 {
0036     if (smc_address & 3)
0037         return -EINVAL;
0038     if ((smc_address + 3) > limit)
0039         return -EINVAL;
0040 
0041     WREG32(SMC_IND_INDEX_0, smc_address);
0042     WREG32_P(SMC_IND_ACCESS_CNTL, 0, ~AUTO_INCREMENT_IND_0);
0043 
0044     return 0;
0045 }
0046 
0047 int si_copy_bytes_to_smc(struct radeon_device *rdev,
0048              u32 smc_start_address,
0049              const u8 *src, u32 byte_count, u32 limit)
0050 {
0051     unsigned long flags;
0052     int ret = 0;
0053     u32 data, original_data, addr, extra_shift;
0054 
0055     if (smc_start_address & 3)
0056         return -EINVAL;
0057     if ((smc_start_address + byte_count) > limit)
0058         return -EINVAL;
0059 
0060     addr = smc_start_address;
0061 
0062     spin_lock_irqsave(&rdev->smc_idx_lock, flags);
0063     while (byte_count >= 4) {
0064         /* SMC address space is BE */
0065         data = (src[0] << 24) | (src[1] << 16) | (src[2] << 8) | src[3];
0066 
0067         ret = si_set_smc_sram_address(rdev, addr, limit);
0068         if (ret)
0069             goto done;
0070 
0071         WREG32(SMC_IND_DATA_0, data);
0072 
0073         src += 4;
0074         byte_count -= 4;
0075         addr += 4;
0076     }
0077 
0078     /* RMW for the final bytes */
0079     if (byte_count > 0) {
0080         data = 0;
0081 
0082         ret = si_set_smc_sram_address(rdev, addr, limit);
0083         if (ret)
0084             goto done;
0085 
0086         original_data = RREG32(SMC_IND_DATA_0);
0087 
0088         extra_shift = 8 * (4 - byte_count);
0089 
0090         while (byte_count > 0) {
0091             /* SMC address space is BE */
0092             data = (data << 8) + *src++;
0093             byte_count--;
0094         }
0095 
0096         data <<= extra_shift;
0097 
0098         data |= (original_data & ~((~0UL) << extra_shift));
0099 
0100         ret = si_set_smc_sram_address(rdev, addr, limit);
0101         if (ret)
0102             goto done;
0103 
0104         WREG32(SMC_IND_DATA_0, data);
0105     }
0106 
0107 done:
0108     spin_unlock_irqrestore(&rdev->smc_idx_lock, flags);
0109 
0110     return ret;
0111 }
0112 
0113 void si_start_smc(struct radeon_device *rdev)
0114 {
0115     u32 tmp = RREG32_SMC(SMC_SYSCON_RESET_CNTL);
0116 
0117     tmp &= ~RST_REG;
0118 
0119     WREG32_SMC(SMC_SYSCON_RESET_CNTL, tmp);
0120 }
0121 
0122 void si_reset_smc(struct radeon_device *rdev)
0123 {
0124     u32 tmp;
0125 
0126     RREG32(CB_CGTT_SCLK_CTRL);
0127     RREG32(CB_CGTT_SCLK_CTRL);
0128     RREG32(CB_CGTT_SCLK_CTRL);
0129     RREG32(CB_CGTT_SCLK_CTRL);
0130 
0131     tmp = RREG32_SMC(SMC_SYSCON_RESET_CNTL);
0132     tmp |= RST_REG;
0133     WREG32_SMC(SMC_SYSCON_RESET_CNTL, tmp);
0134 }
0135 
0136 int si_program_jump_on_start(struct radeon_device *rdev)
0137 {
0138     static const u8 data[] = { 0x0E, 0x00, 0x40, 0x40 };
0139 
0140     return si_copy_bytes_to_smc(rdev, 0x0, data, 4, sizeof(data)+1);
0141 }
0142 
0143 void si_stop_smc_clock(struct radeon_device *rdev)
0144 {
0145     u32 tmp = RREG32_SMC(SMC_SYSCON_CLOCK_CNTL_0);
0146 
0147     tmp |= CK_DISABLE;
0148 
0149     WREG32_SMC(SMC_SYSCON_CLOCK_CNTL_0, tmp);
0150 }
0151 
0152 void si_start_smc_clock(struct radeon_device *rdev)
0153 {
0154     u32 tmp = RREG32_SMC(SMC_SYSCON_CLOCK_CNTL_0);
0155 
0156     tmp &= ~CK_DISABLE;
0157 
0158     WREG32_SMC(SMC_SYSCON_CLOCK_CNTL_0, tmp);
0159 }
0160 
0161 bool si_is_smc_running(struct radeon_device *rdev)
0162 {
0163     u32 rst = RREG32_SMC(SMC_SYSCON_RESET_CNTL);
0164     u32 clk = RREG32_SMC(SMC_SYSCON_CLOCK_CNTL_0);
0165 
0166     if (!(rst & RST_REG) && !(clk & CK_DISABLE))
0167         return true;
0168 
0169     return false;
0170 }
0171 
0172 PPSMC_Result si_send_msg_to_smc(struct radeon_device *rdev, PPSMC_Msg msg)
0173 {
0174     u32 tmp;
0175     int i;
0176 
0177     if (!si_is_smc_running(rdev))
0178         return PPSMC_Result_Failed;
0179 
0180     WREG32(SMC_MESSAGE_0, msg);
0181 
0182     for (i = 0; i < rdev->usec_timeout; i++) {
0183         tmp = RREG32(SMC_RESP_0);
0184         if (tmp != 0)
0185             break;
0186         udelay(1);
0187     }
0188     tmp = RREG32(SMC_RESP_0);
0189 
0190     return (PPSMC_Result)tmp;
0191 }
0192 
0193 PPSMC_Result si_wait_for_smc_inactive(struct radeon_device *rdev)
0194 {
0195     u32 tmp;
0196     int i;
0197 
0198     if (!si_is_smc_running(rdev))
0199         return PPSMC_Result_OK;
0200 
0201     for (i = 0; i < rdev->usec_timeout; i++) {
0202         tmp = RREG32_SMC(SMC_SYSCON_CLOCK_CNTL_0);
0203         if ((tmp & CKEN) == 0)
0204             break;
0205         udelay(1);
0206     }
0207 
0208     return PPSMC_Result_OK;
0209 }
0210 
0211 int si_load_smc_ucode(struct radeon_device *rdev, u32 limit)
0212 {
0213     unsigned long flags;
0214     u32 ucode_start_address;
0215     u32 ucode_size;
0216     const u8 *src;
0217     u32 data;
0218 
0219     if (!rdev->smc_fw)
0220         return -EINVAL;
0221 
0222     if (rdev->new_fw) {
0223         const struct smc_firmware_header_v1_0 *hdr =
0224             (const struct smc_firmware_header_v1_0 *)rdev->smc_fw->data;
0225 
0226         radeon_ucode_print_smc_hdr(&hdr->header);
0227 
0228         ucode_start_address = le32_to_cpu(hdr->ucode_start_addr);
0229         ucode_size = le32_to_cpu(hdr->header.ucode_size_bytes);
0230         src = (const u8 *)
0231             (rdev->smc_fw->data + le32_to_cpu(hdr->header.ucode_array_offset_bytes));
0232     } else {
0233         switch (rdev->family) {
0234         case CHIP_TAHITI:
0235             ucode_start_address = TAHITI_SMC_UCODE_START;
0236             ucode_size = TAHITI_SMC_UCODE_SIZE;
0237             break;
0238         case CHIP_PITCAIRN:
0239             ucode_start_address = PITCAIRN_SMC_UCODE_START;
0240             ucode_size = PITCAIRN_SMC_UCODE_SIZE;
0241             break;
0242         case CHIP_VERDE:
0243             ucode_start_address = VERDE_SMC_UCODE_START;
0244             ucode_size = VERDE_SMC_UCODE_SIZE;
0245             break;
0246         case CHIP_OLAND:
0247             ucode_start_address = OLAND_SMC_UCODE_START;
0248             ucode_size = OLAND_SMC_UCODE_SIZE;
0249             break;
0250         case CHIP_HAINAN:
0251             ucode_start_address = HAINAN_SMC_UCODE_START;
0252             ucode_size = HAINAN_SMC_UCODE_SIZE;
0253             break;
0254         default:
0255             DRM_ERROR("unknown asic in smc ucode loader\n");
0256             BUG();
0257         }
0258         src = (const u8 *)rdev->smc_fw->data;
0259     }
0260 
0261     if (ucode_size & 3)
0262         return -EINVAL;
0263 
0264     spin_lock_irqsave(&rdev->smc_idx_lock, flags);
0265     WREG32(SMC_IND_INDEX_0, ucode_start_address);
0266     WREG32_P(SMC_IND_ACCESS_CNTL, AUTO_INCREMENT_IND_0, ~AUTO_INCREMENT_IND_0);
0267     while (ucode_size >= 4) {
0268         /* SMC address space is BE */
0269         data = (src[0] << 24) | (src[1] << 16) | (src[2] << 8) | src[3];
0270 
0271         WREG32(SMC_IND_DATA_0, data);
0272 
0273         src += 4;
0274         ucode_size -= 4;
0275     }
0276     WREG32_P(SMC_IND_ACCESS_CNTL, 0, ~AUTO_INCREMENT_IND_0);
0277     spin_unlock_irqrestore(&rdev->smc_idx_lock, flags);
0278 
0279     return 0;
0280 }
0281 
0282 int si_read_smc_sram_dword(struct radeon_device *rdev, u32 smc_address,
0283                u32 *value, u32 limit)
0284 {
0285     unsigned long flags;
0286     int ret;
0287 
0288     spin_lock_irqsave(&rdev->smc_idx_lock, flags);
0289     ret = si_set_smc_sram_address(rdev, smc_address, limit);
0290     if (ret == 0)
0291         *value = RREG32(SMC_IND_DATA_0);
0292     spin_unlock_irqrestore(&rdev->smc_idx_lock, flags);
0293 
0294     return ret;
0295 }
0296 
0297 int si_write_smc_sram_dword(struct radeon_device *rdev, u32 smc_address,
0298                 u32 value, u32 limit)
0299 {
0300     unsigned long flags;
0301     int ret;
0302 
0303     spin_lock_irqsave(&rdev->smc_idx_lock, flags);
0304     ret = si_set_smc_sram_address(rdev, smc_address, limit);
0305     if (ret == 0)
0306         WREG32(SMC_IND_DATA_0, value);
0307     spin_unlock_irqrestore(&rdev->smc_idx_lock, flags);
0308 
0309     return ret;
0310 }