Compare commits

..

5 Commits

Author SHA1 Message Date
Mohan Kumar
4212fbd97f ASoC: tegra: avoid enabling aud_mclk during init
Enabling the aud_mclk clock during initialization of drivers
was done for T30 chip due to some external dependencies, now
it is not required for latest version of chips and also due
to this aud_mclk is kept always ON. Add check to avoid enabling
aud_mclk clock other than T30

Bug 4373898

Change-Id: If341b1b73051c5572c5551bf6d4659fab7a116d2
Signed-off-by: Mohan Kumar <mkumard@nvidia.com>
Reviewed-on: https://git-master.nvidia.com/r/c/linux-nv-oot/+/3015891
(cherry picked from commit 7ffd0c9cfa)
Reviewed-on: https://git-master.nvidia.com/r/c/linux-nv-oot/+/3019203
Reviewed-by: Amulya Yarlagadda <ayarlagadda@nvidia.com>
GVS: Gerrit_Virtual_Submit <buildbot_gerritrpt@nvidia.com>
2023-11-22 13:02:29 -08:00
Praveen AC
4e63d195c6 drivers:media: Fix imx390 & imx185 probe issue.
Due to "mingain - 1" & "minexp - 1" during probe time observing
out of range whenever gain or exp is set "0" as min in DT.
Instead doing "maxgain + 1" & "maxexp + 1" to fix the probe.

Bug 4142996
Bug 4189361
Bug 4386912

Change-Id: I103e87b293079dadcd16b91f8e329ec9f938208c
Reviewed-on: https://git-master.nvidia.com/r/c/linux-nv-oot/+/3020349
Tested-by: Praveen AC <pac@nvidia.com>
Reviewed-by: Praveen AC <pac@nvidia.com>
Reviewed-by: Narendra Kondapalli <nkondapalli@nvidia.com>
Reviewed-by: Ankur Pawar <ankurp@nvidia.com>
Reviewed-by: Anubhav Rai <arai@nvidia.com>
Reviewed-by: Amulya Yarlagadda <ayarlagadda@nvidia.com>
GVS: Gerrit_Virtual_Submit <buildbot_gerritrpt@nvidia.com>
2023-11-22 10:18:55 -08:00
Yi-Wei Wang
4ad0e0c6c8 thermal: add thermal trip event cooling device
This change adds a cooling device driver to notify the user space of the
thermal trip event. To avoid having user space process poll the
cooling state, a sysfs node is exposed that supports blocking reads.
The driver also supports a timeout (in milliseconds) for blocking reads
which can be done by writing the value to thermal_trip_event_block node
before reading. The blocked user space process will be woken up when the
cooling device becomes active or times out.

Bug 4261645
Bug 1688327

Signed-off-by: Yi-Wei Wang <yiweiw@nvidia.com>
Change-Id: Ic89406ba2713e5bc8f3806d6cfeb462601c73a7d
Reviewed-on: https://git-master.nvidia.com/r/c/linux-nv-oot/+/3015652
(cherry picked from commit 856471d64f)
Reviewed-on: https://git-master.nvidia.com/r/c/linux-nv-oot/+/3019213
Reviewed-by: Laxman Dewangan <ldewangan@nvidia.com>
GVS: Gerrit_Virtual_Submit <buildbot_gerritrpt@nvidia.com>
2023-11-21 12:24:53 -08:00
Anubhav Rai
969619a872 camera: lt6911uxc update with Shadow EDID
Update the Lontium driver to flash shadow EDID
to lt6911uxc chip. This will ensure that the requested
resolution through the application is flashed to the
chip and the source is forced to select the
requested resolution only.

bug 4266018
bug 4301203
bug 4168489
Signed-off-by: Anubhav Rai <arai@nvidia.com>

Change-Id: I945a9658b52c82956535f3710312d317c0098be7
Reviewed-on: https://git-master.nvidia.com/r/c/linux-nv-oot/+/3007702
(cherry picked from commit c3ddb23392)
Reviewed-on: https://git-master.nvidia.com/r/c/linux-nv-oot/+/3016371
Tested-by: Anubhav Rai <arai@nvidia.com>
Reviewed-by: Anubhav Rai <arai@nvidia.com>
Reviewed-by: Amulya Yarlagadda <ayarlagadda@nvidia.com>
2023-11-16 21:15:37 -08:00
Gautham Srinivasan
ad7508c52a drivers: aon: Add AON Echo driver
Add AON echo driver. This driver creates data_channel file in sysfs
which is used to communicate between CCPLEX and AON.

Bug 4296173

Change-Id: Id790fc4076205e16509611f7fa07ffc073491227
Signed-off-by: Gautham Srinivasan <gauthams@nvidia.com>
Reviewed-on: https://git-master.nvidia.com/r/c/linux-nv-oot/+/2954202
(cherry picked from commit 66c26d1ac3)
Reviewed-on: https://git-master.nvidia.com/r/c/linux-nv-oot/+/3015993
Reviewed-by: Amulya Yarlagadda <ayarlagadda@nvidia.com>
Tested-by: Amulya Yarlagadda <ayarlagadda@nvidia.com>
2023-11-14 20:48:17 -08:00
649 changed files with 80541 additions and 234194 deletions

View File

@@ -5,24 +5,19 @@ correlation feature.
Required properties:
- compatible: This should be nvidia,tegra194-nvpps for Xavier and nvidia,tegra234-nvpps for Orin.
- compatibles: should be "nvpps,tegra194-nvpps"
Optional properties:
- primary-emac: specifies ethernet emac device DT. This is the primary ethernet MAC device utilized
to calculate PTP time. For example, if MGBE0 is used to calculate the PTP time,
then phandle of the device tree node corresponding to MGBE0 needs to be passed.
For Example for Orin:
mgbe0: ethernet@6800000
eqos: ethernet@2310000
For Example for Xavier:
eqos: ethernet@2490000
- sec-emac: specifies secondary ethernet MAC device DT node to be used to calculate PTP time.
- gpios: GPIO number and active level for the PPS input signal
- memmap_phc_regs: boolean flag to indicate MAC PHC regs to be memory mapped
for getting PTP time. If not defined ptp notifer method will
be used with selected interface
- interface: NW interface name to be used for MAC PHC regs. This field can be
set to 'eqos_0', 'mgbe0_0', 'mgbe1_0', 'mgbe2_0' or 'mgbe3_0' for Orin.
For Xavier, it shoud be set to 'eqos_0'. If undef, default to 'eqos_0'
- sec_interface: NW interface name to be used to calculate PTP Time offset.
set to 'eqos_0', 'mgbe0_0', 'mgbe1_0', 'mgbe2_0' or 'mgbe3_0' for Orin.
For Xavier, Leave this undefined. For Orin, If undef default to 'eqos_0'
- ptp_tsc_k_int: Specifies the integer part of the factor used to calculate the delta to
apply to NUM when the fast convergence algorithm is enabled when syncing
or locking TSC time with PTP time domain.
@@ -36,78 +31,42 @@ Optional properties:
If unspecified, NvPPS driver uses 0x26C(corresponding to 20us) by default
- ptp_tsc_sync_dis: boolean flag to indicate if nvpps should disable PTP TSC sync logic.
The default behaviour is to keep PTP TSC sync logic enabled.
- reg: specifies start address and registers count details of TSC module. It is only applicable for Orin.
- nvpps-gpios: specifies GPIO number for PPS input signal.
- timestamps: specifies timestamp for the GPIO provided by HTE.
- timestamp-names: specifies name for GPIO timestamp.
Example: Timer mode on Orin.
mgbe0: ethernet@6800000{
};
Example:
nvpps {
compatible = "nvidia,tegrat194-nvpps";
status = "okay";
compatible = "nvidia,tegra234-nvpps";
primary-emac = <&mgbe0>;
sec-emac = <&mgbe0>;
reg = <0x0 0xc6a0000 0x0 0x1000>;
gpios = <&tegra_aon_gpio TEGRA194_AON_GPIO(BB, 2) GPIO_ACTIVE_HIGH>;
};
Example: Timer mode on Xavier
eqos: ethernet@2490000{
};
Example:
nvpps {
status = "okay";
compatible = "nvidia,tegra194-nvpps";
primary-emac = <&eqos>;
sec-emac = <&eqos>;
};
Example: MAC PHC regs to be memory mapped on Orin
mgbe0: ethernet@6800000{
};
nvpps {
status = "okay";
compatible = "nvidia,tegra234-nvpps";
primary-emac = <&mgbe0>
sec-emac = <&mgbe0>;
gpios = <&tegra_aon_gpio TEGRA234_AON_GPIO(EE, 6) GPIO_ACTIVE_HIGH>;
memmap_phc_regs;
reg = <0x0 0xc6a0000 0x0 0x1000>;
interface = "mgbe2_0";
};
Example: GPIO mode on Orin
mgbe0: ethernet@6800000{
};
Example:
nvpps {
compatible = "nvidia,tegra194-nvpps";
status = "okay";
compatible = "nvidia,tegra234-nvpps";
reg = <0x0 0xc6a0000 0x0 0x1000>;
nvpps-gpios = <&gpio_aon TEGRA234_AON_GPIO(BB, 0) GPIO_ACTIVE_HIGH>;
timestamps = <&hte_aon TEGRA234_AON_GPIO(BB, 0)>;
timestamp-names = "nvpps_gpio";
};
Example: Timer mode on Orin with additional properties.
mgbe0: ethernet@6800000{
};
nvpps {
status = "okay";
compatible = "nvidia,tegra234-nvpps";
primary-emac = <&mgbe0>;
sec-emac = <&mgbe0>;
reg = <0x0 0xc6a0000 0x0 0x1000>;
gpios = <&tegra_aon_gpio TEGRA234_AON_GPIO(EE, 6) GPIO_ACTIVE_HIGH>;
interface = "mgbe2_0";
sec_interface = "eqos_0";
ptp_tsc_k_int = /bits/ 8 <0x70>;
ptp_tsc_lock_threshold = /bits/ 16 <0x26C>;
ptp_tsc_sync_dis;
};
Example: GPIO as optional
nvpps {
compatible = "nvidia,tegra194-nvpps";
status = "okay";
interface = "mgbe2_0";
};

View File

@@ -1,11 +1,67 @@
# SPDX-License-Identifier: GPL-2.0
# Copyright (c) 2022-2024, NVIDIA CORPORATION. All rights reserved.
# Copyright (c) 2022-2023, NVIDIA CORPORATION. All rights reserved.
LINUXINCLUDE += -I$(srctree.nvconftest)
LINUXINCLUDE += -I$(srctree.nvidia-oot)/include
subdir-ccflags-y += -Werror
subdir-ccflags-y += -Wmissing-prototypes
LINUX_VERSION := $(shell expr $(VERSION) \* 256 + $(PATCHLEVEL))
LINUX_VERSION_6_2 := $(shell expr 6 \* 256 + 2)
LINUX_VERSION_6_3 := $(shell expr 6 \* 256 + 3)
LINUX_VERSION_6_6 := $(shell expr 6 \* 256 + 6)
# The Tegra IVC driver was updated to support iosys-map in Linux v6.2.
# For Linux v6.2 kernels, don't build any drivers that requires this.
ifeq ($(shell test $(LINUX_VERSION) -ge $(LINUX_VERSION_6_2); echo $$?),0)
export CONFIG_TEGRA_IVC_LEGACY_DISABLE=y
endif
ifeq ($(CONFIG_TEGRA_IVC_LEGACY_DISABLE),y)
subdir-ccflags-y += -DCONFIG_TEGRA_IVC_LEGACY_DISABLE
endif
# Legacy GPIO support is removed in Linux v6.3
ifeq ($(shell test $(LINUX_VERSION) -ge $(LINUX_VERSION_6_3); echo $$?),0)
export CONFIG_TEGRA_GPIO_LEGACY_DISABLE=y
endif
# Changes done in Linux 6.6 onwards
ifeq ($(shell test $(LINUX_VERSION) -ge $(LINUX_VERSION_6_6); echo $$?),0)
# Move probe to DAI Ops.
export CONFIG_SND_SOC_MOVE_DAI_PROBE_TO_OPS=y
subdir-ccflags-y += -DNV_SND_SOC_DAI_OPS_STRUCT_HAS_PROBE_ARG
# probe_new is removed from i2c driver structure
subdir-ccflags-y += -DNV_I2C_LEGACY_PROBE_NEW_REMOVED
# API changes to replace u8 with unsigned char
subdir-ccflags-y += -DNV_TTY_SERIAL_TYPE_U8_CHANGE
# v4l2_async_subdev is renamed to v4l2_async_connection.
subdir-ccflags-y += -DNV_V4L2_ASYNC_SUBDEV_RENAME
# Rename V4L2_ASYNC_MATCH_FWNODE to V4L2_ASYNC_MATCH_TYPE_FWNODE
subdir-ccflags-y += -DNV_V4L2_ASYNC_MATCH_FWNODE_RENAME
# Rename async_nf_init and v4l2_async_subdev_nf_register
subdir-ccflags-y += -DNV_V4L2_ASYNC_NF_SUBDEVICE_INIT_RENAME
# Deprecate PCIED Error reporting pci_enable_pcie_error_reporting
subdir-ccflags-y += -DNV_DROP_PCIE_ERROR_REPORTING
# Split types and declaration of net/page_pool.h
subdir-ccflags-y += -DNV_SPLIT_PAGE_POOL_HEADER
# Unexport helpers for fd/handle conversion
subdir-ccflags-y += -DNV_UNEXPORT_FD_HANDLE_CONVERSION
# FB Deferred IO helpers name alignment
subdir-ccflags-y += -DNV_FB_DEFERRED_IO_OPS_RENAME
# Crypto driver has major change in it ops, skip it
export CONFIG_SKIP_CRYPTO=y
endif
ifeq ($(CONFIG_TEGRA_VIRTUALIZATION),y)
subdir-ccflags-y += -DCONFIG_TEGRA_VIRTUALIZATION

View File

@@ -0,0 +1,41 @@
# SPDX-License-Identifier: GPL-2.0
# Copyright (c) 2022, NVIDIA CORPORATION. All rights reserved.
objtree = $(srctree)
# Redefine the fixdep command
cmd_and_fixdep = \
$(cmd); \
$(objtree)/scripts/basic/fixdep $(depfile) $@ '$(make-cmd)' > $(dot-target).cmd;\
rm -f $(depfile)
include $(oottree)/scripts/Makefile.lib
oot-dtstree = $(oottree)/arch/arm64/boot/dts/nvidia
DTB_LIST := $(dtb-y)
DTBO_LIST := $(dtbo-y)
dtb-y :=
dts_makefile=$(foreach d,$(wildcard $1*), $(call dts_makefile,$(d)/,$(2)) $(if $(findstring Makefile,$(d)),$(d)))
dts_mfiles = $(call dts_makefile, $(oot-dtstree), Makefile)
ifneq ($(dts_mfiles),)
dts-include :=
include $(dts_mfiles)
dtb-y := $(addprefix nvidia/,$(dtb-y))
dtbo-y := $(addprefix nvidia/,$(dtbo-y))
endif
DTC_INCLUDE := $(oottree)/include
DTB_LIST += $(dtb-y)
DTBO_LIST += $(dtbo-y)
DTB_OBJS := $(addprefix $(obj)/,$(DTB_LIST))
DTBO_OBJS := $(addprefix $(obj)/,$(DTBO_LIST))
dtbs: $(DTB_OBJS) $(DTBO_OBJS) FORCE
dtbsclean:
find $(oot-dtstree) -name *.dtb | xargs rm -rf
find $(oot-dtstree) -name *.dtbo | xargs rm -rf
find $(oot-dtstree) -name *.tmp | xargs rm -rf

View File

@@ -0,0 +1,9 @@
# SPDX-License-Identifier: GPL-2.0
# Copyright (c) 2022-2023, NVIDIA CORPORATION & AFFILIATES. All rights reserved.
DTC_FLAGS += -@
# DT overlays
dtbo-y += tegra194-carveouts.dtbo
dtbo-y += tegra194-jetson.dtbo
dtbo-y += tegra194-p3509-0000+p3668-0001-overlay.dtbo

View File

@@ -0,0 +1,29 @@
// SPDX-License-Identifier: GPL-2.0
/dts-v1/;
/plugin/;
/ {
fragment@0 {
target-path = "/";
__overlay__ {
reserved-memory {
#address-cells = <2>;
#size-cells = <2>;
ranges;
vpr: vpr-carveout {
compatible = "nvidia,vpr-carveout";
status = "okay";
};
};
tegra-carveouts {
compatible = "nvidia,carveouts-t19x";
memory-region = <&vpr>;
status = "okay";
};
};
};
};

View File

@@ -0,0 +1,157 @@
/*
* Copyright (c) 2022, NVIDIA CORPORATION & AFFILIATES.
*
* SPDX-License-Identifier: GPL-2.0
*/
/dts-v1/;
/plugin/;
#include <dt-bindings/clock/tegra194-clock.h>
#include <dt-bindings/interrupt-controller/arm-gic.h>
#include <dt-bindings/interrupt-controller/irq.h>
#include <dt-bindings/memory/tegra194-mc.h>
#include <dt-bindings/power/tegra194-powergate.h>
#include <dt-bindings/reset/tegra194-reset.h>
/ {
overlay-name = "Tegra194 Jetson Overlay";
compatible = "nvidia,tegra194";
fragment@0 {
target-path = "/bus@0/host1x@13e00000";
__overlay__ {
#address-cells = <2>;
#size-cells = <2>;
interrupt-parent = <&gic>;
ranges = <0x0 0x14800000 0x0 0x14800000 0x0 0x02800000>,
<0x0 0x24f00000 0x0 0x24f00000 0x0 0x00100000>;
nvdla0@15880000 {
compatible = "nvidia,tegra194-nvdla";
reg = <0x0 0x15880000 0x0 0x00040000>;
interrupts = <GIC_SPI 236 IRQ_TYPE_LEVEL_HIGH>;
clocks = <&bpmp TEGRA194_CLK_DLA0_CORE>,
<&bpmp TEGRA194_CLK_DLA0_FALCON>;
clock-names = "nvdla", "nvdla_flcn";
resets = <&bpmp TEGRA194_RESET_DLA0>;
reset-names = "nvdla";
power-domains = <&bpmp TEGRA194_POWER_DOMAIN_DLAA>;
interconnects = <&mc TEGRA194_MEMORY_CLIENT_DLA0RDA &emc>,
<&mc TEGRA194_MEMORY_CLIENT_DLA0FALRDB &emc>,
<&mc TEGRA194_MEMORY_CLIENT_DLA0WRA &emc>,
<&mc TEGRA194_MEMORY_CLIENT_DLA0FALWRB &emc>;
interconnect-names = "dma-mem", "read-1", "write", "write-1";
iommus = <&smmu TEGRA194_SID_NVDLA0>;
dma-coherent;
};
nvdla1@158c0000 {
compatible = "nvidia,tegra194-nvdla";
reg = <0x0 0x158c0000 0x0 0x00040000>;
interrupts = <GIC_SPI 237 IRQ_TYPE_LEVEL_HIGH>;
clocks = <&bpmp TEGRA194_CLK_DLA1_CORE>,
<&bpmp TEGRA194_CLK_DLA1_FALCON>;
clock-names = "nvdla", "nvdla_flcn";
resets = <&bpmp TEGRA194_RESET_DLA1>;
reset-names = "nvdla";
power-domains = <&bpmp TEGRA194_POWER_DOMAIN_DLAB>;
interconnects = <&mc TEGRA194_MEMORY_CLIENT_DLA1RDA &emc>,
<&mc TEGRA194_MEMORY_CLIENT_DLA1FALRDB &emc>,
<&mc TEGRA194_MEMORY_CLIENT_DLA1WRA &emc>,
<&mc TEGRA194_MEMORY_CLIENT_DLA1FALWRB &emc>;
interconnect-names = "dma-mem", "read-1", "write", "write-1";
iommus = <&smmu TEGRA194_SID_NVDLA1>;
dma-coherent;
};
pva0@16000000 {
compatible = "nvidia,tegra194-pva";
power-domains = <&bpmp TEGRA194_POWER_DOMAIN_PVAA>;
reg = <0x0 0x16000000 0x0 0x00800000>,
<0x0 0x24f00000 0x0 0x00080000>;
interrupts = <GIC_SPI 234 IRQ_TYPE_LEVEL_HIGH>;
resets = <&bpmp TEGRA194_RESET_PVA0_ALL>;
reset-names = "nvpva";
clocks = <&bpmp TEGRA194_CLK_NAFLL_PVA_VPS>,
<&bpmp TEGRA194_CLK_NAFLL_PVA_CORE>,
<&bpmp TEGRA194_CLK_PVA0_AXI>,
<&bpmp TEGRA194_CLK_PVA0_VPS0>,
<&bpmp TEGRA194_CLK_PVA0_VPS1>;
clock-names = "nafll_pva_vps", "nafll_pva_core", "axi", "vps0", "vps1";
interconnects = <&mc TEGRA194_MEMORY_CLIENT_PVA0RDA &emc>,
<&mc TEGRA194_MEMORY_CLIENT_PVA0RDB &emc>,
<&mc TEGRA194_MEMORY_CLIENT_PVA0RDC &emc>,
<&mc TEGRA194_MEMORY_CLIENT_PVA0WRA &emc>,
<&mc TEGRA194_MEMORY_CLIENT_PVA0WRB &emc>,
<&mc TEGRA194_MEMORY_CLIENT_PVA0WRC &emc>;
interconnect-names = "dma-mem", "read-b", "read-c", "write-a", "write-b", "write-c";
iommus = <&smmu TEGRA194_SID_PVA0>;
dma-coherent;
};
pva1@16800000 {
compatible = "nvidia,tegra194-pva";
power-domains = <&bpmp TEGRA194_POWER_DOMAIN_PVAB>;
reg = <0x0 0x16800000 0x0 0x00800000>,
<0x0 0x24f80000 0x0 0x00080000>;
interrupts = <GIC_SPI 235 IRQ_TYPE_LEVEL_HIGH>;
resets = <&bpmp TEGRA194_RESET_PVA1_ALL>;
reset-names = "nvpva";
clocks = <&bpmp TEGRA194_CLK_PVA1_AXI>,
<&bpmp TEGRA194_CLK_PVA1_VPS0>,
<&bpmp TEGRA194_CLK_PVA1_VPS1>;
clock-names = "axi", "vps0", "vps1";
interconnects = <&mc TEGRA194_MEMORY_CLIENT_PVA1RDA &emc>,
<&mc TEGRA194_MEMORY_CLIENT_PVA1RDB &emc>,
<&mc TEGRA194_MEMORY_CLIENT_PVA1RDC &emc>,
<&mc TEGRA194_MEMORY_CLIENT_PVA1WRA &emc>,
<&mc TEGRA194_MEMORY_CLIENT_PVA1WRB &emc>,
<&mc TEGRA194_MEMORY_CLIENT_PVA1WRC &emc>;
interconnect-names = "dma-mem", "read-b", "read-c", "write-a", "write-b", "write-c";
iommus = <&smmu TEGRA194_SID_PVA1>;
dma-coherent;
};
};
};
fragment@1 {
target-path = "/";
__overlay__ {
#address-cells = <2>;
#size-cells = <2>;
cvnas@14000000 {
compatible = "nvidia,tegra194-cvnas";
reg = <0x0 0x14000000 0x0 0x20000>, /* CV0_REG0_BASE */
<0x0 0x14020000 0x0 0x10000>, /* CV0_SRAM_BASE */
<0x0 0x0b240000 0x0 0x10000>; /* HSM_BASE */
interrupt-parent = <&gic>;
interrupts = <GIC_SPI 238 IRQ_TYPE_LEVEL_HIGH>,
<GIC_SPI 239 IRQ_TYPE_LEVEL_HIGH>;
clocks = <&bpmp TEGRA194_CLK_CVNAS>;
assigned-clocks = <&bpmp TEGRA194_CLK_CVNAS>;
assigned-clock-rates = <1356800000>;
resets = <&bpmp TEGRA194_RESET_CVNAS>,
<&bpmp TEGRA194_RESET_CVNAS_FCM>;
reset-names = "rst", "rst_fcm";
power-domains = <&bpmp TEGRA194_POWER_DOMAIN_CV>;
cvsramslice = <4 0x1000>;
cvsram-reg = <0x0 0x50000000 0x0 0x400000>;
};
};
};
};

View File

@@ -0,0 +1,9 @@
// SPDX-License-Identifier: GPL-2.0
/dts-v1/;
/plugin/;
/ {
overlay-name = "Add p3509-0000+p3668-0001 Overlay Support";
compatible = "nvidia,tegra194";
};

View File

@@ -1,7 +1,7 @@
# SPDX-FileCopyrightText: Copyright (c) 2022-2023 NVIDIA CORPORATION & AFFILIATES. All rights reserved.
# SPDX-License-Identifier: GPL-2.0-only
objtree ?= $(srctree)
objtree = $(srctree)
# Redefine the fixdep command
cmd_and_fixdep = \

View File

@@ -5,102 +5,102 @@ MAKE[0]="make modules"
BUILT_MODULE_NAME[0]="softdog-platform"
BUILT_MODULE_LOCATION[0]="drivers/watchdog"
DEST_MODULE_LOCATION[0]="/updates"
DEST_MODULE_LOCATION[0]="/extra"
BUILT_MODULE_NAME[1]="watchdog-tegra-t18x"
BUILT_MODULE_LOCATION[1]="drivers/watchdog"
DEST_MODULE_LOCATION[1]="/updates"
DEST_MODULE_LOCATION[1]="/extra"
BUILT_MODULE_NAME[2]="pex9749-thermal"
BUILT_MODULE_LOCATION[2]="drivers/thermal"
DEST_MODULE_LOCATION[2]="/updates"
DEST_MODULE_LOCATION[2]="/extra"
BUILT_MODULE_NAME[3]="spi-aurix-tegra"
BUILT_MODULE_LOCATION[3]="drivers/spi"
DEST_MODULE_LOCATION[3]="/updates"
DEST_MODULE_LOCATION[3]="/extra"
BUILT_MODULE_NAME[4]="tegra186-gpc-dma"
BUILT_MODULE_LOCATION[4]="drivers/dma"
DEST_MODULE_LOCATION[4]="/updates"
DEST_MODULE_LOCATION[4]="/extra"
BUILT_MODULE_NAME[5]="pwm-tegra-tachometer"
BUILT_MODULE_LOCATION[5]="drivers/pwm"
DEST_MODULE_LOCATION[5]="/updates"
DEST_MODULE_LOCATION[5]="/extra"
BUILT_MODULE_NAME[6]="pinctrl-tegra234"
BUILT_MODULE_LOCATION[6]="drivers/pinctrl/tegra"
DEST_MODULE_LOCATION[6]="/updates"
DEST_MODULE_LOCATION[6]="/extra"
BUILT_MODULE_NAME[7]="tegra-cactmon"
BUILT_MODULE_LOCATION[7]="drivers/platform/tegra"
DEST_MODULE_LOCATION[7]="/updates"
DEST_MODULE_LOCATION[7]="/extra"
BUILT_MODULE_NAME[8]="pinctrl-tegra234-dpaux"
BUILT_MODULE_LOCATION[8]="drivers/pinctrl"
DEST_MODULE_LOCATION[8]="/updates"
DEST_MODULE_LOCATION[8]="/extra"
BUILT_MODULE_NAME[9]="tegra-fsicom"
BUILT_MODULE_LOCATION[9]="drivers/platform/tegra"
DEST_MODULE_LOCATION[9]="/updates"
DEST_MODULE_LOCATION[9]="/extra"
BUILT_MODULE_NAME[10]="tegra-bootloader-debug"
BUILT_MODULE_LOCATION[10]="drivers/platform/tegra"
DEST_MODULE_LOCATION[10]="/updates"
DEST_MODULE_LOCATION[10]="/extra"
BUILT_MODULE_NAME[11]="host1x-fence"
BUILT_MODULE_LOCATION[11]="drivers/gpu/host1x-fence"
DEST_MODULE_LOCATION[11]="/updates"
DEST_MODULE_LOCATION[11]="/extra"
BUILT_MODULE_NAME[12]="tegra_vnet"
BUILT_MODULE_LOCATION[12]="drivers/net/ethernet/nvidia/pcie"
DEST_MODULE_LOCATION[12]="/updates"
DEST_MODULE_LOCATION[12]="/extra"
BUILT_MODULE_NAME[13]="arm64-ras"
BUILT_MODULE_LOCATION[13]="drivers/ras"
DEST_MODULE_LOCATION[13]="/updates"
DEST_MODULE_LOCATION[13]="/extra"
BUILT_MODULE_NAME[14]="fuse-burn"
BUILT_MODULE_LOCATION[14]="drivers/soc/tegra/fuse"
DEST_MODULE_LOCATION[14]="/updates"
DEST_MODULE_LOCATION[14]="/extra"
BUILT_MODULE_NAME[15]="kfuse"
BUILT_MODULE_LOCATION[15]="drivers/soc/tegra/fuse"
DEST_MODULE_LOCATION[15]="/updates"
DEST_MODULE_LOCATION[15]="/extra"
BUILT_MODULE_NAME[16]="pci-epf-dma-test"
BUILT_MODULE_LOCATION[16]="drivers/pci/endpoint/functions"
DEST_MODULE_LOCATION[16]="/updates"
DEST_MODULE_LOCATION[16]="/extra"
BUILT_MODULE_NAME[17]="tegra-pcie-edma"
BUILT_MODULE_LOCATION[17]="drivers/pci/controller"
DEST_MODULE_LOCATION[17]="/updates"
DEST_MODULE_LOCATION[17]="/extra"
BUILT_MODULE_NAME[18]="pcie-tegra-vf"
BUILT_MODULE_LOCATION[18]="drivers/pci/controller"
DEST_MODULE_LOCATION[18]="/updates"
DEST_MODULE_LOCATION[18]="/extra"
BUILT_MODULE_NAME[19]="tegra-pcie-dma-test"
BUILT_MODULE_LOCATION[19]="drivers/misc"
DEST_MODULE_LOCATION[19]="/updates"
DEST_MODULE_LOCATION[19]="/extra"
BUILT_MODULE_NAME[20]="tegra-se"
BUILT_MODULE_LOCATION[20]="drivers/crypto/tegra"
DEST_MODULE_LOCATION[20]="/updates"
DEST_MODULE_LOCATION[20]="/extra"
BUILT_MODULE_NAME[21]="tegra-se-nvrng"
BUILT_MODULE_LOCATION[21]="drivers/crypto"
DEST_MODULE_LOCATION[21]="/updates"
DEST_MODULE_LOCATION[21]="/extra"
BUILT_MODULE_NAME[22]="nvidia-vrs-pseq"
BUILT_MODULE_LOCATION[22]="drivers/mfd"
DEST_MODULE_LOCATION[22]="/updates"
DEST_MODULE_LOCATION[22]="/extra"
BUILT_MODULE_NAME[23]="cpuidle-debugfs"
BUILT_MODULE_LOCATION[23]="drivers/cpuidle"
DEST_MODULE_LOCATION[23]="/updates"
DEST_MODULE_LOCATION[23]="/extra"
BUILT_MODULE_NAME[24]="pinctrl-tegra194-pexclk-padctrl"
BUILT_MODULE_LOCATION[24]="drivers/pinctrl"
DEST_MODULE_LOCATION[24]="/updates"
DEST_MODULE_LOCATION[24]="/extra"
AUTO_INSTALL="yes"

View File

@@ -1,5 +1,5 @@
# SPDX-License-Identifier: GPL-2.0-only
# SPDX-FileCopyrightText: Copyright (c) 2022-2024 NVIDIA CORPORATION & AFFILIATES. All rights reserved.
# SPDX-FileCopyrightText: Copyright (c) 2022-2023 NVIDIA CORPORATION & AFFILIATES. All rights reserved.
LINUXINCLUDE += -I$(srctree.nvidia-oot)/include
LINUXINCLUDE += -I$(srctree.nvidia-oot)/drivers/gpu/host1x/hw/
@@ -17,7 +17,9 @@ endif
obj-m += c2c/
obj-m += clink/
obj-m += cpuidle/
ifeq ($(CONFIG_SKIP_CRYPTO),)
obj-m += crypto/
endif
ifdef CONFIG_PM_DEVFREQ
obj-m += devfreq/
endif
@@ -32,12 +34,10 @@ endif
ifdef CONFIG_I2C
obj-m += i2c/busses/
obj-m += mfd/
ifdef CONFIG_HTE
ifdef CONFIG_IIO
obj-m += bmi088/
endif
endif
endif
ifdef CONFIG_MEMORY
obj-m += memory/
endif
@@ -81,5 +81,7 @@ obj-m += virt/tegra/
ifdef CONFIG_TEGRA_HOST1X
obj-m += media/
endif
obj-m += staging/platform/tegra/gte/
obj-m += staging/platform/tegra/gte_test/
obj-m += nv-virtio/
obj-m += usb/

View File

@@ -1,19 +1,13 @@
# SPDX-License-Identifier: GPL-2.0-only
# SPDX-FileCopyrightText: Copyright (c) 2022-2024 NVIDIA CORPORATION & AFFILIATES. All rights reserved.
# SPDX-License-Identifier: GPL-2.0
# Copyright (c) 2022, NVIDIA CORPORATION & AFFILIATES. All rights reserved.
#
# Makefile for Virtual Storage Driver
#
LINUX_VERSION := $(shell expr $(VERSION) \* 256 + $(PATCHLEVEL))
LINUX_VERSION_6_11 := $(shell expr 6 \* 256 + 11)
# Use dummy driver for Kernel versions greater than or equal to Linux v6.11
ifeq ($(shell test $(LINUX_VERSION) -lt $(LINUX_VERSION_6_11); echo $$?),0)
tegra_vblk-y += tegra_hv_vblk.o
tegra_vblk-y += tegra_hv_ioctl.o
tegra_vblk-y += tegra_hv_mmc.o
tegra_vblk-y += tegra_hv_scsi.o
tegra_vblk-y += tegra_hv_ufs.o
obj-m += tegra_vblk.o
endif

View File

@@ -1,8 +1,10 @@
// SPDX-License-Identifier: GPL-2.0-only
// SPDX-FileCopyrightText: Copyright (c) 2022-2024 NVIDIA CORPORATION & AFFILIATES. All rights reserved.
/* SPDX-License-Identifier: GPL-2.0-only */
/*
* Copyright (c) 2022-2023, NVIDIA CORPORATION & AFFILIATES. All rights reserved.
*/
#include <linux/kernel.h> /* printk() */
#include <linux/vmalloc.h> /* kmalloc() */
#include <linux/slab.h> /* kmalloc() */
#include <linux/fs.h> /* everything... */
#include <linux/errno.h> /* error codes */
#include <linux/fcntl.h> /* O_ACCMODE */

View File

@@ -1,7 +1,9 @@
// SPDX-License-Identifier: GPL-2.0-only
// SPDX-FileCopyrightText: Copyright (c) 2022-2024 NVIDIA CORPORATION & AFFILIATES. All rights reserved.
/* SPDX-License-Identifier: GPL-2.0-only */
/*
* Copyright (c) 2022, NVIDIA CORPORATION & AFFILIATES. All rights reserved.
*/
#include <linux/vmalloc.h> /* kmalloc() */
#include <linux/slab.h> /* kmalloc() */
#include <linux/errno.h> /* error codes */
#include <linux/delay.h> /* For msleep and usleep_range */
#include <uapi/scsi/ufs/ioctl.h>

View File

@@ -1,5 +1,7 @@
// SPDX-License-Identifier: GPL-2.0-only
// SPDX-FileCopyrightText: Copyright (c) 2022-2024 NVIDIA CORPORATION & AFFILIATES. All rights reserved.
/* SPDX-License-Identifier: GPL-2.0-only */
/*
* Copyright (c) 2022-2023, NVIDIA CORPORATION & AFFILIATES. All rights reserved.
*/
#include <nvidia/conftest.h>
@@ -995,11 +997,7 @@ static void setup_device(struct vblk_dev *vblkdev)
if (ret)
return;
#if defined(NV_BLK_MQ_ALLOC_QUEUE_PRESENT)
vblkdev->queue = blk_mq_alloc_queue(&vblkdev->tag_set, NULL, NULL);
#else
vblkdev->queue = blk_mq_init_queue(&vblkdev->tag_set);
#endif
if (IS_ERR(vblkdev->queue)) {
dev_err(vblkdev->device, "failed to init blk queue\n");
blk_mq_free_tag_set(&vblkdev->tag_set);
@@ -1164,9 +1162,7 @@ static void setup_device(struct vblk_dev *vblkdev)
vblkdev->max_requests = max_requests;
vblkdev->max_ioctl_requests = max_ioctl_requests;
#if defined(NV_BLK_QUEUE_MAX_HW_SECTORS_PRESENT) /* Removed in Linux v6.10 */
blk_queue_max_hw_sectors(vblkdev->queue, max_io_bytes / SECTOR_SIZE);
#endif
blk_queue_flag_set(QUEUE_FLAG_NONROT, vblkdev->queue);
if ((vblkdev->config.blk_config.req_ops_supported & VS_BLK_SECURE_ERASE_OP_F)

View File

@@ -54,7 +54,7 @@ struct cfg_list_item {
struct list_head list;
u16 offset;
u8 len;
u8 data[];
u8 data[0];
};
static struct list_head list_configs;

View File

@@ -1,5 +1,5 @@
// SPDX-License-Identifier: GPL-2.0-only
// SPDX-FileCopyrightText: Copyright (c) 2023-2024, NVIDIA CORPORATION & AFFILIATES. All rights reserved.
// Copyright (c) 2023, NVIDIA CORPORATION & AFFILIATES. All rights reserved.
/* Device tree example:
*
@@ -7,15 +7,13 @@
* compatible = "bmi,bmi088";
* reg = <0x69>; // <-- Must be gyroscope I2C address
* accel_i2c_addr = <0x19>; // Must be specified
* accel_irq-gpios = <&tegra_gpio TEGRA_GPIO(BB, 0) GPIO_ACTIVE_HIGH>;
* gyro_irq-gpios = <&tegra_gpio TEGRA_GPIO(BB, 1) GPIO_ACTIVE_HIGH>;
* accel_irq_gpio = <&tegra_gpio TEGRA_GPIO(BB, 0) GPIO_ACTIVE_HIGH>;
* gyro_irq_gpio = <&tegra_gpio TEGRA_GPIO(BB, 1) GPIO_ACTIVE_HIGH>;
* accel_matrix = [01 00 00 00 01 00 00 00 01];
* gyro_matrix = [01 00 00 00 01 00 00 00 01];
* };
*/
#include <nvidia/conftest.h>
#include <linux/device.h>
#include <linux/version.h>
#include <linux/i2c.h>
@@ -27,8 +25,8 @@
#include <linux/gpio.h>
#include <linux/of_gpio.h>
#include <linux/of.h>
#include <linux/tegra-gte.h>
#include <linux/bitops.h>
#include <linux/hte.h>
#include "bmi_iio.h"
#define BMI_NAME "bmi088"
@@ -109,17 +107,22 @@
#define BMI_PART_BMI088 (0)
#define HTE_TIMEOUT (msecs_to_jiffies(100))
static const struct i2c_device_id bmi_i2c_device_ids[] = {
{ BMI_NAME, BMI_PART_BMI088 },
{},
};
struct bmi_gpio_irq {
struct gpio_desc *gpio_in;
static char *gte_hw_str_t194 = "nvidia,tegra194-gte-aon";
static char *gte_hw_str_t234 = "nvidia,tegra234-gte-aon";
static struct device_node *gte_nd;
struct bmi_gte_irq {
struct tegra_gte_ev_desc *gte;
const char *dev_name;
int gpio;
int irq;
u64 irq_ts;
u64 irq_ts_old;
};
struct bmi_reg_rd {
@@ -408,21 +411,18 @@ struct bmi_snsr {
struct sensor_cfg cfg;
unsigned int usr_cfg;
unsigned int period_us;
u64 irq_ts;
u64 irq_ts_old;
u64 seq;
struct completion hte_ts_cmpl;
struct bmi_gpio_irq gis;
struct bmi_state *st;
};
struct bmi_state {
struct i2c_client *i2c;
struct bmi_snsr snsrs[BMI_HW_N];
struct bmi_gte_irq gis[BMI_HW_N];
bool iio_init_done[BMI_HW_N];
unsigned int part;
unsigned int sts;
unsigned int errs_bus[BMI_HW_N];
unsigned int err_ts_thread[BMI_HW_N];
unsigned int sam_dropped[BMI_HW_N];
unsigned int enabled;
unsigned int suspend_en_st;
unsigned int hw_n;
@@ -537,36 +537,141 @@ static int bmi_i2c_wr(struct bmi_state *st, unsigned int hw, u8 reg, u8 val)
return ret;
}
static void bmi_gte_exit_gpio(struct bmi_gte_irq *ngi, unsigned int n)
{
unsigned int i;
for (i = 0; i < n; i++) {
if (ngi[i].gpio >= 0)
gpio_free(ngi[i].gpio);
}
}
static int bmi_gte_init_gpio2irq(struct device *dev, struct bmi_gte_irq *ngi,
unsigned int n)
{
unsigned int i;
unsigned int prev;
int ret;
for (i = 0; i < n; i++) {
if (!gpio_is_valid(ngi[i].gpio) ||
gpio_request(ngi[i].gpio, ngi[i].dev_name)) {
ret = -EPROBE_DEFER;
if (!i) {
goto out_no_prev;
} else {
prev = i - 1;
goto out;
}
}
ret = gpio_direction_input(ngi[i].gpio);
if (ret < 0) {
dev_err(dev, "%s gpio_dir_input(%d) ERR:%d\n",
ngi[i].dev_name, ngi[i].gpio, ret);
ret = -ENODEV;
if (!i)
prev = i;
else
prev = i - 1;
goto out;
}
ret = gpio_to_irq(ngi[i].gpio);
if (ret <= 0) {
dev_err(dev, "%s gpio_to_irq(%d) ERR:%d\n",
ngi[i].dev_name, ngi[i].gpio, ret);
ret = -ENODEV;
if (!i)
prev = i;
else
prev = i - 1;
goto out;
}
ngi[i].irq = ret;
ret = 0;
}
return ret;
out:
bmi_gte_exit_gpio(ngi, prev);
out_no_prev:
return ret;
}
static int bmi_gte_ts(struct bmi_gte_irq *ngi)
{
struct tegra_gte_ev_desc *desc = (struct tegra_gte_ev_desc *)ngi->gte;
struct tegra_gte_ev_detail dtl;
int ret;
ret = tegra_gte_retrieve_event(desc, &dtl);
if (!ret)
ngi->irq_ts = dtl.ts_ns;
return ret;
}
static inline int bmi_gte_deinit(struct bmi_gte_irq *ngi)
{
int ret = 0;
if (ngi->gte) {
ret = tegra_gte_unregister_event(ngi->gte);
ngi->gte = NULL;
}
return ret;
}
static void bmi_gte_gpio_exit(struct bmi_state *st, unsigned int n)
{
unsigned int i;
struct bmi_gte_irq *ngi = st->gis;
if (gte_nd) {
of_node_put(gte_nd);
gte_nd = NULL;
}
for (i = 0; i < n; i++) {
bmi_gte_deinit(&ngi[i]);
if (ngi[i].gpio >= 0)
gpio_free(ngi[i].gpio);
}
}
static int bmi_gte_init(struct bmi_state *st, unsigned int id)
{
int ret = 0;
struct bmi_gte_irq *ngi = st->gis;
if (!ngi[id].gte) {
ngi[id].gte = tegra_gte_register_event(gte_nd, ngi[id].gpio);
if (!ngi[id].gte)
ret = -ENODEV;
}
return ret;
}
static int bmi_setup_gpio(struct device *dev, struct bmi_state *st,
unsigned int n)
{
unsigned int i;
struct bmi_snsr *snsrs = st->snsrs;
int ret;
struct bmi_gte_irq *ngi = st->gis;
for (i = 0; i < n; i++) {
snsrs[i].gis.irq = -1;
if ((snsrs[i].gis.gpio_in)) {
ret = gpiod_direction_input(snsrs[i].gis.gpio_in);
for (i = 0; i < n; i++)
ngi[i].irq = -1;
if (ret < 0) {
dev_err(dev, "%s gpio_dir_input ERR:%d\n",
snsrs[i].gis.dev_name, ret);
return ret;
}
ret = gpiod_to_irq(snsrs[i].gis.gpio_in);
if (ret < 0) {
dev_err(dev, "%s gpio_to_irq ERR:%d\n",
snsrs[i].gis.dev_name, ret);
return ret;
}
snsrs[i].gis.irq = ret;
}
}
return 0;
return bmi_gte_init_gpio2irq(dev, ngi, n);
}
static int bmi_pm(struct bmi_state *st, int snsr_id, bool en)
@@ -862,32 +967,17 @@ static unsigned long bmi_gyr_irqflags(struct bmi_state *st)
return irqflags;
}
static enum hte_return process_hw_ts(struct hte_ts_data *ts, void *p)
{
struct bmi_snsr *sensor = (struct bmi_snsr *)p;
struct bmi_state *st = sensor->st;
sensor->irq_ts = ts->tsc;
sensor->seq = ts->seq;
complete(&sensor->hte_ts_cmpl);
dev_dbg_ratelimited(&st->i2c->dev, "%s: seq %llu, ts:%llu\n",
__func__, sensor->seq, sensor->irq_ts);
return HTE_CB_HANDLED;
}
static irqreturn_t bmi_irq_thread(int irq, void *dev_id)
{
struct bmi_snsr *sensor = (struct bmi_snsr *)dev_id;
struct bmi_state *st = sensor->st;
struct bmi_state *st = (struct bmi_state *)dev_id;
unsigned int hw;
int ret;
u8 reg;
u8 sample[BMI_IMU_DATA];
int cnt = 0;
u64 ts_old;
if (irq == st->snsrs[BMI_HW_GYR].gis.irq) {
if (irq == st->gis[BMI_HW_GYR].irq) {
hw = BMI_HW_GYR;
reg = BMI_REG_GYR_DATA;
} else {
@@ -895,7 +985,7 @@ static irqreturn_t bmi_irq_thread(int irq, void *dev_id)
reg = BMI_REG_ACC_DATA;
}
/* Disable data ready interrupt before we read out data */
/* Disbale data ready interrupt before we read out data */
ret = bmi_hws[hw].fn_able(st, 0, true);
if (unlikely(ret)) {
dev_err_ratelimited(&st->i2c->dev,
@@ -903,31 +993,71 @@ static irqreturn_t bmi_irq_thread(int irq, void *dev_id)
goto err;
}
/* Wait for HTE IRQ to fetch the latest timestamp */
ret = wait_for_completion_interruptible_timeout(&sensor->hte_ts_cmpl, HTE_TIMEOUT);
if (!ret) {
dev_dbg_ratelimited(&st->i2c->dev,
"sample dropped due to timeout");
goto err;
ts_old = st->gis[hw].irq_ts_old;
/*
* There is a possibility that data ready IRQ may have caused GTE to
* store the timestamps by the time this thread got a chance to run
* and disable IRQ especially for the high data rate, in that case,
* drain the GTE till it returns error and use last timestamp to
* associate the data to be read.
*/
while (bmi_gte_ts(&st->gis[hw]) == 0)
cnt++;
/* Means we failed to get the ts in the first go */
if (!st->gis[hw].irq_ts && !cnt) {
dev_dbg(&st->i2c->dev, "sample dropped, gte get ts failed\n");
st->sam_dropped[hw]++;
goto out;
}
/*
* If ts is same as old or 0, something is seriously wrong,
* re-register with gte
*/
if ((st->gis[hw].irq_ts_old == st->gis[hw].irq_ts) ||
(!st->gis[hw].irq_ts && cnt)) {
dev_dbg(&st->i2c->dev,
"ts issue for: %d, ts old: %llu, new: %llu\n",
hw, st->gis[hw].irq_ts_old, st->gis[hw].irq_ts);
st->err_ts_thread[hw]++;
st->sam_dropped[hw]++;
dev_dbg(&st->i2c->dev, "sample dropped due to ts issues\n");
/* Re-register with GTE */
bmi_gte_deinit(&st->gis[hw]);
ret = bmi_gte_init(st, hw);
if (ret) {
dev_err_ratelimited(&st->i2c->dev,
"GTE re-registration failed: %d\n",
hw);
goto err;
}
goto out;
}
mutex_lock(BMI_MUTEX(st->snsrs[hw].bmi_iio));
ret = bmi_i2c_rd(st, hw, reg, sizeof(sample), sample);
if (!ret) {
bmi_iio_push_buf(st->snsrs[hw].bmi_iio, sample,
sensor->irq_ts);
dev_dbg(&st->i2c->dev, "%d, ts= %lld ts_old= %lld\n",
hw, sensor->irq_ts, sensor->irq_ts_old);
sensor->irq_ts_old = sensor->irq_ts;
}
mutex_unlock(BMI_MUTEX(st->snsrs[hw].bmi_iio));
/* Enable data ready interrupt */
if (!ret) {
bmi_iio_push_buf(st->snsrs[hw].bmi_iio, sample,
st->gis[hw].irq_ts);
st->gis[hw].irq_ts_old = st->gis[hw].irq_ts;
}
dev_dbg(&st->i2c->dev, "%d, ts= %lld, ts_old=%lld\n",
hw, st->gis[hw].irq_ts, ts_old);
out:
st->gis[hw].irq_ts = 0;
bmi_hws[hw].fn_able(st, 1, true);
err:
return IRQ_HANDLED;
}
@@ -942,7 +1072,7 @@ static int bmi_period(struct bmi_state *st, int snsr_id, bool range)
range);
}
static int bmi_enable(void *client, int snsr_id, int enable)
static int bmi_enable(void *client, int snsr_id, int enable, bool is_gte)
{
struct bmi_state *st = (struct bmi_state *)client;
int ret;
@@ -954,10 +1084,20 @@ static int bmi_enable(void *client, int snsr_id, int enable)
return (st->enabled & (1 << snsr_id));
if (enable) {
if (is_gte) {
ret = bmi_gte_init(st, snsr_id);
if (ret)
return ret;
}
enable = st->enabled | (1 << snsr_id);
ret = bmi_pm(st, snsr_id, true);
if (ret < 0)
if (ret < 0) {
if (is_gte)
bmi_gte_deinit(&st->gis[snsr_id]);
return ret;
}
ret = bmi_period(st, snsr_id, true);
ret |= bmi_hws[snsr_id].fn_able(st, 1, false);
@@ -967,6 +1107,9 @@ static int bmi_enable(void *client, int snsr_id, int enable)
}
}
if (is_gte)
bmi_gte_deinit(&st->gis[snsr_id]);
ret = bmi_hws[snsr_id].fn_able(st, 0, false);
ret |= bmi_pm(st, snsr_id, false);
@@ -1159,6 +1302,11 @@ static int bmi_read_err(void *client, int snsr_id, char *buf)
t += snprintf(buf, PAGE_SIZE, "%s:\n", st->snsrs[snsr_id].cfg.name);
t += snprintf(buf + t, PAGE_SIZE - t,
"I2C Bus Errors:%u\n", st->errs_bus[snsr_id]);
t += snprintf(buf + t, PAGE_SIZE - t,
"GTE Timestamp Errors:%u\n", st->err_ts_thread[snsr_id]);
t += snprintf(buf + t, PAGE_SIZE - t,
"Sample dropped:%u\n", st->sam_dropped[snsr_id]);
return t;
}
@@ -1241,9 +1389,11 @@ static int __maybe_unused bmi_suspend(struct device *dev)
for (i = 0; i < st->hw_n; i++) {
mutex_lock(BMI_MUTEX(st->snsrs[i].bmi_iio));
/* check if sensor is enabled to begin with */
old_en_st = bmi_enable(st, st->snsrs[i].cfg.snsr_id, -1);
old_en_st = bmi_enable(st, st->snsrs[i].cfg.snsr_id, -1,
false);
if (old_en_st) {
temp_ret = bmi_enable(st, st->snsrs[i].cfg.snsr_id, 0);
temp_ret = bmi_enable(st, st->snsrs[i].cfg.snsr_id, 0,
false);
if (!temp_ret)
st->suspend_en_st |= old_en_st;
@@ -1265,7 +1415,8 @@ static int __maybe_unused bmi_resume(struct device *dev)
for (i = 0; i < st->hw_n; i++) {
mutex_lock(BMI_MUTEX(st->snsrs[i].bmi_iio));
if (st->suspend_en_st & (1 << st->snsrs[i].cfg.snsr_id))
ret |= bmi_enable(st, st->snsrs[i].cfg.snsr_id, 1);
ret |= bmi_enable(st, st->snsrs[i].cfg.snsr_id, 1,
false);
mutex_unlock(BMI_MUTEX(st->snsrs[i].bmi_iio));
}
@@ -1286,8 +1437,8 @@ static void bmi_shutdown(struct i2c_client *client)
if (st->iio_init_done[i])
mutex_lock(BMI_MUTEX(st->snsrs[i].bmi_iio));
if (bmi_enable(st, st->snsrs[i].cfg.snsr_id, -1))
bmi_enable(st, st->snsrs[i].cfg.snsr_id, 0);
if (bmi_enable(st, st->snsrs[i].cfg.snsr_id, -1, false))
bmi_enable(st, st->snsrs[i].cfg.snsr_id, 0, false);
if (st->iio_init_done[i]) {
mutex_unlock(BMI_MUTEX(st->snsrs[i].bmi_iio));
@@ -1303,6 +1454,7 @@ static void bmi_remove(void *data)
if (st != NULL) {
bmi_shutdown(client);
bmi_gte_gpio_exit(st, BMI_HW_N);
for (i = 0; i < st->hw_n; i++) {
if (st->iio_init_done[i])
bmi_iio_remove(st->snsrs[i].bmi_iio);
@@ -1328,18 +1480,8 @@ static int bmi_of_dt(struct bmi_state *st, struct device_node *dn)
return -ENODEV;
}
st->snsrs[BMI_HW_ACC].gis.gpio_in = devm_gpiod_get(&st->i2c->dev, "accel_irq", 0);
if (IS_ERR(st->snsrs[BMI_HW_ACC].gis.gpio_in)) {
dev_err(&st->i2c->dev, "accel_irq is not set in DT\n");
return PTR_ERR(st->snsrs[BMI_HW_ACC].gis.gpio_in);
}
st->snsrs[BMI_HW_GYR].gis.gpio_in = devm_gpiod_get(&st->i2c->dev, "gyro_irq", 0);
if (IS_ERR(st->snsrs[BMI_HW_GYR].gis.gpio_in)) {
dev_err(&st->i2c->dev, "gyro_irq is not set in DT\n");
return PTR_ERR(st->snsrs[BMI_HW_GYR].gis.gpio_in);
}
st->gis[BMI_HW_ACC].gpio = of_get_named_gpio(dn, "accel_irq_gpio", 0);
st->gis[BMI_HW_GYR].gpio = of_get_named_gpio(dn, "gyro_irq_gpio", 0);
if (!of_property_read_u32(dn, "accel_reg_0x53", &val32))
st->ra_0x53 = (u8)val32;
@@ -1379,11 +1521,14 @@ static int bmi_init(struct bmi_state *st, const struct i2c_device_id *id)
unsigned long irqflags;
unsigned int i;
int ret;
struct hte_ts_desc *desc;
if (id == NULL)
return -EINVAL;
/* driver specific defaults */
for (i = 0; i < BMI_HW_N; i++)
st->gis[i].gpio = -1;
st->ra_0x53 = BMI_INT1_OUT_ACTIVE_HIGH;
st->ra_0x54 = 0x00;
st->ra_0x58 = BMI_INT1_DTRDY;
@@ -1400,6 +1545,13 @@ static int bmi_init(struct bmi_state *st, const struct i2c_device_id *id)
return ret;
}
/*
* Only interrupt mode is supported as we want hardware timestamps
* from GTE.
*/
if (st->gis[BMI_HW_ACC].gpio < 0 || st->gis[BMI_HW_GYR].gpio < 0)
return -EINVAL;
st->part = id->driver_data;
st->i2c_addrs[BMI_HW_GYR] = st->i2c->addr;
ret = bmi_reset_all(st);
@@ -1428,63 +1580,31 @@ static int bmi_init(struct bmi_state *st, const struct i2c_device_id *id)
st->snsrs[i].cfg.part = bmi_i2c_device_ids[st->part].name;
st->snsrs[i].rrs = &bmi_hws[i].rrs[st->part];
bmi_max_range(st, i, st->snsrs[i].cfg.max_range.ival);
st->snsrs[i].gis.dev_name = st->snsrs[i].cfg.name;
st->gis[i].dev_name = st->snsrs[i].cfg.name;
st->gis[i].gte = NULL;
st->iio_init_done[i] = true;
st->snsrs[i].st = st;
init_completion(&st->snsrs[i].hte_ts_cmpl);
}
ret = bmi_setup_gpio(&st->i2c->dev, st, st->hw_n);
if (ret < 0)
return ret;
desc = devm_kzalloc(&st->i2c->dev, sizeof(*desc)*BMI_HW_N, GFP_KERNEL);
if (!desc)
return -ENOMEM;
for (i = 0; i < BMI_HW_N; i++) {
for (i = 0; i < st->hw_n; i++) {
if (bmi_hws[i].fn_irqflags) {
irqflags = bmi_hws[i].fn_irqflags(st);
ret = devm_request_threaded_irq(&st->i2c->dev,
st->snsrs[i].gis.irq,
st->gis[i].irq,
NULL,
bmi_irq_thread,
irqflags,
st->snsrs[i].gis.dev_name,
&st->snsrs[i]);
st->gis[i].dev_name,
st);
if (ret) {
dev_err(&st->i2c->dev,
"req_threaded_irq ERR %d\n", ret);
return ret;
}
}
ret = hte_init_line_attr(&desc[i], 0, 0, NULL,
st->snsrs[i].gis.gpio_in);
if (ret) {
dev_err(&st->i2c->dev,
"hte_init_line_attr ERR %d\n", ret);
return ret;
}
ret = hte_ts_get(&st->i2c->dev, &desc[i], i);
if (ret) {
dev_err(&st->i2c->dev,
"hte_ts_get ERR %d\n", ret);
return ret;
}
ret = devm_hte_request_ts_ns(&st->i2c->dev, &desc[i],
process_hw_ts, NULL,
&st->snsrs[i]);
if (ret) {
dev_err(&st->i2c->dev,
"devm_hte_request_ts_ns ERR %d\n", ret);
return ret;
}
}
/*
@@ -1494,11 +1614,20 @@ static int bmi_init(struct bmi_state *st, const struct i2c_device_id *id)
for (i = 0; i < st->hw_n; i++)
st->snsrs[i].period_us = st->snsrs[i].cfg.delay_us_max;
gte_nd = of_find_compatible_node(NULL, NULL, gte_hw_str_t194);
if (!gte_nd)
gte_nd = of_find_compatible_node(NULL, NULL, gte_hw_str_t234);
if (!gte_nd) {
dev_err(&st->i2c->dev, "Failed to find GTE node\n");
return -ENODEV;
}
return ret;
}
#if defined(NV_I2C_DRIVER_STRUCT_PROBE_WITHOUT_I2C_DEVICE_ID_ARG) /* Linux 6.3 */
#if KERNEL_VERSION(6, 3, 0) <= LINUX_VERSION_CODE
static int bmi_probe(struct i2c_client *client)
#else
static int bmi_probe(struct i2c_client *client, const struct i2c_device_id *id)

View File

@@ -1,5 +1,5 @@
// SPDX-License-Identifier: GPL-2.0-only
// SPDX-FileCopyrightText: Copyright (c) 2023-2024, NVIDIA CORPORATION & AFFILIATES. All rights reserved.
// Copyright (c) 2023, NVIDIA CORPORATION & AFFILIATES. All rights reserved.
#include <linux/init.h>
#include <linux/module.h>
@@ -164,9 +164,6 @@ int bmi_iio_push_buf(struct iio_dev *indio_dev, unsigned char *data, u64 ts)
if (!indio_dev || !data)
return -EINVAL;
if (!indio_dev->active_scan_mask)
return -EINVAL;
st = iio_priv(indio_dev);
if (!st)
return -EINVAL;
@@ -204,7 +201,8 @@ static int bmi_iio_enable(struct iio_dev *indio_dev, bool en)
int bit;
if (!en)
return st->fn_dev->enable(st->client, st->cfg->snsr_id, 0);
return st->fn_dev->enable(st->client, st->cfg->snsr_id,
0, true);
if (indio_dev->num_channels > 1) {
for_each_set_bit(bit, indio_dev->active_scan_mask,
@@ -215,7 +213,7 @@ static int bmi_iio_enable(struct iio_dev *indio_dev, bool en)
}
return st->fn_dev->enable(st->client, st->cfg->snsr_id, enable);
return st->fn_dev->enable(st->client, st->cfg->snsr_id, enable, true);
}
static ssize_t bmi_iio_attr_store(struct device *dev,
@@ -352,7 +350,7 @@ static inline int bmi_iio_check_enable(struct bmi_iio_state *st)
if (!st->fn_dev->enable)
return -EINVAL;
return st->fn_dev->enable(st->client, st->cfg->snsr_id, -1);
return st->fn_dev->enable(st->client, st->cfg->snsr_id, -1, false);
}
static int bmi_iio_read_raw(struct iio_dev *indio_dev,

View File

@@ -1,5 +1,5 @@
// SPDX-License-Identifier: GPL-2.0-only
// SPDX-FileCopyrightText: Copyright (c) 2023-2024, NVIDIA CORPORATION & AFFILIATES. All rights reserved.
// Copyright (c) 2023, NVIDIA CORPORATION & AFFILIATES. All rights reserved.
#ifndef _BMI_IIO_H_
@@ -39,7 +39,7 @@ struct sensor_cfg {
struct iio_fn_dev {
unsigned int *sts;
int (*enable)(void *client, int snsr_id, int enable);
int (*enable)(void *client, int snsr_id, int enable, bool is_gte);
int (*freq_read)(void *client, int snsr_id, int *val, int *val2);
int (*freq_write)(void *client, int snsr_id, int val, int val2);
int (*scale_write)(void *client, int snsr_id, int val, int val2);

View File

@@ -1,5 +1,7 @@
// SPDX-License-Identifier: GPL-2.0-only
// SPDX-FileCopyrightText: Copyright (c) 2022-2024 NVIDIA CORPORATION & AFFILIATES. All rights reserved.
// SPDX-License-Identifier: GPL-2.0
/*
* Copyright (c) 2022, NVIDIA CORPORATION & AFFILIATES. All rights reserved.
*/
#include <linux/clk-provider.h>
#include <linux/device.h>
@@ -364,7 +366,7 @@ static int tegra_bpmp_clk_get_info(struct tegra_bpmp *bpmp, unsigned int id,
if (err < 0)
return err;
strscpy(info->name, response.name, MRQ_CLK_NAME_MAXLEN);
strlcpy(info->name, response.name, MRQ_CLK_NAME_MAXLEN);
info->num_parents = response.num_parents;
for (i = 0; i < info->num_parents; i++)

View File

@@ -1,6 +1,6 @@
// SPDX-License-Identifier: GPL-2.0-only
/*
* Copyright (c) 2019-2024, NVIDIA Corporation. All Rights Reserved.
* Copyright (c) 2019-2023, NVIDIA Corporation. All Rights Reserved.
*
* Cryptographic API.
*/
@@ -15,8 +15,8 @@
#include <linux/dma-mapping.h>
#include <linux/hw_random.h>
#include <linux/io.h>
#include <linux/of.h>
#include <linux/of_device.h>
#include <linux/of_platform.h>
#include <linux/mutex.h>
#include <linux/types.h>
#include <linux/errno.h>

View File

@@ -1,5 +1,5 @@
// SPDX-License-Identifier: GPL-2.0-only
// SPDX-FileCopyrightText: Copyright (c) 2023-2024 NVIDIA CORPORATION & AFFILIATES. All rights reserved.
// SPDX-FileCopyrightText: Copyright (c) 2023 NVIDIA CORPORATION & AFFILIATES. All rights reserved.
ccflags-y += -I$(srctree.nvidia)/drivers/gpu/host1x/include

View File

File diff suppressed because it is too large Load Diff

View File

@@ -1,12 +1,12 @@
// SPDX-License-Identifier: GPL-2.0-only
// SPDX-FileCopyrightText: Copyright (c) 2023-2024 NVIDIA CORPORATION & AFFILIATES. All rights reserved.
// SPDX-FileCopyrightText: Copyright (c) 2023 NVIDIA CORPORATION & AFFILIATES. All rights reserved.
/*
* Crypto driver to handle HASH algorithms using NVIDIA Security Engine.
*/
#include <nvidia/conftest.h>
#include <linux/clk.h>
#include <linux/dma-mapping.h>
#include <linux/host1x-next.h>
#include <linux/module.h>
#include <linux/of_device.h>
#include <linux/platform_device.h>
@@ -23,17 +23,16 @@
#include "tegra-se.h"
struct tegra_sha_ctx {
#ifndef NV_CONFTEST_REMOVE_STRUCT_CRYPTO_ENGINE_CTX
struct crypto_engine_ctx enginectx;
#endif
struct crypto_ahash *fallback_tfm;
struct tegra_se *se;
unsigned int alg;
bool fallback;
u32 key_id;
struct crypto_ahash *fallback_tfm;
};
struct tegra_sha_reqctx {
struct ahash_request fallback_req;
struct scatterlist *src_sg;
struct tegra_se_datbuf datbuf;
struct tegra_se_datbuf residue;
@@ -44,8 +43,6 @@ struct tegra_sha_reqctx {
unsigned int blk_size;
unsigned int task;
u32 key_id;
u32 result[HASH_RESULT_REG_COUNT];
struct ahash_request fallback_req;
};
static int tegra_sha_get_config(u32 alg)
@@ -216,13 +213,13 @@ static int tegra_sha_fallback_export(struct ahash_request *req, void *out)
}
static int tegra_sha_prep_cmd(struct tegra_se *se, u32 *cpuvaddr,
struct tegra_sha_reqctx *rctx)
struct tegra_sha_reqctx *rctx)
{
u64 msg_len, msg_left;
int i = 0;
msg_len = rctx->total_len * 8;
msg_left = rctx->datbuf.size * 8;
msg_len = (u64)rctx->total_len * 8;
msg_left = (u64)rctx->datbuf.size * 8;
/*
* If IN_ADDR_HI_0.SZ > SHA_MSG_LEFT_[0-3] to the HASH engine,
@@ -236,7 +233,7 @@ static int tegra_sha_prep_cmd(struct tegra_se *se, u32 *cpuvaddr,
}
cpuvaddr[i++] = host1x_opcode_setpayload(8);
cpuvaddr[i++] = se_host1x_opcode_incr_w(SE_SHA_MSG_LENGTH);
cpuvaddr[i++] = host1x_opcode_incr_w(SE_SHA_MSG_LENGTH);
cpuvaddr[i++] = lower_32_bits(msg_len);
cpuvaddr[i++] = upper_32_bits(msg_len);
cpuvaddr[i++] = 0;
@@ -246,15 +243,14 @@ static int tegra_sha_prep_cmd(struct tegra_se *se, u32 *cpuvaddr,
cpuvaddr[i++] = 0;
cpuvaddr[i++] = 0;
cpuvaddr[i++] = host1x_opcode_setpayload(6);
cpuvaddr[i++] = se_host1x_opcode_incr_w(SE_SHA_CFG);
cpuvaddr[i++] = host1x_opcode_incr_w(SE_SHA_CFG);
cpuvaddr[i++] = rctx->config;
if (rctx->task & SHA_FIRST) {
cpuvaddr[i++] = SE_SHA_TASK_HASH_INIT;
rctx->task &= ~SHA_FIRST;
} else {
} else
cpuvaddr[i++] = 0;
}
cpuvaddr[i++] = rctx->datbuf.addr;
cpuvaddr[i++] = (u32)(SE_ADDR_HI_MSB(upper_32_bits(rctx->datbuf.addr)) |
@@ -264,47 +260,30 @@ static int tegra_sha_prep_cmd(struct tegra_se *se, u32 *cpuvaddr,
SE_ADDR_HI_SZ(rctx->digest.size));
if (rctx->key_id) {
cpuvaddr[i++] = host1x_opcode_setpayload(1);
cpuvaddr[i++] = se_host1x_opcode_nonincr_w(SE_SHA_CRYPTO_CFG);
cpuvaddr[i++] = host1x_opcode_nonincr_w(SE_SHA_CRYPTO_CFG);
cpuvaddr[i++] = SE_AES_KEY_INDEX(rctx->key_id);
}
cpuvaddr[i++] = host1x_opcode_setpayload(1);
cpuvaddr[i++] = se_host1x_opcode_nonincr_w(SE_SHA_OPERATION);
cpuvaddr[i++] = host1x_opcode_nonincr_w(SE_SHA_OPERATION);
cpuvaddr[i++] = SE_SHA_OP_WRSTALL |
SE_SHA_OP_START |
SE_SHA_OP_LASTBUF;
cpuvaddr[i++] = se_host1x_opcode_nonincr(host1x_uclass_incr_syncpt_r(), 1);
cpuvaddr[i++] = host1x_opcode_nonincr(host1x_uclass_incr_syncpt_r(), 1);
cpuvaddr[i++] = host1x_uclass_incr_syncpt_cond_f(1) |
host1x_uclass_incr_syncpt_indx_f(se->syncpt_id);
dev_dbg(se->dev, "msg len %llu msg left %llu cfg %#x",
msg_len, msg_left, rctx->config);
msg_len, msg_left, rctx->config);
return i;
}
static void tegra_sha_copy_hash_result(struct tegra_se *se, struct tegra_sha_reqctx *rctx)
{
int i;
for (i = 0; i < HASH_RESULT_REG_COUNT; i++)
rctx->result[i] = readl(se->base + se->hw->regs->result + (i * 4));
}
static void tegra_sha_paste_hash_result(struct tegra_se *se, struct tegra_sha_reqctx *rctx)
{
int i;
for (i = 0; i < HASH_RESULT_REG_COUNT; i++)
writel(rctx->result[i],
se->base + se->hw->regs->result + (i * 4));
}
static int tegra_sha_do_update(struct ahash_request *req)
{
struct tegra_sha_ctx *ctx = crypto_ahash_ctx(crypto_ahash_reqtfm(req));
struct tegra_sha_reqctx *rctx = ahash_request_ctx(req);
unsigned int nblks, nresidue, size, ret;
unsigned int nblks, nresidue, size;
u32 *cpuvaddr = ctx->se->cmdbuf->addr;
nresidue = (req->nbytes + rctx->residue.size) % rctx->blk_size;
@@ -329,7 +308,7 @@ static int tegra_sha_do_update(struct ahash_request *req)
*/
if (nblks < 1) {
scatterwalk_map_and_copy(rctx->residue.buf + rctx->residue.size,
rctx->src_sg, 0, req->nbytes, 0);
rctx->src_sg, 0, req->nbytes, 0);
rctx->residue.size += req->nbytes;
return 0;
@@ -340,10 +319,10 @@ static int tegra_sha_do_update(struct ahash_request *req)
memcpy(rctx->datbuf.buf, rctx->residue.buf, rctx->residue.size);
scatterwalk_map_and_copy(rctx->datbuf.buf + rctx->residue.size,
rctx->src_sg, 0, req->nbytes - nresidue, 0);
rctx->src_sg, 0, req->nbytes - nresidue, 0);
scatterwalk_map_and_copy(rctx->residue.buf, rctx->src_sg,
req->nbytes - nresidue, nresidue, 0);
req->nbytes - nresidue, nresidue, 0);
/* Update residue value with the residue after current block */
rctx->residue.size = nresidue;
@@ -351,27 +330,9 @@ static int tegra_sha_do_update(struct ahash_request *req)
rctx->config = tegra_sha_get_config(rctx->alg) |
SE_SHA_DST_HASH_REG;
/*
* If this is not the first 'update' call, paste the previous copied
* intermediate results to the registers so that it gets picked up.
* This is to support the import/export functionality.
*/
if (!(rctx->task & SHA_FIRST))
tegra_sha_paste_hash_result(ctx->se, rctx);
size = tegra_sha_prep_cmd(ctx->se, cpuvaddr, rctx);
ret = tegra_se_host1x_submit(ctx->se, size);
/*
* If this is not the final update, copy the intermediate results
* from the registers so that it can be used in the next 'update'
* call. This is to support the import/export functionality.
*/
if (!(rctx->task & SHA_FINAL))
tegra_sha_copy_hash_result(ctx->se, rctx);
return ret;
return tegra_se_host1x_submit(ctx->se, size);
}
static int tegra_sha_do_final(struct ahash_request *req)
@@ -401,11 +362,11 @@ static int tegra_sha_do_final(struct ahash_request *req)
out:
dma_free_coherent(se->dev, SE_SHA_BUFLEN,
rctx->datbuf.buf, rctx->datbuf.addr);
rctx->datbuf.buf, rctx->datbuf.addr);
dma_free_coherent(se->dev, crypto_ahash_blocksize(tfm),
rctx->residue.buf, rctx->residue.addr);
rctx->residue.buf, rctx->residue.addr);
dma_free_coherent(se->dev, rctx->digest.size, rctx->digest.buf,
rctx->digest.addr);
rctx->digest.addr);
return ret;
}
@@ -416,7 +377,7 @@ static int tegra_sha_do_one_req(struct crypto_engine *engine, void *areq)
struct crypto_ahash *tfm = crypto_ahash_reqtfm(req);
struct tegra_sha_ctx *ctx = crypto_ahash_ctx(tfm);
struct tegra_se *se = ctx->se;
int ret = 0;
int ret = -EINVAL;
if (rctx->task & SHA_UPDATE) {
ret = tegra_sha_do_update(req);
@@ -430,73 +391,44 @@ static int tegra_sha_do_one_req(struct crypto_engine *engine, void *areq)
crypto_finalize_hash_request(se->engine, req, ret);
return 0;
return ret;
}
static void tegra_sha_init_fallback(struct crypto_ahash *tfm, struct tegra_sha_ctx *ctx,
const char *algname)
static void tegra_sha_init_fallback(struct tegra_sha_ctx *ctx, const char *algname)
{
unsigned int statesize;
ctx->fallback_tfm = crypto_alloc_ahash(algname, 0, CRYPTO_ALG_ASYNC |
CRYPTO_ALG_NEED_FALLBACK);
if (IS_ERR(ctx->fallback_tfm)) {
dev_warn(ctx->se->dev,
"failed to allocate fallback for %s\n", algname);
dev_warn(ctx->se->dev, "failed to allocate fallback for %s %ld\n",
algname, PTR_ERR(ctx->fallback_tfm));
ctx->fallback_tfm = NULL;
return;
}
statesize = crypto_ahash_statesize(ctx->fallback_tfm);
if (statesize > sizeof(struct tegra_sha_reqctx))
crypto_hash_alg_common(tfm)->statesize = statesize;
/* Update reqsize if fallback is added */
crypto_ahash_set_reqsize(tfm,
sizeof(struct tegra_sha_reqctx) +
crypto_ahash_reqsize(ctx->fallback_tfm));
}
static int tegra_sha_cra_init(struct crypto_tfm *tfm)
{
struct tegra_sha_ctx *ctx = crypto_tfm_ctx(tfm);
struct crypto_ahash *ahash_tfm = __crypto_ahash_cast(tfm);
struct ahash_alg *alg = __crypto_ahash_alg(tfm->__crt_alg);
struct tegra_se_alg *se_alg;
const char *algname;
int ret;
algname = crypto_tfm_alg_name(tfm);
#ifdef NV_CONFTEST_REMOVE_STRUCT_CRYPTO_ENGINE_CTX
se_alg = container_of(alg, struct tegra_se_alg, alg.ahash.base);
#else
se_alg = container_of(alg, struct tegra_se_alg, alg.ahash);
#endif
crypto_ahash_set_reqsize(ahash_tfm, sizeof(struct tegra_sha_reqctx));
crypto_ahash_set_reqsize(__crypto_ahash_cast(tfm),
sizeof(struct tegra_sha_reqctx));
ctx->se = se_alg->se_dev;
ctx->fallback = false;
ctx->key_id = 0;
ret = se_algname_to_algid(algname);
if (ret < 0) {
dev_err(ctx->se->dev, "invalid algorithm\n");
return ret;
}
ctx->alg = se_algname_to_algid(algname);
ctx->enginectx.op.prepare_request = NULL;
ctx->enginectx.op.do_one_request = tegra_sha_do_one_req;
ctx->enginectx.op.unprepare_request = NULL;
if (se_alg->alg_base)
tegra_sha_init_fallback(ahash_tfm, ctx, algname);
ctx->alg = ret;
#ifndef NV_CONFTEST_REMOVE_STRUCT_CRYPTO_ENGINE_CTX
ctx->enginectx.op.prepare_request = NULL;
ctx->enginectx.op.unprepare_request = NULL;
ctx->enginectx.op.do_one_request = tegra_sha_do_one_req;
#endif
tegra_sha_init_fallback(ctx, algname);
return 0;
}
@@ -508,7 +440,7 @@ static void tegra_sha_cra_exit(struct crypto_tfm *tfm)
if (ctx->fallback_tfm)
crypto_free_ahash(ctx->fallback_tfm);
tegra_key_invalidate(ctx->se, ctx->key_id, ctx->alg);
tegra_key_invalidate(ctx->se, ctx->key_id);
}
static int tegra_sha_init(struct ahash_request *req)
@@ -517,31 +449,34 @@ static int tegra_sha_init(struct ahash_request *req)
struct crypto_ahash *tfm = crypto_ahash_reqtfm(req);
struct tegra_sha_ctx *ctx = crypto_ahash_ctx(tfm);
struct tegra_se *se = ctx->se;
const char *algname;
if (ctx->fallback)
return tegra_sha_fallback_init(req);
algname = crypto_tfm_alg_name(&tfm->base);
rctx->total_len = 0;
rctx->datbuf.size = 0;
rctx->residue.size = 0;
rctx->key_id = ctx->key_id;
rctx->task = SHA_FIRST;
rctx->alg = ctx->alg;
rctx->alg = se_algname_to_algid(algname);
rctx->blk_size = crypto_ahash_blocksize(tfm);
rctx->digest.size = crypto_ahash_digestsize(tfm);
rctx->digest.buf = dma_alloc_coherent(se->dev, rctx->digest.size,
&rctx->digest.addr, GFP_KERNEL);
&rctx->digest.addr, GFP_KERNEL);
if (!rctx->digest.buf)
goto digbuf_fail;
rctx->residue.buf = dma_alloc_coherent(se->dev, rctx->blk_size,
&rctx->residue.addr, GFP_KERNEL);
&rctx->residue.addr, GFP_KERNEL);
if (!rctx->residue.buf)
goto resbuf_fail;
rctx->datbuf.buf = dma_alloc_coherent(se->dev, SE_SHA_BUFLEN,
&rctx->datbuf.addr, GFP_KERNEL);
&rctx->datbuf.addr, GFP_KERNEL);
if (!rctx->datbuf.buf)
goto datbuf_fail;
@@ -549,19 +484,19 @@ static int tegra_sha_init(struct ahash_request *req)
datbuf_fail:
dma_free_coherent(se->dev, rctx->blk_size, rctx->residue.buf,
rctx->residue.addr);
rctx->residue.addr);
resbuf_fail:
dma_free_coherent(se->dev, SE_SHA_BUFLEN, rctx->datbuf.buf,
rctx->datbuf.addr);
rctx->datbuf.addr);
digbuf_fail:
return -ENOMEM;
}
static int tegra_hmac_fallback_setkey(struct tegra_sha_ctx *ctx, const u8 *key,
int tegra_hmac_fallback_setkey(struct tegra_sha_ctx *ctx, const u8 *key,
unsigned int keylen)
{
if (!ctx->fallback_tfm) {
dev_dbg(ctx->se->dev, "invalid key length (%d)\n", keylen);
dev_err(ctx->se->dev, "invalid key length\n");
return -EINVAL;
}
@@ -649,6 +584,9 @@ static int tegra_sha_export(struct ahash_request *req, void *out)
return tegra_sha_fallback_export(req, out);
memcpy(out, rctx, sizeof(*rctx));
/*
* TODO: Copy HASH_RESULT registers as well.
*/
return 0;
}
@@ -670,9 +608,6 @@ static int tegra_sha_import(struct ahash_request *req, const void *in)
static struct tegra_se_alg tegra_hash_algs[] = {
{
.alg.ahash = {
#ifdef NV_CONFTEST_REMOVE_STRUCT_CRYPTO_ENGINE_CTX
.base = {
#endif
.init = tegra_sha_init,
.update = tegra_sha_update,
.final = tegra_sha_final,
@@ -682,6 +617,7 @@ static struct tegra_se_alg tegra_hash_algs[] = {
.import = tegra_sha_import,
.halg.digestsize = SHA1_DIGEST_SIZE,
.halg.statesize = sizeof(struct tegra_sha_reqctx),
.halg.base = {
.cra_name = "sha1",
.cra_driver_name = "tegra-se-sha1",
@@ -694,16 +630,9 @@ static struct tegra_se_alg tegra_hash_algs[] = {
.cra_init = tegra_sha_cra_init,
.cra_exit = tegra_sha_cra_exit,
}
#ifdef NV_CONFTEST_REMOVE_STRUCT_CRYPTO_ENGINE_CTX
},
.op.do_one_request = tegra_sha_do_one_req,
#endif
}
}, {
.alg.ahash = {
#ifdef NV_CONFTEST_REMOVE_STRUCT_CRYPTO_ENGINE_CTX
.base = {
#endif
.init = tegra_sha_init,
.update = tegra_sha_update,
.final = tegra_sha_final,
@@ -713,6 +642,7 @@ static struct tegra_se_alg tegra_hash_algs[] = {
.import = tegra_sha_import,
.halg.digestsize = SHA224_DIGEST_SIZE,
.halg.statesize = sizeof(struct tegra_sha_reqctx),
.halg.base = {
.cra_name = "sha224",
.cra_driver_name = "tegra-se-sha224",
@@ -725,16 +655,9 @@ static struct tegra_se_alg tegra_hash_algs[] = {
.cra_init = tegra_sha_cra_init,
.cra_exit = tegra_sha_cra_exit,
}
#ifdef NV_CONFTEST_REMOVE_STRUCT_CRYPTO_ENGINE_CTX
},
.op.do_one_request = tegra_sha_do_one_req,
#endif
}
}, {
.alg.ahash = {
#ifdef NV_CONFTEST_REMOVE_STRUCT_CRYPTO_ENGINE_CTX
.base = {
#endif
.init = tegra_sha_init,
.update = tegra_sha_update,
.final = tegra_sha_final,
@@ -744,6 +667,7 @@ static struct tegra_se_alg tegra_hash_algs[] = {
.import = tegra_sha_import,
.halg.digestsize = SHA256_DIGEST_SIZE,
.halg.statesize = sizeof(struct tegra_sha_reqctx),
.halg.base = {
.cra_name = "sha256",
.cra_driver_name = "tegra-se-sha256",
@@ -756,16 +680,9 @@ static struct tegra_se_alg tegra_hash_algs[] = {
.cra_init = tegra_sha_cra_init,
.cra_exit = tegra_sha_cra_exit,
}
#ifdef NV_CONFTEST_REMOVE_STRUCT_CRYPTO_ENGINE_CTX
},
.op.do_one_request = tegra_sha_do_one_req,
#endif
}
}, {
.alg.ahash = {
#ifdef NV_CONFTEST_REMOVE_STRUCT_CRYPTO_ENGINE_CTX
.base = {
#endif
.init = tegra_sha_init,
.update = tegra_sha_update,
.final = tegra_sha_final,
@@ -775,6 +692,7 @@ static struct tegra_se_alg tegra_hash_algs[] = {
.import = tegra_sha_import,
.halg.digestsize = SHA384_DIGEST_SIZE,
.halg.statesize = sizeof(struct tegra_sha_reqctx),
.halg.base = {
.cra_name = "sha384",
.cra_driver_name = "tegra-se-sha384",
@@ -787,16 +705,9 @@ static struct tegra_se_alg tegra_hash_algs[] = {
.cra_init = tegra_sha_cra_init,
.cra_exit = tegra_sha_cra_exit,
}
#ifdef NV_CONFTEST_REMOVE_STRUCT_CRYPTO_ENGINE_CTX
},
.op.do_one_request = tegra_sha_do_one_req,
#endif
}
}, {
.alg.ahash = {
#ifdef NV_CONFTEST_REMOVE_STRUCT_CRYPTO_ENGINE_CTX
.base = {
#endif
.init = tegra_sha_init,
.update = tegra_sha_update,
.final = tegra_sha_final,
@@ -806,6 +717,7 @@ static struct tegra_se_alg tegra_hash_algs[] = {
.import = tegra_sha_import,
.halg.digestsize = SHA512_DIGEST_SIZE,
.halg.statesize = sizeof(struct tegra_sha_reqctx),
.halg.base = {
.cra_name = "sha512",
.cra_driver_name = "tegra-se-sha512",
@@ -818,16 +730,9 @@ static struct tegra_se_alg tegra_hash_algs[] = {
.cra_init = tegra_sha_cra_init,
.cra_exit = tegra_sha_cra_exit,
}
#ifdef NV_CONFTEST_REMOVE_STRUCT_CRYPTO_ENGINE_CTX
},
.op.do_one_request = tegra_sha_do_one_req,
#endif
}
}, {
.alg.ahash = {
#ifdef NV_CONFTEST_REMOVE_STRUCT_CRYPTO_ENGINE_CTX
.base = {
#endif
.init = tegra_sha_init,
.update = tegra_sha_update,
.final = tegra_sha_final,
@@ -837,6 +742,7 @@ static struct tegra_se_alg tegra_hash_algs[] = {
.import = tegra_sha_import,
.halg.digestsize = SHA3_224_DIGEST_SIZE,
.halg.statesize = sizeof(struct tegra_sha_reqctx),
.halg.base = {
.cra_name = "sha3-224",
.cra_driver_name = "tegra-se-sha3-224",
@@ -849,16 +755,9 @@ static struct tegra_se_alg tegra_hash_algs[] = {
.cra_init = tegra_sha_cra_init,
.cra_exit = tegra_sha_cra_exit,
}
#ifdef NV_CONFTEST_REMOVE_STRUCT_CRYPTO_ENGINE_CTX
},
.op.do_one_request = tegra_sha_do_one_req,
#endif
}
}, {
.alg.ahash = {
#ifdef NV_CONFTEST_REMOVE_STRUCT_CRYPTO_ENGINE_CTX
.base = {
#endif
.init = tegra_sha_init,
.update = tegra_sha_update,
.final = tegra_sha_final,
@@ -868,6 +767,7 @@ static struct tegra_se_alg tegra_hash_algs[] = {
.import = tegra_sha_import,
.halg.digestsize = SHA3_256_DIGEST_SIZE,
.halg.statesize = sizeof(struct tegra_sha_reqctx),
.halg.base = {
.cra_name = "sha3-256",
.cra_driver_name = "tegra-se-sha3-256",
@@ -880,16 +780,9 @@ static struct tegra_se_alg tegra_hash_algs[] = {
.cra_init = tegra_sha_cra_init,
.cra_exit = tegra_sha_cra_exit,
}
#ifdef NV_CONFTEST_REMOVE_STRUCT_CRYPTO_ENGINE_CTX
},
.op.do_one_request = tegra_sha_do_one_req,
#endif
}
}, {
.alg.ahash = {
#ifdef NV_CONFTEST_REMOVE_STRUCT_CRYPTO_ENGINE_CTX
.base = {
#endif
.init = tegra_sha_init,
.update = tegra_sha_update,
.final = tegra_sha_final,
@@ -899,6 +792,7 @@ static struct tegra_se_alg tegra_hash_algs[] = {
.import = tegra_sha_import,
.halg.digestsize = SHA3_384_DIGEST_SIZE,
.halg.statesize = sizeof(struct tegra_sha_reqctx),
.halg.base = {
.cra_name = "sha3-384",
.cra_driver_name = "tegra-se-sha3-384",
@@ -911,16 +805,9 @@ static struct tegra_se_alg tegra_hash_algs[] = {
.cra_init = tegra_sha_cra_init,
.cra_exit = tegra_sha_cra_exit,
}
#ifdef NV_CONFTEST_REMOVE_STRUCT_CRYPTO_ENGINE_CTX
},
.op.do_one_request = tegra_sha_do_one_req,
#endif
}
}, {
.alg.ahash = {
#ifdef NV_CONFTEST_REMOVE_STRUCT_CRYPTO_ENGINE_CTX
.base = {
#endif
.init = tegra_sha_init,
.update = tegra_sha_update,
.final = tegra_sha_final,
@@ -930,6 +817,7 @@ static struct tegra_se_alg tegra_hash_algs[] = {
.import = tegra_sha_import,
.halg.digestsize = SHA3_512_DIGEST_SIZE,
.halg.statesize = sizeof(struct tegra_sha_reqctx),
.halg.base = {
.cra_name = "sha3-512",
.cra_driver_name = "tegra-se-sha3-512",
@@ -942,17 +830,10 @@ static struct tegra_se_alg tegra_hash_algs[] = {
.cra_init = tegra_sha_cra_init,
.cra_exit = tegra_sha_cra_exit,
}
#ifdef NV_CONFTEST_REMOVE_STRUCT_CRYPTO_ENGINE_CTX
},
.op.do_one_request = tegra_sha_do_one_req,
#endif
}
}, {
.alg_base = "sha224",
.alg.ahash = {
#ifdef NV_CONFTEST_REMOVE_STRUCT_CRYPTO_ENGINE_CTX
.base = {
#endif
.init = tegra_sha_init,
.update = tegra_sha_update,
.final = tegra_sha_final,
@@ -963,6 +844,7 @@ static struct tegra_se_alg tegra_hash_algs[] = {
.setkey = tegra_hmac_setkey,
.halg.digestsize = SHA224_DIGEST_SIZE,
.halg.statesize = sizeof(struct tegra_sha_reqctx),
.halg.base = {
.cra_name = "hmac(sha224)",
.cra_driver_name = "tegra-se-hmac-sha224",
@@ -975,17 +857,10 @@ static struct tegra_se_alg tegra_hash_algs[] = {
.cra_init = tegra_sha_cra_init,
.cra_exit = tegra_sha_cra_exit,
}
#ifdef NV_CONFTEST_REMOVE_STRUCT_CRYPTO_ENGINE_CTX
},
.op.do_one_request = tegra_sha_do_one_req,
#endif
}
}, {
.alg_base = "sha256",
.alg.ahash = {
#ifdef NV_CONFTEST_REMOVE_STRUCT_CRYPTO_ENGINE_CTX
.base = {
#endif
.init = tegra_sha_init,
.update = tegra_sha_update,
.final = tegra_sha_final,
@@ -996,6 +871,7 @@ static struct tegra_se_alg tegra_hash_algs[] = {
.setkey = tegra_hmac_setkey,
.halg.digestsize = SHA256_DIGEST_SIZE,
.halg.statesize = sizeof(struct tegra_sha_reqctx),
.halg.base = {
.cra_name = "hmac(sha256)",
.cra_driver_name = "tegra-se-hmac-sha256",
@@ -1008,17 +884,10 @@ static struct tegra_se_alg tegra_hash_algs[] = {
.cra_init = tegra_sha_cra_init,
.cra_exit = tegra_sha_cra_exit,
}
#ifdef NV_CONFTEST_REMOVE_STRUCT_CRYPTO_ENGINE_CTX
},
.op.do_one_request = tegra_sha_do_one_req,
#endif
}
}, {
.alg_base = "sha384",
.alg.ahash = {
#ifdef NV_CONFTEST_REMOVE_STRUCT_CRYPTO_ENGINE_CTX
.base = {
#endif
.init = tegra_sha_init,
.update = tegra_sha_update,
.final = tegra_sha_final,
@@ -1029,6 +898,7 @@ static struct tegra_se_alg tegra_hash_algs[] = {
.setkey = tegra_hmac_setkey,
.halg.digestsize = SHA384_DIGEST_SIZE,
.halg.statesize = sizeof(struct tegra_sha_reqctx),
.halg.base = {
.cra_name = "hmac(sha384)",
.cra_driver_name = "tegra-se-hmac-sha384",
@@ -1041,17 +911,10 @@ static struct tegra_se_alg tegra_hash_algs[] = {
.cra_init = tegra_sha_cra_init,
.cra_exit = tegra_sha_cra_exit,
}
#ifdef NV_CONFTEST_REMOVE_STRUCT_CRYPTO_ENGINE_CTX
},
.op.do_one_request = tegra_sha_do_one_req,
#endif
}
}, {
.alg_base = "sha512",
.alg.ahash = {
#ifdef NV_CONFTEST_REMOVE_STRUCT_CRYPTO_ENGINE_CTX
.base = {
#endif
.init = tegra_sha_init,
.update = tegra_sha_update,
.final = tegra_sha_final,
@@ -1062,6 +925,7 @@ static struct tegra_se_alg tegra_hash_algs[] = {
.setkey = tegra_hmac_setkey,
.halg.digestsize = SHA512_DIGEST_SIZE,
.halg.statesize = sizeof(struct tegra_sha_reqctx),
.halg.base = {
.cra_name = "hmac(sha512)",
.cra_driver_name = "tegra-se-hmac-sha512",
@@ -1074,10 +938,6 @@ static struct tegra_se_alg tegra_hash_algs[] = {
.cra_init = tegra_sha_cra_init,
.cra_exit = tegra_sha_cra_exit,
}
#ifdef NV_CONFTEST_REMOVE_STRUCT_CRYPTO_ENGINE_CTX
},
.op.do_one_request = tegra_sha_do_one_req,
#endif
}
}
};
@@ -1117,45 +977,37 @@ static int tegra_hash_kac_manifest(u32 user, u32 alg, u32 keylen)
int tegra_init_hash(struct tegra_se *se)
{
#ifdef NV_CONFTEST_REMOVE_STRUCT_CRYPTO_ENGINE_CTX
struct ahash_engine_alg *alg;
#else
struct ahash_alg *alg;
#endif
int i, ret;
se->manifest = tegra_hash_kac_manifest;
for (i = 0; i < ARRAY_SIZE(tegra_hash_algs); i++) {
tegra_hash_algs[i].se_dev = se;
alg = &tegra_hash_algs[i].alg.ahash;
ret = CRYPTO_REGISTER(ahash, alg);
tegra_hash_algs[i].se_dev = se;
ret = crypto_register_ahash(&tegra_hash_algs[i].alg.ahash);
if (ret) {
#ifdef NV_CONFTEST_REMOVE_STRUCT_CRYPTO_ENGINE_CTX
dev_err(se->dev, "failed to register %s\n",
alg->base.halg.base.cra_name);
#else
dev_err(se->dev, "failed to register %s\n",
alg->halg.base.cra_name);
#endif
tegra_hash_algs[i].alg.ahash.halg.base.cra_name);
goto sha_err;
}
}
dev_info(se->dev, "registered HASH algorithms\n");
return 0;
sha_err:
for (--i; i >= 0; i--)
CRYPTO_UNREGISTER(ahash, &tegra_hash_algs[i].alg.ahash);
crypto_unregister_ahash(&tegra_hash_algs[i].alg.ahash);
return ret;
}
void tegra_deinit_hash(struct tegra_se *se)
void tegra_deinit_hash(void)
{
int i;
for (i = 0; i < ARRAY_SIZE(tegra_hash_algs); i++)
CRYPTO_UNREGISTER(ahash, &tegra_hash_algs[i].alg.ahash);
crypto_unregister_ahash(&tegra_hash_algs[i].alg.ahash);
}

View File

@@ -1,5 +1,5 @@
// SPDX-License-Identifier: GPL-2.0-only
// SPDX-FileCopyrightText: Copyright (c) 2023-2024 NVIDIA CORPORATION & AFFILIATES. All rights reserved.
// SPDX-FileCopyrightText: Copyright (c) 2023 NVIDIA CORPORATION & AFFILIATES. All rights reserved.
/*
* Crypto driver file to manage keys of NVIDIA Security Engine.
*/
@@ -16,77 +16,66 @@
#define SE_KEY_RSVD_MASK (BIT(0) | BIT(14) | BIT(15))
#define SE_KEY_VALID_MASK (SE_KEY_FULL_MASK & ~SE_KEY_RSVD_MASK)
/* Mutex lock to guard keyslots */
static DEFINE_MUTEX(kslt_lock);
/* Keyslot bitmask (0 = available, 1 = in use/not available) */
static u16 tegra_se_keyslots = SE_KEY_RSVD_MASK;
static u16 tegra_keyslot_alloc(void)
{
u16 keyid;
mutex_lock(&kslt_lock);
/* Check if all key slots are full */
if (tegra_se_keyslots == GENMASK(SE_MAX_KEYSLOT, 0)) {
mutex_unlock(&kslt_lock);
if (tegra_se_keyslots == GENMASK(SE_MAX_KEYSLOT, 0))
return 0;
}
keyid = ffz(tegra_se_keyslots);
tegra_se_keyslots |= BIT(keyid);
mutex_unlock(&kslt_lock);
return keyid;
}
static void tegra_keyslot_free(u16 slot)
{
mutex_lock(&kslt_lock);
tegra_se_keyslots &= ~(BIT(slot));
mutex_unlock(&kslt_lock);
}
static unsigned int tegra_key_prep_ins_cmd(struct tegra_se *se, u32 *cpuvaddr,
const u32 *key, u32 keylen, u16 slot, u32 alg)
const u32 *key, u32 keylen, u16 slot, u32 alg)
{
int i = 0, j;
cpuvaddr[i++] = host1x_opcode_setpayload(1);
cpuvaddr[i++] = se_host1x_opcode_incr_w(se->hw->regs->op);
cpuvaddr[i++] = host1x_opcode_incr_w(se->hw->regs->op);
cpuvaddr[i++] = SE_AES_OP_WRSTALL | SE_AES_OP_DUMMY;
cpuvaddr[i++] = host1x_opcode_setpayload(1);
cpuvaddr[i++] = se_host1x_opcode_incr_w(se->hw->regs->manifest);
cpuvaddr[i++] = host1x_opcode_incr_w(se->hw->regs->manifest);
cpuvaddr[i++] = se->manifest(se->owner, alg, keylen);
cpuvaddr[i++] = host1x_opcode_setpayload(1);
cpuvaddr[i++] = se_host1x_opcode_incr_w(se->hw->regs->key_dst);
cpuvaddr[i++] = host1x_opcode_incr_w(se->hw->regs->key_dst);
cpuvaddr[i++] = SE_AES_KEY_DST_INDEX(slot);
for (j = 0; j < keylen / 4; j++) {
/* Set key address */
cpuvaddr[i++] = host1x_opcode_setpayload(1);
cpuvaddr[i++] = se_host1x_opcode_incr_w(se->hw->regs->key_addr);
cpuvaddr[i++] = host1x_opcode_incr_w(se->hw->regs->key_addr);
cpuvaddr[i++] = j;
/* Set key data */
cpuvaddr[i++] = host1x_opcode_setpayload(1);
cpuvaddr[i++] = se_host1x_opcode_incr_w(se->hw->regs->key_data);
cpuvaddr[i++] = host1x_opcode_incr_w(se->hw->regs->key_data);
cpuvaddr[i++] = key[j];
}
cpuvaddr[i++] = host1x_opcode_setpayload(1);
cpuvaddr[i++] = se_host1x_opcode_incr_w(se->hw->regs->config);
cpuvaddr[i++] = host1x_opcode_incr_w(se->hw->regs->config);
cpuvaddr[i++] = SE_CFG_INS;
cpuvaddr[i++] = host1x_opcode_setpayload(1);
cpuvaddr[i++] = se_host1x_opcode_incr_w(se->hw->regs->op);
cpuvaddr[i++] = host1x_opcode_incr_w(se->hw->regs->op);
cpuvaddr[i++] = SE_AES_OP_WRSTALL | SE_AES_OP_START |
SE_AES_OP_LASTBUF;
cpuvaddr[i++] = se_host1x_opcode_nonincr(host1x_uclass_incr_syncpt_r(), 1);
cpuvaddr[i++] = host1x_opcode_nonincr(host1x_uclass_incr_syncpt_r(), 1);
cpuvaddr[i++] = host1x_uclass_incr_syncpt_cond_f(1) |
host1x_uclass_incr_syncpt_indx_f(se->syncpt_id);
@@ -98,21 +87,15 @@ static unsigned int tegra_key_prep_ins_cmd(struct tegra_se *se, u32 *cpuvaddr,
static bool tegra_key_in_kslt(u32 keyid)
{
bool ret;
if (keyid > SE_MAX_KEYSLOT)
return false;
mutex_lock(&kslt_lock);
ret = ((BIT(keyid) & SE_KEY_VALID_MASK) &&
return ((BIT(keyid) & SE_KEY_VALID_MASK) &&
(BIT(keyid) & tegra_se_keyslots));
mutex_unlock(&kslt_lock);
return ret;
}
static int tegra_key_insert(struct tegra_se *se, const u8 *key,
u32 keylen, u16 slot, u32 alg)
u32 keylen, u16 slot, u32 alg)
{
const u32 *keyval = (u32 *)key;
u32 *addr = se->cmdbuf->addr, size;
@@ -122,16 +105,11 @@ static int tegra_key_insert(struct tegra_se *se, const u8 *key,
return tegra_se_host1x_submit(se, size);
}
void tegra_key_invalidate(struct tegra_se *se, u32 keyid, u32 alg)
void tegra_key_invalidate(struct tegra_se *se, u32 keyid)
{
u8 zkey[AES_MAX_KEY_SIZE] = {0};
if (!keyid)
return;
/* Overwrite the key with 0s */
tegra_key_insert(se, zkey, AES_MAX_KEY_SIZE, keyid, alg);
tegra_keyslot_free(keyid);
}
@@ -142,10 +120,8 @@ int tegra_key_submit(struct tegra_se *se, const u8 *key, u32 keylen, u32 alg, u3
/* Use the existing slot if it is already allocated */
if (!tegra_key_in_kslt(*keyid)) {
*keyid = tegra_keyslot_alloc();
if (!(*keyid)) {
dev_err(se->dev, "failed to allocate key slot\n");
if (!(*keyid))
return -ENOMEM;
}
}
ret = tegra_key_insert(se, key, keylen, *keyid, alg);

View File

@@ -1,11 +1,12 @@
// SPDX-License-Identifier: GPL-2.0-only
// SPDX-FileCopyrightText: Copyright (c) 2023-2024 NVIDIA CORPORATION & AFFILIATES. All rights reserved.
// SPDX-FileCopyrightText: Copyright (c) 2023 NVIDIA CORPORATION & AFFILIATES. All rights reserved.
/*
* Crypto driver for NVIDIA Security Engine in Tegra Chips
*/
#include <linux/clk.h>
#include <linux/dma-mapping.h>
#include <linux/host1x-next.h>
#include <linux/module.h>
#include <linux/platform_device.h>
#include <linux/mod_devicetable.h>
@@ -123,7 +124,7 @@ static struct tegra_se_cmdbuf *tegra_se_host1x_bo_alloc(struct tegra_se *se, ssi
struct tegra_se_cmdbuf *cmdbuf;
struct device *dev = se->dev->parent;
cmdbuf = kzalloc(sizeof(*cmdbuf), GFP_KERNEL);
cmdbuf = kzalloc(sizeof(struct tegra_se_cmdbuf), GFP_KERNEL);
if (!cmdbuf)
return NULL;
@@ -152,7 +153,7 @@ int tegra_se_host1x_submit(struct tegra_se *se, u32 size)
return -ENOMEM;
}
job->syncpt = host1x_syncpt_get(se->syncpt);
job->syncpt = host1x_syncpt_get(se->syncpt);
job->syncpt_incrs = 1;
job->client = &se->client;
job->class = se->client.class;
@@ -167,17 +168,17 @@ int tegra_se_host1x_submit(struct tegra_se *se, u32 size)
ret = host1x_job_pin(job, se->dev);
if (ret) {
dev_err(se->dev, "failed to pin host1x job\n");
goto job_put;
goto err_job_pin;
}
ret = host1x_job_submit(job);
if (ret) {
dev_err(se->dev, "failed to submit host1x job\n");
goto job_unpin;
goto err_job_submit;
}
ret = host1x_syncpt_wait(job->syncpt, job->syncpt_end,
MAX_SCHEDULE_TIMEOUT, NULL);
MAX_SCHEDULE_TIMEOUT, NULL);
if (ret) {
dev_err(se->dev, "host1x job timed out\n");
return ret;
@@ -186,9 +187,9 @@ int tegra_se_host1x_submit(struct tegra_se *se, u32 size)
host1x_job_put(job);
return 0;
job_unpin:
err_job_submit:
host1x_job_unpin(job);
job_put:
err_job_pin:
host1x_job_put(job);
return ret;
@@ -209,7 +210,7 @@ static int tegra_se_client_init(struct host1x_client *client)
if (!se->syncpt) {
dev_err(se->dev, "host1x syncpt allocation failed\n");
ret = -EINVAL;
goto channel_put;
goto err_syncpt;
}
se->syncpt_id = host1x_syncpt_id(se->syncpt);
@@ -217,22 +218,22 @@ static int tegra_se_client_init(struct host1x_client *client)
se->cmdbuf = tegra_se_host1x_bo_alloc(se, SZ_4K);
if (!se->cmdbuf) {
ret = -ENOMEM;
goto syncpt_put;
goto err_bo;
}
ret = se->hw->init_alg(se);
if (ret) {
dev_err(se->dev, "failed to register algorithms\n");
goto cmdbuf_put;
goto err_alg_reg;
}
return 0;
cmdbuf_put:
err_alg_reg:
tegra_se_cmdbuf_put(&se->cmdbuf->bo);
syncpt_put:
err_bo:
host1x_syncpt_put(se->syncpt);
channel_put:
err_syncpt:
host1x_channel_put(se->channel);
return ret;
@@ -242,7 +243,7 @@ static int tegra_se_client_deinit(struct host1x_client *client)
{
struct tegra_se *se = container_of(client, struct tegra_se, client);
se->hw->deinit_alg(se);
se->hw->deinit_alg();
tegra_se_cmdbuf_put(&se->cmdbuf->bo);
host1x_syncpt_put(se->syncpt);
host1x_channel_put(se->channel);
@@ -255,7 +256,7 @@ static const struct host1x_client_ops tegra_se_client_ops = {
.exit = tegra_se_client_deinit,
};
static int tegra_se_host1x_register(struct tegra_se *se)
int tegra_se_host1x_register(struct tegra_se *se)
{
INIT_LIST_HEAD(&se->client.list);
se->client.dev = se->dev;
@@ -268,6 +269,38 @@ static int tegra_se_host1x_register(struct tegra_se *se)
return 0;
}
static int tegra_se_clk_init(struct tegra_se *se)
{
int i, ret;
se->num_clks = devm_clk_bulk_get_all(se->dev, &se->clks);
if (se->num_clks < 0) {
dev_err(se->dev, "failed to get clocks\n");
return se->num_clks;
}
for (i = 0; i < se->num_clks; i++) {
ret = clk_set_rate(se->clks[i].clk, ULONG_MAX);
if (ret) {
dev_err(se->dev, "failed to set %d clock rate", i);
return ret;
}
}
ret = clk_bulk_prepare_enable(se->num_clks, se->clks);
if (ret) {
dev_err(se->dev, "failed to enable clocks\n");
return ret;
}
return 0;
}
static void tegra_se_clk_deinit(struct tegra_se *se)
{
clk_bulk_disable_unprepare(se->num_clks, se->clks);
}
static int tegra_se_probe(struct platform_device *pdev)
{
struct device *dev = &pdev->dev;
@@ -279,45 +312,61 @@ static int tegra_se_probe(struct platform_device *pdev)
return -ENOMEM;
se->dev = dev;
se->owner = TEGRA_GPSE_ID;
se->hw = device_get_match_data(&pdev->dev);
se->base = devm_platform_ioremap_resource(pdev, 0);
if (IS_ERR(se->base))
return PTR_ERR(se->base);
se->owner = TEGRA_GPSE_ID;
dma_set_mask_and_coherent(dev, DMA_BIT_MASK(39));
platform_set_drvdata(pdev, se);
se->clk = devm_clk_get_enabled(se->dev, NULL);
if (IS_ERR(se->clk))
return dev_err_probe(dev, PTR_ERR(se->clk),
"failed to enable clocks\n");
ret = tegra_se_clk_init(se);
if (ret) {
dev_err(dev, "failed to init clocks\n");
return ret;
}
if (!tegra_dev_iommu_get_stream_id(dev, &se->stream_id))
return dev_err_probe(dev, -ENODEV,
"failed to get IOMMU stream ID\n");
if (!tegra_dev_iommu_get_stream_id(dev, &se->stream_id)) {
dev_err(dev, "failed to get IOMMU stream ID\n");
goto err_iommu_spec;
}
writel(se->stream_id, se->base + SE_STREAM_ID);
se_writel(se, se->stream_id, SE_STREAM_ID);
se->engine = crypto_engine_alloc_init(dev, 0);
if (!se->engine)
return dev_err_probe(dev, -ENOMEM, "failed to init crypto engine\n");
if (!se->engine) {
dev_err(dev, "failed to init crypto engine\n");
ret = -ENOMEM;
goto err_engine_alloc;
}
ret = crypto_engine_start(se->engine);
if (ret) {
crypto_engine_exit(se->engine);
return dev_err_probe(dev, ret, "failed to start crypto engine\n");
dev_err(dev, "failed to start crypto engine\n");
goto err_engine_start;
}
ret = tegra_se_host1x_register(se);
if (ret) {
crypto_engine_stop(se->engine);
crypto_engine_exit(se->engine);
return dev_err_probe(dev, ret, "failed to init host1x params\n");
dev_err(dev, "failed to init host1x params\n");
goto err_host1x_init;
}
return 0;
err_host1x_init:
crypto_engine_stop(se->engine);
err_engine_start:
crypto_engine_exit(se->engine);
err_engine_alloc:
iommu_fwspec_free(se->dev);
err_iommu_spec:
tegra_se_clk_deinit(se);
return ret;
}
static int tegra_se_remove(struct platform_device *pdev)
@@ -328,6 +377,7 @@ static int tegra_se_remove(struct platform_device *pdev)
crypto_engine_exit(se->engine);
iommu_fwspec_free(se->dev);
host1x_client_unregister(&se->client);
tegra_se_clk_deinit(se);
return 0;
}
@@ -374,10 +424,10 @@ static const struct tegra_se_hw tegra234_hash_hw = {
static const struct of_device_id tegra_se_of_match[] = {
{
.compatible = "nvidia,tegra234-se-aes",
.compatible = "nvidia,tegra234-se2-aes",
.data = &tegra234_aes_hw
}, {
.compatible = "nvidia,tegra234-se-hash",
.compatible = "nvidia,tegra234-se4-hash",
.data = &tegra234_hash_hw,
},
{ },
@@ -436,4 +486,4 @@ module_exit(tegra_se_module_exit);
MODULE_DESCRIPTION("NVIDIA Tegra Security Engine Driver");
MODULE_AUTHOR("Akhil R <akhilrajeev@nvidia.com>");
MODULE_LICENSE("GPL");
MODULE_LICENSE("GPL v2");

View File

@@ -1,5 +1,5 @@
// SPDX-License-Identifier: GPL-2.0-only
// SPDX-FileCopyrightText: Copyright (c) 2023-2024 NVIDIA CORPORATION & AFFILIATES. All rights reserved.
// SPDX-FileCopyrightText: Copyright (c) 2023 NVIDIA CORPORATION & AFFILIATES. All rights reserved.
/*
* Header file for NVIDIA Security Engine driver.
*/
@@ -7,18 +7,19 @@
#ifndef _TEGRA_SE_H
#define _TEGRA_SE_H
#include <nvidia/conftest.h>
#include <linux/bitfield.h>
#include <linux/clk.h>
#include <linux/iommu.h>
#include <linux/host1x-next.h>
#include <linux/version.h>
#include <crypto/aead.h>
#include <crypto/engine.h>
#include <crypto/hash.h>
#include <crypto/sha1.h>
#include <crypto/sha3.h>
#include <crypto/sm3.h>
#include <crypto/skcipher.h>
#include <nvidia/conftest.h>
#define SE_MAX_INSTANCES 3
#define SE_OWNERSHIP 0x14
#define SE_OWNERSHIP_UID(x) FIELD_GET(GENMASK(7, 0), x)
#define TEGRA_GPSE_ID 3
@@ -63,8 +64,11 @@
#define SE_SHA_ENC_ALG_HMAC SE_SHA_CFG_ENC_ALG(7)
#define SE_SHA_ENC_ALG_KDF SE_SHA_CFG_ENC_ALG(8)
#define SE_SHA_ENC_ALG_KEY_INVLD SE_SHA_CFG_ENC_ALG(10)
#define SE_SHA_ENC_ALG_KEY_MOV SE_SHA_CFG_ENC_ALG(11)
#define SE_SHA_ENC_ALG_KEY_INQUIRE SE_SHA_CFG_ENC_ALG(12)
#define SE_SHA_ENC_ALG_INS SE_SHA_CFG_ENC_ALG(13)
#define SE_SHA_ENC_ALG_CLONE SE_SHA_CFG_ENC_ALG(14)
#define SE_SHA_ENC_ALG_LOCK SE_SHA_CFG_ENC_ALG(15)
#define SE_SHA_OP_LASTBUF FIELD_PREP(BIT(16), 1)
#define SE_SHA_OP_WRSTALL FIELD_PREP(BIT(15), 1)
@@ -304,6 +308,12 @@
SE_AES_CORE_SEL_DECRYPT | \
SE_AES_IV_SEL_REG)
#define SE_CRYPTO_CFG_OFB (SE_AES_INPUT_SEL_AESOUT | \
SE_AES_VCTRAM_SEL_MEMORY | \
SE_AES_XOR_POS_BOTTOM | \
SE_AES_CORE_SEL_ENCRYPT | \
SE_AES_IV_SEL_REG)
#define SE_CRYPTO_CFG_CTR (SE_AES_INPUT_SEL_LINEAR_CTR | \
SE_AES_VCTRAM_SEL_MEMORY | \
SE_AES_XOR_POS_BOTTOM | \
@@ -342,33 +352,20 @@
#define SE_CRYPTO_CTR_REG_COUNT 4
#define SE_MAX_KEYSLOT 15
#define SE_MAX_MEM_ALLOC SZ_4M
#define SE_SHA_BUFLEN 0x2000
#define SE_AES_BUFLEN 0x8000
#define SE_SHA_BUFLEN SZ_4M
#define SHA_FIRST BIT(0)
#define SHA_UPDATE BIT(1)
#define SHA_FINAL BIT(2)
#ifdef NV_CONFTEST_REMOVE_STRUCT_CRYPTO_ENGINE_CTX
#define CRYPTO_REGISTER(alg, x) \
crypto_engine_register_##alg(x)
#else
#define CRYPTO_REGISTER(alg, x) \
crypto_register_##alg(x)
#endif
#ifdef NV_CONFTEST_REMOVE_STRUCT_CRYPTO_ENGINE_CTX
#define CRYPTO_UNREGISTER(alg, x) \
crypto_engine_unregister_##alg(x)
#else
#define CRYPTO_UNREGISTER(alg, x) \
crypto_unregister_##alg(x)
#endif
/* Security Engine operation modes */
enum se_aes_alg {
SE_ALG_CBC, /* Cipher Block Chaining (CBC) mode */
SE_ALG_ECB, /* Electronic Codebook (ECB) mode */
SE_ALG_CTR, /* Counter (CTR) mode */
SE_ALG_OFB, /* Output feedback (CFB) mode */
SE_ALG_XTS, /* XTS mode */
SE_ALG_GMAC, /* GMAC mode */
SE_ALG_GCM, /* GCM mode */
@@ -401,15 +398,9 @@ struct tegra_se_alg {
const char *alg_base;
union {
#ifndef NV_CONFTEST_REMOVE_STRUCT_CRYPTO_ENGINE_CTX
struct skcipher_alg skcipher;
struct aead_alg aead;
struct ahash_alg ahash;
#else
struct skcipher_engine_alg skcipher;
struct aead_engine_alg aead;
struct ahash_engine_alg ahash;
#endif
struct skcipher_alg skcipher;
struct aead_alg aead;
struct ahash_alg ahash;
} alg;
};
@@ -431,7 +422,7 @@ struct tegra_se_regs {
struct tegra_se_hw {
const struct tegra_se_regs *regs;
int (*init_alg)(struct tegra_se *se);
void (*deinit_alg)(struct tegra_se *se);
void (*deinit_alg)(void);
bool support_sm_alg;
u32 host1x_class;
u32 kac_ver;
@@ -440,17 +431,18 @@ struct tegra_se_hw {
struct tegra_se {
int (*manifest)(u32 user, u32 alg, u32 keylen);
const struct tegra_se_hw *hw;
struct host1x_client client;
struct host1x_channel *channel;
struct tegra_se_cmdbuf *cmdbuf;
struct crypto_engine *engine;
struct host1x_channel *channel;
struct host1x_client client;
struct host1x_syncpt *syncpt;
struct clk_bulk_data *clks;
struct tegra_se_cmdbuf *cmdbuf;
struct device *dev;
struct clk *clk;
unsigned int opcode_addr;
unsigned int stream_id;
unsigned int syncpt_id;
void __iomem *base;
int num_clks;
u32 owner;
};
@@ -460,8 +452,8 @@ struct tegra_se_cmdbuf {
struct device *dev;
struct kref ref;
struct host1x_bo bo;
ssize_t size;
u32 words;
ssize_t size;
};
struct tegra_se_datbuf {
@@ -476,6 +468,8 @@ static inline int se_algname_to_algid(const char *name)
return SE_ALG_CBC;
else if (!strcmp(name, "ecb(aes)"))
return SE_ALG_ECB;
else if (!strcmp(name, "ofb(aes)"))
return SE_ALG_OFB;
else if (!strcmp(name, "ctr(aes)"))
return SE_ALG_CTR;
else if (!strcmp(name, "xts(aes)"))
@@ -518,61 +512,87 @@ static inline int se_algname_to_algid(const char *name)
}
/* Functions */
int tegra_init_aead(struct tegra_se *se);
int tegra_init_aes(struct tegra_se *se);
int tegra_init_hash(struct tegra_se *se);
void tegra_deinit_aes(struct tegra_se *se);
void tegra_deinit_hash(struct tegra_se *se);
int tegra_key_submit(struct tegra_se *se, const u8 *key,
u32 keylen, u32 alg, u32 *keyid);
void tegra_key_invalidate(struct tegra_se *se, u32 keyid, u32 alg);
void tegra_deinit_aead(void);
void tegra_deinit_aes(void);
void tegra_deinit_hash(void);
int tegra_key_submit(struct tegra_se *se, const u8 *key, u32 keylen, u32 alg, u32 *keyid);
unsigned int tegra_key_get_idx(struct tegra_se *se, u32 keyid);
void tegra_key_invalidate(struct tegra_se *se, u32 keyid);
int tegra_se_host1x_register(struct tegra_se *se);
int tegra_se_host1x_submit(struct tegra_se *se, u32 size);
/* HOST1x OPCODES */
static inline void se_writel(struct tegra_se *se, unsigned int val,
unsigned int offset)
{
writel_relaxed(val, se->base + offset);
}
static inline u32 se_readl(struct tegra_se *se, unsigned int offset)
{
return readl_relaxed(se->base + offset);
}
/****
*
* HOST1x OPCODES
*
****/
static inline u32 host1x_opcode_setpayload(unsigned int payload)
{
return (9 << 28) | payload;
}
static inline u32 host1x_opcode_incr_w(unsigned int offset)
#define host1x_opcode_incr_w(x) __host1x_opcode_incr_w((x) / 4)
static inline u32 __host1x_opcode_incr_w(unsigned int offset)
{
/* 22-bit offset supported */
return (10 << 28) | offset;
}
static inline u32 host1x_opcode_nonincr_w(unsigned int offset)
#define host1x_opcode_nonincr_w(x) __host1x_opcode_nonincr_w((x) / 4)
static inline u32 __host1x_opcode_nonincr_w(unsigned int offset)
{
/* 22-bit offset supported */
return (11 << 28) | offset;
}
static inline u32 host1x_opcode_incr(unsigned int offset, unsigned int count)
#define host1x_opcode_incr(x, y) __host1x_opcode_incr((x) / 4, y)
static inline u32 __host1x_opcode_incr(unsigned int offset, unsigned int count)
{
return (1 << 28) | (offset << 16) | count;
return (1 << 28) | (offset << 16) | count;
}
static inline u32 host1x_opcode_nonincr(unsigned int offset, unsigned int count)
#define host1x_opcode_nonincr(x, y) __host1x_opcode_nonincr((x) / 4, y)
static inline u32 __host1x_opcode_nonincr(unsigned int offset, unsigned int count)
{
return (2 << 28) | (offset << 16) | count;
return (2 << 28) | (offset << 16) | count;
}
static inline u32 host1x_uclass_incr_syncpt_cond_f(u32 v)
{
return (v & 0xff) << 10;
return (v & 0xff) << 10;
}
static inline u32 host1x_uclass_incr_syncpt_indx_f(u32 v)
{
return (v & 0x3ff) << 0;
return (v & 0x3ff) << 0;
}
static inline u32 host1x_uclass_wait_syncpt_r(void)
{
return 0x8;
return 0x8;
}
static inline u32 host1x_uclass_incr_syncpt_r(void)
{
return 0x0;
return 0x0;
}
#if !defined(NV_TEGRA_DEV_IOMMU_GET_STREAM_ID_PRESENT)
@@ -591,9 +611,4 @@ static inline bool tegra_dev_iommu_get_stream_id(struct device *dev, u32 *stream
}
#endif
#define se_host1x_opcode_incr_w(x) host1x_opcode_incr_w((x) / 4)
#define se_host1x_opcode_nonincr_w(x) host1x_opcode_nonincr_w((x) / 4)
#define se_host1x_opcode_incr(x, y) host1x_opcode_incr((x) / 4, y)
#define se_host1x_opcode_nonincr(x, y) host1x_opcode_nonincr((x) / 4, y)
#endif /*_TEGRA_SE_H*/

View File

@@ -1,14 +1,16 @@
# SPDX-License-Identifier: GPL-2.0
# Copyright (c) 2022-2024, NVIDIA CORPORATION & AFFILIATES. All rights reserved.
# Copyright (c) 2022-2023, NVIDIA CORPORATION & AFFILIATES. All rights reserved.
#
# Makefile for Extended IVC Driver and BPMP driver
#
obj-m += ivc_ext.o
ifneq ($(CONFIG_TEGRA_IVC_LEGACY_DISABLE),y)
tegra_bpmp-y += ../../clk/tegra/clk-bpmp.o
tegra_bpmp-y += ../../reset/tegra/reset-bpmp.o
tegra_bpmp-y += ../../soc/tegra/powergate-bpmp.o
tegra_bpmp-$(CONFIG_DEBUG_FS) += bpmp-debugfs.o
tegra_bpmp-y += bpmp-tegra186-hv.o
obj-m += tegra_bpmp.o
obj-m += tegra_bpmp.o
endif

View File

@@ -1,10 +1,8 @@
// SPDX-License-Identifier: GPL-2.0
/*
* Copyright (c) 2022-2024, NVIDIA CORPORATION & AFFILIATES. All rights reserved.
* Copyright (c) 2022-2023, NVIDIA CORPORATION & AFFILIATES. All rights reserved.
*/
#include <nvidia/conftest.h>
#include <linux/module.h>
#include <linux/of.h>
#include <linux/of_address.h>
@@ -84,11 +82,7 @@ static void tegra_bpmp_handle_mrq(struct tegra_bpmp *bpmp,
static void tegra_bpmp_channel_signal(struct tegra_bpmp_channel *channel)
{
#if defined(NV_TEGRA_IVC_STRUCT_HAS_IOSYS_MAP)
unsigned long flags = tegra_bpmp_mb_read_field(&channel->ob, flags);
#else
unsigned long flags = channel->ob->flags;
#endif
if ((flags & MSG_RING) == 0)
return;
@@ -122,15 +116,8 @@ void tegra_bpmp_handle_rx(struct tegra_bpmp *bpmp)
/* If supported incoming channel */
if (bpmp->soc->channels.cpu_rx.count == MAX_POSSIBLE_RX_CHANNEL) {
#if defined(NV_TEGRA_IVC_STRUCT_HAS_IOSYS_MAP)
if (tegra_bpmp_is_request_ready(channel)) {
unsigned int mrq = tegra_bpmp_mb_read_field(&channel->ib, code);
tegra_bpmp_handle_mrq(bpmp, mrq, channel);
}
#else
if (tegra_bpmp_is_request_ready(channel))
tegra_bpmp_handle_mrq(bpmp, channel->ib->code, channel);
#endif
}
spin_lock(&bpmp->lock);
@@ -211,20 +198,12 @@ static bool tegra186_bpmp_hv_is_message_ready(struct tegra_bpmp_channel *channel
void *frame;
frame = tegra_hv_ivc_read_get_next_frame(hv_ivc);
#if defined(NV_TEGRA_IVC_STRUCT_HAS_IOSYS_MAP)
if (IS_ERR(frame)) {
iosys_map_clear(&channel->ib);
return false;
}
iosys_map_set_vaddr(&channel->ib, frame);
#else
if (IS_ERR(frame)) {
channel->ib = NULL;
return false;
}
channel->ib = frame;
#endif
return true;
}
@@ -242,20 +221,12 @@ static bool tegra186_hv_bpmp_is_channel_free(struct tegra_bpmp_channel *channel)
void *frame;
frame = tegra_hv_ivc_write_get_next_frame(hv_ivc);
#if defined(NV_TEGRA_IVC_STRUCT_HAS_IOSYS_MAP)
if (IS_ERR(frame)) {
iosys_map_clear(&channel->ob);
return false;
}
iosys_map_set_vaddr(&channel->ob, frame);
#else
if (IS_ERR(frame)) {
channel->ob = NULL;
return false;
}
channel->ob = frame;
#endif
return true;
}
@@ -461,23 +432,13 @@ static void tegra_bpmp_mrq_handle_ping(unsigned int mrq,
struct tegra_bpmp_channel *channel,
void *data)
{
struct mrq_ping_response response;
#if defined(NV_TEGRA_IVC_STRUCT_HAS_IOSYS_MAP)
struct mrq_ping_request request;
tegra_bpmp_mb_read(&request, &channel->ib, sizeof(request));
memset(&response, 0, sizeof(response));
response.reply = request.challenge << 1;
#else
struct mrq_ping_request *request;
struct mrq_ping_response response;
request = (struct mrq_ping_request *)channel->ib->data;
memset(&response, 0, sizeof(response));
response.reply = request->challenge << 1;
#endif
tegra_bpmp_mrq_return(channel, 0, &response, sizeof(response));
}

View File

@@ -1,11 +1,11 @@
# SPDX-License-Identifier: GPL-2.0-only
# Copyright (c) 2022-2024, NVIDIA CORPORATION. All rights reserved.
# Copyright (c) 2022-2023, NVIDIA CORPORATION. All rights reserved.
ccflags-$(CONFIG_DRM_TEGRA_DEBUG) += -DDEBUG
ccflags-y += -I$(srctree.nvidia-oot)/drivers/gpu/drm/tegra/include
ccflags-y += -I$(srctree.hwpm)/include
tegra-drm-y := \
tegra-drm-next-y := \
drm.o \
uapi.o \
submit.o \
@@ -37,6 +37,6 @@ tegra-drm-y := \
ofa.o \
virt.o
tegra-drm-y += trace.o
tegra-drm-next-y += trace.o
obj-m := tegra-drm.o
obj-m := tegra-drm-next.o

View File

@@ -4,8 +4,6 @@
* Copyright (C) 2012 NVIDIA CORPORATION. All rights reserved.
*/
#include <nvidia/conftest.h>
#include <linux/clk.h>
#include <linux/debugfs.h>
#include <linux/delay.h>
@@ -14,7 +12,6 @@
#include <linux/interconnect.h>
#include <linux/module.h>
#include <linux/of_device.h>
#include <linux/platform_device.h>
#include <linux/pm_domain.h>
#include <linux/pm_opp.h>
#include <linux/pm_runtime.h>
@@ -1750,19 +1747,7 @@ static void tegra_dc_early_unregister(struct drm_crtc *crtc)
struct drm_minor *minor = crtc->dev->primary;
struct tegra_dc *dc = to_tegra_dc(crtc);
#if defined(NV_DRM_DEBUGFS_REMOVE_FILES_HAS_ROOT_ARG) /* Linux v6.7 */
struct dentry *root;
#ifdef CONFIG_DEBUG_FS
root = crtc->debugfs_entry;
#else
root = NULL;
#endif
drm_debugfs_remove_files(dc->debugfs_files, count, root, minor);
#else
drm_debugfs_remove_files(dc->debugfs_files, count, minor);
#endif
kfree(dc->debugfs_files);
dc->debugfs_files = NULL;
}

View File

@@ -11,7 +11,6 @@
#include <linux/io.h>
#include <linux/module.h>
#include <linux/of_device.h>
#include <linux/platform_device.h>
#include <linux/pinctrl/pinconf-generic.h>
#include <linux/pinctrl/pinctrl.h>
#include <linux/pinctrl/pinmux.h>

View File

@@ -26,7 +26,6 @@
#include <drm/drm_ioctl.h>
#include <drm/drm_prime.h>
#include <drm/drm_vblank.h>
#include <drm/tegra_drm-next.h>
#if IS_ENABLED(CONFIG_ARM_DMA_USE_IOMMU)
#include <asm/dma-iommu.h>
@@ -892,10 +891,8 @@ static const struct drm_driver tegra_drm_driver = {
.debugfs_init = tegra_debugfs_init,
#endif
#if NV_IS_EXPORT_SYMBOL_PRESENT_drm_gem_prime_handle_to_fd
#if !defined(NV_UNEXPORT_FD_HANDLE_CONVERSION)
.prime_handle_to_fd = drm_gem_prime_handle_to_fd,
#endif
#if NV_IS_EXPORT_SYMBOL_PRESENT_drm_gem_prime_fd_to_handle
.prime_fd_to_handle = drm_gem_prime_fd_to_handle,
#endif
.gem_prime_import = tegra_gem_prime_import,

View File

@@ -3,8 +3,6 @@
* Copyright (C) 2013 NVIDIA Corporation
*/
#include <nvidia/conftest.h>
#include <linux/clk.h>
#include <linux/debugfs.h>
#include <linux/delay.h>
@@ -257,14 +255,8 @@ static void tegra_dsi_early_unregister(struct drm_connector *connector)
unsigned int count = ARRAY_SIZE(debugfs_files);
struct tegra_dsi *dsi = to_dsi(output);
#if defined(NV_DRM_DEBUGFS_REMOVE_FILES_HAS_ROOT_ARG) /* Linux v6.7 */
drm_debugfs_remove_files(dsi->debugfs_files, count,
connector->debugfs_entry,
connector->dev->primary);
#else
drm_debugfs_remove_files(dsi->debugfs_files, count,
connector->dev->primary);
#endif
kfree(dsi->debugfs_files);
dsi->debugfs_files = NULL;
}

View File

@@ -11,8 +11,10 @@
#include <linux/console.h>
#include <linux/version.h>
#if LINUX_VERSION_CODE >= KERNEL_VERSION(6, 5, 0)
#include <linux/fb.h>
#include <linux/vmalloc.h>
#endif
#include <drm/drm_fourcc.h>
#include <drm/drm_framebuffer.h>
@@ -212,21 +214,24 @@ static int tegra_fb_mmap(struct fb_info *info, struct vm_area_struct *vma)
return __tegra_gem_mmap(&bo->gem, vma);
}
#if LINUX_VERSION_CODE >= KERNEL_VERSION(6, 5, 0)
#if defined(NV_FB_DEFERRED_IO_OPS_RENAME)
FB_GEN_DEFAULT_DEFERRED_IOMEM_OPS(tegra_fb,
drm_fb_helper_damage_range,
drm_fb_helper_damage_area)
#else
FB_GEN_DEFAULT_DEFERRED_IO_OPS(tegra_fb,
drm_fb_helper_damage_range,
drm_fb_helper_damage_area)
#endif
#endif
static const struct fb_ops tegra_fb_ops = {
.owner = THIS_MODULE,
#if defined(__FB_DEFAULT_DMAMEM_OPS_RDWR) /* Linux v6.6 */
__FB_DEFAULT_DMAMEM_OPS_RDWR,
#elif defined(__FB_DEFAULT_SYS_OPS_RDWR) /* Linux v6.5 */
__FB_DEFAULT_SYS_OPS_RDWR,
#else
.fb_read = drm_fb_helper_sys_read,
.fb_write = drm_fb_helper_sys_write,
#endif
DRM_FB_HELPER_DEFAULT_OPS,
#if defined(__FB_DEFAULT_DMAMEM_OPS_DRAW) /* Linux v6.6 */
__FB_DEFAULT_DMAMEM_OPS_DRAW,
#elif defined(__FB_DEFAULT_SYS_OPS_DRAW) /* Linux v6.5 */
__FB_DEFAULT_SYS_OPS_DRAW,
#if LINUX_VERSION_CODE >= KERNEL_VERSION(6, 5, 0)
__FB_DEFAULT_DEFERRED_OPS_RDWR(tegra_fb),
__FB_DEFAULT_DEFERRED_OPS_DRAW(tegra_fb),
#else
.fb_fillrect = drm_fb_helper_sys_fillrect,
.fb_copyarea = drm_fb_helper_sys_copyarea,

View File

@@ -15,7 +15,7 @@
#include <linux/dma-buf.h>
#include <linux/iommu.h>
#include <linux/module.h>
#include <linux/vmalloc.h>
#include <linux/version.h>
#include <drm/drm_drv.h>
#include <drm/drm_prime.h>
@@ -584,7 +584,8 @@ int __tegra_gem_mmap(struct drm_gem_object *gem, struct vm_area_struct *vma)
* and set the vm_pgoff (used as a fake buffer offset by DRM)
* to 0 as we want to map the whole buffer.
*/
#if defined(NV_VM_AREA_STRUCT_HAS_CONST_VM_FLAGS) /* Linux v6.3 */
#if (LINUX_VERSION_CODE >= KERNEL_VERSION(6, 3, 0)) \
|| (defined(CONFIG_TEGRA_SYSTEM_TYPE_ACK) && (LINUX_VERSION_CODE >= KERNEL_VERSION(6, 1, 0)))
vm_flags_clear(vma, VM_PFNMAP);
#else
vma->vm_flags &= ~VM_PFNMAP;
@@ -602,7 +603,8 @@ int __tegra_gem_mmap(struct drm_gem_object *gem, struct vm_area_struct *vma)
} else {
pgprot_t prot = vm_get_page_prot(vma->vm_flags);
#if defined(NV_VM_AREA_STRUCT_HAS_CONST_VM_FLAGS) /* Linux v6.3 */
#if (LINUX_VERSION_CODE >= KERNEL_VERSION(6, 3, 0)) \
|| (defined(CONFIG_TEGRA_SYSTEM_TYPE_ACK) && (LINUX_VERSION_CODE >= KERNEL_VERSION(6, 1, 0)))
vm_flags_set(vma, VM_MIXEDMAP);
vm_flags_clear(vma, VM_PFNMAP);
#else
@@ -725,6 +727,7 @@ static int tegra_gem_prime_vmap(struct dma_buf *buf, struct iosys_map *map)
{
struct drm_gem_object *gem = buf->priv;
struct tegra_bo *bo = to_tegra_bo(gem);
#if LINUX_VERSION_CODE >= KERNEL_VERSION(6, 0, 0)
void *vaddr;
vaddr = tegra_bo_mmap(&bo->base);
@@ -732,16 +735,21 @@ static int tegra_gem_prime_vmap(struct dma_buf *buf, struct iosys_map *map)
return PTR_ERR(vaddr);
iosys_map_set_vaddr(map, vaddr);
#else
iosys_map_set_vaddr(map, bo->vaddr);
#endif
return 0;
}
static void tegra_gem_prime_vunmap(struct dma_buf *buf, struct iosys_map *map)
{
#if LINUX_VERSION_CODE >= KERNEL_VERSION(6, 0, 0)
struct drm_gem_object *gem = buf->priv;
struct tegra_bo *bo = to_tegra_bo(gem);
tegra_bo_munmap(&bo->base, map->vaddr);
#endif
}
#else
static int tegra_gem_prime_vmap(struct dma_buf *buf, struct dma_buf_map *map)

View File

@@ -8,9 +8,9 @@
#include <linux/iommu.h>
#include <linux/module.h>
#include <linux/of_device.h>
#include <linux/platform_device.h>
#include <linux/pm_runtime.h>
#include <linux/reset.h>
#include <linux/version.h>
#include <soc/tegra/common.h>
@@ -272,7 +272,7 @@ static int gr2d_probe(struct platform_device *pdev)
gr2d->client.version = gr2d->soc->version;
gr2d->client.ops = &gr2d_ops;
#if defined(NV_DEVM_TEGRA_CORE_DEV_INIT_OPP_TABLE_COMMON_PRESENT) /* Linux v5.17 */
#if LINUX_VERSION_CODE >= KERNEL_VERSION(5, 17, 0)
err = devm_tegra_core_dev_init_opp_table_common(dev);
if (err)
return err;

View File

@@ -530,7 +530,7 @@ static int gr3d_probe(struct platform_device *pdev)
gr3d->client.version = gr3d->soc->version;
gr3d->client.ops = &gr3d_ops;
#if defined(NV_DEVM_TEGRA_CORE_DEV_INIT_OPP_TABLE_COMMON_PRESENT) /* Linux v5.17 */
#if LINUX_VERSION_CODE >= KERNEL_VERSION(5, 17, 0)
err = devm_tegra_core_dev_init_opp_table_common(&pdev->dev);
if (err)
return err;

View File

@@ -4,8 +4,6 @@
* Copyright (C) 2012 NVIDIA CORPORATION. All rights reserved.
*/
#include <nvidia/conftest.h>
#include <linux/clk.h>
#include <linux/debugfs.h>
#include <linux/delay.h>
@@ -25,9 +23,6 @@
#include <drm/drm_atomic_helper.h>
#include <drm/drm_crtc.h>
#include <drm/drm_debugfs.h>
#if defined(NV_DRM_DRM_ELD_H_PRESENT)
#include <drm/drm_eld.h>
#endif
#include <drm/drm_file.h>
#include <drm/drm_fourcc.h>
#include <drm/drm_probe_helper.h>
@@ -1127,12 +1122,7 @@ static void tegra_hdmi_early_unregister(struct drm_connector *connector)
unsigned int count = ARRAY_SIZE(debugfs_files);
struct tegra_hdmi *hdmi = to_hdmi(output);
#if defined(NV_DRM_DEBUGFS_REMOVE_FILES_HAS_ROOT_ARG) /* Linux v6.7 */
drm_debugfs_remove_files(hdmi->debugfs_files, count,
connector->debugfs_entry, minor);
#else
drm_debugfs_remove_files(hdmi->debugfs_files, count, minor);
#endif
kfree(hdmi->debugfs_files);
hdmi->debugfs_files = NULL;
}
@@ -1874,14 +1864,16 @@ static int tegra_hdmi_probe(struct platform_device *pdev)
platform_set_drvdata(pdev, hdmi);
#if LINUX_VERSION_CODE >= KERNEL_VERSION(5, 17, 0)
err = devm_pm_runtime_enable(&pdev->dev);
if (err)
return err;
#if defined(NV_DEVM_TEGRA_CORE_DEV_INIT_OPP_TABLE_COMMON_PRESENT) /* Linux v5.17 */
err = devm_tegra_core_dev_init_opp_table_common(&pdev->dev);
if (err)
return err;
#else
pm_runtime_enable(&pdev->dev);
#endif
INIT_LIST_HEAD(&hdmi->client.list);
@@ -1902,6 +1894,10 @@ static int tegra_hdmi_remove(struct platform_device *pdev)
{
struct tegra_hdmi *hdmi = platform_get_drvdata(pdev);
#if !(LINUX_VERSION_CODE >= KERNEL_VERSION(5, 17, 0))
pm_runtime_disable(&pdev->dev);
#endif
host1x_client_unregister(&hdmi->client);
tegra_output_remove(&hdmi->output);

View File

@@ -8,9 +8,9 @@
#include <linux/dma-mapping.h>
#include <linux/host1x-next.h>
#include <linux/module.h>
#include <linux/of.h>
#include <linux/of_device.h>
#include <linux/of_graph.h>
#include <linux/of_platform.h>
#include <linux/platform_device.h>
#include <linux/pm_runtime.h>
#include <linux/reset.h>

View File

@@ -1,6 +1,6 @@
// SPDX-License-Identifier: GPL-2.0-only
/*
* SPDX-FileCopyrightText: Copyright (c) 2015-2024, NVIDIA CORPORATION & AFFILIATES. All Rights Reserved.
* SPDX-FileCopyrightText: Copyright (c) 2015-2023, NVIDIA CORPORATION & AFFILIATES. All Rights Reserved.
*/
#include <linux/bitops.h>
@@ -43,37 +43,11 @@
#define NVDEC_TFBIF_ACTMON_ACTIVE_WEIGHT 0x2c54
#define NVDEC_AXI_RW_BANDWIDTH 512
#define NVDEC_CG_SLCG_CTRL 0x297c
#define NVDEC_CG_SLCG_CTRL_IDLE_SLCG_DIS BIT(9)
#define NVDEC_RISCV_CG 0x4398
#define NVDEC_RISCV_CG_SLCG BIT(0)
#define NVDEC_RISCV_CG_CORE_SLCG BIT(1)
#define NVDEC_PG 0x2314
#define NVDEC_PG_DEEP_ELPG_EN BIT(18)
#define NVDEC_PG1 0x2318
#define NVDEC_CG2 0x2328
#define NVDEC_CG3 0x232c
#define NVDEC_CG4 0x2950
#define NVDEC_CG5 0x2954
#define NVDEC_CG6 0x2958
#define NVDEC_CG7 0x295c
#define NVDEC_CG8 0x2960
#define NVDEC_CG9 0x2964
#define NVDEC_CG10 0x2968
#define NVDEC_CG11 0x296c
#define NVDEC_CG12 0x2970
#define NVDEC_TFBIF_ACTMON_ACTIVE_MASK_STARVED BIT(0)
#define NVDEC_TFBIF_ACTMON_ACTIVE_MASK_STALLED BIT(1)
#define NVDEC_TFBIF_ACTMON_ACTIVE_MASK_DELAYED BIT(2)
#define NVDEC_TFBIF_ACTMON_ACTIVE_BORPS_ACTIVE BIT(7)
struct nvdec_cg_reg {
u32 offset;
u32 value;
};
struct nvdec_config {
const char *firmware;
unsigned int version;
@@ -81,7 +55,6 @@ struct nvdec_config {
bool supports_timestamping;
bool has_riscv;
bool has_extra_clocks;
const struct nvdec_cg_reg *cg_regs;
};
struct nvdec {
@@ -118,11 +91,6 @@ static inline void nvdec_writel(struct nvdec *nvdec, u32 value,
writel(value, nvdec->regs + offset);
}
static inline u32 nvdec_readl(struct nvdec *nvdec, unsigned int offset)
{
return readl(nvdec->regs + offset);
}
static int nvdec_set_rate(struct nvdec *nvdec, unsigned long rate)
{
unsigned long dev_rate;
@@ -140,7 +108,7 @@ static int nvdec_set_rate(struct nvdec *nvdec, unsigned long rate)
if (nvdec->icc_write) {
emc_kbps = dev_rate * NVDEC_AXI_RW_BANDWIDTH / 1024;
err = icc_set_bw(nvdec->icc_write, 0, kbps_to_icc(emc_kbps));
err = icc_set_bw(nvdec->icc_write, kbps_to_icc(emc_kbps), 0);
if (err)
dev_warn(nvdec->dev, "failed to set icc bw: %d\n", err);
}
@@ -589,29 +557,6 @@ static void nvdec_count_weight_init(struct nvdec *nvdec, unsigned long rate)
}
}
static void nvdec_enable_slcg(struct nvdec *nvdec)
{
const struct nvdec_cg_reg *cg;
u32 val;
if (!nvdec->config->cg_regs)
return;
/* Enable power gating */
nvdec_writel(nvdec, 0xff00a725, NVDEC_PG1);
nvdec_writel(nvdec, NVDEC_PG_DEEP_ELPG_EN | (9 << 20) | (2 << 27), NVDEC_PG);
/* Enable clock gating */
for (cg = nvdec->config->cg_regs; cg->offset; cg++)
nvdec_writel(nvdec, cg->value, cg->offset);
val = nvdec_readl(nvdec, NVDEC_CG_SLCG_CTRL);
val &= ~NVDEC_CG_SLCG_CTRL_IDLE_SLCG_DIS;
nvdec_writel(nvdec, val, NVDEC_CG_SLCG_CTRL);
nvdec_writel(nvdec, NVDEC_RISCV_CG_SLCG | NVDEC_RISCV_CG_CORE_SLCG, NVDEC_RISCV_CG);
}
static __maybe_unused int nvdec_runtime_resume(struct device *dev)
{
struct nvdec *nvdec = dev_get_drvdata(dev);
@@ -637,8 +582,6 @@ static __maybe_unused int nvdec_runtime_resume(struct device *dev)
goto disable;
}
nvdec_enable_slcg(nvdec);
/* Forcely set frequency as Fmax when device is resumed back */
nvdec->devfreq->resume_freq = nvdec->devfreq->scaling_max_freq;
err = devfreq_resume_device(nvdec->devfreq);
@@ -755,28 +698,12 @@ static const struct nvdec_config nvdec_t194_config = {
.supports_timestamping = true,
};
static const struct nvdec_cg_reg nvdec_t234_cg_regs[] = {
{ NVDEC_CG2, 0x00000000 },
{ NVDEC_CG3, 0xfc800000 },
{ NVDEC_CG4, 0xffffffc0 },
{ NVDEC_CG5, 0x00000040 },
{ NVDEC_CG6, 0x04004000 },
{ NVDEC_CG7, 0xfc000000 },
{ NVDEC_CG8, 0x00000000 },
{ NVDEC_CG9, 0x80000000 },
{ NVDEC_CG10, 0xfffffb00 },
{ NVDEC_CG11, 0xfff80000 },
{ NVDEC_CG12, 0xffffff80 },
{ },
};
static const struct nvdec_config nvdec_t234_config = {
.version = 0x23,
.supports_sid = true,
.supports_timestamping = true,
.has_riscv = true,
.has_extra_clocks = true,
.cg_regs = nvdec_t234_cg_regs,
};
static const struct of_device_id tegra_nvdec_of_match[] = {
@@ -877,9 +804,10 @@ static int nvdec_probe(struct platform_device *pdev)
}
nvdec->icc_write = devm_of_icc_get(dev, "write");
if (IS_ERR(nvdec->icc_write))
return dev_err_probe(&pdev->dev, PTR_ERR(nvdec->icc_write),
"failed to get icc write handle\n");
if (IS_ERR(nvdec->icc_write)) {
dev_err(&pdev->dev, "failed to get icc write handle\n");
return PTR_ERR(nvdec->icc_write);
}
platform_set_drvdata(pdev, nvdec);

View File

@@ -1,6 +1,6 @@
// SPDX-License-Identifier: GPL-2.0-only
/*
* SPDX-FileCopyrightText: Copyright (c) 2021-2024, NVIDIA CORPORATION & AFFILIATES. All Rights Reserved.
* SPDX-FileCopyrightText: Copyright (c) 2021-2023, NVIDIA CORPORATION & AFFILIATES. All Rights Reserved.
*/
#include <linux/bitops.h>
@@ -91,7 +91,7 @@ static int nvenc_set_rate(struct nvenc *nvenc, unsigned long rate)
if (nvenc->icc_write) {
emc_kbps = dev_rate * NVENC_AXI_RW_BANDWIDTH / 1024;
err = icc_set_bw(nvenc->icc_write, 0, kbps_to_icc(emc_kbps));
err = icc_set_bw(nvenc->icc_write, kbps_to_icc(emc_kbps), 0);
if (err)
dev_warn(nvenc->dev, "failed to set icc bw: %d\n", err);
}
@@ -670,9 +670,10 @@ static int nvenc_probe(struct platform_device *pdev)
return err;
nvenc->icc_write = devm_of_icc_get(dev, "write");
if (IS_ERR(nvenc->icc_write))
return dev_err_probe(&pdev->dev, PTR_ERR(nvenc->icc_write),
"failed to get icc write handle\n");
if (IS_ERR(nvenc->icc_write)) {
dev_err(&pdev->dev, "failed to get icc write handle\n");
return PTR_ERR(nvenc->icc_write);
}
platform_set_drvdata(pdev, nvenc);

View File

@@ -1,6 +1,6 @@
// SPDX-License-Identifier: GPL-2.0-only
/*
* SPDX-FileCopyrightText: Copyright (c) 2021-2024, NVIDIA CORPORATION & AFFILIATES. All Rights Reserved.
* Copyright (c) 2021-2023, NVIDIA CORPORATION & AFFILIATES. All Rights Reserved.
*/
#include <linux/bitops.h>
@@ -88,7 +88,7 @@ static int nvjpg_set_rate(struct nvjpg *nvjpg, unsigned long rate)
if (nvjpg->icc_write) {
emc_kbps = dev_rate * NVJPG_AXI_RW_BANDWIDTH / 1024;
err = icc_set_bw(nvjpg->icc_write, 0, kbps_to_icc(emc_kbps));
err = icc_set_bw(nvjpg->icc_write, kbps_to_icc(emc_kbps), 0);
if (err)
dev_warn(nvjpg->dev, "failed to set icc bw: %d\n", err);
}
@@ -655,9 +655,10 @@ static int nvjpg_probe(struct platform_device *pdev)
return err;
nvjpg->icc_write = devm_of_icc_get(dev, "write");
if (IS_ERR(nvjpg->icc_write))
return dev_err_probe(&pdev->dev, PTR_ERR(nvjpg->icc_write),
"failed to get icc write handle\n");
if (IS_ERR(nvjpg->icc_write)) {
dev_err(&pdev->dev, "failed to get icc write handle\n");
return PTR_ERR(nvjpg->icc_write);
}
platform_set_drvdata(pdev, nvjpg);

View File

@@ -32,9 +32,6 @@
#endif
#include <drm/drm_atomic_helper.h>
#include <drm/drm_debugfs.h>
#if defined(NV_DRM_DRM_ELD_H_PRESENT)
#include <drm/drm_eld.h>
#endif
#include <drm/drm_file.h>
#include <drm/drm_panel.h>
#include <drm/drm_simple_kms_helper.h>
@@ -1721,15 +1718,8 @@ static void tegra_sor_early_unregister(struct drm_connector *connector)
unsigned int count = ARRAY_SIZE(debugfs_files);
struct tegra_sor *sor = to_sor(output);
#if defined(NV_DRM_DEBUGFS_REMOVE_FILES_HAS_ROOT_ARG) /* Linux v6.7 */
drm_debugfs_remove_files(sor->debugfs_files, count,
connector->debugfs_entry,
connector->dev->primary);
#else
drm_debugfs_remove_files(sor->debugfs_files, count,
connector->dev->primary);
#endif
kfree(sor->debugfs_files);
sor->debugfs_files = NULL;
}

View File

@@ -1,6 +1,6 @@
// SPDX-License-Identifier: GPL-2.0-only
/*
* SPDX-FileCopyrightText: Copyright (C) 2015-2024 NVIDIA CORPORATION. All rights reserved.
* SPDX-FileCopyrightText: Copyright (C) 2015-2023 NVIDIA CORPORATION. All rights reserved.
*/
#include <linux/bitops.h>
@@ -129,7 +129,7 @@ static int vic_set_rate(struct vic *vic, unsigned long rate)
if (vic->icc_write) {
emc_kbps = dev_rate * VIC_AXI_RW_BANDWIDTH / 1024;
err = icc_set_bw(vic->icc_write, 0, kbps_to_icc(emc_kbps));
err = icc_set_bw(vic->icc_write, kbps_to_icc(emc_kbps), 0);
if (err)
dev_warn(vic->dev, "failed to set icc bw: %d\n", err);
}
@@ -723,9 +723,10 @@ static int vic_probe(struct platform_device *pdev)
}
vic->icc_write = devm_of_icc_get(dev, "write");
if (IS_ERR(vic->icc_write))
return dev_err_probe(&pdev->dev, PTR_ERR(vic->icc_write),
"failed to get icc write handle\n");
if (IS_ERR(vic->icc_write)) {
dev_err(&pdev->dev, "failed to get icc write handle\n");
return PTR_ERR(vic->icc_write);
}
if (!dev->pm_domain) {
vic->rst = devm_reset_control_get(dev, "vic");

View File

@@ -1,5 +1,9 @@
// SPDX-License-Identifier: GPL-2.0-only
// SPDX-FileCopyrightText: Copyright (c) 2022-2024, NVIDIA CORPORATION & AFFILIATES. All rights reserved.
/*
* Host1x fence UAPI
*
* Copyright (c) 2022-2023, NVIDIA CORPORATION. All rights reserved.
*/
#include <nvidia/conftest.h>
@@ -10,8 +14,7 @@
#include <linux/host1x-next.h>
#include <linux/module.h>
#include <linux/of.h>
#include <linux/of_platform.h>
#include <linux/platform_device.h>
#include <linux/of_device.h>
#include <linux/poll.h>
#include <linux/slab.h>
#include <linux/sync_file.h>
@@ -201,28 +204,20 @@ struct host1x_pollfd {
static int host1x_pollfd_release(struct inode *inode, struct file *file)
{
struct host1x_pollfd *pollfd = file->private_data;
struct host1x_pollfd_fence *pfd_fence, *pfd_fence_temp;
struct host1x_pollfd_fence *pfd_fence;
mutex_lock(&pollfd->lock);
list_for_each_entry_safe(pfd_fence, pfd_fence_temp, &pollfd->fences, list) {
list_for_each_entry(pfd_fence, &pollfd->fences, list) {
if (pfd_fence->callback_set) {
if (dma_fence_remove_callback(pfd_fence->fence, &pfd_fence->callback))
host1x_fence_cancel(pfd_fence->fence);
pfd_fence->callback_set = false;
}
/*The lock/unlock just ensures that the callback execution has finished*/
spin_lock(pfd_fence->fence->lock);
spin_unlock(pfd_fence->fence->lock);
dma_fence_put(pfd_fence->fence);
kfree(pfd_fence);
}
mutex_unlock(&pollfd->lock);
kfree(pollfd);
return 0;
}
@@ -239,20 +234,8 @@ static unsigned int host1x_pollfd_poll(struct file *file, poll_table *wait)
list_for_each_entry_safe(pfd_fence, pfd_fence_temp, &pollfd->fences, list) {
if (dma_fence_is_signaled(pfd_fence->fence)) {
mask = POLLPRI | POLLIN;
if (pfd_fence->callback_set) {
if (dma_fence_remove_callback(pfd_fence->fence,
&pfd_fence->callback))
host1x_fence_cancel(pfd_fence->fence);
pfd_fence->callback_set = false;
}
/*The lock/unlock just ensures that the callback execution has finished*/
spin_lock(pfd_fence->fence->lock);
spin_unlock(pfd_fence->fence->lock);
dma_fence_put(pfd_fence->fence);
list_del(&pfd_fence->list);
kfree(pfd_fence);
}
}

View File

@@ -1,5 +1,7 @@
// SPDX-License-Identifier: GPL-2.0-only
// SPDX-FileCopyrightText: Copyright (c) 2022-2024 NVIDIA CORPORATION & AFFILIATES. All Rights Reserved.
/*
* Copyright (c) 2022-2023, NVIDIA Corporation. All rights reserved.
*/
#include <nvidia/conftest.h>
@@ -543,6 +545,7 @@ int flcn_intr_init(struct platform_device *pdev)
return -ENXIO;
}
spin_lock_init(&pdata->mirq_lock);
ret = devm_request_irq(&pdev->dev, pdata->irq, flcn_isr, 0,
dev_name(&pdev->dev), pdev);
if (ret) {

View File

@@ -1,7 +1,7 @@
# SPDX-License-Identifier: GPL-2.0-only
# Copyright (c) 2022-2024, NVIDIA CORPORATION. All rights reserved.
# Copyright (c) 2022-2023, NVIDIA CORPORATION. All rights reserved.
host1x-y = \
host1x-next-y = \
bus.o \
syncpt.o \
dev.o \
@@ -21,7 +21,7 @@ host1x-y = \
hw/host1x07.o \
hw/host1x08.o
host1x-$(CONFIG_IOMMU_API) += \
host1x-next-$(CONFIG_IOMMU_API) += \
context.o
obj-m := host1x.o
obj-m := host1x-next.o

View File

@@ -4,8 +4,6 @@
* Copyright (C) 2012-2013, NVIDIA Corporation
*/
#include <nvidia/conftest.h>
#include <linux/debugfs.h>
#include <linux/dma-mapping.h>
#include <linux/host1x-next.h>
@@ -13,6 +11,7 @@
#include <linux/seq_file.h>
#include <linux/slab.h>
#include <linux/of_device.h>
#include <linux/version.h>
#include "bus.h"
#include "dev.h"
@@ -335,16 +334,12 @@ static int host1x_del_client(struct host1x *host1x,
return -ENODEV;
}
#if defined(NV_BUS_TYPE_STRUCT_MATCH_HAS_CONST_DRV_ARG)
static int host1x_device_match(struct device *dev, const struct device_driver *drv)
#else
static int host1x_device_match(struct device *dev, struct device_driver *drv)
#endif
{
return strcmp(dev_name(dev), drv->name) == 0;
}
#if defined(NV_BUS_TYPE_STRUCT_UEVENT_HAS_CONST_DEV_ARG) /* Linux v6.3 */
#if LINUX_VERSION_CODE >= KERNEL_VERSION(6, 3, 0)
static int host1x_device_uevent(const struct device *dev,
#else
static int host1x_device_uevent(struct device *dev,

View File

@@ -35,14 +35,14 @@
/*
* Typically the commands written into the push buffer are a pair of words. We
* use slots to represent each of these pairs and to simplify things. Note the
* strange number of slots allocated here. 1024 slots will fit exactly within a
* two memory pages. We also need one additional word at the end of the push
* strange number of slots allocated here. 512 slots will fit exactly within a
* single memory page. We also need one additional word at the end of the push
* buffer for the RESTART opcode that will instruct the CDMA to jump back to
* the beginning of the push buffer. With 1024 slots, this means that we'll use
* 3 memory pages and waste 4092 bytes of the third page that will never be
* the beginning of the push buffer. With 512 slots, this means that we'll use
* 2 memory pages and waste 4092 bytes of the second page that will never be
* used.
*/
#define HOST1X_PUSHBUFFER_SLOTS 1023
#define HOST1X_PUSHBUFFER_SLOTS 511
/*
* Clean up push buffer resources
@@ -496,7 +496,7 @@ resume:
host1x_hw_cdma_resume(host1x, cdma, restart_addr);
}
static void cdma_update_work(struct work_struct *work)
void cdma_update_work(struct work_struct *work)
{
struct host1x_cdma *cdma = container_of(work, struct host1x_cdma, update_work);

View File

@@ -1,12 +1,12 @@
// SPDX-License-Identifier: GPL-2.0-only
/*
* Copyright (c) 2021-2024, NVIDIA Corporation.
* Copyright (c) 2021, NVIDIA Corporation.
*/
#include <linux/device.h>
#include <linux/kref.h>
#include <linux/of.h>
#include <linux/of_device.h>
#include <linux/of_platform.h>
#include <linux/pid.h>
#include <linux/slab.h>

View File

@@ -5,18 +5,17 @@
* Copyright (c) 2010-2023, NVIDIA CORPORATION & AFFILIATES. All Rights Reserved.
*/
#include <nvidia/conftest.h>
#include <linux/clk.h>
#include <linux/delay.h>
#include <linux/dma-mapping.h>
#include <linux/io.h>
#include <linux/list.h>
#include <linux/module.h>
#include <linux/of_device.h>
#include <linux/of.h>
#include <linux/of_platform.h>
#include <linux/pm_runtime.h>
#include <linux/slab.h>
#include <linux/version.h>
#include <soc/tegra/common.h>
@@ -951,7 +950,7 @@ static int host1x_probe(struct platform_device *pdev)
pm_runtime_enable(&pdev->dev);
#if defined(NV_DEVM_TEGRA_CORE_DEV_INIT_OPP_TABLE_COMMON_PRESENT) /* Linux v5.17 */
#if LINUX_VERSION_CODE >= KERNEL_VERSION(5, 17, 0)
err = devm_tegra_core_dev_init_opp_table_common(&pdev->dev);
if (err)
goto pm_disable;

View File

@@ -177,14 +177,7 @@ static void show_gather(struct output *o, dma_addr_t phys_addr,
for (i = 0; i < words; i++) {
dma_addr_t addr = phys_addr + i * 4;
u32 voffset = offset + i * 4;
u32 val;
/* If we reach the RESTART opcode, continue at the beginning of pushbuffer */
if (cdma && voffset >= cdma->push_buffer.size)
voffset -= cdma->push_buffer.size;
val = *(map_addr + voffset / 4);
u32 val = *(map_addr + offset / 4 + i);
if (!data_count) {
host1x_debug_output(o, " %pad: %08x: ", &addr, val);
@@ -210,7 +203,7 @@ static void show_channel_gathers(struct output *o, struct host1x_cdma *cdma)
job->num_slots, job->num_unpins);
show_gather(o, pb->dma + job->first_get, job->num_slots * 2, cdma,
pb->dma, pb->mapped);
pb->dma + job->first_get, pb->mapped + job->first_get);
for (i = 0; i < job->num_cmds; i++) {
struct host1x_job_gather *g;
@@ -234,7 +227,7 @@ static void show_channel_gathers(struct output *o, struct host1x_cdma *cdma)
host1x_debug_output(o, " GATHER at %pad+%#x, %d words\n",
&g->base, g->offset, g->words);
show_gather(o, g->base + g->offset, g->words, NULL,
show_gather(o, g->base + g->offset, g->words, cdma,
g->base, mapped);
if (!job->gather_copy_mapped)

View File

@@ -1,7 +1,5 @@
// SPDX-License-Identifier: GPL-2.0-only
// SPDX-FileCopyrightText: Copyright (c) 2023-2024 NVIDIA CORPORATION & AFFILIATES. All rights reserved.
#include <nvidia/conftest.h>
// Copyright (c) 2023, NVIDIA CORPORATION & AFFILIATES. All rights reserved.
#include <linux/hwmon-sysfs.h>
#include <linux/hwmon.h>
@@ -1093,10 +1091,8 @@ static int f75308_probe_child_from_dt(struct device *dev,
u32 reg_idx, seg_idx = 0, seg_val;
u8 seg5[F75308_MAX_FAN_SEG_CNT];
const char *val_str;
#if !defined(NV_OF_PROPERTY_FOR_EACH_REMOVED_INTERNAL_ARGS) /* Linux v6.11 */
struct property *prop;
const __be32 *p;
#endif
status = of_property_read_u32(child, "reg", &reg_idx);
if (status) {
@@ -1127,11 +1123,7 @@ static int f75308_probe_child_from_dt(struct device *dev,
if (status)
return status;
#if defined(NV_OF_PROPERTY_FOR_EACH_REMOVED_INTERNAL_ARGS) /* Linux v6.11 */
of_property_for_each_u32(child, "5seg", seg_val) {
#else
of_property_for_each_u32(child, "5seg", prop, p, seg_val) {
#endif
dev_dbg(dev, "%s: seg5[%u]: %u\n", __func__, seg_idx, seg_val);
if (seg_idx < F75308_MAX_FAN_SEG_CNT)
seg5[seg_idx++] = seg_val;
@@ -1222,7 +1214,7 @@ destroy_lock:
return status;
}
#if defined(NV_I2C_DRIVER_STRUCT_REMOVE_RETURN_TYPE_INT) /* Linux 6.1 */
#if KERNEL_VERSION(6, 1, 0) > LINUX_VERSION_CODE
static int f75308_remove(struct i2c_client *client)
#else
static void f75308_remove(struct i2c_client *client)
@@ -1231,7 +1223,7 @@ static void f75308_remove(struct i2c_client *client)
struct f75308_priv *priv = dev_get_drvdata(&client->dev);
mutex_destroy(&priv->locker);
#if defined(NV_I2C_DRIVER_STRUCT_REMOVE_RETURN_TYPE_INT) /* Linux 6.1 */
#if KERNEL_VERSION(6, 1, 0) > LINUX_VERSION_CODE
return 0;
#endif
}
@@ -1264,10 +1256,10 @@ static struct i2c_driver f75308_driver = {
.of_match_table = of_match_ptr(f75308_match_table),
},
.detect = f75308_detect,
#if defined(NV_I2C_DRIVER_STRUCT_HAS_PROBE_NEW) /* Dropped on Linux 6.6 */
.probe_new = f75308_probe,
#else
#if defined(NV_I2C_LEGACY_PROBE_NEW_REMOVED)
.probe = f75308_probe,
#else
.probe_new = f75308_probe,
#endif
.remove = f75308_remove,
.address_list = f75308_addr,

View File

@@ -5,8 +5,6 @@
* Copyright (C) 2022-2023 NVIDIA CORPORATION. All rights reserved.
*/
#include <nvidia/conftest.h>
#include <linux/i2c.h>
#include <linux/module.h>
#include <linux/init.h>
@@ -244,7 +242,7 @@ static int nvvrs11_vendor_info(struct nvvrs11_chip *chip)
return 0;
}
#if defined(NV_I2C_DRIVER_STRUCT_PROBE_WITHOUT_I2C_DEVICE_ID_ARG) /* Linux 6.3 */
#if KERNEL_VERSION(6, 3, 0) <= LINUX_VERSION_CODE
static int nvvrs11_probe(struct i2c_client *client)
#else
static int nvvrs11_probe(struct i2c_client *client,
@@ -310,7 +308,7 @@ exit:
return ret;
}
#if !defined(NV_I2C_DRIVER_STRUCT_REMOVE_RETURN_TYPE_INT) /* Linux 6.1 */
#if KERNEL_VERSION(6, 1, 0) <= LINUX_VERSION_CODE
static void nvvrs11_remove(struct i2c_client *client)
{
nvvrs11_delete_sys_files(&client->dev);

View File

@@ -1,5 +1,5 @@
# SPDX-License-Identifier: GPL-2.0-only
# Copyright (c) 2023-2024 NVIDIA CORPORATION & AFFILIATES. All rights reserved.
# Copyright (c) 2023 NVIDIA CORPORATION & AFFILIATES. All rights reserved.
subdir-ccflags-y += -Werror
@@ -7,8 +7,6 @@ obj-m += max9295.o
obj-m += max9296.o
ifeq ($(findstring ack_src,$(NV_BUILD_KERNEL_OPTIONS)),)
obj-m += max96712.o
ifdef CONFIG_MEDIA_SUPPORT
obj-m += ar1335_common.o
obj-m += lt6911uxc.o
obj-m += nv_imx185.o
@@ -19,10 +17,7 @@ obj-m += nv_imx390.o
obj-m += nv_imx477.o
obj-m += nv_ov5693.o
obj-m += nv_ar0234.o
obj-m += nv_hawk_owl.o
obj-m += max929x.o
endif
obj-m += pca9570.o
obj-m += nv_hawk_owl.o
obj-m += virtual_i2c_mux.o
endif

View File

@@ -1,5 +1,5 @@
/* SPDX-License-Identifier: GPL-2.0 */
/* Copyright (c) 2018-2024, NVIDIA CORPORATION & AFFILIATES. All Rights Reserved. */
/* Copyright (c) 2018-2023, NVIDIA CORPORATION & AFFILIATES. All Rights Reserved. */
/*
* ar0234_mode_tbls.h - ar0234 sensor mode tables
*/
@@ -62,6 +62,7 @@ static struct index_reg_8 ar0234_Double_Dser_Ser[] = {
{0x52, 0x0003, 0xAE}, // Disable CC to link B
{0x80, 0x0000, 0x84}, // Link A serializer address is 0x84
{0x52, 0x0003, 0xAB}, // Disable CC to link A
{0x80, 0x0000, 0x88}, // Link B serializer address is 0x88
{0x52, 0x0003, 0xAA}, // Enable CC to links A and B
@@ -69,17 +70,17 @@ static struct index_reg_8 ar0234_Double_Dser_Ser[] = {
{0x84, 0x0308, 0x7E}, // Pipe X pulls clock from port A, pipe Y from port B
{0x84, 0x0311, 0x21}, // Pipe X pulls data from port A, pipe Y from port B
{0x84, 0x0316, 0x6b}, // RAW10 to pipe Y
{0x84, 0x0314, 0x6b}, // RAW10 to pipe X
{0x84, 0x0314, 0x6b}, // RAW10 to pipe Y
{0x88, 0x0002, 0x33}, // Enable pipes X and Y
{0x88, 0x0308, 0x7E}, // Pipe X pulls clock from port A, pipe Y from port B
{0x88, 0x0311, 0x21}, // Pipe X pulls data from port A, pipe Y from port B
{0x88, 0x0316, 0x6b}, // RAW10 to pipe Y
{0x88, 0x0314, 0x6b}, // RAW10 to pipe X
{0x52, 0x00F4, 0x0f}, // Enable pipes 0-3 in deserializer
{0x88, 0x0314, 0x6b}, // RAW10 to pipe Y
{0x52, 0x00F4, 0x0f}, // Enable pipe 0
{0x52, 0x00F0, 0x10}, // Link A ID 0 to pipe 0 // Link A ID 1 to pipe 1
{0x52, 0x00F1, 0x54}, // Link B ID 0 to pipe 2 // Link B ID 1 to pipe 3
{0x52, 0x08A0, 0x01}, // CSI output is 4x2
{0x52, 0x08A0, 0x01}, // CSI output is 2x4
{0x52, 0x08A3, 0x44}, // Default 4x2 lane mapping
{0x52, 0x08A4, 0x44}, // Default 4x2 lane mapping
@@ -91,16 +92,16 @@ static struct index_reg_8 ar0234_Double_Dser_Ser[] = {
{0x52, 0x1D00, 0xF4},
{0x52, 0x1E00, 0xF4},
{0x52, 0x0415, 0x39},
{0x52, 0x0418, 0x39}, // Date rate is 2500Mbps/lane on port D
{0x52, 0x041B, 0x39}, // Data rate is 2500Mbps/lane on port E
{0x52, 0x041E, 0x39},
{0x52, 0x0415, 0x2E},
{0x52, 0x0418, 0x2E}, // 1400Mbps
{0x52, 0x041B, 0x2E},
{0x52, 0x041E, 0x2E},
{0x52, 0x1D00, 0xF5},
{0x52, 0x1E00, 0xF5},
{0x52, 0x090B, 0x07}, // Enable 3 mappings Pipe 0//video2
{0x52, 0x092D, 0x00}, // All mappings to controller 0 (port C)
{0x52, 0x092D, 0x15}, // All mappings to controller 1 (port A)
{0x52, 0x090D, 0x2B}, // Input RAW10, VC0
{0x52, 0x090E, 0x2B}, // Output RAW10, VC0
{0x52, 0x090F, 0x00}, // Input FS, VC0
@@ -109,7 +110,7 @@ static struct index_reg_8 ar0234_Double_Dser_Ser[] = {
{0x52, 0x0912, 0x01}, // Output FE, VC0
{0x52, 0x094B, 0x07}, // Enable 3 mappings Pipe 1 //video3
{0x52, 0x096D, 0x00}, // All mappings to controller 0 (port C)
{0x52, 0x096D, 0x15}, // All mappings to controller 1 (port A)
{0x52, 0x094D, 0x2B}, // Input RAW10, VC0
{0x52, 0x094E, 0x6B}, // Output RAW10, VC1
{0x52, 0x094F, 0x00}, // Input FS, VC0
@@ -118,23 +119,22 @@ static struct index_reg_8 ar0234_Double_Dser_Ser[] = {
{0x52, 0x0952, 0x41}, // Output FE, VC1
{0x52, 0x098B, 0x07}, // Enable 3 mappings Pipe 2 //video1
{0x52, 0x09AD, 0x15}, // All mappings to controller 1 (port D)
{0x52, 0x09AD, 0x15}, // All mappings to controller 1 (port A)
{0x52, 0x098D, 0x2B}, // Input RAW10, VC0
{0x52, 0x098E, 0x2B}, // Output RAW10, VC0
{0x52, 0x098E, 0xaB}, // Output RAW10, VC2
{0x52, 0x098F, 0x00}, // Input FS, VC0
{0x52, 0x0990, 0x00}, // Output FS, VC0
{0x52, 0x0990, 0x80}, // Output FS, VC2
{0x52, 0x0991, 0x01}, // Input FE, VC0
{0x52, 0x0992, 0x01}, // Output FE, VC0
{0x52, 0x0992, 0x81}, // Output FE, VC2
{0x52, 0x09CB, 0x07}, // Enable 3 mappings Pipe 3 //video0
{0x52, 0x09ED, 0x15}, // All mappings to controller 1 (port D)
{0x52, 0x09ED, 0x15}, // All mappings to controller 1 (port A)
{0x52, 0x09CD, 0x2B}, // Input RAW10, VC0
{0x52, 0x09CE, 0x6B}, // Output RAW10, VC1
{0x52, 0x09CE, 0xeB}, // Output RAW10, VC3
{0x52, 0x09CF, 0x00}, // Input FS, VC0
{0x52, 0x09D0, 0x40}, // Output FS, VC1
{0x52, 0x09D0, 0xc0}, // Output FS, VC3
{0x52, 0x09D1, 0x01}, // Input FE, VC0
{0x52, 0x09D2, 0x41}, // Output FE, VC1
{0x52, 0x09D2, 0xc1}, // Output FE, VC3
{0x52, 0x08A2, 0xF0},
{0x84, 0x02be, 0x90}, // Enable sensor power down pin.

View File

@@ -1,12 +1,10 @@
// SPDX-License-Identifier: GPL-2.0-only
// SPDX-FileCopyrightText: Copyright (c) 2017-2024, NVIDIA CORPORATION & AFFILIATES. All rights reserved.
// Copyright (c) 2017-2023, NVIDIA CORPORATION & AFFILIATES. All rights reserved.
// Copyright (c) 2022, e-con Systems. All rights reserved.
/*
* ar1335_common.c - AR1335 sensor driver
* ar1335.c - AR1335 sensor driver
*/
#include <nvidia/conftest.h>
#include <linux/slab.h>
#include <linux/uaccess.h>
#include <linux/gpio.h>
@@ -52,13 +50,11 @@ static uint32_t u8arr_to_uint32(uint8_t *in_arr)
in_arr[3]);
}
static int mcu_send_ctrl_cmd(struct i2c_client *client,
int cmd,
uint32_t payload_len,
uint16_t index)
static int mcu_send_ctrl_cmd(struct i2c_client *client, int cmd, uint32_t payload_len)
{
int err;
uint8_t orig_crc = 0, calc_crc = 0;
uint16_t index = 0xFFFF;
mc_data[0] = CMD_SIGNATURE;
mc_data[1] = cmd;
@@ -413,7 +409,7 @@ static int cam_set_fmt(struct v4l2_subdev *sd, struct v4l2_subdev_state *cfg,
if ((priv->mcu_cam_frmfmt[ret].size.width ==
format->format.width) &&
(priv->mcu_cam_frmfmt[ret].size.height ==
format->format.height))
format->format.height))
{
priv->frmfmt_mode = priv->mcu_cam_frmfmt[ret].mode;
flag = 1;
@@ -988,7 +984,7 @@ static int mcu_get_ctrl(struct i2c_client *client, uint32_t arg_ctrl_id,
/* First Txn Payload length = 2 */
payload_len = 2;
ret = mcu_send_ctrl_cmd(client, CMD_ID_GET_CTRL, payload_len, index);
ret = mcu_send_ctrl_cmd(client, CMD_ID_GET_CTRL, payload_len);
if (ret) {
dev_err(&client->dev, "CMD_ID_GET_CTRL send failed\n");
goto exit;
@@ -1154,8 +1150,7 @@ static int mcu_list_fmts(struct i2c_client *client,ISP_STREAM_INFO *stream_info,
/* First Txn Payload length = 0 */
payload_len = 2;
ret = mcu_send_ctrl_cmd(client, CMD_ID_GET_STREAM_INFO,
payload_len, index);
ret = mcu_send_ctrl_cmd(client, CMD_ID_GET_STREAM_INFO, payload_len);
if (ret) {
dev_err(&client->dev, "CMD_ID_GET_STREAM_INFO send failed\n");
goto exit;
@@ -1277,8 +1272,7 @@ static int mcu_get_ctrl_ui(struct i2c_client *client,
/* First Txn Payload length = 0 */
payload_len = 2;
ret = mcu_send_ctrl_cmd(client, CMD_ID_GET_CTRL_UI_INFO,
payload_len, index);
ret = mcu_send_ctrl_cmd(client, CMD_ID_GET_CTRL_UI_INFO, payload_len);
if (ret) {
dev_err(&client->dev, "CMD_ID_GET_CTRL_UI_INFO send failed\n");
goto exit;
@@ -1408,8 +1402,7 @@ static int mcu_list_ctrls(struct i2c_client *client,
/* First Txn Payload length = 0 */
payload_len = 2;
ret = mcu_send_ctrl_cmd(client, CMD_ID_GET_CTRL_INFO,
payload_len, index);
ret = mcu_send_ctrl_cmd(client, CMD_ID_GET_CTRL_INFO, payload_len);
if (ret) {
dev_err(&client->dev, "CMD_ID_GET_CTRL_INFO send failed\n");
goto exit;
@@ -2368,7 +2361,7 @@ exit:
return ret;
}
#if defined(NV_I2C_DRIVER_STRUCT_PROBE_WITHOUT_I2C_DEVICE_ID_ARG) /* Linux 6.3 */
#if KERNEL_VERSION(6, 3, 0) <= LINUX_VERSION_CODE
static int cam_probe(struct i2c_client *client)
#else
static int cam_probe(struct i2c_client *client,
@@ -2790,7 +2783,7 @@ exit:
devm_kfree(dev, ptr); \
}
#if defined(NV_I2C_DRIVER_STRUCT_REMOVE_RETURN_TYPE_INT) /* Linux 6.1 */
#if (KERNEL_VERSION(6, 1, 0) > LINUX_VERSION_CODE)
static int cam_remove(struct i2c_client *client)
#else
static void cam_remove(struct i2c_client *client)
@@ -2804,7 +2797,7 @@ static void cam_remove(struct i2c_client *client)
if (!s_data) {
dev_err(&client->dev, "camera common data is NULL\n");
#if defined(NV_I2C_DRIVER_STRUCT_REMOVE_RETURN_TYPE_INT) /* Linux 6.1 */
#if (KERNEL_VERSION(6, 1, 0) > LINUX_VERSION_CODE)
return -EINVAL;
#else
return;
@@ -2816,7 +2809,7 @@ static void cam_remove(struct i2c_client *client)
reset_gpio = of_get_named_gpio(node, "reset-gpios", 0);
if (reset_gpio < 0) {
dev_err(&client->dev, "Unable to get reset GPIO\n");
#if defined(NV_I2C_DRIVER_STRUCT_REMOVE_RETURN_TYPE_INT) /* Linux 6.1 */
#if (KERNEL_VERSION(6, 1, 0) > LINUX_VERSION_CODE)
return -EINVAL;
#else
return;

View File

@@ -1,5 +1,5 @@
/* SPDX-License-Identifier: GPL-2.0 */
/* Copyright (c) 2022-2024, NVIDIA CORPORATION & AFFILIATES. All Rights Reserved. */
/* Copyright (c) 2022-2023, NVIDIA CORPORATION & AFFILIATES. All Rights Reserved. */
/*
* hawk_owl_mode_tbls.h - ar0234 sensor mode tables
*/
@@ -179,9 +179,9 @@ static struct index_reg_8 i2c_address_trans_hawk1_eeprom[] = {
};
static struct index_reg_8 i2c_address_trans_hawk2_eeprom[] = {
{0x96, 0x0042, 0x2A},
{0x96, 0x0042, 0x84},
{0x96, 0x0043, 0xA8},
{0x96, 0x0044, 0x2C},
{0x96, 0x0044, 0x86},
{0x96, 0x0045, 0xAA},
{0x00, AR0234_TABLE_END, 0x00}
};
@@ -530,7 +530,6 @@ static struct index_reg_8 ar0234_Hawk_TripleLink_Dser_Ser[] = {
{0x98, 0x0311, 0x21}, // Pipe X pulls data from port A, pipe Y from port B
{0x98, 0x0316, 0x6b}, // RAW10 to pipe Y
{0x98, 0x0314, 0x6b}, // RAW10 to pipe Y
{0x52, 0x00F4, 0x3f}, // Enable video pipe 0,1,2,3,4,5
/*Tuned params to fix streaming issues */
{0x52, 0x00F0, 0x10}, // Link A ID 0 to pipe 0 // Link A ID 1 to pipe 1

View File

File diff suppressed because it is too large Load Diff

View File

@@ -4,8 +4,6 @@
* Lontium LT6911UXC HDMI-CSI bridge driver
*/
#include <nvidia/conftest.h>
#include <linux/slab.h>
#include <linux/uaccess.h>
#include <linux/gpio.h>
@@ -669,7 +667,7 @@ static struct camera_common_sensor_ops lt6911uxc_common_ops = {
};
#if defined(NV_I2C_DRIVER_STRUCT_PROBE_WITHOUT_I2C_DEVICE_ID_ARG) /* Linux 6.3 */
#if KERNEL_VERSION(6, 3, 0) <= LINUX_VERSION_CODE
static int lt6911uxc_probe(struct i2c_client *client)
#else
static int lt6911uxc_probe(struct i2c_client *client,
@@ -733,7 +731,7 @@ static int lt6911uxc_probe(struct i2c_client *client,
return 0;
}
#if defined(NV_I2C_DRIVER_STRUCT_REMOVE_RETURN_TYPE_INT) /* Linux 6.1 */
#if (KERNEL_VERSION(6, 1, 0) > LINUX_VERSION_CODE)
static int lt6911uxc_remove(struct i2c_client *client)
#else
static void lt6911uxc_remove(struct i2c_client *client)
@@ -743,7 +741,7 @@ static void lt6911uxc_remove(struct i2c_client *client)
struct lt6911uxc *priv;
if (!s_data)
#if defined(NV_I2C_DRIVER_STRUCT_REMOVE_RETURN_TYPE_INT) /* Linux 6.1 */
#if (KERNEL_VERSION(6, 1, 0) > LINUX_VERSION_CODE)
return -EINVAL;
#else
return;
@@ -753,7 +751,7 @@ static void lt6911uxc_remove(struct i2c_client *client)
tegracam_v4l2subdev_unregister(priv->tc_dev);
tegracam_device_unregister(priv->tc_dev);
#if defined(NV_I2C_DRIVER_STRUCT_REMOVE_RETURN_TYPE_INT) /* Linux 6.1 */
#if (KERNEL_VERSION(6, 1, 0) > LINUX_VERSION_CODE)
return 0;
#endif
}

View File

@@ -4,8 +4,6 @@
* max9295.c - max9295 GMSL Serializer driver
*/
#include <nvidia/conftest.h>
#include <media/camera_common.h>
#include <linux/module.h>
#include <media/max9295.h>
@@ -465,7 +463,7 @@ static struct regmap_config max9295_regmap_config = {
.cache_type = REGCACHE_RBTREE,
};
#if defined(NV_I2C_DRIVER_STRUCT_PROBE_WITHOUT_I2C_DEVICE_ID_ARG) /* Linux 6.3 */
#if KERNEL_VERSION(6, 3, 0) <= LINUX_VERSION_CODE
static int max9295_probe(struct i2c_client *client)
#else
static int max9295_probe(struct i2c_client *client,
@@ -514,7 +512,7 @@ static int max9295_probe(struct i2c_client *client,
return err;
}
#if defined(NV_I2C_DRIVER_STRUCT_REMOVE_RETURN_TYPE_INT) /* Linux 6.1 */
#if (KERNEL_VERSION(6, 1, 0) > LINUX_VERSION_CODE)
static int max9295_remove(struct i2c_client *client)
#else
static void max9295_remove(struct i2c_client *client)
@@ -528,7 +526,7 @@ static void max9295_remove(struct i2c_client *client)
i2c_unregister_device(client);
client = NULL;
}
#if defined(NV_I2C_DRIVER_STRUCT_REMOVE_RETURN_TYPE_INT) /* Linux 6.1 */
#if (KERNEL_VERSION(6, 1, 0) > LINUX_VERSION_CODE)
return 0;
#endif
}

View File

@@ -4,8 +4,6 @@
* max9296.c - max9296 GMSL Deserializer driver
*/
#include <nvidia/conftest.h>
#include <linux/gpio.h>
#include <linux/module.h>
#include <linux/of.h>
@@ -848,7 +846,7 @@ static struct regmap_config max9296_regmap_config = {
.cache_type = REGCACHE_RBTREE,
};
#if defined(NV_I2C_DRIVER_STRUCT_PROBE_WITHOUT_I2C_DEVICE_ID_ARG) /* Linux 6.3 */
#if KERNEL_VERSION(6, 3, 0) <= LINUX_VERSION_CODE
static int max9296_probe(struct i2c_client *client)
#else
static int max9296_probe(struct i2c_client *client,
@@ -894,7 +892,7 @@ static int max9296_probe(struct i2c_client *client,
return 0;
}
#if defined(NV_I2C_DRIVER_STRUCT_REMOVE_RETURN_TYPE_INT) /* Linux 6.1 */
#if (KERNEL_VERSION(6, 1, 0) > LINUX_VERSION_CODE)
static int max9296_remove(struct i2c_client *client)
#else
static void max9296_remove(struct i2c_client *client)
@@ -908,7 +906,7 @@ static void max9296_remove(struct i2c_client *client)
i2c_unregister_device(client);
client = NULL;
}
#if defined(NV_I2C_DRIVER_STRUCT_REMOVE_RETURN_TYPE_INT) /* Linux 6.1 */
#if (KERNEL_VERSION(6, 1, 0) > LINUX_VERSION_CODE)
return 0;
#endif
}

View File

@@ -1,194 +0,0 @@
// SPDX-License-Identifier: GPL-2.0-only
// SPDX-FileCopyrightText: Copyright (c) 2024, NVIDIA CORPORATION & AFFILIATES. All rights reserved.
/*
* max929x.c - max929x IO Expander driver
*/
#include <nvidia/conftest.h>
#include <linux/seq_file.h>
#include <linux/debugfs.h>
#include <media/camera_common.h>
#include <linux/module.h>
#include <linux/gpio/consumer.h>
#include <linux/gpio.h>
#include <linux/module.h>
#include <linux/seq_file.h>
#include <linux/of.h>
#include <linux/of_device.h>
#include <linux/of_gpio.h>
#include "max929x.h"
struct max929x {
struct i2c_client *i2c_client;
struct regmap *regmap;
unsigned int pwdn_gpio;
unsigned short ser_addr;
};
struct max929x *priv;
static int max929x_write_reg(u8 slave_addr, u16 reg, u8 val)
{
struct i2c_client *i2c_client = priv->i2c_client;
int err;
i2c_client->addr = slave_addr;
err = regmap_write(priv->regmap, reg, val);
if (err)
dev_err(&i2c_client->dev, "%s:i2c write failed, slave_addr 0x%x, 0x%x = 0x%x\n",
__func__, slave_addr, reg, val);
return err;
}
static int max929x_write_reg_list(struct max929x_reg *table, int size)
{
struct device dev = priv->i2c_client->dev;
int err = 0;
int i;
u8 slave_addr;
u16 reg;
u8 val;
for (i = 0; i < size; i++) {
if (table[i].slave_addr == SER_SLAVE2)
slave_addr = priv->ser_addr;
else
slave_addr = table[i].slave_addr;
reg = table[i].reg;
val = table[i].val;
if (slave_addr == 0xf1) {
msleep(val);
msleep(2000);
continue;
}
dev_dbg(&dev, "%s: size %d, slave_addr 0x%x, reg 0x%x, val 0x%x\n",
__func__, size, slave_addr, reg, val);
err = max929x_write_reg(slave_addr, reg, val);
if (err != 0)
break;
mdelay(5);
}
return err;
}
static struct regmap_config max929x_regmap_config = {
.reg_bits = 16,
.val_bits = 8,
.cache_type = REGCACHE_RBTREE,
};
#if defined(NV_I2C_DRIVER_STRUCT_PROBE_WITHOUT_I2C_DEVICE_ID_ARG) /* Linux 6.3 */
static int max929x_probe(struct i2c_client *client)
#else
static int max929x_probe(struct i2c_client *client,
const struct i2c_device_id *id)
#endif
{
struct device dev = client->dev;
struct device_node *np = (&dev)->of_node;
unsigned short ser_addr = SER_SLAVE2;
int err;
dev_dbg(&dev, "%s: enter\n", __func__);
priv = devm_kzalloc(&client->dev, sizeof(*priv), GFP_KERNEL);
priv->i2c_client = client;
priv->regmap = devm_regmap_init_i2c(priv->i2c_client, &max929x_regmap_config);
if (IS_ERR(priv->regmap)) {
dev_err(&client->dev,
"regmap init failed: %ld\n", PTR_ERR(priv->regmap));
return -ENODEV;
}
priv->pwdn_gpio = of_get_named_gpio(np, "pwdn-gpios", 0);
if (priv->pwdn_gpio < 0) {
dev_err(&dev, "pwdn-gpios not found\n");
return -EINVAL;
}
if (priv->pwdn_gpio) {
gpio_direction_output(priv->pwdn_gpio, 1);
gpio_set_value(priv->pwdn_gpio, 1);
msleep(100);
}
/*
* Try to find the I2C address of serializer by writting to register
* 0x00 at i2c slave address 0x62 and 0x40. When write is successful
* the slave address is saved and used when configuring serializer.
*/
if (max929x_write_reg(SER_SLAVE2, MAX9295_DEV_ADDR, SER_SLAVE2 << 1)) {
if (max929x_write_reg(SER_SLAVE1, MAX9295_DEV_ADDR, SER_SLAVE1 << 1)) {
dev_err(&dev, "%s: failed to find serializer at 0x%x or 0x%x\n",
__func__, SER_SLAVE2, SER_SLAVE1);
return -ENODEV;
}
ser_addr = SER_SLAVE1;
}
msleep(100);
priv->ser_addr = ser_addr;
err = max929x_write_reg_list(max929x_Double_Dser_Ser_init,
sizeof(max929x_Double_Dser_Ser_init)/sizeof(struct max929x_reg));
if (err == 0)
dev_dbg(&dev, "%s: success\n", __func__);
else
dev_err(&dev, "%s: fail\n", __func__);
dev_set_drvdata(&client->dev, priv);
return 0;
}
#if defined(NV_I2C_DRIVER_STRUCT_REMOVE_RETURN_TYPE_INT) /* Linux 6.1 */
static int max929x_remove(struct i2c_client *client)
#else
static void max929x_remove(struct i2c_client *client)
#endif
{
struct device dev = client->dev;
gpio_set_value(priv->pwdn_gpio, 0);
dev_dbg(&dev, "%s: \n", __func__);
#if defined(NV_I2C_DRIVER_STRUCT_REMOVE_RETURN_TYPE_INT) /* Linux 6.1 */
return 0;
#endif
}
static const struct i2c_device_id max929x_id[] = {
{ "max929x", 0 },
{ },
};
MODULE_DEVICE_TABLE(i2c, max929x_id);
const struct of_device_id max929x_of_match[] = {
{ .compatible = "Maxim,max929x", },
{ },
};
MODULE_DEVICE_TABLE(of, max929x_of_match);
static struct i2c_driver max929x_i2c_driver = {
.driver = {
.owner = THIS_MODULE,
.name = "max929x",
.of_match_table = of_match_ptr(max929x_of_match),
},
.probe = max929x_probe,
.remove = max929x_remove,
.id_table = max929x_id,
};
module_i2c_driver(max929x_i2c_driver);
MODULE_DESCRIPTION("IO Expander driver max929x");
MODULE_AUTHOR("NVIDIA Corporation");
MODULE_LICENSE("GPL v2");

View File

@@ -1,152 +0,0 @@
/* SPDX-License-Identifier: GPL-2.0-only */
/* SPDX-FileCopyrightText: Copyright (c) 2024, NVIDIA CORPORATION & AFFILIATES. All rights reserved. */
#ifndef __MAX929X_H__
#define __MAX929X_H__
/* TI FPD Link III 954 deser I2C address */
#define TI954_ADDR (0x30)
/* TI FPD Link III 953 ser I2C address */
#define TI953_ADDR (0x18)
/* TI 953 alias address */
#define TI953_CAM1_ADDR (0x29)
#define TI953_CAM2_ADDR (0X2A)
#define MAX9295_DEV_ADDR 0x00
#define SENSOR_ADDR (0x1a)
/* CAM alias address */
#define CAM1_SENSOR_ADDR (0x1b)
#define CAM2_SENSOR_ADDR (0x1c)
#define TI954_RESET_ADDR (0x01)
#define TI954_RESET_VAL (0x02)
#define AFDRV_I2C_ADDR (0x3E)
/*AF ctrl*/
#define AFDRV1_I2C_ADDR (0x21)
#define AFDRV2_I2C_ADDR (0x20)
#define EEPROM_I2C_ADDR (0x50)
/*eeprom ctrl*/
#define EEPROM1_I2C_ADDR (0x51)
#define EEPROM2_I2C_ADDR (0x52)
struct max929x_reg {
u8 slave_addr;
u16 reg;
u8 val;
};
/* Serializer slave addresses */
#define SER_SLAVE1 0x40
#define SER_SLAVE2 0x62
/* Deserializer slave addresses */
#define DESER_SLAVE 0x48
/*
* MAX9296 i2c addr 0x90(8bits) 0x48(7bits)
* (MAX9296 link A) MAX9295 i2c addr 0xc4(8bits) 0x62(7bits)
*/
static struct max929x_reg max929x_Double_Dser_Ser_init[] = {
/* set MFP0 low to reset sensor */
{0x62, 0x02be, 0x80},
/* Set SER to 1x4 mode (phy_config = 0) */
{0x62, 0x0330, 0x00},
{0x62, 0x0332, 0xe4},
/* Additional lane map */
{0x62, 0x0333, 0xe4},
/* Set 4 lanes for serializer (ctrl1_num_lanes = 3) */
{0x62, 0x0331, 0x31},
/* Start video from both port A and port B. */
{0x62, 0x0311, 0x20},
/*
* Enable info lines. Additional start bits for Port A and B.
* Use data from port B for all pipelines
*/
{0x62, 0x0308, 0x62},
/* Route 16bit DCG (DT = 0x30) to VIDEO_X (Bit 6 enable) */
{0x62, 0x0314, 0x22},
/* Route 12bit RAW (DT = 0x2C) to VIDEO_Y (Bit 6 enable) */
{0x62, 0x0316, 0x6c},
/* Route EMBEDDED8 to VIDEO_Z (Bit 6 enable) */
{0x62, 0x0318, 0x22},
/* Unused VIDEO_U */
{0x62, 0x031A, 0x22},
/*
* Make sure all pipelines start transmission
* (VID_TX_EN_X/Y/Z/U = 1)
*/
{0x62, 0x0002, 0x22},
/* Set MIPI Phy Mode: 2x(1x4) mode */
{0x48, 0x0330, 0x04},
/* lane maps - all 4 ports mapped straight */
{0x48, 0x0333, 0x4E},
/* Additional lane map */
{0x48, 0x0334, 0xE4},
/*
* lane count - 0 lanes striping on controller 0
* (Port A slave in 2x1x4 mode).
*/
{0x48, 0x040A, 0x00},
/*
* lane count - 4 lanes striping on controller 1
* (Port A master in 2x1x4 mode).
*/
{0x48, 0x044A, 0xd0},
/*
* lane count - 4 lanes striping on controller 2
* (Port B master in 2x1x4 mode).
*/
{0x48, 0x048A, 0xd0},
/*
* lane count - 0 lanes striping on controller 3
* (Port B slave in 2x1x4 mode).
*/
{0x48, 0x04CA, 0x00},
/*
* MIPI clock rate - 1.5Gbps from controller 0 clock
* (Port A slave in 2x1x4 mode).
*/
{0x48, 0x031D, 0x2f},
/*
* MIPI clock rate - 1.5Gbps from controller 1 clock
* (Port A master in 2x1x4 mode).
*/
{0x48, 0x0320, 0x2f},
/*
* MIPI clock rate - 1.5Gbps from controller 2 clock
* (Port B master in 2x1x4 mode).
*/
{0x48, 0x0323, 0x2f},
/*
* MIPI clock rate - 1.5Gbps from controller 2 clock
* (Port B slave in 2x1x4 mode).
*/
{0x48, 0x0326, 0x2f},
/* Route data from stream 0 to pipe X */
{0x48, 0x0050, 0x00},
/* Route data from stream 0 to pipe Y */
{0x48, 0x0051, 0x01},
/* Route data from stream 0 to pipe Z */
{0x48, 0x0052, 0x02},
/* Route data from stream 0 to pipe U */
{0x48, 0x0053, 0x03},
/* Enable all PHYS. */
{0x48, 0x0332, 0xF0},
/* Enable sensor power down pin. Put imager in,Active mode */
{0x62, 0x02be, 0x90},
/* Output RCLK to sensor. */
{0x62, 0x03F1, 0x89},
/* MFP8 for FSIN */
{0x62, 0x02D8, 0x10},
{0x62, 0x02D6, 0x04},
/* need disable pixel clk out inb order to use MFP1 */
{0x48, 0x0005, 0x00},
/* GPIO TX compensation */
{0x48, 0x02B3, 0x83},
{0x48, 0x02B4, 0x10},
};
#endif

View File

@@ -7,8 +7,6 @@
/* #define DEBUG */
#include <nvidia/conftest.h>
#include <linux/seq_file.h>
#include <linux/debugfs.h>
#include <media/camera_common.h>
@@ -228,7 +226,7 @@ static struct regmap_config max96712_regmap_config = {
.cache_type = REGCACHE_RBTREE,
};
#if defined(NV_I2C_DRIVER_STRUCT_PROBE_WITHOUT_I2C_DEVICE_ID_ARG) /* Linux 6.3 */
#if KERNEL_VERSION(6, 3, 0) <= LINUX_VERSION_CODE
static int max96712_probe(struct i2c_client *client)
#else
static int max96712_probe(struct i2c_client *client,
@@ -268,7 +266,7 @@ static int max96712_probe(struct i2c_client *client,
return err;
}
#if defined(NV_I2C_DRIVER_STRUCT_REMOVE_RETURN_TYPE_INT) /* Linux 6.1 */
#if (KERNEL_VERSION(6, 1, 0) > LINUX_VERSION_CODE)
static int max96712_remove(struct i2c_client *client)
#else
static void max96712_remove(struct i2c_client *client)
@@ -279,7 +277,7 @@ static void max96712_remove(struct i2c_client *client)
i2c_unregister_device(client);
client = NULL;
}
#if defined(NV_I2C_DRIVER_STRUCT_REMOVE_RETURN_TYPE_INT) /* Linux 6.1 */
#if (KERNEL_VERSION(6, 1, 0) > LINUX_VERSION_CODE)
return 0;
#endif
}

View File

@@ -1,11 +1,9 @@
// SPDX-License-Identifier: GPL-2.0-only
// SPDX-FileCopyrightText: Copyright (c) 2018-2024 NVIDIA CORPORATION & AFFILIATES. All rights reserved.
// SPDX-License-Identifier: GPL-2.0
// Copyright (c) 2018-2023, NVIDIA CORPORATION & AFFILIATES. All Rights Reserved.
/*
* ar0234.c - ar0234 sensor driver
*/
#include <nvidia/conftest.h>
#define DEBUG 1
#include <linux/slab.h>
#include <linux/uaccess.h>
@@ -28,7 +26,6 @@
#define MAX_TANGENTIAL_COEFFICIENTS 2
#define MAX_FISHEYE_COEFFICIENTS 6
#define CAMERA_MAX_SN_LENGTH 32
#define LEOP_CAMERA_MAX_SN_LENGTH 10
#define MAX_RLS_COLOR_CHANNELS 4
#define MAX_RLS_BREAKPOINTS 6
@@ -65,6 +62,7 @@ static const u32 ctrl_cid_list[] = {
TEGRA_CAMERA_CID_ALTERNATING_EXPOSURE,
};
const u16 alternating_exposure_cfg_size = sizeof(struct alternating_exposure_cfg);
// Coefficients as per distortion model (wide FOV) being used
struct fisheye_lens_distortion_coeff {
@@ -127,13 +125,7 @@ struct camera_extrinsics {
float tx, ty, tz;
};
/*
* IMU parameters used by HAWK 1.0. HAWK 1.0 did not have IMU noise model parameters
* in EEPROM. To preserve backward compatibility with HAWK 1.0, the EEPROM data is arranged
* in a certain way which requires tracking the imu noise model parameters in a
* separate structure.
*/
struct imu_params_v1 {
struct imu_params {
// 3D vector to add to accelerometer readings
float linear_acceleration_bias[3];
// 3D vector to add to gyroscope readings
@@ -142,12 +134,7 @@ struct imu_params_v1 {
float gravity_acceleration[3];
// Extrinsic structure for IMU device
struct camera_extrinsics extr;
};
struct imu_params_noise_m {
/*
* Noise model parameters
*/
// Noise model parameters
float update_rate;
float linear_acceleration_noise_density;
float linear_acceleration_random_walk;
@@ -155,14 +142,6 @@ struct imu_params_noise_m {
float angular_velocity_random_walk;
};
/*
* Combined IMU calibration data structure
*/
struct imu_params_v2 {
struct imu_params_v1 imu_data_v1;
struct imu_params_noise_m nm;
};
struct radial_lsc_params {
// Image height
u16 image_height;
@@ -205,7 +184,7 @@ struct NvCamSyncSensorCalibData {
u8 imu_present;
// Intrinsic structure for IMU
struct imu_params_v2 imu;
struct imu_params imu;
// HAWK module serial number
u8 serial_number[CAMERA_MAX_SN_LENGTH];
@@ -240,14 +219,10 @@ struct LiEeprom_Content_Struct {
/**
* Intrinsic structure for IMU
*/
struct imu_params_v1 imu;
u8 tmp[16];
struct imu_params imu;
// HAWK module serial number
u8 serial_number[LEOP_CAMERA_MAX_SN_LENGTH];
struct imu_params_noise_m nm;
u8 serial_number[CAMERA_MAX_SN_LENGTH];
// Radial Lens Shading Correction parameters
struct radial_lsc_params left_rls;
@@ -701,10 +676,9 @@ static int ar0234_fill_eeprom(struct tegracam_device *tc_dev,
priv->EepromCalib.cam_extr = tmp->cam_extr;
priv->EepromCalib.imu_present = tmp->imu_present;
priv->EepromCalib.imu.imu_data_v1 = tmp->imu;
priv->EepromCalib.imu.nm = tmp->nm;
priv->EepromCalib.imu = tmp->imu;
memcpy(priv->EepromCalib.serial_number, tmp->serial_number,
8);
CAMERA_MAX_SN_LENGTH);
if (priv->sync_sensor_index == 1)
priv->EepromCalib.rls = tmp->left_rls;
@@ -818,7 +792,7 @@ static struct tegracam_ctrl_ops ar0234_ctrl_ops = {
.numctrls = ARRAY_SIZE(ctrl_cid_list),
.ctrl_cid_list = ctrl_cid_list,
.string_ctrl_size = {AR0234_EEPROM_STR_SIZE},
.compound_ctrl_size = {sizeof(struct NvCamSyncSensorCalibData), sizeof(struct alternating_exposure_cfg)},
.compound_ctrl_size = {sizeof(struct NvCamSyncSensorCalibData), alternating_exposure_cfg_size},
.set_gain = ar0234_set_gain,
.set_exposure = ar0234_set_exposure,
.set_exposure_short = ar0234_set_exposure,
@@ -1070,7 +1044,7 @@ static int ar0234_board_setup(struct ar0234 *priv)
#if defined(NV_I2C_DRIVER_STRUCT_PROBE_WITHOUT_I2C_DEVICE_ID_ARG) /* Linux 6.3 */
#if KERNEL_VERSION(6, 3, 0) <= LINUX_VERSION_CODE
static int ar0234_probe(struct i2c_client *client)
#else
static int ar0234_probe(struct i2c_client *client,
@@ -1175,7 +1149,7 @@ static int ar0234_probe(struct i2c_client *client,
return 0;
}
#if defined(NV_I2C_DRIVER_STRUCT_REMOVE_RETURN_TYPE_INT) /* Linux 6.1 */
#if (KERNEL_VERSION(6, 1, 0) > LINUX_VERSION_CODE)
static int ar0234_remove(struct i2c_client *client)
#else
static void ar0234_remove(struct i2c_client *client)
@@ -1185,7 +1159,7 @@ static void ar0234_remove(struct i2c_client *client)
struct ar0234 *priv;
if (!s_data)
#if defined(NV_I2C_DRIVER_STRUCT_REMOVE_RETURN_TYPE_INT) /* Linux 6.1 */
#if (KERNEL_VERSION(6, 1, 0) > LINUX_VERSION_CODE)
return -EINVAL;
#else
return;
@@ -1195,7 +1169,7 @@ static void ar0234_remove(struct i2c_client *client)
tegracam_v4l2subdev_unregister(priv->tc_dev);
tegracam_device_unregister(priv->tc_dev);
ar0234_eeprom_device_release(priv);
#if defined(NV_I2C_DRIVER_STRUCT_REMOVE_RETURN_TYPE_INT) /* Linux 6.1 */
#if (KERNEL_VERSION(6, 1, 0) > LINUX_VERSION_CODE)
return 0;
#endif
}

View File

@@ -1,11 +1,9 @@
// SPDX-License-Identifier: GPL-2.0-only
// SPDX-FileCopyrightText: Copyright (c) 2022-2024 NVIDIA CORPORATION & AFFILIATES. All rights reserved.
// SPDX-License-Identifier: GPL-2.0
// Copyright (c) 2022-2023, NVIDIA CORPORATION & AFFILIATES. All Rights Reserved.
/*
* nv_hawk_owl.c.c - ar0234 sensor driver
*/
#include <nvidia/conftest.h>
#define DEBUG 0
#include <linux/slab.h>
#include <linux/uaccess.h>
@@ -17,7 +15,6 @@
#include <linux/of_gpio.h>
#include <media/max9295.h>
#include <media/max9296.h>
#include <media/nv_hawk_owl.h>
#include <media/tegracam_core.h>
#include "hawk_owl_mode_tbls.h"
#include <linux/ktime.h>
@@ -26,7 +23,6 @@
#define MAX_TANGENTIAL_COEFFICIENTS 2
#define MAX_FISHEYE_COEFFICIENTS 6
#define CAMERA_MAX_SN_LENGTH 32
#define LEOP_CAMERA_MAX_SN_LENGTH 10
#define MAX_RLS_COLOR_CHANNELS 4
#define MAX_RLS_BREAKPOINTS 6
#define OWL_CHANNEL 1
@@ -68,6 +64,8 @@ static const u32 ctrl_cid_list[] = {
TEGRA_CAMERA_CID_ALTERNATING_EXPOSURE,
};
const u16 alternating_exposure_cfg_size = sizeof(struct alternating_exposure_cfg);
// Coefficients as per distortion model (wide FOV) being used
typedef struct
{
@@ -129,13 +127,6 @@ typedef struct
// Translation parameter from one camera to another parameter
float tx, ty, tz;
} camera_extrinsics;
/*
* IMU parameters used by HAWK 1.0. HAWK 1.0 did not have IMU noise model parameters
* in EEPROM. To preserve backward compatibility with HAWK 1.0, the EEPROM data is arranged
* in a certain way which requires tracking the imu noise model parameters in a
* separate structure.
*/
typedef struct
{
// 3D vector to add to accelerometer readings
@@ -146,26 +137,13 @@ typedef struct
float gravity_acceleration[3];
// Extrinsic structure for IMU device
camera_extrinsics extr;
} imu_params_v1;
typedef struct {
/*
* Noise model parameters
*/
// Noise model parameters
float update_rate;
float linear_acceleration_noise_density;
float linear_acceleration_random_walk;
float angular_velocity_noise_density;
float angular_velocity_random_walk;
} imu_params_noise_m;
/*
* Combined IMU calibration data structure
*/
typedef struct {
imu_params_v1 imu_data_v1;
imu_params_noise_m nm;
} imu_params_v2;
} imu_params;
typedef struct {
// Image height
@@ -209,7 +187,7 @@ typedef struct
u8 imu_present;
// Intrinsic structure for IMU
imu_params_v2 imu;
imu_params imu;
// HAWK module serial number
u8 serial_number[CAMERA_MAX_SN_LENGTH];
@@ -217,7 +195,6 @@ typedef struct
// Radial Lens Shading Correction parameters
radial_lsc_params rls;
} NvCamSyncSensorCalibData;
typedef struct
{
/**
@@ -245,20 +222,15 @@ typedef struct
/**
* Intrinsic structure for IMU
*/
imu_params_v1 imu;
u8 tmp[16];
imu_params imu;
// HAWK module serial number
u8 serial_number[LEOP_CAMERA_MAX_SN_LENGTH];
imu_params_noise_m nm;
u8 serial_number[CAMERA_MAX_SN_LENGTH];
// Radial Lens Shading Correction parameters
radial_lsc_params left_rls;
radial_lsc_params right_rls;
} LiEeprom_Content_Struct;
struct ar0234 {
struct camera_common_eeprom_data eeprom[AR0234_EEPROM_NUM_BLOCKS];
u8 eeprom_buf[AR0234_EEPROM_SIZE];
@@ -273,20 +245,17 @@ struct ar0234 {
const char *sensor_name;
NvCamSyncSensorCalibData EepromCalib;
};
static const struct regmap_config sensor_regmap_config = {
.reg_bits = 16,
.val_bits = 16,
.cache_type = REGCACHE_RBTREE,
};
static inline void ar0234_get_coarse_time_regs_shs1(ar0234_reg *regs,
u16 coarse_time)
{
regs->addr = AR0234_COARSE_TIME_SHS1_ADDR;
regs->val = (coarse_time) & 0xffff;
}
static inline void ar0234_get_gain_reg(ar0234_reg *regs,
u16 gain)
{
@@ -374,7 +343,7 @@ retry_sensor:
return -1;
} else {
if (0x301a == table[i].addr || 0x3060 == table[i].addr)
msleep(20);
msleep(100);
}
} else {
retry = 5;
@@ -585,7 +554,7 @@ static int ar0234_power_on(struct camera_common_data *s_data)
struct camera_common_power_rail *pw = s_data->power;
struct camera_common_pdata *pdata = s_data->pdata;
struct device *dev = s_data->dev;
struct ar0234 *priv = (struct ar0234 *) s_data->priv;
if (pdata && pdata->power_on) {
err = pdata->power_on(pw);
if (err)
@@ -598,6 +567,8 @@ static int ar0234_power_on(struct camera_common_data *s_data)
gpio_set_value(pw->reset_gpio, 1);
usleep_range(1000, 2000);
pw->state = SWITCH_ON;
/*i2c address trans for Hawk & Owl*/
err = ar0234_hawk_owl_i2ctrans(priv);
return err;
}
static int ar0234_power_off(struct camera_common_data *s_data)
@@ -792,10 +763,9 @@ static int ar0234_fill_eeprom(struct tegracam_device *tc_dev,
}
priv->EepromCalib.cam_extr = tmp->cam_extr;
priv->EepromCalib.imu_present = tmp->imu_present;
priv->EepromCalib.imu.imu_data_v1 = tmp->imu;
priv->EepromCalib.imu.nm = tmp->nm;
priv->EepromCalib.imu = tmp->imu;
memcpy(priv->EepromCalib.serial_number, tmp->serial_number,
8);
CAMERA_MAX_SN_LENGTH);
if (priv->sync_sensor_index == 1)
priv->EepromCalib.rls = tmp->left_rls;
@@ -907,7 +877,7 @@ static struct tegracam_ctrl_ops ar0234_ctrl_ops = {
.numctrls = ARRAY_SIZE(ctrl_cid_list),
.ctrl_cid_list = ctrl_cid_list,
.string_ctrl_size = {AR0234_EEPROM_STR_SIZE},
.compound_ctrl_size = {sizeof(NvCamSyncSensorCalibData), sizeof(struct alternating_exposure_cfg)},
.compound_ctrl_size = {sizeof(NvCamSyncSensorCalibData), alternating_exposure_cfg_size},
.set_gain = ar0234_set_gain,
.set_exposure = ar0234_set_exposure,
.set_exposure_short = ar0234_set_exposure,
@@ -1464,7 +1434,7 @@ static int ar0234_hawk_owl_deser_ser_program(struct ar0234 *priv)
return err;
}
#if defined(NV_I2C_DRIVER_STRUCT_PROBE_WITHOUT_I2C_DEVICE_ID_ARG) /* Linux 6.3 */
#if KERNEL_VERSION(6, 3, 0) <= LINUX_VERSION_CODE
static int ar0234_probe(struct i2c_client *client)
#else
static int ar0234_probe(struct i2c_client *client,
@@ -1533,14 +1503,6 @@ static int ar0234_probe(struct i2c_client *client,
dev_err(&client->dev,"Failed to enable gpio/ to do serializer i2c address trans\n");
goto un_register;
}
/* i2c address trans for Hawk & Owl */
err = ar0234_hawk_owl_i2ctrans(priv);
if (err) {
dev_err(&client->dev, "Failed to do i2c address trans\n");
goto un_register;
}
err = ar0234_power_on(tc_dev->s_data);
if (err) {
dev_err(&client->dev,"Failed to power on\n");
@@ -1610,7 +1572,7 @@ un_register:
return err;
}
#if defined(NV_I2C_DRIVER_STRUCT_REMOVE_RETURN_TYPE_INT) /* Linux 6.1 */
#if (KERNEL_VERSION(6, 1, 0) > LINUX_VERSION_CODE)
static int ar0234_remove(struct i2c_client *client)
#else
static void ar0234_remove(struct i2c_client *client)
@@ -1620,7 +1582,7 @@ static void ar0234_remove(struct i2c_client *client)
struct ar0234 *priv = (struct ar0234 *)s_data->priv;
if (!s_data)
#if defined(NV_I2C_DRIVER_STRUCT_REMOVE_RETURN_TYPE_INT) /* Linux 6.1 */
#if (KERNEL_VERSION(6, 1, 0) > LINUX_VERSION_CODE)
return -EINVAL;
#else
return;
@@ -1628,7 +1590,7 @@ static void ar0234_remove(struct i2c_client *client)
tegracam_v4l2subdev_unregister(priv->tc_dev);
tegracam_device_unregister(priv->tc_dev);
ar0234_eeprom_device_release(priv);
#if defined(NV_I2C_DRIVER_STRUCT_REMOVE_RETURN_TYPE_INT) /* Linux 6.1 */
#if (KERNEL_VERSION(6, 1, 0) > LINUX_VERSION_CODE)
return 0;
#endif
}

View File

@@ -5,8 +5,6 @@
* Copyright (c) 2016-2023 NVIDIA CORPORATION & AFFILIATES. All rights reserved.
*/
#include <nvidia/conftest.h>
#include <linux/slab.h>
#include <linux/uaccess.h>
#include <linux/gpio.h>
@@ -777,7 +775,7 @@ static const struct v4l2_subdev_internal_ops imx185_subdev_internal_ops = {
.open = imx185_open,
};
#if defined(NV_I2C_DRIVER_STRUCT_PROBE_WITHOUT_I2C_DEVICE_ID_ARG) /* Linux 6.3 */
#if KERNEL_VERSION(6, 3, 0) <= LINUX_VERSION_CODE
static int imx185_probe(struct i2c_client *client)
#else
static int imx185_probe(struct i2c_client *client,
@@ -840,11 +838,11 @@ static int imx185_probe(struct i2c_client *client,
return 0;
}
#if defined(NV_I2C_DRIVER_STRUCT_REMOVE_RETURN_TYPE_INT) /* Linux 6.1 */
static int
#if LINUX_VERSION_CODE >= KERNEL_VERSION(6, 1, 0)
static void
imx185_remove(struct i2c_client *client)
#else
static void
static int
imx185_remove(struct i2c_client *client)
#endif
{
@@ -852,17 +850,17 @@ imx185_remove(struct i2c_client *client)
struct imx185 *priv;
if (!s_data)
#if defined(NV_I2C_DRIVER_STRUCT_REMOVE_RETURN_TYPE_INT) /* Linux 6.1 */
return -EINVAL;
#else
#if LINUX_VERSION_CODE >= KERNEL_VERSION(6, 1, 0)
return;
#else
return -EINVAL;
#endif
priv = (struct imx185 *)s_data->priv;
tegracam_v4l2subdev_unregister(priv->tc_dev);
tegracam_device_unregister(priv->tc_dev);
#if defined(NV_I2C_DRIVER_STRUCT_REMOVE_RETURN_TYPE_INT) /* Linux 6.1 */
#if LINUX_VERSION_CODE < KERNEL_VERSION(6, 1, 0)
return 0;
#endif
}

View File

@@ -1,12 +1,11 @@
// SPDX-License-Identifier: GPL-2.0-only
// SPDX-FileCopyrightText: Copyright (c) 2015-2024, NVIDIA CORPORATION & AFFILIATES. All rights reserved.
/*
* nv_imx219.c - imx219 sensor driver
*
* Copyright (c) 2015-2023, NVIDIA CORPORATION & AFFILIATES. All rights reserved.
*
*/
#include <nvidia/conftest.h>
#include <linux/slab.h>
#include <linux/uaccess.h>
#include <linux/gpio.h>
@@ -692,7 +691,7 @@ static const struct v4l2_subdev_internal_ops imx219_subdev_internal_ops = {
.open = imx219_open,
};
#if defined(NV_I2C_DRIVER_STRUCT_PROBE_WITHOUT_I2C_DEVICE_ID_ARG) /* Linux 6.3 */
#if KERNEL_VERSION(6, 3, 0) <= LINUX_VERSION_CODE
static int imx219_probe(struct i2c_client *client)
#else
static int imx219_probe(struct i2c_client *client,
@@ -746,7 +745,6 @@ static int imx219_probe(struct i2c_client *client,
err = tegracam_v4l2subdev_register(tc_dev, true);
if (err) {
tegracam_device_unregister(tc_dev);
dev_err(dev, "tegra camera subdev registration failed\n");
return err;
}
@@ -756,10 +754,10 @@ static int imx219_probe(struct i2c_client *client,
return 0;
}
#if defined(NV_I2C_DRIVER_STRUCT_REMOVE_RETURN_TYPE_INT) /* Linux 6.1 */
static int imx219_remove(struct i2c_client *client)
#else
#if KERNEL_VERSION(6, 1, 0) <= LINUX_VERSION_CODE
static void imx219_remove(struct i2c_client *client)
#else
static int imx219_remove(struct i2c_client *client)
#endif
{
struct camera_common_data *s_data = to_camera_common_data(&client->dev);
@@ -767,7 +765,7 @@ static void imx219_remove(struct i2c_client *client)
if (!s_data) {
dev_err(&client->dev, "camera common data is NULL\n");
#if defined(NV_I2C_DRIVER_STRUCT_REMOVE_RETURN_TYPE_INT) /* Linux 6.1 */
#if KERNEL_VERSION(6, 1, 0) > LINUX_VERSION_CODE
return -EINVAL;
#else
return;
@@ -778,7 +776,7 @@ static void imx219_remove(struct i2c_client *client)
tegracam_v4l2subdev_unregister(priv->tc_dev);
tegracam_device_unregister(priv->tc_dev);
#if defined(NV_I2C_DRIVER_STRUCT_REMOVE_RETURN_TYPE_INT) /* Linux 6.1 */
#if KERNEL_VERSION(6, 1, 0) > LINUX_VERSION_CODE
return 0;
#endif
}

View File

@@ -5,8 +5,6 @@
* Copyright (c) 2015-2023, NVIDIA CORPORATION. All rights reserved.
*/
#include <nvidia/conftest.h>
#include <linux/slab.h>
#include <linux/uaccess.h>
#include <linux/gpio.h>
@@ -1262,7 +1260,7 @@ static const struct v4l2_subdev_internal_ops imx274_subdev_internal_ops = {
.open = imx274_open,
};
#if defined(NV_I2C_DRIVER_STRUCT_PROBE_WITHOUT_I2C_DEVICE_ID_ARG) /* Linux 6.3 */
#if KERNEL_VERSION(6, 3, 0) <= LINUX_VERSION_CODE
static int imx274_probe(struct i2c_client *client)
#else
static int imx274_probe(struct i2c_client *client,
@@ -1335,20 +1333,20 @@ static int imx274_probe(struct i2c_client *client,
return 0;
}
#if defined(NV_I2C_DRIVER_STRUCT_REMOVE_RETURN_TYPE_INT) /* Linux 6.1 */
static int imx274_remove(struct i2c_client *client)
#else
#if LINUX_VERSION_CODE >= KERNEL_VERSION(6, 1, 0)
static void imx274_remove(struct i2c_client *client)
#else
static int imx274_remove(struct i2c_client *client)
#endif
{
struct camera_common_data *s_data = to_camera_common_data(&client->dev);
struct imx274 *priv;
if (!s_data)
#if defined(NV_I2C_DRIVER_STRUCT_REMOVE_RETURN_TYPE_INT) /* Linux 6.1 */
return -EINVAL;
#else
#if LINUX_VERSION_CODE >= KERNEL_VERSION(6, 1, 0)
return;
#else
return -EINVAL;
#endif
priv = (struct imx274 *)s_data->priv;
@@ -1360,7 +1358,7 @@ static void imx274_remove(struct i2c_client *client)
imx274_eeprom_device_release(priv);
mutex_destroy(&priv->streaming_lock);
#if defined(NV_I2C_DRIVER_STRUCT_REMOVE_RETURN_TYPE_INT) /* Linux 6.1 */
#if LINUX_VERSION_CODE < KERNEL_VERSION(6, 1, 0)
return 0;
#endif
}

View File

@@ -1,11 +1,5 @@
// SPDX-License-Identifier: GPL-2.0
// SPDX-FileCopyrightText: Copyright (c) 2017-2024 NVIDIA CORPORATION & AFFILIATES.
// All rights reserved.
//
// nv_imx318.c - imx318 sensor driver
//
#include <nvidia/conftest.h>
// Copyright (c) 2017-2023 NVIDIA CORPORATION & AFFILIATES. All rights reserved.
#include <linux/slab.h>
#include <linux/uaccess.h>
@@ -135,11 +129,6 @@ static int imx318_set_frame_rate_ex(struct tegracam_device *tc_dev,
u8 fl_arr[2];
int err = 0;
if (val < mode->control_properties.min_framerate)
val = mode->control_properties.min_framerate;
else if (val > mode->control_properties.max_framerate)
val = mode->control_properties.max_framerate;
if (mode->image_properties.line_length == 0 ||
val == 0) {
return -EINVAL;
@@ -706,7 +695,7 @@ static const struct v4l2_subdev_internal_ops imx318_subdev_internal_ops = {
.open = imx318_open,
};
#if defined(NV_I2C_DRIVER_STRUCT_PROBE_WITHOUT_I2C_DEVICE_ID_ARG) /* Linux 6.3 */
#if KERNEL_VERSION(6, 3, 0) <= LINUX_VERSION_CODE
static int imx318_probe(struct i2c_client *client)
#else
static int imx318_probe(struct i2c_client *client,
@@ -770,7 +759,7 @@ static int imx318_probe(struct i2c_client *client,
return 0;
}
#if defined(NV_I2C_DRIVER_STRUCT_REMOVE_RETURN_TYPE_INT) /* Linux 6.1 */
#if (KERNEL_VERSION(6, 1, 0) > LINUX_VERSION_CODE)
static int imx318_remove(struct i2c_client *client)
#else
static void imx318_remove(struct i2c_client *client)
@@ -780,7 +769,7 @@ static void imx318_remove(struct i2c_client *client)
struct imx318 *priv;
if (!s_data)
#if defined(NV_I2C_DRIVER_STRUCT_REMOVE_RETURN_TYPE_INT) /* Linux 6.1 */
#if (KERNEL_VERSION(6, 1, 0) > LINUX_VERSION_CODE)
return -EINVAL;
#else
return;
@@ -791,7 +780,7 @@ static void imx318_remove(struct i2c_client *client)
tegracam_device_unregister(priv->tc_dev);
imx318_eeprom_device_release(priv);
#if defined(NV_I2C_DRIVER_STRUCT_REMOVE_RETURN_TYPE_INT) /* Linux 6.1 */
#if (KERNEL_VERSION(6, 1, 0) > LINUX_VERSION_CODE)
return 0;
#endif
}

View File

File diff suppressed because it is too large Load Diff

View File

@@ -1,911 +0,0 @@
// SPDX-License-Identifier: GPL-2.0-only
// SPDX-FileCopyrightText: Copyright (c) 2018-2024, NVIDIA CORPORATION & AFFILIATES. All rights reserved.
#include <nvidia/conftest.h>
#include <linux/slab.h>
#include <linux/uaccess.h>
#include <linux/gpio.h>
#include <linux/module.h>
#include <linux/seq_file.h>
#include <linux/of.h>
#include <linux/of_device.h>
#include <linux/of_gpio.h>
#include <media/max9295.h>
#include <media/max9296.h>
#include <media/tegracam_core.h>
#include "imx390_mode_tbls.h"
#define IMX390_MIN_GAIN (0)
#define IMX390_MAX_GAIN (30)
#define IMX390_MAX_GAIN_REG ((IMX390_MAX_GAIN - IMX390_MIN_GAIN) * 10 / 3)
#define IMX390_DEFAULT_FRAME_LENGTH (1125)
#define IMX390_FRAME_LENGTH_ADDR_MSB 0x200A
#define IMX390_FRAME_LENGTH_ADDR_MID 0x2009
#define IMX390_FRAME_LENGTH_ADDR_LSB 0x2008
#define IMX390_COARSE_TIME_SHS1_ADDR_MSB 0x000E
#define IMX390_COARSE_TIME_SHS1_ADDR_MID 0x000D
#define IMX390_COARSE_TIME_SHS1_ADDR_LSB 0x000C
#define IMX390_COARSE_TIME_SHS2_ADDR_MSB 0x0012
#define IMX390_COARSE_TIME_SHS2_ADDR_MID 0x0011
#define IMX390_COARSE_TIME_SHS2_ADDR_LSB 0x0010
#define IMX390_GROUP_HOLD_ADDR 0x0008
#define IMX390_ANALOG_GAIN_SP1H_ADDR 0x0018
#define IMX390_ANALOG_GAIN_SP1L_ADDR 0x001A
static const struct of_device_id imx390_of_match[] = {
{ .compatible = "sony,imx390",},
{ },
};
MODULE_DEVICE_TABLE(of, imx390_of_match);
static const u32 ctrl_cid_list[] = {
TEGRA_CAMERA_CID_GAIN,
TEGRA_CAMERA_CID_EXPOSURE,
TEGRA_CAMERA_CID_EXPOSURE_SHORT,
TEGRA_CAMERA_CID_FRAME_RATE,
TEGRA_CAMERA_CID_HDR_EN,
};
struct imx390 {
struct i2c_client *i2c_client;
const struct i2c_device_id *id;
struct v4l2_subdev *subdev;
struct device *ser_dev;
struct device *dser_dev;
struct gmsl_link_ctx g_ctx;
u32 frame_length;
struct camera_common_data *s_data;
struct tegracam_device *tc_dev;
};
static const struct regmap_config sensor_regmap_config = {
.reg_bits = 16,
.val_bits = 8,
.cache_type = REGCACHE_RBTREE,
};
static inline void imx390_get_frame_length_regs(imx390_reg *regs,
u32 frame_length)
{
regs->addr = IMX390_FRAME_LENGTH_ADDR_MSB;
regs->val = (frame_length >> 16) & 0x01;
(regs + 1)->addr = IMX390_FRAME_LENGTH_ADDR_MID;
(regs + 1)->val = (frame_length >> 8) & 0xff;
(regs + 2)->addr = IMX390_FRAME_LENGTH_ADDR_LSB;
(regs + 2)->val = (frame_length) & 0xff;
}
static inline void imx390_get_coarse_time_regs_shs1(imx390_reg *regs,
u32 coarse_time)
{
regs->addr = IMX390_COARSE_TIME_SHS1_ADDR_MSB;
regs->val = (coarse_time >> 16) & 0x0f;
(regs + 1)->addr = IMX390_COARSE_TIME_SHS1_ADDR_MID;
(regs + 1)->val = (coarse_time >> 8) & 0xff;
(regs + 2)->addr = IMX390_COARSE_TIME_SHS1_ADDR_LSB;
(regs + 2)->val = (coarse_time) & 0xff;
}
static inline void imx390_get_coarse_time_regs_shs2(imx390_reg *regs,
u32 coarse_time)
{
regs->addr = IMX390_COARSE_TIME_SHS2_ADDR_MSB;
regs->val = (coarse_time >> 16) & 0x0f;
(regs + 1)->addr = IMX390_COARSE_TIME_SHS2_ADDR_MID;
(regs + 1)->val = (coarse_time >> 8) & 0xff;
(regs + 2)->addr = IMX390_COARSE_TIME_SHS2_ADDR_LSB;
(regs + 2)->val = (coarse_time) & 0xff;
}
static inline void imx390_get_gain_reg(imx390_reg *regs,
u16 gain)
{
regs->addr = IMX390_ANALOG_GAIN_SP1H_ADDR;
regs->val = (gain) & 0xff;
(regs + 1)->addr = IMX390_ANALOG_GAIN_SP1H_ADDR + 1;
(regs + 1)->val = (gain >> 8) & 0xff;
(regs + 2)->addr = IMX390_ANALOG_GAIN_SP1L_ADDR;
(regs + 2)->val = (gain) & 0xff;
(regs + 3)->addr = IMX390_ANALOG_GAIN_SP1L_ADDR + 1;
(regs + 3)->val = (gain >> 8) & 0xff;
}
static int test_mode;
module_param(test_mode, int, 0644);
static inline int imx390_read_reg(struct camera_common_data *s_data,
u16 addr, u8 *val)
{
int err = 0;
u32 reg_val = 0;
err = regmap_read(s_data->regmap, addr, &reg_val);
*val = reg_val & 0xFF;
return err;
}
static int imx390_write_reg(struct camera_common_data *s_data,
u16 addr, u8 val)
{
int err;
struct device *dev = s_data->dev;
err = regmap_write(s_data->regmap, addr, val);
if (err)
dev_err(dev, "%s:i2c write failed, 0x%x = %x\n",
__func__, addr, val);
return err;
}
static int imx390_write_table(struct imx390 *priv,
const imx390_reg table[])
{
struct camera_common_data *s_data = priv->s_data;
return regmap_util_write_table_8(s_data->regmap,
table,
NULL, 0,
IMX390_TABLE_WAIT_MS,
IMX390_TABLE_END);
}
static struct mutex serdes_lock__;
static int imx390_gmsl_serdes_setup(struct imx390 *priv)
{
int err = 0;
int des_err = 0;
struct device *dev;
if (!priv || !priv->ser_dev || !priv->dser_dev || !priv->i2c_client)
return -EINVAL;
dev = &priv->i2c_client->dev;
mutex_lock(&serdes_lock__);
/* For now no separate power on required for serializer device */
max9296_power_on(priv->dser_dev);
/* setup serdes addressing and control pipeline */
err = max9296_setup_link(priv->dser_dev, &priv->i2c_client->dev);
if (err) {
dev_err(dev, "gmsl deserializer link config failed\n");
goto error;
}
err = max9295_setup_control(priv->ser_dev);
/* proceed even if ser setup failed, to setup deser correctly */
if (err)
dev_err(dev, "gmsl serializer setup failed\n");
des_err = max9296_setup_control(priv->dser_dev, &priv->i2c_client->dev);
if (des_err) {
dev_err(dev, "gmsl deserializer setup failed\n");
/* overwrite err only if deser setup also failed */
err = des_err;
}
error:
mutex_unlock(&serdes_lock__);
return err;
}
static void imx390_gmsl_serdes_reset(struct imx390 *priv)
{
mutex_lock(&serdes_lock__);
/* reset serdes addressing and control pipeline */
max9295_reset_control(priv->ser_dev);
max9296_reset_control(priv->dser_dev, &priv->i2c_client->dev);
max9296_power_off(priv->dser_dev);
mutex_unlock(&serdes_lock__);
}
static int imx390_power_on(struct camera_common_data *s_data)
{
int err = 0;
struct camera_common_power_rail *pw = s_data->power;
struct camera_common_pdata *pdata = s_data->pdata;
struct device *dev = s_data->dev;
dev_dbg(dev, "%s: power on\n", __func__);
if (pdata && pdata->power_on) {
err = pdata->power_on(pw);
if (err)
dev_err(dev, "%s failed.\n", __func__);
else
pw->state = SWITCH_ON;
return err;
}
pw->state = SWITCH_ON;
return 0;
}
static int imx390_power_off(struct camera_common_data *s_data)
{
int err = 0;
struct camera_common_power_rail *pw = s_data->power;
struct camera_common_pdata *pdata = s_data->pdata;
struct device *dev = s_data->dev;
dev_dbg(dev, "%s:\n", __func__);
if (pdata && pdata->power_off) {
err = pdata->power_off(pw);
if (!err)
goto power_off_done;
else
dev_err(dev, "%s failed.\n", __func__);
return err;
}
power_off_done:
pw->state = SWITCH_OFF;
return 0;
}
static int imx390_power_get(struct tegracam_device *tc_dev)
{
struct device *dev = tc_dev->dev;
struct camera_common_data *s_data = tc_dev->s_data;
struct camera_common_power_rail *pw = s_data->power;
struct camera_common_pdata *pdata = s_data->pdata;
const char *mclk_name;
const char *parentclk_name;
struct clk *parent;
int err = 0;
mclk_name = pdata->mclk_name ?
pdata->mclk_name : "cam_mclk1";
pw->mclk = devm_clk_get(dev, mclk_name);
if (IS_ERR(pw->mclk)) {
dev_err(dev, "unable to get clock %s\n", mclk_name);
return PTR_ERR(pw->mclk);
}
parentclk_name = pdata->parentclk_name;
if (parentclk_name) {
parent = devm_clk_get(dev, parentclk_name);
if (IS_ERR(parent)) {
dev_err(dev, "unable to get parent clcok %s",
parentclk_name);
} else {
err = clk_set_parent(pw->mclk, parent);
if (err < 0)
dev_dbg(dev,
"%s failed to set parent clock %d\n",
__func__, err);
}
}
pw->state = SWITCH_OFF;
return err;
}
static int imx390_power_put(struct tegracam_device *tc_dev)
{
struct camera_common_data *s_data = tc_dev->s_data;
struct camera_common_power_rail *pw = s_data->power;
if (unlikely(!pw))
return -EFAULT;
return 0;
}
static int imx390_set_group_hold(struct tegracam_device *tc_dev, bool val)
{
struct camera_common_data *s_data = tc_dev->s_data;
struct device *dev = tc_dev->dev;
int err;
err = imx390_write_reg(s_data,
IMX390_GROUP_HOLD_ADDR, val);
if (err) {
dev_dbg(dev,
"%s: Group hold control error\n", __func__);
return err;
}
return 0;
}
static int imx390_set_gain(struct tegracam_device *tc_dev, s64 val)
{
struct camera_common_data *s_data = tc_dev->s_data;
struct device *dev = tc_dev->dev;
const struct sensor_mode_properties *mode =
&s_data->sensor_props.sensor_modes[s_data->mode_prop_idx];
imx390_reg reg_list[4];
int err, i;
u16 gain;
gain = (u16)(val / mode->control_properties.step_gain_val);
dev_dbg(dev, "%s: db: %d\n", __func__, gain);
if (gain > IMX390_MAX_GAIN_REG)
gain = IMX390_MAX_GAIN_REG;
imx390_get_gain_reg(reg_list, gain);
for (i = 0; i < 4; i++) {
err = imx390_write_reg(s_data, reg_list[i].addr,
reg_list[i].val);
if (err)
goto fail;
}
return 0;
fail:
dev_info(dev, "%s: GAIN control error\n", __func__);
return err;
}
static int imx390_set_frame_rate(struct tegracam_device *tc_dev, s64 val)
{
struct imx390 *priv = (struct imx390 *)tegracam_get_privdata(tc_dev);
/* fixed 30fps */
priv->frame_length = IMX390_DEFAULT_FRAME_LENGTH;
return 0;
}
static int imx390_set_exposure(struct tegracam_device *tc_dev, s64 val)
{
struct imx390 *priv = (struct imx390 *)tegracam_get_privdata(tc_dev);
struct camera_common_data *s_data = tc_dev->s_data;
const struct sensor_mode_properties *mode =
&s_data->sensor_props.sensor_modes[s_data->mode];
imx390_reg reg_list[3];
int err;
u32 coarse_time;
u32 shs1;
int i = 0;
if (priv->frame_length == 0)
priv->frame_length = IMX390_DEFAULT_FRAME_LENGTH;
/* coarse time in lines */
coarse_time = (u32) (val * s_data->frmfmt[s_data->mode].framerates[0] *
priv->frame_length / mode->control_properties.exposure_factor);
shs1 = priv->frame_length - coarse_time;
/* 0 and 1 are prohibited */
if (shs1 < 2)
shs1 = 2;
imx390_get_coarse_time_regs_shs1(reg_list, shs1);
for (i = 0; i < 3; i++) {
err = imx390_write_reg(priv->s_data, reg_list[i].addr,
reg_list[i].val);
if (err)
goto fail;
}
imx390_get_coarse_time_regs_shs2(reg_list, shs1);
for (i = 0; i < 3; i++) {
err = imx390_write_reg(priv->s_data, reg_list[i].addr,
reg_list[i].val);
if (err)
goto fail;
}
return 0;
fail:
dev_dbg(&priv->i2c_client->dev,
"%s: set coarse time error\n", __func__);
return err;
}
static struct tegracam_ctrl_ops imx390_ctrl_ops = {
.numctrls = ARRAY_SIZE(ctrl_cid_list),
.ctrl_cid_list = ctrl_cid_list,
.set_gain = imx390_set_gain,
.set_exposure = imx390_set_exposure,
.set_exposure_short = imx390_set_exposure,
.set_frame_rate = imx390_set_frame_rate,
.set_group_hold = imx390_set_group_hold,
};
static struct camera_common_pdata
*imx390_parse_dt(struct tegracam_device *tc_dev)
{
struct device *dev = tc_dev->dev;
struct device_node *node = dev->of_node;
struct camera_common_pdata *board_priv_pdata;
const struct of_device_id *match;
int err;
if (!node)
return NULL;
match = of_match_device(imx390_of_match, dev);
if (!match) {
dev_err(dev, "Failed to find matching dt id\n");
return NULL;
}
board_priv_pdata = devm_kzalloc(dev,
sizeof(*board_priv_pdata), GFP_KERNEL);
err = of_property_read_string(node, "mclk",
&board_priv_pdata->mclk_name);
if (err)
dev_err(dev, "mclk not in DT\n");
return board_priv_pdata;
}
static int imx390_set_mode(struct tegracam_device *tc_dev)
{
struct imx390 *priv = (struct imx390 *)tegracam_get_privdata(tc_dev);
struct camera_common_data *s_data = tc_dev->s_data;
struct device *dev = tc_dev->dev;
const struct of_device_id *match;
match = of_match_device(imx390_of_match, dev);
if (!match) {
dev_err(dev, "Failed to find matching dt id\n");
return -EINVAL;
}
if (s_data->mode_prop_idx < 0)
return -EINVAL;
return imx390_write_table(priv, mode_table[s_data->mode_prop_idx]);
}
static int imx390_start_streaming(struct tegracam_device *tc_dev)
{
struct imx390 *priv = (struct imx390 *)tegracam_get_privdata(tc_dev);
struct device *dev = tc_dev->dev;
int err;
/* enable serdes streaming */
err = max9295_setup_streaming(priv->ser_dev);
if (err)
goto exit;
err = max9296_setup_streaming(priv->dser_dev, dev);
if (err)
goto exit;
err = max9296_start_streaming(priv->dser_dev, dev);
if (err)
goto exit;
err = imx390_write_table(priv,
mode_table[IMX390_MODE_START_STREAM]);
if (err)
return err;
msleep(20);
return 0;
exit:
dev_err(dev, "%s: error setting stream\n", __func__);
return err;
}
static int imx390_stop_streaming(struct tegracam_device *tc_dev)
{
struct device *dev = tc_dev->dev;
struct imx390 *priv = (struct imx390 *)tegracam_get_privdata(tc_dev);
/* disable serdes streaming */
max9296_stop_streaming(priv->dser_dev, dev);
return imx390_write_table(priv, mode_table[IMX390_MODE_STOP_STREAM]);
}
static struct camera_common_sensor_ops imx390_common_ops = {
.numfrmfmts = ARRAY_SIZE(imx390_frmfmt),
.frmfmt_table = imx390_frmfmt,
.power_on = imx390_power_on,
.power_off = imx390_power_off,
.write_reg = imx390_write_reg,
.read_reg = imx390_read_reg,
.parse_dt = imx390_parse_dt,
.power_get = imx390_power_get,
.power_put = imx390_power_put,
.set_mode = imx390_set_mode,
.start_streaming = imx390_start_streaming,
.stop_streaming = imx390_stop_streaming,
};
static int imx390_open(struct v4l2_subdev *sd, struct v4l2_subdev_fh *fh)
{
struct i2c_client *client = v4l2_get_subdevdata(sd);
dev_dbg(&client->dev, "%s:\n", __func__);
return 0;
}
static const struct v4l2_subdev_internal_ops imx390_subdev_internal_ops = {
.open = imx390_open,
};
static int imx390_board_setup(struct imx390 *priv)
{
struct tegracam_device *tc_dev = priv->tc_dev;
struct device *dev = tc_dev->dev;
struct device_node *node = dev->of_node;
struct device_node *ser_node;
struct i2c_client *ser_i2c = NULL;
struct device_node *dser_node;
struct i2c_client *dser_i2c = NULL;
struct device_node *gmsl;
int value = 0xFFFF;
const char *str_value;
const char *str_value1[2];
int i;
int err;
err = of_property_read_u32(node, "reg", &priv->g_ctx.sdev_reg);
if (err < 0) {
dev_err(dev, "reg not found\n");
goto error;
}
err = of_property_read_u32(node, "def-addr",
&priv->g_ctx.sdev_def);
if (err < 0) {
dev_err(dev, "def-addr not found\n");
goto error;
}
ser_node = of_parse_phandle(node, "nvidia,gmsl-ser-device", 0);
if (ser_node == NULL) {
dev_err(dev,
"missing %s handle\n",
"nvidia,gmsl-ser-device");
err = -EINVAL;
goto error;
}
err = of_property_read_u32(ser_node, "reg", &priv->g_ctx.ser_reg);
if (err < 0) {
dev_err(dev, "serializer reg not found\n");
goto error;
}
ser_i2c = of_find_i2c_device_by_node(ser_node);
of_node_put(ser_node);
if (ser_i2c == NULL) {
err = -EPROBE_DEFER;
goto error;
}
if (ser_i2c->dev.driver == NULL) {
dev_err(dev, "missing serializer driver\n");
err = -EINVAL;
goto error;
}
priv->ser_dev = &ser_i2c->dev;
dser_node = of_parse_phandle(node, "nvidia,gmsl-dser-device", 0);
if (dser_node == NULL) {
dev_err(dev,
"missing %s handle\n",
"nvidia,gmsl-dser-device");
err = -EINVAL;
goto error;
}
dser_i2c = of_find_i2c_device_by_node(dser_node);
of_node_put(dser_node);
if (dser_i2c == NULL) {
err = -EPROBE_DEFER;
goto error;
}
if (dser_i2c->dev.driver == NULL) {
dev_err(dev, "missing deserializer driver\n");
err = -EINVAL;
goto error;
}
priv->dser_dev = &dser_i2c->dev;
/* populate g_ctx from DT */
gmsl = of_get_child_by_name(node, "gmsl-link");
if (gmsl == NULL) {
dev_err(dev, "missing gmsl-link device node\n");
err = -EINVAL;
goto error;
}
err = of_property_read_string(gmsl, "dst-csi-port", &str_value);
if (err < 0) {
dev_err(dev, "No dst-csi-port found\n");
goto error;
}
priv->g_ctx.dst_csi_port =
(!strcmp(str_value, "a")) ? GMSL_CSI_PORT_A : GMSL_CSI_PORT_B;
err = of_property_read_string(gmsl, "src-csi-port", &str_value);
if (err < 0) {
dev_err(dev, "No src-csi-port found\n");
goto error;
}
priv->g_ctx.src_csi_port =
(!strcmp(str_value, "a")) ? GMSL_CSI_PORT_A : GMSL_CSI_PORT_B;
err = of_property_read_string(gmsl, "csi-mode", &str_value);
if (err < 0) {
dev_err(dev, "No csi-mode found\n");
goto error;
}
if (!strcmp(str_value, "1x4")) {
priv->g_ctx.csi_mode = GMSL_CSI_1X4_MODE;
} else if (!strcmp(str_value, "2x4")) {
priv->g_ctx.csi_mode = GMSL_CSI_2X4_MODE;
} else if (!strcmp(str_value, "4x2")) {
priv->g_ctx.csi_mode = GMSL_CSI_4X2_MODE;
} else if (!strcmp(str_value, "2x2")) {
priv->g_ctx.csi_mode = GMSL_CSI_2X2_MODE;
} else {
dev_err(dev, "invalid csi mode\n");
err = -EINVAL;
goto error;
}
err = of_property_read_string(gmsl, "serdes-csi-link", &str_value);
if (err < 0) {
dev_err(dev, "No serdes-csi-link found\n");
goto error;
}
priv->g_ctx.serdes_csi_link =
(!strcmp(str_value, "a")) ?
GMSL_SERDES_CSI_LINK_A : GMSL_SERDES_CSI_LINK_B;
err = of_property_read_u32(gmsl, "st-vc", &value);
if (err < 0) {
dev_err(dev, "No st-vc info\n");
goto error;
}
priv->g_ctx.st_vc = value;
err = of_property_read_u32(gmsl, "vc-id", &value);
if (err < 0) {
dev_err(dev, "No vc-id info\n");
goto error;
}
priv->g_ctx.dst_vc = value;
err = of_property_read_u32(gmsl, "num-lanes", &value);
if (err < 0) {
dev_err(dev, "No num-lanes info\n");
goto error;
}
priv->g_ctx.num_csi_lanes = value;
priv->g_ctx.num_streams =
of_property_count_strings(gmsl, "streams");
if (priv->g_ctx.num_streams <= 0) {
dev_err(dev, "No streams found\n");
err = -EINVAL;
goto error;
}
for (i = 0; i < priv->g_ctx.num_streams; i++) {
err = of_property_read_string_index(gmsl, "streams", i,
&str_value1[i]);
if (err < 0) {
dev_err(dev, "Failed to get streams index\n");
goto error;
}
if (!str_value1[i]) {
dev_err(dev, "invalid stream info\n");
err = -EINVAL;
goto error;
}
if (!strcmp(str_value1[i], "raw12")) {
priv->g_ctx.streams[i].st_data_type =
GMSL_CSI_DT_RAW_12;
} else if (!strcmp(str_value1[i], "embed")) {
priv->g_ctx.streams[i].st_data_type =
GMSL_CSI_DT_EMBED;
} else if (!strcmp(str_value1[i], "ued-u1")) {
priv->g_ctx.streams[i].st_data_type =
GMSL_CSI_DT_UED_U1;
} else {
dev_err(dev, "invalid stream data type\n");
err = -EINVAL;
goto error;
}
}
priv->g_ctx.s_dev = dev;
return 0;
error:
return err;
}
#if defined(NV_I2C_DRIVER_STRUCT_PROBE_WITHOUT_I2C_DEVICE_ID_ARG) /* Linux 6.3 */
static int imx390_probe(struct i2c_client *client)
#else
static int imx390_probe(struct i2c_client *client,
const struct i2c_device_id *id)
#endif
{
struct device *dev = &client->dev;
struct device_node *node = dev->of_node;
struct tegracam_device *tc_dev;
struct imx390 *priv;
int err;
dev_info(dev, "probing v4l2 sensor.\n");
if (!IS_ENABLED(CONFIG_OF) || !node)
return -EINVAL;
priv = devm_kzalloc(dev, sizeof(struct imx390), GFP_KERNEL);
if (!priv)
return -ENOMEM;
tc_dev = devm_kzalloc(dev,
sizeof(struct tegracam_device), GFP_KERNEL);
if (!tc_dev)
return -ENOMEM;
priv->i2c_client = tc_dev->client = client;
tc_dev->dev = dev;
strscpy(tc_dev->name, "imx390", sizeof(tc_dev->name));
tc_dev->dev_regmap_config = &sensor_regmap_config;
tc_dev->sensor_ops = &imx390_common_ops;
tc_dev->v4l2sd_internal_ops = &imx390_subdev_internal_ops;
tc_dev->tcctrl_ops = &imx390_ctrl_ops;
err = tegracam_device_register(tc_dev);
if (err) {
dev_err(dev, "tegra camera driver registration failed\n");
return err;
}
priv->tc_dev = tc_dev;
priv->s_data = tc_dev->s_data;
priv->subdev = &tc_dev->s_data->subdev;
tegracam_set_privdata(tc_dev, (void *)priv);
err = imx390_board_setup(priv);
if (err) {
tegracam_device_unregister(tc_dev);
dev_err(dev, "board setup failed\n");
return err;
}
mutex_init(&serdes_lock__);
/* Pair sensor to serializer dev */
err = max9295_sdev_pair(priv->ser_dev, &priv->g_ctx);
if (err) {
dev_err(&client->dev, "gmsl ser pairing failed\n");
return err;
}
/* Register sensor to deserializer dev */
err = max9296_sdev_register(priv->dser_dev, &priv->g_ctx);
if (err) {
dev_err(&client->dev, "gmsl deserializer register failed\n");
return err;
}
/*
* gmsl serdes setup
*
* Sensor power on/off should be the right place for serdes
* setup/reset. But the problem is, the total required delay
* in serdes setup/reset exceeds the frame wait timeout, looks to
* be related to multiple channel open and close sequence
* issue (#BUG 200477330).
* Once this bug is fixed, these may be moved to power on/off.
* The delays in serdes is as per guidelines and can't be reduced,
* so it is placed in probe/remove, though for that, deserializer
* would be powered on always post boot, until 1.2v is supplied
* to deserializer from CVB.
*/
err = imx390_gmsl_serdes_setup(priv);
if (err) {
dev_err(&client->dev,
"%s gmsl serdes setup failed\n", __func__);
return err;
}
err = tegracam_v4l2subdev_register(tc_dev, true);
if (err) {
dev_err(dev, "tegra camera subdev registration failed\n");
return err;
}
dev_info(&client->dev, "Detected IMX390 sensor\n");
return 0;
}
#if defined(NV_I2C_DRIVER_STRUCT_REMOVE_RETURN_TYPE_INT) /* Linux 6.1 */
static int imx390_remove(struct i2c_client *client)
#else
static void imx390_remove(struct i2c_client *client)
#endif
{
struct camera_common_data *s_data = to_camera_common_data(&client->dev);
struct imx390 *priv;
if (!s_data)
#if defined(NV_I2C_DRIVER_STRUCT_REMOVE_RETURN_TYPE_INT) /* Linux 6.1 */
return -EINVAL;
#else
return;
#endif
priv = (struct imx390 *)s_data->priv;
imx390_gmsl_serdes_reset(priv);
mutex_destroy(&serdes_lock__);
tegracam_v4l2subdev_unregister(priv->tc_dev);
tegracam_device_unregister(priv->tc_dev);
#if defined(NV_I2C_DRIVER_STRUCT_REMOVE_RETURN_TYPE_INT) /* Linux 6.1 */
return 0;
#endif
}
static const struct i2c_device_id imx390_id[] = {
{ "imx390", 0 },
{ }
};
MODULE_DEVICE_TABLE(i2c, imx390_id);
static struct i2c_driver imx390_i2c_driver = {
.driver = {
.name = "imx390",
.owner = THIS_MODULE,
.of_match_table = of_match_ptr(imx390_of_match),
},
.probe = imx390_probe,
.remove = imx390_remove,
.id_table = imx390_id,
};
module_i2c_driver(imx390_i2c_driver);
MODULE_DESCRIPTION("Media Controller driver for Sony IMX390");
MODULE_AUTHOR("NVIDIA Corporation");
MODULE_AUTHOR("Sudhir Vyas <svyas@nvidia.com");
MODULE_LICENSE("GPL v2");

View File

@@ -1,15 +1,13 @@
// SPDX-License-Identifier: GPL-2.0-only
// SPDX-FileCopyrightText: Copyright (c) 2021-2024, NVIDIA CORPORATION & AFFILIATES. All rights reserved.
/*
* Copyright (c) 2020, RidgeRun. All rights reserved.
* Copyright (c) 2021-2023, NVIDIA CORPORATION & AFFILIATES. All rights reserved.
*
* Contact us: support@ridgerun.com
*
* nv_imx477.c - imx477 sensor driver
*/
#include <nvidia/conftest.h>
#include <linux/slab.h>
#include <linux/uaccess.h>
#include <linux/gpio.h>
@@ -26,8 +24,6 @@
#include "../platform/tegra/camera/camera_gpio.h"
#include "imx477_mode_tbls.h"
#define IMX477_SENSOR_INTERNAL_CLK_FREQ 840000000
static const struct of_device_id imx477_of_match[] = {
{.compatible = "ridgerun,imx477",},
{},
@@ -230,7 +226,7 @@ static int imx477_set_frame_rate(struct tegracam_device *tc_dev, s64 val)
if (val == 0 || mode->image_properties.line_length == 0)
return -EINVAL;
frame_length = (u32) (IMX477_SENSOR_INTERNAL_CLK_FREQ *
frame_length = (u32) (mode->signal_properties.pixel_clock.val *
(u64) mode->control_properties.framerate_factor /
mode->image_properties.line_length / val);
@@ -281,12 +277,12 @@ static int imx477_set_exposure(struct tegracam_device *tc_dev, s64 val)
fine_integ_time_factor = priv->fine_integ_time *
mode->control_properties.exposure_factor /
IMX477_SENSOR_INTERNAL_CLK_FREQ;
mode->signal_properties.pixel_clock.val;
dev_dbg(dev, "%s: Setting exposure control to: %lld\n", __func__, val);
coarse_time = (val - fine_integ_time_factor)
* IMX477_SENSOR_INTERNAL_CLK_FREQ
* mode->signal_properties.pixel_clock.val
/ mode->control_properties.exposure_factor
/ mode->image_properties.line_length;
@@ -724,7 +720,7 @@ static const struct v4l2_subdev_internal_ops imx477_subdev_internal_ops = {
.open = imx477_open,
};
#if defined(NV_I2C_DRIVER_STRUCT_PROBE_WITHOUT_I2C_DEVICE_ID_ARG) /* Linux 6.3 */
#if KERNEL_VERSION(6, 3, 0) <= LINUX_VERSION_CODE
static int imx477_probe(struct i2c_client *client)
#else
static int imx477_probe(struct i2c_client *client,
@@ -775,7 +771,6 @@ static int imx477_probe(struct i2c_client *client,
err = tegracam_v4l2subdev_register(tc_dev, true);
if (err) {
tegracam_device_unregister(tc_dev);
dev_err(dev, "tegra camera subdev registration failed\n");
return err;
}
@@ -785,10 +780,10 @@ static int imx477_probe(struct i2c_client *client,
return 0;
}
#if defined(NV_I2C_DRIVER_STRUCT_REMOVE_RETURN_TYPE_INT) /* Linux 6.1 */
static int imx477_remove(struct i2c_client *client)
#else
#if LINUX_VERSION_CODE >= KERNEL_VERSION(6, 1, 0)
static void imx477_remove(struct i2c_client *client)
#else
static int imx477_remove(struct i2c_client *client)
#endif
{
struct camera_common_data *s_data = to_camera_common_data(&client->dev);
@@ -796,7 +791,7 @@ static void imx477_remove(struct i2c_client *client)
if (!s_data) {
dev_err(&client->dev, "camera common data is NULL\n");
#if defined(NV_I2C_DRIVER_STRUCT_REMOVE_RETURN_TYPE_INT) /* Linux 6.1 */
#if KERNEL_VERSION(6, 1, 0) > LINUX_VERSION_CODE
return -EINVAL;
#else
return;
@@ -806,7 +801,7 @@ static void imx477_remove(struct i2c_client *client)
tegracam_v4l2subdev_unregister(priv->tc_dev);
tegracam_device_unregister(priv->tc_dev);
#if defined(NV_I2C_DRIVER_STRUCT_REMOVE_RETURN_TYPE_INT) /* Linux 6.1 */
#if LINUX_VERSION_CODE < KERNEL_VERSION(6, 1, 0)
return 0;
#endif
}

View File

@@ -6,8 +6,6 @@
*
*/
#include <nvidia/conftest.h>
#include <linux/slab.h>
#include <linux/uaccess.h>
#include <linux/gpio.h>
@@ -1148,7 +1146,7 @@ static const struct v4l2_subdev_internal_ops ov5693_subdev_internal_ops = {
.open = ov5693_open,
};
#if defined(NV_I2C_DRIVER_STRUCT_PROBE_WITHOUT_I2C_DEVICE_ID_ARG) /* Linux 6.3 */
#if KERNEL_VERSION(6, 3, 0) <= LINUX_VERSION_CODE
static int ov5693_probe(struct i2c_client *client)
#else
static int ov5693_probe(struct i2c_client *client,
@@ -1238,7 +1236,7 @@ fail:
return err;
}
#if defined(NV_I2C_DRIVER_STRUCT_REMOVE_RETURN_TYPE_INT) /* Linux 6.1 */
#if (KERNEL_VERSION(6, 1, 0) > LINUX_VERSION_CODE)
static int
ov5693_remove(struct i2c_client *client)
#else
@@ -1250,7 +1248,7 @@ ov5693_remove(struct i2c_client *client)
struct camera_common_data *s_data = to_camera_common_data(&client->dev);
if (!s_data)
#if defined(NV_I2C_DRIVER_STRUCT_REMOVE_RETURN_TYPE_INT) /* Linux 6.1 */
#if (KERNEL_VERSION(6, 1, 0) > LINUX_VERSION_CODE)
return -EINVAL;
#else
return;
@@ -1266,7 +1264,7 @@ ov5693_remove(struct i2c_client *client)
ov5693_eeprom_device_release(priv);
mutex_destroy(&priv->streaming_lock);
#if defined(NV_I2C_DRIVER_STRUCT_REMOVE_RETURN_TYPE_INT) /* Linux 6.1 */
#if (KERNEL_VERSION(6, 1, 0) > LINUX_VERSION_CODE)
return 0;
#endif
}

View File

@@ -5,8 +5,6 @@
* Copyright (c) 2016-2023, NVIDIA CORPORATION & AFFILIATES. All rights reserved.
*/
#include <nvidia/conftest.h>
#include <linux/seq_file.h>
#include <linux/debugfs.h>
#include <linux/i2c.h>
@@ -260,7 +258,7 @@ static struct regmap_config pca9570_regmap_config = {
.cache_type = REGCACHE_RBTREE,
};
#if defined(NV_I2C_DRIVER_STRUCT_PROBE_WITHOUT_I2C_DEVICE_ID_ARG) /* Linux 6.3 */
#if KERNEL_VERSION(6, 3, 0) <= LINUX_VERSION_CODE
static int pca9570_probe(struct i2c_client *client)
#else
static int pca9570_probe(struct i2c_client *client,
@@ -310,7 +308,7 @@ static int pca9570_probe(struct i2c_client *client,
return err;
}
#if defined(NV_I2C_DRIVER_STRUCT_REMOVE_RETURN_TYPE_INT) /* Linux 6.1 */
#if KERNEL_VERSION(6, 1, 0) > LINUX_VERSION_CODE
static int pca9570_remove(struct i2c_client *client)
#else
static void pca9570_remove(struct i2c_client *client)
@@ -321,7 +319,7 @@ static void pca9570_remove(struct i2c_client *client)
client = NULL;
}
#if defined(NV_I2C_DRIVER_STRUCT_REMOVE_RETURN_TYPE_INT) /* Linux 6.1 */
#if KERNEL_VERSION(6, 1, 0) > LINUX_VERSION_CODE
return 0;
#endif
}

View File

@@ -1,11 +1,9 @@
// SPDX-License-Identifier: GPL-2.0-only
// SPDX-FileCopyrightText: Copyright (c) 2023-2024 NVIDIA CORPORATION & AFFILIATES. All rights reserved.
/* SPDX-License-Identifier: GPL-2.0 */
/* Copyright (c) 2023, NVIDIA CORPORATION & AFFILIATES. All Rights Reserved. */
/*
* virtual_i2c_mux.c - virtual i2c mux driver for P3762 & P3783 GMSL boards.
*/
#include <nvidia/conftest.h>
#include <linux/i2c.h>
#include <linux/i2c-mux.h>
#include <linux/module.h>
@@ -49,7 +47,7 @@ static int virtual_i2c_mux_deselect(struct i2c_mux_core *muxc, u32 chan)
return ret;
}
#if defined(NV_I2C_DRIVER_STRUCT_PROBE_WITHOUT_I2C_DEVICE_ID_ARG) /* Linux 6.3 */
#if KERNEL_VERSION(6, 3, 0) <= LINUX_VERSION_CODE
static int virtual_i2c_mux_probe(struct i2c_client *client)
#else
static int virtual_i2c_mux_probe(struct i2c_client *client,
@@ -87,11 +85,7 @@ static int virtual_i2c_mux_probe(struct i2c_client *client,
for (chan = 0; chan < children; chan++) {
pr_info("%s: chan = %d\n",__func__, chan);
#if defined(NV_I2C_MUX_ADD_ADAPTER_HAS_NO_CLASS_ARG)
ret = i2c_mux_add_adapter(muxc, 0, chan);
#else
ret = i2c_mux_add_adapter(muxc, 0, chan, 0);
#endif
if (ret)
goto err_children;
}
@@ -110,7 +104,7 @@ err_parent:
return ret;
}
#if defined(NV_I2C_DRIVER_STRUCT_REMOVE_RETURN_TYPE_INT) /* Linux 6.1 */
#if (KERNEL_VERSION(6, 1, 0) > LINUX_VERSION_CODE)
static int virtual_i2c_mux_remove(struct i2c_client *client)
#else
static void virtual_i2c_mux_remove(struct i2c_client *client)
@@ -120,7 +114,7 @@ static void virtual_i2c_mux_remove(struct i2c_client *client)
i2c_mux_del_adapters(muxc);
i2c_put_adapter(muxc->parent);
#if defined(NV_I2C_DRIVER_STRUCT_REMOVE_RETURN_TYPE_INT) /* Linux 6.1 */
#if (KERNEL_VERSION(6, 1, 0) > LINUX_VERSION_CODE)
return 0;
#endif
}

View File

@@ -1,10 +1,8 @@
# SPDX-License-Identifier: GPL-2.0-only
# Copyright (c) 2022-2024, NVIDIA CORPORATION & AFFILIATES. All rights reserved.
# Copyright (c) 2022-2023, NVIDIA CORPORATION & AFFILIATES. All rights reserved.
ifdef CONFIG_MEDIA_SUPPORT
obj-m += cdi/
obj-m += tpg/
endif
obj-m += isc/
obj-m += camera/
obj-m += tpg/
obj-m += cam_fsync/

View File

@@ -1,7 +1,6 @@
# SPDX-License-Identifier: GPL-2.0-only
# Copyright (c) 2022-2024, NVIDIA CORPORATION. All rights reserved.
# Copyright (c) 2022-2023, NVIDIA CORPORATION. All rights reserved.
ifdef CONFIG_MEDIA_SUPPORT
ifeq ($(findstring ack_src,$(NV_BUILD_KERNEL_OPTIONS)),)
LINUXINCLUDE += -I$(srctree.nvidia-oot)/drivers/video/tegra/camera
LINUXINCLUDE += -I$(srctree.nvidia-oot)/drivers/media/platform/tegra
@@ -33,4 +32,3 @@ tegra-camera-objs += fusa-capture/capture-isp.o
obj-m += tegra-camera.o
obj-m += tests/
endif
endif

View File

@@ -1,18 +1,8 @@
// SPDX-License-Identifier: GPL-2.0 only
/* SPDX-FileCopyrightText: Copyright (c) 2015-2024 NVIDIA CORPORATION & AFFILIATES.
* All rights reserved.
// SPDX-License-Identifier: GPL-2.0
/*
* camera_common.c - utilities for tegra camera driver
*
* This program is free software; you can redistribute it and/or modify it
* under the terms and conditions of the GNU General Public License,
* version 2, as published by the Free Software Foundation.
*
* This program is distributed in the hope 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, see <http://www.gnu.org/licenses/>.
* Copyright (c) 2015-2023, NVIDIA CORPORATION. All rights reserved.
*/
#include <linux/types.h>
#include <media/tegra-v4l2-camera.h>
@@ -54,11 +44,6 @@ static const struct camera_common_colorfmt camera_common_color_fmts[] = {
V4L2_COLORSPACE_SRGB,
V4L2_PIX_FMT_SGBRG12
},
{
MEDIA_BUS_FMT_SBGGR12_1X12,
V4L2_COLORSPACE_SRGB,
V4L2_PIX_FMT_SBGGR12
},
{
MEDIA_BUS_FMT_SRGGB10_1X10,
V4L2_COLORSPACE_SRGB,

View File

@@ -2,11 +2,9 @@
/*
* NVIDIA Tegra CSI Device
*
* Copyright (c) 2015-2024, NVIDIA CORPORATION. All rights reserved.
* Copyright (c) 2015-2022, NVIDIA CORPORATION. All rights reserved.
*/
#include <nvidia/conftest.h>
#include <linux/clk.h>
#include <linux/device.h>
#include <linux/gpio/consumer.h>
@@ -687,9 +685,6 @@ static int tegra_csi_set_format(struct v4l2_subdev *subdev,
}
static int tegra_csi_g_frame_interval(struct v4l2_subdev *sd,
#if defined(NV_V4L2_SUBDEV_PAD_OPS_STRUCT_HAS_GET_FRAME_INTERVAL)
struct v4l2_subdev_state *sd_state,
#endif
struct v4l2_subdev_frame_interval *vfi)
{
struct tegra_csi_channel *chan = to_csi_chan(sd);
@@ -721,15 +716,10 @@ static int tegra_csi_enum_mbus_code(struct v4l2_subdev *sd,
static struct v4l2_subdev_video_ops tegra_csi_video_ops = {
.s_stream = tegra_csi_s_stream,
.g_input_status = tegra_csi_g_input_status,
#if !defined(NV_V4L2_SUBDEV_PAD_OPS_STRUCT_HAS_GET_FRAME_INTERVAL)
.g_frame_interval = tegra_csi_g_frame_interval,
#endif
};
static struct v4l2_subdev_pad_ops tegra_csi_pad_ops = {
#if defined(NV_V4L2_SUBDEV_PAD_OPS_STRUCT_HAS_GET_FRAME_INTERVAL)
.get_frame_interval = tegra_csi_g_frame_interval,
#endif
.get_fmt = tegra_csi_get_format,
.set_fmt = tegra_csi_set_format,
.enum_mbus_code = tegra_csi_enum_mbus_code,

View File

@@ -1,5 +1,5 @@
// SPDX-License-Identifier: GPL-2.0
// SPDX-FileCopyrightText: Copyright (c) 2017-2024 NVIDIA CORPORATION & AFFILIATES. All rights reserved.
// Copyright (c) 2017-2023 NVIDIA Corporation. All rights reserved.
/**
* @file drivers/media/platform/tegra/camera/fusa-capture/capture-isp.c
@@ -14,7 +14,7 @@
#include <linux/nvhost.h>
#include <linux/of_platform.h>
#include <linux/printk.h>
#include <linux/vmalloc.h>
#include <linux/slab.h>
#include <linux/tegra-capture-ivc.h>
#include <asm/arch_timer.h>
#include <soc/tegra/fuse.h>

View File

@@ -1,10 +1,10 @@
// SPDX-License-Identifier: GPL-2.0-only
// SPDX-FileCopyrightText: Copyright (c) 2017-2024 NVIDIA CORPORATION & AFFILIATES. All rights reserved.
// SPDX-License-Identifier: GPL-2.0
// Copyright (c) 2017-2023 NVIDIA Corporation. All rights reserved.
/**
* @file drivers/media/platform/tegra/camera/fusa-capture/capture-vi-channel.c
*
* @brief VI channel character device driver for the T234 Camera RTCPU
* @brief VI channel character device driver for the T186/T194 Camera RTCPU
* platform.
*/
@@ -17,7 +17,7 @@
#include <linux/of_platform.h>
#include <linux/nvhost.h>
#include <linux/sched.h>
#include <linux/vmalloc.h>
#include <linux/slab.h>
#include <linux/uaccess.h>
#include <linux/dma-buf.h>
#include <linux/dma-mapping.h>
@@ -204,7 +204,11 @@ struct tegra_vi_channel *vi_channel_open_ex(
return ERR_PTR(-ENOMEM);
chan->drv = chan_drv;
chan->vi_capture_pdev = chan_drv->vi_capture_pdev;
if (chan_drv->use_legacy_path) {
chan->dev = chan_drv->dev;
chan->ndev = chan_drv->ndev;
} else
chan->vi_capture_pdev = chan_drv->vi_capture_pdev;
chan->ops = chan_drv->ops;
@@ -386,14 +390,17 @@ static long vi_channel_ioctl(
if (copy_from_user(&setup, ptr, sizeof(setup)))
break;
vi_get_nvhost_device(chan, &setup);
if (chan->dev == NULL) {
dev_err(&chan->vi_capture_pdev->dev,
"%s: channel device is NULL",
__func__);
return -EINVAL;
if (chan->drv->use_legacy_path == false) {
vi_get_nvhost_device(chan, &setup);
if (chan->dev == NULL) {
dev_err(&chan->vi_capture_pdev->dev,
"%s: channel device is NULL",
__func__);
return -EINVAL;
}
}
if (setup.request_size < sizeof(struct capture_descriptor)) {
dev_err(chan->dev,
"request size is too small to fit capture descriptor\n");
@@ -643,10 +650,16 @@ int vi_channel_drv_register(
if (unlikely(chan_drv == NULL))
return -ENOMEM;
chan_drv->dev = NULL;
chan_drv->ndev = NULL;
chan_drv->vi_capture_pdev = ndev;
if (strstr(ndev->name, "tegra-capture-vi") == NULL) {
chan_drv->use_legacy_path = true;
chan_drv->dev = &ndev->dev;
chan_drv->ndev = ndev;
} else {
chan_drv->use_legacy_path = false;
chan_drv->dev = NULL;
chan_drv->ndev = NULL;
chan_drv->vi_capture_pdev = ndev;
}
chan_drv->num_channels = max_vi_channels;
mutex_init(&chan_drv->lock);
@@ -663,7 +676,9 @@ int vi_channel_drv_register(
for (i = 0; i < chan_drv->num_channels; i++) {
dev_t devt = MKDEV(vi_channel_major, i);
struct device *dev = &chan_drv->vi_capture_pdev->dev;
struct device *dev =
(chan_drv->use_legacy_path)?chan_drv->dev :
&chan_drv->vi_capture_pdev->dev;
device_create(vi_channel_class, dev, devt, NULL,
"capture-vi-channel%u", i);
}
@@ -710,8 +725,7 @@ void vi_channel_drv_unregister(
mutex_lock(&chdrv_lock);
chan_drv = chdrv_;
chdrv_ = NULL;
WARN_ON(&chan_drv->vi_capture_pdev->dev != dev);
WARN_ON(chan_drv->dev != dev);
mutex_unlock(&chdrv_lock);
for (i = 0; i < chan_drv->num_channels; i++) {
@@ -720,7 +734,7 @@ void vi_channel_drv_unregister(
device_destroy(vi_channel_class, devt);
}
devm_kfree(&chan_drv->vi_capture_pdev->dev, chan_drv);
devm_kfree(chan_drv->dev, chan_drv);
}
EXPORT_SYMBOL(vi_channel_drv_unregister);

View File

@@ -1,22 +1,10 @@
// SPDX-License-Identifier: GPL-2.0-only
/* SPDX-FileCopyrightText: Copyright (c) 2017-2024 NVIDIA CORPORATION & AFFILIATES.
* All rights reserved.
*
*
* This program is free software; you can redistribute it and/or modify it
* under the terms and conditions of the GNU General Public License,
* version 2, as published by the Free Software Foundation.
*
* This program is distributed in the hope 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.
*/
// SPDX-License-Identifier: GPL-2.0
// Copyright (c) 2017-2023 NVIDIA Corporation. All rights reserved.
/**
* @file drivers/media/platform/tegra/camera/fusa-capture/capture-vi.c
*
* @brief VI channel operations for the T234 Camera RTCPU platform.
* @brief VI channel operations for the T186/T194 Camera RTCPU platform.
*/
#include <linux/completion.h>
@@ -24,7 +12,7 @@
#include <linux/nvhost.h>
#include <linux/of_platform.h>
#include <linux/printk.h>
#include <linux/vmalloc.h>
#include <linux/slab.h>
#include <linux/tegra-capture-ivc.h>
#include <linux/tegra-camera-rtcpu.h>
@@ -460,7 +448,10 @@ int vi_capture_init(
struct platform_device *rtc_pdev;
struct device *dev;
dev = &chan->vi_capture_pdev->dev;
if (chan->drv->use_legacy_path)
dev = chan->dev;
else
dev = &chan->vi_capture_pdev->dev;
dev_dbg(dev, "%s++\n", __func__);
dn = of_find_node_by_path("tegra-camera-rtcpu");
@@ -604,7 +595,10 @@ int vi_capture_setup(
uint32_t vi_inst = 0;
struct device *dev;
dev = &chan->vi_capture_pdev->dev;
if (chan->drv->use_legacy_path)
dev = chan->dev;
else
dev = &chan->vi_capture_pdev->dev;
if (setup->csi_stream_id >= MAX_NVCSI_STREAM_IDS ||
setup->virtual_channel_id >= MAX_VIRTUAL_CHANNEL_PER_STREAM) {
@@ -1450,12 +1444,7 @@ int vi_capture_status(
/* negative timeout means wait forever */
if (timeout_ms < 0) {
ret = wait_for_completion_interruptible(&capture->capture_resp);
if (ret == -ERESTARTSYS) {
dev_dbg(chan->dev,
"capture status interrupted\n");
return -ETIMEDOUT;
}
wait_for_completion(&capture->capture_resp);
} else {
ret = wait_for_completion_timeout(
&capture->capture_resp,
@@ -1675,7 +1664,7 @@ static int capture_vi_probe(struct platform_device *pdev)
err = vi_channel_drv_register(pdev, info->max_vi_channels);
if (err) {
vi_channel_drv_exit();
vi_channel_drv_exit();
goto cleanup;
}
@@ -1713,10 +1702,7 @@ static int capture_vi_remove(struct platform_device *pdev)
for (ii = 0; ii < info->num_vi_devices; ii++)
put_device(&info->vi_pdevices[ii]->dev);
vi_channel_drv_unregister(&pdev->dev);
tegra_vi_media_controller_cleanup(&info->vi_common.mc_vi);
vi_channel_drv_exit();
vi_channel_drv_exit();
return 0;
}

View File

@@ -1,6 +1,6 @@
// SPDX-License-Identifier: GPL-2.0-only
/*
* Copyright (c) 2016-2024, NVIDIA CORPORATION & AFFILIATES. All rights reserved.
* Copyright (c) 2016-2023, NVIDIA CORPORATION & AFFILIATES. All rights reserved.
*
* Tegra CSI5 device common APIs
*/
@@ -213,7 +213,6 @@ static int csi5_stream_set_config(struct tegra_csi_channel *chan, u32 stream_id,
struct CAPTURE_CONTROL_MSG msg;
struct nvcsi_brick_config brick_config;
struct nvcsi_cil_config cil_config;
struct nvcsi_error_config err_config;
u32 phy_mode = read_phy_mode_from_dt(chan);
bool is_cphy = (phy_mode == CSI_PHY_MODE_CPHY);
dev_dbg(csi->dev, "%s: stream_id=%u, csi_port=%u\n",
@@ -286,7 +285,6 @@ static int csi5_stream_set_config(struct tegra_csi_channel *chan, u32 stream_id,
else
cil_config.mipi_clock_rate = csi->clk_freq / 1000;
memset(&err_config, 0, sizeof(err_config));
/* Set NVCSI stream config */
memset(&msg, 0, sizeof(msg));
msg.header.msg_id = CAPTURE_CSI_STREAM_SET_CONFIG_REQ;
@@ -295,9 +293,6 @@ static int csi5_stream_set_config(struct tegra_csi_channel *chan, u32 stream_id,
msg.csi_stream_set_config_req.csi_port = csi_port;
msg.csi_stream_set_config_req.brick_config = brick_config;
msg.csi_stream_set_config_req.cil_config = cil_config;
msg.csi_stream_set_config_req.error_config = err_config;
msg.csi_stream_set_config_req.config_flags = NVCSI_CONFIG_FLAG_BRICK |
NVCSI_CONFIG_FLAG_CIL | NVCSI_CONFIG_FLAG_ERROR;
if (tegra_chan->valid_ports > 1)
vi_port = (stream_id > 0) ? 1 : 0;

View File

@@ -2,7 +2,7 @@
/*
* tegracam_ctrls - control framework for tegra camera drivers
*
* Copyright (c) 2017-2023, NVIDIA CORPORATION. All rights reserved.
* Copyright (c) 2017-2022, NVIDIA CORPORATION. All rights reserved.
*/
#include <linux/nospec.h>

View File

@@ -1,11 +1,10 @@
// SPDX-License-Identifier: GPL-2.0-only
// SPDX-FileCopyrightText: Copyright (c) 2015-2024 NVIDIA CORPORATION & AFFILIATES. All rights reserved.
// SPDX-License-Identifier: GPL-2.0
/*
* NVIDIA Tegra Video Input Device
*
* Copyright (c) 2015-2023 NVIDIA CORPORATION & AFFILIATES. All rights reserved.
*/
#include <nvidia/conftest.h>
#include <linux/atomic.h>
#include <linux/bitmap.h>
#include <linux/clk.h>
@@ -25,7 +24,6 @@
#include <media/v4l2-dev.h>
#include <media/v4l2-fh.h>
#include <media/v4l2-ioctl.h>
#include <media/v4l2-subdev.h>
#include <media/videobuf2-core.h>
#include <media/videobuf2-dma-contig.h>
#include <media/tegra-v4l2-camera.h>
@@ -692,33 +690,16 @@ tegra_channel_queue_setup(struct vb2_queue *vq,
{
struct tegra_channel *chan = vb2_get_drv_priv(vq);
struct tegra_mc_vi *vi = chan->vi;
int ret = 0;
/* In some cases, if nplanes is valid
* and the requested image size is less than the
* actual image size, we need to return EINVAL.
* Previously, we were just updating sizes[0] irrespective
* of the requested image size. Although this did not harm the
* flow, according to "v4l2-compliance", we need to check if
* the requested size is invalid.
*/
if (*nplanes) {
if (sizes[0] < chan->format.sizeimage) {
pr_err("%s: sizes[0] = %d chan->format.sizeimage = %d ...\n"
,__func__,sizes[0],chan->format.sizeimage);
return -EINVAL;
}
} else {
sizes[0] = chan->format.sizeimage;
}
*nplanes = 1;
sizes[0] = chan->format.sizeimage;
alloc_devs[0] = tegra_channel_get_vi_unit(chan);
if (vi->fops && vi->fops->vi_setup_queue)
return vi->fops->vi_setup_queue(chan, nbuffers);
return ret;
else
return -EINVAL;
}
int tegra_channel_alloc_buffer_queue(struct tegra_channel *chan,
@@ -1042,21 +1023,14 @@ static int
tegra_channel_querycap(struct file *file, void *fh, struct v4l2_capability *cap)
{
struct tegra_channel *chan = video_drvdata(file);
ssize_t len;
int ret = 0;
cap->device_caps = V4L2_CAP_VIDEO_CAPTURE | V4L2_CAP_STREAMING;
cap->device_caps |= V4L2_CAP_EXT_PIX_FORMAT;
cap->capabilities = cap->device_caps | V4L2_CAP_DEVICE_CAPS;
len = strscpy(cap->driver, "tegra-video", sizeof(cap->driver));
if (len < 0)
return -ENAMETOOLONG;
len = strscpy(cap->card, chan->video->name, sizeof(cap->card));
if (len < 0)
return -ENAMETOOLONG;
strlcpy(cap->driver, "tegra-video", sizeof(cap->driver));
strlcpy(cap->card, chan->video->name, sizeof(cap->card));
ret = snprintf(cap->bus_info, sizeof(cap->bus_info), "platform:%s:%u",
dev_name(chan->vi->dev), chan->port[0]);
if (ret < 0)
@@ -1177,19 +1151,11 @@ tegra_channel_g_dv_timings(struct file *file, void *fh,
{
struct tegra_channel *chan = video_drvdata(file);
#if defined(NV_V4L2_SUBDEV_PAD_OPS_STRUCT_HAS_DV_TIMINGS) /* Linux v6.10 */
if (!v4l2_subdev_has_op(chan->subdev_on_csi, pad, g_dv_timings))
return -ENOTTY;
return v4l2_device_call_until_err(chan->video->v4l2_dev,
chan->grp_id, pad, g_dv_timings, 0, timings);
#else
if (!v4l2_subdev_has_op(chan->subdev_on_csi, video, g_dv_timings))
return -ENOTTY;
return v4l2_device_call_until_err(chan->video->v4l2_dev,
chan->grp_id, video, g_dv_timings, timings);
#endif
}
static int
@@ -1201,11 +1167,7 @@ tegra_channel_s_dv_timings(struct file *file, void *fh,
struct v4l2_dv_timings curr_timings;
int ret;
#if defined(NV_V4L2_SUBDEV_PAD_OPS_STRUCT_HAS_DV_TIMINGS) /* Linux v6.10 */
if (!v4l2_subdev_has_op(chan->subdev_on_csi, pad, s_dv_timings))
#else
if (!v4l2_subdev_has_op(chan->subdev_on_csi, video, s_dv_timings))
#endif
return -ENOTTY;
ret = tegra_channel_g_dv_timings(file, fh, &curr_timings);
@@ -1218,13 +1180,9 @@ tegra_channel_s_dv_timings(struct file *file, void *fh,
if (vb2_is_busy(&chan->queue))
return -EBUSY;
#if defined(NV_V4L2_SUBDEV_PAD_OPS_STRUCT_HAS_DV_TIMINGS) /* Linux v6.10 */
ret = v4l2_device_call_until_err(chan->video->v4l2_dev,
chan->grp_id, pad, s_dv_timings, 0, timings);
#else
ret = v4l2_device_call_until_err(chan->video->v4l2_dev,
chan->grp_id, video, s_dv_timings, timings);
#endif
if (!ret)
tegra_channel_update_format(chan, bt->width, bt->height,
chan->fmtinfo->fourcc, &chan->fmtinfo->bpp,
@@ -1242,19 +1200,11 @@ tegra_channel_query_dv_timings(struct file *file, void *fh,
{
struct tegra_channel *chan = video_drvdata(file);
#if defined(NV_V4L2_SUBDEV_PAD_OPS_STRUCT_HAS_DV_TIMINGS) /* Linux v6.10 */
if (!v4l2_subdev_has_op(chan->subdev_on_csi, pad, query_dv_timings))
return -ENOTTY;
return v4l2_device_call_until_err(chan->video->v4l2_dev,
chan->grp_id, pad, query_dv_timings, 0, timings);
#else
if (!v4l2_subdev_has_op(chan->subdev_on_csi, video, query_dv_timings))
return -ENOTTY;
return v4l2_device_call_until_err(chan->video->v4l2_dev,
chan->grp_id, video, query_dv_timings, timings);
#endif
}
static int
@@ -1301,10 +1251,6 @@ int tegra_channel_s_ctrl(struct v4l2_ctrl *ctrl)
}
break;
case TEGRA_CAMERA_CID_VI_BYPASS_MODE:
/* Prevent changing the bypass mode while the device is still streaming */
if (vb2_is_busy(&chan->queue))
return -EBUSY;
if (switch_ctrl_qmenu[ctrl->val] == SWITCH_ON)
chan->bypass = true;
else if (chan->vi->bypass) {
@@ -1891,13 +1837,8 @@ static void tegra_channel_populate_dev_info(struct tegra_camera_dev_info *cdev,
if (chan->pg_mode) {
/* TPG mode */
cdev->sensor_type = SENSORTYPE_VIRTUAL;
#if defined(NV_V4L2_SUBDEV_PAD_OPS_STRUCT_HAS_DV_TIMINGS) /* Linux v6.10 */
} else if (v4l2_subdev_has_op(chan->subdev_on_csi,
pad, g_dv_timings)) {
#else
} else if (v4l2_subdev_has_op(chan->subdev_on_csi,
video, g_dv_timings)) {
#endif
/* HDMI-IN */
cdev->sensor_type = SENSORTYPE_OTHER;
pixelclock = tegra_channel_get_max_source_rate();
@@ -2224,11 +2165,7 @@ tegra_channel_enum_input(struct file *file, void *fh, struct v4l2_input *inp)
return -ENODEV;
inp->type = V4L2_INPUT_TYPE_CAMERA;
#if defined(NV_V4L2_SUBDEV_PAD_OPS_STRUCT_HAS_DV_TIMINGS) /* Linux v6.10 */
if (v4l2_subdev_has_op(sd_on_csi, pad, s_dv_timings)) {
#else
if (v4l2_subdev_has_op(sd_on_csi, video, s_dv_timings)) {
#endif
inp->capabilities = V4L2_IN_CAP_DV_TIMINGS;
len = snprintf(inp->name,
sizeof(inp->name), "HDMI %u",
@@ -2273,7 +2210,7 @@ static long tegra_channel_default_ioctl(struct file *file, void *fh,
{
struct tegra_channel *chan = video_drvdata(file);
struct tegra_mc_vi *vi = chan->vi;
long ret = -ENOTTY;
long ret = 0;
if (vi->fops && vi->fops->vi_default_ioctl)
ret = vi->fops->vi_default_ioctl(file, fh, use_prio, cmd, arg);

View File

@@ -2,11 +2,8 @@
/*
* NVIDIA Media controller graph management
*
* Copyright (c) 2015-2024 NVIDIA CORPORATION & AFFILIATES. All rights reserved.
* Copyright (c) 2015-2023 NVIDIA CORPORATION & AFFILIATES. All rights reserved.
*/
#include <nvidia/conftest.h>
#include <linux/clk.h>
#include <linux/list.h>
#include <linux/of.h>
@@ -16,6 +13,7 @@
#include <linux/regulator/consumer.h>
#include <linux/reset.h>
#include <linux/slab.h>
#include <linux/version.h>
#include <soc/tegra/fuse.h>
#include <media/media-device.h>
#include <media/v4l2-async.h>
@@ -343,7 +341,7 @@ register_device_error:
return ret;
}
#if defined(NV_V4L2_ASYNC_CONNECTION_STRUCT_PRESENT) /* Linux 6.5 */
#if defined(NV_V4L2_ASYNC_SUBDEV_RENAME)
static int tegra_vi_graph_notify_bound(struct v4l2_async_notifier *notifier,
struct v4l2_subdev *subdev,
struct v4l2_async_connection *asd)
@@ -382,7 +380,7 @@ static int tegra_vi_graph_notify_bound(struct v4l2_async_notifier *notifier,
return -EINVAL;
}
#if defined(NV_V4L2_ASYNC_CONNECTION_STRUCT_PRESENT) /* Linux 6.5 */
#if defined(NV_V4L2_ASYNC_SUBDEV_RENAME)
static void tegra_vi_graph_notify_unbind(struct v4l2_async_notifier *notifier,
struct v4l2_subdev *subdev,
struct v4l2_async_connection *asd)
@@ -425,7 +423,7 @@ void tegra_vi_graph_cleanup(struct tegra_mc_vi *vi)
list_for_each_entry(chan, &vi->vi_chans, list) {
#if defined(CONFIG_V4L2_ASYNC)
#if defined(NV_V4L2_ASYNC_NOTIFIER_INIT_PRESENT)
#if LINUX_VERSION_CODE < KERNEL_VERSION(5, 16, 0)
v4l2_async_notifier_unregister(&chan->notifier);
#else
v4l2_async_nf_unregister(&chan->notifier);
@@ -479,14 +477,12 @@ static int tegra_vi_graph_parse_one(struct tegra_channel *chan,
}
entity->node = remote;
#if !defined(NV_V4L2_ASYNC_CONNECTION_STRUCT_PRESENT) /* Linux 6.5 */
#if defined(NV_V4L2_ASYNC_MATCH_TYPE_ENUM_PRESENT) /* Linux 6.5 */
#if defined(NV_V4L2_ASYNC_MATCH_FWNODE_RENAME)
entity->asd.match.type = V4L2_ASYNC_MATCH_TYPE_FWNODE;
#else
entity->asd.match_type = V4L2_ASYNC_MATCH_FWNODE;
#endif
entity->asd.match.fwnode = of_fwnode_handle(remote);
#endif
list_add_tail(&entity->list, &chan->entities);
chan->num_subdevs++;
@@ -642,14 +638,12 @@ int tegra_vi_graph_init(struct tegra_mc_vi *vi)
/* Add the remote entity of this endpoint */
entity->node = remote;
#if !defined(NV_V4L2_ASYNC_CONNECTION_STRUCT_PRESENT) /* Linux 6.5 */
#if defined(NV_V4L2_ASYNC_MATCH_TYPE_ENUM_PRESENT) /* Linux 6.5 */
#if defined(NV_V4L2_ASYNC_MATCH_FWNODE_RENAME)
entity->asd.match.type = V4L2_ASYNC_MATCH_TYPE_FWNODE;
#else
entity->asd.match_type = V4L2_ASYNC_MATCH_FWNODE;
#endif
entity->asd.match.fwnode = of_fwnode_handle(remote);
#endif
list_add_tail(&entity->list, &chan->entities);
chan->num_subdevs++;
chan->notifier.ops = chan->notifier.ops ? chan->notifier.ops : &vi_chan_notify_ops;
@@ -670,44 +664,39 @@ int tegra_vi_graph_init(struct tegra_mc_vi *vi)
i = 0;
#if defined(CONFIG_V4L2_ASYNC)
#if defined(NV_V4L2_ASYNC_NOTIFIER_INIT_PRESENT)
#if LINUX_VERSION_CODE < KERNEL_VERSION(5, 16, 0)
v4l2_async_notifier_init(&chan->notifier);
list_for_each_entry(entity, &chan->entities, list)
__v4l2_async_notifier_add_subdev(&chan->notifier, &entity->asd);
#else
#if defined(NV_V4L2_ASYNC_NF_INIT_HAS_V4L2_DEV_ARG) /* Linux 6.6 */
v4l2_async_nf_init(&chan->notifier, &vi->v4l2_dev);
#if defined (NV_V4L2_ASYNC_NF_SUBDEVICE_INIT_RENAME)
v4l2_async_subdev_nf_init(&chan->notifier, tegra_channel_find_linked_csi_subdev(chan));
list_for_each_entry(entity, &chan->entities, list) {
struct v4l2_async_connection *asd;
asd = v4l2_async_nf_add_fwnode_remote(&chan->notifier, of_fwnode_handle(remote),
struct v4l2_async_connection);
if (IS_ERR(asd)) {
ret = PTR_ERR(asd);
goto done;
}
}
#else
v4l2_async_nf_init(&chan->notifier);
#endif
#if defined(NV_V4L2_ASYNC_NF_ADD_SUBDEV_PRESENT) /* Linux 6.6 */
list_for_each_entry(entity, &chan->entities, list)
__v4l2_async_nf_add_subdev(&chan->notifier, &entity->asd);
#else
list_for_each_entry(entity, &chan->entities, list) {
struct v4l2_async_connection *asc;
asc = v4l2_async_nf_add_fwnode(&chan->notifier, of_fwnode_handle(entity->node),
struct v4l2_async_connection);
if (IS_ERR(asc))
asc = NULL;
entity->asc = asc;
}
#endif /* NV_V4L2_ASYNC_NF_ADD_SUBDEV_PRESENT */
#endif /* NV_V4L2_ASYNC_NOTIFIER_INIT_PRESENT */
#endif
#endif
chan->link_status = 0;
chan->subdevs_bound = 0;
/* Register the async notifier for this channel */
#if defined(NV_V4L2_ASYNC_NOTIFIER_INIT_PRESENT)
#if LINUX_VERSION_CODE < KERNEL_VERSION(5, 16, 0)
ret = v4l2_async_notifier_register(&vi->v4l2_dev,
&chan->notifier);
#else
#if defined (NV_V4L2_ASYNC_NF_INIT_HAS_V4L2_DEV_ARG) /* Linux 6.6 */
#if defined (NV_V4L2_ASYNC_NF_SUBDEVICE_INIT_RENAME)
ret = v4l2_async_nf_register(&chan->notifier);
if (ret < 0)
v4l2_async_nf_cleanup(&chan->notifier);
#else
ret = v4l2_async_nf_register(&vi->v4l2_dev,
&chan->notifier);
@@ -716,9 +705,9 @@ int tegra_vi_graph_init(struct tegra_mc_vi *vi)
#else
dev_err(vi->dev, "CONFIG_V4L2_ASYNC is not enabled!\n");
ret = -ENOTSUPP;
#endif /* CONFIG_V4L2_ASYNC */
#endif
if (ret < 0) {
dev_err(vi->dev, "notifier registration failed %d\n", ret);
dev_err(vi->dev, "notifier registration failed\n");
goto done;
}

View File

@@ -1,7 +1,8 @@
// SPDX-License-Identifier: GPL-2.0-only
// SPDX-FileCopyrightText: Copyright (c) 2015-2024 NVIDIA CORPORATION & AFFILIATES. All rights reserved.
// SPDX-License-Identifier: GPL-2.0
/*
* Tegra Video Input device common APIs
*
* Copyright (c) 2015-2023 NVIDIA CORPORATION & AFFILIATES. All rights reserved.
*/
#include <linux/init.h>
@@ -115,15 +116,11 @@ static void tegra_vi_notify(struct v4l2_subdev *sd,
int tegra_vi_v4l2_init(struct tegra_mc_vi *vi)
{
ssize_t len;
int ret;
vi->media_dev.dev = vi->dev;
len = strscpy(vi->media_dev.model, "NVIDIA Tegra Video Input Device",
strlcpy(vi->media_dev.model, "NVIDIA Tegra Video Input Device",
sizeof(vi->media_dev.model));
if (len < 0)
return -ENAMETOOLONG;
vi->media_dev.hw_revision = 3;
media_device_init(&vi->media_dev);

View File

@@ -1,14 +1,8 @@
// SPDX-License-Identifier: GPL-2.0
/* SPDX-FileCopyrightText: Copyright (c) 2016-2024 NVIDIA CORPORATION & AFFILIATES.
* All rights reserved.
*
/*
* Tegra Video Input 5 device common APIs
*
* Author: Frank Chen <frank@nvidia.com>
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License version 2 as
* published by the Free Software Foundation.
* Copyright (c) 2016-2023, NVIDIA CORPORATION & AFFILIATES. All rights reserved.
*/
#include <linux/errno.h>
@@ -140,9 +134,6 @@ static int tegra_vi5_s_ctrl(struct v4l2_ctrl *ctrl)
case TEGRA_CAMERA_CID_WRITE_ISPFORMAT:
chan->write_ispformat = ctrl->val;
break;
case TEGRA_CAMERA_CID_VI_CAPTURE_TIMEOUT:
chan->capture_timeout_ms = ctrl->val;
break;
default:
dev_err(&chan->video->dev, "%s:Not valid ctrl\n", __func__);
return -EINVAL;
@@ -209,16 +200,6 @@ static const struct v4l2_ctrl_config vi5_custom_ctrls[] = {
.step = 1,
.dims = { SENSOR_CTRL_BLOB_SIZE },
},
{
.ops = &vi5_ctrl_ops,
.id = TEGRA_CAMERA_CID_VI_CAPTURE_TIMEOUT,
.name = "Override capture timeout ms",
.type = V4L2_CTRL_TYPE_INTEGER,
.def = CAPTURE_TIMEOUT_MS,
.min = -1,
.max = 0x7FFFFFFF,
.step = 1,
},
};
static int vi5_add_ctrls(struct tegra_channel *chan)
@@ -338,8 +319,6 @@ static int tegra_channel_capture_setup(struct tegra_channel *chan, unsigned int
chan->request[vi_port] = dma_alloc_coherent(chan->tegra_vi_channel[vi_port]->rtcpu_dev,
setup.queue_depth * setup.request_size,
&setup.iova, GFP_KERNEL);
chan->request_iova[vi_port] = setup.iova;
if (chan->request[vi_port] == NULL) {
dev_err(chan->vi->dev, "dma_alloc_coherent failed\n");
return -ENOMEM;
@@ -516,7 +495,6 @@ static void vi5_capture_dequeue(struct tegra_channel *chan,
unsigned long flags;
struct tegra_mc_vi *vi = chan->vi;
struct vb2_v4l2_buffer *vb = &buf->buf;
int timeout_ms = CAPTURE_TIMEOUT_MS;
struct timespec64 ts;
struct capture_descriptor *descr = NULL;
@@ -527,21 +505,12 @@ static void vi5_capture_dequeue(struct tegra_channel *chan,
goto rel_buf;
/* Dequeue a frame and check its capture status */
timeout_ms = chan->capture_timeout_ms;
err = vi_capture_status(chan->tegra_vi_channel[vi_port], timeout_ms);
err = vi_capture_status(chan->tegra_vi_channel[vi_port], CAPTURE_TIMEOUT_MS);
if (err) {
if (err == -ETIMEDOUT) {
if (timeout_ms < 0) {
spin_lock_irqsave(&chan->capture_state_lock, flags);
chan->capture_state = CAPTURE_ERROR_TIMEOUT;
spin_unlock_irqrestore(&chan->capture_state_lock, flags);
buf->vb2_state = VB2_BUF_STATE_ERROR;
goto rel_buf;
} else {
dev_err(vi->dev,
"uncorr_err: request timed out after %d ms\n",
timeout_ms);
}
dev_err(vi->dev,
"uncorr_err: request timed out after %d ms\n",
CAPTURE_TIMEOUT_MS);
} else {
dev_err(vi->dev, "uncorr_err: request err %d\n", err);
}
@@ -731,7 +700,6 @@ static int tegra_channel_kthread_capture_dequeue(void *data)
struct tegra_channel_buffer *buf;
set_freezable();
allow_signal(SIGINT);
while (1) {
try_to_freeze();
@@ -752,12 +720,6 @@ static int tegra_channel_kthread_capture_dequeue(void *data)
}
spin_lock_irqsave(&chan->capture_state_lock, flags);
if (chan->capture_state == CAPTURE_ERROR_TIMEOUT) {
spin_unlock_irqrestore(&chan->capture_state_lock,
flags);
break;
}
if (chan->capture_state == CAPTURE_ERROR) {
spin_unlock_irqrestore(&chan->capture_state_lock,
flags);
@@ -827,7 +789,6 @@ static void vi5_channel_stop_kthreads(struct tegra_channel *chan)
/* Stop the kthread for capture dequeue */
if (chan->kthread_capture_dequeue) {
send_sig(SIGINT, chan->kthread_capture_dequeue, 1);
kthread_stop(chan->kthread_capture_dequeue);
chan->kthread_capture_dequeue = NULL;
}
@@ -1006,24 +967,6 @@ static int vi5_channel_stop_streaming(struct vb2_queue *vq)
dev_err(&chan->video->dev,
"vi capture release failed\n");
/* Release capture requests */
if (chan->request[vi_port] != NULL) {
dma_free_coherent(chan->tegra_vi_channel[vi_port]->rtcpu_dev,
chan->capture_queue_depth * sizeof(struct capture_descriptor),
chan->request[vi_port], chan->request_iova[vi_port]);
}
chan->request[vi_port] = NULL;
/* Release emd data buffers */
if (chan->emb_buf_size > 0) {
struct device *vi_unit_dev;
vi5_unit_get_device_handle(chan->vi->ndev, chan->port[0],\
&vi_unit_dev);
dma_free_coherent(vi_unit_dev, chan->emb_buf_size,
chan->emb_buf_addr, chan->emb_buf);
chan->emb_buf_size = 0;
}
vi_channel_close_ex(chan->vi_channel_id[vi_port],
chan->tegra_vi_channel[vi_port]);
chan->tegra_vi_channel[vi_port] = NULL;
@@ -1031,7 +974,6 @@ static int vi5_channel_stop_streaming(struct vb2_queue *vq)
/* release all remaining buffers to v4l2 */
tegra_channel_queued_buf_done(chan, VB2_BUF_STATE_ERROR, false);
}
return 0;

View File

@@ -1,8 +1,10 @@
# SPDX-License-Identifier: GPL-2.0-only
# Copyright (c) 2022-2023, NVIDIA CORPORATION & AFFILIATES. All rights reserved.
ifneq ($(CONFIG_TEGRA_GPIO_LEGACY_DISABLE),y)
obj-m += cdi_gpio.o
obj-m += cdi_mgr.o
endif
obj-m += cdi_dev.o
obj-m += cdi_pwm.o
ifeq ($(findstring ack_src,$(NV_BUILD_KERNEL_OPTIONS)),)

View File

@@ -1,5 +1,5 @@
/* SPDX-License-Identifier: GPL-2.0 */
/* Copyright (c) 2023-2024, NVIDIA CORPORATION & AFFILIATES. All Rights Reserved. */
/* Copyright (c) 2023, NVIDIA CORPORATION & AFFILIATES. All Rights Reserved. */
/*
* cam_cdi_tsc.c - tsc driver.
*/
@@ -147,8 +147,6 @@ struct tsc_signal_controller {
} debugfs;
const struct tsc_signal_controller_features *features;
struct list_head generators;
bool opened;
};
static const struct tsc_signal_controller_features tegra234_tsc_features = {
@@ -460,44 +458,22 @@ static void cdi_tsc_debugfs_remove(struct tsc_signal_controller *controller)
static int cdi_tsc_chardev_open(struct inode *inode, struct file *file)
{
struct tsc_signal_controller *controller = dev_get_drvdata(tsc_charDevice);
int err = 0;
pr_info("%s:Device opened\n", __func__);
if (controller->opened)
return -EBUSY;
/* Set External Fsync */
Hawk_Owl_Fsync_program(EXTERNAL_FSYNC);
/* Make sure device opened only once */
controller->opened = true;
/* Set External Fsync */
err = Hawk_Owl_Fsync_program(EXTERNAL_FSYNC);
if (err)
controller->opened = false;
else
dev_dbg(controller->dev, "%s:Device opened successfully!! \n", __func__);
return err;
return 0;
}
static int cdi_tsc_chardev_release(struct inode *inode, struct file *file)
{
struct tsc_signal_controller *controller = dev_get_drvdata(tsc_charDevice);
int err = -EFAULT;
/* To make sure whenever the device is closed, tsc is also stopped
* to avoid inconsistency behaviour at app level i.e to avoid out of sync.
*/
err = cdi_tsc_stop_generators(controller);
if (err)
return err;
pr_info("%s:Device closed\n", __func__);
/* Set back to Internal Fsync */
err = Hawk_Owl_Fsync_program(INTERNAL_FSYNC);
Hawk_Owl_Fsync_program(INTERNAL_FSYNC);
controller->opened = false;
dev_dbg(controller->dev, "%s Device closed ..\n", __func__);
return err;
return 0;
}
static long cdi_tsc_chardev_ioctl(struct file *file, unsigned int cmd, unsigned long arg)
@@ -544,7 +520,6 @@ static int cdi_tsc_probe(struct platform_device *pdev)
if (!controller)
return -ENOMEM;
controller->opened = false;
controller->dev = &pdev->dev;
controller->features = of_device_get_match_data(&pdev->dev);
if (controller->features == NULL) {

View File

@@ -1,13 +1,11 @@
/* SPDX-License-Identifier: GPL-2.0-only */
/* SPDX-FileCopyrightText: Copyright (c) 2016-2024 NVIDIA CORPORATION & AFFILIATES. All rights reserved. */
// SPDX-License-Identifier: GPL-2.0
// Copyright (c) 2016-2022, NVIDIA CORPORATION & AFFILIATES. All rights reserved.
#ifndef __CDI_PWM_PRIV_H__
#define __CDI_PWM_PRIV_H__
struct cdi_pwm_info {
#if !defined(NV_PWM_CHIP_STRUCT_HAS_STRUCT_DEVICE)
struct pwm_chip chip;
#endif
struct pwm_device *pwm;
atomic_t in_use;
struct mutex mutex;

View File

@@ -1,8 +1,6 @@
// SPDX-License-Identifier: GPL-2.0
// Copyright (c) 2015-2023, NVIDIA CORPORATION & AFFILIATES. All rights reserved.
#include <nvidia/conftest.h>
#include <linux/delay.h>
#include <linux/device.h>
#include <linux/fs.h>
@@ -566,7 +564,7 @@ static void cdi_dev_get_cim_ver(struct device_node *np, struct cdi_dev_info *inf
}
}
#if defined(NV_I2C_DRIVER_STRUCT_PROBE_WITHOUT_I2C_DEVICE_ID_ARG) /* Linux 6.3 */
#if KERNEL_VERSION(6, 3, 0) <= LINUX_VERSION_CODE
static int cdi_dev_probe(struct i2c_client *client)
#else
static int cdi_dev_probe(struct i2c_client *client,
@@ -807,7 +805,7 @@ static int cdi_dev_probe(struct i2c_client *client,
return 0;
}
#if defined(NV_I2C_DRIVER_STRUCT_REMOVE_RETURN_TYPE_INT) /* Linux 6.1 */
#if KERNEL_VERSION(6, 1, 0) > LINUX_VERSION_CODE
static int cdi_dev_remove(struct i2c_client *client)
#else
static void cdi_dev_remove(struct i2c_client *client)
@@ -828,7 +826,7 @@ static void cdi_dev_remove(struct i2c_client *client)
if (info->cdev.dev)
cdev_del(&info->cdev);
#if defined(NV_I2C_DRIVER_STRUCT_REMOVE_RETURN_TYPE_INT) /* Linux 6.1 */
#if KERNEL_VERSION(6, 1, 0) > LINUX_VERSION_CODE
return 0;
#endif
}

View File

@@ -1,7 +1,5 @@
// SPDX-License-Identifier: GPL-2.0-only
// SPDX-FileCopyrightText: Copyright (c) 2017-2024 NVIDIA CORPORATION & AFFILIATES. All rights reserved.
#include <nvidia/conftest.h>
// SPDX-License-Identifier: GPL-2.0
// Copyright (c) 2017-2022, NVIDIA CORPORATION & AFFILIATES. All rights reserved.
#include <linux/init.h>
#include <linux/module.h>
@@ -33,11 +31,7 @@ static int of_cdi_gpio_pdata(struct platform_device *pdev,
return err;
}
#if defined(NV_GPIO_DEVICE_FIND_HAS_CONST_DATA_ARG) /* Linux v6.9 */
static int cdi_gpio_chip_match(struct gpio_chip *chip, const void *data)
#else
static int cdi_gpio_chip_match(struct gpio_chip *chip, void *data)
#endif
{
return !strcmp(chip->label, data);
}
@@ -46,10 +40,6 @@ static struct gpio_chip *cdi_gpio_get_chip(struct platform_device *pdev,
struct cdi_gpio_plat_data *pd)
{
struct gpio_chip *gc = NULL;
#if defined(NV_GPIO_DEVICE_FIND_PRESENT) && \
defined(NV_GPIO_DEVICE_GET_CHIP_PRESENT) /* Linux 6.7 */
struct gpio_device *gdev;
#endif
char name[MAX_STR_SIZE];
if (strlen(pd->gpio_prnt_chip) > MAX_STR_SIZE) {
@@ -59,16 +49,7 @@ static struct gpio_chip *cdi_gpio_get_chip(struct platform_device *pdev,
}
strcpy(name, pd->gpio_prnt_chip);
#if defined(NV_GPIO_DEVICE_FIND_PRESENT) && \
defined(NV_GPIO_DEVICE_GET_CHIP_PRESENT) /* Linux 6.7 */
gdev = gpio_device_find(name, cdi_gpio_chip_match);
if (gdev) {
gc = gpio_device_get_chip(gdev);
gpio_device_put(gdev);
}
#else
gc = gpiochip_find(name, cdi_gpio_chip_match);
#endif
if (!gc) {
dev_err(&pdev->dev, "%s: unable to find gpio parent chip %s\n",
__func__, pd->gpio_prnt_chip);
@@ -294,10 +275,7 @@ static int cdi_gpio_probe(struct platform_device *pdev)
gc->base = -1;
gc->ngpio = pd->max_gpio;
gc->label = "cdi-gpio";
gc->parent = &pdev->dev;
#if defined(NV_GPIO_CHIP_STRUCT_HAS_OF_NODE_PRESENT) /* Linux 6.2 */
gc->of_node = pdev->dev.of_node;
#endif
gc->owner = THIS_MODULE;
err = gpiochip_add_data(gc, cdi_gpio);

View File

@@ -14,7 +14,6 @@
#include <linux/platform_device.h>
#include <linux/device.h>
#include <linux/of_irq.h>
#include <linux/of.h>
#include <linux/interrupt.h>
#include <asm/siginfo.h>
#include <linux/rcupdate.h>
@@ -31,6 +30,7 @@
#include <media/cdi-mgr.h>
#include <linux/gpio/consumer.h>
#include <linux/semaphore.h>
#include <linux/version.h>
#include <asm/barrier.h>
@@ -1328,23 +1328,15 @@ static int cdi_mgr_of_get_grp_gpio(
struct device *dev, struct device_node *np,
const char *name, int size, u32 *grp, u32 *flags)
{
char prop_name[32]; /* 32 is max size of property name */
int num, i;
snprintf(prop_name, sizeof(prop_name), "%s-gpios", name);
num = gpiod_count(dev, name);
dev_dbg(dev, " num gpios of %s: %d\n", prop_name, num);
num = of_gpio_named_count(np, name);
dev_dbg(dev, " num gpios of %s: %d\n", name, num);
if (num < 0)
return 0;
for (i = 0; (i < num) && (i < size); i++) {
#if defined(NV_OF_GET_NAMED_GPIO_FLAGS_PRESENT) /* Linux 6.2 */
grp[i] = of_get_named_gpio_flags(np, prop_name, i, &flags[i]);
#else
grp[i] = of_get_named_gpio(np, prop_name, i);
flags[i] = 0;
#endif
grp[i] = of_get_named_gpio_flags(np, name, i, &flags[i]);
if ((int)grp[i] < 0) {
dev_err(dev, "%s: gpio[%d] invalid\n", __func__, i);
return -EINVAL;
@@ -1454,13 +1446,13 @@ static struct cdi_mgr_platform_data *of_cdi_mgr_pdata(struct platform_device
dev_dbg(&pdev->dev, " csiport: %d\n", pd->csi_port);
pd->num_pwr_gpios = cdi_mgr_of_get_grp_gpio(
&pdev->dev, child_np, "pwdn",
&pdev->dev, child_np, "pwdn-gpios",
ARRAY_SIZE(pd->pwr_gpios), pd->pwr_gpios, pd->pwr_flags);
if (pd->num_pwr_gpios < 0)
return ERR_PTR(pd->num_pwr_gpios);
pd->num_mcdi_gpios = cdi_mgr_of_get_grp_gpio(
&pdev->dev, child_np, "mcdi",
&pdev->dev, child_np, "mcdi-gpios",
ARRAY_SIZE(pd->mcdi_gpios), pd->mcdi_gpios, pd->mcdi_flags);
if (pd->num_mcdi_gpios < 0)
return ERR_PTR(pd->num_mcdi_gpios);
@@ -1496,10 +1488,10 @@ static struct cdi_mgr_platform_data *of_cdi_mgr_pdata(struct platform_device
return pd;
}
#if defined(NV_CLASS_STRUCT_DEVNODE_HAS_CONST_DEV_ARG) /* Linux v6.2 */
static char *cdi_mgr_devnode(const struct device *dev, umode_t *mode)
#else
#if LINUX_VERSION_CODE < KERNEL_VERSION(6, 2, 0)
static char *cdi_mgr_devnode(struct device *dev, umode_t *mode)
#else
static char *cdi_mgr_devnode(const struct device *dev, umode_t *mode)
#endif
{
if (!mode)
@@ -1660,8 +1652,13 @@ static int cdi_mgr_configure_gpios(struct device *dev, struct cdi_mgr_priv *cdi_
}
}
#if LINUX_VERSION_CODE < KERNEL_VERSION(6, 2, 0)
cdi_mgr->gpios[i].desc = devm_fwnode_get_gpiod_from_child(dev,
"devblk", &child->fwnode, GPIOD_ASIS, NULL);
#else
cdi_mgr->gpios[i].desc = devm_fwnode_gpiod_get_index(dev,
&child->fwnode, "devblk", 0, GPIOD_ASIS, NULL);
#endif
if (IS_ERR(cdi_mgr->gpios[i].desc)) {
ret = PTR_ERR(cdi_mgr->gpios[i].desc);
if (ret < 0)

View File

@@ -1,7 +1,5 @@
// SPDX-License-Identifier: GPL-2.0-only
// SPDX-FileCopyrightText: Copyright (c) 2016-2024 NVIDIA CORPORATION & AFFILIATES. All rights reserved.
#include <nvidia/conftest.h>
// SPDX-License-Identifier: GPL-2.0
// Copyright (c) 2016-2022, NVIDIA CORPORATION & AFFILIATES. All rights reserved.
#include <linux/module.h>
#include <linux/of.h>
@@ -30,11 +28,7 @@ static const struct of_device_id cdi_pwm_of_match[] = {
static inline struct cdi_pwm_info *to_cdi_pwm_info(struct pwm_chip *chip)
{
#if defined(NV_PWM_CHIP_STRUCT_HAS_STRUCT_DEVICE)
return pwmchip_get_drvdata(chip);
#else
return container_of(chip, struct cdi_pwm_info, chip);
#endif
}
#if KERNEL_VERSION(6, 0, 0) > LINUX_VERSION_CODE
@@ -99,38 +93,30 @@ static struct pwm_device *of_cdi_pwm_xlate(struct pwm_chip *pc,
{
struct pwm_device *pwm;
struct cdi_pwm_info *info = to_cdi_pwm_info(pc);
#if defined(NV_PWM_CHIP_STRUCT_HAS_STRUCT_DEVICE)
struct device *dev = &pc->dev;
#else
struct device *dev = pc->dev;
#endif
int err = 0;
pwm = of_pwm_xlate_with_flags(pc, args);
if (IS_ERR(pwm))
return NULL;
if (!pwm->args.period) {
dev_err(dev, "Period should be larger than 0\n");
pwm = pwm_request_from_chip(pc, args->args[0], NULL);
if (!args->args[1]) {
dev_err(pc->dev, "Period should be larger than 0\n");
return NULL;
}
if (info->force_on) {
err = pwm_config(info->pwm, args->args[1]/4, args->args[1]);
if (err) {
dev_err(dev, "can't config PWM: %d\n", err);
dev_err(pc->dev, "can't config PWM: %d\n", err);
return NULL;
}
err = pwm_enable(info->pwm);
if (err) {
dev_err(dev, "can't enable PWM: %d\n", err);
dev_err(pc->dev, "can't enable PWM: %d\n", err);
return NULL;
}
} else {
err = pwm_config(pwm, args->args[1]/4, args->args[1]);
if (err) {
dev_err(dev, "can't config PWM: %d\n", err);
dev_err(pc->dev, "can't config PWM: %d\n", err);
return NULL;
}
}
@@ -144,68 +130,55 @@ static const struct pwm_ops cdi_pwm_ops = {
.enable = cdi_pwm_enable,
.disable = cdi_pwm_disable,
#endif
#if defined(NV_PWM_OPS_STRUCT_HAS_OWNER) /* Linux 6.7 */
.owner = THIS_MODULE,
#endif
};
static int cdi_pwm_probe(struct platform_device *pdev)
{
struct cdi_pwm_info *info = NULL;
struct pwm_chip *chip;
int err = 0, npwm;
bool force_on = false;
dev_info(&pdev->dev, "%sing...\n", __func__);
info = devm_kzalloc(
&pdev->dev, sizeof(struct cdi_pwm_info), GFP_KERNEL);
if (!info)
return -ENOMEM;
atomic_set(&info->in_use, 0);
mutex_init(&info->mutex);
err = of_property_read_u32(pdev->dev.of_node, "npwm", &npwm);
if (err < 0) {
dev_err(&pdev->dev, "npwm is not defined: %d\n", err);
return err;
}
#if defined(NV_PWM_CHIP_STRUCT_HAS_STRUCT_DEVICE)
chip = devm_pwmchip_alloc(&pdev->dev, npwm, sizeof(*info));
if (IS_ERR(chip))
return PTR_ERR(chip);
info = to_cdi_pwm_info(chip);
#else
info = devm_kzalloc(
&pdev->dev, sizeof(struct cdi_pwm_info), GFP_KERNEL);
if (!info)
return -ENOMEM;
chip = &info->chip;
chip->dev = &pdev->dev;
chip->npwm = npwm;
#endif
atomic_set(&info->in_use, 0);
mutex_init(&info->mutex);
force_on = of_property_read_bool(pdev->dev.of_node, "force_on");
chip->ops = &cdi_pwm_ops;
#if defined(NV_PWM_CHIP_STRUCT_HAS_BASE_ARG)
chip->base = -1;
#endif
chip->of_xlate = of_cdi_pwm_xlate;
info->chip.dev = &pdev->dev;
info->chip.ops = &cdi_pwm_ops;
info->chip.base = -1;
info->chip.npwm = npwm;
info->chip.of_xlate = of_cdi_pwm_xlate;
info->chip.of_pwm_n_cells = 2;
info->force_on = force_on;
err = pwmchip_add(chip);
err = pwmchip_add(&info->chip);
if (err < 0) {
dev_err(&pdev->dev, "pwmchip_add() failed: %d\n", err);
return err;
}
platform_set_drvdata(pdev, chip);
platform_set_drvdata(pdev, info);
info->pwm = devm_pwm_get(&pdev->dev, NULL);
if (!IS_ERR(info->pwm)) {
pwm_disable(info->pwm);
dev_info(&pdev->dev, "%s success to get PWM\n", __func__);
} else {
pwmchip_remove(chip);
pwmchip_remove(&info->chip);
err = PTR_ERR(info->pwm);
if (err != -EPROBE_DEFER)
dev_err(&pdev->dev,
@@ -217,24 +190,24 @@ static int cdi_pwm_probe(struct platform_device *pdev)
static int cdi_pwm_remove(struct platform_device *pdev)
{
struct pwm_chip *chip = platform_get_drvdata(pdev);
struct cdi_pwm_info *info = platform_get_drvdata(pdev);
pwmchip_remove(chip);
pwmchip_remove(&info->chip);
return 0;
}
static int cdi_pwm_suspend(struct device *dev)
{
struct pwm_chip *chip = dev_get_drvdata(dev);
struct cdi_pwm_info *info = to_cdi_pwm_info(chip);
int err = 0;
struct cdi_pwm_info *info = dev_get_drvdata(dev);
if (info == NULL) {
dev_err(dev, "%s: fail to get info\n", __func__);
} else {
if (!IS_ERR(info->pwm)) {
pwm_disable(info->pwm);
pwm_config(info->pwm, PWM_SUSPEND_DUTY_RATIO,
err = pwm_config(info->pwm, PWM_SUSPEND_DUTY_RATIO,
PWM_SUSPEND_PERIOD);
}
}

View File

@@ -3,7 +3,12 @@
GCOV_PROFILE := y
LINUX_VERSION := $(shell expr $(VERSION) \* 256 + $(PATCHLEVEL))
LINUX_VERSION_6_3 := $(shell expr 6 \* 256 + 3)
ifneq ($(CONFIG_TEGRA_GPIO_LEGACY_DISABLE),y)
obj-m += isc_gpio.o
obj-m += isc_mgr.o
endif
obj-m += isc_dev.o
obj-m += isc_pwm.o

View File

@@ -1,13 +1,13 @@
/* SPDX-License-Identifier: GPL-2.0-only */
/* SPDX-FileCopyrightText: Copyright (c) 2016-2024 NVIDIA CORPORATION & AFFILIATES. All rights reserved. */
/*
* Copyright (c) 2016-2022, NVIDIA CORPORATION & AFFILIATES. All rights reserved.
*/
#ifndef __ISC_PWM_PRIV_H__
#define __ISC_PWM_PRIV_H__
struct isc_pwm_info {
#if !defined(NV_PWM_CHIP_STRUCT_HAS_STRUCT_DEVICE)
struct pwm_chip chip;
#endif
struct pwm_device *pwm;
atomic_t in_use;
struct mutex mutex;

View File

@@ -1,8 +1,6 @@
// SPDX-License-Identifier: GPL-2.0
// Copyright (c) 2015-2023, NVIDIA CORPORATION & AFFILIATES. All rights reserved.
#include <nvidia/conftest.h>
#include <linux/delay.h>
#include <linux/device.h>
#include <linux/fs.h>
@@ -429,7 +427,7 @@ static const struct file_operations isc_dev_fileops = {
.release = isc_dev_release,
};
#if defined(NV_I2C_DRIVER_STRUCT_PROBE_WITHOUT_I2C_DEVICE_ID_ARG) /* Linux 6.3 */
#if KERNEL_VERSION(6, 3, 0) <= LINUX_VERSION_CODE
static int isc_dev_probe(struct i2c_client *client)
#else
static int isc_dev_probe(struct i2c_client *client,
@@ -514,7 +512,7 @@ static int isc_dev_probe(struct i2c_client *client,
return 0;
}
#if defined(NV_I2C_DRIVER_STRUCT_REMOVE_RETURN_TYPE_INT) /* Linux 6.1 */
#if KERNEL_VERSION(6, 1, 0) > LINUX_VERSION_CODE
static int isc_dev_remove(struct i2c_client *client)
#else
static void isc_dev_remove(struct i2c_client *client)
@@ -535,7 +533,7 @@ static void isc_dev_remove(struct i2c_client *client)
if (info->cdev.dev)
cdev_del(&info->cdev);
#if defined(NV_I2C_DRIVER_STRUCT_REMOVE_RETURN_TYPE_INT) /* Linux 6.1 */
#if KERNEL_VERSION(6, 1, 0) > LINUX_VERSION_CODE
return 0;
#endif
}

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