Linux kernel mirror (for testing) git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git
kernel os linux
1
fork

Configure Feed

Select the types of activity you want to include in your feed.

media: platform: synopsys: Add support for HDMI input driver

Add initial support for the Synopsys DesignWare HDMI RX
Controller Driver used by Rockchip RK3588. The driver
supports:
- HDMI 1.4b and 2.0 modes (HDMI 4k@60Hz)
- RGB888, YUV422, YUV444 and YCC420 pixel formats
- CEC
- EDID configuration

The hardware also has Audio and HDCP capabilities, but these are
not yet supported by the driver.

Co-developed-by: Dingxian Wen <shawn.wen@rock-chips.com>
Signed-off-by: Dingxian Wen <shawn.wen@rock-chips.com>
Signed-off-by: Shreeya Patel <shreeya.patel@collabora.com>
Signed-off-by: Dmitry Osipenko <dmitry.osipenko@collabora.com>
Signed-off-by: Hans Verkuil <hverkuil@xs4all.nl>

authored by

Shreeya Patel and committed by
Hans Verkuil
7b59b132 94363326

+3508
+1
drivers/media/platform/Kconfig
··· 85 85 source "drivers/media/platform/samsung/Kconfig" 86 86 source "drivers/media/platform/st/Kconfig" 87 87 source "drivers/media/platform/sunxi/Kconfig" 88 + source "drivers/media/platform/synopsys/Kconfig" 88 89 source "drivers/media/platform/ti/Kconfig" 89 90 source "drivers/media/platform/verisilicon/Kconfig" 90 91 source "drivers/media/platform/via/Kconfig"
+1
drivers/media/platform/Makefile
··· 28 28 obj-y += samsung/ 29 29 obj-y += st/ 30 30 obj-y += sunxi/ 31 + obj-y += synopsys/ 31 32 obj-y += ti/ 32 33 obj-y += verisilicon/ 33 34 obj-y += via/
+3
drivers/media/platform/synopsys/Kconfig
··· 1 + # SPDX-License-Identifier: GPL-2.0-only 2 + 3 + source "drivers/media/platform/synopsys/hdmirx/Kconfig"
+2
drivers/media/platform/synopsys/Makefile
··· 1 + # SPDX-License-Identifier: GPL-2.0-only 2 + obj-y += hdmirx/
+35
drivers/media/platform/synopsys/hdmirx/Kconfig
··· 1 + # SPDX-License-Identifier: GPL-2.0 2 + 3 + config VIDEO_SYNOPSYS_HDMIRX 4 + tristate "Synopsys DesignWare HDMI Receiver driver" 5 + depends on VIDEO_DEV 6 + select MEDIA_CONTROLLER 7 + select VIDEO_V4L2_SUBDEV_API 8 + select VIDEOBUF2_DMA_CONTIG 9 + select CEC_CORE 10 + select HDMI 11 + help 12 + Support for Synopsys HDMI HDMI RX Controller. 13 + This driver supports HDMI 2.0 version. 14 + 15 + To compile this driver as a module, choose M here. The module 16 + will be called synopsys_hdmirx. 17 + 18 + config VIDEO_SYNOPSYS_HDMIRX_LOAD_DEFAULT_EDID 19 + bool "Load default EDID" 20 + depends on VIDEO_SYNOPSYS_HDMIRX 21 + help 22 + Preload default EDID (Extended Display Identification Data) 23 + branded by Linux Foundation that exposes display modes up 24 + to 4k@30Hz, which have best compatibility with HDMI transmitters. 25 + 26 + Enabling this option is recommended for a non-production use-cases. 27 + It will make driver usable out-of-the-box. 28 + 29 + For a higher display modes you will need to load customized EDID 30 + from userspace using v4l2-ctl tool or by other means. 31 + 32 + Without enabling this option driver will be practically 33 + non-functional until EDID will be loaded from userspace. 34 + Which is a wanted behavior when using this driver in a 35 + commercial product that should utilize own branded EDID.
+4
drivers/media/platform/synopsys/hdmirx/Makefile
··· 1 + # SPDX-License-Identifier: GPL-2.0 2 + synopsys-hdmirx-objs := snps_hdmirx.o snps_hdmirx_cec.o 3 + 4 + obj-$(CONFIG_VIDEO_SYNOPSYS_HDMIRX) += synopsys-hdmirx.o
+2750
drivers/media/platform/synopsys/hdmirx/snps_hdmirx.c
··· 1 + // SPDX-License-Identifier: GPL-2.0 2 + /* 3 + * Copyright (C) 2025 Collabora, Ltd. 4 + * Author: Shreeya Patel <shreeya.patel@collabora.com> 5 + * Author: Dmitry Osipenko <dmitry.osipenko@collabora.com> 6 + * 7 + * Copyright (c) 2021 Rockchip Electronics Co. Ltd. 8 + * Author: Dingxian Wen <shawn.wen@rock-chips.com> 9 + */ 10 + 11 + #include <linux/clk.h> 12 + #include <linux/completion.h> 13 + #include <linux/delay.h> 14 + #include <linux/dma-mapping.h> 15 + #include <linux/gpio/consumer.h> 16 + #include <linux/hdmi.h> 17 + #include <linux/interrupt.h> 18 + #include <linux/irq.h> 19 + #include <linux/mfd/syscon.h> 20 + #include <linux/module.h> 21 + #include <linux/of.h> 22 + #include <linux/of_platform.h> 23 + #include <linux/of_reserved_mem.h> 24 + #include <linux/pinctrl/consumer.h> 25 + #include <linux/platform_device.h> 26 + #include <linux/property.h> 27 + #include <linux/regmap.h> 28 + #include <linux/reset.h> 29 + #include <linux/v4l2-dv-timings.h> 30 + #include <linux/workqueue.h> 31 + 32 + #include <media/cec.h> 33 + #include <media/v4l2-common.h> 34 + #include <media/v4l2-ctrls.h> 35 + #include <media/v4l2-device.h> 36 + #include <media/v4l2-dv-timings.h> 37 + #include <media/v4l2-event.h> 38 + #include <media/v4l2-fh.h> 39 + #include <media/v4l2-ioctl.h> 40 + #include <media/videobuf2-dma-contig.h> 41 + #include <media/videobuf2-v4l2.h> 42 + #include <media/v4l2-common.h> 43 + 44 + #include <sound/hdmi-codec.h> 45 + 46 + #include "snps_hdmirx.h" 47 + #include "snps_hdmirx_cec.h" 48 + 49 + #define EDID_NUM_BLOCKS_MAX 4 50 + #define EDID_BLOCK_SIZE 128 51 + #define HDMIRX_PLANE_Y 0 52 + #define HDMIRX_PLANE_CBCR 1 53 + #define FILTER_FRAME_CNT 6 54 + 55 + static int debug; 56 + module_param(debug, int, 0644); 57 + MODULE_PARM_DESC(debug, "debug level (0-3)"); 58 + 59 + enum hdmirx_pix_fmt { 60 + HDMIRX_RGB888 = 0, 61 + HDMIRX_YUV422 = 1, 62 + HDMIRX_YUV444 = 2, 63 + HDMIRX_YUV420 = 3, 64 + }; 65 + 66 + enum ddr_store_fmt { 67 + STORE_RGB888 = 0, 68 + STORE_RGBA_ARGB, 69 + STORE_YUV420_8BIT, 70 + STORE_YUV420_10BIT, 71 + STORE_YUV422_8BIT, 72 + STORE_YUV422_10BIT, 73 + STORE_YUV444_8BIT, 74 + STORE_YUV420_16BIT = 8, 75 + STORE_YUV422_16BIT = 9, 76 + }; 77 + 78 + enum hdmirx_reg_attr { 79 + HDMIRX_ATTR_RW = 0, 80 + HDMIRX_ATTR_RO = 1, 81 + HDMIRX_ATTR_WO = 2, 82 + HDMIRX_ATTR_RE = 3, 83 + }; 84 + 85 + enum { 86 + HDMIRX_RST_A, 87 + HDMIRX_RST_P, 88 + HDMIRX_RST_REF, 89 + HDMIRX_RST_BIU, 90 + HDMIRX_NUM_RST, 91 + }; 92 + 93 + static const char *const pix_fmt_str[] = { 94 + "RGB888", 95 + "YUV422", 96 + "YUV444", 97 + "YUV420", 98 + }; 99 + 100 + struct hdmirx_buffer { 101 + struct vb2_v4l2_buffer vb; 102 + struct list_head queue; 103 + u32 buff_addr[VIDEO_MAX_PLANES]; 104 + }; 105 + 106 + struct hdmirx_stream { 107 + struct snps_hdmirx_dev *hdmirx_dev; 108 + struct video_device vdev; 109 + struct vb2_queue buf_queue; 110 + struct list_head buf_head; 111 + struct hdmirx_buffer *curr_buf; 112 + struct hdmirx_buffer *next_buf; 113 + struct v4l2_pix_format_mplane pixm; 114 + const struct v4l2_format_info *out_finfo; 115 + struct mutex vlock; /* to lock resources associated with video buffer and video device */ 116 + spinlock_t vbq_lock; /* to lock video buffer queue */ 117 + bool stopping; 118 + wait_queue_head_t wq_stopped; 119 + u32 frame_idx; 120 + u32 line_flag_int_cnt; 121 + u32 irq_stat; 122 + }; 123 + 124 + struct snps_hdmirx_dev { 125 + struct device *dev; 126 + struct device *codec_dev; 127 + struct hdmirx_stream stream; 128 + struct v4l2_device v4l2_dev; 129 + struct v4l2_ctrl_handler hdl; 130 + struct v4l2_ctrl *detect_tx_5v_ctrl; 131 + struct v4l2_ctrl *rgb_range; 132 + struct v4l2_ctrl *content_type; 133 + struct v4l2_dv_timings timings; 134 + struct gpio_desc *detect_5v_gpio; 135 + struct delayed_work delayed_work_hotplug; 136 + struct delayed_work delayed_work_res_change; 137 + struct hdmirx_cec *cec; 138 + struct mutex stream_lock; /* to lock video stream capture */ 139 + struct mutex work_lock; /* to lock the critical section of hotplug event */ 140 + struct reset_control_bulk_data resets[HDMIRX_NUM_RST]; 141 + struct clk_bulk_data *clks; 142 + struct regmap *grf; 143 + struct regmap *vo1_grf; 144 + struct completion cr_write_done; 145 + struct completion timer_base_lock; 146 + struct completion avi_pkt_rcv; 147 + struct dentry *debugfs_dir; 148 + struct v4l2_debugfs_if *infoframes; 149 + enum hdmirx_pix_fmt pix_fmt; 150 + void __iomem *regs; 151 + int hdmi_irq; 152 + int dma_irq; 153 + int det_irq; 154 + bool hpd_trigger_level_high; 155 + bool tmds_clk_ratio; 156 + bool plugged; 157 + u32 num_clks; 158 + u32 edid_blocks_written; 159 + u32 cur_fmt_fourcc; 160 + u32 color_depth; 161 + u8 edid[EDID_NUM_BLOCKS_MAX * EDID_BLOCK_SIZE]; 162 + hdmi_codec_plugged_cb plugged_cb; 163 + spinlock_t rst_lock; /* to lock register access */ 164 + }; 165 + 166 + static const struct v4l2_dv_timings cea640x480 = V4L2_DV_BT_CEA_640X480P59_94; 167 + 168 + static const struct v4l2_dv_timings_cap hdmirx_timings_cap = { 169 + .type = V4L2_DV_BT_656_1120, 170 + .reserved = { 0 }, 171 + V4L2_INIT_BT_TIMINGS(640, 4096, /* min/max width */ 172 + 480, 2160, /* min/max height */ 173 + 20000000, 600000000, /* min/max pixelclock */ 174 + /* standards */ 175 + V4L2_DV_BT_STD_CEA861, 176 + /* capabilities */ 177 + V4L2_DV_BT_CAP_PROGRESSIVE | 178 + V4L2_DV_BT_CAP_INTERLACED) 179 + }; 180 + 181 + static void hdmirx_writel(struct snps_hdmirx_dev *hdmirx_dev, int reg, u32 val) 182 + { 183 + guard(spinlock_irqsave)(&hdmirx_dev->rst_lock); 184 + 185 + writel(val, hdmirx_dev->regs + reg); 186 + } 187 + 188 + static u32 hdmirx_readl(struct snps_hdmirx_dev *hdmirx_dev, int reg) 189 + { 190 + guard(spinlock_irqsave)(&hdmirx_dev->rst_lock); 191 + 192 + return readl(hdmirx_dev->regs + reg); 193 + } 194 + 195 + static void hdmirx_reset_dma(struct snps_hdmirx_dev *hdmirx_dev) 196 + { 197 + guard(spinlock_irqsave)(&hdmirx_dev->rst_lock); 198 + 199 + reset_control_reset(hdmirx_dev->resets[0].rstc); 200 + } 201 + 202 + static void hdmirx_update_bits(struct snps_hdmirx_dev *hdmirx_dev, int reg, 203 + u32 mask, u32 data) 204 + { 205 + u32 val; 206 + 207 + guard(spinlock_irqsave)(&hdmirx_dev->rst_lock); 208 + 209 + val = readl(hdmirx_dev->regs + reg) & ~mask; 210 + val |= (data & mask); 211 + writel(val, hdmirx_dev->regs + reg); 212 + } 213 + 214 + static int hdmirx_subscribe_event(struct v4l2_fh *fh, 215 + const struct v4l2_event_subscription *sub) 216 + { 217 + switch (sub->type) { 218 + case V4L2_EVENT_SOURCE_CHANGE: 219 + return v4l2_src_change_event_subscribe(fh, sub); 220 + case V4L2_EVENT_CTRL: 221 + return v4l2_ctrl_subscribe_event(fh, sub); 222 + default: 223 + break; 224 + } 225 + 226 + return -EINVAL; 227 + } 228 + 229 + static bool tx_5v_power_present(struct snps_hdmirx_dev *hdmirx_dev) 230 + { 231 + const unsigned int detection_threshold = 7; 232 + int val, i, cnt = 0; 233 + bool ret; 234 + 235 + for (i = 0; i < 10; i++) { 236 + usleep_range(1000, 1100); 237 + val = gpiod_get_value(hdmirx_dev->detect_5v_gpio); 238 + if (val > 0) 239 + cnt++; 240 + if (cnt >= detection_threshold) 241 + break; 242 + } 243 + 244 + ret = (cnt >= detection_threshold) ? true : false; 245 + v4l2_dbg(3, debug, &hdmirx_dev->v4l2_dev, "%s: %d\n", __func__, ret); 246 + 247 + return ret; 248 + } 249 + 250 + static bool signal_not_lock(struct snps_hdmirx_dev *hdmirx_dev) 251 + { 252 + u32 mu_status, dma_st10, cmu_st; 253 + 254 + mu_status = hdmirx_readl(hdmirx_dev, MAINUNIT_STATUS); 255 + dma_st10 = hdmirx_readl(hdmirx_dev, DMA_STATUS10); 256 + cmu_st = hdmirx_readl(hdmirx_dev, CMU_STATUS); 257 + 258 + if ((mu_status & TMDSVALID_STABLE_ST) && 259 + (dma_st10 & HDMIRX_LOCK) && 260 + (cmu_st & TMDSQPCLK_LOCKED_ST)) 261 + return false; 262 + 263 + return true; 264 + } 265 + 266 + static void hdmirx_get_timings(struct snps_hdmirx_dev *hdmirx_dev, 267 + struct v4l2_bt_timings *bt) 268 + { 269 + struct v4l2_device *v4l2_dev = &hdmirx_dev->v4l2_dev; 270 + u32 hact, vact, htotal, vtotal, fps; 271 + u32 hfp, hs, hbp, vfp, vs, vbp; 272 + u32 val; 273 + 274 + val = hdmirx_readl(hdmirx_dev, DMA_STATUS2); 275 + hact = (val >> 16) & 0xffff; 276 + vact = val & 0xffff; 277 + 278 + val = hdmirx_readl(hdmirx_dev, DMA_STATUS3); 279 + htotal = (val >> 16) & 0xffff; 280 + vtotal = val & 0xffff; 281 + 282 + val = hdmirx_readl(hdmirx_dev, DMA_STATUS4); 283 + hs = (val >> 16) & 0xffff; 284 + vs = val & 0xffff; 285 + 286 + val = hdmirx_readl(hdmirx_dev, DMA_STATUS5); 287 + hbp = (val >> 16) & 0xffff; 288 + vbp = val & 0xffff; 289 + 290 + if (hdmirx_dev->pix_fmt == HDMIRX_YUV420) { 291 + htotal *= 2; 292 + hbp *= 2; 293 + hs *= 2; 294 + } 295 + 296 + hfp = htotal - hact - hs - hbp; 297 + vfp = vtotal - vact - vs - vbp; 298 + 299 + fps = (bt->pixelclock + (htotal * vtotal) / 2) / (htotal * vtotal); 300 + bt->width = hact; 301 + bt->height = vact; 302 + bt->hfrontporch = hfp; 303 + bt->hsync = hs; 304 + bt->hbackporch = hbp; 305 + bt->vfrontporch = vfp; 306 + bt->vsync = vs; 307 + bt->vbackporch = vbp; 308 + 309 + v4l2_dbg(1, debug, v4l2_dev, "get timings from dma\n"); 310 + v4l2_dbg(1, debug, v4l2_dev, 311 + "act:%ux%u%s, total:%ux%u, fps:%u, pixclk:%llu\n", 312 + bt->width, bt->height, bt->interlaced ? "i" : "p", 313 + htotal, vtotal, fps, bt->pixelclock); 314 + 315 + v4l2_dbg(2, debug, v4l2_dev, 316 + "hfp:%u, hact:%u, hs:%u, hbp:%u, vfp:%u, vact:%u, vs:%u, vbp:%u\n", 317 + bt->hfrontporch, hact, bt->hsync, bt->hbackporch, 318 + bt->vfrontporch, vact, bt->vsync, bt->vbackporch); 319 + 320 + if (bt->interlaced == V4L2_DV_INTERLACED) { 321 + bt->height *= 2; 322 + bt->il_vfrontporch = bt->vfrontporch; 323 + bt->il_vsync = bt->vsync + 1; 324 + bt->il_vbackporch = bt->vbackporch; 325 + } 326 + } 327 + 328 + static bool hdmirx_check_timing_valid(struct v4l2_bt_timings *bt) 329 + { 330 + /* 331 + * Sanity-check timing values. Some of the values will be outside 332 + * of a valid range till hardware becomes ready to perform capture. 333 + */ 334 + if (bt->width < 100 || bt->width > 5000 || 335 + bt->height < 100 || bt->height > 5000) 336 + return false; 337 + 338 + if (!bt->hsync || bt->hsync > 200 || 339 + !bt->vsync || bt->vsync > 100) 340 + return false; 341 + 342 + /* 343 + * According to the CEA-861, 1280x720p25 Hblank timing is up to 2680, 344 + * and all standard video format timings are less than 3000. 345 + */ 346 + if (!bt->hbackporch || bt->hbackporch > 3000 || 347 + !bt->vbackporch || bt->vbackporch > 3000) 348 + return false; 349 + 350 + if (!bt->hfrontporch || bt->hfrontporch > 3000 || 351 + !bt->vfrontporch || bt->vfrontporch > 3000) 352 + return false; 353 + 354 + return true; 355 + } 356 + 357 + static void hdmirx_toggle_polarity(struct snps_hdmirx_dev *hdmirx_dev) 358 + { 359 + u32 val = hdmirx_readl(hdmirx_dev, DMA_CONFIG6); 360 + 361 + if (!(val & (VSYNC_TOGGLE_EN | HSYNC_TOGGLE_EN))) { 362 + hdmirx_update_bits(hdmirx_dev, DMA_CONFIG6, 363 + VSYNC_TOGGLE_EN | HSYNC_TOGGLE_EN, 364 + VSYNC_TOGGLE_EN | HSYNC_TOGGLE_EN); 365 + hdmirx_update_bits(hdmirx_dev, VIDEO_CONFIG2, 366 + VPROC_VSYNC_POL_OVR_VALUE | 367 + VPROC_VSYNC_POL_OVR_EN | 368 + VPROC_HSYNC_POL_OVR_VALUE | 369 + VPROC_HSYNC_POL_OVR_EN, 370 + VPROC_VSYNC_POL_OVR_EN | 371 + VPROC_HSYNC_POL_OVR_EN); 372 + return; 373 + } 374 + 375 + hdmirx_update_bits(hdmirx_dev, DMA_CONFIG6, 376 + VSYNC_TOGGLE_EN | HSYNC_TOGGLE_EN, 0); 377 + 378 + hdmirx_update_bits(hdmirx_dev, VIDEO_CONFIG2, 379 + VPROC_VSYNC_POL_OVR_VALUE | 380 + VPROC_VSYNC_POL_OVR_EN | 381 + VPROC_HSYNC_POL_OVR_VALUE | 382 + VPROC_HSYNC_POL_OVR_EN, 0); 383 + } 384 + 385 + /* 386 + * When querying DV timings during preview, if the DMA's timing is stable, 387 + * we retrieve the timings directly from the DMA. However, if the current 388 + * resolution is negative, obtaining the timing from CTRL may require a 389 + * change in the sync polarity, potentially leading to DMA errors. 390 + */ 391 + static int hdmirx_get_detected_timings(struct snps_hdmirx_dev *hdmirx_dev, 392 + struct v4l2_dv_timings *timings) 393 + { 394 + struct v4l2_device *v4l2_dev = &hdmirx_dev->v4l2_dev; 395 + struct v4l2_bt_timings *bt = &timings->bt; 396 + u32 val, tmdsqpclk_freq, pix_clk; 397 + unsigned int num_retries = 0; 398 + u32 field_type, deframer_st; 399 + u64 tmp_data, tmds_clk; 400 + bool is_dvi_mode; 401 + int ret; 402 + 403 + mutex_lock(&hdmirx_dev->work_lock); 404 + retry: 405 + memset(timings, 0, sizeof(struct v4l2_dv_timings)); 406 + timings->type = V4L2_DV_BT_656_1120; 407 + 408 + val = hdmirx_readl(hdmirx_dev, DMA_STATUS11); 409 + field_type = (val & HDMIRX_TYPE_MASK) >> 7; 410 + 411 + if (field_type & BIT(0)) 412 + bt->interlaced = V4L2_DV_INTERLACED; 413 + else 414 + bt->interlaced = V4L2_DV_PROGRESSIVE; 415 + 416 + deframer_st = hdmirx_readl(hdmirx_dev, DEFRAMER_STATUS); 417 + is_dvi_mode = !(deframer_st & OPMODE_STS_MASK); 418 + 419 + tmdsqpclk_freq = hdmirx_readl(hdmirx_dev, CMU_TMDSQPCLK_FREQ); 420 + tmds_clk = tmdsqpclk_freq * 4 * 1000; 421 + tmp_data = tmds_clk * 24; 422 + do_div(tmp_data, hdmirx_dev->color_depth); 423 + pix_clk = tmp_data; 424 + bt->pixelclock = pix_clk; 425 + 426 + if (hdmirx_dev->pix_fmt == HDMIRX_YUV420) 427 + bt->pixelclock *= 2; 428 + 429 + hdmirx_get_timings(hdmirx_dev, bt); 430 + 431 + v4l2_dbg(2, debug, v4l2_dev, "tmds_clk:%llu, pix_clk:%d\n", tmds_clk, pix_clk); 432 + v4l2_dbg(1, debug, v4l2_dev, "interlace:%d, fmt:%d, color:%d, mode:%s\n", 433 + bt->interlaced, hdmirx_dev->pix_fmt, 434 + hdmirx_dev->color_depth, 435 + is_dvi_mode ? "dvi" : "hdmi"); 436 + v4l2_dbg(2, debug, v4l2_dev, "deframer_st:%#x\n", deframer_st); 437 + 438 + /* 439 + * Timing will be invalid until it's latched by HW or if signal's 440 + * polarity doesn't match. 441 + */ 442 + if (!hdmirx_check_timing_valid(bt)) { 443 + if (num_retries++ < 20) { 444 + if (num_retries == 10) 445 + hdmirx_toggle_polarity(hdmirx_dev); 446 + 447 + usleep_range(10 * 1000, 10 * 1100); 448 + goto retry; 449 + } 450 + 451 + ret = -ERANGE; 452 + } else { 453 + ret = 0; 454 + } 455 + 456 + mutex_unlock(&hdmirx_dev->work_lock); 457 + 458 + return ret; 459 + } 460 + 461 + static bool port_no_link(struct snps_hdmirx_dev *hdmirx_dev) 462 + { 463 + return !tx_5v_power_present(hdmirx_dev); 464 + } 465 + 466 + static int hdmirx_query_dv_timings(struct file *file, void *_fh, 467 + struct v4l2_dv_timings *timings) 468 + { 469 + struct hdmirx_stream *stream = video_drvdata(file); 470 + struct snps_hdmirx_dev *hdmirx_dev = stream->hdmirx_dev; 471 + struct v4l2_device *v4l2_dev = &hdmirx_dev->v4l2_dev; 472 + int ret; 473 + 474 + if (port_no_link(hdmirx_dev)) { 475 + v4l2_err(v4l2_dev, "%s: port has no link\n", __func__); 476 + return -ENOLINK; 477 + } 478 + 479 + if (signal_not_lock(hdmirx_dev)) { 480 + v4l2_err(v4l2_dev, "%s: signal is not locked\n", __func__); 481 + return -ENOLCK; 482 + } 483 + 484 + ret = hdmirx_get_detected_timings(hdmirx_dev, timings); 485 + if (ret) 486 + return ret; 487 + 488 + if (debug) 489 + v4l2_print_dv_timings(hdmirx_dev->v4l2_dev.name, 490 + "query_dv_timings: ", timings, false); 491 + 492 + if (!v4l2_valid_dv_timings(timings, &hdmirx_timings_cap, NULL, NULL)) { 493 + v4l2_dbg(1, debug, v4l2_dev, "%s: timings out of range\n", __func__); 494 + return -ERANGE; 495 + } 496 + 497 + return 0; 498 + } 499 + 500 + static void hdmirx_hpd_ctrl(struct snps_hdmirx_dev *hdmirx_dev, bool en) 501 + { 502 + struct v4l2_device *v4l2_dev = &hdmirx_dev->v4l2_dev; 503 + 504 + v4l2_dbg(1, debug, v4l2_dev, "%s: %sable, hpd_trigger_level_high:%d\n", 505 + __func__, en ? "en" : "dis", hdmirx_dev->hpd_trigger_level_high); 506 + 507 + hdmirx_update_bits(hdmirx_dev, SCDC_CONFIG, HPDLOW, en ? 0 : HPDLOW); 508 + hdmirx_writel(hdmirx_dev, CORE_CONFIG, 509 + hdmirx_dev->hpd_trigger_level_high ? en : !en); 510 + 511 + /* 100ms delay as per HDMI spec */ 512 + if (!en) 513 + msleep(100); 514 + } 515 + 516 + static void hdmirx_write_edid_data(struct snps_hdmirx_dev *hdmirx_dev, 517 + u8 *edid, unsigned int num_blocks) 518 + { 519 + static u8 data[EDID_NUM_BLOCKS_MAX * EDID_BLOCK_SIZE]; 520 + unsigned int edid_len = num_blocks * EDID_BLOCK_SIZE; 521 + unsigned int i; 522 + 523 + cec_s_phys_addr_from_edid(hdmirx_dev->cec->adap, 524 + (const struct edid *)edid); 525 + 526 + hdmirx_update_bits(hdmirx_dev, DMA_CONFIG11, 527 + EDID_READ_EN_MASK | 528 + EDID_WRITE_EN_MASK | 529 + EDID_SLAVE_ADDR_MASK, 530 + EDID_READ_EN(0) | 531 + EDID_WRITE_EN(1) | 532 + EDID_SLAVE_ADDR(0x50)); 533 + for (i = 0; i < edid_len; i++) 534 + hdmirx_writel(hdmirx_dev, DMA_CONFIG10, edid[i]); 535 + 536 + /* read out for debug */ 537 + if (debug >= 2) { 538 + hdmirx_update_bits(hdmirx_dev, DMA_CONFIG11, 539 + EDID_READ_EN_MASK | 540 + EDID_WRITE_EN_MASK, 541 + EDID_READ_EN(1) | 542 + EDID_WRITE_EN(0)); 543 + 544 + for (i = 0; i < edid_len; i++) 545 + data[i] = hdmirx_readl(hdmirx_dev, DMA_STATUS14); 546 + 547 + print_hex_dump(KERN_INFO, "", DUMP_PREFIX_NONE, 16, 1, data, 548 + edid_len, false); 549 + } 550 + 551 + /* 552 + * Must set EDID_READ_EN & EDID_WRITE_EN bit to 0, 553 + * when the read/write edid operation is completed. Otherwise, it 554 + * will affect the reading and writing of other registers. 555 + */ 556 + hdmirx_update_bits(hdmirx_dev, DMA_CONFIG11, 557 + EDID_READ_EN_MASK | EDID_WRITE_EN_MASK, 558 + EDID_READ_EN(0) | EDID_WRITE_EN(0)); 559 + } 560 + 561 + static void hdmirx_write_edid(struct snps_hdmirx_dev *hdmirx_dev, 562 + struct v4l2_edid *edid) 563 + { 564 + memset(edid->reserved, 0, sizeof(edid->reserved)); 565 + memset(hdmirx_dev->edid, 0, sizeof(hdmirx_dev->edid)); 566 + 567 + hdmirx_write_edid_data(hdmirx_dev, edid->edid, edid->blocks); 568 + 569 + hdmirx_dev->edid_blocks_written = edid->blocks; 570 + memcpy(hdmirx_dev->edid, edid->edid, edid->blocks * EDID_BLOCK_SIZE); 571 + } 572 + 573 + /* 574 + * Before clearing interrupt, we need to read the interrupt status. 575 + */ 576 + static inline void hdmirx_clear_interrupt(struct snps_hdmirx_dev *hdmirx_dev, 577 + u32 reg, u32 val) 578 + { 579 + /* (interrupt status register) = (interrupt clear register) - 0x8 */ 580 + hdmirx_readl(hdmirx_dev, reg - 0x8); 581 + hdmirx_writel(hdmirx_dev, reg, val); 582 + } 583 + 584 + static void hdmirx_interrupts_setup(struct snps_hdmirx_dev *hdmirx_dev, bool en) 585 + { 586 + v4l2_dbg(1, debug, &hdmirx_dev->v4l2_dev, "%s: %sable\n", 587 + __func__, en ? "en" : "dis"); 588 + 589 + disable_irq(hdmirx_dev->hdmi_irq); 590 + 591 + /* Note: In DVI mode, it needs to be written twice to take effect. */ 592 + hdmirx_clear_interrupt(hdmirx_dev, MAINUNIT_0_INT_CLEAR, 0xffffffff); 593 + hdmirx_clear_interrupt(hdmirx_dev, MAINUNIT_2_INT_CLEAR, 0xffffffff); 594 + hdmirx_clear_interrupt(hdmirx_dev, MAINUNIT_0_INT_CLEAR, 0xffffffff); 595 + hdmirx_clear_interrupt(hdmirx_dev, MAINUNIT_2_INT_CLEAR, 0xffffffff); 596 + hdmirx_clear_interrupt(hdmirx_dev, AVPUNIT_0_INT_CLEAR, 0xffffffff); 597 + 598 + if (en) { 599 + hdmirx_update_bits(hdmirx_dev, MAINUNIT_0_INT_MASK_N, 600 + TMDSQPCLK_OFF_CHG | TMDSQPCLK_LOCKED_CHG, 601 + TMDSQPCLK_OFF_CHG | TMDSQPCLK_LOCKED_CHG); 602 + hdmirx_update_bits(hdmirx_dev, MAINUNIT_2_INT_MASK_N, 603 + TMDSVALID_STABLE_CHG, TMDSVALID_STABLE_CHG); 604 + hdmirx_update_bits(hdmirx_dev, AVPUNIT_0_INT_MASK_N, 605 + CED_DYN_CNT_CH2_IRQ | 606 + CED_DYN_CNT_CH1_IRQ | 607 + CED_DYN_CNT_CH0_IRQ, 608 + CED_DYN_CNT_CH2_IRQ | 609 + CED_DYN_CNT_CH1_IRQ | 610 + CED_DYN_CNT_CH0_IRQ); 611 + } else { 612 + hdmirx_writel(hdmirx_dev, MAINUNIT_0_INT_MASK_N, 0); 613 + hdmirx_writel(hdmirx_dev, MAINUNIT_2_INT_MASK_N, 0); 614 + hdmirx_writel(hdmirx_dev, AVPUNIT_0_INT_MASK_N, 0); 615 + } 616 + 617 + enable_irq(hdmirx_dev->hdmi_irq); 618 + } 619 + 620 + static void hdmirx_plugout(struct snps_hdmirx_dev *hdmirx_dev) 621 + { 622 + if (!hdmirx_dev->plugged) 623 + return; 624 + 625 + hdmirx_update_bits(hdmirx_dev, SCDC_CONFIG, POWERPROVIDED, 0); 626 + hdmirx_interrupts_setup(hdmirx_dev, false); 627 + hdmirx_update_bits(hdmirx_dev, DMA_CONFIG6, HDMIRX_DMA_EN, 0); 628 + hdmirx_update_bits(hdmirx_dev, DMA_CONFIG4, 629 + LINE_FLAG_INT_EN | 630 + HDMIRX_DMA_IDLE_INT | 631 + HDMIRX_LOCK_DISABLE_INT | 632 + LAST_FRAME_AXI_UNFINISH_INT_EN | 633 + FIFO_OVERFLOW_INT_EN | 634 + FIFO_UNDERFLOW_INT_EN | 635 + HDMIRX_AXI_ERROR_INT_EN, 0); 636 + hdmirx_reset_dma(hdmirx_dev); 637 + hdmirx_update_bits(hdmirx_dev, PHY_CONFIG, HDMI_DISABLE | PHY_RESET | 638 + PHY_PDDQ, HDMI_DISABLE); 639 + hdmirx_writel(hdmirx_dev, PHYCREG_CONFIG0, 0x0); 640 + cancel_delayed_work(&hdmirx_dev->delayed_work_res_change); 641 + 642 + /* will be NULL on driver removal */ 643 + if (hdmirx_dev->rgb_range) 644 + v4l2_ctrl_s_ctrl(hdmirx_dev->rgb_range, V4L2_DV_RGB_RANGE_AUTO); 645 + 646 + if (hdmirx_dev->content_type) 647 + v4l2_ctrl_s_ctrl(hdmirx_dev->content_type, 648 + V4L2_DV_IT_CONTENT_TYPE_NO_ITC); 649 + 650 + hdmirx_dev->plugged = false; 651 + } 652 + 653 + static int hdmirx_set_edid(struct file *file, void *fh, struct v4l2_edid *edid) 654 + { 655 + struct hdmirx_stream *stream = video_drvdata(file); 656 + struct snps_hdmirx_dev *hdmirx_dev = stream->hdmirx_dev; 657 + u16 phys_addr; 658 + int err; 659 + 660 + if (edid->pad) 661 + return -EINVAL; 662 + 663 + if (edid->start_block) 664 + return -EINVAL; 665 + 666 + if (edid->blocks > EDID_NUM_BLOCKS_MAX) { 667 + edid->blocks = EDID_NUM_BLOCKS_MAX; 668 + return -E2BIG; 669 + } 670 + 671 + if (edid->blocks) { 672 + phys_addr = cec_get_edid_phys_addr(edid->edid, 673 + edid->blocks * EDID_BLOCK_SIZE, 674 + NULL); 675 + 676 + err = v4l2_phys_addr_validate(phys_addr, &phys_addr, NULL); 677 + if (err) 678 + return err; 679 + } 680 + 681 + /* 682 + * Touching HW registers in parallel with plugin/out handlers 683 + * will bring hardware into a bad state. 684 + */ 685 + mutex_lock(&hdmirx_dev->work_lock); 686 + 687 + hdmirx_hpd_ctrl(hdmirx_dev, false); 688 + 689 + if (edid->blocks) { 690 + hdmirx_write_edid(hdmirx_dev, edid); 691 + hdmirx_hpd_ctrl(hdmirx_dev, true); 692 + } else { 693 + cec_phys_addr_invalidate(hdmirx_dev->cec->adap); 694 + hdmirx_dev->edid_blocks_written = 0; 695 + } 696 + 697 + mutex_unlock(&hdmirx_dev->work_lock); 698 + 699 + return 0; 700 + } 701 + 702 + static int hdmirx_get_edid(struct file *file, void *fh, struct v4l2_edid *edid) 703 + { 704 + struct hdmirx_stream *stream = video_drvdata(file); 705 + struct snps_hdmirx_dev *hdmirx_dev = stream->hdmirx_dev; 706 + struct v4l2_device *v4l2_dev = &hdmirx_dev->v4l2_dev; 707 + 708 + memset(edid->reserved, 0, sizeof(edid->reserved)); 709 + 710 + if (edid->pad) 711 + return -EINVAL; 712 + 713 + if (!edid->start_block && !edid->blocks) { 714 + edid->blocks = hdmirx_dev->edid_blocks_written; 715 + return 0; 716 + } 717 + 718 + if (!hdmirx_dev->edid_blocks_written) 719 + return -ENODATA; 720 + 721 + if (edid->start_block >= hdmirx_dev->edid_blocks_written || !edid->blocks) 722 + return -EINVAL; 723 + 724 + if (edid->start_block + edid->blocks > hdmirx_dev->edid_blocks_written) 725 + edid->blocks = hdmirx_dev->edid_blocks_written - edid->start_block; 726 + 727 + memcpy(edid->edid, hdmirx_dev->edid, edid->blocks * EDID_BLOCK_SIZE); 728 + 729 + v4l2_dbg(1, debug, v4l2_dev, "%s: read EDID:\n", __func__); 730 + if (debug > 0) 731 + print_hex_dump(KERN_INFO, "", DUMP_PREFIX_NONE, 16, 1, 732 + edid->edid, edid->blocks * EDID_BLOCK_SIZE, false); 733 + 734 + return 0; 735 + } 736 + 737 + static int hdmirx_g_parm(struct file *file, void *priv, 738 + struct v4l2_streamparm *parm) 739 + { 740 + struct hdmirx_stream *stream = video_drvdata(file); 741 + struct snps_hdmirx_dev *hdmirx_dev = stream->hdmirx_dev; 742 + 743 + if (parm->type != V4L2_BUF_TYPE_VIDEO_CAPTURE_MPLANE) 744 + return -EINVAL; 745 + 746 + parm->parm.capture.timeperframe = v4l2_calc_timeperframe(&hdmirx_dev->timings); 747 + 748 + return 0; 749 + } 750 + 751 + static int hdmirx_dv_timings_cap(struct file *file, void *fh, 752 + struct v4l2_dv_timings_cap *cap) 753 + { 754 + *cap = hdmirx_timings_cap; 755 + return 0; 756 + } 757 + 758 + static int hdmirx_enum_dv_timings(struct file *file, void *_fh, 759 + struct v4l2_enum_dv_timings *timings) 760 + { 761 + return v4l2_enum_dv_timings_cap(timings, &hdmirx_timings_cap, NULL, NULL); 762 + } 763 + 764 + static void hdmirx_scdc_init(struct snps_hdmirx_dev *hdmirx_dev) 765 + { 766 + hdmirx_update_bits(hdmirx_dev, I2C_SLAVE_CONFIG1, 767 + I2C_SDA_OUT_HOLD_VALUE_QST_MASK | 768 + I2C_SDA_IN_HOLD_VALUE_QST_MASK, 769 + I2C_SDA_OUT_HOLD_VALUE_QST(0x80) | 770 + I2C_SDA_IN_HOLD_VALUE_QST(0x15)); 771 + hdmirx_update_bits(hdmirx_dev, SCDC_REGBANK_CONFIG0, 772 + SCDC_SINKVERSION_QST_MASK, 773 + SCDC_SINKVERSION_QST(1)); 774 + } 775 + 776 + static int wait_reg_bit_status(struct snps_hdmirx_dev *hdmirx_dev, u32 reg, 777 + u32 bit_mask, u32 expect_val, bool is_grf, 778 + u32 ms) 779 + { 780 + struct v4l2_device *v4l2_dev = &hdmirx_dev->v4l2_dev; 781 + u32 i, val; 782 + 783 + for (i = 0; i < ms; i++) { 784 + if (is_grf) 785 + regmap_read(hdmirx_dev->grf, reg, &val); 786 + else 787 + val = hdmirx_readl(hdmirx_dev, reg); 788 + 789 + if ((val & bit_mask) == expect_val) { 790 + v4l2_dbg(2, debug, v4l2_dev, 791 + "%s: i:%d, time: %dms\n", __func__, i, ms); 792 + break; 793 + } 794 + usleep_range(1000, 1010); 795 + } 796 + 797 + if (i == ms) 798 + return -1; 799 + 800 + return 0; 801 + } 802 + 803 + static int hdmirx_phy_register_write(struct snps_hdmirx_dev *hdmirx_dev, 804 + u32 phy_reg, u32 val) 805 + { 806 + struct device *dev = hdmirx_dev->dev; 807 + 808 + reinit_completion(&hdmirx_dev->cr_write_done); 809 + /* clear irq status */ 810 + hdmirx_clear_interrupt(hdmirx_dev, MAINUNIT_2_INT_CLEAR, 0xffffffff); 811 + /* en irq */ 812 + hdmirx_update_bits(hdmirx_dev, MAINUNIT_2_INT_MASK_N, 813 + PHYCREG_CR_WRITE_DONE, PHYCREG_CR_WRITE_DONE); 814 + /* write phy reg addr */ 815 + hdmirx_writel(hdmirx_dev, PHYCREG_CONFIG1, phy_reg); 816 + /* write phy reg val */ 817 + hdmirx_writel(hdmirx_dev, PHYCREG_CONFIG2, val); 818 + /* config write enable */ 819 + hdmirx_writel(hdmirx_dev, PHYCREG_CONTROL, PHYCREG_CR_PARA_WRITE_P); 820 + 821 + if (!wait_for_completion_timeout(&hdmirx_dev->cr_write_done, 822 + msecs_to_jiffies(20))) { 823 + dev_err(dev, "%s wait cr write done failed\n", __func__); 824 + return -1; 825 + } 826 + 827 + return 0; 828 + } 829 + 830 + static void hdmirx_tmds_clk_ratio_config(struct snps_hdmirx_dev *hdmirx_dev) 831 + { 832 + struct v4l2_device *v4l2_dev = &hdmirx_dev->v4l2_dev; 833 + u32 val; 834 + 835 + val = hdmirx_readl(hdmirx_dev, SCDC_REGBANK_STATUS1); 836 + v4l2_dbg(3, debug, v4l2_dev, "%s: scdc_regbank_st:%#x\n", __func__, val); 837 + hdmirx_dev->tmds_clk_ratio = (val & SCDC_TMDSBITCLKRATIO) > 0; 838 + 839 + if (hdmirx_dev->tmds_clk_ratio) { 840 + v4l2_dbg(3, debug, v4l2_dev, "%s: HDMITX greater than 3.4Gbps\n", __func__); 841 + hdmirx_update_bits(hdmirx_dev, PHY_CONFIG, 842 + TMDS_CLOCK_RATIO, TMDS_CLOCK_RATIO); 843 + } else { 844 + v4l2_dbg(3, debug, v4l2_dev, "%s: HDMITX less than 3.4Gbps\n", __func__); 845 + hdmirx_update_bits(hdmirx_dev, PHY_CONFIG, 846 + TMDS_CLOCK_RATIO, 0); 847 + } 848 + } 849 + 850 + static void hdmirx_phy_config(struct snps_hdmirx_dev *hdmirx_dev) 851 + { 852 + struct device *dev = hdmirx_dev->dev; 853 + 854 + hdmirx_clear_interrupt(hdmirx_dev, SCDC_INT_CLEAR, 0xffffffff); 855 + hdmirx_update_bits(hdmirx_dev, SCDC_INT_MASK_N, SCDCTMDSCCFG_CHG, 856 + SCDCTMDSCCFG_CHG); 857 + /* cr_para_clk 24M */ 858 + hdmirx_update_bits(hdmirx_dev, PHY_CONFIG, REFFREQ_SEL_MASK, REFFREQ_SEL(0)); 859 + /* rx data width 40bit valid */ 860 + hdmirx_update_bits(hdmirx_dev, PHY_CONFIG, RXDATA_WIDTH, RXDATA_WIDTH); 861 + hdmirx_update_bits(hdmirx_dev, PHY_CONFIG, PHY_RESET, PHY_RESET); 862 + usleep_range(100, 110); 863 + hdmirx_update_bits(hdmirx_dev, PHY_CONFIG, PHY_RESET, 0); 864 + usleep_range(100, 110); 865 + /* select cr para interface */ 866 + hdmirx_writel(hdmirx_dev, PHYCREG_CONFIG0, 0x3); 867 + 868 + if (wait_reg_bit_status(hdmirx_dev, SYS_GRF_SOC_STATUS1, 869 + HDMIRXPHY_SRAM_INIT_DONE, 870 + HDMIRXPHY_SRAM_INIT_DONE, true, 10)) 871 + dev_err(dev, "%s: phy SRAM init failed\n", __func__); 872 + 873 + regmap_write(hdmirx_dev->grf, SYS_GRF_SOC_CON1, 874 + (HDMIRXPHY_SRAM_EXT_LD_DONE << 16) | 875 + HDMIRXPHY_SRAM_EXT_LD_DONE); 876 + hdmirx_phy_register_write(hdmirx_dev, SUP_DIG_ANA_CREGS_SUP_ANA_NC, 2); 877 + hdmirx_phy_register_write(hdmirx_dev, SUP_DIG_ANA_CREGS_SUP_ANA_NC, 3); 878 + hdmirx_phy_register_write(hdmirx_dev, SUP_DIG_ANA_CREGS_SUP_ANA_NC, 2); 879 + hdmirx_phy_register_write(hdmirx_dev, SUP_DIG_ANA_CREGS_SUP_ANA_NC, 2); 880 + hdmirx_phy_register_write(hdmirx_dev, SUP_DIG_ANA_CREGS_SUP_ANA_NC, 3); 881 + hdmirx_phy_register_write(hdmirx_dev, SUP_DIG_ANA_CREGS_SUP_ANA_NC, 2); 882 + hdmirx_phy_register_write(hdmirx_dev, SUP_DIG_ANA_CREGS_SUP_ANA_NC, 0); 883 + hdmirx_phy_register_write(hdmirx_dev, SUP_DIG_ANA_CREGS_SUP_ANA_NC, 1); 884 + hdmirx_phy_register_write(hdmirx_dev, SUP_DIG_ANA_CREGS_SUP_ANA_NC, 0); 885 + hdmirx_phy_register_write(hdmirx_dev, SUP_DIG_ANA_CREGS_SUP_ANA_NC, 0); 886 + 887 + hdmirx_phy_register_write(hdmirx_dev, 888 + HDMIPCS_DIG_CTRL_PATH_MAIN_FSM_RATE_CALC_HDMI14_CDR_SETTING_3_REG, 889 + CDR_SETTING_BOUNDARY_3_DEFAULT); 890 + hdmirx_phy_register_write(hdmirx_dev, 891 + HDMIPCS_DIG_CTRL_PATH_MAIN_FSM_RATE_CALC_HDMI14_CDR_SETTING_4_REG, 892 + CDR_SETTING_BOUNDARY_4_DEFAULT); 893 + hdmirx_phy_register_write(hdmirx_dev, 894 + HDMIPCS_DIG_CTRL_PATH_MAIN_FSM_RATE_CALC_HDMI14_CDR_SETTING_5_REG, 895 + CDR_SETTING_BOUNDARY_5_DEFAULT); 896 + hdmirx_phy_register_write(hdmirx_dev, 897 + HDMIPCS_DIG_CTRL_PATH_MAIN_FSM_RATE_CALC_HDMI14_CDR_SETTING_6_REG, 898 + CDR_SETTING_BOUNDARY_6_DEFAULT); 899 + hdmirx_phy_register_write(hdmirx_dev, 900 + HDMIPCS_DIG_CTRL_PATH_MAIN_FSM_RATE_CALC_HDMI14_CDR_SETTING_7_REG, 901 + CDR_SETTING_BOUNDARY_7_DEFAULT); 902 + 903 + hdmirx_update_bits(hdmirx_dev, PHY_CONFIG, PHY_PDDQ, 0); 904 + if (wait_reg_bit_status(hdmirx_dev, PHY_STATUS, PDDQ_ACK, 0, false, 10)) 905 + dev_err(dev, "%s: wait pddq ack failed\n", __func__); 906 + 907 + hdmirx_update_bits(hdmirx_dev, PHY_CONFIG, HDMI_DISABLE, 0); 908 + if (wait_reg_bit_status(hdmirx_dev, PHY_STATUS, HDMI_DISABLE_ACK, 0, 909 + false, 50)) 910 + dev_err(dev, "%s: wait hdmi disable ack failed\n", __func__); 911 + 912 + hdmirx_tmds_clk_ratio_config(hdmirx_dev); 913 + } 914 + 915 + static void hdmirx_controller_init(struct snps_hdmirx_dev *hdmirx_dev) 916 + { 917 + const unsigned long iref_clk_freq_hz = 428571429; 918 + struct device *dev = hdmirx_dev->dev; 919 + 920 + reinit_completion(&hdmirx_dev->timer_base_lock); 921 + hdmirx_clear_interrupt(hdmirx_dev, MAINUNIT_0_INT_CLEAR, 0xffffffff); 922 + /* en irq */ 923 + hdmirx_update_bits(hdmirx_dev, MAINUNIT_0_INT_MASK_N, 924 + TIMER_BASE_LOCKED_IRQ, TIMER_BASE_LOCKED_IRQ); 925 + /* write irefclk freq */ 926 + hdmirx_writel(hdmirx_dev, GLOBAL_TIMER_REF_BASE, iref_clk_freq_hz); 927 + 928 + if (!wait_for_completion_timeout(&hdmirx_dev->timer_base_lock, 929 + msecs_to_jiffies(20))) 930 + dev_err(dev, "%s wait timer base lock failed\n", __func__); 931 + 932 + hdmirx_update_bits(hdmirx_dev, CMU_CONFIG0, 933 + TMDSQPCLK_STABLE_FREQ_MARGIN_MASK | 934 + AUDCLK_STABLE_FREQ_MARGIN_MASK, 935 + TMDSQPCLK_STABLE_FREQ_MARGIN(2) | 936 + AUDCLK_STABLE_FREQ_MARGIN(1)); 937 + hdmirx_update_bits(hdmirx_dev, DESCRAND_EN_CONTROL, 938 + SCRAMB_EN_SEL_QST_MASK, SCRAMB_EN_SEL_QST(1)); 939 + hdmirx_update_bits(hdmirx_dev, CED_CONFIG, 940 + CED_VIDDATACHECKEN_QST | 941 + CED_DATAISCHECKEN_QST | 942 + CED_GBCHECKEN_QST | 943 + CED_CTRLCHECKEN_QST | 944 + CED_CHLOCKMAXER_QST_MASK, 945 + CED_VIDDATACHECKEN_QST | 946 + CED_GBCHECKEN_QST | 947 + CED_CTRLCHECKEN_QST | 948 + CED_CHLOCKMAXER_QST(0x10)); 949 + hdmirx_update_bits(hdmirx_dev, DEFRAMER_CONFIG0, 950 + VS_REMAPFILTER_EN_QST | VS_FILTER_ORDER_QST_MASK, 951 + VS_REMAPFILTER_EN_QST | VS_FILTER_ORDER_QST(0x3)); 952 + } 953 + 954 + static void hdmirx_get_colordepth(struct snps_hdmirx_dev *hdmirx_dev) 955 + { 956 + struct v4l2_device *v4l2_dev = &hdmirx_dev->v4l2_dev; 957 + u32 val, color_depth_reg; 958 + 959 + val = hdmirx_readl(hdmirx_dev, DMA_STATUS11); 960 + color_depth_reg = (val & HDMIRX_COLOR_DEPTH_MASK) >> 3; 961 + 962 + switch (color_depth_reg) { 963 + case 0x4: 964 + hdmirx_dev->color_depth = 24; 965 + break; 966 + case 0x5: 967 + hdmirx_dev->color_depth = 30; 968 + break; 969 + case 0x6: 970 + hdmirx_dev->color_depth = 36; 971 + break; 972 + case 0x7: 973 + hdmirx_dev->color_depth = 48; 974 + break; 975 + default: 976 + hdmirx_dev->color_depth = 24; 977 + break; 978 + } 979 + 980 + v4l2_dbg(1, debug, v4l2_dev, "%s: color_depth: %d, reg_val:%d\n", 981 + __func__, hdmirx_dev->color_depth, color_depth_reg); 982 + } 983 + 984 + static void hdmirx_get_pix_fmt(struct snps_hdmirx_dev *hdmirx_dev) 985 + { 986 + struct v4l2_device *v4l2_dev = &hdmirx_dev->v4l2_dev; 987 + u32 val; 988 + 989 + val = hdmirx_readl(hdmirx_dev, DMA_STATUS11); 990 + hdmirx_dev->pix_fmt = val & HDMIRX_FORMAT_MASK; 991 + 992 + switch (hdmirx_dev->pix_fmt) { 993 + case HDMIRX_RGB888: 994 + hdmirx_dev->cur_fmt_fourcc = V4L2_PIX_FMT_BGR24; 995 + break; 996 + case HDMIRX_YUV422: 997 + hdmirx_dev->cur_fmt_fourcc = V4L2_PIX_FMT_NV16; 998 + break; 999 + case HDMIRX_YUV444: 1000 + hdmirx_dev->cur_fmt_fourcc = V4L2_PIX_FMT_NV24; 1001 + break; 1002 + case HDMIRX_YUV420: 1003 + hdmirx_dev->cur_fmt_fourcc = V4L2_PIX_FMT_NV12; 1004 + break; 1005 + default: 1006 + v4l2_err(v4l2_dev, 1007 + "%s: err pix_fmt: %d, set RGB888 as default\n", 1008 + __func__, hdmirx_dev->pix_fmt); 1009 + hdmirx_dev->pix_fmt = HDMIRX_RGB888; 1010 + hdmirx_dev->cur_fmt_fourcc = V4L2_PIX_FMT_BGR24; 1011 + break; 1012 + } 1013 + 1014 + v4l2_dbg(1, debug, v4l2_dev, "%s: pix_fmt: %s\n", __func__, 1015 + pix_fmt_str[hdmirx_dev->pix_fmt]); 1016 + } 1017 + 1018 + static void hdmirx_read_avi_infoframe(struct snps_hdmirx_dev *hdmirx_dev, 1019 + u8 *aviif) 1020 + { 1021 + unsigned int i, b, itr = 0; 1022 + u32 val; 1023 + 1024 + aviif[itr++] = HDMI_INFOFRAME_TYPE_AVI; 1025 + val = hdmirx_readl(hdmirx_dev, PKTDEC_AVIIF_PH2_1); 1026 + aviif[itr++] = val & 0xff; 1027 + aviif[itr++] = (val >> 8) & 0xff; 1028 + 1029 + for (i = 0; i < 7; i++) { 1030 + val = hdmirx_readl(hdmirx_dev, PKTDEC_AVIIF_PB3_0 + 4 * i); 1031 + 1032 + for (b = 0; b < 4; b++) 1033 + aviif[itr++] = (val >> (8 * b)) & 0xff; 1034 + } 1035 + } 1036 + 1037 + static void hdmirx_get_avi_infoframe(struct snps_hdmirx_dev *hdmirx_dev) 1038 + { 1039 + struct v4l2_device *v4l2_dev = &hdmirx_dev->v4l2_dev; 1040 + union hdmi_infoframe frame = {}; 1041 + u8 aviif[3 + 7 * 4]; 1042 + int err; 1043 + 1044 + hdmirx_read_avi_infoframe(hdmirx_dev, aviif); 1045 + 1046 + err = hdmi_infoframe_unpack(&frame, aviif, sizeof(aviif)); 1047 + if (err) { 1048 + v4l2_err(v4l2_dev, "failed to unpack AVI infoframe\n"); 1049 + return; 1050 + } 1051 + 1052 + v4l2_ctrl_s_ctrl(hdmirx_dev->rgb_range, frame.avi.quantization_range); 1053 + 1054 + if (frame.avi.itc) 1055 + v4l2_ctrl_s_ctrl(hdmirx_dev->content_type, 1056 + frame.avi.content_type); 1057 + else 1058 + v4l2_ctrl_s_ctrl(hdmirx_dev->content_type, 1059 + V4L2_DV_IT_CONTENT_TYPE_NO_ITC); 1060 + } 1061 + 1062 + static ssize_t 1063 + hdmirx_debugfs_if_read(u32 type, void *priv, struct file *filp, 1064 + char __user *ubuf, size_t count, loff_t *ppos) 1065 + { 1066 + struct snps_hdmirx_dev *hdmirx_dev = priv; 1067 + u8 aviif[V4L2_DEBUGFS_IF_MAX_LEN] = {}; 1068 + int len; 1069 + 1070 + if (type != V4L2_DEBUGFS_IF_AVI) 1071 + return 0; 1072 + 1073 + hdmirx_read_avi_infoframe(hdmirx_dev, aviif); 1074 + 1075 + len = aviif[2] + 4; 1076 + if (len > V4L2_DEBUGFS_IF_MAX_LEN) 1077 + len = -ENOENT; 1078 + else 1079 + len = simple_read_from_buffer(ubuf, count, ppos, aviif, len); 1080 + 1081 + return len < 0 ? 0 : len; 1082 + } 1083 + 1084 + static void hdmirx_format_change(struct snps_hdmirx_dev *hdmirx_dev) 1085 + { 1086 + struct hdmirx_stream *stream = &hdmirx_dev->stream; 1087 + struct v4l2_device *v4l2_dev = &hdmirx_dev->v4l2_dev; 1088 + static const struct v4l2_event ev_src_chg = { 1089 + .type = V4L2_EVENT_SOURCE_CHANGE, 1090 + .u.src_change.changes = V4L2_EVENT_SRC_CH_RESOLUTION, 1091 + }; 1092 + 1093 + hdmirx_get_pix_fmt(hdmirx_dev); 1094 + hdmirx_get_colordepth(hdmirx_dev); 1095 + hdmirx_get_avi_infoframe(hdmirx_dev); 1096 + 1097 + v4l2_dbg(1, debug, v4l2_dev, "%s: queue res_chg_event\n", __func__); 1098 + v4l2_event_queue(&stream->vdev, &ev_src_chg); 1099 + } 1100 + 1101 + static void hdmirx_set_ddr_store_fmt(struct snps_hdmirx_dev *hdmirx_dev) 1102 + { 1103 + struct v4l2_device *v4l2_dev = &hdmirx_dev->v4l2_dev; 1104 + enum ddr_store_fmt store_fmt; 1105 + u32 dma_cfg1; 1106 + 1107 + switch (hdmirx_dev->pix_fmt) { 1108 + case HDMIRX_RGB888: 1109 + store_fmt = STORE_RGB888; 1110 + break; 1111 + case HDMIRX_YUV444: 1112 + store_fmt = STORE_YUV444_8BIT; 1113 + break; 1114 + case HDMIRX_YUV422: 1115 + store_fmt = STORE_YUV422_8BIT; 1116 + break; 1117 + case HDMIRX_YUV420: 1118 + store_fmt = STORE_YUV420_8BIT; 1119 + break; 1120 + default: 1121 + store_fmt = STORE_RGB888; 1122 + break; 1123 + } 1124 + 1125 + hdmirx_update_bits(hdmirx_dev, DMA_CONFIG1, 1126 + DDR_STORE_FORMAT_MASK, DDR_STORE_FORMAT(store_fmt)); 1127 + dma_cfg1 = hdmirx_readl(hdmirx_dev, DMA_CONFIG1); 1128 + v4l2_dbg(1, debug, v4l2_dev, "%s: pix_fmt: %s, DMA_CONFIG1:%#x\n", 1129 + __func__, pix_fmt_str[hdmirx_dev->pix_fmt], dma_cfg1); 1130 + } 1131 + 1132 + static void hdmirx_dma_config(struct snps_hdmirx_dev *hdmirx_dev) 1133 + { 1134 + hdmirx_set_ddr_store_fmt(hdmirx_dev); 1135 + 1136 + /* Note: uv_swap, rb can not swap, doc err */ 1137 + if (hdmirx_dev->cur_fmt_fourcc != V4L2_PIX_FMT_NV16) 1138 + hdmirx_update_bits(hdmirx_dev, DMA_CONFIG6, RB_SWAP_EN, RB_SWAP_EN); 1139 + else 1140 + hdmirx_update_bits(hdmirx_dev, DMA_CONFIG6, RB_SWAP_EN, 0); 1141 + 1142 + hdmirx_update_bits(hdmirx_dev, DMA_CONFIG7, 1143 + LOCK_FRAME_NUM_MASK, 1144 + LOCK_FRAME_NUM(2)); 1145 + hdmirx_update_bits(hdmirx_dev, DMA_CONFIG1, 1146 + UV_WID_MASK | Y_WID_MASK | ABANDON_EN, 1147 + UV_WID(1) | Y_WID(2) | ABANDON_EN); 1148 + } 1149 + 1150 + static void hdmirx_submodule_init(struct snps_hdmirx_dev *hdmirx_dev) 1151 + { 1152 + /* Note: if not config HDCP2_CONFIG, there will be some errors; */ 1153 + hdmirx_update_bits(hdmirx_dev, HDCP2_CONFIG, 1154 + HDCP2_SWITCH_OVR_VALUE | 1155 + HDCP2_SWITCH_OVR_EN, 1156 + HDCP2_SWITCH_OVR_EN); 1157 + hdmirx_scdc_init(hdmirx_dev); 1158 + hdmirx_controller_init(hdmirx_dev); 1159 + } 1160 + 1161 + static int hdmirx_enum_input(struct file *file, void *priv, 1162 + struct v4l2_input *input) 1163 + { 1164 + if (input->index > 0) 1165 + return -EINVAL; 1166 + 1167 + input->type = V4L2_INPUT_TYPE_CAMERA; 1168 + input->std = 0; 1169 + strscpy(input->name, "HDMI IN", sizeof(input->name)); 1170 + input->capabilities = V4L2_IN_CAP_DV_TIMINGS; 1171 + 1172 + return 0; 1173 + } 1174 + 1175 + static int hdmirx_get_input(struct file *file, void *priv, unsigned int *i) 1176 + { 1177 + *i = 0; 1178 + return 0; 1179 + } 1180 + 1181 + static int hdmirx_set_input(struct file *file, void *priv, unsigned int i) 1182 + { 1183 + if (i) 1184 + return -EINVAL; 1185 + return 0; 1186 + } 1187 + 1188 + static void hdmirx_set_fmt(struct hdmirx_stream *stream, 1189 + struct v4l2_pix_format_mplane *pixm, bool try) 1190 + { 1191 + struct snps_hdmirx_dev *hdmirx_dev = stream->hdmirx_dev; 1192 + struct v4l2_device *v4l2_dev = &hdmirx_dev->v4l2_dev; 1193 + struct v4l2_bt_timings *bt = &hdmirx_dev->timings.bt; 1194 + const struct v4l2_format_info *finfo; 1195 + unsigned int imagesize = 0; 1196 + unsigned int i; 1197 + 1198 + memset(&pixm->plane_fmt[0], 0, sizeof(struct v4l2_plane_pix_format)); 1199 + finfo = v4l2_format_info(pixm->pixelformat); 1200 + if (!finfo) { 1201 + finfo = v4l2_format_info(V4L2_PIX_FMT_BGR24); 1202 + v4l2_dbg(1, debug, v4l2_dev, 1203 + "%s: set_fmt:%#x not supported, use def_fmt:%x\n", 1204 + __func__, pixm->pixelformat, finfo->format); 1205 + } 1206 + 1207 + if (!bt->width || !bt->height) 1208 + v4l2_dbg(1, debug, v4l2_dev, "%s: invalid resolution:%#xx%#x\n", 1209 + __func__, bt->width, bt->height); 1210 + 1211 + pixm->pixelformat = finfo->format; 1212 + pixm->width = bt->width; 1213 + pixm->height = bt->height; 1214 + pixm->num_planes = finfo->mem_planes; 1215 + pixm->quantization = V4L2_QUANTIZATION_DEFAULT; 1216 + pixm->colorspace = V4L2_COLORSPACE_SRGB; 1217 + pixm->ycbcr_enc = V4L2_YCBCR_ENC_DEFAULT; 1218 + 1219 + if (bt->interlaced == V4L2_DV_INTERLACED) 1220 + pixm->field = V4L2_FIELD_INTERLACED_TB; 1221 + else 1222 + pixm->field = V4L2_FIELD_NONE; 1223 + 1224 + memset(pixm->reserved, 0, sizeof(pixm->reserved)); 1225 + 1226 + v4l2_fill_pixfmt_mp(pixm, finfo->format, pixm->width, pixm->height); 1227 + 1228 + for (i = 0; i < finfo->comp_planes; i++) { 1229 + struct v4l2_plane_pix_format *plane_fmt; 1230 + int width, height, bpl, size, bpp = 0; 1231 + const unsigned int hw_align = 64; 1232 + 1233 + if (!i) { 1234 + width = pixm->width; 1235 + height = pixm->height; 1236 + } else { 1237 + width = pixm->width / finfo->hdiv; 1238 + height = pixm->height / finfo->vdiv; 1239 + } 1240 + 1241 + switch (finfo->format) { 1242 + case V4L2_PIX_FMT_NV24: 1243 + case V4L2_PIX_FMT_NV16: 1244 + case V4L2_PIX_FMT_NV12: 1245 + case V4L2_PIX_FMT_BGR24: 1246 + bpp = finfo->bpp[i]; 1247 + break; 1248 + default: 1249 + v4l2_dbg(1, debug, v4l2_dev, 1250 + "fourcc: %#x is not supported\n", 1251 + finfo->format); 1252 + break; 1253 + } 1254 + 1255 + bpl = ALIGN(width * bpp, hw_align); 1256 + size = bpl * height; 1257 + imagesize += size; 1258 + 1259 + if (finfo->mem_planes > i) { 1260 + /* Set bpl and size for each mplane */ 1261 + plane_fmt = pixm->plane_fmt + i; 1262 + plane_fmt->bytesperline = bpl; 1263 + plane_fmt->sizeimage = size; 1264 + } 1265 + 1266 + v4l2_dbg(1, debug, v4l2_dev, 1267 + "C-Plane %u size: %d, Total imagesize: %d\n", 1268 + i, size, imagesize); 1269 + } 1270 + 1271 + /* Convert to non-MPLANE format as we want to unify non-MPLANE and MPLANE */ 1272 + if (finfo->mem_planes == 1) 1273 + pixm->plane_fmt[0].sizeimage = imagesize; 1274 + 1275 + if (!try) { 1276 + stream->out_finfo = finfo; 1277 + stream->pixm = *pixm; 1278 + v4l2_dbg(1, debug, v4l2_dev, 1279 + "%s: req(%d, %d), out(%d, %d), fmt:%#x\n", __func__, 1280 + pixm->width, pixm->height, stream->pixm.width, 1281 + stream->pixm.height, finfo->format); 1282 + } 1283 + } 1284 + 1285 + static int hdmirx_enum_fmt_vid_cap_mplane(struct file *file, void *priv, 1286 + struct v4l2_fmtdesc *f) 1287 + { 1288 + struct hdmirx_stream *stream = video_drvdata(file); 1289 + struct snps_hdmirx_dev *hdmirx_dev = stream->hdmirx_dev; 1290 + 1291 + if (f->index >= 1) 1292 + return -EINVAL; 1293 + 1294 + f->pixelformat = hdmirx_dev->cur_fmt_fourcc; 1295 + 1296 + return 0; 1297 + } 1298 + 1299 + static int hdmirx_s_fmt_vid_cap_mplane(struct file *file, 1300 + void *priv, struct v4l2_format *f) 1301 + { 1302 + struct hdmirx_stream *stream = video_drvdata(file); 1303 + struct snps_hdmirx_dev *hdmirx_dev = stream->hdmirx_dev; 1304 + struct v4l2_device *v4l2_dev = &hdmirx_dev->v4l2_dev; 1305 + 1306 + if (vb2_is_busy(&stream->buf_queue)) { 1307 + v4l2_err(v4l2_dev, "%s: queue busy\n", __func__); 1308 + return -EBUSY; 1309 + } 1310 + 1311 + hdmirx_set_fmt(stream, &f->fmt.pix_mp, false); 1312 + 1313 + return 0; 1314 + } 1315 + 1316 + static int hdmirx_g_fmt_vid_cap_mplane(struct file *file, void *fh, 1317 + struct v4l2_format *f) 1318 + { 1319 + struct hdmirx_stream *stream = video_drvdata(file); 1320 + struct snps_hdmirx_dev *hdmirx_dev = stream->hdmirx_dev; 1321 + struct v4l2_pix_format_mplane pixm = {}; 1322 + 1323 + pixm.pixelformat = hdmirx_dev->cur_fmt_fourcc; 1324 + hdmirx_set_fmt(stream, &pixm, true); 1325 + f->fmt.pix_mp = pixm; 1326 + 1327 + return 0; 1328 + } 1329 + 1330 + static int hdmirx_g_dv_timings(struct file *file, void *_fh, 1331 + struct v4l2_dv_timings *timings) 1332 + { 1333 + struct hdmirx_stream *stream = video_drvdata(file); 1334 + struct snps_hdmirx_dev *hdmirx_dev = stream->hdmirx_dev; 1335 + struct v4l2_device *v4l2_dev = &hdmirx_dev->v4l2_dev; 1336 + u32 dma_cfg1; 1337 + 1338 + *timings = hdmirx_dev->timings; 1339 + dma_cfg1 = hdmirx_readl(hdmirx_dev, DMA_CONFIG1); 1340 + v4l2_dbg(1, debug, v4l2_dev, "%s: pix_fmt: %s, DMA_CONFIG1:%#x\n", 1341 + __func__, pix_fmt_str[hdmirx_dev->pix_fmt], dma_cfg1); 1342 + 1343 + return 0; 1344 + } 1345 + 1346 + static int hdmirx_s_dv_timings(struct file *file, void *_fh, 1347 + struct v4l2_dv_timings *timings) 1348 + { 1349 + struct hdmirx_stream *stream = video_drvdata(file); 1350 + struct snps_hdmirx_dev *hdmirx_dev = stream->hdmirx_dev; 1351 + struct v4l2_device *v4l2_dev = &hdmirx_dev->v4l2_dev; 1352 + 1353 + if (!timings) 1354 + return -EINVAL; 1355 + 1356 + if (debug) 1357 + v4l2_print_dv_timings(hdmirx_dev->v4l2_dev.name, 1358 + "s_dv_timings: ", timings, false); 1359 + 1360 + if (!v4l2_valid_dv_timings(timings, &hdmirx_timings_cap, NULL, NULL)) { 1361 + v4l2_dbg(1, debug, v4l2_dev, 1362 + "%s: timings out of range\n", __func__); 1363 + return -ERANGE; 1364 + } 1365 + 1366 + /* Check if the timings are part of the CEA-861 timings. */ 1367 + v4l2_find_dv_timings_cap(timings, &hdmirx_timings_cap, 0, NULL, NULL); 1368 + 1369 + if (v4l2_match_dv_timings(&hdmirx_dev->timings, timings, 0, false)) { 1370 + v4l2_dbg(1, debug, v4l2_dev, "%s: no change\n", __func__); 1371 + return 0; 1372 + } 1373 + 1374 + /* 1375 + * Changing the timings implies a format change, which is not allowed 1376 + * while buffers for use with streaming have already been allocated. 1377 + */ 1378 + if (vb2_is_busy(&stream->buf_queue)) 1379 + return -EBUSY; 1380 + 1381 + hdmirx_dev->timings = *timings; 1382 + /* Update the internal format */ 1383 + hdmirx_set_fmt(stream, &stream->pixm, false); 1384 + 1385 + return 0; 1386 + } 1387 + 1388 + static int hdmirx_querycap(struct file *file, void *priv, 1389 + struct v4l2_capability *cap) 1390 + { 1391 + struct hdmirx_stream *stream = video_drvdata(file); 1392 + struct device *dev = stream->hdmirx_dev->dev; 1393 + 1394 + strscpy(cap->driver, dev->driver->name, sizeof(cap->driver)); 1395 + strscpy(cap->card, dev->driver->name, sizeof(cap->card)); 1396 + 1397 + return 0; 1398 + } 1399 + 1400 + static int hdmirx_queue_setup(struct vb2_queue *queue, 1401 + unsigned int *num_buffers, 1402 + unsigned int *num_planes, 1403 + unsigned int sizes[], 1404 + struct device *alloc_ctxs[]) 1405 + { 1406 + struct hdmirx_stream *stream = vb2_get_drv_priv(queue); 1407 + struct snps_hdmirx_dev *hdmirx_dev = stream->hdmirx_dev; 1408 + struct v4l2_device *v4l2_dev = &hdmirx_dev->v4l2_dev; 1409 + const struct v4l2_pix_format_mplane *pixm = NULL; 1410 + const struct v4l2_format_info *out_finfo; 1411 + u32 i; 1412 + 1413 + pixm = &stream->pixm; 1414 + out_finfo = stream->out_finfo; 1415 + 1416 + if (!out_finfo) { 1417 + v4l2_err(v4l2_dev, "%s: out_fmt not set\n", __func__); 1418 + return -EINVAL; 1419 + } 1420 + 1421 + if (*num_planes) { 1422 + if (*num_planes != pixm->num_planes) 1423 + return -EINVAL; 1424 + 1425 + for (i = 0; i < *num_planes; i++) 1426 + if (sizes[i] < pixm->plane_fmt[i].sizeimage) 1427 + return -EINVAL; 1428 + return 0; 1429 + } 1430 + 1431 + *num_planes = out_finfo->mem_planes; 1432 + 1433 + for (i = 0; i < out_finfo->mem_planes; i++) 1434 + sizes[i] = pixm->plane_fmt[i].sizeimage; 1435 + 1436 + v4l2_dbg(1, debug, v4l2_dev, "%s: count %d, size %d\n", 1437 + v4l2_type_names[queue->type], *num_buffers, sizes[0]); 1438 + 1439 + return 0; 1440 + } 1441 + 1442 + /* 1443 + * The vb2_buffer are stored in hdmirx_buffer, in order to unify 1444 + * mplane buffer and none-mplane buffer. 1445 + */ 1446 + static void hdmirx_buf_queue(struct vb2_buffer *vb) 1447 + { 1448 + const struct v4l2_pix_format_mplane *pixm; 1449 + const struct v4l2_format_info *out_finfo; 1450 + struct hdmirx_buffer *hdmirx_buf; 1451 + struct vb2_v4l2_buffer *vbuf; 1452 + struct hdmirx_stream *stream; 1453 + struct vb2_queue *queue; 1454 + unsigned long flags; 1455 + unsigned int i; 1456 + 1457 + vbuf = to_vb2_v4l2_buffer(vb); 1458 + hdmirx_buf = container_of(vbuf, struct hdmirx_buffer, vb); 1459 + queue = vb->vb2_queue; 1460 + stream = vb2_get_drv_priv(queue); 1461 + pixm = &stream->pixm; 1462 + out_finfo = stream->out_finfo; 1463 + 1464 + memset(hdmirx_buf->buff_addr, 0, sizeof(hdmirx_buf->buff_addr)); 1465 + 1466 + /* 1467 + * If mplanes > 1, every c-plane has its own m-plane, 1468 + * otherwise, multiple c-planes are in the same m-plane 1469 + */ 1470 + for (i = 0; i < out_finfo->mem_planes; i++) 1471 + hdmirx_buf->buff_addr[i] = vb2_dma_contig_plane_dma_addr(vb, i); 1472 + 1473 + if (out_finfo->mem_planes == 1) { 1474 + if (out_finfo->comp_planes == 1) { 1475 + hdmirx_buf->buff_addr[HDMIRX_PLANE_CBCR] = 1476 + hdmirx_buf->buff_addr[HDMIRX_PLANE_Y]; 1477 + } else { 1478 + for (i = 0; i < out_finfo->comp_planes - 1; i++) 1479 + hdmirx_buf->buff_addr[i + 1] = 1480 + hdmirx_buf->buff_addr[i] + 1481 + pixm->plane_fmt[i].bytesperline * 1482 + pixm->height; 1483 + } 1484 + } 1485 + 1486 + spin_lock_irqsave(&stream->vbq_lock, flags); 1487 + list_add_tail(&hdmirx_buf->queue, &stream->buf_head); 1488 + spin_unlock_irqrestore(&stream->vbq_lock, flags); 1489 + } 1490 + 1491 + static void return_all_buffers(struct hdmirx_stream *stream, 1492 + enum vb2_buffer_state state) 1493 + { 1494 + struct hdmirx_buffer *buf, *tmp; 1495 + unsigned long flags; 1496 + 1497 + spin_lock_irqsave(&stream->vbq_lock, flags); 1498 + if (stream->curr_buf) 1499 + list_add_tail(&stream->curr_buf->queue, &stream->buf_head); 1500 + if (stream->next_buf && stream->next_buf != stream->curr_buf) 1501 + list_add_tail(&stream->next_buf->queue, &stream->buf_head); 1502 + stream->curr_buf = NULL; 1503 + stream->next_buf = NULL; 1504 + 1505 + list_for_each_entry_safe(buf, tmp, &stream->buf_head, queue) { 1506 + list_del(&buf->queue); 1507 + vb2_buffer_done(&buf->vb.vb2_buf, state); 1508 + } 1509 + spin_unlock_irqrestore(&stream->vbq_lock, flags); 1510 + } 1511 + 1512 + static void hdmirx_stop_streaming(struct vb2_queue *queue) 1513 + { 1514 + struct hdmirx_stream *stream = vb2_get_drv_priv(queue); 1515 + struct snps_hdmirx_dev *hdmirx_dev = stream->hdmirx_dev; 1516 + struct v4l2_device *v4l2_dev = &hdmirx_dev->v4l2_dev; 1517 + int ret; 1518 + 1519 + v4l2_dbg(1, debug, v4l2_dev, "stream start stopping\n"); 1520 + mutex_lock(&hdmirx_dev->stream_lock); 1521 + WRITE_ONCE(stream->stopping, true); 1522 + 1523 + /* wait last irq to return the buffer */ 1524 + ret = wait_event_timeout(stream->wq_stopped, !stream->stopping, 1525 + msecs_to_jiffies(500)); 1526 + if (!ret) 1527 + v4l2_dbg(1, debug, v4l2_dev, "%s: timeout waiting last irq\n", 1528 + __func__); 1529 + 1530 + hdmirx_update_bits(hdmirx_dev, DMA_CONFIG6, HDMIRX_DMA_EN, 0); 1531 + return_all_buffers(stream, VB2_BUF_STATE_ERROR); 1532 + mutex_unlock(&hdmirx_dev->stream_lock); 1533 + v4l2_dbg(1, debug, v4l2_dev, "stream stopping finished\n"); 1534 + } 1535 + 1536 + static int hdmirx_start_streaming(struct vb2_queue *queue, unsigned int count) 1537 + { 1538 + struct hdmirx_stream *stream = vb2_get_drv_priv(queue); 1539 + struct snps_hdmirx_dev *hdmirx_dev = stream->hdmirx_dev; 1540 + struct v4l2_device *v4l2_dev = &hdmirx_dev->v4l2_dev; 1541 + struct v4l2_dv_timings timings = hdmirx_dev->timings; 1542 + struct v4l2_bt_timings *bt = &timings.bt; 1543 + unsigned long lock_flags = 0; 1544 + int line_flag; 1545 + 1546 + mutex_lock(&hdmirx_dev->stream_lock); 1547 + stream->frame_idx = 0; 1548 + stream->line_flag_int_cnt = 0; 1549 + stream->curr_buf = NULL; 1550 + stream->next_buf = NULL; 1551 + stream->irq_stat = 0; 1552 + 1553 + WRITE_ONCE(stream->stopping, false); 1554 + 1555 + spin_lock_irqsave(&stream->vbq_lock, lock_flags); 1556 + if (!stream->curr_buf) { 1557 + if (!list_empty(&stream->buf_head)) { 1558 + stream->curr_buf = list_first_entry(&stream->buf_head, 1559 + struct hdmirx_buffer, 1560 + queue); 1561 + list_del(&stream->curr_buf->queue); 1562 + } else { 1563 + stream->curr_buf = NULL; 1564 + } 1565 + } 1566 + spin_unlock_irqrestore(&stream->vbq_lock, lock_flags); 1567 + 1568 + if (!stream->curr_buf) { 1569 + mutex_unlock(&hdmirx_dev->stream_lock); 1570 + return -ENOMEM; 1571 + } 1572 + 1573 + v4l2_dbg(2, debug, v4l2_dev, 1574 + "%s: start_stream cur_buf y_addr:%#x, uv_addr:%#x\n", 1575 + __func__, stream->curr_buf->buff_addr[HDMIRX_PLANE_Y], 1576 + stream->curr_buf->buff_addr[HDMIRX_PLANE_CBCR]); 1577 + hdmirx_writel(hdmirx_dev, DMA_CONFIG2, 1578 + stream->curr_buf->buff_addr[HDMIRX_PLANE_Y]); 1579 + hdmirx_writel(hdmirx_dev, DMA_CONFIG3, 1580 + stream->curr_buf->buff_addr[HDMIRX_PLANE_CBCR]); 1581 + 1582 + if (bt->height) { 1583 + if (bt->interlaced == V4L2_DV_INTERLACED) 1584 + line_flag = bt->height / 4; 1585 + else 1586 + line_flag = bt->height / 2; 1587 + hdmirx_update_bits(hdmirx_dev, DMA_CONFIG7, 1588 + LINE_FLAG_NUM_MASK, 1589 + LINE_FLAG_NUM(line_flag)); 1590 + } else { 1591 + v4l2_err(v4l2_dev, "invalid BT timing height=%d\n", bt->height); 1592 + } 1593 + 1594 + hdmirx_writel(hdmirx_dev, DMA_CONFIG5, 0xffffffff); 1595 + hdmirx_writel(hdmirx_dev, CED_DYN_CONTROL, 0x1); 1596 + hdmirx_update_bits(hdmirx_dev, DMA_CONFIG4, 1597 + LINE_FLAG_INT_EN | 1598 + HDMIRX_DMA_IDLE_INT | 1599 + HDMIRX_LOCK_DISABLE_INT | 1600 + LAST_FRAME_AXI_UNFINISH_INT_EN | 1601 + FIFO_OVERFLOW_INT_EN | 1602 + FIFO_UNDERFLOW_INT_EN | 1603 + HDMIRX_AXI_ERROR_INT_EN, 1604 + LINE_FLAG_INT_EN | 1605 + HDMIRX_DMA_IDLE_INT | 1606 + HDMIRX_LOCK_DISABLE_INT | 1607 + LAST_FRAME_AXI_UNFINISH_INT_EN | 1608 + FIFO_OVERFLOW_INT_EN | 1609 + FIFO_UNDERFLOW_INT_EN | 1610 + HDMIRX_AXI_ERROR_INT_EN); 1611 + hdmirx_update_bits(hdmirx_dev, DMA_CONFIG6, HDMIRX_DMA_EN, HDMIRX_DMA_EN); 1612 + v4l2_dbg(1, debug, v4l2_dev, "%s: enable dma", __func__); 1613 + mutex_unlock(&hdmirx_dev->stream_lock); 1614 + 1615 + return 0; 1616 + } 1617 + 1618 + /* vb2 queue */ 1619 + static const struct vb2_ops hdmirx_vb2_ops = { 1620 + .queue_setup = hdmirx_queue_setup, 1621 + .buf_queue = hdmirx_buf_queue, 1622 + .stop_streaming = hdmirx_stop_streaming, 1623 + .start_streaming = hdmirx_start_streaming, 1624 + }; 1625 + 1626 + static int hdmirx_init_vb2_queue(struct vb2_queue *q, 1627 + struct hdmirx_stream *stream, 1628 + enum v4l2_buf_type buf_type) 1629 + { 1630 + struct snps_hdmirx_dev *hdmirx_dev = stream->hdmirx_dev; 1631 + 1632 + q->type = buf_type; 1633 + q->io_modes = VB2_MMAP | VB2_DMABUF; 1634 + q->drv_priv = stream; 1635 + q->ops = &hdmirx_vb2_ops; 1636 + q->mem_ops = &vb2_dma_contig_memops; 1637 + q->buf_struct_size = sizeof(struct hdmirx_buffer); 1638 + q->timestamp_flags = V4L2_BUF_FLAG_TIMESTAMP_MONOTONIC; 1639 + q->lock = &stream->vlock; 1640 + q->dev = hdmirx_dev->dev; 1641 + q->min_queued_buffers = 1; 1642 + 1643 + return vb2_queue_init(q); 1644 + } 1645 + 1646 + /* video device */ 1647 + static const struct v4l2_ioctl_ops hdmirx_v4l2_ioctl_ops = { 1648 + .vidioc_querycap = hdmirx_querycap, 1649 + .vidioc_try_fmt_vid_cap_mplane = hdmirx_g_fmt_vid_cap_mplane, 1650 + .vidioc_s_fmt_vid_cap_mplane = hdmirx_s_fmt_vid_cap_mplane, 1651 + .vidioc_g_fmt_vid_cap_mplane = hdmirx_g_fmt_vid_cap_mplane, 1652 + .vidioc_enum_fmt_vid_cap = hdmirx_enum_fmt_vid_cap_mplane, 1653 + 1654 + .vidioc_s_dv_timings = hdmirx_s_dv_timings, 1655 + .vidioc_g_dv_timings = hdmirx_g_dv_timings, 1656 + .vidioc_enum_dv_timings = hdmirx_enum_dv_timings, 1657 + .vidioc_query_dv_timings = hdmirx_query_dv_timings, 1658 + .vidioc_dv_timings_cap = hdmirx_dv_timings_cap, 1659 + .vidioc_enum_input = hdmirx_enum_input, 1660 + .vidioc_g_input = hdmirx_get_input, 1661 + .vidioc_s_input = hdmirx_set_input, 1662 + .vidioc_g_edid = hdmirx_get_edid, 1663 + .vidioc_s_edid = hdmirx_set_edid, 1664 + .vidioc_g_parm = hdmirx_g_parm, 1665 + 1666 + .vidioc_reqbufs = vb2_ioctl_reqbufs, 1667 + .vidioc_querybuf = vb2_ioctl_querybuf, 1668 + .vidioc_create_bufs = vb2_ioctl_create_bufs, 1669 + .vidioc_qbuf = vb2_ioctl_qbuf, 1670 + .vidioc_expbuf = vb2_ioctl_expbuf, 1671 + .vidioc_dqbuf = vb2_ioctl_dqbuf, 1672 + .vidioc_prepare_buf = vb2_ioctl_prepare_buf, 1673 + .vidioc_streamon = vb2_ioctl_streamon, 1674 + .vidioc_streamoff = vb2_ioctl_streamoff, 1675 + 1676 + .vidioc_log_status = v4l2_ctrl_log_status, 1677 + .vidioc_subscribe_event = hdmirx_subscribe_event, 1678 + .vidioc_unsubscribe_event = v4l2_event_unsubscribe, 1679 + }; 1680 + 1681 + static const struct v4l2_file_operations hdmirx_fops = { 1682 + .owner = THIS_MODULE, 1683 + .open = v4l2_fh_open, 1684 + .release = vb2_fop_release, 1685 + .unlocked_ioctl = video_ioctl2, 1686 + .poll = vb2_fop_poll, 1687 + .mmap = vb2_fop_mmap, 1688 + }; 1689 + 1690 + static int hdmirx_register_stream_vdev(struct hdmirx_stream *stream) 1691 + { 1692 + struct snps_hdmirx_dev *hdmirx_dev = stream->hdmirx_dev; 1693 + struct v4l2_device *v4l2_dev = &hdmirx_dev->v4l2_dev; 1694 + struct video_device *vdev = &stream->vdev; 1695 + int ret; 1696 + 1697 + strscpy(vdev->name, "stream_hdmirx", sizeof(vdev->name)); 1698 + INIT_LIST_HEAD(&stream->buf_head); 1699 + spin_lock_init(&stream->vbq_lock); 1700 + mutex_init(&stream->vlock); 1701 + init_waitqueue_head(&stream->wq_stopped); 1702 + stream->curr_buf = NULL; 1703 + stream->next_buf = NULL; 1704 + 1705 + vdev->ioctl_ops = &hdmirx_v4l2_ioctl_ops; 1706 + vdev->release = video_device_release_empty; 1707 + vdev->fops = &hdmirx_fops; 1708 + vdev->minor = -1; 1709 + vdev->v4l2_dev = v4l2_dev; 1710 + vdev->lock = &stream->vlock; 1711 + vdev->device_caps = V4L2_CAP_VIDEO_CAPTURE_MPLANE | 1712 + V4L2_CAP_STREAMING; 1713 + vdev->vfl_dir = VFL_DIR_RX; 1714 + 1715 + video_set_drvdata(vdev, stream); 1716 + 1717 + hdmirx_init_vb2_queue(&stream->buf_queue, stream, 1718 + V4L2_BUF_TYPE_VIDEO_CAPTURE_MPLANE); 1719 + vdev->queue = &stream->buf_queue; 1720 + 1721 + ret = video_register_device(vdev, VFL_TYPE_VIDEO, -1); 1722 + if (ret < 0) { 1723 + v4l2_err(v4l2_dev, "video_register_device failed: %d\n", ret); 1724 + return ret; 1725 + } 1726 + 1727 + return 0; 1728 + } 1729 + 1730 + static void process_signal_change(struct snps_hdmirx_dev *hdmirx_dev) 1731 + { 1732 + hdmirx_update_bits(hdmirx_dev, DMA_CONFIG6, HDMIRX_DMA_EN, 0); 1733 + hdmirx_update_bits(hdmirx_dev, DMA_CONFIG4, 1734 + LINE_FLAG_INT_EN | 1735 + HDMIRX_DMA_IDLE_INT | 1736 + HDMIRX_LOCK_DISABLE_INT | 1737 + LAST_FRAME_AXI_UNFINISH_INT_EN | 1738 + FIFO_OVERFLOW_INT_EN | 1739 + FIFO_UNDERFLOW_INT_EN | 1740 + HDMIRX_AXI_ERROR_INT_EN, 0); 1741 + hdmirx_reset_dma(hdmirx_dev); 1742 + queue_delayed_work(system_unbound_wq, 1743 + &hdmirx_dev->delayed_work_res_change, 1744 + msecs_to_jiffies(50)); 1745 + } 1746 + 1747 + static void avpunit_0_int_handler(struct snps_hdmirx_dev *hdmirx_dev, 1748 + int status, bool *handled) 1749 + { 1750 + struct v4l2_device *v4l2_dev = &hdmirx_dev->v4l2_dev; 1751 + 1752 + if (status & (CED_DYN_CNT_CH2_IRQ | 1753 + CED_DYN_CNT_CH1_IRQ | 1754 + CED_DYN_CNT_CH0_IRQ)) { 1755 + process_signal_change(hdmirx_dev); 1756 + v4l2_dbg(2, debug, v4l2_dev, "%s: avp0_st:%#x\n", 1757 + __func__, status); 1758 + *handled = true; 1759 + } 1760 + 1761 + hdmirx_clear_interrupt(hdmirx_dev, AVPUNIT_0_INT_CLEAR, 0xffffffff); 1762 + hdmirx_writel(hdmirx_dev, AVPUNIT_0_INT_FORCE, 0x0); 1763 + } 1764 + 1765 + static void avpunit_1_int_handler(struct snps_hdmirx_dev *hdmirx_dev, 1766 + int status, bool *handled) 1767 + { 1768 + struct v4l2_device *v4l2_dev = &hdmirx_dev->v4l2_dev; 1769 + 1770 + if (status & DEFRAMER_VSYNC_THR_REACHED_IRQ) { 1771 + v4l2_dbg(2, debug, v4l2_dev, 1772 + "Vertical Sync threshold reached interrupt %#x", status); 1773 + hdmirx_update_bits(hdmirx_dev, AVPUNIT_1_INT_MASK_N, 1774 + DEFRAMER_VSYNC_THR_REACHED_MASK_N, 0); 1775 + *handled = true; 1776 + } 1777 + } 1778 + 1779 + static void mainunit_0_int_handler(struct snps_hdmirx_dev *hdmirx_dev, 1780 + int status, bool *handled) 1781 + { 1782 + struct v4l2_device *v4l2_dev = &hdmirx_dev->v4l2_dev; 1783 + 1784 + v4l2_dbg(2, debug, v4l2_dev, "mu0_st:%#x\n", status); 1785 + if (status & TIMER_BASE_LOCKED_IRQ) { 1786 + hdmirx_update_bits(hdmirx_dev, MAINUNIT_0_INT_MASK_N, 1787 + TIMER_BASE_LOCKED_IRQ, 0); 1788 + complete(&hdmirx_dev->timer_base_lock); 1789 + *handled = true; 1790 + } 1791 + 1792 + if (status & TMDSQPCLK_OFF_CHG) { 1793 + process_signal_change(hdmirx_dev); 1794 + v4l2_dbg(2, debug, v4l2_dev, "%s: TMDSQPCLK_OFF_CHG\n", __func__); 1795 + *handled = true; 1796 + } 1797 + 1798 + if (status & TMDSQPCLK_LOCKED_CHG) { 1799 + process_signal_change(hdmirx_dev); 1800 + v4l2_dbg(2, debug, v4l2_dev, "%s: TMDSQPCLK_LOCKED_CHG\n", __func__); 1801 + *handled = true; 1802 + } 1803 + 1804 + hdmirx_clear_interrupt(hdmirx_dev, MAINUNIT_0_INT_CLEAR, 0xffffffff); 1805 + hdmirx_writel(hdmirx_dev, MAINUNIT_0_INT_FORCE, 0x0); 1806 + } 1807 + 1808 + static void mainunit_2_int_handler(struct snps_hdmirx_dev *hdmirx_dev, 1809 + int status, bool *handled) 1810 + { 1811 + struct v4l2_device *v4l2_dev = &hdmirx_dev->v4l2_dev; 1812 + 1813 + v4l2_dbg(2, debug, v4l2_dev, "mu2_st:%#x\n", status); 1814 + if (status & PHYCREG_CR_WRITE_DONE) { 1815 + hdmirx_update_bits(hdmirx_dev, MAINUNIT_2_INT_MASK_N, 1816 + PHYCREG_CR_WRITE_DONE, 0); 1817 + complete(&hdmirx_dev->cr_write_done); 1818 + *handled = true; 1819 + } 1820 + 1821 + if (status & TMDSVALID_STABLE_CHG) { 1822 + process_signal_change(hdmirx_dev); 1823 + v4l2_dbg(2, debug, v4l2_dev, "%s: TMDSVALID_STABLE_CHG\n", __func__); 1824 + *handled = true; 1825 + } 1826 + 1827 + hdmirx_clear_interrupt(hdmirx_dev, MAINUNIT_2_INT_CLEAR, 0xffffffff); 1828 + hdmirx_writel(hdmirx_dev, MAINUNIT_2_INT_FORCE, 0x0); 1829 + } 1830 + 1831 + static void pkt_2_int_handler(struct snps_hdmirx_dev *hdmirx_dev, 1832 + int status, bool *handled) 1833 + { 1834 + struct v4l2_device *v4l2_dev = &hdmirx_dev->v4l2_dev; 1835 + 1836 + v4l2_dbg(2, debug, v4l2_dev, "%s: pk2_st:%#x\n", __func__, status); 1837 + if (status & PKTDEC_AVIIF_RCV_IRQ) { 1838 + hdmirx_update_bits(hdmirx_dev, PKT_2_INT_MASK_N, 1839 + PKTDEC_AVIIF_RCV_IRQ, 0); 1840 + complete(&hdmirx_dev->avi_pkt_rcv); 1841 + v4l2_dbg(2, debug, v4l2_dev, "%s: AVIIF_RCV_IRQ\n", __func__); 1842 + *handled = true; 1843 + } 1844 + 1845 + hdmirx_clear_interrupt(hdmirx_dev, PKT_2_INT_CLEAR, 0xffffffff); 1846 + } 1847 + 1848 + static void scdc_int_handler(struct snps_hdmirx_dev *hdmirx_dev, 1849 + int status, bool *handled) 1850 + { 1851 + struct v4l2_device *v4l2_dev = &hdmirx_dev->v4l2_dev; 1852 + 1853 + v4l2_dbg(2, debug, v4l2_dev, "%s: scdc_st:%#x\n", __func__, status); 1854 + if (status & SCDCTMDSCCFG_CHG) { 1855 + hdmirx_tmds_clk_ratio_config(hdmirx_dev); 1856 + *handled = true; 1857 + } 1858 + 1859 + hdmirx_clear_interrupt(hdmirx_dev, SCDC_INT_CLEAR, 0xffffffff); 1860 + } 1861 + 1862 + static irqreturn_t hdmirx_hdmi_irq_handler(int irq, void *dev_id) 1863 + { 1864 + struct snps_hdmirx_dev *hdmirx_dev = dev_id; 1865 + struct v4l2_device *v4l2_dev = &hdmirx_dev->v4l2_dev; 1866 + u32 mu0_st, mu2_st, pk2_st, scdc_st, avp1_st, avp0_st; 1867 + u32 mu0_mask, mu2_mask, pk2_mask, scdc_mask, avp1_msk, avp0_msk; 1868 + bool handled = false; 1869 + 1870 + mu0_mask = hdmirx_readl(hdmirx_dev, MAINUNIT_0_INT_MASK_N); 1871 + mu2_mask = hdmirx_readl(hdmirx_dev, MAINUNIT_2_INT_MASK_N); 1872 + pk2_mask = hdmirx_readl(hdmirx_dev, PKT_2_INT_MASK_N); 1873 + scdc_mask = hdmirx_readl(hdmirx_dev, SCDC_INT_MASK_N); 1874 + mu0_st = hdmirx_readl(hdmirx_dev, MAINUNIT_0_INT_STATUS); 1875 + mu2_st = hdmirx_readl(hdmirx_dev, MAINUNIT_2_INT_STATUS); 1876 + pk2_st = hdmirx_readl(hdmirx_dev, PKT_2_INT_STATUS); 1877 + scdc_st = hdmirx_readl(hdmirx_dev, SCDC_INT_STATUS); 1878 + avp0_st = hdmirx_readl(hdmirx_dev, AVPUNIT_0_INT_STATUS); 1879 + avp1_st = hdmirx_readl(hdmirx_dev, AVPUNIT_1_INT_STATUS); 1880 + avp0_msk = hdmirx_readl(hdmirx_dev, AVPUNIT_0_INT_MASK_N); 1881 + avp1_msk = hdmirx_readl(hdmirx_dev, AVPUNIT_1_INT_MASK_N); 1882 + mu0_st &= mu0_mask; 1883 + mu2_st &= mu2_mask; 1884 + pk2_st &= pk2_mask; 1885 + avp1_st &= avp1_msk; 1886 + avp0_st &= avp0_msk; 1887 + scdc_st &= scdc_mask; 1888 + 1889 + if (avp0_st) 1890 + avpunit_0_int_handler(hdmirx_dev, avp0_st, &handled); 1891 + if (avp1_st) 1892 + avpunit_1_int_handler(hdmirx_dev, avp1_st, &handled); 1893 + if (mu0_st) 1894 + mainunit_0_int_handler(hdmirx_dev, mu0_st, &handled); 1895 + if (mu2_st) 1896 + mainunit_2_int_handler(hdmirx_dev, mu2_st, &handled); 1897 + if (pk2_st) 1898 + pkt_2_int_handler(hdmirx_dev, pk2_st, &handled); 1899 + if (scdc_st) 1900 + scdc_int_handler(hdmirx_dev, scdc_st, &handled); 1901 + 1902 + if (!handled) { 1903 + v4l2_dbg(2, debug, v4l2_dev, "%s: hdmi irq not handled", __func__); 1904 + v4l2_dbg(2, debug, v4l2_dev, 1905 + "avp0:%#x, avp1:%#x, mu0:%#x, mu2:%#x, pk2:%#x, scdc:%#x\n", 1906 + avp0_st, avp1_st, mu0_st, mu2_st, pk2_st, scdc_st); 1907 + } 1908 + 1909 + v4l2_dbg(2, debug, v4l2_dev, "%s: en_fiq", __func__); 1910 + 1911 + return handled ? IRQ_HANDLED : IRQ_NONE; 1912 + } 1913 + 1914 + static void hdmirx_vb_done(struct hdmirx_stream *stream, 1915 + struct vb2_v4l2_buffer *vb_done) 1916 + { 1917 + const struct v4l2_format_info *finfo = stream->out_finfo; 1918 + u32 i; 1919 + 1920 + /* Dequeue a filled buffer */ 1921 + for (i = 0; i < finfo->mem_planes; i++) { 1922 + vb2_set_plane_payload(&vb_done->vb2_buf, i, 1923 + stream->pixm.plane_fmt[i].sizeimage); 1924 + } 1925 + 1926 + vb_done->vb2_buf.timestamp = ktime_get_ns(); 1927 + vb2_buffer_done(&vb_done->vb2_buf, VB2_BUF_STATE_DONE); 1928 + } 1929 + 1930 + static void dma_idle_int_handler(struct snps_hdmirx_dev *hdmirx_dev, 1931 + bool *handled) 1932 + { 1933 + struct hdmirx_stream *stream = &hdmirx_dev->stream; 1934 + struct v4l2_device *v4l2_dev = &hdmirx_dev->v4l2_dev; 1935 + struct v4l2_dv_timings timings = hdmirx_dev->timings; 1936 + struct v4l2_bt_timings *bt = &timings.bt; 1937 + struct vb2_v4l2_buffer *vb_done = NULL; 1938 + 1939 + if (!(stream->irq_stat) && !(stream->irq_stat & LINE_FLAG_INT_EN)) 1940 + v4l2_dbg(1, debug, v4l2_dev, 1941 + "%s: last time have no line_flag_irq\n", __func__); 1942 + 1943 + /* skip first frames that are expected to come out zeroed from DMA */ 1944 + if (stream->line_flag_int_cnt <= FILTER_FRAME_CNT) 1945 + goto DMA_IDLE_OUT; 1946 + 1947 + if (bt->interlaced != V4L2_DV_INTERLACED || 1948 + !(stream->line_flag_int_cnt % 2)) { 1949 + if (stream->next_buf) { 1950 + if (stream->curr_buf) 1951 + vb_done = &stream->curr_buf->vb; 1952 + 1953 + if (vb_done) { 1954 + vb_done->vb2_buf.timestamp = ktime_get_ns(); 1955 + vb_done->sequence = stream->frame_idx; 1956 + 1957 + if (bt->interlaced) 1958 + vb_done->field = V4L2_FIELD_INTERLACED_TB; 1959 + else 1960 + vb_done->field = V4L2_FIELD_NONE; 1961 + 1962 + hdmirx_vb_done(stream, vb_done); 1963 + stream->frame_idx++; 1964 + if (stream->frame_idx == 30) 1965 + v4l2_dbg(1, debug, v4l2_dev, 1966 + "rcv frames\n"); 1967 + } 1968 + 1969 + stream->curr_buf = NULL; 1970 + if (stream->next_buf) { 1971 + stream->curr_buf = stream->next_buf; 1972 + stream->next_buf = NULL; 1973 + } 1974 + } else { 1975 + v4l2_dbg(3, debug, v4l2_dev, 1976 + "%s: next_buf NULL, skip vb_done\n", __func__); 1977 + } 1978 + } 1979 + 1980 + DMA_IDLE_OUT: 1981 + *handled = true; 1982 + } 1983 + 1984 + static void line_flag_int_handler(struct snps_hdmirx_dev *hdmirx_dev, 1985 + bool *handled) 1986 + { 1987 + struct hdmirx_stream *stream = &hdmirx_dev->stream; 1988 + struct v4l2_device *v4l2_dev = &hdmirx_dev->v4l2_dev; 1989 + struct v4l2_dv_timings timings = hdmirx_dev->timings; 1990 + struct v4l2_bt_timings *bt = &timings.bt; 1991 + u32 dma_cfg6; 1992 + 1993 + stream->line_flag_int_cnt++; 1994 + if (!(stream->irq_stat) && !(stream->irq_stat & HDMIRX_DMA_IDLE_INT)) 1995 + v4l2_dbg(1, debug, v4l2_dev, 1996 + "%s: last have no dma_idle_irq\n", __func__); 1997 + dma_cfg6 = hdmirx_readl(hdmirx_dev, DMA_CONFIG6); 1998 + if (!(dma_cfg6 & HDMIRX_DMA_EN)) { 1999 + v4l2_dbg(2, debug, v4l2_dev, "%s: dma not on\n", __func__); 2000 + goto LINE_FLAG_OUT; 2001 + } 2002 + 2003 + if (stream->line_flag_int_cnt <= FILTER_FRAME_CNT) 2004 + goto LINE_FLAG_OUT; 2005 + 2006 + if (bt->interlaced != V4L2_DV_INTERLACED || 2007 + !(stream->line_flag_int_cnt % 2)) { 2008 + if (!stream->next_buf) { 2009 + spin_lock(&stream->vbq_lock); 2010 + if (!list_empty(&stream->buf_head)) { 2011 + stream->next_buf = list_first_entry(&stream->buf_head, 2012 + struct hdmirx_buffer, 2013 + queue); 2014 + list_del(&stream->next_buf->queue); 2015 + } else { 2016 + stream->next_buf = NULL; 2017 + } 2018 + spin_unlock(&stream->vbq_lock); 2019 + 2020 + if (stream->next_buf) { 2021 + hdmirx_writel(hdmirx_dev, DMA_CONFIG2, 2022 + stream->next_buf->buff_addr[HDMIRX_PLANE_Y]); 2023 + hdmirx_writel(hdmirx_dev, DMA_CONFIG3, 2024 + stream->next_buf->buff_addr[HDMIRX_PLANE_CBCR]); 2025 + } else { 2026 + v4l2_dbg(3, debug, v4l2_dev, 2027 + "%s: no buffer is available\n", __func__); 2028 + } 2029 + } 2030 + } else { 2031 + v4l2_dbg(3, debug, v4l2_dev, "%s: interlace:%d, line_flag_int_cnt:%d\n", 2032 + __func__, bt->interlaced, stream->line_flag_int_cnt); 2033 + } 2034 + 2035 + LINE_FLAG_OUT: 2036 + *handled = true; 2037 + } 2038 + 2039 + static irqreturn_t hdmirx_dma_irq_handler(int irq, void *dev_id) 2040 + { 2041 + struct snps_hdmirx_dev *hdmirx_dev = dev_id; 2042 + struct hdmirx_stream *stream = &hdmirx_dev->stream; 2043 + struct v4l2_device *v4l2_dev = &hdmirx_dev->v4l2_dev; 2044 + u32 dma_stat1, dma_stat13; 2045 + bool handled = false; 2046 + 2047 + dma_stat1 = hdmirx_readl(hdmirx_dev, DMA_STATUS1); 2048 + dma_stat13 = hdmirx_readl(hdmirx_dev, DMA_STATUS13); 2049 + v4l2_dbg(3, debug, v4l2_dev, "dma_irq st1:%#x, st13:%d\n", 2050 + dma_stat1, dma_stat13); 2051 + 2052 + if (READ_ONCE(stream->stopping)) { 2053 + v4l2_dbg(1, debug, v4l2_dev, "%s: stop stream\n", __func__); 2054 + hdmirx_writel(hdmirx_dev, DMA_CONFIG5, 0xffffffff); 2055 + hdmirx_update_bits(hdmirx_dev, DMA_CONFIG4, 2056 + LINE_FLAG_INT_EN | 2057 + HDMIRX_DMA_IDLE_INT | 2058 + HDMIRX_LOCK_DISABLE_INT | 2059 + LAST_FRAME_AXI_UNFINISH_INT_EN | 2060 + FIFO_OVERFLOW_INT_EN | 2061 + FIFO_UNDERFLOW_INT_EN | 2062 + HDMIRX_AXI_ERROR_INT_EN, 0); 2063 + WRITE_ONCE(stream->stopping, false); 2064 + wake_up(&stream->wq_stopped); 2065 + return IRQ_HANDLED; 2066 + } 2067 + 2068 + if (dma_stat1 & HDMIRX_DMA_IDLE_INT) 2069 + dma_idle_int_handler(hdmirx_dev, &handled); 2070 + 2071 + if (dma_stat1 & LINE_FLAG_INT_EN) 2072 + line_flag_int_handler(hdmirx_dev, &handled); 2073 + 2074 + if (!handled) 2075 + v4l2_dbg(3, debug, v4l2_dev, 2076 + "%s: dma irq not handled, dma_stat1:%#x\n", 2077 + __func__, dma_stat1); 2078 + 2079 + stream->irq_stat = dma_stat1; 2080 + hdmirx_writel(hdmirx_dev, DMA_CONFIG5, 0xffffffff); 2081 + 2082 + return IRQ_HANDLED; 2083 + } 2084 + 2085 + static int hdmirx_wait_signal_lock(struct snps_hdmirx_dev *hdmirx_dev) 2086 + { 2087 + struct v4l2_device *v4l2_dev = &hdmirx_dev->v4l2_dev; 2088 + u32 mu_status, scdc_status, dma_st10, cmu_st; 2089 + u32 i; 2090 + 2091 + for (i = 0; i < 300; i++) { 2092 + mu_status = hdmirx_readl(hdmirx_dev, MAINUNIT_STATUS); 2093 + scdc_status = hdmirx_readl(hdmirx_dev, SCDC_REGBANK_STATUS3); 2094 + dma_st10 = hdmirx_readl(hdmirx_dev, DMA_STATUS10); 2095 + cmu_st = hdmirx_readl(hdmirx_dev, CMU_STATUS); 2096 + 2097 + if ((mu_status & TMDSVALID_STABLE_ST) && 2098 + (dma_st10 & HDMIRX_LOCK) && 2099 + (cmu_st & TMDSQPCLK_LOCKED_ST)) 2100 + break; 2101 + 2102 + if (!tx_5v_power_present(hdmirx_dev)) { 2103 + v4l2_dbg(1, debug, v4l2_dev, 2104 + "%s: HDMI pull out, return\n", __func__); 2105 + return -1; 2106 + } 2107 + 2108 + hdmirx_tmds_clk_ratio_config(hdmirx_dev); 2109 + } 2110 + 2111 + if (i == 300) { 2112 + v4l2_err(v4l2_dev, "%s: signal not lock, tmds_clk_ratio:%d\n", 2113 + __func__, hdmirx_dev->tmds_clk_ratio); 2114 + v4l2_err(v4l2_dev, "%s: mu_st:%#x, scdc_st:%#x, dma_st10:%#x\n", 2115 + __func__, mu_status, scdc_status, dma_st10); 2116 + return -1; 2117 + } 2118 + 2119 + v4l2_dbg(1, debug, v4l2_dev, "%s: signal lock ok, i:%d\n", __func__, i); 2120 + hdmirx_writel(hdmirx_dev, GLOBAL_SWRESET_REQUEST, DATAPATH_SWRESETREQ); 2121 + 2122 + reinit_completion(&hdmirx_dev->avi_pkt_rcv); 2123 + hdmirx_clear_interrupt(hdmirx_dev, PKT_2_INT_CLEAR, 0xffffffff); 2124 + hdmirx_update_bits(hdmirx_dev, PKT_2_INT_MASK_N, 2125 + PKTDEC_AVIIF_RCV_IRQ, PKTDEC_AVIIF_RCV_IRQ); 2126 + 2127 + if (!wait_for_completion_timeout(&hdmirx_dev->avi_pkt_rcv, 2128 + msecs_to_jiffies(300))) { 2129 + v4l2_err(v4l2_dev, "%s wait avi_pkt_rcv failed\n", __func__); 2130 + hdmirx_update_bits(hdmirx_dev, PKT_2_INT_MASK_N, 2131 + PKTDEC_AVIIF_RCV_IRQ, 0); 2132 + } 2133 + 2134 + msleep(50); 2135 + hdmirx_format_change(hdmirx_dev); 2136 + 2137 + return 0; 2138 + } 2139 + 2140 + static void hdmirx_plugin(struct snps_hdmirx_dev *hdmirx_dev) 2141 + { 2142 + if (hdmirx_dev->plugged) 2143 + return; 2144 + 2145 + hdmirx_submodule_init(hdmirx_dev); 2146 + hdmirx_update_bits(hdmirx_dev, SCDC_CONFIG, POWERPROVIDED, 2147 + POWERPROVIDED); 2148 + hdmirx_phy_config(hdmirx_dev); 2149 + hdmirx_interrupts_setup(hdmirx_dev, true); 2150 + 2151 + hdmirx_dev->plugged = true; 2152 + } 2153 + 2154 + static void hdmirx_delayed_work_hotplug(struct work_struct *work) 2155 + { 2156 + struct snps_hdmirx_dev *hdmirx_dev; 2157 + bool plugin; 2158 + 2159 + hdmirx_dev = container_of(work, struct snps_hdmirx_dev, 2160 + delayed_work_hotplug.work); 2161 + 2162 + mutex_lock(&hdmirx_dev->work_lock); 2163 + plugin = tx_5v_power_present(hdmirx_dev); 2164 + v4l2_ctrl_s_ctrl(hdmirx_dev->detect_tx_5v_ctrl, plugin); 2165 + v4l2_dbg(1, debug, &hdmirx_dev->v4l2_dev, "%s: plugin:%d\n", 2166 + __func__, plugin); 2167 + 2168 + hdmirx_plugout(hdmirx_dev); 2169 + 2170 + if (plugin) 2171 + hdmirx_plugin(hdmirx_dev); 2172 + 2173 + mutex_unlock(&hdmirx_dev->work_lock); 2174 + } 2175 + 2176 + static void hdmirx_delayed_work_res_change(struct work_struct *work) 2177 + { 2178 + struct snps_hdmirx_dev *hdmirx_dev; 2179 + bool plugin; 2180 + 2181 + hdmirx_dev = container_of(work, struct snps_hdmirx_dev, 2182 + delayed_work_res_change.work); 2183 + 2184 + mutex_lock(&hdmirx_dev->work_lock); 2185 + plugin = tx_5v_power_present(hdmirx_dev); 2186 + v4l2_dbg(1, debug, &hdmirx_dev->v4l2_dev, "%s: plugin:%d\n", 2187 + __func__, plugin); 2188 + if (plugin) { 2189 + hdmirx_interrupts_setup(hdmirx_dev, false); 2190 + hdmirx_submodule_init(hdmirx_dev); 2191 + hdmirx_update_bits(hdmirx_dev, SCDC_CONFIG, POWERPROVIDED, 2192 + POWERPROVIDED); 2193 + hdmirx_phy_config(hdmirx_dev); 2194 + 2195 + if (hdmirx_wait_signal_lock(hdmirx_dev)) { 2196 + hdmirx_plugout(hdmirx_dev); 2197 + queue_delayed_work(system_unbound_wq, 2198 + &hdmirx_dev->delayed_work_hotplug, 2199 + msecs_to_jiffies(200)); 2200 + } else { 2201 + hdmirx_dma_config(hdmirx_dev); 2202 + hdmirx_interrupts_setup(hdmirx_dev, true); 2203 + } 2204 + } 2205 + mutex_unlock(&hdmirx_dev->work_lock); 2206 + } 2207 + 2208 + static irqreturn_t hdmirx_5v_det_irq_handler(int irq, void *dev_id) 2209 + { 2210 + struct snps_hdmirx_dev *hdmirx_dev = dev_id; 2211 + u32 val; 2212 + 2213 + val = gpiod_get_value(hdmirx_dev->detect_5v_gpio); 2214 + v4l2_dbg(3, debug, &hdmirx_dev->v4l2_dev, "%s: 5v:%d\n", __func__, val); 2215 + 2216 + queue_delayed_work(system_unbound_wq, 2217 + &hdmirx_dev->delayed_work_hotplug, 2218 + msecs_to_jiffies(10)); 2219 + 2220 + return IRQ_HANDLED; 2221 + } 2222 + 2223 + static const struct hdmirx_cec_ops hdmirx_cec_ops = { 2224 + .write = hdmirx_writel, 2225 + .read = hdmirx_readl, 2226 + }; 2227 + 2228 + static void devm_hdmirx_of_reserved_mem_device_release(void *dev) 2229 + { 2230 + of_reserved_mem_device_release(dev); 2231 + } 2232 + 2233 + static int hdmirx_parse_dt(struct snps_hdmirx_dev *hdmirx_dev) 2234 + { 2235 + struct device *dev = hdmirx_dev->dev; 2236 + int ret; 2237 + 2238 + hdmirx_dev->num_clks = devm_clk_bulk_get_all(dev, &hdmirx_dev->clks); 2239 + if (hdmirx_dev->num_clks < 1) 2240 + return -ENODEV; 2241 + 2242 + hdmirx_dev->resets[HDMIRX_RST_A].id = "axi"; 2243 + hdmirx_dev->resets[HDMIRX_RST_P].id = "apb"; 2244 + hdmirx_dev->resets[HDMIRX_RST_REF].id = "ref"; 2245 + hdmirx_dev->resets[HDMIRX_RST_BIU].id = "biu"; 2246 + 2247 + ret = devm_reset_control_bulk_get_exclusive(dev, HDMIRX_NUM_RST, 2248 + hdmirx_dev->resets); 2249 + if (ret < 0) { 2250 + dev_err(dev, "failed to get reset controls\n"); 2251 + return ret; 2252 + } 2253 + 2254 + hdmirx_dev->detect_5v_gpio = 2255 + devm_gpiod_get_optional(dev, "hpd", GPIOD_IN); 2256 + 2257 + if (IS_ERR(hdmirx_dev->detect_5v_gpio)) { 2258 + dev_err(dev, "failed to get hdmirx hot plug detection gpio\n"); 2259 + return PTR_ERR(hdmirx_dev->detect_5v_gpio); 2260 + } 2261 + 2262 + hdmirx_dev->grf = syscon_regmap_lookup_by_phandle(dev->of_node, 2263 + "rockchip,grf"); 2264 + if (IS_ERR(hdmirx_dev->grf)) { 2265 + dev_err(dev, "failed to get rockchip,grf\n"); 2266 + return PTR_ERR(hdmirx_dev->grf); 2267 + } 2268 + 2269 + hdmirx_dev->vo1_grf = syscon_regmap_lookup_by_phandle(dev->of_node, 2270 + "rockchip,vo1-grf"); 2271 + if (IS_ERR(hdmirx_dev->vo1_grf)) { 2272 + dev_err(dev, "failed to get rockchip,vo1-grf\n"); 2273 + return PTR_ERR(hdmirx_dev->vo1_grf); 2274 + } 2275 + 2276 + if (!device_property_read_bool(dev, "hpd-is-active-low")) 2277 + hdmirx_dev->hpd_trigger_level_high = true; 2278 + 2279 + ret = of_reserved_mem_device_init(dev); 2280 + if (ret) { 2281 + dev_warn(dev, "no reserved memory for HDMIRX, use default CMA\n"); 2282 + } else { 2283 + ret = devm_add_action_or_reset(dev, 2284 + devm_hdmirx_of_reserved_mem_device_release, 2285 + dev); 2286 + if (ret) 2287 + return ret; 2288 + } 2289 + 2290 + return 0; 2291 + } 2292 + 2293 + static void hdmirx_disable_all_interrupts(struct snps_hdmirx_dev *hdmirx_dev) 2294 + { 2295 + hdmirx_writel(hdmirx_dev, MAINUNIT_0_INT_MASK_N, 0); 2296 + hdmirx_writel(hdmirx_dev, MAINUNIT_1_INT_MASK_N, 0); 2297 + hdmirx_writel(hdmirx_dev, MAINUNIT_2_INT_MASK_N, 0); 2298 + hdmirx_writel(hdmirx_dev, AVPUNIT_0_INT_MASK_N, 0); 2299 + hdmirx_writel(hdmirx_dev, AVPUNIT_1_INT_MASK_N, 0); 2300 + hdmirx_writel(hdmirx_dev, PKT_0_INT_MASK_N, 0); 2301 + hdmirx_writel(hdmirx_dev, PKT_1_INT_MASK_N, 0); 2302 + hdmirx_writel(hdmirx_dev, PKT_2_INT_MASK_N, 0); 2303 + hdmirx_writel(hdmirx_dev, SCDC_INT_MASK_N, 0); 2304 + hdmirx_writel(hdmirx_dev, CEC_INT_MASK_N, 0); 2305 + 2306 + hdmirx_clear_interrupt(hdmirx_dev, MAINUNIT_0_INT_CLEAR, 0xffffffff); 2307 + hdmirx_clear_interrupt(hdmirx_dev, MAINUNIT_1_INT_CLEAR, 0xffffffff); 2308 + hdmirx_clear_interrupt(hdmirx_dev, MAINUNIT_2_INT_CLEAR, 0xffffffff); 2309 + hdmirx_clear_interrupt(hdmirx_dev, AVPUNIT_0_INT_CLEAR, 0xffffffff); 2310 + hdmirx_clear_interrupt(hdmirx_dev, AVPUNIT_1_INT_CLEAR, 0xffffffff); 2311 + hdmirx_clear_interrupt(hdmirx_dev, PKT_0_INT_CLEAR, 0xffffffff); 2312 + hdmirx_clear_interrupt(hdmirx_dev, PKT_1_INT_CLEAR, 0xffffffff); 2313 + hdmirx_clear_interrupt(hdmirx_dev, PKT_2_INT_CLEAR, 0xffffffff); 2314 + hdmirx_clear_interrupt(hdmirx_dev, SCDC_INT_CLEAR, 0xffffffff); 2315 + hdmirx_clear_interrupt(hdmirx_dev, HDCP_INT_CLEAR, 0xffffffff); 2316 + hdmirx_clear_interrupt(hdmirx_dev, HDCP_1_INT_CLEAR, 0xffffffff); 2317 + hdmirx_clear_interrupt(hdmirx_dev, CEC_INT_CLEAR, 0xffffffff); 2318 + } 2319 + 2320 + static void hdmirx_init(struct snps_hdmirx_dev *hdmirx_dev) 2321 + { 2322 + hdmirx_update_bits(hdmirx_dev, PHY_CONFIG, PHY_RESET | PHY_PDDQ, 0); 2323 + 2324 + regmap_write(hdmirx_dev->vo1_grf, VO1_GRF_VO1_CON2, 2325 + (HDMIRX_SDAIN_MSK | HDMIRX_SCLIN_MSK) | 2326 + ((HDMIRX_SDAIN_MSK | HDMIRX_SCLIN_MSK) << 16)); 2327 + /* 2328 + * Some interrupts are enabled by default, so we disable 2329 + * all interrupts and clear interrupts status first. 2330 + */ 2331 + hdmirx_disable_all_interrupts(hdmirx_dev); 2332 + } 2333 + 2334 + /* hdmi-4k-300mhz EDID produced by v4l2-ctl tool */ 2335 + static u8 __maybe_unused edid_default[] = { 2336 + 0x00, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0x00, 2337 + 0x31, 0xd8, 0x34, 0x12, 0x00, 0x00, 0x00, 0x00, 2338 + 0x22, 0x1a, 0x01, 0x03, 0x80, 0x60, 0x36, 0x78, 2339 + 0x0f, 0xee, 0x91, 0xa3, 0x54, 0x4c, 0x99, 0x26, 2340 + 0x0f, 0x50, 0x54, 0x2f, 0xcf, 0x00, 0x31, 0x59, 2341 + 0x45, 0x59, 0x81, 0x80, 0x81, 0x40, 0x90, 0x40, 2342 + 0x95, 0x00, 0xa9, 0x40, 0xb3, 0x00, 0x04, 0x74, 2343 + 0x00, 0x30, 0xf2, 0x70, 0x5a, 0x80, 0xb0, 0x58, 2344 + 0x8a, 0x00, 0xc0, 0x1c, 0x32, 0x00, 0x00, 0x1e, 2345 + 0x00, 0x00, 0x00, 0xfd, 0x00, 0x18, 0x55, 0x18, 2346 + 0x87, 0x1e, 0x00, 0x0a, 0x20, 0x20, 0x20, 0x20, 2347 + 0x20, 0x20, 0x00, 0x00, 0x00, 0xfc, 0x00, 0x68, 2348 + 0x64, 0x6d, 0x69, 0x2d, 0x34, 0x6b, 0x2d, 0x33, 2349 + 0x30, 0x30, 0x0a, 0x20, 0x00, 0x00, 0x00, 0x10, 2350 + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 2351 + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0xc5, 2352 + 2353 + 0x02, 0x03, 0x40, 0xf1, 0x4f, 0x5f, 0x5e, 0x5d, 2354 + 0x10, 0x1f, 0x04, 0x13, 0x22, 0x21, 0x20, 0x05, 2355 + 0x14, 0x02, 0x11, 0x01, 0x23, 0x09, 0x07, 0x07, 2356 + 0x83, 0x01, 0x00, 0x00, 0x6d, 0x03, 0x0c, 0x00, 2357 + 0x10, 0x00, 0x00, 0x3c, 0x21, 0x00, 0x60, 0x01, 2358 + 0x02, 0x03, 0x67, 0xd8, 0x5d, 0xc4, 0x01, 0x00, 2359 + 0x00, 0x00, 0xe2, 0x00, 0xca, 0xe3, 0x05, 0x00, 2360 + 0x00, 0xe3, 0x06, 0x01, 0x00, 0xe2, 0x0d, 0x5f, 2361 + 0xa3, 0x66, 0x00, 0xa0, 0xf0, 0x70, 0x1f, 0x80, 2362 + 0x30, 0x20, 0x35, 0x00, 0xc0, 0x1c, 0x32, 0x00, 2363 + 0x00, 0x1e, 0x1a, 0x36, 0x80, 0xa0, 0x70, 0x38, 2364 + 0x1f, 0x40, 0x30, 0x20, 0x35, 0x00, 0xc0, 0x1c, 2365 + 0x32, 0x00, 0x00, 0x1a, 0x1a, 0x1d, 0x00, 0x80, 2366 + 0x51, 0xd0, 0x1c, 0x20, 0x40, 0x80, 0x35, 0x00, 2367 + 0xc0, 0x1c, 0x32, 0x00, 0x00, 0x1c, 0x00, 0x00, 2368 + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xa1, 2369 + }; 2370 + 2371 + static void hdmirx_load_default_edid(struct snps_hdmirx_dev *hdmirx_dev) 2372 + { 2373 + struct v4l2_edid def_edid = {}; 2374 + 2375 + hdmirx_hpd_ctrl(hdmirx_dev, false); 2376 + 2377 + if (!IS_ENABLED(CONFIG_VIDEO_SYNOPSYS_HDMIRX_LOAD_DEFAULT_EDID)) 2378 + return; 2379 + 2380 + /* disable hpd and write edid */ 2381 + def_edid.blocks = sizeof(edid_default) / EDID_BLOCK_SIZE; 2382 + def_edid.edid = edid_default; 2383 + 2384 + hdmirx_write_edid(hdmirx_dev, &def_edid); 2385 + hdmirx_hpd_ctrl(hdmirx_dev, true); 2386 + } 2387 + 2388 + static int hdmirx_disable(struct device *dev) 2389 + { 2390 + struct snps_hdmirx_dev *hdmirx_dev = dev_get_drvdata(dev); 2391 + struct v4l2_device *v4l2_dev = &hdmirx_dev->v4l2_dev; 2392 + 2393 + hdmirx_plugout(hdmirx_dev); 2394 + hdmirx_hpd_ctrl(hdmirx_dev, false); 2395 + 2396 + clk_bulk_disable_unprepare(hdmirx_dev->num_clks, hdmirx_dev->clks); 2397 + 2398 + v4l2_dbg(2, debug, v4l2_dev, "%s: suspend\n", __func__); 2399 + 2400 + return pinctrl_pm_select_sleep_state(dev); 2401 + } 2402 + 2403 + static int hdmirx_enable(struct device *dev) 2404 + { 2405 + struct snps_hdmirx_dev *hdmirx_dev = dev_get_drvdata(dev); 2406 + struct v4l2_device *v4l2_dev = &hdmirx_dev->v4l2_dev; 2407 + int ret; 2408 + 2409 + v4l2_dbg(2, debug, v4l2_dev, "%s: resume\n", __func__); 2410 + ret = pinctrl_pm_select_default_state(dev); 2411 + if (ret < 0) 2412 + return ret; 2413 + 2414 + ret = clk_bulk_prepare_enable(hdmirx_dev->num_clks, hdmirx_dev->clks); 2415 + if (ret) { 2416 + dev_err(dev, "failed to enable hdmirx bulk clks: %d\n", ret); 2417 + return ret; 2418 + } 2419 + 2420 + reset_control_bulk_assert(HDMIRX_NUM_RST, hdmirx_dev->resets); 2421 + usleep_range(150, 160); 2422 + reset_control_bulk_deassert(HDMIRX_NUM_RST, hdmirx_dev->resets); 2423 + usleep_range(150, 160); 2424 + 2425 + return 0; 2426 + } 2427 + 2428 + static void hdmirx_disable_irq(struct device *dev) 2429 + { 2430 + struct snps_hdmirx_dev *hdmirx_dev = dev_get_drvdata(dev); 2431 + 2432 + disable_irq(hdmirx_dev->det_irq); 2433 + disable_irq(hdmirx_dev->dma_irq); 2434 + disable_irq(hdmirx_dev->hdmi_irq); 2435 + 2436 + cancel_delayed_work_sync(&hdmirx_dev->delayed_work_hotplug); 2437 + cancel_delayed_work_sync(&hdmirx_dev->delayed_work_res_change); 2438 + } 2439 + 2440 + static void hdmirx_enable_irq(struct device *dev) 2441 + { 2442 + struct snps_hdmirx_dev *hdmirx_dev = dev_get_drvdata(dev); 2443 + 2444 + enable_irq(hdmirx_dev->hdmi_irq); 2445 + enable_irq(hdmirx_dev->dma_irq); 2446 + enable_irq(hdmirx_dev->det_irq); 2447 + 2448 + queue_delayed_work(system_unbound_wq, 2449 + &hdmirx_dev->delayed_work_hotplug, 2450 + msecs_to_jiffies(110)); 2451 + } 2452 + 2453 + static __maybe_unused int hdmirx_suspend(struct device *dev) 2454 + { 2455 + struct snps_hdmirx_dev *hdmirx_dev = dev_get_drvdata(dev); 2456 + 2457 + hdmirx_disable_irq(dev); 2458 + 2459 + /* TODO store CEC HW state */ 2460 + disable_irq(hdmirx_dev->cec->irq); 2461 + 2462 + return hdmirx_disable(dev); 2463 + } 2464 + 2465 + static __maybe_unused int hdmirx_resume(struct device *dev) 2466 + { 2467 + struct snps_hdmirx_dev *hdmirx_dev = dev_get_drvdata(dev); 2468 + int ret = hdmirx_enable(dev); 2469 + 2470 + if (ret) 2471 + return ret; 2472 + 2473 + if (hdmirx_dev->edid_blocks_written) { 2474 + hdmirx_write_edid_data(hdmirx_dev, hdmirx_dev->edid, 2475 + hdmirx_dev->edid_blocks_written); 2476 + hdmirx_hpd_ctrl(hdmirx_dev, true); 2477 + } 2478 + 2479 + /* TODO restore CEC HW state */ 2480 + enable_irq(hdmirx_dev->cec->irq); 2481 + 2482 + hdmirx_enable_irq(dev); 2483 + 2484 + return 0; 2485 + } 2486 + 2487 + static const struct dev_pm_ops snps_hdmirx_pm_ops = { 2488 + SET_SYSTEM_SLEEP_PM_OPS(hdmirx_suspend, hdmirx_resume) 2489 + }; 2490 + 2491 + static int hdmirx_setup_irq(struct snps_hdmirx_dev *hdmirx_dev, 2492 + struct platform_device *pdev) 2493 + { 2494 + struct device *dev = hdmirx_dev->dev; 2495 + int ret, irq; 2496 + 2497 + irq = platform_get_irq_byname(pdev, "hdmi"); 2498 + if (irq < 0) { 2499 + dev_err_probe(dev, irq, "failed to get hdmi irq\n"); 2500 + return irq; 2501 + } 2502 + 2503 + irq_set_status_flags(irq, IRQ_NOAUTOEN); 2504 + 2505 + hdmirx_dev->hdmi_irq = irq; 2506 + ret = devm_request_irq(dev, irq, hdmirx_hdmi_irq_handler, 0, 2507 + "rk_hdmirx-hdmi", hdmirx_dev); 2508 + if (ret) { 2509 + dev_err_probe(dev, ret, "failed to request hdmi irq\n"); 2510 + return ret; 2511 + } 2512 + 2513 + irq = platform_get_irq_byname(pdev, "dma"); 2514 + if (irq < 0) { 2515 + dev_err_probe(dev, irq, "failed to get dma irq\n"); 2516 + return irq; 2517 + } 2518 + 2519 + irq_set_status_flags(irq, IRQ_NOAUTOEN); 2520 + 2521 + hdmirx_dev->dma_irq = irq; 2522 + ret = devm_request_threaded_irq(dev, irq, NULL, hdmirx_dma_irq_handler, 2523 + IRQF_ONESHOT, "rk_hdmirx-dma", 2524 + hdmirx_dev); 2525 + if (ret) { 2526 + dev_err_probe(dev, ret, "failed to request dma irq\n"); 2527 + return ret; 2528 + } 2529 + 2530 + irq = gpiod_to_irq(hdmirx_dev->detect_5v_gpio); 2531 + if (irq < 0) { 2532 + dev_err_probe(dev, irq, "failed to get hdmirx-5v irq\n"); 2533 + return irq; 2534 + } 2535 + 2536 + irq_set_status_flags(irq, IRQ_NOAUTOEN); 2537 + 2538 + hdmirx_dev->det_irq = irq; 2539 + ret = devm_request_irq(dev, irq, hdmirx_5v_det_irq_handler, 2540 + IRQF_TRIGGER_FALLING | IRQF_TRIGGER_RISING, 2541 + "rk_hdmirx-5v", hdmirx_dev); 2542 + if (ret) { 2543 + dev_err_probe(dev, ret, "failed to request hdmirx-5v irq\n"); 2544 + return ret; 2545 + } 2546 + 2547 + return 0; 2548 + } 2549 + 2550 + static int hdmirx_register_cec(struct snps_hdmirx_dev *hdmirx_dev, 2551 + struct platform_device *pdev) 2552 + { 2553 + struct device *dev = hdmirx_dev->dev; 2554 + struct hdmirx_cec_data cec_data; 2555 + int irq; 2556 + 2557 + irq = platform_get_irq_byname(pdev, "cec"); 2558 + if (irq < 0) { 2559 + dev_err_probe(dev, irq, "failed to get cec irq\n"); 2560 + return irq; 2561 + } 2562 + 2563 + cec_data.hdmirx = hdmirx_dev; 2564 + cec_data.dev = hdmirx_dev->dev; 2565 + cec_data.ops = &hdmirx_cec_ops; 2566 + cec_data.irq = irq; 2567 + 2568 + hdmirx_dev->cec = snps_hdmirx_cec_register(&cec_data); 2569 + if (IS_ERR(hdmirx_dev->cec)) 2570 + return dev_err_probe(dev, PTR_ERR(hdmirx_dev->cec), 2571 + "failed to register cec\n"); 2572 + 2573 + return 0; 2574 + } 2575 + 2576 + static int hdmirx_probe(struct platform_device *pdev) 2577 + { 2578 + struct snps_hdmirx_dev *hdmirx_dev; 2579 + struct device *dev = &pdev->dev; 2580 + struct v4l2_ctrl_handler *hdl; 2581 + struct hdmirx_stream *stream; 2582 + struct v4l2_device *v4l2_dev; 2583 + int ret; 2584 + 2585 + hdmirx_dev = devm_kzalloc(dev, sizeof(*hdmirx_dev), GFP_KERNEL); 2586 + if (!hdmirx_dev) 2587 + return -ENOMEM; 2588 + 2589 + /* 2590 + * RK3588 HDMIRX SoC integration doesn't use IOMMU and can 2591 + * address only first 32bit of the physical address space. 2592 + */ 2593 + ret = dma_set_mask_and_coherent(dev, DMA_BIT_MASK(32)); 2594 + if (ret) 2595 + return ret; 2596 + 2597 + hdmirx_dev->dev = dev; 2598 + dev_set_drvdata(dev, hdmirx_dev); 2599 + 2600 + ret = hdmirx_parse_dt(hdmirx_dev); 2601 + if (ret) 2602 + return ret; 2603 + 2604 + ret = hdmirx_setup_irq(hdmirx_dev, pdev); 2605 + if (ret) 2606 + return ret; 2607 + 2608 + hdmirx_dev->regs = devm_platform_ioremap_resource(pdev, 0); 2609 + if (IS_ERR(hdmirx_dev->regs)) 2610 + return dev_err_probe(dev, PTR_ERR(hdmirx_dev->regs), 2611 + "failed to remap regs resource\n"); 2612 + 2613 + mutex_init(&hdmirx_dev->stream_lock); 2614 + mutex_init(&hdmirx_dev->work_lock); 2615 + spin_lock_init(&hdmirx_dev->rst_lock); 2616 + 2617 + init_completion(&hdmirx_dev->cr_write_done); 2618 + init_completion(&hdmirx_dev->timer_base_lock); 2619 + init_completion(&hdmirx_dev->avi_pkt_rcv); 2620 + 2621 + INIT_DELAYED_WORK(&hdmirx_dev->delayed_work_hotplug, 2622 + hdmirx_delayed_work_hotplug); 2623 + INIT_DELAYED_WORK(&hdmirx_dev->delayed_work_res_change, 2624 + hdmirx_delayed_work_res_change); 2625 + 2626 + hdmirx_dev->cur_fmt_fourcc = V4L2_PIX_FMT_BGR24; 2627 + hdmirx_dev->timings = cea640x480; 2628 + 2629 + hdmirx_enable(dev); 2630 + hdmirx_init(hdmirx_dev); 2631 + 2632 + v4l2_dev = &hdmirx_dev->v4l2_dev; 2633 + strscpy(v4l2_dev->name, dev_name(dev), sizeof(v4l2_dev->name)); 2634 + 2635 + hdl = &hdmirx_dev->hdl; 2636 + v4l2_ctrl_handler_init(hdl, 3); 2637 + 2638 + hdmirx_dev->detect_tx_5v_ctrl = v4l2_ctrl_new_std(hdl, NULL, 2639 + V4L2_CID_DV_RX_POWER_PRESENT, 2640 + 0, 1, 0, 0); 2641 + 2642 + hdmirx_dev->rgb_range = v4l2_ctrl_new_std_menu(hdl, NULL, 2643 + V4L2_CID_DV_RX_RGB_RANGE, 2644 + V4L2_DV_RGB_RANGE_FULL, 0, 2645 + V4L2_DV_RGB_RANGE_AUTO); 2646 + 2647 + hdmirx_dev->rgb_range->flags |= V4L2_CTRL_FLAG_READ_ONLY; 2648 + 2649 + hdmirx_dev->content_type = 2650 + v4l2_ctrl_new_std_menu(hdl, NULL, V4L2_CID_DV_RX_IT_CONTENT_TYPE, 2651 + V4L2_DV_IT_CONTENT_TYPE_NO_ITC, 0, 2652 + V4L2_DV_IT_CONTENT_TYPE_NO_ITC); 2653 + 2654 + if (hdl->error) { 2655 + ret = hdl->error; 2656 + dev_err_probe(dev, ret, "v4l2 ctrl handler init failed\n"); 2657 + goto err_pm; 2658 + } 2659 + hdmirx_dev->v4l2_dev.ctrl_handler = hdl; 2660 + 2661 + ret = v4l2_device_register(dev, &hdmirx_dev->v4l2_dev); 2662 + if (ret < 0) { 2663 + dev_err_probe(dev, ret, "v4l2 device registration failed\n"); 2664 + goto err_hdl; 2665 + } 2666 + 2667 + stream = &hdmirx_dev->stream; 2668 + stream->hdmirx_dev = hdmirx_dev; 2669 + ret = hdmirx_register_stream_vdev(stream); 2670 + if (ret < 0) { 2671 + dev_err_probe(dev, ret, "video device registration failed\n"); 2672 + goto err_unreg_v4l2_dev; 2673 + } 2674 + 2675 + ret = hdmirx_register_cec(hdmirx_dev, pdev); 2676 + if (ret) 2677 + goto err_unreg_video_dev; 2678 + 2679 + hdmirx_load_default_edid(hdmirx_dev); 2680 + 2681 + hdmirx_enable_irq(dev); 2682 + 2683 + hdmirx_dev->debugfs_dir = debugfs_create_dir(hdmirx_dev->v4l2_dev.name, 2684 + v4l2_debugfs_root()); 2685 + 2686 + hdmirx_dev->infoframes = v4l2_debugfs_if_alloc(hdmirx_dev->debugfs_dir, 2687 + V4L2_DEBUGFS_IF_AVI, hdmirx_dev, 2688 + hdmirx_debugfs_if_read); 2689 + 2690 + return 0; 2691 + 2692 + err_unreg_video_dev: 2693 + vb2_video_unregister_device(&hdmirx_dev->stream.vdev); 2694 + err_unreg_v4l2_dev: 2695 + v4l2_device_unregister(&hdmirx_dev->v4l2_dev); 2696 + err_hdl: 2697 + v4l2_ctrl_handler_free(&hdmirx_dev->hdl); 2698 + err_pm: 2699 + hdmirx_disable(dev); 2700 + 2701 + return ret; 2702 + } 2703 + 2704 + static void hdmirx_remove(struct platform_device *pdev) 2705 + { 2706 + struct device *dev = &pdev->dev; 2707 + struct snps_hdmirx_dev *hdmirx_dev = dev_get_drvdata(dev); 2708 + 2709 + v4l2_debugfs_if_free(hdmirx_dev->infoframes); 2710 + debugfs_remove_recursive(hdmirx_dev->debugfs_dir); 2711 + 2712 + snps_hdmirx_cec_unregister(hdmirx_dev->cec); 2713 + 2714 + hdmirx_disable_irq(dev); 2715 + 2716 + vb2_video_unregister_device(&hdmirx_dev->stream.vdev); 2717 + v4l2_ctrl_handler_free(&hdmirx_dev->hdl); 2718 + v4l2_device_unregister(&hdmirx_dev->v4l2_dev); 2719 + 2720 + /* touched by hdmirx_disable()->hdmirx_plugout() */ 2721 + hdmirx_dev->rgb_range = NULL; 2722 + hdmirx_dev->content_type = NULL; 2723 + 2724 + hdmirx_disable(dev); 2725 + 2726 + reset_control_bulk_assert(HDMIRX_NUM_RST, hdmirx_dev->resets); 2727 + } 2728 + 2729 + static const struct of_device_id hdmirx_id[] = { 2730 + { .compatible = "rockchip,rk3588-hdmirx-ctrler" }, 2731 + { } 2732 + }; 2733 + MODULE_DEVICE_TABLE(of, hdmirx_id); 2734 + 2735 + static struct platform_driver hdmirx_driver = { 2736 + .probe = hdmirx_probe, 2737 + .remove = hdmirx_remove, 2738 + .driver = { 2739 + .name = "snps_hdmirx", 2740 + .of_match_table = hdmirx_id, 2741 + .pm = &snps_hdmirx_pm_ops, 2742 + } 2743 + }; 2744 + module_platform_driver(hdmirx_driver); 2745 + 2746 + MODULE_DESCRIPTION("Synopsys HDMI Receiver Driver"); 2747 + MODULE_AUTHOR("Dingxian Wen <shawn.wen@rock-chips.com>"); 2748 + MODULE_AUTHOR("Shreeya Patel <shreeya.patel@collabora.com>"); 2749 + MODULE_AUTHOR("Dmitry Osipenko <dmitry.osipenko@collabora.com>"); 2750 + MODULE_LICENSE("GPL");
+394
drivers/media/platform/synopsys/hdmirx/snps_hdmirx.h
··· 1 + /* SPDX-License-Identifier: GPL-2.0 */ 2 + /* 3 + * Copyright (c) 2021 Rockchip Electronics Co. Ltd. 4 + * 5 + * Author: Dingxian Wen <shawn.wen@rock-chips.com> 6 + */ 7 + 8 + #ifndef DW_HDMIRX_H 9 + #define DW_HDMIRX_H 10 + 11 + #include <linux/bitops.h> 12 + 13 + #define UPDATE(x, h, l) (((x) << (l)) & GENMASK((h), (l))) 14 + #define HIWORD_UPDATE(v, h, l) (((v) << (l)) | (GENMASK((h), (l)) << 16)) 15 + 16 + /* SYS_GRF */ 17 + #define SYS_GRF_SOC_CON1 0x0304 18 + #define HDMIRXPHY_SRAM_EXT_LD_DONE BIT(1) 19 + #define HDMIRXPHY_SRAM_BYPASS BIT(0) 20 + #define SYS_GRF_SOC_STATUS1 0x0384 21 + #define HDMIRXPHY_SRAM_INIT_DONE BIT(10) 22 + #define SYS_GRF_CHIP_ID 0x0600 23 + 24 + /* VO1_GRF */ 25 + #define VO1_GRF_VO1_CON2 0x0008 26 + #define HDMIRX_SDAIN_MSK BIT(2) 27 + #define HDMIRX_SCLIN_MSK BIT(1) 28 + 29 + /* HDMIRX PHY */ 30 + #define SUP_DIG_ANA_CREGS_SUP_ANA_NC 0x004f 31 + 32 + #define LANE0_DIG_ASIC_RX_OVRD_OUT_0 0x100f 33 + #define LANE1_DIG_ASIC_RX_OVRD_OUT_0 0x110f 34 + #define LANE2_DIG_ASIC_RX_OVRD_OUT_0 0x120f 35 + #define LANE3_DIG_ASIC_RX_OVRD_OUT_0 0x130f 36 + #define ASIC_ACK_OVRD_EN BIT(1) 37 + #define ASIC_ACK BIT(0) 38 + 39 + #define LANE0_DIG_RX_VCOCAL_RX_VCO_CAL_CTRL_2 0x104a 40 + #define LANE1_DIG_RX_VCOCAL_RX_VCO_CAL_CTRL_2 0x114a 41 + #define LANE2_DIG_RX_VCOCAL_RX_VCO_CAL_CTRL_2 0x124a 42 + #define LANE3_DIG_RX_VCOCAL_RX_VCO_CAL_CTRL_2 0x134a 43 + #define FREQ_TUNE_START_VAL_MASK GENMASK(9, 0) 44 + #define FREQ_TUNE_START_VAL(x) UPDATE(x, 9, 0) 45 + 46 + #define HDMIPCS_DIG_CTRL_PATH_MAIN_FSM_FSM_CONFIG 0x20c4 47 + #define HDMIPCS_DIG_CTRL_PATH_MAIN_FSM_ADAPT_REF_FOM 0x20c7 48 + #define HDMIPCS_DIG_CTRL_PATH_MAIN_FSM_RATE_CALC_HDMI14_CDR_SETTING_3_REG 0x20e9 49 + #define CDR_SETTING_BOUNDARY_3_DEFAULT 0x52da 50 + #define HDMIPCS_DIG_CTRL_PATH_MAIN_FSM_RATE_CALC_HDMI14_CDR_SETTING_4_REG 0x20ea 51 + #define CDR_SETTING_BOUNDARY_4_DEFAULT 0x43cd 52 + #define HDMIPCS_DIG_CTRL_PATH_MAIN_FSM_RATE_CALC_HDMI14_CDR_SETTING_5_REG 0x20eb 53 + #define CDR_SETTING_BOUNDARY_5_DEFAULT 0x35b3 54 + #define HDMIPCS_DIG_CTRL_PATH_MAIN_FSM_RATE_CALC_HDMI14_CDR_SETTING_6_REG 0x20fb 55 + #define CDR_SETTING_BOUNDARY_6_DEFAULT 0x2799 56 + #define HDMIPCS_DIG_CTRL_PATH_MAIN_FSM_RATE_CALC_HDMI14_CDR_SETTING_7_REG 0x20fc 57 + #define CDR_SETTING_BOUNDARY_7_DEFAULT 0x1b65 58 + 59 + #define RAWLANE0_DIG_PCS_XF_RX_OVRD_OUT 0x300e 60 + #define RAWLANE1_DIG_PCS_XF_RX_OVRD_OUT 0x310e 61 + #define RAWLANE2_DIG_PCS_XF_RX_OVRD_OUT 0x320e 62 + #define RAWLANE3_DIG_PCS_XF_RX_OVRD_OUT 0x330e 63 + #define PCS_ACK_WRITE_SELECT BIT(14) 64 + #define PCS_EN_CTL BIT(1) 65 + #define PCS_ACK BIT(0) 66 + 67 + #define RAWLANE0_DIG_AON_FAST_FLAGS 0x305c 68 + #define RAWLANE1_DIG_AON_FAST_FLAGS 0x315c 69 + #define RAWLANE2_DIG_AON_FAST_FLAGS 0x325c 70 + #define RAWLANE3_DIG_AON_FAST_FLAGS 0x335c 71 + 72 + /* HDMIRX Ctrler */ 73 + #define GLOBAL_SWRESET_REQUEST 0x0020 74 + #define DATAPATH_SWRESETREQ BIT(12) 75 + #define GLOBAL_SWENABLE 0x0024 76 + #define PHYCTRL_ENABLE BIT(21) 77 + #define CEC_ENABLE BIT(16) 78 + #define TMDS_ENABLE BIT(13) 79 + #define DATAPATH_ENABLE BIT(12) 80 + #define PKTFIFO_ENABLE BIT(11) 81 + #define AVPUNIT_ENABLE BIT(8) 82 + #define MAIN_ENABLE BIT(0) 83 + #define GLOBAL_TIMER_REF_BASE 0x0028 84 + #define CORE_CONFIG 0x0050 85 + #define CMU_CONFIG0 0x0060 86 + #define TMDSQPCLK_STABLE_FREQ_MARGIN_MASK GENMASK(30, 16) 87 + #define TMDSQPCLK_STABLE_FREQ_MARGIN(x) UPDATE(x, 30, 16) 88 + #define AUDCLK_STABLE_FREQ_MARGIN_MASK GENMASK(11, 9) 89 + #define AUDCLK_STABLE_FREQ_MARGIN(x) UPDATE(x, 11, 9) 90 + #define CMU_STATUS 0x007c 91 + #define TMDSQPCLK_LOCKED_ST BIT(4) 92 + #define CMU_TMDSQPCLK_FREQ 0x0084 93 + #define PHY_CONFIG 0x00c0 94 + #define LDO_AFE_PROG_MASK GENMASK(24, 23) 95 + #define LDO_AFE_PROG(x) UPDATE(x, 24, 23) 96 + #define LDO_PWRDN BIT(21) 97 + #define TMDS_CLOCK_RATIO BIT(16) 98 + #define RXDATA_WIDTH BIT(15) 99 + #define REFFREQ_SEL_MASK GENMASK(11, 9) 100 + #define REFFREQ_SEL(x) UPDATE(x, 11, 9) 101 + #define HDMI_DISABLE BIT(8) 102 + #define PHY_PDDQ BIT(1) 103 + #define PHY_RESET BIT(0) 104 + #define PHY_STATUS 0x00c8 105 + #define HDMI_DISABLE_ACK BIT(1) 106 + #define PDDQ_ACK BIT(0) 107 + #define PHYCREG_CONFIG0 0x00e0 108 + #define PHYCREG_CR_PARA_SELECTION_MODE_MASK GENMASK(1, 0) 109 + #define PHYCREG_CR_PARA_SELECTION_MODE(x) UPDATE(x, 1, 0) 110 + #define PHYCREG_CONFIG1 0x00e4 111 + #define PHYCREG_CONFIG2 0x00e8 112 + #define PHYCREG_CONFIG3 0x00ec 113 + #define PHYCREG_CONTROL 0x00f0 114 + #define PHYCREG_CR_PARA_WRITE_P BIT(1) 115 + #define PHYCREG_CR_PARA_READ_P BIT(0) 116 + #define PHYCREG_STATUS 0x00f4 117 + 118 + #define MAINUNIT_STATUS 0x0150 119 + #define TMDSVALID_STABLE_ST BIT(1) 120 + #define DESCRAND_EN_CONTROL 0x0210 121 + #define SCRAMB_EN_SEL_QST_MASK GENMASK(1, 0) 122 + #define SCRAMB_EN_SEL_QST(x) UPDATE(x, 1, 0) 123 + #define DESCRAND_SYNC_CONTROL 0x0214 124 + #define RECOVER_UNSYNC_STREAM_QST BIT(0) 125 + #define DESCRAND_SYNC_SEQ_CONFIG 0x022c 126 + #define DESCRAND_SYNC_SEQ_ERR_CNT_EN BIT(0) 127 + #define DESCRAND_SYNC_SEQ_STATUS 0x0234 128 + #define DEFRAMER_CONFIG0 0x0270 129 + #define VS_CNT_THR_QST_MASK GENMASK(27, 20) 130 + #define VS_CNT_THR_QST(x) UPDATE(x, 27, 20) 131 + #define HS_POL_QST_MASK GENMASK(19, 18) 132 + #define HS_POL_QST(x) UPDATE(x, 19, 18) 133 + #define VS_POL_QST_MASK GENMASK(17, 16) 134 + #define VS_POL_QST(x) UPDATE(x, 17, 16) 135 + #define VS_REMAPFILTER_EN_QST BIT(8) 136 + #define VS_FILTER_ORDER_QST_MASK GENMASK(1, 0) 137 + #define VS_FILTER_ORDER_QST(x) UPDATE(x, 1, 0) 138 + #define DEFRAMER_VSYNC_CNT_CLEAR 0x0278 139 + #define VSYNC_CNT_CLR_P BIT(0) 140 + #define DEFRAMER_STATUS 0x027c 141 + #define OPMODE_STS_MASK GENMASK(6, 4) 142 + #define I2C_SLAVE_CONFIG1 0x0164 143 + #define I2C_SDA_OUT_HOLD_VALUE_QST_MASK GENMASK(15, 8) 144 + #define I2C_SDA_OUT_HOLD_VALUE_QST(x) UPDATE(x, 15, 8) 145 + #define I2C_SDA_IN_HOLD_VALUE_QST_MASK GENMASK(7, 0) 146 + #define I2C_SDA_IN_HOLD_VALUE_QST(x) UPDATE(x, 7, 0) 147 + #define OPMODE_STS_MASK GENMASK(6, 4) 148 + #define REPEATER_QST BIT(28) 149 + #define FASTREAUTH_QST BIT(27) 150 + #define FEATURES_1DOT1_QST BIT(26) 151 + #define FASTI2C_QST BIT(25) 152 + #define EESS_CTL_THR_QST_MASK GENMASK(19, 16) 153 + #define EESS_CTL_THR_QST(x) UPDATE(x, 19, 16) 154 + #define OESS_CTL3_THR_QST_MASK GENMASK(11, 8) 155 + #define OESS_CTL3_THR_QST(x) UPDATE(x, 11, 8) 156 + #define EESS_OESS_SEL_QST_MASK GENMASK(5, 4) 157 + #define EESS_OESS_SEL_QST(x) UPDATE(x, 5, 4) 158 + #define KEY_DECRYPT_EN_QST BIT(0) 159 + #define KEY_DECRYPT_SEED_QST_MASK GENMASK(15, 0) 160 + #define KEY_DECRYPT_SEED_QST(x) UPDATE(x, 15, 0) 161 + #define HDCP_INT_CLEAR 0x50d8 162 + #define HDCP_1_INT_CLEAR 0x50e8 163 + #define HDCP2_CONFIG 0x02f0 164 + #define HDCP2_SWITCH_OVR_VALUE BIT(2) 165 + #define HDCP2_SWITCH_OVR_EN BIT(1) 166 + 167 + #define VIDEO_CONFIG2 0x042c 168 + #define VPROC_VSYNC_POL_OVR_VALUE BIT(19) 169 + #define VPROC_VSYNC_POL_OVR_EN BIT(18) 170 + #define VPROC_HSYNC_POL_OVR_VALUE BIT(17) 171 + #define VPROC_HSYNC_POL_OVR_EN BIT(16) 172 + #define VPROC_FMT_OVR_VALUE_MASK GENMASK(6, 4) 173 + #define VPROC_FMT_OVR_VALUE(x) UPDATE(x, 6, 4) 174 + #define VPROC_FMT_OVR_EN BIT(0) 175 + 176 + #define AFIFO_FILL_RESTART BIT(0) 177 + #define AFIFO_INIT_P BIT(0) 178 + #define AFIFO_THR_LOW_QST_MASK GENMASK(25, 16) 179 + #define AFIFO_THR_LOW_QST(x) UPDATE(x, 25, 16) 180 + #define AFIFO_THR_HIGH_QST_MASK GENMASK(9, 0) 181 + #define AFIFO_THR_HIGH_QST(x) UPDATE(x, 9, 0) 182 + #define AFIFO_THR_MUTE_LOW_QST_MASK GENMASK(25, 16) 183 + #define AFIFO_THR_MUTE_LOW_QST(x) UPDATE(x, 25, 16) 184 + #define AFIFO_THR_MUTE_HIGH_QST_MASK GENMASK(9, 0) 185 + #define AFIFO_THR_MUTE_HIGH_QST(x) UPDATE(x, 9, 0) 186 + 187 + #define AFIFO_UNDERFLOW_ST BIT(25) 188 + #define AFIFO_OVERFLOW_ST BIT(24) 189 + 190 + #define SPEAKER_ALLOC_OVR_EN BIT(16) 191 + #define I2S_BPCUV_EN BIT(4) 192 + #define SPDIF_EN BIT(2) 193 + #define I2S_EN BIT(1) 194 + #define AFIFO_THR_PASS_DEMUTEMASK_N BIT(24) 195 + #define AVMUTE_DEMUTEMASK_N BIT(16) 196 + #define AFIFO_THR_MUTE_LOW_MUTEMASK_N BIT(9) 197 + #define AFIFO_THR_MUTE_HIGH_MUTEMASK_N BIT(8) 198 + #define AVMUTE_MUTEMASK_N BIT(0) 199 + #define SCDC_CONFIG 0x0580 200 + #define HPDLOW BIT(1) 201 + #define POWERPROVIDED BIT(0) 202 + #define SCDC_REGBANK_STATUS1 0x058c 203 + #define SCDC_TMDSBITCLKRATIO BIT(1) 204 + #define SCDC_REGBANK_STATUS3 0x0594 205 + #define SCDC_REGBANK_CONFIG0 0x05c0 206 + #define SCDC_SINKVERSION_QST_MASK GENMASK(7, 0) 207 + #define SCDC_SINKVERSION_QST(x) UPDATE(x, 7, 0) 208 + #define AGEN_LAYOUT BIT(4) 209 + #define AGEN_SPEAKER_ALLOC GENMASK(15, 8) 210 + 211 + #define CED_CONFIG 0x0760 212 + #define CED_VIDDATACHECKEN_QST BIT(27) 213 + #define CED_DATAISCHECKEN_QST BIT(26) 214 + #define CED_GBCHECKEN_QST BIT(25) 215 + #define CED_CTRLCHECKEN_QST BIT(24) 216 + #define CED_CHLOCKMAXER_QST_MASK GENMASK(14, 0) 217 + #define CED_CHLOCKMAXER_QST(x) UPDATE(x, 14, 0) 218 + #define CED_DYN_CONFIG 0x0768 219 + #define CED_DYN_CONTROL 0x076c 220 + #define PKTEX_BCH_ERRFILT_CONFIG 0x07c4 221 + #define PKTEX_CHKSUM_ERRFILT_CONFIG 0x07c8 222 + 223 + #define PKTDEC_ACR_PH2_1 0x1100 224 + #define PKTDEC_ACR_PB3_0 0x1104 225 + #define PKTDEC_ACR_PB7_4 0x1108 226 + #define PKTDEC_AVIIF_PH2_1 0x1200 227 + #define PKTDEC_AVIIF_PB3_0 0x1204 228 + #define PKTDEC_AVIIF_PB7_4 0x1208 229 + #define VIC_VAL_MASK GENMASK(6, 0) 230 + #define PKTDEC_AVIIF_PB11_8 0x120c 231 + #define PKTDEC_AVIIF_PB15_12 0x1210 232 + #define PKTDEC_AVIIF_PB19_16 0x1214 233 + #define PKTDEC_AVIIF_PB23_20 0x1218 234 + #define PKTDEC_AVIIF_PB27_24 0x121c 235 + 236 + #define PKTFIFO_CONFIG 0x1500 237 + #define PKTFIFO_STORE_FILT_CONFIG 0x1504 238 + #define PKTFIFO_THR_CONFIG0 0x1508 239 + #define PKTFIFO_THR_CONFIG1 0x150c 240 + #define PKTFIFO_CONTROL 0x1510 241 + 242 + #define VMON_STATUS1 0x1580 243 + #define VMON_STATUS2 0x1584 244 + #define VMON_STATUS3 0x1588 245 + #define VMON_STATUS4 0x158c 246 + #define VMON_STATUS5 0x1590 247 + #define VMON_STATUS6 0x1594 248 + #define VMON_STATUS7 0x1598 249 + #define VMON_ILACE_DETECT BIT(4) 250 + 251 + #define CEC_TX_CONTROL 0x2000 252 + #define CEC_STATUS 0x2004 253 + #define CEC_CONFIG 0x2008 254 + #define RX_AUTO_DRIVE_ACKNOWLEDGE BIT(9) 255 + #define CEC_ADDR 0x200c 256 + #define CEC_TX_COUNT 0x2020 257 + #define CEC_TX_DATA3_0 0x2024 258 + #define CEC_RX_COUNT_STATUS 0x2040 259 + #define CEC_RX_DATA3_0 0x2044 260 + #define CEC_LOCK_CONTROL 0x2054 261 + #define CEC_RXQUAL_BITTIME_CONFIG 0x2060 262 + #define CEC_RX_BITTIME_CONFIG 0x2064 263 + #define CEC_TX_BITTIME_CONFIG 0x2068 264 + 265 + #define DMA_CONFIG1 0x4400 266 + #define UV_WID_MASK GENMASK(31, 28) 267 + #define UV_WID(x) UPDATE(x, 31, 28) 268 + #define Y_WID_MASK GENMASK(27, 24) 269 + #define Y_WID(x) UPDATE(x, 27, 24) 270 + #define DDR_STORE_FORMAT_MASK GENMASK(15, 12) 271 + #define DDR_STORE_FORMAT(x) UPDATE(x, 15, 12) 272 + #define ABANDON_EN BIT(0) 273 + #define DMA_CONFIG2 0x4404 274 + #define DMA_CONFIG3 0x4408 275 + #define DMA_CONFIG4 0x440c // dma irq en 276 + #define DMA_CONFIG5 0x4410 // dma irq clear status 277 + #define LINE_FLAG_INT_EN BIT(8) 278 + #define HDMIRX_DMA_IDLE_INT BIT(7) 279 + #define HDMIRX_LOCK_DISABLE_INT BIT(6) 280 + #define LAST_FRAME_AXI_UNFINISH_INT_EN BIT(5) 281 + #define FIFO_OVERFLOW_INT_EN BIT(2) 282 + #define FIFO_UNDERFLOW_INT_EN BIT(1) 283 + #define HDMIRX_AXI_ERROR_INT_EN BIT(0) 284 + #define DMA_CONFIG6 0x4414 285 + #define RB_SWAP_EN BIT(9) 286 + #define HSYNC_TOGGLE_EN BIT(5) 287 + #define VSYNC_TOGGLE_EN BIT(4) 288 + #define HDMIRX_DMA_EN BIT(1) 289 + #define DMA_CONFIG7 0x4418 290 + #define LINE_FLAG_NUM_MASK GENMASK(31, 16) 291 + #define LINE_FLAG_NUM(x) UPDATE(x, 31, 16) 292 + #define LOCK_FRAME_NUM_MASK GENMASK(11, 0) 293 + #define LOCK_FRAME_NUM(x) UPDATE(x, 11, 0) 294 + #define DMA_CONFIG8 0x441c 295 + #define REG_MIRROR_EN BIT(0) 296 + #define DMA_CONFIG9 0x4420 297 + #define DMA_CONFIG10 0x4424 298 + #define DMA_CONFIG11 0x4428 299 + #define EDID_READ_EN_MASK BIT(8) 300 + #define EDID_READ_EN(x) UPDATE(x, 8, 8) 301 + #define EDID_WRITE_EN_MASK BIT(7) 302 + #define EDID_WRITE_EN(x) UPDATE(x, 7, 7) 303 + #define EDID_SLAVE_ADDR_MASK GENMASK(6, 0) 304 + #define EDID_SLAVE_ADDR(x) UPDATE(x, 6, 0) 305 + #define DMA_STATUS1 0x4430 // dma irq status 306 + #define DMA_STATUS2 0x4434 307 + #define DMA_STATUS3 0x4438 308 + #define DMA_STATUS4 0x443c 309 + #define DMA_STATUS5 0x4440 310 + #define DMA_STATUS6 0x4444 311 + #define DMA_STATUS7 0x4448 312 + #define DMA_STATUS8 0x444c 313 + #define DMA_STATUS9 0x4450 314 + #define DMA_STATUS10 0x4454 315 + #define HDMIRX_LOCK BIT(3) 316 + #define DMA_STATUS11 0x4458 317 + #define HDMIRX_TYPE_MASK GENMASK(8, 7) 318 + #define HDMIRX_COLOR_DEPTH_MASK GENMASK(6, 3) 319 + #define HDMIRX_FORMAT_MASK GENMASK(2, 0) 320 + #define DMA_STATUS12 0x445c 321 + #define DMA_STATUS13 0x4460 322 + #define DMA_STATUS14 0x4464 323 + 324 + #define MAINUNIT_INTVEC_INDEX 0x5000 325 + #define MAINUNIT_0_INT_STATUS 0x5010 326 + #define CECRX_NOTIFY_ERR BIT(12) 327 + #define CECRX_EOM BIT(11) 328 + #define CECTX_DRIVE_ERR BIT(10) 329 + #define CECRX_BUSY BIT(9) 330 + #define CECTX_BUSY BIT(8) 331 + #define CECTX_FRAME_DISCARDED BIT(5) 332 + #define CECTX_NRETRANSMIT_FAIL BIT(4) 333 + #define CECTX_LINE_ERR BIT(3) 334 + #define CECTX_ARBLOST BIT(2) 335 + #define CECTX_NACK BIT(1) 336 + #define CECTX_DONE BIT(0) 337 + #define MAINUNIT_0_INT_MASK_N 0x5014 338 + #define MAINUNIT_0_INT_CLEAR 0x5018 339 + #define MAINUNIT_0_INT_FORCE 0x501c 340 + #define TIMER_BASE_LOCKED_IRQ BIT(26) 341 + #define TMDSQPCLK_OFF_CHG BIT(5) 342 + #define TMDSQPCLK_LOCKED_CHG BIT(4) 343 + #define MAINUNIT_1_INT_STATUS 0x5020 344 + #define MAINUNIT_1_INT_MASK_N 0x5024 345 + #define MAINUNIT_1_INT_CLEAR 0x5028 346 + #define MAINUNIT_1_INT_FORCE 0x502c 347 + #define MAINUNIT_2_INT_STATUS 0x5030 348 + #define MAINUNIT_2_INT_MASK_N 0x5034 349 + #define MAINUNIT_2_INT_CLEAR 0x5038 350 + #define MAINUNIT_2_INT_FORCE 0x503c 351 + #define PHYCREG_CR_READ_DONE BIT(11) 352 + #define PHYCREG_CR_WRITE_DONE BIT(10) 353 + #define TMDSVALID_STABLE_CHG BIT(1) 354 + 355 + #define AVPUNIT_0_INT_STATUS 0x5040 356 + #define AVPUNIT_0_INT_MASK_N 0x5044 357 + #define AVPUNIT_0_INT_CLEAR 0x5048 358 + #define AVPUNIT_0_INT_FORCE 0x504c 359 + #define CED_DYN_CNT_CH2_IRQ BIT(22) 360 + #define CED_DYN_CNT_CH1_IRQ BIT(21) 361 + #define CED_DYN_CNT_CH0_IRQ BIT(20) 362 + #define AVPUNIT_1_INT_STATUS 0x5050 363 + #define DEFRAMER_VSYNC_THR_REACHED_IRQ BIT(1) 364 + #define AVPUNIT_1_INT_MASK_N 0x5054 365 + #define DEFRAMER_VSYNC_THR_REACHED_MASK_N BIT(1) 366 + #define DEFRAMER_VSYNC_MASK_N BIT(0) 367 + #define AVPUNIT_1_INT_CLEAR 0x5058 368 + #define DEFRAMER_VSYNC_THR_REACHED_CLEAR BIT(1) 369 + #define PKT_0_INT_STATUS 0x5080 370 + #define PKTDEC_ACR_CHG_IRQ BIT(3) 371 + #define PKT_0_INT_MASK_N 0x5084 372 + #define PKTDEC_ACR_CHG_MASK_N BIT(3) 373 + #define PKT_0_INT_CLEAR 0x5088 374 + #define PKT_1_INT_STATUS 0x5090 375 + #define PKT_1_INT_MASK_N 0x5094 376 + #define PKT_1_INT_CLEAR 0x5098 377 + #define PKT_2_INT_STATUS 0x50a0 378 + #define PKTDEC_ACR_RCV_IRQ BIT(3) 379 + #define PKT_2_INT_MASK_N 0x50a4 380 + #define PKTDEC_AVIIF_RCV_IRQ BIT(11) 381 + #define PKTDEC_ACR_RCV_MASK_N BIT(3) 382 + #define PKT_2_INT_CLEAR 0x50a8 383 + #define PKTDEC_AVIIF_RCV_CLEAR BIT(11) 384 + #define PKTDEC_ACR_RCV_CLEAR BIT(3) 385 + #define SCDC_INT_STATUS 0x50c0 386 + #define SCDC_INT_MASK_N 0x50c4 387 + #define SCDC_INT_CLEAR 0x50c8 388 + #define SCDCTMDSCCFG_CHG BIT(2) 389 + 390 + #define CEC_INT_STATUS 0x5100 391 + #define CEC_INT_MASK_N 0x5104 392 + #define CEC_INT_CLEAR 0x5108 393 + 394 + #endif
+275
drivers/media/platform/synopsys/hdmirx/snps_hdmirx_cec.c
··· 1 + // SPDX-License-Identifier: GPL-2.0 2 + /* 3 + * Copyright (c) 2021 Rockchip Electronics Co. Ltd. 4 + * 5 + * Author: Shunqing Chen <csq@rock-chips.com> 6 + */ 7 + 8 + #include <linux/interrupt.h> 9 + #include <linux/io.h> 10 + #include <linux/irq.h> 11 + #include <linux/module.h> 12 + #include <linux/platform_device.h> 13 + #include <linux/slab.h> 14 + 15 + #include <media/cec.h> 16 + 17 + #include "snps_hdmirx.h" 18 + #include "snps_hdmirx_cec.h" 19 + 20 + static void hdmirx_cec_write(struct hdmirx_cec *cec, int reg, u32 val) 21 + { 22 + cec->ops->write(cec->hdmirx, reg, val); 23 + } 24 + 25 + static u32 hdmirx_cec_read(struct hdmirx_cec *cec, int reg) 26 + { 27 + return cec->ops->read(cec->hdmirx, reg); 28 + } 29 + 30 + static void hdmirx_cec_update_bits(struct hdmirx_cec *cec, int reg, u32 mask, 31 + u32 data) 32 + { 33 + u32 val = hdmirx_cec_read(cec, reg) & ~mask; 34 + 35 + val |= (data & mask); 36 + hdmirx_cec_write(cec, reg, val); 37 + } 38 + 39 + static int hdmirx_cec_log_addr(struct cec_adapter *adap, u8 logical_addr) 40 + { 41 + struct hdmirx_cec *cec = cec_get_drvdata(adap); 42 + 43 + if (logical_addr == CEC_LOG_ADDR_INVALID) 44 + cec->addresses = 0; 45 + else 46 + cec->addresses |= BIT(logical_addr) | BIT(15); 47 + 48 + hdmirx_cec_write(cec, CEC_ADDR, cec->addresses); 49 + 50 + return 0; 51 + } 52 + 53 + /* signal_free_time is handled by the Synopsys Designware 54 + * HDMIRX Controller hardware. 55 + */ 56 + static int hdmirx_cec_transmit(struct cec_adapter *adap, u8 attempts, 57 + u32 signal_free_time, struct cec_msg *msg) 58 + { 59 + struct hdmirx_cec *cec = cec_get_drvdata(adap); 60 + u32 data[4] = {0}; 61 + int i, data_len, msg_len; 62 + 63 + msg_len = msg->len; 64 + 65 + hdmirx_cec_write(cec, CEC_TX_COUNT, msg_len - 1); 66 + for (i = 0; i < msg_len; i++) 67 + data[i / 4] |= msg->msg[i] << (i % 4) * 8; 68 + 69 + data_len = DIV_ROUND_UP(msg_len, 4); 70 + 71 + for (i = 0; i < data_len; i++) 72 + hdmirx_cec_write(cec, CEC_TX_DATA3_0 + i * 4, data[i]); 73 + 74 + hdmirx_cec_write(cec, CEC_TX_CONTROL, 0x1); 75 + 76 + return 0; 77 + } 78 + 79 + static irqreturn_t hdmirx_cec_hardirq(int irq, void *data) 80 + { 81 + struct cec_adapter *adap = data; 82 + struct hdmirx_cec *cec = cec_get_drvdata(adap); 83 + u32 stat = hdmirx_cec_read(cec, CEC_INT_STATUS); 84 + irqreturn_t ret = IRQ_HANDLED; 85 + u32 val; 86 + 87 + if (!stat) 88 + return IRQ_NONE; 89 + 90 + hdmirx_cec_write(cec, CEC_INT_CLEAR, stat); 91 + 92 + if (stat & CECTX_LINE_ERR) { 93 + cec->tx_status = CEC_TX_STATUS_ERROR; 94 + cec->tx_done = true; 95 + ret = IRQ_WAKE_THREAD; 96 + } else if (stat & CECTX_DONE) { 97 + cec->tx_status = CEC_TX_STATUS_OK; 98 + cec->tx_done = true; 99 + ret = IRQ_WAKE_THREAD; 100 + } else if (stat & CECTX_NACK) { 101 + cec->tx_status = CEC_TX_STATUS_NACK; 102 + cec->tx_done = true; 103 + ret = IRQ_WAKE_THREAD; 104 + } else if (stat & CECTX_ARBLOST) { 105 + cec->tx_status = CEC_TX_STATUS_ARB_LOST; 106 + cec->tx_done = true; 107 + ret = IRQ_WAKE_THREAD; 108 + } 109 + 110 + if (stat & CECRX_EOM) { 111 + unsigned int len, i; 112 + 113 + val = hdmirx_cec_read(cec, CEC_RX_COUNT_STATUS); 114 + /* rxbuffer locked status */ 115 + if ((val & 0x80)) 116 + return ret; 117 + 118 + len = (val & 0xf) + 1; 119 + if (len > sizeof(cec->rx_msg.msg)) 120 + len = sizeof(cec->rx_msg.msg); 121 + 122 + for (i = 0; i < len; i++) { 123 + if (!(i % 4)) 124 + val = hdmirx_cec_read(cec, CEC_RX_DATA3_0 + i / 4 * 4); 125 + cec->rx_msg.msg[i] = (val >> ((i % 4) * 8)) & 0xff; 126 + } 127 + 128 + cec->rx_msg.len = len; 129 + smp_wmb(); /* receive RX msg */ 130 + cec->rx_done = true; 131 + hdmirx_cec_write(cec, CEC_LOCK_CONTROL, 0x1); 132 + 133 + ret = IRQ_WAKE_THREAD; 134 + } 135 + 136 + return ret; 137 + } 138 + 139 + static irqreturn_t hdmirx_cec_thread(int irq, void *data) 140 + { 141 + struct cec_adapter *adap = data; 142 + struct hdmirx_cec *cec = cec_get_drvdata(adap); 143 + 144 + if (cec->tx_done) { 145 + cec->tx_done = false; 146 + cec_transmit_attempt_done(adap, cec->tx_status); 147 + } 148 + if (cec->rx_done) { 149 + cec->rx_done = false; 150 + smp_rmb(); /* RX msg has been received */ 151 + cec_received_msg(adap, &cec->rx_msg); 152 + } 153 + 154 + return IRQ_HANDLED; 155 + } 156 + 157 + static int hdmirx_cec_enable(struct cec_adapter *adap, bool enable) 158 + { 159 + struct hdmirx_cec *cec = cec_get_drvdata(adap); 160 + 161 + if (!enable) { 162 + hdmirx_cec_write(cec, CEC_INT_MASK_N, 0); 163 + hdmirx_cec_write(cec, CEC_INT_CLEAR, 0); 164 + if (cec->ops->disable) 165 + cec->ops->disable(cec->hdmirx); 166 + } else { 167 + unsigned int irqs; 168 + 169 + hdmirx_cec_log_addr(cec->adap, CEC_LOG_ADDR_INVALID); 170 + if (cec->ops->enable) 171 + cec->ops->enable(cec->hdmirx); 172 + hdmirx_cec_update_bits(cec, GLOBAL_SWENABLE, CEC_ENABLE, CEC_ENABLE); 173 + 174 + irqs = CECTX_LINE_ERR | CECTX_NACK | CECRX_EOM | CECTX_DONE; 175 + hdmirx_cec_write(cec, CEC_INT_MASK_N, irqs); 176 + } 177 + 178 + return 0; 179 + } 180 + 181 + static const struct cec_adap_ops hdmirx_cec_ops = { 182 + .adap_enable = hdmirx_cec_enable, 183 + .adap_log_addr = hdmirx_cec_log_addr, 184 + .adap_transmit = hdmirx_cec_transmit, 185 + }; 186 + 187 + static void hdmirx_cec_del(void *data) 188 + { 189 + struct hdmirx_cec *cec = data; 190 + 191 + cec_delete_adapter(cec->adap); 192 + } 193 + 194 + struct hdmirx_cec *snps_hdmirx_cec_register(struct hdmirx_cec_data *data) 195 + { 196 + struct hdmirx_cec *cec; 197 + unsigned int irqs; 198 + int ret; 199 + 200 + /* 201 + * Our device is just a convenience - we want to link to the real 202 + * hardware device here, so that userspace can see the association 203 + * between the HDMI hardware and its associated CEC chardev. 204 + */ 205 + cec = devm_kzalloc(data->dev, sizeof(*cec), GFP_KERNEL); 206 + if (!cec) 207 + return ERR_PTR(-ENOMEM); 208 + 209 + cec->dev = data->dev; 210 + cec->irq = data->irq; 211 + cec->ops = data->ops; 212 + cec->hdmirx = data->hdmirx; 213 + 214 + hdmirx_cec_update_bits(cec, GLOBAL_SWENABLE, CEC_ENABLE, CEC_ENABLE); 215 + hdmirx_cec_update_bits(cec, CEC_CONFIG, RX_AUTO_DRIVE_ACKNOWLEDGE, 216 + RX_AUTO_DRIVE_ACKNOWLEDGE); 217 + 218 + hdmirx_cec_write(cec, CEC_TX_COUNT, 0); 219 + hdmirx_cec_write(cec, CEC_INT_MASK_N, 0); 220 + hdmirx_cec_write(cec, CEC_INT_CLEAR, ~0); 221 + 222 + cec->adap = cec_allocate_adapter(&hdmirx_cec_ops, cec, "snps-hdmirx", 223 + CEC_CAP_DEFAULTS | CEC_CAP_MONITOR_ALL, 224 + CEC_MAX_LOG_ADDRS); 225 + if (IS_ERR(cec->adap)) { 226 + dev_err(cec->dev, "cec adapter allocation failed\n"); 227 + return ERR_CAST(cec->adap); 228 + } 229 + 230 + /* override the module pointer */ 231 + cec->adap->owner = THIS_MODULE; 232 + 233 + ret = devm_add_action(cec->dev, hdmirx_cec_del, cec); 234 + if (ret) { 235 + cec_delete_adapter(cec->adap); 236 + return ERR_PTR(ret); 237 + } 238 + 239 + irq_set_status_flags(cec->irq, IRQ_NOAUTOEN); 240 + 241 + ret = devm_request_threaded_irq(cec->dev, cec->irq, 242 + hdmirx_cec_hardirq, 243 + hdmirx_cec_thread, IRQF_ONESHOT, 244 + "rk_hdmirx_cec", cec->adap); 245 + if (ret) { 246 + dev_err(cec->dev, "cec irq request failed\n"); 247 + return ERR_PTR(ret); 248 + } 249 + 250 + ret = cec_register_adapter(cec->adap, cec->dev); 251 + if (ret < 0) { 252 + dev_err(cec->dev, "cec adapter registration failed\n"); 253 + return ERR_PTR(ret); 254 + } 255 + 256 + irqs = CECTX_LINE_ERR | CECTX_NACK | CECRX_EOM | CECTX_DONE; 257 + hdmirx_cec_write(cec, CEC_INT_MASK_N, irqs); 258 + 259 + /* 260 + * CEC documentation says we must not call cec_delete_adapter 261 + * after a successful call to cec_register_adapter(). 262 + */ 263 + devm_remove_action(cec->dev, hdmirx_cec_del, cec); 264 + 265 + enable_irq(cec->irq); 266 + 267 + return cec; 268 + } 269 + 270 + void snps_hdmirx_cec_unregister(struct hdmirx_cec *cec) 271 + { 272 + disable_irq(cec->irq); 273 + 274 + cec_unregister_adapter(cec->adap); 275 + }
+43
drivers/media/platform/synopsys/hdmirx/snps_hdmirx_cec.h
··· 1 + /* SPDX-License-Identifier: GPL-2.0 */ 2 + /* 3 + * Copyright (c) 2021 Rockchip Electronics Co. Ltd. 4 + * 5 + * Author: Shunqing Chen <csq@rock-chips.com> 6 + */ 7 + 8 + #ifndef DW_HDMI_RX_CEC_H 9 + #define DW_HDMI_RX_CEC_H 10 + 11 + struct snps_hdmirx_dev; 12 + 13 + struct hdmirx_cec_ops { 14 + void (*write)(struct snps_hdmirx_dev *hdmirx_dev, int reg, u32 val); 15 + u32 (*read)(struct snps_hdmirx_dev *hdmirx_dev, int reg); 16 + void (*enable)(struct snps_hdmirx_dev *hdmirx); 17 + void (*disable)(struct snps_hdmirx_dev *hdmirx); 18 + }; 19 + 20 + struct hdmirx_cec_data { 21 + struct snps_hdmirx_dev *hdmirx; 22 + const struct hdmirx_cec_ops *ops; 23 + struct device *dev; 24 + int irq; 25 + }; 26 + 27 + struct hdmirx_cec { 28 + struct snps_hdmirx_dev *hdmirx; 29 + struct device *dev; 30 + const struct hdmirx_cec_ops *ops; 31 + u32 addresses; 32 + struct cec_adapter *adap; 33 + struct cec_msg rx_msg; 34 + unsigned int tx_status; 35 + bool tx_done; 36 + bool rx_done; 37 + int irq; 38 + }; 39 + 40 + struct hdmirx_cec *snps_hdmirx_cec_register(struct hdmirx_cec_data *data); 41 + void snps_hdmirx_cec_unregister(struct hdmirx_cec *cec); 42 + 43 + #endif /* DW_HDMI_RX_CEC_H */