cachepc-linux

Fork of AMDESE/linux with modifications for CachePC side-channel attack
git clone https://git.sinitax.com/sinitax/cachepc-linux
Log | Files | Refs | README | LICENSE | sfeed.txt

cec.h (16324B)


      1/* SPDX-License-Identifier: GPL-2.0-only */
      2/*
      3 * cec - HDMI Consumer Electronics Control support header
      4 *
      5 * Copyright 2016 Cisco Systems, Inc. and/or its affiliates. All rights reserved.
      6 */
      7
      8#ifndef _MEDIA_CEC_H
      9#define _MEDIA_CEC_H
     10
     11#include <linux/poll.h>
     12#include <linux/fs.h>
     13#include <linux/debugfs.h>
     14#include <linux/device.h>
     15#include <linux/cdev.h>
     16#include <linux/kthread.h>
     17#include <linux/timer.h>
     18#include <linux/cec-funcs.h>
     19#include <media/rc-core.h>
     20
     21#define CEC_CAP_DEFAULTS (CEC_CAP_LOG_ADDRS | CEC_CAP_TRANSMIT | \
     22			  CEC_CAP_PASSTHROUGH | CEC_CAP_RC)
     23
     24/**
     25 * struct cec_devnode - cec device node
     26 * @dev:	cec device
     27 * @cdev:	cec character device
     28 * @minor:	device node minor number
     29 * @lock:	lock to serialize open/release and registration
     30 * @registered:	the device was correctly registered
     31 * @unregistered: the device was unregistered
     32 * @lock_fhs:	lock to control access to @fhs
     33 * @fhs:	the list of open filehandles (cec_fh)
     34 *
     35 * This structure represents a cec-related device node.
     36 *
     37 * To add or remove filehandles from @fhs the @lock must be taken first,
     38 * followed by @lock_fhs. It is safe to access @fhs if either lock is held.
     39 *
     40 * The @parent is a physical device. It must be set by core or device drivers
     41 * before registering the node.
     42 */
     43struct cec_devnode {
     44	/* sysfs */
     45	struct device dev;
     46	struct cdev cdev;
     47
     48	/* device info */
     49	int minor;
     50	/* serialize open/release and registration */
     51	struct mutex lock;
     52	bool registered;
     53	bool unregistered;
     54	/* protect access to fhs */
     55	struct mutex lock_fhs;
     56	struct list_head fhs;
     57};
     58
     59struct cec_adapter;
     60struct cec_data;
     61struct cec_pin;
     62struct cec_notifier;
     63
     64struct cec_data {
     65	struct list_head list;
     66	struct list_head xfer_list;
     67	struct cec_adapter *adap;
     68	struct cec_msg msg;
     69	struct cec_fh *fh;
     70	struct delayed_work work;
     71	struct completion c;
     72	u8 attempts;
     73	bool blocking;
     74	bool completed;
     75};
     76
     77struct cec_msg_entry {
     78	struct list_head	list;
     79	struct cec_msg		msg;
     80};
     81
     82struct cec_event_entry {
     83	struct list_head	list;
     84	struct cec_event	ev;
     85};
     86
     87#define CEC_NUM_CORE_EVENTS 2
     88#define CEC_NUM_EVENTS CEC_EVENT_PIN_5V_HIGH
     89
     90struct cec_fh {
     91	struct list_head	list;
     92	struct list_head	xfer_list;
     93	struct cec_adapter	*adap;
     94	u8			mode_initiator;
     95	u8			mode_follower;
     96
     97	/* Events */
     98	wait_queue_head_t	wait;
     99	struct mutex		lock;
    100	struct list_head	events[CEC_NUM_EVENTS]; /* queued events */
    101	u16			queued_events[CEC_NUM_EVENTS];
    102	unsigned int		total_queued_events;
    103	struct cec_event_entry	core_events[CEC_NUM_CORE_EVENTS];
    104	struct list_head	msgs; /* queued messages */
    105	unsigned int		queued_msgs;
    106};
    107
    108#define CEC_SIGNAL_FREE_TIME_RETRY		3
    109#define CEC_SIGNAL_FREE_TIME_NEW_INITIATOR	5
    110#define CEC_SIGNAL_FREE_TIME_NEXT_XFER		7
    111
    112/* The nominal data bit period is 2.4 ms */
    113#define CEC_FREE_TIME_TO_USEC(ft)		((ft) * 2400)
    114
    115struct cec_adap_ops {
    116	/* Low-level callbacks */
    117	int (*adap_enable)(struct cec_adapter *adap, bool enable);
    118	int (*adap_monitor_all_enable)(struct cec_adapter *adap, bool enable);
    119	int (*adap_monitor_pin_enable)(struct cec_adapter *adap, bool enable);
    120	int (*adap_log_addr)(struct cec_adapter *adap, u8 logical_addr);
    121	void (*adap_configured)(struct cec_adapter *adap, bool configured);
    122	int (*adap_transmit)(struct cec_adapter *adap, u8 attempts,
    123			     u32 signal_free_time, struct cec_msg *msg);
    124	void (*adap_status)(struct cec_adapter *adap, struct seq_file *file);
    125	void (*adap_free)(struct cec_adapter *adap);
    126
    127	/* Error injection callbacks */
    128	int (*error_inj_show)(struct cec_adapter *adap, struct seq_file *sf);
    129	bool (*error_inj_parse_line)(struct cec_adapter *adap, char *line);
    130
    131	/* High-level CEC message callback */
    132	int (*received)(struct cec_adapter *adap, struct cec_msg *msg);
    133};
    134
    135/*
    136 * The minimum message length you can receive (excepting poll messages) is 2.
    137 * With a transfer rate of at most 36 bytes per second this makes 18 messages
    138 * per second worst case.
    139 *
    140 * We queue at most 3 seconds worth of received messages. The CEC specification
    141 * requires that messages are replied to within a second, so 3 seconds should
    142 * give more than enough margin. Since most messages are actually more than 2
    143 * bytes, this is in practice a lot more than 3 seconds.
    144 */
    145#define CEC_MAX_MSG_RX_QUEUE_SZ		(18 * 3)
    146
    147/*
    148 * The transmit queue is limited to 1 second worth of messages (worst case).
    149 * Messages can be transmitted by userspace and kernel space. But for both it
    150 * makes no sense to have a lot of messages queued up. One second seems
    151 * reasonable.
    152 */
    153#define CEC_MAX_MSG_TX_QUEUE_SZ		(18 * 1)
    154
    155/**
    156 * struct cec_adapter - cec adapter structure
    157 * @owner:		module owner
    158 * @name:		name of the CEC adapter
    159 * @devnode:		device node for the /dev/cecX device
    160 * @lock:		mutex controlling access to this structure
    161 * @rc:			remote control device
    162 * @transmit_queue:	queue of pending transmits
    163 * @transmit_queue_sz:	number of pending transmits
    164 * @wait_queue:		queue of transmits waiting for a reply
    165 * @transmitting:	CEC messages currently being transmitted
    166 * @transmit_in_progress: true if a transmit is in progress
    167 * @transmit_in_progress_aborted: true if a transmit is in progress is to be
    168 *			aborted. This happens if the logical address is
    169 *			invalidated while the transmit is ongoing. In that
    170 *			case the transmit will finish, but will not retransmit
    171 *			and be marked as ABORTED.
    172 * @xfer_timeout_ms:	the transfer timeout in ms.
    173 *			If 0, then timeout after 2.1 ms.
    174 * @kthread_config:	kthread used to configure a CEC adapter
    175 * @config_completion:	used to signal completion of the config kthread
    176 * @kthread:		main CEC processing thread
    177 * @kthread_waitq:	main CEC processing wait_queue
    178 * @ops:		cec adapter ops
    179 * @priv:		cec driver's private data
    180 * @capabilities:	cec adapter capabilities
    181 * @available_log_addrs: maximum number of available logical addresses
    182 * @phys_addr:		the current physical address
    183 * @needs_hpd:		if true, then the HDMI HotPlug Detect pin must be high
    184 *	in order to transmit or receive CEC messages. This is usually a HW
    185 *	limitation.
    186 * @is_enabled:		the CEC adapter is enabled
    187 * @is_configuring:	the CEC adapter is configuring (i.e. claiming LAs)
    188 * @must_reconfigure:	while configuring, the PA changed, so reclaim LAs
    189 * @is_configured:	the CEC adapter is configured (i.e. has claimed LAs)
    190 * @cec_pin_is_high:	if true then the CEC pin is high. Only used with the
    191 *	CEC pin framework.
    192 * @adap_controls_phys_addr: if true, then the CEC adapter controls the
    193 *	physical address, i.e. the CEC hardware can detect HPD changes and
    194 *	read the EDID and is not dependent on an external HDMI driver.
    195 *	Drivers that need this can set this field to true after the
    196 *	cec_allocate_adapter() call.
    197 * @last_initiator:	the initiator of the last transmitted message.
    198 * @monitor_all_cnt:	number of filehandles monitoring all msgs
    199 * @monitor_pin_cnt:	number of filehandles monitoring pin changes
    200 * @follower_cnt:	number of filehandles in follower mode
    201 * @cec_follower:	filehandle of the exclusive follower
    202 * @cec_initiator:	filehandle of the exclusive initiator
    203 * @passthrough:	if true, then the exclusive follower is in
    204 *	passthrough mode.
    205 * @log_addrs:		current logical addresses
    206 * @conn_info:		current connector info
    207 * @tx_timeouts:	number of transmit timeouts
    208 * @notifier:		CEC notifier
    209 * @pin:		CEC pin status struct
    210 * @cec_dir:		debugfs cec directory
    211 * @status_file:	debugfs cec status file
    212 * @error_inj_file:	debugfs cec error injection file
    213 * @sequence:		transmit sequence counter
    214 * @input_phys:		remote control input_phys name
    215 *
    216 * This structure represents a cec adapter.
    217 */
    218struct cec_adapter {
    219	struct module *owner;
    220	char name[32];
    221	struct cec_devnode devnode;
    222	struct mutex lock;
    223	struct rc_dev *rc;
    224
    225	struct list_head transmit_queue;
    226	unsigned int transmit_queue_sz;
    227	struct list_head wait_queue;
    228	struct cec_data *transmitting;
    229	bool transmit_in_progress;
    230	bool transmit_in_progress_aborted;
    231	unsigned int xfer_timeout_ms;
    232
    233	struct task_struct *kthread_config;
    234	struct completion config_completion;
    235
    236	struct task_struct *kthread;
    237	wait_queue_head_t kthread_waitq;
    238
    239	const struct cec_adap_ops *ops;
    240	void *priv;
    241	u32 capabilities;
    242	u8 available_log_addrs;
    243
    244	u16 phys_addr;
    245	bool needs_hpd;
    246	bool is_enabled;
    247	bool is_configuring;
    248	bool must_reconfigure;
    249	bool is_configured;
    250	bool cec_pin_is_high;
    251	bool adap_controls_phys_addr;
    252	u8 last_initiator;
    253	u32 monitor_all_cnt;
    254	u32 monitor_pin_cnt;
    255	u32 follower_cnt;
    256	struct cec_fh *cec_follower;
    257	struct cec_fh *cec_initiator;
    258	bool passthrough;
    259	struct cec_log_addrs log_addrs;
    260	struct cec_connector_info conn_info;
    261
    262	u32 tx_timeouts;
    263
    264#ifdef CONFIG_CEC_NOTIFIER
    265	struct cec_notifier *notifier;
    266#endif
    267#ifdef CONFIG_CEC_PIN
    268	struct cec_pin *pin;
    269#endif
    270
    271	struct dentry *cec_dir;
    272
    273	u32 sequence;
    274
    275	char input_phys[32];
    276};
    277
    278static inline void *cec_get_drvdata(const struct cec_adapter *adap)
    279{
    280	return adap->priv;
    281}
    282
    283static inline bool cec_has_log_addr(const struct cec_adapter *adap, u8 log_addr)
    284{
    285	return adap->log_addrs.log_addr_mask & (1 << log_addr);
    286}
    287
    288static inline bool cec_is_sink(const struct cec_adapter *adap)
    289{
    290	return adap->phys_addr == 0;
    291}
    292
    293/**
    294 * cec_is_registered() - is the CEC adapter registered?
    295 *
    296 * @adap:	the CEC adapter, may be NULL.
    297 *
    298 * Return: true if the adapter is registered, false otherwise.
    299 */
    300static inline bool cec_is_registered(const struct cec_adapter *adap)
    301{
    302	return adap && adap->devnode.registered;
    303}
    304
    305#define cec_phys_addr_exp(pa) \
    306	((pa) >> 12), ((pa) >> 8) & 0xf, ((pa) >> 4) & 0xf, (pa) & 0xf
    307
    308struct edid;
    309struct drm_connector;
    310
    311#if IS_REACHABLE(CONFIG_CEC_CORE)
    312struct cec_adapter *cec_allocate_adapter(const struct cec_adap_ops *ops,
    313		void *priv, const char *name, u32 caps, u8 available_las);
    314int cec_register_adapter(struct cec_adapter *adap, struct device *parent);
    315void cec_unregister_adapter(struct cec_adapter *adap);
    316void cec_delete_adapter(struct cec_adapter *adap);
    317
    318int cec_s_log_addrs(struct cec_adapter *adap, struct cec_log_addrs *log_addrs,
    319		    bool block);
    320void cec_s_phys_addr(struct cec_adapter *adap, u16 phys_addr,
    321		     bool block);
    322void cec_s_phys_addr_from_edid(struct cec_adapter *adap,
    323			       const struct edid *edid);
    324void cec_s_conn_info(struct cec_adapter *adap,
    325		     const struct cec_connector_info *conn_info);
    326int cec_transmit_msg(struct cec_adapter *adap, struct cec_msg *msg,
    327		     bool block);
    328
    329/* Called by the adapter */
    330void cec_transmit_done_ts(struct cec_adapter *adap, u8 status,
    331			  u8 arb_lost_cnt, u8 nack_cnt, u8 low_drive_cnt,
    332			  u8 error_cnt, ktime_t ts);
    333
    334static inline void cec_transmit_done(struct cec_adapter *adap, u8 status,
    335				     u8 arb_lost_cnt, u8 nack_cnt,
    336				     u8 low_drive_cnt, u8 error_cnt)
    337{
    338	cec_transmit_done_ts(adap, status, arb_lost_cnt, nack_cnt,
    339			     low_drive_cnt, error_cnt, ktime_get());
    340}
    341/*
    342 * Simplified version of cec_transmit_done for hardware that doesn't retry
    343 * failed transmits. So this is always just one attempt in which case
    344 * the status is sufficient.
    345 */
    346void cec_transmit_attempt_done_ts(struct cec_adapter *adap,
    347				  u8 status, ktime_t ts);
    348
    349static inline void cec_transmit_attempt_done(struct cec_adapter *adap,
    350					     u8 status)
    351{
    352	cec_transmit_attempt_done_ts(adap, status, ktime_get());
    353}
    354
    355void cec_received_msg_ts(struct cec_adapter *adap,
    356			 struct cec_msg *msg, ktime_t ts);
    357
    358static inline void cec_received_msg(struct cec_adapter *adap,
    359				    struct cec_msg *msg)
    360{
    361	cec_received_msg_ts(adap, msg, ktime_get());
    362}
    363
    364/**
    365 * cec_queue_pin_cec_event() - queue a CEC pin event with a given timestamp.
    366 *
    367 * @adap:	pointer to the cec adapter
    368 * @is_high:	when true the CEC pin is high, otherwise it is low
    369 * @dropped_events: when true some events were dropped
    370 * @ts:		the timestamp for this event
    371 *
    372 */
    373void cec_queue_pin_cec_event(struct cec_adapter *adap, bool is_high,
    374			     bool dropped_events, ktime_t ts);
    375
    376/**
    377 * cec_queue_pin_hpd_event() - queue a pin event with a given timestamp.
    378 *
    379 * @adap:	pointer to the cec adapter
    380 * @is_high:	when true the HPD pin is high, otherwise it is low
    381 * @ts:		the timestamp for this event
    382 *
    383 */
    384void cec_queue_pin_hpd_event(struct cec_adapter *adap, bool is_high, ktime_t ts);
    385
    386/**
    387 * cec_queue_pin_5v_event() - queue a pin event with a given timestamp.
    388 *
    389 * @adap:	pointer to the cec adapter
    390 * @is_high:	when true the 5V pin is high, otherwise it is low
    391 * @ts:		the timestamp for this event
    392 *
    393 */
    394void cec_queue_pin_5v_event(struct cec_adapter *adap, bool is_high, ktime_t ts);
    395
    396/**
    397 * cec_get_edid_phys_addr() - find and return the physical address
    398 *
    399 * @edid:	pointer to the EDID data
    400 * @size:	size in bytes of the EDID data
    401 * @offset:	If not %NULL then the location of the physical address
    402 *		bytes in the EDID will be returned here. This is set to 0
    403 *		if there is no physical address found.
    404 *
    405 * Return: the physical address or CEC_PHYS_ADDR_INVALID if there is none.
    406 */
    407u16 cec_get_edid_phys_addr(const u8 *edid, unsigned int size,
    408			   unsigned int *offset);
    409
    410void cec_fill_conn_info_from_drm(struct cec_connector_info *conn_info,
    411				 const struct drm_connector *connector);
    412
    413#else
    414
    415static inline int cec_register_adapter(struct cec_adapter *adap,
    416				       struct device *parent)
    417{
    418	return 0;
    419}
    420
    421static inline void cec_unregister_adapter(struct cec_adapter *adap)
    422{
    423}
    424
    425static inline void cec_delete_adapter(struct cec_adapter *adap)
    426{
    427}
    428
    429static inline void cec_s_phys_addr(struct cec_adapter *adap, u16 phys_addr,
    430				   bool block)
    431{
    432}
    433
    434static inline void cec_s_phys_addr_from_edid(struct cec_adapter *adap,
    435					     const struct edid *edid)
    436{
    437}
    438
    439static inline u16 cec_get_edid_phys_addr(const u8 *edid, unsigned int size,
    440					 unsigned int *offset)
    441{
    442	if (offset)
    443		*offset = 0;
    444	return CEC_PHYS_ADDR_INVALID;
    445}
    446
    447static inline void cec_s_conn_info(struct cec_adapter *adap,
    448				   const struct cec_connector_info *conn_info)
    449{
    450}
    451
    452static inline void
    453cec_fill_conn_info_from_drm(struct cec_connector_info *conn_info,
    454			    const struct drm_connector *connector)
    455{
    456	memset(conn_info, 0, sizeof(*conn_info));
    457}
    458
    459#endif
    460
    461/**
    462 * cec_phys_addr_invalidate() - set the physical address to INVALID
    463 *
    464 * @adap:	the CEC adapter
    465 *
    466 * This is a simple helper function to invalidate the physical
    467 * address.
    468 */
    469static inline void cec_phys_addr_invalidate(struct cec_adapter *adap)
    470{
    471	cec_s_phys_addr(adap, CEC_PHYS_ADDR_INVALID, false);
    472}
    473
    474/**
    475 * cec_get_edid_spa_location() - find location of the Source Physical Address
    476 *
    477 * @edid: the EDID
    478 * @size: the size of the EDID
    479 *
    480 * This EDID is expected to be a CEA-861 compliant, which means that there are
    481 * at least two blocks and one or more of the extensions blocks are CEA-861
    482 * blocks.
    483 *
    484 * The returned location is guaranteed to be <= size-2.
    485 *
    486 * This is an inline function since it is used by both CEC and V4L2.
    487 * Ideally this would go in a module shared by both, but it is overkill to do
    488 * that for just a single function.
    489 */
    490static inline unsigned int cec_get_edid_spa_location(const u8 *edid,
    491						     unsigned int size)
    492{
    493	unsigned int blocks = size / 128;
    494	unsigned int block;
    495	u8 d;
    496
    497	/* Sanity check: at least 2 blocks and a multiple of the block size */
    498	if (blocks < 2 || size % 128)
    499		return 0;
    500
    501	/*
    502	 * If there are fewer extension blocks than the size, then update
    503	 * 'blocks'. It is allowed to have more extension blocks than the size,
    504	 * since some hardware can only read e.g. 256 bytes of the EDID, even
    505	 * though more blocks are present. The first CEA-861 extension block
    506	 * should normally be in block 1 anyway.
    507	 */
    508	if (edid[0x7e] + 1 < blocks)
    509		blocks = edid[0x7e] + 1;
    510
    511	for (block = 1; block < blocks; block++) {
    512		unsigned int offset = block * 128;
    513
    514		/* Skip any non-CEA-861 extension blocks */
    515		if (edid[offset] != 0x02 || edid[offset + 1] != 0x03)
    516			continue;
    517
    518		/* search Vendor Specific Data Block (tag 3) */
    519		d = edid[offset + 2] & 0x7f;
    520		/* Check if there are Data Blocks */
    521		if (d <= 4)
    522			continue;
    523		if (d > 4) {
    524			unsigned int i = offset + 4;
    525			unsigned int end = offset + d;
    526
    527			/* Note: 'end' is always < 'size' */
    528			do {
    529				u8 tag = edid[i] >> 5;
    530				u8 len = edid[i] & 0x1f;
    531
    532				if (tag == 3 && len >= 5 && i + len <= end &&
    533				    edid[i + 1] == 0x03 &&
    534				    edid[i + 2] == 0x0c &&
    535				    edid[i + 3] == 0x00)
    536					return i + 4;
    537				i += len + 1;
    538			} while (i < end);
    539		}
    540	}
    541	return 0;
    542}
    543
    544#endif /* _MEDIA_CEC_H */