mirror of
https://github.com/BobTheBlinker/android_kernel_motorola_sm6375.git
synced 2026-10-08 12:58:12 -04:00
msm: kgsl: Allow sending CP INIT via GMU
This change adds support to send CP INIT and switch to unsecure mode packets via raw packets to GMU. Change-Id: I2915b217c9c6c7d6dc624b4349d137df9a7a2c80 Signed-off-by: Harshdeep Dhatt <hdhatt@codeaurora.org>
This commit is contained in:
parent
dde333681c
commit
fbe170edac
7 changed files with 147 additions and 17 deletions
|
|
@ -686,6 +686,25 @@ void a6xx_start(struct adreno_device *adreno_dev)
|
|||
}
|
||||
}
|
||||
|
||||
void a6xx_unhalt_sqe(struct adreno_device *adreno_dev)
|
||||
{
|
||||
struct kgsl_device *device = KGSL_DEVICE(adreno_dev);
|
||||
struct adreno_firmware *fw = ADRENO_FW(adreno_dev, ADRENO_FW_SQE);
|
||||
uint64_t gpuaddr;
|
||||
|
||||
gpuaddr = fw->memdesc->gpuaddr;
|
||||
|
||||
/* Program the ucode base for CP */
|
||||
kgsl_regwrite(device, A6XX_CP_SQE_INSTR_BASE_LO,
|
||||
lower_32_bits(gpuaddr));
|
||||
kgsl_regwrite(device, A6XX_CP_SQE_INSTR_BASE_HI,
|
||||
upper_32_bits(gpuaddr));
|
||||
|
||||
/* Clear the SQE_HALT to start the CP engine */
|
||||
kgsl_regwrite(device, A6XX_CP_SQE_CNTL, 1);
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
* CP_INIT_MAX_CONTEXT bit tells if the multiple hardware contexts can
|
||||
* be used at once of if they should be serialized
|
||||
|
|
@ -737,14 +756,14 @@ static int a6xx_get_cp_init_cmds(struct adreno_device *adreno_dev)
|
|||
if (adreno_dev->cp_init_cmds)
|
||||
return 0;
|
||||
|
||||
adreno_dev->cp_init_cmds = devm_kzalloc(&device->pdev->dev, 12 << 2,
|
||||
GFP_KERNEL);
|
||||
adreno_dev->cp_init_cmds = devm_kzalloc(&device->pdev->dev,
|
||||
A6XX_CP_INIT_DWORDS << 2, GFP_KERNEL);
|
||||
if (!adreno_dev->cp_init_cmds)
|
||||
return -ENOMEM;
|
||||
|
||||
cmds = (u32 *)adreno_dev->cp_init_cmds;
|
||||
|
||||
cmds[i++] = cp_type7_packet(CP_ME_INIT, 11);
|
||||
cmds[i++] = cp_type7_packet(CP_ME_INIT, A6XX_CP_INIT_DWORDS - 1);
|
||||
|
||||
/* Enabled ordinal mask */
|
||||
cmds[i++] = CP_INIT_MASK;
|
||||
|
|
@ -779,7 +798,7 @@ static int a6xx_get_cp_init_cmds(struct adreno_device *adreno_dev)
|
|||
return 0;
|
||||
}
|
||||
|
||||
static void a6xx_spin_idle_debug(struct adreno_device *adreno_dev,
|
||||
void a6xx_spin_idle_debug(struct adreno_device *adreno_dev,
|
||||
const char *str)
|
||||
{
|
||||
struct kgsl_device *device = &adreno_dev->dev;
|
||||
|
|
@ -911,7 +930,6 @@ static int a6xx_post_start(struct adreno_device *adreno_dev)
|
|||
int a6xx_rb_start(struct adreno_device *adreno_dev)
|
||||
{
|
||||
const struct adreno_a6xx_core *a6xx_core = to_a6xx_core(adreno_dev);
|
||||
struct adreno_firmware *fw = ADRENO_FW(adreno_dev, ADRENO_FW_SQE);
|
||||
struct kgsl_device *device = KGSL_DEVICE(adreno_dev);
|
||||
u32 cp_rb_cntl = A6XX_CP_RB_CNTL_DEFAULT |
|
||||
(ADRENO_FEATURE(adreno_dev, ADRENO_APRIV) ? 0 : (1 << 27));
|
||||
|
|
@ -952,15 +970,7 @@ int a6xx_rb_start(struct adreno_device *adreno_dev)
|
|||
kgsl_regwrite(device, A6XX_CP_RB_BASE_HI,
|
||||
upper_32_bits(rb->buffer_desc->gpuaddr));
|
||||
|
||||
/* Program the ucode base for CP */
|
||||
kgsl_regwrite(device, A6XX_CP_SQE_INSTR_BASE_LO,
|
||||
lower_32_bits(fw->memdesc->gpuaddr));
|
||||
|
||||
kgsl_regwrite(device, A6XX_CP_SQE_INSTR_BASE_HI,
|
||||
upper_32_bits(fw->memdesc->gpuaddr));
|
||||
|
||||
/* Clear the SQE_HALT to start the CP engine */
|
||||
kgsl_regwrite(device, A6XX_CP_SQE_CNTL, 1);
|
||||
a6xx_unhalt_sqe(adreno_dev);
|
||||
|
||||
ret = a6xx_send_cp_init(adreno_dev, rb);
|
||||
if (ret)
|
||||
|
|
|
|||
|
|
@ -183,6 +183,9 @@ struct cpu_gpu_lock {
|
|||
#define A6XX_CP_RB_CNTL_DEFAULT (((ilog2(4) << 8) & 0x1F00) | \
|
||||
(ilog2(KGSL_RB_DWORDS >> 1) & 0x3F))
|
||||
|
||||
/* Size of the CP_INIT pm4 stream in dwords */
|
||||
#define A6XX_CP_INIT_DWORDS 12
|
||||
|
||||
/**
|
||||
* to_a6xx_core - return the a6xx specific GPU core struct
|
||||
* @adreno_dev: An Adreno GPU device handle
|
||||
|
|
@ -274,6 +277,15 @@ u64 a6xx_read_alwayson(struct adreno_device *adreno_dev);
|
|||
*/
|
||||
void a6xx_start(struct adreno_device *adreno_dev);
|
||||
|
||||
/**
|
||||
* a6xx_sqe_unhalt - Unhalt the SQE engine
|
||||
* @adreno_dev: An Adreno GPU handle
|
||||
*
|
||||
* Points the hardware to the microcode location in memory and then
|
||||
* unhalts the SQE so that it can fetch instructions from DDR
|
||||
*/
|
||||
void a6xx_unhalt_sqe(struct adreno_device *adreno_dev);
|
||||
|
||||
/**
|
||||
* a6xx_init - Initialize a6xx resources
|
||||
* @adreno_dev: An Adreno GPU handle
|
||||
|
|
@ -329,4 +341,13 @@ int a6xx_probe_common(struct platform_device *pdev,
|
|||
* Return: True if gpu is idle, otherwise false
|
||||
*/
|
||||
bool a6xx_hw_isidle(struct adreno_device *adreno_dev);
|
||||
|
||||
/**
|
||||
* a6xx_spin_idle_debug - Debug logging used when gpu fails to idle
|
||||
* @adreno_dev: An Adreno GPU handle
|
||||
*
|
||||
* This function logs interesting registers and triggers a snapshot
|
||||
*/
|
||||
void a6xx_spin_idle_debug(struct adreno_device *adreno_dev,
|
||||
const char *str);
|
||||
#endif
|
||||
|
|
|
|||
|
|
@ -286,8 +286,8 @@ static int poll_gmu_reg(struct adreno_device *adreno_dev,
|
|||
return -ETIMEDOUT;
|
||||
}
|
||||
|
||||
static int a6xx_hfi_send_cmd(struct adreno_device *adreno_dev,
|
||||
uint32_t queue_idx, void *data, struct pending_cmd *ret_cmd)
|
||||
int a6xx_hfi_send_cmd(struct adreno_device *adreno_dev, uint32_t queue_idx,
|
||||
void *data, struct pending_cmd *ret_cmd)
|
||||
{
|
||||
struct a6xx_gmu_device *gmu = to_a6xx_gmu(adreno_dev);
|
||||
struct kgsl_device *device = KGSL_DEVICE(adreno_dev);
|
||||
|
|
|
|||
|
|
@ -675,4 +675,16 @@ int a6xx_hfi_send_generic_req(struct adreno_device *adreno_dev,
|
|||
* Return: 0 on success or negative error on failure
|
||||
*/
|
||||
int a6xx_hfi_send_bcl_feature_ctrl(struct adreno_device *adreno_dev);
|
||||
|
||||
/*
|
||||
* a6xx_hfi_send_cmd - Send and wait for a hfi packet
|
||||
* @adreno_dev: Pointer to the adreno device
|
||||
* @queue_idx: Destination queue id
|
||||
* @data: Pointer to hfi packet header and data
|
||||
* @ret_cmd: Container for data needed for waiting for the ack
|
||||
*
|
||||
* Return: 0 on success or negative error on failure
|
||||
*/
|
||||
int a6xx_hfi_send_cmd(struct adreno_device *adreno_dev, u32 queue_idx,
|
||||
void *data, struct pending_cmd *ret_cmd);
|
||||
#endif
|
||||
|
|
|
|||
|
|
@ -256,6 +256,12 @@ static int a6xx_hwsched_gpu_boot(struct adreno_device *adreno_dev)
|
|||
|
||||
a6xx_enable_gpu_irq(adreno_dev);
|
||||
|
||||
ret = a6xx_hwsched_cp_init(adreno_dev);
|
||||
if (ret) {
|
||||
a6xx_disable_gpu_irq(adreno_dev);
|
||||
goto err;
|
||||
}
|
||||
|
||||
device->reset_counter++;
|
||||
err:
|
||||
a6xx_gmu_oob_clear(device, oob_gpu);
|
||||
|
|
|
|||
|
|
@ -8,6 +8,7 @@
|
|||
#include "adreno.h"
|
||||
#include "adreno_a6xx.h"
|
||||
#include "adreno_a6xx_hwsched.h"
|
||||
#include "adreno_pm4types.h"
|
||||
#include "kgsl_device.h"
|
||||
#include "kgsl_pwrctrl.h"
|
||||
#include "kgsl_trace.h"
|
||||
|
|
@ -457,3 +458,69 @@ err:
|
|||
|
||||
return ret;
|
||||
}
|
||||
|
||||
static int submit_raw_cmds(struct adreno_device *adreno_dev, void *cmds,
|
||||
const char *str)
|
||||
{
|
||||
struct pending_cmd ret_cmd = {0};
|
||||
int ret;
|
||||
|
||||
ret = a6xx_hfi_send_cmd(adreno_dev, HFI_CMD_ID, cmds, &ret_cmd);
|
||||
if (ret)
|
||||
return ret;
|
||||
|
||||
ret = timed_poll_check(KGSL_DEVICE(adreno_dev),
|
||||
A6XX_GPU_GMU_AO_GPU_CX_BUSY_STATUS, 0, 200, BIT(23));
|
||||
if (ret)
|
||||
a6xx_spin_idle_debug(adreno_dev, str);
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
static int cp_init(struct adreno_device *adreno_dev)
|
||||
{
|
||||
u32 cmds[A6XX_CP_INIT_DWORDS + 1];
|
||||
|
||||
cmds[0] = CMD_MSG_HDR(H2F_MSG_ISSUE_CMD_RAW,
|
||||
(A6XX_CP_INIT_DWORDS + 1) << 2);
|
||||
memcpy(&cmds[1], adreno_dev->cp_init_cmds, A6XX_CP_INIT_DWORDS << 2);
|
||||
|
||||
return submit_raw_cmds(adreno_dev, cmds,
|
||||
"CP initialization failed to idle\n");
|
||||
}
|
||||
|
||||
static int send_switch_to_unsecure(struct adreno_device *adreno_dev)
|
||||
{
|
||||
u32 cmds[3];
|
||||
|
||||
cmds[0] = CMD_MSG_HDR(H2F_MSG_ISSUE_CMD_RAW, sizeof(cmds));
|
||||
cmds[1] = cp_type7_packet(CP_SET_SECURE_MODE, 1);
|
||||
cmds[2] = 0;
|
||||
|
||||
return submit_raw_cmds(adreno_dev, cmds,
|
||||
"Switch to unsecure failed to idle\n");
|
||||
}
|
||||
|
||||
int a6xx_hwsched_cp_init(struct adreno_device *adreno_dev)
|
||||
{
|
||||
const struct adreno_a6xx_core *a6xx_core = to_a6xx_core(adreno_dev);
|
||||
int ret;
|
||||
|
||||
a6xx_unhalt_sqe(adreno_dev);
|
||||
|
||||
ret = cp_init(adreno_dev);
|
||||
if (ret)
|
||||
return ret;
|
||||
|
||||
ret = adreno_zap_shader_load(adreno_dev, a6xx_core->zap_name);
|
||||
if (ret)
|
||||
return ret;
|
||||
|
||||
if (!adreno_dev->zap_loaded)
|
||||
kgsl_regwrite(KGSL_DEVICE(adreno_dev),
|
||||
A6XX_RBBM_SECVID_TRUST_CNTL, 0x0);
|
||||
else
|
||||
ret = send_switch_to_unsecure(adreno_dev);
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
|
|
|||
|
|
@ -109,9 +109,12 @@ struct a6xx_hwsched_hfi {
|
|||
u32 mem_alloc_entries;
|
||||
};
|
||||
|
||||
/* Interrupt handler for hfi interrupts */
|
||||
irqreturn_t a6xx_hfi_handler(int irq, void *data);
|
||||
|
||||
/**
|
||||
* a6xx_hwsched_hfi_init - Initialize hfi resources
|
||||
* @adreno_dev - Pointer to adreno device structure
|
||||
* @adreno_dev: Pointer to adreno device structure
|
||||
*
|
||||
* This function is used to initialize hfi resources
|
||||
* once before the very first gmu boot
|
||||
|
|
@ -137,4 +140,15 @@ int a6xx_hwsched_hfi_start(struct adreno_device *adreno_dev);
|
|||
* This function does the hfi cleanup when powering down the gmu
|
||||
*/
|
||||
void a6xx_hwsched_hfi_stop(struct adreno_device *adreno_dev);
|
||||
|
||||
/**
|
||||
* a6xx_hwched_cp_init - Send CP_INIT via HFI
|
||||
* @adreno_dev: Pointer to adreno device structure
|
||||
*
|
||||
* This function is used to send CP INIT packet and bring
|
||||
* GPU out of secure mode using hfi raw packets.
|
||||
*
|
||||
* Return: 0 on success and negative error on failure.
|
||||
*/
|
||||
int a6xx_hwsched_cp_init(struct adreno_device *adreno_dev);
|
||||
#endif
|
||||
|
|
|
|||
Loading…
Reference in a new issue