mirror of
git://nv-tegra.nvidia.com/linux-nv-oot.git
synced 2025-12-24 10:11:26 +03:00
Compare commits
12 Commits
rel-36
...
jetson_36.
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
b27a1a79ee | ||
|
|
e488812038 | ||
|
|
cfe6242c8c | ||
|
|
efa698bed8 | ||
|
|
e7bf6f1444 | ||
|
|
e228deeef1 | ||
|
|
36a712b801 | ||
|
|
087418781c | ||
|
|
fe0a030fee | ||
|
|
7ad4c09866 | ||
|
|
f41b74b8c3 | ||
|
|
ff0c2e64e9 |
25
.gitignore
vendored
25
.gitignore
vendored
@@ -1,25 +0,0 @@
|
||||
# SPDX-FileCopyrightText: Copyright (c) 2024 NVIDIA CORPORATION & AFFILIATES. All rights reserved.
|
||||
# SPDX-License-Identifier: GPL-2.0
|
||||
#
|
||||
# Use command 'git ls-files -i --exclude-standard' to ensure that no
|
||||
# tracked files are ignored.
|
||||
#
|
||||
*.o
|
||||
*.o.*
|
||||
*.a
|
||||
*.s
|
||||
*.ko
|
||||
*.so
|
||||
*.so.dbg
|
||||
*.mod.c
|
||||
*.i
|
||||
*.symtypes
|
||||
*.order
|
||||
*.patch
|
||||
modules.builtin
|
||||
Module.symvers
|
||||
*.dwo
|
||||
*.mod
|
||||
*.cmd
|
||||
*mods.dtb*
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
# SPDX-License-Identifier: GPL-2.0-only
|
||||
# SPDX-FileCopyrightText: Copyright (c) 2022-2025 NVIDIA CORPORATION & AFFILIATES. All rights reserved.
|
||||
# SPDX-FileCopyrightText: Copyright (c) 2022-2024 NVIDIA CORPORATION & AFFILIATES. All rights reserved.
|
||||
|
||||
LINUXINCLUDE += -I$(srctree.nvidia-oot)/include
|
||||
LINUXINCLUDE += -I$(srctree.nvidia-oot)/drivers/gpu/host1x/hw/
|
||||
@@ -12,10 +12,8 @@ ifdef CONFIG_PSTORE
|
||||
obj-m += block/tegra_oops_virt_storage/
|
||||
endif
|
||||
ifdef CONFIG_BT
|
||||
ifneq ($(NV_OOT_BLUETOOTH_REALTEK_SKIP_BUILD),y)
|
||||
obj-m += bluetooth/realtek/
|
||||
endif
|
||||
endif
|
||||
obj-m += c2c/
|
||||
obj-m += clink/
|
||||
obj-m += cpuidle/
|
||||
|
||||
@@ -1,10 +1,8 @@
|
||||
// SPDX-License-Identifier: GPL-2.0-only
|
||||
/*
|
||||
* SPDX-FileCopyrightText: Copyright (c) 2023-2025, NVIDIA CORPORATION & AFFILIATES. All rights reserved.
|
||||
* Copyright (c) 2023, NVIDIA CORPORATION & AFFILIATES. All rights reserved.
|
||||
*/
|
||||
|
||||
#include <nvidia/conftest.h>
|
||||
|
||||
#include <linux/version.h>
|
||||
#include <linux/module.h>
|
||||
#include <linux/moduleparam.h>
|
||||
@@ -804,21 +802,9 @@ static const struct of_device_id tegra_hv_vblk_oops_match[] = {
|
||||
MODULE_DEVICE_TABLE(of, tegra_hv_vblk_oops_match);
|
||||
#endif /* CONFIG_OF */
|
||||
|
||||
#if defined(NV_PLATFORM_DRIVER_STRUCT_REMOVE_RETURNS_VOID) /* Linux v6.11 */
|
||||
static void tegra_hv_vblk_oops_remove_wrapper(struct platform_device *pdev)
|
||||
{
|
||||
tegra_hv_vblk_oops_remove(pdev);
|
||||
}
|
||||
#else
|
||||
static int tegra_hv_vblk_oops_remove_wrapper(struct platform_device *pdev)
|
||||
{
|
||||
return tegra_hv_vblk_oops_remove(pdev);
|
||||
}
|
||||
#endif
|
||||
|
||||
static struct platform_driver tegra_hv_vblk_oops_driver = {
|
||||
.probe = tegra_hv_vblk_oops_probe,
|
||||
.remove = tegra_hv_vblk_oops_remove_wrapper,
|
||||
.remove = tegra_hv_vblk_oops_remove,
|
||||
.driver = {
|
||||
.name = OOPS_DRV_NAME,
|
||||
.owner = THIS_MODULE,
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
# SPDX-License-Identifier: GPL-2.0-only
|
||||
# SPDX-FileCopyrightText: Copyright (c) 2022-2025 NVIDIA CORPORATION & AFFILIATES. All rights reserved.
|
||||
# SPDX-FileCopyrightText: Copyright (c) 2022-2024 NVIDIA CORPORATION & AFFILIATES. All rights reserved.
|
||||
|
||||
#
|
||||
# Makefile for Virtual Storage Driver
|
||||
@@ -8,7 +8,6 @@
|
||||
LINUX_VERSION := $(shell expr $(VERSION) \* 256 + $(PATCHLEVEL))
|
||||
LINUX_VERSION_6_11 := $(shell expr 6 \* 256 + 11)
|
||||
|
||||
ifneq ($(NV_OOT_BLOCK_TEGRA_VIRT_STORAGE_SKIP_BUILD),y)
|
||||
# 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
|
||||
@@ -17,5 +16,4 @@ 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
|
||||
endif
|
||||
endif
|
||||
@@ -1,5 +1,5 @@
|
||||
// SPDX-License-Identifier: GPL-2.0-only
|
||||
// SPDX-FileCopyrightText: Copyright (c) 2022-2025 NVIDIA CORPORATION & AFFILIATES. All rights reserved.
|
||||
// SPDX-FileCopyrightText: Copyright (c) 2022-2024 NVIDIA CORPORATION & AFFILIATES. All rights reserved.
|
||||
|
||||
#include <nvidia/conftest.h>
|
||||
|
||||
@@ -145,11 +145,7 @@ static void vblk_put_req(struct vsc_request *req)
|
||||
(vblkdev->queue_state == VBLK_QUEUE_SUSPENDED)) {
|
||||
complete(&vblkdev->req_queue_empty);
|
||||
}
|
||||
#if defined(NV_TIMER_DELETE_PRESENT) /* Linux v6.15 */
|
||||
timer_delete(&req->timer);
|
||||
#else
|
||||
del_timer(&req->timer);
|
||||
#endif
|
||||
}
|
||||
}
|
||||
|
||||
@@ -538,12 +534,8 @@ static bool submit_bio_req(struct vblk_dev *vblkdev)
|
||||
}
|
||||
sg_init_table(vsc_req->sg_lst,
|
||||
bio_req->nr_phys_segments);
|
||||
#if defined(NV_BLK_RQ_MAP_SG_HAS_NO_QUEUE_ARG) /* Linux v6.15 */
|
||||
sg_cnt = blk_rq_map_sg(bio_req, vsc_req->sg_lst);
|
||||
#else
|
||||
sg_cnt = blk_rq_map_sg(vblkdev->queue, bio_req,
|
||||
vsc_req->sg_lst);
|
||||
#endif
|
||||
vsc_req->sg_num_ents = sg_nents(vsc_req->sg_lst);
|
||||
if (dma_map_sg(vblkdev->device, vsc_req->sg_lst,
|
||||
vsc_req->sg_num_ents, DMA_BIDIRECTIONAL) == 0) {
|
||||
@@ -1571,21 +1563,9 @@ static struct of_device_id tegra_hv_vblk_match[] = {
|
||||
MODULE_DEVICE_TABLE(of, tegra_hv_vblk_match);
|
||||
#endif /* CONFIG_OF */
|
||||
|
||||
#if defined(NV_PLATFORM_DRIVER_STRUCT_REMOVE_RETURNS_VOID) /* Linux v6.11 */
|
||||
static void tegra_hv_vblk_remove_wrapper(struct platform_device *pdev)
|
||||
{
|
||||
tegra_hv_vblk_remove(pdev);
|
||||
}
|
||||
#else
|
||||
static int tegra_hv_vblk_remove_wrapper(struct platform_device *pdev)
|
||||
{
|
||||
return tegra_hv_vblk_remove(pdev);
|
||||
}
|
||||
#endif
|
||||
|
||||
static struct platform_driver tegra_hv_vblk_driver = {
|
||||
.probe = tegra_hv_vblk_probe,
|
||||
.remove = tegra_hv_vblk_remove_wrapper,
|
||||
.remove = tegra_hv_vblk_remove,
|
||||
.driver = {
|
||||
.name = DRV_NAME,
|
||||
.owner = THIS_MODULE,
|
||||
|
||||
@@ -1,15 +1,22 @@
|
||||
ifneq ($(KERNELRELEASE),)
|
||||
obj-m := rtk_btusb.o
|
||||
rtk_btusb-y = rtk_coex.o rtk_misc.o rtk_bt.o
|
||||
else
|
||||
PWD := $(shell pwd)
|
||||
KVER := $(shell uname -r)
|
||||
KDIR := /lib/modules/$(KVER)/build
|
||||
|
||||
all:
|
||||
$(MAKE) -C $(KDIR) M=$(PWD) modules
|
||||
|
||||
clean:
|
||||
rm -rf *.o *.mod.c *.mod.o *.ko *.symvers *.order *.a
|
||||
|
||||
endif
|
||||
# SPDX-License-Identifier: GPL-2.0
|
||||
|
||||
CONFIG_BTUSB_AUTOSUSPEND = n
|
||||
CONFIG_BTUSB_WAKEUP_HOST = n
|
||||
CONFIG_BTCOEX = y
|
||||
|
||||
ifeq ($(CONFIG_BTUSB_AUTOSUSPEND), y)
|
||||
EXTRA_CFLAGS += -DCONFIG_BTUSB_AUTOSUSPEND
|
||||
endif
|
||||
|
||||
ifeq ($(CONFIG_BTUSB_WAKEUP_HOST), y)
|
||||
EXTRA_CFLAGS += -DCONFIG_BTUSB_WAKEUP_HOST
|
||||
endif
|
||||
|
||||
ifeq ($(CONFIG_BTCOEX), y)
|
||||
EXTRA_CFLAGS += -DCONFIG_BTCOEX
|
||||
endif
|
||||
|
||||
obj-m := rtk_btusb.o
|
||||
rtk_btusb-objs := rtk_coex.o \
|
||||
rtk_misc.o \
|
||||
rtk_bt.o
|
||||
|
||||
@@ -1,22 +1,8 @@
|
||||
// SPDX-License-Identifier: GPL-2.0-only
|
||||
/*
|
||||
*
|
||||
* Realtek Bluetooth USB driver
|
||||
*
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
* the Free Software Foundation; either version 2 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program; if not, write to the Free Software
|
||||
* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
|
||||
*
|
||||
*/
|
||||
|
||||
#include <linux/kernel.h>
|
||||
@@ -31,11 +17,12 @@
|
||||
#include <linux/dcache.h>
|
||||
#include <linux/reboot.h>
|
||||
#include <net/sock.h>
|
||||
#include <asm/unaligned.h>
|
||||
|
||||
#include "rtk_bt.h"
|
||||
#include "rtk_misc.h"
|
||||
|
||||
#define VERSION "3.1.65ab490.20240531-141726"
|
||||
#define VERSION "3.1.6fd4e69.20220818-105856"
|
||||
|
||||
#ifdef BTCOEX
|
||||
#include "rtk_coex.h"
|
||||
@@ -48,64 +35,95 @@ static DEFINE_SEMAPHORE(switch_sem);
|
||||
#endif
|
||||
|
||||
#if HCI_VERSION_CODE >= KERNEL_VERSION(3, 7, 1)
|
||||
static bool reset = true;
|
||||
static bool reset = 0;
|
||||
#endif
|
||||
|
||||
static struct usb_driver btusb_driver;
|
||||
#if HCI_VERSION_CODE >= KERNEL_VERSION(5, 6, 0)
|
||||
static u16 iso_min_conn_handle = 0x1b;
|
||||
#endif
|
||||
|
||||
static const struct usb_device_id btusb_table[] = {
|
||||
/* Generic Bluetooth USB device */
|
||||
{ USB_DEVICE_INFO(0xe0, 0x01, 0x01) },
|
||||
|
||||
/* Generic Bluetooth USB interface */
|
||||
{ USB_INTERFACE_INFO(0xe0, 0x01, 0x01) },
|
||||
|
||||
{}
|
||||
};
|
||||
|
||||
static const struct usb_device_id blacklist_table[] = {
|
||||
static struct usb_device_id btusb_table[] = {
|
||||
{
|
||||
.match_flags = USB_DEVICE_ID_MATCH_VENDOR,
|
||||
.match_flags = USB_DEVICE_ID_MATCH_VENDOR |
|
||||
USB_DEVICE_ID_MATCH_INT_INFO,
|
||||
.idVendor = 0x0bda,
|
||||
.bInterfaceClass = 0xe0,
|
||||
.bInterfaceSubClass = 0x01,
|
||||
.bInterfaceProtocol = 0x01
|
||||
}, {
|
||||
.match_flags = USB_DEVICE_ID_MATCH_VENDOR,
|
||||
.match_flags = USB_DEVICE_ID_MATCH_VENDOR |
|
||||
USB_DEVICE_ID_MATCH_INT_INFO,
|
||||
.idVendor = 0x13d3,
|
||||
.bInterfaceClass = 0xe0,
|
||||
.bInterfaceSubClass = 0x01,
|
||||
.bInterfaceProtocol = 0x01
|
||||
}, {
|
||||
.match_flags = USB_DEVICE_ID_MATCH_VENDOR,
|
||||
.match_flags = USB_DEVICE_ID_MATCH_VENDOR |
|
||||
USB_DEVICE_ID_MATCH_INT_INFO,
|
||||
.idVendor = 0x0489,
|
||||
.bInterfaceClass = 0xe0,
|
||||
.bInterfaceSubClass = 0x01,
|
||||
.bInterfaceProtocol = 0x01
|
||||
}, {
|
||||
.match_flags = USB_DEVICE_ID_MATCH_VENDOR,
|
||||
.match_flags = USB_DEVICE_ID_MATCH_VENDOR |
|
||||
USB_DEVICE_ID_MATCH_INT_INFO,
|
||||
.idVendor = 0x1358,
|
||||
.bInterfaceClass = 0xe0,
|
||||
.bInterfaceSubClass = 0x01,
|
||||
.bInterfaceProtocol = 0x01
|
||||
}, {
|
||||
.match_flags = USB_DEVICE_ID_MATCH_VENDOR,
|
||||
.match_flags = USB_DEVICE_ID_MATCH_VENDOR |
|
||||
USB_DEVICE_ID_MATCH_INT_INFO,
|
||||
.idVendor = 0x04ca,
|
||||
.bInterfaceClass = 0xe0,
|
||||
.bInterfaceSubClass = 0x01,
|
||||
.bInterfaceProtocol = 0x01
|
||||
}, {
|
||||
.match_flags = USB_DEVICE_ID_MATCH_VENDOR,
|
||||
.match_flags = USB_DEVICE_ID_MATCH_VENDOR |
|
||||
USB_DEVICE_ID_MATCH_INT_INFO,
|
||||
.idVendor = 0x2ff8,
|
||||
.bInterfaceClass = 0xe0,
|
||||
.bInterfaceSubClass = 0x01,
|
||||
.bInterfaceProtocol = 0x01
|
||||
}, {
|
||||
.match_flags = USB_DEVICE_ID_MATCH_VENDOR,
|
||||
.match_flags = USB_DEVICE_ID_MATCH_VENDOR |
|
||||
USB_DEVICE_ID_MATCH_INT_INFO,
|
||||
.idVendor = 0x0b05,
|
||||
.bInterfaceClass = 0xe0,
|
||||
.bInterfaceSubClass = 0x01,
|
||||
.bInterfaceProtocol = 0x01
|
||||
}, {
|
||||
.match_flags = USB_DEVICE_ID_MATCH_VENDOR,
|
||||
.match_flags = USB_DEVICE_ID_MATCH_VENDOR |
|
||||
USB_DEVICE_ID_MATCH_INT_INFO,
|
||||
.idVendor = 0x0930,
|
||||
.bInterfaceClass = 0xe0,
|
||||
.bInterfaceSubClass = 0x01,
|
||||
.bInterfaceProtocol = 0x01
|
||||
}, {
|
||||
.match_flags = USB_DEVICE_ID_MATCH_VENDOR,
|
||||
.match_flags = USB_DEVICE_ID_MATCH_VENDOR |
|
||||
USB_DEVICE_ID_MATCH_INT_INFO,
|
||||
.idVendor = 0x10ec,
|
||||
.bInterfaceClass = 0xe0,
|
||||
.bInterfaceSubClass = 0x01,
|
||||
.bInterfaceProtocol = 0x01
|
||||
}, {
|
||||
.match_flags = USB_DEVICE_ID_MATCH_VENDOR,
|
||||
.match_flags = USB_DEVICE_ID_MATCH_VENDOR |
|
||||
USB_DEVICE_ID_MATCH_INT_INFO,
|
||||
.idVendor = 0x04c5,
|
||||
.bInterfaceClass = 0xe0,
|
||||
.bInterfaceSubClass = 0x01,
|
||||
.bInterfaceProtocol = 0x01
|
||||
}, {
|
||||
.match_flags = USB_DEVICE_ID_MATCH_VENDOR,
|
||||
.match_flags = USB_DEVICE_ID_MATCH_VENDOR |
|
||||
USB_DEVICE_ID_MATCH_INT_INFO,
|
||||
.idVendor = 0x0cb5,
|
||||
.bInterfaceClass = 0xe0,
|
||||
.bInterfaceSubClass = 0x01,
|
||||
.bInterfaceProtocol = 0x01
|
||||
}, {
|
||||
.match_flags = USB_DEVICE_ID_MATCH_VENDOR,
|
||||
.match_flags = USB_DEVICE_ID_MATCH_VENDOR |
|
||||
USB_DEVICE_ID_MATCH_INT_INFO,
|
||||
.idVendor = 0x0cb8,
|
||||
}, {
|
||||
.match_flags = USB_DEVICE_ID_MATCH_VENDOR,
|
||||
.idVendor = 0x04b8,
|
||||
.bInterfaceClass = 0xe0,
|
||||
.bInterfaceSubClass = 0x01,
|
||||
.bInterfaceProtocol = 0x01
|
||||
}, { }
|
||||
};
|
||||
|
||||
@@ -130,6 +148,20 @@ static struct btusb_data *rtk_alloc(struct usb_interface *intf)
|
||||
|
||||
MODULE_DEVICE_TABLE(usb, btusb_table);
|
||||
|
||||
static int inc_tx(struct btusb_data *data)
|
||||
{
|
||||
unsigned long flags;
|
||||
int rv;
|
||||
|
||||
spin_lock_irqsave(&data->txlock, flags);
|
||||
rv = test_bit(BTUSB_SUSPENDING, &data->flags);
|
||||
if (!rv)
|
||||
data->tx_in_flight++;
|
||||
spin_unlock_irqrestore(&data->txlock, flags);
|
||||
|
||||
return rv;
|
||||
}
|
||||
|
||||
#if HCI_VERSION_CODE >= KERNEL_VERSION(3, 18, 0)
|
||||
static inline void btusb_free_frags(struct btusb_data *data)
|
||||
{
|
||||
@@ -172,11 +204,7 @@ static int btusb_recv_intr(struct btusb_data *data, void *buffer, int count)
|
||||
}
|
||||
|
||||
len = min_t(uint, bt_cb(skb)->expect, count);
|
||||
#if HCI_VERSION_CODE >= KERNEL_VERSION(4, 13, 0)
|
||||
skb_put_data(skb, buffer, len);
|
||||
#else
|
||||
memcpy(skb_put(skb, len), buffer, len);
|
||||
#endif
|
||||
|
||||
count -= len;
|
||||
buffer += len;
|
||||
@@ -231,26 +259,15 @@ static int btusb_recv_bulk(struct btusb_data *data, void *buffer, int count)
|
||||
}
|
||||
|
||||
len = min_t(uint, bt_cb(skb)->expect, count);
|
||||
#if HCI_VERSION_CODE >= KERNEL_VERSION(4, 13, 0)
|
||||
skb_put_data(skb, buffer, len);
|
||||
#else
|
||||
memcpy(skb_put(skb, len), buffer, len);
|
||||
#endif
|
||||
|
||||
count -= len;
|
||||
buffer += len;
|
||||
bt_cb(skb)->expect -= len;
|
||||
|
||||
if (skb->len == HCI_ACL_HDR_SIZE) {
|
||||
struct hci_acl_hdr *h = hci_acl_hdr(skb);
|
||||
__le16 dlen = h->dlen;
|
||||
#if HCI_VERSION_CODE >= KERNEL_VERSION(5, 6, 0)
|
||||
__u16 handle = __le16_to_cpu(h->handle) & 0xfff;
|
||||
__le16 dlen = hci_acl_hdr(skb)->dlen;
|
||||
|
||||
if(handle >= iso_min_conn_handle) {
|
||||
bt_cb(skb)->pkt_type = HCI_ISODATA_PKT;
|
||||
}
|
||||
#endif
|
||||
/* Complete ACL header */
|
||||
bt_cb(skb)->expect = __le16_to_cpu(dlen);
|
||||
|
||||
@@ -276,42 +293,10 @@ static int btusb_recv_bulk(struct btusb_data *data, void *buffer, int count)
|
||||
return err;
|
||||
}
|
||||
|
||||
#if HCI_VERSION_CODE >= KERNEL_VERSION(5, 8, 0)
|
||||
static int btrtl_usb_recv_isoc(u16 pos, u8 *data, u8 *p, int len,
|
||||
u16 wMaxPacketSize)
|
||||
{
|
||||
u8 *prev;
|
||||
|
||||
if (pos >= HCI_SCO_HDR_SIZE && pos >= wMaxPacketSize &&
|
||||
len == wMaxPacketSize && !(pos % wMaxPacketSize) &&
|
||||
wMaxPacketSize >= 10 && p[0] == data[0] && p[1] == data[1]) {
|
||||
|
||||
prev = data + (pos - wMaxPacketSize);
|
||||
|
||||
/* Detect the sco data of usb isoc pkt duplication. */
|
||||
if (!memcmp(p + 2, prev + 2, 8))
|
||||
return -EILSEQ;
|
||||
|
||||
if (wMaxPacketSize >= 12 &&
|
||||
p[2] == prev[6] && p[3] == prev[7] &&
|
||||
p[4] == prev[4] && p[5] == prev[5] &&
|
||||
p[6] == prev[10] && p[7] == prev[11] &&
|
||||
p[8] == prev[8] && p[9] == prev[9]) {
|
||||
return -EILSEQ;
|
||||
}
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
#endif
|
||||
|
||||
static int btusb_recv_isoc(struct btusb_data *data, void *buffer, int count)
|
||||
{
|
||||
struct sk_buff *skb;
|
||||
int err = 0;
|
||||
#if HCI_VERSION_CODE >= KERNEL_VERSION(5, 8, 0)
|
||||
u16 wMaxPacketSize = le16_to_cpu(data->isoc_rx_ep->wMaxPacketSize);
|
||||
#endif
|
||||
|
||||
spin_lock(&data->rxlock);
|
||||
skb = data->sco_skb;
|
||||
@@ -331,24 +316,7 @@ static int btusb_recv_isoc(struct btusb_data *data, void *buffer, int count)
|
||||
}
|
||||
|
||||
len = min_t(uint, bt_cb(skb)->expect, count);
|
||||
|
||||
#if HCI_VERSION_CODE >= KERNEL_VERSION(5, 8, 0)
|
||||
/* Gaps in audio could be heard while streaming WBS using USB
|
||||
* alt settings 3 on some platforms.
|
||||
* Add the function to detect it.
|
||||
*/
|
||||
if (test_bit(BTUSB_USE_ALT3_FOR_WBS, &data->flags)) {
|
||||
err = btrtl_usb_recv_isoc(skb->len, skb->data, buffer,
|
||||
len, wMaxPacketSize);
|
||||
if (err)
|
||||
break;
|
||||
}
|
||||
#endif
|
||||
#if HCI_VERSION_CODE >= KERNEL_VERSION(4, 13, 0)
|
||||
skb_put_data(skb, buffer, len);
|
||||
#else
|
||||
memcpy(skb_put(skb, len), buffer, len);
|
||||
#endif
|
||||
|
||||
count -= len;
|
||||
buffer += len;
|
||||
@@ -379,21 +347,6 @@ static int btusb_recv_isoc(struct btusb_data *data, void *buffer, int count)
|
||||
|
||||
return err;
|
||||
}
|
||||
#else
|
||||
static int inc_tx(struct btusb_data *data)
|
||||
{
|
||||
unsigned long flags;
|
||||
int rv;
|
||||
|
||||
spin_lock_irqsave(&data->txlock, flags);
|
||||
rv = test_bit(BTUSB_SUSPENDING, &data->flags);
|
||||
if (!rv)
|
||||
data->tx_in_flight++;
|
||||
spin_unlock_irqrestore(&data->txlock, flags);
|
||||
|
||||
return rv;
|
||||
}
|
||||
|
||||
#endif
|
||||
|
||||
static void btusb_intr_complete(struct urb *urb)
|
||||
@@ -673,51 +626,6 @@ retry:
|
||||
}
|
||||
}
|
||||
|
||||
#if HCI_VERSION_CODE >= KERNEL_VERSION(5, 8, 0)
|
||||
static inline void __fill_isoc_descriptor_msbc(struct urb *urb, int len,
|
||||
int mtu, struct btusb_data *data)
|
||||
{
|
||||
int i = 0, offset = 0;
|
||||
unsigned int interval;
|
||||
|
||||
BT_DBG("len %d mtu %d", len, mtu);
|
||||
|
||||
/* For mSBC ALT 6 settings some Realtek chips need to transmit the data
|
||||
* continuously without the zero length of USB packets.
|
||||
*/
|
||||
if (btrealtek_test_flag(data->hdev, REALTEK_ALT6_CONTINUOUS_TX_CHIP))
|
||||
goto ignore_usb_alt6_packet_flow;
|
||||
|
||||
/* For mSBC ALT 6 setting the host will send the packet at continuous
|
||||
* flow. As per core spec 5, vol 4, part B, table 2.1. For ALT setting
|
||||
* 6 the HCI PACKET INTERVAL should be 7.5ms for every usb packets.
|
||||
* To maintain the rate we send 63bytes of usb packets alternatively for
|
||||
* 7ms and 8ms to maintain the rate as 7.5ms.
|
||||
*/
|
||||
if (data->usb_alt6_packet_flow) {
|
||||
interval = 7;
|
||||
data->usb_alt6_packet_flow = false;
|
||||
} else {
|
||||
interval = 6;
|
||||
data->usb_alt6_packet_flow = true;
|
||||
}
|
||||
|
||||
for (i = 0; i < interval; i++) {
|
||||
urb->iso_frame_desc[i].offset = offset;
|
||||
urb->iso_frame_desc[i].length = offset;
|
||||
}
|
||||
|
||||
ignore_usb_alt6_packet_flow:
|
||||
if (len && i < BTUSB_MAX_ISOC_FRAMES) {
|
||||
urb->iso_frame_desc[i].offset = offset;
|
||||
urb->iso_frame_desc[i].length = len;
|
||||
i++;
|
||||
}
|
||||
|
||||
urb->number_of_packets = i;
|
||||
}
|
||||
#endif
|
||||
|
||||
static inline void __fill_isoc_descriptor(struct urb *urb, int len, int mtu)
|
||||
{
|
||||
int i, offset = 0;
|
||||
@@ -767,12 +675,6 @@ static int btusb_submit_isoc_urb(struct hci_dev *hdev, gfp_t mem_flags)
|
||||
|
||||
pipe = usb_rcvisocpipe(data->udev, data->isoc_rx_ep->bEndpointAddress);
|
||||
|
||||
#if HCI_VERSION_CODE >= KERNEL_VERSION(3, 2, 14)
|
||||
usb_fill_int_urb(urb, data->udev, pipe, buf, size, btusb_isoc_complete,
|
||||
hdev, data->isoc_rx_ep->bInterval);
|
||||
|
||||
urb->transfer_flags = URB_FREE_BUFFER | URB_ISO_ASAP;
|
||||
#else
|
||||
urb->dev = data->udev;
|
||||
urb->pipe = pipe;
|
||||
urb->context = hdev;
|
||||
@@ -782,7 +684,6 @@ static int btusb_submit_isoc_urb(struct hci_dev *hdev, gfp_t mem_flags)
|
||||
urb->transfer_flags = URB_FREE_BUFFER | URB_ISO_ASAP;
|
||||
urb->transfer_buffer = buf;
|
||||
urb->transfer_buffer_length = size;
|
||||
#endif
|
||||
|
||||
__fill_isoc_descriptor(urb, size,
|
||||
le16_to_cpu(data->isoc_rx_ep->wMaxPacketSize));
|
||||
@@ -833,8 +734,8 @@ static void btusb_isoc_tx_complete(struct urb *urb)
|
||||
struct sk_buff *skb = urb->context;
|
||||
struct hci_dev *hdev = (struct hci_dev *)skb->dev;
|
||||
|
||||
RTKBT_DBG("%s: urb %p status %d count %d", __func__,
|
||||
urb, urb->status, urb->actual_length);
|
||||
RTKBT_DBG("%s: urb %p status %d count %d",__func__,
|
||||
urb, urb->status, urb->actual_length);
|
||||
|
||||
if (!test_bit(HCI_RUNNING, &hdev->flags))
|
||||
goto done;
|
||||
@@ -850,49 +751,6 @@ done:
|
||||
kfree_skb(skb);
|
||||
}
|
||||
|
||||
#if HCI_VERSION_CODE >= KERNEL_VERSION(5, 6, 0)
|
||||
static int rtl_read_iso_handle_range(struct hci_dev *hdev)
|
||||
{
|
||||
struct sk_buff *skb;
|
||||
struct __rp {
|
||||
u8 status;
|
||||
u8 min_handle[2];
|
||||
} *rp;
|
||||
int ret = -EIO;
|
||||
|
||||
skb = __hci_cmd_sync(hdev, 0xfdab, 0, NULL, HCI_CMD_TIMEOUT);
|
||||
if (IS_ERR(skb)) {
|
||||
return PTR_ERR(skb);
|
||||
}
|
||||
|
||||
/* FIXME: if the return status is not zero, __hci_cmd_sync() would
|
||||
* return an error and we would not reach here.
|
||||
*/
|
||||
if (skb->data[0]) {
|
||||
RTKBT_ERR("%s: Read failed, status %0x", hdev->name,
|
||||
skb->data[0]);
|
||||
goto err;
|
||||
}
|
||||
|
||||
if (skb->len < sizeof(*rp)) {
|
||||
RTKBT_WARN("%s: The len %u of rp is too short", __func__,
|
||||
skb->len);
|
||||
goto err;
|
||||
}
|
||||
|
||||
rp = (void *)skb->data;
|
||||
iso_min_conn_handle = (u16)rp->min_handle[1] << 8 | rp->min_handle[0];
|
||||
RTKBT_DBG("ISO handle range (handle >= %04x)", iso_min_conn_handle);
|
||||
|
||||
kfree_skb(skb);
|
||||
|
||||
return 0;
|
||||
err:
|
||||
kfree_skb(skb);
|
||||
return ret;
|
||||
}
|
||||
#endif
|
||||
|
||||
static int btusb_open(struct hci_dev *hdev)
|
||||
{
|
||||
struct btusb_data *data = GET_DRV_DATA(hdev);
|
||||
@@ -917,10 +775,6 @@ static int btusb_open(struct hci_dev *hdev)
|
||||
goto failed;
|
||||
/*******************************/
|
||||
|
||||
err = setup_btrealtek_flag(data->intf, hdev);
|
||||
if (err < 0)
|
||||
RTKBT_WARN("setup_btrealtek_flag incorrect!");
|
||||
|
||||
RTKBT_INFO("%s set HCI UP RUNNING", __func__);
|
||||
if (test_and_set_bit(HCI_UP, &hdev->flags))
|
||||
goto done;
|
||||
@@ -963,32 +817,6 @@ failed:
|
||||
return err;
|
||||
}
|
||||
|
||||
#if HCI_VERSION_CODE >= KERNEL_VERSION(5, 6, 0)
|
||||
static int btusb_setup(struct hci_dev *hdev)
|
||||
{
|
||||
rtl_read_iso_handle_range(hdev);
|
||||
return 0;
|
||||
}
|
||||
#endif
|
||||
|
||||
#if HCI_VERSION_CODE >= KERNEL_VERSION(4, 1, 0)
|
||||
static int btusb_shutdown(struct hci_dev *hdev)
|
||||
{
|
||||
struct sk_buff *skb;
|
||||
int ret;
|
||||
|
||||
skb = __hci_cmd_sync(hdev, HCI_OP_RESET, 0, NULL, HCI_INIT_TIMEOUT);
|
||||
if (IS_ERR(skb)) {
|
||||
ret = PTR_ERR(skb);
|
||||
bt_dev_err(hdev, "HCI reset during shutdown failed");
|
||||
return ret;
|
||||
}
|
||||
kfree_skb(skb);
|
||||
|
||||
return 0;
|
||||
}
|
||||
#endif
|
||||
|
||||
static void btusb_stop_traffic(struct btusb_data *data)
|
||||
{
|
||||
mdelay(URB_CANCELING_DELAY_MS); // Added by Realtek
|
||||
@@ -1092,152 +920,8 @@ static const char pkt_ind[][8] = {
|
||||
[HCI_COMMAND_PKT] = "cmd",
|
||||
[HCI_ACLDATA_PKT] = "acl",
|
||||
[HCI_SCODATA_PKT] = "sco",
|
||||
#if HCI_VERSION_CODE >= KERNEL_VERSION(5, 6, 0)
|
||||
[HCI_ISODATA_PKT] = "iso",
|
||||
#endif
|
||||
};
|
||||
|
||||
#if HCI_VERSION_CODE >= KERNEL_VERSION(3, 18, 0)
|
||||
static struct urb *alloc_ctrl_urb(struct hci_dev *hdev, struct sk_buff *skb)
|
||||
{
|
||||
struct btusb_data *data = hci_get_drvdata(hdev);
|
||||
struct usb_ctrlrequest *dr;
|
||||
struct urb *urb;
|
||||
unsigned int pipe;
|
||||
|
||||
urb = usb_alloc_urb(0, GFP_KERNEL);
|
||||
if (!urb)
|
||||
return ERR_PTR(-ENOMEM);
|
||||
|
||||
dr = kmalloc(sizeof(*dr), GFP_KERNEL);
|
||||
if (!dr) {
|
||||
usb_free_urb(urb);
|
||||
return ERR_PTR(-ENOMEM);
|
||||
}
|
||||
|
||||
dr->bRequestType = data->cmdreq_type;
|
||||
dr->bRequest = 0;
|
||||
dr->wIndex = 0;
|
||||
dr->wValue = 0;
|
||||
dr->wLength = __cpu_to_le16(skb->len);
|
||||
|
||||
pipe = usb_sndctrlpipe(data->udev, 0x00);
|
||||
|
||||
usb_fill_control_urb(urb, data->udev, pipe, (void *)dr,
|
||||
skb->data, skb->len, btusb_tx_complete, skb);
|
||||
|
||||
skb->dev = (void *)hdev;
|
||||
|
||||
return urb;
|
||||
}
|
||||
|
||||
static struct urb *alloc_bulk_urb(struct hci_dev *hdev, struct sk_buff *skb)
|
||||
{
|
||||
struct btusb_data *data = hci_get_drvdata(hdev);
|
||||
struct urb *urb;
|
||||
unsigned int pipe;
|
||||
|
||||
if (!data->bulk_tx_ep)
|
||||
return ERR_PTR(-ENODEV);
|
||||
|
||||
urb = usb_alloc_urb(0, GFP_KERNEL);
|
||||
if (!urb)
|
||||
return ERR_PTR(-ENOMEM);
|
||||
|
||||
pipe = usb_sndbulkpipe(data->udev, data->bulk_tx_ep->bEndpointAddress);
|
||||
|
||||
usb_fill_bulk_urb(urb, data->udev, pipe,
|
||||
skb->data, skb->len, btusb_tx_complete, skb);
|
||||
|
||||
skb->dev = (void *)hdev;
|
||||
|
||||
return urb;
|
||||
}
|
||||
|
||||
static struct urb *alloc_isoc_urb(struct hci_dev *hdev, struct sk_buff *skb)
|
||||
{
|
||||
struct btusb_data *data = hci_get_drvdata(hdev);
|
||||
struct urb *urb;
|
||||
unsigned int pipe;
|
||||
|
||||
if (!data->isoc_tx_ep)
|
||||
return ERR_PTR(-ENODEV);
|
||||
|
||||
urb = usb_alloc_urb(BTUSB_MAX_ISOC_FRAMES, GFP_KERNEL);
|
||||
if (!urb)
|
||||
return ERR_PTR(-ENOMEM);
|
||||
|
||||
pipe = usb_sndisocpipe(data->udev, data->isoc_tx_ep->bEndpointAddress);
|
||||
|
||||
usb_fill_int_urb(urb, data->udev, pipe,
|
||||
skb->data, skb->len, btusb_isoc_tx_complete,
|
||||
skb, data->isoc_tx_ep->bInterval);
|
||||
|
||||
urb->transfer_flags = URB_ISO_ASAP;
|
||||
|
||||
#if HCI_VERSION_CODE >= KERNEL_VERSION(5, 8, 0)
|
||||
if (data->isoc_altsetting == 6)
|
||||
__fill_isoc_descriptor_msbc(urb, skb->len,
|
||||
le16_to_cpu(data->isoc_tx_ep->wMaxPacketSize),
|
||||
data);
|
||||
else
|
||||
__fill_isoc_descriptor(urb, skb->len,
|
||||
le16_to_cpu(data->isoc_tx_ep->wMaxPacketSize));
|
||||
#else
|
||||
__fill_isoc_descriptor(urb, skb->len,
|
||||
le16_to_cpu(data->isoc_tx_ep->wMaxPacketSize));
|
||||
#endif
|
||||
|
||||
skb->dev = (void *)hdev;
|
||||
|
||||
return urb;
|
||||
}
|
||||
|
||||
static int submit_tx_urb(struct hci_dev *hdev, struct urb *urb)
|
||||
{
|
||||
struct btusb_data *data = hci_get_drvdata(hdev);
|
||||
int err;
|
||||
|
||||
usb_anchor_urb(urb, &data->tx_anchor);
|
||||
|
||||
err = usb_submit_urb(urb, GFP_KERNEL);
|
||||
if (err < 0) {
|
||||
if (err != -EPERM && err != -ENODEV)
|
||||
RTKBT_ERR("%s urb %p submission failed (%d)",
|
||||
hdev->name, urb, -err);
|
||||
kfree(urb->setup_packet);
|
||||
usb_unanchor_urb(urb);
|
||||
} else {
|
||||
usb_mark_last_busy(data->udev);
|
||||
}
|
||||
|
||||
usb_free_urb(urb);
|
||||
return err;
|
||||
}
|
||||
|
||||
static int submit_or_queue_tx_urb(struct hci_dev *hdev, struct urb *urb)
|
||||
{
|
||||
struct btusb_data *data = hci_get_drvdata(hdev);
|
||||
unsigned long flags;
|
||||
bool suspending;
|
||||
|
||||
spin_lock_irqsave(&data->txlock, flags);
|
||||
suspending = test_bit(BTUSB_SUSPENDING, &data->flags);
|
||||
if (!suspending)
|
||||
data->tx_in_flight++;
|
||||
spin_unlock_irqrestore(&data->txlock, flags);
|
||||
|
||||
if (!suspending)
|
||||
return submit_tx_urb(hdev, urb);
|
||||
|
||||
usb_anchor_urb(urb, &data->deferred);
|
||||
schedule_work(&data->waker);
|
||||
|
||||
usb_free_urb(urb);
|
||||
return 0;
|
||||
}
|
||||
|
||||
#endif
|
||||
#if HCI_VERSION_CODE >= KERNEL_VERSION(3, 13, 0)
|
||||
int btusb_send_frame(struct hci_dev *hdev, struct sk_buff *skb)
|
||||
{
|
||||
@@ -1247,20 +931,14 @@ int btusb_send_frame(struct sk_buff *skb)
|
||||
struct hci_dev *hdev = (struct hci_dev *)skb->dev;
|
||||
#endif
|
||||
|
||||
struct urb *urb;
|
||||
#if HCI_VERSION_CODE < KERNEL_VERSION(3, 18, 0)
|
||||
struct btusb_data *data = GET_DRV_DATA(hdev);
|
||||
struct usb_ctrlrequest *dr;
|
||||
struct urb *urb;
|
||||
unsigned int pipe;
|
||||
int err;
|
||||
#endif
|
||||
|
||||
// RTKBT_DBG("%s", hdev->name);
|
||||
//RTKBT_DBG("%s", hdev->name);
|
||||
|
||||
/* After Kernel version 4.4.0, move the check into the
|
||||
* hci_send_frame function before calling hdev->send
|
||||
*/
|
||||
#if HCI_VERSION_CODE < KERNEL_VERSION(4, 4, 0)
|
||||
if (!test_bit(HCI_RUNNING, &hdev->flags)) {
|
||||
/* If the parameter is wrong, the hdev isn't the correct
|
||||
* one. Then no HCI commands can be sent.
|
||||
@@ -1268,15 +946,13 @@ int btusb_send_frame(struct sk_buff *skb)
|
||||
RTKBT_ERR("HCI is not running");
|
||||
return -EBUSY;
|
||||
}
|
||||
#endif
|
||||
|
||||
/* Before kernel/hci version 3.13.0, the skb->dev is set before
|
||||
* entering btusb_send_frame(). So there is no need to set it here.
|
||||
*
|
||||
* The skb->dev will be used in the callbacks when urb transfer
|
||||
* completes. See btusb_tx_complete() and btusb_isoc_tx_complete() */
|
||||
#if HCI_VERSION_CODE >= KERNEL_VERSION(3, 13, 0) && \
|
||||
HCI_VERSION_CODE < KERNEL_VERSION(3, 18, 0)
|
||||
#if HCI_VERSION_CODE >= KERNEL_VERSION(3, 13, 0)
|
||||
skb->dev = (void *)hdev;
|
||||
#endif
|
||||
|
||||
@@ -1287,14 +963,6 @@ int btusb_send_frame(struct sk_buff *skb)
|
||||
#ifdef BTCOEX
|
||||
rtk_btcoex_parse_cmd(skb->data, skb->len);
|
||||
#endif
|
||||
#if HCI_VERSION_CODE >= KERNEL_VERSION(3, 18, 0)
|
||||
urb = alloc_ctrl_urb(hdev, skb);
|
||||
if (IS_ERR(urb))
|
||||
return PTR_ERR(urb);
|
||||
|
||||
hdev->stat.cmd_tx++;
|
||||
return submit_or_queue_tx_urb(hdev, urb);
|
||||
#else
|
||||
urb = usb_alloc_urb(0, GFP_ATOMIC);
|
||||
if (!urb)
|
||||
return -ENOMEM;
|
||||
@@ -1320,24 +988,11 @@ int btusb_send_frame(struct sk_buff *skb)
|
||||
hdev->stat.cmd_tx++;
|
||||
break;
|
||||
|
||||
#endif
|
||||
#if HCI_VERSION_CODE >= KERNEL_VERSION(5, 6, 0)
|
||||
case HCI_ISODATA_PKT:
|
||||
#endif
|
||||
case HCI_ACLDATA_PKT:
|
||||
print_acl(skb, 1);
|
||||
#ifdef BTCOEX
|
||||
if(bt_cb(skb)->pkt_type == HCI_ACLDATA_PKT)
|
||||
rtk_btcoex_parse_l2cap_data_tx(skb->data, skb->len);
|
||||
rtk_btcoex_parse_l2cap_data_tx(skb->data, skb->len);
|
||||
#endif
|
||||
#if HCI_VERSION_CODE >= KERNEL_VERSION(3, 18, 0)
|
||||
urb = alloc_bulk_urb(hdev, skb);
|
||||
if (IS_ERR(urb))
|
||||
return PTR_ERR(urb);
|
||||
|
||||
hdev->stat.acl_tx++;
|
||||
return submit_or_queue_tx_urb(hdev, urb);
|
||||
#else
|
||||
if (!data->bulk_tx_ep)
|
||||
return -ENODEV;
|
||||
|
||||
@@ -1354,22 +1009,7 @@ int btusb_send_frame(struct sk_buff *skb)
|
||||
hdev->stat.acl_tx++;
|
||||
break;
|
||||
|
||||
#endif
|
||||
case HCI_SCODATA_PKT:
|
||||
#if HCI_VERSION_CODE >= KERNEL_VERSION(3, 18, 0)
|
||||
if (hci_conn_num(hdev, SCO_LINK) < 1)
|
||||
return -ENODEV;
|
||||
|
||||
urb = alloc_isoc_urb(hdev, skb);
|
||||
if (IS_ERR(urb))
|
||||
return PTR_ERR(urb);
|
||||
|
||||
hdev->stat.sco_tx++;
|
||||
return submit_tx_urb(hdev, urb);
|
||||
}
|
||||
|
||||
return -EILSEQ;
|
||||
#else
|
||||
if (!data->isoc_tx_ep || SCO_NUM < 1)
|
||||
return -ENODEV;
|
||||
|
||||
@@ -1395,7 +1035,6 @@ int btusb_send_frame(struct sk_buff *skb)
|
||||
|
||||
default:
|
||||
return -EILSEQ;
|
||||
|
||||
}
|
||||
|
||||
err = inc_tx(data);
|
||||
@@ -1418,14 +1057,12 @@ skip_waking:
|
||||
} else {
|
||||
usb_mark_last_busy(data->udev);
|
||||
}
|
||||
usb_free_urb(urb);
|
||||
|
||||
done:
|
||||
usb_free_urb(urb);
|
||||
return err;
|
||||
#endif
|
||||
}
|
||||
|
||||
|
||||
#if HCI_VERSION_CODE < KERNEL_VERSION(3, 4, 0)
|
||||
static void btusb_destruct(struct hci_dev *hdev)
|
||||
{
|
||||
@@ -1544,9 +1181,6 @@ static struct usb_host_interface *btusb_find_altsetting(struct btusb_data *data,
|
||||
|
||||
BT_DBG("Looking for Alt no :%d", alt);
|
||||
|
||||
if (!intf)
|
||||
return NULL;
|
||||
|
||||
for (i = 0; i < intf->num_altsetting; i++) {
|
||||
if (intf->altsetting[i].desc.bAlternateSetting == alt)
|
||||
return &intf->altsetting[i];
|
||||
@@ -1587,14 +1221,7 @@ static void btusb_work(struct work_struct *work)
|
||||
new_alts = data->sco_num;
|
||||
}
|
||||
} else if (data->air_mode == HCI_NOTIFY_ENABLE_SCO_TRANSP) {
|
||||
if (btusb_find_altsetting(data, 6))
|
||||
new_alts = 6;
|
||||
else if (btusb_find_altsetting(data, 3) &&
|
||||
hdev->sco_mtu >= 72 &&
|
||||
test_bit(BTUSB_USE_ALT3_FOR_WBS, &data->flags))
|
||||
new_alts = 3;
|
||||
else
|
||||
new_alts = 1;
|
||||
new_alts = btusb_find_altsetting(data, 6) ? 6 : 1;
|
||||
}
|
||||
|
||||
if (btusb_switch_alt_setting(hdev, new_alts) < 0)
|
||||
@@ -1794,7 +1421,7 @@ static int rtkbt_pm_notify(struct notifier_block *notifier,
|
||||
result = __rtk_send_hci_cmd(udev, cmd, 3);
|
||||
kfree(cmd);
|
||||
msleep(100); /* From FW colleague's recommendation */
|
||||
result = download_special_patch(intf, "lps_");
|
||||
result = download_lps_patch(intf);
|
||||
#endif
|
||||
|
||||
#ifdef RTKBT_TV_POWERON_WHITELIST
|
||||
@@ -1913,23 +1540,13 @@ static int btusb_probe(struct usb_interface *intf,
|
||||
struct usb_device *udev;
|
||||
udev = interface_to_usbdev(intf);
|
||||
|
||||
RTKBT_INFO("btusb_probe intf->cur_altsetting->desc.bInterfaceNumber %d",
|
||||
RTKBT_DBG("btusb_probe intf->cur_altsetting->desc.bInterfaceNumber %d",
|
||||
intf->cur_altsetting->desc.bInterfaceNumber);
|
||||
|
||||
/* interface numbers are hardcoded in the spec */
|
||||
if (intf->cur_altsetting->desc.bInterfaceNumber != 0)
|
||||
return -ENODEV;
|
||||
|
||||
if (!id->driver_info) {
|
||||
const struct usb_device_id *match;
|
||||
|
||||
match = usb_match_id(intf, blacklist_table);
|
||||
if (match)
|
||||
id = match;
|
||||
else
|
||||
return -ENODEV;
|
||||
}
|
||||
|
||||
/*******************************/
|
||||
flag1 = device_can_wakeup(&udev->dev);
|
||||
flag2 = device_may_wakeup(&udev->dev);
|
||||
@@ -2019,13 +1636,6 @@ static int btusb_probe(struct usb_interface *intf,
|
||||
hdev->flush = btusb_flush;
|
||||
hdev->send = btusb_send_frame;
|
||||
hdev->notify = btusb_notify;
|
||||
#if HCI_VERSION_CODE >= KERNEL_VERSION(5, 6, 0)
|
||||
hdev->setup = btusb_setup;
|
||||
#endif
|
||||
|
||||
#if HCI_VERSION_CODE >= KERNEL_VERSION(4, 1, 0)
|
||||
hdev->shutdown = btusb_shutdown;
|
||||
#endif
|
||||
|
||||
#if HCI_VERSION_CODE >= KERNEL_VERSION(3, 4, 0)
|
||||
hci_set_drvdata(hdev, data);
|
||||
@@ -2035,14 +1645,10 @@ static int btusb_probe(struct usb_interface *intf,
|
||||
hdev->owner = THIS_MODULE;
|
||||
#endif
|
||||
|
||||
#if HCI_VERSION_CODE >= KERNEL_VERSION(5, 8, 0)
|
||||
set_bit(BTUSB_USE_ALT3_FOR_WBS, &data->flags);
|
||||
set_bit(HCI_QUIRK_WIDEBAND_SPEECH_SUPPORTED, &hdev->quirks);
|
||||
#endif
|
||||
|
||||
#if HCI_VERSION_CODE >= KERNEL_VERSION(3, 7, 1)
|
||||
if (!reset)
|
||||
set_bit(HCI_QUIRK_RESET_ON_CLOSE, &hdev->quirks);
|
||||
RTKBT_DBG("set_bit(HCI_QUIRK_RESET_ON_CLOSE, &hdev->quirks);");
|
||||
#endif
|
||||
|
||||
/* Interface numbers are hardcoded in the specification */
|
||||
|
||||
@@ -1,23 +1,12 @@
|
||||
// SPDX-License-Identifier: GPL-2.0-only
|
||||
/*
|
||||
*
|
||||
* Realtek Bluetooth USB driver
|
||||
*
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
* the Free Software Foundation; either version 2 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program; if not, write to the Free Software
|
||||
* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
|
||||
*
|
||||
*/
|
||||
#ifndef __RTK_BT_H__
|
||||
#define __RTK_BT_H__
|
||||
|
||||
#include <linux/interrupt.h>
|
||||
#include <linux/module.h>
|
||||
#include <linux/slab.h>
|
||||
@@ -41,17 +30,14 @@
|
||||
/* #define HCI_VERSION_CODE KERNEL_VERSION(3, 14, 41) */
|
||||
#define HCI_VERSION_CODE LINUX_VERSION_CODE
|
||||
|
||||
#define CONFIG_BTCOEX 1
|
||||
#define CONFIG_BTUSB_WAKEUP_HOST 0
|
||||
|
||||
#if CONFIG_BTCOEX
|
||||
#ifdef CONFIG_BTCOEX
|
||||
#define BTCOEX
|
||||
#endif
|
||||
|
||||
/***********************************
|
||||
** Realtek - For rtk_btusb driver **
|
||||
***********************************/
|
||||
#if CONFIG_BTUSB_WAKEUP_HOST
|
||||
#ifdef CONFIG_BTUSB_WAKEUP_HOST
|
||||
#define BTUSB_WAKEUP_HOST
|
||||
#endif
|
||||
|
||||
@@ -98,7 +84,6 @@ int btusb_send_frame(struct sk_buff *skb);
|
||||
#define BTUSB_ISOC_RUNNING 2
|
||||
#define BTUSB_SUSPENDING 3
|
||||
#define BTUSB_DID_ISO_RESUME 4
|
||||
#define BTUSB_USE_ALT3_FOR_WBS 15
|
||||
|
||||
struct btusb_data {
|
||||
struct hci_dev *hdev;
|
||||
@@ -140,7 +125,6 @@ struct btusb_data {
|
||||
|
||||
#if HCI_VERSION_CODE >= KERNEL_VERSION(5, 8, 0)
|
||||
unsigned int air_mode;
|
||||
bool usb_alt6_packet_flow;
|
||||
#endif
|
||||
int isoc_altsetting;
|
||||
int suspend_count;
|
||||
@@ -152,3 +136,6 @@ struct btusb_data {
|
||||
struct notifier_block shutdown_notifier;
|
||||
void *context;
|
||||
};
|
||||
|
||||
|
||||
#endif /* __RTK_BT_H__ */
|
||||
File diff suppressed because it is too large
Load Diff
@@ -1,23 +1,12 @@
|
||||
// SPDX-License-Identifier: GPL-2.0-only
|
||||
/*
|
||||
*
|
||||
* Realtek Bluetooth USB driver
|
||||
*
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
* the Free Software Foundation; either version 2 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program; if not, write to the Free Software
|
||||
* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
|
||||
*
|
||||
*/
|
||||
#ifndef __RTK_COEX_H__
|
||||
#define __RTK_COEX_H__
|
||||
|
||||
#include <net/bluetooth/hci_core.h>
|
||||
#include <linux/list.h>
|
||||
|
||||
@@ -49,13 +38,6 @@
|
||||
#define HCI_EV_LE_CONN_UPDATE_COMPLETE 0x03
|
||||
#define HCI_EV_LE_ENHANCED_CONN_COMPLETE 0x0a
|
||||
|
||||
#define HCI_EV_LE_CIS_EST 0x19
|
||||
#define HCI_EV_LE_CREATE_BIG_CPL 0x1b
|
||||
#define HCI_EV_LE_TERM_BIG_CPL 0x1c
|
||||
#define HCI_EV_LE_BIG_SYNC_EST 0x1d
|
||||
#define HCI_EV_LE_BIG_SYNC_LOST 0x1e
|
||||
#define HCI_EV_LE_REMOVE_ISO_DATA_PATH 0x23
|
||||
|
||||
//vendor cmd to fw
|
||||
#define HCI_VENDOR_ENABLE_PROFILE_REPORT_COMMAND 0xfc18
|
||||
#define HCI_VENDOR_SET_PROFILE_REPORT_LEGACY_COMMAND 0xfc19
|
||||
@@ -158,11 +140,7 @@ enum {
|
||||
profile_hogp = 5,
|
||||
profile_voice = 6,
|
||||
profile_sink = 7,
|
||||
profile_lea_src = 8,
|
||||
profile_opprx = 9,
|
||||
profile_lea_snk = 10,
|
||||
profile_a2dpsink = 11,
|
||||
profile_max = 12
|
||||
profile_max = 8
|
||||
};
|
||||
|
||||
#define A2DP_SIGNAL 0x01
|
||||
@@ -181,10 +159,7 @@ typedef struct {
|
||||
//profile info for each connection
|
||||
typedef struct rtl_hci_conn {
|
||||
struct list_head list;
|
||||
u16 big_handle;
|
||||
u16 handle;
|
||||
u8 direction;
|
||||
u8 remove_path;
|
||||
uint16_t handle;
|
||||
struct delayed_work a2dp_count_work;
|
||||
struct delayed_work pan_count_work;
|
||||
struct delayed_work hogp_count_work;
|
||||
@@ -195,7 +170,7 @@ typedef struct rtl_hci_conn {
|
||||
uint8_t type; // 0:l2cap, 1:sco/esco, 2:le
|
||||
uint16_t profile_bitmap;
|
||||
uint16_t profile_status;
|
||||
int8_t profile_refcount[profile_max];
|
||||
int8_t profile_refcount[8];
|
||||
} rtk_conn_prof, *prtk_conn_prof;
|
||||
|
||||
#ifdef RTB_SOFTWARE_MAILBOX
|
||||
@@ -229,40 +204,21 @@ struct rtl_btinfo_ctl {
|
||||
};
|
||||
#endif /* RTB_SOFTWARE_MAILBOX */
|
||||
|
||||
#define HCI_PT_CMD 0x01
|
||||
#define HCI_PT_EVT 0x02
|
||||
#define HCI_PT_L2SIG_RX 0x03
|
||||
#define HCI_PT_L2SIG_TX 0x04
|
||||
#define HCI_PT_L2DATA_RX 0x05
|
||||
#define HCI_PT_L2DATA_TX 0x06
|
||||
|
||||
struct rtl_hci_hdr {
|
||||
struct list_head list;
|
||||
u8 type;
|
||||
u16 len;
|
||||
};
|
||||
|
||||
#define MAX_LEN_OF_HCI_EV 32
|
||||
#define NUM_RTL_HCI_EV 32
|
||||
struct rtl_hci_ev {
|
||||
struct list_head list;
|
||||
u8 type;
|
||||
u16 len;
|
||||
|
||||
/* private */
|
||||
__u8 data[MAX_LEN_OF_HCI_EV];
|
||||
__u16 len;
|
||||
struct list_head list;
|
||||
};
|
||||
|
||||
#define L2_MAX_SUBSEC_LEN 128
|
||||
#define L2_MAX_PKTS 16
|
||||
struct rtl_l2_buff {
|
||||
struct list_head list;
|
||||
u8 type;
|
||||
u16 len;
|
||||
|
||||
/* private */
|
||||
__u8 data[L2_MAX_SUBSEC_LEN];
|
||||
__u16 len;
|
||||
__u16 out;
|
||||
struct list_head list;
|
||||
};
|
||||
|
||||
struct rtl_coex_struct {
|
||||
@@ -280,18 +236,18 @@ struct rtl_coex_struct {
|
||||
struct delayed_work sock_work;
|
||||
#endif
|
||||
struct workqueue_struct *fw_wq;
|
||||
struct workqueue_struct *timer_wq;
|
||||
struct delayed_work fw_work;
|
||||
struct delayed_work cmd_work;
|
||||
struct delayed_work l2_work;
|
||||
#ifdef RTB_SOFTWARE_MAILBOX
|
||||
struct sock *sk;
|
||||
#endif
|
||||
struct urb *urb;
|
||||
spinlock_t spin_lock_sock;
|
||||
struct mutex profile_mutex;
|
||||
struct mutex conn_mutex;
|
||||
spinlock_t spin_lock_profile;
|
||||
uint16_t profile_bitmap;
|
||||
uint16_t profile_status;
|
||||
int8_t profile_refcount[profile_max];
|
||||
int8_t profile_refcount[8];
|
||||
uint8_t ispairing;
|
||||
uint8_t isinquirying;
|
||||
uint8_t ispaging;
|
||||
@@ -310,9 +266,12 @@ struct rtl_coex_struct {
|
||||
uint8_t wifi_on;
|
||||
uint8_t sock_open;
|
||||
#endif
|
||||
|
||||
unsigned long cmd_last_tx;
|
||||
|
||||
/* hci ev buff */
|
||||
struct list_head ev_used_list;
|
||||
struct list_head ev_free_list;
|
||||
|
||||
spinlock_t rxlock;
|
||||
__u8 pkt_type;
|
||||
__u16 expect;
|
||||
@@ -320,18 +279,16 @@ struct rtl_coex_struct {
|
||||
__u16 elen;
|
||||
__u8 back_buff[HCI_MAX_EVENT_SIZE];
|
||||
|
||||
struct list_head ev_free_list;
|
||||
/* l2cap rx buff */
|
||||
struct list_head l2_used_list;
|
||||
struct list_head l2_free_list;
|
||||
struct list_head hci_pkt_list;
|
||||
|
||||
/* buff addr and size */
|
||||
spinlock_t buff_lock;
|
||||
unsigned long pages_addr;
|
||||
unsigned long buff_size;
|
||||
|
||||
#define RTL_COEX_RUNNING 1
|
||||
#define RTL_COEX_PKT_COUNTING 2
|
||||
#define RTL_COEX_CONN_REMOVING 3
|
||||
#define RTL_COEX_RUNNING (1 << 0)
|
||||
unsigned long flags;
|
||||
|
||||
};
|
||||
@@ -406,3 +363,6 @@ void rtk_btcoex_close(void);
|
||||
void rtk_btcoex_probe(struct hci_dev *hdev);
|
||||
void rtk_btcoex_init(void);
|
||||
void rtk_btcoex_exit(void);
|
||||
|
||||
|
||||
#endif /* __RTK_COEX_H__ */
|
||||
@@ -1,22 +1,8 @@
|
||||
// SPDX-License-Identifier: GPL-2.0-only
|
||||
/*
|
||||
*
|
||||
* Realtek Bluetooth USB download firmware driver
|
||||
*
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
* the Free Software Foundation; either version 2 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program; if not, write to the Free Software
|
||||
* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
|
||||
*
|
||||
*/
|
||||
|
||||
#include <linux/kernel.h>
|
||||
@@ -30,14 +16,8 @@
|
||||
#include <linux/usb.h>
|
||||
#include <linux/dcache.h>
|
||||
#include <linux/in.h>
|
||||
#include <linux/version.h>
|
||||
#include <net/sock.h>
|
||||
|
||||
#if LINUX_VERSION_CODE >= KERNEL_VERSION(6, 12, 0)
|
||||
#include <linux/unaligned.h>
|
||||
#else
|
||||
#include <asm/unaligned.h>
|
||||
#endif
|
||||
|
||||
#include <linux/interrupt.h>
|
||||
#include <linux/module.h>
|
||||
@@ -50,7 +30,8 @@
|
||||
#include <linux/cdev.h>
|
||||
#include <linux/device.h>
|
||||
#include <linux/poll.h>
|
||||
#include <linux/vmalloc.h>
|
||||
|
||||
#include <linux/version.h>
|
||||
|
||||
#if LINUX_VERSION_CODE >= KERNEL_VERSION(2, 6, 32)
|
||||
#include <linux/pm_runtime.h>
|
||||
@@ -103,7 +84,6 @@ static struct list_head list_extracfgs;
|
||||
#define HCI_VENDOR_READ_RTK_ROM_VERISION 0xfc6d
|
||||
#define HCI_VENDOR_READ_LMP_VERISION 0x1001
|
||||
#define HCI_VENDOR_READ_CMD 0xfc61
|
||||
#define HCI_VENDOR_WRITE_CMD 0xfc62
|
||||
|
||||
#define ROM_LMP_NONE 0x0000
|
||||
#define ROM_LMP_8723a 0x1200
|
||||
@@ -112,9 +92,6 @@ static struct list_head list_extracfgs;
|
||||
#define ROM_LMP_8761a 0X8761
|
||||
#define ROM_LMP_8822b 0X8822
|
||||
#define ROM_LMP_8852a 0x8852
|
||||
#define ROM_LMP_8851b 0x8851
|
||||
#define ROM_LMP_8922a 0x8922
|
||||
#define ROM_LMP_8723c 0x8703
|
||||
|
||||
#define PATCH_SNIPPETS 0x01
|
||||
#define PATCH_DUMMY_HEADER 0x02
|
||||
@@ -186,30 +163,41 @@ static const uint8_t RTK_EPATCH_SIGNATURE_NEW[8] =
|
||||
//Extension Section IGNATURE:0x77FD0451
|
||||
static const uint8_t Extension_Section_SIGNATURE[4] = { 0x51, 0x04, 0xFD, 0x77 };
|
||||
|
||||
static const struct {
|
||||
__u16 lmp_subver;
|
||||
__u8 id;
|
||||
} project_id_to_lmp_subver[] = {
|
||||
{ ROM_LMP_8723a, 0 },
|
||||
{ ROM_LMP_8723b, 1 },
|
||||
{ ROM_LMP_8821a, 2 },
|
||||
{ ROM_LMP_8761a, 3 },
|
||||
{ ROM_LMP_8723c, 7 },
|
||||
{ ROM_LMP_8822b, 8 }, /* 8822B */
|
||||
{ ROM_LMP_8723b, 9 }, /* 8723D */
|
||||
{ ROM_LMP_8821a, 10 }, /* 8821C */
|
||||
{ ROM_LMP_8822b, 13 }, /* 8822C */
|
||||
{ ROM_LMP_8761a, 14 }, /* 8761B */
|
||||
{ ROM_LMP_8852a, 18 }, /* 8852A */
|
||||
{ ROM_LMP_8723b, 19 }, /* 8733B */
|
||||
{ ROM_LMP_8852a, 20 }, /* 8852B */
|
||||
{ ROM_LMP_8852a, 25 }, /* 8852C */
|
||||
{ ROM_LMP_8822b, 33 }, /* 8822E */
|
||||
{ ROM_LMP_8851b, 36 }, /* 8851B */
|
||||
{ ROM_LMP_8852a, 42 }, /* 8852D */
|
||||
{ ROM_LMP_8922a, 44 }, /* 8922A */
|
||||
{ ROM_LMP_8852a, 47 }, /* 8852BT */
|
||||
{ ROM_LMP_8761a, 51 }, /* 8761C */
|
||||
static uint16_t project_id[] = {
|
||||
ROM_LMP_8723a,
|
||||
ROM_LMP_8723b,
|
||||
ROM_LMP_8821a,
|
||||
ROM_LMP_8761a,
|
||||
ROM_LMP_NONE,
|
||||
ROM_LMP_NONE,
|
||||
ROM_LMP_NONE,
|
||||
ROM_LMP_NONE,
|
||||
ROM_LMP_8822b,
|
||||
ROM_LMP_8723b, /* RTL8723DU */
|
||||
ROM_LMP_8821a, /* RTL8821CU */
|
||||
ROM_LMP_NONE,
|
||||
ROM_LMP_NONE,
|
||||
ROM_LMP_8822b, /* RTL8822CU */
|
||||
ROM_LMP_8761a, /* index 14 for 8761BU */
|
||||
ROM_LMP_NONE,
|
||||
ROM_LMP_NONE,
|
||||
ROM_LMP_NONE,
|
||||
ROM_LMP_8852a, /* index 18 for 8852AU */
|
||||
ROM_LMP_8723b, /* index 19 for 8723FU */
|
||||
ROM_LMP_8852a, /* index 20 for 8852BU */
|
||||
ROM_LMP_NONE,
|
||||
ROM_LMP_NONE,
|
||||
ROM_LMP_NONE,
|
||||
ROM_LMP_NONE,
|
||||
ROM_LMP_8852a, /* index 25 for 8852CU */
|
||||
ROM_LMP_NONE,
|
||||
ROM_LMP_NONE,
|
||||
ROM_LMP_NONE,
|
||||
ROM_LMP_NONE,
|
||||
ROM_LMP_NONE,
|
||||
ROM_LMP_NONE,
|
||||
ROM_LMP_NONE,
|
||||
ROM_LMP_8822b, /* index 33 for 8822EU */
|
||||
};
|
||||
|
||||
enum rtk_endpoit {
|
||||
@@ -227,16 +215,10 @@ enum rtk_endpoit {
|
||||
#define RTL8822CU 0x73
|
||||
#define RTL8761BU 0x74
|
||||
#define RTL8852AU 0x75
|
||||
#define RTL8733BU 0x76
|
||||
#define RTL8723FU 0x76
|
||||
#define RTL8852BU 0x77
|
||||
#define RTL8852CU 0x78
|
||||
#define RTL8822EU 0x79
|
||||
#define RTL8851BU 0x7A
|
||||
#define RTL8852DU 0x7B
|
||||
#define RTL8922AU 0x7C
|
||||
#define RTL8852BTU 0x7D
|
||||
#define RTL8761CU 0x80
|
||||
#define RTL8723CU 0x81
|
||||
|
||||
typedef struct {
|
||||
uint16_t prod_id;
|
||||
@@ -297,7 +279,7 @@ static uint8_t g_key_id = 0;
|
||||
|
||||
static dev_data *dev_data_find(struct usb_interface *intf);
|
||||
static patch_info *get_patch_entry(struct usb_device *udev);
|
||||
static int load_firmware(dev_data *dev_entry, xchange_data *xdata);
|
||||
static int load_firmware(dev_data * dev_entry, uint8_t ** buff);
|
||||
static void init_xdata(xchange_data * xdata, dev_data * dev_entry);
|
||||
static int check_fw_version(xchange_data * xdata);
|
||||
static int download_data(xchange_data * xdata);
|
||||
@@ -362,8 +344,6 @@ static patch_info fw_patch_table[] = {
|
||||
{0xb009, 0x8723, "mp_rtl8723du_fw", "rtl8723du_fw", "rtl8723du_config", RTL8723DU}, /* RTL8723DU */
|
||||
{0x0231, 0x8723, "mp_rtl8723du_fw", "rtl8723du_fw", "rtl8723du_config", RTL8723DU}, /* RTL8723DU for LiteOn */
|
||||
|
||||
{0xb703, 0x8703, "mp_rtl8723cu_fw", "rtl8723cu_fw", "rtl8723cu_config", RTL8723CU}, /* RTL8723CU */
|
||||
|
||||
{0xb820, 0x8821, "mp_rtl8821cu_fw", "rtl8821cu_fw", "rtl8821cu_config", RTL8821CU}, /* RTL8821CU */
|
||||
{0xc820, 0x8821, "mp_rtl8821cu_fw", "rtl8821cu_fw", "rtl8821cu_config", RTL8821CU}, /* RTL8821CU */
|
||||
{0xc821, 0x8821, "mp_rtl8821cu_fw", "rtl8821cu_fw", "rtl8821cu_config", RTL8821CU}, /* RTL8821CE */
|
||||
@@ -397,7 +377,6 @@ static patch_info fw_patch_table[] = {
|
||||
{0xc82e, 0x8822, "mp_rtl8822cu_fw", "rtl8822cu_fw", "rtl8822cu_config", RTL8822CU}, /* RTL8822CU */
|
||||
{0xc81d, 0x8822, "mp_rtl8822cu_fw", "rtl8822cu_fw", "rtl8822cu_config", RTL8822CU}, /* RTL8822CU */
|
||||
{0xd820, 0x8822, "mp_rtl8821du_fw", "rtl8821du_fw", "rtl8821du_config", RTL8822CU}, /* RTL8821DU */
|
||||
{0x053b, 0x8822, "mp_rtl8821du_fw", "rtl8821du_fw", "rtl8821du_config", RTL8822CU}, /* RTL8821DU for Epson*/
|
||||
|
||||
{0xc822, 0x8822, "mp_rtl8822cu_fw", "rtl8822cu_fw", "rtl8822cu_config", RTL8822CU}, /* RTL8822CE */
|
||||
{0xc82b, 0x8822, "mp_rtl8822cu_fw", "rtl8822cu_fw", "rtl8822cu_config", RTL8822CU}, /* RTL8822CE */
|
||||
@@ -426,7 +405,6 @@ static patch_info fw_patch_table[] = {
|
||||
{0xc03f, 0x8822, "mp_rtl8822cu_fw", "rtl8822cu_fw", "rtl8822cu_config", RTL8822CU}, /* RTL8822CE-VS */
|
||||
|
||||
{0x8771, 0x8761, "mp_rtl8761b_fw", "rtl8761bu_fw", "rtl8761bu_config", RTL8761BU}, /* RTL8761BU only */
|
||||
{0x876e, 0x8761, "mp_rtl8761b_fw", "rtl8761bu_fw", "rtl8761bu_config", RTL8761BU}, /* RTL8761BUE */
|
||||
{0xa725, 0x8761, "mp_rtl8761b_fw", "rtl8725au_fw", "rtl8725au_config", RTL8761BU}, /* RTL8725AU */
|
||||
{0xa72A, 0x8761, "mp_rtl8761b_fw", "rtl8725au_fw", "rtl8725au_config", RTL8761BU}, /* RTL8725AU BT only */
|
||||
|
||||
@@ -447,13 +425,14 @@ static patch_info fw_patch_table[] = {
|
||||
{0xc125, 0x8852, "mp_rtl8852au_fw", "rtl8852au_fw", "rtl8852au_config", RTL8852AU}, /* RTL8852AE */
|
||||
{0xe852, 0x8852, "mp_rtl8852au_fw", "rtl8852au_fw", "rtl8852au_config", RTL8852AU}, /* RTL8852AE */
|
||||
{0xb852, 0x8852, "mp_rtl8852au_fw", "rtl8852au_fw", "rtl8852au_config", RTL8852AU}, /* RTL8852AE */
|
||||
{0xc852, 0x8852, "mp_rtl8852au_fw", "rtl8852au_fw", "rtl8852au_config", RTL8852AU}, /* RTL8852AE */
|
||||
{0xc549, 0x8852, "mp_rtl8852au_fw", "rtl8852au_fw", "rtl8852au_config", RTL8852AU}, /* RTL8852AE */
|
||||
{0xc127, 0x8852, "mp_rtl8852au_fw", "rtl8852au_fw", "rtl8852au_config", RTL8852AU}, /* RTL8852AE */
|
||||
{0x3565, 0x8852, "mp_rtl8852au_fw", "rtl8852au_fw", "rtl8852au_config", RTL8852AU}, /* RTL8852AE */
|
||||
|
||||
{0xb733, 0x8723, "mp_rtl8733bu_fw", "rtl8733bu_fw", "rtl8733bu_config", RTL8733BU}, /* RTL8733BU */
|
||||
{0xb73a, 0x8723, "mp_rtl8733bu_fw", "rtl8733bu_fw", "rtl8733bu_config", RTL8733BU}, /* RTL8733BU */
|
||||
{0xf72b, 0x8723, "mp_rtl8733bu_fw", "rtl8733bu_fw", "rtl8733bu_config", RTL8733BU}, /* RTL8733BU */
|
||||
{0xb733, 0x8723, "mp_rtl8723fu_fw", "rtl8723fu_fw", "rtl8723fu_config", RTL8723FU}, /* RTL8723FU */
|
||||
{0xb73a, 0x8723, "mp_rtl8723fu_fw", "rtl8723fu_fw", "rtl8723fu_config", RTL8723FU}, /* RTL8723FU */
|
||||
{0xf72b, 0x8723, "mp_rtl8723fu_fw", "rtl8723fu_fw", "rtl8723fu_config", RTL8723FU}, /* RTL8723FU */
|
||||
|
||||
{0x8851, 0x8852, "mp_rtl8851au_fw", "rtl8851au_fw", "rtl8851au_config", RTL8852BU}, /* RTL8851AU */
|
||||
{0xa85b, 0x8852, "mp_rtl8852bu_fw", "rtl8852bu_fw", "rtl8852bu_config", RTL8852BU}, /* RTL8852BU */
|
||||
@@ -474,7 +453,6 @@ static patch_info fw_patch_table[] = {
|
||||
{0x1670, 0x8852, "mp_rtl8852bu_fw", "rtl8852bu_fw", "rtl8852bu_config", RTL8852BU}, /* RTL8852BE */
|
||||
|
||||
{0xc85a, 0x8852, "mp_rtl8852cu_fw", "rtl8852cu_fw", "rtl8852cu_config", RTL8852CU}, /* RTL8852CU */
|
||||
{0xc85d, 0x8852, "mp_rtl8852cu_fw", "rtl8852cu_fw", "rtl8852cu_config", RTL8852CU}, /* RTL8852CU */
|
||||
{0x0852, 0x8852, "mp_rtl8852cu_fw", "rtl8852cu_fw", "rtl8852cu_config", RTL8852CU}, /* RTL8852CE */
|
||||
{0x5852, 0x8852, "mp_rtl8852cu_fw", "rtl8852cu_fw", "rtl8852cu_config", RTL8852CU}, /* RTL8852CE */
|
||||
{0xc85c, 0x8852, "mp_rtl8852cu_fw", "rtl8852cu_fw", "rtl8852cu_config", RTL8852CU}, /* RTL8852CE */
|
||||
@@ -482,29 +460,10 @@ static patch_info fw_patch_table[] = {
|
||||
{0x886c, 0x8852, "mp_rtl8852cu_fw", "rtl8852cu_fw", "rtl8852cu_config", RTL8852CU}, /* RTL8852CE */
|
||||
{0x887c, 0x8852, "mp_rtl8852cu_fw", "rtl8852cu_fw", "rtl8852cu_config", RTL8852CU}, /* RTL8852CE */
|
||||
{0x4007, 0x8852, "mp_rtl8852cu_fw", "rtl8852cu_fw", "rtl8852cu_config", RTL8852CU}, /* RTL8852CE */
|
||||
{0x1675, 0x8852, "mp_rtl8852cu_fw", "rtl8852cu_fw", "rtl8852cu_config", RTL8852CU}, /* RTL8852CE */
|
||||
{0x3586, 0x8852, "mp_rtl8852cu_fw", "rtl8852cu_fw", "rtl8852cu_config", RTL8852CU}, /* RTL8852CE */
|
||||
|
||||
{0xe822, 0x8822, "mp_rtl8822eu_fw", "rtl8822eu_fw", "rtl8822eu_config", RTL8822EU}, /* RTL8822EU */
|
||||
{0xa82a, 0x8822, "mp_rtl8822eu_fw", "rtl8822eu_fw", "rtl8822eu_config", RTL8822EU}, /* RTL8822EU */
|
||||
|
||||
{0xb851, 0x8851, "mp_rtl8851bu_fw", "rtl8851bu_fw", "rtl8851bu_config", RTL8851BU}, /* RTL8851BU */
|
||||
|
||||
{0xd85a, 0x8852, "mp_rtl8852du_fw", "rtl8852du_fw", "rtl8852du_config", RTL8852DU}, /* RTL8852DU */
|
||||
|
||||
{0x892a, 0x8922, "mp_rtl8922au_fw", "rtl8922au_fw", "rtl8922au_config", RTL8922AU}, /* RTL8922AU */
|
||||
{0x8922, 0x8922, "mp_rtl8922au_fw", "rtl8922au_fw", "rtl8922au_config", RTL8922AU}, /* RTL8922AE */
|
||||
{0xa890, 0x8922, "mp_rtl8922au_fw", "rtl8922au_fw", "rtl8922au_config", RTL8922AU}, /* RTL8922AE */
|
||||
{0xa891, 0x8922, "mp_rtl8922au_fw", "rtl8922au_fw", "rtl8922au_config", RTL8922AU}, /* RTL8922AE */
|
||||
{0xa892, 0x8922, "mp_rtl8922au_fw", "rtl8922au_fw", "rtl8922au_config", RTL8922AU}, /* RTL8922AE */
|
||||
{0xd922, 0x8922, "mp_rtl8922au_fw", "rtl8922au_fw", "rtl8922au_config", RTL8922AU}, /* RTL8922AE */
|
||||
{0xb85f, 0x8922, "mp_rtl8922au_fw", "rtl8922au_fw", "rtl8922au_config", RTL8922AU}, /* RTL8922AE */
|
||||
|
||||
{0xc852, 0x8852, "mp_rtl8852btu_fw", "rtl8852btu_fw", "rtl8852btu_config", RTL8852BTU}, /* RTL8852BTU */
|
||||
{0x8520, 0x8852, "mp_rtl8852btu_fw", "rtl8852btu_fw", "rtl8852btu_config", RTL8852BTU}, /* RTL8852BTE */
|
||||
|
||||
{0xc761, 0x8761, "mp_rtl8761cu_fw", "rtl8761cu_mx_fw", "rtl8761cu_mx_config", RTL8761CU}, /* RTL8761CU */
|
||||
|
||||
/* NOTE: must append patch entries above the null entry */
|
||||
{0, 0, NULL, NULL, NULL, 0}
|
||||
};
|
||||
@@ -787,7 +746,6 @@ static inline int get_max_patch_size(u8 chip_type)
|
||||
max_patch_size = 25 * 1024;
|
||||
break;
|
||||
case RTL8723DU:
|
||||
case RTL8723CU:
|
||||
case RTL8822CU:
|
||||
case RTL8761BU:
|
||||
case RTL8821CU:
|
||||
@@ -796,11 +754,10 @@ static inline int get_max_patch_size(u8 chip_type)
|
||||
case RTL8852AU:
|
||||
max_patch_size = 0x114D0 + 529; /* 69.2KB */
|
||||
break;
|
||||
case RTL8733BU:
|
||||
case RTL8723FU:
|
||||
max_patch_size = 0xC4Cf + 529; /* 49.2KB */
|
||||
break;
|
||||
case RTL8852BU:
|
||||
case RTL8851BU:
|
||||
max_patch_size = 0x104D0 + 529; /* 65KB */
|
||||
break;
|
||||
case RTL8852CU:
|
||||
@@ -809,18 +766,6 @@ static inline int get_max_patch_size(u8 chip_type)
|
||||
case RTL8822EU:
|
||||
max_patch_size = 0x24620 + 529; /* 145KB */
|
||||
break;
|
||||
case RTL8852DU:
|
||||
max_patch_size = 0x20D90 + 529; /* 131KB */
|
||||
break;
|
||||
case RTL8922AU:
|
||||
max_patch_size = 0x23810 + 529; /* 142KB */
|
||||
break;
|
||||
case RTL8852BTU:
|
||||
max_patch_size = 0x27E00 + 529; /* 159.5KB */
|
||||
break;
|
||||
case RTL8761CU:
|
||||
max_patch_size = 1024 * 1024; /* 1MB */
|
||||
break;
|
||||
default:
|
||||
max_patch_size = 40 * 1024;
|
||||
break;
|
||||
@@ -829,64 +774,11 @@ static inline int get_max_patch_size(u8 chip_type)
|
||||
return max_patch_size;
|
||||
}
|
||||
|
||||
static int rtk_vendor_write(dev_data * dev_entry)
|
||||
{
|
||||
int ret_val;
|
||||
|
||||
xchange_data *xdata = NULL;
|
||||
unsigned char cmd_buf[] = {0x31, 0x90, 0xd0, 0x29, 0x80, 0x00, 0x00,
|
||||
0x00, 0x00};
|
||||
|
||||
xdata = kzalloc(sizeof(xchange_data), GFP_KERNEL);
|
||||
if (NULL == xdata) {
|
||||
ret_val = 0xFE;
|
||||
RTKBT_DBG("NULL == xdata");
|
||||
return -1;
|
||||
}
|
||||
|
||||
init_xdata(xdata, dev_entry);
|
||||
|
||||
xdata->cmd_hdr->opcode = cpu_to_le16(HCI_VENDOR_WRITE_CMD);
|
||||
xdata->cmd_hdr->plen = 9;
|
||||
memcpy(xdata->send_pkt, &(xdata->cmd_hdr->opcode), 2);
|
||||
memcpy(xdata->send_pkt+2, &(xdata->cmd_hdr->plen), 1);
|
||||
|
||||
memcpy(xdata->send_pkt+3, cmd_buf, sizeof(cmd_buf));
|
||||
|
||||
xdata->pkt_len = CMD_HDR_LEN + 9;
|
||||
|
||||
ret_val = send_hci_cmd(xdata);
|
||||
if (ret_val < 0) {
|
||||
RTKBT_ERR("%s: Failed to send HCI command.", __func__);
|
||||
goto end;
|
||||
}
|
||||
|
||||
ret_val = rcv_hci_evt(xdata);
|
||||
if (ret_val < 0) {
|
||||
RTKBT_ERR("%s: Failed to receive HCI event.", __func__);
|
||||
goto end;
|
||||
}
|
||||
|
||||
ret_val = 0;
|
||||
end:
|
||||
if (xdata != NULL) {
|
||||
if (xdata->send_pkt)
|
||||
kfree(xdata->send_pkt);
|
||||
if (xdata->rcv_pkt)
|
||||
kfree(xdata->rcv_pkt);
|
||||
kfree(xdata);
|
||||
}
|
||||
return ret_val;
|
||||
}
|
||||
|
||||
static int check_fw_chip_ver(dev_data * dev_entry, xchange_data * xdata)
|
||||
{
|
||||
int ret_val;
|
||||
uint16_t chip = 0;
|
||||
uint16_t chip_ver = 0;
|
||||
uint16_t lmp_subver, hci_rev;
|
||||
patch_info *patch_entry;
|
||||
struct hci_rp_read_local_version *read_ver_rsp;
|
||||
|
||||
chip = rtk_vendor_read(dev_entry, READ_CHIP_TYPE);
|
||||
if(chip == 0x8822) {
|
||||
@@ -909,16 +801,9 @@ static int check_fw_chip_ver(dev_data * dev_entry, xchange_data * xdata)
|
||||
gEVersion = rtk_get_eversion(dev_entry);
|
||||
}
|
||||
return ret_val;
|
||||
} else {
|
||||
patch_entry = xdata->dev_entry->patch_entry;
|
||||
read_ver_rsp = (struct hci_rp_read_local_version *)(xdata->rsp_para);
|
||||
lmp_subver = le16_to_cpu(read_ver_rsp->lmp_subver);
|
||||
hci_rev = le16_to_cpu(read_ver_rsp->hci_rev);
|
||||
if (lmp_subver == 0x8852 && hci_rev == 0x000d)
|
||||
ret_val = rtk_vendor_write(dev_entry);
|
||||
}
|
||||
|
||||
return ret_val;
|
||||
return 0;
|
||||
}
|
||||
|
||||
int download_patch(struct usb_interface *intf)
|
||||
@@ -951,7 +836,7 @@ int download_patch(struct usb_interface *intf)
|
||||
if (ret_val != 0 )
|
||||
goto patch_end;
|
||||
|
||||
xdata->fw_len = load_firmware(dev_entry, xdata);
|
||||
xdata->fw_len = load_firmware(dev_entry, &xdata->fw_data);
|
||||
if (xdata->fw_len <= 0) {
|
||||
RTKBT_ERR("load firmware failed!");
|
||||
ret_val = -1;
|
||||
@@ -990,7 +875,7 @@ int download_patch(struct usb_interface *intf)
|
||||
|
||||
ret_val = 0;
|
||||
patch_fail:
|
||||
vfree(fw_buf);
|
||||
kfree(fw_buf);
|
||||
patch_end:
|
||||
if (xdata != NULL) {
|
||||
if (xdata->send_pkt)
|
||||
@@ -1008,7 +893,7 @@ patch_end:
|
||||
* -1: error
|
||||
* 0: download patch successfully
|
||||
* >0: patch already exists */
|
||||
int download_special_patch(struct usb_interface *intf, const char *special_name)
|
||||
int download_lps_patch(struct usb_interface *intf)
|
||||
{
|
||||
dev_data *dev_entry;
|
||||
patch_info *pinfo;
|
||||
@@ -1050,18 +935,15 @@ int download_special_patch(struct usb_interface *intf, const char *special_name)
|
||||
}
|
||||
goto patch_end;
|
||||
}
|
||||
memset(name1, 0, sizeof(name1));
|
||||
memset(name2, 0, sizeof(name2));
|
||||
|
||||
origin_name1 = dev_entry->patch_entry->patch_name;
|
||||
origin_name2 = dev_entry->patch_entry->config_name;
|
||||
memcpy(name1, special_name, strlen(special_name));
|
||||
strncat(name1, origin_name1, sizeof(name1) - 1 - strlen(special_name));
|
||||
memcpy(name2, special_name, strlen(special_name));
|
||||
strncat(name2, origin_name2, sizeof(name2) - 1 - strlen(special_name));
|
||||
snprintf(name1, sizeof(name1), "lps_%s", origin_name1);
|
||||
snprintf(name2, sizeof(name2), "lps_%s", origin_name2);
|
||||
dev_entry->patch_entry->patch_name = name1;
|
||||
dev_entry->patch_entry->config_name = name2;
|
||||
RTKBT_INFO("Loading %s and %s", name1, name2);
|
||||
xdata->fw_len = load_firmware(dev_entry, xdata);
|
||||
xdata->fw_len = load_firmware(dev_entry, &xdata->fw_data);
|
||||
dev_entry->patch_entry->patch_name = origin_name1;
|
||||
dev_entry->patch_entry->config_name = origin_name2;
|
||||
if (xdata->fw_len <= 0) {
|
||||
@@ -1073,13 +955,11 @@ int download_special_patch(struct usb_interface *intf, const char *special_name)
|
||||
fw_buf = xdata->fw_data;
|
||||
|
||||
pinfo = dev_entry->patch_entry;
|
||||
/*
|
||||
if (!pinfo) {
|
||||
RTKBT_ERR("%s: No patch entry", __func__);
|
||||
result = -1;
|
||||
goto patch_fail;
|
||||
}
|
||||
*/
|
||||
max_patch_size = get_max_patch_size(pinfo->chip_type);
|
||||
if (xdata->fw_len > max_patch_size) {
|
||||
result = -1;
|
||||
@@ -1118,39 +998,6 @@ patch_end:
|
||||
}
|
||||
#endif
|
||||
|
||||
int setup_btrealtek_flag(struct usb_interface *intf, struct hci_dev *hdev)
|
||||
{
|
||||
dev_data *dev_entry;
|
||||
patch_info *pinfo;
|
||||
int ret_val = 0;
|
||||
|
||||
dev_entry = dev_data_find(intf);
|
||||
if (NULL == dev_entry) {
|
||||
ret_val = -1;
|
||||
RTKBT_ERR("%s: NULL == dev_entry", __func__);
|
||||
return ret_val;
|
||||
}
|
||||
|
||||
pinfo = dev_entry->patch_entry;
|
||||
if (!pinfo) {
|
||||
RTKBT_ERR("%s: No patch entry", __func__);
|
||||
ret_val = -1;
|
||||
return ret_val;
|
||||
}
|
||||
|
||||
switch (pinfo->chip_type){
|
||||
case RTL8852CU:
|
||||
#if LINUX_VERSION_CODE >= KERNEL_VERSION(5, 8, 0)
|
||||
btrealtek_set_flag(hdev, REALTEK_ALT6_CONTINUOUS_TX_CHIP);
|
||||
#endif
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
|
||||
return ret_val;
|
||||
}
|
||||
|
||||
#if defined RTKBT_SUSPEND_WAKEUP || defined RTKBT_SHUTDOWN_WAKEUP || defined RTKBT_SWITCH_PATCH
|
||||
int set_scan(struct usb_interface *intf)
|
||||
{
|
||||
@@ -1198,7 +1045,7 @@ end:
|
||||
|
||||
dev_data *dev_data_find(struct usb_interface * intf)
|
||||
{
|
||||
dev_data *dev_entry = NULL;
|
||||
dev_data *dev_entry;
|
||||
|
||||
list_for_each_entry(dev_entry, &dev_data_list, list_node) {
|
||||
if (dev_entry->intf == intf) {
|
||||
@@ -1241,7 +1088,6 @@ static int is_mac(u8 chip_type, u16 offset)
|
||||
switch (chip_type) {
|
||||
case RTL8822BU:
|
||||
case RTL8723DU:
|
||||
case RTL8723CU:
|
||||
case RTL8821CU:
|
||||
if (offset == 0x0044)
|
||||
return 1;
|
||||
@@ -1249,15 +1095,10 @@ static int is_mac(u8 chip_type, u16 offset)
|
||||
case RTL8822CU:
|
||||
case RTL8761BU:
|
||||
case RTL8852AU:
|
||||
case RTL8733BU:
|
||||
case RTL8723FU:
|
||||
case RTL8852BU:
|
||||
case RTL8852CU:
|
||||
case RTL8822EU:
|
||||
case RTL8851BU:
|
||||
case RTL8852DU:
|
||||
case RTL8922AU:
|
||||
case RTL8852BTU:
|
||||
case RTL8761CU:
|
||||
if (offset == 0x0030)
|
||||
return 1;
|
||||
break;
|
||||
@@ -1275,21 +1116,15 @@ static uint16_t get_mac_offset(u8 chip_type)
|
||||
switch (chip_type) {
|
||||
case RTL8822BU:
|
||||
case RTL8723DU:
|
||||
case RTL8723CU:
|
||||
case RTL8821CU:
|
||||
return 0x0044;
|
||||
case RTL8822CU:
|
||||
case RTL8761BU:
|
||||
case RTL8852AU:
|
||||
case RTL8733BU:
|
||||
case RTL8723FU:
|
||||
case RTL8852BU:
|
||||
case RTL8852CU:
|
||||
case RTL8822EU:
|
||||
case RTL8851BU:
|
||||
case RTL8852DU:
|
||||
case RTL8922AU:
|
||||
case RTL8852BTU:
|
||||
case RTL8761CU:
|
||||
return 0x0030;
|
||||
case RTLPREVIOUS:
|
||||
return 0x003c;
|
||||
@@ -1617,12 +1452,14 @@ static uint8_t *rtb_get_patch_header(int *len,
|
||||
}
|
||||
break;
|
||||
default:
|
||||
RTKBT_INFO("Unknown Opcode. Ignore");
|
||||
RTKBT_ERR("Wrong Opcode");
|
||||
goto wrong_opcode;
|
||||
}
|
||||
section_pos += (SECTION_HEADER_SIZE + section_hdr.section_len);
|
||||
}
|
||||
*len = patch_len;
|
||||
|
||||
wrong_opcode:
|
||||
return NULL;
|
||||
}
|
||||
|
||||
@@ -1906,7 +1743,7 @@ static int rtk_vendor_read(dev_data * dev_entry, uint8_t class)
|
||||
xchange_data *xdata = NULL;
|
||||
unsigned char cmd_ct_buf[] = {0x10, 0x38, 0x04, 0x28, 0x80};
|
||||
unsigned char cmd_cv_buf[] = {0x10, 0x3A, 0x04, 0x28, 0x80};
|
||||
unsigned char cmd_sec_buf[] = {0x10, 0xA4, 0xAD, 0x00, 0xb0};
|
||||
unsigned char cmd_sec_buf[] = {0x10, 0xA4, 0x0D, 0x00, 0xb0};
|
||||
|
||||
xdata = kzalloc(sizeof(xchange_data), GFP_KERNEL);
|
||||
if (NULL == xdata) {
|
||||
@@ -1974,6 +1811,7 @@ static int rtk_vendor_read(dev_data * dev_entry, uint8_t class)
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
read_end:
|
||||
if (xdata != NULL) {
|
||||
if (xdata->send_pkt)
|
||||
@@ -1985,57 +1823,7 @@ read_end:
|
||||
return ret_val;
|
||||
}
|
||||
|
||||
static int needs_hci_upgrade(xchange_data *xdata, u8 *buf, u32 buf_len)
|
||||
{
|
||||
struct {
|
||||
u8 status;
|
||||
u8 subopcode;
|
||||
u8 ota;
|
||||
} __attribute__((packed)) *evt_params;
|
||||
#define UPG_DL_BLOCK_SIZE 128
|
||||
#define UPG_SUBCMD_CODE 0x01
|
||||
u8 len = UPG_DL_BLOCK_SIZE;
|
||||
u8 *cmd_params;
|
||||
int ret;
|
||||
|
||||
cmd_params = xdata->req_para;
|
||||
evt_params = (void *)xdata->rsp_para;
|
||||
xdata->cmd_hdr->opcode = cpu_to_le16(0xfdbb);
|
||||
if (buf_len < len)
|
||||
len = buf_len;
|
||||
xdata->cmd_hdr->plen = 1 + len;
|
||||
xdata->pkt_len = sizeof(*xdata->cmd_hdr) + xdata->cmd_hdr->plen;
|
||||
*cmd_params++ = UPG_SUBCMD_CODE;
|
||||
memcpy(cmd_params, buf, len);
|
||||
|
||||
ret = send_hci_cmd(xdata);
|
||||
if (ret < 0)
|
||||
return ret;
|
||||
|
||||
ret = rcv_hci_evt(xdata);
|
||||
if (ret < 0)
|
||||
return ret;
|
||||
|
||||
if (evt_params->status) {
|
||||
RTKBT_ERR("needs_hci_upgrade: status %02x", evt_params->status);
|
||||
return -1;
|
||||
}
|
||||
|
||||
if (evt_params->subopcode != UPG_SUBCMD_CODE) {
|
||||
RTKBT_ERR("needs_hci_upgrade: return subopcode %02x",
|
||||
evt_params->subopcode);
|
||||
return -2;
|
||||
}
|
||||
|
||||
RTKBT_INFO("needs_hci_upgrade: state %02x", evt_params->ota);
|
||||
|
||||
return evt_params->ota;
|
||||
}
|
||||
|
||||
/* buff: points to the allocated buffer that stores extracted fw and config
|
||||
* This function returns the total length of extracted fw and config
|
||||
*/
|
||||
int load_firmware(dev_data *dev_entry, xchange_data *xdata)
|
||||
int load_firmware(dev_data * dev_entry, uint8_t ** buff)
|
||||
{
|
||||
const struct firmware *fw;
|
||||
struct usb_device *udev;
|
||||
@@ -2047,13 +1835,12 @@ int load_firmware(dev_data *dev_entry, xchange_data *xdata)
|
||||
uint8_t need_download_fw = 1;
|
||||
uint16_t lmp_version;
|
||||
struct rtk_epatch_entry current_entry = { 0 };
|
||||
|
||||
struct list_head *pos, *next;
|
||||
struct patch_node *tmp;
|
||||
struct patch_node patch_node_hdr;
|
||||
int i;
|
||||
|
||||
RTKBT_DBG("load_firmware start");
|
||||
|
||||
udev = dev_entry->udev;
|
||||
patch_entry = dev_entry->patch_entry;
|
||||
lmp_version = patch_entry->lmp_sub;
|
||||
@@ -2066,13 +1853,16 @@ int load_firmware(dev_data *dev_entry, xchange_data *xdata)
|
||||
ret_val = request_firmware(&fw, fw_name, &udev->dev);
|
||||
if (ret_val < 0) {
|
||||
RTKBT_ERR("request_firmware error");
|
||||
fw_len = 0;
|
||||
kfree(config_file_buf);
|
||||
config_file_buf = NULL;
|
||||
goto fw_fail;
|
||||
}
|
||||
|
||||
INIT_LIST_HEAD(&patch_node_hdr.list);
|
||||
|
||||
epatch_buf = vzalloc(fw->size);
|
||||
if (!epatch_buf)
|
||||
epatch_buf = kzalloc(fw->size, GFP_KERNEL);
|
||||
if (NULL == epatch_buf)
|
||||
goto alloc_fail;
|
||||
|
||||
memcpy(epatch_buf, fw->data, fw->size);
|
||||
@@ -2084,174 +1874,137 @@ int load_firmware(dev_data *dev_entry, xchange_data *xdata)
|
||||
if (memcmp(epatch_buf, RTK_EPATCH_SIGNATURE, 8) == 0) {
|
||||
RTKBT_ERR("8723a Check signature error!");
|
||||
need_download_fw = 0;
|
||||
goto sign_err;
|
||||
}
|
||||
buf = vzalloc(buf_len);
|
||||
if (!buf) {
|
||||
RTKBT_ERR("Can't alloc memory for fw&config");
|
||||
buf_len = -1;
|
||||
goto alloc_buf_err;
|
||||
} else {
|
||||
if (!(buf = kzalloc(buf_len, GFP_KERNEL))) {
|
||||
RTKBT_ERR("Can't alloc memory for fw&config");
|
||||
buf_len = -1;
|
||||
} else {
|
||||
RTKBT_DBG("8723a, fw copy direct");
|
||||
memcpy(buf, epatch_buf, fw->size);
|
||||
if (config_len) {
|
||||
memcpy(&buf[buf_len - config_len],
|
||||
config_file_buf, config_len);
|
||||
}
|
||||
}
|
||||
}
|
||||
} else {
|
||||
RTKBT_ERR("This is not 8723a, use new patch style!");
|
||||
|
||||
RTKBT_DBG("8723a, fw copy direct");
|
||||
memcpy(buf, epatch_buf, fw->size);
|
||||
if (config_len)
|
||||
memcpy(&buf[buf_len - config_len], config_file_buf,
|
||||
config_len);
|
||||
|
||||
goto done;
|
||||
}
|
||||
|
||||
RTKBT_ERR("This is not 8723a, use new patch style!");
|
||||
|
||||
/* Get version from ROM */
|
||||
gEVersion = rtk_get_eversion(dev_entry);
|
||||
RTKBT_DBG("%s: New gEVersion %d", __func__, gEVersion);
|
||||
if (gEVersion == 0xFE) {
|
||||
RTKBT_ERR("%s: Read ROM version failure", __func__);
|
||||
need_download_fw = 0;
|
||||
goto alloc_fail;
|
||||
}
|
||||
|
||||
/* check Signature and Extension Section Field */
|
||||
if ((memcmp(epatch_buf, RTK_EPATCH_SIGNATURE, 8) &&
|
||||
memcmp(epatch_buf, RTK_EPATCH_SIGNATURE_NEW, 8)) ||
|
||||
memcmp(epatch_buf + buf_len - config_len - 4,
|
||||
Extension_Section_SIGNATURE, 4) != 0) {
|
||||
RTKBT_ERR("Check SIGNATURE error! do not download fw");
|
||||
need_download_fw = 0;
|
||||
goto sign_err;
|
||||
}
|
||||
|
||||
proj_id = rtk_get_fw_project_id(epatch_buf + buf_len - config_len - 5);
|
||||
|
||||
for (i = 0; i < ARRAY_SIZE(project_id_to_lmp_subver); i++) {
|
||||
if (proj_id == project_id_to_lmp_subver[i].id &&
|
||||
lmp_version == project_id_to_lmp_subver[i].lmp_subver) {
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
if (i >= ARRAY_SIZE(project_id_to_lmp_subver)) {
|
||||
RTKBT_ERR("lmp_version %04x, project_id %u, does not match!!!",
|
||||
lmp_version, proj_id);
|
||||
need_download_fw = 0;
|
||||
goto proj_id_err;
|
||||
}
|
||||
|
||||
RTKBT_DBG("lmp_version is %04x, project_id is %u, match!",
|
||||
lmp_version, proj_id);
|
||||
|
||||
if (memcmp(epatch_buf, RTK_EPATCH_SIGNATURE_NEW, 8) == 0) {
|
||||
int key_id = rtk_vendor_read(dev_entry, READ_SEC_PROJ);
|
||||
int tmp_len = 0;
|
||||
|
||||
RTKBT_DBG("%s: key id %d", __func__, key_id);
|
||||
if (key_id < 0) {
|
||||
RTKBT_ERR("%s: Read key id failure", __func__);
|
||||
/* Get version from ROM */
|
||||
gEVersion = rtk_get_eversion(dev_entry);
|
||||
RTKBT_DBG("%s: New gEVersion %d", __func__, gEVersion);
|
||||
if (gEVersion == 0xFE) {
|
||||
RTKBT_ERR("%s: Read ROM version failure", __func__);
|
||||
need_download_fw = 0;
|
||||
fw_len = 0;
|
||||
goto extract_err;
|
||||
}
|
||||
rtb_get_patch_header(&buf_len, &patch_node_hdr, epatch_buf,
|
||||
key_id);
|
||||
if (!buf_len)
|
||||
goto extract_err;
|
||||
RTKBT_DBG("buf_len = 0x%x", buf_len);
|
||||
buf_len += config_len;
|
||||
|
||||
buf = vzalloc(buf_len);
|
||||
if (!buf) {
|
||||
RTKBT_ERR("Can't alloc memory for multi fw&config");
|
||||
buf_len = -1;
|
||||
goto alloc_buf_err;
|
||||
goto alloc_fail;
|
||||
}
|
||||
|
||||
list_for_each_safe(pos, next, &patch_node_hdr.list) {
|
||||
tmp = list_entry(pos, struct patch_node, list);
|
||||
RTKBT_DBG("len = 0x%x", tmp->len);
|
||||
memcpy(buf + tmp_len, tmp->payload, tmp->len);
|
||||
tmp_len += tmp->len;
|
||||
list_del_init(pos);
|
||||
kfree(tmp);
|
||||
}
|
||||
if (config_len)
|
||||
memcpy(&buf[buf_len - config_len], config_file_buf,
|
||||
config_len);
|
||||
} else {
|
||||
rtk_get_patch_entry(epatch_buf, ¤t_entry);
|
||||
|
||||
if (current_entry.patch_length == 0)
|
||||
goto extract_err;
|
||||
|
||||
buf_len = current_entry.patch_length + config_len;
|
||||
RTKBT_DBG("buf_len = 0x%x", buf_len);
|
||||
|
||||
buf = vzalloc(buf_len);
|
||||
if (!buf) {
|
||||
RTKBT_ERR("Can't alloc memory for multi fw&config");
|
||||
buf_len = -1;
|
||||
goto alloc_buf_err;
|
||||
}
|
||||
|
||||
memcpy(buf, epatch_buf + current_entry.start_offset,
|
||||
current_entry.patch_length);
|
||||
/* Copy fw version */
|
||||
memcpy(buf + current_entry.patch_length - 4, epatch_buf + 8, 4);
|
||||
if (config_len)
|
||||
memcpy(&buf[buf_len - config_len], config_file_buf,
|
||||
config_len);
|
||||
}
|
||||
|
||||
if (patch_entry->chip_type == RTL8761CU) {
|
||||
if (needs_hci_upgrade(xdata, buf, buf_len) <= 0) {
|
||||
if (config_len > 0) {
|
||||
memmove(buf, buf + buf_len - config_len,
|
||||
config_len);
|
||||
buf_len = config_len;
|
||||
} else {
|
||||
#define FAKE_SEG_LEN 16
|
||||
if (buf_len > FAKE_SEG_LEN)
|
||||
buf_len = FAKE_SEG_LEN;
|
||||
memset(buf, 0, buf_len);
|
||||
}
|
||||
/* check Signature and Extension Section Field */
|
||||
if (((memcmp(epatch_buf, RTK_EPATCH_SIGNATURE, 8) != 0) && (memcmp(epatch_buf, RTK_EPATCH_SIGNATURE_NEW, 8) != 0))||
|
||||
memcmp(epatch_buf + buf_len - config_len - 4,
|
||||
Extension_Section_SIGNATURE, 4) != 0) {
|
||||
RTKBT_ERR("Check SIGNATURE error! do not download fw");
|
||||
need_download_fw = 0;
|
||||
} else {
|
||||
/* It does not need to download config when upgrading */
|
||||
buf_len -= config_len;
|
||||
proj_id =
|
||||
rtk_get_fw_project_id(epatch_buf + buf_len -
|
||||
config_len - 5);
|
||||
|
||||
if (lmp_version != project_id[proj_id]) {
|
||||
RTKBT_ERR
|
||||
("lmp_version is %x, project_id is %x, does not match!!!",
|
||||
lmp_version, project_id[proj_id]);
|
||||
need_download_fw = 0;
|
||||
} else {
|
||||
RTKBT_DBG
|
||||
("lmp_version is %x, project_id is %x, match!",
|
||||
lmp_version, project_id[proj_id]);
|
||||
|
||||
if(memcmp(epatch_buf, RTK_EPATCH_SIGNATURE_NEW, 8) == 0) {
|
||||
int key_id = rtk_vendor_read(dev_entry, READ_SEC_PROJ);
|
||||
RTKBT_DBG("%s: key id %d", __func__, key_id);
|
||||
if (key_id < 0) {
|
||||
RTKBT_ERR("%s: Read key id failure", __func__);
|
||||
need_download_fw = 0;
|
||||
fw_len = 0;
|
||||
goto alloc_fail;
|
||||
}
|
||||
rtb_get_patch_header(&buf_len, &patch_node_hdr, epatch_buf, key_id);
|
||||
if(buf_len == 0)
|
||||
goto alloc_fail;
|
||||
RTKBT_DBG("buf_len = 0x%x", buf_len);
|
||||
buf_len += config_len;
|
||||
} else {
|
||||
rtk_get_patch_entry(epatch_buf, ¤t_entry);
|
||||
|
||||
if (current_entry.patch_length == 0)
|
||||
goto alloc_fail;
|
||||
|
||||
buf_len = current_entry.patch_length + config_len;
|
||||
RTKBT_DBG("buf_len = 0x%x", buf_len);
|
||||
}
|
||||
|
||||
if (!(buf = kzalloc(buf_len, GFP_KERNEL))) {
|
||||
RTKBT_ERR
|
||||
("Can't alloc memory for multi fw&config");
|
||||
buf_len = -1;
|
||||
} else {
|
||||
if(memcmp(epatch_buf, RTK_EPATCH_SIGNATURE_NEW, 8) == 0) {
|
||||
int tmp_len = 0;
|
||||
list_for_each_safe(pos, next, &patch_node_hdr.list)
|
||||
{
|
||||
tmp = list_entry(pos, struct patch_node, list);
|
||||
RTKBT_DBG("len = 0x%x", tmp->len);
|
||||
memcpy(buf + tmp_len, tmp->payload, tmp->len);
|
||||
tmp_len += tmp->len;
|
||||
list_del_init(pos);
|
||||
kfree(tmp);
|
||||
}
|
||||
if (config_len) {
|
||||
memcpy(&buf
|
||||
[buf_len - config_len],
|
||||
config_file_buf,
|
||||
config_len);
|
||||
}
|
||||
} else {
|
||||
memcpy(buf,
|
||||
epatch_buf +
|
||||
current_entry.start_offset,
|
||||
current_entry.patch_length);
|
||||
memcpy(buf + current_entry.patch_length - 4, epatch_buf + 8, 4); /*fw version */
|
||||
if (config_len) {
|
||||
memcpy(&buf
|
||||
[buf_len - config_len],
|
||||
config_file_buf,
|
||||
config_len);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
done:
|
||||
RTKBT_DBG("fw:%s exists, config file:%s exists",
|
||||
buf_len > 0 ? "" : "not", config_len > 0 ? "" : "not");
|
||||
if (buf && buf_len > 0 && need_download_fw) {
|
||||
(buf_len > 0) ? "" : "not", (config_len > 0) ? "" : "not");
|
||||
if (buf && (buf_len > 0) && (need_download_fw)) {
|
||||
fw_len = buf_len;
|
||||
xdata->fw_data = buf;
|
||||
*buff = buf;
|
||||
}
|
||||
|
||||
RTKBT_DBG("load_firmware done");
|
||||
alloc_buf_err:
|
||||
extract_err:
|
||||
/* Make sure all the patch nodes freed */
|
||||
list_for_each_safe(pos, next, &patch_node_hdr.list) {
|
||||
tmp = list_entry(pos, struct patch_node, list);
|
||||
list_del_init(pos);
|
||||
kfree(tmp);
|
||||
}
|
||||
proj_id_err:
|
||||
sign_err:
|
||||
|
||||
alloc_fail:
|
||||
release_firmware(fw);
|
||||
|
||||
if (epatch_buf)
|
||||
vfree(epatch_buf);
|
||||
kfree(epatch_buf);
|
||||
|
||||
fw_fail:
|
||||
if (config_file_buf)
|
||||
kfree(config_file_buf);
|
||||
|
||||
fw_fail:
|
||||
if (fw_len == 0)
|
||||
vfree(buf);
|
||||
kfree(buf);
|
||||
|
||||
return fw_len;
|
||||
}
|
||||
@@ -2396,7 +2149,7 @@ int download_data(xchange_data * xdata)
|
||||
uint8_t *pcur;
|
||||
int pkt_len, frag_num, frag_len;
|
||||
int i, ret_val;
|
||||
int j = 0;
|
||||
int j;
|
||||
|
||||
RTKBT_DBG("download_data start");
|
||||
|
||||
@@ -2408,11 +2161,12 @@ int download_data(xchange_data * xdata)
|
||||
frag_len = PATCH_SEG_MAX;
|
||||
|
||||
for (i = 0; i < frag_num; i++) {
|
||||
cmd_para->index = j++;
|
||||
|
||||
if(cmd_para->index == 0x7f)
|
||||
j = 1;
|
||||
if (i > 0x7f)
|
||||
j = (i & 0x7f) + 1;
|
||||
else
|
||||
j = i;
|
||||
|
||||
cmd_para->index = j;
|
||||
if (i == (frag_num - 1)) {
|
||||
cmd_para->index |= DATA_END;
|
||||
frag_len = xdata->fw_len % PATCH_SEG_MAX;
|
||||
|
||||
@@ -1,23 +1,11 @@
|
||||
// SPDX-License-Identifier: GPL-2.0-only
|
||||
/*
|
||||
*
|
||||
* Realtek Bluetooth USB download firmware driver
|
||||
*
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
* the Free Software Foundation; either version 2 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program; if not, write to the Free Software
|
||||
* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
|
||||
*
|
||||
*/
|
||||
#ifndef __RTK_MISC_H__
|
||||
#define __RTK_MISC_H__
|
||||
|
||||
#include <linux/kernel.h>
|
||||
#include <linux/module.h>
|
||||
@@ -26,8 +14,6 @@
|
||||
#include <linux/usb.h>
|
||||
#include <linux/suspend.h>
|
||||
|
||||
#define CONFIG_BTUSB_AUTOSUSPEND 0
|
||||
|
||||
/* Download LPS patch when host suspends or power off
|
||||
* LPS patch name: lps_rtl8xxx_fw
|
||||
* LPS config name: lps_rtl8xxx_config
|
||||
@@ -59,9 +45,7 @@
|
||||
#endif
|
||||
|
||||
#if LINUX_VERSION_CODE > KERNEL_VERSION(2, 6, 33)
|
||||
#define USB_RPM 1
|
||||
#else
|
||||
#define USB_RPM 0
|
||||
#define USB_RPM
|
||||
#endif
|
||||
|
||||
#define CONFIG_NEEDS_BINDING
|
||||
@@ -72,7 +56,7 @@
|
||||
#endif
|
||||
|
||||
/* USB SS */
|
||||
#if (CONFIG_BTUSB_AUTOSUSPEND && USB_RPM)
|
||||
#if (defined CONFIG_BTUSB_AUTOSUSPEND) && (defined USB_RPM)
|
||||
#define BTUSB_RPM
|
||||
#endif
|
||||
|
||||
@@ -98,41 +82,12 @@ struct api_context {
|
||||
int status;
|
||||
};
|
||||
|
||||
int download_special_patch(struct usb_interface *intf, const char *special_name);
|
||||
int download_lps_patch(struct usb_interface *intf);
|
||||
#endif
|
||||
|
||||
int setup_btrealtek_flag(struct usb_interface *intf, struct hci_dev *hdev);
|
||||
|
||||
enum {
|
||||
#if LINUX_VERSION_CODE >= KERNEL_VERSION(5, 8, 0)
|
||||
REALTEK_ALT6_CONTINUOUS_TX_CHIP,
|
||||
#endif
|
||||
|
||||
__REALTEK_NUM_FLAGS,
|
||||
};
|
||||
|
||||
struct btrealtek_data {
|
||||
DECLARE_BITMAP(flags, __REALTEK_NUM_FLAGS);
|
||||
};
|
||||
|
||||
#if LINUX_VERSION_CODE < KERNEL_VERSION(5, 15, 0)
|
||||
static inline void *hci_get_priv(struct hci_dev *hdev)
|
||||
{
|
||||
return (char *)hdev + sizeof(*hdev);
|
||||
}
|
||||
#endif
|
||||
|
||||
#define btrealtek_set_flag(hdev, nr) \
|
||||
do { \
|
||||
struct btrealtek_data *realtek = hci_get_priv((hdev)); \
|
||||
set_bit((nr), realtek->flags); \
|
||||
} while (0)
|
||||
|
||||
#define btrealtek_get_flag(hdev) \
|
||||
(((struct btrealtek_data *)hci_get_priv(hdev))->flags)
|
||||
|
||||
#define btrealtek_test_flag(hdev, nr) test_bit((nr), btrealtek_get_flag(hdev))
|
||||
|
||||
#if defined RTKBT_SUSPEND_WAKEUP || defined RTKBT_SHUTDOWN_WAKEUP || defined RTKBT_SWITCH_PATCH
|
||||
int set_scan(struct usb_interface *intf);
|
||||
#endif
|
||||
|
||||
|
||||
#endif /* __RTK_MISC_H__ */
|
||||
@@ -1,10 +1,10 @@
|
||||
// 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.
|
||||
*
|
||||
* Module to force cpuidle states through debugfs files.
|
||||
*
|
||||
*/
|
||||
#include <nvidia/conftest.h>
|
||||
|
||||
#include <linux/module.h>
|
||||
#include <linux/irq.h>
|
||||
#include <linux/irqdesc.h>
|
||||
@@ -26,16 +26,9 @@ static void suspend_all_device_irqs(void)
|
||||
{
|
||||
struct irq_data *data;
|
||||
struct irq_desc *desc;
|
||||
unsigned int nirqs;
|
||||
int irq;
|
||||
|
||||
#if defined(NV_IRQ_GET_NR_IRQS_PRESENT) /* Linux v6.13 */
|
||||
nirqs = irq_get_nr_irqs();
|
||||
#else
|
||||
nirqs = nr_irqs;
|
||||
#endif
|
||||
|
||||
for (irq = 0, data = irq_get_irq_data(irq); irq < nirqs;
|
||||
for (irq = 0, data = irq_get_irq_data(irq); irq < nr_irqs;
|
||||
irq++, data = irq_get_irq_data(irq)) {
|
||||
if (!data)
|
||||
continue;
|
||||
@@ -51,16 +44,9 @@ static void resume_all_device_irqs(void)
|
||||
{
|
||||
struct irq_data *data;
|
||||
struct irq_desc *desc;
|
||||
unsigned int nirqs;
|
||||
int irq;
|
||||
|
||||
#if defined(NV_IRQ_GET_NR_IRQS_PRESENT)
|
||||
nirqs = irq_get_nr_irqs();
|
||||
#else
|
||||
nirqs = nr_irqs;
|
||||
#endif
|
||||
|
||||
for (irq = 0, data = irq_get_irq_data(irq); irq < nirqs;
|
||||
for (irq = 0, data = irq_get_irq_data(irq); irq < nr_irqs;
|
||||
irq++, data = irq_get_irq_data(irq)) {
|
||||
if (!data)
|
||||
continue;
|
||||
|
||||
@@ -1,7 +1,5 @@
|
||||
// SPDX-License-Identifier: GPL-2.0-only
|
||||
// SPDX-FileCopyrightText: Copyright (c) 2022-2025 NVIDIA CORPORATION & AFFILIATES. All rights reserved.
|
||||
|
||||
#include <nvidia/conftest.h>
|
||||
// SPDX-License-Identifier: GPL-2.0
|
||||
// Copyright (c) 2022-2023, NVIDIA CORPORATION. All rights reserved.
|
||||
|
||||
#include <linux/cpu_cooling.h>
|
||||
#include <linux/cpuidle.h>
|
||||
@@ -228,21 +226,9 @@ static const struct of_device_id tegra_auto_cpuidle_of[] = {
|
||||
{ },
|
||||
};
|
||||
|
||||
#if defined(NV_PLATFORM_DRIVER_STRUCT_REMOVE_RETURNS_VOID) /* Linux v6.11 */
|
||||
static void tegra_auto_cpuidle_remove_wrapper(struct platform_device *pdev)
|
||||
{
|
||||
tegra_auto_cpuidle_remove(pdev);
|
||||
}
|
||||
#else
|
||||
static int tegra_auto_cpuidle_remove_wrapper(struct platform_device *pdev)
|
||||
{
|
||||
return tegra_auto_cpuidle_remove(pdev);
|
||||
}
|
||||
#endif
|
||||
|
||||
static struct platform_driver tegra_auto_cpuidle_driver __refdata = {
|
||||
.probe = tegra_auto_cpuidle_probe,
|
||||
.remove = tegra_auto_cpuidle_remove_wrapper,
|
||||
.remove = tegra_auto_cpuidle_remove,
|
||||
.driver = {
|
||||
.owner = THIS_MODULE,
|
||||
.name = "cpuidle_tegra_auto",
|
||||
|
||||
@@ -1,11 +1,10 @@
|
||||
// SPDX-License-Identifier: GPL-2.0-only
|
||||
// SPDX-FileCopyrightText: Copyright (c) 2019-2025 NVIDIA CORPORATION & AFFILIATES. All rights reserved.
|
||||
/*
|
||||
* Copyright (c) 2019-2024, NVIDIA Corporation. All Rights Reserved.
|
||||
*
|
||||
* Cryptographic API.
|
||||
*/
|
||||
|
||||
#include <nvidia/conftest.h>
|
||||
|
||||
#include <linux/module.h>
|
||||
#include <linux/init.h>
|
||||
#include <linux/errno.h>
|
||||
@@ -5210,21 +5209,9 @@ static const struct dev_pm_ops tegra_hv_pm_ops = {
|
||||
};
|
||||
#endif /* CONFIG_PM */
|
||||
|
||||
#if defined(NV_PLATFORM_DRIVER_STRUCT_REMOVE_RETURNS_VOID) /* Linux v6.11 */
|
||||
static void tegra_hv_vse_safety_remove_wrapper(struct platform_device *pdev)
|
||||
{
|
||||
tegra_hv_vse_safety_remove(pdev);
|
||||
}
|
||||
#else
|
||||
static int tegra_hv_vse_safety_remove_wrapper(struct platform_device *pdev)
|
||||
{
|
||||
return tegra_hv_vse_safety_remove(pdev);
|
||||
}
|
||||
#endif
|
||||
|
||||
static struct platform_driver tegra_hv_vse_safety_driver = {
|
||||
.probe = tegra_hv_vse_safety_probe,
|
||||
.remove = tegra_hv_vse_safety_remove_wrapper,
|
||||
.remove = tegra_hv_vse_safety_remove,
|
||||
.shutdown = tegra_hv_vse_safety_shutdown,
|
||||
.driver = {
|
||||
.name = "tegra_hv_vse_safety",
|
||||
|
||||
@@ -1,12 +1,10 @@
|
||||
// SPDX-License-Identifier: GPL-2.0-only
|
||||
/*
|
||||
* SPDX-FileCopyrightText: Copyright (c) 2020-2025 NVIDIA CORPORATION & AFFILIATES. All rights reserved.
|
||||
* Copyright (c) 2020-2023, NVIDIA CORPORATION. All rights reserved.
|
||||
*
|
||||
* Support for Tegra NVRNG Engine Error Handling.
|
||||
*/
|
||||
|
||||
#include <nvidia/conftest.h>
|
||||
|
||||
#include <asm/io.h>
|
||||
#include <linux/acpi.h>
|
||||
#include <linux/clk.h>
|
||||
@@ -359,21 +357,9 @@ static const struct of_device_id tegra_se_nvrng_of_match[] = {
|
||||
};
|
||||
MODULE_DEVICE_TABLE(of, tegra_se_nvrng_of_match);
|
||||
|
||||
#if defined(NV_PLATFORM_DRIVER_STRUCT_REMOVE_RETURNS_VOID) /* Linux v6.11 */
|
||||
static void tegra_se_nvrng_remove_wrapper(struct platform_device *pdev)
|
||||
{
|
||||
tegra_se_nvrng_remove(pdev);
|
||||
}
|
||||
#else
|
||||
static int tegra_se_nvrng_remove_wrapper(struct platform_device *pdev)
|
||||
{
|
||||
return tegra_se_nvrng_remove(pdev);
|
||||
}
|
||||
#endif
|
||||
|
||||
static struct platform_driver tegra_se_nvrng_driver = {
|
||||
.probe = tegra_se_nvrng_probe,
|
||||
.remove = tegra_se_nvrng_remove_wrapper,
|
||||
.remove = tegra_se_nvrng_remove,
|
||||
.driver = {
|
||||
.name = "tegra-se-nvrng",
|
||||
.owner = THIS_MODULE,
|
||||
|
||||
@@ -25,7 +25,7 @@
|
||||
#include "tegra-se.h"
|
||||
|
||||
struct tegra_aes_ctx {
|
||||
#ifndef NV_CRYPTO_ENGINE_OPS_PRESENT
|
||||
#ifndef NV_CONFTEST_REMOVE_STRUCT_CRYPTO_ENGINE_CTX
|
||||
struct crypto_engine_ctx enginectx;
|
||||
#endif
|
||||
struct tegra_se *se;
|
||||
@@ -50,7 +50,7 @@ struct tegra_aes_reqctx {
|
||||
};
|
||||
|
||||
struct tegra_aead_ctx {
|
||||
#ifndef NV_CRYPTO_ENGINE_OPS_PRESENT
|
||||
#ifndef NV_CONFTEST_REMOVE_STRUCT_CRYPTO_ENGINE_CTX
|
||||
struct crypto_engine_ctx enginectx;
|
||||
#endif
|
||||
struct tegra_se *se;
|
||||
@@ -78,7 +78,7 @@ struct tegra_aead_reqctx {
|
||||
};
|
||||
|
||||
struct tegra_cmac_ctx {
|
||||
#ifndef NV_CRYPTO_ENGINE_OPS_PRESENT
|
||||
#ifndef NV_CONFTEST_REMOVE_STRUCT_CRYPTO_ENGINE_CTX
|
||||
struct crypto_engine_ctx enginectx;
|
||||
#endif
|
||||
struct tegra_se *se;
|
||||
@@ -357,7 +357,7 @@ static int tegra_aes_cra_init(struct crypto_skcipher *tfm)
|
||||
const char *algname;
|
||||
int ret;
|
||||
|
||||
#ifdef NV_CRYPTO_ENGINE_OPS_PRESENT
|
||||
#ifdef NV_CONFTEST_REMOVE_STRUCT_CRYPTO_ENGINE_CTX
|
||||
se_alg = container_of(alg, struct tegra_se_alg, alg.skcipher.base);
|
||||
#else
|
||||
se_alg = container_of(alg, struct tegra_se_alg, alg.skcipher);
|
||||
@@ -380,7 +380,7 @@ static int tegra_aes_cra_init(struct crypto_skcipher *tfm)
|
||||
|
||||
ctx->alg = ret;
|
||||
|
||||
#ifndef NV_CRYPTO_ENGINE_OPS_PRESENT
|
||||
#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_aes_do_one_req;
|
||||
@@ -533,7 +533,7 @@ static int tegra_aes_decrypt(struct skcipher_request *req)
|
||||
static struct tegra_se_alg tegra_aes_algs[] = {
|
||||
{
|
||||
.alg.skcipher = {
|
||||
#ifdef NV_CRYPTO_ENGINE_OPS_PRESENT
|
||||
#ifdef NV_CONFTEST_REMOVE_STRUCT_CRYPTO_ENGINE_CTX
|
||||
.base = {
|
||||
#endif
|
||||
.init = tegra_aes_cra_init,
|
||||
@@ -554,14 +554,14 @@ static struct tegra_se_alg tegra_aes_algs[] = {
|
||||
.cra_alignmask = 0xf,
|
||||
.cra_module = THIS_MODULE,
|
||||
},
|
||||
#ifdef NV_CRYPTO_ENGINE_OPS_PRESENT
|
||||
#ifdef NV_CONFTEST_REMOVE_STRUCT_CRYPTO_ENGINE_CTX
|
||||
},
|
||||
.op.do_one_request = tegra_aes_do_one_req,
|
||||
#endif
|
||||
}
|
||||
}, {
|
||||
.alg.skcipher = {
|
||||
#ifdef NV_CRYPTO_ENGINE_OPS_PRESENT
|
||||
#ifdef NV_CONFTEST_REMOVE_STRUCT_CRYPTO_ENGINE_CTX
|
||||
.base = {
|
||||
#endif
|
||||
.init = tegra_aes_cra_init,
|
||||
@@ -581,14 +581,14 @@ static struct tegra_se_alg tegra_aes_algs[] = {
|
||||
.cra_alignmask = 0xf,
|
||||
.cra_module = THIS_MODULE,
|
||||
},
|
||||
#ifdef NV_CRYPTO_ENGINE_OPS_PRESENT
|
||||
#ifdef NV_CONFTEST_REMOVE_STRUCT_CRYPTO_ENGINE_CTX
|
||||
},
|
||||
.op.do_one_request = tegra_aes_do_one_req,
|
||||
#endif
|
||||
}
|
||||
}, {
|
||||
.alg.skcipher = {
|
||||
#ifdef NV_CRYPTO_ENGINE_OPS_PRESENT
|
||||
#ifdef NV_CONFTEST_REMOVE_STRUCT_CRYPTO_ENGINE_CTX
|
||||
.base = {
|
||||
#endif
|
||||
.init = tegra_aes_cra_init,
|
||||
@@ -609,14 +609,14 @@ static struct tegra_se_alg tegra_aes_algs[] = {
|
||||
.cra_alignmask = 0xf,
|
||||
.cra_module = THIS_MODULE,
|
||||
},
|
||||
#ifdef NV_CRYPTO_ENGINE_OPS_PRESENT
|
||||
#ifdef NV_CONFTEST_REMOVE_STRUCT_CRYPTO_ENGINE_CTX
|
||||
},
|
||||
.op.do_one_request = tegra_aes_do_one_req,
|
||||
#endif
|
||||
}
|
||||
}, {
|
||||
.alg.skcipher = {
|
||||
#ifdef NV_CRYPTO_ENGINE_OPS_PRESENT
|
||||
#ifdef NV_CONFTEST_REMOVE_STRUCT_CRYPTO_ENGINE_CTX
|
||||
.base = {
|
||||
#endif
|
||||
.init = tegra_aes_cra_init,
|
||||
@@ -636,7 +636,7 @@ static struct tegra_se_alg tegra_aes_algs[] = {
|
||||
.cra_alignmask = (__alignof__(u64) - 1),
|
||||
.cra_module = THIS_MODULE,
|
||||
},
|
||||
#ifdef NV_CRYPTO_ENGINE_OPS_PRESENT
|
||||
#ifdef NV_CONFTEST_REMOVE_STRUCT_CRYPTO_ENGINE_CTX
|
||||
},
|
||||
.op.do_one_request = tegra_aes_do_one_req,
|
||||
#endif
|
||||
@@ -1390,7 +1390,7 @@ static int tegra_ccm_cra_init(struct crypto_aead *tfm)
|
||||
|
||||
algname = crypto_tfm_alg_name(&tfm->base);
|
||||
|
||||
#ifdef NV_CRYPTO_ENGINE_OPS_PRESENT
|
||||
#ifdef NV_CONFTEST_REMOVE_STRUCT_CRYPTO_ENGINE_CTX
|
||||
se_alg = container_of(alg, struct tegra_se_alg, alg.aead.base);
|
||||
#else
|
||||
se_alg = container_of(alg, struct tegra_se_alg, alg.aead);
|
||||
@@ -1410,7 +1410,7 @@ static int tegra_ccm_cra_init(struct crypto_aead *tfm)
|
||||
|
||||
ctx->alg = ret;
|
||||
|
||||
#ifndef NV_CRYPTO_ENGINE_OPS_PRESENT
|
||||
#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_ccm_do_one_req;
|
||||
@@ -1429,7 +1429,7 @@ static int tegra_gcm_cra_init(struct crypto_aead *tfm)
|
||||
|
||||
algname = crypto_tfm_alg_name(&tfm->base);
|
||||
|
||||
#ifdef NV_CRYPTO_ENGINE_OPS_PRESENT
|
||||
#ifdef NV_CONFTEST_REMOVE_STRUCT_CRYPTO_ENGINE_CTX
|
||||
se_alg = container_of(alg, struct tegra_se_alg, alg.aead.base);
|
||||
#else
|
||||
se_alg = container_of(alg, struct tegra_se_alg, alg.aead);
|
||||
@@ -1449,7 +1449,7 @@ static int tegra_gcm_cra_init(struct crypto_aead *tfm)
|
||||
|
||||
ctx->alg = ret;
|
||||
|
||||
#ifndef NV_CRYPTO_ENGINE_OPS_PRESENT
|
||||
#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_gcm_do_one_req;
|
||||
@@ -1809,7 +1809,7 @@ static int tegra_cmac_cra_init(struct crypto_tfm *tfm)
|
||||
int ret;
|
||||
|
||||
algname = crypto_tfm_alg_name(tfm);
|
||||
#ifdef NV_CRYPTO_ENGINE_OPS_PRESENT
|
||||
#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);
|
||||
@@ -1829,7 +1829,7 @@ static int tegra_cmac_cra_init(struct crypto_tfm *tfm)
|
||||
|
||||
ctx->alg = ret;
|
||||
|
||||
#ifndef NV_CRYPTO_ENGINE_OPS_PRESENT
|
||||
#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_cmac_do_one_req;
|
||||
@@ -1969,7 +1969,7 @@ static int tegra_cmac_import(struct ahash_request *req, const void *in)
|
||||
static struct tegra_se_alg tegra_aead_algs[] = {
|
||||
{
|
||||
.alg.aead = {
|
||||
#ifdef NV_CRYPTO_ENGINE_OPS_PRESENT
|
||||
#ifdef NV_CONFTEST_REMOVE_STRUCT_CRYPTO_ENGINE_CTX
|
||||
.base = {
|
||||
#endif
|
||||
.init = tegra_gcm_cra_init,
|
||||
@@ -1989,14 +1989,14 @@ static struct tegra_se_alg tegra_aead_algs[] = {
|
||||
.cra_alignmask = 0xf,
|
||||
.cra_module = THIS_MODULE,
|
||||
},
|
||||
#ifdef NV_CRYPTO_ENGINE_OPS_PRESENT
|
||||
#ifdef NV_CONFTEST_REMOVE_STRUCT_CRYPTO_ENGINE_CTX
|
||||
},
|
||||
.op.do_one_request = tegra_gcm_do_one_req,
|
||||
#endif
|
||||
}
|
||||
}, {
|
||||
.alg.aead = {
|
||||
#ifdef NV_CRYPTO_ENGINE_OPS_PRESENT
|
||||
#ifdef NV_CONFTEST_REMOVE_STRUCT_CRYPTO_ENGINE_CTX
|
||||
.base = {
|
||||
#endif
|
||||
.init = tegra_ccm_cra_init,
|
||||
@@ -2017,7 +2017,7 @@ static struct tegra_se_alg tegra_aead_algs[] = {
|
||||
.cra_alignmask = 0xf,
|
||||
.cra_module = THIS_MODULE,
|
||||
},
|
||||
#ifdef NV_CRYPTO_ENGINE_OPS_PRESENT
|
||||
#ifdef NV_CONFTEST_REMOVE_STRUCT_CRYPTO_ENGINE_CTX
|
||||
},
|
||||
.op.do_one_request = tegra_ccm_do_one_req,
|
||||
#endif
|
||||
@@ -2028,7 +2028,7 @@ static struct tegra_se_alg tegra_aead_algs[] = {
|
||||
static struct tegra_se_alg tegra_cmac_algs[] = {
|
||||
{
|
||||
.alg.ahash = {
|
||||
#ifdef NV_CRYPTO_ENGINE_OPS_PRESENT
|
||||
#ifdef NV_CONFTEST_REMOVE_STRUCT_CRYPTO_ENGINE_CTX
|
||||
.base = {
|
||||
#endif
|
||||
.init = tegra_cmac_init,
|
||||
@@ -2053,7 +2053,7 @@ static struct tegra_se_alg tegra_cmac_algs[] = {
|
||||
.cra_init = tegra_cmac_cra_init,
|
||||
.cra_exit = tegra_cmac_cra_exit,
|
||||
},
|
||||
#ifdef NV_CRYPTO_ENGINE_OPS_PRESENT
|
||||
#ifdef NV_CONFTEST_REMOVE_STRUCT_CRYPTO_ENGINE_CTX
|
||||
},
|
||||
.op.do_one_request = tegra_cmac_do_one_req,
|
||||
#endif
|
||||
@@ -2061,7 +2061,7 @@ static struct tegra_se_alg tegra_cmac_algs[] = {
|
||||
}
|
||||
};
|
||||
|
||||
#ifdef NV_CRYPTO_ENGINE_OPS_PRESENT
|
||||
#ifdef NV_CONFTEST_REMOVE_STRUCT_CRYPTO_ENGINE_CTX
|
||||
int tegra_init_aes(struct tegra_se *se)
|
||||
{
|
||||
struct aead_engine_alg *aead_alg;
|
||||
|
||||
@@ -23,7 +23,7 @@
|
||||
#include "tegra-se.h"
|
||||
|
||||
struct tegra_sha_ctx {
|
||||
#ifndef NV_CRYPTO_ENGINE_OPS_PRESENT
|
||||
#ifndef NV_CONFTEST_REMOVE_STRUCT_CRYPTO_ENGINE_CTX
|
||||
struct crypto_engine_ctx enginectx;
|
||||
#endif
|
||||
struct tegra_se *se;
|
||||
@@ -488,7 +488,7 @@ static int tegra_sha_cra_init(struct crypto_tfm *tfm)
|
||||
int ret;
|
||||
|
||||
algname = crypto_tfm_alg_name(tfm);
|
||||
#ifdef NV_CRYPTO_ENGINE_OPS_PRESENT
|
||||
#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);
|
||||
@@ -511,7 +511,7 @@ static int tegra_sha_cra_init(struct crypto_tfm *tfm)
|
||||
|
||||
ctx->alg = ret;
|
||||
|
||||
#ifndef NV_CRYPTO_ENGINE_OPS_PRESENT
|
||||
#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;
|
||||
@@ -686,7 +686,7 @@ static int tegra_sha_import(struct ahash_request *req, const void *in)
|
||||
static struct tegra_se_alg tegra_hash_algs[] = {
|
||||
{
|
||||
.alg.ahash = {
|
||||
#ifdef NV_CRYPTO_ENGINE_OPS_PRESENT
|
||||
#ifdef NV_CONFTEST_REMOVE_STRUCT_CRYPTO_ENGINE_CTX
|
||||
.base = {
|
||||
#endif
|
||||
.init = tegra_sha_init,
|
||||
@@ -710,14 +710,14 @@ static struct tegra_se_alg tegra_hash_algs[] = {
|
||||
.cra_init = tegra_sha_cra_init,
|
||||
.cra_exit = tegra_sha_cra_exit,
|
||||
}
|
||||
#ifdef NV_CRYPTO_ENGINE_OPS_PRESENT
|
||||
#ifdef NV_CONFTEST_REMOVE_STRUCT_CRYPTO_ENGINE_CTX
|
||||
},
|
||||
.op.do_one_request = tegra_sha_do_one_req,
|
||||
#endif
|
||||
}
|
||||
}, {
|
||||
.alg.ahash = {
|
||||
#ifdef NV_CRYPTO_ENGINE_OPS_PRESENT
|
||||
#ifdef NV_CONFTEST_REMOVE_STRUCT_CRYPTO_ENGINE_CTX
|
||||
.base = {
|
||||
#endif
|
||||
.init = tegra_sha_init,
|
||||
@@ -741,14 +741,14 @@ static struct tegra_se_alg tegra_hash_algs[] = {
|
||||
.cra_init = tegra_sha_cra_init,
|
||||
.cra_exit = tegra_sha_cra_exit,
|
||||
}
|
||||
#ifdef NV_CRYPTO_ENGINE_OPS_PRESENT
|
||||
#ifdef NV_CONFTEST_REMOVE_STRUCT_CRYPTO_ENGINE_CTX
|
||||
},
|
||||
.op.do_one_request = tegra_sha_do_one_req,
|
||||
#endif
|
||||
}
|
||||
}, {
|
||||
.alg.ahash = {
|
||||
#ifdef NV_CRYPTO_ENGINE_OPS_PRESENT
|
||||
#ifdef NV_CONFTEST_REMOVE_STRUCT_CRYPTO_ENGINE_CTX
|
||||
.base = {
|
||||
#endif
|
||||
.init = tegra_sha_init,
|
||||
@@ -772,14 +772,14 @@ static struct tegra_se_alg tegra_hash_algs[] = {
|
||||
.cra_init = tegra_sha_cra_init,
|
||||
.cra_exit = tegra_sha_cra_exit,
|
||||
}
|
||||
#ifdef NV_CRYPTO_ENGINE_OPS_PRESENT
|
||||
#ifdef NV_CONFTEST_REMOVE_STRUCT_CRYPTO_ENGINE_CTX
|
||||
},
|
||||
.op.do_one_request = tegra_sha_do_one_req,
|
||||
#endif
|
||||
}
|
||||
}, {
|
||||
.alg.ahash = {
|
||||
#ifdef NV_CRYPTO_ENGINE_OPS_PRESENT
|
||||
#ifdef NV_CONFTEST_REMOVE_STRUCT_CRYPTO_ENGINE_CTX
|
||||
.base = {
|
||||
#endif
|
||||
.init = tegra_sha_init,
|
||||
@@ -803,14 +803,14 @@ static struct tegra_se_alg tegra_hash_algs[] = {
|
||||
.cra_init = tegra_sha_cra_init,
|
||||
.cra_exit = tegra_sha_cra_exit,
|
||||
}
|
||||
#ifdef NV_CRYPTO_ENGINE_OPS_PRESENT
|
||||
#ifdef NV_CONFTEST_REMOVE_STRUCT_CRYPTO_ENGINE_CTX
|
||||
},
|
||||
.op.do_one_request = tegra_sha_do_one_req,
|
||||
#endif
|
||||
}
|
||||
}, {
|
||||
.alg.ahash = {
|
||||
#ifdef NV_CRYPTO_ENGINE_OPS_PRESENT
|
||||
#ifdef NV_CONFTEST_REMOVE_STRUCT_CRYPTO_ENGINE_CTX
|
||||
.base = {
|
||||
#endif
|
||||
.init = tegra_sha_init,
|
||||
@@ -834,14 +834,14 @@ static struct tegra_se_alg tegra_hash_algs[] = {
|
||||
.cra_init = tegra_sha_cra_init,
|
||||
.cra_exit = tegra_sha_cra_exit,
|
||||
}
|
||||
#ifdef NV_CRYPTO_ENGINE_OPS_PRESENT
|
||||
#ifdef NV_CONFTEST_REMOVE_STRUCT_CRYPTO_ENGINE_CTX
|
||||
},
|
||||
.op.do_one_request = tegra_sha_do_one_req,
|
||||
#endif
|
||||
}
|
||||
}, {
|
||||
.alg.ahash = {
|
||||
#ifdef NV_CRYPTO_ENGINE_OPS_PRESENT
|
||||
#ifdef NV_CONFTEST_REMOVE_STRUCT_CRYPTO_ENGINE_CTX
|
||||
.base = {
|
||||
#endif
|
||||
.init = tegra_sha_init,
|
||||
@@ -865,14 +865,14 @@ static struct tegra_se_alg tegra_hash_algs[] = {
|
||||
.cra_init = tegra_sha_cra_init,
|
||||
.cra_exit = tegra_sha_cra_exit,
|
||||
}
|
||||
#ifdef NV_CRYPTO_ENGINE_OPS_PRESENT
|
||||
#ifdef NV_CONFTEST_REMOVE_STRUCT_CRYPTO_ENGINE_CTX
|
||||
},
|
||||
.op.do_one_request = tegra_sha_do_one_req,
|
||||
#endif
|
||||
}
|
||||
}, {
|
||||
.alg.ahash = {
|
||||
#ifdef NV_CRYPTO_ENGINE_OPS_PRESENT
|
||||
#ifdef NV_CONFTEST_REMOVE_STRUCT_CRYPTO_ENGINE_CTX
|
||||
.base = {
|
||||
#endif
|
||||
.init = tegra_sha_init,
|
||||
@@ -896,14 +896,14 @@ static struct tegra_se_alg tegra_hash_algs[] = {
|
||||
.cra_init = tegra_sha_cra_init,
|
||||
.cra_exit = tegra_sha_cra_exit,
|
||||
}
|
||||
#ifdef NV_CRYPTO_ENGINE_OPS_PRESENT
|
||||
#ifdef NV_CONFTEST_REMOVE_STRUCT_CRYPTO_ENGINE_CTX
|
||||
},
|
||||
.op.do_one_request = tegra_sha_do_one_req,
|
||||
#endif
|
||||
}
|
||||
}, {
|
||||
.alg.ahash = {
|
||||
#ifdef NV_CRYPTO_ENGINE_OPS_PRESENT
|
||||
#ifdef NV_CONFTEST_REMOVE_STRUCT_CRYPTO_ENGINE_CTX
|
||||
.base = {
|
||||
#endif
|
||||
.init = tegra_sha_init,
|
||||
@@ -927,14 +927,14 @@ static struct tegra_se_alg tegra_hash_algs[] = {
|
||||
.cra_init = tegra_sha_cra_init,
|
||||
.cra_exit = tegra_sha_cra_exit,
|
||||
}
|
||||
#ifdef NV_CRYPTO_ENGINE_OPS_PRESENT
|
||||
#ifdef NV_CONFTEST_REMOVE_STRUCT_CRYPTO_ENGINE_CTX
|
||||
},
|
||||
.op.do_one_request = tegra_sha_do_one_req,
|
||||
#endif
|
||||
}
|
||||
}, {
|
||||
.alg.ahash = {
|
||||
#ifdef NV_CRYPTO_ENGINE_OPS_PRESENT
|
||||
#ifdef NV_CONFTEST_REMOVE_STRUCT_CRYPTO_ENGINE_CTX
|
||||
.base = {
|
||||
#endif
|
||||
.init = tegra_sha_init,
|
||||
@@ -958,7 +958,7 @@ static struct tegra_se_alg tegra_hash_algs[] = {
|
||||
.cra_init = tegra_sha_cra_init,
|
||||
.cra_exit = tegra_sha_cra_exit,
|
||||
}
|
||||
#ifdef NV_CRYPTO_ENGINE_OPS_PRESENT
|
||||
#ifdef NV_CONFTEST_REMOVE_STRUCT_CRYPTO_ENGINE_CTX
|
||||
},
|
||||
.op.do_one_request = tegra_sha_do_one_req,
|
||||
#endif
|
||||
@@ -966,7 +966,7 @@ static struct tegra_se_alg tegra_hash_algs[] = {
|
||||
}, {
|
||||
.alg_base = "sha224",
|
||||
.alg.ahash = {
|
||||
#ifdef NV_CRYPTO_ENGINE_OPS_PRESENT
|
||||
#ifdef NV_CONFTEST_REMOVE_STRUCT_CRYPTO_ENGINE_CTX
|
||||
.base = {
|
||||
#endif
|
||||
.init = tegra_sha_init,
|
||||
@@ -991,7 +991,7 @@ static struct tegra_se_alg tegra_hash_algs[] = {
|
||||
.cra_init = tegra_sha_cra_init,
|
||||
.cra_exit = tegra_sha_cra_exit,
|
||||
}
|
||||
#ifdef NV_CRYPTO_ENGINE_OPS_PRESENT
|
||||
#ifdef NV_CONFTEST_REMOVE_STRUCT_CRYPTO_ENGINE_CTX
|
||||
},
|
||||
.op.do_one_request = tegra_sha_do_one_req,
|
||||
#endif
|
||||
@@ -999,7 +999,7 @@ static struct tegra_se_alg tegra_hash_algs[] = {
|
||||
}, {
|
||||
.alg_base = "sha256",
|
||||
.alg.ahash = {
|
||||
#ifdef NV_CRYPTO_ENGINE_OPS_PRESENT
|
||||
#ifdef NV_CONFTEST_REMOVE_STRUCT_CRYPTO_ENGINE_CTX
|
||||
.base = {
|
||||
#endif
|
||||
.init = tegra_sha_init,
|
||||
@@ -1024,7 +1024,7 @@ static struct tegra_se_alg tegra_hash_algs[] = {
|
||||
.cra_init = tegra_sha_cra_init,
|
||||
.cra_exit = tegra_sha_cra_exit,
|
||||
}
|
||||
#ifdef NV_CRYPTO_ENGINE_OPS_PRESENT
|
||||
#ifdef NV_CONFTEST_REMOVE_STRUCT_CRYPTO_ENGINE_CTX
|
||||
},
|
||||
.op.do_one_request = tegra_sha_do_one_req,
|
||||
#endif
|
||||
@@ -1032,7 +1032,7 @@ static struct tegra_se_alg tegra_hash_algs[] = {
|
||||
}, {
|
||||
.alg_base = "sha384",
|
||||
.alg.ahash = {
|
||||
#ifdef NV_CRYPTO_ENGINE_OPS_PRESENT
|
||||
#ifdef NV_CONFTEST_REMOVE_STRUCT_CRYPTO_ENGINE_CTX
|
||||
.base = {
|
||||
#endif
|
||||
.init = tegra_sha_init,
|
||||
@@ -1057,7 +1057,7 @@ static struct tegra_se_alg tegra_hash_algs[] = {
|
||||
.cra_init = tegra_sha_cra_init,
|
||||
.cra_exit = tegra_sha_cra_exit,
|
||||
}
|
||||
#ifdef NV_CRYPTO_ENGINE_OPS_PRESENT
|
||||
#ifdef NV_CONFTEST_REMOVE_STRUCT_CRYPTO_ENGINE_CTX
|
||||
},
|
||||
.op.do_one_request = tegra_sha_do_one_req,
|
||||
#endif
|
||||
@@ -1065,7 +1065,7 @@ static struct tegra_se_alg tegra_hash_algs[] = {
|
||||
}, {
|
||||
.alg_base = "sha512",
|
||||
.alg.ahash = {
|
||||
#ifdef NV_CRYPTO_ENGINE_OPS_PRESENT
|
||||
#ifdef NV_CONFTEST_REMOVE_STRUCT_CRYPTO_ENGINE_CTX
|
||||
.base = {
|
||||
#endif
|
||||
.init = tegra_sha_init,
|
||||
@@ -1090,7 +1090,7 @@ static struct tegra_se_alg tegra_hash_algs[] = {
|
||||
.cra_init = tegra_sha_cra_init,
|
||||
.cra_exit = tegra_sha_cra_exit,
|
||||
}
|
||||
#ifdef NV_CRYPTO_ENGINE_OPS_PRESENT
|
||||
#ifdef NV_CONFTEST_REMOVE_STRUCT_CRYPTO_ENGINE_CTX
|
||||
},
|
||||
.op.do_one_request = tegra_sha_do_one_req,
|
||||
#endif
|
||||
@@ -1133,7 +1133,7 @@ static int tegra_hash_kac_manifest(u32 user, u32 alg, u32 keylen)
|
||||
|
||||
int tegra_init_hash(struct tegra_se *se)
|
||||
{
|
||||
#ifdef NV_CRYPTO_ENGINE_OPS_PRESENT
|
||||
#ifdef NV_CONFTEST_REMOVE_STRUCT_CRYPTO_ENGINE_CTX
|
||||
struct ahash_engine_alg *alg;
|
||||
#else
|
||||
struct ahash_alg *alg;
|
||||
@@ -1148,7 +1148,7 @@ int tegra_init_hash(struct tegra_se *se)
|
||||
|
||||
ret = CRYPTO_REGISTER(ahash, alg);
|
||||
if (ret) {
|
||||
#ifdef NV_CRYPTO_ENGINE_OPS_PRESENT
|
||||
#ifdef NV_CONFTEST_REMOVE_STRUCT_CRYPTO_ENGINE_CTX
|
||||
dev_err(se->dev, "failed to register %s\n",
|
||||
alg->base.halg.base.cra_name);
|
||||
#else
|
||||
|
||||
@@ -1,11 +1,9 @@
|
||||
// SPDX-License-Identifier: GPL-2.0-only
|
||||
// SPDX-FileCopyrightText: Copyright (c) 2023-2025 NVIDIA CORPORATION & AFFILIATES. All rights reserved.
|
||||
// SPDX-FileCopyrightText: Copyright (c) 2023-2024 NVIDIA CORPORATION & AFFILIATES. All rights reserved.
|
||||
/*
|
||||
* Crypto driver for NVIDIA Security Engine in Tegra Chips
|
||||
*/
|
||||
|
||||
#include <nvidia/conftest.h>
|
||||
|
||||
#include <linux/clk.h>
|
||||
#include <linux/dma-mapping.h>
|
||||
#include <linux/module.h>
|
||||
@@ -394,25 +392,13 @@ static const struct of_device_id tegra_se_of_match[] = {
|
||||
};
|
||||
MODULE_DEVICE_TABLE(of, tegra_se_of_match);
|
||||
|
||||
#if defined(NV_PLATFORM_DRIVER_STRUCT_REMOVE_RETURNS_VOID) /* Linux v6.11 */
|
||||
static void tegra_se_remove_wrapper(struct platform_device *pdev)
|
||||
{
|
||||
tegra_se_remove(pdev);
|
||||
}
|
||||
#else
|
||||
static int tegra_se_remove_wrapper(struct platform_device *pdev)
|
||||
{
|
||||
return tegra_se_remove(pdev);
|
||||
}
|
||||
#endif
|
||||
|
||||
static struct platform_driver tegra_se_driver = {
|
||||
.driver = {
|
||||
.name = "tegra-se",
|
||||
.of_match_table = tegra_se_of_match,
|
||||
},
|
||||
.probe = tegra_se_probe,
|
||||
.remove = tegra_se_remove_wrapper,
|
||||
.remove = tegra_se_remove,
|
||||
};
|
||||
|
||||
static int tegra_se_host1x_probe(struct host1x_device *dev)
|
||||
|
||||
@@ -350,18 +350,18 @@
|
||||
#define SHA_UPDATE BIT(1)
|
||||
#define SHA_FINAL BIT(2)
|
||||
|
||||
#if NV_IS_EXPORT_SYMBOL_PRESENT_crypto_engine_register_aead /* Linux v6.6 */
|
||||
#define NV_CRYPTO_ENGINE_OPS_PRESENT
|
||||
#endif
|
||||
|
||||
#ifdef NV_CRYPTO_ENGINE_OPS_PRESENT
|
||||
#ifdef NV_CONFTEST_REMOVE_STRUCT_CRYPTO_ENGINE_CTX
|
||||
#define CRYPTO_REGISTER(alg, x) \
|
||||
crypto_engine_register_##alg(x)
|
||||
#define CRYPTO_UNREGISTER(alg, x) \
|
||||
crypto_engine_unregister_##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
|
||||
@@ -403,14 +403,14 @@ struct tegra_se_alg {
|
||||
const char *alg_base;
|
||||
|
||||
union {
|
||||
#ifdef NV_CRYPTO_ENGINE_OPS_PRESENT
|
||||
struct skcipher_engine_alg skcipher;
|
||||
struct aead_engine_alg aead;
|
||||
struct ahash_engine_alg ahash;
|
||||
#else
|
||||
#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
|
||||
} alg;
|
||||
};
|
||||
|
||||
@@ -1,10 +1,8 @@
|
||||
// SPDX-License-Identifier: GPL-2.0-only
|
||||
/*
|
||||
* SPDX-FileCopyrightText: Copyright (c) 2023-2024 NVIDIA CORPORATION & AFFILIATES. All rights reserved.
|
||||
* Copyright (c) 2023, NVIDIA Corporation. All rights reserved.
|
||||
*/
|
||||
|
||||
#include <nvidia/conftest.h>
|
||||
|
||||
#include <linux/devfreq.h>
|
||||
#include <linux/devfreq/tegra_wmark.h>
|
||||
#include <linux/device.h>
|
||||
@@ -15,7 +13,11 @@
|
||||
#include <linux/slab.h>
|
||||
#include <linux/version.h>
|
||||
|
||||
#if LINUX_VERSION_CODE >= KERNEL_VERSION(5, 19, 0)
|
||||
#include <drivers-private/devfreq/k519/governor.h>
|
||||
#else
|
||||
#include <drivers-private/devfreq/governor.h>
|
||||
#endif
|
||||
|
||||
/**
|
||||
* struct tegra_wmark_data - governor private data stored in struct devfreq
|
||||
@@ -63,12 +65,12 @@ struct tegra_wmark_data {
|
||||
|
||||
static int devfreq_get_freq_index(struct devfreq *df, unsigned long freq)
|
||||
{
|
||||
#if defined(NV_DEVFREQ_HAS_FREQ_TABLE)
|
||||
unsigned long *freq_table = df->freq_table;
|
||||
unsigned int max_state = df->max_state;
|
||||
#else
|
||||
#if LINUX_VERSION_CODE < KERNEL_VERSION(5, 19, 0)
|
||||
unsigned long *freq_table = df->profile->freq_table;
|
||||
unsigned int max_state = df->profile->max_state;
|
||||
#else
|
||||
unsigned long *freq_table = df->freq_table;
|
||||
unsigned int max_state = df->max_state;
|
||||
#endif
|
||||
int i;
|
||||
|
||||
@@ -84,12 +86,12 @@ static int devfreq_tegra_wmark_target_freq(struct devfreq *df, unsigned long *fr
|
||||
{
|
||||
struct tegra_wmark_data *govdata = df->governor_data;
|
||||
struct devfreq_tegra_wmark_data *drvdata = df->data;
|
||||
#if defined(NV_DEVFREQ_HAS_FREQ_TABLE)
|
||||
unsigned long *freq_table = df->freq_table;
|
||||
unsigned int max_state = df->max_state;
|
||||
#else
|
||||
#if LINUX_VERSION_CODE < KERNEL_VERSION(5, 19, 0)
|
||||
unsigned long *freq_table = df->profile->freq_table;
|
||||
unsigned int max_state = df->profile->max_state;
|
||||
#else
|
||||
unsigned long *freq_table = df->freq_table;
|
||||
unsigned int max_state = df->max_state;
|
||||
#endif
|
||||
int target_index = 0;
|
||||
|
||||
@@ -117,6 +119,7 @@ static int devfreq_tegra_wmark_target_freq(struct devfreq *df, unsigned long *fr
|
||||
return 0;
|
||||
}
|
||||
|
||||
#if LINUX_VERSION_CODE < KERNEL_VERSION(5, 19, 0)
|
||||
static s32 devfreq_pm_qos_read_value(struct devfreq *df, enum dev_pm_qos_req_type type)
|
||||
{
|
||||
struct device *dev = df->dev.parent;
|
||||
@@ -150,13 +153,8 @@ static void devfreq_get_freq_range(struct devfreq *df,
|
||||
{
|
||||
s32 qos_min_freq, qos_max_freq;
|
||||
|
||||
#if defined(NV_DEVFREQ_HAS_FREQ_TABLE)
|
||||
*min_freq = df->freq_table[0];
|
||||
*max_freq = df->freq_table[df->max_state - 1];
|
||||
#else
|
||||
*min_freq = df->profile->freq_table[0];
|
||||
*max_freq = df->profile->freq_table[df->profile->max_state - 1];
|
||||
#endif
|
||||
|
||||
qos_min_freq = devfreq_pm_qos_read_value(df, DEV_PM_QOS_MIN_FREQUENCY);
|
||||
qos_max_freq = devfreq_pm_qos_read_value(df, DEV_PM_QOS_MAX_FREQUENCY);
|
||||
@@ -170,6 +168,7 @@ static void devfreq_get_freq_range(struct devfreq *df,
|
||||
*min_freq = max(*min_freq, df->scaling_min_freq);
|
||||
*max_freq = min(*max_freq, df->scaling_max_freq);
|
||||
}
|
||||
#endif
|
||||
|
||||
static void devfreq_update_wmark_threshold(struct devfreq *df)
|
||||
{
|
||||
@@ -177,10 +176,10 @@ static void devfreq_update_wmark_threshold(struct devfreq *df)
|
||||
struct devfreq_tegra_wmark_data *drvdata = df->data;
|
||||
struct devfreq_tegra_wmark_config wmark_config;
|
||||
unsigned long curr_freq, prev_freq, min_freq, max_freq;
|
||||
#if defined(NV_DEVFREQ_HAS_FREQ_TABLE)
|
||||
unsigned long *freq_table = df->freq_table;
|
||||
#else
|
||||
#if LINUX_VERSION_CODE < KERNEL_VERSION(5, 19, 0)
|
||||
unsigned long *freq_table = df->profile->freq_table;
|
||||
#else
|
||||
unsigned long *freq_table = df->freq_table;
|
||||
#endif
|
||||
int err;
|
||||
|
||||
@@ -226,10 +225,10 @@ static ssize_t up_freq_margin_store(struct device *dev,
|
||||
struct devfreq *df = to_devfreq(dev);
|
||||
struct tegra_wmark_data *govdata;
|
||||
unsigned int freq_margin;
|
||||
#if defined(NV_DEVFREQ_HAS_FREQ_TABLE)
|
||||
unsigned int max_state = df->max_state;
|
||||
#else
|
||||
#if LINUX_VERSION_CODE < KERNEL_VERSION(5, 19, 0)
|
||||
unsigned int max_state = df->profile->max_state;
|
||||
#else
|
||||
unsigned int max_state = df->max_state;
|
||||
#endif
|
||||
int ret;
|
||||
|
||||
@@ -271,10 +270,10 @@ static ssize_t down_freq_margin_store(struct device *dev,
|
||||
struct devfreq *df = to_devfreq(dev);
|
||||
struct tegra_wmark_data *govdata;
|
||||
unsigned int freq_margin;
|
||||
#if defined(NV_DEVFREQ_HAS_FREQ_TABLE)
|
||||
unsigned int max_state = df->max_state;
|
||||
#else
|
||||
#if LINUX_VERSION_CODE < KERNEL_VERSION(5, 19, 0)
|
||||
unsigned int max_state = df->profile->max_state;
|
||||
#else
|
||||
unsigned int max_state = df->max_state;
|
||||
#endif
|
||||
int ret;
|
||||
|
||||
|
||||
@@ -197,7 +197,7 @@ static inline int tegra_ivc_check_read(struct tegra_ivc *ivc)
|
||||
tegra_ivc_invalidate(ivc, ivc->rx.phys + offset);
|
||||
|
||||
#if defined(NV_TEGRA_IVC_STRUCT_HAS_IOSYS_MAP)
|
||||
if (tegra_ivc_empty(ivc, &ivc->rx.map))
|
||||
if (!tegra_ivc_empty(ivc, &ivc->rx.map))
|
||||
#else
|
||||
if (tegra_ivc_empty(ivc, ivc->rx.channel))
|
||||
#endif
|
||||
@@ -229,7 +229,7 @@ static inline int tegra_ivc_check_write(struct tegra_ivc *ivc)
|
||||
tegra_ivc_invalidate(ivc, ivc->tx.phys + offset);
|
||||
|
||||
#if defined(NV_TEGRA_IVC_STRUCT_HAS_IOSYS_MAP)
|
||||
if (tegra_ivc_full(ivc, &ivc->tx.map))
|
||||
if (!tegra_ivc_full(ivc, &ivc->tx.map))
|
||||
#else
|
||||
if (tegra_ivc_full(ivc, ivc->tx.channel))
|
||||
#endif
|
||||
|
||||
@@ -1,7 +1,7 @@
|
||||
// SPDX-License-Identifier: GPL-2.0-only
|
||||
/*
|
||||
* Copyright (C) 2012 Avionic Design GmbH
|
||||
* SPDX-FileCopyrightText: Copyright (c) 2012-2025 NVIDIA CORPORATION & AFFILIATES. All rights reserved.
|
||||
* Copyright (C) 2012 NVIDIA CORPORATION. All rights reserved.
|
||||
*/
|
||||
|
||||
#include <nvidia/conftest.h>
|
||||
@@ -3295,23 +3295,11 @@ static int tegra_dc_remove(struct platform_device *pdev)
|
||||
return 0;
|
||||
}
|
||||
|
||||
#if defined(NV_PLATFORM_DRIVER_STRUCT_REMOVE_RETURNS_VOID) /* Linux v6.11 */
|
||||
static void tegra_dc_remove_wrapper(struct platform_device *pdev)
|
||||
{
|
||||
tegra_dc_remove(pdev);
|
||||
}
|
||||
#else
|
||||
static int tegra_dc_remove_wrapper(struct platform_device *pdev)
|
||||
{
|
||||
return tegra_dc_remove(pdev);
|
||||
}
|
||||
#endif
|
||||
|
||||
struct platform_driver tegra_dc_driver = {
|
||||
.driver = {
|
||||
.name = "tegra-dc",
|
||||
.of_match_table = tegra_dc_of_match,
|
||||
},
|
||||
.probe = tegra_dc_probe,
|
||||
.remove = tegra_dc_remove_wrapper,
|
||||
.remove = tegra_dc_remove,
|
||||
};
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
// SPDX-License-Identifier: GPL-2.0-only
|
||||
/*
|
||||
* SPDX-FileCopyrightText: Copyright (c) 2013-2025 NVIDIA CORPORATION & AFFILIATES. All rights reserved.
|
||||
* Copyright (C) 2013 NVIDIA Corporation
|
||||
*/
|
||||
|
||||
#include <nvidia/conftest.h>
|
||||
@@ -708,18 +708,6 @@ static const struct of_device_id tegra_dpaux_of_match[] = {
|
||||
};
|
||||
MODULE_DEVICE_TABLE(of, tegra_dpaux_of_match);
|
||||
|
||||
#if defined(NV_PLATFORM_DRIVER_STRUCT_REMOVE_RETURNS_VOID) /* Linux v6.11 */
|
||||
static void tegra_dpaux_remove_wrapper(struct platform_device *pdev)
|
||||
{
|
||||
tegra_dpaux_remove(pdev);
|
||||
}
|
||||
#else
|
||||
static int tegra_dpaux_remove_wrapper(struct platform_device *pdev)
|
||||
{
|
||||
return tegra_dpaux_remove(pdev);
|
||||
}
|
||||
#endif
|
||||
|
||||
struct platform_driver tegra_dpaux_driver = {
|
||||
.driver = {
|
||||
.name = "tegra-dpaux",
|
||||
@@ -727,7 +715,7 @@ struct platform_driver tegra_dpaux_driver = {
|
||||
.pm = &tegra_dpaux_pm_ops,
|
||||
},
|
||||
.probe = tegra_dpaux_probe,
|
||||
.remove = tegra_dpaux_remove_wrapper,
|
||||
.remove = tegra_dpaux_remove,
|
||||
};
|
||||
|
||||
struct drm_dp_aux *drm_dp_aux_find_by_of_node(struct device_node *np)
|
||||
|
||||
@@ -16,11 +16,7 @@
|
||||
#include <linux/pm_runtime.h>
|
||||
#include <linux/version.h>
|
||||
|
||||
#if defined(NV_APERTURE_REMOVE_ALL_CONFLICTING_DEVICES_PRESENT) /* Linux v6.0 */
|
||||
#include <linux/aperture.h>
|
||||
#else
|
||||
#include <drm/drm_aperture.h>
|
||||
#endif
|
||||
#include <drm/drm_atomic.h>
|
||||
#include <drm/drm_atomic_helper.h>
|
||||
#include <drm/drm_debugfs.h>
|
||||
@@ -65,6 +61,9 @@ static int tegra_atomic_check(struct drm_device *drm,
|
||||
|
||||
static const struct drm_mode_config_funcs tegra_drm_mode_config_funcs = {
|
||||
.fb_create = tegra_fb_create,
|
||||
#ifdef CONFIG_DRM_FBDEV_EMULATION
|
||||
.output_poll_changed = drm_fb_helper_output_poll_changed,
|
||||
#endif
|
||||
.atomic_check = tegra_atomic_check,
|
||||
.atomic_commit = drm_atomic_helper_commit,
|
||||
};
|
||||
@@ -806,9 +805,6 @@ static const struct file_operations tegra_drm_fops = {
|
||||
.read = drm_read,
|
||||
.compat_ioctl = drm_compat_ioctl,
|
||||
.llseek = noop_llseek,
|
||||
#if defined(NV_FOP_UNSIGNED_OFFSET_PRESENT) /* Linux v6.12 */
|
||||
.fop_flags = FOP_UNSIGNED_OFFSET,
|
||||
#endif
|
||||
};
|
||||
|
||||
static int tegra_drm_context_cleanup(int id, void *p, void *data)
|
||||
@@ -890,6 +886,7 @@ static const struct drm_driver tegra_drm_driver = {
|
||||
DRIVER_ATOMIC | DRIVER_RENDER | DRIVER_SYNCOBJ,
|
||||
.open = tegra_drm_open,
|
||||
.postclose = tegra_drm_postclose,
|
||||
.lastclose = drm_fb_helper_lastclose,
|
||||
|
||||
#if defined(CONFIG_DEBUG_FS)
|
||||
.debugfs_init = tegra_debugfs_init,
|
||||
@@ -911,9 +908,7 @@ static const struct drm_driver tegra_drm_driver = {
|
||||
|
||||
.name = DRIVER_NAME,
|
||||
.desc = DRIVER_DESC,
|
||||
#if defined(NV_DRM_DRIVER_STRUCT_HAS_DATE) /* Linux v6.14 */
|
||||
.date = DRIVER_DATE,
|
||||
#endif
|
||||
.major = DRIVER_MAJOR,
|
||||
.minor = DRIVER_MINOR,
|
||||
.patchlevel = DRIVER_PATCHLEVEL,
|
||||
@@ -1188,9 +1183,6 @@ static bool host1x_drm_wants_iommu(struct host1x_device *dev)
|
||||
|
||||
static int host1x_drm_probe(struct host1x_device *dev)
|
||||
{
|
||||
#if defined(NV_IOMMU_PAGING_DOMAIN_ALLOC_PRESENT) /* Linux v6.11 */
|
||||
struct device *dma_dev = dev->dev.parent;
|
||||
#endif
|
||||
struct tegra_drm *tegra;
|
||||
struct drm_device *drm;
|
||||
int err;
|
||||
@@ -1205,13 +1197,8 @@ static int host1x_drm_probe(struct host1x_device *dev)
|
||||
goto put;
|
||||
}
|
||||
|
||||
#if defined(NV_IOMMU_PAGING_DOMAIN_ALLOC_PRESENT) /* Linux v6.11 */
|
||||
if (host1x_drm_wants_iommu(dev) && device_iommu_mapped(dma_dev)) {
|
||||
tegra->domain = iommu_paging_domain_alloc(dma_dev);
|
||||
#else
|
||||
if (host1x_drm_wants_iommu(dev) && iommu_present(&platform_bus_type)) {
|
||||
tegra->domain = iommu_domain_alloc(&platform_bus_type);
|
||||
#endif
|
||||
if (!tegra->domain) {
|
||||
err = -ENOMEM;
|
||||
goto free;
|
||||
@@ -1241,11 +1228,15 @@ static int host1x_drm_probe(struct host1x_device *dev)
|
||||
drm->mode_config.funcs = &tegra_drm_mode_config_funcs;
|
||||
drm->mode_config.helper_private = &tegra_drm_mode_config_helpers;
|
||||
|
||||
err = tegra_drm_fb_prepare(drm);
|
||||
if (err < 0)
|
||||
goto config;
|
||||
|
||||
drm_kms_helper_poll_init(drm);
|
||||
|
||||
err = host1x_device_init(dev);
|
||||
if (err < 0)
|
||||
goto poll;
|
||||
goto fbdev;
|
||||
|
||||
/*
|
||||
* Now that all display controller have been initialized, the maximum
|
||||
@@ -1314,9 +1305,7 @@ static int host1x_drm_probe(struct host1x_device *dev)
|
||||
drm_mode_config_reset(drm);
|
||||
|
||||
if (drm->mode_config.num_crtc > 0) {
|
||||
#if defined(NV_APERTURE_REMOVE_ALL_CONFLICTING_DEVICES_PRESENT) /* Linux v6.0 */
|
||||
err = aperture_remove_all_conflicting_devices(tegra_drm_driver.name);
|
||||
#elif defined(NV_DRM_APERTURE_REMOVE_FRAMEBUFFERS_HAS_NO_PRIMARY_ARG) /* Linux v6.5 */
|
||||
#if defined(NV_DRM_APERTURE_REMOVE_FRAMEBUFFERS_HAS_NO_PRIMARY_ARG) /* Linux v6.5 */
|
||||
err = drm_aperture_remove_framebuffers(&tegra_drm_driver);
|
||||
#elif defined(NV_DRM_APERTURE_REMOVE_FRAMEBUFFERS_HAS_DRM_DRIVER_ARG) /* Linux v5.15 */
|
||||
err = drm_aperture_remove_framebuffers(false, &tegra_drm_driver);
|
||||
@@ -1327,12 +1316,18 @@ static int host1x_drm_probe(struct host1x_device *dev)
|
||||
goto hub;
|
||||
}
|
||||
|
||||
err = drm_dev_register(drm, 0);
|
||||
err = tegra_drm_fb_init(drm);
|
||||
if (err < 0)
|
||||
goto hub;
|
||||
|
||||
err = drm_dev_register(drm, 0);
|
||||
if (err < 0)
|
||||
goto fb;
|
||||
|
||||
return 0;
|
||||
|
||||
fb:
|
||||
tegra_drm_fb_exit(drm);
|
||||
hub:
|
||||
if (tegra->hub)
|
||||
tegra_display_hub_cleanup(tegra->hub);
|
||||
@@ -1345,8 +1340,10 @@ device:
|
||||
}
|
||||
|
||||
host1x_device_exit(dev);
|
||||
poll:
|
||||
fbdev:
|
||||
drm_kms_helper_poll_fini(drm);
|
||||
tegra_drm_fb_free(drm);
|
||||
config:
|
||||
drm_mode_config_cleanup(drm);
|
||||
domain:
|
||||
if (tegra->domain)
|
||||
@@ -1367,6 +1364,7 @@ static int host1x_drm_remove(struct host1x_device *dev)
|
||||
drm_dev_unregister(drm);
|
||||
|
||||
drm_kms_helper_poll_fini(drm);
|
||||
tegra_drm_fb_exit(drm);
|
||||
drm_atomic_helper_shutdown(drm);
|
||||
drm_mode_config_cleanup(drm);
|
||||
|
||||
|
||||
@@ -130,7 +130,7 @@ static inline struct device *
|
||||
tegra_drm_context_get_memory_device(struct tegra_drm_context *context)
|
||||
{
|
||||
if (context->memory_context)
|
||||
return context->memory_context->context_dev;
|
||||
return &context->memory_context->dev;
|
||||
else
|
||||
return context->client->base.dev;
|
||||
}
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
// SPDX-License-Identifier: GPL-2.0-only
|
||||
/*
|
||||
* SPDX-FileCopyrightText: Copyright (c) 2013-2025 NVIDIA CORPORATION & AFFILIATES. All rights reserved.
|
||||
* Copyright (C) 2013 NVIDIA Corporation
|
||||
*/
|
||||
|
||||
#include <nvidia/conftest.h>
|
||||
@@ -1692,23 +1692,11 @@ static const struct of_device_id tegra_dsi_of_match[] = {
|
||||
};
|
||||
MODULE_DEVICE_TABLE(of, tegra_dsi_of_match);
|
||||
|
||||
#if defined(NV_PLATFORM_DRIVER_STRUCT_REMOVE_RETURNS_VOID) /* Linux v6.11 */
|
||||
static void tegra_dsi_remove_wrapper(struct platform_device *pdev)
|
||||
{
|
||||
tegra_dsi_remove(pdev);
|
||||
}
|
||||
#else
|
||||
static int tegra_dsi_remove_wrapper(struct platform_device *pdev)
|
||||
{
|
||||
return tegra_dsi_remove(pdev);
|
||||
}
|
||||
#endif
|
||||
|
||||
struct platform_driver tegra_dsi_driver = {
|
||||
.driver = {
|
||||
.name = "tegra-dsi",
|
||||
.of_match_table = tegra_dsi_of_match,
|
||||
},
|
||||
.probe = tegra_dsi_probe,
|
||||
.remove = tegra_dsi_remove_wrapper,
|
||||
.remove = tegra_dsi_remove,
|
||||
};
|
||||
|
||||
@@ -3,7 +3,7 @@
|
||||
* NVIDIA Tegra DRM GEM helper functions
|
||||
*
|
||||
* Copyright (C) 2012 Sascha Hauer, Pengutronix
|
||||
* Copyright (C) 2013-2024 NVIDIA CORPORATION, All rights reserved.
|
||||
* Copyright (C) 2013-2023 NVIDIA CORPORATION, All rights reserved.
|
||||
*
|
||||
* Based on the GEM/CMA helpers
|
||||
*
|
||||
@@ -24,11 +24,7 @@
|
||||
#include "drm.h"
|
||||
#include "gem.h"
|
||||
|
||||
#if defined(NV_MODULE_IMPORT_NS_CALLS_STRINGIFY)
|
||||
MODULE_IMPORT_NS(DMA_BUF);
|
||||
#else
|
||||
MODULE_IMPORT_NS("DMA_BUF");
|
||||
#endif
|
||||
|
||||
static unsigned int sg_dma_count_chunks(struct scatterlist *sgl, unsigned int nents)
|
||||
{
|
||||
|
||||
@@ -1,10 +1,8 @@
|
||||
// SPDX-License-Identifier: GPL-2.0-only
|
||||
/*
|
||||
* SPDX-FileCopyrightText: Copyright (c) 2012-2025 NVIDIA CORPORATION & AFFILIATES. All rights reserved.
|
||||
* Copyright (c) 2012-2013, NVIDIA Corporation.
|
||||
*/
|
||||
|
||||
#include <nvidia/conftest.h>
|
||||
|
||||
#include <linux/clk.h>
|
||||
#include <linux/delay.h>
|
||||
#include <linux/iommu.h>
|
||||
@@ -394,18 +392,6 @@ static const struct dev_pm_ops tegra_gr2d_pm = {
|
||||
pm_runtime_force_resume)
|
||||
};
|
||||
|
||||
#if defined(NV_PLATFORM_DRIVER_STRUCT_REMOVE_RETURNS_VOID) /* Linux v6.11 */
|
||||
static void gr2d_remove_wrapper(struct platform_device *pdev)
|
||||
{
|
||||
gr2d_remove(pdev);
|
||||
}
|
||||
#else
|
||||
static int gr2d_remove_wrapper(struct platform_device *pdev)
|
||||
{
|
||||
return gr2d_remove(pdev);
|
||||
}
|
||||
#endif
|
||||
|
||||
struct platform_driver tegra_gr2d_driver = {
|
||||
.driver = {
|
||||
.name = "tegra-gr2d",
|
||||
@@ -413,5 +399,5 @@ struct platform_driver tegra_gr2d_driver = {
|
||||
.pm = &tegra_gr2d_pm,
|
||||
},
|
||||
.probe = gr2d_probe,
|
||||
.remove = gr2d_remove_wrapper,
|
||||
.remove = gr2d_remove,
|
||||
};
|
||||
|
||||
@@ -1,11 +1,9 @@
|
||||
// SPDX-License-Identifier: GPL-2.0-only
|
||||
/*
|
||||
* Copyright (C) 2013 Avionic Design GmbH
|
||||
* SPDX-FileCopyrightText: Copyright (c) 2013-2025 NVIDIA CORPORATION & AFFILIATES. All rights reserved.
|
||||
* Copyright (C) 2013 NVIDIA Corporation
|
||||
*/
|
||||
|
||||
#include <nvidia/conftest.h>
|
||||
|
||||
#include <linux/clk.h>
|
||||
#include <linux/delay.h>
|
||||
#include <linux/host1x-next.h>
|
||||
@@ -49,9 +47,6 @@ struct gr3d {
|
||||
unsigned int nclocks;
|
||||
struct reset_control_bulk_data resets[RST_GR3D_MAX];
|
||||
unsigned int nresets;
|
||||
#if defined(NV_DEVM_PM_DOMAIN_ATTACH_LIST_PRESENT) /* Linux v6.13 */
|
||||
struct dev_pm_domain_list *pd_list;
|
||||
#endif
|
||||
|
||||
DECLARE_BITMAP(addr_regs, GR3D_NUM_REGS);
|
||||
};
|
||||
@@ -375,21 +370,13 @@ static int gr3d_power_up_legacy_domain(struct device *dev, const char *name,
|
||||
return 0;
|
||||
}
|
||||
|
||||
#if !defined(NV_DEVM_PM_DOMAIN_ATTACH_LIST_PRESENT) /* Linux v6.13 */
|
||||
static void gr3d_del_link(void *link)
|
||||
{
|
||||
device_link_del(link);
|
||||
}
|
||||
#endif
|
||||
|
||||
static int gr3d_init_power(struct device *dev, struct gr3d *gr3d)
|
||||
{
|
||||
#if defined(NV_DEVM_PM_DOMAIN_ATTACH_LIST_PRESENT) /* Linux v6.13 */
|
||||
struct dev_pm_domain_attach_data pd_data = {
|
||||
.pd_names = (const char *[]) { "3d0", "3d1" },
|
||||
.num_pd_names = 2,
|
||||
};
|
||||
#else
|
||||
#if LINUX_VERSION_CODE >= KERNEL_VERSION(5, 17, 0)
|
||||
static const char * const opp_genpd_names[] = { "3d0", "3d1", NULL };
|
||||
#else
|
||||
@@ -399,7 +386,6 @@ static int gr3d_init_power(struct device *dev, struct gr3d *gr3d)
|
||||
struct device **opp_virt_devs, *pd_dev;
|
||||
struct device_link *link;
|
||||
unsigned int i;
|
||||
#endif
|
||||
int err;
|
||||
|
||||
err = of_count_phandle_with_args(dev->of_node, "power-domains",
|
||||
@@ -433,11 +419,6 @@ static int gr3d_init_power(struct device *dev, struct gr3d *gr3d)
|
||||
if (dev->pm_domain)
|
||||
return 0;
|
||||
|
||||
#if defined(NV_DEVM_PM_DOMAIN_ATTACH_LIST_PRESENT) /* Linux v6.13 */
|
||||
err = devm_pm_domain_attach_list(dev, &pd_data, &gr3d->pd_list);
|
||||
if (err < 0)
|
||||
return err;
|
||||
#else
|
||||
err = devm_pm_opp_attach_genpd(dev, opp_genpd_names, &opp_virt_devs);
|
||||
if (err)
|
||||
return err;
|
||||
@@ -460,7 +441,6 @@ static int gr3d_init_power(struct device *dev, struct gr3d *gr3d)
|
||||
if (err)
|
||||
return err;
|
||||
}
|
||||
#endif
|
||||
|
||||
return 0;
|
||||
}
|
||||
@@ -651,18 +631,6 @@ static const struct dev_pm_ops tegra_gr3d_pm = {
|
||||
pm_runtime_force_resume)
|
||||
};
|
||||
|
||||
#if defined(NV_PLATFORM_DRIVER_STRUCT_REMOVE_RETURNS_VOID) /* Linux v6.11 */
|
||||
static void gr3d_remove_wrapper(struct platform_device *pdev)
|
||||
{
|
||||
gr3d_remove(pdev);
|
||||
}
|
||||
#else
|
||||
static int gr3d_remove_wrapper(struct platform_device *pdev)
|
||||
{
|
||||
return gr3d_remove(pdev);
|
||||
}
|
||||
#endif
|
||||
|
||||
struct platform_driver tegra_gr3d_driver = {
|
||||
.driver = {
|
||||
.name = "tegra-gr3d",
|
||||
@@ -670,5 +638,5 @@ struct platform_driver tegra_gr3d_driver = {
|
||||
.pm = &tegra_gr3d_pm,
|
||||
},
|
||||
.probe = gr3d_probe,
|
||||
.remove = gr3d_remove_wrapper,
|
||||
.remove = gr3d_remove,
|
||||
};
|
||||
|
||||
@@ -1,7 +1,7 @@
|
||||
// SPDX-License-Identifier: GPL-2.0-only
|
||||
/*
|
||||
* Copyright (C) 2012 Avionic Design GmbH
|
||||
* SPDX-FileCopyrightText: Copyright (c) 2012-2025 NVIDIA CORPORATION & AFFILIATES. All rights reserved.
|
||||
* Copyright (C) 2012 NVIDIA CORPORATION. All rights reserved.
|
||||
*/
|
||||
|
||||
#include <nvidia/conftest.h>
|
||||
@@ -1909,23 +1909,11 @@ static int tegra_hdmi_remove(struct platform_device *pdev)
|
||||
return 0;
|
||||
}
|
||||
|
||||
#if defined(NV_PLATFORM_DRIVER_STRUCT_REMOVE_RETURNS_VOID) /* Linux v6.11 */
|
||||
static void tegra_hdmi_remove_wrapper(struct platform_device *pdev)
|
||||
{
|
||||
tegra_hdmi_remove(pdev);
|
||||
}
|
||||
#else
|
||||
static int tegra_hdmi_remove_wrapper(struct platform_device *pdev)
|
||||
{
|
||||
return tegra_hdmi_remove(pdev);
|
||||
}
|
||||
#endif
|
||||
|
||||
struct platform_driver tegra_hdmi_driver = {
|
||||
.driver = {
|
||||
.name = "tegra-hdmi",
|
||||
.of_match_table = tegra_hdmi_of_match,
|
||||
},
|
||||
.probe = tegra_hdmi_probe,
|
||||
.remove = tegra_hdmi_remove_wrapper,
|
||||
.remove = tegra_hdmi_remove,
|
||||
};
|
||||
|
||||
@@ -1,10 +1,8 @@
|
||||
// SPDX-License-Identifier: GPL-2.0-only
|
||||
/*
|
||||
* SPDX-FileCopyrightText: Copyright (c) 2017-2025 NVIDIA CORPORATION & AFFILIATES. All rights reserved.
|
||||
* Copyright (C) 2017 NVIDIA CORPORATION. All rights reserved.
|
||||
*/
|
||||
|
||||
#include <nvidia/conftest.h>
|
||||
|
||||
#include <linux/clk.h>
|
||||
#include <linux/delay.h>
|
||||
#include <linux/dma-mapping.h>
|
||||
@@ -1217,23 +1215,11 @@ static const struct of_device_id tegra_display_hub_of_match[] = {
|
||||
};
|
||||
MODULE_DEVICE_TABLE(of, tegra_display_hub_of_match);
|
||||
|
||||
#if defined(NV_PLATFORM_DRIVER_STRUCT_REMOVE_RETURNS_VOID) /* Linux v6.11 */
|
||||
static void tegra_display_hub_remove_wrapper(struct platform_device *pdev)
|
||||
{
|
||||
tegra_display_hub_remove(pdev);
|
||||
}
|
||||
#else
|
||||
static int tegra_display_hub_remove_wrapper(struct platform_device *pdev)
|
||||
{
|
||||
return tegra_display_hub_remove(pdev);
|
||||
}
|
||||
#endif
|
||||
|
||||
struct platform_driver tegra_display_hub_driver = {
|
||||
.driver = {
|
||||
.name = "tegra-display-hub",
|
||||
.of_match_table = tegra_display_hub_of_match,
|
||||
},
|
||||
.probe = tegra_display_hub_probe,
|
||||
.remove = tegra_display_hub_remove_wrapper,
|
||||
.remove = tegra_display_hub_remove,
|
||||
};
|
||||
|
||||
@@ -1,10 +1,8 @@
|
||||
// SPDX-License-Identifier: GPL-2.0-only
|
||||
/*
|
||||
* SPDX-FileCopyrightText: Copyright (c) 2015-2025 NVIDIA CORPORATION & AFFILIATES. All rights reserved.
|
||||
* SPDX-FileCopyrightText: Copyright (c) 2015-2024, NVIDIA CORPORATION & AFFILIATES. All Rights Reserved.
|
||||
*/
|
||||
|
||||
#include <nvidia/conftest.h>
|
||||
|
||||
#include <linux/bitops.h>
|
||||
#include <linux/clk.h>
|
||||
#include <linux/delay.h>
|
||||
@@ -966,18 +964,6 @@ static const struct dev_pm_ops nvdec_pm_ops = {
|
||||
pm_runtime_force_resume)
|
||||
};
|
||||
|
||||
#if defined(NV_PLATFORM_DRIVER_STRUCT_REMOVE_RETURNS_VOID) /* Linux v6.11 */
|
||||
static void nvdec_remove_wrapper(struct platform_device *pdev)
|
||||
{
|
||||
nvdec_remove(pdev);
|
||||
}
|
||||
#else
|
||||
static int nvdec_remove_wrapper(struct platform_device *pdev)
|
||||
{
|
||||
return nvdec_remove(pdev);
|
||||
}
|
||||
#endif
|
||||
|
||||
struct platform_driver tegra_nvdec_driver = {
|
||||
.driver = {
|
||||
.name = "tegra-nvdec",
|
||||
@@ -985,7 +971,7 @@ struct platform_driver tegra_nvdec_driver = {
|
||||
.pm = &nvdec_pm_ops
|
||||
},
|
||||
.probe = nvdec_probe,
|
||||
.remove = nvdec_remove_wrapper,
|
||||
.remove = nvdec_remove,
|
||||
};
|
||||
|
||||
#if IS_ENABLED(CONFIG_ARCH_TEGRA_210_SOC)
|
||||
|
||||
@@ -1,10 +1,8 @@
|
||||
// SPDX-License-Identifier: GPL-2.0-only
|
||||
/*
|
||||
* SPDX-FileCopyrightText: Copyright (c) 2021-2025 NVIDIA CORPORATION & AFFILIATES. All rights reserved.
|
||||
* SPDX-FileCopyrightText: Copyright (c) 2021-2024, NVIDIA CORPORATION & AFFILIATES. All Rights Reserved.
|
||||
*/
|
||||
|
||||
#include <nvidia/conftest.h>
|
||||
|
||||
#include <linux/bitops.h>
|
||||
#include <linux/clk.h>
|
||||
#include <linux/delay.h>
|
||||
@@ -759,18 +757,6 @@ static const struct dev_pm_ops nvenc_pm_ops = {
|
||||
pm_runtime_force_resume)
|
||||
};
|
||||
|
||||
#if defined(NV_PLATFORM_DRIVER_STRUCT_REMOVE_RETURNS_VOID) /* Linux v6.11 */
|
||||
static void nvenc_remove_wrapper(struct platform_device *pdev)
|
||||
{
|
||||
nvenc_remove(pdev);
|
||||
}
|
||||
#else
|
||||
static int nvenc_remove_wrapper(struct platform_device *pdev)
|
||||
{
|
||||
return nvenc_remove(pdev);
|
||||
}
|
||||
#endif
|
||||
|
||||
struct platform_driver tegra_nvenc_driver = {
|
||||
.driver = {
|
||||
.name = "tegra-nvenc",
|
||||
@@ -778,7 +764,7 @@ struct platform_driver tegra_nvenc_driver = {
|
||||
.pm = &nvenc_pm_ops
|
||||
},
|
||||
.probe = nvenc_probe,
|
||||
.remove = nvenc_remove_wrapper,
|
||||
.remove = nvenc_remove,
|
||||
};
|
||||
|
||||
#if IS_ENABLED(CONFIG_ARCH_TEGRA_210_SOC)
|
||||
|
||||
@@ -1,10 +1,8 @@
|
||||
// SPDX-License-Identifier: GPL-2.0-only
|
||||
/*
|
||||
* SPDX-FileCopyrightText: Copyright (c) 2021-2025 NVIDIA CORPORATION & AFFILIATES. All rights reserved.
|
||||
* SPDX-FileCopyrightText: Copyright (c) 2021-2024, NVIDIA CORPORATION & AFFILIATES. All Rights Reserved.
|
||||
*/
|
||||
|
||||
#include <nvidia/conftest.h>
|
||||
|
||||
#include <linux/bitops.h>
|
||||
#include <linux/clk.h>
|
||||
#include <linux/delay.h>
|
||||
@@ -736,18 +734,6 @@ static const struct dev_pm_ops nvjpg_pm_ops = {
|
||||
pm_runtime_force_resume)
|
||||
};
|
||||
|
||||
#if defined(NV_PLATFORM_DRIVER_STRUCT_REMOVE_RETURNS_VOID) /* Linux v6.11 */
|
||||
static void nvjpg_remove_wrapper(struct platform_device *pdev)
|
||||
{
|
||||
nvjpg_remove(pdev);
|
||||
}
|
||||
#else
|
||||
static int nvjpg_remove_wrapper(struct platform_device *pdev)
|
||||
{
|
||||
return nvjpg_remove(pdev);
|
||||
}
|
||||
#endif
|
||||
|
||||
struct platform_driver tegra_nvjpg_driver = {
|
||||
.driver = {
|
||||
.name = "tegra-nvjpg",
|
||||
@@ -755,7 +741,7 @@ struct platform_driver tegra_nvjpg_driver = {
|
||||
.pm = &nvjpg_pm_ops
|
||||
},
|
||||
.probe = nvjpg_probe,
|
||||
.remove = nvjpg_remove_wrapper,
|
||||
.remove = nvjpg_remove,
|
||||
};
|
||||
|
||||
#if IS_ENABLED(CONFIG_ARCH_TEGRA_210_SOC)
|
||||
|
||||
@@ -1,10 +1,8 @@
|
||||
// SPDX-License-Identifier: GPL-2.0-only
|
||||
/*
|
||||
* SPDX-FileCopyrightText: Copyright (c) 2021-2025 NVIDIA CORPORATION & AFFILIATES. All rights reserved.
|
||||
* SPDX-FileCopyrightText: Copyright (c) 2021-2023, NVIDIA Corporation.
|
||||
*/
|
||||
|
||||
#include <nvidia/conftest.h>
|
||||
|
||||
#include <linux/clk.h>
|
||||
#include <linux/delay.h>
|
||||
#include <linux/devfreq.h>
|
||||
@@ -634,18 +632,6 @@ static const struct dev_pm_ops ofa_pm_ops = {
|
||||
pm_runtime_force_resume)
|
||||
};
|
||||
|
||||
#if defined(NV_PLATFORM_DRIVER_STRUCT_REMOVE_RETURNS_VOID) /* Linux v6.11 */
|
||||
static void ofa_remove_wrapper(struct platform_device *pdev)
|
||||
{
|
||||
ofa_remove(pdev);
|
||||
}
|
||||
#else
|
||||
static int ofa_remove_wrapper(struct platform_device *pdev)
|
||||
{
|
||||
return ofa_remove(pdev);
|
||||
}
|
||||
#endif
|
||||
|
||||
struct platform_driver tegra_ofa_driver = {
|
||||
.driver = {
|
||||
.name = "tegra-ofa",
|
||||
@@ -653,7 +639,7 @@ struct platform_driver tegra_ofa_driver = {
|
||||
.pm = &ofa_pm_ops
|
||||
},
|
||||
.probe = ofa_probe,
|
||||
.remove = ofa_remove_wrapper,
|
||||
.remove = ofa_remove,
|
||||
};
|
||||
|
||||
#if IS_ENABLED(CONFIG_ARCH_TEGRA_234_SOC)
|
||||
|
||||
@@ -1,5 +1,9 @@
|
||||
// SPDX-License-Identifier: GPL-2.0-only
|
||||
// SPDX-FileCopyrightText: Copyright (c) 2022-2024 NVIDIA CORPORATION & AFFILIATES. All rights reserved.
|
||||
/*
|
||||
* Copyright (c) 2022, NVIDIA Corporation.
|
||||
*/
|
||||
|
||||
#include <asm/unaligned.h>
|
||||
|
||||
#include <linux/dev_printk.h>
|
||||
#include <linux/device.h>
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
// SPDX-License-Identifier: GPL-2.0-only
|
||||
/*
|
||||
* SPDX-FileCopyrightText: Copyright (c) 2013-2025 NVIDIA CORPORATION & AFFILIATES. All rights reserved.
|
||||
* Copyright (C) 2013 NVIDIA Corporation
|
||||
*/
|
||||
|
||||
#include <nvidia/conftest.h>
|
||||
@@ -4082,18 +4082,6 @@ static const struct dev_pm_ops tegra_sor_pm_ops = {
|
||||
SET_SYSTEM_SLEEP_PM_OPS(tegra_sor_suspend, tegra_sor_resume)
|
||||
};
|
||||
|
||||
#if defined(NV_PLATFORM_DRIVER_STRUCT_REMOVE_RETURNS_VOID) /* Linux v6.11 */
|
||||
static void tegra_sor_remove_wrapper(struct platform_device *pdev)
|
||||
{
|
||||
tegra_sor_remove(pdev);
|
||||
}
|
||||
#else
|
||||
static int tegra_sor_remove_wrapper(struct platform_device *pdev)
|
||||
{
|
||||
return tegra_sor_remove(pdev);
|
||||
}
|
||||
#endif
|
||||
|
||||
struct platform_driver tegra_sor_driver = {
|
||||
.driver = {
|
||||
.name = "tegra-sor",
|
||||
@@ -4101,5 +4089,5 @@ struct platform_driver tegra_sor_driver = {
|
||||
.pm = &tegra_sor_pm_ops,
|
||||
},
|
||||
.probe = tegra_sor_probe,
|
||||
.remove = tegra_sor_remove_wrapper,
|
||||
.remove = tegra_sor_remove,
|
||||
};
|
||||
|
||||
@@ -240,14 +240,9 @@ static int submit_write_reloc(struct tegra_drm_context *context, struct gather_b
|
||||
struct drm_tegra_submit_buf *buf, struct tegra_drm_mapping *mapping)
|
||||
{
|
||||
/* TODO check that target_offset is within bounds */
|
||||
dma_addr_t iova = buf->reloc.target_offset;
|
||||
dma_addr_t iova = mapping->iova + buf->reloc.target_offset;
|
||||
u32 written_ptr;
|
||||
|
||||
if (mapping->bo_map)
|
||||
iova += mapping->iova;
|
||||
else
|
||||
iova += mapping->ctx_map->mapping->phys;
|
||||
|
||||
#ifdef CONFIG_ARCH_DMA_ADDR_T_64BIT
|
||||
if (buf->flags & DRM_TEGRA_SUBMIT_RELOC_SECTOR_LAYOUT)
|
||||
iova |= BIT_ULL(39);
|
||||
@@ -531,6 +526,9 @@ static void release_job(struct host1x_job *job)
|
||||
struct tegra_drm_submit_data *job_data = job->user_data;
|
||||
u32 i;
|
||||
|
||||
if (job->memory_context)
|
||||
host1x_memory_context_put(job->memory_context);
|
||||
|
||||
if (IS_ENABLED(CONFIG_TRACING) && job_data->timestamps.virt) {
|
||||
u64 *timestamps = job_data->timestamps.virt;
|
||||
|
||||
@@ -544,11 +542,6 @@ static void release_job(struct host1x_job *job)
|
||||
for (i = 0; i < job_data->num_used_mappings; i++)
|
||||
tegra_drm_mapping_put(job_data->used_mappings[i].mapping);
|
||||
|
||||
if (job->memory_context) {
|
||||
host1x_memory_context_inactive(job->memory_context);
|
||||
host1x_memory_context_put(job->memory_context);
|
||||
}
|
||||
|
||||
kfree(job_data->used_mappings);
|
||||
kfree(job_data);
|
||||
|
||||
@@ -588,7 +581,6 @@ static int submit_init_profiling(struct tegra_drm_context *context,
|
||||
int tegra_drm_ioctl_channel_submit(struct drm_device *drm, void *data,
|
||||
struct drm_file *file)
|
||||
{
|
||||
struct host1x_memory_context *active_memctx = NULL;
|
||||
struct tegra_drm_file *fpriv = file->driver_priv;
|
||||
struct drm_tegra_channel_submit *args = data;
|
||||
static atomic_t next_job_id = ATOMIC_INIT(1);
|
||||
@@ -612,17 +604,6 @@ int tegra_drm_ioctl_channel_submit(struct drm_device *drm, void *data,
|
||||
return -EINVAL;
|
||||
}
|
||||
|
||||
if (context->memory_context) {
|
||||
err = host1x_memory_context_active(context->memory_context);
|
||||
if (err) {
|
||||
mutex_unlock(&fpriv->lock);
|
||||
SUBMIT_ERR(context, "failed to activate memory context");
|
||||
return err;
|
||||
}
|
||||
|
||||
active_memctx = context->memory_context;
|
||||
}
|
||||
|
||||
if (args->flags & ~(DRM_TEGRA_SUBMIT_SECONDARY_SYNCPT)) {
|
||||
SUBMIT_ERR(context, "invalid flags '%#x'", args->flags);
|
||||
goto unlock;
|
||||
@@ -723,8 +704,7 @@ int tegra_drm_ioctl_channel_submit(struct drm_device *drm, void *data,
|
||||
}
|
||||
|
||||
if (supported) {
|
||||
job->memory_context = active_memctx;
|
||||
active_memctx = NULL;
|
||||
job->memory_context = context->memory_context;
|
||||
host1x_memory_context_get(job->memory_context);
|
||||
}
|
||||
} else if (context->client->ops->get_streamid_offset) {
|
||||
@@ -845,8 +825,6 @@ put_bo:
|
||||
unlock:
|
||||
if (syncobj)
|
||||
drm_syncobj_put(syncobj);
|
||||
if (active_memctx)
|
||||
host1x_memory_context_inactive(active_memctx);
|
||||
|
||||
mutex_unlock(&fpriv->lock);
|
||||
return err;
|
||||
|
||||
@@ -17,11 +17,7 @@ static void tegra_drm_mapping_release(struct kref *ref)
|
||||
struct tegra_drm_mapping *mapping =
|
||||
container_of(ref, struct tegra_drm_mapping, ref);
|
||||
|
||||
if (mapping->ctx_map)
|
||||
host1x_memory_context_unmap(mapping->ctx_map);
|
||||
else
|
||||
host1x_bo_unpin(mapping->bo_map);
|
||||
|
||||
host1x_bo_unpin(mapping->map);
|
||||
host1x_bo_put(mapping->bo);
|
||||
|
||||
kfree(mapping);
|
||||
@@ -37,12 +33,12 @@ static void tegra_drm_channel_context_close(struct tegra_drm_context *context)
|
||||
struct tegra_drm_mapping *mapping;
|
||||
unsigned long id;
|
||||
|
||||
xa_for_each(&context->mappings, id, mapping)
|
||||
tegra_drm_mapping_put(mapping);
|
||||
|
||||
if (context->memory_context)
|
||||
host1x_memory_context_put(context->memory_context);
|
||||
|
||||
xa_for_each(&context->mappings, id, mapping)
|
||||
tegra_drm_mapping_put(mapping);
|
||||
|
||||
xa_destroy(&context->mappings);
|
||||
|
||||
host1x_channel_put(context->channel);
|
||||
@@ -238,27 +234,16 @@ int tegra_drm_ioctl_channel_map(struct drm_device *drm, void *data, struct drm_f
|
||||
goto put_gem;
|
||||
}
|
||||
|
||||
if (context->memory_context) {
|
||||
mapping->ctx_map = host1x_memory_context_map(
|
||||
context->memory_context, mapping->bo, direction);
|
||||
|
||||
if (IS_ERR(mapping->ctx_map)) {
|
||||
err = PTR_ERR(mapping->ctx_map);
|
||||
goto put_gem;
|
||||
}
|
||||
} else {
|
||||
mapping->bo_map = host1x_bo_pin(context->client->base.dev,
|
||||
mapping->bo, direction, NULL);
|
||||
|
||||
if (IS_ERR(mapping->bo_map)) {
|
||||
err = PTR_ERR(mapping->bo_map);
|
||||
goto put_gem;
|
||||
}
|
||||
|
||||
mapping->iova = mapping->bo_map->phys;
|
||||
mapping->iova_end = mapping->iova + host1x_to_tegra_bo(mapping->bo)->gem.size;
|
||||
mapping->map = host1x_bo_pin(tegra_drm_context_get_memory_device(context),
|
||||
mapping->bo, direction, NULL);
|
||||
if (IS_ERR(mapping->map)) {
|
||||
err = PTR_ERR(mapping->map);
|
||||
goto put_gem;
|
||||
}
|
||||
|
||||
mapping->iova = mapping->map->phys;
|
||||
mapping->iova_end = mapping->iova + host1x_to_tegra_bo(mapping->bo)->gem.size;
|
||||
|
||||
err = xa_alloc(&context->mappings, &args->mapping, mapping, XA_LIMIT(1, U32_MAX),
|
||||
GFP_KERNEL);
|
||||
if (err < 0)
|
||||
@@ -269,10 +254,7 @@ int tegra_drm_ioctl_channel_map(struct drm_device *drm, void *data, struct drm_f
|
||||
return 0;
|
||||
|
||||
unpin:
|
||||
if (mapping->ctx_map)
|
||||
host1x_memory_context_unmap(mapping->ctx_map);
|
||||
else
|
||||
host1x_bo_unpin(mapping->bo_map);
|
||||
host1x_bo_unpin(mapping->map);
|
||||
put_gem:
|
||||
host1x_bo_put(mapping->bo);
|
||||
free:
|
||||
|
||||
@@ -27,8 +27,7 @@ struct tegra_drm_file {
|
||||
struct tegra_drm_mapping {
|
||||
struct kref ref;
|
||||
|
||||
struct host1x_bo_mapping *bo_map;
|
||||
struct host1x_context_mapping *ctx_map;
|
||||
struct host1x_bo_mapping *map;
|
||||
struct host1x_bo *bo;
|
||||
|
||||
dma_addr_t iova;
|
||||
|
||||
@@ -1,10 +1,8 @@
|
||||
// SPDX-License-Identifier: GPL-2.0-only
|
||||
/*
|
||||
* SPDX-FileCopyrightText: Copyright (c) 2015-2025 NVIDIA CORPORATION & AFFILIATES. All rights reserved.
|
||||
* SPDX-FileCopyrightText: Copyright (C) 2015-2024 NVIDIA CORPORATION. All rights reserved.
|
||||
*/
|
||||
|
||||
#include <nvidia/conftest.h>
|
||||
|
||||
#include <linux/bitops.h>
|
||||
#include <linux/clk.h>
|
||||
#include <linux/delay.h>
|
||||
@@ -833,18 +831,6 @@ static const struct dev_pm_ops vic_pm_ops = {
|
||||
#endif
|
||||
};
|
||||
|
||||
#if defined(NV_PLATFORM_DRIVER_STRUCT_REMOVE_RETURNS_VOID) /* Linux v6.11 */
|
||||
static void vic_remove_wrapper(struct platform_device *pdev)
|
||||
{
|
||||
vic_remove(pdev);
|
||||
}
|
||||
#else
|
||||
static int vic_remove_wrapper(struct platform_device *pdev)
|
||||
{
|
||||
return vic_remove(pdev);
|
||||
}
|
||||
#endif
|
||||
|
||||
struct platform_driver tegra_vic_driver = {
|
||||
.driver = {
|
||||
.name = "tegra-vic",
|
||||
@@ -852,7 +838,7 @@ struct platform_driver tegra_vic_driver = {
|
||||
.pm = &vic_pm_ops
|
||||
},
|
||||
.probe = vic_probe,
|
||||
.remove = vic_remove_wrapper,
|
||||
.remove = vic_remove,
|
||||
};
|
||||
|
||||
#if IS_ENABLED(CONFIG_ARCH_TEGRA_124_SOC)
|
||||
|
||||
@@ -1,7 +1,7 @@
|
||||
// SPDX-License-Identifier: GPL-2.0-only
|
||||
// SPDX-FileCopyrightText: Copyright (c) 2023-2025 NVIDIA CORPORATION & AFFILIATES. All rights reserved.
|
||||
|
||||
#include <nvidia/conftest.h>
|
||||
/*
|
||||
* Copyright (c) 2023, NVIDIA Corporation.
|
||||
*/
|
||||
|
||||
#include <linux/clk.h>
|
||||
#include <linux/debugfs.h>
|
||||
@@ -563,18 +563,6 @@ static const struct dev_pm_ops virt_engine_pm_ops = {
|
||||
#endif
|
||||
};
|
||||
|
||||
#if defined(NV_PLATFORM_DRIVER_STRUCT_REMOVE_RETURNS_VOID) /* Linux v6.11 */
|
||||
static void virt_engine_remove_wrapper(struct platform_device *pdev)
|
||||
{
|
||||
virt_engine_remove(pdev);
|
||||
}
|
||||
#else
|
||||
static int virt_engine_remove_wrapper(struct platform_device *pdev)
|
||||
{
|
||||
return virt_engine_remove(pdev);
|
||||
}
|
||||
#endif
|
||||
|
||||
struct platform_driver tegra_virt_engine_driver = {
|
||||
.driver = {
|
||||
.name = "tegra-host1x-virtual-engine",
|
||||
@@ -582,5 +570,5 @@ struct platform_driver tegra_virt_engine_driver = {
|
||||
.pm = &virt_engine_pm_ops,
|
||||
},
|
||||
.probe = virt_engine_probe,
|
||||
.remove = virt_engine_remove_wrapper,
|
||||
.remove = virt_engine_remove,
|
||||
};
|
||||
|
||||
@@ -172,8 +172,6 @@ static int dev_file_ioctl_fence_extract(struct host1x *host1x, void __user *data
|
||||
goto put_fence;
|
||||
}
|
||||
|
||||
dma_fence_put(fence);
|
||||
|
||||
return 0;
|
||||
|
||||
put_fence:
|
||||
|
||||
@@ -1,12 +1,10 @@
|
||||
// SPDX-License-Identifier: GPL-2.0-only
|
||||
/*
|
||||
* SPDX-FileCopyrightText: Copyright (c) 2021-2025 NVIDIA CORPORATION & AFFILIATES. All rights reserved.
|
||||
* Copyright (c) 2021-2024, NVIDIA Corporation.
|
||||
*/
|
||||
|
||||
#include <linux/completion.h>
|
||||
#include <linux/device.h>
|
||||
#include <linux/kref.h>
|
||||
#include <linux/list.h>
|
||||
#include <linux/of.h>
|
||||
#include <linux/of_device.h>
|
||||
#include <linux/pid.h>
|
||||
@@ -19,14 +17,13 @@ int host1x_memory_context_list_init(struct host1x *host1x)
|
||||
{
|
||||
struct host1x_memory_context_list *cdl = &host1x->context_list;
|
||||
struct device_node *node = host1x->dev->of_node;
|
||||
struct host1x_hw_memory_context *ctx;
|
||||
struct host1x_memory_context *ctx;
|
||||
unsigned int i;
|
||||
int err;
|
||||
|
||||
cdl->devs = NULL;
|
||||
cdl->len = 0;
|
||||
mutex_init(&cdl->lock);
|
||||
INIT_LIST_HEAD(&cdl->waiters);
|
||||
|
||||
err = of_property_count_u32_elems(node, "iommu-map");
|
||||
if (err < 0)
|
||||
@@ -57,7 +54,6 @@ int host1x_memory_context_list_init(struct host1x *host1x)
|
||||
ctx->dev.bus = &host1x_context_device_bus_type;
|
||||
ctx->dev.parent = host1x->dev;
|
||||
|
||||
ctx->dev.dma_parms = &ctx->dma_parms;
|
||||
dma_set_max_seg_size(&ctx->dev, UINT_MAX);
|
||||
|
||||
err = device_add(&ctx->dev);
|
||||
@@ -107,288 +103,62 @@ void host1x_memory_context_list_free(struct host1x_memory_context_list *cdl)
|
||||
cdl->len = 0;
|
||||
}
|
||||
|
||||
static bool hw_usable_for_dev(struct host1x_hw_memory_context *hw, struct device *dev)
|
||||
{
|
||||
return hw->dev.iommu->iommu_dev == dev->iommu->iommu_dev;
|
||||
}
|
||||
|
||||
static struct host1x_hw_memory_context *host1x_memory_context_alloc_hw_locked(struct host1x *host1x,
|
||||
struct host1x_memory_context *host1x_memory_context_alloc(struct host1x *host1x,
|
||||
struct device *dev,
|
||||
struct pid *pid)
|
||||
{
|
||||
struct host1x_memory_context_list *cdl = &host1x->context_list;
|
||||
struct host1x_hw_memory_context *free = NULL, *can_steal = NULL;
|
||||
struct host1x_memory_context *ctx;
|
||||
struct host1x_memory_context *free = NULL;
|
||||
int i;
|
||||
|
||||
if (!cdl->len)
|
||||
return ERR_PTR(-EOPNOTSUPP);
|
||||
|
||||
for (i = 0; i < cdl->len; i++) {
|
||||
struct host1x_hw_memory_context *cd = &cdl->devs[i];
|
||||
mutex_lock(&cdl->lock);
|
||||
|
||||
if (!hw_usable_for_dev(cd, dev))
|
||||
for (i = 0; i < cdl->len; i++) {
|
||||
struct host1x_memory_context *cd = &cdl->devs[i];
|
||||
|
||||
if (cd->dev.iommu->iommu_dev != dev->iommu->iommu_dev)
|
||||
continue;
|
||||
|
||||
if (cd->owner == pid) {
|
||||
refcount_inc(&cd->ref);
|
||||
mutex_unlock(&cdl->lock);
|
||||
return cd;
|
||||
} else if (!cd->owner && !free) {
|
||||
free = cd;
|
||||
} else if (!cd->active) {
|
||||
can_steal = cd;
|
||||
}
|
||||
}
|
||||
|
||||
if (free)
|
||||
goto found;
|
||||
|
||||
/* Steal */
|
||||
|
||||
if (!can_steal)
|
||||
if (!free) {
|
||||
mutex_unlock(&cdl->lock);
|
||||
return ERR_PTR(-EBUSY);
|
||||
|
||||
list_for_each_entry(ctx, &can_steal->owners, entry) {
|
||||
struct host1x_context_mapping *mapping;
|
||||
|
||||
ctx->hw = NULL;
|
||||
ctx->context_dev = NULL;
|
||||
|
||||
list_for_each_entry(mapping, &ctx->mappings, entry) {
|
||||
host1x_bo_unpin(mapping->mapping);
|
||||
mapping->mapping = NULL;
|
||||
}
|
||||
}
|
||||
|
||||
put_pid(can_steal->owner);
|
||||
|
||||
free = can_steal;
|
||||
|
||||
found:
|
||||
refcount_set(&free->ref, 1);
|
||||
free->owner = get_pid(pid);
|
||||
INIT_LIST_HEAD(&free->owners);
|
||||
|
||||
mutex_unlock(&cdl->lock);
|
||||
|
||||
return free;
|
||||
}
|
||||
|
||||
static void host1x_memory_context_hw_put(struct host1x_hw_memory_context *cd)
|
||||
{
|
||||
if (refcount_dec_and_test(&cd->ref)) {
|
||||
put_pid(cd->owner);
|
||||
cd->owner = NULL;
|
||||
}
|
||||
}
|
||||
|
||||
struct host1x_memory_context *host1x_memory_context_alloc(
|
||||
struct host1x *host1x, struct device *dev, struct pid *pid)
|
||||
{
|
||||
struct host1x_memory_context_list *cdl = &host1x->context_list;
|
||||
struct host1x_memory_context *ctx;
|
||||
|
||||
if (!cdl->len)
|
||||
return ERR_PTR(-EOPNOTSUPP);
|
||||
|
||||
ctx = kzalloc(sizeof(*ctx), GFP_KERNEL);
|
||||
if (!ctx)
|
||||
return ERR_PTR(-ENOMEM);
|
||||
|
||||
ctx->host = host1x;
|
||||
ctx->dev = dev;
|
||||
ctx->pid = get_pid(pid);
|
||||
|
||||
refcount_set(&ctx->ref, 1);
|
||||
INIT_LIST_HEAD(&ctx->mappings);
|
||||
|
||||
return ctx;
|
||||
}
|
||||
EXPORT_SYMBOL_GPL(host1x_memory_context_alloc);
|
||||
|
||||
struct hw_alloc_waiter {
|
||||
struct completion wait; /* Completion to wait for free hw context */
|
||||
struct list_head entry;
|
||||
struct device *dev;
|
||||
};
|
||||
|
||||
int host1x_memory_context_active(struct host1x_memory_context *ctx)
|
||||
void host1x_memory_context_get(struct host1x_memory_context *cd)
|
||||
{
|
||||
struct host1x_memory_context_list *cdl = &ctx->host->context_list;
|
||||
struct host1x_context_mapping *mapping;
|
||||
struct host1x_hw_memory_context *hw;
|
||||
struct hw_alloc_waiter waiter;
|
||||
bool retrying = false;
|
||||
int err = 0;
|
||||
|
||||
mutex_lock(&cdl->lock);
|
||||
|
||||
retry:
|
||||
if (!ctx->hw) {
|
||||
hw = host1x_memory_context_alloc_hw_locked(ctx->host, ctx->dev, ctx->pid);
|
||||
if (PTR_ERR(hw) == -EBUSY) {
|
||||
/* All contexts busy. Wait for free context. */
|
||||
if (!retrying)
|
||||
dev_warn(ctx->dev, "%s: all memory contexts are busy, waiting\n",
|
||||
current->comm);
|
||||
|
||||
init_completion(&waiter.wait);
|
||||
waiter.dev = ctx->dev;
|
||||
list_add(&waiter.entry, &cdl->waiters);
|
||||
|
||||
mutex_unlock(&cdl->lock);
|
||||
err = wait_for_completion_interruptible(&waiter.wait);
|
||||
mutex_lock(&cdl->lock);
|
||||
|
||||
list_del(&waiter.entry);
|
||||
if (err)
|
||||
goto unlock;
|
||||
|
||||
retrying = true;
|
||||
goto retry;
|
||||
}
|
||||
if (IS_ERR(hw)) {
|
||||
err = PTR_ERR(hw);
|
||||
goto unlock;
|
||||
}
|
||||
|
||||
ctx->hw = hw;
|
||||
ctx->context_dev = &hw->dev;
|
||||
list_add(&ctx->entry, &hw->owners);
|
||||
|
||||
list_for_each_entry(mapping, &ctx->mappings, entry) {
|
||||
mapping->mapping = host1x_bo_pin(
|
||||
&hw->dev, mapping->bo, mapping->direction, NULL);
|
||||
if (IS_ERR(mapping->mapping)) {
|
||||
err = PTR_ERR(mapping->mapping);
|
||||
mapping->mapping = NULL;
|
||||
goto unpin;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
ctx->hw->active++;
|
||||
|
||||
mutex_unlock(&cdl->lock);
|
||||
|
||||
return 0;
|
||||
|
||||
unpin:
|
||||
list_for_each_entry(mapping, &ctx->mappings, entry) {
|
||||
if (mapping->mapping)
|
||||
host1x_bo_unpin(mapping->mapping);
|
||||
}
|
||||
|
||||
host1x_memory_context_hw_put(ctx->hw);
|
||||
list_del(&ctx->entry);
|
||||
ctx->hw = NULL;
|
||||
unlock:
|
||||
mutex_unlock(&cdl->lock);
|
||||
return err;
|
||||
}
|
||||
EXPORT_SYMBOL_GPL(host1x_memory_context_active);
|
||||
|
||||
struct host1x_context_mapping *host1x_memory_context_map(
|
||||
struct host1x_memory_context *ctx, struct host1x_bo *bo, enum dma_data_direction direction)
|
||||
{
|
||||
struct host1x_memory_context_list *cdl = &ctx->host->context_list;
|
||||
struct host1x_context_mapping *m;
|
||||
struct host1x_bo_mapping *bo_m;
|
||||
|
||||
m = kzalloc(sizeof(*m), GFP_KERNEL);
|
||||
if (!m)
|
||||
return ERR_PTR(-ENOMEM);
|
||||
|
||||
m->host = ctx->host;
|
||||
m->bo = bo;
|
||||
m->direction = direction;
|
||||
|
||||
mutex_lock(&cdl->lock);
|
||||
|
||||
if (ctx->hw) {
|
||||
bo_m = host1x_bo_pin(&ctx->hw->dev, bo, direction, NULL);
|
||||
if (IS_ERR(bo_m)) {
|
||||
mutex_unlock(&cdl->lock);
|
||||
kfree(m);
|
||||
|
||||
return ERR_CAST(bo_m);
|
||||
}
|
||||
|
||||
m->mapping = bo_m;
|
||||
}
|
||||
|
||||
list_add(&m->entry, &ctx->mappings);
|
||||
|
||||
mutex_unlock(&cdl->lock);
|
||||
|
||||
return m;
|
||||
}
|
||||
EXPORT_SYMBOL_GPL(host1x_memory_context_map);
|
||||
|
||||
void host1x_memory_context_unmap(struct host1x_context_mapping *m)
|
||||
{
|
||||
struct host1x_memory_context_list *cdl = &m->host->context_list;
|
||||
|
||||
mutex_lock(&cdl->lock);
|
||||
|
||||
list_del(&m->entry);
|
||||
|
||||
mutex_unlock(&cdl->lock);
|
||||
|
||||
if (m->mapping)
|
||||
host1x_bo_unpin(m->mapping);
|
||||
|
||||
kfree(m);
|
||||
}
|
||||
EXPORT_SYMBOL_GPL(host1x_memory_context_unmap);
|
||||
|
||||
void host1x_memory_context_inactive(struct host1x_memory_context *ctx)
|
||||
{
|
||||
struct host1x_memory_context_list *cdl = &ctx->host->context_list;
|
||||
struct hw_alloc_waiter *waiter;
|
||||
|
||||
mutex_lock(&cdl->lock);
|
||||
|
||||
if (--ctx->hw->active == 0) {
|
||||
/* Hardware context becomes eligible for stealing */
|
||||
list_for_each_entry(waiter, &cdl->waiters, entry) {
|
||||
if (!hw_usable_for_dev(ctx->hw, waiter->dev))
|
||||
continue;
|
||||
|
||||
complete(&waiter->wait);
|
||||
|
||||
/*
|
||||
* Need to wake up all waiters -- there could be multiple from
|
||||
* the same process that can use the same freed hardware context.
|
||||
*/
|
||||
}
|
||||
}
|
||||
|
||||
mutex_unlock(&cdl->lock);
|
||||
}
|
||||
EXPORT_SYMBOL_GPL(host1x_memory_context_inactive);
|
||||
|
||||
void host1x_memory_context_get(struct host1x_memory_context *ctx)
|
||||
{
|
||||
refcount_inc(&ctx->ref);
|
||||
refcount_inc(&cd->ref);
|
||||
}
|
||||
EXPORT_SYMBOL_GPL(host1x_memory_context_get);
|
||||
|
||||
void host1x_memory_context_put(struct host1x_memory_context *ctx)
|
||||
void host1x_memory_context_put(struct host1x_memory_context *cd)
|
||||
{
|
||||
struct host1x_memory_context_list *cdl = &ctx->host->context_list;
|
||||
struct host1x_memory_context_list *cdl = &cd->host->context_list;
|
||||
|
||||
if (refcount_dec_and_mutex_lock(&ctx->ref, &cdl->lock)) {
|
||||
if (ctx->hw) {
|
||||
list_del(&ctx->entry);
|
||||
|
||||
host1x_memory_context_hw_put(ctx->hw);
|
||||
ctx->hw = NULL;
|
||||
|
||||
WARN_ON(!list_empty(&ctx->mappings));
|
||||
}
|
||||
|
||||
put_pid(ctx->pid);
|
||||
if (refcount_dec_and_mutex_lock(&cd->ref, &cdl->lock)) {
|
||||
put_pid(cd->owner);
|
||||
cd->owner = NULL;
|
||||
mutex_unlock(&cdl->lock);
|
||||
kfree(ctx);
|
||||
}
|
||||
}
|
||||
EXPORT_SYMBOL_GPL(host1x_memory_context_put);
|
||||
|
||||
@@ -2,7 +2,7 @@
|
||||
/*
|
||||
* Host1x context devices
|
||||
*
|
||||
* SPDX-FileCopyrightText: Copyright (c) 2020-2025 NVIDIA CORPORATION & AFFILIATES. All rights reserved.
|
||||
* Copyright (c) 2020, NVIDIA Corporation.
|
||||
*/
|
||||
|
||||
#ifndef __HOST1X_CONTEXT_H
|
||||
@@ -17,24 +17,8 @@ extern struct bus_type host1x_context_device_bus_type;
|
||||
|
||||
struct host1x_memory_context_list {
|
||||
struct mutex lock;
|
||||
struct host1x_hw_memory_context *devs;
|
||||
struct host1x_memory_context *devs;
|
||||
unsigned int len;
|
||||
struct list_head waiters;
|
||||
};
|
||||
|
||||
struct host1x_hw_memory_context {
|
||||
struct host1x *host;
|
||||
|
||||
refcount_t ref;
|
||||
struct pid *owner;
|
||||
|
||||
struct device_dma_parameters dma_parms;
|
||||
struct device dev;
|
||||
u64 dma_mask;
|
||||
u32 stream_id;
|
||||
|
||||
struct list_head owners;
|
||||
unsigned int active;
|
||||
};
|
||||
|
||||
#ifdef CONFIG_IOMMU_API
|
||||
|
||||
@@ -2,7 +2,7 @@
|
||||
/*
|
||||
* Tegra host1x driver
|
||||
*
|
||||
* SPDX-FileCopyrightText: Copyright (c) 2010-2025 NVIDIA CORPORATION & AFFILIATES. All rights reserved.
|
||||
* Copyright (c) 2010-2023, NVIDIA CORPORATION & AFFILIATES. All Rights Reserved.
|
||||
*/
|
||||
|
||||
#include <nvidia/conftest.h>
|
||||
@@ -620,16 +620,9 @@ static struct iommu_domain *host1x_iommu_attach(struct host1x *host)
|
||||
if (err < 0)
|
||||
goto put_group;
|
||||
|
||||
#if defined(NV_IOMMU_PAGING_DOMAIN_ALLOC_PRESENT) /* Linux v6.11 */
|
||||
host->domain = iommu_paging_domain_alloc(host->dev);
|
||||
if (IS_ERR(host->domain)) {
|
||||
err = PTR_ERR(host->domain);
|
||||
host->domain = NULL;
|
||||
#else
|
||||
host->domain = iommu_domain_alloc(&platform_bus_type);
|
||||
if (!host->domain) {
|
||||
err = -ENOMEM;
|
||||
#endif
|
||||
goto put_cache;
|
||||
}
|
||||
|
||||
@@ -1109,18 +1102,6 @@ static const struct dev_pm_ops host1x_pm_ops = {
|
||||
SET_SYSTEM_SLEEP_PM_OPS(host1x_runtime_suspend, host1x_runtime_resume)
|
||||
};
|
||||
|
||||
#if defined(NV_PLATFORM_DRIVER_STRUCT_REMOVE_RETURNS_VOID) /* Linux v6.11 */
|
||||
static void host1x_remove_wrapper(struct platform_device *pdev)
|
||||
{
|
||||
host1x_remove(pdev);
|
||||
}
|
||||
#else
|
||||
static int host1x_remove_wrapper(struct platform_device *pdev)
|
||||
{
|
||||
return host1x_remove(pdev);
|
||||
}
|
||||
#endif
|
||||
|
||||
static struct platform_driver tegra_host1x_driver = {
|
||||
.driver = {
|
||||
.name = "tegra-host1x",
|
||||
@@ -1128,7 +1109,7 @@ static struct platform_driver tegra_host1x_driver = {
|
||||
.pm = &host1x_pm_ops,
|
||||
},
|
||||
.probe = host1x_probe,
|
||||
.remove = host1x_remove_wrapper,
|
||||
.remove = host1x_remove,
|
||||
};
|
||||
|
||||
static struct platform_driver * const drivers[] = {
|
||||
|
||||
@@ -12,7 +12,6 @@
|
||||
#include <trace/events/host1x.h>
|
||||
|
||||
#include "../channel.h"
|
||||
#include "../context.h"
|
||||
#include "../dev.h"
|
||||
#include "../intr.h"
|
||||
#include "../job.h"
|
||||
@@ -90,7 +89,7 @@ static void submit_setclass(struct host1x_job *job, u32 next_class)
|
||||
* firmware stream ID.
|
||||
*/
|
||||
if (job->memory_context)
|
||||
stream_id = job->memory_context->hw->stream_id;
|
||||
stream_id = job->memory_context->stream_id;
|
||||
else
|
||||
stream_id = job->engine_fallback_streamid;
|
||||
|
||||
|
||||
@@ -495,26 +495,12 @@ int tegra_mipi_finish_calibration(struct tegra_mipi_device *device);
|
||||
struct host1x_memory_context {
|
||||
struct host1x *host;
|
||||
|
||||
struct device *dev; /* Owning engine */
|
||||
struct pid *pid;
|
||||
|
||||
refcount_t ref;
|
||||
struct pid *owner;
|
||||
|
||||
struct host1x_hw_memory_context *hw;
|
||||
struct device *context_dev; /* Context device */
|
||||
struct list_head entry; /* Entry in hw_memory_context's list */
|
||||
struct list_head mappings; /* List of mappings */
|
||||
};
|
||||
|
||||
struct host1x_context_mapping {
|
||||
struct host1x *host;
|
||||
|
||||
struct host1x_bo_mapping *mapping;
|
||||
|
||||
struct host1x_bo *bo;
|
||||
enum dma_data_direction direction;
|
||||
|
||||
struct list_head entry;
|
||||
struct device dev;
|
||||
u64 dma_mask;
|
||||
u32 stream_id;
|
||||
};
|
||||
|
||||
#ifdef CONFIG_IOMMU_API
|
||||
@@ -523,11 +509,6 @@ struct host1x_memory_context *host1x_memory_context_alloc(struct host1x *host1x,
|
||||
struct pid *pid);
|
||||
void host1x_memory_context_get(struct host1x_memory_context *cd);
|
||||
void host1x_memory_context_put(struct host1x_memory_context *cd);
|
||||
int host1x_memory_context_active(struct host1x_memory_context *cd);
|
||||
void host1x_memory_context_inactive(struct host1x_memory_context *cd);
|
||||
struct host1x_context_mapping *host1x_memory_context_map(
|
||||
struct host1x_memory_context *ctx, struct host1x_bo *bo, enum dma_data_direction direction);
|
||||
void host1x_memory_context_unmap(struct host1x_context_mapping *m);
|
||||
#else
|
||||
static inline struct host1x_memory_context *host1x_memory_context_alloc(struct host1x *host1x,
|
||||
struct pid *pid)
|
||||
@@ -542,25 +523,6 @@ static inline void host1x_memory_context_get(struct host1x_memory_context *cd)
|
||||
static inline void host1x_memory_context_put(struct host1x_memory_context *cd)
|
||||
{
|
||||
}
|
||||
|
||||
static inline int host1x_memory_context_active(struct host1x_memory_context *cd)
|
||||
{
|
||||
return -ENODEV;
|
||||
}
|
||||
|
||||
static inline void host1x_memory_context_inactive(struct host1x_memory_context *cd)
|
||||
{
|
||||
}
|
||||
|
||||
static inline struct host1x_context_mapping *host1x_memory_context_map(
|
||||
struct host1x_memory_context *ctx, struct host1x_bo *bo, enum dma_data_direction direction)
|
||||
{
|
||||
return ERR_PTR(-ENODEV);
|
||||
}
|
||||
|
||||
static inline void host1x_memory_context_unmap(struct host1x_context_mapping *m)
|
||||
{
|
||||
}
|
||||
#endif
|
||||
|
||||
int host1x_actmon_read_avg_count(struct host1x_client *client);
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
/*
|
||||
* SPDX-FileCopyrightText: Copyright (c) 2013-2025 NVIDIA CORPORATION & AFFILIATES. All rights reserved.
|
||||
* Copyright (C) 2013 NVIDIA Corporation
|
||||
*
|
||||
* Permission to use, copy, modify, distribute, and sell this software and its
|
||||
* documentation for any purpose is hereby granted without fee, provided that
|
||||
@@ -20,8 +20,6 @@
|
||||
* OF THIS SOFTWARE.
|
||||
*/
|
||||
|
||||
#include <nvidia/conftest.h>
|
||||
|
||||
#include <linux/clk.h>
|
||||
#include <linux/host1x-next.h>
|
||||
#include <linux/io.h>
|
||||
@@ -548,23 +546,11 @@ static int tegra_mipi_remove(struct platform_device *pdev)
|
||||
return 0;
|
||||
}
|
||||
|
||||
#if defined(NV_PLATFORM_DRIVER_STRUCT_REMOVE_RETURNS_VOID) /* Linux v6.11 */
|
||||
static void tegra_mipi_remove_wrapper(struct platform_device *pdev)
|
||||
{
|
||||
tegra_mipi_remove(pdev);
|
||||
}
|
||||
#else
|
||||
static int tegra_mipi_remove_wrapper(struct platform_device *pdev)
|
||||
{
|
||||
return tegra_mipi_remove(pdev);
|
||||
}
|
||||
#endif
|
||||
|
||||
struct platform_driver tegra_mipi_driver = {
|
||||
.driver = {
|
||||
.name = "tegra-mipi",
|
||||
.of_match_table = tegra_mipi_of_match,
|
||||
},
|
||||
.probe = tegra_mipi_probe,
|
||||
.remove = tegra_mipi_remove_wrapper,
|
||||
.remove = tegra_mipi_remove,
|
||||
};
|
||||
|
||||
@@ -1,5 +1,4 @@
|
||||
# SPDX-License-Identifier: GPL-2.0
|
||||
# Copyright (c) 2022-2025, NVIDIA CORPORATION. All rights reserved.
|
||||
# Copyright (c) 2022-2023, NVIDIA CORPORATION. All rights reserved.
|
||||
|
||||
obj-m += i2c-nvvrs11.o
|
||||
obj-m += i2c-tegra-slave-byte.o
|
||||
|
||||
@@ -2,7 +2,7 @@
|
||||
/*
|
||||
* Voltage Regulator Specification: VRS11 High Current Voltage Regulator
|
||||
*
|
||||
* Copyright (C) 2022-2024 NVIDIA CORPORATION. All rights reserved.
|
||||
* Copyright (C) 2022-2023 NVIDIA CORPORATION. All rights reserved.
|
||||
*/
|
||||
|
||||
#include <nvidia/conftest.h>
|
||||
@@ -120,8 +120,8 @@ static ssize_t show_loopA_rail_power(struct device *dev,
|
||||
if (current_A < 0)
|
||||
return current_A;
|
||||
|
||||
power = (voltage_A * current_A);
|
||||
return sprintf(buf, "%u mW\n", power);
|
||||
power = (voltage_A * current_A)/1000;
|
||||
return sprintf(buf, "%u W\n", power);
|
||||
}
|
||||
|
||||
static ssize_t show_loopB_rail_name(struct device *dev,
|
||||
@@ -180,9 +180,9 @@ static ssize_t show_loopB_rail_power(struct device *dev,
|
||||
if (current_B < 0)
|
||||
return current_B;
|
||||
|
||||
power = (voltage_B * current_B);
|
||||
power = (voltage_B * current_B)/1000;
|
||||
|
||||
return sprintf(buf, "%u mW\n", power);
|
||||
return sprintf(buf, "%u W\n", power);
|
||||
}
|
||||
|
||||
static DEVICE_ATTR(loopA_rail_name, S_IRUGO, show_loopA_rail_name, NULL);
|
||||
|
||||
@@ -1,475 +0,0 @@
|
||||
// SPDX-License-Identifier: GPL-2.0-only
|
||||
// SPDX-FileCopyrightText: Copyright (c) 2025 NVIDIA CORPORATION & AFFILIATES. All rights reserved.
|
||||
|
||||
#include <nvidia/conftest.h>
|
||||
|
||||
#include <linux/kernel.h>
|
||||
#include <linux/init.h>
|
||||
#include <linux/platform_device.h>
|
||||
#include <linux/interrupt.h>
|
||||
#include <linux/slab.h>
|
||||
#include <linux/module.h>
|
||||
#include <linux/clk.h>
|
||||
#include <linux/reset.h>
|
||||
#include <linux/of.h>
|
||||
#include <linux/of_device.h>
|
||||
#include <linux/delay.h>
|
||||
#include <linux/i2c.h>
|
||||
#include <linux/iopoll.h>
|
||||
|
||||
#define I2C_SL_CNFG 0x20
|
||||
#define I2C_SL_CNFG_ENABLE_SL BIT(3)
|
||||
#define I2C_SL_CNFG_NEW_SL BIT(2)
|
||||
|
||||
#define I2C_SL_RCVD 0x24
|
||||
|
||||
#define I2C_SL_STATUS 0x28
|
||||
#define I2C_SL_STATUS_END_TRANS BIT(4)
|
||||
#define I2C_SL_STATUS_SL_IRQ BIT(3)
|
||||
#define I2C_SL_STATUS_RCVD BIT(2)
|
||||
#define I2C_SL_STATUS_RNW BIT(1)
|
||||
|
||||
#define I2C_SL_ADDR1 0x2c
|
||||
#define I2C_SL_ADDR2 0x30
|
||||
#define I2C_SL_ADDR2_MASK 0x1FFFF
|
||||
#define I2C_7BIT_ADDR_MASK 0x7F
|
||||
|
||||
#define I2C_TLOW_SEXT 0x34
|
||||
#define I2C_SL_DELAY_COUNT 0x3c
|
||||
#define I2C_SL_DELAY_COUNT_RESET 0x1e
|
||||
|
||||
#define I2C_SL_INT_MASK 0x40
|
||||
#define I2C_SL_INT_SOURCE 0x44
|
||||
|
||||
#define I2C_SL_INT_SET 0x48
|
||||
#define I2C_FIFO_CONTROL 0x5c
|
||||
|
||||
#define I2C_INTERRUPT_MASK_REGISTER 0x64
|
||||
#define I2C_INTERRUPT_STATUS_REGISTER 0x68
|
||||
#define I2C_INTERRUPT_SOURCE_REGISTER 0x70
|
||||
#define I2C_INTERRUPT_SLV_WR2RD BIT(26)
|
||||
#define I2C_INTERRUPT_SET_REGISTER 0x74
|
||||
|
||||
#define I2C_CONFIG_LOAD 0x8c
|
||||
#define I2C_TIMEOUT_CONFIG_LOAD BIT(2)
|
||||
#define I2C_CONFIG_LOAD_SLV BIT(1)
|
||||
#define I2C_CONFIG_LOAD_TIMEOUT 1000000
|
||||
|
||||
#define I2C_CLKEN_OVERRIDE 0x90
|
||||
#define I2C_DEBUG_CONTROL 0xa4
|
||||
|
||||
struct tegra_i2cslv_dev {
|
||||
struct device *dev;
|
||||
struct i2c_adapter adap;
|
||||
struct clk *div_clk;
|
||||
struct reset_control *rstc;
|
||||
void __iomem *base;
|
||||
struct i2c_client *slave;
|
||||
raw_spinlock_t xfer_lock;
|
||||
};
|
||||
|
||||
static inline u32 tegra_i2cslv_readl(struct tegra_i2cslv_dev *i2cslv_dev,
|
||||
unsigned long reg)
|
||||
{
|
||||
return readl(i2cslv_dev->base + reg);
|
||||
}
|
||||
|
||||
static inline void tegra_i2cslv_writel(struct tegra_i2cslv_dev *i2cslv_dev,
|
||||
unsigned long val, unsigned long reg)
|
||||
{
|
||||
writel(val, i2cslv_dev->base + reg);
|
||||
}
|
||||
|
||||
static void tegra_i2cslv_dump_reg(struct tegra_i2cslv_dev *i2cslv_dev)
|
||||
{
|
||||
dev_warn(i2cslv_dev->dev, "I2C_I2C_SL_INT_SOURCE_0 0x%x\n",
|
||||
tegra_i2cslv_readl(i2cslv_dev, I2C_SL_INT_SOURCE));
|
||||
dev_warn(i2cslv_dev->dev, "I2C_INTERRUPT_STATUS_REGISTER_0 0x%x\n",
|
||||
tegra_i2cslv_readl(i2cslv_dev, I2C_INTERRUPT_STATUS_REGISTER));
|
||||
dev_warn(i2cslv_dev->dev, "I2C_I2C_SL_STATUS_0 0x%x\n",
|
||||
tegra_i2cslv_readl(i2cslv_dev, I2C_SL_STATUS));
|
||||
dev_warn(i2cslv_dev->dev, "I2C_INTERRUPT_SOURCE_REGISTER 0x%x\n",
|
||||
tegra_i2cslv_readl(i2cslv_dev, I2C_INTERRUPT_SOURCE_REGISTER));
|
||||
dev_warn(i2cslv_dev->dev, "I2C_I2C_SL_CNFG_0 0x%x\n",
|
||||
tegra_i2cslv_readl(i2cslv_dev, I2C_SL_CNFG));
|
||||
dev_warn(i2cslv_dev->dev, "I2C_SL_ADDR1 0x%x\n",
|
||||
tegra_i2cslv_readl(i2cslv_dev, I2C_SL_ADDR1));
|
||||
dev_warn(i2cslv_dev->dev, "I2C_INTERRUPT_MASK_REGISTER_0 0x%x\n",
|
||||
tegra_i2cslv_readl(i2cslv_dev, I2C_INTERRUPT_MASK_REGISTER));
|
||||
dev_warn(i2cslv_dev->dev, "I2C_I2C_SL_INT_MASK_0 0x%x\n",
|
||||
tegra_i2cslv_readl(i2cslv_dev, I2C_SL_INT_MASK));
|
||||
}
|
||||
|
||||
static int tegra_i2cslv_load_config(struct tegra_i2cslv_dev *i2cslv_dev)
|
||||
{
|
||||
u32 i2c_load_config_reg, val;
|
||||
int ret;
|
||||
|
||||
i2c_load_config_reg = tegra_i2cslv_readl(i2cslv_dev, I2C_CONFIG_LOAD);
|
||||
i2c_load_config_reg |= I2C_CONFIG_LOAD_SLV;
|
||||
tegra_i2cslv_writel(i2cslv_dev, i2c_load_config_reg, I2C_CONFIG_LOAD);
|
||||
|
||||
ret = readl_poll_timeout_atomic(i2cslv_dev->base +
|
||||
I2C_CONFIG_LOAD, val,
|
||||
!(val & I2C_CONFIG_LOAD_SLV),
|
||||
1000, I2C_CONFIG_LOAD_TIMEOUT);
|
||||
if (ret)
|
||||
dev_err(i2cslv_dev->dev, "ERR unable to load i2cslv config\n");
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
/* tegra_i2cslv_handle_rx - To get the data byte from bus and provide the
|
||||
* data to client driver
|
||||
*/
|
||||
static void tegra_i2cslv_handle_rx(struct tegra_i2cslv_dev *i2cslv_dev,
|
||||
const unsigned long i2c_int_src,
|
||||
const unsigned long i2c_slv_src)
|
||||
{
|
||||
u8 value;
|
||||
|
||||
if (i2c_slv_src & I2C_SL_STATUS_END_TRANS) {
|
||||
/* clear the interrupts to release the SCL line */
|
||||
tegra_i2cslv_writel(i2cslv_dev, I2C_SL_STATUS_END_TRANS |
|
||||
I2C_SL_STATUS_SL_IRQ, I2C_SL_STATUS);
|
||||
i2c_slave_event(i2cslv_dev->slave, I2C_SLAVE_STOP, &value);
|
||||
} else {
|
||||
value = (u8)tegra_i2cslv_readl(i2cslv_dev, I2C_SL_RCVD);
|
||||
/* Send the received data to client driver */
|
||||
i2c_slave_event(i2cslv_dev->slave, I2C_SLAVE_WRITE_RECEIVED, &value);
|
||||
/* clear the interrupt to release the SCL line */
|
||||
tegra_i2cslv_writel(i2cslv_dev, I2C_SL_STATUS_SL_IRQ, I2C_SL_STATUS);
|
||||
}
|
||||
}
|
||||
|
||||
/* tegra_i2cslv_handle_tx - To get the data byte fron client driver and
|
||||
* send it to master over bus.
|
||||
*/
|
||||
static void tegra_i2cslv_handle_tx(struct tegra_i2cslv_dev *i2cslv_dev,
|
||||
const unsigned long i2c_int_src,
|
||||
const unsigned long i2c_slv_src)
|
||||
{
|
||||
u8 value;
|
||||
|
||||
if (i2c_slv_src & I2C_SL_STATUS_END_TRANS) {
|
||||
/* clear the interrupt to release the SCL line */
|
||||
tegra_i2cslv_writel(i2cslv_dev, I2C_SL_STATUS_END_TRANS |
|
||||
I2C_SL_STATUS_SL_IRQ, I2C_SL_STATUS);
|
||||
i2c_slave_event(i2cslv_dev->slave, I2C_SLAVE_STOP, &value);
|
||||
} else {
|
||||
/* clear the interrupt to release the SCL line */
|
||||
tegra_i2cslv_writel(i2cslv_dev, I2C_SL_STATUS_SL_IRQ, I2C_SL_STATUS);
|
||||
/* Get the data byte from client driver*/
|
||||
i2c_slave_event(i2cslv_dev->slave, I2C_SLAVE_READ_PROCESSED, &value);
|
||||
tegra_i2cslv_writel(i2cslv_dev, value, I2C_SL_RCVD);
|
||||
}
|
||||
}
|
||||
|
||||
static int tegra_i2cslv_init(struct tegra_i2cslv_dev *i2cslv_dev)
|
||||
{
|
||||
u32 reg;
|
||||
int ret;
|
||||
|
||||
ret = clk_enable(i2cslv_dev->div_clk);
|
||||
if (ret < 0) {
|
||||
dev_err(i2cslv_dev->dev, "Enable div-clk failed: %d\n", ret);
|
||||
return ret;
|
||||
}
|
||||
|
||||
/* Reset the controller */
|
||||
reset_control_assert(i2cslv_dev->rstc);
|
||||
udelay(2);
|
||||
reset_control_deassert(i2cslv_dev->rstc);
|
||||
|
||||
/* Program the 7-bit slave address */
|
||||
tegra_i2cslv_writel(i2cslv_dev, i2cslv_dev->slave->addr &
|
||||
I2C_7BIT_ADDR_MASK, I2C_SL_ADDR1);
|
||||
|
||||
/* Specify its 7-bit address mode */
|
||||
reg = tegra_i2cslv_readl(i2cslv_dev, I2C_SL_ADDR2);
|
||||
reg &= ~(I2C_SL_ADDR2_MASK);
|
||||
tegra_i2cslv_writel(i2cslv_dev, reg, I2C_SL_ADDR2);
|
||||
|
||||
/* Unmask WR2RD interrupt, just to clear it */
|
||||
tegra_i2cslv_writel(i2cslv_dev, (I2C_INTERRUPT_SLV_WR2RD),
|
||||
I2C_INTERRUPT_MASK_REGISTER);
|
||||
|
||||
tegra_i2cslv_writel(i2cslv_dev, (I2C_SL_STATUS_END_TRANS |
|
||||
I2C_SL_STATUS_SL_IRQ | I2C_SL_STATUS_RCVD),
|
||||
I2C_SL_INT_MASK);
|
||||
|
||||
reg = tegra_i2cslv_readl(i2cslv_dev, I2C_SL_CNFG);
|
||||
reg |= (I2C_SL_CNFG_NEW_SL | I2C_SL_CNFG_ENABLE_SL);
|
||||
tegra_i2cslv_writel(i2cslv_dev, reg, I2C_SL_CNFG);
|
||||
|
||||
return tegra_i2cslv_load_config(i2cslv_dev);
|
||||
}
|
||||
|
||||
static void tegra_i2cslv_deinit(struct tegra_i2cslv_dev *i2cslv_dev)
|
||||
{
|
||||
tegra_i2cslv_writel(i2cslv_dev, 0, I2C_INTERRUPT_MASK_REGISTER);
|
||||
tegra_i2cslv_writel(i2cslv_dev, 0, I2C_SL_INT_MASK);
|
||||
clk_disable(i2cslv_dev->div_clk);
|
||||
}
|
||||
|
||||
static irqreturn_t tegra_i2cslv_isr(int irq, void *dev_id)
|
||||
{
|
||||
struct tegra_i2cslv_dev *i2cslv_dev = dev_id;
|
||||
u32 i2c_int_src, i2c_slv_int_src, i2c_slv_sts;
|
||||
u8 value;
|
||||
unsigned long flags;
|
||||
|
||||
raw_spin_lock_irqsave(&i2cslv_dev->xfer_lock, flags);
|
||||
i2c_int_src = tegra_i2cslv_readl(i2cslv_dev,
|
||||
I2C_INTERRUPT_SOURCE_REGISTER);
|
||||
i2c_slv_int_src = tegra_i2cslv_readl(i2cslv_dev, I2C_SL_INT_SOURCE);
|
||||
i2c_slv_sts = tegra_i2cslv_readl(i2cslv_dev, I2C_SL_STATUS);
|
||||
|
||||
/* Address received */
|
||||
if ((i2c_slv_int_src & I2C_SL_STATUS_SL_IRQ) &&
|
||||
(i2c_slv_int_src & I2C_SL_STATUS_RCVD)) {
|
||||
/* End of transfer of previous transaction, just clear it */
|
||||
if (i2c_slv_int_src & I2C_SL_STATUS_END_TRANS) {
|
||||
i2c_slave_event(i2cslv_dev->slave, I2C_SLAVE_STOP,
|
||||
&value);
|
||||
tegra_i2cslv_writel(i2cslv_dev, I2C_SL_STATUS_END_TRANS,
|
||||
I2C_SL_STATUS);
|
||||
}
|
||||
/* Clear the interrupt */
|
||||
tegra_i2cslv_writel(i2cslv_dev, I2C_SL_STATUS_SL_IRQ |
|
||||
I2C_SL_STATUS_RCVD, I2C_SL_STATUS);
|
||||
/* if RNW, master issued read. */
|
||||
if (i2c_slv_sts & I2C_SL_STATUS_RNW) {
|
||||
i2c_slave_event(i2cslv_dev->slave,
|
||||
I2C_SLAVE_READ_REQUESTED, &value);
|
||||
tegra_i2cslv_writel(i2cslv_dev, value,
|
||||
I2C_SL_RCVD);
|
||||
} else {
|
||||
i2c_slave_event(i2cslv_dev->slave,
|
||||
I2C_SLAVE_WRITE_REQUESTED, &value);
|
||||
}
|
||||
goto done;
|
||||
}
|
||||
if (unlikely(i2c_int_src & I2C_INTERRUPT_SLV_WR2RD)) {
|
||||
/* Clear WR2RD interrupt */
|
||||
tegra_i2cslv_writel(i2cslv_dev, I2C_INTERRUPT_SLV_WR2RD,
|
||||
I2C_INTERRUPT_STATUS_REGISTER);
|
||||
goto done;
|
||||
}
|
||||
|
||||
if ((i2c_slv_int_src & I2C_SL_STATUS_SL_IRQ)) {
|
||||
if (!(i2c_slv_sts & I2C_SL_STATUS_RNW)) {
|
||||
/* Master write and Slave receive */
|
||||
tegra_i2cslv_handle_rx(i2cslv_dev, i2c_int_src,
|
||||
i2c_slv_int_src);
|
||||
goto done;
|
||||
} else if (i2c_slv_sts & I2C_SL_STATUS_RNW) {
|
||||
/* Master read and slave write */
|
||||
tegra_i2cslv_handle_tx(i2cslv_dev, i2c_int_src,
|
||||
i2c_slv_int_src);
|
||||
goto done;
|
||||
}
|
||||
} else {
|
||||
dev_err(i2cslv_dev->dev, "Slave IRQ not set\n");
|
||||
goto err;
|
||||
}
|
||||
err:
|
||||
tegra_i2cslv_dump_reg(i2cslv_dev);
|
||||
tegra_i2cslv_init(i2cslv_dev);
|
||||
done:
|
||||
raw_spin_unlock_irqrestore(&i2cslv_dev->xfer_lock, flags);
|
||||
return IRQ_HANDLED;
|
||||
}
|
||||
|
||||
static int tegra_reg_slave(struct i2c_client *slave)
|
||||
{
|
||||
struct tegra_i2cslv_dev *i2cslv_dev =
|
||||
i2c_get_adapdata(slave->adapter);
|
||||
int ret;
|
||||
|
||||
if (i2cslv_dev->slave)
|
||||
return -EBUSY;
|
||||
|
||||
if (slave->flags & I2C_CLIENT_TEN)
|
||||
return -EAFNOSUPPORT;
|
||||
i2cslv_dev->slave = slave;
|
||||
|
||||
ret = clk_enable(i2cslv_dev->div_clk);
|
||||
if (ret < 0) {
|
||||
dev_err(i2cslv_dev->dev, "Enable div-clk failed: %d\n", ret);
|
||||
return ret;
|
||||
}
|
||||
|
||||
return tegra_i2cslv_init(i2cslv_dev);
|
||||
}
|
||||
|
||||
static int tegra_unreg_slave(struct i2c_client *slave)
|
||||
{
|
||||
struct tegra_i2cslv_dev *i2cslv_dev =
|
||||
i2c_get_adapdata(slave->adapter);
|
||||
|
||||
WARN_ON(!i2cslv_dev->slave);
|
||||
tegra_i2cslv_deinit(i2cslv_dev);
|
||||
|
||||
i2cslv_dev->slave = NULL;
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static u32 tegra_i2c_func(struct i2c_adapter *adap)
|
||||
{
|
||||
return I2C_FUNC_I2C | I2C_FUNC_SLAVE;
|
||||
}
|
||||
|
||||
static const struct i2c_algorithm tegra_i2cslv_algo = {
|
||||
.functionality = tegra_i2c_func,
|
||||
.reg_slave = tegra_reg_slave,
|
||||
.unreg_slave = tegra_unreg_slave,
|
||||
};
|
||||
|
||||
static int tegra_i2cslv_probe(struct platform_device *pdev)
|
||||
{
|
||||
struct tegra_i2cslv_dev *i2cslv_dev;
|
||||
struct i2c_adapter *adap;
|
||||
int irq, ret;
|
||||
|
||||
i2cslv_dev = devm_kzalloc(&pdev->dev, sizeof(*i2cslv_dev), GFP_KERNEL);
|
||||
if (!i2cslv_dev)
|
||||
return -ENOMEM;
|
||||
|
||||
i2cslv_dev->base = devm_platform_get_and_ioremap_resource(pdev, 0, NULL);
|
||||
if (IS_ERR(i2cslv_dev->base))
|
||||
return PTR_ERR(i2cslv_dev->base);
|
||||
|
||||
irq = platform_get_irq(pdev, 0);
|
||||
if (irq < 0) {
|
||||
dev_err(&pdev->dev, "failed to get IRQ %d\n", irq);
|
||||
return irq;
|
||||
}
|
||||
|
||||
i2cslv_dev->div_clk = devm_clk_get(&pdev->dev, "div-clk");
|
||||
if (IS_ERR(i2cslv_dev->div_clk)) {
|
||||
dev_err(&pdev->dev, "missing controller clock");
|
||||
return PTR_ERR(i2cslv_dev->div_clk);
|
||||
}
|
||||
|
||||
i2cslv_dev->rstc = devm_reset_control_get(&pdev->dev, "i2c");
|
||||
if (IS_ERR(i2cslv_dev->rstc)) {
|
||||
dev_err(&pdev->dev, "missing controller reset\n");
|
||||
return PTR_ERR(i2cslv_dev->rstc);
|
||||
}
|
||||
|
||||
i2cslv_dev->dev = &pdev->dev;
|
||||
raw_spin_lock_init(&i2cslv_dev->xfer_lock);
|
||||
|
||||
adap = &i2cslv_dev->adap;
|
||||
adap->algo = &tegra_i2cslv_algo;
|
||||
adap->class = I2C_CLASS_DEPRECATED;
|
||||
adap->dev.parent = &pdev->dev;
|
||||
adap->dev.of_node = pdev->dev.of_node;
|
||||
i2c_set_adapdata(adap, i2cslv_dev);
|
||||
platform_set_drvdata(pdev, i2cslv_dev);
|
||||
strscpy(adap->name, pdev->name, sizeof(adap->name));
|
||||
|
||||
ret = clk_prepare(i2cslv_dev->div_clk);
|
||||
if (ret < 0) {
|
||||
dev_err(&pdev->dev, "clock prepare failed %d\n", ret);
|
||||
return ret;
|
||||
}
|
||||
|
||||
ret = devm_request_irq(&pdev->dev, irq, tegra_i2cslv_isr,
|
||||
0, dev_name(&pdev->dev), i2cslv_dev);
|
||||
if (ret < 0) {
|
||||
dev_err(&pdev->dev, "Failed to register ISR for IRQ %d\n", irq);
|
||||
clk_unprepare(i2cslv_dev->div_clk);
|
||||
return ret;
|
||||
}
|
||||
|
||||
ret = i2c_add_adapter(&i2cslv_dev->adap);
|
||||
if (ret) {
|
||||
dev_err(&pdev->dev, "Failed to add I2C adapter\n");
|
||||
clk_unprepare(i2cslv_dev->div_clk);
|
||||
return ret;
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int tegra_i2cslv_remove(struct platform_device *pdev)
|
||||
{
|
||||
struct tegra_i2cslv_dev *i2cslv_dev = platform_get_drvdata(pdev);
|
||||
|
||||
i2c_del_adapter(&i2cslv_dev->adap);
|
||||
clk_unprepare(i2cslv_dev->div_clk);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
#if defined(NV_PLATFORM_DRIVER_STRUCT_REMOVE_RETURNS_VOID) /* Linux v6.11 */
|
||||
static void tegra_i2cslv_remove_wrapper(struct platform_device *pdev)
|
||||
{
|
||||
tegra_i2cslv_remove(pdev);
|
||||
}
|
||||
#else
|
||||
static int tegra_i2cslv_remove_wrapper(struct platform_device *pdev)
|
||||
{
|
||||
return tegra_i2cslv_remove(pdev);
|
||||
}
|
||||
#endif
|
||||
|
||||
#ifdef CONFIG_PM_SLEEP
|
||||
static int tegra_i2cslv_suspend(struct device *dev)
|
||||
{
|
||||
struct tegra_i2cslv_dev *i2cslv_dev = dev_get_drvdata(dev);
|
||||
unsigned long flags;
|
||||
|
||||
raw_spin_lock_irqsave(&i2cslv_dev->xfer_lock, flags);
|
||||
|
||||
tegra_i2cslv_deinit(i2cslv_dev);
|
||||
|
||||
raw_spin_unlock_irqrestore(&i2cslv_dev->xfer_lock, flags);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int tegra_i2cslv_resume(struct device *dev)
|
||||
{
|
||||
struct tegra_i2cslv_dev *i2cslv_dev = dev_get_drvdata(dev);
|
||||
unsigned long flags;
|
||||
int ret;
|
||||
|
||||
raw_spin_lock_irqsave(&i2cslv_dev->xfer_lock, flags);
|
||||
ret = tegra_i2cslv_init(i2cslv_dev);
|
||||
raw_spin_unlock_irqrestore(&i2cslv_dev->xfer_lock, flags);
|
||||
|
||||
return ret;
|
||||
}
|
||||
#endif
|
||||
|
||||
static const struct dev_pm_ops tegra_i2cslv_pm_ops = {
|
||||
SET_SYSTEM_SLEEP_PM_OPS(tegra_i2cslv_suspend, tegra_i2cslv_resume)
|
||||
};
|
||||
|
||||
static const struct of_device_id tegra_i2cslv_of_match[] = {
|
||||
{.compatible = "nvidia,tegra-i2c-slave-byte",},
|
||||
{}
|
||||
};
|
||||
|
||||
MODULE_DEVICE_TABLE(of, tegra_i2cslv_of_match);
|
||||
|
||||
static struct platform_driver tegra_i2cslv_driver = {
|
||||
.probe = tegra_i2cslv_probe,
|
||||
.remove = tegra_i2cslv_remove_wrapper,
|
||||
.driver = {
|
||||
.name = "tegra-i2cslv",
|
||||
.owner = THIS_MODULE,
|
||||
.of_match_table = of_match_ptr(tegra_i2cslv_of_match),
|
||||
.pm = &tegra_i2cslv_pm_ops,
|
||||
},
|
||||
};
|
||||
|
||||
module_platform_driver(tegra_i2cslv_driver);
|
||||
|
||||
MODULE_AUTHOR("Shardar Shariff Md <smohammed@nvidia.com>");
|
||||
MODULE_DESCRIPTION("NVIDIA Tegra I2C slave driver");
|
||||
MODULE_LICENSE("GPL v2");
|
||||
File diff suppressed because it is too large
Load Diff
@@ -1,7 +1,7 @@
|
||||
/* SPDX-License-Identifier: GPL-2.0-only */
|
||||
/* SPDX-FileCopyrightText: Copyright (c) 2020-2025, NVIDIA CORPORATION & AFFILIATES. All rights reserved. */
|
||||
/*
|
||||
* imx477_mode_tbls.h - imx477 sensor mode tables
|
||||
* Copyright (c) 2020-2023, NVIDIA CORPORATION & AFFILIATES. All rights reserved.
|
||||
*
|
||||
*/
|
||||
|
||||
#ifndef __IMX477_I2C_TABLES__
|
||||
@@ -575,9 +575,249 @@ static const imx477_reg imx477_mode_1920x1080_60fps[] = {
|
||||
{IMX477_TABLE_END, 0x0000}
|
||||
};
|
||||
|
||||
static const imx477_reg imx477_mode_3840x2160_30fps_4lane[] = {
|
||||
{0x0112, 0x0A},
|
||||
{0x0113, 0x0A},
|
||||
{0x0114, 0x03},
|
||||
{0x0342, 0x16},
|
||||
{0x0343, 0xC8},
|
||||
{0x0340, 0x12},
|
||||
{0x0341, 0xC0},
|
||||
{0x0344, 0x00},
|
||||
{0x0345, 0x00},
|
||||
{0x0346, 0x01},
|
||||
{0x0347, 0xB8},
|
||||
{0x0348, 0x0F},
|
||||
{0x0349, 0xD7},
|
||||
{0x034A, 0x0A},
|
||||
{0x034B, 0x27},
|
||||
{0x00E3, 0x00},
|
||||
{0x00E4, 0x00},
|
||||
{0x00FC, 0x0A},
|
||||
{0x00FD, 0x0A},
|
||||
{0x00FE, 0x0A},
|
||||
{0x00FF, 0x0A},
|
||||
{0x0E13, 0x00},
|
||||
{0x0220, 0x00},
|
||||
{0x0221, 0x11},
|
||||
{0x0381, 0x01},
|
||||
{0x0383, 0x01},
|
||||
{0x0385, 0x01},
|
||||
{0x0387, 0x01},
|
||||
{0x0900, 0x00},
|
||||
{0x0901, 0x11},
|
||||
{0x0902, 0x02},
|
||||
{0x3140, 0x02},
|
||||
{0x3C00, 0x00},
|
||||
{0x3C01, 0x03},
|
||||
{0x3C02, 0xDC},
|
||||
{0x3F0D, 0x00},
|
||||
{0x5748, 0x07},
|
||||
{0x5749, 0xFF},
|
||||
{0x574A, 0x00},
|
||||
{0x574B, 0x00},
|
||||
{0x7B75, 0x0E},
|
||||
{0x7B76, 0x09},
|
||||
{0x7B77, 0x0C},
|
||||
{0x7B78, 0x06},
|
||||
{0x7B79, 0x3B},
|
||||
{0x7B53, 0x01},
|
||||
{0x9369, 0x5A},
|
||||
{0x936B, 0x55},
|
||||
{0x936D, 0x28},
|
||||
{0x9304, 0x03},
|
||||
{0x9305, 0x00},
|
||||
{0x9E9A, 0x2F},
|
||||
{0x9E9B, 0x2F},
|
||||
{0x9E9C, 0x2F},
|
||||
{0x9E9D, 0x00},
|
||||
{0x9E9E, 0x00},
|
||||
{0x9E9F, 0x00},
|
||||
{0xA2A9, 0x60},
|
||||
{0xA2B7, 0x00},
|
||||
{0x0401, 0x00},
|
||||
{0x0404, 0x00},
|
||||
{0x0405, 0x10},
|
||||
{0x0408, 0x00},
|
||||
{0x0409, 0x6C},
|
||||
{0x040A, 0x00},
|
||||
{0x040B, 0x00},
|
||||
{0x040C, 0x0F},
|
||||
{0x040D, 0x00},
|
||||
{0x040E, 0x08},
|
||||
{0x040F, 0x70},
|
||||
{0x034C, 0x0F},
|
||||
{0x034D, 0x00},
|
||||
{0x034E, 0x08},
|
||||
{0x034F, 0x70},
|
||||
{0x0301, 0x05},
|
||||
{0x0303, 0x02},
|
||||
{0x0305, 0x02},
|
||||
{0x0306, 0x00},
|
||||
{0x0307, 0xAF},
|
||||
{0x0309, 0x0A},
|
||||
{0x030B, 0x01},
|
||||
{0x030D, 0x02},
|
||||
{0x030E, 0x00},
|
||||
{0x030F, 0x7D},
|
||||
{0x0310, 0x01},
|
||||
{0x0820, 0x17},
|
||||
{0x0821, 0x70},
|
||||
{0x0822, 0x00},
|
||||
{0x0823, 0x00},
|
||||
{0x080A, 0x00},
|
||||
{0x080B, 0x97},
|
||||
{0x080C, 0x00},
|
||||
{0x080D, 0x5F},
|
||||
{0x080E, 0x00},
|
||||
{0x080F, 0x9F},
|
||||
{0x0810, 0x00},
|
||||
{0x0811, 0x6F},
|
||||
{0x0812, 0x00},
|
||||
{0x0813, 0x6F},
|
||||
{0x0814, 0x00},
|
||||
{0x0815, 0x57},
|
||||
{0x0816, 0x01},
|
||||
{0x0817, 0x87},
|
||||
{0x0818, 0x00},
|
||||
{0x0819, 0x4F},
|
||||
{0xE04C, 0x00},
|
||||
{0xE04D, 0x9F},
|
||||
{0xE04E, 0x00},
|
||||
{0xE04F, 0x1F},
|
||||
{0x3E20, 0x01},
|
||||
{0x3E37, 0x00},
|
||||
{0x3F50, 0x00},
|
||||
{0x3F56, 0x00},
|
||||
{0x3F57, 0xA7},
|
||||
{IMX477_TABLE_WAIT_MS, IMX477_WAIT_MS},
|
||||
{IMX477_TABLE_END, 0x0000}
|
||||
};
|
||||
|
||||
static const imx477_reg imx477_mode_1920x1080_60fps_4lane[] = {
|
||||
{0x0112, 0x0A},
|
||||
{0x0113, 0x0A},
|
||||
{0x0114, 0x03},
|
||||
{0x0342, 0x0C},
|
||||
{0x0343, 0x04},
|
||||
{0x0340, 0x11},
|
||||
{0x0341, 0xC6},
|
||||
{0x0344, 0x00},
|
||||
{0x0345, 0x00},
|
||||
{0x0346, 0x01},
|
||||
{0x0347, 0xB8},
|
||||
{0x0348, 0x0F},
|
||||
{0x0349, 0xD7},
|
||||
{0x034A, 0x0A},
|
||||
{0x034B, 0x27},
|
||||
{0x00E3, 0x00},
|
||||
{0x00E4, 0x00},
|
||||
{0x00FC, 0x0A},
|
||||
{0x00FD, 0x0A},
|
||||
{0x00FE, 0x0A},
|
||||
{0x00FF, 0x0A},
|
||||
{0x0220, 0x00},
|
||||
{0x0221, 0x11},
|
||||
{0x0381, 0x01},
|
||||
{0x0383, 0x01},
|
||||
{0x0385, 0x01},
|
||||
{0x0387, 0x01},
|
||||
{0x0900, 0x01},
|
||||
{0x0901, 0x22},
|
||||
{0x0902, 0x02},
|
||||
{0x3140, 0x02},
|
||||
{0x3C00, 0x00},
|
||||
{0x3C01, 0x01},
|
||||
{0x3C02, 0x9C},
|
||||
{0x3F0D, 0x00},
|
||||
{0x5748, 0x00},
|
||||
{0x5749, 0x00},
|
||||
{0x574A, 0x00},
|
||||
{0x574B, 0xA4},
|
||||
{0x7B75, 0x0E},
|
||||
{0x7B76, 0x09},
|
||||
{0x7B77, 0x08},
|
||||
{0x7B78, 0x06},
|
||||
{0x7B79, 0x34},
|
||||
{0x7B53, 0x00},
|
||||
{0x9369, 0x73},
|
||||
{0x936B, 0x64},
|
||||
{0x936D, 0x5F},
|
||||
{0x9304, 0x03},
|
||||
{0x9305, 0x80},
|
||||
{0x9E9A, 0x2F},
|
||||
{0x9E9B, 0x2F},
|
||||
{0x9E9C, 0x2F},
|
||||
{0x9E9D, 0x00},
|
||||
{0x9E9E, 0x00},
|
||||
{0x9E9F, 0x00},
|
||||
{0xA2A9, 0x27},
|
||||
{0xA2B7, 0x03},
|
||||
{0x0401, 0x00},
|
||||
{0x0404, 0x00},
|
||||
{0x0405, 0x10},
|
||||
{0x0408, 0x00},
|
||||
{0x0409, 0x36},
|
||||
{0x040A, 0x00},
|
||||
{0x040B, 0x00},
|
||||
{0x040C, 0x07},
|
||||
{0x040D, 0x80},
|
||||
{0x040E, 0x04},
|
||||
{0x040F, 0x38},
|
||||
{0x034C, 0x07},
|
||||
{0x034D, 0x80},
|
||||
{0x034E, 0x04},
|
||||
{0x034F, 0x38},
|
||||
{0x0301, 0x05},
|
||||
{0x0303, 0x02},
|
||||
{0x0305, 0x02},
|
||||
{0x0306, 0x00},
|
||||
{0x0307, 0xAF},
|
||||
{0x0309, 0x0A},
|
||||
{0x030B, 0x01},
|
||||
{0x030D, 0x02},
|
||||
{0x030E, 0x00},
|
||||
{0x030F, 0x7D},
|
||||
{0x0310, 0x01},
|
||||
{0x0820, 0x17},
|
||||
{0x0821, 0x70},
|
||||
{0x0822, 0x00},
|
||||
{0x0823, 0x00},
|
||||
{0x080A, 0x00},
|
||||
{0x080B, 0x97},
|
||||
{0x080C, 0x00},
|
||||
{0x080D, 0x5F},
|
||||
{0x080E, 0x00},
|
||||
{0x080F, 0x9F},
|
||||
{0x0810, 0x00},
|
||||
{0x0811, 0x6F},
|
||||
{0x0812, 0x00},
|
||||
{0x0813, 0x6F},
|
||||
{0x0814, 0x00},
|
||||
{0x0815, 0x57},
|
||||
{0x0816, 0x01},
|
||||
{0x0817, 0x87},
|
||||
{0x0818, 0x00},
|
||||
{0x0819, 0x4F},
|
||||
{0xE04C, 0x00},
|
||||
{0xE04D, 0x9F},
|
||||
{0xE04E, 0x00},
|
||||
{0xE04F, 0x1F},
|
||||
{0x3E20, 0x01},
|
||||
{0x3E37, 0x00},
|
||||
{0x3F50, 0x00},
|
||||
{0x3F56, 0x00},
|
||||
{0x3F57, 0x58},
|
||||
{0X3FF9, 0x01},
|
||||
{IMX477_TABLE_WAIT_MS, IMX477_WAIT_MS},
|
||||
{IMX477_TABLE_END, 0x0000}
|
||||
};
|
||||
|
||||
enum {
|
||||
IMX477_MODE_3840x2160_30FPS,
|
||||
IMX477_MODE_1920x1080_60FPS,
|
||||
IMX477_MODE_3840x2160_30FPS_4LANE,
|
||||
IMX477_MODE_1920x1080_60FPS_4LANE,
|
||||
IMX477_MODE_COMMON,
|
||||
IMX477_START_STREAM,
|
||||
IMX477_STOP_STREAM,
|
||||
@@ -586,6 +826,8 @@ enum {
|
||||
static const imx477_reg *mode_table[] = {
|
||||
[IMX477_MODE_3840x2160_30FPS] = imx477_mode_3840x2160_30fps,
|
||||
[IMX477_MODE_1920x1080_60FPS] = imx477_mode_1920x1080_60fps,
|
||||
[IMX477_MODE_3840x2160_30FPS_4LANE] = imx477_mode_3840x2160_30fps_4lane,
|
||||
[IMX477_MODE_1920x1080_60FPS_4LANE] = imx477_mode_1920x1080_60fps_4lane,
|
||||
[IMX477_MODE_COMMON] = imx477_mode_common,
|
||||
[IMX477_START_STREAM] = imx477_start,
|
||||
[IMX477_STOP_STREAM] = imx477_stop,
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
// SPDX-License-Identifier: GPL-2.0-only
|
||||
// SPDX-FileCopyrightText: Copyright (c) 2021-2025, NVIDIA CORPORATION & AFFILIATES. All rights reserved.
|
||||
// SPDX-FileCopyrightText: Copyright (c) 2021-2024, NVIDIA CORPORATION & AFFILIATES. All rights reserved.
|
||||
/*
|
||||
* imx390.c - imx390 sensor driver
|
||||
* Copyright (c) 2020, RidgeRun. All rights reserved.
|
||||
@@ -23,17 +23,32 @@
|
||||
#include "../platform/tegra/camera/camera_gpio.h"
|
||||
#include "imx390_mode_tbls.h"
|
||||
|
||||
/* imx390 sensor register address */
|
||||
#define IMX390_PGA_GAIN_SP1H 0x0024
|
||||
#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
|
||||
/* imx390 - sensor parameters */
|
||||
#define IMX390_MIN_GAIN (0)
|
||||
#define IMX390_MAX_GAIN (978)
|
||||
#define IMX390_ANALOG_GAIN_C0 (1024)
|
||||
#define IMX390_SHIFT_8_BITS (8)
|
||||
#define IMX390_MIN_COARSE_EXPOSURE (1)
|
||||
#define IMX390_MAX_COARSE_DIFF (10)
|
||||
#define IMX390_MASK_LSB_2_BITS 0x0003
|
||||
#define IMX390_MASK_LSB_8_BITS 0x00ff
|
||||
#define IMX390_MIN_FRAME_LENGTH (3092)
|
||||
#define IMX390_MAX_FRAME_LENGTH (0x1FFFF)
|
||||
|
||||
#define IMX390_DEFAULT_FRAME_LENGTH (1250)
|
||||
/* imx390 sensor register address */
|
||||
#define IMX390_MODEL_ID_ADDR_MSB 0x0000
|
||||
#define IMX390_MODEL_ID_ADDR_LSB 0x0001
|
||||
#define IMX390_ANALOG_GAIN_ADDR_MSB 0x0204
|
||||
#define IMX390_ANALOG_GAIN_ADDR_LSB 0x0205
|
||||
#define IMX390_DIGITAL_GAIN_ADDR_MSB 0x020e
|
||||
#define IMX390_DIGITAL_GAIN_ADDR_LSB 0x020f
|
||||
#define IMX390_FRAME_LENGTH_ADDR_MSB 0x0340
|
||||
#define IMX390_FRAME_LENGTH_ADDR_LSB 0x0341
|
||||
#define IMX390_COARSE_INTEG_TIME_ADDR_MSB 0x0202
|
||||
#define IMX390_COARSE_INTEG_TIME_ADDR_LSB 0x0203
|
||||
#define IMX390_FINE_INTEG_TIME_ADDR_MSB 0x0200
|
||||
#define IMX390_FINE_INTEG_TIME_ADDR_LSB 0x0201
|
||||
#define IMX390_GROUP_HOLD_ADDR 0x0104
|
||||
|
||||
static const struct of_device_id imx390_of_match[] = {
|
||||
{.compatible = "sony,imx390",},
|
||||
@@ -44,7 +59,6 @@ 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,
|
||||
TEGRA_CAMERA_CID_SENSOR_MODE_ID,
|
||||
@@ -65,38 +79,31 @@ static const struct regmap_config sensor_regmap_config = {
|
||||
.cache_type = REGCACHE_NONE,
|
||||
};
|
||||
|
||||
static inline void imx390_get_coarse_time_regs_shs1(imx390_reg *regs,
|
||||
u32 coarse_time)
|
||||
static inline void imx390_get_frame_length_regs(imx390_reg *regs,
|
||||
u32 frame_length)
|
||||
{
|
||||
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;
|
||||
regs->addr = IMX390_FRAME_LENGTH_ADDR_MSB;
|
||||
regs->val = (frame_length >> 8) & 0xff;
|
||||
(regs + 1)->addr = IMX390_FRAME_LENGTH_ADDR_LSB;
|
||||
(regs + 1)->val = (frame_length) & 0xff;
|
||||
}
|
||||
|
||||
static inline void imx390_get_coarse_time_regs_shs2(imx390_reg *regs,
|
||||
u32 coarse_time)
|
||||
static inline void imx390_get_coarse_integ_time_regs(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;
|
||||
regs->addr = IMX390_COARSE_INTEG_TIME_ADDR_MSB;
|
||||
regs->val = (coarse_time >> 8) & 0xff;
|
||||
(regs + 1)->addr = IMX390_COARSE_INTEG_TIME_ADDR_LSB;
|
||||
(regs + 1)->val = (coarse_time) & 0xff;
|
||||
}
|
||||
|
||||
static inline void imx390_get_gain_reg(imx390_reg *regs, u16 gain)
|
||||
static inline void imx390_get_gain_reg(imx390_reg *reg, u16 gain)
|
||||
{
|
||||
regs->addr = IMX390_PGA_GAIN_SP1H + 1;
|
||||
regs->val = (gain >> 8) & 0x03;
|
||||
(regs + 1)->addr = IMX390_PGA_GAIN_SP1H;
|
||||
(regs + 1)->val = gain & 0xff;
|
||||
reg->addr = IMX390_ANALOG_GAIN_ADDR_MSB;
|
||||
reg->val = (gain >> IMX390_SHIFT_8_BITS) & IMX390_MASK_LSB_2_BITS;
|
||||
|
||||
(reg + 1)->addr = IMX390_ANALOG_GAIN_ADDR_LSB;
|
||||
(reg + 1)->val = (gain) & IMX390_MASK_LSB_8_BITS;
|
||||
}
|
||||
|
||||
static inline int imx390_read_reg(struct camera_common_data *s_data,
|
||||
@@ -118,7 +125,7 @@ static inline int imx390_write_reg(struct camera_common_data *s_data,
|
||||
|
||||
err = regmap_write(s_data->regmap, addr, val);
|
||||
if (err)
|
||||
dev_err(s_data->dev, "%s: i2c write failed, 0x%x = %x\n",
|
||||
dev_err(s_data->dev, "%s: i2c write failed, 0x%x = %x",
|
||||
__func__, addr, val);
|
||||
|
||||
return err;
|
||||
@@ -162,146 +169,25 @@ static int imx390_write_table(struct imx390 *priv, const imx390_reg table[])
|
||||
|
||||
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[2];
|
||||
int err, i;
|
||||
u16 gain;
|
||||
|
||||
gain = (u16)(val / mode->control_properties.step_gain_val);
|
||||
|
||||
dev_dbg(dev, "%s: val: %lld db: %d\n", __func__, val, gain);
|
||||
|
||||
imx390_get_gain_reg(reg_list, gain);
|
||||
for (i = 0; i < 2; 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);
|
||||
struct imx390 *priv = (struct imx390 *)tc_dev->priv;
|
||||
|
||||
priv->frame_length = IMX390_DEFAULT_FRAME_LENGTH;
|
||||
priv->frame_length = IMX390_MIN_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;
|
||||
|
||||
/* 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 to 3 are prohibited */
|
||||
if (shs1 < 4)
|
||||
shs1 = 4;
|
||||
/* over VMAX-5 is prohibited */
|
||||
if (shs1 > priv->frame_length - 5)
|
||||
shs1 = priv->frame_length - 5;
|
||||
|
||||
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;
|
||||
}
|
||||
|
||||
dev_dbg(tc_dev->dev, "%s: val=%lld shs1=%u coarse_time=%u frame_len=%u\n",
|
||||
__func__, val, shs1, coarse_time, priv->frame_length);
|
||||
|
||||
return 0;
|
||||
fail:
|
||||
dev_dbg(&priv->i2c_client->dev,
|
||||
"%s: set coarse time error\n", __func__);
|
||||
return err;
|
||||
}
|
||||
|
||||
static int imx390_set_exposure_short(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;
|
||||
|
||||
/* 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 to 3 are prohibited */
|
||||
if (shs1 < 4)
|
||||
shs1 = 4;
|
||||
/* over VMAX-5 is prohibited */
|
||||
if (shs1 > priv->frame_length - 5)
|
||||
shs1 = priv->frame_length - 5;
|
||||
|
||||
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 = {
|
||||
@@ -309,7 +195,6 @@ static struct tegracam_ctrl_ops imx390_ctrl_ops = {
|
||||
.ctrl_cid_list = ctrl_cid_list,
|
||||
.set_gain = imx390_set_gain,
|
||||
.set_exposure = imx390_set_exposure,
|
||||
.set_exposure_short = imx390_set_exposure_short,
|
||||
.set_frame_rate = imx390_set_frame_rate,
|
||||
.set_group_hold = imx390_set_group_hold,
|
||||
};
|
||||
@@ -322,7 +207,6 @@ static int imx390_power_on(struct camera_common_data *s_data)
|
||||
struct device *dev = s_data->dev;
|
||||
|
||||
dev_err(dev, "%s: power on\n", __func__);
|
||||
|
||||
if (pdata && pdata->power_on) {
|
||||
err = pdata->power_on(pw);
|
||||
if (err)
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
// SPDX-License-Identifier: GPL-2.0-only
|
||||
// SPDX-FileCopyrightText: Copyright (c) 2021-2025, NVIDIA CORPORATION & AFFILIATES. All rights reserved.
|
||||
// SPDX-FileCopyrightText: Copyright (c) 2021-2024, NVIDIA CORPORATION & AFFILIATES. All rights reserved.
|
||||
/*
|
||||
* Copyright (c) 2020, RidgeRun. All rights reserved.
|
||||
*
|
||||
@@ -42,6 +42,11 @@ static const u32 ctrl_cid_list[] = {
|
||||
TEGRA_CAMERA_CID_SENSOR_MODE_ID,
|
||||
};
|
||||
|
||||
enum imx477_Config {
|
||||
TWO_LANE_CONFIG,
|
||||
FOUR_LANE_CONFIG,
|
||||
};
|
||||
|
||||
struct imx477 {
|
||||
struct i2c_client *i2c_client;
|
||||
struct v4l2_subdev *subdev;
|
||||
@@ -49,6 +54,7 @@ struct imx477 {
|
||||
u32 frame_length;
|
||||
struct camera_common_data *s_data;
|
||||
struct tegracam_device *tc_dev;
|
||||
enum imx477_Config config;
|
||||
};
|
||||
|
||||
static const struct regmap_config sensor_regmap_config = {
|
||||
@@ -594,14 +600,30 @@ static int imx477_set_mode(struct tegracam_device *tc_dev)
|
||||
struct camera_common_data *s_data = tc_dev->s_data;
|
||||
unsigned int mode_index = 0;
|
||||
int err = 0;
|
||||
const char *config;
|
||||
struct device_node *mode;
|
||||
uint offset = ARRAY_SIZE(imx477_frmfmt);
|
||||
|
||||
dev_dbg(tc_dev->dev, "%s:\n", __func__);
|
||||
mode = of_get_child_by_name(tc_dev->dev->of_node, "mode0");
|
||||
err = of_property_read_string(mode, "num_lanes", &config);
|
||||
|
||||
if (config[0] == '4')
|
||||
priv->config = FOUR_LANE_CONFIG;
|
||||
else if (config[0] == '2')
|
||||
priv->config = TWO_LANE_CONFIG;
|
||||
else
|
||||
dev_err(tc_dev->dev, "Unsupported config\n");
|
||||
|
||||
err = imx477_write_table(priv, mode_table[IMX477_MODE_COMMON]);
|
||||
if (err)
|
||||
return err;
|
||||
|
||||
mode_index = s_data->mode;
|
||||
err = imx477_write_table(priv, mode_table[mode_index]);
|
||||
if (priv->config == FOUR_LANE_CONFIG)
|
||||
err = imx477_write_table(priv, mode_table[mode_index + offset]);
|
||||
else
|
||||
err = imx477_write_table(priv, mode_table[mode_index]);
|
||||
|
||||
if (err)
|
||||
return err;
|
||||
|
||||
@@ -15,10 +15,7 @@
|
||||
#include <linux/version.h>
|
||||
|
||||
#define DESER_A (0)
|
||||
#define ENABLE_CC1 (0xFE)
|
||||
#define ENABLE_CC2 (0xFB)
|
||||
#define ENABLE_CC3 (0xEF)
|
||||
#define ENABLE_CC4 (0xBF)
|
||||
#define ENABLE_IMU (0xFE)
|
||||
#define ENABLE_ALL_CC (0xAA)
|
||||
#define DESER_ADDR (0x52)
|
||||
#define DESER_CC_REG (0x0003)
|
||||
@@ -30,31 +27,10 @@ static int virtual_i2c_mux_select(struct i2c_mux_core *muxc, u32 chan)
|
||||
int ret = 0;
|
||||
|
||||
/* Do select 1st channel, to access IMUs from 1st Hawk */
|
||||
switch (chan) {
|
||||
case 0:
|
||||
ret = max96712_write_reg_Dser(DESER_ADDR, DESER_A, DESER_CC_REG, ENABLE_CC1);
|
||||
if (ret)
|
||||
pr_err("%s: Failed to do i2c address trans for CC1\n", __func__);
|
||||
break;
|
||||
case 1:
|
||||
ret = max96712_write_reg_Dser(DESER_ADDR, DESER_A, DESER_CC_REG, ENABLE_CC2);
|
||||
if (ret)
|
||||
pr_err("%s: Failed to do i2c address trans for CC2\n", __func__);
|
||||
break;
|
||||
case 2:
|
||||
ret = max96712_write_reg_Dser(DESER_ADDR, DESER_A, DESER_CC_REG, ENABLE_CC3);
|
||||
if (ret)
|
||||
pr_err("%s: Failed to do i2c address trans for CC3\n", __func__);
|
||||
break;
|
||||
case 3:
|
||||
ret = max96712_write_reg_Dser(DESER_ADDR, DESER_A, DESER_CC_REG, ENABLE_CC4);
|
||||
if (ret)
|
||||
pr_err("%s: Failed to do i2c address trans for CC4\n", __func__);
|
||||
break;
|
||||
default:
|
||||
pr_err("%s: No channels matched chan = %d\n", __func__, chan);
|
||||
ret = -EINVAL;
|
||||
break;
|
||||
if (!chan) {
|
||||
ret = max96712_write_reg_Dser(DESER_ADDR, DESER_A, DESER_CC_REG, ENABLE_IMU);
|
||||
if (ret)
|
||||
pr_err("%s: Failed to do i2c address trans for IMUs\n",__func__);
|
||||
|
||||
}
|
||||
return ret;
|
||||
@@ -65,10 +41,11 @@ static int virtual_i2c_mux_deselect(struct i2c_mux_core *muxc, u32 chan)
|
||||
int ret = 0;
|
||||
|
||||
/* Enable all control channels */
|
||||
ret = max96712_write_reg_Dser(DESER_ADDR, DESER_A, DESER_CC_REG, ENABLE_ALL_CC);
|
||||
if (ret)
|
||||
pr_err("%s: Failed to do i2c address trans for IMUs\n",__func__);
|
||||
|
||||
if (!chan) {
|
||||
ret = max96712_write_reg_Dser(DESER_ADDR, DESER_A, DESER_CC_REG, ENABLE_ALL_CC);
|
||||
if (ret)
|
||||
pr_err("%s: Failed to do i2c address trans for IMUs\n",__func__);
|
||||
}
|
||||
return ret;
|
||||
}
|
||||
|
||||
|
||||
@@ -1,5 +1,7 @@
|
||||
// SPDX-License-Identifier: GPL-2.0-only
|
||||
// SPDX-FileCopyrightText: Copyright (c) 2022-2025 NVIDIA CORPORATION & AFFILIATES. All rights reserved.
|
||||
/*
|
||||
* Copyright (c) 2022-2023, NVIDIA CORPORATION. All rights reserved.
|
||||
*/
|
||||
|
||||
#include <nvidia/conftest.h>
|
||||
|
||||
@@ -1123,18 +1125,6 @@ MODULE_DEVICE_TABLE(of, cam_fsync_of_match);
|
||||
|
||||
static SIMPLE_DEV_PM_OPS(cam_fsync_pm, cam_fsync_suspend, cam_fsync_resume);
|
||||
|
||||
#if defined(NV_PLATFORM_DRIVER_STRUCT_REMOVE_RETURNS_VOID) /* Linux v6.11 */
|
||||
static void cam_fsync_remove_wrapper(struct platform_device *pdev)
|
||||
{
|
||||
cam_fsync_remove(pdev);
|
||||
}
|
||||
#else
|
||||
static int cam_fsync_remove_wrapper(struct platform_device *pdev)
|
||||
{
|
||||
return cam_fsync_remove(pdev);
|
||||
}
|
||||
#endif
|
||||
|
||||
static struct platform_driver cam_fsync_driver = {
|
||||
.driver = {
|
||||
.name = "cam_fsync",
|
||||
@@ -1143,7 +1133,7 @@ static struct platform_driver cam_fsync_driver = {
|
||||
.pm = &cam_fsync_pm,
|
||||
},
|
||||
.probe = cam_fsync_probe,
|
||||
.remove = cam_fsync_remove_wrapper,
|
||||
.remove = cam_fsync_remove,
|
||||
};
|
||||
module_platform_driver(cam_fsync_driver);
|
||||
|
||||
|
||||
@@ -1,8 +1,19 @@
|
||||
// SPDX-License-Identifier: GPL-2.0-only
|
||||
// SPDX-FileCopyrightText: Copyright (c) 2015-2025 NVIDIA CORPORATION & AFFILIATES. All rights reserved.
|
||||
|
||||
#include <nvidia/conftest.h>
|
||||
|
||||
// SPDX-License-Identifier: GPL-2.0 only
|
||||
/* SPDX-FileCopyrightText: Copyright (c) 2015-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.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
#include <linux/types.h>
|
||||
#include <media/tegra-v4l2-camera.h>
|
||||
#include <media/camera_common.h>
|
||||
@@ -28,26 +39,6 @@
|
||||
#define HDR_ENABLE 0x1
|
||||
|
||||
static const struct camera_common_colorfmt camera_common_color_fmts[] = {
|
||||
{
|
||||
MEDIA_BUS_FMT_SBGGR14_1X14,
|
||||
V4L2_COLORSPACE_SRGB,
|
||||
V4L2_PIX_FMT_SBGGR14,
|
||||
},
|
||||
{
|
||||
MEDIA_BUS_FMT_SRGGB14_1X14,
|
||||
V4L2_COLORSPACE_SRGB,
|
||||
V4L2_PIX_FMT_SRGGB14,
|
||||
},
|
||||
{
|
||||
MEDIA_BUS_FMT_SGRBG14_1X14,
|
||||
V4L2_COLORSPACE_SRGB,
|
||||
V4L2_PIX_FMT_SGRBG14,
|
||||
},
|
||||
{
|
||||
MEDIA_BUS_FMT_SGBRG14_1X14,
|
||||
V4L2_COLORSPACE_SRGB,
|
||||
V4L2_PIX_FMT_SGBRG14
|
||||
},
|
||||
{
|
||||
MEDIA_BUS_FMT_SRGGB12_1X12,
|
||||
V4L2_COLORSPACE_SRGB,
|
||||
@@ -975,12 +966,12 @@ int camera_common_get_mbus_config(struct v4l2_subdev *sd,
|
||||
* then return an error
|
||||
*/
|
||||
cfg->type = V4L2_MBUS_CSI2_DPHY;
|
||||
#if defined(NV_V4L2_FWNODE_ENDPOINT_STRUCT_HAS_V4L2_MBUS_CONFIG_MIPI_CSI2) /* Linux v5.18 */
|
||||
cfg->bus.mipi_csi2.num_data_lanes = 4;
|
||||
#else
|
||||
#if LINUX_VERSION_CODE < KERNEL_VERSION(5, 18, 0)
|
||||
cfg->flags = V4L2_MBUS_CSI2_4_LANE |
|
||||
V4L2_MBUS_CSI2_CHANNEL_0 |
|
||||
V4L2_MBUS_CSI2_CONTINUOUS_CLOCK;
|
||||
#else
|
||||
cfg->bus.mipi_csi2.num_data_lanes = 4;
|
||||
#endif
|
||||
|
||||
return 0;
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
// 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-isp-channel.c
|
||||
@@ -523,9 +523,7 @@ static long isp_channel_ioctl(
|
||||
|
||||
static const struct file_operations isp_channel_fops = {
|
||||
.owner = THIS_MODULE,
|
||||
#if defined(NV_NO_LLSEEK_PRESENT)
|
||||
.llseek = no_llseek,
|
||||
#endif
|
||||
.unlocked_ioctl = isp_channel_ioctl,
|
||||
#ifdef CONFIG_COMPAT
|
||||
.compat_ioctl = isp_channel_ioctl,
|
||||
|
||||
@@ -616,9 +616,7 @@ static long vi_channel_ioctl(
|
||||
|
||||
static const struct file_operations vi_channel_fops = {
|
||||
.owner = THIS_MODULE,
|
||||
#if defined(NV_NO_LLSEEK_PRESENT)
|
||||
.llseek = no_llseek,
|
||||
#endif
|
||||
.unlocked_ioctl = vi_channel_ioctl,
|
||||
#ifdef CONFIG_COMPAT
|
||||
.compat_ioctl = vi_channel_ioctl,
|
||||
|
||||
@@ -1,5 +1,17 @@
|
||||
// SPDX-License-Identifier: GPL-2.0-only
|
||||
// SPDX-FileCopyrightText: Copyright (c) 2017-2025 NVIDIA CORPORATION & AFFILIATES. All rights reserved.
|
||||
/* 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.
|
||||
*/
|
||||
|
||||
/**
|
||||
* @file drivers/media/platform/tegra/camera/fusa-capture/capture-vi.c
|
||||
@@ -7,8 +19,6 @@
|
||||
* @brief VI channel operations for the T234 Camera RTCPU platform.
|
||||
*/
|
||||
|
||||
#include <nvidia/conftest.h>
|
||||
|
||||
#include <linux/completion.h>
|
||||
#include <linux/nospec.h>
|
||||
#include <linux/nvhost.h>
|
||||
@@ -1716,21 +1726,9 @@ static const struct of_device_id capture_vi_of_match[] = {
|
||||
};
|
||||
MODULE_DEVICE_TABLE(of, capture_vi_of_match);
|
||||
|
||||
#if defined(NV_PLATFORM_DRIVER_STRUCT_REMOVE_RETURNS_VOID) /* Linux v6.11 */
|
||||
static void capture_vi_remove_wrapper(struct platform_device *pdev)
|
||||
{
|
||||
capture_vi_remove(pdev);
|
||||
}
|
||||
#else
|
||||
static int capture_vi_remove_wrapper(struct platform_device *pdev)
|
||||
{
|
||||
return capture_vi_remove(pdev);
|
||||
}
|
||||
#endif
|
||||
|
||||
static struct platform_driver capture_vi_driver = {
|
||||
.probe = capture_vi_probe,
|
||||
.remove = capture_vi_remove_wrapper,
|
||||
.remove = capture_vi_remove,
|
||||
.driver = {
|
||||
.owner = THIS_MODULE,
|
||||
.name = "tegra-camrtc-capture-vi",
|
||||
@@ -1762,10 +1760,6 @@ static void __exit capture_vi_exit(void)
|
||||
module_init(capture_vi_init);
|
||||
module_exit(capture_vi_exit);
|
||||
|
||||
#if defined(NV_MODULE_IMPORT_NS_CALLS_STRINGIFY)
|
||||
MODULE_IMPORT_NS(DMA_BUF);
|
||||
#else
|
||||
MODULE_IMPORT_NS("DMA_BUF");
|
||||
#endif
|
||||
MODULE_DESCRIPTION("tegra fusa-capture driver");
|
||||
MODULE_LICENSE("GPL");
|
||||
|
||||
@@ -1,19 +1,8 @@
|
||||
// SPDX-License-Identifier: GPL-2.0-only
|
||||
/*
|
||||
* SPDX-FileCopyrightText: Copyright (c) 2017-2024 NVIDIA CORPORATION & AFFILIATES.
|
||||
* All rights reserved.
|
||||
* sensor_common.c - utilities for tegra sensor drivers
|
||||
*
|
||||
* 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) 2017-2023, NVIDIA CORPORATION & AFFILIATES. All rights reserved.
|
||||
*/
|
||||
|
||||
#include <media/sensor_common.h>
|
||||
@@ -254,14 +243,6 @@ static int extract_pixel_format(
|
||||
*format = V4L2_PIX_FMT_SGBRG12;
|
||||
else if (strncmp(pixel_t, "bayer_grbg12", size) == 0)
|
||||
*format = V4L2_PIX_FMT_SGRBG12;
|
||||
else if (strncmp(pixel_t, "bayer_bggr14", size) == 0)
|
||||
*format = V4L2_PIX_FMT_SBGGR14;
|
||||
else if (strncmp(pixel_t, "bayer_rggb14", size) == 0)
|
||||
*format = V4L2_PIX_FMT_SRGGB14;
|
||||
else if (strncmp(pixel_t, "bayer_gbrg14", size) == 0)
|
||||
*format = V4L2_PIX_FMT_SGBRG14;
|
||||
else if (strncmp(pixel_t, "bayer_grbg14", size) == 0)
|
||||
*format = V4L2_PIX_FMT_SGRBG14;
|
||||
else if (strncmp(pixel_t, "rgb_rgb88824", size) == 0)
|
||||
*format = V4L2_PIX_FMT_RGB24;
|
||||
else if (strncmp(pixel_t, "bayer_wdr_pwl_rggb12", size) == 0)
|
||||
@@ -272,16 +253,6 @@ static int extract_pixel_format(
|
||||
*format = V4L2_PIX_FMT_SGRBG12;
|
||||
else if (strncmp(pixel_t, "bayer_wdr_dol_rggb10", size) == 0)
|
||||
*format = V4L2_PIX_FMT_SRGGB10;
|
||||
else if (strncmp(pixel_t, "bayer_wdr_dol_gbrg10", size) == 0)
|
||||
*format = V4L2_PIX_FMT_SGBRG10;
|
||||
else if (strncmp(pixel_t, "bayer_wdr_dol_grbg10", size) == 0)
|
||||
*format = V4L2_PIX_FMT_SGRBG10;
|
||||
else if (strncmp(pixel_t, "bayer_wdr_dol_rggb12", size) == 0)
|
||||
*format = V4L2_PIX_FMT_SRGGB12;
|
||||
else if (strncmp(pixel_t, "bayer_wdr_dol_gbrg12", size) == 0)
|
||||
*format = V4L2_PIX_FMT_SGBRG12;
|
||||
else if (strncmp(pixel_t, "bayer_wdr_dol_grbg12", size) == 0)
|
||||
*format = V4L2_PIX_FMT_SGRBG12;
|
||||
#if 0 /* disable for Canonical kenrel */
|
||||
else if (strncmp(pixel_t, "bayer_xbggr10p", size) == 0)
|
||||
*format = V4L2_PIX_FMT_XBGGR10P;
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
// SPDX-License-Identifier: GPL-2.0-only
|
||||
// SPDX-FileCopyrightText: Copyright (c) 2015-2025 NVIDIA CORPORATION & AFFILIATES. All rights reserved.
|
||||
// SPDX-FileCopyrightText: Copyright (c) 2015-2024 NVIDIA CORPORATION & AFFILIATES. All rights reserved.
|
||||
/*
|
||||
* NVIDIA Tegra Video Input Device
|
||||
*/
|
||||
@@ -471,7 +471,6 @@ void tegra_channel_init_ring_buffer(struct tegra_channel *chan)
|
||||
chan->capture_descr_index = 0;
|
||||
chan->capture_descr_sequence = 0;
|
||||
chan->queue_error = false;
|
||||
chan->capture_reqs_enqueued = 0;
|
||||
}
|
||||
EXPORT_SYMBOL(tegra_channel_init_ring_buffer);
|
||||
|
||||
@@ -703,12 +702,11 @@ tegra_channel_queue_setup(struct vb2_queue *vq,
|
||||
* 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.
|
||||
* Printing this error as info, to avoid kernel error/warning failure.
|
||||
*/
|
||||
if (*nplanes) {
|
||||
if (sizes[0] < chan->format.sizeimage) {
|
||||
pr_info("%s: sizes[0] = %d, chan->format.sizeimage = %d, for num_planes = %d ...\n"
|
||||
, __func__, sizes[0], chan->format.sizeimage, *nplanes);
|
||||
pr_err("%s: sizes[0] = %d chan->format.sizeimage = %d ...\n"
|
||||
,__func__,sizes[0],chan->format.sizeimage);
|
||||
return -EINVAL;
|
||||
}
|
||||
} else {
|
||||
@@ -1019,7 +1017,6 @@ static void tegra_channel_stop_streaming(struct vb2_queue *vq)
|
||||
|
||||
if (vi->fops) {
|
||||
vi->fops->vi_stop_streaming(vq);
|
||||
atomic_set(&chan->is_streaming, DISABLE);
|
||||
vi->fops->vi_power_off(chan);
|
||||
}
|
||||
|
||||
@@ -1948,7 +1945,7 @@ int tegra_channel_init_subdevices(struct tegra_channel *chan)
|
||||
int len = 0;
|
||||
|
||||
/* set_stream of CSI */
|
||||
#if defined(NV_MEDIA_ENTITY_REMOTE_PAD_PRESENT) /* Linux 6.0 */
|
||||
#if LINUX_VERSION_CODE < KERNEL_VERSION(6, 0, 0)
|
||||
pad = media_entity_remote_pad(&chan->pad);
|
||||
#else
|
||||
pad = media_pad_remote_pad_first(&chan->pad);
|
||||
@@ -1978,7 +1975,7 @@ int tegra_channel_init_subdevices(struct tegra_channel *chan)
|
||||
if (!(pad->flags & MEDIA_PAD_FL_SINK))
|
||||
break;
|
||||
|
||||
#if defined(NV_MEDIA_ENTITY_REMOTE_PAD_PRESENT) /* Linux 6.0 */
|
||||
#if LINUX_VERSION_CODE < KERNEL_VERSION(6, 0, 0)
|
||||
pad = media_entity_remote_pad(pad);
|
||||
#else
|
||||
pad = media_pad_remote_pad_first(pad);
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
// SPDX-License-Identifier: GPL-2.0
|
||||
/* SPDX-FileCopyrightText: Copyright (c) 2016-2025 NVIDIA CORPORATION & AFFILIATES.
|
||||
/* SPDX-FileCopyrightText: Copyright (c) 2016-2024 NVIDIA CORPORATION & AFFILIATES.
|
||||
* All rights reserved.
|
||||
*
|
||||
* Tegra Video Input 5 device common APIs
|
||||
@@ -594,22 +594,15 @@ static void vi5_capture_dequeue(struct tegra_channel *chan,
|
||||
|
||||
uncorr_err:
|
||||
spin_lock_irqsave(&chan->capture_state_lock, flags);
|
||||
if (err == -ETIMEDOUT) {
|
||||
chan->capture_state = CAPTURE_TIMEOUT;
|
||||
buf->vb2_state = VB2_BUF_STATE_QUEUED;
|
||||
} else {
|
||||
chan->capture_state = CAPTURE_ERROR;
|
||||
buf->vb2_state = VB2_BUF_STATE_ERROR;
|
||||
}
|
||||
chan->capture_state = CAPTURE_ERROR;
|
||||
spin_unlock_irqrestore(&chan->capture_state_lock, flags);
|
||||
|
||||
buf->vb2_state = VB2_BUF_STATE_ERROR;
|
||||
|
||||
rel_buf:
|
||||
vi5_release_buffer(chan, buf);
|
||||
}
|
||||
|
||||
static void vi5_unit_get_device_handle(struct platform_device *pdev,
|
||||
uint32_t csi_stream_id, struct device **dev);
|
||||
|
||||
static int vi5_channel_error_recover(struct tegra_channel *chan,
|
||||
bool queue_error)
|
||||
{
|
||||
@@ -627,25 +620,6 @@ static int vi5_channel_error_recover(struct tegra_channel *chan,
|
||||
dev_err(&chan->video->dev, "vi capture release failed\n");
|
||||
goto done;
|
||||
}
|
||||
|
||||
/* 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;
|
||||
@@ -663,10 +637,7 @@ static int vi5_channel_error_recover(struct tegra_channel *chan,
|
||||
buf = dequeue_dequeue_buffer(chan);
|
||||
if (!buf)
|
||||
break;
|
||||
if (chan->capture_state == CAPTURE_TIMEOUT)
|
||||
buf->vb2_state = VB2_BUF_STATE_QUEUED;
|
||||
else
|
||||
buf->vb2_state = VB2_BUF_STATE_ERROR;
|
||||
buf->vb2_state = VB2_BUF_STATE_ERROR;
|
||||
vi5_capture_dequeue(chan, buf);
|
||||
}
|
||||
|
||||
|
||||
@@ -1,14 +1,8 @@
|
||||
/* 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-only */
|
||||
/*
|
||||
* NVIDIA Tegra Video Input Device Driver VI5 formats
|
||||
*
|
||||
* Author: Bhanu Murthy V <bmurthyv@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) 2017-2022, NVIDIA CORPORATION. All rights reserved.
|
||||
*/
|
||||
|
||||
#ifndef __VI5_FORMATS_H_
|
||||
@@ -97,16 +91,6 @@ static const struct tegra_video_format vi5_video_formats[] = {
|
||||
TEGRA_VIDEO_FORMAT(RAW8, 8, SBGGR8_1X8, 1, 1, T_R8,
|
||||
RAW8, SBGGR8, "BGBG.. GRGR.."),
|
||||
|
||||
/* RAW 14 */
|
||||
TEGRA_VIDEO_FORMAT(RAW14, 14, SRGGB14_1X14, 2, 1, T_R16,
|
||||
RAW14, SRGGB14, "RGRG.. GBGB.."),
|
||||
TEGRA_VIDEO_FORMAT(RAW14, 14, SGRBG14_1X14, 2, 1, T_R16,
|
||||
RAW14, SGRBG14, "GRGR.. BGBG.."),
|
||||
TEGRA_VIDEO_FORMAT(RAW14, 14, SGBRG14_1X14, 2, 1, T_R16,
|
||||
RAW14, SGBRG14, "GBGB.. RGRG.."),
|
||||
TEGRA_VIDEO_FORMAT(RAW14, 14, SBGGR14_1X14, 2, 1, T_R16,
|
||||
RAW14, SBGGR14, "BGBG.. GRGR.."),
|
||||
|
||||
/* RAW 10 */
|
||||
TEGRA_VIDEO_FORMAT(RAW10, 10, SRGGB10_1X10, 2, 1, T_R16,
|
||||
RAW10, SRGGB10, "RGRG.. GBGB.."),
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
// SPDX-License-Identifier: GPL-2.0-only
|
||||
// SPDX-FileCopyrightText: Copyright (c) 2023-2025 NVIDIA CORPORATION & AFFILIATES. All rights reserved.
|
||||
/* SPDX-License-Identifier: GPL-2.0 */
|
||||
/* Copyright (c) 2023-2024, NVIDIA CORPORATION & AFFILIATES. All Rights Reserved. */
|
||||
/*
|
||||
* cam_cdi_tsc.c - tsc driver.
|
||||
*/
|
||||
@@ -645,18 +645,6 @@ MODULE_DEVICE_TABLE(of, cdi_tsc_of_match);
|
||||
|
||||
static SIMPLE_DEV_PM_OPS(cdi_tsc_pm, cdi_tsc_suspend, cdi_tsc_resume);
|
||||
|
||||
#if defined(NV_PLATFORM_DRIVER_STRUCT_REMOVE_RETURNS_VOID) /* Linux v6.11 */
|
||||
static void cdi_tsc_remove_wrapper(struct platform_device *pdev)
|
||||
{
|
||||
cdi_tsc_remove(pdev);
|
||||
}
|
||||
#else
|
||||
static int cdi_tsc_remove_wrapper(struct platform_device *pdev)
|
||||
{
|
||||
return cdi_tsc_remove(pdev);
|
||||
}
|
||||
#endif
|
||||
|
||||
static struct platform_driver cdi_tsc_driver = {
|
||||
.driver = {
|
||||
.name = "cdi_tsc",
|
||||
@@ -665,7 +653,7 @@ static struct platform_driver cdi_tsc_driver = {
|
||||
.pm = &cdi_tsc_pm,
|
||||
},
|
||||
.probe = cdi_tsc_probe,
|
||||
.remove = cdi_tsc_remove_wrapper,
|
||||
.remove = cdi_tsc_remove,
|
||||
};
|
||||
module_platform_driver(cdi_tsc_driver);
|
||||
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
// SPDX-License-Identifier: GPL-2.0-only
|
||||
// SPDX-FileCopyrightText: Copyright (c) 2017-2025 NVIDIA CORPORATION & AFFILIATES. All rights reserved.
|
||||
// SPDX-FileCopyrightText: Copyright (c) 2017-2024 NVIDIA CORPORATION & AFFILIATES. All rights reserved.
|
||||
|
||||
#include <nvidia/conftest.h>
|
||||
|
||||
@@ -330,21 +330,9 @@ static const struct of_device_id cdi_gpio_dt_ids[] = {
|
||||
};
|
||||
MODULE_DEVICE_TABLE(of, cdi_gpio_dt_ids);
|
||||
|
||||
#if defined(NV_PLATFORM_DRIVER_STRUCT_REMOVE_RETURNS_VOID) /* Linux v6.11 */
|
||||
static void cdi_gpio_remove_wrapper(struct platform_device *pdev)
|
||||
{
|
||||
cdi_gpio_remove(pdev);
|
||||
}
|
||||
#else
|
||||
static int cdi_gpio_remove_wrapper(struct platform_device *pdev)
|
||||
{
|
||||
return cdi_gpio_remove(pdev);
|
||||
}
|
||||
#endif
|
||||
|
||||
static struct platform_driver cdi_gpio_driver = {
|
||||
.probe = cdi_gpio_probe,
|
||||
.remove = cdi_gpio_remove_wrapper,
|
||||
.remove = cdi_gpio_remove,
|
||||
.driver = {
|
||||
.name = "cdi-gpio",
|
||||
.of_match_table = cdi_gpio_dt_ids,
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
// SPDX-License-Identifier: GPL-2.0-only
|
||||
// SPDX-FileCopyrightText: Copyright (c) 2015-2025 NVIDIA CORPORATION & AFFILIATES. All rights reserved.
|
||||
// SPDX-License-Identifier: GPL-2.0
|
||||
// Copyright (c) 2015-2023, NVIDIA CORPORATION & AFFILIATES. All rights reserved.
|
||||
|
||||
#include <nvidia/conftest.h>
|
||||
|
||||
@@ -1776,14 +1776,9 @@ static int cdi_mgr_probe(struct platform_device *pdev)
|
||||
for (i = 0; i < ARRAY_SIZE(cdi_mgr->gpios); i++) {
|
||||
pin = &cdi_mgr->gpios[i];
|
||||
pin->mgr = cdi_mgr;
|
||||
#if defined(NV_HRTIMER_SETUP_PRESENT) /* Linux v6.13 */
|
||||
hrtimer_setup(&pin->timers.timer, &cdi_mgr_intr_timer,
|
||||
CLOCK_MONOTONIC, HRTIMER_MODE_ABS);
|
||||
#else
|
||||
hrtimer_init(&pin->timers.timer, CLOCK_MONOTONIC,
|
||||
HRTIMER_MODE_ABS);
|
||||
pin->timers.timer.function = &cdi_mgr_intr_timer;
|
||||
#endif
|
||||
}
|
||||
|
||||
if (pdev->dev.of_node) {
|
||||
@@ -2089,18 +2084,6 @@ static const struct of_device_id cdi_mgr_of_match[] = {
|
||||
};
|
||||
MODULE_DEVICE_TABLE(of, cdi_mgr_of_match);
|
||||
|
||||
#if defined(NV_PLATFORM_DRIVER_STRUCT_REMOVE_RETURNS_VOID) /* Linux v6.11 */
|
||||
static void cdi_mgr_remove_wrapper(struct platform_device *pdev)
|
||||
{
|
||||
cdi_mgr_remove(pdev);
|
||||
}
|
||||
#else
|
||||
static int cdi_mgr_remove_wrapper(struct platform_device *pdev)
|
||||
{
|
||||
return cdi_mgr_remove(pdev);
|
||||
}
|
||||
#endif
|
||||
|
||||
static struct platform_driver cdi_mgr_driver = {
|
||||
.driver = {
|
||||
.name = "cdi-mgr",
|
||||
@@ -2109,7 +2092,7 @@ static struct platform_driver cdi_mgr_driver = {
|
||||
.pm = &cdi_mgr_pm_ops,
|
||||
},
|
||||
.probe = cdi_mgr_probe,
|
||||
.remove = cdi_mgr_remove_wrapper,
|
||||
.remove = cdi_mgr_remove,
|
||||
};
|
||||
|
||||
module_platform_driver(cdi_mgr_driver);
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
// SPDX-License-Identifier: GPL-2.0-only
|
||||
// SPDX-FileCopyrightText: Copyright (c) 2016-2025 NVIDIA CORPORATION & AFFILIATES. All rights reserved.
|
||||
// SPDX-FileCopyrightText: Copyright (c) 2016-2024 NVIDIA CORPORATION & AFFILIATES. All rights reserved.
|
||||
|
||||
#include <nvidia/conftest.h>
|
||||
|
||||
@@ -254,18 +254,6 @@ static const struct dev_pm_ops cdi_pwm_pm_ops = {
|
||||
.runtime_resume = cdi_pwm_resume,
|
||||
};
|
||||
|
||||
#if defined(NV_PLATFORM_DRIVER_STRUCT_REMOVE_RETURNS_VOID) /* Linux v6.11 */
|
||||
static void cdi_pwm_remove_wrapper(struct platform_device *pdev)
|
||||
{
|
||||
cdi_pwm_remove(pdev);
|
||||
}
|
||||
#else
|
||||
static int cdi_pwm_remove_wrapper(struct platform_device *pdev)
|
||||
{
|
||||
return cdi_pwm_remove(pdev);
|
||||
}
|
||||
#endif
|
||||
|
||||
static struct platform_driver cdi_pwm_driver = {
|
||||
.driver = {
|
||||
.name = "cdi-pwm",
|
||||
@@ -274,7 +262,7 @@ static struct platform_driver cdi_pwm_driver = {
|
||||
.pm = &cdi_pwm_pm_ops,
|
||||
},
|
||||
.probe = cdi_pwm_probe,
|
||||
.remove = cdi_pwm_remove_wrapper,
|
||||
.remove = cdi_pwm_remove,
|
||||
};
|
||||
|
||||
module_platform_driver(cdi_pwm_driver);
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
// SPDX-License-Identifier: GPL-2.0-only
|
||||
// SPDX-FileCopyrightText: Copyright (c) 2017-2025 NVIDIA CORPORATION & AFFILIATES. All rights reserved.
|
||||
// SPDX-FileCopyrightText: Copyright (c) 2017-2024 NVIDIA CORPORATION & AFFILIATES. All rights reserved.
|
||||
|
||||
#include <nvidia/conftest.h>
|
||||
|
||||
@@ -330,21 +330,9 @@ static const struct of_device_id isc_gpio_dt_ids[] = {
|
||||
};
|
||||
MODULE_DEVICE_TABLE(of, isc_gpio_dt_ids);
|
||||
|
||||
#if defined(NV_PLATFORM_DRIVER_STRUCT_REMOVE_RETURNS_VOID) /* Linux v6.11 */
|
||||
static void isc_gpio_remove_wrapper(struct platform_device *pdev)
|
||||
{
|
||||
isc_gpio_remove(pdev);
|
||||
}
|
||||
#else
|
||||
static int isc_gpio_remove_wrapper(struct platform_device *pdev)
|
||||
{
|
||||
return isc_gpio_remove(pdev);
|
||||
}
|
||||
#endif
|
||||
|
||||
static struct platform_driver isc_gpio_driver = {
|
||||
.probe = isc_gpio_probe,
|
||||
.remove = isc_gpio_remove_wrapper,
|
||||
.remove = isc_gpio_remove,
|
||||
.driver = {
|
||||
.name = "isc-gpio",
|
||||
.of_match_table = isc_gpio_dt_ids,
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
// SPDX-License-Identifier: GPL-2.0-only
|
||||
// SPDX-FileCopyrightText: Copyright (c) 2015-2025 NVIDIA CORPORATION & AFFILIATES. All rights reserved.
|
||||
// SPDX-License-Identifier: GPL-2.0
|
||||
// Copyright (c) 2015-2023, NVIDIA CORPORATION & AFFILIATES. All rights reserved.
|
||||
|
||||
#include <nvidia/conftest.h>
|
||||
|
||||
@@ -1204,18 +1204,6 @@ static const struct of_device_id isc_mgr_of_match[] = {
|
||||
};
|
||||
MODULE_DEVICE_TABLE(of, isc_mgr_of_match);
|
||||
|
||||
#if defined(NV_PLATFORM_DRIVER_STRUCT_REMOVE_RETURNS_VOID) /* Linux v6.11 */
|
||||
static void isc_mgr_remove_wrapper(struct platform_device *pdev)
|
||||
{
|
||||
isc_mgr_remove(pdev);
|
||||
}
|
||||
#else
|
||||
static int isc_mgr_remove_wrapper(struct platform_device *pdev)
|
||||
{
|
||||
return isc_mgr_remove(pdev);
|
||||
}
|
||||
#endif
|
||||
|
||||
static struct platform_driver isc_mgr_driver = {
|
||||
.driver = {
|
||||
.name = "isc-mgr",
|
||||
@@ -1224,7 +1212,7 @@ static struct platform_driver isc_mgr_driver = {
|
||||
.pm = &isc_mgr_pm_ops,
|
||||
},
|
||||
.probe = isc_mgr_probe,
|
||||
.remove = isc_mgr_remove_wrapper,
|
||||
.remove = isc_mgr_remove,
|
||||
};
|
||||
|
||||
module_platform_driver(isc_mgr_driver);
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
// SPDX-License-Identifier: GPL-2.0-only
|
||||
// SPDX-FileCopyrightText: Copyright (c) 2016-2025 NVIDIA CORPORATION & AFFILIATES. All rights reserved.
|
||||
// SPDX-License-Identifier: GPL-2.0
|
||||
// Copyright (c) 2016-2024, NVIDIA CORPORATION & AFFILIATES. All rights reserved.
|
||||
|
||||
#include <nvidia/conftest.h>
|
||||
|
||||
@@ -254,18 +254,6 @@ static const struct dev_pm_ops isc_pwm_pm_ops = {
|
||||
.runtime_resume = isc_pwm_resume,
|
||||
};
|
||||
|
||||
#if defined(NV_PLATFORM_DRIVER_STRUCT_REMOVE_RETURNS_VOID) /* Linux v6.11 */
|
||||
static void isc_pwm_remove_wrapper(struct platform_device *pdev)
|
||||
{
|
||||
isc_pwm_remove(pdev);
|
||||
}
|
||||
#else
|
||||
static int isc_pwm_remove_wrapper(struct platform_device *pdev)
|
||||
{
|
||||
return isc_pwm_remove(pdev);
|
||||
}
|
||||
#endif
|
||||
|
||||
static struct platform_driver isc_pwm_driver = {
|
||||
.driver = {
|
||||
.name = "isc-pwm",
|
||||
@@ -274,7 +262,7 @@ static struct platform_driver isc_pwm_driver = {
|
||||
.pm = &isc_pwm_pm_ops,
|
||||
},
|
||||
.probe = isc_pwm_probe,
|
||||
.remove = isc_pwm_remove_wrapper,
|
||||
.remove = isc_pwm_remove,
|
||||
};
|
||||
|
||||
module_platform_driver(isc_pwm_driver);
|
||||
|
||||
@@ -2,7 +2,7 @@
|
||||
/*
|
||||
* Voltage Regulator Specification: Power Sequencer MFD Driver
|
||||
*
|
||||
* SPDX-FileCopyrightText: Copyright (c) 2020-2025 NVIDIA CORPORATION & AFFILIATES. All rights reserved.
|
||||
* Copyright (C) 2020-2023 NVIDIA CORPORATION. All rights reserved.
|
||||
*/
|
||||
|
||||
#include <nvidia/conftest.h>
|
||||
@@ -228,14 +228,6 @@ static int nvvrs_pseq_probe(struct i2c_client *client,
|
||||
return ret;
|
||||
}
|
||||
|
||||
/* When battery mounted, the chip may have IRQ asserted. */
|
||||
/* Clear it before IRQ requested. */
|
||||
ret = nvvrs_pseq_irq_clear(nvvrs_chip);
|
||||
if (ret < 0) {
|
||||
dev_err(nvvrs_chip->dev, "Failed to clear IRQ: %d\n", ret);
|
||||
return ret;
|
||||
}
|
||||
|
||||
nvvrs_pseq_irq_chip.irq_drv_data = nvvrs_chip;
|
||||
ret = devm_regmap_add_irq_chip(nvvrs_chip->dev, nvvrs_chip->rmap, client->irq,
|
||||
IRQF_ONESHOT | IRQF_SHARED, 0,
|
||||
|
||||
@@ -17,4 +17,3 @@ endif
|
||||
obj-m += bluedroid_pm.o
|
||||
obj-m += nvscic2c-pcie/
|
||||
obj-m += ioctl_example.o
|
||||
obj-m += tegra-cec/
|
||||
|
||||
@@ -1,5 +1,7 @@
|
||||
// SPDX-License-Identifier: GPL-2.0-only
|
||||
// SPDX-FileCopyrightText: Copyright (c) 2019-2025 NVIDIA CORPORATION & AFFILIATES. All rights reserved.
|
||||
// SPDX-FileCopyrightText: Copyright (C) 2019-2023 NVIDIA CORPORATION. All rights reserved.
|
||||
|
||||
#include <nvidia/conftest.h>
|
||||
|
||||
#include <nvidia/conftest.h>
|
||||
|
||||
@@ -265,11 +267,7 @@ static ssize_t lpm_write_proc(struct file *file, const char __user *buffer,
|
||||
bluedroid_pm_gpio_set_value(
|
||||
bluedroid_pm->ext_wake, 1);
|
||||
__pm_stay_awake(&bluedroid_pm->wake_lock);
|
||||
#if defined(NV_TIMER_DELETE_PRESENT) /* Linux v6.15 */
|
||||
timer_delete(&bluedroid_pm_timer);
|
||||
#else
|
||||
del_timer(&bluedroid_pm_timer);
|
||||
#endif
|
||||
set_bit(BT_WAKE, &bluedroid_pm->flags);
|
||||
} else {
|
||||
kfree(buf);
|
||||
@@ -541,11 +539,7 @@ static int bluedroid_pm_remove(struct platform_device *pdev)
|
||||
wakeup_source_destroy(&bluedroid_pm->wake_lock);
|
||||
gpio_free(bluedroid_pm->ext_wake);
|
||||
remove_bt_proc_interface();
|
||||
#if defined(NV_TIMER_DELETE_PRESENT) /* Linux v6.15 */
|
||||
timer_delete(&bluedroid_pm_timer);
|
||||
#else
|
||||
del_timer(&bluedroid_pm_timer);
|
||||
#endif
|
||||
}
|
||||
if ((gpio_is_valid(bluedroid_pm->gpio_reset)) ||
|
||||
(gpio_is_valid(bluedroid_pm->gpio_shutdown)) ||
|
||||
@@ -633,21 +627,9 @@ static struct of_device_id bdroid_of_match[] = {
|
||||
};
|
||||
MODULE_DEVICE_TABLE(of, bdroid_of_match);
|
||||
|
||||
#if defined(NV_PLATFORM_DRIVER_STRUCT_REMOVE_RETURNS_VOID) /* Linux v6.11 */
|
||||
static void bluedroid_pm_remove_wrapper(struct platform_device *pdev)
|
||||
{
|
||||
bluedroid_pm_remove(pdev);
|
||||
}
|
||||
#else
|
||||
static int bluedroid_pm_remove_wrapper(struct platform_device *pdev)
|
||||
{
|
||||
return bluedroid_pm_remove(pdev);
|
||||
}
|
||||
#endif
|
||||
|
||||
static struct platform_driver bluedroid_pm_driver = {
|
||||
.probe = bluedroid_pm_probe,
|
||||
.remove = bluedroid_pm_remove_wrapper,
|
||||
.remove = bluedroid_pm_remove,
|
||||
.suspend = bluedroid_pm_suspend,
|
||||
.resume = bluedroid_pm_resume,
|
||||
.shutdown = bluedroid_pm_shutdown,
|
||||
|
||||
@@ -1,7 +1,5 @@
|
||||
// SPDX-License-Identifier: GPL-2.0-only
|
||||
/* SPDX-FileCopyrightText: Copyright (c) 2014-2025, NVIDIA CORPORATION. All rights reserved. */
|
||||
|
||||
#include <nvidia/conftest.h>
|
||||
/* SPDX-FileCopyrightText: Copyright (c) 2014-2023, NVIDIA CORPORATION. All rights reserved. */
|
||||
|
||||
#include <linux/dma-buf.h>
|
||||
#include <linux/module.h>
|
||||
@@ -10,11 +8,7 @@
|
||||
|
||||
#include "mods_internal.h"
|
||||
|
||||
#if defined(NV_MODULE_IMPORT_NS_CALLS_STRINGIFY)
|
||||
MODULE_IMPORT_NS(DMA_BUF);
|
||||
#else
|
||||
MODULE_IMPORT_NS("DMA_BUF");
|
||||
#endif
|
||||
|
||||
static struct device *dummy_device;
|
||||
|
||||
|
||||
@@ -171,8 +171,7 @@ allocate_outbound_area(struct pci_epf *epf, size_t win_size,
|
||||
return ret;
|
||||
}
|
||||
|
||||
#if defined(NV_PCI_EPC_EVENT_OPS_STRUCT_HAS_EPC_DEINIT) || \
|
||||
defined(NV_PCI_EPC_EVENT_OPS_STRUCT_HAS_CORE_DEINIT) /* Linux v6.11 || Nvidia Internal */
|
||||
#if defined(NV_PCI_EPC_EVENT_OPS_STRUCT_HAS_CORE_DEINIT) /* Nvidia Internal */
|
||||
static void
|
||||
clear_inbound_translation(struct pci_epf *epf)
|
||||
{
|
||||
@@ -495,8 +494,7 @@ deinit_work(struct work_struct *work)
|
||||
* @DRV_MODE_EPC would have already gone then by the time
|
||||
* struct pci_epc_event_ops.core_deinit is called.
|
||||
*/
|
||||
#if defined(NV_PCI_EPC_EVENT_OPS_STRUCT_HAS_EPC_DEINIT) || \
|
||||
defined(NV_PCI_EPC_EVENT_OPS_STRUCT_HAS_CORE_DEINIT) /* Linux v6.11 || Nvidia Internal */
|
||||
#if defined(NV_PCI_EPC_EVENT_OPS_STRUCT_HAS_CORE_DEINIT) /* Nvidia Internal */
|
||||
static int
|
||||
nvscic2c_pcie_epf_core_deinit(struct pci_epf *epf)
|
||||
{
|
||||
@@ -524,13 +522,6 @@ nvscic2c_pcie_epf_core_deinit(struct pci_epf *epf)
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
#if defined(NV_PCI_EPC_EVENT_OPS_STRUCT_HAS_EPC_DEINIT)
|
||||
static void nvscic2c_pcie_epf_epc_deinit(struct pci_epf *epf)
|
||||
{
|
||||
WARN_ON(nvscic2c_pcie_epf_core_deinit(epf));
|
||||
}
|
||||
#endif
|
||||
#endif
|
||||
|
||||
/* Handle link message from @DRV_MODE_EPC. */
|
||||
@@ -743,14 +734,8 @@ get_driverdata(const struct pci_epf_device_id *id,
|
||||
}
|
||||
|
||||
static const struct pci_epc_event_ops nvscic2c_event_ops = {
|
||||
#if defined(NV_PCI_EPC_EVENT_OPS_STRUCT_HAS_EPC_INIT) /* Linux v6.11 */
|
||||
.epc_init = nvscic2c_pcie_epf_core_init,
|
||||
#else
|
||||
.core_init = nvscic2c_pcie_epf_core_init,
|
||||
#endif
|
||||
#if defined(NV_PCI_EPC_EVENT_OPS_STRUCT_HAS_EPC_DEINIT) /* Linux v6.11 */
|
||||
.epc_deinit = nvscic2c_pcie_epf_epc_deinit,
|
||||
#elif defined(NV_PCI_EPC_EVENT_OPS_STRUCT_HAS_CORE_DEINIT) /* Nvidia Internal */
|
||||
#if defined(NV_PCI_EPC_EVENT_OPS_STRUCT_HAS_CORE_DEINIT) /* Nvidia Internal */
|
||||
.core_deinit = nvscic2c_pcie_epf_core_deinit,
|
||||
#endif
|
||||
};
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
// 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 & AFFILIATES. All rights reserved.
|
||||
|
||||
#define pr_fmt(fmt) "nvscic2c-pcie: vmap-pin: " fmt
|
||||
|
||||
@@ -380,8 +380,4 @@ err:
|
||||
return ret;
|
||||
}
|
||||
|
||||
#if defined(NV_MODULE_IMPORT_NS_CALLS_STRINGIFY)
|
||||
MODULE_IMPORT_NS(DMA_BUF);
|
||||
#else
|
||||
MODULE_IMPORT_NS("DMA_BUF");
|
||||
#endif
|
||||
|
||||
@@ -1,5 +1,7 @@
|
||||
// SPDX-License-Identifier: GPL-2.0-only
|
||||
// SPDX-FileCopyrightText: Copyright (c) 2019-2025 NVIDIA CORPORATION & AFFILIATES. All rights reserved.
|
||||
/* SPDX-License-Identifier: GPL-2.0-only */
|
||||
/*
|
||||
* SPDX-FileCopyrightText: Copyright (c) 2019-2023 NVIDIA CORPORATION & AFFILIATES. All rights reserved.
|
||||
*/
|
||||
|
||||
/*
|
||||
* This is NvSciIpc kernel driver. At present its only use is to support
|
||||
@@ -82,20 +84,11 @@ NvSciError NvSciIpcEndpointValidateAuthTokenLinuxCurrent(
|
||||
}
|
||||
|
||||
f = fdget((int)authToken);
|
||||
#if defined(NV_FD_EMPTY_PRESENT) /* Linux v6.12 */
|
||||
if (fd_empty(f)) {
|
||||
#else
|
||||
if (!f.file) {
|
||||
#endif
|
||||
ERR("invalid auth token\n");
|
||||
return NvSciError_BadParameter;
|
||||
}
|
||||
|
||||
#if defined(NV_FD_FILE_PRESENT) /* Linux v6.12 */
|
||||
filp = fd_file(f);
|
||||
#else
|
||||
filp = f.file;
|
||||
#endif
|
||||
|
||||
devlen = strlen(filp->f_path.dentry->d_name.name);
|
||||
#if DEBUG_VALIDATE_TOKEN
|
||||
@@ -685,9 +678,7 @@ static const struct file_operations nvsciipc_fops = {
|
||||
.open = nvsciipc_dev_open,
|
||||
.release = nvsciipc_dev_release,
|
||||
.unlocked_ioctl = nvsciipc_dev_ioctl,
|
||||
#if defined(NV_NO_LLSEEK_PRESENT)
|
||||
.llseek = no_llseek,
|
||||
#endif
|
||||
.read = nvsciipc_dbg_read,
|
||||
};
|
||||
|
||||
@@ -831,21 +822,9 @@ exit:
|
||||
return 0;
|
||||
}
|
||||
|
||||
#if defined(NV_PLATFORM_DRIVER_STRUCT_REMOVE_RETURNS_VOID) /* Linux v6.11 */
|
||||
static void nvsciipc_remove_wrapper(struct platform_device *pdev)
|
||||
{
|
||||
nvsciipc_remove(pdev);
|
||||
}
|
||||
#else
|
||||
static int nvsciipc_remove_wrapper(struct platform_device *pdev)
|
||||
{
|
||||
return nvsciipc_remove(pdev);
|
||||
}
|
||||
#endif
|
||||
|
||||
static struct platform_driver nvsciipc_driver = {
|
||||
.probe = nvsciipc_probe,
|
||||
.remove = nvsciipc_remove_wrapper,
|
||||
.remove = nvsciipc_remove,
|
||||
.driver = {
|
||||
.name = MODULE_NAME,
|
||||
},
|
||||
|
||||
@@ -1,5 +0,0 @@
|
||||
# SPDX-License-Identifier: GPL-2.0
|
||||
# Copyright (c) 2022-2024, NVIDIA CORPORATION. All rights reserved.
|
||||
|
||||
subdir-ccflags-y = -Werror
|
||||
obj-m += tegra_cec.o
|
||||
@@ -1,860 +0,0 @@
|
||||
// SPDX-License-Identifier: GPL-2.0-only
|
||||
// SPDX-FileCopyrightText: Copyright (c) 2019-2025 NVIDIA CORPORATION & AFFILIATES. All rights reserved.
|
||||
|
||||
#include <nvidia/conftest.h>
|
||||
|
||||
#include <linux/module.h>
|
||||
#include <linux/kernel.h>
|
||||
#include <linux/err.h>
|
||||
#include <linux/errno.h>
|
||||
#include <linux/interrupt.h>
|
||||
#include <linux/slab.h>
|
||||
#include <linux/io.h>
|
||||
#include <linux/clk.h>
|
||||
#include <linux/delay.h>
|
||||
#include <linux/workqueue.h>
|
||||
#include <linux/ktime.h>
|
||||
#include <linux/wait.h>
|
||||
#include <linux/sched.h>
|
||||
#include <linux/fs.h>
|
||||
#include <linux/uaccess.h>
|
||||
#include <linux/of_device.h>
|
||||
#include <linux/version.h>
|
||||
#include <linux/reset.h>
|
||||
|
||||
#include <linux/platform_device.h>
|
||||
#include <linux/miscdevice.h>
|
||||
#include <linux/clk/tegra.h>
|
||||
#include <linux/of.h>
|
||||
|
||||
#if defined(CONFIG_TEGRA_POWERGATE)
|
||||
#include <soc/tegra/tegra_powergate.h>
|
||||
#endif
|
||||
#include "tegra_cec.h"
|
||||
|
||||
#define LOGICAL_ADDRESS_RESERVED2 0xD
|
||||
#define LOGICAL_ADDRESS_TV 0x0
|
||||
#define LOGICAL_ADDRESS_BROADCAST 0xF
|
||||
#define TEXT_VIEW_ON 0x0D
|
||||
#define ACTIVE_SOURCE 0x82
|
||||
/*
|
||||
* 400 ms is the time it takes for one 16 byte message to be
|
||||
* transferred and 5 is the maximum number of retries. Add
|
||||
* another 100 ms as a margin.
|
||||
*/
|
||||
#define CEC_XFER_TIMEOUT_MS (5 * 400 + 100)
|
||||
|
||||
static bool post_recovery, text_view_on_sent;
|
||||
static u8 text_view_on_command[] = {
|
||||
LOGICAL_ADDRESS_RESERVED2 << 4 | LOGICAL_ADDRESS_TV,
|
||||
TEXT_VIEW_ON
|
||||
};
|
||||
static u8 active_source_command[] = {
|
||||
LOGICAL_ADDRESS_RESERVED2 << 4 | LOGICAL_ADDRESS_BROADCAST,
|
||||
ACTIVE_SOURCE,
|
||||
0x00,
|
||||
0x00
|
||||
};
|
||||
|
||||
static ssize_t cec_logical_addr_store(struct device *dev,
|
||||
struct device_attribute *attr, const char *buf, size_t count);
|
||||
|
||||
static ssize_t cec_logical_addr_show(struct device *dev,
|
||||
struct device_attribute *attr, char *buf);
|
||||
|
||||
static DEVICE_ATTR(cec_logical_addr_config, S_IWUSR | S_IRUGO,
|
||||
cec_logical_addr_show, cec_logical_addr_store);
|
||||
|
||||
/* keeping this for debug support to track register read/writes */
|
||||
struct tegra_cec *tegra_cec_global;
|
||||
|
||||
/* Try again in case of reset control failure */
|
||||
static int reset_retry_count = 5;
|
||||
|
||||
static void tegra_cec_writel(u32 value, void __iomem *addr)
|
||||
{
|
||||
writel(value, addr);
|
||||
}
|
||||
|
||||
static u32 tegra_cec_readl(const void __iomem *addr)
|
||||
{
|
||||
return readl(addr);
|
||||
}
|
||||
|
||||
static int tegra_cec_open(struct inode *inode, struct file *file)
|
||||
{
|
||||
struct miscdevice *miscdev = file->private_data;
|
||||
struct tegra_cec *cec = container_of(miscdev,
|
||||
struct tegra_cec, misc_dev);
|
||||
int ret = 0;
|
||||
|
||||
dev_dbg(cec->dev, "%s\n", __func__);
|
||||
|
||||
ret = wait_event_interruptible(cec->init_waitq,
|
||||
atomic_read(&cec->init_done) == 1);
|
||||
if (ret)
|
||||
return ret;
|
||||
file->private_data = cec;
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
static int tegra_cec_release(struct inode *inode, struct file *file)
|
||||
{
|
||||
struct tegra_cec *cec = file->private_data;
|
||||
|
||||
dev_dbg(cec->dev, "%s\n", __func__);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static inline void tegra_cec_native_tx(const struct tegra_cec *cec, u32 block)
|
||||
{
|
||||
u32 tx_reg, retry;
|
||||
|
||||
tegra_cec_writel(block, cec->cec_base + TEGRA_CEC_TX_REGISTER);
|
||||
|
||||
tx_reg = tegra_cec_readl(cec->cec_base + TEGRA_CEC_TX_REGISTER);
|
||||
retry = 10;
|
||||
while ((tx_reg & 0x80000000) && retry--) {
|
||||
udelay(31); // one clock cycle = 30.5us
|
||||
tx_reg = tegra_cec_readl(cec->cec_base + TEGRA_CEC_TX_REGISTER);
|
||||
}
|
||||
}
|
||||
|
||||
static inline void tegra_cec_error_recovery(struct tegra_cec *cec)
|
||||
{
|
||||
u32 hw_ctrl;
|
||||
|
||||
hw_ctrl = tegra_cec_readl(cec->cec_base + TEGRA_CEC_HW_CONTROL);
|
||||
tegra_cec_writel(0x0, cec->cec_base + TEGRA_CEC_HW_CONTROL);
|
||||
tegra_cec_writel(0xFFFFFFFE, cec->cec_base + TEGRA_CEC_INT_STAT);
|
||||
tegra_cec_writel(hw_ctrl, cec->cec_base + TEGRA_CEC_HW_CONTROL);
|
||||
}
|
||||
|
||||
static
|
||||
int tegra_cec_native_write_l(struct tegra_cec *cec, const u8 *buf, size_t cnt)
|
||||
{
|
||||
int ret;
|
||||
size_t i;
|
||||
u32 start, mode, eom;
|
||||
u32 mask;
|
||||
|
||||
/*
|
||||
* In case previous transmission was interrupted by signal,
|
||||
* driver will try to complete the frame anyway. However,
|
||||
* this means we have to wait for it to finish before beginning
|
||||
* subsequent transmission.
|
||||
*/
|
||||
ret = wait_event_interruptible_timeout(cec->tx_waitq, cec->tx_wake == 1,
|
||||
msecs_to_jiffies(CEC_XFER_TIMEOUT_MS));
|
||||
if (ret == 0)
|
||||
return -ETIME;
|
||||
else if (ret < 0)
|
||||
return ret;
|
||||
|
||||
mode = TEGRA_CEC_LADDR_MODE(buf[0]) << TEGRA_CEC_TX_REG_ADDR_MODE_SHIFT;
|
||||
|
||||
cec->tx_wake = 0;
|
||||
cec->tx_error = 0;
|
||||
cec->tx_buf_cur = 0;
|
||||
cec->tx_buf_cnt = cnt;
|
||||
|
||||
for (i = 0; i < cnt; i++) {
|
||||
start = i == 0 ? (1 << TEGRA_CEC_TX_REG_START_BIT_SHIFT) : 0;
|
||||
eom = i == cnt-1 ? (1 << TEGRA_CEC_TX_REG_EOM_SHIFT) : 0;
|
||||
cec->tx_buf[i] = start | mode | eom | buf[i];
|
||||
}
|
||||
|
||||
mask = tegra_cec_readl(cec->cec_base + TEGRA_CEC_INT_MASK);
|
||||
tegra_cec_writel(mask | TEGRA_CEC_INT_MASK_TX_REGISTER_EMPTY,
|
||||
cec->cec_base + TEGRA_CEC_INT_MASK);
|
||||
|
||||
ret = wait_event_interruptible_timeout(cec->tx_waitq, cec->tx_wake == 1,
|
||||
msecs_to_jiffies(CEC_XFER_TIMEOUT_MS));
|
||||
if (ret > 0) {
|
||||
ret = cec->tx_error;
|
||||
} else if (ret == 0) {
|
||||
dev_err(cec->dev, "timeout in %s:%d.", __func__, __LINE__);
|
||||
tegra_cec_error_recovery(cec);
|
||||
cec->tx_wake = 1;
|
||||
ret = -ETIME;
|
||||
}
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
static ssize_t tegra_cec_write(struct file *file, const char __user *buf,
|
||||
size_t count, loff_t *ppos)
|
||||
{
|
||||
u8 tx_buf[TEGRA_CEC_FRAME_MAX_LENGTH];
|
||||
struct tegra_cec *cec = file->private_data;
|
||||
ssize_t ret;
|
||||
|
||||
if (count == 0 || count > TEGRA_CEC_FRAME_MAX_LENGTH)
|
||||
return -EMSGSIZE;
|
||||
|
||||
ret = wait_event_interruptible(cec->init_waitq,
|
||||
atomic_read(&cec->init_done) == 1);
|
||||
if (ret)
|
||||
return ret;
|
||||
|
||||
if (copy_from_user(tx_buf, buf, count))
|
||||
return -EFAULT;
|
||||
|
||||
mutex_lock(&cec->tx_lock);
|
||||
ret = tegra_cec_native_write_l(cec, tx_buf, count);
|
||||
mutex_unlock(&cec->tx_lock);
|
||||
if (ret)
|
||||
return ret;
|
||||
else {
|
||||
dev_dbg(cec->dev, "%s: %*phC", __func__, (int)count, tx_buf);
|
||||
return count;
|
||||
}
|
||||
}
|
||||
|
||||
static ssize_t tegra_cec_read(struct file *file, char __user *buffer,
|
||||
size_t count, loff_t *ppos)
|
||||
{
|
||||
struct tegra_cec *cec = file->private_data;
|
||||
ssize_t ret;
|
||||
|
||||
ret = wait_event_interruptible(cec->init_waitq,
|
||||
atomic_read(&cec->init_done) == 1);
|
||||
if (ret)
|
||||
return ret;
|
||||
|
||||
if (cec->rx_wake == 0)
|
||||
if (file->f_flags & O_NONBLOCK)
|
||||
return -EAGAIN;
|
||||
|
||||
ret = wait_event_interruptible(cec->rx_waitq, cec->rx_wake == 1);
|
||||
if (ret)
|
||||
return ret;
|
||||
|
||||
count = sizeof(cec->rx_fifo[0]) * (cec->rx_fifo_data);
|
||||
if (copy_to_user(buffer, &(cec->rx_fifo[0]), count))
|
||||
return -EFAULT;
|
||||
|
||||
dev_dbg(cec->dev, "%s: %*phC", __func__, (int)count,
|
||||
&(cec->rx_fifo[0]));
|
||||
|
||||
memset(&(cec->rx_fifo[0]), 0, count);
|
||||
cec->rx_wake = 0;
|
||||
cec->rx_fifo_data = 0;
|
||||
return count;
|
||||
}
|
||||
|
||||
static irqreturn_t tegra_cec_irq_handler(int irq, void *data)
|
||||
{
|
||||
struct device *dev = data;
|
||||
struct tegra_cec *cec = dev_get_drvdata(dev);
|
||||
u32 status, mask, i;
|
||||
|
||||
status = tegra_cec_readl(cec->cec_base + TEGRA_CEC_INT_STAT);
|
||||
mask = tegra_cec_readl(cec->cec_base + TEGRA_CEC_INT_MASK);
|
||||
|
||||
status &= mask;
|
||||
|
||||
if (!status)
|
||||
goto out;
|
||||
|
||||
if (status & TEGRA_CEC_INT_STAT_TX_REGISTER_UNDERRUN) {
|
||||
dev_err(dev, "TX underrun, interrupt timing issue!\n");
|
||||
|
||||
tegra_cec_error_recovery(cec);
|
||||
tegra_cec_writel(mask & ~TEGRA_CEC_INT_MASK_TX_REGISTER_EMPTY,
|
||||
cec->cec_base + TEGRA_CEC_INT_MASK);
|
||||
|
||||
cec->tx_error = -EIO;
|
||||
cec->tx_wake = 1;
|
||||
|
||||
wake_up_interruptible(&cec->tx_waitq);
|
||||
|
||||
goto out;
|
||||
} else if ((status & TEGRA_CEC_INT_STAT_TX_ARBITRATION_FAILED) ||
|
||||
(status & TEGRA_CEC_INT_STAT_TX_BUS_ANOMALY_DETECTED)) {
|
||||
tegra_cec_error_recovery(cec);
|
||||
tegra_cec_writel(mask & ~TEGRA_CEC_INT_MASK_TX_REGISTER_EMPTY,
|
||||
cec->cec_base + TEGRA_CEC_INT_MASK);
|
||||
|
||||
cec->tx_error = -ECOMM;
|
||||
cec->tx_wake = 1;
|
||||
|
||||
wake_up_interruptible(&cec->tx_waitq);
|
||||
|
||||
goto out;
|
||||
} else if (status & TEGRA_CEC_INT_STAT_TX_FRAME_TRANSMITTED) {
|
||||
tegra_cec_writel((TEGRA_CEC_INT_STAT_TX_FRAME_TRANSMITTED),
|
||||
cec->cec_base + TEGRA_CEC_INT_STAT);
|
||||
|
||||
if (status & TEGRA_CEC_INT_STAT_TX_FRAME_OR_BLOCK_NAKD) {
|
||||
tegra_cec_error_recovery(cec);
|
||||
|
||||
cec->tx_error = TEGRA_CEC_LADDR_MODE(cec->tx_buf[0]) ?
|
||||
-ECONNRESET : -EHOSTUNREACH;
|
||||
}
|
||||
cec->tx_wake = 1;
|
||||
|
||||
wake_up_interruptible(&cec->tx_waitq);
|
||||
|
||||
goto out;
|
||||
} else if (status & TEGRA_CEC_INT_STAT_TX_FRAME_OR_BLOCK_NAKD)
|
||||
dev_warn(dev, "TX NAKed on the fly!\n");
|
||||
|
||||
if (status & TEGRA_CEC_INT_STAT_TX_REGISTER_EMPTY) {
|
||||
if (cec->tx_buf_cur == cec->tx_buf_cnt)
|
||||
tegra_cec_writel(mask & ~TEGRA_CEC_INT_MASK_TX_REGISTER_EMPTY,
|
||||
cec->cec_base + TEGRA_CEC_INT_MASK);
|
||||
else
|
||||
tegra_cec_native_tx(cec,
|
||||
cec->tx_buf[cec->tx_buf_cur++]);
|
||||
}
|
||||
|
||||
if (status & (TEGRA_CEC_INT_STAT_RX_REGISTER_OVERRUN |
|
||||
TEGRA_CEC_INT_STAT_RX_BUS_ANOMALY_DETECTED |
|
||||
TEGRA_CEC_INT_STAT_RX_START_BIT_DETECTED |
|
||||
TEGRA_CEC_INT_STAT_RX_BUS_ERROR_DETECTED)) {
|
||||
tegra_cec_writel((TEGRA_CEC_INT_STAT_RX_REGISTER_OVERRUN |
|
||||
TEGRA_CEC_INT_STAT_RX_BUS_ANOMALY_DETECTED |
|
||||
TEGRA_CEC_INT_STAT_RX_START_BIT_DETECTED |
|
||||
TEGRA_CEC_INT_STAT_RX_BUS_ERROR_DETECTED),
|
||||
cec->cec_base + TEGRA_CEC_INT_STAT);
|
||||
} else if (status & TEGRA_CEC_INT_STAT_RX_REGISTER_FULL) {
|
||||
/*
|
||||
Read TEGRA_CEC_RX_BUFFER_STAT_0 which have total number of blocks,
|
||||
then read every block continuously from TEGRA_CEC_RX_REGISTER.
|
||||
TEGRA_CEC_INT_STAT_RX_REGISTER_FULL sets only once and not for
|
||||
every block if there are more than 1 block in FIFO.
|
||||
*/
|
||||
cec->rx_fifo_data =
|
||||
tegra_cec_readl(cec->cec_base + TEGRA_CEC_RX_BUFFER_STAT_0);
|
||||
for (i = 0; i < cec->rx_fifo_data; i++) {
|
||||
cec->rx_fifo[i] =
|
||||
readw(cec->cec_base + TEGRA_CEC_RX_REGISTER);
|
||||
}
|
||||
|
||||
tegra_cec_writel(TEGRA_CEC_INT_STAT_RX_REGISTER_FULL,
|
||||
cec->cec_base + TEGRA_CEC_INT_STAT);
|
||||
cec->rx_wake = 1;
|
||||
wake_up_interruptible(&cec->rx_waitq);
|
||||
}
|
||||
|
||||
out:
|
||||
return IRQ_HANDLED;
|
||||
}
|
||||
|
||||
static int tegra_cec_dump_registers(struct tegra_cec *cec)
|
||||
{
|
||||
int value, i;
|
||||
|
||||
dev_info(cec->dev, "base address = %llx\n", (u64)cec->cec_base);
|
||||
for (i = 0; i <= TEGRA_CEC_RX_OPCODE_4; i += 4) {
|
||||
value = tegra_cec_readl(cec->cec_base + i);
|
||||
dev_info(cec->dev, "offset %08x: %08x\n", i, value);
|
||||
}
|
||||
return i;
|
||||
|
||||
}
|
||||
|
||||
static int tegra_cec_set_rx_snoop(struct tegra_cec *cec, u32 enable)
|
||||
{
|
||||
u32 state;
|
||||
|
||||
if (!atomic_read(&cec->init_done))
|
||||
return -EAGAIN;
|
||||
state = tegra_cec_readl(cec->cec_base + TEGRA_CEC_HW_CONTROL);
|
||||
if (((state & TEGRA_CEC_HWCTRL_RX_SNOOP) != 0) ^ (enable != 0)) {
|
||||
state ^= TEGRA_CEC_HWCTRL_RX_SNOOP;
|
||||
tegra_cec_writel(state, cec->cec_base + TEGRA_CEC_HW_CONTROL);
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int tegra_cec_get_rx_snoop(struct tegra_cec *cec, u32 *state)
|
||||
{
|
||||
if (!atomic_read(&cec->init_done))
|
||||
return -EAGAIN;
|
||||
*state = (readl(cec->cec_base + TEGRA_CEC_HW_CONTROL) & TEGRA_CEC_HWCTRL_RX_SNOOP) >> 15;
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int tegra_cec_access_ok(bool write, unsigned long arg, size_t size)
|
||||
{
|
||||
int err = 0;
|
||||
|
||||
#if KERNEL_VERSION(5, 4, 0) > LINUX_VERSION_CODE
|
||||
u8 __maybe_unused access_type = write ? VERIFY_WRITE : VERIFY_READ;
|
||||
err = !access_ok(access_type, arg, size);
|
||||
#else
|
||||
err = !access_ok((void *)arg, size);
|
||||
#endif
|
||||
|
||||
return err;
|
||||
}
|
||||
|
||||
static long tegra_cec_ioctl(struct file *file, unsigned int cmd,
|
||||
unsigned long arg)
|
||||
{
|
||||
int err;
|
||||
u32 state;
|
||||
|
||||
struct tegra_cec *cec = file->private_data;
|
||||
|
||||
if (_IOC_TYPE(cmd) != TEGRA_CEC_IOC_MAGIC)
|
||||
return -EINVAL;
|
||||
|
||||
switch (cmd) {
|
||||
case TEGRA_CEC_IOCTL_ERROR_RECOVERY:
|
||||
mutex_lock(&cec->recovery_lock);
|
||||
tegra_cec_error_recovery(cec);
|
||||
mutex_unlock(&cec->recovery_lock);
|
||||
break;
|
||||
case TEGRA_CEC_IOCTL_DUMP_REGISTERS:
|
||||
tegra_cec_dump_registers(cec);
|
||||
break;
|
||||
case TEGRA_CEC_IOCTL_SET_RX_SNOOP:
|
||||
err = tegra_cec_access_ok(false, arg, sizeof(u32));
|
||||
if (err)
|
||||
return -EFAULT;
|
||||
if (copy_from_user((u32 *) &state, (u32 *) arg, sizeof(u32)))
|
||||
return -EFAULT;
|
||||
tegra_cec_set_rx_snoop(cec, state);
|
||||
break;
|
||||
case TEGRA_CEC_IOCTL_GET_RX_SNOOP:
|
||||
err = tegra_cec_access_ok(true, arg, sizeof(u32));
|
||||
if (err)
|
||||
return -EFAULT;
|
||||
err = tegra_cec_get_rx_snoop(cec, &state);
|
||||
if (!err) {
|
||||
if (copy_to_user((u32 *) arg, &state, sizeof(u32)))
|
||||
return -EFAULT;
|
||||
}
|
||||
break;
|
||||
case TEGRA_CEC_IOCTL_GET_POST_RECOVERY:
|
||||
err = tegra_cec_access_ok(true, arg, sizeof(u32));
|
||||
if (err)
|
||||
return -EFAULT;
|
||||
if (copy_to_user((bool *) arg, &post_recovery, sizeof(bool)))
|
||||
return -EFAULT;
|
||||
break;
|
||||
default:
|
||||
dev_err(cec->dev, "unsupported ioctl\n");
|
||||
return -EINVAL;
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static const struct file_operations tegra_cec_fops = {
|
||||
.owner = THIS_MODULE,
|
||||
.open = tegra_cec_open,
|
||||
.release = tegra_cec_release,
|
||||
.read = tegra_cec_read,
|
||||
.write = tegra_cec_write,
|
||||
.unlocked_ioctl = tegra_cec_ioctl,
|
||||
#ifdef CONFIG_COMPAT
|
||||
.compat_ioctl = tegra_cec_ioctl,
|
||||
#endif
|
||||
};
|
||||
|
||||
static int tegra_cec_send_one_touch_play(struct tegra_cec *cec)
|
||||
{
|
||||
int res = 0;
|
||||
u8 phy_address[2] = {0};
|
||||
u32 state = 0;
|
||||
|
||||
text_view_on_sent = true;
|
||||
|
||||
/*
|
||||
* UEFI writes physical address at register TEGRA_CEC_HW_SPARE during boot.
|
||||
*/
|
||||
state = tegra_cec_readl(cec->cec_base + TEGRA_CEC_HW_SPARE);
|
||||
phy_address[0] = state & 0x000F;
|
||||
phy_address[1] = state & 0x00F0;
|
||||
|
||||
dev_info(cec->dev, "physical address: %02x:%02x.\n",
|
||||
phy_address[0], phy_address[1]);
|
||||
|
||||
if ((phy_address[0] == 0) && (phy_address[1] == 0)) {
|
||||
dev_err(cec->dev, "Can't find physical address.\n");
|
||||
return 0;
|
||||
}
|
||||
|
||||
active_source_command[2] = phy_address[0];
|
||||
active_source_command[3] = phy_address[1];
|
||||
|
||||
mutex_lock(&cec->tx_lock);
|
||||
res = tegra_cec_native_write_l(cec, text_view_on_command,
|
||||
sizeof(text_view_on_command));
|
||||
dev_notice(cec->dev, "Sent <Text View On> res: %d.\n", res);
|
||||
if (!res) {
|
||||
res = tegra_cec_native_write_l(cec, active_source_command,
|
||||
sizeof(active_source_command));
|
||||
dev_notice(cec->dev,
|
||||
"Broadcast <Active Source> res: %d.\n", res);
|
||||
}
|
||||
mutex_unlock(&cec->tx_lock);
|
||||
|
||||
return res;
|
||||
}
|
||||
|
||||
static void tegra_cec_init(struct tegra_cec *cec)
|
||||
{
|
||||
u32 state;
|
||||
cec->rx_wake = 0;
|
||||
cec->tx_wake = 1;
|
||||
cec->tx_buf_cnt = 0;
|
||||
cec->tx_buf_cur = 0;
|
||||
cec->tx_error = 0;
|
||||
|
||||
tegra_cec_global = cec;
|
||||
dev_notice(cec->dev, "%s started\n", __func__);
|
||||
|
||||
tegra_cec_writel(0x00, cec->cec_base + TEGRA_CEC_HW_CONTROL);
|
||||
tegra_cec_writel(0x00, cec->cec_base + TEGRA_CEC_INT_MASK);
|
||||
|
||||
#ifdef CONFIG_PM
|
||||
if (wait_event_interruptible_timeout(cec->suspend_waitq,
|
||||
atomic_xchg(&cec->init_cancel, 0) == 1,
|
||||
msecs_to_jiffies(1000)) > 0)
|
||||
return;
|
||||
#else
|
||||
msleep(1000);
|
||||
#endif
|
||||
|
||||
tegra_cec_writel(0x00, cec->cec_base + TEGRA_CEC_SW_CONTROL);
|
||||
|
||||
cec->logical_addr = TEGRA_CEC_HWCTRL_RX_LADDR_UNREG;
|
||||
|
||||
state = TEGRA_CEC_HWCTRL_AUTO_CLR_TX_EMPTY_INTR |
|
||||
TEGRA_CEC_HWCTRL_RX_LADDR(cec->logical_addr);
|
||||
tegra_cec_writel(state, cec->cec_base + TEGRA_CEC_HW_CONTROL);
|
||||
|
||||
tegra_cec_writel(0x1, cec->cec_base + TEGRA_CEC_MESSAGE_FILTER_CTRL);
|
||||
|
||||
state = (0xff << TEGRA_CEC_RX_TIMING_1_RX_DATA_BIT_MAX_LO_TIME_MASK) |
|
||||
(0x22 << TEGRA_CEC_RX_TIMING_1_RX_DATA_BIT_SAMPLE_TIME_MASK) |
|
||||
(0xe0 << TEGRA_CEC_RX_TIMING_1_RX_DATA_BIT_MAX_DURATION_MASK) |
|
||||
(0x41 << TEGRA_CEC_RX_TIMING_1_RX_DATA_BIT_MIN_DURATION_MASK);
|
||||
tegra_cec_writel(state, cec->cec_base + TEGRA_CEC_RX_TIMING_1);
|
||||
|
||||
state = (0x7 << TEGRA_CEC_TX_TIMING_2_BUS_IDLE_TIME_ADDITIONAL_FRAME_MASK) |
|
||||
(0x1 << TEGRA_CEC_TX_TIMING_2_BUS_IDLE_TIME_NEW_FRAME_MASK) |
|
||||
(0x3 << TEGRA_CEC_TX_TIMING_2_BUS_IDLE_TIME_RETRY_FRAME_MASK);
|
||||
tegra_cec_writel(state, cec->cec_base + TEGRA_CEC_TX_TIMING_2);
|
||||
|
||||
/*
|
||||
* By default, keep RX buffer depth to 2 bytes like previous chips.
|
||||
* Value 1 = 2 bytes (1 fifo depth)
|
||||
* Value 0x40 = 128 bytes (64 fifo depth)
|
||||
*/
|
||||
tegra_cec_writel(0x1, cec->cec_base + TEGRA_CEC_RX_BUFFER_AFULL_CFG_0);
|
||||
|
||||
state = tegra_cec_readl(cec->cec_base + TEGRA_CEC_HW_CONTROL);
|
||||
state |= TEGRA_CEC_HWCTRL_TX_RX_MODE;
|
||||
tegra_cec_writel(state, cec->cec_base + TEGRA_CEC_HW_CONTROL);
|
||||
|
||||
tegra_cec_writel(TEGRA_CEC_INT_MASK_TX_REGISTER_UNDERRUN |
|
||||
TEGRA_CEC_INT_MASK_TX_FRAME_OR_BLOCK_NAKD |
|
||||
TEGRA_CEC_INT_MASK_TX_ARBITRATION_FAILED |
|
||||
TEGRA_CEC_INT_MASK_TX_BUS_ANOMALY_DETECTED |
|
||||
TEGRA_CEC_INT_MASK_TX_FRAME_TRANSMITTED |
|
||||
TEGRA_CEC_INT_MASK_RX_REGISTER_FULL |
|
||||
TEGRA_CEC_INT_MASK_RX_REGISTER_OVERRUN,
|
||||
cec->cec_base + TEGRA_CEC_INT_MASK);
|
||||
|
||||
atomic_set(&cec->init_done, 1);
|
||||
wake_up_interruptible(&cec->init_waitq);
|
||||
|
||||
if (!text_view_on_sent && !post_recovery)
|
||||
tegra_cec_send_one_touch_play(cec);
|
||||
dev_notice(cec->dev, "%s Done.\n", __func__);
|
||||
}
|
||||
|
||||
static void tegra_cec_init_worker(struct work_struct *work)
|
||||
{
|
||||
struct tegra_cec *cec = container_of(work, struct tegra_cec, work);
|
||||
|
||||
tegra_cec_init(cec);
|
||||
}
|
||||
|
||||
static ssize_t cec_logical_addr_show(struct device *dev,
|
||||
struct device_attribute *attr, char *buf)
|
||||
{
|
||||
struct tegra_cec *cec = dev_get_drvdata(dev);
|
||||
|
||||
if (!atomic_read(&cec->init_done))
|
||||
return -EAGAIN;
|
||||
|
||||
if (buf)
|
||||
return sprintf(buf, "0x%x\n", (u32)cec->logical_addr);
|
||||
return 1;
|
||||
}
|
||||
|
||||
static ssize_t cec_logical_addr_store(struct device *dev,
|
||||
struct device_attribute *attr, const char *buf, size_t count)
|
||||
{
|
||||
ssize_t ret;
|
||||
u32 state;
|
||||
u16 addr;
|
||||
struct tegra_cec *cec;
|
||||
|
||||
if (!buf || !count)
|
||||
return -EINVAL;
|
||||
|
||||
cec = dev_get_drvdata(dev);
|
||||
if (!atomic_read(&cec->init_done))
|
||||
return -EAGAIN;
|
||||
|
||||
ret = kstrtou16(buf, 0, &addr);
|
||||
if (ret)
|
||||
return ret;
|
||||
|
||||
dev_info(dev, "set logical address: 0x%x\n", (u32)addr);
|
||||
cec->logical_addr = addr;
|
||||
|
||||
// clear TX_RX_MODE
|
||||
state = tegra_cec_readl(cec->cec_base + TEGRA_CEC_HW_CONTROL);
|
||||
state &= ~TEGRA_CEC_HWCTRL_TX_RX_MODE;
|
||||
tegra_cec_writel(state, cec->cec_base + TEGRA_CEC_HW_CONTROL);
|
||||
// write logical address
|
||||
state = tegra_cec_readl(cec->cec_base + TEGRA_CEC_HW_CONTROL);
|
||||
state &= ~TEGRA_CEC_HWCTRL_RX_LADDR_MASK;
|
||||
state |= TEGRA_CEC_HWCTRL_RX_LADDR(cec->logical_addr);
|
||||
tegra_cec_writel(state, cec->cec_base + TEGRA_CEC_HW_CONTROL);
|
||||
// enable tx_rx mode
|
||||
state = tegra_cec_readl(cec->cec_base + TEGRA_CEC_HW_CONTROL);
|
||||
state |= TEGRA_CEC_HWCTRL_TX_RX_MODE;
|
||||
tegra_cec_writel(state, cec->cec_base + TEGRA_CEC_HW_CONTROL);
|
||||
|
||||
return count;
|
||||
}
|
||||
|
||||
static int tegra_cec_probe(struct platform_device *pdev)
|
||||
{
|
||||
struct tegra_cec *cec;
|
||||
struct resource *res;
|
||||
int ret = 0;
|
||||
struct reset_control *rst = NULL;
|
||||
|
||||
cec = devm_kzalloc(&pdev->dev, sizeof(struct tegra_cec), GFP_KERNEL);
|
||||
|
||||
if (!cec)
|
||||
return -ENOMEM;
|
||||
|
||||
if (reset_retry_count != 0) {
|
||||
rst = devm_reset_control_get(&pdev->dev, "cec");
|
||||
if (IS_ERR(rst)) {
|
||||
/* BPMP reset mechanism not available, return and retry again */
|
||||
dev_info(&pdev->dev, "reset control is not found, deferring probe to retry again.\n");
|
||||
devm_kfree(&pdev->dev, cec);
|
||||
reset_retry_count--;
|
||||
return -EPROBE_DEFER;
|
||||
}
|
||||
|
||||
/* take CEC engine out of reset */
|
||||
if (reset_control_reset(rst) != 0) {
|
||||
dev_info(&pdev->dev, "reset control reset failed, deferring probe to retry again.\n");
|
||||
devm_kfree(&pdev->dev, cec);
|
||||
reset_retry_count--;
|
||||
return -EPROBE_DEFER;
|
||||
}
|
||||
}
|
||||
|
||||
res = platform_get_resource(pdev, IORESOURCE_MEM, 0);
|
||||
|
||||
if (!res) {
|
||||
dev_err(&pdev->dev,
|
||||
"Unable to allocate resources for device.\n");
|
||||
ret = -EBUSY;
|
||||
goto cec_error;
|
||||
}
|
||||
|
||||
if (!devm_request_mem_region(&pdev->dev, res->start, resource_size(res),
|
||||
pdev->name)) {
|
||||
dev_err(&pdev->dev,
|
||||
"Unable to request mem region for device.\n");
|
||||
ret = -EBUSY;
|
||||
goto cec_error;
|
||||
}
|
||||
|
||||
cec->tegra_cec_irq = platform_get_irq(pdev, 0);
|
||||
|
||||
if (cec->tegra_cec_irq <= 0) {
|
||||
ret = -EBUSY;
|
||||
goto cec_error;
|
||||
}
|
||||
|
||||
cec->cec_base = devm_ioremap(&pdev->dev, res->start,
|
||||
resource_size(res));
|
||||
|
||||
if (!cec->cec_base) {
|
||||
dev_err(&pdev->dev, "Unable to grab IOs for device.\n");
|
||||
ret = -EBUSY;
|
||||
goto cec_error;
|
||||
}
|
||||
|
||||
dev_info(&pdev->dev, "dt=%d start=0x%08llX end=0x%08llX irq=%d\n",
|
||||
(pdev->dev.of_node != NULL),
|
||||
res->start, res->end,
|
||||
cec->tegra_cec_irq);
|
||||
|
||||
atomic_set(&cec->init_done, 0);
|
||||
mutex_init(&cec->tx_lock);
|
||||
mutex_init(&cec->recovery_lock);
|
||||
cec->dev = &pdev->dev;
|
||||
|
||||
/* set context info. */
|
||||
init_waitqueue_head(&cec->rx_waitq);
|
||||
init_waitqueue_head(&cec->tx_waitq);
|
||||
init_waitqueue_head(&cec->init_waitq);
|
||||
|
||||
#ifdef CONFIG_PM
|
||||
init_waitqueue_head(&cec->suspend_waitq);
|
||||
atomic_set(&cec->init_cancel, 0);
|
||||
#endif
|
||||
|
||||
platform_set_drvdata(pdev, cec);
|
||||
/* clear out the hardware. */
|
||||
|
||||
INIT_WORK(&cec->work, tegra_cec_init_worker);
|
||||
schedule_work(&cec->work);
|
||||
|
||||
device_init_wakeup(&pdev->dev, 1);
|
||||
|
||||
cec->misc_dev.minor = MISC_DYNAMIC_MINOR;
|
||||
cec->misc_dev.name = TEGRA_CEC_NAME;
|
||||
cec->misc_dev.fops = &tegra_cec_fops;
|
||||
cec->misc_dev.parent = &pdev->dev;
|
||||
|
||||
if (misc_register(&cec->misc_dev)) {
|
||||
printk(KERN_WARNING "Couldn't register device , %s.\n", TEGRA_CEC_NAME);
|
||||
goto cec_error;
|
||||
}
|
||||
|
||||
ret = devm_request_irq(&pdev->dev, cec->tegra_cec_irq,
|
||||
tegra_cec_irq_handler, 0x0, "cec_irq", &pdev->dev);
|
||||
|
||||
if (ret) {
|
||||
dev_err(&pdev->dev,
|
||||
"Unable to request interrupt for device (err=%d).\n", ret);
|
||||
goto cec_error;
|
||||
}
|
||||
|
||||
/*
|
||||
* Create a symlink for tegra_cec if it is not under platform bus or
|
||||
* it has been created with different name.
|
||||
*/
|
||||
if ((pdev->dev.parent != &platform_bus) ||
|
||||
strcmp(dev_name(&pdev->dev), TEGRA_CEC_NAME)) {
|
||||
ret = sysfs_create_link(&platform_bus.kobj,
|
||||
&pdev->dev.kobj, TEGRA_CEC_NAME);
|
||||
if (ret)
|
||||
dev_warn(&pdev->dev, "Could not create sysfs link.\n");
|
||||
}
|
||||
|
||||
ret = sysfs_create_file(
|
||||
&pdev->dev.kobj, &dev_attr_cec_logical_addr_config.attr);
|
||||
dev_info(&pdev->dev, "cec_add_sysfs ret=%d\n", ret);
|
||||
if (ret != 0) {
|
||||
dev_err(&pdev->dev, "Failed to add sysfs: %d\n", ret);
|
||||
goto cec_error;
|
||||
}
|
||||
|
||||
dev_notice(&pdev->dev, "probed\n");
|
||||
|
||||
return 0;
|
||||
|
||||
cec_error:
|
||||
cancel_work_sync(&cec->work);
|
||||
return ret;
|
||||
}
|
||||
|
||||
static void tegra_cec_remove(struct platform_device *pdev)
|
||||
{
|
||||
struct tegra_cec *cec = platform_get_drvdata(pdev);
|
||||
|
||||
misc_deregister(&cec->misc_dev);
|
||||
cancel_work_sync(&cec->work);
|
||||
}
|
||||
|
||||
#ifdef CONFIG_PM
|
||||
static int tegra_cec_suspend(struct platform_device *pdev, pm_message_t state)
|
||||
{
|
||||
struct tegra_cec *cec = platform_get_drvdata(pdev);
|
||||
|
||||
atomic_set(&cec->init_cancel, 1);
|
||||
wmb();
|
||||
|
||||
wake_up_interruptible(&cec->suspend_waitq);
|
||||
|
||||
/* cancel the work queue */
|
||||
cancel_work_sync(&cec->work);
|
||||
|
||||
atomic_set(&cec->init_done, 0);
|
||||
atomic_set(&cec->init_cancel, 0);
|
||||
/*
|
||||
* Wakeup from SC7 on CEC is broken for T234 in HW.
|
||||
* Don't do anything for this while going to suspend.
|
||||
*/
|
||||
dev_notice(&pdev->dev, "suspended\n");
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int tegra_cec_resume(struct platform_device *pdev)
|
||||
{
|
||||
struct tegra_cec *cec = platform_get_drvdata(pdev);
|
||||
|
||||
dev_notice(&pdev->dev, "Resuming\n");
|
||||
|
||||
/*
|
||||
* Wakeup from SC7 on CEC is broken for T234 in HW.
|
||||
* Don't do anything after exiting suspend.
|
||||
*/
|
||||
schedule_work(&cec->work);
|
||||
|
||||
return 0;
|
||||
}
|
||||
#endif
|
||||
|
||||
static struct of_device_id tegra_cec_of_match[] = {
|
||||
{ .compatible = "nvidia,tegra234-cec"},
|
||||
{},
|
||||
};
|
||||
|
||||
#if defined(NV_PLATFORM_DRIVER_STRUCT_REMOVE_RETURNS_VOID) /* Linux v6.11 */
|
||||
static void tegra_cec_remove_wrapper(struct platform_device *pdev)
|
||||
{
|
||||
tegra_cec_remove(pdev);
|
||||
}
|
||||
#else
|
||||
static int tegra_cec_remove_wrapper(struct platform_device *pdev)
|
||||
{
|
||||
tegra_cec_remove(pdev);
|
||||
|
||||
return 0;
|
||||
}
|
||||
#endif
|
||||
|
||||
static struct platform_driver tegra_cec_driver = {
|
||||
.driver = {
|
||||
.name = TEGRA_CEC_NAME,
|
||||
.owner = THIS_MODULE,
|
||||
|
||||
.of_match_table = of_match_ptr(tegra_cec_of_match),
|
||||
},
|
||||
.probe = tegra_cec_probe,
|
||||
.remove = tegra_cec_remove_wrapper,
|
||||
|
||||
#ifdef CONFIG_PM
|
||||
.suspend = tegra_cec_suspend,
|
||||
.resume = tegra_cec_resume,
|
||||
#endif
|
||||
};
|
||||
|
||||
module_platform_driver(tegra_cec_driver);
|
||||
|
||||
MODULE_DESCRIPTION("NVIDIA TEGRA CEC Driver");
|
||||
MODULE_AUTHOR("NVIDIA");
|
||||
MODULE_LICENSE("GPL");
|
||||
@@ -1,167 +0,0 @@
|
||||
// SPDX-License-Identifier: GPL-2.0
|
||||
// Copyright (c) 2022-2025, NVIDIA CORPORATION. All rights reserved.
|
||||
|
||||
#ifndef TEGRA_CEC_H
|
||||
#define TEGRA_CEC_H
|
||||
|
||||
#include <linux/pm.h>
|
||||
#include <asm/atomic.h>
|
||||
#include <uapi/misc/tegra_cec.h>
|
||||
|
||||
#define TEGRA_CEC_FRAME_MAX_LENGTH 16
|
||||
#define TEGRA_CEC_RX_FIFO_LENGTH 64
|
||||
|
||||
struct tegra_cec {
|
||||
struct device *dev;
|
||||
struct miscdevice misc_dev;
|
||||
struct clk *clk;
|
||||
struct mutex tx_lock;
|
||||
struct mutex recovery_lock;
|
||||
void __iomem *cec_base;
|
||||
int tegra_cec_irq;
|
||||
wait_queue_head_t rx_waitq;
|
||||
wait_queue_head_t tx_waitq;
|
||||
wait_queue_head_t init_waitq;
|
||||
atomic_t init_done;
|
||||
#ifdef CONFIG_PM
|
||||
wait_queue_head_t suspend_waitq;
|
||||
atomic_t init_cancel;
|
||||
#endif
|
||||
u16 logical_addr;
|
||||
struct work_struct work;
|
||||
unsigned int rx_wake;
|
||||
unsigned int tx_wake;
|
||||
long tx_error;
|
||||
u32 tx_buf[TEGRA_CEC_FRAME_MAX_LENGTH];
|
||||
u8 tx_buf_cur;
|
||||
u8 tx_buf_cnt;
|
||||
struct reset_control *reset;
|
||||
u16 rx_fifo[TEGRA_CEC_RX_FIFO_LENGTH];
|
||||
u16 rx_fifo_data;
|
||||
};
|
||||
|
||||
#define TEGRA_CEC_LADDR_BROADCAST 0xF
|
||||
#define TEGRA_CEC_LADDR_MASK 0xF
|
||||
#define TEGRA_CEC_LADDR_WIDTH 4
|
||||
#define TEGRA_CEC_LADDR_MODE(blk) \
|
||||
((blk & TEGRA_CEC_LADDR_MASK) == TEGRA_CEC_LADDR_BROADCAST)
|
||||
|
||||
/*CEC Timing registers*/
|
||||
#define TEGRA_CEC_SW_CONTROL 0X000
|
||||
#define TEGRA_CEC_HW_CONTROL 0X004
|
||||
#define TEGRA_CEC_INPUT_FILTER 0X008
|
||||
#define TEGRA_CEC_TX_REGISTER 0X010
|
||||
#define TEGRA_CEC_RX_REGISTER 0X014
|
||||
#define TEGRA_CEC_RX_TIMING_0 0X018
|
||||
#define TEGRA_CEC_RX_TIMING_1 0X01C
|
||||
#define TEGRA_CEC_RX_TIMING_2 0X020
|
||||
#define TEGRA_CEC_TX_TIMING_0 0X024
|
||||
#define TEGRA_CEC_TX_TIMING_1 0X028
|
||||
#define TEGRA_CEC_TX_TIMING_2 0X02C
|
||||
#define TEGRA_CEC_INT_STAT 0X030
|
||||
#define TEGRA_CEC_INT_MASK 0X034
|
||||
#define TEGRA_CEC_HW_DEBUG_RX 0X038
|
||||
#define TEGRA_CEC_HW_DEBUG_TX 0X03C
|
||||
#define TEGRA_CEC_HW_SPARE 0X040
|
||||
|
||||
#define TEGRA_CEC_WAKE_STAT_0 0x044
|
||||
#define TEGRA_CEC_WAKE_MASK_0 0x048
|
||||
#define TEGRA_CEC_RX_BUFFER_AFULL_CFG_0 0x04c
|
||||
#define TEGRA_CEC_RX_BUFFER_STAT_0 0x050
|
||||
#define TEGRA_CEC_RX_TIMING_3_0 0x054
|
||||
#define TEGRA_CEC_MESSAGE_FILTER_CTRL 0X058
|
||||
#define TEGRA_CEC_RX_PHYSICAL_ADDR_0 0X05C
|
||||
#define TEGRA_CEC_RX_OPCODE_0 0x060
|
||||
#define TEGRA_CEC_RX_OPCODE_1 0x064
|
||||
#define TEGRA_CEC_RX_OPCODE_2 0x068
|
||||
#define TEGRA_CEC_RX_OPCODE_3 0x06c
|
||||
#define TEGRA_CEC_RX_OPCODE_4 0x070
|
||||
|
||||
#define TEGRA_CEC_MAX_LOGICAL_ADDR 15
|
||||
#define TEGRA_CEC_HWCTRL_RX_LADDR_UNREG 0x0
|
||||
#define TEGRA_CEC_HWCTRL_RX_LADDR_MASK 0x7FFF
|
||||
#define TEGRA_CEC_HWCTRL_RX_LADDR(x) \
|
||||
((x<<0) & TEGRA_CEC_HWCTRL_RX_LADDR_MASK)
|
||||
#define TEGRA_CEC_HWCTRL_RX_SNOOP (1<<15)
|
||||
#define TEGRA_CEC_HWCTRL_RX_NAK_MODE (1<<16)
|
||||
#define TEGRA_CEC_HWCTRL_TX_NAK_MODE (1<<24)
|
||||
#define TEGRA_CEC_HWCTRL_AUTO_CLR_TX_EMPTY_INTR (1<<29)
|
||||
#define TEGRA_CEC_HWCTRL_FAST_SIM_MODE (1<<30)
|
||||
#define TEGRA_CEC_HWCTRL_TX_RX_MODE (1<<31)
|
||||
|
||||
#define TEGRA_CEC_INPUT_FILTER_MODE (1<<31)
|
||||
#define TEGRA_CEC_INPUT_FILTER_FIFO_LENGTH_MASK 0
|
||||
|
||||
#define TEGRA_CEC_TX_REG_DATA_SHIFT 0
|
||||
#define TEGRA_CEC_TX_REG_EOM_SHIFT 8
|
||||
#define TEGRA_CEC_TX_REG_ADDR_MODE_SHIFT 12
|
||||
#define TEGRA_CEC_TX_REG_START_BIT_SHIFT 16
|
||||
#define TEGRA_CEC_TX_REG_RETRY_BIT_SHIFT 17
|
||||
|
||||
#define TEGRA_CEC_RX_REGISTER_MASK 0
|
||||
#define TEGRA_CEC_RX_REGISTER_EOM (1<<8)
|
||||
#define TEGRA_CEC_RX_REGISTER_ACK (1<<9)
|
||||
|
||||
#define TEGRA_CEC_RX_TIMING_0_RX_START_BIT_MAX_LO_TIME_MASK 0
|
||||
#define TEGRA_CEC_RX_TIMING_0_RX_START_BIT_MIN_LO_TIME_MASK 8
|
||||
#define TEGRA_CEC_RX_TIMING_0_RX_START_BIT_MAX_DURATION_MASK 16
|
||||
#define TEGRA_CEC_RX_TIMING_0_RX_START_BIT_MIN_DURATION_MASK 24
|
||||
|
||||
#define TEGRA_CEC_RX_TIMING_1_RX_DATA_BIT_MAX_LO_TIME_MASK 0
|
||||
#define TEGRA_CEC_RX_TIMING_1_RX_DATA_BIT_SAMPLE_TIME_MASK 8
|
||||
#define TEGRA_CEC_RX_TIMING_1_RX_DATA_BIT_MAX_DURATION_MASK 16
|
||||
#define TEGRA_CEC_RX_TIMING_1_RX_DATA_BIT_MIN_DURATION_MASK 24
|
||||
|
||||
#define TEGRA_CEC_RX_TIMING_2_RX_END_OF_BLOCK_TIME_MASK 0
|
||||
|
||||
#define TEGRA_CEC_TX_TIMING_0_TX_START_BIT_LO_TIME_MASK 0
|
||||
#define TEGRA_CEC_TX_TIMING_0_TX_START_BIT_DURATION_MASK 8
|
||||
#define TEGRA_CEC_TX_TIMING_0_TX_BUS_XITION_TIME_MASK 16
|
||||
#define TEGRA_CEC_TX_TIMING_0_TX_BUS_ERROR_LO_TIME_MASK 24
|
||||
|
||||
#define TEGRA_CEC_TX_TIMING_1_TX_LO_DATA_BIT_LO_TIME_MASK 0
|
||||
#define TEGRA_CEC_TX_TIMING_1_TX_HI_DATA_BIT_LO_TIME_MASK 8
|
||||
#define TEGRA_CEC_TX_TIMING_1_TX_DATA_BIT_DURATION_MASK 16
|
||||
#define TEGRA_CEC_TX_TIMING_1_TX_ACK_NAK_BIT_SAMPLE_TIME_MASK 24
|
||||
|
||||
#define TEGRA_CEC_TX_TIMING_2_BUS_IDLE_TIME_ADDITIONAL_FRAME_MASK 0
|
||||
#define TEGRA_CEC_TX_TIMING_2_BUS_IDLE_TIME_NEW_FRAME_MASK 4
|
||||
#define TEGRA_CEC_TX_TIMING_2_BUS_IDLE_TIME_RETRY_FRAME_MASK 8
|
||||
|
||||
#define TEGRA_CEC_INT_STAT_TX_REGISTER_EMPTY (1<<0)
|
||||
#define TEGRA_CEC_INT_STAT_TX_REGISTER_UNDERRUN (1<<1)
|
||||
#define TEGRA_CEC_INT_STAT_TX_FRAME_OR_BLOCK_NAKD (1<<2)
|
||||
#define TEGRA_CEC_INT_STAT_TX_ARBITRATION_FAILED (1<<3)
|
||||
#define TEGRA_CEC_INT_STAT_TX_BUS_ANOMALY_DETECTED (1<<4)
|
||||
#define TEGRA_CEC_INT_STAT_TX_FRAME_TRANSMITTED (1<<5)
|
||||
#define TEGRA_CEC_INT_STAT_RX_REGISTER_FULL (1<<8)
|
||||
#define TEGRA_CEC_INT_STAT_RX_REGISTER_OVERRUN (1<<9)
|
||||
#define TEGRA_CEC_INT_STAT_RX_START_BIT_DETECTED (1<<10)
|
||||
#define TEGRA_CEC_INT_STAT_RX_BUS_ANOMALY_DETECTED (1<<11)
|
||||
#define TEGRA_CEC_INT_STAT_RX_BUS_ERROR_DETECTED (1<<12)
|
||||
#define TEGRA_CEC_INT_STAT_FILTERED_RX_DATA_PIN_TRANSITION_H2L (1<<13)
|
||||
#define TEGRA_CEC_INT_STAT_FILTERED_RX_DATA_PIN_TRANSITION_L2H (1<<14)
|
||||
|
||||
#define TEGRA_CEC_INT_MASK_TX_REGISTER_EMPTY (1<<0)
|
||||
#define TEGRA_CEC_INT_MASK_TX_REGISTER_UNDERRUN (1<<1)
|
||||
#define TEGRA_CEC_INT_MASK_TX_FRAME_OR_BLOCK_NAKD (1<<2)
|
||||
#define TEGRA_CEC_INT_MASK_TX_ARBITRATION_FAILED (1<<3)
|
||||
#define TEGRA_CEC_INT_MASK_TX_BUS_ANOMALY_DETECTED (1<<4)
|
||||
#define TEGRA_CEC_INT_MASK_TX_FRAME_TRANSMITTED (1<<5)
|
||||
#define TEGRA_CEC_INT_MASK_RX_REGISTER_FULL (1<<8)
|
||||
#define TEGRA_CEC_INT_MASK_RX_REGISTER_OVERRUN (1<<9)
|
||||
#define TEGRA_CEC_INT_MASK_RX_START_BIT_DETECTED (1<<10)
|
||||
#define TEGRA_CEC_INT_MASK_RX_BUS_ANOMALY_DETECTED (1<<11)
|
||||
#define TEGRA_CEC_INT_MASK_RX_BUS_ERROR_DETECTED (1<<12)
|
||||
#define TEGRA_CEC_INT_MASK_FILTERED_RX_DATA_PIN_TRANSITION_H2L (1<<13)
|
||||
#define TEGRA_CEC_INT_MASK_FILTERED_RX_DATA_PIN_TRANSITION_L2H (1<<14)
|
||||
|
||||
#define TEGRA_CEC_HW_DEBUG_TX_DURATION_COUNT_MASK 0
|
||||
#define TEGRA_CEC_HW_DEBUG_TX_TXBIT_COUNT_MASK 17
|
||||
#define TEGRA_CEC_HW_DEBUG_TX_STATE_MASK 21
|
||||
#define TEGRA_CEC_HW_DEBUG_TX_FORCELOOUT (1<<25)
|
||||
#define TEGRA_CEC_HW_DEBUG_TX_TXDATABIT_SAMPLE_TIMER (1<<26)
|
||||
|
||||
#define TEGRA_CEC_NAME "tegra_cec"
|
||||
|
||||
#endif /* TEGRA_CEC_H */
|
||||
@@ -1,7 +1,7 @@
|
||||
// SPDX-License-Identifier: GPL-2.0-only
|
||||
// SPDX-FileCopyrightText: Copyright (c) 2023-2025 NVIDIA CORPORATION & AFFILIATES. All rights reserved.
|
||||
|
||||
#include <nvidia/conftest.h>
|
||||
/*
|
||||
* Copyright (c) 2023, NVIDIA CORPORATION & AFFILIATES. All rights reserved.
|
||||
*/
|
||||
|
||||
#include <linux/module.h>
|
||||
#include <linux/moduleparam.h>
|
||||
@@ -726,21 +726,9 @@ static struct of_device_id tegra_virt_mtd_match[] = {
|
||||
MODULE_DEVICE_TABLE(of, tegra_virt_mtd_match);
|
||||
#endif /* CONFIG_OF */
|
||||
|
||||
#if defined(NV_PLATFORM_DRIVER_STRUCT_REMOVE_RETURNS_VOID) /* Linux v6.11 */
|
||||
static void tegra_virt_mtd_remove_wrapper(struct platform_device *pdev)
|
||||
{
|
||||
tegra_virt_mtd_remove(pdev);
|
||||
}
|
||||
#else
|
||||
static int tegra_virt_mtd_remove_wrapper(struct platform_device *pdev)
|
||||
{
|
||||
return tegra_virt_mtd_remove(pdev);
|
||||
}
|
||||
#endif
|
||||
|
||||
static struct platform_driver tegra_virt_mtd_driver = {
|
||||
.probe = tegra_virt_mtd_probe,
|
||||
.remove = tegra_virt_mtd_remove_wrapper,
|
||||
.remove = tegra_virt_mtd_remove,
|
||||
.driver = {
|
||||
.name = "Virtual MTD device",
|
||||
.owner = THIS_MODULE,
|
||||
|
||||
@@ -291,7 +291,7 @@ inline u32 ttcan_read_ecr(struct ttcan_controller *ttcan)
|
||||
return ttcan_read32(ttcan, ADR_MTTCAN_ECR);
|
||||
}
|
||||
|
||||
#if !defined(CONFIG_TEGRA_PROD_NEXT_GEN)
|
||||
#if LINUX_VERSION_CODE < KERNEL_VERSION(5, 16, 0)
|
||||
static void tegra_mttcan_config_prod_settings(struct mttcan_priv *priv)
|
||||
{
|
||||
struct ttcan_controller *ttcan = priv->ttcan;
|
||||
|
||||
@@ -287,7 +287,7 @@ struct ttcan_controller {
|
||||
struct list_head rx_q1;
|
||||
struct list_head rx_b;
|
||||
struct list_head tx_evt;
|
||||
#if !defined(CONFIG_TEGRA_PROD_NEXT_GEN)
|
||||
#if LINUX_VERSION_CODE < KERNEL_VERSION(5, 16, 0)
|
||||
struct tegra_prod *prod_list;
|
||||
#else
|
||||
struct tegra_prod_cfg_list *prod_list;
|
||||
|
||||
@@ -1,5 +1,7 @@
|
||||
// SPDX-License-Identifier: GPL-2.0-only
|
||||
// SPDX-FileCopyrightText: Copyright (c) 2022-2025 NVIDIA CORPORATION & AFFILIATES. All rights reserved.
|
||||
/* SPDX-License-Identifier: GPL-2.0-only */
|
||||
/*
|
||||
* Copyright (c) 2022-2024, NVIDIA CORPORATION & AFFILIATES. All rights reserved.
|
||||
*/
|
||||
|
||||
#include <nvidia/conftest.h>
|
||||
|
||||
@@ -10,7 +12,7 @@
|
||||
#define CAN_MSG_FLUSH_TIMEOUT 100
|
||||
static void mttcan_start(struct net_device *dev);
|
||||
|
||||
#if defined(CONFIG_TEGRA_PROD_NEXT_GEN)
|
||||
#if LINUX_VERSION_CODE >= KERNEL_VERSION(5, 16, 0)
|
||||
#define MTTCAN_PROD_FIELD(name, rindex, roffset, fname) \
|
||||
{ \
|
||||
.field_name = name, \
|
||||
@@ -1877,7 +1879,7 @@ static int mttcan_probe(struct platform_device *pdev)
|
||||
if (ret)
|
||||
goto exit_free_device;
|
||||
|
||||
#if !defined(CONFIG_TEGRA_PROD_NEXT_GEN)
|
||||
#if LINUX_VERSION_CODE < KERNEL_VERSION(5, 16, 0)
|
||||
priv->ttcan->prod_list = devm_tegra_prod_get(&pdev->dev);
|
||||
#else
|
||||
priv->ttcan->prod_list = devm_tegra_prod_get_list(&pdev->dev, &mttcan_prod_dev_info);
|
||||
@@ -1933,11 +1935,7 @@ static int mttcan_remove(struct platform_device *pdev)
|
||||
|
||||
dev_info(&dev->dev, "%s\n", __func__);
|
||||
|
||||
#if defined(NV_TIMER_DELETE_PRESENT) /* Linux v6.15 */
|
||||
timer_delete_sync(&priv->timer);
|
||||
#else
|
||||
del_timer_sync(&priv->timer);
|
||||
#endif
|
||||
mttcan_delete_sys_files(&dev->dev);
|
||||
unregister_mttcan_dev(dev);
|
||||
mttcan_unprepare_clock(priv);
|
||||
@@ -2011,18 +2009,6 @@ static int mttcan_resume(struct platform_device *pdev)
|
||||
}
|
||||
#endif
|
||||
|
||||
#if defined(NV_PLATFORM_DRIVER_STRUCT_REMOVE_RETURNS_VOID) /* Linux v6.11 */
|
||||
static void mttcan_remove_wrapper(struct platform_device *pdev)
|
||||
{
|
||||
mttcan_remove(pdev);
|
||||
}
|
||||
#else
|
||||
static int mttcan_remove_wrapper(struct platform_device *pdev)
|
||||
{
|
||||
return mttcan_remove(pdev);
|
||||
}
|
||||
#endif
|
||||
|
||||
static struct platform_driver mttcan_plat_driver = {
|
||||
.driver = {
|
||||
.name = KBUILD_MODNAME,
|
||||
@@ -2030,7 +2016,7 @@ static struct platform_driver mttcan_plat_driver = {
|
||||
.of_match_table = of_match_ptr(mttcan_of_table),
|
||||
},
|
||||
.probe = mttcan_probe,
|
||||
.remove = mttcan_remove_wrapper,
|
||||
.remove = mttcan_remove,
|
||||
#ifdef CONFIG_PM
|
||||
.suspend = mttcan_suspend,
|
||||
.resume = mttcan_resume,
|
||||
|
||||
@@ -1,4 +0,0 @@
|
||||
# SPDX-FileCopyrightText: Copyright (c) 2024 NVIDIA CORPORATION & AFFILIATES. All rights reserved.
|
||||
# SPDX-License-Identifier: GPL-2.0
|
||||
|
||||
nvethernetrm
|
||||
@@ -59,9 +59,5 @@ nvethernet-objs:= ether_linux.o \
|
||||
|
||||
include $(srctree.nvidia-oot)/drivers/net/ethernet/nvidia/nvethernet/nvethernetrm/include/config.tmk
|
||||
|
||||
ifeq ($(NV_BUILD_CONFIGURATION_IS_VLTEST),1)
|
||||
ccflags-y += -DNV_VLTEST_BUILD
|
||||
endif
|
||||
|
||||
# Undefine HSI_SUPPORT if CONFIG_TEGRA_EPL is not defined.
|
||||
ccflags-y += $(if $(CONFIG_TEGRA_EPL),,-UHSI_SUPPORT)
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
// SPDX-License-Identifier: GPL-2.0-only
|
||||
// SPDX-FileCopyrightText: Copyright (c) 2019-2025 NVIDIA CORPORATION & AFFILIATES. All rights reserved.
|
||||
// SPDX-FileCopyrightText: Copyright (c) 2019-2024, NVIDIA CORPORATION & AFFILIATES. All rights reserved.
|
||||
|
||||
#include <nvidia/conftest.h>
|
||||
|
||||
@@ -339,9 +339,8 @@ static inline void ether_hsi_work_func(struct work_struct *work)
|
||||
mutex_unlock(&pdata->hsi_lock);
|
||||
}
|
||||
|
||||
if (osi_core->hsi.enabled == OSI_ENABLE &&
|
||||
(osi_core->hsi.report_err == OSI_ENABLE ||
|
||||
osi_core->hsi.macsec_report_err == OSI_ENABLE))
|
||||
if (osi_core->hsi.report_err == OSI_ENABLE ||
|
||||
osi_core->hsi.macsec_report_err == OSI_ENABLE)
|
||||
ether_common_isr_thread(0, (void *)pdata);
|
||||
|
||||
schedule_delayed_work(&pdata->ether_hsi_work,
|
||||
@@ -2449,18 +2448,15 @@ static int ether_mdio_write(struct mii_bus *bus, int phyaddr, int phyreg,
|
||||
{
|
||||
struct net_device *ndev = bus->priv;
|
||||
struct ether_priv_data *pdata = netdev_priv(ndev);
|
||||
int ret = 0;
|
||||
|
||||
if (!pdata->clks_enable) {
|
||||
dev_err(pdata->dev,
|
||||
"%s:No clks available, skipping PHY write\n", __func__);
|
||||
return -ENODEV;
|
||||
}
|
||||
mutex_lock(&pdata->osi_mdio_lock);
|
||||
ret = osi_write_phy_reg(pdata->osi_core, (unsigned int)phyaddr, (unsigned int)phyreg, phydata);
|
||||
mutex_unlock(&pdata->osi_mdio_lock);
|
||||
|
||||
return ret;
|
||||
return osi_write_phy_reg(pdata->osi_core, (unsigned int)phyaddr,
|
||||
(unsigned int)phyreg, phydata);
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -2482,18 +2478,15 @@ static int ether_mdio_read(struct mii_bus *bus, int phyaddr, int phyreg)
|
||||
{
|
||||
struct net_device *ndev = bus->priv;
|
||||
struct ether_priv_data *pdata = netdev_priv(ndev);
|
||||
int ret = 0;
|
||||
|
||||
if (!pdata->clks_enable) {
|
||||
dev_err(pdata->dev,
|
||||
"%s:No clks available, skipping PHY read\n", __func__);
|
||||
return -ENODEV;
|
||||
}
|
||||
mutex_lock(&pdata->osi_mdio_lock);
|
||||
ret = osi_read_phy_reg(pdata->osi_core, (unsigned int)phyaddr, (unsigned int)phyreg);
|
||||
mutex_unlock(&pdata->osi_mdio_lock);
|
||||
|
||||
return ret;
|
||||
return osi_read_phy_reg(pdata->osi_core, (unsigned int)phyaddr,
|
||||
(unsigned int)phyreg);
|
||||
}
|
||||
|
||||
#if defined(NV_MII_BUS_STRUCT_HAS_WRITE_C45) /* Linux v6.3 */
|
||||
@@ -2956,11 +2949,7 @@ static int ether_close(struct net_device *ndev)
|
||||
int i;
|
||||
|
||||
#ifdef ETHER_NVGRO
|
||||
#if defined(NV_TIMER_DELETE_PRESENT) /* Linux v6.15 */
|
||||
timer_delete_sync(&pdata->nvgro_timer);
|
||||
#else
|
||||
del_timer_sync(&pdata->nvgro_timer);
|
||||
#endif
|
||||
/* TODO: purge the queues */
|
||||
#endif
|
||||
|
||||
@@ -3808,9 +3797,7 @@ static int ether_handle_priv_rmdio_ioctl(struct ether_priv_data *pdata,
|
||||
dev_dbg(pdata->dev, "%s: phy_id:%d regadd: %d devaddr:%d\n",
|
||||
__func__, mii_data->phy_id, prtad, devad);
|
||||
|
||||
mutex_lock(&pdata->osi_mdio_lock);
|
||||
ret = osi_read_phy_reg(pdata->osi_core, prtad, devad);
|
||||
mutex_unlock(&pdata->osi_mdio_lock);
|
||||
if (ret < 0) {
|
||||
dev_err(pdata->dev, "%s: Data read failed\n", __func__);
|
||||
return -EFAULT;
|
||||
@@ -3838,7 +3825,6 @@ static int ether_handle_priv_wmdio_ioctl(struct ether_priv_data *pdata,
|
||||
{
|
||||
struct mii_ioctl_data *mii_data = if_mii(ifr);
|
||||
unsigned int prtad, devad;
|
||||
int ret = 0;
|
||||
|
||||
if (mdio_phy_id_is_c45(mii_data->phy_id)) {
|
||||
prtad = mdio_phy_id_prtad(mii_data->phy_id);
|
||||
@@ -3852,11 +3838,8 @@ static int ether_handle_priv_wmdio_ioctl(struct ether_priv_data *pdata,
|
||||
dev_dbg(pdata->dev, "%s: phy_id:%d regadd: %d devaddr:%d val:%d\n",
|
||||
__func__, mii_data->phy_id, prtad, devad, mii_data->val_in);
|
||||
|
||||
mutex_lock(&pdata->osi_mdio_lock);
|
||||
ret = osi_write_phy_reg(pdata->osi_core, prtad, devad, mii_data->val_in);
|
||||
mutex_unlock(&pdata->osi_mdio_lock);
|
||||
|
||||
return ret;
|
||||
return osi_write_phy_reg(pdata->osi_core, prtad, devad,
|
||||
mii_data->val_in);
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -5807,13 +5790,6 @@ static int ether_parse_dt(struct ether_priv_data *pdata)
|
||||
}
|
||||
}
|
||||
|
||||
/* Read MAC instance id */
|
||||
ret = of_property_read_u32(np, "nvidia,instance_id", &osi_core->instance_id);
|
||||
if (ret != 0) {
|
||||
dev_info(dev, "DT instance_id missing\n");
|
||||
return -EINVAL;
|
||||
}
|
||||
|
||||
if (osi_dma->num_dma_chans != osi_core->num_mtl_queues) {
|
||||
dev_err(dev, "mismatch in numbers of DMA channel and MTL Q\n");
|
||||
return -EINVAL;
|
||||
@@ -6564,8 +6540,6 @@ static int ether_probe(struct platform_device *pdev)
|
||||
osi_core->osd = pdata;
|
||||
osi_dma->osd = pdata;
|
||||
|
||||
mutex_init(&pdata->osi_mdio_lock);
|
||||
|
||||
osi_core->num_mtl_queues = num_mtl_queues;
|
||||
osi_dma->num_dma_chans = num_dma_chans;
|
||||
|
||||
@@ -6673,16 +6647,10 @@ static int ether_probe(struct platform_device *pdev)
|
||||
chan = osi_dma->dma_chans[i];
|
||||
atomic_set(&pdata->tx_napi[chan]->tx_usecs_timer_armed,
|
||||
OSI_DISABLE);
|
||||
#if defined(NV_HRTIMER_SETUP_PRESENT) /* Linux v6.13 */
|
||||
hrtimer_setup(&pdata->tx_napi[chan]->tx_usecs_timer,
|
||||
ether_tx_usecs_hrtimer, CLOCK_MONOTONIC,
|
||||
HRTIMER_MODE_REL);
|
||||
#else
|
||||
hrtimer_init(&pdata->tx_napi[chan]->tx_usecs_timer,
|
||||
CLOCK_MONOTONIC, HRTIMER_MODE_REL);
|
||||
pdata->tx_napi[chan]->tx_usecs_timer.function =
|
||||
ether_tx_usecs_hrtimer;
|
||||
#endif
|
||||
}
|
||||
|
||||
ret = register_netdev(ndev);
|
||||
@@ -6855,107 +6823,6 @@ static void ether_shutdown(struct platform_device *pdev)
|
||||
}
|
||||
|
||||
#ifdef CONFIG_PM
|
||||
#ifndef OSI_STRIPPED_LIB
|
||||
/**
|
||||
* @brief Revert the WOL settings
|
||||
*
|
||||
* Alogorithm: Create a struct ethtool_wolinfo to disable WOL settings
|
||||
*
|
||||
* @param[in] dev: Platform device associated with platform driver.
|
||||
*
|
||||
* @retval 0 on success
|
||||
* @retval "negative value" on failure.
|
||||
*/
|
||||
static inline int ether_revert_wol(struct device *dev)
|
||||
{
|
||||
int ret = 0;
|
||||
u32 wolopts = 0;
|
||||
struct net_device *ndev = dev_get_drvdata(dev);
|
||||
struct ether_priv_data *pdata = netdev_priv(ndev);
|
||||
|
||||
swap(pdata->wol.wolopts, wolopts);
|
||||
ret = ether_set_wol_impl(ndev, &pdata->wol);
|
||||
pdata->wol.wolopts = wolopts;
|
||||
if (ret)
|
||||
dev_err(pdata->dev, "Fail to enable PHY network functionality %d\n", ret);
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Ethernet platform driver prepare callback.
|
||||
*
|
||||
* Alogorithm: Configure the defer WOL settings if enabled by user
|
||||
*
|
||||
* @param[in] dev: Platform device associated with platform driver.
|
||||
*
|
||||
* @retval 0 on success
|
||||
* @retval "negative value" on failure.
|
||||
*/
|
||||
static int ether_prepare(struct device *dev)
|
||||
{
|
||||
int ret = 0;
|
||||
struct net_device *ndev = dev_get_drvdata(dev);
|
||||
struct ether_priv_data *pdata = netdev_priv(ndev);
|
||||
struct phy_device *phydev = pdata->phydev;
|
||||
|
||||
if (pdata->wol.wolopts) {
|
||||
ret = ether_set_wol_impl(ndev, &pdata->wol);
|
||||
if (ret)
|
||||
goto ether_prepare_fail;
|
||||
|
||||
ret = enable_irq_wake(phydev->irq);
|
||||
if (ret) {
|
||||
dev_err(pdata->dev, "PHY enable irq wake failed, %d\n",
|
||||
ret);
|
||||
goto ether_prepare_fail;
|
||||
}
|
||||
/* enable device wake on WoL set */
|
||||
device_init_wakeup(&ndev->dev, true);
|
||||
}
|
||||
|
||||
ether_prepare_fail:
|
||||
if (unlikely(ret))
|
||||
ether_revert_wol(dev);
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Ethernet platform driver complete callback.
|
||||
*
|
||||
* Alogorithm: Revert the defer WOL settings if enabled by user
|
||||
*
|
||||
* @param[in] dev: Platform device associated with platform driver.
|
||||
*/
|
||||
static void ether_complete(struct device *dev)
|
||||
{
|
||||
int ret;
|
||||
struct net_device *ndev = dev_get_drvdata(dev);
|
||||
struct ether_priv_data *pdata = netdev_priv(ndev);
|
||||
struct phy_device *phydev = pdata->phydev;
|
||||
|
||||
if (pdata->wol.wolopts) {
|
||||
ret = ether_revert_wol(dev);
|
||||
if (ret) {
|
||||
dev_err(pdata->dev, "Fail to enable PHY network functionality %d\n", ret);
|
||||
return;
|
||||
}
|
||||
|
||||
ret = disable_irq_wake(phydev->irq);
|
||||
if (ret) {
|
||||
dev_info(pdata->dev,
|
||||
"PHY disable irq wake failed, %d\n",
|
||||
ret);
|
||||
}
|
||||
/* disable device wake on WoL reset */
|
||||
device_init_wakeup(&ndev->dev, false);
|
||||
}
|
||||
|
||||
return;
|
||||
}
|
||||
#endif /* !(OSI_STRIPPED_LIB) */
|
||||
|
||||
/**
|
||||
* @brief Ethernet platform driver resume call.
|
||||
*
|
||||
@@ -7160,14 +7027,10 @@ static int ether_resume_noirq(struct device *dev)
|
||||
return ret;
|
||||
}
|
||||
|
||||
return ret;
|
||||
return 0;
|
||||
}
|
||||
|
||||
static const struct dev_pm_ops ether_pm_ops = {
|
||||
#ifndef OSI_STRIPPED_LIB
|
||||
.prepare = ether_prepare,
|
||||
.complete = ether_complete,
|
||||
#endif /* !OSI_STRIPPED_LIB */
|
||||
.suspend = ether_suspend_noirq,
|
||||
.resume = ether_resume_noirq,
|
||||
};
|
||||
@@ -7185,24 +7048,12 @@ static const struct of_device_id ether_of_match[] = {
|
||||
};
|
||||
MODULE_DEVICE_TABLE(of, ether_of_match);
|
||||
|
||||
#if defined(NV_PLATFORM_DRIVER_STRUCT_REMOVE_RETURNS_VOID) /* Linux v6.11 */
|
||||
static void ether_remove_wrapper(struct platform_device *pdev)
|
||||
{
|
||||
ether_remove(pdev);
|
||||
}
|
||||
#else
|
||||
static int ether_remove_wrapper(struct platform_device *pdev)
|
||||
{
|
||||
return ether_remove(pdev);
|
||||
}
|
||||
#endif
|
||||
|
||||
/**
|
||||
* @brief Ethernet platform driver instance
|
||||
*/
|
||||
static struct platform_driver ether_driver = {
|
||||
.probe = ether_probe,
|
||||
.remove = ether_remove_wrapper,
|
||||
.remove = ether_remove,
|
||||
.shutdown = ether_shutdown,
|
||||
.driver = {
|
||||
.name = "nvethernet",
|
||||
|
||||
@@ -668,10 +668,6 @@ struct ether_priv_data {
|
||||
struct tasklet_struct lane_restart_task;
|
||||
/** xtra sw error counters */
|
||||
struct ether_xtra_stat_counters xstats;
|
||||
/** wol configs */
|
||||
struct ethtool_wolinfo wol;
|
||||
/** MDIO lock for OSI function calls **/
|
||||
struct mutex osi_mdio_lock;
|
||||
};
|
||||
|
||||
/**
|
||||
@@ -682,21 +678,6 @@ struct ether_priv_data {
|
||||
* @note Network device needs to created.
|
||||
*/
|
||||
void ether_set_ethtool_ops(struct net_device *ndev);
|
||||
|
||||
/**
|
||||
* @brief Configure WOL settings in PHY subsystem
|
||||
*
|
||||
* @param[in] ndev – pointer to net device structure.
|
||||
* @param[in] wol – pointer to ethtool_wolinfo structure.
|
||||
*
|
||||
* @note MAC and PHY need to be initialized.
|
||||
*
|
||||
* @retval zero on success and -ve number on failure.
|
||||
*/
|
||||
|
||||
int ether_set_wol_impl(struct net_device *ndev, struct ethtool_wolinfo *wol);
|
||||
|
||||
|
||||
/**
|
||||
* @brief Creates Ethernet sysfs group
|
||||
*
|
||||
|
||||
@@ -1336,38 +1336,6 @@ static int ether_set_eee(struct net_device *ndev,
|
||||
return 0;
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Configure WOL settings in PHY subsystem
|
||||
*
|
||||
* Algorithm: Call phy subsystem to enable or disable
|
||||
* Wake On Lan settings based on wol param
|
||||
*
|
||||
* @param[in] ndev – pointer to net device structure.
|
||||
* @param[in] wol – pointer to ethtool_wolinfo structure.
|
||||
*
|
||||
* @note MAC and PHY need to be initialized.
|
||||
*
|
||||
* @retval zero on success and -ve number on failure.
|
||||
*/
|
||||
|
||||
int ether_set_wol_impl(struct net_device *ndev, struct ethtool_wolinfo *wol)
|
||||
{
|
||||
struct ether_priv_data *pdata = netdev_priv(ndev);
|
||||
struct phy_device *phydev = pdata->phydev;
|
||||
|
||||
if (!phydev) {
|
||||
netdev_err(pdata->ndev,
|
||||
"%s: phydev is null check iface up status\n",
|
||||
__func__);
|
||||
return -ENOTSUPP;
|
||||
}
|
||||
|
||||
if (!phy_interrupt_is_valid(phydev))
|
||||
return -ENOTSUPP;
|
||||
|
||||
return phy_ethtool_set_wol(pdata->phydev, wol);
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief This function is invoked by kernel when user request to set
|
||||
* pmt parameters for remote wakeup or magic wakeup
|
||||
@@ -1383,24 +1351,46 @@ int ether_set_wol_impl(struct net_device *ndev, struct ethtool_wolinfo *wol)
|
||||
*/
|
||||
static int ether_set_wol(struct net_device *ndev, struct ethtool_wolinfo *wol)
|
||||
{
|
||||
int ret = 0;
|
||||
struct ether_priv_data *pdata = netdev_priv(ndev);
|
||||
int ret;
|
||||
|
||||
if (!wol)
|
||||
return -EINVAL;
|
||||
|
||||
/* Disable WOL on demand.
|
||||
* Enabling WOL will to deferred to before system suspend.
|
||||
*/
|
||||
if (wol->wolopts) {
|
||||
/* The WOL request to the PHY layer is defered, and will apply on
|
||||
* it only when the system is going to suspend. */
|
||||
memcpy(&pdata->wol, wol, sizeof(struct ethtool_wolinfo));
|
||||
|
||||
} else {
|
||||
/* Set wolopts to 0 to implicitly say that WOL is disabled */
|
||||
pdata->wol.wolopts = 0;
|
||||
ret = ether_set_wol_impl(ndev, wol);
|
||||
if (!pdata->phydev) {
|
||||
netdev_err(pdata->ndev,
|
||||
"%s: phydev is null check iface up status\n",
|
||||
__func__);
|
||||
return -ENOTSUPP;
|
||||
}
|
||||
|
||||
if (!phy_interrupt_is_valid(pdata->phydev))
|
||||
return -ENOTSUPP;
|
||||
|
||||
ret = phy_ethtool_set_wol(pdata->phydev, wol);
|
||||
if (ret < 0)
|
||||
return ret;
|
||||
|
||||
if (wol->wolopts) {
|
||||
ret = enable_irq_wake(pdata->phydev->irq);
|
||||
if (ret) {
|
||||
dev_err(pdata->dev, "PHY enable irq wake failed, %d\n",
|
||||
ret);
|
||||
return ret;
|
||||
}
|
||||
/* enable device wake on WoL set */
|
||||
device_init_wakeup(&ndev->dev, true);
|
||||
} else {
|
||||
ret = disable_irq_wake(pdata->phydev->irq);
|
||||
if (ret) {
|
||||
dev_info(pdata->dev,
|
||||
"PHY disable irq wake failed, %d\n",
|
||||
ret);
|
||||
}
|
||||
/* disable device wake on WoL reset */
|
||||
device_init_wakeup(&ndev->dev, false);
|
||||
}
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
@@ -1421,7 +1411,6 @@ static int ether_set_wol(struct net_device *ndev, struct ethtool_wolinfo *wol)
|
||||
static void ether_get_wol(struct net_device *ndev, struct ethtool_wolinfo *wol)
|
||||
{
|
||||
struct ether_priv_data *pdata = netdev_priv(ndev);
|
||||
u32 wolopts;
|
||||
|
||||
if (!wol)
|
||||
return;
|
||||
@@ -1433,20 +1422,13 @@ static void ether_get_wol(struct net_device *ndev, struct ethtool_wolinfo *wol)
|
||||
return;
|
||||
}
|
||||
|
||||
wol->supported = 0;
|
||||
wol->wolopts = 0;
|
||||
|
||||
if (!phy_interrupt_is_valid(pdata->phydev))
|
||||
return;
|
||||
|
||||
wolopts = pdata->wol.wolopts;
|
||||
|
||||
pdata->wol.supported = 0;
|
||||
pdata->wol.wolopts = 0;
|
||||
|
||||
phy_ethtool_get_wol(pdata->phydev, &pdata->wol);
|
||||
|
||||
if (wolopts & WAKE_MAGIC) {
|
||||
pdata->wol.wolopts |= WAKE_MAGIC;
|
||||
}
|
||||
memcpy(wol, &pdata->wol, sizeof(struct ethtool_wolinfo));
|
||||
phy_ethtool_get_wol(pdata->phydev, wol);
|
||||
}
|
||||
|
||||
/**
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
// SPDX-License-Identifier: GPL-2.0-only
|
||||
/* Copyright (c) 2019-2025, NVIDIA CORPORATION. All rights reserved */
|
||||
/* Copyright (c) 2019-2023, NVIDIA CORPORATION. All rights reserved */
|
||||
|
||||
#ifdef MACSEC_SUPPORT
|
||||
#include "ether_linux.h"
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
// SPDX-License-Identifier: GPL-2.0-only
|
||||
// SPDX-FileCopyrightText: Copyright (c) 2019-2025, NVIDIA CORPORATION & AFFILIATES. All rights reserved
|
||||
/* Copyright (c) 2019-2022, NVIDIA CORPORATION & AFFILIATES. All rights reserved */
|
||||
|
||||
#ifndef OSI_STRIPPED_LIB
|
||||
#include "ether_linux.h"
|
||||
@@ -290,11 +290,7 @@ static int ether_test_phy_loopback(struct ether_priv_data *pdata)
|
||||
if (!pdata->phydev)
|
||||
return -ENODEV;
|
||||
|
||||
#if defined(NV_PHY_LOOPBACK_HAS_SPEED_ARG) /* Linux v6.15 */
|
||||
ret = phy_loopback(pdata->phydev, true, 0);
|
||||
#else
|
||||
ret = phy_loopback(pdata->phydev, true);
|
||||
#endif
|
||||
if (ret != 0 && ret != -EBUSY)
|
||||
return ret;
|
||||
|
||||
@@ -410,11 +406,7 @@ void ether_selftest_run(struct net_device *dev,
|
||||
case ETHER_LOOPBACK_PHY:
|
||||
ret = -EOPNOTSUPP;
|
||||
if (dev->phydev)
|
||||
#if defined(NV_PHY_LOOPBACK_HAS_SPEED_ARG) /* Linux v6.15 */
|
||||
ret = phy_loopback(dev->phydev, true, 0);
|
||||
#else
|
||||
ret = phy_loopback(dev->phydev, true);
|
||||
#endif
|
||||
if (!ret)
|
||||
break;
|
||||
/* Fallthrough */
|
||||
@@ -447,11 +439,7 @@ void ether_selftest_run(struct net_device *dev,
|
||||
case ETHER_LOOPBACK_PHY:
|
||||
ret = -EOPNOTSUPP;
|
||||
if (dev->phydev)
|
||||
#if defined(NV_PHY_LOOPBACK_HAS_SPEED_ARG) /* Linux v6.15 */
|
||||
ret = phy_loopback(dev->phydev, false, 0);
|
||||
#else
|
||||
ret = phy_loopback(dev->phydev, false);
|
||||
#endif
|
||||
if (!ret)
|
||||
break;
|
||||
/* Fallthrough */
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
// SPDX-License-Identifier: GPL-2.0-only
|
||||
/* Copyright (c) 2019-2025, NVIDIA CORPORATION & AFFILIATES. All rights reserved */
|
||||
/* Copyright (c) 2019-2023, NVIDIA CORPORATION & AFFILIATES. All rights reserved */
|
||||
|
||||
#include "ether_linux.h"
|
||||
#include "macsec.h"
|
||||
@@ -2543,7 +2543,8 @@ static DEVICE_ATTR(nvgro_dump, 0644,
|
||||
ether_nvgro_dump_show, NULL);
|
||||
#endif
|
||||
|
||||
#if defined HSI_SUPPORT && defined(NV_VLTEST_BUILD) && (IS_ENABLED(CONFIG_TEGRA_HSIERRRPTINJ))
|
||||
#ifdef HSI_SUPPORT
|
||||
#if (IS_ENABLED(CONFIG_TEGRA_HSIERRRPTINJ))
|
||||
static int hsi_inject_err_fsi(unsigned int inst_id,
|
||||
struct epl_error_report_frame error_report,
|
||||
void *data)
|
||||
@@ -2561,6 +2562,7 @@ static int hsi_inject_err_fsi(unsigned int inst_id,
|
||||
|
||||
return ret;
|
||||
}
|
||||
#endif
|
||||
|
||||
/**
|
||||
* @brief Shows HSI feature enabled status
|
||||
@@ -2609,8 +2611,10 @@ static ssize_t hsi_enable_store(struct device *dev,
|
||||
struct osi_core_priv_data *osi_core = pdata->osi_core;
|
||||
struct osi_ioctl ioctl_data = {};
|
||||
int ret = 0;
|
||||
#if (IS_ENABLED(CONFIG_TEGRA_HSIERRRPTINJ))
|
||||
u32 inst_id = osi_core->instance_id;
|
||||
u32 ip_type[2] = {IP_EQOS, IP_MGBE};
|
||||
#endif
|
||||
|
||||
if (osi_core->use_virtualization == OSI_ENABLE) {
|
||||
dev_err(pdata->dev, "Not supported with Ethernet virtualization enabled\n");
|
||||
@@ -2632,6 +2636,7 @@ static ssize_t hsi_enable_store(struct device *dev,
|
||||
} else {
|
||||
osi_core->hsi.enabled = OSI_ENABLE;
|
||||
dev_info(pdata->dev, "HSI Enabled\n");
|
||||
#if (IS_ENABLED(CONFIG_TEGRA_HSIERRRPTINJ))
|
||||
if (osi_core->instance_id == OSI_INSTANCE_ID_EQOS)
|
||||
inst_id = 0;
|
||||
|
||||
@@ -2641,6 +2646,7 @@ static ssize_t hsi_enable_store(struct device *dev,
|
||||
dev_err(pdata->dev, "Err inj callback registration failed: %d",
|
||||
ret);
|
||||
}
|
||||
#endif
|
||||
}
|
||||
} else if (strncmp(buf, "disable", 7) == OSI_NONE) {
|
||||
ioctl_data.arg1_u32 = OSI_DISABLE;
|
||||
@@ -2651,6 +2657,7 @@ static ssize_t hsi_enable_store(struct device *dev,
|
||||
} else {
|
||||
osi_core->hsi.enabled = OSI_DISABLE;
|
||||
dev_info(pdata->dev, "HSI Disabled\n");
|
||||
#if (IS_ENABLED(CONFIG_TEGRA_HSIERRRPTINJ))
|
||||
if (osi_core->instance_id == OSI_INSTANCE_ID_EQOS)
|
||||
inst_id = 0;
|
||||
|
||||
@@ -2659,6 +2666,7 @@ static ssize_t hsi_enable_store(struct device *dev,
|
||||
dev_err(pdata->dev, "Err inj callback deregistration failed: %d",
|
||||
ret);
|
||||
}
|
||||
#endif
|
||||
}
|
||||
} else {
|
||||
dev_err(pdata->dev,
|
||||
@@ -2720,40 +2728,13 @@ static struct attribute *ether_sysfs_attrs[] = {
|
||||
&dev_attr_nvgro_stats.attr,
|
||||
&dev_attr_nvgro_dump.attr,
|
||||
#endif
|
||||
#if defined HSI_SUPPORT && defined(NV_VLTEST_BUILD) && (IS_ENABLED(CONFIG_TEGRA_HSIERRRPTINJ))
|
||||
#ifdef HSI_SUPPORT
|
||||
&dev_attr_hsi_enable.attr,
|
||||
#endif
|
||||
#endif /* OSI_STRIPPED_LIB */
|
||||
NULL
|
||||
};
|
||||
|
||||
/**
|
||||
* @brief Attributes for nvethernet sysfs without MACSEC
|
||||
*/
|
||||
static struct attribute *ether_sysfs_attrs_without_macsec[] = {
|
||||
#ifndef OSI_STRIPPED_LIB
|
||||
#ifdef OSI_DEBUG
|
||||
&dev_attr_desc_dump_enable.attr,
|
||||
#endif /* OSI_DEBUG */
|
||||
&dev_attr_mac_loopback.attr,
|
||||
&dev_attr_ptp_mode.attr,
|
||||
&dev_attr_ptp_sync.attr,
|
||||
&dev_attr_frp.attr,
|
||||
&dev_attr_uphy_gbe_mode.attr,
|
||||
&dev_attr_phy_iface_mode.attr,
|
||||
#ifdef ETHER_NVGRO
|
||||
&dev_attr_nvgro_pkt_age_msec.attr,
|
||||
&dev_attr_nvgro_timer_interval.attr,
|
||||
&dev_attr_nvgro_stats.attr,
|
||||
&dev_attr_nvgro_dump.attr,
|
||||
#endif
|
||||
#endif /* OSI_STRIPPED_LIB */
|
||||
#if defined HSI_SUPPORT && defined(NV_VLTEST_BUILD) && (IS_ENABLED(CONFIG_TEGRA_HSIERRRPTINJ))
|
||||
&dev_attr_hsi_enable.attr,
|
||||
#endif
|
||||
NULL
|
||||
};
|
||||
|
||||
/**
|
||||
* @brief Ethernet sysfs attribute group
|
||||
*/
|
||||
@@ -2762,14 +2743,6 @@ static struct attribute_group ether_attribute_group = {
|
||||
.attrs = ether_sysfs_attrs,
|
||||
};
|
||||
|
||||
/**
|
||||
* @brief Ethernet sysfs attribute group without macsec
|
||||
*/
|
||||
static struct attribute_group ether_attribute_group_wo_macsec = {
|
||||
.name = "nvethernet",
|
||||
.attrs = ether_sysfs_attrs_without_macsec,
|
||||
};
|
||||
|
||||
#ifndef OSI_STRIPPED_LIB
|
||||
#ifdef CONFIG_DEBUG_FS
|
||||
static char *timestamp_system_source(unsigned int source)
|
||||
@@ -3358,10 +3331,7 @@ int ether_sysfs_register(struct ether_priv_data *pdata)
|
||||
#endif /* OSI_STRIPPED_LIB */
|
||||
|
||||
/* Create nvethernet sysfs group under /sys/devices/<ether_device>/ */
|
||||
if (pdata->macsec_pdata)
|
||||
return sysfs_create_group(&dev->kobj, ðer_attribute_group);
|
||||
else
|
||||
return sysfs_create_group(&dev->kobj, ðer_attribute_group_wo_macsec);
|
||||
return sysfs_create_group(&dev->kobj, ðer_attribute_group);
|
||||
}
|
||||
|
||||
void ether_sysfs_unregister(struct ether_priv_data *pdata)
|
||||
@@ -3373,8 +3343,5 @@ void ether_sysfs_unregister(struct ether_priv_data *pdata)
|
||||
#endif
|
||||
#endif /* OSI_STRIPPED_LIB */
|
||||
/* Remove nvethernet sysfs group under /sys/devices/<ether_device>/ */
|
||||
if (pdata->macsec_pdata)
|
||||
sysfs_remove_group(&dev->kobj, ðer_attribute_group);
|
||||
else
|
||||
sysfs_remove_group(&dev->kobj, ðer_attribute_group_wo_macsec);
|
||||
sysfs_remove_group(&dev->kobj, ðer_attribute_group);
|
||||
}
|
||||
|
||||
@@ -28435,8 +28435,7 @@ rtl8168_init_one(struct pci_dev *pdev,
|
||||
struct rtl8168_private *tp;
|
||||
void __iomem *ioaddr = NULL;
|
||||
static int board_idx = -1;
|
||||
u16 desired_mps = 128;
|
||||
u32 desired_mrrs = 512;
|
||||
|
||||
int rc;
|
||||
|
||||
assert(pdev != NULL);
|
||||
@@ -28599,22 +28598,6 @@ rtl8168_init_one(struct pci_dev *pdev,
|
||||
|
||||
rtl8168_hw_reset(dev);
|
||||
|
||||
/* Set Maximum Payload Size (MPS) */
|
||||
rc = pcie_set_mps(pdev->bus->self, desired_mps);
|
||||
if (rc) {
|
||||
dev_err(&pdev->bus->self->dev, "Failed to set MPS to %u (error %d)\n",
|
||||
desired_mps, rc);
|
||||
return rc;
|
||||
}
|
||||
|
||||
/* Set Maximum Read Request Size (MRRS) */
|
||||
rc = pcie_set_readrq(pdev->bus->self, desired_mrrs);
|
||||
if (rc) {
|
||||
dev_err(&pdev->bus->self->dev, "Failed to set MRRS to %u (error %d)\n",
|
||||
desired_mrrs, rc);
|
||||
return rc;
|
||||
}
|
||||
|
||||
/* Get production from EEPROM */
|
||||
if (((tp->mcfg == CFG_METHOD_21 || tp->mcfg == CFG_METHOD_22 ||
|
||||
tp->mcfg == CFG_METHOD_25 || tp->mcfg == CFG_METHOD_29 ||
|
||||
|
||||
@@ -1,18 +1,10 @@
|
||||
# SPDX-License-Identifier: GPL-2.0-only
|
||||
# SPDX-FileCopyrightText: Copyright (c) 2022-2024 NVIDIA CORPORATION & AFFILIATES. All rights reserved.
|
||||
|
||||
LINUX_VERSION := $(shell expr $(VERSION) \* 256 + $(PATCHLEVEL))
|
||||
LINUX_VERSION_6_6 := $(shell expr 6 \* 256 + 6)
|
||||
|
||||
ifeq ($(findstring ack_src,$(NV_BUILD_KERNEL_OPTIONS)),)
|
||||
ifeq ($(VERSION).$(PATCHLEVEL),5.15)
|
||||
ifneq ($(NV_OOT_REALTEK_RTL8822CE_SKIP_BUILD),y)
|
||||
obj-m += rtl8822ce/
|
||||
endif
|
||||
endif
|
||||
ifneq ($(NV_OOT_REALTEK_RTL8852CE_SKIP_BUILD),y)
|
||||
ifeq ($(shell test $(LINUX_VERSION) -lt $(LINUX_VERSION_6_6); echo $$?),0)
|
||||
obj-m += rtl8852ce/
|
||||
endif
|
||||
endif
|
||||
endif
|
||||
|
||||
@@ -115,7 +115,7 @@ CONFIG_RTW_LOG_LEVEL = 0
|
||||
CONFIG_PROC_DEBUG = y
|
||||
|
||||
######################## Wake On Lan ##########################
|
||||
CONFIG_WOWLAN = y
|
||||
CONFIG_WOWLAN = n
|
||||
#bit2: deauth, bit1: unicast, bit0: magic pkt.
|
||||
CONFIG_WAKEUP_TYPE = 0x7
|
||||
CONFIG_WOW_LPS_MODE = default
|
||||
|
||||
@@ -13,8 +13,6 @@
|
||||
*
|
||||
*****************************************************************************/
|
||||
|
||||
#include <nvidia/conftest.h>
|
||||
|
||||
#ifdef CONFIG_GPIO_WAKEUP
|
||||
#include <linux/gpio.h>
|
||||
#endif
|
||||
@@ -1277,22 +1275,10 @@ static int wifi_resume(struct platform_device *pdev)
|
||||
return 0;
|
||||
}
|
||||
|
||||
#if defined(NV_PLATFORM_DRIVER_STRUCT_REMOVE_RETURNS_VOID) /* Linux v6.11 */
|
||||
static inline void wifi_remove_wrapper(struct platform_device *pdev)
|
||||
{
|
||||
wifi_remove(pdev);
|
||||
}
|
||||
#else
|
||||
static inline int wifi_remove_wrapper(struct platform_device *pdev)
|
||||
{
|
||||
return wifi_remove(pdev);
|
||||
}
|
||||
#endif
|
||||
|
||||
/* temporarily use these two */
|
||||
static struct platform_driver wifi_device = {
|
||||
.probe = wifi_probe,
|
||||
.remove = wifi_remove_wrapper,
|
||||
.remove = wifi_remove,
|
||||
.suspend = wifi_suspend,
|
||||
.resume = wifi_resume,
|
||||
#ifdef RTW_SUPPORT_PLATFORM_SHUTDOWN
|
||||
@@ -1303,21 +1289,9 @@ static struct platform_driver wifi_device = {
|
||||
}
|
||||
};
|
||||
|
||||
#if defined(NV_PLATFORM_DRIVER_STRUCT_REMOVE_RETURNS_VOID) /* Linux v6.11 */
|
||||
static inline void wifi_remove_wrapper(struct platform_device *pdev)
|
||||
{
|
||||
wifi_remove(pdev);
|
||||
}
|
||||
#else
|
||||
static inline int wifi_remove_wrapper(struct platform_device *pdev)
|
||||
{
|
||||
return wifi_remove(pdev);
|
||||
}
|
||||
#endif
|
||||
|
||||
static struct platform_driver wifi_device_legacy = {
|
||||
.probe = wifi_probe,
|
||||
.remove = wifi_remove_wrapper,
|
||||
.remove = wifi_remove,
|
||||
.suspend = wifi_suspend,
|
||||
.resume = wifi_resume,
|
||||
.driver = {
|
||||
|
||||
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user