2 * Tegra CEC implementation
4 * The original 3.10 CEC driver using a custom API:
6 * Copyright (c) 2012-2015, NVIDIA CORPORATION. All rights reserved.
8 * Conversion to the CEC framework and to the mainline kernel:
10 * Copyright 2016-2017 Cisco Systems, Inc. and/or its affiliates. All rights reserved.
12 * This program is free software; you can redistribute it and/or modify it
13 * under the terms and conditions of the GNU General Public License,
14 * version 2, as published by the Free Software Foundation.
16 * This program is distributed in the hope it will be useful, but WITHOUT
17 * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
18 * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for
21 * You should have received a copy of the GNU General Public License
22 * along with this program. If not, see <http://www.gnu.org/licenses/>.
25 #include <linux/module.h>
26 #include <linux/kernel.h>
27 #include <linux/err.h>
28 #include <linux/errno.h>
29 #include <linux/interrupt.h>
30 #include <linux/slab.h>
32 #include <linux/clk.h>
33 #include <linux/delay.h>
36 #include <linux/of_platform.h>
37 #include <linux/platform_device.h>
38 #include <linux/clk/tegra.h>
40 #include <media/cec-notifier.h>
42 #include "tegra_cec.h"
44 #define TEGRA_CEC_NAME "tegra-cec"
47 struct cec_adapter
*adap
;
50 void __iomem
*cec_base
;
51 struct cec_notifier
*notifier
;
56 u8 rx_buf
[CEC_MAX_MSG_SIZE
];
58 u32 tx_buf
[CEC_MAX_MSG_SIZE
];
63 static inline u32
cec_read(struct tegra_cec
*cec
, u32 reg
)
65 return readl(cec
->cec_base
+ reg
);
68 static inline void cec_write(struct tegra_cec
*cec
, u32 reg
, u32 val
)
70 writel(val
, cec
->cec_base
+ reg
);
73 static void tegra_cec_error_recovery(struct tegra_cec
*cec
)
77 hw_ctrl
= cec_read(cec
, TEGRA_CEC_HW_CONTROL
);
78 cec_write(cec
, TEGRA_CEC_HW_CONTROL
, 0);
79 cec_write(cec
, TEGRA_CEC_INT_STAT
, 0xffffffff);
80 cec_write(cec
, TEGRA_CEC_HW_CONTROL
, hw_ctrl
);
83 static irqreturn_t
tegra_cec_irq_thread_handler(int irq
, void *data
)
85 struct device
*dev
= data
;
86 struct tegra_cec
*cec
= dev_get_drvdata(dev
);
89 cec_transmit_attempt_done(cec
->adap
, cec
->tx_status
);
93 struct cec_msg msg
= {};
95 msg
.len
= cec
->rx_buf_cnt
;
96 memcpy(msg
.msg
, cec
->rx_buf
, msg
.len
);
97 cec_received_msg(cec
->adap
, &msg
);
104 static irqreturn_t
tegra_cec_irq_handler(int irq
, void *data
)
106 struct device
*dev
= data
;
107 struct tegra_cec
*cec
= dev_get_drvdata(dev
);
110 status
= cec_read(cec
, TEGRA_CEC_INT_STAT
);
111 mask
= cec_read(cec
, TEGRA_CEC_INT_MASK
);
118 if (status
& TEGRA_CEC_INT_STAT_TX_REGISTER_UNDERRUN
) {
119 dev_err(dev
, "TX underrun, interrupt timing issue!\n");
121 tegra_cec_error_recovery(cec
);
122 cec_write(cec
, TEGRA_CEC_INT_MASK
,
123 mask
& ~TEGRA_CEC_INT_MASK_TX_REGISTER_EMPTY
);
126 cec
->tx_status
= CEC_TX_STATUS_ERROR
;
127 return IRQ_WAKE_THREAD
;
130 if ((status
& TEGRA_CEC_INT_STAT_TX_ARBITRATION_FAILED
) ||
131 (status
& TEGRA_CEC_INT_STAT_TX_BUS_ANOMALY_DETECTED
)) {
132 tegra_cec_error_recovery(cec
);
133 cec_write(cec
, TEGRA_CEC_INT_MASK
,
134 mask
& ~TEGRA_CEC_INT_MASK_TX_REGISTER_EMPTY
);
137 if (status
& TEGRA_CEC_INT_STAT_TX_BUS_ANOMALY_DETECTED
)
138 cec
->tx_status
= CEC_TX_STATUS_LOW_DRIVE
;
140 cec
->tx_status
= CEC_TX_STATUS_ARB_LOST
;
141 return IRQ_WAKE_THREAD
;
144 if (status
& TEGRA_CEC_INT_STAT_TX_FRAME_TRANSMITTED
) {
145 cec_write(cec
, TEGRA_CEC_INT_STAT
,
146 TEGRA_CEC_INT_STAT_TX_FRAME_TRANSMITTED
);
148 if (status
& TEGRA_CEC_INT_STAT_TX_FRAME_OR_BLOCK_NAKD
) {
149 tegra_cec_error_recovery(cec
);
152 cec
->tx_status
= CEC_TX_STATUS_NACK
;
155 cec
->tx_status
= CEC_TX_STATUS_OK
;
157 return IRQ_WAKE_THREAD
;
160 if (status
& TEGRA_CEC_INT_STAT_TX_FRAME_OR_BLOCK_NAKD
)
161 dev_warn(dev
, "TX NAKed on the fly!\n");
163 if (status
& TEGRA_CEC_INT_STAT_TX_REGISTER_EMPTY
) {
164 if (cec
->tx_buf_cur
== cec
->tx_buf_cnt
) {
165 cec_write(cec
, TEGRA_CEC_INT_MASK
,
166 mask
& ~TEGRA_CEC_INT_MASK_TX_REGISTER_EMPTY
);
168 cec_write(cec
, TEGRA_CEC_TX_REGISTER
,
169 cec
->tx_buf
[cec
->tx_buf_cur
++]);
170 cec_write(cec
, TEGRA_CEC_INT_STAT
,
171 TEGRA_CEC_INT_STAT_TX_REGISTER_EMPTY
);
175 if (status
& TEGRA_CEC_INT_STAT_RX_START_BIT_DETECTED
) {
176 cec_write(cec
, TEGRA_CEC_INT_STAT
,
177 TEGRA_CEC_INT_STAT_RX_START_BIT_DETECTED
);
178 cec
->rx_done
= false;
181 if (status
& TEGRA_CEC_INT_STAT_RX_REGISTER_FULL
) {
184 cec_write(cec
, TEGRA_CEC_INT_STAT
,
185 TEGRA_CEC_INT_STAT_RX_REGISTER_FULL
);
186 v
= cec_read(cec
, TEGRA_CEC_RX_REGISTER
);
187 if (cec
->rx_buf_cnt
< CEC_MAX_MSG_SIZE
)
188 cec
->rx_buf
[cec
->rx_buf_cnt
++] = v
& 0xff;
189 if (v
& TEGRA_CEC_RX_REGISTER_EOM
) {
191 return IRQ_WAKE_THREAD
;
198 static int tegra_cec_adap_enable(struct cec_adapter
*adap
, bool enable
)
200 struct tegra_cec
*cec
= adap
->priv
;
206 cec_write(cec
, TEGRA_CEC_HW_CONTROL
, 0);
207 cec_write(cec
, TEGRA_CEC_INT_MASK
, 0);
208 cec_write(cec
, TEGRA_CEC_INT_STAT
, 0xffffffff);
209 cec_write(cec
, TEGRA_CEC_SW_CONTROL
, 0);
214 cec_write(cec
, TEGRA_CEC_INPUT_FILTER
, (1U << 31) | 0x20);
216 cec_write(cec
, TEGRA_CEC_RX_TIMING_0
,
217 (0x7a << TEGRA_CEC_RX_TIM0_START_BIT_MAX_LO_TIME_SHIFT
) |
218 (0x6d << TEGRA_CEC_RX_TIM0_START_BIT_MIN_LO_TIME_SHIFT
) |
219 (0x93 << TEGRA_CEC_RX_TIM0_START_BIT_MAX_DURATION_SHIFT
) |
220 (0x86 << TEGRA_CEC_RX_TIM0_START_BIT_MIN_DURATION_SHIFT
));
222 cec_write(cec
, TEGRA_CEC_RX_TIMING_1
,
223 (0x35 << TEGRA_CEC_RX_TIM1_DATA_BIT_MAX_LO_TIME_SHIFT
) |
224 (0x21 << TEGRA_CEC_RX_TIM1_DATA_BIT_SAMPLE_TIME_SHIFT
) |
225 (0x56 << TEGRA_CEC_RX_TIM1_DATA_BIT_MAX_DURATION_SHIFT
) |
226 (0x40 << TEGRA_CEC_RX_TIM1_DATA_BIT_MIN_DURATION_SHIFT
));
228 cec_write(cec
, TEGRA_CEC_RX_TIMING_2
,
229 (0x50 << TEGRA_CEC_RX_TIM2_END_OF_BLOCK_TIME_SHIFT
));
231 cec_write(cec
, TEGRA_CEC_TX_TIMING_0
,
232 (0x74 << TEGRA_CEC_TX_TIM0_START_BIT_LO_TIME_SHIFT
) |
233 (0x8d << TEGRA_CEC_TX_TIM0_START_BIT_DURATION_SHIFT
) |
234 (0x08 << TEGRA_CEC_TX_TIM0_BUS_XITION_TIME_SHIFT
) |
235 (0x71 << TEGRA_CEC_TX_TIM0_BUS_ERROR_LO_TIME_SHIFT
));
237 cec_write(cec
, TEGRA_CEC_TX_TIMING_1
,
238 (0x2f << TEGRA_CEC_TX_TIM1_LO_DATA_BIT_LO_TIME_SHIFT
) |
239 (0x13 << TEGRA_CEC_TX_TIM1_HI_DATA_BIT_LO_TIME_SHIFT
) |
240 (0x4b << TEGRA_CEC_TX_TIM1_DATA_BIT_DURATION_SHIFT
) |
241 (0x21 << TEGRA_CEC_TX_TIM1_ACK_NAK_BIT_SAMPLE_TIME_SHIFT
));
243 cec_write(cec
, TEGRA_CEC_TX_TIMING_2
,
244 (0x07 << TEGRA_CEC_TX_TIM2_BUS_IDLE_TIME_ADDITIONAL_FRAME_SHIFT
) |
245 (0x05 << TEGRA_CEC_TX_TIM2_BUS_IDLE_TIME_NEW_FRAME_SHIFT
) |
246 (0x03 << TEGRA_CEC_TX_TIM2_BUS_IDLE_TIME_RETRY_FRAME_SHIFT
));
248 cec_write(cec
, TEGRA_CEC_INT_MASK
,
249 TEGRA_CEC_INT_MASK_TX_REGISTER_UNDERRUN
|
250 TEGRA_CEC_INT_MASK_TX_FRAME_OR_BLOCK_NAKD
|
251 TEGRA_CEC_INT_MASK_TX_ARBITRATION_FAILED
|
252 TEGRA_CEC_INT_MASK_TX_BUS_ANOMALY_DETECTED
|
253 TEGRA_CEC_INT_MASK_TX_FRAME_TRANSMITTED
|
254 TEGRA_CEC_INT_MASK_RX_REGISTER_FULL
|
255 TEGRA_CEC_INT_MASK_RX_START_BIT_DETECTED
);
257 cec_write(cec
, TEGRA_CEC_HW_CONTROL
, TEGRA_CEC_HWCTRL_TX_RX_MODE
);
261 static int tegra_cec_adap_log_addr(struct cec_adapter
*adap
, u8 logical_addr
)
263 struct tegra_cec
*cec
= adap
->priv
;
264 u32 state
= cec_read(cec
, TEGRA_CEC_HW_CONTROL
);
266 if (logical_addr
== CEC_LOG_ADDR_INVALID
)
267 state
&= ~TEGRA_CEC_HWCTRL_RX_LADDR_MASK
;
269 state
|= TEGRA_CEC_HWCTRL_RX_LADDR((1 << logical_addr
));
271 cec_write(cec
, TEGRA_CEC_HW_CONTROL
, state
);
275 static int tegra_cec_adap_monitor_all_enable(struct cec_adapter
*adap
,
278 struct tegra_cec
*cec
= adap
->priv
;
279 u32 reg
= cec_read(cec
, TEGRA_CEC_HW_CONTROL
);
282 reg
|= TEGRA_CEC_HWCTRL_RX_SNOOP
;
284 reg
&= ~TEGRA_CEC_HWCTRL_RX_SNOOP
;
285 cec_write(cec
, TEGRA_CEC_HW_CONTROL
, reg
);
289 static int tegra_cec_adap_transmit(struct cec_adapter
*adap
, u8 attempts
,
290 u32 signal_free_time_ms
, struct cec_msg
*msg
)
292 bool retry_xfer
= signal_free_time_ms
== CEC_SIGNAL_FREE_TIME_RETRY
;
293 struct tegra_cec
*cec
= adap
->priv
;
298 if (cec_msg_is_broadcast(msg
))
299 mode
= TEGRA_CEC_TX_REG_BCAST
;
302 cec
->tx_buf_cnt
= msg
->len
;
304 for (i
= 0; i
< msg
->len
; i
++) {
305 cec
->tx_buf
[i
] = mode
| msg
->msg
[i
];
307 cec
->tx_buf
[i
] |= TEGRA_CEC_TX_REG_START_BIT
;
308 if (i
== msg
->len
- 1)
309 cec
->tx_buf
[i
] |= TEGRA_CEC_TX_REG_EOM
;
310 if (i
== 0 && retry_xfer
)
311 cec
->tx_buf
[i
] |= TEGRA_CEC_TX_REG_RETRY
;
314 mask
= cec_read(cec
, TEGRA_CEC_INT_MASK
);
315 cec_write(cec
, TEGRA_CEC_INT_MASK
,
316 mask
| TEGRA_CEC_INT_MASK_TX_REGISTER_EMPTY
);
321 static const struct cec_adap_ops tegra_cec_ops
= {
322 .adap_enable
= tegra_cec_adap_enable
,
323 .adap_log_addr
= tegra_cec_adap_log_addr
,
324 .adap_transmit
= tegra_cec_adap_transmit
,
325 .adap_monitor_all_enable
= tegra_cec_adap_monitor_all_enable
,
328 static int tegra_cec_probe(struct platform_device
*pdev
)
330 struct platform_device
*hdmi_dev
;
331 struct device_node
*np
;
332 struct tegra_cec
*cec
;
333 struct resource
*res
;
336 np
= of_parse_phandle(pdev
->dev
.of_node
, "hdmi-phandle", 0);
339 dev_err(&pdev
->dev
, "Failed to find hdmi node in device tree\n");
342 hdmi_dev
= of_find_device_by_node(np
);
343 if (hdmi_dev
== NULL
)
344 return -EPROBE_DEFER
;
346 cec
= devm_kzalloc(&pdev
->dev
, sizeof(struct tegra_cec
), GFP_KERNEL
);
351 res
= platform_get_resource(pdev
, IORESOURCE_MEM
, 0);
355 "Unable to allocate resources for device\n");
359 if (!devm_request_mem_region(&pdev
->dev
, res
->start
, resource_size(res
),
362 "Unable to request mem region for device\n");
366 cec
->tegra_cec_irq
= platform_get_irq(pdev
, 0);
368 if (cec
->tegra_cec_irq
<= 0)
371 cec
->cec_base
= devm_ioremap_nocache(&pdev
->dev
, res
->start
,
374 if (!cec
->cec_base
) {
375 dev_err(&pdev
->dev
, "Unable to grab IOs for device\n");
379 cec
->clk
= devm_clk_get(&pdev
->dev
, "cec");
381 if (IS_ERR_OR_NULL(cec
->clk
)) {
382 dev_err(&pdev
->dev
, "Can't get clock for CEC\n");
386 clk_prepare_enable(cec
->clk
);
388 /* set context info. */
389 cec
->dev
= &pdev
->dev
;
391 platform_set_drvdata(pdev
, cec
);
393 ret
= devm_request_threaded_irq(&pdev
->dev
, cec
->tegra_cec_irq
,
394 tegra_cec_irq_handler
, tegra_cec_irq_thread_handler
,
395 0, "cec_irq", &pdev
->dev
);
399 "Unable to request interrupt for device\n");
403 cec
->notifier
= cec_notifier_get(&hdmi_dev
->dev
);
404 if (!cec
->notifier
) {
409 cec
->adap
= cec_allocate_adapter(&tegra_cec_ops
, cec
, TEGRA_CEC_NAME
,
410 CEC_CAP_DEFAULTS
| CEC_CAP_MONITOR_ALL
,
412 if (IS_ERR(cec
->adap
)) {
414 dev_err(&pdev
->dev
, "Couldn't create cec adapter\n");
417 ret
= cec_register_adapter(cec
->adap
, &pdev
->dev
);
419 dev_err(&pdev
->dev
, "Couldn't register device\n");
423 cec_register_cec_notifier(cec
->adap
, cec
->notifier
);
429 cec_notifier_put(cec
->notifier
);
430 cec_delete_adapter(cec
->adap
);
432 clk_disable_unprepare(cec
->clk
);
436 static int tegra_cec_remove(struct platform_device
*pdev
)
438 struct tegra_cec
*cec
= platform_get_drvdata(pdev
);
440 clk_disable_unprepare(cec
->clk
);
442 cec_unregister_adapter(cec
->adap
);
443 cec_notifier_put(cec
->notifier
);
449 static int tegra_cec_suspend(struct platform_device
*pdev
, pm_message_t state
)
451 struct tegra_cec
*cec
= platform_get_drvdata(pdev
);
453 clk_disable_unprepare(cec
->clk
);
455 dev_notice(&pdev
->dev
, "suspended\n");
459 static int tegra_cec_resume(struct platform_device
*pdev
)
461 struct tegra_cec
*cec
= platform_get_drvdata(pdev
);
463 dev_notice(&pdev
->dev
, "Resuming\n");
465 clk_prepare_enable(cec
->clk
);
471 static const struct of_device_id tegra_cec_of_match
[] = {
472 { .compatible
= "nvidia,tegra114-cec", },
473 { .compatible
= "nvidia,tegra124-cec", },
474 { .compatible
= "nvidia,tegra210-cec", },
478 static struct platform_driver tegra_cec_driver
= {
480 .name
= TEGRA_CEC_NAME
,
481 .of_match_table
= of_match_ptr(tegra_cec_of_match
),
483 .probe
= tegra_cec_probe
,
484 .remove
= tegra_cec_remove
,
487 .suspend
= tegra_cec_suspend
,
488 .resume
= tegra_cec_resume
,
492 module_platform_driver(tegra_cec_driver
);
494 MODULE_DESCRIPTION("Tegra HDMI CEC driver");
495 MODULE_AUTHOR("NVIDIA CORPORATION");
496 MODULE_AUTHOR("Cisco Systems, Inc. and/or its affiliates");
497 MODULE_LICENSE("GPL v2");