Merge "msm: kgsl: Set bus scaling function during gmu probe"

This commit is contained in:
qctecmdr 2020-02-27 11:35:12 -08:00 • committed by Gerrit - the friendly Code Review server
commit 4f6c398965
8 changed files with 179 additions and 117 deletions

View file

@ -1830,6 +1830,12 @@ static int adreno_init(struct kgsl_device *device)
if (ret)
return ret;
if (gpudev->init != NULL) {
ret = gpudev->init(adreno_dev);
if (ret)
return ret;
}
ret = gmu_core_init(device);
if (ret)
return ret;
@ -1853,9 +1859,6 @@ static int adreno_init(struct kgsl_device *device)
if (ADRENO_GPUREV(adreno_dev) < 600)
kgsl_pwrctrl_change_state(device, KGSL_STATE_SLUMBER);
if (gpudev->init != NULL)
gpudev->init(adreno_dev);
set_bit(ADRENO_DEVICE_INITIALIZED, &adreno_dev->priv);
/*

View file

@ -536,7 +536,8 @@ struct adreno_device {
* @critpkts: Memory descriptor for 5xx secure critical packets
*/
struct kgsl_memdesc *critpkts_secure;
/** @cp_init_cmds: A copy of the CP INIT commands */
const void *cp_init_cmds;
};
/**
@ -776,7 +777,7 @@ struct adreno_gpudev {
void (*snapshot)(struct adreno_device *adreno_dev,
struct kgsl_snapshot *snapshot);
void (*platform_setup)(struct adreno_device *adreno_dev);
void (*init)(struct adreno_device *adreno_dev);
int (*init)(struct adreno_device *adreno_dev);
void (*remove)(struct adreno_device *adreno_dev);
int (*rb_start)(struct adreno_device *adreno_dev);
int (*microcode_read)(struct adreno_device *adreno_dev);

View file

@ -1,6 +1,6 @@
// SPDX-License-Identifier: GPL-2.0-only
/*
* Copyright (c) 2012-2019, The Linux Foundation. All rights reserved.
* Copyright (c) 2012-2020, The Linux Foundation. All rights reserved.
*/
#include <linux/firmware.h>
@ -124,6 +124,8 @@ static const unsigned int _a3xx_pwron_fixup_fs_instructions[] = {
0x00000000, 0x03000000, 0x00000000, 0x00000000,
};
static int a3xx_get_cp_init_cmds(struct adreno_device *adreno_dev);
static void a3xx_efuse_speed_bin(struct adreno_device *adreno_dev)
{
unsigned int val;
@ -623,28 +625,7 @@ static int a3xx_send_me_init(struct adreno_device *adreno_dev,
if (cmds == NULL)
return -ENOSPC;
*cmds++ = cp_type3_packet(CP_ME_INIT, 17);
*cmds++ = 0x000003f7;
*cmds++ = 0x00000000;
*cmds++ = 0x00000000;
*cmds++ = 0x00000000;
*cmds++ = 0x00000080;
*cmds++ = 0x00000100;
*cmds++ = 0x00000180;
*cmds++ = 0x00006600;
*cmds++ = 0x00000150;
*cmds++ = 0x0000014e;
*cmds++ = 0x00000154;
*cmds++ = 0x00000001;
*cmds++ = 0x00000000;
*cmds++ = 0x00000000;
/* Enable protected mode registers for A3XX */
*cmds++ = 0x20000000;
*cmds++ = 0x00000000;
*cmds++ = 0x00000000;
memcpy(cmds, adreno_dev->cp_init_cmds, 18 << 2);
ret = adreno_ringbuffer_submit_spin(rb, NULL, 2000);
if (ret) {
@ -685,13 +666,56 @@ static int a3xx_rb_start(struct adreno_device *adreno_dev)
return a3xx_send_me_init(adreno_dev, rb);
}
static int a3xx_get_cp_init_cmds(struct adreno_device *adreno_dev)
{
struct kgsl_device *device = KGSL_DEVICE(adreno_dev);
u32 *cmds;
if (adreno_dev->cp_init_cmds)
return 0;
adreno_dev->cp_init_cmds = devm_kzalloc(&device->pdev->dev, 18 << 2,
GFP_KERNEL);
if (!adreno_dev->cp_init_cmds)
return -ENOMEM;
cmds = (u32 *)adreno_dev->cp_init_cmds;
*cmds++ = cp_type3_packet(CP_ME_INIT, 17);
*cmds++ = 0x000003f7;
*cmds++ = 0x00000000;
*cmds++ = 0x00000000;
*cmds++ = 0x00000000;
*cmds++ = 0x00000080;
*cmds++ = 0x00000100;
*cmds++ = 0x00000180;
*cmds++ = 0x00006600;
*cmds++ = 0x00000150;
*cmds++ = 0x0000014e;
*cmds++ = 0x00000154;
*cmds++ = 0x00000001;
*cmds++ = 0x00000000;
*cmds++ = 0x00000000;
/* Enable protected mode registers for A3XX */
*cmds++ = 0x20000000;
*cmds++ = 0x00000000;
*cmds++ = 0x00000000;
return 0;
}
/*
* a3xx_init() - Initialize gpu specific data
* @adreno_dev: Pointer to adreno device
*/
static void a3xx_init(struct adreno_device *adreno_dev)
static int a3xx_init(struct adreno_device *adreno_dev)
{
_a3xx_pwron_fixup(adreno_dev);
return a3xx_get_cp_init_cmds(adreno_dev);
}
/*

View file

@ -25,6 +25,7 @@ static int _read_fw2_block_header(struct kgsl_device *device,
uint32_t id, uint32_t major, uint32_t minor);
static void a5xx_gpmu_reset(struct work_struct *work);
static int a5xx_gpmu_init(struct adreno_device *adreno_dev);
static int a5xx_get_cp_init_cmds(struct adreno_device *adreno_dev);
/**
* Number of times to check if the regulator enabled before
@ -185,7 +186,7 @@ static int a5xx_critical_packet_construct(struct adreno_device *adreno_dev)
return 0;
}
static void a5xx_init(struct adreno_device *adreno_dev)
static int a5xx_init(struct adreno_device *adreno_dev)
{
const struct adreno_a5xx_core *a5xx_core = to_a5xx_core(adreno_dev);
@ -199,8 +200,9 @@ static void a5xx_init(struct adreno_device *adreno_dev)
if (ADRENO_QUIRK(adreno_dev, ADRENO_QUIRK_CRITICAL_PACKETS))
a5xx_critical_packet_construct(adreno_dev);
a5xx_crashdump_init(adreno_dev);
return a5xx_get_cp_init_cmds(adreno_dev);
}
const static struct {
@ -1739,42 +1741,6 @@ static int _me_init_ucode_workarounds(struct adreno_device *adreno_dev)
CP_INIT_DEFAULT_RESET_STATE | \
CP_INIT_UCODE_WORKAROUND_MASK)
static void _set_ordinals(struct adreno_device *adreno_dev,
unsigned int *cmds, unsigned int count)
{
unsigned int *start = cmds;
/* Enabled ordinal mask */
*cmds++ = CP_INIT_MASK;
if (CP_INIT_MASK & CP_INIT_MAX_CONTEXT)
*cmds++ = 0x00000003;
if (CP_INIT_MASK & CP_INIT_ERROR_DETECTION_CONTROL)
*cmds++ = 0x20000000;
if (CP_INIT_MASK & CP_INIT_HEADER_DUMP) {
/* Header dump address */
*cmds++ = 0x00000000;
/* Header dump enable and dump size */
*cmds++ = 0x00000000;
}
if (CP_INIT_MASK & CP_INIT_DRAWCALL_FILTER_RANGE) {
/* Start range */
*cmds++ = 0x00000000;
/* End range (inclusive) */
*cmds++ = 0x00000000;
}
if (CP_INIT_MASK & CP_INIT_UCODE_WORKAROUND_MASK)
*cmds++ = _me_init_ucode_workarounds(adreno_dev);
/* Pad rest of the cmds with 0's */
while ((unsigned int)(cmds - start) < count)
*cmds++ = 0x0;
}
static int a5xx_critical_packet_submit(struct adreno_device *adreno_dev,
struct adreno_ringbuffer *rb)
{
@ -1800,6 +1766,53 @@ static int a5xx_critical_packet_submit(struct adreno_device *adreno_dev,
return ret;
}
static int a5xx_get_cp_init_cmds(struct adreno_device *adreno_dev)
{
struct kgsl_device *device = KGSL_DEVICE(adreno_dev);
u32 *cmds, i = 0;
if (adreno_dev->cp_init_cmds)
return 0;
adreno_dev->cp_init_cmds = devm_kzalloc(&device->pdev->dev, 9 << 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, 8);
/* Enabled ordinal mask */
cmds[i++] = CP_INIT_MASK;
if (CP_INIT_MASK & CP_INIT_MAX_CONTEXT)
cmds[i++] = 0x00000003;
if (CP_INIT_MASK & CP_INIT_ERROR_DETECTION_CONTROL)
cmds[i++] = 0x20000000;
if (CP_INIT_MASK & CP_INIT_HEADER_DUMP) {
/* Header dump address */
cmds[i++] = 0x00000000;
/* Header dump enable and dump size */
cmds[i++] = 0x00000000;
}
if (CP_INIT_MASK & CP_INIT_DRAWCALL_FILTER_RANGE) {
/* Start range */
cmds[i++] = 0x00000000;
/* End range (inclusive) */
cmds[i++] = 0x00000000;
}
if (CP_INIT_MASK & CP_INIT_UCODE_WORKAROUND_MASK)
cmds[i++] = _me_init_ucode_workarounds(adreno_dev);
return 0;
}
/*
* a5xx_send_me_init() - Initialize ringbuffer
* @adreno_dev: Pointer to adreno device
@ -1819,9 +1832,7 @@ static int a5xx_send_me_init(struct adreno_device *adreno_dev,
if (cmds == NULL)
return -ENOSPC;
*cmds++ = cp_type7_packet(CP_ME_INIT, 8);
_set_ordinals(adreno_dev, cmds, 8);
memcpy(cmds, adreno_dev->cp_init_cmds, 9 << 2);
ret = adreno_ringbuffer_submit_spin(rb, NULL, 2000);
if (ret)

View file

@ -99,10 +99,11 @@ static u32 a612_pwrup_reglist[] = {
A6XX_RBBM_PERFCTR_CNTL,
};
static void a6xx_init(struct adreno_device *adreno_dev)
static int a6xx_get_cp_init_cmds(struct adreno_device *adreno_dev);
static int a6xx_init(struct adreno_device *adreno_dev)
{
const struct adreno_a6xx_core *a6xx_core = to_a6xx_core(adreno_dev);
struct kgsl_device *device = KGSL_DEVICE(adreno_dev);
adreno_dev->highest_bank_bit = a6xx_core->highest_bank_bit;
@ -111,10 +112,16 @@ static void a6xx_init(struct adreno_device *adreno_dev)
a6xx_crashdump_init(adreno_dev);
if (IS_ERR_OR_NULL(adreno_dev->pwrup_reglist))
adreno_dev->pwrup_reglist = kgsl_allocate_global(device,
PAGE_SIZE, 0, KGSL_MEMDESC_PRIVILEGED,
"powerup_register_list");
if (IS_ERR_OR_NULL(adreno_dev->pwrup_reglist)) {
adreno_dev->pwrup_reglist =
kgsl_allocate_global(KGSL_DEVICE(adreno_dev),
PAGE_SIZE, 0, KGSL_MEMDESC_PRIVILEGED,
"powerup_register_list");
if (IS_ERR(adreno_dev->pwrup_reglist))
return PTR_ERR(adreno_dev->pwrup_reglist);
}
return a6xx_get_cp_init_cmds(adreno_dev);
}
static void a6xx_protect_init(struct adreno_device *adreno_dev)
@ -671,44 +678,54 @@ static int a6xx_microcode_load(struct adreno_device *adreno_dev)
CP_INIT_OPERATION_MODE_MASK | \
CP_INIT_REGISTER_INIT_LIST_WITH_SPINLOCK)
static void _set_ordinals(struct adreno_device *adreno_dev,
unsigned int *cmds, unsigned int count)
static int a6xx_get_cp_init_cmds(struct adreno_device *adreno_dev)
{
unsigned int *start = cmds;
struct kgsl_device *device = KGSL_DEVICE(adreno_dev);
u32 *cmds, i = 0;
if (adreno_dev->cp_init_cmds)
return 0;
adreno_dev->cp_init_cmds = devm_kzalloc(&device->pdev->dev, 12 << 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);
/* Enabled ordinal mask */
*cmds++ = CP_INIT_MASK;
cmds[i++] = CP_INIT_MASK;
if (CP_INIT_MASK & CP_INIT_MAX_CONTEXT)
*cmds++ = 0x00000003;
cmds[i++] = 0x00000003;
if (CP_INIT_MASK & CP_INIT_ERROR_DETECTION_CONTROL)
*cmds++ = 0x20000000;
cmds[i++] = 0x20000000;
if (CP_INIT_MASK & CP_INIT_HEADER_DUMP) {
/* Header dump address */
*cmds++ = 0x00000000;
cmds[i++] = 0x00000000;
/* Header dump enable and dump size */
*cmds++ = 0x00000000;
cmds[i++] = 0x00000000;
}
if (CP_INIT_MASK & CP_INIT_UCODE_WORKAROUND_MASK)
*cmds++ = 0x00000000;
cmds[i++] = 0x00000000;
if (CP_INIT_MASK & CP_INIT_OPERATION_MODE_MASK)
*cmds++ = 0x00000002;
cmds[i++] = 0x00000002;
if (CP_INIT_MASK & CP_INIT_REGISTER_INIT_LIST_WITH_SPINLOCK) {
uint64_t gpuaddr = adreno_dev->pwrup_reglist->gpuaddr;
*cmds++ = lower_32_bits(gpuaddr);
*cmds++ = upper_32_bits(gpuaddr);
*cmds++ = 0;
cmds[i++] = lower_32_bits(gpuaddr);
cmds[i++] = upper_32_bits(gpuaddr);
cmds[i++] = 0;
}
/* Pad rest of the cmds with 0's */
while ((unsigned int)(cmds - start) < count)
*cmds++ = 0x0;
return 0;
}
/*
@ -729,9 +746,7 @@ static int a6xx_send_cp_init(struct adreno_device *adreno_dev,
if (IS_ERR(cmds))
return PTR_ERR(cmds);
*cmds++ = cp_type7_packet(CP_ME_INIT, 11);
_set_ordinals(adreno_dev, cmds, 11);
memcpy(cmds, adreno_dev->cp_init_cmds, 12 << 2);
ret = adreno_ringbuffer_submit_spin(rb, NULL, 2000);
if (ret) {

View file

@ -351,10 +351,6 @@ static int a6xx_gmu_start(struct kgsl_device *device)
mask = 0xFFFFFFFF;
}
/* Set the log wptr index */
gmu_core_regwrite(device, A6XX_GPU_GMU_CX_GMU_PWR_COL_CP_RESP,
gmu->log_wptr_retention);
/* Bring GMU out of reset */
gmu_core_regwrite(device, A6XX_GMU_CM3_SYSRESET, 0);
@ -1069,6 +1065,18 @@ static int a6xx_gmu_fw_start(struct kgsl_device *device,
*/
gmu_core_regwrite(device, A6XX_GMU_CM3_CFG, 0x4052);
/**
* We may have asserted gbif halt as part of reset sequence which may
* not get cleared if the gdsc was not reset. So clear it before
* attempting GMU boot.
*/
if (!adreno_is_a630(ADRENO_DEVICE(device)))
kgsl_regwrite(device, A6XX_GBIF_HALT, 0x0);
/* Set the log wptr index */
gmu_core_regwrite(device, A6XX_GPU_GMU_CX_GMU_PWR_COL_CP_RESP,
gmu->log_wptr_retention);
/* Pass chipid to GMU FW, must happen before starting GMU */
/* Keep Core and Major bitfields unchanged */

View file

@ -10,20 +10,6 @@
#include "kgsl_device.h"
#include "kgsl_trace.h"
static int gmu_bus_set(struct kgsl_device *device, int buslevel,
u32 ab)
{
struct kgsl_pwrctrl *pwr = &device->pwrctrl;
int ret;
ret = gmu_core_dcvs_set(device, INVALID_DCVS_IDX, buslevel);
if (!ret)
icc_set_bw(pwr->icc_path, MBps_to_icc(ab), 0);
return ret;
}
static int interconnect_bus_set(struct kgsl_device *device, int level,
u32 ab)
{
@ -179,10 +165,7 @@ done:
return PTR_ERR(pwr->icc_path);
}
if (gmu_core_scales_bandwidth(device))
pwr->bus_set = gmu_bus_set;
else
pwr->bus_set = interconnect_bus_set;
pwr->bus_set = interconnect_bus_set;
return 0;
}

View file

@ -1282,6 +1282,20 @@ static void gmu_acd_probe(struct kgsl_device *device, struct gmu_device *gmu,
"AOP mailbox init failed: %d\n", ret);
}
static int gmu_bus_set(struct kgsl_device *device, int buslevel,
u32 ab)
{
struct kgsl_pwrctrl *pwr = &device->pwrctrl;
int ret;
ret = gmu_core_dcvs_set(device, INVALID_DCVS_IDX, buslevel);
if (!ret)
icc_set_bw(pwr->icc_path, MBps_to_icc(ab), 0);
return ret;
}
/* Do not access any GMU registers in GMU probe function */
static int gmu_probe(struct kgsl_device *device, struct device_node *node)
{
@ -1409,6 +1423,9 @@ static int gmu_probe(struct kgsl_device *device, struct device_node *node)
gmu_acd_probe(device, gmu, node);
if (gmu_core_scales_bandwidth(device))
pwr->bus_set = gmu_bus_set;
set_bit(GMU_ENABLED, &device->gmu_core.flags);
device->gmu_core.dev_ops = &adreno_a6xx_gmudev;