mirror of
git://nv-tegra.nvidia.com/linux-nv-oot.git
synced 2025-12-22 17:25:35 +03:00
tegra-cec: remove pre-t23x support.
This change removes pre-t23x support and removing
dependency on tegra-dc module for tegra-cec driver.
It also removes the previously used uapi header file
for user-space ioctl intefrace which will be added along
with loadable module change.
Verification:
Verified on orin-slt with basic cec tx-rx data with TV.
bug 4954851
Change-Id: Ie820ba706ac5e66da282e411a4ae74bd0e6cb58b
Signed-off-by: Prafull Suryawanshi <prafulls@nvidia.com>
Reviewed-on: https://git-master.nvidia.com/r/c/linux-nv-oot/+/3264311
(cherry picked from commit 0cac4c3b02)
Reviewed-on: https://git-master.nvidia.com/r/c/linux-nv-oot/+/3258901
GVS: buildbot_gerritrpt <buildbot_gerritrpt@nvidia.com>
Reviewed-by: Bitan Biswas <bbiswas@nvidia.com>
This commit is contained in:
committed by
Jon Hunter
parent
7c70fdd3f1
commit
27e8c7ae95
@@ -1,5 +1,5 @@
|
|||||||
# SPDX-License-Identifier: GPL-2.0-only
|
# SPDX-License-Identifier: GPL-2.0-only
|
||||||
# SPDX-FileCopyrightText: Copyright (c) 2022-2024 NVIDIA CORPORATION & AFFILIATES. All rights reserved.
|
# SPDX-FileCopyrightText: Copyright (c) 2022-2025 NVIDIA CORPORATION & AFFILIATES. All rights reserved.
|
||||||
|
|
||||||
# MODS is currently broken for Linux v6.11 and later
|
# MODS is currently broken for Linux v6.11 and later
|
||||||
ifndef CONFIG_TEGRA_SYSTEM_TYPE_ACK
|
ifndef CONFIG_TEGRA_SYSTEM_TYPE_ACK
|
||||||
@@ -12,3 +12,4 @@ endif
|
|||||||
obj-m += bluedroid_pm.o
|
obj-m += bluedroid_pm.o
|
||||||
obj-m += nvscic2c-pcie/
|
obj-m += nvscic2c-pcie/
|
||||||
obj-m += ioctl_example.o
|
obj-m += ioctl_example.o
|
||||||
|
obj-m += tegra-cec/
|
||||||
|
|||||||
@@ -1,9 +1,5 @@
|
|||||||
#
|
# SPDX-License-Identifier: GPL-2.0
|
||||||
# Makefile for tegra cec support.
|
# SPDX-FileCopyrightText: Copyright (c) 2022-2025 NVIDIA CORPORATION & AFFILIATES. All rights reserved.
|
||||||
#
|
|
||||||
|
|
||||||
subdir-ccflags-y = -Werror
|
subdir-ccflags-y = -Werror
|
||||||
|
obj-m += tegra_cec.o
|
||||||
ccflags-y += -I$(overlay)/drivers/video/tegra/dc
|
|
||||||
|
|
||||||
obj-$(CONFIG_TEGRA_CEC_SUPPORT) += tegra_cec.o
|
|
||||||
|
|||||||
@@ -1,20 +1,5 @@
|
|||||||
/*
|
// SPDX-License-Identifier: GPL-2.0-only
|
||||||
* drivers/misc/tegra-cec/tegra_cec.c
|
// SPDX-FileCopyrightText: Copyright (c) 2012-2025 NVIDIA CORPORATION & AFFILIATES. All rights reserved.
|
||||||
*
|
|
||||||
* Copyright (c) 2012-2022, NVIDIA CORPORATION. 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/module.h>
|
#include <linux/module.h>
|
||||||
#include <linux/kernel.h>
|
#include <linux/kernel.h>
|
||||||
@@ -33,6 +18,7 @@
|
|||||||
#include <linux/uaccess.h>
|
#include <linux/uaccess.h>
|
||||||
#include <linux/of_device.h>
|
#include <linux/of_device.h>
|
||||||
#include <linux/version.h>
|
#include <linux/version.h>
|
||||||
|
#include <linux/reset.h>
|
||||||
|
|
||||||
#include <linux/platform_device.h>
|
#include <linux/platform_device.h>
|
||||||
#include <linux/miscdevice.h>
|
#include <linux/miscdevice.h>
|
||||||
@@ -44,9 +30,6 @@
|
|||||||
#endif
|
#endif
|
||||||
#include "tegra_cec.h"
|
#include "tegra_cec.h"
|
||||||
|
|
||||||
#include "dc.h"
|
|
||||||
#include "dc_priv.h"
|
|
||||||
|
|
||||||
#define LOGICAL_ADDRESS_RESERVED2 0xD
|
#define LOGICAL_ADDRESS_RESERVED2 0xD
|
||||||
#define LOGICAL_ADDRESS_TV 0x0
|
#define LOGICAL_ADDRESS_TV 0x0
|
||||||
#define LOGICAL_ADDRESS_BROADCAST 0xF
|
#define LOGICAL_ADDRESS_BROADCAST 0xF
|
||||||
@@ -88,9 +71,6 @@ static int reset_retry_count = 5;
|
|||||||
|
|
||||||
static void tegra_cec_writel(u32 value, void __iomem *addr)
|
static void tegra_cec_writel(u32 value, void __iomem *addr)
|
||||||
{
|
{
|
||||||
/* TODO, for T23x, find out why this delay required */
|
|
||||||
if (tegra_cec_global->soc->cec_always_on)
|
|
||||||
mdelay(1);
|
|
||||||
writel(value, addr);
|
writel(value, addr);
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -140,10 +120,7 @@ static inline void tegra_cec_error_recovery(struct tegra_cec *cec)
|
|||||||
|
|
||||||
hw_ctrl = tegra_cec_readl(cec->cec_base + TEGRA_CEC_HW_CONTROL);
|
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(0x0, cec->cec_base + TEGRA_CEC_HW_CONTROL);
|
||||||
if (cec->soc->cec_always_on)
|
|
||||||
tegra_cec_writel(0xFFFFFFFE, cec->cec_base + TEGRA_CEC_INT_STAT);
|
tegra_cec_writel(0xFFFFFFFE, cec->cec_base + TEGRA_CEC_INT_STAT);
|
||||||
else
|
|
||||||
tegra_cec_writel(0xFFFFFFFF, cec->cec_base + TEGRA_CEC_INT_STAT);
|
|
||||||
tegra_cec_writel(hw_ctrl, cec->cec_base + TEGRA_CEC_HW_CONTROL);
|
tegra_cec_writel(hw_ctrl, cec->cec_base + TEGRA_CEC_HW_CONTROL);
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -337,7 +314,7 @@ static irqreturn_t tegra_cec_irq_handler(int irq, void *data)
|
|||||||
} else if (status & TEGRA_CEC_INT_STAT_RX_REGISTER_FULL) {
|
} else if (status & TEGRA_CEC_INT_STAT_RX_REGISTER_FULL) {
|
||||||
tegra_cec_writel(TEGRA_CEC_INT_STAT_RX_REGISTER_FULL,
|
tegra_cec_writel(TEGRA_CEC_INT_STAT_RX_REGISTER_FULL,
|
||||||
cec->cec_base + TEGRA_CEC_INT_STAT);
|
cec->cec_base + TEGRA_CEC_INT_STAT);
|
||||||
cec->rx_buffer = readw(cec->cec_base + TEGRA_CEC_RX_REGISTER);
|
cec->rx_buffer = tegra_cec_readl(cec->cec_base + TEGRA_CEC_RX_REGISTER);
|
||||||
cec->rx_wake = 1;
|
cec->rx_wake = 1;
|
||||||
wake_up_interruptible(&cec->rx_waitq);
|
wake_up_interruptible(&cec->rx_waitq);
|
||||||
}
|
}
|
||||||
@@ -351,7 +328,7 @@ static int tegra_cec_dump_registers(struct tegra_cec *cec)
|
|||||||
int value, i;
|
int value, i;
|
||||||
|
|
||||||
dev_info(cec->dev, "base address = %llx\n", (u64)cec->cec_base);
|
dev_info(cec->dev, "base address = %llx\n", (u64)cec->cec_base);
|
||||||
for (i = 0; i <= cec->soc->offset; i += 4) {
|
for (i = 0; i <= TEGRA_CEC_RX_OPCODE_4; i += 4) {
|
||||||
value = tegra_cec_readl(cec->cec_base + i);
|
value = tegra_cec_readl(cec->cec_base + i);
|
||||||
dev_info(cec->dev, "offset %08x: %08x\n", i, value);
|
dev_info(cec->dev, "offset %08x: %08x\n", i, value);
|
||||||
}
|
}
|
||||||
@@ -359,42 +336,6 @@ static int tegra_cec_dump_registers(struct tegra_cec *cec)
|
|||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
static int tegra_cec_unpowergate(struct tegra_cec *cec)
|
|
||||||
{
|
|
||||||
int ret = 0;
|
|
||||||
|
|
||||||
if (cec->soc->cec_always_on)
|
|
||||||
return 0;
|
|
||||||
|
|
||||||
if (!tegra_dc_is_nvdisplay())
|
|
||||||
return 0;
|
|
||||||
|
|
||||||
#if defined(CONFIG_TEGRA_POWERGATE)
|
|
||||||
ret = tegra_unpowergate_partition(cec->soc->powergate_id);
|
|
||||||
#else
|
|
||||||
ret = pm_runtime_get(cec->dev);
|
|
||||||
#endif
|
|
||||||
if (IS_ERR(ERR_PTR(ret)))
|
|
||||||
dev_err(cec->dev, "Failed to unpowergate DISP,err = %d\n", ret);
|
|
||||||
|
|
||||||
return ret;
|
|
||||||
}
|
|
||||||
|
|
||||||
static void tegra_cec_powergate(struct tegra_cec *cec)
|
|
||||||
{
|
|
||||||
if (cec->soc->cec_always_on)
|
|
||||||
return;
|
|
||||||
|
|
||||||
if (!tegra_dc_is_nvdisplay())
|
|
||||||
return;
|
|
||||||
|
|
||||||
#if defined(CONFIG_TEGRA_POWERGATE)
|
|
||||||
tegra_powergate_partition(cec->soc->powergate_id);
|
|
||||||
#else
|
|
||||||
pm_runtime_put(cec->dev);
|
|
||||||
#endif
|
|
||||||
}
|
|
||||||
|
|
||||||
static int tegra_cec_set_rx_snoop(struct tegra_cec *cec, u32 enable)
|
static int tegra_cec_set_rx_snoop(struct tegra_cec *cec, u32 enable)
|
||||||
{
|
{
|
||||||
u32 state;
|
u32 state;
|
||||||
@@ -504,21 +445,12 @@ static int tegra_cec_send_one_touch_play(struct tegra_cec *cec)
|
|||||||
|
|
||||||
text_view_on_sent = true;
|
text_view_on_sent = true;
|
||||||
|
|
||||||
if (cec->soc->use_tegra_dc) {
|
|
||||||
res = tegra_dc_get_source_physical_address(phy_address);
|
|
||||||
if (res) {
|
|
||||||
dev_notice(cec->dev, "Can't find physical address.\n");
|
|
||||||
return res;
|
|
||||||
}
|
|
||||||
} else {
|
|
||||||
/*
|
/*
|
||||||
* When tegradc is absent, UEFI suppose to write physical address
|
* UEFI writes physical address at register TEGRA_CEC_HW_SPARE during boot.
|
||||||
* at register TEGRA_CEC_HW_SPARE.
|
|
||||||
*/
|
*/
|
||||||
state = tegra_cec_readl(cec->cec_base + TEGRA_CEC_HW_SPARE);
|
state = tegra_cec_readl(cec->cec_base + TEGRA_CEC_HW_SPARE);
|
||||||
phy_address[0] = state & 0x000F;
|
phy_address[0] = state & 0x000F;
|
||||||
phy_address[1] = state & 0x00F0;
|
phy_address[1] = state & 0x00F0;
|
||||||
}
|
|
||||||
|
|
||||||
dev_info(cec->dev, "physical address: %02x:%02x.\n",
|
dev_info(cec->dev, "physical address: %02x:%02x.\n",
|
||||||
phy_address[0], phy_address[1]);
|
phy_address[0], phy_address[1]);
|
||||||
@@ -574,53 +506,6 @@ static void tegra_cec_init(struct tegra_cec *cec)
|
|||||||
|
|
||||||
cec->logical_addr = TEGRA_CEC_HWCTRL_RX_LADDR_UNREG;
|
cec->logical_addr = TEGRA_CEC_HWCTRL_RX_LADDR_UNREG;
|
||||||
|
|
||||||
/* CEC initialization settings till T194 */
|
|
||||||
if (!cec->soc->cec_always_on) {
|
|
||||||
|
|
||||||
tegra_cec_writel(0xffffffff, cec->cec_base + TEGRA_CEC_INT_STAT);
|
|
||||||
|
|
||||||
tegra_cec_writel(TEGRA_CEC_HWCTRL_RX_LADDR(cec->logical_addr) |
|
|
||||||
TEGRA_CEC_HWCTRL_TX_NAK_MODE |
|
|
||||||
TEGRA_CEC_HWCTRL_TX_RX_MODE,
|
|
||||||
cec->cec_base + TEGRA_CEC_HW_CONTROL);
|
|
||||||
|
|
||||||
tegra_cec_writel((1U << 31) | 0x20, cec->cec_base + TEGRA_CEC_INPUT_FILTER);
|
|
||||||
|
|
||||||
tegra_cec_writel((0x7a << TEGRA_CEC_RX_TIMING_0_RX_START_BIT_MAX_LO_TIME_MASK) |
|
|
||||||
(0x6d << TEGRA_CEC_RX_TIMING_0_RX_START_BIT_MIN_LO_TIME_MASK) |
|
|
||||||
(0x93 << TEGRA_CEC_RX_TIMING_0_RX_START_BIT_MAX_DURATION_MASK) |
|
|
||||||
(0x86 << TEGRA_CEC_RX_TIMING_0_RX_START_BIT_MIN_DURATION_MASK),
|
|
||||||
cec->cec_base + TEGRA_CEC_RX_TIMING_0);
|
|
||||||
|
|
||||||
tegra_cec_writel((0x35 << TEGRA_CEC_RX_TIMING_1_RX_DATA_BIT_MAX_LO_TIME_MASK) |
|
|
||||||
(0x21 << TEGRA_CEC_RX_TIMING_1_RX_DATA_BIT_SAMPLE_TIME_MASK) |
|
|
||||||
(0x56 << TEGRA_CEC_RX_TIMING_1_RX_DATA_BIT_MAX_DURATION_MASK) |
|
|
||||||
(0x40 << TEGRA_CEC_RX_TIMING_1_RX_DATA_BIT_MIN_DURATION_MASK),
|
|
||||||
cec->cec_base + TEGRA_CEC_RX_TIMING_1);
|
|
||||||
|
|
||||||
tegra_cec_writel((0x50 << TEGRA_CEC_RX_TIMING_2_RX_END_OF_BLOCK_TIME_MASK),
|
|
||||||
cec->cec_base + TEGRA_CEC_RX_TIMING_2);
|
|
||||||
|
|
||||||
tegra_cec_writel((0x74 << TEGRA_CEC_TX_TIMING_0_TX_START_BIT_LO_TIME_MASK) |
|
|
||||||
(0x8d << TEGRA_CEC_TX_TIMING_0_TX_START_BIT_DURATION_MASK) |
|
|
||||||
(0x08 << TEGRA_CEC_TX_TIMING_0_TX_BUS_XITION_TIME_MASK) |
|
|
||||||
(0x71 << TEGRA_CEC_TX_TIMING_0_TX_BUS_ERROR_LO_TIME_MASK),
|
|
||||||
cec->cec_base + TEGRA_CEC_TX_TIMING_0);
|
|
||||||
|
|
||||||
tegra_cec_writel((0x2f << TEGRA_CEC_TX_TIMING_1_TX_LO_DATA_BIT_LO_TIME_MASK) |
|
|
||||||
(0x13 << TEGRA_CEC_TX_TIMING_1_TX_HI_DATA_BIT_LO_TIME_MASK) |
|
|
||||||
(0x4b << TEGRA_CEC_TX_TIMING_1_TX_DATA_BIT_DURATION_MASK) |
|
|
||||||
(0x21 << TEGRA_CEC_TX_TIMING_1_TX_ACK_NAK_BIT_SAMPLE_TIME_MASK),
|
|
||||||
cec->cec_base + TEGRA_CEC_TX_TIMING_1);
|
|
||||||
|
|
||||||
tegra_cec_writel(
|
|
||||||
(0x07 << TEGRA_CEC_TX_TIMING_2_BUS_IDLE_TIME_ADDITIONAL_FRAME_MASK) |
|
|
||||||
(0x05 << TEGRA_CEC_TX_TIMING_2_BUS_IDLE_TIME_NEW_FRAME_MASK) |
|
|
||||||
(0x03 << TEGRA_CEC_TX_TIMING_2_BUS_IDLE_TIME_RETRY_FRAME_MASK),
|
|
||||||
cec->cec_base + TEGRA_CEC_TX_TIMING_2);
|
|
||||||
|
|
||||||
} else {
|
|
||||||
|
|
||||||
tegra_cec_writel(TEGRA_CEC_HWCTRL_RX_LADDR(cec->logical_addr),
|
tegra_cec_writel(TEGRA_CEC_HWCTRL_RX_LADDR(cec->logical_addr),
|
||||||
cec->cec_base + TEGRA_CEC_HW_CONTROL);
|
cec->cec_base + TEGRA_CEC_HW_CONTROL);
|
||||||
|
|
||||||
@@ -648,8 +533,6 @@ static void tegra_cec_init(struct tegra_cec *cec)
|
|||||||
state |= TEGRA_CEC_HWCTRL_TX_RX_MODE;
|
state |= TEGRA_CEC_HWCTRL_TX_RX_MODE;
|
||||||
tegra_cec_writel(state, cec->cec_base + TEGRA_CEC_HW_CONTROL);
|
tegra_cec_writel(state, cec->cec_base + TEGRA_CEC_HW_CONTROL);
|
||||||
|
|
||||||
}
|
|
||||||
|
|
||||||
tegra_cec_writel(TEGRA_CEC_INT_MASK_TX_REGISTER_UNDERRUN |
|
tegra_cec_writel(TEGRA_CEC_INT_MASK_TX_REGISTER_UNDERRUN |
|
||||||
TEGRA_CEC_INT_MASK_TX_FRAME_OR_BLOCK_NAKD |
|
TEGRA_CEC_INT_MASK_TX_FRAME_OR_BLOCK_NAKD |
|
||||||
TEGRA_CEC_INT_MASK_TX_ARBITRATION_FAILED |
|
TEGRA_CEC_INT_MASK_TX_ARBITRATION_FAILED |
|
||||||
@@ -709,7 +592,6 @@ static ssize_t cec_logical_addr_store(struct device *dev,
|
|||||||
dev_info(dev, "set logical address: 0x%x\n", (u32)addr);
|
dev_info(dev, "set logical address: 0x%x\n", (u32)addr);
|
||||||
cec->logical_addr = addr;
|
cec->logical_addr = addr;
|
||||||
|
|
||||||
if (cec->soc->cec_always_on) {
|
|
||||||
// clear TX_RX_MODE
|
// clear TX_RX_MODE
|
||||||
state = tegra_cec_readl(cec->cec_base + TEGRA_CEC_HW_CONTROL);
|
state = tegra_cec_readl(cec->cec_base + TEGRA_CEC_HW_CONTROL);
|
||||||
state &= ~TEGRA_CEC_HWCTRL_TX_RX_MODE;
|
state &= ~TEGRA_CEC_HWCTRL_TX_RX_MODE;
|
||||||
@@ -723,12 +605,6 @@ static ssize_t cec_logical_addr_store(struct device *dev,
|
|||||||
state = tegra_cec_readl(cec->cec_base + TEGRA_CEC_HW_CONTROL);
|
state = tegra_cec_readl(cec->cec_base + TEGRA_CEC_HW_CONTROL);
|
||||||
state |= TEGRA_CEC_HWCTRL_TX_RX_MODE;
|
state |= TEGRA_CEC_HWCTRL_TX_RX_MODE;
|
||||||
tegra_cec_writel(state, cec->cec_base + TEGRA_CEC_HW_CONTROL);
|
tegra_cec_writel(state, cec->cec_base + TEGRA_CEC_HW_CONTROL);
|
||||||
} else {
|
|
||||||
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);
|
|
||||||
}
|
|
||||||
|
|
||||||
return count;
|
return count;
|
||||||
}
|
}
|
||||||
@@ -737,7 +613,6 @@ static int tegra_cec_probe(struct platform_device *pdev)
|
|||||||
{
|
{
|
||||||
struct tegra_cec *cec;
|
struct tegra_cec *cec;
|
||||||
struct resource *res;
|
struct resource *res;
|
||||||
struct device_node *np = pdev->dev.of_node;
|
|
||||||
int ret = 0;
|
int ret = 0;
|
||||||
struct reset_control *rst = NULL;
|
struct reset_control *rst = NULL;
|
||||||
|
|
||||||
@@ -746,14 +621,7 @@ static int tegra_cec_probe(struct platform_device *pdev)
|
|||||||
if (!cec)
|
if (!cec)
|
||||||
return -ENOMEM;
|
return -ENOMEM;
|
||||||
|
|
||||||
cec->soc = of_device_get_match_data(&pdev->dev);
|
if (reset_retry_count != 0) {
|
||||||
if (cec->soc == NULL) {
|
|
||||||
dev_err(&pdev->dev, "No cec dev table found\n");
|
|
||||||
devm_kfree(&pdev->dev, cec);
|
|
||||||
return -ENODEV;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (cec->soc->cec_always_on && reset_retry_count != 0) {
|
|
||||||
rst = devm_reset_control_get(&pdev->dev, "cec");
|
rst = devm_reset_control_get(&pdev->dev, "cec");
|
||||||
if (IS_ERR(rst)) {
|
if (IS_ERR(rst)) {
|
||||||
/* BPMP reset mechanism not available, return and retry again */
|
/* BPMP reset mechanism not available, return and retry again */
|
||||||
@@ -815,36 +683,6 @@ static int tegra_cec_probe(struct platform_device *pdev)
|
|||||||
mutex_init(&cec->recovery_lock);
|
mutex_init(&cec->recovery_lock);
|
||||||
cec->dev = &pdev->dev;
|
cec->dev = &pdev->dev;
|
||||||
|
|
||||||
if (!cec->soc->cec_always_on) {
|
|
||||||
|
|
||||||
#if !defined(CONFIG_TEGRA_POWERGATE)
|
|
||||||
if (tegra_dc_is_nvdisplay())
|
|
||||||
pm_runtime_enable(&pdev->dev);
|
|
||||||
#endif
|
|
||||||
|
|
||||||
ret = tegra_cec_unpowergate(cec);
|
|
||||||
if (IS_ERR(ERR_PTR(ret)))
|
|
||||||
goto clk_error;
|
|
||||||
dev_info(&pdev->dev, "Unpowergated DISP\n");
|
|
||||||
|
|
||||||
if (tegra_dc_is_nvdisplay()) {
|
|
||||||
if (np)
|
|
||||||
cec->clk = of_clk_get_by_name(np, "cec");
|
|
||||||
} else {
|
|
||||||
cec->clk = clk_get(&pdev->dev, "cec");
|
|
||||||
}
|
|
||||||
|
|
||||||
if (IS_ERR_OR_NULL(cec->clk)) {
|
|
||||||
dev_err(&pdev->dev, "can't get clock for CEC\n");
|
|
||||||
ret = -ENOENT;
|
|
||||||
goto clk_error;
|
|
||||||
}
|
|
||||||
|
|
||||||
ret = clk_prepare_enable(cec->clk);
|
|
||||||
dev_info(&pdev->dev, "Enable clock result: %d.\n", ret);
|
|
||||||
|
|
||||||
}
|
|
||||||
|
|
||||||
/* set context info. */
|
/* set context info. */
|
||||||
init_waitqueue_head(&cec->rx_waitq);
|
init_waitqueue_head(&cec->rx_waitq);
|
||||||
init_waitqueue_head(&cec->tx_waitq);
|
init_waitqueue_head(&cec->tx_waitq);
|
||||||
@@ -908,12 +746,6 @@ static int tegra_cec_probe(struct platform_device *pdev)
|
|||||||
|
|
||||||
cec_error:
|
cec_error:
|
||||||
cancel_work_sync(&cec->work);
|
cancel_work_sync(&cec->work);
|
||||||
if (!cec->soc->cec_always_on) {
|
|
||||||
clk_disable(cec->clk);
|
|
||||||
clk_put(cec->clk);
|
|
||||||
tegra_cec_powergate(cec);
|
|
||||||
}
|
|
||||||
clk_error:
|
|
||||||
return ret;
|
return ret;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -921,17 +753,6 @@ static int tegra_cec_remove(struct platform_device *pdev)
|
|||||||
{
|
{
|
||||||
struct tegra_cec *cec = platform_get_drvdata(pdev);
|
struct tegra_cec *cec = platform_get_drvdata(pdev);
|
||||||
|
|
||||||
if (!cec->soc->cec_always_on) {
|
|
||||||
|
|
||||||
clk_disable(cec->clk);
|
|
||||||
clk_put(cec->clk);
|
|
||||||
tegra_cec_powergate(cec);
|
|
||||||
#if !defined(CONFIG_TEGRA_POWERGATE)
|
|
||||||
if (tegra_dc_is_nvdisplay())
|
|
||||||
pm_runtime_disable(&pdev->dev);
|
|
||||||
#endif
|
|
||||||
}
|
|
||||||
|
|
||||||
misc_deregister(&cec->misc_dev);
|
misc_deregister(&cec->misc_dev);
|
||||||
cancel_work_sync(&cec->work);
|
cancel_work_sync(&cec->work);
|
||||||
|
|
||||||
@@ -953,20 +774,10 @@ static int tegra_cec_suspend(struct platform_device *pdev, pm_message_t state)
|
|||||||
|
|
||||||
atomic_set(&cec->init_done, 0);
|
atomic_set(&cec->init_done, 0);
|
||||||
atomic_set(&cec->init_cancel, 0);
|
atomic_set(&cec->init_cancel, 0);
|
||||||
|
|
||||||
if (!cec->soc->cec_always_on) {
|
|
||||||
clk_disable(cec->clk);
|
|
||||||
tegra_cec_powergate(cec);
|
|
||||||
} else {
|
|
||||||
/*
|
/*
|
||||||
* TODO:
|
* Wakeup from SC7 on CEC is broken for T234 in HW.
|
||||||
* 1. Program TEGRA_CEC_RX_BUFFER_AFULL_CFG_0 for 0x40
|
* Don't do anything for this while going to suspend.
|
||||||
* 2. Program TEGRA_CEC_MESSAGE_FILTER_CTRL,
|
|
||||||
* TEGRA_CEC_RX_PHYSICAL_ADDR_0,
|
|
||||||
* TEGRA_CEC_RX_OPCODE_0/1/2/3/4.
|
|
||||||
*/
|
*/
|
||||||
}
|
|
||||||
|
|
||||||
dev_notice(&pdev->dev, "suspended\n");
|
dev_notice(&pdev->dev, "suspended\n");
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
@@ -977,71 +788,18 @@ static int tegra_cec_resume(struct platform_device *pdev)
|
|||||||
|
|
||||||
dev_notice(&pdev->dev, "Resuming\n");
|
dev_notice(&pdev->dev, "Resuming\n");
|
||||||
|
|
||||||
if (!cec->soc->cec_always_on) {
|
/*
|
||||||
tegra_cec_unpowergate(cec);
|
* Wakeup from SC7 on CEC is broken for T234 in HW.
|
||||||
clk_enable(cec->clk);
|
* Don't do anything after exiting suspend.
|
||||||
} else {
|
|
||||||
/* TODO:
|
|
||||||
* 1. Read TEGRA_CEC_RX_BUFFER_STAT_0 value and read RX buffer data
|
|
||||||
* 2. Configure TEGRA_CEC_RX_BUFFER_AFULL_CFG_0 back to 0x1.
|
|
||||||
*/
|
*/
|
||||||
}
|
|
||||||
|
|
||||||
schedule_work(&cec->work);
|
schedule_work(&cec->work);
|
||||||
|
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
static int __init check_post_recovery(char *options)
|
|
||||||
{
|
|
||||||
post_recovery = true;
|
|
||||||
|
|
||||||
pr_info("tegra_cec: the post_recovery is %d .\n", post_recovery);
|
|
||||||
|
|
||||||
return 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
early_param("post_recovery", check_post_recovery);
|
|
||||||
|
|
||||||
static struct tegra_cec_soc tegra210_soc_data = {
|
|
||||||
#if defined(CONFIG_TEGRA_POWERGATE)
|
|
||||||
.powergate_id = TEGRA210_POWER_DOMAIN_DISA,
|
|
||||||
#endif
|
|
||||||
.offset = TEGRA_CEC_HW_SPARE,
|
|
||||||
.use_tegra_dc = true,
|
|
||||||
.cec_always_on = false,
|
|
||||||
};
|
|
||||||
|
|
||||||
static struct tegra_cec_soc tegra186_soc_data = {
|
|
||||||
#if defined(CONFIG_TEGRA_POWERGATE)
|
|
||||||
.powergate_id = TEGRA186_POWER_DOMAIN_DISP,
|
|
||||||
#endif
|
|
||||||
.offset = TEGRA_CEC_HW_SPARE,
|
|
||||||
.use_tegra_dc = true,
|
|
||||||
.cec_always_on = false,
|
|
||||||
};
|
|
||||||
|
|
||||||
static struct tegra_cec_soc tegra194_soc_data = {
|
|
||||||
#if defined(CONFIG_TEGRA_POWERGATE)
|
|
||||||
.powergate_id = TEGRA194_POWER_DOMAIN_DISP,
|
|
||||||
#endif
|
|
||||||
.offset = TEGRA_CEC_HW_SPARE,
|
|
||||||
.use_tegra_dc = true,
|
|
||||||
.cec_always_on = false,
|
|
||||||
};
|
|
||||||
|
|
||||||
static struct tegra_cec_soc tegra234_soc_data = {
|
|
||||||
.offset = TEGRA_CEC_RX_OPCODE_4,
|
|
||||||
.use_tegra_dc = false,
|
|
||||||
.cec_always_on = true,
|
|
||||||
};
|
|
||||||
|
|
||||||
static struct of_device_id tegra_cec_of_match[] = {
|
static struct of_device_id tegra_cec_of_match[] = {
|
||||||
{ .compatible = "nvidia,tegra210-cec", .data = &tegra210_soc_data },
|
{ .compatible = "nvidia,tegra234-cec"},
|
||||||
{ .compatible = "nvidia,tegra186-cec", .data = &tegra186_soc_data },
|
|
||||||
{ .compatible = "nvidia,tegra194-cec", .data = &tegra194_soc_data },
|
|
||||||
{ .compatible = "nvidia,tegra234-cec", .data = &tegra234_soc_data },
|
|
||||||
{},
|
{},
|
||||||
};
|
};
|
||||||
|
|
||||||
@@ -1060,5 +818,3 @@ static struct platform_driver tegra_cec_driver = {
|
|||||||
.resume = tegra_cec_resume,
|
.resume = tegra_cec_resume,
|
||||||
#endif
|
#endif
|
||||||
};
|
};
|
||||||
|
|
||||||
module_platform_driver(tegra_cec_driver);
|
|
||||||
|
|||||||
@@ -1,19 +1,6 @@
|
|||||||
|
/* SPDX-License-Identifier: GPL-2.0-only */
|
||||||
/*
|
/*
|
||||||
* drivers/misc/tegra-cec/tegra_cec.h
|
* SPDX-FileCopyrightText: Copyright (c) 2012-2025 NVIDIA CORPORATION & AFFILIATES. All rights reserved.
|
||||||
*
|
|
||||||
* Copyright (c) 2012-2021, NVIDIA CORPORATION. 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/>.
|
|
||||||
*/
|
*/
|
||||||
|
|
||||||
#ifndef TEGRA_CEC_H
|
#ifndef TEGRA_CEC_H
|
||||||
@@ -25,13 +12,6 @@
|
|||||||
|
|
||||||
#define TEGRA_CEC_FRAME_MAX_LENGTH 16
|
#define TEGRA_CEC_FRAME_MAX_LENGTH 16
|
||||||
|
|
||||||
struct tegra_cec_soc {
|
|
||||||
int powergate_id;
|
|
||||||
int offset;
|
|
||||||
bool use_tegra_dc;
|
|
||||||
bool cec_always_on;
|
|
||||||
};
|
|
||||||
|
|
||||||
struct tegra_cec {
|
struct tegra_cec {
|
||||||
struct device *dev;
|
struct device *dev;
|
||||||
struct miscdevice misc_dev;
|
struct miscdevice misc_dev;
|
||||||
@@ -50,7 +30,6 @@ struct tegra_cec {
|
|||||||
#endif
|
#endif
|
||||||
u16 logical_addr;
|
u16 logical_addr;
|
||||||
struct work_struct work;
|
struct work_struct work;
|
||||||
const struct tegra_cec_soc *soc;
|
|
||||||
unsigned int rx_wake;
|
unsigned int rx_wake;
|
||||||
unsigned int tx_wake;
|
unsigned int tx_wake;
|
||||||
u16 rx_buffer;
|
u16 rx_buffer;
|
||||||
|
|||||||
@@ -1,31 +0,0 @@
|
|||||||
/*
|
|
||||||
* include/uapi/misc/tegra_cec.h
|
|
||||||
*
|
|
||||||
* Copyright (c) 2012-2020, NVIDIA CORPORATION. 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/>.
|
|
||||||
*/
|
|
||||||
|
|
||||||
|
|
||||||
#ifndef __UAPI_TEGRA_CEC_H
|
|
||||||
#define __UAPI_TEGRA_CEC_H
|
|
||||||
|
|
||||||
#define TEGRA_CEC_IOC_MAGIC 'C'
|
|
||||||
|
|
||||||
#define TEGRA_CEC_IOCTL_ERROR_RECOVERY _IO(TEGRA_CEC_IOC_MAGIC, 1)
|
|
||||||
#define TEGRA_CEC_IOCTL_DUMP_REGISTERS _IO(TEGRA_CEC_IOC_MAGIC, 2)
|
|
||||||
#define TEGRA_CEC_IOCTL_SET_RX_SNOOP _IO(TEGRA_CEC_IOC_MAGIC, 3)
|
|
||||||
#define TEGRA_CEC_IOCTL_GET_RX_SNOOP _IO(TEGRA_CEC_IOC_MAGIC, 4)
|
|
||||||
#define TEGRA_CEC_IOCTL_GET_POST_RECOVERY _IO(TEGRA_CEC_IOC_MAGIC, 5)
|
|
||||||
|
|
||||||
#endif /* __UAPI_TEGRA_CEC_H */
|
|
||||||
Reference in New Issue
Block a user