Files
linux-nv-oot/drivers/misc/tegra-cec/tegra_cec.h
Robert Huang a0aa537149 misc: cec: add wake up support.
This change adds SC7 wake support to cec driver.
CEC engine can detect TV packets in SC7 state and
can wake up when particular pattern detected.
In resume functionality, the total arrived packets on FIFO
needs to read and reported back to user-space.

This change adds -
1. Program CEC engine to activate for SC7 wake.
2. Program required opcode and physical address.
3. Register for wake and read packets in resume path.
4. Provide sysfs control to program physical address.

Verification of SC7 wake is done for below cases -
1. TV turn on and off is tested.
2. TV source input change is tested.
3. CEC Analyzer set-stream is tested.

Bug 4974679

Change-Id: Ia1ceeb13b89614c96d0b6d42f2bb58419865414b
Signed-off-by: Robert Huang <robhuang@nvidia.com>
Reviewed-on: https://git-master.nvidia.com/r/c/linux-nv-oot/+/3300821
GVS: buildbot_gerritrpt <buildbot_gerritrpt@nvidia.com>
Reviewed-by: Bitan Biswas <bbiswas@nvidia.com>
Reviewed-by: Prafull Suryawanshi <prafulls@nvidia.com>
2025-07-24 10:19:16 +00:00

172 lines
6.3 KiB
C

/* SPDX-License-Identifier: GPL-2.0-only */
/*
* SPDX-FileCopyrightText: Copyright (c) 2012-2025 NVIDIA CORPORATION & AFFILIATES. 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;
u16 physical_addr;
struct work_struct work;
unsigned int rx_wake;
unsigned int tx_wake;
u16 rx_buffer;
long tx_error;
u32 tx_buf[TEGRA_CEC_FRAME_MAX_LENGTH];
u8 tx_buf_cur;
u8 tx_buf_cnt;
struct reset_control *reset;
bool is_tegra_cec_suspended;
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_0 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_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 */