mirror of
https://github.com/BobTheBlinker/android_kernel_motorola_sm6375.git
synced 2026-10-09 05:39:54 -04:00
msm: kgsl: Add target specific probe functions
Add support for target specific probe functions to give individual targets the flexibility to define their own device structs and do other target specific setup that doesn't belong in the generic init. To start all targets use a common helper probe function but that is expected to change soon. Change-Id: Ic0dedbad9e159be724368c7d2a496af151226cc0 Signed-off-by: Jordan Crouse <jcrouse@codeaurora.org>
This commit is contained in:
parent
bbc7f2d3ed
commit
c96f021616
5 changed files with 163 additions and 106 deletions
|
|
@ -691,26 +691,64 @@ adreno_get_soc_hw_revision_node(struct platform_device *pdev, u32 hwrev)
|
|||
return NULL;
|
||||
}
|
||||
|
||||
static u32 adreno_efuse_read_soc_hw_rev(struct platform_device *pdev)
|
||||
{
|
||||
unsigned int val;
|
||||
unsigned int soc_hw_rev[3];
|
||||
int ret;
|
||||
|
||||
if (of_property_read_u32_array(pdev->dev.of_node,
|
||||
"qcom,soc-hw-rev-efuse", soc_hw_rev, 3))
|
||||
return 0;
|
||||
|
||||
ret = adreno_efuse_map(pdev);
|
||||
if (ret) {
|
||||
dev_err(&pdev->dev,
|
||||
"Unable to map hardware revision fuse: ret=%d\n", ret);
|
||||
return 0;
|
||||
}
|
||||
|
||||
ret = adreno_efuse_read_u32(soc_hw_rev[0], &val);
|
||||
adreno_efuse_unmap();
|
||||
|
||||
if (ret) {
|
||||
dev_err(&pdev->dev,
|
||||
"Unable to read hardware revision fuse: ret=%d\n", ret);
|
||||
return 0;
|
||||
}
|
||||
|
||||
return (val >> soc_hw_rev[1]) & soc_hw_rev[2];
|
||||
}
|
||||
|
||||
static int adreno_get_chipid(struct platform_device *pdev, u32 *chipid)
|
||||
{
|
||||
u32 hwrev = adreno_efuse_read_soc_hw_rev(pdev);
|
||||
struct device_node *node;
|
||||
int ret;
|
||||
|
||||
node = adreno_get_soc_hw_revision_node(pdev, hwrev);
|
||||
if (!node)
|
||||
node = of_node_get(pdev->dev.of_node);
|
||||
|
||||
ret = of_property_read_u32(node, "qcom,chipid", chipid);
|
||||
|
||||
of_node_put(node);
|
||||
return ret;
|
||||
}
|
||||
|
||||
static void
|
||||
adreno_update_soc_hw_revision_quirks(struct adreno_device *adreno_dev,
|
||||
struct platform_device *pdev, u32 hwrev)
|
||||
struct platform_device *pdev)
|
||||
{
|
||||
struct device_node *node;
|
||||
int i;
|
||||
u32 hwrev;
|
||||
|
||||
hwrev = adreno_efuse_read_soc_hw_rev(pdev);
|
||||
|
||||
node = adreno_get_soc_hw_revision_node(pdev, hwrev);
|
||||
if (node == NULL)
|
||||
node = pdev->dev.of_node;
|
||||
|
||||
/* get chip id, fall back to parent if revision node does not have it */
|
||||
if (of_property_read_u32(node, "qcom,chipid", &adreno_dev->chipid)) {
|
||||
if (of_property_read_u32(pdev->dev.of_node,
|
||||
"qcom,chipid", &adreno_dev->chipid)) {
|
||||
dev_crit(&pdev->dev, "No GPU chip ID was specified\n");
|
||||
BUG();
|
||||
return;
|
||||
}
|
||||
}
|
||||
node = of_node_get(pdev->dev.of_node);
|
||||
|
||||
/* update quirk */
|
||||
for (i = 0; i < ARRAY_SIZE(adreno_quirks); i++) {
|
||||
|
|
@ -723,55 +761,40 @@ adreno_update_soc_hw_revision_quirks(struct adreno_device *adreno_dev,
|
|||
kgsl_mmu_set_feature(KGSL_DEVICE(adreno_dev),
|
||||
KGSL_MMU_SECURE_CB_ALT);
|
||||
|
||||
|
||||
if (node != pdev->dev.of_node)
|
||||
of_node_put(node);
|
||||
of_node_put(node);
|
||||
}
|
||||
|
||||
static int adreno_identify_gpu(struct platform_device *pdev,
|
||||
struct adreno_device *adreno_dev)
|
||||
static const struct adreno_gpu_core *
|
||||
adreno_identify_gpu(struct platform_device *pdev, u32 *chipid)
|
||||
{
|
||||
struct adreno_gpudev *gpudev;
|
||||
int i;
|
||||
const struct adreno_gpu_core *gpucore;
|
||||
|
||||
adreno_dev->gpucore = _get_gpu_core(pdev, adreno_dev->chipid);
|
||||
if (adreno_get_chipid(pdev, chipid)) {
|
||||
dev_crit(&pdev->dev, "Unable to get the GPU chip ID\n");
|
||||
return ERR_PTR(-ENODEV);
|
||||
}
|
||||
|
||||
if (adreno_dev->gpucore == NULL) {
|
||||
dev_crit(&pdev->dev,
|
||||
"Unknown GPU chip ID %8.8X\n", adreno_dev->chipid);
|
||||
return -ENODEV;
|
||||
gpucore = _get_gpu_core(pdev, *chipid);
|
||||
if (!gpucore) {
|
||||
dev_crit(&pdev->dev, "Unknown GPU chip ID %8.8x\n", *chipid);
|
||||
return ERR_PTR(-ENODEV);
|
||||
}
|
||||
|
||||
/*
|
||||
* Identify non-longer supported targets and spins and print a helpful
|
||||
* message
|
||||
*/
|
||||
if (adreno_dev->gpucore->features & ADRENO_DEPRECATED) {
|
||||
if (gpucore->features & ADRENO_DEPRECATED) {
|
||||
dev_err(&pdev->dev,
|
||||
"Support for GPU %d.%d.%d.%d has been deprecated\n",
|
||||
adreno_dev->gpucore->core,
|
||||
adreno_dev->gpucore->major,
|
||||
adreno_dev->gpucore->minor,
|
||||
adreno_dev->gpucore->patchid);
|
||||
return -ENODEV;
|
||||
gpucore->core,
|
||||
gpucore->major,
|
||||
gpucore->minor,
|
||||
gpucore->patchid);
|
||||
return ERR_PTR(-ENODEV);
|
||||
}
|
||||
|
||||
gpudev = ADRENO_GPU_DEVICE(adreno_dev);
|
||||
|
||||
/*
|
||||
* Initialize uninitialzed gpu registers, only needs to be done once
|
||||
* Make all offsets that are not initialized to ADRENO_REG_UNUSED
|
||||
*/
|
||||
for (i = 0; i < ADRENO_REG_REGISTER_MAX; i++) {
|
||||
if (!gpudev->reg_offsets[i])
|
||||
gpudev->reg_offsets[i] = ADRENO_REG_UNUSED;
|
||||
}
|
||||
|
||||
/* Do target specific identification */
|
||||
if (gpudev->platform_setup != NULL)
|
||||
gpudev->platform_setup(adreno_dev);
|
||||
|
||||
return 0;
|
||||
return gpucore;
|
||||
}
|
||||
|
||||
static const struct of_device_id adreno_match_table[] = {
|
||||
|
|
@ -1132,50 +1155,20 @@ static void adreno_isense_probe(struct kgsl_device *device)
|
|||
dev_warn(device->dev, "isense ioremap failed\n");
|
||||
}
|
||||
|
||||
static u32 adreno_efuse_read_soc_hw_rev(struct platform_device *pdev)
|
||||
{
|
||||
unsigned int val;
|
||||
unsigned int soc_hw_rev[3];
|
||||
int ret;
|
||||
|
||||
if (of_property_read_u32_array(pdev->dev.of_node,
|
||||
"qcom,soc-hw-rev-efuse", soc_hw_rev, 3))
|
||||
return 0;
|
||||
|
||||
ret = adreno_efuse_map(pdev);
|
||||
if (ret) {
|
||||
dev_err(&pdev->dev,
|
||||
"Unable to map hardware revision fuse: ret=%d\n", ret);
|
||||
return 0;
|
||||
}
|
||||
|
||||
ret = adreno_efuse_read_u32(soc_hw_rev[0], &val);
|
||||
adreno_efuse_unmap();
|
||||
|
||||
if (ret) {
|
||||
dev_err(&pdev->dev,
|
||||
"Unable to read hardware revision fuse: ret=%d\n", ret);
|
||||
return 0;
|
||||
}
|
||||
|
||||
return (val >> soc_hw_rev[1]) & soc_hw_rev[2];
|
||||
}
|
||||
|
||||
static bool adreno_is_gpu_disabled(struct adreno_device *adreno_dev)
|
||||
static bool adreno_is_gpu_disabled(struct platform_device *pdev)
|
||||
{
|
||||
unsigned int row0;
|
||||
unsigned int pte_row0_msb[3];
|
||||
int ret;
|
||||
struct kgsl_device *device = KGSL_DEVICE(adreno_dev);
|
||||
|
||||
if (of_property_read_u32_array(device->pdev->dev.of_node,
|
||||
if (of_property_read_u32_array(pdev->dev.of_node,
|
||||
"qcom,gpu-disable-fuse", pte_row0_msb, 3))
|
||||
return false;
|
||||
/*
|
||||
* Read the fuse value to disable GPU driver if fuse
|
||||
* is blown. By default(fuse value is 0) GPU is enabled.
|
||||
*/
|
||||
if (adreno_efuse_map(device->pdev))
|
||||
if (adreno_efuse_map(pdev))
|
||||
return false;
|
||||
|
||||
ret = adreno_efuse_read_u32(pte_row0_msb[0], &row0);
|
||||
|
|
@ -1278,8 +1271,6 @@ static void adreno_setup_device(struct adreno_device *adreno_dev)
|
|||
{
|
||||
u32 i;
|
||||
|
||||
memset(adreno_dev, 0, sizeof(*adreno_dev));
|
||||
|
||||
adreno_dev->dev.name = "kgsl-3d0";
|
||||
adreno_dev->dev.ftbl = &adreno_functable;
|
||||
|
||||
|
|
@ -1310,35 +1301,23 @@ static void adreno_setup_device(struct adreno_device *adreno_dev)
|
|||
}
|
||||
}
|
||||
|
||||
static int adreno_bind(struct device *dev)
|
||||
int adreno_device_probe(struct platform_device *pdev,
|
||||
struct adreno_device *adreno_dev)
|
||||
{
|
||||
struct platform_device *pdev = to_platform_device(dev);
|
||||
struct adreno_device *adreno_dev;
|
||||
struct kgsl_device *device;
|
||||
int status;
|
||||
struct kgsl_device *device = KGSL_DEVICE(adreno_dev);
|
||||
struct device *dev = &pdev->dev;
|
||||
unsigned int priv = 0;
|
||||
u32 size, hwrev;
|
||||
|
||||
adreno_dev = (struct adreno_device *) of_device_get_match_data(dev);
|
||||
int status;
|
||||
u32 size;
|
||||
|
||||
/* Initialize the adreno device structure */
|
||||
adreno_setup_device(adreno_dev);
|
||||
|
||||
device = KGSL_DEVICE(adreno_dev);
|
||||
|
||||
dev_set_drvdata(dev, device);
|
||||
|
||||
device->pdev = pdev;
|
||||
|
||||
if (adreno_is_gpu_disabled(adreno_dev)) {
|
||||
dev_err(&pdev->dev, "adreno: GPU is disabled on this device\n");
|
||||
return -ENODEV;
|
||||
}
|
||||
|
||||
/* Identify SOC hardware revision to be used */
|
||||
hwrev = adreno_efuse_read_soc_hw_rev(pdev);
|
||||
|
||||
adreno_update_soc_hw_revision_quirks(adreno_dev, pdev, hwrev);
|
||||
adreno_update_soc_hw_revision_quirks(adreno_dev, pdev);
|
||||
|
||||
status = adreno_read_speed_bin(pdev);
|
||||
if (status < 0)
|
||||
|
|
@ -1346,10 +1325,6 @@ static int adreno_bind(struct device *dev)
|
|||
|
||||
device->speed_bin = status;
|
||||
|
||||
/* Get the chip ID from the DT and set up target specific parameters */
|
||||
if (adreno_identify_gpu(pdev, adreno_dev))
|
||||
return -ENODEV;
|
||||
|
||||
status = adreno_of_get_power(adreno_dev, pdev);
|
||||
if (status)
|
||||
return status;
|
||||
|
|
@ -1478,6 +1453,52 @@ err:
|
|||
return status;
|
||||
}
|
||||
|
||||
int adreno_target_probe(struct platform_device *pdev,
|
||||
u32 chipid, const struct adreno_gpu_core *gpucore)
|
||||
{
|
||||
struct adreno_device *adreno_dev = &device_3d0;
|
||||
struct adreno_gpudev *gpudev = gpucore->gpudev;
|
||||
int i;
|
||||
|
||||
memset(adreno_dev, 0, sizeof(*adreno_dev));
|
||||
|
||||
adreno_dev->gpucore = gpucore;
|
||||
adreno_dev->chipid = chipid;
|
||||
|
||||
/*
|
||||
* Initialize uninitialzed gpu registers, only needs to be done once
|
||||
* Make all offsets that are not initialized to ADRENO_REG_UNUSED
|
||||
*/
|
||||
for (i = 0; i < ADRENO_REG_REGISTER_MAX; i++) {
|
||||
if (!gpudev->reg_offsets[i])
|
||||
gpudev->reg_offsets[i] = ADRENO_REG_UNUSED;
|
||||
}
|
||||
|
||||
/* Do target specific identification */
|
||||
if (gpudev->platform_setup)
|
||||
gpudev->platform_setup(adreno_dev);
|
||||
|
||||
return adreno_device_probe(pdev, adreno_dev);
|
||||
}
|
||||
|
||||
static int adreno_bind(struct device *dev)
|
||||
{
|
||||
struct platform_device *pdev = to_platform_device(dev);
|
||||
const struct adreno_gpu_core *gpucore;
|
||||
u32 chipid;
|
||||
|
||||
if (adreno_is_gpu_disabled(pdev)) {
|
||||
dev_err(&pdev->dev, "adreno: GPU is disabled on this device\n");
|
||||
return -ENODEV;
|
||||
}
|
||||
|
||||
gpucore = adreno_identify_gpu(pdev, &chipid);
|
||||
if (IS_ERR(gpucore))
|
||||
return PTR_ERR(gpucore);
|
||||
|
||||
return gpucore->gpudev->probe(pdev, chipid, gpucore);
|
||||
}
|
||||
|
||||
static void _adreno_free_memories(struct adreno_device *adreno_dev)
|
||||
{
|
||||
struct adreno_firmware *pfp_fw = ADRENO_FW(adreno_dev, ADRENO_FW_PFP);
|
||||
|
|
@ -1500,9 +1521,11 @@ static void adreno_unbind(struct device *dev)
|
|||
struct kgsl_device *device;
|
||||
struct adreno_gpudev *gpudev;
|
||||
|
||||
adreno_dev = (struct adreno_device *) of_device_get_match_data(dev);
|
||||
device = dev_get_drvdata(dev);
|
||||
if (!device)
|
||||
return;
|
||||
|
||||
device = KGSL_DEVICE(adreno_dev);
|
||||
adreno_dev = ADRENO_DEVICE(device);
|
||||
gpudev = ADRENO_GPU_DEVICE(adreno_dev);
|
||||
|
||||
if (gpudev->remove != NULL)
|
||||
|
|
|
|||
|
|
@ -746,6 +746,8 @@ struct adreno_gpudev {
|
|||
unsigned int gbif_arb_halt_mask;
|
||||
unsigned int gbif_gx_halt_mask;
|
||||
/* GPU specific function hooks */
|
||||
int (*probe)(struct platform_device *pdev, u32 chipid,
|
||||
const struct adreno_gpu_core *gpucore);
|
||||
void (*snapshot)(struct adreno_device *adreno_dev,
|
||||
struct kgsl_snapshot *snapshot);
|
||||
void (*platform_setup)(struct adreno_device *adreno_dev);
|
||||
|
|
@ -1706,4 +1708,33 @@ int adreno_zap_shader_load(struct adreno_device *adreno_dev,
|
|||
irqreturn_t adreno_irq_callbacks(struct adreno_device *adreno_dev,
|
||||
struct adreno_irq_funcs *funcs, u32 status);
|
||||
|
||||
|
||||
/**
|
||||
* adreno_device_probe - Generic adreno device probe function
|
||||
* @pdev: Pointer to the platform device
|
||||
* @adreno_dev: Adreno GPU device handle
|
||||
*
|
||||
* Do the generic setup for the Adreno device. Called from the target specific
|
||||
* probe functions.
|
||||
*
|
||||
* Return: 0 on success or negative on failure
|
||||
*/
|
||||
int adreno_device_probe(struct platform_device *pdev,
|
||||
struct adreno_device *adreno_dev);
|
||||
|
||||
/**
|
||||
* adreno_target_probe - Helper function for target specific probe
|
||||
* @pdev: Pointer to the platform device
|
||||
* @chipid: Chipid for the target
|
||||
* @gpucore: Pointer to the GPU core definition for this target
|
||||
*
|
||||
* This is a generic probe function for targets that don't need any special
|
||||
* setup. This function sets up the reg_offsets and platform setup and then
|
||||
* calls the generic device probe.
|
||||
*
|
||||
* Return: 0 on success or negative on failure
|
||||
*/
|
||||
int adreno_target_probe(struct platform_device *pdev,
|
||||
u32 chipid, const struct adreno_gpu_core *gpucore);
|
||||
|
||||
#endif /*__ADRENO_H */
|
||||
|
|
|
|||
|
|
@ -1406,6 +1406,7 @@ struct adreno_gpudev adreno_a3xx_gpudev = {
|
|||
.perfcounters = &a3xx_perfcounters,
|
||||
.irq_handler = a3xx_irq_handler,
|
||||
.vbif_xin_halt_ctrl0_mask = A30X_VBIF_XIN_HALT_CTRL0_MASK,
|
||||
.probe = adreno_target_probe,
|
||||
.platform_setup = a3xx_platform_setup,
|
||||
.rb_start = a3xx_rb_start,
|
||||
.init = a3xx_init,
|
||||
|
|
|
|||
|
|
@ -2970,6 +2970,7 @@ struct adreno_gpudev adreno_a5xx_gpudev = {
|
|||
#ifdef CONFIG_QCOM_KGSL_CORESIGHT
|
||||
.coresight = {&a5xx_coresight},
|
||||
#endif
|
||||
.probe = adreno_target_probe,
|
||||
.start = a5xx_start,
|
||||
.snapshot = a5xx_snapshot,
|
||||
.platform_setup = a5xx_platform_setup,
|
||||
|
|
|
|||
|
|
@ -2635,6 +2635,7 @@ u64 a6xx_read_alwayson(struct adreno_device *adreno_dev)
|
|||
|
||||
struct adreno_gpudev adreno_a6xx_gpudev = {
|
||||
.reg_offsets = a6xx_register_offsets,
|
||||
.probe = adreno_target_probe,
|
||||
.start = a6xx_start,
|
||||
.snapshot = a6xx_snapshot,
|
||||
.platform_setup = a6xx_platform_setup,
|
||||
|
|
|
|||
Loading…
Reference in a new issue