Skip to content
86 changes: 64 additions & 22 deletions Documentation/devicetree/bindings/display/msm/gpu.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -45,11 +45,11 @@ properties:
- const: amd,imageon

clocks:
minItems: 2
minItems: 1
maxItems: 7

clock-names:
minItems: 2
minItems: 1
maxItems: 7

reg:
Expand Down Expand Up @@ -387,26 +387,68 @@ allOf:
required:
- clocks
- clock-names
else:
if:
properties:
compatible:
contains:
oneOf:
- pattern: '^qcom,adreno-[67][0-9][0-9]\.[0-9]+$'
- pattern: '^qcom,adreno-[0-9a-f]{8}$'

then: # Starting with A6xx, the clocks are usually defined in the GMU node
properties:
clocks: false
clock-names: false

reg-names:
minItems: 1
items:
- const: kgsl_3d0_reg_memory
- const: cx_mem
- const: cx_dbgc

- if:
properties:
compatible:
contains:
const: qcom,adreno-612.0
then:
properties:
clocks:
items:
- description: GPU Core clock

clock-names:
items:
- const: core

reg-names:
minItems: 1
items:
- const: kgsl_3d0_reg_memory
- const: cx_mem
- const: cx_dbgc

required:
- clocks
- clock-names

- if:
properties:
compatible:
contains:
enum:
- qcom,adreno-615.0
- qcom,adreno-618.0
- qcom,adreno-619.0
- qcom,adreno-621.0
- qcom,adreno-623.0
- qcom,adreno-630.2
- qcom,adreno-635.0
- qcom,adreno-640.1
- qcom,adreno-650.2
- qcom,adreno-660.1
- qcom,adreno-663.0
- qcom,adreno-680.1
- qcom,adreno-690.0
- qcom,adreno-730.1
- qcom,adreno-43030c00
- qcom,adreno-43050a01
- qcom,adreno-43050c01
- qcom,adreno-43051401

then: # Starting with A6xx, the clocks are usually defined in the GMU node
properties:
clocks: false
clock-names: false

reg-names:
minItems: 1
items:
- const: kgsl_3d0_reg_memory
- const: cx_mem
- const: cx_dbgc

examples:
- |
Expand Down
126 changes: 126 additions & 0 deletions Documentation/devicetree/bindings/display/msm/qcom,adreno-rgmu.yaml
Original file line number Diff line number Diff line change
@@ -0,0 +1,126 @@
# SPDX-License-Identifier: GPL-2.0-only OR BSD-2-Clause
# Copyright (c) Qualcomm Technologies, Inc. and/or its subsidiaries.
%YAML 1.2
---

$id: http://devicetree.org/schemas/display/msm/qcom,adreno-rgmu.yaml#
$schema: http://devicetree.org/meta-schemas/core.yaml#

title: RGMU attached to certain Adreno GPUs

maintainers:
- Rob Clark <robin.clark@oss.qualcomm.com>

description:
RGMU (Reduced Graphics Management Unit) IP is present in some GPUs that
belong to Adreno A6xx family. It is a small state machine that helps to
toggle the GX GDSC (connected to CX rail) to implement IFPC feature and save
power.

properties:
compatible:
items:
- const: qcom,adreno-rgmu-612.0
- const: qcom,adreno-rgmu

reg:
items:
- description: Core RGMU registers

clocks:
items:
- description: GMU clock
- description: GPU CX clock
- description: GPU AXI clock
- description: GPU MEMNOC clock
- description: GPU SMMU vote clock

clock-names:
items:
- const: gmu
- const: cxo
- const: axi
- const: memnoc
- const: smmu_vote

power-domains:
items:
- description: CX GDSC power domain
- description: GX GDSC power domain

power-domain-names:
items:
- const: cx
- const: gx

interrupts:
items:
- description: GMU OOB interrupt
- description: GMU interrupt

interrupt-names:
items:
- const: oob
- const: gmu

operating-points-v2: true
opp-table:
type: object

required:
- compatible
- reg
- clocks
- clock-names
- power-domains
- power-domain-names
- interrupts
- interrupt-names
- operating-points-v2

additionalProperties: false

examples:
- |
#include <dt-bindings/clock/qcom,qcs615-gpucc.h>
#include <dt-bindings/clock/qcom,qcs615-gcc.h>
#include <dt-bindings/interrupt-controller/arm-gic.h>
#include <dt-bindings/power/qcom,rpmhpd.h>

gmu@506a000 {
compatible = "qcom,adreno-rgmu-612.0", "qcom,adreno-rgmu";

reg = <0x05000000 0x90000>;

clocks = <&gpucc GPU_CC_CX_GMU_CLK>,
<&gpucc GPU_CC_CXO_CLK>,
<&gcc GCC_DDRSS_GPU_AXI_CLK>,
<&gcc GCC_GPU_MEMNOC_GFX_CLK>,
<&gpucc GPU_CC_HLOS1_VOTE_GPU_SMMU_CLK>;
clock-names = "gmu",
"cxo",
"axi",
"memnoc",
"smmu_vote";

power-domains = <&gpucc CX_GDSC>,
<&gpucc GX_GDSC>;
power-domain-names = "cx",
"gx";

interrupts = <GIC_SPI 304 IRQ_TYPE_LEVEL_HIGH>,
<GIC_SPI 305 IRQ_TYPE_LEVEL_HIGH>;
interrupt-names = "oob",
"gmu";

operating-points-v2 = <&gmu_opp_table>;

gmu_opp_table: opp-table {
compatible = "operating-points-v2";

opp-200000000 {
opp-hz = /bits/ 64 <200000000>;
required-opps = <&rpmhpd_opp_low_svs>;
};
};
};
1 change: 1 addition & 0 deletions MAINTAINERS
Original file line number Diff line number Diff line change
Expand Up @@ -7982,6 +7982,7 @@ S: Maintained
B: https://gitlab.freedesktop.org/drm/msm/-/issues
T: git https://gitlab.freedesktop.org/drm/msm.git
F: Documentation/devicetree/bindings/display/msm/gpu.yaml
F: Documentation/devicetree/bindings/display/msm/qcom,adreno-rgmu.yaml
F: Documentation/devicetree/bindings/opp/opp-v2-qcom-adreno.yaml
F: drivers/gpu/drm/msm/adreno/
F: drivers/gpu/drm/msm/msm_gpu.*
Expand Down
5 changes: 1 addition & 4 deletions drivers/gpu/drm/msm/adreno/a6xx_catalog.c
Original file line number Diff line number Diff line change
Expand Up @@ -501,8 +501,6 @@ static const struct adreno_reglist a690_hwcg[] = {
{REG_A6XX_RBBM_CLOCK_CNTL_GMU_GX, 0x00000222},
{REG_A6XX_RBBM_CLOCK_DELAY_GMU_GX, 0x00000111},
{REG_A6XX_RBBM_CLOCK_HYST_GMU_GX, 0x00000555},
{REG_A6XX_GPU_GMU_AO_GMU_CGC_DELAY_CNTL, 0x10111},
{REG_A6XX_GPU_GMU_AO_GMU_CGC_HYST_CNTL, 0x5555},
{}
};

Expand Down Expand Up @@ -1750,7 +1748,7 @@ static const u32 x285_protect_regs[] = {
A6XX_PROTECT_NORDWR(0x27c06, 0x0000),
};

DECLARE_ADRENO_PROTECT(x285_protect, 64);
DECLARE_ADRENO_PROTECT(x285_protect, 15);

static const struct adreno_reglist_pipe a840_nonctxt_regs[] = {
{ REG_A8XX_CP_SMMU_STREAM_ID_LPAC, 0x00000101, BIT(PIPE_NONE) },
Expand Down Expand Up @@ -1957,5 +1955,4 @@ static inline __always_unused void __build_asserts(void)
BUILD_BUG_ON(a660_protect.count > a660_protect.count_max);
BUILD_BUG_ON(a690_protect.count > a690_protect.count_max);
BUILD_BUG_ON(a730_protect.count > a730_protect.count_max);
BUILD_BUG_ON(a840_protect.count > a840_protect.count_max);
}
14 changes: 6 additions & 8 deletions drivers/gpu/drm/msm/adreno/a6xx_gmu.c
Original file line number Diff line number Diff line change
Expand Up @@ -2029,21 +2029,19 @@ static int cxpd_notifier_cb(struct notifier_block *nb,
return 0;
}

static void __iomem *a6xx_gmu_get_mmio(struct platform_device *pdev,
const char *name, resource_size_t *start)
static void __iomem *a6xx_gmu_get_mmio(struct platform_device *pdev, resource_size_t *start)
{
struct resource *res = platform_get_resource(pdev, IORESOURCE_MEM, 0);
void __iomem *ret;
struct resource *res = platform_get_resource_byname(pdev,
IORESOURCE_MEM, name);

if (!res) {
DRM_DEV_ERROR(&pdev->dev, "Unable to find the %s registers\n", name);
DRM_DEV_ERROR(&pdev->dev, "Unable to find the gmu core registers\n");
return ERR_PTR(-EINVAL);
}

ret = ioremap(res->start, resource_size(res));
if (!ret) {
DRM_DEV_ERROR(&pdev->dev, "Unable to map the %s registers\n", name);
DRM_DEV_ERROR(&pdev->dev, "Unable to map the gmu core registers\n");
return ERR_PTR(-EINVAL);
}

Expand Down Expand Up @@ -2085,7 +2083,7 @@ int a6xx_gmu_wrapper_init(struct a6xx_gpu *a6xx_gpu, struct device_node *node)
gmu->nr_clocks = ret;

/* Map the GMU registers */
gmu->mmio = a6xx_gmu_get_mmio(pdev, "gmu", &start);
gmu->mmio = a6xx_gmu_get_mmio(pdev, &start);
if (IS_ERR(gmu->mmio)) {
ret = PTR_ERR(gmu->mmio);
goto err_mmio;
Expand Down Expand Up @@ -2244,7 +2242,7 @@ int a6xx_gmu_init(struct a6xx_gpu *a6xx_gpu, struct device_node *node)
goto err_memory;

/* Map the GMU registers */
gmu->mmio = a6xx_gmu_get_mmio(pdev, "gmu", &start);
gmu->mmio = a6xx_gmu_get_mmio(pdev, &start);
if (IS_ERR(gmu->mmio)) {
ret = PTR_ERR(gmu->mmio);
goto err_memory;
Expand Down
18 changes: 10 additions & 8 deletions drivers/gpu/drm/msm/adreno/a6xx_gpu.c
Original file line number Diff line number Diff line change
Expand Up @@ -873,15 +873,17 @@ static void a7xx_patch_pwrup_reglist(struct msm_gpu *gpu)
lock->gpu_req = lock->cpu_req = lock->turn = 0;

reglist = adreno_gpu->info->a6xx->ifpc_reglist;
lock->ifpc_list_len = reglist->count;
if (reglist) {
lock->ifpc_list_len = reglist->count;

/*
* For each entry in each of the lists, write the offset and the current
* register value into the GPU buffer
*/
for (i = 0; i < reglist->count; i++) {
*dest++ = reglist->regs[i];
*dest++ = gpu_read(gpu, reglist->regs[i]);
/*
* For each entry in each of the lists, write the offset and the current
* register value into the GPU buffer
*/
for (i = 0; i < reglist->count; i++) {
*dest++ = reglist->regs[i];
*dest++ = gpu_read(gpu, reglist->regs[i]);
}
}

reglist = adreno_gpu->info->a6xx->pwrup_reglist;
Expand Down
1 change: 1 addition & 0 deletions drivers/gpu/drm/msm/adreno/adreno_device.c
Original file line number Diff line number Diff line change
Expand Up @@ -302,6 +302,7 @@ static const struct of_device_id dt_match[] = {
{ .compatible = "qcom,kgsl-3d0" },
{}
};
MODULE_DEVICE_TABLE(of, dt_match);

static int adreno_runtime_resume(struct device *dev)
{
Expand Down