Back to home page

OSCL-LXR

 
 

    


0001 /*
0002  * Copyright 2018 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  */
0023 
0024 #include "common_baco.h"
0025 
0026 
0027 static bool baco_wait_register(struct pp_hwmgr *hwmgr, u32 reg, u32 mask, u32 value)
0028 {
0029     struct amdgpu_device *adev = (struct amdgpu_device *)(hwmgr->adev);
0030     u32 timeout = 5000, data;
0031 
0032     do {
0033         msleep(1);
0034         data = RREG32(reg);
0035         timeout--;
0036     } while (value != (data & mask) && (timeout != 0));
0037 
0038     if (timeout == 0)
0039         return false;
0040 
0041     return true;
0042 }
0043 
0044 static bool baco_cmd_handler(struct pp_hwmgr *hwmgr, u32 command, u32 reg, u32 mask,
0045                     u32 shift, u32 value, u32 timeout)
0046 {
0047     struct amdgpu_device *adev = (struct amdgpu_device *)(hwmgr->adev);
0048     u32 data;
0049     bool ret = true;
0050 
0051     switch (command) {
0052     case CMD_WRITE:
0053         WREG32(reg, value << shift);
0054         break;
0055     case CMD_READMODIFYWRITE:
0056         data = RREG32(reg);
0057         data = (data & (~mask)) | (value << shift);
0058         WREG32(reg, data);
0059         break;
0060     case CMD_WAITFOR:
0061         ret = baco_wait_register(hwmgr, reg, mask, value);
0062         break;
0063     case CMD_DELAY_MS:
0064         if (timeout)
0065             /* Delay in milli Seconds */
0066             msleep(timeout);
0067         break;
0068     case CMD_DELAY_US:
0069         if (timeout)
0070             /* Delay in micro Seconds */
0071             udelay(timeout);
0072         break;
0073 
0074     default:
0075         dev_warn(adev->dev, "Invalid BACO command.\n");
0076         ret = false;
0077     }
0078 
0079     return ret;
0080 }
0081 
0082 bool baco_program_registers(struct pp_hwmgr *hwmgr,
0083                 const struct baco_cmd_entry *entry,
0084                 const u32 array_size)
0085 {
0086     u32 i, reg = 0;
0087 
0088     for (i = 0; i < array_size; i++) {
0089         if ((entry[i].cmd == CMD_WRITE) ||
0090             (entry[i].cmd == CMD_READMODIFYWRITE) ||
0091             (entry[i].cmd == CMD_WAITFOR))
0092             reg = entry[i].reg_offset;
0093         if (!baco_cmd_handler(hwmgr, entry[i].cmd, reg, entry[i].mask,
0094                      entry[i].shift, entry[i].val, entry[i].timeout))
0095             return false;
0096     }
0097 
0098     return true;
0099 }
0100 
0101 bool soc15_baco_program_registers(struct pp_hwmgr *hwmgr,
0102                  const struct soc15_baco_cmd_entry *entry,
0103                  const u32 array_size)
0104 {
0105     struct amdgpu_device *adev = (struct amdgpu_device *)(hwmgr->adev);
0106     u32 i, reg = 0;
0107 
0108     for (i = 0; i < array_size; i++) {
0109         if ((entry[i].cmd == CMD_WRITE) ||
0110             (entry[i].cmd == CMD_READMODIFYWRITE) ||
0111             (entry[i].cmd == CMD_WAITFOR))
0112             reg = adev->reg_offset[entry[i].hwip][entry[i].inst][entry[i].seg]
0113                 + entry[i].reg_offset;
0114         if (!baco_cmd_handler(hwmgr, entry[i].cmd, reg, entry[i].mask,
0115                      entry[i].shift, entry[i].val, entry[i].timeout))
0116             return false;
0117     }
0118 
0119     return true;
0120 }