Merge commit '66cc998fcfe01db4376f8706b6dc5825030cd372'

* commit '66cc998fcfe01db4376f8706b6dc5825030cd372': (49 commits)
  drm/rockchip: vop2: Fix vcstate for splice vp
  MALI: bifrost: Optimize gpu mem sysfs entry
  arm64: configs: vehicle.config: enable vehicle driver default
  input: touchscreen: gt1x: return error when initialization fails
  Mali: valhall: from ARM: Fix UAF issue of user IO pages after group fatal error
  MALI: valhall: upgrade DDK to g29p0-00eac0, from g28p0-00eac0
  arm64: dts: rockchip: rv1126b-evb2: Add explicit data-map-mode for RGB output
  arm64: dts: rockchip: rv1126bp-evb: Make rgb output compatible with RV1126
  dt-bindings: display: Add rockchip MCU/BT1120/BT656 data map
  drm/rockchip: vop: Add support for set data map mode for RV1126B
  drm/rockchip: rgb: Add support for set data map mode
  arm64: dts: rockchip: rv1126bp-evb: Include rv1126bp dtsi
  arm64: dts: rockchip: Add rv1126bp dtsi
  misc: vehicle: add vehicle drivers with protobuf for vhal
  arm64: dts: rockchip: rv1126b: Fix clk_aisp_pll_src init freq
  clk: rockchip: rv1126b: fix clk_cpll_div10 parent clk
  arm64: dts: rockchip: rk3588/rk3576/rk3568-evb: delay init-delay-ms before panel initail code send
  media: rockchip: vicap: support reserved mem attach dma_buf with iommu
  arm64: dts: rockchip: Add rk3576 toybrick SD0 board
  ARM: configs: rv1126b-rndis support rndis config
  ...

Change-Id: I0c3edf16775441868613d3cd6f7db2fb015f8fd4
This commit is contained in:
Tao Huang
2025-06-18 17:31:26 +08:00
306 changed files with 16650 additions and 37163 deletions

View File

@@ -1,15 +1,21 @@
// SPDX-License-Identifier: GPL-2.0 WITH Linux-syscall-note
/*
*
* (C) COPYRIGHT 2023 ARM Limited. All rights reserved.
* (C) COPYRIGHT 2017-2024 ARM Limited. All rights reserved.
*
* This program is free software and is provided to you under the terms of the
* GNU General Public License version 2 as published by the Free Software
* Foundation) and any use by you of this program is subject to the terms
* of such GNU licence.
* Foundation, and any use by you of this program is subject to the terms
* of such GNU license.
*
* A copy of the licence is included with the program) and can also be obtained
* from Free Software Foundation) Inc.) 51 Franklin Street) Fifth Floor)
* Boston) MA 02110-1301) USA.
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program; if not, you can access it online at
* http://www.gnu.org/licenses/gpl-2.0.html.
*
*/
@@ -34,16 +40,6 @@ Description:
driver, On reading it provides the current DVFS sampling period,
on writing a value we set the DVFS sampling period.
What: /sys/class/misc/mali%u/device/dummy_job_wa_info
Description:
This attribute is available only with platform device that
supports a Job Manager based GPU that requires a GPU workaround
to execute the dummy fragment job on all shader cores to
workaround a hang issue.
Its a readonly attribute and on reading gives details on the
options used with the dummy workaround.
What: /sys/class/misc/mali%u/device/fw_timeout
Description:
This attribute is available only with mali platform
@@ -78,111 +74,6 @@ Description:
is supported or is powered down after suspending command
stream groups.
What: /sys/class/misc/mali%u/device/js_ctx_scheduling_mode
Description:
This attribute is available only with platform device that
supports a Job Manager based GPU. This attribute is used to set
context scheduling priority for a job slot.
On Reading it provides the currently set job slot context
priority.
Writing 0 to this attribute sets it to the mode were
higher priority atoms will be scheduled first, regardless of
the context they belong to. Newly-runnable higher priority atoms
can preempt lower priority atoms currently running on the GPU,
even if they belong to a different context.
Writing 1 to this attribute set it to the mode were the
highest-priority atom will be chosen from each context in turn
using a round-robin algorithm, so priority only has an effect
within the context an atom belongs to. Newly-runnable higher
priority atoms can preempt the lower priority atoms currently
running on the GPU, but only if they belong to the same context.
What: /sys/class/misc/mali%u/device/js_scheduling_period
Description:
This attribute is available only with platform device that
supports a Job Manager based GPU. Used to set the job scheduler
tick period in nano-seconds. The Job Scheduler determines the
jobs that are run on the GPU, and for how long, Job Scheduler
makes decisions at a regular time interval determined by value
in js_scheduling_period.
What: /sys/class/misc/mali%u/device/js_softstop_always
Description:
This attribute is available only with platform device that
supports a Job Manager based GPU. Soft-stops are disabled when
only a single context is present, this attribute is used to
enable soft-stop when only a single context is present can be
used for debug and unit-testing purposes.
What: /sys/class/misc/mali%u/device/js_timeouts
Description:
This attribute is available only with platform device that
supports a Job Manager based GPU. It used to set the soft stop
and hard stop times for the job scheduler.
Writing value 0 causes no change, or -1 to restore the
default timeout.
The format used to set js_timeouts is
"<soft_stop_ms> <soft_stop_ms_cl> <hard_stop_ms_ss>
<hard_stop_ms_cl> <hard_stop_ms_dumping> <reset_ms_ss>
<reset_ms_cl> <reset_ms_dumping>"
What: /sys/class/misc/mali%u/device/lp_mem_pool_max_size
Description:
This attribute is used to set the maximum number of large pages
memory pools that the driver can contain. Large pages are of
size 2MB. On read it displays all the max size of all memory
pools and can be used to modify each individual pools as well.
What: /sys/class/misc/mali%u/device/lp_mem_pool_size
Description:
This attribute is used to set the number of large memory pages
which should be populated, changing this value may cause
existing pages to be removed from the pool, or new pages to be
created and then added to the pool. On read it will provide
pool size for all available pools and we can modify individual
pool.
What: /sys/class/misc/mali%u/device/mem_pool_max_size
Description:
This attribute is used to set the maximum number of small pages
for memory pools that the driver can contain. Here small pages
are of size 4KB. On read it will display the max size for all
available pools and allows us to set max size of
individual pools.
What: /sys/class/misc/mali%u/device/mem_pool_size
Description:
This attribute is used to set the number of small memory pages
which should be populated, changing this value may cause
existing pages to be removed from the pool, or new pages to
be created and then added to the pool. On read it will provide
pool size for all available pools and we can modify individual
pool.
What: /sys/class/misc/mali%u/device/device/mempool/ctx_default_max_size
Description:
This attribute is used to set maximum memory pool size for
all the memory pool so that the maximum amount of free memory
that each pool can hold is identical.
What: /sys/class/misc/mali%u/device/device/mempool/lp_max_size
Description:
This attribute is used to set the maximum number of large pages
for all memory pools that the driver can contain.
Large pages are of size 2MB.
What: /sys/class/misc/mali%u/device/device/mempool/max_size
Description:
This attribute is used to set the maximum number of small pages
for all the memory pools that the driver can contain.
Here small pages are of size 4KB.
What: /sys/class/misc/mali%u/device/pm_poweroff
Description:
This attribute contains the current values, represented as the

View File

@@ -1,15 +1,21 @@
// SPDX-License-Identifier: GPL-2.0 WITH Linux-syscall-note
/*
*
* (C) COPYRIGHT 2023 ARM Limited. All rights reserved.
* (C) COPYRIGHT 2017-2024 ARM Limited. All rights reserved.
*
* This program is free software and is provided to you under the terms of the
* GNU General Public License version 2 as published by the Free Software
* Foundation) and any use by you of this program is subject to the terms
* of such GNU licence.
* Foundation, and any use by you of this program is subject to the terms
* of such GNU license.
*
* A copy of the licence is included with the program) and can also be obtained
* from Free Software Foundation) Inc.) 51 Franklin Street) Fifth Floor)
* Boston) MA 02110-1301) USA.
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program; if not, you can access it online at
* http://www.gnu.org/licenses/gpl-2.0.html.
*
*/

View File

@@ -0,0 +1,257 @@
# SPDX-License-Identifier: GPL-2.0 WITH Linux-syscall-note
#
# (C) COPYRIGHT 2013-2024 ARM Limited. All rights reserved.
#
# This program is free software and is provided to you under the terms of the
# GNU General Public License version 2 as published by the Free Software
# Foundation, and any use by you of this program is subject to the terms
# of such GNU license.
#
# This program is distributed in the hope that it will be useful,
# but WITHOUT ANY WARRANTY; without even the implied warranty of
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
# GNU General Public License for more details.
#
# You should have received a copy of the GNU General Public License
# along with this program; if not, you can access it online at
# http://www.gnu.org/licenses/gpl-2.0.html.
#
#
* ARM Mali Midgard / Bifrost devices
Required properties:
- compatible : Should be mali<chip>, replacing digits with x from the back,
until malit<Major>xx, and it must end with one of: "arm,malit6xx" or
"arm,mali-midgard" or "arm,mali-bifrost"
- reg : Physical base address of the device and length of the register area.
- interrupts : Contains the three IRQ lines required by T-6xx devices
- interrupt-names : Contains the names of IRQ resources in the order they were
provided in the interrupts property. Must contain: "JOB, "MMU", "GPU".
Optional:
- clocks : One or more pairs of phandle to clock and clock specifier
for the Mali device. The order is important: the first clock
shall correspond to the "clk_mali" source. Other clocks are optional
and, if present, they shall correspond to domains like "shadercores",
which is available for all GPUs, or "coregroup" and "neuralengines"
which are available for newer GPUs. Also notice that the "neuralengines"
clock domain, if present, doesn't expect a corresponding regulator.
- clock-names : Shall be set to values like: "clk_mali", "shadercores", "coregroup",
"neuralengines". Only the first one is mandatory. Most GPUs
support only the first two entries.
- mali-supply : Phandle to the top level regulator for the Mali device.
Refer to
Documentation/devicetree/bindings/regulator/regulator.txt for details.
- mem-supply : Phandle to memory regulator for the Mali device. This is optional.
- operating-points-v2 : Refer to Documentation/devicetree/bindings/power/mali-opp.txt
for details.
- quirks-gpu : Used to write to the JM_CONFIG or CSF_CONFIG register.
Should be used with care. Options passed here are used to override
certain default behavior. Note: This will override 'idvs-group-size'
field in devicetree and module param 'corestack_driver_control',
therefore if 'quirks-gpu' is used then 'idvs-group-size' and
'corestack_driver_control' value should be incorporated into 'quirks-gpu'.
- quirks-sc : Used to write to the SHADER_CONFIG register.
Should be used with care. Options passed here are used to override
certain default behavior.
- quirks-tiler : Used to write to the TILER_CONFIG register.
Should be used with care. Options passed here are used to
disable or override certain default behavior.
- quirks-mmu : Used to write to the L2_CONFIG register.
Should be used with care. Options passed here are used to
disable or override certain default behavior.
- power-model : Sets the power model parameters. Defined power models include:
"mali-simple-power-model", "mali-g51-power-model", "mali-g52-power-model",
"mali-g52_r1-power-model", "mali-g71-power-model", "mali-g72-power-model",
"mali-g76-power-model", "mali-g77-power-model", "mali-tnax-power-model",
"mali-tbex-power-model" and "mali-tbax-power-model".
- mali-simple-power-model: this model derives the GPU power usage based
on the GPU voltage scaled by the system temperature. Note: it was
designed for the Juno platform, and may not be suitable for others.
- compatible: Should be "arm,mali-simple-power-model"
- dynamic-coefficient: Coefficient, in pW/(Hz V^2), which is
multiplied by v^2*f to calculate the dynamic power consumption.
- static-coefficient: Coefficient, in uW/V^3, which is
multiplied by v^3 to calculate the static power consumption.
- ts: An array containing coefficients for the temperature
scaling factor. This is used to scale the static power by a
factor of tsf/1000000,
where tsf = ts[3]*T^3 + ts[2]*T^2 + ts[1]*T + ts[0],
and T = temperature in degrees.
- thermal-zone: A string identifying the thermal zone used for
the GPU
- temp-poll-interval-ms: the interval at which the system
temperature is polled
- mali-g*-power-model(s): unless being stated otherwise, these models derive
the GPU power usage based on performance counters, so they are more
accurate.
- compatible: Should be, as examples, "arm,mali-g51-power-model" /
"arm,mali-g72-power-model".
- scale: the dynamic power calculated by the power model is
multiplied by a factor of 'scale'. This value should be
chosen to match a particular implementation.
- min_sample_cycles: Fall back to the simple power model if the
number of GPU cycles for a given counter dump is less than
'min_sample_cycles'. The default value of this should suffice.
* Note: when IPA is used, two separate power models (simple and counter-based)
are used at different points so care should be taken to configure
both power models in the device tree (specifically dynamic-coefficient,
static-coefficient and scale) to best match the platform.
- power-policy : Sets the GPU power policy at probe time. Available options are
"coarse_demand" and "always_on". If not set, then "coarse_demand" is used.
- system-coherency : Sets the coherency protocol to be used for coherent
accesses made from the GPU.
If not set then no coherency is used.
- 0 : ACE-Lite
- 1 : ACE
- 31 : No coherency
- ipa-model : Sets the IPA model to be used for power management. GPU probe will fail if the
model is not found in the registered models list. If no model is specified here,
a gpu-id based model is picked if available, otherwise the default model is used.
- mali-simple-power-model: Default model used on mali
- idvs-group-size : Override the IDVS group size value. Tasks are sent to
cores in groups of N + 1, so i.e. 0xF means 16 tasks.
Valid values are between 0 to 0x3F (including).
- l2-size : Override L2 cache size on GPU that supports it. Value should be larger than the minimum
size 1KiB and smaller than the maximum size. Maximum size is Hardware integration dependent.
The value passed should be of log2(Cache Size in Bytes).
For example for a 1KiB of cache size, 0xa should be passed.
- l2-hash : Override L2 hash function on GPU that supports it
- l2-hash-values : Override L2 hash function using provided hash values, on GPUs that supports it.
It is mutually exclusive with 'l2-hash'. Only one or the other must be
used in a supported GPU.
- arbiter-if : Phandle to the arbif platform device, used to provide KBASE with an interface
to the Arbiter. This is required when using arbitration; setting to a non-NULL
value will enable arbitration.
If arbitration is in use, then there should be no external GPU control.
When arbiter-if is in use then the following must not be:
- power-model (no IPA allowed with arbitration)
- #cooling-cells
- operating-points-v2 (no dvfs in kbase with arbitration)
- system-coherency with a value of 1 (no full coherency with arbitration)
- int-id-override: list of <ID Setting[7:0]> tuples defining the IDs needed to be
set and the setting coresponding to the SYSC_ALLOC register.
- propagate-bits: Used to write to L2_CONFIG.PBHA_HWU. This bitset establishes which
PBHA bits are propagated on the AXI bus.
- mma-wa-id: Sets a GPU MMU PBHA value to be used as NONCACHEABLE. GPU Page Table Entries
(PTEs) with this PBHA value set will have uncached transactions from the GPU.
Valid values are from 1 to 15. See mgm_update_gpu_pte() in
include/linux/memory_group_manager.h for the interface to configure the PTEs. Only
supported by arch 14.8.x and later GPUs.
Example for a Mali GPU with 1 clock and 1 regulator:
gpu@0xfc010000 {
compatible = "arm,malit602", "arm,malit60x", "arm,malit6xx", "arm,mali-midgard";
reg = <0xfc010000 0x4000>;
interrupts = <0 36 4>, <0 37 4>, <0 38 4>;
interrupt-names = "JOB", "MMU", "GPU";
clocks = <&pclk_mali>;
clock-names = "clk_mali";
mali-supply = <&vdd_mali>;
operating-points-v2 = <&gpu_opp_table>;
power_model@0 {
compatible = "arm,mali-simple-power-model";
static-coefficient = <2427750>;
dynamic-coefficient = <4687>;
ts = <20000 2000 (-20) 2>;
thermal-zone = "gpu";
};
power_model@1 {
compatible = "arm,mali-g71-power-model";
scale = <5>;
};
idvs-group-size = <0x7>;
l2-size = /bits/ 8 <0x10>;
l2-hash = /bits/ 8 <0x04>; /* or l2-hash-values = <0x12345678 0x8765 0xAB>; */
};
gpu_opp_table: opp_table0 {
compatible = "operating-points-v2";
opp@533000000 {
opp-hz = /bits/ 64 <533000000>;
opp-microvolt = <1250000>;
};
opp@450000000 {
opp-hz = /bits/ 64 <450000000>;
opp-microvolt = <1150000>;
};
opp@400000000 {
opp-hz = /bits/ 64 <400000000>;
opp-microvolt = <1125000>;
};
opp@350000000 {
opp-hz = /bits/ 64 <350000000>;
opp-microvolt = <1075000>;
};
opp@266000000 {
opp-hz = /bits/ 64 <266000000>;
opp-microvolt = <1025000>;
};
opp@160000000 {
opp-hz = /bits/ 64 <160000000>;
opp-microvolt = <925000>;
};
opp@100000000 {
opp-hz = /bits/ 64 <100000000>;
opp-microvolt = <912500>;
};
};
Example for a Mali GPU with 2 clocks and 2 regulators:
gpu: gpu@6e000000 {
compatible = "arm,mali-midgard";
reg = <0x0 0x6e000000 0x0 0x200000>;
interrupts = <0 168 4>, <0 168 4>, <0 168 4>;
interrupt-names = "JOB", "MMU", "GPU";
clocks = <&clk_mali 0>, <&clk_mali 1>;
clock-names = "clk_mali", "shadercores";
mali-supply = <&supply0_3v3>;
mem-supply = <&supply1_3v3>;
system-coherency = <31>;
operating-points-v2 = <&gpu_opp_table>;
};
gpu_opp_table: opp_table0 {
compatible = "operating-points-v2", "operating-points-v2-mali";
opp@0 {
opp-hz = /bits/ 64 <50000000>;
opp-hz-real = /bits/ 64 <50000000>, /bits/ 64 <45000000>;
opp-microvolt = <820000>, <800000>;
opp-core-mask = /bits/ 64 <0xf>;
};
opp@1 {
opp-hz = /bits/ 64 <40000000>;
opp-hz-real = /bits/ 64 <40000000>, /bits/ 64 <35000000>;
opp-microvolt = <720000>, <700000>;
opp-core-mask = /bits/ 64 <0x7>;
};
opp@2 {
opp-hz = /bits/ 64 <30000000>;
opp-hz-real = /bits/ 64 <30000000>, /bits/ 64 <25000000>;
opp-microvolt = <620000>, <700000>;
opp-core-mask = /bits/ 64 <0x3>;
};
};
Example for a Mali GPU supporting PBHA configuration via DTB (default):
gpu@0xfc010000 {
...
pbha {
int-id-override = <2 0x32>, <9 0x05>, <16 0x32>;
propagate-bits = /bits/ 8 <0x03>;
mma-wa-id = <2>;
};
...
};

View File

@@ -1179,6 +1179,9 @@ dtb-$(CONFIG_ARCH_ROCKCHIP) += \
rv1126b-evb1-v10-bt-sco.dtb \
rv1126b-evb1-v10-dual-4k.dtb \
rv1126b-evb1-v10-dv.dtb \
rv1126b-evb1-v10-fastboot-emmc.dtb \
rv1126b-evb1-v10-fastboot-spi-nand.dtb \
rv1126b-evb1-v10-fastboot-spi-nor.dtb \
rv1126b-evb1-v10-spi-nor.dtb \
rv1126b-evb2-v10.dtb \
rv1126b-evb2-v10-mcu-k350c4516t.dtb \

View File

@@ -0,0 +1,23 @@
// SPDX-License-Identifier: (GPL-2.0+ OR MIT)
/*
* Copyright (c) 2025 Rockchip Electronics Co., Ltd.
*/
#include "arm64/rockchip/rv1126b-evb1-v10-fastboot-emmc.dts"
/ {
model = "Rockchip RV1126B EVB1 V10 Fastboot Board";
compatible = "rockchip,rv1126b-evb1-v10-fastboot", "rockchip,rv1126b";
chosen {
bootargs = "loglevel=0 initcall_debug=0 earlycon=uart8250,mmio32,0x20810000 console=ttyFIQ0 root=/dev/rd0 rootfstype=erofs rootflags=dax snd_soc_core.prealloc_buffer_size_kbytes=16 coherent_pool=32K";
};
};
&ramdisk_r {
reg = <0x48c40000 (40 * 0x00100000)>;
};
&ramdisk_c {
reg = <0x4b440000 (20 * 0x00100000)>;
};

View File

@@ -0,0 +1,23 @@
// SPDX-License-Identifier: (GPL-2.0+ OR MIT)
/*
* Copyright (c) 2025 Rockchip Electronics Co., Ltd.
*/
#include "arm64/rockchip/rv1126b-evb1-v10-fastboot-spi-nand.dts"
/ {
model = "Rockchip RV1126B EVB1 V10 Board";
compatible = "rockchip,rv1126b-evb1-v10-fastboot-spi-nand", "rockchip,rv1126b";
chosen {
bootargs = "loglevel=0 initcall_debug=0 earlycon=uart8250,mmio32,0x20810000 console=ttyFIQ0 root=/dev/rd0 rootfstype=erofs rootflags=dax snd_soc_core.prealloc_buffer_size_kbytes=16 coherent_pool=32K";
};
};
&ramdisk_r {
reg = <0x48c40000 (40 * 0x00100000)>;
};
&ramdisk_c {
reg = <0x4b440000 (20 * 0x00100000)>;
};

View File

@@ -0,0 +1,23 @@
// SPDX-License-Identifier: (GPL-2.0+ OR MIT)
/*
* Copyright (c) 2025 Rockchip Electronics Co., Ltd.
*/
#include "arm64/rockchip/rv1126b-evb1-v10-fastboot-spi-nor.dts"
/ {
model = "Rockchip RV1126B EVB1 V10 Board";
compatible = "rockchip,rv1126b-evb1-v10-fastboot-spi-nand", "rockchip,rv1126b";
chosen {
bootargs = "loglevel=0 initcall_debug=0 earlycon=uart8250,mmio32,0x20810000 console=ttyFIQ0 root=/dev/rd0 rootfstype=erofs rootflags=dax snd_soc_core.prealloc_buffer_size_kbytes=16 coherent_pool=32K";
};
};
&ramdisk_r {
reg = <0x48c40000 (20 * 0x00100000)>;
};
&ramdisk_c {
reg = <0x4a040000 (10 * 0x00100000)>;
};

View File

@@ -1,45 +1,54 @@
CONFIG_BLK_DEV_INITRD=y
CONFIG_CRC16=m
CONFIG_CRC16=y
CONFIG_CRYPTO=y
CONFIG_DAX=y
CONFIG_ELF_CORE=y
CONFIG_EROFS_FS=y
# CONFIG_ETHERNET is not set
CONFIG_EXT4_FS=m
CONFIG_EXTCON=y
CONFIG_FILE_LOCKING=y
CONFIG_INPUT=y
CONFIG_JFFS2_FS=y
CONFIG_KERNEL_GZIP=y
# CONFIG_KERNEL_XZ is not set
CONFIG_LIBCRC32C=y
CONFIG_MAILBOX=y
# CONFIG_MDIO_DEVICE is not set
CONFIG_MMC=y
CONFIG_MSDOS_FS=m
CONFIG_MSDOS_PARTITION=y
CONFIG_MTD_BLOCK=m
CONFIG_NLS_CODEPAGE_936=m
# CONFIG_PHYLIB is not set
CONFIG_PHY_ROCKCHIP_CSI2_DPHY=y
CONFIG_RK_DMABUF_PROCFS=y
CONFIG_ROCKCHIP_DVBM=y
CONFIG_ROCKCHIP_HW_DECOMPRESS=y
CONFIG_ROCKCHIP_MULTI_RGA=y
CONFIG_ROCKCHIP_OPP=y
CONFIG_ROCKCHIP_RAMDISK=y
CONFIG_ROCKCHIP_RGA_PROC_FS=y
CONFIG_ROCKCHIP_THUNDER_BOOT=y
CONFIG_ROCKCHIP_THUNDER_BOOT_DEFER_FREE_MEMBLOCK=y
CONFIG_ROCKCHIP_VENDOR_STORAGE=m
# CONFIG_SLUB_SYSFS is not set
CONFIG_SND_SIMPLE_CARD=m
CONFIG_SND_SIMPLE_CARD_UTILS=m
# CONFIG_SND_SIMPLE_CARD is not set
CONFIG_SND_SOC_DUMMY_CODEC=m
CONFIG_SND_SOC_RK_DSM=m
CONFIG_SND_SOC_ROCKCHIP=m
CONFIG_SND_SOC_ROCKCHIP_ASRC=m
CONFIG_SND_SOC_ROCKCHIP_PDM_V2=m
CONFIG_SND_SOC_ROCKCHIP_SAI=m
CONFIG_SND_SOC_RV1106=m
CONFIG_SPI=y
CONFIG_SQUASHFS_LZ4=y
CONFIG_VFAT_FS=m
# CONFIG_VIDEO_RK_IRCUT is not set
CONFIG_VIDEO_ROCKCHIP_AIISP=y
CONFIG_VIDEO_ROCKCHIP_AVSP=y
CONFIG_VIDEO_ROCKCHIP_CIF=y
CONFIG_VIDEO_ROCKCHIP_FEC=y
CONFIG_VIDEO_ROCKCHIP_ISP=y
CONFIG_VIDEO_ROCKCHIP_VPSS=y
CONFIG_VIDEO_SC200AI=y
CONFIG_VIDEO_SC450AI=y
CONFIG_VIDEO_SC850SL=y
# CONFIG_AD2S1200 is not set
# CONFIG_AD2S1210 is not set
# CONFIG_AD2S90 is not set
@@ -109,16 +118,14 @@ CONFIG_VIDEO_SC450AI=y
# CONFIG_ADXRS290 is not set
# CONFIG_ADXRS450 is not set
# CONFIG_AFE4403 is not set
# CONFIG_ALTERA_MBOX is not set
# CONFIG_ARM_MHU is not set
# CONFIG_ARM_MHU_V2 is not set
# CONFIG_ARM_SCPI_PROTOCOL is not set
# CONFIG_AS3935 is not set
# CONFIG_BMA220 is not set
# CONFIG_BMC150_MAGN_SPI is not set
# CONFIG_BMI088_ACCEL is not set
# CONFIG_BMI160_SPI is not set
# CONFIG_BSD_DISKLABEL is not set
# CONFIG_CHARGER_BQ24190 is not set
CONFIG_CORE_DUMP_DEFAULT_ELF_HEADERS=y
# CONFIG_CRYPTO_842 is not set
# CONFIG_CRYPTO_ADIANTUM is not set
# CONFIG_CRYPTO_AEGIS128 is not set
@@ -215,8 +222,11 @@ CONFIG_CRYPTO_MANAGER_DISABLE_TESTS=y
# CONFIG_CRYPTO_XTS is not set
# CONFIG_CRYPTO_XXHASH is not set
# CONFIG_CRYPTO_ZSTD is not set
# CONFIG_DM9051 is not set
# CONFIG_EEPROM_93XX46 is not set
# CONFIG_EEPROM_AT25 is not set
# CONFIG_ENC28J60 is not set
# CONFIG_ENCX24J600 is not set
# CONFIG_EROFS_FS_DEBUG is not set
# CONFIG_EROFS_FS_XATTR is not set
# CONFIG_EROFS_FS_ZIP is not set
@@ -224,6 +234,14 @@ CONFIG_CRYPTO_MANAGER_DISABLE_TESTS=y
# CONFIG_EXT4_FS_POSIX_ACL is not set
# CONFIG_EXT4_FS_SECURITY is not set
CONFIG_EXT4_USE_FOR_EXT2=y
# CONFIG_EXTCON_ADC_JACK is not set
# CONFIG_EXTCON_FSA9480 is not set
# CONFIG_EXTCON_GPIO is not set
# CONFIG_EXTCON_MAX3355 is not set
# CONFIG_EXTCON_PTN5150 is not set
# CONFIG_EXTCON_RT8973A is not set
# CONFIG_EXTCON_SM5502 is not set
# CONFIG_EXTCON_USB_GPIO is not set
# CONFIG_EZX_PCAP is not set
CONFIG_FAT_DEFAULT_CODEPAGE=936
CONFIG_FAT_DEFAULT_IOCHARSET="cp936"
@@ -241,10 +259,27 @@ CONFIG_FS_MBCACHE=m
# CONFIG_GPIO_PISOSR is not set
# CONFIG_GPIO_XRA1403 is not set
# CONFIG_HI8435 is not set
# CONFIG_HID is not set
# CONFIG_I2C_HID_OF is not set
# CONFIG_I2C_HID_OF_ELAN is not set
# CONFIG_I2C_HID_OF_GOODIX is not set
# CONFIG_IIO_SSP_SENSORHUB is not set
CONFIG_INITCALL_ASYNC=y
# CONFIG_INITRAMFS_FORCE is not set
CONFIG_INITRAMFS_SOURCE=""
# CONFIG_INPUT_EVBUG is not set
CONFIG_INPUT_EVDEV=y
# CONFIG_INPUT_FF_MEMLESS is not set
# CONFIG_INPUT_JOYDEV is not set
# CONFIG_INPUT_JOYSTICK is not set
CONFIG_INPUT_KEYBOARD=y
# CONFIG_INPUT_MATRIXKMAP is not set
# CONFIG_INPUT_MISC is not set
# CONFIG_INPUT_MOUSE is not set
# CONFIG_INPUT_MOUSEDEV is not set
# CONFIG_INPUT_SPARSEKMAP is not set
# CONFIG_INPUT_TABLET is not set
# CONFIG_INPUT_TOUCHSCREEN is not set
# CONFIG_INV_ICM42600_SPI is not set
# CONFIG_INV_ICM42670_SPI is not set
# CONFIG_INV_MPU6050_SPI is not set
@@ -264,6 +299,36 @@ CONFIG_JFFS2_FS_WRITEBUFFER=y
# CONFIG_JFFS2_RUBIN is not set
# CONFIG_JFFS2_SUMMARY is not set
CONFIG_JFFS2_ZLIB=y
CONFIG_KEYBOARD_ADC=y
# CONFIG_KEYBOARD_ADP5588 is not set
# CONFIG_KEYBOARD_ADP5589 is not set
# CONFIG_KEYBOARD_ATKBD is not set
# CONFIG_KEYBOARD_BCM is not set
# CONFIG_KEYBOARD_CAP11XX is not set
# CONFIG_KEYBOARD_CYPRESS_SF is not set
# CONFIG_KEYBOARD_DLINK_DIR685 is not set
# CONFIG_KEYBOARD_GPIO is not set
# CONFIG_KEYBOARD_GPIO_POLLED is not set
# CONFIG_KEYBOARD_LKKBD is not set
# CONFIG_KEYBOARD_LM8333 is not set
# CONFIG_KEYBOARD_MATRIX is not set
# CONFIG_KEYBOARD_MAX7359 is not set
# CONFIG_KEYBOARD_MCS is not set
# CONFIG_KEYBOARD_MPR121 is not set
# CONFIG_KEYBOARD_NEWTON is not set
# CONFIG_KEYBOARD_OMAP4 is not set
# CONFIG_KEYBOARD_OPENCORES is not set
# CONFIG_KEYBOARD_PINEPHONE is not set
# CONFIG_KEYBOARD_QT1050 is not set
# CONFIG_KEYBOARD_QT1070 is not set
# CONFIG_KEYBOARD_QT2160 is not set
# CONFIG_KEYBOARD_SAMSUNG is not set
# CONFIG_KEYBOARD_STOWAWAY is not set
# CONFIG_KEYBOARD_SUNKBD is not set
# CONFIG_KEYBOARD_TCA6416 is not set
# CONFIG_KEYBOARD_TCA8418 is not set
# CONFIG_KEYBOARD_XTKBD is not set
# CONFIG_KS8851 is not set
# CONFIG_LATTICE_ECP3_CONFIG is not set
# CONFIG_LMK04832 is not set
# CONFIG_LTC1660 is not set
@@ -271,8 +336,7 @@ CONFIG_JFFS2_ZLIB=y
# CONFIG_LTC2632 is not set
# CONFIG_LTC2688 is not set
# CONFIG_LTC2983 is not set
# CONFIG_MAILBOX_POLL_PERIOD_US is not set
# CONFIG_MAILBOX_TEST is not set
CONFIG_LZ4_DECOMPRESS=y
# CONFIG_MAX1027 is not set
# CONFIG_MAX11100 is not set
# CONFIG_MAX1118 is not set
@@ -322,6 +386,7 @@ CONFIG_MMC_QUEUE_DEPTH=1
# CONFIG_MMC_USDHI6ROL0 is not set
# CONFIG_MOXTET is not set
# CONFIG_MPL115_SPI is not set
# CONFIG_MSE102X is not set
CONFIG_MTD_BLKDEVS=m
# CONFIG_MTD_DATAFLASH is not set
# CONFIG_MTD_MCHP23K256 is not set
@@ -357,11 +422,12 @@ CONFIG_MTD_SPI_NOR_WINBOND=y
# CONFIG_MTD_SPI_NOR_XMC is not set
# CONFIG_MTD_SPI_NOR_XTX is not set
# CONFIG_MTD_SST25L is not set
CONFIG_NET_VENDOR_ADI=y
# CONFIG_PI433 is not set
# CONFIG_PL320_MBOX is not set
# CONFIG_PLATFORM_MHU is not set
# CONFIG_PWRSEQ_EMMC is not set
CONFIG_PWRSEQ_SIMPLE=y
# CONFIG_QCA7000_SPI is not set
# CONFIG_RC_CORE is not set
# CONFIG_RD_BZIP2 is not set
# CONFIG_RD_GZIP is not set
# CONFIG_RD_LZ4 is not set
@@ -371,16 +437,15 @@ CONFIG_PWRSEQ_SIMPLE=y
# CONFIG_RD_ZSTD is not set
CONFIG_REGMAP_SPI=y
# CONFIG_REGULATOR_TPS6524X is not set
# CONFIG_RMI4_CORE is not set
# CONFIG_ROCKCHIP_HW_DECOMPRESS_TEST is not set
# CONFIG_ROCKCHIP_MBOX is not set
# CONFIG_ROCKCHIP_MMC_VENDOR_STORAGE is not set
CONFIG_ROCKCHIP_MTD_VENDOR_STORAGE=m
# CONFIG_ROCKCHIP_RAM_VENDOR_STORAGE is not set
# CONFIG_ROCKCHIP_REMOTECTL is not set
CONFIG_ROCKCHIP_RGA_DEBUGGER=y
CONFIG_ROCKCHIP_THUNDER_BOOT_MMC=y
# CONFIG_ROCKCHIP_THUNDER_BOOT_SERVICE is not set
CONFIG_ROCKCHIP_THUNDER_BOOT_SFC=y
# CONFIG_RPMSG_QCOM_GLINK_RPM is not set
# CONFIG_RTC_DRV_DS1302 is not set
# CONFIG_RTC_DRV_DS1305 is not set
# CONFIG_RTC_DRV_DS1343 is not set
@@ -399,15 +464,21 @@ CONFIG_ROCKCHIP_THUNDER_BOOT_SFC=y
# CONFIG_SCA3300 is not set
# CONFIG_SDIO_UART is not set
# CONFIG_SENSORS_HMC5843_SPI is not set
# CONFIG_SENSORS_LIS3_I2C is not set
# CONFIG_SENSORS_LIS3_SPI is not set
# CONFIG_SENSORS_RM3100_SPI is not set
# CONFIG_SENSOR_DEVICE is not set
# CONFIG_SERIAL_MAX3100 is not set
# CONFIG_SERIAL_MAX310X is not set
CONFIG_SND_JACK_INPUT_DEV=y
# CONFIG_SND_SOC_ADAU1372_SPI is not set
# CONFIG_SND_SOC_ADAU1761_SPI is not set
# CONFIG_SND_SOC_AK4104 is not set
# CONFIG_SND_SOC_CS35L41_SPI is not set
# CONFIG_SND_SOC_CS35L45_SPI is not set
# CONFIG_SND_SOC_CS4271_SPI is not set
# CONFIG_SND_SOC_CS42L52 is not set
# CONFIG_SND_SOC_CS42L56 is not set
# CONFIG_SND_SOC_ES8328_SPI is not set
# CONFIG_SND_SOC_PCM179X_SPI is not set
# CONFIG_SND_SOC_PCM186X_SPI is not set
@@ -415,6 +486,7 @@ CONFIG_ROCKCHIP_THUNDER_BOOT_SFC=y
# CONFIG_SND_SOC_PCM3168A_SPI is not set
# CONFIG_SND_SOC_PCM512x_SPI is not set
# CONFIG_SND_SOC_RK3399_GRU_SOUND is not set
CONFIG_SND_SOC_ROCKCHIP_MULTICODECS=m
# CONFIG_SND_SOC_ROCKCHIP_SPI_CODEC is not set
# CONFIG_SND_SOC_SSM2602_SPI is not set
# CONFIG_SND_SOC_TLV320AIC23_SPI is not set
@@ -423,11 +495,13 @@ CONFIG_ROCKCHIP_THUNDER_BOOT_SFC=y
# CONFIG_SND_SOC_WM8731_SPI is not set
# CONFIG_SND_SOC_WM8770 is not set
# CONFIG_SND_SOC_WM8804_SPI is not set
# CONFIG_SND_SOC_WM8962 is not set
# CONFIG_SND_SOC_ZL38060 is not set
# CONFIG_SND_SPI is not set
# CONFIG_SOLARIS_X86_PARTITION is not set
# CONFIG_SPI_ALTERA is not set
# CONFIG_SPI_AMD is not set
# CONFIG_SPI_AX88796C is not set
# CONFIG_SPI_AXI_SPI_ENGINE is not set
# CONFIG_SPI_BITBANG is not set
# CONFIG_SPI_CADENCE is not set

View File

@@ -1,6 +1,81 @@
CONFIG_CRC16=y
CONFIG_CRYPTO=y
CONFIG_MTD_UBI=y
CONFIG_SPI=y
# CONFIG_AD2S1200 is not set
# CONFIG_AD2S1210 is not set
# CONFIG_AD2S90 is not set
# CONFIG_AD3552R is not set
# CONFIG_AD5360 is not set
# CONFIG_AD5421 is not set
# CONFIG_AD5449 is not set
# CONFIG_AD5504 is not set
# CONFIG_AD5592R is not set
# CONFIG_AD5624R_SPI is not set
# CONFIG_AD5686_SPI is not set
# CONFIG_AD5755 is not set
# CONFIG_AD5758 is not set
# CONFIG_AD5761 is not set
# CONFIG_AD5764 is not set
# CONFIG_AD5766 is not set
# CONFIG_AD5770R is not set
# CONFIG_AD5791 is not set
# CONFIG_AD7124 is not set
# CONFIG_AD7192 is not set
# CONFIG_AD7266 is not set
# CONFIG_AD7280 is not set
# CONFIG_AD7292 is not set
# CONFIG_AD7293 is not set
# CONFIG_AD7298 is not set
# CONFIG_AD7303 is not set
# CONFIG_AD74413R is not set
# CONFIG_AD7476 is not set
# CONFIG_AD7606_IFACE_SPI is not set
# CONFIG_AD7766 is not set
# CONFIG_AD7768_1 is not set
# CONFIG_AD7780 is not set
# CONFIG_AD7791 is not set
# CONFIG_AD7793 is not set
# CONFIG_AD7816 is not set
# CONFIG_AD7887 is not set
# CONFIG_AD7923 is not set
# CONFIG_AD7949 is not set
# CONFIG_AD8366 is not set
# CONFIG_AD8801 is not set
# CONFIG_AD9523 is not set
# CONFIG_AD9832 is not set
# CONFIG_AD9834 is not set
# CONFIG_ADA4250 is not set
# CONFIG_ADF4350 is not set
# CONFIG_ADF4371 is not set
# CONFIG_ADIS16080 is not set
# CONFIG_ADIS16130 is not set
# CONFIG_ADIS16136 is not set
# CONFIG_ADIS16201 is not set
# CONFIG_ADIS16203 is not set
# CONFIG_ADIS16209 is not set
# CONFIG_ADIS16240 is not set
# CONFIG_ADIS16260 is not set
# CONFIG_ADIS16400 is not set
# CONFIG_ADIS16460 is not set
# CONFIG_ADIS16475 is not set
# CONFIG_ADIS16480 is not set
# CONFIG_ADMV1013 is not set
# CONFIG_ADMV4420 is not set
# CONFIG_ADRF6780 is not set
# CONFIG_ADXL313_SPI is not set
# CONFIG_ADXL345_SPI is not set
# CONFIG_ADXL355_SPI is not set
# CONFIG_ADXL367_SPI is not set
# CONFIG_ADXL372_SPI is not set
# CONFIG_ADXRS290 is not set
# CONFIG_ADXRS450 is not set
# CONFIG_AFE4403 is not set
# CONFIG_AS3935 is not set
# CONFIG_BMA220 is not set
# CONFIG_BMC150_MAGN_SPI is not set
# CONFIG_BMI088_ACCEL is not set
# CONFIG_BMI160_SPI is not set
# CONFIG_CRYPTO_842 is not set
CONFIG_CRYPTO_ACOMP2=y
# CONFIG_CRYPTO_ADIANTUM is not set
@@ -103,14 +178,204 @@ CONFIG_CRYPTO_MANAGER_DISABLE_TESTS=y
# CONFIG_CRYPTO_XTS is not set
# CONFIG_CRYPTO_XXHASH is not set
# CONFIG_CRYPTO_ZSTD is not set
# CONFIG_DM9051 is not set
# CONFIG_EEPROM_93XX46 is not set
# CONFIG_EEPROM_AT25 is not set
# CONFIG_ENC28J60 is not set
# CONFIG_ENCX24J600 is not set
# CONFIG_EZX_PCAP is not set
# CONFIG_FXLS8962AF_SPI is not set
# CONFIG_FXOS8700_SPI is not set
# CONFIG_GPIO_74X164 is not set
# CONFIG_GPIO_MAX3191X is not set
# CONFIG_GPIO_MAX7301 is not set
# CONFIG_GPIO_MC33880 is not set
# CONFIG_GPIO_PISOSR is not set
# CONFIG_GPIO_XRA1403 is not set
# CONFIG_HI8435 is not set
# CONFIG_IIO_SSP_SENSORHUB is not set
# CONFIG_INV_ICM42600_SPI is not set
# CONFIG_INV_ICM42670_SPI is not set
# CONFIG_INV_MPU6050_SPI is not set
# CONFIG_KS8851 is not set
# CONFIG_LATTICE_ECP3_CONFIG is not set
# CONFIG_LMK04832 is not set
# CONFIG_LTC1660 is not set
# CONFIG_LTC2496 is not set
# CONFIG_LTC2632 is not set
# CONFIG_LTC2688 is not set
# CONFIG_LTC2983 is not set
CONFIG_LZO_COMPRESS=y
CONFIG_LZO_DECOMPRESS=y
# CONFIG_MAX1027 is not set
# CONFIG_MAX11100 is not set
# CONFIG_MAX1118 is not set
# CONFIG_MAX11205 is not set
# CONFIG_MAX1241 is not set
# CONFIG_MAX31856 is not set
# CONFIG_MAX31865 is not set
# CONFIG_MAX5481 is not set
# CONFIG_MAX5487 is not set
# CONFIG_MAXIM_THERMOCOUPLE is not set
# CONFIG_MCP320X is not set
# CONFIG_MCP3911 is not set
# CONFIG_MCP41010 is not set
# CONFIG_MCP4131 is not set
# CONFIG_MCP4922 is not set
# CONFIG_MFD_ARIZONA_SPI is not set
# CONFIG_MFD_CPCAP is not set
# CONFIG_MFD_DA9052_SPI is not set
# CONFIG_MFD_INTEL_M10_BMC is not set
# CONFIG_MFD_MC13XXX_SPI is not set
# CONFIG_MFD_OCELOT is not set
# CONFIG_MFD_RK806_SPI is not set
# CONFIG_MFD_RSMU_SPI is not set
# CONFIG_MFD_TPS65912_SPI is not set
# CONFIG_MFD_WM831X_SPI is not set
# CONFIG_MICREL_KS8995MA is not set
# CONFIG_MMA7455_SPI is not set
# CONFIG_MOXTET is not set
# CONFIG_MPL115_SPI is not set
# CONFIG_MSE102X is not set
# CONFIG_MTD_DATAFLASH is not set
# CONFIG_MTD_MCHP23K256 is not set
# CONFIG_MTD_MCHP48L640 is not set
CONFIG_MTD_NAND_BBT_USING_FLASH=y
CONFIG_MTD_NAND_CORE=y
CONFIG_MTD_NAND_ECC=y
CONFIG_MTD_SPI_NAND=y
CONFIG_MTD_SPI_NAND_ATO=y
CONFIG_MTD_SPI_NAND_BIWIN=y
CONFIG_MTD_SPI_NAND_DEVICE_AUTOSELECT=y
CONFIG_MTD_SPI_NAND_DOSILICON=y
CONFIG_MTD_SPI_NAND_ESMT=y
CONFIG_MTD_SPI_NAND_ETRON=y
CONFIG_MTD_SPI_NAND_FMSH=y
CONFIG_MTD_SPI_NAND_FORESEE=y
CONFIG_MTD_SPI_NAND_GIGADEVICE=y
CONFIG_MTD_SPI_NAND_GSTO=y
CONFIG_MTD_SPI_NAND_HIKSEMI=y
CONFIG_MTD_SPI_NAND_HYF=y
CONFIG_MTD_SPI_NAND_JSC=y
CONFIG_MTD_SPI_NAND_MACRONIX=y
CONFIG_MTD_SPI_NAND_MICRON=y
CONFIG_MTD_SPI_NAND_PARAGON=y
CONFIG_MTD_SPI_NAND_SILICONGO=y
CONFIG_MTD_SPI_NAND_SKYHIGH=y
CONFIG_MTD_SPI_NAND_TOSHIBA=y
CONFIG_MTD_SPI_NAND_UNIM=y
CONFIG_MTD_SPI_NAND_WINBOND=y
CONFIG_MTD_SPI_NAND_XINCUN=y
CONFIG_MTD_SPI_NAND_XTX=y
CONFIG_MTD_SPI_NAND_ZBIT=y
# CONFIG_MTD_SPI_NOR is not set
# CONFIG_MTD_SST25L is not set
CONFIG_MTD_UBI_BEB_LIMIT=20
CONFIG_MTD_UBI_BLOCK=y
# CONFIG_MTD_UBI_FASTMAP is not set
# CONFIG_MTD_UBI_GLUEBI is not set
CONFIG_MTD_UBI_WL_THRESHOLD=4096
# CONFIG_NET_VENDOR_ADI is not set
# CONFIG_PI433 is not set
# CONFIG_QCA7000_SPI is not set
CONFIG_REGMAP_SPI=y
# CONFIG_REGULATOR_TPS6524X is not set
# CONFIG_ROCKCHIP_MTD_VENDOR_STORAGE is not set
# CONFIG_RTC_DRV_DS1302 is not set
# CONFIG_RTC_DRV_DS1305 is not set
# CONFIG_RTC_DRV_DS1343 is not set
# CONFIG_RTC_DRV_DS1347 is not set
# CONFIG_RTC_DRV_DS1390 is not set
# CONFIG_RTC_DRV_M41T93 is not set
# CONFIG_RTC_DRV_M41T94 is not set
# CONFIG_RTC_DRV_MAX6902 is not set
# CONFIG_RTC_DRV_MAX6916 is not set
# CONFIG_RTC_DRV_MCP795 is not set
# CONFIG_RTC_DRV_PCF2123 is not set
# CONFIG_RTC_DRV_R9701 is not set
# CONFIG_RTC_DRV_RS5C348 is not set
# CONFIG_RTC_DRV_RX4581 is not set
# CONFIG_SCA3000 is not set
# CONFIG_SCA3300 is not set
# CONFIG_SENSORS_HMC5843_SPI is not set
# CONFIG_SENSORS_RM3100_SPI is not set
# CONFIG_SERIAL_MAX3100 is not set
# CONFIG_SERIAL_MAX310X is not set
CONFIG_SGL_ALLOC=y
# CONFIG_SND_SOC_ADAU1372_SPI is not set
# CONFIG_SND_SOC_ADAU1761_SPI is not set
# CONFIG_SND_SOC_AK4104 is not set
# CONFIG_SND_SOC_CS35L41_SPI is not set
# CONFIG_SND_SOC_CS35L45_SPI is not set
# CONFIG_SND_SOC_CS4271_SPI is not set
# CONFIG_SND_SOC_ES8328_SPI is not set
# CONFIG_SND_SOC_PCM179X_SPI is not set
# CONFIG_SND_SOC_PCM186X_SPI is not set
# CONFIG_SND_SOC_PCM3060_SPI is not set
# CONFIG_SND_SOC_PCM3168A_SPI is not set
# CONFIG_SND_SOC_PCM512x_SPI is not set
# CONFIG_SND_SOC_RK3399_GRU_SOUND is not set
# CONFIG_SND_SOC_ROCKCHIP_SPI_CODEC is not set
# CONFIG_SND_SOC_SSM2602_SPI is not set
# CONFIG_SND_SOC_TLV320AIC23_SPI is not set
# CONFIG_SND_SOC_TLV320AIC32X4_SPI is not set
# CONFIG_SND_SOC_TLV320AIC3X_SPI is not set
# CONFIG_SND_SOC_WM8731_SPI is not set
# CONFIG_SND_SOC_WM8770 is not set
# CONFIG_SND_SOC_WM8804_SPI is not set
# CONFIG_SND_SOC_ZL38060 is not set
# CONFIG_SND_SPI is not set
# CONFIG_SPI_ALTERA is not set
# CONFIG_SPI_AMD is not set
# CONFIG_SPI_AX88796C is not set
# CONFIG_SPI_AXI_SPI_ENGINE is not set
# CONFIG_SPI_BITBANG is not set
# CONFIG_SPI_CADENCE is not set
# CONFIG_SPI_CADENCE_QUADSPI is not set
# CONFIG_SPI_CADENCE_XSPI is not set
# CONFIG_SPI_DEBUG is not set
# CONFIG_SPI_DESIGNWARE is not set
# CONFIG_SPI_FSL_SPI is not set
# CONFIG_SPI_GPIO is not set
# CONFIG_SPI_LOOPBACK_TEST is not set
CONFIG_SPI_MASTER=y
CONFIG_SPI_MEM=y
# CONFIG_SPI_MICROCHIP_CORE is not set
# CONFIG_SPI_MICROCHIP_CORE_QSPI is not set
# CONFIG_SPI_MUX is not set
# CONFIG_SPI_MXIC is not set
# CONFIG_SPI_NXP_FLEXSPI is not set
# CONFIG_SPI_OC_TINY is not set
# CONFIG_SPI_PL022 is not set
# CONFIG_SPI_ROCKCHIP is not set
# CONFIG_SPI_ROCKCHIP_FLEXBUS_FSPI is not set
# CONFIG_SPI_ROCKCHIP_FLEXBUS_SPI is not set
CONFIG_SPI_ROCKCHIP_SFC=y
# CONFIG_SPI_ROCKCHIP_SLAVE is not set
# CONFIG_SPI_SC18IS602 is not set
# CONFIG_SPI_SIFIVE is not set
# CONFIG_SPI_SLAVE is not set
# CONFIG_SPI_SPIDEV is not set
# CONFIG_SPI_TLE62X0 is not set
# CONFIG_SPI_XCOMM is not set
# CONFIG_SPI_XILINX is not set
# CONFIG_SPI_ZYNQMP_GQSPI is not set
# CONFIG_TI_ADC0832 is not set
# CONFIG_TI_ADC084S021 is not set
# CONFIG_TI_ADC108S102 is not set
# CONFIG_TI_ADC12138 is not set
# CONFIG_TI_ADC128S052 is not set
# CONFIG_TI_ADC161S626 is not set
# CONFIG_TI_ADS124S08 is not set
# CONFIG_TI_ADS131E08 is not set
# CONFIG_TI_ADS7950 is not set
# CONFIG_TI_ADS8344 is not set
# CONFIG_TI_ADS8688 is not set
# CONFIG_TI_DAC082S085 is not set
# CONFIG_TI_DAC7311 is not set
# CONFIG_TI_DAC7612 is not set
# CONFIG_TI_TLC4541 is not set
# CONFIG_TI_TSC2046 is not set
# CONFIG_UBIFS_ATIME_SUPPORT is not set
CONFIG_UBIFS_FS=y
CONFIG_UBIFS_FS_ADVANCED_COMPR=y
@@ -120,6 +385,9 @@ CONFIG_UBIFS_FS_SECURITY=y
CONFIG_UBIFS_FS_XATTR=y
CONFIG_UBIFS_FS_ZLIB=y
# CONFIG_UBIFS_FS_ZSTD is not set
# CONFIG_VIDEO_GS1662 is not set
# CONFIG_VIDEO_ROCKCHIP_PREISP is not set
# CONFIG_VIDEO_S5C73M3 is not set
CONFIG_ZLIB_DEFLATE=y
CONFIG_ZLIB_INFLATE=y
# CONFIG_ZRAM is not set

View File

@@ -1,5 +1,6 @@
CONFIG_CONFIGFS_FS=y
CONFIG_CONFIGFS_FS=m
CONFIG_EXTCON=y
CONFIG_PHY_ROCKCHIP_NANENG_COMBO_PHY=m
CONFIG_USB_SUPPORT=y
CONFIG_VIDEOBUF2_DMA_SG=m
# CONFIG_APPLE_MFI_FASTCHARGE is not set
@@ -12,6 +13,7 @@ CONFIG_VIDEOBUF2_DMA_SG=m
# CONFIG_EXTCON_RT8973A is not set
# CONFIG_EXTCON_SM5502 is not set
# CONFIG_EXTCON_USB_GPIO is not set
# CONFIG_HISI_HIKEY_USB is not set
# CONFIG_I2C_CP2615 is not set
# CONFIG_I2C_DIOLAN_U2C is not set
# CONFIG_I2C_ROBOTFUZZ_OSIF is not set
@@ -55,13 +57,13 @@ CONFIG_USB_CONFIGFS=m
# CONFIG_USB_CONFIGFS_ECM_SUBSET is not set
# CONFIG_USB_CONFIGFS_EEM is not set
CONFIG_USB_CONFIGFS_F_FS=y
# CONFIG_USB_CONFIGFS_F_HID is not set
CONFIG_USB_CONFIGFS_F_HID=y
# CONFIG_USB_CONFIGFS_F_LB_SS is not set
# CONFIG_USB_CONFIGFS_F_MIDI is not set
# CONFIG_USB_CONFIGFS_F_PRINTER is not set
# CONFIG_USB_CONFIGFS_F_UAC1 is not set
CONFIG_USB_CONFIGFS_F_UAC1=y
# CONFIG_USB_CONFIGFS_F_UAC1_LEGACY is not set
# CONFIG_USB_CONFIGFS_F_UAC2 is not set
CONFIG_USB_CONFIGFS_F_UAC2=y
CONFIG_USB_CONFIGFS_F_UVC=y
# CONFIG_USB_CONFIGFS_MASS_STORAGE is not set
# CONFIG_USB_CONFIGFS_NCM is not set
@@ -76,12 +78,16 @@ CONFIG_USB_DEFAULT_PERSIST=y
# CONFIG_USB_DUMMY_HCD is not set
# CONFIG_USB_DWC2 is not set
CONFIG_USB_DWC3=m
# CONFIG_USB_DWC3_DUAL_ROLE is not set
CONFIG_USB_DWC3_GADGET=y
CONFIG_USB_DWC3_DUAL_ROLE=y
# CONFIG_USB_DWC3_GADGET is not set
# CONFIG_USB_DWC3_HOST is not set
CONFIG_USB_DWC3_OF_SIMPLE=m
# CONFIG_USB_DYNAMIC_MINORS is not set
# CONFIG_USB_EHCI_HCD is not set
# CONFIG_USB_EHCI_FSL is not set
CONFIG_USB_EHCI_HCD=m
CONFIG_USB_EHCI_HCD_PLATFORM=m
# CONFIG_USB_EHCI_ROOT_HUB_TT is not set
CONFIG_USB_EHCI_TT_NEWSCHED=y
# CONFIG_USB_EHSET_TEST_FIXTURE is not set
# CONFIG_USB_EMI26 is not set
# CONFIG_USB_EMI62 is not set
@@ -94,7 +100,10 @@ CONFIG_USB_DWC3_OF_SIMPLE=m
# CONFIG_USB_FUNCTIONFS is not set
# CONFIG_USB_FUSB300 is not set
CONFIG_USB_F_FS=m
CONFIG_USB_F_HID=m
CONFIG_USB_F_RNDIS=m
CONFIG_USB_F_UAC1=m
CONFIG_USB_F_UAC2=m
CONFIG_USB_F_UVC=m
CONFIG_USB_GADGET=m
# CONFIG_USB_GADGETFS is not set
@@ -138,7 +147,8 @@ CONFIG_USB_LIBCOMPOSITE=m
# CONFIG_USB_MV_UDC is not set
# CONFIG_USB_NET2272 is not set
# CONFIG_USB_NET_DRIVERS is not set
# CONFIG_USB_OHCI_HCD is not set
CONFIG_USB_OHCI_HCD=m
CONFIG_USB_OHCI_HCD_PLATFORM=m
# CONFIG_USB_ONBOARD_HUB is not set
# CONFIG_USB_OTG is not set
# CONFIG_USB_OTG_DISABLE_EXTERNAL_HUB is not set
@@ -149,9 +159,10 @@ CONFIG_USB_LIBCOMPOSITE=m
# CONFIG_USB_R8A66597 is not set
# CONFIG_USB_R8A66597_HCD is not set
# CONFIG_USB_RAW_GADGET is not set
# CONFIG_USB_ROLE_SWITCH is not set
CONFIG_USB_ROLE_SWITCH=m
# CONFIG_USB_SERIAL is not set
# CONFIG_USB_SEVSEG is not set
# CONFIG_USB_SISUSBVGA is not set
# CONFIG_USB_SL811_HCD is not set
# CONFIG_USB_SNP_UDC_PLAT is not set
# CONFIG_USB_TEST is not set
@@ -159,9 +170,13 @@ CONFIG_USB_LIBCOMPOSITE=m
# CONFIG_USB_TRANCEVIBRATOR is not set
# CONFIG_USB_ULPI is not set
# CONFIG_USB_ULPI_BUS is not set
CONFIG_USB_U_AUDIO=m
CONFIG_USB_U_ETHER=m
# CONFIG_USB_WDM is not set
# CONFIG_USB_XHCI_HCD is not set
# CONFIG_USB_XHCI_DBGCAP is not set
CONFIG_USB_XHCI_HCD=m
# CONFIG_USB_XHCI_PCI_RENESAS is not set
CONFIG_USB_XHCI_PLATFORM=m
# CONFIG_USB_YUREX is not set
# CONFIG_USB_ZERO is not set
# CONFIG_XILLYUSB is not set

View File

@@ -0,0 +1,459 @@
CONFIG_BLK_DEV_INITRD=y
# CONFIG_CPU_FREQ_DEFAULT_GOV_ONDEMAND is not set
CONFIG_CPU_FREQ_DEFAULT_GOV_PERFORMANCE=y
CONFIG_CRYPTO=y
CONFIG_DAX=y
CONFIG_EROFS_FS=y
# CONFIG_ETHERNET is not set
CONFIG_JFFS2_FS=y
CONFIG_KERNEL_GZIP=y
# CONFIG_KERNEL_XZ is not set
CONFIG_LIBCRC32C=y
CONFIG_MAILBOX=y
# CONFIG_MDIO_DEVICE is not set
CONFIG_MMC=y
CONFIG_MTD_BLOCK=y
# CONFIG_PHYLIB is not set
CONFIG_PHY_ROCKCHIP_CSI2_DPHY=y
CONFIG_ROCKCHIP_DVBM=y
CONFIG_ROCKCHIP_HW_DECOMPRESS=y
CONFIG_ROCKCHIP_MULTI_RGA=y
CONFIG_ROCKCHIP_RAMDISK=y
CONFIG_ROCKCHIP_RGA_PROC_FS=y
CONFIG_ROCKCHIP_THUNDER_BOOT=y
CONFIG_ROCKCHIP_THUNDER_BOOT_DEFER_FREE_MEMBLOCK=y
CONFIG_ROCKCHIP_VENDOR_STORAGE=y
# CONFIG_SLUB_SYSFS is not set
CONFIG_SPI=y
CONFIG_VIDEO_ROCKCHIP_AIISP=y
CONFIG_VIDEO_ROCKCHIP_AVSP=y
CONFIG_VIDEO_ROCKCHIP_CIF=y
CONFIG_VIDEO_ROCKCHIP_ISP=y
CONFIG_VIDEO_ROCKCHIP_VPSS=y
CONFIG_VIDEO_SC200AI=y
CONFIG_VIDEO_SC450AI=y
# CONFIG_AD2S1200 is not set
# CONFIG_AD2S1210 is not set
# CONFIG_AD2S90 is not set
# CONFIG_AD3552R is not set
# CONFIG_AD5360 is not set
# CONFIG_AD5421 is not set
# CONFIG_AD5449 is not set
# CONFIG_AD5504 is not set
# CONFIG_AD5592R is not set
# CONFIG_AD5624R_SPI is not set
# CONFIG_AD5686_SPI is not set
# CONFIG_AD5755 is not set
# CONFIG_AD5758 is not set
# CONFIG_AD5761 is not set
# CONFIG_AD5764 is not set
# CONFIG_AD5766 is not set
# CONFIG_AD5770R is not set
# CONFIG_AD5791 is not set
# CONFIG_AD7124 is not set
# CONFIG_AD7192 is not set
# CONFIG_AD7266 is not set
# CONFIG_AD7280 is not set
# CONFIG_AD7292 is not set
# CONFIG_AD7293 is not set
# CONFIG_AD7298 is not set
# CONFIG_AD7303 is not set
# CONFIG_AD74413R is not set
# CONFIG_AD7476 is not set
# CONFIG_AD7606_IFACE_SPI is not set
# CONFIG_AD7766 is not set
# CONFIG_AD7768_1 is not set
# CONFIG_AD7780 is not set
# CONFIG_AD7791 is not set
# CONFIG_AD7793 is not set
# CONFIG_AD7816 is not set
# CONFIG_AD7887 is not set
# CONFIG_AD7923 is not set
# CONFIG_AD7949 is not set
# CONFIG_AD8366 is not set
# CONFIG_AD8801 is not set
# CONFIG_AD9523 is not set
# CONFIG_AD9832 is not set
# CONFIG_AD9834 is not set
# CONFIG_ADA4250 is not set
# CONFIG_ADF4350 is not set
# CONFIG_ADF4371 is not set
# CONFIG_ADIS16080 is not set
# CONFIG_ADIS16130 is not set
# CONFIG_ADIS16136 is not set
# CONFIG_ADIS16201 is not set
# CONFIG_ADIS16203 is not set
# CONFIG_ADIS16209 is not set
# CONFIG_ADIS16240 is not set
# CONFIG_ADIS16260 is not set
# CONFIG_ADIS16400 is not set
# CONFIG_ADIS16460 is not set
# CONFIG_ADIS16475 is not set
# CONFIG_ADIS16480 is not set
# CONFIG_ADMV1013 is not set
# CONFIG_ADMV4420 is not set
# CONFIG_ADRF6780 is not set
# CONFIG_ADXL313_SPI is not set
# CONFIG_ADXL345_SPI is not set
# CONFIG_ADXL355_SPI is not set
# CONFIG_ADXL367_SPI is not set
# CONFIG_ADXL372_SPI is not set
# CONFIG_ADXRS290 is not set
# CONFIG_ADXRS450 is not set
# CONFIG_AFE4403 is not set
# CONFIG_ALTERA_MBOX is not set
# CONFIG_ARM_MHU is not set
# CONFIG_ARM_MHU_V2 is not set
# CONFIG_ARM_SCPI_PROTOCOL is not set
# CONFIG_AS3935 is not set
# CONFIG_BMA220 is not set
# CONFIG_BMC150_MAGN_SPI is not set
# CONFIG_BMI088_ACCEL is not set
# CONFIG_BMI160_SPI is not set
# CONFIG_CRYPTO_842 is not set
# CONFIG_CRYPTO_ADIANTUM is not set
# CONFIG_CRYPTO_AEGIS128 is not set
# CONFIG_CRYPTO_AES is not set
# CONFIG_CRYPTO_AES_ARM is not set
# CONFIG_CRYPTO_AES_TI is not set
CONFIG_CRYPTO_ALGAPI=y
CONFIG_CRYPTO_ALGAPI2=y
# CONFIG_CRYPTO_ANSI_CPRNG is not set
# CONFIG_CRYPTO_ARIA is not set
# CONFIG_CRYPTO_AUTHENC is not set
# CONFIG_CRYPTO_BLAKE2B is not set
# CONFIG_CRYPTO_BLAKE2S_ARM is not set
# CONFIG_CRYPTO_BLOWFISH is not set
# CONFIG_CRYPTO_CAMELLIA is not set
# CONFIG_CRYPTO_CAST5 is not set
# CONFIG_CRYPTO_CAST6 is not set
# CONFIG_CRYPTO_CBC is not set
# CONFIG_CRYPTO_CCM is not set
# CONFIG_CRYPTO_CFB is not set
# CONFIG_CRYPTO_CHACHA20 is not set
# CONFIG_CRYPTO_CHACHA20POLY1305 is not set
# CONFIG_CRYPTO_CHACHA20_NEON is not set
# CONFIG_CRYPTO_CMAC is not set
# CONFIG_CRYPTO_CRC32 is not set
CONFIG_CRYPTO_CRC32C=y
# CONFIG_CRYPTO_CRCT10DIF is not set
# CONFIG_CRYPTO_CRYPTD is not set
# CONFIG_CRYPTO_CTR is not set
# CONFIG_CRYPTO_CTS is not set
# CONFIG_CRYPTO_CURVE25519 is not set
# CONFIG_CRYPTO_DEFLATE is not set
# CONFIG_CRYPTO_DES is not set
# CONFIG_CRYPTO_DH is not set
# CONFIG_CRYPTO_DRBG_MENU is not set
# CONFIG_CRYPTO_ECB is not set
# CONFIG_CRYPTO_ECDH is not set
# CONFIG_CRYPTO_ECDSA is not set
# CONFIG_CRYPTO_ECHAINIV is not set
# CONFIG_CRYPTO_ECRDSA is not set
# CONFIG_CRYPTO_ESSIV is not set
# CONFIG_CRYPTO_FCRYPT is not set
# CONFIG_CRYPTO_GCM is not set
# CONFIG_CRYPTO_GHASH is not set
CONFIG_CRYPTO_HASH=y
CONFIG_CRYPTO_HASH2=y
# CONFIG_CRYPTO_HCTR2 is not set
# CONFIG_CRYPTO_HMAC is not set
# CONFIG_CRYPTO_HW is not set
# CONFIG_CRYPTO_JITTERENTROPY is not set
# CONFIG_CRYPTO_KEYWRAP is not set
# CONFIG_CRYPTO_LIB_CHACHA20POLY1305 is not set
CONFIG_CRYPTO_LIB_UTILS=y
# CONFIG_CRYPTO_LRW is not set
# CONFIG_CRYPTO_LZ4 is not set
# CONFIG_CRYPTO_LZ4HC is not set
# CONFIG_CRYPTO_LZO is not set
# CONFIG_CRYPTO_MANAGER is not set
CONFIG_CRYPTO_MANAGER_DISABLE_TESTS=y
# CONFIG_CRYPTO_MD4 is not set
# CONFIG_CRYPTO_MD5 is not set
# CONFIG_CRYPTO_MICHAEL_MIC is not set
# CONFIG_CRYPTO_NULL is not set
# CONFIG_CRYPTO_OFB is not set
# CONFIG_CRYPTO_PCBC is not set
# CONFIG_CRYPTO_PCRYPT is not set
# CONFIG_CRYPTO_POLY1305 is not set
# CONFIG_CRYPTO_POLY1305_ARM is not set
# CONFIG_CRYPTO_RMD160 is not set
# CONFIG_CRYPTO_RSA is not set
# CONFIG_CRYPTO_SEQIV is not set
# CONFIG_CRYPTO_SERPENT is not set
# CONFIG_CRYPTO_SHA1 is not set
# CONFIG_CRYPTO_SHA1_ARM is not set
# CONFIG_CRYPTO_SHA256 is not set
# CONFIG_CRYPTO_SHA256_ARM is not set
# CONFIG_CRYPTO_SHA3 is not set
# CONFIG_CRYPTO_SHA512 is not set
# CONFIG_CRYPTO_SHA512_ARM is not set
# CONFIG_CRYPTO_SM2 is not set
# CONFIG_CRYPTO_SM3_GENERIC is not set
# CONFIG_CRYPTO_SM4_GENERIC is not set
# CONFIG_CRYPTO_STREEBOG is not set
# CONFIG_CRYPTO_TEST is not set
# CONFIG_CRYPTO_TWOFISH is not set
# CONFIG_CRYPTO_USER is not set
# CONFIG_CRYPTO_USER_API_AEAD is not set
# CONFIG_CRYPTO_USER_API_HASH is not set
# CONFIG_CRYPTO_USER_API_RNG is not set
# CONFIG_CRYPTO_USER_API_SKCIPHER is not set
# CONFIG_CRYPTO_VMAC is not set
# CONFIG_CRYPTO_WP512 is not set
# CONFIG_CRYPTO_XCBC is not set
# CONFIG_CRYPTO_XTS is not set
# CONFIG_CRYPTO_XXHASH is not set
# CONFIG_CRYPTO_ZSTD is not set
# CONFIG_EEPROM_93XX46 is not set
# CONFIG_EEPROM_AT25 is not set
# CONFIG_EROFS_FS_DEBUG is not set
# CONFIG_EROFS_FS_XATTR is not set
# CONFIG_EROFS_FS_ZIP is not set
# CONFIG_EZX_PCAP is not set
CONFIG_FS_DAX=y
CONFIG_FS_IOMAP=y
# CONFIG_FXLS8962AF_SPI is not set
# CONFIG_FXOS8700_SPI is not set
# CONFIG_GPIO_74X164 is not set
# CONFIG_GPIO_MAX3191X is not set
# CONFIG_GPIO_MAX7301 is not set
# CONFIG_GPIO_MC33880 is not set
# CONFIG_GPIO_PISOSR is not set
# CONFIG_GPIO_XRA1403 is not set
# CONFIG_HI8435 is not set
# CONFIG_IIO_SSP_SENSORHUB is not set
CONFIG_INITCALL_ASYNC=y
# CONFIG_INITRAMFS_FORCE is not set
CONFIG_INITRAMFS_SOURCE=""
# CONFIG_INV_ICM42600_SPI is not set
# CONFIG_INV_ICM42670_SPI is not set
# CONFIG_INV_MPU6050_SPI is not set
# CONFIG_JFFS2_COMPRESSION_OPTIONS is not set
CONFIG_JFFS2_FS_DEBUG=0
# CONFIG_JFFS2_FS_WBUF_VERIFY is not set
CONFIG_JFFS2_FS_WRITEBUFFER=y
# CONFIG_JFFS2_FS_XATTR is not set
CONFIG_JFFS2_RTIME=y
# CONFIG_JFFS2_SUMMARY is not set
CONFIG_JFFS2_ZLIB=y
# CONFIG_LATTICE_ECP3_CONFIG is not set
# CONFIG_LMK04832 is not set
# CONFIG_LTC1660 is not set
# CONFIG_LTC2496 is not set
# CONFIG_LTC2632 is not set
# CONFIG_LTC2688 is not set
# CONFIG_LTC2983 is not set
CONFIG_MAILBOX_POLL_PERIOD_US=y
# CONFIG_MAILBOX_TEST is not set
# CONFIG_MAX1027 is not set
# CONFIG_MAX11100 is not set
# CONFIG_MAX1118 is not set
# CONFIG_MAX11205 is not set
# CONFIG_MAX1241 is not set
# CONFIG_MAX31856 is not set
# CONFIG_MAX31865 is not set
# CONFIG_MAX5481 is not set
# CONFIG_MAX5487 is not set
# CONFIG_MAXIM_THERMOCOUPLE is not set
# CONFIG_MCP320X is not set
# CONFIG_MCP3911 is not set
# CONFIG_MCP41010 is not set
# CONFIG_MCP4131 is not set
# CONFIG_MCP4922 is not set
# CONFIG_MFD_ARIZONA_SPI is not set
# CONFIG_MFD_CPCAP is not set
# CONFIG_MFD_DA9052_SPI is not set
# CONFIG_MFD_INTEL_M10_BMC is not set
# CONFIG_MFD_MC13XXX_SPI is not set
# CONFIG_MFD_OCELOT is not set
# CONFIG_MFD_RK806_SPI is not set
# CONFIG_MFD_RSMU_SPI is not set
# CONFIG_MFD_TPS65912_SPI is not set
# CONFIG_MFD_WM831X_SPI is not set
# CONFIG_MICREL_KS8995MA is not set
# CONFIG_MMA7455_SPI is not set
# CONFIG_MMC_ARMMMCI is not set
CONFIG_MMC_BLOCK=y
CONFIG_MMC_BLOCK_MINORS=32
# CONFIG_MMC_CQHCI is not set
# CONFIG_MMC_DEBUG is not set
CONFIG_MMC_DW=y
# CONFIG_MMC_DW_BLUEFIELD is not set
# CONFIG_MMC_DW_EXYNOS is not set
# CONFIG_MMC_DW_HI3798CV200 is not set
# CONFIG_MMC_DW_K3 is not set
CONFIG_MMC_DW_PLTFM=y
CONFIG_MMC_DW_ROCKCHIP=m
# CONFIG_MMC_HSQ is not set
# CONFIG_MMC_MTK is not set
CONFIG_MMC_QUEUE_DEPTH=1
# CONFIG_MMC_SDHCI is not set
# CONFIG_MMC_SPI is not set
# CONFIG_MMC_TEST is not set
# CONFIG_MMC_USDHI6ROL0 is not set
# CONFIG_MOXTET is not set
# CONFIG_MPL115_SPI is not set
CONFIG_MTD_BLKDEVS=y
# CONFIG_MTD_DATAFLASH is not set
# CONFIG_MTD_MCHP23K256 is not set
# CONFIG_MTD_MCHP48L640 is not set
# CONFIG_MTD_SPI_NAND is not set
CONFIG_MTD_SPI_NOR=y
# CONFIG_MTD_SPI_NOR_ATMEL is not set
# CONFIG_MTD_SPI_NOR_BOYA is not set
# CONFIG_MTD_SPI_NOR_CATALYST is not set
# CONFIG_MTD_SPI_NOR_DEVICE_AUTOSELECT is not set
# CONFIG_MTD_SPI_NOR_DOSILICON is not set
# CONFIG_MTD_SPI_NOR_EON is not set
# CONFIG_MTD_SPI_NOR_ESMT is not set
# CONFIG_MTD_SPI_NOR_EVERSPIN is not set
# CONFIG_MTD_SPI_NOR_FMSH is not set
# CONFIG_MTD_SPI_NOR_FUJITSU is not set
CONFIG_MTD_SPI_NOR_GIGADEVICE=y
# CONFIG_MTD_SPI_NOR_INTEL is not set
# CONFIG_MTD_SPI_NOR_ISSI is not set
CONFIG_MTD_SPI_NOR_MACRONIX=y
CONFIG_MTD_SPI_NOR_MISC=y
# CONFIG_MTD_SPI_NOR_NORMEM is not set
# CONFIG_MTD_SPI_NOR_PUYA is not set
# CONFIG_MTD_SPI_NOR_SPANSION is not set
# CONFIG_MTD_SPI_NOR_SST is not set
# CONFIG_MTD_SPI_NOR_STMICRO is not set
# CONFIG_MTD_SPI_NOR_SWP_DISABLE is not set
CONFIG_MTD_SPI_NOR_SWP_DISABLE_ON_VOLATILE=y
# CONFIG_MTD_SPI_NOR_SWP_KEEP is not set
CONFIG_MTD_SPI_NOR_USE_4K_SECTORS=y
CONFIG_MTD_SPI_NOR_WINBOND=y
# CONFIG_MTD_SPI_NOR_XILINX is not set
# CONFIG_MTD_SPI_NOR_XMC is not set
CONFIG_MTD_SPI_NOR_XTX=y
# CONFIG_MTD_SST25L is not set
# CONFIG_PI433 is not set
# CONFIG_PL320_MBOX is not set
# CONFIG_PLATFORM_MHU is not set
# CONFIG_PWRSEQ_EMMC is not set
CONFIG_PWRSEQ_SIMPLE=y
# CONFIG_RD_BZIP2 is not set
# CONFIG_RD_GZIP is not set
# CONFIG_RD_LZ4 is not set
# CONFIG_RD_LZMA is not set
# CONFIG_RD_LZO is not set
# CONFIG_RD_XZ is not set
# CONFIG_RD_ZSTD is not set
CONFIG_REGMAP_SPI=y
# CONFIG_REGULATOR_TPS6524X is not set
# CONFIG_ROCKCHIP_HW_DECOMPRESS_TEST is not set
CONFIG_ROCKCHIP_MBOX=y
# CONFIG_ROCKCHIP_MBOX_DEMO is not set
# CONFIG_ROCKCHIP_MMC_VENDOR_STORAGE is not set
# CONFIG_ROCKCHIP_MTD_VENDOR_STORAGE is not set
# CONFIG_ROCKCHIP_RAM_VENDOR_STORAGE is not set
CONFIG_ROCKCHIP_RGA_DEBUGGER=y
CONFIG_ROCKCHIP_THUNDER_BOOT_MMC=y
CONFIG_ROCKCHIP_THUNDER_BOOT_SERVICE=y
CONFIG_ROCKCHIP_THUNDER_BOOT_SFC=y
# CONFIG_RPMSG_QCOM_GLINK_RPM is not set
# CONFIG_RPMSG_ROCKCHIP_MBOX is not set
# CONFIG_RTC_DRV_DS1302 is not set
# CONFIG_RTC_DRV_DS1305 is not set
# CONFIG_RTC_DRV_DS1343 is not set
# CONFIG_RTC_DRV_DS1347 is not set
# CONFIG_RTC_DRV_DS1390 is not set
# CONFIG_RTC_DRV_M41T93 is not set
# CONFIG_RTC_DRV_M41T94 is not set
# CONFIG_RTC_DRV_MAX6902 is not set
# CONFIG_RTC_DRV_MAX6916 is not set
# CONFIG_RTC_DRV_MCP795 is not set
# CONFIG_RTC_DRV_PCF2123 is not set
# CONFIG_RTC_DRV_R9701 is not set
# CONFIG_RTC_DRV_RS5C348 is not set
# CONFIG_RTC_DRV_RX4581 is not set
# CONFIG_SCA3000 is not set
# CONFIG_SCA3300 is not set
# CONFIG_SDIO_UART is not set
# CONFIG_SENSORS_HMC5843_SPI is not set
# CONFIG_SENSORS_RM3100_SPI is not set
# CONFIG_SERIAL_MAX3100 is not set
# CONFIG_SERIAL_MAX310X is not set
# CONFIG_SND_SOC_ADAU1372_SPI is not set
# CONFIG_SND_SOC_ADAU1761_SPI is not set
# CONFIG_SND_SOC_AK4104 is not set
# CONFIG_SND_SOC_CS35L41_SPI is not set
# CONFIG_SND_SOC_CS35L45_SPI is not set
# CONFIG_SND_SOC_CS4271_SPI is not set
# CONFIG_SND_SOC_ES8328_SPI is not set
# CONFIG_SND_SOC_PCM179X_SPI is not set
# CONFIG_SND_SOC_PCM186X_SPI is not set
# CONFIG_SND_SOC_PCM3060_SPI is not set
# CONFIG_SND_SOC_PCM3168A_SPI is not set
# CONFIG_SND_SOC_PCM512x_SPI is not set
# CONFIG_SND_SOC_RK3399_GRU_SOUND is not set
# CONFIG_SND_SOC_ROCKCHIP_SPI_CODEC is not set
# CONFIG_SND_SOC_SSM2602_SPI is not set
# CONFIG_SND_SOC_TLV320AIC23_SPI is not set
# CONFIG_SND_SOC_TLV320AIC32X4_SPI is not set
# CONFIG_SND_SOC_TLV320AIC3X_SPI is not set
# CONFIG_SND_SOC_WM8731_SPI is not set
# CONFIG_SND_SOC_WM8770 is not set
# CONFIG_SND_SOC_WM8804_SPI is not set
# CONFIG_SND_SOC_ZL38060 is not set
# CONFIG_SND_SPI is not set
# CONFIG_SPI_ALTERA is not set
# CONFIG_SPI_AMD is not set
# CONFIG_SPI_AXI_SPI_ENGINE is not set
# CONFIG_SPI_BITBANG is not set
# CONFIG_SPI_CADENCE is not set
# CONFIG_SPI_CADENCE_QUADSPI is not set
# CONFIG_SPI_CADENCE_XSPI is not set
# CONFIG_SPI_DEBUG is not set
# CONFIG_SPI_DESIGNWARE is not set
# CONFIG_SPI_FSL_SPI is not set
# CONFIG_SPI_GPIO is not set
# CONFIG_SPI_LOOPBACK_TEST is not set
CONFIG_SPI_MASTER=y
CONFIG_SPI_MEM=y
# CONFIG_SPI_MICROCHIP_CORE is not set
# CONFIG_SPI_MICROCHIP_CORE_QSPI is not set
# CONFIG_SPI_MUX is not set
# CONFIG_SPI_MXIC is not set
# CONFIG_SPI_NXP_FLEXSPI is not set
# CONFIG_SPI_OC_TINY is not set
# CONFIG_SPI_PL022 is not set
# CONFIG_SPI_ROCKCHIP is not set
# CONFIG_SPI_ROCKCHIP_FLEXBUS_FSPI is not set
# CONFIG_SPI_ROCKCHIP_FLEXBUS_SPI is not set
CONFIG_SPI_ROCKCHIP_SFC=y
# CONFIG_SPI_ROCKCHIP_SLAVE is not set
# CONFIG_SPI_SC18IS602 is not set
# CONFIG_SPI_SIFIVE is not set
# CONFIG_SPI_SLAVE is not set
# CONFIG_SPI_SPIDEV is not set
# CONFIG_SPI_TLE62X0 is not set
# CONFIG_SPI_XCOMM is not set
# CONFIG_SPI_XILINX is not set
# CONFIG_SPI_ZYNQMP_GQSPI is not set
# CONFIG_TI_ADC0832 is not set
# CONFIG_TI_ADC084S021 is not set
# CONFIG_TI_ADC108S102 is not set
# CONFIG_TI_ADC12138 is not set
# CONFIG_TI_ADC128S052 is not set
# CONFIG_TI_ADC161S626 is not set
# CONFIG_TI_ADS124S08 is not set
# CONFIG_TI_ADS131E08 is not set
# CONFIG_TI_ADS7950 is not set
# CONFIG_TI_ADS8344 is not set
# CONFIG_TI_ADS8688 is not set
# CONFIG_TI_DAC082S085 is not set
# CONFIG_TI_DAC7311 is not set
# CONFIG_TI_DAC7612 is not set
# CONFIG_TI_TLC4541 is not set
# CONFIG_TI_TSC2046 is not set
# CONFIG_VIDEO_GS1662 is not set
# CONFIG_VIDEO_ROCKCHIP_PREISP is not set
CONFIG_VIDEO_ROCKCHIP_THUNDER_BOOT_ISP=y
CONFIG_VIDEO_ROCKCHIP_THUNDER_BOOT_SETUP=y
# CONFIG_VIDEO_S5C73M3 is not set
CONFIG_ZLIB_DEFLATE=y
CONFIG_ZLIB_INFLATE=y

View File

@@ -293,12 +293,14 @@ dtb-$(CONFIG_ARCH_ROCKCHIP) += rk3576-test2-v10.dtb
dtb-$(CONFIG_ARCH_ROCKCHIP) += rk3576-test2-v10-linux.dtb
dtb-$(CONFIG_ARCH_ROCKCHIP) += rk3576-test3-v10.dtb
dtb-$(CONFIG_ARCH_ROCKCHIP) += rk3576-test5-v10.dtb
dtb-$(CONFIG_ARCH_ROCKCHIP) += rk3576-toybrick-d0-linux.dtb
dtb-$(CONFIG_ARCH_ROCKCHIP) += rk3576-vehicle-evb-v10.dtb
dtb-$(CONFIG_ARCH_ROCKCHIP) += rk3576-vehicle-evb-v10-linux.dtb
dtb-$(CONFIG_ARCH_ROCKCHIP) += rk3576-vehicle-evb-v20.dtb
dtb-$(CONFIG_ARCH_ROCKCHIP) += rk3576-vehicle-evb-v20-amp.dtb
dtb-$(CONFIG_ARCH_ROCKCHIP) += rk3576-vehicle-evb-v20-linux.dtb
dtb-$(CONFIG_ARCH_ROCKCHIP) += rk3576-vehicle-evb-v20-ufs.dtb
dtb-$(CONFIG_ARCH_ROCKCHIP) += rk3576-vehicle-evb-v21.dtb
dtb-$(CONFIG_ARCH_ROCKCHIP) += rk3576s-evb1-v10.dtb
dtb-$(CONFIG_ARCH_ROCKCHIP) += rk3576s-evb1-v10-linux.dtb
dtb-$(CONFIG_ARCH_ROCKCHIP) += rk3576s-tablet-v10.dtb
@@ -377,6 +379,9 @@ dtb-$(CONFIG_ARCH_ROCKCHIP) += rv1126b-evb1-v10-amp.dtb
dtb-$(CONFIG_ARCH_ROCKCHIP) += rv1126b-evb1-v10-bt-sco.dtb
dtb-$(CONFIG_ARCH_ROCKCHIP) += rv1126b-evb1-v10-dual-4k.dtb
dtb-$(CONFIG_ARCH_ROCKCHIP) += rv1126b-evb1-v10-dv.dtb
dtb-$(CONFIG_ARCH_ROCKCHIP) += rv1126b-evb1-v10-fastboot-emmc.dtb
dtb-$(CONFIG_ARCH_ROCKCHIP) += rv1126b-evb1-v10-fastboot-spi-nand.dtb
dtb-$(CONFIG_ARCH_ROCKCHIP) += rv1126b-evb1-v10-fastboot-spi-nor.dtb
dtb-$(CONFIG_ARCH_ROCKCHIP) += rv1126b-evb1-v10-spi-nor.dtb
dtb-$(CONFIG_ARCH_ROCKCHIP) += rv1126b-evb2-v10.dtb
dtb-$(CONFIG_ARCH_ROCKCHIP) += rv1126b-evb2-v10-mcu-k350c4516t.dtb

View File

@@ -396,6 +396,7 @@
reset-delay-ms = <60>;
enable-delay-ms = <60>;
prepare-delay-ms = <60>;
init-delay-ms = <10>;
unprepare-delay-ms = <60>;
disable-delay-ms = <60>;
width-mm = <68>;
@@ -730,6 +731,7 @@
reset-delay-ms = <60>;
enable-delay-ms = <60>;
prepare-delay-ms = <60>;
init-delay-ms = <10>;
unprepare-delay-ms = <60>;
disable-delay-ms = <60>;
width-mm = <68>;

View File

@@ -270,6 +270,7 @@
reset-delay-ms = <10>;
enable-delay-ms = <10>;
prepare-delay-ms = <10>;
init-delay-ms = <10>;
unprepare-delay-ms = <10>;
disable-delay-ms = <60>;
width-mm = <68>;

View File

@@ -0,0 +1,195 @@
// SPDX-License-Identifier: (GPL-2.0+ OR MIT)
/*
* Copyright (c) 2024 Rockchip Electronics Co., Ltd.
*
*/
&csi2_dcphy0 {
status = "okay";
ports {
#address-cells = <1>;
#size-cells = <0>;
port@0 {
reg = <0>;
#address-cells = <1>;
#size-cells = <0>;
mipi_in_ucam0: endpoint@1 {
reg = <1>;
remote-endpoint = <&imx415_out0>;
data-lanes = <1 2 3 4>;
};
mipi_in_ucam1: endpoint@2 {
reg = <2>;
remote-endpoint = <&ov50c40_out0>;
data-lanes = <1 2 3 4>;
};
};
port@1 {
reg = <1>;
#address-cells = <1>;
#size-cells = <0>;
csidcphy0_out: endpoint@0 {
reg = <0>;
remote-endpoint = <&mipi0_csi2_input>;
};
};
};
};
&i2c9 {
status = "okay";
pinctrl-names = "default";
pinctrl-0 = <&i2c9m2_xfer>;
imx415_dcphy0: imx415@1a {
compatible = "sony,imx415";
reg = <0x1a>;
clocks = <&cru CLK_MIPI_CAMERAOUT_M0>;
clock-names = "xvclk";
pinctrl-names = "default";
pinctrl-0 = <&cam_clk0m1_clk0>;
power-domains = <&power RK3576_PD_VI>;
power-gpios = <&gpio2 RK_PD0 GPIO_ACTIVE_HIGH>;
reset-gpios = <&gpio2 RK_PD3 GPIO_ACTIVE_LOW>;
rockchip,camera-module-index = <0>;
rockchip,camera-module-facing = "back";
rockchip,camera-module-name = "CMK-OT2022-PX1";
rockchip,camera-module-lens-name = "IR0147-50IRC-8M-F20";
port {
imx415_out0: endpoint {
remote-endpoint = <&mipi_in_ucam0>;
data-lanes = <1 2 3 4>;
};
};
};
aw8601_0: aw8601@c {
compatible = "awinic,aw8601";
status = "okay";
reg = <0x0c>;
rockchip,vcm-start-current = <56>;
rockchip,vcm-rated-current = <96>;
rockchip,vcm-step-mode = <4>;
rockchip,camera-module-index = <0>;
rockchip,camera-module-facing = "back";
};
otp_eeprom_0: otp_eeprom@50 {
compatible = "rk,otp_eeprom";
status = "okay";
reg = <0x50>;
};
ov50c40_dcph0: ov50c40@36 {
compatible = "ovti,ov50c40";
reg = <0x36>;
clocks = <&cru CLK_MIPI_CAMERAOUT_M0>;
clock-names = "xvclk";
power-domains = <&power RK3576_PD_VI>;
pinctrl-names = "default";
pinctrl-0 = <&cam_clk0m1_clk0>;
pwdn-gpios = <&gpio2 RK_PD0 GPIO_ACTIVE_LOW>;// must be high at last
reset-gpios = <&gpio2 RK_PD3 GPIO_ACTIVE_LOW>;// must be high at last
rockchip,camera-module-index = <0>;
rockchip,camera-module-facing = "back";
rockchip,camera-module-name = "HZGA06";
rockchip,camera-module-lens-name = "ZE0082C1-RK3568";
eeprom-ctrl = <&otp_eeprom_0>;
lens-focus = <&aw8601_0>;
port {
ov50c40_out0: endpoint {
remote-endpoint = <&mipi_in_ucam1>;
data-lanes = <1 2 3 4>;
};
};
};
};
&mipi0_csi2 {
status = "okay";
ports {
#address-cells = <1>;
#size-cells = <0>;
port@0 {
reg = <0>;
#address-cells = <1>;
#size-cells = <0>;
mipi0_csi2_input: endpoint@1 {
reg = <1>;
remote-endpoint = <&csidcphy0_out>;
};
};
port@1 {
reg = <1>;
#address-cells = <1>;
#size-cells = <0>;
mipi0_csi2_output: endpoint@0 {
reg = <0>;
remote-endpoint = <&cif_mipi_in0>;
};
};
};
};
&rkcif {
status = "okay";
};
&rkcif_mipi_lvds {
status = "okay";
port {
cif_mipi_in0: endpoint {
remote-endpoint = <&mipi0_csi2_output>;
};
};
};
&rkcif_mipi_lvds_sditf {
status = "okay";
port {
mipi_lvds_sditf: endpoint {
remote-endpoint = <&isp_vir0>;
};
};
};
&rkcif_mmu {
status = "okay";
};
&rkisp {
status = "okay";
};
&rkisp_mmu {
status = "okay";
};
&rkisp_vir0 {
status = "okay";
port {
#address-cells = <1>;
#size-cells = <0>;
isp_vir0: endpoint@0 {
reg = <0>;
remote-endpoint = <&mipi_lvds_sditf>;
};
};
};
&rkisp_vir0_sditf {
status = "okay";
};

View File

@@ -0,0 +1,199 @@
// SPDX-License-Identifier: (GPL-2.0+ OR MIT)
/*
* Copyright (c) 2024 Rockchip Electronics Co., Ltd.
*
*/
&csi2_dphy0_hw {
status = "okay";
};
&csi2_dphy1_hw {
status = "okay";
};
&csi2_dphy3 {
status = "okay";
ports {
#address-cells = <1>;
#size-cells = <0>;
port@0 {
reg = <0>;
#address-cells = <1>;
#size-cells = <0>;
mipi_in_ucam30: endpoint@1 {
reg = <1>;
remote-endpoint = <&imx415_out1>;
data-lanes = <1 2 3 4>;
};
mipi_in_ucam31: endpoint@2 {
reg = <2>;
remote-endpoint = <&ov50c40_out1>;
data-lanes = <1 2 3 4>;
};
};
port@1 {
reg = <1>;
#address-cells = <1>;
#size-cells = <0>;
csidphy3_out: endpoint@0 {
reg = <0>;
remote-endpoint = <&mipi3_csi2_input>;
};
};
};
};
&i2c6 {
status = "okay";
pinctrl-names = "default";
pinctrl-0 = <&i2c6m1_xfer>;
imx415_dphy3: imx415@1a {
compatible = "sony,imx415";
reg = <0x1a>;
clocks = <&cru CLK_MIPI_CAMERAOUT_M2>;
clock-names = "xvclk";
pinctrl-names = "default";
pinctrl-0 = <&cam_clk2m1_clk2>;
power-domains = <&power RK3576_PD_VI>;
power-gpios = <&gpio1 RK_PD4 GPIO_ACTIVE_HIGH>;
reset-gpios = <&gpio2 RK_PD6 GPIO_ACTIVE_LOW>;
rockchip,camera-module-index = <1>;
rockchip,camera-module-facing = "back";
rockchip,camera-module-name = "CMK-OT2022-PX1";
rockchip,camera-module-lens-name = "IR0147-50IRC-8M-F20";
port {
imx415_out1: endpoint {
remote-endpoint = <&mipi_in_ucam30>;
data-lanes = <1 2 3 4>;
};
};
};
aw8601_1: aw8601@c {
compatible = "awinic,aw8601";
status = "okay";
reg = <0x0c>;
rockchip,vcm-start-current = <56>;
rockchip,vcm-rated-current = <96>;
rockchip,vcm-step-mode = <4>;
rockchip,camera-module-index = <0>;
rockchip,camera-module-facing = "back";
};
otp_eeprom_1: otp_eeprom@50 {
compatible = "rk,otp_eeprom";
status = "okay";
reg = <0x50>;
};
ov50c40_dphy3: ov50c40@36 {
compatible = "ovti,ov50c40";
reg = <0x36>;
clocks = <&cru CLK_MIPI_CAMERAOUT_M2>;
clock-names = "xvclk";
power-domains = <&power RK3576_PD_VI>;
pinctrl-names = "default";
pinctrl-0 = <&cam_clk2m1_clk2>;
pwdn-gpios = <&gpio1 RK_PD4 GPIO_ACTIVE_LOW>;// must be high at last
reset-gpios = <&gpio2 RK_PD6 GPIO_ACTIVE_LOW>;// must be high at last
rockchip,camera-module-index = <0>;
rockchip,camera-module-facing = "back";
rockchip,camera-module-name = "HZGA06";
rockchip,camera-module-lens-name = "ZE0082C1-RK3568";
eeprom-ctrl = <&otp_eeprom_1>;
lens-focus = <&aw8601_1>;
port {
ov50c40_out1: endpoint {
remote-endpoint = <&mipi_in_ucam31>;
data-lanes = <1 2 3 4>;
};
};
};
};
&mipi3_csi2 {
status = "okay";
ports {
#address-cells = <1>;
#size-cells = <0>;
port@0 {
reg = <0>;
#address-cells = <1>;
#size-cells = <0>;
mipi3_csi2_input: endpoint@1 {
reg = <1>;
remote-endpoint = <&csidphy3_out>;
};
};
port@1 {
reg = <1>;
#address-cells = <1>;
#size-cells = <0>;
mipi3_csi2_output: endpoint@0 {
reg = <0>;
remote-endpoint = <&cif_mipi3_in>;
};
};
};
};
&rkcif {
status = "okay";
};
&rkcif_mipi_lvds3 {
status = "okay";
port {
cif_mipi3_in: endpoint {
remote-endpoint = <&mipi3_csi2_output>;
};
};
};
&rkcif_mipi_lvds3_sditf {
status = "okay";
port {
mipi_lvds3_sditf: endpoint {
remote-endpoint = <&isp_vir1>;
};
};
};
&rkcif_mmu {
status = "okay";
};
&rkisp {
status = "okay";
};
&rkisp_mmu {
status = "okay";
};
&rkisp_vir1 {
status = "okay";
port {
#address-cells = <1>;
#size-cells = <0>;
isp_vir1: endpoint@0 {
reg = <0>;
remote-endpoint = <&mipi_lvds3_sditf>;
};
};
};

File diff suppressed because it is too large Load Diff

View File

@@ -0,0 +1,729 @@
// SPDX-License-Identifier: (GPL-2.0+ OR MIT)
/*
* Copyright (c) 2025 Rockchip Electronics Co., Ltd.
*
*/
#include <dt-bindings/display/media-bus-format.h>
/ {
max96712_dcphy0_osc: max96712-dcphy0-oscillator {
compatible = "fixed-clock";
#clock-cells = <1>;
clock-frequency = <25000000>;
clock-output-names = "max96712-dcphy0-osc";
};
max96712_dcphy0_vcc1v2: max96712-dcphy0-vcc1v2 {
compatible = "regulator-fixed";
regulator-name = "max96712_dcphy0_vcc1v2";
regulator-boot-on;
regulator-always-on;
regulator-min-microvolt = <1200000>;
regulator-max-microvolt = <1200000>;
startup-delay-us = <850>;
vin-supply = <&vcc_2v0_pldo_s3>;
};
max96712_dcphy0_vcc1v8: max96712-dcphy0-vcc1v8 {
compatible = "regulator-fixed";
regulator-name = "max96712_dcphy0_vcc1v8";
regulator-boot-on;
regulator-always-on;
regulator-min-microvolt = <1800000>;
regulator-max-microvolt = <1800000>;
startup-delay-us = <200>;
vin-supply = <&vcc_2v0_pldo_s3>;
};
max96712_dcphy0_pwdn_regulator: max96712-dcphy0-pwdn-regulator {
compatible = "regulator-fixed";
regulator-name = "max96712_dcphy0_pwdn";
gpio = <&gpio2 RK_PA0 GPIO_ACTIVE_HIGH>;
pinctrl-names = "default";
pinctrl-0 = <&max96712_dcphy0_pwdn>;
enable-active-high;
startup-delay-us = <10000>;
off-on-delay-us = <5000>;
};
max96712_dcphy0_poc_regulator: max96712-dcphy0-poc-regulator {
compatible = "regulator-fixed";
regulator-name = "max96712_dcphy0_poc";
gpio = <&i2c7_nca9539_gpio 2 GPIO_ACTIVE_HIGH>;
enable-active-high;
startup-delay-us = <10000>;
off-on-delay-us = <5000>;
vin-supply = <&dcphy0_vcc12v_buck1>;
};
};
&csi2_dcphy0 {
status = "okay";
ports {
#address-cells = <1>;
#size-cells = <0>;
port@0 {
reg = <0>;
#address-cells = <1>;
#size-cells = <0>;
mipi_dcphy0_in_max96712: endpoint@1 {
reg = <1>;
remote-endpoint = <&max96712_dcphy0_out>;
data-lanes = <1 2 3 4>;
};
};
port@1 {
reg = <1>;
#address-cells = <1>;
#size-cells = <0>;
csidcphy0_out: endpoint@0 {
reg = <0>;
remote-endpoint = <&mipi0_csi2_input>;
};
};
};
};
&i2c2 {
max96712_dcphy0: max96712@29 {
compatible = "maxim4c,max96712";
status = "okay";
reg = <0x29>;
clock-names = "xvclk";
clocks = <&max96712_dcphy0_osc 0>;
pinctrl-names = "default";
pinctrl-0 = <&max96712_dcphy0_errb>, <&max96712_dcphy0_lock>;
power-domains = <&power RK3576_PD_VI>;
rockchip,grf = <&sys_grf>;
vcc1v2-supply = <&max96712_dcphy0_vcc1v2>;
vcc1v8-supply = <&max96712_dcphy0_vcc1v8>;
pwdn-supply = <&max96712_dcphy0_pwdn_regulator>;
lock-gpios = <&gpio2 RK_PA2 GPIO_ACTIVE_HIGH>;
rockchip,camera-module-index = <0>;
rockchip,camera-module-facing = "back";
rockchip,camera-module-name = "default";
rockchip,camera-module-lens-name = "default";
port {
max96712_dcphy0_out: endpoint {
remote-endpoint = <&mipi_dcphy0_in_max96712>;
data-lanes = <1 2 3 4>;
};
};
/* support mode config start */
support-mode-config {
status = "okay";
bus-format = <MEDIA_BUS_FMT_YUYV8_2X8>;
sensor-width = <1920>;
sensor-height = <1280>;
max-fps-numerator = <10000>;
max-fps-denominator = <300000>;
bpp = <16>;
link-freq-idx = <20>;
};
/* support mode config end */
/* serdes local device start */
serdes-local-device {
status = "okay";
/* GMSL LINK config start */
gmsl-links {
status = "okay";
link-vdd-ldo1-en = <1>;
link-vdd-ldo2-en = <1>;
// Link A: link-id = 0
gmsl-link-config-0 {
status = "okay";
link-id = <0>; // Link ID: 0/1/2/3
link-type = <1>; // 0: GMSL1, 1: GMSL2
link-rx-rate = <1>; // 0: 3GBPS, 1: 6GBPS
link-tx-rate = <0>; // 0: default for 187.5MBPS
link-remote-cam = <&max96712_dcphy0_cam0>; // remote camera
link-init-sequence {
seq-item-size = <5>; // reg-addr-len + reg-val-len * 2 + 1
reg-addr-len = <2>; // 1: 8bits, 2: 16bits
reg-val-len = <1>; // 1: 8bits, 2: 16bits, 3: 24bits
// reg_addr reg_val val_mask delay
init-sequence = [
14 D1 03 00 00 // VGAHiGain
14 45 00 00 00 // Disable SSC
];
};
};
// Link B: link-id = 1
gmsl-link-config-1 {
status = "okay";
link-id = <1>; // Link ID: 0/1/2/3
link-type = <1>; // 0: GMSL1, 1: GMSL2
link-rx-rate = <1>; // 0: 3GBPS, 1: 6GBPS
link-tx-rate = <0>; // 0: default for 187.5MBPS
link-remote-cam = <&max96712_dcphy0_cam1>; // remote camera
link-init-sequence {
seq-item-size = <5>; // reg-addr-len + reg-val-len * 2 + 1
reg-addr-len = <2>; // 1: 8bits, 2: 16bits
reg-val-len = <1>; // 1: 8bits, 2: 16bits, 3: 24bits
// reg_addr reg_val val_mask delay
init-sequence = [
15 D1 03 00 00 // VGAHiGain
15 45 00 00 00 // Disable SSC
];
};
};
// Link C: link-id = 2
gmsl-link-config-2 {
status = "okay";
link-id = <2>; // Link ID: 0/1/2/3
link-type = <1>; // 0: GMSL1, 1: GMSL2
link-rx-rate = <1>; // 0: 3GBPS, 1: 6GBPS
link-tx-rate = <0>; // 0: default for 187.5MBPS
link-remote-cam = <&max96712_dcphy0_cam2>; // remote camera
link-init-sequence {
seq-item-size = <5>; // reg-addr-len + reg-val-len * 2 + 1
reg-addr-len = <2>; // 1: 8bits, 2: 16bits
reg-val-len = <1>; // 1: 8bits, 2: 16bits, 3: 24bits
// reg_addr reg_val val_mask delay
init-sequence = [
16 D1 03 00 00 // VGAHiGain
16 45 00 00 00 // Disable SSC
];
};
};
// Link D: link-id = 3
gmsl-link-config-3 {
status = "okay";
link-id = <3>; // Link ID: 0/1/2/3
link-type = <1>; // 0: GMSL1, 1: GMSL2
link-rx-rate = <1>; // 0: 3GBPS, 1: 6GBPS
link-tx-rate = <0>; // 0: default for 187.5MBPS
link-remote-cam = <&max96712_dcphy0_cam3>; // remote camera
link-init-sequence {
seq-item-size = <5>; // reg-addr-len + reg-val-len * 2 + 1
reg-addr-len = <2>; // 1: 8bits, 2: 16bits
reg-val-len = <1>; // 1: 8bits, 2: 16bits, 3: 24bits
// reg_addr reg_val val_mask delay
init-sequence = [
17 D1 03 00 00 // VGAHiGain
17 45 00 00 00 // Disable SSC
];
};
};
};
/* GMSL LINK config end */
/* VIDEO PIPE config start */
video-pipes {
status = "okay";
// Video Pipe 0
video-pipe-config-0 {
status = "okay";
pipe-id = <0>; // Video Pipe ID: 0/1/2/3/4/5/6/7
pipe-idx = <2>; // Video Pipe X/Y/Z/U: 0/1/2/3
link-idx = <0>; // Link A/B/C/D: 0/1/2/3
pipe-init-sequence {
seq-item-size = <5>; // reg-addr-len + reg-val-len * 2 + 1
reg-addr-len = <2>; // 1: 8bits, 2: 16bits
reg-val-len = <1>; // 1: 8bits, 2: 16bits, 3: 24bits
// reg_addr reg_val val_mask delay
init-sequence = [
// Send YUV422, FS, and FE from Video Pipe 0 to Controller 1
09 0B 07 00 00 // Enable 0/1/2 SRC/DST Mappings
09 2D 15 00 00 // SRC/DST 0/1/2 -> CSI2 Controller 1;
// For the following MSB 2 bits = VC, LSB 6 bits = DT
09 0D 1e 00 00 // SRC0 VC = 0, DT = YUV422 8bit
09 0E 1e 00 00 // DST0 VC = 0, DT = YUV422 8bit
09 0F 00 00 00 // SRC1 VC = 0, DT = Frame Start
09 10 00 00 00 // DST1 VC = 0, DT = Frame Start
09 11 01 00 00 // SRC2 VC = 0, DT = Frame End
09 12 01 00 00 // DST2 VC = 0, DT = Frame End
];
};
};
// Video Pipe 1
video-pipe-config-1 {
status = "okay";
pipe-id = <1>; // Video Pipe 1: pipe-id = 1
pipe-idx = <2>; // Video Pipe X/Y/Z/U: 0/1/2/3
link-idx = <1>; // Link A/B/C/D: 0/1/2/3
pipe-init-sequence {
seq-item-size = <5>; // reg-addr-len + reg-val-len * 2 + 1
reg-addr-len = <2>; // 1: 8bits, 2: 16bits
reg-val-len = <1>; // 1: 8bits, 2: 16bits, 3: 24bits
// reg_addr reg_val val_mask delay
init-sequence = [
// Send YUV422, FS, and FE from Video Pipe 1 to Controller 1
09 4B 07 00 00 // Enable 0/1/2 SRC/DST Mappings
09 6D 15 00 00 // SRC/DST 0/1/2 -> CSI2 Controller 1;
// For the following MSB 2 bits = VC, LSB 6 bits = DT
09 4D 1e 00 00 // SRC0 VC = 0, DT = YUV422 8bit
09 4E 5e 00 00 // DST0 VC = 1, DT = YUV422 8bit
09 4F 00 00 00 // SRC1 VC = 0, DT = Frame Start
09 50 40 00 00 // DST1 VC = 1, DT = Frame Start
09 51 01 00 00 // SRC2 VC = 0, DT = Frame End
09 52 41 00 00 // DST2 VC = 1, DT = Frame End
];
};
};
// Video Pipe 2
video-pipe-config-2 {
status = "okay";
pipe-id = <2>; // Video Pipe ID: 0/1/2/3/4/5/6/7
pipe-idx = <2>; // Video Pipe X/Y/Z/U: 0/1/2/3
link-idx = <2>; // Link A/B/C/D: 0/1/2/3
pipe-init-sequence {
seq-item-size = <5>; // reg-addr-len + reg-val-len * 2 + 1
reg-addr-len = <2>; // 1: 8bits, 2: 16bits
reg-val-len = <1>; // 1: 8bits, 2: 16bits, 3: 24bits
// reg_addr reg_val val_mask delay
init-sequence = [
// Send YUV422, FS, and FE from Video Pipe 2 to Controller 1
09 8B 07 00 00 // Enable 0/1/2 SRC/DST Mappings
09 AD 15 00 00 // SRC/DST 0/1/2 -> CSI2 Controller 1;
// For the following MSB 2 bits = VC, LSB 6 bits = DT
09 8D 1e 00 00 // SRC0 VC = 0, DT = YUV422 8bit
09 8E 9e 00 00 // DST0 VC = 2, DT = YUV422 8bit
09 8F 00 00 00 // SRC1 VC = 0, DT = Frame Start
09 90 80 00 00 // DST1 VC = 2, DT = Frame Start
09 91 01 00 00 // SRC2 VC = 0, DT = Frame End
09 92 81 00 00 // DST2 VC = 2, DT = Frame End
];
};
};
// Video Pipe 3
video-pipe-config-3 {
status = "okay";
pipe-id = <3>; // Video Pipe ID: 0/1/2/3/4/5/6/7
pipe-idx = <2>; // Video Pipe X/Y/Z/U: 0/1/2/3
link-idx = <3>; // Link A/B/C/D: 0/1/2/3
pipe-init-sequence {
seq-item-size = <5>; // reg-addr-len + reg-val-len * 2 + 1
reg-addr-len = <2>; // 1: 8bits, 2: 16bits
reg-val-len = <1>; // 1: 8bits, 2: 16bits, 3: 24bits
// reg_addr reg_val val_mask delay
init-sequence = [
// Send YUV422, FS, and FE from Video Pipe 3 to Controller 1
09 CB 07 00 00 // Enable 0/1/2 SRC/DST Mappings
09 ED 15 00 00 // SRC/DST 0/1/2 -> CSI2 Controller 1;
// For the following MSB 2 bits = VC, LSB 6 bits = DT
09 CD 1e 00 00 // SRC0 VC = 0, DT = YUV422 8bit
09 CE de 00 00 // DST0 VC = 3, DT = YUV422 8bit
09 CF 00 00 00 // SRC1 VC = 0, DT = Frame Start
09 D0 c0 00 00 // DST1 VC = 3, DT = Frame Start
09 D1 01 00 00 // SRC2 VC = 0, DT = Frame End
09 D2 c1 00 00 // DST2 VC = 3, DT = Frame End
];
};
};
};
/* VIDEO PIPE config end */
/* MIPI TXPHY config start */
mipi-txphys {
status = "okay";
phy-mode = <0>; // 0: 4Lanes, 1: 2Lanes
phy-force-clock-out = <1>; // 1: default for force clock out
phy-force-clk0-en = <1>; // provide MIPI clock: 0 = PHY1, 1 = PHY0
phy-force-clk3-en = <0>; // provide MIPI clock: 0 = PHY2, 1 = PHY3
// MIPI TXPHY A: phy-id = 0
mipi-txphy-config-0 {
status = "okay";
phy-id = <0>; // MIPI TXPHY ID: 0/1/2/3
phy-type = <0>; // 0: DPHY, 1: CPHY
auto-deskew = <0x80>;
data-lane-num = <4>;
data-lane-map = <0x4>;
vc-ext-en = <0>;
};
// MIPI TXPHY B: phy-id = 1
mipi-txphy-config-1 {
status = "okay";
phy-id = <1>; // MIPI TXPHY ID: 0/1/2/3
phy-type = <0>; // 0: DPHY, 1: CPHY
auto-deskew = <0x80>;
data-lane-num = <4>;
data-lane-map = <0xe>;
vc-ext-en = <0>;
};
};
/* MIPI TXPHY config end */
/* local device extra init sequence */
extra-init-sequence {
status = "disabled";
seq-item-size = <5>; // reg-addr-len + reg-val-len * 2 + 1
reg-addr-len = <2>; // 1: 8bits, 2: 16bits
reg-val-len = <1>; // 1: 8bits, 2: 16bits, 3: 24bits
// reg_addr reg_val val_mask delay
init-sequence = [
// common init sequence such as fsync / gpio and so on
];
};
};
/* serdes local device end */
/* i2c-mux start */
i2c-mux {
#address-cells = <1>;
#size-cells = <0>;
i2c@0 {
#address-cells = <1>;
#size-cells = <0>;
reg = <0>;
// Note: Serializer node defined before camera node
max96712_dcphy0_ser0: max96717@51 {
compatible = "maxim,ser,max96717";
reg = <0x51>;
ser-i2c-addr-def = <0x40>;
ser-init-sequence {
seq-item-size = <5>; // reg-addr-len + reg-val-len * 2 + 1
reg-addr-len = <2>; // 1: 8bits, 2: 16bits
reg-val-len = <1>; // 1: 8bits, 2: 16bits, 3: 24bits
// reg_addr reg_val val_mask delay
init-sequence = [
02 BE 00 00 01 // MFP0 GPIO_OUT = 0: MFP0 output is driven to 0
03 02 10 00 00 // Improve CMU voltage performance to improve link robustness
14 17 00 00 00 // RLMS17 = 0x00: disable AGC/DFE adaptation
14 32 7f 00 00 // RLMS32 = 0x7F: change OSN loop mode
03 F0 59 00 00 // REFGEN_PREDEF_FREQ_ALT = 1: Alternative table, REFGEN_PREDEF_FREQ = 0x1: 24MHz
00 03 03 00 00 // RCLKSEL = 0x3: Reference PLL output
00 06 B1 00 01 // RCLKEN = 1: RCLK output is enabled
02 BF 40 00 00 // MFP0 PULL_UPDN_SEL = 1: Pullup
02 BE 10 00 01 // MFP0 GPIO_OUT = 1: MFP0 output is driven to 1
];
};
};
max96712_dcphy0_cam0: ox03j10@31 {
compatible = "maxim,ovti,ox03j10";
reg = <0x31>;
cam-i2c-addr-def = <0x36>;
cam-remote-ser = <&max96712_dcphy0_ser0>; // remote serializer
poc-supply = <&max96712_dcphy0_poc_regulator>;
rockchip,camera-module-index = <0>;
rockchip,camera-module-facing = "back";
rockchip,camera-module-name = "default";
rockchip,camera-module-lens-name = "default";
/* port config start */
port {
max96712_dcphy0_cam0_out: endpoint {
data-lanes = <1 2 3 4>;
};
};
/* port config end */
};
};
i2c@1 {
#address-cells = <1>;
#size-cells = <0>;
reg = <1>;
// Note: Serializer node defined before camera node
max96712_dcphy0_ser1: max96717@52 {
compatible = "maxim,ser,max96717";
reg = <0x52>;
ser-i2c-addr-def = <0x40>;
ser-init-sequence {
seq-item-size = <5>; // reg-addr-len + reg-val-len * 2 + 1
reg-addr-len = <2>; // 1: 8bits, 2: 16bits
reg-val-len = <1>; // 1: 8bits, 2: 16bits, 3: 24bits
// reg_addr reg_val val_mask delay
init-sequence = [
02 BE 00 00 01 // MFP0 GPIO_OUT = 0: MFP0 output is driven to 0
03 02 10 00 00 // Improve CMU voltage performance to improve link robustness
14 17 00 00 00 // RLMS17 = 0x00: disable AGC/DFE adaptation
14 32 7f 00 00 // RLMS32 = 0x7F: change OSN loop mode
03 F0 59 00 00 // REFGEN_PREDEF_FREQ_ALT = 1: Alternative table, REFGEN_PREDEF_FREQ = 0x1: 24MHz
00 03 03 00 00 // RCLKSEL = 0x3: Reference PLL output
00 06 B1 00 01 // RCLKEN = 1: RCLK output is enabled
02 BF 40 00 00 // MFP0 PULL_UPDN_SEL = 1: Pullup
02 BE 10 00 01 // MFP0 GPIO_OUT = 1: MFP0 output is driven to 1
];
};
};
max96712_dcphy0_cam1: ox03j10@32 {
compatible = "maxim,ovti,ox03j10";
reg = <0x32>;
cam-i2c-addr-def = <0x36>;
cam-remote-ser = <&max96712_dcphy0_ser1>; // remote serializer
poc-supply = <&max96712_dcphy0_poc_regulator>;
rockchip,camera-module-index = <1>;
rockchip,camera-module-facing = "back";
rockchip,camera-module-name = "default";
rockchip,camera-module-lens-name = "default";
/* port config start */
port {
max96712_dcphy0_cam1_out: endpoint {
data-lanes = <1 2 3 4>;
};
};
/* port config end */
};
};
i2c@2 {
#address-cells = <1>;
#size-cells = <0>;
reg = <2>;
// Note: Serializer node defined before camera node
max96712_dcphy0_ser2: max96717@53 {
compatible = "maxim,ser,max96717";
reg = <0x53>;
ser-i2c-addr-def = <0x40>;
ser-init-sequence {
seq-item-size = <5>; // reg-addr-len + reg-val-len * 2 + 1
reg-addr-len = <2>; // 1: 8bits, 2: 16bits
reg-val-len = <1>; // 1: 8bits, 2: 16bits, 3: 24bits
// reg_addr reg_val val_mask delay
init-sequence = [
02 BE 00 00 01 // MFP0 GPIO_OUT = 0: MFP0 output is driven to 0
03 02 10 00 00 // Improve CMU voltage performance to improve link robustness
14 17 00 00 00 // RLMS17 = 0x00: disable AGC/DFE adaptation
14 32 7f 00 00 // RLMS32 = 0x7F: change OSN loop mode
03 F0 59 00 00 // REFGEN_PREDEF_FREQ_ALT = 1: Alternative table, REFGEN_PREDEF_FREQ = 0x1: 24MHz
00 03 03 00 00 // RCLKSEL = 0x3: Reference PLL output
00 06 B1 00 01 // RCLKEN = 1: RCLK output is enabled
02 BF 40 00 00 // MFP0 PULL_UPDN_SEL = 1: Pullup
02 BE 10 00 01 // MFP0 GPIO_OUT = 1: MFP0 output is driven to 1
];
};
};
max96712_dcphy0_cam2: ox03j10@33 {
compatible = "maxim,ovti,ox03j10";
reg = <0x33>;
cam-i2c-addr-def = <0x36>;
cam-remote-ser = <&max96712_dcphy0_ser2>; // remote serializer
poc-supply = <&max96712_dcphy0_poc_regulator>;
rockchip,camera-module-index = <2>;
rockchip,camera-module-facing = "back";
rockchip,camera-module-name = "default";
rockchip,camera-module-lens-name = "default";
/* port config start */
port {
max96712_dcphy0_cam2_out: endpoint {
data-lanes = <1 2 3 4>;
};
};
/* port config end */
};
};
i2c@3 {
#address-cells = <1>;
#size-cells = <0>;
reg = <3>;
// Note: Serializer node defined before camera node
max96712_dcphy0_ser3: max96717@54 {
compatible = "maxim,ser,max96717";
reg = <0x54>;
ser-i2c-addr-def = <0x40>;
ser-init-sequence {
seq-item-size = <5>; // reg-addr-len + reg-val-len * 2 + 1
reg-addr-len = <2>; // 1: 8bits, 2: 16bits
reg-val-len = <1>; // 1: 8bits, 2: 16bits, 3: 24bits
// reg_addr reg_val val_mask delay
init-sequence = [
02 BE 00 00 01 // MFP0 GPIO_OUT = 0: MFP0 output is driven to 0
03 02 10 00 00 // Improve CMU voltage performance to improve link robustness
14 17 00 00 00 // RLMS17 = 0x00: disable AGC/DFE adaptation
14 32 7f 00 00 // RLMS32 = 0x7F: change OSN loop mode
03 F0 59 00 00 // REFGEN_PREDEF_FREQ_ALT = 1: Alternative table, REFGEN_PREDEF_FREQ = 0x1: 24MHz
00 03 03 00 00 // RCLKSEL = 0x3: Reference PLL output
00 06 B1 00 01 // RCLKEN = 1: RCLK output is enabled
02 BF 40 00 00 // MFP0 PULL_UPDN_SEL = 1: Pullup
02 BE 10 00 01 // MFP0 GPIO_OUT = 1: MFP0 output is driven to 1
];
};
};
max96712_dcphy0_cam3: ox03j10@34 {
compatible = "maxim,ovti,ox03j10";
reg = <0x34>;
cam-i2c-addr-def = <0x36>;
cam-remote-ser = <&max96712_dcphy0_ser3>; // remote serializer
poc-supply = <&max96712_dcphy0_poc_regulator>;
rockchip,camera-module-index = <3>;
rockchip,camera-module-facing = "back";
rockchip,camera-module-name = "default";
rockchip,camera-module-lens-name = "default";
/* port config start */
port {
max96712_dcphy0_cam3_out: endpoint {
data-lanes = <1 2 3 4>;
};
};
/* port config end */
};
};
};
/* i2c-mux end */
};
};
&mipi0_csi2 {
status = "okay";
ports {
#address-cells = <1>;
#size-cells = <0>;
port@0 {
reg = <0>;
#address-cells = <1>;
#size-cells = <0>;
mipi0_csi2_input: endpoint@1 {
reg = <1>;
remote-endpoint = <&csidcphy0_out>;
};
};
port@1 {
reg = <1>;
#address-cells = <1>;
#size-cells = <0>;
mipi0_csi2_output: endpoint@0 {
reg = <0>;
remote-endpoint = <&cif_mipi0_in>;
};
};
};
};
&rkcif_mipi_lvds {
status = "okay";
/* parameters for do cif reset detecting:
* index0: monitor mode,
0 for idle,
1 for continue,
2 for trigger,
3 for hotplug (for nextchip)
* index1: the frame id to start timer,
min is 2
* index2: frame num of monitoring cycle
* index3: err time for keep monitoring
after finding out err (ms)
* index4: csi2 err reference val for resetting
*/
rockchip,cif-monitor = <3 2 1 1000 5>;
port {
cif_mipi0_in: endpoint {
remote-endpoint = <&mipi0_csi2_output>;
};
};
};
&rkcif {
status = "okay";
rockchip,android-usb-camerahal-enable;
};
&rkcif_mmu {
status = "okay";
};
&pinctrl {
max96712-dcphy0 {
max96712_dcphy0_pwdn: max96712-dcphy0-pwdn {
rockchip,pins = <2 RK_PA0 RK_FUNC_GPIO &pcfg_output_low>;
};
max96712_dcphy0_errb: max96712-dcphy0-errb {
rockchip,pins = <2 RK_PA1 RK_FUNC_GPIO &pcfg_pull_none_smt>;
};
max96712_dcphy0_lock: max96712-dcphy0-lock {
rockchip,pins = <2 RK_PA2 RK_FUNC_GPIO &pcfg_pull_none_smt>;
};
};
};

View File

@@ -0,0 +1,576 @@
// SPDX-License-Identifier: (GPL-2.0+ OR MIT)
/*
* Copyright (c) 2025 Rockchip Electronics Co., Ltd.
*
*/
/dts-v1/;
#include "rk3576.dtsi"
#include "rk3576-vehicle-evb-v20.dtsi"
#include "rk3576-vehicle-evb-v20-nca9539-io-expander.dtsi"
#include "rk3576-vehicle-evb-v20-serdes-mfd-display-maxim.dtsi"
#include "rk3576-vehicle-evb-v20-maxim-max96712-dphy0-ox03j10.dtsi"
#include "rk3576-vehicle-evb-v20-maxim-max96712-dphy3-sc233at.dtsi"
#include "rk3576-android.dtsi"
/delete-node/ &vcc5v0_host_usb30;
/ {
model = "Rockchip RK3576 VEHICLE EVB V21 Board";
compatible = "rockchip,rk3576-vehicle-evb-v21", "rockchip,rk3576";
chosen: chosen {
bootargs = "earlycon=uart8250,mmio32,0x2ad40000 console=ttyFIQ0 rcupdate.rcu_expedited=1 rcu_nocbs=all spidev.bufsiz=131072";
};
vehicle_dummy: vehicle-dummy {
status = "okay";
compatible = "rockchip,vehicle-dummy-adc";
io-channels = <&saradc 4>, <&saradc 5>, <&saradc 6>;
io-channel-names = "gear", "turn_left", "turn_right";
};
vcc5v0_buck: vcc5v0-buck {
compatible = "regulator-fixed";
regulator-name = "vcc5v0_buck";
regulator-boot-on;
regulator-always-on;
regulator-min-microvolt = <5000000>;
regulator-max-microvolt = <5000000>;
enable-active-high;
gpio = <&gpio0 RK_PD3 GPIO_ACTIVE_HIGH>;
vin-supply = <&vcc12v_dcin>;
pinctrl-names = "default";
pinctrl-0 = <&vcc5v0_buck_en>;
startup-delay-us = <2500>;
off-on-delay-us = <1500>;
regulator-state-mem {
regulator-on-in-suspend;
regulator-suspend-microvolt = <5000000>;
};
};
cluster_power_buck: cluster_power-buck {
compatible = "regulator-fixed";
regulator-name = "cluster_power_buck";
regulator-boot-on;
regulator-always-on;
regulator-min-microvolt = <1800000>;
regulator-max-microvolt = <1800000>;
//enable-active-high;
gpio = <&gpio0 RK_PA5 GPIO_ACTIVE_LOW>;
vin-supply = <&vcc_1v8_s0>;
pinctrl-names = "default";
pinctrl-0 = <&cluster_buck_en>;
regulator-state-mem {
regulator-off-in-suspend;
regulator-suspend-microvolt = <1800000>;
};
};
usb_otg_vcc5v_buck: usb_otg_vcc5v-buck {
compatible = "regulator-fixed";
regulator-name = "usb_otg_vcc5v_buck";
regulator-boot-on;
regulator-always-on;
regulator-min-microvolt = <5000000>;
regulator-max-microvolt = <5000000>;
//enable-active-high;
gpio = <&i2c0_nca9539_gpio 0 GPIO_ACTIVE_HIGH>;
vin-supply = <&vcc5v0_buck>;
regulator-state-mem {
regulator-off-in-suspend;
regulator-suspend-microvolt = <5000000>;
};
};
usb_host_vcc5v_buck: usb_host_vcc5v-buck {
compatible = "regulator-fixed";
regulator-name = "usb_host_vcc5v_buck";
//regulator-boot-on;
//regulator-always-on;
regulator-min-microvolt = <5000000>;
regulator-max-microvolt = <5000000>;
enable-active-high;
gpio = <&i2c0_nca9539_gpio 1 GPIO_ACTIVE_HIGH>;
vin-supply = <&vcc5v0_buck>;
regulator-state-mem {
regulator-off-in-suspend;
regulator-suspend-microvolt = <5000000>;
};
};
lcd1_vcc12v_buck: lcd1_vcc12v-buck {
compatible = "regulator-fixed";
regulator-name = "lcd1_vcc12v_buck";
regulator-boot-on;
regulator-always-on;
regulator-min-microvolt = <12000000>;
regulator-max-microvolt = <12000000>;
enable-active-high;
gpio = <&i2c0_nca9539_gpio 2 GPIO_ACTIVE_HIGH>;
vin-supply = <&vcc12v_dcin>;
regulator-state-mem {
regulator-off-in-suspend;
regulator-suspend-microvolt = <12000000>;
};
};
lcd2_vcc12v_buck: lcd2_vcc12v-buck {
compatible = "regulator-fixed";
regulator-name = "lcd2_vcc12v_buck";
regulator-boot-on;
regulator-always-on;
regulator-min-microvolt = <12000000>;
regulator-max-microvolt = <12000000>;
enable-active-high;
gpio = <&i2c0_nca9539_gpio 3 GPIO_ACTIVE_HIGH>;
vin-supply = <&vcc12v_dcin>;
regulator-state-mem {
regulator-off-in-suspend;
regulator-suspend-microvolt = <12000000>;
};
};
lcd1_ser_vcc5v_buck: lcd1_ser_vcc5v-buck {
compatible = "regulator-fixed";
regulator-name = "lcd1_ser_vcc5v_buck";
regulator-boot-on;
regulator-always-on;
regulator-min-microvolt = <5000000>;
regulator-max-microvolt = <5000000>;
enable-active-high;
gpio = <&i2c0_nca9539_gpio 4 GPIO_ACTIVE_HIGH>;
vin-supply = <&vcc5v0_buck>;
regulator-state-mem {
regulator-off-in-suspend;
regulator-suspend-microvolt = <5000000>;
};
};
lcd2_ser_vcc5v_buck: lcd2_ser_vcc5v-buck {
compatible = "regulator-fixed";
regulator-name = "lcd2_ser_vcc5v_buck";
regulator-boot-on;
regulator-always-on;
regulator-min-microvolt = <5000000>;
regulator-max-microvolt = <5000000>;
enable-active-high;
gpio = <&i2c0_nca9539_gpio 5 GPIO_ACTIVE_HIGH>;
vin-supply = <&vcc5v0_buck>;
regulator-state-mem {
regulator-off-in-suspend;
regulator-suspend-microvolt = <5000000>;
};
};
adsp_vcc12v_buck: adsp_vcc12v-buck {
compatible = "regulator-fixed";
regulator-name = "adsp_vcc12v_buck";
regulator-boot-on;
regulator-always-on;
regulator-min-microvolt = <12000000>;
regulator-max-microvolt = <12000000>;
enable-active-high;
gpio = <&i2c0_nca9539_gpio 6 GPIO_ACTIVE_HIGH>;
vin-supply = <&vcc12v_dcin>;
regulator-state-mem {
regulator-off-in-suspend;
regulator-suspend-microvolt = <12000000>;
};
};
lcd3_vcc12v_buck: lcd3_vcc12v-buck {
compatible = "regulator-fixed";
regulator-name = "lcd3_vcc12v_buck";
regulator-boot-on;
regulator-always-on;
regulator-min-microvolt = <12000000>;
regulator-max-microvolt = <12000000>;
enable-active-high;
gpio = <&i2c7_nca9539_gpio 0 GPIO_ACTIVE_HIGH>;
vin-supply = <&vcc12v_dcin>;
regulator-state-mem {
regulator-off-in-suspend;
regulator-suspend-microvolt = <12000000>;
};
};
lcd3_vcc5v_buck: lcd3_vcc5v-buck {
compatible = "regulator-fixed";
regulator-name = "lcd3_vcc5v_buck";
regulator-boot-on;
regulator-always-on;
regulator-min-microvolt = <5000000>;
regulator-max-microvolt = <5000000>;
enable-active-high;
gpio = <&i2c7_nca9539_gpio 1 GPIO_ACTIVE_HIGH>;
vin-supply = <&vcc12v_dcin>;
regulator-state-mem {
regulator-off-in-suspend;
regulator-suspend-microvolt = <12000000>;
};
};
dcphy0_vcc12v_buck1: dcphy0_vcc12v-buck1 {
compatible = "regulator-fixed";
regulator-name = "dcphy0_vcc12v_buck1";
regulator-boot-on;
regulator-min-microvolt = <12000000>;
regulator-max-microvolt = <12000000>;
enable-active-high;
gpio = <&i2c7_nca9539_gpio 3 GPIO_ACTIVE_HIGH>;
startup-delay-us = <2000>;
off-on-delay-us = <16000>;
vin-supply = <&vcc12v_dcin>;
regulator-state-mem {
regulator-off-in-suspend;
regulator-suspend-microvolt = <12000000>;
};
};
dcphy0_vcc12v_buck2: dcphy0_vcc12v-buck2 {
compatible = "regulator-fixed";
regulator-name = "dcphy0_vcc12v_buck2";
regulator-boot-on;
regulator-min-microvolt = <12000000>;
regulator-max-microvolt = <12000000>;
enable-active-high;
gpio = <&i2c7_nca9539_gpio 4 GPIO_ACTIVE_HIGH>;
startup-delay-us = <2000>;
off-on-delay-us = <16000>;
vin-supply = <&vcc12v_dcin>;
regulator-state-mem {
regulator-off-in-suspend;
regulator-suspend-microvolt = <12000000>;
};
};
dcphy0_vcc12v_buck3: dcphy0_vcc12v-buck3 {
compatible = "regulator-fixed";
regulator-name = "dcphy0_vcc12v_buck3";
regulator-boot-on;
regulator-min-microvolt = <12000000>;
regulator-max-microvolt = <12000000>;
enable-active-high;
gpio = <&i2c7_nca9539_gpio 5 GPIO_ACTIVE_HIGH>;
startup-delay-us = <2000>;
off-on-delay-us = <16000>;
vin-supply = <&vcc12v_dcin>;
regulator-state-mem {
regulator-off-in-suspend;
regulator-suspend-microvolt = <12000000>;
};
};
dcphy0_vcc12v_buck4: dcphy0_vcc12v-buck4 {
compatible = "regulator-fixed";
regulator-name = "dcphy0_vcc12v_buck4";
regulator-boot-on;
regulator-min-microvolt = <12000000>;
regulator-max-microvolt = <12000000>;
enable-active-high;
gpio = <&i2c7_nca9539_gpio 6 GPIO_ACTIVE_HIGH>;
startup-delay-us = <2000>;
off-on-delay-us = <16000>;
vin-supply = <&vcc12v_dcin>;
regulator-state-mem {
regulator-off-in-suspend;
regulator-suspend-microvolt = <12000000>;
};
};
dphy0_vcc12v_buck1: dphy0_vcc12v-buck1 {
compatible = "regulator-fixed";
regulator-name = "dphy0_vcc12v_buck1";
regulator-boot-on;
regulator-min-microvolt = <12000000>;
regulator-max-microvolt = <12000000>;
enable-active-high;
gpio = <&i2c7_nca9539_gpio 7 GPIO_ACTIVE_HIGH>;
startup-delay-us = <2000>;
off-on-delay-us = <16000>;
vin-supply = <&vcc12v_dcin>;
regulator-state-mem {
regulator-off-in-suspend;
regulator-suspend-microvolt = <12000000>;
};
};
dphy0_vcc12v_buck2: dphy0_vcc12v-buck2 {
compatible = "regulator-fixed";
regulator-name = "dphy0_vcc12v_buck2";
regulator-boot-on;
regulator-min-microvolt = <12000000>;
regulator-max-microvolt = <12000000>;
enable-active-high;
gpio = <&i2c7_nca9539_gpio 8 GPIO_ACTIVE_HIGH>;
startup-delay-us = <2000>;
off-on-delay-us = <16000>;
vin-supply = <&vcc12v_dcin>;
regulator-state-mem {
regulator-off-in-suspend;
regulator-suspend-microvolt = <12000000>;
};
};
dphy0_vcc12v_buck3: dphy0_vcc12v-buck3 {
compatible = "regulator-fixed";
regulator-name = "dphy0_vcc12v_buck3";
regulator-boot-on;
regulator-min-microvolt = <12000000>;
regulator-max-microvolt = <12000000>;
enable-active-high;
gpio = <&i2c7_nca9539_gpio 9 GPIO_ACTIVE_HIGH>;
startup-delay-us = <2000>;
off-on-delay-us = <16000>;
vin-supply = <&vcc12v_dcin>;
regulator-state-mem {
regulator-off-in-suspend;
regulator-suspend-microvolt = <12000000>;
};
};
dphy0_vcc12v_buck4: dphy0_vcc12v-buck4 {
compatible = "regulator-fixed";
regulator-name = "dphy0_vcc12v_buck4";
regulator-boot-on;
regulator-min-microvolt = <12000000>;
regulator-max-microvolt = <12000000>;
enable-active-high;
gpio = <&i2c7_nca9539_gpio 10 GPIO_ACTIVE_HIGH>;
startup-delay-us = <2000>;
off-on-delay-us = <16000>;
vin-supply = <&vcc12v_dcin>;
regulator-state-mem {
regulator-off-in-suspend;
regulator-suspend-microvolt = <12000000>;
};
};
dphy3_vcc12v_buck1: dphy3_vcc12v-buck1 {
compatible = "regulator-fixed";
regulator-name = "dphy3_vcc12v_buck1";
regulator-boot-on;
regulator-min-microvolt = <12000000>;
regulator-max-microvolt = <12000000>;
enable-active-high;
gpio = <&i2c7_nca9539_gpio 11 GPIO_ACTIVE_HIGH>;
startup-delay-us = <2000>;
off-on-delay-us = <16000>;
vin-supply = <&vcc12v_dcin>;
regulator-state-mem {
regulator-off-in-suspend;
regulator-suspend-microvolt = <12000000>;
};
};
dphy3_vcc12v_buck2: dphy3_vcc12v-buck2 {
compatible = "regulator-fixed";
regulator-name = "dphy3_vcc12v_buck2";
regulator-boot-on;
regulator-min-microvolt = <12000000>;
regulator-max-microvolt = <12000000>;
enable-active-high;
gpio = <&i2c7_nca9539_gpio 12 GPIO_ACTIVE_HIGH>;
startup-delay-us = <2000>;
off-on-delay-us = <16000>;
vin-supply = <&vcc12v_dcin>;
regulator-state-mem {
regulator-off-in-suspend;
regulator-suspend-microvolt = <12000000>;
};
};
dphy3_vcc12v_buck3: dphy3_vcc12v-buck3 {
compatible = "regulator-fixed";
regulator-name = "dphy3_vcc12v_buck3";
regulator-boot-on;
regulator-min-microvolt = <12000000>;
regulator-max-microvolt = <12000000>;
enable-active-high;
gpio = <&i2c7_nca9539_gpio 13 GPIO_ACTIVE_HIGH>;
startup-delay-us = <2000>;
off-on-delay-us = <16000>;
vin-supply = <&vcc12v_dcin>;
regulator-state-mem {
regulator-off-in-suspend;
regulator-suspend-microvolt = <12000000>;
};
};
dphy3_vcc12v_buck4: dphy3_vcc12v-buck4 {
compatible = "regulator-fixed";
regulator-name = "dphy3_vcc12v_buck4";
regulator-boot-on;
regulator-min-microvolt = <12000000>;
regulator-max-microvolt = <12000000>;
enable-active-high;
gpio = <&i2c7_nca9539_gpio 14 GPIO_ACTIVE_HIGH>;
startup-delay-us = <2000>;
off-on-delay-us = <16000>;
vin-supply = <&vcc12v_dcin>;
regulator-state-mem {
regulator-off-in-suspend;
regulator-suspend-microvolt = <12000000>;
};
};
};
&dfi {
status = "disabled";
};
&dmc {
status = "disabled";
};
&gmac1 {
status = "disabled";
};
&hym8563 {
status = "disabled";
};
&i2c2 {
status = "okay";
pinctrl-names = "default";
pinctrl-0 = <&i2c2m0_xfer>;
};
/*edp*/
&i2c3_max96752 {
use-reg-check-work;
vpower-supply = <&lcd1_vcc12v_buck>;
};
/*edp touch*/
&i2c3_himax {
himax,irq-gpio = <&gpio0 RK_PB6 IRQ_TYPE_EDGE_FALLING>;
};
/*dp*/
&i2c5_max96745 {
lock-gpios = <&gpio0 RK_PC5 GPIO_ACTIVE_HIGH>;
};
&i2c5_ilitek {
interrupt-parent = <&gpio4>;
interrupts = <RK_PA0 IRQ_TYPE_LEVEL_LOW>;
};
/*dp*/
&i2c5_max96752 {
use-reg-check-work;
vpower-supply = <&lcd2_vcc12v_buck>;
};
&i2c8_max96789 {
route-enable;
};
/*dsi*/
&i2c8_max96752 {
use-reg-check-work;
vpower-supply = <&lcd3_vcc12v_buck>;
};
&dp2lvds_backlight0 {
pwms = <&pwm2_8ch_7 0 25000 0>;
};
&edp2lvds_backlight0 {
pwms = <&pwm0_2ch_0 0 25000 0>;
};
/* edp->serdes->lvds_panel */
&pwm0_2ch_0 {
pinctrl-0 = <&pwm0m3_ch0>;
};
/* dp->serdes->lvds_panel */
&pwm2_8ch_7 {
pinctrl-0 = <&pwm2m3_ch7>;
};
&pinctrl {
touch {
//dsi-i2c8
touch_gpio_dsi: touch-gpio-dsi {
rockchip,pins =
<3 RK_PA3 RK_FUNC_GPIO &pcfg_pull_up>;
};
//dp-i2c5
touch_gpio_dp: touch-gpio-dp {
rockchip,pins = <4 RK_PA0 RK_FUNC_GPIO &pcfg_pull_up>;
};
//edp0-i2c3
touch_gpio_edp: touch-gpio-edp {
rockchip,pins =
<0 RK_PB6 RK_FUNC_GPIO &pcfg_pull_up>;
};
};
vcc5v0-buck {
vcc5v0_buck_en: vcc5v0-buck-en {
rockchip,pins = <0 RK_PD3 RK_FUNC_GPIO &pcfg_pull_none>;
};
};
cluster-buck {
cluster_buck_en: cluster-buck-en {
rockchip,pins = <0 RK_PA5 RK_FUNC_GPIO &pcfg_pull_down>;
};
};
};
&rkvpss {
status = "okay";
};
&rkvpss_mmu {
status = "okay";
};
&rkvpss_vir0 {
status = "okay";
};
&route_dsi {
status = "okay";
};
&sdmmc {
status = "disabled";
};
&ufs {
status = "disabled";
};
&u2phy0 {
status = "okay";
};
&u2phy0_otg {
//vbus-supply = <&usb_otg_vcc5v_buck>;
status = "okay";
};
&u2phy1_otg {
phy-supply = <&usb_host_vcc5v_buck>;
status = "okay";
};
&usbdp_phy {
maximum-speed = "high-speed";
status = "okay";
};
&usb_drd1_dwc3 {
snps,dis_u2_susphy_quirk;
snps,usb2-lpm-disable;
status = "okay";
};

View File

@@ -296,6 +296,7 @@
reset-delay-ms = <10>;
enable-delay-ms = <10>;
prepare-delay-ms = <10>;
init-delay-ms = <10>;
unprepare-delay-ms = <10>;
disable-delay-ms = <60>;
width-mm = <68>;
@@ -630,6 +631,7 @@
reset-delay-ms = <10>;
enable-delay-ms = <10>;
prepare-delay-ms = <10>;
init-delay-ms = <10>;
unprepare-delay-ms = <10>;
disable-delay-ms = <10>;
width-mm = <68>;

View File

@@ -0,0 +1,24 @@
// SPDX-License-Identifier: (GPL-2.0+ OR MIT)
/*
* Copyright (c) 2025 Rockchip Electronics Co., Ltd.
*/
#include "rv1126b-evb1-v10.dts"
#include "rv1126b-fastboot-emmc.dtsi"
/ {
model = "Rockchip RV1126B EVB1 V10 Arm64 Fastboot Board";
compatible = "rockchip,rv1126b-evb1-v10-fastboot", "rockchip,rv1126b";
chosen {
bootargs = "loglevel=0 initcall_debug=0 earlycon=uart8250,mmio32,0x20810000 console=ttyFIQ0 root=/dev/rd0 rootfstype=erofs rootflags=dax snd_soc_core.prealloc_buffer_size_kbytes=16 coherent_pool=32K";
};
};
&ramdisk_r {
reg = <0x48c40000 (40 * 0x00100000)>;
};
&ramdisk_c {
reg = <0x4b440000 (20 * 0x00100000)>;
};

View File

@@ -0,0 +1,37 @@
// SPDX-License-Identifier: (GPL-2.0+ OR MIT)
/*
* Copyright (c) 2025 Rockchip Electronics Co., Ltd.
*/
/dts-v1/;
#include "rv1126b-evb1-v10.dts"
#include "rv1126b-fastboot-spi-nand.dtsi"
/ {
model = "Rockchip RV1126B EVB1 V10 Arm64 Board";
compatible = "rockchip,rv1126b-evb1-v10-fastboot-spi-nand", "rockchip,rv1126b";
chosen {
bootargs = "loglevel=0 initcall_debug=0 earlycon=uart8250,mmio32,0x20810000 console=ttyFIQ0 root=/dev/rd0 rootfstype=erofs rootflags=dax snd_soc_core.prealloc_buffer_size_kbytes=16 coherent_pool=32K";
};
};
&fspi0 {
status = "okay";
flash@0 {
compatible = "spi-nand";
reg = <0>;
spi-max-frequency = <75000000>;
spi-rx-bus-width = <4>;
spi-tx-bus-width = <1>;
};
};
&ramdisk_r {
reg = <0x48c40000 (40 * 0x00100000)>;
};
&ramdisk_c {
reg = <0x4b440000 (20 * 0x00100000)>;
};

View File

@@ -0,0 +1,37 @@
// SPDX-License-Identifier: (GPL-2.0+ OR MIT)
/*
* Copyright (c) 2025 Rockchip Electronics Co., Ltd.
*/
/dts-v1/;
#include "rv1126b-evb1-v10.dts"
#include "rv1126b-fastboot-spi-nor.dtsi"
/ {
model = "Rockchip RV1126B EVB1 V10 Arm64 Board";
compatible = "rockchip,rv1126b-evb1-v10-fastboot-spi-nor", "rockchip,rv1126b";
chosen {
bootargs = "loglevel=0 initcall_debug=0 earlycon=uart8250,mmio32,0x20810000 console=ttyFIQ0 root=/dev/rd0 rootfstype=erofs rootflags=dax snd_soc_core.prealloc_buffer_size_kbytes=16 coherent_pool=32K";
};
};
&fspi0 {
status = "okay";
flash@0 {
compatible = "jedec,spi-nor";
reg = <0>;
spi-max-frequency = <75000000>;
spi-rx-bus-width = <4>;
spi-tx-bus-width = <1>;
};
};
&ramdisk_r {
reg = <0x48c40000 (20 * 0x00100000)>;
};
&ramdisk_c {
reg = <0x4a040000 (10 * 0x00100000)>;
};

View File

@@ -6,6 +6,7 @@
/dts-v1/;
#include <dt-bindings/display/media-bus-format.h>
#include <dt-bindings/display/rockchip_vop.h>
#include "rv1126b-evb2-v10.dts"
/ {
@@ -15,6 +16,7 @@
&rgb {
status = "okay";
rockchip,data-map-mode = <ROCKCHIP_MCU_DATA_MAP_DATA_WITH_DUMMY_0>;
rockchip,data-sync-bypass;
pinctrl-names = "default";
/*

View File

@@ -6,6 +6,7 @@
/dts-v1/;
#include <dt-bindings/display/media-bus-format.h>
#include <dt-bindings/display/rockchip_vop.h>
#include "rv1126b-evb2-v10.dts"
/ {
@@ -60,6 +61,11 @@
&rgb {
status = "okay";
/*
* BT1120: ROCKCHIP_BT1120_DATA_MAP_DATA_WITH_DUMMY_0
* BT656: ROCKCHIP_BT656_DATA_MAP_DATA_WITH_DUMMY_0
*/
rockchip,data-map-mode = <ROCKCHIP_BT1120_DATA_MAP_DATA_WITH_DUMMY_0>;
pinctrl-names = "default";
/*
* bt1120_pins for bt1120

View File

@@ -3,7 +3,11 @@
* Copyright (c) 2025 Rockchip Electronics Co., Ltd.
*/
#include "rv1126b-evb2-v10.dts"
/dts-v1/;
#include "rv1126b.dtsi"
#include "rv1126b-evb.dtsi"
#include "rv1126b-evb2-v10.dtsi"
#include "rv1126b-thunder-boot-cam.dtsi"
#include "rv1126b-thunder-boot-spi-nor.dtsi"
/ {
@@ -15,6 +19,36 @@
};
};
&i2c3 {
clock-frequency = <400000>;
pinctrl-names = "default";
pinctrl-0 = <&i2c3m1_pins>;
rockchip,amp-shared;
status = "okay";
sc450ai: sc450ai@30 {
compatible = "smartsens,sc450ai";
status = "okay";
reg = <0x30>;
clocks = <&cru CLK_MIPI0_OUT2IO>;
clock-names = "xvclk";
reset-gpios = <&gpio4 RK_PA7 GPIO_ACTIVE_LOW>;
pwdn-gpios = <&gpio4 RK_PA2 GPIO_ACTIVE_HIGH>;
pinctrl-names = "default";
pinctrl-0 = <&cam_clk0_pins>;
rockchip,camera-module-index = <0>;
rockchip,camera-module-facing = "back";
rockchip,camera-module-name = "default";
rockchip,camera-module-lens-name = "default";
port {
cam0_out: endpoint {
remote-endpoint = <&csi_dphy_input0>;
data-lanes = <1 2 3 4>;
};
};
};
};
&ramdisk_r {
reg = <0x48c40000 (40 * 0x00100000)>;
};
@@ -22,3 +56,12 @@
&ramdisk_c {
reg = <0x4b440000 (20 * 0x00100000)>;
};
&rkisp_thunderboot {
/* reg's offset MUST match with RTOS */
/*
* vicap, capture raw10, ceil(w*10/8/256)*256*h *4(buf num)
* e.g. 2688x1520: 0x14c8000
*/
reg = <0x41300000 0x14c8000>;
};

View File

@@ -6,405 +6,18 @@
/dts-v1/;
#include "rv1126b.dtsi"
#include "rv1126b-evb.dtsi"
#include "rv1126b-evb2-v10.dtsi"
#include "rv1126b-evb-cam-csi0.dtsi"
/ {
model = "Rockchip RV1126B EVB2 V10 Board";
compatible = "rockchip,rv1126b-evb2-v10", "rockchip,rv1126b";
gpio-keys {
compatible = "gpio-keys";
autorepeat;
pinctrl-names = "default";
pinctrl-0 = <&pwr_key>;
power-key {
gpios = <&gpio0 RK_PA4 GPIO_ACTIVE_LOW>;
linux,code = <KEY_POWER>;
label ="GPIO Key Power";
debounce-interval = <100>;
wakeup-source;
/* gpio-key,wakeup; */
};
};
vcc5v0_dcin: vcc5v0-dcin {
compatible = "regulator-fixed";
regulator-name = "vcc5v0_dcin";
regulator-always-on;
regulator-boot-on;
regulator-min-microvolt = <5000000>;
regulator-max-microvolt = <5000000>;
vin-supply = <&vcc12v_dcin>;
};
vcc5v0_host: vcc5v0-host {
compatible = "regulator-fixed";
regulator-name = "vcc5v0_host";
regulator-boot-on;
regulator-always-on;
regulator-min-microvolt = <5000000>;
regulator-max-microvolt = <5000000>;
enable-active-high;
gpio = <&gpio0 RK_PD1 GPIO_ACTIVE_HIGH>;
vin-supply = <&vcc5v0_dcin>;
pinctrl-names = "default";
pinctrl-0 = <&vcc5v0_host_en>;
};
vccsys_stb: vccsys-stb {
compatible = "regulator-fixed";
regulator-name = "vccsys_stb";
regulator-always-on;
regulator-boot-on;
regulator-min-microvolt = <5000000>;
regulator-max-microvolt = <5000000>;
vin-supply = <&vcc5v0_dcin>;
};
vcc3v3_stb: vcc3v3-stb {
compatible = "regulator-fixed";
regulator-name = "vcc3v3_stb";
regulator-always-on;
regulator-boot-on;
regulator-min-microvolt = <3300000>;
regulator-max-microvolt = <3300000>;
vin-supply = <&vccsys_stb>;
};
vcc1v8_pmu: vdd1_1v8_ddr: vcc1v8_pmu {
compatible = "regulator-fixed";
regulator-name = "vcc3v3_stb";
regulator-always-on;
regulator-boot-on;
regulator-min-microvolt = <1800000>;
regulator-max-microvolt = <1800000>;
vin-supply = <&vccsys_stb>;
};
vdd2_1v1_ddr: vdd2_1v1_ddr {
compatible = "regulator-fixed";
regulator-name = "vdd2_1v1_ddr";
regulator-always-on;
regulator-boot-on;
regulator-min-microvolt = <1100000>;
regulator-max-microvolt = <1100000>;
vin-supply = <&vccsys_stb>;
};
vddq_0v6_lp4x: vddq-0v6-lp4x {
compatible = "regulator-fixed";
regulator-name = "vddq_0v6_lp4x";
regulator-always-on;
regulator-boot-on;
regulator-min-microvolt = <600000>;
regulator-max-microvolt = <600000>;
vin-supply = <&vccsys_stb>;
};
vcc3v3_pmu: vcc3v3-pmu {
compatible = "regulator-fixed";
regulator-name = "vcc3v3_pmu";
regulator-always-on;
regulator-boot-on;
regulator-min-microvolt = <3300000>;
regulator-max-microvolt = <3300000>;
vin-supply = <&vccsys_stb>;
};
vcc0v9_pmu: vcc0v9-pmu {
compatible = "regulator-fixed";
regulator-name = "vcc0v9_pmu";
regulator-always-on;
regulator-boot-on;
regulator-min-microvolt = <900000>;
regulator-max-microvolt = <900000>;
vin-supply = <&vcc1v8_pmu>;
};
vcc_mipi: vcc-mipi{
compatible = "regulator-fixed";
regulator-name = "vcc_mipi";
regulator-always-on;
regulator-boot-on;
vin-supply = <&vcc1v8_pmu>;
};
vcc_1v8: vcc-1v8 {
compatible = "regulator-fixed";
regulator-name = "vcc_1v8";
regulator-always-on;
regulator-boot-on;
regulator-min-microvolt = <1800000>;
regulator-max-microvolt = <1800000>;
vin-supply = <&vccsys_stb>;
};
vcc_3v3: vcc3v3_dev: vcc-3v3 {
compatible = "regulator-fixed";
regulator-name = "vcc_3v3";
regulator-always-on;
regulator-boot-on;
regulator-min-microvolt = <3300000>;
regulator-max-microvolt = <3300000>;
vin-supply = <&vccsys_stb>;
};
vcc_lcd: vcc-lcd {
compatible = "regulator-fixed";
gpio = <&gpio7 RK_PA7 GPIO_ACTIVE_HIGH>;
regulator-name = "vcc_lcd";
enable-active-high;
};
vcc_sd: vcc-sd {
compatible = "regulator-fixed";
gpio = <&gpio0 RK_PB0 GPIO_ACTIVE_LOW>;
regulator-name = "vcc_sd";
regulator-min-microvolt = <3300000>;
regulator-max-microvolt = <3300000>;
enable-active-low;
vin-supply = <&vcc_3v3>;
};
vccio_sd: vccio-sd {
compatible = "regulator-gpio";
regulator-boot-on;
regulator-name = "vccio_sd";
regulator-min-microvolt = <1800000>;
regulator-max-microvolt = <3300000>;
pinctrl-names = "default";
pinctrl-0 = <&sdmmc_volt>;
gpios = <&gpio0 RK_PA6 GPIO_ACTIVE_HIGH>;
vin-supply = <&vccsys_stb>;
states = <1800000 0x0
3300000 0x1>;
};
vdd_log: vdd-log {
compatible = "pwm-regulator";
pwms = <&pwm0_8ch_2 0 25000 1>;
regulator-name = "vdd_log";
regulator-init-microvolt = <905000>;
regulator-min-microvolt = <810000>;
regulator-max-microvolt = <1006000>;
regulator-always-on;
regulator-boot-on;
pwm-supply = <&vccsys_stb>;
status = "okay";
};
vdd_cpu: vdd-cpu {
compatible = "pwm-regulator";
pwms = <&pwm0_8ch_0 0 25000 1>;
regulator-name = "vdd_cpu";
regulator-init-microvolt = <950000>;
regulator-min-microvolt = <750000>;
regulator-max-microvolt = <1100000>;
regulator-always-on;
regulator-boot-on;
pwm-supply = <&vccsys_stb>;
status = "okay";
};
vdd_npu: vdd-npu {
compatible = "pwm-regulator";
pwms = <&pwm0_8ch_1 0 25000 1>;
regulator-name = "vdd_npu";
regulator-init-microvolt = <950000>;
regulator-min-microvolt = <750000>;
regulator-max-microvolt = <1100000>;
regulator-always-on;
regulator-boot-on;
pwm-supply = <&vccsys_stb>;
status = "okay";
};
wireless-bluetooth {
compatible = "bluetooth-platdata";
uart_rts_gpios = <&gpio3 RK_PA6 GPIO_ACTIVE_LOW>;
pinctrl-names = "default", "rts_gpio";
pinctrl-0 = <&uart2m0_rtsn_pins>;
pinctrl-1 = <&uart2_gpios>;
BT,power_gpio = <&gpio0 RK_PA0 GPIO_ACTIVE_HIGH>;
status = "okay";
};
wireless-wlan {
compatible = "wlan-platdata";
rockchip,grf = <&grf>;
pinctrl-names = "default";
pinctrl-0 = <&wifi_wake_host>;
wifi_chip_type = "rk96x";
WIFI,host_wake_irq = <&gpio0 RK_PC0 GPIO_ACTIVE_HIGH>;
status = "okay";
};
};
&acdcdig_dsm {
pa-ctl-gpios = <&gpio0 RK_PC1 GPIO_ACTIVE_HIGH>;
status = "okay";
};
&acodec_sound {
status = "okay";
};
&audio_codec {
status = "okay";
};
&backlight {
pwms = <&pwm2_8ch_7 0 25000 0>;
};
&cpu0 {
cpu-supply = <&vdd_cpu>;
};
&display_subsystem {
status = "okay";
};
&dsi {
status = "okay";
};
&dsi_in_vop {
status = "okay";
};
&dsi_panel {
power-supply = <&vcc_lcd>;
};
&fspi0 {
status = "okay";
flash@0 {
compatible = "jedec,spi-nor";
reg = <0>;
spi-max-frequency = <100000000>;
spi-rx-bus-width = <4>;
spi-tx-bus-width = <1>;
};
};
&gmac {
phy-mode = "rmii";
clock_in_out = "input";
phy-handle = <&rmii_phy>;
status = "okay";
};
&imx415 {
reset-gpios = <&gpio4 RK_PA7 GPIO_ACTIVE_HIGH>;
};
&i2c2 {
pinctrl-0 = <&i2c2m1_pins>;
status = "okay";
gt1x: gt1x@14 {
compatible = "goodix,gt1x";
reg = <0x14>;
pinctrl-names = "default";
pinctrl-0 = <&touch_gpio>;
vdd_ana-supply = <&vcc_lcd>;
goodix,rst-gpio = <&gpio5 RK_PD6 GPIO_ACTIVE_HIGH>;
goodix,irq-gpio = <&gpio3 RK_PB7 IRQ_TYPE_LEVEL_LOW>;
};
};
&mdio {
rmii_phy: ethernet-phy@2 {
compatible = "ethernet-phy-id0680.8101", "ethernet-phy-ieee802.3-c22";
reg = <2>;
clocks = <&cru CLK_MACPHY>;
clock-frequency = <24000000>;
resets = <&cru SRST_RESETN_MACPHY>;
pinctrl-names = "default";
pinctrl-0 = <&fephym2_pins>;
phy-is-integrated;
};
};
&mipi_dphy {
status = "okay";
};
&pinctrl {
buttons {
pwr_key: pwr-key {
rockchip,pins = <0 RK_PA4 RK_FUNC_GPIO &pcfg_pull_up>;
};
};
sdmmc {
/omit-if-no-ref/
sdmmc_volt: sdmmc-volt {
rockchip,pins = <0 RK_PA6 RK_FUNC_GPIO &pcfg_pull_none>;
};
};
touch {
touch_gpio: touch-gpio {
rockchip,pins =
<3 RK_PB7 RK_FUNC_GPIO &pcfg_pull_up>,
<5 RK_PD6 RK_FUNC_GPIO &pcfg_pull_none>;
};
};
usb {
vcc5v0_host_en: vcc5v0-host-en {
rockchip,pins = <0 RK_PD1 RK_FUNC_GPIO &pcfg_pull_none>;
};
};
wireless-bluetooth {
uart2_gpios: uart2-gpios {
rockchip,pins = <3 RK_PA6 RK_FUNC_GPIO &pcfg_pull_none>;
};
};
wireless-wlan {
wifi_wake_host: wifi-wake-host {
rockchip,pins = <0 RK_PB1 RK_FUNC_GPIO &pcfg_pull_up>;
};
};
};
&pwm0_8ch_0 {
status = "okay";
};
&pwm0_8ch_1 {
status = "okay";
};
&pwm0_8ch_2 {
status = "okay";
};
&pwm2_8ch_7 {
status = "okay";
};
&rkaiisp {
status = "okay";
};
&rkaiisp_mmu {
status = "okay";
};
&rkaiisp_vir0 {
status = "okay";
};
&rknpu {
rknpu-supply = <&vdd_npu>;
};
&rockchip_suspend {
status = "okay";
@@ -562,26 +175,6 @@
>;
};
&route_dsi {
status = "okay";
};
&rtc {
rockchip,rtc-suspend-bypass;
status = "okay";
};
&sai2 {
rockchip,sai-rx-route = <1 0 2 3>;
status = "okay";
/delete-property/ pinctrl-names;
/delete-property/ pinctrl-0;
};
&saradc0 {
vref-supply = <&vcc_1v8>;
};
&sc450ai {
reset-gpios = <&gpio4 RK_PA7 GPIO_ACTIVE_LOW>;
};
@@ -590,56 +183,3 @@
reset-gpios = <&gpio4 RK_PA7 GPIO_ACTIVE_HIGH>;
rockchip,camera-module-stb = <1>;
};
&sdmmc0 {
max-frequency = <200000000>;
no-sdio;
no-mmc;
bus-width = <4>;
cap-mmc-highspeed;
cap-sd-highspeed;
disable-wp;
sd-uhs-sdr104;
vmmc-supply = <&vcc_sd>;
vqmmc-supply = <&vccio_sd>;
status = "okay";
};
&sdmmc1 {
bus-width = <1>;
cap-sd-highspeed;
no-sd;
no-mmc;
max-frequency = <200000000>;
pinctrl-names = "default";
pinctrl-0 = <&sdmmc1_clk_pins &sdmmc1_cmd_pins &sdmmc1_bus4_pins>;
keep-power-in-suspend;
non-removable;
//mmc-pwrseq = <&sdio_pwrseq>;
//sd-uhs-sdr104;
status = "okay";
};
&uart2 {
status = "okay";
pinctrl-names = "default";
pinctrl-0 = <&uart2m0_xfer_pins &uart2m0_ctsn_pins>;
};
&usb2phy_host {
phy-supply = <&vcc5v0_host>;
};
&usb3phy {
status = "disabled";
};
&usb_drd_dwc3 {
dr_mode = "otg";
extcon = <&usb2phy>;
maximum-speed = "high-speed";
phys = <&usb2phy_otg>;
phy-names = "usb2-phy";
snps,dis_u2_susphy_quirk;
snps,usb2-lpm-disable;
};

View File

@@ -0,0 +1,467 @@
// SPDX-License-Identifier: (GPL-2.0+ OR MIT)
/*
* Copyright (c) 2025 Rockchip Electronics Co., Ltd.
*/
/ {
gpio-keys {
compatible = "gpio-keys";
autorepeat;
pinctrl-names = "default";
pinctrl-0 = <&pwr_key>;
power-key {
gpios = <&gpio0 RK_PA4 GPIO_ACTIVE_LOW>;
linux,code = <KEY_POWER>;
label ="GPIO Key Power";
debounce-interval = <100>;
wakeup-source;
/* gpio-key,wakeup; */
};
};
vcc5v0_dcin: vcc5v0-dcin {
compatible = "regulator-fixed";
regulator-name = "vcc5v0_dcin";
regulator-always-on;
regulator-boot-on;
regulator-min-microvolt = <5000000>;
regulator-max-microvolt = <5000000>;
vin-supply = <&vcc12v_dcin>;
};
vcc5v0_host: vcc5v0-host {
compatible = "regulator-fixed";
regulator-name = "vcc5v0_host";
regulator-boot-on;
regulator-always-on;
regulator-min-microvolt = <5000000>;
regulator-max-microvolt = <5000000>;
enable-active-high;
gpio = <&gpio0 RK_PD1 GPIO_ACTIVE_HIGH>;
vin-supply = <&vcc5v0_dcin>;
pinctrl-names = "default";
pinctrl-0 = <&vcc5v0_host_en>;
};
vccsys_stb: vccsys-stb {
compatible = "regulator-fixed";
regulator-name = "vccsys_stb";
regulator-always-on;
regulator-boot-on;
regulator-min-microvolt = <5000000>;
regulator-max-microvolt = <5000000>;
vin-supply = <&vcc5v0_dcin>;
};
vcc3v3_stb: vcc3v3-stb {
compatible = "regulator-fixed";
regulator-name = "vcc3v3_stb";
regulator-always-on;
regulator-boot-on;
regulator-min-microvolt = <3300000>;
regulator-max-microvolt = <3300000>;
vin-supply = <&vccsys_stb>;
};
vcc1v8_pmu: vdd1_1v8_ddr: vcc1v8_pmu {
compatible = "regulator-fixed";
regulator-name = "vcc3v3_stb";
regulator-always-on;
regulator-boot-on;
regulator-min-microvolt = <1800000>;
regulator-max-microvolt = <1800000>;
vin-supply = <&vccsys_stb>;
};
vdd2_1v1_ddr: vdd2_1v1_ddr {
compatible = "regulator-fixed";
regulator-name = "vdd2_1v1_ddr";
regulator-always-on;
regulator-boot-on;
regulator-min-microvolt = <1100000>;
regulator-max-microvolt = <1100000>;
vin-supply = <&vccsys_stb>;
};
vddq_0v6_lp4x: vddq-0v6-lp4x {
compatible = "regulator-fixed";
regulator-name = "vddq_0v6_lp4x";
regulator-always-on;
regulator-boot-on;
regulator-min-microvolt = <600000>;
regulator-max-microvolt = <600000>;
vin-supply = <&vccsys_stb>;
};
vcc3v3_pmu: vcc3v3-pmu {
compatible = "regulator-fixed";
regulator-name = "vcc3v3_pmu";
regulator-always-on;
regulator-boot-on;
regulator-min-microvolt = <3300000>;
regulator-max-microvolt = <3300000>;
vin-supply = <&vccsys_stb>;
};
vcc0v9_pmu: vcc0v9-pmu {
compatible = "regulator-fixed";
regulator-name = "vcc0v9_pmu";
regulator-always-on;
regulator-boot-on;
regulator-min-microvolt = <900000>;
regulator-max-microvolt = <900000>;
vin-supply = <&vcc1v8_pmu>;
};
vcc_mipi: vcc-mipi{
compatible = "regulator-fixed";
regulator-name = "vcc_mipi";
regulator-always-on;
regulator-boot-on;
vin-supply = <&vcc1v8_pmu>;
};
vcc_1v8: vcc-1v8 {
compatible = "regulator-fixed";
regulator-name = "vcc_1v8";
regulator-always-on;
regulator-boot-on;
regulator-min-microvolt = <1800000>;
regulator-max-microvolt = <1800000>;
vin-supply = <&vccsys_stb>;
};
vcc_3v3: vcc3v3_dev: vcc-3v3 {
compatible = "regulator-fixed";
regulator-name = "vcc_3v3";
regulator-always-on;
regulator-boot-on;
regulator-min-microvolt = <3300000>;
regulator-max-microvolt = <3300000>;
vin-supply = <&vccsys_stb>;
};
vcc_lcd: vcc-lcd {
compatible = "regulator-fixed";
gpio = <&gpio7 RK_PA7 GPIO_ACTIVE_HIGH>;
regulator-name = "vcc_lcd";
enable-active-high;
};
vcc_sd: vcc-sd {
compatible = "regulator-fixed";
gpio = <&gpio0 RK_PB0 GPIO_ACTIVE_LOW>;
regulator-name = "vcc_sd";
regulator-min-microvolt = <3300000>;
regulator-max-microvolt = <3300000>;
enable-active-low;
vin-supply = <&vcc_3v3>;
};
vccio_sd: vccio-sd {
compatible = "regulator-gpio";
regulator-boot-on;
regulator-name = "vccio_sd";
regulator-min-microvolt = <1800000>;
regulator-max-microvolt = <3300000>;
pinctrl-names = "default";
pinctrl-0 = <&sdmmc_volt>;
gpios = <&gpio0 RK_PA6 GPIO_ACTIVE_HIGH>;
vin-supply = <&vccsys_stb>;
states = <1800000 0x0
3300000 0x1>;
};
vdd_log: vdd-log {
compatible = "pwm-regulator";
pwms = <&pwm0_8ch_2 0 25000 1>;
regulator-name = "vdd_log";
regulator-init-microvolt = <905000>;
regulator-min-microvolt = <810000>;
regulator-max-microvolt = <1006000>;
regulator-always-on;
regulator-boot-on;
pwm-supply = <&vccsys_stb>;
status = "okay";
};
vdd_cpu: vdd-cpu {
compatible = "pwm-regulator";
pwms = <&pwm0_8ch_0 0 25000 1>;
regulator-name = "vdd_cpu";
regulator-init-microvolt = <950000>;
regulator-min-microvolt = <750000>;
regulator-max-microvolt = <1100000>;
regulator-always-on;
regulator-boot-on;
pwm-supply = <&vccsys_stb>;
status = "okay";
};
vdd_npu: vdd-npu {
compatible = "pwm-regulator";
pwms = <&pwm0_8ch_1 0 25000 1>;
regulator-name = "vdd_npu";
regulator-init-microvolt = <950000>;
regulator-min-microvolt = <750000>;
regulator-max-microvolt = <1100000>;
regulator-always-on;
regulator-boot-on;
pwm-supply = <&vccsys_stb>;
status = "okay";
};
wireless-bluetooth {
compatible = "bluetooth-platdata";
uart_rts_gpios = <&gpio3 RK_PA6 GPIO_ACTIVE_LOW>;
pinctrl-names = "default", "rts_gpio";
pinctrl-0 = <&uart2m0_rtsn_pins>;
pinctrl-1 = <&uart2_gpios>;
BT,power_gpio = <&gpio0 RK_PA0 GPIO_ACTIVE_HIGH>;
status = "okay";
};
wireless-wlan {
compatible = "wlan-platdata";
rockchip,grf = <&grf>;
pinctrl-names = "default";
pinctrl-0 = <&wifi_wake_host>;
wifi_chip_type = "rk96x";
WIFI,host_wake_irq = <&gpio0 RK_PC0 GPIO_ACTIVE_HIGH>;
status = "okay";
};
};
&acdcdig_dsm {
pa-ctl-gpios = <&gpio0 RK_PC1 GPIO_ACTIVE_HIGH>;
status = "okay";
};
&acodec_sound {
status = "okay";
};
&audio_codec {
status = "okay";
};
&backlight {
pwms = <&pwm2_8ch_7 0 25000 0>;
};
&cpu0 {
cpu-supply = <&vdd_cpu>;
};
&display_subsystem {
status = "okay";
};
&dsi {
status = "okay";
};
&dsi_in_vop {
status = "okay";
};
&dsi_panel {
power-supply = <&vcc_lcd>;
};
&fspi0 {
status = "okay";
flash@0 {
compatible = "jedec,spi-nor";
reg = <0>;
spi-max-frequency = <100000000>;
spi-rx-bus-width = <4>;
spi-tx-bus-width = <1>;
};
};
&gmac {
phy-mode = "rmii";
clock_in_out = "input";
phy-handle = <&rmii_phy>;
status = "okay";
};
&i2c2 {
pinctrl-0 = <&i2c2m1_pins>;
status = "okay";
gt1x: gt1x@14 {
compatible = "goodix,gt1x";
reg = <0x14>;
pinctrl-names = "default";
pinctrl-0 = <&touch_gpio>;
vdd_ana-supply = <&vcc_lcd>;
goodix,rst-gpio = <&gpio5 RK_PD6 GPIO_ACTIVE_HIGH>;
goodix,irq-gpio = <&gpio3 RK_PB7 IRQ_TYPE_LEVEL_LOW>;
};
};
&mdio {
rmii_phy: ethernet-phy@2 {
compatible = "ethernet-phy-id0680.8101", "ethernet-phy-ieee802.3-c22";
reg = <2>;
clocks = <&cru CLK_MACPHY>;
clock-frequency = <24000000>;
resets = <&cru SRST_RESETN_MACPHY>;
pinctrl-names = "default";
pinctrl-0 = <&fephym2_pins>;
phy-is-integrated;
};
};
&mipi_dphy {
status = "okay";
};
&pinctrl {
buttons {
pwr_key: pwr-key {
rockchip,pins = <0 RK_PA4 RK_FUNC_GPIO &pcfg_pull_up>;
};
};
sdmmc {
/omit-if-no-ref/
sdmmc_volt: sdmmc-volt {
rockchip,pins = <0 RK_PA6 RK_FUNC_GPIO &pcfg_pull_none>;
};
};
touch {
touch_gpio: touch-gpio {
rockchip,pins =
<3 RK_PB7 RK_FUNC_GPIO &pcfg_pull_up>,
<5 RK_PD6 RK_FUNC_GPIO &pcfg_pull_none>;
};
};
usb {
vcc5v0_host_en: vcc5v0-host-en {
rockchip,pins = <0 RK_PD1 RK_FUNC_GPIO &pcfg_pull_none>;
};
};
wireless-bluetooth {
uart2_gpios: uart2-gpios {
rockchip,pins = <3 RK_PA6 RK_FUNC_GPIO &pcfg_pull_none>;
};
};
wireless-wlan {
wifi_wake_host: wifi-wake-host {
rockchip,pins = <0 RK_PB1 RK_FUNC_GPIO &pcfg_pull_up>;
};
};
};
&pwm0_8ch_0 {
status = "okay";
};
&pwm0_8ch_1 {
status = "okay";
};
&pwm0_8ch_2 {
status = "okay";
};
&pwm2_8ch_7 {
status = "okay";
};
&rkaiisp {
status = "okay";
};
&rkaiisp_mmu {
status = "okay";
};
&rkaiisp_vir0 {
status = "okay";
};
&rknpu {
rknpu-supply = <&vdd_npu>;
};
&route_dsi {
status = "okay";
};
&rtc {
rockchip,rtc-suspend-bypass;
status = "okay";
};
&sai2 {
rockchip,sai-rx-route = <1 0 2 3>;
status = "okay";
/delete-property/ pinctrl-names;
/delete-property/ pinctrl-0;
};
&saradc0 {
vref-supply = <&vcc_1v8>;
};
&sdmmc0 {
max-frequency = <200000000>;
no-sdio;
no-mmc;
bus-width = <4>;
cap-mmc-highspeed;
cap-sd-highspeed;
disable-wp;
sd-uhs-sdr104;
vmmc-supply = <&vcc_sd>;
vqmmc-supply = <&vccio_sd>;
status = "okay";
};
&sdmmc1 {
bus-width = <1>;
cap-sd-highspeed;
no-sd;
no-mmc;
max-frequency = <200000000>;
pinctrl-names = "default";
pinctrl-0 = <&sdmmc1_clk_pins &sdmmc1_cmd_pins &sdmmc1_bus4_pins>;
keep-power-in-suspend;
non-removable;
//mmc-pwrseq = <&sdio_pwrseq>;
//sd-uhs-sdr104;
status = "okay";
};
&uart2 {
status = "okay";
pinctrl-names = "default";
pinctrl-0 = <&uart2m0_xfer_pins &uart2m0_ctsn_pins>;
};
&usb2phy_host {
phy-supply = <&vcc5v0_host>;
};
&usb3phy {
status = "disabled";
};
&usb_drd_dwc3 {
dr_mode = "otg";
extcon = <&usb2phy>;
maximum-speed = "high-speed";
phys = <&usb2phy_otg>;
phy-names = "usb2-phy";
snps,dis_u2_susphy_quirk;
snps,usb2-lpm-disable;
};

View File

@@ -0,0 +1,55 @@
// SPDX-License-Identifier: (GPL-2.0+ OR MIT)
/*
* Copyright (c) 2025 Rockchip Electronics Co., Ltd.
*/
/ {
ramdisk: ramdisk {
compatible = "rockchip,ramdisk";
memory-region = <&ramdisk_r>;
};
thunder_boot_mmc: thunder-boot-mmc {
compatible = "rockchip,thunder-boot-mmc";
reg = <0x21470000 0x4000>;
clocks = <&cru HCLK_EMMC>, <&cru CCLK_EMMC>;
clock-names = "biu", "ciu";
memory-region-src = <&ramdisk_c>;
memory-region-dst = <&ramdisk_r>;
memory-region-idmac = <&mmc_idmac>;
};
};
&emmc {
memory-region-ecsd = <&mmc_ecsd>;
post-power-on-delay-ms = <0>;
};
&reserved_memory {
/* Should enable this node if the security feature is enabled, like TA. */
tee: tee@48400000 {
reg = <0x48400000 0x00800000>;
status = "disabled";
};
mmc_idmac: mmc@48000000 {
reg = <0x48000000 0x00400000>;
};
mmc_ecsd: mmc@47FFFE00{
reg = <0x47FFFE00 0x00001000>;
};
ramdisk_r: ramdisk_r {
reg = <0x48c40000 (40 * 0x00100000)>;
};
ramdisk_c: ramdisk_c {
reg = <0x4b440000 (20 * 0x00100000)>;
};
};
&hw_decompress {
memory-region = <&ramdisk_c>;
status = "okay";
};

View File

@@ -0,0 +1,32 @@
// SPDX-License-Identifier: (GPL-2.0+ OR MIT)
/*
* Copyright (c) 2025 Rockchip Electronics Co., Ltd.
*/
/ {
ramdisk: ramdisk {
compatible = "rockchip,ramdisk";
memory-region = <&ramdisk_r>;
};
};
&reserved_memory {
/* Should enable this node if the security feature is enabled, like TA. */
tee: tee@48400000 {
reg = <0x48400000 0x00800000>;
status = "disabled";
};
ramdisk_r: ramdisk_r {
reg = <0x48c40000 (40 * 0x00100000)>;
};
ramdisk_c: ramdisk_c {
reg = <0x4b440000 (20 * 0x00100000)>;
};
};
&hw_decompress {
memory-region = <&ramdisk_c>;
status = "okay";
};

View File

@@ -0,0 +1,39 @@
// SPDX-License-Identifier: (GPL-2.0+ OR MIT)
/*
* Copyright (c) 2025 Rockchip Electronics Co., Ltd.
*/
/ {
ramdisk: ramdisk {
compatible = "rockchip,ramdisk";
memory-region = <&ramdisk_r>;
};
thunder_boot_spi_nor: thunder-boot-spi-nor {
compatible = "rockchip,thunder-boot-sfc";
reg = <0x21460000 0x4000>;
memory-region-src = <&ramdisk_c>;
memory-region-dst = <&ramdisk_r>;
};
};
&reserved_memory {
/* Should enable this node if the security feature is enabled, like TA. */
tee: tee@48400000 {
reg = <0x48400000 0x00800000>;
status = "disabled";
};
ramdisk_r: ramdisk_r {
reg = <0x48c40000 (20 * 0x00100000)>;
};
ramdisk_c: ramdisk_c {
reg = <0x4a040000 (10 * 0x00100000)>;
};
};
&hw_decompress {
memory-region = <&ramdisk_c>;
status = "okay";
};

View File

@@ -0,0 +1,135 @@
// SPDX-License-Identifier: (GPL-2.0+ OR MIT)
/*
* Copyright (c) 2025 Rockchip Electronics Co., Ltd.
*
*/
&csi2_dphy0 {
status = "okay";
ports {
#address-cells = <1>;
#size-cells = <0>;
port@0 {
reg = <0>;
#address-cells = <1>;
#size-cells = <0>;
csi_dphy_input0: endpoint@1 {
reg = <1>;
remote-endpoint = <&cam0_out>;
data-lanes = <1 2 3 4>;
};
};
port@1 {
reg = <1>;
#address-cells = <1>;
#size-cells = <0>;
csidphy0_out: endpoint@0 {
reg = <0>;
remote-endpoint = <&mipi0_csi2_input>;
};
};
};
};
&mipi0_csi2 {
status = "okay";
ports {
#address-cells = <1>;
#size-cells = <0>;
port@0 {
reg = <0>;
#address-cells = <1>;
#size-cells = <0>;
mipi0_csi2_input: endpoint@1 {
reg = <1>;
remote-endpoint = <&csidphy0_out>;
};
};
port@1 {
reg = <1>;
#address-cells = <1>;
#size-cells = <0>;
mipi0_csi2_output: endpoint@0 {
reg = <0>;
remote-endpoint = <&cif_mipi_in0>;
};
};
};
};
&rkcif {
status = "okay";
};
&rkcif_mipi_lvds {
status = "okay";
memory-region-thunderboot = <&rkisp_thunderboot>;
port {
cif_mipi_in0: endpoint {
remote-endpoint = <&mipi0_csi2_output>;
};
};
};
&rkcif_mipi_lvds_sditf {
status = "okay";
port {
mipi_lvds_sditf: endpoint {
remote-endpoint = <&isp_vir0>;
};
};
};
&rkcif_mmu {
status = "okay";
};
&rkisp {
status = "okay";
};
&rkisp_mmu {
status = "okay";
};
&rkisp_vir0 {
status = "okay";
memory-region-thunderboot = <&rkisp_thunderboot>;
port {
#address-cells = <1>;
#size-cells = <0>;
isp_vir0: endpoint@0 {
reg = <0>;
remote-endpoint = <&mipi_lvds_sditf>;
};
};
};
&rkisp_vir0_sditf {
status = "okay";
};
&rkvpss {
status = "okay";
dvbm = <&rkdvbm>;
};
&rkvpss_mmu {
status = "okay";
};
&rkvpss_vir0 {
status = "okay";
};

View File

@@ -8,6 +8,49 @@
compatible = "rockchip,ramdisk";
memory-region = <&ramdisk_r>;
};
thunder_boot_rkisp: thunder-boot-rkisp {
compatible = "rockchip,thunder-boot-rkisp";
clocks = <&cru CLK_HPMCU>,
<&cru PCLK_HPMCU_INTMUX>, <&cru PCLK_HPMCU_MAILBOX>,
<&cru PCLK_WDT_HPMCU>, <&cru HCLK_CACHE>,
<&cru PCLK_TIMER>,
<&cru ACLK_ISP>, <&cru HCLK_ISP>,
<&cru CLK_CORE_ISP>, <&cru ISP0CLK_VICAP>,
<&cru ACLK_VICAP>, <&cru HCLK_VICAP>,
<&cru DCLK_VICAP>, <&cru ISP0CLK_VICAP>,
<&cru PCLK_CSI2HOST0>, <&cru PCLK_CSI2HOST1>,
<&cru CLK_I2C4>, <&cru PCLK_I2C4>;
clock-names = "clk_hpmcu",
"pclk_hpmcu_intmux", "pclk_hpmcu_mailbox",
"pclk_wdt_hpmcu", "hclk_cache",
"pclk_timer",
"aclk_isp", "hclk_isp",
"clk_isp_core", "clk_isp_core_vicap",
"aclk_cif","hclk_cif",
"dclk_cif", "isp0clk_cif",
"pclk_csi2host0", "pclk_csi2host1",
"clk_i2c4", "pclk_i2c4";
};
thunder_boot_service: thunder-boot-service {
compatible = "rockchip,thunder-boot-service";
mbox-names = "amp-rx";
mboxes = <&hpmcu_mbox0 0>;
resets = <&cru SRST_RESETN_HPMCU_FULL_CLUSTER>;
reset-names = "hpmcu_full_cluster";
memory-region = <&rtos>;
status = "okay";
};
};
&hpmcu_mbox0 {
status = "okay";
};
&hw_decompress {
memory-region = <&ramdisk_c>;
status = "okay";
};
&reserved_memory {
@@ -88,8 +131,3 @@
reg = <0x49640000 (5 * 0x00100000)>;
};
};
&hw_decompress {
memory-region = <&ramdisk_c>;
status = "okay";
};

View File

@@ -940,7 +940,7 @@
<&cru CLK_UART_FRAC0>, <&cru CLK_UART_FRAC1>,
<&cru CLK_CM_FRAC0>, <&cru CLK_CM_FRAC1>,
<&cru CLK_CM_FRAC2>, <&cru CLK_AUDIO_FRAC0>,
<&cru CLK_AUDIO_FRAC1>, <&cru CLK_AISP_PLL>,
<&cru CLK_AUDIO_FRAC1>, <&cru CLK_AISP_PLL_SRC>,
<&cru CLK_CPLL_DIV10>;
assigned-clock-rates =
<1188000000>, <1000000000>,
@@ -951,7 +951,7 @@
<96000000>, <128000000>,
<18432000>, <500000000>,
<32768000>, <45158400>,
<49152000>, <393216000>,
<49152000>, <786432000>,
<98304000>;
};
@@ -1904,9 +1904,6 @@
clocks = <&cru CLK_TSADC>, <&cru PCLK_TSADC>,
<&cru CLK_TSADC_PHYCTRL>;
clock-names = "tsadc", "apb_pclk", "tsadc_phyctrl";
resets = <&cru SRST_RESETN_TSADC>, <&cru SRST_PRESETN_TSADC>,
<&cru SRST_RESETN_TSADC_PHYCTRL>;
reset-names = "tsadc", "tsadc-apb", "tsadc-phy";
#thermal-sensor-cells = <1>;
rockchip,grf = <&grf>;
rockchip,hw-tshut-temp = <120000>;

View File

@@ -4,7 +4,7 @@
*/
/dts-v1/;
#include "rv1126b.dtsi"
#include "rv1126bp.dtsi"
#include "rv1126bp-evb.dtsi"
#include "rv1126bp-evb-v14.dtsi"
#include "rv1126bp-evb-v14-dual-cam.dtsi"

View File

@@ -4,7 +4,7 @@
*/
/dts-v1/;
#include "rv1126b.dtsi"
#include "rv1126bp.dtsi"
#include "rv1126bp-evb.dtsi"
#include "rv1126bp-evb-v14.dtsi"
#include "rv1126bp-evb-cam-csi0.dtsi"

View File

@@ -383,6 +383,17 @@
status = "okay";
};
&rgb {
/*
* RV1126 compatible pin output mode 0.
*
* MCU: ROCKCHIP_MCU_DATA_MAP_DATA_1x24
* BT1120: ROCKCHIP_BT1120_DATA_MAP_DATA_PADLO
* BT656: ROCKCHIP_BT656_DATA_MAP_PADLO
*/
rockchip,data-map-mode = <0>;
};
&rkdvbm {
status = "okay";
};

View File

@@ -0,0 +1,9 @@
// SPDX-License-Identifier: (GPL-2.0+ OR MIT)
/*
* Copyright (c) 2025 Rockchip Electronics Co., Ltd.
*/
#include "rv1126b.dtsi"
/ {
};

View File

@@ -39,6 +39,7 @@ CONFIG_HZ_1000=y
# CONFIG_LIGHT_DEVICE is not set
CONFIG_LOG_BUF_SHIFT=20
# CONFIG_MALI400 is not set
CONFIG_MALI_BIFROST=y
# CONFIG_MALI_MIDGARD is not set
# CONFIG_MFD_MAX96745 is not set
# CONFIG_MFD_MAX96755F is not set
@@ -57,8 +58,6 @@ CONFIG_REALTEK_PHY=y
# CONFIG_REGULATOR_WL2868C is not set
# CONFIG_REGULATOR_XZ3216 is not set
# CONFIG_ROCKCHIP_CHARGER_MANAGER is not set
# CONFIG_ROCKCHIP_CLK_INV is not set
# CONFIG_ROCKCHIP_CLK_PVTM is not set
CONFIG_ROCKCHIP_DRM_DIRECT_SHOW=y
CONFIG_RTC_DRV_S35390A=y
# CONFIG_SLUB_SYSFS is not set
@@ -73,6 +72,7 @@ CONFIG_RTC_DRV_S35390A=y
# CONFIG_SND_SOC_RK817 is not set
# CONFIG_SND_SOC_RK_CODEC_DIGITAL is not set
# CONFIG_SND_SOC_RT5640 is not set
CONFIG_SPI_SLAVE=y
# CONFIG_TOUCHSCREEN_ELAN5515 is not set
# CONFIG_TOUCHSCREEN_GSL3673 is not set
# CONFIG_TOUCHSCREEN_GSLX680_PAD is not set
@@ -93,6 +93,7 @@ CONFIG_TOUCHSCREEN_ILI210X=m
# CONFIG_USB_NET_SMSC95XX is not set
CONFIG_USB_OHCI_HCD=m
CONFIG_USB_OHCI_HCD_PLATFORM=m
CONFIG_VEHICLE_CORE=y
# CONFIG_VIDEO_AW36518 is not set
# CONFIG_VIDEO_AW8601 is not set
# CONFIG_VIDEO_CN3927V is not set
@@ -117,6 +118,32 @@ CONFIG_VIDEO_MAXIM_SERDES=y
# CONFIG_VIDEO_S5KJN1 is not set
# CONFIG_VIDEO_SGM3784 is not set
# CONFIG_VL6180 is not set
CONFIG_LARGE_PAGE_SUPPORT=y
# CONFIG_MALI_ARBITER_SUPPORT is not set
# CONFIG_MALI_ARBITRATION is not set
CONFIG_MALI_BIFROST_DEBUG=y
CONFIG_MALI_BIFROST_DEVFREQ=y
CONFIG_MALI_BIFROST_ENABLE_TRACE=y
CONFIG_MALI_BIFROST_EXPERT=y
CONFIG_MALI_BIFROST_FENCE_DEBUG=y
CONFIG_MALI_BIFROST_GATOR_SUPPORT=y
# CONFIG_MALI_BIFROST_NO_MALI is not set
# CONFIG_MALI_BIFROST_PRFCNT_SET_SECONDARY is not set
CONFIG_MALI_BIFROST_SYSTEM_TRACE=y
# CONFIG_MALI_CSF_SUPPORT is not set
# CONFIG_MALI_DMA_BUF_LEGACY_COMPAT is not set
# CONFIG_MALI_DMA_BUF_MAP_ON_DEMAND is not set
# CONFIG_MALI_HW_ERRATA_1485982_NOT_AFFECTED is not set
# CONFIG_MALI_HW_ERRATA_1485982_USE_CLOCK_ALTERNATIVE is not set
# CONFIG_MALI_IS_FPGA is not set
# CONFIG_MALI_JOB_DUMP is not set
CONFIG_MALI_PLATFORM_NAME="rk"
CONFIG_MALI_PRFCNT_SET_PRIMARY=y
# CONFIG_MALI_PRFCNT_SET_SELECT_VIA_DEBUG_FS is not set
# CONFIG_MALI_PRFCNT_SET_TERTIARY is not set
CONFIG_MALI_REAL_HW=y
CONFIG_MALI_TRACE_POWER_GPU_WORK_PERIOD=y
CONFIG_PAGE_MIGRATION_SUPPORT=y
# CONFIG_ROCKCHIP_DRM_SELF_TEST is not set
CONFIG_SERDES_DISPLAY_CHIP_MAXIM=y
CONFIG_SERDES_DISPLAY_CHIP_MAXIM_MAX96745=y
@@ -132,6 +159,15 @@ CONFIG_SERDES_DISPLAY_CHIP_ROCKCHIP_RKX121=y
CONFIG_SERDES_DISPLAY_CHIP_ROHM=y
CONFIG_SERDES_DISPLAY_CHIP_ROHM_BU18RL82=y
CONFIG_SERDES_DISPLAY_CHIP_ROHM_BU18TL82=y
CONFIG_SPI_DYNAMIC=y
# CONFIG_SPI_SLAVE_ROCKCHIP_OBJ is not set
# CONFIG_SPI_SLAVE_SYSTEM_CONTROL is not set
# CONFIG_SPI_SLAVE_TIME is not set
CONFIG_VEHICLE_ADC=y
CONFIG_VEHICLE_DUMMY=y
CONFIG_VEHICLE_GPIO=y
CONFIG_VEHICLE_SPI=y
# CONFIG_VEHICLE_SPI_PROTOCOL is not set
CONFIG_VIDEO_MAXIM_CAM_DUMMY=y
# CONFIG_VIDEO_MAXIM_CAM_OS04A10 is not set
CONFIG_VIDEO_MAXIM_CAM_OV231X=y
@@ -144,7 +180,3 @@ CONFIG_VIDEO_MAXIM_SER_MAX9295=y
CONFIG_VIDEO_MAXIM_SER_MAX96715=y
CONFIG_VIDEO_MAXIM_SER_MAX96717=y
# CONFIG_VIDEO_REVERSE_IMAGE is not set
CONFIG_MALI_BIFROST=y
CONFIG_MALI_PLATFORM_NAME="rk"
CONFIG_MALI_BIFROST_EXPERT=y
CONFIG_MALI_BIFROST_DEBUG=y

View File

@@ -40,6 +40,7 @@ CONFIG_HZ_1000=y
CONFIG_LOG_BUF_SHIFT=20
# CONFIG_MALI400 is not set
# CONFIG_MALI_MIDGARD is not set
CONFIG_MALI_VALHALL=y
# CONFIG_MFD_MAX96745 is not set
# CONFIG_MFD_MAX96755F is not set
# CONFIG_MFD_RK618 is not set
@@ -57,8 +58,6 @@ CONFIG_REALTEK_PHY=y
# CONFIG_REGULATOR_WL2868C is not set
# CONFIG_REGULATOR_XZ3216 is not set
# CONFIG_ROCKCHIP_CHARGER_MANAGER is not set
# CONFIG_ROCKCHIP_CLK_INV is not set
# CONFIG_ROCKCHIP_CLK_PVTM is not set
CONFIG_ROCKCHIP_DRM_DIRECT_SHOW=y
CONFIG_RTC_DRV_S35390A=y
# CONFIG_SLUB_SYSFS is not set
@@ -73,6 +72,7 @@ CONFIG_RTC_DRV_S35390A=y
# CONFIG_SND_SOC_RK817 is not set
# CONFIG_SND_SOC_RK_CODEC_DIGITAL is not set
# CONFIG_SND_SOC_RT5640 is not set
CONFIG_SPI_SLAVE=y
# CONFIG_TOUCHSCREEN_ELAN5515 is not set
# CONFIG_TOUCHSCREEN_GSL3673 is not set
# CONFIG_TOUCHSCREEN_GSLX680_PAD is not set
@@ -93,6 +93,7 @@ CONFIG_TOUCHSCREEN_ILI210X=m
# CONFIG_USB_NET_SMSC95XX is not set
CONFIG_USB_OHCI_HCD=m
CONFIG_USB_OHCI_HCD_PLATFORM=m
CONFIG_VEHICLE_CORE=y
# CONFIG_VIDEO_AW36518 is not set
# CONFIG_VIDEO_AW8601 is not set
# CONFIG_VIDEO_CN3927V is not set
@@ -117,6 +118,30 @@ CONFIG_VIDEO_MAXIM_SERDES=y
# CONFIG_VIDEO_S5KJN1 is not set
# CONFIG_VIDEO_SGM3784 is not set
# CONFIG_VL6180 is not set
CONFIG_MALI_CSF_INCLUDE_FW=y
# CONFIG_MALI_VALHALL_ARBITRATION is not set
# CONFIG_MALI_VALHALL_CORESIGHT is not set
# CONFIG_MALI_VALHALL_CORESTACK is not set
CONFIG_MALI_VALHALL_CSF_SUPPORT=y
CONFIG_MALI_VALHALL_DEBUG=y
CONFIG_MALI_VALHALL_DEVFREQ=y
# CONFIG_MALI_VALHALL_DMA_BUF_LEGACY_COMPAT is not set
# CONFIG_MALI_VALHALL_DMA_BUF_MAP_ON_DEMAND is not set
CONFIG_MALI_VALHALL_ENABLE_TRACE=y
CONFIG_MALI_VALHALL_EXPERT=y
CONFIG_MALI_VALHALL_FENCE_DEBUG=y
CONFIG_MALI_VALHALL_GATOR_SUPPORT=y
# CONFIG_MALI_VALHALL_HW_ERRATA_1485982_NOT_AFFECTED is not set
# CONFIG_MALI_VALHALL_HW_ERRATA_1485982_USE_CLOCK_ALTERNATIVE is not set
# CONFIG_MALI_VALHALL_JOB_DUMP is not set
# CONFIG_MALI_VALHALL_NO_MALI is not set
CONFIG_MALI_VALHALL_PLATFORM_NAME="rk"
CONFIG_MALI_VALHALL_PRFCNT_SET_PRIMARY=y
# CONFIG_MALI_VALHALL_PRFCNT_SET_SECONDARY is not set
# CONFIG_MALI_VALHALL_PRFCNT_SET_TERTIARY is not set
CONFIG_MALI_VALHALL_REAL_HW=y
CONFIG_MALI_VALHALL_SYSTEM_TRACE=y
CONFIG_MALI_VALHALL_TRACE_POWER_GPU_WORK_PERIOD=y
# CONFIG_ROCKCHIP_DRM_SELF_TEST is not set
CONFIG_SERDES_DISPLAY_CHIP_MAXIM=y
CONFIG_SERDES_DISPLAY_CHIP_MAXIM_MAX96745=y
@@ -132,6 +157,16 @@ CONFIG_SERDES_DISPLAY_CHIP_ROCKCHIP_RKX121=y
CONFIG_SERDES_DISPLAY_CHIP_ROHM=y
CONFIG_SERDES_DISPLAY_CHIP_ROHM_BU18RL82=y
CONFIG_SERDES_DISPLAY_CHIP_ROHM_BU18TL82=y
CONFIG_SPI_DYNAMIC=y
# CONFIG_SPI_SLAVE_ROCKCHIP_OBJ is not set
# CONFIG_SPI_SLAVE_SYSTEM_CONTROL is not set
# CONFIG_SPI_SLAVE_TIME is not set
CONFIG_VALHALL_LARGE_PAGE_SUPPORT=y
CONFIG_VEHICLE_ADC=y
CONFIG_VEHICLE_DUMMY=y
CONFIG_VEHICLE_GPIO=y
CONFIG_VEHICLE_SPI=y
# CONFIG_VEHICLE_SPI_PROTOCOL is not set
CONFIG_VIDEO_MAXIM_CAM_DUMMY=y
CONFIG_VIDEO_MAXIM_CAM_OS04A10=y
CONFIG_VIDEO_MAXIM_CAM_OV231X=y
@@ -144,7 +179,3 @@ CONFIG_VIDEO_MAXIM_SER_MAX9295=y
CONFIG_VIDEO_MAXIM_SER_MAX96715=y
CONFIG_VIDEO_MAXIM_SER_MAX96717=y
# CONFIG_VIDEO_REVERSE_IMAGE is not set
CONFIG_MALI_VALHALL=y
CONFIG_MALI_VALHALL_PLATFORM_NAME="rk"
CONFIG_MALI_VALHALL_EXPERT=y
CONFIG_MALI_VALHALL_DEBUG=y

View File

@@ -310,6 +310,18 @@ static u64 example_mgm_update_gpu_pte(struct memory_group_manager_device *const
if (WARN_ON(group_id >= MEMORY_GROUP_MANAGER_NR_GROUPS))
return pte;
/* If a page is mapped uncached on the CPU but cached on the GPU, it will be considered to
* have Mismatched Memory Attributes (MMA), and the MMA_VIOLATION bit will be set in the
* pte_flags argument.
*
* If the system requires consistent memory attributes external to the GPU, system
* integrators must allocate one of the PBHA values (range 1-15) for this feature, and
* specify the value either via the mma-wa-id devicetree property or via the mma_wa_id
* module parameter, which is then passed into this function via the pbha_id parameter. The
* GPU will continue to use cached transactions internally, but use non-cacheable
* transactions externally. Note that system integrators may choose not to set the PBHA
* value here if their system does not require it.
*/
if (pte_flags & BIT(MMA_VIOLATION)) {
pr_warn_once("MMA violation! Applying PBHA override workaround to PTE\n");
pte |= ((u64)pbha_id << PTE_PBHA_SHIFT) & PTE_PBHA_MASK;

View File

@@ -144,7 +144,7 @@ PNAME(clk_timer3_parents_p) = { "clk_timer_root", "mclk_asrc0", "mclk_asrc1" };
PNAME(clk_timer4_parents_p) = { "clk_timer_root", "mclk_asrc2", "mclk_asrc3" };
PNAME(clk_macphy_p) = { "xin24m", "clk_cpll_div20" };
PNAME(mux_ddrphy_p) = { "dpll", "aclk_sysmem" };
PNAME(clk_cpll_div10_p) = { "gpll", "clk_aisp_pll" };
PNAME(clk_cpll_div10_p) = { "gpll", "clk_aisp_pll_src" };
static struct rockchip_pll_clock rv1126b_pll_clks[] __initdata = {
[gpll] = PLL(pll_rk3328, PLL_GPLL, "gpll", mux_pll_p,
@@ -866,7 +866,7 @@ static struct rockchip_clk_branch rv1126b_clk_branches[] __initdata = {
RV1126B_BUSCLKGATE_CON(2), 14, GFLAGS),
GATE(HCLK_RKRNG_NS, "hclk_rkrng_ns", "hclk_rkrng_s_ns", 0,
RV1126B_BUSCLKGATE_CON(2), 15, GFLAGS),
GATE(CLK_TIMER5, "clk_timer5", "clk_timer_root", 0,
GATE(CLK_TIMER5, "clk_timer5", "clk_timer_root", CLK_IS_CRITICAL,
RV1126B_BUSCLKGATE_CON(2), 11, GFLAGS),
GATE(PCLK_I2C0, "pclk_i2c0", "pclk_bus_root", 0,
RV1126B_BUSCLKGATE_CON(3), 0, GFLAGS),
@@ -924,9 +924,9 @@ static struct rockchip_clk_branch rv1126b_clk_branches[] __initdata = {
RV1126B_BUSCLKGATE_CON(4), 14, GFLAGS),
GATE(PCLK_UART7, "pclk_uart7", "pclk_bus_root", 0,
RV1126B_BUSCLKGATE_CON(4), 15, GFLAGS),
GATE(PCLK_TSADC, "pclk_tsadc", "pclk_bus_root", 0,
GATE(PCLK_TSADC, "pclk_tsadc", "pclk_bus_root", CLK_IS_CRITICAL,
RV1126B_BUSCLKGATE_CON(5), 0, GFLAGS),
GATE(CLK_TSADC, "clk_tsadc", "xin24m", 0,
GATE(CLK_TSADC, "clk_tsadc", "xin24m", CLK_IS_CRITICAL,
RV1126B_BUSCLKGATE_CON(5), 1, GFLAGS),
GATE(HCLK_SAI0, "hclk_sai0", "hclk_bus_root", 0,
RV1126B_BUSCLKGATE_CON(5), 2, GFLAGS),
@@ -962,7 +962,7 @@ static struct rockchip_clk_branch rv1126b_clk_branches[] __initdata = {
RV1126B_BUSCLKGATE_CON(6), 4, GFLAGS),
GATE(PCLK_OTP_MASK, "pclk_otp_mask", "pclk_bus_root", 0,
RV1126B_BUSCLKGATE_CON(6), 6, GFLAGS),
GATE(CLK_TSADC_PHYCTRL, "clk_tsadc_phyctrl", "xin24m", 0,
GATE(CLK_TSADC_PHYCTRL, "clk_tsadc_phyctrl", "xin24m", CLK_IS_CRITICAL,
RV1126B_BUSCLKGATE_CON(6), 8, GFLAGS),
MUX(LRCK_SRC_ASRC0, "lrck_src_asrc0", lrck_src_asrc_p, 0,
RV1126B_BUSCLKSEL_CON(3), 0, 3, MFLAGS),
@@ -1016,9 +1016,11 @@ static struct rockchip_clk_branch rv1126b_clk_branches[] __initdata = {
};
static struct rockchip_clk_branch rv1126b_clk_cpll_div10_v0[] __initdata = {
COMPOSITE(CLK_AISP_PLL, "clk_aisp_pll", mux_gpll_aupll_cpll_p, 0,
RV1126B_CLKSEL_CON(62), 4, 2, MFLAGS, 0, 3, DFLAGS,
COMPOSITE_NODIV(CLK_AISP_PLL_SRC, "clk_aisp_pll_src", mux_gpll_aupll_cpll_p, 0,
RV1126B_CLKSEL_CON(62), 4, 2, MFLAGS,
RV1126B_CLKGATE_CON(5), 4, GFLAGS),
DIV(CLK_AISP_PLL, "clk_aisp_pll", "clk_aisp_pll_src", 0,
RV1126B_CLKSEL_CON(62), 0, 3, DFLAGS),
COMPOSITE(CLK_CPLL_DIV10, "clk_cpll_div10", mux_gpll_cpll_p, 0,
RV1126B_CLKSEL_CON(1), 15, 1, MFLAGS, 5, 5, DFLAGS,
@@ -1026,9 +1028,11 @@ static struct rockchip_clk_branch rv1126b_clk_cpll_div10_v0[] __initdata = {
};
static struct rockchip_clk_branch rv1126b_clk_cpll_div10[] __initdata = {
COMPOSITE(CLK_AISP_PLL, "clk_aisp_pll", mux_gpll_aupll_cpll_p, 0,
RV1126B_CLKSEL_CON(62), 4, 2, MFLAGS, 0, 3, DFLAGS,
COMPOSITE_NODIV(CLK_AISP_PLL_SRC, "clk_aisp_pll_src", mux_gpll_aupll_cpll_p, 0,
RV1126B_CLKSEL_CON(62), 4, 2, MFLAGS,
RV1126B_CLKGATE_CON(5), 4, GFLAGS),
DIV(CLK_AISP_PLL, "clk_aisp_pll", "clk_aisp_pll_src", 0,
RV1126B_CLKSEL_CON(62), 0, 3, DFLAGS),
COMPOSITE(CLK_CPLL_DIV10, "clk_cpll_div10", clk_cpll_div10_p, 0,
RV1126B_CLKSEL_CON(1), 15, 1, MFLAGS, 5, 5, DFLAGS,

View File

@@ -72,6 +72,75 @@ static struct kbase_process *find_process_node(struct rb_node *node, pid_t tgid)
return kprcs;
}
static ssize_t kbase_kctx_attr_show(struct kobject *kobj, struct attribute *attr, char *buf)
{
struct kobj_attribute *kattr = container_of(attr, struct kobj_attribute, attr);
if (kattr->show)
return kattr->show(kobj, kattr, buf);
return -EIO;
}
static ssize_t kbase_total_gpu_mem_show(struct kobject *kobj, struct kobj_attribute *attr, char *buf)
{
struct kbase_context *kctx = container_of(kobj, struct kbase_context, kobj);
return scnprintf(buf, PAGE_SIZE, "%zu\n", kctx->kprcs->total_gpu_pages << PAGE_SHIFT);
}
static ssize_t kbase_private_gpu_mem_show(struct kobject *kobj, struct kobj_attribute *attr, char *buf)
{
struct kbase_context *kctx = container_of(kobj, struct kbase_context, kobj);
struct kbase_process *kprcs = kctx->kprcs;
struct kbase_context *tmp_kctx;
size_t total_pages = 0;
/* Sum up used_pages from all contexts in the process */
list_for_each_entry(tmp_kctx, &kprcs->kctx_list, kprcs_link) {
total_pages += atomic_read(&tmp_kctx->used_pages);
}
return scnprintf(buf, PAGE_SIZE, "%zu\n", total_pages << PAGE_SHIFT);
}
static struct kobj_attribute kbase_total_gpu_mem_attr = {
.attr = {
.name = "total_gpu_mem",
.mode = 0444,
},
.show = kbase_total_gpu_mem_show,
.store = NULL,
};
static struct kobj_attribute kbase_private_gpu_mem_attr = {
.attr = {
.name = "private_gpu_mem",
.mode = 0444,
},
.show = kbase_private_gpu_mem_show,
.store = NULL,
};
static struct attribute *kbase_kctx_attrs[] = {
&kbase_total_gpu_mem_attr.attr,
&kbase_private_gpu_mem_attr.attr,
NULL,
};
static const struct attribute_group kbase_kctx_attr_group = {
.attrs = kbase_kctx_attrs,
};
static const struct sysfs_ops kbase_kctx_sysfs_ops = {
.show = kbase_kctx_attr_show,
};
static const struct kobj_type kbase_kctx_ktype = {
.sysfs_ops = &kbase_kctx_sysfs_ops,
.default_groups = (const struct attribute_group *[]) { &kbase_kctx_attr_group, NULL },
};
/**
* kbase_insert_kctx_to_process - Initialise kbase process context.
*
@@ -100,6 +169,8 @@ static int kbase_insert_kctx_to_process(struct kbase_context *kctx)
*/
if (!kprcs) {
struct rb_node **new = &prcs_root->rb_node, *parent = NULL;
char kctx_name[64];
int ret = 0;
kprcs = kzalloc(sizeof(*kprcs), GFP_KERNEL);
if (kprcs == NULL)
@@ -109,6 +180,15 @@ static int kbase_insert_kctx_to_process(struct kbase_context *kctx)
kprcs->dma_buf_root = RB_ROOT;
kprcs->total_gpu_pages = 0;
if (unlikely(!scnprintf(kctx_name, 64, "%d", tgid)))
return -ENOMEM;
ret = kobject_init_and_add(&kctx->kobj, &kbase_kctx_ktype, kctx->kbdev->kprcs_kobj, kctx_name);
if (ret) {
dev_err(kctx->kbdev->dev, "Failed to create kctx kobject");
kobject_put(&kctx->kobj);
}
while (*new) {
struct kbase_process *prcs_node;
@@ -260,6 +340,7 @@ static void kbase_remove_kctx_from_process(struct kbase_context *kctx)
* we can remove it from the process rb_tree.
*/
if (list_empty(&kprcs->kctx_list)) {
kobject_put(&kctx->kobj);
rb_erase(&kprcs->kprcs_node, &kctx->kbdev->process_root);
/* Add checks, so that the terminating process Should not
* hold any gpu_memory.

View File

@@ -3182,6 +3182,56 @@ static ssize_t gpuinfo_show(struct device *dev, struct device_attribute *attr, c
}
static DEVICE_ATTR_RO(gpuinfo);
/**
* gpumem_private_show - Show callback for the gpumem_private sysfs entry.
* @dev: The device this sysfs file is for.
* @attr: The attributes of the sysfs file.
* @buf: The output buffer to receive the GPU memory information.
*
* This function is called to get the current number of pages used by the GPU.
* The returned value is in bytes.
*
* Return: The number of bytes output to @buf.
*/
static ssize_t private_gpu_mem_show(struct device *dev, struct device_attribute *attr, char *buf)
{
struct kbase_device *kbdev;
CSTD_UNUSED(attr);
kbdev = to_kbase_device(dev);
if (!kbdev)
return -ENODEV;
return scnprintf(buf, PAGE_SIZE, "%llu\n", (u64)atomic_read(&(kbdev->memdev.used_pages)) << PAGE_SHIFT);
}
static DEVICE_ATTR_RO(private_gpu_mem);
/**
* total_gpu_mem_show - Show callback for the total_gpu_mem sysfs entry.
* @dev: The device this sysfs file is for.
* @attr: The attributes of the sysfs file.
* @buf: The output buffer to receive the GPU memory information.
*
* This function is called to get the total GPU memory including dmabuf memory.
* The returned value is in bytes.
*
* Return: The number of bytes output to @buf.
*/
static ssize_t total_gpu_mem_show(struct device *dev, struct device_attribute *attr, char *buf)
{
struct kbase_device *kbdev;
CSTD_UNUSED(attr);
kbdev = to_kbase_device(dev);
if (!kbdev)
return -ENODEV;
return scnprintf(buf, PAGE_SIZE, "%zu\n", kbdev->total_gpu_pages << PAGE_SHIFT);
}
static DEVICE_ATTR_RO(total_gpu_mem);
/**
* dvfs_period_store - Store callback for the dvfs_period sysfs file.
* @dev: The device with sysfs file is for
@@ -5556,6 +5606,8 @@ static struct attribute *kbase_attrs[] = {
&dev_attr_soft_job_timeout.attr,
#endif /* !MALI_USE_CSF */
&dev_attr_gpuinfo.attr,
&dev_attr_total_gpu_mem.attr,
&dev_attr_private_gpu_mem.attr,
&dev_attr_dvfs_period.attr,
&dev_attr_pm_poweroff.attr,
&dev_attr_reset_timeout.attr,
@@ -5631,6 +5683,14 @@ int kbase_sysfs_init(struct kbase_device *kbdev)
sysfs_remove_group(&kbdev->dev->kobj, &kbase_attr_group);
}
kbdev->kprcs_kobj = kobject_create_and_add("kprcs", &kbdev->dev->kobj);
if (!kbdev->kprcs_kobj) {
dev_err(kbdev->dev, "Creation of kprcs sysfs group failed");
sysfs_remove_group(&kbdev->dev->kobj, &kbase_mempool_attr_group);
sysfs_remove_group(&kbdev->dev->kobj, &kbase_scheduling_attr_group);
sysfs_remove_group(&kbdev->dev->kobj, &kbase_attr_group);
}
return err;
}
@@ -5639,6 +5699,7 @@ void kbase_sysfs_term(struct kbase_device *kbdev)
sysfs_remove_group(&kbdev->dev->kobj, &kbase_mempool_attr_group);
sysfs_remove_group(&kbdev->dev->kobj, &kbase_scheduling_attr_group);
sysfs_remove_group(&kbdev->dev->kobj, &kbase_attr_group);
kobject_put(kbdev->kprcs_kobj);
put_device(kbdev->dev);
}

View File

@@ -1109,6 +1109,7 @@ struct kbase_device {
unsigned int nr_regulators;
#endif /* CONFIG_REGULATOR */
char devname[DEVNAME_SIZE];
struct kobject *kprcs_kobj;
u32 id;
#if !IS_ENABLED(CONFIG_MALI_REAL_HW)
@@ -1901,6 +1902,7 @@ struct kbase_sub_alloc {
* is made on the device file.
*/
struct kbase_context {
struct kobject kobj;
struct file *filp;
struct kbase_device *kbdev;
struct list_head kctx_list_link;

View File

@@ -63,7 +63,7 @@ endif
#
# Driver version string which is returned to userspace via an ioctl
MALI_RELEASE_NAME ?= '"g28p0-00eac0"'
MALI_RELEASE_NAME ?= '"g29p0-00eac0"'
# Set up defaults if not defined by build system
ifeq ($(CONFIG_MALI_VALHALL_DEBUG), y)
MALI_UNIT_TEST = 1
@@ -79,13 +79,10 @@ MALI_PLATFORM_DIR := $(shell echo $(CONFIG_MALI_VALHALL_PLATFORM_NAME))
ifeq ($(CONFIG_MALI_VALHALL_CSF_SUPPORT),y)
MALI_JIT_PRESSURE_LIMIT_BASE = 0
MALI_USE_CSF = 1
else
MALI_JIT_PRESSURE_LIMIT_BASE ?= 1
MALI_USE_CSF ?= 0
endif
ifneq ($(CONFIG_MALI_VALHALL_KUTF), n)
MALI_KERNEL_TEST_API ?= 1
else
@@ -104,7 +101,6 @@ endif
#
ccflags-y = \
-DMALI_CUSTOMER_RELEASE=$(MALI_CUSTOMER_RELEASE) \
-DMALI_USE_CSF=$(MALI_USE_CSF) \
-DMALI_KERNEL_TEST_API=$(MALI_KERNEL_TEST_API) \
-DMALI_UNIT_TEST=$(MALI_UNIT_TEST) \
-DMALI_COVERAGE=$(MALI_COVERAGE) \
@@ -112,7 +108,6 @@ ccflags-y = \
-DMALI_JIT_PRESSURE_LIMIT_BASE=$(MALI_JIT_PRESSURE_LIMIT_BASE) \
-DMALI_PLATFORM_DIR=$(MALI_PLATFORM_DIR)
ifeq ($(KBUILD_EXTMOD),)
# in-tree
ccflags-y +=-DMALI_KBASE_PLATFORM_PATH=../../$(src)/platform/$(CONFIG_MALI_VALHALL_PLATFORM_NAME)
@@ -183,23 +178,6 @@ valhall_kbase-$(CONFIG_MALI_VALHALL_TRACE_POWER_GPU_WORK_PERIOD) += \
mali_power_gpu_work_period_trace.o \
mali_kbase_gpu_metrics.o
ifneq ($(CONFIG_MALI_VALHALL_CSF_SUPPORT),y)
valhall_kbase-y += \
mali_kbase_jm.o \
mali_kbase_dummy_job_wa.o \
mali_kbase_debug_job_fault.o \
mali_kbase_event.o \
mali_kbase_jd.o \
mali_kbase_jd_debugfs.o \
mali_kbase_js.o \
mali_kbase_js_ctx_attr.o \
mali_kbase_kinstr_jm.o
valhall_kbase-$(CONFIG_SYNC_FILE) += \
mali_kbase_fence_ops.o \
mali_kbase_fence.o
endif
INCLUDE_SUBDIR = \
$(src)/arbiter/Kbuild \

View File

@@ -324,15 +324,6 @@ config MALI_VALHALL_HW_ERRATA_1485982_USE_CLOCK_ALTERNATIVE
endif
config MALI_VALHALL_ARBITRATION
tristate "Enable Virtualization reference code"
depends on MALI_VALHALL
default n
help
Enables the build of several reference modules used in the reference
virtualization setup for Mali
If unsure, say N.
config MALI_VALHALL_TRACE_POWER_GPU_WORK_PERIOD
bool "Enable per-application GPU metrics tracepoints"
depends on MALI_VALHALL

View File

@@ -39,7 +39,6 @@ ifeq ($(MALI_KCONFIG_EXT_PREFIX),)
CONFIG_MALI_VALHALL_PLATFORM_NAME ?= "devicetree"
CONFIG_MALI_VALHALL_TRACE_POWER_GPU_WORK_PERIOD ?= y
CONFIG_MALI_BIFROST_GATOR_SUPPORT ?= y
CONFIG_MALI_VALHALL_ARBITRATION ?= n
CONFIG_MALI_KUTF_PTM_TESTS ?= n
@@ -143,7 +142,6 @@ ifeq ($(MALI_KCONFIG_EXT_PREFIX),)
endif
else
# Prevent misuse when CONFIG_MALI_BIFROST=n
CONFIG_MALI_VALHALL_ARBITRATION = n
CONFIG_MALI_VALHALL_KUTF = n
CONFIG_MALI_VALHALL_KUTF_IRQ_TEST = n
CONFIG_MALI_VALHALL_KUTF_CLK_RATE_TRACE = n
@@ -155,7 +153,6 @@ ifeq ($(MALI_KCONFIG_EXT_PREFIX),)
CONFIG_MALI_BIFROST \
CONFIG_MALI_VALHALL_CSF_SUPPORT \
CONFIG_MALI_BIFROST_GATOR_SUPPORT \
CONFIG_MALI_VALHALL_ARBITRATION \
CONFIG_MALI_KUTF_PTM_TESTS \
CONFIG_MALI_VALHALL_REAL_HW \
CONFIG_MALI_BIFROST_DEVFREQ \

View File

@@ -36,264 +36,6 @@
#error "Unsupported Mali Arbiter interface version."
#endif
static void on_max_config(struct device *dev, uint32_t max_l2_slices, uint32_t max_core_mask)
{
struct kbase_device *kbdev;
if (!dev) {
pr_err("%s(): dev is NULL", __func__);
return;
}
kbdev = dev_get_drvdata(dev);
if (!kbdev) {
dev_err(dev, "%s(): kbdev is NULL", __func__);
return;
}
if (!max_l2_slices || !max_core_mask) {
dev_dbg(dev, "%s(): max_config ignored as one of the fields is zero", __func__);
return;
}
/* set the max config info in the kbase device */
kbase_arbiter_set_max_config(kbdev, max_l2_slices, max_core_mask);
}
/**
* on_update_freq() - Updates GPU clock frequency
* @dev: arbiter interface device handle
* @freq: GPU clock frequency value reported from arbiter
*
* call back function to update GPU clock frequency with
* new value from arbiter
*/
static void on_update_freq(struct device *dev, uint32_t freq)
{
struct kbase_device *kbdev;
if (!dev) {
pr_err("%s(): dev is NULL", __func__);
return;
}
kbdev = dev_get_drvdata(dev);
if (!kbdev) {
dev_err(dev, "%s(): kbdev is NULL", __func__);
return;
}
kbase_arbiter_pm_update_gpu_freq(&kbdev->arb.arb_freq, freq);
}
/**
* on_gpu_stop() - sends KBASE_VM_GPU_STOP_EVT event on VM stop
* @dev: arbiter interface device handle
*
* call back function to signal a GPU STOP event from arbiter interface
*/
static void on_gpu_stop(struct device *dev)
{
struct kbase_device *kbdev;
if (!dev) {
pr_err("%s(): dev is NULL", __func__);
return;
}
kbdev = dev_get_drvdata(dev);
if (!kbdev) {
dev_err(dev, "%s(): kbdev is NULL", __func__);
return;
}
KBASE_TLSTREAM_TL_ARBITER_STOP_REQUESTED(kbdev, kbdev);
KBASE_KTRACE_ADD(kbdev, ARB_GPU_STOP_REQUESTED, NULL, 0);
kbase_arbiter_pm_vm_event(kbdev, KBASE_VM_GPU_STOP_EVT);
}
/**
* on_gpu_granted() - sends KBASE_VM_GPU_GRANTED_EVT event on GPU granted
* @dev: arbiter interface device handle
*
* call back function to signal a GPU GRANT event from arbiter interface
*/
static void on_gpu_granted(struct device *dev)
{
struct kbase_device *kbdev;
if (!dev) {
pr_err("%s(): dev is NULL", __func__);
return;
}
kbdev = dev_get_drvdata(dev);
if (!kbdev) {
dev_err(dev, "%s(): kbdev is NULL", __func__);
return;
}
KBASE_TLSTREAM_TL_ARBITER_GRANTED(kbdev, kbdev);
KBASE_KTRACE_ADD(kbdev, ARB_GPU_GRANTED, NULL, 0);
kbase_arbiter_pm_vm_event(kbdev, KBASE_VM_GPU_GRANTED_EVT);
}
/**
* on_gpu_lost() - sends KBASE_VM_GPU_LOST_EVT event on GPU granted
* @dev: arbiter interface device handle
*
* call back function to signal a GPU LOST event from arbiter interface
*/
static void on_gpu_lost(struct device *dev)
{
struct kbase_device *kbdev;
if (!dev) {
pr_err("%s(): dev is NULL", __func__);
return;
}
kbdev = dev_get_drvdata(dev);
if (!kbdev) {
dev_err(dev, "%s(): kbdev is NULL", __func__);
return;
}
KBASE_TLSTREAM_TL_ARBITER_LOST(kbdev, kbdev);
KBASE_KTRACE_ADD(kbdev, ARB_GPU_LOST, NULL, 0);
kbase_arbiter_pm_vm_event(kbdev, KBASE_VM_GPU_LOST_EVT);
}
static int kbase_arbif_of_init(struct kbase_device *kbdev)
{
struct arbiter_if_dev *arb_if;
struct device_node *arbiter_if_node;
struct platform_device *pdev;
if (!IS_ENABLED(CONFIG_OF)) {
/*
* Return -ENODEV in the event CONFIG_OF is not available and let the
* internal AW check for suitability for arbitration.
*/
return -ENODEV;
}
arbiter_if_node = of_parse_phandle(kbdev->dev->of_node, "arbiter-if", 0);
if (!arbiter_if_node)
arbiter_if_node = of_parse_phandle(kbdev->dev->of_node, "arbiter_if", 0);
if (!arbiter_if_node) {
dev_dbg(kbdev->dev, "No arbiter_if in Device Tree");
/* no arbiter interface defined in device tree */
kbdev->arb.arb_dev = NULL;
kbdev->arb.arb_if = NULL;
return -ENODEV;
}
pdev = of_find_device_by_node(arbiter_if_node);
if (!pdev) {
dev_err(kbdev->dev, "Failed to find arbiter_if device");
return -EPROBE_DEFER;
}
if (!pdev->dev.driver || !try_module_get(pdev->dev.driver->owner)) {
dev_err(kbdev->dev, "arbiter_if driver not available");
put_device(&pdev->dev);
return -EPROBE_DEFER;
}
kbdev->arb.arb_dev = &pdev->dev;
arb_if = platform_get_drvdata(pdev);
if (!arb_if) {
dev_err(kbdev->dev, "arbiter_if driver not ready");
module_put(pdev->dev.driver->owner);
put_device(&pdev->dev);
return -EPROBE_DEFER;
}
kbdev->arb.arb_if = arb_if;
return 0;
}
static void kbase_arbif_of_term(struct kbase_device *kbdev)
{
if (!IS_ENABLED(CONFIG_OF))
return;
if (kbdev->arb.arb_dev) {
module_put(kbdev->arb.arb_dev->driver->owner);
put_device(kbdev->arb.arb_dev);
}
kbdev->arb.arb_dev = NULL;
}
/**
* kbase_arbif_init() - Kbase Arbiter interface initialisation.
* @kbdev: The kbase device structure for the device (must be a valid pointer)
*
* Initialise Kbase Arbiter interface and assign callback functions.
*
* Return:
* * 0 - the interface was initialized or was not specified
* * in the device tree.
* * -EFAULT - the interface was specified but failed to initialize.
* * -EPROBE_DEFER - module dependencies are not yet available.
*/
int kbase_arbif_init(struct kbase_device *kbdev)
{
struct arbiter_if_arb_vm_ops ops;
struct arbiter_if_dev *arb_if;
int err = 0;
/* Tries to init with 'arbiter-if' if present in devicetree */
err = kbase_arbif_of_init(kbdev);
if (err == -ENODEV) {
/* devicetree does not support arbitration */
return -EPERM;
}
if (err)
return err;
ops.arb_vm_gpu_stop = on_gpu_stop;
ops.arb_vm_gpu_granted = on_gpu_granted;
ops.arb_vm_gpu_lost = on_gpu_lost;
ops.arb_vm_max_config = on_max_config;
ops.arb_vm_update_freq = on_update_freq;
kbdev->arb.arb_freq.arb_freq = 0;
kbdev->arb.arb_freq.freq_updated = false;
mutex_init(&kbdev->arb.arb_freq.arb_freq_lock);
arb_if = kbdev->arb.arb_if;
if (arb_if == NULL) {
dev_err(kbdev->dev, "No arbiter interface present");
goto failure_term;
}
if (!arb_if->vm_ops.vm_arb_register_dev) {
dev_err(kbdev->dev, "arbiter_if registration callback not present");
goto failure_term;
}
/* register kbase arbiter_if callbacks */
err = arb_if->vm_ops.vm_arb_register_dev(arb_if, kbdev->dev, &ops);
if (err) {
dev_err(kbdev->dev, "Failed to register with arbiter. (err = %d)", err);
goto failure_term;
}
return 0;
failure_term:
{
kbase_arbif_of_term(kbdev);
}
if (err != -EPROBE_DEFER)
err = -EFAULT;
return err;
}
/**
* kbase_arbif_destroy() - De-init Kbase arbiter interface
@@ -308,9 +50,6 @@ void kbase_arbif_destroy(struct kbase_device *kbdev)
if (arb_if && arb_if->vm_ops.vm_arb_unregister_dev)
arb_if->vm_ops.vm_arb_unregister_dev(kbdev->arb.arb_if);
{
kbase_arbif_of_term(kbdev);
}
kbdev->arb.arb_if = NULL;
}

View File

@@ -51,21 +51,6 @@ enum kbase_arbif_evt {
};
/**
* kbase_arbif_init() - Initialize the arbiter interface functionality.
* @kbdev: The kbase device structure for the device (must be a valid pointer)
*
* Initialize the arbiter interface and also determines
* if Arbiter functionality is required.
*
* Return:
* * 0 - the interface was initialized or was not specified
* * in the device tree.
* * -EFAULT - the interface was specified but failed to initialize.
* * -EPROBE_DEFER - module dependencies are not yet available.
*/
int kbase_arbif_init(struct kbase_device *kbdev);
/**
* kbase_arbif_destroy() - Cleanups the arbiter interface functionality.
* @kbdev: The kbase device structure for the device (must be a valid pointer)

View File

@@ -31,9 +31,7 @@
#include <mali_kbase_gpuprops.h>
#include <mali_kbase_io.h>
#if MALI_USE_CSF
#include <csf/mali_kbase_csf_scheduler.h>
#endif
/* A dmesg warning will occur if the GPU is not granted
* after the following time (in milliseconds) has ellapsed.
@@ -299,7 +297,9 @@ int kbase_arbiter_pm_early_init(struct kbase_device *kbdev)
arb_vm_state->vm_request_timer.function = request_timer_callback;
kbdev->pm.arb_vm_state = arb_vm_state;
err = kbase_arbif_init(kbdev);
/* platform does not support arbitration */
err = -EPERM;
if (err) {
if (err != -EPERM)
dev_err(kbdev->dev, "Failed to initialise arbif module. (err = %d)", err);
@@ -360,10 +360,8 @@ void kbase_arbiter_pm_early_term(struct kbase_device *kbdev)
cancel_request_timer(kbdev);
mutex_lock(&arb_vm_state->vm_state_lock);
if (arb_vm_state->vm_state > KBASE_VM_STATE_STOPPED_GPU_REQUESTED) {
kbase_io_clear_status(kbdev->io, KBASE_IO_STATUS_AW_REMOVED);
if (arb_vm_state->vm_state > KBASE_VM_STATE_STOPPED_GPU_REQUESTED)
kbase_arbif_gpu_stopped(kbdev, false);
}
mutex_unlock(&arb_vm_state->vm_state_lock);
destroy_workqueue(arb_vm_state->vm_arb_wq);
kbase_arbif_destroy(kbdev);
@@ -410,6 +408,7 @@ void kbase_arbiter_pm_vm_stopped(struct kbase_device *kbdev)
{
bool request_gpu = false;
struct kbase_arbiter_vm_state *arb_vm_state = kbdev->pm.arb_vm_state;
unsigned long flags;
lockdep_assert_held(&arb_vm_state->vm_state_lock);
@@ -420,17 +419,6 @@ void kbase_arbiter_pm_vm_stopped(struct kbase_device *kbdev)
dev_dbg(kbdev->dev, "%s %s\n", __func__,
kbase_arbiter_pm_vm_state_str(arb_vm_state->vm_state));
/*
* Release the interrupts on external arb_if to address Xen requirements.
* Interrupts are not released with internal arb_if as the IRQs are required
* to handle messaging to/from Arbiter/Resource Group.
*/
if (arb_vm_state->interrupts_installed
) {
arb_vm_state->interrupts_installed = false;
kbase_release_interrupts(kbdev);
}
switch (arb_vm_state->vm_state) {
case KBASE_VM_STATE_STOPPING_ACTIVE:
request_gpu = true;
@@ -447,7 +435,17 @@ void kbase_arbiter_pm_vm_stopped(struct kbase_device *kbdev)
break;
}
kbase_io_clear_status(kbdev->io, KBASE_IO_STATUS_AW_REMOVED);
spin_lock_irqsave(&kbdev->hwaccess_lock, flags);
if (kbdev->pm.backend.gpu_lost_pending) {
{
kbdev->csf.firmware_reload_needed = true;
dev_warn(kbdev->dev, "%s(): GPU LOST detected, marking MCU for cold boot",
__func__);
}
}
kbase_io_set_status(kbdev->io, KBASE_IO_STATUS_AW_REMOVED);
kbdev->pm.backend.gpu_lost_pending = false;
spin_unlock_irqrestore(&kbdev->hwaccess_lock, flags);
{
kbase_arbif_gpu_stopped(kbdev, request_gpu);
@@ -550,16 +548,6 @@ static void kbase_arbiter_pm_vm_gpu_start(struct kbase_device *kbdev)
break;
case KBASE_VM_STATE_STOPPED_GPU_REQUESTED:
kbase_arbiter_pm_vm_set_state(kbdev, KBASE_VM_STATE_STARTING);
arb_vm_state->interrupts_installed = true;
/*
* Re-install interrupts that were released for external arb_if to
* address Xen requirements. Interrupts are not released with internal
* arb_if as the IRQs are required to handle messaging to/from
* Arbiter/Resource Group.
*/
{
kbase_install_interrupts(kbdev);
}
/*
* GPU GRANTED received while in stop can be a result of a
* repartitioning.
@@ -569,7 +557,6 @@ static void kbase_arbiter_pm_vm_gpu_start(struct kbase_device *kbdev)
queue_work(arb_vm_state->vm_arb_wq, &arb_vm_state->vm_resume_work);
break;
case KBASE_VM_STATE_SUSPEND_WAIT_FOR_GRANT:
kbase_io_clear_status(kbdev->io, KBASE_IO_STATUS_AW_REMOVED);
kbase_arbif_gpu_stopped(kbdev, false);
kbase_arbiter_pm_vm_set_state(kbdev, KBASE_VM_STATE_SUSPENDED);
break;
@@ -637,7 +624,6 @@ static void kbase_arbiter_pm_vm_gpu_stop(struct kbase_device *kbdev)
static void kbase_gpu_lost(struct kbase_device *kbdev)
{
struct kbase_arbiter_vm_state *arb_vm_state = kbdev->pm.arb_vm_state;
bool handle_gpu_lost = false;
lockdep_assert_held(&arb_vm_state->vm_state_lock);
@@ -648,13 +634,11 @@ static void kbase_gpu_lost(struct kbase_device *kbdev)
dev_warn(kbdev->dev, "GPU lost in state %s",
kbase_arbiter_pm_vm_state_str(arb_vm_state->vm_state));
kbase_arbiter_pm_vm_gpu_stop(kbdev);
handle_gpu_lost = true;
break;
case KBASE_VM_STATE_STOPPING_IDLE:
case KBASE_VM_STATE_STOPPING_ACTIVE:
case KBASE_VM_STATE_SUSPEND_PENDING:
dev_dbg(kbdev->dev, "GPU lost while stopping");
handle_gpu_lost = true;
dev_warn(kbdev->dev, "GPU lost while stopping");
break;
case KBASE_VM_STATE_SUSPENDED:
case KBASE_VM_STATE_STOPPED:
@@ -668,8 +652,6 @@ static void kbase_gpu_lost(struct kbase_device *kbdev)
default:
break;
}
if (handle_gpu_lost)
kbase_pm_handle_gpu_lost(kbdev);
}
/**
@@ -798,6 +780,7 @@ static void kbase_arbiter_pm_vm_os_resume(struct kbase_device *kbdev)
void kbase_arbiter_pm_vm_event(struct kbase_device *kbdev, enum kbase_arbif_evt evt)
{
struct kbase_arbiter_vm_state *arb_vm_state = kbdev->pm.arb_vm_state;
unsigned long flags;
if (!kbase_has_arbiter(kbdev))
return;
@@ -816,6 +799,13 @@ void kbase_arbiter_pm_vm_event(struct kbase_device *kbdev, enum kbase_arbif_evt
break;
case KBASE_VM_GPU_LOST_EVT:
dev_dbg(kbdev->dev, "KBASE_ARBIF_GPU_LOST_EVT!");
spin_lock_irqsave(&kbdev->hwaccess_lock, flags);
if (!kbdev->pm.backend.gpu_lost_pending) {
dev_dbg(kbdev->dev, "skipping GPU_LOST handling");
spin_unlock_irqrestore(&kbdev->hwaccess_lock, flags);
break;
}
spin_unlock_irqrestore(&kbdev->hwaccess_lock, flags);
kbase_gpu_lost(kbdev);
break;
case KBASE_VM_OS_SUSPEND_EVENT:
@@ -933,10 +923,6 @@ int kbase_arbiter_pm_ctx_active_handle_suspend(struct kbase_device *kbdev,
struct kbase_arbiter_vm_state *arb_vm_state = kbdev->pm.arb_vm_state;
int res = 0;
#if !MALI_USE_CSF
CSTD_UNUSED(sched_lock_held);
#endif
if (!kbase_has_arbiter(kbdev))
return res;
@@ -949,7 +935,8 @@ int kbase_arbiter_pm_ctx_active_handle_suspend(struct kbase_device *kbdev,
kbase_arbiter_pm_vm_set_state(kbdev, KBASE_VM_STATE_STOPPED_GPU_REQUESTED);
kbase_arbif_gpu_request(kbdev);
start_request_timer(kbdev);
} else if (arb_vm_state->vm_state == KBASE_VM_STATE_STOPPING_ACTIVE) {
} else if (suspend_handler != KBASE_PM_SUSPEND_HANDLER_NOT_POSSIBLE &&
arb_vm_state->vm_state == KBASE_VM_STATE_STOPPING_ACTIVE) {
res = 1;
break;
} else if (arb_vm_state->vm_state == KBASE_VM_STATE_INITIALIZING_WITH_GPU)
@@ -985,15 +972,11 @@ int kbase_arbiter_pm_ctx_active_handle_suspend(struct kbase_device *kbdev,
atomic_inc(&kbdev->pm.gpu_users_waiting);
mutex_unlock(&arb_vm_state->vm_state_lock);
kbase_pm_unlock(kbdev);
#if MALI_USE_CSF
if (sched_lock_held)
kbase_csf_scheduler_unlock(kbdev);
#endif
kbase_arbiter_pm_vm_wait_gpu_assignment(kbdev);
#if MALI_USE_CSF
if (sched_lock_held)
kbase_csf_scheduler_lock(kbdev);
#endif
kbase_pm_lock(kbdev);
mutex_lock(&arb_vm_state->vm_state_lock);
atomic_dec(&kbdev->pm.gpu_users_waiting);

View File

@@ -1,6 +1,6 @@
# SPDX-License-Identifier: GPL-2.0 WITH Linux-syscall-note
#
# (C) COPYRIGHT 2014-2023 ARM Limited. All rights reserved.
# (C) COPYRIGHT 2014-2024 ARM Limited. All rights reserved.
#
# This program is free software and is provided to you under the terms of the
# GNU General Public License version 2 as published by the Free Software
@@ -33,16 +33,6 @@ valhall_kbase-y += \
backend/gpu/mali_kbase_l2_mmu_config.o \
backend/gpu/mali_kbase_clk_rate_trace_mgr.o
ifeq ($(MALI_USE_CSF),0)
valhall_kbase-y += \
backend/gpu/mali_kbase_instr_backend.o \
backend/gpu/mali_kbase_jm_as.o \
backend/gpu/mali_kbase_debug_job_fault_backend.o \
backend/gpu/mali_kbase_jm_hw.o \
backend/gpu/mali_kbase_jm_rb.o \
backend/gpu/mali_kbase_js_backend.o
endif
valhall_kbase-$(CONFIG_MALI_VALHALL_DEVFREQ) += \
backend/gpu/mali_kbase_devfreq.o

View File

@@ -1,7 +1,7 @@
// SPDX-License-Identifier: GPL-2.0 WITH Linux-syscall-note
/*
*
* (C) COPYRIGHT 2014-2023 ARM Limited. All rights reserved.
* (C) COPYRIGHT 2014-2024 ARM Limited. All rights reserved.
*
* This program is free software and is provided to you under the terms of the
* GNU General Public License version 2 as published by the Free Software
@@ -27,7 +27,6 @@ void kbase_cache_set_coherency_mode(struct kbase_device *kbdev, u32 mode)
kbdev->current_gpu_coherency_mode = mode;
#if MALI_USE_CSF
if (kbdev->gpu_props.gpu_id.arch_id >= GPU_ID_ARCH_MAKE(12, 0, 1)) {
/* AMBA_ENABLE present from 12.0.1 */
u32 val = kbase_reg_read32(kbdev, GPU_CONTROL_ENUM(AMBA_ENABLE));
@@ -38,14 +37,10 @@ void kbase_cache_set_coherency_mode(struct kbase_device *kbdev, u32 mode)
/* Fallback to COHERENCY_ENABLE for older versions */
kbase_reg_write32(kbdev, GPU_CONTROL_ENUM(COHERENCY_ENABLE), mode);
}
#else /* MALI_USE_CSF */
kbase_reg_write32(kbdev, GPU_CONTROL_ENUM(COHERENCY_ENABLE), mode);
#endif /* MALI_USE_CSF */
}
void kbase_amba_set_shareable_cache_support(struct kbase_device *kbdev)
{
#if MALI_USE_CSF
/* AMBA registers only present from 12.0.1 */
if (kbdev->gpu_props.gpu_id.arch_id < GPU_ID_ARCH_MAKE(12, 0, 1))
@@ -60,5 +55,4 @@ void kbase_amba_set_shareable_cache_support(struct kbase_device *kbdev)
kbase_reg_write32(kbdev, GPU_CONTROL_ENUM(AMBA_ENABLE), val);
}
}
#endif /* MALI_USE_CSF */
}

View File

@@ -1,167 +0,0 @@
// SPDX-License-Identifier: GPL-2.0 WITH Linux-syscall-note
/*
*
* (C) COPYRIGHT 2012-2023 ARM Limited. All rights reserved.
*
* This program is free software and is provided to you under the terms of the
* GNU General Public License version 2 as published by the Free Software
* Foundation, and any use by you of this program is subject to the terms
* of such GNU license.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program; if not, you can access it online at
* http://www.gnu.org/licenses/gpl-2.0.html.
*
*/
#include <mali_kbase.h>
#include <device/mali_kbase_device.h>
#include <hw_access/mali_kbase_hw_access.h>
#include "mali_kbase_debug_job_fault.h"
#if IS_ENABLED(CONFIG_DEBUG_FS)
/*GPU_CONTROL_REG(r)*/
static unsigned int gpu_control_reg_snapshot[] = { GPU_CONTROL_ENUM(GPU_ID),
GPU_CONTROL_ENUM(SHADER_READY),
GPU_CONTROL_ENUM(TILER_READY),
GPU_CONTROL_ENUM(L2_READY) };
/* JOB_CONTROL_REG(r) */
static unsigned int job_control_reg_snapshot[] = { JOB_CONTROL_ENUM(JOB_IRQ_MASK),
JOB_CONTROL_ENUM(JOB_IRQ_STATUS) };
/* JOB_SLOT_REG(n,r) */
static unsigned int job_slot_reg_snapshot[] = {
JOB_SLOT_ENUM(0, HEAD) - JOB_SLOT_BASE_ENUM(0),
JOB_SLOT_ENUM(0, TAIL) - JOB_SLOT_BASE_ENUM(0),
JOB_SLOT_ENUM(0, AFFINITY) - JOB_SLOT_BASE_ENUM(0),
JOB_SLOT_ENUM(0, CONFIG) - JOB_SLOT_BASE_ENUM(0),
JOB_SLOT_ENUM(0, STATUS) - JOB_SLOT_BASE_ENUM(0),
JOB_SLOT_ENUM(0, HEAD_NEXT) - JOB_SLOT_BASE_ENUM(0),
JOB_SLOT_ENUM(0, AFFINITY_NEXT) - JOB_SLOT_BASE_ENUM(0),
JOB_SLOT_ENUM(0, CONFIG_NEXT) - JOB_SLOT_BASE_ENUM(0)
};
/*MMU_CONTROL_REG(r)*/
static unsigned int mmu_reg_snapshot[] = { MMU_CONTROL_ENUM(IRQ_MASK),
MMU_CONTROL_ENUM(IRQ_STATUS) };
/* MMU_AS_REG(n,r) */
static unsigned int as_reg_snapshot[] = { MMU_AS_ENUM(0, TRANSTAB) - MMU_AS_BASE_ENUM(0),
MMU_AS_ENUM(0, TRANSCFG) - MMU_AS_BASE_ENUM(0),
MMU_AS_ENUM(0, MEMATTR) - MMU_AS_BASE_ENUM(0),
MMU_AS_ENUM(0, FAULTSTATUS) - MMU_AS_BASE_ENUM(0),
MMU_AS_ENUM(0, FAULTADDRESS) - MMU_AS_BASE_ENUM(0),
MMU_AS_ENUM(0, STATUS) - MMU_AS_BASE_ENUM(0) };
bool kbase_debug_job_fault_reg_snapshot_init(struct kbase_context *kctx, int reg_range)
{
uint i, j;
int offset = 0;
uint slot_number;
uint as_number;
if (kctx->reg_dump == NULL)
return false;
slot_number = kctx->kbdev->gpu_props.num_job_slots;
as_number = kctx->kbdev->gpu_props.num_address_spaces;
/* get the GPU control registers*/
for (i = 0; i < ARRAY_SIZE(gpu_control_reg_snapshot); i++) {
kctx->reg_dump[offset] = gpu_control_reg_snapshot[i];
if (kbase_reg_is_size64(kctx->kbdev, kctx->reg_dump[offset]))
offset += 4;
else
offset += 2;
}
/* get the Job control registers*/
for (i = 0; i < ARRAY_SIZE(job_control_reg_snapshot); i++) {
kctx->reg_dump[offset] = job_control_reg_snapshot[i];
if (kbase_reg_is_size64(kctx->kbdev, kctx->reg_dump[offset]))
offset += 4;
else
offset += 2;
}
/* get the Job Slot registers*/
for (j = 0; j < slot_number; j++) {
for (i = 0; i < ARRAY_SIZE(job_slot_reg_snapshot); i++) {
kctx->reg_dump[offset] = JOB_SLOT_BASE_OFFSET(j) + job_slot_reg_snapshot[i];
if (kbase_reg_is_size64(kctx->kbdev, kctx->reg_dump[offset]))
offset += 4;
else
offset += 2;
}
}
/* get the MMU registers*/
for (i = 0; i < ARRAY_SIZE(mmu_reg_snapshot); i++) {
kctx->reg_dump[offset] = mmu_reg_snapshot[i];
if (kbase_reg_is_size64(kctx->kbdev, kctx->reg_dump[offset]))
offset += 4;
else
offset += 2;
}
/* get the Address space registers*/
for (j = 0; j < as_number; j++) {
for (i = 0; i < ARRAY_SIZE(as_reg_snapshot); i++) {
kctx->reg_dump[offset] = MMU_AS_BASE_OFFSET(j) + as_reg_snapshot[i];
if (kbase_reg_is_size64(kctx->kbdev, kctx->reg_dump[offset]))
offset += 4;
else
offset += 2;
}
}
WARN_ON(offset >= (reg_range * 2 / 4));
/* set the termination flag*/
kctx->reg_dump[offset] = REGISTER_DUMP_TERMINATION_FLAG;
kctx->reg_dump[offset + 1] = REGISTER_DUMP_TERMINATION_FLAG;
dev_dbg(kctx->kbdev->dev, "kbase_job_fault_reg_snapshot_init:%d\n", offset);
return true;
}
bool kbase_job_fault_get_reg_snapshot(struct kbase_context *kctx)
{
int offset = 0;
u32 reg_enum;
u64 val64;
if (kctx->reg_dump == NULL)
return false;
while (kctx->reg_dump[offset] != REGISTER_DUMP_TERMINATION_FLAG) {
reg_enum = kctx->reg_dump[offset];
/* Get register offset from enum */
kbase_reg_get_offset(kctx->kbdev, reg_enum, &kctx->reg_dump[offset]);
if (kbase_reg_is_size64(kctx->kbdev, reg_enum)) {
val64 = kbase_reg_read64(kctx->kbdev, reg_enum);
/* offset computed offset to get _HI offset */
kctx->reg_dump[offset + 2] = kctx->reg_dump[offset] + 4;
kctx->reg_dump[offset + 1] = (u32)(val64 & 0xFFFFFFFF);
kctx->reg_dump[offset + 3] = (u32)(val64 >> 32);
offset += 4;
} else {
kctx->reg_dump[offset + 1] = kbase_reg_read32(kctx->kbdev, reg_enum);
offset += 2;
}
}
return true;
}
#endif

View File

@@ -1,7 +1,7 @@
/* SPDX-License-Identifier: GPL-2.0 WITH Linux-syscall-note */
/*
*
* (C) COPYRIGHT 2014-2023 ARM Limited. All rights reserved.
* (C) COPYRIGHT 2014-2024 ARM Limited. All rights reserved.
*
* This program is free software and is provided to you under the terms of the
* GNU General Public License version 2 as published by the Free Software
@@ -98,12 +98,6 @@ struct slot_rb {
* The hwaccess_lock (a spinlock) must be held when accessing this structure
*/
struct kbase_backend_data {
#if !MALI_USE_CSF
struct slot_rb slot_rb[BASE_JM_MAX_NR_SLOTS];
struct hrtimer scheduling_timer;
bool timer_running;
#endif
bool suspend_timer;
atomic_t reset_gpu;

View File

@@ -1,7 +1,7 @@
// SPDX-License-Identifier: GPL-2.0 WITH Linux-syscall-note
/*
*
* (C) COPYRIGHT 2014-2024 ARM Limited. All rights reserved.
* (C) COPYRIGHT 2014-2025 ARM Limited. All rights reserved.
*
* This program is free software and is provided to you under the terms of the
* GNU General Public License version 2 as published by the Free Software
@@ -195,7 +195,7 @@ static int kbase_devfreq_status(struct device *dev, struct devfreq_dev_status *s
stat->current_frequency = kbdev->current_nominal_freq;
stat->private_data = NULL;
#if MALI_USE_CSF && defined CONFIG_DEVFREQ_THERMAL
#if defined CONFIG_DEVFREQ_THERMAL
if (!kbdev->devfreq_profile.is_cooling_device)
kbase_ipa_reset_data(kbdev);
#endif
@@ -399,7 +399,6 @@ static int kbase_devfreq_init_core_mask_table(struct kbase_device *kbdev)
opp_freq);
continue;
}
#if MALI_USE_CSF
if (kbase_csf_dev_has_ne(kbdev)) {
u64 neural_present = kbdev->gpu_props.neural_present;
u64 sc_with_ne = shader_present & neural_present;
@@ -423,7 +422,6 @@ static int kbase_devfreq_init_core_mask_table(struct kbase_device *kbdev)
continue;
}
}
#endif /* MALI_USE_CSF */
core_count_p = of_get_property(node, "opp-core-count", NULL);
if (core_count_p) {

View File

@@ -44,22 +44,10 @@ int kbase_backend_gpuprops_get(struct kbase_device *kbdev, struct kbasep_gpuprop
if (kbase_reg_is_valid(kbdev, GPU_CONTROL_ENUM(STACK_PRESENT)))
regdump->stack_present = kbase_reg_read64(kbdev, GPU_CONTROL_ENUM(STACK_PRESENT));
#if !MALI_USE_CSF
regdump->js_present = kbase_reg_read32(kbdev, GPU_CONTROL_ENUM(JS_PRESENT));
/* Not a valid register on TMIX */
/* TGOx specific register */
if (kbase_hw_has_feature(kbdev, KBASE_HW_FEATURE_THREAD_TLS_ALLOC))
regdump->thread_tls_alloc =
kbase_reg_read32(kbdev, GPU_CONTROL_ENUM(THREAD_TLS_ALLOC));
#endif /* !MALI_USE_CSF */
regdump->thread_max_threads = kbase_reg_read32(kbdev, GPU_CONTROL_ENUM(THREAD_MAX_THREADS));
if (kbase_reg_is_valid(kbdev, GPU_CONTROL_ENUM(THREAD_MAX_WORKGROUP_SIZE)))
regdump->thread_max_workgroup_size =
kbase_reg_read32(kbdev, GPU_CONTROL_ENUM(THREAD_MAX_WORKGROUP_SIZE));
#if MALI_USE_CSF
#endif /* MALI_USE_CSF */
if (kbase_reg_is_valid(kbdev, GPU_CONTROL_ENUM(THREAD_MAX_BARRIER_SIZE)))
regdump->thread_max_barrier_size =
kbase_reg_read32(kbdev, GPU_CONTROL_ENUM(THREAD_MAX_BARRIER_SIZE));
@@ -73,7 +61,6 @@ int kbase_backend_gpuprops_get(struct kbase_device *kbdev, struct kbasep_gpuprop
if (kbase_hw_has_feature(kbdev, KBASE_HW_FEATURE_CORE_FEATURES))
regdump->core_features = KBASE_REG_READ(kbdev, GPU_CONTROL_ENUM(CORE_FEATURES));
#if MALI_USE_CSF
if (kbase_reg_is_valid(kbdev, GPU_CONTROL_ENUM(GPU_FEATURES)))
regdump->gpu_features = KBASE_REG_READ(kbdev, GPU_CONTROL_ENUM(GPU_FEATURES));
/* Only applicable to GPUs with power control domain registers */
@@ -82,19 +69,11 @@ int kbase_backend_gpuprops_get(struct kbase_device *kbdev, struct kbasep_gpuprop
regdump->neural_present = kbase_reg_read64(kbdev, HOST_POWER_ENUM(NEURAL_PRESENT));
}
#endif /* MALI_USE_CSF */
regdump->tiler_features = KBASE_REG_READ(kbdev, GPU_CONTROL_ENUM(TILER_FEATURES));
regdump->l2_features = KBASE_REG_READ(kbdev, GPU_CONTROL_ENUM(L2_FEATURES));
regdump->mem_features = KBASE_REG_READ(kbdev, GPU_CONTROL_ENUM(MEM_FEATURES));
regdump->mmu_features = KBASE_REG_READ(kbdev, GPU_CONTROL_ENUM(MMU_FEATURES));
#if !MALI_USE_CSF
for (i = 0; i < GPU_MAX_JOB_SLOTS; i++)
regdump->js_features[i] = kbase_reg_read32(kbdev, GPU_JS_FEATURES_OFFSET(i));
#endif /* !MALI_USE_CSF */
#if MALI_USE_CSF
#endif /* MALI_USE_CSF */
{
for (i = 0; i < BASE_GPU_NUM_TEXTURE_FEATURES_REGISTERS; i++)
regdump->texture_features[i] =
@@ -131,14 +110,12 @@ int kbase_backend_gpuprops_get_l2_features(struct kbase_device *kbdev,
regdump->l2_features = KBASE_REG_READ(kbdev, GPU_CONTROL_ENUM(L2_FEATURES));
regdump->l2_config = kbase_reg_read32(kbdev, GPU_CONTROL_ENUM(L2_CONFIG));
#if MALI_USE_CSF
if (kbase_hw_has_l2_slice_hash_feature(kbdev)) {
uint i;
for (i = 0; i < GPU_L2_SLICE_HASH_COUNT; i++)
regdump->l2_slice_hash[i] =
kbase_reg_read32(kbdev, GPU_L2_SLICE_HASH_OFFSET(i));
}
#endif /* MALI_USE_CSF */
if (!kbase_io_has_gpu(kbdev))
return -EIO;

View File

@@ -1,479 +0,0 @@
// SPDX-License-Identifier: GPL-2.0 WITH Linux-syscall-note
/*
*
* (C) COPYRIGHT 2014-2024 ARM Limited. All rights reserved.
*
* This program is free software and is provided to you under the terms of the
* GNU General Public License version 2 as published by the Free Software
* Foundation, and any use by you of this program is subject to the terms
* of such GNU license.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program; if not, you can access it online at
* http://www.gnu.org/licenses/gpl-2.0.html.
*
*/
/*
* GPU backend instrumentation APIs.
*/
#include <mali_kbase.h>
#include <hw_access/mali_kbase_hw_access_regmap.h>
#include <mali_kbase_hwaccess_instr.h>
#include <device/mali_kbase_device.h>
#include <backend/gpu/mali_kbase_instr_internal.h>
#include <mali_kbase_io.h>
#define WAIT_FOR_DUMP_TIMEOUT_MS 5000
static int wait_prfcnt_ready(struct kbase_device *kbdev)
{
u32 val;
const u32 timeout_us =
kbase_get_timeout_ms(kbdev, KBASE_PRFCNT_ACTIVE_TIMEOUT) * USEC_PER_MSEC;
const int err = kbase_reg_poll32_timeout(kbdev, GPU_CONTROL_ENUM(GPU_STATUS), val,
!(val & GPU_STATUS_PRFCNT_ACTIVE), 0, timeout_us,
false);
if (err) {
dev_err(kbdev->dev, "PRFCNT_ACTIVE bit stuck\n");
return -EBUSY;
}
return 0;
}
int kbase_instr_hwcnt_enable_internal(struct kbase_device *kbdev, struct kbase_context *kctx,
struct kbase_instr_hwcnt_enable *enable)
{
unsigned long flags;
int err = -EINVAL;
u32 irq_mask;
u32 prfcnt_config;
lockdep_assert_held(&kbdev->hwaccess_lock);
/* alignment failure */
if ((enable->dump_buffer == 0ULL) || (enable->dump_buffer & (2048 - 1)))
return err;
spin_lock_irqsave(&kbdev->hwcnt.lock, flags);
if (kbdev->hwcnt.backend.state != KBASE_INSTR_STATE_DISABLED) {
/* Instrumentation is already enabled */
spin_unlock_irqrestore(&kbdev->hwcnt.lock, flags);
return err;
}
if (!kbase_io_has_gpu(kbdev)) {
/* GPU has been removed by Arbiter */
spin_unlock_irqrestore(&kbdev->hwcnt.lock, flags);
return err;
}
/* Enable interrupt */
irq_mask = kbase_reg_read32(kbdev, GPU_CONTROL_ENUM(GPU_IRQ_MASK));
kbase_reg_write32(kbdev, GPU_CONTROL_ENUM(GPU_IRQ_MASK),
irq_mask | PRFCNT_SAMPLE_COMPLETED);
/* In use, this context is the owner */
kbdev->hwcnt.kctx = kctx;
/* Remember the dump address so we can reprogram it later */
kbdev->hwcnt.addr = enable->dump_buffer;
kbdev->hwcnt.addr_bytes = enable->dump_buffer_bytes;
spin_unlock_irqrestore(&kbdev->hwcnt.lock, flags);
/* Configure */
prfcnt_config = (u32)kctx->as_nr << PRFCNT_CONFIG_AS_SHIFT;
#ifdef CONFIG_MALI_VALHALL_PRFCNT_SET_SELECT_VIA_DEBUG_FS
prfcnt_config |= (u32)kbdev->hwcnt.backend.override_counter_set
<< PRFCNT_CONFIG_SETSELECT_SHIFT;
#else
prfcnt_config |= (u32)enable->counter_set << PRFCNT_CONFIG_SETSELECT_SHIFT;
#endif
/* Wait until prfcnt config register can be written */
err = wait_prfcnt_ready(kbdev);
if (err)
return err;
kbase_reg_write32(kbdev, GPU_CONTROL_ENUM(PRFCNT_CONFIG),
prfcnt_config | PRFCNT_CONFIG_MODE_OFF);
/* Wait until prfcnt is disabled before writing configuration registers */
err = wait_prfcnt_ready(kbdev);
if (err)
return err;
kbase_reg_write64(kbdev, GPU_CONTROL_ENUM(PRFCNT_BASE), enable->dump_buffer);
kbase_reg_write32(kbdev, GPU_CONTROL_ENUM(PRFCNT_JM_EN), enable->fe_bm);
kbase_reg_write32(kbdev, GPU_CONTROL_ENUM(PRFCNT_SHADER_EN), enable->shader_bm);
kbase_reg_write32(kbdev, GPU_CONTROL_ENUM(PRFCNT_MMU_L2_EN), enable->mmu_l2_bm);
kbase_reg_write32(kbdev, GPU_CONTROL_ENUM(PRFCNT_TILER_EN), enable->tiler_bm);
kbase_reg_write32(kbdev, GPU_CONTROL_ENUM(PRFCNT_CONFIG),
prfcnt_config | PRFCNT_CONFIG_MODE_MANUAL);
spin_lock_irqsave(&kbdev->hwcnt.lock, flags);
kbdev->hwcnt.backend.state = KBASE_INSTR_STATE_IDLE;
kbdev->hwcnt.backend.triggered = 1;
wake_up(&kbdev->hwcnt.backend.wait);
spin_unlock_irqrestore(&kbdev->hwcnt.lock, flags);
dev_dbg(kbdev->dev, "HW counters dumping set-up for context %pK", kctx);
return 0;
}
static void kbasep_instr_hwc_disable_hw_prfcnt(struct kbase_device *kbdev)
{
u32 irq_mask;
lockdep_assert_held(&kbdev->hwaccess_lock);
lockdep_assert_held(&kbdev->hwcnt.lock);
if (!kbase_io_has_gpu(kbdev))
/* GPU has been removed by Arbiter */
return;
/* Disable interrupt */
irq_mask = kbase_reg_read32(kbdev, GPU_CONTROL_ENUM(GPU_IRQ_MASK));
kbase_reg_write32(kbdev, GPU_CONTROL_ENUM(GPU_IRQ_MASK),
irq_mask & ~PRFCNT_SAMPLE_COMPLETED);
/* Wait until prfcnt config register can be written, then disable the counters.
* Return value is ignored as we are disabling anyway.
*/
wait_prfcnt_ready(kbdev);
kbase_reg_write32(kbdev, GPU_CONTROL_ENUM(PRFCNT_CONFIG), 0);
kbdev->hwcnt.kctx = NULL;
kbdev->hwcnt.addr = 0ULL;
kbdev->hwcnt.addr_bytes = 0ULL;
}
int kbase_instr_hwcnt_disable_internal(struct kbase_context *kctx)
{
unsigned long flags, pm_flags;
struct kbase_device *kbdev = kctx->kbdev;
const unsigned long timeout = msecs_to_jiffies(WAIT_FOR_DUMP_TIMEOUT_MS);
unsigned int remaining;
while (1) {
spin_lock_irqsave(&kbdev->hwaccess_lock, pm_flags);
spin_lock_irqsave(&kbdev->hwcnt.lock, flags);
if (kbdev->hwcnt.backend.state == KBASE_INSTR_STATE_UNRECOVERABLE_ERROR) {
/* Instrumentation is in unrecoverable error state,
* there is nothing for us to do.
*/
spin_unlock_irqrestore(&kbdev->hwcnt.lock, flags);
spin_unlock_irqrestore(&kbdev->hwaccess_lock, pm_flags);
/* Already disabled, return no error. */
return 0;
}
if (kbdev->hwcnt.backend.state == KBASE_INSTR_STATE_DISABLED) {
/* Instrumentation is not enabled */
spin_unlock_irqrestore(&kbdev->hwcnt.lock, flags);
spin_unlock_irqrestore(&kbdev->hwaccess_lock, pm_flags);
return -EINVAL;
}
if (kbdev->hwcnt.kctx != kctx) {
/* Instrumentation has been setup for another context */
spin_unlock_irqrestore(&kbdev->hwcnt.lock, flags);
spin_unlock_irqrestore(&kbdev->hwaccess_lock, pm_flags);
return -EINVAL;
}
if (kbdev->hwcnt.backend.state == KBASE_INSTR_STATE_IDLE)
break;
spin_unlock_irqrestore(&kbdev->hwcnt.lock, flags);
spin_unlock_irqrestore(&kbdev->hwaccess_lock, pm_flags);
/* Ongoing dump/setup - wait for its completion */
remaining = wait_event_timeout(kbdev->hwcnt.backend.wait,
kbdev->hwcnt.backend.triggered != 0, timeout);
if (remaining == 0)
kbdev->hwcnt.backend.state = KBASE_INSTR_STATE_UNRECOVERABLE_ERROR;
}
kbdev->hwcnt.backend.state = KBASE_INSTR_STATE_DISABLED;
kbdev->hwcnt.backend.triggered = 0;
kbasep_instr_hwc_disable_hw_prfcnt(kbdev);
spin_unlock_irqrestore(&kbdev->hwcnt.lock, flags);
spin_unlock_irqrestore(&kbdev->hwaccess_lock, pm_flags);
dev_dbg(kbdev->dev, "HW counters dumping disabled for context %pK", kctx);
return 0;
}
int kbase_instr_hwcnt_request_dump(struct kbase_context *kctx)
{
unsigned long flags;
int err = -EINVAL;
struct kbase_device *kbdev = kctx->kbdev;
spin_lock_irqsave(&kbdev->hwcnt.lock, flags);
if (kbdev->hwcnt.kctx != kctx) {
/* The instrumentation has been setup for another context */
goto unlock;
}
if (kbdev->hwcnt.backend.state != KBASE_INSTR_STATE_IDLE) {
/* HW counters are disabled or another dump is ongoing, or we're
* resetting, or we are in unrecoverable error state.
*/
goto unlock;
}
if (!kbase_io_has_gpu(kbdev)) {
/* GPU has been removed by Arbiter */
goto unlock;
}
kbdev->hwcnt.backend.triggered = 0;
/* Mark that we're dumping - the PF handler can signal that we faulted
*/
kbdev->hwcnt.backend.state = KBASE_INSTR_STATE_DUMPING;
/* Wait until prfcnt is ready to request dump */
err = wait_prfcnt_ready(kbdev);
if (err)
goto unlock;
/* Reconfigure the dump address */
kbase_reg_write64(kbdev, GPU_CONTROL_ENUM(PRFCNT_BASE), kbdev->hwcnt.addr);
/* Start dumping */
KBASE_KTRACE_ADD(kbdev, CORE_GPU_PRFCNT_SAMPLE, NULL, kbdev->hwcnt.addr);
kbase_reg_write32(kbdev, GPU_CONTROL_ENUM(GPU_COMMAND), GPU_COMMAND_PRFCNT_SAMPLE);
dev_dbg(kbdev->dev, "HW counters dumping done for context %pK", kctx);
unlock:
spin_unlock_irqrestore(&kbdev->hwcnt.lock, flags);
return err;
}
KBASE_EXPORT_SYMBOL(kbase_instr_hwcnt_request_dump);
bool kbase_instr_hwcnt_dump_complete(struct kbase_context *kctx, bool *const success)
{
unsigned long flags;
bool complete = false;
struct kbase_device *kbdev = kctx->kbdev;
spin_lock_irqsave(&kbdev->hwcnt.lock, flags);
if (kbdev->hwcnt.backend.state == KBASE_INSTR_STATE_IDLE) {
*success = true;
complete = true;
} else if (kbdev->hwcnt.backend.state == KBASE_INSTR_STATE_FAULT) {
*success = false;
complete = true;
kbdev->hwcnt.backend.state = KBASE_INSTR_STATE_IDLE;
}
spin_unlock_irqrestore(&kbdev->hwcnt.lock, flags);
return complete;
}
KBASE_EXPORT_SYMBOL(kbase_instr_hwcnt_dump_complete);
void kbase_instr_hwcnt_sample_done(struct kbase_device *kbdev)
{
unsigned long flags;
spin_lock_irqsave(&kbdev->hwcnt.lock, flags);
/* If the state is in unrecoverable error, we already wake_up the waiter
* and don't need to do any action when sample is done.
*/
if (kbdev->hwcnt.backend.state == KBASE_INSTR_STATE_FAULT) {
kbdev->hwcnt.backend.triggered = 1;
wake_up(&kbdev->hwcnt.backend.wait);
} else if (kbdev->hwcnt.backend.state == KBASE_INSTR_STATE_DUMPING) {
/* All finished and idle */
kbdev->hwcnt.backend.state = KBASE_INSTR_STATE_IDLE;
kbdev->hwcnt.backend.triggered = 1;
wake_up(&kbdev->hwcnt.backend.wait);
}
spin_unlock_irqrestore(&kbdev->hwcnt.lock, flags);
}
int kbase_instr_hwcnt_wait_for_dump(struct kbase_context *kctx)
{
struct kbase_device *kbdev = kctx->kbdev;
unsigned long flags;
int err;
unsigned long remaining;
const unsigned long timeout = msecs_to_jiffies(WAIT_FOR_DUMP_TIMEOUT_MS);
/* Wait for dump & cache clean to complete */
remaining = wait_event_timeout(kbdev->hwcnt.backend.wait,
kbdev->hwcnt.backend.triggered != 0, timeout);
if (remaining == 0) {
err = -ETIME;
/* Set the backend state so it's clear things have gone bad (could be a HW issue)
*/
kbdev->hwcnt.backend.state = KBASE_INSTR_STATE_UNRECOVERABLE_ERROR;
goto timed_out;
}
spin_lock_irqsave(&kbdev->hwcnt.lock, flags);
if (kbdev->hwcnt.backend.state == KBASE_INSTR_STATE_FAULT) {
err = -EINVAL;
kbdev->hwcnt.backend.state = KBASE_INSTR_STATE_IDLE;
} else if (kbdev->hwcnt.backend.state == KBASE_INSTR_STATE_UNRECOVERABLE_ERROR) {
err = -EIO;
} else {
/* Dump done */
KBASE_DEBUG_ASSERT(kbdev->hwcnt.backend.state == KBASE_INSTR_STATE_IDLE);
err = 0;
}
spin_unlock_irqrestore(&kbdev->hwcnt.lock, flags);
timed_out:
return err;
}
int kbase_instr_hwcnt_clear(struct kbase_context *kctx)
{
unsigned long flags;
int err = -EINVAL;
struct kbase_device *kbdev = kctx->kbdev;
spin_lock_irqsave(&kbdev->hwcnt.lock, flags);
/* Check it's the context previously set up and we're not in IDLE
* state.
*/
if (kbdev->hwcnt.kctx != kctx || kbdev->hwcnt.backend.state != KBASE_INSTR_STATE_IDLE)
goto unlock;
if (!kbase_io_has_gpu(kbdev)) {
/* GPU has been removed by Arbiter */
goto unlock;
}
/* Wait until prfcnt is ready to clear */
err = wait_prfcnt_ready(kbdev);
if (err)
goto unlock;
/* Clear the counters */
KBASE_KTRACE_ADD(kbdev, CORE_GPU_PRFCNT_CLEAR, NULL, 0);
kbase_reg_write32(kbdev, GPU_CONTROL_ENUM(GPU_COMMAND), GPU_COMMAND_PRFCNT_CLEAR);
unlock:
spin_unlock_irqrestore(&kbdev->hwcnt.lock, flags);
return err;
}
KBASE_EXPORT_SYMBOL(kbase_instr_hwcnt_clear);
void kbase_instr_hwcnt_on_unrecoverable_error(struct kbase_device *kbdev)
{
unsigned long flags;
lockdep_assert_held(&kbdev->hwaccess_lock);
spin_lock_irqsave(&kbdev->hwcnt.lock, flags);
/* If we already in unrecoverable error state, early return. */
if (kbdev->hwcnt.backend.state == KBASE_INSTR_STATE_UNRECOVERABLE_ERROR) {
spin_unlock_irqrestore(&kbdev->hwcnt.lock, flags);
return;
}
kbdev->hwcnt.backend.state = KBASE_INSTR_STATE_UNRECOVERABLE_ERROR;
/* Need to disable HW if it's not disabled yet. */
if (kbdev->hwcnt.backend.state != KBASE_INSTR_STATE_DISABLED)
kbasep_instr_hwc_disable_hw_prfcnt(kbdev);
/* Wake up any waiters. */
kbdev->hwcnt.backend.triggered = 1;
wake_up(&kbdev->hwcnt.backend.wait);
spin_unlock_irqrestore(&kbdev->hwcnt.lock, flags);
}
KBASE_EXPORT_SYMBOL(kbase_instr_hwcnt_on_unrecoverable_error);
void kbase_instr_hwcnt_on_before_reset(struct kbase_device *kbdev)
{
unsigned long flags;
spin_lock_irqsave(&kbdev->hwcnt.lock, flags);
/* A reset is the only way to exit the unrecoverable error state */
if (kbdev->hwcnt.backend.state == KBASE_INSTR_STATE_UNRECOVERABLE_ERROR)
kbdev->hwcnt.backend.state = KBASE_INSTR_STATE_DISABLED;
spin_unlock_irqrestore(&kbdev->hwcnt.lock, flags);
}
KBASE_EXPORT_SYMBOL(kbase_instr_hwcnt_on_before_reset);
int kbase_instr_backend_init(struct kbase_device *kbdev)
{
spin_lock_init(&kbdev->hwcnt.lock);
kbdev->hwcnt.backend.state = KBASE_INSTR_STATE_DISABLED;
init_waitqueue_head(&kbdev->hwcnt.backend.wait);
#ifdef CONFIG_MALI_VALHALL_PRFCNT_SET_SELECT_VIA_DEBUG_FS
/* Use the build time option for the override default. */
#if defined(CONFIG_MALI_VALHALL_PRFCNT_SET_SECONDARY)
kbdev->hwcnt.backend.override_counter_set = KBASE_HWCNT_PHYSICAL_SET_SECONDARY;
#elif defined(CONFIG_MALI_VALHALL_PRFCNT_SET_TERTIARY)
kbdev->hwcnt.backend.override_counter_set = KBASE_HWCNT_PHYSICAL_SET_TERTIARY;
#else
/* Default to primary */
kbdev->hwcnt.backend.override_counter_set = KBASE_HWCNT_PHYSICAL_SET_PRIMARY;
#endif
#endif
return 0;
}
void kbase_instr_backend_term(struct kbase_device *kbdev)
{
CSTD_UNUSED(kbdev);
}
#ifdef CONFIG_MALI_VALHALL_PRFCNT_SET_SELECT_VIA_DEBUG_FS
void kbase_instr_backend_debugfs_init(struct kbase_device *kbdev)
{
/* No validation is done on the debugfs input. Invalid input could cause
* performance counter errors. This is acceptable since this is a debug
* only feature and users should know what they are doing.
*
* Valid inputs are the values accepted bythe SET_SELECT bits of the
* PRFCNT_CONFIG register as defined in the architecture specification.
*/
debugfs_create_u8("hwcnt_set_select", 0644, kbdev->mali_debugfs_directory,
(u8 *)&kbdev->hwcnt.backend.override_counter_set);
}
#endif

View File

@@ -62,12 +62,8 @@ static irqreturn_t kbase_job_irq_handler(int irq, void *data)
dev_dbg(kbdev->dev, "%s: irq %d irqstatus 0x%x\n", __func__, irq, val);
#if MALI_USE_CSF
/* call the csf interrupt handler */
kbase_csf_interrupt(kbdev, val);
#else
kbase_job_done(kbdev, val);
#endif
spin_unlock_irqrestore(&kbdev->hwaccess_lock, flags);
@@ -108,7 +104,6 @@ static irqreturn_t kbase_mmu_irq_handler(int irq, void *data)
return IRQ_HANDLED;
}
#if MALI_USE_CSF
static irqreturn_t kbase_pwr_irq_handler(int irq, void *data)
{
unsigned long flags;
@@ -138,7 +133,6 @@ static irqreturn_t kbase_pwr_irq_handler(int irq, void *data)
return irq_state;
}
#endif /* MALI_USE_CSF */
static irqreturn_t kbase_gpuonly_irq_handler(int irq, void *data)
@@ -181,7 +175,6 @@ static irqreturn_t kbase_gpuonly_irq_handler(int irq, void *data)
static irqreturn_t kbase_gpu_irq_handler(int irq, void *data)
{
irqreturn_t irq_state = kbase_gpuonly_irq_handler(irq, data);
#if MALI_USE_CSF
struct kbase_device *kbdev = kbase_untag(data);
/* Skip if HOST_POWER page is not available */
@@ -189,7 +182,6 @@ static irqreturn_t kbase_gpu_irq_handler(int irq, void *data)
if (kbase_pwr_irq_handler(irq, data) == IRQ_HANDLED)
irq_state = IRQ_HANDLED;
}
#endif /* MALI_USE_CSF */
return irq_state;
}
@@ -350,6 +342,40 @@ static enum hrtimer_restart kbasep_test_interrupt_timeout(struct hrtimer *timer)
return HRTIMER_NORESTART;
}
struct interrupt_masks {
u32 job;
u32 mmu;
u32 gpu;
u32 pwr;
};
static void store_interrupt_masks(struct interrupt_masks *masks, struct kbase_device *const kbdev)
{
/* Store all interrupt masks */
masks->job = kbase_reg_read32(kbdev, JOB_CONTROL_ENUM(JOB_IRQ_MASK));
masks->mmu = kbase_reg_read32(kbdev, MMU_CONTROL_ENUM(IRQ_MASK));
masks->gpu = kbase_reg_read32(kbdev, GPU_CONTROL_ENUM(GPU_IRQ_MASK));
if (kbdev->pm.backend.has_host_pwr_iface)
masks->pwr = kbase_reg_read32(kbdev, HOST_POWER_ENUM(PWR_IRQ_MASK));
/* Set all masks to 0 to disable all interrupt sources */
kbase_reg_write32(kbdev, JOB_CONTROL_ENUM(JOB_IRQ_MASK), 0x0);
kbase_reg_write32(kbdev, MMU_CONTROL_ENUM(IRQ_MASK), 0x0);
kbase_reg_write32(kbdev, GPU_CONTROL_ENUM(GPU_IRQ_MASK), 0x0);
if (kbdev->pm.backend.has_host_pwr_iface)
kbase_reg_write32(kbdev, HOST_POWER_ENUM(PWR_IRQ_MASK), 0x0);
}
static void restore_interrupt_masks(struct interrupt_masks *masks, struct kbase_device *const kbdev)
{
/* Restore all interrupt masks to their previous values */
kbase_reg_write32(kbdev, JOB_CONTROL_ENUM(JOB_IRQ_MASK), masks->job);
kbase_reg_write32(kbdev, MMU_CONTROL_ENUM(IRQ_MASK), masks->mmu);
kbase_reg_write32(kbdev, GPU_CONTROL_ENUM(GPU_IRQ_MASK), masks->gpu);
if (kbdev->pm.backend.has_host_pwr_iface)
kbase_reg_write32(kbdev, HOST_POWER_ENUM(PWR_IRQ_MASK), masks->pwr);
}
/**
* validate_interrupt - Validate an interrupt
* @kbdev: Kbase device
@@ -364,9 +390,9 @@ static enum hrtimer_restart kbasep_test_interrupt_timeout(struct hrtimer *timer)
static int validate_interrupt(struct kbase_device *const kbdev, u32 tag)
{
int err = 0;
struct interrupt_masks masks = { 0 };
irq_handler_t handler;
const int irq = (kbdev->nr_irqs == 1) ? 0 : tag;
u32 old_mask_val;
u16 mask_offset;
u16 rawstat_offset;
@@ -389,10 +415,8 @@ static int validate_interrupt(struct kbase_device *const kbdev, u32 tag)
return -EINVAL;
}
/* store old mask */
old_mask_val = kbase_reg_read32(kbdev, mask_offset);
/* mask interrupts */
kbase_reg_write32(kbdev, mask_offset, 0x0);
/* store masks and disable all possible interrupt sources */
store_interrupt_masks(&masks, kbdev);
if (kbdev->irqs[irq].irq) {
/* release original handler and install test handler */
@@ -441,8 +465,8 @@ static int validate_interrupt(struct kbase_device *const kbdev, u32 tag)
err = -EINVAL;
}
}
/* restore old mask */
kbase_reg_write32(kbdev, mask_offset, old_mask_val);
/* restore old masks */
restore_interrupt_masks(&masks, kbdev);
return err;
}
@@ -487,7 +511,6 @@ int kbase_install_interrupts(struct kbase_device *kbdev)
{
u32 irq_index;
#if MALI_USE_CSF
if (kbdev->gpu_props.gpu_id.arch_id >= GPU_ID_ARCH_MAKE(14, 8, 0)) {
if (kbdev->nr_irqs != 1) {
dev_err(kbdev->dev, "Incorrect number of irq entries (%u)", kbdev->nr_irqs);
@@ -499,7 +522,6 @@ int kbase_install_interrupts(struct kbase_device *kbdev)
return -EINVAL;
}
}
#endif /* MALI_USE_CSF */
for (irq_index = 0; irq_index < kbdev->nr_irqs; irq_index++) {
const int result = request_irq(kbdev->irqs[irq_index].irq,
kbase_get_interrupt_handler(kbdev, irq_index),

View File

@@ -1,237 +0,0 @@
// SPDX-License-Identifier: GPL-2.0 WITH Linux-syscall-note
/*
*
* (C) COPYRIGHT 2014-2023 ARM Limited. All rights reserved.
*
* This program is free software and is provided to you under the terms of the
* GNU General Public License version 2 as published by the Free Software
* Foundation, and any use by you of this program is subject to the terms
* of such GNU license.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program; if not, you can access it online at
* http://www.gnu.org/licenses/gpl-2.0.html.
*
*/
/*
* Register backend context / address space management
*/
#include <mali_kbase.h>
#include <mali_kbase_hwaccess_jm.h>
#include <mali_kbase_ctx_sched.h>
/**
* assign_and_activate_kctx_addr_space - Assign an AS to a context
* @kbdev: Kbase device
* @kctx: Kbase context
* @current_as: Address Space to assign
*
* Assign an Address Space (AS) to a context, and add the context to the Policy.
*
* This includes
* setting up the global runpool_irq structure and the context on the AS,
* Activating the MMU on the AS,
* Allowing jobs to be submitted on the AS.
*
* Context:
* kbasep_js_kctx_info.jsctx_mutex held,
* kbasep_js_device_data.runpool_mutex held,
* AS transaction mutex held,
* Runpool IRQ lock held
*/
static void assign_and_activate_kctx_addr_space(struct kbase_device *kbdev,
struct kbase_context *kctx,
struct kbase_as *current_as)
{
struct kbasep_js_device_data *js_devdata = &kbdev->js_data;
CSTD_UNUSED(current_as);
lockdep_assert_held(&kctx->jctx.sched_info.ctx.jsctx_mutex);
lockdep_assert_held(&js_devdata->runpool_mutex);
lockdep_assert_held(&kbdev->hwaccess_lock);
#if !MALI_USE_CSF
/* Attribute handling */
kbasep_js_ctx_attr_runpool_retain_ctx(kbdev, kctx);
#endif
/* Allow it to run jobs */
kbasep_js_set_submit_allowed(js_devdata, kctx);
kbase_js_runpool_inc_context_count(kbdev, kctx);
}
bool kbase_backend_use_ctx_sched(struct kbase_device *kbdev, struct kbase_context *kctx,
unsigned int js)
{
int i;
if (kbdev->hwaccess.active_kctx[js] == kctx) {
/* Context is already active */
return true;
}
for (i = 0; i < kbdev->nr_hw_address_spaces; i++) {
if (kbdev->as_to_kctx[i] == kctx) {
/* Context already has ASID - mark as active */
return true;
}
}
/* Context does not have address space assigned */
return false;
}
void kbase_backend_release_ctx_irq(struct kbase_device *kbdev, struct kbase_context *kctx)
{
int as_nr = kctx->as_nr;
if (as_nr == KBASEP_AS_NR_INVALID) {
WARN(1, "Attempting to release context without ASID\n");
return;
}
lockdep_assert_held(&kbdev->hwaccess_lock);
if (atomic_read(&kctx->refcount) != 1) {
WARN(1, "Attempting to release active ASID\n");
return;
}
kbasep_js_clear_submit_allowed(&kbdev->js_data, kctx);
kbase_ctx_sched_release_ctx(kctx);
kbase_js_runpool_dec_context_count(kbdev, kctx);
}
void kbase_backend_release_ctx_noirq(struct kbase_device *kbdev, struct kbase_context *kctx)
{
CSTD_UNUSED(kbdev);
CSTD_UNUSED(kctx);
}
int kbase_backend_find_and_release_free_address_space(struct kbase_device *kbdev,
struct kbase_context *kctx)
{
struct kbasep_js_device_data *js_devdata;
struct kbasep_js_kctx_info *js_kctx_info;
unsigned long flags;
int i;
js_devdata = &kbdev->js_data;
js_kctx_info = &kctx->jctx.sched_info;
mutex_lock(&js_kctx_info->ctx.jsctx_mutex);
mutex_lock(&js_devdata->runpool_mutex);
spin_lock_irqsave(&kbdev->hwaccess_lock, flags);
for (i = 0; i < kbdev->nr_hw_address_spaces; i++) {
struct kbasep_js_kctx_info *as_js_kctx_info;
struct kbase_context *as_kctx;
as_kctx = kbdev->as_to_kctx[i];
as_js_kctx_info = &as_kctx->jctx.sched_info;
/* Don't release privileged or active contexts, or contexts with
* jobs running.
* Note that a context will have at least 1 reference (which
* was previously taken by kbasep_js_schedule_ctx()) until
* descheduled.
*/
if (as_kctx && !kbase_ctx_flag(as_kctx, KCTX_PRIVILEGED) &&
atomic_read(&as_kctx->refcount) == 1) {
if (!kbase_ctx_sched_inc_refcount_nolock(as_kctx)) {
WARN(1, "Failed to retain active context\n");
spin_unlock_irqrestore(&kbdev->hwaccess_lock, flags);
mutex_unlock(&js_devdata->runpool_mutex);
mutex_unlock(&js_kctx_info->ctx.jsctx_mutex);
return KBASEP_AS_NR_INVALID;
}
kbasep_js_clear_submit_allowed(js_devdata, as_kctx);
/* Drop and retake locks to take the jsctx_mutex on the
* context we're about to release without violating lock
* ordering
*/
spin_unlock_irqrestore(&kbdev->hwaccess_lock, flags);
mutex_unlock(&js_devdata->runpool_mutex);
mutex_unlock(&js_kctx_info->ctx.jsctx_mutex);
/* Release context from address space */
mutex_lock(&as_js_kctx_info->ctx.jsctx_mutex);
mutex_lock(&js_devdata->runpool_mutex);
kbasep_js_runpool_release_ctx_nolock(kbdev, as_kctx);
if (!kbase_ctx_flag(as_kctx, KCTX_SCHEDULED)) {
kbasep_js_runpool_requeue_or_kill_ctx(kbdev, as_kctx, true);
mutex_unlock(&js_devdata->runpool_mutex);
mutex_unlock(&as_js_kctx_info->ctx.jsctx_mutex);
return i;
}
/* Context was retained while locks were dropped,
* continue looking for free AS
*/
mutex_unlock(&js_devdata->runpool_mutex);
mutex_unlock(&as_js_kctx_info->ctx.jsctx_mutex);
mutex_lock(&js_kctx_info->ctx.jsctx_mutex);
mutex_lock(&js_devdata->runpool_mutex);
spin_lock_irqsave(&kbdev->hwaccess_lock, flags);
}
}
spin_unlock_irqrestore(&kbdev->hwaccess_lock, flags);
mutex_unlock(&js_devdata->runpool_mutex);
mutex_unlock(&js_kctx_info->ctx.jsctx_mutex);
return KBASEP_AS_NR_INVALID;
}
bool kbase_backend_use_ctx(struct kbase_device *kbdev, struct kbase_context *kctx, int as_nr)
{
struct kbasep_js_device_data *js_devdata;
struct kbase_as *new_address_space = NULL;
int js;
js_devdata = &kbdev->js_data;
for (js = 0; js < BASE_JM_MAX_NR_SLOTS; js++) {
if (kbdev->hwaccess.active_kctx[js] == kctx) {
WARN(1, "Context is already scheduled in\n");
return false;
}
}
new_address_space = &kbdev->as[as_nr];
lockdep_assert_held(&js_devdata->runpool_mutex);
lockdep_assert_held(&kbdev->mmu_hw_mutex);
lockdep_assert_held(&kbdev->hwaccess_lock);
assign_and_activate_kctx_addr_space(kbdev, kctx, new_address_space);
if (kbase_ctx_flag(kctx, KCTX_PRIVILEGED)) {
/* We need to retain it to keep the corresponding address space
*/
kbase_ctx_sched_retain_ctx_refcount(kctx);
}
return true;
}

File diff suppressed because it is too large Load Diff

View File

@@ -1,140 +0,0 @@
/* SPDX-License-Identifier: GPL-2.0 WITH Linux-syscall-note */
/*
*
* (C) COPYRIGHT 2011-2024 ARM Limited. All rights reserved.
*
* This program is free software and is provided to you under the terms of the
* GNU General Public License version 2 as published by the Free Software
* Foundation, and any use by you of this program is subject to the terms
* of such GNU license.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program; if not, you can access it online at
* http://www.gnu.org/licenses/gpl-2.0.html.
*
*/
/*
* Job Manager backend-specific low-level APIs.
*/
#ifndef _KBASE_JM_HWACCESS_H_
#define _KBASE_JM_HWACCESS_H_
#include <mali_kbase_hw.h>
#include <mali_kbase_debug.h>
#include <linux/atomic.h>
#include <backend/gpu/mali_kbase_jm_rb.h>
#include <device/mali_kbase_device.h>
/**
* kbase_job_done_slot() - Complete the head job on a particular job-slot
* @kbdev: Device pointer
* @s: Job slot
* @completion_code: Completion code of job reported by GPU
* @job_tail: Job tail address reported by GPU
* @end_timestamp: Timestamp of job completion
*/
void kbase_job_done_slot(struct kbase_device *kbdev, int s, u32 completion_code, u64 job_tail,
ktime_t *end_timestamp);
/**
* kbase_job_hw_submit() - Submit a job to the GPU
* @kbdev: Device pointer
* @katom: Atom to submit
* @js: Job slot to submit on
*
* The caller must check kbasep_jm_is_submit_slots_free() != false before
* calling this.
*
* The following locking conditions are made on the caller:
* - it must hold the hwaccess_lock
*
* Return: 0 if the job was successfully submitted to hardware, an error otherwise.
*/
int kbase_job_hw_submit(struct kbase_device *kbdev, struct kbase_jd_atom *katom, unsigned int js);
#if !MALI_USE_CSF
/**
* kbasep_job_slot_soft_or_hard_stop_do_action() - Perform a soft or hard stop
* on the specified atom
* @kbdev: Device pointer
* @js: Job slot to stop on
* @action: The action to perform, either JS_COMMAND_HARD_STOP or
* JS_COMMAND_SOFT_STOP
* @core_reqs: Core requirements of atom to stop
* @target_katom: Atom to stop
*
* The following locking conditions are made on the caller:
* - it must hold the hwaccess_lock
*/
void kbasep_job_slot_soft_or_hard_stop_do_action(struct kbase_device *kbdev, unsigned int js,
u32 action, base_jd_core_req core_reqs,
struct kbase_jd_atom *target_katom);
#endif /* !MALI_USE_CSF */
/**
* kbase_backend_soft_hard_stop_slot() - Soft or hard stop jobs on a given job
* slot belonging to a given context.
* @kbdev: Device pointer
* @kctx: Context pointer. May be NULL
* @katom: Specific atom to stop. May be NULL
* @js: Job slot to hard stop
* @action: The action to perform, either JS_COMMAND_HARD_STOP or
* JS_COMMAND_SOFT_STOP
*
* If no context is provided then all jobs on the slot will be soft or hard
* stopped.
*
* If a katom is provided then only that specific atom will be stopped. In this
* case the kctx parameter is ignored.
*
* Jobs that are on the slot but are not yet on the GPU will be unpulled and
* returned to the job scheduler.
*
* Return: true if an atom was stopped, false otherwise
*/
bool kbase_backend_soft_hard_stop_slot(struct kbase_device *kbdev, struct kbase_context *kctx,
unsigned int js, struct kbase_jd_atom *katom, u32 action);
/**
* kbase_job_slot_init - Initialise job slot framework
* @kbdev: Device pointer
*
* Called on driver initialisation
*
* Return: 0 on success
*/
int kbase_job_slot_init(struct kbase_device *kbdev);
/**
* kbase_job_slot_halt - Halt the job slot framework
* @kbdev: Device pointer
*
* Should prevent any further job slot processing
*/
void kbase_job_slot_halt(struct kbase_device *kbdev);
/**
* kbase_job_slot_term - Terminate job slot framework
* @kbdev: Device pointer
*
* Called on driver termination
*/
void kbase_job_slot_term(struct kbase_device *kbdev);
/**
* kbase_gpu_cache_clean - Cause a GPU cache clean & flush
* @kbdev: Device pointer
*
* Caller must not be in IRQ context
*/
void kbase_gpu_cache_clean(struct kbase_device *kbdev);
#endif /* _KBASE_JM_HWACCESS_H_ */

File diff suppressed because it is too large Load Diff

View File

@@ -1,77 +0,0 @@
/* SPDX-License-Identifier: GPL-2.0 WITH Linux-syscall-note */
/*
*
* (C) COPYRIGHT 2014-2018, 2020-2022 ARM Limited. All rights reserved.
*
* This program is free software and is provided to you under the terms of the
* GNU General Public License version 2 as published by the Free Software
* Foundation, and any use by you of this program is subject to the terms
* of such GNU license.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program; if not, you can access it online at
* http://www.gnu.org/licenses/gpl-2.0.html.
*
*/
/*
* Register-based HW access backend specific APIs
*/
#ifndef _KBASE_HWACCESS_GPU_H_
#define _KBASE_HWACCESS_GPU_H_
#include <backend/gpu/mali_kbase_pm_internal.h>
/**
* kbase_gpu_irq_evict - Evict an atom from a NEXT slot
*
* @kbdev: Device pointer
* @js: Job slot to evict from
* @completion_code: Event code from job that was run.
*
* Evict the atom in the NEXT slot for the specified job slot. This function is
* called from the job complete IRQ handler when the previous job has failed.
*
* Return: true if job evicted from NEXT registers, false otherwise
*/
bool kbase_gpu_irq_evict(struct kbase_device *kbdev, unsigned int js, u32 completion_code);
/**
* kbase_gpu_complete_hw - Complete an atom on job slot js
*
* @kbdev: Device pointer
* @js: Job slot that has completed
* @completion_code: Event code from job that has completed
* @job_tail: The tail address from the hardware if the job has partially
* completed
* @end_timestamp: Time of completion
*/
void kbase_gpu_complete_hw(struct kbase_device *kbdev, unsigned int js, u32 completion_code,
u64 job_tail, ktime_t *end_timestamp);
/**
* kbase_gpu_inspect - Inspect the contents of the HW access ringbuffer
*
* @kbdev: Device pointer
* @js: Job slot to inspect
* @idx: Index into ringbuffer. 0 is the job currently running on
* the slot, 1 is the job waiting, all other values are invalid.
* Return: The atom at that position in the ringbuffer
* or NULL if no atom present
*/
struct kbase_jd_atom *kbase_gpu_inspect(struct kbase_device *kbdev, unsigned int js, int idx);
/**
* kbase_gpu_dump_slots - Print the contents of the slot ringbuffers
*
* @kbdev: Device pointer
*/
void kbase_gpu_dump_slots(struct kbase_device *kbdev);
#endif /* _KBASE_HWACCESS_GPU_H_ */

View File

@@ -1,371 +0,0 @@
// SPDX-License-Identifier: GPL-2.0 WITH Linux-syscall-note
/*
*
* (C) COPYRIGHT 2014-2024 ARM Limited. All rights reserved.
*
* This program is free software and is provided to you under the terms of the
* GNU General Public License version 2 as published by the Free Software
* Foundation, and any use by you of this program is subject to the terms
* of such GNU license.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program; if not, you can access it online at
* http://www.gnu.org/licenses/gpl-2.0.html.
*
*/
/*
* Register-based HW access backend specific job scheduler APIs
*/
#include <mali_kbase.h>
#include <mali_kbase_hwaccess_jm.h>
#include <mali_kbase_reset_gpu.h>
#include <backend/gpu/mali_kbase_jm_internal.h>
#include <backend/gpu/mali_kbase_js_internal.h>
#if IS_ENABLED(CONFIG_MALI_VALHALL_TRACE_POWER_GPU_WORK_PERIOD)
#include <mali_kbase_gpu_metrics.h>
#endif
/*
* Hold the runpool_mutex for this
*/
static inline bool timer_callback_should_run(struct kbase_device *kbdev, int nr_running_ctxs)
{
lockdep_assert_held(&kbdev->js_data.runpool_mutex);
#ifdef CONFIG_MALI_VALHALL_DEBUG
if (kbdev->js_data.softstop_always) {
/* Debug support for allowing soft-stop on a single context */
return true;
}
#endif /* CONFIG_MALI_VALHALL_DEBUG */
if (kbase_hw_has_issue(kbdev, KBASE_HW_ISSUE_9435)) {
/* Timeouts would have to be 4x longer (due to micro-
* architectural design) to support OpenCL conformance tests, so
* only run the timer when there's:
* - 2 or more CL contexts
* - 1 or more GLES contexts
*
* NOTE: We will treat a context that has both Compute and Non-
* Compute jobs will be treated as an OpenCL context (hence, we
* don't check KBASEP_JS_CTX_ATTR_NON_COMPUTE).
*/
{
int nr_compute_ctxs = kbasep_js_ctx_attr_count_on_runpool(
kbdev, KBASEP_JS_CTX_ATTR_COMPUTE);
int nr_noncompute_ctxs = nr_running_ctxs - nr_compute_ctxs;
return (bool)(nr_compute_ctxs >= 2 || nr_noncompute_ctxs > 0);
}
} else {
/* Run the timer callback whenever you have at least 1 context
*/
return (bool)(nr_running_ctxs > 0);
}
}
static enum hrtimer_restart timer_callback(struct hrtimer *timer)
{
unsigned long flags;
struct kbase_device *kbdev;
struct kbasep_js_device_data *js_devdata;
struct kbase_backend_data *backend;
unsigned int s;
bool reset_needed = false;
KBASE_DEBUG_ASSERT(timer != NULL);
backend = container_of(timer, struct kbase_backend_data, scheduling_timer);
kbdev = container_of(backend, struct kbase_device, hwaccess.backend);
js_devdata = &kbdev->js_data;
/* Loop through the slots */
spin_lock_irqsave(&kbdev->hwaccess_lock, flags);
for (s = 0; s < kbdev->gpu_props.num_job_slots; s++) {
struct kbase_jd_atom *atom = NULL;
if (kbase_backend_nr_atoms_on_slot(kbdev, s) > 0) {
atom = kbase_gpu_inspect(kbdev, s, 0);
KBASE_DEBUG_ASSERT(atom != NULL);
}
if (atom != NULL) {
/* The current version of the model doesn't support
* Soft-Stop
*/
if (!kbase_hw_has_issue(kbdev, KBASE_HW_ISSUE_5736)) {
u32 ticks = atom->ticks++;
#if !defined(CONFIG_MALI_VALHALL_JOB_DUMP) && !defined(CONFIG_MALI_VECTOR_DUMP)
u32 soft_stop_ticks, hard_stop_ticks, gpu_reset_ticks;
if (atom->core_req & BASE_JD_REQ_ONLY_COMPUTE) {
soft_stop_ticks = js_devdata->soft_stop_ticks_cl;
hard_stop_ticks = js_devdata->hard_stop_ticks_cl;
gpu_reset_ticks = js_devdata->gpu_reset_ticks_cl;
} else {
soft_stop_ticks = js_devdata->soft_stop_ticks;
if (kbase_is_quick_reset_enabled(kbdev)) {
hard_stop_ticks = 2;
gpu_reset_ticks = 3;
} else {
hard_stop_ticks = js_devdata->hard_stop_ticks_ss;
gpu_reset_ticks = js_devdata->gpu_reset_ticks_ss;
}
}
/* If timeouts have been changed then ensure
* that atom tick count is not greater than the
* new soft_stop timeout. This ensures that
* atoms do not miss any of the timeouts due to
* races between this worker and the thread
* changing the timeouts.
*/
if (backend->timeouts_updated && ticks > soft_stop_ticks)
ticks = atom->ticks = soft_stop_ticks;
/* Job is Soft-Stoppable */
if (ticks == soft_stop_ticks) {
/* Job has been scheduled for at least
* js_devdata->soft_stop_ticks ticks.
* Soft stop the slot so we can run
* other jobs.
*/
#if !KBASE_DISABLE_SCHEDULING_SOFT_STOPS
int disjoint_threshold =
KBASE_DISJOINT_STATE_INTERLEAVED_CONTEXT_COUNT_THRESHOLD;
u32 softstop_flags = 0u;
dev_dbg(kbdev->dev, "Soft-stop");
/* nr_user_contexts_running is updated
* with the runpool_mutex, but we can't
* take that here.
*
* However, if it's about to be
* increased then the new context can't
* run any jobs until they take the
* hwaccess_lock, so it's OK to observe
* the older value.
*
* Similarly, if it's about to be
* decreased, the last job from another
* context has already finished, so
* it's not too bad that we observe the
* older value and register a disjoint
* event when we try soft-stopping
*/
if (js_devdata->nr_user_contexts_running >=
disjoint_threshold)
softstop_flags |= JS_COMMAND_SW_CAUSES_DISJOINT;
kbase_job_slot_softstop_swflags(kbdev, s, atom,
softstop_flags);
#endif
} else if (ticks == hard_stop_ticks) {
/* Job has been scheduled for at least
* js_devdata->hard_stop_ticks_ss ticks.
* It should have been soft-stopped by
* now. Hard stop the slot.
*/
#if !KBASE_DISABLE_SCHEDULING_HARD_STOPS
u32 ms = js_devdata->scheduling_period_ns / 1000000u;
if (!kbase_is_quick_reset_enabled(kbdev))
dev_warn(
kbdev->dev,
"JS: Job Hard-Stopped (took more than %u ticks at %u ms/tick)",
ticks, ms);
kbase_job_slot_hardstop(atom->kctx, s, atom);
#endif
} else if (ticks == gpu_reset_ticks) {
/* Job has been scheduled for at least
* js_devdata->gpu_reset_ticks_ss ticks.
* It should have left the GPU by now.
* Signal that the GPU needs to be
* reset.
*/
reset_needed = true;
}
#else /* !CONFIG_MALI_VALHALL_JOB_DUMP */
/* NOTE: During CONFIG_MALI_VALHALL_JOB_DUMP, we use
* the alternate timeouts, which makes the hard-
* stop and GPU reset timeout much longer. We
* also ensure that we don't soft-stop at all.
*/
if (ticks == js_devdata->soft_stop_ticks) {
/* Job has been scheduled for at least
* js_devdata->soft_stop_ticks. We do
* not soft-stop during
* CONFIG_MALI_VALHALL_JOB_DUMP, however.
*/
dev_dbg(kbdev->dev, "Soft-stop");
} else if (ticks == js_devdata->hard_stop_ticks_dumping) {
/* Job has been scheduled for at least
* js_devdata->hard_stop_ticks_dumping
* ticks. Hard stop the slot.
*/
#if !KBASE_DISABLE_SCHEDULING_HARD_STOPS
u32 ms = js_devdata->scheduling_period_ns / 1000000u;
dev_warn(
kbdev->dev,
"JS: Job Hard-Stopped (took more than %u ticks at %u ms/tick)",
ticks, ms);
kbase_job_slot_hardstop(atom->kctx, s, atom);
#endif
} else if (ticks == js_devdata->gpu_reset_ticks_dumping) {
/* Job has been scheduled for at least
* js_devdata->gpu_reset_ticks_dumping
* ticks. It should have left the GPU by
* now. Signal that the GPU needs to be
* reset.
*/
reset_needed = true;
}
#endif /* !CONFIG_MALI_VALHALL_JOB_DUMP */
}
}
}
if (reset_needed) {
if (kbase_is_quick_reset_enabled(kbdev))
dev_err(kbdev->dev, "quick reset");
else
dev_err(kbdev->dev,
"JS: Job has been on the GPU for too long (JS_RESET_TICKS_SS/DUMPING timeout hit). Issuing GPU soft-reset to resolve.");
if (kbase_prepare_to_reset_gpu_locked(kbdev, RESET_FLAGS_NONE))
kbase_reset_gpu_locked(kbdev);
}
/* the timer is re-issued if there is contexts in the run-pool */
if (backend->timer_running)
hrtimer_start(&backend->scheduling_timer,
HR_TIMER_DELAY_NSEC(js_devdata->scheduling_period_ns),
HRTIMER_MODE_REL);
backend->timeouts_updated = false;
spin_unlock_irqrestore(&kbdev->hwaccess_lock, flags);
return HRTIMER_NORESTART;
}
void kbase_backend_ctx_count_changed(struct kbase_device *kbdev)
{
struct kbasep_js_device_data *js_devdata = &kbdev->js_data;
struct kbase_backend_data *backend = &kbdev->hwaccess.backend;
unsigned long flags;
/* Timer must stop if we are suspending */
const bool suspend_timer = backend->suspend_timer;
const int nr_running_ctxs = atomic_read(&kbdev->js_data.nr_contexts_runnable);
lockdep_assert_held(&js_devdata->runpool_mutex);
if (suspend_timer || !timer_callback_should_run(kbdev, nr_running_ctxs)) {
/* Take spinlock to force synchronisation with timer */
spin_lock_irqsave(&kbdev->hwaccess_lock, flags);
backend->timer_running = false;
spin_unlock_irqrestore(&kbdev->hwaccess_lock, flags);
/* From now on, return value of timer_callback_should_run()
* will also cause the timer to not requeue itself. Its return
* value cannot change, because it depends on variables updated
* with the runpool_mutex held, which the caller of this must
* also hold
*/
hrtimer_cancel(&backend->scheduling_timer);
}
if (!suspend_timer && timer_callback_should_run(kbdev, nr_running_ctxs) &&
!backend->timer_running) {
/* Take spinlock to force synchronisation with timer */
spin_lock_irqsave(&kbdev->hwaccess_lock, flags);
backend->timer_running = true;
spin_unlock_irqrestore(&kbdev->hwaccess_lock, flags);
hrtimer_start(&backend->scheduling_timer,
HR_TIMER_DELAY_NSEC(js_devdata->scheduling_period_ns),
HRTIMER_MODE_REL);
KBASE_KTRACE_ADD_JM(kbdev, JS_POLICY_TIMER_START, NULL, NULL, 0u, 0u);
}
#if IS_ENABLED(CONFIG_MALI_VALHALL_TRACE_POWER_GPU_WORK_PERIOD)
if (unlikely(suspend_timer)) {
js_devdata->gpu_metrics_timer_needed = false;
/* Cancel the timer as System suspend is happening */
hrtimer_cancel(&js_devdata->gpu_metrics_timer);
js_devdata->gpu_metrics_timer_running = false;
spin_lock_irqsave(&kbdev->hwaccess_lock, flags);
/* Explicitly emit the tracepoint on System suspend */
kbase_gpu_metrics_emit_tracepoint(kbdev, ktime_get_raw_ns());
spin_unlock_irqrestore(&kbdev->hwaccess_lock, flags);
return;
}
if (!nr_running_ctxs) {
/* Just set the flag to not restart the timer on expiry */
js_devdata->gpu_metrics_timer_needed = false;
return;
}
/* There are runnable contexts so the timer is needed */
if (!js_devdata->gpu_metrics_timer_needed) {
spin_lock_irqsave(&kbdev->hwaccess_lock, flags);
js_devdata->gpu_metrics_timer_needed = true;
/* No need to restart the timer if it is already running. */
if (!js_devdata->gpu_metrics_timer_running) {
hrtimer_start(&js_devdata->gpu_metrics_timer,
HR_TIMER_DELAY_NSEC(kbase_gpu_metrics_get_tp_emit_interval()),
HRTIMER_MODE_REL);
js_devdata->gpu_metrics_timer_running = true;
}
spin_unlock_irqrestore(&kbdev->hwaccess_lock, flags);
}
#endif
}
int kbase_backend_timer_init(struct kbase_device *kbdev)
{
struct kbase_backend_data *backend = &kbdev->hwaccess.backend;
hrtimer_init(&backend->scheduling_timer, CLOCK_MONOTONIC, HRTIMER_MODE_REL);
backend->scheduling_timer.function = timer_callback;
backend->timer_running = false;
return 0;
}
void kbase_backend_timer_term(struct kbase_device *kbdev)
{
struct kbase_backend_data *backend = &kbdev->hwaccess.backend;
hrtimer_cancel(&backend->scheduling_timer);
}
void kbase_backend_timer_suspend(struct kbase_device *kbdev)
{
struct kbase_backend_data *backend = &kbdev->hwaccess.backend;
backend->suspend_timer = true;
kbase_backend_ctx_count_changed(kbdev);
}
void kbase_backend_timer_resume(struct kbase_device *kbdev)
{
struct kbase_backend_data *backend = &kbdev->hwaccess.backend;
backend->suspend_timer = false;
kbase_backend_ctx_count_changed(kbdev);
}
void kbase_backend_timeouts_changed(struct kbase_device *kbdev)
{
struct kbase_backend_data *backend = &kbdev->hwaccess.backend;
backend->timeouts_updated = true;
}

View File

@@ -1,72 +0,0 @@
/* SPDX-License-Identifier: GPL-2.0 WITH Linux-syscall-note */
/*
*
* (C) COPYRIGHT 2014-2015, 2020-2021 ARM Limited. All rights reserved.
*
* This program is free software and is provided to you under the terms of the
* GNU General Public License version 2 as published by the Free Software
* Foundation, and any use by you of this program is subject to the terms
* of such GNU license.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program; if not, you can access it online at
* http://www.gnu.org/licenses/gpl-2.0.html.
*
*/
/*
* Register-based HW access backend specific job scheduler APIs
*/
#ifndef _KBASE_JS_BACKEND_H_
#define _KBASE_JS_BACKEND_H_
/**
* kbase_backend_timer_init() - Initialise the JS scheduling timer
* @kbdev: Device pointer
*
* This function should be called at driver initialisation
*
* Return: 0 on success
*/
int kbase_backend_timer_init(struct kbase_device *kbdev);
/**
* kbase_backend_timer_term() - Terminate the JS scheduling timer
* @kbdev: Device pointer
*
* This function should be called at driver termination
*/
void kbase_backend_timer_term(struct kbase_device *kbdev);
/**
* kbase_backend_timer_suspend - Suspend is happening, stop the JS scheduling
* timer
* @kbdev: Device pointer
*
* This function should be called on suspend, after the active count has reached
* zero. This is required as the timer may have been started on job submission
* to the job scheduler, but before jobs are submitted to the GPU.
*
* Caller must hold runpool_mutex.
*/
void kbase_backend_timer_suspend(struct kbase_device *kbdev);
/**
* kbase_backend_timer_resume - Resume is happening, re-evaluate the JS
* scheduling timer
* @kbdev: Device pointer
*
* This function should be called on resume. Note that is not guaranteed to
* re-start the timer, only evalute whether it should be re-started.
*
* Caller must hold runpool_mutex.
*/
void kbase_backend_timer_resume(struct kbase_device *kbdev);
#endif /* _KBASE_JS_BACKEND_H_ */

View File

@@ -36,7 +36,6 @@
#include <asm/arch_timer.h>
#if MALI_USE_CSF
#include <csf/mali_kbase_csf_firmware.h>
/* Index of the last value register for each type of core, with the 1st value
@@ -55,11 +54,8 @@ static u32 gpu_control_base_addr;
/* Array for storing the value of SELECT register for each type of core */
static u64 ipa_ctl_select_config[KBASE_IPA_CORE_TYPE_NUM];
static u32 ipa_control_timer_enabled;
#endif
#if MALI_USE_CSF
static u32 sysc_alloc_regs[SYSC_ALLOC_COUNT];
#endif
#define LO_MASK(M) ((M)&0xFFFFFFFF)
#define HI_MASK(M) ((M)&0xFFFFFFFF00000000)
@@ -69,13 +65,8 @@ static u32 sysc_alloc_regs[SYSC_ALLOC_COUNT];
* significant bits, which are set to THREAD_FEATURES_IMPLEMENTATION_TECHNOLOGY_SOFTWARE in
* midgard_model_read_reg().
*/
#if MALI_USE_CSF
#define THREAD_FEATURES_PARTIAL(MAX_REGISTERS, MAX_TASK_QUEUE, MAX_TG_SPLIT) \
((MAX_REGISTERS) | ((MAX_TASK_QUEUE) << 24))
#else
#define THREAD_FEATURES_PARTIAL(MAX_REGISTERS, MAX_TASK_QUEUE, MAX_TG_SPLIT) \
((MAX_REGISTERS) | ((MAX_TASK_QUEUE) << 16) | ((MAX_TG_SPLIT) << 24))
#endif
struct error_status_t hw_error_status;
@@ -133,24 +124,18 @@ enum pwr_on_index {
INDEX_TILER,
INDEX_SHADER,
INDEX_STACK,
#if MALI_USE_CSF
INDEX_BASE,
INDEX_NEURAL,
#endif
INDEX_DOMAIN_COUNT
};
struct dummy_model_t {
int reset_completed;
int reset_completed_mask;
#if !MALI_USE_CSF
int prfcnt_sample_completed;
#endif /* !MALI_USE_CSF */
int power_changed_mask; /* 2 bits: _ALL,_SINGLE */
int power_changed; /* 1 bit */
bool clean_caches_completed;
bool clean_caches_completed_irq_enabled;
#if MALI_USE_CSF
bool flush_pa_range_completed;
bool flush_pa_range_completed_irq_enabled;
/* Representations of COMMAND_NOT_ALLOWED and COMMAND_INVALID bits in
@@ -164,7 +149,6 @@ struct dummy_model_t {
u64 command_arg; /* PWR_CMDARG register */
u64 gov_core_mask;
#endif
uint32_t domain_power_on[INDEX_DOMAIN_COUNT];
u32 coherency_enable;
unsigned int job_irq_js_state;
@@ -462,9 +446,6 @@ static const struct control_reg_values_t all_control_reg_values[] = {
static struct {
spinlock_t access_lock;
#if !MALI_USE_CSF
unsigned long prfcnt_base;
#endif /* !MALI_USE_CSF */
u32 *prfcnt_base_cpu;
u32 time;
@@ -474,11 +455,7 @@ static struct {
u64 l2_present;
u64 shader_present;
#if !MALI_USE_CSF
u64 jm_counters[KBASE_DUMMY_MODEL_COUNTER_PER_CORE];
#else
u64 cshw_counters[KBASE_DUMMY_MODEL_COUNTER_PER_CORE];
#endif /* !MALI_USE_CSF */
u64 tiler_counters[KBASE_DUMMY_MODEL_COUNTER_PER_CORE];
u64 l2_counters[KBASE_DUMMY_MODEL_MAX_MEMSYS_BLOCKS * KBASE_DUMMY_MODEL_COUNTER_PER_CORE];
u64 shader_counters[KBASE_DUMMY_MODEL_MAX_SHADER_CORES * KBASE_DUMMY_MODEL_COUNTER_PER_CORE];
@@ -510,7 +487,6 @@ static u32 get_implementation_register(u32 reg,
return 0;
}
#if MALI_USE_CSF
static u32
hctrl_get_implementation_register(u32 reg,
const struct control_reg_values_t *const control_reg_values)
@@ -531,7 +507,6 @@ hctrl_get_implementation_register(u32 reg,
return 0;
}
#endif
void gpu_device_set_data(void *model, void *data)
{
@@ -553,7 +528,6 @@ static char *no_mali_gpu = CONFIG_MALI_VALHALL_NO_MALI_DEFAULT_GPU;
module_param(no_mali_gpu, charp, 0000);
MODULE_PARM_DESC(no_mali_gpu, "GPU to identify as");
#if MALI_USE_CSF
static u32 gpu_model_get_prfcnt_value(enum kbase_ipa_core_type core_type, u32 cnt_idx,
bool is_low_word)
{
@@ -628,7 +602,6 @@ static u32 gpu_model_get_prfcnt_value(enum kbase_ipa_core_type core_type, u32 cn
else
return (value >> 32);
}
#endif /* MALI_USE_CSF */
/**
* gpu_model_clear_prfcnt_values_nolock - Clear performance counter values
@@ -639,18 +612,13 @@ static u32 gpu_model_get_prfcnt_value(enum kbase_ipa_core_type core_type, u32 cn
static void gpu_model_clear_prfcnt_values_nolock(void)
{
lockdep_assert_held(&performance_counters.access_lock);
#if !MALI_USE_CSF
memset(performance_counters.jm_counters, 0, sizeof(performance_counters.jm_counters));
#else
memset(performance_counters.cshw_counters, 0, sizeof(performance_counters.cshw_counters));
#endif /* !MALI_USE_CSF */
memset(performance_counters.tiler_counters, 0, sizeof(performance_counters.tiler_counters));
memset(performance_counters.l2_counters, 0, sizeof(performance_counters.l2_counters));
memset(performance_counters.shader_counters, 0,
sizeof(performance_counters.shader_counters));
}
#if MALI_USE_CSF
void gpu_model_clear_prfcnt_values(void)
{
unsigned long flags;
@@ -660,7 +628,6 @@ void gpu_model_clear_prfcnt_values(void)
spin_unlock_irqrestore(&performance_counters.access_lock, flags);
}
KBASE_EXPORT_TEST_API(gpu_model_clear_prfcnt_values);
#endif /* MALI_USE_CSF */
/**
* gpu_model_dump_prfcnt_blocks() - Dump performance counter values to buffer
@@ -689,11 +656,9 @@ static void gpu_model_dump_prfcnt_blocks(u64 *values, u32 *out_index, u32 block_
for (block_idx = 0; block_idx < block_count; block_idx++) {
/* only dump values if core is present */
if (!(blocks_present & (1U << block_idx))) {
#if MALI_USE_CSF
/* if CSF dump zeroed out block */
memset(&prfcnt_base[*out_index], 0, KBASE_DUMMY_MODEL_BLOCK_SIZE);
*out_index += KBASE_DUMMY_MODEL_VALUES_PER_BLOCK;
#endif /* MALI_USE_CSF */
continue;
}
@@ -724,13 +689,8 @@ static void gpu_model_dump_nolock(void)
lockdep_assert_held(&performance_counters.access_lock);
#if !MALI_USE_CSF
gpu_model_dump_prfcnt_blocks(performance_counters.jm_counters, &index, 1,
performance_counters.prfcnt_en.fe, 0x1);
#else
gpu_model_dump_prfcnt_blocks(performance_counters.cshw_counters, &index, 1,
performance_counters.prfcnt_en.fe, 0x1);
#endif /* !MALI_USE_CSF */
gpu_model_dump_prfcnt_blocks(performance_counters.tiler_counters, &index, 1,
performance_counters.prfcnt_en.tiler,
DUMMY_IMPLEMENTATION_TILER_PRESENT);
@@ -763,16 +723,6 @@ static void gpu_model_raise_irq(void *model, u32 irq)
gpu_device_raise_irq(model, irq);
}
#if !MALI_USE_CSF
static void midgard_model_dump_prfcnt(void)
{
unsigned long flags;
spin_lock_irqsave(&performance_counters.access_lock, flags);
gpu_model_dump_nolock();
spin_unlock_irqrestore(&performance_counters.access_lock, flags);
}
#else
void gpu_model_prfcnt_dump_request(u32 *sample_buf, struct gpu_model_prfcnt_en enable_maps)
{
unsigned long flags;
@@ -796,7 +746,6 @@ void gpu_model_glb_request_job_irq(void *model)
spin_unlock_irqrestore(&hw_error_status.access_lock, flags);
gpu_model_raise_irq(model, MODEL_LINUX_JOB_IRQ);
}
#endif /* !MALI_USE_CSF */
static void init_register_statuses(struct dummy_model_t *dummy)
{
@@ -830,117 +779,6 @@ static void update_register_statuses(struct dummy_model_t *dummy, u32 job_slot)
if (hw_error_status.errors_mask & IS_A_JOB_ERROR) {
if (job_slot == hw_error_status.current_job_slot) {
#if !MALI_USE_CSF
if (hw_error_status.js_status[job_slot] == 0) {
/* status reg is clean; it can be written */
switch (hw_error_status.errors_mask & IS_A_JOB_ERROR) {
case KBASE_JOB_INTERRUPTED:
hw_error_status.js_status[job_slot] = JS_STATUS_INTERRUPTED;
break;
case KBASE_JOB_STOPPED:
hw_error_status.js_status[job_slot] = JS_STATUS_STOPPED;
break;
case KBASE_JOB_TERMINATED:
hw_error_status.js_status[job_slot] = JS_STATUS_TERMINATED;
break;
case KBASE_JOB_CONFIG_FAULT:
hw_error_status.js_status[job_slot] =
JS_STATUS_CONFIG_FAULT;
break;
case KBASE_JOB_POWER_FAULT:
hw_error_status.js_status[job_slot] = JS_STATUS_POWER_FAULT;
break;
case KBASE_JOB_READ_FAULT:
hw_error_status.js_status[job_slot] = JS_STATUS_READ_FAULT;
break;
case KBASE_JOB_WRITE_FAULT:
hw_error_status.js_status[job_slot] = JS_STATUS_WRITE_FAULT;
break;
case KBASE_JOB_AFFINITY_FAULT:
hw_error_status.js_status[job_slot] =
JS_STATUS_AFFINITY_FAULT;
break;
case KBASE_JOB_BUS_FAULT:
hw_error_status.js_status[job_slot] = JS_STATUS_BUS_FAULT;
break;
case KBASE_INSTR_INVALID_PC:
hw_error_status.js_status[job_slot] =
JS_STATUS_INSTR_INVALID_PC;
break;
case KBASE_INSTR_INVALID_ENC:
hw_error_status.js_status[job_slot] =
JS_STATUS_INSTR_INVALID_ENC;
break;
case KBASE_INSTR_TYPE_MISMATCH:
hw_error_status.js_status[job_slot] =
JS_STATUS_INSTR_TYPE_MISMATCH;
break;
case KBASE_INSTR_OPERAND_FAULT:
hw_error_status.js_status[job_slot] =
JS_STATUS_INSTR_OPERAND_FAULT;
break;
case KBASE_INSTR_TLS_FAULT:
hw_error_status.js_status[job_slot] =
JS_STATUS_INSTR_TLS_FAULT;
break;
case KBASE_INSTR_BARRIER_FAULT:
hw_error_status.js_status[job_slot] =
JS_STATUS_INSTR_BARRIER_FAULT;
break;
case KBASE_INSTR_ALIGN_FAULT:
hw_error_status.js_status[job_slot] =
JS_STATUS_INSTR_ALIGN_FAULT;
break;
case KBASE_DATA_INVALID_FAULT:
hw_error_status.js_status[job_slot] =
JS_STATUS_DATA_INVALID_FAULT;
break;
case KBASE_TILE_RANGE_FAULT:
hw_error_status.js_status[job_slot] =
JS_STATUS_TILE_RANGE_FAULT;
break;
case KBASE_ADDR_RANGE_FAULT:
hw_error_status.js_status[job_slot] =
JS_STATUS_ADDRESS_RANGE_FAULT;
break;
case KBASE_OUT_OF_MEMORY:
hw_error_status.js_status[job_slot] =
JS_STATUS_OUT_OF_MEMORY;
break;
case KBASE_UNKNOWN:
hw_error_status.js_status[job_slot] = JS_STATUS_UNKNOWN;
break;
default:
model_error_log(KBASE_CORE,
"\nAtom Chain 0x%llx: Invalid Error Mask!",
hw_error_status.current_jc);
break;
}
}
#endif /* !MALI_USE_CSF */
/* we set JOB_FAIL_<n> */
hw_error_status.job_irq_rawstat |=
(dummy->slots[job_slot].job_complete_irq_asserted)
@@ -1049,40 +887,6 @@ static void update_register_statuses(struct dummy_model_t *dummy, u32 job_slot)
hw_error_status.errors_mask = 0; /*clear error mask */
}
#if !MALI_USE_CSF
static void update_job_irq_js_state(struct dummy_model_t *dummy, int mask)
{
int i;
lockdep_assert_held(&hw_error_status.access_lock);
pr_debug("%s", "Updating the JS_ACTIVE register");
for (i = 0; i < NUM_SLOTS; i++) {
int slot_active = dummy->slots[i].job_active;
int next_busy = dummy->slots[i].job_queued;
if ((mask & (1 << i)) || (mask & (1 << (i + 16)))) {
/* clear the bits we're updating */
dummy->job_irq_js_state &= ~((1 << (16 + i)) | (1 << i));
if (hw_error_status.js_status[i]) {
dummy->job_irq_js_state |= next_busy << (i + 16);
if (mask & (1 << (i + 16))) {
/* clear job slot status */
hw_error_status.js_status[i] = 0;
/* continue execution of jobchain */
dummy->slots[i].job_active = dummy->slots[i].job_queued;
}
} else {
/* set bits if needed */
dummy->job_irq_js_state |=
((slot_active << i) | (next_busy << (i + 16)));
}
}
}
pr_debug("The new snapshot is 0x%08X\n", dummy->job_irq_js_state);
}
#endif /* !MALI_USE_CSF */
/**
* find_gpu_rev() - Append GPU HW revision to the GPU name, if needed.
* @new_gpu_name: Caller-allocated string for the new GPU name.
@@ -1121,6 +925,9 @@ static const struct control_reg_values_t *find_control_reg_values(const char *gp
const struct control_reg_values_t *ret = NULL;
char *gpu_with_rev = kmalloc(strlen(gpu) + GPU_REV_STR_LEN + 1, GFP_KERNEL);
if (gpu_with_rev == NULL)
return NULL;
/* Fix gpu name in case there are multiple entries for different HW versions. */
find_gpu_rev(gpu_with_rev, gpu);
@@ -1164,10 +971,15 @@ void *midgard_model_create(struct kbase_device *kbdev)
dummy->job_irq_js_state = 0;
init_register_statuses(dummy);
dummy->control_reg_values = find_control_reg_values(no_mali_gpu);
if (dummy->control_reg_values == NULL) {
kfree(dummy);
return NULL;
}
dummy->arch_id = get_arch_id(dummy->control_reg_values->gpu_id);
gpu_control_base_addr = GPU_CONTROL_BASE;
#if MALI_USE_CSF
if (kbdev->pm.backend.has_host_pwr_iface) {
performance_counters.l2_present = hctrl_get_implementation_register(
GET_HOST_POWER_REG(HOST_POWER_L2_PRESENT_LO),
@@ -1175,9 +987,7 @@ void *midgard_model_create(struct kbase_device *kbdev)
performance_counters.shader_present = hctrl_get_implementation_register(
GET_HOST_POWER_REG(HOST_POWER_SHADER_PRESENT_LO),
dummy->control_reg_values);
} else
#endif /* MALI_USE_CSF */
{
} else {
performance_counters.l2_present = get_implementation_register(
GET_GPU_CONTROL_REG(L2_PRESENT_LO), dummy->control_reg_values);
performance_counters.shader_present = get_implementation_register(
@@ -1299,73 +1109,6 @@ void midgard_model_write_reg(void *h, u32 addr, u32 value)
spin_lock_irqsave(&hw_error_status.access_lock, flags);
#if !MALI_USE_CSF
if ((addr >= JOB_CONTROL_REG(JOB_SLOT0)) && (addr < (JOB_CONTROL_REG(JOB_SLOT15) + 0x80))) {
unsigned int slot_idx = (addr >> 7) & 0xf;
KBASE_DEBUG_ASSERT(slot_idx < NUM_SLOTS);
if (addr == JOB_SLOT_REG(slot_idx, JS_HEAD_NEXT_LO)) {
hw_error_status.current_jc &= ~((u64)(0xFFFFFFFF));
hw_error_status.current_jc |= (u64)value;
}
if (addr == JOB_SLOT_REG(slot_idx, JS_HEAD_NEXT_HI)) {
hw_error_status.current_jc &= (u64)0xFFFFFFFF;
hw_error_status.current_jc |= ((u64)value) << 32;
}
if (addr == JOB_SLOT_REG(slot_idx, JS_COMMAND_NEXT) && value == 1) {
pr_debug("%s", "start detected");
KBASE_DEBUG_ASSERT(!dummy->slots[slot_idx].job_active ||
!dummy->slots[slot_idx].job_queued);
if ((dummy->slots[slot_idx].job_active) ||
(hw_error_status.job_irq_rawstat & (1 << (slot_idx + 16)))) {
pr_debug(
"~~~~~~~~~~~ Start: job slot is already active or there are IRQ pending ~~~~~~~~~");
dummy->slots[slot_idx].job_queued = 1;
} else {
dummy->slots[slot_idx].job_active = 1;
}
}
if (addr == JOB_SLOT_REG(slot_idx, JS_COMMAND_NEXT) && value == 0)
dummy->slots[slot_idx].job_queued = 0;
if ((addr == JOB_SLOT_REG(slot_idx, JS_COMMAND)) &&
(value == JS_COMMAND_SOFT_STOP || value == JS_COMMAND_HARD_STOP)) {
/*dummy->slots[slot_idx].job_active = 0; */
hw_error_status.current_job_slot = slot_idx;
if (value == JS_COMMAND_SOFT_STOP) {
hw_error_status.errors_mask = KBASE_JOB_STOPPED;
} else { /*value == 3 */
if (dummy->slots[slot_idx].job_disabled != 0) {
pr_debug("enabling slot after HARD_STOP");
dummy->slots[slot_idx].job_disabled = 0;
}
hw_error_status.errors_mask = KBASE_JOB_TERMINATED;
}
}
} else if (addr == JOB_CONTROL_REG(JOB_IRQ_CLEAR)) {
int i;
for (i = 0; i < NUM_SLOTS; i++) {
if (value & ((1u << i) | (1u << (i + 16))))
dummy->slots[i].job_complete_irq_asserted = 0;
/* hw_error_status.js_status[i] is cleared in
* update_job_irq_js_state
*/
}
pr_debug("%s", "job irq cleared");
update_job_irq_js_state(dummy, value);
/*remove error condition for JOB */
hw_error_status.job_irq_rawstat &= ~(value);
hw_error_status.job_irq_status &= ~(value);
} else if (addr == JOB_CONTROL_REG(JOB_IRQ_MASK)) {
int i;
for (i = 0; i < NUM_SLOTS; i++)
dummy->slots[i].job_irq_mask = (value >> i) & 0x01;
pr_debug("job irq mask to value %x", value);
#else /* MALI_USE_CSF */
if (addr == JOB_CONTROL_REG(JOB_IRQ_CLEAR)) {
pr_debug("%s", "job irq cleared");
@@ -1376,25 +1119,16 @@ void midgard_model_write_reg(void *h, u32 addr, u32 value)
hw_error_status.job_irq_status |= value;
} else if (addr == JOB_CONTROL_REG(JOB_IRQ_MASK)) {
/* ignore JOB_IRQ_MASK as it is handled by CSFFW */
#endif /* !MALI_USE_CSF */
} else if (addr == GET_GPU_CONTROL_REG(GPU_IRQ_MASK)) {
pr_debug("GPU_IRQ_MASK set to 0x%x", value);
#if MALI_USE_CSF
if (!dummy->kbdev->pm.backend.has_host_pwr_iface) {
dummy->reset_completed_mask = (value >> 8) & 0x01;
dummy->power_changed_mask = (value >> 9) & 0x03;
}
#else
dummy->reset_completed_mask = (value >> 8) & 0x01;
dummy->power_changed_mask = (value >> 9) & 0x03;
#endif
dummy->clean_caches_completed_irq_enabled = (value & (1u << 17)) != 0u;
#if MALI_USE_CSF
dummy->flush_pa_range_completed_irq_enabled = (value & (1u << 20)) != 0u;
#endif
} else if (addr == GET_GPU_CONTROL_REG(COHERENCY_ENABLE)) {
dummy->coherency_enable = value;
#if MALI_USE_CSF
} else if (addr == GET_HOST_POWER_REG(PWR_IRQ_MASK)) {
pr_debug("PWR_IRQ_MASK set to 0x%x", value);
dummy->power_changed_mask = (value & PWR_IRQ_POWER_CHANGED_SINGLE) |
@@ -1531,28 +1265,12 @@ void midgard_model_write_reg(void *h, u32 addr, u32 value)
if (value & (POWER_CHANGED_SINGLE | POWER_CHANGED_ALL))
dummy->power_changed = 0;
}
#else
} else if (addr == GET_GPU_CONTROL_REG(GPU_IRQ_CLEAR)) {
if (value & RESET_COMPLETED) {
pr_debug("%s", "gpu RESET_COMPLETED irq cleared");
dummy->reset_completed = 0;
}
if (value & (POWER_CHANGED_SINGLE | POWER_CHANGED_ALL))
dummy->power_changed = 0;
#endif /* MALI_USE_CSF */
if (value & CLEAN_CACHES_COMPLETED)
dummy->clean_caches_completed = false;
#if MALI_USE_CSF
if (value & (1u << 20))
dummy->flush_pa_range_completed = false;
#endif /* MALI_USE_CSF */
#if !MALI_USE_CSF
if (value & PRFCNT_SAMPLE_COMPLETED) /* (1 << 16) */
dummy->prfcnt_sample_completed = 0;
#endif /* !MALI_USE_CSF */
/*update error status */
hw_error_status.gpu_error_irq &= ~(value);
@@ -1566,41 +1284,26 @@ void midgard_model_write_reg(void *h, u32 addr, u32 value)
/* completed reset instantly */
dummy->reset_completed = 1;
break;
#if MALI_USE_CSF
case GPU_COMMAND_CACHE_CLN_INV_L2:
case GPU_COMMAND_CACHE_CLN_INV_L2_LSC:
case GPU_COMMAND_CACHE_CLN_INV_FULL:
#else
case GPU_COMMAND_CLEAN_CACHES:
case GPU_COMMAND_CLEAN_INV_CACHES:
#endif
pr_debug("clean caches requested");
dummy->clean_caches_completed = true;
break;
#if MALI_USE_CSF
case GPU_COMMAND_FLUSH_PA_RANGE_CLN_INV_L2:
case GPU_COMMAND_FLUSH_PA_RANGE_CLN_INV_L2_LSC:
case GPU_COMMAND_FLUSH_PA_RANGE_CLN_INV_FULL:
pr_debug("pa range flush requested");
dummy->flush_pa_range_completed = true;
break;
#endif /* MALI_USE_CSF */
#if !MALI_USE_CSF
case GPU_COMMAND_PRFCNT_SAMPLE:
midgard_model_dump_prfcnt();
dummy->prfcnt_sample_completed = 1;
#endif /* !MALI_USE_CSF */
default:
break;
}
#if MALI_USE_CSF
} else if (addr >= GET_GPU_CONTROL_REG(GPU_COMMAND_ARG0_LO) &&
addr <= GET_GPU_CONTROL_REG(GPU_COMMAND_ARG1_HI)) {
/* Writes ignored */
#endif
} else if (addr == GET_GPU_CONTROL_REG(L2_CONFIG)) {
dummy->l2_config = value;
#if MALI_USE_CSF
} else if (addr >= CSF_HW_DOORBELL_PAGE_OFFSET &&
addr < CSF_HW_DOORBELL_PAGE_OFFSET +
(dummy->kbdev->csf.num_doorbells * CSF_HW_DOORBELL_PAGE_SIZE)) {
@@ -1650,7 +1353,6 @@ void midgard_model_write_reg(void *h, u32 addr, u32 value)
}
} else if (addr == GPU_GOV_CORE_MASK_OFFSET) {
dummy->gov_core_mask = value;
#endif /* MALI_USE_CSF */
} else if (addr == MMU_CONTROL_REG(MMU_IRQ_MASK)) {
hw_error_status.mmu_irq_mask = value;
} else if (addr == MMU_CONTROL_REG(MMU_IRQ_CLEAR)) {
@@ -1659,6 +1361,9 @@ void midgard_model_write_reg(void *h, u32 addr, u32 value)
(addr <= MMU_STAGE1_REG(MMU_AS_REG(15, AS_STATUS)))) {
u32 mem_addr_space = (addr - MMU_STAGE1_REG(MMU_AS_REG(0, AS_TRANSTAB_LO))) >>
MMU_STAGE1_AS_SHIFT;
if (WARN_ON(mem_addr_space >= NUM_MMU_AS)) {
return;
}
switch (addr & 0x3F) {
case AS_COMMAND:
@@ -1737,32 +1442,6 @@ void midgard_model_write_reg(void *h, u32 addr, u32 value)
}
} else {
switch (addr) {
#if !MALI_USE_CSF
case PRFCNT_BASE_LO:
performance_counters.prfcnt_base =
HI_MASK(performance_counters.prfcnt_base) | value;
performance_counters.prfcnt_base_cpu =
(u32 *)(uintptr_t)performance_counters.prfcnt_base;
break;
case PRFCNT_BASE_HI:
performance_counters.prfcnt_base =
LO_MASK(performance_counters.prfcnt_base) | (((u64)value) << 32);
performance_counters.prfcnt_base_cpu =
(u32 *)(uintptr_t)performance_counters.prfcnt_base;
break;
case PRFCNT_JM_EN:
performance_counters.prfcnt_en.fe = value;
break;
case PRFCNT_SHADER_EN:
performance_counters.prfcnt_en.shader = value;
break;
case PRFCNT_TILER_EN:
performance_counters.prfcnt_en.tiler = value;
break;
case PRFCNT_MMU_L2_EN:
performance_counters.prfcnt_en.l2 = value;
break;
#endif /* !MALI_USE_CSF */
case TILER_PWRON_LO:
dummy->domain_power_on[INDEX_TILER] |= value &
DUMMY_IMPLEMENTATION_TILER_PRESENT;
@@ -1813,13 +1492,8 @@ void midgard_model_write_reg(void *h, u32 addr, u32 value)
case PWR_KEY:
case PWR_OVERRIDE0:
case PWR_OVERRIDE1:
#if MALI_USE_CSF
case SHADER_PWRFEATURES:
case CSF_CONFIG:
#else /* !MALI_USE_CSF */
case JM_CONFIG:
case PRFCNT_CONFIG:
#endif /* MALI_USE_CSF */
case SHADER_CONFIG:
case TILER_CONFIG:
case L2_MMU_CONFIG:
@@ -1847,15 +1521,7 @@ void midgard_model_read_reg(void *h, u32 addr, u32 *const value)
spin_lock_irqsave(&hw_error_status.access_lock, flags);
*value = 0; /* 0 by default */
#if !MALI_USE_CSF
if (addr == JOB_CONTROL_REG(JOB_IRQ_JS_STATE)) {
pr_debug("%s", "JS_ACTIVE being read");
*value = dummy->job_irq_js_state;
} else if (addr == GET_GPU_CONTROL_REG(GPU_ID)) {
#else /* !MALI_USE_CSF */
if (addr == GET_GPU_CONTROL_REG(GPU_ID)) {
#endif /* !MALI_USE_CSF */
*value = dummy->control_reg_values->gpu_id & U32_MAX;
} else if (addr == JOB_CONTROL_REG(JOB_IRQ_RAWSTAT)) {
*value = hw_error_status.job_irq_rawstat;
@@ -1863,42 +1529,21 @@ void midgard_model_read_reg(void *h, u32 addr, u32 *const value)
} else if (addr == JOB_CONTROL_REG(JOB_IRQ_STATUS)) {
*value = hw_error_status.job_irq_status;
pr_debug("JS_IRQ_STATUS being read %x", *value);
#if !MALI_USE_CSF
} else if (addr == JOB_CONTROL_REG(JOB_IRQ_MASK)) {
int i;
*value = 0;
for (i = 0; i < NUM_SLOTS; i++)
*value |= dummy->slots[i].job_irq_mask << i;
pr_debug("JS_IRQ_MASK being read %x", *value);
#else /* !MALI_USE_CSF */
} else if (addr == JOB_CONTROL_REG(JOB_IRQ_MASK)) {
/* ignore JOB_IRQ_MASK as it is handled by CSFFW */
#endif /* !MALI_USE_CSF */
} else if (addr == GET_GPU_CONTROL_REG(GPU_IRQ_MASK)) {
*value = (dummy->reset_completed_mask << 8) |
((dummy->clean_caches_completed_irq_enabled ? 1u : 0u) << 17) |
#if MALI_USE_CSF
((dummy->flush_pa_range_completed_irq_enabled ? 1u : 0u) << 20) |
#endif
(dummy->power_changed_mask << 9) | (1u << 7) | 1u;
pr_debug("GPU_IRQ_MASK read %x", *value);
} else if (addr == GET_GPU_CONTROL_REG(GPU_IRQ_RAWSTAT)) {
*value = ((dummy->clean_caches_completed ? 1u : 0u) << 17) |
#if MALI_USE_CSF
((dummy->flush_pa_range_completed ? 1u : 0u) << 20) |
#else
(dummy->prfcnt_sample_completed ? PRFCNT_SAMPLE_COMPLETED : 0) |
#endif
hw_error_status.gpu_error_irq;
#if MALI_USE_CSF
if (!dummy->kbdev->pm.backend.has_host_pwr_iface)
*value |= (dummy->power_changed << 9) | (dummy->power_changed << 10) |
(dummy->reset_completed << 8);
#else
*value |= (dummy->power_changed << 9) | (dummy->power_changed << 10) |
(dummy->reset_completed << 8);
#endif
pr_debug("GPU_IRQ_RAWSTAT read %x", *value);
} else if (addr == GET_GPU_CONTROL_REG(GPU_IRQ_STATUS)) {
@@ -1907,40 +1552,25 @@ void midgard_model_read_reg(void *h, u32 addr, u32 *const value)
1u :
0u)
<< 17) |
#if MALI_USE_CSF
(((dummy->flush_pa_range_completed &&
dummy->flush_pa_range_completed_irq_enabled) ?
1u :
0u)
<< 20) |
#else
(dummy->prfcnt_sample_completed ? PRFCNT_SAMPLE_COMPLETED : 0) |
#endif
hw_error_status.gpu_error_irq;
#if MALI_USE_CSF
if (!dummy->kbdev->pm.backend.has_host_pwr_iface)
*value |=
((dummy->power_changed && (dummy->power_changed_mask & 0x1)) << 9) |
((dummy->power_changed && (dummy->power_changed_mask & 0x2))
<< 10) |
((dummy->reset_completed & dummy->reset_completed_mask) << 8);
#else
*value |= ((dummy->power_changed && (dummy->power_changed_mask & 0x1)) << 9) |
((dummy->power_changed && (dummy->power_changed_mask & 0x2)) << 10) |
((dummy->reset_completed & dummy->reset_completed_mask) << 8);
#endif
pr_debug("GPU_IRQ_STAT read %x", *value);
} else if (addr == GET_GPU_CONTROL_REG(GPU_STATUS)) {
*value = 0;
#if !MALI_USE_CSF
} else if (addr == GET_GPU_CONTROL_REG(LATEST_FLUSH)) {
*value = 0;
#endif
} else if (addr == GET_GPU_CONTROL_REG(GPU_FAULTSTATUS)) {
*value = hw_error_status.gpu_fault_status;
} else if (addr == GET_GPU_CONTROL_REG(L2_CONFIG)) {
*value = dummy->l2_config;
#if MALI_USE_CSF
} else if ((addr >= GET_GPU_CONTROL_REG(SYSC_ALLOC0)) &&
(addr < GET_GPU_CONTROL_REG(SYSC_ALLOC(SYSC_ALLOC_COUNT)))) {
u32 alloc_reg = (addr - GET_GPU_CONTROL_REG(SYSC_ALLOC0)) >> 2;
@@ -2042,8 +1672,6 @@ void midgard_model_read_reg(void *h, u32 addr, u32 *const value)
addr == GET_HOST_POWER_REG(HOST_POWER_NEURAL_PWRTRANS_LO) ||
addr == GET_HOST_POWER_REG(HOST_POWER_NEURAL_PWRTRANS_HI) ||
addr == GET_HOST_POWER_REG(HOST_POWER_L2_PWRACTIVE_LO) ||
addr == GET_HOST_POWER_REG(HOST_POWER_L2_PWRACTIVE_HI) ||
addr == GET_HOST_POWER_REG(HOST_POWER_TILER_PWRACTIVE_LO) ||
addr == GET_HOST_POWER_REG(HOST_POWER_TILER_PWRACTIVE_HI) ||
addr == GET_HOST_POWER_REG(HOST_POWER_SHADER_PWRACTIVE_LO) ||
@@ -2066,7 +1694,6 @@ void midgard_model_read_reg(void *h, u32 addr, u32 *const value)
"Dummy model register access: Reading unknown control reg 0x%x\n",
addr);
}
#endif
} else if ((addr >= GET_GPU_CONTROL_REG(SHADER_PRESENT_LO)) &&
(addr <= GET_GPU_CONTROL_REG(L2_MMU_CONFIG))) {
if (addr == GET_GPU_CONTROL_REG(SHADER_PRESENT_LO) ||
@@ -2106,8 +1733,6 @@ void midgard_model_read_reg(void *h, u32 addr, u32 *const value)
addr == GET_GPU_CONTROL_REG(SHADER_PWRTRANS_HI) ||
addr == GET_GPU_CONTROL_REG(STACK_PWRTRANS_LO) ||
addr == GET_GPU_CONTROL_REG(STACK_PWRTRANS_HI) ||
addr == GET_GPU_CONTROL_REG(L2_PWRACTIVE_LO) ||
addr == GET_GPU_CONTROL_REG(L2_PWRACTIVE_HI) ||
addr == GET_GPU_CONTROL_REG(TILER_PWRACTIVE_LO) ||
addr == GET_GPU_CONTROL_REG(TILER_PWRACTIVE_HI) ||
addr == GET_GPU_CONTROL_REG(SHADER_PWRACTIVE_LO) ||
@@ -2131,51 +1756,6 @@ void midgard_model_read_reg(void *h, u32 addr, u32 *const value)
addr);
}
#if !MALI_USE_CSF
} else if ((addr >= JOB_CONTROL_REG(JOB_SLOT0)) &&
(addr < (JOB_CONTROL_REG(JOB_SLOT15) + 0x80))) {
int slot_idx = (addr >> 7) & 0xf;
int sub_reg = addr & 0x7F;
KBASE_DEBUG_ASSERT(slot_idx < NUM_SLOTS);
switch (sub_reg) {
case JS_HEAD_NEXT_LO:
*value = (u32)((hw_error_status.current_jc) & 0xFFFFFFFF);
break;
case JS_HEAD_NEXT_HI:
*value = (u32)(hw_error_status.current_jc >> 32);
break;
case JS_STATUS:
if (hw_error_status.js_status[slot_idx])
*value = hw_error_status.js_status[slot_idx];
else /* 0x08 means active, 0x00 idle */
*value = (dummy->slots[slot_idx].job_active) << 3;
break;
case JS_COMMAND_NEXT:
*value = dummy->slots[slot_idx].job_queued;
break;
/**
* The dummy model does not implement these registers
* avoid printing error messages
*/
case JS_HEAD_HI:
case JS_HEAD_LO:
case JS_TAIL_HI:
case JS_TAIL_LO:
case JS_FLUSH_ID_NEXT:
break;
default:
model_error_log(
KBASE_CORE,
"Dummy model register access: unknown job slot reg 0x%02X being read\n",
sub_reg);
break;
}
} else if (addr == GET_GPU_CONTROL_REG(JS_PRESENT)) {
*value = 0x7;
#endif /* !MALI_USE_CSF */
} else if (addr == GET_GPU_CONTROL_REG(AS_PRESENT)) {
*value = dummy->control_reg_values->as_present;
} else if (addr >= GET_GPU_CONTROL_REG(TEXTURE_FEATURES_0) &&
@@ -2188,27 +1768,6 @@ void midgard_model_read_reg(void *h, u32 addr, u32 *const value)
*value = 0x9f81ffff;
else if (addr == GET_GPU_CONTROL_REG(TEXTURE_FEATURES_3))
*value = 0;
#if !MALI_USE_CSF
} else if (addr >= GPU_CONTROL_REG(JS0_FEATURES) &&
addr <= GPU_CONTROL_REG(JS15_FEATURES)) {
switch (addr) {
case GPU_CONTROL_REG(JS0_FEATURES):
*value = 0x20e;
break;
case GPU_CONTROL_REG(JS1_FEATURES):
*value = 0x1fe;
break;
case GPU_CONTROL_REG(JS2_FEATURES):
*value = 0x7e;
break;
default:
*value = 0;
break;
}
#endif /* !MALI_USE_CSF */
} else if (addr >= GET_GPU_CONTROL_REG(L2_FEATURES) &&
addr <= GET_GPU_CONTROL_REG(MMU_FEATURES)) {
if (addr == GET_GPU_CONTROL_REG(L2_FEATURES))
@@ -2242,8 +1801,11 @@ void midgard_model_read_reg(void *h, u32 addr, u32 *const value)
} else if ((addr >= MMU_STAGE1_REG(MMU_AS_REG(0, AS_TRANSTAB_LO))) &&
(addr <= MMU_STAGE1_REG(MMU_AS_REG(15, AS_STATUS)))) {
u32 mem_addr_space = (addr - MMU_STAGE1_REG(MMU_AS_REG(0, AS_TRANSTAB_LO))) >>
MMU_STAGE1_AS_SHIFT;
u32 mem_addr_space;
mem_addr_space = (addr - MMU_STAGE1_REG(MMU_AS_REG(0, AS_TRANSTAB_LO))) >>
MMU_STAGE1_AS_SHIFT;
switch (addr & 0x3F) {
case AS_TRANSTAB_LO:
*value = (u32)(hw_error_status.as_transtab[mem_addr_space] & 0xffffffff);
@@ -2289,7 +1851,6 @@ void midgard_model_read_reg(void *h, u32 addr, u32 *const value)
*value = hw_error_status.mmu_irq_rawstat;
} else if (addr == MMU_CONTROL_REG(MMU_IRQ_STATUS)) {
*value = hw_error_status.mmu_irq_mask & hw_error_status.mmu_irq_rawstat;
#if MALI_USE_CSF
} else if (addr == IPA_CONTROL_REG(STATUS) ||
addr == IPA_CONTROL_REG(STATUS) + GPU_GOV_IPA_CONTROL_OFFSET) {
*value = (ipa_control_timer_enabled << 31);
@@ -2382,7 +1943,6 @@ void midgard_model_read_reg(void *h, u32 addr, u32 *const value)
*value = gpu_model_get_prfcnt_value(KBASE_IPA_CORE_TYPE_NEURAL, counter_index,
is_low_word);
#endif /* MALI_USE_CSF */
} else if (addr == GET_GPU_CONTROL_REG(GPU_FEATURES_LO)) {
*value = dummy->control_reg_values->gpu_features_lo;
} else if (addr == GET_GPU_CONTROL_REG(GPU_FEATURES_HI)) {
@@ -2473,13 +2033,8 @@ int gpu_model_set_dummy_prfcnt_user_sample(u32 __user *data, u32 size)
}
spin_lock_irqsave(&performance_counters.access_lock, flags);
#if !MALI_USE_CSF
offset = set_user_sample_core_type(performance_counters.jm_counters, user_data, offset,
size, 1);
#else
offset = set_user_sample_core_type(performance_counters.cshw_counters, user_data, offset,
size, 1);
#endif /* !MALI_USE_CSF */
offset = set_user_sample_core_type(performance_counters.tiler_counters, user_data, offset,
size, hweight64(DUMMY_IMPLEMENTATION_TILER_PRESENT));
offset = set_user_sample_core_type(performance_counters.l2_counters, user_data, offset,
@@ -2499,13 +2054,8 @@ void gpu_model_set_dummy_prfcnt_kernel_sample(u64 *data, u32 size)
u32 offset = 0;
spin_lock_irqsave(&performance_counters.access_lock, flags);
#if !MALI_USE_CSF
offset = set_kernel_sample_core_type(performance_counters.jm_counters, data, offset, size,
1);
#else
offset = set_kernel_sample_core_type(performance_counters.cshw_counters, data, offset, size,
1);
#endif /* !MALI_USE_CSF */
offset = set_kernel_sample_core_type(performance_counters.tiler_counters, data, offset,
size, hweight64(DUMMY_IMPLEMENTATION_TILER_PRESENT));
offset = set_kernel_sample_core_type(performance_counters.l2_counters, data, offset, size,

View File

@@ -202,7 +202,6 @@ void gpu_model_set_dummy_prfcnt_cores(struct kbase_device *kbdev, u64 l2_present
/* Clear the counter values array maintained by the dummy model */
void gpu_model_clear_prfcnt_values(void);
#if MALI_USE_CSF
/**
* gpu_model_prfcnt_dump_request() - Request performance counter sample dump.
* @sample_buf: Pointer to KBASE_DUMMY_MODEL_MAX_VALUES_PER_SAMPLE sized array
@@ -217,7 +216,6 @@ void gpu_model_prfcnt_dump_request(uint32_t *sample_buf, struct gpu_model_prfcnt
* @model: Model pointer returned by midgard_model_create().
*/
void gpu_model_glb_request_job_irq(void *model);
#endif /* MALI_USE_CSF */
extern struct error_status_t hw_error_status;

View File

@@ -1,7 +1,7 @@
// SPDX-License-Identifier: GPL-2.0 WITH Linux-syscall-note
/*
*
* (C) COPYRIGHT 2010-2023 ARM Limited. All rights reserved.
* (C) COPYRIGHT 2010-2024 ARM Limited. All rights reserved.
*
* This program is free software and is provided to you under the terms of the
* GNU General Public License version 2 as published by the Free Software
@@ -67,9 +67,7 @@ const struct kbase_pm_policy kbase_pm_always_on_policy_ops = {
always_on_get_core_active, /* get_core_active */
NULL, /* handle_event */
KBASE_PM_POLICY_ID_ALWAYS_ON, /* id */
#if MALI_USE_CSF
ALWAYS_ON_PM_SCHED_FLAGS, /* pm_sched_flags */
#endif
};
KBASE_EXPORT_TEST_API(kbase_pm_always_on_policy_ops);

View File

@@ -29,20 +29,13 @@
#include <mali_kbase_io.h>
#include <mali_kbase_pm.h>
#if !MALI_USE_CSF
#include <mali_kbase_hwaccess_jm.h>
#include <backend/gpu/mali_kbase_js_internal.h>
#include <backend/gpu/mali_kbase_jm_internal.h>
#else
#include <linux/version_compat_defs_for_valhall.h>
#include <linux/pm_runtime.h>
#include <mali_kbase_reset_gpu.h>
#include <csf/mali_kbase_csf_scheduler.h>
#endif /* !MALI_USE_CSF */
#include <hwcnt/mali_kbase_hwcnt_context.h>
#include <backend/gpu/mali_kbase_pm_internal.h>
#include <backend/gpu/mali_kbase_devfreq.h>
#include <mali_kbase_dummy_job_wa.h>
#include <backend/gpu/mali_kbase_irq_internal.h>
@@ -99,9 +92,6 @@ void kbase_pm_register_access_enable(struct kbase_device *kbdev)
if (callbacks)
callbacks->power_on_callback(kbdev);
if (WARN_ON(kbase_io_is_aw_removed(kbdev)))
dev_err(kbdev->dev, "Attempting to power on while GPU lost\n");
kbase_io_clear_status(kbdev->io, KBASE_IO_STATUS_GPU_OFF);
}
@@ -124,6 +114,7 @@ int kbase_hwaccess_pm_init(struct kbase_device *kbdev)
KBASE_DEBUG_ASSERT(kbdev != NULL);
mutex_init(&kbdev->pm.lock);
kbdev->pm.runtime_suspend_result = 0;
kbdev->pm.backend.gpu_poweroff_wait_wq =
alloc_workqueue("kbase_pm_poweroff_wait", WQ_HIGHPRI | WQ_UNBOUND, 1);
@@ -133,22 +124,17 @@ int kbase_hwaccess_pm_init(struct kbase_device *kbdev)
INIT_WORK(&kbdev->pm.backend.gpu_poweroff_wait_work, kbase_pm_gpu_poweroff_wait_wq);
kbdev->pm.backend.ca_cores_enabled = ~0ull;
kbase_io_clear_status(kbdev->io, KBASE_IO_STATUS_AW_REMOVED);
if (kbase_hw_has_feature(kbdev, KBASE_HW_FEATURE_GOV_CORE_MASK_SUPPORT))
kbdev->pm.backend.ca_gov_cores_enabled = ~0ull;
init_waitqueue_head(&kbdev->pm.backend.gpu_in_desired_state_wait);
#if !MALI_USE_CSF
/* Initialise the metrics subsystem */
ret = kbasep_pm_metrics_init(kbdev);
if (ret)
return ret;
#else
mutex_init(&kbdev->pm.backend.policy_change_lock);
kbdev->pm.backend.policy_change_clamp_state_to_off = false;
/* Due to dependency on kbase_ipa_control, the metrics subsystem can't
* be initialized here.
*/
CSTD_UNUSED(ret);
#endif
init_waitqueue_head(&kbdev->pm.backend.reset_done_wait);
kbdev->pm.backend.reset_done = false;
@@ -162,12 +148,10 @@ int kbase_hwaccess_pm_init(struct kbase_device *kbdev)
init_waitqueue_head(&kbdev->pm.backend.poweroff_wait);
#if MALI_USE_CSF
/* Select the power interface that the GPU is using. */
kbdev->pm.backend.has_host_pwr_iface =
kbase_hw_has_feature(kbdev, KBASE_HW_FEATURE_POWER_CONTROL);
kbdev->pm.backend.pwr_cntl_delegated = false;
#endif
if (kbase_pm_ca_init(kbdev) != 0)
goto workq_fail;
@@ -181,24 +165,27 @@ int kbase_hwaccess_pm_init(struct kbase_device *kbdev)
INIT_WORK(&kbdev->pm.backend.hwcnt_disable_work, kbase_pm_hwcnt_disable_worker);
kbase_hwcnt_context_disable(kbdev->hwcnt_gpu_ctx);
#if MALI_USE_CSF && defined(KBASE_PM_RUNTIME)
kbdev->pm.backend.gpu_sleep_allowed = 0;
if (kbase_hw_has_feature(kbdev, KBASE_HW_FEATURE_GPU_SLEEP) &&
!kbase_hw_has_issue(kbdev, KBASE_HW_ISSUE_TURSEHW_1997) &&
kbdev->pm.backend.callback_power_runtime_gpu_active &&
kbdev->pm.backend.callback_power_runtime_gpu_idle)
set_bit(KBASE_GPU_SUPPORTS_GPU_SLEEP, &kbdev->pm.backend.gpu_sleep_allowed);
if (IS_ENABLED(CONFIG_PM)) {
kbdev->pm.backend.gpu_sleep_allowed = 0;
if (kbase_hw_has_feature(kbdev, KBASE_HW_FEATURE_GPU_SLEEP) &&
!kbase_hw_has_issue(kbdev, KBASE_HW_ISSUE_TURSEHW_1997) &&
kbdev->pm.backend.callback_power_runtime_gpu_active &&
kbdev->pm.backend.callback_power_runtime_gpu_idle)
set_bit(KBASE_GPU_SUPPORTS_GPU_SLEEP, &kbdev->pm.backend.gpu_sleep_allowed);
kbdev->pm.backend.apply_hw_issue_TITANHW_2938_wa =
kbase_hw_has_issue(kbdev, KBASE_HW_ISSUE_TITANHW_2938) &&
test_bit(KBASE_GPU_SUPPORTS_GPU_SLEEP, &kbdev->pm.backend.gpu_sleep_allowed);
kbdev->pm.backend.apply_hw_issue_TITANHW_2938_wa =
kbase_hw_has_issue(kbdev, KBASE_HW_ISSUE_TITANHW_2938) &&
test_bit(KBASE_GPU_SUPPORTS_GPU_SLEEP,
&kbdev->pm.backend.gpu_sleep_allowed);
/* FW Sleep-on-Idle is only available in certain architecture revisions */
if ((kbdev->gpu_props.gpu_id.arch_major > 11) ||
((kbdev->gpu_props.gpu_id.arch_major == 11) &&
(kbdev->gpu_props.gpu_id.arch_minor >= 8) && (kbdev->gpu_props.gpu_id.arch_rev >= 10)))
set_bit(KBASE_GPU_SUPPORTS_FW_SLEEP_ON_IDLE, &kbdev->pm.backend.gpu_sleep_allowed);
#endif
/* FW Sleep-on-Idle is only available in certain architecture revisions */
if ((kbdev->gpu_props.gpu_id.arch_major > 11) ||
((kbdev->gpu_props.gpu_id.arch_major == 11) &&
(kbdev->gpu_props.gpu_id.arch_minor >= 8) &&
(kbdev->gpu_props.gpu_id.arch_rev >= 10)))
set_bit(KBASE_GPU_SUPPORTS_FW_SLEEP_ON_IDLE,
&kbdev->pm.backend.gpu_sleep_allowed);
}
if (IS_ENABLED(CONFIG_MALI_VALHALL_HW_ERRATA_1485982_NOT_AFFECTED))
return 0;
@@ -225,9 +212,6 @@ pm_state_machine_fail:
kbase_pm_policy_term(kbdev);
kbase_pm_ca_term(kbdev);
workq_fail:
#if !MALI_USE_CSF
kbasep_pm_metrics_term(kbdev);
#endif
return -EINVAL;
}
@@ -259,7 +243,6 @@ void kbase_pm_do_poweron(struct kbase_device *kbdev, bool is_resume)
*/
}
#if MALI_USE_CSF
static bool wait_cond_mmu_fault_handling_in_gpu_poweroff_wait_wq(struct kbase_device *kbdev,
int faults_pending)
{
@@ -272,7 +255,6 @@ static bool wait_cond_mmu_fault_handling_in_gpu_poweroff_wait_wq(struct kbase_de
return cond;
}
#endif
/**
* wait_for_mmu_fault_handling_in_gpu_poweroff_wait() - Wait for pending MMU
@@ -288,7 +270,6 @@ static bool wait_cond_mmu_fault_handling_in_gpu_poweroff_wait_wq(struct kbase_de
*/
static void wait_for_mmu_fault_handling_in_gpu_poweroff_wait(struct kbase_device *kbdev)
{
#if MALI_USE_CSF
bool reset_triggered = false;
int ret = 0;
@@ -318,19 +299,12 @@ static void wait_for_mmu_fault_handling_in_gpu_poweroff_wait(struct kbase_device
}
} while (ret);
kbdev->pm.backend.waiting_for_mmu_fault_handling = false;
#else
kbase_pm_unlock(kbdev);
kbase_flush_mmu_wqs(kbdev);
kbase_pm_lock(kbdev);
#endif
}
static void pm_handle_power_off(struct kbase_device *kbdev)
{
struct kbase_pm_backend_data *backend = &kbdev->pm.backend;
#if MALI_USE_CSF
enum kbase_mcu_state mcu_state;
#endif
unsigned long flags;
lockdep_assert_held(&kbdev->pm.lock);
@@ -339,28 +313,24 @@ static void pm_handle_power_off(struct kbase_device *kbdev)
return;
spin_lock_irqsave(&kbdev->hwaccess_lock, flags);
#if MALI_USE_CSF && defined(KBASE_PM_RUNTIME)
if (kbdev->pm.backend.gpu_wakeup_override) {
if (IS_ENABLED(CONFIG_PM) && kbdev->pm.backend.gpu_wakeup_override) {
spin_unlock_irqrestore(&kbdev->hwaccess_lock, flags);
return;
}
#endif
WARN_ON(backend->shaders_state != KBASE_SHADERS_OFF_CORESTACK_OFF ||
backend->l2_state != KBASE_L2_OFF);
#if MALI_USE_CSF
mcu_state = backend->mcu_state;
WARN_ON(!kbase_pm_is_mcu_inactive(kbdev, mcu_state));
#endif
spin_unlock_irqrestore(&kbdev->hwaccess_lock, flags);
#if MALI_USE_CSF && defined(KBASE_PM_RUNTIME)
if (backend->callback_power_runtime_gpu_idle) {
if (IS_ENABLED(CONFIG_PM) && backend->callback_power_runtime_gpu_idle) {
WARN_ON(backend->gpu_idled);
backend->callback_power_runtime_gpu_idle(kbdev);
backend->gpu_idled = true;
return;
}
#endif
/* Disable interrupts and turn the clock off */
if (unlikely(!kbase_pm_clock_off(kbdev))) {
@@ -398,21 +368,12 @@ void kbase_pm_handle_gpu_poweroff_wait_work(struct kbase_device *kbdev)
KBASE_KTRACE_ADD(kbdev, PM_POWEROFF_WAIT_WQ, NULL, 0);
#if !MALI_USE_CSF
/* Wait for power transitions to complete. We do this with no locks held
* so that we don't deadlock with any pending workqueues.
*/
kbase_pm_wait_for_desired_state(kbdev);
#endif
kbase_pm_lock(kbdev);
#if MALI_USE_CSF
spin_lock_irqsave(&kbdev->hwaccess_lock, flags);
if (pm->backend.invoke_poweroff_wait_wq_when_l2_off ||
!pm->backend.poweroff_wait_in_progress)
goto wakeup_exit;
spin_unlock_irqrestore(&kbdev->hwaccess_lock, flags);
#endif
pm_handle_power_off(kbdev);
@@ -421,18 +382,11 @@ void kbase_pm_handle_gpu_poweroff_wait_work(struct kbase_device *kbdev)
if (backend->poweron_required) {
backend->poweron_required = false;
kbdev->pm.backend.l2_desired = true;
#if MALI_USE_CSF
kbdev->pm.backend.mcu_desired = true;
#endif
kbase_pm_update_state(kbdev);
kbase_pm_update_cores_state_nolock(kbdev);
#if !MALI_USE_CSF
kbase_backend_slot_update(kbdev);
#endif /* !MALI_USE_CSF */
}
#if MALI_USE_CSF
wakeup_exit:
#endif
spin_unlock_irqrestore(&kbdev->hwaccess_lock, flags);
kbase_pm_unlock(kbdev);
wake_up(&kbdev->pm.backend.poweroff_wait);
@@ -589,28 +543,20 @@ static void kbase_pm_hwcnt_disable_worker(struct work_struct *data)
*/
backend->hwcnt_disabled = true;
kbase_pm_update_state(kbdev);
#if !MALI_USE_CSF
kbase_backend_slot_update(kbdev);
#endif /* !MALI_USE_CSF */
} else {
/* PM state was updated while we were doing the disable,
* so we need to undo the disable we just performed.
*/
#if MALI_USE_CSF
unsigned long lock_flags;
kbase_csf_scheduler_spin_lock(kbdev, &lock_flags);
#endif
kbase_hwcnt_context_enable(kbdev->hwcnt_gpu_ctx);
#if MALI_USE_CSF
kbase_csf_scheduler_spin_unlock(kbdev, lock_flags);
#endif
}
spin_unlock_irqrestore(&kbdev->hwaccess_lock, flags);
}
#if MALI_USE_CSF && defined(KBASE_PM_RUNTIME)
/**
* kbase_pm_do_poweroff_sync - Do the synchronous power down of GPU
*
@@ -679,7 +625,6 @@ out:
kbase_pm_unlock(kbdev);
return ret;
}
#endif
void kbase_pm_do_poweroff(struct kbase_device *kbdev)
{
@@ -695,12 +640,7 @@ void kbase_pm_do_poweroff(struct kbase_device *kbdev)
if (kbdev->pm.backend.poweroff_wait_in_progress)
goto unlock_hwaccess;
#if MALI_USE_CSF
kbdev->pm.backend.mcu_desired = false;
#else
/* Force all cores off */
kbdev->pm.backend.shaders_desired = false;
#endif
kbdev->pm.backend.l2_desired = false;
kbdev->pm.backend.poweroff_wait_in_progress = true;
@@ -744,7 +684,10 @@ int kbase_hwaccess_pm_powerup(struct kbase_device *kbdev, unsigned int flags)
kbase_pm_unlock(kbdev);
return ret;
}
#if MALI_USE_CSF
if (kbase_hw_has_feature(kbdev, KBASE_HW_FEATURE_GOV_CORE_MASK_SUPPORT))
kbdev->pm.sysfs_gov_core_mask = kbdev->gpu_props.shader_present;
kbdev->pm.debug_core_mask = kbdev->gpu_props.shader_present;
spin_lock_irqsave(&kbdev->hwaccess_lock, irq_flags);
/* Set the initial value for 'shaders_avail'. It would be later
@@ -755,25 +698,19 @@ int kbase_hwaccess_pm_powerup(struct kbase_device *kbdev, unsigned int flags)
*/
kbdev->pm.backend.shaders_avail = kbase_pm_ca_get_core_mask(kbdev);
spin_unlock_irqrestore(&kbdev->hwaccess_lock, irq_flags);
#else
kbdev->pm.debug_core_mask_all = kbdev->pm.debug_core_mask[0] =
kbdev->pm.debug_core_mask[1] = kbdev->pm.debug_core_mask[2] =
kbdev->gpu_props.shader_present;
#endif
/* Pretend the GPU is active to prevent a power policy turning the GPU
* cores off
*/
kbdev->pm.active_count = 1;
#if MALI_USE_CSF && KBASE_PM_RUNTIME
if (kbdev->pm.backend.callback_power_runtime_gpu_active) {
if (IS_ENABLED(CONFIG_PM) && kbdev->pm.backend.callback_power_runtime_gpu_active) {
/* Take the RPM reference count to match with the internal
* PM reference count
*/
kbdev->pm.backend.callback_power_runtime_gpu_active(kbdev);
WARN_ON(kbdev->pm.backend.gpu_idled);
}
#endif
spin_lock_irqsave(&kbdev->pm.backend.gpu_cycle_counter_requests_lock, irq_flags);
/* Ensure cycle counter is off */
@@ -790,12 +727,10 @@ int kbase_hwaccess_pm_powerup(struct kbase_device *kbdev, unsigned int flags)
kbdev->pm.backend.gpu_ready = true;
/* Turn on the GPU and any cores needed by the policy */
#if MALI_USE_CSF
/* Turn on the L2 caches, needed for firmware boot */
spin_lock_irqsave(&kbdev->hwaccess_lock, irq_flags);
kbdev->pm.backend.l2_desired = true;
spin_unlock_irqrestore(&kbdev->hwaccess_lock, irq_flags);
#endif
kbase_pm_do_poweron(kbdev, false);
kbase_pm_unlock(kbdev);
@@ -806,15 +741,14 @@ void kbase_hwaccess_pm_halt(struct kbase_device *kbdev)
{
KBASE_DEBUG_ASSERT(kbdev != NULL);
#if MALI_USE_CSF && defined(KBASE_PM_RUNTIME)
WARN_ON(kbase_pm_do_poweroff_sync(kbdev));
#else
mutex_lock(&kbdev->pm.lock);
kbase_pm_do_poweroff(kbdev);
mutex_unlock(&kbdev->pm.lock);
kbase_pm_wait_for_poweroff_work_complete(kbdev);
#endif
if (IS_ENABLED(CONFIG_PM))
WARN_ON(kbase_pm_do_poweroff_sync(kbdev));
else {
mutex_lock(&kbdev->pm.lock);
kbase_pm_do_poweroff(kbdev);
mutex_unlock(&kbdev->pm.lock);
kbase_pm_wait_for_poweroff_work_complete(kbdev);
}
}
KBASE_EXPORT_TEST_API(kbase_hwaccess_pm_halt);
@@ -827,17 +761,12 @@ void kbase_hwaccess_pm_term(struct kbase_device *kbdev)
cancel_work_sync(&kbdev->pm.backend.hwcnt_disable_work);
if (kbdev->pm.backend.hwcnt_disabled) {
if (kbdev->pm.backend.hwcnt_disabled && kbdev->csf.firmware_hctl_core_pwr) {
unsigned long flags;
#if MALI_USE_CSF
kbase_csf_scheduler_spin_lock(kbdev, &flags);
kbase_hwcnt_context_enable(kbdev->hwcnt_gpu_ctx);
kbase_csf_scheduler_spin_unlock(kbdev, flags);
#else
spin_lock_irqsave(&kbdev->hwaccess_lock, flags);
kbase_hwcnt_context_enable(kbdev->hwcnt_gpu_ctx);
spin_unlock_irqrestore(&kbdev->hwaccess_lock, flags);
#endif
}
/* Free any resources the policy allocated */
@@ -845,16 +774,11 @@ void kbase_hwaccess_pm_term(struct kbase_device *kbdev)
kbase_pm_policy_term(kbdev);
kbase_pm_ca_term(kbdev);
#if !MALI_USE_CSF
/* Shut down the metrics subsystem */
kbasep_pm_metrics_term(kbdev);
#else
if (WARN_ON(mutex_is_locked(&kbdev->pm.backend.policy_change_lock))) {
mutex_lock(&kbdev->pm.backend.policy_change_lock);
mutex_unlock(&kbdev->pm.backend.policy_change_lock);
}
mutex_destroy(&kbdev->pm.backend.policy_change_lock);
#endif
destroy_workqueue(kbdev->pm.backend.gpu_poweroff_wait_wq);
}
@@ -866,48 +790,23 @@ void kbase_pm_power_changed(struct kbase_device *kbdev)
spin_lock_irqsave(&kbdev->hwaccess_lock, flags);
kbase_pm_update_state(kbdev);
#if !MALI_USE_CSF
kbase_backend_slot_update(kbdev);
#endif /* !MALI_USE_CSF */
spin_unlock_irqrestore(&kbdev->hwaccess_lock, flags);
}
#if MALI_USE_CSF
void kbase_pm_set_debug_core_mask(struct kbase_device *kbdev, u64 new_core_mask)
{
lockdep_assert_held(&kbdev->hwaccess_lock);
lockdep_assert_held(&kbdev->pm.lock);
kbdev->pm.debug_core_mask = new_core_mask;
kbase_pm_update_dynamic_cores_onoff(kbdev);
if (kbase_hw_has_feature(kbdev, KBASE_HW_FEATURE_GOV_CORE_MASK_SUPPORT)) {
kbdev->pm.sysfs_gov_core_mask = new_core_mask;
kbase_pm_ca_set_gov_core_mask_nolock(kbdev, SYSFS_COREMASK, new_core_mask);
} else {
kbdev->pm.debug_core_mask = new_core_mask;
kbase_pm_update_dynamic_cores_onoff(kbdev);
}
}
KBASE_EXPORT_TEST_API(kbase_pm_set_debug_core_mask);
#else
void kbase_pm_set_debug_core_mask(struct kbase_device *kbdev, u64 *new_core_mask,
size_t new_core_mask_size)
{
size_t i;
lockdep_assert_held(&kbdev->hwaccess_lock);
lockdep_assert_held(&kbdev->pm.lock);
if (kbase_dummy_job_wa_enabled(kbdev)) {
dev_warn_once(
kbdev->dev,
"Change of core mask not supported for slot 0 as dummy job WA is enabled");
new_core_mask[0] = kbdev->pm.debug_core_mask[0];
}
kbdev->pm.debug_core_mask_all = 0;
for (i = 0; i < new_core_mask_size; i++) {
kbdev->pm.debug_core_mask[i] = new_core_mask[i];
kbdev->pm.debug_core_mask_all |= new_core_mask[i];
}
kbase_pm_update_dynamic_cores_onoff(kbdev);
}
#endif /* MALI_USE_CSF */
void kbase_hwaccess_pm_gpu_active(struct kbase_device *kbdev)
{
@@ -923,35 +822,23 @@ int kbase_hwaccess_pm_suspend(struct kbase_device *kbdev)
{
int ret = 0;
#if MALI_USE_CSF && defined(KBASE_PM_RUNTIME)
ret = kbase_pm_do_poweroff_sync(kbdev);
if (ret)
return ret;
#else
/* Force power off the GPU and all cores (regardless of policy), only
* after the PM active count reaches zero (otherwise, we risk turning it
* off prematurely)
*/
kbase_pm_lock(kbdev);
if (IS_ENABLED(CONFIG_PM)) {
ret = kbase_pm_do_poweroff_sync(kbdev);
if (ret)
return ret;
} else {
/* Force power off the GPU and all cores (regardless of policy), only
* after the PM active count reaches zero (otherwise, we risk turning it
* off prematurely)
*/
kbase_pm_lock(kbdev);
kbase_pm_do_poweroff(kbdev);
kbase_pm_unlock(kbdev);
kbase_pm_do_poweroff(kbdev);
#if !MALI_USE_CSF
kbase_backend_timer_suspend(kbdev);
#endif /* !MALI_USE_CSF */
kbase_pm_unlock(kbdev);
ret = kbase_pm_wait_for_poweroff_work_complete(kbdev);
if (ret) {
#if !MALI_USE_CSF
mutex_lock(&kbdev->js_data.runpool_mutex);
kbase_backend_timer_resume(kbdev);
mutex_unlock(&kbdev->js_data.runpool_mutex);
#endif /* !MALI_USE_CSF */
return ret;
ret = kbase_pm_wait_for_poweroff_work_complete(kbdev);
if (ret)
return ret;
}
#endif
WARN_ON(kbase_io_is_gpu_powered(kbdev));
WARN_ON(atomic_read(&kbdev->faults_pending));
@@ -976,10 +863,6 @@ void kbase_hwaccess_pm_resume(struct kbase_device *kbdev)
}
kbase_pm_do_poweron(kbdev, true);
#if !MALI_USE_CSF
kbase_backend_timer_resume(kbdev);
#endif /* !MALI_USE_CSF */
kbase_pm_unlock(kbdev);
}
@@ -995,24 +878,23 @@ void kbase_pm_handle_gpu_lost(struct kbase_device *kbdev)
return;
}
#if MALI_USE_CSF
spin_lock_irqsave(&kbdev->hwaccess_lock, flags);
if (kbase_io_is_gpu_powered(kbdev) && !kbase_io_is_aw_removed(kbdev)) {
if (kbase_io_is_aw_removed(kbdev)) {
unsigned long flags_sched;
spin_unlock_irqrestore(&kbdev->hwaccess_lock, flags);
/* GPU is no longer mapped to VM. So no interrupts will
* be received and Mali registers have been replaced by
* dummy RAM
*/
WARN(kbase_io_has_gpu(kbdev), "GPU is still available after GPU lost event\n");
spin_lock_irqsave(&kbdev->hwaccess_lock, flags);
kbase_csf_scheduler_spin_lock(kbdev, &flags_sched);
if (atomic_read(&kbdev->hwaccess.backend.reset_gpu) != KBASE_RESET_GPU_NOT_PENDING)
dev_warn(kbdev->dev, "GPU reset pending at the time of GPU lost event");
atomic_set(&kbdev->hwaccess.backend.reset_gpu, KBASE_RESET_GPU_NOT_PENDING);
kbase_csf_scheduler_spin_unlock(kbdev, flags_sched);
spin_unlock_irqrestore(&kbdev->hwaccess_lock, flags);
kbase_synchronize_irqs(kbdev);
@@ -1030,60 +912,13 @@ void kbase_pm_handle_gpu_lost(struct kbase_device *kbdev)
spin_lock_irqsave(&kbdev->hwaccess_lock, flags);
kbdev->protected_mode = false;
kbase_pm_update_state(kbdev);
spin_unlock_irqrestore(&kbdev->hwaccess_lock, flags);
/* Cancel any pending HWC dumps */
kbase_hwcnt_backend_csf_on_unrecoverable_error(&kbdev->hwcnt_gpu_iface);
}
spin_unlock_irqrestore(&kbdev->hwaccess_lock, flags);
#else
/* Releasing the VM state lock here is safe because
* we are guaranteed to be in either STOPPING_IDLE,
* STOPPING_ACTIVE or SUSPEND_PENDING at this point.
* The only transitions that are valid from here are to
* STOPPED, STOPPED_GPU_REQUESTED or SUSPENDED which can
* only happen at the completion of the GPU lost handling.
*/
mutex_unlock(&arb_vm_state->vm_state_lock);
mutex_lock(&kbdev->pm.lock);
mutex_lock(&arb_vm_state->vm_state_lock);
if (kbase_io_is_gpu_powered(kbdev) && !kbase_io_is_aw_removed(kbdev)) {
ktime_t end_timestamp = ktime_get_raw();
/* GPU is no longer mapped to VM. So no interrupts will
* be received and Mali registers have been replaced by
* dummy RAM
*/
WARN(kbase_io_has_gpu(kbdev), "GPU is still available after GPU lost event\n");
/* Full GPU reset will have been done by hypervisor, so cancel */
atomic_set(&kbdev->hwaccess.backend.reset_gpu, KBASE_RESET_GPU_NOT_PENDING);
hrtimer_cancel(&kbdev->hwaccess.backend.reset_timer);
kbase_synchronize_irqs(kbdev);
/* Clear all jobs running on the GPU */
spin_lock_irqsave(&kbdev->hwaccess_lock, flags);
kbdev->protected_mode = false;
kbase_backend_reset(kbdev, &end_timestamp);
kbase_pm_metrics_update(kbdev, NULL);
kbase_pm_update_state(kbdev);
spin_unlock_irqrestore(&kbdev->hwaccess_lock, flags);
/* Cancel any pending HWC dumps */
spin_lock_irqsave(&kbdev->hwcnt.lock, flags);
if (kbdev->hwcnt.backend.state == KBASE_INSTR_STATE_DUMPING ||
kbdev->hwcnt.backend.state == KBASE_INSTR_STATE_FAULT) {
kbdev->hwcnt.backend.state = KBASE_INSTR_STATE_FAULT;
kbdev->hwcnt.backend.triggered = 1;
wake_up(&kbdev->hwcnt.backend.wait);
}
spin_unlock_irqrestore(&kbdev->hwcnt.lock, flags);
}
mutex_unlock(&kbdev->pm.lock);
#endif /* MALI_USE_CSF */
}
#if MALI_USE_CSF && defined(KBASE_PM_RUNTIME)
int kbase_pm_force_mcu_wakeup_after_sleep(struct kbase_device *kbdev)
{
unsigned long flags;
@@ -1108,17 +943,15 @@ static int pm_handle_mcu_sleep_on_runtime_suspend(struct kbase_device *kbdev)
lockdep_assert_held(&kbdev->csf.scheduler.lock);
lockdep_assert_held(&kbdev->pm.lock);
#ifdef CONFIG_MALI_VALHALL_DEBUG
/* In case of no active CSG on slot, powering up L2 could be skipped and
* proceed directly to suspend GPU.
* ToDo: firmware has to be reloaded after wake-up as no halt command
* has been sent when GPU was put to sleep mode.
*/
if (!kbase_csf_scheduler_get_nr_active_csgs(kbdev))
if (IS_ENABLED(CONFIG_MALI_VALHALL_DEBUG) && !kbase_csf_scheduler_get_nr_active_csgs(kbdev))
dev_info(
kbdev->dev,
"No active CSGs. Can skip the power up of L2 and go for suspension directly");
#endif
ret = kbase_pm_force_mcu_wakeup_after_sleep(kbdev);
if (ret) {
@@ -1300,5 +1133,3 @@ out:
return ret;
}
#endif

View File

@@ -1,7 +1,7 @@
// SPDX-License-Identifier: GPL-2.0 WITH Linux-syscall-note
/*
*
* (C) COPYRIGHT 2013-2024 ARM Limited. All rights reserved.
* (C) COPYRIGHT 2013-2025 ARM Limited. All rights reserved.
*
* This program is free software and is provided to you under the terms of the
* GNU General Public License version 2 as published by the Free Software
@@ -27,19 +27,37 @@
#include <mali_kbase_pm.h>
#include <backend/gpu/mali_kbase_pm_internal.h>
#include <backend/gpu/mali_kbase_model_linux.h>
#include <mali_kbase_dummy_job_wa.h>
int kbase_pm_ca_init(struct kbase_device *kbdev)
{
#ifdef CONFIG_MALI_VALHALL_DEVFREQ
static void pm_init_cores_enabled_mask(struct kbase_device *kbdev)
{
struct kbase_pm_backend_data *pm_backend = &kbdev->pm.backend;
if (kbdev->current_core_mask)
pm_backend->ca_cores_enabled = kbdev->current_core_mask;
else
pm_backend->ca_cores_enabled = kbdev->gpu_props.shader_present;
}
static void pm_init_gov_cores_enabled_mask(struct kbase_device *kbdev)
{
struct kbase_pm_backend_data *pm_backend = &kbdev->pm.backend;
if (kbdev->current_core_mask)
pm_backend->ca_gov_cores_enabled = kbdev->current_core_mask;
else
pm_backend->ca_gov_cores_enabled = kbdev->gpu_props.shader_present;
}
#endif
int kbase_pm_ca_init(struct kbase_device *kbdev)
{
#ifdef CONFIG_MALI_VALHALL_DEVFREQ
if (kbase_hw_has_feature(kbdev, KBASE_HW_FEATURE_GOV_CORE_MASK_SUPPORT))
pm_init_gov_cores_enabled_mask(kbdev);
pm_init_cores_enabled_mask(kbdev);
#endif
return 0;
}
@@ -48,61 +66,119 @@ void kbase_pm_ca_term(struct kbase_device *kbdev)
CSTD_UNUSED(kbdev);
}
#ifdef CONFIG_MALI_VALHALL_DEVFREQ
void kbase_devfreq_set_core_mask(struct kbase_device *kbdev, u64 core_mask)
void kbase_pm_ca_set_gov_core_mask_nolock(struct kbase_device *kbdev, enum mask_type core_mask_type,
u64 core_mask)
{
struct kbase_pm_backend_data *pm_backend = &kbdev->pm.backend;
unsigned long flags;
#if MALI_USE_CSF
u64 old_core_mask = 0;
bool mmu_sync_needed = false;
if (!IS_ENABLED(CONFIG_MALI_VALHALL_NO_MALI) &&
kbase_hw_has_issue(kbdev, KBASE_HW_ISSUE_GPU2019_3901)) {
mmu_sync_needed = true;
down_write(&kbdev->csf.mmu_sync_sem);
if (!kbase_hw_has_feature(kbdev, KBASE_HW_FEATURE_GOV_CORE_MASK_SUPPORT)) {
dev_warn(
kbdev->dev,
"This function requires Kbase to have access to GOV_CORE_MASK register, cannot proceed\n");
return;
}
lockdep_assert_held(&kbdev->hwaccess_lock);
/** A value of ZERO means disabling.
* When disabling, store the last used mask for re-enabling
*/
if (core_mask_type == SYSFS_COREMASK) {
if (core_mask != 0)
pm_backend->ca_gov_cores_enabled = core_mask;
else
#ifdef CONFIG_MALI_VALHALL_DEVFREQ
pm_backend->ca_gov_cores_enabled = kbdev->current_core_mask;
#else
pm_backend->ca_gov_cores_enabled =
kbdev->gpu_props.curr_config.shader_present;
#endif
}
#ifdef CONFIG_MALI_VALHALL_DEVFREQ
/* sysfs core mask takes priority over OPP mask when sysfs core mask is set */
else if (core_mask_type == DEVFREQ_COREMASK) {
if (core_mask == 0) {
dev_warn(kbdev->dev,
"Required core_mask cannot be zero when sysfs usage disabled\n");
return;
}
/* if sysfs non-zero then no need to re-write value */
if (kbdev->pm.sysfs_gov_core_mask)
return;
pm_backend->ca_gov_cores_enabled = core_mask;
}
#endif
spin_lock_irqsave(&kbdev->hwaccess_lock, flags);
/** after all checks, write the to GOV_CORE_MASK register if GPU powered,
* otherwise value will be applied on next reboot.
*/
if (kbase_io_is_gpu_powered(kbdev))
kbase_reg_write64(kbdev, GPU_GOVERNOR_ENUM(GOV_CORE_MASK),
pm_backend->ca_gov_cores_enabled);
}
#if MALI_USE_CSF
if (kbase_hw_has_feature(kbdev, KBASE_HW_FEATURE_GOV_CORE_MASK_SUPPORT)) {
if (kbase_io_is_gpu_powered(kbdev)) {
kbase_reg_write64(kbdev, GPU_GOVERNOR_ENUM(GOV_CORE_MASK),
core_mask & kbdev->pm.debug_core_mask);
}
void kbase_pm_ca_set_gov_core_mask(struct kbase_device *kbdev, enum mask_type core_mask_type,
u64 core_mask)
{
unsigned long flags;
goto unlock;
if (!kbase_hw_has_feature(kbdev, KBASE_HW_FEATURE_GOV_CORE_MASK_SUPPORT)) {
dev_warn(
kbdev->dev,
"This function requires Kbase to have access to GOV_CORE_MASK register, cannot proceed\n");
return;
}
spin_lock_irqsave(&kbdev->hwaccess_lock, flags);
kbase_pm_ca_set_gov_core_mask_nolock(kbdev, core_mask_type, core_mask);
spin_unlock_irqrestore(&kbdev->hwaccess_lock, flags);
}
#ifdef CONFIG_MALI_VALHALL_DEVFREQ
static int set_core_mask_gov(struct kbase_device *kbdev, u64 core_mask)
{
if (!kbase_hw_has_feature(kbdev, KBASE_HW_FEATURE_GOV_CORE_MASK_SUPPORT)) {
dev_warn(
kbdev->dev,
"This function requires Kbase to have access to GOV_CORE_MASK register, cannot proceed\n");
return -EIO;
}
/* Requires a validity check to ensure we don't try to set cores we do not have */
if ((core_mask & kbdev->gpu_props.shader_present) != core_mask) {
dev_err(kbdev->dev,
"core_mask (%llu) must be a subset of the shader present (%llu)", core_mask,
kbdev->gpu_props.shader_present);
return -EINVAL;
}
kbase_pm_ca_set_gov_core_mask(kbdev, DEVFREQ_COREMASK, core_mask);
return 0;
}
static int set_core_mask_legacy(struct kbase_device *kbdev, u64 core_mask)
{
struct kbase_pm_backend_data *pm_backend = &kbdev->pm.backend;
u64 old_core_mask = 0;
unsigned long flags;
spin_lock_irqsave(&kbdev->hwaccess_lock, flags);
if (!(core_mask & kbdev->pm.debug_core_mask)) {
dev_err(kbdev->dev,
"OPP core mask 0x%llX does not intersect with debug mask 0x%llX\n",
"OPP core mask 0x%llX does not intersect with sysfs debug mask 0x%llX\n",
core_mask, kbdev->pm.debug_core_mask);
goto unlock;
spin_unlock_irqrestore(&kbdev->hwaccess_lock, flags);
return -EINVAL;
}
old_core_mask = pm_backend->ca_cores_enabled;
#else
if (!(core_mask & kbdev->pm.debug_core_mask_all)) {
dev_err(kbdev->dev,
"OPP core mask 0x%llX does not intersect with debug mask 0x%llX\n",
core_mask, kbdev->pm.debug_core_mask_all);
goto unlock;
}
if (kbase_dummy_job_wa_enabled(kbdev)) {
dev_err_once(kbdev->dev,
"Dynamic core scaling not supported as dummy job WA is enabled");
goto unlock;
}
#endif /* MALI_USE_CSF */
pm_backend->ca_cores_enabled = core_mask;
kbase_pm_update_state(kbdev);
spin_unlock_irqrestore(&kbdev->hwaccess_lock, flags);
#if MALI_USE_CSF
/* Check if old_core_mask contained the undesired cores and wait
* for those cores to get powered down
*/
@@ -114,33 +190,51 @@ void kbase_devfreq_set_core_mask(struct kbase_device *kbdev, u64 core_mask)
}
}
return 0;
}
void kbase_devfreq_set_core_mask(struct kbase_device *kbdev, u64 core_mask)
{
bool mmu_sync_needed = false;
int err;
if (!IS_ENABLED(CONFIG_MALI_VALHALL_NO_MALI) &&
kbase_hw_has_issue(kbdev, KBASE_HW_ISSUE_GPU2019_3901)) {
mmu_sync_needed = true;
down_write(&kbdev->csf.mmu_sync_sem);
}
err = kbase_hw_has_feature(kbdev, KBASE_HW_FEATURE_GOV_CORE_MASK_SUPPORT) ?
set_core_mask_gov(kbdev, core_mask) :
set_core_mask_legacy(kbdev, core_mask);
if (mmu_sync_needed)
up_write(&kbdev->csf.mmu_sync_sem);
#endif
dev_dbg(kbdev->dev, "Devfreq policy : new core mask=%llX\n", pm_backend->ca_cores_enabled);
return;
unlock:
spin_unlock_irqrestore(&kbdev->hwaccess_lock, flags);
#if MALI_USE_CSF
if (mmu_sync_needed)
up_write(&kbdev->csf.mmu_sync_sem);
#endif
if (!err)
dev_dbg(kbdev->dev, "Devfreq policy : new core mask=%llX\n", core_mask);
}
KBASE_EXPORT_TEST_API(kbase_devfreq_set_core_mask);
#endif
u64 kbase_pm_ca_get_debug_core_mask(struct kbase_device *kbdev)
{
#if MALI_USE_CSF
return kbdev->pm.debug_core_mask;
#else
return kbdev->pm.debug_core_mask_all;
#endif
}
KBASE_EXPORT_TEST_API(kbase_pm_ca_get_debug_core_mask);
u64 kbase_pm_ca_get_sysfs_gov_core_mask(struct kbase_device *kbdev)
{
if (!kbase_hw_has_feature(kbdev, KBASE_HW_FEATURE_GOV_CORE_MASK_SUPPORT)) {
dev_warn(
kbdev->dev,
"This function requires Kbase to have access to GOV_CORE_MASK register, cannot proceed\n");
return 0;
}
return kbdev->pm.sysfs_gov_core_mask;
}
KBASE_EXPORT_TEST_API(kbase_pm_ca_get_sysfs_gov_core_mask);
u64 kbase_pm_ca_get_core_mask(struct kbase_device *kbdev)
{
u64 debug_core_mask = kbase_pm_ca_get_debug_core_mask(kbdev);
@@ -160,18 +254,23 @@ u64 kbase_pm_ca_get_core_mask(struct kbase_device *kbdev)
return kbdev->gpu_props.curr_config.shader_present & debug_core_mask;
#endif
}
KBASE_EXPORT_TEST_API(kbase_pm_ca_get_core_mask);
u64 kbase_pm_ca_get_gov_core_mask(struct kbase_device *kbdev)
{
lockdep_assert_held(&kbdev->hwaccess_lock);
return kbdev->pm.backend.ca_gov_cores_enabled;
}
KBASE_EXPORT_TEST_API(kbase_pm_ca_get_gov_core_mask);
u64 kbase_pm_ca_get_instr_core_mask(struct kbase_device *kbdev)
{
lockdep_assert_held(&kbdev->hwaccess_lock);
#if IS_ENABLED(CONFIG_MALI_VALHALL_NO_MALI)
return (((1ull) << KBASE_DUMMY_MODEL_MAX_SHADER_CORES) - 1);
#elif MALI_USE_CSF
return kbase_pm_get_ready_cores(kbdev, KBASE_PM_CORE_SHADER);
#else
return kbdev->pm.backend.pm_shaders_core_mask;
return kbase_pm_get_ready_cores(kbdev, KBASE_PM_CORE_SHADER);
#endif
}

View File

@@ -1,7 +1,7 @@
/* SPDX-License-Identifier: GPL-2.0 WITH Linux-syscall-note */
/*
*
* (C) COPYRIGHT 2011-2023 ARM Limited. All rights reserved.
* (C) COPYRIGHT 2011-2024 ARM Limited. All rights reserved.
*
* This program is free software and is provided to you under the terms of the
* GNU General Public License version 2 as published by the Free Software
@@ -68,6 +68,26 @@ u64 kbase_pm_ca_get_core_mask(struct kbase_device *kbdev);
*/
u64 kbase_pm_ca_get_debug_core_mask(struct kbase_device *kbdev);
/**
* kbase_pm_ca_get_sysfs_gov_core_mask - Get the value sysfs has requested to set shader core mask
*
* @kbdev: The kbase device structure for the device (must be a valid pointer)
*
* This is used only when Kbase has access to the GOV_CORE_MASK register.
* Return: The bit mask of user-selected cores
*/
u64 kbase_pm_ca_get_sysfs_gov_core_mask(struct kbase_device *kbdev);
/**
* kbase_pm_ca_get_gov_core_mask - Get currently available gov core mask.
*
* @kbdev: The kbase device structure for the device (must be a valid pointer)
*
* This is used only when Kbase has access to the GOV_CORE_MASK register.
* Return: a mask of the currently available shader cores.
*/
u64 kbase_pm_ca_get_gov_core_mask(struct kbase_device *kbdev);
/**
* kbase_pm_ca_update_core_status - Update core status
*

View File

@@ -1,7 +1,7 @@
// SPDX-License-Identifier: GPL-2.0 WITH Linux-syscall-note
/*
*
* (C) COPYRIGHT 2012-2023 ARM Limited. All rights reserved.
* (C) COPYRIGHT 2012-2024 ARM Limited. All rights reserved.
*
* This program is free software and is provided to you under the terms of the
* GNU General Public License version 2 as published by the Free Software
@@ -59,9 +59,7 @@ const struct kbase_pm_policy kbase_pm_coarse_demand_policy_ops = {
coarse_demand_get_core_active, /* get_core_active */
NULL, /* handle_event */
KBASE_PM_POLICY_ID_COARSE_DEMAND, /* id */
#if MALI_USE_CSF
COARSE_ON_DEMAND_PM_SCHED_FLAGS, /* pm_sched_flags */
#endif
};
KBASE_EXPORT_TEST_API(kbase_pm_coarse_demand_policy_ops);

View File

@@ -31,10 +31,6 @@
#include <hw_access/mali_kbase_hw_access_regmap.h>
#if defined(CONFIG_PM_RUNTIME) || defined(CONFIG_PM)
#define KBASE_PM_RUNTIME 1
#endif
/* Forward definition - see mali_kbase.h */
struct kbase_device;
struct kbase_jd_atom;
@@ -61,7 +57,6 @@ struct kbase_jd_atom;
*
* They specify which type of core should be acted on.
*/
#if MALI_USE_CSF
enum kbase_pm_core_type {
KBASE_PM_CORE_L2 = HOST_POWER_ENUM(L2_PRESENT),
KBASE_PM_CORE_SHADER = HOST_POWER_ENUM(SHADER_PRESENT),
@@ -76,14 +71,6 @@ enum kbase_pm_core_type {
*/
KBASE_PM_CORE_BASE = HOST_POWER_ENUM(BASE_PRESENT)
};
#else
enum kbase_pm_core_type {
KBASE_PM_CORE_L2 = GPU_CONTROL_ENUM(L2_PRESENT),
KBASE_PM_CORE_SHADER = GPU_CONTROL_ENUM(SHADER_PRESENT),
KBASE_PM_CORE_TILER = GPU_CONTROL_ENUM(TILER_PRESENT),
KBASE_PM_CORE_STACK = GPU_CONTROL_ENUM(STACK_PRESENT)
};
#endif
/*
* enum kbase_l2_core_state - The states used for the L2 cache & tiler power
@@ -95,7 +82,6 @@ enum kbase_l2_core_state {
#undef KBASEP_L2_STATE
};
#if MALI_USE_CSF
/*
* enum kbase_mcu_state - The states used for the MCU state machine.
*/
@@ -104,7 +90,6 @@ enum kbase_mcu_state {
#include "mali_kbase_pm_mcu_states.h"
#undef KBASEP_MCU_STATE
};
#endif
/*
* enum kbase_shader_core_state - The states used for the shaders' state machine.
@@ -163,22 +148,11 @@ enum kbase_pm_runtime_suspend_abort_reason {
* time_period_start timestamp, measured in units of 256ns.
* @time_in_protm: The amount of time the GPU has spent in protected mode since
* the time_period_start timestamp, measured in units of 256ns.
* @busy_cl: the amount of time the GPU was busy executing CL jobs. Note that
* if two CL jobs were active for 256ns, this value would be updated
* with 2 (2x256ns).
* @busy_gl: the amount of time the GPU was busy executing GL jobs. Note that
* if two GL jobs were active for 256ns, this value would be updated
* with 2 (2x256ns).
*/
struct kbasep_pm_metrics {
u32 time_busy;
u32 time_idle;
#if MALI_USE_CSF
u32 time_in_protm;
#else
u32 busy_cl[2];
u32 busy_gl;
#endif
};
/**
@@ -189,11 +163,6 @@ struct kbasep_pm_metrics {
* kbase_ipa_control client
* @skip_gpu_active_sanity_check: Decide whether to skip GPU_ACTIVE sanity
* check in DVFS utilisation calculation
* @gpu_active: true when the GPU is executing jobs. false when
* not. Updated when the job scheduler informs us a job in submitted
* or removed from a GPU slot.
* @active_cl_ctx: number of CL jobs active on the GPU. Array is per-device.
* @active_gl_ctx: number of GL jobs active on the GPU. Array is per-slot.
* @lock: spinlock protecting the kbasep_pm_metrics_state structure
* @platform_data: pointer to data controlled by platform specific code
* @kbdev: pointer to kbase device for which metrics are collected
@@ -209,14 +178,8 @@ struct kbasep_pm_metrics {
*/
struct kbasep_pm_metrics_state {
ktime_t time_period_start;
#if MALI_USE_CSF
void *ipa_control_client;
bool skip_gpu_active_sanity_check;
#else
bool gpu_active;
u32 active_cl_ctx[2];
u32 active_gl_ctx[3];
#endif
spinlock_t lock;
void *platform_data;
@@ -336,6 +299,8 @@ union kbase_pm_policy_data {
* called previously.
* See &struct kbase_pm_callback_conf.
* @ca_cores_enabled: Cores that are currently available
* @ca_gov_cores_enabled: Final value used for setting GOV_CORE_MASK register.
* Depends on sysfs-core-mask and devfreq-core-mask.
* @apply_hw_issue_TITANHW_2938_wa: Indicates if the workaround for KBASE_HW_ISSUE_TITANHW_2938
* needs to be applied when unmapping memory from GPU.
* @mcu_state: The current state of the micro-control unit, only applicable
@@ -421,20 +386,6 @@ union kbase_pm_policy_data {
* re-enabled whilst the flag is set.
* @in_reset: True if a GPU is resetting and normal power manager operation is
* suspended
* @partial_shaderoff: True if we want to partial power off shader cores,
* it indicates a partial shader core off case,
* do some special operation for such case like flush
* L2 cache because of GPU2017-861
* @protected_entry_transition_override : True if GPU reset is being used
* before entering the protected mode and so
* the reset handling behaviour is being
* overridden.
* @protected_transition_override : True if a protected mode transition is in
* progress and is overriding power manager
* behaviour.
* @protected_l2_override : Non-zero if the L2 cache is required during a
* protected mode transition. Has no effect if not
* transitioning.
* @hwcnt_desired: True if we want GPU hardware counters to be enabled.
* @hwcnt_disabled: True if GPU hardware counters are not enabled.
* @hwcnt_disable_work: Work item to disable GPU hardware counters, used if
@@ -456,6 +407,7 @@ union kbase_pm_policy_data {
* @gpu_clock_control_work: work item to set GPU clock during L2 power cycle
* using gpu_clock_control
* @reset_in_progress: Set if reset is ongoing, otherwise set to 0
* @gpu_lost_pending: Set if GPU_LOST is detected and its handling is pending.
*
* This structure contains data for the power management framework. There is one
* instance of this structure per device in the system.
@@ -508,16 +460,14 @@ struct kbase_pm_backend_data {
void (*callback_power_runtime_gpu_active)(struct kbase_device *kbdev);
u64 ca_cores_enabled;
u64 ca_gov_cores_enabled;
#if MALI_USE_CSF
bool apply_hw_issue_TITANHW_2938_wa;
enum kbase_mcu_state mcu_state;
#endif
enum kbase_l2_core_state l2_state;
enum kbase_shader_core_state shaders_state;
u64 shaders_avail;
u64 shaders_desired_mask;
#if MALI_USE_CSF
bool mcu_desired;
bool policy_change_clamp_state_to_off;
bool waiting_for_mmu_fault_handling;
@@ -525,8 +475,6 @@ struct kbase_pm_backend_data {
struct mutex policy_change_lock;
struct workqueue_struct *core_idle_wq;
struct work_struct core_idle_work;
#ifdef KBASE_PM_RUNTIME
unsigned long gpu_sleep_allowed;
bool gpu_sleep_mode_active;
bool exit_gpu_sleep_mode;
@@ -534,7 +482,6 @@ struct kbase_pm_backend_data {
bool gpu_wakeup_override;
bool db_mirror_interrupt_enabled;
enum kbase_pm_runtime_suspend_abort_reason runtime_suspend_abort_reason;
#endif
/**
* @has_host_pwr_iface: GPU supports the host power control interface.
@@ -547,21 +494,12 @@ struct kbase_pm_backend_data {
*/
bool pwr_cntl_delegated;
bool l2_force_off_after_mcu_halt;
#endif
bool l2_desired;
bool l2_always_on;
bool shaders_desired;
bool in_reset;
#if !MALI_USE_CSF
bool partial_shaderoff;
bool protected_entry_transition_override;
bool protected_transition_override;
int protected_l2_override;
#endif
bool hwcnt_desired;
bool hwcnt_disabled;
struct work_struct hwcnt_disable_work;
@@ -573,9 +511,10 @@ struct kbase_pm_backend_data {
struct work_struct gpu_clock_control_work;
atomic_t reset_in_progress;
bool gpu_lost_pending;
};
#if MALI_USE_CSF
/* CSF PM flag, signaling that the MCU shader Core should be kept on */
#define CSF_DYNAMIC_PM_CORE_KEEP_ON (1 << 0)
/* CSF PM flag, signaling no scheduler suspension on idle groups */
@@ -591,7 +530,6 @@ struct kbase_pm_backend_data {
#if !MALI_CUSTOMER_RELEASE
#define ALWAYS_ON_DEMAND_PM_SCHED_FLAGS (CSF_DYNAMIC_PM_SCHED_IGNORE_IDLE)
#endif
#endif
/* List of policy IDs */
enum kbase_pm_policy_id {
@@ -714,14 +652,12 @@ struct kbase_pm_policy {
enum kbase_pm_policy_id id;
#if MALI_USE_CSF
/* Policy associated with CSF PM scheduling operational flags.
* There are pre-defined required flags exist for each of the
* ARM released policies, such as 'always_on', 'coarse_demand'
* and etc.
*/
unsigned int pm_sched_flags;
#endif
};
#endif /* _KBASE_PM_HWACCESS_DEFS_H_ */

File diff suppressed because it is too large Load Diff

View File

@@ -31,6 +31,19 @@
#include "backend/gpu/mali_kbase_pm_ca.h"
#include "mali_kbase_pm_policy.h"
/**
* enum mask_type - used to determine which mask is being updated
*
* @SYSFS_COREMASK: core mask requested via sysfs
* @DEVFREQ_COREMASK: core mask requested via devfreq
*/
enum mask_type {
SYSFS_COREMASK,
#ifdef CONFIG_MALI_VALHALL_DEVFREQ
DEVFREQ_COREMASK
#endif
};
/**
* kbase_pm_dev_idle - The GPU is idle.
*
@@ -200,7 +213,6 @@ int kbase_pm_init_hw(struct kbase_device *kbdev, unsigned int flags);
*/
void kbase_pm_reset_done(struct kbase_device *kbdev);
#if MALI_USE_CSF
/**
* kbase_pm_wait_for_desired_state - Wait for the desired power state to be
* reached
@@ -222,30 +234,6 @@ void kbase_pm_reset_done(struct kbase_device *kbdev);
* Return: 0 on success, or -ETIMEDOUT code on timeout error.
*/
int kbase_pm_wait_for_desired_state(struct kbase_device *kbdev);
#else
/**
* kbase_pm_wait_for_desired_state - Wait for the desired power state to be
* reached
* @kbdev: The kbase device structure for the device (must be a valid pointer)
*
* Wait for the L2 and shader power state machines to reach the states
* corresponding to the values of 'l2_desired' and 'shaders_desired'.
*
* The usual use-case for this is to ensure cores are 'READY' after performing
* a GPU Reset.
*
* Unlike kbase_pm_update_state(), the caller must not hold hwaccess_lock,
* because this function will take that lock itself.
*
* NOTE: This may not wait until the correct state is reached if there is a
* power off in progress. To correctly wait for the desired state the caller
* must ensure that this is not the case by, for example, calling
* kbase_pm_wait_for_poweroff_work_complete()
*
* Return: 0 on success, or -ETIMEDOUT error code on timeout error.
*/
int kbase_pm_wait_for_desired_state(struct kbase_device *kbdev);
#endif
/**
* kbase_pm_killable_wait_for_desired_state - Wait for the desired power state to be
@@ -279,7 +267,6 @@ int kbase_pm_killable_wait_for_desired_state(struct kbase_device *kbdev);
*/
int kbase_pm_wait_for_l2_powered(struct kbase_device *kbdev);
#if MALI_USE_CSF
/**
* kbase_pm_wait_for_cores_down_scale - Wait for the downscaling of shader cores
*
@@ -308,7 +295,6 @@ int kbase_pm_wait_for_l2_powered(struct kbase_device *kbdev);
* Return: 0 on success, error code on error or remaining jiffies on timeout.
*/
int kbase_pm_wait_for_cores_down_scale(struct kbase_device *kbdev);
#endif
/**
* kbase_pm_update_dynamic_cores_onoff - Update the L2 and shader power state
@@ -534,14 +520,11 @@ void kbase_pm_runtime_term(struct kbase_device *kbdev);
* @kbdev: The kbase device structure for the device (must be a valid pointer)
*
* Enables access to the GPU registers before power management has powered up
* the GPU with kbase_pm_powerup().
* the GPU.
*
* This results in the power management callbacks provided in the driver
* configuration to get called to turn on power and/or clocks to the GPU. See
* kbase_pm_callback_conf.
*
* This should only be used before power management is powered up with
* kbase_pm_powerup()
*/
void kbase_pm_register_access_enable(struct kbase_device *kbdev);
@@ -555,9 +538,6 @@ void kbase_pm_register_access_enable(struct kbase_device *kbdev);
* This results in the power management callbacks provided in the driver
* configuration to get called to turn off power and/or clocks to the GPU. See
* kbase_pm_callback_conf
*
* This should only be used before power management is powered up with
* kbase_pm_powerup()
*/
void kbase_pm_register_access_disable(struct kbase_device *kbdev);
@@ -606,7 +586,6 @@ void kbase_pm_get_dvfs_metrics(struct kbase_device *kbdev, struct kbasep_pm_metr
#ifdef CONFIG_MALI_VALHALL_DVFS
#if MALI_USE_CSF
/**
* kbase_platform_dvfs_event - Report utilisation to DVFS code for CSF GPU
*
@@ -620,24 +599,6 @@ void kbase_pm_get_dvfs_metrics(struct kbase_device *kbdev, struct kbasep_pm_metr
* Return: Returns 0 on failure and non zero on success.
*/
int kbase_platform_dvfs_event(struct kbase_device *kbdev, u32 utilisation);
#else
/**
* kbase_platform_dvfs_event - Report utilisation to DVFS code for JM GPU
*
* @kbdev: The kbase device structure for the device (must be a
* valid pointer)
* @utilisation: The current calculated utilisation by the metrics system.
* @util_gl_share: The current calculated gl share of utilisation.
* @util_cl_share: The current calculated cl share of utilisation per core
* group.
* Function provided by platform specific code when DVFS is enabled to allow
* the power management metrics system to report utilisation.
*
* Return: Returns 0 on failure and non zero on success.
*/
int kbase_platform_dvfs_event(struct kbase_device *kbdev, u32 utilisation, u32 util_gl_share,
u32 util_cl_share[2]);
#endif
#endif /* CONFIG_MALI_VALHALL_DVFS */
@@ -672,6 +633,28 @@ void kbase_pm_cache_snoop_enable(struct kbase_device *kbdev);
*/
void kbase_pm_cache_snoop_disable(struct kbase_device *kbdev);
/**
* kbase_pm_ca_set_gov_core_mask - Set governor core mask
* @kbdev: Device pointer.
* @core_mask_type: which mask is being used to update register.
* @core_mask: New core mask.
*
* This function is used to change the available core mask as defined via either sysfs or devfreq.
*/
void kbase_pm_ca_set_gov_core_mask(struct kbase_device *kbdev, enum mask_type core_mask_type,
u64 core_mask);
/**
* kbase_pm_ca_set_gov_core_mask_nolock - Set governor core mask with lock already taken
* @kbdev: Device pointer.
* @core_mask_type: which mask is being used to update register.
* @core_mask: New core mask.
*
* This function is used to change the available core mask as defined via either sysfs or devfreq.
*/
void kbase_pm_ca_set_gov_core_mask_nolock(struct kbase_device *kbdev, enum mask_type core_mask_type,
u64 core_mask);
#ifdef CONFIG_MALI_VALHALL_DEVFREQ
/**
* kbase_devfreq_set_core_mask - Set devfreq core mask
@@ -704,81 +687,6 @@ void kbase_pm_reset_start_locked(struct kbase_device *kbdev);
*/
void kbase_pm_reset_complete(struct kbase_device *kbdev);
#if !MALI_USE_CSF
/**
* kbase_pm_protected_override_enable - Enable the protected mode override
* @kbdev: Device pointer
*
* When the protected mode override is enabled, all shader cores are requested
* to power down, and the L2 power state can be controlled by
* kbase_pm_protected_l2_override().
*
* Caller must hold hwaccess_lock.
*/
void kbase_pm_protected_override_enable(struct kbase_device *kbdev);
/**
* kbase_pm_protected_override_disable - Disable the protected mode override
* @kbdev: Device pointer
*
* Caller must hold hwaccess_lock.
*/
void kbase_pm_protected_override_disable(struct kbase_device *kbdev);
/**
* kbase_pm_protected_l2_override - Control the protected mode L2 override
* @kbdev: Device pointer
* @override: true to enable the override, false to disable
*
* When the driver is transitioning in or out of protected mode, the L2 cache is
* forced to power off. This can be overridden to force the L2 cache to power
* on. This is required to change coherency settings on some GPUs.
*/
void kbase_pm_protected_l2_override(struct kbase_device *kbdev, bool override);
/**
* kbase_pm_protected_entry_override_enable - Enable the protected mode entry
* override
* @kbdev: Device pointer
*
* Initiate a GPU reset and enable the protected mode entry override flag if
* l2_always_on WA is enabled and platform is fully coherent. If the GPU
* reset is already ongoing then protected mode entry override flag will not
* be enabled and function will have to be called again.
*
* When protected mode entry override flag is enabled to power down L2 via GPU
* reset, the GPU reset handling behavior gets changed. For example call to
* kbase_backend_reset() is skipped, Hw counters are not re-enabled and L2
* isn't powered up again post reset.
* This is needed only as a workaround for a Hw issue where explicit power down
* of L2 causes a glitch. For entering protected mode on fully coherent
* platforms L2 needs to be powered down to switch to IO coherency mode, so to
* avoid the glitch GPU reset is used to power down L2. Hence, this function
* does nothing on systems where the glitch issue isn't present.
*
* Caller must hold hwaccess_lock. Should be only called during the transition
* to enter protected mode.
*
* Return: -EAGAIN if a GPU reset was required for the glitch workaround but
* was already ongoing, otherwise 0.
*/
int kbase_pm_protected_entry_override_enable(struct kbase_device *kbdev);
/**
* kbase_pm_protected_entry_override_disable - Disable the protected mode entry
* override
* @kbdev: Device pointer
*
* This shall be called once L2 has powered down and switch to IO coherency
* mode has been made. As with kbase_pm_protected_entry_override_enable(),
* this function does nothing on systems where the glitch issue isn't present.
*
* Caller must hold hwaccess_lock. Should be only called during the transition
* to enter protected mode.
*/
void kbase_pm_protected_entry_override_disable(struct kbase_device *kbdev);
#endif
/* If true, the driver should explicitly control corestack power management,
* instead of relying on the Power Domain Controller.
*/
@@ -795,7 +703,6 @@ extern bool corestack_driver_control;
*/
bool kbase_pm_is_l2_desired(struct kbase_device *kbdev);
#if MALI_USE_CSF
/**
* kbase_pm_is_mcu_desired - Check whether MCU is desired
*
@@ -821,8 +728,6 @@ bool kbase_pm_is_mcu_desired(struct kbase_device *kbdev);
*/
bool kbase_pm_is_mcu_inactive(struct kbase_device *kbdev, enum kbase_mcu_state state);
#ifdef KBASE_PM_RUNTIME
/**
* kbase_pm_enable_mcu_db_notification - Enable the Doorbell notification on
* MCU side
@@ -834,8 +739,6 @@ bool kbase_pm_is_mcu_inactive(struct kbase_device *kbdev, enum kbase_mcu_state s
*/
void kbase_pm_enable_mcu_db_notification(struct kbase_device *kbdev);
#endif /* KBASE_PM_RUNTIME */
/**
* kbase_pm_idle_groups_sched_suspendable - Check whether the scheduler can be
* suspended to low power state when all
@@ -907,8 +810,6 @@ static inline bool kbase_pm_mcu_is_in_desired_state(struct kbase_device *kbdev)
return in_desired_state;
}
#endif
/**
* kbase_pm_l2_is_in_desired_state - Check if L2 is in stable ON/OFF state.
*
@@ -937,9 +838,6 @@ static inline bool kbase_pm_l2_is_in_desired_state(struct kbase_device *kbdev)
*/
static inline void kbase_pm_lock(struct kbase_device *kbdev)
{
#if !MALI_USE_CSF
mutex_lock(&kbdev->js_data.runpool_mutex);
#endif /* !MALI_USE_CSF */
mutex_lock(&kbdev->pm.lock);
}
@@ -951,12 +849,8 @@ static inline void kbase_pm_lock(struct kbase_device *kbdev)
static inline void kbase_pm_unlock(struct kbase_device *kbdev)
{
mutex_unlock(&kbdev->pm.lock);
#if !MALI_USE_CSF
mutex_unlock(&kbdev->js_data.runpool_mutex);
#endif /* !MALI_USE_CSF */
}
#if MALI_USE_CSF && defined(KBASE_PM_RUNTIME)
/**
* kbase_pm_gpu_sleep_allowed - Check if the GPU is allowed to be put in sleep
*
@@ -978,8 +872,10 @@ static inline bool kbase_pm_gpu_sleep_allowed(struct kbase_device *kbdev)
* A high positive value of autosuspend_delay can be used to keep the
* GPU in sleep state for a long time.
*/
#if IS_ENABLED(CONFIG_PM)
if (unlikely(kbdev->dev->power.autosuspend_delay <= 0))
return false;
#endif
return test_bit(KBASE_GPU_SUPPORTS_GPU_SLEEP, &kbdev->pm.backend.gpu_sleep_allowed);
}
@@ -997,8 +893,10 @@ static inline bool kbase_pm_gpu_sleep_allowed(struct kbase_device *kbdev)
*/
static inline bool kbase_pm_fw_sleep_on_idle_allowed(struct kbase_device *kbdev)
{
#if IS_ENABLED(CONFIG_PM)
if (unlikely(kbdev->dev->power.autosuspend_delay <= 0))
return false;
#endif
return kbdev->pm.backend.gpu_sleep_allowed == KBASE_GPU_FW_SLEEP_ON_IDLE_ALLOWED;
}
@@ -1049,7 +947,6 @@ static inline void kbase_pm_disable_db_mirror_interrupt(struct kbase_device *kbd
kbdev->pm.backend.db_mirror_interrupt_enabled = false;
}
}
#endif
/**
* kbase_pm_l2_allow_mmu_page_migration - L2 state allows MMU page migration or not
@@ -1074,7 +971,12 @@ static inline bool kbase_pm_l2_allow_mmu_page_migration(struct kbase_device *kbd
return (backend->l2_state != KBASE_L2_PEND_ON && backend->l2_state != KBASE_L2_PEND_OFF);
}
#if MALI_USE_CSF
#if MALI_UNIT_TEST
int delegate_pm_domain_control_to_fw(struct kbase_device *kbdev, u32 pm_domain);
int retract_pm_domain_control_from_fw(struct kbase_device *kbdev, u32 pm_domain);
#endif
/**
* kbase_pm_get_domain_status - get pm domain status for particular endpoint
*
@@ -1089,6 +991,5 @@ static inline bool kbase_pm_l2_allow_mmu_page_migration(struct kbase_device *kbd
*/
int kbase_pm_get_domain_status(struct kbase_device *kbdev, u32 pm_domain, u32 endpoint,
u32 *domain_status);
#endif /* MALI_USE_CSF */
#endif /* _KBASE_BACKEND_PM_INTERNAL_H_ */

View File

@@ -28,17 +28,13 @@
#include <mali_kbase_pm.h>
#include <backend/gpu/mali_kbase_pm_internal.h>
#if MALI_USE_CSF
#include "backend/gpu/mali_kbase_clk_rate_trace_mgr.h"
#include <csf/ipa_control/mali_kbase_csf_ipa_control.h>
#else
#include <backend/gpu/mali_kbase_jm_rb.h>
#endif /* !MALI_USE_CSF */
#include <backend/gpu/mali_kbase_pm_defs.h>
#include <mali_linux_trace.h>
#if defined(CONFIG_MALI_VALHALL_DEVFREQ) || defined(CONFIG_MALI_VALHALL_DVFS) || !MALI_USE_CSF
#if defined(CONFIG_MALI_VALHALL_DEVFREQ) || defined(CONFIG_MALI_VALHALL_DVFS)
/* Shift used for kbasep_pm_metrics_data.time_busy/idle - units of (1 << 8) ns
* This gives a maximum period between samples of 2^(32+8)/100 ns = slightly
* under 11s. Exceeding this will cause overflow
@@ -46,10 +42,8 @@
#define KBASE_PM_TIME_SHIFT 8
#endif
#if MALI_USE_CSF
/* To get the GPU_ACTIVE value in nano seconds unit */
#define GPU_ACTIVE_SCALING_FACTOR ((u64)1E9)
#endif
/*
* Possible state transitions
@@ -101,7 +95,6 @@ static enum hrtimer_restart dvfs_callback(struct hrtimer *timer)
int kbasep_pm_metrics_init(struct kbase_device *kbdev)
{
#if MALI_USE_CSF
struct kbase_ipa_control_perf_counter perf_counter;
int err;
@@ -129,11 +122,6 @@ int kbasep_pm_metrics_init(struct kbase_device *kbdev)
dev_err(kbdev->dev, "Failed to register IPA with kbase_ipa_control: err=%d", err);
return -1;
}
#else
KBASE_DEBUG_ASSERT(kbdev != NULL);
kbdev->pm.backend.metrics.kbdev = kbdev;
kbdev->pm.backend.metrics.time_period_start = ktime_get_raw();
#endif
spin_lock_init(&kbdev->pm.backend.metrics.lock);
#ifdef CONFIG_MALI_VALHALL_DVFS
@@ -144,13 +132,11 @@ int kbasep_pm_metrics_init(struct kbase_device *kbdev)
kbase_pm_metrics_start(kbdev);
#endif /* CONFIG_MALI_VALHALL_DVFS */
#if MALI_USE_CSF
/* The sanity check on the GPU_ACTIVE performance counter
* is skipped for Juno platforms that have timing problems.
*/
kbdev->pm.backend.metrics.skip_gpu_active_sanity_check =
(kbdev->gpu_props.impl_tech >= THREAD_FEATURES_IMPLEMENTATION_TECHNOLOGY_FPGA);
#endif
return 0;
}
@@ -167,11 +153,7 @@ void kbasep_pm_metrics_term(struct kbase_device *kbdev)
hrtimer_cancel(&kbdev->pm.backend.metrics.timer);
#endif /* CONFIG_MALI_VALHALL_DVFS */
#if MALI_USE_CSF
kbase_ipa_control_unregister(kbdev, kbdev->pm.backend.metrics.ipa_control_client);
#else
CSTD_UNUSED(kbdev);
#endif
}
KBASE_EXPORT_TEST_API(kbasep_pm_metrics_term);
@@ -179,7 +161,6 @@ KBASE_EXPORT_TEST_API(kbasep_pm_metrics_term);
/* caller needs to hold kbdev->pm.backend.metrics.lock before calling this
* function
*/
#if MALI_USE_CSF
#if defined(CONFIG_MALI_VALHALL_DEVFREQ) || defined(CONFIG_MALI_VALHALL_DVFS)
static void kbase_pm_get_dvfs_utilisation_calc(struct kbase_device *kbdev)
{
@@ -284,39 +265,6 @@ static void kbase_pm_get_dvfs_utilisation_calc(struct kbase_device *kbdev)
kbdev->pm.backend.metrics.time_period_start = now;
}
#endif /* defined(CONFIG_MALI_VALHALL_DEVFREQ) || defined(CONFIG_MALI_VALHALL_DVFS) */
#else
static void kbase_pm_get_dvfs_utilisation_calc(struct kbase_device *kbdev, ktime_t now)
{
ktime_t diff;
lockdep_assert_held(&kbdev->pm.backend.metrics.lock);
diff = ktime_sub(now, kbdev->pm.backend.metrics.time_period_start);
if (ktime_to_ns(diff) < 0)
return;
if (kbdev->pm.backend.metrics.gpu_active) {
u32 ns_time = (u32)(ktime_to_ns(diff) >> KBASE_PM_TIME_SHIFT);
kbdev->pm.backend.metrics.values.time_busy += ns_time;
if (kbdev->pm.backend.metrics.active_cl_ctx[0])
kbdev->pm.backend.metrics.values.busy_cl[0] += ns_time;
if (kbdev->pm.backend.metrics.active_cl_ctx[1])
kbdev->pm.backend.metrics.values.busy_cl[1] += ns_time;
if (kbdev->pm.backend.metrics.active_gl_ctx[0])
kbdev->pm.backend.metrics.values.busy_gl += ns_time;
if (kbdev->pm.backend.metrics.active_gl_ctx[1])
kbdev->pm.backend.metrics.values.busy_gl += ns_time;
if (kbdev->pm.backend.metrics.active_gl_ctx[2])
kbdev->pm.backend.metrics.values.busy_gl += ns_time;
} else {
kbdev->pm.backend.metrics.values.time_idle +=
(u32)(ktime_to_ns(diff) >> KBASE_PM_TIME_SHIFT);
}
kbdev->pm.backend.metrics.time_period_start = now;
}
#endif /* MALI_USE_CSF */
#if defined(CONFIG_MALI_VALHALL_DEVFREQ) || defined(CONFIG_MALI_VALHALL_DVFS)
void kbase_pm_get_dvfs_metrics(struct kbase_device *kbdev, struct kbasep_pm_metrics *last,
@@ -326,23 +274,13 @@ void kbase_pm_get_dvfs_metrics(struct kbase_device *kbdev, struct kbasep_pm_metr
unsigned long flags;
spin_lock_irqsave(&kbdev->pm.backend.metrics.lock, flags);
#if MALI_USE_CSF
kbase_pm_get_dvfs_utilisation_calc(kbdev);
#else
kbase_pm_get_dvfs_utilisation_calc(kbdev, ktime_get_raw());
#endif
memset(diff, 0, sizeof(*diff));
diff->time_busy = cur->time_busy - last->time_busy;
diff->time_idle = cur->time_idle - last->time_idle;
#if MALI_USE_CSF
diff->time_in_protm = cur->time_in_protm - last->time_in_protm;
#else
diff->busy_cl[0] = cur->busy_cl[0] - last->busy_cl[0];
diff->busy_cl[1] = cur->busy_cl[1] - last->busy_cl[1];
diff->busy_gl = cur->busy_gl - last->busy_gl;
#endif
*last = *cur;
@@ -356,11 +294,6 @@ void kbase_pm_get_dvfs_action(struct kbase_device *kbdev)
{
int utilisation;
struct kbasep_pm_metrics *diff;
#if !MALI_USE_CSF
int busy;
int util_gl_share;
int util_cl_share[2];
#endif
KBASE_DEBUG_ASSERT(kbdev != NULL);
@@ -370,15 +303,6 @@ void kbase_pm_get_dvfs_action(struct kbase_device *kbdev)
utilisation = (100 * diff->time_busy) / max(diff->time_busy + diff->time_idle, 1u);
#if !MALI_USE_CSF
busy = max(diff->busy_gl + diff->busy_cl[0] + diff->busy_cl[1], 1u);
util_gl_share = (100 * diff->busy_gl) / busy;
util_cl_share[0] = (100 * diff->busy_cl[0]) / busy;
util_cl_share[1] = (100 * diff->busy_cl[1]) / busy;
kbase_platform_dvfs_event(kbdev, utilisation, util_gl_share, util_cl_share);
#else
/* Note that, at present, we don't pass protected-mode time to the
* platform here. It's unlikely to be useful, however, as the platform
* probably just cares whether the GPU is busy or not; time in
@@ -386,7 +310,6 @@ void kbase_pm_get_dvfs_action(struct kbase_device *kbdev)
* so we should be good.
*/
kbase_platform_dvfs_event(kbdev, utilisation);
#endif
}
bool kbase_pm_metrics_is_active(struct kbase_device *kbdev)
@@ -421,77 +344,3 @@ void kbase_pm_metrics_stop(struct kbase_device *kbdev)
}
#endif /* CONFIG_MALI_VALHALL_DVFS */
#if !MALI_USE_CSF
/**
* kbase_pm_metrics_active_calc - Update PM active counts based on currently
* running atoms
* @kbdev: Device pointer
*
* The caller must hold kbdev->pm.backend.metrics.lock
*/
static void kbase_pm_metrics_active_calc(struct kbase_device *kbdev)
{
unsigned int js;
lockdep_assert_held(&kbdev->pm.backend.metrics.lock);
kbdev->pm.backend.metrics.active_gl_ctx[0] = 0;
kbdev->pm.backend.metrics.active_gl_ctx[1] = 0;
kbdev->pm.backend.metrics.active_gl_ctx[2] = 0;
kbdev->pm.backend.metrics.active_cl_ctx[0] = 0;
kbdev->pm.backend.metrics.active_cl_ctx[1] = 0;
kbdev->pm.backend.metrics.gpu_active = false;
for (js = 0; js < BASE_JM_MAX_NR_SLOTS; js++) {
struct kbase_jd_atom *katom = kbase_gpu_inspect(kbdev, js, 0);
/* Head atom may have just completed, so if it isn't running
* then try the next atom
*/
if (katom && katom->gpu_rb_state != KBASE_ATOM_GPU_RB_SUBMITTED)
katom = kbase_gpu_inspect(kbdev, js, 1);
if (katom && katom->gpu_rb_state == KBASE_ATOM_GPU_RB_SUBMITTED) {
if (katom->core_req & BASE_JD_REQ_ONLY_COMPUTE) {
u32 device_nr =
(katom->core_req & BASE_JD_REQ_SPECIFIC_COHERENT_GROUP) ?
katom->device_nr :
0;
if (!WARN_ON(device_nr >= 2))
kbdev->pm.backend.metrics.active_cl_ctx[device_nr] = 1;
} else {
kbdev->pm.backend.metrics.active_gl_ctx[js] = 1;
trace_sysgraph(SGR_ACTIVE, 0, js);
}
kbdev->pm.backend.metrics.gpu_active = true;
} else {
trace_sysgraph(SGR_INACTIVE, 0, js);
}
}
}
/* called when job is submitted to or removed from a GPU slot */
void kbase_pm_metrics_update(struct kbase_device *kbdev, ktime_t *timestamp)
{
unsigned long flags;
ktime_t now;
lockdep_assert_held(&kbdev->hwaccess_lock);
spin_lock_irqsave(&kbdev->pm.backend.metrics.lock, flags);
if (!timestamp) {
now = ktime_get_raw();
timestamp = &now;
}
/* Track how much of time has been spent busy or idle. For JM GPUs,
* this also evaluates how long CL and/or GL jobs have been busy for.
*/
kbase_pm_get_dvfs_utilisation_calc(kbdev, *timestamp);
kbase_pm_metrics_active_calc(kbdev);
spin_unlock_irqrestore(&kbdev->pm.backend.metrics.lock, flags);
}
#endif /* !MALI_USE_CSF */

View File

@@ -30,7 +30,7 @@
#include <mali_kbase_reset_gpu.h>
#include <mali_kbase_io.h>
#if MALI_USE_CSF && defined CONFIG_MALI_VALHALL_DEBUG
#if defined CONFIG_MALI_VALHALL_DEBUG
#include <csf/mali_kbase_csf_firmware.h>
#endif
@@ -64,7 +64,7 @@ void kbase_pm_policy_init(struct kbase_device *kbdev)
}
}
#if MALI_USE_CSF && defined(CONFIG_MALI_VALHALL_DEBUG)
#if defined(CONFIG_MALI_VALHALL_DEBUG)
/* Use always_on policy if module param fw_debug=1 is
* passed, to aid firmware debugging.
*/
@@ -74,24 +74,19 @@ void kbase_pm_policy_init(struct kbase_device *kbdev)
default_policy->init(kbdev);
#if MALI_USE_CSF
spin_lock_irqsave(&kbdev->hwaccess_lock, flags);
kbdev->pm.backend.pm_current_policy = default_policy;
kbdev->pm.backend.csf_pm_sched_flags = default_policy->pm_sched_flags;
#ifdef KBASE_PM_RUNTIME
if (kbase_pm_idle_groups_sched_suspendable(kbdev))
clear_bit(KBASE_GPU_IGNORE_IDLE_EVENT, &kbdev->pm.backend.gpu_sleep_allowed);
else
set_bit(KBASE_GPU_IGNORE_IDLE_EVENT, &kbdev->pm.backend.gpu_sleep_allowed);
#endif /* KBASE_PM_RUNTIME */
if (IS_ENABLED(CONFIG_PM)) {
if (kbase_pm_idle_groups_sched_suspendable(kbdev))
clear_bit(KBASE_GPU_IGNORE_IDLE_EVENT,
&kbdev->pm.backend.gpu_sleep_allowed);
else
set_bit(KBASE_GPU_IGNORE_IDLE_EVENT, &kbdev->pm.backend.gpu_sleep_allowed);
}
spin_unlock_irqrestore(&kbdev->hwaccess_lock, flags);
#else
CSTD_UNUSED(flags);
kbdev->pm.backend.pm_current_policy = default_policy;
#endif
}
void kbase_pm_policy_term(struct kbase_device *kbdev)
@@ -123,7 +118,6 @@ void kbase_pm_update_active(struct kbase_device *kbdev)
if (!pm->backend.invoke_poweroff_wait_wq_when_l2_off &&
pm->backend.poweroff_wait_in_progress) {
KBASE_DEBUG_ASSERT(kbase_io_is_gpu_powered(kbdev));
#if MALI_USE_CSF
if (likely(!pm->backend.waiting_for_mmu_fault_handling)) {
/* L2 has been powered off. Invoke the state machine to power
* up the L2 cache and also effectively cancel the GPU power off
@@ -137,7 +131,6 @@ void kbase_pm_update_active(struct kbase_device *kbdev)
wake_up(&kbdev->pm.backend.poweroff_wait);
return;
}
#endif
pm->backend.poweron_required = true;
spin_unlock_irqrestore(&kbdev->hwaccess_lock, flags);
} else {
@@ -151,9 +144,7 @@ void kbase_pm_update_active(struct kbase_device *kbdev)
pm->backend.invoke_poweroff_wait_wq_when_l2_off = false;
pm->backend.poweroff_wait_in_progress = false;
pm->backend.l2_desired = true;
#if MALI_USE_CSF
pm->backend.mcu_desired = true;
#endif
spin_unlock_irqrestore(&kbdev->hwaccess_lock, flags);
kbase_pm_do_poweron(kbdev, false);
@@ -190,7 +181,6 @@ void kbase_pm_update_dynamic_cores_onoff(struct kbase_device *kbdev)
if (kbdev->pm.backend.poweroff_wait_in_progress)
return;
#if MALI_USE_CSF
CSTD_UNUSED(shaders_desired);
/* Invoke the MCU state machine to send a request to FW for updating
* the mask of shader cores that can be used for allocation of
@@ -198,18 +188,6 @@ void kbase_pm_update_dynamic_cores_onoff(struct kbase_device *kbdev)
*/
if (kbase_pm_is_mcu_desired(kbdev))
kbase_pm_update_state(kbdev);
#else
/* In protected transition, don't allow outside shader core request
* affect transition, return directly
*/
if (kbdev->pm.backend.protected_transition_override)
return;
shaders_desired = kbdev->pm.backend.pm_current_policy->shaders_needed(kbdev);
if (shaders_desired && kbase_pm_is_l2_desired(kbdev))
kbase_pm_update_state(kbdev);
#endif
}
void kbase_pm_update_cores_state_nolock(struct kbase_device *kbdev)
@@ -223,16 +201,6 @@ void kbase_pm_update_cores_state_nolock(struct kbase_device *kbdev)
if (kbdev->pm.backend.poweroff_wait_in_progress)
return;
#if !MALI_USE_CSF
if (kbdev->pm.backend.protected_transition_override)
/* We are trying to change in/out of protected mode - force all
* cores off so that the L2 powers down
*/
shaders_desired = false;
else
shaders_desired = kbdev->pm.backend.pm_current_policy->shaders_needed(kbdev);
#endif
if (kbdev->pm.backend.shaders_desired != shaders_desired) {
KBASE_KTRACE_ADD(kbdev, PM_CORES_CHANGE_DESIRED, NULL,
kbdev->pm.backend.shaders_desired);
@@ -274,7 +242,6 @@ const struct kbase_pm_policy *kbase_pm_get_policy(struct kbase_device *kbdev)
KBASE_EXPORT_TEST_API(kbase_pm_get_policy);
#if MALI_USE_CSF
static int policy_change_wait_for_L2_off(struct kbase_device *kbdev)
{
long remaining;
@@ -308,13 +275,11 @@ static int policy_change_wait_for_L2_off(struct kbase_device *kbdev)
return err;
}
#endif
void kbase_pm_set_policy(struct kbase_device *kbdev, const struct kbase_pm_policy *new_policy)
{
const struct kbase_pm_policy *old_policy;
unsigned long flags;
#if MALI_USE_CSF
unsigned int new_policy_csf_pm_sched_flags;
bool sched_suspend;
bool reset_gpu = false;
@@ -322,14 +287,12 @@ void kbase_pm_set_policy(struct kbase_device *kbdev, const struct kbase_pm_polic
struct kbase_csf_scheduler *scheduler = NULL;
u64 pwroff_ns;
bool switching_to_always_on;
#endif
KBASE_DEBUG_ASSERT(kbdev != NULL);
KBASE_DEBUG_ASSERT(new_policy != NULL);
KBASE_KTRACE_ADD(kbdev, PM_SET_POLICY, NULL, new_policy->id);
#if MALI_USE_CSF
pwroff_ns = kbase_csf_firmware_get_mcu_core_pwroff_time(kbdev);
switching_to_always_on = new_policy == &kbase_pm_always_on_policy_ops;
if (pwroff_ns == 0 && !switching_to_always_on) {
@@ -392,7 +355,6 @@ void kbase_pm_set_policy(struct kbase_device *kbdev, const struct kbase_pm_polic
if (sched_suspend)
reset_gpu = policy_change_wait_for_L2_off(kbdev);
#endif
kbase_pm_lock(kbdev);
@@ -424,19 +386,19 @@ void kbase_pm_set_policy(struct kbase_device *kbdev, const struct kbase_pm_polic
spin_lock_irqsave(&kbdev->hwaccess_lock, flags);
kbdev->pm.backend.pm_current_policy = new_policy;
#if MALI_USE_CSF
kbdev->pm.backend.csf_pm_sched_flags = new_policy_csf_pm_sched_flags;
/* New policy in place, release the clamping on mcu/L2 off state */
kbdev->pm.backend.policy_change_clamp_state_to_off = false;
kbase_pm_update_state(kbdev);
#ifdef KBASE_PM_RUNTIME
if (kbase_pm_idle_groups_sched_suspendable(kbdev))
clear_bit(KBASE_GPU_IGNORE_IDLE_EVENT, &kbdev->pm.backend.gpu_sleep_allowed);
else
set_bit(KBASE_GPU_IGNORE_IDLE_EVENT, &kbdev->pm.backend.gpu_sleep_allowed);
#endif /* KBASE_PM_RUNTIME */
#endif
if (IS_ENABLED(CONFIG_PM)) {
if (kbase_pm_idle_groups_sched_suspendable(kbdev))
clear_bit(KBASE_GPU_IGNORE_IDLE_EVENT,
&kbdev->pm.backend.gpu_sleep_allowed);
else
set_bit(KBASE_GPU_IGNORE_IDLE_EVENT, &kbdev->pm.backend.gpu_sleep_allowed);
}
spin_unlock_irqrestore(&kbdev->hwaccess_lock, flags);
/* If any core power state changes were previously attempted, but
@@ -452,7 +414,6 @@ void kbase_pm_set_policy(struct kbase_device *kbdev, const struct kbase_pm_polic
kbase_pm_context_idle_locked(kbdev);
kbase_pm_unlock(kbdev);
#if MALI_USE_CSF
/* Reverse the suspension done */
if (sched_suspend)
kbase_csf_scheduler_pm_resume_no_lock(kbdev);
@@ -469,7 +430,6 @@ void kbase_pm_set_policy(struct kbase_device *kbdev, const struct kbase_pm_polic
}
mutex_unlock(&kbdev->pm.backend.policy_change_lock);
#endif
}
KBASE_EXPORT_TEST_API(kbase_pm_set_policy);

View File

@@ -1,7 +1,7 @@
/* SPDX-License-Identifier: GPL-2.0 WITH Linux-syscall-note */
/*
*
* (C) COPYRIGHT 2018-2021 ARM Limited. All rights reserved.
* (C) COPYRIGHT 2018-2024 ARM Limited. All rights reserved.
*
* This program is free software and is provided to you under the terms of the
* GNU General Public License version 2 as published by the Free Software
@@ -42,11 +42,6 @@
* @WAIT_OFF_CORESTACK_ON: The shaders have been requested to power
* off, but they remain on for the duration
* of the hysteresis timer
* @WAIT_GPU_IDLE: The shaders partial poweroff needs to
* reach a state where jobs on the GPU are
* finished including jobs currently running
* and in the GPU queue because of
* GPU2017-861
* @WAIT_FINISHED_CORESTACK_ON: The hysteresis timer has expired
* @L2_FLUSHING_CORESTACK_ON: The core stacks are on and the level 2
* cache is being flushed.
@@ -67,9 +62,6 @@ KBASEP_SHADER_STATE(PEND_ON_CORESTACK_ON)
KBASEP_SHADER_STATE(ON_CORESTACK_ON)
KBASEP_SHADER_STATE(ON_CORESTACK_ON_RECHECK)
KBASEP_SHADER_STATE(WAIT_OFF_CORESTACK_ON)
#if !MALI_USE_CSF
KBASEP_SHADER_STATE(WAIT_GPU_IDLE)
#endif /* !MALI_USE_CSF */
KBASEP_SHADER_STATE(WAIT_FINISHED_CORESTACK_ON)
KBASEP_SHADER_STATE(L2_FLUSHING_CORESTACK_ON)
KBASEP_SHADER_STATE(READY_OFF_CORESTACK_ON)

View File

@@ -310,6 +310,9 @@ KBASE_EXPORT_TEST_API(kbase_get_timeout_ms);
u64 kbase_backend_get_cycle_cnt(struct kbase_device *kbdev)
{
if (kbase_io_is_aw_removed(kbdev))
return 0;
return kbase_reg_read64_coherent(kbdev, GPU_CONTROL_ENUM(CYCLE_COUNT));
}
@@ -330,6 +333,36 @@ u64 kbase_arch_timer_get_cntfrq(struct kbase_device *kbdev)
return freq;
}
static int kbase_gpu_timestamp_offset_read(void *data, u64 *val)
{
struct kbase_device *kbdev = (struct kbase_device *)data;
if (kbdev->backend_time.gpu_timestamp_offset == GPU_TIMESTAMP_OFFSET_INVALID)
return -EINVAL;
*val = kbdev->backend_time.gpu_timestamp_offset;
return 0;
}
DEFINE_DEBUGFS_ATTRIBUTE(timestamp_offset_debugfs_fops, kbase_gpu_timestamp_offset_read, NULL,
"%lld\n");
void kbase_gpu_timestamp_offset_debugfs_init(struct kbase_device *kbdev)
{
struct dentry *timestamp_offset_file;
if (unlikely(!kbdev)) {
pr_warn("%s: kbdev is NULL\n", __func__);
return;
}
timestamp_offset_file = debugfs_create_file("gpu_timestamp_offset", 0400,
kbdev->mali_debugfs_directory, kbdev,
&timestamp_offset_debugfs_fops);
if (IS_ERR_OR_NULL(timestamp_offset_file))
dev_warn(kbdev->dev, "Failed to create gpu_timestamp_offset debugfs entry");
}
int kbase_backend_time_init(struct kbase_device *kbdev)
{

View File

@@ -117,7 +117,6 @@ bob_defaults {
"CONFIG_MALI_VALHALL_PLATFORM_NAME={{.mali_platform_name}}",
"MALI_CUSTOMER_RELEASE={{.release}}",
"MALI_UNIT_TEST={{.unit_test_code}}",
"MALI_USE_CSF={{.gpu_has_csf}}",
"MALI_JIT_PRESSURE_LIMIT_BASE={{.jit_pressure_limit_base}}",
// Start of CS experimental features definitions.
@@ -133,7 +132,6 @@ bob_defaults {
// is an umbrella feature that would be open for inappropriate use
// (catch-all for experimental CS code without separating it into
// different features).
"MALI_BASE_CSF_PERFORMANCE_TESTS={{.base_csf_performance_tests}}",
],
}

View File

@@ -1,6 +1,6 @@
# SPDX-License-Identifier: GPL-2.0 WITH Linux-syscall-note
#
# (C) COPYRIGHT 2012-2013, 2016-2017, 2020-2021 ARM Limited. All rights reserved.
# (C) COPYRIGHT 2012-2013, 2016-2017, 2020-2021, 2024 ARM Limited. All rights reserved.
#
# This program is free software and is provided to you under the terms of the
# GNU General Public License version 2 as published by the Free Software
@@ -18,10 +18,6 @@
#
#
valhall_kbase-y += context/mali_kbase_context.o
ifeq ($(CONFIG_MALI_VALHALL_CSF_SUPPORT),y)
valhall_kbase-y += context/backend/mali_kbase_context_csf.o
else
valhall_kbase-y += context/backend/mali_kbase_context_jm.o
endif
valhall_kbase-y += \
context/mali_kbase_context.o \
context/backend/mali_kbase_context_csf.o

View File

@@ -91,6 +91,8 @@ static const struct kbase_context_init context_init[] = {
"Common context initialization failed" },
{ kbase_context_mem_pool_group_init, kbase_context_mem_pool_group_term,
"Memory pool group initialization failed" },
{ kbase_context_pgd_mem_pool_init, kbase_context_pgd_mem_pool_term,
"pgd memory pool initialization failed" },
{ kbase_mem_evictable_init, kbase_mem_evictable_deinit,
"Memory evictable initialization failed" },
{ kbase_ctx_sched_init_ctx, NULL, NULL },
@@ -207,6 +209,7 @@ void kbase_destroy_context(struct kbase_context *kctx)
wait_event(kbdev->pm.resume_wait, !kbase_pm_is_resuming(kbdev));
kbase_mem_pool_group_mark_dying(&kctx->mem_pools);
kbase_mem_pool_mark_dying(&kctx->pgd_mem_pool);
kbase_context_term_partial(kctx, ARRAY_SIZE(context_init));

View File

@@ -1,266 +0,0 @@
// SPDX-License-Identifier: GPL-2.0 WITH Linux-syscall-note
/*
*
* (C) COPYRIGHT 2019-2024 ARM Limited. All rights reserved.
*
* This program is free software and is provided to you under the terms of the
* GNU General Public License version 2 as published by the Free Software
* Foundation, and any use by you of this program is subject to the terms
* of such GNU license.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program; if not, you can access it online at
* http://www.gnu.org/licenses/gpl-2.0.html.
*
*/
/*
* Base kernel context APIs for Job Manager GPUs
*/
#include <context/mali_kbase_context_internal.h>
#include <hw_access/mali_kbase_hw_access_regmap.h>
#include <mali_kbase.h>
#include <mali_kbase_ctx_sched.h>
#include <mali_kbase_kinstr_jm.h>
#include <mali_kbase_mem_linux.h>
#include <mali_kbase_mem_pool_group.h>
#include <mmu/mali_kbase_mmu.h>
#include <tl/mali_kbase_timeline.h>
#if IS_ENABLED(CONFIG_DEBUG_FS)
#include <mali_kbase_debug_mem_view.h>
#include <mali_kbase_debug_mem_zones.h>
#include <mali_kbase_debug_mem_allocs.h>
#include <mali_kbase_mem_pool_debugfs.h>
void kbase_context_debugfs_init(struct kbase_context *const kctx)
{
kbase_debug_mem_view_init(kctx);
kbase_debug_mem_zones_init(kctx);
kbase_debug_mem_allocs_init(kctx);
kbase_mem_pool_debugfs_init(kctx->kctx_dentry, kctx);
kbase_jit_debugfs_init(kctx);
kbasep_jd_debugfs_ctx_init(kctx);
}
KBASE_EXPORT_SYMBOL(kbase_context_debugfs_init);
void kbase_context_debugfs_term(struct kbase_context *const kctx)
{
debugfs_remove_recursive(kctx->kctx_dentry);
}
KBASE_EXPORT_SYMBOL(kbase_context_debugfs_term);
#else
void kbase_context_debugfs_init(struct kbase_context *const kctx)
{
CSTD_UNUSED(kctx);
}
KBASE_EXPORT_SYMBOL(kbase_context_debugfs_init);
void kbase_context_debugfs_term(struct kbase_context *const kctx)
{
CSTD_UNUSED(kctx);
}
KBASE_EXPORT_SYMBOL(kbase_context_debugfs_term);
#endif /* CONFIG_DEBUG_FS */
static int kbase_context_kbase_kinstr_jm_init(struct kbase_context *kctx)
{
return kbase_kinstr_jm_init(&kctx->kinstr_jm);
}
static void kbase_context_kbase_kinstr_jm_term(struct kbase_context *kctx)
{
kbase_kinstr_jm_term(kctx->kinstr_jm);
}
static int kbase_context_kbase_timer_setup(struct kbase_context *kctx)
{
kbase_timer_setup(&kctx->soft_job_timeout, kbasep_soft_job_timeout_worker);
return 0;
}
static int kbase_context_submit_check(struct kbase_context *kctx)
{
struct kbasep_js_kctx_info *js_kctx_info = &kctx->jctx.sched_info;
unsigned long irq_flags = 0;
base_context_create_flags const flags = kctx->create_flags;
mutex_lock(&js_kctx_info->ctx.jsctx_mutex);
spin_lock_irqsave(&kctx->kbdev->hwaccess_lock, irq_flags);
/* Translate the flags */
if ((flags & BASE_CONTEXT_SYSTEM_MONITOR_SUBMIT_DISABLED) == 0)
kbase_ctx_flag_clear(kctx, KCTX_SUBMIT_DISABLED);
spin_unlock_irqrestore(&kctx->kbdev->hwaccess_lock, irq_flags);
mutex_unlock(&js_kctx_info->ctx.jsctx_mutex);
return 0;
}
static void kbase_context_flush_jobs(struct kbase_context *kctx)
{
kbase_jd_zap_context(kctx);
flush_workqueue(kctx->jctx.job_done_wq);
}
/**
* kbase_context_free - Free kcontext at its destruction
*
* @kctx: kcontext to be freed
*/
static void kbase_context_free(struct kbase_context *kctx)
{
kbase_timeline_post_kbase_context_destroy(kctx);
vfree(kctx);
}
static const struct kbase_context_init context_init[] = {
{ NULL, kbase_context_free, NULL },
{ kbase_context_common_init, kbase_context_common_term,
"Common context initialization failed" },
{ kbase_context_mem_pool_group_init, kbase_context_mem_pool_group_term,
"Memory pool group initialization failed" },
{ kbase_mem_evictable_init, kbase_mem_evictable_deinit,
"Memory evictable initialization failed" },
{ kbase_ctx_sched_init_ctx, NULL, NULL },
{ kbase_context_mmu_init, kbase_context_mmu_term, "MMU initialization failed" },
{ kbase_context_mem_alloc_page, kbase_context_mem_pool_free, "Memory alloc page failed" },
{ kbase_region_tracker_init, kbase_region_tracker_term,
"Region tracker initialization failed" },
{ kbase_sticky_resource_init, kbase_context_sticky_resource_term,
"Sticky resource initialization failed" },
{ kbase_jit_init, kbase_jit_term, "JIT initialization failed" },
{ kbase_context_kbase_kinstr_jm_init, kbase_context_kbase_kinstr_jm_term,
"JM instrumentation initialization failed" },
{ kbase_context_kbase_timer_setup, NULL, "Timers initialization failed" },
{ kbase_event_init, kbase_event_cleanup, "Event initialization failed" },
{ kbasep_js_kctx_init, kbasep_js_kctx_term, "JS kctx initialization failed" },
{ kbase_jd_init, kbase_jd_exit, "JD initialization failed" },
{ kbase_context_submit_check, NULL, "Enabling job submission failed" },
#if IS_ENABLED(CONFIG_DEBUG_FS)
{ kbase_debug_job_fault_context_init, kbase_debug_job_fault_context_term,
"Job fault context initialization failed" },
#endif
{ kbasep_platform_context_init, kbasep_platform_context_term,
"Platform callback for kctx initialization failed" },
{ NULL, kbase_context_flush_jobs, NULL },
{ kbase_context_add_to_dev_list, kbase_context_remove_from_dev_list,
"Adding kctx to device failed" },
};
static void kbase_context_term_partial(struct kbase_context *kctx, unsigned int i)
{
while (i-- > 0) {
if (context_init[i].term)
context_init[i].term(kctx);
}
}
struct kbase_context *kbase_create_context(struct kbase_device *kbdev, bool is_compat,
base_context_create_flags const flags,
unsigned long const api_version, struct file *const filp)
{
struct kbase_context *kctx;
unsigned int i = 0;
if (WARN_ON(!kbdev))
return NULL;
/* Validate flags */
if (WARN_ON(flags != (flags & BASEP_CONTEXT_CREATE_KERNEL_FLAGS)))
return NULL;
/* zero-inited as lot of code assume it's zero'ed out on create */
kctx = vzalloc(sizeof(*kctx));
if (WARN_ON(!kctx))
return NULL;
kctx->kbdev = kbdev;
kctx->api_version = api_version;
kctx->filp = filp;
kctx->create_flags = flags;
if (is_compat)
kbase_ctx_flag_set(kctx, KCTX_COMPAT);
#if defined(CONFIG_64BIT)
else
kbase_ctx_flag_set(kctx, KCTX_FORCE_SAME_VA);
#endif /* defined(CONFIG_64BIT) */
for (i = 0; i < ARRAY_SIZE(context_init); i++) {
int err = 0;
if (context_init[i].init)
err = context_init[i].init(kctx);
if (err) {
dev_err(kbdev->dev, "%s error = %d\n", context_init[i].err_mes, err);
/* kctx should be freed by kbase_context_free().
* Otherwise it will result in memory leak.
*/
WARN_ON(i == 0);
kbase_context_term_partial(kctx, i);
return NULL;
}
}
return kctx;
}
KBASE_EXPORT_SYMBOL(kbase_create_context);
void kbase_destroy_context(struct kbase_context *kctx)
{
struct kbase_device *kbdev;
if (WARN_ON(!kctx))
return;
kbdev = kctx->kbdev;
if (WARN_ON(!kbdev))
return;
/* Context termination could happen whilst the system suspend of
* the GPU device is ongoing or has completed. It has been seen on
* Customer side that a hang could occur if context termination is
* not blocked until the resume of GPU device.
*/
if (kbase_has_arbiter(kbdev))
atomic_inc(&kbdev->pm.gpu_users_waiting);
while (kbase_pm_context_active_handle_suspend(kbdev,
KBASE_PM_SUSPEND_HANDLER_DONT_INCREASE)) {
dev_dbg(kbdev->dev, "Suspend in progress when destroying context");
wait_event(kbdev->pm.resume_wait, !kbase_pm_is_suspending(kbdev));
}
/* Have synchronized against the System suspend and incremented the
* pm.active_count. So any subsequent invocation of System suspend
* callback would get blocked.
* If System suspend callback was already in progress then the above loop
* would have waited till the System resume callback has begun.
* So wait for the System resume callback to also complete as we want to
* avoid context termination during System resume also.
*/
wait_event(kbdev->pm.resume_wait, !kbase_pm_is_resuming(kbdev));
if (kbase_has_arbiter(kbdev))
atomic_dec(&kbdev->pm.gpu_users_waiting);
kbase_mem_pool_group_mark_dying(&kctx->mem_pools);
kbase_context_term_partial(kctx, ARRAY_SIZE(context_init));
kbase_pm_context_idle(kbdev);
}
KBASE_EXPORT_SYMBOL(kbase_destroy_context);

View File

@@ -203,6 +203,7 @@ int kbase_context_common_init(struct kbase_context *kctx)
}
}
kctx->offslot_ts = 0;
return err;
}
@@ -296,8 +297,11 @@ void kbase_context_common_term(struct kbase_context *kctx)
int kbase_context_mem_pool_group_init(struct kbase_context *kctx)
{
return kbase_mem_pool_group_init(&kctx->mem_pools, kctx->kbdev,
&kctx->kbdev->mem_pool_defaults, &kctx->kbdev->mem_pools);
size_t const small_max_size = KBASE_MEM_POOL_MAX_SIZE_KCTX;
size_t const large_max_size = small_max_size >> (KBASE_MEM_POOL_2MB_PAGE_TABLE_ORDER -
KBASE_MEM_POOL_SMALL_PAGE_TABLE_ORDER);
return kbase_mem_pool_group_init(&kctx->mem_pools, kctx->kbdev, small_max_size,
large_max_size, NULL);
}
void kbase_context_mem_pool_group_term(struct kbase_context *kctx)
@@ -305,6 +309,20 @@ void kbase_context_mem_pool_group_term(struct kbase_context *kctx)
kbase_mem_pool_group_term(&kctx->mem_pools);
}
int kbase_context_pgd_mem_pool_init(struct kbase_context *kctx)
{
int err = kbase_mem_pool_init_no_reclaim(&kctx->pgd_mem_pool,
BASE_PGD_MEM_POOL_MAX_SIZE_KBDEV,
KBASE_MEM_POOL_SMALL_PAGE_TABLE_ORDER, 0,
kctx->kbdev);
return err;
}
void kbase_context_pgd_mem_pool_term(struct kbase_context *kctx)
{
kbase_mem_pool_term(&kctx->pgd_mem_pool);
}
int kbase_context_mmu_init(struct kbase_context *kctx)
{
return kbase_mmu_init(kctx->kbdev, &kctx->mmu, kctx,

View File

@@ -1,7 +1,7 @@
/* SPDX-License-Identifier: GPL-2.0 WITH Linux-syscall-note */
/*
*
* (C) COPYRIGHT 2019-2023 ARM Limited. All rights reserved.
* (C) COPYRIGHT 2019-2024 ARM Limited. All rights reserved.
*
* This program is free software and is provided to you under the terms of the
* GNU General Public License version 2 as published by the Free Software
@@ -50,6 +50,9 @@ void kbase_context_common_term(struct kbase_context *kctx);
int kbase_context_mem_pool_group_init(struct kbase_context *kctx);
void kbase_context_mem_pool_group_term(struct kbase_context *kctx);
int kbase_context_pgd_mem_pool_init(struct kbase_context *kctx);
void kbase_context_pgd_mem_pool_term(struct kbase_context *kctx);
int kbase_context_mmu_init(struct kbase_context *kctx);
void kbase_context_mmu_term(struct kbase_context *kctx);

View File

@@ -897,7 +897,6 @@ void kbase_ipa_control_handle_gpu_reset_post(struct kbase_device *kbdev)
}
KBASE_EXPORT_TEST_API(kbase_ipa_control_handle_gpu_reset_post);
#ifdef KBASE_PM_RUNTIME
void kbase_ipa_control_handle_gpu_sleep_enter(struct kbase_device *kbdev)
{
lockdep_assert_held(&kbdev->hwaccess_lock);
@@ -931,7 +930,6 @@ void kbase_ipa_control_handle_gpu_sleep_exit(struct kbase_device *kbdev)
}
}
KBASE_EXPORT_TEST_API(kbase_ipa_control_handle_gpu_sleep_exit);
#endif
#if MALI_UNIT_TEST
void kbase_ipa_control_rate_change_notify_test(struct kbase_device *kbdev, u32 clk_index,

View File

@@ -1,7 +1,7 @@
/* SPDX-License-Identifier: GPL-2.0 WITH Linux-syscall-note */
/*
*
* (C) COPYRIGHT 2020-2023 ARM Limited. All rights reserved.
* (C) COPYRIGHT 2020-2024 ARM Limited. All rights reserved.
*
* This program is free software and is provided to you under the terms of the
* GNU General Public License version 2 as published by the Free Software
@@ -197,7 +197,6 @@ void kbase_ipa_control_handle_gpu_reset_pre(struct kbase_device *kbdev);
*/
void kbase_ipa_control_handle_gpu_reset_post(struct kbase_device *kbdev);
#ifdef KBASE_PM_RUNTIME
/**
* kbase_ipa_control_handle_gpu_sleep_enter - Handle the pre GPU Sleep event
*
@@ -222,7 +221,6 @@ void kbase_ipa_control_handle_gpu_sleep_enter(struct kbase_device *kbdev);
* was called previously.
*/
void kbase_ipa_control_handle_gpu_sleep_exit(struct kbase_device *kbdev);
#endif
#if MALI_UNIT_TEST
/**

View File

@@ -1,7 +1,7 @@
// SPDX-License-Identifier: GPL-2.0 WITH Linux-syscall-note
/*
*
* (C) COPYRIGHT 2018-2024 ARM Limited. All rights reserved.
* (C) COPYRIGHT 2018-2025 ARM Limited. All rights reserved.
*
* This program is free software and is provided to you under the terms of the
* GNU General Public License version 2 as published by the Free Software
@@ -319,10 +319,9 @@ void kbase_csf_free_command_stream_user_pages(struct kbase_context *kctx, struct
* This condition is only true when mali_kbase_supports_csg_cs_user_page_allocation()
* is disable.
*/
if (!mali_kbase_supports_csg_cs_user_page_allocation(kctx->api_version)) {
if (!mali_kbase_supports_csg_cs_user_page_allocation(kctx->api_version))
kernel_free_user_io_pages(kctx, queue->phys, queue->user_io_addr);
queue->user_io_addr = NULL;
}
queue->user_io_addr = NULL;
/* The user_io_gpu_va should have been unmapped inside the scheduler */
WARN_ONCE(queue->user_io_gpu_va, "Userio pages appears still have mapping");
@@ -773,6 +772,12 @@ int kbase_csf_queue_bind(struct kbase_context *kctx, union kbase_ioctl_cs_queue_
if (bind->in.csi_index >= max_streams)
goto out;
if (queue->user_io_addr != NULL) {
dev_err(kctx->kbdev->dev, "Queue with stale user_io address: %pK",
(void *)queue->user_io_addr);
goto out;
}
if (group->run_state == KBASE_CSF_GROUP_TERMINATED)
goto out;
@@ -1018,6 +1023,13 @@ static void unbind_stopped_queue(struct kbase_context *kctx, struct kbase_queue
queue->group = NULL;
kbase_csf_scheduler_spin_unlock(kctx->kbdev, flags);
/* Ensure that the user I/O pages are no longer accessible */
mutex_lock(&kctx->kbdev->csf.reg_lock);
unmap_mapping_range(kctx->kbdev->csf.db_filp->f_inode->i_mapping,
(loff_t)(queue->db_file_offset << PAGE_SHIFT),
BASEP_QUEUE_NR_MMAP_USER_PAGES * PAGE_SIZE, 1);
mutex_unlock(&kctx->kbdev->csf.reg_lock);
put_user_pages_mmap_handle(kctx, queue);
WARN_ON_ONCE(queue->doorbell_nr != KBASEP_USER_DB_NR_INVALID);
queue->bind_state = KBASE_CSF_QUEUE_UNBOUND;
@@ -1852,8 +1864,6 @@ void kbase_csf_ctx_handle_fault(struct kbase_context *kctx, struct kbase_fault *
void kbase_csf_ctx_term(struct kbase_context *kctx)
{
struct kbase_device *kbdev = kctx->kbdev;
struct kbase_as *as = NULL;
unsigned long flags;
u32 i;
int err;
bool reset_prevented = false;
@@ -1922,15 +1932,57 @@ void kbase_csf_ctx_term(struct kbase_context *kctx)
flush_work(&kctx->kbdev->csf.glb_fatal_work);
/* A work item to handle page_fault/bus_fault/gpu_fault could be
* pending for the outgoing context. Flush the workqueue that will
* execute that work item.
* pending for the outgoing context which we no longer care about.
* Ensure that the context won't be accessed anymore by the fault
* workers.
*/
spin_lock_irqsave(&kctx->kbdev->hwaccess_lock, flags);
if (kctx->as_nr != KBASEP_AS_NR_INVALID)
as = &kctx->kbdev->as[kctx->as_nr];
spin_unlock_irqrestore(&kctx->kbdev->hwaccess_lock, flags);
if (as)
flush_workqueue(as->pf_wq);
while (true) {
unsigned long flags;
int refcount;
mutex_lock(&kbdev->mmu_hw_mutex);
spin_lock_irqsave(&kbdev->hwaccess_lock, flags);
refcount = atomic_read(&kctx->refcount);
if ((refcount != 0) && !WARN_ON_ONCE(kctx->as_nr == KBASEP_AS_NR_INVALID)) {
struct kbase_as *as = &kctx->kbdev->as[kctx->as_nr];
int new_refcount;
dev_dbg(kbdev->dev,
"Waiting for pending fault worker to complete when terminating context (%d_%d)",
kctx->tgid, kctx->id);
spin_unlock_irqrestore(&kbdev->hwaccess_lock, flags);
mutex_unlock(&kbdev->mmu_hw_mutex);
flush_workqueue(as->pf_wq);
new_refcount = atomic_read(&kctx->refcount);
if (refcount != new_refcount) {
/* Fault workers executed and released some references, re-check */
continue;
} else {
/* Waiting for pending fault workers to execute was not effective,
* we're going to forcefully de-assign the AS from this context
* because nothing else should still be accessing the context at
* this point.
*
* This should never happen and a WARN_ON() would be printed by
* kbase_ctx_sched_remove_ctx() if the refcount is non-zero.
*/
dev_warn(
kbdev->dev,
"No fault workers executed, %d refs remain for terminating context (%d_%d)",
new_refcount, kctx->tgid, kctx->id);
kbase_ctx_sched_remove_ctx(kctx);
}
} else {
kbase_ctx_sched_remove_ctx_nolock(kctx);
spin_unlock_irqrestore(&kbdev->hwaccess_lock, flags);
mutex_unlock(&kbdev->mmu_hw_mutex);
}
break;
}
mutex_lock(&kctx->csf.lock);
@@ -2439,27 +2491,33 @@ static void handle_progress_timer_events(struct kbase_device *const kbdev, unsig
u32 max_csg_slots = kbdev->csf.global_iface.group_num;
u32 csg_nr;
struct kbase_queue_group *group = NULL;
bool aw_removed;
kbase_csf_scheduler_spin_lock_assert_held(kbdev);
if (likely(bitmap_empty(slot_mask, BASEP_QUEUE_GROUP_MAX)))
return;
/* Log each timeout and Update timestamp of compute progress timeout */
for_each_set_bit(csg_nr, slot_mask, max_csg_slots) {
group = kbdev->csf.scheduler.csg_slots[csg_nr].resident_group;
group->progress_timer_state = kbase_csf_fw_io_group_read(&kbdev->csf.fw_io, csg_nr,
CSG_PROGRESS_TIMER_STATE);
aw_removed = kbase_io_is_aw_removed(kbdev);
dev_info(
kbdev->dev,
"[%llu] Iterator PROGRESS_TIMER timeout notification received for group %u of ctx %d_%d on slot %u with state %x",
kbase_backend_get_cycle_cnt(kbdev), group->handle, group->kctx->tgid,
group->kctx->id, csg_nr, group->progress_timer_state);
if (!aw_removed)
/* Log each timeout and Update timestamp of compute progress timeout */
for_each_set_bit(csg_nr, slot_mask, max_csg_slots) {
group = kbdev->csf.scheduler.csg_slots[csg_nr].resident_group;
group->progress_timer_state = kbase_csf_fw_io_group_read(
&kbdev->csf.fw_io, csg_nr, CSG_PROGRESS_TIMER_STATE);
if (CSG_PROGRESS_TIMER_STATE_GET(group->progress_timer_state) ==
CSG_PROGRESS_TIMER_STATE_COMPUTE)
kbdev->csf.compute_progress_timeout_cc = kbase_backend_get_cycle_cnt(kbdev);
}
dev_info(
kbdev->dev,
"[%llu] Iterator PROGRESS_TIMER timeout notification received for group %u of ctx %d_%d on slot %u with state %x",
kbase_backend_get_cycle_cnt(kbdev), group->handle,
group->kctx->tgid, group->kctx->id, csg_nr,
group->progress_timer_state);
if (CSG_PROGRESS_TIMER_STATE_GET(group->progress_timer_state) ==
CSG_PROGRESS_TIMER_STATE_COMPUTE)
kbdev->csf.compute_progress_timeout_cc =
kbase_backend_get_cycle_cnt(kbdev);
}
/* Ignore fragment timeout if it is following a compute timeout.
* Otherwise, terminate the command stream group.
@@ -2470,8 +2528,8 @@ static void handle_progress_timer_events(struct kbase_device *const kbdev, unsig
/* Check if it is a fragment timeout right after another compute timeout.
* In such case, kill compute CSG and give fragment CSG a second chance
*/
if (CSG_PROGRESS_TIMER_STATE_GET(group->progress_timer_state) ==
CSG_PROGRESS_TIMER_STATE_FRAGMENT) {
if (!aw_removed && CSG_PROGRESS_TIMER_STATE_GET(group->progress_timer_state) ==
CSG_PROGRESS_TIMER_STATE_FRAGMENT) {
u64 cycle_counter = kbase_backend_get_cycle_cnt(kbdev);
u64 compute_progress_timeout_cc = kbdev->csf.compute_progress_timeout_cc;
@@ -3005,7 +3063,27 @@ static int process_cs_interrupts(struct kbase_queue_group *const group, u32 grou
kbase_csf_fw_io_close(fw_io, fw_io_flags);
}
/* PROTM_PEND and TILER_OOM can be safely ignored
/* PROTM_PEND request should be handled if the group
* is assigned a CSG slot in the future. We set
* protm_pending_bitmap here in case we skip saving
* the CS slots' state due to the group becoming active
* shortly after the suspension request is made.
*/
if ((cs_req & CS_REQ_PROTM_PEND_MASK) ^ (cs_ack & CS_ACK_PROTM_PEND_MASK)) {
KBASE_KTRACE_ADD_CSF_GRP_Q(kbdev, CSI_INTERRUPT_PROTM_PEND, group,
queue, cs_req ^ cs_ack);
dev_dbg(kbdev->dev,
"Protected mode entry request for queue on csi %d bound to group-%d on slot %d",
queue->csi_index, group->handle, group->csg_nr);
bitmap_set(group->protm_pending_bitmap, i, 1);
KBASE_KTRACE_ADD_CSF_GRP_Q(kbdev, CSI_PROTM_PEND_SET, group, queue,
group->protm_pending_bitmap[0]);
protm_pend = true;
}
/* TILER_OOM can be safely ignored
* because they will be raised again if the group
* is assigned a CSG slot in future.
*/
@@ -3026,20 +3104,6 @@ static int process_cs_interrupts(struct kbase_queue_group *const group, u32 grou
kbase_csf_handle_pending_oom_interrupt(queue, group_id);
}
if ((cs_req & CS_REQ_PROTM_PEND_MASK) ^ (cs_ack & CS_ACK_PROTM_PEND_MASK)) {
KBASE_KTRACE_ADD_CSF_GRP_Q(kbdev, CSI_INTERRUPT_PROTM_PEND, group,
queue, cs_req ^ cs_ack);
dev_dbg(kbdev->dev,
"Protected mode entry request for queue on csi %d bound to group-%d on slot %d",
queue->csi_index, group->handle, group->csg_nr);
bitmap_set(group->protm_pending_bitmap, i, 1);
KBASE_KTRACE_ADD_CSF_GRP_Q(kbdev, CSI_PROTM_PEND_SET, group, queue,
group->protm_pending_bitmap[0]);
protm_pend = true;
}
}
}
@@ -3757,7 +3821,7 @@ void kbase_csf_doorbell_mapping_term(struct kbase_device *kbdev)
* module unload path, so the page can be left uncleared before returning it
* back to kbdev memory pool.
*/
kbase_mem_pool_free(&kbdev->mem_pools.small[KBASE_MEM_GROUP_CSF_FW], page, false);
kbase_mem_pool_free(&kbdev->fw_mem_pools.small, page, false);
fput(kbdev->csf.db_filp);
}
@@ -3773,8 +3837,7 @@ int kbase_csf_doorbell_mapping_init(struct kbase_device *kbdev)
if (IS_ERR(filp))
return PTR_ERR(filp);
ret = kbase_mem_pool_alloc_pages(&kbdev->mem_pools.small[KBASE_MEM_GROUP_CSF_FW], 1, &phys,
false, NULL);
ret = kbase_mem_pool_alloc_pages(&kbdev->fw_mem_pools.small, 1, &phys, false, NULL);
if (ret <= 0) {
fput(filp);
@@ -3821,7 +3884,7 @@ void kbase_csf_free_dummy_user_reg_page(struct kbase_device *kbdev)
* path, so the page can be left uncleared before returning it back to kbdev
* memory pool.
*/
kbase_mem_pool_free(&kbdev->mem_pools.small[KBASE_MEM_GROUP_CSF_FW], page, false);
kbase_mem_pool_free(&kbdev->fw_mem_pools.small, page, false);
fput(kbdev->csf.user_reg.filp);
}
}
@@ -3841,8 +3904,7 @@ int kbase_csf_setup_dummy_user_reg_page(struct kbase_device *kbdev)
return PTR_ERR(filp);
}
if (kbase_mem_pool_alloc_pages(&kbdev->mem_pools.small[KBASE_MEM_GROUP_CSF_FW], 1, &phys,
false, NULL) <= 0) {
if (kbase_mem_pool_alloc_pages(&kbdev->fw_mem_pools.small, 1, &phys, false, NULL) <= 0) {
fput(filp);
return -ENOMEM;
}

View File

@@ -50,10 +50,8 @@ static const char *scheduler_state_to_string(struct kbase_device *kbdev,
return "INACTIVE";
case SCHED_SUSPENDED:
return "SUSPENDED";
#ifdef KBASE_PM_RUNTIME
case SCHED_SLEEPING:
return "SLEEPING";
#endif
default:
dev_warn(kbdev->dev, "Unknown Scheduler state %d", sched_state);
return NULL;
@@ -249,10 +247,8 @@ static ssize_t kbase_csf_debugfs_scheduler_state_set(struct file *file, const ch
if (sysfs_streq(buf, "SUSPENDED"))
kbase_csf_scheduler_pm_suspend(kbdev);
#ifdef KBASE_PM_RUNTIME
else if (sysfs_streq(buf, "SLEEPING"))
else if (IS_ENABLED(CONFIG_PM) && sysfs_streq(buf, "SLEEPING"))
kbase_csf_scheduler_force_sleep(kbdev);
#endif
else if (sysfs_streq(buf, "INACTIVE"))
kbase_csf_scheduler_force_wakeup(kbdev);
else {

View File

@@ -1043,6 +1043,17 @@ struct kbase_csf_csg_slot {
u8 priority;
};
/**
* struct kbase_csf_heap_reclaim_offslot - Setting for reclaiming offslot CSG's heap.
*
* @timeout_ms: Reclaim from CSGs being offslot longer than this.
* @pages: Max number of pages for each reclaim.
*/
struct kbase_csf_heap_reclaim_offslot {
u32 timeout_ms;
u32 pages;
};
/**
* struct kbase_csf_sched_heap_reclaim_mgr - Object for managing tiler heap reclaim
* kctx lists inside the CSF device's scheduler.
@@ -1052,12 +1063,14 @@ struct kbase_csf_csg_slot {
* lists track the kctxs attached to the reclaim manager.
* @unused_pages: Estimated number of unused pages from the @ctxlist array. The
* number is indicative for use with reclaim shrinker's count method.
* @offslot_setting: Setting for reclaiming offslot CSG's heap.
*/
struct kbase_csf_sched_heap_reclaim_mgr {
DEFINE_KBASE_SHRINKER heap_reclaim;
struct list_head ctx_lists[KBASE_QUEUE_GROUP_PRIORITY_COUNT];
atomic_t unused_pages;
struct kbase_csf_heap_reclaim_offslot offslot_setting;
};
/**
@@ -1177,6 +1190,9 @@ struct kbase_csf_mcu_shared_regions {
* perform a scheduling tock.
* @pending_gpu_idle_work: Indicates that kbase_csf_scheduler_kthread() should
* handle the GPU IDLE event.
* @pending_runtime_suspend_work: Indicates that kbase_csf_scheduler_kthread()
* should proceed to suspend the GPU as part of
* handling the runtime suspend event.
* @pending_power_off_work: Indicates that kbase_csf_scheduler_kthread() should
* proceed to power off the GPU.
* @ping_work: Work item that would ping the firmware at regular
@@ -1228,10 +1244,13 @@ struct kbase_csf_mcu_shared_regions {
* @mcu_regs_data: Scheduler MCU shared regions data for managing the
* shared interface mappings for on-slot queues and
* CSG suspend buffers.
* @kthread_signal: Used to wake up the GPU queue submission
* thread when a queue needs attention.
* @kthread_running: Whether the GPU queue submission thread should keep
* executing.
* @kthread_signal: Used to wake up the main CSF scheduler thread
* to handle pending work items.
* @kthread_running: Set to true to indicate that the CSF scheduler
* thread will handle work items. Work items that
* are handled by this thread all require the schduler
* mutex lock, thus are serialised and executed in a
* predefined order.
* @gpuq_kthread: Dedicated thread primarily used to handle
* latency-sensitive tasks such as GPU queue
* submissions.
@@ -1272,6 +1291,7 @@ struct kbase_csf_scheduler {
atomic_t pending_tick_work;
atomic_t pending_tock_work;
atomic_t pending_gpu_idle_work;
atomic_t pending_runtime_suspend_work;
atomic_t pending_power_off_work;
struct delayed_work ping_work;
struct kbase_context *top_kctx;
@@ -1813,7 +1833,8 @@ struct kbase_csf_user_reg {
* @fw_io: Firmware I/O interface.
* @compute_progress_timeout_cc: Value of GPU cycle count register when progress
* timer timeout is reported for the compute iterator.
* @num_doorbells: Number of doorbells supported by the GPU.
* @neural_allowed_mask: A mask for optionally disabling neural cores across all CSGs
* @num_doorbells: Number of doorbells supported by the GPU.
*/
struct kbase_csf_device {
struct kbase_mmu_table mcu_mmu;
@@ -1877,6 +1898,7 @@ struct kbase_csf_device {
u32 page_fault_cnt;
struct kbase_csf_fw_io fw_io;
u64 compute_progress_timeout_cc;
u64 neural_allowed_mask;
u32 num_doorbells;
};

View File

@@ -94,11 +94,11 @@ static void sync_update_notify_gpu(struct kbase_context *kctx)
spin_lock_irqsave(&kctx->kbdev->hwaccess_lock, flags);
can_notify_gpu = kbase_io_is_gpu_powered(kctx->kbdev);
#ifdef KBASE_PM_RUNTIME
if (kctx->kbdev->pm.backend.db_mirror_interrupt_enabled ||
kctx->kbdev->pm.backend.gpu_sleep_mode_active)
can_notify_gpu = false;
#endif
if (IS_ENABLED(CONFIG_PM)) {
if (kctx->kbdev->pm.backend.db_mirror_interrupt_enabled ||
kctx->kbdev->pm.backend.gpu_sleep_mode_active)
can_notify_gpu = false;
}
if (can_notify_gpu) {

View File

@@ -1,7 +1,7 @@
// SPDX-License-Identifier: GPL-2.0 WITH Linux-syscall-note
/*
*
* (C) COPYRIGHT 2018-2024 ARM Limited. All rights reserved.
* (C) COPYRIGHT 2018-2025 ARM Limited. All rights reserved.
*
* This program is free software and is provided to you under the terms of the
* GNU General Public License version 2 as published by the Free Software
@@ -377,6 +377,15 @@ void kbase_csf_stop_firmware_and_wait(struct kbase_device *kbdev)
kbase_csf_firmware_disable_mcu_wait(kbdev);
}
static void kbasep_hwcnt_init_on_boot(struct kbase_device *kbdev)
{
kbase_hwcnt_backend_csf_on_before_mcu_cold_boot(&kbdev->hwcnt_gpu_iface);
kbase_hwcnt_backend_csf_set_hw_availability(&kbdev->hwcnt_gpu_iface,
kbdev->gpu_props.curr_config.l2_slices,
kbdev->gpu_props.curr_config.shader_present,
kbdev->pm.debug_core_mask);
}
static void wait_for_firmware_boot(struct kbase_device *kbdev)
{
long wait_timeout;
@@ -400,6 +409,8 @@ static void wait_for_firmware_boot(struct kbase_device *kbdev)
wait_timeout);
if (!remaining)
dev_err(kbdev->dev, "Timed out waiting for fw boot completion");
kbase_hwcnt_backend_csf_on_after_mcu_on(&kbdev->hwcnt_gpu_iface);
kbdev->csf.interrupt_received = false;
}
@@ -414,6 +425,8 @@ static void enable_mcu(struct kbase_device *kbdev)
static void boot_csf_firmware(struct kbase_device *kbdev)
{
kbasep_hwcnt_init_on_boot(kbdev);
enable_mcu(kbdev);
wait_for_firmware_boot(kbdev);
@@ -440,6 +453,12 @@ static int wait_ready(struct kbase_device *kbdev)
if (!err)
return 0;
/* Bailout on GPU_LOST without RESET */
if (err == -ENODEV) {
dev_warn(kbdev->dev, "%s: AW removed, bailing out", __func__);
return 0;
}
dev_err(kbdev->dev,
"AS_ACTIVE bit stuck for MCU AS. Might be caused by unstable GPU clk/pwr or faulty system");
@@ -835,10 +854,10 @@ retry_alloc:
}
} else {
if (!reuse_pages) {
ret = kbase_mem_pool_alloc_pages(
kbase_mem_pool_group_select(kbdev, KBASE_MEM_GROUP_CSF_FW,
is_small_page),
num_pages_aligned, phys, false, NULL);
ret = kbase_mem_pool_alloc_pages(is_small_page ?
&kbdev->fw_mem_pools.small :
&kbdev->fw_mem_pools.large,
num_pages_aligned, phys, false, NULL);
}
}
@@ -971,10 +990,9 @@ out:
kbase_csf_protected_memory_free(kbdev, pma, num_pages_aligned,
is_small_page);
} else {
kbase_mem_pool_free_pages(
kbase_mem_pool_group_select(kbdev, KBASE_MEM_GROUP_CSF_FW,
is_small_page),
num_pages_aligned, phys, false, false);
kbase_mem_pool_free_pages(is_small_page ? &kbdev->fw_mem_pools.small :
&kbdev->fw_mem_pools.large,
num_pages_aligned, phys, false, false);
}
kfree(phys);
}
@@ -1386,6 +1404,11 @@ static int parse_capabilities(struct kbase_device *kbdev)
else
iface->instr_features = 0;
if (iface->version >= kbase_csf_interface_version(1, 1, 0))
iface->prfcnt_features = shared_info[GLB_PRFCNT_FEATURES / 4];
else
iface->prfcnt_features = 0;
if ((GROUP_CONTROL_0 + (unsigned long)iface->group_num * iface->group_stride) >
(interface->num_pages * PAGE_SIZE)) {
dev_err(kbdev->dev,
@@ -1600,9 +1623,7 @@ static void set_global_request(struct kbase_csf_fw_io *fw_io, u32 const req_mask
kbase_csf_fw_io_global_write_mask(fw_io, GLB_REQ, glb_req, req_mask);
}
static void enable_endpoints_global(struct kbase_csf_fw_io *fw_io,
u64 const shader_core_mask)
static void enable_endpoints_global(struct kbase_csf_fw_io *fw_io, u64 const shader_core_mask)
{
kbase_csf_fw_io_assert_opened(fw_io);
@@ -1905,6 +1926,11 @@ static void global_init(struct kbase_device *const kbdev, u64 core_mask)
kbasep_enable_rtu(kbdev);
/* Update shader core allocation enable mask */
if (kbase_hw_has_feature(kbdev, KBASE_HW_FEATURE_GOV_CORE_MASK_SUPPORT))
if (kbase_io_is_gpu_powered(kbdev))
kbase_reg_write64(kbdev, GPU_GOVERNOR_ENUM(GOV_CORE_MASK),
kbase_pm_ca_get_gov_core_mask(kbdev));
enable_endpoints_global(fw_io, core_mask);
set_shader_poweroff_timer(fw_io);
@@ -1935,6 +1961,13 @@ static void global_init(struct kbase_device *const kbdev, u64 core_mask)
if (kbdev->pm.backend.has_host_pwr_iface)
ack_irq_mask |= GLB_ACK_IRQ_MASK_STATE_MASK;
/* Do not modify PRFCNT bits of GLB_ACK_IRQ_MASK. */
ack_irq_mask |=
(kbase_csf_fw_io_global_input_read(&kbdev->csf.fw_io, GLB_ACK_IRQ_MASK) &
(GLB_ACK_IRQ_MASK_PRFCNT_SAMPLE_MASK | GLB_ACK_IRQ_MASK_PRFCNT_THRESHOLD_MASK |
GLB_ACK_IRQ_MASK_PRFCNT_OVERFLOW_MASK | GLB_ACK_IRQ_MASK_PRFCNT_ENABLE_MASK));
/* Unmask the interrupts */
kbase_csf_fw_io_global_write(fw_io, GLB_ACK_IRQ_MASK, ack_irq_mask);
@@ -1965,14 +1998,32 @@ exit:
*/
static int global_init_on_boot(struct kbase_device *const kbdev)
{
unsigned long flags;
unsigned long flags, scheduler_lock_flags;
u64 core_mask;
int ret = 0;
u32 request_mask = CSF_GLB_REQ_CFG_MASK;
spin_lock_irqsave(&kbdev->hwaccess_lock, flags);
core_mask = kbase_pm_ca_get_core_mask(kbdev);
kbdev->csf.firmware_hctl_core_pwr = kbase_pm_no_mcu_core_pwroff(kbdev);
/* Enable the HWC context for the case of MCU controlling the shader core power.
* HWC context will be left enabled throughout the MCU power cycles, unless
* there is a GPU reset.
*
* In case of GPU reset, HWC needs to be disabled to ensure
* the correct HWC backend functionality. The context then gets reenabled during
* the reboot.
*/
if (!kbdev->csf.firmware_hctl_core_pwr) {
kbase_csf_scheduler_spin_lock(kbdev, &scheduler_lock_flags);
kbase_hwcnt_context_enable(kbdev->hwcnt_gpu_ctx);
kbase_csf_scheduler_spin_unlock(kbdev, scheduler_lock_flags);
kbdev->pm.backend.hwcnt_disabled = false;
kbdev->pm.backend.hwcnt_desired = true;
}
spin_unlock_irqrestore(&kbdev->hwaccess_lock, flags);
global_init(kbdev, core_mask);
@@ -1996,10 +2047,25 @@ static int global_init_on_boot(struct kbase_device *const kbdev)
void kbase_csf_firmware_global_reinit(struct kbase_device *kbdev, u64 core_mask)
{
unsigned long flags;
lockdep_assert_held(&kbdev->hwaccess_lock);
kbdev->csf.glb_init_request_pending = true;
kbdev->csf.firmware_hctl_core_pwr = kbase_pm_no_mcu_core_pwroff(kbdev);
if (!kbdev->csf.firmware_hctl_core_pwr) {
/* The HWC context reenabling is needed if:
* - shader core power control was previously under host.
* - context was disabled when preparing for a GPU reset.
*/
kbdev->pm.backend.hwcnt_desired = true;
if (kbdev->pm.backend.hwcnt_disabled) {
kbase_csf_scheduler_spin_lock(kbdev, &flags);
kbase_hwcnt_context_enable(kbdev->hwcnt_gpu_ctx);
kbase_csf_scheduler_spin_unlock(kbdev, flags);
kbdev->pm.backend.hwcnt_disabled = false;
}
}
global_init(kbdev, core_mask);
}
@@ -2020,9 +2086,6 @@ void kbase_csf_firmware_update_core_attr(struct kbase_device *kbdev, bool update
struct kbase_csf_fw_io *fw_io = &kbdev->csf.fw_io;
unsigned long flags, fw_io_flags;
if (kbase_hw_has_feature(kbdev, KBASE_HW_FEATURE_GOV_CORE_MASK_SUPPORT))
core_mask = U64_MAX;
lockdep_assert_held(&kbdev->hwaccess_lock);
kbase_csf_scheduler_spin_lock(kbdev, &flags);
@@ -2083,6 +2146,7 @@ static void kbase_csf_firmware_reload_worker(struct work_struct *work)
return;
/* Reboot the firmware */
kbase_hwcnt_backend_csf_on_before_mcu_cold_boot(&kbdev->hwcnt_gpu_iface);
spin_lock_irqsave(&kbdev->hwaccess_lock, flags);
kbase_csf_firmware_enable_mcu(kbdev);
spin_unlock_irqrestore(&kbdev->hwaccess_lock, flags);
@@ -2096,9 +2160,13 @@ void kbase_csf_firmware_trigger_reload(struct kbase_device *kbdev)
if (kbdev->csf.firmware_reload_needed) {
kbdev->csf.firmware_reload_needed = false;
/* MCU cold boot requested. */
queue_work(system_wq, &kbdev->csf.firmware_reload_work);
} else {
kbase_csf_firmware_enable_mcu(kbdev);
/* MCU shall not boot while reset is in progress */
if (likely(!kbdev->pm.backend.in_reset))
/* MCU warm boot requested. */
kbase_csf_firmware_enable_mcu(kbdev);
}
}
@@ -2129,6 +2197,11 @@ void kbase_csf_firmware_reload_completed(struct kbase_device *kbdev)
dev_err(kbdev->dev, "Version check failed in firmware reboot.");
KBASE_KTRACE_ADD(kbdev, CSF_FIRMWARE_REBOOT, NULL, 0u);
kbase_hwcnt_backend_csf_set_hw_availability(&kbdev->hwcnt_gpu_iface,
kbdev->gpu_props.curr_config.l2_slices,
kbdev->gpu_props.curr_config.shader_present,
kbdev->pm.debug_core_mask);
kbase_hwcnt_backend_csf_on_after_mcu_on(&kbdev->hwcnt_gpu_iface);
/* Tell MCU state machine to transit to next state */
kbdev->csf.firmware_reloaded = true;
@@ -2419,10 +2492,9 @@ int kbase_csf_firmware_late_init(struct kbase_device *kbdev)
kbdev->csf.gpu_idle_hysteresis_ns = FIRMWARE_IDLE_HYSTERESIS_TIME_NS;
#ifdef KBASE_PM_RUNTIME
if (kbase_pm_gpu_sleep_allowed(kbdev))
if (IS_ENABLED(CONFIG_PM) && kbase_pm_gpu_sleep_allowed(kbdev))
kbdev->csf.gpu_idle_hysteresis_ns /= FIRMWARE_IDLE_HYSTERESIS_GPU_SLEEP_SCALER;
#endif
WARN_ON(!kbdev->csf.gpu_idle_hysteresis_ns);
kbdev->csf.gpu_idle_dur_count =
convert_dur_to_idle_count(kbdev, kbdev->csf.gpu_idle_hysteresis_ns, &no_modifier);
@@ -2751,10 +2823,11 @@ void kbase_csf_firmware_unload_term(struct kbase_device *kbdev)
interface->num_pages_aligned,
interface->is_small_page);
} else {
kbase_mem_pool_free_pages(
kbase_mem_pool_group_select(kbdev, KBASE_MEM_GROUP_CSF_FW,
interface->is_small_page),
interface->num_pages_aligned, interface->phys, true, false);
kbase_mem_pool_free_pages(interface->is_small_page ?
&kbdev->fw_mem_pools.small :
&kbdev->fw_mem_pools.large,
interface->num_pages_aligned,
interface->phys, true, false);
}
kfree(interface->phys);
@@ -3128,7 +3201,6 @@ void kbase_csf_firmware_enable_mcu(struct kbase_device *kbdev)
enable_mcu(kbdev);
}
#ifdef KBASE_PM_RUNTIME
void kbase_csf_firmware_trigger_mcu_sleep(struct kbase_device *kbdev)
{
struct kbase_csf_fw_io *fw_io = &kbdev->csf.fw_io;
@@ -3169,7 +3241,6 @@ bool kbase_csf_firmware_is_mcu_in_sleep(struct kbase_device *kbdev)
}
KBASE_EXPORT_TEST_API(kbase_csf_firmware_is_mcu_in_sleep);
#endif /* KBASE_PM_RUNTIME */
bool kbase_csf_firmware_mcu_halt_req_complete(struct kbase_device *kbdev)
{
@@ -3359,8 +3430,7 @@ int kbase_csf_firmware_mcu_shared_mapping_init(struct kbase_device *kbdev, unsig
if (!page_list)
goto page_list_alloc_error;
ret = kbase_mem_pool_alloc_pages(&kbdev->mem_pools.small[KBASE_MEM_GROUP_CSF_FW], num_pages,
phys, false, NULL);
ret = kbase_mem_pool_alloc_pages(&kbdev->fw_mem_pools.small, num_pages, phys, false, NULL);
if (ret <= 0)
goto phys_mem_pool_alloc_error;
@@ -3408,8 +3478,7 @@ va_region_add_error:
va_region_alloc_error:
vunmap(cpu_addr);
vmap_error:
kbase_mem_pool_free_pages(&kbdev->mem_pools.small[KBASE_MEM_GROUP_CSF_FW], num_pages, phys,
false, false);
kbase_mem_pool_free_pages(&kbdev->fw_mem_pools.small, num_pages, phys, false, false);
phys_mem_pool_alloc_error:
kfree(page_list);
@@ -3441,16 +3510,14 @@ void kbase_csf_firmware_mcu_shared_mapping_term(struct kbase_device *kbdev,
/* This is on module unload path, so the pages can be left uncleared before
* returning them back to kbdev memory pool.
*/
kbase_mem_pool_free_pages(&kbdev->mem_pools.small[KBASE_MEM_GROUP_CSF_FW],
csf_mapping->num_pages, csf_mapping->phys, false, false);
kbase_mem_pool_free_pages(&kbdev->fw_mem_pools.small, csf_mapping->num_pages,
csf_mapping->phys, false, false);
}
vunmap(csf_mapping->cpu_addr);
kfree(csf_mapping->phys);
}
#ifdef KBASE_PM_RUNTIME
void kbase_csf_firmware_soi_update(struct kbase_device *kbdev)
{
struct kbase_csf_scheduler *scheduler = &kbdev->csf.scheduler;
@@ -3592,5 +3659,3 @@ int kbase_csf_firmware_soi_disable_on_scheduler_suspend(struct kbase_device *kbd
return 0;
}
#endif /* KBASE_PM_RUNTIME */

View File

@@ -161,6 +161,7 @@ struct kbase_csf_cmd_stream_group_info {
* CSG capability structures.
* @prfcnt_size: Performance counters size.
* @instr_features: Instrumentation features. (csf >= 1.1.0)
* @prfcnt_features: Performance Counter features.
* @groups: Address of an array of CSG capability structures.
*/
struct kbase_csf_global_iface {
@@ -171,6 +172,7 @@ struct kbase_csf_global_iface {
u32 group_stride;
u32 prfcnt_size;
u32 instr_features;
u32 prfcnt_features;
struct kbase_csf_cmd_stream_group_info *groups;
};
@@ -477,7 +479,6 @@ void kbase_csf_firmware_disable_mcu_wait(struct kbase_device *kbdev);
*/
void kbase_csf_stop_firmware_and_wait(struct kbase_device *kbdev);
#ifdef KBASE_PM_RUNTIME
/**
* kbase_csf_firmware_trigger_mcu_sleep - Send the command to put MCU in sleep
* state.
@@ -496,7 +497,6 @@ void kbase_csf_firmware_trigger_mcu_sleep(struct kbase_device *kbdev);
*/
bool kbase_csf_firmware_is_mcu_in_sleep(struct kbase_device *kbdev);
#endif
/**
* kbase_csf_firmware_trigger_reload() - Trigger the reboot of MCU firmware, for
@@ -812,8 +812,6 @@ int kbase_csf_trigger_firmware_config_update(struct kbase_device *kbdev);
*/
int kbase_csf_firmware_req_core_dump(struct kbase_device *const kbdev);
#ifdef KBASE_PM_RUNTIME
/**
* kbase_csf_firmware_soi_update - Update FW Sleep-on-Idle config
*
@@ -842,7 +840,5 @@ void kbase_csf_firmware_glb_idle_timer_update(struct kbase_device *kbdev);
*/
int kbase_csf_firmware_soi_disable_on_scheduler_suspend(struct kbase_device *kbdev);
#endif /* KBASE_PM_RUNTIME */
#endif
#endif /* _KBASE_CSF_FIRMWARE_H_ */

View File

@@ -221,6 +221,12 @@ static int invent_capabilities(struct kbase_device *kbdev)
iface->group_num = ARRAY_SIZE(interface->csg);
iface->group_stride = 0;
iface->prfcnt_features = 0;
/* Set METATA_SIZE in GLB_PRFCNT_FEATURES. Always equal to one block. */
WARN_ON((KBASE_DUMMY_MODEL_BLOCK_SIZE >> 8) > 0xf);
iface->prfcnt_features |= ((KBASE_DUMMY_MODEL_BLOCK_SIZE >> 8) & 0xf);
iface->groups = kcalloc(iface->group_num, sizeof(*iface->groups), GFP_KERNEL);
if (iface->groups == NULL)
return -ENOMEM;
@@ -584,11 +590,22 @@ static void global_init(struct kbase_device *const kbdev, u64 core_mask)
}
/* Update shader core allocation enable mask */
if (kbase_hw_has_feature(kbdev, KBASE_HW_FEATURE_GOV_CORE_MASK_SUPPORT))
if (kbase_io_is_gpu_powered(kbdev))
kbase_reg_write64(kbdev, GPU_GOVERNOR_ENUM(GOV_CORE_MASK),
kbase_pm_ca_get_gov_core_mask(kbdev));
enable_endpoints_global(fw_io, core_mask);
set_shader_poweroff_timer(fw_io);
set_timeout_global(fw_io, kbase_csf_timeout_get(kbdev));
/* Do not modify PRFCNT bits of GLB_ACK_IRQ_MASK. */
ack_irq_mask |=
(kbase_csf_fw_io_global_input_read(&kbdev->csf.fw_io, GLB_ACK_IRQ_MASK) &
(GLB_ACK_IRQ_MASK_PRFCNT_SAMPLE_MASK | GLB_ACK_IRQ_MASK_PRFCNT_THRESHOLD_MASK |
GLB_ACK_IRQ_MASK_PRFCNT_OVERFLOW_MASK | GLB_ACK_IRQ_MASK_PRFCNT_ENABLE_MASK));
/* Unmask the interrupts */
kbase_csf_fw_io_global_write(fw_io, GLB_ACK_IRQ_MASK, ack_irq_mask);
@@ -610,14 +627,32 @@ exit:
*/
static int global_init_on_boot(struct kbase_device *const kbdev)
{
unsigned long flags;
unsigned long flags, scheduler_lock_flags;
u64 core_mask;
int ret = 0;
u32 request_mask = CSF_GLB_REQ_CFG_MASK;
spin_lock_irqsave(&kbdev->hwaccess_lock, flags);
core_mask = kbase_pm_ca_get_core_mask(kbdev);
kbdev->csf.firmware_hctl_core_pwr = kbase_pm_no_mcu_core_pwroff(kbdev);
/* Enable the HWC context for the case of MCU controlling the shader core power.
* HWC context will be left enabled throughout the MCU power cycles, unless
* there is a GPU reset.
*
* In case of GPU reset, HWC needs to be disabled to ensure
* the correct HWC backend functionality. The context then gets reenabled during
* the reboot.
*/
if (!kbdev->csf.firmware_hctl_core_pwr) {
kbase_csf_scheduler_spin_lock(kbdev, &scheduler_lock_flags);
kbase_hwcnt_context_enable(kbdev->hwcnt_gpu_ctx);
kbase_csf_scheduler_spin_unlock(kbdev, scheduler_lock_flags);
kbdev->pm.backend.hwcnt_disabled = false;
kbdev->pm.backend.hwcnt_desired = true;
}
spin_unlock_irqrestore(&kbdev->hwaccess_lock, flags);
global_init(kbdev, core_mask);
@@ -629,10 +664,25 @@ static int global_init_on_boot(struct kbase_device *const kbdev)
void kbase_csf_firmware_global_reinit(struct kbase_device *kbdev, u64 core_mask)
{
unsigned long flags;
lockdep_assert_held(&kbdev->hwaccess_lock);
kbdev->csf.glb_init_request_pending = true;
kbdev->csf.firmware_hctl_core_pwr = kbase_pm_no_mcu_core_pwroff(kbdev);
if (!kbdev->csf.firmware_hctl_core_pwr) {
/* The HWC context reenabling is needed if:
* - shader core power control was previously under host.
* - context was disabled when preparing for a GPU reset.
*/
kbdev->pm.backend.hwcnt_desired = true;
if (kbdev->pm.backend.hwcnt_disabled) {
kbase_csf_scheduler_spin_lock(kbdev, &flags);
kbase_hwcnt_context_enable(kbdev->hwcnt_gpu_ctx);
kbase_csf_scheduler_spin_unlock(kbdev, flags);
kbdev->pm.backend.hwcnt_disabled = false;
}
}
global_init(kbdev, core_mask);
}
@@ -653,9 +703,6 @@ void kbase_csf_firmware_update_core_attr(struct kbase_device *kbdev, bool update
struct kbase_csf_fw_io *fw_io = &kbdev->csf.fw_io;
unsigned long flags, fw_io_flags;
if (kbase_hw_has_feature(kbdev, KBASE_HW_FEATURE_GOV_CORE_MASK_SUPPORT))
core_mask = U64_MAX;
lockdep_assert_held(&kbdev->hwaccess_lock);
kbase_csf_scheduler_spin_lock(kbdev, &flags);
@@ -688,10 +735,16 @@ static void kbase_csf_firmware_reload_worker(struct work_struct *work)
container_of(work, struct kbase_device, csf.firmware_reload_work);
unsigned long flags;
kbase_hwcnt_backend_csf_on_before_mcu_cold_boot(&kbdev->hwcnt_gpu_iface);
spin_lock_irqsave(&kbdev->hwaccess_lock, flags);
/* Reboot the firmware */
kbase_csf_firmware_enable_mcu(kbdev);
kbase_hwcnt_backend_csf_set_hw_availability(&kbdev->hwcnt_gpu_iface,
kbdev->gpu_props.curr_config.l2_slices,
kbdev->gpu_props.curr_config.shader_present,
kbdev->pm.debug_core_mask);
kbase_hwcnt_backend_csf_on_after_mcu_on(&kbdev->hwcnt_gpu_iface);
/* Tell MCU state machine to transit to next state */
kbdev->csf.firmware_reloaded = true;
kbase_pm_update_state(kbdev);
@@ -709,6 +762,10 @@ void kbase_csf_firmware_trigger_reload(struct kbase_device *kbdev)
queue_work(system_wq, &kbdev->csf.firmware_reload_work);
} else {
kbase_csf_firmware_enable_mcu(kbdev);
kbase_hwcnt_backend_csf_set_hw_availability(
&kbdev->hwcnt_gpu_iface, kbdev->gpu_props.curr_config.l2_slices,
kbdev->gpu_props.curr_config.shader_present, kbdev->pm.debug_core_mask);
kbase_hwcnt_backend_csf_on_after_mcu_on(&kbdev->hwcnt_gpu_iface);
kbdev->csf.firmware_reloaded = true;
}
}
@@ -721,7 +778,11 @@ void kbase_csf_firmware_reload_completed(struct kbase_device *kbdev)
if (unlikely(!kbdev->csf.firmware_inited))
return;
kbase_hwcnt_backend_csf_set_hw_availability(&kbdev->hwcnt_gpu_iface,
kbdev->gpu_props.curr_config.l2_slices,
kbdev->gpu_props.curr_config.shader_present,
kbdev->pm.debug_core_mask);
kbase_hwcnt_backend_csf_on_after_mcu_on(&kbdev->hwcnt_gpu_iface);
/* Tell MCU state machine to transit to next state */
kbdev->csf.firmware_reloaded = true;
kbase_pm_update_state(kbdev);
@@ -955,6 +1016,15 @@ u32 kbase_csf_firmware_reset_mcu_core_pwroff_time(struct kbase_device *kbdev)
return kbase_csf_firmware_set_mcu_core_pwroff_time(kbdev, DEFAULT_GLB_PWROFF_TIMEOUT_NS);
}
static void kbasep_hwcnt_init_on_boot(struct kbase_device *kbdev)
{
kbase_hwcnt_backend_csf_on_before_mcu_cold_boot(&kbdev->hwcnt_gpu_iface);
kbase_hwcnt_backend_csf_set_hw_availability(&kbdev->hwcnt_gpu_iface,
kbdev->gpu_props.curr_config.l2_slices,
kbdev->gpu_props.curr_config.shader_present,
kbdev->pm.debug_core_mask);
}
int kbase_csf_firmware_early_init(struct kbase_device *kbdev)
{
kbdev->csf.num_doorbells = CSF_NUM_DOORBELL_MAX;
@@ -987,10 +1057,9 @@ int kbase_csf_firmware_late_init(struct kbase_device *kbdev)
u32 no_modifier = 0;
kbdev->csf.gpu_idle_hysteresis_ns = FIRMWARE_IDLE_HYSTERESIS_TIME_NS;
#ifdef KBASE_PM_RUNTIME
if (kbase_pm_gpu_sleep_allowed(kbdev))
if (IS_ENABLED(CONFIG_PM) && kbase_pm_gpu_sleep_allowed(kbdev))
kbdev->csf.gpu_idle_hysteresis_ns /= FIRMWARE_IDLE_HYSTERESIS_GPU_SLEEP_SCALER;
#endif
WARN_ON(!kbdev->csf.gpu_idle_hysteresis_ns);
kbdev->csf.gpu_idle_dur_count =
convert_dur_to_idle_count(kbdev, kbdev->csf.gpu_idle_hysteresis_ns, &no_modifier);
@@ -1041,6 +1110,8 @@ int kbase_csf_firmware_load_init(struct kbase_device *kbdev)
kbase_csf_fw_io_init(&kbdev->csf.fw_io, kbdev);
kbasep_hwcnt_init_on_boot(kbdev);
ret = invent_capabilities(kbdev);
if (ret != 0)
goto error;
@@ -1273,7 +1344,6 @@ void kbase_csf_firmware_enable_mcu(struct kbase_device *kbdev)
kbase_reg_write32(kbdev, GPU_CONTROL_ENUM(MCU_CONTROL), MCU_CONTROL_REQ_AUTO);
}
#ifdef KBASE_PM_RUNTIME
void kbase_csf_firmware_trigger_mcu_sleep(struct kbase_device *kbdev)
{
struct kbase_csf_fw_io *fw_io = &kbdev->csf.fw_io;
@@ -1299,7 +1369,6 @@ bool kbase_csf_firmware_is_mcu_in_sleep(struct kbase_device *kbdev)
kbase_csf_firmware_mcu_halted(kbdev));
}
#endif
bool kbase_csf_firmware_mcu_halt_req_complete(struct kbase_device *kbdev)
{
@@ -1467,8 +1536,7 @@ int kbase_csf_firmware_mcu_shared_mapping_init(struct kbase_device *kbdev, unsig
if (!page_list)
goto page_list_alloc_error;
ret = kbase_mem_pool_alloc_pages(&kbdev->mem_pools.small[KBASE_MEM_GROUP_CSF_FW], num_pages,
phys, false, NULL);
ret = kbase_mem_pool_alloc_pages(&kbdev->fw_mem_pools.small, num_pages, phys, false, NULL);
if (ret <= 0)
goto phys_mem_pool_alloc_error;
@@ -1516,8 +1584,7 @@ va_region_add_error:
va_region_alloc_error:
vunmap(cpu_addr);
vmap_error:
kbase_mem_pool_free_pages(&kbdev->mem_pools.small[KBASE_MEM_GROUP_CSF_FW], num_pages, phys,
false, false);
kbase_mem_pool_free_pages(&kbdev->fw_mem_pools.small, num_pages, phys, false, false);
phys_mem_pool_alloc_error:
kfree(page_list);
@@ -1546,16 +1613,14 @@ void kbase_csf_firmware_mcu_shared_mapping_term(struct kbase_device *kbdev,
}
if (csf_mapping->phys) {
kbase_mem_pool_free_pages(&kbdev->mem_pools.small[KBASE_MEM_GROUP_CSF_FW],
csf_mapping->num_pages, csf_mapping->phys, false, false);
kbase_mem_pool_free_pages(&kbdev->fw_mem_pools.small, csf_mapping->num_pages,
csf_mapping->phys, false, false);
}
vunmap(csf_mapping->cpu_addr);
kfree(csf_mapping->phys);
}
#ifdef KBASE_PM_RUNTIME
void kbase_csf_firmware_soi_update(struct kbase_device *kbdev)
{
}
@@ -1568,5 +1633,3 @@ int kbase_csf_firmware_soi_disable_on_scheduler_suspend(struct kbase_device *kbd
{
return 0;
}
#endif /* KBASE_PM_RUNTIME */

View File

@@ -22,7 +22,6 @@
#include "mali_kbase.h"
#include "mali_kbase_csf_fw_io.h"
#include <mali_kbase_linux.h>
#include "mali_kbase_io.h"
#include <linux/mutex.h>
static inline u32 input_page_read(const u32 *const input, const u32 offset)
@@ -89,7 +88,7 @@ static inline void input_page_partial_write64(u64 *const input, const u32 offset
void kbase_csf_fw_io_init(struct kbase_csf_fw_io *fw_io, struct kbase_device *kbdev)
{
spin_lock_init(&fw_io->lock);
kbase_io_clear_status(kbdev->io, KBASE_IO_STATUS_GPU_SUSPENDED);
bitmap_zero(fw_io->status, KBASEP_FW_IO_STATUS_NUM_BITS);
fw_io->kbdev = kbdev;
}
KBASE_EXPORT_TEST_API(kbase_csf_fw_io_init);
@@ -358,19 +357,19 @@ KBASE_EXPORT_TEST_API(kbase_csf_fw_io_stream_read);
void kbase_csf_fw_io_set_status_gpu_suspended(struct kbase_csf_fw_io *fw_io)
{
kbase_io_set_status(fw_io->kbdev->io, KBASE_IO_STATUS_GPU_SUSPENDED);
set_bit(KBASEP_FW_IO_STATUS_GPU_SUSPENDED, fw_io->status);
}
KBASE_EXPORT_TEST_API(kbase_csf_fw_io_set_status_gpu_suspended);
void kbase_csf_fw_io_clear_status_gpu_suspended(struct kbase_csf_fw_io *fw_io)
{
kbase_io_clear_status(fw_io->kbdev->io, KBASE_IO_STATUS_GPU_SUSPENDED);
clear_bit(KBASEP_FW_IO_STATUS_GPU_SUSPENDED, fw_io->status);
}
KBASE_EXPORT_TEST_API(kbase_csf_fw_io_clear_status_gpu_suspended);
bool kbase_csf_fw_io_check_status_gpu_suspended(struct kbase_csf_fw_io *fw_io)
{
return kbase_io_test_status(fw_io->kbdev, KBASE_IO_STATUS_GPU_SUSPENDED);
return test_bit(KBASEP_FW_IO_STATUS_GPU_SUSPENDED, fw_io->status);
}
KBASE_EXPORT_TEST_API(kbase_csf_fw_io_check_status_gpu_suspended);

View File

@@ -31,6 +31,17 @@
/** The wait completed because the GPU was lost. */
#define KBASE_CSF_FW_IO_WAIT_GPU_LOST 1
/**
* enum kbasep_csf_fw_io_status_bits - Status bits for firmware I/O interface.
*
* @KBASEP_FW_IO_STATUS_GPU_SUSPENDED: The GPU is suspended.
* @KBASEP_FW_IO_STATUS_NUM_BITS: Number of bits used to encode the status.
*/
enum kbasep_csf_fw_io_status_bits {
KBASEP_FW_IO_STATUS_GPU_SUSPENDED = 0,
KBASEP_FW_IO_STATUS_NUM_BITS,
};
/**
* struct kbasep_csf_fw_io_stream_pages - Addresses to CS I/O pages.
*
@@ -72,11 +83,13 @@ struct kbasep_csf_fw_io_pages {
* struct kbase_csf_fw_io - Manager of firmware input/output interface.
*
* @lock: Mutex to serialize access to the interface.
* @status: Internal status of the MCU interface.
* @pages: Addresses to FW I/O pages
* @kbdev: Pointer to the instance of a GPU platform device that implements a CSF interface.
*/
struct kbase_csf_fw_io {
spinlock_t lock;
DECLARE_BITMAP(status, KBASEP_FW_IO_STATUS_NUM_BITS);
struct kbasep_csf_fw_io_pages pages;
struct kbase_device *kbdev;
};
@@ -169,7 +182,8 @@ void kbase_csf_fw_io_pages_term(struct kbase_csf_fw_io *fw_io, u32 group_num);
*/
static inline int kbase_csf_fw_io_open(struct kbase_csf_fw_io *fw_io, unsigned long *flags)
{
if (kbase_io_test_status(fw_io->kbdev, KBASE_IO_STATUS_GPU_SUSPENDED))
if (test_bit(KBASEP_FW_IO_STATUS_GPU_SUSPENDED, fw_io->status) ||
kbase_io_is_aw_removed(fw_io->kbdev))
return -KBASE_CSF_FW_IO_WAIT_GPU_LOST;
spin_lock_irqsave(&fw_io->lock, *flags);
@@ -410,8 +424,8 @@ bool kbase_csf_fw_io_check_status_gpu_suspended(struct kbase_csf_fw_io *fw_io);
/**
* kbase_csf_fw_io_wait_event_timeout() - Wait until condition gets true, timeout
* occurs or a GPU_SUSPENDED FW I/O status bit is set. The rest of the functionalities is equal
* to wait_event_timeout().
* occurs, GPU_SUSPENDED FW I/O status bit is set, or AW was removed.
* The rest of the functionalities is equal to wait_event_timeout().
*
* @fw_io: Firmware I/O manager.
* @wq_head: The waitqueue to wait on.
@@ -420,16 +434,20 @@ bool kbase_csf_fw_io_check_status_gpu_suspended(struct kbase_csf_fw_io *fw_io);
*
* Return: Remaining jiffies (at least 1) on success,
* 0 on timeout,
* negative KBASE_CSF_FW_IO_WAIT_LOST error if GPU_SUSPENDED FW I/O status bit is set.
* negative KBASE_CSF_FW_IO_WAIT_LOST error
* if GPU_SUSPENDED FW I/O status bit is set
* or AW was removed.
*/
#define kbase_csf_fw_io_wait_event_timeout(fw_io, wq_head, condition, timeout) \
({ \
int __ret; \
int __wait_remaining = wait_event_timeout( \
wq_head, (condition) || kbase_csf_fw_io_check_status_gpu_suspended(fw_io), \
timeout); \
__ret = kbasep_csf_fw_io_handle_wait_result(fw_io, __wait_remaining); \
__ret; \
#define kbase_csf_fw_io_wait_event_timeout(fw_io, wq_head, condition, timeout) \
({ \
int __ret; \
int __wait_remaining = wait_event_timeout( \
wq_head, \
(condition) || kbase_csf_fw_io_check_status_gpu_suspended(fw_io) || \
kbase_io_is_aw_removed((fw_io)->kbdev), \
timeout); \
__ret = kbasep_csf_fw_io_handle_wait_result(fw_io, __wait_remaining); \
__ret; \
})
/**
@@ -441,13 +459,17 @@ bool kbase_csf_fw_io_check_status_gpu_suspended(struct kbase_csf_fw_io *fw_io);
*
* Return: Remaining jiffies (at least 1) on success,
* 0 on timeout,
* negative KBASE_CSF_FW_IO_WAIT_LOST error if GPU_SUSPENDED FW I/O status bit is set.
* negative KBASE_CSF_FW_IO_WAIT_LOST error
* if GPU_SUSPENDED FW I/O status bit is set
* or AW was removed.
*/
static inline int kbasep_csf_fw_io_handle_wait_result(struct kbase_csf_fw_io *fw_io,
int wait_remaining)
{
return kbase_csf_fw_io_check_status_gpu_suspended(fw_io) ? -KBASE_CSF_FW_IO_WAIT_GPU_LOST :
wait_remaining;
return (kbase_csf_fw_io_check_status_gpu_suspended(fw_io) ||
kbase_io_is_aw_removed(fw_io->kbdev)) ?
-KBASE_CSF_FW_IO_WAIT_GPU_LOST :
wait_remaining;
}
#if IS_ENABLED(CONFIG_MALI_VALHALL_DEBUG) || IS_ENABLED(CONFIG_MALI_VALHALL_NO_MALI)

View File

@@ -87,7 +87,7 @@ static inline void input_page_partial_write64(u64 *const input, const u32 offset
void kbase_csf_fw_io_init(struct kbase_csf_fw_io *fw_io, struct kbase_device *kbdev)
{
spin_lock_init(&fw_io->lock);
kbase_io_clear_status(kbdev->io, KBASE_IO_STATUS_GPU_SUSPENDED);
bitmap_zero(fw_io->status, KBASEP_FW_IO_STATUS_NUM_BITS);
fw_io->kbdev = kbdev;
}
KBASE_EXPORT_TEST_API(kbase_csf_fw_io_init);
@@ -393,19 +393,19 @@ KBASE_EXPORT_TEST_API(kbase_csf_fw_io_stream_read);
void kbase_csf_fw_io_set_status_gpu_suspended(struct kbase_csf_fw_io *fw_io)
{
kbase_io_set_status(fw_io->kbdev->io, KBASE_IO_STATUS_GPU_SUSPENDED);
set_bit(KBASEP_FW_IO_STATUS_GPU_SUSPENDED, fw_io->status);
}
KBASE_EXPORT_TEST_API(kbase_csf_fw_io_set_status_gpu_suspended);
void kbase_csf_fw_io_clear_status_gpu_suspended(struct kbase_csf_fw_io *fw_io)
{
kbase_io_clear_status(fw_io->kbdev->io, KBASE_IO_STATUS_GPU_SUSPENDED);
clear_bit(KBASEP_FW_IO_STATUS_GPU_SUSPENDED, fw_io->status);
}
KBASE_EXPORT_TEST_API(kbase_csf_fw_io_clear_status_gpu_suspended);
bool kbase_csf_fw_io_check_status_gpu_suspended(struct kbase_csf_fw_io *fw_io)
{
return kbase_io_test_status(fw_io->kbdev, KBASE_IO_STATUS_GPU_SUSPENDED);
return test_bit(KBASEP_FW_IO_STATUS_GPU_SUSPENDED, fw_io->status);
}
KBASE_EXPORT_TEST_API(kbase_csf_fw_io_check_status_gpu_suspended);

View File

@@ -1664,7 +1664,7 @@ static int kbase_kcpu_fence_force_signal_process(struct kbase_kcpu_command_queue
#endif
/* dma_fence refcount needs to be decreased to release it. */
dma_fence_put(fence_info->fence);
kbase_fence_put(fence_info->fence);
fence_info->fence = NULL;
return ret;
@@ -1700,6 +1700,7 @@ static void kcpu_force_signal_fence(struct kbase_kcpu_command_queue *kcpu_queue)
/* set ETIMEDOUT error flag before signal the fence*/
dma_fence_set_error_helper(fence, -ETIMEDOUT);
kbase_fence_put(fence);
/* force signal fence */
status =
@@ -1860,6 +1861,8 @@ static int kbasep_kcpu_fence_signal_init(struct kbase_kcpu_command_queue *kcpu_q
goto fd_flags_fail;
}
__module_get(THIS_MODULE);
kcpu_fence->module = THIS_MODULE;
fence->basep.fd = *fd;
current_command->type = BASE_KCPU_COMMAND_TYPE_FENCE_SIGNAL;

View File

@@ -1,7 +1,7 @@
/* SPDX-License-Identifier: GPL-2.0 WITH Linux-syscall-note */
/*
*
* (C) COPYRIGHT 2018-2023 ARM Limited. All rights reserved.
* (C) COPYRIGHT 2018-2024 ARM Limited. All rights reserved.
*
* This program is free software and is provided to you under the terms of the
* GNU General Public License version 2 as published by the Free Software

Some files were not shown because too many files have changed in this diff Show More