summaryrefslogtreecommitdiffstats
path: root/bsp/meta-rcar/meta-rcar-gen3-adas/recipes-kernel/linux
diff options
context:
space:
mode:
authorToshikazuOhiwa <toshikazu_ohiwa@mail.toyota.co.jp>2020-03-30 09:24:26 +0900
committerToshikazuOhiwa <toshikazu_ohiwa@mail.toyota.co.jp>2020-03-30 09:24:26 +0900
commit5b80bfd7bffd4c20d80b7c70a7130529e9a755dd (patch)
treeb4bb18dcd1487dbf1ea8127e5671b7bb2eded033 /bsp/meta-rcar/meta-rcar-gen3-adas/recipes-kernel/linux
parent706ad73eb02caf8532deaf5d38995bd258725cb8 (diff)
agl-basesystem
Diffstat (limited to 'bsp/meta-rcar/meta-rcar-gen3-adas/recipes-kernel/linux')
-rw-r--r--bsp/meta-rcar/meta-rcar-gen3-adas/recipes-kernel/linux/linux-renesas/0001-spi-sh-msiof-fixes.patch33
-rw-r--r--bsp/meta-rcar/meta-rcar-gen3-adas/recipes-kernel/linux/linux-renesas/0002-spi-spidev-add-spi-gpio-into-spidev.patch27
-rw-r--r--bsp/meta-rcar/meta-rcar-gen3-adas/recipes-kernel/linux/linux-renesas/0003-spi-spi-gpio-fix-CPOL-mode.patch42
-rw-r--r--bsp/meta-rcar/meta-rcar-gen3-adas/recipes-kernel/linux/linux-renesas/0006-spi-spi-gpio-fix-set-CPOL-default-inverted.patch30
-rw-r--r--bsp/meta-rcar/meta-rcar-gen3-adas/recipes-kernel/linux/linux-renesas/0008-Revert-PCI-rcar-pcie-Add-bus-notifier-so-we-can-limi.patch59
-rw-r--r--bsp/meta-rcar/meta-rcar-gen3-adas/recipes-kernel/linux/linux-renesas/0009-arm64-dma-check-parent-bus-restrictions-in-dma_capab.patch94
-rw-r--r--bsp/meta-rcar/meta-rcar-gen3-adas/recipes-kernel/linux/linux-renesas/0010-can-rcar_can-add-enable-and-standby-control-pins.patch156
-rw-r--r--bsp/meta-rcar/meta-rcar-gen3-adas/recipes-kernel/linux/linux-renesas/0011-can-rcar_canfd-add-enable-and-standby-control-pins.patch119
-rw-r--r--bsp/meta-rcar/meta-rcar-gen3-adas/recipes-kernel/linux/linux-renesas/0012-mtd-Add-RPC-HyperFlash-driver.patch1028
-rw-r--r--bsp/meta-rcar/meta-rcar-gen3-adas/recipes-kernel/linux/linux-renesas/0013-IMR-driver-interim-patch.patch2002
-rw-r--r--bsp/meta-rcar/meta-rcar-gen3-adas/recipes-kernel/linux/linux-renesas/0014-lib-swiotlb-reduce-verbosity.patch40
-rw-r--r--bsp/meta-rcar/meta-rcar-gen3-adas/recipes-kernel/linux/linux-renesas/0015-gpio-max732x-fix-gpio-set.patch29
-rw-r--r--bsp/meta-rcar/meta-rcar-gen3-adas/recipes-kernel/linux/linux-renesas/0016-gpio-gpiolib-suppress-gpiod-warning.patch29
-rw-r--r--bsp/meta-rcar/meta-rcar-gen3-adas/recipes-kernel/linux/linux-renesas/0017-media-soc_camera-add-legacy-VIN-CSI2.patch5162
-rw-r--r--bsp/meta-rcar/meta-rcar-gen3-adas/recipes-kernel/linux/linux-renesas/0018-arm64-renesas-r8a7797-Add-Renesas-R8A7797-SoC-suppor.patch5340
-rw-r--r--bsp/meta-rcar/meta-rcar-gen3-adas/recipes-kernel/linux/linux-renesas/0019-Revert-media-v4l2-async-remove-unneeded-.registered_.patch51
-rw-r--r--bsp/meta-rcar/meta-rcar-gen3-adas/recipes-kernel/linux/linux-renesas/0020-ti-st-add-device-tree-support.patch236
-rw-r--r--bsp/meta-rcar/meta-rcar-gen3-adas/recipes-kernel/linux/linux-renesas/0021-btwilink-add-minimal-device-tree-support.patch54
-rw-r--r--bsp/meta-rcar/meta-rcar-gen3-adas/recipes-kernel/linux/linux-renesas/0022-ASoC-Modify-check-condition-of-multiple-bindings-of-.patch49
-rw-r--r--bsp/meta-rcar/meta-rcar-gen3-adas/recipes-kernel/linux/linux-renesas/0023-ASoC-add-dummy-Si468x-driver.patch122
-rw-r--r--bsp/meta-rcar/meta-rcar-gen3-adas/recipes-kernel/linux/linux-renesas/0024-wl18xx-do-not-invert-IRQ-on-WLxxxx-side.patch47
-rw-r--r--bsp/meta-rcar/meta-rcar-gen3-adas/recipes-kernel/linux/linux-renesas/0025-drm-adv7511-Enable-HPD-interrupts-to-support-hotplug.patch29
-rw-r--r--bsp/meta-rcar/meta-rcar-gen3-adas/recipes-kernel/linux/linux-renesas/0026-drm-adv7511-add-polling-mode-when-no-irq-available.patch30
-rw-r--r--bsp/meta-rcar/meta-rcar-gen3-adas/recipes-kernel/linux/linux-renesas/0027-gpu-drm-bridge-adv7511-Add-interlaced-mode-support.patch44
-rw-r--r--bsp/meta-rcar/meta-rcar-gen3-adas/recipes-kernel/linux/linux-renesas/0030-Gen3-LVDS-cameras.patch11563
-rw-r--r--bsp/meta-rcar/meta-rcar-gen3-adas/recipes-kernel/linux/linux-renesas/0031-media-i2c-Add-ov5647-sensor.patch951
-rw-r--r--bsp/meta-rcar/meta-rcar-gen3-adas/recipes-kernel/linux/linux-renesas/0032-media-i2c-Add-ov5642-sensor.patch2155
-rw-r--r--bsp/meta-rcar/meta-rcar-gen3-adas/recipes-kernel/linux/linux-renesas/0033-media-soc-camera-fix-parallel-i-f-in-VIN.patch69
-rw-r--r--bsp/meta-rcar/meta-rcar-gen3-adas/recipes-kernel/linux/linux-renesas/0034-media-soc_camera-Fix-VIDIOC_S_SELECTION-ioctl-miscal.patch50
-rw-r--r--bsp/meta-rcar/meta-rcar-gen3-adas/recipes-kernel/linux/linux-renesas/0036-Add-MOST-support-for-r8a77965.patch100
-rw-r--r--bsp/meta-rcar/meta-rcar-gen3-adas/recipes-kernel/linux/linux-renesas/0037-media-soc_camera-rcar_vin-Fix-VnCSI_IFMD-settings.patch98
-rw-r--r--bsp/meta-rcar/meta-rcar-gen3-adas/recipes-kernel/linux/linux-renesas/0038-media-soc_camera-rcar_vin-Add-R-Car-M3N-support.patch236
-rw-r--r--bsp/meta-rcar/meta-rcar-gen3-adas/recipes-kernel/linux/linux-renesas/0039-media-soc_camera-rcar_csi2-Add-R-Car-M3N-support.patch49
-rw-r--r--bsp/meta-rcar/meta-rcar-gen3-adas/recipes-kernel/linux/linux-renesas/0040-arm64-dts-renesas-add-ADAS-boards.patch13885
-rw-r--r--bsp/meta-rcar/meta-rcar-gen3-adas/recipes-kernel/linux/linux-renesas/0041-arm64-dts-renesas-ulcb-kf-Move-panel-configuration-t.patch125
-rw-r--r--bsp/meta-rcar/meta-rcar-gen3-adas/recipes-kernel/linux/linux-renesas/0042-arm64-dts-renesas-r8a7795-es1-h3ulcb-disable-eMMC.patch27
-rw-r--r--bsp/meta-rcar/meta-rcar-gen3-adas/recipes-kernel/linux/linux-renesas/0043-pinctrl-sh-pfc-pfc-r8a77965-Add-missing-avb_mii-pin-.patch154
-rw-r--r--bsp/meta-rcar/meta-rcar-gen3-adas/recipes-kernel/linux/linux-renesas/0045-clk-r8a779x-add-mlp-clock.patch38
-rw-r--r--bsp/meta-rcar/meta-rcar-gen3-adas/recipes-kernel/linux/linux-renesas/0046-arm64-dts-renesas-r8a779x-add-mlp-nodes.patch62
-rw-r--r--bsp/meta-rcar/meta-rcar-gen3-adas/recipes-kernel/linux/linux-renesas/0047-arm64-dts-renesas-ulcb-kf-enable-sd3.patch28
-rw-r--r--bsp/meta-rcar/meta-rcar-gen3-adas/recipes-kernel/linux/linux-renesas/0048-arm64-dts-renesas-ulcb-kf-enable-most.patch28
-rw-r--r--bsp/meta-rcar/meta-rcar-gen3-adas/recipes-kernel/linux/linux-renesas/0049-clk-r8a779x-add-IMP-clock.patch40
-rw-r--r--bsp/meta-rcar/meta-rcar-gen3-adas/recipes-kernel/linux/linux-renesas/0050-arm64-dts-renesas-r8a779x-add-IMP-nodes.patch198
-rw-r--r--bsp/meta-rcar/meta-rcar-gen3-adas/recipes-kernel/linux/linux-renesas/0051-arm64-renesas-r8a7798-Add-Renesas-R8A7798-SoC-suppor.patch6490
-rw-r--r--bsp/meta-rcar/meta-rcar-gen3-adas/recipes-kernel/linux/linux-renesas/0052-soc-renesas-rcar-sysc-Add-workaround-for-A3-PD-issue.patch278
-rw-r--r--bsp/meta-rcar/meta-rcar-gen3-adas/recipes-kernel/linux/linux-renesas/0062-IIO-lsm9ds0-add-IMU-driver.patch958
-rw-r--r--bsp/meta-rcar/meta-rcar-gen3-adas/recipes-kernel/linux/linux-renesas/0063-ASoC-PCM3168A-add-TDM-modes-merge-ADC-and-DAC.patch474
-rw-r--r--bsp/meta-rcar/meta-rcar-gen3-adas/recipes-kernel/linux/linux-renesas/0064-drm-bridge-adv7511-Add-frequency-and-vrefresh-limita.patch96
-rw-r--r--bsp/meta-rcar/meta-rcar-gen3-adas/recipes-kernel/linux/linux-renesas/0066-pci-pcie-rcar-add-regulators-support.patch100
-rw-r--r--bsp/meta-rcar/meta-rcar-gen3-adas/recipes-kernel/linux/linux-renesas/0067-ti-st-use-proper-way-to-get-shutdown-gpio.patch61
-rw-r--r--bsp/meta-rcar/meta-rcar-gen3-adas/recipes-kernel/linux/linux-renesas/0068-drm-adv7511-use-smbus-to-retrieve-edid.patch53
-rw-r--r--bsp/meta-rcar/meta-rcar-gen3-adas/recipes-kernel/linux/linux-renesas/0071-ASoC-add-dummy-device-for-WL18xx-PCM-audio.patch128
-rw-r--r--bsp/meta-rcar/meta-rcar-gen3-adas/recipes-kernel/linux/linux-renesas/0072-usb-hub-disable-autosuspend-for-SMSC-hubs.patch51
-rw-r--r--bsp/meta-rcar/meta-rcar-gen3-adas/recipes-kernel/linux/linux-renesas/0073-MOST-dim2-add-device-tree-support.patch169
-rw-r--r--bsp/meta-rcar/meta-rcar-gen3-adas/recipes-kernel/linux/linux-renesas/0074-MOST-dim2-add-R-Car3-related-initialization.patch63
-rw-r--r--bsp/meta-rcar/meta-rcar-gen3-adas/recipes-kernel/linux/linux-renesas/0075-MOST-core-fix-memory-allocation-at-arm64.patch54
-rw-r--r--bsp/meta-rcar/meta-rcar-gen3-adas/recipes-kernel/linux/linux-renesas/0076-MOST-dim2-Renesas-R-Car3-variant.patch120
-rw-r--r--bsp/meta-rcar/meta-rcar-gen3-adas/recipes-kernel/linux/linux-renesas/0077-MOST-dim2-add-timeouts.patch46
-rw-r--r--bsp/meta-rcar/meta-rcar-gen3-adas/recipes-kernel/linux/linux-renesas/0078-MOST-aim-fix-null-pointer-crash.patch29
-rw-r--r--bsp/meta-rcar/meta-rcar-gen3-adas/recipes-kernel/linux/linux-renesas/0079-Revert-dmaengine-rcar-dmac-use-TCRB-instead-of-TCR-f.patch31
-rw-r--r--bsp/meta-rcar/meta-rcar-gen3-adas/recipes-kernel/linux/linux-renesas/0082-gpio-pca953x-fix-interrupt-trigger.patch28
-rw-r--r--bsp/meta-rcar/meta-rcar-gen3-adas/recipes-kernel/linux/linux-renesas/0090-ASoC-rsnd-fixup-rsnd_ssi_master_clk_start-user-count.patch41
-rw-r--r--bsp/meta-rcar/meta-rcar-gen3-adas/recipes-kernel/linux/linux-renesas/0100-LVDS-ar0132-use-raw12.patch152
-rw-r--r--bsp/meta-rcar/meta-rcar-gen3-adas/recipes-kernel/linux/linux-renesas/0101-LVDS-ar0132-use-context-swwitch.patch119
-rw-r--r--bsp/meta-rcar/meta-rcar-gen3-adas/recipes-kernel/linux/linux-renesas/0103-gpu-drm-rcar-du-Extend-VSP1-DRM-interface.patch546
-rw-r--r--bsp/meta-rcar/meta-rcar-gen3-adas/recipes-kernel/linux/linux-renesas/0104-media-vsp1-extend-DRM-VSP1-interface.patch367
-rw-r--r--bsp/meta-rcar/meta-rcar-gen3-adas/recipes-kernel/linux/linux-renesas/0105-media-rcar-imr-IMR-driver-updates-for-raw-DL.patch538
-rw-r--r--bsp/meta-rcar/meta-rcar-gen3-adas/recipes-kernel/linux/linux-renesas/0106-media-rcar-imr-Add-RSE-support.patch327
-rw-r--r--bsp/meta-rcar/meta-rcar-gen3-adas/recipes-kernel/linux/linux-renesas/0109-serial-sh-sci-Fix-minimal-rx_timeout-value.patch34
-rw-r--r--bsp/meta-rcar/meta-rcar-gen3-adas/recipes-kernel/linux/linux-renesas/0110-mmc-tmio-Add-SDHI-SEQUENCER-support.patch295
-rw-r--r--bsp/meta-rcar/meta-rcar-gen3-adas/recipes-kernel/linux/linux-renesas/0111-mmc-renesas_sdhi-Add-SDHI-SEQUENCER-support.patch747
-rw-r--r--bsp/meta-rcar/meta-rcar-gen3-adas/recipes-kernel/linux/linux-renesas/0112-ARM64-dts-renesas-ulcb-Make-AK4613-sound-device-name.patch34
-rw-r--r--bsp/meta-rcar/meta-rcar-gen3-adas/recipes-kernel/linux/linux-renesas/0113-arm64-dts-ulcb-kf-increase-SDIO-frequency-for-WLAN-c.patch32
-rw-r--r--bsp/meta-rcar/meta-rcar-gen3-adas/recipes-kernel/linux/linux-renesas/0114-Sony-IMX219-driver.patch1115
-rw-r--r--bsp/meta-rcar/meta-rcar-gen3-adas/recipes-kernel/linux/linux-renesas/0115-arm64-dts-renesas-ulcb-kf-enable-enable-IMX219.patch95
-rw-r--r--bsp/meta-rcar/meta-rcar-gen3-adas/recipes-kernel/linux/linux-renesas/0116-media-i2c-soc_camera-Fix-Bad-of_node_put-error.patch250
-rw-r--r--bsp/meta-rcar/meta-rcar-gen3-adas/recipes-kernel/linux/linux-renesas/0117-rcar-vin-fix-get_selection-use.patch48
-rw-r--r--bsp/meta-rcar/meta-rcar-gen3-adas/recipes-kernel/linux/linux-renesas/0118-clk-clk-gpio-Allow-GPIO-to-sleep-in-set-get_parent.patch43
-rw-r--r--bsp/meta-rcar/meta-rcar-gen3-adas/recipes-kernel/linux/linux-renesas/0119-i2c-mix-pca954x-reset-mux-in-case-of-error-during-bu.patch102
-rw-r--r--bsp/meta-rcar/meta-rcar-gen3-adas/recipes-kernel/linux/linux-renesas/0120-arm64-dts-ulcb-kf-pcm3168a-reset-earlier-i2c-mux-dis.patch82
-rw-r--r--bsp/meta-rcar/meta-rcar-gen3-adas/recipes-kernel/linux/linux-renesas/0121-arm64-dts-renesas-ulcb-kf-Set-KOE-TX31D200VM0BAA-128.patch64
-rw-r--r--bsp/meta-rcar/meta-rcar-gen3-adas/recipes-kernel/linux/linux-renesas/0121-arm64-dts-renesas-ulcb-kf-Set-Mitsubishi-AA104XD12-1.patch64
-rw-r--r--bsp/meta-rcar/meta-rcar-gen3-adas/recipes-kernel/linux/linux-renesas/0121-arm64-dts-renesas-ulcb-kf-Set-Mitsubishi-AA121TD01-1.patch71
-rw-r--r--bsp/meta-rcar/meta-rcar-gen3-adas/recipes-kernel/linux/linux-renesas/0122-block-blk-mq-Fix-IO-hang.patch78
-rw-r--r--bsp/meta-rcar/meta-rcar-gen3-adas/recipes-kernel/linux/linux-renesas/0123-nvme-Workaround-Samsung-970-Pro-power-state-issues.patch33
-rw-r--r--bsp/meta-rcar/meta-rcar-gen3-adas/recipes-kernel/linux/linux-renesas/0124-nvme-pci-add-SGL-support.patch393
-rw-r--r--bsp/meta-rcar/meta-rcar-gen3-adas/recipes-kernel/linux/linux-renesas/0125-nvme-pci-don-t-open-code-nvme_reset_ctrl.patch36
-rw-r--r--bsp/meta-rcar/meta-rcar-gen3-adas/recipes-kernel/linux/linux-renesas/0126-nvme-pci-limit-max-IO-size-and-segments-to-avoid-hig.patch164
-rw-r--r--bsp/meta-rcar/meta-rcar-gen3-adas/recipes-kernel/linux/linux-renesas/0127-swiotlb-Respect-DMA_ATTR_NO_WARN-in-swiotlb_map_sg_a.patch33
-rw-r--r--bsp/meta-rcar/meta-rcar-gen3-adas/recipes-kernel/linux/linux-renesas/0128-arm64-dts-Add-H3ULCB-VideoBox-2.1-support.patch292
-rw-r--r--bsp/meta-rcar/meta-rcar-gen3-adas/recipes-kernel/linux/linux-renesas/0129-can-rcar_canfd-fix-possible-IRQ-storm-on-high-load.patch63
-rw-r--r--bsp/meta-rcar/meta-rcar-gen3-adas/recipes-kernel/linux/linux-renesas/0130-LVDS-ar0132-use-context-swwitch.patch119
-rw-r--r--bsp/meta-rcar/meta-rcar-gen3-adas/recipes-kernel/linux/linux-renesas/0131-media-i2c-soc_camera-Bunch-update-from-2.23.1.patch13431
-rw-r--r--bsp/meta-rcar/meta-rcar-gen3-adas/recipes-kernel/linux/linux-renesas/0132-lvds-ti960-fix-frame-sync-time-for-different-ref-clo.patch85
-rw-r--r--bsp/meta-rcar/meta-rcar-gen3-adas/recipes-kernel/linux/linux-renesas/0133-lvds-add-AR0323-imager.patch1998
-rw-r--r--bsp/meta-rcar/meta-rcar-gen3-adas/recipes-kernel/linux/linux-renesas/0134-lvds-add-ISX016-imager.patch729
-rw-r--r--bsp/meta-rcar/meta-rcar-gen3-adas/recipes-kernel/linux/linux-renesas/0135-LVDS-ar0233-set-frame-size-1920x1200.patch104
-rw-r--r--bsp/meta-rcar/meta-rcar-gen3-adas/recipes-kernel/linux/linux-renesas/0136-lvds-AR0233-add-different-vendor.patch258
-rw-r--r--bsp/meta-rcar/meta-rcar-gen3-adas/recipes-kernel/linux/linux-renesas/0137-lvds-poll-ub960-deserializer-lock-status.patch70
-rw-r--r--bsp/meta-rcar/meta-rcar-gen3-adas/recipes-kernel/linux/linux-renesas/0138-lvds-AR0231-modify-with-rev7-silicon.patch633
-rw-r--r--bsp/meta-rcar/meta-rcar-gen3-adas/recipes-kernel/linux/linux-renesas/0139-lvds-AR0233-modify-with-rev2-silicon.patch1349
-rw-r--r--bsp/meta-rcar/meta-rcar-gen3-adas/recipes-kernel/linux/linux-renesas/0140-lvds-ti9x4-fix-remote-gpio-enablement-for-4-cams.patch81
-rw-r--r--bsp/meta-rcar/meta-rcar-gen3-adas/recipes-kernel/linux/linux-renesas/0141-media-soc_camera-imx390-Add-new-V4L-controls.patch122
-rw-r--r--bsp/meta-rcar/meta-rcar-gen3-adas/recipes-kernel/linux/linux-renesas/0142-lvds-AR233-add-rev1-silion-setup.patch1788
-rw-r--r--bsp/meta-rcar/meta-rcar-gen3-adas/recipes-kernel/linux/linux-renesas/0143-LVDS-AR0231-add-rev6-rev4-on-max9286.patch663
-rw-r--r--bsp/meta-rcar/meta-rcar-gen3-adas/recipes-kernel/linux/linux-renesas/0144-lvds-add-OV10640-imager.patch3174
-rw-r--r--bsp/meta-rcar/meta-rcar-gen3-adas/recipes-kernel/linux/linux-renesas/0145-lvds-ti9x4-fix-remote-gpio-enablement-on-UB913.patch37
-rw-r--r--bsp/meta-rcar/meta-rcar-gen3-adas/recipes-kernel/linux/linux-renesas/0146-lvds-add-dummy-imager-driver.patch350
-rw-r--r--bsp/meta-rcar/meta-rcar-gen3-adas/recipes-kernel/linux/linux-renesas/0147-lvds-ti9x4-use-REFCLK-23.0MHz.patch39
-rw-r--r--bsp/meta-rcar/meta-rcar-gen3-adas/recipes-kernel/linux/linux-renesas/0148-lvds-ar0231-fix-comments.patch48
-rw-r--r--bsp/meta-rcar/meta-rcar-gen3-adas/recipes-kernel/linux/linux-renesas/0149-lvds-ISX019-rename-isx016-to-isx019.patch1402
-rw-r--r--bsp/meta-rcar/meta-rcar-gen3-adas/recipes-kernel/linux/linux-renesas/0150-lvds-add-ISX016-imager.patch705
-rw-r--r--bsp/meta-rcar/meta-rcar-gen3-adas/recipes-kernel/linux/linux-renesas/0151-lvds-ti9x4-add-DVP-LSB-MSB-selection.patch67
-rw-r--r--bsp/meta-rcar/meta-rcar-gen3-adas/recipes-kernel/linux/linux-renesas/0152-lvds-AR323-fix-reset-gpio-nadling.patch145
-rw-r--r--bsp/meta-rcar/meta-rcar-gen3-adas/recipes-kernel/linux/linux-renesas/0153-lvds-OV495-fix-reset-gpio-handling.patch65
-rw-r--r--bsp/meta-rcar/meta-rcar-gen3-adas/recipes-kernel/linux/linux-renesas/0154-lvds-AR0323-replace-with-REV2-setup-table.patch2888
-rw-r--r--bsp/meta-rcar/meta-rcar-gen3-adas/recipes-kernel/linux/linux-renesas/0155-AR0143-add-original-ONSEMI-setup.patch1552
-rw-r--r--bsp/meta-rcar/meta-rcar-gen3-adas/recipes-kernel/linux/linux-renesas/0156-AR0143-enable-3exp-in-custom-setup.patch61
-rw-r--r--bsp/meta-rcar/meta-rcar-gen3-adas/recipes-kernel/linux/linux-renesas/0157-AR0143-add-choose-of-imager-setup.patch132
-rw-r--r--bsp/meta-rcar/meta-rcar-gen3-adas/recipes-kernel/linux/linux-renesas/0158-MAX9286-fix-BWS-setup-to-reserve-reboot.patch85
-rw-r--r--bsp/meta-rcar/meta-rcar-gen3-adas/recipes-kernel/linux/linux-renesas/0159-MAX9286-adjust-POC-trigger-for-unstable-link.patch88
-rw-r--r--bsp/meta-rcar/meta-rcar-gen3-adas/recipes-kernel/linux/linux-renesas/0160-lvds-onsemi-fix-revsion-parsing.patch89
-rw-r--r--bsp/meta-rcar/meta-rcar-gen3-adas/recipes-kernel/linux/linux-renesas/0161-lvds-AR0233-add-module-trigger-parameter.patch116
-rw-r--r--bsp/meta-rcar/meta-rcar-gen3-adas/recipes-kernel/linux/linux-renesas/0162-lvds-AR0233-migrate-to-composed-tables.patch539
-rw-r--r--bsp/meta-rcar/meta-rcar-gen3-adas/recipes-kernel/linux/linux-renesas/0163-lvds-AP0101-AR014X-add-TI-serializers.patch76
-rw-r--r--bsp/meta-rcar/meta-rcar-gen3-adas/recipes-kernel/linux/linux-renesas/0164-lvds-fix-vendor-names.patch125
-rw-r--r--bsp/meta-rcar/meta-rcar-gen3-adas/recipes-kernel/linux/linux-renesas/0165-LVDS-add-GW5200-IMX390-camera.patch673
-rw-r--r--bsp/meta-rcar/meta-rcar-gen3-adas/recipes-kernel/linux/linux-renesas/0166-lvds-AR0233-add-superexposure-plus.patch1251
-rw-r--r--bsp/meta-rcar/meta-rcar-gen3-adas/recipes-kernel/linux/linux-renesas/0167-lvds-AR0233-fix-matrix-size-set-default-h-vflip.patch90
-rw-r--r--bsp/meta-rcar/meta-rcar-gen3-adas/recipes-kernel/linux/linux-renesas/0168-lvds-ISX019-fix-add-address-intf-fix-read-write.patch228
-rw-r--r--bsp/meta-rcar/meta-rcar-gen3-adas/recipes-kernel/linux/linux-renesas/0169-lvds-OVT-add-dvp_order-parameter-for-ov10635.patch67
-rw-r--r--bsp/meta-rcar/meta-rcar-gen3-adas/recipes-kernel/linux/linux-renesas/0170-media-i2c-add-AR0147-imager.patch2224
-rw-r--r--bsp/meta-rcar/meta-rcar-gen3-adas/recipes-kernel/linux/linux-renesas/0171-lvds-ONSEMI-fix-matrix-position-during-crop.patch130
-rw-r--r--bsp/meta-rcar/meta-rcar-gen3-adas/recipes-kernel/linux/linux-renesas/0172-media-i2c-ar0147-fix-super-exposure-artifact-line.patch28
-rw-r--r--bsp/meta-rcar/meta-rcar-gen3-adas/recipes-kernel/linux/linux-renesas/0173-lvds-ti9x4-fix-remote-gpio-setup.patch132
-rw-r--r--bsp/meta-rcar/meta-rcar-gen3-adas/recipes-kernel/linux/linux-renesas/0174-arm64-dts-renesas-ulcb-vb2-Drive-CAN-controller-rese.patch89
-rw-r--r--bsp/meta-rcar/meta-rcar-gen3-adas/recipes-kernel/linux/linux-renesas/0175-lvds-ov2775-add-exposure-gain.patch76
-rw-r--r--bsp/meta-rcar/meta-rcar-gen3-adas/recipes-kernel/linux/linux-renesas/0176-lvds-geosemi-put-imager-to-autodetect-tail.patch58
-rw-r--r--bsp/meta-rcar/meta-rcar-gen3-adas/recipes-kernel/linux/linux-renesas/0177-media-rcar_vin-add-GREY-Y8-bypass.patch85
-rw-r--r--bsp/meta-rcar/meta-rcar-gen3-adas/recipes-kernel/linux/linux-renesas/0178-lvds-add-OV2311-imager.patch935
-rw-r--r--bsp/meta-rcar/meta-rcar-gen3-adas/recipes-kernel/linux/linux-renesas/0179-media-i2c-soc_camera-Fix-more-Bad-of_node_put-errors.patch139
-rw-r--r--bsp/meta-rcar/meta-rcar-gen3-adas/recipes-kernel/linux/linux-renesas/0180-media-i2c-ov490-add-LI-cameras.patch61
-rw-r--r--bsp/meta-rcar/meta-rcar-gen3-adas/recipes-kernel/linux/linux-renesas/0181-ARM64-dts-Remove-conflicting-with-mainline-V3M-and-V.patch635
-rw-r--r--bsp/meta-rcar/meta-rcar-gen3-adas/recipes-kernel/linux/linux-renesas/0182-iommu-msm-Claim-bus-ops-on-probe.patch58
-rw-r--r--bsp/meta-rcar/meta-rcar-gen3-adas/recipes-kernel/linux/linux-renesas/0183-iommu-Clean-up-of_iommu_init_fn.patch163
-rw-r--r--bsp/meta-rcar/meta-rcar-gen3-adas/recipes-kernel/linux/linux-renesas/0184-iommu-ipmmu-vmsa-Hook-up-r8a779-70-95-DT-matching-co.patch67
-rw-r--r--bsp/meta-rcar/meta-rcar-gen3-adas/recipes-kernel/linux/linux-renesas/0185-dt-bindings-display-bridge-Document-THC63LVD1024-LVD.patch96
-rw-r--r--bsp/meta-rcar/meta-rcar-gen3-adas/recipes-kernel/linux/linux-renesas/0186-gpio-rcar-document-R8A77980-bindings.patch32
-rw-r--r--bsp/meta-rcar/meta-rcar-gen3-adas/recipes-kernel/linux/linux-renesas/0187-arm64-dts-renesas-r8a77980-add-SMP-support.patch93
-rw-r--r--bsp/meta-rcar/meta-rcar-gen3-adas/recipes-kernel/linux/linux-renesas/0188-arm64-dts-renesas-r8a77980-add-GEther-support.patch47
-rw-r--r--bsp/meta-rcar/meta-rcar-gen3-adas/recipes-kernel/linux/linux-renesas/0189-arm64-dts-renesas-v3hsk-add-GEther-support.patch61
-rw-r--r--bsp/meta-rcar/meta-rcar-gen3-adas/recipes-kernel/linux/linux-renesas/0190-arm64-dts-renesas-r8a77980-add-I2C-support.patch145
-rw-r--r--bsp/meta-rcar/meta-rcar-gen3-adas/recipes-kernel/linux/linux-renesas/0191-arm64-dts-renesas-condor-add-I2C0-support.patch67
-rw-r--r--bsp/meta-rcar/meta-rcar-gen3-adas/recipes-kernel/linux/linux-renesas/0192-arm64-dts-renesas-r8a77980-add-GPIO-support.patch123
-rw-r--r--bsp/meta-rcar/meta-rcar-gen3-adas/recipes-kernel/linux/linux-renesas/0193-arm64-dts-renesas-condor-v3hsk-specify-Ethernet-PHY-.patch50
-rw-r--r--bsp/meta-rcar/meta-rcar-gen3-adas/recipes-kernel/linux/linux-renesas/0194-arm64-dts-renesas-r8a77980-add-FCPVD-VSPD-DU-LVDS-su.patch112
-rw-r--r--bsp/meta-rcar/meta-rcar-gen3-adas/recipes-kernel/linux/linux-renesas/0195-sh_eth-fix-enum-RPADIR_BIT.patch38
-rw-r--r--bsp/meta-rcar/meta-rcar-gen3-adas/recipes-kernel/linux/linux-renesas/0196-sh_eth-remove-sh_eth_cpu_data-rpadir_value.patch95
-rw-r--r--bsp/meta-rcar/meta-rcar-gen3-adas/recipes-kernel/linux/linux-renesas/0197-sh_eth-fix-enum-A-M-PR_BIT.patch62
-rw-r--r--bsp/meta-rcar/meta-rcar-gen3-adas/recipes-kernel/linux/linux-renesas/0198-iommu-ipmmu-vmsa-Document-R-Car-V3H-and-E3-IPMMU-DT-.patch36
-rw-r--r--bsp/meta-rcar/meta-rcar-gen3-adas/recipes-kernel/linux/linux-renesas/0199-dt-bindings-phy-Renesas-R-Car-Gen3-PCIe-PHY-bindings.patch54
-rw-r--r--bsp/meta-rcar/meta-rcar-gen3-adas/recipes-kernel/linux/linux-renesas/0200-phy-Renesas-R-Car-gen3-PCIe-PHY-driver.patch208
-rw-r--r--bsp/meta-rcar/meta-rcar-gen3-adas/recipes-kernel/linux/linux-renesas/0201-dt-bindings-irqchip-renesas-irqc-Document-r8a77980-s.patch33
-rw-r--r--bsp/meta-rcar/meta-rcar-gen3-adas/recipes-kernel/linux/linux-renesas/0202-arm64-dts-renesas-r8a77980-add-INTC-EX-support.patch49
-rw-r--r--bsp/meta-rcar/meta-rcar-gen3-adas/recipes-kernel/linux/linux-renesas/0203-net-phy-allow-scanning-busses-with-missing-phys.patch50
-rw-r--r--bsp/meta-rcar/meta-rcar-gen3-adas/recipes-kernel/linux/linux-renesas/0204-arm64-dts-renesas-r8a77980-add-RWDT-support.patch79
-rw-r--r--bsp/meta-rcar/meta-rcar-gen3-adas/recipes-kernel/linux/linux-renesas/0205-arm64-enable-CMT-TMU-support-for-Renesas-SoC.patch33
-rw-r--r--bsp/meta-rcar/meta-rcar-gen3-adas/recipes-kernel/linux/linux-renesas/0206-arm64-dts-renesas-r8a77980-add-Cortex-A53-PMU-suppor.patch44
-rw-r--r--bsp/meta-rcar/meta-rcar-gen3-adas/recipes-kernel/linux/linux-renesas/0207-arm64-dts-renesas-r8a77980-move-IPMMU-nodes.patch164
-rw-r--r--bsp/meta-rcar/meta-rcar-gen3-adas/recipes-kernel/linux/linux-renesas/0208-arm64-dts-renesas-r8a779-7-8-0-move-CAN-clock-node.patch86
-rw-r--r--bsp/meta-rcar/meta-rcar-gen3-adas/recipes-kernel/linux/linux-renesas/0209-arm64-dts-renesas-r8a77980-add-CSI2-VIN-support.patch411
-rw-r--r--bsp/meta-rcar/meta-rcar-gen3-adas/recipes-kernel/linux/linux-renesas/0210-arm64-dts-renesas-r8a77970-add-MMC-support.patch44
-rw-r--r--bsp/meta-rcar/meta-rcar-gen3-adas/recipes-kernel/linux/linux-renesas/0211-arm64-dts-renesas-v3msk-add-eMMC-support.patch72
-rw-r--r--bsp/meta-rcar/meta-rcar-gen3-adas/recipes-kernel/linux/linux-renesas/0212-arm64-dts-renesas-condor-v3hsk-add-DU-LVDS-HDMI-supp.patch312
-rw-r--r--bsp/meta-rcar/meta-rcar-gen3-adas/recipes-kernel/linux/linux-renesas/0213-arm64-dts-renesas-r8a77980-add-PCIe-support.patch96
-rw-r--r--bsp/meta-rcar/meta-rcar-gen3-adas/recipes-kernel/linux/linux-renesas/0214-arm64-dts-renesas-condor-add-PCIe-support.patch45
-rw-r--r--bsp/meta-rcar/meta-rcar-gen3-adas/recipes-kernel/linux/linux-renesas/0215-arm64-dts-renesas-v3hsk-Move-lvds0-node.patch61
-rw-r--r--bsp/meta-rcar/meta-rcar-gen3-adas/recipes-kernel/linux/linux-renesas/0216-arm64-dts-renesas-r8a77980-Attach-the-SYS-DMAC-to-th.patch54
-rw-r--r--bsp/meta-rcar/meta-rcar-gen3-adas/recipes-kernel/linux/linux-renesas/0217-arm64-dts-renesas-r8a779-7-8-0-add-CMT-support.patch185
-rw-r--r--bsp/meta-rcar/meta-rcar-gen3-adas/recipes-kernel/linux/linux-renesas/0218-dt-bindings-timer-renesas-tmu-document-R8A779-7-8-0-.patch34
-rw-r--r--bsp/meta-rcar/meta-rcar-gen3-adas/recipes-kernel/linux/linux-renesas/0219-arm64-dts-renesas-r8a779-7-8-0-add-TPU-support.patch66
-rw-r--r--bsp/meta-rcar/meta-rcar-gen3-adas/recipes-kernel/linux/linux-renesas/0220-arm64-dts-renesas-r8a779-7-8-0-add-PWM-support.patch145
-rw-r--r--bsp/meta-rcar/meta-rcar-gen3-adas/recipes-kernel/linux/linux-renesas/0221-media-vsp1-Use-header-display-lists-for-all-WPF-outp.patch274
-rw-r--r--bsp/meta-rcar/meta-rcar-gen3-adas/recipes-kernel/linux/linux-renesas/0222-arm64-dts-renesas-r8a77970-add-thermal-support.patch72
-rw-r--r--bsp/meta-rcar/meta-rcar-gen3-adas/recipes-kernel/linux/linux-renesas/0223-arm64-dts-renesas-r8a77980-add-thermal-support.patch93
-rw-r--r--bsp/meta-rcar/meta-rcar-gen3-adas/recipes-kernel/linux/linux-renesas/0224-arm64-dts-renesas-r8a779-7-8-0-add-TMU-support.patch174
-rw-r--r--bsp/meta-rcar/meta-rcar-gen3-adas/recipes-kernel/linux/linux-renesas/0225-arm64-dts-renesas-r8a779-7-8-0-add-MSIOF-support.patch163
-rw-r--r--bsp/meta-rcar/meta-rcar-gen3-adas/recipes-kernel/linux/linux-renesas/0226-arm64-dts-renesas-r8a77980-Connect-R-Car-V3H-AVB-to-.patch32
-rw-r--r--bsp/meta-rcar/meta-rcar-gen3-adas/recipes-kernel/linux/linux-renesas/0227-clk-renesas-r8a77980-Add-OSC-predivider-configuratio.patch72
-rw-r--r--bsp/meta-rcar/meta-rcar-gen3-adas/recipes-kernel/linux/linux-renesas/0228-clk-renesas-r8a77980-Add-RCLK-for-watchdog-timer.patch55
-rw-r--r--bsp/meta-rcar/meta-rcar-gen3-adas/recipes-kernel/linux/linux-renesas/0229-drm-rcar-du-lvds-add-R8A77980-support.patch31
-rw-r--r--bsp/meta-rcar/meta-rcar-gen3-adas/recipes-kernel/linux/linux-renesas/0230-drivers-flag-buses-which-demand-DMA-configuration.patch139
-rw-r--r--bsp/meta-rcar/meta-rcar-gen3-adas/recipes-kernel/linux/linux-renesas/0231-gpu-host1x-Call-of_dma_configure-after-setting-bus.patch39
-rw-r--r--bsp/meta-rcar/meta-rcar-gen3-adas/recipes-kernel/linux/linux-renesas/0232-gpu-host1x-Cleanup-on-initialization-failure.patch48
-rw-r--r--bsp/meta-rcar/meta-rcar-gen3-adas/recipes-kernel/linux/linux-renesas/0233-dma-mapping-move-dma-configuration-to-bus-infrastruc.patch261
-rw-r--r--bsp/meta-rcar/meta-rcar-gen3-adas/recipes-kernel/linux/linux-renesas/0234-drivers-remove-force-dma-flag-from-buses.patch252
-rw-r--r--bsp/meta-rcar/meta-rcar-gen3-adas/recipes-kernel/linux/linux-renesas/0235-clk-renesas-r8a77980-Add-CMT-clocks.patch36
-rw-r--r--bsp/meta-rcar/meta-rcar-gen3-adas/recipes-kernel/linux/linux-renesas/0236-clk-renesas-r8a77970-Add-SD0H-SD0-clocks-for-SDHI.patch169
-rw-r--r--bsp/meta-rcar/meta-rcar-gen3-adas/recipes-kernel/linux/linux-renesas/0237-clk-renesas-r8a77970-Add-CMT-clocks.patch37
-rw-r--r--bsp/meta-rcar/meta-rcar-gen3-adas/recipes-kernel/linux/linux-renesas/0238-clk-renesas-r8a77970-Add-TMU-clocks.patch38
-rw-r--r--bsp/meta-rcar/meta-rcar-gen3-adas/recipes-kernel/linux/linux-renesas/0239-dt-bindings-display-renesas-du-document-R8A77980-bin.patch43
-rw-r--r--bsp/meta-rcar/meta-rcar-gen3-adas/recipes-kernel/linux/linux-renesas/0240-dt-bindings-display-renesas-lvds-document-R8A77980-b.patch34
-rw-r--r--bsp/meta-rcar/meta-rcar-gen3-adas/recipes-kernel/linux/linux-renesas/0241-clk-renesas-r8a77970-Add-TPU-clock.patch35
-rw-r--r--bsp/meta-rcar/meta-rcar-gen3-adas/recipes-kernel/linux/linux-renesas/0242-mmc-renesas_sdhi_internal_dmac-add-R8A77970-to-white.patch35
-rw-r--r--bsp/meta-rcar/meta-rcar-gen3-adas/recipes-kernel/linux/linux-renesas/0243-dt-bindings-mmc-tmio_mmc-document-Renesas-R8A77970-b.patch33
-rw-r--r--bsp/meta-rcar/meta-rcar-gen3-adas/recipes-kernel/linux/linux-renesas/0244-dt-bindings-thermal-rcar-gen3-thermal-document-R8A77.patch49
-rw-r--r--bsp/meta-rcar/meta-rcar-gen3-adas/recipes-kernel/linux/linux-renesas/0245-thermal-rcar_gen3_thermal-add-R8A77980-support.patch39
-rw-r--r--bsp/meta-rcar/meta-rcar-gen3-adas/recipes-kernel/linux/linux-renesas/0246-dt-bindings-thermal-rcar-thermal-document-R8A77970-b.patch54
-rw-r--r--bsp/meta-rcar/meta-rcar-gen3-adas/recipes-kernel/linux/linux-renesas/0247-thermal-rcar_thermal-add-R8A77970-support.patch37
-rw-r--r--bsp/meta-rcar/meta-rcar-gen3-adas/recipes-kernel/linux/linux-renesas/0248-clk-renesas-r8a77970-Add-RPC-clocks.patch41
-rw-r--r--bsp/meta-rcar/meta-rcar-gen3-adas/recipes-kernel/linux/linux-renesas/0249-pinctrl-sh-pfc-r8a77970-Add-QSPI-pins-groups-and-fun.patch128
-rw-r--r--bsp/meta-rcar/meta-rcar-gen3-adas/recipes-kernel/linux/linux-renesas/0250-pinctrl-sh-pfc-r8a77980-Add-QSPI-pins-groups-and-fun.patch127
-rw-r--r--bsp/meta-rcar/meta-rcar-gen3-adas/recipes-kernel/linux/linux-renesas/0251-media-rcar-rcar-csi2-Update-V3M-E3-PHTW-tables.patch94
-rw-r--r--bsp/meta-rcar/meta-rcar-gen3-adas/recipes-kernel/linux/linux-renesas/0252-soc-renesas-r8a77970-sysc-Remove-non-existent-CR7-po.patch50
-rw-r--r--bsp/meta-rcar/meta-rcar-gen3-adas/recipes-kernel/linux/linux-renesas/0253-soc-renesas-r8a77970-sysc-Correct-names-of-A2DP-A2CN.patch61
-rw-r--r--bsp/meta-rcar/meta-rcar-gen3-adas/recipes-kernel/linux/linux-renesas/0254-soc-renesas-r8a77980-sysc-Correct-names-of-A2DP-01-p.patch56
-rw-r--r--bsp/meta-rcar/meta-rcar-gen3-adas/recipes-kernel/linux/linux-renesas/0255-soc-renesas-r8a77980-sysc-Correct-A3VIP-012-power-do.patch57
-rw-r--r--bsp/meta-rcar/meta-rcar-gen3-adas/recipes-kernel/linux/linux-renesas/0256-clk-renesas-r8a77970-Add-CPEX-clock.patch31
-rw-r--r--bsp/meta-rcar/meta-rcar-gen3-adas/recipes-kernel/linux/linux-renesas/0257-media-rcar-csi2-add-R8A77980-support.patch62
-rw-r--r--bsp/meta-rcar/meta-rcar-gen3-adas/recipes-kernel/linux/linux-renesas/0258-media-rcar-vin-add-R8A77980-support.patch87
-rw-r--r--bsp/meta-rcar/meta-rcar-gen3-adas/recipes-kernel/linux/linux-renesas/0259-pinctrl-sh-pfc-r8a77970-Add-missing-MOD_SEL0-field.patch34
-rw-r--r--bsp/meta-rcar/meta-rcar-gen3-adas/recipes-kernel/linux/linux-renesas/0260-pinctrl-sh-pfc-r8a77980-Add-missing-MOD_SEL0-field.patch34
-rw-r--r--bsp/meta-rcar/meta-rcar-gen3-adas/recipes-kernel/linux/linux-renesas/0261-media-rcar-csi2-Fix-PHTW-table-values-for-E3-V3M.patch99
-rw-r--r--bsp/meta-rcar/meta-rcar-gen3-adas/recipes-kernel/linux/linux-renesas/0262-pinctrl-sh-pfc-Reduce-kernel-size-for-narrow-VIN-cha.patch165
-rw-r--r--bsp/meta-rcar/meta-rcar-gen3-adas/recipes-kernel/linux/linux-renesas/0263-pinctrl-sh-pfc-r8a77970-Deduplicate-VIN-01-pin-defin.patch186
-rw-r--r--bsp/meta-rcar/meta-rcar-gen3-adas/recipes-kernel/linux/linux-renesas/0264-pinctrl-sh-pfc-r8a77980-Deduplicate-VIN1-pin-definit.patch110
-rw-r--r--bsp/meta-rcar/meta-rcar-gen3-adas/recipes-kernel/linux/linux-renesas/0265-arm64-dts-renesas-v3msk-specify-EtherAVB-PHY-IRQ.patch33
-rw-r--r--bsp/meta-rcar/meta-rcar-gen3-adas/recipes-kernel/linux/linux-renesas/0266-sh_eth-rename-sh_eth_cpu_data-hw_checksum.patch104
-rw-r--r--bsp/meta-rcar/meta-rcar-gen3-adas/recipes-kernel/linux/linux-renesas/0267-sh_eth-RX-checksum-offload-support.patch232
-rw-r--r--bsp/meta-rcar/meta-rcar-gen3-adas/recipes-kernel/linux/linux-renesas/0268-sh_eth-offload-RX-checksum-on-R7S72100.patch31
-rw-r--r--bsp/meta-rcar/meta-rcar-gen3-adas/recipes-kernel/linux/linux-renesas/0269-sh_eth-offload-RX-checksum-on-R8A7740.patch32
-rw-r--r--bsp/meta-rcar/meta-rcar-gen3-adas/recipes-kernel/linux/linux-renesas/0270-sh_eth-offload-RX-checksum-on-R8A77980.patch31
-rw-r--r--bsp/meta-rcar/meta-rcar-gen3-adas/recipes-kernel/linux/linux-renesas/0271-sh_eth-offload-RX-checksum-on-SH7734.patch31
-rw-r--r--bsp/meta-rcar/meta-rcar-gen3-adas/recipes-kernel/linux/linux-renesas/0272-sh_eth-offload-RX-checksum-on-SH7763.patch31
-rw-r--r--bsp/meta-rcar/meta-rcar-gen3-adas/recipes-kernel/linux/linux-renesas/0273-clk-renesas-rcar-gen3-Factor-out-cpg_reg_modify.patch119
-rw-r--r--bsp/meta-rcar/meta-rcar-gen3-adas/recipes-kernel/linux/linux-renesas/0274-clk-renesas-rcar-gen3-Add-spinlock.patch52
-rw-r--r--bsp/meta-rcar/meta-rcar-gen3-adas/recipes-kernel/linux/linux-renesas/0275-clk-renesas-rcar-gen3-Add-RPC-clocks.patch169
-rw-r--r--bsp/meta-rcar/meta-rcar-gen3-adas/recipes-kernel/linux/linux-renesas/0276-clk-renesas-r8a77980-Add-RPC-clocks.patch55
-rw-r--r--bsp/meta-rcar/meta-rcar-gen3-adas/recipes-kernel/linux/linux-renesas/0277-pinctrl-sh-pfc-r8a77970-Rename-IOCTRLx-registers.patch65
-rw-r--r--bsp/meta-rcar/meta-rcar-gen3-adas/recipes-kernel/linux/linux-renesas/0278-pinctrl-sh-pfc-r8a77980-Rename-IOCTRLx-registers.patch77
-rw-r--r--bsp/meta-rcar/meta-rcar-gen3-adas/recipes-kernel/linux/linux-renesas/0279-clk-renesas-r8a77980-Fix-RPC-IF-module-clock-s-paren.patch34
-rw-r--r--bsp/meta-rcar/meta-rcar-gen3-adas/recipes-kernel/linux/linux-renesas/0280-arm64-dts-renesas-r8a77980-Add-renesas-id-to-VIN.patch157
-rw-r--r--bsp/meta-rcar/meta-rcar-gen3-adas/recipes-kernel/linux/linux-renesas/0281-arm64-dts-renesas-eagle-Add-x1-clock.patch43
-rw-r--r--bsp/meta-rcar/meta-rcar-gen3-adas/recipes-kernel/linux/linux-renesas/0282-arm64-dts-renesas-r8a77980-condor-Add-GEther-support.patch80
-rw-r--r--bsp/meta-rcar/meta-rcar-gen3-adas/recipes-kernel/linux/linux-renesas/0283-iommu-ipmmu-vmsa-Add-r8a77980-support.patch45
-rw-r--r--bsp/meta-rcar/meta-rcar-gen3-adas/recipes-kernel/linux/linux-renesas/0284-iommu-ipmmu-vmsa-Fix-NULL-pointer-dereference.patch29
-rw-r--r--bsp/meta-rcar/meta-rcar-gen3-adas/recipes-kernel/linux/linux-renesas/0285-iommu-ipmmu-vmsa-Add-r8a779-7-8-0-whitelist.patch65
-rw-r--r--bsp/meta-rcar/meta-rcar-gen3-adas/recipes-kernel/linux/linux-renesas/0286-clk-renesas-r8a77980-cpg-mssr-Add-VIN-clocks.patch34
-rw-r--r--bsp/meta-rcar/meta-rcar-gen3-adas/recipes-kernel/linux/linux-renesas/0287-clk-renesas-r8a77970-cpg-mssr-Add-IMR-clocks.patch30
-rw-r--r--bsp/meta-rcar/meta-rcar-gen3-adas/recipes-kernel/linux/linux-renesas/0288-clk-renesas-r8a77980-cpg-mssr-Add-IMR-clocks.patch39
-rw-r--r--bsp/meta-rcar/meta-rcar-gen3-adas/recipes-kernel/linux/linux-renesas/0289-clk-renesas-r8a77970-cpg-mssr-Add-ISP-clock.patch27
-rw-r--r--bsp/meta-rcar/meta-rcar-gen3-adas/recipes-kernel/linux/linux-renesas/0290-clk-renesas-r8a77980-cpg-mssr-Add-ISP-clocks.patch28
-rw-r--r--bsp/meta-rcar/meta-rcar-gen3-adas/recipes-kernel/linux/linux-renesas/0291-clk-renesas-r8a77980-cpg-mssr-Add-IMP-clocks.patch36
-rw-r--r--bsp/meta-rcar/meta-rcar-gen3-adas/recipes-kernel/linux/linux-renesas/0292-clk-renesas-r8a77980-cpg-mssr-Add-VIP-clocks.patch43
-rw-r--r--bsp/meta-rcar/meta-rcar-gen3-adas/recipes-kernel/linux/linux-renesas/0293-clk-renesas-r8a77970-cpg-mssr-Add-IMP-clocks.patch33
-rw-r--r--bsp/meta-rcar/meta-rcar-gen3-adas/recipes-kernel/linux/linux-renesas/0294-media-soc_camera-Add-CONFIG_VIDEO_ADV_DEBUG-support.patch78
-rw-r--r--bsp/meta-rcar/meta-rcar-gen3-adas/recipes-kernel/linux/linux-renesas/0295-media-platform-soc_camera-Add-V4L2-R-Car-ISP-driver.patch2150
-rw-r--r--bsp/meta-rcar/meta-rcar-gen3-adas/recipes-kernel/linux/linux-renesas/0296-media-platform-soc_camera-rcar_isp-Fix-unused-variab.patch51
-rw-r--r--bsp/meta-rcar/meta-rcar-gen3-adas/recipes-kernel/linux/linux-renesas/0297-media-platform-soc_camera-rcar_vin-Update-R-Car-V3M-.patch57
-rw-r--r--bsp/meta-rcar/meta-rcar-gen3-adas/recipes-kernel/linux/linux-renesas/0298-media-platform-soc_camera-rcar_vin-Add-r8a77980-supp.patch256
-rw-r--r--bsp/meta-rcar/meta-rcar-gen3-adas/recipes-kernel/linux/linux-renesas/0299-media-platform-soc_camera-rcar_csi2-r8a77970-Update-.patch73
-rw-r--r--bsp/meta-rcar/meta-rcar-gen3-adas/recipes-kernel/linux/linux-renesas/0300-media-platform-soc_camera-rcar_csi2-Add-r8a77980-sup.patch89
-rw-r--r--bsp/meta-rcar/meta-rcar-gen3-adas/recipes-kernel/linux/linux-renesas/0301-arm64-dts-renesas-r8a77970-Convert-VIN-nodes-to-soc_.patch116
-rw-r--r--bsp/meta-rcar/meta-rcar-gen3-adas/recipes-kernel/linux/linux-renesas/0302-arm64-dts-renesas-r8a77980-Convert-VIN-nodes-to-soc_.patch212
-rw-r--r--bsp/meta-rcar/meta-rcar-gen3-adas/recipes-kernel/linux/linux-renesas/0303-arm64-dts-renesas-r8a77970-Convert-SCI2-nodes-to-soc.patch56
-rw-r--r--bsp/meta-rcar/meta-rcar-gen3-adas/recipes-kernel/linux/linux-renesas/0304-arm64-dts-renesas-r8a77980-Convert-CSI2-nodes-to-soc.patch92
-rw-r--r--bsp/meta-rcar/meta-rcar-gen3-adas/recipes-kernel/linux/linux-renesas/0305-arm64-dts-renesas-r8a77970-Add-IMR-nodes.patch66
-rw-r--r--bsp/meta-rcar/meta-rcar-gen3-adas/recipes-kernel/linux/linux-renesas/0306-arm64-dts-renesas-r8a77980-Add-IMR-nodes.patch84
-rw-r--r--bsp/meta-rcar/meta-rcar-gen3-adas/recipes-kernel/linux/linux-renesas/0307-arm64-dts-renesas-r8a77970-Add-ISP-node.patch36
-rw-r--r--bsp/meta-rcar/meta-rcar-gen3-adas/recipes-kernel/linux/linux-renesas/0308-arm64-dts-renesas-r8a77980-Add-ISP-nodes.patch46
-rw-r--r--bsp/meta-rcar/meta-rcar-gen3-adas/recipes-kernel/linux/linux-renesas/0309-arm64-dts-renesas-eagle-Add-video-input-support.patch326
-rw-r--r--bsp/meta-rcar/meta-rcar-gen3-adas/recipes-kernel/linux/linux-renesas/0310-arm64-dts-renesas-condor-Add-video-input-support.patch587
-rw-r--r--bsp/meta-rcar/meta-rcar-gen3-adas/recipes-kernel/linux/linux-renesas/0311-arm64-dts-renesas-v3msk-Add-reserved-memory-nodes.patch53
-rw-r--r--bsp/meta-rcar/meta-rcar-gen3-adas/recipes-kernel/linux/linux-renesas/0312-arm64-dts-renesas-v3hsk-Add-reserved-memory-nodes.patch53
-rw-r--r--bsp/meta-rcar/meta-rcar-gen3-adas/recipes-kernel/linux/linux-renesas/0313-arm64-dts-renesas-eagle-Add-reserved-memory-nodes.patch53
-rw-r--r--bsp/meta-rcar/meta-rcar-gen3-adas/recipes-kernel/linux/linux-renesas/0314-arm64-dts-renesas-condor-Add-reserved-memory-nodes.patch54
-rw-r--r--bsp/meta-rcar/meta-rcar-gen3-adas/recipes-kernel/linux/linux-renesas/0315-arm64-dts-renesas-v3msk-Add-mmngr-and-mmngrbuf-nodes.patch36
-rw-r--r--bsp/meta-rcar/meta-rcar-gen3-adas/recipes-kernel/linux/linux-renesas/0316-arm64-dts-renesas-v3hsk-Add-mmngr-and-mmngrbuf-nodes.patch36
-rw-r--r--bsp/meta-rcar/meta-rcar-gen3-adas/recipes-kernel/linux/linux-renesas/0317-arm64-dts-renesas-eagle-Add-mmngr-and-mmngrbuf-nodes.patch36
-rw-r--r--bsp/meta-rcar/meta-rcar-gen3-adas/recipes-kernel/linux/linux-renesas/0318-arm64-dts-renesas-condor-Add-mmngr-and-mmngrbuf-node.patch36
-rw-r--r--bsp/meta-rcar/meta-rcar-gen3-adas/recipes-kernel/linux/linux-renesas/0319-arm64-dts-renesas-v3msk-Add-vspm_if-node.patch30
-rw-r--r--bsp/meta-rcar/meta-rcar-gen3-adas/recipes-kernel/linux/linux-renesas/0320-arm64-dts-renesas-v3hsk-Add-vspm_if-node.patch30
-rw-r--r--bsp/meta-rcar/meta-rcar-gen3-adas/recipes-kernel/linux/linux-renesas/0321-arm64-dts-renesas-eagle-Add-vspm_if-node.patch30
-rw-r--r--bsp/meta-rcar/meta-rcar-gen3-adas/recipes-kernel/linux/linux-renesas/0322-arm64-dts-renesas-condor-Add-vspm_if-node.patch30
-rw-r--r--bsp/meta-rcar/meta-rcar-gen3-adas/recipes-kernel/linux/linux-renesas/0323-arm64-dts-renesas-eagle-Add-Dialog-DA9063-MFD.patch56
-rw-r--r--bsp/meta-rcar/meta-rcar-gen3-adas/recipes-kernel/linux/linux-renesas/0324-arm64-dts-renesas-Add-r8a77970-eagle-function-suppor.patch41
-rw-r--r--bsp/meta-rcar/meta-rcar-gen3-adas/recipes-kernel/linux/linux-renesas/0325-arm64-dts-renesas-Add-r8a77970-es1-support.patch131
-rw-r--r--bsp/meta-rcar/meta-rcar-gen3-adas/recipes-kernel/linux/linux-renesas/0326-arm64-dts-renesas-Add-r8a77970-v3msk-view-support.patch39
-rw-r--r--bsp/meta-rcar/meta-rcar-gen3-adas/recipes-kernel/linux/linux-renesas/0327-arm64-dts-renesas-Add-r8a77970-v3msk-kf-support.patch39
-rw-r--r--bsp/meta-rcar/meta-rcar-gen3-adas/recipes-kernel/linux/linux-renesas/0328-arm64-dts-renesas-Add-r8a77970-v3msk-vbm-support.patch44
-rw-r--r--bsp/meta-rcar/meta-rcar-gen3-adas/recipes-kernel/linux/linux-renesas/0329-arm64-dts-renesas-Add-r8a77970-v3mzf-support.patch114
-rw-r--r--bsp/meta-rcar/meta-rcar-gen3-adas/recipes-kernel/linux/linux-renesas/0330-arm64-dts-renesas-Add-r8a77980-v3hsk-vbm-support.patch57
-rw-r--r--bsp/meta-rcar/meta-rcar-gen3-adas/recipes-kernel/linux/linux-renesas/0331-arm64-dts-renesas-r8a779-7-8-0-Add-IMP-devices.patch321
-rw-r--r--bsp/meta-rcar/meta-rcar-gen3-adas/recipes-kernel/linux/linux-renesas/0332-arm64-dts-renesas-r8a77980-Add-VIP-nodes.patch183
-rw-r--r--bsp/meta-rcar/meta-rcar-gen3-adas/recipes-kernel/linux/linux-renesas/0333-arm64-dts-renesas-r8a779-78-0-Add-linux-multimedia-r.patch108
-rw-r--r--bsp/meta-rcar/meta-rcar-gen3-adas/recipes-kernel/linux/linux-renesas/0334-IMR-UIO-Driver-initial-version.patch816
-rw-r--r--bsp/meta-rcar/meta-rcar-gen3-adas/recipes-kernel/linux/linux-renesas/0335-media-rcar-imr-IMR-driver-updates-for-raw-DL.patch538
-rw-r--r--bsp/meta-rcar/meta-rcar-gen3-adas/recipes-kernel/linux/linux-renesas/0336-media-rcar-imr-Add-RSE-support.patch348
-rw-r--r--bsp/meta-rcar/meta-rcar-gen3-adas/recipes-kernel/linux/linux-renesas/0337-rcar_imr-v4l2-driver-Fix-module-support.patch278
-rw-r--r--bsp/meta-rcar/meta-rcar-gen3-adas/recipes-kernel/linux/linux-renesas/0338-V3Hsk-Condor-and-V3Msk-Eagle-Remove-cma-default-area.patch103
-rw-r--r--bsp/meta-rcar/meta-rcar-gen3-adas/recipes-kernel/linux/linux-renesas/0339-media-rcar_imr-Enable-LUCE-for-NV16-format.patch49
-rw-r--r--bsp/meta-rcar/meta-rcar-gen3-adas/recipes-kernel/linux/linux-renesas/0340-clk-cs2000-add-support-for-cs2300.patch256
-rw-r--r--bsp/meta-rcar/meta-rcar-gen3-adas/recipes-kernel/linux/linux-renesas/0341-V3H-add-support-for-8-4-channel-VideoBox-board-from-.patch1626
-rw-r--r--bsp/meta-rcar/meta-rcar-gen3-adas/recipes-kernel/linux/linux-renesas/0342-arm64-dts-r8a77970-Videobox-Mini-V3-board-support.patch95
-rw-r--r--bsp/meta-rcar/meta-rcar-gen3-adas/recipes-kernel/linux/linux-renesas/0343-arm64-dts-renesas-r8a77970-v3msk-Add-ethernet0-alias.patch31
-rw-r--r--bsp/meta-rcar/meta-rcar-gen3-adas/recipes-kernel/linux/linux-renesas/0344-arm64-dts-renesas-r8a77970-Add-ISP0-alias.patch36
-rw-r--r--bsp/meta-rcar/meta-rcar-gen3-adas/recipes-kernel/linux/linux-renesas/0345-arm64-dts-renesas-r8a77980-Add-ISP-aliases.patch46
-rw-r--r--bsp/meta-rcar/meta-rcar-gen3-adas/recipes-kernel/linux/linux-renesas/0346-media-soc_camera-Add-soc_camera-host-preregister.patch74
-rw-r--r--bsp/meta-rcar/meta-rcar-gen3-adas/recipes-kernel/linux/linux-renesas/0347-arm64-renesas-r8a77980-use-CSI-4-lanes.patch339
-rw-r--r--bsp/meta-rcar/meta-rcar-gen3-adas/recipes-kernel/linux/linux-renesas/0348-Bunch-update-of-r8a77980-v3hsk-vb-4ch.dts.patch139
-rw-r--r--bsp/meta-rcar/meta-rcar-gen3-adas/recipes-kernel/linux/linux-renesas/0349-arm64-dts-renesas-r8a77980-VideoBox-Mini-fix-csi-spe.patch26
-rw-r--r--bsp/meta-rcar/meta-rcar-gen3-adas/recipes-kernel/linux/linux-renesas/0350-arm64-dts-renesas-r8a77980-v3hsk-vb-4ch-and-8ch-fix-.patch193
-rw-r--r--bsp/meta-rcar/meta-rcar-gen3-adas/recipes-kernel/linux/linux-renesas/0351-arm64-dts-renesas-r8a77980-VB-4ch-and-8ch-Add-PCIE-p.patch44
-rw-r--r--bsp/meta-rcar/meta-rcar-gen3-adas/recipes-kernel/linux/linux-renesas/0352-gpu-drm-rcar_du-Fix-physical-address-of-the-CMA-back.patch30
-rw-r--r--bsp/meta-rcar/meta-rcar-gen3-adas/recipes-kernel/linux/linux-renesas/0353-media-soc_camera-rcar_csi2-add-dump-module-param.patch65
-rw-r--r--bsp/meta-rcar/meta-rcar-gen3-adas/recipes-kernel/linux/linux-renesas/0354-media-rcar_csi2-Disable-data-type-matching.patch58
-rw-r--r--bsp/meta-rcar/meta-rcar-gen3-adas/recipes-kernel/linux/linux-renesas/0355-gpu-drm-rcar-du-Extend-VSP1-DRM-interface.patch547
-rw-r--r--bsp/meta-rcar/meta-rcar-gen3-adas/recipes-kernel/linux/linux-renesas/0356-media-platform-vsp1-Extend-DRM-VSP1-interface.patch374
-rw-r--r--bsp/meta-rcar/meta-rcar-gen3-adas/recipes-kernel/linux/linux-renesas/0357-gpu-drm-rcar-du-rcar_du_vsp-Check-if-gem-buffer-has-.patch29
-rw-r--r--bsp/meta-rcar/meta-rcar-gen3-adas/recipes-kernel/linux/linux-renesas/0358-media-platform-vsp1-Add-cropping-handling-to-VSP-alp.patch56
-rw-r--r--bsp/meta-rcar/meta-rcar-gen3-adas/recipes-kernel/linux/linux-renesas/0359-media-platform-rcar_imr-Clean-up-to-avoid-compiler-w.patch106
-rw-r--r--bsp/meta-rcar/meta-rcar-gen3-adas/recipes-kernel/linux/linux-renesas/0360-arm64-dts-renesas-r8a77970-and-r8a77980-Add-CPU-oper.patch206
-rw-r--r--bsp/meta-rcar/meta-rcar-gen3-adas/recipes-kernel/linux/linux-renesas/0361-V3H-DTS-Add-FCPR-devices.patch70
-rw-r--r--bsp/meta-rcar/meta-rcar-gen3-adas/recipes-kernel/linux/linux-renesas/0362-arm64-dts-r8a77980-v3hsk-Enable-onboard-eMMC.patch69
-rw-r--r--bsp/meta-rcar/meta-rcar-gen3-adas/recipes-kernel/linux/linux-renesas/0363-arm64-dts-renesas-r8a77980-v3hsk-vb-Xch-Fix-Ethernet.patch50
-rw-r--r--bsp/meta-rcar/meta-rcar-gen3-adas/recipes-kernel/linux/linux-renesas/0364-clocksource-drivers-sh_cmt-Add-R-Car-gen3-support.patch37
-rw-r--r--bsp/meta-rcar/meta-rcar-gen3-adas/recipes-kernel/linux/linux-renesas/0365-mtd-spi-nor-Add-R-Car-Gen3-RPC-QSPI-driver.patch1334
-rw-r--r--bsp/meta-rcar/meta-rcar-gen3-adas/recipes-kernel/linux/linux-renesas/0366-mtd-spi-nor-renesas-rpc-Workaround-256-byte-data-siz.patch35
-rw-r--r--bsp/meta-rcar/meta-rcar-gen3-adas/recipes-kernel/linux/linux-renesas/0367-mtd-spi-nor-Add-s25fs512s-and-s25fs128s-01-SPI-NOR-f.patch37
-rw-r--r--bsp/meta-rcar/meta-rcar-gen3-adas/recipes-kernel/linux/linux-renesas/0368-arm64-dts-renesas-r8a77970-Add-RPC-QSPI-node.patch41
-rw-r--r--bsp/meta-rcar/meta-rcar-gen3-adas/recipes-kernel/linux/linux-renesas/0369-arm64-dts-renesas-r8a77980-Add-RPC-QSPI-node.patch41
-rw-r--r--bsp/meta-rcar/meta-rcar-gen3-adas/recipes-kernel/linux/linux-renesas/0370-arm64-dts-renesas-v3msk-Add-s25fs512s-QSPI-flash-nod.patch107
-rw-r--r--bsp/meta-rcar/meta-rcar-gen3-adas/recipes-kernel/linux/linux-renesas/0371-arm64-dts-renesas-v3mzf-Add-s25fs512s-QSPI-flash-nod.patch104
-rw-r--r--bsp/meta-rcar/meta-rcar-gen3-adas/recipes-kernel/linux/linux-renesas/0372-arm64-dts-renesas-eagle-Add-s25fs512s-QSPI-flash-nod.patch107
-rw-r--r--bsp/meta-rcar/meta-rcar-gen3-adas/recipes-kernel/linux/linux-renesas/0373-arm64-dts-renesas-v3hsk-Add-s25fs512s-QSPI-flash-nod.patch101
-rw-r--r--bsp/meta-rcar/meta-rcar-gen3-adas/recipes-kernel/linux/linux-renesas/0374-arm64-dts-renesas-condor-Add-s25fs512s-QSPI-flash-no.patch108
-rw-r--r--bsp/meta-rcar/meta-rcar-gen3-adas/recipes-kernel/linux/linux-renesas/0375-mtd-spi-nor-renesas-rpc-Support-single-mode-write-co.patch61
-rw-r--r--bsp/meta-rcar/meta-rcar-gen3-adas/recipes-kernel/linux/linux-renesas/0376-mtd-spi-nor-renesas-rpc-Add-DMA-read-support.patch219
-rw-r--r--bsp/meta-rcar/meta-rcar-gen3-adas/recipes-kernel/linux/linux-renesas/0377-r8a779-78-dtsi-Add-iccom-nodes.patch196
-rw-r--r--bsp/meta-rcar/meta-rcar-gen3-adas/recipes-kernel/linux/linux-renesas/0378-arm64-dts-renesas-Add-temperature-emergency-levels.patch52
-rw-r--r--bsp/meta-rcar/meta-rcar-gen3-adas/recipes-kernel/linux/linux-renesas/0379-r8a77980-dts-Add-vbm-v3-on-r8a77980-SoC.patch70
-rw-r--r--bsp/meta-rcar/meta-rcar-gen3-adas/recipes-kernel/linux/linux-renesas/0380-arm64-dts-r8a77970-Enable-TMU-and-CMT.patch101
-rw-r--r--bsp/meta-rcar/meta-rcar-gen3-adas/recipes-kernel/linux/linux-renesas/0381-arm64-dts-r8a77980-Enable-TMU-and-CMT.patch101
-rw-r--r--bsp/meta-rcar/meta-rcar-gen3-adas/recipes-kernel/linux/linux-renesas/0382-arm64-dts-renesas-r8a77970-and-r8a77980-Add-QoS-node.patch46
-rw-r--r--bsp/meta-rcar/meta-rcar-gen3-adas/recipes-kernel/linux/linux-renesas/0383-clk-renesas-r8a77970-cpg-mssr-Add-sadc-clock.patch26
-rw-r--r--bsp/meta-rcar/meta-rcar-gen3-adas/recipes-kernel/linux/linux-renesas/0384-arm64-dts-renesas-r8a77970-Add-sadc-node.patch37
-rw-r--r--bsp/meta-rcar/meta-rcar-gen3-adas/recipes-kernel/linux/linux-renesas/0385-iio-adc-Add-R-Car-SADC-driver.patch456
-rw-r--r--bsp/meta-rcar/meta-rcar-gen3-adas/recipes-kernel/linux/linux-renesas/0386-rcar-vin-add-ISP-source-enable.patch66
-rw-r--r--bsp/meta-rcar/meta-rcar-gen3-adas/recipes-kernel/linux/linux-renesas/0387-media-soc_camera-Add-events-support.patch426
-rw-r--r--bsp/meta-rcar/meta-rcar-gen3-adas/recipes-kernel/linux/linux-renesas/0388-media-rcar-imr-Add-stride-support-to-IMR.patch216
-rw-r--r--bsp/meta-rcar/meta-rcar-gen3-adas/recipes-kernel/linux/linux-renesas/0389-arm64-renesas-r8a77980-VB-use-REFCLK-23.0MHZ.patch78
-rw-r--r--bsp/meta-rcar/meta-rcar-gen3-adas/recipes-kernel/linux/linux-renesas/0390-arm64-dts-renesas-Add-V3x-VideoBox-FDPLink-support.patch123
-rw-r--r--bsp/meta-rcar/meta-rcar-gen3-adas/recipes-kernel/linux/linux-renesas/0391-arm64-dts-renesas-Enable-FDPLink-output-on-V3x-Video.patch71
-rw-r--r--bsp/meta-rcar/meta-rcar-gen3-adas/recipes-kernel/linux/linux-renesas/0392-gpu-drm-bridge-thc63-Set-upper-clock-limit-to-150-MH.patch32
-rw-r--r--bsp/meta-rcar/meta-rcar-gen3-adas/recipes-kernel/linux/linux-renesas/0393-media-soc_camera-dummy-add-mbus-controls-ids.patch338
-rw-r--r--bsp/meta-rcar/meta-rcar-gen3-adas/recipes-kernel/linux/linux-renesas/0394-media-i2c-ar0233-fix-superexposure.patch31
-rw-r--r--bsp/meta-rcar/meta-rcar-gen3-adas/recipes-kernel/linux/linux-renesas/0395-media-i2c-ap0101-add-V-H-flip.patch63
-rw-r--r--bsp/meta-rcar/meta-rcar-gen3-adas/recipes-kernel/linux/linux-renesas/0396-media-i2c-ap0101-ar014x-get-OTP-more-complex.patch72
-rw-r--r--bsp/meta-rcar/meta-rcar-gen3-adas/recipes-kernel/linux/linux-renesas/0397-media-i2c-ar0147-add-mipi-rev3-lvds-support.patch1083
-rw-r--r--bsp/meta-rcar/meta-rcar-gen3-adas/recipes-kernel/linux/linux-renesas/0398-media-i2c-ar0147-add-SE-mode.patch284
-rw-r--r--bsp/meta-rcar/meta-rcar-gen3-adas/recipes-kernel/linux/linux-renesas/0399-media-i2c-ar0233-fix-artifact-line-at-vflip.patch59
-rw-r--r--bsp/meta-rcar/meta-rcar-gen3-adas/recipes-kernel/linux/linux-renesas/0400-media-platform-soc_mediabus-add-Bayer-16bit-format.patch36
-rw-r--r--bsp/meta-rcar/meta-rcar-gen3-adas/recipes-kernel/linux/linux-renesas/0401-media-i2c-ov490_ov10640-add-group-switch.patch103
-rw-r--r--bsp/meta-rcar/meta-rcar-gen3-adas/recipes-kernel/linux/linux-renesas/0402-media-i2c-gw5200-detection-workaround.patch118
-rw-r--r--bsp/meta-rcar/meta-rcar-gen3-adas/recipes-kernel/linux/linux-renesas/0403-media-i2c-ov2311-put-to-autodetect-head.patch48
-rw-r--r--bsp/meta-rcar/meta-rcar-gen3-adas/recipes-kernel/linux/linux-renesas/0404-media-i2c-onsemi-imager-correct-trigger-handling.patch165
-rw-r--r--bsp/meta-rcar/meta-rcar-gen3-adas/recipes-kernel/linux/linux-renesas/0405-media-i2c-ov10640-fix-controls.patch70
-rw-r--r--bsp/meta-rcar/meta-rcar-gen3-adas/recipes-kernel/linux/linux-renesas/0406-Add-new-custom_ioctl-ops-for-soc-camera.patch58
-rw-r--r--bsp/meta-rcar/meta-rcar-gen3-adas/recipes-kernel/linux/linux-renesas/0407-arm64-dts-renesas-r8a77970-v3msk-Fix-memory-size.patch28
-rw-r--r--bsp/meta-rcar/meta-rcar-gen3-adas/recipes-kernel/linux/linux-renesas/0408-arm64-dts-renesas-v3hsk-Add-GEther-PHY-GPIO-reset-pi.patch36
-rw-r--r--bsp/meta-rcar/meta-rcar-gen3-adas/recipes-kernel/linux/linux-renesas/0409-arm64-dts-renesas-condor-Add-GEther-PHY-GPIO-reset-p.patch28
-rw-r--r--bsp/meta-rcar/meta-rcar-gen3-adas/recipes-kernel/linux/linux-renesas/0410-arm64-dts-renesas-eagle-Add-RAVB-PHY-GPIO-reset-pin-.patch28
-rw-r--r--bsp/meta-rcar/meta-rcar-gen3-adas/recipes-kernel/linux/linux-renesas/0411-media-soc_camera-add-MAX9288-support.patch956
-rw-r--r--bsp/meta-rcar/meta-rcar-gen3-adas/recipes-kernel/linux/linux-renesas/0412-media-i2c-soc_camera-differenciate-max9286-and-max92.patch351
-rw-r--r--bsp/meta-rcar/meta-rcar-gen3-adas/recipes-kernel/linux/linux-renesas/0413-media-i2c-max9288-fix-stream-on-off.patch57
-rw-r--r--bsp/meta-rcar/meta-rcar-gen3-adas/recipes-kernel/linux/linux-renesas/0414-gpio-pca953x-do-not-ignore-i2c-errors.patch33
-rw-r--r--bsp/meta-rcar/meta-rcar-gen3-adas/recipes-kernel/linux/linux-renesas/0415-usb-host-xhci-rcar-Add-XHCI_TRUST_TX_LENGTH-quirk.patch37
-rw-r--r--bsp/meta-rcar/meta-rcar-gen3-adas/recipes-kernel/linux/linux-renesas/0416-arm64-dtb-renesas-vb2.1-enable-usb2-channel-3.patch55
-rw-r--r--bsp/meta-rcar/meta-rcar-gen3-adas/recipes-kernel/linux/linux-renesas/0417-USB-tusb8041-add-simple-driver-to-start-device-over-.patch288
-rw-r--r--bsp/meta-rcar/meta-rcar-gen3-adas/recipes-kernel/linux/linux-renesas/0418-arm64-dts-renesas-ulcb-vb2-fix-USB30-and-HUB.patch116
-rw-r--r--bsp/meta-rcar/meta-rcar-gen3-adas/recipes-kernel/linux/linux-renesas/0419-phy-rcar-gen3-usb2-power-on-port-in-host-mode-to.patch62
-rw-r--r--bsp/meta-rcar/meta-rcar-gen3-adas/recipes-kernel/linux/linux-renesas/cma.cfg2
-rw-r--r--bsp/meta-rcar/meta-rcar-gen3-adas/recipes-kernel/linux/linux-renesas/condor.cfg34
-rw-r--r--bsp/meta-rcar/meta-rcar-gen3-adas/recipes-kernel/linux/linux-renesas/disable-unused.cfg33
-rw-r--r--bsp/meta-rcar/meta-rcar-gen3-adas/recipes-kernel/linux/linux-renesas/eagle.cfg35
-rw-r--r--bsp/meta-rcar/meta-rcar-gen3-adas/recipes-kernel/linux/linux-renesas/hyperflash.cfg2
-rw-r--r--bsp/meta-rcar/meta-rcar-gen3-adas/recipes-kernel/linux/linux-renesas/imr.cfg3
-rw-r--r--bsp/meta-rcar/meta-rcar-gen3-adas/recipes-kernel/linux/linux-renesas/nvme.cfg2
-rw-r--r--bsp/meta-rcar/meta-rcar-gen3-adas/recipes-kernel/linux/linux-renesas/qspi.cfg3
-rw-r--r--bsp/meta-rcar/meta-rcar-gen3-adas/recipes-kernel/linux/linux-renesas/renesas-not-applied.scc16
-rw-r--r--bsp/meta-rcar/meta-rcar-gen3-adas/recipes-kernel/linux/linux-renesas/renesas.scc357
-rw-r--r--bsp/meta-rcar/meta-rcar-gen3-adas/recipes-kernel/linux/linux-renesas/salvator-x.cfg27
-rw-r--r--bsp/meta-rcar/meta-rcar-gen3-adas/recipes-kernel/linux/linux-renesas/sdhi_seq.cfg2
-rw-r--r--bsp/meta-rcar/meta-rcar-gen3-adas/recipes-kernel/linux/linux-renesas/ulcb.cfg87
-rw-r--r--bsp/meta-rcar/meta-rcar-gen3-adas/recipes-kernel/linux/linux-renesas/v3hsk.cfg43
-rw-r--r--bsp/meta-rcar/meta-rcar-gen3-adas/recipes-kernel/linux/linux-renesas/v3msk.cfg39
-rw-r--r--bsp/meta-rcar/meta-rcar-gen3-adas/recipes-kernel/linux/linux-renesas/v3mzf.cfg25
-rw-r--r--bsp/meta-rcar/meta-rcar-gen3-adas/recipes-kernel/linux/linux-renesas_4.14.bbappend134
398 files changed, 132088 insertions, 0 deletions
diff --git a/bsp/meta-rcar/meta-rcar-gen3-adas/recipes-kernel/linux/linux-renesas/0001-spi-sh-msiof-fixes.patch b/bsp/meta-rcar/meta-rcar-gen3-adas/recipes-kernel/linux/linux-renesas/0001-spi-sh-msiof-fixes.patch
new file mode 100644
index 00000000..2e75272a
--- /dev/null
+++ b/bsp/meta-rcar/meta-rcar-gen3-adas/recipes-kernel/linux/linux-renesas/0001-spi-sh-msiof-fixes.patch
@@ -0,0 +1,33 @@
+From 7fcc40a9b19ca41bf140eb9ebe9a7dbd5871b54e Mon Sep 17 00:00:00 2001
+From: Vladimir Barinov <vladimir.barinov@cogentembedded.com>
+Date: Sun, 15 May 2016 21:53:13 +0300
+Subject: [PATCH 001/122] spi: sh-msiof: fixes
+
+speed up polling of CTR register
+
+Signed-off-by: Vladimir Barinov <vladimir.barinov@cogentembedded.com>
+---
+ drivers/spi/spi-sh-msiof.c | 4 ++--
+ 1 file changed, 2 insertions(+), 2 deletions(-)
+
+diff --git a/drivers/spi/spi-sh-msiof.c b/drivers/spi/spi-sh-msiof.c
+index d32e631..6a27bca 100644
+--- a/drivers/spi/spi-sh-msiof.c
++++ b/drivers/spi/spi-sh-msiof.c
+@@ -253,11 +253,11 @@ static int sh_msiof_modify_ctr_wait(struct sh_msiof_spi_priv *p,
+ data |= set;
+ sh_msiof_write(p, CTR, data);
+
+- for (k = 100; k > 0; k--) {
++ for (k = 1000; k > 0; k--) {
+ if ((sh_msiof_read(p, CTR) & mask) == set)
+ break;
+
+- udelay(10);
++ udelay(1);
+ }
+
+ return k > 0 ? 0 : -ETIMEDOUT;
+--
+2.7.4
+
diff --git a/bsp/meta-rcar/meta-rcar-gen3-adas/recipes-kernel/linux/linux-renesas/0002-spi-spidev-add-spi-gpio-into-spidev.patch b/bsp/meta-rcar/meta-rcar-gen3-adas/recipes-kernel/linux/linux-renesas/0002-spi-spidev-add-spi-gpio-into-spidev.patch
new file mode 100644
index 00000000..f3da1092
--- /dev/null
+++ b/bsp/meta-rcar/meta-rcar-gen3-adas/recipes-kernel/linux/linux-renesas/0002-spi-spidev-add-spi-gpio-into-spidev.patch
@@ -0,0 +1,27 @@
+From 3130e4c0eed99cafc5e2431e7a7bbc0f85398aec Mon Sep 17 00:00:00 2001
+From: Vladimir Barinov <vladimir.barinov@cogentembedded.com>
+Date: Sun, 15 May 2016 21:47:02 +0300
+Subject: [PATCH 002/122] spi: spidev: add spi-gpio into spidev
+
+Add spi-gpio to spidev
+
+Signed-off-by: Vladimir Barinov <vladimir.barinov@cogentembedded.com>
+---
+ drivers/spi/spidev.c | 1 +
+ 1 file changed, 1 insertion(+)
+
+diff --git a/drivers/spi/spidev.c b/drivers/spi/spidev.c
+index cda1071..788d2d6 100644
+--- a/drivers/spi/spidev.c
++++ b/drivers/spi/spidev.c
+@@ -669,6 +669,7 @@ static const struct of_device_id spidev_dt_ids[] = {
+ { .compatible = "lineartechnology,ltc2488" },
+ { .compatible = "ge,achc" },
+ { .compatible = "semtech,sx1301" },
++ { .compatible = "spi-gpio" },
+ {},
+ };
+ MODULE_DEVICE_TABLE(of, spidev_dt_ids);
+--
+2.7.4
+
diff --git a/bsp/meta-rcar/meta-rcar-gen3-adas/recipes-kernel/linux/linux-renesas/0003-spi-spi-gpio-fix-CPOL-mode.patch b/bsp/meta-rcar/meta-rcar-gen3-adas/recipes-kernel/linux/linux-renesas/0003-spi-spi-gpio-fix-CPOL-mode.patch
new file mode 100644
index 00000000..a9f69be8
--- /dev/null
+++ b/bsp/meta-rcar/meta-rcar-gen3-adas/recipes-kernel/linux/linux-renesas/0003-spi-spi-gpio-fix-CPOL-mode.patch
@@ -0,0 +1,42 @@
+From 9995ac251006b1ca4989c009129e13ecac8b3e50 Mon Sep 17 00:00:00 2001
+From: Vladimir Barinov <vladimir.barinov@cogentembedded.com>
+Date: Sun, 29 May 2016 23:18:49 +0300
+Subject: [PATCH 003/122] spi: spi-gpio: fix CPOL mode
+
+This fixes the SPI SPOL mode, since the cs_gpios is already used
+in generic code spi.c
+
+Signed-off-by: Vladimir Barinov <vladimir.barinov@cogentembedded.com>
+---
+ drivers/spi/spi-gpio.c | 8 ++++----
+ 1 file changed, 4 insertions(+), 4 deletions(-)
+
+diff --git a/drivers/spi/spi-gpio.c b/drivers/spi/spi-gpio.c
+index 1c34c93..6e60521 100644
+--- a/drivers/spi/spi-gpio.c
++++ b/drivers/spi/spi-gpio.c
+@@ -218,10 +218,6 @@ static void spi_gpio_chipselect(struct spi_device *spi, int is_active)
+ struct spi_gpio *spi_gpio = spi_to_spi_gpio(spi);
+ unsigned long cs = spi_gpio->cs_gpios[spi->chip_select];
+
+- /* set initial clock polarity */
+- if (is_active)
+- setsck(spi, spi->mode & SPI_CPOL);
+-
+ if (cs != SPI_GPIO_NO_CHIPSELECT) {
+ /* SPI is normally active-low */
+ gpio_set_value_cansleep(cs, (spi->mode & SPI_CS_HIGH) ? is_active : !is_active);
+@@ -257,6 +253,10 @@ static int spi_gpio_setup(struct spi_device *spi)
+ !(spi->mode & SPI_CS_HIGH));
+ }
+ }
++
++ /* set initial clock polarity */
++ setsck(spi, spi->mode & SPI_CPOL);
++
+ if (!status) {
+ /* in case it was initialized from static board data */
+ spi_gpio->cs_gpios[spi->chip_select] = cs;
+--
+2.7.4
+
diff --git a/bsp/meta-rcar/meta-rcar-gen3-adas/recipes-kernel/linux/linux-renesas/0006-spi-spi-gpio-fix-set-CPOL-default-inverted.patch b/bsp/meta-rcar/meta-rcar-gen3-adas/recipes-kernel/linux/linux-renesas/0006-spi-spi-gpio-fix-set-CPOL-default-inverted.patch
new file mode 100644
index 00000000..45da60a7
--- /dev/null
+++ b/bsp/meta-rcar/meta-rcar-gen3-adas/recipes-kernel/linux/linux-renesas/0006-spi-spi-gpio-fix-set-CPOL-default-inverted.patch
@@ -0,0 +1,30 @@
+From c6a4047e20e95dd01e0c5ec629b77a50b3bc73d0 Mon Sep 17 00:00:00 2001
+From: Vladimir Barinov <vladimir.barinov@cogentembedded.com>
+Date: Sun, 29 May 2016 23:18:49 +0300
+Subject: [PATCH 004/122] spi: spi-gpio: set CPOL default inverted
+
+Workaround:
+ Set default value at probe to 1 due to issue with H3ULCB.HAD FPGA
+ ethernet switch
+
+Signed-off-by: Vladimir Barinov <vladimir.barinov@cogentembedded.com>
+---
+ drivers/spi/spi-gpio.c | 2 +-
+ 1 file changed, 1 insertion(+), 1 deletion(-)
+
+diff --git a/drivers/spi/spi-gpio.c b/drivers/spi/spi-gpio.c
+index 6e60521..428417d 100644
+--- a/drivers/spi/spi-gpio.c
++++ b/drivers/spi/spi-gpio.c
+@@ -289,7 +289,7 @@ static int spi_gpio_alloc(unsigned pin, const char *label, bool is_in)
+ if (is_in)
+ value = gpio_direction_input(pin);
+ else
+- value = gpio_direction_output(pin, 0);
++ value = gpio_direction_output(pin, 1);
+ }
+ return value;
+ }
+--
+2.7.4
+
diff --git a/bsp/meta-rcar/meta-rcar-gen3-adas/recipes-kernel/linux/linux-renesas/0008-Revert-PCI-rcar-pcie-Add-bus-notifier-so-we-can-limi.patch b/bsp/meta-rcar/meta-rcar-gen3-adas/recipes-kernel/linux/linux-renesas/0008-Revert-PCI-rcar-pcie-Add-bus-notifier-so-we-can-limi.patch
new file mode 100644
index 00000000..83f5cbbb
--- /dev/null
+++ b/bsp/meta-rcar/meta-rcar-gen3-adas/recipes-kernel/linux/linux-renesas/0008-Revert-PCI-rcar-pcie-Add-bus-notifier-so-we-can-limi.patch
@@ -0,0 +1,59 @@
+From d01c738d46c186bd58b9314d348e5897ef1fd344 Mon Sep 17 00:00:00 2001
+From: Nikita Yushchenko <nikita.yoush@cogentembedded.com>
+Date: Sun, 24 Jun 2018 17:56:22 +0300
+Subject: [PATCH 005/122] Revert "PCI: rcar-pcie: Add bus notifier so we can
+ limit the dma range"
+
+This reverts commit 56c039c504f32e68e2e8decbf01ea34d7f7ee03e.
+
+Resetting dma_mask this way is racy. If driver configures 64-bit
+dma_mask in it's probe method and then immediately issues I/O, this
+will be handled with dma_mask set to 64-bit.
+
+Thus different workaround is needed, and this workaround must be
+reverted.
+
+Signed-off-by: Nikita Yushchenko <nikita.yoush@cogentembedded.com>
+---
+ drivers/pci/host/pcie-rcar.c | 28 ----------------------------
+ 1 file changed, 28 deletions(-)
+
+diff --git a/drivers/pci/host/pcie-rcar.c b/drivers/pci/host/pcie-rcar.c
+index 3679e8e..46b2622 100644
+--- a/drivers/pci/host/pcie-rcar.c
++++ b/drivers/pci/host/pcie-rcar.c
+@@ -1377,31 +1377,3 @@ static struct platform_driver rcar_pcie_driver = {
+ .probe = rcar_pcie_probe,
+ };
+ builtin_platform_driver(rcar_pcie_driver);
+-
+-static int rcar_pcie_pci_notifier(struct notifier_block *nb,
+- unsigned long action, void *data)
+-{
+- struct device *dev = data;
+-
+- switch (action) {
+- case BUS_NOTIFY_BOUND_DRIVER:
+- /* Force the DMA mask to lower 32-bits */
+- dma_set_mask_and_coherent(dev, DMA_BIT_MASK(32));
+- break;
+- default:
+- return NOTIFY_DONE;
+- }
+-
+- return NOTIFY_OK;
+-}
+-
+-static struct notifier_block device_nb = {
+- .notifier_call = rcar_pcie_pci_notifier,
+-};
+-
+-static int __init register_rcar_pcie_pci_notifier(void)
+-{
+- return bus_register_notifier(&pci_bus_type, &device_nb);
+-}
+-
+-arch_initcall(register_rcar_pcie_pci_notifier);
+--
+2.7.4
+
diff --git a/bsp/meta-rcar/meta-rcar-gen3-adas/recipes-kernel/linux/linux-renesas/0009-arm64-dma-check-parent-bus-restrictions-in-dma_capab.patch b/bsp/meta-rcar/meta-rcar-gen3-adas/recipes-kernel/linux/linux-renesas/0009-arm64-dma-check-parent-bus-restrictions-in-dma_capab.patch
new file mode 100644
index 00000000..7aa80114
--- /dev/null
+++ b/bsp/meta-rcar/meta-rcar-gen3-adas/recipes-kernel/linux/linux-renesas/0009-arm64-dma-check-parent-bus-restrictions-in-dma_capab.patch
@@ -0,0 +1,94 @@
+From 98081ba7f59438b1c8f9176b5467b924b9b392f5 Mon Sep 17 00:00:00 2001
+From: Nikita Yushchenko <nikita.yoush@cogentembedded.com>
+Date: Sun, 24 Jun 2018 18:04:23 +0300
+Subject: [PATCH 006/122] arm64: dma: check parent bus restrictions in
+ dma_capable()
+
+It may happen that although hardware device is capable of full 64-bit
+addressing in DMA operations, way device is connected to the system
+imposes addressing limitations. Example: NVMe device connected to PCIe
+host sitting on AXI bus with 32-bit addressing (and no iommu configured).
+
+There is no agreement on setting dma_mask in this case. For low level,
+dma_mask must be 32-bit - that's what hardware provides for software.
+But for higher level, dma_mask must be 64-bit - that's what platform
+(hardware + swiotlb) provides for higher levels.
+
+dma_capable() is swiotlb's check if current address is DMAable by device
+directly or swiotlb should provide bounce buffer for it. Using dma_mask
+in dma_capable() assumes that dma_mask is set for low level - which does
+not always match reality.
+
+This patch changes dma_capable() to check additional restrictions.
+
+It is a workaround against ambiguous dma_mask semantics.
+
+Signed-off-by: Nikita Yushchenko <nikita.yoush@cogentembedded.com>
+---
+ arch/arm64/include/asm/device.h | 1 +
+ arch/arm64/include/asm/dma-mapping.h | 9 ++++++++-
+ arch/arm64/mm/dma-mapping.c | 13 ++++++++++++-
+ 3 files changed, 21 insertions(+), 2 deletions(-)
+
+diff --git a/arch/arm64/include/asm/device.h b/arch/arm64/include/asm/device.h
+index 5a5fa47..ac3eb0c 100644
+--- a/arch/arm64/include/asm/device.h
++++ b/arch/arm64/include/asm/device.h
+@@ -24,6 +24,7 @@ struct dev_archdata {
+ const struct dma_map_ops *dev_dma_ops;
+ #endif
+ bool dma_coherent;
++ u64 parent_dma_mask;
+ };
+
+ struct pdev_archdata {
+diff --git a/arch/arm64/include/asm/dma-mapping.h b/arch/arm64/include/asm/dma-mapping.h
+index 0df756b..15edb0c 100644
+--- a/arch/arm64/include/asm/dma-mapping.h
++++ b/arch/arm64/include/asm/dma-mapping.h
+@@ -66,10 +66,17 @@ static inline phys_addr_t dma_to_phys(struct device *dev, dma_addr_t dev_addr)
+
+ static inline bool dma_capable(struct device *dev, dma_addr_t addr, size_t size)
+ {
++ u64 mask;
++
+ if (!dev->dma_mask)
+ return false;
+
+- return addr + size - 1 <= *dev->dma_mask;
++ mask = *dev->dma_mask;
++ if (dev->archdata.parent_dma_mask &&
++ mask > dev->archdata.parent_dma_mask)
++ mask = dev->archdata.parent_dma_mask;
++
++ return addr + size - 1 <= mask;
+ }
+
+ static inline void dma_mark_clean(void *addr, size_t size)
+diff --git a/arch/arm64/mm/dma-mapping.c b/arch/arm64/mm/dma-mapping.c
+index 58470b1..c9c1892 100644
+--- a/arch/arm64/mm/dma-mapping.c
++++ b/arch/arm64/mm/dma-mapping.c
+@@ -928,7 +928,18 @@ void arch_setup_dma_ops(struct device *dev, u64 dma_base, u64 size,
+ dev->dma_ops = &swiotlb_dma_ops;
+
+ dev->archdata.dma_coherent = coherent;
+- __iommu_setup_dma_ops(dev, dma_base, size, iommu);
++
++ if (!iommu) {
++ /*
++ * we don't yet support buses that have a non-zero mapping.
++ * Let's hope we won't need it
++ */
++ WARN_ON(dma_base != 0);
++
++ /* save parent_dma_mask for swiotlb's dma_capable() */
++ dev->archdata.parent_dma_mask = size - 1;
++ } else
++ __iommu_setup_dma_ops(dev, dma_base, size, iommu);
+
+ #ifdef CONFIG_XEN
+ if (xen_initial_domain()) {
+--
+2.7.4
+
diff --git a/bsp/meta-rcar/meta-rcar-gen3-adas/recipes-kernel/linux/linux-renesas/0010-can-rcar_can-add-enable-and-standby-control-pins.patch b/bsp/meta-rcar/meta-rcar-gen3-adas/recipes-kernel/linux/linux-renesas/0010-can-rcar_can-add-enable-and-standby-control-pins.patch
new file mode 100644
index 00000000..a9b9fdc4
--- /dev/null
+++ b/bsp/meta-rcar/meta-rcar-gen3-adas/recipes-kernel/linux/linux-renesas/0010-can-rcar_can-add-enable-and-standby-control-pins.patch
@@ -0,0 +1,156 @@
+From ff03f1075bd445d1dbb5bb087c8d8d3f3b29a025 Mon Sep 17 00:00:00 2001
+From: Vladimir Barinov <vladimir.barinov@cogentembedded.com>
+Date: Mon, 2 May 2016 22:05:53 +0300
+Subject: [PATCH 007/122] can: rcar_can: add enable and standby control pins
+
+Add enable and standby can transceiver control pins
+
+Signed-off-by: Vladimir Barinov <vladimir.barinov@cogentembedded.com>
+---
+ .../devicetree/bindings/net/can/rcar_can.txt | 4 ++
+ drivers/net/can/rcar/rcar_can.c | 58 +++++++++++++++++-----
+ include/linux/can/platform/rcar_can.h | 2 +
+ 3 files changed, 51 insertions(+), 13 deletions(-)
+
+diff --git a/Documentation/devicetree/bindings/net/can/rcar_can.txt b/Documentation/devicetree/bindings/net/can/rcar_can.txt
+index 94a7f33..5860349 100644
+--- a/Documentation/devicetree/bindings/net/can/rcar_can.txt
++++ b/Documentation/devicetree/bindings/net/can/rcar_can.txt
+@@ -43,6 +43,7 @@ Optional properties:
+ <0x0> (default) : Peripheral clock (clkp1)
+ <0x1> : Peripheral clock (clkp2)
+ <0x3> : Externally input clock
++- gpios: GPIO used for controlling the enable pin and standby pin
+
+ Example
+ -------
+@@ -64,5 +65,8 @@ Board specific .dts file:
+ &can0 {
+ pinctrl-0 = <&can0_pins>;
+ pinctrl-names = "default";
++ gpios = <&gpio5 29 GPIO_ACTIVE_HIGH /* enable */
++ &gpio5 30 GPIO_ACTIVE_LOW /* standby */
++ >;
+ status = "okay";
+ };
+diff --git a/drivers/net/can/rcar/rcar_can.c b/drivers/net/can/rcar/rcar_can.c
+index 11662f4..8d2c709 100644
+--- a/drivers/net/can/rcar/rcar_can.c
++++ b/drivers/net/can/rcar/rcar_can.c
+@@ -21,6 +21,7 @@
+ #include <linux/clk.h>
+ #include <linux/can/platform/rcar_can.h>
+ #include <linux/of.h>
++#include <linux/of_gpio.h>
+
+ #define RCAR_CAN_DRV_NAME "rcar_can"
+
+@@ -94,6 +95,8 @@ struct rcar_can_priv {
+ u32 tx_tail;
+ u8 clock_select;
+ u8 ier;
++ unsigned int enable_pin; /* transceiver enable */
++ unsigned int standby_pin; /* transceiver standby */
+ };
+
+ static const struct can_bittiming_const rcar_can_bittiming_const = {
+@@ -505,6 +508,10 @@ static int rcar_can_open(struct net_device *ndev)
+ struct rcar_can_priv *priv = netdev_priv(ndev);
+ int err;
+
++ /* transceiver normal mode */
++ if (gpio_is_valid(priv->standby_pin))
++ gpio_set_value(priv->standby_pin, 1);
++
+ err = clk_prepare_enable(priv->clk);
+ if (err) {
+ netdev_err(ndev,
+@@ -581,6 +588,9 @@ static int rcar_can_close(struct net_device *ndev)
+ clk_disable_unprepare(priv->clk);
+ close_candev(ndev);
+ can_led_event(ndev, CAN_LED_EVENT_STOP);
++ /* transceiver stanby mode */
++ if (gpio_is_valid(priv->standby_pin))
++ gpio_set_value(priv->standby_pin, 0);
+ return 0;
+ }
+
+@@ -743,20 +753,9 @@ static int rcar_can_probe(struct platform_device *pdev)
+ struct resource *mem;
+ void __iomem *addr;
+ u32 clock_select = CLKR_CLKP1;
+- int err = -ENODEV;
++ int err = -ENODEV, ret;
+ int irq;
+-
+- if (pdev->dev.of_node) {
+- of_property_read_u32(pdev->dev.of_node,
+- "renesas,can-clock-select", &clock_select);
+- } else {
+- pdata = dev_get_platdata(&pdev->dev);
+- if (!pdata) {
+- dev_err(&pdev->dev, "No platform data provided!\n");
+- goto fail;
+- }
+- clock_select = pdata->clock_select;
+- }
++ enum of_gpio_flags enable_flags, standby_flags;
+
+ irq = platform_get_irq(pdev, 0);
+ if (irq < 0) {
+@@ -826,6 +825,39 @@ static int rcar_can_probe(struct platform_device *pdev)
+
+ devm_can_led_init(ndev);
+
++ if (pdev->dev.of_node) {
++ of_property_read_u32(pdev->dev.of_node,
++ "renesas,can-clock-select", &clock_select);
++ priv->enable_pin = of_get_gpio_flags(pdev->dev.of_node, 0, &enable_flags);
++ priv->standby_pin = of_get_gpio_flags(pdev->dev.of_node, 1, &standby_flags);
++ } else {
++ pdata = dev_get_platdata(&pdev->dev);
++ if (!pdata) {
++ dev_err(&pdev->dev, "No platform data provided!\n");
++ goto fail;
++ }
++ clock_select = pdata->clock_select;
++ priv->enable_pin = pdata->enable_pin;
++ priv->standby_pin = pdata->standby_pin;
++ }
++
++ if (gpio_is_valid(priv->enable_pin)) {
++ int val = enable_flags & OF_GPIO_ACTIVE_LOW ?
++ GPIOF_OUT_INIT_LOW : GPIOF_OUT_INIT_HIGH;
++ ret = devm_gpio_request_one(&pdev->dev, priv->enable_pin, val, "enable");
++ if (ret)
++ dev_info(&pdev->dev, "Failed to request enable pin\n");
++ }
++
++ if (gpio_is_valid(priv->standby_pin)) {
++ int val = standby_flags & OF_GPIO_ACTIVE_LOW ?
++ GPIOF_OUT_INIT_LOW : GPIOF_OUT_INIT_HIGH;
++ /* transceiver standby mode */
++ ret = devm_gpio_request_one(&pdev->dev, priv->standby_pin, val, "standby");
++ if (ret)
++ dev_info(&pdev->dev, "Failed to request standby pin\n");
++ }
++
+ dev_info(&pdev->dev, "device registered (IRQ%d)\n", ndev->irq);
+
+ return 0;
+diff --git a/include/linux/can/platform/rcar_can.h b/include/linux/can/platform/rcar_can.h
+index a43dcd0..8f23659 100644
+--- a/include/linux/can/platform/rcar_can.h
++++ b/include/linux/can/platform/rcar_can.h
+@@ -13,6 +13,8 @@ enum CLKR {
+
+ struct rcar_can_platform_data {
+ enum CLKR clock_select; /* Clock source select */
++ unsigned int enable_pin;
++ unsigned int standby_pin;
+ };
+
+ #endif /* !_CAN_PLATFORM_RCAR_CAN_H_ */
+--
+2.7.4
+
diff --git a/bsp/meta-rcar/meta-rcar-gen3-adas/recipes-kernel/linux/linux-renesas/0011-can-rcar_canfd-add-enable-and-standby-control-pins.patch b/bsp/meta-rcar/meta-rcar-gen3-adas/recipes-kernel/linux/linux-renesas/0011-can-rcar_canfd-add-enable-and-standby-control-pins.patch
new file mode 100644
index 00000000..bdcd4054
--- /dev/null
+++ b/bsp/meta-rcar/meta-rcar-gen3-adas/recipes-kernel/linux/linux-renesas/0011-can-rcar_canfd-add-enable-and-standby-control-pins.patch
@@ -0,0 +1,119 @@
+From e22e679c7dc63204157d70e04df1fc23cb5b009f Mon Sep 17 00:00:00 2001
+From: Vladimir Barinov <vladimir.barinov@cogentembedded.com>
+Date: Mon, 30 May 2016 01:51:47 +0300
+Subject: [PATCH 008/122] can: rcar_canfd: add enable and standby control pins
+
+Add enable and standby can transceiver control pins
+
+Signed-off-by: Vladimir Barinov <vladimir.barinov@cogentembedded.com>
+---
+ .../devicetree/bindings/net/can/rcar_canfd.txt | 5 ++++
+ drivers/net/can/rcar/rcar_canfd.c | 33 +++++++++++++++++++++-
+ 2 files changed, 37 insertions(+), 1 deletion(-)
+
+diff --git a/Documentation/devicetree/bindings/net/can/rcar_canfd.txt b/Documentation/devicetree/bindings/net/can/rcar_canfd.txt
+index ac71daa..829604a 100644
+--- a/Documentation/devicetree/bindings/net/can/rcar_canfd.txt
++++ b/Documentation/devicetree/bindings/net/can/rcar_canfd.txt
+@@ -19,6 +19,7 @@ Required properties:
+ - clock-names: 3 clock input name strings: "fck", "canfd", "can_clk".
+ - pinctrl-0: pin control group to be used for this controller.
+ - pinctrl-names: must be "default".
++- gpios: GPIO used for controlling the enable pin and standby pin
+
+ Required child nodes:
+ The controller supports two channels and each is represented as a child node.
+@@ -62,6 +63,10 @@ SoC common .dtsi file:
+ power-domains = <&cpg>;
+ status = "disabled";
+
++ gpios = <&gpio5 29 GPIO_ACTIVE_HIGH /* enable */
++ &gpio5 30 GPIO_ACTIVE_LOW /* standby */
++ >;
++
+ channel0 {
+ status = "disabled";
+ };
+diff --git a/drivers/net/can/rcar/rcar_canfd.c b/drivers/net/can/rcar/rcar_canfd.c
+index 602c19e..5b98f8c 100644
+--- a/drivers/net/can/rcar/rcar_canfd.c
++++ b/drivers/net/can/rcar/rcar_canfd.c
+@@ -38,6 +38,7 @@
+ #include <linux/clk.h>
+ #include <linux/of.h>
+ #include <linux/of_device.h>
++#include <linux/of_gpio.h>
+ #include <linux/bitmap.h>
+ #include <linux/bitops.h>
+ #include <linux/iopoll.h>
+@@ -517,6 +518,8 @@ struct rcar_canfd_global {
+ enum rcar_canfd_fcanclk fcan; /* CANFD or Ext clock */
+ unsigned long channels_mask; /* Enabled channels mask */
+ bool fdmode; /* CAN FD or Classical CAN only mode */
++ unsigned int enable_pin; /* transceiver enable */
++ unsigned int standby_pin; /* transceiver standby */
+ };
+
+ /* CAN FD mode nominal rate constants */
+@@ -1268,6 +1271,10 @@ static int rcar_canfd_open(struct net_device *ndev)
+ struct rcar_canfd_global *gpriv = priv->gpriv;
+ int err;
+
++ /* transceiver normal mode */
++ if (gpio_is_valid(gpriv->standby_pin))
++ gpio_set_value(gpriv->standby_pin, 1);
++
+ /* Peripheral clock is already enabled in probe */
+ err = clk_prepare_enable(gpriv->can_clk);
+ if (err) {
+@@ -1336,6 +1343,9 @@ static int rcar_canfd_close(struct net_device *ndev)
+ clk_disable_unprepare(gpriv->can_clk);
+ close_candev(ndev);
+ can_led_event(ndev, CAN_LED_EVENT_STOP);
++ /* transceiver stanby mode */
++ if (gpio_is_valid(gpriv->standby_pin))
++ gpio_set_value(gpriv->standby_pin, 0);
+ return 0;
+ }
+
+@@ -1639,8 +1649,9 @@ static int rcar_canfd_probe(struct platform_device *pdev)
+ struct rcar_canfd_global *gpriv;
+ struct device_node *of_child;
+ unsigned long channels_mask = 0;
+- int err, ch_irq, g_irq;
++ int err, ret, ch_irq, g_irq;
+ bool fdmode = true; /* CAN FD only mode - default */
++ enum of_gpio_flags enable_flags, standby_flags;
+
+ if (of_property_read_bool(pdev->dev.of_node, "renesas,no-can-fd"))
+ fdmode = false; /* Classical CAN only mode */
+@@ -1785,6 +1796,26 @@ static int rcar_canfd_probe(struct platform_device *pdev)
+ goto fail_channel;
+ }
+
++ gpriv->enable_pin = of_get_gpio_flags(pdev->dev.of_node, 0, &enable_flags);
++ gpriv->standby_pin = of_get_gpio_flags(pdev->dev.of_node, 1, &standby_flags);
++
++ if (gpio_is_valid(gpriv->enable_pin)) {
++ int val = enable_flags & OF_GPIO_ACTIVE_LOW ?
++ GPIOF_OUT_INIT_LOW : GPIOF_OUT_INIT_HIGH;
++ ret = devm_gpio_request_one(&pdev->dev, gpriv->enable_pin, val, "enable");
++ if (ret)
++ dev_info(&pdev->dev, "Failed to request enable pin\n");
++ }
++
++ if (gpio_is_valid(gpriv->standby_pin)) {
++ int val = standby_flags & OF_GPIO_ACTIVE_LOW ?
++ GPIOF_OUT_INIT_LOW : GPIOF_OUT_INIT_HIGH;
++ /* transceiver standby mode */
++ ret = devm_gpio_request_one(&pdev->dev, gpriv->standby_pin, val, "standby");
++ if (ret)
++ dev_info(&pdev->dev, "Failed to request standby pin\n");
++ }
++
+ platform_set_drvdata(pdev, gpriv);
+ dev_info(&pdev->dev, "global operational state (clk %d, fdmode %d)\n",
+ gpriv->fcan, gpriv->fdmode);
+--
+2.7.4
+
diff --git a/bsp/meta-rcar/meta-rcar-gen3-adas/recipes-kernel/linux/linux-renesas/0012-mtd-Add-RPC-HyperFlash-driver.patch b/bsp/meta-rcar/meta-rcar-gen3-adas/recipes-kernel/linux/linux-renesas/0012-mtd-Add-RPC-HyperFlash-driver.patch
new file mode 100644
index 00000000..ccf9216e
--- /dev/null
+++ b/bsp/meta-rcar/meta-rcar-gen3-adas/recipes-kernel/linux/linux-renesas/0012-mtd-Add-RPC-HyperFlash-driver.patch
@@ -0,0 +1,1028 @@
+From 86cb4077ff3911412e1452de00e2e0c61ad79395 Mon Sep 17 00:00:00 2001
+From: Valentine Barshak <valentine.barshak@cogentembedded.com>
+Date: Fri, 3 Jun 2016 23:04:20 +0300
+Subject: [PATCH 009/122] mtd: Add RPC HyperFlash driver
+
+This adds RPC HyperFlash driver.
+
+Signed-off-by: Valentine Barshak <valentine.barshak@cogentembedded.com>
+---
+ drivers/mtd/Kconfig | 5 +
+ drivers/mtd/Makefile | 1 +
+ drivers/mtd/rpc_hyperflash.c | 976 +++++++++++++++++++++++++++++++++++++++++++
+ 3 files changed, 982 insertions(+)
+ create mode 100644 drivers/mtd/rpc_hyperflash.c
+
+diff --git a/drivers/mtd/Kconfig b/drivers/mtd/Kconfig
+index 5a2d717..0619e1f 100644
+--- a/drivers/mtd/Kconfig
++++ b/drivers/mtd/Kconfig
+@@ -11,6 +11,11 @@ menuconfig MTD
+ particular hardware and users of MTD devices. If unsure, say N.
+
+ if MTD
++config MTD_RPC_HYPERFLASH
++ tristate "MTD Renesas R-Car Gen3 RPC HyperFlash"
++ depends on ARCH_R8A7795
++ ---help---
++ This option includes Renesas R-Car Gen3 RPC HyperFlash support.
+
+ config MTD_TESTS
+ tristate "MTD tests support (DANGEROUS)"
+diff --git a/drivers/mtd/Makefile b/drivers/mtd/Makefile
+index d6f8f62..f3fb2b0 100644
+--- a/drivers/mtd/Makefile
++++ b/drivers/mtd/Makefile
+@@ -15,6 +15,7 @@ obj-$(CONFIG_MTD_AR7_PARTS) += ar7part.o
+ obj-$(CONFIG_MTD_BCM63XX_PARTS) += bcm63xxpart.o
+ obj-$(CONFIG_MTD_BCM47XX_PARTS) += bcm47xxpart.o
+ obj-y += parsers/
++obj-$(CONFIG_MTD_RPC_HYPERFLASH) += rpc_hyperflash.o
+
+ # 'Users' - code which presents functionality to userspace.
+ obj-$(CONFIG_MTD_BLKDEVS) += mtd_blkdevs.o
+diff --git a/drivers/mtd/rpc_hyperflash.c b/drivers/mtd/rpc_hyperflash.c
+new file mode 100644
+index 0000000..cf4d56e
+--- /dev/null
++++ b/drivers/mtd/rpc_hyperflash.c
+@@ -0,0 +1,976 @@
++/*
++ * Linux driver for R-Car Gen3 RPC HyperFlash
++ *
++ * Copyright (C) 2016 Renesas Electronics Corporation
++ * Copyright (C) 2016 Cogent Embedded, Inc.
++ *
++ * This program is free software; you can redistribute it and/or modify
++ * it under the terms of the GNU General Public License version 2 as
++ * published by the Free Software Foundation.
++ */
++
++#include <linux/delay.h>
++#include <linux/io.h>
++#include <linux/module.h>
++#include <linux/mtd/mtd.h>
++#include <linux/mtd/partitions.h>
++#include <linux/of.h>
++#include <linux/rwsem.h>
++#include <linux/slab.h>
++
++/* RPC */
++#define RPC_BASE 0xEE200000
++#define RPC_SIZE 0x8100
++#define RPC_FLASH_BASE 0x08000000
++#define RPC_FLASH_SIZE 0x04000000
++
++#define RPC_CMNCR 0x0000 /* R/W */
++#define RPC_CMNCR_MD (0x1 << 31)
++#define RPC_CMNCR_MOIIO0(val) (((val) & 0x3) << 16)
++#define RPC_CMNCR_MOIIO1(val) (((val) & 0x3) << 18)
++#define RPC_CMNCR_MOIIO2(val) (((val) & 0x3) << 20)
++#define RPC_CMNCR_MOIIO3(val) (((val) & 0x3) << 22)
++#define RPC_CMNCR_MOIIO_HIZ (RPC_CMNCR_MOIIO0(3) | RPC_CMNCR_MOIIO1(3) | \
++ RPC_CMNCR_MOIIO2(3) | RPC_CMNCR_MOIIO3(3))
++#define RPC_CMNCR_IO0FV(val) (((val) & 0x3) << 8)
++#define RPC_CMNCR_IO2FV(val) (((val) & 0x3) << 12)
++#define RPC_CMNCR_IO3FV(val) (((val) & 0x3) << 14)
++#define RPC_CMNCR_IOFV_HIZ (RPC_CMNCR_IO0FV(3) | RPC_CMNCR_IO2FV(3) | \
++ RPC_CMNCR_IO3FV(3))
++#define RPC_CMNCR_BSZ(val) (((val) & 0x3) << 0)
++
++#define RPC_SSLDR 0x0004 /* R/W */
++#define RPC_SSLDR_SPNDL(d) (((d) & 0x7) << 16)
++#define RPC_SSLDR_SLNDL(d) (((d) & 0x7) << 8)
++#define RPC_SSLDR_SCKDL(d) (((d) & 0x7) << 0)
++
++#define RPC_DRCR 0x000C /* R/W */
++#define RPC_DRCR_SSLN (0x1 << 24)
++#define RPC_DRCR_RBURST(v) (((v) & 0x1F) << 16)
++#define RPC_DRCR_RCF (0x1 << 9)
++#define RPC_DRCR_RBE (0x1 << 8)
++#define RPC_DRCR_SSLE (0x1 << 0)
++
++#define RPC_DRCMR 0x0010 /* R/W */
++#define RPC_DRCMR_CMD(c) (((c) & 0xFF) << 16)
++#define RPC_DRCMR_OCMD(c) (((c) & 0xFF) << 0)
++
++#define RPC_DREAR 0x0014 /* R/W */
++#define RPC_DREAR_EAV(v) (((v) & 0xFF) << 16)
++#define RPC_DREAR_EAC(v) (((v) & 0x7) << 0)
++
++#define RPC_DROPR 0x0018 /* R/W */
++#define RPC_DROPR_OPD3(o) (((o) & 0xFF) << 24)
++#define RPC_DROPR_OPD2(o) (((o) & 0xFF) << 16)
++#define RPC_DROPR_OPD1(o) (((o) & 0xFF) << 8)
++#define RPC_DROPR_OPD0(o) (((o) & 0xFF) << 0)
++
++#define RPC_DRENR 0x001C /* R/W */
++#define RPC_DRENR_CDB(o) (((o) & 0x3) << 30)
++#define RPC_DRENR_OCDB(o) (((o) & 0x3) << 28)
++#define RPC_DRENR_ADB(o) (((o) & 0x3) << 24)
++#define RPC_DRENR_OPDB(o) (((o) & 0x3) << 20)
++#define RPC_DRENR_SPIDB(o) (((o) & 0x3) << 16)
++#define RPC_DRENR_DME (0x1 << 15)
++#define RPC_DRENR_CDE (0x1 << 14)
++#define RPC_DRENR_OCDE (0x1 << 12)
++#define RPC_DRENR_ADE(v) (((v) & 0xF) << 8)
++#define RPC_DRENR_OPDE(v) (((v) & 0xF) << 4)
++
++#define RPC_SMCR 0x0020 /* R/W */
++#define RPC_SMCR_SSLKP (0x1 << 8)
++#define RPC_SMCR_SPIRE (0x1 << 2)
++#define RPC_SMCR_SPIWE (0x1 << 1)
++#define RPC_SMCR_SPIE (0x1 << 0)
++
++#define RPC_SMCMR 0x0024 /* R/W */
++#define RPC_SMCMR_CMD(c) (((c) & 0xFF) << 16)
++#define RPC_SMCMR_OCMD(c) (((c) & 0xFF) << 0)
++
++#define RPC_SMADR 0x0028 /* R/W */
++#define RPC_SMOPR 0x002C /* R/W */
++#define RPC_SMOPR_OPD0(o) (((o) & 0xFF) << 0)
++#define RPC_SMOPR_OPD1(o) (((o) & 0xFF) << 8)
++#define RPC_SMOPR_OPD2(o) (((o) & 0xFF) << 16)
++#define RPC_SMOPR_OPD3(o) (((o) & 0xFF) << 24)
++
++#define RPC_SMENR 0x0030 /* R/W */
++#define RPC_SMENR_CDB(o) (((o) & 0x3) << 30)
++#define RPC_SMENR_OCDB(o) (((o) & 0x3) << 28)
++#define RPC_SMENR_ADB(o) (((o) & 0x3) << 24)
++#define RPC_SMENR_OPDB(o) (((o) & 0x3) << 20)
++#define RPC_SMENR_SPIDB(o) (((o) & 0x3) << 16)
++#define RPC_SMENR_DME (0x1 << 15)
++#define RPC_SMENR_CDE (0x1 << 14)
++#define RPC_SMENR_OCDE (0x1 << 12)
++#define RPC_SMENR_ADE(v) (((v) & 0xF) << 8)
++#define RPC_SMENR_OPDE(v) (((v) & 0xF) << 4)
++#define RPC_SMENR_SPIDE(v) (((v) & 0xF) << 0)
++
++#define RPC_SMRDR0 0x0038 /* R */
++#define RPC_SMRDR1 0x003C /* R */
++#define RPC_SMWDR0 0x0040 /* R/W */
++#define RPC_SMWDR1 0x0044 /* R/W */
++#define RPC_CMNSR 0x0048 /* R */
++#define RPC_CMNSR_SSLF (0x1 << 1)
++#define RPC_CMNSR_TEND (0x1 << 0)
++
++#define RPC_DRDMCR 0x0058 /* R/W */
++#define RPC_DRDMCR_DMCYC(v) (((v) & 0xF) << 0)
++
++#define RPC_DRDRENR 0x005C /* R/W */
++#define RPC_DRDRENR_HYPE (0x5 << 12)
++#define RPC_DRDRENR_ADDRE (0x1 << 0x8)
++#define RPC_DRDRENR_OPDRE (0x1 << 0x4)
++#define RPC_DRDRENR_DRDRE (0x1 << 0x0)
++
++#define RPC_SMDMCR 0x0060 /* R/W */
++#define RPC_SMDMCR_DMCYC(v) (((v) & 0xF) << 0)
++
++#define RPC_SMDRENR 0x0064 /* R/W */
++#define RPC_SMDRENR_HYPE (0x5 << 12)
++#define RPC_SMDRENR_ADDRE (0x1 << 0x8)
++#define RPC_SMDRENR_OPDRE (0x1 << 0x4)
++#define RPC_SMDRENR_SPIDRE (0x1 << 0x0)
++
++#define RPC_PHYCNT 0x007C /* R/W */
++#define RPC_PHYCNT_CAL (0x1 << 31)
++#define PRC_PHYCNT_OCTA_AA (0x1 << 22)
++#define PRC_PHYCNT_OCTA_SA (0x2 << 22)
++#define PRC_PHYCNT_EXDS (0x1 << 21)
++#define RPC_PHYCNT_OCT (0x1 << 20)
++#define RPC_PHYCNT_WBUF2 (0x1 << 4)
++#define RPC_PHYCNT_WBUF (0x1 << 2)
++#define RPC_PHYCNT_MEM(v) (((v) & 0x3) << 0)
++
++#define RPC_PHYINT 0x0088 /* R/W */
++#define RPC_PHYINT_RSTEN (0x1 << 18)
++#define RPC_PHYINT_WPEN (0x1 << 17)
++#define RPC_PHYINT_INTEN (0x1 << 16)
++#define RPC_PHYINT_RST (0x1 << 2)
++#define RPC_PHYINT_WP (0x1 << 1)
++#define RPC_PHYINT_INT (0x1 << 0)
++
++#define RPC_WBUF 0x8000 /* R/W size=4/8/16/32/64Bytes */
++#define RPC_WBUF_SIZE 0x100
++
++struct rpc_info {
++ struct rw_semaphore lock;
++ void __iomem *rpc_base;
++ void __iomem *flash_base;
++ struct resource *rpc_res;
++ struct resource *flash_res;
++ u32 flash_id;
++ struct mtd_info mtd;
++};
++
++static inline void __iomem *rpc_addr(struct rpc_info *info, u32 offset)
++{
++ return info->rpc_base + offset;
++}
++
++static inline u32 rpc_readl(struct rpc_info *info, u32 offset)
++{
++ u32 val;
++
++ val = readl(rpc_addr(info, offset));
++ return val;
++}
++
++static inline void rpc_writel(struct rpc_info *info, u32 offset, u32 val)
++{
++ writel(val, rpc_addr(info, offset));
++}
++
++static inline void rpc_setl(struct rpc_info *info, u32 offset, u32 mask, u32 set)
++{
++ void __iomem *addr;
++ u32 val;
++
++ addr = rpc_addr(info, offset);
++ val = readl(addr);
++ val &= mask;
++ val |= set;
++ writel(val, addr);
++}
++
++static void rpc_wait_tend(struct rpc_info *info)
++{
++ while (!(rpc_readl(info, RPC_CMNSR) & RPC_CMNSR_TEND))
++ cpu_relax();
++}
++
++/* RPC HyperFlash */
++#define RPC_HF_CMD_CA47 (0x1 << 7) /* Read */
++#define RPC_HF_CMD_CA46 (0x1 << 6) /* Register space */
++#define RPC_HF_CMD_CA45 (0x1 << 5) /* Liner burst */
++
++#define RPC_HF_CMD_READ_REG (RPC_HF_CMD_CA47 | RPC_HF_CMD_CA46)
++#define RPC_HF_CMD_READ_MEM RPC_HF_CMD_CA47
++#define RPC_HF_CMD_WRITE_REG RPC_HF_CMD_CA46
++#define RPC_HF_CMD_WRITE_MEM 0x0
++
++#define RPC_HF_ERASE_SIZE 0x40000
++
++#define RPC_CFI_STATUS_DRB (0x1 << 7)
++#define RPC_CFI_STATUS_ESSB (0x1 << 6)
++#define RPC_CFI_STATUS_ESB (0x1 << 5)
++#define RPC_CFI_STATUS_PSB (0x1 << 4)
++#define RPC_CFI_STATUS_WBASB (0x1 << 3)
++#define RPC_CFI_STATUS_PSSB (0x1 << 2)
++#define RPC_CFI_STATUS_SLSB (0x1 << 1)
++#define RPC_CFI_STATUS_ESTAT (0x1 << 0)
++
++#define RPC_CFI_UNLOCK1 (0x555 << 1)
++#define RPC_CFI_UNLOCK2 (0x2AA << 1)
++
++#define RPC_CFI_CMD_UNLOCK_START 0xAA
++#define RPC_CFI_CMD_UNLOCK_ACK 0x55
++#define RPC_CFI_CMD_RESET 0xF0
++#define RPC_CFI_CMD_READ_STATUS 0x70
++#define RPC_CFI_CMD_READ_ID 0x90
++#define RPC_CFI_CMD_WRITE 0xA0
++#define RPC_CFI_CMD_ERASE_START 0x80
++#define RPC_CFI_CMD_ERASE_SECTOR 0x30
++
++#define RPC_CFI_ID_MASK 0x000F
++#define RPC_CFI_ID_MAN_SPANSION 0x0001
++#define RPC_CFI_ID_TYPE_HYPERFLASH 0x000E
++
++enum rpc_hf_size {
++ RPC_HF_SIZE_16BIT = RPC_SMENR_SPIDE(0x8),
++ RPC_HF_SIZE_32BIT = RPC_SMENR_SPIDE(0xC),
++ RPC_HF_SIZE_64BIT = RPC_SMENR_SPIDE(0xF),
++};
++
++struct rpc_info *rpc_info;
++
++static void rpc_hf_mode_man(struct rpc_info *info)
++{
++ rpc_wait_tend(info);
++
++ /*
++ * RPC_PHYCNT = 0x80000263
++ * bit31 CAL = 1 : PHY calibration
++ * bit1-0 PHYMEM[1:0] = 11 : HyperFlash
++ */
++ rpc_setl(info, RPC_PHYCNT,
++ ~(RPC_PHYCNT_WBUF | RPC_PHYCNT_WBUF2 |
++ RPC_PHYCNT_CAL | RPC_PHYCNT_MEM(3)),
++ RPC_PHYCNT_CAL | RPC_PHYCNT_MEM(3));
++
++ /*
++ * RPC_CMNCR = 0x81FFF301
++ * bit31 MD = 1 : Manual mode
++ * bit1-0 BSZ[1:0] = 01 : QSPI Flash x 2 or HyperFlash
++ */
++ rpc_setl(info, RPC_CMNCR,
++ ~(RPC_CMNCR_MD | RPC_CMNCR_BSZ(3)),
++ RPC_CMNCR_MOIIO_HIZ | RPC_CMNCR_IOFV_HIZ |
++ RPC_CMNCR_MD | RPC_CMNCR_BSZ(1));
++}
++
++static void rpc_hf_mode_ext(struct rpc_info *info)
++{
++ rpc_wait_tend(info);
++
++ /*
++ * RPC_PHYCNT = 0x80000263
++ * bit31 CAL = 1 : PHY calibration
++ * bit1-0 PHYMEM[1:0] = 11 : HyperFlash
++ */
++ rpc_setl(info, RPC_PHYCNT,
++ ~(RPC_PHYCNT_WBUF | RPC_PHYCNT_WBUF2 |
++ RPC_PHYCNT_CAL | RPC_PHYCNT_MEM(3)),
++ RPC_PHYCNT_CAL | RPC_PHYCNT_MEM(3));
++
++ /*
++ * RPC_CMNCR = 0x81FFF301
++ * bit31 MD = 1 : Manual mode
++ * bit1-0 BSZ[1:0] = 01 : QSPI Flash x 2 or HyperFlash
++ */
++ rpc_setl(info, RPC_CMNCR,
++ ~(RPC_CMNCR_MD | RPC_CMNCR_BSZ(3)),
++ RPC_CMNCR_MOIIO_HIZ | RPC_CMNCR_IOFV_HIZ |
++ RPC_CMNCR_BSZ(1));
++
++ /*
++ * RPC_DRCR = 0x001F0100
++ * bit21-16 RBURST[4:0] = 11111 : Read burst 32 64-bit data units
++ * bit9 RCF = 1 : Clear cache
++ * bit8 RBE = 1 : Read burst enable
++ */
++ rpc_writel(info, RPC_DRCR,
++ RPC_DRCR_RBURST(0x1F) | RPC_DRCR_RCF | RPC_DRCR_RBE);
++
++ rpc_writel(info, RPC_DRCMR, RPC_DRCMR_CMD(0xA0));
++ rpc_writel(info, RPC_DRENR,
++ RPC_DRENR_CDB(2) | RPC_DRENR_OCDB(2) |
++ RPC_DRENR_ADB(2) | RPC_DRENR_SPIDB(2) |
++ RPC_DRENR_CDE | RPC_DRENR_OCDE | RPC_DRENR_ADE(4));
++ rpc_writel(info, RPC_DRDMCR, RPC_DRDMCR_DMCYC(0xE));
++ rpc_writel(info, RPC_DRDRENR,
++ RPC_DRDRENR_HYPE | RPC_DRDRENR_ADDRE | RPC_DRDRENR_DRDRE);
++
++ /* Dummy read */
++ rpc_readl(info, RPC_DRCR);
++}
++
++static void rpc_hf_xfer(struct rpc_info *info, u32 addr, u16 *data,
++ enum rpc_hf_size size, u8 cmd)
++{
++ u32 val;
++
++ rpc_hf_mode_man(info);
++
++ /*
++ * bit23-21 CMD[7:5] : CA47-45
++ * CA47 = 0/1 : Write/Read
++ * CA46 = 0/1 : Memory Space/Register Space
++ * CA45 = 0/1 : Wrapped Burst/Linear Burst
++ */
++ rpc_writel(info, RPC_SMCMR, RPC_SMCMR_CMD(cmd));
++
++ rpc_writel(info, RPC_SMADR, addr >> 1);
++
++ rpc_writel(info, RPC_SMOPR, 0x0);
++
++ /*
++ * RPC_SMDRENR = 0x00005101
++ * bit14-12 HYPE = 101: Hyperflash mode
++ * bit8 ADDRE = 1 : Address DDR transfer
++ * bit0 SPIDRE = 1 : DATA DDR transfer
++ */
++ rpc_writel(info, RPC_SMDRENR,
++ RPC_SMDRENR_HYPE | RPC_SMDRENR_ADDRE | RPC_SMDRENR_SPIDRE);
++
++ val = RPC_SMENR_CDB(2) | RPC_SMENR_OCDB(2) |
++ RPC_SMENR_ADB(2) | RPC_SMENR_SPIDB(2) |
++ RPC_SMENR_CDE | RPC_SMENR_OCDE | RPC_SMENR_ADE(4) | size;
++
++ if (cmd & RPC_HF_CMD_CA47)
++ goto read_transfer;
++
++ /*
++ * RPC_SMENR = 0xA222540x
++ * bit31-30 CDB[1:0] = 10 : 4bit width command
++ * bit25-24 ADB[1:0] = 10 : 4bit width address
++ * bit17-16 SPIDB[1:0] = 10 : 4bit width transfer data
++ * bit15 DME = 0 : dummy cycle disable
++ * bit14 CDE = 1 : Command enable
++ * bit12 OCDE = 1 : Option Command enable
++ * bit11-8 ADE[3:0] = 0100 : ADR[23:0] output
++ * bit7-4 OPDE[3:0] = 0000 : Option data disable
++ * bit3-0 SPIDE[3:0] = xxxx : Transfer size
++ */
++ rpc_writel(info, RPC_SMENR, val);
++
++ switch (size) {
++ case RPC_HF_SIZE_64BIT:
++ val = cmd & RPC_HF_CMD_CA46 ?
++ cpu_to_be16(data[0]) | cpu_to_be16(data[1]) << 16 :
++ data[0] | data[1] << 16;
++ rpc_writel(info, RPC_SMWDR1, val);
++ val = cmd & RPC_HF_CMD_CA46 ?
++ cpu_to_be16(data[2]) | cpu_to_be16(data[3]) << 16 :
++ data[2] | data[3] << 16;
++ break;
++ case RPC_HF_SIZE_32BIT:
++ val = cmd & RPC_HF_CMD_CA46 ?
++ cpu_to_be16(data[0]) | cpu_to_be16(data[1]) << 16 :
++ data[0] | data[1] << 16;
++ break;
++ default:
++ val = cmd & RPC_HF_CMD_CA46 ?
++ cpu_to_be16(data[0]) << 16 :
++ data[0] << 16;
++ break;
++ }
++
++ rpc_writel(info, RPC_SMWDR0, val);
++ /*
++ * RPC_SMCR = 0x00000003
++ * bit1 SPIWE = 1 : Data write enable
++ * bit0 SPIE = 1 : SPI transfer start
++ */
++ rpc_writel(info, RPC_SMCR, RPC_SMCR_SPIWE | RPC_SMCR_SPIE);
++ return;
++
++read_transfer:
++ rpc_writel(info, RPC_SMDMCR, RPC_SMDMCR_DMCYC(0xE));
++ val |= RPC_SMENR_DME;
++
++ /*
++ * RPC_SMENR = 0xA222D40x
++ * bit31-30 CDB[1:0] = 10 : 4bit width command
++ * bit25-24 ADB[1:0] = 10 : 4bit width address
++ * bit17-16 SPIDB[1:0] = 10 : 4bit width transfer data
++ * bit15 DME = 1 : dummy cycle disable
++ * bit14 CDE = 1 : Command enable
++ * bit12 OCDE = 1 : Option Command enable
++ * bit11-8 ADE[3:0] = 0100 : ADR[23:0] output (24 Bit Address)
++ * bit7-4 OPDE[3:0] = 0000 : Option data disable
++ * bit3-0 SPIDE[3:0] = xxxx : Transfer size
++ */
++ rpc_writel(info, RPC_SMENR, val);
++
++ /*
++ * RPC_SMCR = 0x00000005
++ * bit2 SPIRE = 1 : Data read disable
++ * bit0 SPIE = 1 : SPI transfer start
++ */
++ rpc_writel(info, RPC_SMCR, RPC_SMCR_SPIRE | RPC_SMCR_SPIE);
++
++ rpc_wait_tend(info);
++ val = rpc_readl(info, RPC_SMRDR0);
++
++ /*
++ * Read data from either register or memory space.
++ * Register space is always big-endian.
++ */
++ switch (size) {
++ case RPC_HF_SIZE_64BIT:
++ if (cmd & RPC_HF_CMD_CA46) {
++ data[3] = be16_to_cpu((val >> 16) & 0xFFFF);
++ data[2] = be16_to_cpu(val & 0xFFFF);
++ } else {
++ data[3] = (val >> 16) & 0xFFFF;
++ data[2] = val & 0xFFFF;
++ }
++ val = rpc_readl(info, RPC_SMRDR1);
++ if (cmd & RPC_HF_CMD_CA46) {
++ data[1] = be16_to_cpu((val >> 16) & 0xFFFF);
++ data[0] = be16_to_cpu(val & 0xFFFF);
++ } else {
++ data[1] = (val >> 16) & 0xFFFF;
++ data[0] = val & 0xFFFF;
++ }
++ break;
++ case RPC_HF_SIZE_32BIT:
++ if (cmd & RPC_HF_CMD_CA46) {
++ data[1] = be16_to_cpu((val >> 16) & 0xFFFF);
++ data[0] = be16_to_cpu(val & 0xFFFF);
++ } else {
++ data[1] = (val >> 16) & 0xFFFF;
++ data[0] = val & 0xFFFF;
++ }
++ break;
++ default:
++ data[0] = cmd & RPC_HF_CMD_CA46 ?
++ be16_to_cpu((val >> 16) & 0xFFFF) :
++ (val >> 16) & 0xFFFF;
++ break;
++ }
++}
++
++static void rpc_hf_wbuf_enable(struct rpc_info *info)
++{
++ rpc_wait_tend(info);
++
++ /*
++ * RPC_PHYCNT = 0x80000277
++ * bit31 CAL = 1 : PHY calibration
++ * bit4 WBUF2 = 1 : Write buffer enable 2
++ * bit2 WBUF = 1 : Write buffer enable
++ * bit1-0 PHYMEM[1:0] = 11 : HyperFlash
++ */
++ rpc_setl(info, RPC_PHYCNT,
++ ~(RPC_PHYCNT_WBUF2 | RPC_PHYCNT_WBUF |
++ RPC_PHYCNT_CAL | RPC_PHYCNT_MEM(3)),
++ RPC_PHYCNT_WBUF2 | RPC_PHYCNT_WBUF |
++ RPC_PHYCNT_CAL | RPC_PHYCNT_MEM(3));
++
++ /*
++ * RPC_DRCR = 0x001F0100
++ * bit21-16 RBURST[4:0] = 11111 : Read burst 32 64-bit data units
++ * bit9 RCF = 1 : Clear cache
++ * bit8 RBE = 1 : Read burst enable
++ */
++ rpc_writel(info, RPC_DRCR,
++ RPC_DRCR_RBURST(0x1F) | RPC_DRCR_RCF | RPC_DRCR_RBE);
++
++ rpc_writel(info, RPC_SMCMR, RPC_SMCMR_CMD(RPC_HF_CMD_WRITE_MEM));
++
++ rpc_writel(info, RPC_SMOPR, 0x0);
++
++ /*
++ * RPC_SMDRENR = 0x00005101
++ * bit14-12 HYPE = 101:Hyperflash mode
++ * bit8 ADDRE = 1 : Address DDR transfer
++ * bit0 SPIDRE = 1 : DATA DDR transfer
++ */
++ rpc_writel(info, RPC_SMDRENR,
++ RPC_SMDRENR_HYPE | RPC_SMDRENR_ADDRE | RPC_SMDRENR_SPIDRE);
++
++ /*
++ * RPC_SMENR = 0xA222540F
++ * bit31-30 CDB[1:0] = 10 : 4bit width command
++ * bit25-24 ADB[1:0] = 10 : 4bit width address
++ * bit17-16 SPIDB[1:0] = 10 : 4bit width transfer data
++ * bit15 DME = 0 : dummy cycle disable
++ * bit14 CDE = 1 : Command enable
++ * bit12 OCDE = 1 : Option Command enable
++ * bit11-8 ADE[3:0] = 0100 : ADR[23:0] output (24 Bit Address)
++ * bit7-4 OPDE[3:0] = 0000 : Option data disable
++ * bit3-0 SPIDE[3:0] = 1111 : 64-bit transfer size
++ */
++ rpc_writel(info, RPC_SMENR,
++ RPC_SMENR_CDB(2) | RPC_SMENR_OCDB(2) |
++ RPC_SMENR_ADB(2) | RPC_SMENR_SPIDB(2) |
++ RPC_SMENR_CDE | RPC_SMENR_OCDE |
++ RPC_SMENR_ADE(4) | RPC_HF_SIZE_64BIT);
++
++ /* Dummy read */
++ rpc_readl(info, RPC_DRCR);
++}
++
++static inline void rpc_hf_write_cmd(struct rpc_info *info, u32 addr, u16 cmd)
++{
++ rpc_hf_xfer(info, addr, &cmd, RPC_HF_SIZE_16BIT, RPC_HF_CMD_WRITE_REG);
++}
++
++static inline void rpc_hf_read_reg(struct rpc_info *info, u32 addr, u16 *data,
++ enum rpc_hf_size size)
++{
++ rpc_hf_xfer(info, addr, data, size, RPC_HF_CMD_READ_REG);
++}
++
++static inline void rpc_hf_write_reg(struct rpc_info *info, u32 addr, u16 *data,
++ enum rpc_hf_size size)
++{
++ rpc_hf_xfer(info, addr, data, size, RPC_HF_CMD_WRITE_REG);
++}
++
++static inline void rpc_hf_read_mem(struct rpc_info *info, u32 addr, u16 *data,
++ enum rpc_hf_size size)
++{
++ rpc_hf_xfer(info, addr, data, size, RPC_HF_CMD_READ_MEM);
++}
++
++static inline void rpc_hf_write_mem(struct rpc_info *info, u32 addr, u16 *data,
++ enum rpc_hf_size size)
++{
++ rpc_hf_xfer(info, addr, data, size, RPC_HF_CMD_WRITE_MEM);
++}
++
++static void rpc_hf_wp(struct rpc_info *info, int enable)
++{
++ rpc_setl(info, RPC_PHYINT, ~RPC_PHYINT_WP, enable ? RPC_PHYINT_WP : 0);
++}
++
++static void rpc_hf_unlock(struct rpc_info *info, u32 addr)
++{
++ rpc_hf_write_cmd(info, addr + RPC_CFI_UNLOCK1,
++ RPC_CFI_CMD_UNLOCK_START);
++ rpc_hf_write_cmd(info, addr + RPC_CFI_UNLOCK2,
++ RPC_CFI_CMD_UNLOCK_ACK);
++}
++
++static inline int rpc_hf_status(struct rpc_info *info, u32 addr,
++ int iterations, int delay)
++{
++ int retval;
++ u16 status = 0;
++
++ while (iterations-- > 0) {
++ rpc_hf_write_cmd(info, addr + RPC_CFI_UNLOCK1, RPC_CFI_CMD_READ_STATUS);
++ rpc_hf_read_reg(info, addr, &status, RPC_HF_SIZE_16BIT);
++
++ if (status & RPC_CFI_STATUS_DRB)
++ break;
++
++ if (delay < 10000)
++ usleep_range(delay, delay * 2);
++ else
++ msleep(delay / 1000);
++ }
++
++ if (!(status & RPC_CFI_STATUS_DRB)) {
++ retval = -ETIMEDOUT;
++ goto out;
++ }
++
++ if (status & (RPC_CFI_STATUS_PSB | RPC_CFI_STATUS_ESB)) {
++ retval = -EIO;
++ goto out;
++ }
++
++ return 0;
++
++out:
++ /* Reset the flash */
++ rpc_hf_write_cmd(info, 0, RPC_CFI_CMD_RESET);
++ return retval;
++}
++
++static int rpc_hf_sector_erase(struct rpc_info *info, u32 addr)
++{
++ rpc_hf_unlock(info, addr);
++ rpc_hf_write_cmd(info, addr + RPC_CFI_UNLOCK1, RPC_CFI_CMD_ERASE_START);
++ rpc_hf_unlock(info, addr);
++ rpc_hf_write_cmd(info, addr, RPC_CFI_CMD_ERASE_SECTOR);
++
++ return rpc_hf_status(info, addr, 1000, 10000);
++}
++
++/* Flash read */
++static int rpc_hf_mtd_read(struct mtd_info *mtd, loff_t from, size_t len,
++ size_t *retlen, u_char *buf)
++{
++ struct rpc_info *info = mtd->priv;
++
++ down_read(&info->lock);
++ memcpy_fromio(buf, info->flash_base + from, len);
++ up_read(&info->lock);
++
++ *retlen = len;
++ return 0;
++}
++
++/* Flash erase */
++static int rpc_hf_mtd_erase(struct mtd_info *mtd, struct erase_info *instr)
++{
++ struct rpc_info *info = mtd->priv;
++ u32 addr, end;
++ int retval = 0;
++
++ if (mtd_mod_by_eb(instr->addr, mtd)) {
++ pr_debug("%s: unaligned address\n", __func__);
++ return -EINVAL;
++ }
++
++ if (mtd_mod_by_eb(instr->len, mtd)) {
++ pr_debug("%s: unaligned length\n", __func__);
++ return -EINVAL;
++ }
++
++ end = instr->addr + instr->len;
++
++ down_write(&info->lock);
++ for (addr = instr->addr; addr < end; addr += mtd->erasesize) {
++ retval = rpc_hf_sector_erase(info, addr);
++
++ if (retval)
++ break;
++ }
++
++ rpc_hf_mode_ext(info);
++ up_write(&info->lock);
++
++ instr->state = retval ? MTD_ERASE_FAILED : MTD_ERASE_DONE;
++ mtd_erase_callback(instr);
++
++ return retval;
++}
++
++/* Copy memory to flash */
++static int rpc_hf_mtd_write(struct mtd_info *mtd, loff_t offset, size_t len,
++ size_t *retlen, const u_char *src)
++{
++ struct rpc_info *info = mtd->priv;
++ union {
++ u8 b[4];
++ u16 w[2];
++ u32 d;
++ } data;
++ loff_t addr;
++ size_t size, cnt;
++ int retval, idx;
++ u8 last;
++
++ retval = 0;
++ *retlen = 0;
++ cnt = len;
++ idx = 0;
++
++ down_write(&info->lock);
++
++ /* Handle unaligned start */
++ if (offset & 0x1) {
++ offset--;
++ data.b[idx] = readb(info->flash_base + offset);
++ idx++;
++ }
++
++ /* Handle unaligned end */
++ addr = offset + idx + len;
++ last = addr & 0x1 ? readb(info->flash_base + addr) : 0xFF;
++
++ addr = offset - mtd_mod_by_eb(offset, mtd);
++ size = mtd->erasesize - (offset - addr);
++
++ while (cnt) {
++ if (size > cnt)
++ size = cnt;
++
++ cnt -= size;
++ while (size) {
++ rpc_hf_unlock(info, addr);
++ rpc_hf_write_cmd(info,
++ addr + RPC_CFI_UNLOCK1,
++ RPC_CFI_CMD_WRITE);
++
++ if (size > 0x7) {
++ u32 wbuf = RPC_WBUF;
++ int block = size >= RPC_WBUF_SIZE ?
++ RPC_WBUF_SIZE : size & ~0x7;
++
++ rpc_hf_wbuf_enable(info);
++
++ rpc_writel(info, RPC_SMADR, offset >> 1);
++ offset += block;
++
++ block >>= 3;
++ while (block--) {
++ while (idx < 4) {
++ data.b[idx++] = *src++;
++ size--;
++ }
++ rpc_writel(info, wbuf, data.d);
++ wbuf += 4;
++
++ idx = 0;
++ while (idx < 4) {
++ data.b[idx++] = *src++;
++ size--;
++ }
++ rpc_writel(info, wbuf, data.d);
++ wbuf += 4;
++
++ idx = 0;
++ }
++
++ rpc_writel(info, RPC_SMCR,
++ RPC_SMCR_SPIWE | RPC_SMCR_SPIE);
++ } else {
++ enum rpc_hf_size bits;
++
++ while (idx < 4) {
++ data.b[idx++] = *src++;
++ size--;
++
++ if (!size)
++ break;
++ }
++
++ if (idx & 0x1)
++ data.b[idx++] = last;
++
++ switch (idx) {
++ case 2:
++ bits = RPC_HF_SIZE_16BIT;
++ break;
++ default:
++ bits = RPC_HF_SIZE_32BIT;
++ break;
++ }
++
++ rpc_hf_write_mem(info, offset, data.w, bits);
++ offset += idx;
++ idx = 0;
++ }
++
++ retval = rpc_hf_status(info, addr, 1000000, 10);
++ if (retval)
++ goto out;
++ }
++
++ size = mtd->erasesize;
++ addr += size;
++ offset = addr;
++ *retlen = len - cnt;
++ }
++
++out:
++ rpc_hf_mode_ext(info);
++ up_write(&info->lock);
++ return retval;
++}
++
++static struct mtd_partition partition_info[]={
++ {
++ .name = "bootparam",
++ .offset = 0,
++ .size = 0x40000,
++ }, {
++ .name = "bl2",
++ .offset = MTDPART_OFS_APPEND,
++ .size = 0x140000
++ }, {
++ .name = "cert_header",
++ .offset = MTDPART_OFS_APPEND,
++ .size = 0x40000,
++ }, {
++ .name = "bl31",
++ .offset = MTDPART_OFS_APPEND,
++ .size = 0x40000,
++ }, {
++ .name = "optee",
++ .offset = MTDPART_OFS_APPEND,
++ .size = 0x440000,
++ }, {
++ .name = "u-boot",
++ .offset = MTDPART_OFS_APPEND,
++ .size = 0x80000,
++ }, {
++ .name = "reserved",
++ .offset = MTDPART_OFS_APPEND,
++ .size = 0x80000,
++ }, {
++ .name = "u-boot-env",
++ .offset = MTDPART_OFS_APPEND,
++ .size = 0x40000,
++ }, {
++ .name = "dtb",
++ .offset = MTDPART_OFS_APPEND,
++ .size = 0x80000,
++ }, {
++ .name = "kernel",
++ .offset = MTDPART_OFS_APPEND,
++ .size = 0x1000000,
++ }, {
++ .name = "user",
++ .offset = MTDPART_OFS_APPEND,
++ .size = MTDPART_SIZ_FULL,
++ },
++};
++
++static int rpc_hf_init_mtd(struct rpc_info *info)
++{
++ struct mtd_info *mtd = &info->mtd;
++ u16 data[2] = { 0, 0 };
++ u32 id, size;
++ int retval;
++
++ rpc_hf_mode_ext(info);
++
++ rpc_hf_wp(info, 0);
++
++ rpc_hf_unlock(info, 0);
++ rpc_hf_write_cmd(info, RPC_CFI_UNLOCK1, RPC_CFI_CMD_READ_ID);
++
++ rpc_hf_read_reg(info, 0x0, data, RPC_HF_SIZE_32BIT);
++ if ((data[0] & RPC_CFI_ID_MASK) != RPC_CFI_ID_MAN_SPANSION ||
++ (data[1] & RPC_CFI_ID_MASK) != RPC_CFI_ID_TYPE_HYPERFLASH) {
++ retval = -ENODEV;
++ goto out;
++ }
++
++ id = data[0] | data[1] << 16;
++
++ rpc_hf_read_reg(info, 0x27 << 1, data, RPC_HF_SIZE_16BIT);
++ size = 1 << data[0];
++
++ if (size > resource_size(info->flash_res))
++ size = resource_size(info->flash_res);
++
++ if (size & (RPC_HF_ERASE_SIZE - 1)) {
++ retval = -EINVAL;
++ goto out;
++ }
++
++ init_rwsem(&info->lock);
++ info->flash_id = id;
++ mtd->name = "HyperFlash";
++ mtd->type = MTD_NORFLASH;
++ mtd->flags = MTD_CAP_NORFLASH;
++ mtd->size = size;
++ mtd->writesize = 1;
++ mtd->writebufsize = RPC_WBUF_SIZE;
++ mtd->erasesize = RPC_HF_ERASE_SIZE;
++ mtd->owner = THIS_MODULE;
++ mtd->priv = info;
++ mtd->_erase = rpc_hf_mtd_erase;
++ mtd->_write = rpc_hf_mtd_write;
++ mtd->_read = rpc_hf_mtd_read;
++ retval = mtd_device_register(mtd, partition_info,
++ ARRAY_SIZE(partition_info));
++out:
++ rpc_hf_write_cmd(info, 0, RPC_CFI_CMD_RESET);
++ rpc_hf_mode_ext(info);
++ return retval;
++}
++
++static int rpc_flash_init(void)
++{
++ struct rpc_info *info;
++ struct resource *res;
++ void __iomem *base;
++ int retval = -ENODEV;
++
++ if (!of_machine_is_compatible("renesas,r8a7795"))
++ return -ENODEV;
++
++ info = kzalloc(sizeof(*info), GFP_KERNEL);
++ if (!info)
++ return -ENOMEM;
++
++ res = request_mem_region(RPC_BASE, RPC_SIZE, "RPC");
++ if (!res)
++ goto out_info;
++
++ info->rpc_res = res;
++ base = ioremap(res->start, resource_size(res));
++ if (!base)
++ goto out_rpc_res;
++
++ info->rpc_base = base;
++ res = request_mem_region(RPC_FLASH_BASE, RPC_FLASH_SIZE, "RPC-ext");
++ if (!res)
++ goto out_rpc_base;
++
++ info->flash_res = res;
++ base = ioremap(res->start, resource_size(res));
++ if (!base)
++ goto out_flash_res;
++
++ info->flash_base = base;
++ retval = rpc_hf_init_mtd(info);
++ if (retval)
++ goto out_flash_base;
++
++ pr_info("HyperFlash Id: %x\n", info->flash_id);
++
++ rpc_info = info;
++ return 0;
++
++out_flash_base:
++ iounmap(info->flash_base);
++out_flash_res:
++ release_mem_region(info->flash_res->start,
++ resource_size(info->flash_res));
++out_rpc_base:
++ iounmap(info->rpc_base);
++out_rpc_res:
++ release_mem_region(info->rpc_res->start,
++ resource_size(info->rpc_res));
++out_info:
++ kfree(info);
++ return retval;
++}
++
++static void rpc_flash_exit(void)
++{
++ struct rpc_info *info = rpc_info;
++
++ if (!info)
++ return;
++
++ rpc_info = NULL;
++
++ mtd_device_unregister(&info->mtd);
++
++ iounmap(info->flash_base);
++ release_mem_region(info->flash_res->start,
++ resource_size(info->flash_res));
++ iounmap(info->rpc_base);
++ release_mem_region(info->rpc_res->start,
++ resource_size(info->rpc_res));
++ kfree(info);
++}
++
++module_init(rpc_flash_init);
++module_exit(rpc_flash_exit);
++
++MODULE_LICENSE("GPL v2");
++MODULE_DESCRIPTION("Renesas RPC HyperFlash MTD driver");
+--
+2.7.4
+
diff --git a/bsp/meta-rcar/meta-rcar-gen3-adas/recipes-kernel/linux/linux-renesas/0013-IMR-driver-interim-patch.patch b/bsp/meta-rcar/meta-rcar-gen3-adas/recipes-kernel/linux/linux-renesas/0013-IMR-driver-interim-patch.patch
new file mode 100644
index 00000000..2ef0fafb
--- /dev/null
+++ b/bsp/meta-rcar/meta-rcar-gen3-adas/recipes-kernel/linux/linux-renesas/0013-IMR-driver-interim-patch.patch
@@ -0,0 +1,2002 @@
+From 1b3ded1c8d137c417f7f75e6adffb9811d8e21a9 Mon Sep 17 00:00:00 2001
+From: Konstantin Kozhevnikov <Konstantin.Kozhevnikov@cogentembedded.com>
+Date: Wed, 7 Sep 2016 22:55:37 +0300
+Subject: [PATCH 010/122] IMR driver - interim patch
+
+Signed-off-by: Konstantin Kozhevnikov <Konstantin.Kozhevnikov@cogentembedded.com>
+---
+ drivers/media/platform/Kconfig | 11 +
+ drivers/media/platform/Makefile | 1 +
+ drivers/media/platform/rcar_imr.c | 1840 +++++++++++++++++++++++++++++++++++++
+ include/uapi/linux/rcar-imr.h | 98 ++
+ 4 files changed, 1950 insertions(+)
+ create mode 100644 drivers/media/platform/rcar_imr.c
+ create mode 100644 include/uapi/linux/rcar-imr.h
+
+diff --git a/drivers/media/platform/Kconfig b/drivers/media/platform/Kconfig
+index 63f434c..3e165fc 100644
+--- a/drivers/media/platform/Kconfig
++++ b/drivers/media/platform/Kconfig
+@@ -454,6 +454,17 @@ config VIDEO_RENESAS_FCP
+ To compile this driver as a module, choose M here: the module
+ will be called rcar-fcp.
+
++config VIDEO_RENESAS_IMR
++ tristate "Renesas Image Renderer (Distortion Correction) Unit"
++ depends on VIDEO_DEV && VIDEO_V4L2
++ select VIDEOBUF2_DMA_CONTIG
++ select V4L2_MEM2MEM_DEV
++ ---help---
++ This is a V4L2 driver for the Renesas IMR-X2/LX2/LX4 Processing Unit.
++
++ To compile this driver as a module, choose M here: the module
++ will be called rcar_imr.
++
+ config VIDEO_RENESAS_VSP1
+ tristate "Renesas VSP1 Video Processing Engine"
+ depends on VIDEO_V4L2 && VIDEO_V4L2_SUBDEV_API && HAS_DMA
+diff --git a/drivers/media/platform/Makefile b/drivers/media/platform/Makefile
+index 76149a1..d985603 100644
+--- a/drivers/media/platform/Makefile
++++ b/drivers/media/platform/Makefile
+@@ -62,6 +62,7 @@ obj-$(CONFIG_VIDEO_RENESAS_CEU) += renesas-ceu.o
+ obj-$(CONFIG_VIDEO_RENESAS_FCP) += rcar-fcp.o
+ obj-$(CONFIG_VIDEO_RENESAS_FDP1) += rcar_fdp1.o
+ obj-$(CONFIG_VIDEO_RENESAS_JPU) += rcar_jpu.o
++obj-$(CONFIG_VIDEO_RENESAS_IMR) += rcar_imr.o
+ obj-$(CONFIG_VIDEO_RENESAS_VSP1) += vsp1/
+
+ obj-y += omap/
+diff --git a/drivers/media/platform/rcar_imr.c b/drivers/media/platform/rcar_imr.c
+new file mode 100644
+index 0000000..30c6742
+--- /dev/null
++++ b/drivers/media/platform/rcar_imr.c
+@@ -0,0 +1,1840 @@
++/*
++ * rcar_imr.c -- R-Car IMR-LX4 Driver
++ *
++ * Copyright (C) 2015 Cogent Embedded, Inc. <source@cogentembedded.com>
++ *
++ * This program is free software; you can redistribute it and/or modify
++ * it under the terms of the GNU General Public License as published by
++ * the Free Software Foundation; either version 2 of the License, or
++ * (at your option) any later version.
++ */
++
++#include <linux/kernel.h>
++#include <linux/module.h>
++#include <linux/platform_device.h>
++#include <linux/clk.h>
++#include <linux/interrupt.h>
++#include <linux/pm_runtime.h>
++#include <linux/delay.h>
++#include <linux/rcar-imr.h>
++#include <media/v4l2-device.h>
++#include <media/v4l2-ctrls.h>
++#include <media/v4l2-fh.h>
++#include <media/v4l2-mem2mem.h>
++#include <media/v4l2-ioctl.h>
++#include <media/videobuf2-dma-contig.h>
++
++#define DRV_NAME "rcar_imr"
++
++/*******************************************************************************
++ * Module parameters
++ ******************************************************************************/
++
++static int debug;
++module_param(debug, int, 0644);
++MODULE_PARM_DESC(debug, "Debug level (0-4)");
++
++/*******************************************************************************
++ * Local types definitions
++ ******************************************************************************/
++
++/* ...configuration data */
++struct imr_cfg {
++ /* ...display-list main program data */
++ void *dl_vaddr;
++ dma_addr_t dl_dma_addr;
++ u32 dl_size;
++ u32 dl_start_offset;
++
++ /* ...pointers to the source/destination planes */
++ u32 *src_pa_ptr[2];
++ u32 *dst_pa_ptr[2];
++
++ /* ...subpixel destination coordinates space */
++ int dst_subpixel;
++
++ /* ...reference counter */
++ u32 refcount;
++
++ /* ...identifier (for debug output) */
++ u32 id;
++};
++
++struct imr_buffer {
++ /* ...standard M2M buffer descriptor */
++ struct v4l2_m2m_buffer buf;
++
++ /* ...pointer to mesh configuration for processing */
++ struct imr_cfg *cfg;
++};
++
++struct imr_q_data {
++ /* ...latched pixel format */
++ struct v4l2_pix_format fmt;
++
++ /* ...current format flags */
++ u32 flags;
++};
++
++struct imr_format_info {
++ char *name;
++ u32 fourcc;
++ u32 flags;
++};
++
++/* ...per-device data */
++struct imr_device {
++ struct device *dev;
++ struct clk *clock;
++ void __iomem *mmio;
++ int irq;
++ struct mutex mutex;
++ spinlock_t lock;
++
++ struct v4l2_device v4l2_dev;
++ struct video_device video_dev;
++ struct v4l2_m2m_dev *m2m_dev;
++
++ /* ...do we need that counter really? framework counts fh structures for us - tbd */
++ int refcount;
++
++ /* ...should we include media-dev? likely, no - tbd */
++};
++
++/* ...per file-handle context */
++struct imr_ctx {
++ struct v4l2_fh fh;
++ struct imr_device *imr;
++ struct v4l2_m2m_ctx *m2m_ctx;
++ struct imr_q_data queue[2];
++
++ /* ...current job configuration */
++ struct imr_cfg *cfg;
++
++ /* ...frame sequence counter */
++ u32 sequence;
++
++ /* ...cropping parameters (in pixels) */
++ u16 crop[4];
++
++ /* ...number of active configurations (debugging) */
++ u32 cfg_num;
++};
++
++/*******************************************************************************
++ * IMR registers
++ ******************************************************************************/
++
++#define IMR_CR 0x08
++#define IMR_CR_RS (1 << 0)
++#define IMR_CR_SWRST (1 << 15)
++
++#define IMR_SR 0x0C
++#define IMR_SRCR 0x10
++#define IMR_SR_TRA (1 << 0)
++#define IMR_SR_IER (1 << 1)
++#define IMR_SR_INT (1 << 2)
++#define IMR_SR_REN (1 << 5)
++
++#define IMR_ICR 0x14
++#define IMR_IMR 0x18
++#define IMR_ICR_TRAEN (1 << 0)
++#define IMR_ICR_IEREN (1 << 1)
++#define IMR_ICR_INTEN (1 << 2)
++
++#define IMR_DLSP 0x1C
++#define IMR_DLSR 0x20
++#define IMR_DLSAR 0x30
++
++#define IMR_DSAR 0x34
++#define IMR_SSAR 0x38
++#define IMR_DSTR 0x3C
++#define IMR_SSTR 0x40
++#define IMR_DSOR 0x50
++
++#define IMR_CMRCR 0x54
++#define IMR_CMRCSR 0x58
++#define IMR_CMRCCR 0x5C
++#define IMR_CMR_LUCE (1 << 1)
++#define IMR_CMR_CLCE (1 << 2)
++#define IMR_CMR_DUV_SHIFT 3
++#define IMR_CMR_DUV_MASK (3 << IMR_CMR_DUV_SHIFT)
++#define IMR_CMR_SUV_SHIFT 5
++#define IMR_CMR_SUV_MASK (3 << IMR_CMR_SUV_SHIFT)
++#define IMR_CMR_YISM (1 << 7)
++#define IMR_CMR_DY10 (1 << 8)
++#define IMR_CMR_DY12 (1 << 9)
++#define IMR_CMR_SY10 (1 << 11)
++#define IMR_CMR_SY12 (1 << 12)
++#define IMR_CMR_YCM (1 << 14)
++#define IMR_CMR_CP16E (1 << 15)
++
++#define IMR_CMRCR2 0xE4
++#define IMR_CMRCSR2 0xE8
++#define IMR_CMRCCR2 0xEC
++#define IMR_CMR2_LUTE (1 << 0)
++#define IMR_CMR2_YUV422E (1 << 2)
++#define IMR_CMR2_YUV422FORM (1 << 5)
++#define IMR_CMR2_UVFORM (1 << 6)
++#define IMR_CMR2_TCTE (1 << 12)
++#define IMR_CMR2_DCTE (1 << 15)
++
++#define IMR_TRIMR 0x60
++#define IMR_TRIMSR 0x64
++#define IMR_TRIMCR 0x68
++#define IMR_TRIM_TME (1 << 0)
++#define IMR_TRIM_BFE (1 << 1)
++#define IMR_TRIM_AUTODG (1 << 2)
++#define IMR_TRIM_AUTOSG (1 << 3)
++#define IMR_TRIM_DYDXM (1 << 4)
++#define IMR_TRIM_DUDVM (1 << 5)
++#define IMR_TRIM_TCM (1 << 6)
++
++#define IMR_TRICR 0x6C
++#define IMR_TRIC_YCFORM (1 << 31)
++
++#define IMR_UVDPOR 0x70
++#define IMR_SUSR 0x74
++#define IMR_SVSR 0x78
++
++#define IMR_XMINR 0x80
++#define IMR_YMINR 0x84
++#define IMR_XMAXR 0x88
++#define IMR_YMAXR 0x8C
++
++#define IMR_AMXSR 0x90
++#define IMR_AMYSR 0x94
++#define IMR_AMXOR 0x98
++#define IMR_AMYOR 0x9C
++
++#define IMR_CPDPOR 0xD0
++#define IMR_CPDP_YLDPO_SHIFT 8
++#define IMR_CPDP_UBDPO_SHIFT 4
++#define IMR_CPDP_VRDPO_SHIFT 0
++
++/*******************************************************************************
++ * Auxiliary helpers
++ ******************************************************************************/
++
++static inline struct imr_ctx * fh_to_ctx(struct v4l2_fh *fh)
++{
++ return container_of(fh, struct imr_ctx, fh);
++}
++
++static inline struct imr_buffer * to_imr_buffer(struct vb2_v4l2_buffer *vbuf)
++{
++ struct v4l2_m2m_buffer *b = container_of(vbuf, struct v4l2_m2m_buffer, vb);
++
++ return container_of(b, struct imr_buffer, buf);
++}
++
++/*******************************************************************************
++ * Local constants definition
++ ******************************************************************************/
++
++#define IMR_F_Y8 (1 << 0)
++#define IMR_F_Y10 (1 << 1)
++#define IMR_F_Y12 (1 << 2)
++#define IMR_F_UV8 (1 << 3)
++#define IMR_F_UV10 (1 << 4)
++#define IMR_F_UV12 (1 << 5)
++#define IMR_F_PLANAR (1 << 6)
++#define IMR_F_INTERLEAVED (1 << 7)
++#define IMR_F_PLANES_MASK ((1 << 8) - 1)
++#define IMR_F_UV_SWAP (1 << 8)
++#define IMR_F_YUV_SWAP (1 << 9)
++
++/* ...get common planes bits */
++static inline u32 __imr_flags_common(u32 iflags, u32 oflags)
++{
++ return (iflags & oflags) & IMR_F_PLANES_MASK;
++}
++
++static const struct imr_format_info imr_lx4_formats[] = {
++ {
++ .name = "YUV 4:2:2 semiplanar (NV16)",
++ .fourcc = V4L2_PIX_FMT_NV16,
++ .flags = IMR_F_Y8 | IMR_F_UV8 | IMR_F_PLANAR,
++ },
++ {
++ .name = "YVU 4:2:2 semiplanar (NV61)",
++ .fourcc = V4L2_PIX_FMT_NV61,
++ .flags = IMR_F_Y8 | IMR_F_UV8 | IMR_F_PLANAR | IMR_F_UV_SWAP,
++ },
++ {
++ .name = "YUV 4:2:2 interleaved (YUYV)",
++ .fourcc = V4L2_PIX_FMT_YUYV,
++ .flags = IMR_F_Y8 | IMR_F_UV8,
++ },
++ {
++ .name = "YUV 4:2:2 interleaved (UYVY)",
++ .fourcc = V4L2_PIX_FMT_UYVY,
++ .flags = IMR_F_Y8 | IMR_F_UV8 | IMR_F_YUV_SWAP,
++ },
++ {
++ .name = "YUV 4:2:2 interleaved (YVYU)",
++ .fourcc = V4L2_PIX_FMT_YVYU,
++ .flags = IMR_F_Y8 | IMR_F_UV8 | IMR_F_UV_SWAP,
++ },
++ {
++ .name = "YUV 4:2:2 interleaved (UYVY)",
++ .fourcc = V4L2_PIX_FMT_VYUY,
++ .flags = IMR_F_Y8 | IMR_F_UV8 | IMR_F_UV_SWAP | IMR_F_YUV_SWAP,
++ },
++ {
++ .name = "Greyscale 8-bit",
++ .fourcc = V4L2_PIX_FMT_GREY,
++ .flags = IMR_F_Y8 | IMR_F_PLANAR,
++ },
++ {
++ .name = "Greyscale 10-bit",
++ .fourcc = V4L2_PIX_FMT_Y10,
++ .flags = IMR_F_Y8 | IMR_F_Y10 | IMR_F_PLANAR,
++ },
++ {
++ .name = "Greyscale 12-bit",
++ .fourcc = V4L2_PIX_FMT_Y12,
++ .flags = IMR_F_Y8 | IMR_F_Y10 | IMR_F_Y12 | IMR_F_PLANAR,
++ },
++ {
++ .name = "Chrominance UV 8-bit",
++ .fourcc = V4L2_PIX_FMT_UV8,
++ .flags = IMR_F_UV8 | IMR_F_PLANAR,
++ },
++};
++
++/* ...mesh configuration constructor */
++static struct imr_cfg * imr_cfg_create(struct imr_ctx *ctx, u32 dl_size, u32 dl_start)
++{
++ struct imr_device *imr = ctx->imr;
++ struct imr_cfg *cfg;
++
++ /* ...allocate configuration descriptor */
++ cfg = kmalloc(sizeof(*cfg), GFP_KERNEL);
++ if (!cfg) {
++ v4l2_err(&imr->v4l2_dev, "failed to allocate configuration descriptor\n");
++ return ERR_PTR(-ENOMEM);
++ }
++
++ /* ...allocate contiguous memory for a display list */
++ cfg->dl_vaddr = dma_alloc_writecombine(imr->dev, dl_size, &cfg->dl_dma_addr, GFP_KERNEL);
++ if (!cfg->dl_vaddr) {
++ v4l2_err(&imr->v4l2_dev, "failed to allocate %u bytes for a DL\n", dl_size);
++ kfree(cfg);
++ return ERR_PTR(-ENOMEM);
++ }
++
++ cfg->dl_size = dl_size;
++ cfg->dl_start_offset = dl_start;
++ cfg->refcount = 1;
++ cfg->id = ctx->sequence;
++
++ /* ...for debugging purposes, advance number of active configurations */
++ ctx->cfg_num++;
++
++ return cfg;
++}
++
++/* ...add reference to the current configuration */
++static inline struct imr_cfg * imr_cfg_ref(struct imr_ctx *ctx)
++{
++ struct imr_cfg *cfg = ctx->cfg;
++
++ BUG_ON(!cfg);
++ cfg->refcount++;
++ return cfg;
++}
++
++/* ...mesh configuration destructor */
++static void imr_cfg_unref(struct imr_ctx *ctx, struct imr_cfg *cfg)
++{
++ struct imr_device *imr = ctx->imr;
++
++ /* ...no atomicity is required as operation is locked with device mutex */
++ if (!cfg || --cfg->refcount)
++ return;
++
++ /* ...release memory allocated for a display list */
++ if (cfg->dl_vaddr)
++ dma_free_writecombine(imr->dev, cfg->dl_size, cfg->dl_vaddr, cfg->dl_dma_addr);
++
++ /* ...destroy the configuration structure */
++ kfree(cfg);
++
++ /* ...decrement number of active configurations (debugging) */
++ WARN_ON(!ctx->cfg_num--);
++}
++
++
++
++/*******************************************************************************
++ * Context processing queue
++ ******************************************************************************/
++
++static int imr_queue_setup(struct vb2_queue *vq,
++ unsigned int *nbuffers, unsigned int *nplanes,
++ unsigned int sizes[], struct device *alloc_devs[])
++{
++ struct imr_ctx *ctx = vb2_get_drv_priv(vq);
++ struct imr_q_data *q_data = &ctx->queue[V4L2_TYPE_IS_OUTPUT(vq->type) ? 0 : 1];
++ int w = q_data->fmt.width;
++ int h = q_data->fmt.height;
++
++ /* ...we use only single-plane formats */
++ *nplanes = 1;
++
++ /* ...specify plane size */
++ switch (q_data->fmt.pixelformat) {
++ case V4L2_PIX_FMT_UYVY:
++ case V4L2_PIX_FMT_YUYV:
++ case V4L2_PIX_FMT_VYUY:
++ case V4L2_PIX_FMT_YVYU:
++ case V4L2_PIX_FMT_NV16:
++ case V4L2_PIX_FMT_Y10:
++ case V4L2_PIX_FMT_Y16:
++ sizes[0] = w * h * 2;
++ break;
++
++ case V4L2_PIX_FMT_UV8:
++ case V4L2_PIX_FMT_GREY:
++ sizes[0] = w * h;
++ break;
++
++ default:
++ return -EINVAL;
++ }
++
++ return 0;
++}
++
++static int imr_buf_prepare(struct vb2_buffer *vb)
++{
++ /* ...unclear yet if we want to prepare a buffer somehow (cache invalidation? - tbd) */
++ return 0;
++}
++
++static void imr_buf_queue(struct vb2_buffer *vb)
++{
++ struct vb2_queue *q = vb->vb2_queue;
++ struct imr_ctx *ctx = vb2_get_drv_priv(q);
++ struct vb2_v4l2_buffer *vbuf = to_vb2_v4l2_buffer(vb);
++
++ WARN_ON_ONCE(!mutex_is_locked(&ctx->imr->mutex));
++
++ v4l2_dbg(3, debug, &ctx->imr->v4l2_dev, "%sput buffer <0x%08llx> submitted\n",
++ q->is_output ? "in" : "out",
++ vb2_dma_contig_plane_dma_addr(vb, 0));
++
++ /* ...for input buffer, put current configuration pointer (add reference) */
++ if (q->is_output)
++ to_imr_buffer(vbuf)->cfg = imr_cfg_ref(ctx);
++
++ v4l2_m2m_buf_queue(ctx->m2m_ctx, vbuf);
++}
++
++static void imr_buf_finish(struct vb2_buffer *vb)
++{
++ struct vb2_queue *q = vb->vb2_queue;
++ struct imr_ctx *ctx = vb2_get_drv_priv(q);
++ struct vb2_v4l2_buffer *vbuf = to_vb2_v4l2_buffer(vb);
++
++ WARN_ON(!mutex_is_locked(&ctx->imr->mutex));
++
++ /* ...any special processing of completed buffer? - tbd */
++ v4l2_dbg(3, debug, &ctx->imr->v4l2_dev, "%sput buffer <0x%08llx> done\n",
++ q->is_output ? "in" : "out",
++ vb2_dma_contig_plane_dma_addr(vb, 0));
++
++ /* ...unref configuration pointer as needed */
++ if (q->is_output)
++ imr_cfg_unref(ctx, to_imr_buffer(vbuf)->cfg);
++}
++
++static int imr_start_streaming(struct vb2_queue *vq, unsigned int count)
++{
++ struct imr_ctx *ctx = vb2_get_drv_priv(vq);
++ int ret;
++
++ ret = 0;//pm_runtime_get_sync(ctx->imr->dev);
++ if (ret < 0) {
++ v4l2_err(&ctx->imr->v4l2_dev, "failed to start %s streaming: %d\n",
++ (V4L2_TYPE_IS_OUTPUT(vq->type) ? "output" : "capture"), ret);
++ return ret;
++ } else {
++ v4l2_dbg(1, debug, &ctx->imr->v4l2_dev, "%s streaming started\n",
++ (V4L2_TYPE_IS_OUTPUT(vq->type) ? "output" : "capture"));
++ return 0;
++ }
++}
++
++static void imr_stop_streaming(struct vb2_queue *vq)
++{
++ struct imr_ctx *ctx = vb2_get_drv_priv(vq);
++ struct vb2_v4l2_buffer *vb;
++ unsigned long flags;
++
++ spin_lock_irqsave(&ctx->imr->lock, flags);
++
++ /* ...purge all buffers from a queue */
++ if (V4L2_TYPE_IS_OUTPUT(vq->type)) {
++ while ((vb = v4l2_m2m_src_buf_remove(ctx->m2m_ctx)) != NULL)
++ v4l2_m2m_buf_done(vb, VB2_BUF_STATE_ERROR);
++ } else {
++ while ((vb = v4l2_m2m_dst_buf_remove(ctx->m2m_ctx)) != NULL)
++ v4l2_m2m_buf_done(vb, VB2_BUF_STATE_ERROR);
++ }
++
++ spin_unlock_irqrestore(&ctx->imr->lock, flags);
++
++ v4l2_dbg(1, debug, &ctx->imr->v4l2_dev, "%s streaming stopped\n",
++ (V4L2_TYPE_IS_OUTPUT(vq->type) ? "output" : "capture"));
++
++ //pm_runtime_put(ctx->imr->dev);
++}
++
++/* ...buffer queue operations */
++static struct vb2_ops imr_qops = {
++ .queue_setup = imr_queue_setup,
++ .buf_prepare = imr_buf_prepare,
++ .buf_queue = imr_buf_queue,
++ .buf_finish = imr_buf_finish,
++ .start_streaming = imr_start_streaming,
++ .stop_streaming = imr_stop_streaming,
++ .wait_prepare = vb2_ops_wait_prepare,
++ .wait_finish = vb2_ops_wait_finish,
++};
++
++/* ...M2M device processing queue initialization */
++static int imr_queue_init(void *priv, struct vb2_queue *src_vq,
++ struct vb2_queue *dst_vq)
++{
++ struct imr_ctx *ctx = priv;
++ int ret;
++
++ memset(src_vq, 0, sizeof(*src_vq));
++ src_vq->type = V4L2_BUF_TYPE_VIDEO_OUTPUT;
++ src_vq->io_modes = VB2_MMAP | VB2_USERPTR | VB2_DMABUF;
++ src_vq->drv_priv = ctx;
++ src_vq->buf_struct_size = sizeof(struct imr_buffer);
++ src_vq->ops = &imr_qops;
++ src_vq->mem_ops = &vb2_dma_contig_memops;
++ src_vq->timestamp_flags = V4L2_BUF_FLAG_TIMESTAMP_MONOTONIC;
++ src_vq->lock = &ctx->imr->mutex;
++ src_vq->dev = ctx->imr->v4l2_dev.dev;
++ ret = vb2_queue_init(src_vq);
++ if (ret)
++ return ret;
++
++ memset(dst_vq, 0, sizeof(*dst_vq));
++ dst_vq->type = V4L2_BUF_TYPE_VIDEO_CAPTURE;
++ dst_vq->io_modes = VB2_MMAP | VB2_USERPTR | VB2_DMABUF;
++ dst_vq->drv_priv = ctx;
++ dst_vq->buf_struct_size = sizeof(struct v4l2_m2m_buffer);
++ dst_vq->ops = &imr_qops;
++ dst_vq->mem_ops = &vb2_dma_contig_memops;
++ dst_vq->timestamp_flags = V4L2_BUF_FLAG_TIMESTAMP_MONOTONIC;
++ dst_vq->lock = &ctx->imr->mutex;
++ ret = vb2_queue_init(dst_vq);
++ if (ret)
++ return ret;
++
++ return 0;
++}
++
++/*******************************************************************************
++ * Display list commands
++ ******************************************************************************/
++
++/* ...display list opcodes */
++#define IMR_OP_TRI(n) ((0x8A << 24) | ((n) & 0xFFFF))
++#define IMR_OP_LINE(n) ((0x8B << 24) | ((n) & 0xFFFF))
++#define IMR_OP_NOP(n) ((0x80 << 24) | ((n) & 0xFFFF))
++#define IMR_OP_TRAP ((0x8F << 24))
++#define IMR_OP_WTL(add, n) ((0x81 << 24) | (((add) / 4) << 16) | ((n) & 0xFFFF))
++#define IMR_OP_WTS(add, data) ((0x82 << 24) | (((add) / 4) << 16) | ((data) & 0xFFFF))
++#define IMR_OP_WTL2(add, n) ((0x83 << 24) | (((add) / 4) << 10) | ((n) & 0x3FF))
++#define IMR_OP_INT ((0x88 << 24))
++#define IMR_OP_SYNCM ((0x86 << 24))
++#define IMR_OP_GOSUB ((0x8C << 24))
++#define IMR_OP_RET ((0x8D << 24))
++
++/*******************************************************************************
++ * Operation type decoding helpers
++ ******************************************************************************/
++
++static inline u16 __imr_auto_sg_dg_tcm(u32 type)
++{
++ return (type & IMR_MAP_AUTOSG ? IMR_TRIM_AUTOSG : (type & IMR_MAP_AUTODG ? IMR_TRIM_AUTODG : 0)) |
++ (type & IMR_MAP_TCM ? IMR_TRIM_TCM : 0);
++}
++
++static inline u16 __imr_uvdp(u32 type)
++{
++ return __IMR_MAP_UVDPOR(type) | (type & IMR_MAP_DDP ? (1 << 8) : 0);
++}
++
++static inline u16 __imr_cpdp(u32 type)
++{
++ return (__IMR_MAP_YLDPO(type) << 8) | (__IMR_MAP_UBDPO(type) << 4) | __IMR_MAP_VRDPO(type);
++}
++
++static inline u16 __imr_luce(u32 type)
++{
++ return (type & IMR_MAP_LUCE ? IMR_CMR_LUCE : 0);
++}
++
++static inline u16 __imr_clce(u32 type)
++{
++ return (type & IMR_MAP_CLCE ? IMR_CMR_CLCE : 0);
++}
++
++/*******************************************************************************
++ * Type A (absolute coordinates of source/destination) mapping
++ ******************************************************************************/
++
++/* ...return size of the subroutine for type "a" mapping */
++static inline u32 imr_tri_type_a_get_length(struct imr_mesh *mesh, int item_size)
++{
++ return ((mesh->columns * (item_size / 2) + 1) * (mesh->rows - 1) + 1) * sizeof(u32);
++}
++
++/* ...set a mesh rows * columns using absolute coordinates */
++static inline u32 * imr_tri_set_type_a(u32 *dl, void *map, struct imr_mesh *mesh, int item_size)
++{
++ int rows = mesh->rows;
++ int columns = mesh->columns;
++ u32 stride = item_size * columns;
++ int i, j;
++
++ /* ...convert lattice into set of stripes */
++ for (i = 0; i < rows - 1; i++) {
++ *dl++ = IMR_OP_TRI(columns * 2);
++ for (j = 0; j < columns; j++) {
++ memcpy((void *)dl, map, item_size);
++ memcpy((void *)dl + item_size, map + stride, item_size);
++ dl += item_size / 2;
++ map += item_size;
++ }
++ }
++
++ *dl++ = IMR_OP_RET;
++ return dl;
++}
++
++/*******************************************************************************
++ * Type B mapping (automatically generated source or destination coordinates)
++ ******************************************************************************/
++
++/* ...calculate length of a type "b" mapping */
++static inline u32 imr_tri_type_b_get_length(struct imr_mesh *mesh, int item_size)
++{
++ return ((mesh->columns * (item_size / 2) + 2) * (mesh->rows - 1) + 4) * sizeof(u32);
++}
++
++/* ...set an auto-generated mesh n * m for a source/destination */
++static inline u32 * imr_tri_set_type_b(u32 *dl, void *map, struct imr_mesh *mesh, int item_size)
++{
++ int rows = mesh->rows;
++ int columns = mesh->columns;
++ int x0 = mesh->x0;
++ int y0 = mesh->y0;
++ int dx = mesh->dx;
++ int dy = mesh->dy;
++ int stride = item_size * columns;
++ int i, j;
++
++ /* ...set mesh configuration */
++ *dl++ = IMR_OP_WTS(IMR_AMXSR, dx);
++ *dl++ = IMR_OP_WTS(IMR_AMYSR, dy);
++
++ /* ...origin by "x" coordinate is the same across all rows */
++ *dl++ = IMR_OP_WTS(IMR_AMXOR, x0);
++
++ /* ...convert lattice into set of stripes */
++ for (i = 0; i < rows - 1; i++, y0 += dy) {
++ /* ...set origin by "y" coordinate for a current row */
++ *dl++ = IMR_OP_WTS(IMR_AMYOR, y0);
++ *dl++ = IMR_OP_TRI(2 * columns);
++
++ /* ...fill single row */
++ for (j = 0; j < columns; j++) {
++ memcpy((void *)dl, map, item_size);
++ memcpy((void *)dl + item_size, map + stride, item_size);
++ dl += item_size / 2;
++ map += item_size;
++ }
++ }
++
++ *dl++ = IMR_OP_RET;
++ return dl;
++}
++
++/*******************************************************************************
++ * Type C mapping (vertex-buffer-object)
++ ******************************************************************************/
++
++/* ...calculate length of a type "c" mapping */
++static inline u32 imr_tri_type_c_get_length(struct imr_vbo *vbo, int item_size)
++{
++ return ((4 + 3 * item_size) * vbo->num + 4);
++}
++
++/* ...set a VBO mapping using absolute coordinates */
++static inline u32 * imr_tri_set_type_c(u32 *dl, void *map, struct imr_vbo *vbo, int item_size)
++{
++ int num = vbo->num;
++ int i;
++
++ /* ...prepare list of triangles to draw */
++ for (i = 0; i < num; i++) {
++ *dl++ = IMR_OP_TRI(3);
++ memcpy((void *)dl, map, 3 * item_size);
++ dl += 3 * item_size / 4;
++ map += 3 * item_size;
++ }
++
++ *dl++ = IMR_OP_RET;
++ return dl;
++}
++
++/*******************************************************************************
++ * DL program creation
++ ******************************************************************************/
++
++/* ...return length of a DL main program */
++static inline u32 imr_dl_program_length(struct imr_ctx *ctx)
++{
++ u32 iflags = ctx->queue[0].flags;
++ u32 oflags = ctx->queue[1].flags;
++ u32 cflags = __imr_flags_common(iflags, oflags);
++
++ /* ...check if formats are compatible */
++ if (((iflags & IMR_F_PLANAR) != 0 && (oflags & IMR_F_PLANAR) == 0) || (cflags == 0)) {
++ v4l2_err(&ctx->imr->v4l2_dev, "formats are incompatible: if=%x, of=%x, cf=%x\n", iflags, oflags, cflags);
++ return 0;
++ }
++
++ /* ...maximal possible length of the program is 27 32-bits words; round up to 32 */
++ return 32 << 2;
++}
++
++/* ...setup DL for Y/YUV planar/interleaved processing */
++static inline void imr_dl_program_setup(struct imr_ctx *ctx, struct imr_cfg *cfg, u32 type, u32 *dl, u32 subaddr)
++{
++ u32 iflags = ctx->queue[0].flags;
++ u32 oflags = ctx->queue[1].flags;
++ u32 cflags = __imr_flags_common(iflags, oflags);
++ u16 src_y_fmt = (iflags & IMR_F_Y12 ? IMR_CMR_SY12 : (iflags & IMR_F_Y10 ? IMR_CMR_SY10 : 0));
++ u16 src_uv_fmt = (iflags & IMR_F_UV12 ? 2 : (iflags & IMR_F_UV10 ? 1 : 0)) << IMR_CMR_SUV_SHIFT;
++ u16 dst_y_fmt = (cflags & IMR_F_Y12 ? IMR_CMR_DY12 : (cflags & IMR_F_Y10 ? IMR_CMR_DY10 : 0));
++ u16 dst_uv_fmt = (cflags & IMR_F_UV12 ? 2 : (cflags & IMR_F_UV10 ? 1 : 0)) << IMR_CMR_DUV_SHIFT;
++ int w = ctx->queue[0].fmt.width;
++ int h = ctx->queue[0].fmt.height;
++ int W = ctx->queue[1].fmt.width;
++ int H = ctx->queue[1].fmt.height;
++
++ v4l2_dbg(2, debug, &ctx->imr->v4l2_dev, "setup %u*%u -> %u*%u mapping (type=%x)\n", w, h, W, H, type);
++
++ /* ...set triangle mode register from user-supplied descriptor */
++ *dl++ = IMR_OP_WTS(IMR_TRIMCR, 0xFFFF);
++
++ /* ...set automatic source / destination coordinates generation flags */
++ *dl++ = IMR_OP_WTS(IMR_TRIMSR, __imr_auto_sg_dg_tcm(type) | IMR_TRIM_BFE | IMR_TRIM_TME);
++
++ /* ...set source / destination coordinate precision */
++ *dl++ = IMR_OP_WTS(IMR_UVDPOR, __imr_uvdp(type));
++
++ /* ...set luminance/chromacity correction parameters precision */
++ *dl++ = IMR_OP_WTS(IMR_CPDPOR, __imr_cpdp(type));
++
++ /* ...reset rendering mode registers */
++ *dl++ = IMR_OP_WTS(IMR_CMRCCR, 0xFFFF);
++ *dl++ = IMR_OP_WTS(IMR_CMRCCR2, 0xFFFF);
++
++ /* ...set source/destination addresses of Y/UV plane */
++ *dl++ = IMR_OP_WTL(IMR_DSAR, 2);
++ cfg->dst_pa_ptr[0] = dl++;
++ cfg->src_pa_ptr[0] = dl++;
++
++ /* ...select planar/interleaved mode basing on input format */
++ if (iflags & IMR_F_PLANAR) {
++ /* ...planar input means planar output; set Y-plane precision */
++ if (cflags & IMR_F_Y8) {
++ /* ...setup Y-plane processing: YCM=0, SY/DY=xx, SUV/DUV=0 */
++ *dl++ = IMR_OP_WTS(IMR_CMRCSR, src_y_fmt | src_uv_fmt | dst_y_fmt | dst_uv_fmt | __imr_luce(type));
++
++ /* ...set source/destination strides basing on Y-plane precision */
++ *dl++ = IMR_OP_WTS(IMR_DSTR, W << (cflags & IMR_F_Y10 ? 1 : 0));
++ *dl++ = IMR_OP_WTS(IMR_SSTR, w << (iflags & IMR_F_Y10 ? 1 : 0));
++ } else {
++ /* ...setup UV-plane processing only */
++ *dl++ = IMR_OP_WTS(IMR_CMRCSR, IMR_CMR_YCM | src_uv_fmt | dst_uv_fmt | __imr_clce(type));
++
++ /* ...set source/destination strides basing on UV-plane precision */
++ *dl++ = IMR_OP_WTS(IMR_DSTR, W << (cflags & IMR_F_UV10 ? 1 : 0));
++ *dl++ = IMR_OP_WTS(IMR_SSTR, w << (iflags & IMR_F_UV10 ? 1 : 0));
++ }
++ } else {
++ u16 src_fmt = (iflags & IMR_F_UV_SWAP ? IMR_CMR2_UVFORM : 0) | (iflags & IMR_F_YUV_SWAP ? IMR_CMR2_YUV422FORM : 0);
++ u32 dst_fmt = (oflags & IMR_F_YUV_SWAP ? IMR_TRIC_YCFORM : 0);
++
++ /* ...interleaved input; output is either interleaved or planar */
++ *dl++ = IMR_OP_WTS(IMR_CMRCSR2, IMR_CMR2_YUV422E | src_fmt);
++
++ /* ...destination is always YUYV or UYVY */
++ *dl++ = IMR_OP_WTL(IMR_TRICR, 1);
++ *dl++ = dst_fmt;
++
++ /* ...set precision of Y/UV planes and required correction */
++ *dl++ = IMR_OP_WTS(IMR_CMRCSR, src_y_fmt | src_uv_fmt | dst_y_fmt | dst_uv_fmt | __imr_clce(type) | __imr_luce(type));
++
++ /* ...set source stride basing on precision (2 or 4 bytes/pixel) */
++ *dl++ = IMR_OP_WTS(IMR_SSTR, w << (iflags & IMR_F_Y10 ? 2 : 1));
++
++ /* ...if output is planar, put the offset value */
++ if (oflags & IMR_F_PLANAR) {
++ /* ...specify offset of a destination UV plane */
++ *dl++ = IMR_OP_WTL(IMR_DSOR, 1);
++ *dl++ = W * H;
++
++ /* ...destination stride is 1 or 2 bytes/pixel (same for both Y and UV planes) */
++ *dl++ = IMR_OP_WTS(IMR_DSTR, W << (cflags & IMR_F_Y10 ? 1 : 0));
++ } else {
++ /* ...destination stride if 2 or 4 bytes/pixel (Y and UV planes interleaved) */
++ *dl++ = IMR_OP_WTS(IMR_DSTR, W << (cflags & IMR_F_Y10 ? 2 : 1));
++ }
++ }
++
++ /* ...set source width/height of Y/UV plane (for Y plane upper part of SUSR is ignored) */
++ *dl++ = IMR_OP_WTL(IMR_SUSR, 2);
++ *dl++ = ((w - 2) << 16) | (w - 1);
++ *dl++ = h - 1;
++
++ /* ...invoke subroutine for triangles drawing */
++ *dl++ = IMR_OP_GOSUB;
++ *dl++ = subaddr;
++
++ /* ...if we have a planar output with both Y and UV planes available */
++ if ((cflags & (IMR_F_PLANAR | IMR_F_Y8 | IMR_F_UV8)) == (IMR_F_PLANAR | IMR_F_Y8 | IMR_F_UV8)) {
++ /* ...select UV-plane processing mode; put sync before switching */
++ *dl++ = IMR_OP_SYNCM;
++
++ /* ...setup UV-plane source/destination addresses */
++ *dl++ = IMR_OP_WTL(IMR_DSAR, 2);
++ cfg->dst_pa_ptr[1] = dl++;
++ cfg->src_pa_ptr[1] = dl++;
++
++ /* ...select correction mode */
++ *dl++ = IMR_OP_WTS(IMR_CMRCSR, IMR_CMR_YCM | __imr_clce(type));
++
++ /* ...luminance correction bit must be cleared (if it was set) */
++ *dl++ = IMR_OP_WTS(IMR_CMRCCR, IMR_CMR_LUCE);
++
++ /* ...draw triangles */
++ *dl++ = IMR_OP_GOSUB;
++ *dl++ = subaddr;
++ } else {
++ /* ...clear pointers to the source/destination UV-planes addresses */
++ cfg->src_pa_ptr[1] = cfg->dst_pa_ptr[1] = NULL;
++ }
++
++ /* ...signal completion of the operation */
++ *dl++ = IMR_OP_SYNCM;
++ *dl++ = IMR_OP_TRAP;
++}
++
++/*******************************************************************************
++ * Mapping specification processing
++ ******************************************************************************/
++
++/* ...set mapping data (function called with video device lock held) */
++static int imr_ioctl_map(struct imr_ctx *ctx, struct imr_map_desc *desc)
++{
++ struct imr_device *imr = ctx->imr;
++ struct imr_mesh *mesh;
++ struct imr_vbo *vbo;
++ struct imr_cfg *cfg;
++ void *buf, *map;
++ u32 type;
++ u32 length, item_size;
++ u32 tri_length;
++ void *dl_vaddr;
++ u32 dl_size;
++ u32 dl_start_offset;
++ dma_addr_t dl_dma_addr;
++ int ret;
++
++ /* ...read remainder of data into temporary buffer */
++ length = desc->size;
++ buf = kmalloc(length, GFP_KERNEL);
++ if (!buf) {
++ v4l2_err(&imr->v4l2_dev, "failed to allocate %u bytes for mapping reading\n", length);
++ return -ENOMEM;
++ }
++
++ /* ...copy mesh data */
++ if (copy_from_user(buf, (void __user *)desc->data, length)) {
++ v4l2_err(&imr->v4l2_dev, "failed to read %u bytes of mapping specification\n", length);
++ ret = -EFAULT;
++ goto out;
++ }
++
++ type = desc->type;
++
++ /* ...mesh item size calculation */
++ item_size = (type & IMR_MAP_LUCE ? 4 : 0) + (type & IMR_MAP_CLCE ? 4 : 0);
++
++ /* ...calculate the length of a display list */
++ if (type & IMR_MAP_MESH) {
++ /* ...assure we have proper mesh descriptor */
++ if (length < sizeof(struct imr_mesh)) {
++ v4l2_err(&imr->v4l2_dev, "invalid mesh specification size: %u\n", length);
++ ret = -EINVAL;
++ goto out;
++ }
++
++ mesh = (struct imr_mesh *)buf;
++ length -= sizeof(struct imr_mesh);
++ map = buf + sizeof(struct imr_mesh);
++
++ if (type & (IMR_MAP_AUTODG | IMR_MAP_AUTOSG)) {
++ /* ...source / destination vertex size is 4 bytes */
++ item_size += 4;
++
++ /* ...mapping is given using automatic generation pattern; check size */
++ if (mesh->rows * mesh->columns * item_size != length) {
++ v4l2_err(&imr->v4l2_dev, "invalid mesh size: %u*%u*%u != %u\n", mesh->rows, mesh->columns, item_size, length);
++ ret = -EINVAL;
++ goto out;
++ }
++
++ /* ...calculate size of triangles drawing subroutine */
++ tri_length = imr_tri_type_b_get_length(mesh, item_size);
++ } else {
++ /* ...source / destination vertes size if 8 bytes */
++ item_size += 8;
++
++ /* ...mapping is done with absolute coordinates */
++ if (mesh->rows * mesh->columns * item_size != length) {
++ v4l2_err(&imr->v4l2_dev, "invalid mesh size: %u*%u*%u != %u\n", mesh->rows, mesh->columns, item_size, length);
++ ret = -EINVAL;
++ goto out;
++ }
++
++ /* ...calculate size of triangles drawing subroutine */
++ tri_length = imr_tri_type_a_get_length(mesh, item_size);
++ }
++ } else {
++ /* ...assure we have proper VBO descriptor */
++ if (length < sizeof(struct imr_vbo)) {
++ v4l2_err(&imr->v4l2_dev, "invalid vbo specification size: %u\n", length);
++ ret = -EINVAL;
++ goto out;
++ }
++
++ /* ...make sure there is no automatic-generation flags */
++ if (type & (IMR_MAP_AUTODG | IMR_MAP_AUTOSG)) {
++ v4l2_err(&imr->v4l2_dev, "invalid auto-dg/sg flags: 0x%x\n", type);
++ ret = -EINVAL;
++ goto out;
++ }
++
++ vbo = (struct imr_vbo *)buf;
++ length -= sizeof(struct imr_vbo);
++ map = buf + sizeof(struct imr_vbo);
++
++ /* ...vertex is given with absolute coordinates */
++ item_size += 8;
++
++ /* ...check the length is sane */
++ if (length != vbo->num * 3 * item_size) {
++ v4l2_err(&imr->v4l2_dev, "invalid vbo size: %u*%u*3 != %u\n", vbo->num, item_size, length);
++ ret = -EINVAL;
++ goto out;
++ }
++
++ /* ...calculate size of trangles drawing subroutine */
++ tri_length = imr_tri_type_c_get_length(vbo, item_size);
++ }
++
++ /* ...DL main program shall start with 8-byte aligned address */
++ dl_start_offset = (tri_length + 7) & ~7;
++
++ /* ...calculate main routine length */
++ dl_size = imr_dl_program_length(ctx);
++ if (!dl_size) {
++ v4l2_err(&imr->v4l2_dev, "format configuration error\n");
++ ret = -EINVAL;
++ goto out;
++ }
++
++ /* ...we use a single display list, with TRI subroutine prepending MAIN */
++ dl_size += dl_start_offset;
++
++ /* ...unref current configuration (will not be used by subsequent jobs) */
++ imr_cfg_unref(ctx, ctx->cfg);
++
++ /* ...create new configuration */
++ ctx->cfg = cfg = imr_cfg_create(ctx, dl_size, dl_start_offset);
++ if (IS_ERR(cfg)) {
++ ret = PTR_ERR(cfg);
++ v4l2_err(&imr->v4l2_dev, "failed to create configuration: %d\n", ret);
++ goto out;
++ }
++
++ /* ...get pointer to the new display list */
++ dl_vaddr = cfg->dl_vaddr;
++ dl_dma_addr = cfg->dl_dma_addr;
++
++ /* ...prepare a triangles drawing subroutine */
++ if (type & IMR_MAP_MESH) {
++ if (type & (IMR_MAP_AUTOSG | IMR_MAP_AUTODG)) {
++ imr_tri_set_type_b(dl_vaddr, map, mesh, item_size);
++ } else {
++ imr_tri_set_type_a(dl_vaddr, map, mesh, item_size);
++ }
++ } else {
++ imr_tri_set_type_c(dl_vaddr, map, vbo, item_size);
++ }
++
++ /* ...prepare main DL-program */
++ imr_dl_program_setup(ctx, cfg, type, dl_vaddr + dl_start_offset, (u32)dl_dma_addr);
++
++ /* ...update cropping parameters */
++ cfg->dst_subpixel = (type & IMR_MAP_DDP ? 2 : 0);
++
++ /* ...display list updated successfully */
++ v4l2_dbg(2, debug, &ctx->imr->v4l2_dev, "display-list created: #%u[%08X]:%u[%u]\n",
++ cfg->id, (u32)dl_dma_addr, dl_size, dl_start_offset);
++
++ if (debug >= 4)
++ print_hex_dump_bytes("DL-", DUMP_PREFIX_OFFSET, dl_vaddr + dl_start_offset, dl_size - dl_start_offset);
++
++ /* ...success */
++ ret = 0;
++
++out:
++ /* ...release interim buffer */
++ kfree(buf);
++
++ return ret;
++}
++
++/*******************************************************************************
++ * V4L2 I/O controls
++ ******************************************************************************/
++
++/* ...test for a format supported */
++static int __imr_try_fmt(struct imr_ctx *ctx, struct v4l2_format *f)
++{
++ struct v4l2_pix_format *pix = &f->fmt.pix;
++ u32 fourcc = pix->pixelformat;
++ int i;
++
++ /* ...both output and capture interface have the same set of supported formats */
++ for (i = 0; i < ARRAY_SIZE(imr_lx4_formats); i++) {
++ if (fourcc == imr_lx4_formats[i].fourcc) {
++ /* ...fix-up format specification as needed */
++ pix->field = V4L2_FIELD_NONE;
++
++ v4l2_dbg(1, debug, &ctx->imr->v4l2_dev, "format request: '%c%c%c%c', %d*%d\n",
++ (fourcc >> 0) & 0xff, (fourcc >> 8) & 0xff,
++ (fourcc >> 16) & 0xff, (fourcc >> 24) & 0xff,
++ pix->width, pix->height);
++
++ /* ...verify source/destination image dimensions */
++ if (V4L2_TYPE_IS_OUTPUT(f->type))
++ v4l_bound_align_image(&pix->width, 128, 2048, 7, &pix->height, 1, 2048, 0, 0);
++ else
++ v4l_bound_align_image(&pix->width, 64, 2048, 6, &pix->height, 1, 2048, 0, 0);
++
++ return i;
++ }
++ }
++
++ v4l2_err(&ctx->imr->v4l2_dev, "unsupported format request: '%c%c%c%c'\n",
++ (fourcc >> 0) & 0xff, (fourcc >> 8) & 0xff,
++ (fourcc >> 16) & 0xff, (fourcc >> 24) & 0xff);
++
++ return -EINVAL;
++}
++
++/* ...capabilities query */
++static int imr_querycap(struct file *file, void *priv, struct v4l2_capability *cap)
++{
++ strlcpy(cap->driver, DRV_NAME, sizeof(cap->driver));
++ strlcpy(cap->card, DRV_NAME, sizeof(cap->card));
++ strlcpy(cap->bus_info, DRV_NAME, sizeof(cap->bus_info));
++
++ cap->device_caps = V4L2_CAP_VIDEO_CAPTURE | V4L2_CAP_VIDEO_OUTPUT |
++ V4L2_CAP_VIDEO_M2M | V4L2_CAP_STREAMING;
++
++ cap->capabilities = cap->device_caps | V4L2_CAP_DEVICE_CAPS;
++
++ return 0;
++}
++
++/* ...enumerate supported formats */
++static int imr_enum_fmt(struct file *file, void *priv, struct v4l2_fmtdesc *f)
++{
++ /* ...no distinction between output/capture formats */
++ if (f->index < ARRAY_SIZE(imr_lx4_formats)) {
++ const struct imr_format_info *fmt = &imr_lx4_formats[f->index];
++ strlcpy(f->description, fmt->name, sizeof(f->description));
++ f->pixelformat = fmt->fourcc;
++ return 0;
++ }
++
++ return -EINVAL;
++}
++
++/* ...retrieve current queue format; operation is locked ? */
++static int imr_g_fmt(struct file *file, void *priv, struct v4l2_format *f)
++{
++ struct imr_ctx *ctx = fh_to_ctx(priv);
++ struct vb2_queue *vq;
++ struct imr_q_data *q_data;
++
++ vq = v4l2_m2m_get_vq(ctx->m2m_ctx, f->type);
++ if (!vq)
++ return -EINVAL;
++
++ q_data = &ctx->queue[V4L2_TYPE_IS_OUTPUT(f->type) ? 0 : 1];
++
++ /* ...processing is locked? tbd */
++ f->fmt.pix = q_data->fmt;
++
++ return 0;
++}
++
++/* ...test particular format; operation is not locked */
++static int imr_try_fmt(struct file *file, void *priv, struct v4l2_format *f)
++{
++ struct imr_ctx *ctx = fh_to_ctx(priv);
++ struct vb2_queue *vq;
++
++ /* ...make sure we have a queue of particular type */
++ vq = v4l2_m2m_get_vq(ctx->m2m_ctx, f->type);
++ if (!vq)
++ return -EINVAL;
++
++ /* ...test if format is supported (adjust as appropriate) */
++ return (__imr_try_fmt(ctx, f) >= 0 ? 0 : -EINVAL);
++}
++
++/* ...apply queue format; operation is locked ? */
++static int imr_s_fmt(struct file *file, void *priv, struct v4l2_format *f)
++{
++ struct imr_ctx *ctx = fh_to_ctx(priv);
++ struct vb2_queue *vq;
++ struct imr_q_data *q_data;
++ int i;
++
++ vq = v4l2_m2m_get_vq(ctx->m2m_ctx, f->type);
++ if (!vq)
++ return -EINVAL;
++
++ /* ...check if queue is busy */
++ if (vb2_is_busy(vq))
++ return -EBUSY;
++
++ /* ...test if format is supported (adjust as appropriate) */
++ i = __imr_try_fmt(ctx, f);
++ if (i < 0)
++ return -EINVAL;
++
++ /* ...format is supported; save current format in a queue-specific data */
++ q_data = &ctx->queue[V4L2_TYPE_IS_OUTPUT(f->type) ? 0 : 1];
++
++ /* ...processing is locked? tbd */
++ q_data->fmt = f->fmt.pix;
++ q_data->flags = imr_lx4_formats[i].flags;
++
++ /* ...set default crop factors */
++ if (V4L2_TYPE_IS_OUTPUT(f->type) == 0) {
++ ctx->crop[0] = 0;
++ ctx->crop[1] = f->fmt.pix.width - 1;
++ ctx->crop[2] = 0;
++ ctx->crop[3] = f->fmt.pix.height - 1;
++ }
++
++ return 0;
++}
++
++static int imr_reqbufs(struct file *file, void *priv, struct v4l2_requestbuffers *reqbufs)
++{
++ struct imr_ctx *ctx = fh_to_ctx(priv);
++
++ return v4l2_m2m_reqbufs(file, ctx->m2m_ctx, reqbufs);
++}
++
++static int imr_querybuf(struct file *file, void *priv, struct v4l2_buffer *buf)
++{
++ struct imr_ctx *ctx = fh_to_ctx(priv);
++
++ return v4l2_m2m_querybuf(file, ctx->m2m_ctx, buf);
++}
++
++static int imr_qbuf(struct file *file, void *priv, struct v4l2_buffer *buf)
++{
++ struct imr_ctx *ctx = fh_to_ctx(priv);
++
++ /* ...operation is protected with a queue lock */
++ WARN_ON(!mutex_is_locked(&ctx->imr->mutex));
++
++ /* ...verify the configuration is complete */
++ if (!V4L2_TYPE_IS_OUTPUT(buf->type) && !ctx->cfg) {
++ v4l2_err(&ctx->imr->v4l2_dev, "stream configuration is not complete\n");
++ return -EINVAL;
++ }
++
++ return v4l2_m2m_qbuf(file, ctx->m2m_ctx, buf);
++}
++
++static int imr_dqbuf(struct file *file, void *priv, struct v4l2_buffer *buf)
++{
++ struct imr_ctx *ctx = fh_to_ctx(priv);
++
++ return v4l2_m2m_dqbuf(file, ctx->m2m_ctx, buf);
++}
++
++static int imr_expbuf(struct file *file, void *priv, struct v4l2_exportbuffer *eb)
++{
++ struct imr_ctx *ctx = fh_to_ctx(priv);
++
++ return v4l2_m2m_expbuf(file, ctx->m2m_ctx, eb);
++}
++
++static int imr_streamon(struct file *file, void *priv, enum v4l2_buf_type type)
++{
++ struct imr_ctx *ctx = fh_to_ctx(priv);
++
++ /* ...context is prepared for a streaming */
++ return v4l2_m2m_streamon(file, ctx->m2m_ctx, type);
++}
++
++static int imr_streamoff(struct file *file, void *priv, enum v4l2_buf_type type)
++{
++ struct imr_ctx *ctx = fh_to_ctx(priv);
++
++ return v4l2_m2m_streamoff(file, ctx->m2m_ctx, type);
++}
++
++static int imr_g_crop(struct file *file, void *priv, struct v4l2_crop *cr)
++{
++ struct imr_ctx *ctx = fh_to_ctx(priv);
++
++ /* ...subpixel resolution of output buffer is not counted here */
++ cr->c.left = ctx->crop[0];
++ cr->c.top = ctx->crop[2];
++ cr->c.width = ctx->crop[1] - ctx->crop[0];
++ cr->c.height = ctx->crop[3] - ctx->crop[2];
++
++ return 0;
++}
++
++static int imr_s_crop(struct file *file, void *priv, const struct v4l2_crop *cr)
++{
++ struct imr_ctx *ctx = fh_to_ctx(priv);
++ int x0 = cr->c.left;
++ int y0 = cr->c.top;
++ int x1 = x0 + cr->c.width;
++ int y1 = y0 + cr->c.height;
++
++ if (x0 < 0 || x1 >= 2048 || y0 < 0 || y1 >= 2048) {
++ v4l2_err(&ctx->imr->v4l2_dev, "invalid cropping: %d/%d/%d/%d\n", x0, x1, y0, y1);
++ return -EINVAL;
++ }
++
++ /* ...subpixel resolution of output buffer is not counted here */
++ ctx->crop[0] = x0;
++ ctx->crop[1] = x1;
++ ctx->crop[2] = y0;
++ ctx->crop[3] = y1;
++
++ return 0;
++}
++
++/* ...customized I/O control processing */
++static long imr_default(struct file *file, void *fh, bool valid_prio, unsigned int cmd, void *arg)
++{
++ struct imr_ctx *ctx = fh_to_ctx(fh);
++
++ switch (cmd) {
++ case VIDIOC_IMR_MESH:
++ /* ...set mesh data */
++ return imr_ioctl_map(ctx, (struct imr_map_desc *)arg);
++
++ default:
++ return -ENOIOCTLCMD;
++ }
++}
++
++static const struct v4l2_ioctl_ops imr_ioctl_ops = {
++ .vidioc_querycap = imr_querycap,
++
++ .vidioc_enum_fmt_vid_cap = imr_enum_fmt,
++ .vidioc_enum_fmt_vid_out = imr_enum_fmt,
++ .vidioc_g_fmt_vid_cap = imr_g_fmt,
++ .vidioc_g_fmt_vid_out = imr_g_fmt,
++ .vidioc_try_fmt_vid_cap = imr_try_fmt,
++ .vidioc_try_fmt_vid_out = imr_try_fmt,
++ .vidioc_s_fmt_vid_cap = imr_s_fmt,
++ .vidioc_s_fmt_vid_out = imr_s_fmt,
++
++ .vidioc_reqbufs = imr_reqbufs,
++ .vidioc_querybuf = imr_querybuf,
++ .vidioc_qbuf = imr_qbuf,
++ .vidioc_dqbuf = imr_dqbuf,
++ .vidioc_expbuf = imr_expbuf,
++ .vidioc_streamon = imr_streamon,
++ .vidioc_streamoff = imr_streamoff,
++
++ .vidioc_g_crop = imr_g_crop,
++ .vidioc_s_crop = imr_s_crop,
++
++ .vidioc_default = imr_default,
++};
++
++/*******************************************************************************
++ * Generic device file operations
++ ******************************************************************************/
++
++static int imr_open(struct file *file)
++{
++ struct imr_device *imr = video_drvdata(file);
++ struct video_device *vfd = video_devdata(file);
++ struct imr_ctx *ctx;
++ int ret;
++
++ /* ...allocate processing context associated with given instance */
++ ctx = kzalloc(sizeof(*ctx), GFP_KERNEL);
++ if (!ctx)
++ return -ENOMEM;
++
++ /* ...initialize per-file-handle structure */
++ v4l2_fh_init(&ctx->fh, vfd);
++ //ctx->fh.ctrl_handler = &ctx->ctrl_handler;
++ file->private_data = &ctx->fh;
++ v4l2_fh_add(&ctx->fh);
++
++ /* ...set default source / destination formats - need that? */
++ ctx->imr = imr;
++ ctx->queue[0].fmt.pixelformat = 0;
++ ctx->queue[1].fmt.pixelformat = 0;
++
++ /* ...set default cropping parameters */
++ ctx->crop[1] = ctx->crop[3] = 0x3FF;
++
++ /* ...initialize M2M processing context */
++ ctx->m2m_ctx = v4l2_m2m_ctx_init(imr->m2m_dev, ctx, imr_queue_init);
++ if (IS_ERR(ctx->m2m_ctx)) {
++ ret = PTR_ERR(ctx->m2m_ctx);
++ goto v4l_prepare_rollback;
++ }
++
++#if 0
++ /* ...initialize controls and stuff */
++ ret = imr_controls_create(ctx);
++ if (ret < 0)
++ goto v4l_prepare_rollback;
++#endif
++
++ /* ...lock access to global device data */
++ if (mutex_lock_interruptible(&imr->mutex)) {
++ ret = -ERESTARTSYS;
++ goto v4l_prepare_rollback;
++ }
++
++ /* ...bring-up device as needed */
++ if (imr->refcount == 0) {
++ ret = clk_prepare_enable(imr->clock);
++ if (ret < 0)
++ goto device_prepare_rollback;
++ }
++
++ imr->refcount++;
++
++ mutex_unlock(&imr->mutex);
++
++ v4l2_dbg(1, debug, &imr->v4l2_dev, "IMR device opened (refcount=%u)\n", imr->refcount);
++
++ return 0;
++
++device_prepare_rollback:
++ /* ...unlock global device data */
++ mutex_unlock(&imr->mutex);
++
++v4l_prepare_rollback:
++ /* ...destroy context */
++ v4l2_fh_del(&ctx->fh);
++ v4l2_fh_exit(&ctx->fh);
++ kfree(ctx);
++
++ return ret;
++}
++
++static int imr_release(struct file *file)
++{
++ struct imr_device *imr = video_drvdata(file);
++ struct imr_ctx *ctx = fh_to_ctx(file->private_data);
++
++ /* ...I don't need to get a device-scope lock here really - tbd */
++ mutex_lock(&imr->mutex);
++
++ /* ...destroy M2M device processing context */
++ v4l2_m2m_ctx_release(ctx->m2m_ctx);
++ //v4l2_ctrl_handler_free(&ctx->ctrl_handler);
++ v4l2_fh_del(&ctx->fh);
++ v4l2_fh_exit(&ctx->fh);
++
++ /* ...drop active configuration as needed */
++ imr_cfg_unref(ctx, ctx->cfg);
++
++ /* ...make sure there are no more active configs */
++ WARN_ON(ctx->cfg_num);
++
++ /* ...destroy context data */
++ kfree(ctx);
++
++ /* ...disable hardware operation */
++ if (--imr->refcount == 0)
++ clk_disable_unprepare(imr->clock);
++
++ mutex_unlock(&imr->mutex);
++
++ v4l2_dbg(1, debug, &imr->v4l2_dev, "closed device instance\n");
++
++ return 0;
++}
++
++static unsigned int imr_poll(struct file *file, struct poll_table_struct *wait)
++{
++ struct imr_device *imr = video_drvdata(file);
++ struct imr_ctx *ctx = fh_to_ctx(file->private_data);
++ unsigned int res;
++
++ if (mutex_lock_interruptible(&imr->mutex))
++ return -ERESTARTSYS;
++
++ res = v4l2_m2m_poll(file, ctx->m2m_ctx, wait);
++ mutex_unlock(&imr->mutex);
++
++ return res;
++}
++
++static int imr_mmap(struct file *file, struct vm_area_struct *vma)
++{
++ struct imr_device *imr = video_drvdata(file);
++ struct imr_ctx *ctx = fh_to_ctx(file->private_data);
++ int ret;
++
++ /* ...should we protect all M2M operations with mutex? - tbd */
++ if (mutex_lock_interruptible(&imr->mutex))
++ return -ERESTARTSYS;
++
++ ret = v4l2_m2m_mmap(file, ctx->m2m_ctx, vma);
++
++ mutex_unlock(&imr->mutex);
++
++ return ret;
++}
++
++static const struct v4l2_file_operations imr_fops = {
++ .owner = THIS_MODULE,
++ .open = imr_open,
++ .release = imr_release,
++ .poll = imr_poll,
++ .mmap = imr_mmap,
++ .unlocked_ioctl = video_ioctl2,
++};
++
++/*******************************************************************************
++ * M2M device interface
++ ******************************************************************************/
++
++#if 0
++/* ...job cleanup function */
++static void imr_cleanup(struct imr_ctx *ctx)
++{
++ struct imr_device *imr = ctx->imr;
++ struct vb2_v4l2_buffer *src_buf, *dst_buf;
++ unsigned long flags;
++
++ /* ...interlock buffer handling with interrupt */
++ spin_lock_irqsave(&imr->lock, flags);
++
++ while ((src_buf = v4l2_m2m_src_buf_remove(ctx->m2m_ctx)) != NULL)
++ v4l2_m2m_buf_done(src_buf, VB2_BUF_STATE_ERROR);
++
++ while ((dst_buf = v4l2_m2m_dst_buf_remove(ctx->m2m_ctx)) != NULL)
++ v4l2_m2m_buf_done(dst_buf, VB2_BUF_STATE_ERROR);
++
++ /* ...release lock before we mark current job as finished */
++ spin_unlock_irqrestore(&imr->lock, flags);
++}
++#endif
++
++/* ...job execution function */
++static void imr_device_run(void *priv)
++{
++ struct imr_ctx *ctx = priv;
++ struct imr_device *imr = ctx->imr;
++ struct imr_cfg *cfg;
++ struct vb2_buffer *src_buf, *dst_buf;
++ u32 src_addr, dst_addr;
++ unsigned long flags;
++
++ v4l2_dbg(3, debug, &imr->v4l2_dev, "run next job...\n");
++
++ /* ...protect access to internal device state */
++ spin_lock_irqsave(&imr->lock, flags);
++
++ /* ...retrieve input/output buffers */
++ src_buf = v4l2_m2m_next_src_buf(ctx->m2m_ctx);
++ dst_buf = v4l2_m2m_next_dst_buf(ctx->m2m_ctx);
++
++ /* ...take configuration pointer associated with input buffer */
++ cfg = to_imr_buffer(to_vb2_v4l2_buffer(src_buf))->cfg;
++
++ /* ...cancel software reset state as needed */
++ iowrite32(0, imr->mmio + IMR_CR);
++
++ /* ...set cropping data with respect to destination sub-pixel mode */
++ iowrite32(ctx->crop[0] << cfg->dst_subpixel, imr->mmio + IMR_XMINR);
++ iowrite32(ctx->crop[1] << cfg->dst_subpixel, imr->mmio + IMR_XMAXR);
++ iowrite32(ctx->crop[2] << cfg->dst_subpixel, imr->mmio + IMR_YMINR);
++ iowrite32(ctx->crop[3] << cfg->dst_subpixel, imr->mmio + IMR_YMAXR);
++
++ /* ...adjust source/destination parameters of the program (interleaved / semiplanar) */
++ *cfg->src_pa_ptr[0] = src_addr = (u32)vb2_dma_contig_plane_dma_addr(src_buf, 0);
++ *cfg->dst_pa_ptr[0] = dst_addr = (u32)vb2_dma_contig_plane_dma_addr(dst_buf, 0);
++
++ /* ...adjust source/destination parameters of the UV-plane as needed */
++ if (cfg->src_pa_ptr[1] && cfg->dst_pa_ptr[1]) {
++ *cfg->src_pa_ptr[1] = src_addr + ctx->queue[0].fmt.width * ctx->queue[0].fmt.height;
++ *cfg->dst_pa_ptr[1] = dst_addr + ctx->queue[1].fmt.width * ctx->queue[1].fmt.height;
++ }
++
++ v4l2_dbg(3, debug, &imr->v4l2_dev, "process buffer-pair 0x%08x:0x%08x\n",
++ *cfg->src_pa_ptr[0], *cfg->dst_pa_ptr[0]);
++
++ /* ...force clearing of status register bits */
++ iowrite32(0x7, imr->mmio + IMR_SRCR);
++
++ /* ...unmask/enable interrupts */
++ iowrite32(ioread32(imr->mmio + IMR_ICR) | (IMR_ICR_TRAEN | IMR_ICR_IEREN | IMR_ICR_INTEN), imr->mmio + IMR_ICR);
++ iowrite32(ioread32(imr->mmio + IMR_IMR) & ~(IMR_ICR_TRAEN | IMR_ICR_IEREN | IMR_ICR_INTEN), imr->mmio + IMR_IMR);
++
++ /* ...set display list address */
++ iowrite32(cfg->dl_dma_addr + cfg->dl_start_offset, imr->mmio + IMR_DLSAR);
++
++ /* ...explicitly flush any pending write operations (don't need that, I guess) */
++ wmb();
++
++ /* ...start rendering operation */
++ iowrite32(IMR_CR_RS, imr->mmio + IMR_CR);
++
++ /* ...timestamp input buffer */
++ src_buf->timestamp = ktime_get_ns();
++
++ /* ...unlock device access */
++ spin_unlock_irqrestore(&imr->lock, flags);
++
++ v4l2_dbg(1, debug, &imr->v4l2_dev, "rendering started: status=%X, DLSAR=0x%08X, DLPR=0x%08X\n", ioread32(imr->mmio + IMR_SR), ioread32(imr->mmio + IMR_DLSAR), ioread32(imr->mmio + IMR_DLSR));
++}
++
++/* ...check whether a job is ready for execution */
++static int imr_job_ready(void *priv)
++{
++ /* ...no specific requirements on the job readiness */
++ return 1;
++}
++
++/* ...abort currently processed job */
++static void imr_job_abort(void *priv)
++{
++ struct imr_ctx *ctx = priv;
++ struct imr_device *imr = ctx->imr;
++ unsigned long flags;
++
++ /* ...protect access to internal device state */
++ spin_lock_irqsave(&imr->lock, flags);
++
++ /* ...make sure current job is still current (may get finished by interrupt already) */
++ if (v4l2_m2m_get_curr_priv(imr->m2m_dev) == ctx) {
++ v4l2_dbg(1, debug, &imr->v4l2_dev, "abort job: status=%X, DLSAR=0x%08X, DLPR=0x%08X\n",
++ ioread32(imr->mmio + IMR_SR), ioread32(imr->mmio + IMR_DLSAR), ioread32(imr->mmio + IMR_DLSR));
++
++ /* ...force device reset to stop processing of the buffers */
++ //iowrite32(IMR_CR_SWRST, imr->mmio + IMR_CR);
++
++ /* ...resetting the module while operation is active may lead to hw-stall */
++ spin_unlock_irqrestore(&imr->lock, flags);
++
++ /* ...finish current job as interrupt will probably not occur */
++ //v4l2_m2m_job_finish(imr->m2m_dev, ctx->m2m_ctx);
++ } else {
++ spin_unlock_irqrestore(&imr->lock, flags);
++ v4l2_dbg(1, debug, &imr->v4l2_dev, "job has completed already\n");
++ }
++}
++
++/* ...M2M interface definition */
++static struct v4l2_m2m_ops imr_m2m_ops = {
++ .device_run = imr_device_run,
++ .job_ready = imr_job_ready,
++ .job_abort = imr_job_abort,
++};
++
++/*******************************************************************************
++ * Interrupt handling
++ ******************************************************************************/
++
++static irqreturn_t imr_irq_handler(int irq, void *data)
++{
++ struct imr_device *imr = data;
++ struct imr_ctx *ctx;
++ struct vb2_v4l2_buffer *src_buf, *dst_buf;
++ u32 status;
++ irqreturn_t ret = IRQ_NONE;
++
++ /* ...check and ack interrupt status */
++ status = ioread32(imr->mmio + IMR_SR);
++ iowrite32(status, imr->mmio + IMR_SRCR);
++ if (!(status & (IMR_SR_INT | IMR_SR_IER | IMR_SR_TRA))) {
++ v4l2_err(&imr->v4l2_dev, "spurious interrupt: %x\n", status);
++ return ret;
++ }
++
++ /* ...protect access to current context */
++ spin_lock(&imr->lock);
++
++ /* ...get current job context (may have been cancelled already) */
++ ctx = v4l2_m2m_get_curr_priv(imr->m2m_dev);
++ if (!ctx) {
++ v4l2_dbg(3, debug, &imr->v4l2_dev, "no active job\n");
++ goto handled;
++ }
++
++ /* ...remove buffers (may have been removed already?) */
++ src_buf = v4l2_m2m_src_buf_remove(ctx->m2m_ctx);
++ dst_buf = v4l2_m2m_dst_buf_remove(ctx->m2m_ctx);
++ if (!src_buf || !dst_buf) {
++ v4l2_dbg(3, debug, &imr->v4l2_dev, "no buffers associated with current context\n");
++ goto handled;
++ }
++
++ /* ...check for a TRAP interrupt indicating completion of current DL */
++ if (status & IMR_SR_TRA) {
++ /* ...operation completed normally; timestamp output buffer */
++ dst_buf->vb2_buf.timestamp = ktime_get_ns();
++ if (src_buf->flags & V4L2_BUF_FLAG_TIMECODE)
++ dst_buf->timecode = src_buf->timecode;
++ dst_buf->flags = src_buf->flags & (V4L2_BUF_FLAG_TIMECODE | V4L2_BUF_FLAG_KEYFRAME |
++ V4L2_BUF_FLAG_PFRAME | V4L2_BUF_FLAG_BFRAME | V4L2_BUF_FLAG_TSTAMP_SRC_MASK);
++ dst_buf->sequence = src_buf->sequence = ctx->sequence++;
++ v4l2_m2m_buf_done(src_buf, VB2_BUF_STATE_DONE);
++ v4l2_m2m_buf_done(dst_buf, VB2_BUF_STATE_DONE);
++
++ v4l2_dbg(3, debug, &imr->v4l2_dev, "buffers <0x%08x,0x%08x> done\n",
++ (u32)vb2_dma_contig_plane_dma_addr(&src_buf->vb2_buf, 0),
++ (u32)vb2_dma_contig_plane_dma_addr(&dst_buf->vb2_buf, 0));
++ } else {
++ /* ...operation completed in error; no way to understand what exactly went wrong */
++ v4l2_m2m_buf_done(src_buf, VB2_BUF_STATE_ERROR);
++ v4l2_m2m_buf_done(dst_buf, VB2_BUF_STATE_ERROR);
++
++ v4l2_dbg(3, debug, &imr->v4l2_dev, "buffers <0x%08x,0x%08x> done in error\n",
++ (u32)vb2_dma_contig_plane_dma_addr(&src_buf->vb2_buf, 0),
++ (u32)vb2_dma_contig_plane_dma_addr(&dst_buf->vb2_buf, 0));
++ }
++
++ spin_unlock(&imr->lock);
++
++ /* ...finish current job (and start any pending) */
++ v4l2_m2m_job_finish(imr->m2m_dev, ctx->m2m_ctx);
++
++ return IRQ_HANDLED;
++
++handled:
++ /* ...again, what exactly is to be protected? */
++ spin_unlock(&imr->lock);
++
++ return IRQ_HANDLED;
++}
++
++/*******************************************************************************
++ * Device probing / removal interface
++ ******************************************************************************/
++
++static int imr_probe(struct platform_device *pdev)
++{
++ struct imr_device *imr;
++ struct resource *res;
++ int ret;
++
++ imr = devm_kzalloc(&pdev->dev, sizeof(*imr), GFP_KERNEL);
++ if (!imr)
++ return -ENOMEM;
++
++ mutex_init(&imr->mutex);
++ spin_lock_init(&imr->lock);
++ imr->dev = &pdev->dev;
++
++ /* ...memory-mapped registers */
++ res = platform_get_resource(pdev, IORESOURCE_MEM, 0);
++ if (!res) {
++ dev_err(&pdev->dev, "cannot get memory region\n");
++ return -EINVAL;
++ }
++
++ imr->mmio = devm_ioremap_resource(&pdev->dev, res);
++ if (IS_ERR(imr->mmio))
++ return PTR_ERR(imr->mmio);
++
++ /* ...interrupt service routine registration */
++ imr->irq = ret = platform_get_irq(pdev, 0);
++ if (ret < 0) {
++ dev_err(&pdev->dev, "cannot find IRQ\n");
++ return ret;
++ }
++
++ ret = devm_request_irq(&pdev->dev, imr->irq, imr_irq_handler, 0, dev_name(&pdev->dev), imr);
++ if (ret) {
++ dev_err(&pdev->dev, "cannot claim IRQ %d\n", imr->irq);
++ return ret;
++ }
++
++ imr->clock = devm_clk_get(&pdev->dev, NULL);
++ if (IS_ERR(imr->clock)) {
++ dev_err(&pdev->dev, "cannot get clock\n");
++ return PTR_ERR(imr->clock);
++ }
++
++ /* ...create v4l2 device */
++ ret = v4l2_device_register(&pdev->dev, &imr->v4l2_dev);
++ if (ret) {
++ dev_err(&pdev->dev, "Failed to register v4l2 device\n");
++ return ret;
++ }
++
++ /* ...create mem2mem device handle */
++ imr->m2m_dev = v4l2_m2m_init(&imr_m2m_ops);
++ if (IS_ERR(imr->m2m_dev)) {
++ v4l2_err(&imr->v4l2_dev, "Failed to init mem2mem device\n");
++ ret = PTR_ERR(imr->m2m_dev);
++ goto device_register_rollback;
++ }
++
++ strlcpy(imr->video_dev.name, dev_name(&pdev->dev), sizeof(imr->video_dev.name));
++ imr->video_dev.fops = &imr_fops;
++ imr->video_dev.ioctl_ops = &imr_ioctl_ops;
++ imr->video_dev.minor = -1;
++ imr->video_dev.release = video_device_release_empty;
++ imr->video_dev.lock = &imr->mutex;
++ imr->video_dev.v4l2_dev = &imr->v4l2_dev;
++ imr->video_dev.vfl_dir = VFL_DIR_M2M;
++
++ ret = video_register_device(&imr->video_dev, VFL_TYPE_GRABBER, -1);
++ if (ret) {
++ v4l2_err(&imr->v4l2_dev, "Failed to register video device\n");
++ goto m2m_init_rollback;
++ }
++
++ video_set_drvdata(&imr->video_dev, imr);
++ platform_set_drvdata(pdev, imr);
++ //pm_runtime_enable(&pdev->dev);
++
++ v4l2_info(&imr->v4l2_dev, "IMR device (pdev: %d) registered as /dev/video%d\n", pdev->id, imr->video_dev.num);
++
++ return 0;
++
++m2m_init_rollback:
++ v4l2_m2m_release(imr->m2m_dev);
++
++device_register_rollback:
++ v4l2_device_unregister(&imr->v4l2_dev);
++
++ return ret;
++}
++
++static int imr_remove(struct platform_device *pdev)
++{
++ struct imr_device *imr = platform_get_drvdata(pdev);
++
++ //pm_runtime_disable(imr->v4l2_dev.dev);
++ video_unregister_device(&imr->video_dev);
++ v4l2_m2m_release(imr->m2m_dev);
++ v4l2_device_unregister(&imr->v4l2_dev);
++
++ return 0;
++}
++
++/*******************************************************************************
++ * Power management
++ ******************************************************************************/
++
++#ifdef CONFIG_PM_SLEEP
++
++/* ...device suspend hook; clock control only - tbd */
++static int imr_pm_suspend(struct device *dev)
++{
++ struct imr_device *imr = dev_get_drvdata(dev);
++
++ WARN_ON(mutex_is_locked(&imr->mutex));
++
++ if (imr->refcount == 0)
++ return 0;
++
++ clk_disable_unprepare(imr->clock);
++
++ return 0;
++}
++
++/* ...device resume hook; clock control only */
++static int imr_pm_resume(struct device *dev)
++{
++ struct imr_device *imr = dev_get_drvdata(dev);
++
++ WARN_ON(mutex_is_locked(&imr->mutex));
++
++ if (imr->refcount == 0)
++ return 0;
++
++ clk_prepare_enable(imr->clock);
++
++ return 0;
++}
++
++#endif /* CONFIG_PM_SLEEP */
++
++/* ...power management callbacks */
++static const struct dev_pm_ops imr_pm_ops = {
++ SET_SYSTEM_SLEEP_PM_OPS(imr_pm_suspend, imr_pm_resume)
++};
++
++/* ...device table */
++static const struct of_device_id imr_of_match[] = {
++ { .compatible = "renesas,imr-lx4" },
++ { },
++};
++
++/* ...platform driver interface */
++static struct platform_driver imr_platform_driver = {
++ .probe = imr_probe,
++ .remove = imr_remove,
++ .driver = {
++ .owner = THIS_MODULE,
++ .name = "imr",
++ .pm = &imr_pm_ops,
++ .of_match_table = imr_of_match,
++ },
++};
++
++module_platform_driver(imr_platform_driver);
++
++MODULE_ALIAS("imr");
++MODULE_AUTHOR("Cogent Embedded Inc. <sources@cogentembedded.com>");
++MODULE_DESCRIPTION("Renesas IMR-LX4 Driver");
++MODULE_LICENSE("GPL");
+diff --git a/include/uapi/linux/rcar-imr.h b/include/uapi/linux/rcar-imr.h
+new file mode 100644
+index 0000000..d02082f
+--- /dev/null
++++ b/include/uapi/linux/rcar-imr.h
+@@ -0,0 +1,98 @@
++/*
++ * imr.h -- R-Car IMR-LX4 Driver UAPI
++ *
++ * Copyright (C) 2016 Cogent Embedded, Inc. <source@cogentembedded.com>
++ *
++ * This program is free software; you can redistribute it and/or modify
++ * it under the terms of the GNU General Public License as published by
++ * the Free Software Foundation; either version 2 of the License, or
++ * (at your option) any later version.
++ */
++
++#ifndef RCAR_IMR_USER_H
++#define RCAR_IMR_USER_H
++
++#include <linux/videodev2.h>
++
++/*******************************************************************************
++ * Mapping specification descriptor
++ ******************************************************************************/
++
++struct imr_map_desc {
++ /* ...mapping types */
++ u32 type;
++
++ /* ...total size of the mesh structure */
++ u32 size;
++
++ /* ...map-specific user-pointer */
++ void *data;
++
++} __attribute__((packed));
++
++/* ...regular mesh specification */
++#define IMR_MAP_MESH (1 << 0)
++
++/* ...auto-generated source coordinates */
++#define IMR_MAP_AUTODG (1 << 1)
++
++/* ...auto-generated destination coordinates */
++#define IMR_MAP_AUTOSG (1 << 2)
++
++/* ...luminance correction flag */
++#define IMR_MAP_LUCE (1 << 3)
++
++/* ...chromacity correction flag */
++#define IMR_MAP_CLCE (1 << 4)
++
++/* ...vertex clockwise-mode order */
++#define IMR_MAP_TCM (1 << 5)
++
++/* ...source coordinate decimal point position bit index */
++#define __IMR_MAP_UVDPOR_SHIFT 8
++#define __IMR_MAP_UVDPOR(v) (((v) >> __IMR_MAP_UVDPOR_SHIFT) & 0x7)
++#define IMR_MAP_UVDPOR(n) ((n & 0x7) << __IMR_MAP_UVDPOR_SHIFT)
++
++/* ...destination coordinate sub-pixel mode */
++#define IMR_MAP_DDP (1 << 11)
++
++/* ...luminance correction offset decimal point position */
++#define __IMR_MAP_YLDPO_SHIFT 12
++#define __IMR_MAP_YLDPO(v) (((v) >> __IMR_MAP_YLDPO_SHIFT) & 0x7)
++#define IMR_MAP_YLDPO(n) ((n & 0x7) << __IMR_MAP_YLDPO_SHIFT)
++
++/* ...chromacity (U) correction offset decimal point position */
++#define __IMR_MAP_UBDPO_SHIFT 15
++#define __IMR_MAP_UBDPO(v) (((v) >> __IMR_MAP_UBDPO_SHIFT) & 0x7)
++#define IMR_MAP_UBDPO(n) ((n & 0x7) << __IMR_MAP_UBDPO_SHIFT)
++
++/* ...chromacity (V) correction offset decimal point position */
++#define __IMR_MAP_VRDPO_SHIFT 18
++#define __IMR_MAP_VRDPO(v) (((v) >> __IMR_MAP_VRDPO_SHIFT) & 0x7)
++#define IMR_MAP_VRDPO(n) ((n & 0x7) << __IMR_MAP_VRDPO_SHIFT)
++
++/* ...regular mesh specification */
++struct imr_mesh {
++ /* ...rectangular mesh size */
++ u16 rows, columns;
++
++ /* ...mesh parameters */
++ u16 x0, y0, dx, dy;
++
++} __attribute__((packed));
++
++/* ...VBO descriptor */
++struct imr_vbo {
++ /* ...number of triangles */
++ u16 num;
++
++} __attribute__((packed));
++
++
++/*******************************************************************************
++ * Private IOCTL codes
++ ******************************************************************************/
++
++#define VIDIOC_IMR_MESH _IOW('V', BASE_VIDIOC_PRIVATE + 0, struct imr_map_desc)
++
++#endif /* RCAR_IMR_USER_H */
+--
+2.7.4
+
diff --git a/bsp/meta-rcar/meta-rcar-gen3-adas/recipes-kernel/linux/linux-renesas/0014-lib-swiotlb-reduce-verbosity.patch b/bsp/meta-rcar/meta-rcar-gen3-adas/recipes-kernel/linux/linux-renesas/0014-lib-swiotlb-reduce-verbosity.patch
new file mode 100644
index 00000000..6cb5f65c
--- /dev/null
+++ b/bsp/meta-rcar/meta-rcar-gen3-adas/recipes-kernel/linux/linux-renesas/0014-lib-swiotlb-reduce-verbosity.patch
@@ -0,0 +1,40 @@
+From f52105d57c1ec04f8dac9b403232d8b1965a02ca Mon Sep 17 00:00:00 2001
+From: Vladimir Barinov <vladimir.barinov@cogentembedded.com>
+Date: Thu, 26 Jan 2017 16:37:50 +0300
+Subject: [PATCH] lib: swiotlb: reduce verbosity
+
+Signed-off-by: Nikita Yushchenko <nikita.yoush@cogentembedded.com>
+Signed-off-by: Vladimir Barinov <vladimir.barinov@cogentembedded.com>
+---
+ lib/swiotlb.c | 4 ++--
+ 1 file changed, 2 insertions(+), 2 deletions(-)
+
+diff --git a/lib/swiotlb.c b/lib/swiotlb.c
+index 771234d..b395abc 100644
+--- a/lib/swiotlb.c
++++ b/lib/swiotlb.c
+@@ -513,8 +513,10 @@ phys_addr_t swiotlb_tbl_map_single(struct device *hwdev,
+
+ not_found:
+ spin_unlock_irqrestore(&io_tlb_lock, flags);
++#if 0
+ if (printk_ratelimit())
+ dev_warn(hwdev, "swiotlb buffer is full (sz: %zd bytes)\n", size);
++#endif
+ return SWIOTLB_MAP_ERROR;
+ found:
+ spin_unlock_irqrestore(&io_tlb_lock, flags);
+@@ -714,8 +714,10 @@ swiotlb_full(struct device *dev, size_t size, enum dma_data_direction dir,
+ * When the mapping is small enough return a static buffer to limit
+ * the damage, or panic when the transfer is too big.
+ */
++#if 0
+ dev_err_ratelimited(dev, "DMA: Out of SW-IOMMU space for %zu bytes\n",
+ size);
++#endif
+
+ if (size <= io_tlb_overflow || !do_panic)
+ return;
+--
+1.9.1
+
diff --git a/bsp/meta-rcar/meta-rcar-gen3-adas/recipes-kernel/linux/linux-renesas/0015-gpio-max732x-fix-gpio-set.patch b/bsp/meta-rcar/meta-rcar-gen3-adas/recipes-kernel/linux/linux-renesas/0015-gpio-max732x-fix-gpio-set.patch
new file mode 100644
index 00000000..e40c9292
--- /dev/null
+++ b/bsp/meta-rcar/meta-rcar-gen3-adas/recipes-kernel/linux/linux-renesas/0015-gpio-max732x-fix-gpio-set.patch
@@ -0,0 +1,29 @@
+From d3dd821694e6e2a99089bb4916ba4013de54c503 Mon Sep 17 00:00:00 2001
+From: Vladimir Barinov <vladimir.barinov@cogentembedded.com>
+Date: Tue, 11 Apr 2017 20:12:56 +0300
+Subject: [PATCH 011/122] gpio: max732x: fix gpio set
+
+gpio set value/direction must 0 or 1, but
+gpiolib sets it to not binary values
+
+Signed-off-by: Vladimir Barinov <vladimir.barinov@cogentembedded.com>
+---
+ drivers/gpio/gpio-max732x.c | 2 +-
+ 1 file changed, 1 insertion(+), 1 deletion(-)
+
+diff --git a/drivers/gpio/gpio-max732x.c b/drivers/gpio/gpio-max732x.c
+index 7f4d26c..a8ccf56 100644
+--- a/drivers/gpio/gpio-max732x.c
++++ b/drivers/gpio/gpio-max732x.c
+@@ -237,7 +237,7 @@ static void max732x_gpio_set_value(struct gpio_chip *gc, unsigned off, int val)
+ unsigned base = off & ~0x7;
+ uint8_t mask = 1u << (off & 0x7);
+
+- max732x_gpio_set_mask(gc, base, mask, val << (off & 0x7));
++ max732x_gpio_set_mask(gc, base, mask, (!!val) << (off & 0x7));
+ }
+
+ static void max732x_gpio_set_multiple(struct gpio_chip *gc,
+--
+2.7.4
+
diff --git a/bsp/meta-rcar/meta-rcar-gen3-adas/recipes-kernel/linux/linux-renesas/0016-gpio-gpiolib-suppress-gpiod-warning.patch b/bsp/meta-rcar/meta-rcar-gen3-adas/recipes-kernel/linux/linux-renesas/0016-gpio-gpiolib-suppress-gpiod-warning.patch
new file mode 100644
index 00000000..da491501
--- /dev/null
+++ b/bsp/meta-rcar/meta-rcar-gen3-adas/recipes-kernel/linux/linux-renesas/0016-gpio-gpiolib-suppress-gpiod-warning.patch
@@ -0,0 +1,29 @@
+From 365985d00dadb9231ad51d9a518d99e2120dc525 Mon Sep 17 00:00:00 2001
+From: Vladimir Barinov <vladimir.barinov@cogentembedded.com>
+Date: Thu, 13 Apr 2017 12:18:18 +0300
+Subject: [PATCH 012/122] gpio: gpiolib: suppress gpiod warning
+
+Suppress warning about use gpiod instead gpio deprecated callbacks
+
+Signed-off-by: Vladimir Barinov <vladimir.barinov@cogentembedded.com>
+---
+ drivers/gpio/gpiolib.c | 2 ++
+ 1 file changed, 2 insertions(+)
+
+diff --git a/drivers/gpio/gpiolib.c b/drivers/gpio/gpiolib.c
+index d4226e4..7c16e76 100644
+--- a/drivers/gpio/gpiolib.c
++++ b/drivers/gpio/gpiolib.c
+@@ -2670,7 +2670,9 @@ void gpiod_set_raw_value(struct gpio_desc *desc, int value)
+ {
+ VALIDATE_DESC_VOID(desc);
+ /* Should be using gpiod_set_value_cansleep() */
++#if 0
+ WARN_ON(desc->gdev->chip->can_sleep);
++#endif
+ _gpiod_set_raw_value(desc, value);
+ }
+ EXPORT_SYMBOL_GPL(gpiod_set_raw_value);
+--
+2.7.4
+
diff --git a/bsp/meta-rcar/meta-rcar-gen3-adas/recipes-kernel/linux/linux-renesas/0017-media-soc_camera-add-legacy-VIN-CSI2.patch b/bsp/meta-rcar/meta-rcar-gen3-adas/recipes-kernel/linux/linux-renesas/0017-media-soc_camera-add-legacy-VIN-CSI2.patch
new file mode 100644
index 00000000..69ee2ee3
--- /dev/null
+++ b/bsp/meta-rcar/meta-rcar-gen3-adas/recipes-kernel/linux/linux-renesas/0017-media-soc_camera-add-legacy-VIN-CSI2.patch
@@ -0,0 +1,5162 @@
+From 36b7bfbe6c0c45fdbb201f7a79899c7bd934fb17 Mon Sep 17 00:00:00 2001
+From: Vladimir Barinov <vladimir.barinov@cogentembedded.com>
+Date: Sun, 14 May 2017 13:43:24 +0300
+Subject: [PATCH 013/122] media: soc_camera: add legacy VIN/CSI2
+
+Add legacy/old R-CAR VIN/CSI2 drivers
+
+Signed-off-by: Vladimir Barinov <vladimir.barinov@cogentembedded.com>
+---
+ arch/arm64/boot/dts/renesas/r8a7795-es1.dtsi | 133 -
+ arch/arm64/boot/dts/renesas/r8a7795.dtsi | 271 --
+ arch/arm64/boot/dts/renesas/r8a7796.dtsi | 259 --
+ arch/arm64/boot/dts/renesas/r8a77965.dtsi | 258 --
+ arch/arm64/boot/dts/renesas/salvator-common.dtsi | 33 -
+ drivers/media/platform/soc_camera/Kconfig | 28 +
+ drivers/media/platform/soc_camera/Makefile | 2 +
+ drivers/media/platform/soc_camera/rcar_csi2.c | 708 +++++
+ drivers/media/platform/soc_camera/rcar_vin.c | 3071 ++++++++++++++++++++++
+ include/media/rcar_csi2.h | 66 +
+ 10 files changed, 3875 insertions(+), 954 deletions(-)
+ create mode 100644 drivers/media/platform/soc_camera/rcar_csi2.c
+ create mode 100644 drivers/media/platform/soc_camera/rcar_vin.c
+ create mode 100644 include/media/rcar_csi2.h
+
+diff --git a/arch/arm64/boot/dts/renesas/r8a7795-es1.dtsi b/arch/arm64/boot/dts/renesas/r8a7795-es1.dtsi
+index 81e7625..a8c976e 100644
+--- a/arch/arm64/boot/dts/renesas/r8a7795-es1.dtsi
++++ b/arch/arm64/boot/dts/renesas/r8a7795-es1.dtsi
+@@ -201,51 +201,6 @@
+ power-domains = <&sysc R8A7795_PD_ALWAYS_ON>;
+ resets = <&cpg 713>;
+ status = "disabled";
+-
+- ports {
+- #address-cells = <1>;
+- #size-cells = <0>;
+-
+- port@1 {
+- #address-cells = <1>;
+- #size-cells = <0>;
+-
+- reg = <1>;
+-
+- csi21vin0: endpoint@0 {
+- reg = <0>;
+- remote-endpoint = <&vin0csi21>;
+- };
+- csi21vin1: endpoint@1 {
+- reg = <1>;
+- remote-endpoint = <&vin1csi21>;
+- };
+- csi21vin2: endpoint@2 {
+- reg = <2>;
+- remote-endpoint = <&vin2csi21>;
+- };
+- csi21vin3: endpoint@3 {
+- reg = <3>;
+- remote-endpoint = <&vin3csi21>;
+- };
+- csi21vin4: endpoint@4 {
+- reg = <4>;
+- remote-endpoint = <&vin4csi21>;
+- };
+- csi21vin5: endpoint@5 {
+- reg = <5>;
+- remote-endpoint = <&vin5csi21>;
+- };
+- csi21vin6: endpoint@6 {
+- reg = <6>;
+- remote-endpoint = <&vin6csi21>;
+- };
+- csi21vin7: endpoint@7 {
+- reg = <7>;
+- remote-endpoint = <&vin7csi21>;
+- };
+- };
+- };
+ };
+ };
+
+@@ -284,91 +239,3 @@
+ &du {
+ vsps = <&vspd0 &vspd1 &vspd2 &vspd3>;
+ };
+-
+-&vin0 {
+- ports {
+- port@1 {
+- vin0csi21: endpoint@1 {
+- reg = <1>;
+- remote-endpoint = <&csi21vin0>;
+- };
+- };
+- };
+-};
+-
+-&vin1 {
+- ports {
+- port@1 {
+- vin1csi21: endpoint@1 {
+- reg = <1>;
+- remote-endpoint = <&csi21vin1>;
+- };
+- };
+- };
+-};
+-
+-&vin2 {
+- ports {
+- port@1 {
+- vin2csi21: endpoint@1 {
+- reg = <1>;
+- remote-endpoint = <&csi21vin2>;
+- };
+- };
+- };
+-};
+-
+-&vin3 {
+- ports {
+- port@1 {
+- vin3csi21: endpoint@1 {
+- reg = <1>;
+- remote-endpoint = <&csi21vin3>;
+- };
+- };
+- };
+-};
+-
+-&vin4 {
+- ports {
+- port@1 {
+- vin4csi21: endpoint@1 {
+- reg = <1>;
+- remote-endpoint = <&csi21vin4>;
+- };
+- };
+- };
+-};
+-
+-&vin5 {
+- ports {
+- port@1 {
+- vin5csi21: endpoint@1 {
+- reg = <1>;
+- remote-endpoint = <&csi21vin5>;
+- };
+- };
+- };
+-};
+-
+-&vin6 {
+- ports {
+- port@1 {
+- vin6csi21: endpoint@1 {
+- reg = <1>;
+- remote-endpoint = <&csi21vin6>;
+- };
+- };
+- };
+-};
+-
+-&vin7 {
+- ports {
+- port@1 {
+- vin7csi21: endpoint@1 {
+- reg = <1>;
+- remote-endpoint = <&csi21vin7>;
+- };
+- };
+- };
+-};
+diff --git a/arch/arm64/boot/dts/renesas/r8a7795.dtsi b/arch/arm64/boot/dts/renesas/r8a7795.dtsi
+index 8c5b5fe..f15d587 100644
+--- a/arch/arm64/boot/dts/renesas/r8a7795.dtsi
++++ b/arch/arm64/boot/dts/renesas/r8a7795.dtsi
+@@ -1943,27 +1943,6 @@
+ resets = <&cpg 811>;
+ renesas,id = <0>;
+ status = "disabled";
+-
+- ports {
+- #address-cells = <1>;
+- #size-cells = <0>;
+-
+- port@1 {
+- #address-cells = <1>;
+- #size-cells = <0>;
+-
+- reg = <1>;
+-
+- vin0csi20: endpoint@0 {
+- reg = <0>;
+- remote-endpoint = <&csi20vin0>;
+- };
+- vin0csi40: endpoint@2 {
+- reg = <2>;
+- remote-endpoint = <&csi40vin0>;
+- };
+- };
+- };
+ };
+
+ vin1: video@e6ef1000 {
+@@ -1975,27 +1954,6 @@
+ resets = <&cpg 810>;
+ renesas,id = <1>;
+ status = "disabled";
+-
+- ports {
+- #address-cells = <1>;
+- #size-cells = <0>;
+-
+- port@1 {
+- #address-cells = <1>;
+- #size-cells = <0>;
+-
+- reg = <1>;
+-
+- vin1csi20: endpoint@0 {
+- reg = <0>;
+- remote-endpoint = <&csi20vin1>;
+- };
+- vin1csi40: endpoint@2 {
+- reg = <2>;
+- remote-endpoint = <&csi40vin1>;
+- };
+- };
+- };
+ };
+
+ vin2: video@e6ef2000 {
+@@ -2007,27 +1965,6 @@
+ resets = <&cpg 809>;
+ renesas,id = <2>;
+ status = "disabled";
+-
+- ports {
+- #address-cells = <1>;
+- #size-cells = <0>;
+-
+- port@1 {
+- #address-cells = <1>;
+- #size-cells = <0>;
+-
+- reg = <1>;
+-
+- vin2csi20: endpoint@0 {
+- reg = <0>;
+- remote-endpoint = <&csi20vin2>;
+- };
+- vin2csi40: endpoint@2 {
+- reg = <2>;
+- remote-endpoint = <&csi40vin2>;
+- };
+- };
+- };
+ };
+
+ vin3: video@e6ef3000 {
+@@ -2039,27 +1976,6 @@
+ resets = <&cpg 808>;
+ renesas,id = <3>;
+ status = "disabled";
+-
+- ports {
+- #address-cells = <1>;
+- #size-cells = <0>;
+-
+- port@1 {
+- #address-cells = <1>;
+- #size-cells = <0>;
+-
+- reg = <1>;
+-
+- vin3csi20: endpoint@0 {
+- reg = <0>;
+- remote-endpoint = <&csi20vin3>;
+- };
+- vin3csi40: endpoint@2 {
+- reg = <2>;
+- remote-endpoint = <&csi40vin3>;
+- };
+- };
+- };
+ };
+
+ vin4: video@e6ef4000 {
+@@ -2071,27 +1987,6 @@
+ resets = <&cpg 807>;
+ renesas,id = <4>;
+ status = "disabled";
+-
+- ports {
+- #address-cells = <1>;
+- #size-cells = <0>;
+-
+- port@1 {
+- #address-cells = <1>;
+- #size-cells = <0>;
+-
+- reg = <1>;
+-
+- vin4csi20: endpoint@0 {
+- reg = <0>;
+- remote-endpoint = <&csi20vin4>;
+- };
+- vin4csi41: endpoint@3 {
+- reg = <3>;
+- remote-endpoint = <&csi41vin4>;
+- };
+- };
+- };
+ };
+
+ vin5: video@e6ef5000 {
+@@ -2103,27 +1998,6 @@
+ resets = <&cpg 806>;
+ renesas,id = <5>;
+ status = "disabled";
+-
+- ports {
+- #address-cells = <1>;
+- #size-cells = <0>;
+-
+- port@1 {
+- #address-cells = <1>;
+- #size-cells = <0>;
+-
+- reg = <1>;
+-
+- vin5csi20: endpoint@0 {
+- reg = <0>;
+- remote-endpoint = <&csi20vin5>;
+- };
+- vin5csi41: endpoint@3 {
+- reg = <3>;
+- remote-endpoint = <&csi41vin5>;
+- };
+- };
+- };
+ };
+
+ vin6: video@e6ef6000 {
+@@ -2135,27 +2009,6 @@
+ resets = <&cpg 805>;
+ renesas,id = <6>;
+ status = "disabled";
+-
+- ports {
+- #address-cells = <1>;
+- #size-cells = <0>;
+-
+- port@1 {
+- #address-cells = <1>;
+- #size-cells = <0>;
+-
+- reg = <1>;
+-
+- vin6csi20: endpoint@0 {
+- reg = <0>;
+- remote-endpoint = <&csi20vin6>;
+- };
+- vin6csi41: endpoint@3 {
+- reg = <3>;
+- remote-endpoint = <&csi41vin6>;
+- };
+- };
+- };
+ };
+
+ vin7: video@e6ef7000 {
+@@ -2167,27 +2020,6 @@
+ resets = <&cpg 804>;
+ renesas,id = <7>;
+ status = "disabled";
+-
+- ports {
+- #address-cells = <1>;
+- #size-cells = <0>;
+-
+- port@1 {
+- #address-cells = <1>;
+- #size-cells = <0>;
+-
+- reg = <1>;
+-
+- vin7csi20: endpoint@0 {
+- reg = <0>;
+- remote-endpoint = <&csi20vin7>;
+- };
+- vin7csi41: endpoint@3 {
+- reg = <3>;
+- remote-endpoint = <&csi41vin7>;
+- };
+- };
+- };
+ };
+
+ drif00: rif@e6f40000 {
+@@ -3258,51 +3090,6 @@
+ power-domains = <&sysc R8A7795_PD_ALWAYS_ON>;
+ resets = <&cpg 714>;
+ status = "disabled";
+-
+- ports {
+- #address-cells = <1>;
+- #size-cells = <0>;
+-
+- port@1 {
+- #address-cells = <1>;
+- #size-cells = <0>;
+-
+- reg = <1>;
+-
+- csi20vin0: endpoint@0 {
+- reg = <0>;
+- remote-endpoint = <&vin0csi20>;
+- };
+- csi20vin1: endpoint@1 {
+- reg = <1>;
+- remote-endpoint = <&vin1csi20>;
+- };
+- csi20vin2: endpoint@2 {
+- reg = <2>;
+- remote-endpoint = <&vin2csi20>;
+- };
+- csi20vin3: endpoint@3 {
+- reg = <3>;
+- remote-endpoint = <&vin3csi20>;
+- };
+- csi20vin4: endpoint@4 {
+- reg = <4>;
+- remote-endpoint = <&vin4csi20>;
+- };
+- csi20vin5: endpoint@5 {
+- reg = <5>;
+- remote-endpoint = <&vin5csi20>;
+- };
+- csi20vin6: endpoint@6 {
+- reg = <6>;
+- remote-endpoint = <&vin6csi20>;
+- };
+- csi20vin7: endpoint@7 {
+- reg = <7>;
+- remote-endpoint = <&vin7csi20>;
+- };
+- };
+- };
+ };
+
+ csi40: csi2@feaa0000 {
+@@ -3313,35 +3100,6 @@
+ power-domains = <&sysc R8A7795_PD_ALWAYS_ON>;
+ resets = <&cpg 716>;
+ status = "disabled";
+-
+- ports {
+- #address-cells = <1>;
+- #size-cells = <0>;
+-
+- port@1 {
+- #address-cells = <1>;
+- #size-cells = <0>;
+-
+- reg = <1>;
+-
+- csi40vin0: endpoint@0 {
+- reg = <0>;
+- remote-endpoint = <&vin0csi40>;
+- };
+- csi40vin1: endpoint@1 {
+- reg = <1>;
+- remote-endpoint = <&vin1csi40>;
+- };
+- csi40vin2: endpoint@2 {
+- reg = <2>;
+- remote-endpoint = <&vin2csi40>;
+- };
+- csi40vin3: endpoint@3 {
+- reg = <3>;
+- remote-endpoint = <&vin3csi40>;
+- };
+- };
+- };
+ };
+
+ csi41: csi2@feab0000 {
+@@ -3352,35 +3110,6 @@
+ power-domains = <&sysc R8A7795_PD_ALWAYS_ON>;
+ resets = <&cpg 715>;
+ status = "disabled";
+-
+- ports {
+- #address-cells = <1>;
+- #size-cells = <0>;
+-
+- port@1 {
+- #address-cells = <1>;
+- #size-cells = <0>;
+-
+- reg = <1>;
+-
+- csi41vin4: endpoint@0 {
+- reg = <0>;
+- remote-endpoint = <&vin4csi41>;
+- };
+- csi41vin5: endpoint@1 {
+- reg = <1>;
+- remote-endpoint = <&vin5csi41>;
+- };
+- csi41vin6: endpoint@2 {
+- reg = <2>;
+- remote-endpoint = <&vin6csi41>;
+- };
+- csi41vin7: endpoint@3 {
+- reg = <3>;
+- remote-endpoint = <&vin7csi41>;
+- };
+- };
+- };
+ };
+
+ hdmi0: hdmi@fead0000 {
+diff --git a/arch/arm64/boot/dts/renesas/r8a7796.dtsi b/arch/arm64/boot/dts/renesas/r8a7796.dtsi
+index 19f2199..00433dc 100644
+--- a/arch/arm64/boot/dts/renesas/r8a7796.dtsi
++++ b/arch/arm64/boot/dts/renesas/r8a7796.dtsi
+@@ -1849,27 +1849,6 @@
+ resets = <&cpg 811>;
+ renesas,id = <0>;
+ status = "disabled";
+-
+- ports {
+- #address-cells = <1>;
+- #size-cells = <0>;
+-
+- port@1 {
+- #address-cells = <1>;
+- #size-cells = <0>;
+-
+- reg = <1>;
+-
+- vin0csi20: endpoint@0 {
+- reg = <0>;
+- remote-endpoint = <&csi20vin0>;
+- };
+- vin0csi40: endpoint@2 {
+- reg = <2>;
+- remote-endpoint = <&csi40vin0>;
+- };
+- };
+- };
+ };
+
+ vin1: video@e6ef1000 {
+@@ -1881,27 +1860,6 @@
+ resets = <&cpg 810>;
+ renesas,id = <1>;
+ status = "disabled";
+-
+- ports {
+- #address-cells = <1>;
+- #size-cells = <0>;
+-
+- port@1 {
+- #address-cells = <1>;
+- #size-cells = <0>;
+-
+- reg = <1>;
+-
+- vin1csi20: endpoint@0 {
+- reg = <0>;
+- remote-endpoint = <&csi20vin1>;
+- };
+- vin1csi40: endpoint@2 {
+- reg = <2>;
+- remote-endpoint = <&csi40vin1>;
+- };
+- };
+- };
+ };
+
+ vin2: video@e6ef2000 {
+@@ -1913,27 +1871,6 @@
+ resets = <&cpg 809>;
+ renesas,id = <2>;
+ status = "disabled";
+-
+- ports {
+- #address-cells = <1>;
+- #size-cells = <0>;
+-
+- port@1 {
+- #address-cells = <1>;
+- #size-cells = <0>;
+-
+- reg = <1>;
+-
+- vin2csi20: endpoint@0 {
+- reg = <0>;
+- remote-endpoint = <&csi20vin2>;
+- };
+- vin2csi40: endpoint@2 {
+- reg = <2>;
+- remote-endpoint = <&csi40vin2>;
+- };
+- };
+- };
+ };
+
+ vin3: video@e6ef3000 {
+@@ -1945,27 +1882,6 @@
+ resets = <&cpg 808>;
+ renesas,id = <3>;
+ status = "disabled";
+-
+- ports {
+- #address-cells = <1>;
+- #size-cells = <0>;
+-
+- port@1 {
+- #address-cells = <1>;
+- #size-cells = <0>;
+-
+- reg = <1>;
+-
+- vin3csi20: endpoint@0 {
+- reg = <0>;
+- remote-endpoint = <&csi20vin3>;
+- };
+- vin3csi40: endpoint@2 {
+- reg = <2>;
+- remote-endpoint = <&csi40vin3>;
+- };
+- };
+- };
+ };
+
+ vin4: video@e6ef4000 {
+@@ -1977,27 +1893,6 @@
+ resets = <&cpg 807>;
+ renesas,id = <4>;
+ status = "disabled";
+-
+- ports {
+- #address-cells = <1>;
+- #size-cells = <0>;
+-
+- port@1 {
+- #address-cells = <1>;
+- #size-cells = <0>;
+-
+- reg = <1>;
+-
+- vin4csi20: endpoint@0 {
+- reg = <0>;
+- remote-endpoint = <&csi20vin4>;
+- };
+- vin4csi40: endpoint@2 {
+- reg = <2>;
+- remote-endpoint = <&csi40vin4>;
+- };
+- };
+- };
+ };
+
+ vin5: video@e6ef5000 {
+@@ -2009,27 +1904,6 @@
+ resets = <&cpg 806>;
+ renesas,id = <5>;
+ status = "disabled";
+-
+- ports {
+- #address-cells = <1>;
+- #size-cells = <0>;
+-
+- port@1 {
+- #address-cells = <1>;
+- #size-cells = <0>;
+-
+- reg = <1>;
+-
+- vin5csi20: endpoint@0 {
+- reg = <0>;
+- remote-endpoint = <&csi20vin5>;
+- };
+- vin5csi40: endpoint@2 {
+- reg = <2>;
+- remote-endpoint = <&csi40vin5>;
+- };
+- };
+- };
+ };
+
+ vin6: video@e6ef6000 {
+@@ -2041,27 +1915,6 @@
+ resets = <&cpg 805>;
+ renesas,id = <6>;
+ status = "disabled";
+-
+- ports {
+- #address-cells = <1>;
+- #size-cells = <0>;
+-
+- port@1 {
+- #address-cells = <1>;
+- #size-cells = <0>;
+-
+- reg = <1>;
+-
+- vin6csi20: endpoint@0 {
+- reg = <0>;
+- remote-endpoint = <&csi20vin6>;
+- };
+- vin6csi40: endpoint@2 {
+- reg = <2>;
+- remote-endpoint = <&csi40vin6>;
+- };
+- };
+- };
+ };
+
+ vin7: video@e6ef7000 {
+@@ -2073,27 +1926,6 @@
+ resets = <&cpg 804>;
+ renesas,id = <7>;
+ status = "disabled";
+-
+- ports {
+- #address-cells = <1>;
+- #size-cells = <0>;
+-
+- port@1 {
+- #address-cells = <1>;
+- #size-cells = <0>;
+-
+- reg = <1>;
+-
+- vin7csi20: endpoint@0 {
+- reg = <0>;
+- remote-endpoint = <&csi20vin7>;
+- };
+- vin7csi40: endpoint@2 {
+- reg = <2>;
+- remote-endpoint = <&csi40vin7>;
+- };
+- };
+- };
+ };
+
+ drif00: rif@e6f40000 {
+@@ -2989,51 +2821,6 @@
+ power-domains = <&sysc R8A7796_PD_ALWAYS_ON>;
+ resets = <&cpg 714>;
+ status = "disabled";
+-
+- ports {
+- #address-cells = <1>;
+- #size-cells = <0>;
+-
+- port@1 {
+- #address-cells = <1>;
+- #size-cells = <0>;
+-
+- reg = <1>;
+-
+- csi20vin0: endpoint@0 {
+- reg = <0>;
+- remote-endpoint = <&vin0csi20>;
+- };
+- csi20vin1: endpoint@1 {
+- reg = <1>;
+- remote-endpoint = <&vin1csi20>;
+- };
+- csi20vin2: endpoint@2 {
+- reg = <2>;
+- remote-endpoint = <&vin2csi20>;
+- };
+- csi20vin3: endpoint@3 {
+- reg = <3>;
+- remote-endpoint = <&vin3csi20>;
+- };
+- csi20vin4: endpoint@4 {
+- reg = <4>;
+- remote-endpoint = <&vin4csi20>;
+- };
+- csi20vin5: endpoint@5 {
+- reg = <5>;
+- remote-endpoint = <&vin5csi20>;
+- };
+- csi20vin6: endpoint@6 {
+- reg = <6>;
+- remote-endpoint = <&vin6csi20>;
+- };
+- csi20vin7: endpoint@7 {
+- reg = <7>;
+- remote-endpoint = <&vin7csi20>;
+- };
+- };
+- };
+ };
+
+ csi40: csi2@feaa0000 {
+@@ -3044,52 +2831,6 @@
+ power-domains = <&sysc R8A7796_PD_ALWAYS_ON>;
+ resets = <&cpg 716>;
+ status = "disabled";
+-
+- ports {
+- #address-cells = <1>;
+- #size-cells = <0>;
+-
+- port@1 {
+- #address-cells = <1>;
+- #size-cells = <0>;
+-
+- reg = <1>;
+-
+- csi40vin0: endpoint@0 {
+- reg = <0>;
+- remote-endpoint = <&vin0csi40>;
+- };
+- csi40vin1: endpoint@1 {
+- reg = <1>;
+- remote-endpoint = <&vin1csi40>;
+- };
+- csi40vin2: endpoint@2 {
+- reg = <2>;
+- remote-endpoint = <&vin2csi40>;
+- };
+- csi40vin3: endpoint@3 {
+- reg = <3>;
+- remote-endpoint = <&vin3csi40>;
+- };
+- csi40vin4: endpoint@4 {
+- reg = <4>;
+- remote-endpoint = <&vin4csi40>;
+- };
+- csi40vin5: endpoint@5 {
+- reg = <5>;
+- remote-endpoint = <&vin5csi40>;
+- };
+- csi40vin6: endpoint@6 {
+- reg = <6>;
+- remote-endpoint = <&vin6csi40>;
+- };
+- csi40vin7: endpoint@7 {
+- reg = <7>;
+- remote-endpoint = <&vin7csi40>;
+- };
+- };
+-
+- };
+ };
+
+ hdmi0: hdmi@fead0000 {
+diff --git a/arch/arm64/boot/dts/renesas/r8a77965.dtsi b/arch/arm64/boot/dts/renesas/r8a77965.dtsi
+index a58fba8..e682d10 100644
+--- a/arch/arm64/boot/dts/renesas/r8a77965.dtsi
++++ b/arch/arm64/boot/dts/renesas/r8a77965.dtsi
+@@ -1263,27 +1263,6 @@
+ resets = <&cpg 811>;
+ renesas,id = <0>;
+ status = "disabled";
+-
+- ports {
+- #address-cells = <1>;
+- #size-cells = <0>;
+-
+- port@1 {
+- #address-cells = <1>;
+- #size-cells = <0>;
+-
+- reg = <1>;
+-
+- vin0csi20: endpoint@0 {
+- reg = <0>;
+- remote-endpoint = <&csi20vin0>;
+- };
+- vin0csi40: endpoint@2 {
+- reg = <2>;
+- remote-endpoint = <&csi40vin0>;
+- };
+- };
+- };
+ };
+
+ vin1: video@e6ef1000 {
+@@ -1295,27 +1274,6 @@
+ resets = <&cpg 810>;
+ renesas,id = <1>;
+ status = "disabled";
+-
+- ports {
+- #address-cells = <1>;
+- #size-cells = <0>;
+-
+- port@1 {
+- #address-cells = <1>;
+- #size-cells = <0>;
+-
+- reg = <1>;
+-
+- vin1csi20: endpoint@0 {
+- reg = <0>;
+- remote-endpoint = <&csi20vin1>;
+- };
+- vin1csi40: endpoint@2 {
+- reg = <2>;
+- remote-endpoint = <&csi40vin1>;
+- };
+- };
+- };
+ };
+
+ vin2: video@e6ef2000 {
+@@ -1327,27 +1285,6 @@
+ resets = <&cpg 809>;
+ renesas,id = <2>;
+ status = "disabled";
+-
+- ports {
+- #address-cells = <1>;
+- #size-cells = <0>;
+-
+- port@1 {
+- #address-cells = <1>;
+- #size-cells = <0>;
+-
+- reg = <1>;
+-
+- vin2csi20: endpoint@0 {
+- reg = <0>;
+- remote-endpoint = <&csi20vin2>;
+- };
+- vin2csi40: endpoint@2 {
+- reg = <2>;
+- remote-endpoint = <&csi40vin2>;
+- };
+- };
+- };
+ };
+
+ vin3: video@e6ef3000 {
+@@ -1359,27 +1296,6 @@
+ resets = <&cpg 808>;
+ renesas,id = <3>;
+ status = "disabled";
+-
+- ports {
+- #address-cells = <1>;
+- #size-cells = <0>;
+-
+- port@1 {
+- #address-cells = <1>;
+- #size-cells = <0>;
+-
+- reg = <1>;
+-
+- vin3csi20: endpoint@0 {
+- reg = <0>;
+- remote-endpoint = <&csi20vin3>;
+- };
+- vin3csi40: endpoint@2 {
+- reg = <2>;
+- remote-endpoint = <&csi40vin3>;
+- };
+- };
+- };
+ };
+
+ vin4: video@e6ef4000 {
+@@ -1391,27 +1307,6 @@
+ resets = <&cpg 807>;
+ renesas,id = <4>;
+ status = "disabled";
+-
+- ports {
+- #address-cells = <1>;
+- #size-cells = <0>;
+-
+- port@1 {
+- #address-cells = <1>;
+- #size-cells = <0>;
+-
+- reg = <1>;
+-
+- vin4csi20: endpoint@0 {
+- reg = <0>;
+- remote-endpoint = <&csi20vin4>;
+- };
+- vin4csi40: endpoint@2 {
+- reg = <2>;
+- remote-endpoint = <&csi40vin4>;
+- };
+- };
+- };
+ };
+
+ vin5: video@e6ef5000 {
+@@ -1423,27 +1318,6 @@
+ resets = <&cpg 806>;
+ renesas,id = <5>;
+ status = "disabled";
+-
+- ports {
+- #address-cells = <1>;
+- #size-cells = <0>;
+-
+- port@1 {
+- #address-cells = <1>;
+- #size-cells = <0>;
+-
+- reg = <1>;
+-
+- vin5csi20: endpoint@0 {
+- reg = <0>;
+- remote-endpoint = <&csi20vin5>;
+- };
+- vin5csi40: endpoint@2 {
+- reg = <2>;
+- remote-endpoint = <&csi40vin5>;
+- };
+- };
+- };
+ };
+
+ vin6: video@e6ef6000 {
+@@ -1455,27 +1329,6 @@
+ resets = <&cpg 805>;
+ renesas,id = <6>;
+ status = "disabled";
+-
+- ports {
+- #address-cells = <1>;
+- #size-cells = <0>;
+-
+- port@1 {
+- #address-cells = <1>;
+- #size-cells = <0>;
+-
+- reg = <1>;
+-
+- vin6csi20: endpoint@0 {
+- reg = <0>;
+- remote-endpoint = <&csi20vin6>;
+- };
+- vin6csi40: endpoint@2 {
+- reg = <2>;
+- remote-endpoint = <&csi40vin6>;
+- };
+- };
+- };
+ };
+
+ vin7: video@e6ef7000 {
+@@ -1487,27 +1340,6 @@
+ resets = <&cpg 804>;
+ renesas,id = <7>;
+ status = "disabled";
+-
+- ports {
+- #address-cells = <1>;
+- #size-cells = <0>;
+-
+- port@1 {
+- #address-cells = <1>;
+- #size-cells = <0>;
+-
+- reg = <1>;
+-
+- vin7csi20: endpoint@0 {
+- reg = <0>;
+- remote-endpoint = <&csi20vin7>;
+- };
+- vin7csi40: endpoint@2 {
+- reg = <2>;
+- remote-endpoint = <&csi40vin7>;
+- };
+- };
+- };
+ };
+
+ rcar_sound: sound@ec500000 {
+@@ -2230,51 +2062,6 @@
+ power-domains = <&sysc R8A77965_PD_ALWAYS_ON>;
+ resets = <&cpg 714>;
+ status = "disabled";
+-
+- ports {
+- #address-cells = <1>;
+- #size-cells = <0>;
+-
+- port@1 {
+- #address-cells = <1>;
+- #size-cells = <0>;
+-
+- reg = <1>;
+-
+- csi20vin0: endpoint@0 {
+- reg = <0>;
+- remote-endpoint = <&vin0csi20>;
+- };
+- csi20vin1: endpoint@1 {
+- reg = <1>;
+- remote-endpoint = <&vin1csi20>;
+- };
+- csi20vin2: endpoint@2 {
+- reg = <2>;
+- remote-endpoint = <&vin2csi20>;
+- };
+- csi20vin3: endpoint@3 {
+- reg = <3>;
+- remote-endpoint = <&vin3csi20>;
+- };
+- csi20vin4: endpoint@4 {
+- reg = <4>;
+- remote-endpoint = <&vin4csi20>;
+- };
+- csi20vin5: endpoint@5 {
+- reg = <5>;
+- remote-endpoint = <&vin5csi20>;
+- };
+- csi20vin6: endpoint@6 {
+- reg = <6>;
+- remote-endpoint = <&vin6csi20>;
+- };
+- csi20vin7: endpoint@7 {
+- reg = <7>;
+- remote-endpoint = <&vin7csi20>;
+- };
+- };
+- };
+ };
+
+ csi40: csi2@feaa0000 {
+@@ -2285,51 +2072,6 @@
+ power-domains = <&sysc R8A77965_PD_ALWAYS_ON>;
+ resets = <&cpg 716>;
+ status = "disabled";
+-
+- ports {
+- #address-cells = <1>;
+- #size-cells = <0>;
+-
+- port@1 {
+- #address-cells = <1>;
+- #size-cells = <0>;
+-
+- reg = <1>;
+-
+- csi40vin0: endpoint@0 {
+- reg = <0>;
+- remote-endpoint = <&vin0csi40>;
+- };
+- csi40vin1: endpoint@1 {
+- reg = <1>;
+- remote-endpoint = <&vin1csi40>;
+- };
+- csi40vin2: endpoint@2 {
+- reg = <2>;
+- remote-endpoint = <&vin2csi40>;
+- };
+- csi40vin3: endpoint@3 {
+- reg = <3>;
+- remote-endpoint = <&vin3csi40>;
+- };
+- csi40vin4: endpoint@4 {
+- reg = <4>;
+- remote-endpoint = <&vin4csi40>;
+- };
+- csi40vin5: endpoint@5 {
+- reg = <5>;
+- remote-endpoint = <&vin5csi40>;
+- };
+- csi40vin6: endpoint@6 {
+- reg = <6>;
+- remote-endpoint = <&vin6csi40>;
+- };
+- csi40vin7: endpoint@7 {
+- reg = <7>;
+- remote-endpoint = <&vin7csi40>;
+- };
+- };
+- };
+ };
+
+ hdmi0: hdmi@fead0000 {
+diff --git a/arch/arm64/boot/dts/renesas/salvator-common.dtsi b/arch/arm64/boot/dts/renesas/salvator-common.dtsi
+index 1b191af..788d38f 100644
+--- a/arch/arm64/boot/dts/renesas/salvator-common.dtsi
++++ b/arch/arm64/boot/dts/renesas/salvator-common.dtsi
+@@ -341,37 +341,6 @@
+ };
+ };
+
+-&csi20 {
+- status = "okay";
+-
+- ports {
+- port@0 {
+- reg = <0>;
+- csi20_in: endpoint {
+- clock-lanes = <0>;
+- data-lanes = <1>;
+- remote-endpoint = <&adv7482_txb>;
+- };
+- };
+- };
+-};
+-
+-&csi40 {
+- status = "okay";
+-
+- ports {
+- port@0 {
+- reg = <0>;
+-
+- csi40_in: endpoint {
+- clock-lanes = <0>;
+- data-lanes = <1 2 3 4>;
+- remote-endpoint = <&adv7482_txa>;
+- };
+- };
+- };
+-};
+-
+ &du {
+ pinctrl-0 = <&du_pins>;
+ pinctrl-names = "default";
+@@ -531,7 +500,6 @@
+ adv7482_txa: endpoint {
+ clock-lanes = <0>;
+ data-lanes = <1 2 3 4>;
+- remote-endpoint = <&csi40_in>;
+ };
+ };
+
+@@ -541,7 +509,6 @@
+ adv7482_txb: endpoint {
+ clock-lanes = <0>;
+ data-lanes = <1>;
+- remote-endpoint = <&csi20_in>;
+ };
+ };
+ };
+diff --git a/drivers/media/platform/soc_camera/Kconfig b/drivers/media/platform/soc_camera/Kconfig
+index f5979c1..a3bf60d 100644
+--- a/drivers/media/platform/soc_camera/Kconfig
++++ b/drivers/media/platform/soc_camera/Kconfig
+@@ -16,6 +16,34 @@ config SOC_CAMERA_PLATFORM
+ help
+ This is a generic SoC camera platform driver, useful for testing
+
++config VIDEO_RCAR_VIN_LEGACY
++ tristate "R-Car Video Input (VIN) support"
++ depends on VIDEO_DEV && SOC_CAMERA
++ depends on ARCH_RENESAS || COMPILE_TEST
++ depends on HAS_DMA
++ select VIDEOBUF2_DMA_CONTIG
++ select SOC_CAMERA_SCALE_CROP
++ select V4L2_FWNODE
++ ---help---
++ This is a v4l2 driver for the R-Car VIN Interface
++
++config VIDEO_RCAR_VIN_LEGACY_DEBUG
++ bool "Renesas VIN overflow debug messages"
++ depends on VIDEO_RCAR_VIN_LEGACY
++ ---help---
++ Enable debug overflow messages on R-Car Video
++ Input driver.
++ If you set to enable, When an overflow occurred,
++ a debug overflow message is output.
++
++config VIDEO_RCAR_CSI2_LEGACY
++ tristate "R-Car MIPI CSI-2 Interface driver"
++ depends on VIDEO_DEV && SOC_CAMERA && HAVE_CLK
++ depends on ARCH_R8A7795 || ARCH_R8A7796 || COMPILE_TEST
++ select V4L2_FWNODE
++ ---help---
++ This is a v4l2 driver for the R-Car CSI-2 Interface
++
+ config VIDEO_SH_MOBILE_CEU
+ tristate "SuperH Mobile CEU Interface driver"
+ depends on VIDEO_DEV && SOC_CAMERA && HAS_DMA && HAVE_CLK
+diff --git a/drivers/media/platform/soc_camera/Makefile b/drivers/media/platform/soc_camera/Makefile
+index 07a451e..1a70361 100644
+--- a/drivers/media/platform/soc_camera/Makefile
++++ b/drivers/media/platform/soc_camera/Makefile
+@@ -7,3 +7,5 @@ obj-$(CONFIG_SOC_CAMERA_PLATFORM) += soc_camera_platform.o
+
+ # soc-camera host drivers have to be linked after camera drivers
+ obj-$(CONFIG_VIDEO_SH_MOBILE_CEU) += sh_mobile_ceu_camera.o
++obj-$(CONFIG_VIDEO_RCAR_CSI2_LEGACY) += rcar_csi2.o
++obj-$(CONFIG_VIDEO_RCAR_VIN_LEGACY) += rcar_vin.o
+diff --git a/drivers/media/platform/soc_camera/rcar_csi2.c b/drivers/media/platform/soc_camera/rcar_csi2.c
+new file mode 100644
+index 0000000..05f623468
+--- /dev/null
++++ b/drivers/media/platform/soc_camera/rcar_csi2.c
+@@ -0,0 +1,708 @@
++/*
++ * drivers/media/platform/soc_camera/rcar_csi2.c
++ * This file is the driver for the R-Car MIPI CSI-2 unit.
++ *
++ * Copyright (C) 2015-2016 Renesas Electronics Corporation
++ *
++ * This file is based on the drivers/media/platform/soc_camera/sh_mobile_csi2.c
++ *
++ * Driver for the SH-Mobile MIPI CSI-2 unit
++ *
++ * Copyright (C) 2010, Guennadi Liakhovetski <g.liakhovetski@gmx.de>
++ *
++ * This program is free software; you can redistribute it and/or modify
++ * it under the terms of the GNU General Public License version 2 as
++ * published by the Free Software Foundation.
++ */
++
++#include <linux/delay.h>
++#include <linux/interrupt.h>
++#include <linux/err.h>
++#include <linux/i2c.h>
++#include <linux/io.h>
++#include <linux/platform_device.h>
++#include <linux/pm_runtime.h>
++#include <linux/slab.h>
++#include <linux/videodev2.h>
++#include <linux/module.h>
++
++#include <media/rcar_csi2.h>
++#include <media/soc_camera.h>
++#include <media/v4l2-common.h>
++#include <media/v4l2-dev.h>
++#include <media/v4l2-device.h>
++#include <media/v4l2-mediabus.h>
++#include <media/v4l2-subdev.h>
++
++#include <media/v4l2-of.h>
++
++#define DRV_NAME "rcar_csi2"
++#define CONNECT_SLAVE_NAME "adv7482"
++#define VC_MAX_CHANNEL 4
++
++#define RCAR_CSI2_TREF 0x00
++#define RCAR_CSI2_SRST 0x04
++#define RCAR_CSI2_PHYCNT 0x08
++#define RCAR_CSI2_CHKSUM 0x0C
++#define RCAR_CSI2_VCDT 0x10
++
++#define RCAR_CSI2_VCDT2 0x14 /* Channel Data Type Select */
++#define RCAR_CSI2_FRDT 0x18 /* Frame Data Type Select */
++#define RCAR_CSI2_FLD 0x1C /* Field Detection Control */
++#define RCAR_CSI2_ASTBY 0x20 /* Automatic standby control */
++#define RCAR_CSI2_LNGDT0 0x28
++#define RCAR_CSI2_LNGDT1 0x2C
++#define RCAR_CSI2_INTEN 0x30
++#define RCAR_CSI2_INTCLOSE 0x34
++#define RCAR_CSI2_INTSTATE 0x38
++#define RCAR_CSI2_INTERRSTATE 0x3C
++
++#define RCAR_CSI2_SHPDAT 0x40
++#define RCAR_CSI2_SHPCNT 0x44
++
++#define RCAR_CSI2_LINKCNT 0x48
++#define RCAR_CSI2_LSWAP 0x4C
++#define RCAR_CSI2_PHTC 0x58
++#define RCAR_CSI2_PHYPLL 0x68
++
++#define RCAR_CSI2_PHEERM 0x74
++#define RCAR_CSI2_PHCLM 0x78
++#define RCAR_CSI2_PHDLM 0x7C
++
++#define RCAR_CSI2_PHYCNT_SHUTDOWNZ (1 << 17)
++#define RCAR_CSI2_PHYCNT_RSTZ (1 << 16)
++#define RCAR_CSI2_PHYCNT_ENABLECLK (1 << 4)
++#define RCAR_CSI2_PHYCNT_ENABLE_3 (1 << 3)
++#define RCAR_CSI2_PHYCNT_ENABLE_2 (1 << 2)
++#define RCAR_CSI2_PHYCNT_ENABLE_1 (1 << 1)
++#define RCAR_CSI2_PHYCNT_ENABLE_0 (1 << 0)
++
++#define RCAR_CSI2_VCDT_VCDTN_EN (1 << 15)
++#define RCAR_CSI2_VCDT_SEL_VCN (1 << 8)
++#define RCAR_CSI2_VCDT_SEL_DTN_ON (1 << 6)
++#define RCAR_CSI2_VCDT_SEL_DTN (1 << 0)
++
++#define RCAR_CSI2_LINKCNT_MONITOR_EN (1 << 31)
++#define RCAR_CSI2_LINKCNT_REG_MONI_PACT_EN (1 << 25)
++
++#define RCAR_CSI2_LSWAP_L3SEL_PLANE0 (0 << 6)
++#define RCAR_CSI2_LSWAP_L3SEL_PLANE1 (1 << 6)
++#define RCAR_CSI2_LSWAP_L3SEL_PLANE2 (2 << 6)
++#define RCAR_CSI2_LSWAP_L3SEL_PLANE3 (3 << 6)
++
++#define RCAR_CSI2_LSWAP_L2SEL_PLANE0 (0 << 4)
++#define RCAR_CSI2_LSWAP_L2SEL_PLANE1 (1 << 4)
++#define RCAR_CSI2_LSWAP_L2SEL_PLANE2 (2 << 4)
++#define RCAR_CSI2_LSWAP_L2SEL_PLANE3 (3 << 4)
++
++#define RCAR_CSI2_LSWAP_L1SEL_PLANE0 (0 << 2)
++#define RCAR_CSI2_LSWAP_L1SEL_PLANE1 (1 << 2)
++#define RCAR_CSI2_LSWAP_L1SEL_PLANE2 (2 << 2)
++#define RCAR_CSI2_LSWAP_L1SEL_PLANE3 (3 << 2)
++
++#define RCAR_CSI2_LSWAP_L0SEL_PLANE0 (0 << 0)
++#define RCAR_CSI2_LSWAP_L0SEL_PLANE1 (1 << 0)
++#define RCAR_CSI2_LSWAP_L0SEL_PLANE2 (2 << 0)
++#define RCAR_CSI2_LSWAP_L0SEL_PLANE3 (3 << 0)
++
++#define RCAR_CSI2_PHTC_TESTCLR (1 << 0)
++
++/* interrupt status registers */
++#define RCAR_CSI2_INTSTATE_EBD_CH1 (1 << 29)
++#define RCAR_CSI2_INTSTATE_LESS_THAN_WC (1 << 28)
++#define RCAR_CSI2_INTSTATE_AFIFO_OF (1 << 27)
++#define RCAR_CSI2_INTSTATE_VD4_START (1 << 26)
++#define RCAR_CSI2_INTSTATE_VD4_END (1 << 25)
++#define RCAR_CSI2_INTSTATE_VD3_START (1 << 24)
++#define RCAR_CSI2_INTSTATE_VD3_END (1 << 23)
++#define RCAR_CSI2_INTSTATE_VD2_START (1 << 22)
++#define RCAR_CSI2_INTSTATE_VD2_END (1 << 21)
++#define RCAR_CSI2_INTSTATE_VD1_START (1 << 20)
++#define RCAR_CSI2_INTSTATE_VD1_END (1 << 19)
++#define RCAR_CSI2_INTSTATE_SHP (1 << 18)
++#define RCAR_CSI2_INTSTATE_FSFE (1 << 17)
++#define RCAR_CSI2_INTSTATE_LNP (1 << 16)
++#define RCAR_CSI2_INTSTATE_CRC_ERR (1 << 15)
++#define RCAR_CSI2_INTSTATE_HD_WC_ZERO (1 << 14)
++#define RCAR_CSI2_INTSTATE_FRM_SEQ_ERR1 (1 << 13)
++#define RCAR_CSI2_INTSTATE_FRM_SEQ_ERR2 (1 << 12)
++#define RCAR_CSI2_INTSTATE_ECC_ERR (1 << 11)
++#define RCAR_CSI2_INTSTATE_ECC_CRCT_ERR (1 << 10)
++#define RCAR_CSI2_INTSTATE_LPDT_START (1 << 9)
++#define RCAR_CSI2_INTSTATE_LPDT_END (1 << 8)
++#define RCAR_CSI2_INTSTATE_ULPS_START (1 << 7)
++#define RCAR_CSI2_INTSTATE_ULPS_END (1 << 6)
++#define RCAR_CSI2_INTSTATE_RESERVED (1 << 5)
++#define RCAR_CSI2_INTSTATE_ERRSOTHS (1 << 4)
++#define RCAR_CSI2_INTSTATE_ERRSOTSYNCCHS (1 << 3)
++#define RCAR_CSI2_INTSTATE_ERRESC (1 << 2)
++#define RCAR_CSI2_INTSTATE_ERRSYNCESC (1 << 1)
++#define RCAR_CSI2_INTSTATE_ERRCONTROL (1 << 0)
++
++/* monitoring registers of interrupt error status */
++#define RCAR_CSI2_INTSTATE_ECC_ERR (1 << 11)
++#define RCAR_CSI2_INTSTATE_ECC_CRCT_ERR (1 << 10)
++#define RCAR_CSI2_INTSTATE_LPDT_START (1 << 9)
++#define RCAR_CSI2_INTSTATE_LPDT_END (1 << 8)
++#define RCAR_CSI2_INTSTATE_ULPS_START (1 << 7)
++#define RCAR_CSI2_INTSTATE_ULPS_END (1 << 6)
++#define RCAR_CSI2_INTSTATE_RESERVED (1 << 5)
++#define RCAR_CSI2_INTSTATE_ERRSOTHS (1 << 4)
++#define RCAR_CSI2_INTSTATE_ERRSOTSYNCCHS (1 << 3)
++#define RCAR_CSI2_INTSTATE_ERRESC (1 << 2)
++#define RCAR_CSI2_INTSTATE_ERRSYNCESC (1 << 1)
++#define RCAR_CSI2_INTSTATE_ERRCONTROL (1 << 0)
++
++enum chip_id {
++ RCAR_GEN3,
++ RCAR_GEN2,
++};
++
++enum decoder_input_interface {
++ DECODER_INPUT_INTERFACE_RGB888,
++ DECODER_INPUT_INTERFACE_YCBCR422,
++ DECODER_INPUT_INTERFACE_NONE,
++};
++
++/**
++ * struct rcar_csi2_link_config - Describes rcar_csi2 hardware configuration
++ * @input_colorspace: The input colorspace (RGB, YUV444, YUV422)
++ */
++struct rcar_csi2_link_config {
++ enum decoder_input_interface input_interface;
++ unsigned char lanes;
++ unsigned long vcdt;
++ unsigned long vcdt2;
++};
++
++#define INIT_RCAR_CSI2_LINK_CONFIG(m) \
++{ \
++ m.input_interface = DECODER_INPUT_INTERFACE_NONE; \
++ m.lanes = 0; \
++}
++
++struct rcar_csi_irq_counter_log {
++ unsigned long crc_err;
++};
++
++struct rcar_csi2 {
++ struct v4l2_subdev subdev;
++ struct v4l2_mbus_framefmt *mf;
++ unsigned int irq;
++ unsigned long mipi_flags;
++ void __iomem *base;
++ struct platform_device *pdev;
++ struct rcar_csi2_client_config *client;
++ unsigned long vcdt;
++ unsigned long vcdt2;
++
++ unsigned int field;
++ unsigned int code;
++ unsigned int lanes;
++ spinlock_t lock;
++};
++
++#define RCAR_CSI_80MBPS 0
++#define RCAR_CSI_90MBPS 1
++#define RCAR_CSI_100MBPS 2
++#define RCAR_CSI_110MBPS 3
++#define RCAR_CSI_120MBPS 4
++#define RCAR_CSI_130MBPS 5
++#define RCAR_CSI_140MBPS 6
++#define RCAR_CSI_150MBPS 7
++#define RCAR_CSI_160MBPS 8
++#define RCAR_CSI_170MBPS 9
++#define RCAR_CSI_180MBPS 10
++#define RCAR_CSI_190MBPS 11
++#define RCAR_CSI_205MBPS 12
++#define RCAR_CSI_220MBPS 13
++#define RCAR_CSI_235MBPS 14
++#define RCAR_CSI_250MBPS 15
++#define RCAR_CSI_275MBPS 16
++#define RCAR_CSI_300MBPS 17
++#define RCAR_CSI_325MBPS 18
++#define RCAR_CSI_350MBPS 19
++#define RCAR_CSI_400MBPS 20
++#define RCAR_CSI_450MBPS 21
++#define RCAR_CSI_500MBPS 22
++#define RCAR_CSI_550MBPS 23
++#define RCAR_CSI_600MBPS 24
++#define RCAR_CSI_650MBPS 25
++#define RCAR_CSI_700MBPS 26
++#define RCAR_CSI_750MBPS 27
++#define RCAR_CSI_800MBPS 28
++#define RCAR_CSI_850MBPS 29
++#define RCAR_CSI_900MBPS 30
++#define RCAR_CSI_950MBPS 31
++#define RCAR_CSI_1000MBPS 32
++#define RCAR_CSI_1050MBPS 33
++#define RCAR_CSI_1100MBPS 34
++#define RCAR_CSI_1150MBPS 35
++#define RCAR_CSI_1200MBPS 36
++#define RCAR_CSI_1250MBPS 37
++#define RCAR_CSI_1300MBPS 38
++#define RCAR_CSI_1350MBPS 39
++#define RCAR_CSI_1400MBPS 40
++#define RCAR_CSI_1450MBPS 41
++#define RCAR_CSI_1500MBPS 42
++
++static int rcar_csi2_set_phy_freq(struct rcar_csi2 *priv)
++{
++ const uint32_t const hs_freq_range[43] = {
++ 0x00, 0x10, 0x20, 0x30, 0x01, /* 0-4 */
++ 0x11, 0x21, 0x31, 0x02, 0x12, /* 5-9 */
++ 0x22, 0x32, 0x03, 0x13, 0x23, /* 10-14 */
++ 0x33, 0x04, 0x14, 0x05, 0x15, /* 15-19 */
++ 0x25, 0x06, 0x16, 0x07, 0x17, /* 20-24 */
++ 0x08, 0x18, 0x09, 0x19, 0x29, /* 25-29 */
++ 0x39, 0x0A, 0x1A, 0x2A, 0x3A, /* 30-34 */
++ 0x0B, 0x1B, 0x2B, 0x3B, 0x0C, /* 35-39 */
++ 0x1C, 0x2C, 0x3C /* 40-42 */
++ };
++ uint32_t bps_per_lane = RCAR_CSI_190MBPS;
++
++ dev_dbg(&priv->pdev->dev, "Input size (%dx%d%c)\n",
++ priv->mf->width, priv->mf->height,
++ (priv->mf->field == V4L2_FIELD_NONE) ? 'p' : 'i');
++
++ switch (priv->lanes) {
++ case 1:
++ bps_per_lane = RCAR_CSI_400MBPS;
++ break;
++ case 4:
++ if (priv->mf->field == V4L2_FIELD_NONE) {
++ if ((priv->mf->width == 1920) &&
++ (priv->mf->height == 1080))
++ bps_per_lane = RCAR_CSI_900MBPS;
++ else if ((priv->mf->width == 1280) &&
++ (priv->mf->height == 720))
++ bps_per_lane = RCAR_CSI_450MBPS;
++ else if ((priv->mf->width == 720) &&
++ (priv->mf->height == 480))
++ bps_per_lane = RCAR_CSI_190MBPS;
++ else if ((priv->mf->width == 720) &&
++ (priv->mf->height == 576))
++ bps_per_lane = RCAR_CSI_190MBPS;
++ else if ((priv->mf->width == 640) &&
++ (priv->mf->height == 480))
++ bps_per_lane = RCAR_CSI_100MBPS;
++ else
++ goto error;
++ } else {
++ if ((priv->mf->width == 1920) &&
++ (priv->mf->height == 1080))
++ bps_per_lane = RCAR_CSI_450MBPS;
++ else
++ goto error;
++ }
++ break;
++ default:
++ dev_err(&priv->pdev->dev, "ERROR: lanes is invalid (%d)\n",
++ priv->lanes);
++ return -EINVAL;
++ }
++
++ dev_dbg(&priv->pdev->dev, "bps_per_lane (%d)\n", bps_per_lane);
++
++ iowrite32((hs_freq_range[bps_per_lane] << 16),
++ priv->base + RCAR_CSI2_PHYPLL);
++ return 0;
++
++error:
++ dev_err(&priv->pdev->dev, "Not support resolution (%dx%d%c)\n",
++ priv->mf->width, priv->mf->height,
++ (priv->mf->field == V4L2_FIELD_NONE) ? 'p' : 'i');
++ return -EINVAL;
++}
++
++static irqreturn_t rcar_csi2_irq(int irq, void *data)
++{
++ struct rcar_csi2 *priv = data;
++ u32 int_status;
++ unsigned int handled = 0;
++
++ spin_lock(&priv->lock);
++
++ int_status = ioread32(priv->base + RCAR_CSI2_INTSTATE);
++ if (!int_status)
++ goto done;
++
++ /* ack interrupts */
++ iowrite32(int_status, priv->base + RCAR_CSI2_INTSTATE);
++ handled = 1;
++
++done:
++ spin_unlock(&priv->lock);
++
++ return IRQ_RETVAL(handled);
++
++}
++
++static void rcar_csi2_hwdeinit(struct rcar_csi2 *priv)
++{
++ iowrite32(0, priv->base + RCAR_CSI2_PHYCNT);
++
++ /* reset CSI2 hardware */
++ iowrite32(0x00000001, priv->base + RCAR_CSI2_SRST);
++ udelay(5);
++ iowrite32(0x00000000, priv->base + RCAR_CSI2_SRST);
++}
++
++static int rcar_csi2_hwinit(struct rcar_csi2 *priv)
++{
++ int ret;
++ __u32 tmp = 0x10; /* Enable MIPI CSI clock lane */
++
++ /* Reflect registers immediately */
++ iowrite32(0x00000001, priv->base + RCAR_CSI2_TREF);
++ /* reset CSI2 hardware */
++ iowrite32(0x00000001, priv->base + RCAR_CSI2_SRST);
++ udelay(5);
++ iowrite32(0x00000000, priv->base + RCAR_CSI2_SRST);
++
++ iowrite32(0x00000000, priv->base + RCAR_CSI2_PHTC);
++
++ /* setting HS reception frequency */
++ {
++ switch (priv->lanes) {
++ case 1:
++ /* First field number setting */
++ iowrite32(0x0001000f, priv->base + RCAR_CSI2_FLD);
++ tmp |= 0x1;
++ break;
++ case 4:
++ /* First field number setting */
++ iowrite32(0x0002000f, priv->base + RCAR_CSI2_FLD);
++ tmp |= 0xF;
++ break;
++ default:
++ dev_err(&priv->pdev->dev,
++ "ERROR: lanes is invalid (%d)\n",
++ priv->lanes);
++ return -EINVAL;
++ }
++
++ /* set PHY frequency */
++ ret = rcar_csi2_set_phy_freq(priv);
++ if (ret < 0)
++ return ret;
++
++ /* Enable lanes */
++ iowrite32(tmp, priv->base + RCAR_CSI2_PHYCNT);
++
++ iowrite32(tmp | RCAR_CSI2_PHYCNT_SHUTDOWNZ,
++ priv->base + RCAR_CSI2_PHYCNT);
++ iowrite32(tmp | (RCAR_CSI2_PHYCNT_SHUTDOWNZ |
++ RCAR_CSI2_PHYCNT_RSTZ),
++ priv->base + RCAR_CSI2_PHYCNT);
++ }
++
++ iowrite32(0x00000003, priv->base + RCAR_CSI2_CHKSUM);
++ iowrite32(priv->vcdt, priv->base + RCAR_CSI2_VCDT);
++ iowrite32(priv->vcdt2, priv->base + RCAR_CSI2_VCDT2);
++ iowrite32(0x00010000, priv->base + RCAR_CSI2_FRDT);
++ udelay(10);
++ iowrite32(0x83000000, priv->base + RCAR_CSI2_LINKCNT);
++ iowrite32(0x000000e4, priv->base + RCAR_CSI2_LSWAP);
++
++ dev_dbg(&priv->pdev->dev, "CSI2 VCDT: 0x%x\n",
++ ioread32(priv->base + RCAR_CSI2_VCDT));
++ dev_dbg(&priv->pdev->dev, "CSI2 VCDT2: 0x%x\n",
++ ioread32(priv->base + RCAR_CSI2_VCDT2));
++
++ /* wait until video decoder power off */
++ msleep(10);
++ {
++ int timeout = 100;
++
++ /* Read the PHY clock lane monitor register (PHCLM). */
++ while (!(ioread32(priv->base + RCAR_CSI2_PHCLM) & 0x01)
++ && timeout) {
++ timeout--;
++ }
++ if (timeout == 0)
++ dev_err(&priv->pdev->dev,
++ "Timeout of reading the PHY clock lane\n");
++ else
++ dev_dbg(&priv->pdev->dev,
++ "Detected the PHY clock lane\n");
++
++ timeout = 100;
++
++ /* Read the PHY data lane monitor register (PHDLM). */
++ while (!(ioread32(priv->base + RCAR_CSI2_PHDLM) & 0x01)
++ && timeout) {
++ timeout--;
++ }
++ if (timeout == 0)
++ dev_err(&priv->pdev->dev,
++ "Timeout of reading the PHY data lane\n");
++ else
++ dev_dbg(&priv->pdev->dev,
++ "Detected the PHY data lane\n");
++ }
++
++ return 0;
++}
++
++static int rcar_csi2_s_power(struct v4l2_subdev *sd, int on)
++{
++ struct rcar_csi2 *priv = container_of(sd, struct rcar_csi2, subdev);
++ struct v4l2_subdev *tmp_sd;
++ struct v4l2_subdev_format fmt = {
++ .which = V4L2_SUBDEV_FORMAT_ACTIVE,
++ };
++ struct v4l2_mbus_framefmt *mf = &fmt.format;
++ int ret = 0;
++
++ if (on) {
++ v4l2_device_for_each_subdev(tmp_sd, sd->v4l2_dev) {
++ if (strncmp(tmp_sd->name, CONNECT_SLAVE_NAME,
++ sizeof(CONNECT_SLAVE_NAME) - 1) == 0) {
++ v4l2_subdev_call(tmp_sd, pad, get_fmt,
++ NULL, &fmt);
++ if (ret < 0)
++ return ret;
++ }
++ }
++ priv->mf = mf;
++ pm_runtime_get_sync(&priv->pdev->dev);
++ ret = rcar_csi2_hwinit(priv);
++ if (ret < 0)
++ return ret;
++ } else {
++ rcar_csi2_hwdeinit(priv);
++ pm_runtime_put_sync(&priv->pdev->dev);
++ }
++
++ return ret;
++}
++
++static struct v4l2_subdev_core_ops rcar_csi2_subdev_core_ops = {
++ .s_power = rcar_csi2_s_power,
++};
++
++static struct v4l2_subdev_ops rcar_csi2_subdev_ops = {
++ .core = &rcar_csi2_subdev_core_ops,
++};
++
++#ifdef CONFIG_OF
++static const struct of_device_id rcar_csi2_of_table[] = {
++ { .compatible = "renesas,r8a7796-csi2", .data = (void *)RCAR_GEN3 },
++ { .compatible = "renesas,r8a7795-csi2", .data = (void *)RCAR_GEN3 },
++ { },
++};
++MODULE_DEVICE_TABLE(of, rcar_csi2_of_table);
++#endif
++
++static struct platform_device_id rcar_csi2_id_table[] = {
++ { "r8a7796-csi2", RCAR_GEN3 },
++ { "r8a7795-csi2", RCAR_GEN3 },
++ {},
++};
++MODULE_DEVICE_TABLE(platform, rcar_csi2_id_table);
++
++static int rcar_csi2_parse_dt(struct device_node *np,
++ struct rcar_csi2_link_config *config)
++{
++ struct v4l2_of_endpoint bus_cfg;
++ struct device_node *endpoint;
++ struct device_node *vc_np, *vc_ch;
++ const char *str;
++ char csi_name[9];
++ int ret;
++ int i, ch;
++
++ /* Parse the endpoint. */
++ endpoint = of_graph_get_next_endpoint(np, NULL);
++ if (!endpoint)
++ return -EINVAL;
++
++ v4l2_of_parse_endpoint(endpoint, &bus_cfg);
++ of_node_put(endpoint);
++
++ config->lanes = bus_cfg.bus.mipi_csi2.num_data_lanes;
++
++ ret = of_property_read_string(np, "adi,input-interface", &str);
++ if (ret < 0)
++ return ret;
++
++ vc_np = of_get_child_by_name(np, "virtual,channel");
++
++ config->vcdt = 0;
++ config->vcdt2 = 0;
++ for (i = 0; i < VC_MAX_CHANNEL; i++) {
++ sprintf(csi_name, "csi2_vc%d", i);
++
++ vc_ch = of_get_child_by_name(vc_np, csi_name);
++ if (!vc_ch)
++ continue;
++ ret = of_property_read_string(vc_ch, "data,type", &str);
++ if (ret < 0)
++ return ret;
++ ret = of_property_read_u32(vc_ch, "receive,vc", &ch);
++ if (ret < 0)
++ return ret;
++
++ if (i < 2) {
++ if (!strcmp(str, "rgb888"))
++ config->vcdt |= (0x24 << (i * 16));
++ else if (!strcmp(str, "ycbcr422"))
++ config->vcdt |= (0x1e << (i * 16));
++ else
++ config->vcdt |= 0;
++
++ config->vcdt |= (ch << (8 + (i * 16)));
++ config->vcdt |= (RCAR_CSI2_VCDT_VCDTN_EN << (i * 16)) |
++ (RCAR_CSI2_VCDT_SEL_DTN_ON << (i * 16));
++ }
++ if (i >= 2) {
++ int j = (i - 2);
++
++ if (!strcmp(str, "rgb888"))
++ config->vcdt2 |= (0x24 << (j * 16));
++ else if (!strcmp(str, "ycbcr422"))
++ config->vcdt2 |= (0x1e << (j * 16));
++ else
++ config->vcdt2 |= 0;
++
++ config->vcdt2 |= (ch << (8 + (j * 16)));
++ config->vcdt2 |= (RCAR_CSI2_VCDT_VCDTN_EN << (j * 16)) |
++ (RCAR_CSI2_VCDT_SEL_DTN_ON << (j * 16));
++ }
++ }
++
++ return 0;
++}
++
++static int rcar_csi2_probe(struct platform_device *pdev)
++{
++ struct resource *res;
++ unsigned int irq;
++ int ret;
++ struct rcar_csi2 *priv;
++ /* Platform data specify the PHY, lanes, ECC, CRC */
++ struct rcar_csi2_pdata *pdata;
++ struct rcar_csi2_link_config link_config;
++
++ dev_dbg(&pdev->dev, "CSI2 probed.\n");
++
++ INIT_RCAR_CSI2_LINK_CONFIG(link_config);
++
++ if (pdev->dev.of_node) {
++ ret = rcar_csi2_parse_dt(pdev->dev.of_node, &link_config);
++ if (ret)
++ return ret;
++
++ if (link_config.lanes == 4)
++ dev_info(&pdev->dev,
++ "Detected rgb888 in rcar_csi2_parse_dt\n");
++ else
++ dev_info(&pdev->dev,
++ "Detected YCbCr422 in rcar_csi2_parse_dt\n");
++ } else {
++ pdata = pdev->dev.platform_data;
++ if (!pdata)
++ return -EINVAL;
++ }
++
++ priv = devm_kzalloc(&pdev->dev, sizeof(struct rcar_csi2), GFP_KERNEL);
++ if (!priv)
++ return -ENOMEM;
++
++ res = platform_get_resource(pdev, IORESOURCE_MEM, 0);
++ /* Interrupt unused so far */
++ irq = platform_get_irq(pdev, 0);
++
++ if (!res || (int)irq <= 0) {
++ dev_err(&pdev->dev, "Not enough CSI2 platform resources.\n");
++ return -ENODEV;
++ }
++
++ priv->irq = irq;
++
++ priv->base = devm_ioremap_resource(&pdev->dev, res);
++ if (IS_ERR(priv->base))
++ return PTR_ERR(priv->base);
++
++ ret = devm_request_irq(&pdev->dev, irq, rcar_csi2_irq, IRQF_SHARED,
++ dev_name(&pdev->dev), priv);
++ if (ret)
++ return ret;
++
++ priv->pdev = pdev;
++ priv->subdev.owner = THIS_MODULE;
++ priv->subdev.dev = &pdev->dev;
++ priv->lanes = link_config.lanes;
++ priv->vcdt = link_config.vcdt;
++ priv->vcdt2 = link_config.vcdt2;
++
++ platform_set_drvdata(pdev, &priv->subdev);
++
++ v4l2_subdev_init(&priv->subdev, &rcar_csi2_subdev_ops);
++ v4l2_set_subdevdata(&priv->subdev, &pdev->dev);
++
++ snprintf(priv->subdev.name, V4L2_SUBDEV_NAME_SIZE, "rcar_csi2.%s",
++ dev_name(&pdev->dev));
++
++ ret = v4l2_async_register_subdev(&priv->subdev);
++ if (ret < 0)
++ return ret;
++
++ spin_lock_init(&priv->lock);
++
++ pm_runtime_enable(&pdev->dev);
++
++ dev_dbg(&pdev->dev, "CSI2 probed.\n");
++
++ return 0;
++}
++
++static int rcar_csi2_remove(struct platform_device *pdev)
++{
++ struct v4l2_subdev *subdev = platform_get_drvdata(pdev);
++ struct rcar_csi2 *priv = container_of(subdev, struct rcar_csi2, subdev);
++
++ v4l2_async_unregister_subdev(&priv->subdev);
++ pm_runtime_disable(&pdev->dev);
++
++ return 0;
++}
++
++#ifdef CONFIG_PM_SLEEP
++static int rcar_csi2_suspend(struct device *dev)
++{
++ /* Empty function for now */
++ return 0;
++}
++
++static int rcar_csi2_resume(struct device *dev)
++{
++ /* Empty function for now */
++ return 0;
++}
++
++static SIMPLE_DEV_PM_OPS(rcar_csi2_pm_ops,
++ rcar_csi2_suspend, rcar_csi2_resume);
++#define DEV_PM_OPS (&rcar_csi2_pm_ops)
++#else
++#define DEV_PM_OPS NULL
++#endif /* CONFIG_PM_SLEEP */
++
++static struct platform_driver __refdata rcar_csi2_pdrv = {
++ .remove = rcar_csi2_remove,
++ .probe = rcar_csi2_probe,
++ .driver = {
++ .name = DRV_NAME,
++ .pm = DEV_PM_OPS,
++ .of_match_table = of_match_ptr(rcar_csi2_of_table),
++ },
++ .id_table = rcar_csi2_id_table,
++};
++
++module_platform_driver(rcar_csi2_pdrv);
++
++MODULE_DESCRIPTION("Renesas R-Car MIPI CSI-2 driver");
++MODULE_AUTHOR("Koji Matsuoka <koji.matsuoka.xm@renesas.com>");
++MODULE_LICENSE("GPL v2");
++MODULE_ALIAS("platform:rcar-csi2");
+diff --git a/drivers/media/platform/soc_camera/rcar_vin.c b/drivers/media/platform/soc_camera/rcar_vin.c
+new file mode 100644
+index 0000000..400958b
+--- /dev/null
++++ b/drivers/media/platform/soc_camera/rcar_vin.c
+@@ -0,0 +1,3071 @@
++/*
++ * SoC-camera host driver for Renesas R-Car VIN unit
++ *
++ * Copyright (C) 2015-2016 Renesas Electronics Corporation
++ * Copyright (C) 2011-2013 Renesas Solutions Corp.
++ * Copyright (C) 2013 Cogent Embedded, Inc., <source@cogentembedded.com>
++ *
++ * Based on V4L2 Driver for SuperH Mobile CEU interface "sh_mobile_ceu_camera.c"
++ *
++ * Copyright (C) 2008 Magnus Damm
++ *
++ * This program is free software; you can redistribute it and/or modify it
++ * under the terms of the GNU General Public License as published by the
++ * Free Software Foundation; either version 2 of the License, or (at your
++ * option) any later version.
++ */
++
++#ifdef CONFIG_VIDEO_RCAR_VIN_LEGACY_DEBUG
++#define DEBUG
++#endif
++
++#include <linux/delay.h>
++#include <linux/interrupt.h>
++#include <linux/io.h>
++#include <linux/kernel.h>
++#include <linux/module.h>
++#include <linux/of.h>
++#include <linux/of_device.h>
++#include <linux/platform_device.h>
++#include <linux/pm_runtime.h>
++#include <linux/slab.h>
++#include <linux/videodev2.h>
++#include <linux/list.h>
++
++#include <media/soc_camera.h>
++#include <media/drv-intf/soc_mediabus.h>
++#include <media/v4l2-common.h>
++#include <media/v4l2-dev.h>
++#include <media/v4l2-device.h>
++#include <media/v4l2-mediabus.h>
++#include <media/v4l2-of.h>
++#include <media/v4l2-subdev.h>
++#include <media/videobuf2-dma-contig.h>
++
++#include <media/rcar_csi2.h>
++
++#include "soc_scale_crop.h"
++
++#define DRV_NAME "rcar_vin"
++
++/* Register offsets for R-Car VIN */
++#define VNMC_REG 0x00 /* Video n Main Control Register */
++#define VNMS_REG 0x04 /* Video n Module Status Register */
++#define VNFC_REG 0x08 /* Video n Frame Capture Register */
++#define VNSLPRC_REG 0x0C /* Video n Start Line Pre-Clip Register */
++#define VNELPRC_REG 0x10 /* Video n End Line Pre-Clip Register */
++#define VNSPPRC_REG 0x14 /* Video n Start Pixel Pre-Clip Register */
++#define VNEPPRC_REG 0x18 /* Video n End Pixel Pre-Clip Register */
++#define VNSLPOC_REG 0x1C /* Video n Start Line Post-Clip Register */
++#define VNELPOC_REG 0x20 /* Video n End Line Post-Clip Register */
++#define VNSPPOC_REG 0x24 /* Video n Start Pixel Post-Clip Register */
++#define VNEPPOC_REG 0x28 /* Video n End Pixel Post-Clip Register */
++#define VNIS_REG 0x2C /* Video n Image Stride Register */
++#define VNMB_REG(m) (0x30 + ((m) << 2)) /* Video n Memory Base m Register */
++#define VNIE_REG 0x40 /* Video n Interrupt Enable Register */
++#define VNINTS_REG 0x44 /* Video n Interrupt Status Register */
++#define VNSI_REG 0x48 /* Video n Scanline Interrupt Register */
++#define VNMTC_REG 0x4C /* Video n Memory Transfer Control Register */
++#define VNYS_REG 0x50 /* Video n Y Scale Register */
++#define VNXS_REG 0x54 /* Video n X Scale Register */
++#define VNDMR_REG 0x58 /* Video n Data Mode Register */
++#define VNDMR2_REG 0x5C /* Video n Data Mode Register 2 */
++#define VNUVAOF_REG 0x60 /* Video n UV Address Offset Register */
++#define VNC1A_REG 0x80 /* Video n Coefficient Set C1A Register */
++#define VNC1B_REG 0x84 /* Video n Coefficient Set C1B Register */
++#define VNC1C_REG 0x88 /* Video n Coefficient Set C1C Register */
++#define VNC2A_REG 0x90 /* Video n Coefficient Set C2A Register */
++#define VNC2B_REG 0x94 /* Video n Coefficient Set C2B Register */
++#define VNC2C_REG 0x98 /* Video n Coefficient Set C2C Register */
++#define VNC3A_REG 0xA0 /* Video n Coefficient Set C3A Register */
++#define VNC3B_REG 0xA4 /* Video n Coefficient Set C3B Register */
++#define VNC3C_REG 0xA8 /* Video n Coefficient Set C3C Register */
++#define VNC4A_REG 0xB0 /* Video n Coefficient Set C4A Register */
++#define VNC4B_REG 0xB4 /* Video n Coefficient Set C4B Register */
++#define VNC4C_REG 0xB8 /* Video n Coefficient Set C4C Register */
++#define VNC5A_REG 0xC0 /* Video n Coefficient Set C5A Register */
++#define VNC5B_REG 0xC4 /* Video n Coefficient Set C5B Register */
++#define VNC5C_REG 0xC8 /* Video n Coefficient Set C5C Register */
++#define VNC6A_REG 0xD0 /* Video n Coefficient Set C6A Register */
++#define VNC6B_REG 0xD4 /* Video n Coefficient Set C6B Register */
++#define VNC6C_REG 0xD8 /* Video n Coefficient Set C6C Register */
++#define VNC7A_REG 0xE0 /* Video n Coefficient Set C7A Register */
++#define VNC7B_REG 0xE4 /* Video n Coefficient Set C7B Register */
++#define VNC7C_REG 0xE8 /* Video n Coefficient Set C7C Register */
++#define VNC8A_REG 0xF0 /* Video n Coefficient Set C8A Register */
++#define VNC8B_REG 0xF4 /* Video n Coefficient Set C8B Register */
++#define VNC8C_REG 0xF8 /* Video n Coefficient Set C8C Register */
++
++/* Register bit fields for R-Car VIN */
++/* Video n Main Control Register bits */
++#define VNMC_DPINE (1 << 27)
++#define VNMC_SCLE (1 << 26)
++#define VNMC_FOC (1 << 21)
++#define VNMC_YCAL (1 << 19)
++#define VNMC_INF_YUV8_BT656 (0 << 16)
++#define VNMC_INF_YUV8_BT601 (1 << 16)
++#define VNMC_INF_YUV10_BT656 (2 << 16)
++#define VNMC_INF_YUV10_BT601 (3 << 16)
++#define VNMC_INF_YUV16 (5 << 16)
++#define VNMC_INF_RGB888 (6 << 16)
++#define VNMC_INF_MASK (7 << 16)
++#define VNMC_VUP (1 << 10)
++#define VNMC_IM_ODD (0 << 3)
++#define VNMC_IM_ODD_EVEN (1 << 3)
++#define VNMC_IM_EVEN (2 << 3)
++#define VNMC_IM_FULL (3 << 3)
++#define VNMC_BPS (1 << 1)
++#define VNMC_ME (1 << 0)
++
++/* Video n Module Status Register bits */
++#define VNMS_FBS_MASK (3 << 3)
++#define VNMS_FBS_SHIFT 3
++#define VNMS_AV (1 << 1)
++#define VNMS_CA (1 << 0)
++
++/* Video n Frame Capture Register bits */
++#define VNFC_C_FRAME (1 << 1)
++#define VNFC_S_FRAME (1 << 0)
++
++/* Video n Interrupt Enable Register bits */
++#define VNIE_FIE (1 << 4)
++#define VNIE_EFE (1 << 1)
++#define VNIE_FOE (1 << 0)
++
++/* Video n Interrupt Status Register bits */
++#define VNINTS_FIS (1 << 4)
++#define VNINTS_EFS (1 << 1)
++#define VNINTS_FOS (1 << 0)
++
++/* Video n Data Mode Register bits */
++#define VNDMR_EXRGB (1 << 8)
++#define VNDMR_BPSM (1 << 4)
++#define VNDMR_DTMD_YCSEP (1 << 1)
++#define VNDMR_DTMD_ARGB (1 << 0)
++#define VNDMR_DTMD_YCSEP_YCBCR420 (3 << 0)
++
++/* Video n Data Mode Register 2 bits */
++#define VNDMR2_VPS (1 << 30)
++#define VNDMR2_HPS (1 << 29)
++#define VNDMR2_FTEV (1 << 17)
++#define VNDMR2_VLV(n) ((n & 0xf) << 12)
++
++/* setting CSI2 on R-Car Gen3*/
++#define VNCSI_IFMD_REG 0x20 /* Video n CSI2 Interface Mode Register */
++
++#define VNCSI_IFMD_DES1 (1 << 26) /* CSI20 */
++#define VNCSI_IFMD_DES0 (1 << 25) /* H3:CSI40/41, M3:CSI40 */
++
++#define VNCSI_IFMD_CSI_CHSEL(n) (n << 0)
++#define VNCSI_IFMD_SEL_NUMBER 5
++
++/* UDS */
++#define VNUDS_CTRL_REG 0x80 /* Scaling Control Registers */
++#define VNUDS_CTRL_AMD (1 << 30)
++#define VNUDS_CTRL_BC (1 << 20)
++#define VNUDS_CTRL_TDIPC (1 << 1)
++
++#define VNUDS_SCALE_REG 0x84 /* Scaling Factor Register */
++#define VNUDS_PASS_BWIDTH_REG 0x90 /* Passband Registers */
++#define VNUDS_IPC_REG 0x98 /* 2D IPC Setting Register */
++#define VNUDS_CLIP_SIZE_REG 0xA4 /* UDS Output Size Clipping Register */
++
++#define TIMEOUT_MS 100
++
++#define RCAR_VIN_HSYNC_ACTIVE_LOW (1 << 0)
++#define RCAR_VIN_VSYNC_ACTIVE_LOW (1 << 1)
++#define RCAR_VIN_BT601 (1 << 2)
++#define RCAR_VIN_BT656 (1 << 3)
++#define RCAR_VIN_CSI2 (1 << 4)
++
++static int ifmd0_reg_match[VNCSI_IFMD_SEL_NUMBER];
++static int ifmd4_reg_match[VNCSI_IFMD_SEL_NUMBER];
++static int ifmd0_init = true;
++static int ifmd4_init = true;
++
++enum chip_id {
++ RCAR_GEN3,
++ RCAR_M3,
++ RCAR_H3,
++ RCAR_GEN2,
++ RCAR_H1,
++ RCAR_M1,
++ RCAR_E1,
++};
++
++enum csi2_ch {
++ RCAR_CSI_CH_NONE = -1,
++ RCAR_CSI40,
++ RCAR_CSI20,
++ RCAR_CSI41,
++ RCAR_CSI21,
++ RCAR_CSI_MAX,
++};
++
++enum gen3_vin_ch {
++ RCAR_VIN_CH_NONE = -1,
++ RCAR_VIDEO_0,
++ RCAR_VIDEO_1,
++ RCAR_VIDEO_2,
++ RCAR_VIDEO_3,
++ RCAR_VIDEO_4,
++ RCAR_VIDEO_5,
++ RCAR_VIDEO_6,
++ RCAR_VIDEO_7,
++ RCAR_VIDEO_MAX,
++};
++
++enum virtual_ch {
++ RCAR_VIRTUAL_NONE = -1,
++ RCAR_VIRTUAL_CH0,
++ RCAR_VIRTUAL_CH1,
++ RCAR_VIRTUAL_CH2,
++ RCAR_VIRTUAL_CH3,
++ RCAR_VIRTUAL_MAX,
++};
++
++struct vin_gen3_virtual_sel {
++ enum csi2_ch csi2_ch;
++ enum virtual_ch vc;
++};
++
++struct vin_gen3_ifmd {
++ unsigned int set_reg;
++ struct vin_gen3_virtual_sel v_sel[8];
++};
++
++static const struct vin_gen3_ifmd vin_h3_vc_ifmd[] = {
++ { 0x0000,
++ {
++ {RCAR_CSI40, RCAR_VIRTUAL_CH0},
++ {RCAR_CSI20, RCAR_VIRTUAL_CH0},
++ {RCAR_CSI20, RCAR_VIRTUAL_CH1},
++ {RCAR_CSI40, RCAR_VIRTUAL_CH1},
++ {RCAR_CSI41, RCAR_VIRTUAL_CH0},
++ {RCAR_CSI20, RCAR_VIRTUAL_CH0},
++ {RCAR_CSI20, RCAR_VIRTUAL_CH1},
++ {RCAR_CSI41, RCAR_VIRTUAL_CH1},
++ }
++ },
++ { 0x0001,
++ {
++ {RCAR_CSI20, RCAR_VIRTUAL_CH0},
++ {RCAR_CSI40, RCAR_VIRTUAL_CH1},
++ {RCAR_CSI40, RCAR_VIRTUAL_CH0},
++ {RCAR_CSI20, RCAR_VIRTUAL_CH1},
++ {RCAR_CSI20, RCAR_VIRTUAL_CH0},
++ {RCAR_CSI41, RCAR_VIRTUAL_CH1},
++ {RCAR_CSI41, RCAR_VIRTUAL_CH0},
++ {RCAR_CSI20, RCAR_VIRTUAL_CH1},
++ }
++ },
++ { 0x0002,
++ {
++ {RCAR_CSI40, RCAR_VIRTUAL_CH1},
++ {RCAR_CSI40, RCAR_VIRTUAL_CH0},
++ {RCAR_CSI20, RCAR_VIRTUAL_CH0},
++ {RCAR_CSI20, RCAR_VIRTUAL_CH1},
++ {RCAR_CSI41, RCAR_VIRTUAL_CH1},
++ {RCAR_CSI41, RCAR_VIRTUAL_CH0},
++ {RCAR_CSI20, RCAR_VIRTUAL_CH0},
++ {RCAR_CSI20, RCAR_VIRTUAL_CH1},
++ }
++ },
++ { 0x0003,
++ {
++ {RCAR_CSI40, RCAR_VIRTUAL_CH0},
++ {RCAR_CSI40, RCAR_VIRTUAL_CH1},
++ {RCAR_CSI40, RCAR_VIRTUAL_CH2},
++ {RCAR_CSI40, RCAR_VIRTUAL_CH3},
++ {RCAR_CSI41, RCAR_VIRTUAL_CH0},
++ {RCAR_CSI41, RCAR_VIRTUAL_CH1},
++ {RCAR_CSI41, RCAR_VIRTUAL_CH2},
++ {RCAR_CSI41, RCAR_VIRTUAL_CH3},
++ }
++ },
++ { 0x0004,
++ {
++ {RCAR_CSI20, RCAR_VIRTUAL_CH0},
++ {RCAR_CSI20, RCAR_VIRTUAL_CH1},
++ {RCAR_CSI20, RCAR_VIRTUAL_CH2},
++ {RCAR_CSI20, RCAR_VIRTUAL_CH3},
++ {RCAR_CSI20, RCAR_VIRTUAL_CH0},
++ {RCAR_CSI20, RCAR_VIRTUAL_CH1},
++ {RCAR_CSI20, RCAR_VIRTUAL_CH2},
++ {RCAR_CSI20, RCAR_VIRTUAL_CH3},
++ }
++ },
++};
++
++static const struct vin_gen3_ifmd vin_m3_vc_ifmd[] = {
++ { 0x0000,
++ {
++ {RCAR_CSI40, RCAR_VIRTUAL_CH0},
++ {RCAR_CSI20, RCAR_VIRTUAL_CH0},
++ {RCAR_CSI_CH_NONE, RCAR_VIN_CH_NONE},
++ {RCAR_CSI40, RCAR_VIRTUAL_CH1},
++ {RCAR_CSI40, RCAR_VIRTUAL_CH0},
++ {RCAR_CSI20, RCAR_VIRTUAL_CH0},
++ {RCAR_CSI_CH_NONE, RCAR_VIN_CH_NONE},
++ {RCAR_CSI40, RCAR_VIRTUAL_CH1},
++ }
++ },
++ { 0x0001,
++ {
++ {RCAR_CSI20, RCAR_VIRTUAL_CH0},
++ {RCAR_CSI_CH_NONE, RCAR_VIN_CH_NONE},
++ {RCAR_CSI40, RCAR_VIRTUAL_CH0},
++ {RCAR_CSI20, RCAR_VIRTUAL_CH1},
++ {RCAR_CSI20, RCAR_VIRTUAL_CH0},
++ {RCAR_CSI_CH_NONE, RCAR_VIN_CH_NONE},
++ {RCAR_CSI40, RCAR_VIRTUAL_CH0},
++ {RCAR_CSI20, RCAR_VIRTUAL_CH1},
++ }
++ },
++ { 0x0002,
++ {
++ {RCAR_CSI_CH_NONE, RCAR_VIN_CH_NONE},
++ {RCAR_CSI40, RCAR_VIRTUAL_CH0},
++ {RCAR_CSI20, RCAR_VIRTUAL_CH0},
++ {RCAR_CSI_CH_NONE, RCAR_VIN_CH_NONE},
++ {RCAR_CSI_CH_NONE, RCAR_VIN_CH_NONE},
++ {RCAR_CSI40, RCAR_VIRTUAL_CH0},
++ {RCAR_CSI20, RCAR_VIRTUAL_CH0},
++ {RCAR_CSI_CH_NONE, RCAR_VIN_CH_NONE},
++ }
++ },
++ { 0x0003,
++ {
++ {RCAR_CSI40, RCAR_VIRTUAL_CH0},
++ {RCAR_CSI40, RCAR_VIRTUAL_CH1},
++ {RCAR_CSI40, RCAR_VIRTUAL_CH2},
++ {RCAR_CSI40, RCAR_VIRTUAL_CH3},
++ {RCAR_CSI40, RCAR_VIRTUAL_CH0},
++ {RCAR_CSI40, RCAR_VIRTUAL_CH1},
++ {RCAR_CSI40, RCAR_VIRTUAL_CH2},
++ {RCAR_CSI40, RCAR_VIRTUAL_CH3},
++ }
++ },
++ { 0x0004,
++ {
++ {RCAR_CSI20, RCAR_VIRTUAL_CH0},
++ {RCAR_CSI20, RCAR_VIRTUAL_CH1},
++ {RCAR_CSI20, RCAR_VIRTUAL_CH2},
++ {RCAR_CSI20, RCAR_VIRTUAL_CH3},
++ {RCAR_CSI20, RCAR_VIRTUAL_CH0},
++ {RCAR_CSI20, RCAR_VIRTUAL_CH1},
++ {RCAR_CSI20, RCAR_VIRTUAL_CH2},
++ {RCAR_CSI20, RCAR_VIRTUAL_CH3},
++ }
++ },
++};
++
++enum csi2_fmt {
++ RCAR_CSI_FMT_NONE = -1,
++ RCAR_CSI_RGB888,
++ RCAR_CSI_YCBCR422,
++};
++
++struct vin_coeff {
++ unsigned short xs_value;
++ u32 coeff_set[24];
++};
++
++static const struct vin_coeff vin_coeff_set[] = {
++ { 0x0000, {
++ 0x00000000, 0x00000000, 0x00000000,
++ 0x00000000, 0x00000000, 0x00000000,
++ 0x00000000, 0x00000000, 0x00000000,
++ 0x00000000, 0x00000000, 0x00000000,
++ 0x00000000, 0x00000000, 0x00000000,
++ 0x00000000, 0x00000000, 0x00000000,
++ 0x00000000, 0x00000000, 0x00000000,
++ 0x00000000, 0x00000000, 0x00000000 },
++ },
++ { 0x1000, {
++ 0x000fa400, 0x000fa400, 0x09625902,
++ 0x000003f8, 0x00000403, 0x3de0d9f0,
++ 0x001fffed, 0x00000804, 0x3cc1f9c3,
++ 0x001003de, 0x00000c01, 0x3cb34d7f,
++ 0x002003d2, 0x00000c00, 0x3d24a92d,
++ 0x00200bca, 0x00000bff, 0x3df600d2,
++ 0x002013cc, 0x000007ff, 0x3ed70c7e,
++ 0x00100fde, 0x00000000, 0x3f87c036 },
++ },
++ { 0x1200, {
++ 0x002ffff1, 0x002ffff1, 0x02a0a9c8,
++ 0x002003e7, 0x001ffffa, 0x000185bc,
++ 0x002007dc, 0x000003ff, 0x3e52859c,
++ 0x00200bd4, 0x00000002, 0x3d53996b,
++ 0x00100fd0, 0x00000403, 0x3d04ad2d,
++ 0x00000bd5, 0x00000403, 0x3d35ace7,
++ 0x3ff003e4, 0x00000801, 0x3dc674a1,
++ 0x3fffe800, 0x00000800, 0x3e76f461 },
++ },
++ { 0x1400, {
++ 0x00100be3, 0x00100be3, 0x04d1359a,
++ 0x00000fdb, 0x002003ed, 0x0211fd93,
++ 0x00000fd6, 0x002003f4, 0x0002d97b,
++ 0x000007d6, 0x002ffffb, 0x3e93b956,
++ 0x3ff003da, 0x001003ff, 0x3db49926,
++ 0x3fffefe9, 0x00100001, 0x3d655cee,
++ 0x3fffd400, 0x00000003, 0x3d65f4b6,
++ 0x000fb421, 0x00000402, 0x3dc6547e },
++ },
++ { 0x1600, {
++ 0x00000bdd, 0x00000bdd, 0x06519578,
++ 0x3ff007da, 0x00000be3, 0x03c24973,
++ 0x3ff003d9, 0x00000be9, 0x01b30d5f,
++ 0x3ffff7df, 0x001003f1, 0x0003c542,
++ 0x000fdfec, 0x001003f7, 0x3ec4711d,
++ 0x000fc400, 0x002ffffd, 0x3df504f1,
++ 0x001fa81a, 0x002ffc00, 0x3d957cc2,
++ 0x002f8c3c, 0x00100000, 0x3db5c891 },
++ },
++ { 0x1800, {
++ 0x3ff003dc, 0x3ff003dc, 0x0791e558,
++ 0x000ff7dd, 0x3ff007de, 0x05328554,
++ 0x000fe7e3, 0x3ff00be2, 0x03232546,
++ 0x000fd7ee, 0x000007e9, 0x0143bd30,
++ 0x001fb800, 0x000007ee, 0x00044511,
++ 0x002fa015, 0x000007f4, 0x3ef4bcee,
++ 0x002f8832, 0x001003f9, 0x3e4514c7,
++ 0x001f7853, 0x001003fd, 0x3de54c9f },
++ },
++ { 0x1a00, {
++ 0x000fefe0, 0x000fefe0, 0x08721d3c,
++ 0x001fdbe7, 0x000ffbde, 0x0652a139,
++ 0x001fcbf0, 0x000003df, 0x0463292e,
++ 0x002fb3ff, 0x3ff007e3, 0x0293a91d,
++ 0x002f9c12, 0x3ff00be7, 0x01241905,
++ 0x001f8c29, 0x000007ed, 0x3fe470eb,
++ 0x000f7c46, 0x000007f2, 0x3f04b8ca,
++ 0x3fef7865, 0x000007f6, 0x3e74e4a8 },
++ },
++ { 0x1c00, {
++ 0x001fd3e9, 0x001fd3e9, 0x08f23d26,
++ 0x002fbff3, 0x001fe3e4, 0x0712ad23,
++ 0x002fa800, 0x000ff3e0, 0x05631d1b,
++ 0x001f9810, 0x000ffbe1, 0x03b3890d,
++ 0x000f8c23, 0x000003e3, 0x0233e8fa,
++ 0x3fef843b, 0x000003e7, 0x00f430e4,
++ 0x3fbf8456, 0x3ff00bea, 0x00046cc8,
++ 0x3f8f8c72, 0x3ff00bef, 0x3f3490ac },
++ },
++ { 0x1e00, {
++ 0x001fbbf4, 0x001fbbf4, 0x09425112,
++ 0x001fa800, 0x002fc7ed, 0x0792b110,
++ 0x000f980e, 0x001fdbe6, 0x0613110a,
++ 0x3fff8c20, 0x001fe7e3, 0x04a368fd,
++ 0x3fcf8c33, 0x000ff7e2, 0x0343b8ed,
++ 0x3f9f8c4a, 0x000fffe3, 0x0203f8da,
++ 0x3f5f9c61, 0x000003e6, 0x00e428c5,
++ 0x3f1fb07b, 0x000003eb, 0x3fe440af },
++ },
++ { 0x2000, {
++ 0x000fa400, 0x000fa400, 0x09625902,
++ 0x3fff980c, 0x001fb7f5, 0x0812b0ff,
++ 0x3fdf901c, 0x001fc7ed, 0x06b2fcfa,
++ 0x3faf902d, 0x001fd3e8, 0x055348f1,
++ 0x3f7f983f, 0x001fe3e5, 0x04038ce3,
++ 0x3f3fa454, 0x001fefe3, 0x02e3c8d1,
++ 0x3f0fb86a, 0x001ff7e4, 0x01c3e8c0,
++ 0x3ecfd880, 0x000fffe6, 0x00c404ac },
++ },
++ { 0x2200, {
++ 0x3fdf9c0b, 0x3fdf9c0b, 0x09725cf4,
++ 0x3fbf9818, 0x3fffa400, 0x0842a8f1,
++ 0x3f8f9827, 0x000fb3f7, 0x0702f0ec,
++ 0x3f5fa037, 0x000fc3ef, 0x05d330e4,
++ 0x3f2fac49, 0x001fcfea, 0x04a364d9,
++ 0x3effc05c, 0x001fdbe7, 0x038394ca,
++ 0x3ecfdc6f, 0x001fe7e6, 0x0273b0bb,
++ 0x3ea00083, 0x001fefe6, 0x0183c0a9 },
++ },
++ { 0x2400, {
++ 0x3f9fa014, 0x3f9fa014, 0x098260e6,
++ 0x3f7f9c23, 0x3fcf9c0a, 0x08629ce5,
++ 0x3f4fa431, 0x3fefa400, 0x0742d8e1,
++ 0x3f1fb440, 0x3fffb3f8, 0x062310d9,
++ 0x3eefc850, 0x000fbbf2, 0x050340d0,
++ 0x3ecfe062, 0x000fcbec, 0x041364c2,
++ 0x3ea00073, 0x001fd3ea, 0x03037cb5,
++ 0x3e902086, 0x001fdfe8, 0x022388a5 },
++ },
++ { 0x2600, {
++ 0x3f5fa81e, 0x3f5fa81e, 0x096258da,
++ 0x3f3fac2b, 0x3f8fa412, 0x088290d8,
++ 0x3f0fbc38, 0x3fafa408, 0x0772c8d5,
++ 0x3eefcc47, 0x3fcfa800, 0x0672f4ce,
++ 0x3ecfe456, 0x3fefaffa, 0x05531cc6,
++ 0x3eb00066, 0x3fffbbf3, 0x047334bb,
++ 0x3ea01c77, 0x000fc7ee, 0x039348ae,
++ 0x3ea04486, 0x000fd3eb, 0x02b350a1 },
++ },
++ { 0x2800, {
++ 0x3f2fb426, 0x3f2fb426, 0x094250ce,
++ 0x3f0fc032, 0x3f4fac1b, 0x086284cd,
++ 0x3eefd040, 0x3f7fa811, 0x0782acc9,
++ 0x3ecfe84c, 0x3f9fa807, 0x06a2d8c4,
++ 0x3eb0005b, 0x3fbfac00, 0x05b2f4bc,
++ 0x3eb0186a, 0x3fdfb3fa, 0x04c308b4,
++ 0x3eb04077, 0x3fefbbf4, 0x03f31ca8,
++ 0x3ec06884, 0x000fbff2, 0x03031c9e },
++ },
++ { 0x2a00, {
++ 0x3f0fc42d, 0x3f0fc42d, 0x090240c4,
++ 0x3eefd439, 0x3f2fb822, 0x08526cc2,
++ 0x3edfe845, 0x3f4fb018, 0x078294bf,
++ 0x3ec00051, 0x3f6fac0f, 0x06b2b4bb,
++ 0x3ec0185f, 0x3f8fac07, 0x05e2ccb4,
++ 0x3ec0386b, 0x3fafac00, 0x0502e8ac,
++ 0x3ed05c77, 0x3fcfb3fb, 0x0432f0a3,
++ 0x3ef08482, 0x3fdfbbf6, 0x0372f898 },
++ },
++ { 0x2c00, {
++ 0x3eefdc31, 0x3eefdc31, 0x08e238b8,
++ 0x3edfec3d, 0x3f0fc828, 0x082258b9,
++ 0x3ed00049, 0x3f1fc01e, 0x077278b6,
++ 0x3ed01455, 0x3f3fb815, 0x06c294b2,
++ 0x3ed03460, 0x3f5fb40d, 0x0602acac,
++ 0x3ef0506c, 0x3f7fb006, 0x0542c0a4,
++ 0x3f107476, 0x3f9fb400, 0x0472c89d,
++ 0x3f309c80, 0x3fbfb7fc, 0x03b2cc94 },
++ },
++ { 0x2e00, {
++ 0x3eefec37, 0x3eefec37, 0x088220b0,
++ 0x3ee00041, 0x3effdc2d, 0x07f244ae,
++ 0x3ee0144c, 0x3f0fd023, 0x07625cad,
++ 0x3ef02c57, 0x3f1fc81a, 0x06c274a9,
++ 0x3f004861, 0x3f3fbc13, 0x060288a6,
++ 0x3f20686b, 0x3f5fb80c, 0x05529c9e,
++ 0x3f408c74, 0x3f6fb805, 0x04b2ac96,
++ 0x3f80ac7e, 0x3f8fb800, 0x0402ac8e },
++ },
++ { 0x3000, {
++ 0x3ef0003a, 0x3ef0003a, 0x084210a6,
++ 0x3ef01045, 0x3effec32, 0x07b228a7,
++ 0x3f00284e, 0x3f0fdc29, 0x073244a4,
++ 0x3f104058, 0x3f0fd420, 0x06a258a2,
++ 0x3f305c62, 0x3f2fc818, 0x0612689d,
++ 0x3f508069, 0x3f3fc011, 0x05728496,
++ 0x3f80a072, 0x3f4fc00a, 0x04d28c90,
++ 0x3fc0c07b, 0x3f6fbc04, 0x04429088 },
++ },
++ { 0x3200, {
++ 0x3f00103e, 0x3f00103e, 0x07f1fc9e,
++ 0x3f102447, 0x3f000035, 0x0782149d,
++ 0x3f203c4f, 0x3f0ff02c, 0x07122c9c,
++ 0x3f405458, 0x3f0fe424, 0x06924099,
++ 0x3f607061, 0x3f1fd41d, 0x06024c97,
++ 0x3f909068, 0x3f2fcc16, 0x05726490,
++ 0x3fc0b070, 0x3f3fc80f, 0x04f26c8a,
++ 0x0000d077, 0x3f4fc409, 0x04627484 },
++ },
++ { 0x3400, {
++ 0x3f202040, 0x3f202040, 0x07a1e898,
++ 0x3f303449, 0x3f100c38, 0x0741fc98,
++ 0x3f504c50, 0x3f10002f, 0x06e21495,
++ 0x3f706459, 0x3f1ff028, 0x06722492,
++ 0x3fa08060, 0x3f1fe421, 0x05f2348f,
++ 0x3fd09c67, 0x3f1fdc19, 0x05824c89,
++ 0x0000bc6e, 0x3f2fd014, 0x04f25086,
++ 0x0040dc74, 0x3f3fcc0d, 0x04825c7f },
++ },
++ { 0x3600, {
++ 0x3f403042, 0x3f403042, 0x0761d890,
++ 0x3f504848, 0x3f301c3b, 0x0701f090,
++ 0x3f805c50, 0x3f200c33, 0x06a2008f,
++ 0x3fa07458, 0x3f10002b, 0x06520c8d,
++ 0x3fd0905e, 0x3f1ff424, 0x05e22089,
++ 0x0000ac65, 0x3f1fe81d, 0x05823483,
++ 0x0030cc6a, 0x3f2fdc18, 0x04f23c81,
++ 0x0080e871, 0x3f2fd412, 0x0482407c },
++ },
++ { 0x3800, {
++ 0x3f604043, 0x3f604043, 0x0721c88a,
++ 0x3f80544a, 0x3f502c3c, 0x06d1d88a,
++ 0x3fb06851, 0x3f301c35, 0x0681e889,
++ 0x3fd08456, 0x3f30082f, 0x0611fc88,
++ 0x00009c5d, 0x3f200027, 0x05d20884,
++ 0x0030b863, 0x3f2ff421, 0x05621880,
++ 0x0070d468, 0x3f2fe81b, 0x0502247c,
++ 0x00c0ec6f, 0x3f2fe015, 0x04a22877 },
++ },
++ { 0x3a00, {
++ 0x3f904c44, 0x3f904c44, 0x06e1b884,
++ 0x3fb0604a, 0x3f70383e, 0x0691c885,
++ 0x3fe07451, 0x3f502c36, 0x0661d483,
++ 0x00009055, 0x3f401831, 0x0601ec81,
++ 0x0030a85b, 0x3f300c2a, 0x05b1f480,
++ 0x0070c061, 0x3f300024, 0x0562047a,
++ 0x00b0d867, 0x3f3ff41e, 0x05020c77,
++ 0x00f0f46b, 0x3f2fec19, 0x04a21474 },
++ },
++ { 0x3c00, {
++ 0x3fb05c43, 0x3fb05c43, 0x06c1b07e,
++ 0x3fe06c4b, 0x3f902c3f, 0x0681c081,
++ 0x0000844f, 0x3f703838, 0x0631cc7d,
++ 0x00309855, 0x3f602433, 0x05d1d47e,
++ 0x0060b459, 0x3f50142e, 0x0581e47b,
++ 0x00a0c85f, 0x3f400828, 0x0531f078,
++ 0x00e0e064, 0x3f300021, 0x0501fc73,
++ 0x00b0fc6a, 0x3f3ff41d, 0x04a20873 },
++ },
++ { 0x3e00, {
++ 0x3fe06444, 0x3fe06444, 0x0681a07a,
++ 0x00007849, 0x3fc0503f, 0x0641b07a,
++ 0x0020904d, 0x3fa0403a, 0x05f1c07a,
++ 0x0060a453, 0x3f803034, 0x05c1c878,
++ 0x0090b858, 0x3f70202f, 0x0571d477,
++ 0x00d0d05d, 0x3f501829, 0x0531e073,
++ 0x0110e462, 0x3f500825, 0x04e1e471,
++ 0x01510065, 0x3f40001f, 0x04a1f06d },
++ },
++ { 0x4000, {
++ 0x00007044, 0x00007044, 0x06519476,
++ 0x00208448, 0x3fe05c3f, 0x0621a476,
++ 0x0050984d, 0x3fc04c3a, 0x05e1b075,
++ 0x0080ac52, 0x3fa03c35, 0x05a1b875,
++ 0x00c0c056, 0x3f803030, 0x0561c473,
++ 0x0100d45b, 0x3f70202b, 0x0521d46f,
++ 0x0140e860, 0x3f601427, 0x04d1d46e,
++ 0x01810064, 0x3f500822, 0x0491dc6b },
++ },
++ { 0x5000, {
++ 0x0110a442, 0x0110a442, 0x0551545e,
++ 0x0140b045, 0x00e0983f, 0x0531585f,
++ 0x0160c047, 0x00c08c3c, 0x0511645e,
++ 0x0190cc4a, 0x00908039, 0x04f1685f,
++ 0x01c0dc4c, 0x00707436, 0x04d1705e,
++ 0x0200e850, 0x00506833, 0x04b1785b,
++ 0x0230f453, 0x00305c30, 0x0491805a,
++ 0x02710056, 0x0010542d, 0x04718059 },
++ },
++ { 0x6000, {
++ 0x01c0bc40, 0x01c0bc40, 0x04c13052,
++ 0x01e0c841, 0x01a0b43d, 0x04c13851,
++ 0x0210cc44, 0x0180a83c, 0x04a13453,
++ 0x0230d845, 0x0160a03a, 0x04913c52,
++ 0x0260e047, 0x01409838, 0x04714052,
++ 0x0280ec49, 0x01208c37, 0x04514c50,
++ 0x02b0f44b, 0x01008435, 0x04414c50,
++ 0x02d1004c, 0x00e07c33, 0x0431544f },
++ },
++ { 0x7000, {
++ 0x0230c83e, 0x0230c83e, 0x04711c4c,
++ 0x0250d03f, 0x0210c43c, 0x0471204b,
++ 0x0270d840, 0x0200b83c, 0x0451244b,
++ 0x0290dc42, 0x01e0b43a, 0x0441244c,
++ 0x02b0e443, 0x01c0b038, 0x0441284b,
++ 0x02d0ec44, 0x01b0a438, 0x0421304a,
++ 0x02f0f445, 0x0190a036, 0x04213449,
++ 0x0310f847, 0x01709c34, 0x04213848 },
++ },
++ { 0x8000, {
++ 0x0280d03d, 0x0280d03d, 0x04310c48,
++ 0x02a0d43e, 0x0270c83c, 0x04311047,
++ 0x02b0dc3e, 0x0250c83a, 0x04311447,
++ 0x02d0e040, 0x0240c03a, 0x04211446,
++ 0x02e0e840, 0x0220bc39, 0x04111847,
++ 0x0300e842, 0x0210b438, 0x04012445,
++ 0x0310f043, 0x0200b037, 0x04012045,
++ 0x0330f444, 0x01e0ac36, 0x03f12445 },
++ },
++ { 0xefff, {
++ 0x0340dc3a, 0x0340dc3a, 0x03b0ec40,
++ 0x0340e03a, 0x0330e039, 0x03c0f03e,
++ 0x0350e03b, 0x0330dc39, 0x03c0ec3e,
++ 0x0350e43a, 0x0320dc38, 0x03c0f43e,
++ 0x0360e43b, 0x0320d839, 0x03b0f03e,
++ 0x0360e83b, 0x0310d838, 0x03c0fc3b,
++ 0x0370e83b, 0x0310d439, 0x03a0f83d,
++ 0x0370e83c, 0x0300d438, 0x03b0fc3c },
++ }
++};
++
++enum rcar_vin_state {
++ STOPPED = 0,
++ RUNNING,
++ STOPPING,
++};
++
++struct rcar_vin_async_client {
++ struct v4l2_async_subdev *sensor;
++ struct v4l2_async_notifier notifier;
++ struct platform_device *pdev;
++ struct list_head list; /* needed for clean up */
++};
++
++struct soc_of_info {
++ struct soc_camera_async_subdev sasd;
++ struct rcar_vin_async_client sasc;
++ struct v4l2_async_subdev *subdev;
++};
++
++struct rcar_vin_priv {
++ void __iomem *base;
++ spinlock_t lock;
++ int sequence;
++ /* State of the VIN module in capturing mode */
++ enum rcar_vin_state state;
++ struct soc_camera_host ici;
++ struct list_head capture;
++#define MAX_BUFFER_NUM 3
++ struct vb2_v4l2_buffer *queue_buf[MAX_BUFFER_NUM];
++ enum v4l2_field field;
++ unsigned int pdata_flags;
++ unsigned int vb_count;
++ unsigned int nr_hw_slots;
++ bool request_to_stop;
++ struct completion capture_stop;
++ enum chip_id chip;
++ unsigned int max_width;
++ unsigned int max_height;
++ unsigned int ratio_h;
++ unsigned int ratio_v;
++ bool error_flag;
++ enum csi2_ch csi_ch;
++ enum csi2_fmt csi_fmt;
++ enum virtual_ch vc;
++ bool csi_sync;
++
++ struct rcar_vin_async_client *async_client;
++ /* Asynchronous CSI2 linking */
++ struct v4l2_subdev *csi2_sd;
++ /* Synchronous probing compatibility */
++ struct platform_device *csi2_pdev;
++
++ unsigned int index;
++};
++
++#define is_continuous_transfer(priv) (priv->vb_count > MAX_BUFFER_NUM)
++
++struct rcar_vin_buffer {
++ struct vb2_v4l2_buffer vb;
++ struct list_head list;
++};
++
++#define to_buf_list(vb2_buffer) (&container_of(vb2_buffer, \
++ struct rcar_vin_buffer, \
++ vb)->list)
++
++struct rcar_vin_cam {
++ /* VIN offsets within the camera output, before the VIN scaler */
++ unsigned int vin_left;
++ unsigned int vin_top;
++ /* Client output, as seen by the VIN */
++ unsigned int width;
++ unsigned int height;
++ /* User window from S_FMT */
++ unsigned int out_width;
++ unsigned int out_height;
++ /*
++ * User window from S_SELECTION / G_SELECTION, produced by client cropping and
++ * scaling, VIN scaling and VIN cropping, mapped back onto the client
++ * input window
++ */
++ struct v4l2_rect subrect;
++ /* Camera cropping rectangle */
++ struct v4l2_rect rect;
++ const struct soc_mbus_pixelfmt *extra_fmt;
++};
++
++#define VIN_UT_IRQ 0x01
++
++static unsigned int vin_debug;
++module_param_named(debug, vin_debug, int, 0600);
++static int overflow_video[RCAR_VIDEO_MAX];
++module_param_array(overflow_video, int, NULL, 0600);
++
++#ifdef CONFIG_VIDEO_RCAR_VIN_LEGACY_DEBUG
++#define VIN_IRQ_DEBUG(fmt, args...) \
++ do { \
++ if (unlikely(vin_debug & VIN_UT_IRQ)) \
++ vin_ut_debug_printk(__func__, fmt, ##args); \
++ } while (0)
++#else
++#define VIN_IRQ_DEBUG(fmt, args...)
++#endif
++
++void vin_ut_debug_printk(const char *function_name, const char *format, ...)
++{
++ struct va_format vaf;
++ va_list args;
++
++ va_start(args, format);
++ vaf.fmt = format;
++ vaf.va = &args;
++
++ pr_debug("[" DRV_NAME ":%s] %pV", function_name, &vaf);
++
++ va_end(args);
++}
++
++static void rcar_vin_cpg_enable_for_ifmd(unsigned int ch, bool enable)
++{
++ void __iomem *smstpcr8;
++
++ smstpcr8 = ioremap(0xE6150990, 0x04);
++
++ if (enable) {
++ if (ch < RCAR_VIDEO_4)
++ iowrite32((ioread32(smstpcr8) & 0xFFFFF7FF), smstpcr8);
++ else
++ iowrite32((ioread32(smstpcr8) & 0xFFFFFF7F), smstpcr8);
++ } else {
++ if (ch < RCAR_VIDEO_4)
++ iowrite32((ioread32(smstpcr8) | 0x00000800), smstpcr8);
++ else
++ iowrite32((ioread32(smstpcr8) | 0x00000080), smstpcr8);
++ }
++
++ iounmap(smstpcr8);
++}
++
++static inline int is_scaling(struct rcar_vin_cam *cam)
++{
++ struct v4l2_rect *cam_subrect = &cam->subrect;
++
++ if ((cam_subrect->width != cam->out_width) ||
++ (cam_subrect->height != cam->out_height))
++ return 1;
++
++ return 0;
++}
++
++/*
++ * .queue_setup() is called to check whether the driver can accept the requested
++ * number of buffers and to fill in plane sizes for the current frame format if
++ * required
++ */
++static int rcar_vin_videobuf_setup(struct vb2_queue *vq,
++ unsigned int *count,
++ unsigned int *num_planes,
++ unsigned int sizes[], struct device *alloc_devs[])
++{
++ struct soc_camera_device *icd = soc_camera_from_vb2q(vq);
++ struct soc_camera_host *ici = to_soc_camera_host(icd->parent);
++ struct rcar_vin_priv *priv = ici->priv;
++ struct rcar_vin_cam *cam = icd->host_priv;
++
++ if (priv->chip == RCAR_H3 || priv->chip == RCAR_M3) {
++ if ((priv->ratio_h > 0x10000) || (priv->ratio_v > 0x10000)) {
++ dev_err(icd->parent, "Scaling rate parameter error\n");
++ return -EINVAL;
++ }
++ if (is_scaling(cam) && (cam->out_width % 32)) {
++ dev_err(icd->parent, "Scaling parameter error\n");
++ return -EINVAL;
++ }
++ if (!is_scaling(cam) && (cam->out_width % 16)) {
++ dev_err(icd->parent, "Image stride parameter error\n");
++ return -EINVAL;
++ }
++ }
++
++ if (!vq->num_buffers)
++ priv->sequence = 0;
++
++ if (!*count)
++ *count = 2;
++ priv->vb_count = *count;
++
++ /* Number of hardware slots */
++ if (is_continuous_transfer(priv))
++ priv->nr_hw_slots = MAX_BUFFER_NUM;
++ else
++ priv->nr_hw_slots = 1;
++
++ if (*num_planes)
++ return sizes[0] < icd->sizeimage ? -EINVAL : 0;
++
++ sizes[0] = icd->sizeimage;
++ *num_planes = 1;
++
++ dev_dbg(icd->parent, "count=%d, size=%u\n", *count, sizes[0]);
++
++ return 0;
++}
++
++static int rcar_vin_setup(struct rcar_vin_priv *priv)
++{
++ struct soc_camera_device *icd = priv->ici.icd;
++ struct rcar_vin_cam *cam = icd->host_priv;
++ u32 vnmc, dmr, interrupts;
++ bool progressive = false, output_is_yuv = false, input_is_yuv = false;
++
++ switch (priv->field) {
++ case V4L2_FIELD_TOP:
++ vnmc = VNMC_IM_ODD;
++ break;
++ case V4L2_FIELD_BOTTOM:
++ vnmc = VNMC_IM_EVEN;
++ break;
++ case V4L2_FIELD_INTERLACED:
++ case V4L2_FIELD_INTERLACED_TB:
++ vnmc = VNMC_IM_FULL;
++ break;
++ case V4L2_FIELD_INTERLACED_BT:
++ vnmc = VNMC_IM_FULL | VNMC_FOC;
++ break;
++ case V4L2_FIELD_NONE:
++ if (is_continuous_transfer(priv)) {
++ vnmc = VNMC_IM_ODD_EVEN;
++ progressive = true;
++ } else {
++ vnmc = VNMC_IM_ODD;
++ }
++ break;
++ default:
++ vnmc = VNMC_IM_ODD;
++ break;
++ }
++
++ /* input interface */
++ switch (icd->current_fmt->code) {
++ case MEDIA_BUS_FMT_YUYV8_1X16:
++ /* BT.601/BT.1358 16bit YCbCr422 */
++ vnmc |= VNMC_INF_YUV16;
++ input_is_yuv = true;
++ break;
++ case MEDIA_BUS_FMT_YUYV8_2X8:
++ /* BT.656 8bit YCbCr422 or BT.601 8bit YCbCr422 */
++ vnmc |= priv->pdata_flags & RCAR_VIN_BT656 ?
++ VNMC_INF_YUV8_BT656 : VNMC_INF_YUV8_BT601;
++ input_is_yuv = true;
++ break;
++ case MEDIA_BUS_FMT_RGB888_1X24:
++ vnmc |= VNMC_INF_RGB888;
++ break;
++ case MEDIA_BUS_FMT_YUYV10_2X10:
++ /* BT.656 10bit YCbCr422 or BT.601 10bit YCbCr422 */
++ vnmc |= priv->pdata_flags & RCAR_VIN_BT656 ?
++ VNMC_INF_YUV10_BT656 : VNMC_INF_YUV10_BT601;
++ input_is_yuv = true;
++ break;
++ default:
++ break;
++ }
++
++ /* output format */
++ switch (icd->current_fmt->host_fmt->fourcc) {
++ case V4L2_PIX_FMT_NV12:
++ if (priv->chip == RCAR_H3 || priv->chip == RCAR_M3) {
++ iowrite32(ALIGN((cam->out_width * cam->out_height),
++ 0x80), priv->base + VNUVAOF_REG);
++ dmr = VNDMR_DTMD_YCSEP_YCBCR420;
++ output_is_yuv = true;
++ } else {
++ dev_warn(icd->parent, "Not support format\n");
++ return -EINVAL;
++ }
++ break;
++ case V4L2_PIX_FMT_NV16:
++ iowrite32(ALIGN((cam->out_width * cam->out_height), 0x80),
++ priv->base + VNUVAOF_REG);
++ dmr = VNDMR_DTMD_YCSEP;
++ output_is_yuv = true;
++ break;
++ case V4L2_PIX_FMT_YUYV:
++ dmr = VNDMR_BPSM;
++ output_is_yuv = true;
++ break;
++ case V4L2_PIX_FMT_UYVY:
++ dmr = 0;
++ output_is_yuv = true;
++ break;
++ case V4L2_PIX_FMT_ARGB555:
++ dmr = VNDMR_DTMD_ARGB;
++ break;
++ case V4L2_PIX_FMT_RGB565:
++ dmr = 0;
++ break;
++ case V4L2_PIX_FMT_XBGR32:
++ if (priv->chip != RCAR_H3 && priv->chip != RCAR_M3 &&
++ priv->chip != RCAR_GEN2 && priv->chip != RCAR_H1 &&
++ priv->chip != RCAR_E1)
++ goto e_format;
++
++ dmr = VNDMR_EXRGB;
++ break;
++ case V4L2_PIX_FMT_ABGR32:
++ if (priv->chip != RCAR_H3 && priv->chip != RCAR_M3)
++ goto e_format;
++
++ dmr = VNDMR_EXRGB | VNDMR_DTMD_ARGB;
++ break;
++ default:
++ goto e_format;
++ }
++
++ /* Always update on field change */
++ vnmc |= VNMC_VUP;
++
++ /* If input and output use the same colorspace, use bypass mode */
++ if (input_is_yuv == output_is_yuv)
++ vnmc |= VNMC_BPS;
++
++ if (priv->chip == RCAR_H3 || priv->chip == RCAR_M3) {
++ if (priv->pdata_flags & RCAR_VIN_CSI2)
++ vnmc &= ~VNMC_DPINE;
++ else
++ vnmc |= VNMC_DPINE;
++
++ if ((icd->current_fmt->host_fmt->fourcc != V4L2_PIX_FMT_NV12)
++ && is_scaling(cam))
++ vnmc |= VNMC_SCLE;
++ }
++
++ /* progressive or interlaced mode */
++ interrupts = progressive ? VNIE_FIE : VNIE_EFE;
++
++ /* Enable Overflow */
++ if (vin_debug)
++ interrupts |= VNIE_FOE;
++
++ /* ack interrupts */
++ iowrite32(interrupts, priv->base + VNINTS_REG);
++ /* enable interrupts */
++ iowrite32(interrupts, priv->base + VNIE_REG);
++ /* start capturing */
++ iowrite32(dmr, priv->base + VNDMR_REG);
++ iowrite32(vnmc | VNMC_ME, priv->base + VNMC_REG);
++
++ return 0;
++
++e_format:
++ dev_warn(icd->parent, "Invalid fourcc format (0x%x)\n",
++ icd->current_fmt->host_fmt->fourcc);
++ return -EINVAL;
++}
++
++static void rcar_vin_capture(struct rcar_vin_priv *priv)
++{
++ if (is_continuous_transfer(priv))
++ /* Continuous Frame Capture Mode */
++ iowrite32(VNFC_C_FRAME, priv->base + VNFC_REG);
++ else
++ /* Single Frame Capture Mode */
++ iowrite32(VNFC_S_FRAME, priv->base + VNFC_REG);
++}
++
++static void rcar_vin_request_capture_stop(struct rcar_vin_priv *priv)
++{
++ priv->state = STOPPING;
++
++ /* set continuous & single transfer off */
++ iowrite32(0, priv->base + VNFC_REG);
++ /* disable capture (release DMA buffer), reset */
++ iowrite32(ioread32(priv->base + VNMC_REG) & ~VNMC_ME,
++ priv->base + VNMC_REG);
++
++ /* update the status if stopped already */
++ if (!(ioread32(priv->base + VNMS_REG) & VNMS_CA))
++ priv->state = STOPPED;
++}
++
++static int rcar_vin_get_free_hw_slot(struct rcar_vin_priv *priv)
++{
++ int slot;
++
++ for (slot = 0; slot < priv->nr_hw_slots; slot++)
++ if (priv->queue_buf[slot] == NULL)
++ return slot;
++
++ return -1;
++}
++
++static int rcar_vin_hw_ready(struct rcar_vin_priv *priv)
++{
++ /* Ensure all HW slots are filled */
++ return rcar_vin_get_free_hw_slot(priv) < 0 ? 1 : 0;
++}
++
++/* Moves a buffer from the queue to the HW slots */
++static int rcar_vin_fill_hw_slot(struct rcar_vin_priv *priv)
++{
++ struct vb2_v4l2_buffer *vbuf;
++ dma_addr_t phys_addr_top;
++ int slot;
++
++ if (list_empty(&priv->capture))
++ return 0;
++
++ /* Find a free HW slot */
++ slot = rcar_vin_get_free_hw_slot(priv);
++ if (slot < 0)
++ return 0;
++
++ vbuf = &list_entry(priv->capture.next,
++ struct rcar_vin_buffer, list)->vb;
++ list_del_init(to_buf_list(vbuf));
++ priv->queue_buf[slot] = vbuf;
++ phys_addr_top = vb2_dma_contig_plane_dma_addr(&vbuf->vb2_buf, 0);
++ iowrite32(phys_addr_top, priv->base + VNMB_REG(slot));
++
++ return 1;
++}
++
++static void rcar_vin_videobuf_queue(struct vb2_buffer *vb)
++{
++ struct vb2_v4l2_buffer *vbuf = to_vb2_v4l2_buffer(vb);
++ struct soc_camera_device *icd = soc_camera_from_vb2q(vb->vb2_queue);
++ struct soc_camera_host *ici = to_soc_camera_host(icd->parent);
++ struct rcar_vin_priv *priv = ici->priv;
++ unsigned long size;
++
++ size = icd->sizeimage;
++
++ if (vb2_plane_size(vb, 0) < size) {
++ dev_err(icd->parent, "Buffer #%d too small (%lu < %lu)\n",
++ vb->index, vb2_plane_size(vb, 0), size);
++ goto error;
++ }
++
++ vb2_set_plane_payload(vb, 0, size);
++
++ dev_dbg(icd->parent, "%s (vb=0x%p) 0x%p %lu\n", __func__,
++ vb, vb2_plane_vaddr(vb, 0), vb2_get_plane_payload(vb, 0));
++
++ spin_lock_irq(&priv->lock);
++
++ list_add_tail(to_buf_list(vbuf), &priv->capture);
++ rcar_vin_fill_hw_slot(priv);
++
++ /* If we weren't running, and have enough buffers, start capturing! */
++ if (priv->state != RUNNING && rcar_vin_hw_ready(priv)) {
++ if (rcar_vin_setup(priv)) {
++ /* Submit error */
++ list_del_init(to_buf_list(vbuf));
++ spin_unlock_irq(&priv->lock);
++ goto error;
++ }
++ priv->request_to_stop = false;
++ init_completion(&priv->capture_stop);
++ priv->state = RUNNING;
++ rcar_vin_capture(priv);
++ }
++
++ spin_unlock_irq(&priv->lock);
++
++ return;
++
++error:
++ vb2_buffer_done(vb, VB2_BUF_STATE_ERROR);
++}
++
++/*
++ * Wait for capture to stop and all in-flight buffers to be finished with by
++ * the video hardware. This must be called under &priv->lock
++ *
++ */
++static void rcar_vin_wait_stop_streaming(struct rcar_vin_priv *priv)
++{
++ while (priv->state != STOPPED) {
++ /* issue stop if running */
++ if (priv->state == RUNNING)
++ rcar_vin_request_capture_stop(priv);
++
++ /* wait until capturing has been stopped */
++ if (priv->state == STOPPING) {
++ priv->request_to_stop = true;
++ spin_unlock_irq(&priv->lock);
++ if (!wait_for_completion_timeout(
++ &priv->capture_stop,
++ msecs_to_jiffies(TIMEOUT_MS)))
++ priv->state = STOPPED;
++ spin_lock_irq(&priv->lock);
++ }
++ }
++}
++
++static void rcar_vin_stop_streaming(struct vb2_queue *vq)
++{
++ struct soc_camera_device *icd = soc_camera_from_vb2q(vq);
++ struct soc_camera_host *ici = to_soc_camera_host(icd->parent);
++ struct rcar_vin_priv *priv = ici->priv;
++ struct list_head *buf_head, *tmp;
++ int i;
++
++ spin_lock_irq(&priv->lock);
++ rcar_vin_wait_stop_streaming(priv);
++
++ for (i = 0; i < MAX_BUFFER_NUM; i++) {
++ if (priv->queue_buf[i]) {
++ vb2_buffer_done(&priv->queue_buf[i]->vb2_buf,
++ VB2_BUF_STATE_ERROR);
++ priv->queue_buf[i] = NULL;
++ }
++ }
++
++ list_for_each_safe(buf_head, tmp, &priv->capture) {
++ vb2_buffer_done(&list_entry(buf_head,
++ struct rcar_vin_buffer, list)->vb.vb2_buf,
++ VB2_BUF_STATE_ERROR);
++ list_del_init(buf_head);
++ }
++ spin_unlock_irq(&priv->lock);
++}
++
++static const struct vb2_ops rcar_vin_vb2_ops = {
++ .queue_setup = rcar_vin_videobuf_setup,
++ .buf_queue = rcar_vin_videobuf_queue,
++ .stop_streaming = rcar_vin_stop_streaming,
++ .wait_prepare = vb2_ops_wait_prepare,
++ .wait_finish = vb2_ops_wait_finish,
++};
++
++static irqreturn_t rcar_vin_irq(int irq, void *data)
++{
++ struct rcar_vin_priv *priv = data;
++ u32 int_status;
++ bool can_run = false, hw_stopped;
++ int slot;
++ unsigned int handled = 0;
++ int vin_ovr_cnt = 0;
++
++ spin_lock(&priv->lock);
++
++ int_status = ioread32(priv->base + VNINTS_REG);
++ if (!int_status)
++ goto done;
++
++ /* ack interrupts */
++ iowrite32(int_status, priv->base + VNINTS_REG);
++ handled = 1;
++
++ /* overflow occurs */
++ if (vin_debug && (int_status & VNINTS_FOS)) {
++ vin_ovr_cnt = ++overflow_video[priv->index];
++ VIN_IRQ_DEBUG("overflow occurrs num[%d] at VIN (%s)\n",
++ vin_ovr_cnt, dev_name(priv->ici.v4l2_dev.dev));
++ }
++
++ /* nothing to do if capture status is 'STOPPED' */
++ if (priv->state == STOPPED)
++ goto done;
++
++ hw_stopped = !(ioread32(priv->base + VNMS_REG) & VNMS_CA);
++
++ if (!priv->request_to_stop) {
++ if (is_continuous_transfer(priv))
++ slot = (ioread32(priv->base + VNMS_REG) &
++ VNMS_FBS_MASK) >> VNMS_FBS_SHIFT;
++ else
++ slot = 0;
++
++ if (!is_continuous_transfer(priv) || ((priv->state == RUNNING)
++ && !list_empty(&priv->capture))) {
++ priv->queue_buf[slot]->field = priv->field;
++ priv->queue_buf[slot]->sequence = priv->sequence++;
++ priv->queue_buf[slot]->vb2_buf.timestamp =
++ ktime_get_ns();
++ vb2_buffer_done(&priv->queue_buf[slot]->vb2_buf,
++ VB2_BUF_STATE_DONE);
++ priv->queue_buf[slot] = NULL;
++
++ can_run = rcar_vin_fill_hw_slot(priv);
++ }
++
++ if (is_continuous_transfer(priv)) {
++ if (hw_stopped)
++ priv->state = STOPPED;
++ else if (list_empty(&priv->capture) &&
++ priv->state == RUNNING)
++ /*
++ * The continuous capturing requires an
++ * explicit stop operation when there is no
++ * buffer to be set into the VnMBm registers.
++ */
++ rcar_vin_request_capture_stop(priv);
++ } else {
++ if (can_run)
++ rcar_vin_capture(priv);
++ else
++ priv->state = STOPPED;
++ }
++ } else if (hw_stopped) {
++ priv->state = STOPPED;
++ priv->request_to_stop = false;
++ complete(&priv->capture_stop);
++ }
++
++done:
++ spin_unlock(&priv->lock);
++
++ return IRQ_RETVAL(handled);
++}
++
++static struct v4l2_subdev *find_csi2(struct rcar_vin_priv *pcdev)
++{
++ struct v4l2_subdev *sd;
++ char name[] = "rcar_csi2";
++
++ v4l2_device_for_each_subdev(sd, &pcdev->ici.v4l2_dev) {
++ if (!strncmp(name, sd->name, sizeof(name) - 1)) {
++ pcdev->csi2_sd = sd;
++ return sd;
++ }
++ }
++
++ return NULL;
++}
++
++static int rcar_vin_add_device(struct soc_camera_device *icd)
++{
++ struct soc_camera_host *ici = to_soc_camera_host(icd->parent);
++ struct rcar_vin_priv *priv = ici->priv;
++ int i;
++
++ for (i = 0; i < MAX_BUFFER_NUM; i++)
++ priv->queue_buf[i] = NULL;
++
++ pm_runtime_get_sync(ici->v4l2_dev.dev);
++
++ if (priv->chip == RCAR_H3 || priv->chip == RCAR_M3) {
++ struct v4l2_subdev *csi2_sd = find_csi2(priv);
++ int ret;
++
++ if (csi2_sd) {
++ csi2_sd->grp_id = soc_camera_grp_id(icd);
++ v4l2_set_subdev_hostdata(csi2_sd, icd);
++
++ ret = v4l2_subdev_call(csi2_sd, core, s_power, 1);
++ priv->csi_sync = true;
++
++ if (ret < 0 && ret != -EINVAL)
++ priv->csi_sync = false;
++
++ if (ret < 0 && ret != -ENOIOCTLCMD && ret != -ENODEV)
++ return ret;
++ }
++ /*
++ * -ENODEV is special:
++ * either csi2_sd == NULL or the CSI-2 driver
++ * has not found this soc-camera device among its clients
++ */
++ if (csi2_sd && ret == -ENODEV)
++ csi2_sd->grp_id = 0;
++
++ dev_dbg(icd->parent,
++ "R-Car VIN/CSI-2 driver attached to camera %d\n",
++ icd->devnum);
++
++ } else
++ dev_dbg(icd->parent, "R-Car VIN driver attached to camera %d\n",
++ icd->devnum);
++
++ priv->error_flag = false;
++
++ return 0;
++}
++
++static void rcar_vin_remove_device(struct soc_camera_device *icd)
++{
++ struct soc_camera_host *ici = to_soc_camera_host(icd->parent);
++ struct rcar_vin_priv *priv = ici->priv;
++ struct vb2_v4l2_buffer *vbuf;
++ struct v4l2_subdev *csi2_sd = find_csi2(priv);
++ int i;
++
++ /* disable capture, disable interrupts */
++ iowrite32(ioread32(priv->base + VNMC_REG) & ~VNMC_ME,
++ priv->base + VNMC_REG);
++ iowrite32(0, priv->base + VNIE_REG);
++
++ priv->state = STOPPED;
++ priv->request_to_stop = false;
++ priv->error_flag = false;
++
++ /* make sure active buffer is cancelled */
++ spin_lock_irq(&priv->lock);
++ for (i = 0; i < MAX_BUFFER_NUM; i++) {
++ vbuf = priv->queue_buf[i];
++ if (vbuf) {
++ list_del_init(to_buf_list(vbuf));
++ vb2_buffer_done(&vbuf->vb2_buf, VB2_BUF_STATE_ERROR);
++ }
++ }
++ spin_unlock_irq(&priv->lock);
++
++ pm_runtime_put(ici->v4l2_dev.dev);
++
++ if ((csi2_sd) && (priv->csi_sync))
++ v4l2_subdev_call(csi2_sd, core, s_power, 0);
++
++ dev_dbg(icd->parent, "R-Car VIN driver detached from camera %d\n",
++ icd->devnum);
++}
++
++struct rcar_vin_uds_regs {
++ unsigned long ctrl;
++ unsigned long scale;
++ unsigned long pass_bwidth;
++ unsigned long clip_size;
++};
++
++static unsigned long rcar_vin_get_bwidth(unsigned long ratio)
++{
++ unsigned long bwidth;
++ unsigned long mant, frac;
++
++ mant = (ratio & 0xF000) >> 12;
++ frac = ratio & 0x0FFF;
++ if (mant)
++ bwidth = 64 * 4096 * mant / (4096 * mant + frac);
++ else
++ bwidth = 64;
++
++ return bwidth;
++}
++
++static unsigned long rcar_vin_compute_ratio(unsigned int input,
++ unsigned int output)
++{
++ return ((input * 4096 / output) == 0x10000) ?
++ 0xFFFF : (input * 4096 / output);
++}
++
++int rcar_vin_uds_set(struct rcar_vin_priv *priv, struct rcar_vin_cam *cam)
++{
++ struct rcar_vin_uds_regs regs;
++ unsigned long ratio_h, ratio_v;
++ unsigned long bwidth_h, bwidth_v;
++ unsigned long ctrl;
++ unsigned long clip_size;
++ struct v4l2_rect *cam_subrect = &cam->subrect;
++ u32 vnmc;
++
++ ratio_h = rcar_vin_compute_ratio(cam_subrect->width, cam->out_width);
++ ratio_v = rcar_vin_compute_ratio(cam_subrect->height, cam->out_height);
++
++ priv->ratio_h = ratio_h;
++ priv->ratio_v = ratio_v;
++
++ bwidth_h = rcar_vin_get_bwidth(ratio_h);
++ bwidth_v = rcar_vin_get_bwidth(ratio_v);
++
++ ctrl = VNUDS_CTRL_AMD;
++
++ if (priv->field == V4L2_FIELD_NONE)
++ clip_size = (cam->out_width << 16) | (cam->out_height);
++ else
++ clip_size = (cam->out_width << 16) | (cam->out_height / 2);
++
++ regs.ctrl = ctrl;
++ regs.scale = (ratio_h << 16) | ratio_v;
++ regs.pass_bwidth = (bwidth_h << 16) | bwidth_v;
++ regs.clip_size = clip_size;
++
++ vnmc = ioread32(priv->base + VNMC_REG);
++ iowrite32(vnmc | VNMC_SCLE, priv->base + VNMC_REG);
++ iowrite32(regs.ctrl, priv->base + VNUDS_CTRL_REG);
++ iowrite32(regs.scale, priv->base + VNUDS_SCALE_REG);
++ iowrite32(regs.pass_bwidth, priv->base + VNUDS_PASS_BWIDTH_REG);
++ iowrite32(regs.clip_size, priv->base + VNUDS_CLIP_SIZE_REG);
++
++ return 0;
++}
++
++static void set_coeff(struct rcar_vin_priv *priv, unsigned short xs)
++{
++ int i;
++ const struct vin_coeff *p_prev_set = NULL;
++ const struct vin_coeff *p_set = NULL;
++
++ /* Look for suitable coefficient values */
++ for (i = 0; i < ARRAY_SIZE(vin_coeff_set); i++) {
++ p_prev_set = p_set;
++ p_set = &vin_coeff_set[i];
++
++ if (xs < p_set->xs_value)
++ break;
++ }
++
++ /* Use previous value if its XS value is closer */
++ if (p_prev_set && p_set &&
++ xs - p_prev_set->xs_value < p_set->xs_value - xs)
++ p_set = p_prev_set;
++
++ /* Set coefficient registers */
++ iowrite32(p_set->coeff_set[0], priv->base + VNC1A_REG);
++ iowrite32(p_set->coeff_set[1], priv->base + VNC1B_REG);
++ iowrite32(p_set->coeff_set[2], priv->base + VNC1C_REG);
++
++ iowrite32(p_set->coeff_set[3], priv->base + VNC2A_REG);
++ iowrite32(p_set->coeff_set[4], priv->base + VNC2B_REG);
++ iowrite32(p_set->coeff_set[5], priv->base + VNC2C_REG);
++
++ iowrite32(p_set->coeff_set[6], priv->base + VNC3A_REG);
++ iowrite32(p_set->coeff_set[7], priv->base + VNC3B_REG);
++ iowrite32(p_set->coeff_set[8], priv->base + VNC3C_REG);
++
++ iowrite32(p_set->coeff_set[9], priv->base + VNC4A_REG);
++ iowrite32(p_set->coeff_set[10], priv->base + VNC4B_REG);
++ iowrite32(p_set->coeff_set[11], priv->base + VNC4C_REG);
++
++ iowrite32(p_set->coeff_set[12], priv->base + VNC5A_REG);
++ iowrite32(p_set->coeff_set[13], priv->base + VNC5B_REG);
++ iowrite32(p_set->coeff_set[14], priv->base + VNC5C_REG);
++
++ iowrite32(p_set->coeff_set[15], priv->base + VNC6A_REG);
++ iowrite32(p_set->coeff_set[16], priv->base + VNC6B_REG);
++ iowrite32(p_set->coeff_set[17], priv->base + VNC6C_REG);
++
++ iowrite32(p_set->coeff_set[18], priv->base + VNC7A_REG);
++ iowrite32(p_set->coeff_set[19], priv->base + VNC7B_REG);
++ iowrite32(p_set->coeff_set[20], priv->base + VNC7C_REG);
++
++ iowrite32(p_set->coeff_set[21], priv->base + VNC8A_REG);
++ iowrite32(p_set->coeff_set[22], priv->base + VNC8B_REG);
++ iowrite32(p_set->coeff_set[23], priv->base + VNC8C_REG);
++}
++
++/* rect is guaranteed to not exceed the scaled camera rectangle */
++static int rcar_vin_set_rect(struct soc_camera_device *icd)
++{
++ struct soc_camera_host *ici = to_soc_camera_host(icd->parent);
++ struct rcar_vin_cam *cam = icd->host_priv;
++ struct rcar_vin_priv *priv = ici->priv;
++ unsigned int left_offset, top_offset;
++ unsigned char dsize = 0;
++ struct v4l2_rect *cam_subrect = &cam->subrect;
++ u32 value;
++ int ret = 0;
++
++ dev_dbg(icd->parent, "Crop %ux%u@%u:%u\n",
++ icd->user_width, icd->user_height, cam->vin_left, cam->vin_top);
++
++ left_offset = cam->vin_left;
++ top_offset = cam->vin_top;
++
++ if (icd->current_fmt->host_fmt->fourcc == V4L2_PIX_FMT_XBGR32 &&
++ priv->chip == RCAR_E1)
++ dsize = 1;
++
++ dev_dbg(icd->parent, "Cam %ux%u@%u:%u\n",
++ cam->width, cam->height, cam->vin_left, cam->vin_top);
++ dev_dbg(icd->parent, "Cam subrect %ux%u@%u:%u\n",
++ cam_subrect->width, cam_subrect->height,
++ cam_subrect->left, cam_subrect->top);
++
++ /* Set Start/End Pixel/Line Pre-Clip */
++ iowrite32(left_offset << dsize, priv->base + VNSPPRC_REG);
++ iowrite32((left_offset + cam_subrect->width - 1) << dsize,
++ priv->base + VNEPPRC_REG);
++ switch (priv->field) {
++ case V4L2_FIELD_INTERLACED:
++ case V4L2_FIELD_INTERLACED_TB:
++ case V4L2_FIELD_INTERLACED_BT:
++ iowrite32(top_offset / 2, priv->base + VNSLPRC_REG);
++ iowrite32((top_offset + cam_subrect->height) / 2 - 1,
++ priv->base + VNELPRC_REG);
++ break;
++ default:
++ iowrite32(top_offset, priv->base + VNSLPRC_REG);
++ iowrite32(top_offset + cam_subrect->height - 1,
++ priv->base + VNELPRC_REG);
++ break;
++ }
++
++ if (priv->chip == RCAR_H3 || priv->chip == RCAR_M3) {
++ if ((icd->current_fmt->host_fmt->fourcc != V4L2_PIX_FMT_NV12)
++ && is_scaling(cam)) {
++ ret = rcar_vin_uds_set(priv, cam);
++ if (ret < 0)
++ return ret;
++ }
++ if (is_scaling(cam) ||
++ (icd->current_fmt->host_fmt->fourcc == V4L2_PIX_FMT_NV16) ||
++ (icd->current_fmt->host_fmt->fourcc == V4L2_PIX_FMT_NV12))
++ iowrite32(ALIGN(cam->out_width, 0x20),
++ priv->base + VNIS_REG);
++ else
++ iowrite32(ALIGN(cam->out_width, 0x10),
++ priv->base + VNIS_REG);
++ } else {
++ /* Set scaling coefficient */
++ value = 0;
++ if (cam_subrect->height != cam->out_height)
++ value = (4096 * cam_subrect->height) / cam->out_height;
++ dev_dbg(icd->parent, "YS Value: %x\n", value);
++ iowrite32(value, priv->base + VNYS_REG);
++
++ value = 0;
++ if (cam_subrect->width != cam->out_width)
++ value = (4096 * cam_subrect->width) / cam->out_width;
++
++ /* Horizontal upscaling is up to double size */
++ if (value < 2048)
++ value = 2048;
++
++ dev_dbg(icd->parent, "XS Value: %x\n", value);
++ iowrite32(value, priv->base + VNXS_REG);
++
++ /* Horizontal upscaling is carried out */
++ /* by scaling down from double size */
++ if (value < 4096)
++ value *= 2;
++
++ set_coeff(priv, value);
++
++ /* Set Start/End Pixel/Line Post-Clip */
++ iowrite32(0, priv->base + VNSPPOC_REG);
++ iowrite32(0, priv->base + VNSLPOC_REG);
++ iowrite32((cam->out_width - 1) << dsize,
++ priv->base + VNEPPOC_REG);
++ switch (priv->field) {
++ case V4L2_FIELD_INTERLACED:
++ case V4L2_FIELD_INTERLACED_TB:
++ case V4L2_FIELD_INTERLACED_BT:
++ iowrite32(cam->out_height / 2 - 1,
++ priv->base + VNELPOC_REG);
++ break;
++ default:
++ iowrite32(cam->out_height - 1,
++ priv->base + VNELPOC_REG);
++ break;
++ }
++
++ iowrite32(ALIGN(cam->out_width, 0x10), priv->base + VNIS_REG);
++ }
++
++ return ret;
++}
++
++static void capture_stop_preserve(struct rcar_vin_priv *priv, u32 *vnmc)
++{
++ *vnmc = ioread32(priv->base + VNMC_REG);
++ /* module disable */
++ iowrite32(*vnmc & ~VNMC_ME, priv->base + VNMC_REG);
++}
++
++static void capture_restore(struct rcar_vin_priv *priv, u32 vnmc)
++{
++ unsigned long timeout = jiffies + 10 * HZ;
++
++ /*
++ * Wait until the end of the current frame. It can take a long time,
++ * but if it has been aborted by a MRST1 reset, it should exit sooner.
++ */
++ while ((ioread32(priv->base + VNMS_REG) & VNMS_AV) &&
++ time_before(jiffies, timeout))
++ msleep(1);
++
++ if (time_after(jiffies, timeout)) {
++ dev_err(priv->ici.v4l2_dev.dev,
++ "Timeout waiting for frame end! Interface problem?\n");
++ return;
++ }
++
++ iowrite32(vnmc, priv->base + VNMC_REG);
++}
++
++#define VIN_MBUS_FLAGS (V4L2_MBUS_MASTER | \
++ V4L2_MBUS_PCLK_SAMPLE_RISING | \
++ V4L2_MBUS_HSYNC_ACTIVE_HIGH | \
++ V4L2_MBUS_HSYNC_ACTIVE_LOW | \
++ V4L2_MBUS_VSYNC_ACTIVE_HIGH | \
++ V4L2_MBUS_VSYNC_ACTIVE_LOW | \
++ V4L2_MBUS_DATA_ACTIVE_HIGH)
++
++static int rcar_vin_set_bus_param(struct soc_camera_device *icd)
++{
++ struct soc_camera_host *ici = to_soc_camera_host(icd->parent);
++ struct rcar_vin_priv *priv = ici->priv;
++ struct v4l2_subdev *sd = soc_camera_to_subdev(icd);
++ struct v4l2_mbus_config cfg;
++ unsigned long common_flags;
++ u32 vnmc;
++ u32 val;
++ int ret;
++
++ capture_stop_preserve(priv, &vnmc);
++
++ ret = v4l2_subdev_call(sd, video, g_mbus_config, &cfg);
++ if (!ret) {
++ common_flags = soc_mbus_config_compatible(&cfg, VIN_MBUS_FLAGS);
++ if (!common_flags) {
++ dev_warn(icd->parent,
++ "MBUS flags incompatible: camera 0x%x, host 0x%x\n",
++ cfg.flags, VIN_MBUS_FLAGS);
++ return -EINVAL;
++ }
++ } else if (ret != -ENOIOCTLCMD) {
++ return ret;
++ } else {
++ common_flags = VIN_MBUS_FLAGS;
++ }
++
++ /* Make choises, based on platform preferences */
++ if ((common_flags & V4L2_MBUS_HSYNC_ACTIVE_HIGH) &&
++ (common_flags & V4L2_MBUS_HSYNC_ACTIVE_LOW)) {
++ if (priv->pdata_flags & RCAR_VIN_HSYNC_ACTIVE_LOW)
++ common_flags &= ~V4L2_MBUS_HSYNC_ACTIVE_HIGH;
++ else
++ common_flags &= ~V4L2_MBUS_HSYNC_ACTIVE_LOW;
++ }
++
++ if ((common_flags & V4L2_MBUS_VSYNC_ACTIVE_HIGH) &&
++ (common_flags & V4L2_MBUS_VSYNC_ACTIVE_LOW)) {
++ if (priv->pdata_flags & RCAR_VIN_VSYNC_ACTIVE_LOW)
++ common_flags &= ~V4L2_MBUS_VSYNC_ACTIVE_HIGH;
++ else
++ common_flags &= ~V4L2_MBUS_VSYNC_ACTIVE_LOW;
++ }
++
++ cfg.flags = common_flags;
++ ret = v4l2_subdev_call(sd, video, s_mbus_config, &cfg);
++ if (ret < 0 && ret != -ENOIOCTLCMD)
++ return ret;
++
++ if (priv->chip == RCAR_H3 || priv->chip == RCAR_M3) {
++ if (cfg.type == V4L2_MBUS_CSI2)
++ vnmc &= ~VNMC_DPINE;
++ else
++ vnmc |= VNMC_DPINE;
++ }
++
++ if (priv->chip == RCAR_H3 || priv->chip == RCAR_M3)
++ val = VNDMR2_FTEV;
++ else
++ val = VNDMR2_FTEV | VNDMR2_VLV(1);
++ if (!(common_flags & V4L2_MBUS_VSYNC_ACTIVE_LOW))
++ val |= VNDMR2_VPS;
++ if (!(common_flags & V4L2_MBUS_HSYNC_ACTIVE_LOW))
++ val |= VNDMR2_HPS;
++ iowrite32(val, priv->base + VNDMR2_REG);
++
++ ret = rcar_vin_set_rect(icd);
++ if (ret < 0)
++ return ret;
++
++ capture_restore(priv, vnmc);
++
++ return 0;
++}
++
++static int rcar_vin_try_bus_param(struct soc_camera_device *icd,
++ unsigned char buswidth)
++{
++ struct v4l2_subdev *sd = soc_camera_to_subdev(icd);
++ struct v4l2_mbus_config cfg;
++ int ret;
++
++ ret = v4l2_subdev_call(sd, video, g_mbus_config, &cfg);
++ if (ret == -ENOIOCTLCMD)
++ return 0;
++ else if (ret)
++ return ret;
++
++ if (buswidth > 24)
++ return -EINVAL;
++
++ /* check is there common mbus flags */
++ ret = soc_mbus_config_compatible(&cfg, VIN_MBUS_FLAGS);
++ if (ret)
++ return 0;
++
++ dev_warn(icd->parent,
++ "MBUS flags incompatible: camera 0x%x, host 0x%x\n",
++ cfg.flags, VIN_MBUS_FLAGS);
++
++ return -EINVAL;
++}
++
++static bool rcar_vin_packing_supported(const struct soc_mbus_pixelfmt *fmt)
++{
++ return fmt->packing == SOC_MBUS_PACKING_NONE ||
++ (fmt->bits_per_sample > 8 &&
++ fmt->packing == SOC_MBUS_PACKING_EXTEND16);
++}
++
++static const struct soc_mbus_pixelfmt rcar_vin_formats[] = {
++ {
++ .fourcc = V4L2_PIX_FMT_NV12,
++ .name = "NV12",
++ .bits_per_sample = 8,
++ .packing = SOC_MBUS_PACKING_1_5X8,
++ .order = SOC_MBUS_ORDER_LE,
++ .layout = SOC_MBUS_LAYOUT_PLANAR_2Y_C,
++ },
++ {
++ .fourcc = V4L2_PIX_FMT_NV16,
++ .name = "NV16",
++ .bits_per_sample = 8,
++ .packing = SOC_MBUS_PACKING_2X8_PADHI,
++ .order = SOC_MBUS_ORDER_LE,
++ .layout = SOC_MBUS_LAYOUT_PLANAR_Y_C,
++ },
++ {
++ .fourcc = V4L2_PIX_FMT_YUYV,
++ .name = "YUYV",
++ .bits_per_sample = 16,
++ .packing = SOC_MBUS_PACKING_NONE,
++ .order = SOC_MBUS_ORDER_LE,
++ .layout = SOC_MBUS_LAYOUT_PACKED,
++ },
++ {
++ .fourcc = V4L2_PIX_FMT_UYVY,
++ .name = "UYVY",
++ .bits_per_sample = 16,
++ .packing = SOC_MBUS_PACKING_NONE,
++ .order = SOC_MBUS_ORDER_LE,
++ .layout = SOC_MBUS_LAYOUT_PACKED,
++ },
++ {
++ .fourcc = V4L2_PIX_FMT_RGB565,
++ .name = "RGB565",
++ .bits_per_sample = 16,
++ .packing = SOC_MBUS_PACKING_NONE,
++ .order = SOC_MBUS_ORDER_LE,
++ .layout = SOC_MBUS_LAYOUT_PACKED,
++ },
++ {
++ .fourcc = V4L2_PIX_FMT_ARGB555,
++ .name = "ARGB1555",
++ .bits_per_sample = 16,
++ .packing = SOC_MBUS_PACKING_NONE,
++ .order = SOC_MBUS_ORDER_LE,
++ .layout = SOC_MBUS_LAYOUT_PACKED,
++ },
++ {
++ .fourcc = V4L2_PIX_FMT_XBGR32,
++ .name = "RGB888",
++ .bits_per_sample = 32,
++ .packing = SOC_MBUS_PACKING_NONE,
++ .order = SOC_MBUS_ORDER_LE,
++ .layout = SOC_MBUS_LAYOUT_PACKED,
++ },
++ {
++ .fourcc = V4L2_PIX_FMT_ABGR32,
++ .name = "ARGB8888",
++ .bits_per_sample = 32,
++ .packing = SOC_MBUS_PACKING_NONE,
++ .order = SOC_MBUS_ORDER_LE,
++ .layout = SOC_MBUS_LAYOUT_PACKED,
++ },
++};
++
++static int rcar_vin_get_formats(struct soc_camera_device *icd, unsigned int idx,
++ struct soc_camera_format_xlate *xlate)
++{
++ struct v4l2_subdev *sd = soc_camera_to_subdev(icd);
++ struct device *dev = icd->parent;
++ int ret, k, n;
++ int formats = 0;
++ struct rcar_vin_cam *cam;
++ struct soc_camera_host *ici = to_soc_camera_host(icd->parent);
++ struct rcar_vin_priv *priv = ici->priv;
++ struct v4l2_subdev_mbus_code_enum code = {
++ .which = V4L2_SUBDEV_FORMAT_ACTIVE,
++ .index = idx,
++ };
++ const struct soc_mbus_pixelfmt *fmt;
++
++ ret = v4l2_subdev_call(sd, pad, enum_mbus_code, NULL, &code);
++ if (ret < 0)
++ return 0;
++
++ fmt = soc_mbus_get_fmtdesc(code.code);
++ if (!fmt) {
++ dev_warn(dev, "unsupported format code #%u: %d\n", idx, code.code);
++ return 0;
++ }
++
++ ret = rcar_vin_try_bus_param(icd, fmt->bits_per_sample);
++ if (ret < 0)
++ return 0;
++
++ if (!icd->host_priv) {
++ struct v4l2_subdev_format fmt = {
++ .which = V4L2_SUBDEV_FORMAT_ACTIVE,
++ };
++ struct v4l2_mbus_framefmt *mf = &fmt.format;
++ struct v4l2_rect rect;
++ struct device *dev = icd->parent;
++ int shift;
++
++ ret = v4l2_subdev_call(sd, pad, get_fmt, NULL, &fmt);
++ if (ret < 0)
++ return ret;
++
++ /* Cache current client geometry */
++ ret = soc_camera_client_g_rect(sd, &rect);
++ if (ret == -ENOIOCTLCMD) {
++ /* Sensor driver doesn't support cropping */
++ rect.left = 0;
++ rect.top = 0;
++ rect.width = mf->width;
++ rect.height = mf->height;
++ } else if (ret < 0) {
++ return ret;
++ }
++
++ /*
++ * If sensor proposes too large format then try smaller ones:
++ * 1280x960, 640x480, 320x240
++ */
++ for (shift = 0; shift < 3; shift++) {
++ if (mf->width <= priv->max_width &&
++ mf->height <= priv->max_height)
++ break;
++
++ mf->width = 1280 >> shift;
++ mf->height = 960 >> shift;
++ ret = v4l2_device_call_until_err(sd->v4l2_dev,
++ soc_camera_grp_id(icd),
++ pad, set_fmt, NULL,
++ &fmt);
++ if (ret < 0)
++ return ret;
++ }
++
++ if (shift == 3) {
++ dev_err(dev,
++ "Failed to configure the client below %ux%u\n",
++ mf->width, mf->height);
++ return -EIO;
++ }
++
++ dev_dbg(dev, "camera fmt %ux%u\n", mf->width, mf->height);
++
++ cam = kzalloc(sizeof(*cam), GFP_KERNEL);
++ if (!cam)
++ return -ENOMEM;
++ /*
++ * We are called with current camera crop,
++ * initialise subrect with it
++ */
++ cam->rect = rect;
++ cam->subrect = rect;
++ cam->width = mf->width;
++ cam->height = mf->height;
++ cam->out_width = mf->width;
++ cam->out_height = mf->height;
++
++ icd->host_priv = cam;
++ } else {
++ cam = icd->host_priv;
++ }
++
++ /* Beginning of a pass */
++ if (!idx)
++ cam->extra_fmt = NULL;
++
++ switch (code.code) {
++ case MEDIA_BUS_FMT_YUYV8_1X16:
++ case MEDIA_BUS_FMT_YUYV8_2X8:
++ case MEDIA_BUS_FMT_YUYV10_2X10:
++ case MEDIA_BUS_FMT_RGB888_1X24:
++ if (cam->extra_fmt)
++ break;
++
++ /* Add all our formats that can be generated by VIN */
++ cam->extra_fmt = rcar_vin_formats;
++
++ n = ARRAY_SIZE(rcar_vin_formats);
++ formats += n;
++ for (k = 0; xlate && k < n; k++, xlate++) {
++ xlate->host_fmt = &rcar_vin_formats[k];
++ xlate->code = code.code;
++ dev_dbg(dev, "Providing format %s using code %d\n",
++ rcar_vin_formats[k].name, code.code);
++ }
++ break;
++ default:
++ if (!rcar_vin_packing_supported(fmt))
++ return 0;
++
++ dev_dbg(dev, "Providing format %s in pass-through mode\n",
++ fmt->name);
++ break;
++ }
++
++ /* Generic pass-through */
++ formats++;
++ if (xlate) {
++ xlate->host_fmt = fmt;
++ xlate->code = code.code;
++ xlate++;
++ }
++
++ return formats;
++}
++
++static void rcar_vin_put_formats(struct soc_camera_device *icd)
++{
++ kfree(icd->host_priv);
++ icd->host_priv = NULL;
++}
++
++static int rcar_vin_set_selection(struct soc_camera_device *icd,
++ struct v4l2_selection *sel)
++{
++ const struct v4l2_rect *rect = &sel->r;
++ struct soc_camera_host *ici = to_soc_camera_host(icd->parent);
++ struct rcar_vin_priv *priv = ici->priv;
++ struct v4l2_selection cam_sel;
++ struct rcar_vin_cam *cam = icd->host_priv;
++ struct v4l2_rect *cam_rect = &cam_sel.r;
++ struct v4l2_subdev *sd = soc_camera_to_subdev(icd);
++ struct device *dev = icd->parent;
++ struct v4l2_subdev_format fmt = {
++ .which = V4L2_SUBDEV_FORMAT_ACTIVE,
++ };
++ struct v4l2_mbus_framefmt *mf = &fmt.format;
++ u32 vnmc;
++ int ret, i;
++
++ dev_dbg(dev, "S_SELECTION(%ux%u@%u:%u)\n", rect->width, rect->height,
++ rect->left, rect->top);
++
++ /* During camera cropping its output window can change too, stop VIN */
++ capture_stop_preserve(priv, &vnmc);
++ dev_dbg(dev, "VNMC_REG 0x%x\n", vnmc);
++
++ /* Apply iterative camera S_SELECTION for new input window. */
++ ret = soc_camera_client_s_selection(sd, sel, &cam_sel,
++ &cam->rect, &cam->subrect);
++ if (ret < 0)
++ return ret;
++
++ dev_dbg(dev, "camera cropped to %ux%u@%u:%u\n",
++ cam_rect->width, cam_rect->height,
++ cam_rect->left, cam_rect->top);
++
++ /* On success cam_crop contains current camera crop */
++
++ /* Retrieve camera output window */
++ ret = v4l2_subdev_call(sd, pad, get_fmt, NULL, &fmt);
++ if (ret < 0)
++ return ret;
++
++ if (mf->width > priv->max_width || mf->height > priv->max_height)
++ return -EINVAL;
++
++ /* Cache camera output window */
++ cam->width = mf->width;
++ cam->height = mf->height;
++
++ cam->vin_left = rect->left;
++ cam->vin_top = rect->top;
++
++ /* Use VIN cropping to crop to the new window. */
++ ret = rcar_vin_set_rect(icd);
++ if (ret < 0)
++ return ret;
++
++ dev_dbg(dev, "VIN cropped to %ux%u@%u:%u\n",
++ icd->user_width, icd->user_height,
++ cam->vin_left, cam->vin_top);
++
++ /* Restore capture */
++ for (i = 0; i < MAX_BUFFER_NUM; i++) {
++ if (priv->queue_buf[i] && priv->state == STOPPED) {
++ vnmc |= VNMC_ME;
++ break;
++ }
++ }
++ capture_restore(priv, vnmc);
++
++ /* Even if only camera cropping succeeded */
++ return ret;
++}
++
++static int rcar_vin_get_selection(struct soc_camera_device *icd,
++ struct v4l2_selection *sel)
++{
++ struct rcar_vin_cam *cam = icd->host_priv;
++
++ sel->r = cam->subrect;
++
++ return 0;
++}
++
++/* Similar to set_crop multistage iterative algorithm */
++static int rcar_vin_set_fmt(struct soc_camera_device *icd,
++ struct v4l2_format *f)
++{
++ struct soc_camera_host *ici = to_soc_camera_host(icd->parent);
++ struct rcar_vin_priv *priv = ici->priv;
++ struct v4l2_subdev *sd = soc_camera_to_subdev(icd);
++ struct rcar_vin_cam *cam = icd->host_priv;
++ struct v4l2_pix_format *pix = &f->fmt.pix;
++ struct v4l2_mbus_framefmt mf;
++ struct device *dev = icd->parent;
++ __u32 pixfmt = pix->pixelformat;
++ const struct soc_camera_format_xlate *xlate;
++ unsigned int vin_sub_width = 0, vin_sub_height = 0;
++ int ret;
++ bool can_scale;
++ enum v4l2_field field;
++ v4l2_std_id std;
++
++ dev_dbg(dev, "S_FMT(pix=0x%x, %ux%u)\n",
++ pixfmt, pix->width, pix->height);
++
++ /* At the time of NV16 capture format, the user has to specify */
++ /* the width of the multiple of 32 for H/W specification. */
++ if (priv->error_flag == false)
++ priv->error_flag = true;
++ else {
++ if (((pixfmt == V4L2_PIX_FMT_NV16) ||
++ (pixfmt == V4L2_PIX_FMT_NV12)) &&
++ (pix->width & 0x1F)) {
++ dev_dbg(icd->parent,
++ "specify width of 32 multiple in separate format.\n");
++ return -EINVAL;
++ }
++ }
++
++ switch (pix->field) {
++ default:
++ pix->field = V4L2_FIELD_NONE;
++ /* fall-through */
++ case V4L2_FIELD_NONE:
++ case V4L2_FIELD_TOP:
++ case V4L2_FIELD_BOTTOM:
++ case V4L2_FIELD_INTERLACED_TB:
++ case V4L2_FIELD_INTERLACED_BT:
++ field = pix->field;
++ break;
++ case V4L2_FIELD_INTERLACED:
++ /* Query for standard if not explicitly mentioned _TB/_BT */
++ ret = v4l2_subdev_call(sd, video, querystd, &std);
++ if (ret == -ENOIOCTLCMD) {
++ field = V4L2_FIELD_NONE;
++ } else if (ret < 0) {
++ return ret;
++ } else {
++ field = std & V4L2_STD_625_50 ?
++ V4L2_FIELD_INTERLACED_TB :
++ V4L2_FIELD_INTERLACED_BT;
++ }
++ break;
++ }
++
++ xlate = soc_camera_xlate_by_fourcc(icd, pixfmt);
++ if (!xlate) {
++ dev_warn(dev, "Format %x not found\n", pixfmt);
++ return -EINVAL;
++ }
++ /* Calculate client output geometry */
++ soc_camera_calc_client_output(icd, &cam->rect, &cam->subrect, pix, &mf,
++ 12);
++ mf.field = pix->field;
++ mf.colorspace = pix->colorspace;
++ mf.code = xlate->code;
++
++ switch (pixfmt) {
++ case V4L2_PIX_FMT_XBGR32:
++ can_scale = priv->chip != RCAR_E1;
++ break;
++ case V4L2_PIX_FMT_ABGR32:
++ case V4L2_PIX_FMT_UYVY:
++ case V4L2_PIX_FMT_YUYV:
++ case V4L2_PIX_FMT_RGB565:
++ case V4L2_PIX_FMT_ARGB555:
++ case V4L2_PIX_FMT_NV16:
++ can_scale = true;
++ break;
++ case V4L2_PIX_FMT_NV12:
++ default:
++ can_scale = false;
++ break;
++ }
++
++ dev_dbg(dev, "request camera output %ux%u\n", mf.width, mf.height);
++
++ ret = soc_camera_client_scale(icd, &cam->rect, &cam->subrect,
++ &mf, &vin_sub_width, &vin_sub_height,
++ can_scale, 12);
++
++ /* Done with the camera. Now see if we can improve the result */
++ dev_dbg(dev, "Camera %d fmt %ux%u, requested %ux%u\n",
++ ret, mf.width, mf.height, pix->width, pix->height);
++
++ if (ret == -ENOIOCTLCMD)
++ dev_dbg(dev, "Sensor doesn't support scaling\n");
++ else if (ret < 0)
++ return ret;
++
++ if (mf.code != xlate->code)
++ return -EINVAL;
++
++ /* Prepare VIN crop */
++ cam->width = mf.width;
++ cam->height = mf.height;
++
++ /* Use VIN scaling to scale to the requested user window. */
++
++ /* We cannot scale up */
++ if (pix->width > vin_sub_width)
++ vin_sub_width = pix->width;
++
++ if (pix->height > vin_sub_height)
++ vin_sub_height = pix->height;
++
++ pix->colorspace = mf.colorspace;
++
++ if (!can_scale) {
++ pix->width = vin_sub_width;
++ pix->height = vin_sub_height;
++ }
++
++ /*
++ * We have calculated CFLCR, the actual configuration will be performed
++ * in rcar_vin_set_bus_param()
++ */
++
++ dev_dbg(dev, "W: %u : %u, H: %u : %u\n",
++ vin_sub_width, pix->width, vin_sub_height, pix->height);
++
++ cam->out_width = pix->width;
++ cam->out_height = pix->height;
++
++ icd->current_fmt = xlate;
++
++ priv->field = field;
++
++ return 0;
++}
++
++static int rcar_vin_try_fmt(struct soc_camera_device *icd,
++ struct v4l2_format *f)
++{
++ const struct soc_camera_format_xlate *xlate;
++ struct soc_camera_host *ici = to_soc_camera_host(icd->parent);
++ struct rcar_vin_priv *priv = ici->priv;
++ struct v4l2_pix_format *pix = &f->fmt.pix;
++ struct v4l2_subdev *sd = soc_camera_to_subdev(icd);
++ struct v4l2_subdev_pad_config pad_cfg;
++ struct v4l2_subdev_format format = {
++ .which = V4L2_SUBDEV_FORMAT_TRY,
++ };
++ struct v4l2_mbus_framefmt *mf = &format.format;
++ __u32 pixfmt = pix->pixelformat;
++ int width, height;
++ int ret;
++
++ xlate = soc_camera_xlate_by_fourcc(icd, pixfmt);
++ if (!xlate) {
++ xlate = icd->current_fmt;
++ dev_dbg(icd->parent, "Format %x not found, keeping %x\n",
++ pixfmt, xlate->host_fmt->fourcc);
++ pixfmt = xlate->host_fmt->fourcc;
++ pix->pixelformat = pixfmt;
++ pix->colorspace = icd->colorspace;
++ }
++
++ /* When performing a YCbCr-422 format output, even if it performs */
++ /* odd number clipping by pixel post clip processing, */
++ /* it is outputted to a memory per even pixels. */
++ if ((pixfmt == V4L2_PIX_FMT_NV16) || (pixfmt == V4L2_PIX_FMT_NV12) ||
++ (pixfmt == V4L2_PIX_FMT_YUYV) || (pixfmt == V4L2_PIX_FMT_UYVY))
++ v4l_bound_align_image(&pix->width, 5, priv->max_width, 1,
++ &pix->height, 2, priv->max_height, 0, 0);
++ else
++ v4l_bound_align_image(&pix->width, 5, priv->max_width, 0,
++ &pix->height, 2, priv->max_height, 0, 0);
++
++ width = pix->width;
++ height = pix->height;
++
++ /* let soc-camera calculate these values */
++ pix->bytesperline = 0;
++ pix->sizeimage = 0;
++
++ /* limit to sensor capabilities */
++ mf->width = pix->width;
++ mf->height = pix->height;
++ mf->field = pix->field;
++ mf->code = xlate->code;
++ mf->colorspace = pix->colorspace;
++
++ ret = v4l2_device_call_until_err(sd->v4l2_dev, soc_camera_grp_id(icd),
++ pad, set_fmt, &pad_cfg, &format);
++ if (ret < 0)
++ return ret;
++
++ if (priv->chip == RCAR_H3 || priv->chip == RCAR_M3) {
++ /* Adjust max scaling size for Gen3 */
++ if (pix->width > 4096)
++ pix->width = priv->max_width;
++ if (pix->height > 4096)
++ pix->height = priv->max_height;
++ } else {
++ /* Adjust only if VIN cannot scale */
++ if (pix->width > mf->width * 2)
++ pix->width = mf->width * 2;
++ if (pix->height > mf->height * 3)
++ pix->height = mf->height * 3;
++ }
++
++ pix->field = mf->field;
++ pix->colorspace = mf->colorspace;
++
++ if (pixfmt == V4L2_PIX_FMT_NV16) {
++ /* FIXME: check against rect_max after converting soc-camera */
++ /* We can scale precisely, need a bigger image from camera */
++ if (pix->width < width || pix->height < height) {
++ /*
++ * We presume, the sensor behaves sanely, i.e. if
++ * requested a bigger rectangle, it will not return a
++ * smaller one.
++ */
++ mf->width = priv->max_width;
++ mf->height = priv->max_height;
++ ret = v4l2_device_call_until_err(sd->v4l2_dev,
++ soc_camera_grp_id(icd),
++ pad, set_fmt, &pad_cfg,
++ &format);
++ if (ret < 0) {
++ dev_err(icd->parent,
++ "client try_fmt() = %d\n", ret);
++ return ret;
++ }
++ }
++ /* We will scale exactly */
++ if (mf->width > width)
++ pix->width = width;
++ if (mf->height > height)
++ pix->height = height;
++ }
++
++ return ret;
++}
++
++static unsigned int rcar_vin_poll(struct file *file, poll_table *pt)
++{
++ struct soc_camera_device *icd = file->private_data;
++
++ return vb2_poll(&icd->vb2_vidq, file, pt);
++}
++
++static int rcar_vin_querycap(struct soc_camera_host *ici,
++ struct v4l2_capability *cap)
++{
++ strlcpy(cap->card, "R_Car_VIN", sizeof(cap->card));
++ cap->device_caps = V4L2_CAP_VIDEO_CAPTURE | V4L2_CAP_STREAMING;
++ cap->capabilities = cap->device_caps | V4L2_CAP_DEVICE_CAPS;
++ snprintf(cap->bus_info, sizeof(cap->bus_info), "platform:%s%d", DRV_NAME, ici->nr);
++
++ return 0;
++}
++
++static int rcar_vin_init_videobuf2(struct vb2_queue *vq,
++ struct soc_camera_device *icd)
++{
++ struct soc_camera_host *ici = to_soc_camera_host(icd->parent);
++
++ vq->type = V4L2_BUF_TYPE_VIDEO_CAPTURE;
++ vq->io_modes = VB2_MMAP | VB2_USERPTR | VB2_DMABUF;
++ vq->drv_priv = icd;
++ vq->ops = &rcar_vin_vb2_ops;
++ vq->mem_ops = &vb2_dma_contig_memops;
++ vq->buf_struct_size = sizeof(struct rcar_vin_buffer);
++ vq->timestamp_flags = V4L2_BUF_FLAG_TIMESTAMP_MONOTONIC;
++ vq->lock = &ici->host_lock;
++ vq->dev = ici->v4l2_dev.dev;
++
++ return vb2_queue_init(vq);
++}
++
++#if 0
++static int rcar_vin_get_selection(struct soc_camera_device *icd,
++ struct v4l2_selection *sel)
++{
++ struct v4l2_subdev *sd = soc_camera_to_subdev(icd);
++ struct v4l2_subdev_format fmt = {
++ .which = V4L2_SUBDEV_FORMAT_ACTIVE,
++ };
++ struct v4l2_mbus_framefmt *mf = &fmt.format;
++ int ret;
++
++ ret = v4l2_subdev_call(sd, pad, get_fmt, NULL, &fmt);
++ if (ret < 0)
++ return ret;
++
++ if (sel->type != V4L2_BUF_TYPE_VIDEO_CAPTURE)
++ return -EINVAL;
++
++ switch (sel->target) {
++ case V4L2_SEL_TGT_CROP_BOUNDS:
++ case V4L2_SEL_TGT_CROP_DEFAULT:
++ sel->r.left = sel->r.top = 0;
++ sel->r.width = mf->width;
++ sel->r.height = mf->height;
++ break;
++ default:
++ return -EINVAL;
++ }
++
++ return 0;
++}
++
++static int rcar_vin_cropcap(struct soc_camera_device *icd,
++ struct v4l2_cropcap *crop)
++{
++ struct v4l2_subdev *sd = soc_camera_to_subdev(icd);
++ struct v4l2_subdev_format fmt = {
++ .which = V4L2_SUBDEV_FORMAT_ACTIVE,
++ };
++ struct v4l2_mbus_framefmt *mf = &fmt.format;
++ int ret;
++
++ ret = v4l2_subdev_call(sd, pad, get_fmt, NULL, &fmt);
++ if (ret < 0)
++ return ret;
++
++ crop->bounds.left = 0;
++ crop->bounds.top = 0;
++ crop->bounds.width = mf->width;
++ crop->bounds.height = mf->height;
++
++ /* default cropping rectangle */
++ crop->defrect = crop->bounds;
++ crop->type = V4L2_BUF_TYPE_VIDEO_CAPTURE;
++
++ return 0;
++}
++#endif
++
++static struct soc_camera_host_ops rcar_vin_host_ops = {
++ .owner = THIS_MODULE,
++ .add = rcar_vin_add_device,
++ .remove = rcar_vin_remove_device,
++ .get_formats = rcar_vin_get_formats,
++ .put_formats = rcar_vin_put_formats,
++ .get_selection = rcar_vin_get_selection,
++ .set_selection = rcar_vin_set_selection,
++ .try_fmt = rcar_vin_try_fmt,
++ .set_fmt = rcar_vin_set_fmt,
++ .poll = rcar_vin_poll,
++ .querycap = rcar_vin_querycap,
++ .set_bus_param = rcar_vin_set_bus_param,
++ .init_videobuf2 = rcar_vin_init_videobuf2,
++#if 0
++ .get_selection = rcar_vin_get_selection,
++ .cropcap = rcar_vin_cropcap,
++#endif
++};
++
++#ifdef CONFIG_OF
++static const struct of_device_id rcar_vin_of_table[] = {
++ { .compatible = "renesas,vin-r8a7796", .data = (void *)RCAR_M3 },
++ { .compatible = "renesas,vin-r8a7795", .data = (void *)RCAR_H3 },
++ { .compatible = "renesas,vin-r8a7794", .data = (void *)RCAR_GEN2 },
++ { .compatible = "renesas,vin-r8a7793", .data = (void *)RCAR_GEN2 },
++ { .compatible = "renesas,vin-r8a7791", .data = (void *)RCAR_GEN2 },
++ { .compatible = "renesas,vin-r8a7790", .data = (void *)RCAR_GEN2 },
++ { .compatible = "renesas,vin-r8a7779", .data = (void *)RCAR_H1 },
++ { .compatible = "renesas,vin-r8a7778", .data = (void *)RCAR_M1 },
++ { .compatible = "renesas,rcar-gen3-vin", .data = (void *)RCAR_GEN3 },
++ { .compatible = "renesas,rcar-gen2-vin", .data = (void *)RCAR_GEN2 },
++ { },
++};
++MODULE_DEVICE_TABLE(of, rcar_vin_of_table);
++#endif
++
++#define MAP_MAX_NUM 32
++static DECLARE_BITMAP(device_map, MAP_MAX_NUM);
++static DEFINE_MUTEX(list_lock);
++
++static int rcar_vin_dyn_pdev(struct soc_camera_desc *sdesc,
++ struct rcar_vin_async_client *sasc)
++{
++ struct platform_device *pdev;
++ int ret, i;
++
++ mutex_lock(&list_lock);
++ i = find_first_zero_bit(device_map, MAP_MAX_NUM);
++ if (i < MAP_MAX_NUM)
++ set_bit(i, device_map);
++ mutex_unlock(&list_lock);
++ if (i >= MAP_MAX_NUM)
++ return -ENOMEM;
++
++ pdev = platform_device_alloc("soc-camera-pdrv", ((2 * i) + 1));
++ if (!pdev)
++ return -ENOMEM;
++
++ ret = platform_device_add_data(pdev, sdesc, sizeof(*sdesc));
++ if (ret < 0) {
++ platform_device_put(pdev);
++ return ret;
++ }
++
++ sasc->pdev = pdev;
++
++ return 0;
++}
++
++static int rcar_vin_async_bound(struct v4l2_async_notifier *notifier,
++ struct v4l2_subdev *sd,
++ struct v4l2_async_subdev *asd)
++{
++ /* None. */
++ return 0;
++}
++
++static void rcar_vin_async_unbind(struct v4l2_async_notifier *notifier,
++ struct v4l2_subdev *sd,
++ struct v4l2_async_subdev *asd)
++{
++ /* None. */
++}
++
++static int rcar_vin_async_probe(struct soc_camera_host *ici,
++ struct soc_camera_device *icd)
++{
++ struct soc_camera_desc *sdesc = to_soc_camera_desc(icd);
++ struct soc_camera_host_desc *shd = &sdesc->host_desc;
++ struct device *control = NULL;
++ int ret;
++
++ ret = v4l2_ctrl_handler_init(&icd->ctrl_handler, 16);
++ if (ret < 0)
++ return ret;
++
++ if (shd->module_name)
++ ret = request_module(shd->module_name);
++
++ ret = shd->add_device(icd);
++
++ control = to_soc_camera_control(icd);
++ if (!control || !control->driver || !dev_get_drvdata(control) ||
++ !try_module_get(control->driver->owner)) {
++ shd->del_device(icd);
++ ret = -ENODEV;
++ }
++
++ return ret;
++}
++
++static int rcar_vin_async_complete(struct v4l2_async_notifier *notifier)
++{
++ struct rcar_vin_async_client *sasc = container_of(notifier,
++ struct rcar_vin_async_client, notifier);
++ struct soc_camera_device *icd = platform_get_drvdata(sasc->pdev);
++
++ if (to_soc_camera_control(icd)) {
++ struct soc_camera_host *ici = to_soc_camera_host(icd->parent);
++ int ret;
++
++ mutex_lock(&list_lock);
++ ret = rcar_vin_async_probe(ici, icd);
++ mutex_unlock(&list_lock);
++ if (ret < 0)
++ return ret;
++ }
++
++ return 0;
++}
++
++static struct soc_camera_device *rcar_vin_add_pdev(
++ struct rcar_vin_async_client *sasc)
++{
++ struct platform_device *pdev = sasc->pdev;
++ int ret;
++
++ ret = platform_device_add(pdev);
++
++ if (ret < 0 || !pdev->dev.driver)
++ return NULL;
++
++ return platform_get_drvdata(pdev);
++}
++
++static int rcar_vin_soc_of_bind(struct rcar_vin_priv *priv,
++ struct soc_camera_host *ici,
++ struct device_node *ep,
++ struct device_node *remote)
++{
++ struct soc_camera_device *icd;
++ struct soc_camera_desc sdesc = {.host_desc.bus_id = ici->nr,};
++ struct rcar_vin_async_client *sasc;
++ struct soc_of_info *info;
++ struct i2c_client *client;
++ char clk_name[V4L2_SUBDEV_NAME_SIZE];
++ int ret;
++
++ /* allocate a new subdev and add match info to it */
++ info = devm_kzalloc(ici->v4l2_dev.dev, sizeof(struct soc_of_info),
++ GFP_KERNEL);
++ if (!info)
++ return -ENOMEM;
++
++ info->sasd.asd.match.of.node = remote;
++ info->sasd.asd.match_type = V4L2_ASYNC_MATCH_OF;
++ info->subdev = &info->sasd.asd;
++
++ /* Or shall this be managed by the soc-camera device? */
++ sasc = &info->sasc;
++
++ ret = rcar_vin_dyn_pdev(&sdesc, sasc);
++ if (ret < 0)
++ goto eallocpdev;
++
++ sasc->sensor = &info->sasd.asd;
++
++ icd = rcar_vin_add_pdev(sasc);
++ if (!icd) {
++ ret = -ENOMEM;
++ goto eaddpdev;
++ }
++
++ sasc->notifier.subdevs = &info->subdev;
++ sasc->notifier.num_subdevs = 1;
++ sasc->notifier.bound = rcar_vin_async_bound;
++ sasc->notifier.unbind = rcar_vin_async_unbind;
++ sasc->notifier.complete = rcar_vin_async_complete;
++
++ priv->async_client = sasc;
++
++ client = of_find_i2c_device_by_node(remote);
++
++ if (client)
++ snprintf(clk_name, sizeof(clk_name), "%d-%04x",
++ client->adapter->nr, client->addr);
++ else
++ snprintf(clk_name, sizeof(clk_name), "of-%s",
++ of_node_full_name(remote));
++
++ ret = v4l2_async_notifier_register(&ici->v4l2_dev, &sasc->notifier);
++ if (!ret)
++ return 0;
++
++ platform_device_del(sasc->pdev);
++eaddpdev:
++ platform_device_put(sasc->pdev);
++eallocpdev:
++ devm_kfree(ici->v4l2_dev.dev, info);
++ dev_err(ici->v4l2_dev.dev, "group probe failed: %d\n", ret);
++
++ return ret;
++}
++
++static int rcar_vin_probe(struct platform_device *pdev)
++{
++ const struct of_device_id *match = NULL;
++ struct rcar_vin_priv *priv;
++ struct v4l2_of_endpoint ep;
++ struct device_node *np;
++ struct resource *mem;
++ unsigned int pdata_flags;
++ int irq, ret;
++ const char *str;
++ unsigned int i;
++ struct device_node *epn = NULL, *ren = NULL;
++ bool csi_use = false;
++
++ match = of_match_device(of_match_ptr(rcar_vin_of_table), &pdev->dev);
++
++ np = of_graph_get_next_endpoint(pdev->dev.of_node, NULL);
++ if (!np) {
++ dev_err(&pdev->dev, "could not find endpoint\n");
++ return -EINVAL;
++ }
++
++ for (i = 0; ; i++) {
++ epn = of_graph_get_next_endpoint(pdev->dev.of_node,
++ epn);
++ if (!epn)
++ break;
++
++ ren = of_graph_get_remote_port(epn);
++ if (!ren) {
++ dev_notice(&pdev->dev, "no remote for %s\n",
++ of_node_full_name(epn));
++ continue;
++ }
++
++ /* so we now have a remote node to connect */
++ dev_dbg(&pdev->dev, "node name:%s\n",
++ of_node_full_name(ren->parent));
++
++ if (strcmp(ren->parent->name, "csi2") == 0)
++ csi_use = true;
++
++ of_node_put(ren);
++
++ if (i)
++ break;
++ }
++
++ ret = v4l2_of_parse_endpoint(np, &ep);
++ if (ret) {
++ dev_err(&pdev->dev, "could not parse endpoint\n");
++ return ret;
++ }
++
++ if (ep.bus_type == V4L2_MBUS_BT656)
++ pdata_flags = RCAR_VIN_BT656;
++ else if (ep.bus_type == V4L2_MBUS_CSI2)
++ pdata_flags = RCAR_VIN_BT656 | RCAR_VIN_CSI2;
++ else {
++ pdata_flags = 0;
++ if (ep.bus.parallel.flags & V4L2_MBUS_HSYNC_ACTIVE_LOW)
++ pdata_flags |= RCAR_VIN_HSYNC_ACTIVE_LOW;
++ if (ep.bus.parallel.flags & V4L2_MBUS_VSYNC_ACTIVE_LOW)
++ pdata_flags |= RCAR_VIN_VSYNC_ACTIVE_LOW;
++ }
++
++ of_node_put(np);
++
++ dev_dbg(&pdev->dev, "pdata_flags = %08x\n", pdata_flags);
++
++ mem = platform_get_resource(pdev, IORESOURCE_MEM, 0);
++ if (mem == NULL)
++ return -EINVAL;
++
++ irq = platform_get_irq(pdev, 0);
++ if (irq <= 0)
++ return -EINVAL;
++
++ priv = devm_kzalloc(&pdev->dev, sizeof(struct rcar_vin_priv),
++ GFP_KERNEL);
++ if (!priv)
++ return -ENOMEM;
++
++ priv->base = devm_ioremap_resource(&pdev->dev, mem);
++ if (IS_ERR(priv->base))
++ return PTR_ERR(priv->base);
++
++ ret = devm_request_irq(&pdev->dev, irq, rcar_vin_irq, IRQF_SHARED,
++ dev_name(&pdev->dev), priv);
++ if (ret)
++ return ret;
++
++ priv->ici.priv = priv;
++ priv->ici.v4l2_dev.dev = &pdev->dev;
++ priv->ici.drv_name = dev_name(&pdev->dev);
++ priv->ici.ops = &rcar_vin_host_ops;
++ priv->csi_sync = false;
++
++ priv->pdata_flags = pdata_flags;
++ if (!match) {
++ priv->ici.nr = pdev->id;
++ priv->chip = pdev->id_entry->driver_data;
++ } else {
++ priv->ici.nr = of_alias_get_id(pdev->dev.of_node, "vin");
++ priv->chip = (enum chip_id)match->data;
++ }
++
++ if (priv->chip == RCAR_H3 || priv->chip == RCAR_M3) {
++ priv->max_width = 4096;
++ priv->max_height = 4096;
++ } else {
++ priv->max_width = 2048;
++ priv->max_height = 2048;
++ }
++
++ if (priv->chip == RCAR_H3 || priv->chip == RCAR_M3) {
++ u32 ifmd = 0;
++ bool match_flag = false;
++ const struct vin_gen3_ifmd *gen3_ifmd_table = NULL;
++ int vc, num;
++
++ num = VNCSI_IFMD_SEL_NUMBER;
++
++ if (strcmp(dev_name(priv->ici.v4l2_dev.dev),
++ "e6ef0000.video") == 0)
++ priv->index = RCAR_VIDEO_0;
++ else if (strcmp(dev_name(priv->ici.v4l2_dev.dev),
++ "e6ef1000.video") == 0)
++ priv->index = RCAR_VIDEO_1;
++ else if (strcmp(dev_name(priv->ici.v4l2_dev.dev),
++ "e6ef2000.video") == 0)
++ priv->index = RCAR_VIDEO_2;
++ else if (strcmp(dev_name(priv->ici.v4l2_dev.dev),
++ "e6ef3000.video") == 0)
++ priv->index = RCAR_VIDEO_3;
++ else if (strcmp(dev_name(priv->ici.v4l2_dev.dev),
++ "e6ef4000.video") == 0)
++ priv->index = RCAR_VIDEO_4;
++ else if (strcmp(dev_name(priv->ici.v4l2_dev.dev),
++ "e6ef5000.video") == 0)
++ priv->index = RCAR_VIDEO_5;
++ else if (strcmp(dev_name(priv->ici.v4l2_dev.dev),
++ "e6ef6000.video") == 0)
++ priv->index = RCAR_VIDEO_6;
++ else if (strcmp(dev_name(priv->ici.v4l2_dev.dev),
++ "e6ef7000.video") == 0)
++ priv->index = RCAR_VIDEO_7;
++ else
++ priv->index = RCAR_VIN_CH_NONE;
++
++ ret = of_property_read_string(np, "csi,select", &str);
++ if (ret) {
++ dev_err(&pdev->dev, "could not parse csi,select\n");
++ return ret;
++ }
++
++ if (strcmp(str, "csi40") == 0)
++ priv->csi_ch = RCAR_CSI40;
++ else if (strcmp(str, "csi20") == 0)
++ priv->csi_ch = RCAR_CSI20;
++ else if (strcmp(str, "csi41") == 0)
++ priv->csi_ch = RCAR_CSI41;
++ else if (strcmp(str, "csi21") == 0)
++ priv->csi_ch = RCAR_CSI21;
++ else
++ priv->csi_ch = RCAR_CSI_CH_NONE;
++
++ ret = of_property_read_u32(np, "virtual,channel", &vc);
++ if (ret) {
++ dev_err(&pdev->dev,
++ "could not parse virtual,channel\n");
++ return ret;
++ }
++
++ if (vc == 0)
++ priv->vc = RCAR_VIRTUAL_CH0;
++ else if (vc == 1)
++ priv->vc = RCAR_VIRTUAL_CH1;
++ else if (vc == 2)
++ priv->vc = RCAR_VIRTUAL_CH2;
++ else if (vc == 3)
++ priv->vc = RCAR_VIRTUAL_CH3;
++ else
++ priv->vc = RCAR_VIRTUAL_NONE;
++
++ dev_dbg(&pdev->dev, "csi_ch:%d, vc:%d\n",
++ priv->csi_ch, priv->vc);
++
++ ifmd = VNCSI_IFMD_DES1 | VNCSI_IFMD_DES0;
++
++ if (priv->chip == RCAR_H3)
++ gen3_ifmd_table = vin_h3_vc_ifmd;
++ else if (priv->chip == RCAR_M3)
++ gen3_ifmd_table = vin_m3_vc_ifmd;
++
++ for (i = 0; i < num; i++) {
++ if ((gen3_ifmd_table[i].v_sel[priv->index].csi2_ch
++ == priv->csi_ch) &&
++ (gen3_ifmd_table[i].v_sel[priv->index].vc
++ == priv->vc)) {
++ if (priv->index < RCAR_VIDEO_4) {
++ if (ifmd0_init) {
++ ifmd0_reg_match[i] = true;
++ match_flag = true;
++ } else if (ifmd0_reg_match[i])
++ match_flag = true;
++ } else {
++ if (ifmd4_init) {
++ ifmd4_reg_match[i] = true;
++ match_flag = true;
++ } else if (ifmd4_reg_match[i])
++ match_flag = true;
++ }
++ } else {
++ if (priv->index < RCAR_VIDEO_4)
++ ifmd0_reg_match[i] = false;
++ else
++ ifmd4_reg_match[i] = false;
++ }
++ }
++ if (priv->index < RCAR_VIDEO_4)
++ ifmd0_init = false;
++ else
++ ifmd4_init = false;
++
++ if (!match_flag) {
++ dev_err(&pdev->dev,
++ "Not match, virtual channel pattern error.\n");
++ return -EINVAL;
++ }
++
++ rcar_vin_cpg_enable_for_ifmd(priv->index, true);
++
++ if (priv->index < RCAR_VIDEO_4) {
++ void __iomem *ifmd0_mem;
++
++ for (i = 0; i < num; i++) {
++ if (ifmd0_reg_match[i]) {
++ ifmd |= gen3_ifmd_table[i].set_reg;
++ break;
++ }
++ }
++
++ ifmd0_mem = ioremap(0xe6ef0000 + VNCSI_IFMD_REG, 0x04);
++ iowrite32(ifmd, ifmd0_mem);
++ iounmap(ifmd0_mem);
++ } else {
++ void __iomem *ifmd4_mem;
++
++ for (i = 0; i < num; i++) {
++ if (ifmd4_reg_match[i]) {
++ ifmd |= gen3_ifmd_table[i].set_reg;
++ break;
++ }
++ }
++
++ ifmd4_mem = ioremap(0xe6ef4000 + VNCSI_IFMD_REG, 0x04);
++ iowrite32(ifmd, ifmd4_mem);
++ iounmap(ifmd4_mem);
++ }
++
++ rcar_vin_cpg_enable_for_ifmd(priv->index, false);
++ }
++
++ spin_lock_init(&priv->lock);
++ INIT_LIST_HEAD(&priv->capture);
++
++ priv->state = STOPPED;
++
++ pm_suspend_ignore_children(&pdev->dev, true);
++ pm_runtime_enable(&pdev->dev);
++
++ ret = soc_camera_host_register(&priv->ici);
++ if (ret)
++ goto cleanup;
++
++ if (csi_use) {
++ ret = rcar_vin_soc_of_bind(priv, &priv->ici, epn, ren->parent);
++ if (ret)
++ goto cleanup;
++ }
++
++ vin_debug = 0;
++
++ return 0;
++
++cleanup:
++ pm_runtime_disable(&pdev->dev);
++
++ return ret;
++}
++
++static int rcar_vin_remove(struct platform_device *pdev)
++{
++ struct soc_camera_host *soc_host = to_soc_camera_host(&pdev->dev);
++ struct rcar_vin_priv *priv = container_of(soc_host,
++ struct rcar_vin_priv, ici);
++
++ platform_device_del(priv->async_client->pdev);
++ platform_device_put(priv->async_client->pdev);
++
++ v4l2_async_notifier_unregister(&priv->async_client->notifier);
++
++ soc_camera_host_unregister(soc_host);
++ pm_runtime_disable(&pdev->dev);
++
++ return 0;
++}
++
++#ifdef CONFIG_PM_SLEEP
++static int rcar_vin_suspend(struct device *dev)
++{
++ /* Empty function for now */
++ return 0;
++}
++
++static int rcar_vin_resume(struct device *dev)
++{
++ u32 ifmd = 0;
++ bool match_flag = false;
++ const struct vin_gen3_ifmd *gen3_ifmd_table = NULL;
++ int num;
++ unsigned int i;
++ struct soc_camera_host *soc_host = to_soc_camera_host(dev);
++ struct rcar_vin_priv *priv = container_of(soc_host,
++ struct rcar_vin_priv, ici);
++ num = VNCSI_IFMD_SEL_NUMBER;
++ ifmd0_init = true;
++ ifmd4_init = true;
++
++ if (priv->chip == RCAR_H3) {
++ ifmd = VNCSI_IFMD_DES1 | VNCSI_IFMD_DES0;
++ gen3_ifmd_table = vin_h3_vc_ifmd;
++ } else if (priv->chip == RCAR_M3) {
++ ifmd = VNCSI_IFMD_DES1;
++ gen3_ifmd_table = vin_m3_vc_ifmd;
++ }
++
++ for (i = 0; i < num; i++) {
++ if ((gen3_ifmd_table[i].v_sel[priv->index].csi2_ch
++ == priv->csi_ch) &&
++ (gen3_ifmd_table[i].v_sel[priv->index].vc
++ == priv->vc)) {
++ if (priv->index < RCAR_VIDEO_4) {
++ if (ifmd0_init) {
++ ifmd0_reg_match[i] = true;
++ match_flag = true;
++ } else if (ifmd0_reg_match[i])
++ match_flag = true;
++ } else {
++ if (ifmd4_init) {
++ ifmd4_reg_match[i] = true;
++ match_flag = true;
++ } else if (ifmd4_reg_match[i])
++ match_flag = true;
++ }
++ } else {
++ if (priv->index < RCAR_VIDEO_4)
++ ifmd0_reg_match[i] = false;
++ else
++ ifmd4_reg_match[i] = false;
++ }
++ }
++ if (priv->index < RCAR_VIDEO_4)
++ ifmd0_init = false;
++ else
++ ifmd4_init = false;
++
++ if (priv->index < RCAR_VIDEO_4) {
++ void __iomem *ifmd0_mem;
++
++ for (i = 0; i < num; i++) {
++ if (ifmd0_reg_match[i]) {
++ ifmd |= gen3_ifmd_table[i].set_reg;
++ break;
++ }
++ }
++
++ ifmd0_mem = ioremap(0xe6ef0000 + VNCSI_IFMD_REG, 0x04);
++ iowrite32(ifmd, ifmd0_mem);
++ iounmap(ifmd0_mem);
++ } else {
++ void __iomem *ifmd4_mem;
++
++ for (i = 0; i < num; i++) {
++ if (ifmd4_reg_match[i]) {
++ ifmd |= gen3_ifmd_table[i].set_reg;
++ break;
++ }
++ }
++
++ ifmd4_mem = ioremap(0xe6ef4000 + VNCSI_IFMD_REG, 0x04);
++ iowrite32(ifmd, ifmd4_mem);
++ iounmap(ifmd4_mem);
++ }
++
++ return 0;
++}
++
++static SIMPLE_DEV_PM_OPS(rcar_vin_pm_ops,
++ rcar_vin_suspend, rcar_vin_resume);
++#define DEV_PM_OPS (&rcar_vin_pm_ops)
++#else
++#define DEV_PM_OPS NULL
++#endif /* CONFIG_PM_SLEEP */
++
++static struct platform_driver rcar_vin_driver = {
++ .probe = rcar_vin_probe,
++ .remove = rcar_vin_remove,
++ .driver = {
++ .name = DRV_NAME,
++ .pm = DEV_PM_OPS,
++ .of_match_table = of_match_ptr(rcar_vin_of_table),
++ },
++};
++
++module_platform_driver(rcar_vin_driver);
++
++MODULE_LICENSE("GPL");
++MODULE_ALIAS("platform:rcar_vin");
++MODULE_DESCRIPTION("Renesas R-Car VIN camera host driver");
++MODULE_AUTHOR("Koji Matsuoka <koji.matsuoka.xm@renesas.com>");
+diff --git a/include/media/rcar_csi2.h b/include/media/rcar_csi2.h
+new file mode 100644
+index 0000000..1a040fa
+--- /dev/null
++++ b/include/media/rcar_csi2.h
+@@ -0,0 +1,66 @@
++/*
++ * include/media/rcar_csi2.h
++ * This file is the driver header
++ * for the Renesas R-Car MIPI CSI-2 unit.
++ *
++ * Copyright (C) 2015 Renesas Electronics Corporation
++ *
++ * This file is based on the include/media/sh_mobile_csi2.h
++ *
++ * Driver header for the SH-Mobile MIPI CSI-2 unit
++ *
++ * Copyright (C) 2010, Guennadi Liakhovetski <g.liakhovetski@gmx.de>
++ *
++ * This program is free software; you can redistribute it and/or modify
++ * it under the terms of the GNU General Public License version 2 as
++ * published by the Free Software Foundation.
++ */
++
++#ifndef RCAR_MIPI_CSI
++#define RCAR_MIPI_CSI
++
++#include <linux/list.h>
++
++enum rcar_csi2_phy {
++ RCAR_CSI2_PHY_CSI40, /* CSI0 */
++ RCAR_CSI2_PHY_CSI20, /* CSI1 */
++ RCAR_CSI2_PHY_CSI41, /* CSI2 */
++ RCAR_CSI2_PHY_CSI21, /* CSI3 */
++};
++
++enum rcar_csi2_link {
++ RCAR_CSI2_LINK_CSI40,
++ RCAR_CSI2_LINK_CSI20,
++ RCAR_CSI2_LINK_CSI41,
++ RCAR_CSI2_LINK_CSI21,
++};
++
++enum rcar_csi2_type {
++ RCAR_CSI2_CSI4X,
++ RCAR_CSI2_CSI2X,
++};
++
++#define RCAR_CSI2_CRC (1 << 0)
++#define RCAR_CSI2_ECC (1 << 1)
++
++struct platform_device;
++
++struct rcar_csi2_client_config {
++ enum rcar_csi2_phy phy;
++ enum rcar_csi2_link link;
++ unsigned char lanes; /* bitmask[3:0] */
++ unsigned char channel; /* 0..3 */
++ struct platform_device *pdev; /* client platform device */
++ const char *name; /* async matching: client name */
++};
++
++struct v4l2_device;
++
++struct rcar_csi2_pdata {
++ enum rcar_csi2_type type;
++ unsigned int flags;
++ struct rcar_csi2_client_config *clients;
++ int num_clients;
++};
++
++#endif
+--
+2.7.4
+
diff --git a/bsp/meta-rcar/meta-rcar-gen3-adas/recipes-kernel/linux/linux-renesas/0018-arm64-renesas-r8a7797-Add-Renesas-R8A7797-SoC-suppor.patch b/bsp/meta-rcar/meta-rcar-gen3-adas/recipes-kernel/linux/linux-renesas/0018-arm64-renesas-r8a7797-Add-Renesas-R8A7797-SoC-suppor.patch
new file mode 100644
index 00000000..1f2b11c7
--- /dev/null
+++ b/bsp/meta-rcar/meta-rcar-gen3-adas/recipes-kernel/linux/linux-renesas/0018-arm64-renesas-r8a7797-Add-Renesas-R8A7797-SoC-suppor.patch
@@ -0,0 +1,5340 @@
+From e8fd03e53c50c67a2aebf19f39a9f14b583f0e2d Mon Sep 17 00:00:00 2001
+From: Vladimir Barinov <vladimir.barinov@cogentembedded.com>
+Date: Sun, 14 May 2017 14:48:08 +0300
+Subject: [PATCH] arm64: renesas: r8a7797: Add Renesas R8A7797 SoC support
+
+This adds Renesas R8A7797 SoC support
+
+Signed-off-by: Vladimir Barinov <vladimir.barinov@cogentembedded.com>
+---
+ arch/arm64/Kconfig.platforms | 8 +
+ arch/arm64/boot/dts/renesas/r8a7797.dtsi | 1156 +++++++++++
+ drivers/clk/renesas/Kconfig | 1 +
+ drivers/clk/renesas/Makefile | 1 +
+ drivers/clk/renesas/r8a7797-cpg-mssr.c | 232 +++
+ drivers/clk/renesas/rcar-gen3-cpg.c | 41 +-
+ drivers/clk/renesas/rcar-gen3-cpg.h | 6 +
+ drivers/clk/renesas/renesas-cpg-mssr.c | 6 +
+ drivers/clk/renesas/renesas-cpg-mssr.h | 1 +
+ drivers/cpufreq/cpufreq-dt-platdev.c | 1 +
+ drivers/gpio/gpio-rcar.c | 6 +-
+ drivers/gpu/drm/rcar-du/rcar_du_drv.c | 25 +
+ drivers/gpu/drm/rcar-du/rcar_du_group.c | 12 +-
+ drivers/gpu/drm/rcar-du/rcar_du_lvdsenc.c | 38 +-
+ drivers/i2c/busses/i2c-rcar.c | 1 +
+ drivers/iommu/ipmmu-vmsa.c | 7 +-
+ drivers/media/platform/soc_camera/Kconfig | 2 +-
+ drivers/media/platform/soc_camera/rcar_csi2.c | 26 +-
+ drivers/media/platform/soc_camera/rcar_vin.c | 86 +-
+ drivers/media/platform/vsp1/vsp1_drv.c | 9 +
+ drivers/media/platform/vsp1/vsp1_lif.c | 12 +-
+ drivers/media/platform/vsp1/vsp1_regs.h | 7 +
+ drivers/mmc/host/sh_mobile_sdhi.c | 1 +
+ drivers/net/ethernet/renesas/ravb_main.c | 1 +
+ drivers/pinctrl/sh-pfc/Kconfig | 5 +
+ drivers/pinctrl/sh-pfc/Makefile | 1 +
+ drivers/pinctrl/sh-pfc/core.c | 7 +
+ drivers/pinctrl/sh-pfc/pfc-r8a7797.c | 2628 +++++++++++++++++++++++++
+ drivers/pinctrl/sh-pfc/sh_pfc.h | 12 +
+ drivers/soc/renesas/Makefile | 4 +
+ drivers/soc/renesas/r8a7797-sysc.c | 39 +
+ drivers/soc/renesas/rcar-rst.c | 1 +
+ drivers/soc/renesas/rcar-sysc.c | 3 +
+ drivers/soc/renesas/rcar-sysc.h | 1 +
+ drivers/soc/renesas/rcar_ems_ctrl.c | 10 +
+ drivers/soc/renesas/renesas-soc.c | 8 +
+ drivers/spi/spi-sh-msiof.c | 4 +-
+ drivers/thermal/rcar_gen3_thermal.c | 29 +
+ include/dt-bindings/clock/r8a7797-cpg-mssr.h | 48 +
+ include/dt-bindings/power/r8a7797-sysc.h | 32 +
+ 40 files changed, 4489 insertions(+), 29 deletions(-)
+ create mode 100644 arch/arm64/boot/dts/renesas/r8a7797.dtsi
+ create mode 100644 drivers/clk/renesas/r8a7797-cpg-mssr.c
+ create mode 100644 drivers/pinctrl/sh-pfc/pfc-r8a7797.c
+ create mode 100644 drivers/soc/renesas/r8a7797-sysc.c
+ create mode 100644 include/dt-bindings/clock/r8a7797-cpg-mssr.h
+ create mode 100644 include/dt-bindings/power/r8a7797-sysc.h
+
+diff --git a/arch/arm64/Kconfig.platforms b/arch/arm64/Kconfig.platforms
+index ebe0a37..9cebaad 100644
+--- a/arch/arm64/Kconfig.platforms
++++ b/arch/arm64/Kconfig.platforms
+@@ -166,6 +166,14 @@ config ARCH_R8A77965
+ help
+ This enables support for the Renesas R-Car M3N SoC.
+
++config ARCH_R8A7797
++ bool "Renesas R-Car V3M SoC Platform"
++ select SYS_SUPPORTS_SH_TMU
++ select SYS_SUPPORTS_SH_CMT
++ depends on ARCH_RENESAS
++ help
++ This enables support for the Renesas R-Car V3M SoC.
++
+ config ARCH_STRATIX10
+ bool "Altera's Stratix 10 SoCFPGA Family"
+ help
+diff --git a/arch/arm64/boot/dts/renesas/r8a7797.dtsi b/arch/arm64/boot/dts/renesas/r8a7797.dtsi
+new file mode 100644
+index 0000000..5319b1a
+--- /dev/null
++++ b/arch/arm64/boot/dts/renesas/r8a7797.dtsi
+@@ -0,0 +1,1156 @@
++/*
++ * Device Tree Source for the r8a7797 SoC
++ *
++ * Copyright (C) 2016 - 2017 Renesas Electronics Corp.
++ *
++ * This file is licensed under the terms of the GNU General Public License
++ * version 2. This program is licensed "as is" without any warranty of any
++ * kind, whether express or implied.
++ */
++
++#include <dt-bindings/clock/r8a7797-cpg-mssr.h>
++#include <dt-bindings/interrupt-controller/arm-gic.h>
++#include <dt-bindings/power/r8a7797-sysc.h>
++
++/ {
++ compatible = "renesas,r8a7797";
++ #address-cells = <2>;
++ #size-cells = <2>;
++
++ aliases {
++ csi2_40 = &csi2_40;
++ i2c0 = &i2c0;
++ i2c1 = &i2c1;
++ i2c2 = &i2c2;
++ i2c3 = &i2c3;
++ i2c4 = &i2c4;
++ spi1 = &msiof0;
++ spi2 = &msiof1;
++ spi3 = &msiof2;
++ spi4 = &msiof3;
++ vin0 = &vin0;
++ vin1 = &vin1;
++ vin2 = &vin2;
++ vin3 = &vin3;
++ tsc0 = &tsc1;
++ };
++
++ psci {
++ compatible = "arm,psci-1.0";
++ method = "smc";
++ };
++
++ cpus {
++ #address-cells = <1>;
++ #size-cells = <0>;
++
++ a53_0: cpu@0 {
++ compatible = "arm,cortex-a53", "arm,armv8";
++ reg = <0x0>;
++ device_type = "cpu";
++ power-domains = <&sysc R8A7797_PD_CA53_CPU0>;
++ next-level-cache = <&L2_CA53>;
++ enable-method = "psci";
++ cpu-idle-states = <&CPU_SLEEP_0>;
++ #cooling-cells = <2>;
++ dynamic-power-coefficient = <277>;
++ cooling-min-level = <0>;
++ cooling-max-level = <2>;
++ clocks =<&cpg CPG_CORE R8A7797_CLK_Z2>;
++ operating-points-v2 = <&cluster0_opp_tb0>;
++ /*cpu-supply = <&vdd_dvfs>;*/
++ };
++
++ a53_1: cpu@1 {
++ compatible = "arm,cortex-a53","arm,armv8";
++ reg = <0x1>;
++ device_type = "cpu";
++ power-domains = <&sysc R8A7797_PD_CA53_CPU1>;
++ next-level-cache = <&L2_CA53>;
++ enable-method = "psci";
++ cpu-idle-states = <&CPU_SLEEP_0>;
++ operating-points-v2 = <&cluster0_opp_tb0>;
++ };
++
++ idle-states {
++ entry-method = "psci";
++
++ CPU_SLEEP_0: cpu-sleep-0 {
++ compatible = "arm,idle-state";
++ arm,psci-suspend-param = <0x0010000>;
++ local-timer-stop;
++ entry-latency-us = <639>;
++ exit-latency-us = <680>;
++ min-residency-us = <1088>;
++ status = "disabled";
++ };
++ };
++ };
++
++ L2_CA53: cache-controller@1 {
++ compatible = "cache";
++ power-domains = <&sysc R8A7797_PD_CA53_SCU>;
++ cache-unified;
++ cache-level = <2>;
++ };
++
++ cluster0_opp_tb0: opp_table0 {
++ compatible = "operating-points-v2";
++ opp-shared;
++
++ opp@800000000 {
++ opp-hz = /bits/ 64 <800000000>;
++ opp-microvolt = <850000>;
++ clock-latency-ns = <300000>;
++ };
++ };
++
++ extal_clk: extal {
++ compatible = "fixed-clock";
++ #clock-cells = <0>;
++ /* This value must be overridden by the board */
++ clock-frequency = <0>;
++ };
++
++ extalr_clk: extalr {
++ compatible = "fixed-clock";
++ #clock-cells = <0>;
++ /* This value must be overridden by the board */
++ clock-frequency = <0>;
++ };
++
++ /* External CAN clock - to be overridden by boards that provide it */
++ can_clk: can {
++ compatible = "fixed-clock";
++ #clock-cells = <0>;
++ clock-frequency = <0>;
++ };
++
++ /* External SCIF clock - to be overridden by boards that provide it */
++ scif_clk: scif {
++ compatible = "fixed-clock";
++ #clock-cells = <0>;
++ clock-frequency = <0>;
++ };
++
++ /* DU input dot clock - tob be overriden by boards that probide it */
++ du_dotclkin0: dclkin-0 {
++ compatible = "fixed-clock";
++ #clock-cells = <0>;
++ clock-frequency = <148500000>;
++ };
++
++ soc {
++ compatible = "simple-bus";
++ interrupt-parent = <&gic>;
++
++ #address-cells = <2>;
++ #size-cells = <2>;
++ ranges;
++
++ gic: interrupt-controller@0xf1010000 {
++ compatible = "arm,gic-400";
++ #interrupt-cells = <3>;
++ #address-cells = <0>;
++ interrupt-controller;
++ reg = <0x0 0xf1010000 0 0x1000>,
++ <0x0 0xf1020000 0 0x20000>,
++ <0x0 0xf1040000 0 0x20000>,
++ <0x0 0xf1060000 0 0x20000>;
++ interrupts = <GIC_PPI 9
++ (GIC_CPU_MASK_SIMPLE(8) | IRQ_TYPE_LEVEL_HIGH)>; /* PPI9:Virtual maintenance interrupt */
++/* clocks = <&cpg CPG_MOD 408>;
++ clock-names = "clk";
++ power-domains = <&sysc R8A7797_PD_ALWAYS_ON>; */
++ };
++
++ gpio0: gpio@e6050000 {
++ compatible = "renesas,gpio-r8a7797",
++ "renesas,gpio-rcar";
++ reg = <0 0xe6050000 0 0x50>;
++ interrupts = <GIC_SPI 4 IRQ_TYPE_LEVEL_HIGH>; /* SPI4:GPIO.ch0 */
++ #gpio-cells = <2>;
++ gpio-controller;
++ gpio-ranges = <&pfc 0 0 22>;
++ #interrupt-cells = <2>;
++ interrupt-controller;
++ clocks = <&cpg CPG_MOD 912>; /* RMSTPCR9/bit12:GPIO0 */
++ power-domains = <&sysc R8A7797_PD_ALWAYS_ON>;
++ };
++
++ gpio1: gpio@e6051000 {
++ compatible = "renesas,gpio-r8a7797",
++ "renesas,gpio-rcar";
++ reg = <0 0xe6051000 0 0x50>;
++ interrupts = <GIC_SPI 5 IRQ_TYPE_LEVEL_HIGH>; /* SPI5:GPIO.ch1 */
++ #gpio-cells = <2>;
++ gpio-controller;
++ gpio-ranges = <&pfc 0 32 28>;
++ #interrupt-cells = <2>;
++ interrupt-controller;
++ clocks = <&cpg CPG_MOD 911>; /* RMSTPCR9/bit11:GPIO1 */
++ power-domains = <&sysc R8A7797_PD_ALWAYS_ON>;
++ };
++
++ gpio2: gpio@e6052000 {
++ compatible = "renesas,gpio-r8a7797",
++ "renesas,gpio-rcar";
++ reg = <0 0xe6052000 0 0x50>;
++ interrupts = <GIC_SPI 6 IRQ_TYPE_LEVEL_HIGH>; /* SPI6:GPIO.ch2 */
++ #gpio-cells = <2>;
++ gpio-controller;
++ gpio-ranges = <&pfc 0 64 17>;
++ #interrupt-cells = <2>;
++ interrupt-controller;
++ clocks = <&cpg CPG_MOD 910>; /* RMSTPCR9/bit10:GPIO2 */
++ power-domains = <&sysc R8A7797_PD_ALWAYS_ON>;
++ };
++
++ gpio3: gpio@e6053000 {
++ compatible = "renesas,gpio-r8a7797",
++ "renesas,gpio-rcar";
++ reg = <0 0xe6053000 0 0x50>;
++ interrupts = <GIC_SPI 7 IRQ_TYPE_LEVEL_HIGH>; /* SPI7:GPIO.ch3 */
++ #gpio-cells = <2>;
++ gpio-controller;
++ gpio-ranges = <&pfc 0 96 17>;
++ #interrupt-cells = <2>;
++ interrupt-controller;
++ clocks = <&cpg CPG_MOD 909>; /* RMSTPCR9/bit9:GPIO3 */
++ power-domains = <&sysc R8A7797_PD_ALWAYS_ON>;
++ };
++
++ gpio4: gpio@e6054000 {
++ compatible = "renesas,gpio-r8a7797",
++ "renesas,gpio-rcar";
++ reg = <0 0xe6054000 0 0x50>;
++ interrupts = <GIC_SPI 8 IRQ_TYPE_LEVEL_HIGH>; /* SPI8:GPIO.ch4 */
++ #gpio-cells = <2>;
++ gpio-controller;
++ gpio-ranges = <&pfc 0 128 6>;
++ #interrupt-cells = <2>;
++ interrupt-controller;
++ clocks = <&cpg CPG_MOD 908>; /* RMSTPCR9/bit8:GPIO4 */
++ power-domains = <&sysc R8A7797_PD_ALWAYS_ON>;
++ };
++
++ gpio5: gpio@e6055000 {
++ compatible = "renesas,gpio-r8a7797",
++ "renesas,gpio-rcar";
++ reg = <0 0xe6055000 0 0x50>;
++ interrupts = <GIC_SPI 9 IRQ_TYPE_LEVEL_HIGH>; /* SPI9:GPIO.ch5 */
++ #gpio-cells = <2>;
++ gpio-controller;
++ gpio-ranges = <&pfc 0 160 15>;
++ #interrupt-cells = <2>;
++ interrupt-controller;
++ clocks = <&cpg CPG_MOD 907>; /* RMSTPCR9/bit7:GPIO5 */
++ power-domains = <&sysc R8A7797_PD_ALWAYS_ON>;
++ };
++
++ pmu_a53 {
++ compatible = "arm,cortex-a53-pmu";
++ interrupts = <GIC_SPI 84 IRQ_TYPE_LEVEL_HIGH>,
++ <GIC_SPI 85 IRQ_TYPE_LEVEL_HIGH>; /* SPI84:AP-System Core.CA53core0 pmu, SPI85:AP-System Core.CA53core1 pmu */
++ interrupt-affinity = <&a53_0>,
++ <&a53_1>;
++ };
++
++ timer {
++ compatible = "arm,armv8-timer";
++ interrupts = <GIC_PPI 13
++ (GIC_CPU_MASK_SIMPLE(8) | IRQ_TYPE_LEVEL_LOW)>,
++ <GIC_PPI 14
++ (GIC_CPU_MASK_SIMPLE(8) | IRQ_TYPE_LEVEL_LOW)>,
++ <GIC_PPI 11
++ (GIC_CPU_MASK_SIMPLE(8) | IRQ_TYPE_LEVEL_LOW)>,
++ <GIC_PPI 10
++ (GIC_CPU_MASK_SIMPLE(8) | IRQ_TYPE_LEVEL_LOW)>; /* PPI13:Secure physical timer, PPI14:Non-secure physical timer,
++ PPI11:Virtual timer, PPI10:Hypervisor timer */
++ };
++
++ wdt0: wdt@e6020000 {
++ compatible = "renesas,r8a7797-wdt", "renesas,rcar-gen3-wdt";
++ reg = <0 0xe6020000 0 0x0c>;
++ clocks = <&cpg CPG_MOD 402>; /* RMSTPCR4/bit2:RWDT */
++ power-domains = <&sysc R8A7797_PD_ALWAYS_ON>;
++ status = "disabled";
++ };
++
++ cpg: clock-controller@e6150000 {
++ compatible = "renesas,r8a7797-cpg-mssr";
++ reg = <0 0xe6150000 0 0x1000>;
++ clocks = <&extal_clk>, <&extalr_clk>;
++ clock-names = "extal", "extalr";
++ #clock-cells = <2>;
++ #power-domain-cells = <0>;
++ };
++
++ csi2_40: csi2@feaa0000 {
++ compatible = "renesas,r8a7797-csi2";
++ reg = <0 0xfeaa0000 0 0x10000>;
++ interrupts = <GIC_SPI 246 IRQ_TYPE_LEVEL_HIGH>; /* SPI246:CSI2.ch2 */
++ clocks = <&cpg CPG_MOD 716>; /* RMSTPCR7/bit16:CSI40 */
++ power-domains = <&sysc R8A7797_PD_ALWAYS_ON>;
++ status = "disabled";
++ };
++
++ prr: chipid@fff00044 {
++ compatible = "renesas,prr";
++ reg = <0 0xfff00044 0 4>;
++ };
++
++ rst: reset-controller@e6160000 {
++ compatible = "renesas,r8a7797-rst";
++ reg = <0 0xe6160000 0 0x0200>;
++ };
++
++ sysc: system-controller@e6180000 {
++ compatible = "renesas,r8a7797-sysc";
++ reg = <0 0xe6180000 0 0x0440>;
++ #power-domain-cells = <1>;
++ };
++
++ pfc: pfc@e6060000 {
++ compatible = "renesas,pfc-r8a7797";
++ reg = <0 0xe6060000 0 0x50c>;
++ };
++
++ intc_ex: interrupt-controller@e61c0000 {
++ compatible = "renesas,intc-ex-r8a7797", "renesas,irqc";
++ #interrupt-cells = <2>;
++ interrupt-controller;
++ reg = <0 0xe61c0000 0 0x200>;
++ interrupts = <GIC_SPI 0 IRQ_TYPE_LEVEL_HIGH
++ GIC_SPI 1 IRQ_TYPE_LEVEL_HIGH
++ GIC_SPI 2 IRQ_TYPE_LEVEL_HIGH
++ GIC_SPI 3 IRQ_TYPE_LEVEL_HIGH
++ GIC_SPI 18 IRQ_TYPE_LEVEL_HIGH
++ GIC_SPI 161 IRQ_TYPE_LEVEL_HIGH>; /* SPI1:IRQ1, SPI2:IRQ2, SPI3:IRQ3, SPI18:IRQ4, SPI161:IRQ5 */
++ clocks = <&cpg CPG_MOD 407>; /* RMSTPCR4/bit7:INTC-EX */
++ power-domains = <&sysc R8A7797_PD_ALWAYS_ON>;
++ };
++
++ ipmmu_vi: mmu@febd0000 {
++ compatible = "renesas,ipmmu-r8a7797";
++ reg = <0 0xfebd0000 0 0x1000>; /* IPMMU-VI */
++ renesas,ipmmu-main = <&ipmmu_mm 11>;
++ #iommu-cells = <1>;
++ status = "disabled";
++ };
++
++ ipmmu_ir: mmu@ff8b0000 {
++ compatible = "renesas,ipmmu-r8a7797";
++ reg = <0 0xff8b0000 0 0x1000>; /* IPMMU-IR */
++ renesas,ipmmu-main = <&ipmmu_mm 3>;
++ #iommu-cells = <1>;
++ status = "disabled";
++ };
++
++ ipmmu_rt: mmu@ffc80000 {
++ compatible = "renesas,ipmmu-r8a7797";
++ reg = <0 0xffc80000 0 0x1000>; /* IPMMU-RT */
++ renesas,ipmmu-main = <&ipmmu_mm 7>;
++ #iommu-cells = <1>;
++ status = "disabled";
++ };
++
++ ipmmu_ds0: mmu@e6740000 {
++ compatible = "renesas,ipmmu-r8a7797";
++ reg = <0 0xe6740000 0 0x1000>; /* IPMMU-DS0 */
++ renesas,ipmmu-main = <&ipmmu_mm 0>;
++ #iommu-cells = <1>;
++ status = "disabled";
++ };
++
++ ipmmu_mm: mmu@e67b0000 {
++ compatible = "renesas,ipmmu-r8a7797";
++ reg = <0 0xe67b0000 0 0x1000>; /* IPMMU-MM */
++ interrupts = <GIC_SPI 196 IRQ_TYPE_LEVEL_HIGH>,
++ <GIC_SPI 197 IRQ_TYPE_LEVEL_HIGH>; /* SPI196:IPMMU, SPI197:IPMMU sec */
++ #iommu-cells = <1>;
++ status = "disabled";
++ };
++
++ dmac1: dma-controller@e7300000 {
++ compatible = "renesas,dmac-r8a7797",
++ "renesas,rcar-dmac";
++ reg = <0 0xe7300000 0 0x10000>;
++ interrupts = <GIC_SPI 220 IRQ_TYPE_LEVEL_HIGH
++ GIC_SPI 216 IRQ_TYPE_LEVEL_HIGH
++ GIC_SPI 217 IRQ_TYPE_LEVEL_HIGH
++ GIC_SPI 218 IRQ_TYPE_LEVEL_HIGH
++ GIC_SPI 219 IRQ_TYPE_LEVEL_HIGH
++ GIC_SPI 308 IRQ_TYPE_LEVEL_HIGH
++ GIC_SPI 309 IRQ_TYPE_LEVEL_HIGH
++ GIC_SPI 310 IRQ_TYPE_LEVEL_HIGH
++ GIC_SPI 311 IRQ_TYPE_LEVEL_HIGH>; /* SPI220::SYS-DMAC1 err,
++ SPI216~219:SYS-DMAC1.ch0~SYS-DMAC1.ch3,
++ SPI308~311:SYS-DMAC1.ch4~SYS-DMAC1.ch7 */
++ interrupt-names = "error",
++ "ch0", "ch1", "ch2", "ch3",
++ "ch4", "ch5", "ch6", "ch7";
++ clocks = <&cpg CPG_MOD 218>; /* RMSTPCR2/bit18:SYS-DMAC1 */
++ clock-names = "fck";
++ power-domains = <&sysc R8A7797_PD_ALWAYS_ON>;
++ #dma-cells = <1>;
++ dma-channels = <8>;
++ iommus = <&ipmmu_ds0 0>, <&ipmmu_ds0 1>,
++ <&ipmmu_ds0 2>, <&ipmmu_ds0 3>,
++ <&ipmmu_ds0 4>, <&ipmmu_ds0 5>,
++ <&ipmmu_ds0 6>, <&ipmmu_ds0 7>; /* @@ */
++ };
++
++ dmac2: dma-controller@e7310000 {
++ compatible = "renesas,dmac-r8a7797",
++ "renesas,rcar-dmac";
++ reg = <0 0xe7310000 0 0x10000>;
++ interrupts = <GIC_SPI 307 IRQ_TYPE_LEVEL_HIGH
++ GIC_SPI 312 IRQ_TYPE_LEVEL_HIGH
++ GIC_SPI 313 IRQ_TYPE_LEVEL_HIGH
++ GIC_SPI 314 IRQ_TYPE_LEVEL_HIGH
++ GIC_SPI 315 IRQ_TYPE_LEVEL_HIGH
++ GIC_SPI 316 IRQ_TYPE_LEVEL_HIGH
++ GIC_SPI 317 IRQ_TYPE_LEVEL_HIGH
++ GIC_SPI 318 IRQ_TYPE_LEVEL_HIGH
++ GIC_SPI 319 IRQ_TYPE_LEVEL_HIGH>; /* SPI307::SYS-DMAC2 err,
++ SPI312~319:SYS-DMAC2.ch0~SYS-DMAC1.ch7 */
++ interrupt-names = "error",
++ "ch0", "ch1", "ch2", "ch3",
++ "ch4", "ch5", "ch6", "ch7";
++ clocks = <&cpg CPG_MOD 217>; /* RMSTPCR2/bit17:SYS-DMAC2 */
++ clock-names = "fck";
++ power-domains = <&sysc R8A7797_PD_ALWAYS_ON>;
++ #dma-cells = <1>;
++ dma-channels = <8>;
++ iommus = <&ipmmu_ds0 16>, <&ipmmu_ds0 17>,
++ <&ipmmu_ds0 18>, <&ipmmu_ds0 19>,
++ <&ipmmu_ds0 20>, <&ipmmu_ds0 21>,
++ <&ipmmu_ds0 22>, <&ipmmu_ds0 23>; /* @@ */
++ };
++
++ avb: ethernet@e6800000 {
++ compatible = "renesas,etheravb-r8a7797",
++ "renesas,etheravb-rcar-gen3";
++ reg = <0 0xe6800000 0 0x800>, <0 0xe6a00000 0 0x10000>;
++ interrupts = <GIC_SPI 39 IRQ_TYPE_LEVEL_HIGH>,
++ <GIC_SPI 40 IRQ_TYPE_LEVEL_HIGH>,
++ <GIC_SPI 41 IRQ_TYPE_LEVEL_HIGH>,
++ <GIC_SPI 42 IRQ_TYPE_LEVEL_HIGH>,
++ <GIC_SPI 43 IRQ_TYPE_LEVEL_HIGH>,
++ <GIC_SPI 44 IRQ_TYPE_LEVEL_HIGH>,
++ <GIC_SPI 45 IRQ_TYPE_LEVEL_HIGH>,
++ <GIC_SPI 46 IRQ_TYPE_LEVEL_HIGH>,
++ <GIC_SPI 47 IRQ_TYPE_LEVEL_HIGH>,
++ <GIC_SPI 48 IRQ_TYPE_LEVEL_HIGH>,
++ <GIC_SPI 49 IRQ_TYPE_LEVEL_HIGH>,
++ <GIC_SPI 50 IRQ_TYPE_LEVEL_HIGH>,
++ <GIC_SPI 51 IRQ_TYPE_LEVEL_HIGH>,
++ <GIC_SPI 52 IRQ_TYPE_LEVEL_HIGH>,
++ <GIC_SPI 53 IRQ_TYPE_LEVEL_HIGH>,
++ <GIC_SPI 54 IRQ_TYPE_LEVEL_HIGH>,
++ <GIC_SPI 55 IRQ_TYPE_LEVEL_HIGH>,
++ <GIC_SPI 56 IRQ_TYPE_LEVEL_HIGH>,
++ <GIC_SPI 57 IRQ_TYPE_LEVEL_HIGH>,
++ <GIC_SPI 58 IRQ_TYPE_LEVEL_HIGH>,
++ <GIC_SPI 59 IRQ_TYPE_LEVEL_HIGH>,
++ <GIC_SPI 60 IRQ_TYPE_LEVEL_HIGH>,
++ <GIC_SPI 61 IRQ_TYPE_LEVEL_HIGH>,
++ <GIC_SPI 62 IRQ_TYPE_LEVEL_HIGH>,
++ <GIC_SPI 63 IRQ_TYPE_LEVEL_HIGH>; /* SPI39~63:Ethernet AVB.ch0~24 */
++ /* @@ errreq_avb_p[0]~[3] add (T.B.D) */
++ interrupt-names = "ch0", "ch1", "ch2", "ch3",
++ "ch4", "ch5", "ch6", "ch7",
++ "ch8", "ch9", "ch10", "ch11",
++ "ch12", "ch13", "ch14", "ch15",
++ "ch16", "ch17", "ch18", "ch19",
++ "ch20", "ch21", "ch22", "ch23",
++ "ch24";
++ clocks = <&cpg CPG_MOD 812>; /* RMSTPCR8/bit12:EAVB-IF */
++ power-domains = <&sysc R8A7797_PD_ALWAYS_ON>;
++ phy-mode = "rgmii-id";
++ #address-cells = <1>;
++ #size-cells = <0>;
++ };
++
++ canfd: canfd@e66c0000 {
++ compatible = "renesas,r8a7797-canfd",
++ "renesas,rcar-gen3-canfd";
++ reg = <0 0xe66c0000 0 0x8000>;
++ interrupts = <GIC_SPI 29 IRQ_TYPE_LEVEL_HIGH>,
++ <GIC_SPI 30 IRQ_TYPE_LEVEL_HIGH>;
++ clocks = <&cpg CPG_MOD 914>,
++ <&cpg CPG_CORE R8A7797_CLK_CANFD>,
++ <&can_clk>;
++ clock-names = "fck", "canfd", "can_clk";
++ assigned-clocks = <&cpg CPG_CORE R8A7797_CLK_CANFD>;
++ assigned-clock-rates = <40000000>;
++ power-domains = <&sysc R8A7797_PD_ALWAYS_ON>;
++ status = "disabled";
++
++ channel0 {
++ status = "disabled";
++ };
++
++ channel1 {
++ status = "disabled";
++ };
++ };
++
++ cmt0: timer@e60f0000 {
++ compatible = "renesas,cmt-48-r8a7797", "renesas,cmt-48-gen2";
++ reg = <0 0xe60f0000 0 0x1004>;
++ interrupts = <GIC_SPI 142 IRQ_TYPE_LEVEL_HIGH>,
++ <GIC_SPI 143 IRQ_TYPE_LEVEL_HIGH>;
++ clocks = <&cpg CPG_MOD 303>;
++ clock-names = "fck";
++ power-domains = <&sysc R8A7797_PD_ALWAYS_ON>;
++
++ renesas,channels-mask = <0x60>;
++
++ status = "disabled";
++ };
++
++ cmt1: timer@e6130000 {
++ compatible = "renesas,cmt-48-r8a7797", "renesas,cmt-48-gen2";
++ reg = <0 0xe6130000 0 0x1004>;
++ interrupts = <GIC_SPI 120 IRQ_TYPE_LEVEL_HIGH>,
++ <GIC_SPI 121 IRQ_TYPE_LEVEL_HIGH>,
++ <GIC_SPI 122 IRQ_TYPE_LEVEL_HIGH>,
++ <GIC_SPI 123 IRQ_TYPE_LEVEL_HIGH>,
++ <GIC_SPI 124 IRQ_TYPE_LEVEL_HIGH>,
++ <GIC_SPI 125 IRQ_TYPE_LEVEL_HIGH>,
++ <GIC_SPI 126 IRQ_TYPE_LEVEL_HIGH>,
++ <GIC_SPI 127 IRQ_TYPE_LEVEL_HIGH>;
++ clocks = <&cpg CPG_MOD 302>;
++ clock-names = "fck";
++ power-domains = <&sysc R8A7797_PD_ALWAYS_ON>;
++
++ renesas,channels-mask = <0xff>;
++
++ status = "disabled";
++ };
++
++ cmt2: timer@e6140000 {
++ compatible = "renesas,cmt-48-r8a7797", "renesas,cmt-48-gen2";
++ reg = <0 0xe6140000 0 0x1004>;
++ interrupts = <GIC_SPI 258 IRQ_TYPE_LEVEL_HIGH>,
++ <GIC_SPI 259 IRQ_TYPE_LEVEL_HIGH>,
++ <GIC_SPI 260 IRQ_TYPE_LEVEL_HIGH>,
++ <GIC_SPI 261 IRQ_TYPE_LEVEL_HIGH>,
++ <GIC_SPI 262 IRQ_TYPE_LEVEL_HIGH>,
++ <GIC_SPI 263 IRQ_TYPE_LEVEL_HIGH>,
++ <GIC_SPI 264 IRQ_TYPE_LEVEL_HIGH>,
++ <GIC_SPI 265 IRQ_TYPE_LEVEL_HIGH>;
++ clocks = <&cpg CPG_MOD 301>;
++ clock-names = "fck";
++ power-domains = <&sysc R8A7797_PD_ALWAYS_ON>;
++
++ renesas,channels-mask = <0xff>;
++
++ status = "disabled";
++ };
++
++ cmt3: timer@e6148000 {
++ compatible = "renesas,cmt-48-r8a7797", "renesas,cmt-48-gen2";
++ reg = <0 0xe6148000 0 0x1004>;
++ interrupts = <GIC_SPI 273 IRQ_TYPE_LEVEL_HIGH>,
++ <GIC_SPI 274 IRQ_TYPE_LEVEL_HIGH>,
++ <GIC_SPI 275 IRQ_TYPE_LEVEL_HIGH>,
++ <GIC_SPI 276 IRQ_TYPE_LEVEL_HIGH>,
++ <GIC_SPI 277 IRQ_TYPE_LEVEL_HIGH>,
++ <GIC_SPI 278 IRQ_TYPE_LEVEL_HIGH>,
++ <GIC_SPI 279 IRQ_TYPE_LEVEL_HIGH>,
++ <GIC_SPI 280 IRQ_TYPE_LEVEL_HIGH>;
++ clocks = <&cpg CPG_MOD 300>;
++ clock-names = "fck";
++ power-domains = <&sysc R8A7797_PD_ALWAYS_ON>;
++
++ renesas,channels-mask = <0xff>;
++
++ status = "disabled";
++ };
++
++ tpu: pwm@e6e80000 {
++ compatible = "renesas,tpu-r8a7797", "renesas,tpu";
++ reg = <0 0xe6e80000 0 0x100>;
++ clocks = <&cpg CPG_MOD 304>;
++ power-domains = <&sysc R8A7797_PD_ALWAYS_ON>;
++ status = "disabled";
++ #pwm-cells = <4>;
++ };
++
++ tmu0: timer@e61e0000 {
++ compatible = "renesas,tmu-r8a7797", "renesas,tmu";
++ reg = <0 0xe61e0000 0 0x30>;
++ interrupts = <GIC_SPI 136 IRQ_TYPE_LEVEL_HIGH>,
++ <GIC_SPI 137 IRQ_TYPE_LEVEL_HIGH>,
++ <GIC_SPI 138 IRQ_TYPE_LEVEL_HIGH>;
++ clocks = <&cpg CPG_MOD 125>;
++ clock-names = "fck";
++ power-domains = <&sysc R8A7797_PD_ALWAYS_ON>;
++ #renesas,channels = <3>;
++ status = "disabled";
++ };
++
++ tmu1: timer@e6fc0000 {
++ compatible = "renesas,tmu-r8a7797", "renesas,tmu";
++ reg = <0 0xe6fc0000 0 0x30>;
++ interrupts = <GIC_SPI 128 IRQ_TYPE_LEVEL_HIGH>,
++ <GIC_SPI 129 IRQ_TYPE_LEVEL_HIGH>,
++ <GIC_SPI 130 IRQ_TYPE_LEVEL_HIGH>,
++ <GIC_SPI 147 IRQ_TYPE_LEVEL_HIGH>;
++ clocks = <&cpg CPG_MOD 124>;
++ clock-names = "fck";
++ power-domains = <&sysc R8A7797_PD_ALWAYS_ON>;
++ #renesas,channels = <3>;
++ status = "disabled";
++ };
++
++ tmu2: timer@e6fd0000 {
++ compatible = "renesas,tmu-r8a7797", "renesas,tmu";
++ reg = <0 0xe6fd0000 0 0x30>;
++ interrupts = <GIC_SPI 303 IRQ_TYPE_LEVEL_HIGH>,
++ <GIC_SPI 304 IRQ_TYPE_LEVEL_HIGH>,
++ <GIC_SPI 305 IRQ_TYPE_LEVEL_HIGH>,
++ <GIC_SPI 306 IRQ_TYPE_LEVEL_HIGH>;
++ clocks = <&cpg CPG_MOD 123>;
++ clock-names = "fck";
++ power-domains = <&sysc R8A7797_PD_ALWAYS_ON>;
++ #renesas,channels = <3>;
++ status = "disabled";
++ };
++
++ tmu3: timer@e6fe0000 {
++ compatible = "renesas,tmu-r8a7797", "renesas,tmu";
++ reg = <0 0xe6fe0000 0 0x30>;
++ interrupts = <GIC_SPI 131 IRQ_TYPE_LEVEL_HIGH>,
++ <GIC_SPI 132 IRQ_TYPE_LEVEL_HIGH>,
++ <GIC_SPI 133 IRQ_TYPE_LEVEL_HIGH>,
++ <GIC_SPI 146 IRQ_TYPE_LEVEL_HIGH>;
++ clocks = <&cpg CPG_MOD 122>;
++ clock-names = "fck";
++ power-domains = <&sysc R8A7797_PD_ALWAYS_ON>;
++ #renesas,channels = <3>;
++ status = "disabled";
++ };
++
++ tmu4: timer@ffc00000 {
++ compatible = "renesas,tmu-r8a7797", "renesas,tmu";
++ reg = <0 0xffc00000 0 0x30>;
++ interrupts = <GIC_SPI 116 IRQ_TYPE_LEVEL_HIGH>,
++ <GIC_SPI 117 IRQ_TYPE_LEVEL_HIGH>,
++ <GIC_SPI 118 IRQ_TYPE_LEVEL_HIGH>,
++ <GIC_SPI 369 IRQ_TYPE_LEVEL_HIGH>;
++ clocks = <&cpg CPG_MOD 121>;
++ clock-names = "fck";
++ power-domains = <&sysc R8A7797_PD_ALWAYS_ON>;
++ #renesas,channels = <3>;
++ status = "disabled";
++ };
++
++ pwm0: pwm@e6e30000 {
++ compatible = "renesas,pwm-r8a7797", "renesas,pwm-rcar";
++ reg = <0 0xe6e30000 0 0x10>;
++ #pwm-cells = <2>;
++ clocks = <&cpg CPG_MOD 523>; /* RMSTPCR5/bit23:PWM */
++ power-domains = <&sysc R8A7797_PD_ALWAYS_ON>;
++ status = "disabled";
++ };
++
++ pwm1: pwm@e6e31000 {
++ compatible = "renesas,pwm-r8a7797", "renesas,pwm-rcar";
++ reg = <0 0xe6e31000 0 0x10>;
++ #pwm-cells = <2>;
++ clocks = <&cpg CPG_MOD 523>; /* RMSTPCR5/bit23:PWM */
++ power-domains = <&sysc R8A7797_PD_ALWAYS_ON>;
++ status = "disabled";
++ };
++
++ pwm2: pwm@e6e32000 {
++ compatible = "renesas,pwm-r8a7797", "renesas,pwm-rcar";
++ reg = <0 0xe6e32000 0 0x10>;
++ #pwm-cells = <2>;
++ clocks = <&cpg CPG_MOD 523>; /* RMSTPCR5/bit23:PWM */
++ power-domains = <&sysc R8A7797_PD_ALWAYS_ON>;
++ status = "disabled";
++ };
++
++ pwm3: pwm@e6e33000 {
++ compatible = "renesas,pwm-r8a7797", "renesas,pwm-rcar";
++ reg = <0 0xe6e33000 0 0x10>;
++ #pwm-cells = <2>;
++ clocks = <&cpg CPG_MOD 523>; /* RMSTPCR5/bit23:PWM */
++ power-domains = <&sysc R8A7797_PD_ALWAYS_ON>;
++ status = "disabled";
++ };
++
++ pwm4: pwm@e6e34000 {
++ compatible = "renesas,pwm-r8a7797", "renesas,pwm-rcar";
++ reg = <0 0xe6e34000 0 0x10>;
++ #pwm-cells = <2>;
++ clocks = <&cpg CPG_MOD 523>; /* RMSTPCR5/bit23:PWM */
++ power-domains = <&sysc R8A7797_PD_ALWAYS_ON>;
++ status = "disabled";
++ };
++
++ hscif0: serial@e6540000 {
++ compatible = "renesas,hscif-r8a7797",
++ "renesas,rcar-gen3-hscif",
++ "renesas,hscif";
++ reg = <0 0xe6540000 0 96>;
++ interrupts = <GIC_SPI 154 IRQ_TYPE_LEVEL_HIGH>; /* SPI154:HSCIF.ch0 */
++ clocks = <&cpg CPG_MOD 520>,
++ <&cpg CPG_CORE R8A7797_CLK_S2D1>,
++ <&scif_clk>; /* RMSTPCR5/bit20:HSCIF0 */
++ clock-names = "fck", "brg_int", "scif_clk";
++ dmas = <&dmac1 0x31>, <&dmac1 0x30>;
++ dma-names = "tx", "rx";
++ power-domains = <&sysc R8A7797_PD_ALWAYS_ON>;
++ status = "disabled";
++ };
++
++ hscif1: serial@e6550000 {
++ compatible = "renesas,hscif-r8a7797",
++ "renesas,rcar-gen3-hscif",
++ "renesas,hscif";
++ reg = <0 0xe6550000 0 96>;
++ interrupts = <GIC_SPI 155 IRQ_TYPE_LEVEL_HIGH>; /* SPI155:HSCIF.ch1 */
++ clocks = <&cpg CPG_MOD 519>,
++ <&cpg CPG_CORE R8A7797_CLK_S2D1>,
++ <&scif_clk>; /* RMSTPCR5/bit19:HSCIF1 */
++ clock-names = "fck", "brg_int", "scif_clk";
++ dmas = <&dmac1 0x33>, <&dmac1 0x32>;
++ dma-names = "tx", "rx";
++ power-domains = <&sysc R8A7797_PD_ALWAYS_ON>;
++ status = "disabled";
++ };
++
++ hscif2: serial@e6560000 {
++ compatible = "renesas,hscif-r8a7797",
++ "renesas,rcar-gen3-hscif",
++ "renesas,hscif";
++ reg = <0 0xe6560000 0 96>;
++ interrupts = <GIC_SPI 144 IRQ_TYPE_LEVEL_HIGH>; /* SPI144:HSCIF.ch2 */
++ clocks = <&cpg CPG_MOD 518>,
++ <&cpg CPG_CORE R8A7797_CLK_S2D1>,
++ <&scif_clk>; /* RMSTPCR5/bit18:HSCIF2 */
++ clock-names = "fck", "brg_int", "scif_clk";
++ dmas = <&dmac1 0x35>, <&dmac1 0x34>;
++ dma-names = "tx", "rx";
++ power-domains = <&sysc R8A7797_PD_ALWAYS_ON>;
++ status = "disabled";
++ };
++
++ hscif3: serial@e66a0000 {
++ compatible = "renesas,hscif-r8a7797",
++ "renesas,rcar-gen3-hscif",
++ "renesas,hscif";
++ reg = <0 0xe66a0000 0 96>;
++ interrupts = <GIC_SPI 145 IRQ_TYPE_LEVEL_HIGH>; /* SPI145:HSCIF.ch3 */
++ clocks = <&cpg CPG_MOD 517>,
++ <&cpg CPG_CORE R8A7797_CLK_S2D1>,
++ <&scif_clk>; /* RMSTPCR5/bit17:HSCIF3 */
++ clock-names = "fck", "brg_int", "scif_clk";
++ dmas = <&dmac1 0x37>, <&dmac1 0x36>;
++ dma-names = "tx", "rx";
++ power-domains = <&sysc R8A7797_PD_ALWAYS_ON>;
++ status = "disabled";
++ };
++
++ scif0: serial@e6e60000 {
++ compatible = "renesas,scif-r8a7797",
++ "renesas,rcar-gen3-scif", "renesas,scif";
++ reg = <0 0xe6e60000 0 64>;
++ interrupts = <GIC_SPI 152 IRQ_TYPE_LEVEL_HIGH>; /* SPI152:SCIF.ch0 */
++ clocks = <&cpg CPG_MOD 207>,
++ <&cpg CPG_CORE R8A7797_CLK_S2D1>,
++ <&scif_clk>; /* RMSTPCR2/bit7:SCIF0 */
++ /*clock-names = "fck", "sck", "brg_int", "scif_clk"; */
++ clock-names = "fck";
++ dmas = <&dmac1 0x51>, <&dmac1 0x50>;
++ dma-names = "tx", "rx";
++ power-domains = <&sysc R8A7797_PD_ALWAYS_ON>;
++ status = "disabled";
++ };
++
++ scif1: serial@e6e68000 {
++ compatible = "renesas,scif-r8a7797",
++ "renesas,rcar-gen3-scif", "renesas,scif";
++ reg = <0 0xe6e68000 0 64>;
++ interrupts = <GIC_SPI 153 IRQ_TYPE_LEVEL_HIGH>; /* SPI153:SCIF.ch1 */
++ clocks = <&cpg CPG_MOD 206>,
++ <&cpg CPG_CORE R8A7797_CLK_S2D1>,
++ <&scif_clk>; /* RMSTPCR2/bit6:SCIF1 */
++ clock-names = "fck", "brg_int", "scif_clk";
++ dmas = <&dmac1 0x53>, <&dmac1 0x52>;
++ dma-names = "tx", "rx";
++ power-domains = <&sysc R8A7797_PD_ALWAYS_ON>;
++ status = "disabled";
++ };
++
++ scif3: serial@e6c50000 {
++ compatible = "renesas,scif-r8a7797",
++ "renesas,rcar-gen3-scif", "renesas,scif";
++ reg = <0 0xe6c50000 0 64>;
++ interrupts = <GIC_SPI 23 IRQ_TYPE_LEVEL_HIGH>; /* SPI23:SCIF.ch3 */
++ clocks = <&cpg CPG_MOD 204>,
++ <&cpg CPG_CORE R8A7797_CLK_S2D1>,
++ <&scif_clk>; /* RMSTPCR2/bit4:SCIF3 */
++ clock-names = "fck", "brg_int", "scif_clk";
++ dmas = <&dmac1 0x57>, <&dmac1 0x56>;
++ dma-names = "tx", "rx";
++ power-domains = <&sysc R8A7797_PD_ALWAYS_ON>;
++ status = "disabled";
++ };
++
++ scif4: serial@e6c40000 {
++ compatible = "renesas,scif-r8a7797",
++ "renesas,rcar-gen3-scif", "renesas,scif";
++ reg = <0 0xe6c40000 0 64>;
++ interrupts = <GIC_SPI 16 IRQ_TYPE_LEVEL_HIGH>; /* SPI16:SCIF.ch4 */
++ clocks = <&cpg CPG_MOD 203>,
++ <&cpg CPG_CORE R8A7797_CLK_S2D1>,
++ <&scif_clk>; /* RMSTPCR2/bit3:SCIF4 */
++ clock-names = "fck", "brg_int", "scif_clk";
++ dmas = <&dmac1 0x59>, <&dmac1 0x58>;
++ dma-names = "tx", "rx";
++ power-domains = <&sysc R8A7797_PD_ALWAYS_ON>;
++ status = "disabled";
++ };
++
++ i2c0: i2c@e6500000 {
++ #address-cells = <1>;
++ #size-cells = <0>;
++ compatible = "renesas,i2c-r8a7797";
++ reg = <0 0xe6500000 0 0x40>;
++ interrupts = <GIC_SPI 287 IRQ_TYPE_LEVEL_HIGH>; /* SPI287:I2C.ch0 */
++ clocks = <&cpg CPG_MOD 931>; /* RMSTPCR9/bit31:I2C-IF0 */
++ power-domains = <&sysc R8A7797_PD_ALWAYS_ON>;
++ dmas = <&dmac1 0x91>, <&dmac1 0x90>;
++ dma-names = "tx", "rx";
++ i2c-scl-internal-delay-ns = <6>;
++ status = "disabled";
++ };
++
++ i2c1: i2c@e6508000 {
++ #address-cells = <1>;
++ #size-cells = <0>;
++ compatible = "renesas,i2c-r8a7797";
++ reg = <0 0xe6508000 0 0x40>;
++ interrupts = <GIC_SPI 288 IRQ_TYPE_LEVEL_HIGH>; /* SPI288:I2C.ch1 */
++ clocks = <&cpg CPG_MOD 930>; /* RMSTPCR9/bit30:I2C-IF1 */
++ power-domains = <&sysc R8A7797_PD_ALWAYS_ON>;
++ dmas = <&dmac1 0x93>, <&dmac1 0x92>;
++ dma-names = "tx", "rx";
++ i2c-scl-internal-delay-ns = <6>;
++ status = "disabled";
++ };
++
++ i2c2: i2c@e6510000 {
++ #address-cells = <1>;
++ #size-cells = <0>;
++ compatible = "renesas,i2c-r8a7797";
++ reg = <0 0xe6510000 0 0x40>;
++ interrupts = <GIC_SPI 286 IRQ_TYPE_LEVEL_HIGH>; /* SPI286:I2C.ch2 */
++ clocks = <&cpg CPG_MOD 929>; /* RMSTPCR9/bit29:I2C-IF2 */
++ power-domains = <&sysc R8A7797_PD_ALWAYS_ON>;
++ dmas = <&dmac1 0x95>, <&dmac1 0x94>;
++ dma-names = "tx", "rx";
++ i2c-scl-internal-delay-ns = <6>;
++ status = "disabled";
++ };
++
++ i2c3: i2c@e66d0000 {
++ #address-cells = <1>;
++ #size-cells = <0>;
++ compatible = "renesas,i2c-r8a7797";
++ reg = <0 0xe66d0000 0 0x40>;
++ interrupts = <GIC_SPI 290 IRQ_TYPE_LEVEL_HIGH>; /* SPI290:I2C.ch3 */
++ clocks = <&cpg CPG_MOD 928>; /* RMSTPCR9/bit28:I2C-IF3 */
++ power-domains = <&sysc R8A7797_PD_ALWAYS_ON>;
++ dmas = <&dmac1 0x97>, <&dmac1 0x96>;
++ dma-names = "tx", "rx";
++ i2c-scl-internal-delay-ns = <6>;
++ status = "disabled";
++ };
++
++ i2c4: i2c@e66d8000 {
++ #address-cells = <1>;
++ #size-cells = <0>;
++ compatible = "renesas,i2c-r8a7797";
++ reg = <0 0xe66d8000 0 0x40>;
++ interrupts = <GIC_SPI 19 IRQ_TYPE_LEVEL_HIGH>; /* SPI19:I2C.ch4 */
++ clocks = <&cpg CPG_MOD 927>; /* RMSTPCR9/bit27:I2C-IF4 */
++ power-domains = <&sysc R8A7797_PD_ALWAYS_ON>;
++ dmas = <&dmac1 0x99>, <&dmac1 0x98>;
++ dma-names = "tx", "rx";
++ i2c-scl-internal-delay-ns = <6>;
++ status = "disabled";
++ };
++
++ msiof0: spi@e6e90000 {
++ #address-cells = <1>;
++ #size-cells = <0>;
++ compatible = "renesas,msiof-r8a7797";
++ reg = <0 0xe6e90000 0 0x64>;
++ interrupts = <GIC_SPI 156 IRQ_TYPE_LEVEL_HIGH>; /* SPI156:MSIOF.ch0 */
++ clocks = <&cpg CPG_MOD 211>, <&msiof_ref_clk>; /* RMSTPCR2/bit11:MSIOF0, @@ msiof_ref_clk->Eagle.dts */
++ clock-names = "msiof_clk", "msiof_ref_clk";
++ dmas = <&dmac1 0x41>, <&dmac1 0x40>;
++ dma-names = "tx", "rx";
++ power-domains = <&sysc R8A7797_PD_ALWAYS_ON>;
++ status = "disabled";
++ };
++
++ msiof1: spi@e6ea0000 {
++ #address-cells = <1>;
++ #size-cells = <0>;
++ compatible = "renesas,msiof-r8a7797";
++ reg = <0 0xe6ea0000 0 0x0064>;
++ interrupts = <GIC_SPI 157 IRQ_TYPE_LEVEL_HIGH>; /* SPI157:MSIOF.ch1 */
++ clocks = <&cpg CPG_MOD 210>, <&msiof_ref_clk>; /* RMSTPCR2/bit10:MSIOF1, @@ msiof_ref_clk->Eagle.dts */
++ clock-names = "msiof_clk", "msiof_ref_clk";
++ dmas = <&dmac1 0x43>, <&dmac1 0x42>;
++ dma-names = "tx", "rx";
++ power-domains = <&sysc R8A7797_PD_ALWAYS_ON>;
++ status = "disabled";
++ };
++
++ msiof2: spi@e6c00000 {
++ #address-cells = <1>;
++ #size-cells = <0>;
++ compatible = "renesas,msiof-r8a7797";
++ reg = <0 0xe6c00000 0 0x0064>;
++ interrupts = <GIC_SPI 158 IRQ_TYPE_LEVEL_HIGH>; /* SPI158:MSIOF.ch2 */
++ clocks = <&cpg CPG_MOD 209>, <&msiof_ref_clk>; /* RMSTPCR2/bit9:MSIOF2, @@ msiof_ref_clk->Eagle.dts */
++ clock-names = "msiof_clk", "msiof_ref_clk";
++ dmas = <&dmac1 0x45>, <&dmac1 0x44>;
++ dma-names = "tx", "rx";
++ power-domains = <&sysc R8A7797_PD_ALWAYS_ON>;
++ status = "disabled";
++ };
++
++ msiof3: spi@e6c10000 {
++ #address-cells = <1>;
++ #size-cells = <0>;
++ compatible = "renesas,msiof-r8a7797";
++ reg = <0 0xe6c10000 0 0x0064>;
++ interrupts = <GIC_SPI 159 IRQ_TYPE_LEVEL_HIGH>; /* SPI159:MSIOF.ch3 */
++ clocks = <&cpg CPG_MOD 208>, <&msiof_ref_clk>; /* RMSTPCR2/bit8:MSIOF3, @@ msiof_ref_clk->Eagle.dts */
++ clock-names = "msiof_clk", "msiof_ref_clk";
++ dmas = <&dmac1 0x47>, <&dmac1 0x46>;
++ dma-names = "tx", "rx";
++ power-domains = <&sysc R8A7797_PD_ALWAYS_ON>;
++ status = "disabled";
++ };
++
++ vin0: video@e6ef0000 {
++ compatible = "renesas,vin-r8a7797";
++ reg = <0 0xe6ef0000 0 0x1000>;
++ interrupts = <GIC_SPI 188 IRQ_TYPE_LEVEL_HIGH>; /* SPI188:VIN.ch0 */
++ clocks = <&cpg CPG_MOD 811>; /* RMSTPCR8/bit11:VIN0 */
++ power-domains = <&sysc R8A7797_PD_ALWAYS_ON>;
++ status = "disabled";
++ };
++
++ vin1: video@e6ef1000 {
++ compatible = "renesas,vin-r8a7797";
++ reg = <0 0xe6ef1000 0 0x1000>;
++ interrupts = <GIC_SPI 189 IRQ_TYPE_LEVEL_HIGH>; /* SPI189:VIN.ch1 */
++ clocks = <&cpg CPG_MOD 810>; /* RMSTPCR8/bit10:VIN1 */
++ power-domains = <&sysc R8A7797_PD_ALWAYS_ON>;
++ status = "disabled";
++ };
++
++ vin2: video@e6ef2000 {
++ compatible = "renesas,vin-r8a7797";
++ reg = <0 0xe6ef2000 0 0x1000>;
++ interrupts = <GIC_SPI 190 IRQ_TYPE_LEVEL_HIGH>; /* SPI190:VIN.ch2 */
++ clocks = <&cpg CPG_MOD 809>; /* RMSTPCR8/bit9:VIN2 */
++ power-domains = <&sysc R8A7797_PD_ALWAYS_ON>;
++ status = "disabled";
++ };
++
++ vin3: video@e6ef3000 {
++ compatible = "renesas,vin-r8a7797";
++ reg = <0 0xe6ef3000 0 0x1000>;
++ interrupts = <GIC_SPI 191 IRQ_TYPE_LEVEL_HIGH>; /* SPI191:VIN.ch3 */
++ clocks = <&cpg CPG_MOD 808>; /* RMSTPCR8/bit8:VIN3 */
++ power-domains = <&sysc R8A7797_PD_ALWAYS_ON>;
++ status = "disabled";
++ };
++
++ sdhi2: sd@ee140000 {
++ compatible = "renesas,sdhi-r8a7797";
++ reg = <0 0xee140000 0 0x2000>;
++ interrupts = <GIC_SPI 165 IRQ_TYPE_LEVEL_HIGH>;
++ clocks = <&cpg CPG_MOD 314>;
++ power-domains = <&sysc R8A7797_PD_ALWAYS_ON>;
++ renesas,clk-rate = <200000000>;
++ status = "disabled";
++ };
++
++ qos@e67e0000 {
++ compatible = "renesas,qos";
++ };
++
++ vspd0: vsp@fea20000 {
++ compatible = "renesas,vsp2";
++ reg = <0 0xfea20000 0 0x4000>;
++
++ interrupts = <GIC_SPI 169 IRQ_TYPE_LEVEL_HIGH>;
++ clocks = <&cpg CPG_MOD 623>; /* RMSTPCR6/bit23:VSP(VSPD0) */
++ power-domains = <&sysc R8A7797_PD_ALWAYS_ON>;
++
++ renesas,fcp = <&fcpvd0>;
++ };
++
++ fcpvd0: fcp@fea27000 {
++ compatible = "renesas,r8a7797-fcpv", "renesas,fcpv";
++ reg = <0 0xfea27000 0 0x200>;
++ clocks = <&cpg CPG_MOD 603>; /* RMSTPCR6/bit3:FCPVD0 */
++ power-domains = <&sysc R8A7797_PD_ALWAYS_ON>;
++ };
++
++ du: display@feb00000 {
++ compatible = "renesas,du-r8a7797";
++ reg = <0 0xfeb00000 0 0x80000>,
++ <0 0xfeb90000 0 0x14>; /* LDVS */
++ reg-names = "du", "lvds.0";
++ interrupts = <GIC_SPI 256 IRQ_TYPE_LEVEL_HIGH>; /* SPI256:DU.ch0 */
++ clocks = <&cpg CPG_MOD 724>,
++ <&cpg CPG_MOD 727>,
++ <&dclkin_p0>;
++ clock-names = "du.0", "lvds.0", "dclkin.0";
++ status = "disabled";
++
++ vsps = <&vspd0>;
++
++ interlaced = <1>;
++
++ ports {
++ #address-cells = <1>;
++ #size-cells = <0>;
++
++ port@0 {
++ reg = <0>;
++ du_out_lvds0: endpoint {
++ };
++ };
++ };
++ };
++
++ tsc1: thermal@0xe6190000 {
++ compatible = "renesas,rcar-thermal";
++ reg = <0 0xe6190000 0 0x14
++ 0 0xe6190100 0 0x38>;
++
++ interrupts = <GIC_SPI 67 IRQ_TYPE_LEVEL_HIGH>,
++ <GIC_SPI 68 IRQ_TYPE_LEVEL_HIGH>,
++ <GIC_SPI 69 IRQ_TYPE_LEVEL_HIGH>; /* SPI67~69:Thermal Sensor.ch0~2 */
++ clocks = <&cpg CPG_MOD 522>; /* RMSTPCR5/bit22:THS/TSC */
++ power-domains = <&sysc R8A7797_PD_ALWAYS_ON>;
++ #thermal-sensor-cells = <0>;
++ status = "okay";
++ };
++
++ thermal-zones {
++ emergency {
++ polling-delay = <1000>;
++ on-temperature = <110000>;
++ off-temperature = <95000>;
++ target_cpus = <&a53_1>;
++ status = "disabled";
++ };
++
++ sensor_thermal1: sensor-thermal1 {
++ polling-delay-passive = <250>;
++ polling-delay = <0>;
++ sustainable-power = <6313>;
++
++ /* sensor ID */
++ thermal-sensors = <&tsc1>;
++
++ trips {
++ threshold: trip-point@0 {
++ /* miliCelsius */
++ temperature = <90000>;
++ hysteresis = <2000>;
++ type = "passive";
++ };
++
++ target: trip-point@1 {
++ /* miliCelsius */
++ temperature = <100000>;
++ hysteresis = <2000>;
++ type = "passive";
++ };
++
++ sensor1_crit: sensor1-crit {
++ temperature = <120000>;
++ hysteresis = <2000>;
++ type = "critical";
++ };
++ };
++
++ cooling-maps {
++ map0 {
++ trip = <&target>;
++ cooling-device = <&a53_0 0 2>;
++ contribution = <1024>;
++ };
++ };
++ };
++ };
++
++ mfis: mfis@e6260000 {
++ compatible = "renesas,mfis-r8a7797", "renesas,mfis";
++ reg = <0 0xe6260000 0 0x0200>;
++ clocks = <&cpg CPG_MOD 213>;
++ clock-names = "mfis";
++ interrupts = <GIC_SPI 180 IRQ_TYPE_LEVEL_HIGH>;
++ interrupt-names = "eicr0";
++ status = "okay";
++ };
++
++ mfis_lock: mfis-lock@e62600c0 {
++ compatible = "renesas,mfis-lock-r8a7797",
++ "renesas,mfis-lock";
++ reg = <0 0xe62600c0 0 0x0020>;
++ status = "okay";
++ };
++
++ imrlx4_ch0: imr-lx4@fe860000 {
++ compatible = "renesas,imr-lx4";
++ reg = <0 0xfe860000 0 0x2000>;
++ interrupts = <GIC_SPI 192 IRQ_TYPE_LEVEL_HIGH>;
++ clocks = <&cpg CPG_MOD 823>;
++ power-domains = <&sysc R8A7797_PD_ALWAYS_ON>;
++ };
++
++ imrlx4_ch1: imr-lx4@fe870000 {
++ compatible = "renesas,imr-lx4";
++ reg = <0 0xfe870000 0 0x2000>;
++ interrupts = <GIC_SPI 193 IRQ_TYPE_LEVEL_HIGH>;
++ clocks = <&cpg CPG_MOD 822>;
++ power-domains = <&sysc R8A7797_PD_ALWAYS_ON>;
++ };
++
++ imrlx4_ch2: imr-lx4@fe880000 {
++ compatible = "renesas,imr-lx4";
++ reg = <0 0xfe880000 0 0x2000>;
++ interrupts = <GIC_SPI 194 IRQ_TYPE_LEVEL_HIGH>;
++ clocks = <&cpg CPG_MOD 821>;
++ power-domains = <&sysc R8A7797_PD_ALWAYS_ON>;
++ };
++
++ imrlx4_ch3: imr-lx4@fe890000 {
++ compatible = "renesas,imr-lx4";
++ reg = <0 0xfe890000 0 0x2000>;
++ interrupts = <GIC_SPI 195 IRQ_TYPE_LEVEL_HIGH>;
++ clocks = <&cpg CPG_MOD 820>;
++ power-domains = <&sysc R8A7797_PD_ALWAYS_ON>;
++ };
++ };
++};
+diff --git a/drivers/clk/renesas/Kconfig b/drivers/clk/renesas/Kconfig
+index bbd9701..b52e907 100644
+--- a/drivers/clk/renesas/Kconfig
++++ b/drivers/clk/renesas/Kconfig
+@@ -5,6 +5,7 @@ config CLK_RENESAS_CPG_MSSR
+ default y if ARCH_R8A7795
+ default y if ARCH_R8A7796
+ default y if ARCH_R8A77965
++ default y if ARCH_R8A7797
+
+ config CLK_RENESAS_CPG_MSTP
+ bool
+diff --git a/drivers/clk/renesas/Makefile b/drivers/clk/renesas/Makefile
+index 2c224e9..c2ef11e 100644
+--- a/drivers/clk/renesas/Makefile
++++ b/drivers/clk/renesas/Makefile
+@@ -14,6 +14,7 @@ obj-$(CONFIG_ARCH_R8A7794) += clk-rcar-gen2.o clk-div6.o
+ obj-$(CONFIG_ARCH_R8A7795) += r8a7795-cpg-mssr.o rcar-gen3-cpg.o
+ obj-$(CONFIG_ARCH_R8A7796) += r8a7796-cpg-mssr.o rcar-gen3-cpg.o
+ obj-$(CONFIG_ARCH_R8A77965) += r8a77965-cpg-mssr.o rcar-gen3-cpg.o
++obj-$(CONFIG_ARCH_R8A7797) += r8a7797-cpg-mssr.o rcar-gen3-cpg.o
+ obj-$(CONFIG_ARCH_SH73A0) += clk-sh73a0.o clk-div6.o
+
+ obj-$(CONFIG_CLK_RENESAS_CPG_MSSR) += renesas-cpg-mssr.o clk-div6.o
+diff --git a/drivers/clk/renesas/r8a7797-cpg-mssr.c b/drivers/clk/renesas/r8a7797-cpg-mssr.c
+new file mode 100644
+index 0000000..0460ed4
+--- /dev/null
++++ b/drivers/clk/renesas/r8a7797-cpg-mssr.c
+@@ -0,0 +1,232 @@
++/*
++ * r8a7797 Clock Pulse Generator / Module Standby and Software Reset
++ *
++ * Copyright (C) 2016 Glider bvba
++ *
++ * Based on r8a7795-cpg-mssr.c
++ *
++ * Copyright (C) 2016 Renesas Electronics Corp.
++ *
++ * This program is free software; you can redistribute it and/or modify
++ * it under the terms of the GNU General Public License as published by
++ * the Free Software Foundation; version 2 of the License.
++ */
++
++#include <linux/device.h>
++#include <linux/init.h>
++#include <linux/kernel.h>
++#include <linux/soc/renesas/rcar-rst.h>
++#include <linux/sys_soc.h>
++
++#include <dt-bindings/clock/r8a7797-cpg-mssr.h>
++
++#include "renesas-cpg-mssr.h"
++#include "rcar-gen3-cpg.h"
++
++enum clk_ids {
++ /* Core Clock Outputs exported to DT */
++ LAST_DT_CORE_CLK = R8A7797_CLK_OSC,
++
++ /* External Input Clocks */
++ CLK_EXTAL,
++ CLK_EXTALR,
++
++ /* Internal Core Clocks */
++ CLK_MAIN,
++ CLK_PLL0,
++ CLK_PLL1,
++ CLK_PLL3,
++ CLK_PLL1_DIV2,
++ CLK_PLL1_DIV4,
++ CLK_S1,
++ CLK_S2,
++ CLK_RINT,
++
++ /* Module Clocks */
++ MOD_CLK_BASE
++};
++
++static const struct cpg_core_clk r8a7797_core_clks[] __initconst = {
++ /* External Clock Inputs */
++ DEF_INPUT("extal", CLK_EXTAL),
++ DEF_INPUT("extalr", CLK_EXTALR),
++
++ /* Internal Core Clocks */
++ DEF_BASE(".main", CLK_MAIN, CLK_TYPE_GEN3_MAIN, CLK_EXTAL),
++ DEF_BASE(".pll0", CLK_PLL0, CLK_TYPE_GEN3_PLL0, CLK_MAIN),
++ DEF_BASE(".pll1", CLK_PLL1, CLK_TYPE_GEN3_PLL1, CLK_MAIN),
++ DEF_BASE(".pll3", CLK_PLL3, CLK_TYPE_GEN3_PLL3, CLK_MAIN),
++
++ DEF_FIXED(".pll1_div2", CLK_PLL1_DIV2, CLK_PLL1, 2, 1),
++ DEF_FIXED(".pll1_div4", CLK_PLL1_DIV4, CLK_PLL1_DIV2, 2, 1),
++ DEF_FIXED(".s1", CLK_S1, CLK_PLL1_DIV2, 4, 1),
++ DEF_FIXED(".s2", CLK_S2, CLK_PLL1_DIV2, 6, 1),
++
++ /* Core Clock Outputs */
++ DEF_BASE("z2", R8A7797_CLK_Z2, CLK_TYPE_GEN3_Z2, CLK_PLL1_DIV4),
++ DEF_FIXED("ztr", R8A7797_CLK_ZTR, CLK_PLL1_DIV2, 6, 1),
++ DEF_FIXED("ztrd2", R8A7797_CLK_ZTRD2, CLK_PLL1_DIV2, 12, 1),
++ DEF_FIXED("zt", R8A7797_CLK_ZT, CLK_PLL1_DIV2, 4, 1),
++ DEF_FIXED("zx", R8A7797_CLK_ZX, CLK_PLL1_DIV2, 3, 1),
++ DEF_FIXED("s1d1", R8A7797_CLK_S1D1, CLK_S1, 1, 1),
++ DEF_FIXED("s1d2", R8A7797_CLK_S1D2, CLK_S1, 2, 1),
++ DEF_FIXED("s1d4", R8A7797_CLK_S1D4, CLK_S1, 4, 1),
++ DEF_FIXED("s2d1", R8A7797_CLK_S2D1, CLK_S2, 1, 1),
++ DEF_FIXED("s2d2", R8A7797_CLK_S2D2, CLK_S2, 2, 1),
++ DEF_FIXED("s2d4", R8A7797_CLK_S2D4, CLK_S2, 4, 1),
++
++ DEF_GEN3_SD0H("sd0h", R8A7797_CLK_SD0H, CLK_PLL1_DIV4, 0x0074),
++ DEF_GEN3_SD0("sd0", R8A7797_CLK_SD0, CLK_PLL1_DIV4, 0x0074),
++
++ DEF_FIXED("cl", R8A7797_CLK_CL, CLK_PLL1_DIV2, 48, 1),
++ DEF_FIXED("cp", R8A7797_CLK_CP, CLK_EXTAL, 2, 1),
++
++ DEF_DIV6P1("mso", R8A7797_CLK_MSO, CLK_PLL1_DIV4, 0x014),
++ DEF_DIV6P1("canfd", R8A7797_CLK_CANFD, CLK_PLL1_DIV4, 0x244),
++ DEF_DIV6P1("csi0", R8A7797_CLK_CSI0, CLK_PLL1_DIV4, 0x00c),
++
++ DEF_FIXED("osc", R8A7797_CLK_OSC, CLK_PLL1_DIV2, (12*1024), 1),
++ DEF_BASE("r_int", CLK_RINT, CLK_TYPE_GEN3_RINT, CLK_EXTAL),
++
++ DEF_BASE("r", R8A7797_CLK_R, CLK_TYPE_GEN3_R, CLK_RINT),
++};
++
++static const struct mssr_mod_clk r8a7797_mod_clks[] __initconst = {
++ DEF_MOD("tmu4", 121, R8A7797_CLK_S2D2),
++ DEF_MOD("tmu3", 122, R8A7797_CLK_S2D2),
++ DEF_MOD("tmu2", 123, R8A7797_CLK_S2D2),
++ DEF_MOD("tmu1", 124, R8A7797_CLK_S2D2),
++ DEF_MOD("tmu0", 125, R8A7797_CLK_CP),
++ DEF_MOD("ivcp1e", 127, R8A7797_CLK_S2D1),
++ DEF_MOD("scif4", 203, R8A7797_CLK_S2D4), /* @@ H3=S3D4 */
++ DEF_MOD("scif3", 204, R8A7797_CLK_S2D4), /* @@ H3=S3D4 */
++ DEF_MOD("scif1", 206, R8A7797_CLK_S2D4), /* @@ H3=S3D4 */
++ DEF_MOD("scif0", 207, R8A7797_CLK_S2D4), /* @@ H3=S3D4 */
++ DEF_MOD("msiof3", 208, R8A7797_CLK_MSO),
++ DEF_MOD("msiof2", 209, R8A7797_CLK_MSO),
++ DEF_MOD("msiof1", 210, R8A7797_CLK_MSO),
++ DEF_MOD("msiof0", 211, R8A7797_CLK_MSO),
++ DEF_MOD("mfis", 213, R8A7797_CLK_S2D2), /* @@ H3=S3D2 */
++ DEF_MOD("sys-dmac2", 217, R8A7797_CLK_S2D1), /* @@ H3=S3D1 */
++ DEF_MOD("sys-dmac1", 218, R8A7797_CLK_S2D1), /* @@ H3=S3D1 */
++ DEF_MOD("cmt3", 300, R8A7797_CLK_R),
++ DEF_MOD("cmt2", 301, R8A7797_CLK_R),
++ DEF_MOD("cmt1", 302, R8A7797_CLK_R),
++ DEF_MOD("cmt0", 303, R8A7797_CLK_R),
++ DEF_MOD("tpu", 304, R8A7797_CLK_S2D4),
++ DEF_MOD("sdif", 314, R8A7797_CLK_SD0),
++ DEF_MOD("rwdt0", 402, R8A7797_CLK_R),
++ DEF_MOD("intc-ex", 407, R8A7797_CLK_CP),
++ DEF_MOD("intc-ap", 408, R8A7797_CLK_S2D1), /* @@ H3=S3D1 */
++ DEF_MOD("hscif3", 517, R8A7797_CLK_S2D1), /* @@ H3=S3D1 */
++ DEF_MOD("hscif2", 518, R8A7797_CLK_S2D1), /* @@ H3=S3D1 */
++ DEF_MOD("hscif1", 519, R8A7797_CLK_S2D1), /* @@ H3=S3D1 */
++ DEF_MOD("hscif0", 520, R8A7797_CLK_S2D1), /* @@ H3=S3D1 */
++ DEF_MOD("thermal", 522, R8A7797_CLK_CP),
++ DEF_MOD("pwm", 523, R8A7797_CLK_S2D4),
++ DEF_MOD("fcpvd0", 603, R8A7797_CLK_S2D1),
++ DEF_MOD("vspd0", 623, R8A7797_CLK_S2D1),
++ DEF_MOD("csi40", 716, R8A7797_CLK_CSI0),
++ DEF_MOD("du0", 724, R8A7797_CLK_S2D1),
++ DEF_MOD("lvds", 727, R8A7797_CLK_S2D1),
++ DEF_MOD("vin3", 808, R8A7797_CLK_S2D1),
++ DEF_MOD("vin2", 809, R8A7797_CLK_S2D1),
++ DEF_MOD("vin1", 810, R8A7797_CLK_S2D1),
++ DEF_MOD("vin0", 811, R8A7797_CLK_S2D1),
++ DEF_MOD("etheravb", 812, R8A7797_CLK_S2D2),
++ DEF_MOD("isp", 817, R8A7797_CLK_S2D1), /* @@ Unknown Module Clock */
++ DEF_MOD("imr3", 820, R8A7797_CLK_S2D1),
++ DEF_MOD("imr2", 821, R8A7797_CLK_S2D1),
++ DEF_MOD("imr1", 822, R8A7797_CLK_S2D1),
++ DEF_MOD("imr0", 823, R8A7797_CLK_S2D1),
++ DEF_MOD("gpio5", 907, R8A7797_CLK_CP),
++ DEF_MOD("gpio4", 908, R8A7797_CLK_CP),
++ DEF_MOD("gpio3", 909, R8A7797_CLK_CP),
++ DEF_MOD("gpio2", 910, R8A7797_CLK_CP),
++ DEF_MOD("gpio1", 911, R8A7797_CLK_CP),
++ DEF_MOD("gpio0", 912, R8A7797_CLK_CP),
++ DEF_MOD("can-fd", 914, R8A7797_CLK_S2D2), /* @@ H3=S3D2 */
++ DEF_MOD("i2c4", 927, R8A7797_CLK_S2D2),
++ DEF_MOD("i2c3", 928, R8A7797_CLK_S2D2),
++ DEF_MOD("i2c2", 929, R8A7797_CLK_S2D2),
++ DEF_MOD("i2c1", 930, R8A7797_CLK_S2D2),
++ DEF_MOD("i2c0", 931, R8A7797_CLK_S2D2),
++};
++
++static const unsigned int r8a7797_crit_mod_clks[] __initconst = {
++ MOD_CLK_ID(408), /* INTC-AP (GIC) */
++};
++
++
++/*
++ * CPG Clock Data
++ */
++
++/*
++ * MD EXTAL PLL0 PLL1 PLL3
++ * 14 13 19 (MHz)
++ *-------------------------------------------------
++ * 0 0 0 16.66 x 1 x192 x192 x96
++ * 0 0 1 16.66 x 1 x192 x192 x80
++ * 0 1 0 20 x 1 x160 x160 x80
++ * 0 1 1 20 x 1 x160 x160 x66
++ * 1 0 0 27 / 2 x236 x236 x118
++ * 1 0 1 27 / 2 x236 x236 x98
++ * 1 1 0 33.33 / 2 x192 x192 x96
++ * 1 1 1 33.33 / 2 x192 x192 x80
++ */
++#define CPG_PLL_CONFIG_INDEX(md) ((((md) & BIT(14)) >> 12) | \
++ (((md) & BIT(13)) >> 12) | \
++ (((md) & BIT(19)) >> 19))
++
++static const struct rcar_gen3_cpg_pll_config cpg_pll_configs[8] __initconst = {
++ /* EXTAL div PLL1 mult PLL3 mult */
++ { 1, 192, 96, },
++ { 1, 192, 80, },
++ { 1, 160, 80, },
++ { 1, 160, 66, },
++ { 2, 236, 118, },
++ { 2, 236, 98, },
++ { 2, 192, 96, },
++ { 2, 192, 80, },
++};
++
++static int __init r8a7797_cpg_mssr_init(struct device *dev)
++{
++ const struct rcar_gen3_cpg_pll_config *cpg_pll_config;
++ u32 cpg_mode;
++ int error;
++
++ error = rcar_rst_read_mode_pins(&cpg_mode);
++ if (error)
++ return error;
++
++ cpg_pll_config = &cpg_pll_configs[CPG_PLL_CONFIG_INDEX(cpg_mode)];
++ if (!cpg_pll_config->extal_div) {
++ dev_err(dev, "Prohibited setting (cpg_mode=0x%x)\n", cpg_mode);
++ return -EINVAL;
++ }
++
++ return rcar_gen3_cpg_init(cpg_pll_config, CLK_EXTALR, cpg_mode);
++}
++
++const struct cpg_mssr_info r8a7797_cpg_mssr_info __initconst = {
++ /* Core Clocks */
++ .core_clks = r8a7797_core_clks,
++ .num_core_clks = ARRAY_SIZE(r8a7797_core_clks),
++ .last_dt_core_clk = LAST_DT_CORE_CLK,
++ .num_total_core_clks = MOD_CLK_BASE,
++
++ /* Module Clocks */
++ .mod_clks = r8a7797_mod_clks,
++ .num_mod_clks = ARRAY_SIZE(r8a7797_mod_clks),
++ .num_hw_mod_clks = 12 * 32,
++
++ /* Critical Module Clocks */
++ .crit_mod_clks = r8a7797_crit_mod_clks,
++ .num_crit_mod_clks = ARRAY_SIZE(r8a7797_crit_mod_clks),
++
++ /* Callbacks */
++ .init = r8a7797_cpg_mssr_init,
++ .cpg_clk_register = rcar_gen3_cpg_clk_register,
++};
+diff --git a/drivers/clk/renesas/rcar-gen3-cpg.c b/drivers/clk/renesas/rcar-gen3-cpg.c
+index 1cd2c05..b145f14 100644
+--- a/drivers/clk/renesas/rcar-gen3-cpg.c
++++ b/drivers/clk/renesas/rcar-gen3-cpg.c
+@@ -26,6 +26,13 @@
+ #include "renesas-cpg-mssr.h"
+ #include "rcar-gen3-cpg.h"
+
++static spinlock_t cpg_lock;
++
++static const struct soc_device_attribute r8a7797[] = {
++ { .soc_id = "r8a7797" },
++ { /* sentinel */ }
++};
++
+ #define CPG_PLL0CR 0x00d8
+ #define CPG_PLL2CR 0x002c
+ #define CPG_PLL4CR 0x01f4
+@@ -228,7 +235,10 @@ static unsigned long cpg_z2_clk_recalc_rate(struct clk_hw *hw,
+ unsigned int val;
+ unsigned long rate;
+
+- val = (clk_readl(zclk->reg) & CPG_FRQCRC_Z2FC_MASK);
++ if (!soc_device_match(r8a7797))
++ val = (clk_readl(zclk->reg) & CPG_FRQCRC_Z2FC_MASK);
++ else
++ val = 0;
+ mult = 32 - val;
+
+ rate = div_u64((u64)parent_rate * mult + 16, 32);
+@@ -372,6 +382,11 @@ static int cpg_z2_clk_set_rate(struct clk_hw *hw, unsigned long rate,
+ u32 val, kick;
+ unsigned int i;
+
++ if (soc_device_match(r8a7797)){
++ pr_info("Do not support V3M's Z2 clock changing\n");
++ return 0;
++ }
++
+ mult = div_u64((u64)rate * 32 + parent_rate/2, parent_rate);
+ mult = clamp(mult, 1U, 32U);
+
+@@ -566,6 +581,19 @@ static struct clk * __init cpg_zg_clk_register(const char *name,
+ /*
+ * SDn Clock
+ */
++/* SDHI divisors */
++static const struct clk_div_table cpg_sdh_div_table[] = {
++ { 0, 2 }, { 1, 3 }, { 2, 4 }, { 3, 6 },
++ { 4, 8 }, { 5, 12 }, { 6, 16 }, { 7, 18 },
++ { 8, 24 }, { 10, 36 }, { 11, 48 }, { 0, 0 },
++};
++
++static const struct clk_div_table cpg_sd01_div_table[] = {
++ { 4, 8 },
++ { 5, 12 }, { 6, 16 }, { 7, 18 }, { 8, 24 },
++ { 10, 36 }, { 11, 48 }, { 12, 10 }, { 0, 0 },
++};
++
+ #define CPG_SD_STP_HCK BIT(9)
+ #define CPG_SD_STP_CK BIT(8)
+
+@@ -864,6 +892,14 @@ struct clk * __init rcar_gen3_cpg_clk_register(struct device *dev,
+ case CLK_TYPE_GEN3_SD:
+ return cpg_sd_clk_register(core, base, __clk_get_name(parent));
+
++ case CLK_TYPE_GEN3_SD0:
++ return clk_register_divider_table(NULL, core->name, __clk_get_name(parent), 0, base + 0x0074,
++ 4, 4,0, cpg_sd01_div_table, &cpg_lock);
++
++ case CLK_TYPE_GEN3_SD0H:
++ return clk_register_divider_table(NULL, core->name, __clk_get_name(parent), 0, base + 0x0074,
++ 8, 4,0, cpg_sdh_div_table, &cpg_lock);
++
+ case CLK_TYPE_GEN3_RINT:
+ div = cpg_pll_config->rint;
+ break;
+@@ -917,5 +953,8 @@ int __init rcar_gen3_cpg_init(const struct rcar_gen3_cpg_pll_config *config,
+ if (attr)
+ cpg_quirks = (uintptr_t)attr->data;
+ pr_debug("%s: mode = 0x%x quirks = 0x%x\n", __func__, mode, cpg_quirks);
++
++ spin_lock_init(&cpg_lock);
++
+ return 0;
+ }
+diff --git a/drivers/clk/renesas/rcar-gen3-cpg.h b/drivers/clk/renesas/rcar-gen3-cpg.h
+index 51ae7b8..694bedc 100644
+--- a/drivers/clk/renesas/rcar-gen3-cpg.h
++++ b/drivers/clk/renesas/rcar-gen3-cpg.h
+@@ -19,6 +19,8 @@ enum rcar_gen3_clk_types {
+ CLK_TYPE_GEN3_PLL3,
+ CLK_TYPE_GEN3_PLL4,
+ CLK_TYPE_GEN3_SD,
++ CLK_TYPE_GEN3_SD0,
++ CLK_TYPE_GEN3_SD0H,
+ CLK_TYPE_GEN3_R,
+ CLK_TYPE_GEN3_Z,
+ CLK_TYPE_GEN3_Z2,
+@@ -29,6 +31,10 @@ enum rcar_gen3_clk_types {
+
+ #define DEF_GEN3_SD(_name, _id, _parent, _offset) \
+ DEF_BASE(_name, _id, CLK_TYPE_GEN3_SD, _parent, .offset = _offset)
++#define DEF_GEN3_SD0(_name, _id, _parent, _offset) \
++ DEF_BASE(_name, _id, CLK_TYPE_GEN3_SD0, _parent, .offset = _offset)
++#define DEF_GEN3_SD0H(_name, _id, _parent, _offset) \
++ DEF_BASE(_name, _id, CLK_TYPE_GEN3_SD0H, _parent, .offset = _offset)
+
+ struct rcar_gen3_cpg_pll_config {
+ unsigned int extal_div;
+diff --git a/drivers/clk/renesas/renesas-cpg-mssr.c b/drivers/clk/renesas/renesas-cpg-mssr.c
+index 8c261e1..bd901a6 100644
+--- a/drivers/clk/renesas/renesas-cpg-mssr.c
++++ b/drivers/clk/renesas/renesas-cpg-mssr.c
+@@ -594,6 +594,12 @@ static int __init cpg_mssr_add_clk_domain(struct device *dev,
+ .data = &r8a77965_cpg_mssr_info,
+ },
+ #endif
++#ifdef CONFIG_ARCH_R8A7797
++ {
++ .compatible = "renesas,r8a7797-cpg-mssr",
++ .data = &r8a7797_cpg_mssr_info,
++ },
++#endif
+ { /* sentinel */ }
+ };
+
+diff --git a/drivers/clk/renesas/renesas-cpg-mssr.h b/drivers/clk/renesas/renesas-cpg-mssr.h
+index 145b738..ce3546a 100644
+--- a/drivers/clk/renesas/renesas-cpg-mssr.h
++++ b/drivers/clk/renesas/renesas-cpg-mssr.h
+@@ -135,6 +135,7 @@ struct cpg_mssr_info {
+ extern const struct cpg_mssr_info r8a7795_cpg_mssr_info;
+ extern const struct cpg_mssr_info r8a7796_cpg_mssr_info;
+ extern const struct cpg_mssr_info r8a77965_cpg_mssr_info;
++extern const struct cpg_mssr_info r8a7797_cpg_mssr_info;
+
+
+ /*
+diff --git a/drivers/cpufreq/cpufreq-dt-platdev.c b/drivers/cpufreq/cpufreq-dt-platdev.c
+index 515d0e7..5a2ec23 100644
+--- a/drivers/cpufreq/cpufreq-dt-platdev.c
++++ b/drivers/cpufreq/cpufreq-dt-platdev.c
+@@ -60,6 +60,7 @@
+ { .compatible = "renesas,r8a7795", },
+ { .compatible = "renesas,r8a7796", },
+ { .compatible = "renesas,r8a77965", },
++ { .compatible = "renesas,r8a7797", },
+ { .compatible = "renesas,sh73a0", },
+
+ { .compatible = "rockchip,rk2928", },
+diff --git a/drivers/gpio/gpio-rcar.c b/drivers/gpio/gpio-rcar.c
+index 6917932..fd15649 100644
+--- a/drivers/gpio/gpio-rcar.c
++++ b/drivers/gpio/gpio-rcar.c
+@@ -1,7 +1,7 @@
+ /*
+ * Renesas R-Car GPIO Support
+ *
+- * Copyright (C) 2014 Renesas Electronics Corporation
++ * Copyright (C) 2014-2016 Renesas Electronics Corporation
+ * Copyright (C) 2013 Magnus Damm
+ *
+ * This program is free software; you can redistribute it and/or modify
+@@ -367,6 +367,10 @@ struct gpio_rcar_info {
+ /* Gen3 GPIO is identical to Gen2. */
+ .data = &gpio_rcar_info_gen2,
+ }, {
++ .compatible = "renesas,gpio-r8a7797",
++ /* Gen3 GPIO is identical to Gen2. */
++ .data = &gpio_rcar_info_gen2,
++ }, {
+ .compatible = "renesas,gpio-rcar",
+ .data = &gpio_rcar_info_gen1,
+ }, {
+diff --git a/drivers/gpu/drm/rcar-du/rcar_du_drv.c b/drivers/gpu/drm/rcar-du/rcar_du_drv.c
+index b234918..f74f264 100644
+--- a/drivers/gpu/drm/rcar-du/rcar_du_drv.c
++++ b/drivers/gpu/drm/rcar-du/rcar_du_drv.c
+@@ -312,6 +312,30 @@
+ .skip_ch = BIT(2),
+ };
+
++static const struct rcar_du_device_info rcar_du_r8a7797_info = {
++ .gen = 3,
++ .features = RCAR_DU_FEATURE_CRTC_IRQ_CLOCK
++ | RCAR_DU_FEATURE_EXT_CTRL_REGS
++ | RCAR_DU_FEATURE_VSP1_SOURCE
++ | RCAR_DU_FEATURE_GEN3_REGS,
++ .num_crtcs = 1,
++ .routes = {
++ /* R8A7797 has one RGB output, one LVDS output. */
++ [RCAR_DU_OUTPUT_DPAD0] = {
++ .possible_crtcs = BIT(0),
++ .encoder_type = DRM_MODE_ENCODER_NONE,
++ .port = 1,
++ },
++ [RCAR_DU_OUTPUT_LVDS0] = {
++ .possible_crtcs = BIT(0),
++ .encoder_type = DRM_MODE_ENCODER_LVDS,
++ .port = 0,
++ },
++ },
++ .num_lvds = 1,
++ .dpll_ch = BIT(1),
++};
++
+ static const struct soc_device_attribute ths_quirks_match[] = {
+ { .soc_id = "r8a7795", .revision = "ES1.*",
+ .data = (void *)(RCAR_DU_DPLL_DUTY_RATE_WA
+@@ -335,6 +359,7 @@
+ { .compatible = "renesas,du-r8a7795", .data = &rcar_du_r8a7795_info },
+ { .compatible = "renesas,du-r8a7796", .data = &rcar_du_r8a7796_info },
+ { .compatible = "renesas,du-r8a77965", .data = &rcar_du_r8a77965_info },
++ { .compatible = "renesas,du-r8a7797", .data = &rcar_du_r8a7797_info },
+ { }
+ };
+
+diff --git a/drivers/gpu/drm/rcar-du/rcar_du_group.c b/drivers/gpu/drm/rcar-du/rcar_du_group.c
+index 1af5eb7..3916b63 100644
+--- a/drivers/gpu/drm/rcar-du/rcar_du_group.c
++++ b/drivers/gpu/drm/rcar-du/rcar_du_group.c
+@@ -29,11 +29,17 @@
+
+ #include <linux/clk.h>
+ #include <linux/io.h>
++#include <linux/sys_soc.h>
+
+ #include "rcar_du_drv.h"
+ #include "rcar_du_group.h"
+ #include "rcar_du_regs.h"
+
++static const struct soc_device_attribute r8a7797[] = {
++ { .soc_id = "r8a7797" },
++ { }
++};
++
+ u32 rcar_du_group_read(struct rcar_du_group *rgrp, u32 reg)
+ {
+ return rcar_du_read(rgrp->dev, rgrp->mmio_offset + reg);
+@@ -155,8 +161,10 @@ static void rcar_du_group_setup(struct rcar_du_group *rgrp)
+
+ /* Apply planes to CRTCs association. */
+ mutex_lock(&rgrp->lock);
+- rcar_du_group_write(rgrp, DPTSR, (rgrp->dptsr_planes << 16) |
+- rgrp->dptsr_planes);
++ if (!soc_device_match(r8a7797))
++ rcar_du_group_write(rgrp, DPTSR, (rgrp->dptsr_planes << 16) |
++ rgrp->dptsr_planes);
++
+ mutex_unlock(&rgrp->lock);
+ }
+
+diff --git a/drivers/gpu/drm/rcar-du/rcar_du_lvdsenc.c b/drivers/gpu/drm/rcar-du/rcar_du_lvdsenc.c
+index ecae864..d5fa06c 100644
+--- a/drivers/gpu/drm/rcar-du/rcar_du_lvdsenc.c
++++ b/drivers/gpu/drm/rcar-du/rcar_du_lvdsenc.c
+@@ -17,12 +17,18 @@
+ #include <linux/of_gpio.h>
+ #include <linux/platform_device.h>
+ #include <linux/slab.h>
++#include <linux/sys_soc.h>
+
+ #include "rcar_du_drv.h"
+ #include "rcar_du_encoder.h"
+ #include "rcar_du_lvdsenc.h"
+ #include "rcar_lvds_regs.h"
+
++static const struct soc_device_attribute r8a7797[] = {
++ { .soc_id = "r8a7797" },
++ { }
++};
++
+ struct rcar_du_lvdsenc {
+ struct rcar_du_device *dev;
+
+@@ -96,14 +102,25 @@ static void rcar_du_lvdsenc_start_gen3(struct rcar_du_lvdsenc *lvds,
+ u32 pllcr;
+
+ /* PLL clock configuration */
+- if (freq < 42000)
+- pllcr = LVDPLLCR_PLLDIVCNT_42M;
+- else if (freq < 85000)
+- pllcr = LVDPLLCR_PLLDIVCNT_85M;
+- else if (freq < 128000)
+- pllcr = LVDPLLCR_PLLDIVCNT_128M;
+- else
+- pllcr = LVDPLLCR_PLLDIVCNT_148M;
++ if (soc_device_match(r8a7797)) {
++ if (freq < 39000)
++ pllcr = LVDPLLCR_CEEN | LVDPLLCR_COSEL | LVDPLLCR_PLLDLYCNT_38M;
++ else if (freq < 61000)
++ pllcr = LVDPLLCR_CEEN | LVDPLLCR_COSEL | LVDPLLCR_PLLDLYCNT_60M;
++ else if (freq < 121000)
++ pllcr = LVDPLLCR_CEEN | LVDPLLCR_COSEL | LVDPLLCR_PLLDLYCNT_121M;
++ else
++ pllcr = LVDPLLCR_PLLDLYCNT_150M;
++ } else {
++ if (freq < 42000)
++ pllcr = LVDPLLCR_PLLDIVCNT_42M;
++ else if (freq < 85000)
++ pllcr = LVDPLLCR_PLLDIVCNT_85M;
++ else if (freq < 128000)
++ pllcr = LVDPLLCR_PLLDIVCNT_128M;
++ else
++ pllcr = LVDPLLCR_PLLDIVCNT_148M;
++ }
+
+ rcar_lvds_write(lvds, LVDPLLCR, pllcr);
+
+@@ -123,6 +140,11 @@ static void rcar_du_lvdsenc_start_gen3(struct rcar_du_lvdsenc *lvds,
+ lvdcr0 |= LVDCR0_PWD;
+ rcar_lvds_write(lvds, LVDCR0, lvdcr0);
+
++ if (soc_device_match(r8a7797)) {
++ lvdcr0 |= LVDCR0_LVEN;
++ rcar_lvds_write(lvds, LVDCR0, lvdcr0);
++ }
++
+ usleep_range(100, 150);
+
+ lvdcr0 |= LVDCR0_LVRES;
+diff --git a/drivers/i2c/busses/i2c-rcar.c b/drivers/i2c/busses/i2c-rcar.c
+index 74c17d8..149c107 100644
+--- a/drivers/i2c/busses/i2c-rcar.c
++++ b/drivers/i2c/busses/i2c-rcar.c
+@@ -807,6 +807,7 @@ static u32 rcar_i2c_func(struct i2c_adapter *adap)
+ { .compatible = "renesas,i2c-r8a7795", .data = (void *)I2C_RCAR_GEN3 },
+ { .compatible = "renesas,i2c-r8a7796", .data = (void *)I2C_RCAR_GEN3 },
+ { .compatible = "renesas,i2c-r8a77965", .data = (void *)I2C_RCAR_GEN3 },
++ { .compatible = "renesas,i2c-r8a7797", .data = (void *)I2C_RCAR_GEN3 },
+ {},
+ };
+ MODULE_DEVICE_TABLE(of, rcar_i2c_dt_ids);
+diff --git a/drivers/iommu/ipmmu-vmsa.c b/drivers/iommu/ipmmu-vmsa.c
+index e2baed1..1ae9174 100644
+--- a/drivers/iommu/ipmmu-vmsa.c
++++ b/drivers/iommu/ipmmu-vmsa.c
+@@ -1,7 +1,7 @@
+ /*
+ * IPMMU VMSA
+ *
+- * Copyright (C) 2014 Renesas Electronics Corporation
++ * Copyright (C) 2014-2016 Renesas Electronics Corporation
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+@@ -1277,6 +1277,9 @@ static void ipmmu_device_reset(struct ipmmu_vmsa_device *mmu)
+ .compatible = "renesas,ipmmu-r8a7796",
+ .data = &ipmmu_features_rcar_gen3,
+ }, {
++ .compatible = "renesas,ipmmu-r8a7797",
++ .data = &ipmmu_features_rcar_gen3,
++ }, {
+ /* Terminator */
+ },
+ };
+@@ -1648,6 +1651,8 @@ static int __init ipmmu_vmsa_iommu_of_setup(struct device_node *np)
+ ipmmu_vmsa_iommu_of_setup);
+ IOMMU_OF_DECLARE(ipmmu_r8a7796_iommu_of, "renesas,ipmmu-r8a7796",
+ ipmmu_vmsa_iommu_of_setup);
++IOMMU_OF_DECLARE(ipmmu_r8a7797_iommu_of, "renesas,ipmmu-r8a7797",
++ ipmmu_vmsa_iommu_of_setup);
+ #endif
+
+ MODULE_DESCRIPTION("IOMMU API for Renesas VMSA-compatible IPMMU");
+diff --git a/drivers/media/platform/soc_camera/Kconfig b/drivers/media/platform/soc_camera/Kconfig
+index 17178ad..5539c5d 100644
+--- a/drivers/media/platform/soc_camera/Kconfig
++++ b/drivers/media/platform/soc_camera/Kconfig
+@@ -39,7 +39,7 @@ config VIDEO_RCAR_VIN_LEGACY_DEBUG
+ config VIDEO_RCAR_CSI2_LEGACY
+ tristate "R-Car MIPI CSI-2 Interface driver"
+ depends on VIDEO_DEV && SOC_CAMERA && HAVE_CLK
+- depends on ARCH_R8A7795 || ARCH_R8A7796 || COMPILE_TEST
++ depends on ARCH_R8A7795 || ARCH_R8A7796 || ARCH_R8A7797 || COMPILE_TEST
+ ---help---
+ This is a v4l2 driver for the R-Car CSI-2 Interface
+
+diff --git a/drivers/media/platform/soc_camera/rcar_csi2.c b/drivers/media/platform/soc_camera/rcar_csi2.c
+index 05f623468..4d95da6 100644
+--- a/drivers/media/platform/soc_camera/rcar_csi2.c
++++ b/drivers/media/platform/soc_camera/rcar_csi2.c
+@@ -25,6 +25,7 @@
+ #include <linux/slab.h>
+ #include <linux/videodev2.h>
+ #include <linux/module.h>
++#include <linux/sys_soc.h>
+
+ #include <media/rcar_csi2.h>
+ #include <media/soc_camera.h>
+@@ -153,6 +154,11 @@
+ #define RCAR_CSI2_INTSTATE_ERRSYNCESC (1 << 1)
+ #define RCAR_CSI2_INTSTATE_ERRCONTROL (1 << 0)
+
++static const struct soc_device_attribute r8a7797[] = {
++ { .soc_id = "r8a7797" },
++ { }
++};
++
+ enum chip_id {
+ RCAR_GEN3,
+ RCAR_GEN2,
+@@ -248,6 +254,17 @@ struct rcar_csi2 {
+
+ static int rcar_csi2_set_phy_freq(struct rcar_csi2 *priv)
+ {
++ const uint32_t const hs_freq_range_v3m[43] = {
++ 0x00, 0x00, 0x20, 0x40, 0x02, /* 80M, 90M, 100M, 110M, 120M */
++ 0x02, 0x22, 0x42, 0x04, 0x04, /* 130M, 140M, 150M, 160M, 170M */
++ 0x24, 0x44, 0x44, 0x06, 0x26, /* 180M, 190M, 205M, 220M, 235M */
++ 0x46, 0x08, 0x28, 0x0a, 0x2a, /* 250M, 270M, 300M, 325M, 350M */
++ 0x4a, 0x4a, 0x4a, 0x4a, 0x4a, /* 400M, 450M, 500M, 550M, 600M */
++ 0x10, 0x30, 0x12, 0x32, 0x52, /* 650M, 700M, 750M, 800M, 950M */
++ 0x72, 0x14, 0x34, 0x52, 0x74, /* 900M, 950M, 1000M, 1050M, 1100M */
++ 0x16, 0x36, 0x56, 0x76, 0x18, /* 1150M, 1200M, 1250M, 1300M, 1350M */
++ 0x38, 0x58, 0x78 /* 1400M, 1450M, 1500M */
++ };
+ const uint32_t const hs_freq_range[43] = {
+ 0x00, 0x10, 0x20, 0x30, 0x01, /* 0-4 */
+ 0x11, 0x21, 0x31, 0x02, 0x12, /* 5-9 */
+@@ -304,7 +321,12 @@ static int rcar_csi2_set_phy_freq(struct rcar_csi2 *priv)
+
+ dev_dbg(&priv->pdev->dev, "bps_per_lane (%d)\n", bps_per_lane);
+
+- iowrite32((hs_freq_range[bps_per_lane] << 16),
++ if (soc_device_match(r8a7797))
++ iowrite32((hs_freq_range_v3m[bps_per_lane] << 16) |
++ RCAR_CSI2_PHTW_DWEN | RCAR_CSI2_PHTW_CWEN | 0x44,
++ priv->base + RCAR_CSI2_PHTW);
++ else
++ iowrite32(hs_freq_range[bps_per_lane] << 16,
+ priv->base + RCAR_CSI2_PHYPLL);
+ return 0;
+
+@@ -488,6 +510,7 @@ static int rcar_csi2_s_power(struct v4l2_subdev *sd, int on)
+
+ #ifdef CONFIG_OF
+ static const struct of_device_id rcar_csi2_of_table[] = {
++ { .compatible = "renesas,r8a7797-csi2", .data = (void *)RCAR_GEN3 },
+ { .compatible = "renesas,r8a7796-csi2", .data = (void *)RCAR_GEN3 },
+ { .compatible = "renesas,r8a7795-csi2", .data = (void *)RCAR_GEN3 },
+ { },
+@@ -496,6 +519,7 @@ static int rcar_csi2_s_power(struct v4l2_subdev *sd, int on)
+ #endif
+
+ static struct platform_device_id rcar_csi2_id_table[] = {
++ { "r8a7797-csi2", RCAR_GEN3 },
+ { "r8a7796-csi2", RCAR_GEN3 },
+ { "r8a7795-csi2", RCAR_GEN3 },
+ {},
+diff --git a/drivers/media/platform/soc_camera/rcar_vin.c b/drivers/media/platform/soc_camera/rcar_vin.c
+index 400958b..74fb005 100644
+--- a/drivers/media/platform/soc_camera/rcar_vin.c
++++ b/drivers/media/platform/soc_camera/rcar_vin.c
+@@ -154,7 +154,7 @@
+ #define VNCSI_IFMD_REG 0x20 /* Video n CSI2 Interface Mode Register */
+
+ #define VNCSI_IFMD_DES1 (1 << 26) /* CSI20 */
+-#define VNCSI_IFMD_DES0 (1 << 25) /* H3:CSI40/41, M3:CSI40 */
++#define VNCSI_IFMD_DES0 (1 << 25) /* H3:CSI40/41, M3:CSI40, V3M:CSI40 */
+
+ #define VNCSI_IFMD_CSI_CHSEL(n) (n << 0)
+ #define VNCSI_IFMD_SEL_NUMBER 5
+@@ -185,6 +185,7 @@
+
+ enum chip_id {
+ RCAR_GEN3,
++ RCAR_V3M,
+ RCAR_M3,
+ RCAR_H3,
+ RCAR_GEN2,
+@@ -360,6 +361,49 @@ struct vin_gen3_ifmd {
+ },
+ };
+
++static const struct vin_gen3_ifmd vin_v3_vc_ifmd[] = {
++ { 0x0000,
++ {
++ {RCAR_CSI40, RCAR_VIRTUAL_CH0},
++ {RCAR_CSI_CH_NONE, RCAR_VIN_CH_NONE},
++ {RCAR_CSI_CH_NONE, RCAR_VIN_CH_NONE},
++ {RCAR_CSI40, RCAR_VIRTUAL_CH1},
++ }
++ },
++ { 0x0001,
++ {
++ {RCAR_CSI_CH_NONE, RCAR_VIN_CH_NONE},
++ {RCAR_CSI_CH_NONE, RCAR_VIN_CH_NONE},
++ {RCAR_CSI40, RCAR_VIRTUAL_CH0},
++ {RCAR_CSI_CH_NONE, RCAR_VIN_CH_NONE},
++ }
++ },
++ { 0x0002,
++ {
++ {RCAR_CSI_CH_NONE, RCAR_VIN_CH_NONE},
++ {RCAR_CSI40, RCAR_VIRTUAL_CH0},
++ {RCAR_CSI_CH_NONE, RCAR_VIN_CH_NONE},
++ {RCAR_CSI_CH_NONE, RCAR_VIN_CH_NONE},
++ }
++ },
++ { 0x0003,
++ {
++ {RCAR_CSI40, RCAR_VIRTUAL_CH0},
++ {RCAR_CSI40, RCAR_VIRTUAL_CH1},
++ {RCAR_CSI40, RCAR_VIRTUAL_CH2},
++ {RCAR_CSI40, RCAR_VIRTUAL_CH3},
++ }
++ },
++ { 0x0004,
++ {
++ {RCAR_CSI_CH_NONE, RCAR_VIN_CH_NONE},
++ {RCAR_CSI_CH_NONE, RCAR_VIN_CH_NONE},
++ {RCAR_CSI_CH_NONE, RCAR_VIN_CH_NONE},
++ {RCAR_CSI_CH_NONE, RCAR_VIN_CH_NONE},
++ }
++ },
++};
++
+ enum csi2_fmt {
+ RCAR_CSI_FMT_NONE = -1,
+ RCAR_CSI_RGB888,
+@@ -849,7 +893,8 @@ static int rcar_vin_videobuf_setup(struct vb2_queue *vq,
+ struct rcar_vin_priv *priv = ici->priv;
+ struct rcar_vin_cam *cam = icd->host_priv;
+
+- if (priv->chip == RCAR_H3 || priv->chip == RCAR_M3) {
++ if (priv->chip == RCAR_H3 || priv->chip == RCAR_M3 ||
++ priv->chip == RCAR_V3M) {
+ if ((priv->ratio_h > 0x10000) || (priv->ratio_v > 0x10000)) {
+ dev_err(icd->parent, "Scaling rate parameter error\n");
+ return -EINVAL;
+@@ -951,7 +996,8 @@ static int rcar_vin_setup(struct rcar_vin_priv *priv)
+ /* output format */
+ switch (icd->current_fmt->host_fmt->fourcc) {
+ case V4L2_PIX_FMT_NV12:
+- if (priv->chip == RCAR_H3 || priv->chip == RCAR_M3) {
++ if (priv->chip == RCAR_H3 || priv->chip == RCAR_M3 ||
++ priv->chip == RCAR_V3M) {
+ iowrite32(ALIGN((cam->out_width * cam->out_height),
+ 0x80), priv->base + VNUVAOF_REG);
+ dmr = VNDMR_DTMD_YCSEP_YCBCR420;
+@@ -983,6 +1029,7 @@ static int rcar_vin_setup(struct rcar_vin_priv *priv)
+ break;
+ case V4L2_PIX_FMT_XBGR32:
+ if (priv->chip != RCAR_H3 && priv->chip != RCAR_M3 &&
++ priv->chip != RCAR_V3M &&
+ priv->chip != RCAR_GEN2 && priv->chip != RCAR_H1 &&
+ priv->chip != RCAR_E1)
+ goto e_format;
+@@ -990,7 +1037,8 @@ static int rcar_vin_setup(struct rcar_vin_priv *priv)
+ dmr = VNDMR_EXRGB;
+ break;
+ case V4L2_PIX_FMT_ABGR32:
+- if (priv->chip != RCAR_H3 && priv->chip != RCAR_M3)
++ if (priv->chip != RCAR_H3 && priv->chip != RCAR_M3 &&
++ priv->chip != RCAR_V3M)
+ goto e_format;
+
+ dmr = VNDMR_EXRGB | VNDMR_DTMD_ARGB;
+@@ -1006,7 +1054,8 @@ static int rcar_vin_setup(struct rcar_vin_priv *priv)
+ if (input_is_yuv == output_is_yuv)
+ vnmc |= VNMC_BPS;
+
+- if (priv->chip == RCAR_H3 || priv->chip == RCAR_M3) {
++ if (priv->chip == RCAR_H3 || priv->chip == RCAR_M3 ||
++ priv->chip == RCAR_V3M) {
+ if (priv->pdata_flags & RCAR_VIN_CSI2)
+ vnmc &= ~VNMC_DPINE;
+ else
+@@ -1323,7 +1372,8 @@ static int rcar_vin_add_device(struct soc_camera_device *icd)
+
+ pm_runtime_get_sync(ici->v4l2_dev.dev);
+
+- if (priv->chip == RCAR_H3 || priv->chip == RCAR_M3) {
++ if (priv->chip == RCAR_H3 || priv->chip == RCAR_M3 ||
++ priv->chip == RCAR_V3M) {
+ struct v4l2_subdev *csi2_sd = find_csi2(priv);
+ int ret;
+
+@@ -1569,7 +1619,8 @@ static int rcar_vin_set_rect(struct soc_camera_device *icd)
+ break;
+ }
+
+- if (priv->chip == RCAR_H3 || priv->chip == RCAR_M3) {
++ if (priv->chip == RCAR_H3 || priv->chip == RCAR_M3 ||
++ priv->chip == RCAR_V3M) {
+ if ((icd->current_fmt->host_fmt->fourcc != V4L2_PIX_FMT_NV12)
+ && is_scaling(cam)) {
+ ret = rcar_vin_uds_set(priv, cam);
+@@ -1720,14 +1771,16 @@ static int rcar_vin_set_bus_param(struct soc_camera_device *icd)
+ if (ret < 0 && ret != -ENOIOCTLCMD)
+ return ret;
+
+- if (priv->chip == RCAR_H3 || priv->chip == RCAR_M3) {
++ if (priv->chip == RCAR_H3 || priv->chip == RCAR_M3 ||
++ priv->chip == RCAR_V3M) {
+ if (cfg.type == V4L2_MBUS_CSI2)
+ vnmc &= ~VNMC_DPINE;
+ else
+ vnmc |= VNMC_DPINE;
+ }
+
+- if (priv->chip == RCAR_H3 || priv->chip == RCAR_M3)
++ if (priv->chip == RCAR_H3 || priv->chip == RCAR_M3 ||
++ priv->chip == RCAR_V3M)
+ val = VNDMR2_FTEV;
+ else
+ val = VNDMR2_FTEV | VNDMR2_VLV(1);
+@@ -2289,7 +2342,8 @@ static int rcar_vin_try_fmt(struct soc_camera_device *icd,
+ if (ret < 0)
+ return ret;
+
+- if (priv->chip == RCAR_H3 || priv->chip == RCAR_M3) {
++ if (priv->chip == RCAR_H3 || priv->chip == RCAR_M3 ||
++ priv->chip == RCAR_V3M) {
+ /* Adjust max scaling size for Gen3 */
+ if (pix->width > 4096)
+ pix->width = priv->max_width;
+@@ -2454,6 +2508,7 @@ static int rcar_vin_cropcap(struct soc_camera_device *icd,
+
+ #ifdef CONFIG_OF
+ static const struct of_device_id rcar_vin_of_table[] = {
++ { .compatible = "renesas,vin-r8a7797", .data = (void *)RCAR_V3M },
+ { .compatible = "renesas,vin-r8a7796", .data = (void *)RCAR_M3 },
+ { .compatible = "renesas,vin-r8a7795", .data = (void *)RCAR_H3 },
+ { .compatible = "renesas,vin-r8a7794", .data = (void *)RCAR_GEN2 },
+@@ -2754,7 +2809,8 @@ static int rcar_vin_probe(struct platform_device *pdev)
+ priv->chip = (enum chip_id)match->data;
+ }
+
+- if (priv->chip == RCAR_H3 || priv->chip == RCAR_M3) {
++ if (priv->chip == RCAR_H3 || priv->chip == RCAR_M3 ||
++ priv->chip == RCAR_V3M) {
+ priv->max_width = 4096;
+ priv->max_height = 4096;
+ } else {
+@@ -2762,7 +2818,8 @@ static int rcar_vin_probe(struct platform_device *pdev)
+ priv->max_height = 2048;
+ }
+
+- if (priv->chip == RCAR_H3 || priv->chip == RCAR_M3) {
++ if (priv->chip == RCAR_H3 || priv->chip == RCAR_M3 ||
++ priv->chip == RCAR_V3M) {
+ u32 ifmd = 0;
+ bool match_flag = false;
+ const struct vin_gen3_ifmd *gen3_ifmd_table = NULL;
+@@ -2841,6 +2898,8 @@ static int rcar_vin_probe(struct platform_device *pdev)
+ gen3_ifmd_table = vin_h3_vc_ifmd;
+ else if (priv->chip == RCAR_M3)
+ gen3_ifmd_table = vin_m3_vc_ifmd;
++ else if (priv->chip == RCAR_V3M)
++ gen3_ifmd_table = vin_v3_vc_ifmd;
+
+ for (i = 0; i < num; i++) {
+ if ((gen3_ifmd_table[i].v_sel[priv->index].csi2_ch
+@@ -2983,6 +3042,9 @@ static int rcar_vin_resume(struct device *dev)
+ } else if (priv->chip == RCAR_M3) {
+ ifmd = VNCSI_IFMD_DES1;
+ gen3_ifmd_table = vin_m3_vc_ifmd;
++ } else if (priv->chip == RCAR_V3M) {
++ ifmd = VNCSI_IFMD_DES1;
++ gen3_ifmd_table = vin_v3_vc_ifmd;
+ }
+
+ for (i = 0; i < num; i++) {
+diff --git a/drivers/media/platform/vsp1/vsp1_drv.c b/drivers/media/platform/vsp1/vsp1_drv.c
+index cdaa097..6daeab4 100644
+--- a/drivers/media/platform/vsp1/vsp1_drv.c
++++ b/drivers/media/platform/vsp1/vsp1_drv.c
+@@ -893,6 +893,15 @@ void vsp1_device_put(struct vsp1_device *vsp1)
+ .wpf_count = 2,
+ .num_bru_inputs = 5,
+ .header_mode = true,
++ }, {
++ .version = VI6_IP_VERSION_MODEL_VSPD_V3M,
++ .model = "VSP2-D",
++ .gen = 3,
++ .features = VSP1_HAS_BRU | VSP1_HAS_LIF,
++ .rpf_count = 5,
++ .wpf_count = 1,
++ .num_bru_inputs = 5,
++ .header_mode = true,
+ },
+ };
+
+diff --git a/drivers/media/platform/vsp1/vsp1_lif.c b/drivers/media/platform/vsp1/vsp1_lif.c
+index b442d14..e79f9e6 100644
+--- a/drivers/media/platform/vsp1/vsp1_lif.c
++++ b/drivers/media/platform/vsp1/vsp1_lif.c
+@@ -13,6 +13,7 @@
+
+ #include <linux/device.h>
+ #include <linux/gfp.h>
++#include <linux/sys_soc.h>
+
+ #include <media/v4l2-subdev.h>
+
+@@ -23,6 +24,11 @@
+ #define LIF_MIN_SIZE 2U
+ #define LIF_MAX_SIZE 8190U
+
++static const struct soc_device_attribute r8a7797[] = {
++ { .soc_id = "r8a7797" },
++ { }
++};
++
+ /* -----------------------------------------------------------------------------
+ * Device Access
+ */
+@@ -145,7 +151,7 @@ static void lif_configure(struct vsp1_entity *entity,
+ format = vsp1_entity_get_pad_format(&lif->entity, lif->entity.config,
+ LIF_PAD_SOURCE);
+
+- if (vsp1_gen3_vspdl_check(vsp1))
++ if (vsp1_gen3_vspdl_check(vsp1) || soc_device_match(r8a7797))
+ obth = 1500;
+ else
+ obth = 3000;
+@@ -158,6 +164,10 @@ static void lif_configure(struct vsp1_entity *entity,
+ (obth << VI6_LIF_CTRL_OBTH_SHIFT) |
+ (format->code == 0 ? VI6_LIF_CTRL_CFMT : 0) |
+ VI6_LIF_CTRL_REQSEL | VI6_LIF_CTRL_LIF_EN);
++
++ if (soc_device_match(r8a7797))
++ vsp1_lif_write(lif, dl, VI6_LIF_LBA, VI6_LIF_LBA_LBA0 |
++ VI6_LIF_LBA_LBA1);
+ }
+
+ static const struct vsp1_entity_operations lif_entity_ops = {
+diff --git a/drivers/media/platform/vsp1/vsp1_regs.h b/drivers/media/platform/vsp1/vsp1_regs.h
+index 9134dbd..6c971f7 100644
+--- a/drivers/media/platform/vsp1/vsp1_regs.h
++++ b/drivers/media/platform/vsp1/vsp1_regs.h
+@@ -789,6 +789,12 @@
+ #define VI6_LIF_CSBTH_LBTH_MASK (0x7ff << 0)
+ #define VI6_LIF_CSBTH_LBTH_SHIFT 0
+
++
++#define VI6_LIF_LBA 0x3b0c
++#define VI6_LIF_LBA_LBA0 (1 << 31)
++#define VI6_LIF_LBA_LBA1 (0x600 << 16)
++
++
+ /* -----------------------------------------------------------------------------
+ * Security Control Registers
+ */
+@@ -812,6 +818,7 @@
+ #define VI6_IP_VERSION_MODEL_VSPBD_GEN3 (0x15 << 8)
+ #define VI6_IP_VERSION_MODEL_VSPBC_GEN3 (0x16 << 8)
+ #define VI6_IP_VERSION_MODEL_VSPD_GEN3 (0x17 << 8)
++#define VI6_IP_VERSION_MODEL_VSPD_V3M (0x18 << 8)
+ #define VI6_IP_VERSION_MODEL_VSPDL_GEN3 (0x19 << 8)
+
+ #define VI6_IP_VERSION_SOC_MASK (0xff << 0)
+diff --git a/drivers/mmc/host/sh_mobile_sdhi.c b/drivers/mmc/host/sh_mobile_sdhi.c
+index a7fb054..040f474 100644
+--- a/drivers/mmc/host/sh_mobile_sdhi.c
++++ b/drivers/mmc/host/sh_mobile_sdhi.c
+@@ -140,6 +140,7 @@ struct sh_mobile_sdhi_of_data {
+ { .compatible = "renesas,sdhi-r8a7796", .data = &of_rcar_gen3_compatible, },
+ { .compatible = "renesas,sdhi-r8a77965",
+ .data = &of_rcar_gen3_compatible, },
++ { .compatible = "renesas,sdhi-r8a7797", .data = &of_rcar_gen3_compatible, },
+ {},
+ };
+ MODULE_DEVICE_TABLE(of, sh_mobile_sdhi_of_match);
+diff --git a/drivers/net/ethernet/renesas/ravb_main.c b/drivers/net/ethernet/renesas/ravb_main.c
+index 5ad4d13..73fa286 100644
+--- a/drivers/net/ethernet/renesas/ravb_main.c
++++ b/drivers/net/ethernet/renesas/ravb_main.c
+@@ -1920,6 +1920,7 @@ static int ravb_mdio_release(struct ravb_private *priv)
+ { .compatible = "renesas,etheravb-r8a7795", .data = (void *)RCAR_GEN3 },
+ { .compatible = "renesas,etheravb-r8a7796", .data = (void *)RCAR_GEN3 },
+ { .compatible = "renesas,etheravb-r8a77965", .data = (void *)RCAR_GEN3 },
++ { .compatible = "renesas,etheravb-r8a7797", .data = (void *)RCAR_GEN3 },
+ { .compatible = "renesas,etheravb-rcar-gen3", .data = (void *)RCAR_GEN3 },
+ { }
+ };
+diff --git a/drivers/pinctrl/sh-pfc/Kconfig b/drivers/pinctrl/sh-pfc/Kconfig
+index 6d2cdf8..4aaf0be 100644
+--- a/drivers/pinctrl/sh-pfc/Kconfig
++++ b/drivers/pinctrl/sh-pfc/Kconfig
+@@ -84,6 +84,11 @@ config PINCTRL_PFC_R8A77965
+ depends on ARCH_R8A77965
+ select PINCTRL_SH_PFC
+
++config PINCTRL_PFC_R8A7797
++ def_bool y
++ depends on ARCH_R8A7797
++ select PINCTRL_SH_PFC
++
+ config PINCTRL_PFC_SH7203
+ def_bool y
+ depends on CPU_SUBTYPE_SH7203
+diff --git a/drivers/pinctrl/sh-pfc/Makefile b/drivers/pinctrl/sh-pfc/Makefile
+index f12017b..e263c14 100644
+--- a/drivers/pinctrl/sh-pfc/Makefile
++++ b/drivers/pinctrl/sh-pfc/Makefile
+@@ -14,6 +14,7 @@ obj-$(CONFIG_PINCTRL_PFC_R8A7795) += pfc-r8a7795.o
+ obj-$(CONFIG_PINCTRL_PFC_R8A7795) += pfc-r8a7795-es1.o
+ obj-$(CONFIG_PINCTRL_PFC_R8A7796) += pfc-r8a7796.o
+ obj-$(CONFIG_PINCTRL_PFC_R8A77965) += pfc-r8a77965.o
++obj-$(CONFIG_PINCTRL_PFC_R8A7797) += pfc-r8a7797.o
+ obj-$(CONFIG_PINCTRL_PFC_SH7203) += pfc-sh7203.o
+ obj-$(CONFIG_PINCTRL_PFC_SH7264) += pfc-sh7264.o
+ obj-$(CONFIG_PINCTRL_PFC_SH7269) += pfc-sh7269.o
+diff --git a/drivers/pinctrl/sh-pfc/core.c b/drivers/pinctrl/sh-pfc/core.c
+index a6a8f65..9aba933 100644
+--- a/drivers/pinctrl/sh-pfc/core.c
++++ b/drivers/pinctrl/sh-pfc/core.c
+@@ -5,6 +5,7 @@
+ *
+ * Copyright (C) 2008 Magnus Damm
+ * Copyright (C) 2009 - 2012 Paul Mundt
++ * Copyright (C) 2016 Renesas Electronics Corp.
+ *
+ * This file is subject to the terms and conditions of the GNU General Public
+ * License. See the file "COPYING" in the main directory of this archive
+@@ -545,6 +546,12 @@ static int sh_pfc_init_ranges(struct sh_pfc *pfc)
+ .data = &r8a77965_pinmux_info,
+ },
+ #endif
++#ifdef CONFIG_PINCTRL_PFC_R8A7797
++ {
++ .compatible = "renesas,pfc-r8a7797",
++ .data = &r8a7797_pinmux_info,
++ },
++#endif
+ #ifdef CONFIG_PINCTRL_PFC_SH73A0
+ {
+ .compatible = "renesas,pfc-sh73a0",
+diff --git a/drivers/pinctrl/sh-pfc/pfc-r8a7797.c b/drivers/pinctrl/sh-pfc/pfc-r8a7797.c
+new file mode 100644
+index 0000000..6b83f44
+--- /dev/null
++++ b/drivers/pinctrl/sh-pfc/pfc-r8a7797.c
+@@ -0,0 +1,2628 @@
++/*
++ * R8A7797 processor support - PFC hardware block.
++ *
++ * Copyright (C) 2016 Renesas Electronics Corp.
++ *
++ * This file is based on the drivers/pinctrl/sh-pfc/pfc-r8a7795.c
++ *
++ * R-Car Gen3 processor support - PFC hardware block.
++ *
++ * Copyright (C) 2015 Renesas Electronics Corporation
++ *
++ * This program is free software; you can redistribute it and/or modify
++ * it under the terms of the GNU General Public License as published by
++ * the Free Software Foundation; version 2 of the License.
++ */
++
++#include <linux/io.h>
++#include <linux/kernel.h>
++#include <linux/sys_soc.h>
++
++#include "core.h"
++#include "sh_pfc.h"
++
++#define CPU_ALL_PORT(fn, sfx) \
++ PORT_GP_CFG_22(0, fn, sfx, SH_PFC_PIN_CFG_DRIVE_STRENGTH), \
++ PORT_GP_CFG_28(1, fn, sfx, SH_PFC_PIN_CFG_DRIVE_STRENGTH), \
++ PORT_GP_CFG_17(2, fn, sfx, SH_PFC_PIN_CFG_DRIVE_STRENGTH), \
++ PORT_GP_CFG_17(3, fn, sfx, SH_PFC_PIN_CFG_DRIVE_STRENGTH | \
++ SH_PFC_PIN_CFG_IO_VOLTAGE), \
++ PORT_GP_CFG_6(4, fn, sfx, SH_PFC_PIN_CFG_DRIVE_STRENGTH), \
++ PORT_GP_CFG_15(5, fn, sfx, SH_PFC_PIN_CFG_DRIVE_STRENGTH)
++/*
++ * F_() : just information
++ * FM() : macro for FN_xxx / xxx_MARK
++ */
++
++/* GPSR0 */
++#define GPSR0_21 F_(DU_EXODDF_DU_ODDF_DISP_CDE, IP2_23_20)
++#define GPSR0_20 F_(DU_EXVSYNC_DU_VSYNC, IP2_19_16)
++#define GPSR0_19 F_(DU_EXHSYNC_DU_HSYNC, IP2_15_12)
++#define GPSR0_18 F_(DU_DOTCLKOUT, IP2_11_8)
++#define GPSR0_17 F_(DU_DB7, IP2_7_4)
++#define GPSR0_16 F_(DU_DB6, IP2_3_0)
++#define GPSR0_15 F_(DU_DB5, IP1_31_28)
++#define GPSR0_14 F_(DU_DB4, IP1_27_24)
++#define GPSR0_13 F_(DU_DB3, IP1_23_20)
++#define GPSR0_12 F_(DU_DB2, IP1_19_16)
++#define GPSR0_11 F_(DU_DG7, IP1_15_12)
++#define GPSR0_10 F_(DU_DG6, IP1_11_8)
++#define GPSR0_9 F_(DU_DG5, IP1_7_4)
++#define GPSR0_8 F_(DU_DG4, IP1_3_0)
++#define GPSR0_7 F_(DU_DG3, IP0_31_28)
++#define GPSR0_6 F_(DU_DG2, IP0_27_24)
++#define GPSR0_5 F_(DU_DR7, IP0_23_20)
++#define GPSR0_4 F_(DU_DR6, IP0_19_16)
++#define GPSR0_3 F_(DU_DR5, IP0_15_12)
++#define GPSR0_2 F_(DU_DR4, IP0_11_8)
++#define GPSR0_1 F_(DU_DR3, IP0_7_4)
++#define GPSR0_0 F_(DU_DR2, IP0_3_0)
++
++/* GPSR1 */
++#define GPSR1_27 F_(DIGRF_CLKOUT, IP8_27_24)
++#define GPSR1_26 F_(DIGRF_CLKIN, IP8_23_20)
++#define GPSR1_25 F_(CANFD_CLK_A, IP8_19_16)
++#define GPSR1_24 F_(CANFD1_RX, IP8_15_12)
++#define GPSR1_23 F_(CANFD1_TX, IP8_11_8)
++#define GPSR1_22 F_(CANFD0_RX_A, IP8_7_4)
++#define GPSR1_21 F_(CANFD0_TX_A, IP8_3_0)
++#define GPSR1_20 F_(AVB0_AVTP_CAPTURE, IP7_31_28)
++#define GPSR1_19 FM(AVB0_AVTP_MATCH)
++#define GPSR1_18 FM(AVB0_LINK)
++#define GPSR1_17 FM(AVB0_PHY_INT)
++#define GPSR1_16 FM(AVB0_MAGIC)
++#define GPSR1_15 FM(AVB0_MDC)
++#define GPSR1_14 FM(AVB0_MDIO)
++#define GPSR1_13 FM(AVB0_TXCREFCLK)
++#define GPSR1_12 FM(AVB0_TD3)
++#define GPSR1_11 FM(AVB0_TD2)
++#define GPSR1_10 FM(AVB0_TD1)
++#define GPSR1_9 FM(AVB0_TD0)
++#define GPSR1_8 FM(AVB0_TXC)
++#define GPSR1_7 FM(AVB0_TX_CTL)
++#define GPSR1_6 FM(AVB0_RD3)
++#define GPSR1_5 FM(AVB0_RD2)
++#define GPSR1_4 FM(AVB0_RD1)
++#define GPSR1_3 FM(AVB0_RD0)
++#define GPSR1_2 FM(AVB0_RXC)
++#define GPSR1_1 FM(AVB0_RX_CTL)
++#define GPSR1_0 F_(IRQ0, IP2_27_24)
++
++/* GPSR2 */
++#define GPSR2_16 F_(VI0_FIELD, IP4_31_28)
++#define GPSR2_15 F_(VI0_DATA11, IP4_27_24)
++#define GPSR2_14 F_(VI0_DATA10, IP4_23_20)
++#define GPSR2_13 F_(VI0_DATA9, IP4_19_16)
++#define GPSR2_12 F_(VI0_DATA8, IP4_15_12)
++#define GPSR2_11 F_(VI0_DATA7, IP4_11_8)
++#define GPSR2_10 F_(VI0_DATA6, IP4_7_4)
++#define GPSR2_9 F_(VI0_DATA5, IP4_3_0)
++#define GPSR2_8 F_(VI0_DATA4, IP3_31_28)
++#define GPSR2_7 F_(VI0_DATA3, IP3_27_24)
++#define GPSR2_6 F_(VI0_DATA2, IP3_23_20)
++#define GPSR2_5 F_(VI0_DATA1, IP3_19_16)
++#define GPSR2_4 F_(VI0_DATA0, IP3_15_12)
++#define GPSR2_3 F_(VI0_VSYNC_N, IP3_11_8)
++#define GPSR2_2 F_(VI0_HSYNC_N, IP3_7_4)
++#define GPSR2_1 F_(VI0_CLKENB, IP3_3_0)
++#define GPSR2_0 F_(VI0_CLK, IP2_31_28)
++
++/* GPSR3 */
++#define GPSR3_16 F_(VI1_FIELD, IP7_3_0)
++#define GPSR3_15 F_(VI1_DATA11, IP6_31_28)
++#define GPSR3_14 F_(VI1_DATA10, IP6_27_24)
++#define GPSR3_13 F_(VI1_DATA9, IP6_23_20)
++#define GPSR3_12 F_(VI1_DATA8, IP6_19_16)
++#define GPSR3_11 F_(VI1_DATA7, IP6_15_12)
++#define GPSR3_10 F_(VI1_DATA6, IP6_11_8)
++#define GPSR3_9 F_(VI1_DATA5, IP6_7_4)
++#define GPSR3_8 F_(VI1_DATA4, IP6_3_0)
++#define GPSR3_7 F_(VI1_DATA3, IP5_31_28)
++#define GPSR3_6 F_(VI1_DATA2, IP5_27_24)
++#define GPSR3_5 F_(VI1_DATA1, IP5_23_20)
++#define GPSR3_4 F_(VI1_DATA0, IP5_19_16)
++#define GPSR3_3 F_(VI1_VSYNC_N, IP5_15_12)
++#define GPSR3_2 F_(VI1_HSYNC_N, IP5_11_8)
++#define GPSR3_1 F_(VI1_CLKENB, IP5_7_4)
++#define GPSR3_0 F_(VI1_CLK, IP5_3_0)
++
++/* GPSR4 */
++#define GPSR4_5 F_(SDA2, IP7_27_24)
++#define GPSR4_4 F_(SCL2, IP7_23_20)
++#define GPSR4_3 F_(SDA1, IP7_19_16)
++#define GPSR4_2 F_(SCL1, IP7_15_12)
++#define GPSR4_1 F_(SDA0, IP7_11_8)
++#define GPSR4_0 F_(SCL0, IP7_7_4)
++
++/* GPSR5 */
++#define GPSR5_14 FM(RPC_INT_N)
++#define GPSR5_13 FM(RPC_WP_N)
++#define GPSR5_12 FM(RPC_RESET_N)
++#define GPSR5_11 FM(QSPI1_SSL)
++#define GPSR5_10 FM(QSPI1_IO3)
++#define GPSR5_9 FM(QSPI1_IO2)
++#define GPSR5_8 FM(QSPI1_MISO_IO1)
++#define GPSR5_7 FM(QSPI1_MOSI_IO0)
++#define GPSR5_6 FM(QSPI1_SPCLK)
++#define GPSR5_5 FM(QSPI0_SSL)
++#define GPSR5_4 FM(QSPI0_IO3)
++#define GPSR5_3 FM(QSPI0_IO2)
++#define GPSR5_2 FM(QSPI0_MISO_IO1)
++#define GPSR5_1 FM(QSPI0_MOSI_IO0)
++#define GPSR5_0 FM(QSPI0_SPCLK)
++
++
++/* IPSRx */ /* 0 */ /* 1 */ /* 2 */ /* 3 */ /* 4 */ /* 5 */ /* 6 */ /* 7 */ /* 8 */ /* 9 */ /* A */ /* B */ /* C */ /* D */ /* E */ /* F */
++#define IP0_3_0 FM(DU_DR2) FM(HSCK0) F_(0, 0) FM(A0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0)
++#define IP0_7_4 FM(DU_DR3) FM(HRTS0_N) F_(0, 0) FM(A1) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0)
++#define IP0_11_8 FM(DU_DR4) FM(HCTS0_N) F_(0, 0) FM(A2) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0)
++#define IP0_15_12 FM(DU_DR5) FM(HTX0) F_(0, 0) FM(A3) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0)
++#define IP0_19_16 FM(DU_DR6) FM(MSIOF3_RXD) F_(0, 0) FM(A4) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0)
++#define IP0_23_20 FM(DU_DR7) FM(MSIOF3_TXD) F_(0, 0) FM(A5) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0)
++#define IP0_27_24 FM(DU_DG2) FM(MSIOF3_SS1) F_(0, 0) FM(A6) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0)
++#define IP0_31_28 FM(DU_DG3) FM(MSIOF3_SS2) F_(0, 0) FM(A7) FM(PWMFSW0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0)
++#define IP1_3_0 FM(DU_DG4) F_(0, 0) F_(0, 0) FM(A8) FM(FSO_CFE_0_N_A) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0)
++#define IP1_7_4 FM(DU_DG5) F_(0, 0) F_(0, 0) FM(A9) FM(FSO_CFE_1_N_A) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0)
++#define IP1_11_8 FM(DU_DG6) F_(0, 0) F_(0, 0) FM(A10) FM(FSO_TOE_N_A) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0)
++#define IP1_15_12 FM(DU_DG7) F_(0, 0) F_(0, 0) FM(A11) FM(IRQ1) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0)
++#define IP1_19_16 FM(DU_DB2) F_(0, 0) F_(0, 0) FM(A12) FM(IRQ2) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0)
++#define IP1_23_20 FM(DU_DB3) F_(0, 0) F_(0, 0) FM(A13) FM(FXR_CLKOUT1) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0)
++#define IP1_27_24 FM(DU_DB4) F_(0, 0) F_(0, 0) FM(A14) FM(FXR_CLKOUT2) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0)
++#define IP1_31_28 FM(DU_DB5) F_(0, 0) F_(0, 0) FM(A15) FM(FXR_TXENA_N) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0)
++#define IP2_3_0 FM(DU_DB6) F_(0, 0) F_(0, 0) FM(A16) FM(FXR_TXENB_N) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0)
++#define IP2_7_4 FM(DU_DB7) F_(0, 0) F_(0, 0) FM(A17) FM(STPWT_EXTFXR) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0)
++#define IP2_11_8 FM(DU_DOTCLKOUT) FM(SCIF_CLK_A) F_(0, 0) FM(A18) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0)
++#define IP2_15_12 FM(DU_EXHSYNC_DU_HSYNC) FM(HRX0) F_(0, 0) FM(A19) FM(IRQ3) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0)
++#define IP2_19_16 FM(DU_EXVSYNC_DU_VSYNC) FM(MSIOF3_SCK) F_(0, 0) FM(A20) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0)
++#define IP2_23_20 FM(DU_EXODDF_DU_ODDF_DISP_CDE) FM(MSIOF3_SYNC) F_(0, 0) FM(A21) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0)
++#define IP2_27_24 FM(IRQ0) FM(CC5_OSCOUT) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0)
++#define IP2_31_28 FM(VI0_CLK) FM(MSIOF2_SCK) FM(SCK3) F_(0, 0) FM(HSCK3) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0)
++#define IP3_3_0 FM(VI0_CLKENB) FM(MSIOF2_RXD) FM(RX3) FM(RD_WR_N) FM(HCTS3_N) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0)
++#define IP3_7_4 FM(VI0_HSYNC_N) FM(MSIOF2_TXD) FM(TX3) F_(0, 0) FM(HRTS3_N) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0)
++#define IP3_11_8 FM(VI0_VSYNC_N) FM(MSIOF2_SYNC) FM(CTS3_N) F_(0, 0) FM(HTX3) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0)
++#define IP3_15_12 FM(VI0_DATA0) FM(MSIOF2_SS1) FM(RTS3_N_TANS) F_(0, 0) FM(HRX3) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0)
++#define IP3_19_16 FM(VI0_DATA1) FM(MSIOF2_SS2) FM(SCK1) F_(0, 0) FM(SPEEDIN_A) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0)
++#define IP3_23_20 FM(VI0_DATA2) FM(AVB0_AVTP_PPS) FM(SDA3_A) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0)
++#define IP3_27_24 FM(VI0_DATA3) FM(HSCK1) FM(SCL3_A) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0)
++#define IP3_31_28 FM(VI0_DATA4) FM(HRTS1_N) FM(RX1_A) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0)
++#define IP4_3_0 FM(VI0_DATA5) FM(HCTS1_N) FM(TX1_A) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0)
++#define IP4_7_4 FM(VI0_DATA6) FM(HTX1) FM(CTS1_N) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0)
++#define IP4_11_8 FM(VI0_DATA7) FM(HRX1) FM(RTS1_N_TANS) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0)
++#define IP4_15_12 FM(VI0_DATA8) FM(HSCK2) FM(PWM0_A) FM(A22) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0)
++#define IP4_19_16 FM(VI0_DATA9) FM(HCTS2_N) FM(PWM1_A) FM(A23) FM(FSO_CFE_0_N_B) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0)
++#define IP4_23_20 FM(VI0_DATA10) FM(HRTS2_N) FM(PWM2_A) FM(A24) FM(FSO_CFE_1_N_B) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0)
++#define IP4_27_24 FM(VI0_DATA11) FM(HTX2) FM(PWM3_A) FM(A25) FM(FSO_TOE_N_B) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0)
++#define IP4_31_28 FM(VI0_FIELD) FM(HRX2) FM(PWM4_A) FM(CS1_N_A26) FM(FSCLKST2_N_A) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0)
++#define IP5_3_0 FM(VI1_CLK) FM(MSIOF1_RXD) F_(0, 0) FM(CS0_N) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0)
++#define IP5_7_4 FM(VI1_CLKENB) FM(MSIOF1_TXD) F_(0, 0) FM(D0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0)
++#define IP5_11_8 FM(VI1_HSYNC_N) FM(MSIOF1_SCK) F_(0, 0) FM(D1) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0)
++#define IP5_15_12 FM(VI1_VSYNC_N) FM(MSIOF1_SYNC) F_(0, 0) FM(D2) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0)
++#define IP5_19_16 FM(VI1_DATA0) FM(MSIOF1_SS1) F_(0, 0) FM(D3) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0)
++#define IP5_23_20 FM(VI1_DATA1) FM(MSIOF1_SS2) F_(0, 0) FM(D4) FM(MMC_CMD) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0)
++#define IP5_27_24 FM(VI1_DATA2) FM(CANFD0_TX_B) F_(0, 0) FM(D5) FM(MMC_D0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0)
++#define IP5_31_28 FM(VI1_DATA3) FM(CANFD0_RX_B) F_(0, 0) FM(D6) FM(MMC_D1) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0)
++#define IP6_3_0 FM(VI1_DATA4) FM(CANFD_CLK_B) F_(0, 0) FM(D7) FM(MMC_D2) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0)
++#define IP6_7_4 FM(VI1_DATA5) F_(0,0) FM(SCK4) FM(D8) FM(MMC_D3) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0)
++#define IP6_11_8 FM(VI1_DATA6) F_(0,0) FM(RX4) FM(D9) FM(MMC_CLK) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0)
++#define IP6_15_12 FM(VI1_DATA7) F_(0,0) FM(TX4) FM(D10) FM(MMC_D4) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0)
++#define IP6_19_16 FM(VI1_DATA8) F_(0,0) FM(CTS4_N) FM(D11) FM(MMC_D5) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0)
++#define IP6_23_20 FM(VI1_DATA9) F_(0,0) FM(RTS4_N_TANS) FM(D12) FM(MMC_D6) FM(SCL3_B) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0)
++#define IP6_27_24 FM(VI1_DATA10) F_(0,0) F_(0, 0) FM(D13) FM(MMC_D7) FM(SDA3_B) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0)
++#define IP6_31_28 FM(VI1_DATA11) FM(SCL4) FM(IRQ4) FM(D14) FM(MMC_WP) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0)
++#define IP7_3_0 FM(VI1_FIELD) FM(SDA4) FM(IRQ5) FM(D15) FM(MMC_CD) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0)
++#define IP7_7_4 FM(SCL0) FM(DU_DR0) FM(TPU0TO0) FM(CLKOUT) F_(0, 0) FM(MSIOF0_RXD) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0)
++#define IP7_11_8 FM(SDA0) FM(DU_DR1) FM(TPU0TO1) FM(BS_N) FM(SCK0) FM(MSIOF0_TXD) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0)
++#define IP7_15_12 FM(SCL1) FM(DU_DG0) FM(TPU0TO2) FM(RD_N) FM(CTS0_N) FM(MSIOF0_SCK) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0)
++#define IP7_19_16 FM(SDA1) FM(DU_DG1) FM(TPU0TO3) FM(WE0_N) FM(RTS0_N_TANS) FM(MSIOF0_SYNC) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0)
++#define IP7_23_20 FM(SCL2) FM(DU_DB0) FM(TCLK1_A) FM(WE1_N) FM(RX0) FM(MSIOF0_SS1) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0)
++#define IP7_27_24 FM(SDA2) FM(DU_DB1) FM(TCLK2_A) FM(EX_WAIT0) FM(TX0) FM(MSIOF0_SS2) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0)
++#define IP7_31_28 FM(AVB0_AVTP_CAPTURE) F_(0, 0) F_(0, 0) F_(0, 0) FM(FSCLKST2_N_B) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0)
++#define IP8_3_0 FM(CANFD0_TX_A) FM(FXR_TXDA) FM(PWM0_B) FM(DU_DISP) FM(FSCLKST2_N_C) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0)
++#define IP8_7_4 FM(CANFD0_RX_A) FM(RXDA_EXTFXR) FM(PWM1_B) FM(DU_CDE) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0)
++#define IP8_11_8 FM(CANFD1_TX) FM(FXR_TXDB) FM(PWM2_B) FM(TCLK1_B) FM(TX1_B) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0)
++#define IP8_15_12 FM(CANFD1_RX) FM(RXDB_EXTFXR) FM(PWM3_B) FM(TCLK2_B) FM(RX1_B) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0)
++#define IP8_19_16 FM(CANFD_CLK_A) FM(CLK_EXTFXR) FM(PWM4_B) FM(SPEEDIN_B) FM(SCIF_CLK_B) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0)
++#define IP8_23_20 FM(DIGRF_CLKIN) FM(DIGRF_CLKEN_IN) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0)
++#define IP8_27_24 FM(DIGRF_CLKOUT) FM(DIGRF_CLKEN_OUT) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0)
++#define IP8_31_28 F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0)
++
++#define PINMUX_GPSR \
++\
++ GPSR1_27 \
++ GPSR1_26 \
++ GPSR1_25 \
++ GPSR1_24 \
++ GPSR1_23 \
++ GPSR1_22 \
++GPSR0_21 GPSR1_21 \
++GPSR0_20 GPSR1_20 \
++GPSR0_19 GPSR1_19 \
++GPSR0_18 GPSR1_18 \
++GPSR0_17 GPSR1_17 \
++GPSR0_16 GPSR1_16 GPSR2_16 GPSR3_16 \
++GPSR0_15 GPSR1_15 GPSR2_15 GPSR3_15 \
++GPSR0_14 GPSR1_14 GPSR2_14 GPSR3_14 GPSR5_14 \
++GPSR0_13 GPSR1_13 GPSR2_13 GPSR3_13 GPSR5_13 \
++GPSR0_12 GPSR1_12 GPSR2_12 GPSR3_12 GPSR5_12 \
++GPSR0_11 GPSR1_11 GPSR2_11 GPSR3_11 GPSR5_11 \
++GPSR0_10 GPSR1_10 GPSR2_10 GPSR3_10 GPSR5_10 \
++GPSR0_9 GPSR1_9 GPSR2_9 GPSR3_9 GPSR5_9 \
++GPSR0_8 GPSR1_8 GPSR2_8 GPSR3_8 GPSR5_8 \
++GPSR0_7 GPSR1_7 GPSR2_7 GPSR3_7 GPSR5_7 \
++GPSR0_6 GPSR1_6 GPSR2_6 GPSR3_6 GPSR5_6 \
++GPSR0_5 GPSR1_5 GPSR2_5 GPSR3_5 GPSR4_5 GPSR5_5 \
++GPSR0_4 GPSR1_4 GPSR2_4 GPSR3_4 GPSR4_4 GPSR5_4 \
++GPSR0_3 GPSR1_3 GPSR2_3 GPSR3_3 GPSR4_3 GPSR5_3 \
++GPSR0_2 GPSR1_2 GPSR2_2 GPSR3_2 GPSR4_2 GPSR5_2 \
++GPSR0_1 GPSR1_1 GPSR2_1 GPSR3_1 GPSR4_1 GPSR5_1 \
++GPSR0_0 GPSR1_0 GPSR2_0 GPSR3_0 GPSR4_0 GPSR5_0
++
++#define PINMUX_IPSR \
++\
++FM(IP0_3_0) IP0_3_0 FM(IP1_3_0) IP1_3_0 FM(IP2_3_0) IP2_3_0 FM(IP3_3_0) IP3_3_0 \
++FM(IP0_7_4) IP0_7_4 FM(IP1_7_4) IP1_7_4 FM(IP2_7_4) IP2_7_4 FM(IP3_7_4) IP3_7_4 \
++FM(IP0_11_8) IP0_11_8 FM(IP1_11_8) IP1_11_8 FM(IP2_11_8) IP2_11_8 FM(IP3_11_8) IP3_11_8 \
++FM(IP0_15_12) IP0_15_12 FM(IP1_15_12) IP1_15_12 FM(IP2_15_12) IP2_15_12 FM(IP3_15_12) IP3_15_12 \
++FM(IP0_19_16) IP0_19_16 FM(IP1_19_16) IP1_19_16 FM(IP2_19_16) IP2_19_16 FM(IP3_19_16) IP3_19_16 \
++FM(IP0_23_20) IP0_23_20 FM(IP1_23_20) IP1_23_20 FM(IP2_23_20) IP2_23_20 FM(IP3_23_20) IP3_23_20 \
++FM(IP0_27_24) IP0_27_24 FM(IP1_27_24) IP1_27_24 FM(IP2_27_24) IP2_27_24 FM(IP3_27_24) IP3_27_24 \
++FM(IP0_31_28) IP0_31_28 FM(IP1_31_28) IP1_31_28 FM(IP2_31_28) IP2_31_28 FM(IP3_31_28) IP3_31_28 \
++\
++FM(IP4_3_0) IP4_3_0 FM(IP5_3_0) IP5_3_0 FM(IP6_3_0) IP6_3_0 FM(IP7_3_0) IP7_3_0 \
++FM(IP4_7_4) IP4_7_4 FM(IP5_7_4) IP5_7_4 FM(IP6_7_4) IP6_7_4 FM(IP7_7_4) IP7_7_4 \
++FM(IP4_11_8) IP4_11_8 FM(IP5_11_8) IP5_11_8 FM(IP6_11_8) IP6_11_8 FM(IP7_11_8) IP7_11_8 \
++FM(IP4_15_12) IP4_15_12 FM(IP5_15_12) IP5_15_12 FM(IP6_15_12) IP6_15_12 FM(IP7_15_12) IP7_15_12 \
++FM(IP4_19_16) IP4_19_16 FM(IP5_19_16) IP5_19_16 FM(IP6_19_16) IP6_19_16 FM(IP7_19_16) IP7_19_16 \
++FM(IP4_23_20) IP4_23_20 FM(IP5_23_20) IP5_23_20 FM(IP6_23_20) IP6_23_20 FM(IP7_23_20) IP7_23_20 \
++FM(IP4_27_24) IP4_27_24 FM(IP5_27_24) IP5_27_24 FM(IP6_27_24) IP6_27_24 FM(IP7_27_24) IP7_27_24 \
++FM(IP4_31_28) IP4_31_28 FM(IP5_31_28) IP5_31_28 FM(IP6_31_28) IP6_31_28 FM(IP7_31_28) IP7_31_28 \
++\
++FM(IP8_3_0) IP8_3_0 \
++FM(IP8_7_4) IP8_7_4 \
++FM(IP8_11_8) IP8_11_8 \
++FM(IP8_15_12) IP8_15_12 \
++FM(IP8_19_16) IP8_19_16 \
++FM(IP8_23_20) IP8_23_20 \
++FM(IP8_27_24) IP8_27_24 \
++FM(IP8_31_28) IP8_31_28
++
++/*
++ Set Value = H'0 Set Value = H'1
++Register Function Pin Function Pin
++------------------------------------------------------------
++sel_i2c3 SDA3_A VI0_DATA2 SDA3_B VI1_DATA10
++ SCL3_A VI0_DATA3 SCL3_B VI1_DATA9
++sel_hscif0 HSCIF0_A SCIF_CLK HSCIF0_B SCIF_CLK
++sel_scif1 SCIF1_A RX1 SCIF1_B TX1
++ SCIF1_A TX1 SCIF1_B RX1
++sel_canfd0 CANFD0_A CANFD0_TX CANFD0_B CANFD0_TX
++ CANFD0_A CANFD0_RX CANFD0_B CANFD0_RX
++ CANFD0_A CANFD_CLK CANFD0_B CANFD_CLK
++sel_pwm4 PWM4_A PWM4 PWM4_B PWM4
++sel_pwm3 PWM3_A PWM3 PWM3_B PWM3
++sel_pwm2 PWM2_A PWM2 PWM2_B PWM2
++sel_pwm1 PWM1_A PWM1 PWM1_B PWM1
++sel_pwm0 PWM0_A PWM0 PWM0_B PWM0
++sel_rfso RFSO_A FSO_CFE_0_N RFSO_B FSO_CFE_0_N
++ RFSO_A FSO_CFE_1_N RFSO_B FSO_CFE_1_N
++ RFSO_A FSO_TOE_N RFSO_B FSO_TOE_N
++sel_rsp RSP_A SPEEDIN RSP_B SPEEDIN
++sel_tmu TMU_A TCLK1 TMU_B TCLK1
++ TMU_A TCLK2 TMU_B TCLK2
++*/
++/* MOD_SEL0 */ /* 0 */ /* 1 */ /* 2 */ /* 3 */ /* 4 */ /* 5 */ /* 6 */ /* 7 */
++#define MOD_SEL0_11 FM(SEL_I2C3_0) FM(SEL_I2C3_1)
++#define MOD_SEL0_10 FM(SEL_HSCIF0_0) FM(SEL_HSCIF0_1)
++#define MOD_SEL0_9 FM(SEL_SCIF1_0) FM(SEL_SCIF1_1)
++#define MOD_SEL0_8 FM(SEL_CANFD0_0) FM(SEL_CANFD0_1)
++#define MOD_SEL0_7 FM(SEL_PWM4_0) FM(SEL_PWM4_1)
++#define MOD_SEL0_6 FM(SEL_PWM3_0) FM(SEL_PWM3_1)
++#define MOD_SEL0_5 FM(SEL_PWM2_0) FM(SEL_PWM2_1)
++#define MOD_SEL0_4 FM(SEL_PWM1_0) FM(SEL_PWM1_1)
++#define MOD_SEL0_3 FM(SEL_PWM0_0) FM(SEL_PWM0_1)
++#define MOD_SEL0_2 FM(SEL_RFSO_0) FM(SEL_RFSO_1)
++#define MOD_SEL0_1 FM(SEL_RSP_0) FM(SEL_RSP_1)
++#define MOD_SEL0_0 FM(SEL_TMU_0) FM(SEL_TMU_1)
++
++#define PINMUX_MOD_SELS \
++\
++MOD_SEL0_11 \
++MOD_SEL0_10 \
++MOD_SEL0_9 \
++MOD_SEL0_8 \
++MOD_SEL0_7 \
++MOD_SEL0_6 \
++MOD_SEL0_5 \
++MOD_SEL0_4 \
++MOD_SEL0_3 \
++MOD_SEL0_2 \
++MOD_SEL0_1 \
++MOD_SEL0_0
++
++enum {
++ PINMUX_RESERVED = 0,
++
++ PINMUX_DATA_BEGIN,
++ GP_ALL(DATA),
++ PINMUX_DATA_END,
++
++#define F_(x, y)
++#define FM(x) FN_##x,
++ PINMUX_FUNCTION_BEGIN,
++ GP_ALL(FN),
++ PINMUX_GPSR
++ PINMUX_IPSR
++ PINMUX_MOD_SELS
++ PINMUX_FUNCTION_END,
++#undef F_
++#undef FM
++
++#define F_(x, y)
++#define FM(x) x##_MARK,
++ PINMUX_MARK_BEGIN,
++ PINMUX_GPSR
++ PINMUX_IPSR
++ PINMUX_MOD_SELS
++ PINMUX_MARK_END,
++#undef F_
++#undef FM
++};
++
++static const u16 pinmux_data[] = {
++ PINMUX_DATA_GP_ALL(),
++
++ PINMUX_SINGLE(AVB0_RX_CTL),
++ PINMUX_SINGLE(AVB0_RXC),
++ PINMUX_SINGLE(AVB0_RD0),
++ PINMUX_SINGLE(AVB0_RD1),
++ PINMUX_SINGLE(AVB0_RD2),
++ PINMUX_SINGLE(AVB0_RD3),
++ PINMUX_SINGLE(AVB0_TX_CTL),
++ PINMUX_SINGLE(AVB0_TXC),
++ PINMUX_SINGLE(AVB0_TD0),
++ PINMUX_SINGLE(AVB0_TD1),
++ PINMUX_SINGLE(AVB0_TD2),
++ PINMUX_SINGLE(AVB0_TD3),
++ PINMUX_SINGLE(AVB0_TXCREFCLK),
++ PINMUX_SINGLE(AVB0_MDIO),
++ PINMUX_SINGLE(AVB0_MDC),
++ PINMUX_SINGLE(AVB0_MAGIC),
++ PINMUX_SINGLE(AVB0_PHY_INT),
++ PINMUX_SINGLE(AVB0_LINK),
++ PINMUX_SINGLE(AVB0_AVTP_MATCH),
++
++ PINMUX_SINGLE(QSPI0_SPCLK),
++ PINMUX_SINGLE(QSPI0_MOSI_IO0),
++ PINMUX_SINGLE(QSPI0_MISO_IO1),
++ PINMUX_SINGLE(QSPI0_IO2),
++ PINMUX_SINGLE(QSPI0_IO3),
++ PINMUX_SINGLE(QSPI0_SSL),
++ PINMUX_SINGLE(QSPI1_SPCLK),
++ PINMUX_SINGLE(QSPI1_MOSI_IO0),
++ PINMUX_SINGLE(QSPI1_MISO_IO1),
++ PINMUX_SINGLE(QSPI1_IO2),
++ PINMUX_SINGLE(QSPI1_IO3),
++ PINMUX_SINGLE(QSPI1_SSL),
++ PINMUX_SINGLE(RPC_RESET_N),
++ PINMUX_SINGLE(RPC_WP_N),
++ PINMUX_SINGLE(RPC_INT_N),
++
++ /* IPSR0 */
++ PINMUX_IPSR_GPSR(IP0_3_0, DU_DR2),
++ PINMUX_IPSR_GPSR(IP0_3_0, HSCK0),
++ PINMUX_IPSR_GPSR(IP0_3_0, A0),
++
++ PINMUX_IPSR_GPSR(IP0_7_4, DU_DR3),
++ PINMUX_IPSR_GPSR(IP0_7_4, HRTS0_N),
++ PINMUX_IPSR_GPSR(IP0_7_4, A1),
++
++ PINMUX_IPSR_GPSR(IP0_11_8, DU_DR4),
++ PINMUX_IPSR_GPSR(IP0_11_8, HCTS0_N),
++ PINMUX_IPSR_GPSR(IP0_11_8, A2),
++
++ PINMUX_IPSR_GPSR(IP0_15_12, DU_DR5),
++ PINMUX_IPSR_GPSR(IP0_15_12, HTX0),
++ PINMUX_IPSR_GPSR(IP0_15_12, A3),
++
++ PINMUX_IPSR_GPSR(IP0_19_16, DU_DR6),
++ PINMUX_IPSR_GPSR(IP0_19_16, MSIOF3_RXD),
++ PINMUX_IPSR_GPSR(IP0_19_16, A4),
++
++ PINMUX_IPSR_GPSR(IP0_23_20, DU_DR7),
++ PINMUX_IPSR_GPSR(IP0_23_20, MSIOF3_TXD),
++ PINMUX_IPSR_GPSR(IP0_23_20, A5),
++
++ PINMUX_IPSR_GPSR(IP0_27_24, DU_DG2),
++ PINMUX_IPSR_GPSR(IP0_27_24, MSIOF3_SS1),
++ PINMUX_IPSR_GPSR(IP0_27_24, A6),
++
++ PINMUX_IPSR_GPSR(IP0_31_28, DU_DG3),
++ PINMUX_IPSR_GPSR(IP0_31_28, MSIOF3_SS2),
++ PINMUX_IPSR_GPSR(IP0_31_28, A7),
++ PINMUX_IPSR_GPSR(IP0_31_28, PWMFSW0),
++
++ /* IPSR1 */
++ PINMUX_IPSR_GPSR(IP1_3_0, DU_DG4),
++ PINMUX_IPSR_GPSR(IP1_3_0, A8),
++ PINMUX_IPSR_MSEL(IP1_3_0, FSO_CFE_0_N_A, SEL_RFSO_0),
++
++ PINMUX_IPSR_GPSR(IP1_7_4, DU_DG5),
++ PINMUX_IPSR_GPSR(IP1_7_4, A9),
++ PINMUX_IPSR_MSEL(IP1_7_4, FSO_CFE_1_N_A, SEL_RFSO_0),
++
++ PINMUX_IPSR_GPSR(IP1_11_8, DU_DG6),
++ PINMUX_IPSR_GPSR(IP1_11_8, A10),
++ PINMUX_IPSR_MSEL(IP1_11_8, FSO_TOE_N_A, SEL_RFSO_0),
++
++ PINMUX_IPSR_GPSR(IP1_15_12, DU_DG7),
++ PINMUX_IPSR_GPSR(IP1_15_12, A11),
++ PINMUX_IPSR_GPSR(IP1_15_12, IRQ1),
++
++ PINMUX_IPSR_GPSR(IP1_19_16, DU_DB2),
++ PINMUX_IPSR_GPSR(IP1_19_16, A12),
++ PINMUX_IPSR_GPSR(IP1_19_16, IRQ2),
++
++ PINMUX_IPSR_GPSR(IP1_23_20, DU_DB3),
++ PINMUX_IPSR_GPSR(IP1_23_20, A13),
++ PINMUX_IPSR_GPSR(IP1_23_20, FXR_CLKOUT1),
++
++ PINMUX_IPSR_GPSR(IP1_27_24, DU_DB4),
++ PINMUX_IPSR_GPSR(IP1_27_24, A14),
++ PINMUX_IPSR_GPSR(IP1_27_24, FXR_CLKOUT2),
++
++ PINMUX_IPSR_GPSR(IP1_31_28, DU_DB5),
++ PINMUX_IPSR_GPSR(IP1_31_28, A15),
++ PINMUX_IPSR_GPSR(IP1_31_28, FXR_TXENA_N),
++
++ /* IPSR2 */
++ PINMUX_IPSR_GPSR(IP2_3_0, DU_DB6),
++ PINMUX_IPSR_GPSR(IP2_3_0, A16),
++ PINMUX_IPSR_GPSR(IP2_3_0, FXR_TXENB_N),
++
++ PINMUX_IPSR_GPSR(IP2_7_4, DU_DB7),
++ PINMUX_IPSR_GPSR(IP2_7_4, A17),
++ PINMUX_IPSR_GPSR(IP2_7_4, STPWT_EXTFXR),
++
++ PINMUX_IPSR_GPSR(IP2_11_8, DU_DOTCLKOUT),
++ PINMUX_IPSR_MSEL(IP2_11_8, SCIF_CLK_A, SEL_HSCIF0_0),
++ PINMUX_IPSR_GPSR(IP2_11_8, A18),
++
++ PINMUX_IPSR_GPSR(IP2_15_12, DU_EXHSYNC_DU_HSYNC),
++ PINMUX_IPSR_GPSR(IP2_15_12, HRX0),
++ PINMUX_IPSR_GPSR(IP2_15_12, A19),
++ PINMUX_IPSR_GPSR(IP2_15_12, IRQ3),
++
++ PINMUX_IPSR_GPSR(IP2_19_16, DU_EXVSYNC_DU_VSYNC),
++ PINMUX_IPSR_GPSR(IP2_19_16, MSIOF3_SCK),
++ PINMUX_IPSR_GPSR(IP2_19_16, A20),
++
++ PINMUX_IPSR_GPSR(IP2_23_20, DU_EXODDF_DU_ODDF_DISP_CDE),
++ PINMUX_IPSR_GPSR(IP2_23_20, MSIOF3_SYNC),
++ PINMUX_IPSR_GPSR(IP2_23_20, A21),
++
++ PINMUX_IPSR_GPSR(IP2_27_24, IRQ0),
++ PINMUX_IPSR_GPSR(IP2_27_24, CC5_OSCOUT),
++
++ PINMUX_IPSR_GPSR(IP2_31_28, VI0_CLK),
++ PINMUX_IPSR_GPSR(IP2_31_28, MSIOF2_SCK),
++ PINMUX_IPSR_GPSR(IP2_31_28, SCK3),
++ PINMUX_IPSR_GPSR(IP2_31_28, HSCK3),
++
++ /* IPSR3 */
++ PINMUX_IPSR_GPSR(IP3_3_0, VI0_CLKENB),
++ PINMUX_IPSR_GPSR(IP3_3_0, MSIOF2_RXD),
++ PINMUX_IPSR_GPSR(IP3_3_0, RX3),
++ PINMUX_IPSR_GPSR(IP3_3_0, RD_WR_N),
++ PINMUX_IPSR_GPSR(IP3_3_0, HCTS3_N),
++
++ PINMUX_IPSR_GPSR(IP3_7_4, VI0_HSYNC_N),
++ PINMUX_IPSR_GPSR(IP3_7_4, MSIOF2_TXD),
++ PINMUX_IPSR_GPSR(IP3_7_4, TX3),
++ PINMUX_IPSR_GPSR(IP3_7_4, HRTS3_N),
++
++ PINMUX_IPSR_GPSR(IP3_11_8, VI0_VSYNC_N),
++ PINMUX_IPSR_GPSR(IP3_11_8, MSIOF2_SYNC),
++ PINMUX_IPSR_GPSR(IP3_11_8, CTS3_N),
++ PINMUX_IPSR_GPSR(IP3_11_8, HTX3),
++
++ PINMUX_IPSR_GPSR(IP3_15_12, VI0_DATA0),
++ PINMUX_IPSR_GPSR(IP3_15_12, MSIOF2_SS1),
++ PINMUX_IPSR_GPSR(IP3_15_12, RTS3_N_TANS),
++ PINMUX_IPSR_GPSR(IP3_15_12, HRX3),
++
++ PINMUX_IPSR_GPSR(IP3_19_16, VI0_DATA1),
++ PINMUX_IPSR_GPSR(IP3_19_16, MSIOF2_SS2),
++ PINMUX_IPSR_GPSR(IP3_19_16, SCK1),
++ PINMUX_IPSR_MSEL(IP3_19_16, SPEEDIN_A, SEL_RSP_1),
++
++ PINMUX_IPSR_GPSR(IP3_23_20, VI0_DATA2),
++ PINMUX_IPSR_GPSR(IP3_23_20, AVB0_AVTP_PPS),
++ PINMUX_IPSR_GPSR(IP3_23_20, SDA3_A),
++
++ PINMUX_IPSR_GPSR(IP3_27_24, VI0_DATA3),
++ PINMUX_IPSR_GPSR(IP3_27_24, HSCK1),
++ PINMUX_IPSR_GPSR(IP3_27_24, SCL3_A),
++
++ PINMUX_IPSR_GPSR(IP3_31_28, VI0_DATA4),
++ PINMUX_IPSR_GPSR(IP3_31_28, HRTS1_N),
++ PINMUX_IPSR_MSEL(IP3_31_28, RX1_A, SEL_SCIF1_0),
++
++ /* IPSR4 */
++ PINMUX_IPSR_GPSR(IP4_3_0, VI0_DATA5),
++ PINMUX_IPSR_GPSR(IP4_3_0, HCTS1_N),
++ PINMUX_IPSR_MSEL(IP4_3_0, TX1_A, SEL_SCIF1_0),
++
++ PINMUX_IPSR_GPSR(IP4_7_4, VI0_DATA6),
++ PINMUX_IPSR_GPSR(IP4_7_4, HTX1),
++ PINMUX_IPSR_GPSR(IP4_7_4, CTS1_N),
++
++ PINMUX_IPSR_GPSR(IP4_11_8, VI0_DATA7),
++ PINMUX_IPSR_GPSR(IP4_11_8, HRX1),
++ PINMUX_IPSR_GPSR(IP4_11_8, RTS1_N_TANS),
++
++ PINMUX_IPSR_GPSR(IP4_15_12, VI0_DATA8),
++ PINMUX_IPSR_GPSR(IP4_15_12, HSCK2),
++ PINMUX_IPSR_MSEL(IP4_15_12, PWM0_A, SEL_PWM0_0),
++ PINMUX_IPSR_GPSR(IP4_15_12, A22),
++
++ PINMUX_IPSR_GPSR(IP4_19_16, VI0_DATA9),
++ PINMUX_IPSR_GPSR(IP4_19_16, HCTS2_N),
++ PINMUX_IPSR_MSEL(IP4_19_16, PWM1_A, SEL_PWM1_0),
++ PINMUX_IPSR_GPSR(IP4_19_16, A23),
++ PINMUX_IPSR_MSEL(IP4_19_16, FSO_CFE_0_N_B, SEL_RFSO_1),
++
++ PINMUX_IPSR_GPSR(IP4_23_20, VI0_DATA10),
++ PINMUX_IPSR_GPSR(IP4_23_20, HRTS2_N),
++ PINMUX_IPSR_MSEL(IP4_23_20, PWM2_A, SEL_PWM2_0),
++ PINMUX_IPSR_GPSR(IP4_23_20, A24),
++ PINMUX_IPSR_MSEL(IP4_23_20, FSO_CFE_1_N_B, SEL_RFSO_1),
++
++ PINMUX_IPSR_GPSR(IP4_27_24, VI0_DATA11),
++ PINMUX_IPSR_GPSR(IP4_27_24, HTX2),
++ PINMUX_IPSR_MSEL(IP4_27_24, PWM3_A, SEL_PWM3_0),
++ PINMUX_IPSR_GPSR(IP4_27_24, A25),
++ PINMUX_IPSR_MSEL(IP4_27_24, FSO_TOE_N_B, SEL_RFSO_1),
++
++ PINMUX_IPSR_GPSR(IP4_31_28, VI0_FIELD),
++ PINMUX_IPSR_GPSR(IP4_31_28, HRX2),
++ PINMUX_IPSR_MSEL(IP4_31_28, PWM4_A, SEL_PWM4_0),
++ PINMUX_IPSR_GPSR(IP4_31_28, CS1_N_A26),
++ PINMUX_IPSR_GPSR(IP4_31_28, FSCLKST2_N_A),
++
++ /* IPSR5 */
++ PINMUX_IPSR_GPSR(IP5_3_0, VI1_CLK),
++ PINMUX_IPSR_GPSR(IP5_3_0, MSIOF1_RXD),
++ PINMUX_IPSR_GPSR(IP5_3_0, CS0_N),
++
++ PINMUX_IPSR_GPSR(IP5_7_4, VI1_CLKENB),
++ PINMUX_IPSR_GPSR(IP5_7_4, MSIOF1_TXD),
++ PINMUX_IPSR_GPSR(IP5_7_4, D0),
++
++ PINMUX_IPSR_GPSR(IP5_11_8, VI1_HSYNC_N),
++ PINMUX_IPSR_GPSR(IP5_11_8, MSIOF1_SCK),
++ PINMUX_IPSR_GPSR(IP5_11_8, D1),
++
++ PINMUX_IPSR_GPSR(IP5_15_12, VI1_VSYNC_N),
++ PINMUX_IPSR_GPSR(IP5_15_12, MSIOF1_SYNC),
++ PINMUX_IPSR_GPSR(IP5_15_12, D2),
++
++ PINMUX_IPSR_GPSR(IP5_19_16, VI1_DATA0),
++ PINMUX_IPSR_GPSR(IP5_19_16, MSIOF1_SS1),
++ PINMUX_IPSR_GPSR(IP5_19_16, D3),
++
++ PINMUX_IPSR_GPSR(IP5_23_20, VI1_DATA1),
++ PINMUX_IPSR_GPSR(IP5_23_20, MSIOF1_SS2),
++ PINMUX_IPSR_GPSR(IP5_23_20, D4),
++ PINMUX_IPSR_GPSR(IP5_23_20, MMC_CMD),
++
++ PINMUX_IPSR_GPSR(IP5_27_24, VI1_DATA2),
++ PINMUX_IPSR_MSEL(IP5_27_24, CANFD0_TX_B, SEL_CANFD0_1),
++ PINMUX_IPSR_GPSR(IP5_27_24, D5),
++ PINMUX_IPSR_GPSR(IP5_27_24, MMC_D0),
++
++ PINMUX_IPSR_GPSR(IP5_31_28, VI1_DATA3),
++ PINMUX_IPSR_MSEL(IP5_31_28, CANFD0_RX_B, SEL_CANFD0_1),
++ PINMUX_IPSR_GPSR(IP5_31_28, D6),
++ PINMUX_IPSR_GPSR(IP5_31_28, MMC_D1),
++
++ /* IPSR6 */
++ PINMUX_IPSR_GPSR(IP6_3_0, VI1_DATA4),
++ PINMUX_IPSR_MSEL(IP6_3_0, CANFD_CLK_B, SEL_CANFD0_1),
++ PINMUX_IPSR_GPSR(IP6_3_0, D7),
++ PINMUX_IPSR_GPSR(IP6_3_0, MMC_D2),
++
++ PINMUX_IPSR_GPSR(IP6_7_4, VI1_DATA5),
++ PINMUX_IPSR_GPSR(IP6_7_4, SCK4),
++ PINMUX_IPSR_GPSR(IP6_7_4, D8),
++ PINMUX_IPSR_GPSR(IP6_7_4, MMC_D3),
++
++ PINMUX_IPSR_GPSR(IP6_11_8, VI1_DATA6),
++ PINMUX_IPSR_GPSR(IP6_11_8, RX4),
++ PINMUX_IPSR_GPSR(IP6_11_8, D9),
++ PINMUX_IPSR_GPSR(IP6_11_8, MMC_CLK),
++
++ PINMUX_IPSR_GPSR(IP6_15_12, VI1_DATA7),
++ PINMUX_IPSR_GPSR(IP6_15_12, TX4),
++ PINMUX_IPSR_GPSR(IP6_15_12, D10),
++ PINMUX_IPSR_GPSR(IP6_15_12, MMC_D4),
++
++ PINMUX_IPSR_GPSR(IP6_19_16, VI1_DATA8),
++ PINMUX_IPSR_GPSR(IP6_19_16, CTS4_N),
++ PINMUX_IPSR_GPSR(IP6_19_16, D11),
++ PINMUX_IPSR_GPSR(IP6_19_16, MMC_D5),
++
++ PINMUX_IPSR_GPSR(IP6_23_20, VI1_DATA9),
++ PINMUX_IPSR_GPSR(IP6_23_20, RTS4_N_TANS),
++ PINMUX_IPSR_GPSR(IP6_23_20, D12),
++ PINMUX_IPSR_GPSR(IP6_23_20, MMC_D6),
++ PINMUX_IPSR_GPSR(IP6_23_20, SCL3_B),
++
++ PINMUX_IPSR_GPSR(IP6_27_24, VI1_DATA10),
++ PINMUX_IPSR_GPSR(IP6_27_24, D13),
++ PINMUX_IPSR_GPSR(IP6_27_24, MMC_D7),
++ PINMUX_IPSR_GPSR(IP6_27_24, SDA3_B),
++
++ PINMUX_IPSR_GPSR(IP6_31_28, VI1_DATA11),
++ PINMUX_IPSR_GPSR(IP6_31_28, SCL4),
++ PINMUX_IPSR_GPSR(IP6_31_28, IRQ4),
++ PINMUX_IPSR_GPSR(IP6_31_28, D14),
++ PINMUX_IPSR_GPSR(IP6_31_28, MMC_WP),
++
++ /* IPSR7 */
++ PINMUX_IPSR_GPSR(IP7_3_0, VI1_FIELD),
++ PINMUX_IPSR_GPSR(IP7_3_0, SDA4),
++ PINMUX_IPSR_GPSR(IP7_3_0, IRQ5),
++ PINMUX_IPSR_GPSR(IP7_3_0, D15),
++ PINMUX_IPSR_GPSR(IP7_3_0, MMC_CD),
++
++ PINMUX_IPSR_GPSR(IP7_7_4, SCL0),
++ PINMUX_IPSR_GPSR(IP7_7_4, DU_DR0),
++ PINMUX_IPSR_GPSR(IP7_7_4, TPU0TO0),
++ PINMUX_IPSR_GPSR(IP7_7_4, CLKOUT),
++ PINMUX_IPSR_GPSR(IP7_7_4, MSIOF0_RXD),
++
++ PINMUX_IPSR_GPSR(IP7_11_8, SDA0),
++ PINMUX_IPSR_GPSR(IP7_11_8, DU_DR1),
++ PINMUX_IPSR_GPSR(IP7_11_8, TPU0TO1),
++ PINMUX_IPSR_GPSR(IP7_11_8, BS_N),
++ PINMUX_IPSR_GPSR(IP7_11_8, SCK0),
++ PINMUX_IPSR_GPSR(IP7_11_8, MSIOF0_TXD),
++
++ PINMUX_IPSR_GPSR(IP7_15_12, SCL1),
++ PINMUX_IPSR_GPSR(IP7_15_12, DU_DG0),
++ PINMUX_IPSR_GPSR(IP7_15_12, TPU0TO2),
++ PINMUX_IPSR_GPSR(IP7_15_12, RD_N),
++ PINMUX_IPSR_GPSR(IP7_15_12, CTS0_N),
++ PINMUX_IPSR_GPSR(IP7_15_12, MSIOF0_SCK),
++
++ PINMUX_IPSR_GPSR(IP7_19_16, SDA1),
++ PINMUX_IPSR_GPSR(IP7_19_16, DU_DG1),
++ PINMUX_IPSR_GPSR(IP7_19_16, TPU0TO3),
++ PINMUX_IPSR_GPSR(IP7_19_16, WE0_N),
++ PINMUX_IPSR_GPSR(IP7_19_16, RTS0_N_TANS),
++ PINMUX_IPSR_GPSR(IP7_19_16, MSIOF0_SYNC),
++
++ PINMUX_IPSR_GPSR(IP7_23_20, SCL2),
++ PINMUX_IPSR_GPSR(IP7_23_20, DU_DB0),
++ PINMUX_IPSR_MSEL(IP7_23_20, TCLK1_A, SEL_TMU_0),
++ PINMUX_IPSR_GPSR(IP7_23_20, WE1_N),
++ PINMUX_IPSR_GPSR(IP7_23_20, RX0),
++ PINMUX_IPSR_GPSR(IP7_23_20, MSIOF0_SS1),
++
++ PINMUX_IPSR_GPSR(IP7_27_24, SDA2),
++ PINMUX_IPSR_GPSR(IP7_27_24, DU_DB1),
++ PINMUX_IPSR_MSEL(IP7_27_24, TCLK2_A, SEL_TMU_0),
++ PINMUX_IPSR_GPSR(IP7_27_24, EX_WAIT0),
++ PINMUX_IPSR_GPSR(IP7_27_24, TX0),
++ PINMUX_IPSR_GPSR(IP7_27_24, MSIOF0_SS2),
++
++ PINMUX_IPSR_GPSR(IP7_31_28, AVB0_AVTP_CAPTURE),
++ PINMUX_IPSR_GPSR(IP7_31_28, FSCLKST2_N_B),
++
++ /* IPSR8 */
++ PINMUX_IPSR_MSEL(IP8_3_0, CANFD0_TX_A, SEL_CANFD0_0),
++ PINMUX_IPSR_GPSR(IP8_3_0, FXR_TXDA),
++ PINMUX_IPSR_MSEL(IP8_3_0, PWM0_B, SEL_PWM0_1),
++ PINMUX_IPSR_GPSR(IP8_3_0, DU_DISP),
++ PINMUX_IPSR_GPSR(IP8_3_0, FSCLKST2_N_C),
++
++ PINMUX_IPSR_MSEL(IP8_7_4, CANFD0_RX_A, SEL_CANFD0_0),
++ PINMUX_IPSR_GPSR(IP8_7_4, RXDA_EXTFXR),
++ PINMUX_IPSR_MSEL(IP8_7_4, PWM1_B, SEL_PWM1_1),
++ PINMUX_IPSR_GPSR(IP8_7_4, DU_CDE),
++
++ PINMUX_IPSR_GPSR(IP8_11_8, CANFD1_TX),
++ PINMUX_IPSR_GPSR(IP8_11_8, FXR_TXDB),
++ PINMUX_IPSR_MSEL(IP8_11_8, PWM2_B, SEL_PWM2_1),
++ PINMUX_IPSR_MSEL(IP8_11_8, TCLK1_B, SEL_TMU_1),
++ PINMUX_IPSR_MSEL(IP8_11_8, TX1_B, SEL_SCIF1_1),
++
++ PINMUX_IPSR_GPSR(IP8_15_12, CANFD1_RX),
++ PINMUX_IPSR_GPSR(IP8_15_12, RXDB_EXTFXR),
++ PINMUX_IPSR_MSEL(IP8_15_12, PWM3_B, SEL_PWM3_1),
++ PINMUX_IPSR_MSEL(IP8_15_12, TCLK2_B, SEL_TMU_1),
++ PINMUX_IPSR_MSEL(IP8_15_12, RX1_B, SEL_SCIF1_1),
++
++ PINMUX_IPSR_MSEL(IP8_19_16, CANFD_CLK_A, SEL_CANFD0_0),
++ PINMUX_IPSR_GPSR(IP8_19_16, CLK_EXTFXR),
++ PINMUX_IPSR_MSEL(IP8_19_16, PWM4_B, SEL_PWM4_1),
++ PINMUX_IPSR_MSEL(IP8_19_16, SPEEDIN_B, SEL_RSP_0),
++ PINMUX_IPSR_MSEL(IP8_19_16, SCIF_CLK_B, SEL_HSCIF0_1),
++
++ PINMUX_IPSR_GPSR(IP8_23_20, DIGRF_CLKIN),
++ PINMUX_IPSR_GPSR(IP8_23_20, DIGRF_CLKEN_IN),
++
++ PINMUX_IPSR_GPSR(IP8_27_24, DIGRF_CLKOUT),
++ PINMUX_IPSR_GPSR(IP8_27_24, DIGRF_CLKEN_OUT),
++};
++
++static const struct sh_pfc_pin pinmux_pins[] = {
++ PINMUX_GPIO_GP_ALL(),
++};
++
++/* - EtherAVB --------------------------------------------------------------- */
++static const unsigned int avb0_rx_ctrl_pins[] = {
++ /* AVB0_RX_CTL */
++ RCAR_GP_PIN(1, 1),
++};
++static const unsigned int avb0_rx_ctrl_mux[] = {
++ AVB0_RX_CTL_MARK,
++};
++static const unsigned int avb0_rxc_pins[] = {
++ /* AVB0_RXC */
++ RCAR_GP_PIN(1, 2),
++};
++static const unsigned int avb0_rxc_mux[] = {
++ AVB0_RXC_MARK,
++};
++static const unsigned int avb0_rd0_pins[] = {
++ /* AVB0_RD[0] */
++ RCAR_GP_PIN(1, 3),
++};
++static const unsigned int avb0_rd0_mux[] = {
++ AVB0_RD0_MARK,
++};
++static const unsigned int avb0_rd1_pins[] = {
++ /* AVB0_RD[1] */
++ RCAR_GP_PIN(1, 4),
++};
++static const unsigned int avb0_rd1_mux[] = {
++ AVB0_RD1_MARK,
++};
++static const unsigned int avb0_rd2_pins[] = {
++ /* AVB0_RD[2] */
++ RCAR_GP_PIN(1, 5),
++};
++static const unsigned int avb0_rd2_mux[] = {
++ AVB0_RD2_MARK,
++};
++static const unsigned int avb0_rd3_pins[] = {
++ /* AVB0_RD[3] */
++ RCAR_GP_PIN(1, 6),
++};
++static const unsigned int avb0_rd3_mux[] = {
++ AVB0_RD3_MARK,
++};
++static const unsigned int avb0_rd4_pins[] = {
++ /* AVB0_RD[3:0] */
++ RCAR_GP_PIN(1, 3), RCAR_GP_PIN(1, 4),
++ RCAR_GP_PIN(1, 5), RCAR_GP_PIN(1, 6),
++};
++static const unsigned int avb0_rd4_mux[] = {
++ AVB0_RD0_MARK, AVB0_RD1_MARK,
++ AVB0_RD2_MARK, AVB0_RD3_MARK,
++};
++static const unsigned int avb0_tx_ctrl_pins[] = {
++ /* AVB0_TX_CTL */
++ RCAR_GP_PIN(1, 7),
++};
++static const unsigned int avb0_tx_ctrl_mux[] = {
++ AVB0_TX_CTL_MARK,
++};
++static const unsigned int avb0_txc_pins[] = {
++ /* AVB0_TXC */
++ RCAR_GP_PIN(1, 8),
++};
++static const unsigned int avb0_txc_mux[] = {
++ AVB0_TXC_MARK,
++};
++static const unsigned int avb0_td0_pins[] = {
++ /* AVB0_TD[0] */
++ RCAR_GP_PIN(1, 9),
++};
++static const unsigned int avb0_td0_mux[] = {
++ AVB0_TD0_MARK,
++};
++static const unsigned int avb0_td1_pins[] = {
++ /* AVB0_TD[1] */
++ RCAR_GP_PIN(1, 10),
++};
++static const unsigned int avb0_td1_mux[] = {
++ AVB0_TD1_MARK,
++};
++static const unsigned int avb0_td2_pins[] = {
++ /* AVB0_TD[2] */
++ RCAR_GP_PIN(1, 11),
++};
++static const unsigned int avb0_td2_mux[] = {
++ AVB0_TD2_MARK,
++};
++static const unsigned int avb0_td3_pins[] = {
++ /* AVB0_TD[3] */
++ RCAR_GP_PIN(1, 12),
++};
++static const unsigned int avb0_td3_mux[] = {
++ AVB0_TD3_MARK,
++};
++static const unsigned int avb0_td4_pins[] = {
++ /* AVB0_TD[3:0] */
++ RCAR_GP_PIN(1, 9), RCAR_GP_PIN(1, 10),
++ RCAR_GP_PIN(1, 11), RCAR_GP_PIN(1, 12),
++};
++static const unsigned int avb0_td4_mux[] = {
++ AVB0_TD0_MARK, AVB0_TD1_MARK,
++ AVB0_TD2_MARK, AVB0_TD3_MARK,
++};
++static const unsigned int avb0_txcrefclk_pins[] = {
++ /* AVB0_TXCREFCLK */
++ RCAR_GP_PIN(1, 13),
++};
++static const unsigned int avb0_txcrefclk_mux[] = {
++ AVB0_TXCREFCLK_MARK,
++};
++static const unsigned int avb0_mdio_pins[] = {
++ /* AVB0_MDIO */
++ RCAR_GP_PIN(1, 14),
++};
++static const unsigned int avb0_mdio_mux[] = {
++ AVB0_MDIO_MARK,
++};
++static const unsigned int avb0_mdc_pins[] = {
++ /* AVB0_MDC */
++ RCAR_GP_PIN(1, 15),
++};
++static const unsigned int avb0_mdc_mux[] = {
++ AVB0_MDC_MARK,
++};
++static const unsigned int avb0_magic_pins[] = {
++ /* AVB0_MAGIC */
++ RCAR_GP_PIN(1, 16),
++};
++static const unsigned int avb0_magic_mux[] = {
++ AVB0_MAGIC_MARK,
++};
++static const unsigned int avb0_phy_int_pins[] = {
++ /* AVB0_PHY_INT */
++ RCAR_GP_PIN(1, 17),
++};
++static const unsigned int avb0_phy_int_mux[] = {
++ AVB0_PHY_INT_MARK,
++};
++static const unsigned int avb0_link_pins[] = {
++ /* AVB0_LINK */
++ RCAR_GP_PIN(1, 18),
++};
++static const unsigned int avb0_link_mux[] = {
++ AVB0_LINK_MARK,
++};
++static const unsigned int avb0_avtp_match_pins[] = {
++ /* AVB0_AVTP_MATCH */
++ RCAR_GP_PIN(1, 19),
++};
++static const unsigned int avb0_avtp_match_mux[] = {
++ AVB0_AVTP_MATCH_MARK,
++};
++static const unsigned int avb0_avtp_pps_pins[] = {
++ /* AVB0_AVTP_PPS */
++ RCAR_GP_PIN(2, 6),
++};
++static const unsigned int avb0_avtp_pps_mux[] = {
++ AVB0_AVTP_PPS_MARK,
++};
++static const unsigned int avb0_avtp_capture_pins[] = {
++ /* AVB0_AVTP_CAPTURE */
++ RCAR_GP_PIN(1, 20),
++};
++static const unsigned int avb0_avtp_capture_mux[] = {
++ AVB0_AVTP_CAPTURE_MARK,
++};
++
++/* - CANFD0 ----------------------------------------------------------------- */
++static const unsigned int canfd0_data_a_pins[] = {
++ /* TX, RX */
++ RCAR_GP_PIN(1, 21), RCAR_GP_PIN(1, 22),
++};
++static const unsigned int canfd0_data_a_mux[] = {
++ CANFD0_TX_A_MARK, CANFD0_RX_A_MARK,
++};
++static const unsigned int canfd_clk_a_pins[] = {
++ /* CLK */
++ RCAR_GP_PIN(1, 25),
++};
++static const unsigned int canfd_clk_a_mux[] = {
++ CANFD_CLK_A_MARK,
++};
++static const unsigned int canfd0_data_b_pins[] = {
++ /* TX, RX */
++ RCAR_GP_PIN(3, 6), RCAR_GP_PIN(3, 7),
++};
++static const unsigned int canfd0_data_b_mux[] = {
++ CANFD0_TX_B_MARK, CANFD0_RX_B_MARK,
++};
++static const unsigned int canfd_clk_b_pins[] = {
++ /* CLK */
++ RCAR_GP_PIN(3, 8),
++};
++static const unsigned int canfd_clk_b_mux[] = {
++ CANFD_CLK_B_MARK,
++};
++
++/* - CANFD1 ----------------------------------------------------------------- */
++static const unsigned int canfd1_data_pins[] = {
++ /* TX, RX */
++ RCAR_GP_PIN(1, 23), RCAR_GP_PIN(1, 24),
++};
++static const unsigned int canfd1_data_mux[] = {
++ CANFD1_TX_MARK, CANFD1_RX_MARK,
++};
++
++/* - DU --------------------------------------------------------------------- */
++static const unsigned int du_rgb666_pins[] = {
++ /* R[7:0] */
++ RCAR_GP_PIN(0, 5), RCAR_GP_PIN(0, 4),
++ RCAR_GP_PIN(0, 3), RCAR_GP_PIN(0, 2),
++ RCAR_GP_PIN(0, 1), RCAR_GP_PIN(0, 0),
++ /* G[7:0] */
++ RCAR_GP_PIN(0, 11), RCAR_GP_PIN(0, 10),
++ RCAR_GP_PIN(0, 9), RCAR_GP_PIN(0, 8),
++ RCAR_GP_PIN(0, 7), RCAR_GP_PIN(0, 6),
++ /* B[7:0] */
++ RCAR_GP_PIN(0, 17), RCAR_GP_PIN(0, 16),
++ RCAR_GP_PIN(0, 15), RCAR_GP_PIN(0, 14),
++ RCAR_GP_PIN(0, 13), RCAR_GP_PIN(0, 12),
++};
++static const unsigned int du_rgb666_mux[] = {
++ DU_DR7_MARK, DU_DR6_MARK,
++ DU_DR5_MARK, DU_DR4_MARK,
++ DU_DR3_MARK, DU_DR2_MARK,
++ DU_DG7_MARK, DU_DG6_MARK,
++ DU_DG5_MARK, DU_DG4_MARK,
++ DU_DG3_MARK, DU_DG2_MARK,
++ DU_DB7_MARK, DU_DB6_MARK,
++ DU_DB5_MARK, DU_DB4_MARK,
++ DU_DB3_MARK, DU_DB2_MARK,
++};
++static const unsigned int du_clk_out_0_pins[] = {
++ /* CLKOUT0 */
++ RCAR_GP_PIN(0, 18),
++};
++static const unsigned int du_clk_out_0_mux[] = {
++ DU_DOTCLKOUT_MARK,
++};
++static const unsigned int du_clk_out_1_pins[] = {
++ /* CLKOUT1 */
++ RCAR_GP_PIN(0, 18), /* @@ */
++};
++static const unsigned int du_clk_out_1_mux[] = {
++ DU_DOTCLKOUT_MARK,
++};
++static const unsigned int du_sync_pins[] = {
++ /* EXVSYNC/VSYNC, EXHSYNC/HSYNC */
++ RCAR_GP_PIN(0, 20), RCAR_GP_PIN(0, 19),
++};
++static const unsigned int du_sync_mux[] = {
++ DU_EXVSYNC_DU_VSYNC_MARK, DU_EXHSYNC_DU_HSYNC_MARK,
++};
++static const unsigned int du_oddf_pins[] = {
++ /* EXDISP/EXODDF/EXCDE */
++ RCAR_GP_PIN(0, 21),
++};
++static const unsigned int du_oddf_mux[] = {
++ DU_EXODDF_DU_ODDF_DISP_CDE_MARK,
++};
++static const unsigned int du_cde_pins[] = {
++ /* CDE */
++ RCAR_GP_PIN(1, 22),
++};
++static const unsigned int du_cde_mux[] = {
++ DU_CDE_MARK,
++};
++static const unsigned int du_disp_pins[] = {
++ /* DISP */
++ RCAR_GP_PIN(1, 21),
++};
++static const unsigned int du_disp_mux[] = {
++ DU_DISP_MARK,
++};
++
++/* - HSCIF0 ----------------------------------------------------------------- */
++static const unsigned int hscif0_data_pins[] = {
++ /* HRX0, HTX0 */
++ RCAR_GP_PIN(0, 19), RCAR_GP_PIN(0, 3),
++};
++static const unsigned int hscif0_data_mux[] = {
++ HRX0_MARK, HTX0_MARK,
++};
++static const unsigned int hscif0_clk_pins[] = {
++ /* HSCK0 */
++ RCAR_GP_PIN(0, 0),
++};
++static const unsigned int hscif0_clk_mux[] = {
++ HSCK0_MARK,
++};
++static const unsigned int hscif0_ctrl_pins[] = {
++ /* HRTS0#, HCTS0# */
++ RCAR_GP_PIN(0, 1), RCAR_GP_PIN(0, 2),
++};
++static const unsigned int hscif0_ctrl_mux[] = {
++ HRTS0_N_MARK, HCTS0_N_MARK,
++};
++
++/* - HSCIF1 ----------------------------------------------------------------- */
++static const unsigned int hscif1_data_pins[] = {
++ /* HRX1, HTX1 */
++ RCAR_GP_PIN(2, 11), RCAR_GP_PIN(2, 10),
++};
++static const unsigned int hscif1_data_mux[] = {
++ HRX1_MARK, HTX1_MARK,
++};
++static const unsigned int hscif1_clk_pins[] = {
++ /* HSCK1 */
++ RCAR_GP_PIN(2, 7),
++};
++static const unsigned int hscif1_clk_mux[] = {
++ HSCK1_MARK,
++};
++static const unsigned int hscif1_ctrl_pins[] = {
++ /* HRTS1#, HCTS1# */
++ RCAR_GP_PIN(2, 8), RCAR_GP_PIN(2, 9),
++};
++static const unsigned int hscif1_ctrl_mux[] = {
++ HRTS1_N_MARK, HCTS1_N_MARK,
++};
++
++/* - HSCIF2 ----------------------------------------------------------------- */
++static const unsigned int hscif2_data_pins[] = {
++ /* HRX2, HTX2 */
++ RCAR_GP_PIN(2, 16), RCAR_GP_PIN(2, 15),
++};
++static const unsigned int hscif2_data_mux[] = {
++ HRX2_MARK, HTX2_MARK,
++};
++static const unsigned int hscif2_clk_pins[] = {
++ /* HSCK2 */
++ RCAR_GP_PIN(2, 12),
++};
++static const unsigned int hscif2_clk_mux[] = {
++ HSCK2_MARK,
++};
++static const unsigned int hscif2_ctrl_pins[] = {
++ /* HRTS2#, HCTS2# */
++ RCAR_GP_PIN(2, 14), RCAR_GP_PIN(2, 13),
++};
++static const unsigned int hscif2_ctrl_mux[] = {
++ HRTS2_N_MARK, HCTS2_N_MARK,
++};
++
++/* - HSCIF3 ----------------------------------------------------------------- */
++static const unsigned int hscif3_data_pins[] = {
++ /* HRX3, HTX3 */
++ RCAR_GP_PIN(2, 4), RCAR_GP_PIN(2, 3),
++};
++static const unsigned int hscif3_data_mux[] = {
++ HRX3_MARK, HTX3_MARK,
++};
++static const unsigned int hscif3_clk_pins[] = {
++ /* HSCK3 */
++ RCAR_GP_PIN(2, 0),
++};
++static const unsigned int hscif3_clk_mux[] = {
++ HSCK3_MARK,
++};
++static const unsigned int hscif3_ctrl_pins[] = {
++ /* HRTS3#, HCTS3# */
++ RCAR_GP_PIN(2, 2), RCAR_GP_PIN(2, 1),
++};
++static const unsigned int hscif3_ctrl_mux[] = {
++ HRTS3_N_MARK, HCTS3_N_MARK,
++};
++
++/* - SCIF Clock ------------------------------------------------------------- */
++static const unsigned int scif_clk_a_pins[] = {
++ /* SCIF_CLK */
++ RCAR_GP_PIN(0, 18),
++};
++static const unsigned int scif_clk_a_mux[] = {
++ SCIF_CLK_A_MARK,
++};
++static const unsigned int scif_clk_b_pins[] = {
++ /* SCIF_CLK */
++ RCAR_GP_PIN(1, 25),
++};
++static const unsigned int scif_clk_b_mux[] = {
++ SCIF_CLK_B_MARK,
++};
++
++/* - I2C -------------------------------------------------------------------- */
++static const unsigned int i2c0_pins[] = {
++ /* SDA0, SCL0 */
++ RCAR_GP_PIN(4, 1), RCAR_GP_PIN(4, 0),
++};
++static const unsigned int i2c0_mux[] = {
++ SDA0_MARK, SCL0_MARK,
++};
++static const unsigned int i2c1_pins[] = {
++ /* SDA1, SCL1 */
++ RCAR_GP_PIN(4, 3), RCAR_GP_PIN(4, 2),
++};
++static const unsigned int i2c1_mux[] = {
++ SDA1_MARK, SCL1_MARK,
++};
++static const unsigned int i2c2_pins[] = {
++ /* SDA2, SCL2 */
++ RCAR_GP_PIN(4, 5), RCAR_GP_PIN(4, 4),
++};
++static const unsigned int i2c2_mux[] = {
++ SDA2_MARK, SCL2_MARK,
++};
++static const unsigned int i2c3_pins[] = {
++ /* SDA3_A, SCL3_A */
++ RCAR_GP_PIN(2, 6), RCAR_GP_PIN(2, 5),
++};
++static const unsigned int i2c3_mux[] = {
++ SDA3_A_MARK, SCL3_A_MARK,
++};
++static const unsigned int i2c4_pins[] = {
++ /* SDA4, SCL4 */
++ RCAR_GP_PIN(3, 16), RCAR_GP_PIN(3, 15),
++};
++static const unsigned int i2c4_mux[] = {
++ SDA4_MARK, SCL4_MARK,
++};
++
++/* - INTC-EX ---------------------------------------------------------------- */
++static const unsigned int intc_ex_irq0_pins[] = {
++ /* IRQ0 */
++ RCAR_GP_PIN(1, 0),
++};
++static const unsigned int intc_ex_irq0_mux[] = {
++ IRQ0_MARK,
++};
++static const unsigned int intc_ex_irq1_pins[] = {
++ /* IRQ1 */
++ RCAR_GP_PIN(0, 11),
++};
++static const unsigned int intc_ex_irq1_mux[] = {
++ IRQ1_MARK,
++};
++static const unsigned int intc_ex_irq2_pins[] = {
++ /* IRQ2 */
++ RCAR_GP_PIN(0, 12),
++};
++static const unsigned int intc_ex_irq2_mux[] = {
++ IRQ2_MARK,
++};
++static const unsigned int intc_ex_irq3_pins[] = {
++ /* IRQ3 */
++ RCAR_GP_PIN(0, 19),
++};
++static const unsigned int intc_ex_irq3_mux[] = {
++ IRQ3_MARK,
++};
++static const unsigned int intc_ex_irq4_pins[] = {
++ /* IRQ4 */
++ RCAR_GP_PIN(3, 15),
++};
++static const unsigned int intc_ex_irq4_mux[] = {
++ IRQ4_MARK,
++};
++static const unsigned int intc_ex_irq5_pins[] = {
++ /* IRQ5 */
++ RCAR_GP_PIN(3, 16),
++};
++static const unsigned int intc_ex_irq5_mux[] = {
++ IRQ5_MARK,
++};
++
++/* - MSIOF0 ----------------------------------------------------------------- */
++static const unsigned int msiof0_clk_pins[] = {
++ /* SCK */
++ RCAR_GP_PIN(4, 2),
++};
++static const unsigned int msiof0_clk_mux[] = {
++ MSIOF0_SCK_MARK,
++};
++static const unsigned int msiof0_sync_pins[] = {
++ /* SYNC */
++ RCAR_GP_PIN(4, 3),
++};
++static const unsigned int msiof0_sync_mux[] = {
++ MSIOF0_SYNC_MARK,
++};
++static const unsigned int msiof0_ss1_pins[] = {
++ /* SS1 */
++ RCAR_GP_PIN(4, 4),
++};
++static const unsigned int msiof0_ss1_mux[] = {
++ MSIOF0_SS1_MARK,
++};
++static const unsigned int msiof0_ss2_pins[] = {
++ /* SS2 */
++ RCAR_GP_PIN(4, 5),
++};
++static const unsigned int msiof0_ss2_mux[] = {
++ MSIOF0_SS2_MARK,
++};
++static const unsigned int msiof0_txd_pins[] = {
++ /* TXD */
++ RCAR_GP_PIN(4, 1),
++};
++static const unsigned int msiof0_txd_mux[] = {
++ MSIOF0_TXD_MARK,
++};
++static const unsigned int msiof0_rxd_pins[] = {
++ /* RXD */
++ RCAR_GP_PIN(4, 0),
++};
++static const unsigned int msiof0_rxd_mux[] = {
++ MSIOF0_RXD_MARK,
++};
++
++/* - MSIOF1 ----------------------------------------------------------------- */
++static const unsigned int msiof1_clk_pins[] = {
++ /* SCK */
++ RCAR_GP_PIN(3, 2),
++};
++static const unsigned int msiof1_clk_mux[] = {
++ MSIOF1_SCK_MARK,
++};
++static const unsigned int msiof1_sync_pins[] = {
++ /* SYNC */
++ RCAR_GP_PIN(3, 3),
++};
++static const unsigned int msiof1_sync_mux[] = {
++ MSIOF1_SYNC_MARK,
++};
++static const unsigned int msiof1_ss1_pins[] = {
++ /* SS1 */
++ RCAR_GP_PIN(3, 4),
++};
++static const unsigned int msiof1_ss1_mux[] = {
++ MSIOF1_SS1_MARK,
++};
++static const unsigned int msiof1_ss2_pins[] = {
++ /* SS2 */
++ RCAR_GP_PIN(3, 5),
++};
++static const unsigned int msiof1_ss2_mux[] = {
++ MSIOF1_SS2_MARK,
++};
++static const unsigned int msiof1_txd_pins[] = {
++ /* TXD */
++ RCAR_GP_PIN(3, 1),
++};
++static const unsigned int msiof1_txd_mux[] = {
++ MSIOF1_TXD_MARK,
++};
++static const unsigned int msiof1_rxd_pins[] = {
++ /* RXD */
++ RCAR_GP_PIN(3, 0),
++};
++static const unsigned int msiof1_rxd_mux[] = {
++ MSIOF1_RXD_MARK,
++};
++
++/* - MSIOF2 ----------------------------------------------------------------- */
++static const unsigned int msiof2_clk_pins[] = {
++ /* SCK */
++ RCAR_GP_PIN(2, 0),
++};
++static const unsigned int msiof2_clk_mux[] = {
++ MSIOF2_SCK_MARK,
++};
++static const unsigned int msiof2_sync_pins[] = {
++ /* SYNC */
++ RCAR_GP_PIN(2, 3),
++};
++static const unsigned int msiof2_sync_mux[] = {
++ MSIOF2_SYNC_MARK,
++};
++static const unsigned int msiof2_ss1_pins[] = {
++ /* SS1 */
++ RCAR_GP_PIN(2, 4),
++};
++static const unsigned int msiof2_ss1_mux[] = {
++ MSIOF2_SS1_MARK,
++};
++static const unsigned int msiof2_ss2_pins[] = {
++ /* SS2 */
++ RCAR_GP_PIN(2, 5),
++};
++static const unsigned int msiof2_ss2_mux[] = {
++ MSIOF2_SS2_MARK,
++};
++static const unsigned int msiof2_txd_pins[] = {
++ /* TXD */
++ RCAR_GP_PIN(2, 2),
++};
++static const unsigned int msiof2_txd_mux[] = {
++ MSIOF2_TXD_MARK,
++};
++static const unsigned int msiof2_rxd_pins[] = {
++ /* RXD */
++ RCAR_GP_PIN(2, 1),
++};
++static const unsigned int msiof2_rxd_mux[] = {
++ MSIOF2_RXD_MARK,
++};
++
++/* - MSIOF3 ----------------------------------------------------------------- */
++static const unsigned int msiof3_clk_pins[] = {
++ /* SCK */
++ RCAR_GP_PIN(0, 20),
++};
++static const unsigned int msiof3_clk_mux[] = {
++ MSIOF3_SCK_MARK,
++};
++static const unsigned int msiof3_sync_pins[] = {
++ /* SYNC */
++ RCAR_GP_PIN(0, 21),
++};
++static const unsigned int msiof3_sync_mux[] = {
++ MSIOF3_SYNC_MARK,
++};
++static const unsigned int msiof3_ss1_pins[] = {
++ /* SS1 */
++ RCAR_GP_PIN(0, 6),
++};
++static const unsigned int msiof3_ss1_mux[] = {
++ MSIOF3_SS1_MARK,
++};
++static const unsigned int msiof3_ss2_pins[] = {
++ /* SS2 */
++ RCAR_GP_PIN(0, 7),
++};
++static const unsigned int msiof3_ss2_mux[] = {
++ MSIOF3_SS2_MARK,
++};
++static const unsigned int msiof3_txd_pins[] = {
++ /* TXD */
++ RCAR_GP_PIN(0, 5),
++};
++static const unsigned int msiof3_txd_mux[] = {
++ MSIOF3_TXD_MARK,
++};
++static const unsigned int msiof3_rxd_pins[] = {
++ /* RXD */
++ RCAR_GP_PIN(0, 4),
++};
++static const unsigned int msiof3_rxd_mux[] = {
++ MSIOF3_RXD_MARK,
++};
++
++/* - TPU ------------------------------------------------------------------- */
++static const unsigned int tpu_to0_pins[] = {
++ /* TPU0TO0 */
++ RCAR_GP_PIN(4, 0),
++};
++static const unsigned int tpu_to0_mux[] = {
++ TPU0TO0_MARK,
++};
++static const unsigned int tpu_to1_pins[] = {
++ /* TPU0TO1 */
++ RCAR_GP_PIN(4, 1),
++};
++static const unsigned int tpu_to1_mux[] = {
++ TPU0TO1_MARK,
++};
++static const unsigned int tpu_to2_pins[] = {
++ /* TPU0TO2 */
++ RCAR_GP_PIN(4, 2),
++};
++static const unsigned int tpu_to2_mux[] = {
++ TPU0TO2_MARK,
++};
++static const unsigned int tpu_to3_pins[] = {
++ /* TPU0TO3 */
++ RCAR_GP_PIN(4, 3),
++};
++static const unsigned int tpu_to3_mux[] = {
++ TPU0TO3_MARK,
++};
++
++/* - PWM0 ------------------------------------------------------------------- */
++static const unsigned int pwm0_a_pins[] = {
++ /* PWM0 */
++ RCAR_GP_PIN(2, 12),
++};
++static const unsigned int pwm0_a_mux[] = {
++ PWM0_A_MARK,
++};
++static const unsigned int pwm0_b_pins[] = {
++ /* PWM0 */
++ RCAR_GP_PIN(1, 21),
++};
++static const unsigned int pwm0_b_mux[] = {
++ PWM0_B_MARK,
++};
++
++/* - PWM1 ------------------------------------------------------------------- */
++static const unsigned int pwm1_a_pins[] = {
++ /* PWM1 */
++ RCAR_GP_PIN(2, 13),
++};
++static const unsigned int pwm1_a_mux[] = {
++ PWM1_A_MARK,
++};
++static const unsigned int pwm1_b_pins[] = {
++ /* PWM1 */
++ RCAR_GP_PIN(1, 22),
++};
++static const unsigned int pwm1_b_mux[] = {
++ PWM1_B_MARK,
++};
++
++/* - PWM2 ------------------------------------------------------------------- */
++static const unsigned int pwm2_a_pins[] = {
++ /* PWM2 */
++ RCAR_GP_PIN(2, 14),
++};
++static const unsigned int pwm2_a_mux[] = {
++ PWM2_A_MARK,
++};
++static const unsigned int pwm2_b_pins[] = {
++ /* PWM2 */
++ RCAR_GP_PIN(1, 23),
++};
++static const unsigned int pwm2_b_mux[] = {
++ PWM2_B_MARK,
++};
++
++/* - PWM3 ------------------------------------------------------------------- */
++static const unsigned int pwm3_a_pins[] = {
++ /* PWM3 */
++ RCAR_GP_PIN(2, 15),
++};
++static const unsigned int pwm3_a_mux[] = {
++ PWM3_A_MARK,
++};
++static const unsigned int pwm3_b_pins[] = {
++ /* PWM3 */
++ RCAR_GP_PIN(1, 24),
++};
++static const unsigned int pwm3_b_mux[] = {
++ PWM3_B_MARK,
++};
++
++/* - PWM4 ------------------------------------------------------------------- */
++static const unsigned int pwm4_a_pins[] = {
++ /* PWM4 */
++ RCAR_GP_PIN(2, 16),
++};
++static const unsigned int pwm4_a_mux[] = {
++ PWM4_A_MARK,
++};
++static const unsigned int pwm4_b_pins[] = {
++ /* PWM4 */
++ RCAR_GP_PIN(1, 25),
++};
++static const unsigned int pwm4_b_mux[] = {
++ PWM4_B_MARK,
++};
++
++/* - SCIF0 ------------------------------------------------------------------ */
++static const unsigned int scif0_data_pins[] = {
++ /* RX, TX */
++ RCAR_GP_PIN(4, 4), RCAR_GP_PIN(4, 5),
++};
++static const unsigned int scif0_data_mux[] = {
++ RX0_MARK, TX0_MARK,
++};
++static const unsigned int scif0_clk_pins[] = {
++ /* SCK */
++ RCAR_GP_PIN(4, 1),
++};
++static const unsigned int scif0_clk_mux[] = {
++ SCK0_MARK,
++};
++
++static const unsigned int scif0_ctrl_pins[] = {
++ /* RTS, CTS */
++ RCAR_GP_PIN(4, 3), RCAR_GP_PIN(4, 2),
++};
++static const unsigned int scif0_ctrl_mux[] = {
++ RTS0_N_TANS_MARK, CTS0_N_MARK,
++};
++
++/* - SCIF1 ------------------------------------------------------------------ */
++static const unsigned int scif1_data_a_pins[] = {
++ /* RX, TX */
++ RCAR_GP_PIN(2, 8), RCAR_GP_PIN(2, 9),
++};
++static const unsigned int scif1_data_a_mux[] = {
++ RX1_A_MARK, TX1_A_MARK,
++};
++static const unsigned int scif1_clk_pins[] = {
++ /* SCK */
++ RCAR_GP_PIN(2, 5),
++};
++static const unsigned int scif1_clk_mux[] = {
++ SCK1_MARK,
++};
++static const unsigned int scif1_ctrl_pins[] = {
++ /* RTS, CTS */
++ RCAR_GP_PIN(2, 11), RCAR_GP_PIN(2, 10),
++};
++static const unsigned int scif1_ctrl_mux[] = {
++ RTS1_N_TANS_MARK, CTS1_N_MARK,
++};
++static const unsigned int scif1_data_b_pins[] = {
++ /* RX, TX */
++ RCAR_GP_PIN(1, 24), RCAR_GP_PIN(1, 23),
++};
++static const unsigned int scif1_data_b_mux[] = {
++ RX1_B_MARK, TX1_B_MARK,
++};
++
++/* - SCIF3 ------------------------------------------------------------------ */
++static const unsigned int scif3_data_pins[] = {
++ /* RX, TX */
++ RCAR_GP_PIN(2, 1), RCAR_GP_PIN(2, 2),
++};
++static const unsigned int scif3_data_mux[] = {
++ RX3_MARK, TX3_MARK,
++};
++static const unsigned int scif3_clk_pins[] = {
++ /* SCK */
++ RCAR_GP_PIN(2, 0),
++};
++static const unsigned int scif3_clk_mux[] = {
++ SCK3_MARK,
++};
++static const unsigned int scif3_ctrl_pins[] = {
++ /* RTS, CTS */
++ RCAR_GP_PIN(2, 4), RCAR_GP_PIN(2, 3),
++};
++static const unsigned int scif3_ctrl_mux[] = {
++ RTS3_N_TANS_MARK, CTS3_N_MARK,
++};
++
++/* - SCIF4 ------------------------------------------------------------------ */
++static const unsigned int scif4_data_pins[] = {
++ /* RX, TX */
++ RCAR_GP_PIN(3, 10), RCAR_GP_PIN(3, 11),
++};
++static const unsigned int scif4_data_mux[] = {
++ RX4_MARK, TX4_MARK,
++};
++static const unsigned int scif4_clk_pins[] = {
++ /* SCK */
++ RCAR_GP_PIN(3, 9),
++};
++static const unsigned int scif4_clk_mux[] = {
++ SCK4_MARK,
++};
++static const unsigned int scif4_ctrl_pins[] = {
++ /* RTS, CTS */
++ RCAR_GP_PIN(3, 13), RCAR_GP_PIN(3, 12),
++};
++static const unsigned int scif4_ctrl_mux[] = {
++ RTS4_N_TANS_MARK, CTS4_N_MARK,
++};
++
++/* - MMC -------------------------------------------------------------------- */
++static const unsigned int mmc_data1_pins[] = {
++ /* D0 */
++ RCAR_GP_PIN(3, 6),
++};
++static const unsigned int mmc_data1_mux[] = {
++ MMC_D0_MARK,
++};
++static const unsigned int mmc_data4_pins[] = {
++ /* D[0:3] */
++ RCAR_GP_PIN(3, 6), RCAR_GP_PIN(3, 7),
++ RCAR_GP_PIN(3, 8), RCAR_GP_PIN(3, 9),
++};
++static const unsigned int mmc_data4_mux[] = {
++ MMC_D0_MARK, MMC_D1_MARK,
++ MMC_D2_MARK, MMC_D3_MARK,
++};
++static const unsigned int mmc_data8_pins[] = {
++ /* D[0:7] */
++ RCAR_GP_PIN(3, 6), RCAR_GP_PIN(3, 7),
++ RCAR_GP_PIN(3, 8), RCAR_GP_PIN(3, 9),
++ RCAR_GP_PIN(3, 11), RCAR_GP_PIN(3, 12),
++ RCAR_GP_PIN(3, 13), RCAR_GP_PIN(3, 14),
++};
++static const unsigned int mmc_data8_mux[] = {
++ MMC_D0_MARK, MMC_D1_MARK,
++ MMC_D2_MARK, MMC_D3_MARK,
++ MMC_D4_MARK, MMC_D5_MARK,
++ MMC_D6_MARK, MMC_D7_MARK,
++};
++static const unsigned int mmc_ctrl_pins[] = {
++ /* CLK, CMD */
++ RCAR_GP_PIN(3, 10), RCAR_GP_PIN(3, 5),
++};
++static const unsigned int mmc_ctrl_mux[] = {
++ MMC_CLK_MARK, MMC_CMD_MARK,
++};
++static const unsigned int mmc_cd_pins[] = {
++ /* CD */
++ RCAR_GP_PIN(3, 16),
++};
++static const unsigned int mmc_cd_mux[] = {
++ MMC_CD_MARK,
++};
++static const unsigned int mmc_wp_pins[] = {
++ /* WP */
++ RCAR_GP_PIN(3, 15),
++};
++static const unsigned int mmc_wp_mux[] = {
++ MMC_WP_MARK,
++};
++
++/* - TMU -------------------------------------------------------------------- */
++static const unsigned int tmu_tclk1_a_pins[] = {
++ /* TCLK1 */
++ RCAR_GP_PIN(4, 4),
++};
++static const unsigned int tmu_tclk1_a_mux[] = {
++ TCLK1_A_MARK,
++};
++static const unsigned int tmu_tclk1_b_pins[] = {
++ /* TCLK1 */
++ RCAR_GP_PIN(1, 23),
++};
++static const unsigned int tmu_tclk1_b_mux[] = {
++ TCLK1_B_MARK,
++};
++static const unsigned int tmu_tclk2_a_pins[] = {
++ /* TCLK2 */
++ RCAR_GP_PIN(4, 5),
++};
++static const unsigned int tmu_tclk2_a_mux[] = {
++ TCLK2_A_MARK,
++};
++static const unsigned int tmu_tclk2_b_pins[] = {
++ /* TCLK2 */
++ RCAR_GP_PIN(1, 24),
++};
++static const unsigned int tmu_tclk2_b_mux[] = {
++ TCLK2_B_MARK,
++};
++
++/* - VIN0 ------------------------------------------------------------------- */
++static const unsigned int vin0_data8_pins[] = {
++ RCAR_GP_PIN(2, 4), RCAR_GP_PIN(2, 5),
++ RCAR_GP_PIN(2, 6), RCAR_GP_PIN(2, 7),
++ RCAR_GP_PIN(2, 8), RCAR_GP_PIN(2, 9),
++ RCAR_GP_PIN(2, 10), RCAR_GP_PIN(2, 11),
++};
++static const unsigned int vin0_data8_mux[] = {
++ VI0_DATA0_MARK, VI0_DATA1_MARK,
++ VI0_DATA2_MARK, VI0_DATA3_MARK,
++ VI0_DATA4_MARK, VI0_DATA5_MARK,
++ VI0_DATA6_MARK, VI0_DATA7_MARK,
++};
++static const unsigned int vin0_data10_pins[] = {
++ RCAR_GP_PIN(2, 4), RCAR_GP_PIN(2, 5),
++ RCAR_GP_PIN(2, 6), RCAR_GP_PIN(2, 7),
++ RCAR_GP_PIN(2, 8), RCAR_GP_PIN(2, 9),
++ RCAR_GP_PIN(2, 10), RCAR_GP_PIN(2, 11),
++ RCAR_GP_PIN(2, 12), RCAR_GP_PIN(2, 13),
++};
++static const unsigned int vin0_data10_mux[] = {
++ VI0_DATA0_MARK, VI0_DATA1_MARK,
++ VI0_DATA2_MARK, VI0_DATA3_MARK,
++ VI0_DATA4_MARK, VI0_DATA5_MARK,
++ VI0_DATA6_MARK, VI0_DATA7_MARK,
++ VI0_DATA8_MARK, VI0_DATA9_MARK,
++};
++static const unsigned int vin0_data12_pins[] = {
++ RCAR_GP_PIN(2, 4), RCAR_GP_PIN(2, 5),
++ RCAR_GP_PIN(2, 6), RCAR_GP_PIN(2, 7),
++ RCAR_GP_PIN(2, 8), RCAR_GP_PIN(2, 9),
++ RCAR_GP_PIN(2, 10), RCAR_GP_PIN(2, 11),
++ RCAR_GP_PIN(2, 12), RCAR_GP_PIN(2, 13),
++ RCAR_GP_PIN(2, 14), RCAR_GP_PIN(2, 15),
++};
++static const unsigned int vin0_data12_mux[] = {
++ VI0_DATA0_MARK, VI0_DATA1_MARK,
++ VI0_DATA2_MARK, VI0_DATA3_MARK,
++ VI0_DATA4_MARK, VI0_DATA5_MARK,
++ VI0_DATA6_MARK, VI0_DATA7_MARK,
++ VI0_DATA8_MARK, VI0_DATA9_MARK,
++ VI0_DATA10_MARK, VI0_DATA11_MARK,
++};
++static const unsigned int vin0_sync_pins[] = {
++ /* VSYNC_N, HSYNC_N */
++ RCAR_GP_PIN(2, 3), RCAR_GP_PIN(2, 2),
++};
++static const unsigned int vin0_sync_mux[] = {
++ VI0_HSYNC_N_MARK, VI0_VSYNC_N_MARK,
++};
++static const unsigned int vin0_field_pins[] = {
++ /* FIELD */
++ RCAR_GP_PIN(2, 16),
++};
++static const unsigned int vin0_field_mux[] = {
++ VI0_FIELD_MARK,
++};
++static const unsigned int vin0_clkenb_pins[] = {
++ /* CLKENB */
++ RCAR_GP_PIN(2, 1),
++};
++static const unsigned int vin0_clkenb_mux[] = {
++ VI0_CLKENB_MARK,
++};
++static const unsigned int vin0_clk_pins[] = {
++ /* CLK */
++ RCAR_GP_PIN(2, 0),
++};
++static const unsigned int vin0_clk_mux[] = {
++ VI0_CLK_MARK,
++};
++/* - VIN1 ------------------------------------------------------------------- */
++static const unsigned int vin1_data8_pins[] = {
++ RCAR_GP_PIN(3, 4), RCAR_GP_PIN(3, 5),
++ RCAR_GP_PIN(3, 6), RCAR_GP_PIN(3, 7),
++ RCAR_GP_PIN(3, 8), RCAR_GP_PIN(3, 9),
++ RCAR_GP_PIN(3, 10), RCAR_GP_PIN(3, 11),
++};
++static const unsigned int vin1_data8_mux[] = {
++ VI1_DATA0_MARK, VI1_DATA1_MARK,
++ VI1_DATA2_MARK, VI1_DATA3_MARK,
++ VI1_DATA4_MARK, VI1_DATA5_MARK,
++ VI1_DATA6_MARK, VI1_DATA7_MARK,
++};
++static const unsigned int vin1_data10_pins[] = {
++ RCAR_GP_PIN(3, 4), RCAR_GP_PIN(3, 5),
++ RCAR_GP_PIN(3, 6), RCAR_GP_PIN(3, 7),
++ RCAR_GP_PIN(3, 8), RCAR_GP_PIN(3, 9),
++ RCAR_GP_PIN(3, 10), RCAR_GP_PIN(3, 11),
++ RCAR_GP_PIN(3, 12), RCAR_GP_PIN(3, 13),
++};
++static const unsigned int vin1_data10_mux[] = {
++ VI1_DATA0_MARK, VI1_DATA1_MARK,
++ VI1_DATA2_MARK, VI1_DATA3_MARK,
++ VI1_DATA4_MARK, VI1_DATA5_MARK,
++ VI1_DATA6_MARK, VI1_DATA7_MARK,
++ VI1_DATA8_MARK, VI1_DATA9_MARK,
++};
++static const unsigned int vin1_data12_pins[] = {
++ RCAR_GP_PIN(3, 4), RCAR_GP_PIN(3, 5),
++ RCAR_GP_PIN(3, 6), RCAR_GP_PIN(3, 7),
++ RCAR_GP_PIN(3, 8), RCAR_GP_PIN(3, 9),
++ RCAR_GP_PIN(3, 10), RCAR_GP_PIN(3, 11),
++ RCAR_GP_PIN(3, 12), RCAR_GP_PIN(3, 13),
++ RCAR_GP_PIN(3, 14), RCAR_GP_PIN(3, 15),
++};
++static const unsigned int vin1_data12_mux[] = {
++ VI1_DATA0_MARK, VI1_DATA1_MARK,
++ VI1_DATA2_MARK, VI1_DATA3_MARK,
++ VI1_DATA4_MARK, VI1_DATA5_MARK,
++ VI1_DATA6_MARK, VI1_DATA7_MARK,
++ VI1_DATA8_MARK, VI1_DATA9_MARK,
++ VI1_DATA10_MARK, VI1_DATA11_MARK,
++};
++static const unsigned int vin1_sync_pins[] = {
++ /* VSYNC_N, HSYNC_N */
++ RCAR_GP_PIN(3, 3), RCAR_GP_PIN(3, 2),
++};
++static const unsigned int vin1_sync_mux[] = {
++ VI1_HSYNC_N_MARK, VI1_VSYNC_N_MARK,
++};
++static const unsigned int vin1_field_pins[] = {
++ /* FIELD */
++ RCAR_GP_PIN(3, 16),
++};
++static const unsigned int vin1_field_mux[] = {
++ VI1_FIELD_MARK,
++};
++static const unsigned int vin1_clkenb_pins[] = {
++ /* CLKENB */
++ RCAR_GP_PIN(3, 1),
++};
++static const unsigned int vin1_clkenb_mux[] = {
++ VI1_CLKENB_MARK,
++};
++static const unsigned int vin1_clk_pins[] = {
++ /* CLK */
++ RCAR_GP_PIN(3, 0),
++};
++static const unsigned int vin1_clk_mux[] = {
++ VI1_CLK_MARK,
++};
++
++static const struct sh_pfc_pin_group pinmux_groups[] = {
++ SH_PFC_PIN_GROUP(avb0_rx_ctrl),
++ SH_PFC_PIN_GROUP(avb0_rxc),
++ SH_PFC_PIN_GROUP(avb0_rd0),
++ SH_PFC_PIN_GROUP(avb0_rd1),
++ SH_PFC_PIN_GROUP(avb0_rd2),
++ SH_PFC_PIN_GROUP(avb0_rd3),
++ SH_PFC_PIN_GROUP(avb0_rd4),
++ SH_PFC_PIN_GROUP(avb0_tx_ctrl),
++ SH_PFC_PIN_GROUP(avb0_txc),
++ SH_PFC_PIN_GROUP(avb0_td0),
++ SH_PFC_PIN_GROUP(avb0_td1),
++ SH_PFC_PIN_GROUP(avb0_td2),
++ SH_PFC_PIN_GROUP(avb0_td3),
++ SH_PFC_PIN_GROUP(avb0_td4),
++ SH_PFC_PIN_GROUP(avb0_txcrefclk),
++ SH_PFC_PIN_GROUP(avb0_mdio),
++ SH_PFC_PIN_GROUP(avb0_mdc),
++ SH_PFC_PIN_GROUP(avb0_magic),
++ SH_PFC_PIN_GROUP(avb0_phy_int),
++ SH_PFC_PIN_GROUP(avb0_link),
++ SH_PFC_PIN_GROUP(avb0_avtp_match),
++ SH_PFC_PIN_GROUP(avb0_avtp_pps),
++ SH_PFC_PIN_GROUP(avb0_avtp_capture),
++ SH_PFC_PIN_GROUP(canfd0_data_a),
++ SH_PFC_PIN_GROUP(canfd_clk_a),
++ SH_PFC_PIN_GROUP(canfd0_data_b),
++ SH_PFC_PIN_GROUP(canfd_clk_b),
++ SH_PFC_PIN_GROUP(canfd1_data),
++ SH_PFC_PIN_GROUP(du_rgb666),
++ SH_PFC_PIN_GROUP(du_clk_out_0),
++ SH_PFC_PIN_GROUP(du_clk_out_1),
++ SH_PFC_PIN_GROUP(du_sync),
++ SH_PFC_PIN_GROUP(du_oddf),
++ SH_PFC_PIN_GROUP(du_cde),
++ SH_PFC_PIN_GROUP(du_disp),
++ SH_PFC_PIN_GROUP(hscif0_data),
++ SH_PFC_PIN_GROUP(hscif0_clk),
++ SH_PFC_PIN_GROUP(hscif0_ctrl),
++ SH_PFC_PIN_GROUP(hscif1_data),
++ SH_PFC_PIN_GROUP(hscif1_clk),
++ SH_PFC_PIN_GROUP(hscif1_ctrl),
++ SH_PFC_PIN_GROUP(hscif2_data),
++ SH_PFC_PIN_GROUP(hscif2_clk),
++ SH_PFC_PIN_GROUP(hscif2_ctrl),
++ SH_PFC_PIN_GROUP(hscif3_data),
++ SH_PFC_PIN_GROUP(hscif3_clk),
++ SH_PFC_PIN_GROUP(hscif3_ctrl),
++ SH_PFC_PIN_GROUP(scif_clk_a),
++ SH_PFC_PIN_GROUP(scif_clk_b),
++ SH_PFC_PIN_GROUP(i2c0),
++ SH_PFC_PIN_GROUP(i2c1),
++ SH_PFC_PIN_GROUP(i2c2),
++ SH_PFC_PIN_GROUP(i2c3),
++ SH_PFC_PIN_GROUP(i2c4),
++ SH_PFC_PIN_GROUP(intc_ex_irq0),
++ SH_PFC_PIN_GROUP(intc_ex_irq1),
++ SH_PFC_PIN_GROUP(intc_ex_irq2),
++ SH_PFC_PIN_GROUP(intc_ex_irq3),
++ SH_PFC_PIN_GROUP(intc_ex_irq4),
++ SH_PFC_PIN_GROUP(intc_ex_irq5),
++ SH_PFC_PIN_GROUP(msiof0_clk),
++ SH_PFC_PIN_GROUP(msiof0_sync),
++ SH_PFC_PIN_GROUP(msiof0_ss1),
++ SH_PFC_PIN_GROUP(msiof0_ss2),
++ SH_PFC_PIN_GROUP(msiof0_txd),
++ SH_PFC_PIN_GROUP(msiof0_rxd),
++ SH_PFC_PIN_GROUP(msiof1_clk),
++ SH_PFC_PIN_GROUP(msiof1_sync),
++ SH_PFC_PIN_GROUP(msiof1_ss1),
++ SH_PFC_PIN_GROUP(msiof1_ss2),
++ SH_PFC_PIN_GROUP(msiof1_txd),
++ SH_PFC_PIN_GROUP(msiof1_rxd),
++ SH_PFC_PIN_GROUP(msiof2_clk),
++ SH_PFC_PIN_GROUP(msiof2_sync),
++ SH_PFC_PIN_GROUP(msiof2_ss1),
++ SH_PFC_PIN_GROUP(msiof2_ss2),
++ SH_PFC_PIN_GROUP(msiof2_txd),
++ SH_PFC_PIN_GROUP(msiof2_rxd),
++ SH_PFC_PIN_GROUP(msiof3_clk),
++ SH_PFC_PIN_GROUP(msiof3_sync),
++ SH_PFC_PIN_GROUP(msiof3_ss1),
++ SH_PFC_PIN_GROUP(msiof3_ss2),
++ SH_PFC_PIN_GROUP(msiof3_txd),
++ SH_PFC_PIN_GROUP(msiof3_rxd),
++ SH_PFC_PIN_GROUP(tpu_to0),
++ SH_PFC_PIN_GROUP(tpu_to1),
++ SH_PFC_PIN_GROUP(tpu_to2),
++ SH_PFC_PIN_GROUP(tpu_to3),
++ SH_PFC_PIN_GROUP(pwm0_a),
++ SH_PFC_PIN_GROUP(pwm0_b),
++ SH_PFC_PIN_GROUP(pwm1_a),
++ SH_PFC_PIN_GROUP(pwm1_b),
++ SH_PFC_PIN_GROUP(pwm2_a),
++ SH_PFC_PIN_GROUP(pwm2_b),
++ SH_PFC_PIN_GROUP(pwm3_a),
++ SH_PFC_PIN_GROUP(pwm3_b),
++ SH_PFC_PIN_GROUP(pwm4_a),
++ SH_PFC_PIN_GROUP(pwm4_b),
++ SH_PFC_PIN_GROUP(scif0_data),
++ SH_PFC_PIN_GROUP(scif0_clk),
++ SH_PFC_PIN_GROUP(scif0_ctrl),
++ SH_PFC_PIN_GROUP(scif1_data_a),
++ SH_PFC_PIN_GROUP(scif1_clk),
++ SH_PFC_PIN_GROUP(scif1_ctrl),
++ SH_PFC_PIN_GROUP(scif1_data_b),
++ SH_PFC_PIN_GROUP(scif3_data),
++ SH_PFC_PIN_GROUP(scif3_clk),
++ SH_PFC_PIN_GROUP(scif3_ctrl),
++ SH_PFC_PIN_GROUP(scif4_data),
++ SH_PFC_PIN_GROUP(scif4_clk),
++ SH_PFC_PIN_GROUP(scif4_ctrl),
++ SH_PFC_PIN_GROUP(mmc_data1),
++ SH_PFC_PIN_GROUP(mmc_data4),
++ SH_PFC_PIN_GROUP(mmc_data8),
++ SH_PFC_PIN_GROUP(mmc_ctrl),
++ SH_PFC_PIN_GROUP(mmc_cd),
++ SH_PFC_PIN_GROUP(mmc_wp),
++ SH_PFC_PIN_GROUP(tmu_tclk1_a),
++ SH_PFC_PIN_GROUP(tmu_tclk1_b),
++ SH_PFC_PIN_GROUP(tmu_tclk2_a),
++ SH_PFC_PIN_GROUP(tmu_tclk2_b),
++ SH_PFC_PIN_GROUP(vin0_data8),
++ SH_PFC_PIN_GROUP(vin0_data10),
++ SH_PFC_PIN_GROUP(vin0_data12),
++ SH_PFC_PIN_GROUP(vin0_sync),
++ SH_PFC_PIN_GROUP(vin0_field),
++ SH_PFC_PIN_GROUP(vin0_clkenb),
++ SH_PFC_PIN_GROUP(vin0_clk),
++ SH_PFC_PIN_GROUP(vin1_data8),
++ SH_PFC_PIN_GROUP(vin1_data10),
++ SH_PFC_PIN_GROUP(vin1_data12),
++ SH_PFC_PIN_GROUP(vin1_sync),
++ SH_PFC_PIN_GROUP(vin1_field),
++ SH_PFC_PIN_GROUP(vin1_clkenb),
++ SH_PFC_PIN_GROUP(vin1_clk),
++};
++
++static const char * const avb0_groups[] = {
++ "avb0_rx_ctrl",
++ "avb0_rxc",
++ "avb0_rd1",
++ "avb0_rd4",
++ "avb0_tx_ctrl",
++ "avb0_txc",
++ "avb0_td1",
++ "avb0_td4",
++ "avb0_txcrefclk",
++ "avb0_mdio",
++ "avb0_mdc",
++ "avb0_magic",
++ "avb0_phy_int",
++ "avb0_link",
++ "avb0_avtp_match",
++ "avb0_avtp_pps",
++ "avb0_avtp_capture",
++};
++
++static const char * const canfd0_groups[] = {
++ "canfd0_data_a",
++ "canfd_clk_a",
++ "canfd0_data_b",
++ "canfd_clk_b",
++};
++
++static const char * const canfd1_groups[] = {
++ "canfd1_data",
++};
++
++static const char * const du_groups[] = {
++ "du_rgb666",
++ "du_clk_out_0",
++ "du_clk_out_1",
++ "du_sync",
++ "du_oddf",
++ "du_cde",
++ "du_disp",
++};
++
++static const char * const hscif0_groups[] = {
++ "hscif0_data",
++ "hscif0_clk",
++ "hscif0_ctrl",
++};
++
++static const char * const hscif1_groups[] = {
++ "hscif1_data",
++ "hscif1_clk",
++ "hscif1_ctrl",
++};
++
++static const char * const hscif2_groups[] = {
++ "hscif2_data",
++ "hscif2_clk",
++ "hscif2_ctrl",
++};
++
++static const char * const hscif3_groups[] = {
++ "hscif3_data",
++ "hscif3_clk",
++ "hscif3_ctrl",
++};
++
++static const char * const scif_clk_groups[] = {
++ "scif_clk_a",
++ "scif_clk_b",
++};
++
++static const char * const i2c0_groups[] = {
++ "i2c0",
++};
++
++static const char * const i2c1_groups[] = {
++ "i2c1",
++};
++
++static const char * const i2c2_groups[] = {
++ "i2c2",
++};
++
++static const char * const i2c3_groups[] = {
++ "i2c3",
++};
++
++static const char * const i2c4_groups[] = {
++ "i2c4",
++};
++
++static const char * const intc_ex_groups[] = {
++ "intc_ex_irq0",
++ "intc_ex_irq1",
++ "intc_ex_irq2",
++ "intc_ex_irq3",
++ "intc_ex_irq4",
++ "intc_ex_irq5",
++};
++
++static const char * const msiof0_groups[] = {
++ "msiof0_clk",
++ "msiof0_sync",
++ "msiof0_ss1",
++ "msiof0_ss2",
++ "msiof0_txd",
++ "msiof0_rxd",
++};
++
++static const char * const msiof1_groups[] = {
++ "msiof1_clk",
++ "msiof1_sync",
++ "msiof1_ss1",
++ "msiof1_ss2",
++ "msiof1_txd",
++ "msiof1_rxd",
++};
++
++static const char * const msiof2_groups[] = {
++ "msiof2_clk",
++ "msiof2_sync",
++ "msiof2_ss1",
++ "msiof2_ss2",
++ "msiof2_txd",
++ "msiof2_rxd",
++};
++
++static const char * const msiof3_groups[] = {
++ "msiof3_clk",
++ "msiof3_sync",
++ "msiof3_ss1",
++ "msiof3_ss2",
++ "msiof3_txd",
++ "msiof3_rxd",
++};
++
++static const char * const tpu_groups[] = {
++ "tpu_to0",
++ "tpu_to1",
++ "tpu_to2",
++ "tpu_to3",
++};
++
++static const char * const pwm0_groups[] = {
++ "pwm0_a",
++ "pwm0_b",
++};
++
++static const char * const pwm1_groups[] = {
++ "pwm1_a",
++ "pwm1_b",
++};
++
++static const char * const pwm2_groups[] = {
++ "pwm2_a",
++ "pwm2_b",
++};
++
++static const char * const pwm3_groups[] = {
++ "pwm3_a",
++ "pwm3_b",
++};
++
++static const char * const pwm4_groups[] = {
++ "pwm4_a",
++ "pwm4_b",
++};
++
++static const char * const scif0_groups[] = {
++ "scif0_data",
++// "scif0_clk",
++// "scif0_ctrl",
++};
++
++static const char * const scif1_groups[] = {
++ "scif1_data_a",
++ "scif1_clk",
++ "scif1_ctrl",
++ "scif1_data_b",
++};
++
++static const char * const scif3_groups[] = {
++ "scif3_data",
++ "scif3_clk",
++ "scif3_ctrl",
++};
++
++static const char * const scif4_groups[] = {
++ "scif4_data",
++ "scif4_clk",
++ "scif4_ctrl",
++};
++
++static const char * const mmc_groups[] = {
++ "mmc_data1",
++ "mmc_data4",
++ "mmc_data8",
++ "mmc_ctrl",
++ "mmc_cd",
++ "mmc_wp",
++};
++
++static const char * const tmu_groups[] = {
++ "tmu_tclk1_a",
++ "tmu_tclk1_b",
++ "tmu_tclk2_a",
++ "tmu_tclk2_b",
++};
++
++static const char * const vin0_groups[] = {
++ "vin0_data8",
++ "vin0_data10",
++ "vin0_data12",
++ "vin0_sync",
++ "vin0_field",
++ "vin0_clkenb",
++ "vin0_clk",
++};
++
++static const char * const vin1_groups[] = {
++ "vin1_data8",
++ "vin1_data10",
++ "vin1_data12",
++ "vin1_sync",
++ "vin1_field",
++ "vin1_clkenb",
++ "vin1_clk",
++};
++
++#define POCCTRL0 0x380
++#define POCCTRL1 0x384
++#define PIN2POCCTRL0_SHIFT(a) ({ \
++ int _gp = (a) >> 5; \
++ int _bit = (a) & 0x1f; \
++ ((_gp == 3) && (_bit < 17)) ? _bit + 7 : -1; \
++})
++
++
++static const struct sh_pfc_function pinmux_functions[] = {
++ SH_PFC_FUNCTION(avb0),
++ SH_PFC_FUNCTION(canfd0),
++ SH_PFC_FUNCTION(canfd1),
++ SH_PFC_FUNCTION(du),
++ SH_PFC_FUNCTION(hscif0),
++ SH_PFC_FUNCTION(hscif1),
++ SH_PFC_FUNCTION(hscif2),
++ SH_PFC_FUNCTION(hscif3),
++ SH_PFC_FUNCTION(scif_clk),
++ SH_PFC_FUNCTION(i2c0),
++ SH_PFC_FUNCTION(i2c1),
++ SH_PFC_FUNCTION(i2c2),
++ SH_PFC_FUNCTION(i2c3),
++ SH_PFC_FUNCTION(i2c4),
++ SH_PFC_FUNCTION(intc_ex),
++ SH_PFC_FUNCTION(msiof0),
++ SH_PFC_FUNCTION(msiof1),
++ SH_PFC_FUNCTION(msiof2),
++ SH_PFC_FUNCTION(msiof3),
++ SH_PFC_FUNCTION(tpu),
++ SH_PFC_FUNCTION(pwm0),
++ SH_PFC_FUNCTION(pwm1),
++ SH_PFC_FUNCTION(pwm2),
++ SH_PFC_FUNCTION(pwm3),
++ SH_PFC_FUNCTION(pwm4),
++ SH_PFC_FUNCTION(scif0),
++ SH_PFC_FUNCTION(scif1),
++ SH_PFC_FUNCTION(scif3),
++ SH_PFC_FUNCTION(scif4),
++ SH_PFC_FUNCTION(mmc),
++ SH_PFC_FUNCTION(tmu),
++ SH_PFC_FUNCTION(vin0),
++ SH_PFC_FUNCTION(vin1),
++};
++
++static const struct pinmux_cfg_reg pinmux_config_regs[] = {
++#define F_(x, y) FN_##y
++#define FM(x) FN_##x
++ { PINMUX_CFG_REG("GPSR0", 0xe6060100, 32, 1) {
++ 0, 0,
++ 0, 0,
++ 0, 0,
++ 0, 0,
++ 0, 0,
++ 0, 0,
++ 0, 0,
++ 0, 0,
++ 0, 0,
++ 0, 0,
++ GP_0_21_FN, GPSR0_21,
++ GP_0_20_FN, GPSR0_20,
++ GP_0_19_FN, GPSR0_19,
++ GP_0_18_FN, GPSR0_18,
++ GP_0_17_FN, GPSR0_17,
++ GP_0_16_FN, GPSR0_16,
++ GP_0_15_FN, GPSR0_15,
++ GP_0_14_FN, GPSR0_14,
++ GP_0_13_FN, GPSR0_13,
++ GP_0_12_FN, GPSR0_12,
++ GP_0_11_FN, GPSR0_11,
++ GP_0_10_FN, GPSR0_10,
++ GP_0_9_FN, GPSR0_9,
++ GP_0_8_FN, GPSR0_8,
++ GP_0_7_FN, GPSR0_7,
++ GP_0_6_FN, GPSR0_6,
++ GP_0_5_FN, GPSR0_5,
++ GP_0_4_FN, GPSR0_4,
++ GP_0_3_FN, GPSR0_3,
++ GP_0_2_FN, GPSR0_2,
++ GP_0_1_FN, GPSR0_1,
++ GP_0_0_FN, GPSR0_0, }
++ },
++ { PINMUX_CFG_REG("GPSR1", 0xe6060104, 32, 1) {
++ 0, 0,
++ 0, 0,
++ 0, 0,
++ 0, 0,
++ GP_1_27_FN, GPSR1_27,
++ GP_1_26_FN, GPSR1_26,
++ GP_1_25_FN, GPSR1_25,
++ GP_1_24_FN, GPSR1_24,
++ GP_1_23_FN, GPSR1_23,
++ GP_1_22_FN, GPSR1_22,
++ GP_1_21_FN, GPSR1_21,
++ GP_1_20_FN, GPSR1_20,
++ GP_1_19_FN, GPSR1_19,
++ GP_1_18_FN, GPSR1_18,
++ GP_1_17_FN, GPSR1_17,
++ GP_1_16_FN, GPSR1_16,
++ GP_1_15_FN, GPSR1_15,
++ GP_1_14_FN, GPSR1_14,
++ GP_1_13_FN, GPSR1_13,
++ GP_1_12_FN, GPSR1_12,
++ GP_1_11_FN, GPSR1_11,
++ GP_1_10_FN, GPSR1_10,
++ GP_1_9_FN, GPSR1_9,
++ GP_1_8_FN, GPSR1_8,
++ GP_1_7_FN, GPSR1_7,
++ GP_1_6_FN, GPSR1_6,
++ GP_1_5_FN, GPSR1_5,
++ GP_1_4_FN, GPSR1_4,
++ GP_1_3_FN, GPSR1_3,
++ GP_1_2_FN, GPSR1_2,
++ GP_1_1_FN, GPSR1_1,
++ GP_1_0_FN, GPSR1_0, }
++ },
++ { PINMUX_CFG_REG("GPSR2", 0xe6060108, 32, 1) {
++ 0, 0,
++ 0, 0,
++ 0, 0,
++ 0, 0,
++ 0, 0,
++ 0, 0,
++ 0, 0,
++ 0, 0,
++ 0, 0,
++ 0, 0,
++ 0, 0,
++ 0, 0,
++ 0, 0,
++ 0, 0,
++ 0, 0,
++ GP_2_16_FN, GPSR2_16,
++ GP_2_15_FN, GPSR2_15,
++ GP_2_14_FN, GPSR2_14,
++ GP_2_13_FN, GPSR2_13,
++ GP_2_12_FN, GPSR2_12,
++ GP_2_11_FN, GPSR2_11,
++ GP_2_10_FN, GPSR2_10,
++ GP_2_9_FN, GPSR2_9,
++ GP_2_8_FN, GPSR2_8,
++ GP_2_7_FN, GPSR2_7,
++ GP_2_6_FN, GPSR2_6,
++ GP_2_5_FN, GPSR2_5,
++ GP_2_4_FN, GPSR2_4,
++ GP_2_3_FN, GPSR2_3,
++ GP_2_2_FN, GPSR2_2,
++ GP_2_1_FN, GPSR2_1,
++ GP_2_0_FN, GPSR2_0, }
++ },
++ { PINMUX_CFG_REG("GPSR3", 0xe606010c, 32, 1) {
++ 0, 0,
++ 0, 0,
++ 0, 0,
++ 0, 0,
++ 0, 0,
++ 0, 0,
++ 0, 0,
++ 0, 0,
++ 0, 0,
++ 0, 0,
++ 0, 0,
++ 0, 0,
++ 0, 0,
++ 0, 0,
++ 0, 0,
++ GP_3_16_FN, GPSR3_16,
++ GP_3_15_FN, GPSR3_15,
++ GP_3_14_FN, GPSR3_14,
++ GP_3_13_FN, GPSR3_13,
++ GP_3_12_FN, GPSR3_12,
++ GP_3_11_FN, GPSR3_11,
++ GP_3_10_FN, GPSR3_10,
++ GP_3_9_FN, GPSR3_9,
++ GP_3_8_FN, GPSR3_8,
++ GP_3_7_FN, GPSR3_7,
++ GP_3_6_FN, GPSR3_6,
++ GP_3_5_FN, GPSR3_5,
++ GP_3_4_FN, GPSR3_4,
++ GP_3_3_FN, GPSR3_3,
++ GP_3_2_FN, GPSR3_2,
++ GP_3_1_FN, GPSR3_1,
++ GP_3_0_FN, GPSR3_0, }
++ },
++ { PINMUX_CFG_REG("GPSR4", 0xe6060110, 32, 1) {
++ 0, 0,
++ 0, 0,
++ 0, 0,
++ 0, 0,
++ 0, 0,
++ 0, 0,
++ 0, 0,
++ 0, 0,
++ 0, 0,
++ 0, 0,
++ 0, 0,
++ 0, 0,
++ 0, 0,
++ 0, 0,
++ 0, 0,
++ 0, 0,
++ 0, 0,
++ 0, 0,
++ 0, 0,
++ 0, 0,
++ 0, 0,
++ 0, 0,
++ 0, 0,
++ 0, 0,
++ 0, 0,
++ 0, 0,
++ GP_4_5_FN, GPSR4_5,
++ GP_4_4_FN, GPSR4_4,
++ GP_4_3_FN, GPSR4_3,
++ GP_4_2_FN, GPSR4_2,
++ GP_4_1_FN, GPSR4_1,
++ GP_4_0_FN, GPSR4_0, }
++ },
++ { PINMUX_CFG_REG("GPSR5", 0xe6060114, 32, 1) {
++ 0, 0,
++ 0, 0,
++ 0, 0,
++ 0, 0,
++ 0, 0,
++ 0, 0,
++ 0, 0,
++ 0, 0,
++ 0, 0,
++ 0, 0,
++ 0, 0,
++ 0, 0,
++ 0, 0,
++ 0, 0,
++ 0, 0,
++ 0, 0,
++ 0, 0,
++ GP_5_14_FN, GPSR5_14,
++ GP_5_13_FN, GPSR5_13,
++ GP_5_12_FN, GPSR5_12,
++ GP_5_11_FN, GPSR5_11,
++ GP_5_10_FN, GPSR5_10,
++ GP_5_9_FN, GPSR5_9,
++ GP_5_8_FN, GPSR5_8,
++ GP_5_7_FN, GPSR5_7,
++ GP_5_6_FN, GPSR5_6,
++ GP_5_5_FN, GPSR5_5,
++ GP_5_4_FN, GPSR5_4,
++ GP_5_3_FN, GPSR5_3,
++ GP_5_2_FN, GPSR5_2,
++ GP_5_1_FN, GPSR5_1,
++ GP_5_0_FN, GPSR5_0, }
++ },
++#undef F_
++#undef FM
++
++#define F_(x, y) x,
++#define FM(x) FN_##x,
++ { PINMUX_CFG_REG("IPSR0", 0xe6060200, 32, 4) {
++ IP0_31_28
++ IP0_27_24
++ IP0_23_20
++ IP0_19_16
++ IP0_15_12
++ IP0_11_8
++ IP0_7_4
++ IP0_3_0 }
++ },
++ { PINMUX_CFG_REG("IPSR1", 0xe6060204, 32, 4) {
++ IP1_31_28
++ IP1_27_24
++ IP1_23_20
++ IP1_19_16
++ IP1_15_12
++ IP1_11_8
++ IP1_7_4
++ IP1_3_0 }
++ },
++ { PINMUX_CFG_REG("IPSR2", 0xe6060208, 32, 4) {
++ IP2_31_28
++ IP2_27_24
++ IP2_23_20
++ IP2_19_16
++ IP2_15_12
++ IP2_11_8
++ IP2_7_4
++ IP2_3_0 }
++ },
++ { PINMUX_CFG_REG("IPSR3", 0xe606020c, 32, 4) {
++ IP3_31_28
++ IP3_27_24
++ IP3_23_20
++ IP3_19_16
++ IP3_15_12
++ IP3_11_8
++ IP3_7_4
++ IP3_3_0 }
++ },
++ { PINMUX_CFG_REG("IPSR4", 0xe6060210, 32, 4) {
++ IP4_31_28
++ IP4_27_24
++ IP4_23_20
++ IP4_19_16
++ IP4_15_12
++ IP4_11_8
++ IP4_7_4
++ IP4_3_0 }
++ },
++ { PINMUX_CFG_REG("IPSR5", 0xe6060214, 32, 4) {
++ IP5_31_28
++ IP5_27_24
++ IP5_23_20
++ IP5_19_16
++ IP5_15_12
++ IP5_11_8
++ IP5_7_4
++ IP5_3_0 }
++ },
++ { PINMUX_CFG_REG("IPSR6", 0xe6060218, 32, 4) {
++ IP6_31_28
++ IP6_27_24
++ IP6_23_20
++ IP6_19_16
++ IP6_15_12
++ IP6_11_8
++ IP6_7_4
++ IP6_3_0 }
++ },
++ { PINMUX_CFG_REG("IPSR7", 0xe606021c, 32, 4) {
++ IP7_31_28
++ IP7_27_24
++ IP7_23_20
++ IP7_19_16
++ IP7_15_12
++ IP7_11_8
++ IP7_7_4
++ IP7_3_0 }
++ },
++ { PINMUX_CFG_REG("IPSR8", 0xe6060220, 32, 4) {
++ IP8_31_28
++ IP8_27_24
++ IP8_23_20
++ IP8_19_16
++ IP8_15_12
++ IP8_11_8
++ IP8_7_4
++ IP8_3_0 }
++ },
++#undef F_
++#undef FM
++
++#define F_(x, y) x,
++#define FM(x) FN_##x,
++ { PINMUX_CFG_REG("MOD_SEL0", 0xe6060500, 32, 1) {
++ /* RESERVED 31..12 */
++ 0, 0,
++ 0, 0,
++ 0, 0,
++ 0, 0,
++ 0, 0,
++ 0, 0,
++ 0, 0,
++ 0, 0,
++ 0, 0,
++ 0, 0,
++ 0, 0,
++ 0, 0,
++ 0, 0,
++ 0, 0,
++ 0, 0,
++ 0, 0,
++ 0, 0,
++ 0, 0,
++ 0, 0,
++ 0, 0,
++ MOD_SEL0_11
++ MOD_SEL0_10
++ MOD_SEL0_9
++ MOD_SEL0_8
++ MOD_SEL0_7
++ MOD_SEL0_6
++ MOD_SEL0_5
++ MOD_SEL0_4
++ MOD_SEL0_3
++ MOD_SEL0_2
++ MOD_SEL0_1
++ MOD_SEL0_0 }
++ },
++ { },
++};
++
++static int r8a7797_pin_to_pocctrl(struct sh_pfc *pfc, unsigned int pin, u32 *pocctrl)
++{
++ int bit = -EINVAL;
++
++ *pocctrl = 0xe6060384;
++
++ if (pin >= RCAR_GP_PIN(3, 0) && pin <= RCAR_GP_PIN(3, 16))
++ bit = (pin & 0x1f) + 7;
++
++ return bit;
++}
++
++static const struct sh_pfc_soc_operations pinmux_ops = {
++ .pin_to_pocctrl = r8a7797_pin_to_pocctrl,
++};
++
++const struct sh_pfc_soc_info r8a7797_pinmux_info = {
++ .name = "r8a77970_pfc",
++ .ops = &pinmux_ops,
++ .unlock_reg = 0xe6060000, /* PMMR */
++
++ .function = { PINMUX_FUNCTION_BEGIN, PINMUX_FUNCTION_END },
++
++ .pins = pinmux_pins,
++ .nr_pins = ARRAY_SIZE(pinmux_pins),
++ .groups = pinmux_groups,
++ .nr_groups = ARRAY_SIZE(pinmux_groups),
++ .functions = pinmux_functions,
++ .nr_functions = ARRAY_SIZE(pinmux_functions),
++
++ .cfg_regs = pinmux_config_regs,
++
++ .pinmux_data = pinmux_data,
++ .pinmux_data_size = ARRAY_SIZE(pinmux_data),
++};
+diff --git a/drivers/pinctrl/sh-pfc/sh_pfc.h b/drivers/pinctrl/sh-pfc/sh_pfc.h
+index 5a0da3c..062af89 100644
+--- a/drivers/pinctrl/sh-pfc/sh_pfc.h
++++ b/drivers/pinctrl/sh-pfc/sh_pfc.h
+@@ -288,6 +288,7 @@ struct sh_pfc_soc_info {
+ extern const struct sh_pfc_soc_info r8a7795_es1_pinmux_info;
+ extern const struct sh_pfc_soc_info r8a7796_pinmux_info;
+ extern const struct sh_pfc_soc_info r8a77965_pinmux_info;
++extern const struct sh_pfc_soc_info r8a7797_pinmux_info;
+ extern const struct sh_pfc_soc_info sh7203_pinmux_info;
+ extern const struct sh_pfc_soc_info sh7264_pinmux_info;
+ extern const struct sh_pfc_soc_info sh7269_pinmux_info;
+@@ -393,6 +394,11 @@ struct sh_pfc_soc_info {
+ PORT_GP_CFG_1(bank, 3, fn, sfx, cfg)
+ #define PORT_GP_4(bank, fn, sfx) PORT_GP_CFG_4(bank, fn, sfx, 0)
+
++#define PORT_GP_CFG_6(bank, fn, sfx, cfg) \
++ PORT_GP_CFG_4(bank, fn, sfx, cfg), \
++ PORT_GP_CFG_1(bank, 4, fn, sfx, cfg), PORT_GP_CFG_1(bank, 5, fn, sfx, cfg)
++#define PORT_GP_6(bank, fn, sfx) PORT_GP_CFG_6(bank, fn, sfx, 0)
++
+ #define PORT_GP_CFG_8(bank, fn, sfx, cfg) \
+ PORT_GP_CFG_4(bank, fn, sfx, cfg), \
+ PORT_GP_CFG_1(bank, 4, fn, sfx, cfg), \
+@@ -439,6 +445,12 @@ struct sh_pfc_soc_info {
+ PORT_GP_CFG_1(bank, 17, fn, sfx, cfg)
+ #define PORT_GP_18(bank, fn, sfx) PORT_GP_CFG_18(bank, fn, sfx, 0)
+
++#define PORT_GP_CFG_22(bank, fn, sfx, cfg) \
++ PORT_GP_CFG_18(bank, fn, sfx, cfg), \
++ PORT_GP_CFG_1(bank, 18, fn, sfx, cfg), PORT_GP_CFG_1(bank, 19, fn, sfx, cfg), \
++ PORT_GP_CFG_1(bank, 20, fn, sfx, cfg), PORT_GP_CFG_1(bank, 21, fn, sfx, cfg)
++#define PORT_GP_22(bank, fn, sfx) PORT_GP_CFG_22(bank, fn, sfx, 0)
++
+ #define PORT_GP_CFG_23(bank, fn, sfx, cfg) \
+ PORT_GP_CFG_18(bank, fn, sfx, cfg), \
+ PORT_GP_CFG_1(bank, 18, fn, sfx, cfg), \
+diff --git a/drivers/soc/renesas/Makefile b/drivers/soc/renesas/Makefile
+index 29b8a4d..2ba6a76 100644
+--- a/drivers/soc/renesas/Makefile
++++ b/drivers/soc/renesas/Makefile
+@@ -5,6 +5,7 @@ obj-$(CONFIG_ARCH_RCAR_GEN2) += rcar-rst.o
+ obj-$(CONFIG_ARCH_R8A7795) += rcar-rst.o
+ obj-$(CONFIG_ARCH_R8A7796) += rcar-rst.o
+ obj-$(CONFIG_ARCH_R8A77965) += rcar-rst.o
++obj-$(CONFIG_ARCH_R8A7797) += rcar-rst.o
+
+ obj-$(CONFIG_ARCH_R8A7743) += rcar-sysc.o r8a7743-sysc.o
+ obj-$(CONFIG_ARCH_R8A7745) += rcar-sysc.o r8a7745-sysc.o
+@@ -18,13 +19,16 @@ obj-$(CONFIG_ARCH_R8A7794) += rcar-sysc.o r8a7794-sysc.o
+ obj-$(CONFIG_ARCH_R8A7795) += rcar-sysc.o r8a7795-sysc.o
+ obj-$(CONFIG_ARCH_R8A7796) += rcar-sysc.o r8a7796-sysc.o
+ obj-$(CONFIG_ARCH_R8A77965) += rcar-sysc.o r8a77965-sysc.o
++obj-$(CONFIG_ARCH_R8A7797) += rcar-sysc.o r8a7797-sysc.o
+
+ obj-$(CONFIG_ARCH_R8A7795) += rcar-avs.o
+ obj-$(CONFIG_ARCH_R8A7796) += rcar-avs.o
+ obj-$(CONFIG_ARCH_R8A77965) += rcar-avs.o
++obj-$(CONFIG_ARCH_R8A7797) += rcar-avs.o
+ # EMS for R-Car Gen3
+ obj-$(CONFIG_ARCH_R8A7795) += rcar_ems_ctrl.o
+ obj-$(CONFIG_ARCH_R8A7796) += rcar_ems_ctrl.o
+ obj-$(CONFIG_ARCH_R8A77965) += rcar_ems_ctrl.o
++obj-$(CONFIG_ARCH_R8A7797) += rcar_ems_ctrl.o
+
+ obj-$(CONFIG_RCAR_DDR_BACKUP) += s2ram_ddr_backup.o
+diff --git a/drivers/soc/renesas/r8a7797-sysc.c b/drivers/soc/renesas/r8a7797-sysc.c
+new file mode 100644
+index 0000000..cde7d9e
+--- /dev/null
++++ b/drivers/soc/renesas/r8a7797-sysc.c
+@@ -0,0 +1,39 @@
++/*
++ * Renesas R-Car V3M System Controller
++ *
++ * Copyright (C) 2016 Glider bvba
++ *
++ * This program is free software; you can redistribute it and/or modify
++ * it under the terms of the GNU General Public License as published by
++ * the Free Software Foundation; version 2 of the License.
++ */
++
++#include <linux/bug.h>
++#include <linux/kernel.h>
++
++#include <dt-bindings/power/r8a7797-sysc.h>
++
++#include "rcar-sysc.h"
++
++static const struct rcar_sysc_area r8a7797_areas[] __initconst = {
++ { "always-on", 0, 0, R8A7797_PD_ALWAYS_ON, -1, PD_ALWAYS_ON },
++ { "ca53-scu", 0x140, 0, R8A7797_PD_CA53_SCU, R8A7797_PD_ALWAYS_ON,
++ PD_SCU },
++ { "ca53-cpu0", 0x200, 0, R8A7797_PD_CA53_CPU0, R8A7797_PD_CA53_SCU,
++ PD_CPU_NOCR },
++ { "ca53-cpu1", 0x200, 1, R8A7797_PD_CA53_CPU1, R8A7797_PD_CA53_SCU,
++ PD_CPU_NOCR },
++ { "cr7", 0x240, 0, R8A7797_PD_CR7, R8A7797_PD_ALWAYS_ON },
++ { "a3ir", 0x180, 0, R8A7797_PD_A3IR, R8A7797_PD_ALWAYS_ON },
++ { "a2ir0", 0x400, 0, R8A7797_PD_A2IR0, R8A7797_PD_A3IR },
++ { "a2ir1", 0x400, 1, R8A7797_PD_A2IR1, R8A7797_PD_A3IR },
++ { "a2ir2", 0x400, 2, R8A7797_PD_A2IR2, R8A7797_PD_A3IR },
++ { "a2ir3", 0x400, 3, R8A7797_PD_A2IR3, R8A7797_PD_A3IR },
++ { "a2sc0", 0x400, 4, R8A7797_PD_A2SC0, R8A7797_PD_A3IR },
++ { "a2sc1", 0x400, 5, R8A7797_PD_A2SC1, R8A7797_PD_A3IR },
++};
++
++const struct rcar_sysc_info r8a7797_sysc_info __initconst = {
++ .areas = r8a7797_areas,
++ .num_areas = ARRAY_SIZE(r8a7797_areas),
++};
+diff --git a/drivers/soc/renesas/rcar-rst.c b/drivers/soc/renesas/rcar-rst.c
+index 61c2f2c..bc3632b 100644
+--- a/drivers/soc/renesas/rcar-rst.c
++++ b/drivers/soc/renesas/rcar-rst.c
+@@ -42,6 +42,7 @@ struct rst_config {
+ { .compatible = "renesas,r8a7795-rst", .data = &rcar_rst_gen2 },
+ { .compatible = "renesas,r8a7796-rst", .data = &rcar_rst_gen2 },
+ { .compatible = "renesas,r8a77965-rst", .data = &rcar_rst_gen2 },
++ { .compatible = "renesas,r8a7797-rst", .data = &rcar_rst_gen2 },
+ { /* sentinel */ }
+ };
+
+diff --git a/drivers/soc/renesas/rcar-sysc.c b/drivers/soc/renesas/rcar-sysc.c
+index b25c5cf..1d5d440 100644
+--- a/drivers/soc/renesas/rcar-sysc.c
++++ b/drivers/soc/renesas/rcar-sysc.c
+@@ -324,6 +324,9 @@ static void __init rcar_sysc_pd_setup(struct rcar_sysc_pd *pd)
+ #ifdef CONFIG_ARCH_R8A77965
+ { .compatible = "renesas,r8a77965-sysc", .data = &r8a77965_sysc_info },
+ #endif
++#ifdef CONFIG_ARCH_R8A7797
++ { .compatible = "renesas,r8a7797-sysc", .data = &r8a7797_sysc_info },
++#endif
+ { /* sentinel */ }
+ };
+
+diff --git a/drivers/soc/renesas/rcar-sysc.h b/drivers/soc/renesas/rcar-sysc.h
+index 04b5d01..1eb4e6d 100644
+--- a/drivers/soc/renesas/rcar-sysc.h
++++ b/drivers/soc/renesas/rcar-sysc.h
+@@ -61,4 +61,5 @@ struct rcar_sysc_info {
+ extern const struct rcar_sysc_info r8a7795_sysc_info;
+ extern const struct rcar_sysc_info r8a7796_sysc_info;
+ extern const struct rcar_sysc_info r8a77965_sysc_info;
++extern const struct rcar_sysc_info r8a7797_sysc_info;
+ #endif /* __SOC_RENESAS_RCAR_SYSC_H__ */
+diff --git a/drivers/soc/renesas/rcar_ems_ctrl.c b/drivers/soc/renesas/rcar_ems_ctrl.c
+index ca9af73..388c570 100644
+--- a/drivers/soc/renesas/rcar_ems_ctrl.c
++++ b/drivers/soc/renesas/rcar_ems_ctrl.c
+@@ -24,11 +24,17 @@
+ #include <linux/pm_runtime.h>
+ #include <linux/spinlock.h>
+ #include <linux/thermal.h>
++#include <linux/sys_soc.h>
+
+ #include <linux/soc/renesas/rcar_ems_ctrl.h>
+
+ #define EMS_THERMAL_ZONE_MAX 10
+
++static const struct soc_device_attribute r8a7797[] = {
++ { .soc_id = "r8a7797" },
++ { }
++};
++
+ static void rcar_ems_monitor(struct work_struct *ws);
+ static DECLARE_DELAYED_WORK(rcar_ems_monitor_work, rcar_ems_monitor);
+
+@@ -268,6 +274,10 @@ static int __init rcar_ems_cpu_shutdown_init(void)
+
+ for_each_online_cpu(cpu) {
+ tmp_node = of_get_cpu_node(cpu, NULL);
++ if (soc_device_match(r8a7797)) {
++ if (!of_device_is_compatible(tmp_node, "arm,cortex-a53"))
++ continue;
++ }
+ if (!of_device_is_compatible(tmp_node, "arm,cortex-a57"))
+ continue;
+ for (i = 0; i < total_target_cpu; i++) {
+diff --git a/drivers/soc/renesas/renesas-soc.c b/drivers/soc/renesas/renesas-soc.c
+index 1b33c50..63f943d 100644
+--- a/drivers/soc/renesas/renesas-soc.c
++++ b/drivers/soc/renesas/renesas-soc.c
+@@ -139,6 +139,11 @@ struct renesas_soc {
+ .id = 0x55,
+ };
+
++static const struct renesas_soc soc_rcar_v3m __initconst __maybe_unused = {
++ .family = &fam_rcar_gen3,
++ .id = 0x54,
++};
++
+ static const struct renesas_soc soc_shmobile_ag5 __initconst __maybe_unused = {
+ .family = &fam_shmobile,
+ .id = 0x37,
+@@ -191,6 +196,9 @@ struct renesas_soc {
+ #ifdef CONFIG_ARCH_R8A77965
+ { .compatible = "renesas,r8a77965", .data = &soc_rcar_m3_n },
+ #endif
++#ifdef CONFIG_ARCH_R8A7797
++ { .compatible = "renesas,r8a7797", .data = &soc_rcar_v3m },
++#endif
+ #ifdef CONFIG_ARCH_SH73A0
+ { .compatible = "renesas,sh73a0", .data = &soc_shmobile_ag5 },
+ #endif
+diff --git a/drivers/spi/spi-sh-msiof.c b/drivers/spi/spi-sh-msiof.c
+index 36e70db..a2606fe 100644
+--- a/drivers/spi/spi-sh-msiof.c
++++ b/drivers/spi/spi-sh-msiof.c
+@@ -216,7 +216,8 @@ static int msiof_rcar_is_gen3(struct device *dev)
+
+ return of_device_is_compatible(node, "renesas,msiof-r8a7795") ||
+ of_device_is_compatible(node, "renesas,msiof-r8a7796") ||
+- of_device_is_compatible(node, "renesas,msiof-r8a77965");
++ of_device_is_compatible(node, "renesas,msiof-r8a77965") ||
++ of_device_is_compatible(node, "renesas,msiof-r8a7797");
+ }
+
+ static u32 sh_msiof_read(struct sh_msiof_spi_priv *p, int reg_offs)
+@@ -1190,6 +1191,7 @@ static int sh_msiof_transfer_one(struct spi_master *master,
+ { .compatible = "renesas,msiof-r8a7795", .data = &r8a779x_data },
+ { .compatible = "renesas,msiof-r8a7796", .data = &r8a779x_data },
+ { .compatible = "renesas,msiof-r8a77965", .data = &r8a779x_data },
++ { .compatible = "renesas,msiof-r8a7797", .data = &r8a779x_data },
+ {},
+ };
+ MODULE_DEVICE_TABLE(of, sh_msiof_match);
+diff --git a/drivers/thermal/rcar_gen3_thermal.c b/drivers/thermal/rcar_gen3_thermal.c
+index 6eb7395..a23dd44 100644
+--- a/drivers/thermal/rcar_gen3_thermal.c
++++ b/drivers/thermal/rcar_gen3_thermal.c
+@@ -391,6 +391,30 @@ static int rcar_gen3_r8a7795_thermal_init(struct rcar_thermal_priv *priv)
+ return 0;
+ }
+
++/* @@ transitional */
++static int rcar_gen3_r8a7797_thermal_init(struct rcar_thermal_priv *priv)
++{
++#if 0
++ unsigned long flags;
++ unsigned long reg_val;
++
++ spin_lock_irqsave(&priv->lock, flags);
++ rcar_thermal_write(priv, REG_GEN3_THCTR, 0x0);
++ udelay(1000);
++ rcar_thermal_write(priv, REG_GEN3_IRQCTL, 0x3F);
++ rcar_thermal_write(priv, REG_GEN3_IRQEN,
++ IRQ_TEMP1_BIT | IRQ_TEMPD2_BIT);
++ rcar_thermal_write(priv, REG_GEN3_THCTR, CTCTL | THCNTSEN(BIT_LEN_12));
++ reg_val = rcar_thermal_read(priv, REG_GEN3_THCTR);
++ reg_val &= ~CTCTL;
++ reg_val |= THSST;
++ rcar_thermal_write(priv, REG_GEN3_THCTR, reg_val);
++
++ spin_unlock_irqrestore(&priv->lock, flags);
++#endif
++ return 0;
++}
++
+ /*
+ * Interrupt
+ */
+@@ -472,10 +496,15 @@ static int rcar_gen3_thermal_remove(struct platform_device *pdev)
+ .thermal_init = rcar_gen3_r8a7796_thermal_init,
+ };
+
++static const struct rcar_thermal_data r8a7797_data = {
++ .thermal_init = rcar_gen3_r8a7797_thermal_init,
++};
++
+ static const struct of_device_id rcar_thermal_dt_ids[] = {
+ { .compatible = "renesas,thermal-r8a7795", .data = &r8a7795_data},
+ { .compatible = "renesas,thermal-r8a7796", .data = &r8a7796_data},
+ { .compatible = "renesas,thermal-r8a77965", .data = &r8a7796_data},
++ { .compatible = "renesas,thermal-r8a7797", .data = &r8a7797_data},
+ {},
+ };
+ MODULE_DEVICE_TABLE(of, rcar_thermal_dt_ids);
+diff --git a/include/dt-bindings/clock/r8a7797-cpg-mssr.h b/include/dt-bindings/clock/r8a7797-cpg-mssr.h
+new file mode 100644
+index 0000000..ae6b3af
+--- /dev/null
++++ b/include/dt-bindings/clock/r8a7797-cpg-mssr.h
+@@ -0,0 +1,48 @@
++/*
++ * Copyright (C) 2016 Renesas Electronics Corp.
++ *
++ * This program is free software; you can redistribute it and/or modify
++ * it under the terms of the GNU General Public License as published by
++ * the Free Software Foundation; either version 2 of the License, or
++ * (at your option) any later version.
++ */
++#ifndef __DT_BINDINGS_CLOCK_R8A7797_CPG_MSSR_H__
++#define __DT_BINDINGS_CLOCK_R8A7797_CPG_MSSR_H__
++
++#include <dt-bindings/clock/renesas-cpg-mssr.h>
++
++/* r8a7797 CPG Core Clocks */
++#define R8A7797_CLK_Z2 0
++#define R8A7797_CLK_ZR 1
++#define R8A7797_CLK_ZTR 2
++#define R8A7797_CLK_ZTRD2 3
++#define R8A7797_CLK_ZT 4
++#define R8A7797_CLK_ZX 5
++#define R8A7797_CLK_S1D1 6
++#define R8A7797_CLK_S1D2 7
++#define R8A7797_CLK_S1D4 8
++#define R8A7797_CLK_S2D1 9
++#define R8A7797_CLK_S2D2 10
++#define R8A7797_CLK_S2D4 11
++#define R8A7797_CLK_LB 12
++#define R8A7797_CLK_CL 13
++#define R8A7797_CLK_ZB3 14
++#define R8A7797_CLK_ZB3D2 15
++#define R8A7797_CLK_DDR 16
++#define R8A7797_CLK_CR 17
++#define R8A7797_CLK_CRD2 18
++#define R8A7797_CLK_SD0H 19
++#define R8A7797_CLK_SD0 20
++#define R8A7797_CLK_RPC 21
++#define R8A7797_CLK_RPCD2 22
++#define R8A7797_CLK_MSO 23
++#define R8A7797_CLK_CANFD 24
++#define R8A7797_CLK_CSI0 25
++#define R8A7797_CLK_CSIREF 26
++#define R8A7797_CLK_FRAY 27
++#define R8A7797_CLK_CP 28
++#define R8A7797_CLK_CPEX 29
++#define R8A7797_CLK_R 30
++#define R8A7797_CLK_OSC 31
++
++#endif /* __DT_BINDINGS_CLOCK_R8A7797_CPG_MSSR_H__ */
+diff --git a/include/dt-bindings/power/r8a7797-sysc.h b/include/dt-bindings/power/r8a7797-sysc.h
+new file mode 100644
+index 0000000..5aef212
+--- /dev/null
++++ b/include/dt-bindings/power/r8a7797-sysc.h
+@@ -0,0 +1,32 @@
++/*
++ * Copyright (C) 2016 Glider bvba
++ *
++ * This program is free software; you can redistribute it and/or modify
++ * it under the terms of the GNU General Public License as published by
++ * the Free Software Foundation; version 2 of the License.
++ */
++#ifndef __DT_BINDINGS_POWER_R8A7797_SYSC_H__
++#define __DT_BINDINGS_POWER_R8A7797_SYSC_H__
++
++/*
++ * These power domain indices match the numbers of the interrupt bits
++ * representing the power areas in the various Interrupt Registers
++ * (e.g. SYSCISR, Interrupt Status Register)
++ */
++
++#define R8A7797_PD_CA53_CPU0 5
++#define R8A7797_PD_CA53_CPU1 6
++#define R8A7797_PD_CR7 13
++#define R8A7797_PD_CA53_SCU 21
++#define R8A7797_PD_A2IR0 23
++#define R8A7797_PD_A3IR 24
++#define R8A7797_PD_A2IR1 27
++#define R8A7797_PD_A2IR2 28
++#define R8A7797_PD_A2IR3 29
++#define R8A7797_PD_A2SC0 30
++#define R8A7797_PD_A2SC1 31
++
++/* Always-on power area */
++#define R8A7797_PD_ALWAYS_ON 32
++
++#endif /* __DT_BINDINGS_POWER_R8A7797_SYSC_H__ */
+--
+1.9.1
+
diff --git a/bsp/meta-rcar/meta-rcar-gen3-adas/recipes-kernel/linux/linux-renesas/0019-Revert-media-v4l2-async-remove-unneeded-.registered_.patch b/bsp/meta-rcar/meta-rcar-gen3-adas/recipes-kernel/linux/linux-renesas/0019-Revert-media-v4l2-async-remove-unneeded-.registered_.patch
new file mode 100644
index 00000000..d75e56b7
--- /dev/null
+++ b/bsp/meta-rcar/meta-rcar-gen3-adas/recipes-kernel/linux/linux-renesas/0019-Revert-media-v4l2-async-remove-unneeded-.registered_.patch
@@ -0,0 +1,51 @@
+From f12f0b1d3fdb5acbe1490c0cbf086a7b250e0d12 Mon Sep 17 00:00:00 2001
+From: Vladimir Barinov <vladimir.barinov@cogentembedded.com>
+Date: Sun, 14 May 2017 15:23:57 +0300
+Subject: [PATCH 014/122] Revert "[media] v4l2-async: remove unneeded
+ .registered_async callback"
+
+This reverts commit a53d2f299dc83340c695e153363a2f21641d5f58.
+---
+ drivers/media/v4l2-core/v4l2-async.c | 4 ++++
+ include/media/v4l2-subdev.h | 3 +++
+ 2 files changed, 7 insertions(+)
+
+diff --git a/drivers/media/v4l2-core/v4l2-async.c b/drivers/media/v4l2-core/v4l2-async.c
+index a7c3464..7b6c556 100644
+--- a/drivers/media/v4l2-core/v4l2-async.c
++++ b/drivers/media/v4l2-core/v4l2-async.c
+@@ -225,6 +225,10 @@ static int v4l2_async_match_notify(struct v4l2_async_notifier *notifier,
+ /* Move from the global subdevice list to notifier's done */
+ list_move(&sd->async_list, &notifier->done);
+
++ ret = v4l2_subdev_call(sd, core, registered_async);
++ if (ret < 0 && ret != -ENOIOCTLCMD)
++ return ret;
++
+ /*
+ * See if the sub-device has a notifier. If not, return here.
+ */
+diff --git a/include/media/v4l2-subdev.h b/include/media/v4l2-subdev.h
+index ec399c7..c7f2a77 100644
+--- a/include/media/v4l2-subdev.h
++++ b/include/media/v4l2-subdev.h
+@@ -184,6 +184,8 @@ struct v4l2_subdev_io_pin_config {
+ * for it to be warned when the value of a control changes.
+ *
+ * @unsubscribe_event: remove event subscription from the control framework.
++ *
++ * @registered_async: the subdevice has been registered async.
+ */
+ struct v4l2_subdev_core_ops {
+ int (*log_status)(struct v4l2_subdev *sd);
+@@ -209,6 +211,7 @@ struct v4l2_subdev_core_ops {
+ struct v4l2_event_subscription *sub);
+ int (*unsubscribe_event)(struct v4l2_subdev *sd, struct v4l2_fh *fh,
+ struct v4l2_event_subscription *sub);
++ int (*registered_async)(struct v4l2_subdev *sd);
+ };
+
+ /**
+--
+2.7.4
+
diff --git a/bsp/meta-rcar/meta-rcar-gen3-adas/recipes-kernel/linux/linux-renesas/0020-ti-st-add-device-tree-support.patch b/bsp/meta-rcar/meta-rcar-gen3-adas/recipes-kernel/linux/linux-renesas/0020-ti-st-add-device-tree-support.patch
new file mode 100644
index 00000000..4493f7ac
--- /dev/null
+++ b/bsp/meta-rcar/meta-rcar-gen3-adas/recipes-kernel/linux/linux-renesas/0020-ti-st-add-device-tree-support.patch
@@ -0,0 +1,236 @@
+From b40d2c028af5fd365d8e6352b40264036e1a3dd2 Mon Sep 17 00:00:00 2001
+From: Eyal Reizer <eyalr@ti.com>
+Date: Thu, 23 May 2013 17:11:14 +0300
+Subject: [PATCH 015/122] ti-st: add device tree support
+
+When using device tree, driver configuration data need to be read from
+device node.
+Add support for getting the platform data information from the device
+tree information stored in the .dtb file in case it exists.
+
+Change-Id: I74f7f869fc257a057edb9f35c5fd8cbafb810164
+Signed-off-by: Eyal Reizer <eyalr@ti.com>
+Signed-off-by: bvijay <bvijay@ti.com>
+Signed-off-by: Andrey Gusakov <andrey.gusakov@cogentembedded.com>
+---
+ drivers/misc/ti-st/st_kim.c | 92 +++++++++++++++++++++++++++++++++++++++++----
+ drivers/misc/ti-st/st_ll.c | 19 +++++++++-
+ 2 files changed, 102 insertions(+), 9 deletions(-)
+
+diff --git a/drivers/misc/ti-st/st_kim.c b/drivers/misc/ti-st/st_kim.c
+index dda3ed7..01edf9d 100644
+--- a/drivers/misc/ti-st/st_kim.c
++++ b/drivers/misc/ti-st/st_kim.c
+@@ -43,6 +43,9 @@ static struct platform_device *st_kim_devices[MAX_ST_DEVICES];
+ /**********************************************************************/
+ /* internal functions */
+
++struct ti_st_plat_data *dt_pdata;
++static struct ti_st_plat_data *get_platform_data(struct device *dev);
++
+ /**
+ * st_get_plat_device -
+ * function which returns the reference to the platform device
+@@ -463,7 +466,12 @@ long st_kim_start(void *kim_data)
+ struct kim_data_s *kim_gdata = (struct kim_data_s *)kim_data;
+
+ pr_info(" %s", __func__);
+- pdata = kim_gdata->kim_pdev->dev.platform_data;
++ if (kim_gdata->kim_pdev->dev.of_node) {
++ pr_debug("use device tree data");
++ pdata = dt_pdata;
++ } else {
++ pdata = kim_gdata->kim_pdev->dev.platform_data;
++ }
+
+ do {
+ /* platform specific enabling code here */
+@@ -523,12 +531,17 @@ long st_kim_stop(void *kim_data)
+ {
+ long err = 0;
+ struct kim_data_s *kim_gdata = (struct kim_data_s *)kim_data;
+- struct ti_st_plat_data *pdata =
+- kim_gdata->kim_pdev->dev.platform_data;
++ struct ti_st_plat_data *pdata;
+ struct tty_struct *tty = kim_gdata->core_data->tty;
+
+ reinit_completion(&kim_gdata->ldisc_installed);
+
++ if (kim_gdata->kim_pdev->dev.of_node) {
++ pr_debug("use device tree data");
++ pdata = dt_pdata;
++ } else
++ pdata = kim_gdata->kim_pdev->dev.platform_data;
++
+ if (tty) { /* can be called before ldisc is installed */
+ /* Flush any pending characters in the driver and discipline. */
+ tty_ldisc_flush(tty);
+@@ -720,13 +733,53 @@ static const struct file_operations list_debugfs_fops = {
+ * board-*.c file
+ */
+
++static const struct of_device_id kim_of_match[] = {
++{
++ .compatible = "kim",
++ },
++ {}
++};
++MODULE_DEVICE_TABLE(of, kim_of_match);
++
++static struct ti_st_plat_data *get_platform_data(struct device *dev)
++{
++ struct device_node *np = dev->of_node;
++ const u32 *dt_property;
++ int len;
++
++ dt_pdata = kzalloc(sizeof(*dt_pdata), GFP_KERNEL);
++
++ if (!dt_pdata)
++ pr_err("Can't allocate device_tree platform data\n");
++
++ dt_property = of_get_property(np, "dev_name", &len);
++ if (dt_property)
++ memcpy(&dt_pdata->dev_name, dt_property, len);
++ of_property_read_u32(np, "nshutdown_gpio",
++ (u32 *)&dt_pdata->nshutdown_gpio);
++ of_property_read_u32(np, "flow_cntrl", (u32 *)&dt_pdata->flow_cntrl);
++ of_property_read_u32(np, "baud_rate", (u32 *)&dt_pdata->baud_rate);
++
++ return dt_pdata;
++}
++
+ static struct dentry *kim_debugfs_dir;
+ static int kim_probe(struct platform_device *pdev)
+ {
+ struct kim_data_s *kim_gdata;
+- struct ti_st_plat_data *pdata = pdev->dev.platform_data;
++ struct ti_st_plat_data *pdata;
+ int err;
+
++ if (pdev->dev.of_node)
++ pdata = get_platform_data(&pdev->dev);
++ else
++ pdata = pdev->dev.platform_data;
++
++ if (pdata == NULL) {
++ dev_err(&pdev->dev, "Platform Data is missing\n");
++ return -ENXIO;
++ }
++
+ if ((pdev->id != -1) && (pdev->id < MAX_ST_DEVICES)) {
+ /* multiple devices could exist */
+ st_kim_devices[pdev->id] = pdev;
+@@ -807,9 +860,16 @@ static int kim_probe(struct platform_device *pdev)
+ static int kim_remove(struct platform_device *pdev)
+ {
+ /* free the GPIOs requested */
+- struct ti_st_plat_data *pdata = pdev->dev.platform_data;
++ struct ti_st_plat_data *pdata;
+ struct kim_data_s *kim_gdata;
+
++ if (pdev->dev.of_node) {
++ pr_debug("use device tree data");
++ pdata = dt_pdata;
++ } else {
++ pdata = pdev->dev.platform_data;
++ }
++
+ kim_gdata = platform_get_drvdata(pdev);
+
+ /* Free the Bluetooth/FM/GPIO
+@@ -827,12 +887,22 @@ static int kim_remove(struct platform_device *pdev)
+
+ kfree(kim_gdata);
+ kim_gdata = NULL;
++ kfree(dt_pdata);
++ dt_pdata = NULL;
++
+ return 0;
+ }
+
+ static int kim_suspend(struct platform_device *pdev, pm_message_t state)
+ {
+- struct ti_st_plat_data *pdata = pdev->dev.platform_data;
++ struct ti_st_plat_data *pdata;
++
++ if (pdev->dev.of_node) {
++ pr_debug("use device tree data");
++ pdata = dt_pdata;
++ } else {
++ pdata = pdev->dev.platform_data;
++ }
+
+ if (pdata->suspend)
+ return pdata->suspend(pdev, state);
+@@ -842,7 +912,14 @@ static int kim_suspend(struct platform_device *pdev, pm_message_t state)
+
+ static int kim_resume(struct platform_device *pdev)
+ {
+- struct ti_st_plat_data *pdata = pdev->dev.platform_data;
++ struct ti_st_plat_data *pdata;
++
++ if (pdev->dev.of_node) {
++ pr_debug("use device tree data");
++ pdata = dt_pdata;
++ } else {
++ pdata = pdev->dev.platform_data;
++ }
+
+ if (pdata->resume)
+ return pdata->resume(pdev);
+@@ -859,6 +936,7 @@ static struct platform_driver kim_platform_driver = {
+ .resume = kim_resume,
+ .driver = {
+ .name = "kim",
++ .of_match_table = of_match_ptr(kim_of_match),
+ },
+ };
+
+diff --git a/drivers/misc/ti-st/st_ll.c b/drivers/misc/ti-st/st_ll.c
+index 93b4d67..644f00e 100644
+--- a/drivers/misc/ti-st/st_ll.c
++++ b/drivers/misc/ti-st/st_ll.c
+@@ -25,7 +25,10 @@
+ #include <linux/platform_device.h>
+ #include <linux/ti_wilink_st.h>
+
++extern struct ti_st_plat_data *dt_pdata;
++
+ /**********************************************************************/
++
+ /* internal functions */
+ static void send_ll_cmd(struct st_data_s *st_data,
+ unsigned char cmd)
+@@ -53,7 +56,13 @@ static void ll_device_want_to_sleep(struct st_data_s *st_data)
+
+ /* communicate to platform about chip asleep */
+ kim_data = st_data->kim_data;
+- pdata = kim_data->kim_pdev->dev.platform_data;
++ if (kim_data->kim_pdev->dev.of_node) {
++ pr_debug("use device tree data");
++ pdata = dt_pdata;
++ } else {
++ pdata = kim_data->kim_pdev->dev.platform_data;
++ }
++
+ if (pdata->chip_asleep)
+ pdata->chip_asleep(NULL);
+ }
+@@ -86,7 +95,13 @@ static void ll_device_want_to_wakeup(struct st_data_s *st_data)
+
+ /* communicate to platform about chip wakeup */
+ kim_data = st_data->kim_data;
+- pdata = kim_data->kim_pdev->dev.platform_data;
++ if (kim_data->kim_pdev->dev.of_node) {
++ pr_debug("use device tree data");
++ pdata = dt_pdata;
++ } else {
++ pdata = kim_data->kim_pdev->dev.platform_data;
++ }
++
+ if (pdata->chip_awake)
+ pdata->chip_awake(NULL);
+ }
+--
+2.7.4
+
diff --git a/bsp/meta-rcar/meta-rcar-gen3-adas/recipes-kernel/linux/linux-renesas/0021-btwilink-add-minimal-device-tree-support.patch b/bsp/meta-rcar/meta-rcar-gen3-adas/recipes-kernel/linux/linux-renesas/0021-btwilink-add-minimal-device-tree-support.patch
new file mode 100644
index 00000000..0d79c3b6
--- /dev/null
+++ b/bsp/meta-rcar/meta-rcar-gen3-adas/recipes-kernel/linux/linux-renesas/0021-btwilink-add-minimal-device-tree-support.patch
@@ -0,0 +1,54 @@
+From e1a68682ff98b44c9614dad8e21d2bd12d8038d8 Mon Sep 17 00:00:00 2001
+From: Eyal Reizer <eyalr@ti.com>
+Date: Thu, 23 May 2013 17:15:21 +0300
+Subject: [PATCH 016/122] btwilink: add minimal device tree support
+
+Add minimal device tree support to the btwilink driver that is used
+for binding bluetooth with the ti-st shared transport driver.
+
+Change-Id: I301c49d29046f20f8868bebb14347e82c12c8140
+Signed-off-by: Eyal Reizer <eyalr@ti.com>
+Signed-off-by: bvijay <bvijay@ti.com>
+Signed-off-by: Andrey Gusakov <andrey.gusakov@cogentembedded.com>
+---
+ drivers/bluetooth/btwilink.c | 10 ++++++++++
+ 1 file changed, 10 insertions(+)
+
+diff --git a/drivers/bluetooth/btwilink.c b/drivers/bluetooth/btwilink.c
+index 5ef8000..9f053f2 100644
+--- a/drivers/bluetooth/btwilink.c
++++ b/drivers/bluetooth/btwilink.c
+@@ -30,6 +30,7 @@
+
+ #include <linux/ti_wilink_st.h>
+ #include <linux/module.h>
++#include <linux/of.h>
+
+ /* Bluetooth Driver Version */
+ #define VERSION "1.0"
+@@ -274,6 +275,14 @@ static int ti_st_send_frame(struct hci_dev *hdev, struct sk_buff *skb)
+ return 0;
+ }
+
++static const struct of_device_id btwilink_of_match[] = {
++{
++ .compatible = "btwilink",
++ },
++ {}
++};
++MODULE_DEVICE_TABLE(of, btwilink_of_match);
++
+ static int bt_ti_probe(struct platform_device *pdev)
+ {
+ struct ti_st *hst;
+@@ -337,6 +346,7 @@ static struct platform_driver btwilink_driver = {
+ .remove = bt_ti_remove,
+ .driver = {
+ .name = "btwilink",
++ .of_match_table = of_match_ptr(btwilink_of_match),
+ },
+ };
+
+--
+2.7.4
+
diff --git a/bsp/meta-rcar/meta-rcar-gen3-adas/recipes-kernel/linux/linux-renesas/0022-ASoC-Modify-check-condition-of-multiple-bindings-of-.patch b/bsp/meta-rcar/meta-rcar-gen3-adas/recipes-kernel/linux/linux-renesas/0022-ASoC-Modify-check-condition-of-multiple-bindings-of-.patch
new file mode 100644
index 00000000..282a4eb6
--- /dev/null
+++ b/bsp/meta-rcar/meta-rcar-gen3-adas/recipes-kernel/linux/linux-renesas/0022-ASoC-Modify-check-condition-of-multiple-bindings-of-.patch
@@ -0,0 +1,49 @@
+From e27c2e3bb765958c217e46429776a0386c5b089f Mon Sep 17 00:00:00 2001
+From: Andrey Gusakov <andrey.gusakov@cogentembedded.com>
+Date: Tue, 13 Dec 2016 18:08:39 +0300
+Subject: [PATCH 017/122] ASoC: Modify check condition of multiple bindings of
+ components
+
+https://patchwork.kernel.org/patch/7385501/
+...and some more hacks to bind one component (with several DAIs)
+to more than one sound card.
+
+KF has 4 sound cards (pcm3168a, ak4613, radio, wl18xx) and just one
+compinent ec500000.sound that can not be bound to all 4 cards.
+This is a lack of current implementation of sound/soc/sh/rcar/* ASoC stack
+The ec500000.sound resources (PCM/DMA, dais) needs to be shared between
+all 4 sound cards if we want all cards work runtime.
+Or we have to enable only one of them in dts file as it is designed.
+
+Signed-off-by: Andrey Gusakov <andrey.gusakov@cogentembedded.com>
+---
+ sound/soc/soc-core.c | 6 ++++--
+ 1 file changed, 4 insertions(+), 2 deletions(-)
+
+diff --git a/sound/soc/soc-core.c b/sound/soc/soc-core.c
+index 8771405..0ec3674 100644
+--- a/sound/soc/soc-core.c
++++ b/sound/soc/soc-core.c
+@@ -1516,7 +1516,8 @@ static int soc_probe_component(struct snd_soc_card *card,
+ return 0;
+
+ if (component->card) {
+- if (component->card != card) {
++ if (component->card != card &&
++ component->registered_as_component) {
+ dev_err(component->dev,
+ "Trying to bind component to card \"%s\" but is already bound to card \"%s\"\n",
+ card->name, component->card->name);
+@@ -3471,7 +3472,8 @@ int snd_soc_add_component(struct device *dev,
+ goto err_free;
+
+ component->ignore_pmdown_time = true;
+- component->registered_as_component = true;
++ if (num_dai == 1)
++ component->registered_as_component = true;
+
+ if (component_driver->endianness) {
+ for (i = 0; i < num_dai; i++) {
+--
+2.7.4
+
diff --git a/bsp/meta-rcar/meta-rcar-gen3-adas/recipes-kernel/linux/linux-renesas/0023-ASoC-add-dummy-Si468x-driver.patch b/bsp/meta-rcar/meta-rcar-gen3-adas/recipes-kernel/linux/linux-renesas/0023-ASoC-add-dummy-Si468x-driver.patch
new file mode 100644
index 00000000..17111d96
--- /dev/null
+++ b/bsp/meta-rcar/meta-rcar-gen3-adas/recipes-kernel/linux/linux-renesas/0023-ASoC-add-dummy-Si468x-driver.patch
@@ -0,0 +1,122 @@
+From e4ed26d4d88b11516307ca0369c7f5f213bd3811 Mon Sep 17 00:00:00 2001
+From: Andrey Gusakov <andrey.gusakov@cogentembedded.com>
+Date: Tue, 13 Dec 2016 18:07:13 +0300
+Subject: [PATCH 018/122] ASoC: add dummy Si468x driver
+
+Signed-off-by: Andrey Gusakov <andrey.gusakov@cogentembedded.com>
+---
+ sound/soc/codecs/Kconfig | 3 +++
+ sound/soc/codecs/Makefile | 2 ++
+ sound/soc/codecs/si468x.c | 66 +++++++++++++++++++++++++++++++++++++++++++++++
+ 3 files changed, 71 insertions(+)
+ create mode 100644 sound/soc/codecs/si468x.c
+
+diff --git a/sound/soc/codecs/Kconfig b/sound/soc/codecs/Kconfig
+index c367d11..8d52af2 100644
+--- a/sound/soc/codecs/Kconfig
++++ b/sound/soc/codecs/Kconfig
+@@ -679,6 +679,9 @@ config SND_SOC_PCM3168A_SPI
+ select SND_SOC_PCM3168A
+ select REGMAP_SPI
+
++config SND_SOC_SI468X
++ tristate "Dummy sound driver for Si468x radio"
++
+ config SND_SOC_PCM5102A
+ tristate
+
+diff --git a/sound/soc/codecs/Makefile b/sound/soc/codecs/Makefile
+index 05018b7..79b4386 100644
+--- a/sound/soc/codecs/Makefile
++++ b/sound/soc/codecs/Makefile
+@@ -139,6 +139,7 @@ snd-soc-sigmadsp-objs := sigmadsp.o
+ snd-soc-sigmadsp-i2c-objs := sigmadsp-i2c.o
+ snd-soc-sigmadsp-regmap-objs := sigmadsp-regmap.o
+ snd-soc-si476x-objs := si476x.o
++snd-soc-si468x-objs := si468x.o
+ snd-soc-sirf-audio-codec-objs := sirf-audio-codec.o
+ snd-soc-sn95031-objs := sn95031.o
+ snd-soc-spdif-tx-objs := spdif_transmitter.o
+@@ -377,6 +378,7 @@ obj-$(CONFIG_SND_SOC_SIGMADSP) += snd-soc-sigmadsp.o
+ obj-$(CONFIG_SND_SOC_SIGMADSP_I2C) += snd-soc-sigmadsp-i2c.o
+ obj-$(CONFIG_SND_SOC_SIGMADSP_REGMAP) += snd-soc-sigmadsp-regmap.o
+ obj-$(CONFIG_SND_SOC_SI476X) += snd-soc-si476x.o
++obj-$(CONFIG_SND_SOC_SI468X) += snd-soc-si468x.o
+ obj-$(CONFIG_SND_SOC_SN95031) +=snd-soc-sn95031.o
+ obj-$(CONFIG_SND_SOC_SPDIF) += snd-soc-spdif-rx.o snd-soc-spdif-tx.o
+ obj-$(CONFIG_SND_SOC_SIRF_AUDIO_CODEC) += sirf-audio-codec.o
+diff --git a/sound/soc/codecs/si468x.c b/sound/soc/codecs/si468x.c
+new file mode 100644
+index 0000000..18b099f
+--- /dev/null
++++ b/sound/soc/codecs/si468x.c
+@@ -0,0 +1,66 @@
++/*
++ * Dummy sound driver for Si468x DAB/FM/AM chips
++ * Copyright 2016 Andrey Gusakov <andrey.gusakov@cogentembedded.com>
++ *
++ * Based on: Driver for the DFBM-CS320 bluetooth module
++ * Copyright 2011 Lars-Peter Clausen <lars@metafoo.de>
++ *
++ * This program is free software; you can redistribute it and/or modify it
++ * under the terms of the GNU General Public License as published by the
++ * Free Software Foundation; either version 2 of the License, or (at your
++ * option) any later version.
++ *
++ */
++
++#include <linux/init.h>
++#include <linux/module.h>
++#include <linux/platform_device.h>
++
++#include <sound/soc.h>
++
++static struct snd_soc_dai_driver si468x_dai = {
++ .name = "si468x-pcm",
++ .capture = {
++ .channels_min = 2,
++ .channels_max = 2,
++ .rates = SNDRV_PCM_RATE_48000,
++ .formats = SNDRV_PCM_FMTBIT_S16_LE,
++ },
++};
++
++static struct snd_soc_codec_driver soc_codec_dev_si468x;
++
++static int si468x_probe(struct platform_device *pdev)
++{
++ return snd_soc_register_codec(&pdev->dev, &soc_codec_dev_si468x,
++ &si468x_dai, 1);
++}
++
++static int si468x_remove(struct platform_device *pdev)
++{
++ snd_soc_unregister_codec(&pdev->dev);
++
++ return 0;
++}
++
++static const struct of_device_id si468x_of_match[] = {
++ { .compatible = "si,si468x-pcm", },
++ { }
++};
++MODULE_DEVICE_TABLE(of, si468x_of_match);
++
++static struct platform_driver si468x_driver = {
++ .driver = {
++ .name = "si468x",
++ .of_match_table = si468x_of_match,
++ .owner = THIS_MODULE,
++ },
++ .probe = si468x_probe,
++ .remove = si468x_remove,
++};
++
++module_platform_driver(si468x_driver);
++
++MODULE_AUTHOR("Andrey Gusakov <andrey.gusakov@cogentembedded.com>");
++MODULE_DESCRIPTION("ASoC Si468x radio chip driver");
++MODULE_LICENSE("GPL");
+--
+2.7.4
+
diff --git a/bsp/meta-rcar/meta-rcar-gen3-adas/recipes-kernel/linux/linux-renesas/0024-wl18xx-do-not-invert-IRQ-on-WLxxxx-side.patch b/bsp/meta-rcar/meta-rcar-gen3-adas/recipes-kernel/linux/linux-renesas/0024-wl18xx-do-not-invert-IRQ-on-WLxxxx-side.patch
new file mode 100644
index 00000000..0b2c1fc7
--- /dev/null
+++ b/bsp/meta-rcar/meta-rcar-gen3-adas/recipes-kernel/linux/linux-renesas/0024-wl18xx-do-not-invert-IRQ-on-WLxxxx-side.patch
@@ -0,0 +1,47 @@
+From df629d74744e453f2d72f412698befb20bf56f73 Mon Sep 17 00:00:00 2001
+From: Andrey Gusakov <andrey.gusakov@cogentembedded.com>
+Date: Mon, 22 May 2017 17:22:38 +0300
+Subject: [PATCH 019/122] wl18xx: do not invert IRQ on WLxxxx side
+
+Signed-off-by: Andrey Gusakov <andrey.gusakov@cogentembedded.com>
+---
+ drivers/net/wireless/ti/wl18xx/main.c | 8 ++++++++
+ 1 file changed, 8 insertions(+)
+
+diff --git a/drivers/net/wireless/ti/wl18xx/main.c b/drivers/net/wireless/ti/wl18xx/main.c
+index 0cf3b40..b1c4cdb 100644
+--- a/drivers/net/wireless/ti/wl18xx/main.c
++++ b/drivers/net/wireless/ti/wl18xx/main.c
+@@ -878,7 +878,9 @@ static int wl18xx_pre_upload(struct wl1271 *wl)
+ {
+ u32 tmp;
+ int ret;
++#if 0
+ u16 irq_invert;
++#endif
+
+ BUILD_BUG_ON(sizeof(struct wl18xx_mac_and_phy_params) >
+ WL18XX_PHY_INIT_MEM_SIZE);
+@@ -931,6 +933,11 @@ static int wl18xx_pre_upload(struct wl1271 *wl)
+ if (ret < 0)
+ goto out;
+
++#if 0
++ /* We have level translator with inversion on IRQ line so we
++ * set IRQ_TYPE_EDGE_FALLING in DTS, but we do not need to
++ * invert IRQ logic on WLxxxx side!
++ */
+ ret = irq_get_trigger_type(wl->irq);
+ if ((ret == IRQ_TYPE_LEVEL_LOW) || (ret == IRQ_TYPE_EDGE_FALLING)) {
+ wl1271_info("using inverted interrupt logic: %d", ret);
+@@ -950,6 +957,7 @@ static int wl18xx_pre_upload(struct wl1271 *wl)
+
+ ret = wlcore_set_partition(wl, &wl->ptable[PART_PHY_INIT]);
+ }
++#endif
+
+ out:
+ return ret;
+--
+2.7.4
+
diff --git a/bsp/meta-rcar/meta-rcar-gen3-adas/recipes-kernel/linux/linux-renesas/0025-drm-adv7511-Enable-HPD-interrupts-to-support-hotplug.patch b/bsp/meta-rcar/meta-rcar-gen3-adas/recipes-kernel/linux/linux-renesas/0025-drm-adv7511-Enable-HPD-interrupts-to-support-hotplug.patch
new file mode 100644
index 00000000..f4dfb8fa
--- /dev/null
+++ b/bsp/meta-rcar/meta-rcar-gen3-adas/recipes-kernel/linux/linux-renesas/0025-drm-adv7511-Enable-HPD-interrupts-to-support-hotplug.patch
@@ -0,0 +1,29 @@
+From 1bb61bdd98bc8980abd6359d5a839af3f4d75a2f Mon Sep 17 00:00:00 2001
+From: Vladimir Barinov <vladimir.barinov@cogentembedded.com>
+Date: Tue, 30 May 2017 17:41:21 +0300
+Subject: [PATCH 020/122] drm: adv7511: Enable HPD interrupts to support
+ hotplug
+
+This patch enables HPD (hot plug detect) interrupt support
+
+Signed-off-by: Andrey Gusakov <andrey.gusakov@cogentembedded.com>
+---
+ drivers/gpu/drm/bridge/adv7511/adv7511_drv.c | 2 +-
+ 1 file changed, 1 insertion(+), 1 deletion(-)
+
+diff --git a/drivers/gpu/drm/bridge/adv7511/adv7511_drv.c b/drivers/gpu/drm/bridge/adv7511/adv7511_drv.c
+index dbc4642..69f605b 100644
+--- a/drivers/gpu/drm/bridge/adv7511/adv7511_drv.c
++++ b/drivers/gpu/drm/bridge/adv7511/adv7511_drv.c
+@@ -27,7 +27,7 @@ static const struct reg_sequence adv7511_fixed_registers[] = {
+ { 0x98, 0x03 },
+ { 0x9a, 0xe0 },
+ { 0x9c, 0x30 },
+- { 0x9d, 0x61 },
++ { 0x9d, 0x01 },
+ { 0xa2, 0xa4 },
+ { 0xa3, 0xa4 },
+ { 0xe0, 0xd0 },
+--
+2.7.4
+
diff --git a/bsp/meta-rcar/meta-rcar-gen3-adas/recipes-kernel/linux/linux-renesas/0026-drm-adv7511-add-polling-mode-when-no-irq-available.patch b/bsp/meta-rcar/meta-rcar-gen3-adas/recipes-kernel/linux/linux-renesas/0026-drm-adv7511-add-polling-mode-when-no-irq-available.patch
new file mode 100644
index 00000000..3adfa21d
--- /dev/null
+++ b/bsp/meta-rcar/meta-rcar-gen3-adas/recipes-kernel/linux/linux-renesas/0026-drm-adv7511-add-polling-mode-when-no-irq-available.patch
@@ -0,0 +1,30 @@
+From 06473f51a6aa077cd56745bd14d114ff3269fe19 Mon Sep 17 00:00:00 2001
+From: Andrey Gusakov <andrey.gusakov@cogentembedded.com>
+Date: Tue, 30 May 2017 18:42:09 +0300
+Subject: [PATCH] drm: adv7511: add polling mode (when no irq available)
+
+Signed-off-by: Andrey Gusakov <andrey.gusakov@cogentembedded.com>
+---
+ drivers/gpu/drm/bridge/adv7511/adv7511_drv.c | 6 +++++-
+ 1 file changed, 5 insertions(+), 1 deletion(-)
+
+diff --git a/drivers/gpu/drm/bridge/adv7511/adv7511_drv.c b/drivers/gpu/drm/bridge/adv7511/adv7511_drv.c
+index a104b43b56a0..8be1baca05d0 100644
+--- a/drivers/gpu/drm/bridge/adv7511/adv7511_drv.c
++++ b/drivers/gpu/drm/bridge/adv7511/adv7511_drv.c
+@@ -838,7 +838,11 @@ static int adv7511_bridge_attach(struct drm_bridge *bridge)
+ return -ENODEV;
+ }
+
+- adv->connector.polled = DRM_CONNECTOR_POLL_HPD;
++ if (adv->i2c_main->irq)
++ adv->connector.polled = DRM_CONNECTOR_POLL_HPD;
++ else
++ adv->connector.polled = DRM_CONNECTOR_POLL_CONNECT |
++ DRM_CONNECTOR_POLL_DISCONNECT;
+
+ ret = drm_connector_init(bridge->dev, &adv->connector,
+ &adv7511_connector_funcs,
+--
+2.13.0
+
diff --git a/bsp/meta-rcar/meta-rcar-gen3-adas/recipes-kernel/linux/linux-renesas/0027-gpu-drm-bridge-adv7511-Add-interlaced-mode-support.patch b/bsp/meta-rcar/meta-rcar-gen3-adas/recipes-kernel/linux/linux-renesas/0027-gpu-drm-bridge-adv7511-Add-interlaced-mode-support.patch
new file mode 100644
index 00000000..01983096
--- /dev/null
+++ b/bsp/meta-rcar/meta-rcar-gen3-adas/recipes-kernel/linux/linux-renesas/0027-gpu-drm-bridge-adv7511-Add-interlaced-mode-support.patch
@@ -0,0 +1,44 @@
+From bf8408f6e06e4d6e80940d0c8e08f7e8da330de7 Mon Sep 17 00:00:00 2001
+From: Valentine Barshak <valentine.barshak@cogentembedded.com>
+Date: Wed, 21 Mar 2018 20:48:02 +0300
+Subject: [PATCH 021/122] gpu: drm: bridge: adv7511: Add interlaced mode
+ support
+
+This adds "interlace-allowed" DTS property
+that allows interlaced mode support when set.
+
+Signed-off-by: Valentine Barshak <valentine.barshak@cogentembedded.com>
+---
+ Documentation/devicetree/bindings/display/bridge/adi,adv7511.txt | 1 +
+ drivers/gpu/drm/bridge/adv7511/adv7511_drv.c | 3 +++
+ 2 files changed, 4 insertions(+)
+
+diff --git a/Documentation/devicetree/bindings/display/bridge/adi,adv7511.txt b/Documentation/devicetree/bindings/display/bridge/adi,adv7511.txt
+index 06668bc..e0a2360 100644
+--- a/Documentation/devicetree/bindings/display/bridge/adi,adv7511.txt
++++ b/Documentation/devicetree/bindings/display/bridge/adi,adv7511.txt
+@@ -60,6 +60,7 @@ Optional properties:
+ - interrupts: Specifier for the ADV7511 interrupt
+ - pd-gpios: Specifier for the GPIO connected to the power down signal
+
++- interlace-allowed - Allows interlaced modes when set.
+ - adi,clock-delay: Video data clock delay relative to the pixel clock, in ps
+ (-1200 ps .. 1600 ps). Defaults to no delay.
+ - adi,embedded-sync: The input uses synchronization signals embedded in the
+diff --git a/drivers/gpu/drm/bridge/adv7511/adv7511_drv.c b/drivers/gpu/drm/bridge/adv7511/adv7511_drv.c
+index 69f605b..808021f 100644
+--- a/drivers/gpu/drm/bridge/adv7511/adv7511_drv.c
++++ b/drivers/gpu/drm/bridge/adv7511/adv7511_drv.c
+@@ -863,6 +863,9 @@ static int adv7511_bridge_attach(struct drm_bridge *bridge)
+ adv->connector.polled = DRM_CONNECTOR_POLL_CONNECT |
+ DRM_CONNECTOR_POLL_DISCONNECT;
+
++ adv->connector.interlace_allowed =
++ of_property_read_bool(bridge->of_node, "interlace-allowed");
++
+ ret = drm_connector_init(bridge->dev, &adv->connector,
+ &adv7511_connector_funcs,
+ DRM_MODE_CONNECTOR_HDMIA);
+--
+2.7.4
+
diff --git a/bsp/meta-rcar/meta-rcar-gen3-adas/recipes-kernel/linux/linux-renesas/0030-Gen3-LVDS-cameras.patch b/bsp/meta-rcar/meta-rcar-gen3-adas/recipes-kernel/linux/linux-renesas/0030-Gen3-LVDS-cameras.patch
new file mode 100644
index 00000000..3a3026b5
--- /dev/null
+++ b/bsp/meta-rcar/meta-rcar-gen3-adas/recipes-kernel/linux/linux-renesas/0030-Gen3-LVDS-cameras.patch
@@ -0,0 +1,11563 @@
+From ea57c63245c9f3e05b0981ac5ee621f37e52dc35 Mon Sep 17 00:00:00 2001
+From: Vladimir Barinov <vladimir.barinov@cogentembedded.com>
+Date: Sun, 14 May 2017 15:20:01 +0300
+Subject: [PATCH 022/122] Gen3: LVDS cameras
+
+This add Gen3 LVDS cameras support:
+- deserializers: MAX9286, DS90UB954/960/964
+- cameras: ov10635, ov490+ov10640, ov495+OV2775, ar0132, ar0220,
+ ap0101+ar014x, ov2775
+
+Signed-off-by: Vladimir Barinov <vladimir.barinov@cogentembedded.com>
+---
+ drivers/media/i2c/soc_camera/Kconfig | 18 +
+ drivers/media/i2c/soc_camera/Makefile | 4 +
+ drivers/media/i2c/soc_camera/ap0101_ar014x.c | 589 +++++++
+ drivers/media/i2c/soc_camera/ap0101_ar014x.h | 28 +
+ drivers/media/i2c/soc_camera/ar0132.c | 566 +++++++
+ drivers/media/i2c/soc_camera/ar0132.h | 213 +++
+ drivers/media/i2c/soc_camera/ar0220.c | 532 +++++++
+ drivers/media/i2c/soc_camera/ar0220.h | 43 +
+ drivers/media/i2c/soc_camera/max9286.c | 694 ++++++++
+ drivers/media/i2c/soc_camera/max9286.h | 244 +++
+ drivers/media/i2c/soc_camera/ov10635.c | 760 +++++++++
+ drivers/media/i2c/soc_camera/ov10635.h | 1139 +++++++++++++
+ drivers/media/i2c/soc_camera/ov10635_debug.h | 54 +
+ drivers/media/i2c/soc_camera/ov106xx.c | 139 ++
+ drivers/media/i2c/soc_camera/ov2775.c | 528 +++++++
+ drivers/media/i2c/soc_camera/ov2775.h | 1841 ++++++++++++++++++++++
+ drivers/media/i2c/soc_camera/ov490_ov10640.c | 1134 +++++++++++++
+ drivers/media/i2c/soc_camera/ov490_ov10640.h | 102 ++
+ drivers/media/i2c/soc_camera/ov495_ov2775.c | 640 ++++++++
+ drivers/media/i2c/soc_camera/ov495_ov2775.h | 23 +
+ drivers/media/i2c/soc_camera/ti9x4.c | 520 ++++++
+ drivers/media/i2c/soc_camera/ti9x4.h | 156 ++
+ drivers/media/platform/soc_camera/rcar_csi2.c | 330 ++--
+ drivers/media/platform/soc_camera/rcar_vin.c | 309 +++-
+ drivers/media/platform/soc_camera/soc_camera.c | 17 +-
+ drivers/media/platform/soc_camera/soc_mediabus.c | 16 +
+ drivers/media/v4l2-core/v4l2-async.c | 2 +
+ include/media/drv-intf/soc_mediabus.h | 3 +
+ include/media/soc_camera.h | 1 +
+ 29 files changed, 10512 insertions(+), 133 deletions(-)
+ create mode 100644 drivers/media/i2c/soc_camera/ap0101_ar014x.c
+ create mode 100644 drivers/media/i2c/soc_camera/ap0101_ar014x.h
+ create mode 100644 drivers/media/i2c/soc_camera/ar0132.c
+ create mode 100644 drivers/media/i2c/soc_camera/ar0132.h
+ create mode 100644 drivers/media/i2c/soc_camera/ar0220.c
+ create mode 100644 drivers/media/i2c/soc_camera/ar0220.h
+ create mode 100644 drivers/media/i2c/soc_camera/max9286.c
+ create mode 100644 drivers/media/i2c/soc_camera/max9286.h
+ create mode 100644 drivers/media/i2c/soc_camera/ov10635.c
+ create mode 100644 drivers/media/i2c/soc_camera/ov10635.h
+ create mode 100644 drivers/media/i2c/soc_camera/ov10635_debug.h
+ create mode 100644 drivers/media/i2c/soc_camera/ov106xx.c
+ create mode 100644 drivers/media/i2c/soc_camera/ov2775.c
+ create mode 100644 drivers/media/i2c/soc_camera/ov2775.h
+ create mode 100644 drivers/media/i2c/soc_camera/ov490_ov10640.c
+ create mode 100644 drivers/media/i2c/soc_camera/ov490_ov10640.h
+ create mode 100644 drivers/media/i2c/soc_camera/ov495_ov2775.c
+ create mode 100644 drivers/media/i2c/soc_camera/ov495_ov2775.h
+ create mode 100644 drivers/media/i2c/soc_camera/ti9x4.c
+ create mode 100644 drivers/media/i2c/soc_camera/ti9x4.h
+
+diff --git a/drivers/media/i2c/soc_camera/Kconfig b/drivers/media/i2c/soc_camera/Kconfig
+index 72b3698..d30a3f9 100644
+--- a/drivers/media/i2c/soc_camera/Kconfig
++++ b/drivers/media/i2c/soc_camera/Kconfig
+@@ -76,3 +76,21 @@ config SOC_CAMERA_TW9910
+ depends on SOC_CAMERA && I2C
+ help
+ This is a tw9910 video driver
++
++config SOC_CAMERA_MAX9286
++ tristate "max9286 GMSL support"
++ depends on SOC_CAMERA && I2C
++ help
++ This is a MAXIM max9286 GMSL driver
++
++config SOC_CAMERA_TI9X4
++ tristate "ti9x4 FPDLink3 support"
++ depends on SOC_CAMERA && I2C
++ help
++ This is an Texas Instruments ti9X4 FPDLink3 driver
++
++config SOC_CAMERA_OV106XX
++ tristate "ov106xx camera support"
++ depends on SOC_CAMERA && I2C
++ help
++ This is a runtime detected GMSL/FPDLink3 sensors driver
+diff --git a/drivers/media/i2c/soc_camera/Makefile b/drivers/media/i2c/soc_camera/Makefile
+index faa2df8..1134c03 100644
+--- a/drivers/media/i2c/soc_camera/Makefile
++++ b/drivers/media/i2c/soc_camera/Makefile
+@@ -10,3 +10,7 @@ obj-$(CONFIG_SOC_CAMERA_OV9640) += ov9640.o
+ obj-$(CONFIG_SOC_CAMERA_OV9740) += ov9740.o
+ obj-$(CONFIG_SOC_CAMERA_RJ54N1) += rj54n1cb0c.o
+ obj-$(CONFIG_SOC_CAMERA_TW9910) += tw9910.o
++obj-$(CONFIG_SOC_CAMERA_MAX9286) += max9286.o
++obj-$(CONFIG_SOC_CAMERA_TI9X4) += ti9x4.o
++obj-$(CONFIG_SOC_CAMERA_OV106XX) += ov106xx.o
++
+diff --git a/drivers/media/i2c/soc_camera/ap0101_ar014x.c b/drivers/media/i2c/soc_camera/ap0101_ar014x.c
+new file mode 100644
+index 0000000..cae0b19
+--- /dev/null
++++ b/drivers/media/i2c/soc_camera/ap0101_ar014x.c
+@@ -0,0 +1,589 @@
++/*
++ * ON Semiconductor AP0101-AR014X sensor camera driver
++ *
++ * Copyright (C) 2018 Cogent Embedded, Inc.
++ *
++ * This program is free software; you can redistribute it and/or modify it
++ * under the terms of the GNU General Public License as published by the
++ * Free Software Foundation; either version 2 of the License, or (at your
++ * option) any later version.
++ */
++
++#include <linux/delay.h>
++#include <linux/init.h>
++#include <linux/i2c.h>
++#include <linux/module.h>
++#include <linux/of_graph.h>
++#include <linux/videodev2.h>
++
++#include <media/soc_camera.h>
++#include <media/v4l2-common.h>
++#include <media/v4l2-ctrls.h>
++#include <media/v4l2-fwnode.h>
++
++#include "ap0101_ar014x.h"
++
++#define AP0101_I2C_ADDR 0x5d
++
++#define AP0101_PID 0x0000
++#define AP0101_VERSION_REG 0x0160
++
++#define AP0101_MEDIA_BUS_FMT MEDIA_BUS_FMT_YUYV8_2X8
++
++static void ap0101_otp_id_read(struct i2c_client *client);
++
++struct ap0101_priv {
++ struct v4l2_subdev sd;
++ struct v4l2_ctrl_handler hdl;
++ struct media_pad pad;
++ struct v4l2_rect rect;
++ int init_complete;
++ u8 id[6];
++ int exposure;
++ int gain;
++ int autogain;
++ /* serializers */
++ int max9286_addr;
++ int max9271_addr;
++ int port;
++ int gpio_resetb;
++ int gpio_fsin;
++};
++
++static inline struct ap0101_priv *to_ap0101(const struct i2c_client *client)
++{
++ return container_of(i2c_get_clientdata(client), struct ap0101_priv, sd);
++}
++
++static void ap0101_s_port(struct i2c_client *client, int fwd_en)
++{
++ struct ap0101_priv *priv = to_ap0101(client);
++ int tmp_addr;
++
++ if (priv->max9286_addr) {
++ tmp_addr = client->addr;
++ client->addr = priv->max9286_addr; /* Deserializer I2C address */
++ reg8_write(client, 0x0a, fwd_en ? 0x11 << priv->port : 0); /* Enable/disable reverse/forward control for this port */
++ usleep_range(5000, 5500); /* wait 5ms */
++ client->addr = tmp_addr;
++ };
++}
++
++static int ap0101_set_regs(struct i2c_client *client,
++ const struct ap0101_reg *regs, int nr_regs)
++{
++ int i;
++
++ for (i = 0; i < nr_regs; i++) {
++ if (regs[i].reg == AP0101_DELAY) {
++ mdelay(regs[i].val);
++ continue;
++ }
++
++ reg16_write16(client, regs[i].reg, regs[i].val);
++ }
++
++ return 0;
++}
++
++static u16 ap0101_ar014x_read(struct i2c_client *client, u16 addr)
++{
++ u16 reg_val = 0;
++
++ reg16_write16(client, 0x0040, 0x8d00);
++ usleep_range(100, 150); /* wait 100 us */
++ reg16_write16(client, 0xfc00, addr);
++ reg16_write16(client, 0xfc02, 0x0200); /* 2 bytes */
++ reg16_write16(client, 0x0040, 0x8d05);
++ usleep_range(100, 150); /* wait 100 us */
++ reg16_write16(client, 0x0040, 0x8d08);
++ usleep_range(100, 150); /* wait 100 us */
++ reg16_read16(client, 0xfc00, &reg_val);
++ reg16_write16(client, 0x0040, 0x8d02);
++ usleep_range(100, 150); /* wait 100 us */
++
++ return reg_val;
++}
++
++static void ap0101_ar014x_write(struct i2c_client *client, u16 addr, u16 val)
++{
++ reg16_write16(client, 0x0040, 0x8d00);
++ usleep_range(100, 150); /* wait 100 us */
++ reg16_write16(client, 0xfc00, addr);
++ reg16_write16(client, 0xfc02, 0x0200 | (val >> 8)); /* 2 bytes */
++ reg16_write16(client, 0xfc04, (val & 0xff) << 8);
++ reg16_write16(client, 0x0040, 0x8d06);
++ usleep_range(100, 150); /* wait 100 us */
++ reg16_write16(client, 0x0040, 0x8d08);
++ usleep_range(100, 150); /* wait 100 us */
++ reg16_write16(client, 0x0040, 0x8d02);
++ usleep_range(100, 150); /* wait 100 us */
++}
++
++static int ap0101_s_stream(struct v4l2_subdev *sd, int enable)
++{
++ return 0;
++}
++
++static int ap0101_get_fmt(struct v4l2_subdev *sd,
++ struct v4l2_subdev_pad_config *cfg,
++ struct v4l2_subdev_format *format)
++{
++ struct v4l2_mbus_framefmt *mf = &format->format;
++ struct i2c_client *client = v4l2_get_subdevdata(sd);
++ struct ap0101_priv *priv = to_ap0101(client);
++
++ if (format->pad)
++ return -EINVAL;
++
++ mf->width = priv->rect.width;
++ mf->height = priv->rect.height;
++ mf->code = AP0101_MEDIA_BUS_FMT;
++ mf->colorspace = V4L2_COLORSPACE_SMPTE170M;
++ mf->field = V4L2_FIELD_NONE;
++
++ return 0;
++}
++
++static int ap0101_set_fmt(struct v4l2_subdev *sd,
++ struct v4l2_subdev_pad_config *cfg,
++ struct v4l2_subdev_format *format)
++{
++ struct v4l2_mbus_framefmt *mf = &format->format;
++
++ mf->code = AP0101_MEDIA_BUS_FMT;
++ mf->colorspace = V4L2_COLORSPACE_SMPTE170M;
++ mf->field = V4L2_FIELD_NONE;
++
++ if (format->which == V4L2_SUBDEV_FORMAT_TRY)
++ cfg->try_fmt = *mf;
++
++ return 0;
++}
++
++static int ap0101_enum_mbus_code(struct v4l2_subdev *sd,
++ struct v4l2_subdev_pad_config *cfg,
++ struct v4l2_subdev_mbus_code_enum *code)
++{
++ if (code->pad || code->index > 0)
++ return -EINVAL;
++
++ code->code = AP0101_MEDIA_BUS_FMT;
++
++ return 0;
++}
++
++static int ap0101_get_edid(struct v4l2_subdev *sd, struct v4l2_edid *edid)
++{
++ struct i2c_client *client = v4l2_get_subdevdata(sd);
++ struct ap0101_priv *priv = to_ap0101(client);
++
++ ap0101_otp_id_read(client);
++
++ memcpy(edid->edid, priv->id, 6);
++
++ edid->edid[6] = 0xff;
++ edid->edid[7] = client->addr;
++ edid->edid[8] = AP0101_VERSION_REG >> 8;
++ edid->edid[9] = AP0101_VERSION_REG & 0xff;
++
++ return 0;
++}
++
++static int ap0101_set_selection(struct v4l2_subdev *sd,
++ struct v4l2_subdev_pad_config *cfg,
++ struct v4l2_subdev_selection *sel)
++{
++ struct v4l2_rect *rect = &sel->r;
++ struct i2c_client *client = v4l2_get_subdevdata(sd);
++ struct ap0101_priv *priv = to_ap0101(client);
++
++ if (sel->which != V4L2_SUBDEV_FORMAT_ACTIVE ||
++ sel->target != V4L2_SEL_TGT_CROP)
++ return -EINVAL;
++
++ rect->left = ALIGN(rect->left, 2);
++ rect->top = ALIGN(rect->top, 2);
++ rect->width = ALIGN(rect->width, 2);
++ rect->height = ALIGN(rect->height, 2);
++
++ if ((rect->left + rect->width > AP0101_MAX_WIDTH) ||
++ (rect->top + rect->height > AP0101_MAX_HEIGHT))
++ *rect = priv->rect;
++
++ priv->rect.left = rect->left;
++ priv->rect.top = rect->top;
++ priv->rect.width = rect->width;
++ priv->rect.height = rect->height;
++
++ return 0;
++}
++
++static int ap0101_get_selection(struct v4l2_subdev *sd,
++ struct v4l2_subdev_pad_config *cfg,
++ struct v4l2_subdev_selection *sel)
++{
++ struct i2c_client *client = v4l2_get_subdevdata(sd);
++ struct ap0101_priv *priv = to_ap0101(client);
++
++ if (sel->which != V4L2_SUBDEV_FORMAT_ACTIVE)
++ return -EINVAL;
++
++ switch (sel->target) {
++ case V4L2_SEL_TGT_CROP_BOUNDS:
++ sel->r.left = 0;
++ sel->r.top = 0;
++ sel->r.width = AP0101_MAX_WIDTH;
++ sel->r.height = AP0101_MAX_HEIGHT;
++ return 0;
++ case V4L2_SEL_TGT_CROP_DEFAULT:
++ sel->r.left = 0;
++ sel->r.top = 0;
++ sel->r.width = AP0101_MAX_WIDTH;
++ sel->r.height = AP0101_MAX_HEIGHT;
++ return 0;
++ case V4L2_SEL_TGT_CROP:
++ sel->r = priv->rect;
++ return 0;
++ default:
++ return -EINVAL;
++ }
++}
++
++static int ap0101_g_mbus_config(struct v4l2_subdev *sd,
++ struct v4l2_mbus_config *cfg)
++{
++ cfg->flags = V4L2_MBUS_CSI2_1_LANE | V4L2_MBUS_CSI2_CHANNEL_0 |
++ V4L2_MBUS_CSI2_CONTINUOUS_CLOCK;
++ cfg->type = V4L2_MBUS_CSI2;
++
++ return 0;
++}
++
++#ifdef CONFIG_VIDEO_ADV_DEBUG
++static int ap0101_g_register(struct v4l2_subdev *sd,
++ struct v4l2_dbg_register *reg)
++{
++ struct i2c_client *client = v4l2_get_subdevdata(sd);
++ int ret;
++ u16 val = 0;
++
++ ret = reg16_read16(client, (u16)reg->reg, &val);
++ if (ret < 0)
++ return ret;
++
++ reg->val = val;
++ reg->size = sizeof(u16);
++
++ return 0;
++}
++
++static int ap0101_s_register(struct v4l2_subdev *sd,
++ const struct v4l2_dbg_register *reg)
++{
++ struct i2c_client *client = v4l2_get_subdevdata(sd);
++
++ return reg16_write16(client, (u16)reg->reg, (u16)reg->val);
++}
++#endif
++
++static struct v4l2_subdev_core_ops ap0101_core_ops = {
++#ifdef CONFIG_VIDEO_ADV_DEBUG
++ .g_register = ap0101_g_register,
++ .s_register = ap0101_s_register,
++#endif
++};
++
++static int ap0101_s_ctrl(struct v4l2_ctrl *ctrl)
++{
++ struct v4l2_subdev *sd = to_sd(ctrl);
++ struct i2c_client *client = v4l2_get_subdevdata(sd);
++ struct ap0101_priv *priv = to_ap0101(client);
++ int ret = -EINVAL;
++
++ if (!priv->init_complete)
++ return 0;
++
++ switch (ctrl->id) {
++ case V4L2_CID_BRIGHTNESS:
++ case V4L2_CID_CONTRAST:
++ case V4L2_CID_SATURATION:
++ case V4L2_CID_HUE:
++ case V4L2_CID_GAMMA:
++ case V4L2_CID_SHARPNESS:
++ case V4L2_CID_AUTOGAIN:
++ case V4L2_CID_GAIN:
++ case V4L2_CID_EXPOSURE:
++ case V4L2_CID_HFLIP:
++ case V4L2_CID_VFLIP:
++ break;
++ }
++
++ return ret;
++}
++
++static const struct v4l2_ctrl_ops ap0101_ctrl_ops = {
++ .s_ctrl = ap0101_s_ctrl,
++};
++
++static struct v4l2_subdev_video_ops ap0101_video_ops = {
++ .s_stream = ap0101_s_stream,
++ .g_mbus_config = ap0101_g_mbus_config,
++};
++
++static const struct v4l2_subdev_pad_ops ap0101_subdev_pad_ops = {
++ .get_edid = ap0101_get_edid,
++ .enum_mbus_code = ap0101_enum_mbus_code,
++ .get_selection = ap0101_get_selection,
++ .set_selection = ap0101_set_selection,
++ .get_fmt = ap0101_get_fmt,
++ .set_fmt = ap0101_set_fmt,
++};
++
++static struct v4l2_subdev_ops ap0101_subdev_ops = {
++ .core = &ap0101_core_ops,
++ .video = &ap0101_video_ops,
++ .pad = &ap0101_subdev_pad_ops,
++};
++
++static void ap0101_otp_id_read(struct i2c_client *client)
++{
++ struct ap0101_priv *priv = to_ap0101(client);
++ int i;
++
++ /* read camera id from ar014x OTP memory */
++ ap0101_ar014x_write(client, 0x3054, 0x400);
++ ap0101_ar014x_write(client, 0x304a, 0x110);
++ usleep_range(25000, 25500); /* wait 25 ms */
++
++ for (i = 0; i < 6; i += 2) {
++ /* first 4 bytes are equal on all ar014x */
++ priv->id[i] = ap0101_ar014x_read(client, 0x3800 + i + 4) >> 8;
++ priv->id[i + 1] = ap0101_ar014x_read(client, 0x3800 + i + 4) & 0xff;
++ }
++}
++
++static ssize_t ap0101_otp_id_show(struct device *dev,
++ struct device_attribute *attr, char *buf)
++{
++ struct v4l2_subdev *sd = i2c_get_clientdata(to_i2c_client(dev));
++ struct i2c_client *client = v4l2_get_subdevdata(sd);
++ struct ap0101_priv *priv = to_ap0101(client);
++
++ ap0101_otp_id_read(client);
++
++ return snprintf(buf, 32, "%02x:%02x:%02x:%02x:%02x:%02x\n",
++ priv->id[0], priv->id[1], priv->id[2], priv->id[3], priv->id[4], priv->id[5]);
++}
++
++static DEVICE_ATTR(otp_id_ap0101, S_IRUGO, ap0101_otp_id_show, NULL);
++
++static int ap0101_initialize(struct i2c_client *client)
++{
++ struct ap0101_priv *priv = to_ap0101(client);
++ u16 pid = 0;
++ int ret = 0;
++
++ ap0101_s_port(client, 1);
++
++ /* check and show model ID */
++ reg16_read16(client, AP0101_PID, &pid);
++
++ if (pid != AP0101_VERSION_REG) {
++ dev_dbg(&client->dev, "Product ID error %x\n", pid);
++ ret = -ENODEV;
++ goto err;
++ }
++
++ /* Program wizard registers */
++ ap0101_set_regs(client, ap0101_regs_wizard, ARRAY_SIZE(ap0101_regs_wizard));
++ /* Read OTP IDs */
++ ap0101_otp_id_read(client);
++
++ dev_info(&client->dev, "ap0101 PID %x, res %dx%d, OTP_ID %02x:%02x:%02x:%02x:%02x:%02x\n",
++ pid, AP0101_MAX_WIDTH, AP0101_MAX_HEIGHT, priv->id[0], priv->id[1], priv->id[2], priv->id[3], priv->id[4], priv->id[5]);
++err:
++ ap0101_s_port(client, 0);
++
++ return ret;
++}
++
++static int ap0101_parse_dt(struct device_node *np, struct ap0101_priv *priv)
++{
++ struct i2c_client *client = v4l2_get_subdevdata(&priv->sd);
++ int i;
++ struct device_node *endpoint = NULL, *rendpoint = NULL;
++ int tmp_addr = 0;
++
++ for (i = 0; ; i++) {
++ endpoint = of_graph_get_next_endpoint(np, endpoint);
++ if (!endpoint)
++ break;
++
++ of_node_put(endpoint);
++
++ rendpoint = of_parse_phandle(endpoint, "remote-endpoint", 0);
++ if (!rendpoint)
++ continue;
++
++ if (!of_property_read_u32(rendpoint, "max9271-addr", &priv->max9271_addr) &&
++ !of_property_read_u32(rendpoint->parent->parent, "reg", &priv->max9286_addr) &&
++ !kstrtouint(strrchr(rendpoint->full_name, '@') + 1, 0, &priv->port))
++ break;
++ }
++
++ if (!priv->max9286_addr) {
++ dev_err(&client->dev, "deserializer does not present for AP0101\n");
++ return -EINVAL;
++ }
++
++ ap0101_s_port(client, 1);
++
++ /* setup I2C translator address */
++ tmp_addr = client->addr;
++ if (priv->max9286_addr) {
++ client->addr = priv->max9271_addr; /* Serializer I2C address */
++
++ reg8_write(client, 0x09, tmp_addr << 1); /* Sensor translated I2C address */
++ reg8_write(client, 0x0A, AP0101_I2C_ADDR << 1); /* Sensor native I2C address */
++ usleep_range(2000, 2500); /* wait 2ms */
++ };
++ client->addr = tmp_addr;
++
++ mdelay(10);
++
++ return 0;
++}
++
++static int ap0101_probe(struct i2c_client *client,
++ const struct i2c_device_id *did)
++{
++ struct ap0101_priv *priv;
++ int ret;
++
++ priv = devm_kzalloc(&client->dev, sizeof(*priv), GFP_KERNEL);
++ if (!priv)
++ return -ENOMEM;
++
++ v4l2_i2c_subdev_init(&priv->sd, client, &ap0101_subdev_ops);
++ priv->sd.flags = V4L2_SUBDEV_FL_HAS_DEVNODE;
++
++ priv->exposure = 0x100;
++ priv->gain = 0x100;
++ priv->autogain = 1;
++ v4l2_ctrl_handler_init(&priv->hdl, 4);
++ v4l2_ctrl_new_std(&priv->hdl, &ap0101_ctrl_ops,
++ V4L2_CID_BRIGHTNESS, 0, 16, 1, 7);
++ v4l2_ctrl_new_std(&priv->hdl, &ap0101_ctrl_ops,
++ V4L2_CID_CONTRAST, 0, 16, 1, 7);
++ v4l2_ctrl_new_std(&priv->hdl, &ap0101_ctrl_ops,
++ V4L2_CID_SATURATION, 0, 7, 1, 2);
++ v4l2_ctrl_new_std(&priv->hdl, &ap0101_ctrl_ops,
++ V4L2_CID_HUE, 0, 23, 1, 12);
++ v4l2_ctrl_new_std(&priv->hdl, &ap0101_ctrl_ops,
++ V4L2_CID_GAMMA, -128, 128, 1, 0);
++ v4l2_ctrl_new_std(&priv->hdl, &ap0101_ctrl_ops,
++ V4L2_CID_SHARPNESS, 0, 10, 1, 3);
++ v4l2_ctrl_new_std(&priv->hdl, &ap0101_ctrl_ops,
++ V4L2_CID_AUTOGAIN, 0, 1, 1, priv->autogain);
++ v4l2_ctrl_new_std(&priv->hdl, &ap0101_ctrl_ops,
++ V4L2_CID_GAIN, 0, 0xffff, 1, priv->gain);
++ v4l2_ctrl_new_std(&priv->hdl, &ap0101_ctrl_ops,
++ V4L2_CID_EXPOSURE, 0, 0xffff, 1, priv->exposure);
++ v4l2_ctrl_new_std(&priv->hdl, &ap0101_ctrl_ops,
++ V4L2_CID_HFLIP, 0, 1, 1, 1);
++ v4l2_ctrl_new_std(&priv->hdl, &ap0101_ctrl_ops,
++ V4L2_CID_VFLIP, 0, 1, 1, 0);
++ priv->sd.ctrl_handler = &priv->hdl;
++
++ ret = priv->hdl.error;
++ if (ret)
++ goto cleanup;
++
++ v4l2_ctrl_handler_setup(&priv->hdl);
++
++ priv->pad.flags = MEDIA_PAD_FL_SOURCE;
++ priv->sd.entity.flags |= MEDIA_ENT_F_CAM_SENSOR;
++ ret = media_entity_pads_init(&priv->sd.entity, 1, &priv->pad);
++ if (ret < 0)
++ goto cleanup;
++
++ ret = ap0101_parse_dt(client->dev.of_node, priv);
++ if (ret)
++ goto cleanup;
++
++ ret = ap0101_initialize(client);
++ if (ret < 0)
++ goto cleanup;
++
++ priv->rect.left = 0;
++ priv->rect.top = 0;
++ priv->rect.width = AP0101_MAX_WIDTH;
++ priv->rect.height = AP0101_MAX_HEIGHT;
++
++ ret = v4l2_async_register_subdev(&priv->sd);
++ if (ret)
++ goto cleanup;
++
++ if (device_create_file(&client->dev, &dev_attr_otp_id_ap0101) != 0) {
++ dev_err(&client->dev, "sysfs otp_id entry creation failed\n");
++ goto cleanup;
++ }
++
++ priv->init_complete = 1;
++
++ return 0;
++
++cleanup:
++ media_entity_cleanup(&priv->sd.entity);
++ v4l2_ctrl_handler_free(&priv->hdl);
++ v4l2_device_unregister_subdev(&priv->sd);
++#ifdef CONFIG_SOC_CAMERA_AP0101
++ v4l_err(client, "failed to probe @ 0x%02x (%s)\n",
++ client->addr, client->adapter->name);
++#endif
++ return ret;
++}
++
++static int ap0101_remove(struct i2c_client *client)
++{
++ struct ap0101_priv *priv = i2c_get_clientdata(client);
++
++ device_remove_file(&client->dev, &dev_attr_otp_id_ap0101);
++ v4l2_async_unregister_subdev(&priv->sd);
++ media_entity_cleanup(&priv->sd.entity);
++ v4l2_ctrl_handler_free(&priv->hdl);
++ v4l2_device_unregister_subdev(&priv->sd);
++
++ return 0;
++}
++
++#ifdef CONFIG_SOC_CAMERA_AP0101
++static const struct i2c_device_id ap0101_id[] = {
++ { "ap0101", 0 },
++ { }
++};
++MODULE_DEVICE_TABLE(i2c, ap0101_id);
++
++static const struct of_device_id ap0101_of_ids[] = {
++ { .compatible = "aptina,ap0101", },
++ { }
++};
++MODULE_DEVICE_TABLE(of, ap0101_of_ids);
++
++static struct i2c_driver ap0101_i2c_driver = {
++ .driver = {
++ .name = "ap0101",
++ .of_match_table = ap0101_of_ids,
++ },
++ .probe = ap0101_probe,
++ .remove = ap0101_remove,
++ .id_table = ap0101_id,
++};
++
++module_i2c_driver(ap0101_i2c_driver);
++
++MODULE_DESCRIPTION("SoC Camera driver for AP0101");
++MODULE_AUTHOR("Vladimir Barinov");
++MODULE_LICENSE("GPL");
++#endif
+diff --git a/drivers/media/i2c/soc_camera/ap0101_ar014x.h b/drivers/media/i2c/soc_camera/ap0101_ar014x.h
+new file mode 100644
+index 0000000..16599a1
+--- /dev/null
++++ b/drivers/media/i2c/soc_camera/ap0101_ar014x.h
+@@ -0,0 +1,28 @@
++/*
++ * ON Semiconductor ap0101-ar014x sensor camera wizard 1280x720@30/UYVY/BT601/8bit
++ *
++ * Copyright (C) 2018 Cogent Embedded, Inc.
++ *
++ * This program is free software; you can redistribute it and/or modify it
++ * under the terms of the GNU General Public License as published by the
++ * Free Software Foundation; either version 2 of the License, or (at your
++ * option) any later version.
++ */
++
++#define AP0101_MAX_WIDTH 1280
++#define AP0101_MAX_HEIGHT 720
++
++#define AP0101_DELAY 0xffff
++
++struct ap0101_reg {
++ u16 reg;
++ u16 val;
++};
++
++static const struct ap0101_reg ap0101_regs_wizard[] = {
++/* enable FSIN */
++{0xc88c, 0x0303},
++{0xfc00, 0x2800},
++{0x0040, 0x8100},
++{AP0101_DELAY, 100},
++};
+diff --git a/drivers/media/i2c/soc_camera/ar0132.c b/drivers/media/i2c/soc_camera/ar0132.c
+new file mode 100644
+index 0000000..a7ee868
+--- /dev/null
++++ b/drivers/media/i2c/soc_camera/ar0132.c
+@@ -0,0 +1,566 @@
++/*
++ * ON Semiconductor AR0132 sensor camera driver
++ *
++ * Copyright (C) 2017 Cogent Embedded, Inc.
++ *
++ * This program is free software; you can redistribute it and/or modify it
++ * under the terms of the GNU General Public License as published by the
++ * Free Software Foundation; either version 2 of the License, or (at your
++ * option) any later version.
++ */
++
++#include <linux/delay.h>
++#include <linux/init.h>
++#include <linux/i2c.h>
++#include <linux/module.h>
++#include <linux/of_graph.h>
++#include <linux/videodev2.h>
++
++#include <media/soc_camera.h>
++#include <media/v4l2-common.h>
++#include <media/v4l2-ctrls.h>
++#include <media/v4l2-fwnode.h>
++
++#include "ar0132.h"
++
++#define AR0132_I2C_ADDR 0x18
++//#define AR0132_I2C_ADDR 0x50 // eeprom
++
++#define AR0132_PID 0x3000
++#define AR0132_VERSION_REG 0x2400
++
++#define AR0132_MEDIA_BUS_FMT MEDIA_BUS_FMT_SBGGR12_1X12
++
++struct ar0132_priv {
++ struct v4l2_subdev sd;
++ struct v4l2_ctrl_handler hdl;
++ struct media_pad pad;
++ struct v4l2_rect rect;
++ int init_complete;
++ u8 id[6];
++ int exposure;
++ int gain;
++ int autogain;
++ int dvp_order;
++ /* serializers */
++ int max9286_addr;
++ int max9271_addr;
++ int ti9x4_addr;
++ int ti9x3_addr;
++ int port;
++ int gpio_resetb;
++ int gpio_fsin;
++
++};
++
++static inline struct ar0132_priv *to_ar0132(const struct i2c_client *client)
++{
++ return container_of(i2c_get_clientdata(client), struct ar0132_priv, sd);
++}
++
++static void ar0132_s_port(struct i2c_client *client, int fwd_en)
++{
++ struct ar0132_priv *priv = to_ar0132(client);
++ int tmp_addr;
++
++ if (priv->max9286_addr) {
++ tmp_addr = client->addr;
++ client->addr = priv->max9286_addr; /* Deserializer I2C address */
++ reg8_write(client, 0x0a, fwd_en ? 0x11 << priv->port : 0); /* Enable/disable reverse/forward control for this port */
++ usleep_range(5000, 5500); /* wait 5ms */
++ client->addr = tmp_addr;
++ };
++}
++
++static int ar0132_set_regs(struct i2c_client *client,
++ const struct ar0132_reg *regs, int nr_regs)
++{
++ int i;
++
++ for (i = 0; i < nr_regs; i++) {
++ if (regs[i].reg == AR0132_DELAY) {
++ mdelay(regs[i].val);
++ continue;
++ }
++
++ reg16_write16(client, regs[i].reg, regs[i].val);
++ }
++
++ return 0;
++}
++
++static int ar0132_s_stream(struct v4l2_subdev *sd, int enable)
++{
++ return 0;
++}
++
++static int ar0132_get_fmt(struct v4l2_subdev *sd,
++ struct v4l2_subdev_pad_config *cfg,
++ struct v4l2_subdev_format *format)
++{
++ struct v4l2_mbus_framefmt *mf = &format->format;
++ struct i2c_client *client = v4l2_get_subdevdata(sd);
++ struct ar0132_priv *priv = to_ar0132(client);
++
++ if (format->pad)
++ return -EINVAL;
++
++ mf->width = priv->rect.width;
++ mf->height = priv->rect.height;
++ mf->code = AR0132_MEDIA_BUS_FMT;
++ mf->colorspace = V4L2_COLORSPACE_SMPTE170M;
++ mf->field = V4L2_FIELD_NONE;
++
++ return 0;
++}
++
++static int ar0132_set_fmt(struct v4l2_subdev *sd,
++ struct v4l2_subdev_pad_config *cfg,
++ struct v4l2_subdev_format *format)
++{
++ struct v4l2_mbus_framefmt *mf = &format->format;
++
++ mf->code = AR0132_MEDIA_BUS_FMT;
++ mf->colorspace = V4L2_COLORSPACE_SMPTE170M;
++ mf->field = V4L2_FIELD_NONE;
++
++ if (format->which == V4L2_SUBDEV_FORMAT_TRY)
++ cfg->try_fmt = *mf;
++
++ return 0;
++}
++
++static int ar0132_enum_mbus_code(struct v4l2_subdev *sd,
++ struct v4l2_subdev_pad_config *cfg,
++ struct v4l2_subdev_mbus_code_enum *code)
++{
++ if (code->pad || code->index > 0)
++ return -EINVAL;
++
++ code->code = AR0132_MEDIA_BUS_FMT;
++
++ return 0;
++}
++
++static int ar0132_get_edid(struct v4l2_subdev *sd, struct v4l2_edid *edid)
++{
++ struct i2c_client *client = v4l2_get_subdevdata(sd);
++ struct ar0132_priv *priv = to_ar0132(client);
++
++ memcpy(edid->edid, priv->id, 6);
++
++ edid->edid[6] = 0xff;
++ edid->edid[7] = client->addr;
++ edid->edid[8] = AR0132_VERSION_REG >> 8;
++ edid->edid[9] = AR0132_VERSION_REG & 0xff;
++
++ return 0;
++}
++
++static int ar0132_set_selection(struct v4l2_subdev *sd,
++ struct v4l2_subdev_pad_config *cfg,
++ struct v4l2_subdev_selection *sel)
++{
++ struct v4l2_rect *rect = &sel->r;
++ struct i2c_client *client = v4l2_get_subdevdata(sd);
++ struct ar0132_priv *priv = to_ar0132(client);
++
++ if (sel->which != V4L2_SUBDEV_FORMAT_ACTIVE ||
++ sel->target != V4L2_SEL_TGT_CROP)
++ return -EINVAL;
++
++ rect->left = ALIGN(rect->left, 2);
++ rect->top = ALIGN(rect->top, 2);
++ rect->width = ALIGN(rect->width, 2);
++ rect->height = ALIGN(rect->height, 2);
++
++ if ((rect->left + rect->width > AR0132_MAX_WIDTH) ||
++ (rect->top + rect->height > AR0132_MAX_HEIGHT))
++ *rect = priv->rect;
++
++ priv->rect.left = rect->left;
++ priv->rect.top = rect->top;
++ priv->rect.width = rect->width;
++ priv->rect.height = rect->height;
++
++ return 0;
++}
++
++static int ar0132_get_selection(struct v4l2_subdev *sd,
++ struct v4l2_subdev_pad_config *cfg,
++ struct v4l2_subdev_selection *sel)
++{
++ struct i2c_client *client = v4l2_get_subdevdata(sd);
++ struct ar0132_priv *priv = to_ar0132(client);
++
++ if (sel->which != V4L2_SUBDEV_FORMAT_ACTIVE)
++ return -EINVAL;
++
++ switch (sel->target) {
++ case V4L2_SEL_TGT_CROP_BOUNDS:
++ sel->r.left = 0;
++ sel->r.top = 0;
++ sel->r.width = AR0132_MAX_WIDTH;
++ sel->r.height = AR0132_MAX_HEIGHT;
++ return 0;
++ case V4L2_SEL_TGT_CROP_DEFAULT:
++ sel->r.left = 0;
++ sel->r.top = 0;
++ sel->r.width = AR0132_MAX_WIDTH;
++ sel->r.height = AR0132_MAX_HEIGHT;
++ return 0;
++ case V4L2_SEL_TGT_CROP:
++ sel->r = priv->rect;
++ return 0;
++ default:
++ return -EINVAL;
++ }
++}
++
++static int ar0132_g_mbus_config(struct v4l2_subdev *sd,
++ struct v4l2_mbus_config *cfg)
++{
++ cfg->flags = V4L2_MBUS_CSI2_1_LANE | V4L2_MBUS_CSI2_CHANNEL_0 |
++ V4L2_MBUS_CSI2_CONTINUOUS_CLOCK;
++ cfg->type = V4L2_MBUS_CSI2;
++
++ return 0;
++}
++
++#ifdef CONFIG_VIDEO_ADV_DEBUG
++static int ar0132_g_register(struct v4l2_subdev *sd,
++ struct v4l2_dbg_register *reg)
++{
++ struct i2c_client *client = v4l2_get_subdevdata(sd);
++ int ret;
++ u16 val = 0;
++
++ ret = reg16_read16(client, (u16)reg->reg, &val);
++ if (ret < 0)
++ return ret;
++
++ reg->val = val;
++ reg->size = sizeof(u16);
++
++ return 0;
++}
++
++static int ar0132_s_register(struct v4l2_subdev *sd,
++ const struct v4l2_dbg_register *reg)
++{
++ struct i2c_client *client = v4l2_get_subdevdata(sd);
++
++ return reg16_write16(client, (u16)reg->reg, (u16)reg->val);
++}
++#endif
++
++static struct v4l2_subdev_core_ops ar0132_core_ops = {
++#ifdef CONFIG_VIDEO_ADV_DEBUG
++ .g_register = ar0132_g_register,
++ .s_register = ar0132_s_register,
++#endif
++};
++
++static int ar0132_s_ctrl(struct v4l2_ctrl *ctrl)
++{
++ struct v4l2_subdev *sd = to_sd(ctrl);
++ struct i2c_client *client = v4l2_get_subdevdata(sd);
++ struct ar0132_priv *priv = to_ar0132(client);
++ int ret = -EINVAL;
++
++ if (!priv->init_complete)
++ return 0;
++
++ switch (ctrl->id) {
++ case V4L2_CID_BRIGHTNESS:
++ case V4L2_CID_CONTRAST:
++ case V4L2_CID_SATURATION:
++ case V4L2_CID_HUE:
++ case V4L2_CID_GAMMA:
++ case V4L2_CID_SHARPNESS:
++ case V4L2_CID_AUTOGAIN:
++ case V4L2_CID_GAIN:
++ case V4L2_CID_EXPOSURE:
++ case V4L2_CID_HFLIP:
++ case V4L2_CID_VFLIP:
++ break;
++ }
++
++ return ret;
++}
++
++static const struct v4l2_ctrl_ops ar0132_ctrl_ops = {
++ .s_ctrl = ar0132_s_ctrl,
++};
++
++static struct v4l2_subdev_video_ops ar0132_video_ops = {
++ .s_stream = ar0132_s_stream,
++ .g_mbus_config = ar0132_g_mbus_config,
++};
++
++static const struct v4l2_subdev_pad_ops ar0132_subdev_pad_ops = {
++ .get_edid = ar0132_get_edid,
++ .enum_mbus_code = ar0132_enum_mbus_code,
++ .get_selection = ar0132_get_selection,
++ .set_selection = ar0132_set_selection,
++ .get_fmt = ar0132_get_fmt,
++ .set_fmt = ar0132_set_fmt,
++};
++
++static struct v4l2_subdev_ops ar0132_subdev_ops = {
++ .core = &ar0132_core_ops,
++ .video = &ar0132_video_ops,
++ .pad = &ar0132_subdev_pad_ops,
++};
++
++static void ar0132_otp_id_read(struct i2c_client *client)
++{
++}
++
++static ssize_t ar0132_otp_id_show(struct device *dev,
++ struct device_attribute *attr, char *buf)
++{
++ struct v4l2_subdev *sd = i2c_get_clientdata(to_i2c_client(dev));
++ struct i2c_client *client = v4l2_get_subdevdata(sd);
++ struct ar0132_priv *priv = to_ar0132(client);
++
++ return snprintf(buf, 32, "%02x:%02x:%02x:%02x:%02x:%02x\n",
++ priv->id[0], priv->id[1], priv->id[2], priv->id[3], priv->id[4], priv->id[5]);
++}
++
++static DEVICE_ATTR(otp_id_ar0132, S_IRUGO, ar0132_otp_id_show, NULL);
++
++static int ar0132_initialize(struct i2c_client *client)
++{
++ struct ar0132_priv *priv = to_ar0132(client);
++ u16 val = 0;
++ u16 pid = 0;
++ int ret = 0;
++
++ ar0132_s_port(client, 1);
++
++ /* check and show model ID */
++ reg16_read16(client, AR0132_PID, &pid);
++
++ if (pid != AR0132_VERSION_REG) {
++ dev_dbg(&client->dev, "Product ID error %x\n", pid);
++ ret = -ENODEV;
++ goto err;
++ }
++
++ /* Program wizard registers */
++ ar0132_set_regs(client, ar0132_regs_wizard, ARRAY_SIZE(ar0132_regs_wizard));
++
++ /* Enable stream */
++ reg16_read16(client, 0x301a, &val); // read inital reset_register value
++ val |= (1 << 2); // Set streamOn bit
++ reg16_write16(client, 0x301a, val); // Start Streaming
++
++ /* Read OTP IDs */
++ ar0132_otp_id_read(client);
++
++ dev_info(&client->dev, "ar0132 PID %x, res %dx%d, OTP_ID %02x:%02x:%02x:%02x:%02x:%02x\n",
++ pid, AR0132_MAX_WIDTH, AR0132_MAX_HEIGHT, priv->id[0], priv->id[1], priv->id[2], priv->id[3], priv->id[4], priv->id[5]);
++err:
++ ar0132_s_port(client, 0);
++
++ return ret;
++}
++
++static int ar0132_parse_dt(struct device_node *np, struct ar0132_priv *priv)
++{
++ struct i2c_client *client = v4l2_get_subdevdata(&priv->sd);
++ int i;
++ struct device_node *endpoint = NULL, *rendpoint = NULL;
++ int tmp_addr = 0;
++
++ for (i = 0; ; i++) {
++ endpoint = of_graph_get_next_endpoint(np, endpoint);
++ if (!endpoint)
++ break;
++
++ of_node_put(endpoint);
++
++ of_property_read_u32(endpoint, "dvp-order", &priv->dvp_order);
++
++ rendpoint = of_parse_phandle(endpoint, "remote-endpoint", 0);
++ if (!rendpoint)
++ continue;
++
++ if (!of_property_read_u32(rendpoint, "max9271-addr", &priv->max9271_addr) &&
++ !of_property_read_u32(rendpoint->parent->parent, "reg", &priv->max9286_addr) &&
++ !kstrtouint(strrchr(rendpoint->full_name, '@') + 1, 0, &priv->port))
++ break;
++
++ if (!of_property_read_u32(rendpoint, "ti9x3-addr", &priv->ti9x3_addr) &&
++ !of_property_match_string(rendpoint->parent->parent, "compatible", "ti,ti9x4") &&
++ !of_property_read_u32(rendpoint->parent->parent, "reg", &priv->ti9x4_addr) &&
++ !kstrtouint(strrchr(rendpoint->full_name, '@') + 1, 0, &priv->port))
++ break;
++ }
++
++ if (!priv->max9286_addr && !priv->ti9x4_addr) {
++ dev_err(&client->dev, "deserializer does not present for AR0132\n");
++ return -EINVAL;
++ }
++
++ ar0132_s_port(client, 1);
++
++ /* setup I2C translator address */
++ tmp_addr = client->addr;
++ if (priv->max9286_addr) {
++ client->addr = priv->max9271_addr; /* Serializer I2C address */
++
++ reg8_write(client, 0x09, tmp_addr << 1); /* Sensor translated I2C address */
++ reg8_write(client, 0x0A, AR0132_I2C_ADDR << 1); /* Sensor native I2C address */
++ usleep_range(2000, 2500); /* wait 2ms */
++ };
++ if (priv->ti9x4_addr) {
++ client->addr = priv->ti9x4_addr; /* Deserializer I2C address */
++
++ reg8_write(client, 0x4c, (priv->port << 4) | (1 << priv->port)); /* Select RX port number */
++ usleep_range(2000, 2500); /* wait 2ms */
++ reg8_write(client, 0x65, tmp_addr << 1); /* Sensor translated I2C address */
++ reg8_write(client, 0x5d, AR0132_I2C_ADDR << 1); /* Sensor native I2C address */
++
++ reg8_write(client, 0x6e, 0xa9); /* GPIO0 - reset, GPIO1 - fsin */
++ }
++ client->addr = tmp_addr;
++
++ mdelay(10);
++
++ return 0;
++}
++
++static int ar0132_probe(struct i2c_client *client,
++ const struct i2c_device_id *did)
++{
++ struct ar0132_priv *priv;
++ int ret;
++
++ priv = devm_kzalloc(&client->dev, sizeof(*priv), GFP_KERNEL);
++ if (!priv)
++ return -ENOMEM;
++
++ v4l2_i2c_subdev_init(&priv->sd, client, &ar0132_subdev_ops);
++ priv->sd.flags = V4L2_SUBDEV_FL_HAS_DEVNODE;
++
++ priv->exposure = 0x100;
++ priv->gain = 0x100;
++ priv->autogain = 1;
++ v4l2_ctrl_handler_init(&priv->hdl, 4);
++ v4l2_ctrl_new_std(&priv->hdl, &ar0132_ctrl_ops,
++ V4L2_CID_BRIGHTNESS, 0, 16, 1, 7);
++ v4l2_ctrl_new_std(&priv->hdl, &ar0132_ctrl_ops,
++ V4L2_CID_CONTRAST, 0, 16, 1, 7);
++ v4l2_ctrl_new_std(&priv->hdl, &ar0132_ctrl_ops,
++ V4L2_CID_SATURATION, 0, 7, 1, 2);
++ v4l2_ctrl_new_std(&priv->hdl, &ar0132_ctrl_ops,
++ V4L2_CID_HUE, 0, 23, 1, 12);
++ v4l2_ctrl_new_std(&priv->hdl, &ar0132_ctrl_ops,
++ V4L2_CID_GAMMA, -128, 128, 1, 0);
++ v4l2_ctrl_new_std(&priv->hdl, &ar0132_ctrl_ops,
++ V4L2_CID_SHARPNESS, 0, 10, 1, 3);
++ v4l2_ctrl_new_std(&priv->hdl, &ar0132_ctrl_ops,
++ V4L2_CID_AUTOGAIN, 0, 1, 1, priv->autogain);
++ v4l2_ctrl_new_std(&priv->hdl, &ar0132_ctrl_ops,
++ V4L2_CID_GAIN, 0, 0xffff, 1, priv->gain);
++ v4l2_ctrl_new_std(&priv->hdl, &ar0132_ctrl_ops,
++ V4L2_CID_EXPOSURE, 0, 0xffff, 1, priv->exposure);
++ v4l2_ctrl_new_std(&priv->hdl, &ar0132_ctrl_ops,
++ V4L2_CID_HFLIP, 0, 1, 1, 1);
++ v4l2_ctrl_new_std(&priv->hdl, &ar0132_ctrl_ops,
++ V4L2_CID_VFLIP, 0, 1, 1, 0);
++ priv->sd.ctrl_handler = &priv->hdl;
++
++ ret = priv->hdl.error;
++ if (ret)
++ goto cleanup;
++
++ v4l2_ctrl_handler_setup(&priv->hdl);
++
++ priv->pad.flags = MEDIA_PAD_FL_SOURCE;
++ priv->sd.entity.flags |= MEDIA_ENT_F_CAM_SENSOR;
++ ret = media_entity_pads_init(&priv->sd.entity, 1, &priv->pad);
++ if (ret < 0)
++ goto cleanup;
++
++ ret = ar0132_parse_dt(client->dev.of_node, priv);
++ if (ret)
++ goto cleanup;
++
++ ret = ar0132_initialize(client);
++ if (ret < 0)
++ goto cleanup;
++
++ priv->rect.left = 0;
++ priv->rect.top = 0;
++ priv->rect.width = AR0132_MAX_WIDTH;
++ priv->rect.height = AR0132_MAX_HEIGHT;
++
++ ret = v4l2_async_register_subdev(&priv->sd);
++ if (ret)
++ goto cleanup;
++
++ if (device_create_file(&client->dev, &dev_attr_otp_id_ar0132) != 0) {
++ dev_err(&client->dev, "sysfs otp_id entry creation failed\n");
++ goto cleanup;
++ }
++
++ priv->init_complete = 1;
++
++ return 0;
++
++cleanup:
++ media_entity_cleanup(&priv->sd.entity);
++ v4l2_ctrl_handler_free(&priv->hdl);
++ v4l2_device_unregister_subdev(&priv->sd);
++#ifdef CONFIG_SOC_CAMERA_AR0132
++ v4l_err(client, "failed to probe @ 0x%02x (%s)\n",
++ client->addr, client->adapter->name);
++#endif
++ return ret;
++}
++
++static int ar0132_remove(struct i2c_client *client)
++{
++ struct ar0132_priv *priv = i2c_get_clientdata(client);
++
++ device_remove_file(&client->dev, &dev_attr_otp_id_ar0132);
++ v4l2_async_unregister_subdev(&priv->sd);
++ media_entity_cleanup(&priv->sd.entity);
++ v4l2_ctrl_handler_free(&priv->hdl);
++ v4l2_device_unregister_subdev(&priv->sd);
++
++ return 0;
++}
++
++#ifdef CONFIG_SOC_CAMERA_AR0132
++static const struct i2c_device_id ar0132_id[] = {
++ { "ar0132", 0 },
++ { }
++};
++MODULE_DEVICE_TABLE(i2c, ar0132_id);
++
++static const struct of_device_id ar0132_of_ids[] = {
++ { .compatible = "aptina,ar0132", },
++ { }
++};
++MODULE_DEVICE_TABLE(of, ar0132_of_ids);
++
++static struct i2c_driver ar0132_i2c_driver = {
++ .driver = {
++ .name = "ar0132",
++ .of_match_table = ar0132_of_ids,
++ },
++ .probe = ar0132_probe,
++ .remove = ar0132_remove,
++ .id_table = ar0132_id,
++};
++
++module_i2c_driver(ar0132_i2c_driver);
++
++MODULE_DESCRIPTION("SoC Camera driver for AR0132");
++MODULE_AUTHOR("Vladimir Barinov");
++MODULE_LICENSE("GPL");
++#endif
+diff --git a/drivers/media/i2c/soc_camera/ar0132.h b/drivers/media/i2c/soc_camera/ar0132.h
+new file mode 100644
+index 0000000..bafa193
+--- /dev/null
++++ b/drivers/media/i2c/soc_camera/ar0132.h
+@@ -0,0 +1,213 @@
++/*
++ * ON Semiconductor AR0132 sensor camera wizard 1110x620@30/BGGR/BT601/12bit
++ *
++ * Copyright (C) 2017 Cogent Embedded, Inc.
++ *
++ * This program is free software; you can redistribute it and/or modify it
++ * under the terms of the GNU General Public License as published by the
++ * Free Software Foundation; either version 2 of the License, or (at your
++ * option) any later version.
++ */
++
++//#define AR0132_DISPLAY_PATTERN_FIXED
++//#define AR0132_DISPLAY_PATTERN_COLOR_BAR
++
++#define AR0132_EMBEDDED_LINE
++
++#define AR0132_MAX_WIDTH 1665 // (1110*3/2)
++#define AR0132_MAX_HEIGHT 624
++
++#define AR0132_DELAY 0xffff
++
++#define AR0132_MAX_ROI_DIM_X 1288
++#define AR0132_MAX_ROI_DIM_Y 968
++#define AR0132_InfoLines 4
++
++#define AR0132_ROI_DIM_X 1110 // 1104
++#define AR0132_ROI_DIM_Y 620 // AR0132_MAX_HEIGHT
++
++#define AR0132_ROI_Y_START 0x00AE
++#define AR0132_ROI_X_START 0x005C
++#define AR0132_ROI_Y_END AR0132_ROI_Y_START+AR0132_ROI_DIM_Y-1
++#define AR0132_ROI_X_END AR0132_ROI_X_START+AR0132_ROI_DIM_X-1
++
++#define AR0132_FrameLength_Lines 0x029E
++#define AR0132_LineLength_Ticks 0x06B6
++
++#define AR0132_PLL_VT_Pix_Clk_Div 0x0008
++#define AR0132_PLL_VT_Sys_Clk_Div 0x0001
++#define AR0132_PLL_Pre_Clk_Div 0x0004
++#define AR0132_PLL_Multiplier 0x003C
++
++#define AR0132_DigitalTest 0x2002
++
++struct ar0132_reg {
++ u16 reg;
++ u16 val;
++};
++
++static const struct ar0132_reg ar0132_regs_wizard[] = {
++{0x301A, 0x0001}, // reset
++{AR0132_DELAY, 100},
++{0x301A, 0x10D8}, // Stream off and setup parallel
++{0x3070, 0x0001},
++{0x3070, 0x0000}, // 1: Solid color test pattern,
++ // 2: Full color bar test pattern,
++ // 3: Fade to grey color bar test pattern,
++ //256: Walking 1 test pattern (12 bit)
++#ifdef AR0132_DISPLAY_PATTERN_FIXED
++{0x3070, 0x0001},
++{0x3072, 0x0123}, // R
++{0x3074, 0x0456}, // G(GR row)
++{0x3076, 0x0abc}, // B
++{0x3078, 0x0def}, // G(GB row)
++#endif
++#ifdef AR0132_DISPLAY_PATTERN_COLOR_BAR
++{0x3070, 0x0002},
++#endif
++{AR0132_DELAY, 250},
++// patch begin
++{0x3088, 0x8000},
++{0x3086, 0x0025}, {0x3086, 0x5050}, {0x3086, 0x2D26}, {0x3086, 0x0828}, {0x3086, 0x0D17}, {0x3086, 0x0926}, {0x3086, 0x0028}, {0x3086, 0x0526},
++{0x3086, 0xA728}, {0x3086, 0x0725}, {0x3086, 0x8080}, {0x3086, 0x2925}, {0x3086, 0x0040}, {0x3086, 0x2702}, {0x3086, 0x1616}, {0x3086, 0x2706},
++{0x3086, 0x1736}, {0x3086, 0x26A6}, {0x3086, 0x1703}, {0x3086, 0x26A4}, {0x3086, 0x171F}, {0x3086, 0x2805}, {0x3086, 0x2620}, {0x3086, 0x2804},
++{0x3086, 0x2520}, {0x3086, 0x2027}, {0x3086, 0x0017}, {0x3086, 0x1D25}, {0x3086, 0x0020}, {0x3086, 0x1F17}, {0x3086, 0x1028}, {0x3086, 0x0519},
++{0x3086, 0x1703}, {0x3086, 0x2706}, {0x3086, 0x1703}, {0x3086, 0x1741}, {0x3086, 0x2660}, {0x3086, 0x17AE}, {0x3086, 0x2500}, {0x3086, 0x9027},
++{0x3086, 0x0026}, {0x3086, 0x1828}, {0x3086, 0x002E}, {0x3086, 0x2A28}, {0x3086, 0x081C}, {0x3086, 0x1470}, {0x3086, 0x7003}, {0x3086, 0x1470},
++{0x3086, 0x7004}, {0x3086, 0x1470}, {0x3086, 0x7005}, {0x3086, 0x1470}, {0x3086, 0x7009}, {0x3086, 0x170C}, {0x3086, 0x0014}, {0x3086, 0x0020},
++{0x3086, 0x2300}, {0x3086, 0x1400}, {0x3086, 0x5003}, {0x3086, 0x1400}, {0x3086, 0x2003}, {0x3086, 0x1400}, {0x3086, 0x5022}, {0x3086, 0x0414},
++{0x3086, 0x0020}, {0x3086, 0x0414}, {0x3086, 0x0050}, {0x3086, 0x0514}, {0x3086, 0x0020}, {0x3086, 0x2405}, {0x3086, 0x1400}, {0x3086, 0x5001},
++{0x3086, 0x2550}, {0x3086, 0x502D}, {0x3086, 0x2608}, {0x3086, 0x280D}, {0x3086, 0x1709}, {0x3086, 0x2600}, {0x3086, 0x2805}, {0x3086, 0x26A7},
++{0x3086, 0x2807}, {0x3086, 0x2580}, {0x3086, 0x8029}, {0x3086, 0x2500}, {0x3086, 0x4027}, {0x3086, 0x0216}, {0x3086, 0x1627}, {0x3086, 0x0617},
++{0x3086, 0x3626}, {0x3086, 0xA617}, {0x3086, 0x0326}, {0x3086, 0xA417}, {0x3086, 0x1F28}, {0x3086, 0x0526}, {0x3086, 0x2028}, {0x3086, 0x0425},
++{0x3086, 0x2020}, {0x3086, 0x2700}, {0x3086, 0x171D}, {0x3086, 0x2500}, {0x3086, 0x2020}, {0x3086, 0x1710}, {0x3086, 0x2805}, {0x3086, 0x1A17},
++{0x3086, 0x0327}, {0x3086, 0x0617}, {0x3086, 0x0317}, {0x3086, 0x4126}, {0x3086, 0x6017}, {0x3086, 0xAE25}, {0x3086, 0x0090}, {0x3086, 0x2700},
++{0x3086, 0x2618}, {0x3086, 0x2800}, {0x3086, 0x2E2A}, {0x3086, 0x2808}, {0x3086, 0x1D05}, {0x3086, 0x1470}, {0x3086, 0x7009}, {0x3086, 0x1720},
++{0x3086, 0x1400}, {0x3086, 0x2024}, {0x3086, 0x1400}, {0x3086, 0x5002}, {0x3086, 0x2550}, {0x3086, 0x502D}, {0x3086, 0x2608}, {0x3086, 0x280D},
++{0x3086, 0x1709}, {0x3086, 0x2600}, {0x3086, 0x2805}, {0x3086, 0x26A7}, {0x3086, 0x2807}, {0x3086, 0x2580}, {0x3086, 0x8029}, {0x3086, 0x2500},
++{0x3086, 0x4027}, {0x3086, 0x0216}, {0x3086, 0x1627}, {0x3086, 0x0617}, {0x3086, 0x3626}, {0x3086, 0xA617}, {0x3086, 0x0326}, {0x3086, 0xA417},
++{0x3086, 0x1F28}, {0x3086, 0x0526}, {0x3086, 0x2028}, {0x3086, 0x0425}, {0x3086, 0x2020}, {0x3086, 0x2700}, {0x3086, 0x171D}, {0x3086, 0x2500},
++{0x3086, 0x2021}, {0x3086, 0x1710}, {0x3086, 0x2805}, {0x3086, 0x1B17}, {0x3086, 0x0327}, {0x3086, 0x0617}, {0x3086, 0x0317}, {0x3086, 0x4126},
++{0x3086, 0x6017}, {0x3086, 0xAE25}, {0x3086, 0x0090}, {0x3086, 0x2700}, {0x3086, 0x2618}, {0x3086, 0x2800}, {0x3086, 0x2E2A}, {0x3086, 0x2808},
++{0x3086, 0x1E17}, {0x3086, 0x0A05}, {0x3086, 0x1470}, {0x3086, 0x7009}, {0x3086, 0x1616}, {0x3086, 0x1616}, {0x3086, 0x1616}, {0x3086, 0x1616},
++{0x3086, 0x1616}, {0x3086, 0x1616}, {0x3086, 0x1616}, {0x3086, 0x1616}, {0x3086, 0x1616}, {0x3086, 0x1616}, {0x3086, 0x1616}, {0x3086, 0x1616},
++{0x3086, 0x1616}, {0x3086, 0x1616}, {0x3086, 0x1616}, {0x3086, 0x1616}, {0x3086, 0x1400}, {0x3086, 0x2024}, {0x3086, 0x1400}, {0x3086, 0x502B},
++{0x3086, 0x302C}, {0x3086, 0x2C2C}, {0x3086, 0x2C00}, {0x3086, 0x0225}, {0x3086, 0x5050}, {0x3086, 0x2D26}, {0x3086, 0x0828}, {0x3086, 0x0D17},
++{0x3086, 0x0926}, {0x3086, 0x0028}, {0x3086, 0x0526}, {0x3086, 0xA728}, {0x3086, 0x0725}, {0x3086, 0x8080}, {0x3086, 0x2917}, {0x3086, 0x0525},
++{0x3086, 0x0040}, {0x3086, 0x2702}, {0x3086, 0x1616}, {0x3086, 0x2706}, {0x3086, 0x1736}, {0x3086, 0x26A6}, {0x3086, 0x1703}, {0x3086, 0x26A4},
++{0x3086, 0x171F}, {0x3086, 0x2805}, {0x3086, 0x2620}, {0x3086, 0x2804}, {0x3086, 0x2520}, {0x3086, 0x2027}, {0x3086, 0x0017}, {0x3086, 0x1E25},
++{0x3086, 0x0020}, {0x3086, 0x2117}, {0x3086, 0x1028}, {0x3086, 0x051B}, {0x3086, 0x1703}, {0x3086, 0x2706}, {0x3086, 0x1703}, {0x3086, 0x1747},
++{0x3086, 0x2660}, {0x3086, 0x17AE}, {0x3086, 0x2500}, {0x3086, 0x9027}, {0x3086, 0x0026}, {0x3086, 0x1828}, {0x3086, 0x002E}, {0x3086, 0x2A28},
++{0x3086, 0x081E}, {0x3086, 0x0831}, {0x3086, 0x1440}, {0x3086, 0x4014}, {0x3086, 0x2020}, {0x3086, 0x1410}, {0x3086, 0x1034}, {0x3086, 0x1400},
++{0x3086, 0x1014}, {0x3086, 0x0020}, {0x3086, 0x1400}, {0x3086, 0x4013}, {0x3086, 0x1802}, {0x3086, 0x1470}, {0x3086, 0x7004}, {0x3086, 0x1470},
++{0x3086, 0x7003}, {0x3086, 0x1470}, {0x3086, 0x7017}, {0x3086, 0x2002}, {0x3086, 0x1400}, {0x3086, 0x2002}, {0x3086, 0x1400}, {0x3086, 0x5004},
++{0x3086, 0x1400}, {0x3086, 0x2004}, {0x3086, 0x1400}, {0x3086, 0x5022}, {0x3086, 0x0314}, {0x3086, 0x0020}, {0x3086, 0x0314}, {0x3086, 0x0050},
++{0x3086, 0x2C2C}, {0x3086, 0x2C2C},
++{0x309E, 0x0186},
++{0x309E, 0x0186},
++// patch end
++{AR0132_DELAY, 250},
++{0x301A, 0x10D8}, // WR= RESET_REGISTER, 0x10D8 - stop streaming
++{0x3082, 0x0028}, // Set HiDy OPERATION_MODE_CTRL(A) Requested integration time ratio (T2 to T3): 8 & (T1 t0 T2): 16
++{0x3084, 0x0028}, // Set HiDy OPERATION_MODE_CTRL(B) Requested integration time ratio (T2 to T3): 16 & (T1 t0 T2): 16
++{0x301E, 0x00C8}, // set datapedestal to 200 to avoid clipping near saturation
++{0x3EDA, 0x0F03}, // Set vln_dac to 0x3 as recommended by Sergey
++{0x3EDE, 0xC007},
++{0x3ED8, 0x01EF}, // Vrst_low = +1
++{0x3EE2, 0xA46B},
++{0x3EE0, 0x067D}, // enable anti eclipse and adjust setting for high conversion gain
++{0x3EDC, 0x0070}, // adjust anti eclipse setting for low conversion gain
++{0x3044, 0x0404}, // disable digital row noise correction and cancels TX during column correction
++{0x3EE6, 0x4303}, // Helps with column noise at low light
++{0x3EE4, 0xD208}, // enable analog row noise correction
++{0x3ED6, 0x00BD},
++{0x3EE6, 0x8303}, // improves low light FPN
++{0x30E4, 0x6372}, // ADC settings to improve noise performance
++{0x30E2, 0x7253},
++{0x30E0, 0x5470},
++{0x30E6, 0xC4CC},
++{0x30E8, 0x8050},
++{AR0132_DELAY, 250},
++{0x3058, 0x003F}, // WR= BLUE_GAIN, 0x003F
++{0x3014, 0}, // Fine_IT_Time(A)
++{0x3002, AR0132_ROI_Y_START}, // WR= Y_ADDR_START_(A)
++{0x3004, AR0132_ROI_X_START}, // WR= X_ADDR_START_(A)
++{0x3006, AR0132_ROI_Y_END}, // WR= Y_ADDR_END_(A)
++{0x3008, AR0132_ROI_X_END}, // WR= X_ADDR_END_(A)
++{0x300A, AR0132_FrameLength_Lines}, // WR= FRAME_LENGTH_LINES_(A)
++{0x3018, 0}, // Fine_IT_Time(B)
++{0x308C, AR0132_ROI_Y_START}, // Y_ADDR_START_(B)
++{0x308A, AR0132_ROI_X_START}, // X_ADDR_START_(B)
++{0x3090, AR0132_ROI_Y_END}, // Y_ADDR_END_(B)
++{0x308E, AR0132_ROI_X_END}, // X_ADDR_END_(B)
++{0x30AA, AR0132_FrameLength_Lines}, // FRAME_LENGTH_LINES_(B)
++{0x300C, AR0132_LineLength_Ticks}, // Line Length
++{0x301A, 0x10D8}, // Disable Streaming and setup parallel
++{0x31D0, 0x0001}, // Set to 12 bits
++{0x3028, 0x0010}, // ROW_SPEED = 16
++{0x302A, AR0132_PLL_VT_Pix_Clk_Div},
++{0x302C, AR0132_PLL_VT_Sys_Clk_Div},
++{0x302E, AR0132_PLL_Pre_Clk_Div},
++{0x3030, AR0132_PLL_Multiplier},
++{0x3032, 0x0000}, // SCALING_MODE = 0
++{0x3040, 0xC000}, // READ_MODE = read_mode_vert_flip | read_mode_horiz_mirror
++{0x3044, 0x0404}, // Dark Control = 1028
++{0x30A6, 0x0001}, // Y Odd Inc. (A) = 1
++{0x30A8, 0x0001}, // Y Odd Inc. (B) = 1
++{0x30B0, AR0132_DigitalTest},
++{AR0132_DELAY, 100},
++#ifdef AR0132_EMBEDDED_LINE
++{0x3064, 0x1982}, // Embedded Data on
++#else
++{0x3064, 0x1802}, // Embedded Data off
++#endif
++{0x3100, 0x0084}, // WR= AECTRLREG,
++{0x3190, 0x6BA0},
++{0x3194, 0x0E74},
++{0x3196, 0x0ED8},
++{0x3198, 0x0FA0},
++{0x319E, 0x5040}, // resetvalue
++{0x31A2, 0x0FA0},
++//FrontCamera Specific Section
++//Common
++#ifdef AR0132_EMBEDDED_LINE
++{0x3064, 0x1982},
++#else
++{0x3064, 0x1802},
++#endif
++{0x30B4, 0x0011},
++{0x30ba, 0x0008},
++{0x3180, 0xE000},
++{0x3182, 0x012C},
++{0x3190, 0x6BA0},
++{0x3194, 0x0E74},
++{0x3196, 0x0ED8},
++{0x3198, 0x0FA0},
++{0x319E, 0x5040},
++{0x31A2, 0x0FA0},
++//Context A:0
++{0x3012, 0x0021},
++{0x3014, 0x0000},
++{0x30A6, 0x0001},
++{0x3056, 0x0008},
++{0x3058, 0x0008},
++{0x305A, 0x0008},
++{0x305C, 0x0008},
++{0x305E, 0x0008},
++{0x3082, 0x0014},
++//Context B:0
++{0x3016, 0x007F},
++{0x3018, 0x0000},
++{0x30A8, 0x0001},
++{0x30BC, 0x0020},
++{0x30BE, 0x0020},
++{0x30C0, 0x0020},
++{0x30C2, 0x0020},
++{0x30C4, 0x0020},
++{0x3084, 0x0028},
++//not covered
++{0x301E, 0x00C8},
++{0x3044, 0x0404},
++{0x31D0, 0x0001},
++{0x30B0, 0x2002},
++};
+diff --git a/drivers/media/i2c/soc_camera/ar0220.c b/drivers/media/i2c/soc_camera/ar0220.c
+new file mode 100644
+index 0000000..e00fe4a
+--- /dev/null
++++ b/drivers/media/i2c/soc_camera/ar0220.c
+@@ -0,0 +1,532 @@
++/*
++ * ON Semiconductor AR0220 sensor camera driver
++ *
++ * Copyright (C) 2017-2018 Cogent Embedded, Inc.
++ *
++ * This program is free software; you can redistribute it and/or modify it
++ * under the terms of the GNU General Public License as published by the
++ * Free Software Foundation; either version 2 of the License, or (at your
++ * option) any later version.
++ */
++
++#include <linux/delay.h>
++#include <linux/init.h>
++#include <linux/i2c.h>
++#include <linux/module.h>
++#include <linux/of_graph.h>
++#include <linux/videodev2.h>
++
++#include <media/soc_camera.h>
++#include <media/v4l2-common.h>
++#include <media/v4l2-ctrls.h>
++#include <media/v4l2-fwnode.h>
++
++#include "ar0220.h"
++
++#define AR0220_I2C_ADDR 0x10
++//#define AR0220_I2C_ADDR 0x54 // eeprom
++
++#define AR0220_PID 0x3000
++#define AR0220_VERSION_REG 0x0C54
++
++#define AR0220_MEDIA_BUS_FMT MEDIA_BUS_FMT_SBGGR8_1X8
++
++struct ar0220_priv {
++ struct v4l2_subdev sd;
++ struct v4l2_ctrl_handler hdl;
++ struct media_pad pad;
++ struct v4l2_rect rect;
++ int init_complete;
++ u8 id[6];
++ int exposure;
++ int gain;
++ int autogain;
++ /* serializers */
++ int ti9x4_addr;
++ int ti9x3_addr;
++ int port;
++ int gpio_resetb;
++ int gpio_fsin;
++
++};
++
++static inline struct ar0220_priv *to_ar0220(const struct i2c_client *client)
++{
++ return container_of(i2c_get_clientdata(client), struct ar0220_priv, sd);
++}
++
++static int ar0220_set_regs(struct i2c_client *client,
++ const struct ar0220_reg *regs, int nr_regs)
++{
++ int i;
++
++ for (i = 0; i < nr_regs; i++) {
++ if (regs[i].reg == AR0220_DELAY) {
++ mdelay(regs[i].val);
++ continue;
++ }
++
++ reg16_write16(client, regs[i].reg, regs[i].val);
++ }
++
++ return 0;
++}
++
++static int ar0220_s_stream(struct v4l2_subdev *sd, int enable)
++{
++ return 0;
++}
++
++static int ar0220_get_fmt(struct v4l2_subdev *sd,
++ struct v4l2_subdev_pad_config *cfg,
++ struct v4l2_subdev_format *format)
++{
++ struct v4l2_mbus_framefmt *mf = &format->format;
++ struct i2c_client *client = v4l2_get_subdevdata(sd);
++ struct ar0220_priv *priv = to_ar0220(client);
++
++ if (format->pad)
++ return -EINVAL;
++
++ mf->width = priv->rect.width;
++ mf->height = priv->rect.height;
++ mf->code = AR0220_MEDIA_BUS_FMT;
++ mf->colorspace = V4L2_COLORSPACE_SMPTE170M;
++ mf->field = V4L2_FIELD_NONE;
++
++ return 0;
++}
++
++static int ar0220_set_fmt(struct v4l2_subdev *sd,
++ struct v4l2_subdev_pad_config *cfg,
++ struct v4l2_subdev_format *format)
++{
++ struct v4l2_mbus_framefmt *mf = &format->format;
++
++ mf->code = AR0220_MEDIA_BUS_FMT;
++ mf->colorspace = V4L2_COLORSPACE_SMPTE170M;
++ mf->field = V4L2_FIELD_NONE;
++
++ if (format->which == V4L2_SUBDEV_FORMAT_TRY)
++ cfg->try_fmt = *mf;
++
++ return 0;
++}
++
++static int ar0220_enum_mbus_code(struct v4l2_subdev *sd,
++ struct v4l2_subdev_pad_config *cfg,
++ struct v4l2_subdev_mbus_code_enum *code)
++{
++ if (code->pad || code->index > 0)
++ return -EINVAL;
++
++ code->code = AR0220_MEDIA_BUS_FMT;
++
++ return 0;
++}
++
++static int ar0220_get_edid(struct v4l2_subdev *sd, struct v4l2_edid *edid)
++{
++ struct i2c_client *client = v4l2_get_subdevdata(sd);
++ struct ar0220_priv *priv = to_ar0220(client);
++
++ memcpy(edid->edid, priv->id, 6);
++
++ edid->edid[6] = 0xff;
++ edid->edid[7] = client->addr;
++ edid->edid[8] = AR0220_VERSION_REG >> 8;
++ edid->edid[9] = AR0220_VERSION_REG & 0xff;
++
++ return 0;
++}
++
++static int ar0220_set_selection(struct v4l2_subdev *sd,
++ struct v4l2_subdev_pad_config *cfg,
++ struct v4l2_subdev_selection *sel)
++{
++ struct v4l2_rect *rect = &sel->r;
++ struct i2c_client *client = v4l2_get_subdevdata(sd);
++ struct ar0220_priv *priv = to_ar0220(client);
++
++ if (sel->which != V4L2_SUBDEV_FORMAT_ACTIVE ||
++ sel->target != V4L2_SEL_TGT_CROP)
++ return -EINVAL;
++
++ rect->left = ALIGN(rect->left, 2);
++ rect->top = ALIGN(rect->top, 2);
++ rect->width = ALIGN(rect->width, 2);
++ rect->height = ALIGN(rect->height, 2);
++
++ if ((rect->left + rect->width > AR0220_MAX_WIDTH) ||
++ (rect->top + rect->height > AR0220_MAX_HEIGHT))
++ *rect = priv->rect;
++
++ priv->rect.left = rect->left;
++ priv->rect.top = rect->top;
++ priv->rect.width = rect->width;
++ priv->rect.height = rect->height;
++
++ return 0;
++}
++
++static int ar0220_get_selection(struct v4l2_subdev *sd,
++ struct v4l2_subdev_pad_config *cfg,
++ struct v4l2_subdev_selection *sel)
++{
++ struct i2c_client *client = v4l2_get_subdevdata(sd);
++ struct ar0220_priv *priv = to_ar0220(client);
++
++ if (sel->which != V4L2_SUBDEV_FORMAT_ACTIVE)
++ return -EINVAL;
++
++ switch (sel->target) {
++ case V4L2_SEL_TGT_CROP_BOUNDS:
++ sel->r.left = 0;
++ sel->r.top = 0;
++ sel->r.width = AR0220_MAX_WIDTH;
++ sel->r.height = AR0220_MAX_HEIGHT;
++ return 0;
++ case V4L2_SEL_TGT_CROP_DEFAULT:
++ sel->r.left = 0;
++ sel->r.top = 0;
++ sel->r.width = AR0220_MAX_WIDTH;
++ sel->r.height = AR0220_MAX_HEIGHT;
++ return 0;
++ case V4L2_SEL_TGT_CROP:
++ sel->r = priv->rect;
++ return 0;
++ default:
++ return -EINVAL;
++ }
++}
++
++static int ar0220_g_mbus_config(struct v4l2_subdev *sd,
++ struct v4l2_mbus_config *cfg)
++{
++ cfg->flags = V4L2_MBUS_CSI2_1_LANE | V4L2_MBUS_CSI2_CHANNEL_0 |
++ V4L2_MBUS_CSI2_CONTINUOUS_CLOCK;
++ cfg->type = V4L2_MBUS_CSI2;
++
++ return 0;
++}
++
++#ifdef CONFIG_VIDEO_ADV_DEBUG
++static int ar0220_g_register(struct v4l2_subdev *sd,
++ struct v4l2_dbg_register *reg)
++{
++ struct i2c_client *client = v4l2_get_subdevdata(sd);
++ int ret;
++ u16 val = 0;
++
++ ret = reg16_read16(client, (u16)reg->reg, &val);
++ if (ret < 0)
++ return ret;
++
++ reg->val = val;
++ reg->size = sizeof(u16);
++
++ return 0;
++}
++
++static int ar0220_s_register(struct v4l2_subdev *sd,
++ const struct v4l2_dbg_register *reg)
++{
++ struct i2c_client *client = v4l2_get_subdevdata(sd);
++
++ return reg16_write16(client, (u16)reg->reg, (u16)reg->val);
++}
++#endif
++
++static struct v4l2_subdev_core_ops ar0220_core_ops = {
++#ifdef CONFIG_VIDEO_ADV_DEBUG
++ .g_register = ar0220_g_register,
++ .s_register = ar0220_s_register,
++#endif
++};
++
++static int ar0220_s_ctrl(struct v4l2_ctrl *ctrl)
++{
++ struct v4l2_subdev *sd = to_sd(ctrl);
++ struct i2c_client *client = v4l2_get_subdevdata(sd);
++ struct ar0220_priv *priv = to_ar0220(client);
++ int ret = -EINVAL;
++
++ if (!priv->init_complete)
++ return 0;
++
++ switch (ctrl->id) {
++ case V4L2_CID_BRIGHTNESS:
++ case V4L2_CID_CONTRAST:
++ case V4L2_CID_SATURATION:
++ case V4L2_CID_HUE:
++ case V4L2_CID_GAMMA:
++ case V4L2_CID_SHARPNESS:
++ case V4L2_CID_AUTOGAIN:
++ case V4L2_CID_GAIN:
++ case V4L2_CID_EXPOSURE:
++ case V4L2_CID_HFLIP:
++ case V4L2_CID_VFLIP:
++ break;
++ }
++
++ return ret;
++}
++
++static const struct v4l2_ctrl_ops ar0220_ctrl_ops = {
++ .s_ctrl = ar0220_s_ctrl,
++};
++
++static struct v4l2_subdev_video_ops ar0220_video_ops = {
++ .s_stream = ar0220_s_stream,
++ .g_mbus_config = ar0220_g_mbus_config,
++};
++
++static const struct v4l2_subdev_pad_ops ar0220_subdev_pad_ops = {
++ .get_edid = ar0220_get_edid,
++ .enum_mbus_code = ar0220_enum_mbus_code,
++ .get_selection = ar0220_get_selection,
++ .set_selection = ar0220_set_selection,
++ .get_fmt = ar0220_get_fmt,
++ .set_fmt = ar0220_set_fmt,
++};
++
++static struct v4l2_subdev_ops ar0220_subdev_ops = {
++ .core = &ar0220_core_ops,
++ .video = &ar0220_video_ops,
++ .pad = &ar0220_subdev_pad_ops,
++};
++
++static void ar0220_otp_id_read(struct i2c_client *client)
++{
++}
++
++static ssize_t ar0220_otp_id_show(struct device *dev,
++ struct device_attribute *attr, char *buf)
++{
++ struct v4l2_subdev *sd = i2c_get_clientdata(to_i2c_client(dev));
++ struct i2c_client *client = v4l2_get_subdevdata(sd);
++ struct ar0220_priv *priv = to_ar0220(client);
++
++ return snprintf(buf, 32, "%02x:%02x:%02x:%02x:%02x:%02x\n",
++ priv->id[0], priv->id[1], priv->id[2], priv->id[3], priv->id[4], priv->id[5]);
++}
++
++static DEVICE_ATTR(otp_id_ar0220, S_IRUGO, ar0220_otp_id_show, NULL);
++
++static int ar0220_initialize(struct i2c_client *client)
++{
++ struct ar0220_priv *priv = to_ar0220(client);
++ u16 val = 0;
++ u16 pid = 0;
++ int ret = 0;
++
++ /* check and show model ID */
++ reg16_read16(client, AR0220_PID, &pid);
++
++ if (pid != AR0220_VERSION_REG) {
++ dev_dbg(&client->dev, "Product ID error %x\n", pid);
++ ret = -ENODEV;
++ goto err;
++ }
++
++ /* Program wizard registers */
++ ar0220_set_regs(client, ar0220_regs_wizard, ARRAY_SIZE(ar0220_regs_wizard));
++
++ /* Enable stream */
++ reg16_read16(client, 0x301a, &val); // read inital reset_register value
++ val |= (1 << 2); // Set streamOn bit
++ reg16_write16(client, 0x301a, val); // Start Streaming
++
++ /* Read OTP IDs */
++ ar0220_otp_id_read(client);
++
++ dev_info(&client->dev, "ar0220 PID %x, res %dx%d, OTP_ID %02x:%02x:%02x:%02x:%02x:%02x\n",
++ pid, AR0220_MAX_WIDTH, AR0220_MAX_HEIGHT, priv->id[0], priv->id[1], priv->id[2], priv->id[3], priv->id[4], priv->id[5]);
++err:
++ return ret;
++}
++
++static int ar0220_parse_dt(struct device_node *np, struct ar0220_priv *priv)
++{
++ struct i2c_client *client = v4l2_get_subdevdata(&priv->sd);
++ int i;
++ struct device_node *endpoint = NULL, *rendpoint = NULL;
++ int tmp_addr = 0;
++
++ for (i = 0; ; i++) {
++ endpoint = of_graph_get_next_endpoint(np, endpoint);
++ if (!endpoint)
++ break;
++
++ of_node_put(endpoint);
++
++ rendpoint = of_parse_phandle(endpoint, "remote-endpoint", 0);
++ if (!rendpoint)
++ continue;
++
++ if (!of_property_read_u32(rendpoint, "ti9x3-addr", &priv->ti9x3_addr) &&
++ !of_property_match_string(rendpoint->parent->parent, "compatible", "ti,ti9x4") &&
++ !of_property_read_u32(rendpoint->parent->parent, "reg", &priv->ti9x4_addr) &&
++ !kstrtouint(strrchr(rendpoint->full_name, '@') + 1, 0, &priv->port))
++ break;
++ }
++
++ if (!priv->ti9x4_addr) {
++ dev_err(&client->dev, "deserializer does not present\n");
++ return -EINVAL;
++ }
++
++ /* setup I2C translator address */
++ tmp_addr = client->addr;
++ if (priv->ti9x4_addr) {
++ client->addr = priv->ti9x4_addr; /* Deserializer I2C address */
++
++ reg8_write(client, 0x4c, (priv->port << 4) | (1 << priv->port)); /* Select RX port number */
++ usleep_range(2000, 2500); /* wait 2ms */
++ reg8_write(client, 0x65, tmp_addr << 1); /* Sensor translated I2C address */
++ reg8_write(client, 0x5d, AR0220_I2C_ADDR << 1); /* Sensor native I2C address */
++// reg8_write(client, 0x6e, 0xa9); /* GPIO0 - reset, GPIO1 - fsin */
++
++ client->addr = priv->ti9x3_addr; /* Serializer I2C address */
++ reg8_write(client, 0x06, 0x41); /* Set clock divider M */
++ reg8_write(client, 0x07, 0x25); /* Set clock divider N = 27MHz */
++ }
++ client->addr = tmp_addr;
++
++ mdelay(10);
++
++ return 0;
++}
++
++static int ar0220_probe(struct i2c_client *client,
++ const struct i2c_device_id *did)
++{
++ struct ar0220_priv *priv;
++ int ret;
++
++ priv = devm_kzalloc(&client->dev, sizeof(*priv), GFP_KERNEL);
++ if (!priv)
++ return -ENOMEM;
++
++ v4l2_i2c_subdev_init(&priv->sd, client, &ar0220_subdev_ops);
++ priv->sd.flags = V4L2_SUBDEV_FL_HAS_DEVNODE;
++
++ priv->exposure = 0x100;
++ priv->gain = 0x100;
++ priv->autogain = 1;
++ v4l2_ctrl_handler_init(&priv->hdl, 4);
++ v4l2_ctrl_new_std(&priv->hdl, &ar0220_ctrl_ops,
++ V4L2_CID_BRIGHTNESS, 0, 16, 1, 7);
++ v4l2_ctrl_new_std(&priv->hdl, &ar0220_ctrl_ops,
++ V4L2_CID_CONTRAST, 0, 16, 1, 7);
++ v4l2_ctrl_new_std(&priv->hdl, &ar0220_ctrl_ops,
++ V4L2_CID_SATURATION, 0, 7, 1, 2);
++ v4l2_ctrl_new_std(&priv->hdl, &ar0220_ctrl_ops,
++ V4L2_CID_HUE, 0, 23, 1, 12);
++ v4l2_ctrl_new_std(&priv->hdl, &ar0220_ctrl_ops,
++ V4L2_CID_GAMMA, -128, 128, 1, 0);
++ v4l2_ctrl_new_std(&priv->hdl, &ar0220_ctrl_ops,
++ V4L2_CID_SHARPNESS, 0, 10, 1, 3);
++ v4l2_ctrl_new_std(&priv->hdl, &ar0220_ctrl_ops,
++ V4L2_CID_AUTOGAIN, 0, 1, 1, priv->autogain);
++ v4l2_ctrl_new_std(&priv->hdl, &ar0220_ctrl_ops,
++ V4L2_CID_GAIN, 0, 0xffff, 1, priv->gain);
++ v4l2_ctrl_new_std(&priv->hdl, &ar0220_ctrl_ops,
++ V4L2_CID_EXPOSURE, 0, 0xffff, 1, priv->exposure);
++ v4l2_ctrl_new_std(&priv->hdl, &ar0220_ctrl_ops,
++ V4L2_CID_HFLIP, 0, 1, 1, 1);
++ v4l2_ctrl_new_std(&priv->hdl, &ar0220_ctrl_ops,
++ V4L2_CID_VFLIP, 0, 1, 1, 0);
++ priv->sd.ctrl_handler = &priv->hdl;
++
++ ret = priv->hdl.error;
++ if (ret)
++ goto cleanup;
++
++ v4l2_ctrl_handler_setup(&priv->hdl);
++
++ priv->pad.flags = MEDIA_PAD_FL_SOURCE;
++ priv->sd.entity.flags |= MEDIA_ENT_F_CAM_SENSOR;
++ ret = media_entity_pads_init(&priv->sd.entity, 1, &priv->pad);
++ if (ret < 0)
++ goto cleanup;
++
++ ret = ar0220_parse_dt(client->dev.of_node, priv);
++ if (ret)
++ goto cleanup;
++
++ ret = ar0220_initialize(client);
++ if (ret < 0)
++ goto cleanup;
++
++ priv->rect.left = 0;
++ priv->rect.top = 0;
++ priv->rect.width = AR0220_MAX_WIDTH;
++ priv->rect.height = AR0220_MAX_HEIGHT;
++
++ ret = v4l2_async_register_subdev(&priv->sd);
++ if (ret)
++ goto cleanup;
++
++ if (device_create_file(&client->dev, &dev_attr_otp_id_ar0220) != 0) {
++ dev_err(&client->dev, "sysfs otp_id entry creation failed\n");
++ goto cleanup;
++ }
++
++ priv->init_complete = 1;
++
++ return 0;
++
++cleanup:
++ media_entity_cleanup(&priv->sd.entity);
++ v4l2_ctrl_handler_free(&priv->hdl);
++ v4l2_device_unregister_subdev(&priv->sd);
++#ifdef CONFIG_SOC_CAMERA_AR0220
++ v4l_err(client, "failed to probe @ 0x%02x (%s)\n",
++ client->addr, client->adapter->name);
++#endif
++ return ret;
++}
++
++static int ar0220_remove(struct i2c_client *client)
++{
++ struct ar0220_priv *priv = i2c_get_clientdata(client);
++
++ device_remove_file(&client->dev, &dev_attr_otp_id_ar0220);
++ v4l2_async_unregister_subdev(&priv->sd);
++ media_entity_cleanup(&priv->sd.entity);
++ v4l2_ctrl_handler_free(&priv->hdl);
++ v4l2_device_unregister_subdev(&priv->sd);
++
++ return 0;
++}
++
++#ifdef CONFIG_SOC_CAMERA_AR0220
++static const struct i2c_device_id ar0220_id[] = {
++ { "ar0220", 0 },
++ { }
++};
++MODULE_DEVICE_TABLE(i2c, ar0220_id);
++
++static const struct of_device_id ar0220_of_ids[] = {
++ { .compatible = "aptina,ar0220", },
++ { }
++};
++MODULE_DEVICE_TABLE(of, ar0220_of_ids);
++
++static struct i2c_driver ar0220_i2c_driver = {
++ .driver = {
++ .name = "ar0220",
++ .of_match_table = ar0220_of_ids,
++ },
++ .probe = ar0220_probe,
++ .remove = ar0220_remove,
++ .id_table = ar0220_id,
++};
++
++module_i2c_driver(ar0220_i2c_driver);
++
++MODULE_DESCRIPTION("SoC Camera driver for AR0220");
++MODULE_AUTHOR("Vladimir Barinov");
++MODULE_LICENSE("GPL");
++#endif
+diff --git a/drivers/media/i2c/soc_camera/ar0220.h b/drivers/media/i2c/soc_camera/ar0220.h
+new file mode 100644
+index 0000000..8ef557d
+--- /dev/null
++++ b/drivers/media/i2c/soc_camera/ar0220.h
+@@ -0,0 +1,43 @@
++/*
++ * ON Semiconductor AR0220 sensor camera wizard 1820x940@44/RCCB/MIPI
++ *
++ * Copyright (C) 2017 Cogent Embedded, Inc.
++ *
++ * This program is free software; you can redistribute it and/or modify it
++ * under the terms of the GNU General Public License as published by the
++ * Free Software Foundation; either version 2 of the License, or (at your
++ * option) any later version.
++ */
++
++//#define AR0220_DISPLAY_PATTERN_FIXED
++//#define AR0220_DISPLAY_PATTERN_COLOR_BAR
++
++#define AR0220_MAX_WIDTH 3648 // (1820*2=3640) <- must be multiple of 16 - requred by R-CAR VIN
++#define AR0220_MAX_HEIGHT 944
++
++#define AR0220_DELAY 0xffff
++
++struct ar0220_reg {
++ u16 reg;
++ u16 val;
++};
++
++static const struct ar0220_reg ar0220_regs_wizard[] = {
++{0x301A, 0x0018}, // RESET_REGISTER
++{AR0220_DELAY, 500}, // Wait 500ms
++{0x3070, 0x0000}, // 1: Solid color test pattern,
++ // 2: Full color bar test pattern,
++ // 3: Fade to grey color bar test pattern,
++ //256: Walking 1 test pattern (12 bit)
++{0x3072, 0x0123}, // R
++{0x3074, 0x0456}, // G(GR row)
++{0x3076, 0x0abc}, // B
++{0x3078, 0x0def}, // G(GB row)
++#ifdef AR0220_DISPLAY_PATTERN_FIXED
++{0x3070, 0x0001},
++#endif
++#ifdef AR0220_DISPLAY_PATTERN_COLOR_BAR
++{0x3070, 0x0002},
++#endif
++{AR0220_DELAY, 100}, // Wait 100ms
++};
+diff --git a/drivers/media/i2c/soc_camera/max9286.c b/drivers/media/i2c/soc_camera/max9286.c
+new file mode 100644
+index 0000000..6a5d0889
+--- /dev/null
++++ b/drivers/media/i2c/soc_camera/max9286.c
+@@ -0,0 +1,694 @@
++/*
++ * MAXIM max9286 GMSL driver
++ *
++ * Copyright (C) 2015-2018 Cogent Embedded, Inc.
++ *
++ * This program is free software; you can redistribute it and/or modify it
++ * under the terms of the GNU General Public License as published by the
++ * Free Software Foundation; either version 2 of the License, or (at your
++ * option) any later version.
++ */
++
++#include <linux/delay.h>
++#include <linux/i2c.h>
++#include <linux/module.h>
++#include <linux/notifier.h>
++#include <linux/of_gpio.h>
++#include <linux/of_graph.h>
++#include <linux/videodev2.h>
++
++#include <media/v4l2-async.h>
++#include <media/v4l2-common.h>
++#include <media/v4l2-device.h>
++#include <media/v4l2-fwnode.h>
++#include <media/v4l2-subdev.h>
++
++#include "max9286.h"
++
++#define MAXIM_I2C_I2C_SPEED_837KHZ (0x7 << 2) /* 837kbps */
++#define MAXIM_I2C_I2C_SPEED_533KHZ (0x6 << 2) /* 533kbps */
++#define MAXIM_I2C_I2C_SPEED_339KHZ (0x5 << 2) /* 339 kbps */
++#define MAXIM_I2C_I2C_SPEED_173KHZ (0x4 << 2) /* 174kbps */
++#define MAXIM_I2C_I2C_SPEED_105KHZ (0x3 << 2) /* 105 kbps */
++#define MAXIM_I2C_I2C_SPEED_085KHZ (0x2 << 2) /* 84.7 kbps */
++#define MAXIM_I2C_I2C_SPEED_028KHZ (0x1 << 2) /* 28.3 kbps */
++#define MAXIM_I2C_I2C_SPEED MAXIM_I2C_I2C_SPEED_339KHZ
++
++struct max9286_priv {
++ struct v4l2_subdev sd[4];
++ struct fwnode_handle *sd_fwnode[4];
++ int des_addr;
++ int des_quirk_addr; /* second MAX9286 on the same I2C bus */
++ int links;
++ int links_mask;
++ int lanes;
++ int csi_rate;
++ const char *fsync_mode;
++ int fsync_period;
++ char pclk_rising_edge;
++ int gpio_resetb;
++ int active_low_resetb;
++ int him;
++ int hsync;
++ int vsync;
++ int timeout;
++ int poc_delay;
++ atomic_t use_count;
++ u32 csi2_outord;
++ struct i2c_client *client;
++ int max9271_addr_map[4];
++ int ser_id;
++ struct gpio_desc *poc_gpio[4]; /* PoC power supply */
++};
++
++static char fsync_mode_default[20] = "manual"; /* manual, automatic, semi-automatic, external */
++
++static int conf_link;
++module_param(conf_link, int, 0644);
++MODULE_PARM_DESC(conf_link, " Force configuration link. Used only if robust firmware flashing required (f.e. recovery)");
++
++static int poc_trig;
++module_param(poc_trig, int, 0644);
++MODULE_PARM_DESC(poc_trig, " Use PoC triggering during reverse channel setup. Useful on systems with dedicated PoC and unstable ser-des lock");
++
++static int him;
++module_param(him, int, 0644);
++MODULE_PARM_DESC(him, " Use High-Immunity mode (default: leagacy mode)");
++
++static int fsync_period;
++module_param(fsync_period, int, 0644);
++MODULE_PARM_DESC(fsync_period, " Frame sync period (default: 3.2MHz)");
++
++static int hsync;
++module_param(hsync, int, 0644);
++MODULE_PARM_DESC(hsync, " HSYNC invertion (default: 0 - not inverted)");
++
++static int vsync = 1;
++module_param(vsync, int, 0644);
++MODULE_PARM_DESC(vsync, " VSYNC invertion (default: 1 - inverted)");
++
++static int gpio_resetb;
++module_param(gpio_resetb, int, 0644);
++MODULE_PARM_DESC(gpio_resetb, " Serializer GPIO reset (default: 0 - not used)");
++
++static int active_low_resetb;
++module_param(active_low_resetb, int, 0644);
++MODULE_PARM_DESC(active_low_resetb, " Serializer GPIO reset level (default: 0 - active high)");
++
++static int poc_delay;
++module_param(poc_delay, int, 0644);
++MODULE_PARM_DESC(poc_delay, " Delay in ms after POC enable (default: 0 ms)");
++
++static char* ser_name(int id)
++{
++ switch (id) {
++ case MAX9271_ID:
++ return "MAX9271";
++ case MAX96705_ID:
++ return "MAX96705";
++ default:
++ return "unknown";
++ }
++}
++
++static void max9286_preinit(struct i2c_client *client, int addr)
++{
++ struct max9286_priv *priv = i2c_get_clientdata(client);
++
++ client->addr = addr; /* MAX9286-CAMx I2C */
++ reg8_write(client, 0x0a, 0x00); /* disable reverse control for all cams */
++ reg8_write(client, 0x00, 0x00); /* disable all GMSL links [0:3] */
++ usleep_range(2000, 2500); /* wait 2ms after any change of reverse channel settings */
++ reg8_write(client, 0x1c, priv->him ? 0xf4 : 0x04); /* high-immunity or legacy mode */
++}
++
++static void max9286_sensor_reset(struct i2c_client *client, int addr, int reset_on)
++{
++ struct max9286_priv *priv = i2c_get_clientdata(client);
++
++ if (priv->gpio_resetb < 1 || priv->gpio_resetb > 5)
++ return;
++
++ /* sensor reset/unreset */
++ client->addr = addr; /* MAX9271-CAMx I2C */
++ reg8_write(client, 0x0f, (0xfe & ~BIT(priv->gpio_resetb)) | /* set GPIOn value to reset/unreset */
++ ((priv->active_low_resetb ? BIT(priv->gpio_resetb) : 0) ^ reset_on));
++ reg8_write(client, 0x0e, 0x42 | BIT(priv->gpio_resetb)); /* set GPIOn direction output */
++}
++
++static void max9286_postinit(struct i2c_client *client, int addr)
++{
++ struct max9286_priv *priv = i2c_get_clientdata(client);
++ int idx;
++
++ for (idx = 0; idx < priv->links; idx++) {
++ client->addr = priv->des_addr; /* MAX9286 I2C */
++ reg8_write(client, 0x0a, 0x11 << idx); /* enable reverse/forward control for CAMx */
++
++ client->addr = priv->max9271_addr_map[idx]; /* MAX9271-CAMx I2C */
++ max9286_sensor_reset(client, client->addr, 0); /* sensor unreset */
++ }
++
++ client->addr = addr; /* MAX9286 I2C */
++ reg8_write(client, 0x0a, 0x00); /* disable reverse control for all cams */
++ reg8_write(client, 0x00, 0xe0 | priv->links_mask); /* enable GMSL link for CAMs */
++ reg8_write(client, 0x0b, priv->csi2_outord); /* CSI2 output order */
++ reg8_write(client, 0x15, 0x9b); /* enable CSI output, VC is set accordingly to Link number, BIT7 magic must be set */
++ reg8_write(client, 0x1b, priv->links_mask); /* enable equalizer for CAMs */
++ usleep_range(5000, 5500); /* wait 2ms after any change of reverse channel settings */
++
++ if (strcmp(priv->fsync_mode, "manual") == 0) {
++ reg8_write(client, 0x01, 0x00); /* manual: FRAMESYNC set manually via [0x06:0x08] regs */
++ } else if (strcmp(priv->fsync_mode, "automatic") == 0) {
++ reg8_write(client, 0x01, 0x02); /* automatic: FRAMESYNC taken from the slowest Link */
++ } else if (strcmp(priv->fsync_mode, "semi-automatic") == 0) {
++ reg8_write(client, 0x01, 0x01); /* semi-automatic: FRAMESYNC taken from the slowest Link */
++ } else if (strcmp(priv->fsync_mode, "external") == 0) {
++ reg8_write(client, 0x01, 0xc0); /* ECU (aka MCU) based FrameSync using GPI-to-GPO */
++ }
++}
++
++static int max9286_reverse_channel_setup(struct i2c_client *client, int idx)
++{
++ struct max9286_priv *priv = i2c_get_clientdata(client);
++ u8 val = 0;
++ int timeout = priv->timeout;
++ char timeout_str[10];
++ int ret = 0;
++
++ /* Reverse channel enable */
++ client->addr = priv->des_addr; /* MAX9286-CAMx I2C */
++ reg8_write(client, 0x3f, 0x4f); /* enable custom reverse channel & first pulse length */
++ reg8_write(client, 0x34, 0xa2 | MAXIM_I2C_I2C_SPEED); /* enable artificial ACKs, I2C speed set */
++ usleep_range(2000, 2500); /* wait 2ms after any change of reverse channel settings */
++ reg8_write(client, 0x00, 0xe0 | BIT(idx)); /* enable GMSL link for CAMx */
++ reg8_write(client, 0x0a, 0x11 << idx); /* enable reverse control for CAMx */
++ usleep_range(2000, 2500); /* wait 2ms after any change of reverse channel settings */
++
++ for (;;) {
++ client->addr = priv->des_addr; /* MAX9286-CAMx I2C */
++ reg8_write(client, 0x3b, 0x1e); /* first pulse length rise time changed from 300ns to 200ns, amplitude 100mV */
++ usleep_range(2000, 2500); /* wait 2ms after any change of reverse channel settings */
++
++ client->addr = 0x40; /* MAX9271-CAMx I2C */
++ reg8_write(client, 0x04, 0x43); /* wake-up, enable reverse_control/conf_link */
++ usleep_range(2000, 2500); /* wait 2ms after any change of reverse channel settings */
++ reg8_write(client, 0x08, 0x01); /* reverse channel receiver high threshold enable */
++ reg8_write(client, 0x97, priv->him ? 0xaf : 0x5f); /* enable reverse control channel programming (MAX96705-MAX96711 only) */
++ usleep_range(2000, 2500); /* wait 2ms after any change of reverse channel settings */
++
++ client->addr = priv->des_addr; /* MAX9286-CAMx I2C */
++ reg8_write(client, 0x3b, 0x19); /* reverse channel increase amplitude 170mV to compensate high threshold enabled */
++ usleep_range(2000, 2500); /* wait 2ms after any change of reverse channel settings */
++
++ client->addr = 0x40; /* MAX9271-CAMx I2C */
++ reg8_read(client, 0x1e, &val); /* read max9271 ID */
++ if (val == MAX9271_ID || val == MAX96705_ID || --timeout == 0) {
++ priv->ser_id = val;
++ break;
++ }
++
++ /* Check if already initialized (after reboot/reset ?) */
++ client->addr = priv->max9271_addr_map[idx]; /* MAX9271-CAMx I2C */
++ reg8_read(client, 0x1e, &val); /* read max9271 ID */
++ if (val == MAX9271_ID || val == MAX96705_ID) {
++ priv->ser_id = val;
++ reg8_write(client, 0x04, 0x43); /* enable reverse_control/conf_link */
++ usleep_range(2000, 2500); /* wait 2ms after any change of reverse channel settings */
++ ret = -EADDRINUSE;
++ break;
++ }
++
++ if (timeout == priv->timeout / 2 && poc_trig) {
++ if (!IS_ERR(priv->poc_gpio[idx])) {
++ gpiod_direction_output(priv->poc_gpio[idx], 0); /* POC power off */
++ mdelay(200);
++ gpiod_direction_output(priv->poc_gpio[idx], 1); /* POC power on */
++ mdelay(priv->poc_delay);
++ }
++ }
++ }
++
++ max9286_sensor_reset(client, client->addr, 1); /* sensor reset */
++
++ if (!timeout) {
++ ret = -ETIMEDOUT;
++ goto out;
++ }
++
++ priv->links_mask |= BIT(idx);
++ priv->csi2_outord &= ~(0x3 << (idx * 2));
++ priv->csi2_outord |= ((hweight8(priv->links_mask) - 1) << (idx * 2));
++
++out:
++ sprintf(timeout_str, "retries=%d", priv->timeout - timeout);
++ dev_info(&client->dev, "link%d %s %sat 0x%x %s %s\n", idx, ser_name(priv->ser_id),
++ ret == -EADDRINUSE ? "already " : "", priv->max9271_addr_map[idx],
++ ret == -ETIMEDOUT ? "not found: timeout GMSL link establish" : "",
++ priv->timeout - timeout? timeout_str : "");
++
++ return ret;
++}
++
++static void max9286_initial_setup(struct i2c_client *client)
++{
++ struct max9286_priv *priv = i2c_get_clientdata(client);
++
++ /* Initial setup */
++ client->addr = priv->des_addr; /* MAX9286-CAMx I2C */
++ reg8_write(client, 0x15, 0x13); /* disable CSI output, VC is set accordingly to Link number */
++ reg8_write(client, 0x69, 0x0f); /* mask CSI forwarding from all links */
++ switch (priv->lanes) {
++ case 1:
++ reg8_write(client, 0x12, 0x33); /* enable CSI-2 Lane D0, DBL mode, YUV422 8-bit*/
++ break;
++ case 2:
++ reg8_write(client, 0x12, 0x73); /* enable CSI-2 Lanes D0,D1, DBL mode, YUV422 8-bit*/
++ break;
++ case 3:
++ reg8_write(client, 0x12, 0xd3); /* enable CSI-2 Lanes D0-D2, DBL mode, YUV422 8-bit*/
++ break;
++ case 4:
++ reg8_write(client, 0x12, 0xf3); /* enable CSI-2 Lanes D0-D3, DBL mode, YUV422 8-bit*/
++ break;
++ default:
++ dev_err(&client->dev, "CSI2 lanes number is invalid (%d)\n", priv->lanes);
++ }
++
++ /* Start GMSL initialization with FSYNC disabled. This is required for some odd LVDS cameras */
++ reg8_write(client, 0x01, 0xc0); /* ECU (aka MCU) based FrameSync using GPI-to-GPO */
++ reg8_write(client, 0x06, priv->fsync_period & 0xff);
++ reg8_write(client, 0x07, (priv->fsync_period >> 8) & 0xff);
++ reg8_write(client, 0x08, priv->fsync_period >> 16);
++
++ reg8_write(client, 0x63, 0); /* disable overlap window */
++ reg8_write(client, 0x64, 0);
++ reg8_write(client, 0x0c, 0x91 | (priv->vsync ? BIT(3) : 0) | (priv->hsync ? BIT(2) : 0)); /* enable HS/VS encoding, use D14/15 for HS/VS, invert HS/VS */
++ reg8_write(client, 0x19, 0x0c); /* Drive HSTRAIL state for 120ns after the last payload bit */
++}
++
++static void max9286_gmsl_link_setup(struct i2c_client *client, int idx)
++{
++ struct max9286_priv *priv = i2c_get_clientdata(client);
++
++ /* GMSL setup */
++ client->addr = 0x40; /* MAX9271-CAMx I2C */
++ reg8_write(client, 0x0d, 0x22 | MAXIM_I2C_I2C_SPEED); /* disable artificial ACK, I2C speed set */
++ reg8_write(client, 0x07, 0x84 | (priv->pclk_rising_edge ? 0 : 0x10)); /* RAW/YUV, PCLK edge, HS/VS encoding enabled */
++ usleep_range(2000, 2500); /* wait 2ms */
++ reg8_write(client, 0x02, 0xff); /* spread spectrum +-4%, pclk range automatic, Gbps automatic */
++ usleep_range(2000, 2500); /* wait 2ms */
++
++ if (priv->ser_id == MAX96705_ID) {
++ /* setup crossbar in DBL mode: reverse DVP bus */
++ reg8_write(client, 0x20, 0x07);
++ reg8_write(client, 0x21, 0x06);
++ reg8_write(client, 0x22, 0x05);
++ reg8_write(client, 0x23, 0x04);
++ reg8_write(client, 0x24, 0x03);
++ reg8_write(client, 0x25, 0x02);
++ reg8_write(client, 0x26, 0x01);
++ reg8_write(client, 0x27, 0x00);
++
++ reg8_write(client, 0x30, 0x17);
++ reg8_write(client, 0x31, 0x16);
++ reg8_write(client, 0x32, 0x15);
++ reg8_write(client, 0x33, 0x14);
++ reg8_write(client, 0x34, 0x13);
++ reg8_write(client, 0x35, 0x12);
++ reg8_write(client, 0x36, 0x11);
++ reg8_write(client, 0x37, 0x10);
++ }
++
++ client->addr = priv->des_addr; /* MAX9286-CAMx I2C */
++ reg8_write(client, 0x34, 0x22 | MAXIM_I2C_I2C_SPEED); /* disable artificial ACK, I2C speed set */
++ usleep_range(2000, 2500); /* wait 2ms */
++
++ /* I2C translator setup */
++ client->addr = 0x40; /* MAX9271-CAMx I2C */
++// reg8_write(client, 0x09, maxim_map[2][idx] << 1); /* SENSOR I2C translated - must be set by sensor driver */
++// reg8_write(client, 0x0A, 0x30 << 1); /* SENSOR I2C native - must be set by sensor driver */
++ reg8_write(client, 0x0B, BROADCAST << 1); /* broadcast I2C */
++ reg8_write(client, 0x0C, priv->max9271_addr_map[idx] << 1); /* MAX9271-CAMx I2C new */
++ /* I2C addresse change */
++ reg8_write(client, 0x01, priv->des_addr << 1); /* MAX9286 I2C */
++ reg8_write(client, 0x00, priv->max9271_addr_map[idx] << 1); /* MAX9271-CAM0 I2C new */
++ usleep_range(2000, 2500); /* wait 2ms */
++ /* put MAX9271 in configuration link state */
++ client->addr = priv->max9271_addr_map[idx]; /* MAX9271-CAMx I2C new */
++ reg8_write(client, 0x04, 0x43); /* enable reverse_control/conf_link */
++ usleep_range(2000, 2500); /* wait 2ms */
++#ifdef MAXIM_DUMP
++ client->addr = priv->des_addr; /* MAX9286-CAMx I2C */
++ maxim_max927x_dump_regs(client);
++ client->addr = priv->max9271_addr_map[idx]; /* MAX9271-CAMx I2C new */
++ maxim_max927x_dump_regs(client);
++#endif
++}
++
++static int max9286_initialize(struct i2c_client *client)
++{
++ struct max9286_priv *priv = i2c_get_clientdata(client);
++ int idx, ret;
++
++ dev_info(&client->dev, "LINKs=%d, LANES=%d, FSYNC mode=%s, FSYNC period=%d, PCLK edge=%s\n",
++ priv->links, priv->lanes, priv->fsync_mode, priv->fsync_period,
++ priv->pclk_rising_edge ? "rising" : "falling");
++
++ if (priv->des_quirk_addr)
++ max9286_preinit(client, priv->des_quirk_addr);
++
++ max9286_preinit(client, priv->des_addr);
++ max9286_initial_setup(client);
++
++ for (idx = 0; idx < priv->links; idx++) {
++ if (!IS_ERR(priv->poc_gpio[idx])) {
++ gpiod_direction_output(priv->poc_gpio[idx], 1); /* POC power on */
++ mdelay(priv->poc_delay);
++ }
++
++ ret = max9286_reverse_channel_setup(client, idx);
++ if (ret)
++ continue;
++ max9286_gmsl_link_setup(client, idx);
++ }
++
++ max9286_postinit(client, priv->des_addr);
++
++ client->addr = priv->des_addr;
++
++ return 0;
++}
++
++#ifdef CONFIG_VIDEO_ADV_DEBUG
++static int max9286_g_register(struct v4l2_subdev *sd,
++ struct v4l2_dbg_register *reg)
++{
++ struct max9286_priv *priv = v4l2_get_subdevdata(sd);
++ struct i2c_client *client = priv->client;
++ int ret;
++ u8 val = 0;
++
++ ret = reg8_read(client, (u8)reg->reg, &val);
++ if (ret < 0)
++ return ret;
++
++ reg->val = val;
++ reg->size = sizeof(u8);
++
++ return 0;
++}
++
++static int max9286_s_register(struct v4l2_subdev *sd,
++ const struct v4l2_dbg_register *reg)
++{
++ struct max9286_priv *priv = v4l2_get_subdevdata(sd);
++ struct i2c_client *client = priv->client;
++
++ return reg8_write(client, (u8)reg->reg, (u8)reg->val);
++}
++#endif
++
++static int max9286_s_power(struct v4l2_subdev *sd, int on)
++{
++ struct max9286_priv *priv = v4l2_get_subdevdata(sd);
++ struct i2c_client *client = priv->client;
++
++ if (on) {
++ if (atomic_inc_return(&priv->use_count) == 1)
++ reg8_write(client, 0x69, priv->links_mask ^ 0x0f); /* unmask CSI forwarding from detected links */
++ } else {
++ if (atomic_dec_return(&priv->use_count) == 0)
++ reg8_write(client, 0x69, 0x0f); /* mask CSI forwarding from all links */
++ }
++
++ return 0;
++}
++
++static int max9286_registered_async(struct v4l2_subdev *sd)
++{
++ struct max9286_priv *priv = v4l2_get_subdevdata(sd);
++ struct i2c_client *client = priv->client;
++ int idx, tmp_addr;
++
++ /* switch to GMSL serial_link for streaming video */
++ tmp_addr = client->addr;
++ idx = sd->grp_id;
++
++ client->addr = priv->des_addr; /* MAX9286 I2C */
++ reg8_write(client, 0x0a, 0x11 << idx); /* enable reverse/forward control for CAMx */
++
++ client->addr = priv->max9271_addr_map[idx]; /* MAX9271-CAMx */
++ reg8_write(client, 0x04, conf_link ? 0x43 : 0x83); /* enable serial_link */
++ usleep_range(2000, 2500); /* wait 2ms after changing reverse_control */
++
++ client->addr = priv->des_addr; /* MAX9286 I2C */
++ reg8_write(client, 0x0a, (priv->links_mask << 4) | priv->links_mask); /* enable reverse/forward control for all CAMs */
++
++ client->addr = tmp_addr;
++
++ return 0;
++}
++
++static struct v4l2_subdev_core_ops max9286_subdev_core_ops = {
++#ifdef CONFIG_VIDEO_ADV_DEBUG
++ .g_register = max9286_g_register,
++ .s_register = max9286_s_register,
++#endif
++ .s_power = max9286_s_power,
++ .registered_async = max9286_registered_async,
++};
++
++static struct v4l2_subdev_ops max9286_subdev_ops = {
++ .core = &max9286_subdev_core_ops,
++};
++
++static int max9286_parse_dt(struct i2c_client *client)
++{
++ struct max9286_priv *priv = i2c_get_clientdata(client);
++ struct device_node *np = client->dev.of_node;
++ struct device_node *endpoint = NULL;
++ struct property *prop;
++ int err, pwen, i;
++ int sensor_delay, gpio0 = 1, gpio1 = 1;
++ u8 val = 0;
++ char poc_name[10];
++
++ if (of_property_read_u32(np, "maxim,links", &priv->links))
++ priv->links = 4;
++
++ if (of_property_read_u32(np, "maxim,lanes", &priv->lanes))
++ priv->lanes = 4;
++
++ pwen = of_get_gpio(np, 0);
++ if (pwen > 0) {
++ err = gpio_request_one(pwen, GPIOF_OUT_INIT_HIGH, dev_name(&client->dev));
++ if (err)
++ dev_err(&client->dev, "cannot request PWEN gpio %d: %d\n", pwen, err);
++ }
++
++ mdelay(250);
++
++ for (i = 0; i < 4; i++) {
++ sprintf(poc_name, "POC%d", i);
++ priv->poc_gpio[i] = devm_gpiod_get_optional(&client->dev, poc_name, 0);
++ }
++
++ reg8_read(client, 0x1e, &val); /* read max9286 ID */
++ if (val != MAX9286_ID) {
++ prop = of_find_property(np, "reg", NULL);
++ if (prop)
++ of_remove_property(np, prop);
++ return -ENODEV;
++ }
++
++ if (!of_property_read_u32(np, "maxim,gpio0", &gpio0) ||
++ !of_property_read_u32(np, "maxim,gpio1", &gpio1))
++ reg8_write(client, 0x0f, 0x08 | (gpio1 << 1) | gpio0);
++
++ if (of_property_read_u32(np, "maxim,resetb-gpio", &priv->gpio_resetb)) {
++ priv->gpio_resetb = -1;
++ } else {
++ if (of_property_read_bool(np, "maxim,resetb-active-high"))
++ priv->active_low_resetb = 0;
++ else
++ priv->active_low_resetb = 1;
++ }
++
++ if (!of_property_read_u32(np, "maxim,sensor_delay", &sensor_delay))
++ mdelay(sensor_delay);
++ if (of_property_read_string(np, "maxim,fsync-mode", &priv->fsync_mode))
++ priv->fsync_mode = fsync_mode_default;
++ if (of_property_read_u32(np, "maxim,fsync-period", &priv->fsync_period))
++ priv->fsync_period = 3200000; /* 96MHz/30fps */
++ priv->pclk_rising_edge = true;
++ if (of_property_read_bool(np, "maxim,pclk-falling-edge"))
++ priv->pclk_rising_edge = false;
++ if (of_property_read_u32(np, "maxim,timeout", &priv->timeout))
++ priv->timeout = 100;
++ if (of_property_read_u32(np, "maxim,i2c-quirk", &priv->des_quirk_addr))
++ priv->des_quirk_addr = 0;
++ if (of_property_read_u32(np, "maxim,him", &priv->him))
++ priv->him = 0;
++ if (of_property_read_u32(np, "maxim,hsync", &priv->hsync))
++ priv->hsync = 0;
++ if (of_property_read_u32(np, "maxim,vsync", &priv->vsync))
++ priv->vsync = 1;
++ if (of_property_read_u32(np, "maxim,poc-delay", &priv->poc_delay))
++ priv->poc_delay = 50;
++
++ /* module params override dts */
++ if (him)
++ priv->him = him;
++ if (fsync_period) {
++ priv->fsync_period = fsync_period;
++ priv->fsync_mode = fsync_mode_default;
++ }
++ if (hsync)
++ priv->hsync = hsync;
++ if (!vsync)
++ priv->vsync = vsync;
++ if (gpio_resetb)
++ priv->gpio_resetb = gpio_resetb;
++ if (active_low_resetb)
++ priv->active_low_resetb = active_low_resetb;
++ if (poc_delay)
++ priv->poc_delay = poc_delay;
++
++ for (i = 0; i < priv->links; i++) {
++ endpoint = of_graph_get_next_endpoint(np, endpoint);
++ if (!endpoint)
++ break;
++
++ of_node_put(endpoint);
++
++ if (of_property_read_u32(endpoint, "max9271-addr", &priv->max9271_addr_map[i])) {
++ dev_err(&client->dev, "max9271-addr not set\n");
++ return -EINVAL;
++ }
++
++ priv->sd_fwnode[i] = of_fwnode_handle(endpoint);
++ }
++
++ return 0;
++}
++
++static void max9286_setup_remote_endpoint(struct i2c_client *client)
++{
++ struct max9286_priv *priv = i2c_get_clientdata(client);
++ struct device_node *np = client->dev.of_node;
++ struct device_node *endpoint = NULL, *rendpoint = NULL;
++ int i;
++ struct property *csi_rate_prop, *dvp_order_prop;
++
++ for (i = 0; ; i++) {
++ endpoint = of_graph_get_next_endpoint(np, endpoint);
++ if (!endpoint)
++ break;
++
++ of_node_put(endpoint);
++
++ rendpoint = of_parse_phandle(endpoint, "remote-endpoint", 0);
++ if (!rendpoint)
++ continue;
++
++ csi_rate_prop = of_find_property(endpoint, "csi-rate", NULL);
++ if (csi_rate_prop) {
++ /* CSI2_RATE = PCLK*sizeof(YUV8)*links/lanes */
++ priv->csi_rate = cpu_to_be32(100 * 8 * hweight8(priv->links_mask) / priv->lanes);
++ csi_rate_prop->value = &priv->csi_rate;
++ of_update_property(rendpoint, csi_rate_prop);
++ }
++
++ dvp_order_prop = of_find_property(endpoint, "dvp-order", NULL);
++ if (dvp_order_prop)
++ of_update_property(rendpoint, dvp_order_prop);
++ }
++}
++
++static int max9286_probe(struct i2c_client *client,
++ const struct i2c_device_id *did)
++{
++ struct max9286_priv *priv;
++ int err, i;
++
++ priv = devm_kzalloc(&client->dev, sizeof(*priv), GFP_KERNEL);
++ if (!priv)
++ return -ENOMEM;
++
++ i2c_set_clientdata(client, priv);
++ priv->des_addr = client->addr;
++ priv->client = client;
++ atomic_set(&priv->use_count, 0);
++ priv->csi2_outord = 0xff;
++
++ err = max9286_parse_dt(client);
++ if (err)
++ goto out;
++
++ err = max9286_initialize(client);
++ if (err < 0)
++ goto out;
++
++ max9286_setup_remote_endpoint(client);
++
++ for (i = 0; i < 4; i++) {
++ v4l2_subdev_init(&priv->sd[i], &max9286_subdev_ops);
++ priv->sd[i].owner = client->dev.driver->owner;
++ priv->sd[i].dev = &client->dev;
++ priv->sd[i].grp_id = i;
++ v4l2_set_subdevdata(&priv->sd[i], priv);
++ priv->sd[i].fwnode = priv->sd_fwnode[i];
++
++ snprintf(priv->sd[i].name, V4L2_SUBDEV_NAME_SIZE, "%s.%d %d-%04x",
++ client->dev.driver->name, i, i2c_adapter_id(client->adapter),
++ client->addr);
++
++ err = v4l2_async_register_subdev(&priv->sd[i]);
++ if (err < 0)
++ goto out;
++ }
++out:
++ return err;
++}
++
++static int max9286_remove(struct i2c_client *client)
++{
++ struct max9286_priv *priv = i2c_get_clientdata(client);
++ int i;
++
++ for (i = 0; i < 4; i++) {
++ v4l2_async_unregister_subdev(&priv->sd[i]);
++ v4l2_device_unregister_subdev(&priv->sd[i]);
++ }
++
++ return 0;
++}
++
++static const struct of_device_id max9286_dt_ids[] = {
++ { .compatible = "maxim,max9286" },
++ {},
++};
++MODULE_DEVICE_TABLE(of, max9286_dt_ids);
++
++static const struct i2c_device_id max9286_id[] = {
++ { "max9286", 0 },
++ { }
++};
++MODULE_DEVICE_TABLE(i2c, max9286_id);
++
++static struct i2c_driver max9286_i2c_driver = {
++ .driver = {
++ .name = "max9286",
++ .of_match_table = of_match_ptr(max9286_dt_ids),
++ },
++ .probe = max9286_probe,
++ .remove = max9286_remove,
++ .id_table = max9286_id,
++};
++
++module_i2c_driver(max9286_i2c_driver);
++
++MODULE_DESCRIPTION("GMSL driver for MAX9286");
++MODULE_AUTHOR("Vladimir Barinov");
++MODULE_LICENSE("GPL");
+diff --git a/drivers/media/i2c/soc_camera/max9286.h b/drivers/media/i2c/soc_camera/max9286.h
+new file mode 100644
+index 0000000..6c2a9e0
+--- /dev/null
++++ b/drivers/media/i2c/soc_camera/max9286.h
+@@ -0,0 +1,244 @@
++/*
++ * MAXIM max9286-max9271 GMSL driver include file
++ *
++ * Copyright (C) 2015-2017 Cogent Embedded, Inc.
++ *
++ * This program is free software; you can redistribute it and/or modify it
++ * under the terms of the GNU General Public License as published by the
++ * Free Software Foundation; either version 2 of the License, or (at your
++ * option) any later version.
++ */
++
++#ifndef _MAX9286_MAX9271_H
++#define _MAX9286_MAX9271_H
++
++//#define DEBUG
++#ifdef DEBUG
++//#define WRITE_VERIFY
++#define MAXIM_DUMP
++#undef dev_dbg
++#define dev_dbg dev_info
++#endif
++
++#define REG8_NUM_RETRIES 1 /* number of read/write retries */
++#define REG16_NUM_RETRIES 10 /* number of read/write retries */
++#define MAX9271_ID 0x9
++#define MAX96705_ID 0x41
++#define MAX9286_ID 0x40
++#define BROADCAST 0x6f
++
++static inline int reg8_read(struct i2c_client *client, u8 reg, u8 *val)
++{
++ int ret, retries;
++
++ for (retries = REG8_NUM_RETRIES; retries; retries--) {
++ ret = i2c_smbus_read_byte_data(client, reg);
++ if (!(ret < 0))
++ break;
++ }
++
++ if (ret < 0) {
++ dev_dbg(&client->dev,
++ "read fail: chip 0x%x register 0x%x: %d\n",
++ client->addr, reg, ret);
++ } else {
++ *val = ret;
++ }
++
++ return ret < 0 ? ret : 0;
++}
++
++static inline int reg8_write(struct i2c_client *client, u8 reg, u8 val)
++{
++ int ret, retries;
++
++ for (retries = REG8_NUM_RETRIES; retries; retries--) {
++ ret = i2c_smbus_write_byte_data(client, reg, val);
++ if (!(ret < 0))
++ break;
++ }
++
++ if (ret < 0) {
++ dev_dbg(&client->dev,
++ "write fail: chip 0x%x register 0x%x: %d\n",
++ client->addr, reg, ret);
++ } else {
++#ifdef WRITE_VERIFY
++ u8 val2;
++ reg8_read(client, reg, &val2);
++ if (val != val2)
++ dev_err(&client->dev,
++ "write verify mismatch: chip 0x%x reg=0x%x "
++ "0x%x->0x%x\n", client->addr, reg, val, val2);
++#endif
++ }
++
++ return ret < 0 ? ret : 0;
++}
++
++static inline int reg16_read(struct i2c_client *client, u16 reg, u8 *val)
++{
++ int ret, retries;
++ u8 buf[2] = {reg >> 8, reg & 0xff};
++
++ for (retries = REG16_NUM_RETRIES; retries; retries--) {
++ ret = i2c_master_send(client, buf, 2);
++ if (ret == 2) {
++ ret = i2c_master_recv(client, buf, 1);
++ if (ret == 1)
++ break;
++ }
++ }
++
++ if (ret < 0) {
++ dev_dbg(&client->dev,
++ "read fail: chip 0x%x register 0x%x: %d\n",
++ client->addr, reg, ret);
++ } else {
++ *val = buf[0];
++ }
++
++ return ret < 0 ? ret : 0;
++}
++
++static inline int reg16_write(struct i2c_client *client, u16 reg, u8 val)
++{
++ int ret, retries;
++ u8 buf[3] = {reg >> 8, reg & 0xff, val};
++
++ for (retries = REG16_NUM_RETRIES; retries; retries--) {
++ ret = i2c_master_send(client, buf, 3);
++ if (ret == 3)
++ break;
++ }
++
++ if (ret < 0) {
++ dev_dbg(&client->dev,
++ "write fail: chip 0x%x register 0x%x: %d\n",
++ client->addr, reg, ret);
++ } else {
++#ifdef WRITE_VERIFY
++ u8 val2;
++ reg16_read(client, reg, &val2);
++ if (val != val2)
++ dev_err(&client->dev,
++ "write verify mismatch: chip 0x%x reg=0x%x "
++ "0x%x->0x%x\n", client->addr, reg, val, val2);
++#endif
++ }
++
++ return ret < 0 ? ret : 0;
++}
++
++
++static inline int reg16_read16(struct i2c_client *client, u16 reg, u16 *val)
++{
++ int ret, retries;
++ u8 buf[2] = {reg >> 8, reg & 0xff};
++
++ for (retries = REG8_NUM_RETRIES; retries; retries--) {
++ ret = i2c_master_send(client, buf, 2);
++ if (ret == 2) {
++ ret = i2c_master_recv(client, buf, 2);
++ if (ret == 2)
++ break;
++ }
++ }
++
++ if (ret < 0) {
++ dev_err(&client->dev,
++ "read fail: chip 0x%x register 0x%x: %d\n",
++ client->addr, reg, ret);
++ } else {
++ *val = ((u16)buf[0] << 8) | buf[1];
++ }
++
++ return ret < 0 ? ret : 0;
++}
++
++static inline int reg16_write16(struct i2c_client *client, u16 reg, u16 val)
++{
++ int ret, retries;
++ u8 buf[4] = {reg >> 8, reg & 0xff, val >> 8, val & 0xff};
++
++ for (retries = REG8_NUM_RETRIES; retries; retries--) {
++ ret = i2c_master_send(client, buf, 4);
++ if (ret == 4)
++ break;
++ }
++
++ if (ret < 0) {
++ dev_err(&client->dev,
++ "write fail: chip 0x%x register 0x%x: %d\n",
++ client->addr, reg, ret);
++ }
++
++ return ret < 0 ? ret : 0;
++}
++
++
++#ifdef MAXIM_DUMP
++static void maxim_ovsensor_dump_regs(struct i2c_client *client)
++{
++ int ret, i;
++ u8 val = 0;
++ u16 regs[] = {0x300a, 0x300b, 0x300c};
++
++ dev_dbg(&client->dev, "dump regs 0x%x\n", client->addr);
++
++ for (i = 0; i < sizeof(regs) / 2; i++) {
++ ret = reg16_read(client, regs[i], &val);
++ if (ret < 0)
++ dev_err(&client->dev,
++ "read fail: chip 0x%x register 0x%02x: %d\n",
++ client->addr, regs[i], ret);
++ printk("0x%02x -> 0x%x\n", regs[i], val);
++ }
++}
++
++static void maxim_ov10635_dump_format_regs(struct i2c_client *client)
++{
++ int ret, i;
++ u8 val;
++ u16 regs[] = {0x3003, 0x3004, 0x4300,
++ 0x4605, 0x3621, 0x3702, 0x3703, 0x3704,
++ 0x3802, 0x3803, 0x3806, 0x3807, 0x3808, 0x3809, 0x380a,
++ 0x380b, 0x380c, 0x380d, 0x380e, 0x380f,
++ 0x4606, 0x4607, 0x460a, 0x460b,
++ 0xc488, 0xc489, 0xc48a, 0xc48b,
++ 0xc4cc, 0xc4cd, 0xc4ce, 0xc4cf, 0xc512, 0xc513,
++ 0xc518, 0xc519, 0xc51a, 0xc51b,
++ };
++
++ dev_dbg(&client->dev, "dump regs 0x%x\n", client->addr);
++
++ for (i = 0; i < sizeof(regs) / 2; i++) {
++ ret = reg16_read(client, regs[i], &val);
++ if (ret < 0)
++ dev_err(&client->dev,
++ "read fail: chip 0x%x register 0x%02x: %d\n",
++ client->addr, regs[i], ret);
++ printk("0x%02x -> 0x%x\n", regs[i], val);
++ }
++}
++
++static void maxim_max927x_dump_regs(struct i2c_client *client)
++{
++ int ret;
++ u8 reg;
++
++ dev_dbg(&client->dev, "dump regs 0x%x\n", client->addr);
++
++ for (reg = 0; reg < 0x20; reg++) {
++ ret = i2c_smbus_read_byte_data(client, reg);
++ if (ret < 0)
++ dev_err(&client->dev,
++ "read fail: chip 0x%x register 0x%x: %d\n",
++ client->addr, reg, ret);
++ printk("0x%02x ", ret);
++ if (((reg + 1) % 0x10) == 0)
++ printk("\n");
++ }
++}
++#endif /* MAXIM_DUMP */
++#endif /* _MAX9286_MAX9271_H */
+diff --git a/drivers/media/i2c/soc_camera/ov10635.c b/drivers/media/i2c/soc_camera/ov10635.c
+new file mode 100644
+index 0000000..eacf015
+--- /dev/null
++++ b/drivers/media/i2c/soc_camera/ov10635.c
+@@ -0,0 +1,760 @@
++/*
++ * OmniVision ov10635 sensor camera driver
++ *
++ * Copyright (C) 2015-2017 Cogent Embedded, Inc.
++ *
++ * This program is free software; you can redistribute it and/or modify it
++ * under the terms of the GNU General Public License as published by the
++ * Free Software Foundation; either version 2 of the License, or (at your
++ * option) any later version.
++ */
++
++#include <linux/delay.h>
++#include <linux/init.h>
++#include <linux/i2c.h>
++#include <linux/module.h>
++#include <linux/of_graph.h>
++#include <linux/videodev2.h>
++
++#include <media/soc_camera.h>
++#include <media/v4l2-common.h>
++#include <media/v4l2-ctrls.h>
++#include <media/v4l2-fwnode.h>
++
++#include "max9286.h"
++#include "ov10635.h"
++
++#define OV10635_I2C_ADDR 0x30
++
++#define OV10635_PID 0x300a
++#define OV10635_VER 0x300b
++#define OV10635_VERSION_REG 0xa635
++#define OV10635_VERSION(pid, ver) (((pid) << 8) | ((ver) & 0xff))
++
++struct ov10635_priv {
++ struct v4l2_subdev sd;
++ struct v4l2_ctrl_handler hdl;
++ struct media_pad pad;
++ struct v4l2_rect rect;
++ int subsampling;
++ int fps_denominator;
++ int init_complete;
++ u8 id[6];
++ int dvp_order;
++ /* serializers */
++ int max9286_addr;
++ int max9271_addr;
++ int ti964_addr;
++ int ti954_addr;
++ int ti9x3_addr;
++ int port;
++ int gpio_resetb;
++ int gpio_fsin;
++};
++
++static inline struct ov10635_priv *to_ov10635(const struct i2c_client *client)
++{
++ return container_of(i2c_get_clientdata(client), struct ov10635_priv, sd);
++}
++
++static inline struct v4l2_subdev *to_sd(struct v4l2_ctrl *ctrl)
++{
++ return &container_of(ctrl->handler, struct ov10635_priv, hdl)->sd;
++}
++
++static void ov10635_s_port(struct i2c_client *client, int fwd_en)
++{
++ struct ov10635_priv *priv = to_ov10635(client);
++ int tmp_addr;
++
++ if (priv->max9286_addr) {
++ tmp_addr = client->addr;
++ client->addr = priv->max9286_addr; /* Deserializer I2C address */
++ reg8_write(client, 0x0a, fwd_en ? 0x11 << priv->port : 0); /* Enable/disable reverse/forward control for this port */
++ usleep_range(5000, 5500); /* wait 5ms */
++ client->addr = tmp_addr;
++ };
++}
++
++static int ov10635_set_regs(struct i2c_client *client,
++ const struct ov10635_reg *regs, int nr_regs)
++{
++ int i;
++
++ for (i = 0; i < nr_regs; i++) {
++ if (reg16_write(client, regs[i].reg, regs[i].val)) {
++ usleep_range(100, 150); /* wait 100ns */
++ reg16_write(client, regs[i].reg, regs[i].val);
++ }
++ }
++
++ return 0;
++}
++
++static int ov10635_s_stream(struct v4l2_subdev *sd, int enable)
++{
++ return 0;
++}
++
++static int ov10635_set_window(struct v4l2_subdev *sd, int subsampling)
++{
++ struct i2c_client *client = v4l2_get_subdevdata(sd);
++ struct ov10635_priv *priv = to_ov10635(client);
++
++ /* disable clocks */
++ reg16_write(client, 0x302e, 0x00);
++ reg16_write(client, 0x301b, 0xff);
++ reg16_write(client, 0x301c, 0xff);
++ reg16_write(client, 0x301a, 0xff);
++
++ /* setup resolution */
++ reg16_write(client, 0x3808, priv->rect.width >> 8);
++ reg16_write(client, 0x3809, priv->rect.width & 0xff);
++ reg16_write(client, 0x380a, priv->rect.height >> 8);
++ reg16_write(client, 0x380b, priv->rect.height & 0xff);
++
++ /* enable/disable subsampling */
++ reg16_write(client, 0x5005, subsampling ? 0x89 : 0x08);
++ reg16_write(client, 0x3007, subsampling ? 0x02 : 0x01);
++ reg16_write(client, 0x4004, subsampling ? 0x02 : 0x04);
++
++#if 0 /* This is implemented in VIN via SOC_CAMERA layer, hence skip */
++ /* horiz crop start */
++ reg16_write(client, 0x3800, priv->rect.left >> 8);
++ reg16_write(client, 0x3801, priv->rect.left & 0xff);
++ /* horiz crop end */
++ reg16_write(client, 0x3804, (priv->rect.left + priv->rect.width + 1) >> 8);
++ reg16_write(client, 0x3805, (priv->rect.left + priv->rect.width + 1) & 0xff);
++ /* vert crop start */
++ reg16_write(client, 0x3802, priv->rect.top >> 8);
++ reg16_write(client, 0x3803, priv->rect.top & 0xff);
++ /* vert crop end */
++ reg16_write(client, 0x3806, (priv->rect.top + priv->rect.height + 1) >> 8);
++ reg16_write(client, 0x3807, (priv->rect.top + priv->rect.height + 1) & 0xff);
++#endif
++ /* enable clocks */
++ reg16_write(client, 0x301b, 0xf0);
++ reg16_write(client, 0x301c, 0xf0);
++ reg16_write(client, 0x301a, 0xf0);
++ reg16_write(client, 0x302e, 0x01);
++
++ return 0;
++};
++
++static int ov10635_get_fmt(struct v4l2_subdev *sd,
++ struct v4l2_subdev_pad_config *cfg,
++ struct v4l2_subdev_format *format)
++{
++ struct v4l2_mbus_framefmt *mf = &format->format;
++ struct i2c_client *client = v4l2_get_subdevdata(sd);
++ struct ov10635_priv *priv = to_ov10635(client);
++
++ if (format->pad)
++ return -EINVAL;
++
++ mf->width = priv->rect.width;
++ mf->height = priv->rect.height;
++ mf->code = MEDIA_BUS_FMT_YUYV8_2X8;
++ mf->colorspace = V4L2_COLORSPACE_SMPTE170M;
++ mf->field = V4L2_FIELD_NONE;
++
++ return 0;
++}
++
++static int ov10635_set_fmt(struct v4l2_subdev *sd,
++ struct v4l2_subdev_pad_config *cfg,
++ struct v4l2_subdev_format *format)
++{
++ struct v4l2_mbus_framefmt *mf = &format->format;
++
++ mf->code = MEDIA_BUS_FMT_YUYV8_2X8;
++ mf->colorspace = V4L2_COLORSPACE_SMPTE170M;
++ mf->field = V4L2_FIELD_NONE;
++
++ if (format->which == V4L2_SUBDEV_FORMAT_TRY)
++ cfg->try_fmt = *mf;
++
++ return 0;
++}
++
++static int ov10635_enum_mbus_code(struct v4l2_subdev *sd,
++ struct v4l2_subdev_pad_config *cfg,
++ struct v4l2_subdev_mbus_code_enum *code)
++{
++ if (code->pad || code->index > 0)
++ return -EINVAL;
++
++ code->code = MEDIA_BUS_FMT_YUYV8_2X8;
++
++ return 0;
++}
++
++static int ov10635_get_edid(struct v4l2_subdev *sd, struct v4l2_edid *edid)
++{
++ struct i2c_client *client = v4l2_get_subdevdata(sd);
++ struct ov10635_priv *priv = to_ov10635(client);
++
++ memcpy(edid->edid, priv->id, 6);
++
++ edid->edid[6] = 0xff;
++ edid->edid[7] = client->addr;
++ edid->edid[8] = OV10635_VERSION_REG >> 8;
++ edid->edid[9] = OV10635_VERSION_REG & 0xff;
++
++ return 0;
++}
++
++static int ov10635_set_selection(struct v4l2_subdev *sd,
++ struct v4l2_subdev_pad_config *cfg,
++ struct v4l2_subdev_selection *sel)
++{
++ struct v4l2_rect *rect = &sel->r;
++ struct i2c_client *client = v4l2_get_subdevdata(sd);
++ struct ov10635_priv *priv = to_ov10635(client);
++ int subsampling = 0;
++
++ if (sel->which != V4L2_SUBDEV_FORMAT_ACTIVE ||
++ sel->target != V4L2_SEL_TGT_CROP)
++ return -EINVAL;
++
++ rect->left = ALIGN(rect->left, 2);
++ rect->top = ALIGN(rect->top, 2);
++ rect->width = ALIGN(rect->width, 2);
++ rect->height = ALIGN(rect->height, 2);
++
++ if ((rect->left + rect->width > OV10635_MAX_WIDTH) ||
++ (rect->top + rect->height > OV10635_MAX_HEIGHT))
++ *rect = priv->rect;
++
++ if (rect->width == OV10635_MAX_WIDTH / 2 &&
++ rect->height == OV10635_MAX_HEIGHT / 2)
++ subsampling = 1;
++
++ priv->rect.left = rect->left;
++ priv->rect.top = rect->top;
++ priv->rect.width = rect->width;
++ priv->rect.height = rect->height;
++
++ /* change window only for subsampling, crop is done by VIN */
++ if (subsampling != priv->subsampling) {
++ ov10635_set_window(sd, subsampling);
++ priv->subsampling = subsampling;
++ }
++
++ return 0;
++}
++
++static int ov10635_get_selection(struct v4l2_subdev *sd,
++ struct v4l2_subdev_pad_config *cfg,
++ struct v4l2_subdev_selection *sel)
++{
++ struct i2c_client *client = v4l2_get_subdevdata(sd);
++ struct ov10635_priv *priv = to_ov10635(client);
++
++ if (sel->which != V4L2_SUBDEV_FORMAT_ACTIVE)
++ return -EINVAL;
++
++ switch (sel->target) {
++ case V4L2_SEL_TGT_CROP_BOUNDS:
++ sel->r.left = 0;
++ sel->r.top = 0;
++ sel->r.width = OV10635_MAX_WIDTH;
++ sel->r.height = OV10635_MAX_HEIGHT;
++ return 0;
++ case V4L2_SEL_TGT_CROP_DEFAULT:
++ sel->r.left = 0;
++ sel->r.top = 0;
++ sel->r.width = OV10635_MAX_WIDTH;
++ sel->r.height = OV10635_MAX_HEIGHT;
++ return 0;
++ case V4L2_SEL_TGT_CROP:
++ sel->r = priv->rect;
++ return 0;
++ default:
++ return -EINVAL;
++ }
++}
++
++static int ov10635_g_mbus_config(struct v4l2_subdev *sd,
++ struct v4l2_mbus_config *cfg)
++{
++ cfg->flags = V4L2_MBUS_CSI2_1_LANE | V4L2_MBUS_CSI2_CHANNEL_0 |
++ V4L2_MBUS_CSI2_CONTINUOUS_CLOCK;
++ cfg->type = V4L2_MBUS_CSI2;
++
++ return 0;
++}
++
++static int ov10635_g_parm(struct v4l2_subdev *sd, struct v4l2_streamparm *parms)
++{
++ struct i2c_client *client = v4l2_get_subdevdata(sd);
++ struct ov10635_priv *priv = to_ov10635(client);
++ struct v4l2_captureparm *cp = &parms->parm.capture;
++
++ if (parms->type != V4L2_BUF_TYPE_VIDEO_CAPTURE)
++ return -EINVAL;
++
++ memset(cp, 0, sizeof(struct v4l2_captureparm));
++ cp->capability = V4L2_CAP_TIMEPERFRAME;
++ cp->timeperframe.numerator = 1;
++ cp->timeperframe.denominator = priv->fps_denominator;
++
++ return 0;
++}
++
++static int ov10635_s_parm(struct v4l2_subdev *sd, struct v4l2_streamparm *parms)
++{
++ struct i2c_client *client = v4l2_get_subdevdata(sd);
++ struct ov10635_priv *priv = to_ov10635(client);
++ struct v4l2_captureparm *cp = &parms->parm.capture;
++ int ret = 0;
++
++ if (parms->type != V4L2_BUF_TYPE_VIDEO_CAPTURE)
++ return -EINVAL;
++ if (cp->extendedmode != 0)
++ return -EINVAL;
++
++ if (priv->fps_denominator != cp->timeperframe.denominator) {
++ switch (cp->timeperframe.denominator) {
++ case 5:
++ ret = ov10635_set_regs(client, ov10635_regs_5fps,
++ ARRAY_SIZE(ov10635_regs_5fps));
++ break;
++ case 10:
++ ret = ov10635_set_regs(client, ov10635_regs_10fps,
++ ARRAY_SIZE(ov10635_regs_10fps));
++ break;
++ case 15:
++ ret = ov10635_set_regs(client, ov10635_regs_15fps,
++ ARRAY_SIZE(ov10635_regs_15fps));
++ break;
++ case 30:
++ ret = ov10635_set_regs(client, ov10635_regs_30fps,
++ ARRAY_SIZE(ov10635_regs_30fps));
++ break;
++ default:
++ ret = -EINVAL;
++ goto out;
++ }
++
++ priv->fps_denominator = cp->timeperframe.denominator;
++ }
++
++out:
++ return ret;
++}
++
++#ifdef CONFIG_VIDEO_ADV_DEBUG
++static int ov10635_g_register(struct v4l2_subdev *sd,
++ struct v4l2_dbg_register *reg)
++{
++ struct i2c_client *client = v4l2_get_subdevdata(sd);
++ int ret;
++ u8 val = 0;
++
++ ret = reg16_read(client, (u16)reg->reg, &val);
++ if (ret < 0)
++ return ret;
++
++ reg->val = val;
++ reg->size = sizeof(u16);
++
++ return 0;
++}
++
++static int ov10635_s_register(struct v4l2_subdev *sd,
++ const struct v4l2_dbg_register *reg)
++{
++ struct i2c_client *client = v4l2_get_subdevdata(sd);
++
++ return reg16_write(client, (u16)reg->reg, (u8)reg->val);
++}
++#endif
++
++static struct v4l2_subdev_core_ops ov10635_core_ops = {
++#ifdef CONFIG_VIDEO_ADV_DEBUG
++ .g_register = ov10635_g_register,
++ .s_register = ov10635_s_register,
++#endif
++};
++
++static int ov10635_s_ctrl(struct v4l2_ctrl *ctrl)
++{
++ struct v4l2_subdev *sd = to_sd(ctrl);
++ struct i2c_client *client = v4l2_get_subdevdata(sd);
++ struct ov10635_priv *priv = to_ov10635(client);
++ int ret = -EINVAL;
++ u8 val = 0;
++
++ if (!priv->init_complete)
++ return 0;
++
++ switch (ctrl->id) {
++ case V4L2_CID_BRIGHTNESS:
++ /* AEC/AGC target */
++ ret = reg16_write(client, 0xc46a, ctrl->val);
++ break;
++ case V4L2_CID_CONTRAST:
++ udelay(100);
++ ret = ov10635_set_regs(client, &ov10635_regs_contrast[ctrl->val][0], 18);
++ break;
++ case V4L2_CID_SATURATION:
++ ret = reg16_write(client, 0xc316, ctrl->val);
++ break;
++ case V4L2_CID_HUE:
++ /* CMX ? */
++ ret = 0;
++ break;
++ case V4L2_CID_GAMMA:
++ ret = reg16_write(client, 0xc4be, ctrl->val >> 8);
++ ret |= reg16_write(client, 0xc4bf, ctrl->val & 0xff);
++ break;
++ case V4L2_CID_AUTOGAIN:
++ /* automatic gain/exposure */
++ ret = reg16_write(client, 0x56d0, !ctrl->val);
++ break;
++ case V4L2_CID_GAIN:
++ /* manual gain */
++ ret = reg16_write(client, 0x3504, 0);
++ ret |= reg16_write(client, 0x56d1, ctrl->val >> 8);
++ ret |= reg16_write(client, 0x56d2, ctrl->val & 0xff);
++ ret |= reg16_write(client, 0x3504, 1); /* validate gain */
++ break;
++ case V4L2_CID_EXPOSURE:
++ /* manual exposure */
++ ret = reg16_write(client, 0x3504, 0);
++ ret |= reg16_write(client, 0x56d5, ctrl->val >> 8);
++ ret |= reg16_write(client, 0x56d6, ctrl->val & 0xff);
++ ret |= reg16_write(client, 0x3504, 1); /* validate exposure */
++ break;
++ case V4L2_CID_HFLIP:
++ ret = reg16_read(client, 0x381d, &val);
++ if (ret < 0)
++ goto out;
++ if (ctrl->val)
++ val |= 0x3;
++ else
++ val &= ~0x3;
++ ret = reg16_write(client, 0x381d, val);
++ break;
++ case V4L2_CID_VFLIP:
++ ret = reg16_read(client, 0x381c, &val);
++ if (ctrl->val)
++ val |= 0xc0;
++ else
++ val &= ~0xc0;
++ ret = reg16_write(client, 0x381c, val);
++ break;
++ case V4L2_CID_MIN_BUFFERS_FOR_CAPTURE:
++ ret = 0;
++ break;
++ }
++
++out:
++ return ret;
++}
++
++static const struct v4l2_ctrl_ops ov10635_ctrl_ops = {
++ .s_ctrl = ov10635_s_ctrl,
++};
++
++static struct v4l2_subdev_video_ops ov10635_video_ops = {
++ .s_stream = ov10635_s_stream,
++ .g_mbus_config = ov10635_g_mbus_config,
++ .g_parm = ov10635_g_parm,
++ .s_parm = ov10635_s_parm,
++};
++
++static const struct v4l2_subdev_pad_ops ov10635_subdev_pad_ops = {
++ .get_edid = ov10635_get_edid,
++ .enum_mbus_code = ov10635_enum_mbus_code,
++ .get_selection = ov10635_get_selection,
++ .set_selection = ov10635_set_selection,
++ .get_fmt = ov10635_get_fmt,
++ .set_fmt = ov10635_set_fmt,
++};
++
++static struct v4l2_subdev_ops ov10635_subdev_ops = {
++ .core = &ov10635_core_ops,
++ .video = &ov10635_video_ops,
++ .pad = &ov10635_subdev_pad_ops,
++};
++
++static void ov10635_otp_id_read(struct i2c_client *client)
++{
++ struct ov10635_priv *priv = to_ov10635(client);
++ int i;
++
++ /* read camera id from OTP memory */
++ reg16_write(client, 0x3d10, 1);
++
++ usleep_range(15000, 16000); /* wait 15ms */
++
++ for (i = 0; i < 6; i++)
++ reg16_read(client, 0x3d00 + i, &priv->id[i]);
++}
++
++static ssize_t ov10635_otp_id_show(struct device *dev,
++ struct device_attribute *attr, char *buf)
++{
++ struct v4l2_subdev *sd = i2c_get_clientdata(to_i2c_client(dev));
++ struct i2c_client *client = v4l2_get_subdevdata(sd);
++ struct ov10635_priv *priv = to_ov10635(client);
++
++ return snprintf(buf, 32, "%02x:%02x:%02x:%02x:%02x:%02x\n",
++ priv->id[0], priv->id[1], priv->id[2], priv->id[3], priv->id[4], priv->id[5]);
++}
++
++static DEVICE_ATTR(otp_id_ov10635, S_IRUGO, ov10635_otp_id_show, NULL);
++
++static int ov10635_initialize(struct i2c_client *client)
++{
++ struct ov10635_priv *priv = to_ov10635(client);
++ u8 pid = 0, ver = 0;
++ int ret = 0;
++
++ ov10635_s_port(client, 1);
++
++ /* check and show product ID and manufacturer ID */
++ reg16_read(client, OV10635_PID, &pid);
++ reg16_read(client, OV10635_VER, &ver);
++
++ if (OV10635_VERSION(pid, ver) != OV10635_VERSION_REG) {
++ dev_dbg(&client->dev, "Product ID error %x:%x\n", pid, ver);
++ ret = -ENODEV;
++ goto out;
++ }
++
++ /* s/w reset sensor */
++ reg16_write(client, 0x103, 0x1);
++ udelay(100);
++ /* Program wizard registers */
++ ov10635_set_regs(client, ov10635_regs_wizard, ARRAY_SIZE(ov10635_regs_wizard));
++ /* Set DVP bit swap */
++ reg16_write(client, 0x4709, priv->dvp_order << 4);
++ /* Read OTP IDs */
++ ov10635_otp_id_read(client);
++
++ dev_info(&client->dev, "ov10635 Product ID %x Manufacturer ID %x OTP_ID %02x:%02x:%02x:%02x:%02x:%02x\n",
++ pid, ver, priv->id[0], priv->id[1], priv->id[2], priv->id[3], priv->id[4], priv->id[5]);
++out:
++ ov10635_s_port(client, 0);
++
++ return ret;
++}
++
++static int ov10635_parse_dt(struct device_node *np, struct ov10635_priv *priv)
++{
++ struct i2c_client *client = v4l2_get_subdevdata(&priv->sd);
++ int i;
++ struct device_node *endpoint = NULL, *rendpoint = NULL;
++ int tmp_addr = 0;
++
++ for (i = 0; ; i++) {
++ endpoint = of_graph_get_next_endpoint(np, endpoint);
++ if (!endpoint)
++ break;
++
++ of_node_put(endpoint);
++
++ of_property_read_u32(endpoint, "dvp-order", &priv->dvp_order);
++
++ rendpoint = of_parse_phandle(endpoint, "remote-endpoint", 0);
++ if (!rendpoint)
++ continue;
++
++ if (!of_property_read_u32(rendpoint, "max9271-addr", &priv->max9271_addr) &&
++ !of_property_read_u32(rendpoint->parent->parent, "reg", &priv->max9286_addr) &&
++ !kstrtouint(strrchr(rendpoint->full_name, '@') + 1, 0, &priv->port))
++ break;
++
++ if (!of_property_read_u32(rendpoint, "ti9x3-addr", &priv->ti9x3_addr) &&
++ !of_property_match_string(rendpoint->parent->parent, "compatible", "ti,ti964-ti9x3") &&
++ !of_property_read_u32(rendpoint->parent->parent, "reg", &priv->ti964_addr) &&
++ !kstrtouint(strrchr(rendpoint->full_name, '@') + 1, 0, &priv->port))
++ break;
++
++ if (!of_property_read_u32(rendpoint, "ti9x3-addr", &priv->ti9x3_addr) &&
++ !of_property_match_string(rendpoint->parent->parent, "compatible", "ti,ti954-ti9x3") &&
++ !of_property_read_u32(rendpoint->parent->parent, "reg", &priv->ti954_addr) &&
++ !kstrtouint(strrchr(rendpoint->full_name, '@') + 1, 0, &priv->port))
++ break;
++ }
++
++ if (!priv->max9286_addr && !priv->ti964_addr && !priv->ti954_addr) {
++ dev_err(&client->dev, "deserializer does not present for OV10635\n");
++ return -EINVAL;
++ }
++
++ ov10635_s_port(client, 1);
++
++ /* setup I2C translator address */
++ tmp_addr = client->addr;
++ if (priv->max9286_addr) {
++ client->addr = priv->max9271_addr; /* Serializer I2C address */
++
++ reg8_write(client, 0x09, tmp_addr << 1); /* Sensor translated I2C address */
++ reg8_write(client, 0x0A, OV10635_I2C_ADDR << 1); /* Sensor native I2C address */
++ usleep_range(2000, 2500); /* wait 2ms */
++ };
++
++ if (priv->ti964_addr) {
++ client->addr = priv->ti964_addr; /* Deserializer I2C address */
++
++ reg8_write(client, 0x4c, (priv->port << 4) | (1 << priv->port)); /* Select RX port number */
++ usleep_range(2000, 2500); /* wait 2ms */
++ reg8_write(client, 0x65, tmp_addr << 1); /* Sensor translated I2C address */
++ reg8_write(client, 0x5d, OV10635_I2C_ADDR << 1); /* Sensor native I2C address */
++
++ reg8_write(client, 0x6e, 0xa9); /* GPIO0 - resetb, GPIO1 - fsin */
++ }
++
++ if (priv->ti954_addr) {
++ client->addr = priv->ti954_addr; /* Deserializer I2C address */
++
++ reg8_write(client, 0x4c, (priv->port << 4) | (1 << priv->port)); /* Select RX port number */
++ usleep_range(2000, 2500); /* wait 2ms */
++ reg8_write(client, 0x65, tmp_addr << 1); /* Sensor translated I2C address */
++ reg8_write(client, 0x5d, OV10635_I2C_ADDR << 1); /* Sensor native I2C address */
++
++ reg8_write(client, 0x6e, 0xa9); /* GPIO0 - resetb, GPIO1 - fsin */
++ }
++ client->addr = tmp_addr;
++
++ udelay(100);
++
++ return 0;
++}
++
++static int ov10635_probe(struct i2c_client *client,
++ const struct i2c_device_id *did)
++{
++ struct ov10635_priv *priv;
++ struct v4l2_ctrl *ctrl;
++ int ret;
++
++ priv = devm_kzalloc(&client->dev, sizeof(*priv), GFP_KERNEL);
++ if (!priv)
++ return -ENOMEM;
++
++ v4l2_i2c_subdev_init(&priv->sd, client, &ov10635_subdev_ops);
++ priv->sd.flags = V4L2_SUBDEV_FL_HAS_DEVNODE;
++ priv->rect.left = 0;
++ priv->rect.top = 0;
++ priv->rect.width = OV10635_MAX_WIDTH;
++ priv->rect.height = OV10635_MAX_HEIGHT;
++ priv->fps_denominator = 30;
++
++ v4l2_ctrl_handler_init(&priv->hdl, 4);
++ v4l2_ctrl_new_std(&priv->hdl, &ov10635_ctrl_ops,
++ V4L2_CID_BRIGHTNESS, 0, 0xff, 1, 0x30);
++ v4l2_ctrl_new_std(&priv->hdl, &ov10635_ctrl_ops,
++ V4L2_CID_CONTRAST, 0, 4, 1, 2);
++ v4l2_ctrl_new_std(&priv->hdl, &ov10635_ctrl_ops,
++ V4L2_CID_SATURATION, 0, 0xff, 1, 0xff);
++ v4l2_ctrl_new_std(&priv->hdl, &ov10635_ctrl_ops,
++ V4L2_CID_HUE, 0, 255, 1, 0);
++ v4l2_ctrl_new_std(&priv->hdl, &ov10635_ctrl_ops,
++ V4L2_CID_GAMMA, 0, 0xffff, 1, 0x233);
++ v4l2_ctrl_new_std(&priv->hdl, &ov10635_ctrl_ops,
++ V4L2_CID_AUTOGAIN, 0, 1, 1, 1);
++ v4l2_ctrl_new_std(&priv->hdl, &ov10635_ctrl_ops,
++ V4L2_CID_GAIN, 0, 0x3ff, 1, 0x10);
++ v4l2_ctrl_new_std(&priv->hdl, &ov10635_ctrl_ops,
++ V4L2_CID_EXPOSURE, 0, 0xffff, 1, 0x80);
++ v4l2_ctrl_new_std(&priv->hdl, &ov10635_ctrl_ops,
++ V4L2_CID_HFLIP, 0, 1, 1, 0);
++ v4l2_ctrl_new_std(&priv->hdl, &ov10635_ctrl_ops,
++ V4L2_CID_VFLIP, 0, 1, 1, 0);
++ ctrl = v4l2_ctrl_new_std(&priv->hdl, &ov10635_ctrl_ops,
++ V4L2_CID_MIN_BUFFERS_FOR_CAPTURE, 1, 32, 1, 9);
++ if (ctrl)
++ ctrl->flags &= ~V4L2_CTRL_FLAG_READ_ONLY;
++ priv->sd.ctrl_handler = &priv->hdl;
++
++ ret = priv->hdl.error;
++ if (ret)
++ goto cleanup;
++
++ v4l2_ctrl_handler_setup(&priv->hdl);
++
++ priv->pad.flags = MEDIA_PAD_FL_SOURCE;
++ priv->sd.entity.flags |= MEDIA_ENT_F_CAM_SENSOR;
++ ret = media_entity_pads_init(&priv->sd.entity, 1, &priv->pad);
++ if (ret < 0)
++ goto cleanup;
++
++ ret = ov10635_parse_dt(client->dev.of_node, priv);
++ if (ret)
++ goto cleanup;
++
++ ret = ov10635_initialize(client);
++ if (ret < 0)
++ goto cleanup;
++
++ ret = v4l2_async_register_subdev(&priv->sd);
++ if (ret)
++ goto cleanup;
++
++ if (device_create_file(&client->dev, &dev_attr_otp_id_ov10635) != 0) {
++ dev_err(&client->dev, "sysfs otp_id entry creation failed\n");
++ goto cleanup;
++ }
++
++ priv->init_complete = 1;
++
++ return 0;
++
++cleanup:
++ media_entity_cleanup(&priv->sd.entity);
++ v4l2_ctrl_handler_free(&priv->hdl);
++ v4l2_device_unregister_subdev(&priv->sd);
++#ifdef CONFIG_SOC_CAMERA_OV10635
++ v4l_err(client, "failed to probe @ 0x%02x (%s)\n",
++ client->addr, client->adapter->name);
++#endif
++ return ret;
++}
++
++static int ov10635_remove(struct i2c_client *client)
++{
++ struct ov10635_priv *priv = i2c_get_clientdata(client);
++
++ device_remove_file(&client->dev, &dev_attr_otp_id_ov10635);
++ v4l2_async_unregister_subdev(&priv->sd);
++ media_entity_cleanup(&priv->sd.entity);
++ v4l2_ctrl_handler_free(&priv->hdl);
++ v4l2_device_unregister_subdev(&priv->sd);
++
++ return 0;
++}
++
++#ifdef CONFIG_SOC_CAMERA_OV10635
++static const struct i2c_device_id ov10635_id[] = {
++ { "ov10635", 0 },
++ { }
++};
++MODULE_DEVICE_TABLE(i2c, ov10635_id);
++
++static const struct of_device_id ov10635_of_ids[] = {
++ { .compatible = "ovti,ov10635", },
++ { }
++};
++MODULE_DEVICE_TABLE(of, ov10635_of_ids);
++
++static struct i2c_driver ov10635_i2c_driver = {
++ .driver = {
++ .name = "ov10635",
++ .of_match_table = ov10635_of_ids,
++ },
++ .probe = ov10635_probe,
++ .remove = ov10635_remove,
++ .id_table = ov10635_id,
++};
++
++module_i2c_driver(ov10635_i2c_driver);
++
++MODULE_DESCRIPTION("SoC Camera driver for OV10635");
++MODULE_AUTHOR("Vladimir Barinov");
++MODULE_LICENSE("GPL");
++#endif
+diff --git a/drivers/media/i2c/soc_camera/ov10635.h b/drivers/media/i2c/soc_camera/ov10635.h
+new file mode 100644
+index 0000000..a0e510d
+--- /dev/null
++++ b/drivers/media/i2c/soc_camera/ov10635.h
+@@ -0,0 +1,1139 @@
++/*
++ * OmniVision ov10635 sensor camera wizard 1280x800@30/UYVY/BT601/8bit
++ *
++ * Copyright (C) 2015-2017 Cogent Embedded, Inc.
++ *
++ * This program is free software; you can redistribute it and/or modify it
++ * under the terms of the GNU General Public License as published by the
++ * Free Software Foundation; either version 2 of the License, or (at your
++ * option) any later version.
++ */
++
++//#define OV10635_DISPLAY_PATTERN
++
++#define OV10635_SENSOR_WIDTH 1312
++#define OV10635_SENSOR_HEIGHT 814
++
++#define OV10635_MAX_WIDTH 1280
++#define OV10635_MAX_HEIGHT 800
++
++//#define OV10635_PCLK_96MHZ
++#define OV10635_PCLK_88MHZ
++
++#if defined(OV10635_PCLK_96MHZ)
++/* VTS=PCLK/FPS/HTS/2 (=96MHz/30/1600/2) */
++ #define OV10635_HTS 1600
++ #define OV10635_VTS 1000 /* fps=30 */
++#elif defined(OV10635_PCLK_88MHZ)
++/* VTS=PCLK/FPS/HTS/2 (=88MHz/1572/30/2) */
++ #define OV10635_HTS 1572
++ #define OV10635_VTS 933 /* fps=29.9998 */
++#else
++ #error PCLK not defined
++#endif
++
++struct ov10635_reg {
++ u16 reg;
++ u8 val;
++};
++
++static const struct ov10635_reg ov10635_regs_wizard[] = {
++//{0x0103, 0x01},
++{0x300C, 0x61},
++{0x300C, 0x61},
++{0x300C, 0x61},
++{0x300C, 0x61},
++{0x300C, 0x61},
++{0x300C, 0x61},
++{0x300C, 0x61},
++{0x300C, 0x61},
++{0x300C, 0x61},
++{0x300C, 0x61},
++{0x300C, 0x61},
++{0x300C, 0x61},
++{0x300C, 0x61},
++{0x300C, 0x61},
++{0x300C, 0x61},
++{0x300C, 0x61},
++{0x300C, 0x61},
++{0x300C, 0x61},
++{0x300C, 0x61},
++{0x300C, 0x61},
++{0x300C, 0x61},
++{0x300C, 0x61},
++{0x300C, 0x61},
++{0x301B, 0xFF},
++{0x301C, 0xFF},
++{0x301A, 0xFF},
++{0x3011, 0x42},
++{0x6900, 0x0C},
++{0x6901, 0x19},
++{0x3503, 0x10},
++{0x3025, 0x03},
++#if defined(OV10635_PCLK_96MHZ)
++{0x3003, 0x20},
++{0x3004, 0x21},
++#elif defined(OV10635_PCLK_88MHZ)
++{0x3003, 0x16},
++{0x3004, 0x30},
++#endif
++{0x3005, 0x40},
++{0x3006, 0x91},
++{0x3600, 0x74},
++{0x3601, 0x2B},
++{0x3612, 0x00},
++{0x3611, 0x67},
++{0x3633, 0xCA},
++{0x3602, 0xAF},
++{0x3603, 0x04},
++{0x3630, 0x28},
++{0x3631, 0x16},
++{0x3714, 0x10},
++{0x371D, 0x01},
++{0x4300, 0x3A},
++{0x3007, 0x01},
++{0x3024, 0x03},
++{0x3020, 0x0A},
++{0x3702, 0x0D},
++{0x3703, 0x20},
++{0x3704, 0x15},
++{0x3709, 0xA8},
++{0x370C, 0xC7},
++{0x370D, 0x80},
++{0x3712, 0x00},
++{0x3713, 0x20},
++{0x3715, 0x04},
++{0x381D, 0x40},
++{0x381C, 0x00},
++{0x3822, 0x50},
++{0x3824, 0x10},
++{0x3815, 0x8C},
++{0x3804, 0x05},
++{0x3805, 0x1F},
++{0x3800, 0x00},
++{0x3801, 0x00},
++{0x3806, 0x03},
++{0x3807, 0x28},
++{0x3802, 0x00},
++{0x3803, 0x07},
++{0x3808, 0x05},
++{0x3809, 0x00},
++{0x380A, 0x03},
++{0x380B, 0x20},
++{0x380C, OV10635_HTS >> 8},
++{0x380D, OV10635_HTS & 0xff},
++{0x380E, OV10635_VTS >> 8},
++{0x380F, OV10635_VTS & 0xff},
++{0x3813, 0x02},
++{0x3811, 0x08},
++{0x381F, 0x0C},
++{0x3819, 0x04},
++{0x3804, 0x01},
++{0x3805, 0x00},
++{0x3828, 0x03},
++{0x3829, 0x10},
++{0x382A, 0x10},
++{0x3621, 0x63},
++{0x5005, 0x08},
++{0x56D5, 0x00},
++{0x56D6, 0x80},
++{0x56D7, 0x00},
++{0x56D8, 0x00},
++{0x56D9, 0x00},
++{0x56DA, 0x80},
++{0x56DB, 0x00},
++{0x56DC, 0x00},
++{0x56E8, 0x00},
++{0x56E9, 0x7F},
++{0x56EA, 0x00},
++{0x56EB, 0x7F},
++{0x5100, 0x00},
++{0x5101, 0x80},
++{0x5102, 0x00},
++{0x5103, 0x80},
++{0x5104, 0x00},
++{0x5105, 0x80},
++{0x5106, 0x00},
++{0x5107, 0x80},
++{0x5108, 0x00},
++{0x5109, 0x00},
++{0x510A, 0x00},
++{0x510B, 0x00},
++{0x510C, 0x00},
++{0x510D, 0x00},
++{0x510E, 0x00},
++{0x510F, 0x00},
++{0x5110, 0x00},
++{0x5111, 0x80},
++{0x5112, 0x00},
++{0x5113, 0x80},
++{0x5114, 0x00},
++{0x5115, 0x80},
++{0x5116, 0x00},
++{0x5117, 0x80},
++{0x5118, 0x00},
++{0x5119, 0x00},
++{0x511A, 0x00},
++{0x511B, 0x00},
++{0x511C, 0x00},
++{0x511D, 0x00},
++{0x511E, 0x00},
++{0x511F, 0x00},
++{0x56D0, 0x00},
++{0x5006, 0x04},
++{0x5608, 0x05},
++{0x52D7, 0x06},
++{0x528D, 0x08},
++{0x5293, 0x12},
++{0x52D3, 0x12},
++{0x5288, 0x06},
++{0x5289, 0x20},
++{0x52C8, 0x06},
++{0x52C9, 0x20},
++{0x52CD, 0x04},
++{0x5381, 0x00},
++{0x5382, 0xFF},
++{0x5589, 0x76},
++{0x558A, 0x47},
++{0x558B, 0xEF},
++{0x558C, 0xC9},
++{0x558D, 0x49},
++{0x558E, 0x30},
++{0x558F, 0x67},
++{0x5590, 0x3F},
++{0x5591, 0xF0},
++{0x5592, 0x10},
++{0x55A2, 0x6D},
++{0x55A3, 0x55},
++{0x55A4, 0xC3},
++{0x55A5, 0xB5},
++{0x55A6, 0x43},
++{0x55A7, 0x38},
++{0x55A8, 0x5F},
++{0x55A9, 0x4B},
++{0x55AA, 0xF0},
++{0x55AB, 0x10},
++{0x5581, 0x52},
++{0x5300, 0x01},
++{0x5301, 0x00},
++{0x5302, 0x00},
++{0x5303, 0x0E},
++{0x5304, 0x00},
++{0x5305, 0x0E},
++{0x5306, 0x00},
++{0x5307, 0x36},
++{0x5308, 0x00},
++{0x5309, 0xD9},
++{0x530A, 0x00},
++{0x530B, 0x0F},
++{0x530C, 0x00},
++{0x530D, 0x2C},
++{0x530E, 0x00},
++{0x530F, 0x59},
++{0x5310, 0x00},
++{0x5311, 0x7B},
++{0x5312, 0x00},
++{0x5313, 0x22},
++{0x5314, 0x00},
++{0x5315, 0xD5},
++{0x5316, 0x00},
++{0x5317, 0x13},
++{0x5318, 0x00},
++{0x5319, 0x18},
++{0x531A, 0x00},
++{0x531B, 0x26},
++{0x531C, 0x00},
++{0x531D, 0xDC},
++{0x531E, 0x00},
++{0x531F, 0x02},
++{0x5320, 0x00},
++{0x5321, 0x24},
++{0x5322, 0x00},
++{0x5323, 0x56},
++{0x5324, 0x00},
++{0x5325, 0x85},
++{0x5326, 0x00},
++{0x5327, 0x20},
++{0x5609, 0x01},
++{0x560A, 0x40},
++{0x560B, 0x01},
++{0x560C, 0x40},
++{0x560D, 0x00},
++{0x560E, 0xFA},
++{0x560F, 0x00},
++{0x5610, 0xFA},
++{0x5611, 0x02},
++{0x5612, 0x80},
++{0x5613, 0x02},
++{0x5614, 0x80},
++{0x5615, 0x01},
++{0x5616, 0x2C},
++{0x5617, 0x01},
++{0x5618, 0x2C},
++{0x563B, 0x01},
++{0x563C, 0x01},
++{0x563D, 0x01},
++{0x563E, 0x01},
++{0x563F, 0x03},
++{0x5640, 0x03},
++{0x5641, 0x03},
++{0x5642, 0x05},
++{0x5643, 0x09},
++{0x5644, 0x05},
++{0x5645, 0x05},
++{0x5646, 0x05},
++{0x5647, 0x05},
++{0x5651, 0x00},
++{0x5652, 0x80},
++{0x521A, 0x01},
++{0x521B, 0x03},
++{0x521C, 0x06},
++{0x521D, 0x0A},
++{0x521E, 0x0E},
++{0x521F, 0x12},
++{0x5220, 0x16},
++{0x5223, 0x02},
++{0x5225, 0x04},
++{0x5227, 0x08},
++{0x5229, 0x0C},
++{0x522B, 0x12},
++{0x522D, 0x18},
++{0x522F, 0x1E},
++{0x5241, 0x04},
++{0x5242, 0x01},
++{0x5243, 0x03},
++{0x5244, 0x06},
++{0x5245, 0x0A},
++{0x5246, 0x0E},
++{0x5247, 0x12},
++{0x5248, 0x16},
++{0x524A, 0x03},
++{0x524C, 0x04},
++{0x524E, 0x08},
++{0x5250, 0x0C},
++{0x5252, 0x12},
++{0x5254, 0x18},
++{0x5256, 0x1E},
++{0x4606, (2*OV10635_HTS) >> 8}, /* fifo_line_length = 2*hts */
++{0x4607, (2*OV10635_HTS) & 0xff},
++{0x460a, (2*(OV10635_HTS-OV10635_MAX_WIDTH)) >> 8}, /* fifo_hsync_start = 2*(hts - xres) */
++{0x460b, (2*(OV10635_HTS-OV10635_MAX_WIDTH)) & 0xff },
++{0x460C, 0x00},
++{0x4620, 0x0E},
++#if 0
++{0x4700, 0x02}, // BT656: mode is acceptable but artefact lines on left/bottom due to BT656 SAV/EAV are parsed as image data
++#else
++{0x4700, 0x04}, // BT601: 0x08 is also accaptable as HS/VS mode
++#endif
++{0x4701, 0x00},
++{0x4702, 0x01},
++{0x4004, 0x04},
++{0x4005, 0x18},
++{0x4001, 0x06},
++{0x4050, 0x22},
++{0x4051, 0x24},
++{0x4052, 0x02},
++{0x4057, 0x9C},
++{0x405A, 0x00},
++{0x4202, 0x02},
++{0x3023, 0x10},
++{0x0100, 0x01},
++{0x0100, 0x01},
++{0x6F10, 0x07},
++{0x6F11, 0x82},
++{0x6F12, 0x04},
++{0x6F13, 0x00},
++{0xD000, 0x19},
++{0xD001, 0xA0},
++{0xD002, 0x00},
++{0xD003, 0x01},
++{0xD004, 0xA9},
++{0xD005, 0xAD},
++{0xD006, 0x10},
++{0xD007, 0x40},
++{0xD008, 0x44},
++{0xD009, 0x00},
++{0xD00A, 0x68},
++{0xD00B, 0x00},
++{0xD00C, 0x15},
++{0xD00D, 0x00},
++{0xD00E, 0x00},
++{0xD00F, 0x00},
++{0xD040, 0x9C},
++{0xD041, 0x21},
++{0xD042, 0xFF},
++{0xD043, 0xF8},
++{0xD044, 0xD4},
++{0xD045, 0x01},
++{0xD046, 0x48},
++{0xD047, 0x00},
++{0xD048, 0xD4},
++{0xD049, 0x01},
++{0xD04A, 0x50},
++{0xD04B, 0x04},
++{0xD04C, 0x18},
++{0xD04D, 0x60},
++{0xD04E, 0x00},
++{0xD04F, 0x01},
++{0xD050, 0xA8},
++{0xD051, 0x63},
++{0xD052, 0x02},
++{0xD053, 0xA4},
++{0xD054, 0x85},
++{0xD055, 0x43},
++{0xD056, 0x00},
++{0xD057, 0x00},
++{0xD058, 0x18},
++{0xD059, 0x60},
++{0xD05A, 0x00},
++{0xD05B, 0x01},
++{0xD05C, 0xA8},
++{0xD05D, 0x63},
++{0xD05E, 0x03},
++{0xD05F, 0xF0},
++{0xD060, 0x98},
++{0xD061, 0xA3},
++{0xD062, 0x00},
++{0xD063, 0x00},
++{0xD064, 0x8C},
++{0xD065, 0x6A},
++{0xD066, 0x00},
++{0xD067, 0x6E},
++{0xD068, 0xE5},
++{0xD069, 0x85},
++{0xD06A, 0x18},
++{0xD06B, 0x00},
++{0xD06C, 0x10},
++{0xD06D, 0x00},
++{0xD06E, 0x00},
++{0xD06F, 0x10},
++{0xD070, 0x9C},
++{0xD071, 0x80},
++{0xD072, 0x00},
++{0xD073, 0x03},
++{0xD074, 0x18},
++{0xD075, 0x60},
++{0xD076, 0x00},
++{0xD077, 0x01},
++{0xD078, 0xA8},
++{0xD079, 0x63},
++{0xD07A, 0x07},
++{0xD07B, 0x80},
++{0xD07C, 0x07},
++{0xD07D, 0xFF},
++{0xD07E, 0xF9},
++{0xD07F, 0x03},
++{0xD080, 0x8C},
++{0xD081, 0x63},
++{0xD082, 0x00},
++{0xD083, 0x00},
++{0xD084, 0xA5},
++{0xD085, 0x6B},
++{0xD086, 0x00},
++{0xD087, 0xFF},
++{0xD088, 0x18},
++{0xD089, 0x80},
++{0xD08A, 0x00},
++{0xD08B, 0x01},
++{0xD08C, 0xA8},
++{0xD08D, 0x84},
++{0xD08E, 0x01},
++{0xD08F, 0x04},
++{0xD090, 0xE1},
++{0xD091, 0x6B},
++{0xD092, 0x58},
++{0xD093, 0x00},
++{0xD094, 0x94},
++{0xD095, 0x6A},
++{0xD096, 0x00},
++{0xD097, 0x70},
++{0xD098, 0xE1},
++{0xD099, 0x6B},
++{0xD09A, 0x20},
++{0xD09B, 0x00},
++{0xD09C, 0x95},
++{0xD09D, 0x6B},
++{0xD09E, 0x00},
++{0xD09F, 0x00},
++{0xD0A0, 0xE4},
++{0xD0A1, 0x8B},
++{0xD0A2, 0x18},
++{0xD0A3, 0x00},
++{0xD0A4, 0x0C},
++{0xD0A5, 0x00},
++{0xD0A6, 0x00},
++{0xD0A7, 0x23},
++{0xD0A8, 0x15},
++{0xD0A9, 0x00},
++{0xD0AA, 0x00},
++{0xD0AB, 0x00},
++{0xD0AC, 0x18},
++{0xD0AD, 0x60},
++{0xD0AE, 0x80},
++{0xD0AF, 0x06},
++{0xD0B0, 0xA8},
++{0xD0B1, 0x83},
++{0xD0B2, 0x40},
++{0xD0B3, 0x08},
++{0xD0B4, 0xA8},
++{0xD0B5, 0xE3},
++{0xD0B6, 0x38},
++{0xD0B7, 0x2A},
++{0xD0B8, 0xA8},
++{0xD0B9, 0xC3},
++{0xD0BA, 0x40},
++{0xD0BB, 0x09},
++{0xD0BC, 0xA8},
++{0xD0BD, 0xA3},
++{0xD0BE, 0x38},
++{0xD0BF, 0x29},
++{0xD0C0, 0x8C},
++{0xD0C1, 0x65},
++{0xD0C2, 0x00},
++{0xD0C3, 0x00},
++{0xD0C4, 0xD8},
++{0xD0C5, 0x04},
++{0xD0C6, 0x18},
++{0xD0C7, 0x00},
++{0xD0C8, 0x8C},
++{0xD0C9, 0x67},
++{0xD0CA, 0x00},
++{0xD0CB, 0x00},
++{0xD0CC, 0xD8},
++{0xD0CD, 0x06},
++{0xD0CE, 0x18},
++{0xD0CF, 0x00},
++{0xD0D0, 0x18},
++{0xD0D1, 0x60},
++{0xD0D2, 0x80},
++{0xD0D3, 0x06},
++{0xD0D4, 0xA8},
++{0xD0D5, 0xE3},
++{0xD0D6, 0x67},
++{0xD0D7, 0x02},
++{0xD0D8, 0xA9},
++{0xD0D9, 0x03},
++{0xD0DA, 0x67},
++{0xD0DB, 0x03},
++{0xD0DC, 0xA8},
++{0xD0DD, 0xC3},
++{0xD0DE, 0x3D},
++{0xD0DF, 0x05},
++{0xD0E0, 0x8C},
++{0xD0E1, 0x66},
++{0xD0E2, 0x00},
++{0xD0E3, 0x00},
++{0xD0E4, 0xB8},
++{0xD0E5, 0x63},
++{0xD0E6, 0x00},
++{0xD0E7, 0x18},
++{0xD0E8, 0xB8},
++{0xD0E9, 0x63},
++{0xD0EA, 0x00},
++{0xD0EB, 0x98},
++{0xD0EC, 0xBC},
++{0xD0ED, 0x03},
++{0xD0EE, 0x00},
++{0xD0EF, 0x00},
++{0xD0F0, 0x10},
++{0xD0F1, 0x00},
++{0xD0F2, 0x00},
++{0xD0F3, 0x16},
++{0xD0F4, 0xB8},
++{0xD0F5, 0x83},
++{0xD0F6, 0x00},
++{0xD0F7, 0x19},
++{0xD0F8, 0x8C},
++{0xD0F9, 0x67},
++{0xD0FA, 0x00},
++{0xD0FB, 0x00},
++{0xD0FC, 0xB8},
++{0xD0FD, 0xA4},
++{0xD0FE, 0x00},
++{0xD0FF, 0x98},
++{0xD100, 0xB8},
++{0xD101, 0x83},
++{0xD102, 0x00},
++{0xD103, 0x08},
++{0xD104, 0x8C},
++{0xD105, 0x68},
++{0xD106, 0x00},
++{0xD107, 0x00},
++{0xD108, 0xE0},
++{0xD109, 0x63},
++{0xD10A, 0x20},
++{0xD10B, 0x04},
++{0xD10C, 0xE0},
++{0xD10D, 0x65},
++{0xD10E, 0x18},
++{0xD10F, 0x00},
++{0xD110, 0xA4},
++{0xD111, 0x83},
++{0xD112, 0xFF},
++{0xD113, 0xFF},
++{0xD114, 0xB8},
++{0xD115, 0x64},
++{0xD116, 0x00},
++{0xD117, 0x48},
++{0xD118, 0xD8},
++{0xD119, 0x07},
++{0xD11A, 0x18},
++{0xD11B, 0x00},
++{0xD11C, 0xD8},
++{0xD11D, 0x08},
++{0xD11E, 0x20},
++{0xD11F, 0x00},
++{0xD120, 0x9C},
++{0xD121, 0x60},
++{0xD122, 0x00},
++{0xD123, 0x00},
++{0xD124, 0xD8},
++{0xD125, 0x06},
++{0xD126, 0x18},
++{0xD127, 0x00},
++{0xD128, 0x00},
++{0xD129, 0x00},
++{0xD12A, 0x00},
++{0xD12B, 0x08},
++{0xD12C, 0x15},
++{0xD12D, 0x00},
++{0xD12E, 0x00},
++{0xD12F, 0x00},
++{0xD130, 0x8C},
++{0xD131, 0x6A},
++{0xD132, 0x00},
++{0xD133, 0x76},
++{0xD134, 0xBC},
++{0xD135, 0x23},
++{0xD136, 0x00},
++{0xD137, 0x00},
++{0xD138, 0x13},
++{0xD139, 0xFF},
++{0xD13A, 0xFF},
++{0xD13B, 0xE6},
++{0xD13C, 0x18},
++{0xD13D, 0x60},
++{0xD13E, 0x80},
++{0xD13F, 0x06},
++{0xD140, 0x03},
++{0xD141, 0xFF},
++{0xD142, 0xFF},
++{0xD143, 0xDD},
++{0xD144, 0xA8},
++{0xD145, 0x83},
++{0xD146, 0x40},
++{0xD147, 0x08},
++{0xD148, 0x85},
++{0xD149, 0x21},
++{0xD14A, 0x00},
++{0xD14B, 0x00},
++{0xD14C, 0x85},
++{0xD14D, 0x41},
++{0xD14E, 0x00},
++{0xD14F, 0x04},
++{0xD150, 0x44},
++{0xD151, 0x00},
++{0xD152, 0x48},
++{0xD153, 0x00},
++{0xD154, 0x9C},
++{0xD155, 0x21},
++{0xD156, 0x00},
++{0xD157, 0x08},
++{0x6F0E, 0x03},
++{0x6F0F, 0x00},
++{0x460E, 0x08},
++{0x460F, 0x01},
++{0x4610, 0x00},
++{0x4611, 0x01},
++{0x4612, 0x00},
++{0x4613, 0x01},
++{0x4605, 0x08}, // 8bit
++//{0x4709, 0x10}, // swap data bits order [9:0] -> [0:9]
++{0x4608, 0x00},
++{0x4609, 0x08},
++{0x6804, 0x00},
++{0x6805, 0x06},
++{0x6806, 0x00},
++{0x5120, 0x00},
++{0x3510, 0x00},
++{0x3504, 0x00},
++{0x6800, 0x00},
++{0x6F0D, 0x01},
++{0x4708, 0x01}, // PCLK rising edge
++{0x5000, 0xFF},
++{0x5001, 0xBF},
++{0x5002, 0x7E},
++#ifdef OV10635_DISPLAY_PATTERN
++{0x503d, 0x80},
++#else
++{0x503D, 0x00},
++#endif
++{0xC450, 0x01}, /* AA mode */
++{0xC452, 0x04},
++{0xC453, 0x00},
++{0xC454, 0x00},
++{0xC455, 0x01},
++{0xC456, 0x01},
++{0xC457, 0x00},
++{0xC458, 0x00},
++{0xC459, 0x00},
++{0xC45B, 0x00},
++{0xC45C, 0x01},
++{0xC45D, 0x00},
++{0xC45E, 0x00},
++{0xC45F, 0x00},
++{0xC460, 0x00},
++{0xC461, 0x01},
++{0xC462, 0x01},
++{0xC464, 0x03},
++{0xC465, 0x00},
++{0xC466, 0x8A},
++{0xC467, 0x00},
++{0xC468, 0x86},
++{0xC469, 0x00},
++{0xC46A, 0x30},
++{0xC46B, 0x50},
++{0xC46C, 0x30},
++{0xC46D, 0x28},
++{0xC46E, 0x60},
++{0xC46F, 0x40},
++{0xC47C, 0x01},
++{0xC47D, 0x38},
++{0xC47E, 0x00},
++{0xC47F, 0x00},
++{0xC480, 0x00},
++{0xC481, 0xFF},
++{0xC482, 0x00},
++{0xC483, 0x40},
++{0xC484, 0x00},
++{0xC485, 0x18},
++{0xC486, 0x00},
++{0xC487, 0x18},
++{0xC488, (OV10635_VTS-8)*16 >> 8},
++{0xC489, (OV10635_VTS-8)*16 & 0xff},
++{0xC48A, (OV10635_VTS-8)*16 >> 8},
++{0xC48B, (OV10635_VTS-8)*16 & 0xff},
++{0xC48C, 0x00},
++{0xC48D, 0x04},
++{0xC48E, 0x00},
++{0xC48F, 0x04},
++{0xC490, 0x03},
++{0xC492, 0x20},
++{0xC493, 0x08},
++{0xC498, 0x02},
++{0xC499, 0x00},
++{0xC49A, 0x02},
++{0xC49B, 0x00},
++{0xC49C, 0x02},
++{0xC49D, 0x00},
++{0xC49E, 0x02},
++{0xC49F, 0x60},
++{0xC4A0, 0x03},
++{0xC4A1, 0x00},
++{0xC4A2, 0x04},
++{0xC4A3, 0x00},
++{0xC4A4, 0x00},
++{0xC4A5, 0x10},
++{0xC4A6, 0x00},
++{0xC4A7, 0x40},
++{0xC4A8, 0x00},
++{0xC4A9, 0x80},
++{0xC4AA, 0x0D},
++{0xC4AB, 0x00},
++{0xC4AC, 0x0F},
++{0xC4AD, 0xC0},
++{0xC4B4, 0x01},
++{0xC4B5, 0x01},
++{0xC4B6, 0x00},
++{0xC4B7, 0x01},
++{0xC4B8, 0x00},
++{0xC4B9, 0x01},
++{0xC4BA, 0x01},
++{0xC4BB, 0x00},
++{0xC4BC, 0x01},
++{0xC4BD, 0x60},
++{0xC4BE, 0x02},
++{0xC4BF, 0x33},
++{0xC4C8, 0x03},
++{0xC4C9, 0xD0},
++{0xC4CA, 0x0E},
++{0xC4CB, 0x00},
++{0xC4CC, 0x0E},
++{0xC4CD, 0x51},
++{0xC4CE, 0x0E},
++{0xC4CF, 0x51},
++{0xC4D0, 0x04},
++{0xC4D1, 0x80},
++{0xC4E0, 0x04},
++{0xC4E1, 0x02},
++{0xC4E2, 0x01},
++{0xC4E4, 0x10},
++{0xC4E5, 0x20},
++{0xC4E6, 0x30},
++{0xC4E7, 0x40},
++{0xC4E8, 0x50},
++{0xC4E9, 0x60},
++{0xC4EA, 0x70},
++{0xC4EB, 0x80},
++{0xC4EC, 0x90},
++{0xC4ED, 0xA0},
++{0xC4EE, 0xB0},
++{0xC4EF, 0xC0},
++{0xC4F0, 0xD0},
++{0xC4F1, 0xE0},
++{0xC4F2, 0xF0},
++{0xC4F3, 0x80},
++{0xC4F4, 0x00},
++{0xC4F5, 0x20},
++{0xC4F6, 0x02},
++{0xC4F7, 0x00},
++{0xC4F8, 0x00},
++{0xC4F9, 0x00},
++{0xC4FA, 0x00},
++{0xC4FB, 0x01},
++{0xC4FC, 0x01},
++{0xC4FD, 0x00},
++{0xC4FE, 0x04},
++{0xC4FF, 0x02},
++{0xC500, 0x48},
++{0xC501, 0x74},
++{0xC502, 0x58},
++{0xC503, 0x80},
++{0xC504, 0x05},
++{0xC505, 0x80},
++{0xC506, 0x03},
++{0xC507, 0x80},
++{0xC508, 0x01},
++{0xC509, 0xC0},
++{0xC50A, 0x01},
++{0xC50B, 0xA0},
++{0xC50C, 0x01},
++{0xC50D, 0x2C},
++{0xC50E, 0x01},
++{0xC50F, 0x0A},
++{0xC510, 0x00},
++{0xC511, 0x00},
++{0xC512, 0xE5},
++{0xC513, 0x14},
++{0xC514, 0x04},
++{0xC515, 0x00},
++{0xC518, OV10635_VTS >> 8},
++{0xC519, OV10635_VTS & 0xff},
++{0xC51A, OV10635_HTS >> 8},
++{0xC51B, OV10635_HTS & 0xff},
++{0xC2E0, 0x00},
++{0xC2E1, 0x51},
++{0xC2E2, 0x00},
++{0xC2E3, 0xD6},
++{0xC2E4, 0x01},
++{0xC2E5, 0x5E},
++{0xC2E9, 0x01},
++{0xC2EA, 0x7A},
++{0xC2EB, 0x90},
++{0xC2ED, 0x00},
++{0xC2EE, 0x7A},
++{0xC2EF, 0x64},
++{0xC308, 0x00},
++{0xC309, 0x00},
++{0xC30A, 0x00},
++{0xC30C, 0x00},
++{0xC30D, 0x01},
++{0xC30E, 0x00},
++{0xC30F, 0x00},
++{0xC310, 0x01},
++{0xC311, 0x60},
++{0xC312, 0xFF},
++{0xC313, 0x08},
++{0xC314, 0x01},
++{0xC315, 0x00}, /* min saturation gain */
++{0xC316, 0xFF}, /* max saturation gain */
++{0xC317, 0x0B},
++{0xC318, 0x00},
++{0xC319, 0x0C},
++{0xC31A, 0x00},
++{0xC31B, 0xE0},
++{0xC31C, 0x00},
++{0xC31D, 0x14},
++{0xC31E, 0x00},
++{0xC31F, 0xC5},
++{0xC320, 0xFF},
++{0xC321, 0x4B},
++{0xC322, 0xFF},
++{0xC323, 0xF0},
++{0xC324, 0xFF},
++{0xC325, 0xE8},
++{0xC326, 0x00},
++{0xC327, 0x46},
++{0xC328, 0xFF},
++{0xC329, 0xD2},
++{0xC32A, 0xFF},
++{0xC32B, 0xE4},
++{0xC32C, 0xFF},
++{0xC32D, 0xBB},
++{0xC32E, 0x00},
++{0xC32F, 0x61},
++{0xC330, 0xFF},
++{0xC331, 0xF9},
++{0xC332, 0x00},
++{0xC333, 0xD9},
++{0xC334, 0x00},
++{0xC335, 0x2E},
++{0xC336, 0x00},
++{0xC337, 0xB1},
++{0xC338, 0xFF},
++{0xC339, 0x64},
++{0xC33A, 0xFF},
++{0xC33B, 0xEB},
++{0xC33C, 0xFF},
++{0xC33D, 0xE8},
++{0xC33E, 0x00},
++{0xC33F, 0x48},
++{0xC340, 0xFF},
++{0xC341, 0xD0},
++{0xC342, 0xFF},
++{0xC343, 0xED},
++{0xC344, 0xFF},
++{0xC345, 0xAD},
++{0xC346, 0x00},
++{0xC347, 0x66},
++{0xC348, 0x01},
++{0xC349, 0x00},
++{0x6700, 0x04},
++{0x6701, 0x7B},
++{0x6702, 0xFD},
++{0x6703, 0xF9},
++{0x6704, 0x3D},
++{0x6705, 0x71},
++{0x6706, 0x78},
++{0x6708, 0x05},
++{0x6F06, 0x6F},
++{0x6F07, 0x00},
++{0x6F0A, 0x6F},
++{0x6F0B, 0x00},
++{0x6F00, 0x03},
++{0xC34C, 0x01},
++{0xC34D, 0x00},
++{0xC34E, 0x46},
++{0xC34F, 0x55},
++{0xC350, 0x00},
++{0xC351, 0x40},
++{0xC352, 0x00},
++{0xC353, 0xFF},
++{0xC354, 0x04},
++{0xC355, 0x08},
++{0xC356, 0x01},
++{0xC357, 0xEF},
++{0xC358, 0x30},
++{0xC359, 0x01},
++{0xC35A, 0x64},
++{0xC35B, 0x46},
++{0xC35C, 0x00},
++{0x3042, 0xF0},
++{0x3042, 0xF0},
++{0x3042, 0xF0},
++{0x3042, 0xF0},
++{0x3042, 0xF0},
++{0x3042, 0xF0},
++{0x3042, 0xF0},
++{0x3042, 0xF0},
++{0x3042, 0xF0},
++{0x3042, 0xF0},
++{0x3042, 0xF0},
++{0x3042, 0xF0},
++{0x3042, 0xF0},
++{0x3042, 0xF0},
++{0x3042, 0xF0},
++{0x3042, 0xF0},
++{0x3042, 0xF0},
++{0x3042, 0xF0},
++{0x3042, 0xF0},
++{0x3042, 0xF0},
++{0x3042, 0xF0},
++{0x3042, 0xF0},
++{0x3042, 0xF0},
++{0x3042, 0xF0},
++{0x3042, 0xF0},
++{0x3042, 0xF0},
++{0xC261, 0x01},
++{0x301B, 0xF0},
++{0x301C, 0xF0},
++{0x301A, 0xF0},
++{0x6F00, 0xC3},
++{0xC46A, 0x30},
++{0xC46D, 0x20},
++{0xC464, 0x84},
++{0xC465, 0x00},
++{0x6F00, 0x03},
++{0x6F00, 0x43},
++{0x381C, 0x00},
++{0x381D, 0x40},
++{0xC454, 0x01},
++{0x6F00, 0xC3},
++{0xC454, 0x00},
++{0xC4B1, 0x02},
++{0xC4B2, 0x01},
++{0xC4B3, 0x03},
++{0x6F00, 0x03},
++{0x6F00, 0x43},
++/* enable FSIN (FRAMESYNC input) functionality */
++{0x3832, (0x0d+2*0x20+0x15+38) >> 8},
++{0x3833, (0x0d+2*0x20+0x15+38) & 0xff},
++{0x3834, OV10635_VTS >> 8},
++{0x3835, OV10635_VTS & 0xff},
++{0x302E, 0x01},
++};
++
++static const struct ov10635_reg ov10635_regs_30fps[] = {
++/* disable clocks */
++{0x301b, 0xff},
++{0x301c, 0xff},
++{0x301a, 0xff},
++/* clk = 24Mhz/2*32/2(1+1)=96Mhz, 30fps */
++{0x3003, 0x20},
++{0x3004, 0x21},
++/* enable clocks */
++{0x301b, 0xf0},
++{0x301c, 0xf0},
++{0x301a, 0xf0},
++};
++
++static const struct ov10635_reg ov10635_regs_15fps[] = {
++/* disable clocks */
++{0x301b, 0xff},
++{0x301c, 0xff},
++{0x301a, 0xff},
++/* clk = 24Mhz/2*32/2(1+3)=48Mhz, 15fps */
++{0x3003, 0x20},
++{0x3004, 0x23},
++/* enable clocks */
++{0x301b, 0xf0},
++{0x301c, 0xf0},
++{0x301a, 0xf0},
++};
++
++static const struct ov10635_reg ov10635_regs_10fps[] = {
++/* disable clocks */
++{0x301b, 0xff},
++{0x301c, 0xff},
++{0x301a, 0xff},
++/* clk = 24Mhz/2*32/2(1+5)=32Mhz, 10fps */
++{0x3003, 0x20},
++{0x3004, 0x25},
++/* enable clocks */
++{0x301b, 0xf0},
++{0x301c, 0xf0},
++{0x301a, 0xf0},
++};
++
++static const struct ov10635_reg ov10635_regs_5fps[] = {
++/* disable clocks */
++{0x301b, 0xff},
++{0x301c, 0xff},
++{0x301a, 0xff},
++/* clk = 24Mhz/4*32/2(1+5)=96Mhz, 5fps */
++{0x3003, 0x20},
++{0x3004, 0x45},
++/* enable clocks */
++{0x301b, 0xf0},
++{0x301c, 0xf0},
++{0x301a, 0xf0},
++};
++
++static const struct ov10635_reg ov10635_regs_contrast[5][18] = {
++{
++ {0x6f00, 0xc3},
++ {0xc4e4, 0x20},
++ {0xc4e5, 0x40},
++ {0xc4e6, 0x60},
++ {0xc4e7, 0x80},
++ {0xc4e8, 0xa0},
++ {0xc4e9, 0xb4},
++ {0xc4ea, 0xc0},
++ {0xc4eb, 0xcb},
++ {0xc4ec, 0xd5},
++ {0xc4ed, 0xde},
++ {0xc4ee, 0xe6},
++ {0xc4ef, 0xed},
++ {0xc4f0, 0xf3},
++ {0xc4f1, 0xf8},
++ {0xc4f2, 0xfc},
++ {0x6f00, 0x03},
++ {0x6f00, 0x43},
++}, {
++ {0x6f00, 0xc3},
++ {0xc4e4, 0x18},
++ {0xc4e5, 0x30},
++ {0xc4e6, 0x48},
++ {0xc4e7, 0x60},
++ {0xc4e8, 0x78},
++ {0xc4e9, 0x90},
++ {0xc4ea, 0xa4},
++ {0xc4eb, 0xb4},
++ {0xc4ec, 0xc2},
++ {0xc4ed, 0xcf},
++ {0xc4ee, 0xdb},
++ {0xc4ef, 0xe5},
++ {0xc4f0, 0xee},
++ {0xc4f1, 0xf6},
++ {0xc4f2, 0xfc},
++ {0x6f00, 0x03},
++ {0x6f00, 0x43},
++}, {
++ {0x6f00, 0xc3},
++ {0xc4e4, 0x10},
++ {0xc4e5, 0x20},
++ {0xc4e6, 0x30},
++ {0xc4e7, 0x40},
++ {0xc4e8, 0x50},
++ {0xc4e9, 0x60},
++ {0xc4ea, 0x70},
++ {0xc4eb, 0x80},
++ {0xc4ec, 0x90},
++ {0xc4ed, 0xa0},
++ {0xc4ee, 0xb0},
++ {0xc4ef, 0xc0},
++ {0xc4f0, 0xd0},
++ {0xc4f1, 0xe0},
++ {0xc4f2, 0xf0},
++ {0x6f00, 0x03},
++ {0x6f00, 0x43},
++}, {
++ {0x6f00, 0xc3},
++ {0xc4e4, 0x0c},
++ {0xc4e5, 0x18},
++ {0xc4e6, 0x24},
++ {0xc4e7, 0x30},
++ {0xc4e8, 0x3c},
++ {0xc4e9, 0x48},
++ {0xc4ea, 0x54},
++ {0xc4eb, 0x62},
++ {0xc4ec, 0x72},
++ {0xc4ed, 0x84},
++ {0xc4ee, 0x94},
++ {0xc4ef, 0xa6},
++ {0xc4f0, 0xb9},
++ {0xc4f1, 0xcd},
++ {0xc4f2, 0xe2},
++ {0x6f00, 0x03},
++ {0x6f00, 0x43},
++}, {
++ {0x6f00, 0xc3},
++ {0xc4e4, 0x06},
++ {0xc4e5, 0x0d},
++ {0xc4e6, 0x15},
++ {0xc4e7, 0x1e},
++ {0xc4e8, 0x28},
++ {0xc4e9, 0x32},
++ {0xc4ea, 0x3c},
++ {0xc4eb, 0x48},
++ {0xc4ec, 0x56},
++ {0xc4ed, 0x66},
++ {0xc4ee, 0x78},
++ {0xc4ef, 0x8c},
++ {0xc4f0, 0xa2},
++ {0xc4f1, 0xba},
++ {0xc4f2, 0xd4},
++ {0x6f00, 0x03},
++ {0x6f00, 0x43},
++}
++};
+diff --git a/drivers/media/i2c/soc_camera/ov10635_debug.h b/drivers/media/i2c/soc_camera/ov10635_debug.h
+new file mode 100644
+index 0000000..4c3515a
+--- /dev/null
++++ b/drivers/media/i2c/soc_camera/ov10635_debug.h
+@@ -0,0 +1,54 @@
++
++#if 0
++{0x4700, 0x02}, // BT656
++{0x381d, 0x40}, // mirror off
++{0x381c, 0x00}, // flip off
++{0x4300, 0x3a}, // YUV: UYVY
++{0x4708, 0x00}, // PCLK rising edge
++
++// clk = 24Mhz/3*22/2= 88Mhz
++{0x3003, 0x16},
++{0x3004, 0x30},
++#endif
++
++#define WIDTH 1280
++#define HEIGHT 720
++
++// DVP frame size
++{0x3808, WIDTH >> 8},
++{0x3809, WIDTH & 0xff},
++{0x380a, HEIGHT >> 8},
++{0x380b, HEIGHT & 0xff},
++
++{0x3802, ((814 - HEIGHT)/2) >> 8}, // vert crop start
++{0x3803, ((814 - HEIGHT)/2) & 0xff},
++{0x3806, ((814 - HEIGHT)/2 + HEIGHT + 1) >> 8}, // vert crop end
++{0x3807, ((814 - HEIGHT)/2 + HEIGHT + 1) & 0xff},
++
++#if 0
++#define HTS 0x6f6 // got from above table 1782
++#define VTS (0x2ec+80) // got from above table 748 + 80
++
++{0x380c, HTS >> 8}, // hts
++{0x380d, HTS & 0xff},
++{0x380e, VTS >> 8}, // vts
++{0x380f, VTS & 0xff},
++
++// fifo
++{0x4606, (2*HTS) >> 8}, // fifo_line_length = 2*hts
++{0x4607, (2*HTS) & 0xff},
++{0x460a, (2*(HTS-1280)) >> 8}, // fifo_hsync_start = 2*(hts - xres)
++{0x460b, (2*(HTS-1280)) & 0xff },
++
++// exposure
++{0xC488, (VTS-8)*16 >> 8},
++{0xC489, (VTS-8)*16 & 0xff},
++{0xC48A, (VTS-8)*16 >> 8},
++{0xC48B, (VTS-8)*16 & 0xff},
++
++// vts/hts
++{0xC518, VTS >> 8},
++{0xC519, VTS & 0xff},
++{0xC51A, HTS >> 8},
++{0xC51B, HTS & 0xff},
++#endif
+diff --git a/drivers/media/i2c/soc_camera/ov106xx.c b/drivers/media/i2c/soc_camera/ov106xx.c
+new file mode 100644
+index 0000000..fa775ae
+--- /dev/null
++++ b/drivers/media/i2c/soc_camera/ov106xx.c
+@@ -0,0 +1,139 @@
++/*
++ * OmniVision ov10635/ov490-ov10640/ov495-ov2775 sensor camera driver
++ *
++ * Copyright (C) 2016-2017 Cogent Embedded, Inc.
++ *
++ * This program is free software; you can redistribute it and/or modify it
++ * under the terms of the GNU General Public License as published by the
++ * Free Software Foundation; either version 2 of the License, or (at your
++ * option) any later version.
++ */
++
++#include "ov10635.c"
++#include "ov490_ov10640.c"
++#include "ov495_ov2775.c"
++#include "ar0132.c"
++#include "ar0220.c"
++#include "ap0101_ar014x.c"
++#include "ov2775.c"
++
++static enum {
++ ID_OV10635,
++ ID_OV490_OV10640,
++ ID_OV495_OV2775,
++ ID_AR0132,
++ ID_AR0220,
++ ID_AP0101_AR014X,
++ ID_OV2775,
++} chip_id;
++
++static int ov106xx_probe(struct i2c_client *client,
++ const struct i2c_device_id *did)
++{
++ int ret;
++ chip_id = -EINVAL;
++
++ ret = ov10635_probe(client, did);
++ if (!ret) {
++ chip_id = ID_OV10635;
++ goto out;
++ }
++
++ ret = ov490_probe(client, did);
++ if (!ret) {
++ chip_id = ID_OV490_OV10640;
++ goto out;
++ }
++
++ ret = ov495_probe(client, did);
++ if (!ret) {
++ chip_id = ID_OV495_OV2775;
++ goto out;
++ }
++
++ ret = ar0132_probe(client, did);
++ if (!ret) {
++ chip_id = ID_AR0132;
++ goto out;
++ }
++
++ ret = ar0220_probe(client, did);
++ if (!ret) {
++ chip_id = ID_AR0220;
++ goto out;
++ }
++
++ ret = ap0101_probe(client, did);
++ if (!ret) {
++ chip_id = ID_AP0101_AR014X;
++ goto out;
++ }
++
++ ret = ov2775_probe(client, did);
++ if (!ret) {
++ chip_id = ID_OV2775;
++ goto out;
++ }
++
++ v4l_err(client, "failed to probe @ 0x%02x (%s)\n",
++ client->addr, client->adapter->name);
++out:
++ return ret;
++}
++
++static int ov106xx_remove(struct i2c_client *client)
++{
++ switch (chip_id) {
++ case ID_OV10635:
++ ov10635_remove(client);
++ break;
++ case ID_OV490_OV10640:
++ ov490_remove(client);
++ break;
++ case ID_OV495_OV2775:
++ ov495_remove(client);
++ break;
++ case ID_AR0132:
++ ar0132_remove(client);
++ break;
++ case ID_AR0220:
++ ar0220_remove(client);
++ break;
++ case ID_AP0101_AR014X:
++ ap0101_remove(client);
++ break;
++ case ID_OV2775:
++ ov2775_remove(client);
++ break;
++ };
++
++ return 0;
++}
++
++static const struct i2c_device_id ov106xx_id[] = {
++ { "ov106xx", 0 },
++ { }
++};
++MODULE_DEVICE_TABLE(i2c, ov106xx_id);
++
++static const struct of_device_id ov106xx_of_ids[] = {
++ { .compatible = "ovti,ov106xx", },
++ { }
++};
++MODULE_DEVICE_TABLE(of, ov106xx_of_ids);
++
++static struct i2c_driver ov106xx_i2c_driver = {
++ .driver = {
++ .name = "ov106xx",
++ .of_match_table = ov106xx_of_ids,
++ },
++ .probe = ov106xx_probe,
++ .remove = ov106xx_remove,
++ .id_table = ov106xx_id,
++};
++
++module_i2c_driver(ov106xx_i2c_driver);
++
++MODULE_DESCRIPTION("SoC Camera driver for OV10635, OV490/OV10640, OV495/OV2775, AR0132, AR0220, AP0101/AR014X");
++MODULE_AUTHOR("Vladimir Barinov");
++MODULE_LICENSE("GPL");
+diff --git a/drivers/media/i2c/soc_camera/ov2775.c b/drivers/media/i2c/soc_camera/ov2775.c
+new file mode 100644
+index 0000000..feb547f
+--- /dev/null
++++ b/drivers/media/i2c/soc_camera/ov2775.c
+@@ -0,0 +1,528 @@
++/*
++ * OmniVision OV2775 sensor camera driver
++ *
++ * Copyright (C) 2018 Cogent Embedded, Inc.
++ *
++ * This program is free software; you can redistribute it and/or modify it
++ * under the terms of the GNU General Public License as published by the
++ * Free Software Foundation; either version 2 of the License, or (at your
++ * option) any later version.
++ */
++
++#include <linux/delay.h>
++#include <linux/init.h>
++#include <linux/i2c.h>
++#include <linux/module.h>
++#include <linux/of_graph.h>
++#include <linux/videodev2.h>
++
++#include <media/soc_camera.h>
++#include <media/v4l2-common.h>
++#include <media/v4l2-ctrls.h>
++#include <media/v4l2-fwnode.h>
++
++#include "ov2775.h"
++
++#define OV2775_I2C_ADDR 0x36
++
++#define OV2775_PID 0x300a
++#define OV2775_VER 0x300b
++#define OV2775_VERSION_REG 0x2770
++
++#define OV2775_MEDIA_BUS_FMT MEDIA_BUS_FMT_SBGGR8_1X8
++
++struct ov2775_priv {
++ struct v4l2_subdev sd;
++ struct v4l2_ctrl_handler hdl;
++ struct media_pad pad;
++ struct v4l2_rect rect;
++ int init_complete;
++ u8 id[6];
++ int exposure;
++ int gain;
++ int autogain;
++ /* serializers */
++ int ti9x4_addr;
++ int ti9x3_addr;
++ int port;
++ int gpio_resetb;
++ int gpio_fsin;
++
++};
++
++static inline struct ov2775_priv *to_ov2775(const struct i2c_client *client)
++{
++ return container_of(i2c_get_clientdata(client), struct ov2775_priv, sd);
++}
++
++static int ov2775_set_regs(struct i2c_client *client,
++ const struct ov2775_reg *regs, int nr_regs)
++{
++ int i;
++
++ for (i = 0; i < nr_regs; i++) {
++ if (regs[i].reg == OV2775_DELAY) {
++ mdelay(regs[i].val);
++ continue;
++ }
++
++ reg16_write(client, regs[i].reg, regs[i].val);
++ }
++
++ return 0;
++}
++
++static int ov2775_s_stream(struct v4l2_subdev *sd, int enable)
++{
++ return 0;
++}
++
++static int ov2775_get_fmt(struct v4l2_subdev *sd,
++ struct v4l2_subdev_pad_config *cfg,
++ struct v4l2_subdev_format *format)
++{
++ struct v4l2_mbus_framefmt *mf = &format->format;
++ struct i2c_client *client = v4l2_get_subdevdata(sd);
++ struct ov2775_priv *priv = to_ov2775(client);
++
++ if (format->pad)
++ return -EINVAL;
++
++ mf->width = priv->rect.width;
++ mf->height = priv->rect.height;
++ mf->code = OV2775_MEDIA_BUS_FMT;
++ mf->colorspace = V4L2_COLORSPACE_SMPTE170M;
++ mf->field = V4L2_FIELD_NONE;
++
++ return 0;
++}
++
++static int ov2775_set_fmt(struct v4l2_subdev *sd,
++ struct v4l2_subdev_pad_config *cfg,
++ struct v4l2_subdev_format *format)
++{
++ struct v4l2_mbus_framefmt *mf = &format->format;
++
++ mf->code = OV2775_MEDIA_BUS_FMT;
++ mf->colorspace = V4L2_COLORSPACE_SMPTE170M;
++ mf->field = V4L2_FIELD_NONE;
++
++ if (format->which == V4L2_SUBDEV_FORMAT_TRY)
++ cfg->try_fmt = *mf;
++
++ return 0;
++}
++
++static int ov2775_enum_mbus_code(struct v4l2_subdev *sd,
++ struct v4l2_subdev_pad_config *cfg,
++ struct v4l2_subdev_mbus_code_enum *code)
++{
++ if (code->pad || code->index > 0)
++ return -EINVAL;
++
++ code->code = OV2775_MEDIA_BUS_FMT;
++
++ return 0;
++}
++
++static int ov2775_get_edid(struct v4l2_subdev *sd, struct v4l2_edid *edid)
++{
++ struct i2c_client *client = v4l2_get_subdevdata(sd);
++ struct ov2775_priv *priv = to_ov2775(client);
++
++ memcpy(edid->edid, priv->id, 6);
++
++ edid->edid[6] = 0xff;
++ edid->edid[7] = client->addr;
++ edid->edid[8] = OV2775_VERSION_REG >> 8;
++ edid->edid[9] = OV2775_VERSION_REG & 0xff;
++
++ return 0;
++}
++
++static int ov2775_set_selection(struct v4l2_subdev *sd,
++ struct v4l2_subdev_pad_config *cfg,
++ struct v4l2_subdev_selection *sel)
++{
++ struct v4l2_rect *rect = &sel->r;
++ struct i2c_client *client = v4l2_get_subdevdata(sd);
++ struct ov2775_priv *priv = to_ov2775(client);
++
++ if (sel->which != V4L2_SUBDEV_FORMAT_ACTIVE ||
++ sel->target != V4L2_SEL_TGT_CROP)
++ return -EINVAL;
++
++ rect->left = ALIGN(rect->left, 2);
++ rect->top = ALIGN(rect->top, 2);
++ rect->width = ALIGN(rect->width, 2);
++ rect->height = ALIGN(rect->height, 2);
++
++ if ((rect->left + rect->width > OV2775_MAX_WIDTH) ||
++ (rect->top + rect->height > OV2775_MAX_HEIGHT))
++ *rect = priv->rect;
++
++ priv->rect.left = rect->left;
++ priv->rect.top = rect->top;
++ priv->rect.width = rect->width;
++ priv->rect.height = rect->height;
++
++ return 0;
++}
++
++static int ov2775_get_selection(struct v4l2_subdev *sd,
++ struct v4l2_subdev_pad_config *cfg,
++ struct v4l2_subdev_selection *sel)
++{
++ struct i2c_client *client = v4l2_get_subdevdata(sd);
++ struct ov2775_priv *priv = to_ov2775(client);
++
++ if (sel->which != V4L2_SUBDEV_FORMAT_ACTIVE)
++ return -EINVAL;
++
++ switch (sel->target) {
++ case V4L2_SEL_TGT_CROP_BOUNDS:
++ sel->r.left = 0;
++ sel->r.top = 0;
++ sel->r.width = OV2775_MAX_WIDTH;
++ sel->r.height = OV2775_MAX_HEIGHT;
++ return 0;
++ case V4L2_SEL_TGT_CROP_DEFAULT:
++ sel->r.left = 0;
++ sel->r.top = 0;
++ sel->r.width = OV2775_MAX_WIDTH;
++ sel->r.height = OV2775_MAX_HEIGHT;
++ return 0;
++ case V4L2_SEL_TGT_CROP:
++ sel->r = priv->rect;
++ return 0;
++ default:
++ return -EINVAL;
++ }
++}
++
++static int ov2775_g_mbus_config(struct v4l2_subdev *sd,
++ struct v4l2_mbus_config *cfg)
++{
++ cfg->flags = V4L2_MBUS_CSI2_1_LANE | V4L2_MBUS_CSI2_CHANNEL_0 |
++ V4L2_MBUS_CSI2_CONTINUOUS_CLOCK;
++ cfg->type = V4L2_MBUS_CSI2;
++
++ return 0;
++}
++
++#ifdef CONFIG_VIDEO_ADV_DEBUG
++static int ov2775_g_register(struct v4l2_subdev *sd,
++ struct v4l2_dbg_register *reg)
++{
++ struct i2c_client *client = v4l2_get_subdevdata(sd);
++ int ret;
++ u8 val = 0;
++
++ ret = reg16_read(client, (u16)reg->reg, &val);
++ if (ret < 0)
++ return ret;
++
++ reg->val = val;
++ reg->size = sizeof(u8);
++
++ return 0;
++}
++
++static int ov2775_s_register(struct v4l2_subdev *sd,
++ const struct v4l2_dbg_register *reg)
++{
++ struct i2c_client *client = v4l2_get_subdevdata(sd);
++
++ return reg16_write(client, (u16)reg->reg, (u8)reg->val);
++}
++#endif
++
++static struct v4l2_subdev_core_ops ov2775_core_ops = {
++#ifdef CONFIG_VIDEO_ADV_DEBUG
++ .g_register = ov2775_g_register,
++ .s_register = ov2775_s_register,
++#endif
++};
++
++static int ov2775_s_ctrl(struct v4l2_ctrl *ctrl)
++{
++ struct v4l2_subdev *sd = to_sd(ctrl);
++ struct i2c_client *client = v4l2_get_subdevdata(sd);
++ struct ov2775_priv *priv = to_ov2775(client);
++ int ret = -EINVAL;
++
++ if (!priv->init_complete)
++ return 0;
++
++ switch (ctrl->id) {
++ case V4L2_CID_BRIGHTNESS:
++ case V4L2_CID_CONTRAST:
++ case V4L2_CID_SATURATION:
++ case V4L2_CID_HUE:
++ case V4L2_CID_GAMMA:
++ case V4L2_CID_SHARPNESS:
++ case V4L2_CID_AUTOGAIN:
++ case V4L2_CID_GAIN:
++ case V4L2_CID_EXPOSURE:
++ case V4L2_CID_HFLIP:
++ case V4L2_CID_VFLIP:
++ break;
++ }
++
++ return ret;
++}
++
++static const struct v4l2_ctrl_ops ov2775_ctrl_ops = {
++ .s_ctrl = ov2775_s_ctrl,
++};
++
++static struct v4l2_subdev_video_ops ov2775_video_ops = {
++ .s_stream = ov2775_s_stream,
++ .g_mbus_config = ov2775_g_mbus_config,
++};
++
++static const struct v4l2_subdev_pad_ops ov2775_subdev_pad_ops = {
++ .get_edid = ov2775_get_edid,
++ .enum_mbus_code = ov2775_enum_mbus_code,
++ .get_selection = ov2775_get_selection,
++ .set_selection = ov2775_set_selection,
++ .get_fmt = ov2775_get_fmt,
++ .set_fmt = ov2775_set_fmt,
++};
++
++static struct v4l2_subdev_ops ov2775_subdev_ops = {
++ .core = &ov2775_core_ops,
++ .video = &ov2775_video_ops,
++ .pad = &ov2775_subdev_pad_ops,
++};
++
++static void ov2775_otp_id_read(struct i2c_client *client)
++{
++}
++
++static ssize_t ov2775_otp_id_show(struct device *dev,
++ struct device_attribute *attr, char *buf)
++{
++ struct v4l2_subdev *sd = i2c_get_clientdata(to_i2c_client(dev));
++ struct i2c_client *client = v4l2_get_subdevdata(sd);
++ struct ov2775_priv *priv = to_ov2775(client);
++
++ return snprintf(buf, 32, "%02x:%02x:%02x:%02x:%02x:%02x\n",
++ priv->id[0], priv->id[1], priv->id[2], priv->id[3], priv->id[4], priv->id[5]);
++}
++
++static DEVICE_ATTR(otp_id_ov2775, S_IRUGO, ov2775_otp_id_show, NULL);
++
++static int ov2775_initialize(struct i2c_client *client)
++{
++ struct ov2775_priv *priv = to_ov2775(client);
++ u8 val = 0;
++ u16 pid;
++ int ret = 0;
++
++ /* check and show model ID */
++ reg16_read(client, OV2775_PID, &val);
++ pid = val;
++ reg16_read(client, OV2775_VER, &val);
++ pid = (pid << 8) | val;
++
++ if (pid != OV2775_VERSION_REG) {
++ dev_dbg(&client->dev, "Product ID error %x\n", pid);
++ ret = -ENODEV;
++ goto err;
++ }
++
++ /* Program wizard registers */
++ ov2775_set_regs(client, ov2775_regs_wizard, ARRAY_SIZE(ov2775_regs_wizard));
++ /* Read OTP IDs */
++ ov2775_otp_id_read(client);
++
++ dev_info(&client->dev, "ov2775 PID %x, res %dx%d, OTP_ID %02x:%02x:%02x:%02x:%02x:%02x\n",
++ pid, OV2775_MAX_WIDTH, OV2775_MAX_HEIGHT, priv->id[0], priv->id[1], priv->id[2], priv->id[3], priv->id[4], priv->id[5]);
++err:
++ return ret;
++}
++
++static int ov2775_parse_dt(struct device_node *np, struct ov2775_priv *priv)
++{
++ struct i2c_client *client = v4l2_get_subdevdata(&priv->sd);
++ int i;
++ struct device_node *endpoint = NULL, *rendpoint = NULL;
++ int tmp_addr = 0;
++
++ for (i = 0; ; i++) {
++ endpoint = of_graph_get_next_endpoint(np, endpoint);
++ if (!endpoint)
++ break;
++
++ of_node_put(endpoint);
++
++ rendpoint = of_parse_phandle(endpoint, "remote-endpoint", 0);
++ if (!rendpoint)
++ continue;
++
++ if (!of_property_read_u32(rendpoint, "ti9x3-addr", &priv->ti9x3_addr) &&
++ !of_property_match_string(rendpoint->parent->parent, "compatible", "ti,ti9x4") &&
++ !of_property_read_u32(rendpoint->parent->parent, "reg", &priv->ti9x4_addr) &&
++ !kstrtouint(strrchr(rendpoint->full_name, '@') + 1, 0, &priv->port))
++ break;
++ }
++
++ if (!priv->ti9x4_addr) {
++ dev_err(&client->dev, "deserializer does not present\n");
++ return -EINVAL;
++ }
++
++ /* setup I2C translator address */
++ tmp_addr = client->addr;
++ if (priv->ti9x4_addr) {
++ client->addr = priv->ti9x4_addr; /* Deserializer I2C address */
++ reg8_write(client, 0x4c, (priv->port << 4) | (1 << priv->port)); /* Select RX port number */
++ usleep_range(2000, 2500); /* wait 2ms */
++ reg8_write(client, 0x65, tmp_addr << 1); /* Sensor translated I2C address */
++ reg8_write(client, 0x5d, OV2775_I2C_ADDR << 1); /* Sensor native I2C address */
++// reg8_write(client, 0x6e, 0xa9); /* GPIO0 - reset, GPIO1 - fsin */
++
++ client->addr = priv->ti9x3_addr; /* Serializer I2C address */
++ reg8_write(client, 0x0d, 0x03); /* unreset gpios */
++ reg8_write(client, 0x0e, 0xf0); /* unreset gpios */
++ }
++ client->addr = tmp_addr;
++
++ mdelay(10);
++
++ return 0;
++}
++
++static int ov2775_probe(struct i2c_client *client,
++ const struct i2c_device_id *did)
++{
++ struct ov2775_priv *priv;
++ int ret;
++
++ priv = devm_kzalloc(&client->dev, sizeof(*priv), GFP_KERNEL);
++ if (!priv)
++ return -ENOMEM;
++
++ v4l2_i2c_subdev_init(&priv->sd, client, &ov2775_subdev_ops);
++ priv->sd.flags = V4L2_SUBDEV_FL_HAS_DEVNODE;
++
++ priv->exposure = 0x100;
++ priv->gain = 0x100;
++ priv->autogain = 1;
++ v4l2_ctrl_handler_init(&priv->hdl, 4);
++ v4l2_ctrl_new_std(&priv->hdl, &ov2775_ctrl_ops,
++ V4L2_CID_BRIGHTNESS, 0, 16, 1, 7);
++ v4l2_ctrl_new_std(&priv->hdl, &ov2775_ctrl_ops,
++ V4L2_CID_CONTRAST, 0, 16, 1, 7);
++ v4l2_ctrl_new_std(&priv->hdl, &ov2775_ctrl_ops,
++ V4L2_CID_SATURATION, 0, 7, 1, 2);
++ v4l2_ctrl_new_std(&priv->hdl, &ov2775_ctrl_ops,
++ V4L2_CID_HUE, 0, 23, 1, 12);
++ v4l2_ctrl_new_std(&priv->hdl, &ov2775_ctrl_ops,
++ V4L2_CID_GAMMA, -128, 128, 1, 0);
++ v4l2_ctrl_new_std(&priv->hdl, &ov2775_ctrl_ops,
++ V4L2_CID_SHARPNESS, 0, 10, 1, 3);
++ v4l2_ctrl_new_std(&priv->hdl, &ov2775_ctrl_ops,
++ V4L2_CID_AUTOGAIN, 0, 1, 1, priv->autogain);
++ v4l2_ctrl_new_std(&priv->hdl, &ov2775_ctrl_ops,
++ V4L2_CID_GAIN, 0, 0xffff, 1, priv->gain);
++ v4l2_ctrl_new_std(&priv->hdl, &ov2775_ctrl_ops,
++ V4L2_CID_EXPOSURE, 0, 0xffff, 1, priv->exposure);
++ v4l2_ctrl_new_std(&priv->hdl, &ov2775_ctrl_ops,
++ V4L2_CID_HFLIP, 0, 1, 1, 1);
++ v4l2_ctrl_new_std(&priv->hdl, &ov2775_ctrl_ops,
++ V4L2_CID_VFLIP, 0, 1, 1, 0);
++ priv->sd.ctrl_handler = &priv->hdl;
++
++ ret = priv->hdl.error;
++ if (ret)
++ goto cleanup;
++
++ v4l2_ctrl_handler_setup(&priv->hdl);
++
++ priv->pad.flags = MEDIA_PAD_FL_SOURCE;
++ priv->sd.entity.flags |= MEDIA_ENT_F_CAM_SENSOR;
++ ret = media_entity_pads_init(&priv->sd.entity, 1, &priv->pad);
++ if (ret < 0)
++ goto cleanup;
++
++ ret = ov2775_parse_dt(client->dev.of_node, priv);
++ if (ret)
++ goto cleanup;
++
++ ret = ov2775_initialize(client);
++ if (ret < 0)
++ goto cleanup;
++
++ priv->rect.left = 0;
++ priv->rect.top = 0;
++ priv->rect.width = OV2775_MAX_WIDTH;
++ priv->rect.height = OV2775_MAX_HEIGHT;
++
++ ret = v4l2_async_register_subdev(&priv->sd);
++ if (ret)
++ goto cleanup;
++
++ if (device_create_file(&client->dev, &dev_attr_otp_id_ov2775) != 0) {
++ dev_err(&client->dev, "sysfs otp_id entry creation failed\n");
++ goto cleanup;
++ }
++
++ priv->init_complete = 1;
++
++ return 0;
++
++cleanup:
++ media_entity_cleanup(&priv->sd.entity);
++ v4l2_ctrl_handler_free(&priv->hdl);
++ v4l2_device_unregister_subdev(&priv->sd);
++#ifdef CONFIG_SOC_CAMERA_OV2775
++ v4l_err(client, "failed to probe @ 0x%02x (%s)\n",
++ client->addr, client->adapter->name);
++#endif
++ return ret;
++}
++
++static int ov2775_remove(struct i2c_client *client)
++{
++ struct ov2775_priv *priv = i2c_get_clientdata(client);
++
++ device_remove_file(&client->dev, &dev_attr_otp_id_ov2775);
++ v4l2_async_unregister_subdev(&priv->sd);
++ media_entity_cleanup(&priv->sd.entity);
++ v4l2_ctrl_handler_free(&priv->hdl);
++ v4l2_device_unregister_subdev(&priv->sd);
++
++ return 0;
++}
++
++#ifdef CONFIG_SOC_CAMERA_OV2775
++static const struct i2c_device_id ov2775_id[] = {
++ { "ov2775", 0 },
++ { }
++};
++MODULE_DEVICE_TABLE(i2c, ov2775_id);
++
++static const struct of_device_id ov2775_of_ids[] = {
++ { .compatible = "ovti,ov2775", },
++ { }
++};
++MODULE_DEVICE_TABLE(of, ov2775_of_ids);
++
++static struct i2c_driver ov2775_i2c_driver = {
++ .driver = {
++ .name = "ov2775",
++ .of_match_table = ov2775_of_ids,
++ },
++ .probe = ov2775_probe,
++ .remove = ov2775_remove,
++ .id_table = ov2775_id,
++};
++
++module_i2c_driver(ov2775_i2c_driver);
++
++MODULE_DESCRIPTION("SoC Camera driver for OV2775");
++MODULE_AUTHOR("Vladimir Barinov");
++MODULE_LICENSE("GPL");
++#endif
+diff --git a/drivers/media/i2c/soc_camera/ov2775.h b/drivers/media/i2c/soc_camera/ov2775.h
+new file mode 100644
+index 0000000..1cdfb50
+--- /dev/null
++++ b/drivers/media/i2c/soc_camera/ov2775.h
+@@ -0,0 +1,1841 @@
++/*
++ * OmniVision OV2775 sensor camera wizard 1928x1088@30/RGGB/MIPI
++ *
++ * Copyright (C) 2018 Cogent Embedded, Inc.
++ *
++ * This program is free software; you can redistribute it and/or modify it
++ * under the terms of the GNU General Public License as published by the
++ * Free Software Foundation; either version 2 of the License, or (at your
++ * option) any later version.
++ */
++
++//#define OV2775_DISPLAY_PATTERN_COLOR_BAR
++
++#define OV2775_MAX_WIDTH 2880 // (1928*1.5=2892) <- must be multiple of 16 - requred by R-CAR VIN
++#define OV2775_MAX_HEIGHT 1088
++
++#define OV2775_DELAY 0xffff
++#define OV2775_DT 0x2c // MIPI Data Type
++
++struct ov2775_reg {
++ u16 reg;
++ u8 val;
++};
++
++/* wizard: MIPI 1928x1088 RAW12 Linear 30fps 960Mbps */
++static const struct ov2775_reg ov2775_regs_wizard[] = {
++{0x3013, 0x01}, // s/w reset
++{OV2775_DELAY, 10}, // Wait 10ms
++{0x3000, 0x02},
++{0x3001, 0x28},
++{0x3002, 0x03},
++{0x3003, 0x01},
++{0x3004, 0x02},
++{0x3005, 0x26},
++{0x3006, 0x00},
++{0x3007, 0x07},
++{0x3008, 0x01},
++{0x3009, 0x00},
++{0x300c, 0x6c},
++{0x300e, 0x80},
++{0x300f, 0x00},
++{0x3012, 0x00},
++{0x3013, 0x00},
++{0x3014, 0xc4},
++{0x3015, 0x00},
++{0x3017, 0x00},
++{0x3018, 0x00},
++{0x3019, 0x00},
++{0x301a, 0x00},
++{0x301b, 0x01},
++{0x301e, 0x17},
++{0x301f, 0xe1},
++{0x3030, 0x02},
++{0x3031, 0x72},
++{0x3032, 0xf0},
++{0x3033, 0x30},
++{0x3034, 0x3f},
++{0x3035, 0x5f},
++{0x3036, 0x02},
++{0x3037, 0x9f},
++{0x3038, 0x04},
++{0x3039, 0xb7},
++{0x303a, 0x04},
++{0x303b, 0x07},
++{0x303c, 0xf0},
++{0x303d, 0x00},
++{0x303e, 0x0b},
++{0x303f, 0xe3},
++{0x3040, 0xf3},
++{0x3041, 0x29},
++{0x3042, 0xf6},
++{0x3043, 0x65},
++{0x3044, 0x06},
++{0x3045, 0x0f},
++{0x3046, 0x59},
++{0x3047, 0x07},
++{0x3048, 0x82},
++{0x3049, 0xcf},
++{0x304a, 0x12},
++{0x304b, 0x40},
++{0x304c, 0x33},
++{0x304d, 0xa4},
++{0x304e, 0x0b},
++{0x304f, 0x3d},
++{0x3050, 0x10},
++{0x3060, 0x00},
++{0x3061, 0x64},
++{0x3062, 0x00},
++{0x3063, 0xe4},
++{0x3066, 0x80},
++{0x3080, 0x00},
++{0x3081, 0x00},
++{0x3082, 0x01},
++{0x3083, 0xe3},
++{0x3084, 0x06},
++{0x3085, 0x00},
++{0x3086, 0x10},
++{0x3087, 0x10},
++{0x3089, 0x00},
++{0x308a, 0x01},
++{0x3093, 0x00},
++{0x30a0, 0x00},
++{0x30a1, 0x00},
++{0x30a2, 0x00},
++{0x30a3, 0x00},
++{0x30a4, 0x07},
++{0x30a5, 0x8f},
++{0x30a6, 0x04},
++{0x30a7, 0x47},
++{0x30a8, 0x00},
++{0x30a9, 0x00},
++{0x30aa, 0x00},
++{0x30ab, 0x00},
++{0x30ac, 0x07},
++{0x30ad, 0x90},
++{0x30ae, 0x04},
++{0x30af, 0x48},
++{0x30b0, 0x04},
++{0x30b1, 0x7e},
++{0x30b2, 0x04},
++{0x30b3, 0x65},
++{0x30b4, 0x00},
++{0x30b5, 0x00},
++{0x30b6, 0x00},
++{0x30b7, 0x10},
++{0x30b8, 0x00},
++{0x30b9, 0x02},
++{0x30ba, 0x10},
++{0x30bb, 0x00},
++{0x30bc, 0x00},
++{0x30bd, 0x03},
++{0x30be, 0x5c},
++{0x30bf, 0x00},
++{0x30c0, 0x01},
++{0x30c1, 0x00},
++{0x30c2, 0x20},
++{0x30c3, 0x00},
++{0x30c4, 0x4a},
++{0x30c5, 0x00},
++{0x30c7, 0x00},
++{0x30c8, 0x00},
++{0x30d1, 0x00},
++{0x30d2, 0x00},
++{0x30d3, 0x80},
++{0x30d4, 0x00},
++{0x30d9, 0x09},
++{0x30da, 0x64},
++{0x30dd, 0x00},
++{0x30de, 0x16},
++{0x30df, 0x00},
++{0x30e0, 0x17},
++{0x30e1, 0x00},
++{0x30e2, 0x18},
++{0x30e3, 0x10},
++{0x30e4, 0x04},
++{0x30e5, 0x00},
++{0x30e6, 0x00},
++{0x30e7, 0x00},
++{0x30e8, 0x00},
++{0x30e9, 0x00},
++{0x30ea, 0x00},
++{0x30eb, 0x00},
++{0x30ec, 0x00},
++{0x30ed, 0x00},
++{0x3101, 0x00},
++{0x3102, 0x00},
++{0x3103, 0x00},
++{0x3104, 0x00},
++{0x3105, 0x8c},
++{0x3106, 0x87},
++{0x3107, 0xc0},
++{0x3108, 0x9d},
++{0x3109, 0x8d},
++{0x310a, 0x8d},
++{0x310b, 0x6a},
++{0x310c, 0x3a},
++{0x310d, 0x5a},
++{0x310e, 0x00},
++{0x3120, 0x00},
++{0x3121, 0x00},
++{0x3122, 0x00},
++{0x3123, 0xf0},
++{0x3124, 0x00},
++{0x3125, 0x70},
++{0x3126, 0x1f},
++{0x3127, 0x0f},
++{0x3128, 0x00},
++{0x3129, 0x3a},
++{0x312a, 0x02},
++{0x312b, 0x0f},
++{0x312c, 0x00},
++{0x312d, 0x0f},
++{0x312e, 0x1d},
++{0x312f, 0x00},
++{0x3130, 0x00},
++{0x3131, 0x00},
++{0x3132, 0x00},
++{0x3140, 0x0a},
++{0x3141, 0x03},
++{0x3142, 0x00},
++{0x3143, 0x00},
++{0x3144, 0x00},
++{0x3145, 0x00},
++{0x3146, 0x00},
++{0x3147, 0x00},
++{0x3148, 0x00},
++{0x3149, 0x00},
++{0x314a, 0x00},
++{0x314b, 0x00},
++{0x314c, 0x00},
++{0x314d, 0x00},
++{0x314e, 0x1c},
++{0x314f, 0xff},
++{0x3150, 0xff},
++{0x3151, 0xff},
++{0x3152, 0x10},
++{0x3153, 0x10},
++{0x3154, 0x10},
++{0x3155, 0x00},
++{0x3156, 0x03},
++{0x3157, 0x00},
++{0x3158, 0x0f},
++{0x3159, 0xff},
++{0x315a, 0x01},
++{0x315b, 0x00},
++{0x315c, 0x01},
++{0x315d, 0x00},
++{0x315e, 0x01},
++{0x315f, 0x00},
++{0x3160, 0x00},
++{0x3161, 0x40},
++{0x3162, 0x00},
++{0x3163, 0x40},
++{0x3164, 0x00},
++{0x3165, 0x40},
++{0x3190, 0x08},
++{0x3191, 0x99},
++{0x3193, 0x08},
++{0x3194, 0x13},
++{0x3195, 0x33},
++{0x3196, 0x00},
++{0x3197, 0x10},
++{0x3198, 0x00},
++{0x3199, 0x7f},
++{0x319a, 0x80},
++{0x319b, 0xff},
++{0x319c, 0x80},
++{0x319d, 0xbf},
++{0x319e, 0xc0},
++{0x319f, 0xff},
++{0x31a0, 0x24},
++{0x31a1, 0x55},
++{0x31a2, 0x00},
++{0x31a3, 0x00},
++{0x31a6, 0x00},
++{0x31a7, 0x00},
++{0x31b0, 0x00},
++{0x31b1, 0x00},
++{0x31b2, 0x02},
++{0x31b3, 0x00},
++{0x31b4, 0x00},
++{0x31b5, 0x01},
++{0x31b6, 0x00},
++{0x31b7, 0x00},
++{0x31b8, 0x00},
++{0x31b9, 0x00},
++{0x31ba, 0x00},
++{0x31d0, 0x3c},
++{0x31d1, 0x34},
++{0x31d2, 0x3c},
++{0x31d3, 0x00},
++{0x31d4, 0x2d},
++{0x31d5, 0x00},
++{0x31d6, 0x01},
++{0x31d7, 0x06},
++{0x31d8, 0x00},
++{0x31d9, 0x64},
++{0x31da, 0x00},
++{0x31db, 0x30},
++{0x31dc, 0x04},
++{0x31dd, 0x69},
++{0x31de, 0x0a},
++{0x31df, 0x3c},
++{0x31e0, 0x04},
++{0x31e1, 0x32},
++{0x31e2, 0x00},
++{0x31e3, 0x00},
++{0x31e4, 0x08},
++{0x31e5, 0x80},
++{0x31e6, 0x00},
++{0x31e7, OV2775_DT},
++{0x31e8, 0x6c},
++{0x31e9, 0xac},
++{0x31ea, 0xec},
++{0x31eb, 0x3f},
++{0x31ec, 0x0f},
++{0x31ed, 0x20},
++{0x31ee, 0x04},
++{0x31ef, 0x48},
++{0x31f0, 0x07},
++{0x31f1, 0x90},
++{0x31f2, 0x04},
++{0x31f3, 0x48},
++{0x31f4, 0x07},
++{0x31f5, 0x90},
++{0x31f6, 0x04},
++{0x31f7, 0x48},
++{0x31f8, 0x07},
++{0x31f9, 0x90},
++{0x31fa, 0x04},
++{0x31fb, 0x48},
++{0x31fd, 0xcb},
++{0x31fe, 0x0f},
++{0x31ff, 0x03},
++{0x3200, 0x00},
++{0x3201, 0xff},
++{0x3202, 0x00},
++{0x3203, 0xff},
++{0x3204, 0xff},
++{0x3205, 0xff},
++{0x3206, 0xff},
++{0x3207, 0xff},
++{0x3208, 0xff},
++{0x3209, 0xff},
++{0x320a, 0xff},
++{0x320b, 0x1b},
++{0x320c, 0x1f},
++{0x320d, 0x1e},
++{0x320e, 0x30},
++{0x320f, 0x2d},
++{0x3210, OV2775_DT},
++{0x3211, 0x2b},
++{0x3212, 0x2a},
++{0x3213, 0x24},
++{0x3214, 0x22},
++{0x3215, 0x00},
++{0x3216, 0x04},
++{0x3217, OV2775_DT},
++{0x3218, 0x6c},
++{0x3219, 0xac},
++{0x321a, 0xec},
++{0x321b, 0x00},
++{0x3230, 0x3a},
++{0x3231, 0x00},
++{0x3232, 0x80},
++{0x3233, 0x00},
++{0x3234, 0x10},
++{0x3235, 0xaa},
++{0x3236, 0x55},
++{0x3237, 0x99},
++{0x3238, 0x66},
++{0x3239, 0x08},
++{0x323a, 0x88},
++{0x323b, 0x00},
++{0x323c, 0x00},
++{0x323d, 0x03},
++{0x3250, 0x33},
++{0x3251, 0x00},
++{0x3252, 0x20},
++#ifdef OV2775_DISPLAY_PATTERN_COLOR_BAR
++{0x3253, 0x80},
++#else
++{0x3253, 0x00},
++#endif
++{0x3254, 0x00},
++{0x3255, 0x01},
++{0x3256, 0x00},
++{0x3257, 0x00},
++{0x3258, 0x00},
++{0x3270, 0x01},
++{0x3271, 0x60},
++{0x3272, 0xc0},
++{0x3273, 0x00},
++{0x3274, 0x80},
++{0x3275, 0x40},
++{0x3276, 0x02},
++{0x3277, 0x08},
++{0x3278, 0x10},
++{0x3279, 0x04},
++{0x327a, 0x00},
++{0x327b, 0x03},
++{0x327c, 0x10},
++{0x327d, 0x60},
++{0x327e, 0xc0},
++{0x327f, 0x06},
++{0x3288, 0x10},
++{0x3289, 0x00},
++{0x328a, 0x08},
++{0x328b, 0x00},
++{0x328c, 0x04},
++{0x328d, 0x00},
++{0x328e, 0x02},
++{0x328f, 0x00},
++{0x3290, 0x20},
++{0x3291, 0x00},
++{0x3292, 0x10},
++{0x3293, 0x00},
++{0x3294, 0x08},
++{0x3295, 0x00},
++{0x3296, 0x04},
++{0x3297, 0x00},
++{0x3298, 0x40},
++{0x3299, 0x00},
++{0x329a, 0x20},
++{0x329b, 0x00},
++{0x329c, 0x10},
++{0x329d, 0x00},
++{0x329e, 0x08},
++{0x329f, 0x00},
++{0x32a0, 0x7f},
++{0x32a1, 0xff},
++{0x32a2, 0x40},
++{0x32a3, 0x00},
++{0x32a4, 0x20},
++{0x32a5, 0x00},
++{0x32a6, 0x10},
++{0x32a7, 0x00},
++{0x32a8, 0x00},
++{0x32a9, 0x00},
++{0x32aa, 0x00},
++{0x32ab, 0x00},
++{0x32ac, 0x00},
++{0x32ad, 0x00},
++{0x32ae, 0x00},
++{0x32af, 0x00},
++{0x32b0, 0x00},
++{0x32b1, 0x00},
++{0x32b2, 0x00},
++{0x32b3, 0x00},
++{0x32b4, 0x00},
++{0x32b5, 0x00},
++{0x32b6, 0x00},
++{0x32b7, 0x00},
++{0x32b8, 0x00},
++{0x32b9, 0x00},
++{0x32ba, 0x00},
++{0x32bb, 0x00},
++{0x32bc, 0x00},
++{0x32bd, 0x00},
++{0x32be, 0x00},
++{0x32bf, 0x00},
++{0x32c0, 0x00},
++{0x32c1, 0x00},
++{0x32c2, 0x00},
++{0x32c3, 0x00},
++{0x32c4, 0x00},
++{0x32c5, 0x00},
++{0x32c6, 0x00},
++{0x32c7, 0x00},
++{0x32c8, 0x87},
++{0x32c9, 0x00},
++{0x3330, 0x03},
++{0x3331, 0xc8},
++{0x3332, 0x02},
++{0x3333, 0x24},
++{0x3334, 0x00},
++{0x3335, 0x00},
++{0x3336, 0x00},
++{0x3337, 0x00},
++{0x3338, 0x03},
++{0x3339, 0xc8},
++{0x333a, 0x02},
++{0x333b, 0x24},
++{0x333c, 0x00},
++{0x333d, 0x00},
++{0x333e, 0x00},
++{0x333f, 0x00},
++{0x3340, 0x03},
++{0x3341, 0xc8},
++{0x3342, 0x02},
++{0x3343, 0x24},
++{0x3344, 0x00},
++{0x3345, 0x00},
++{0x3346, 0x00},
++{0x3347, 0x00},
++{0x3348, 0x40},
++{0x3349, 0x00},
++{0x334a, 0x00},
++{0x334b, 0x00},
++{0x334c, 0x00},
++{0x334d, 0x00},
++{0x334e, 0x80},
++{0x3360, 0x01},
++{0x3361, 0x00},
++{0x3362, 0x01},
++{0x3363, 0x00},
++{0x3364, 0x01},
++{0x3365, 0x00},
++{0x3366, 0x01},
++{0x3367, 0x00},
++{0x3368, 0x01},
++{0x3369, 0x00},
++{0x336a, 0x01},
++{0x336b, 0x00},
++{0x336c, 0x01},
++{0x336d, 0x00},
++{0x336e, 0x01},
++{0x336f, 0x00},
++{0x3370, 0x01},
++{0x3371, 0x00},
++{0x3372, 0x01},
++{0x3373, 0x00},
++{0x3374, 0x01},
++{0x3375, 0x00},
++{0x3376, 0x01},
++{0x3377, 0x00},
++{0x3378, 0x00},
++{0x3379, 0x00},
++{0x337a, 0x00},
++{0x337b, 0x00},
++{0x337c, 0x00},
++{0x337d, 0x00},
++{0x337e, 0x00},
++{0x337f, 0x00},
++{0x3380, 0x00},
++{0x3381, 0x00},
++{0x3382, 0x00},
++{0x3383, 0x00},
++{0x3384, 0x00},
++{0x3385, 0x00},
++{0x3386, 0x00},
++{0x3387, 0x00},
++{0x3388, 0x00},
++{0x3389, 0x00},
++{0x338a, 0x00},
++{0x338b, 0x00},
++{0x338c, 0x00},
++{0x338d, 0x00},
++{0x338e, 0x00},
++{0x338f, 0x00},
++{0x3390, 0x00},
++{0x3391, 0x00},
++{0x3392, 0x00},
++{0x3393, 0x00},
++{0x3394, 0x00},
++{0x3395, 0x00},
++{0x3396, 0x00},
++{0x3397, 0x00},
++{0x3398, 0x00},
++{0x3399, 0x00},
++{0x339a, 0x00},
++{0x339b, 0x00},
++{0x33b0, 0x00},
++{0x33b1, 0x50},
++{0x33b2, 0x01},
++{0x33b3, 0xff},
++{0x33b4, 0xe0},
++{0x33b5, 0x6b},
++{0x33b6, 0x00},
++{0x33b7, 0x00},
++{0x33b8, 0x00},
++{0x33b9, 0x00},
++{0x33ba, 0x00},
++{0x33bb, 0x1f},
++{0x33bc, 0x01},
++{0x33bd, 0x01},
++{0x33be, 0x01},
++{0x33bf, 0x01},
++{0x33c0, 0x00},
++{0x33c1, 0x00},
++{0x33c2, 0x00},
++{0x33c3, 0x00},
++{0x33e0, 0x14},
++{0x33e1, 0x0f},
++{0x33e2, 0x02},
++{0x33e3, 0x01},
++{0x33e4, 0x01},
++{0x33e5, 0x01},
++{0x33e6, 0x00},
++{0x33e7, 0x04},
++{0x33e8, 0x0c},
++{0x33e9, 0x02},
++{0x33ea, 0x02},
++{0x33eb, 0x02},
++{0x33ec, 0x03},
++{0x33ed, 0x01},
++{0x33ee, 0x02},
++{0x33ef, 0x08},
++{0x33f0, 0x08},
++{0x33f1, 0x04},
++{0x33f2, 0x04},
++{0x33f3, 0x00},
++{0x33f4, 0x03},
++{0x33f5, 0x14},
++{0x33f6, 0x0f},
++{0x33f7, 0x02},
++{0x33f8, 0x01},
++{0x33f9, 0x01},
++{0x33fa, 0x01},
++{0x33fb, 0x00},
++{0x33fc, 0x04},
++{0x33fd, 0x0c},
++{0x33fe, 0x02},
++{0x33ff, 0x02},
++{0x3400, 0x02},
++{0x3401, 0x03},
++{0x3402, 0x01},
++{0x3403, 0x02},
++{0x3404, 0x08},
++{0x3405, 0x08},
++{0x3406, 0x04},
++{0x3407, 0x04},
++{0x3408, 0x00},
++{0x3409, 0x03},
++{0x340a, 0x14},
++{0x340b, 0x0f},
++{0x340c, 0x04},
++{0x340d, 0x02},
++{0x340e, 0x01},
++{0x340f, 0x01},
++{0x3410, 0x00},
++{0x3411, 0x04},
++{0x3412, 0x0c},
++{0x3413, 0x00},
++{0x3414, 0x01},
++{0x3415, 0x02},
++{0x3416, 0x03},
++{0x3417, 0x02},
++{0x3418, 0x05},
++{0x3419, 0x0a},
++{0x341a, 0x08},
++{0x341b, 0x04},
++{0x341c, 0x04},
++{0x341d, 0x00},
++{0x341e, 0x03},
++{0x3440, 0x00},
++{0x3441, 0x00},
++{0x3442, 0x00},
++{0x3443, 0x00},
++{0x3444, 0x02},
++{0x3445, 0xf0},
++{0x3446, 0x02},
++{0x3447, 0x08},
++{0x3448, 0x00},
++{0x3460, 0x40},
++{0x3461, 0x40},
++{0x3462, 0x40},
++{0x3463, 0x40},
++{0x3464, 0x03},
++{0x3465, 0x01},
++{0x3466, 0x01},
++{0x3467, 0x02},
++{0x3468, 0x30},
++{0x3469, 0x00},
++{0x346a, 0x33},
++{0x346b, 0xbf},
++{0x3480, 0x40},
++{0x3481, 0x00},
++{0x3482, 0x00},
++{0x3483, 0x00},
++{0x3484, 0x0d},
++{0x3485, 0x00},
++{0x3486, 0x00},
++{0x3487, 0x00},
++{0x3488, 0x00},
++{0x3489, 0x00},
++{0x348a, 0x00},
++{0x348b, 0x04},
++{0x348c, 0x00},
++{0x348d, 0x01},
++{0x348f, 0x01},
++{0x3030, 0x0a},
++{0x3030, 0x02},
++{0x7000, 0x58},
++{0x7001, 0x7a},
++{0x7002, 0x1a},
++{0x7003, 0xc1},
++{0x7004, 0x03},
++{0x7005, 0xda},
++{0x7006, 0xbd},
++{0x7007, 0x03},
++{0x7008, 0xbd},
++{0x7009, 0x06},
++{0x700a, 0xe6},
++{0x700b, 0xec},
++{0x700c, 0xbc},
++{0x700d, 0xff},
++{0x700e, 0xbc},
++{0x700f, 0x73},
++{0x7010, 0xda},
++{0x7011, 0x72},
++{0x7012, 0x76},
++{0x7013, 0xb6},
++{0x7014, 0xee},
++{0x7015, 0xcf},
++{0x7016, 0xac},
++{0x7017, 0xd0},
++{0x7018, 0xac},
++{0x7019, 0xd1},
++{0x701a, 0x50},
++{0x701b, 0xac},
++{0x701c, 0xd2},
++{0x701d, 0xbc},
++{0x701e, 0x2e},
++{0x701f, 0xb4},
++{0x7020, 0x00},
++{0x7021, 0xdc},
++{0x7022, 0xdf},
++{0x7023, 0xb0},
++{0x7024, 0x6e},
++{0x7025, 0xbd},
++{0x7026, 0x01},
++{0x7027, 0xd7},
++{0x7028, 0xed},
++{0x7029, 0xe1},
++{0x702a, 0x36},
++{0x702b, 0x30},
++{0x702c, 0xd3},
++{0x702d, 0x2e},
++{0x702e, 0x54},
++{0x702f, 0x46},
++{0x7030, 0xbc},
++{0x7031, 0x22},
++{0x7032, 0x66},
++{0x7033, 0xbc},
++{0x7034, 0x24},
++{0x7035, 0x2c},
++{0x7036, 0x28},
++{0x7037, 0xbc},
++{0x7038, 0x3c},
++{0x7039, 0xa1},
++{0x703a, 0xac},
++{0x703b, 0xd8},
++{0x703c, 0xd6},
++{0x703d, 0xb4},
++{0x703e, 0x04},
++{0x703f, 0x46},
++{0x7040, 0xb7},
++{0x7041, 0x04},
++{0x7042, 0xbe},
++{0x7043, 0x08},
++{0x7044, 0xc3},
++{0x7045, 0xd9},
++{0x7046, 0xad},
++{0x7047, 0xc3},
++{0x7048, 0xbc},
++{0x7049, 0x19},
++{0x704a, 0xc1},
++{0x704b, 0x27},
++{0x704c, 0xe7},
++{0x704d, 0x00},
++{0x704e, 0x50},
++{0x704f, 0x20},
++{0x7050, 0xb8},
++{0x7051, 0x02},
++{0x7052, 0xbc},
++{0x7053, 0x17},
++{0x7054, 0xdb},
++{0x7055, 0xc7},
++{0x7056, 0xb8},
++{0x7057, 0x00},
++{0x7058, 0x28},
++{0x7059, 0x54},
++{0x705a, 0xb4},
++{0x705b, 0x14},
++{0x705c, 0xab},
++{0x705d, 0xbe},
++{0x705e, 0x06},
++{0x705f, 0xd8},
++{0x7060, 0xd6},
++{0x7061, 0x00},
++{0x7062, 0xb4},
++{0x7063, 0xc7},
++{0x7064, 0x07},
++{0x7065, 0xb9},
++{0x7066, 0x05},
++{0x7067, 0xee},
++{0x7068, 0xe6},
++{0x7069, 0xad},
++{0x706a, 0xb4},
++{0x706b, 0x26},
++{0x706c, 0x19},
++{0x706d, 0xc1},
++{0x706e, 0x3a},
++{0x706f, 0xc3},
++{0x7070, 0xaf},
++{0x7071, 0x00},
++{0x7072, 0xc0},
++{0x7073, 0x3c},
++{0x7074, 0xc3},
++{0x7075, 0xbe},
++{0x7076, 0xe7},
++{0x7077, 0x00},
++{0x7078, 0x15},
++{0x7079, 0xc2},
++{0x707a, 0x40},
++{0x707b, 0xc3},
++{0x707c, 0xa4},
++{0x707d, 0xc0},
++{0x707e, 0x3c},
++{0x707f, 0x00},
++{0x7080, 0xb9},
++{0x7081, 0x64},
++{0x7082, 0x29},
++{0x7083, 0x00},
++{0x7084, 0xb8},
++{0x7085, 0x12},
++{0x7086, 0xbe},
++{0x7087, 0x01},
++{0x7088, 0xd0},
++{0x7089, 0xbc},
++{0x708a, 0x01},
++{0x708b, 0xac},
++{0x708c, 0x37},
++{0x708d, 0xd2},
++{0x708e, 0xac},
++{0x708f, 0x45},
++{0x7090, 0xad},
++{0x7091, 0x28},
++{0x7092, 0x00},
++{0x7093, 0xb8},
++{0x7094, 0x00},
++{0x7095, 0xbc},
++{0x7096, 0x01},
++{0x7097, 0x36},
++{0x7098, 0xd3},
++{0x7099, 0x30},
++{0x709a, 0x04},
++{0x709b, 0xe0},
++{0x709c, 0xd8},
++{0x709d, 0xb4},
++{0x709e, 0xe9},
++{0x709f, 0x00},
++{0x70a0, 0xbe},
++{0x70a1, 0x05},
++{0x70a2, 0x62},
++{0x70a3, 0x07},
++{0x70a4, 0xb9},
++{0x70a5, 0x05},
++{0x70a6, 0xad},
++{0x70a7, 0xc3},
++{0x70a8, 0xcf},
++{0x70a9, 0x00},
++{0x70aa, 0x15},
++{0x70ab, 0xc2},
++{0x70ac, 0x59},
++{0x70ad, 0xc3},
++{0x70ae, 0xc9},
++{0x70af, 0xc0},
++{0x70b0, 0x55},
++{0x70b1, 0x00},
++{0x70b2, 0x46},
++{0x70b3, 0xa1},
++{0x70b4, 0xb9},
++{0x70b5, 0x64},
++{0x70b6, 0x29},
++{0x70b7, 0x00},
++{0x70b8, 0xb8},
++{0x70b9, 0x02},
++{0x70ba, 0xbe},
++{0x70bb, 0x02},
++{0x70bc, 0xd0},
++{0x70bd, 0xdc},
++{0x70be, 0xac},
++{0x70bf, 0xbc},
++{0x70c0, 0x01},
++{0x70c1, 0x37},
++{0x70c2, 0xac},
++{0x70c3, 0xd2},
++{0x70c4, 0x45},
++{0x70c5, 0xad},
++{0x70c6, 0x28},
++{0x70c7, 0x00},
++{0x70c8, 0xb8},
++{0x70c9, 0x00},
++{0x70ca, 0xbc},
++{0x70cb, 0x01},
++{0x70cc, 0x36},
++{0x70cd, 0x30},
++{0x70ce, 0xe0},
++{0x70cf, 0xd8},
++{0x70d0, 0xb5},
++{0x70d1, 0x0b},
++{0x70d2, 0xd6},
++{0x70d3, 0xbe},
++{0x70d4, 0x07},
++{0x70d5, 0x00},
++{0x70d6, 0x62},
++{0x70d7, 0x07},
++{0x70d8, 0xb9},
++{0x70d9, 0x05},
++{0x70da, 0xad},
++{0x70db, 0xc3},
++{0x70dc, 0xcf},
++{0x70dd, 0x46},
++{0x70de, 0xcd},
++{0x70df, 0x07},
++{0x70e0, 0xcd},
++{0x70e1, 0x00},
++{0x70e2, 0xe3},
++{0x70e3, 0x18},
++{0x70e4, 0xc2},
++{0x70e5, 0xa2},
++{0x70e6, 0xb9},
++{0x70e7, 0x64},
++{0x70e8, 0xd1},
++{0x70e9, 0xdd},
++{0x70ea, 0xac},
++{0x70eb, 0xcf},
++{0x70ec, 0xdf},
++{0x70ed, 0xb5},
++{0x70ee, 0x19},
++{0x70ef, 0x46},
++{0x70f0, 0x50},
++{0x70f1, 0xb6},
++{0x70f2, 0xee},
++{0x70f3, 0xe8},
++{0x70f4, 0xe6},
++{0x70f5, 0xbc},
++{0x70f6, 0x31},
++{0x70f7, 0xe1},
++{0x70f8, 0x36},
++{0x70f9, 0x30},
++{0x70fa, 0xd3},
++{0x70fb, 0x2e},
++{0x70fc, 0x54},
++{0x70fd, 0xbd},
++{0x70fe, 0x03},
++{0x70ff, 0xec},
++{0x7100, 0x2c},
++{0x7101, 0x50},
++{0x7102, 0x20},
++{0x7103, 0x04},
++{0x7104, 0xb8},
++{0x7105, 0x02},
++{0x7106, 0xbc},
++{0x7107, 0x18},
++{0x7108, 0xc7},
++{0x7109, 0xb8},
++{0x710a, 0x00},
++{0x710b, 0x28},
++{0x710c, 0x54},
++{0x710d, 0xbc},
++{0x710e, 0x02},
++{0x710f, 0xb4},
++{0x7110, 0xda},
++{0x7111, 0xbe},
++{0x7112, 0x04},
++{0x7113, 0xd6},
++{0x7114, 0xd8},
++{0x7115, 0xab},
++{0x7116, 0x00},
++{0x7117, 0x62},
++{0x7118, 0x07},
++{0x7119, 0xb9},
++{0x711a, 0x05},
++{0x711b, 0xad},
++{0x711c, 0xc3},
++{0x711d, 0xbc},
++{0x711e, 0xe7},
++{0x711f, 0xb9},
++{0x7120, 0x64},
++{0x7121, 0x29},
++{0x7122, 0x00},
++{0x7123, 0xb8},
++{0x7124, 0x02},
++{0x7125, 0xbe},
++{0x7126, 0x00},
++{0x7127, 0x45},
++{0x7128, 0xad},
++{0x7129, 0xe2},
++{0x712a, 0x28},
++{0x712b, 0x00},
++{0x712c, 0xb8},
++{0x712d, 0x00},
++{0x712e, 0xe0},
++{0x712f, 0xd8},
++{0x7130, 0xb4},
++{0x7131, 0xe9},
++{0x7132, 0xbe},
++{0x7133, 0x03},
++{0x7134, 0x00},
++{0x7135, 0x30},
++{0x7136, 0x62},
++{0x7137, 0x07},
++{0x7138, 0xb9},
++{0x7139, 0x05},
++{0x713a, 0xad},
++{0x713b, 0xc3},
++{0x713c, 0xcf},
++{0x713d, 0x42},
++{0x713e, 0xe4},
++{0x713f, 0xcd},
++{0x7140, 0x07},
++{0x7141, 0xcd},
++{0x7142, 0x00},
++{0x7143, 0x00},
++{0x7144, 0x17},
++{0x7145, 0xc2},
++{0x7146, 0xbb},
++{0x7147, 0xde},
++{0x7148, 0xcf},
++{0x7149, 0xdf},
++{0x714a, 0xac},
++{0x714b, 0xd1},
++{0x714c, 0x44},
++{0x714d, 0xac},
++{0x714e, 0xb9},
++{0x714f, 0x76},
++{0x7150, 0xb8},
++{0x7151, 0x08},
++{0x7152, 0xb6},
++{0x7153, 0xfe},
++{0x7154, 0xb4},
++{0x7155, 0xca},
++{0x7156, 0xd6},
++{0x7157, 0xd8},
++{0x7158, 0xab},
++{0x7159, 0x00},
++{0x715a, 0xe1},
++{0x715b, 0x36},
++{0x715c, 0x30},
++{0x715d, 0xd3},
++{0x715e, 0xbc},
++{0x715f, 0x29},
++{0x7160, 0xb4},
++{0x7161, 0x1f},
++{0x7162, 0xaa},
++{0x7163, 0xbd},
++{0x7164, 0x01},
++{0x7165, 0xb8},
++{0x7166, 0x0c},
++{0x7167, 0x45},
++{0x7168, 0xa4},
++{0x7169, 0xbd},
++{0x716a, 0x03},
++{0x716b, 0xec},
++{0x716c, 0xbc},
++{0x716d, 0x3d},
++{0x716e, 0xc3},
++{0x716f, 0xcf},
++{0x7170, 0x42},
++{0x7171, 0xb8},
++{0x7172, 0x00},
++{0x7173, 0xe4},
++{0x7174, 0xd5},
++{0x7175, 0x00},
++{0x7176, 0xb6},
++{0x7177, 0x00},
++{0x7178, 0x74},
++{0x7179, 0xbd},
++{0x717a, 0x03},
++{0x717b, 0x40},
++{0x717c, 0xb5},
++{0x717d, 0x39},
++{0x717e, 0x58},
++{0x717f, 0xdd},
++{0x7180, 0x19},
++{0x7181, 0xc1},
++{0x7182, 0xc8},
++{0x7183, 0xbd},
++{0x7184, 0x06},
++{0x7185, 0x17},
++{0x7186, 0xc1},
++{0x7187, 0xc6},
++{0x7188, 0xe8},
++{0x7189, 0x00},
++{0x718a, 0xc0},
++{0x718b, 0xc8},
++{0x718c, 0xe6},
++{0x718d, 0x95},
++{0x718e, 0x15},
++{0x718f, 0x00},
++{0x7190, 0xbc},
++{0x7191, 0x19},
++{0x7192, 0xb9},
++{0x7193, 0xf6},
++{0x7194, 0x14},
++{0x7195, 0xc1},
++{0x7196, 0xd0},
++{0x7197, 0xd1},
++{0x7198, 0xac},
++{0x7199, 0x37},
++{0x719a, 0xbc},
++{0x719b, 0x35},
++{0x719c, 0x36},
++{0x719d, 0x30},
++{0x719e, 0xe1},
++{0x719f, 0xd3},
++{0x71a0, 0x7a},
++{0x71a1, 0xb6},
++{0x71a2, 0x0c},
++{0x71a3, 0xff},
++{0x71a4, 0xb4},
++{0x71a5, 0xc7},
++{0x71a6, 0xd9},
++{0x71a7, 0x00},
++{0x71a8, 0xbd},
++{0x71a9, 0x01},
++{0x71aa, 0x56},
++{0x71ab, 0xc0},
++{0x71ac, 0xda},
++{0x71ad, 0xb4},
++{0x71ae, 0x1f},
++{0x71af, 0x56},
++{0x71b0, 0xaa},
++{0x71b1, 0xbc},
++{0x71b2, 0x08},
++{0x71b3, 0x00},
++{0x71b4, 0x57},
++{0x71b5, 0xe8},
++{0x71b6, 0xb5},
++{0x71b7, 0x36},
++{0x71b8, 0x00},
++{0x71b9, 0x54},
++{0x71ba, 0xe7},
++{0x71bb, 0xc8},
++{0x71bc, 0xb4},
++{0x71bd, 0x1f},
++{0x71be, 0x56},
++{0x71bf, 0xaa},
++{0x71c0, 0xbc},
++{0x71c1, 0x08},
++{0x71c2, 0x57},
++{0x71c3, 0x00},
++{0x71c4, 0xb5},
++{0x71c5, 0x36},
++{0x71c6, 0x00},
++{0x71c7, 0x54},
++{0x71c8, 0xc8},
++{0x71c9, 0xb5},
++{0x71ca, 0x18},
++{0x71cb, 0xd9},
++{0x71cc, 0x00},
++{0x71cd, 0xbd},
++{0x71ce, 0x01},
++{0x71cf, 0x56},
++{0x71d0, 0x08},
++{0x71d1, 0x57},
++{0x71d2, 0xe8},
++{0x71d3, 0xb4},
++{0x71d4, 0x42},
++{0x71d5, 0x00},
++{0x71d6, 0x54},
++{0x71d7, 0xe7},
++{0x71d8, 0xc8},
++{0x71d9, 0xab},
++{0x71da, 0x00},
++{0x71db, 0x66},
++{0x71dc, 0x62},
++{0x71dd, 0x06},
++{0x71de, 0x74},
++{0x71df, 0xb9},
++{0x71e0, 0x05},
++{0x71e1, 0xb7},
++{0x71e2, 0x14},
++{0x71e3, 0x0e},
++{0x71e4, 0xb7},
++{0x71e5, 0x04},
++{0x71e6, 0xc8},
++{0x7600, 0x04},
++{0x7601, 0x80},
++{0x7602, 0x07},
++{0x7603, 0x44},
++{0x7604, 0x05},
++{0x7605, 0x33},
++{0x7606, 0x0f},
++{0x7607, 0x00},
++{0x7608, 0x07},
++{0x7609, 0x40},
++{0x760a, 0x04},
++{0x760b, 0xe5},
++{0x760c, 0x06},
++{0x760d, 0x50},
++{0x760e, 0x04},
++{0x760f, 0xe4},
++{0x7610, 0x00},
++{0x7611, 0x00},
++{0x7612, 0x06},
++{0x7613, 0x5c},
++{0x7614, 0x00},
++{0x7615, 0x0f},
++{0x7616, 0x06},
++{0x7617, 0x1c},
++{0x7618, 0x00},
++{0x7619, 0x02},
++{0x761a, 0x06},
++{0x761b, 0xa2},
++{0x761c, 0x00},
++{0x761d, 0x01},
++{0x761e, 0x06},
++{0x761f, 0xae},
++{0x7620, 0x00},
++{0x7621, 0x0e},
++{0x7622, 0x05},
++{0x7623, 0x30},
++{0x7624, 0x07},
++{0x7625, 0x00},
++{0x7626, 0x0f},
++{0x7627, 0x00},
++{0x7628, 0x04},
++{0x7629, 0xe5},
++{0x762a, 0x05},
++{0x762b, 0x33},
++{0x762c, 0x06},
++{0x762d, 0x12},
++{0x762e, 0x00},
++{0x762f, 0x01},
++{0x7630, 0x06},
++{0x7631, 0x52},
++{0x7632, 0x00},
++{0x7633, 0x01},
++{0x7634, 0x06},
++{0x7635, 0x5e},
++{0x7636, 0x04},
++{0x7637, 0xe4},
++{0x7638, 0x00},
++{0x7639, 0x01},
++{0x763a, 0x05},
++{0x763b, 0x30},
++{0x763c, 0x0f},
++{0x763d, 0x00},
++{0x763e, 0x06},
++{0x763f, 0xa6},
++{0x7640, 0x00},
++{0x7641, 0x02},
++{0x7642, 0x06},
++{0x7643, 0x26},
++{0x7644, 0x00},
++{0x7645, 0x02},
++{0x7646, 0x05},
++{0x7647, 0x33},
++{0x7648, 0x06},
++{0x7649, 0x20},
++{0x764a, 0x0f},
++{0x764b, 0x00},
++{0x764c, 0x06},
++{0x764d, 0x56},
++{0x764e, 0x00},
++{0x764f, 0x02},
++{0x7650, 0x06},
++{0x7651, 0x16},
++{0x7652, 0x05},
++{0x7653, 0x33},
++{0x7654, 0x06},
++{0x7655, 0x10},
++{0x7656, 0x0f},
++{0x7657, 0x00},
++{0x7658, 0x06},
++{0x7659, 0x10},
++{0x765a, 0x0f},
++{0x765b, 0x00},
++{0x765c, 0x06},
++{0x765d, 0x20},
++{0x765e, 0x0f},
++{0x765f, 0x00},
++{0x7660, 0x00},
++{0x7661, 0x00},
++{0x7662, 0x00},
++{0x7663, 0x02},
++{0x7664, 0x04},
++{0x7665, 0xe5},
++{0x7666, 0x04},
++{0x7667, 0xe4},
++{0x7668, 0x0f},
++{0x7669, 0x00},
++{0x766a, 0x00},
++{0x766b, 0x00},
++{0x766c, 0x00},
++{0x766d, 0x01},
++{0x766e, 0x04},
++{0x766f, 0xe5},
++{0x7670, 0x04},
++{0x7671, 0xe4},
++{0x7672, 0x0f},
++{0x7673, 0x00},
++{0x7674, 0x00},
++{0x7675, 0x02},
++{0x7676, 0x04},
++{0x7677, 0xe4},
++{0x7678, 0x00},
++{0x7679, 0x02},
++{0x767a, 0x04},
++{0x767b, 0xc4},
++{0x767c, 0x00},
++{0x767d, 0x02},
++{0x767e, 0x04},
++{0x767f, 0xc4},
++{0x7680, 0x05},
++{0x7681, 0x83},
++{0x7682, 0x0f},
++{0x7683, 0x00},
++{0x7684, 0x00},
++{0x7685, 0x02},
++{0x7686, 0x04},
++{0x7687, 0xe4},
++{0x7688, 0x00},
++{0x7689, 0x02},
++{0x768a, 0x04},
++{0x768b, 0xc4},
++{0x768c, 0x00},
++{0x768d, 0x02},
++{0x768e, 0x04},
++{0x768f, 0xc4},
++{0x7690, 0x05},
++{0x7691, 0x83},
++{0x7692, 0x03},
++{0x7693, 0x0b},
++{0x7694, 0x05},
++{0x7695, 0x83},
++{0x7696, 0x00},
++{0x7697, 0x07},
++{0x7698, 0x05},
++{0x7699, 0x03},
++{0x769a, 0x00},
++{0x769b, 0x05},
++{0x769c, 0x05},
++{0x769d, 0x32},
++{0x769e, 0x05},
++{0x769f, 0x30},
++{0x76a0, 0x00},
++{0x76a1, 0x02},
++{0x76a2, 0x05},
++{0x76a3, 0x78},
++{0x76a4, 0x00},
++{0x76a5, 0x01},
++{0x76a6, 0x05},
++{0x76a7, 0x7c},
++{0x76a8, 0x03},
++{0x76a9, 0x9a},
++{0x76aa, 0x05},
++{0x76ab, 0x83},
++{0x76ac, 0x00},
++{0x76ad, 0x04},
++{0x76ae, 0x05},
++{0x76af, 0x03},
++{0x76b0, 0x00},
++{0x76b1, 0x03},
++{0x76b2, 0x05},
++{0x76b3, 0x32},
++{0x76b4, 0x05},
++{0x76b5, 0x30},
++{0x76b6, 0x00},
++{0x76b7, 0x02},
++{0x76b8, 0x05},
++{0x76b9, 0x78},
++{0x76ba, 0x00},
++{0x76bb, 0x01},
++{0x76bc, 0x05},
++{0x76bd, 0x7c},
++{0x76be, 0x03},
++{0x76bf, 0x99},
++{0x76c0, 0x05},
++{0x76c1, 0x83},
++{0x76c2, 0x00},
++{0x76c3, 0x03},
++{0x76c4, 0x05},
++{0x76c5, 0x03},
++{0x76c6, 0x00},
++{0x76c7, 0x01},
++{0x76c8, 0x05},
++{0x76c9, 0x32},
++{0x76ca, 0x05},
++{0x76cb, 0x30},
++{0x76cc, 0x00},
++{0x76cd, 0x02},
++{0x76ce, 0x05},
++{0x76cf, 0x78},
++{0x76d0, 0x00},
++{0x76d1, 0x01},
++{0x76d2, 0x05},
++{0x76d3, 0x7c},
++{0x76d4, 0x03},
++{0x76d5, 0x98},
++{0x76d6, 0x05},
++{0x76d7, 0x83},
++{0x76d8, 0x00},
++{0x76d9, 0x00},
++{0x76da, 0x05},
++{0x76db, 0x03},
++{0x76dc, 0x00},
++{0x76dd, 0x01},
++{0x76de, 0x05},
++{0x76df, 0x32},
++{0x76e0, 0x05},
++{0x76e1, 0x30},
++{0x76e2, 0x00},
++{0x76e3, 0x02},
++{0x76e4, 0x05},
++{0x76e5, 0x78},
++{0x76e6, 0x00},
++{0x76e7, 0x01},
++{0x76e8, 0x05},
++{0x76e9, 0x7c},
++{0x76ea, 0x03},
++{0x76eb, 0x97},
++{0x76ec, 0x05},
++{0x76ed, 0x83},
++{0x76ee, 0x00},
++{0x76ef, 0x00},
++{0x76f0, 0x05},
++{0x76f1, 0x03},
++{0x76f2, 0x05},
++{0x76f3, 0x32},
++{0x76f4, 0x05},
++{0x76f5, 0x30},
++{0x76f6, 0x00},
++{0x76f7, 0x02},
++{0x76f8, 0x05},
++{0x76f9, 0x78},
++{0x76fa, 0x00},
++{0x76fb, 0x01},
++{0x76fc, 0x05},
++{0x76fd, 0x7c},
++{0x76fe, 0x03},
++{0x76ff, 0x96},
++{0x7700, 0x05},
++{0x7701, 0x83},
++{0x7702, 0x05},
++{0x7703, 0x03},
++{0x7704, 0x05},
++{0x7705, 0x32},
++{0x7706, 0x05},
++{0x7707, 0x30},
++{0x7708, 0x00},
++{0x7709, 0x02},
++{0x770a, 0x05},
++{0x770b, 0x78},
++{0x770c, 0x00},
++{0x770d, 0x01},
++{0x770e, 0x05},
++{0x770f, 0x7c},
++{0x7710, 0x03},
++{0x7711, 0x95},
++{0x7712, 0x05},
++{0x7713, 0x83},
++{0x7714, 0x05},
++{0x7715, 0x03},
++{0x7716, 0x05},
++{0x7717, 0x32},
++{0x7718, 0x05},
++{0x7719, 0x30},
++{0x771a, 0x00},
++{0x771b, 0x02},
++{0x771c, 0x05},
++{0x771d, 0x78},
++{0x771e, 0x00},
++{0x771f, 0x01},
++{0x7720, 0x05},
++{0x7721, 0x7c},
++{0x7722, 0x03},
++{0x7723, 0x94},
++{0x7724, 0x05},
++{0x7725, 0x83},
++{0x7726, 0x00},
++{0x7727, 0x01},
++{0x7728, 0x05},
++{0x7729, 0x03},
++{0x772a, 0x00},
++{0x772b, 0x01},
++{0x772c, 0x05},
++{0x772d, 0x32},
++{0x772e, 0x05},
++{0x772f, 0x30},
++{0x7730, 0x00},
++{0x7731, 0x02},
++{0x7732, 0x05},
++{0x7733, 0x78},
++{0x7734, 0x00},
++{0x7735, 0x01},
++{0x7736, 0x05},
++{0x7737, 0x7c},
++{0x7738, 0x03},
++{0x7739, 0x93},
++{0x773a, 0x05},
++{0x773b, 0x83},
++{0x773c, 0x00},
++{0x773d, 0x00},
++{0x773e, 0x05},
++{0x773f, 0x03},
++{0x7740, 0x00},
++{0x7741, 0x00},
++{0x7742, 0x05},
++{0x7743, 0x32},
++{0x7744, 0x05},
++{0x7745, 0x30},
++{0x7746, 0x00},
++{0x7747, 0x02},
++{0x7748, 0x05},
++{0x7749, 0x78},
++{0x774a, 0x00},
++{0x774b, 0x01},
++{0x774c, 0x05},
++{0x774d, 0x7c},
++{0x774e, 0x03},
++{0x774f, 0x92},
++{0x7750, 0x05},
++{0x7751, 0x83},
++{0x7752, 0x05},
++{0x7753, 0x03},
++{0x7754, 0x00},
++{0x7755, 0x00},
++{0x7756, 0x05},
++{0x7757, 0x32},
++{0x7758, 0x05},
++{0x7759, 0x30},
++{0x775a, 0x00},
++{0x775b, 0x02},
++{0x775c, 0x05},
++{0x775d, 0x78},
++{0x775e, 0x00},
++{0x775f, 0x01},
++{0x7760, 0x05},
++{0x7761, 0x7c},
++{0x7762, 0x03},
++{0x7763, 0x91},
++{0x7764, 0x05},
++{0x7765, 0x83},
++{0x7766, 0x05},
++{0x7767, 0x03},
++{0x7768, 0x05},
++{0x7769, 0x32},
++{0x776a, 0x05},
++{0x776b, 0x30},
++{0x776c, 0x00},
++{0x776d, 0x02},
++{0x776e, 0x05},
++{0x776f, 0x78},
++{0x7770, 0x00},
++{0x7771, 0x01},
++{0x7772, 0x05},
++{0x7773, 0x7c},
++{0x7774, 0x03},
++{0x7775, 0x90},
++{0x7776, 0x05},
++{0x7777, 0x83},
++{0x7778, 0x05},
++{0x7779, 0x03},
++{0x777a, 0x05},
++{0x777b, 0x32},
++{0x777c, 0x05},
++{0x777d, 0x30},
++{0x777e, 0x00},
++{0x777f, 0x02},
++{0x7780, 0x05},
++{0x7781, 0x78},
++{0x7782, 0x00},
++{0x7783, 0x01},
++{0x7784, 0x05},
++{0x7785, 0x7c},
++{0x7786, 0x02},
++{0x7787, 0x90},
++{0x7788, 0x05},
++{0x7789, 0x03},
++{0x778a, 0x07},
++{0x778b, 0x00},
++{0x778c, 0x0f},
++{0x778d, 0x00},
++{0x778e, 0x08},
++{0x778f, 0x30},
++{0x7790, 0x08},
++{0x7791, 0xee},
++{0x7792, 0x0f},
++{0x7793, 0x00},
++{0x7794, 0x05},
++{0x7795, 0x33},
++{0x7796, 0x04},
++{0x7797, 0xe5},
++{0x7798, 0x06},
++{0x7799, 0x52},
++{0x779a, 0x04},
++{0x779b, 0xe4},
++{0x779c, 0x00},
++{0x779d, 0x00},
++{0x779e, 0x06},
++{0x779f, 0x5e},
++{0x77a0, 0x00},
++{0x77a1, 0x0f},
++{0x77a2, 0x06},
++{0x77a3, 0x1e},
++{0x77a4, 0x00},
++{0x77a5, 0x02},
++{0x77a6, 0x06},
++{0x77a7, 0xa2},
++{0x77a8, 0x00},
++{0x77a9, 0x01},
++{0x77aa, 0x06},
++{0x77ab, 0xae},
++{0x77ac, 0x00},
++{0x77ad, 0x03},
++{0x77ae, 0x05},
++{0x77af, 0x30},
++{0x77b0, 0x09},
++{0x77b1, 0x19},
++{0x77b2, 0x0f},
++{0x77b3, 0x00},
++{0x77b4, 0x05},
++{0x77b5, 0x33},
++{0x77b6, 0x04},
++{0x77b7, 0xe5},
++{0x77b8, 0x06},
++{0x77b9, 0x52},
++{0x77ba, 0x04},
++{0x77bb, 0xe4},
++{0x77bc, 0x00},
++{0x77bd, 0x00},
++{0x77be, 0x06},
++{0x77bf, 0x5e},
++{0x77c0, 0x00},
++{0x77c1, 0x0f},
++{0x77c2, 0x06},
++{0x77c3, 0x1e},
++{0x77c4, 0x00},
++{0x77c5, 0x02},
++{0x77c6, 0x06},
++{0x77c7, 0xa2},
++{0x77c8, 0x00},
++{0x77c9, 0x01},
++{0x77ca, 0x06},
++{0x77cb, 0xae},
++{0x77cc, 0x00},
++{0x77cd, 0x03},
++{0x77ce, 0x05},
++{0x77cf, 0x30},
++{0x77d0, 0x0f},
++{0x77d1, 0x00},
++{0x77d2, 0x00},
++{0x77d3, 0x00},
++{0x77d4, 0x00},
++{0x77d5, 0x02},
++{0x77d6, 0x04},
++{0x77d7, 0xe5},
++{0x77d8, 0x04},
++{0x77d9, 0xe4},
++{0x77da, 0x05},
++{0x77db, 0x33},
++{0x77dc, 0x07},
++{0x77dd, 0x10},
++{0x77de, 0x00},
++{0x77df, 0x00},
++{0x77e0, 0x01},
++{0x77e1, 0xbb},
++{0x77e2, 0x00},
++{0x77e3, 0x00},
++{0x77e4, 0x01},
++{0x77e5, 0xaa},
++{0x77e6, 0x00},
++{0x77e7, 0x00},
++{0x77e8, 0x01},
++{0x77e9, 0x99},
++{0x77ea, 0x00},
++{0x77eb, 0x00},
++{0x77ec, 0x01},
++{0x77ed, 0x88},
++{0x77ee, 0x00},
++{0x77ef, 0x00},
++{0x77f0, 0x01},
++{0x77f1, 0x77},
++{0x77f2, 0x00},
++{0x77f3, 0x00},
++{0x77f4, 0x01},
++{0x77f5, 0x66},
++{0x77f6, 0x00},
++{0x77f7, 0x00},
++{0x77f8, 0x01},
++{0x77f9, 0x55},
++{0x77fa, 0x00},
++{0x77fb, 0x00},
++{0x77fc, 0x01},
++{0x77fd, 0x44},
++{0x77fe, 0x00},
++{0x77ff, 0x00},
++{0x7800, 0x01},
++{0x7801, 0x33},
++{0x7802, 0x00},
++{0x7803, 0x00},
++{0x7804, 0x01},
++{0x7805, 0x22},
++{0x7806, 0x00},
++{0x7807, 0x00},
++{0x7808, 0x01},
++{0x7809, 0x11},
++{0x780a, 0x00},
++{0x780b, 0x00},
++{0x780c, 0x01},
++{0x780d, 0x00},
++{0x780e, 0x01},
++{0x780f, 0xff},
++{0x7810, 0x07},
++{0x7811, 0x00},
++{0x7812, 0x02},
++{0x7813, 0xa0},
++{0x7814, 0x0f},
++{0x7815, 0x00},
++{0x7816, 0x08},
++{0x7817, 0x35},
++{0x7818, 0x06},
++{0x7819, 0x52},
++{0x781a, 0x04},
++{0x781b, 0xe4},
++{0x781c, 0x00},
++{0x781d, 0x00},
++{0x781e, 0x06},
++{0x781f, 0x5e},
++{0x7820, 0x05},
++{0x7821, 0x33},
++{0x7822, 0x09},
++{0x7823, 0x19},
++{0x7824, 0x06},
++{0x7825, 0x1e},
++{0x7826, 0x05},
++{0x7827, 0x33},
++{0x7828, 0x00},
++{0x7829, 0x01},
++{0x782a, 0x06},
++{0x782b, 0x24},
++{0x782c, 0x06},
++{0x782d, 0x20},
++{0x782e, 0x0f},
++{0x782f, 0x00},
++{0x7830, 0x08},
++{0x7831, 0x35},
++{0x7832, 0x07},
++{0x7833, 0x10},
++{0x7834, 0x00},
++{0x7835, 0x00},
++{0x7836, 0x01},
++{0x7837, 0xbb},
++{0x7838, 0x00},
++{0x7839, 0x00},
++{0x783a, 0x01},
++{0x783b, 0xaa},
++{0x783c, 0x00},
++{0x783d, 0x00},
++{0x783e, 0x01},
++{0x783f, 0x99},
++{0x7840, 0x00},
++{0x7841, 0x00},
++{0x7842, 0x01},
++{0x7843, 0x88},
++{0x7844, 0x00},
++{0x7845, 0x00},
++{0x7846, 0x01},
++{0x7847, 0x77},
++{0x7848, 0x00},
++{0x7849, 0x00},
++{0x784a, 0x01},
++{0x784b, 0x66},
++{0x784c, 0x00},
++{0x784d, 0x00},
++{0x784e, 0x01},
++{0x784f, 0x55},
++{0x7850, 0x00},
++{0x7851, 0x00},
++{0x7852, 0x01},
++{0x7853, 0x44},
++{0x7854, 0x00},
++{0x7855, 0x00},
++{0x7856, 0x01},
++{0x7857, 0x33},
++{0x7858, 0x00},
++{0x7859, 0x00},
++{0x785a, 0x01},
++{0x785b, 0x22},
++{0x785c, 0x00},
++{0x785d, 0x00},
++{0x785e, 0x01},
++{0x785f, 0x11},
++{0x7860, 0x00},
++{0x7861, 0x00},
++{0x7862, 0x01},
++{0x7863, 0x00},
++{0x7864, 0x07},
++{0x7865, 0x00},
++{0x7866, 0x01},
++{0x7867, 0xff},
++{0x7868, 0x02},
++{0x7869, 0xa0},
++{0x786a, 0x0f},
++{0x786b, 0x00},
++{0x786c, 0x08},
++{0x786d, 0x3a},
++{0x786e, 0x08},
++{0x786f, 0x6a},
++{0x7870, 0x0f},
++{0x7871, 0x00},
++{0x7872, 0x04},
++{0x7873, 0xc0},
++{0x7874, 0x09},
++{0x7875, 0x19},
++{0x7876, 0x04},
++{0x7877, 0x99},
++{0x7878, 0x07},
++{0x7879, 0x14},
++{0x787a, 0x00},
++{0x787b, 0x01},
++{0x787c, 0x04},
++{0x787d, 0xa4},
++{0x787e, 0x00},
++{0x787f, 0x0f},
++{0x7880, 0x00},
++{0x7881, 0x0f},
++{0x7882, 0x04},
++{0x7883, 0xa6},
++{0x7884, 0x00},
++{0x7885, 0x00},
++{0x7886, 0x04},
++{0x7887, 0xa0},
++{0x7888, 0x04},
++{0x7889, 0x80},
++{0x788a, 0x04},
++{0x788b, 0x00},
++{0x788c, 0x05},
++{0x788d, 0x03},
++{0x788e, 0x06},
++{0x788f, 0x00},
++{0x7890, 0x0f},
++{0x7891, 0x00},
++{0x7892, 0x0f},
++{0x7893, 0x00},
++{0x7894, 0x0f},
++{0x7895, 0x00},
++{0x30a0, 0x00},
++{0x30a1, 0x00},
++{0x30a2, 0x00},
++{0x30a3, 0x00},
++{0x30a4, 0x07},
++{0x30a5, 0x8f},
++{0x30a6, 0x04},
++{0x30a7, 0x47},
++{0x30a8, 0x00},
++{0x30a9, 0x04},
++{0x30aa, 0x00},
++{0x30ab, 0x04},
++{0x30ac, 0x07},
++{0x30ad, 0x88},
++{0x30ae, 0x04},
++{0x30af, 0x40},
++{0x30b0, 0x0d},
++{0x30b1, 0xde},
++{0x30b2, 0x04},
++{0x30b3, 0x66},
++{0x3196, 0x00},
++{0x3197, 0x0a},
++{0x3195, 0x29},
++{0x315a, 0x02},
++{0x315b, 0x00},
++{0x30bb, 0x40},
++{0x3250, 0xf7},
++{0x3012, 0x01},
++};
+diff --git a/drivers/media/i2c/soc_camera/ov490_ov10640.c b/drivers/media/i2c/soc_camera/ov490_ov10640.c
+new file mode 100644
+index 0000000..e698f59
+--- /dev/null
++++ b/drivers/media/i2c/soc_camera/ov490_ov10640.c
+@@ -0,0 +1,1134 @@
++/*
++ * OmniVision ov490-ov10640 sensor camera driver
++ *
++ * Copyright (C) 2016-2018 Cogent Embedded, Inc.
++ *
++ * This program is free software; you can redistribute it and/or modify it
++ * under the terms of the GNU General Public License as published by the
++ * Free Software Foundation; either version 2 of the License, or (at your
++ * option) any later version.
++ */
++
++#include <linux/delay.h>
++#include <linux/init.h>
++#include <linux/i2c.h>
++#include <linux/module.h>
++#include <linux/of_graph.h>
++#include <linux/videodev2.h>
++
++#include <media/soc_camera.h>
++#include <media/v4l2-common.h>
++#include <media/v4l2-ctrls.h>
++#include <media/v4l2-fwnode.h>
++
++#include "max9286.h"
++#include "ov490_ov10640.h"
++
++#define OV490_I2C_ADDR 0x24
++
++#define OV490_PID 0x300a
++#define OV490_VER 0x300b
++#define OV490_VERSION_REG 0x0490
++#define OV490_VERSION(pid, ver) (((pid) << 8) | ((ver) & 0xff))
++
++#define OV490_ISP_HSIZE_LOW 0x60
++#define OV490_ISP_HSIZE_HIGH 0x61
++#define OV490_ISP_VSIZE_LOW 0x62
++#define OV490_ISP_VSIZE_HIGH 0x63
++
++struct ov490_priv {
++ struct v4l2_subdev sd;
++ struct v4l2_ctrl_handler hdl;
++ struct media_pad pad;
++ struct v4l2_rect rect;
++ int max_width;
++ int max_height;
++ char is_fixed_sensor;
++ int init_complete;
++ u8 id[6];
++ int exposure;
++ int gain;
++ int autogain;
++ int red;
++ int green_r;
++ int green_b;
++ int blue;
++ int awb;
++ int dvp_order;
++ /* serializers */
++ int max9286_addr;
++ int max9271_addr;
++ int ti9x4_addr;
++ int ti9x3_addr;
++ int port;
++ int gpio_resetb;
++ int active_low_resetb;
++ int gpio_fsin;
++};
++
++static int conf_link;
++module_param(conf_link, int, 0644);
++MODULE_PARM_DESC(conf_link, " Force configuration link. Used only if robust firmware flashing required (f.e. recovery)");
++
++static int dvp_order;
++module_param(dvp_order, int, 0644);
++MODULE_PARM_DESC(dvp_order, " DVP bus bits order");
++
++static int max_width;
++module_param(max_width, int, 0644);
++MODULE_PARM_DESC(max_width, " Fixed sensor width");
++
++static int max_height;
++module_param(max_height, int, 0644);
++MODULE_PARM_DESC(max_height, " Fixed sensor height");
++
++static inline struct ov490_priv *to_ov490(const struct i2c_client *client)
++{
++ return container_of(i2c_get_clientdata(client), struct ov490_priv, sd);
++}
++
++static void ov490_s_port(struct i2c_client *client, int fwd_en)
++{
++ struct ov490_priv *priv = to_ov490(client);
++ int tmp_addr;
++
++ if (priv->max9286_addr) {
++ tmp_addr = client->addr;
++ client->addr = priv->max9286_addr; /* Deserializer I2C address */
++ reg8_write(client, 0x0a, fwd_en ? 0x11 << priv->port : 0); /* Enable/disable reverse/forward control for this port */
++ usleep_range(5000, 5500); /* wait 5ms */
++ client->addr = tmp_addr;
++ };
++}
++
++static void ov490_reset(struct i2c_client *client)
++{
++ struct ov490_priv *priv = to_ov490(client);
++ int tmp_addr;
++
++ if (priv->max9286_addr) {
++ if (priv->gpio_resetb < 1 || priv->gpio_resetb > 5)
++ return;
++
++ tmp_addr = client->addr;
++ /* get out from sensor reset */
++ client->addr = priv->max9271_addr; /* MAX9271 I2C address */
++ reg8_write(client, 0x0f, (0xfe & ~BIT(priv->gpio_resetb)) |
++ (priv->active_low_resetb ? 0 : BIT(priv->gpio_resetb))); /* set GPIOn value to reset */
++ usleep_range(2000, 2500); /* wait 2ms */
++ reg8_write(client, 0x0f, (0xfe & ~BIT(priv->gpio_resetb)) |
++ (priv->active_low_resetb ? BIT(priv->gpio_resetb) : 0)); /* set GPIOn value to un-reset */
++ usleep_range(2000, 2500); /* wait 2ms */
++ client->addr = tmp_addr;
++ }
++
++ if (priv->ti9x4_addr) {
++ client->addr = priv->ti9x4_addr; /* TI9x4 I2C address */
++
++ reg8_write(client, 0x4c, (priv->port << 4) | (1 << priv->port)); /* Select RX port number */
++ usleep_range(2000, 2500); /* wait 2ms */
++ reg8_write(client, 0x6e, 0x8a); /* set GPIO1 value to reset */
++ usleep_range(2000, 2500); /* wait 2ms */
++ reg8_write(client, 0x6e, 0x9a); /* set GPIO1 value to un-reset */
++ }
++}
++
++static int ov490_set_regs(struct i2c_client *client,
++ const struct ov490_reg *regs, int nr_regs)
++{
++ int i;
++
++ for (i = 0; i < nr_regs; i++) {
++ if (reg16_write(client, regs[i].reg, regs[i].val)) {
++ usleep_range(100, 150); /* wait 100 us */
++ reg16_write(client, regs[i].reg, regs[i].val);
++ }
++ }
++
++ return 0;
++}
++
++static u8 ov490_ov10640_read(struct i2c_client *client, u16 addr)
++{
++ u8 reg_val = 0;
++
++ reg16_write(client, 0xFFFD, 0x80);
++ usleep_range(100, 150); /* wait 100 us */
++ reg16_write(client, 0xFFFE, 0x19);
++ usleep_range(100, 150); /* wait 100 us */
++ reg16_write(client, 0x5000, 0x01); /* read operation */
++ reg16_write(client, 0x5001, addr >> 8);
++ reg16_write(client, 0x5002, addr & 0xff);
++ reg16_write(client, 0xFFFE, 0x80);
++ usleep_range(100, 150); /* wait 100 us */
++ reg16_write(client, 0x00C0, 0xc1);
++ reg16_write(client, 0xFFFE, 0x19);
++ usleep_range(1000, 1500); /* wait 1 ms */
++ reg16_read(client, 0x5000, &reg_val);
++
++ return reg_val;
++}
++
++static void ov490_ov10640_write(struct i2c_client *client, u16 addr, u8 val)
++{
++ reg16_write(client, 0xFFFD, 0x80);
++ usleep_range(100, 150); /* wait 100 us */
++ reg16_write(client, 0xFFFE, 0x19);
++ usleep_range(100, 150); /* wait 100 us */
++ reg16_write(client, 0x5000, 0x00); /* write operation */
++ reg16_write(client, 0x5001, addr >> 8);
++ reg16_write(client, 0x5002, addr & 0xff);
++ reg16_write(client, 0x5003, val);
++ reg16_write(client, 0xFFFE, 0x80);
++ usleep_range(100, 150); /* wait 100 us */
++ reg16_write(client, 0x00C0, 0xc1);
++}
++
++static int ov490_s_stream(struct v4l2_subdev *sd, int enable)
++{
++ return 0;
++}
++
++static int ov490_get_fmt(struct v4l2_subdev *sd,
++ struct v4l2_subdev_pad_config *cfg,
++ struct v4l2_subdev_format *format)
++{
++ struct v4l2_mbus_framefmt *mf = &format->format;
++ struct i2c_client *client = v4l2_get_subdevdata(sd);
++ struct ov490_priv *priv = to_ov490(client);
++
++ if (format->pad)
++ return -EINVAL;
++
++ mf->width = priv->rect.width;
++ mf->height = priv->rect.height;
++ mf->code = MEDIA_BUS_FMT_YUYV8_2X8;
++ mf->colorspace = V4L2_COLORSPACE_SMPTE170M;
++ mf->field = V4L2_FIELD_NONE;
++
++ return 0;
++}
++
++static int ov490_set_fmt(struct v4l2_subdev *sd,
++ struct v4l2_subdev_pad_config *cfg,
++ struct v4l2_subdev_format *format)
++{
++ struct v4l2_mbus_framefmt *mf = &format->format;
++
++ mf->code = MEDIA_BUS_FMT_YUYV8_2X8;
++ mf->colorspace = V4L2_COLORSPACE_SMPTE170M;
++ mf->field = V4L2_FIELD_NONE;
++
++ if (format->which == V4L2_SUBDEV_FORMAT_TRY)
++ cfg->try_fmt = *mf;
++
++ return 0;
++}
++
++static int ov490_enum_mbus_code(struct v4l2_subdev *sd,
++ struct v4l2_subdev_pad_config *cfg,
++ struct v4l2_subdev_mbus_code_enum *code)
++{
++ if (code->pad || code->index > 0)
++ return -EINVAL;
++
++ code->code = MEDIA_BUS_FMT_YUYV8_2X8;
++
++ return 0;
++}
++
++static int ov490_get_edid(struct v4l2_subdev *sd, struct v4l2_edid *edid)
++{
++ struct i2c_client *client = v4l2_get_subdevdata(sd);
++ struct ov490_priv *priv = to_ov490(client);
++
++ memcpy(edid->edid, priv->id, 6);
++
++ edid->edid[6] = 0xff;
++ edid->edid[7] = client->addr;
++ edid->edid[8] = OV490_VERSION_REG >> 8;
++ edid->edid[9] = OV490_VERSION_REG & 0xff;
++
++ return 0;
++}
++
++static int ov490_set_selection(struct v4l2_subdev *sd,
++ struct v4l2_subdev_pad_config *cfg,
++ struct v4l2_subdev_selection *sel)
++{
++ struct v4l2_rect *rect = &sel->r;
++ struct i2c_client *client = v4l2_get_subdevdata(sd);
++ struct ov490_priv *priv = to_ov490(client);
++
++ if (sel->which != V4L2_SUBDEV_FORMAT_ACTIVE ||
++ sel->target != V4L2_SEL_TGT_CROP)
++ return -EINVAL;
++
++ rect->left = ALIGN(rect->left, 2);
++ rect->top = ALIGN(rect->top, 2);
++ rect->width = ALIGN(rect->width, 2);
++ rect->height = ALIGN(rect->height, 2);
++
++ if ((rect->left + rect->width > priv->max_width) ||
++ (rect->top + rect->height > priv->max_height))
++ *rect = priv->rect;
++
++ priv->rect.left = rect->left;
++ priv->rect.top = rect->top;
++ priv->rect.width = rect->width;
++ priv->rect.height = rect->height;
++
++ return 0;
++}
++
++static int ov490_get_selection(struct v4l2_subdev *sd,
++ struct v4l2_subdev_pad_config *cfg,
++ struct v4l2_subdev_selection *sel)
++{
++ struct i2c_client *client = v4l2_get_subdevdata(sd);
++ struct ov490_priv *priv = to_ov490(client);
++
++ if (sel->which != V4L2_SUBDEV_FORMAT_ACTIVE)
++ return -EINVAL;
++
++ switch (sel->target) {
++ case V4L2_SEL_TGT_CROP_BOUNDS:
++ sel->r.left = 0;
++ sel->r.top = 0;
++ sel->r.width = priv->max_width;
++ sel->r.height = priv->max_height;
++ return 0;
++ case V4L2_SEL_TGT_CROP_DEFAULT:
++ sel->r.left = 0;
++ sel->r.top = 0;
++ sel->r.width = priv->max_width;
++ sel->r.height = priv->max_height;
++ return 0;
++ case V4L2_SEL_TGT_CROP:
++ sel->r = priv->rect;
++ return 0;
++ default:
++ return -EINVAL;
++ }
++}
++
++static int ov490_g_mbus_config(struct v4l2_subdev *sd,
++ struct v4l2_mbus_config *cfg)
++{
++ cfg->flags = V4L2_MBUS_CSI2_1_LANE | V4L2_MBUS_CSI2_CHANNEL_0 |
++ V4L2_MBUS_CSI2_CONTINUOUS_CLOCK;
++ cfg->type = V4L2_MBUS_CSI2;
++
++ return 0;
++}
++
++#ifdef CONFIG_VIDEO_ADV_DEBUG
++static int ov490_g_register(struct v4l2_subdev *sd,
++ struct v4l2_dbg_register *reg)
++{
++ struct i2c_client *client = v4l2_get_subdevdata(sd);
++ int ret;
++ u8 val = 0;
++
++ ret = reg16_read(client, (u16)reg->reg, &val);
++ if (ret < 0)
++ return ret;
++
++ reg->val = val;
++ reg->size = sizeof(u16);
++
++ return 0;
++}
++
++static int ov490_s_register(struct v4l2_subdev *sd,
++ const struct v4l2_dbg_register *reg)
++{
++ struct i2c_client *client = v4l2_get_subdevdata(sd);
++ int ret;
++
++ ret = reg16_write(client, (u16)reg->reg, (u8)reg->val);
++ if ((u8)reg->reg == 0xFFFD)
++ usleep_range(100, 150); /* wait 100 us */
++ if ((u8)reg->reg == 0xFFFE)
++ usleep_range(100, 150); /* wait 100 us */
++ return ret;
++}
++#endif
++
++static struct v4l2_subdev_core_ops ov490_core_ops = {
++#ifdef CONFIG_VIDEO_ADV_DEBUG
++ .g_register = ov490_g_register,
++ .s_register = ov490_s_register,
++#endif
++};
++
++static int ov490_s_gamma(int a, int ref)
++{
++ if ((a + ref) > 0xff)
++ return 0xff;
++
++ if ((a + ref) < 0)
++ return 0;
++
++ return a + ref;
++}
++
++static int ov490_s_ctrl(struct v4l2_ctrl *ctrl)
++{
++ struct v4l2_subdev *sd = to_sd(ctrl);
++ struct i2c_client *client = v4l2_get_subdevdata(sd);
++ struct ov490_priv *priv = to_ov490(client);
++ int ret = -EINVAL;
++
++ if (!priv->init_complete)
++ return 0;
++
++ switch (ctrl->id) {
++ case V4L2_CID_BRIGHTNESS:
++ /* SDE (rough) brightness */
++ ret = reg16_write(client, 0xFFFD, 0x80);
++ ret |= reg16_write(client, 0xFFFE, 0x19);
++ usleep_range(100, 150); /* wait 100 us */
++ ret |= reg16_write(client, 0x5000, 0x00);
++ ret |= reg16_write(client, 0x5001, ctrl->val);
++ ret |= reg16_write(client, 0xFFFE, 0x80);
++ usleep_range(100, 150); /* wait 100 us */
++ ret |= reg16_write(client, 0x00C0, 0xf1);
++ break;
++ case V4L2_CID_CONTRAST:
++ ret = reg16_write(client, 0xFFFD, 0x80);
++ ret |= reg16_write(client, 0xFFFE, 0x19);
++ usleep_range(100, 150); /* wait 100 us */
++ ret |= reg16_write(client, 0x5000, ctrl->val);
++ ret |= reg16_write(client, 0xFFFE, 0x80);
++ usleep_range(100, 150); /* wait 100 us */
++ ret |= reg16_write(client, 0x00C0, 0xfd);
++ break;
++ case V4L2_CID_SATURATION:
++ ret = reg16_write(client, 0xFFFD, 0x80);
++ ret |= reg16_write(client, 0xFFFE, 0x19);
++ usleep_range(100, 150); /* wait 100 us */
++ ret |= reg16_write(client, 0x5000, ctrl->val);
++ ret |= reg16_write(client, 0xFFFE, 0x80);
++ usleep_range(100, 150); /* wait 100 us */
++ ret |= reg16_write(client, 0x00C0, 0xf3);
++ break;
++ case V4L2_CID_HUE:
++ ret = reg16_write(client, 0xFFFD, 0x80);
++ ret |= reg16_write(client, 0xFFFE, 0x19);
++ usleep_range(100, 150); /* wait 100 us */
++ ret |= reg16_write(client, 0x5000, ctrl->val);
++ ret |= reg16_write(client, 0xFFFE, 0x80);
++ usleep_range(100, 150); /* wait 100 us */
++ ret |= reg16_write(client, 0x00C0, 0xf5);
++ break;
++ case V4L2_CID_GAMMA:
++ ret = reg16_write(client, 0xFFFD, 0x80);
++ ret |= reg16_write(client, 0xFFFE, 0x19);
++ usleep_range(100, 150); /* wait 100 us */
++ ret |= reg16_write(client, 0x5000, ov490_s_gamma(ctrl->val, 0x12));
++ ret |= reg16_write(client, 0x5001, ov490_s_gamma(ctrl->val, 0x20));
++ ret |= reg16_write(client, 0x5002, ov490_s_gamma(ctrl->val, 0x3b));
++ ret |= reg16_write(client, 0x5003, ov490_s_gamma(ctrl->val, 0x5d));
++ ret |= reg16_write(client, 0x5004, ov490_s_gamma(ctrl->val, 0x6a));
++ ret |= reg16_write(client, 0x5005, ov490_s_gamma(ctrl->val, 0x76));
++ ret |= reg16_write(client, 0x5006, ov490_s_gamma(ctrl->val, 0x81));
++ ret |= reg16_write(client, 0x5007, ov490_s_gamma(ctrl->val, 0x8b));
++ ret |= reg16_write(client, 0x5008, ov490_s_gamma(ctrl->val, 0x96));
++ ret |= reg16_write(client, 0x5009, ov490_s_gamma(ctrl->val, 0x9e));
++ ret |= reg16_write(client, 0x500a, ov490_s_gamma(ctrl->val, 0xae));
++ ret |= reg16_write(client, 0x500b, ov490_s_gamma(ctrl->val, 0xbc));
++ ret |= reg16_write(client, 0x500c, ov490_s_gamma(ctrl->val, 0xcf));
++ ret |= reg16_write(client, 0x500d, ov490_s_gamma(ctrl->val, 0xde));
++ ret |= reg16_write(client, 0x500e, ov490_s_gamma(ctrl->val, 0xec));
++ ret |= reg16_write(client, 0xFFFE, 0x80);
++ usleep_range(100, 150); /* wait 100 us */
++ ret |= reg16_write(client, 0x00C0, 0xf9);
++ break;
++ case V4L2_CID_SHARPNESS:
++ ret = reg16_write(client, 0xFFFD, 0x80);
++ ret |= reg16_write(client, 0xFFFE, 0x19);
++ usleep_range(100, 150); /* wait 100 us */
++ ret |= reg16_write(client, 0x5000, ctrl->val);
++ ret |= reg16_write(client, 0xFFFE, 0x80);
++ usleep_range(100, 150); /* wait 100 us */
++ ret |= reg16_write(client, 0x00C0, 0xfb);
++ break;
++ case V4L2_CID_AUTOGAIN:
++ case V4L2_CID_GAIN:
++ case V4L2_CID_EXPOSURE:
++ if (ctrl->id == V4L2_CID_AUTOGAIN)
++ priv->autogain = ctrl->val;
++ if (ctrl->id == V4L2_CID_GAIN)
++ priv->gain = ctrl->val;
++ if (ctrl->id == V4L2_CID_EXPOSURE)
++ priv->exposure = ctrl->val;
++
++ ret = reg16_write(client, 0xFFFD, 0x80);
++ ret |= reg16_write(client, 0xFFFE, 0x19);
++ usleep_range(100, 150); /* wait 100 us */
++ ret |= reg16_write(client, 0x5000, !priv->autogain);
++ ret |= reg16_write(client, 0x5001, priv->exposure >> 8);
++ ret |= reg16_write(client, 0x5002, priv->exposure & 0xff);
++ ret |= reg16_write(client, 0x5003, priv->exposure >> 8);
++ ret |= reg16_write(client, 0x5004, priv->exposure & 0xff);
++ ret |= reg16_write(client, 0x5005, priv->exposure >> 8);
++ ret |= reg16_write(client, 0x5006, priv->exposure & 0xff);
++ ret |= reg16_write(client, 0x5007, priv->gain >> 8);
++ ret |= reg16_write(client, 0x5008, priv->gain & 0xff);
++ ret |= reg16_write(client, 0x5009, priv->gain >> 8);
++ ret |= reg16_write(client, 0x500a, priv->gain & 0xff);
++ ret |= reg16_write(client, 0x500b, priv->gain >> 8);
++ ret |= reg16_write(client, 0x500c, priv->gain & 0xff);
++ ret |= reg16_write(client, 0xFFFE, 0x80);
++ usleep_range(100, 150); /* wait 100 us */
++ ret |= reg16_write(client, 0x00C0, 0xea);
++ break;
++ case V4L2_CID_AUTO_WHITE_BALANCE:
++ case V4L2_CID_RED_BALANCE:
++ case V4L2_CID_BLUE_BALANCE:
++ if (ctrl->id == V4L2_CID_AUTO_WHITE_BALANCE)
++ priv->awb = ctrl->val;
++ if (ctrl->id == V4L2_CID_RED_BALANCE) {
++ priv->red = ctrl->val;
++ priv->red <<= 8;
++ priv->green_r = priv->red / 2;
++ }
++ if (ctrl->id == V4L2_CID_BLUE_BALANCE) {
++ priv->blue = ctrl->val;
++ priv->blue <<= 8;
++ priv->green_b = priv->blue / 2;
++ }
++
++ ret = reg16_write(client, 0xFFFD, 0x80);
++ ret |= reg16_write(client, 0xFFFE, 0x19);
++ usleep_range(100, 150); /* wait 100 us */
++ ret |= reg16_write(client, 0x5000, !priv->awb);
++ ret |= reg16_write(client, 0x5001, priv->red >> 8);
++ ret |= reg16_write(client, 0x5002, priv->red & 0xff);
++ ret |= reg16_write(client, 0x5003, priv->green_r >> 8);
++ ret |= reg16_write(client, 0x5004, priv->green_r & 0xff);
++ ret |= reg16_write(client, 0x5005, priv->green_b >> 8);
++ ret |= reg16_write(client, 0x5006, priv->green_b & 0xff);
++ ret |= reg16_write(client, 0x5007, priv->blue >> 8);
++ ret |= reg16_write(client, 0x5008, priv->blue & 0xff);
++ ret |= reg16_write(client, 0x5009, priv->red >> 8);
++ ret |= reg16_write(client, 0x500a, priv->red & 0xff);
++ ret |= reg16_write(client, 0x500b, priv->green_r >> 8);
++ ret |= reg16_write(client, 0x500c, priv->green_r & 0xff);
++ ret |= reg16_write(client, 0x500d, priv->green_b >> 8);
++ ret |= reg16_write(client, 0x500e, priv->green_b & 0xff);
++ ret |= reg16_write(client, 0x500f, priv->blue >> 8);
++ ret |= reg16_write(client, 0x5010, priv->blue & 0xff);
++ ret |= reg16_write(client, 0x5011, priv->red >> 8);
++ ret |= reg16_write(client, 0x5012, priv->red & 0xff);
++ ret |= reg16_write(client, 0x5013, priv->green_r >> 8);
++ ret |= reg16_write(client, 0x5014, priv->green_r & 0xff);
++ ret |= reg16_write(client, 0x5015, priv->green_b >> 8);
++ ret |= reg16_write(client, 0x5016, priv->green_b & 0xff);
++ ret |= reg16_write(client, 0x5017, priv->blue >> 8);
++ ret |= reg16_write(client, 0x5018, priv->blue & 0xff);
++ ret |= reg16_write(client, 0xFFFE, 0x80);
++ usleep_range(100, 150); /* wait 100 us */
++ ret |= reg16_write(client, 0x00C0, 0xeb);
++ break;
++ case V4L2_CID_HFLIP:
++#if 1
++ ret = reg16_write(client, 0xFFFD, 0x80);
++ ret |= reg16_write(client, 0xFFFE, 0x19);
++ usleep_range(100, 150); /* wait 100 us */
++ ret |= reg16_write(client, 0x5000, ctrl->val);
++ ret |= reg16_write(client, 0x5001, 0x00);
++ ret |= reg16_write(client, 0xFFFE, 0x80);
++ usleep_range(100, 150); /* wait 100 us */
++ ret |= reg16_write(client, 0x00C0, 0xdc);
++#else
++ ret = reg16_write(client, 0xFFFD, 0x80);
++ ret |= reg16_write(client, 0xFFFE, 0x19);
++ usleep_range(100, 150); /* wait 100 us */
++ ret |= reg16_write(client, 0x5000, 0x01); // read 0x3128
++ ret |= reg16_write(client, 0x5001, 0x31);
++ ret |= reg16_write(client, 0x5002, 0x28);
++ ret |= reg16_write(client, 0xFFFE, 0x80);
++ usleep_range(100, 150); /* wait 100 us */
++ ret |= reg16_write(client, 0x00C0, 0xc1);
++ ret |= reg16_write(client, 0xFFFE, 0x19);
++ usleep_range(100, 150); /* wait 100 us */
++ ret |= reg16_read(client, 0x5000, &val);
++ val &= ~(0x1 << 0);
++ val |= (ctrl->val << 0);
++ ret |= reg16_write(client, 0xFFFE, 0x19);
++ usleep_range(100, 150); /* wait 100 us */
++ ret |= reg16_write(client, 0x5000, 0x00); // write 0x3128
++ ret |= reg16_write(client, 0x5001, 0x31);
++ ret |= reg16_write(client, 0x5002, 0x28);
++ ret |= reg16_write(client, 0x5003, val);
++ ret |= reg16_write(client, 0xFFFE, 0x80);
++ usleep_range(100, 150); /* wait 100 us */
++ ret |= reg16_write(client, 0x00C0, 0xc1);
++
++ ret |= reg16_write(client, 0xFFFE, 0x19);
++ usleep_range(100, 150); /* wait 100 us */
++ ret |= reg16_write(client, 0x5000, 0x01); // read 0x3291
++ ret |= reg16_write(client, 0x5001, 0x32);
++ ret |= reg16_write(client, 0x5002, 0x91);
++ ret |= reg16_write(client, 0xFFFE, 0x80);
++ usleep_range(100, 150); /* wait 100 us */
++ ret |= reg16_write(client, 0x00C0, 0xc1);
++ ret |= reg16_write(client, 0xFFFE, 0x19);
++ usleep_range(100, 150); /* wait 100 us */
++ ret |= reg16_read(client, 0x5000, &val);
++ val &= ~(0x1 << 1);
++ val |= (ctrl->val << 1);
++ ret |= reg16_write(client, 0xFFFE, 0x19);
++ usleep_range(100, 150); /* wait 100 us */
++ ret |= reg16_write(client, 0x5000, 0x00); // write 0x3291
++ ret |= reg16_write(client, 0x5001, 0x32);
++ ret |= reg16_write(client, 0x5002, 0x91);
++ ret |= reg16_write(client, 0x5003, val);
++ ret |= reg16_write(client, 0xFFFE, 0x80);
++ usleep_range(100, 150); /* wait 100 us */
++ ret |= reg16_write(client, 0x00C0, 0xc1);
++
++ ret |= reg16_write(client, 0xFFFE, 0x19);
++ usleep_range(100, 150); /* wait 100 us */
++ ret |= reg16_write(client, 0x5000, 0x01); // read 0x3090
++ ret |= reg16_write(client, 0x5001, 0x30);
++ ret |= reg16_write(client, 0x5002, 0x90);
++ ret |= reg16_write(client, 0xFFFE, 0x80);
++ usleep_range(100, 150); /* wait 100 us */
++ ret |= reg16_write(client, 0x00C0, 0xc1);
++ ret |= reg16_write(client, 0xFFFE, 0x19);
++ usleep_range(100, 150); /* wait 100 us */
++ ret |= reg16_read(client, 0x5000, &val);
++ val &= ~(0x1 << 2);
++ val |= (ctrl->val << 2);
++ ret |= reg16_write(client, 0xFFFE, 0x19);
++ usleep_range(100, 150); /* wait 100 us */
++ ret |= reg16_write(client, 0x5000, 0x00); // write 0x3090
++ ret |= reg16_write(client, 0x5001, 0x30);
++ ret |= reg16_write(client, 0x5002, 0x90);
++ ret |= reg16_write(client, 0x5003, val);
++ ret |= reg16_write(client, 0xFFFE, 0x80);
++ usleep_range(100, 150); /* wait 100 us */
++ ret |= reg16_write(client, 0x00C0, 0xc1);
++#endif
++ break;
++ case V4L2_CID_VFLIP:
++#if 1
++ ret = reg16_write(client, 0xFFFD, 0x80);
++ ret |= reg16_write(client, 0xFFFE, 0x19);
++ usleep_range(100, 150); /* wait 100 us */
++ ret |= reg16_write(client, 0x5000, ctrl->val);
++ ret |= reg16_write(client, 0x5001, 0x01);
++ ret |= reg16_write(client, 0xFFFE, 0x80);
++ usleep_range(100, 150); /* wait 100 us */
++ ret |= reg16_write(client, 0x00C0, 0xdc);
++#else
++ ret = reg16_write(client, 0xFFFD, 0x80);
++ ret |= reg16_write(client, 0xFFFE, 0x19);
++ usleep_range(100, 150); /* wait 100 us */
++ ret |= reg16_write(client, 0x5000, 0x01); // read 0x3128
++ ret |= reg16_write(client, 0x5001, 0x31);
++ ret |= reg16_write(client, 0x5002, 0x28);
++ ret |= reg16_write(client, 0xFFFE, 0x80);
++ usleep_range(100, 150); /* wait 100 us */
++ ret |= reg16_write(client, 0x00C0, 0xc1);
++ ret |= reg16_write(client, 0xFFFE, 0x19);
++ usleep_range(100, 150); /* wait 100 us */
++ ret |= reg16_read(client, 0x5000, &val);
++ val &= ~(0x1 << 1);
++ val |= (ctrl->val << 1);
++ ret |= reg16_write(client, 0xFFFE, 0x19);
++ usleep_range(100, 150); /* wait 100 us */
++ ret |= reg16_write(client, 0x5000, 0x00); // write 0x3128
++ ret |= reg16_write(client, 0x5001, 0x31);
++ ret |= reg16_write(client, 0x5002, 0x28);
++ ret |= reg16_write(client, 0x5003, val);
++ ret |= reg16_write(client, 0xFFFE, 0x80);
++ usleep_range(100, 150); /* wait 100 us */
++ ret |= reg16_write(client, 0x00C0, 0xc1);
++
++ ret |= reg16_write(client, 0xFFFE, 0x19);
++ usleep_range(100, 150); /* wait 100 us */
++ ret |= reg16_write(client, 0x5000, 0x01); // read 0x3291
++ ret |= reg16_write(client, 0x5001, 0x32);
++ ret |= reg16_write(client, 0x5002, 0x91);
++ ret |= reg16_write(client, 0xFFFE, 0x80);
++ usleep_range(100, 150); /* wait 100 us */
++ ret |= reg16_write(client, 0x00C0, 0xc1);
++ ret |= reg16_write(client, 0xFFFE, 0x19);
++ usleep_range(100, 150); /* wait 100 us */
++ ret |= reg16_read(client, 0x5000, &val);
++ val &= ~(0x1 << 2);
++ val |= (ctrl->val << 2);
++ ret |= reg16_write(client, 0xFFFE, 0x19);
++ usleep_range(100, 150); /* wait 100 us */
++ ret |= reg16_write(client, 0x5000, 0x00); // write 0x3291
++ ret |= reg16_write(client, 0x5001, 0x32);
++ ret |= reg16_write(client, 0x5002, 0x91);
++ ret |= reg16_write(client, 0x5003, val);
++ ret |= reg16_write(client, 0xFFFE, 0x80);
++ usleep_range(100, 150); /* wait 100 us */
++ ret |= reg16_write(client, 0x00C0, 0xc1);
++
++ ret |= reg16_write(client, 0xFFFE, 0x19);
++ usleep_range(100, 150); /* wait 100 us */
++ ret |= reg16_write(client, 0x5000, 0x01); // read 0x3090
++ ret |= reg16_write(client, 0x5001, 0x30);
++ ret |= reg16_write(client, 0x5002, 0x90);
++ ret |= reg16_write(client, 0xFFFE, 0x80);
++ usleep_range(100, 150); /* wait 100 us */
++ ret |= reg16_write(client, 0x00C0, 0xc1);
++ ret |= reg16_write(client, 0xFFFE, 0x19);
++ usleep_range(100, 150); /* wait 100 us */
++ ret |= reg16_read(client, 0x5000, &val);
++ val &= ~(0x1 << 3);
++ val |= (ctrl->val << 3);
++ ret |= reg16_write(client, 0xFFFE, 0x19);
++ usleep_range(100, 150); /* wait 100 us */
++ ret |= reg16_write(client, 0x5000, 0x00); // write 0x3090
++ ret |= reg16_write(client, 0x5001, 0x30);
++ ret |= reg16_write(client, 0x5002, 0x90);
++ ret |= reg16_write(client, 0x5003, val);
++ ret |= reg16_write(client, 0xFFFE, 0x80);
++ usleep_range(100, 150); /* wait 100 us */
++ ret |= reg16_write(client, 0x00C0, 0xc1);
++#endif
++ break;
++ case V4L2_CID_MIN_BUFFERS_FOR_CAPTURE:
++ ret = 0;
++ break;
++ }
++
++ return ret;
++}
++
++static const struct v4l2_ctrl_ops ov490_ctrl_ops = {
++ .s_ctrl = ov490_s_ctrl,
++};
++
++static struct v4l2_subdev_video_ops ov490_video_ops = {
++ .s_stream = ov490_s_stream,
++ .g_mbus_config = ov490_g_mbus_config,
++};
++
++static const struct v4l2_subdev_pad_ops ov490_subdev_pad_ops = {
++ .get_edid = ov490_get_edid,
++ .enum_mbus_code = ov490_enum_mbus_code,
++ .get_selection = ov490_get_selection,
++ .set_selection = ov490_set_selection,
++ .get_fmt = ov490_get_fmt,
++ .set_fmt = ov490_set_fmt,
++};
++
++static struct v4l2_subdev_ops ov490_subdev_ops = {
++ .core = &ov490_core_ops,
++ .video = &ov490_video_ops,
++ .pad = &ov490_subdev_pad_ops,
++};
++
++static void ov490_otp_id_read(struct i2c_client *client)
++{
++ struct ov490_priv *priv = to_ov490(client);
++ int i;
++ int otp_bank0_allzero = 1;
++
++#if 0
++ /* read camera id from ov490 OTP memory */
++ reg16_write(client, 0xFFFD, 0x80);
++ reg16_write(client, 0xFFFE, 0x28);
++ usleep_range(100, 150); /* wait 100 us */
++ reg16_write(client, 0xE084, 0x40); /* manual mode, bank#0 */
++ reg16_write(client, 0xE081, 1); /* start OTP read */
++
++ usleep_range(25000, 26000); /* wait 25 ms */
++
++ for (i = 0; i < 6; i++)
++ reg16_read(client, 0xe000 + i + 4, &priv->id[i]);
++#else
++ /* read camera id from ov10640 OTP memory */
++ ov490_ov10640_write(client, 0x349C, 1);
++ usleep_range(25000, 25500); /* wait 25 ms */
++
++ for (i = 0; i < 6; i++) {
++ /* first 6 bytes are equal on all ov10640 */
++ priv->id[i] = ov490_ov10640_read(client, 0x349e + i + 6);
++ if (priv->id[i])
++ otp_bank0_allzero = 0;
++ }
++
++ if (otp_bank0_allzero) {
++ ov490_ov10640_write(client, 0x3495, 0x41); /* bank#1 */
++ ov490_ov10640_write(client, 0x349C, 1);
++ usleep_range(25000, 25500); /* wait 25 ms */
++
++ for (i = 0; i < 6; i++)
++ priv->id[i] = ov490_ov10640_read(client, 0x34ae + i);
++ }
++#endif
++}
++
++static ssize_t ov490_otp_id_show(struct device *dev,
++ struct device_attribute *attr, char *buf)
++{
++ struct v4l2_subdev *sd = i2c_get_clientdata(to_i2c_client(dev));
++ struct i2c_client *client = v4l2_get_subdevdata(sd);
++ struct ov490_priv *priv = to_ov490(client);
++
++ return snprintf(buf, 32, "%02x:%02x:%02x:%02x:%02x:%02x\n",
++ priv->id[0], priv->id[1], priv->id[2], priv->id[3], priv->id[4], priv->id[5]);
++}
++
++static DEVICE_ATTR(otp_id_ov490, S_IRUGO, ov490_otp_id_show, NULL);
++
++static int ov490_initialize(struct i2c_client *client)
++{
++ struct ov490_priv *priv = to_ov490(client);
++ u8 val = 0;
++ u8 pid = 0, ver = 0;
++ int ret = 0, timeout, retry_timeout = 3;
++
++ if (priv->is_fixed_sensor) {
++ dev_info(&client->dev, "ov490/ov10640 fixed-sensor res %dx%d\n", priv->max_width, priv->max_height);
++ return 0;
++ }
++
++ ov490_s_port(client, 1);
++
++ /* check and show product ID and manufacturer ID */
++ reg16_write(client, 0xFFFD, 0x80);
++ reg16_write(client, 0xFFFE, 0x80);
++ usleep_range(100, 150); /* wait 100 us */
++ reg16_read(client, OV490_PID, &pid);
++ reg16_read(client, OV490_VER, &ver);
++
++ if (OV490_VERSION(pid, ver) != OV490_VERSION_REG) {
++ dev_dbg(&client->dev, "Product ID error %x:%x\n", pid, ver);
++ ret = -ENODEV;
++ goto err;
++ }
++
++ if (unlikely(conf_link))
++ goto out;
++
++again:
++ /* Check if firmware booted by reading stream-on status */
++ reg16_write(client, 0xFFFD, 0x80);
++ reg16_write(client, 0xFFFE, 0x29);
++ usleep_range(100, 150); /* wait 100 us */
++ for (timeout = 300; timeout > 0; timeout--) {
++ reg16_read(client, 0xd000, &val);
++ if (val == 0x0c)
++ break;
++ mdelay(1);
++ }
++
++ /* wait firmware apps started by reading OV10640 ID */
++ for (;timeout > 0; timeout--) {
++ reg16_write(client, 0xFFFD, 0x80);
++ reg16_write(client, 0xFFFE, 0x19);
++ usleep_range(100, 150); /* wait 100 us */
++ reg16_write(client, 0x5000, 0x01);
++ reg16_write(client, 0x5001, 0x30);
++ reg16_write(client, 0x5002, 0x0a);
++ reg16_write(client, 0xFFFE, 0x80);
++ usleep_range(100, 150); /* wait 100 us */
++ reg16_write(client, 0xC0, 0xc1);
++ reg16_write(client, 0xFFFE, 0x19);
++ usleep_range(1000, 1500); /* wait 1 ms */
++ reg16_read(client, 0x5000, &val);
++ if (val == 0xa6)
++ break;
++ mdelay(1);
++ }
++
++ if (!timeout) {
++ dev_err(&client->dev, "Timeout firmware boot wait, retrying\n");
++ /* reset OV10640 using RESETB pin controlled by OV490 GPIO0 */
++ reg16_write(client, 0xFFFD, 0x80);
++ reg16_write(client, 0xFFFE, 0x80);
++ usleep_range(100, 150); /* wait 100 us */
++ reg16_write(client, 0x0050, 0x01);
++ reg16_write(client, 0x0054, 0x01);
++ reg16_write(client, 0x0058, 0x00);
++ mdelay(10);
++ reg16_write(client, 0x0058, 0x01);
++ /* reset OV490 using RESETB pin controlled by serializer */
++ ov490_reset(client);
++ if (retry_timeout--)
++ goto again;
++ }
++
++ /* read resolution used by current firmware */
++ reg16_write(client, 0xFFFD, 0x80);
++ reg16_write(client, 0xFFFE, 0x82);
++ usleep_range(100, 150); /* wait 100 us */
++ reg16_read(client, OV490_ISP_HSIZE_HIGH, &val);
++ priv->max_width = val;
++ reg16_read(client, OV490_ISP_HSIZE_LOW, &val);
++ priv->max_width = (priv->max_width << 8) | val;
++ reg16_read(client, OV490_ISP_VSIZE_HIGH, &val);
++ priv->max_height = val;
++ reg16_read(client, OV490_ISP_VSIZE_LOW, &val);
++ priv->max_height = (priv->max_height << 8) | val;
++ /* Program wizard registers */
++ ov490_set_regs(client, ov490_regs_wizard, ARRAY_SIZE(ov490_regs_wizard));
++ /* Set DVP bit swap */
++ reg16_write(client, 0xFFFD, 0x80);
++ reg16_write(client, 0xFFFE, 0x28);
++ usleep_range(100, 150); /* wait 100 us */
++ reg16_write(client, 0x6009, priv->dvp_order << 4);
++ /* Read OTP IDs */
++ ov490_otp_id_read(client);
++
++out:
++ dev_info(&client->dev, "ov490/ov10640 PID %x%x, res %dx%d, OTP_ID %02x:%02x:%02x:%02x:%02x:%02x\n",
++ pid, ver, priv->max_width, priv->max_height, priv->id[0], priv->id[1], priv->id[2], priv->id[3], priv->id[4], priv->id[5]);
++err:
++ ov490_s_port(client, 0);
++
++ return ret;
++}
++
++static int ov490_parse_dt(struct device_node *np, struct ov490_priv *priv)
++{
++ struct i2c_client *client = v4l2_get_subdevdata(&priv->sd);
++ int i;
++ const char *fixed_sensor;
++ struct device_node *endpoint = NULL, *rendpoint = NULL;
++ int tmp_addr = 0;
++
++ for (i = 0; ; i++) {
++ endpoint = of_graph_get_next_endpoint(np, endpoint);
++ if (!endpoint)
++ break;
++
++ of_node_put(endpoint);
++
++ of_property_read_u32(endpoint, "dvp-order", &priv->dvp_order);
++
++ rendpoint = of_parse_phandle(endpoint, "remote-endpoint", 0);
++ if (!rendpoint)
++ continue;
++
++ if (!of_property_read_u32(rendpoint, "max9271-addr", &priv->max9271_addr) &&
++ !of_property_read_u32(rendpoint->parent->parent, "reg", &priv->max9286_addr) &&
++ !kstrtouint(strrchr(rendpoint->full_name, '@') + 1, 0, &priv->port)) {
++ if (of_property_read_u32(rendpoint->parent->parent, "maxim,resetb-gpio", &priv->gpio_resetb)) {
++ priv->gpio_resetb = -1;
++ } else {
++ if (of_property_read_bool(rendpoint->parent->parent, "maxim,resetb-active-high"))
++ priv->active_low_resetb = false;
++ else
++ priv->active_low_resetb = true;
++ }
++ break;
++ }
++
++ if (!of_property_read_u32(rendpoint, "ti9x3-addr", &priv->ti9x3_addr) &&
++ !of_property_match_string(rendpoint->parent->parent, "compatible", "ti,ti9x4") &&
++ !of_property_read_u32(rendpoint->parent->parent, "reg", &priv->ti9x4_addr) &&
++ !kstrtouint(strrchr(rendpoint->full_name, '@') + 1, 0, &priv->port))
++ break;
++ }
++
++ if (!priv->max9286_addr && !priv->ti9x4_addr) {
++ dev_err(&client->dev, "deserializer does not present for OV490\n");
++ return -EINVAL;
++ }
++
++ ov490_s_port(client, 1);
++
++ /* setup I2C translator address */
++ tmp_addr = client->addr;
++ if (priv->max9286_addr) {
++ client->addr = priv->max9271_addr; /* Serializer I2C address */
++
++ reg8_write(client, 0x09, tmp_addr << 1); /* Sensor translated I2C address */
++ reg8_write(client, 0x0A, OV490_I2C_ADDR << 1); /* Sensor native I2C address */
++ usleep_range(2000, 2500); /* wait 2ms */
++ };
++ if (priv->ti9x4_addr) {
++ client->addr = priv->ti9x4_addr; /* Deserializer I2C address */
++
++ reg8_write(client, 0x4c, (priv->port << 4) | (1 << priv->port)); /* Select RX port number */
++ usleep_range(2000, 2500); /* wait 2ms */
++ reg8_write(client, 0x65, tmp_addr << 1); /* Sensor translated I2C address */
++ reg8_write(client, 0x5d, OV490_I2C_ADDR << 1); /* Sensor native I2C address */
++
++ reg8_write(client, 0x6e, 0x9a); /* GPIO0 - fsin, GPIO1 - resetb */
++ }
++ client->addr = tmp_addr;
++
++ if (!of_property_read_string(np, "maxim,fixed-sensor", &fixed_sensor) &&
++ strcmp(fixed_sensor, "ov490") == 0) {
++ if (of_property_read_u32(np, "maxim,width", &priv->max_width))
++ priv->max_width = 1280;
++
++ if (of_property_read_u32(np, "maxim,height", &priv->max_height))
++ priv->max_height = 966;
++
++ priv->is_fixed_sensor = true;
++ }
++
++ /* module params override dts */
++ if (dvp_order)
++ priv->dvp_order = dvp_order;
++ if (max_width && max_height) {
++ priv->max_width = max_width;
++ priv->max_height = max_height;
++ priv->is_fixed_sensor = true;
++ }
++
++ return 0;
++}
++
++static int ov490_probe(struct i2c_client *client,
++ const struct i2c_device_id *did)
++{
++ struct ov490_priv *priv;
++ struct v4l2_ctrl *ctrl;
++ int ret;
++
++ priv = devm_kzalloc(&client->dev, sizeof(*priv), GFP_KERNEL);
++ if (!priv)
++ return -ENOMEM;
++
++ v4l2_i2c_subdev_init(&priv->sd, client, &ov490_subdev_ops);
++ priv->sd.flags = V4L2_SUBDEV_FL_HAS_DEVNODE;
++
++ priv->exposure = 0x100;
++ priv->gain = 0x100;
++ priv->autogain = 1;
++ priv->red = 0x400;
++ priv->blue = 0x400;
++ priv->green_r = priv->red / 2;
++ priv->green_b = priv->blue / 2;
++ priv->awb = 1;
++ v4l2_ctrl_handler_init(&priv->hdl, 4);
++ v4l2_ctrl_new_std(&priv->hdl, &ov490_ctrl_ops,
++ V4L2_CID_BRIGHTNESS, 0, 16, 1, 7);
++ v4l2_ctrl_new_std(&priv->hdl, &ov490_ctrl_ops,
++ V4L2_CID_CONTRAST, 0, 16, 1, 7);
++ v4l2_ctrl_new_std(&priv->hdl, &ov490_ctrl_ops,
++ V4L2_CID_SATURATION, 0, 7, 1, 2);
++ v4l2_ctrl_new_std(&priv->hdl, &ov490_ctrl_ops,
++ V4L2_CID_HUE, 0, 23, 1, 12);
++ v4l2_ctrl_new_std(&priv->hdl, &ov490_ctrl_ops,
++ V4L2_CID_GAMMA, -128, 128, 1, 0);
++ v4l2_ctrl_new_std(&priv->hdl, &ov490_ctrl_ops,
++ V4L2_CID_SHARPNESS, 0, 10, 1, 3);
++ v4l2_ctrl_new_std(&priv->hdl, &ov490_ctrl_ops,
++ V4L2_CID_AUTOGAIN, 0, 1, 1, priv->autogain);
++ v4l2_ctrl_new_std(&priv->hdl, &ov490_ctrl_ops,
++ V4L2_CID_GAIN, 0, 0xffff, 1, priv->gain);
++ v4l2_ctrl_new_std(&priv->hdl, &ov490_ctrl_ops,
++ V4L2_CID_EXPOSURE, 0, 0xffff, 1, priv->exposure);
++ v4l2_ctrl_new_std(&priv->hdl, &ov490_ctrl_ops,
++ V4L2_CID_AUTO_WHITE_BALANCE, 0, 1, 1, priv->autogain);
++ v4l2_ctrl_new_std(&priv->hdl, &ov490_ctrl_ops,
++ V4L2_CID_RED_BALANCE, 2, 0xf, 1, priv->red >> 8);
++ v4l2_ctrl_new_std(&priv->hdl, &ov490_ctrl_ops,
++ V4L2_CID_BLUE_BALANCE, 2, 0xf, 1, priv->blue >> 8);
++ v4l2_ctrl_new_std(&priv->hdl, &ov490_ctrl_ops,
++ V4L2_CID_HFLIP, 0, 1, 1, 1);
++ v4l2_ctrl_new_std(&priv->hdl, &ov490_ctrl_ops,
++ V4L2_CID_VFLIP, 0, 1, 1, 0);
++ ctrl = v4l2_ctrl_new_std(&priv->hdl, &ov490_ctrl_ops,
++ V4L2_CID_MIN_BUFFERS_FOR_CAPTURE, 1, 32, 1, 9);
++ if (ctrl)
++ ctrl->flags &= ~V4L2_CTRL_FLAG_READ_ONLY;
++ priv->sd.ctrl_handler = &priv->hdl;
++
++ ret = priv->hdl.error;
++ if (ret)
++ goto cleanup;
++
++ v4l2_ctrl_handler_setup(&priv->hdl);
++
++ priv->pad.flags = MEDIA_PAD_FL_SOURCE;
++ priv->sd.entity.flags |= MEDIA_ENT_F_CAM_SENSOR;
++ ret = media_entity_pads_init(&priv->sd.entity, 1, &priv->pad);
++ if (ret < 0)
++ goto cleanup;
++
++ ret = ov490_parse_dt(client->dev.of_node, priv);
++ if (ret)
++ goto cleanup;
++
++ ret = ov490_initialize(client);
++ if (ret < 0)
++ goto cleanup;
++
++ priv->rect.left = 0;
++ priv->rect.top = 0;
++ priv->rect.width = priv->max_width;
++ priv->rect.height = priv->max_height;
++
++ ret = v4l2_async_register_subdev(&priv->sd);
++ if (ret)
++ goto cleanup;
++
++ if (device_create_file(&client->dev, &dev_attr_otp_id_ov490) != 0) {
++ dev_err(&client->dev, "sysfs otp_id entry creation failed\n");
++ goto cleanup;
++ }
++
++ priv->init_complete = 1;
++
++ return 0;
++
++cleanup:
++ media_entity_cleanup(&priv->sd.entity);
++ v4l2_ctrl_handler_free(&priv->hdl);
++ v4l2_device_unregister_subdev(&priv->sd);
++#ifdef CONFIG_SOC_CAMERA_OV490_OV10640
++ v4l_err(client, "failed to probe @ 0x%02x (%s)\n",
++ client->addr, client->adapter->name);
++#endif
++ return ret;
++}
++
++static int ov490_remove(struct i2c_client *client)
++{
++ struct ov490_priv *priv = i2c_get_clientdata(client);
++
++ device_remove_file(&client->dev, &dev_attr_otp_id_ov490);
++ v4l2_async_unregister_subdev(&priv->sd);
++ media_entity_cleanup(&priv->sd.entity);
++ v4l2_ctrl_handler_free(&priv->hdl);
++ v4l2_device_unregister_subdev(&priv->sd);
++
++ return 0;
++}
++
++#ifdef CONFIG_SOC_CAMERA_OV490_OV10640
++static const struct i2c_device_id ov490_id[] = {
++ { "ov490-ov10640", 0 },
++ { }
++};
++MODULE_DEVICE_TABLE(i2c, ov490_id);
++
++static const struct of_device_id ov490_of_ids[] = {
++ { .compatible = "ovti,ov490-ov10640", },
++ { }
++};
++MODULE_DEVICE_TABLE(of, ov490_of_ids);
++
++static struct i2c_driver ov490_i2c_driver = {
++ .driver = {
++ .name = "ov490-ov10640",
++ .of_match_table = ov490_of_ids,
++ },
++ .probe = ov490_probe,
++ .remove = ov490_remove,
++ .id_table = ov490_id,
++};
++
++module_i2c_driver(ov490_i2c_driver);
++
++MODULE_DESCRIPTION("SoC Camera driver for OV490-OV10640");
++MODULE_AUTHOR("Vladimir Barinov");
++MODULE_LICENSE("GPL");
++#endif
+diff --git a/drivers/media/i2c/soc_camera/ov490_ov10640.h b/drivers/media/i2c/soc_camera/ov490_ov10640.h
+new file mode 100644
+index 0000000..b22e93e
+--- /dev/null
++++ b/drivers/media/i2c/soc_camera/ov490_ov10640.h
+@@ -0,0 +1,102 @@
++/*
++ * OmniVision ov490-ov10640 sensor camera wizard 1280x1080@30/UYVY/BT601/8bit
++ *
++ * Copyright (C) 2016-2017 Cogent Embedded, Inc.
++ *
++ * This program is free software; you can redistribute it and/or modify it
++ * under the terms of the GNU General Public License as published by the
++ * Free Software Foundation; either version 2 of the License, or (at your
++ * option) any later version.
++ */
++
++//#define OV490_DISPLAY_PATTERN
++
++struct ov490_reg {
++ u16 reg;
++ u8 val;
++};
++
++static const struct ov490_reg ov490_regs_wizard[] = {
++/* The following registers should match firmware */
++{0xfffd, 0x80},
++{0xfffe, 0x82},
++{0x0071, 0x11},
++{0x0075, 0x11},
++{0xfffe, 0x29},
++{0x6010, 0x01},
++/* ov490 EMB line disable in YUV and RAW data, NOTE: EMB line is still used in ISP and sensor */
++{0xe000, 0x14},
++#if 0 /* do not disable EMB line in ISP! */
++{0x4017, 0x00},
++#endif
++{0xfffe, 0x28},
++{0x6000, 0x04},
++{0x6004, 0x00},
++{0x6008, 0x00}, // PCLK polarity - useless due to silicon bug -> use 0x808000bb register
++{0xfffe, 0x80},
++{0x0091, 0x00},
++{0x00bb, 0x1d}, // bit[3]=0 - PCLK polarity workaround
++/* ov10640 EMB line disable */
++#if 0 /* do not disable EMB line in sensor! */
++{0xfffe, 0x19},
++{0x5000, 0x00},
++{0x5001, 0x30},
++{0x5002, 0x91},
++{0x5003, 0x08},
++{0xfffe, 0x80},
++{0x00c0, 0xc1},
++#endif
++/* Ov490 FSIN: app_fsin_from_fsync */
++{0xfffe, 0x85},
++{0x0008, 0x00},
++{0x0009, 0x01},
++{0x000A, 0x05}, // fsin0 src
++{0x000B, 0x00},
++{0x0030, 0x02}, // fsin0_delay
++{0x0031, 0x00},
++{0x0032, 0x00},
++{0x0033, 0x00},
++{0x0038, 0x02}, // fsin1_delay
++{0x0039, 0x00},
++{0x003A, 0x00},
++{0x003B, 0x00},
++{0x0070, 0x2C}, // fsin0_length
++{0x0071, 0x01},
++{0x0072, 0x00},
++{0x0073, 0x00},
++{0x0074, 0x64}, // fsin1_length
++{0x0075, 0x00},
++{0x0076, 0x00},
++{0x0077, 0x00},
++{0x0000, 0x14},
++{0x0001, 0x00},
++{0x0002, 0x00},
++{0x0003, 0x00},
++{0x0004, 0x32}, // load fsin0,load fsin1,load other, it will be cleared automatically.
++{0x0005, 0x00},
++{0x0006, 0x00},
++{0x0007, 0x00},
++{0xfffe, 0x80},
++{0x0081, 0x00}, // 03;SENSOR FSIN
++/* ov10640 FSIN */
++{0xfffe, 0x19},
++{0x5000, 0x00},
++{0x5001, 0x30},
++{0x5002, 0x8c},
++{0x5003, 0xb2},
++{0xfffe, 0x80},
++{0x00c0, 0xc1},
++/* ov10640 HFLIP=1 by default */
++{0xfffe, 0x19},
++{0x5000, 0x01},
++{0x5001, 0x00},
++{0xfffe, 0x80},
++{0x00c0, 0xdc},
++#ifdef OV490_DISPLAY_PATTERN
++{0xfffd, 0x80},
++{0xfffe, 0x19},
++{0x5000, 0x02},
++{0xfffe, 0x80},
++{0x00c0, 0xd6},
++#endif
++};
+diff --git a/drivers/media/i2c/soc_camera/ov495_ov2775.c b/drivers/media/i2c/soc_camera/ov495_ov2775.c
+new file mode 100644
+index 0000000..bb5991c
+--- /dev/null
++++ b/drivers/media/i2c/soc_camera/ov495_ov2775.c
+@@ -0,0 +1,640 @@
++/*
++ * OmniVision ov495-ov2775 sensor camera driver
++ *
++ * Copyright (C) 2017 Cogent Embedded, Inc.
++ *
++ * This program is free software; you can redistribute it and/or modify it
++ * under the terms of the GNU General Public License as published by the
++ * Free Software Foundation; either version 2 of the License, or (at your
++ * option) any later version.
++ */
++
++#include <linux/delay.h>
++#include <linux/init.h>
++#include <linux/i2c.h>
++#include <linux/module.h>
++#include <linux/of_graph.h>
++#include <linux/videodev2.h>
++
++#include <media/soc_camera.h>
++#include <media/v4l2-common.h>
++#include <media/v4l2-ctrls.h>
++#include <media/v4l2-fwnode.h>
++
++#include "ov495_ov2775.h"
++
++#define OV495_I2C_ADDR 0x24
++
++#define OV495_PID 0x300a
++#define OV495_VER 0x300b
++#define OV495_VERSION_REG 0x0495
++#define OV495_VERSION(pid, ver) (((pid) << 8) | ((ver) & 0xff))
++
++#define OV495_ISP_HSIZE_LOW 0x60
++#define OV495_ISP_HSIZE_HIGH 0x61
++#define OV495_ISP_VSIZE_LOW 0x62
++#define OV495_ISP_VSIZE_HIGH 0x63
++
++struct ov495_priv {
++ struct v4l2_subdev sd;
++ struct v4l2_ctrl_handler hdl;
++ struct media_pad pad;
++ struct v4l2_rect rect;
++ int max_width;
++ int max_height;
++ int init_complete;
++ u8 id[6];
++ int exposure;
++ int gain;
++ int autogain;
++ /* serializers */
++ int max9286_addr;
++ int max9271_addr;
++ int ti9x4_addr;
++ int ti9x3_addr;
++ int port;
++ int gpio_resetb;
++ int gpio_fsin;
++
++};
++
++static int force_conf_link;
++
++static __init int ov495_force_conf_link(char *str)
++{
++ /* force configuration link */
++ /* used only if robust firmware flashing required (f.e. recovery) */
++ force_conf_link = 1;
++ return 0;
++}
++early_param("force_conf_link", ov495_force_conf_link);
++
++static inline struct ov495_priv *to_ov495(const struct i2c_client *client)
++{
++ return container_of(i2c_get_clientdata(client), struct ov495_priv, sd);
++}
++
++static int ov495_set_regs(struct i2c_client *client,
++ const struct ov495_reg *regs, int nr_regs)
++{
++ int i;
++
++ for (i = 0; i < nr_regs; i++) {
++ if (reg16_write(client, regs[i].reg, regs[i].val)) {
++ usleep_range(100, 150); /* wait 100 us */
++ reg16_write(client, regs[i].reg, regs[i].val);
++ }
++ }
++
++ return 0;
++}
++
++static int ov495_s_stream(struct v4l2_subdev *sd, int enable)
++{
++ return 0;
++}
++
++static int ov495_get_fmt(struct v4l2_subdev *sd,
++ struct v4l2_subdev_pad_config *cfg,
++ struct v4l2_subdev_format *format)
++{
++ struct v4l2_mbus_framefmt *mf = &format->format;
++ struct i2c_client *client = v4l2_get_subdevdata(sd);
++ struct ov495_priv *priv = to_ov495(client);
++
++ if (format->pad)
++ return -EINVAL;
++
++ mf->width = priv->rect.width;
++ mf->height = priv->rect.height;
++ mf->code = MEDIA_BUS_FMT_YUYV8_2X8;
++ mf->colorspace = V4L2_COLORSPACE_SMPTE170M;
++ mf->field = V4L2_FIELD_NONE;
++
++ return 0;
++}
++
++static int ov495_set_fmt(struct v4l2_subdev *sd,
++ struct v4l2_subdev_pad_config *cfg,
++ struct v4l2_subdev_format *format)
++{
++ struct v4l2_mbus_framefmt *mf = &format->format;
++
++ mf->code = MEDIA_BUS_FMT_YUYV8_2X8;
++ mf->colorspace = V4L2_COLORSPACE_SMPTE170M;
++ mf->field = V4L2_FIELD_NONE;
++
++ if (format->which == V4L2_SUBDEV_FORMAT_TRY)
++ cfg->try_fmt = *mf;
++
++ return 0;
++}
++
++static int ov495_enum_mbus_code(struct v4l2_subdev *sd,
++ struct v4l2_subdev_pad_config *cfg,
++ struct v4l2_subdev_mbus_code_enum *code)
++{
++ if (code->pad || code->index > 0)
++ return -EINVAL;
++
++ code->code = MEDIA_BUS_FMT_YUYV8_2X8;
++
++ return 0;
++}
++
++static int ov495_get_edid(struct v4l2_subdev *sd, struct v4l2_edid *edid)
++{
++ struct i2c_client *client = v4l2_get_subdevdata(sd);
++ struct ov495_priv *priv = to_ov495(client);
++
++ memcpy(edid->edid, priv->id, 6);
++
++ edid->edid[6] = 0xff;
++ edid->edid[7] = client->addr;
++ edid->edid[8] = OV495_VERSION_REG >> 8;
++ edid->edid[9] = OV495_VERSION_REG & 0xff;
++
++ return 0;
++}
++
++static int ov495_set_selection(struct v4l2_subdev *sd,
++ struct v4l2_subdev_pad_config *cfg,
++ struct v4l2_subdev_selection *sel)
++{
++ struct v4l2_rect *rect = &sel->r;
++ struct i2c_client *client = v4l2_get_subdevdata(sd);
++ struct ov495_priv *priv = to_ov495(client);
++
++ if (sel->which != V4L2_SUBDEV_FORMAT_ACTIVE ||
++ sel->target != V4L2_SEL_TGT_CROP)
++ return -EINVAL;
++
++ rect->left = ALIGN(rect->left, 2);
++ rect->top = ALIGN(rect->top, 2);
++ rect->width = ALIGN(rect->width, 2);
++ rect->height = ALIGN(rect->height, 2);
++
++ if ((rect->left + rect->width > priv->max_width) ||
++ (rect->top + rect->height > priv->max_height))
++ *rect = priv->rect;
++
++ priv->rect.left = rect->left;
++ priv->rect.top = rect->top;
++ priv->rect.width = rect->width;
++ priv->rect.height = rect->height;
++
++ return 0;
++}
++
++static int ov495_get_selection(struct v4l2_subdev *sd,
++ struct v4l2_subdev_pad_config *cfg,
++ struct v4l2_subdev_selection *sel)
++{
++ struct i2c_client *client = v4l2_get_subdevdata(sd);
++ struct ov495_priv *priv = to_ov495(client);
++
++ if (sel->which != V4L2_SUBDEV_FORMAT_ACTIVE)
++ return -EINVAL;
++
++ switch (sel->target) {
++ case V4L2_SEL_TGT_CROP_BOUNDS:
++ sel->r.left = 0;
++ sel->r.top = 0;
++ sel->r.width = priv->max_width;
++ sel->r.height = priv->max_height;
++ return 0;
++ case V4L2_SEL_TGT_CROP_DEFAULT:
++ sel->r.left = 0;
++ sel->r.top = 0;
++ sel->r.width = priv->max_width;
++ sel->r.height = priv->max_height;
++ return 0;
++ case V4L2_SEL_TGT_CROP:
++ sel->r = priv->rect;
++ return 0;
++ default:
++ return -EINVAL;
++ }
++}
++
++static int ov495_g_mbus_config(struct v4l2_subdev *sd,
++ struct v4l2_mbus_config *cfg)
++{
++ cfg->flags = V4L2_MBUS_CSI2_1_LANE | V4L2_MBUS_CSI2_CHANNEL_0 |
++ V4L2_MBUS_CSI2_CONTINUOUS_CLOCK;
++ cfg->type = V4L2_MBUS_CSI2;
++
++ return 0;
++}
++
++#ifdef CONFIG_VIDEO_ADV_DEBUG
++static int ov495_g_register(struct v4l2_subdev *sd,
++ struct v4l2_dbg_register *reg)
++{
++ struct i2c_client *client = v4l2_get_subdevdata(sd);
++ int ret;
++ u8 val = 0;
++
++ ret = reg16_read(client, (u16)reg->reg, &val);
++ if (ret < 0)
++ return ret;
++
++ reg->val = val;
++ reg->size = sizeof(u16);
++
++ return 0;
++}
++
++static int ov495_s_register(struct v4l2_subdev *sd,
++ const struct v4l2_dbg_register *reg)
++{
++ struct i2c_client *client = v4l2_get_subdevdata(sd);
++ int ret;
++
++ ret = reg16_write(client, (u16)reg->reg, (u8)reg->val);
++ if ((u8)reg->reg == 0xFFFD)
++ usleep_range(100, 150); /* wait 100 us */
++ if ((u8)reg->reg == 0xFFFE)
++ usleep_range(100, 150); /* wait 100 us */
++ return ret;
++}
++#endif
++
++static struct v4l2_subdev_core_ops ov495_core_ops = {
++#ifdef CONFIG_VIDEO_ADV_DEBUG
++ .g_register = ov495_g_register,
++ .s_register = ov495_s_register,
++#endif
++};
++
++static int ov495_s_ctrl(struct v4l2_ctrl *ctrl)
++{
++ struct v4l2_subdev *sd = to_sd(ctrl);
++ struct i2c_client *client = v4l2_get_subdevdata(sd);
++ struct ov495_priv *priv = to_ov495(client);
++ int ret = -EINVAL;
++
++ if (!priv->init_complete)
++ return 0;
++
++ switch (ctrl->id) {
++ case V4L2_CID_BRIGHTNESS:
++ break;
++ case V4L2_CID_CONTRAST:
++ break;
++ case V4L2_CID_SATURATION:
++ break;
++ case V4L2_CID_HUE:
++ break;
++ case V4L2_CID_GAMMA:
++ break;
++ case V4L2_CID_SHARPNESS:
++ break;
++ case V4L2_CID_AUTOGAIN:
++ case V4L2_CID_GAIN:
++ case V4L2_CID_EXPOSURE:
++ break;
++ case V4L2_CID_HFLIP:
++ ret = reg16_write(client, 0x3516, 0x00);
++ ret |= reg16_write(client, 0x0ffc, 0x00);
++ ret |= reg16_write(client, 0x0500, ctrl->val);
++ ret |= reg16_write(client, 0x0501, 0x00);
++ usleep_range(100, 150); /* wait 100 us */
++ ret |= reg16_write(client, 0x30C0, 0xdc);
++ ret |= reg16_write(client, 0x3516, 0x01);
++ break;
++ case V4L2_CID_VFLIP:
++ ret = reg16_write(client, 0x3516, 0x00);
++ ret |= reg16_write(client, 0x0ffc, 0x00);
++ ret |= reg16_write(client, 0x0500, ctrl->val);
++ ret |= reg16_write(client, 0x0501, 0x01);
++ usleep_range(100, 150); /* wait 100 us */
++ ret |= reg16_write(client, 0x30C0, 0xdc);
++ ret |= reg16_write(client, 0x3516, 0x01);
++ break;
++ case V4L2_CID_MIN_BUFFERS_FOR_CAPTURE:
++ ret = 0;
++ break;
++ }
++
++ return ret;
++}
++
++static const struct v4l2_ctrl_ops ov495_ctrl_ops = {
++ .s_ctrl = ov495_s_ctrl,
++};
++
++static struct v4l2_subdev_video_ops ov495_video_ops = {
++ .s_stream = ov495_s_stream,
++ .g_mbus_config = ov495_g_mbus_config,
++};
++
++static const struct v4l2_subdev_pad_ops ov495_subdev_pad_ops = {
++ .get_edid = ov495_get_edid,
++ .enum_mbus_code = ov495_enum_mbus_code,
++ .get_selection = ov495_get_selection,
++ .set_selection = ov495_set_selection,
++ .get_fmt = ov495_get_fmt,
++ .set_fmt = ov495_set_fmt,
++};
++
++static struct v4l2_subdev_ops ov495_subdev_ops = {
++ .core = &ov495_core_ops,
++ .video = &ov495_video_ops,
++ .pad = &ov495_subdev_pad_ops,
++};
++
++static void ov495_otp_id_read(struct i2c_client *client)
++{
++ struct ov495_priv *priv = to_ov495(client);
++ int i;
++
++#if 0
++ /* read camera id from ov495 OTP memory */
++ reg16_write(client, 0xFFFD, 0x80);
++ reg16_write(client, 0xFFFE, 0x20);
++ usleep_range(100, 150); /* wait 100 us */
++ reg16_write(client, 0x7384, 0x40); /* manual mode, bank#0 */
++ reg16_write(client, 0x7381, 1); /* start OTP read */
++
++ usleep_range(25000, 26000); /* wait 25 ms */
++
++ for (i = 0; i < 6; i++)
++ reg16_read(client, 0x7300 + i + 4, &priv->id[i]);
++#else
++ /* read camera id from ov2775 OTP memory */
++ reg16_write(client, 0x3516, 0x00); /* unlock write */
++ reg16_write(client, 0x0FFC, 0);
++ reg16_write(client, 0x0500, 0x00); /* write 0x34a1 -> 1 */
++ reg16_write(client, 0x0501, 0x34);
++ reg16_write(client, 0x0502, 0xa1);
++ reg16_write(client, 0x0503, 1);
++ reg16_write(client, 0x30C0, 0xc1);
++
++ usleep_range(25000, 25500); /* wait 25 ms */
++
++ for (i = 0; i < 6; i++) {
++ reg16_write(client, 0x3516, 0x00); /* unlock write */
++ reg16_write(client, 0x0500, 0x01); /* read (0x7a00 + i) */
++ reg16_write(client, 0x0501, 0x7a);
++ reg16_write(client, 0x0502, 0x00 + i + (i < 3 ? 11 : 3)); /* take bytes 11,12,13,6,7,8 */
++ reg16_write(client, 0x30C0, 0xc1);
++ usleep_range(1000, 1500); /* wait 1 ms */
++ reg16_read(client, 0x0500, &priv->id[i]);
++ }
++#endif
++}
++
++static ssize_t ov495_otp_id_show(struct device *dev,
++ struct device_attribute *attr, char *buf)
++{
++ struct v4l2_subdev *sd = i2c_get_clientdata(to_i2c_client(dev));
++ struct i2c_client *client = v4l2_get_subdevdata(sd);
++ struct ov495_priv *priv = to_ov495(client);
++
++ return snprintf(buf, 32, "%02x:%02x:%02x:%02x:%02x:%02x\n",
++ priv->id[0], priv->id[1], priv->id[2], priv->id[3], priv->id[4], priv->id[5]);
++}
++
++static DEVICE_ATTR(otp_id_ov495, S_IRUGO, ov495_otp_id_show, NULL);
++
++static int ov495_initialize(struct i2c_client *client)
++{
++ struct ov495_priv *priv = to_ov495(client);
++ u8 pid = 0, ver = 0;
++ int ret = 0;
++
++ /* check and show product ID and manufacturer ID */
++ reg16_write(client, 0xFFFD, 0x80);
++ reg16_write(client, 0xFFFE, 0x80);
++ usleep_range(100, 150); /* wait 100 us */
++ reg16_read(client, OV495_PID, &pid);
++ reg16_read(client, OV495_VER, &ver);
++
++ if (OV495_VERSION(pid, ver) != OV495_VERSION_REG) {
++ dev_err(&client->dev, "Product ID error %x:%x\n", pid, ver);
++ ret = -ENODEV;
++ goto err;
++ }
++
++ if (unlikely(force_conf_link))
++ goto out;
++
++#if 0
++ /* read resolution used by current firmware */
++ reg16_write(client, 0xFFFD, 0x80);
++ reg16_write(client, 0xFFFE, 0x82);
++ usleep_range(100, 150); /* wait 100 us */
++ reg16_read(client, OV495_ISP_HSIZE_HIGH, &val);
++ priv->max_width = val;
++ reg16_read(client, OV495_ISP_HSIZE_LOW, &val);
++ priv->max_width = (priv->max_width << 8) | val;
++ reg16_read(client, OV495_ISP_VSIZE_HIGH, &val);
++ priv->max_height = val;
++ reg16_read(client, OV495_ISP_VSIZE_LOW, &val);
++ priv->max_height = (priv->max_height << 8) | val;
++#else
++ priv->max_width = 1920;
++ priv->max_height = 1080;
++#endif
++
++ /* set virtual channel */
++ ov495_regs_wizard[3].val = 0x1e | (priv->port << 6);
++ /* Program wizard registers */
++ ov495_set_regs(client, ov495_regs_wizard, ARRAY_SIZE(ov495_regs_wizard));
++ /* Read OTP IDs */
++ ov495_otp_id_read(client);
++
++out:
++ dev_info(&client->dev, "ov495/ov2775 PID %x%x, res %dx%d, OTP_ID %02x:%02x:%02x:%02x:%02x:%02x\n",
++ pid, ver, priv->max_width, priv->max_height, priv->id[0], priv->id[1], priv->id[2], priv->id[3], priv->id[4], priv->id[5]);
++err:
++ return ret;
++}
++
++static int ov495_parse_dt(struct device_node *np, struct ov495_priv *priv)
++{
++ struct i2c_client *client = v4l2_get_subdevdata(&priv->sd);
++ int i;
++ struct device_node *endpoint = NULL, *rendpoint = NULL;
++ int tmp_addr = 0;
++
++ for (i = 0; ; i++) {
++ endpoint = of_graph_get_next_endpoint(np, endpoint);
++ if (!endpoint)
++ break;
++
++ of_node_put(endpoint);
++
++ rendpoint = of_parse_phandle(endpoint, "remote-endpoint", 0);
++ if (!rendpoint)
++ continue;
++
++ if (!of_property_read_u32(rendpoint, "ti9x3-addr", &priv->ti9x3_addr) &&
++ !of_property_match_string(rendpoint->parent->parent, "compatible", "ti,ti9x4") &&
++ !of_property_read_u32(rendpoint->parent->parent, "reg", &priv->ti9x4_addr) &&
++ !kstrtouint(strrchr(rendpoint->full_name, '@') + 1, 0, &priv->port))
++ break;
++ }
++
++ if (!priv->ti9x4_addr) {
++ dev_err(&client->dev, "deserializer does not present for OV495\n");
++ return -EINVAL;
++ }
++
++ /* setup I2C translator address */
++ tmp_addr = client->addr;
++ if (priv->ti9x4_addr) {
++ client->addr = priv->ti9x4_addr; /* Deserializer I2C address */
++
++ reg8_write(client, 0x4c, (priv->port << 4) | (1 << priv->port)); /* Select RX port number */
++ usleep_range(2000, 2500); /* wait 2ms */
++ reg8_write(client, 0x65, tmp_addr << 1); /* Sensor translated I2C address */
++ reg8_write(client, 0x5d, OV495_I2C_ADDR << 1); /* Sensor native I2C address */
++
++ reg8_write(client, 0x6e, 0x9a); /* GPIO0 - fsin, GPIO1 - resetb */
++ /* TODO: why too long? move logic to workqueue? */
++ mdelay(350); /* time needed to boot all sensor IPs */
++ }
++ client->addr = tmp_addr;
++
++ return 0;
++}
++
++static int ov495_probe(struct i2c_client *client,
++ const struct i2c_device_id *did)
++{
++ struct ov495_priv *priv;
++ struct v4l2_ctrl *ctrl;
++ int ret;
++
++ priv = devm_kzalloc(&client->dev, sizeof(*priv), GFP_KERNEL);
++ if (!priv)
++ return -ENOMEM;
++
++ v4l2_i2c_subdev_init(&priv->sd, client, &ov495_subdev_ops);
++ priv->sd.flags = V4L2_SUBDEV_FL_HAS_DEVNODE;
++
++ priv->exposure = 0x100;
++ priv->gain = 0x100;
++ priv->autogain = 1;
++ v4l2_ctrl_handler_init(&priv->hdl, 4);
++ v4l2_ctrl_new_std(&priv->hdl, &ov495_ctrl_ops,
++ V4L2_CID_BRIGHTNESS, 0, 16, 1, 7);
++ v4l2_ctrl_new_std(&priv->hdl, &ov495_ctrl_ops,
++ V4L2_CID_CONTRAST, 0, 16, 1, 7);
++ v4l2_ctrl_new_std(&priv->hdl, &ov495_ctrl_ops,
++ V4L2_CID_SATURATION, 0, 7, 1, 2);
++ v4l2_ctrl_new_std(&priv->hdl, &ov495_ctrl_ops,
++ V4L2_CID_HUE, 0, 23, 1, 12);
++ v4l2_ctrl_new_std(&priv->hdl, &ov495_ctrl_ops,
++ V4L2_CID_GAMMA, -128, 128, 1, 0);
++ v4l2_ctrl_new_std(&priv->hdl, &ov495_ctrl_ops,
++ V4L2_CID_SHARPNESS, 0, 10, 1, 3);
++ v4l2_ctrl_new_std(&priv->hdl, &ov495_ctrl_ops,
++ V4L2_CID_AUTOGAIN, 0, 1, 1, priv->autogain);
++ v4l2_ctrl_new_std(&priv->hdl, &ov495_ctrl_ops,
++ V4L2_CID_GAIN, 0, 0xffff, 1, priv->gain);
++ v4l2_ctrl_new_std(&priv->hdl, &ov495_ctrl_ops,
++ V4L2_CID_EXPOSURE, 0, 0xffff, 1, priv->exposure);
++ v4l2_ctrl_new_std(&priv->hdl, &ov495_ctrl_ops,
++ V4L2_CID_HFLIP, 0, 1, 1, 0);
++ v4l2_ctrl_new_std(&priv->hdl, &ov495_ctrl_ops,
++ V4L2_CID_VFLIP, 0, 1, 1, 0);
++ ctrl = v4l2_ctrl_new_std(&priv->hdl, &ov495_ctrl_ops,
++ V4L2_CID_MIN_BUFFERS_FOR_CAPTURE, 1, 32, 1, 9);
++ if (ctrl)
++ ctrl->flags &= ~V4L2_CTRL_FLAG_READ_ONLY;
++ priv->sd.ctrl_handler = &priv->hdl;
++
++ ret = priv->hdl.error;
++ if (ret)
++ goto cleanup;
++
++ v4l2_ctrl_handler_setup(&priv->hdl);
++
++ priv->pad.flags = MEDIA_PAD_FL_SOURCE;
++ priv->sd.entity.flags |= MEDIA_ENT_F_CAM_SENSOR;
++ ret = media_entity_pads_init(&priv->sd.entity, 1, &priv->pad);
++ if (ret < 0)
++ goto cleanup;
++
++ ret = ov495_parse_dt(client->dev.of_node, priv);
++ if (ret)
++ goto cleanup;
++
++ ret = ov495_initialize(client);
++ if (ret < 0)
++ goto cleanup;
++
++ priv->rect.left = 0;
++ priv->rect.top = 0;
++ priv->rect.width = priv->max_width;
++ priv->rect.height = priv->max_height;
++
++ ret = v4l2_async_register_subdev(&priv->sd);
++ if (ret)
++ goto cleanup;
++
++ if (device_create_file(&client->dev, &dev_attr_otp_id_ov495) != 0) {
++ dev_err(&client->dev, "sysfs otp_id entry creation failed\n");
++ goto cleanup;
++ }
++
++ priv->init_complete = 1;
++
++ return 0;
++
++cleanup:
++ media_entity_cleanup(&priv->sd.entity);
++ v4l2_ctrl_handler_free(&priv->hdl);
++ v4l2_device_unregister_subdev(&priv->sd);
++#ifdef CONFIG_SOC_CAMERA_OV495_OV2775
++ v4l_err(client, "failed to probe @ 0x%02x (%s)\n",
++ client->addr, client->adapter->name);
++#endif
++ return ret;
++}
++
++static int ov495_remove(struct i2c_client *client)
++{
++ struct ov495_priv *priv = i2c_get_clientdata(client);
++
++ device_remove_file(&client->dev, &dev_attr_otp_id_ov495);
++ v4l2_async_unregister_subdev(&priv->sd);
++ media_entity_cleanup(&priv->sd.entity);
++ v4l2_ctrl_handler_free(&priv->hdl);
++ v4l2_device_unregister_subdev(&priv->sd);
++
++ return 0;
++}
++
++#ifdef CONFIG_SOC_CAMERA_OV495_OV2775
++static const struct i2c_device_id ov495_id[] = {
++ { "ov495-ov2775", 0 },
++ { }
++};
++MODULE_DEVICE_TABLE(i2c, ov495_id);
++
++static const struct of_device_id ov495_of_ids[] = {
++ { .compatible = "ovti,ov495-ov2775", },
++ { }
++};
++MODULE_DEVICE_TABLE(of, ov495_of_ids);
++
++static struct i2c_driver ov495_i2c_driver = {
++ .driver = {
++ .name = "ov495-ov2775",
++ .of_match_table = ov495_of_ids,
++ },
++ .probe = ov495_probe,
++ .remove = ov495_remove,
++ .id_table = ov495_id,
++};
++
++module_i2c_driver(ov495_i2c_driver);
++
++MODULE_DESCRIPTION("SoC Camera driver for OV495-OV2775");
++MODULE_AUTHOR("Vladimir Barinov");
++MODULE_LICENSE("GPL");
++#endif
+diff --git a/drivers/media/i2c/soc_camera/ov495_ov2775.h b/drivers/media/i2c/soc_camera/ov495_ov2775.h
+new file mode 100644
+index 0000000..17c94ae
+--- /dev/null
++++ b/drivers/media/i2c/soc_camera/ov495_ov2775.h
+@@ -0,0 +1,23 @@
++/*
++ * OmniVision ov495-ov2775 sensor camera wizard 1920x1080@30/UYVY/MIPI
++ *
++ * Copyright (C) 2017 Cogent Embedded, Inc.
++ *
++ * This program is free software; you can redistribute it and/or modify it
++ * under the terms of the GNU General Public License as published by the
++ * Free Software Foundation; either version 2 of the License, or (at your
++ * option) any later version.
++ */
++
++struct ov495_reg {
++ u16 reg;
++ u8 val;
++};
++
++static struct ov495_reg ov495_regs_wizard[] = {
++{0x3516, 0x00}, /* unlock write */
++{0xFFFD, 0x80},
++{0xFFFE, 0x20},
++{0x8017, 0x1e | (0 << 6)},
++{0x7c10, 0x01}, /* UYVY */
++};
+diff --git a/drivers/media/i2c/soc_camera/ti9x4.c b/drivers/media/i2c/soc_camera/ti9x4.c
+new file mode 100644
+index 0000000..2ce98b4
+--- /dev/null
++++ b/drivers/media/i2c/soc_camera/ti9x4.c
+@@ -0,0 +1,520 @@
++ /*
++ * TI DS90UB954/960/964 FPDLinkIII driver
++ *
++ * Copyright (C) 2017-2018 Cogent Embedded, Inc.
++ *
++ * This program is free software; you can redistribute it and/or modify it
++ * under the terms of the GNU General Public License as published by the
++ * Free Software Foundation; either version 2 of the License, or (at your
++ * option) any later version.
++ */
++
++#include <linux/delay.h>
++#include <linux/i2c.h>
++#include <linux/module.h>
++#include <linux/notifier.h>
++#include <linux/of_gpio.h>
++#include <linux/of_graph.h>
++#include <linux/videodev2.h>
++
++#include <media/v4l2-async.h>
++#include <media/v4l2-common.h>
++#include <media/v4l2-device.h>
++#include <media/v4l2-fwnode.h>
++#include <media/v4l2-subdev.h>
++
++#include "ti9x4.h"
++
++struct ti9x4_priv {
++ struct v4l2_subdev sd[4];
++ struct fwnode_handle *sd_fwnode[4];
++ int des_addr;
++ int links;
++ int lanes;
++ int csi_rate;
++ const char *forwarding_mode;
++ int is_coax;
++ int dvp_bus;
++ int hsync;
++ int vsync;
++ int poc_delay;
++ atomic_t use_count;
++ struct i2c_client *client;
++ int ti9x3_addr_map[4];
++ char chip_id[6];
++ int ser_id;
++ struct gpio_desc *poc_gpio[4]; /* PoC power supply */
++};
++
++static int ser_id;
++module_param(ser_id, int, 0644);
++MODULE_PARM_DESC(ser_id, " Serializer ID (default: TI913)");
++
++static int is_stp;
++module_param(is_stp, int, 0644);
++MODULE_PARM_DESC(is_stp, " STP cable (default: Coax cable)");
++
++static int dvp_bus = 8;
++module_param(dvp_bus, int, 0644);
++MODULE_PARM_DESC(dvp_bus, " DVP/CSI over FPDLink (default: DVP 8-bit)");
++
++static int hsync;
++module_param(hsync, int, 0644);
++MODULE_PARM_DESC(hsync, " HSYNC invertion (default: 0 - not inverted)");
++
++static int vsync = 1;
++module_param(vsync, int, 0644);
++MODULE_PARM_DESC(vsync, " VSYNC invertion (default: 1 - inverted)");
++
++static int poc_delay;
++module_param(poc_delay, int, 0644);
++MODULE_PARM_DESC(poc_delay, " Delay in ms after POC enable (default: 0 ms)");
++
++#ifdef TI954_SILICON_ERRATA
++static int indirect_write(struct i2c_client *client, unsigned int page, u8 reg, u8 val)
++{
++ if (page > 7)
++ return -EINVAL;
++
++ reg8_write(client, 0xb0, page << 2);
++ reg8_write(client, 0xb1, reg);
++ reg8_write(client, 0xb2, val);
++
++ return 0;
++}
++
++static int indirect_read(struct i2c_client *client, unsigned int page, u8 reg, u8 *val)
++{
++ if (page > 7)
++ return -EINVAL;
++
++ reg8_write(client, 0xb0, page << 2);
++ reg8_write(client, 0xb1, reg);
++ reg8_read(client, 0xb2, val);
++
++ return 0;
++}
++#endif
++
++static void ti9x4_read_chipid(struct i2c_client *client)
++{
++ struct ti9x4_priv *priv = i2c_get_clientdata(client);
++
++ /* Chip ID */
++ reg8_read(client, 0xf1, &priv->chip_id[0]);
++ reg8_read(client, 0xf2, &priv->chip_id[1]);
++ reg8_read(client, 0xf3, &priv->chip_id[2]);
++ reg8_read(client, 0xf4, &priv->chip_id[3]);
++ reg8_read(client, 0xf5, &priv->chip_id[4]);
++ priv->chip_id[5] = '\0';
++}
++
++static void ti9x4_initial_setup(struct i2c_client *client)
++{
++ struct ti9x4_priv *priv = i2c_get_clientdata(client);
++
++ /* Initial setup */
++ client->addr = priv->des_addr; /* TI9x4 I2C */
++ reg8_write(client, 0x08, 0x1c); /* I2C glitch filter depth */
++ reg8_write(client, 0x0a, 0x79); /* I2C high pulse width */
++ reg8_write(client, 0x0b, 0x79); /* I2C low pulse width */
++ reg8_write(client, 0x0d, 0xb9); /* VDDIO 3.3V */
++ switch (priv->csi_rate) {
++ case 1600: /* REFCLK = 25MHZ */
++ case 1450: /* REFCLK = 22.5MHZ */
++ reg8_write(client, 0x1f, 0x00); /* CSI rate 1.5/1.6Gbps */
++ break;
++ case 800: /* REFCLK = 25MHZ */
++ case 700: /* REFCLK = 22.5MHZ */
++ reg8_write(client, 0x1f, 0x02); /* CSI rate 700/800Mbps */
++ break;
++ case 400: /* REFCLK = 25MHZ */
++ reg8_write(client, 0x1f, 0x03); /* CSI rate 400Mbps */
++ break;
++ default:
++ dev_err(&client->dev, "unsupported CSI rate %d\n", priv->csi_rate);
++ }
++
++ if (strcmp(priv->forwarding_mode, "round-robin") == 0) {
++ reg8_write(client, 0x21, 0x01); /* Round Robin forwarding enable */
++ } else if (strcmp(priv->forwarding_mode, "synchronized") == 0) {
++ reg8_write(client, 0x21, 0x44); /* Basic Syncronized forwarding enable (FrameSync must be enabled!!) */
++ }
++
++ reg8_write(client, 0x32, 0x01); /* Select TX (CSI) port 0 */
++ reg8_write(client, 0x33, ((priv->lanes - 1) ^ 0x3) << 4); /* disable CSI output, set CSI lane count, non-continuous CSI mode */
++ reg8_write(client, 0x20, 0xf0); /* disable port forwarding */
++#if 0
++ /* FrameSync setup for REFCLK=25MHz, FPS=30: period_counts=1/2/FPS*25MHz =1/2/30*25Mhz =416666 -> FS_TIME=416666 */
++ /* FrameSync setup for REFCLK=22.5MHz, FPS=30: period_counts=1/2/FPS*22.5Mhz=1/2/30*22.5Mhz=375000 -> FS_TIME=375000 */
++// #define FS_TIME (priv->csi_rate == 1450 ? 376000 : 417666)
++ #define FS_TIME (priv->csi_rate == 1450 ? 385000 : 428000) // FPS=29.2 (new vendor's firmware AWB restriction?)
++ reg8_write(client, 0x1a, FS_TIME >> 16); /* FrameSync time 24bit */
++ reg8_write(client, 0x1b, (FS_TIME >> 8) & 0xff);
++ reg8_write(client, 0x1c, FS_TIME & 0xff);
++ reg8_write(client, 0x18, 0x43); /* Enable FrameSync, 50/50 mode, Frame clock from 25MHz */
++#else
++ /* FrameSync setup for REFCLK=25MHz, FPS=30: period_counts=1/FPS/12mks=1/30/12e-6=2777 -> HI=2, LO=2775 */
++ /* FrameSync setup for REFCLK=22.5MHz, FPS=30: period_counts=1/FPS/13.333mks=1/30/13.333e-6=2500 -> HI=2, LO=2498 */
++ #define FS_TIME (priv->csi_rate == 1450 ? (2498+15) : (2775+15))
++ reg8_write(client, 0x19, 2 >> 8); /* FrameSync high time MSB */
++ reg8_write(client, 0x1a, 2 & 0xff); /* FrameSync high time LSB */
++ reg8_write(client, 0x1b, FS_TIME >> 8); /* FrameSync low time MSB */
++ reg8_write(client, 0x1c, FS_TIME & 0xff); /* FrameSync low time LSB */
++ reg8_write(client, 0x18, 0x01); /* Enable FrameSync, HI/LO mode, Frame clock from port0 */
++#endif
++}
++
++//#define SENSOR_ID 0x30 // ov10635
++//#define SENSOR_ID 0x24 // ov490
++
++static void ti9x4_fpdlink3_setup(struct i2c_client *client, int idx)
++{
++ struct ti9x4_priv *priv = i2c_get_clientdata(client);
++ u8 port_config = 0x78;
++ u8 port_config2 = 0;
++
++ /* FPDLinkIII setup */
++ client->addr = priv->des_addr; /* TI9x4 I2C */
++ reg8_write(client, 0x4c, (idx << 4) | (1 << idx)); /* Select RX port number */
++ usleep_range(2000, 2500); /* wait 2ms */
++
++ switch (priv->ser_id) {
++ case TI913_ID:
++ reg8_write(client, 0x58, 0x58); /* Back channel: Freq=2.5Mbps */
++ break;
++ case TI953_ID:
++ reg8_write(client, 0x58, 0x5e); /* Back channel: Freq=50Mbps */
++ break;
++ default:
++ break;
++ }
++
++ reg8_write(client, 0x5c, priv->ti9x3_addr_map[idx] << 1); /* TI9X3 I2C addr */
++// reg8_write(client, 0x5d, SENSOR_ID << 1); /* SENSOR I2C native - must be set by sensor driver */
++// reg8_write(client, 0x65, (0x60 + idx) << 1); /* SENSOR I2C translated - must be set by sensor driver */
++
++ if (priv->is_coax)
++ port_config |= 0x04; /* Coax */
++ else
++ port_config |= 0x00; /* STP */
++
++ switch (priv->dvp_bus) {
++ case 8:
++ port_config2 |= 0x80; /* RAW10 as 8-bit prosessing using upper bits */
++ /* fall through */
++ case 10:
++ port_config |= 0x03; /* DVP over FPDLink (TI913 compatible) RAW10/RAW8 */
++ break;
++ case 12:
++ port_config |= 0x02; /* DVP over FPDLink (TI913 compatible) RAW12 */
++ break;
++ default:
++ port_config |= 0x00; /* CSI over FPDLink (TI953 compatible) */
++ }
++
++ if (priv->vsync)
++ port_config2 |= 0x01; /* VSYNC acive low */
++ if (priv->hsync)
++ port_config2 |= 0x02; /* HSYNC acive low */
++
++ reg8_write(client, 0x6d, port_config);
++ reg8_write(client, 0x7c, port_config2);
++ reg8_write(client, 0x70, (idx << 6) | 0x1e); /* CSI data type: yuv422 8-bit, assign VC */
++ reg8_write(client, 0x71, (idx << 6) | 0x2a); /* CSI data type: RAW8, assign VC */
++ reg8_write(client, 0xbc, 0x00); /* Setup minimal time between FV and LV to 3 PCLKs */
++ reg8_write(client, 0x6e, 0x88); /* Sensor reset: backchannel GPIO0/GPIO1 set low */
++}
++
++static int ti9x4_initialize(struct i2c_client *client)
++{
++ struct ti9x4_priv *priv = i2c_get_clientdata(client);
++ int idx;
++
++ dev_info(&client->dev, "LINKs=%d, LANES=%d, FORWARDING=%s, CABLE=%s, ID=%s\n",
++ priv->links, priv->lanes, priv->forwarding_mode, priv->is_coax ? "coax" : "stp", priv->chip_id);
++
++ ti9x4_initial_setup(client);
++
++ for (idx = 0; idx < priv->links; idx++) {
++ if (!IS_ERR(priv->poc_gpio[idx])) {
++ gpiod_direction_output(priv->poc_gpio[idx], 1); /* POC power on */
++ mdelay(priv->poc_delay);
++ }
++
++ ti9x4_fpdlink3_setup(client, idx);
++ }
++
++ client->addr = priv->des_addr;
++
++ return 0;
++}
++
++#ifdef CONFIG_VIDEO_ADV_DEBUG
++static int ti9x4_g_register(struct v4l2_subdev *sd,
++ struct v4l2_dbg_register *reg)
++{
++ struct ti9x4_priv *priv = v4l2_get_subdevdata(sd);
++ struct i2c_client *client = priv->client;
++ int ret;
++ u8 val = 0;
++
++ ret = reg8_read(client, (u8)reg->reg, &val);
++ if (ret < 0)
++ return ret;
++
++ reg->val = val;
++ reg->size = sizeof(u8);
++
++ return 0;
++}
++
++static int ti9x4_s_register(struct v4l2_subdev *sd,
++ const struct v4l2_dbg_register *reg)
++{
++ struct ti9x4_priv *priv = v4l2_get_subdevdata(sd);
++ struct i2c_client *client = priv->client;
++
++ return reg8_write(client, (u8)reg->reg, (u8)reg->val);
++}
++#endif
++
++static int ti9x4_s_power(struct v4l2_subdev *sd, int on)
++{
++ struct ti9x4_priv *priv = v4l2_get_subdevdata(sd);
++ struct i2c_client *client = priv->client;
++
++ if (on) {
++ if (atomic_inc_return(&priv->use_count) == 1)
++ reg8_write(client, 0x20, 0x00); /* enable port forwarding to CSI */
++ } else {
++ if (atomic_dec_return(&priv->use_count) == 0)
++ reg8_write(client, 0x20, 0xf0); /* disable port forwarding to CSI */
++ }
++
++ return 0;
++}
++
++static int ti9x4_registered_async(struct v4l2_subdev *sd)
++{
++ struct ti9x4_priv *priv = v4l2_get_subdevdata(sd);
++ struct i2c_client *client = priv->client;
++
++ reg8_write(client, 0x33, ((priv->lanes - 1) ^ 0x3) << 4 | 0x1); /* enable CSI output, set CSI lane count, non-continuous CSI mode */
++
++ return 0;
++}
++
++static struct v4l2_subdev_core_ops ti9x4_subdev_core_ops = {
++#ifdef CONFIG_VIDEO_ADV_DEBUG
++ .g_register = ti9x4_g_register,
++ .s_register = ti9x4_s_register,
++#endif
++ .s_power = ti9x4_s_power,
++ .registered_async = ti9x4_registered_async,
++};
++
++static struct v4l2_subdev_ops ti9x4_subdev_ops = {
++ .core = &ti9x4_subdev_core_ops,
++};
++
++static int ti9x4_parse_dt(struct i2c_client *client)
++{
++ struct ti9x4_priv *priv = i2c_get_clientdata(client);
++ struct device_node *np = client->dev.of_node;
++ struct device_node *endpoint = NULL, *rendpoint = NULL;
++ struct property *prop;
++ int err, pwen, i;
++ int sensor_delay;
++ char forwarding_mode_default[20] = "round-robin"; /* round-robin, synchronized */
++ struct property *csi_rate_prop, *dvp_order_prop;
++ u8 val = 0;
++ char poc_name[10];
++
++ if (of_property_read_u32(np, "ti,links", &priv->links))
++ priv->links = 4;
++
++ if (of_property_read_u32(np, "ti,lanes", &priv->lanes))
++ priv->lanes = 4;
++
++ pwen = of_get_gpio(np, 0);
++ if (pwen > 0) {
++ err = devm_gpio_request_one(&client->dev, pwen, GPIOF_OUT_INIT_LOW, dev_name(&client->dev));
++ if (err)
++ dev_err(&client->dev, "cannot request PWEN gpio %d: %d\n", pwen, err);
++ else
++ mdelay(250);
++ }
++
++ for (i = 0; i < 4; i++) {
++ sprintf(poc_name, "POC%d", i);
++ priv->poc_gpio[i] = devm_gpiod_get_optional(&client->dev, poc_name, 0);
++ }
++
++ reg8_read(client, 0x00, &val); /* read TI9x4 I2C address */
++ if (val != (priv->des_addr << 1)) {
++ prop = of_find_property(np, "reg", NULL);
++ if (prop)
++ of_remove_property(np, prop);
++ return -ENODEV;
++ }
++
++ ti9x4_read_chipid(client);
++
++#ifdef TI954_SILICON_ERRATA
++ indirect_write(client, 7, 0x15, 0x30);
++ if (pwen > 0)
++ gpio_set_value(pwen, 1);
++ usleep_range(5000, 5500); /* wait 5ms */
++ indirect_write(client, 7, 0x15, 0);
++#endif
++ if (!of_property_read_u32(np, "ti,sensor_delay", &sensor_delay))
++ mdelay(sensor_delay);
++ if (of_property_read_string(np, "ti,forwarding-mode", &priv->forwarding_mode))
++ priv->forwarding_mode = forwarding_mode_default;
++ if (of_property_read_bool(np, "ti,stp"))
++ priv->is_coax = 0;
++ else
++ priv->is_coax = 1;
++ if (of_property_read_u32(np, "ti,dvp_bus", &priv->dvp_bus))
++ priv->dvp_bus = 8;
++ if (of_property_read_u32(np, "ti,hsync", &priv->hsync))
++ priv->vsync = 0;
++ if (of_property_read_u32(np, "ti,vsync", &priv->vsync))
++ priv->vsync = 1;
++ if (of_property_read_u32(np, "ti,ser_id", &priv->ser_id))
++ priv->ser_id = TI913_ID;
++ if (of_property_read_u32(np, "ti,poc-delay", &priv->poc_delay))
++ priv->poc_delay = 50;
++
++ /* module params override dts */
++ if (is_stp)
++ priv->is_coax = 0;
++ if (dvp_bus != 8)
++ priv->dvp_bus = dvp_bus;
++ if (hsync)
++ priv->hsync = hsync;
++ if (!vsync)
++ priv->vsync = vsync;
++ if (ser_id)
++ priv->ser_id = ser_id;
++ if (poc_delay)
++ priv->poc_delay = poc_delay;
++
++ for (i = 0; ; i++) {
++ endpoint = of_graph_get_next_endpoint(np, endpoint);
++ if (!endpoint)
++ break;
++
++ of_node_put(endpoint);
++
++ if (i < priv->links) {
++ if (of_property_read_u32(endpoint, "ti9x3-addr", &priv->ti9x3_addr_map[i])) {
++ dev_err(&client->dev, "ti9x3-addr not set\n");
++ return -EINVAL;
++ }
++ priv->sd_fwnode[i] = of_fwnode_handle(endpoint);
++ }
++
++ rendpoint = of_parse_phandle(endpoint, "remote-endpoint", 0);
++ if (!rendpoint)
++ continue;
++
++ csi_rate_prop = of_find_property(endpoint, "csi-rate", NULL);
++ if (csi_rate_prop) {
++ of_property_read_u32(endpoint, "csi-rate", &priv->csi_rate);
++ of_update_property(rendpoint, csi_rate_prop);
++ }
++
++ dvp_order_prop = of_find_property(endpoint, "dvp-order", NULL);
++ if (dvp_order_prop)
++ of_update_property(rendpoint, dvp_order_prop);
++ }
++
++ return 0;
++}
++
++static int ti9x4_probe(struct i2c_client *client,
++ const struct i2c_device_id *did)
++{
++ struct ti9x4_priv *priv;
++ int err, i;
++
++ priv = devm_kzalloc(&client->dev, sizeof(*priv), GFP_KERNEL);
++ if (!priv)
++ return -ENOMEM;
++
++ i2c_set_clientdata(client, priv);
++ priv->des_addr = client->addr;
++ priv->client = client;
++ atomic_set(&priv->use_count, 0);
++
++ err = ti9x4_parse_dt(client);
++ if (err)
++ goto out;
++
++ err = ti9x4_initialize(client);
++ if (err < 0)
++ goto out;
++
++ for (i = 0; i < priv->links; i++) {
++ v4l2_subdev_init(&priv->sd[i], &ti9x4_subdev_ops);
++ priv->sd[i].owner = client->dev.driver->owner;
++ priv->sd[i].dev = &client->dev;
++ priv->sd[i].grp_id = i;
++ v4l2_set_subdevdata(&priv->sd[i], priv);
++ priv->sd[i].fwnode = priv->sd_fwnode[i];
++
++ snprintf(priv->sd[i].name, V4L2_SUBDEV_NAME_SIZE, "%s %d-%04x",
++ client->dev.driver->name, i2c_adapter_id(client->adapter),
++ client->addr);
++
++ err = v4l2_async_register_subdev(&priv->sd[i]);
++ if (err < 0)
++ goto out;
++ }
++
++out:
++ return err;
++}
++
++static int ti9x4_remove(struct i2c_client *client)
++{
++ struct ti9x4_priv *priv = i2c_get_clientdata(client);
++ int i;
++
++ for (i = 0; i < priv->links; i++) {
++ v4l2_async_unregister_subdev(&priv->sd[i]);
++ v4l2_device_unregister_subdev(&priv->sd[i]);
++ }
++
++ return 0;
++}
++
++static const struct of_device_id ti9x4_dt_ids[] = {
++ { .compatible = "ti,ti9x4" },
++ {},
++};
++MODULE_DEVICE_TABLE(of, ti9x4_dt_ids);
++
++static const struct i2c_device_id ti9x4_id[] = {
++ { "ti9x4", 0 },
++ { }
++};
++MODULE_DEVICE_TABLE(i2c, ti9x4_id);
++
++static struct i2c_driver ti9x4_i2c_driver = {
++ .driver = {
++ .name = "ti9x4",
++ .of_match_table = of_match_ptr(ti9x4_dt_ids),
++ },
++ .probe = ti9x4_probe,
++ .remove = ti9x4_remove,
++ .id_table = ti9x4_id,
++};
++
++module_i2c_driver(ti9x4_i2c_driver);
++
++MODULE_DESCRIPTION("FPDLinkIII driver for DS90UB9x4");
++MODULE_AUTHOR("Vladimir Barinov");
++MODULE_LICENSE("GPL");
+diff --git a/drivers/media/i2c/soc_camera/ti9x4.h b/drivers/media/i2c/soc_camera/ti9x4.h
+new file mode 100644
+index 0000000..b53b4c6
+--- /dev/null
++++ b/drivers/media/i2c/soc_camera/ti9x4.h
+@@ -0,0 +1,156 @@
++/*
++ * TI FPDLinkIII driver include file
++ *
++ * Copyright (C) 2017 Cogent Embedded, Inc.
++ *
++ * This program is free software; you can redistribute it and/or modify it
++ * under the terms of the GNU General Public License as published by the
++ * Free Software Foundation; either version 2 of the License, or (at your
++ * option) any later version.
++ */
++
++#ifndef _TI9X4_H
++#define _TI9X4_H
++
++//#define DEBUG
++#ifdef DEBUG
++#undef dev_dbg
++#define dev_dbg dev_info
++#endif
++
++#define MAXIM_NUM_RETRIES 1 /* number of read/write retries */
++#define TI913_ID 0x58
++#define TI953_ID 0x30 /* or starapped to 0x32 */
++#define TI9X4_ID 0x00 /* strapped */
++#define BROADCAST 0x6f
++
++static inline int reg8_read(struct i2c_client *client, u8 reg, u8 *val)
++{
++ int ret, retries;
++
++ for (retries = MAXIM_NUM_RETRIES; retries; retries--) {
++ ret = i2c_smbus_read_byte_data(client, reg);
++ if (!(ret < 0))
++ break;
++ }
++
++ if (ret < 0) {
++ dev_dbg(&client->dev,
++ "read fail: chip 0x%x register 0x%x: %d\n",
++ client->addr, reg, ret);
++ } else {
++ *val = ret;
++ }
++
++ return ret < 0 ? ret : 0;
++}
++
++static inline int reg8_write(struct i2c_client *client, u8 reg, u8 val)
++{
++ int ret, retries;
++
++ for (retries = MAXIM_NUM_RETRIES; retries; retries--) {
++ ret = i2c_smbus_write_byte_data(client, reg, val);
++ if (!(ret < 0))
++ break;
++ }
++
++ if (ret < 0) {
++ dev_dbg(&client->dev,
++ "write fail: chip 0x%x register 0x%x: %d\n",
++ client->addr, reg, ret);
++ }
++
++ return ret < 0 ? ret : 0;
++}
++
++static inline int reg16_read(struct i2c_client *client, u16 reg, u8 *val)
++{
++ int ret, retries;
++ u8 buf[2] = {reg >> 8, reg & 0xff};
++
++ for (retries = MAXIM_NUM_RETRIES; retries; retries--) {
++ ret = i2c_master_send(client, buf, 2);
++ if (ret == 2) {
++ ret = i2c_master_recv(client, buf, 1);
++ if (ret == 1)
++ break;
++ }
++ }
++
++ if (ret < 0) {
++ dev_dbg(&client->dev,
++ "read fail: chip 0x%x register 0x%x: %d\n",
++ client->addr, reg, ret);
++ } else {
++ *val = buf[0];
++ }
++
++ return ret < 0 ? ret : 0;
++}
++
++static inline int reg16_write(struct i2c_client *client, u16 reg, u8 val)
++{
++ int ret, retries;
++ u8 buf[3] = {reg >> 8, reg & 0xff, val};
++
++ for (retries = MAXIM_NUM_RETRIES; retries; retries--) {
++ ret = i2c_master_send(client, buf, 3);
++ if (ret == 3)
++ break;
++ }
++
++ if (ret < 0) {
++ dev_dbg(&client->dev,
++ "write fail: chip 0x%x register 0x%x: %d\n",
++ client->addr, reg, ret);
++ }
++
++ return ret < 0 ? ret : 0;
++}
++
++static inline int reg16_read16(struct i2c_client *client, u16 reg, u16 *val)
++{
++ int ret, retries;
++ u8 buf[2] = {reg >> 8, reg & 0xff};
++
++ for (retries = MAXIM_NUM_RETRIES; retries; retries--) {
++ ret = i2c_master_send(client, buf, 2);
++ if (ret == 2) {
++ ret = i2c_master_recv(client, buf, 2);
++ if (ret == 2)
++ break;
++ }
++ }
++
++ if (ret < 0) {
++ dev_err(&client->dev,
++ "read fail: chip 0x%x register 0x%x: %d\n",
++ client->addr, reg, ret);
++ } else {
++ *val = ((u16)buf[0] << 8) | buf[1];
++ }
++
++ return ret < 0 ? ret : 0;
++}
++
++static inline int reg16_write16(struct i2c_client *client, u16 reg, u16 val)
++{
++ int ret, retries;
++ u8 buf[4] = {reg >> 8, reg & 0xff, val >> 8, val & 0xff};
++
++ for (retries = MAXIM_NUM_RETRIES; retries; retries--) {
++ ret = i2c_master_send(client, buf, 4);
++ if (ret == 4)
++ break;
++ }
++
++ if (ret < 0) {
++ dev_err(&client->dev,
++ "write fail: chip 0x%x register 0x%x: %d\n",
++ client->addr, reg, ret);
++ }
++
++ return ret < 0 ? ret : 0;
++}
++#endif /* _TI9X4_H */
+diff --git a/drivers/media/platform/soc_camera/rcar_csi2.c b/drivers/media/platform/soc_camera/rcar_csi2.c
+index 05f623468..2e710e3 100644
+--- a/drivers/media/platform/soc_camera/rcar_csi2.c
++++ b/drivers/media/platform/soc_camera/rcar_csi2.c
+@@ -20,24 +20,29 @@
+ #include <linux/err.h>
+ #include <linux/i2c.h>
+ #include <linux/io.h>
++#include <linux/of_graph.h>
+ #include <linux/platform_device.h>
+ #include <linux/pm_runtime.h>
+ #include <linux/slab.h>
+ #include <linux/videodev2.h>
+ #include <linux/module.h>
++#include <linux/sys_soc.h>
+
+ #include <media/rcar_csi2.h>
+ #include <media/soc_camera.h>
++#include <media/v4l2-async.h>
++#include <media/v4l2-fwnode.h>
+ #include <media/v4l2-common.h>
+ #include <media/v4l2-dev.h>
+ #include <media/v4l2-device.h>
+ #include <media/v4l2-mediabus.h>
+ #include <media/v4l2-subdev.h>
+
+-#include <media/v4l2-of.h>
++#include <media/v4l2-fwnode.h>
++
++//#define RCAR_CSI2_DUMP
+
+ #define DRV_NAME "rcar_csi2"
+-#define CONNECT_SLAVE_NAME "adv7482"
+ #define VC_MAX_CHANNEL 4
+
+ #define RCAR_CSI2_TREF 0x00
+@@ -62,6 +67,7 @@
+
+ #define RCAR_CSI2_LINKCNT 0x48
+ #define RCAR_CSI2_LSWAP 0x4C
++#define RCAR_CSI2_PHTW 0x50
+ #define RCAR_CSI2_PHTC 0x58
+ #define RCAR_CSI2_PHYPLL 0x68
+
+@@ -69,6 +75,10 @@
+ #define RCAR_CSI2_PHCLM 0x78
+ #define RCAR_CSI2_PHDLM 0x7C
+
++#define RCAR_CSI2_CSI0CLKFCPR 0x254 /* CSI0CLK Frequency Configuration Preset */
++/* CSI0CLK frequency configuration bit */
++#define CSI0CLKFREQRANGE(n) ((n & 0x3f) << 16)
++
+ #define RCAR_CSI2_PHYCNT_SHUTDOWNZ (1 << 17)
+ #define RCAR_CSI2_PHYCNT_RSTZ (1 << 16)
+ #define RCAR_CSI2_PHYCNT_ENABLECLK (1 << 4)
+@@ -105,6 +115,9 @@
+ #define RCAR_CSI2_LSWAP_L0SEL_PLANE2 (2 << 0)
+ #define RCAR_CSI2_LSWAP_L0SEL_PLANE3 (3 << 0)
+
++#define RCAR_CSI2_PHTW_DWEN (1 << 24)
++#define RCAR_CSI2_PHTW_CWEN (1 << 8)
++
+ #define RCAR_CSI2_PHTC_TESTCLR (1 << 0)
+
+ /* interrupt status registers */
+@@ -153,6 +166,16 @@
+ #define RCAR_CSI2_INTSTATE_ERRSYNCESC (1 << 1)
+ #define RCAR_CSI2_INTSTATE_ERRCONTROL (1 << 0)
+
++static const struct soc_device_attribute r8a7797[] = {
++ { .soc_id = "r8a7797" },
++ { }
++};
++
++static const struct soc_device_attribute r8a7795[] = {
++ { .soc_id = "r8a7795", .revision = "ES2.0" },
++ { }
++};
++
+ enum chip_id {
+ RCAR_GEN3,
+ RCAR_GEN2,
+@@ -173,6 +196,7 @@ struct rcar_csi2_link_config {
+ unsigned char lanes;
+ unsigned long vcdt;
+ unsigned long vcdt2;
++ unsigned int csi_rate;
+ };
+
+ #define INIT_RCAR_CSI2_LINK_CONFIG(m) \
+@@ -186,8 +210,7 @@ struct rcar_csi_irq_counter_log {
+ };
+
+ struct rcar_csi2 {
+- struct v4l2_subdev subdev;
+- struct v4l2_mbus_framefmt *mf;
++ struct v4l2_subdev subdev[4];
+ unsigned int irq;
+ unsigned long mipi_flags;
+ void __iomem *base;
+@@ -199,7 +222,9 @@ struct rcar_csi2 {
+ unsigned int field;
+ unsigned int code;
+ unsigned int lanes;
++ unsigned int csi_rate;
+ spinlock_t lock;
++ atomic_t use_count;
+ };
+
+ #define RCAR_CSI_80MBPS 0
+@@ -245,10 +270,104 @@ struct rcar_csi2 {
+ #define RCAR_CSI_1400MBPS 40
+ #define RCAR_CSI_1450MBPS 41
+ #define RCAR_CSI_1500MBPS 42
++#define RCAR_CSI_NUMRATES 43
++
++#define RCAR_CSI2_PHxM0(i) (0xf0 + i * 0x08)
++#define RCAR_CSI2_PHxM1(i) (0xf4 + i * 0x08)
++#define RCAR_CSI2_PHRM(i) (0x110 + i * 0x04)
++#define RCAR_CSI2_PHCM(i) (0x120 + i * 0x04)
++#define RCAR_CSI2_SERCCNT 0x140
++#define RCAR_CSI2_SSERCCNT 0x144
++#define RCAR_CSI2_ECCCM 0x148
++#define RCAR_CSI2_ECECM 0x14c
++#define RCAR_CSI2_CRCECM 0x150
++#define RCAR_CSI2_LCNT(i) (0x160 + i * 0x04)
++#define RCAR_CSI2_LCNTM(i) (0x168 + i * 0x04)
++#define RCAR_CSI2_FCNTM 0x170
++#define RCAR_CSI2_FCNTM2 0x174
++#define RCAR_CSI2_VINSM(i) (0x190 + i * 0x04)
++#define RCAR_CSI2_PHM(i) (0x1C0 + i * 0x04)
++
++#define RCAR_CSI2_INTSTATE_ALL 0x3FFFFCDD
++
++#ifdef RCAR_CSI2_DUMP
++static void rcar_sci2_debug_show(struct rcar_csi2 *priv)
++{
++ int i;
++ u32 reg0, reg1;
++
++ printk("Debug registers:\n");
++ printk("FCNTM : 0x%08x\n", ioread32(priv->base + RCAR_CSI2_FCNTM));
++ printk("FCNTM2: 0x%08x\n", ioread32(priv->base + RCAR_CSI2_FCNTM2));
++
++ for (i = 0; i < 4; i++) {
++ reg0 = ioread32(priv->base + RCAR_CSI2_PHxM0(i));
++ reg1 = ioread32(priv->base + RCAR_CSI2_PHxM1(i));
++
++ printk("Packet header %d: dt: 0x%02x, vc: %d, wc: %d, cnt: %d\n",
++ i,
++ reg0 & 0x3F, (reg0 >> 6) & 0x03, (reg0 >> 8) & 0xffff,
++ reg1 & 0xffff);
++ }
++ for (i = 0; i < 3; i++) {
++ reg0 = ioread32(priv->base + RCAR_CSI2_PHRM(i));
++
++ printk("Packet header R %d dt: 0x%02x, vc: %d, wc: %d, ecc: 0x%02x\n",
++ i,
++ reg0 & 0x3F, (reg0 >> 6) & 0x03, (reg0 >> 8) & 0xffff,
++ (reg0 >> 24) & 0xff);
++ }
++ for (i = 0; i < 2; i++) {
++ reg0 = ioread32(priv->base + RCAR_CSI2_PHCM(i));
++
++ printk("Packet header C %d: dt: 0x%02x, vc: %d, wc: %d, cal_parity: 0x%02x\n",
++ i,
++ reg0 & 0x3F, (reg0 >> 6) & 0x03, (reg0 >> 8) & 0xffff,
++ (reg0 >> 24) & 0xff);
++ }
++ for (i = 0; i < 8; i++) {
++ reg0 = ioread32(priv->base + RCAR_CSI2_PHM(i));
++
++ printk("Packet header Monitor %d: dt: 0x%02x, vc: %d, wc: %d, ecc: 0x%02x\n",
++ i + 1,
++ reg0 & 0x3F, (reg0 >> 6) & 0x03, (reg0 >> 8) & 0xffff,
++ (reg0 >> 24) & 0xff);
++ }
++ for (i = 0; i < 3; i++)
++ printk("VINSM%d: 0x%08x\n", i, ioread32(priv->base + RCAR_CSI2_VINSM(i)));
++ printk("SERCCNT: %d\n",
++ ioread32(priv->base + RCAR_CSI2_SERCCNT));
++ printk("SSERCCNT: %d\n",
++ ioread32(priv->base + RCAR_CSI2_SSERCCNT));
++ printk("ECCCM: %d\n",
++ ioread32(priv->base + RCAR_CSI2_ECCCM));
++ printk("ECECM: %d\n",
++ ioread32(priv->base + RCAR_CSI2_ECECM));
++ printk("CRCECM: %d\n",
++ ioread32(priv->base + RCAR_CSI2_CRCECM));
++ for (i = 0; i < 2; i++)
++ printk("LCNT%d: 0x%08x\n", i, ioread32(priv->base + RCAR_CSI2_LCNT(i)));
++ for (i = 0; i < 2; i++)
++ printk("LCNTM%d: 0x%08x\n", i, ioread32(priv->base + RCAR_CSI2_LCNTM(i)));
++}
++#else
++#define rcar_sci2_debug_show(args)
++#endif /* RCAR_CSI2_DUMP */
+
+ static int rcar_csi2_set_phy_freq(struct rcar_csi2 *priv)
+ {
+- const uint32_t const hs_freq_range[43] = {
++ const uint32_t hs_freq_range_v3m[43] = {
++ 0x00, 0x00, 0x20, 0x40, 0x02, /* 80M, 90M, 100M, 110M, 120M */
++ 0x02, 0x22, 0x42, 0x04, 0x04, /* 130M, 140M, 150M, 160M, 170M */
++ 0x24, 0x44, 0x44, 0x06, 0x26, /* 180M, 190M, 205M, 220M, 235M */
++ 0x46, 0x08, 0x28, 0x0a, 0x2a, /* 250M, 270M, 300M, 325M, 350M */
++ 0x4a, 0x4a, 0x4a, 0x4a, 0x4a, /* 400M, 450M, 500M, 550M, 600M */
++ 0x10, 0x30, 0x12, 0x32, 0x52, /* 650M, 700M, 750M, 800M, 950M */
++ 0x72, 0x14, 0x34, 0x52, 0x74, /* 900M, 950M, 1000M, 1050M, 1100M */
++ 0x16, 0x36, 0x56, 0x76, 0x18, /* 1150M, 1200M, 1250M, 1300M, 1350M */
++ 0x38, 0x58, 0x78 /* 1400M, 1450M, 1500M */
++ };
++ const uint32_t hs_freq_range_m3[43] = {
+ 0x00, 0x10, 0x20, 0x30, 0x01, /* 0-4 */
+ 0x11, 0x21, 0x31, 0x02, 0x12, /* 5-9 */
+ 0x22, 0x32, 0x03, 0x13, 0x23, /* 10-14 */
+@@ -259,60 +378,49 @@ static int rcar_csi2_set_phy_freq(struct rcar_csi2 *priv)
+ 0x0B, 0x1B, 0x2B, 0x3B, 0x0C, /* 35-39 */
+ 0x1C, 0x2C, 0x3C /* 40-42 */
+ };
++ const uint32_t hs_freq_range_h3[43] = {
++ 0x00, 0x10, 0x20, 0x30, 0x01, /* 0-4 */
++ 0x11, 0x21, 0x31, 0x02, 0x12, /* 5-9 */
++ 0x22, 0x32, 0x03, 0x13, 0x23, /* 10-14 */
++ 0x33, 0x04, 0x14, 0x25, 0x35, /* 15-19 */
++ 0x05, 0x26, 0x36, 0x37, 0x07, /* 20-24 */
++ 0x18, 0x28, 0x39, 0x09, 0x19, /* 25-29 */
++ 0x29, 0x3A, 0x0A, 0x1A, 0x2A, /* 30-34 */
++ 0x3B, 0x0B, 0x1B, 0x2B, 0x3C, /* 35-39 */
++ 0x0C, 0x1C, 0x2C /* 40-42 */
++ };
++ const uint32_t csi2_rate_range[43] = {
++ 80, 90, 100, 110, 120, /* 0-4 */
++ 130, 140, 150, 160, 170, /* 5-9 */
++ 180, 190, 205, 220, 235, /* 10-14 */
++ 250, 275, 300, 325, 350, /* 15-19 */
++ 400, 450, 500, 550, 600, /* 20-24 */
++ 650, 700, 750, 800, 850, /* 25-29 */
++ 900, 950, 1000, 1050, 1100, /* 30-34 */
++ 1150, 1200, 1250, 1300, 1350, /* 35-39 */
++ 1400, 1450, 1500 /* 40-42 */
++ };
+ uint32_t bps_per_lane = RCAR_CSI_190MBPS;
+
+- dev_dbg(&priv->pdev->dev, "Input size (%dx%d%c)\n",
+- priv->mf->width, priv->mf->height,
+- (priv->mf->field == V4L2_FIELD_NONE) ? 'p' : 'i');
+-
+- switch (priv->lanes) {
+- case 1:
+- bps_per_lane = RCAR_CSI_400MBPS;
+- break;
+- case 4:
+- if (priv->mf->field == V4L2_FIELD_NONE) {
+- if ((priv->mf->width == 1920) &&
+- (priv->mf->height == 1080))
+- bps_per_lane = RCAR_CSI_900MBPS;
+- else if ((priv->mf->width == 1280) &&
+- (priv->mf->height == 720))
+- bps_per_lane = RCAR_CSI_450MBPS;
+- else if ((priv->mf->width == 720) &&
+- (priv->mf->height == 480))
+- bps_per_lane = RCAR_CSI_190MBPS;
+- else if ((priv->mf->width == 720) &&
+- (priv->mf->height == 576))
+- bps_per_lane = RCAR_CSI_190MBPS;
+- else if ((priv->mf->width == 640) &&
+- (priv->mf->height == 480))
+- bps_per_lane = RCAR_CSI_100MBPS;
+- else
+- goto error;
+- } else {
+- if ((priv->mf->width == 1920) &&
+- (priv->mf->height == 1080))
+- bps_per_lane = RCAR_CSI_450MBPS;
+- else
+- goto error;
+- }
+- break;
+- default:
+- dev_err(&priv->pdev->dev, "ERROR: lanes is invalid (%d)\n",
+- priv->lanes);
+- return -EINVAL;
++ for (bps_per_lane = 0; bps_per_lane < RCAR_CSI_NUMRATES; bps_per_lane++) {
++ if (priv->csi_rate <= csi2_rate_range[bps_per_lane])
++ break;
+ }
+
+ dev_dbg(&priv->pdev->dev, "bps_per_lane (%d)\n", bps_per_lane);
+
+- iowrite32((hs_freq_range[bps_per_lane] << 16),
++ if (soc_device_match(r8a7797))
++ iowrite32((hs_freq_range_v3m[bps_per_lane] << 16) |
++ RCAR_CSI2_PHTW_DWEN | RCAR_CSI2_PHTW_CWEN | 0x44,
++ priv->base + RCAR_CSI2_PHTW);
++ else if (soc_device_match(r8a7795))
++ iowrite32(hs_freq_range_h3[bps_per_lane] << 16,
++ priv->base + RCAR_CSI2_PHYPLL);
++ else
++ /* h3 ws1.x is similar to m3 */
++ iowrite32(hs_freq_range_m3[bps_per_lane] << 16,
+ priv->base + RCAR_CSI2_PHYPLL);
+ return 0;
+-
+-error:
+- dev_err(&priv->pdev->dev, "Not support resolution (%dx%d%c)\n",
+- priv->mf->width, priv->mf->height,
+- (priv->mf->field == V4L2_FIELD_NONE) ? 'p' : 'i');
+- return -EINVAL;
+ }
+
+ static irqreturn_t rcar_csi2_irq(int irq, void *data)
+@@ -370,6 +478,16 @@ static int rcar_csi2_hwinit(struct rcar_csi2 *priv)
+ iowrite32(0x0001000f, priv->base + RCAR_CSI2_FLD);
+ tmp |= 0x1;
+ break;
++ case 2:
++ /* First field number setting */
++ iowrite32(0x0001000f, priv->base + RCAR_CSI2_FLD);
++ tmp |= 0x3;
++ break;
++ case 3:
++ /* First field number setting */
++ iowrite32(0x0001000f, priv->base + RCAR_CSI2_FLD);
++ tmp |= 0x7;
++ break;
+ case 4:
+ /* First field number setting */
+ iowrite32(0x0002000f, priv->base + RCAR_CSI2_FLD);
+@@ -382,11 +500,27 @@ static int rcar_csi2_hwinit(struct rcar_csi2 *priv)
+ return -EINVAL;
+ }
+
++ if (soc_device_match(r8a7795)) {
++ /* Set PHY Test Interface Write Register in R-Car H3(ES2.0) */
++ iowrite32(0x01cc01e2, priv->base + RCAR_CSI2_PHTW);
++ iowrite32(0x010101e3, priv->base + RCAR_CSI2_PHTW);
++ iowrite32(0x010101e4, priv->base + RCAR_CSI2_PHTW);
++ iowrite32(0x01100104, priv->base + RCAR_CSI2_PHTW);
++ iowrite32(0x01030100, priv->base + RCAR_CSI2_PHTW);
++ iowrite32(0x01800107, priv->base + RCAR_CSI2_PHTW);
++ }
++
+ /* set PHY frequency */
+ ret = rcar_csi2_set_phy_freq(priv);
+ if (ret < 0)
+ return ret;
+
++ /* Set CSI0CLK Frequency Configuration Preset Register
++ * in R-Car H3(ES2.0)
++ */
++ if (soc_device_match(r8a7795))
++ iowrite32(CSI0CLKFREQRANGE(32), priv->base + RCAR_CSI2_CSI0CLKFCPR);
++
+ /* Enable lanes */
+ iowrite32(tmp, priv->base + RCAR_CSI2_PHYCNT);
+
+@@ -447,32 +581,22 @@ static int rcar_csi2_hwinit(struct rcar_csi2 *priv)
+
+ static int rcar_csi2_s_power(struct v4l2_subdev *sd, int on)
+ {
+- struct rcar_csi2 *priv = container_of(sd, struct rcar_csi2, subdev);
+- struct v4l2_subdev *tmp_sd;
+- struct v4l2_subdev_format fmt = {
+- .which = V4L2_SUBDEV_FORMAT_ACTIVE,
+- };
+- struct v4l2_mbus_framefmt *mf = &fmt.format;
++ struct rcar_csi2 *priv = v4l2_get_subdevdata(sd);
+ int ret = 0;
+
+ if (on) {
+- v4l2_device_for_each_subdev(tmp_sd, sd->v4l2_dev) {
+- if (strncmp(tmp_sd->name, CONNECT_SLAVE_NAME,
+- sizeof(CONNECT_SLAVE_NAME) - 1) == 0) {
+- v4l2_subdev_call(tmp_sd, pad, get_fmt,
+- NULL, &fmt);
+- if (ret < 0)
+- return ret;
+- }
++ if (atomic_inc_return(&priv->use_count) == 1) {
++ pm_runtime_get_sync(&priv->pdev->dev);
++ ret = rcar_csi2_hwinit(priv);
++ if (ret < 0)
++ return ret;
+ }
+- priv->mf = mf;
+- pm_runtime_get_sync(&priv->pdev->dev);
+- ret = rcar_csi2_hwinit(priv);
+- if (ret < 0)
+- return ret;
+ } else {
+- rcar_csi2_hwdeinit(priv);
+- pm_runtime_put_sync(&priv->pdev->dev);
++ if (atomic_dec_return(&priv->use_count) == 0) {
++ rcar_sci2_debug_show(priv);
++ rcar_csi2_hwdeinit(priv);
++ pm_runtime_put_sync(&priv->pdev->dev);
++ }
+ }
+
+ return ret;
+@@ -488,6 +612,7 @@ static struct v4l2_subdev_ops rcar_csi2_subdev_ops = {
+
+ #ifdef CONFIG_OF
+ static const struct of_device_id rcar_csi2_of_table[] = {
++ { .compatible = "renesas,r8a7797-csi2", .data = (void *)RCAR_GEN3 },
+ { .compatible = "renesas,r8a7796-csi2", .data = (void *)RCAR_GEN3 },
+ { .compatible = "renesas,r8a7795-csi2", .data = (void *)RCAR_GEN3 },
+ { },
+@@ -496,6 +621,7 @@ MODULE_DEVICE_TABLE(of, rcar_csi2_of_table);
+ #endif
+
+ static struct platform_device_id rcar_csi2_id_table[] = {
++ { "r8a7797-csi2", RCAR_GEN3 },
+ { "r8a7796-csi2", RCAR_GEN3 },
+ { "r8a7795-csi2", RCAR_GEN3 },
+ {},
+@@ -505,7 +631,7 @@ MODULE_DEVICE_TABLE(platform, rcar_csi2_id_table);
+ static int rcar_csi2_parse_dt(struct device_node *np,
+ struct rcar_csi2_link_config *config)
+ {
+- struct v4l2_of_endpoint bus_cfg;
++ struct v4l2_fwnode_endpoint bus_cfg;
+ struct device_node *endpoint;
+ struct device_node *vc_np, *vc_ch;
+ const char *str;
+@@ -518,19 +644,20 @@ static int rcar_csi2_parse_dt(struct device_node *np,
+ if (!endpoint)
+ return -EINVAL;
+
+- v4l2_of_parse_endpoint(endpoint, &bus_cfg);
++ v4l2_fwnode_endpoint_parse(of_fwnode_handle(endpoint), &bus_cfg);
++ ret = of_property_read_u32(endpoint, "csi-rate", &config->csi_rate);
++ if (ret < 0) {
++ printk(KERN_ERR "csi-rate not set\n");
++ return ret;
++ }
+ of_node_put(endpoint);
+
+ config->lanes = bus_cfg.bus.mipi_csi2.num_data_lanes;
+
+- ret = of_property_read_string(np, "adi,input-interface", &str);
+- if (ret < 0)
+- return ret;
+-
+ vc_np = of_get_child_by_name(np, "virtual,channel");
+
+- config->vcdt = 0;
+- config->vcdt2 = 0;
++ config->vcdt = 0x81008000;
++ config->vcdt2 = 0x83008200;
+ for (i = 0; i < VC_MAX_CHANNEL; i++) {
+ sprintf(csi_name, "csi2_vc%d", i);
+
+@@ -549,6 +676,8 @@ static int rcar_csi2_parse_dt(struct device_node *np,
+ config->vcdt |= (0x24 << (i * 16));
+ else if (!strcmp(str, "ycbcr422"))
+ config->vcdt |= (0x1e << (i * 16));
++ else if (!strcmp(str, "raw8"))
++ config->vcdt |= (0x2a << (i * 16));
+ else
+ config->vcdt |= 0;
+
+@@ -563,6 +692,8 @@ static int rcar_csi2_parse_dt(struct device_node *np,
+ config->vcdt2 |= (0x24 << (j * 16));
+ else if (!strcmp(str, "ycbcr422"))
+ config->vcdt2 |= (0x1e << (j * 16));
++ else if (!strcmp(str, "raw8"))
++ config->vcdt2 |= (0x2a << (j * 16));
+ else
+ config->vcdt2 |= 0;
+
+@@ -584,6 +715,7 @@ static int rcar_csi2_probe(struct platform_device *pdev)
+ /* Platform data specify the PHY, lanes, ECC, CRC */
+ struct rcar_csi2_pdata *pdata;
+ struct rcar_csi2_link_config link_config;
++ int i;
+
+ dev_dbg(&pdev->dev, "CSI2 probed.\n");
+
+@@ -594,12 +726,7 @@ static int rcar_csi2_probe(struct platform_device *pdev)
+ if (ret)
+ return ret;
+
+- if (link_config.lanes == 4)
+- dev_info(&pdev->dev,
+- "Detected rgb888 in rcar_csi2_parse_dt\n");
+- else
+- dev_info(&pdev->dev,
+- "Detected YCbCr422 in rcar_csi2_parse_dt\n");
++ dev_info(&pdev->dev, "Data lanes %d, link freq %d\n", link_config.lanes, link_config.csi_rate);
+ } else {
+ pdata = pdev->dev.platform_data;
+ if (!pdata)
+@@ -631,23 +758,27 @@ static int rcar_csi2_probe(struct platform_device *pdev)
+ return ret;
+
+ priv->pdev = pdev;
+- priv->subdev.owner = THIS_MODULE;
+- priv->subdev.dev = &pdev->dev;
+ priv->lanes = link_config.lanes;
+ priv->vcdt = link_config.vcdt;
+ priv->vcdt2 = link_config.vcdt2;
++ priv->csi_rate = link_config.csi_rate;
++ atomic_set(&priv->use_count, 0);
+
+- platform_set_drvdata(pdev, &priv->subdev);
++ platform_set_drvdata(pdev, priv);
+
+- v4l2_subdev_init(&priv->subdev, &rcar_csi2_subdev_ops);
+- v4l2_set_subdevdata(&priv->subdev, &pdev->dev);
++ for (i= 0; i < 4; i++) {
++ priv->subdev[i].owner = THIS_MODULE;
++ priv->subdev[i].dev = &pdev->dev;
++ v4l2_subdev_init(&priv->subdev[i], &rcar_csi2_subdev_ops);
++ v4l2_set_subdevdata(&priv->subdev[i], priv);
+
+- snprintf(priv->subdev.name, V4L2_SUBDEV_NAME_SIZE, "rcar_csi2.%s",
+- dev_name(&pdev->dev));
++ snprintf(priv->subdev[i].name, V4L2_SUBDEV_NAME_SIZE, "rcar_csi2.%s",
++ dev_name(&pdev->dev));
+
+- ret = v4l2_async_register_subdev(&priv->subdev);
+- if (ret < 0)
+- return ret;
++ ret = v4l2_async_register_subdev(&priv->subdev[i]);
++ if (ret < 0)
++ return ret;
++ }
+
+ spin_lock_init(&priv->lock);
+
+@@ -660,10 +791,11 @@ static int rcar_csi2_probe(struct platform_device *pdev)
+
+ static int rcar_csi2_remove(struct platform_device *pdev)
+ {
+- struct v4l2_subdev *subdev = platform_get_drvdata(pdev);
+- struct rcar_csi2 *priv = container_of(subdev, struct rcar_csi2, subdev);
++ struct rcar_csi2 *priv = platform_get_drvdata(pdev);
++ int i;
+
+- v4l2_async_unregister_subdev(&priv->subdev);
++ for (i= 0; i < 4; i++)
++ v4l2_async_unregister_subdev(&priv->subdev[i]);
+ pm_runtime_disable(&pdev->dev);
+
+ return 0;
+diff --git a/drivers/media/platform/soc_camera/rcar_vin.c b/drivers/media/platform/soc_camera/rcar_vin.c
+index 400958b..9733555 100644
+--- a/drivers/media/platform/soc_camera/rcar_vin.c
++++ b/drivers/media/platform/soc_camera/rcar_vin.c
+@@ -26,6 +26,7 @@
+ #include <linux/module.h>
+ #include <linux/of.h>
+ #include <linux/of_device.h>
++#include <linux/of_graph.h>
+ #include <linux/platform_device.h>
+ #include <linux/pm_runtime.h>
+ #include <linux/slab.h>
+@@ -34,11 +35,12 @@
+
+ #include <media/soc_camera.h>
+ #include <media/drv-intf/soc_mediabus.h>
++#include <media/v4l2-async.h>
+ #include <media/v4l2-common.h>
+ #include <media/v4l2-dev.h>
+ #include <media/v4l2-device.h>
++#include <media/v4l2-fwnode.h>
+ #include <media/v4l2-mediabus.h>
+-#include <media/v4l2-of.h>
+ #include <media/v4l2-subdev.h>
+ #include <media/videobuf2-dma-contig.h>
+
+@@ -95,17 +97,21 @@
+ #define VNC8A_REG 0xF0 /* Video n Coefficient Set C8A Register */
+ #define VNC8B_REG 0xF4 /* Video n Coefficient Set C8B Register */
+ #define VNC8C_REG 0xF8 /* Video n Coefficient Set C8C Register */
++#define VNLUTP_REG 0x100 /* Video n Lookup table pointer */
++#define VNLUTD_REG 0x104 /* Video n Lookup table data register */
+
+ /* Register bit fields for R-Car VIN */
+ /* Video n Main Control Register bits */
+ #define VNMC_DPINE (1 << 27)
+ #define VNMC_SCLE (1 << 26)
+ #define VNMC_FOC (1 << 21)
++#define VNMC_LUTE (1 << 20)
+ #define VNMC_YCAL (1 << 19)
+ #define VNMC_INF_YUV8_BT656 (0 << 16)
+ #define VNMC_INF_YUV8_BT601 (1 << 16)
+ #define VNMC_INF_YUV10_BT656 (2 << 16)
+ #define VNMC_INF_YUV10_BT601 (3 << 16)
++#define VNMC_INF_RAW8 (4 << 16)
+ #define VNMC_INF_YUV16 (5 << 16)
+ #define VNMC_INF_RGB888 (6 << 16)
+ #define VNMC_INF_MASK (7 << 16)
+@@ -138,6 +144,7 @@
+ #define VNINTS_FOS (1 << 0)
+
+ /* Video n Data Mode Register bits */
++#define VNDMR_YMODE_Y8 (1 << 12)
+ #define VNDMR_EXRGB (1 << 8)
+ #define VNDMR_BPSM (1 << 4)
+ #define VNDMR_DTMD_YCSEP (1 << 1)
+@@ -154,7 +161,7 @@
+ #define VNCSI_IFMD_REG 0x20 /* Video n CSI2 Interface Mode Register */
+
+ #define VNCSI_IFMD_DES1 (1 << 26) /* CSI20 */
+-#define VNCSI_IFMD_DES0 (1 << 25) /* H3:CSI40/41, M3:CSI40 */
++#define VNCSI_IFMD_DES0 (1 << 25) /* H3:CSI40/41, M3:CSI40, V3M:CSI40 */
+
+ #define VNCSI_IFMD_CSI_CHSEL(n) (n << 0)
+ #define VNCSI_IFMD_SEL_NUMBER 5
+@@ -178,6 +185,10 @@
+ #define RCAR_VIN_BT656 (1 << 3)
+ #define RCAR_VIN_CSI2 (1 << 4)
+
++static int lut_reverse;
++module_param(lut_reverse, int, 0644);
++MODULE_PARM_DESC(lut_reverse, " Use LUT for data order reverse (only 8-bit data allowed)*/");
++
+ static int ifmd0_reg_match[VNCSI_IFMD_SEL_NUMBER];
+ static int ifmd4_reg_match[VNCSI_IFMD_SEL_NUMBER];
+ static int ifmd0_init = true;
+@@ -185,6 +196,7 @@ static int ifmd4_init = true;
+
+ enum chip_id {
+ RCAR_GEN3,
++ RCAR_V3M,
+ RCAR_M3,
+ RCAR_H3,
+ RCAR_GEN2,
+@@ -360,10 +372,54 @@ static const struct vin_gen3_ifmd vin_m3_vc_ifmd[] = {
+ },
+ };
+
++static const struct vin_gen3_ifmd vin_v3_vc_ifmd[] = {
++ { 0x0000,
++ {
++ {RCAR_CSI40, RCAR_VIRTUAL_CH0},
++ {RCAR_CSI_CH_NONE, RCAR_VIN_CH_NONE},
++ {RCAR_CSI_CH_NONE, RCAR_VIN_CH_NONE},
++ {RCAR_CSI40, RCAR_VIRTUAL_CH1},
++ }
++ },
++ { 0x0001,
++ {
++ {RCAR_CSI_CH_NONE, RCAR_VIN_CH_NONE},
++ {RCAR_CSI_CH_NONE, RCAR_VIN_CH_NONE},
++ {RCAR_CSI40, RCAR_VIRTUAL_CH0},
++ {RCAR_CSI_CH_NONE, RCAR_VIN_CH_NONE},
++ }
++ },
++ { 0x0002,
++ {
++ {RCAR_CSI_CH_NONE, RCAR_VIN_CH_NONE},
++ {RCAR_CSI40, RCAR_VIRTUAL_CH0},
++ {RCAR_CSI_CH_NONE, RCAR_VIN_CH_NONE},
++ {RCAR_CSI_CH_NONE, RCAR_VIN_CH_NONE},
++ }
++ },
++ { 0x0003,
++ {
++ {RCAR_CSI40, RCAR_VIRTUAL_CH0},
++ {RCAR_CSI40, RCAR_VIRTUAL_CH1},
++ {RCAR_CSI40, RCAR_VIRTUAL_CH2},
++ {RCAR_CSI40, RCAR_VIRTUAL_CH3},
++ }
++ },
++ { 0x0004,
++ {
++ {RCAR_CSI_CH_NONE, RCAR_VIN_CH_NONE},
++ {RCAR_CSI_CH_NONE, RCAR_VIN_CH_NONE},
++ {RCAR_CSI_CH_NONE, RCAR_VIN_CH_NONE},
++ {RCAR_CSI_CH_NONE, RCAR_VIN_CH_NONE},
++ }
++ },
++};
++
+ enum csi2_fmt {
+ RCAR_CSI_FMT_NONE = -1,
+ RCAR_CSI_RGB888,
+ RCAR_CSI_YCBCR422,
++ RCAR_CSI_RAW8,
+ };
+
+ struct vin_coeff {
+@@ -729,10 +785,14 @@ struct rcar_vin_priv {
+ enum csi2_fmt csi_fmt;
+ enum virtual_ch vc;
+ bool csi_sync;
++ bool deser_sync;
++ int lut_updated;
+
+ struct rcar_vin_async_client *async_client;
+ /* Asynchronous CSI2 linking */
+ struct v4l2_subdev *csi2_sd;
++ /* Asynchronous Deserializer linking */
++ struct v4l2_subdev *deser_sd;
+ /* Synchronous probing compatibility */
+ struct platform_device *csi2_pdev;
+
+@@ -849,7 +909,8 @@ static int rcar_vin_videobuf_setup(struct vb2_queue *vq,
+ struct rcar_vin_priv *priv = ici->priv;
+ struct rcar_vin_cam *cam = icd->host_priv;
+
+- if (priv->chip == RCAR_H3 || priv->chip == RCAR_M3) {
++ if (priv->chip == RCAR_H3 || priv->chip == RCAR_M3 ||
++ priv->chip == RCAR_V3M) {
+ if ((priv->ratio_h > 0x10000) || (priv->ratio_v > 0x10000)) {
+ dev_err(icd->parent, "Scaling rate parameter error\n");
+ return -EINVAL;
+@@ -894,6 +955,8 @@ static int rcar_vin_setup(struct rcar_vin_priv *priv)
+ struct rcar_vin_cam *cam = icd->host_priv;
+ u32 vnmc, dmr, interrupts;
+ bool progressive = false, output_is_yuv = false, input_is_yuv = false;
++ int i;
++ u32 lutd;
+
+ switch (priv->field) {
+ case V4L2_FIELD_TOP:
+@@ -944,6 +1007,10 @@ static int rcar_vin_setup(struct rcar_vin_priv *priv)
+ VNMC_INF_YUV10_BT656 : VNMC_INF_YUV10_BT601;
+ input_is_yuv = true;
+ break;
++ case MEDIA_BUS_FMT_SBGGR8_1X8:
++ case MEDIA_BUS_FMT_SBGGR12_1X12:
++ vnmc |= VNMC_INF_RAW8 | VNMC_BPS;
++ break;
+ default:
+ break;
+ }
+@@ -951,7 +1018,8 @@ static int rcar_vin_setup(struct rcar_vin_priv *priv)
+ /* output format */
+ switch (icd->current_fmt->host_fmt->fourcc) {
+ case V4L2_PIX_FMT_NV12:
+- if (priv->chip == RCAR_H3 || priv->chip == RCAR_M3) {
++ if (priv->chip == RCAR_H3 || priv->chip == RCAR_M3 ||
++ priv->chip == RCAR_V3M) {
+ iowrite32(ALIGN((cam->out_width * cam->out_height),
+ 0x80), priv->base + VNUVAOF_REG);
+ dmr = VNDMR_DTMD_YCSEP_YCBCR420;
+@@ -975,6 +1043,10 @@ static int rcar_vin_setup(struct rcar_vin_priv *priv)
+ dmr = 0;
+ output_is_yuv = true;
+ break;
++ case V4L2_PIX_FMT_GREY:
++ dmr = VNDMR_DTMD_YCSEP | VNDMR_YMODE_Y8;
++ output_is_yuv = true;
++ break;
+ case V4L2_PIX_FMT_ARGB555:
+ dmr = VNDMR_DTMD_ARGB;
+ break;
+@@ -983,6 +1055,7 @@ static int rcar_vin_setup(struct rcar_vin_priv *priv)
+ break;
+ case V4L2_PIX_FMT_XBGR32:
+ if (priv->chip != RCAR_H3 && priv->chip != RCAR_M3 &&
++ priv->chip != RCAR_V3M &&
+ priv->chip != RCAR_GEN2 && priv->chip != RCAR_H1 &&
+ priv->chip != RCAR_E1)
+ goto e_format;
+@@ -990,11 +1063,16 @@ static int rcar_vin_setup(struct rcar_vin_priv *priv)
+ dmr = VNDMR_EXRGB;
+ break;
+ case V4L2_PIX_FMT_ABGR32:
+- if (priv->chip != RCAR_H3 && priv->chip != RCAR_M3)
++ if (priv->chip != RCAR_H3 && priv->chip != RCAR_M3 &&
++ priv->chip != RCAR_V3M)
+ goto e_format;
+
+ dmr = VNDMR_EXRGB | VNDMR_DTMD_ARGB;
+ break;
++ case V4L2_PIX_FMT_SBGGR8:
++ case V4L2_PIX_FMT_SBGGR12:
++ dmr = 0;
++ break;
+ default:
+ goto e_format;
+ }
+@@ -1006,13 +1084,16 @@ static int rcar_vin_setup(struct rcar_vin_priv *priv)
+ if (input_is_yuv == output_is_yuv)
+ vnmc |= VNMC_BPS;
+
+- if (priv->chip == RCAR_H3 || priv->chip == RCAR_M3) {
++ if (priv->chip == RCAR_H3 || priv->chip == RCAR_M3 ||
++ priv->chip == RCAR_V3M) {
+ if (priv->pdata_flags & RCAR_VIN_CSI2)
+ vnmc &= ~VNMC_DPINE;
+ else
+ vnmc |= VNMC_DPINE;
+
+- if ((icd->current_fmt->host_fmt->fourcc != V4L2_PIX_FMT_NV12)
++ if ((icd->current_fmt->host_fmt->fourcc != V4L2_PIX_FMT_NV12) &&
++ (icd->current_fmt->host_fmt->fourcc != V4L2_PIX_FMT_SBGGR8) &&
++ (icd->current_fmt->host_fmt->fourcc != V4L2_PIX_FMT_SBGGR12)
+ && is_scaling(cam))
+ vnmc |= VNMC_SCLE;
+ }
+@@ -1024,6 +1105,33 @@ static int rcar_vin_setup(struct rcar_vin_priv *priv)
+ if (vin_debug)
+ interrupts |= VNIE_FOE;
+
++ if (lut_reverse && !priv->lut_updated) {
++ iowrite32(0, priv->base + VNLUTP_REG);
++
++ for (i = 0; i < 1024; i++) {
++ /* reverse MSB 8bits image at 10bit LUT address */
++ lutd = ((i >> 2) & BIT(0) ? BIT(7) : 0);
++ lutd |= ((i >> 2) & BIT(1) ? BIT(6) : 0);
++ lutd |= ((i >> 2) & BIT(2) ? BIT(5) : 0);
++ lutd |= ((i >> 2) & BIT(3) ? BIT(4) : 0);
++ lutd |= ((i >> 2) & BIT(4) ? BIT(3) : 0);
++ lutd |= ((i >> 2) & BIT(5) ? BIT(2) : 0);
++ lutd |= ((i >> 2) & BIT(6) ? BIT(1) : 0);
++ lutd |= ((i >> 2) & BIT(7) ? BIT(0) : 0);
++#if 0
++ /* strait (no any density convertion, used for testing) */
++ lutd = i >> 2;
++#endif
++ lutd = (lutd << 16) | (lutd << 8) | lutd;
++ iowrite32(lutd, priv->base + VNLUTD_REG);
++ }
++ /* update LUT table once */
++ priv->lut_updated = 1;
++ }
++
++ if (lut_reverse)
++ vnmc |= VNMC_LUTE;
++
+ /* ack interrupts */
+ iowrite32(interrupts, priv->base + VNINTS_REG);
+ /* enable interrupts */
+@@ -1162,6 +1270,10 @@ static void rcar_vin_videobuf_queue(struct vb2_buffer *vb)
+ */
+ static void rcar_vin_wait_stop_streaming(struct rcar_vin_priv *priv)
+ {
++ /* update the status if hardware is not stopped */
++ if (ioread32(priv->base + VNMS_REG) & VNMS_CA)
++ priv->state = RUNNING;
++
+ while (priv->state != STOPPED) {
+ /* issue stop if running */
+ if (priv->state == RUNNING)
+@@ -1312,6 +1424,26 @@ static struct v4l2_subdev *find_csi2(struct rcar_vin_priv *pcdev)
+ return NULL;
+ }
+
++static struct v4l2_subdev *find_deser(struct rcar_vin_priv *pcdev)
++{
++ struct v4l2_subdev *sd;
++ char name[] = "max9286";
++ char name2[] = "ti9x4";
++
++ v4l2_device_for_each_subdev(sd, &pcdev->ici.v4l2_dev) {
++ if (!strncmp(name, sd->name, sizeof(name) - 1)) {
++ pcdev->deser_sd = sd;
++ return sd;
++ }
++ if (!strncmp(name2, sd->name, sizeof(name2) - 1)) {
++ pcdev->deser_sd = sd;
++ return sd;
++ }
++ }
++
++ return NULL;
++}
++
+ static int rcar_vin_add_device(struct soc_camera_device *icd)
+ {
+ struct soc_camera_host *ici = to_soc_camera_host(icd->parent);
+@@ -1323,9 +1455,11 @@ static int rcar_vin_add_device(struct soc_camera_device *icd)
+
+ pm_runtime_get_sync(ici->v4l2_dev.dev);
+
+- if (priv->chip == RCAR_H3 || priv->chip == RCAR_M3) {
++ if (priv->chip == RCAR_H3 || priv->chip == RCAR_M3 ||
++ priv->chip == RCAR_V3M) {
+ struct v4l2_subdev *csi2_sd = find_csi2(priv);
+- int ret;
++ struct v4l2_subdev *deser_sd = find_deser(priv);
++ int ret = 0;
+
+ if (csi2_sd) {
+ csi2_sd->grp_id = soc_camera_grp_id(icd);
+@@ -1340,6 +1474,18 @@ static int rcar_vin_add_device(struct soc_camera_device *icd)
+ if (ret < 0 && ret != -ENOIOCTLCMD && ret != -ENODEV)
+ return ret;
+ }
++ if (deser_sd) {
++ v4l2_set_subdev_hostdata(deser_sd, icd);
++
++ ret = v4l2_subdev_call(deser_sd, core, s_power, 1);
++ priv->deser_sync = true;
++
++ if (ret < 0 && ret != -EINVAL)
++ priv->deser_sync = false;
++
++ if (ret < 0 && ret != -ENOIOCTLCMD && ret != -ENODEV)
++ return ret;
++ }
+ /*
+ * -ENODEV is special:
+ * either csi2_sd == NULL or the CSI-2 driver
+@@ -1367,6 +1513,7 @@ static void rcar_vin_remove_device(struct soc_camera_device *icd)
+ struct rcar_vin_priv *priv = ici->priv;
+ struct vb2_v4l2_buffer *vbuf;
+ struct v4l2_subdev *csi2_sd = find_csi2(priv);
++ struct v4l2_subdev *deser_sd = find_deser(priv);
+ int i;
+
+ /* disable capture, disable interrupts */
+@@ -1393,6 +1540,8 @@ static void rcar_vin_remove_device(struct soc_camera_device *icd)
+
+ if ((csi2_sd) && (priv->csi_sync))
+ v4l2_subdev_call(csi2_sd, core, s_power, 0);
++ if ((deser_sd) && (priv->deser_sync))
++ v4l2_subdev_call(deser_sd, core, s_power, 0);
+
+ dev_dbg(icd->parent, "R-Car VIN driver detached from camera %d\n",
+ icd->devnum);
+@@ -1569,14 +1718,21 @@ static int rcar_vin_set_rect(struct soc_camera_device *icd)
+ break;
+ }
+
+- if (priv->chip == RCAR_H3 || priv->chip == RCAR_M3) {
+- if ((icd->current_fmt->host_fmt->fourcc != V4L2_PIX_FMT_NV12)
++ if (priv->chip == RCAR_H3 || priv->chip == RCAR_M3 ||
++ priv->chip == RCAR_V3M) {
++ if ((icd->current_fmt->host_fmt->fourcc != V4L2_PIX_FMT_NV12) &&
++ (icd->current_fmt->host_fmt->fourcc != V4L2_PIX_FMT_SBGGR8) &&
++ (icd->current_fmt->host_fmt->fourcc != V4L2_PIX_FMT_SBGGR12)
+ && is_scaling(cam)) {
+ ret = rcar_vin_uds_set(priv, cam);
+ if (ret < 0)
+ return ret;
+ }
+- if (is_scaling(cam) ||
++ if ((icd->current_fmt->host_fmt->fourcc == V4L2_PIX_FMT_SBGGR8) ||
++ (icd->current_fmt->host_fmt->fourcc == V4L2_PIX_FMT_SBGGR12))
++ iowrite32(ALIGN(cam->out_width / 2, 0x10),
++ priv->base + VNIS_REG);
++ else if (is_scaling(cam) ||
+ (icd->current_fmt->host_fmt->fourcc == V4L2_PIX_FMT_NV16) ||
+ (icd->current_fmt->host_fmt->fourcc == V4L2_PIX_FMT_NV12))
+ iowrite32(ALIGN(cam->out_width, 0x20),
+@@ -1720,14 +1876,16 @@ static int rcar_vin_set_bus_param(struct soc_camera_device *icd)
+ if (ret < 0 && ret != -ENOIOCTLCMD)
+ return ret;
+
+- if (priv->chip == RCAR_H3 || priv->chip == RCAR_M3) {
++ if (priv->chip == RCAR_H3 || priv->chip == RCAR_M3 ||
++ priv->chip == RCAR_V3M) {
+ if (cfg.type == V4L2_MBUS_CSI2)
+ vnmc &= ~VNMC_DPINE;
+ else
+ vnmc |= VNMC_DPINE;
+ }
+
+- if (priv->chip == RCAR_H3 || priv->chip == RCAR_M3)
++ if (priv->chip == RCAR_H3 || priv->chip == RCAR_M3 ||
++ priv->chip == RCAR_V3M)
+ val = VNDMR2_FTEV;
+ else
+ val = VNDMR2_FTEV | VNDMR2_VLV(1);
+@@ -1815,6 +1973,14 @@ static const struct soc_mbus_pixelfmt rcar_vin_formats[] = {
+ .layout = SOC_MBUS_LAYOUT_PACKED,
+ },
+ {
++ .fourcc = V4L2_PIX_FMT_GREY,
++ .name = "GREY8",
++ .bits_per_sample = 8,
++ .packing = SOC_MBUS_PACKING_NONE,
++ .order = SOC_MBUS_ORDER_LE,
++ .layout = SOC_MBUS_LAYOUT_PACKED,
++ },
++ {
+ .fourcc = V4L2_PIX_FMT_RGB565,
+ .name = "RGB565",
+ .bits_per_sample = 16,
+@@ -1846,6 +2012,22 @@ static const struct soc_mbus_pixelfmt rcar_vin_formats[] = {
+ .order = SOC_MBUS_ORDER_LE,
+ .layout = SOC_MBUS_LAYOUT_PACKED,
+ },
++ {
++ .fourcc = V4L2_PIX_FMT_SBGGR8,
++ .name = "Bayer 8 BGGR",
++ .bits_per_sample = 8,
++ .packing = SOC_MBUS_PACKING_NONE,
++ .order = SOC_MBUS_ORDER_LE,
++ .layout = SOC_MBUS_LAYOUT_PACKED,
++ },
++ {
++ .fourcc = V4L2_PIX_FMT_SBGGR12,
++ .name = "Bayer 12 BGGR",
++ .bits_per_sample = 8,
++ .packing = SOC_MBUS_PACKING_NONE,
++ .order = SOC_MBUS_ORDER_LE,
++ .layout = SOC_MBUS_LAYOUT_PACKED,
++ },
+ };
+
+ static int rcar_vin_get_formats(struct soc_camera_device *icd, unsigned int idx,
+@@ -1959,6 +2141,8 @@ static int rcar_vin_get_formats(struct soc_camera_device *icd, unsigned int idx,
+ case MEDIA_BUS_FMT_YUYV8_2X8:
+ case MEDIA_BUS_FMT_YUYV10_2X10:
+ case MEDIA_BUS_FMT_RGB888_1X24:
++ case MEDIA_BUS_FMT_SBGGR8_1X8:
++ case MEDIA_BUS_FMT_SBGGR12_1X12:
+ if (cam->extra_fmt)
+ break;
+
+@@ -2165,12 +2349,15 @@ static int rcar_vin_set_fmt(struct soc_camera_device *icd,
+ case V4L2_PIX_FMT_ABGR32:
+ case V4L2_PIX_FMT_UYVY:
+ case V4L2_PIX_FMT_YUYV:
++ case V4L2_PIX_FMT_GREY:
+ case V4L2_PIX_FMT_RGB565:
+ case V4L2_PIX_FMT_ARGB555:
+ case V4L2_PIX_FMT_NV16:
+ can_scale = true;
+ break;
+ case V4L2_PIX_FMT_NV12:
++ case V4L2_PIX_FMT_SBGGR8:
++ case V4L2_PIX_FMT_SBGGR12:
+ default:
+ can_scale = false;
+ break;
+@@ -2263,7 +2450,8 @@ static int rcar_vin_try_fmt(struct soc_camera_device *icd,
+ /* odd number clipping by pixel post clip processing, */
+ /* it is outputted to a memory per even pixels. */
+ if ((pixfmt == V4L2_PIX_FMT_NV16) || (pixfmt == V4L2_PIX_FMT_NV12) ||
+- (pixfmt == V4L2_PIX_FMT_YUYV) || (pixfmt == V4L2_PIX_FMT_UYVY))
++ (pixfmt == V4L2_PIX_FMT_YUYV) || (pixfmt == V4L2_PIX_FMT_UYVY) ||
++ (pixfmt == V4L2_PIX_FMT_GREY))
+ v4l_bound_align_image(&pix->width, 5, priv->max_width, 1,
+ &pix->height, 2, priv->max_height, 0, 0);
+ else
+@@ -2289,7 +2477,8 @@ static int rcar_vin_try_fmt(struct soc_camera_device *icd,
+ if (ret < 0)
+ return ret;
+
+- if (priv->chip == RCAR_H3 || priv->chip == RCAR_M3) {
++ if (priv->chip == RCAR_H3 || priv->chip == RCAR_M3 ||
++ priv->chip == RCAR_V3M) {
+ /* Adjust max scaling size for Gen3 */
+ if (pix->width > 4096)
+ pix->width = priv->max_width;
+@@ -2432,6 +2621,19 @@ static int rcar_vin_cropcap(struct soc_camera_device *icd,
+ }
+ #endif
+
++static int rcar_vin_get_edid(struct soc_camera_device *icd,
++ struct v4l2_edid *edid)
++{
++ struct v4l2_subdev *sd = soc_camera_to_subdev(icd);
++ int ret;
++
++ ret = v4l2_subdev_call(sd, pad, get_edid, edid);
++ if (ret < 0)
++ return ret;
++
++ return 0;
++}
++
+ static struct soc_camera_host_ops rcar_vin_host_ops = {
+ .owner = THIS_MODULE,
+ .add = rcar_vin_add_device,
+@@ -2450,10 +2652,12 @@ static struct soc_camera_host_ops rcar_vin_host_ops = {
+ .get_selection = rcar_vin_get_selection,
+ .cropcap = rcar_vin_cropcap,
+ #endif
++ .get_edid = rcar_vin_get_edid,
+ };
+
+ #ifdef CONFIG_OF
+ static const struct of_device_id rcar_vin_of_table[] = {
++ { .compatible = "renesas,vin-r8a7797", .data = (void *)RCAR_V3M },
+ { .compatible = "renesas,vin-r8a7796", .data = (void *)RCAR_M3 },
+ { .compatible = "renesas,vin-r8a7795", .data = (void *)RCAR_H3 },
+ { .compatible = "renesas,vin-r8a7794", .data = (void *)RCAR_GEN2 },
+@@ -2469,7 +2673,7 @@ static const struct of_device_id rcar_vin_of_table[] = {
+ MODULE_DEVICE_TABLE(of, rcar_vin_of_table);
+ #endif
+
+-#define MAP_MAX_NUM 32
++#define MAP_MAX_NUM 128
+ static DECLARE_BITMAP(device_map, MAP_MAX_NUM);
+ static DEFINE_MUTEX(list_lock);
+
+@@ -2578,6 +2782,12 @@ static struct soc_camera_device *rcar_vin_add_pdev(
+ return platform_get_drvdata(pdev);
+ }
+
++static const struct v4l2_async_notifier_operations rcar_vin_sensor_ops = {
++ .bound = rcar_vin_async_bound,
++ .unbind = rcar_vin_async_unbind,
++ .complete = rcar_vin_async_complete,
++};
++
+ static int rcar_vin_soc_of_bind(struct rcar_vin_priv *priv,
+ struct soc_camera_host *ici,
+ struct device_node *ep,
+@@ -2597,8 +2807,8 @@ static int rcar_vin_soc_of_bind(struct rcar_vin_priv *priv,
+ if (!info)
+ return -ENOMEM;
+
+- info->sasd.asd.match.of.node = remote;
+- info->sasd.asd.match_type = V4L2_ASYNC_MATCH_OF;
++ info->sasd.asd.match.fwnode.fwnode = of_fwnode_handle(remote);
++ info->sasd.asd.match_type = V4L2_ASYNC_MATCH_FWNODE;
+ info->subdev = &info->sasd.asd;
+
+ /* Or shall this be managed by the soc-camera device? */
+@@ -2618,9 +2828,7 @@ static int rcar_vin_soc_of_bind(struct rcar_vin_priv *priv,
+
+ sasc->notifier.subdevs = &info->subdev;
+ sasc->notifier.num_subdevs = 1;
+- sasc->notifier.bound = rcar_vin_async_bound;
+- sasc->notifier.unbind = rcar_vin_async_unbind;
+- sasc->notifier.complete = rcar_vin_async_complete;
++ sasc->notifier.ops = &rcar_vin_sensor_ops;
+
+ priv->async_client = sasc;
+
+@@ -2651,7 +2859,7 @@ static int rcar_vin_probe(struct platform_device *pdev)
+ {
+ const struct of_device_id *match = NULL;
+ struct rcar_vin_priv *priv;
+- struct v4l2_of_endpoint ep;
++ struct v4l2_fwnode_endpoint ep;
+ struct device_node *np;
+ struct resource *mem;
+ unsigned int pdata_flags;
+@@ -2659,7 +2867,10 @@ static int rcar_vin_probe(struct platform_device *pdev)
+ const char *str;
+ unsigned int i;
+ struct device_node *epn = NULL, *ren = NULL;
++ struct device_node *csi2_ren = NULL, *max9286_ren = NULL, *ti9x4_ren = NULL;
+ bool csi_use = false;
++ bool max9286_use = false;
++ bool ti9x4_use = false;
+
+ match = of_match_device(of_match_ptr(rcar_vin_of_table), &pdev->dev);
+
+@@ -2686,16 +2897,25 @@ static int rcar_vin_probe(struct platform_device *pdev)
+ dev_dbg(&pdev->dev, "node name:%s\n",
+ of_node_full_name(ren->parent));
+
+- if (strcmp(ren->parent->name, "csi2") == 0)
++ if (strcmp(ren->parent->name, "csi2") == 0) {
++ csi2_ren = ren;
+ csi_use = true;
++ }
+
+- of_node_put(ren);
++ if (strcmp(ren->parent->name, "max9286") == 0) {
++ max9286_ren = of_parse_phandle(epn, "remote-endpoint", 0);
++ max9286_use = true;
++ }
+
+- if (i)
+- break;
++ if (strcmp(ren->parent->name, "ti9x4") == 0) {
++ ti9x4_ren = of_parse_phandle(epn, "remote-endpoint", 0);
++ ti9x4_use = true;
++ }
++
++ of_node_put(ren);
+ }
+
+- ret = v4l2_of_parse_endpoint(np, &ep);
++ ret = v4l2_fwnode_endpoint_parse(of_fwnode_handle(np), &ep);
+ if (ret) {
+ dev_err(&pdev->dev, "could not parse endpoint\n");
+ return ret;
+@@ -2744,17 +2964,24 @@ static int rcar_vin_probe(struct platform_device *pdev)
+ priv->ici.drv_name = dev_name(&pdev->dev);
+ priv->ici.ops = &rcar_vin_host_ops;
+ priv->csi_sync = false;
++ priv->deser_sync = false;
+
+ priv->pdata_flags = pdata_flags;
+ if (!match) {
+ priv->ici.nr = pdev->id;
+ priv->chip = pdev->id_entry->driver_data;
+ } else {
+- priv->ici.nr = of_alias_get_id(pdev->dev.of_node, "vin");
++ if (of_property_read_u32(pdev->dev.of_node, "renesas,id", &i)) {
++ dev_err(&pdev->dev, "%s: No renesas,id property found\n",
++ of_node_full_name(pdev->dev.of_node));
++ return -EINVAL;
++ }
++ priv->ici.nr = i;
+ priv->chip = (enum chip_id)match->data;
+ }
+
+- if (priv->chip == RCAR_H3 || priv->chip == RCAR_M3) {
++ if (priv->chip == RCAR_H3 || priv->chip == RCAR_M3 ||
++ priv->chip == RCAR_V3M) {
+ priv->max_width = 4096;
+ priv->max_height = 4096;
+ } else {
+@@ -2762,7 +2989,8 @@ static int rcar_vin_probe(struct platform_device *pdev)
+ priv->max_height = 2048;
+ }
+
+- if (priv->chip == RCAR_H3 || priv->chip == RCAR_M3) {
++ if (priv->chip == RCAR_H3 || priv->chip == RCAR_M3 ||
++ priv->chip == RCAR_V3M) {
+ u32 ifmd = 0;
+ bool match_flag = false;
+ const struct vin_gen3_ifmd *gen3_ifmd_table = NULL;
+@@ -2841,6 +3069,8 @@ static int rcar_vin_probe(struct platform_device *pdev)
+ gen3_ifmd_table = vin_h3_vc_ifmd;
+ else if (priv->chip == RCAR_M3)
+ gen3_ifmd_table = vin_m3_vc_ifmd;
++ else if (priv->chip == RCAR_V3M)
++ gen3_ifmd_table = vin_v3_vc_ifmd;
+
+ for (i = 0; i < num; i++) {
+ if ((gen3_ifmd_table[i].v_sel[priv->index].csi2_ch
+@@ -2924,7 +3154,19 @@ static int rcar_vin_probe(struct platform_device *pdev)
+ goto cleanup;
+
+ if (csi_use) {
+- ret = rcar_vin_soc_of_bind(priv, &priv->ici, epn, ren->parent);
++ ret = rcar_vin_soc_of_bind(priv, &priv->ici, epn, csi2_ren->parent);
++ if (ret)
++ goto cleanup;
++ }
++
++ if (max9286_use) {
++ ret = rcar_vin_soc_of_bind(priv, &priv->ici, epn, max9286_ren);
++ if (ret)
++ goto cleanup;
++ }
++
++ if (ti9x4_use) {
++ ret = rcar_vin_soc_of_bind(priv, &priv->ici, epn, ti9x4_ren);
+ if (ret)
+ goto cleanup;
+ }
+@@ -2983,6 +3225,9 @@ static int rcar_vin_resume(struct device *dev)
+ } else if (priv->chip == RCAR_M3) {
+ ifmd = VNCSI_IFMD_DES1;
+ gen3_ifmd_table = vin_m3_vc_ifmd;
++ } else if (priv->chip == RCAR_V3M) {
++ ifmd = VNCSI_IFMD_DES1;
++ gen3_ifmd_table = vin_v3_vc_ifmd;
+ }
+
+ for (i = 0; i < num; i++) {
+diff --git a/drivers/media/platform/soc_camera/soc_camera.c b/drivers/media/platform/soc_camera/soc_camera.c
+index 916ff68..1f840cf 100644
+--- a/drivers/media/platform/soc_camera/soc_camera.c
++++ b/drivers/media/platform/soc_camera/soc_camera.c
+@@ -44,7 +44,7 @@
+ #define DEFAULT_WIDTH 640
+ #define DEFAULT_HEIGHT 480
+
+-#define MAP_MAX_NUM 32
++#define MAP_MAX_NUM 128
+ static DECLARE_BITMAP(device_map, MAP_MAX_NUM);
+ static LIST_HEAD(hosts);
+ static LIST_HEAD(devices);
+@@ -1044,6 +1044,18 @@ static int soc_camera_s_parm(struct file *file, void *fh,
+ return -ENOIOCTLCMD;
+ }
+
++static int soc_camera_g_edid(struct file *file, void *fh,
++ struct v4l2_edid *edid)
++{
++ struct soc_camera_device *icd = file->private_data;
++ struct soc_camera_host *ici = to_soc_camera_host(icd->parent);
++
++ if (ici->ops->get_edid)
++ return ici->ops->get_edid(icd, edid);
++
++ return -ENOIOCTLCMD;
++}
++
+ static int soc_camera_probe(struct soc_camera_host *ici,
+ struct soc_camera_device *icd);
+
+@@ -1602,7 +1614,7 @@ static void scan_of_host(struct soc_camera_host *ici)
+ of_node_put(ren);
+
+ if (i) {
+- dev_err(dev, "multiple subdevices aren't supported yet!\n");
++ dev_dbg(dev, "multiple subdevices aren't supported yet!\n");
+ break;
+ }
+ }
+@@ -2013,6 +2025,7 @@ static const struct v4l2_ioctl_ops soc_camera_ioctl_ops = {
+ .vidioc_s_selection = soc_camera_s_selection,
+ .vidioc_g_parm = soc_camera_g_parm,
+ .vidioc_s_parm = soc_camera_s_parm,
++ .vidioc_g_edid = soc_camera_g_edid,
+ };
+
+ static int video_dev_create(struct soc_camera_device *icd)
+diff --git a/drivers/media/platform/soc_camera/soc_mediabus.c b/drivers/media/platform/soc_camera/soc_mediabus.c
+index 0ad4b28..d4e5c1e 100644
+--- a/drivers/media/platform/soc_camera/soc_mediabus.c
++++ b/drivers/media/platform/soc_camera/soc_mediabus.c
+@@ -57,6 +57,16 @@ static const struct soc_mbus_lookup mbus_fmt[] = {
+ .layout = SOC_MBUS_LAYOUT_PACKED,
+ },
+ }, {
++ .code = MEDIA_BUS_FMT_YUYV10_2X10,
++ .fmt = {
++ .fourcc = V4L2_PIX_FMT_YUYV,
++ .name = "YUYV",
++ .bits_per_sample = 10,
++ .packing = SOC_MBUS_PACKING_2X10_PADHI,
++ .order = SOC_MBUS_ORDER_LE,
++ .layout = SOC_MBUS_LAYOUT_PACKED,
++ },
++}, {
+ .code = MEDIA_BUS_FMT_RGB555_2X8_PADHI_LE,
+ .fmt = {
+ .fourcc = V4L2_PIX_FMT_RGB555,
+@@ -403,6 +413,10 @@ int soc_mbus_samples_per_pixel(const struct soc_mbus_pixelfmt *mf,
+ *numerator = 2;
+ *denominator = 1;
+ return 0;
++ case SOC_MBUS_PACKING_2X10_PADHI:
++ *numerator = 3;
++ *denominator = 1;
++ return 0;
+ case SOC_MBUS_PACKING_1_5X8:
+ *numerator = 3;
+ *denominator = 2;
+@@ -428,6 +442,8 @@ s32 soc_mbus_bytes_per_line(u32 width, const struct soc_mbus_pixelfmt *mf)
+ case SOC_MBUS_PACKING_2X8_PADLO:
+ case SOC_MBUS_PACKING_EXTEND16:
+ return width * 2;
++ case SOC_MBUS_PACKING_2X10_PADHI:
++ return width * 3;
+ case SOC_MBUS_PACKING_1_5X8:
+ return width * 3 / 2;
+ case SOC_MBUS_PACKING_VARIABLE:
+diff --git a/drivers/media/v4l2-core/v4l2-async.c b/drivers/media/v4l2-core/v4l2-async.c
+index 7b6c556..1fed0f8 100644
+--- a/drivers/media/v4l2-core/v4l2-async.c
++++ b/drivers/media/v4l2-core/v4l2-async.c
+@@ -398,6 +398,7 @@ static int __v4l2_async_notifier_register(struct v4l2_async_notifier *notifier)
+ case V4L2_ASYNC_MATCH_I2C:
+ break;
+ case V4L2_ASYNC_MATCH_FWNODE:
++#if 0
+ if (v4l2_async_notifier_fwnode_has_async_subdev(
+ notifier, asd->match.fwnode.fwnode, i)) {
+ dev_err(dev,
+@@ -405,6 +406,7 @@ static int __v4l2_async_notifier_register(struct v4l2_async_notifier *notifier)
+ ret = -EEXIST;
+ goto err_unlock;
+ }
++#endif
+ break;
+ default:
+ dev_err(dev, "Invalid match type %u on %p\n",
+diff --git a/include/media/drv-intf/soc_mediabus.h b/include/media/drv-intf/soc_mediabus.h
+index 2ff7737..e5f3f53 100644
+--- a/include/media/drv-intf/soc_mediabus.h
++++ b/include/media/drv-intf/soc_mediabus.h
+@@ -21,6 +21,8 @@
+ * @SOC_MBUS_PACKING_2X8_PADHI: 16 bits transferred in 2 8-bit samples, in the
+ * possibly incomplete byte high bits are padding
+ * @SOC_MBUS_PACKING_2X8_PADLO: as above, but low bits are padding
++ * @SOC_MBUS_PACKING_2X10_PADHI:20 bits transferred in 2 10-bit samples. The
++ * high bits are padding
+ * @SOC_MBUS_PACKING_EXTEND16: sample width (e.g., 10 bits) has to be extended
+ * to 16 bits
+ * @SOC_MBUS_PACKING_VARIABLE: compressed formats with variable packing
+@@ -33,6 +35,7 @@ enum soc_mbus_packing {
+ SOC_MBUS_PACKING_NONE,
+ SOC_MBUS_PACKING_2X8_PADHI,
+ SOC_MBUS_PACKING_2X8_PADLO,
++ SOC_MBUS_PACKING_2X10_PADHI,
+ SOC_MBUS_PACKING_EXTEND16,
+ SOC_MBUS_PACKING_VARIABLE,
+ SOC_MBUS_PACKING_1_5X8,
+diff --git a/include/media/soc_camera.h b/include/media/soc_camera.h
+index 4d8cb07..4381be0 100644
+--- a/include/media/soc_camera.h
++++ b/include/media/soc_camera.h
+@@ -118,6 +118,7 @@ struct soc_camera_host_ops {
+ int (*set_parm)(struct soc_camera_device *, struct v4l2_streamparm *);
+ int (*enum_framesizes)(struct soc_camera_device *, struct v4l2_frmsizeenum *);
+ unsigned int (*poll)(struct file *, poll_table *);
++ int (*get_edid)(struct soc_camera_device *, struct v4l2_edid *);
+ };
+
+ #define SOCAM_SENSOR_INVERT_PCLK (1 << 0)
+--
+2.7.4
+
diff --git a/bsp/meta-rcar/meta-rcar-gen3-adas/recipes-kernel/linux/linux-renesas/0031-media-i2c-Add-ov5647-sensor.patch b/bsp/meta-rcar/meta-rcar-gen3-adas/recipes-kernel/linux/linux-renesas/0031-media-i2c-Add-ov5647-sensor.patch
new file mode 100644
index 00000000..6a530f19
--- /dev/null
+++ b/bsp/meta-rcar/meta-rcar-gen3-adas/recipes-kernel/linux/linux-renesas/0031-media-i2c-Add-ov5647-sensor.patch
@@ -0,0 +1,951 @@
+From 649acea146fb60eff7a7d924f2affcf76b13a3a8 Mon Sep 17 00:00:00 2001
+From: Vladimir Barinov <vladimir.barinov@cogentembedded.com>
+Date: Thu, 1 Jun 2017 19:59:56 +0300
+Subject: [PATCH 023/122] media: i2c: Add ov5647 sensor
+
+Add ov5647 camera sensor driver
+
+Signed-off-by: Vladimir Barinov <vladimir.barinov@cogentembedded.com>
+---
+ drivers/media/i2c/soc_camera/Kconfig | 6 +
+ drivers/media/i2c/soc_camera/Makefile | 1 +
+ drivers/media/i2c/soc_camera/ov5647.c | 648 ++++++++++++++++++++++++++++++++++
+ drivers/media/i2c/soc_camera/ov5647.h | 242 +++++++++++++
+ 4 files changed, 897 insertions(+)
+ create mode 100644 drivers/media/i2c/soc_camera/ov5647.c
+ create mode 100644 drivers/media/i2c/soc_camera/ov5647.h
+
+diff --git a/drivers/media/i2c/soc_camera/Kconfig b/drivers/media/i2c/soc_camera/Kconfig
+index d30a3f9..1db3c6b 100644
+--- a/drivers/media/i2c/soc_camera/Kconfig
++++ b/drivers/media/i2c/soc_camera/Kconfig
+@@ -47,6 +47,12 @@ config SOC_CAMERA_OV5642
+ help
+ This is a V4L2 camera driver for the OmniVision OV5642 sensor
+
++config SOC_CAMERA_OV5647
++ tristate "ov5647 camera support"
++ depends on SOC_CAMERA && I2C
++ help
++ This is a V4L2 camera driver for the OmniVision OV5647 sensor
++
+ config SOC_CAMERA_OV772X
+ tristate "ov772x camera support"
+ depends on SOC_CAMERA && I2C
+diff --git a/drivers/media/i2c/soc_camera/Makefile b/drivers/media/i2c/soc_camera/Makefile
+index 1134c03..0d4242e 100644
+--- a/drivers/media/i2c/soc_camera/Makefile
++++ b/drivers/media/i2c/soc_camera/Makefile
+@@ -5,6 +5,7 @@ obj-$(CONFIG_SOC_CAMERA_MT9T031) += mt9t031.o
+ obj-$(CONFIG_SOC_CAMERA_MT9T112) += mt9t112.o
+ obj-$(CONFIG_SOC_CAMERA_MT9V022) += mt9v022.o
+ obj-$(CONFIG_SOC_CAMERA_OV5642) += ov5642.o
++obj-$(CONFIG_SOC_CAMERA_OV5647) += ov5647.o
+ obj-$(CONFIG_SOC_CAMERA_OV772X) += ov772x.o
+ obj-$(CONFIG_SOC_CAMERA_OV9640) += ov9640.o
+ obj-$(CONFIG_SOC_CAMERA_OV9740) += ov9740.o
+diff --git a/drivers/media/i2c/soc_camera/ov5647.c b/drivers/media/i2c/soc_camera/ov5647.c
+new file mode 100644
+index 0000000..d8b87c1
+--- /dev/null
++++ b/drivers/media/i2c/soc_camera/ov5647.c
+@@ -0,0 +1,648 @@
++/*
++ * V4L2 driver for OmniVision OV5647 cameras.
++ *
++ * Based on Samsung S5K6AAFX SXGA 1/6" 1.3M CMOS Image Sensor driver
++ * Copyright (C) 2011 Sylwester Nawrocki <s.nawrocki@samsung.com>
++ *
++ * Based on Omnivision OV7670 Camera Driver
++ * Copyright (C) 2006-7 Jonathan Corbet <corbet@lwn.net>
++ *
++ * Copyright (C) 2016, Synopsys, Inc.
++ *
++ * Copyright (C) 2017 Cogent Embedded, Inc
++ */
++
++#include <linux/init.h>
++#include <linux/module.h>
++#include <linux/slab.h>
++#include <linux/i2c.h>
++#include <linux/delay.h>
++#include <linux/videodev2.h>
++#include <media/v4l2-device.h>
++#include <media/v4l2-ctrls.h>
++#include <media/v4l2-mediabus.h>
++#include <media/v4l2-image-sizes.h>
++#include <linux/io.h>
++
++#include "ov5647.h"
++
++static bool debug = true;
++module_param(debug, bool, 0644);
++MODULE_PARM_DESC(debug, "Debug level (0-1)");
++
++#define OV5647_I2C_ADDR 0x6c
++#define SENSOR_NAME "ov5647"
++
++#define OV5647_REG_CHIPID_H 0x300A
++#define OV5647_REG_CHIPID_L 0x300B
++
++#define REG_TERM 0xfffe
++#define VAL_TERM 0xfe
++#define REG_DLY 0xffff
++
++/*define the voltage level of control signal*/
++#define CSI_STBY_ON 1
++#define CSI_STBY_OFF 0
++#define CSI_RST_ON 0
++#define CSI_RST_OFF 1
++#define CSI_PWR_ON 1
++#define CSI_PWR_OFF 0
++#define CSI_AF_PWR_ON 1
++#define CSI_AF_PWR_OFF 0
++
++#define OV5647_ROW_START 0x01
++#define OV5647_ROW_START_MIN 0
++#define OV5647_ROW_START_MAX 2004
++#define OV5647_ROW_START_DEF 54
++
++#define OV5647_COLUMN_START 0x02
++#define OV5647_COLUMN_START_MIN 0
++#define OV5647_COLUMN_START_MAX 2750
++#define OV5647_COLUMN_START_DEF 16
++
++#define OV5647_WINDOW_HEIGHT 0x03
++#define OV5647_WINDOW_HEIGHT_MIN 2
++#define OV5647_WINDOW_HEIGHT_MAX 2006
++#define OV5647_WINDOW_HEIGHT_DEF 1944
++
++#define OV5647_WINDOW_WIDTH 0x04
++#define OV5647_WINDOW_WIDTH_MIN 2
++#define OV5647_WINDOW_WIDTH_MAX 2752
++#define OV5647_WINDOW_WIDTH_DEF 2592
++
++enum power_seq_cmd {
++ CSI_SUBDEV_PWR_OFF = 0x00,
++ CSI_SUBDEV_PWR_ON = 0x01,
++};
++
++struct sensor_format_struct {
++ __u8 *desc;
++ u32 mbus_code;
++ enum v4l2_colorspace colorspace;
++ struct regval_list *regs;
++ int regs_size;
++ int bpp;
++};
++
++struct cfg_array {
++ struct regval_list *regs;
++ int size;
++};
++
++struct sensor_win_size {
++ int width;
++ int height;
++ unsigned int hoffset;
++ unsigned int voffset;
++ unsigned int hts;
++ unsigned int vts;
++ unsigned int pclk;
++ unsigned int mipi_bps;
++ unsigned int fps_fixed;
++ unsigned int bin_factor;
++ unsigned int intg_min;
++ unsigned int intg_max;
++ void *regs;
++ int regs_size;
++ int (*set_size)(struct v4l2_subdev *subdev);
++};
++
++struct ov5647 {
++ struct device *dev;
++ struct v4l2_subdev subdev;
++ struct media_pad pad;
++ struct mutex lock;
++ struct v4l2_mbus_framefmt format;
++ struct sensor_format_struct *fmt;
++ unsigned int width;
++ unsigned int height;
++ unsigned int capture_mode;
++ int hue;
++ struct v4l2_fract tpf;
++ struct sensor_win_size *current_wins;
++};
++
++static inline struct ov5647 *to_state(struct v4l2_subdev *subdev)
++{
++ return container_of(subdev, struct ov5647, subdev);
++}
++
++static struct sensor_format_struct sensor_formats[] = {
++ {
++ .mbus_code = OV5647_CODE,
++ .colorspace = V4L2_COLORSPACE_JPEG,
++ },
++};
++#define N_FMTS ARRAY_SIZE(sensor_formats)
++
++static int ov5647_write(struct v4l2_subdev *sd, uint16_t reg, uint8_t val)
++{
++ int ret;
++ unsigned char data[3] = { reg >> 8, reg & 0xff, val};
++ struct i2c_client *client = v4l2_get_subdevdata(sd);
++
++ ret = i2c_master_send(client, data, 3);
++ if (ret < 3) {
++ printk( "%s: i2c write error, reg: %x, %d\n",
++ __func__, reg, ret);
++ return ret < 0 ? ret : -EIO;
++ }
++
++ return 0;
++}
++
++static int ov5647_read(struct v4l2_subdev *sd, uint16_t reg, uint8_t *val)
++{
++ int ret;
++ unsigned char data_w[2] = { reg >> 8, reg & 0xff };
++ struct i2c_client *client = v4l2_get_subdevdata(sd);
++
++
++ ret = i2c_master_send(client, data_w, 2);
++
++ if (ret < 2) {
++ printk("%s: i2c read error, reg: %x\n",
++ __func__, reg);
++ return ret < 0 ? ret : -EIO;
++ }
++
++ ret = i2c_master_recv(client, val, 1);
++
++ if (ret < 1) {
++ printk("%s: i2c read error, reg: %x\n",
++ __func__, reg);
++ return ret < 0 ? ret : -EIO;
++ }
++
++ return 0;
++}
++
++static int ov5647_write_array(struct v4l2_subdev *subdev,
++ struct regval_list *regs, int array_size)
++{
++ int i = 0;
++ int ret = 0;
++
++ if (!regs)
++ return -EINVAL;
++
++ while (i < array_size) {
++ if (regs->addr == REG_DLY)
++ mdelay(regs->data);
++ else
++ ret = ov5647_write(subdev, regs->addr, regs->data);
++
++ if (ret == -EIO)
++ return ret;
++
++ i++;
++ regs++;
++ }
++ return 0;
++}
++
++static void ov5647_set_virtual_channel(struct v4l2_subdev *subdev, int channel)
++{
++#if 0
++ u8 channel_id;
++
++ ov5647_read(subdev, 0x4814, &channel_id);
++// channel_id = 0x1e; //override
++
++ channel_id &= ~(3 << 6);
++ channel_id |= (channel << 6);
++ printk("0x4814 = 0x%02x\n", channel_id);
++ ov5647_write(subdev, 0x4814, channel_id);
++ ov5647_write(subdev, 0x4801, 0x8f);
++#endif
++}
++
++void ov5647_stream_on(struct v4l2_subdev *subdev)
++{
++ ov5647_write(subdev, 0x4202, 0x00);
++ ov5647_write(subdev, 0x300D, 0x00);
++}
++
++void ov5647_stream_off(struct v4l2_subdev *subdev)
++{
++ ov5647_write(subdev, 0x4202, 0x0f);
++ ov5647_write(subdev, 0x300D, 0x01);
++}
++
++static int sensor_s_sw_stby(struct v4l2_subdev *subdev, int on_off)
++{
++ int ret;
++ unsigned char rdval;
++
++ ret = ov5647_read(subdev, 0x0100, &rdval);
++ if (ret != 0)
++ return ret;
++
++ if (on_off == CSI_STBY_ON)
++ ret = ov5647_write(subdev, 0x0100, rdval&0xfe);
++ else
++ ret = ov5647_write(subdev, 0x0100, rdval|0x01);
++
++ return ret;
++}
++
++static int __sensor_init(struct v4l2_subdev *subdev)
++{
++ int ret;
++ unsigned char rdval;
++
++ ret = ov5647_read(subdev, 0x0100, &rdval);
++ if (ret != 0)
++ return ret;
++
++ ov5647_write(subdev, 0x4800, 0x25);
++ ov5647_stream_off(subdev);
++
++ ov5647_write(subdev, 0x100, 0);
++ /* reset */
++ ov5647_write(subdev, 0x103, 1);
++ ov5647_write(subdev, 0x103, 1);
++ ov5647_write(subdev, 0x103, 1);
++ mdelay(10);
++
++ ret = ov5647_write_array(subdev, ov5647_recommend_settings,
++ ARRAY_SIZE(ov5647_recommend_settings));
++#if 1
++ ret = ov5647_write_array(subdev, ov5647_snap_settings,
++ ARRAY_SIZE(ov5647_snap_settings));
++#else
++ ret = ov5647_write_array(subdev, ov5647_prev_settings,
++ ARRAY_SIZE(ov5647_prev_settings));
++#endif
++ ov5647_set_virtual_channel(subdev, 0);
++
++ ov5647_write(subdev, 0x0100, 0x01);
++
++ ov5647_write(subdev, 0x04800, 0x04);
++ ov5647_stream_on(subdev);
++ msleep(30);
++
++ return 0;
++}
++
++static int sensor_power(struct v4l2_subdev *subdev, int on)
++{
++ int ret = 0;
++ struct ov5647 *ov5647 = to_state(subdev);
++
++ mutex_lock(&ov5647->lock);
++
++ switch (on) {
++ case CSI_SUBDEV_PWR_OFF:
++ ret = sensor_s_sw_stby(subdev, CSI_STBY_ON);
++ if (ret < 0)
++ printk("soft stby failed!\n");
++ break;
++ case CSI_SUBDEV_PWR_ON:
++ ret = __sensor_init(subdev);
++ if (ret < 0) {
++ v4l2_err(subdev, "Camera not available, check power\n");
++ break;
++ }
++ break;
++ default:
++ return -EINVAL;
++ }
++
++ mutex_unlock(&ov5647->lock);
++
++ return 0;
++}
++
++#ifdef CONFIG_VIDEO_ADV_DEBUG
++static int sensor_get_register(struct v4l2_subdev *subdev,
++ struct v4l2_dbg_register *reg)
++{
++ u8 val = 0;
++ int ret;
++
++ ret = ov5647_read(subdev, (u16)reg->reg, &val);
++ if (ret < 0)
++ return ret;
++
++ reg->val = val;
++ reg->size = sizeof(u8);
++
++ return ret;
++}
++
++static int sensor_set_register(struct v4l2_subdev *subdev,
++ const struct v4l2_dbg_register *reg)
++{
++ ov5647_write(subdev, (u16)reg->reg, (u8)reg->val);
++
++ return 0;
++}
++#endif
++
++static const struct v4l2_subdev_core_ops sensor_core_ops = {
++ .s_power = sensor_power,
++#ifdef CONFIG_VIDEO_ADV_DEBUG
++ .g_register = sensor_get_register,
++ .s_register = sensor_set_register,
++#endif
++};
++
++static int sensor_s_stream(struct v4l2_subdev *sd, int enable)
++{
++ if (enable)
++ ov5647_stream_on(sd);
++ else
++ ov5647_stream_off(sd);
++
++ return 0;
++}
++
++static int sensor_enum_fmt(struct v4l2_subdev *sd,
++ struct v4l2_subdev_pad_config *cfg,
++ struct v4l2_subdev_mbus_code_enum *code)
++{
++ if (code->pad || code->index >= N_FMTS)
++ return -EINVAL;
++
++ code->code = OV5647_CODE;
++
++ return 0;
++}
++
++static int sensor_try_fmt_internal(struct v4l2_subdev *subdev,
++ struct v4l2_mbus_framefmt *fmt,
++ struct sensor_format_struct **ret_fmt,
++ struct sensor_win_size **ret_wsize)
++{
++ int index;
++
++ for (index = 0; index < N_FMTS; index++)
++ if (sensor_formats[index].mbus_code == fmt->code)
++ break;
++
++ if (index >= N_FMTS)
++ return -EINVAL;
++
++ if (ret_fmt != NULL)
++ *ret_fmt = sensor_formats + index;
++
++ fmt->field = V4L2_FIELD_NONE;
++
++ return 0;
++}
++
++static int sensor_s_fmt(struct v4l2_subdev *subdev,
++ struct v4l2_subdev_pad_config *cfg,
++ struct v4l2_subdev_format *fmt)
++{
++ int ret;
++ struct sensor_format_struct *sensor_fmt;
++ struct sensor_win_size *wsize = NULL;
++ struct ov5647 *info = to_state(subdev);
++
++ ret = sensor_try_fmt_internal(subdev, &fmt->format,
++ &sensor_fmt, &wsize);
++ if (ret)
++ return ret;
++
++ info->fmt = sensor_fmt;
++ info->width = OV5647_WIDTH;
++ info->height = OV5647_HEIGHT;
++
++ return 0;
++}
++
++static int sensor_g_fmt(struct v4l2_subdev *sd,
++ struct v4l2_subdev_pad_config *cfg,
++ struct v4l2_subdev_format *format)
++{
++ struct ov5647 *info = to_state(sd);
++ struct v4l2_mbus_framefmt *mf = &format->format;
++
++ if (format->pad != 0)
++ return -EINVAL;
++
++ mf->width = OV5647_WIDTH;
++ mf->height = OV5647_HEIGHT;
++ mf->code = OV5647_CODE;
++ mf->colorspace = info->fmt->colorspace;
++ mf->field = V4L2_FIELD_NONE;
++
++ return 0;
++}
++
++static int sensor_s_parm(struct v4l2_subdev *subdev,
++ struct v4l2_streamparm *parms)
++{
++ struct v4l2_captureparm *cp = &parms->parm.capture;
++ struct ov5647 *info = to_state(subdev);
++
++ if (parms->type != V4L2_BUF_TYPE_VIDEO_CAPTURE)
++ return -EINVAL;
++
++ if (info->tpf.numerator == 0)
++ return -EINVAL;
++
++ info->capture_mode = cp->capturemode;
++
++ return 0;
++}
++
++static int sensor_g_parm(struct v4l2_subdev *subdev,
++ struct v4l2_streamparm *parms)
++{
++ struct v4l2_captureparm *cp = &parms->parm.capture;
++ struct ov5647 *info = to_state(subdev);
++
++ if (parms->type != V4L2_BUF_TYPE_VIDEO_CAPTURE)
++ return -EINVAL;
++
++ memset(cp, 0, sizeof(struct v4l2_captureparm));
++ cp->capability = V4L2_CAP_TIMEPERFRAME;
++ cp->capturemode = info->capture_mode;
++
++ return 0;
++}
++
++static int sensor_g_mbus_config(struct v4l2_subdev *sd,
++ struct v4l2_mbus_config *cfg)
++{
++ cfg->flags = V4L2_MBUS_CSI2_1_LANE | V4L2_MBUS_CSI2_CHANNEL_0 |
++ V4L2_MBUS_CSI2_CONTINUOUS_CLOCK;
++ cfg->type = V4L2_MBUS_CSI2;
++
++ return 0;
++}
++
++static const struct v4l2_subdev_pad_ops sensor_pad_ops = {
++ .enum_mbus_code = sensor_enum_fmt,
++ .set_fmt = sensor_s_fmt,
++ .get_fmt = sensor_g_fmt,
++};
++
++static const struct v4l2_subdev_video_ops sensor_video_ops = {
++ .s_stream = sensor_s_stream,
++ .s_parm = sensor_s_parm,
++ .g_parm = sensor_g_parm,
++ .g_mbus_config = sensor_g_mbus_config,
++};
++
++static const struct v4l2_subdev_ops subdev_ops = {
++ .core = &sensor_core_ops,
++ .video = &sensor_video_ops,
++ .pad = &sensor_pad_ops,
++};
++
++static int ov5647_detect(struct v4l2_subdev *sd)
++{
++ struct i2c_client *client = v4l2_get_subdevdata(sd);
++ unsigned char id_h, id_l;
++ int ret;
++
++ ret = sensor_power(sd, 1);
++ if (ret < 0)
++ return ret;
++
++ ret = ov5647_read(sd, OV5647_REG_CHIPID_H, &id_h);
++ if (ret < 0)
++ return ret;
++ ret = ov5647_read(sd, OV5647_REG_CHIPID_L, &id_l);
++ if (ret < 0)
++ return ret;
++
++ if ((id_h != 0x56) || (id_l != 0x47)) {
++ v4l2_info(sd, "Invalid device ID: %02x%02x\n", id_h, id_l);
++ return -ENODEV;
++ }
++
++ v4l2_info(sd, "OV5647 detected at address 0x%02x\n", client->addr);
++
++ ret = sensor_power(sd, 0);
++ if (ret < 0)
++ return ret;
++
++ return 0;
++}
++
++static int ov5647_registered(struct v4l2_subdev *subdev)
++{
++ return 0;
++}
++
++static int ov5647_open(struct v4l2_subdev *subdev, struct v4l2_subdev_fh *fh)
++{
++ struct v4l2_mbus_framefmt *format =
++ v4l2_subdev_get_try_format(subdev, fh->pad, 0);
++ struct v4l2_rect *crop =
++ v4l2_subdev_get_try_crop(subdev, fh->pad, 0);
++
++ crop->left = 0;
++ crop->top = 0;
++ crop->width = OV5647_WIDTH;
++ crop->height = OV5647_HEIGHT;
++
++ format->code = OV5647_CODE;
++
++ format->width = OV5647_WIDTH;
++ format->height = OV5647_HEIGHT;
++ format->field = V4L2_FIELD_NONE;
++ format->colorspace = sensor_formats[0].colorspace;
++
++ return sensor_power(subdev, 1);
++}
++
++static int ov5647_close(struct v4l2_subdev *subdev, struct v4l2_subdev_fh *fh)
++{
++ return sensor_power(subdev, 0);
++}
++
++static const struct v4l2_subdev_internal_ops ov5647_subdev_internal_ops = {
++ .registered = ov5647_registered,
++ .open = ov5647_open,
++ .close = ov5647_close,
++};
++
++static int ov5647_probe(struct i2c_client *client,
++ const struct i2c_device_id *id)
++{
++ struct device *dev = &client->dev;
++ struct ov5647 *sensor;
++ int ret = 0;
++ struct v4l2_subdev *sd;
++
++ sensor = devm_kzalloc(dev, sizeof(*sensor), GFP_KERNEL);
++ if (sensor == NULL)
++ return -ENOMEM;
++
++ mutex_init(&sensor->lock);
++ sensor->dev = dev;
++ sensor->fmt = &sensor_formats[0];
++ sensor->width = OV5647_WIDTH;
++ sensor->height = OV5647_HEIGHT;
++
++ sd = &sensor->subdev;
++ v4l2_i2c_subdev_init(sd, client, &subdev_ops);
++ sensor->subdev.flags |= V4L2_SUBDEV_FL_HAS_DEVNODE;
++
++ ret = ov5647_detect(sd);
++ if (ret < 0) {
++ v4l2_err(sd, "OV5647 not found!\n");
++ goto out;
++ }
++
++ sensor->pad.flags = MEDIA_PAD_FL_SOURCE;
++ sd->entity.function = MEDIA_ENT_F_CAM_SENSOR;
++ ret = media_entity_pads_init(&sd->entity, 1, &sensor->pad);
++ if (ret < 0)
++ return ret;
++
++ ret = v4l2_async_register_subdev(sd);
++ if (ret < 0)
++ media_entity_cleanup(&sd->entity);
++
++out:
++ return ret;
++}
++
++static int ov5647_remove(struct i2c_client *client)
++{
++ struct v4l2_subdev *subdev = i2c_get_clientdata(client);
++ struct ov5647 *ov5647 = to_state(subdev);
++
++ v4l2_async_unregister_subdev(&ov5647->subdev);
++ media_entity_cleanup(&ov5647->subdev.entity);
++ v4l2_device_unregister_subdev(subdev);
++
++ return 0;
++}
++
++static const struct i2c_device_id ov5647_id[] = {
++ { "ov5647", 0 },
++ { }
++};
++MODULE_DEVICE_TABLE(i2c, ov5647_id);
++
++#if IS_ENABLED(CONFIG_OF)
++static const struct of_device_id ov5647_of_match[] = {
++ { .compatible = "ovti,ov5647" },
++ { /* sentinel */ },
++};
++MODULE_DEVICE_TABLE(of, ov5647_of_match);
++#endif
++
++static struct i2c_driver ov5647_driver = {
++ .driver = {
++ .of_match_table = of_match_ptr(ov5647_of_match),
++ .owner = THIS_MODULE,
++ .name = "ov5647",
++ },
++ .probe = ov5647_probe,
++ .remove = ov5647_remove,
++ .id_table = ov5647_id,
++};
++module_i2c_driver(ov5647_driver);
++
++MODULE_AUTHOR("Ramiro Oliveira <roliveir@synopsys.com>");
++MODULE_DESCRIPTION("A low-level driver for OmniVision ov5647 sensors");
++MODULE_LICENSE("GPL");
+diff --git a/drivers/media/i2c/soc_camera/ov5647.h b/drivers/media/i2c/soc_camera/ov5647.h
+new file mode 100644
+index 0000000..f854da8
+--- /dev/null
++++ b/drivers/media/i2c/soc_camera/ov5647.h
+@@ -0,0 +1,242 @@
++/*
++ * Copyright (c) 2012, The Linux Foundation. All rights reserved.
++ * Copyright (C) 2017 Cogent Embedded, Inc
++ *
++ * This program is free software; you can redistribute it and/or modify
++ * it under the terms of the GNU General Public License version 2 and
++ * only version 2 as published by the Free Software Foundation.
++ *
++ * This program is distributed in the hope that it will be useful,
++ * but WITHOUT ANY WARRANTY; without even the implied warranty of
++ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
++ * GNU General Public License for more details.
++ */
++
++//#define TEST_PATTERN
++
++#define OV5647_WIDTH 2592
++#define OV5647_HEIGHT 1944
++
++#define OV5647_CODE MEDIA_BUS_FMT_SBGGR8_1X8
++//#define OV5647_CODE MEDIA_BUS_FMT_YUYV8_2X8
++
++struct regval_list {
++ uint16_t addr;
++ uint8_t data;
++};
++
++enum ov5647_test_mode_t {
++ TEST_OFF,
++ TEST_1,
++ TEST_2,
++ TEST_3
++};
++
++struct regval_list ov5647_prev_settings[] = {
++ /*1280*960 Reference Setting 24M MCLK 2lane 280Mbps/lane 30fps
++ for back to preview*/
++ {0x3035, 0x21},
++ {0x3036, 0x37},
++ {0x3821, 0x07},
++ {0x3820, 0x41},
++ {0x3612, 0x09},
++ {0x3618, 0x00},
++ {0x380c, 0x07},
++ {0x380d, 0x68},
++ {0x380e, 0x03},
++ {0x380f, 0xd8},
++ {0x3814, 0x31},
++ {0x3815, 0x31},
++ {0x3709, 0x52},
++ {0x3808, 0x05}, // 1280
++ {0x3809, 0x00},
++ {0x380a, 0x03}, // 960
++ {0x380b, 0xc0},
++ {0x3800, 0x00},
++ {0x3801, 0x18},
++ {0x3802, 0x00},
++ {0x3803, 0x0e},
++ {0x3804, 0x0a},
++ {0x3805, 0x27},
++ {0x3806, 0x07},
++ {0x3807, 0x95},
++ {0x4004, 0x02},
++};
++struct regval_list ov5647_snap_settings[] = {
++ /*2608*1952 Reference Setting 24M MCLK 2lane 280Mbps/lane 30fps*/
++ {0x3035, 0x21},
++ {0x3036, 0x4f},
++ {0x3821, 0x06},
++ {0x3820, 0x00},
++ {0x3612, 0x0b},
++ {0x3618, 0x04},
++ {0x380c, 0x0a},
++ {0x380d, 0x8c},
++ {0x380e, 0x07},
++ {0x380f, 0xb0},
++ {0x3814, 0x11},
++ {0x3815, 0x11},
++ {0x3709, 0x12},
++#if 0
++ {0x3808, 0x0a},
++ {0x3809, 0x30},
++ {0x380a, 0x07},
++ {0x380b, 0xa0},
++#else
++ {0x3808, OV5647_WIDTH >> 8},
++ {0x3809, OV5647_WIDTH & 0xff},
++ {0x380a, OV5647_HEIGHT >> 8},
++ {0x380b, OV5647_HEIGHT & 0xff},
++#endif
++ {0x3800, 0x00},
++ {0x3801, 0x04},
++ {0x3802, 0x00},
++ {0x3803, 0x00},
++ {0x3804, 0x0a},
++ {0x3805, 0x3b},
++ {0x3806, 0x07},
++ {0x3807, 0xa3},
++ {0x4004, 0x04},
++};
++struct regval_list ov5647_recommend_settings[] = {
++#ifdef TEST_PATTERN
++ {0x503d, 0x80},
++#endif
++#if 0
++ {0x4814, 0x1e},
++ {0x4801, 0x8f},
++#endif
++ {0x3035, 0x11},
++ {0x303c, 0x11},
++ {0x370c, 0x03},
++ {0x5000, 0x06},
++ {0x5003, 0x08},
++ {0x5a00, 0x08},
++ {0x3000, 0xff},
++ {0x3001, 0xff},
++ {0x3002, 0xff},
++ {0x301d, 0xf0},
++ {0x3a18, 0x00},
++ {0x3a19, 0xf8},
++ {0x3c01, 0x80},
++ {0x3b07, 0x0c},
++ {0x3708, 0x64},
++ {0x3630, 0x2e},
++ {0x3632, 0xe2},
++ {0x3633, 0x23},
++ {0x3634, 0x44},
++ {0x3620, 0x64},
++ {0x3621, 0xe0},
++ {0x3600, 0x37},
++ {0x3704, 0xa0},
++ {0x3703, 0x5a},
++ {0x3715, 0x78},
++ {0x3717, 0x01},
++ {0x3731, 0x02},
++ {0x370b, 0x60},
++ {0x3705, 0x1a},
++ {0x3f05, 0x02},
++ {0x3f06, 0x10},
++ {0x3f01, 0x0a},
++ {0x3a08, 0x01},
++ {0x3a0f, 0x58},
++ {0x3a10, 0x50},
++ {0x3a1b, 0x58},
++ {0x3a1e, 0x50},
++ {0x3a11, 0x60},
++ {0x3a1f, 0x28},
++ {0x4001, 0x02},
++ {0x4000, 0x09},
++ {0x3000, 0x00},
++ {0x3001, 0x00},
++ {0x3002, 0x00},
++ {0x3017, 0xe0},
++ {0x301c, 0xfc},
++ {0x3636, 0x06},
++ {0x3016, 0x08},
++ {0x3827, 0xec},
++ {0x3018, 0x44},
++ {0x3035, 0x21},
++ {0x3106, 0xf5},
++ {0x3034, 0x18},
++ {0x301c, 0xf8},
++ /*lens setting*/
++ {0x5000, 0x86},
++ {0x5800, 0x11},
++ {0x5801, 0x0c},
++ {0x5802, 0x0a},
++ {0x5803, 0x0b},
++ {0x5804, 0x0d},
++ {0x5805, 0x13},
++ {0x5806, 0x09},
++ {0x5807, 0x05},
++ {0x5808, 0x03},
++ {0x5809, 0x03},
++ {0x580a, 0x06},
++ {0x580b, 0x08},
++ {0x580c, 0x05},
++ {0x580d, 0x01},
++ {0x580e, 0x00},
++ {0x580f, 0x00},
++ {0x5810, 0x02},
++ {0x5811, 0x06},
++ {0x5812, 0x05},
++ {0x5813, 0x01},
++ {0x5814, 0x00},
++ {0x5815, 0x00},
++ {0x5816, 0x02},
++ {0x5817, 0x06},
++ {0x5818, 0x09},
++ {0x5819, 0x05},
++ {0x581a, 0x04},
++ {0x581b, 0x04},
++ {0x581c, 0x06},
++ {0x581d, 0x09},
++ {0x581e, 0x11},
++ {0x581f, 0x0c},
++ {0x5820, 0x0b},
++ {0x5821, 0x0b},
++ {0x5822, 0x0d},
++ {0x5823, 0x13},
++ {0x5824, 0x22},
++ {0x5825, 0x26},
++ {0x5826, 0x26},
++ {0x5827, 0x24},
++ {0x5828, 0x24},
++ {0x5829, 0x24},
++ {0x582a, 0x22},
++ {0x582b, 0x20},
++ {0x582c, 0x22},
++ {0x582d, 0x26},
++ {0x582e, 0x22},
++ {0x582f, 0x22},
++ {0x5830, 0x42},
++ {0x5831, 0x22},
++ {0x5832, 0x02},
++ {0x5833, 0x24},
++ {0x5834, 0x22},
++ {0x5835, 0x22},
++ {0x5836, 0x22},
++ {0x5837, 0x26},
++ {0x5838, 0x42},
++ {0x5839, 0x26},
++ {0x583a, 0x06},
++ {0x583b, 0x26},
++ {0x583c, 0x24},
++ {0x583d, 0xce},
++ /* manual AWB,manual AE,close Lenc,open WBC*/
++ {0x3503, 0x03}, /*manual AE*/
++ {0x3501, 0x10},
++ {0x3502, 0x80},
++ {0x350a, 0x00},
++ {0x350b, 0x7f},
++ {0x5001, 0x01}, /*manual AWB*/
++ {0x5180, 0x08},
++ {0x5186, 0x04},
++ {0x5187, 0x00},
++ {0x5188, 0x04},
++ {0x5189, 0x00},
++ {0x518a, 0x04},
++ {0x518b, 0x00},
++ {0x5000, 0x06}, /*No lenc,WBC on*/
++};
+--
+2.7.4
+
diff --git a/bsp/meta-rcar/meta-rcar-gen3-adas/recipes-kernel/linux/linux-renesas/0032-media-i2c-Add-ov5642-sensor.patch b/bsp/meta-rcar/meta-rcar-gen3-adas/recipes-kernel/linux/linux-renesas/0032-media-i2c-Add-ov5642-sensor.patch
new file mode 100644
index 00000000..8a1b53f7
--- /dev/null
+++ b/bsp/meta-rcar/meta-rcar-gen3-adas/recipes-kernel/linux/linux-renesas/0032-media-i2c-Add-ov5642-sensor.patch
@@ -0,0 +1,2155 @@
+From 989c2131d4bae27c2866d47206e2825cfd039778 Mon Sep 17 00:00:00 2001
+From: Vladimir Barinov <vladimir.barinov@cogentembedded.com>
+Date: Sun, 11 Jun 2017 00:50:59 +0300
+Subject: [PATCH 024/122] media: i2c: ov5642 sensor
+
+Add ov5642 camera sensor driver update
+
+Signed-off-by: Vladimir Barinov <vladimir.barinov@cogentembedded.com>
+---
+ drivers/media/i2c/soc_camera/ov5642.c | 699 +++++-----------------------
+ drivers/media/i2c/soc_camera/ov5642.h | 592 ++++++++++++++++++++++++
+ drivers/media/i2c/soc_camera/ov5642_720p.h | 711 +++++++++++++++++++++++++++++
+ 3 files changed, 1409 insertions(+), 593 deletions(-)
+ create mode 100644 drivers/media/i2c/soc_camera/ov5642.h
+ create mode 100644 drivers/media/i2c/soc_camera/ov5642_720p.h
+
+diff --git a/drivers/media/i2c/soc_camera/ov5642.c b/drivers/media/i2c/soc_camera/ov5642.c
+index 39f420d..3fa4756 100644
+--- a/drivers/media/i2c/soc_camera/ov5642.c
++++ b/drivers/media/i2c/soc_camera/ov5642.c
+@@ -22,584 +22,16 @@
+ #include <linux/videodev2.h>
+ #include <linux/module.h>
+ #include <linux/v4l2-mediabus.h>
++#include <linux/gpio.h>
++#include <linux/gpio/consumer.h>
++#include <linux/of_gpio.h>
+
+ #include <media/soc_camera.h>
+ #include <media/v4l2-clk.h>
+ #include <media/v4l2-subdev.h>
+
+-/* OV5642 registers */
+-#define REG_CHIP_ID_HIGH 0x300a
+-#define REG_CHIP_ID_LOW 0x300b
+-
+-#define REG_WINDOW_START_X_HIGH 0x3800
+-#define REG_WINDOW_START_X_LOW 0x3801
+-#define REG_WINDOW_START_Y_HIGH 0x3802
+-#define REG_WINDOW_START_Y_LOW 0x3803
+-#define REG_WINDOW_WIDTH_HIGH 0x3804
+-#define REG_WINDOW_WIDTH_LOW 0x3805
+-#define REG_WINDOW_HEIGHT_HIGH 0x3806
+-#define REG_WINDOW_HEIGHT_LOW 0x3807
+-#define REG_OUT_WIDTH_HIGH 0x3808
+-#define REG_OUT_WIDTH_LOW 0x3809
+-#define REG_OUT_HEIGHT_HIGH 0x380a
+-#define REG_OUT_HEIGHT_LOW 0x380b
+-#define REG_OUT_TOTAL_WIDTH_HIGH 0x380c
+-#define REG_OUT_TOTAL_WIDTH_LOW 0x380d
+-#define REG_OUT_TOTAL_HEIGHT_HIGH 0x380e
+-#define REG_OUT_TOTAL_HEIGHT_LOW 0x380f
+-#define REG_OUTPUT_FORMAT 0x4300
+-#define REG_ISP_CTRL_01 0x5001
+-#define REG_AVG_WINDOW_END_X_HIGH 0x5682
+-#define REG_AVG_WINDOW_END_X_LOW 0x5683
+-#define REG_AVG_WINDOW_END_Y_HIGH 0x5686
+-#define REG_AVG_WINDOW_END_Y_LOW 0x5687
+-
+-/* active pixel array size */
+-#define OV5642_SENSOR_SIZE_X 2592
+-#define OV5642_SENSOR_SIZE_Y 1944
+-
+-/*
+- * About OV5642 resolution, cropping and binning:
+- * This sensor supports it all, at least in the feature description.
+- * Unfortunately, no combination of appropriate registers settings could make
+- * the chip work the intended way. As it works with predefined register lists,
+- * some undocumented registers are presumably changed there to achieve their
+- * goals.
+- * This driver currently only works for resolutions up to 720 lines with a
+- * 1:1 scale. Hopefully these restrictions will be removed in the future.
+- */
+-#define OV5642_MAX_WIDTH OV5642_SENSOR_SIZE_X
+-#define OV5642_MAX_HEIGHT 720
+-
+-/* default sizes */
+-#define OV5642_DEFAULT_WIDTH 1280
+-#define OV5642_DEFAULT_HEIGHT OV5642_MAX_HEIGHT
+-
+-/* minimum extra blanking */
+-#define BLANKING_EXTRA_WIDTH 500
+-#define BLANKING_EXTRA_HEIGHT 20
+-
+-/*
+- * the sensor's autoexposure is buggy when setting total_height low.
+- * It tries to expose longer than 1 frame period without taking care of it
+- * and this leads to weird output. So we set 1000 lines as minimum.
+- */
+-#define BLANKING_MIN_HEIGHT 1000
+-
+-struct regval_list {
+- u16 reg_num;
+- u8 value;
+-};
+-
+-static struct regval_list ov5642_default_regs_init[] = {
+- { 0x3103, 0x93 },
+- { 0x3008, 0x82 },
+- { 0x3017, 0x7f },
+- { 0x3018, 0xfc },
+- { 0x3810, 0xc2 },
+- { 0x3615, 0xf0 },
+- { 0x3000, 0x0 },
+- { 0x3001, 0x0 },
+- { 0x3002, 0x0 },
+- { 0x3003, 0x0 },
+- { 0x3004, 0xff },
+- { 0x3030, 0x2b },
+- { 0x3011, 0x8 },
+- { 0x3010, 0x10 },
+- { 0x3604, 0x60 },
+- { 0x3622, 0x60 },
+- { 0x3621, 0x9 },
+- { 0x3709, 0x0 },
+- { 0x4000, 0x21 },
+- { 0x401d, 0x22 },
+- { 0x3600, 0x54 },
+- { 0x3605, 0x4 },
+- { 0x3606, 0x3f },
+- { 0x3c01, 0x80 },
+- { 0x300d, 0x22 },
+- { 0x3623, 0x22 },
+- { 0x5000, 0x4f },
+- { 0x5020, 0x4 },
+- { 0x5181, 0x79 },
+- { 0x5182, 0x0 },
+- { 0x5185, 0x22 },
+- { 0x5197, 0x1 },
+- { 0x5500, 0xa },
+- { 0x5504, 0x0 },
+- { 0x5505, 0x7f },
+- { 0x5080, 0x8 },
+- { 0x300e, 0x18 },
+- { 0x4610, 0x0 },
+- { 0x471d, 0x5 },
+- { 0x4708, 0x6 },
+- { 0x370c, 0xa0 },
+- { 0x5687, 0x94 },
+- { 0x501f, 0x0 },
+- { 0x5000, 0x4f },
+- { 0x5001, 0xcf },
+- { 0x4300, 0x30 },
+- { 0x4300, 0x30 },
+- { 0x460b, 0x35 },
+- { 0x471d, 0x0 },
+- { 0x3002, 0xc },
+- { 0x3002, 0x0 },
+- { 0x4713, 0x3 },
+- { 0x471c, 0x50 },
+- { 0x4721, 0x2 },
+- { 0x4402, 0x90 },
+- { 0x460c, 0x22 },
+- { 0x3815, 0x44 },
+- { 0x3503, 0x7 },
+- { 0x3501, 0x73 },
+- { 0x3502, 0x80 },
+- { 0x350b, 0x0 },
+- { 0x3818, 0xc8 },
+- { 0x3824, 0x11 },
+- { 0x3a00, 0x78 },
+- { 0x3a1a, 0x4 },
+- { 0x3a13, 0x30 },
+- { 0x3a18, 0x0 },
+- { 0x3a19, 0x7c },
+- { 0x3a08, 0x12 },
+- { 0x3a09, 0xc0 },
+- { 0x3a0a, 0xf },
+- { 0x3a0b, 0xa0 },
+- { 0x350c, 0x7 },
+- { 0x350d, 0xd0 },
+- { 0x3a0d, 0x8 },
+- { 0x3a0e, 0x6 },
+- { 0x3500, 0x0 },
+- { 0x3501, 0x0 },
+- { 0x3502, 0x0 },
+- { 0x350a, 0x0 },
+- { 0x350b, 0x0 },
+- { 0x3503, 0x0 },
+- { 0x3a0f, 0x3c },
+- { 0x3a10, 0x32 },
+- { 0x3a1b, 0x3c },
+- { 0x3a1e, 0x32 },
+- { 0x3a11, 0x80 },
+- { 0x3a1f, 0x20 },
+- { 0x3030, 0x2b },
+- { 0x3a02, 0x0 },
+- { 0x3a03, 0x7d },
+- { 0x3a04, 0x0 },
+- { 0x3a14, 0x0 },
+- { 0x3a15, 0x7d },
+- { 0x3a16, 0x0 },
+- { 0x3a00, 0x78 },
+- { 0x3a08, 0x9 },
+- { 0x3a09, 0x60 },
+- { 0x3a0a, 0x7 },
+- { 0x3a0b, 0xd0 },
+- { 0x3a0d, 0x10 },
+- { 0x3a0e, 0xd },
+- { 0x4407, 0x4 },
+- { 0x5193, 0x70 },
+- { 0x589b, 0x0 },
+- { 0x589a, 0xc0 },
+- { 0x401e, 0x20 },
+- { 0x4001, 0x42 },
+- { 0x401c, 0x6 },
+- { 0x3825, 0xac },
+- { 0x3827, 0xc },
+- { 0x528a, 0x1 },
+- { 0x528b, 0x4 },
+- { 0x528c, 0x8 },
+- { 0x528d, 0x10 },
+- { 0x528e, 0x20 },
+- { 0x528f, 0x28 },
+- { 0x5290, 0x30 },
+- { 0x5292, 0x0 },
+- { 0x5293, 0x1 },
+- { 0x5294, 0x0 },
+- { 0x5295, 0x4 },
+- { 0x5296, 0x0 },
+- { 0x5297, 0x8 },
+- { 0x5298, 0x0 },
+- { 0x5299, 0x10 },
+- { 0x529a, 0x0 },
+- { 0x529b, 0x20 },
+- { 0x529c, 0x0 },
+- { 0x529d, 0x28 },
+- { 0x529e, 0x0 },
+- { 0x529f, 0x30 },
+- { 0x5282, 0x0 },
+- { 0x5300, 0x0 },
+- { 0x5301, 0x20 },
+- { 0x5302, 0x0 },
+- { 0x5303, 0x7c },
+- { 0x530c, 0x0 },
+- { 0x530d, 0xc },
+- { 0x530e, 0x20 },
+- { 0x530f, 0x80 },
+- { 0x5310, 0x20 },
+- { 0x5311, 0x80 },
+- { 0x5308, 0x20 },
+- { 0x5309, 0x40 },
+- { 0x5304, 0x0 },
+- { 0x5305, 0x30 },
+- { 0x5306, 0x0 },
+- { 0x5307, 0x80 },
+- { 0x5314, 0x8 },
+- { 0x5315, 0x20 },
+- { 0x5319, 0x30 },
+- { 0x5316, 0x10 },
+- { 0x5317, 0x0 },
+- { 0x5318, 0x2 },
+- { 0x5380, 0x1 },
+- { 0x5381, 0x0 },
+- { 0x5382, 0x0 },
+- { 0x5383, 0x4e },
+- { 0x5384, 0x0 },
+- { 0x5385, 0xf },
+- { 0x5386, 0x0 },
+- { 0x5387, 0x0 },
+- { 0x5388, 0x1 },
+- { 0x5389, 0x15 },
+- { 0x538a, 0x0 },
+- { 0x538b, 0x31 },
+- { 0x538c, 0x0 },
+- { 0x538d, 0x0 },
+- { 0x538e, 0x0 },
+- { 0x538f, 0xf },
+- { 0x5390, 0x0 },
+- { 0x5391, 0xab },
+- { 0x5392, 0x0 },
+- { 0x5393, 0xa2 },
+- { 0x5394, 0x8 },
+- { 0x5480, 0x14 },
+- { 0x5481, 0x21 },
+- { 0x5482, 0x36 },
+- { 0x5483, 0x57 },
+- { 0x5484, 0x65 },
+- { 0x5485, 0x71 },
+- { 0x5486, 0x7d },
+- { 0x5487, 0x87 },
+- { 0x5488, 0x91 },
+- { 0x5489, 0x9a },
+- { 0x548a, 0xaa },
+- { 0x548b, 0xb8 },
+- { 0x548c, 0xcd },
+- { 0x548d, 0xdd },
+- { 0x548e, 0xea },
+- { 0x548f, 0x1d },
+- { 0x5490, 0x5 },
+- { 0x5491, 0x0 },
+- { 0x5492, 0x4 },
+- { 0x5493, 0x20 },
+- { 0x5494, 0x3 },
+- { 0x5495, 0x60 },
+- { 0x5496, 0x2 },
+- { 0x5497, 0xb8 },
+- { 0x5498, 0x2 },
+- { 0x5499, 0x86 },
+- { 0x549a, 0x2 },
+- { 0x549b, 0x5b },
+- { 0x549c, 0x2 },
+- { 0x549d, 0x3b },
+- { 0x549e, 0x2 },
+- { 0x549f, 0x1c },
+- { 0x54a0, 0x2 },
+- { 0x54a1, 0x4 },
+- { 0x54a2, 0x1 },
+- { 0x54a3, 0xed },
+- { 0x54a4, 0x1 },
+- { 0x54a5, 0xc5 },
+- { 0x54a6, 0x1 },
+- { 0x54a7, 0xa5 },
+- { 0x54a8, 0x1 },
+- { 0x54a9, 0x6c },
+- { 0x54aa, 0x1 },
+- { 0x54ab, 0x41 },
+- { 0x54ac, 0x1 },
+- { 0x54ad, 0x20 },
+- { 0x54ae, 0x0 },
+- { 0x54af, 0x16 },
+- { 0x54b0, 0x1 },
+- { 0x54b1, 0x20 },
+- { 0x54b2, 0x0 },
+- { 0x54b3, 0x10 },
+- { 0x54b4, 0x0 },
+- { 0x54b5, 0xf0 },
+- { 0x54b6, 0x0 },
+- { 0x54b7, 0xdf },
+- { 0x5402, 0x3f },
+- { 0x5403, 0x0 },
+- { 0x3406, 0x0 },
+- { 0x5180, 0xff },
+- { 0x5181, 0x52 },
+- { 0x5182, 0x11 },
+- { 0x5183, 0x14 },
+- { 0x5184, 0x25 },
+- { 0x5185, 0x24 },
+- { 0x5186, 0x6 },
+- { 0x5187, 0x8 },
+- { 0x5188, 0x8 },
+- { 0x5189, 0x7c },
+- { 0x518a, 0x60 },
+- { 0x518b, 0xb2 },
+- { 0x518c, 0xb2 },
+- { 0x518d, 0x44 },
+- { 0x518e, 0x3d },
+- { 0x518f, 0x58 },
+- { 0x5190, 0x46 },
+- { 0x5191, 0xf8 },
+- { 0x5192, 0x4 },
+- { 0x5193, 0x70 },
+- { 0x5194, 0xf0 },
+- { 0x5195, 0xf0 },
+- { 0x5196, 0x3 },
+- { 0x5197, 0x1 },
+- { 0x5198, 0x4 },
+- { 0x5199, 0x12 },
+- { 0x519a, 0x4 },
+- { 0x519b, 0x0 },
+- { 0x519c, 0x6 },
+- { 0x519d, 0x82 },
+- { 0x519e, 0x0 },
+- { 0x5025, 0x80 },
+- { 0x3a0f, 0x38 },
+- { 0x3a10, 0x30 },
+- { 0x3a1b, 0x3a },
+- { 0x3a1e, 0x2e },
+- { 0x3a11, 0x60 },
+- { 0x3a1f, 0x10 },
+- { 0x5688, 0xa6 },
+- { 0x5689, 0x6a },
+- { 0x568a, 0xea },
+- { 0x568b, 0xae },
+- { 0x568c, 0xa6 },
+- { 0x568d, 0x6a },
+- { 0x568e, 0x62 },
+- { 0x568f, 0x26 },
+- { 0x5583, 0x40 },
+- { 0x5584, 0x40 },
+- { 0x5580, 0x2 },
+- { 0x5000, 0xcf },
+- { 0x5800, 0x27 },
+- { 0x5801, 0x19 },
+- { 0x5802, 0x12 },
+- { 0x5803, 0xf },
+- { 0x5804, 0x10 },
+- { 0x5805, 0x15 },
+- { 0x5806, 0x1e },
+- { 0x5807, 0x2f },
+- { 0x5808, 0x15 },
+- { 0x5809, 0xd },
+- { 0x580a, 0xa },
+- { 0x580b, 0x9 },
+- { 0x580c, 0xa },
+- { 0x580d, 0xc },
+- { 0x580e, 0x12 },
+- { 0x580f, 0x19 },
+- { 0x5810, 0xb },
+- { 0x5811, 0x7 },
+- { 0x5812, 0x4 },
+- { 0x5813, 0x3 },
+- { 0x5814, 0x3 },
+- { 0x5815, 0x6 },
+- { 0x5816, 0xa },
+- { 0x5817, 0xf },
+- { 0x5818, 0xa },
+- { 0x5819, 0x5 },
+- { 0x581a, 0x1 },
+- { 0x581b, 0x0 },
+- { 0x581c, 0x0 },
+- { 0x581d, 0x3 },
+- { 0x581e, 0x8 },
+- { 0x581f, 0xc },
+- { 0x5820, 0xa },
+- { 0x5821, 0x5 },
+- { 0x5822, 0x1 },
+- { 0x5823, 0x0 },
+- { 0x5824, 0x0 },
+- { 0x5825, 0x3 },
+- { 0x5826, 0x8 },
+- { 0x5827, 0xc },
+- { 0x5828, 0xe },
+- { 0x5829, 0x8 },
+- { 0x582a, 0x6 },
+- { 0x582b, 0x4 },
+- { 0x582c, 0x5 },
+- { 0x582d, 0x7 },
+- { 0x582e, 0xb },
+- { 0x582f, 0x12 },
+- { 0x5830, 0x18 },
+- { 0x5831, 0x10 },
+- { 0x5832, 0xc },
+- { 0x5833, 0xa },
+- { 0x5834, 0xb },
+- { 0x5835, 0xe },
+- { 0x5836, 0x15 },
+- { 0x5837, 0x19 },
+- { 0x5838, 0x32 },
+- { 0x5839, 0x1f },
+- { 0x583a, 0x18 },
+- { 0x583b, 0x16 },
+- { 0x583c, 0x17 },
+- { 0x583d, 0x1e },
+- { 0x583e, 0x26 },
+- { 0x583f, 0x53 },
+- { 0x5840, 0x10 },
+- { 0x5841, 0xf },
+- { 0x5842, 0xd },
+- { 0x5843, 0xc },
+- { 0x5844, 0xe },
+- { 0x5845, 0x9 },
+- { 0x5846, 0x11 },
+- { 0x5847, 0x10 },
+- { 0x5848, 0x10 },
+- { 0x5849, 0x10 },
+- { 0x584a, 0x10 },
+- { 0x584b, 0xe },
+- { 0x584c, 0x10 },
+- { 0x584d, 0x10 },
+- { 0x584e, 0x11 },
+- { 0x584f, 0x10 },
+- { 0x5850, 0xf },
+- { 0x5851, 0xc },
+- { 0x5852, 0xf },
+- { 0x5853, 0x10 },
+- { 0x5854, 0x10 },
+- { 0x5855, 0xf },
+- { 0x5856, 0xe },
+- { 0x5857, 0xb },
+- { 0x5858, 0x10 },
+- { 0x5859, 0xd },
+- { 0x585a, 0xd },
+- { 0x585b, 0xc },
+- { 0x585c, 0xc },
+- { 0x585d, 0xc },
+- { 0x585e, 0xb },
+- { 0x585f, 0xc },
+- { 0x5860, 0xc },
+- { 0x5861, 0xc },
+- { 0x5862, 0xd },
+- { 0x5863, 0x8 },
+- { 0x5864, 0x11 },
+- { 0x5865, 0x18 },
+- { 0x5866, 0x18 },
+- { 0x5867, 0x19 },
+- { 0x5868, 0x17 },
+- { 0x5869, 0x19 },
+- { 0x586a, 0x16 },
+- { 0x586b, 0x13 },
+- { 0x586c, 0x13 },
+- { 0x586d, 0x12 },
+- { 0x586e, 0x13 },
+- { 0x586f, 0x16 },
+- { 0x5870, 0x14 },
+- { 0x5871, 0x12 },
+- { 0x5872, 0x10 },
+- { 0x5873, 0x11 },
+- { 0x5874, 0x11 },
+- { 0x5875, 0x16 },
+- { 0x5876, 0x14 },
+- { 0x5877, 0x11 },
+- { 0x5878, 0x10 },
+- { 0x5879, 0xf },
+- { 0x587a, 0x10 },
+- { 0x587b, 0x14 },
+- { 0x587c, 0x13 },
+- { 0x587d, 0x12 },
+- { 0x587e, 0x11 },
+- { 0x587f, 0x11 },
+- { 0x5880, 0x12 },
+- { 0x5881, 0x15 },
+- { 0x5882, 0x14 },
+- { 0x5883, 0x15 },
+- { 0x5884, 0x15 },
+- { 0x5885, 0x15 },
+- { 0x5886, 0x13 },
+- { 0x5887, 0x17 },
+- { 0x3710, 0x10 },
+- { 0x3632, 0x51 },
+- { 0x3702, 0x10 },
+- { 0x3703, 0xb2 },
+- { 0x3704, 0x18 },
+- { 0x370b, 0x40 },
+- { 0x370d, 0x3 },
+- { 0x3631, 0x1 },
+- { 0x3632, 0x52 },
+- { 0x3606, 0x24 },
+- { 0x3620, 0x96 },
+- { 0x5785, 0x7 },
+- { 0x3a13, 0x30 },
+- { 0x3600, 0x52 },
+- { 0x3604, 0x48 },
+- { 0x3606, 0x1b },
+- { 0x370d, 0xb },
+- { 0x370f, 0xc0 },
+- { 0x3709, 0x1 },
+- { 0x3823, 0x0 },
+- { 0x5007, 0x0 },
+- { 0x5009, 0x0 },
+- { 0x5011, 0x0 },
+- { 0x5013, 0x0 },
+- { 0x519e, 0x0 },
+- { 0x5086, 0x0 },
+- { 0x5087, 0x0 },
+- { 0x5088, 0x0 },
+- { 0x5089, 0x0 },
+- { 0x302b, 0x0 },
+- { 0x3503, 0x7 },
+- { 0x3011, 0x8 },
+- { 0x350c, 0x2 },
+- { 0x350d, 0xe4 },
+- { 0x3621, 0xc9 },
+- { 0x370a, 0x81 },
+- { 0xffff, 0xff },
+-};
+-
+-static struct regval_list ov5642_default_regs_finalise[] = {
+- { 0x3810, 0xc2 },
+- { 0x3818, 0xc9 },
+- { 0x381c, 0x10 },
+- { 0x381d, 0xa0 },
+- { 0x381e, 0x5 },
+- { 0x381f, 0xb0 },
+- { 0x3820, 0x0 },
+- { 0x3821, 0x0 },
+- { 0x3824, 0x11 },
+- { 0x3a08, 0x1b },
+- { 0x3a09, 0xc0 },
+- { 0x3a0a, 0x17 },
+- { 0x3a0b, 0x20 },
+- { 0x3a0d, 0x2 },
+- { 0x3a0e, 0x1 },
+- { 0x401c, 0x4 },
+- { 0x5682, 0x5 },
+- { 0x5683, 0x0 },
+- { 0x5686, 0x2 },
+- { 0x5687, 0xcc },
+- { 0x5001, 0x4f },
+- { 0x589b, 0x6 },
+- { 0x589a, 0xc5 },
+- { 0x3503, 0x0 },
+- { 0x460c, 0x20 },
+- { 0x460b, 0x37 },
+- { 0x471c, 0xd0 },
+- { 0x471d, 0x5 },
+- { 0x3815, 0x1 },
+- { 0x3818, 0xc1 },
+- { 0x501f, 0x0 },
+- { 0x5002, 0xe0 },
+- { 0x4300, 0x32 }, /* UYVY */
+- { 0x3002, 0x1c },
+- { 0x4800, 0x14 },
+- { 0x4801, 0xf },
+- { 0x3007, 0x3b },
+- { 0x300e, 0x4 },
+- { 0x4803, 0x50 },
+- { 0x3815, 0x1 },
+- { 0x4713, 0x2 },
+- { 0x4842, 0x1 },
+- { 0x300f, 0xe },
+- { 0x3003, 0x3 },
+- { 0x3003, 0x1 },
+- { 0xffff, 0xff },
+-};
++#define USE_PREDEF
++#include "ov5642.h"
+
+ struct ov5642_datafmt {
+ u32 code;
+@@ -608,6 +40,7 @@ struct ov5642_datafmt {
+
+ struct ov5642 {
+ struct v4l2_subdev subdev;
++ struct media_pad pad;
+ const struct ov5642_datafmt *fmt;
+ struct v4l2_rect crop_rect;
+ struct v4l2_clk *clk;
+@@ -615,10 +48,14 @@ struct ov5642 {
+ /* blanking information */
+ int total_width;
+ int total_height;
++
++ struct soc_camera_subdev_desc ssdd_dt;
++ struct gpio_desc *resetb_gpio;
++ struct gpio_desc *pwdn_gpio;
+ };
+
+ static const struct ov5642_datafmt ov5642_colour_fmts[] = {
+- {MEDIA_BUS_FMT_UYVY8_2X8, V4L2_COLORSPACE_JPEG},
++ {MEDIA_BUS_FMT_YUYV8_2X8, V4L2_COLORSPACE_JPEG},
+ };
+
+ static struct ov5642 *to_ov5642(const struct i2c_client *client)
+@@ -676,10 +113,7 @@ static int reg_write(struct i2c_client *client, u16 reg, u8 val)
+ return 0;
+ }
+
+-/*
+- * convenience function to write 16 bit register values that are split up
+- * into two consecutive high and low parts
+- */
++#if 0
+ static int reg_write16(struct i2c_client *client, u16 reg, u16 val16)
+ {
+ int ret;
+@@ -689,6 +123,7 @@ static int reg_write16(struct i2c_client *client, u16 reg, u16 val16)
+ return ret;
+ return reg_write(client, reg + 1, val16 & 0x00ff);
+ }
++#endif
+
+ #ifdef CONFIG_VIDEO_ADV_DEBUG
+ static int ov5642_get_register(struct v4l2_subdev *sd, struct v4l2_dbg_register *reg)
+@@ -733,6 +168,7 @@ static int ov5642_write_array(struct i2c_client *client,
+ return 0;
+ }
+
++#ifndef USE_PREDEF
+ static int ov5642_set_resolution(struct v4l2_subdev *sd)
+ {
+ struct i2c_client *client = v4l2_get_subdevdata(sd);
+@@ -785,6 +221,7 @@ static int ov5642_set_resolution(struct v4l2_subdev *sd)
+
+ return ret;
+ }
++#endif
+
+ static int ov5642_set_fmt(struct v4l2_subdev *sd,
+ struct v4l2_subdev_pad_config *cfg,
+@@ -872,15 +309,15 @@ static int ov5642_set_selection(struct v4l2_subdev *sd,
+ priv->total_height = max_t(int, rect.height +
+ BLANKING_EXTRA_HEIGHT,
+ BLANKING_MIN_HEIGHT);
+- priv->crop_rect.width = rect.width;
+- priv->crop_rect.height = rect.height;
+-
++#ifdef USE_PREDEF
++ ret = ov5642_write_array(client, OV5642_720P_30FPS);
++#else
+ ret = ov5642_write_array(client, ov5642_default_regs_init);
+ if (!ret)
+ ret = ov5642_set_resolution(sd);
+ if (!ret)
+ ret = ov5642_write_array(client, ov5642_default_regs_finalise);
+-
++#endif
+ return ret;
+ }
+
+@@ -913,10 +350,10 @@ static int ov5642_get_selection(struct v4l2_subdev *sd,
+ static int ov5642_g_mbus_config(struct v4l2_subdev *sd,
+ struct v4l2_mbus_config *cfg)
+ {
+- cfg->type = V4L2_MBUS_CSI2;
+- cfg->flags = V4L2_MBUS_CSI2_2_LANE | V4L2_MBUS_CSI2_CHANNEL_0 |
+- V4L2_MBUS_CSI2_CONTINUOUS_CLOCK;
+-
++ cfg->type = V4L2_MBUS_PARALLEL;
++ cfg->flags = V4L2_MBUS_MASTER | V4L2_MBUS_PCLK_SAMPLE_RISING |
++ V4L2_MBUS_HSYNC_ACTIVE_LOW | V4L2_MBUS_VSYNC_ACTIVE_HIGH |
++ V4L2_MBUS_DATA_ACTIVE_HIGH;
+ return 0;
+ }
+
+@@ -934,12 +371,15 @@ static int ov5642_s_power(struct v4l2_subdev *sd, int on)
+ if (ret < 0)
+ return ret;
+
++#ifdef USE_PREDEF
++ ret = ov5642_write_array(client, OV5642_720P_30FPS);
++#else
+ ret = ov5642_write_array(client, ov5642_default_regs_init);
+ if (!ret)
+ ret = ov5642_set_resolution(sd);
+ if (!ret)
+ ret = ov5642_write_array(client, ov5642_default_regs_finalise);
+-
++#endif
+ return ret;
+ }
+
+@@ -969,6 +409,63 @@ static const struct v4l2_subdev_ops ov5642_subdev_ops = {
+ .pad = &ov5642_subdev_pad_ops,
+ };
+
++/* OF probe functions */
++static int ov5642_hw_power(struct device *dev, int on)
++{
++ struct i2c_client *client = to_i2c_client(dev);
++ struct ov5642 *priv = to_ov5642(client);
++
++ dev_dbg(&client->dev, "%s: %s the camera\n",
++ __func__, on ? "ENABLE" : "DISABLE");
++
++ if (priv->pwdn_gpio)
++ gpiod_direction_output(priv->pwdn_gpio, !on);
++
++ return 0;
++}
++
++static int ov5642_hw_reset(struct device *dev)
++{
++ struct i2c_client *client = to_i2c_client(dev);
++ struct ov5642 *priv = to_ov5642(client);
++
++ if (priv->resetb_gpio) {
++ /* Active the resetb pin to perform a reset pulse */
++ gpiod_direction_output(priv->resetb_gpio, 1);
++ usleep_range(3000, 5000);
++ gpiod_direction_output(priv->resetb_gpio, 0);
++ }
++
++ return 0;
++}
++
++static int ov5642_probe_dt(struct i2c_client *client,
++ struct ov5642 *priv)
++{
++ /* Request the reset GPIO deasserted */
++ priv->resetb_gpio = devm_gpiod_get_optional(&client->dev, "resetb",
++ GPIOD_OUT_LOW);
++ if (!priv->resetb_gpio)
++ dev_dbg(&client->dev, "resetb gpio is not assigned!\n");
++ else if (IS_ERR(priv->resetb_gpio))
++ return PTR_ERR(priv->resetb_gpio);
++
++ /* Request the power down GPIO asserted */
++ priv->pwdn_gpio = devm_gpiod_get_optional(&client->dev, "pwdn",
++ GPIOD_OUT_HIGH);
++ if (!priv->pwdn_gpio)
++ dev_dbg(&client->dev, "pwdn gpio is not assigned!\n");
++ else if (IS_ERR(priv->pwdn_gpio))
++ return PTR_ERR(priv->pwdn_gpio);
++
++ /* Initialize the soc_camera_subdev_desc */
++ priv->ssdd_dt.power = ov5642_hw_power;
++ priv->ssdd_dt.reset = ov5642_hw_reset;
++ client->dev.platform_data = &priv->ssdd_dt;
++
++ return 0;
++}
++
+ static int ov5642_video_probe(struct i2c_client *client)
+ {
+ struct v4l2_subdev *subdev = i2c_get_clientdata(client);
+@@ -1011,19 +508,23 @@ static int ov5642_probe(struct i2c_client *client,
+ const struct i2c_device_id *did)
+ {
+ struct ov5642 *priv;
++ struct v4l2_subdev *sd;
+ struct soc_camera_subdev_desc *ssdd = soc_camera_i2c_to_desc(client);
+ int ret;
+
+- if (!ssdd) {
+- dev_err(&client->dev, "OV5642: missing platform data!\n");
+- return -EINVAL;
+- }
+-
+ priv = devm_kzalloc(&client->dev, sizeof(struct ov5642), GFP_KERNEL);
+ if (!priv)
+ return -ENOMEM;
+
++ if (!ssdd) {
++ ret = ov5642_probe_dt(client, priv);
++ if (ret)
++ return ret;
++ }
++
++ sd = &priv->subdev;
+ v4l2_i2c_subdev_init(&priv->subdev, client, &ov5642_subdev_ops);
++ priv->subdev.flags |= V4L2_SUBDEV_FL_HAS_DEVNODE;
+
+ priv->fmt = &ov5642_colour_fmts[0];
+
+@@ -1039,8 +540,20 @@ static int ov5642_probe(struct i2c_client *client,
+ return PTR_ERR(priv->clk);
+
+ ret = ov5642_video_probe(client);
+- if (ret < 0)
++ if (ret < 0) {
+ v4l2_clk_put(priv->clk);
++ return ret;
++ }
++
++ priv->pad.flags = MEDIA_PAD_FL_SOURCE;
++ sd->entity.function = MEDIA_ENT_F_CAM_SENSOR;
++ ret = media_entity_pads_init(&sd->entity, 1, &priv->pad);
++ if (ret < 0)
++ return ret;
++
++ ret = v4l2_async_register_subdev(sd);
++ if (ret < 0)
++ media_entity_cleanup(&sd->entity);
+
+ return ret;
+ }
+diff --git a/drivers/media/i2c/soc_camera/ov5642.h b/drivers/media/i2c/soc_camera/ov5642.h
+new file mode 100644
+index 0000000..ac47a16
+--- /dev/null
++++ b/drivers/media/i2c/soc_camera/ov5642.h
+@@ -0,0 +1,592 @@
++#ifndef _OV5642_H_
++#define _OV5642_H_
++
++
++/* OV5642 registers */
++#define REG_CHIP_ID_HIGH 0x300a
++#define REG_CHIP_ID_LOW 0x300b
++
++#define REG_WINDOW_START_X_HIGH 0x3800
++#define REG_WINDOW_START_X_LOW 0x3801
++#define REG_WINDOW_START_Y_HIGH 0x3802
++#define REG_WINDOW_START_Y_LOW 0x3803
++#define REG_WINDOW_WIDTH_HIGH 0x3804
++#define REG_WINDOW_WIDTH_LOW 0x3805
++#define REG_WINDOW_HEIGHT_HIGH 0x3806
++#define REG_WINDOW_HEIGHT_LOW 0x3807
++#define REG_OUT_WIDTH_HIGH 0x3808
++#define REG_OUT_WIDTH_LOW 0x3809
++#define REG_OUT_HEIGHT_HIGH 0x380a
++#define REG_OUT_HEIGHT_LOW 0x380b
++#define REG_OUT_TOTAL_WIDTH_HIGH 0x380c
++#define REG_OUT_TOTAL_WIDTH_LOW 0x380d
++#define REG_OUT_TOTAL_HEIGHT_HIGH 0x380e
++#define REG_OUT_TOTAL_HEIGHT_LOW 0x380f
++#define REG_OUTPUT_FORMAT 0x4300
++#define REG_ISP_CTRL_00 0x5000
++#define REG_ISP_CTRL_01 0x5001
++#define REG_AVG_WINDOW_START_X_HIGH 0x5680
++#define REG_AVG_WINDOW_START_X_LOW 0x5681
++#define REG_AVG_WINDOW_END_X_HIGH 0x5682
++#define REG_AVG_WINDOW_END_X_LOW 0x5683
++#define REG_AVG_WINDOW_START_Y_HIGH 0x5684
++#define REG_AVG_WINDOW_START_Y_LOW 0x5685
++#define REG_AVG_WINDOW_END_Y_HIGH 0x5686
++#define REG_AVG_WINDOW_END_Y_LOW 0x5687
++
++/* active pixel array size */
++#define OV5642_SENSOR_SIZE_X 2592
++#define OV5642_SENSOR_SIZE_Y 1944
++
++/*
++ * About OV5642 resolution, cropping and binning:
++ * This sensor supports it all, at least in the feature description.
++ * Unfortunately, no combination of appropriate registers settings could make
++ * the chip work the intended way. As it works with predefined register lists,
++ * some undocumented registers are presumably changed there to achieve their
++ * goals.
++ * This driver currently only works for resolutions up to 720 lines with a
++ * 1:1 scale. Hopefully these restrictions will be removed in the future.
++ */
++#define OV5642_MAX_WIDTH OV5642_SENSOR_SIZE_X
++#define OV5642_MAX_HEIGHT 720
++
++/* default sizes */
++#define OV5642_DEFAULT_WIDTH 1280
++#define OV5642_DEFAULT_HEIGHT OV5642_MAX_HEIGHT
++
++/* minimum extra blanking */
++#define BLANKING_EXTRA_WIDTH 500
++#define BLANKING_EXTRA_HEIGHT 20
++
++/*
++ * the sensor's autoexposure is buggy when setting total_height low.
++ * It tries to expose longer than 1 frame period without taking care of it
++ * and this leads to weird output. So we set 1000 lines as minimum.
++ */
++#define BLANKING_MIN_HEIGHT 1000
++
++struct regval_list {
++ u16 reg_num;
++ u8 value;
++};
++
++#ifdef USE_PREDEF
++ #include "ov5642_720p.h"
++#endif
++
++#ifndef USE_PREDEF
++
++static struct regval_list ov5642_default_regs_init[] = {
++ { 0x3103, 0x93 },
++ { 0x3008, 0x82 },
++ { 0x3017, 0x7f },
++ { 0x3018, 0xfc },
++ { 0x3810, 0xc2 },
++ { 0x3615, 0xf0 },
++ { 0x3000, 0x0 },
++ { 0x3001, 0x0 },
++ { 0x3002, 0x0 },
++ { 0x3003, 0x0 },
++ { 0x3004, 0xff },
++ { 0x3030, 0x2b },
++ { 0x3011, 0x8 },
++ { 0x3010, 0x10 },
++ { 0x3604, 0x60 },
++ { 0x3622, 0x60 },
++ { 0x3621, 0x9 },
++ { 0x3709, 0x0 },
++ { 0x4000, 0x21 },
++ { 0x401d, 0x22 },
++ { 0x3600, 0x54 },
++ { 0x3605, 0x4 },
++ { 0x3606, 0x3f },
++ { 0x3c01, 0x80 },
++ { 0x300d, 0x22 },
++ { 0x3623, 0x22 },
++ { 0x5000, 0x4f },
++ { 0x5020, 0x4 },
++ { 0x5181, 0x79 },
++ { 0x5182, 0x0 },
++ { 0x5185, 0x22 },
++ { 0x5197, 0x1 },
++ { 0x5500, 0xa },
++ { 0x5504, 0x0 },
++ { 0x5505, 0x7f },
++ { 0x5080, 0x8 },
++ { 0x300e, 0x18 },
++ { 0x4610, 0x0 },
++ { 0x471d, 0x5 },
++ { 0x4708, 0x6 },
++ { 0x370c, 0xa0 },
++ { 0x5687, 0x94 },
++ { 0x501f, 0x0 },
++ { 0x5000, 0x4f },
++ { 0x5001, 0xcf },
++ { 0x4300, 0x30 },
++ { 0x4300, 0x30 },
++ { 0x460b, 0x35 },
++ { 0x471d, 0x0 },
++ { 0x3002, 0xc },
++ { 0x3002, 0x0 },
++ { 0x4713, 0x3 },
++ { 0x471c, 0x50 },
++ { 0x4721, 0x2 },
++ { 0x4402, 0x90 },
++ { 0x460c, 0x22 },
++ { 0x3815, 0x44 },
++ { 0x3503, 0x7 },
++ { 0x3501, 0x73 },
++ { 0x3502, 0x80 },
++ { 0x350b, 0x0 },
++ { 0x3818, 0xc8 },
++ { 0x3824, 0x11 },
++ { 0x3a00, 0x78 },
++ { 0x3a1a, 0x4 },
++ { 0x3a13, 0x30 },
++ { 0x3a18, 0x0 },
++ { 0x3a19, 0x7c },
++ { 0x3a08, 0x12 },
++ { 0x3a09, 0xc0 },
++ { 0x3a0a, 0xf },
++ { 0x3a0b, 0xa0 },
++ { 0x350c, 0x7 },
++ { 0x350d, 0xd0 },
++ { 0x3a0d, 0x8 },
++ { 0x3a0e, 0x6 },
++ { 0x3500, 0x0 },
++ { 0x3501, 0x0 },
++ { 0x3502, 0x0 },
++ { 0x350a, 0x0 },
++ { 0x350b, 0x0 },
++ { 0x3503, 0x0 },
++ { 0x3a0f, 0x3c },
++ { 0x3a10, 0x32 },
++ { 0x3a1b, 0x3c },
++ { 0x3a1e, 0x32 },
++ { 0x3a11, 0x80 },
++ { 0x3a1f, 0x20 },
++ { 0x3030, 0x2b },
++ { 0x3a02, 0x0 },
++ { 0x3a03, 0x7d },
++ { 0x3a04, 0x0 },
++ { 0x3a14, 0x0 },
++ { 0x3a15, 0x7d },
++ { 0x3a16, 0x0 },
++ { 0x3a00, 0x78 },
++ { 0x3a08, 0x9 },
++ { 0x3a09, 0x60 },
++ { 0x3a0a, 0x7 },
++ { 0x3a0b, 0xd0 },
++ { 0x3a0d, 0x10 },
++ { 0x3a0e, 0xd },
++ { 0x4407, 0x4 },
++ { 0x5193, 0x70 },
++ { 0x589b, 0x0 },
++ { 0x589a, 0xc0 },
++ { 0x401e, 0x20 },
++ { 0x4001, 0x42 },
++ { 0x401c, 0x6 },
++ { 0x3825, 0xac },
++ { 0x3827, 0xc },
++ { 0x528a, 0x1 },
++ { 0x528b, 0x4 },
++ { 0x528c, 0x8 },
++ { 0x528d, 0x10 },
++ { 0x528e, 0x20 },
++ { 0x528f, 0x28 },
++ { 0x5290, 0x30 },
++ { 0x5292, 0x0 },
++ { 0x5293, 0x1 },
++ { 0x5294, 0x0 },
++ { 0x5295, 0x4 },
++ { 0x5296, 0x0 },
++ { 0x5297, 0x8 },
++ { 0x5298, 0x0 },
++ { 0x5299, 0x10 },
++ { 0x529a, 0x0 },
++ { 0x529b, 0x20 },
++ { 0x529c, 0x0 },
++ { 0x529d, 0x28 },
++ { 0x529e, 0x0 },
++ { 0x529f, 0x30 },
++ { 0x5282, 0x0 },
++ { 0x5300, 0x0 },
++ { 0x5301, 0x20 },
++ { 0x5302, 0x0 },
++ { 0x5303, 0x7c },
++ { 0x530c, 0x0 },
++ { 0x530d, 0xc },
++ { 0x530e, 0x20 },
++ { 0x530f, 0x80 },
++ { 0x5310, 0x20 },
++ { 0x5311, 0x80 },
++ { 0x5308, 0x20 },
++ { 0x5309, 0x40 },
++ { 0x5304, 0x0 },
++ { 0x5305, 0x30 },
++ { 0x5306, 0x0 },
++ { 0x5307, 0x80 },
++ { 0x5314, 0x8 },
++ { 0x5315, 0x20 },
++ { 0x5319, 0x30 },
++ { 0x5316, 0x10 },
++ { 0x5317, 0x0 },
++ { 0x5318, 0x2 },
++ { 0x5380, 0x1 },
++ { 0x5381, 0x0 },
++ { 0x5382, 0x0 },
++ { 0x5383, 0x4e },
++ { 0x5384, 0x0 },
++ { 0x5385, 0xf },
++ { 0x5386, 0x0 },
++ { 0x5387, 0x0 },
++ { 0x5388, 0x1 },
++ { 0x5389, 0x15 },
++ { 0x538a, 0x0 },
++ { 0x538b, 0x31 },
++ { 0x538c, 0x0 },
++ { 0x538d, 0x0 },
++ { 0x538e, 0x0 },
++ { 0x538f, 0xf },
++ { 0x5390, 0x0 },
++ { 0x5391, 0xab },
++ { 0x5392, 0x0 },
++ { 0x5393, 0xa2 },
++ { 0x5394, 0x8 },
++ { 0x5480, 0x14 },
++ { 0x5481, 0x21 },
++ { 0x5482, 0x36 },
++ { 0x5483, 0x57 },
++ { 0x5484, 0x65 },
++ { 0x5485, 0x71 },
++ { 0x5486, 0x7d },
++ { 0x5487, 0x87 },
++ { 0x5488, 0x91 },
++ { 0x5489, 0x9a },
++ { 0x548a, 0xaa },
++ { 0x548b, 0xb8 },
++ { 0x548c, 0xcd },
++ { 0x548d, 0xdd },
++ { 0x548e, 0xea },
++ { 0x548f, 0x1d },
++ { 0x5490, 0x5 },
++ { 0x5491, 0x0 },
++ { 0x5492, 0x4 },
++ { 0x5493, 0x20 },
++ { 0x5494, 0x3 },
++ { 0x5495, 0x60 },
++ { 0x5496, 0x2 },
++ { 0x5497, 0xb8 },
++ { 0x5498, 0x2 },
++ { 0x5499, 0x86 },
++ { 0x549a, 0x2 },
++ { 0x549b, 0x5b },
++ { 0x549c, 0x2 },
++ { 0x549d, 0x3b },
++ { 0x549e, 0x2 },
++ { 0x549f, 0x1c },
++ { 0x54a0, 0x2 },
++ { 0x54a1, 0x4 },
++ { 0x54a2, 0x1 },
++ { 0x54a3, 0xed },
++ { 0x54a4, 0x1 },
++ { 0x54a5, 0xc5 },
++ { 0x54a6, 0x1 },
++ { 0x54a7, 0xa5 },
++ { 0x54a8, 0x1 },
++ { 0x54a9, 0x6c },
++ { 0x54aa, 0x1 },
++ { 0x54ab, 0x41 },
++ { 0x54ac, 0x1 },
++ { 0x54ad, 0x20 },
++ { 0x54ae, 0x0 },
++ { 0x54af, 0x16 },
++ { 0x54b0, 0x1 },
++ { 0x54b1, 0x20 },
++ { 0x54b2, 0x0 },
++ { 0x54b3, 0x10 },
++ { 0x54b4, 0x0 },
++ { 0x54b5, 0xf0 },
++ { 0x54b6, 0x0 },
++ { 0x54b7, 0xdf },
++ { 0x5402, 0x3f },
++ { 0x5403, 0x0 },
++ { 0x3406, 0x0 },
++ { 0x5180, 0xff },
++ { 0x5181, 0x52 },
++ { 0x5182, 0x11 },
++ { 0x5183, 0x14 },
++ { 0x5184, 0x25 },
++ { 0x5185, 0x24 },
++ { 0x5186, 0x6 },
++ { 0x5187, 0x8 },
++ { 0x5188, 0x8 },
++ { 0x5189, 0x7c },
++ { 0x518a, 0x60 },
++ { 0x518b, 0xb2 },
++ { 0x518c, 0xb2 },
++ { 0x518d, 0x44 },
++ { 0x518e, 0x3d },
++ { 0x518f, 0x58 },
++ { 0x5190, 0x46 },
++ { 0x5191, 0xf8 },
++ { 0x5192, 0x4 },
++ { 0x5193, 0x70 },
++ { 0x5194, 0xf0 },
++ { 0x5195, 0xf0 },
++ { 0x5196, 0x3 },
++ { 0x5197, 0x1 },
++ { 0x5198, 0x4 },
++ { 0x5199, 0x12 },
++ { 0x519a, 0x4 },
++ { 0x519b, 0x0 },
++ { 0x519c, 0x6 },
++ { 0x519d, 0x82 },
++ { 0x519e, 0x0 },
++ { 0x5025, 0x80 },
++ { 0x3a0f, 0x38 },
++ { 0x3a10, 0x30 },
++ { 0x3a1b, 0x3a },
++ { 0x3a1e, 0x2e },
++ { 0x3a11, 0x60 },
++ { 0x3a1f, 0x10 },
++ { 0x5688, 0xa6 },
++ { 0x5689, 0x6a },
++ { 0x568a, 0xea },
++ { 0x568b, 0xae },
++ { 0x568c, 0xa6 },
++ { 0x568d, 0x6a },
++ { 0x568e, 0x62 },
++ { 0x568f, 0x26 },
++ { 0x5583, 0x40 },
++ { 0x5584, 0x40 },
++ { 0x5580, 0x2 },
++ { 0x5000, 0xcf },
++ { 0x5800, 0x27 },
++ { 0x5801, 0x19 },
++ { 0x5802, 0x12 },
++ { 0x5803, 0xf },
++ { 0x5804, 0x10 },
++ { 0x5805, 0x15 },
++ { 0x5806, 0x1e },
++ { 0x5807, 0x2f },
++ { 0x5808, 0x15 },
++ { 0x5809, 0xd },
++ { 0x580a, 0xa },
++ { 0x580b, 0x9 },
++ { 0x580c, 0xa },
++ { 0x580d, 0xc },
++ { 0x580e, 0x12 },
++ { 0x580f, 0x19 },
++ { 0x5810, 0xb },
++ { 0x5811, 0x7 },
++ { 0x5812, 0x4 },
++ { 0x5813, 0x3 },
++ { 0x5814, 0x3 },
++ { 0x5815, 0x6 },
++ { 0x5816, 0xa },
++ { 0x5817, 0xf },
++ { 0x5818, 0xa },
++ { 0x5819, 0x5 },
++ { 0x581a, 0x1 },
++ { 0x581b, 0x0 },
++ { 0x581c, 0x0 },
++ { 0x581d, 0x3 },
++ { 0x581e, 0x8 },
++ { 0x581f, 0xc },
++ { 0x5820, 0xa },
++ { 0x5821, 0x5 },
++ { 0x5822, 0x1 },
++ { 0x5823, 0x0 },
++ { 0x5824, 0x0 },
++ { 0x5825, 0x3 },
++ { 0x5826, 0x8 },
++ { 0x5827, 0xc },
++ { 0x5828, 0xe },
++ { 0x5829, 0x8 },
++ { 0x582a, 0x6 },
++ { 0x582b, 0x4 },
++ { 0x582c, 0x5 },
++ { 0x582d, 0x7 },
++ { 0x582e, 0xb },
++ { 0x582f, 0x12 },
++ { 0x5830, 0x18 },
++ { 0x5831, 0x10 },
++ { 0x5832, 0xc },
++ { 0x5833, 0xa },
++ { 0x5834, 0xb },
++ { 0x5835, 0xe },
++ { 0x5836, 0x15 },
++ { 0x5837, 0x19 },
++ { 0x5838, 0x32 },
++ { 0x5839, 0x1f },
++ { 0x583a, 0x18 },
++ { 0x583b, 0x16 },
++ { 0x583c, 0x17 },
++ { 0x583d, 0x1e },
++ { 0x583e, 0x26 },
++ { 0x583f, 0x53 },
++ { 0x5840, 0x10 },
++ { 0x5841, 0xf },
++ { 0x5842, 0xd },
++ { 0x5843, 0xc },
++ { 0x5844, 0xe },
++ { 0x5845, 0x9 },
++ { 0x5846, 0x11 },
++ { 0x5847, 0x10 },
++ { 0x5848, 0x10 },
++ { 0x5849, 0x10 },
++ { 0x584a, 0x10 },
++ { 0x584b, 0xe },
++ { 0x584c, 0x10 },
++ { 0x584d, 0x10 },
++ { 0x584e, 0x11 },
++ { 0x584f, 0x10 },
++ { 0x5850, 0xf },
++ { 0x5851, 0xc },
++ { 0x5852, 0xf },
++ { 0x5853, 0x10 },
++ { 0x5854, 0x10 },
++ { 0x5855, 0xf },
++ { 0x5856, 0xe },
++ { 0x5857, 0xb },
++ { 0x5858, 0x10 },
++ { 0x5859, 0xd },
++ { 0x585a, 0xd },
++ { 0x585b, 0xc },
++ { 0x585c, 0xc },
++ { 0x585d, 0xc },
++ { 0x585e, 0xb },
++ { 0x585f, 0xc },
++ { 0x5860, 0xc },
++ { 0x5861, 0xc },
++ { 0x5862, 0xd },
++ { 0x5863, 0x8 },
++ { 0x5864, 0x11 },
++ { 0x5865, 0x18 },
++ { 0x5866, 0x18 },
++ { 0x5867, 0x19 },
++ { 0x5868, 0x17 },
++ { 0x5869, 0x19 },
++ { 0x586a, 0x16 },
++ { 0x586b, 0x13 },
++ { 0x586c, 0x13 },
++ { 0x586d, 0x12 },
++ { 0x586e, 0x13 },
++ { 0x586f, 0x16 },
++ { 0x5870, 0x14 },
++ { 0x5871, 0x12 },
++ { 0x5872, 0x10 },
++ { 0x5873, 0x11 },
++ { 0x5874, 0x11 },
++ { 0x5875, 0x16 },
++ { 0x5876, 0x14 },
++ { 0x5877, 0x11 },
++ { 0x5878, 0x10 },
++ { 0x5879, 0xf },
++ { 0x587a, 0x10 },
++ { 0x587b, 0x14 },
++ { 0x587c, 0x13 },
++ { 0x587d, 0x12 },
++ { 0x587e, 0x11 },
++ { 0x587f, 0x11 },
++ { 0x5880, 0x12 },
++ { 0x5881, 0x15 },
++ { 0x5882, 0x14 },
++ { 0x5883, 0x15 },
++ { 0x5884, 0x15 },
++ { 0x5885, 0x15 },
++ { 0x5886, 0x13 },
++ { 0x5887, 0x17 },
++ { 0x3710, 0x10 },
++ { 0x3632, 0x51 },
++ { 0x3702, 0x10 },
++ { 0x3703, 0xb2 },
++ { 0x3704, 0x18 },
++ { 0x370b, 0x40 },
++ { 0x370d, 0x3 },
++ { 0x3631, 0x1 },
++ { 0x3632, 0x52 },
++ { 0x3606, 0x24 },
++ { 0x3620, 0x96 },
++ { 0x5785, 0x7 },
++ { 0x3a13, 0x30 },
++ { 0x3600, 0x52 },
++ { 0x3604, 0x48 },
++ { 0x3606, 0x1b },
++ { 0x370d, 0xb },
++ { 0x370f, 0xc0 },
++ { 0x3709, 0x1 },
++ { 0x3823, 0x0 },
++ { 0x5007, 0x0 },
++ { 0x5009, 0x0 },
++ { 0x5011, 0x0 },
++ { 0x5013, 0x0 },
++ { 0x519e, 0x0 },
++ { 0x5086, 0x0 },
++ { 0x5087, 0x0 },
++ { 0x5088, 0x0 },
++ { 0x5089, 0x0 },
++ { 0x302b, 0x0 },
++ { 0x3503, 0x7 },
++ { 0x3011, 0x8 },
++ { 0x350c, 0x2 },
++ { 0x350d, 0xe4 },
++ { 0x3621, 0xc9 },
++ { 0x370a, 0x81 },
++ { 0xffff, 0xff },
++};
++
++static struct regval_list ov5642_default_regs_finalise[] = {
++ { 0x3810, 0xc2 },
++ { 0x3818, 0xc9 },
++ { 0x381c, 0x10 },
++ { 0x381d, 0xa0 },
++ { 0x381e, 0x5 },
++ { 0x381f, 0xb0 },
++ { 0x3820, 0x0 },
++ { 0x3821, 0x0 },
++ { 0x3824, 0x11 },
++ { 0x3a08, 0x1b },
++ { 0x3a09, 0xc0 },
++ { 0x3a0a, 0x17 },
++ { 0x3a0b, 0x20 },
++ { 0x3a0d, 0x2 },
++ { 0x3a0e, 0x1 },
++ { 0x401c, 0x4 },
++ { 0x5682, 0x5 },
++ { 0x5683, 0x0 },
++ { 0x5686, 0x2 },
++ { 0x5687, 0xcc },
++ { 0x5001, 0x4f },
++ { 0x589b, 0x6 },
++ { 0x589a, 0xc5 },
++ { 0x3503, 0x0 },
++ { 0x460c, 0x20 },
++ { 0x460b, 0x37 },
++ { 0x471c, 0xd0 },
++ { 0x471d, 0x5 },
++ { 0x3815, 0x1 },
++ { 0x3818, 0xc1 },
++ { 0x501f, 0x0 },
++ { 0x5002, 0xe0 },
++ { 0x4300, 0x32 }, /* UYVY */
++ { 0x3002, 0x1c },
++ { 0x4800, 0x14 },
++ { 0x4801, 0xf },
++ { 0x3007, 0x3b },
++ { 0x300e, 0x4 },
++ { 0x4803, 0x50 },
++ { 0x3815, 0x1 },
++ { 0x4713, 0x2 },
++ { 0x4842, 0x1 },
++ { 0x300f, 0xe },
++ { 0x3003, 0x3 },
++ { 0x3003, 0x1 },
++ { 0xffff, 0xff },
++};
++
++#endif
++
++#endif /* _OV5642_H_ */
+diff --git a/drivers/media/i2c/soc_camera/ov5642_720p.h b/drivers/media/i2c/soc_camera/ov5642_720p.h
+new file mode 100644
+index 0000000..d5a52e3
+--- /dev/null
++++ b/drivers/media/i2c/soc_camera/ov5642_720p.h
+@@ -0,0 +1,711 @@
++/* Settings array from
++ * From 5e8e49e226b29c144ddf482afe7d3ad659c9897f Mon Sep 17 00:00:00 2001
++ * From: Kazuya Nishimura <kazuya.nishimura@windriver.com>
++ * Date: Mon, 20 Oct 2014 15:12:56 +0900
++ * Subject: [PATCH] Enabled VIN driver for MMB
++ */
++
++/* 720p 30fps @ 1280x720 */
++/* for the setting , 24MHz Mlck input and 90MHz Plck output */
++/* refer to OV5642.c */
++
++static struct regval_list OV5642_720P_30FPS[] =
++{
++ {0x3103, 0x93},
++ {0x3008, 0x82},
++ {0x3017, 0x7f},
++ {0x3018, 0xfc},
++ /* drive capability 4x */
++ { 0x302c, (3 << 5) | 0x02 },
++ {0x3810, 0xc2},
++ {0x3615, 0xf0},
++ {0x3000, 0x00},
++ {0x3001, 0x00},
++ {0x3002, 0x00},
++ {0x3003, 0x00},
++ {0x3000, 0xf8},
++ {0x3001, 0x48},
++ {0x3002, 0x5c},
++ {0x3003, 0x02},
++ {0x3004, 0x07},
++ {0x3005, 0xb7},
++ {0x3006, 0x43},
++ {0x3007, 0x37},
++ {0x3011, 0x0f}, //PLL CONTROL 02 : Bit[5:0] PLL DIVP divider
++ {0x3010, 0x10}, //PLL CONTROL 01 : Bit[7:4] PLL DIVS, Bit[3:0] PLL DIVM (MIPI divider ratio)
++ //29-30fps
++ {0x460c, 0x22},
++ {0x3815, 0x04},
++ {0x370d, 0x06},
++ {0x370c, 0xa0},
++ {0x3602, 0xfc},
++ {0x3612, 0xff},
++ {0x3634, 0xc0},
++ {0x3613, 0x00},
++ {0x3605, 0x7c},
++ {0x3621, 0x09},
++ {0x3622, 0x00},
++ {0x3604, 0x40},
++ {0x3603, 0xa7},
++ {0x3603, 0x27},
++ {0x4000, 0x21},
++ {0x401d, 0x02},
++ {0x3600, 0x54},
++ {0x3605, 0x04},
++ {0x3606, 0x3f},
++ {0x3c01, 0x80},
++ {REG_ISP_CTRL_00, 0x4f},
++ {0x4300, 0x32}, /* YUV422: UYVY... */
++ {0x5020, 0x04},
++ {0x5181, 0x79},
++ {0x5182, 0x00},
++ {0x5185, 0x22},
++ {0x5197, 0x01},
++ {REG_ISP_CTRL_01, 0xff},
++ {0x5500, 0x0a},
++ {0x5504, 0x00},
++ {0x5505, 0x7f},
++ {0x5080, 0x08},
++ {0x300e, 0x18},
++ {0x4610, 0x00},
++ {0x471d, 0x05},
++ {0x4708, 0x06},
++ /* POLARITY CTRL 00
++ * [0] VSYNC - act low
++ * [1] HREF - act low
++ * [2] gate PCLK under HREF - no
++ * [3] gate PCLK under VSYNK - no
++ * [5] PCLK - falling edge
++ */
++ {0x4740, 0x20},
++ {0x3710, 0x10},
++ {0x3632, 0x41},
++ {0x3702, 0x40},
++ {0x3620, 0x37},
++ {0x3631, 0x01},
++ {REG_OUT_WIDTH_HIGH, 0x02}, // TIMING DVPHO Bit[3:0] DVP output horizontal width high byte
++ {REG_OUT_WIDTH_LOW, 0x80}, // TIMING DVPHO Bit[7:0] DVP output horizontal width low byte
++ // 0x280 => 640
++ {REG_OUT_HEIGHT_HIGH, 0x01}, // TIMING DVPVO Bit[3:0] DVP output vertical height high byte
++ {REG_OUT_HEIGHT_LOW, 0xe0}, // TIMING DVPVO Bit[7:0] DVP output vertical height low byte
++ // 0x1e0 => 480
++ {REG_OUT_TOTAL_HEIGHT_HIGH, 0x07}, // TIMING VTS Bit[3:0] Total vertical size high byte [11:8]
++ {REG_OUT_TOTAL_HEIGHT_LOW, 0xd0}, // TIMING VTS Bit[7:0] Total vertical size low byte [7:0]
++ // 0x7d0 => 2000
++ {0x501f, 0x00},
++ {REG_ISP_CTRL_00, 0x4f},
++ {REG_OUTPUT_FORMAT, 0x32}, //UYVY
++ {0x3503, 0x07},
++ {0x3501, 0x73},
++ {0x3502, 0x80},
++ {0x350b, 0x00},
++ {0x3503, 0x07},
++ {0x3824, 0x11},
++ {0x3501, 0x1e},
++ {0x3502, 0x80},
++ {0x350b, 0x7f},
++ {REG_OUT_TOTAL_WIDTH_HIGH, 0x0c},
++ {REG_OUT_TOTAL_WIDTH_LOW, 0x80},
++ {REG_OUT_TOTAL_HEIGHT_HIGH, 0x03}, // TIMING VTS Bit[3:0] Total vertical size high byte [11:8]
++ {REG_OUT_TOTAL_HEIGHT_LOW, 0xe8}, // TIMING VTS Bit[7:0] Total vertical size low byte [7:0]
++ // 0x3e8 => 1000
++ {0x3a0d, 0x04},
++ {0x3a0e, 0x03},
++ {0x3818, 0xc1},
++ {0x3705, 0xdb},
++ {0x370a, 0x81},
++ {REG_WINDOW_START_X_LOW, 0x80},
++ {0x3621, 0xc7},
++ {REG_WINDOW_START_X_LOW, 0x50},
++ {REG_WINDOW_START_Y_LOW, 0x08},
++ {0x3827, 0x08},
++ {0x3810, 0xc0},
++ {REG_WINDOW_WIDTH_HIGH, 0x05},
++ {REG_WINDOW_WIDTH_LOW, 0x00},
++ {REG_AVG_WINDOW_END_X_HIGH, 0x05},
++ {REG_AVG_WINDOW_END_X_LOW, 0x00},
++ {REG_WINDOW_HEIGHT_HIGH, 0x03},
++ {REG_WINDOW_HEIGHT_LOW, 0xc0},
++ {REG_AVG_WINDOW_END_Y_HIGH, 0x03},
++ {REG_AVG_WINDOW_END_Y_LOW, 0xc0},
++ {0x3a00, 0x78},
++ {0x3a1a, 0x04},
++ {0x3a13, 0x30},
++ {0x3a18, 0x00},
++ {0x3a19, 0x7c},
++ {0x3a08, 0x12},
++ {0x3a09, 0xc0},
++ {0x3a0a, 0x0f},
++ {0x3a0b, 0xa0},
++ {0x3004, 0xff},
++ {0x350c, 0x07},
++ {0x350d, 0xd0},
++ {0x3500, 0x00},
++ {0x3501, 0x00},
++ {0x3502, 0x00},
++ {0x350a, 0x00},
++ {0x350b, 0x00},
++ {0x3503, 0x00},
++ {0x528a, 0x02},
++ {0x528b, 0x04},
++ {0x528c, 0x08},
++ {0x528d, 0x08},
++ {0x528e, 0x08},
++ {0x528f, 0x10},
++ {0x5290, 0x10},
++ {0x5292, 0x00},
++ {0x5293, 0x02},
++ {0x5294, 0x00},
++ {0x5295, 0x02},
++ {0x5296, 0x00},
++ {0x5297, 0x02},
++ {0x5298, 0x00},
++ {0x5299, 0x02},
++ {0x529a, 0x00},
++ {0x529b, 0x02},
++ {0x529c, 0x00},
++ {0x529d, 0x02},
++ {0x529e, 0x00},
++ {0x529f, 0x02},
++ {0x3a0f, 0x3c},
++ {0x3a10, 0x30},
++ {0x3a1b, 0x3c},
++ {0x3a1e, 0x30},
++ {0x3a11, 0x70},
++ {0x3a1f, 0x10},
++ {0x3030, 0x0b},
++ {0x3a02, 0x00},
++ {0x3a03, 0x7d},
++ {0x3a04, 0x00},
++ {0x3a14, 0x00},
++ {0x3a15, 0x7d},
++ {0x3a16, 0x00},
++ {0x3a00, 0x78},
++ {0x3a08, 0x09},
++ {0x3a09, 0x60},
++ {0x3a0a, 0x07},
++ {0x3a0b, 0xd0},
++ {0x3a0d, 0x08},
++ {0x3a0e, 0x06},
++ {0x5193, 0x70},
++ {0x3620, 0x57},
++ {0x3703, 0x98},
++ {0x3704, 0x1c},
++ {0x589b, 0x04},
++ {0x589a, 0xc5},
++ {0x528a, 0x00},
++ {0x528b, 0x02},
++ {0x528c, 0x08},
++ {0x528d, 0x10},
++ {0x528e, 0x20},
++ {0x528f, 0x28},
++ {0x5290, 0x30},
++ {0x5292, 0x00},
++ {0x5293, 0x00},
++ {0x5294, 0x00},
++ {0x5295, 0x02},
++ {0x5296, 0x00},
++ {0x5297, 0x08},
++ {0x5298, 0x00},
++ {0x5299, 0x10},
++ {0x529a, 0x00},
++ {0x529b, 0x20},
++ {0x529c, 0x00},
++ {0x529d, 0x28},
++ {0x529e, 0x00},
++ {0x529f, 0x30},
++ {0x5282, 0x00},
++ {0x5300, 0x00},
++ {0x5301, 0x20},
++ {0x5302, 0x00},
++ {0x5303, 0x7c},
++ {0x530c, 0x00},
++ {0x530d, 0x0c},
++ {0x530e, 0x20},
++ {0x530f, 0x80},
++ {0x5310, 0x20},
++ {0x5311, 0x80},
++ {0x5308, 0x20},
++ {0x5309, 0x40},
++ {0x5304, 0x00},
++ {0x5305, 0x30},
++ {0x5306, 0x00},
++ {0x5307, 0x80},
++ {0x5314, 0x08},
++ {0x5315, 0x20},
++ {0x5319, 0x30},
++ {0x5316, 0x10},
++ {0x5317, 0x08},
++ {0x5318, 0x02},
++ {0x5380, 0x01},
++ {0x5381, 0x00},
++ {0x5382, 0x00},
++ {0x5383, 0x4e},
++ {0x5384, 0x00},
++ {0x5385, 0x0f},
++ {0x5386, 0x00},
++ {0x5387, 0x00},
++ {0x5388, 0x01},
++ {0x5389, 0x15},
++ {0x538a, 0x00},
++ {0x538b, 0x31},
++ {0x538c, 0x00},
++ {0x538d, 0x00},
++ {0x538e, 0x00},
++ {0x538f, 0x0f},
++ {0x5390, 0x00},
++ {0x5391, 0xab},
++ {0x5392, 0x00},
++ {0x5393, 0xa2},
++ {0x5394, 0x08},
++ {0x5480, 0x14},
++ {0x5481, 0x21},
++ {0x5482, 0x36},
++ {0x5483, 0x57},
++ {0x5484, 0x65},
++ {0x5485, 0x71},
++ {0x5486, 0x7d},
++ {0x5487, 0x87},
++ {0x5488, 0x91},
++ {0x5489, 0x9a},
++ {0x548a, 0xaa},
++ {0x548b, 0xb8},
++ {0x548c, 0xcd},
++ {0x548d, 0xdd},
++ {0x548e, 0xea},
++ {0x548f, 0x10},
++ {0x5490, 0x05},
++ {0x5491, 0x00},
++ {0x5492, 0x04},
++ {0x5493, 0x20},
++ {0x5494, 0x03},
++ {0x5495, 0x60},
++ {0x5496, 0x02},
++ {0x5497, 0xb8},
++ {0x5498, 0x02},
++ {0x5499, 0x86},
++ {0x549a, 0x02},
++ {0x549b, 0x5b},
++ {0x549c, 0x02},
++ {0x549d, 0x3b},
++ {0x549e, 0x02},
++ {0x549f, 0x1c},
++ {0x54a0, 0x02},
++ {0x54a1, 0x04},
++ {0x54a2, 0x01},
++ {0x54a3, 0xed},
++ {0x54a4, 0x01},
++ {0x54a5, 0xc5},
++ {0x54a6, 0x01},
++ {0x54a7, 0xa5},
++ {0x54a8, 0x01},
++ {0x54a9, 0x6c},
++ {0x54aa, 0x01},
++ {0x54ab, 0x41},
++ {0x54ac, 0x01},
++ {0x54ad, 0x20},
++ {0x54ae, 0x00},
++ {0x54af, 0x16},
++ {0x3406, 0x00},
++ {0x5192, 0x04},
++ {0x5191, 0xf8},
++ {0x5193, 0x70},
++ {0x5194, 0xf0},
++ {0x5195, 0xf0},
++ {0x518d, 0x3d},
++ {0x518f, 0x54},
++ {0x518e, 0x3d},
++ {0x5190, 0x54},
++ {0x518b, 0xc0},
++ {0x518c, 0xbd},
++ {0x5187, 0x18},
++ {0x5188, 0x18},
++ {0x5189, 0x6e},
++ {0x518a, 0x68},
++ {0x5186, 0x1c},
++ {0x5181, 0x50},
++ {0x5184, 0x25},
++ {0x5182, 0x11},
++ {0x5183, 0x14},
++ {0x5184, 0x25},
++ {0x5185, 0x24},
++ {0x5025, 0x82},
++ {0x3a0f, 0x7e},
++ {0x3a10, 0x72},
++ {0x3a1b, 0x80},
++ {0x3a1e, 0x70},
++ {0x3a11, 0xd0},
++ {0x3a1f, 0x40},
++ {0x5583, 0x40},
++ {0x5584, 0x40},
++ {0x5580, 0x02},
++ {0x3633, 0x07},
++ {0x3702, 0x10},
++ {0x3703, 0xb2},
++ {0x3704, 0x18},
++ {0x370b, 0x40},
++ {0x370d, 0x02},
++ {0x3620, 0x52},
++ {0x3c00, 0x04},
++
++ {REG_ISP_CTRL_01, 0xFF},
++ {0x5583, 0x50},
++ {0x5584, 0x50},
++ {0x5580, 0x02},
++ {0x3c01, 0x80},
++ {0x3c00, 0x04},
++ {0x5800, 0x27},
++ {0x5801, 0x22},
++ {0x5802, 0x1b},
++ {0x5803, 0x17},
++ {0x5804, 0x16},
++ {0x5805, 0x18},
++ {0x5806, 0x20},
++ {0x5807, 0x20},
++ {0x5808, 0x1b},
++ {0x5809, 0x15},
++ {0x580a, 0x0f},
++ {0x580b, 0x0d},
++ {0x580c, 0x0d},
++ {0x580d, 0x0e},
++ {0x580e, 0x11},
++ {0x580f, 0x18},
++ {0x5810, 0x10},
++ {0x5811, 0x0d},
++ {0x5812, 0x08},
++ {0x5813, 0x05},
++ {0x5814, 0x04},
++ {0x5815, 0x06},
++ {0x5816, 0x09},
++ {0x5817, 0x0e},
++ {0x5818, 0x0d},
++ {0x5819, 0x09},
++ {0x581a, 0x03},
++ {0x581b, 0x00},
++ {0x581c, 0x00},
++ {0x581d, 0x01},
++ {0x581e, 0x05},
++ {0x581f, 0x0b},
++ {0x5820, 0x0d},
++ {0x5821, 0x09},
++ {0x5822, 0x03},
++ {0x5823, 0x00},
++ {0x5824, 0x00},
++ {0x5825, 0x01},
++ {0x5826, 0x05},
++ {0x5827, 0x0b},
++ {0x5828, 0x10},
++ {0x5829, 0x0c},
++ {0x582a, 0x08},
++ {0x582b, 0x04},
++ {0x582c, 0x03},
++ {0x582d, 0x05},
++ {0x582e, 0x09},
++ {0x582f, 0x0e},
++ {0x5830, 0x1b},
++ {0x5831, 0x14},
++ {0x5832, 0x0f},
++ {0x5833, 0x0c},
++ {0x5834, 0x0c},
++ {0x5835, 0x0d},
++ {0x5836, 0x10},
++ {0x5837, 0x19},
++ {0x5838, 0x25},
++ {0x5839, 0x23},
++ {0x583a, 0x1a},
++ {0x583b, 0x16},
++ {0x583c, 0x15},
++ {0x583d, 0x18},
++ {0x583e, 0x1f},
++ {0x583f, 0x25},
++ {0x5840, 0x10},
++ {0x5841, 0x0e},
++ {0x5842, 0x0e},
++ {0x5843, 0x0e},
++ {0x5844, 0x0f},
++ {0x5845, 0x0a},
++ {0x5846, 0x08},
++ {0x5847, 0x0f},
++ {0x5848, 0x0f},
++ {0x5849, 0x0f},
++ {0x584a, 0x0c},
++ {0x584b, 0x0f},
++ {0x584c, 0x09},
++ {0x584d, 0x10},
++ {0x584e, 0x11},
++ {0x584f, 0x10},
++ {0x5850, 0x0f},
++ {0x5851, 0x0e},
++ {0x5852, 0x08},
++ {0x5853, 0x10},
++ {0x5854, 0x10},
++ {0x5855, 0x10},
++ {0x5856, 0x0e},
++ {0x5857, 0x0e},
++ {0x5858, 0x0a},
++ {0x5859, 0x0e},
++ {0x585a, 0x0e},
++ {0x585b, 0x0e},
++ {0x585c, 0x0e},
++ {0x585d, 0x0d},
++ {0x585e, 0x08},
++ {0x585f, 0x0b},
++ {0x5860, 0x0a},
++ {0x5861, 0x0a},
++ {0x5862, 0x09},
++ {0x5863, 0x0d},
++ {0x5864, 0x13},
++ {0x5865, 0x0e},
++ {0x5866, 0x10},
++ {0x5867, 0x10},
++ {0x5868, 0x0e},
++ {0x5869, 0x11},
++ {0x586a, 0x12},
++ {0x586b, 0x10},
++ {0x586c, 0x10},
++ {0x586d, 0x10},
++ {0x586e, 0x10},
++ {0x586f, 0x11},
++ {0x5870, 0x15},
++ {0x5871, 0x10},
++ {0x5872, 0x10},
++ {0x5873, 0x10},
++ {0x5874, 0x11},
++ {0x5875, 0x11},
++ {0x5876, 0x14},
++ {0x5877, 0x0f},
++ {0x5878, 0x10},
++ {0x5879, 0x10},
++ {0x587a, 0x10},
++ {0x587b, 0x11},
++ {0x587c, 0x12},
++ {0x587d, 0x0f},
++ {0x587e, 0x0f},
++ {0x587f, 0x10},
++ {0x5880, 0x10},
++ {0x5881, 0x0f},
++ {0x5882, 0x12},
++ {0x5883, 0x0e},
++ {0x5884, 0x10},
++ {0x5885, 0x10},
++ {0x5886, 0x0e},
++ {0x5887, 0x0e},
++ {0x5180, 0xff},
++ {0x5181, 0x52},
++ {0x5182, 0x11},
++ {0x5183, 0x14},
++ {0x5184, 0x25},
++ {0x5185, 0x24},
++ {0x5186, 0x14},
++ {0x5187, 0x14},
++ {0x5188, 0x14},
++ {0x5189, 0x6c},
++ {0x518a, 0x60},
++ {0x518b, 0xbd},
++ {0x518c, 0x9c},
++ {0x518d, 0x3d},
++ {0x518e, 0x34},
++ {0x518f, 0x57},
++ {0x5190, 0x4a},
++ {0x5191, 0xf8},
++ {0x5192, 0x04},
++ {0x5193, 0x70},
++ {0x5194, 0xf0},
++ {0x5195, 0xf0},
++ {0x5196, 0x03},
++ {0x5197, 0x01},
++ {0x5198, 0x04},
++ {0x5199, 0x00},
++ {0x519a, 0x04},
++ {0x519b, 0x35},
++ {0x519c, 0x08},
++ {0x519d, 0xb8},
++ {0x519e, 0xa0},
++ {0x528a, 0x00},
++ {0x528b, 0x01},
++ {0x528c, 0x04},
++ {0x528d, 0x08},
++ {0x528e, 0x10},
++ {0x528f, 0x20},
++ {0x5290, 0x30},
++ {0x5292, 0x00},
++ {0x5293, 0x00},
++ {0x5294, 0x00},
++ {0x5295, 0x01},
++ {0x5296, 0x00},
++ {0x5297, 0x04},
++ {0x5298, 0x00},
++ {0x5299, 0x08},
++ {0x529a, 0x00},
++ {0x529b, 0x10},
++ {0x529c, 0x00},
++ {0x529d, 0x20},
++ {0x529e, 0x00},
++ {0x529f, 0x30},
++ {0x5282, 0x00},
++ {0x5300, 0x00},
++ {0x5301, 0x20},
++ {0x5302, 0x00},
++ {0x5303, 0x7c},
++ {0x530c, 0x00},
++ {0x530d, 0x10},
++ {0x530e, 0x20},
++ {0x530f, 0x80},
++ {0x5310, 0x20},
++ {0x5311, 0x80},
++ {0x5308, 0x20},
++ {0x5309, 0x40},
++ {0x5304, 0x00},
++ {0x5305, 0x30},
++ {0x5306, 0x00},
++ {0x5307, 0x80},
++ {0x5314, 0x08},
++ {0x5315, 0x20},
++ {0x5319, 0x30},
++ {0x5316, 0x10},
++ {0x5317, 0x00},
++ {0x5318, 0x02},
++ {0x5380, 0x01},
++ {0x5381, 0x00},
++ {0x5382, 0x00},
++ {0x5383, 0x1f},
++ {0x5384, 0x00},
++ {0x5385, 0x06},
++ {0x5386, 0x00},
++ {0x5387, 0x00},
++ {0x5388, 0x00},
++ {0x5389, 0xE1},
++ {0x538A, 0x00},
++ {0x538B, 0x2B},
++ {0x538C, 0x00},
++ {0x538D, 0x00},
++ {0x538E, 0x00},
++ {0x538F, 0x10},
++ {0x5390, 0x00},
++ {0x5391, 0xB3},
++ {0x5392, 0x00},
++ {0x5393, 0xA6},
++ {0x5394, 0x08},
++ {0x5480, 0x14},
++ {0x5481, 0x21},
++ {0x5482, 0x36},
++ {0x5483, 0x57},
++ {0x5484, 0x65},
++ {0x5485, 0x71},
++ {0x5486, 0x7D},
++ {0x5487, 0x87},
++ {0x5488, 0x91},
++ {0x5489, 0x9A},
++ {0x548A, 0xAA},
++ {0x548B, 0xB8},
++ {0x548C, 0xCD},
++ {0x548D, 0xDD},
++ {0x548E, 0xEA},
++ {0x548F, 0x1d},
++ {0x5490, 0x05},
++ {0x5491, 0x00},
++ {0x5492, 0x04},
++ {0x5493, 0x20},
++ {0x5494, 0x03},
++ {0x5495, 0x60},
++ {0x5496, 0x02},
++ {0x5497, 0xB8},
++ {0x5498, 0x02},
++ {0x5499, 0x86},
++ {0x549A, 0x02},
++ {0x549B, 0x5B},
++ {0x549C, 0x02},
++ {0x549D, 0x3B},
++ {0x549E, 0x02},
++ {0x549F, 0x1C},
++ {0x54A0, 0x02},
++ {0x54A1, 0x04},
++ {0x54A2, 0x01},
++ {0x54A3, 0xED},
++ {0x54A4, 0x01},
++ {0x54A5, 0xC5},
++ {0x54A6, 0x01},
++ {0x54A7, 0xA5},
++ {0x54A8, 0x01},
++ {0x54A9, 0x6C},
++ {0x54AA, 0x01},
++ {0x54AB, 0x41},
++ {0x54AC, 0x01},
++ {0x54AD, 0x20},
++ {0x54AE, 0x00},
++ {0x54AF, 0x16},
++ {0x54B0, 0x01},
++ {0x54B1, 0x20},
++ {0x54B2, 0x00},
++ {0x54B3, 0x10},
++ {0x54B4, 0x00},
++ {0x54B5, 0xf0},
++ {0x54B6, 0x00},
++ {0x54B7, 0xDF},
++ {0x5402, 0x3f},
++ {0x5403, 0x00},
++ {0x5500, 0x10},
++ {0x5502, 0x00},
++ {0x5503, 0x06},
++ {0x5504, 0x00},
++ {0x5505, 0x7f},
++ {0x5025, 0x80},
++ {0x3a0f, 0x48}, //0x30
++ {0x3a10, 0x38}, //0x28
++ {0x3a1b, 0x50}, //0x30
++ {0x3a1e, 0x30}, //0x28
++ {0x3a11, 0x71}, //0x61
++ {0x3a1f, 0x10},
++ {0x5688, 0xfd},
++ {0x5689, 0xdf},
++ {0x568a, 0xfe},
++ {0x568b, 0xef},
++ {0x568c, 0xfe},
++ {0x568d, 0xef},
++ {0x568e, 0xaa},
++ {0x568f, 0xaa},
++
++ {REG_WINDOW_START_X_HIGH, 0x1 },
++ {REG_WINDOW_START_X_LOW, 0x50},
++ //0x150 = 336
++ {REG_WINDOW_START_Y_HIGH, 0x0 },
++ {REG_WINDOW_START_Y_LOW, 0x8 },
++ //0x8 = 8
++ {REG_WINDOW_WIDTH_HIGH, 0x5 },
++ {REG_WINDOW_WIDTH_LOW, 0x0 },
++ //0x500 = 1280
++ {REG_WINDOW_HEIGHT_HIGH, 0x3 },
++ {REG_WINDOW_HEIGHT_LOW, 0xc0},
++ //0x3c0 = 960
++ {REG_OUT_WIDTH_HIGH, 0x5 }, // TIMING DVPHO Bit[3:0] DVP output horizontal width high byte
++ {REG_OUT_WIDTH_LOW, 0x00}, // TIMING DVPHO Bit[7:0] DVP output horizontal width low byte
++ // 0x500 => 1280
++ {REG_OUT_HEIGHT_HIGH, 0x2 }, // TIMING DVPVO Bit[3:0] DVP output vertical height high byte
++// {REG_OUT_HEIGHT_LOW, 0xd0}, // TIMING DVPVO Bit[7:0] DVP output vertical height low byte
++ // 0x2d0 => 720
++ {REG_OUT_HEIGHT_LOW, 0xd5}, // TIMING DVPVO Bit[7:0] DVP output vertical height low byte
++ // 0x2d5 => 725
++ {REG_OUT_TOTAL_WIDTH_HIGH, 0xc }, // TIMING HTS Bit[3:0] Total horizontal size high byte [11:8]
++ {REG_OUT_TOTAL_WIDTH_LOW, 0x80}, // TIMING HTS Bit[7:0] Total horizontal size low byte [7:0]
++ // 0xc80 => 3200
++ {REG_OUT_TOTAL_HEIGHT_HIGH, 0x3 }, // TIMING VTS Bit[3:0] Total vertical size high byte [11:8]
++ {REG_OUT_TOTAL_HEIGHT_LOW, 0xe8}, // TIMING VTS Bit[7:0] Total vertical size low byte [7:0]
++ // 0x3e8 => 1000
++ {REG_ISP_CTRL_01, 0x7f},
++ {REG_AVG_WINDOW_START_X_HIGH, 0x0 },
++ {REG_AVG_WINDOW_START_X_LOW, 0x0 },
++ {REG_AVG_WINDOW_END_X_HIGH, 0x5 },
++ {REG_AVG_WINDOW_END_X_LOW, 0x0 },
++ {REG_AVG_WINDOW_START_Y_HIGH, 0x0 },
++ {REG_AVG_WINDOW_START_Y_LOW, 0x0 },
++ {REG_AVG_WINDOW_END_Y_HIGH, 0x3 },
++ //{REG_AVG_WINDOW_END_Y_LOW, 0xc0},
++ {REG_AVG_WINDOW_END_Y_LOW, 0xc0},
++ {0x3815, 0x02},
++ {0x3503, 0x00},
++ //{0x4730, 0x01},
++ {0x4730, 0x00},
++ {REG_OUTPUT_FORMAT, 0x32},
++
++ {0xffff, 0xff},
++};
+--
+2.7.4
+
diff --git a/bsp/meta-rcar/meta-rcar-gen3-adas/recipes-kernel/linux/linux-renesas/0033-media-soc-camera-fix-parallel-i-f-in-VIN.patch b/bsp/meta-rcar/meta-rcar-gen3-adas/recipes-kernel/linux/linux-renesas/0033-media-soc-camera-fix-parallel-i-f-in-VIN.patch
new file mode 100644
index 00000000..be22dc35
--- /dev/null
+++ b/bsp/meta-rcar/meta-rcar-gen3-adas/recipes-kernel/linux/linux-renesas/0033-media-soc-camera-fix-parallel-i-f-in-VIN.patch
@@ -0,0 +1,69 @@
+From cbe8bbb04c7cff0d4c7cca6ca6b6f28f4998fb2a Mon Sep 17 00:00:00 2001
+From: Vladimir Barinov <vladimir.barinov@cogentembedded.com>
+Date: Fri, 14 Jul 2017 21:55:20 +0300
+Subject: [PATCH 025/122] media: soc_camera: fix parallel i/f in VIN
+
+This fixes parallel interface in VIN
+
+Signed-off-by: Vladimir Barinov <vladimir.barinov@cogentembedded.com>
+---
+ drivers/media/platform/soc_camera/rcar_vin.c | 18 ++++++++++--------
+ 1 file changed, 10 insertions(+), 8 deletions(-)
+
+diff --git a/drivers/media/platform/soc_camera/rcar_vin.c b/drivers/media/platform/soc_camera/rcar_vin.c
+index 9733555..ded9288 100644
+--- a/drivers/media/platform/soc_camera/rcar_vin.c
++++ b/drivers/media/platform/soc_camera/rcar_vin.c
+@@ -154,6 +154,9 @@
+ /* Video n Data Mode Register 2 bits */
+ #define VNDMR2_VPS (1 << 30)
+ #define VNDMR2_HPS (1 << 29)
++#define VNDMR2_CES (1 << 28)
++#define VNDMR2_DES (1 << 27)
++#define VNDMR2_CHS (1 << 23)
+ #define VNDMR2_FTEV (1 << 17)
+ #define VNDMR2_VLV(n) ((n & 0xf) << 12)
+
+@@ -1889,10 +1892,15 @@ static int rcar_vin_set_bus_param(struct soc_camera_device *icd)
+ val = VNDMR2_FTEV;
+ else
+ val = VNDMR2_FTEV | VNDMR2_VLV(1);
++
+ if (!(common_flags & V4L2_MBUS_VSYNC_ACTIVE_LOW))
+ val |= VNDMR2_VPS;
+ if (!(common_flags & V4L2_MBUS_HSYNC_ACTIVE_LOW))
+ val |= VNDMR2_HPS;
++
++ val |= VNDMR2_CES;
++ dev_dbg(icd->parent, "VNDMR2=0x%x\n", val);
++
+ iowrite32(val, priv->base + VNDMR2_REG);
+
+ ret = rcar_vin_set_rect(icd);
+@@ -2989,8 +2997,8 @@ static int rcar_vin_probe(struct platform_device *pdev)
+ priv->max_height = 2048;
+ }
+
+- if (priv->chip == RCAR_H3 || priv->chip == RCAR_M3 ||
+- priv->chip == RCAR_V3M) {
++ if ((priv->chip == RCAR_H3 || priv->chip == RCAR_M3 ||
++ priv->chip == RCAR_V3M) && !of_property_read_string(np, "csi,select", &str)) {
+ u32 ifmd = 0;
+ bool match_flag = false;
+ const struct vin_gen3_ifmd *gen3_ifmd_table = NULL;
+@@ -3025,12 +3033,6 @@ static int rcar_vin_probe(struct platform_device *pdev)
+ else
+ priv->index = RCAR_VIN_CH_NONE;
+
+- ret = of_property_read_string(np, "csi,select", &str);
+- if (ret) {
+- dev_err(&pdev->dev, "could not parse csi,select\n");
+- return ret;
+- }
+-
+ if (strcmp(str, "csi40") == 0)
+ priv->csi_ch = RCAR_CSI40;
+ else if (strcmp(str, "csi20") == 0)
+--
+2.7.4
+
diff --git a/bsp/meta-rcar/meta-rcar-gen3-adas/recipes-kernel/linux/linux-renesas/0034-media-soc_camera-Fix-VIDIOC_S_SELECTION-ioctl-miscal.patch b/bsp/meta-rcar/meta-rcar-gen3-adas/recipes-kernel/linux/linux-renesas/0034-media-soc_camera-Fix-VIDIOC_S_SELECTION-ioctl-miscal.patch
new file mode 100644
index 00000000..ade2361a
--- /dev/null
+++ b/bsp/meta-rcar/meta-rcar-gen3-adas/recipes-kernel/linux/linux-renesas/0034-media-soc_camera-Fix-VIDIOC_S_SELECTION-ioctl-miscal.patch
@@ -0,0 +1,50 @@
+From e9d22a6f30941cad86b22258fd0a467a7b69ede4 Mon Sep 17 00:00:00 2001
+From: Vladimir Barinov <vladimir.barinov@cogentembedded.com>
+Date: Mon, 31 Jul 2017 19:26:05 +0300
+Subject: [PATCH 026/122] media: soc_camera: Fix VIDIOC_S_SELECTION ioctl
+ miscalculation
+
+This patch corrects the miscalculation of the capture buffer
+size and clipping data update in VIDIOC_S_SELECTION sequence.
+
+Patch isbased on work by: Koji Matsuoka <koji.matsuoka.xm@renesas.com>
+
+Signed-off-by: Vladimir Barinov <vladimir.barinov@cogentembedded.com>
+---
+ drivers/media/platform/soc_camera/soc_scale_crop.c | 6 +++---
+ 1 file changed, 3 insertions(+), 3 deletions(-)
+
+diff --git a/drivers/media/platform/soc_camera/soc_scale_crop.c b/drivers/media/platform/soc_camera/soc_scale_crop.c
+index 092c73f..6050f52 100644
+--- a/drivers/media/platform/soc_camera/soc_scale_crop.c
++++ b/drivers/media/platform/soc_camera/soc_scale_crop.c
+@@ -126,6 +126,7 @@ int soc_camera_client_s_selection(struct v4l2_subdev *sd,
+ dev_dbg(dev, "Camera S_SELECTION successful for %dx%d@%d:%d\n",
+ rect->width, rect->height, rect->left, rect->top);
+ *target_rect = *cam_rect;
++ *subrect = *rect;
+ return 0;
+ }
+
+@@ -217,6 +218,7 @@ int soc_camera_client_s_selection(struct v4l2_subdev *sd,
+
+ if (!ret) {
+ *target_rect = *cam_rect;
++ *subrect = *rect;
+ move_and_crop_subrect(target_rect, subrect);
+ }
+
+@@ -297,9 +299,7 @@ static int client_set_fmt(struct soc_camera_device *icd,
+ if (ret < 0)
+ return ret;
+
+- if (host_1to1)
+- *subrect = *rect;
+- else
++ if (!host_1to1)
+ move_and_crop_subrect(rect, subrect);
+
+ return 0;
+--
+2.7.4
+
diff --git a/bsp/meta-rcar/meta-rcar-gen3-adas/recipes-kernel/linux/linux-renesas/0036-Add-MOST-support-for-r8a77965.patch b/bsp/meta-rcar/meta-rcar-gen3-adas/recipes-kernel/linux/linux-renesas/0036-Add-MOST-support-for-r8a77965.patch
new file mode 100644
index 00000000..0ff54d35
--- /dev/null
+++ b/bsp/meta-rcar/meta-rcar-gen3-adas/recipes-kernel/linux/linux-renesas/0036-Add-MOST-support-for-r8a77965.patch
@@ -0,0 +1,100 @@
+From 084e65dfa693df84189b907ab06ec0bac92abc92 Mon Sep 17 00:00:00 2001
+From: Yusuke Goda <yusuke.goda.sx@renesas.com>
+Date: Fri, 26 Oct 2018 15:42:38 +0900
+Subject: [PATCH 027/122] Add MOST support for r8a77965
+
+This adds MOST support to R-Car M3N.
+
+Signed-off-by: Yusuke Goda <yusuke.goda.sx@renesas.com>
+Signed-off-by: Valentine Barshak <valentine.barshak@cogentembedded.com>
+---
+ arch/arm64/boot/dts/renesas/r8a77965.dtsi | 13 +++++++++++++
+ drivers/clk/renesas/r8a77965-cpg-mssr.c | 1 +
+ drivers/pinctrl/sh-pfc/pfc-r8a77965.c | 14 ++++++++++++++
+ 3 files changed, 28 insertions(+)
+
+diff --git a/arch/arm64/boot/dts/renesas/r8a77965.dtsi b/arch/arm64/boot/dts/renesas/r8a77965.dtsi
+index e682d10..b5926ff 100644
+--- a/arch/arm64/boot/dts/renesas/r8a77965.dtsi
++++ b/arch/arm64/boot/dts/renesas/r8a77965.dtsi
+@@ -1188,6 +1188,19 @@
+ status = "disabled";
+ };
+
++ mlp: mlp@ec520000 {
++ compatible = "rcar,medialb-dim2";
++ reg = <0 0xec520000 0 0x800>;
++ interrupts = <GIC_SPI 385 IRQ_TYPE_LEVEL_HIGH>,
++ <GIC_SPI 386 IRQ_TYPE_LEVEL_HIGH>,
++ <GIC_SPI 384 IRQ_TYPE_LEVEL_HIGH>,
++ <GIC_SPI 387 IRQ_TYPE_LEVEL_HIGH>,
++ <GIC_SPI 388 IRQ_TYPE_LEVEL_HIGH>;
++ clocks = <&cpg CPG_MOD 802>;
++ power-domains = <&sysc R8A77965_PD_ALWAYS_ON>;
++ status = "disabled";
++ };
++
+ msiof0: spi@e6e90000 {
+ compatible = "renesas,msiof-r8a77965",
+ "renesas,rcar-gen3-msiof";
+diff --git a/drivers/clk/renesas/r8a77965-cpg-mssr.c b/drivers/clk/renesas/r8a77965-cpg-mssr.c
+index b3b637f..3d4fe53 100644
+--- a/drivers/clk/renesas/r8a77965-cpg-mssr.c
++++ b/drivers/clk/renesas/r8a77965-cpg-mssr.c
+@@ -190,6 +190,7 @@ static const struct mssr_mod_clk r8a77965_mod_clks[] __initconst = {
+ DEF_MOD("lvds", 727, R8A77965_CLK_S2D1),
+ DEF_MOD("hdmi0", 729, R8A77965_CLK_HDMI),
+
++ DEF_MOD("mlp", 802, R8A77965_CLK_S2D1),
+ DEF_MOD("vin7", 804, R8A77965_CLK_S0D2),
+ DEF_MOD("vin6", 805, R8A77965_CLK_S0D2),
+ DEF_MOD("vin5", 806, R8A77965_CLK_S0D2),
+diff --git a/drivers/pinctrl/sh-pfc/pfc-r8a77965.c b/drivers/pinctrl/sh-pfc/pfc-r8a77965.c
+index 8f4b73c..91aa6c0 100644
+--- a/drivers/pinctrl/sh-pfc/pfc-r8a77965.c
++++ b/drivers/pinctrl/sh-pfc/pfc-r8a77965.c
+@@ -2627,6 +2627,14 @@ static const unsigned int intc_ex_irq5_mux[] = {
+ IRQ5_MARK,
+ };
+
++/* - MLB+ ------------------------------------------------------------------- */
++static const unsigned int mlb_3pin_pins[] = {
++ RCAR_GP_PIN(5, 23), RCAR_GP_PIN(5, 24), RCAR_GP_PIN(5, 25),
++};
++static const unsigned int mlb_3pin_mux[] = {
++ MLB_CLK_MARK, MLB_SIG_MARK, MLB_DAT_MARK,
++};
++
+ /* - MSIOF0 ----------------------------------------------------------------- */
+ static const unsigned int msiof0_clk_pins[] = {
+ /* SCK */
+@@ -4562,6 +4570,7 @@ static const struct sh_pfc_pin_group pinmux_groups[] = {
+ SH_PFC_PIN_GROUP(intc_ex_irq3),
+ SH_PFC_PIN_GROUP(intc_ex_irq4),
+ SH_PFC_PIN_GROUP(intc_ex_irq5),
++ SH_PFC_PIN_GROUP(mlb_3pin),
+ SH_PFC_PIN_GROUP(msiof0_clk),
+ SH_PFC_PIN_GROUP(msiof0_sync),
+ SH_PFC_PIN_GROUP(msiof0_ss1),
+@@ -4982,6 +4991,10 @@ static const char * const intc_ex_groups[] = {
+ "intc_ex_irq5",
+ };
+
++static const char * const mlb_3pin_groups[] = {
++ "mlb_3pin",
++};
++
+ static const char * const msiof0_groups[] = {
+ "msiof0_clk",
+ "msiof0_sync",
+@@ -5325,6 +5338,7 @@ static const struct sh_pfc_function pinmux_functions[] = {
+ SH_PFC_FUNCTION(i2c5),
+ SH_PFC_FUNCTION(i2c6),
+ SH_PFC_FUNCTION(intc_ex),
++ SH_PFC_FUNCTION(mlb_3pin),
+ SH_PFC_FUNCTION(msiof0),
+ SH_PFC_FUNCTION(msiof1),
+ SH_PFC_FUNCTION(msiof2),
+--
+2.7.4
+
diff --git a/bsp/meta-rcar/meta-rcar-gen3-adas/recipes-kernel/linux/linux-renesas/0037-media-soc_camera-rcar_vin-Fix-VnCSI_IFMD-settings.patch b/bsp/meta-rcar/meta-rcar-gen3-adas/recipes-kernel/linux/linux-renesas/0037-media-soc_camera-rcar_vin-Fix-VnCSI_IFMD-settings.patch
new file mode 100644
index 00000000..d3afbcf3
--- /dev/null
+++ b/bsp/meta-rcar/meta-rcar-gen3-adas/recipes-kernel/linux/linux-renesas/0037-media-soc_camera-rcar_vin-Fix-VnCSI_IFMD-settings.patch
@@ -0,0 +1,98 @@
+From c6c33a6088a78955da739ceac223843f66052745 Mon Sep 17 00:00:00 2001
+From: Valentine Barshak <valentine.barshak@cogentembedded.com>
+Date: Tue, 6 Nov 2018 15:51:09 +0300
+Subject: [PATCH 028/122] media: soc_camera: rcar_vin: Fix VnCSI_IFMD settings
+
+This makes VnCSI_IFMD DES[01] bit settings identical in both
+probe and resume callbacks. The DES0 bit is set for all SoCs,
+while DES1 bit is reserved on V3M, V3H, and E3.
+
+While at it, also handle the situations when priv->chip
+is not found among supported SoCs.
+
+Signed-off-by: Valentine Barshak <valentine.barshak@cogentembedded.com>
+---
+ drivers/media/platform/soc_camera/rcar_vin.c | 37 ++++++++++++++++++++--------
+ 1 file changed, 27 insertions(+), 10 deletions(-)
+
+diff --git a/drivers/media/platform/soc_camera/rcar_vin.c b/drivers/media/platform/soc_camera/rcar_vin.c
+index ded9288..77c8d6b 100644
+--- a/drivers/media/platform/soc_camera/rcar_vin.c
++++ b/drivers/media/platform/soc_camera/rcar_vin.c
+@@ -2999,7 +2999,7 @@ static int rcar_vin_probe(struct platform_device *pdev)
+
+ if ((priv->chip == RCAR_H3 || priv->chip == RCAR_M3 ||
+ priv->chip == RCAR_V3M) && !of_property_read_string(np, "csi,select", &str)) {
+- u32 ifmd = 0;
++ u32 ifmd;
+ bool match_flag = false;
+ const struct vin_gen3_ifmd *gen3_ifmd_table = NULL;
+ int vc, num;
+@@ -3065,14 +3065,24 @@ static int rcar_vin_probe(struct platform_device *pdev)
+ dev_dbg(&pdev->dev, "csi_ch:%d, vc:%d\n",
+ priv->csi_ch, priv->vc);
+
+- ifmd = VNCSI_IFMD_DES1 | VNCSI_IFMD_DES0;
++ ifmd = VNCSI_IFMD_DES0;
+
+- if (priv->chip == RCAR_H3)
++ switch (priv->chip) {
++ case RCAR_H3:
+ gen3_ifmd_table = vin_h3_vc_ifmd;
+- else if (priv->chip == RCAR_M3)
++ ifmd = VNCSI_IFMD_DES1;
++ break;
++ case RCAR_M3:
+ gen3_ifmd_table = vin_m3_vc_ifmd;
+- else if (priv->chip == RCAR_V3M)
++ ifmd = VNCSI_IFMD_DES1;
++ break;
++ case RCAR_V3M:
+ gen3_ifmd_table = vin_v3_vc_ifmd;
++ break;
++ default:
++ BUG();
++ break;
++ }
+
+ for (i = 0; i < num; i++) {
+ if ((gen3_ifmd_table[i].v_sel[priv->index].csi2_ch
+@@ -3209,7 +3219,7 @@ static int rcar_vin_suspend(struct device *dev)
+
+ static int rcar_vin_resume(struct device *dev)
+ {
+- u32 ifmd = 0;
++ u32 ifmd;
+ bool match_flag = false;
+ const struct vin_gen3_ifmd *gen3_ifmd_table = NULL;
+ int num;
+@@ -3221,15 +3231,22 @@ static int rcar_vin_resume(struct device *dev)
+ ifmd0_init = true;
+ ifmd4_init = true;
+
+- if (priv->chip == RCAR_H3) {
+- ifmd = VNCSI_IFMD_DES1 | VNCSI_IFMD_DES0;
++ ifmd = VNCSI_IFMD_DES0;
++
++ switch (priv->chip) {
++ case RCAR_H3:
+ gen3_ifmd_table = vin_h3_vc_ifmd;
+- } else if (priv->chip == RCAR_M3) {
+ ifmd = VNCSI_IFMD_DES1;
++ break;
++ case RCAR_M3:
+ gen3_ifmd_table = vin_m3_vc_ifmd;
+- } else if (priv->chip == RCAR_V3M) {
+ ifmd = VNCSI_IFMD_DES1;
++ break;
++ case RCAR_V3M:
+ gen3_ifmd_table = vin_v3_vc_ifmd;
++ break;
++ default:
++ return 0;
+ }
+
+ for (i = 0; i < num; i++) {
+--
+2.7.4
+
diff --git a/bsp/meta-rcar/meta-rcar-gen3-adas/recipes-kernel/linux/linux-renesas/0038-media-soc_camera-rcar_vin-Add-R-Car-M3N-support.patch b/bsp/meta-rcar/meta-rcar-gen3-adas/recipes-kernel/linux/linux-renesas/0038-media-soc_camera-rcar_vin-Add-R-Car-M3N-support.patch
new file mode 100644
index 00000000..1c35fead
--- /dev/null
+++ b/bsp/meta-rcar/meta-rcar-gen3-adas/recipes-kernel/linux/linux-renesas/0038-media-soc_camera-rcar_vin-Add-R-Car-M3N-support.patch
@@ -0,0 +1,236 @@
+From d6c2b71e753a46bc72743d09000ca4589da51251 Mon Sep 17 00:00:00 2001
+From: Valentine Barshak <valentine.barshak@cogentembedded.com>
+Date: Tue, 6 Nov 2018 16:02:21 +0300
+Subject: [PATCH 029/122] media: soc_camera: rcar_vin: Add R-Car M3N support
+
+This adds R8A77965 SoC support.
+
+Signed-off-by: Valentine Barshak <valentine.barshak@cogentembedded.com>
+---
+ drivers/media/platform/soc_camera/rcar_vin.c | 98 ++++++++++++++++++++++++----
+ 1 file changed, 86 insertions(+), 12 deletions(-)
+
+diff --git a/drivers/media/platform/soc_camera/rcar_vin.c b/drivers/media/platform/soc_camera/rcar_vin.c
+index 77c8d6b..228bbf3 100644
+--- a/drivers/media/platform/soc_camera/rcar_vin.c
++++ b/drivers/media/platform/soc_camera/rcar_vin.c
+@@ -200,6 +200,7 @@ static int ifmd4_init = true;
+ enum chip_id {
+ RCAR_GEN3,
+ RCAR_V3M,
++ RCAR_M3N,
+ RCAR_M3,
+ RCAR_H3,
+ RCAR_GEN2,
+@@ -375,6 +376,69 @@ static const struct vin_gen3_ifmd vin_m3_vc_ifmd[] = {
+ },
+ };
+
++static const struct vin_gen3_ifmd vin_m3n_vc_ifmd[] = {
++ { 0x0000,
++ {
++ {RCAR_CSI40, RCAR_VIRTUAL_CH0},
++ {RCAR_CSI20, RCAR_VIRTUAL_CH0},
++ {RCAR_CSI20, RCAR_VIRTUAL_CH1},
++ {RCAR_CSI40, RCAR_VIRTUAL_CH1},
++ {RCAR_CSI40, RCAR_VIRTUAL_CH0},
++ {RCAR_CSI20, RCAR_VIRTUAL_CH0},
++ {RCAR_CSI20, RCAR_VIRTUAL_CH1},
++ {RCAR_CSI40, RCAR_VIRTUAL_CH1},
++ }
++ },
++ { 0x0001,
++ {
++ {RCAR_CSI20, RCAR_VIRTUAL_CH0},
++ {RCAR_CSI40, RCAR_VIRTUAL_CH1},
++ {RCAR_CSI40, RCAR_VIRTUAL_CH0},
++ {RCAR_CSI20, RCAR_VIRTUAL_CH1},
++ {RCAR_CSI20, RCAR_VIRTUAL_CH0},
++ {RCAR_CSI40, RCAR_VIRTUAL_CH1},
++ {RCAR_CSI40, RCAR_VIRTUAL_CH0},
++ {RCAR_CSI20, RCAR_VIRTUAL_CH1},
++ }
++ },
++ { 0x0002,
++ {
++ {RCAR_CSI40, RCAR_VIRTUAL_CH1},
++ {RCAR_CSI40, RCAR_VIRTUAL_CH0},
++ {RCAR_CSI20, RCAR_VIRTUAL_CH0},
++ {RCAR_CSI20, RCAR_VIRTUAL_CH1},
++ {RCAR_CSI40, RCAR_VIRTUAL_CH1},
++ {RCAR_CSI40, RCAR_VIRTUAL_CH0},
++ {RCAR_CSI20, RCAR_VIRTUAL_CH0},
++ {RCAR_CSI20, RCAR_VIRTUAL_CH1},
++ }
++ },
++ { 0x0003,
++ {
++ {RCAR_CSI40, RCAR_VIRTUAL_CH0},
++ {RCAR_CSI40, RCAR_VIRTUAL_CH1},
++ {RCAR_CSI40, RCAR_VIRTUAL_CH2},
++ {RCAR_CSI40, RCAR_VIRTUAL_CH3},
++ {RCAR_CSI40, RCAR_VIRTUAL_CH0},
++ {RCAR_CSI40, RCAR_VIRTUAL_CH1},
++ {RCAR_CSI40, RCAR_VIRTUAL_CH2},
++ {RCAR_CSI40, RCAR_VIRTUAL_CH3},
++ }
++ },
++ { 0x0004,
++ {
++ {RCAR_CSI20, RCAR_VIRTUAL_CH0},
++ {RCAR_CSI20, RCAR_VIRTUAL_CH1},
++ {RCAR_CSI20, RCAR_VIRTUAL_CH2},
++ {RCAR_CSI20, RCAR_VIRTUAL_CH3},
++ {RCAR_CSI20, RCAR_VIRTUAL_CH0},
++ {RCAR_CSI20, RCAR_VIRTUAL_CH1},
++ {RCAR_CSI20, RCAR_VIRTUAL_CH2},
++ {RCAR_CSI20, RCAR_VIRTUAL_CH3},
++ }
++ },
++};
++
+ static const struct vin_gen3_ifmd vin_v3_vc_ifmd[] = {
+ { 0x0000,
+ {
+@@ -913,7 +977,7 @@ static int rcar_vin_videobuf_setup(struct vb2_queue *vq,
+ struct rcar_vin_cam *cam = icd->host_priv;
+
+ if (priv->chip == RCAR_H3 || priv->chip == RCAR_M3 ||
+- priv->chip == RCAR_V3M) {
++ priv->chip == RCAR_M3N || priv->chip == RCAR_V3M) {
+ if ((priv->ratio_h > 0x10000) || (priv->ratio_v > 0x10000)) {
+ dev_err(icd->parent, "Scaling rate parameter error\n");
+ return -EINVAL;
+@@ -1022,7 +1086,7 @@ static int rcar_vin_setup(struct rcar_vin_priv *priv)
+ switch (icd->current_fmt->host_fmt->fourcc) {
+ case V4L2_PIX_FMT_NV12:
+ if (priv->chip == RCAR_H3 || priv->chip == RCAR_M3 ||
+- priv->chip == RCAR_V3M) {
++ priv->chip == RCAR_M3N || priv->chip == RCAR_V3M) {
+ iowrite32(ALIGN((cam->out_width * cam->out_height),
+ 0x80), priv->base + VNUVAOF_REG);
+ dmr = VNDMR_DTMD_YCSEP_YCBCR420;
+@@ -1058,7 +1122,7 @@ static int rcar_vin_setup(struct rcar_vin_priv *priv)
+ break;
+ case V4L2_PIX_FMT_XBGR32:
+ if (priv->chip != RCAR_H3 && priv->chip != RCAR_M3 &&
+- priv->chip != RCAR_V3M &&
++ priv->chip != RCAR_M3N && priv->chip != RCAR_V3M &&
+ priv->chip != RCAR_GEN2 && priv->chip != RCAR_H1 &&
+ priv->chip != RCAR_E1)
+ goto e_format;
+@@ -1067,7 +1131,7 @@ static int rcar_vin_setup(struct rcar_vin_priv *priv)
+ break;
+ case V4L2_PIX_FMT_ABGR32:
+ if (priv->chip != RCAR_H3 && priv->chip != RCAR_M3 &&
+- priv->chip != RCAR_V3M)
++ priv->chip != RCAR_M3N && priv->chip != RCAR_V3M)
+ goto e_format;
+
+ dmr = VNDMR_EXRGB | VNDMR_DTMD_ARGB;
+@@ -1088,7 +1152,7 @@ static int rcar_vin_setup(struct rcar_vin_priv *priv)
+ vnmc |= VNMC_BPS;
+
+ if (priv->chip == RCAR_H3 || priv->chip == RCAR_M3 ||
+- priv->chip == RCAR_V3M) {
++ priv->chip == RCAR_M3N || priv->chip == RCAR_V3M) {
+ if (priv->pdata_flags & RCAR_VIN_CSI2)
+ vnmc &= ~VNMC_DPINE;
+ else
+@@ -1459,7 +1523,7 @@ static int rcar_vin_add_device(struct soc_camera_device *icd)
+ pm_runtime_get_sync(ici->v4l2_dev.dev);
+
+ if (priv->chip == RCAR_H3 || priv->chip == RCAR_M3 ||
+- priv->chip == RCAR_V3M) {
++ priv->chip == RCAR_M3N || priv->chip == RCAR_V3M) {
+ struct v4l2_subdev *csi2_sd = find_csi2(priv);
+ struct v4l2_subdev *deser_sd = find_deser(priv);
+ int ret = 0;
+@@ -1722,7 +1786,7 @@ static int rcar_vin_set_rect(struct soc_camera_device *icd)
+ }
+
+ if (priv->chip == RCAR_H3 || priv->chip == RCAR_M3 ||
+- priv->chip == RCAR_V3M) {
++ priv->chip == RCAR_M3N || priv->chip == RCAR_V3M) {
+ if ((icd->current_fmt->host_fmt->fourcc != V4L2_PIX_FMT_NV12) &&
+ (icd->current_fmt->host_fmt->fourcc != V4L2_PIX_FMT_SBGGR8) &&
+ (icd->current_fmt->host_fmt->fourcc != V4L2_PIX_FMT_SBGGR12)
+@@ -1880,7 +1944,7 @@ static int rcar_vin_set_bus_param(struct soc_camera_device *icd)
+ return ret;
+
+ if (priv->chip == RCAR_H3 || priv->chip == RCAR_M3 ||
+- priv->chip == RCAR_V3M) {
++ priv->chip == RCAR_M3N || priv->chip == RCAR_V3M) {
+ if (cfg.type == V4L2_MBUS_CSI2)
+ vnmc &= ~VNMC_DPINE;
+ else
+@@ -1888,7 +1952,7 @@ static int rcar_vin_set_bus_param(struct soc_camera_device *icd)
+ }
+
+ if (priv->chip == RCAR_H3 || priv->chip == RCAR_M3 ||
+- priv->chip == RCAR_V3M)
++ priv->chip == RCAR_M3N || priv->chip == RCAR_V3M)
+ val = VNDMR2_FTEV;
+ else
+ val = VNDMR2_FTEV | VNDMR2_VLV(1);
+@@ -2486,7 +2550,7 @@ static int rcar_vin_try_fmt(struct soc_camera_device *icd,
+ return ret;
+
+ if (priv->chip == RCAR_H3 || priv->chip == RCAR_M3 ||
+- priv->chip == RCAR_V3M) {
++ priv->chip == RCAR_M3N || priv->chip == RCAR_V3M) {
+ /* Adjust max scaling size for Gen3 */
+ if (pix->width > 4096)
+ pix->width = priv->max_width;
+@@ -2666,6 +2730,7 @@ static struct soc_camera_host_ops rcar_vin_host_ops = {
+ #ifdef CONFIG_OF
+ static const struct of_device_id rcar_vin_of_table[] = {
+ { .compatible = "renesas,vin-r8a7797", .data = (void *)RCAR_V3M },
++ { .compatible = "renesas,vin-r8a77965", .data = (void *)RCAR_M3N },
+ { .compatible = "renesas,vin-r8a7796", .data = (void *)RCAR_M3 },
+ { .compatible = "renesas,vin-r8a7795", .data = (void *)RCAR_H3 },
+ { .compatible = "renesas,vin-r8a7794", .data = (void *)RCAR_GEN2 },
+@@ -2989,7 +3054,7 @@ static int rcar_vin_probe(struct platform_device *pdev)
+ }
+
+ if (priv->chip == RCAR_H3 || priv->chip == RCAR_M3 ||
+- priv->chip == RCAR_V3M) {
++ priv->chip == RCAR_M3N || priv->chip == RCAR_V3M) {
+ priv->max_width = 4096;
+ priv->max_height = 4096;
+ } else {
+@@ -2998,7 +3063,8 @@ static int rcar_vin_probe(struct platform_device *pdev)
+ }
+
+ if ((priv->chip == RCAR_H3 || priv->chip == RCAR_M3 ||
+- priv->chip == RCAR_V3M) && !of_property_read_string(np, "csi,select", &str)) {
++ priv->chip == RCAR_M3N || priv->chip == RCAR_V3M) &&
++ !of_property_read_string(np, "csi,select", &str)) {
+ u32 ifmd;
+ bool match_flag = false;
+ const struct vin_gen3_ifmd *gen3_ifmd_table = NULL;
+@@ -3076,6 +3142,10 @@ static int rcar_vin_probe(struct platform_device *pdev)
+ gen3_ifmd_table = vin_m3_vc_ifmd;
+ ifmd = VNCSI_IFMD_DES1;
+ break;
++ case RCAR_M3N:
++ gen3_ifmd_table = vin_m3n_vc_ifmd;
++ ifmd = VNCSI_IFMD_DES1;
++ break;
+ case RCAR_V3M:
+ gen3_ifmd_table = vin_v3_vc_ifmd;
+ break;
+@@ -3242,6 +3312,10 @@ static int rcar_vin_resume(struct device *dev)
+ gen3_ifmd_table = vin_m3_vc_ifmd;
+ ifmd = VNCSI_IFMD_DES1;
+ break;
++ case RCAR_M3N:
++ gen3_ifmd_table = vin_m3n_vc_ifmd;
++ ifmd = VNCSI_IFMD_DES1;
++ break;
+ case RCAR_V3M:
+ gen3_ifmd_table = vin_v3_vc_ifmd;
+ break;
+--
+2.7.4
+
diff --git a/bsp/meta-rcar/meta-rcar-gen3-adas/recipes-kernel/linux/linux-renesas/0039-media-soc_camera-rcar_csi2-Add-R-Car-M3N-support.patch b/bsp/meta-rcar/meta-rcar-gen3-adas/recipes-kernel/linux/linux-renesas/0039-media-soc_camera-rcar_csi2-Add-R-Car-M3N-support.patch
new file mode 100644
index 00000000..262517fa
--- /dev/null
+++ b/bsp/meta-rcar/meta-rcar-gen3-adas/recipes-kernel/linux/linux-renesas/0039-media-soc_camera-rcar_csi2-Add-R-Car-M3N-support.patch
@@ -0,0 +1,49 @@
+From 94708fd89d1dc5a22177e30a15752d25287157eb Mon Sep 17 00:00:00 2001
+From: Valentine Barshak <valentine.barshak@cogentembedded.com>
+Date: Tue, 6 Nov 2018 16:03:30 +0300
+Subject: [PATCH 030/122] media: soc_camera: rcar_csi2: Add R-Car M3N support
+
+This adds R8A77965 SoC support.
+
+Signed-off-by: Valentine Barshak <valentine.barshak@cogentembedded.com>
+---
+ drivers/media/platform/soc_camera/Kconfig | 2 +-
+ drivers/media/platform/soc_camera/rcar_csi2.c | 2 ++
+ 2 files changed, 3 insertions(+), 1 deletion(-)
+
+diff --git a/drivers/media/platform/soc_camera/Kconfig b/drivers/media/platform/soc_camera/Kconfig
+index a3bf60d..6616d59 100644
+--- a/drivers/media/platform/soc_camera/Kconfig
++++ b/drivers/media/platform/soc_camera/Kconfig
+@@ -39,7 +39,7 @@ config VIDEO_RCAR_VIN_LEGACY_DEBUG
+ config VIDEO_RCAR_CSI2_LEGACY
+ tristate "R-Car MIPI CSI-2 Interface driver"
+ depends on VIDEO_DEV && SOC_CAMERA && HAVE_CLK
+- depends on ARCH_R8A7795 || ARCH_R8A7796 || COMPILE_TEST
++ depends on ARCH_R8A7795 || ARCH_R8A7796 || ARCH_R8A77965 || COMPILE_TEST
+ select V4L2_FWNODE
+ ---help---
+ This is a v4l2 driver for the R-Car CSI-2 Interface
+diff --git a/drivers/media/platform/soc_camera/rcar_csi2.c b/drivers/media/platform/soc_camera/rcar_csi2.c
+index 2e710e3..384d7e9 100644
+--- a/drivers/media/platform/soc_camera/rcar_csi2.c
++++ b/drivers/media/platform/soc_camera/rcar_csi2.c
+@@ -613,6 +613,7 @@ static struct v4l2_subdev_ops rcar_csi2_subdev_ops = {
+ #ifdef CONFIG_OF
+ static const struct of_device_id rcar_csi2_of_table[] = {
+ { .compatible = "renesas,r8a7797-csi2", .data = (void *)RCAR_GEN3 },
++ { .compatible = "renesas,r8a77965-csi2", .data = (void *)RCAR_GEN3 },
+ { .compatible = "renesas,r8a7796-csi2", .data = (void *)RCAR_GEN3 },
+ { .compatible = "renesas,r8a7795-csi2", .data = (void *)RCAR_GEN3 },
+ { },
+@@ -622,6 +623,7 @@ MODULE_DEVICE_TABLE(of, rcar_csi2_of_table);
+
+ static struct platform_device_id rcar_csi2_id_table[] = {
+ { "r8a7797-csi2", RCAR_GEN3 },
++ { "r8a77965-csi2", RCAR_GEN3 },
+ { "r8a7796-csi2", RCAR_GEN3 },
+ { "r8a7795-csi2", RCAR_GEN3 },
+ {},
+--
+2.7.4
+
diff --git a/bsp/meta-rcar/meta-rcar-gen3-adas/recipes-kernel/linux/linux-renesas/0040-arm64-dts-renesas-add-ADAS-boards.patch b/bsp/meta-rcar/meta-rcar-gen3-adas/recipes-kernel/linux/linux-renesas/0040-arm64-dts-renesas-add-ADAS-boards.patch
new file mode 100644
index 00000000..08922ed1
--- /dev/null
+++ b/bsp/meta-rcar/meta-rcar-gen3-adas/recipes-kernel/linux/linux-renesas/0040-arm64-dts-renesas-add-ADAS-boards.patch
@@ -0,0 +1,13885 @@
+From dc3cc58aeac5bb30a7e8ebd50dd81a7249756a01 Mon Sep 17 00:00:00 2001
+From: Vladimir Barinov <vladimir.barinov@cogentembedded.com>
+Date: Fri, 14 Jul 2017 15:05:42 +0300
+Subject: [PATCH 031/122] arm64: dts: renesas: add ADAS boards
+
+Salvator-X.View board on R8A7795 ES1.x SoC
+Salvator-X.View board on R8A7795 SoC
+Salvator-X.View board on R8A7796 SoC
+H3ULCB.View board on R8A7795 ES1.x SoC
+H3ULCB.View board on R8A7795 SoC
+M3ULCB.View board on R8A7796 SoC
+H3ULCB.HAD board on R8A7795 ES1.x SoC
+H3ULCB.HAD board on R8A7795 SoC
+Kingfisher board on R8A7795 ES1.x SoC
+Kingfisher board on R8A7795 SoC
+Kingfisher board on R8A7796 SoC
+Kingfisher board on R8A77965 SoC
+Kingfisher board on R8A77970 ES1.0/2.0 SoC
+Videobox board on R8A7795 ES1.x SoC
+Videobox board on R8A7795 SoC
+Eagle board on R8A77970 ES1.0/2.0 SoC
+Eagle Function board on R8A77970 ES1.0/2.0 SoC
+V3MSK board on R8A77970 ES1.0/2.0 SoC
+V3MSK.View board on R8A77970 ES1.0/2.0 SoC
+V3MZF board on R8A77970 SoC
+Videobox Mini board on R8A7795 ES1.x SoC
+Videobox Mini board on R8A7795 SoC
+Videobox Mini board on R8A77970 ES1.0/2.0 SoC
+Videobox Mini V2 board on R8A77970 ES1.0/2.0 SoC
+Videobox2 board on R8A7795 ES1.x SoC
+Videobox2 board on R8A7795 SoC
+Condor board on R8A77980 SoC
+V3HSK board on R8A77980 SoC
+Videobox Mini board on R8A77980 SoC
+Videobox Mini V2 board on R8A77980 SoC
+
+Signed-off-by: Vladimir Barinov <vladimir.barinov@cogentembedded.com>
+---
+ arch/arm64/boot/dts/renesas/Makefile | 23 +
+ .../dts/renesas/r8a7795-es1-h3ulcb-had-alfa.dts | 22 +
+ .../dts/renesas/r8a7795-es1-h3ulcb-had-beta.dts | 23 +
+ .../boot/dts/renesas/r8a7795-es1-h3ulcb-had.dtsi | 202 +++
+ .../boot/dts/renesas/r8a7795-es1-h3ulcb-kf.dts | 25 +
+ .../boot/dts/renesas/r8a7795-es1-h3ulcb-vb.dts | 69 +
+ .../boot/dts/renesas/r8a7795-es1-h3ulcb-vb2.dts | 77 +
+ .../boot/dts/renesas/r8a7795-es1-h3ulcb-vbm.dts | 26 +
+ .../boot/dts/renesas/r8a7795-es1-h3ulcb-view.dts | 544 +++++++
+ .../dts/renesas/r8a7795-es1-salvator-x-view.dts | 550 +++++++
+ .../boot/dts/renesas/r8a7795-h3ulcb-4x2g-kf.dts | 44 +
+ .../boot/dts/renesas/r8a7795-h3ulcb-4x2g-vb.dts | 68 +
+ .../boot/dts/renesas/r8a7795-h3ulcb-4x2g-vb2.dts | 68 +
+ .../boot/dts/renesas/r8a7795-h3ulcb-4x2g-vbm.dts | 26 +
+ .../boot/dts/renesas/r8a7795-h3ulcb-had-alfa.dts | 22 +
+ .../boot/dts/renesas/r8a7795-h3ulcb-had-beta.dts | 23 +
+ .../arm64/boot/dts/renesas/r8a7795-h3ulcb-had.dtsi | 196 +++
+ arch/arm64/boot/dts/renesas/r8a7795-h3ulcb-kf.dts | 25 +
+ arch/arm64/boot/dts/renesas/r8a7795-h3ulcb-vb.dts | 68 +
+ arch/arm64/boot/dts/renesas/r8a7795-h3ulcb-vb2.dts | 68 +
+ arch/arm64/boot/dts/renesas/r8a7795-h3ulcb-vbm.dts | 26 +
+ .../arm64/boot/dts/renesas/r8a7795-h3ulcb-view.dts | 544 +++++++
+ .../boot/dts/renesas/r8a7795-salvator-x-view.dts | 550 +++++++
+ arch/arm64/boot/dts/renesas/r8a7796-m3ulcb-kf.dts | 26 +
+ .../arm64/boot/dts/renesas/r8a7796-m3ulcb-view.dts | 286 ++++
+ .../boot/dts/renesas/r8a7796-salvator-x-view.dts | 317 ++++
+ .../arm64/boot/dts/renesas/r8a77965-m3nulcb-kf.dts | 41 +
+ .../boot/dts/renesas/r8a77970-eagle-function.dts | 62 +
+ arch/arm64/boot/dts/renesas/r8a77970-eagle.dts | 356 +++++
+ .../dts/renesas/r8a77970-es1-eagle-function.dts | 17 +
+ arch/arm64/boot/dts/renesas/r8a77970-es1-eagle.dts | 17 +
+ .../boot/dts/renesas/r8a77970-es1-v3msk-kf.dts | 17 +
+ .../boot/dts/renesas/r8a77970-es1-v3msk-vbm-v2.dts | 17 +
+ .../boot/dts/renesas/r8a77970-es1-v3msk-vbm.dts | 17 +
+ .../boot/dts/renesas/r8a77970-es1-v3msk-view.dts | 17 +
+ arch/arm64/boot/dts/renesas/r8a77970-es1-v3msk.dts | 17 +
+ arch/arm64/boot/dts/renesas/r8a77970-es1.dtsi | 116 ++
+ arch/arm64/boot/dts/renesas/r8a77970-v3msk-kf.dts | 519 +++++++
+ .../boot/dts/renesas/r8a77970-v3msk-vbm-v2.dts | 82 +
+ arch/arm64/boot/dts/renesas/r8a77970-v3msk-vbm.dts | 507 ++++++
+ .../arm64/boot/dts/renesas/r8a77970-v3msk-view.dts | 297 ++++
+ arch/arm64/boot/dts/renesas/r8a77970-v3msk.dts | 71 +
+ arch/arm64/boot/dts/renesas/r8a77970-v3mzf.dts | 442 ++++++
+ arch/arm64/boot/dts/renesas/r8a77980-condor.dts | 40 +
+ .../boot/dts/renesas/r8a77980-v3hsk-vbm-v2.dts | 73 +
+ arch/arm64/boot/dts/renesas/r8a77980-v3hsk-vbm.dts | 505 ++++++
+ arch/arm64/boot/dts/renesas/r8a77980-v3hsk.dts | 41 +
+ arch/arm64/boot/dts/renesas/ulcb-kf-cn11.dtsi | 462 ++++++
+ arch/arm64/boot/dts/renesas/ulcb-kf-most.dtsi | 30 +
+ arch/arm64/boot/dts/renesas/ulcb-kf-sd3.dtsi | 46 +
+ arch/arm64/boot/dts/renesas/ulcb-kf.dtsi | 1272 ++++++++++++++-
+ arch/arm64/boot/dts/renesas/ulcb-vb-cn12.dtsi | 459 ++++++
+ arch/arm64/boot/dts/renesas/ulcb-vb.dtsi | 1591 +++++++++++++++++++
+ arch/arm64/boot/dts/renesas/ulcb-vb2.dtsi | 1641 ++++++++++++++++++++
+ arch/arm64/boot/dts/renesas/ulcb-vbm.dtsi | 523 +++++++
+ 55 files changed, 13210 insertions(+), 3 deletions(-)
+ create mode 100644 arch/arm64/boot/dts/renesas/r8a7795-es1-h3ulcb-had-alfa.dts
+ create mode 100644 arch/arm64/boot/dts/renesas/r8a7795-es1-h3ulcb-had-beta.dts
+ create mode 100644 arch/arm64/boot/dts/renesas/r8a7795-es1-h3ulcb-had.dtsi
+ create mode 100644 arch/arm64/boot/dts/renesas/r8a7795-es1-h3ulcb-vb.dts
+ create mode 100644 arch/arm64/boot/dts/renesas/r8a7795-es1-h3ulcb-vb2.dts
+ create mode 100644 arch/arm64/boot/dts/renesas/r8a7795-es1-h3ulcb-vbm.dts
+ create mode 100644 arch/arm64/boot/dts/renesas/r8a7795-es1-h3ulcb-view.dts
+ create mode 100644 arch/arm64/boot/dts/renesas/r8a7795-es1-salvator-x-view.dts
+ create mode 100644 arch/arm64/boot/dts/renesas/r8a7795-h3ulcb-4x2g-kf.dts
+ create mode 100644 arch/arm64/boot/dts/renesas/r8a7795-h3ulcb-4x2g-vb.dts
+ create mode 100644 arch/arm64/boot/dts/renesas/r8a7795-h3ulcb-4x2g-vb2.dts
+ create mode 100644 arch/arm64/boot/dts/renesas/r8a7795-h3ulcb-4x2g-vbm.dts
+ create mode 100644 arch/arm64/boot/dts/renesas/r8a7795-h3ulcb-had-alfa.dts
+ create mode 100644 arch/arm64/boot/dts/renesas/r8a7795-h3ulcb-had-beta.dts
+ create mode 100644 arch/arm64/boot/dts/renesas/r8a7795-h3ulcb-had.dtsi
+ create mode 100644 arch/arm64/boot/dts/renesas/r8a7795-h3ulcb-vb.dts
+ create mode 100644 arch/arm64/boot/dts/renesas/r8a7795-h3ulcb-vb2.dts
+ create mode 100644 arch/arm64/boot/dts/renesas/r8a7795-h3ulcb-vbm.dts
+ create mode 100644 arch/arm64/boot/dts/renesas/r8a7795-h3ulcb-view.dts
+ create mode 100644 arch/arm64/boot/dts/renesas/r8a7795-salvator-x-view.dts
+ create mode 100644 arch/arm64/boot/dts/renesas/r8a7796-m3ulcb-view.dts
+ create mode 100644 arch/arm64/boot/dts/renesas/r8a7796-salvator-x-view.dts
+ create mode 100644 arch/arm64/boot/dts/renesas/r8a77965-m3nulcb-kf.dts
+ create mode 100644 arch/arm64/boot/dts/renesas/r8a77970-eagle-function.dts
+ create mode 100644 arch/arm64/boot/dts/renesas/r8a77970-es1-eagle-function.dts
+ create mode 100644 arch/arm64/boot/dts/renesas/r8a77970-es1-eagle.dts
+ create mode 100644 arch/arm64/boot/dts/renesas/r8a77970-es1-v3msk-kf.dts
+ create mode 100644 arch/arm64/boot/dts/renesas/r8a77970-es1-v3msk-vbm-v2.dts
+ create mode 100644 arch/arm64/boot/dts/renesas/r8a77970-es1-v3msk-vbm.dts
+ create mode 100644 arch/arm64/boot/dts/renesas/r8a77970-es1-v3msk-view.dts
+ create mode 100644 arch/arm64/boot/dts/renesas/r8a77970-es1-v3msk.dts
+ create mode 100644 arch/arm64/boot/dts/renesas/r8a77970-es1.dtsi
+ create mode 100644 arch/arm64/boot/dts/renesas/r8a77970-v3msk-kf.dts
+ create mode 100644 arch/arm64/boot/dts/renesas/r8a77970-v3msk-vbm-v2.dts
+ create mode 100644 arch/arm64/boot/dts/renesas/r8a77970-v3msk-vbm.dts
+ create mode 100644 arch/arm64/boot/dts/renesas/r8a77970-v3msk-view.dts
+ create mode 100644 arch/arm64/boot/dts/renesas/r8a77970-v3mzf.dts
+ create mode 100644 arch/arm64/boot/dts/renesas/r8a77980-v3hsk-vbm-v2.dts
+ create mode 100644 arch/arm64/boot/dts/renesas/r8a77980-v3hsk-vbm.dts
+ create mode 100644 arch/arm64/boot/dts/renesas/ulcb-kf-cn11.dtsi
+ create mode 100644 arch/arm64/boot/dts/renesas/ulcb-kf-most.dtsi
+ create mode 100644 arch/arm64/boot/dts/renesas/ulcb-kf-sd3.dtsi
+ create mode 100644 arch/arm64/boot/dts/renesas/ulcb-vb-cn12.dtsi
+ create mode 100644 arch/arm64/boot/dts/renesas/ulcb-vb.dtsi
+ create mode 100644 arch/arm64/boot/dts/renesas/ulcb-vb2.dtsi
+ create mode 100644 arch/arm64/boot/dts/renesas/ulcb-vbm.dtsi
+
+diff --git a/arch/arm64/boot/dts/renesas/Makefile b/arch/arm64/boot/dts/renesas/Makefile
+index b9f6bf0..e7fc36e 100644
+--- a/arch/arm64/boot/dts/renesas/Makefile
++++ b/arch/arm64/boot/dts/renesas/Makefile
+@@ -20,4 +20,27 @@ dtb-$(CONFIG_ARCH_R8A77990) += r8a77990-ebisu-4d.dtb
+ dtb-$(CONFIG_ARCH_R8A77990) += r8a77990-es10-ebisu.dtb r8a77990-es10-ebisu-4d.dtb
+ dtb-$(CONFIG_ARCH_R8A77995) += r8a77995-draak.dtb
+
++# ADAS boards
++dtb-$(CONFIG_ARCH_R8A7796) += r8a7796-salvator-x-view.dtb
++dtb-$(CONFIG_ARCH_R8A7796) += r8a7796-m3ulcb-view.dtb
++dtb-$(CONFIG_ARCH_R8A7796) += r8a7796-m3ulcb-kf.dtb
++dtb-$(CONFIG_ARCH_R8A7795) += r8a7795-salvator-x-view.dtb r8a7795-es1-salvator-x-view.dtb
++dtb-$(CONFIG_ARCH_R8A7795) += r8a7795-h3ulcb-view.dtb r8a7795-es1-h3ulcb-view.dtb
++dtb-$(CONFIG_ARCH_R8A7795) += r8a7795-h3ulcb-had-alfa.dtb r8a7795-h3ulcb-had-beta.dtb r8a7795-es1-h3ulcb-had-alfa.dtb r8a7795-es1-h3ulcb-had-beta.dtb
++dtb-$(CONFIG_ARCH_R8A7795) += r8a7795-h3ulcb-kf.dtb r8a7795-es1-h3ulcb-kf.dtb r8a7795-h3ulcb-4x2g-kf.dtb
++dtb-$(CONFIG_ARCH_R8A7795) += r8a7795-h3ulcb-vb.dtb r8a7795-es1-h3ulcb-vb.dtb r8a7795-h3ulcb-4x2g-vb.dtb
++dtb-$(CONFIG_ARCH_R8A7795) += r8a7795-h3ulcb-vb2.dtb r8a7795-es1-h3ulcb-vb2.dtb r8a7795-h3ulcb-4x2g-vb2.dtb
++dtb-$(CONFIG_ARCH_R8A7795) += r8a7795-h3ulcb-vbm.dtb r8a7795-es1-h3ulcb-vbm.dtb r8a7795-h3ulcb-4x2g-vbm.dtb
++dtb-$(CONFIG_ARCH_R8A77965) += r8a77965-m3nulcb-kf.dtb
++#dtb-$(CONFIG_ARCH_R8A77970) += r8a77970-eagle-function.dtb
++#dtb-$(CONFIG_ARCH_R8A77970) += r8a77970-es1-eagle.dtb r8a77970-es1-eagle-function.dtb
++#dtb-$(CONFIG_ARCH_R8A77970) += r8a77970-es1-v3msk.dtb
++#dtb-$(CONFIG_ARCH_R8A77970) += r8a77970-v3msk-view.dtb r8a77970-es1-v3msk-view.dtb
++#dtb-$(CONFIG_ARCH_R8A77970) += r8a77970-v3msk-kf.dtb r8a77970-es1-v3msk-kf.dtb
++#dtb-$(CONFIG_ARCH_R8A77970) += r8a77970-v3msk-vbm.dtb r8a77970-es1-v3msk-vbm.dtb
++#dtb-$(CONFIG_ARCH_R8A77970) += r8a77970-v3msk-vbm-v2.dtb r8a77970-es1-v3msk-vbm-v2.dtb
++#dtb-$(CONFIG_ARCH_R8A77970) += r8a77970-v3mzf.dtb
++#dtb-$(CONFIG_ARCH_R8A77980) += r8a77980-v3hsk-vbm.dtb
++#dtb-$(CONFIG_ARCH_R8A77980) += r8a77980-v3hsk-vbm-v2.dtb
++
+ always := $(dtb-y)
+diff --git a/arch/arm64/boot/dts/renesas/r8a7795-es1-h3ulcb-had-alfa.dts b/arch/arm64/boot/dts/renesas/r8a7795-es1-h3ulcb-had-alfa.dts
+new file mode 100644
+index 0000000..6b13f07
+--- /dev/null
++++ b/arch/arm64/boot/dts/renesas/r8a7795-es1-h3ulcb-had-alfa.dts
+@@ -0,0 +1,22 @@
++/*
++ * Device Tree Source for the H3ULCB.HAD board Alfa side on r8a7795 ES1.x
++ *
++ * Copyright (C) 2017 Renesas Electronics Corp.
++ * Copyright (C) 2017 Cogent Embedded, Inc.
++ *
++ * This file is licensed under the terms of the GNU General Public License
++ * version 2. This program is licensed "as is" without any warranty of any
++ * kind, whether express or implied.
++ */
++
++#include "r8a7795-es1-h3ulcb-had.dtsi"
++
++/ {
++ model = "Renesas H3ULCB.HAD board Alfa side based on r8a7795";
++};
++
++&pciec0 {
++ status = "okay";
++
++ /* Root complex */
++};
+diff --git a/arch/arm64/boot/dts/renesas/r8a7795-es1-h3ulcb-had-beta.dts b/arch/arm64/boot/dts/renesas/r8a7795-es1-h3ulcb-had-beta.dts
+new file mode 100644
+index 0000000..2f8b274
+--- /dev/null
++++ b/arch/arm64/boot/dts/renesas/r8a7795-es1-h3ulcb-had-beta.dts
+@@ -0,0 +1,23 @@
++/*
++ * Device Tree Source for the H3ULCB.HAD board Beta side on r8a7795 ES1.x
++ *
++ * Copyright (C) 2017 Renesas Electronics Corp.
++ * Copyright (C) 2017 Cogent Embedded, Inc.
++ *
++ * This file is licensed under the terms of the GNU General Public License
++ * version 2. This program is licensed "as is" without any warranty of any
++ * kind, whether express or implied.
++ */
++
++#include "r8a7795-es1-h3ulcb-had.dtsi"
++
++/ {
++ model = "Renesas H3ULCB.HAD board Beta side based on r8a7795";
++};
++
++&pciec0 {
++ status = "okay";
++
++ /* Endpoint */
++ endpoint;
++};
+diff --git a/arch/arm64/boot/dts/renesas/r8a7795-es1-h3ulcb-had.dtsi b/arch/arm64/boot/dts/renesas/r8a7795-es1-h3ulcb-had.dtsi
+new file mode 100644
+index 0000000..484d97a
+--- /dev/null
++++ b/arch/arm64/boot/dts/renesas/r8a7795-es1-h3ulcb-had.dtsi
+@@ -0,0 +1,202 @@
++/*
++ * Device Tree Source for the H3ULCB.HAD board on r8a7795 ES1.x
++ *
++ * Copyright (C) 2016-2017 Renesas Electronics Corp.
++ * Copyright (C) 2016-2017 Cogent Embedded, Inc.
++ *
++ * This file is licensed under the terms of the GNU General Public License
++ * version 2. This program is licensed "as is" without any warranty of any
++ * kind, whether express or implied.
++ */
++
++/*
++ * MSIOF0 - /dev/spidev1.0 connected to FPGA ethernet switch (both sides)
++ * MSIOF1 - /dev/spidev2.0 connected to RH850 (sideA to CSIH1, sideB to CSIH0)
++ */
++
++#include "r8a7795-es1-h3ulcb-view.dts"
++
++/ {
++ model = "Renesas H3ULCB.HAD board based on r8a7795";
++
++ aliases {
++ serial0 = &scif1;
++ spi1 = &spi0_gpio;
++ spi2 = &spi1_gpio;
++ };
++
++ spi0_gpio: spi_gpio@0 {
++ compatible = "spi-gpio";
++ num-chipselects = <1>;
++ gpio-sck = <&gpio5 17 0>;
++ gpio-mosi = <&gpio5 20 0>;
++ gpio-miso = <&gpio5 22 0>;
++ cs-gpios = <&gpio5 19 0>;
++ #address-cells = <1>;
++ #size-cells = <0>;
++
++ spidev@0 {
++ compatible = "spi-gpio";
++ reg = <0>;
++ spi-max-frequency = <2000000>;
++ spi-cpha;
++ spi-cpol;
++ };
++ };
++
++ spi1_gpio: spi_gpio@1 {
++ compatible = "spi-gpio";
++ num-chipselects = <1>;
++ gpio-sck = <&gpio6 8 0>;
++ gpio-mosi = <&gpio6 7 0>;
++ gpio-miso = <&gpio6 10 0>;
++ cs-gpios = <&gpio6 5 0>;
++ #address-cells = <1>;
++ #size-cells = <0>;
++
++ spidev@0 {
++ compatible = "spi-gpio";
++ reg = <0>;
++ spi-max-frequency = <2000000>;
++ spi-cpha;
++ spi-cpol;
++ };
++ };
++
++ hdmi1-out {
++ compatible = "hdmi-connector";
++ label = "HDMI1 OUT";
++ type = "a";
++
++ port {
++ hdmi1_con: endpoint {
++ };
++ };
++ };
++};
++
++&hdmi1 {
++ status = "okay";
++
++ ports {
++ port@1 {
++ reg = <1>;
++ rcar_dw_hdmi1_out: endpoint {
++ remote-endpoint = <&hdmi1_con>;
++ };
++ };
++ };
++};
++
++&hdmi1_con {
++ remote-endpoint = <&rcar_dw_hdmi1_out>;
++};
++
++&pfc {
++ scif1_pins: scif1 {
++ groups = "scif1_data_a";
++ function = "scif1";
++ };
++
++ msiof0_pins: spi1 {
++ groups = "msiof0_clk", "msiof0_rxd", "msiof0_txd",
++ "msiof0_ss1";
++ function = "msiof0";
++ };
++
++ msiof1_pins: spi2 {
++ groups = "msiof1_clk_a", "msiof1_rxd_a", "msiof1_txd_a",
++ "msiof1_ss1_a";
++ function = "msiof1";
++ };
++
++ sound_clk_pins: sound-clk {
++ groups = "audio_clk_a_a", "audio_clk_b_a", "audio_clk_c_a",
++ "audio_clkout_a" /*, "audio_clkout3_a"*/;
++ function = "audio_clk";
++ };
++
++ usb31_pins: usb31 {
++ groups = "usb31";
++ function = "usb31";
++ };
++
++ can0_pins: can0 {
++ groups = "can0_data_a";
++ function = "can0";
++ };
++
++ canfd0_pins: canfd0 {
++ groups = "canfd0_data_a";
++ function = "canfd0";
++ };
++};
++
++&scif1 {
++ pinctrl-0 = <&scif1_pins>;
++ pinctrl-names = "default";
++ status = "okay";
++};
++
++&avb {
++ /delete-property/phy-handle;
++ /delete-property/phy-gpios;
++ /delete-node/ethernet-phy@0;
++
++ fixed-link {
++ speed = <1000>;
++ full-duplex;
++ };
++};
++
++&msiof0 {
++ pinctrl-0 = <&msiof0_pins>;
++ pinctrl-names = "default";
++ status = "disabled";
++ cs-gpios = <&gpio5 19 0>;
++
++ spidev@0 {
++ compatible = "renesas,sh-msiof";
++ reg = <0>;
++ spi-max-frequency = <66666666>;
++ spi-cpha;
++ spi-cpol;
++ };
++};
++
++&msiof1 {
++ status = "disabled";
++ cs-gpios = <&gpio6 5 0>;
++};
++
++&can0 {
++ pinctrl-0 = <&can0_pins>;
++ pinctrl-names = "default";
++ status = "disabled";
++
++ renesas,can-clock-select = <0x0>;
++ gpios = <&gpio2 6 GPIO_ACTIVE_HIGH /* enable - shared with camera board */
++ &gpio2 7 GPIO_ACTIVE_LOW /* standby */
++ >;
++};
++
++&canfd {
++ pinctrl-0 = <&canfd0_pins>;
++ pinctrl-names = "default";
++ status = "okay";
++
++ renesas,can-clock-select = <0x0>;
++ gpios = <&gpio2 6 GPIO_ACTIVE_HIGH /* enable - shared with camera board */
++ &gpio2 7 GPIO_ACTIVE_LOW /* standby */
++ >;
++
++ channel0 {
++ status = "okay";
++ };
++};
++
++&xhci1 {
++ status = "okay";
++ pinctrl-0 = <&usb31_pins>;
++ pinctrl-names = "default";
++};
+diff --git a/arch/arm64/boot/dts/renesas/r8a7795-es1-h3ulcb-kf.dts b/arch/arm64/boot/dts/renesas/r8a7795-es1-h3ulcb-kf.dts
+index 2f24dfc..88fee1f 100644
+--- a/arch/arm64/boot/dts/renesas/r8a7795-es1-h3ulcb-kf.dts
++++ b/arch/arm64/boot/dts/renesas/r8a7795-es1-h3ulcb-kf.dts
+@@ -14,3 +14,28 @@
+ compatible = "shimafuji,kingfisher", "renesas,h3ulcb",
+ "renesas,r8a7795";
+ };
++
++&du {
++ ports {
++ port@0 {
++ endpoint {
++ remote-endpoint = <&adv7513_in>;
++ };
++ };
++ };
++};
++
++&lvds0 {
++ status = "okay";
++
++ ports {
++ port@1 {
++ lvds0_out: endpoint {
++ remote-endpoint = <&lvds_in>;
++ };
++ };
++ };
++};
++
++/* use CN11 instead default CN29/CN48 (H3 only) */
++//#include "ulcb-kf-cn11.dtsi"
+diff --git a/arch/arm64/boot/dts/renesas/r8a7795-es1-h3ulcb-vb.dts b/arch/arm64/boot/dts/renesas/r8a7795-es1-h3ulcb-vb.dts
+new file mode 100644
+index 0000000..db9f80f
+--- /dev/null
++++ b/arch/arm64/boot/dts/renesas/r8a7795-es1-h3ulcb-vb.dts
+@@ -0,0 +1,69 @@
++/*
++ * Device Tree Source for the H3ULCB Videobox board on r8a7795 ES1.x
++ *
++ * Copyright (C) 2017 Renesas Electronics Corp.
++ * Copyright (C) 2017 Cogent Embedded, Inc.
++ *
++ * This file is licensed under the terms of the GNU General Public License
++ * version 2. This program is licensed "as is" without any warranty of any
++ * kind, whether express or implied.
++ */
++
++#include "r8a7795-es1-h3ulcb.dts"
++#include "ulcb-vb.dtsi"
++
++/ {
++ model = "Renesas H3ULCB Videobox board based on r8a7795";
++
++ hdmi1-out {
++ compatible = "hdmi-connector";
++ type = "a";
++
++ port {
++ hdmi1_con: endpoint {
++ remote-endpoint = <&rcar_dw_hdmi1_out>;
++ };
++ };
++ };
++};
++
++&du {
++ ports {
++ port@2 {
++ endpoint {
++ remote-endpoint = <&rcar_dw_hdmi1_in>;
++ };
++ };
++ port@3 {
++ endpoint {
++ remote-endpoint = <&lvds_in>;
++ };
++ };
++ };
++};
++
++&hdmi1 {
++ status = "okay";
++
++ ports {
++ #address-cells = <1>;
++ #size-cells = <0>;
++
++ port@0 {
++ reg = <0>;
++ rcar_dw_hdmi1_in: endpoint {
++ remote-endpoint = <&du_out_hdmi1>;
++ };
++ };
++ port@1 {
++ reg = <1>;
++ rcar_dw_hdmi1_out: endpoint {
++ remote-endpoint = <&hdmi1_con>;
++ };
++ };
++ };
++};
++
++&hsusb {
++ status = "okay";
++};
+diff --git a/arch/arm64/boot/dts/renesas/r8a7795-es1-h3ulcb-vb2.dts b/arch/arm64/boot/dts/renesas/r8a7795-es1-h3ulcb-vb2.dts
+new file mode 100644
+index 0000000..6d51ffd
+--- /dev/null
++++ b/arch/arm64/boot/dts/renesas/r8a7795-es1-h3ulcb-vb2.dts
+@@ -0,0 +1,77 @@
++/*
++ * Device Tree Source for the H3ULCB Videobox board V2 on r8a7795
++ *
++ * Copyright (C) 2018 Cogent Embedded, Inc.
++ *
++ * This file is licensed under the terms of the GNU General Public License
++ * version 2. This program is licensed "as is" without any warranty of any
++ * kind, whether express or implied.
++ */
++
++#include "r8a7795-es1-h3ulcb.dts"
++#include "ulcb-vb2.dtsi"
++
++/ {
++ model = "Renesas H3ULCB Videobox board based on r8a7795";
++
++ hdmi1-out {
++ compatible = "hdmi-connector";
++ type = "a";
++
++ port {
++ hdmi1_con: endpoint {
++ remote-endpoint = <&rcar_dw_hdmi1_out>;
++ };
++ };
++ };
++};
++
++&pfc {
++ usb31_pins: usb31 {
++ groups = "usb31";
++ function = "usb31";
++ };
++};
++
++&du {
++ ports {
++ port@2 {
++ endpoint {
++ remote-endpoint = <&rcar_dw_hdmi1_in>;
++ };
++ };
++ port@3 {
++ endpoint {
++ remote-endpoint = <&lvds_in>;
++ };
++ };
++ };
++};
++
++&hdmi1 {
++ status = "okay";
++
++ ports {
++ #address-cells = <1>;
++ #size-cells = <0>;
++
++ port@0 {
++ reg = <0>;
++ rcar_dw_hdmi1_in: endpoint {
++ remote-endpoint = <&du_out_hdmi1>;
++ };
++ };
++ port@1 {
++ reg = <1>;
++ rcar_dw_hdmi1_out: endpoint {
++ remote-endpoint = <&hdmi1_con>;
++ };
++ };
++ };
++};
++
++&xhci1 {
++ status = "okay";
++ pinctrl-0 = <&usb31_pins>;
++ pinctrl-names = "default";
++};
+diff --git a/arch/arm64/boot/dts/renesas/r8a7795-es1-h3ulcb-vbm.dts b/arch/arm64/boot/dts/renesas/r8a7795-es1-h3ulcb-vbm.dts
+new file mode 100644
+index 0000000..64815d4
+--- /dev/null
++++ b/arch/arm64/boot/dts/renesas/r8a7795-es1-h3ulcb-vbm.dts
+@@ -0,0 +1,26 @@
++/*
++ * Device Tree Source for the H3ULCB Videobox Mini board on r8a7795 ES1.x
++ *
++ * Copyright (C) 2017 Cogent Embedded, Inc.
++ *
++ * This file is licensed under the terms of the GNU General Public License
++ * version 2. This program is licensed "as is" without any warranty of any
++ * kind, whether express or implied.
++ */
++
++#include "r8a7795-es1-h3ulcb.dts"
++#include "ulcb-vbm.dtsi"
++
++/ {
++ model = "Renesas H3ULCB Videobox Mini board based on r8a7795";
++};
++
++&du {
++ ports {
++ port@3 {
++ endpoint {
++ remote-endpoint = <&lvds_in>;
++ };
++ };
++ };
++};
+diff --git a/arch/arm64/boot/dts/renesas/r8a7795-es1-h3ulcb-view.dts b/arch/arm64/boot/dts/renesas/r8a7795-es1-h3ulcb-view.dts
+new file mode 100644
+index 0000000..1ce261d
+--- /dev/null
++++ b/arch/arm64/boot/dts/renesas/r8a7795-es1-h3ulcb-view.dts
+@@ -0,0 +1,544 @@
++/*
++ * Device Tree Source for the H3ULCB.View board on r8a7795 ES1.x
++ *
++ * Copyright (C) 2016-2017 Renesas Electronics Corp.
++ * Copyright (C) 2016-2017 Cogent Embedded, Inc.
++ *
++ * This file is licensed under the terms of the GNU General Public License
++ * version 2. This program is licensed "as is" without any warranty of any
++ * kind, whether express or implied.
++ */
++
++#include "r8a7795-es1-h3ulcb.dts"
++
++/ {
++ model = "Renesas H3ULCB.View board based on r8a7795";
++};
++
++&i2c4 {
++ ov106xx@0 {
++ compatible = "ovti,ov106xx";
++ reg = <0x60>;
++
++ port@0 {
++ ov106xx_in0: endpoint {
++ clock-lanes = <0>;
++ data-lanes = <1 2 3 4>;
++ remote-endpoint = <&vin0ep0>;
++ };
++ };
++ port@1 {
++ ov106xx_max9286_des0ep0: endpoint@0 {
++ remote-endpoint = <&max9286_des0ep0>;
++ };
++ };
++ };
++
++ ov106xx@1 {
++ compatible = "ovti,ov106xx";
++ reg = <0x61>;
++
++ port@0 {
++ ov106xx_in1: endpoint {
++ clock-lanes = <0>;
++ data-lanes = <1 2 3 4>;
++ remote-endpoint = <&vin1ep0>;
++ };
++ };
++ port@1 {
++ ov106xx_max9286_des0ep1: endpoint@0 {
++ remote-endpoint = <&max9286_des0ep1>;
++ };
++ };
++ };
++
++ ov106xx@2 {
++ compatible = "ovti,ov106xx";
++ reg = <0x62>;
++
++ port@0 {
++ ov106xx_in2: endpoint {
++ clock-lanes = <0>;
++ data-lanes = <1 2 3 4>;
++ remote-endpoint = <&vin2ep0>;
++ };
++ };
++ port@1 {
++ ov106xx_max9286_des0ep2: endpoint@0 {
++ remote-endpoint = <&max9286_des0ep2>;
++ };
++ };
++ };
++
++ ov106xx@3 {
++ compatible = "ovti,ov106xx";
++ reg = <0x63>;
++
++ port@0 {
++ ov106xx_in3: endpoint {
++ clock-lanes = <0>;
++ data-lanes = <1 2 3 4>;
++ remote-endpoint = <&vin3ep0>;
++ };
++ };
++ port@1 {
++ ov106xx_des0ep3: endpoint {
++ remote-endpoint = <&max9286_des0ep3>;
++ };
++ };
++ };
++
++ ov106xx@4 {
++ compatible = "ovti,ov106xx";
++ reg = <0x64>;
++
++ port@0 {
++ ov106xx_in4: endpoint {
++ clock-lanes = <0>;
++ data-lanes = <1 2 3 4>;
++ remote-endpoint = <&vin4ep0>;
++ };
++ };
++ port@1 {
++ ov106xx_max9286_des1ep0: endpoint@0 {
++ remote-endpoint = <&max9286_des1ep0>;
++ };
++ };
++ };
++
++ ov106xx@5 {
++ compatible = "ovti,ov106xx";
++ reg = <0x65>;
++
++ port@0 {
++ ov106xx_in5: endpoint {
++ clock-lanes = <0>;
++ data-lanes = <1 2 3 4>;
++ remote-endpoint = <&vin5ep0>;
++ };
++ };
++ port@1 {
++ ov106xx_max9286_des1ep1: endpoint@0 {
++ remote-endpoint = <&max9286_des1ep1>;
++ };
++ };
++ };
++
++ ov106xx@6 {
++ compatible = "ovti,ov106xx";
++ reg = <0x66>;
++
++ port@0 {
++ ov106xx_in6: endpoint {
++ clock-lanes = <0>;
++ data-lanes = <1 2 3 4>;
++ remote-endpoint = <&vin6ep0>;
++ };
++ };
++ port@1 {
++ ov106xx_max9286_des1ep2: endpoint@0 {
++ remote-endpoint = <&max9286_des1ep2>;
++ };
++ };
++ };
++
++ ov106xx@7 {
++ compatible = "ovti,ov106xx";
++ reg = <0x67>;
++
++ port@0 {
++ ov106xx_in7: endpoint {
++ clock-lanes = <0>;
++ data-lanes = <1 2 3 4>;
++ remote-endpoint = <&vin7ep0>;
++ };
++ };
++ port@1 {
++ ov106xx_des1ep3: endpoint {
++ remote-endpoint = <&max9286_des1ep3>;
++ };
++ };
++ };
++
++ max9286@0 {
++ compatible = "maxim,max9286";
++ reg = <0x4c>;
++ gpios = <&gpio2 6 GPIO_ACTIVE_HIGH>;
++ maxim,links = <4>;
++ maxim,lanes = <4>;
++ maxim,resetb-gpio = <1>;
++ maxim,fsync-mode = "automatic";
++ maxim,timeout = <100>;
++ maxim,i2c-quirk = <0x6c>;
++
++ port@0 {
++ max9286_des0ep0: endpoint@0 {
++ max9271-addr = <0x50>;
++ dvp-order = <1>;
++ remote-endpoint = <&ov106xx_in0>;
++ };
++ max9286_des0ep1: endpoint@1 {
++ max9271-addr = <0x51>;
++ dvp-order = <1>;
++ remote-endpoint = <&ov106xx_in1>;
++ };
++ max9286_des0ep2: endpoint@2 {
++ max9271-addr = <0x52>;
++ dvp-order = <1>;
++ remote-endpoint = <&ov106xx_in2>;
++ };
++ max9286_des0ep3: endpoint@3 {
++ max9271-addr = <0x53>;
++ dvp-order = <1>;
++ remote-endpoint = <&ov106xx_in3>;
++ };
++ };
++ port@1 {
++ max9286_csi0ep0: endpoint {
++ csi-rate = <700>;
++ remote-endpoint = <&csi40_ep>;
++ };
++ };
++ };
++
++ max9286@1 {
++ compatible = "maxim,max9286";
++ reg = <0x6c>;
++ gpios = <&gpio5 25 GPIO_ACTIVE_HIGH>;
++ maxim,links = <4>;
++ maxim,lanes = <4>;
++ maxim,resetb-gpio = <1>;
++ maxim,fsync-mode = "automatic";
++ maxim,timeout = <100>;
++
++ port@0 {
++ max9286_des1ep0: endpoint@0 {
++ max9271-addr = <0x54>;
++ dvp-order = <1>;
++ remote-endpoint = <&ov106xx_in4>;
++ };
++ max9286_des1ep1: endpoint@1 {
++ max9271-addr = <0x55>;
++ dvp-order = <1>;
++ remote-endpoint = <&ov106xx_in5>;
++ };
++ max9286_des1ep2: endpoint@2 {
++ max9271-addr = <0x56>;
++ dvp-order = <1>;
++ remote-endpoint = <&ov106xx_in6>;
++ };
++ max9286_des1ep3: endpoint@3 {
++ max9271-addr = <0x57>;
++ dvp-order = <1>;
++ remote-endpoint = <&ov106xx_in7>;
++ };
++ };
++ port@1 {
++ max9286_csi2ep0: endpoint {
++ csi-rate = <700>;
++ remote-endpoint = <&csi41_ep>;
++ };
++ };
++ };
++};
++
++&pcie_bus_clk {
++ clock-frequency = <100000000>;
++ status = "okay";
++};
++
++&pciec1 {
++ status = "okay";
++};
++
++&vin0 {
++ status = "okay";
++
++ ports {
++ #address-cells = <1>;
++ #size-cells = <0>;
++
++ port@0 {
++ vin0ep0: endpoint {
++ csi,select = "csi40";
++ virtual,channel = <0>;
++ data-lanes = <1 2 3 4>;
++ remote-endpoint = <&ov106xx_in0>;
++ };
++ };
++ port@1 {
++ csi0ep0: endpoint {
++ remote-endpoint = <&csi40_ep>;
++ };
++ };
++ port@2 {
++ vin0_max9286_des0ep0: endpoint@0 {
++ remote-endpoint = <&max9286_des0ep0>;
++ };
++ };
++ };
++};
++
++&vin1 {
++ status = "okay";
++
++ ports {
++ #address-cells = <1>;
++ #size-cells = <0>;
++
++ port@0 {
++ vin1ep0: endpoint {
++ csi,select = "csi40";
++ virtual,channel = <1>;
++ data-lanes = <1 2 3 4>;
++ remote-endpoint = <&ov106xx_in1>;
++ };
++ };
++ port@1 {
++ csi0ep1: endpoint {
++ remote-endpoint = <&csi40_ep>;
++ };
++ };
++ port@2 {
++ vin1_max9286_des0ep1: endpoint@0 {
++ remote-endpoint = <&max9286_des0ep1>;
++ };
++ };
++ };
++};
++
++&vin2 {
++ status = "okay";
++
++ ports {
++ #address-cells = <1>;
++ #size-cells = <0>;
++
++ port@0 {
++ vin2ep0: endpoint {
++ csi,select = "csi40";
++ virtual,channel = <2>;
++ data-lanes = <1 2 3 4>;
++ remote-endpoint = <&ov106xx_in2>;
++ };
++ };
++ port@1 {
++ csi0ep2: endpoint {
++ remote-endpoint = <&csi40_ep>;
++ };
++ };
++ port@2 {
++ vin2_max9286_des0ep2: endpoint@0 {
++ remote-endpoint = <&max9286_des0ep2>;
++ };
++ };
++ };
++};
++
++&vin3 {
++ status = "okay";
++
++ ports {
++ #address-cells = <1>;
++ #size-cells = <0>;
++
++ port@0 {
++ vin3ep0: endpoint {
++ csi,select = "csi40";
++ virtual,channel = <3>;
++ data-lanes = <1 2 3 4>;
++ remote-endpoint = <&ov106xx_in3>;
++ };
++ };
++ port@1 {
++ csi0ep3: endpoint {
++ remote-endpoint = <&csi40_ep>;
++ };
++ };
++ port@2 {
++ vin3_max9286_des0ep3: endpoint@0 {
++ remote-endpoint = <&max9286_des0ep3>;
++ };
++ };
++ };
++};
++
++&vin4 {
++ status = "okay";
++
++ ports {
++ #address-cells = <1>;
++ #size-cells = <0>;
++
++ port@0 {
++ vin4ep0: endpoint {
++ csi,select = "csi41";
++ virtual,channel = <0>;
++ remote-endpoint = <&ov106xx_in4>;
++ data-lanes = <1 2 3 4>;
++ };
++ };
++ port@1 {
++ csi2ep0: endpoint {
++ remote-endpoint = <&csi41_ep>;
++ };
++ };
++ port@2 {
++ vin4_max9286_des1ep0: endpoint@0 {
++ remote-endpoint = <&max9286_des1ep0>;
++ };
++ };
++ };
++};
++
++&vin5 {
++ status = "okay";
++
++ ports {
++ #address-cells = <1>;
++ #size-cells = <0>;
++
++ port@0 {
++ vin5ep0: endpoint@0 {
++ csi,select = "csi41";
++ virtual,channel = <1>;
++ remote-endpoint = <&ov106xx_in5>;
++ data-lanes = <1 2 3 4>;
++ };
++ };
++ port@1 {
++ csi2ep1: endpoint {
++ remote-endpoint = <&csi41_ep>;
++ };
++ };
++ port@2 {
++ vin5_max9286_des1ep1: endpoint@0 {
++ remote-endpoint = <&max9286_des1ep1>;
++ };
++ };
++ };
++};
++
++&vin6 {
++ status = "okay";
++
++ ports {
++ #address-cells = <1>;
++ #size-cells = <0>;
++
++ port@0 {
++ vin6ep0: endpoint@0 {
++ csi,select = "csi41";
++ virtual,channel = <2>;
++ remote-endpoint = <&ov106xx_in6>;
++ data-lanes = <1 2 3 4>;
++ };
++ };
++ port@1 {
++ csi2ep2: endpoint {
++ remote-endpoint = <&csi41_ep>;
++ };
++ };
++ port@2 {
++ vin6_max9286_des1ep2: endpoint@0 {
++ remote-endpoint = <&max9286_des1ep2>;
++ };
++ };
++ };
++};
++
++&vin7 {
++ status = "okay";
++
++ ports {
++ #address-cells = <1>;
++ #size-cells = <0>;
++
++ port@0 {
++ vin7ep0: endpoint@0 {
++ csi,select = "csi41";
++ virtual,channel = <3>;
++ remote-endpoint = <&ov106xx_in7>;
++ data-lanes = <1 2 3 4>;
++ };
++ };
++ port@1 {
++ csi2ep3: endpoint {
++ remote-endpoint = <&csi41_ep>;
++ };
++ };
++ port@2 {
++ vin7_max9286_des1ep3: endpoint@0 {
++ remote-endpoint = <&max9286_des1ep3>;
++ };
++ };
++ };
++};
++
++&csi40 {
++ status = "okay";
++
++ virtual,channel {
++ csi2_vc0 {
++ data,type = "ycbcr422";
++ receive,vc = <0>;
++ };
++ csi2_vc1 {
++ data,type = "ycbcr422";
++ receive,vc = <1>;
++ };
++ csi2_vc2 {
++ data,type = "ycbcr422";
++ receive,vc = <2>;
++ };
++ csi2_vc3 {
++ data,type = "ycbcr422";
++ receive,vc = <3>;
++ };
++ };
++
++ port {
++ #address-cells = <1>;
++ #size-cells = <0>;
++
++ csi40_ep: endpoint {
++ clock-lanes = <0>;
++ data-lanes = <1 2 3 4>;
++ csi-rate = <300>;
++ };
++ };
++};
++
++&csi41 {
++ status = "okay";
++
++ virtual,channel {
++ csi2_vc0 {
++ data,type = "ycbcr422";
++ receive,vc = <0>;
++ };
++ csi2_vc1 {
++ data,type = "ycbcr422";
++ receive,vc = <1>;
++ };
++ csi2_vc2 {
++ data,type = "ycbcr422";
++ receive,vc = <2>;
++ };
++ csi2_vc3 {
++ data,type = "ycbcr422";
++ receive,vc = <3>;
++ };
++ };
++
++ port {
++ #address-cells = <1>;
++ #size-cells = <0>;
++
++ csi41_ep: endpoint {
++ clock-lanes = <0>;
++ data-lanes = <1 2 3 4>;
++ csi-rate = <300>;
++ };
++ };
++};
+diff --git a/arch/arm64/boot/dts/renesas/r8a7795-es1-salvator-x-view.dts b/arch/arm64/boot/dts/renesas/r8a7795-es1-salvator-x-view.dts
+new file mode 100644
+index 0000000..9a7487c
+--- /dev/null
++++ b/arch/arm64/boot/dts/renesas/r8a7795-es1-salvator-x-view.dts
+@@ -0,0 +1,550 @@
++/*
++ * Device Tree Source for the Salvator-X.View board on r8a7795 ES1.x
++ *
++ * Copyright (C) 2016-2017 Renesas Electronics Corp.
++ * Copyright (C) 2015-2017 Cogent Embedded, Inc
++ *
++ * This file is licensed under the terms of the GNU General Public License
++ * version 2. This program is licensed "as is" without any warranty of any
++ * kind, whether express or implied.
++ */
++
++#include "r8a7795-es1-salvator-x.dts"
++
++/ {
++ model = "Renesas Salvator-X.View board based on r8a7795";
++};
++
++&pfc {
++ can0_pins: can0 {
++ groups = "can0_data_a";
++ function = "can0";
++ };
++
++ can1_pins: can1 {
++ groups = "can1_data";
++ function = "can1";
++ };
++};
++
++&i2c4 {
++ /delete-node/hdmi-in@34;
++ /delete-node/composite-in@70;
++
++ ov106xx@0 {
++ compatible = "ovti,ov106xx";
++ reg = <0x60>;
++
++ port@0 {
++ ov106xx_in0: endpoint {
++ clock-lanes = <0>;
++ data-lanes = <1 2 3 4>;
++ remote-endpoint = <&vin0ep0>;
++ };
++ };
++ port@1 {
++ ov106xx_max9286_des0ep0: endpoint@0 {
++ remote-endpoint = <&max9286_des0ep0>;
++ };
++ };
++ };
++
++ ov106xx@1 {
++ compatible = "ovti,ov106xx";
++ reg = <0x61>;
++
++ port@0 {
++ ov106xx_in1: endpoint {
++ clock-lanes = <0>;
++ data-lanes = <1 2 3 4>;
++ remote-endpoint = <&vin1ep0>;
++ };
++ };
++ port@1 {
++ ov106xx_max9286_des0ep1: endpoint@0 {
++ remote-endpoint = <&max9286_des0ep1>;
++ };
++ };
++ };
++
++ ov106xx@2 {
++ compatible = "ovti,ov106xx";
++ reg = <0x62>;
++
++ port@0 {
++ ov106xx_in2: endpoint {
++ clock-lanes = <0>;
++ data-lanes = <1 2 3 4>;
++ remote-endpoint = <&vin2ep0>;
++ };
++ };
++ port@1 {
++ ov106xx_max9286_des0ep2: endpoint@0 {
++ remote-endpoint = <&max9286_des0ep2>;
++ };
++ };
++ };
++
++ ov106xx@3 {
++ compatible = "ovti,ov106xx";
++ reg = <0x63>;
++
++ port@0 {
++ ov106xx_in3: endpoint {
++ clock-lanes = <0>;
++ data-lanes = <1 2 3 4>;
++ remote-endpoint = <&vin3ep0>;
++ };
++ };
++ port@1 {
++ ov106xx_des0ep3: endpoint {
++ remote-endpoint = <&max9286_des0ep3>;
++ };
++ };
++ };
++
++ ov106xx@4 {
++ compatible = "ovti,ov106xx";
++ reg = <0x64>;
++
++ port@0 {
++ ov106xx_in4: endpoint {
++ clock-lanes = <0>;
++ data-lanes = <1 2 3 4>;
++ remote-endpoint = <&vin4ep0>;
++ };
++ };
++ port@1 {
++ ov106xx_max9286_des1ep0: endpoint@0 {
++ remote-endpoint = <&max9286_des1ep0>;
++ };
++ };
++ };
++
++ ov106xx@5 {
++ compatible = "ovti,ov106xx";
++ reg = <0x65>;
++
++ port@0 {
++ ov106xx_in5: endpoint {
++ clock-lanes = <0>;
++ data-lanes = <1 2 3 4>;
++ remote-endpoint = <&vin5ep0>;
++ };
++ };
++ port@1 {
++ ov106xx_max9286_des1ep1: endpoint@0 {
++ remote-endpoint = <&max9286_des1ep1>;
++ };
++ };
++ };
++
++ ov106xx@6 {
++ compatible = "ovti,ov106xx";
++ reg = <0x66>;
++
++ port@0 {
++ ov106xx_in6: endpoint {
++ clock-lanes = <0>;
++ data-lanes = <1 2 3 4>;
++ remote-endpoint = <&vin6ep0>;
++ };
++ };
++ port@1 {
++ ov106xx_max9286_des1ep2: endpoint@0 {
++ remote-endpoint = <&max9286_des1ep2>;
++ };
++ };
++ };
++
++ ov106xx@7 {
++ compatible = "ovti,ov106xx";
++ reg = <0x67>;
++
++ port@0 {
++ ov106xx_in7: endpoint {
++ clock-lanes = <0>;
++ data-lanes = <1 2 3 4>;
++ remote-endpoint = <&vin7ep0>;
++ };
++ };
++ port@1 {
++ ov106xx_des1ep3: endpoint {
++ remote-endpoint = <&max9286_des1ep3>;
++ };
++ };
++ };
++
++ max9286@0 {
++ compatible = "maxim,max9286";
++ reg = <0x4c>;
++ gpios = <&gpio6 30 GPIO_ACTIVE_LOW>;
++ maxim,links = <4>;
++ maxim,lanes = <4>;
++ maxim,resetb-gpio = <1>;
++ maxim,fsync-mode = "automatic";
++ maxim,timeout = <100>;
++ maxim,i2c-quirk = <0x6c>;
++
++ port@0 {
++ max9286_des0ep0: endpoint@0 {
++ max9271-addr = <0x50>;
++ dvp-order = <1>;
++ remote-endpoint = <&ov106xx_in0>;
++ };
++ max9286_des0ep1: endpoint@1 {
++ max9271-addr = <0x51>;
++ dvp-order = <1>;
++ remote-endpoint = <&ov106xx_in1>;
++ };
++ max9286_des0ep2: endpoint@2 {
++ max9271-addr = <0x52>;
++ dvp-order = <1>;
++ remote-endpoint = <&ov106xx_in2>;
++ };
++ max9286_des0ep3: endpoint@3 {
++ max9271-addr = <0x53>;
++ dvp-order = <1>;
++ remote-endpoint = <&ov106xx_in3>;
++ };
++ };
++ port@1 {
++ max9286_csi0ep0: endpoint {
++ csi-rate = <700>;
++ remote-endpoint = <&csi40_ep>;
++ };
++ };
++ };
++
++ max9286@1 {
++ compatible = "maxim,max9286";
++ reg = <0x6c>;
++ maxim,links = <4>;
++ maxim,lanes = <4>;
++ maxim,resetb-gpio = <1>;
++ maxim,fsync-mode = "automatic";
++ maxim,timeout = <100>;
++
++ port@0 {
++ max9286_des1ep0: endpoint@0 {
++ max9271-addr = <0x54>;
++ dvp-order = <1>;
++ remote-endpoint = <&ov106xx_in4>;
++ };
++ max9286_des1ep1: endpoint@1 {
++ max9271-addr = <0x55>;
++ dvp-order = <1>;
++ remote-endpoint = <&ov106xx_in5>;
++ };
++ max9286_des1ep2: endpoint@2 {
++ max9271-addr = <0x56>;
++ dvp-order = <1>;
++ remote-endpoint = <&ov106xx_in6>;
++ };
++ max9286_des1ep3: endpoint@3 {
++ max9271-addr = <0x57>;
++ dvp-order = <1>;
++ remote-endpoint = <&ov106xx_in7>;
++ };
++ };
++ port@1 {
++ max9286_csi2ep0: endpoint {
++ csi-rate = <700>;
++ remote-endpoint = <&csi41_ep>;
++ };
++ };
++ };
++};
++
++&vin0 {
++ ports {
++ #address-cells = <1>;
++ #size-cells = <0>;
++
++ port@0 {
++ vin0ep0: endpoint {
++ csi,select = "csi40";
++ virtual,channel = <0>;
++ data-lanes = <1 2 3 4>;
++ remote-endpoint = <&ov106xx_in0>;
++ };
++ };
++ port@1 {
++ csi0ep0: endpoint {
++ remote-endpoint = <&csi40_ep>;
++ };
++ };
++ port@2 {
++ vin0_max9286_des0ep0: endpoint@0 {
++ remote-endpoint = <&max9286_des0ep0>;
++ };
++ };
++ };
++};
++
++&vin1 {
++ ports {
++ #address-cells = <1>;
++ #size-cells = <0>;
++
++ port@0 {
++ vin1ep0: endpoint {
++ csi,select = "csi40";
++ virtual,channel = <1>;
++ data-lanes = <1 2 3 4>;
++ remote-endpoint = <&ov106xx_in1>;
++ };
++ };
++ port@1 {
++ csi0ep1: endpoint {
++ remote-endpoint = <&csi40_ep>;
++ };
++ };
++ port@2 {
++ vin1_max9286_des0ep1: endpoint@0 {
++ remote-endpoint = <&max9286_des0ep1>;
++ };
++ };
++ };
++};
++
++&vin2 {
++ ports {
++ #address-cells = <1>;
++ #size-cells = <0>;
++
++ port@0 {
++ vin2ep0: endpoint {
++ csi,select = "csi40";
++ virtual,channel = <2>;
++ data-lanes = <1 2 3 4>;
++ remote-endpoint = <&ov106xx_in2>;
++ };
++ };
++ port@1 {
++ csi0ep2: endpoint {
++ remote-endpoint = <&csi40_ep>;
++ };
++ };
++ port@2 {
++ vin2_max9286_des0ep2: endpoint@0 {
++ remote-endpoint = <&max9286_des0ep2>;
++ };
++ };
++ };
++};
++
++&vin3 {
++ ports {
++ #address-cells = <1>;
++ #size-cells = <0>;
++
++ port@0 {
++ vin3ep0: endpoint {
++ csi,select = "csi40";
++ virtual,channel = <3>;
++ data-lanes = <1 2 3 4>;
++ remote-endpoint = <&ov106xx_in3>;
++ };
++ };
++ port@1 {
++ csi0ep3: endpoint {
++ remote-endpoint = <&csi40_ep>;
++ };
++ };
++ port@2 {
++ vin3_max9286_des0ep3: endpoint@0 {
++ remote-endpoint = <&max9286_des0ep3>;
++ };
++ };
++ };
++};
++
++&vin4 {
++ ports {
++ #address-cells = <1>;
++ #size-cells = <0>;
++
++ port@0 {
++ vin4ep0: endpoint {
++ csi,select = "csi41";
++ virtual,channel = <0>;
++ remote-endpoint = <&ov106xx_in4>;
++ data-lanes = <1 2 3 4>;
++ };
++ };
++ port@1 {
++ csi2ep0: endpoint {
++ remote-endpoint = <&csi41_ep>;
++ };
++ };
++ port@2 {
++ vin4_max9286_des1ep0: endpoint@0 {
++ remote-endpoint = <&max9286_des1ep0>;
++ };
++ };
++ };
++};
++
++&vin5 {
++ ports {
++ #address-cells = <1>;
++ #size-cells = <0>;
++
++ port@0 {
++ vin5ep0: endpoint@0 {
++ csi,select = "csi41";
++ virtual,channel = <1>;
++ remote-endpoint = <&ov106xx_in5>;
++ data-lanes = <1 2 3 4>;
++ };
++ };
++ port@1 {
++ csi2ep1: endpoint {
++ remote-endpoint = <&csi41_ep>;
++ };
++ };
++ port@2 {
++ vin5_max9286_des1ep1: endpoint@0 {
++ remote-endpoint = <&max9286_des1ep1>;
++ };
++ };
++ };
++};
++
++&vin6 {
++ ports {
++ #address-cells = <1>;
++ #size-cells = <0>;
++
++ port@0 {
++ vin6ep0: endpoint@0 {
++ csi,select = "csi41";
++ virtual,channel = <2>;
++ remote-endpoint = <&ov106xx_in6>;
++ data-lanes = <1 2 3 4>;
++ };
++ };
++ port@1 {
++ csi2ep2: endpoint {
++ remote-endpoint = <&csi41_ep>;
++ };
++ };
++ port@2 {
++ vin6_max9286_des1ep2: endpoint@0 {
++ remote-endpoint = <&max9286_des1ep2>;
++ };
++ };
++ };
++};
++
++&vin7 {
++ ports {
++ #address-cells = <1>;
++ #size-cells = <0>;
++
++ port@0 {
++ vin7ep0: endpoint@0 {
++ csi,select = "csi41";
++ virtual,channel = <3>;
++ remote-endpoint = <&ov106xx_in7>;
++ data-lanes = <1 2 3 4>;
++ };
++ };
++ port@1 {
++ csi2ep3: endpoint {
++ remote-endpoint = <&csi41_ep>;
++ };
++ };
++ port@2 {
++ vin7_max9286_des1ep3: endpoint@0 {
++ remote-endpoint = <&max9286_des1ep3>;
++ };
++ };
++ };
++};
++
++&csi20 {
++ status = "disabled";
++ /delete-node/ports;
++};
++
++&csi40 {
++ /delete-node/ports;
++
++ virtual,channel {
++ csi2_vc0 {
++ data,type = "ycbcr422";
++ receive,vc = <0>;
++ };
++ csi2_vc1 {
++ data,type = "ycbcr422";
++ receive,vc = <1>;
++ };
++ csi2_vc2 {
++ data,type = "ycbcr422";
++ receive,vc = <2>;
++ };
++ csi2_vc3 {
++ data,type = "ycbcr422";
++ receive,vc = <3>;
++ };
++ };
++
++ port {
++ #address-cells = <1>;
++ #size-cells = <0>;
++
++ csi40_ep: endpoint {
++ clock-lanes = <0>;
++ data-lanes = <1 2 3 4>;
++ csi-rate = <300>;
++ };
++ };
++};
++
++&csi41 {
++ status = "okay";
++
++ virtual,channel {
++ csi2_vc0 {
++ data,type = "ycbcr422";
++ receive,vc = <0>;
++ };
++ csi2_vc1 {
++ data,type = "ycbcr422";
++ receive,vc = <1>;
++ };
++ csi2_vc2 {
++ data,type = "ycbcr422";
++ receive,vc = <2>;
++ };
++ csi2_vc3 {
++ data,type = "ycbcr422";
++ receive,vc = <3>;
++ };
++ };
++
++ port {
++ #address-cells = <1>;
++ #size-cells = <0>;
++
++ csi41_ep: endpoint {
++ clock-lanes = <0>;
++ data-lanes = <1 2 3 4>;
++ csi-rate = <300>;
++ };
++ };
++};
++
++&can0 {
++ pinctrl-0 = <&can0_pins>;
++ pinctrl-names = "default";
++ status = "okay";
++};
++
++&can1 {
++ pinctrl-0 = <&can1_pins>;
++ pinctrl-names = "default";
++ status = "okay";
++};
+diff --git a/arch/arm64/boot/dts/renesas/r8a7795-h3ulcb-4x2g-kf.dts b/arch/arm64/boot/dts/renesas/r8a7795-h3ulcb-4x2g-kf.dts
+new file mode 100644
+index 0000000..5e391ae
+--- /dev/null
++++ b/arch/arm64/boot/dts/renesas/r8a7795-h3ulcb-4x2g-kf.dts
+@@ -0,0 +1,44 @@
++/*
++ * Device Tree Source for the H3ULCB Kingfisher board
++ *
++ * Copyright (C) 2018 Renesas Electronics Corp.
++ * Copyright (C) 2018 Cogent Embedded, Inc.
++ *
++ * This file is licensed under the terms of the GNU General Public License
++ * version 2. This program is licensed "as is" without any warranty of any
++ * kind, whether express or implied.
++ */
++
++#include "r8a7795-h3ulcb-4x2g.dts"
++#include "ulcb-kf.dtsi"
++
++/ {
++ model = "Renesas H3ULCB Kingfisher board based on r8a7795 ES2.0+";
++ compatible = "shimafuji,kingfisher", "renesas,h3ulcb",
++ "renesas,r8a7795";
++};
++
++&du {
++ ports {
++ port@0 {
++ endpoint {
++ remote-endpoint = <&adv7513_in>;
++ };
++ };
++ };
++};
++
++&lvds0 {
++ status = "okay";
++
++ ports {
++ port@1 {
++ lvds0_out: endpoint {
++ remote-endpoint = <&lvds_in>;
++ };
++ };
++ };
++};
++
++/* use CN11 instead default CN29/CN48 (H3 only) */
++//#include "ulcb-kf-cn11.dtsi"
+diff --git a/arch/arm64/boot/dts/renesas/r8a7795-h3ulcb-4x2g-vb.dts b/arch/arm64/boot/dts/renesas/r8a7795-h3ulcb-4x2g-vb.dts
+new file mode 100644
+index 0000000..ce16cab
+--- /dev/null
++++ b/arch/arm64/boot/dts/renesas/r8a7795-h3ulcb-4x2g-vb.dts
+@@ -0,0 +1,68 @@
++/*
++ * Device Tree Source for the H3ULCB Videobox board on r8a7795
++ *
++ * Copyright (C) 2017 Cogent Embedded, Inc.
++ *
++ * This file is licensed under the terms of the GNU General Public License
++ * version 2. This program is licensed "as is" without any warranty of any
++ * kind, whether express or implied.
++ */
++
++#include "r8a7795-h3ulcb-4x2g.dts"
++#include "ulcb-vb.dtsi"
++
++/ {
++ model = "Renesas H3ULCB with 8GiB (4 x 2 GiB) Videobox board based on r8a7795";
++
++ hdmi1-out {
++ compatible = "hdmi-connector";
++ type = "a";
++
++ port {
++ hdmi1_con: endpoint {
++ remote-endpoint = <&rcar_dw_hdmi1_out>;
++ };
++ };
++ };
++};
++
++&du {
++ ports {
++ port@2 {
++ endpoint {
++ remote-endpoint = <&rcar_dw_hdmi1_in>;
++ };
++ };
++ port@3 {
++ endpoint {
++ remote-endpoint = <&lvds_in>;
++ };
++ };
++ };
++};
++
++&hdmi1 {
++ status = "okay";
++
++ ports {
++ #address-cells = <1>;
++ #size-cells = <0>;
++
++ port@0 {
++ reg = <0>;
++ rcar_dw_hdmi1_in: endpoint {
++ remote-endpoint = <&du_out_hdmi1>;
++ };
++ };
++ port@1 {
++ reg = <1>;
++ rcar_dw_hdmi1_out: endpoint {
++ remote-endpoint = <&hdmi1_con>;
++ };
++ };
++ };
++};
++
++&hsusb {
++ status = "okay";
++};
+diff --git a/arch/arm64/boot/dts/renesas/r8a7795-h3ulcb-4x2g-vb2.dts b/arch/arm64/boot/dts/renesas/r8a7795-h3ulcb-4x2g-vb2.dts
+new file mode 100644
+index 0000000..1351c6f
+--- /dev/null
++++ b/arch/arm64/boot/dts/renesas/r8a7795-h3ulcb-4x2g-vb2.dts
+@@ -0,0 +1,68 @@
++/*
++ * Device Tree Source for the H3ULCB Videobox board V2 on r8a7795
++ *
++ * Copyright (C) 2018 Cogent Embedded, Inc.
++ *
++ * This file is licensed under the terms of the GNU General Public License
++ * version 2. This program is licensed "as is" without any warranty of any
++ * kind, whether express or implied.
++ */
++
++#include "r8a7795-h3ulcb-4x2g.dts"
++#include "ulcb-vb2.dtsi"
++
++/ {
++ model = "Renesas H3ULCB with 8GiB (4 x 2 GiB) Videobox board based on r8a7795";
++
++ hdmi1-out {
++ compatible = "hdmi-connector";
++ type = "a";
++
++ port {
++ hdmi1_con: endpoint {
++ remote-endpoint = <&rcar_dw_hdmi1_out>;
++ };
++ };
++ };
++};
++
++&du {
++ ports {
++ port@2 {
++ endpoint {
++ remote-endpoint = <&rcar_dw_hdmi1_in>;
++ };
++ };
++ port@3 {
++ endpoint {
++ remote-endpoint = <&lvds_in>;
++ };
++ };
++ };
++};
++
++&hdmi1 {
++ status = "okay";
++
++ ports {
++ #address-cells = <1>;
++ #size-cells = <0>;
++
++ port@0 {
++ reg = <0>;
++ rcar_dw_hdmi1_in: endpoint {
++ remote-endpoint = <&du_out_hdmi1>;
++ };
++ };
++ port@1 {
++ reg = <1>;
++ rcar_dw_hdmi1_out: endpoint {
++ remote-endpoint = <&hdmi1_con>;
++ };
++ };
++ };
++};
++
++&hsusb {
++ status = "okay";
++};
+diff --git a/arch/arm64/boot/dts/renesas/r8a7795-h3ulcb-4x2g-vbm.dts b/arch/arm64/boot/dts/renesas/r8a7795-h3ulcb-4x2g-vbm.dts
+new file mode 100644
+index 0000000..352cc0d
+--- /dev/null
++++ b/arch/arm64/boot/dts/renesas/r8a7795-h3ulcb-4x2g-vbm.dts
+@@ -0,0 +1,26 @@
++/*
++ * Device Tree Source for the H3ULCB Videobox Mini board on r8a7795 ES1.x
++ *
++ * Copyright (C) 2017 Cogent Embedded, Inc.
++ *
++ * This file is licensed under the terms of the GNU General Public License
++ * version 2. This program is licensed "as is" without any warranty of any
++ * kind, whether express or implied.
++ */
++
++#include "r8a7795-h3ulcb-4x2g.dts"
++#include "ulcb-vbm.dtsi"
++
++/ {
++ model = "Renesas H3ULCB with 8GiB (4 x 2 GiB) Videobox Mini board based on r8a7795";
++};
++
++&du {
++ ports {
++ port@3 {
++ endpoint {
++ remote-endpoint = <&lvds_in>;
++ };
++ };
++ };
++};
+diff --git a/arch/arm64/boot/dts/renesas/r8a7795-h3ulcb-had-alfa.dts b/arch/arm64/boot/dts/renesas/r8a7795-h3ulcb-had-alfa.dts
+new file mode 100644
+index 0000000..ae115bd
+--- /dev/null
++++ b/arch/arm64/boot/dts/renesas/r8a7795-h3ulcb-had-alfa.dts
+@@ -0,0 +1,22 @@
++/*
++ * Device Tree Source for the H3ULCB.HAD board Alfa side
++ *
++ * Copyright (C) 2017 Renesas Electronics Corp.
++ * Copyright (C) 2017 Cogent Embedded, Inc.
++ *
++ * This file is licensed under the terms of the GNU General Public License
++ * version 2. This program is licensed "as is" without any warranty of any
++ * kind, whether express or implied.
++ */
++
++#include "r8a7795-h3ulcb-had.dtsi"
++
++/ {
++ model = "Renesas H3ULCB.HAD board Alfa side based on r8a7795";
++};
++
++&pciec0 {
++ status = "okay";
++
++ /* Root complex */
++};
+diff --git a/arch/arm64/boot/dts/renesas/r8a7795-h3ulcb-had-beta.dts b/arch/arm64/boot/dts/renesas/r8a7795-h3ulcb-had-beta.dts
+new file mode 100644
+index 0000000..805067e
+--- /dev/null
++++ b/arch/arm64/boot/dts/renesas/r8a7795-h3ulcb-had-beta.dts
+@@ -0,0 +1,23 @@
++/*
++ * Device Tree Source for the H3ULCB.HAD board Beta side
++ *
++ * Copyright (C) 2017 Renesas Electronics Corp.
++ * Copyright (C) 2017 Cogent Embedded, Inc.
++ *
++ * This file is licensed under the terms of the GNU General Public License
++ * version 2. This program is licensed "as is" without any warranty of any
++ * kind, whether express or implied.
++ */
++
++#include "r8a7795-h3ulcb-had.dtsi"
++
++/ {
++ model = "Renesas H3ULCB.HAD board Beta side based on r8a7795";
++};
++
++&pciec0 {
++ status = "okay";
++
++ /* Endpoint */
++ endpoint;
++};
+diff --git a/arch/arm64/boot/dts/renesas/r8a7795-h3ulcb-had.dtsi b/arch/arm64/boot/dts/renesas/r8a7795-h3ulcb-had.dtsi
+new file mode 100644
+index 0000000..2571de6
+--- /dev/null
++++ b/arch/arm64/boot/dts/renesas/r8a7795-h3ulcb-had.dtsi
+@@ -0,0 +1,196 @@
++/*
++ * Device Tree Source for the H3ULCB.HAD board on r8a7795
++ *
++ * Copyright (C) 2016-2017 Renesas Electronics Corp.
++ * Copyright (C) 2016-2017 Cogent Embedded, Inc.
++ *
++ * This file is licensed under the terms of the GNU General Public License
++ * version 2. This program is licensed "as is" without any warranty of any
++ * kind, whether express or implied.
++ */
++
++/*
++ * MSIOF0 - /dev/spidev1.0 connected to FPGA ethernet switch (both sides)
++ * MSIOF1 - /dev/spidev2.0 connected to RH850 (sideA to CSIH1, sideB to CSIH0)
++ */
++
++#include "r8a7795-h3ulcb-view.dts"
++
++/ {
++ model = "Renesas H3ULCB.HAD board based on r8a7795";
++
++ aliases {
++ serial0 = &scif1;
++ spi1 = &spi0_gpio;
++ spi2 = &spi1_gpio;
++ };
++
++ spi0_gpio: spi_gpio@0 {
++ compatible = "spi-gpio";
++ num-chipselects = <1>;
++ gpio-sck = <&gpio5 17 0>;
++ gpio-mosi = <&gpio5 20 0>;
++ gpio-miso = <&gpio5 22 0>;
++ cs-gpios = <&gpio5 19 0>;
++ #address-cells = <1>;
++ #size-cells = <0>;
++
++ spidev@0 {
++ compatible = "spi-gpio";
++ reg = <0>;
++ spi-max-frequency = <2000000>;
++ spi-cpha;
++ spi-cpol;
++ };
++ };
++
++ spi1_gpio: spi_gpio@1 {
++ compatible = "spi-gpio";
++ num-chipselects = <1>;
++ gpio-sck = <&gpio6 8 0>;
++ gpio-mosi = <&gpio6 7 0>;
++ gpio-miso = <&gpio6 10 0>;
++ cs-gpios = <&gpio6 5 0>;
++ #address-cells = <1>;
++ #size-cells = <0>;
++
++ spidev@0 {
++ compatible = "spi-gpio";
++ reg = <0>;
++ spi-max-frequency = <2000000>;
++ spi-cpha;
++ spi-cpol;
++ };
++ };
++
++ hdmi1-out {
++ compatible = "hdmi-connector";
++ label = "HDMI1 OUT";
++ type = "a";
++
++ port {
++ hdmi1_con: endpoint {
++ };
++ };
++ };
++};
++
++&hdmi1 {
++ status = "okay";
++
++ ports {
++ port@1 {
++ reg = <1>;
++ rcar_dw_hdmi1_out: endpoint {
++ remote-endpoint = <&hdmi1_con>;
++ };
++ };
++ };
++};
++
++&hdmi1_con {
++ remote-endpoint = <&rcar_dw_hdmi1_out>;
++};
++
++&pfc {
++ scif1_pins: scif1 {
++ groups = "scif1_data_a";
++ function = "scif1";
++ };
++
++ msiof0_pins: spi1 {
++ groups = "msiof0_clk", "msiof0_rxd", "msiof0_txd",
++ "msiof0_ss1";
++ function = "msiof0";
++ };
++
++ msiof1_pins: spi2 {
++ groups = "msiof1_clk_a", "msiof1_rxd_a", "msiof1_txd_a",
++ "msiof1_ss1_a";
++ function = "msiof1";
++ };
++
++ sound_clk_pins: sound-clk {
++ groups = "audio_clk_a_a", "audio_clk_b_a", "audio_clk_c_a",
++ "audio_clkout_a" /*, "audio_clkout3_a"*/;
++ function = "audio_clk";
++ };
++
++ usb31_pins: usb31 {
++ groups = "usb31";
++ function = "usb31";
++ };
++
++ can0_pins: can0 {
++ groups = "can0_data_a";
++ function = "can0";
++ };
++
++ canfd0_pins: canfd0 {
++ groups = "canfd0_data_a";
++ function = "canfd0";
++ };
++};
++
++&scif1 {
++ pinctrl-0 = <&scif1_pins>;
++ pinctrl-names = "default";
++ status = "okay";
++};
++
++&avb {
++ /delete-property/phy-handle;
++ /delete-property/phy-gpios;
++ /delete-node/ethernet-phy@0;
++
++ fixed-link {
++ speed = <1000>;
++ full-duplex;
++ };
++};
++
++&msiof0 {
++ pinctrl-0 = <&msiof0_pins>;
++ pinctrl-names = "default";
++ status = "disabled";
++ cs-gpios = <&gpio5 19 0>;
++
++ spidev@0 {
++ compatible = "renesas,sh-msiof";
++ reg = <0>;
++ spi-max-frequency = <66666666>;
++ spi-cpha;
++ spi-cpol;
++ };
++};
++
++&msiof1 {
++ status = "disabled";
++ cs-gpios = <&gpio6 5 0>;
++};
++
++&can0 {
++ pinctrl-0 = <&can0_pins>;
++ pinctrl-names = "default";
++ status = "disabled";
++
++ renesas,can-clock-select = <0x0>;
++ gpios = <&gpio2 6 GPIO_ACTIVE_HIGH /* enable - shared with camera board */
++ &gpio2 7 GPIO_ACTIVE_LOW /* standby */
++ >;
++};
++
++&canfd {
++ pinctrl-0 = <&canfd0_pins>;
++ pinctrl-names = "default";
++ status = "okay";
++
++ renesas,can-clock-select = <0x0>;
++ gpios = <&gpio2 6 GPIO_ACTIVE_HIGH /* enable - shared with camera board */
++ &gpio2 7 GPIO_ACTIVE_LOW /* standby */
++ >;
++
++ channel0 {
++ status = "okay";
++ };
++};
+diff --git a/arch/arm64/boot/dts/renesas/r8a7795-h3ulcb-kf.dts b/arch/arm64/boot/dts/renesas/r8a7795-h3ulcb-kf.dts
+index 80791ed..c848c0e 100644
+--- a/arch/arm64/boot/dts/renesas/r8a7795-h3ulcb-kf.dts
++++ b/arch/arm64/boot/dts/renesas/r8a7795-h3ulcb-kf.dts
+@@ -14,3 +14,28 @@
+ compatible = "shimafuji,kingfisher", "renesas,h3ulcb",
+ "renesas,r8a7795";
+ };
++
++&du {
++ ports {
++ port@0 {
++ endpoint {
++ remote-endpoint = <&adv7513_in>;
++ };
++ };
++ };
++};
++
++&lvds0 {
++ status = "okay";
++
++ ports {
++ port@1 {
++ lvds0_out: endpoint {
++ remote-endpoint = <&lvds_in>;
++ };
++ };
++ };
++};
++
++/* use CN11 instead default CN29/CN48 (H3 only) */
++//#include "ulcb-kf-cn11.dtsi"
+diff --git a/arch/arm64/boot/dts/renesas/r8a7795-h3ulcb-vb.dts b/arch/arm64/boot/dts/renesas/r8a7795-h3ulcb-vb.dts
+new file mode 100644
+index 0000000..26c15f4
+--- /dev/null
++++ b/arch/arm64/boot/dts/renesas/r8a7795-h3ulcb-vb.dts
+@@ -0,0 +1,68 @@
++/*
++ * Device Tree Source for the H3ULCB Videobox board on r8a7795
++ *
++ * Copyright (C) 2017 Cogent Embedded, Inc.
++ *
++ * This file is licensed under the terms of the GNU General Public License
++ * version 2. This program is licensed "as is" without any warranty of any
++ * kind, whether express or implied.
++ */
++
++#include "r8a7795-h3ulcb.dts"
++#include "ulcb-vb.dtsi"
++
++/ {
++ model = "Renesas H3ULCB Videobox board based on r8a7795";
++
++ hdmi1-out {
++ compatible = "hdmi-connector";
++ type = "a";
++
++ port {
++ hdmi1_con: endpoint {
++ remote-endpoint = <&rcar_dw_hdmi1_out>;
++ };
++ };
++ };
++};
++
++&du {
++ ports {
++ port@2 {
++ endpoint {
++ remote-endpoint = <&rcar_dw_hdmi1_in>;
++ };
++ };
++ port@3 {
++ endpoint {
++ remote-endpoint = <&lvds_in>;
++ };
++ };
++ };
++};
++
++&hdmi1 {
++ status = "okay";
++
++ ports {
++ #address-cells = <1>;
++ #size-cells = <0>;
++
++ port@0 {
++ reg = <0>;
++ rcar_dw_hdmi1_in: endpoint {
++ remote-endpoint = <&du_out_hdmi1>;
++ };
++ };
++ port@1 {
++ reg = <1>;
++ rcar_dw_hdmi1_out: endpoint {
++ remote-endpoint = <&hdmi1_con>;
++ };
++ };
++ };
++};
++
++&hsusb {
++ status = "okay";
++};
+diff --git a/arch/arm64/boot/dts/renesas/r8a7795-h3ulcb-vb2.dts b/arch/arm64/boot/dts/renesas/r8a7795-h3ulcb-vb2.dts
+new file mode 100644
+index 0000000..816c7da
+--- /dev/null
++++ b/arch/arm64/boot/dts/renesas/r8a7795-h3ulcb-vb2.dts
+@@ -0,0 +1,68 @@
++/*
++ * Device Tree Source for the H3ULCB Videobox board V2 on r8a7795
++ *
++ * Copyright (C) 2018 Cogent Embedded, Inc.
++ *
++ * This file is licensed under the terms of the GNU General Public License
++ * version 2. This program is licensed "as is" without any warranty of any
++ * kind, whether express or implied.
++ */
++
++#include "r8a7795-h3ulcb.dts"
++#include "ulcb-vb2.dtsi"
++
++/ {
++ model = "Renesas H3ULCB Videobox board based on r8a7795";
++
++ hdmi1-out {
++ compatible = "hdmi-connector";
++ type = "a";
++
++ port {
++ hdmi1_con: endpoint {
++ remote-endpoint = <&rcar_dw_hdmi1_out>;
++ };
++ };
++ };
++};
++
++&du {
++ ports {
++ port@2 {
++ endpoint {
++ remote-endpoint = <&rcar_dw_hdmi1_in>;
++ };
++ };
++ port@3 {
++ endpoint {
++ remote-endpoint = <&lvds_in>;
++ };
++ };
++ };
++};
++
++&hdmi1 {
++ status = "okay";
++
++ ports {
++ #address-cells = <1>;
++ #size-cells = <0>;
++
++ port@0 {
++ reg = <0>;
++ rcar_dw_hdmi1_in: endpoint {
++ remote-endpoint = <&du_out_hdmi1>;
++ };
++ };
++ port@1 {
++ reg = <1>;
++ rcar_dw_hdmi1_out: endpoint {
++ remote-endpoint = <&hdmi1_con>;
++ };
++ };
++ };
++};
++
++&hsusb {
++ status = "okay";
++};
+diff --git a/arch/arm64/boot/dts/renesas/r8a7795-h3ulcb-vbm.dts b/arch/arm64/boot/dts/renesas/r8a7795-h3ulcb-vbm.dts
+new file mode 100644
+index 0000000..053a60e
+--- /dev/null
++++ b/arch/arm64/boot/dts/renesas/r8a7795-h3ulcb-vbm.dts
+@@ -0,0 +1,26 @@
++/*
++ * Device Tree Source for the H3ULCB Videobox Mini board on r8a7795 ES1.x
++ *
++ * Copyright (C) 2017 Cogent Embedded, Inc.
++ *
++ * This file is licensed under the terms of the GNU General Public License
++ * version 2. This program is licensed "as is" without any warranty of any
++ * kind, whether express or implied.
++ */
++
++#include "r8a7795-h3ulcb.dts"
++#include "ulcb-vbm.dtsi"
++
++/ {
++ model = "Renesas H3ULCB Videobox Mini board based on r8a7795";
++};
++
++&du {
++ ports {
++ port@3 {
++ endpoint {
++ remote-endpoint = <&lvds_in>;
++ };
++ };
++ };
++};
+diff --git a/arch/arm64/boot/dts/renesas/r8a7795-h3ulcb-view.dts b/arch/arm64/boot/dts/renesas/r8a7795-h3ulcb-view.dts
+new file mode 100644
+index 0000000..ae90fb89
+--- /dev/null
++++ b/arch/arm64/boot/dts/renesas/r8a7795-h3ulcb-view.dts
+@@ -0,0 +1,544 @@
++/*
++ * Device Tree Source for the H3ULCB.View board
++ *
++ * Copyright (C) 2016-2017 Renesas Electronics Corp.
++ * Copyright (C) 2016-2017 Cogent Embedded, Inc.
++ *
++ * This file is licensed under the terms of the GNU General Public License
++ * version 2. This program is licensed "as is" without any warranty of any
++ * kind, whether express or implied.
++ */
++
++#include "r8a7795-h3ulcb.dts"
++
++/ {
++ model = "Renesas H3ULCB.View board based on r8a7795";
++};
++
++&i2c4 {
++ ov106xx@0 {
++ compatible = "ovti,ov106xx";
++ reg = <0x60>;
++
++ port@0 {
++ ov106xx_in0: endpoint {
++ clock-lanes = <0>;
++ data-lanes = <1 2 3 4>;
++ remote-endpoint = <&vin0ep0>;
++ };
++ };
++ port@1 {
++ ov106xx_max9286_des0ep0: endpoint@0 {
++ remote-endpoint = <&max9286_des0ep0>;
++ };
++ };
++ };
++
++ ov106xx@1 {
++ compatible = "ovti,ov106xx";
++ reg = <0x61>;
++
++ port@0 {
++ ov106xx_in1: endpoint {
++ clock-lanes = <0>;
++ data-lanes = <1 2 3 4>;
++ remote-endpoint = <&vin1ep0>;
++ };
++ };
++ port@1 {
++ ov106xx_max9286_des0ep1: endpoint@0 {
++ remote-endpoint = <&max9286_des0ep1>;
++ };
++ };
++ };
++
++ ov106xx@2 {
++ compatible = "ovti,ov106xx";
++ reg = <0x62>;
++
++ port@0 {
++ ov106xx_in2: endpoint {
++ clock-lanes = <0>;
++ data-lanes = <1 2 3 4>;
++ remote-endpoint = <&vin2ep0>;
++ };
++ };
++ port@1 {
++ ov106xx_max9286_des0ep2: endpoint@0 {
++ remote-endpoint = <&max9286_des0ep2>;
++ };
++ };
++ };
++
++ ov106xx@3 {
++ compatible = "ovti,ov106xx";
++ reg = <0x63>;
++
++ port@0 {
++ ov106xx_in3: endpoint {
++ clock-lanes = <0>;
++ data-lanes = <1 2 3 4>;
++ remote-endpoint = <&vin3ep0>;
++ };
++ };
++ port@1 {
++ ov106xx_des0ep3: endpoint {
++ remote-endpoint = <&max9286_des0ep3>;
++ };
++ };
++ };
++
++ ov106xx@4 {
++ compatible = "ovti,ov106xx";
++ reg = <0x64>;
++
++ port@0 {
++ ov106xx_in4: endpoint {
++ clock-lanes = <0>;
++ data-lanes = <1 2 3 4>;
++ remote-endpoint = <&vin4ep0>;
++ };
++ };
++ port@1 {
++ ov106xx_max9286_des1ep0: endpoint@0 {
++ remote-endpoint = <&max9286_des1ep0>;
++ };
++ };
++ };
++
++ ov106xx@5 {
++ compatible = "ovti,ov106xx";
++ reg = <0x65>;
++
++ port@0 {
++ ov106xx_in5: endpoint {
++ clock-lanes = <0>;
++ data-lanes = <1 2 3 4>;
++ remote-endpoint = <&vin5ep0>;
++ };
++ };
++ port@1 {
++ ov106xx_max9286_des1ep1: endpoint@0 {
++ remote-endpoint = <&max9286_des1ep1>;
++ };
++ };
++ };
++
++ ov106xx@6 {
++ compatible = "ovti,ov106xx";
++ reg = <0x66>;
++
++ port@0 {
++ ov106xx_in6: endpoint {
++ clock-lanes = <0>;
++ data-lanes = <1 2 3 4>;
++ remote-endpoint = <&vin6ep0>;
++ };
++ };
++ port@1 {
++ ov106xx_max9286_des1ep2: endpoint@0 {
++ remote-endpoint = <&max9286_des1ep2>;
++ };
++ };
++ };
++
++ ov106xx@7 {
++ compatible = "ovti,ov106xx";
++ reg = <0x67>;
++
++ port@0 {
++ ov106xx_in7: endpoint {
++ clock-lanes = <0>;
++ data-lanes = <1 2 3 4>;
++ remote-endpoint = <&vin7ep0>;
++ };
++ };
++ port@1 {
++ ov106xx_des1ep3: endpoint {
++ remote-endpoint = <&max9286_des1ep3>;
++ };
++ };
++ };
++
++ max9286@0 {
++ compatible = "maxim,max9286";
++ reg = <0x4c>;
++ gpios = <&gpio2 6 GPIO_ACTIVE_HIGH>;
++ maxim,links = <4>;
++ maxim,lanes = <4>;
++ maxim,resetb-gpio = <1>;
++ maxim,fsync-mode = "automatic";
++ maxim,timeout = <100>;
++ maxim,i2c-quirk = <0x6c>;
++
++ port@0 {
++ max9286_des0ep0: endpoint@0 {
++ max9271-addr = <0x50>;
++ dvp-order = <1>;
++ remote-endpoint = <&ov106xx_in0>;
++ };
++ max9286_des0ep1: endpoint@1 {
++ max9271-addr = <0x51>;
++ dvp-order = <1>;
++ remote-endpoint = <&ov106xx_in1>;
++ };
++ max9286_des0ep2: endpoint@2 {
++ max9271-addr = <0x52>;
++ dvp-order = <1>;
++ remote-endpoint = <&ov106xx_in2>;
++ };
++ max9286_des0ep3: endpoint@3 {
++ max9271-addr = <0x53>;
++ dvp-order = <1>;
++ remote-endpoint = <&ov106xx_in3>;
++ };
++ };
++ port@1 {
++ max9286_csi0ep0: endpoint {
++ csi-rate = <700>;
++ remote-endpoint = <&csi40_ep>;
++ };
++ };
++ };
++
++ max9286@1 {
++ compatible = "maxim,max9286";
++ reg = <0x6c>;
++ gpios = <&gpio5 25 GPIO_ACTIVE_HIGH>;
++ maxim,links = <4>;
++ maxim,lanes = <4>;
++ maxim,resetb-gpio = <1>;
++ maxim,fsync-mode = "automatic";
++ maxim,timeout = <100>;
++
++ port@0 {
++ max9286_des1ep0: endpoint@0 {
++ max9271-addr = <0x54>;
++ dvp-order = <1>;
++ remote-endpoint = <&ov106xx_in4>;
++ };
++ max9286_des1ep1: endpoint@1 {
++ max9271-addr = <0x55>;
++ dvp-order = <1>;
++ remote-endpoint = <&ov106xx_in5>;
++ };
++ max9286_des1ep2: endpoint@2 {
++ max9271-addr = <0x56>;
++ dvp-order = <1>;
++ remote-endpoint = <&ov106xx_in6>;
++ };
++ max9286_des1ep3: endpoint@3 {
++ max9271-addr = <0x57>;
++ dvp-order = <1>;
++ remote-endpoint = <&ov106xx_in7>;
++ };
++ };
++ port@1 {
++ max9286_csi2ep0: endpoint {
++ csi-rate = <700>;
++ remote-endpoint = <&csi41_ep>;
++ };
++ };
++ };
++};
++
++&pcie_bus_clk {
++ clock-frequency = <100000000>;
++ status = "okay";
++};
++
++&pciec1 {
++ status = "okay";
++};
++
++&vin0 {
++ status = "okay";
++
++ ports {
++ #address-cells = <1>;
++ #size-cells = <0>;
++
++ port@0 {
++ vin0ep0: endpoint {
++ csi,select = "csi40";
++ virtual,channel = <0>;
++ data-lanes = <1 2 3 4>;
++ remote-endpoint = <&ov106xx_in0>;
++ };
++ };
++ port@1 {
++ csi0ep0: endpoint {
++ remote-endpoint = <&csi40_ep>;
++ };
++ };
++ port@2 {
++ vin0_max9286_des0ep0: endpoint@0 {
++ remote-endpoint = <&max9286_des0ep0>;
++ };
++ };
++ };
++};
++
++&vin1 {
++ status = "okay";
++
++ ports {
++ #address-cells = <1>;
++ #size-cells = <0>;
++
++ port@0 {
++ vin1ep0: endpoint {
++ csi,select = "csi40";
++ virtual,channel = <1>;
++ data-lanes = <1 2 3 4>;
++ remote-endpoint = <&ov106xx_in1>;
++ };
++ };
++ port@1 {
++ csi0ep1: endpoint {
++ remote-endpoint = <&csi40_ep>;
++ };
++ };
++ port@2 {
++ vin1_max9286_des0ep1: endpoint@0 {
++ remote-endpoint = <&max9286_des0ep1>;
++ };
++ };
++ };
++};
++
++&vin2 {
++ status = "okay";
++
++ ports {
++ #address-cells = <1>;
++ #size-cells = <0>;
++
++ port@0 {
++ vin2ep0: endpoint {
++ csi,select = "csi40";
++ virtual,channel = <2>;
++ data-lanes = <1 2 3 4>;
++ remote-endpoint = <&ov106xx_in2>;
++ };
++ };
++ port@1 {
++ csi0ep2: endpoint {
++ remote-endpoint = <&csi40_ep>;
++ };
++ };
++ port@2 {
++ vin2_max9286_des0ep2: endpoint@0 {
++ remote-endpoint = <&max9286_des0ep2>;
++ };
++ };
++ };
++};
++
++&vin3 {
++ status = "okay";
++
++ ports {
++ #address-cells = <1>;
++ #size-cells = <0>;
++
++ port@0 {
++ vin3ep0: endpoint {
++ csi,select = "csi40";
++ virtual,channel = <3>;
++ data-lanes = <1 2 3 4>;
++ remote-endpoint = <&ov106xx_in3>;
++ };
++ };
++ port@1 {
++ csi0ep3: endpoint {
++ remote-endpoint = <&csi40_ep>;
++ };
++ };
++ port@2 {
++ vin3_max9286_des0ep3: endpoint@0 {
++ remote-endpoint = <&max9286_des0ep3>;
++ };
++ };
++ };
++};
++
++&vin4 {
++ status = "okay";
++
++ ports {
++ #address-cells = <1>;
++ #size-cells = <0>;
++
++ port@0 {
++ vin4ep0: endpoint {
++ csi,select = "csi41";
++ virtual,channel = <0>;
++ remote-endpoint = <&ov106xx_in4>;
++ data-lanes = <1 2 3 4>;
++ };
++ };
++ port@1 {
++ csi2ep0: endpoint {
++ remote-endpoint = <&csi41_ep>;
++ };
++ };
++ port@2 {
++ vin4_max9286_des1ep0: endpoint@0 {
++ remote-endpoint = <&max9286_des1ep0>;
++ };
++ };
++ };
++};
++
++&vin5 {
++ status = "okay";
++
++ ports {
++ #address-cells = <1>;
++ #size-cells = <0>;
++
++ port@0 {
++ vin5ep0: endpoint@0 {
++ csi,select = "csi41";
++ virtual,channel = <1>;
++ remote-endpoint = <&ov106xx_in5>;
++ data-lanes = <1 2 3 4>;
++ };
++ };
++ port@1 {
++ csi2ep1: endpoint {
++ remote-endpoint = <&csi41_ep>;
++ };
++ };
++ port@2 {
++ vin5_max9286_des1ep1: endpoint@0 {
++ remote-endpoint = <&max9286_des1ep1>;
++ };
++ };
++ };
++};
++
++&vin6 {
++ status = "okay";
++
++ ports {
++ #address-cells = <1>;
++ #size-cells = <0>;
++
++ port@0 {
++ vin6ep0: endpoint@0 {
++ csi,select = "csi41";
++ virtual,channel = <2>;
++ remote-endpoint = <&ov106xx_in6>;
++ data-lanes = <1 2 3 4>;
++ };
++ };
++ port@1 {
++ csi2ep2: endpoint {
++ remote-endpoint = <&csi41_ep>;
++ };
++ };
++ port@2 {
++ vin6_max9286_des1ep2: endpoint@0 {
++ remote-endpoint = <&max9286_des1ep2>;
++ };
++ };
++ };
++};
++
++&vin7 {
++ status = "okay";
++
++ ports {
++ #address-cells = <1>;
++ #size-cells = <0>;
++
++ port@0 {
++ vin7ep0: endpoint@0 {
++ csi,select = "csi41";
++ virtual,channel = <3>;
++ remote-endpoint = <&ov106xx_in7>;
++ data-lanes = <1 2 3 4>;
++ };
++ };
++ port@1 {
++ csi2ep3: endpoint {
++ remote-endpoint = <&csi41_ep>;
++ };
++ };
++ port@2 {
++ vin7_max9286_des1ep3: endpoint@0 {
++ remote-endpoint = <&max9286_des1ep3>;
++ };
++ };
++ };
++};
++
++&csi40 {
++ status = "okay";
++
++ virtual,channel {
++ csi2_vc0 {
++ data,type = "ycbcr422";
++ receive,vc = <0>;
++ };
++ csi2_vc1 {
++ data,type = "ycbcr422";
++ receive,vc = <1>;
++ };
++ csi2_vc2 {
++ data,type = "ycbcr422";
++ receive,vc = <2>;
++ };
++ csi2_vc3 {
++ data,type = "ycbcr422";
++ receive,vc = <3>;
++ };
++ };
++
++ port {
++ #address-cells = <1>;
++ #size-cells = <0>;
++
++ csi40_ep: endpoint {
++ clock-lanes = <0>;
++ data-lanes = <1 2 3 4>;
++ csi-rate = <300>;
++ };
++ };
++};
++
++&csi41 {
++ status = "okay";
++
++ virtual,channel {
++ csi2_vc0 {
++ data,type = "ycbcr422";
++ receive,vc = <0>;
++ };
++ csi2_vc1 {
++ data,type = "ycbcr422";
++ receive,vc = <1>;
++ };
++ csi2_vc2 {
++ data,type = "ycbcr422";
++ receive,vc = <2>;
++ };
++ csi2_vc3 {
++ data,type = "ycbcr422";
++ receive,vc = <3>;
++ };
++ };
++
++ port {
++ #address-cells = <1>;
++ #size-cells = <0>;
++
++ csi41_ep: endpoint {
++ clock-lanes = <0>;
++ data-lanes = <1 2 3 4>;
++ csi-rate = <300>;
++ };
++ };
++};
+diff --git a/arch/arm64/boot/dts/renesas/r8a7795-salvator-x-view.dts b/arch/arm64/boot/dts/renesas/r8a7795-salvator-x-view.dts
+new file mode 100644
+index 0000000..d4d5557
+--- /dev/null
++++ b/arch/arm64/boot/dts/renesas/r8a7795-salvator-x-view.dts
+@@ -0,0 +1,550 @@
++/*
++ * Device Tree Source for the Salvator-X.View board
++ *
++ * Copyright (C) 2016-2017 Renesas Electronics Corp.
++ * Copyright (C) 2015-2017 Cogent Embedded, Inc
++ *
++ * This file is licensed under the terms of the GNU General Public License
++ * version 2. This program is licensed "as is" without any warranty of any
++ * kind, whether express or implied.
++ */
++
++#include "r8a7795-salvator-x.dts"
++
++/ {
++ model = "Renesas Salvator-X.View board based on r8a7795";
++};
++
++&pfc {
++ can0_pins: can0 {
++ groups = "can0_data_a";
++ function = "can0";
++ };
++
++ can1_pins: can1 {
++ groups = "can1_data";
++ function = "can1";
++ };
++};
++
++&i2c4 {
++ /delete-node/hdmi-in@34;
++ /delete-node/composite-in@70;
++
++ ov106xx@0 {
++ compatible = "ovti,ov106xx";
++ reg = <0x60>;
++
++ port@0 {
++ ov106xx_in0: endpoint {
++ clock-lanes = <0>;
++ data-lanes = <1 2 3 4>;
++ remote-endpoint = <&vin0ep0>;
++ };
++ };
++ port@1 {
++ ov106xx_max9286_des0ep0: endpoint@0 {
++ remote-endpoint = <&max9286_des0ep0>;
++ };
++ };
++ };
++
++ ov106xx@1 {
++ compatible = "ovti,ov106xx";
++ reg = <0x61>;
++
++ port@0 {
++ ov106xx_in1: endpoint {
++ clock-lanes = <0>;
++ data-lanes = <1 2 3 4>;
++ remote-endpoint = <&vin1ep0>;
++ };
++ };
++ port@1 {
++ ov106xx_max9286_des0ep1: endpoint@0 {
++ remote-endpoint = <&max9286_des0ep1>;
++ };
++ };
++ };
++
++ ov106xx@2 {
++ compatible = "ovti,ov106xx";
++ reg = <0x62>;
++
++ port@0 {
++ ov106xx_in2: endpoint {
++ clock-lanes = <0>;
++ data-lanes = <1 2 3 4>;
++ remote-endpoint = <&vin2ep0>;
++ };
++ };
++ port@1 {
++ ov106xx_max9286_des0ep2: endpoint@0 {
++ remote-endpoint = <&max9286_des0ep2>;
++ };
++ };
++ };
++
++ ov106xx@3 {
++ compatible = "ovti,ov106xx";
++ reg = <0x63>;
++
++ port@0 {
++ ov106xx_in3: endpoint {
++ clock-lanes = <0>;
++ data-lanes = <1 2 3 4>;
++ remote-endpoint = <&vin3ep0>;
++ };
++ };
++ port@1 {
++ ov106xx_des0ep3: endpoint {
++ remote-endpoint = <&max9286_des0ep3>;
++ };
++ };
++ };
++
++ ov106xx@4 {
++ compatible = "ovti,ov106xx";
++ reg = <0x64>;
++
++ port@0 {
++ ov106xx_in4: endpoint {
++ clock-lanes = <0>;
++ data-lanes = <1 2 3 4>;
++ remote-endpoint = <&vin4ep0>;
++ };
++ };
++ port@1 {
++ ov106xx_max9286_des1ep0: endpoint@0 {
++ remote-endpoint = <&max9286_des1ep0>;
++ };
++ };
++ };
++
++ ov106xx@5 {
++ compatible = "ovti,ov106xx";
++ reg = <0x65>;
++
++ port@0 {
++ ov106xx_in5: endpoint {
++ clock-lanes = <0>;
++ data-lanes = <1 2 3 4>;
++ remote-endpoint = <&vin5ep0>;
++ };
++ };
++ port@1 {
++ ov106xx_max9286_des1ep1: endpoint@0 {
++ remote-endpoint = <&max9286_des1ep1>;
++ };
++ };
++ };
++
++ ov106xx@6 {
++ compatible = "ovti,ov106xx";
++ reg = <0x66>;
++
++ port@0 {
++ ov106xx_in6: endpoint {
++ clock-lanes = <0>;
++ data-lanes = <1 2 3 4>;
++ remote-endpoint = <&vin6ep0>;
++ };
++ };
++ port@1 {
++ ov106xx_max9286_des1ep2: endpoint@0 {
++ remote-endpoint = <&max9286_des1ep2>;
++ };
++ };
++ };
++
++ ov106xx@7 {
++ compatible = "ovti,ov106xx";
++ reg = <0x67>;
++
++ port@0 {
++ ov106xx_in7: endpoint {
++ clock-lanes = <0>;
++ data-lanes = <1 2 3 4>;
++ remote-endpoint = <&vin7ep0>;
++ };
++ };
++ port@1 {
++ ov106xx_des1ep3: endpoint {
++ remote-endpoint = <&max9286_des1ep3>;
++ };
++ };
++ };
++
++ max9286@0 {
++ compatible = "maxim,max9286";
++ reg = <0x4c>;
++ gpios = <&gpio6 30 GPIO_ACTIVE_LOW>;
++ maxim,links = <4>;
++ maxim,lanes = <4>;
++ maxim,resetb-gpio = <1>;
++ maxim,fsync-mode = "automatic";
++ maxim,timeout = <100>;
++ maxim,i2c-quirk = <0x6c>;
++
++ port@0 {
++ max9286_des0ep0: endpoint@0 {
++ max9271-addr = <0x50>;
++ dvp-order = <1>;
++ remote-endpoint = <&ov106xx_in0>;
++ };
++ max9286_des0ep1: endpoint@1 {
++ max9271-addr = <0x51>;
++ dvp-order = <1>;
++ remote-endpoint = <&ov106xx_in1>;
++ };
++ max9286_des0ep2: endpoint@2 {
++ max9271-addr = <0x52>;
++ dvp-order = <1>;
++ remote-endpoint = <&ov106xx_in2>;
++ };
++ max9286_des0ep3: endpoint@3 {
++ max9271-addr = <0x53>;
++ dvp-order = <1>;
++ remote-endpoint = <&ov106xx_in3>;
++ };
++ };
++ port@1 {
++ max9286_csi0ep0: endpoint {
++ csi-rate = <700>;
++ remote-endpoint = <&csi40_ep>;
++ };
++ };
++ };
++
++ max9286@1 {
++ compatible = "maxim,max9286";
++ reg = <0x6c>;
++ maxim,links = <4>;
++ maxim,lanes = <4>;
++ maxim,resetb-gpio = <1>;
++ maxim,fsync-mode = "automatic";
++ maxim,timeout = <100>;
++
++ port@0 {
++ max9286_des1ep0: endpoint@0 {
++ max9271-addr = <0x54>;
++ dvp-order = <1>;
++ remote-endpoint = <&ov106xx_in4>;
++ };
++ max9286_des1ep1: endpoint@1 {
++ max9271-addr = <0x55>;
++ dvp-order = <1>;
++ remote-endpoint = <&ov106xx_in5>;
++ };
++ max9286_des1ep2: endpoint@2 {
++ max9271-addr = <0x56>;
++ dvp-order = <1>;
++ remote-endpoint = <&ov106xx_in6>;
++ };
++ max9286_des1ep3: endpoint@3 {
++ max9271-addr = <0x57>;
++ dvp-order = <1>;
++ remote-endpoint = <&ov106xx_in7>;
++ };
++ };
++ port@1 {
++ max9286_csi2ep0: endpoint {
++ csi-rate = <700>;
++ remote-endpoint = <&csi41_ep>;
++ };
++ };
++ };
++};
++
++&vin0 {
++ ports {
++ #address-cells = <1>;
++ #size-cells = <0>;
++
++ port@0 {
++ vin0ep0: endpoint {
++ csi,select = "csi40";
++ virtual,channel = <0>;
++ data-lanes = <1 2 3 4>;
++ remote-endpoint = <&ov106xx_in0>;
++ };
++ };
++ port@1 {
++ csi0ep0: endpoint {
++ remote-endpoint = <&csi40_ep>;
++ };
++ };
++ port@2 {
++ vin0_max9286_des0ep0: endpoint@0 {
++ remote-endpoint = <&max9286_des0ep0>;
++ };
++ };
++ };
++};
++
++&vin1 {
++ ports {
++ #address-cells = <1>;
++ #size-cells = <0>;
++
++ port@0 {
++ vin1ep0: endpoint {
++ csi,select = "csi40";
++ virtual,channel = <1>;
++ data-lanes = <1 2 3 4>;
++ remote-endpoint = <&ov106xx_in1>;
++ };
++ };
++ port@1 {
++ csi0ep1: endpoint {
++ remote-endpoint = <&csi40_ep>;
++ };
++ };
++ port@2 {
++ vin1_max9286_des0ep1: endpoint@0 {
++ remote-endpoint = <&max9286_des0ep1>;
++ };
++ };
++ };
++};
++
++&vin2 {
++ ports {
++ #address-cells = <1>;
++ #size-cells = <0>;
++
++ port@0 {
++ vin2ep0: endpoint {
++ csi,select = "csi40";
++ virtual,channel = <2>;
++ data-lanes = <1 2 3 4>;
++ remote-endpoint = <&ov106xx_in2>;
++ };
++ };
++ port@1 {
++ csi0ep2: endpoint {
++ remote-endpoint = <&csi40_ep>;
++ };
++ };
++ port@2 {
++ vin2_max9286_des0ep2: endpoint@0 {
++ remote-endpoint = <&max9286_des0ep2>;
++ };
++ };
++ };
++};
++
++&vin3 {
++ ports {
++ #address-cells = <1>;
++ #size-cells = <0>;
++
++ port@0 {
++ vin3ep0: endpoint {
++ csi,select = "csi40";
++ virtual,channel = <3>;
++ data-lanes = <1 2 3 4>;
++ remote-endpoint = <&ov106xx_in3>;
++ };
++ };
++ port@1 {
++ csi0ep3: endpoint {
++ remote-endpoint = <&csi40_ep>;
++ };
++ };
++ port@2 {
++ vin3_max9286_des0ep3: endpoint@0 {
++ remote-endpoint = <&max9286_des0ep3>;
++ };
++ };
++ };
++};
++
++&vin4 {
++ ports {
++ #address-cells = <1>;
++ #size-cells = <0>;
++
++ port@0 {
++ vin4ep0: endpoint {
++ csi,select = "csi41";
++ virtual,channel = <0>;
++ remote-endpoint = <&ov106xx_in4>;
++ data-lanes = <1 2 3 4>;
++ };
++ };
++ port@1 {
++ csi2ep0: endpoint {
++ remote-endpoint = <&csi41_ep>;
++ };
++ };
++ port@2 {
++ vin4_max9286_des1ep0: endpoint@0 {
++ remote-endpoint = <&max9286_des1ep0>;
++ };
++ };
++ };
++};
++
++&vin5 {
++ ports {
++ #address-cells = <1>;
++ #size-cells = <0>;
++
++ port@0 {
++ vin5ep0: endpoint@0 {
++ csi,select = "csi41";
++ virtual,channel = <1>;
++ remote-endpoint = <&ov106xx_in5>;
++ data-lanes = <1 2 3 4>;
++ };
++ };
++ port@1 {
++ csi2ep1: endpoint {
++ remote-endpoint = <&csi41_ep>;
++ };
++ };
++ port@2 {
++ vin5_max9286_des1ep1: endpoint@0 {
++ remote-endpoint = <&max9286_des1ep1>;
++ };
++ };
++ };
++};
++
++&vin6 {
++ ports {
++ #address-cells = <1>;
++ #size-cells = <0>;
++
++ port@0 {
++ vin6ep0: endpoint@0 {
++ csi,select = "csi41";
++ virtual,channel = <2>;
++ remote-endpoint = <&ov106xx_in6>;
++ data-lanes = <1 2 3 4>;
++ };
++ };
++ port@1 {
++ csi2ep2: endpoint {
++ remote-endpoint = <&csi41_ep>;
++ };
++ };
++ port@2 {
++ vin6_max9286_des1ep2: endpoint@0 {
++ remote-endpoint = <&max9286_des1ep2>;
++ };
++ };
++ };
++};
++
++&vin7 {
++ ports {
++ #address-cells = <1>;
++ #size-cells = <0>;
++
++ port@0 {
++ vin7ep0: endpoint@0 {
++ csi,select = "csi41";
++ virtual,channel = <3>;
++ remote-endpoint = <&ov106xx_in7>;
++ data-lanes = <1 2 3 4>;
++ };
++ };
++ port@1 {
++ csi2ep3: endpoint {
++ remote-endpoint = <&csi41_ep>;
++ };
++ };
++ port@2 {
++ vin7_max9286_des1ep3: endpoint@0 {
++ remote-endpoint = <&max9286_des1ep3>;
++ };
++ };
++ };
++};
++
++&csi20 {
++ status = "disabled";
++ /delete-node/ports;
++};
++
++&csi40 {
++ /delete-node/ports;
++
++ virtual,channel {
++ csi2_vc0 {
++ data,type = "ycbcr422";
++ receive,vc = <0>;
++ };
++ csi2_vc1 {
++ data,type = "ycbcr422";
++ receive,vc = <1>;
++ };
++ csi2_vc2 {
++ data,type = "ycbcr422";
++ receive,vc = <2>;
++ };
++ csi2_vc3 {
++ data,type = "ycbcr422";
++ receive,vc = <3>;
++ };
++ };
++
++ port {
++ #address-cells = <1>;
++ #size-cells = <0>;
++
++ csi40_ep: endpoint {
++ clock-lanes = <0>;
++ data-lanes = <1 2 3 4>;
++ csi-rate = <300>;
++ };
++ };
++};
++
++&csi41 {
++ status = "okay";
++
++ virtual,channel {
++ csi2_vc0 {
++ data,type = "ycbcr422";
++ receive,vc = <0>;
++ };
++ csi2_vc1 {
++ data,type = "ycbcr422";
++ receive,vc = <1>;
++ };
++ csi2_vc2 {
++ data,type = "ycbcr422";
++ receive,vc = <2>;
++ };
++ csi2_vc3 {
++ data,type = "ycbcr422";
++ receive,vc = <3>;
++ };
++ };
++
++ port {
++ #address-cells = <1>;
++ #size-cells = <0>;
++
++ csi41_ep: endpoint {
++ clock-lanes = <0>;
++ data-lanes = <1 2 3 4>;
++ csi-rate = <300>;
++ };
++ };
++};
++
++&can0 {
++ pinctrl-0 = <&can0_pins>;
++ pinctrl-names = "default";
++ status = "okay";
++};
++
++&can1 {
++ pinctrl-0 = <&can1_pins>;
++ pinctrl-names = "default";
++ status = "okay";
++};
+diff --git a/arch/arm64/boot/dts/renesas/r8a7796-m3ulcb-kf.dts b/arch/arm64/boot/dts/renesas/r8a7796-m3ulcb-kf.dts
+index 2df50eb..803d3e1 100644
+--- a/arch/arm64/boot/dts/renesas/r8a7796-m3ulcb-kf.dts
++++ b/arch/arm64/boot/dts/renesas/r8a7796-m3ulcb-kf.dts
+@@ -14,3 +14,29 @@
+ compatible = "shimafuji,kingfisher", "renesas,m3ulcb",
+ "renesas,r8a7796";
+ };
++
++&du {
++ ports {
++ port@0 {
++ endpoint {
++ remote-endpoint = <&adv7513_in>;
++ };
++ };
++ };
++};
++
++&lvds0 {
++ status = "okay";
++
++ ports {
++ port@1 {
++ lvds0_out: endpoint {
++ remote-endpoint = <&lvds_in>;
++ };
++ };
++ };
++};
++
++&xhci0 {
++ status = "disabled";
++};
+diff --git a/arch/arm64/boot/dts/renesas/r8a7796-m3ulcb-view.dts b/arch/arm64/boot/dts/renesas/r8a7796-m3ulcb-view.dts
+new file mode 100644
+index 0000000..9e764c5
+--- /dev/null
++++ b/arch/arm64/boot/dts/renesas/r8a7796-m3ulcb-view.dts
+@@ -0,0 +1,286 @@
++/*
++ * Device Tree Source for the M3ULCB.View board on r8a7796
++ *
++ * Copyright (C) 2016-2017 Renesas Electronics Corp.
++ * Copyright (C) 2016-2017 Cogent Embedded, Inc.
++ *
++ * This file is licensed under the terms of the GNU General Public License
++ * version 2. This program is licensed "as is" without any warranty of any
++ * kind, whether express or implied.
++ */
++
++#include "r8a7796-m3ulcb.dts"
++
++/ {
++ model = "Renesas M3ULCB.View board based on r8a7796";
++};
++
++&i2c4 {
++ ov106xx@0 {
++ compatible = "ovti,ov106xx";
++ reg = <0x60>;
++
++ port@0 {
++ ov106xx_in0: endpoint {
++ clock-lanes = <0>;
++ data-lanes = <1 2 3 4>;
++ remote-endpoint = <&vin0ep0>;
++ };
++ };
++ port@1 {
++ ov106xx_max9286_des0ep0: endpoint@0 {
++ remote-endpoint = <&max9286_des0ep0>;
++ };
++ };
++ };
++
++ ov106xx@1 {
++ compatible = "ovti,ov106xx";
++ reg = <0x61>;
++
++ port@0 {
++ ov106xx_in1: endpoint {
++ clock-lanes = <0>;
++ data-lanes = <1 2 3 4>;
++ remote-endpoint = <&vin1ep0>;
++ };
++ };
++ port@1 {
++ ov106xx_max9286_des0ep1: endpoint@0 {
++ remote-endpoint = <&max9286_des0ep1>;
++ };
++ };
++ };
++
++ ov106xx@2 {
++ compatible = "ovti,ov106xx";
++ reg = <0x62>;
++
++ port@0 {
++ ov106xx_in2: endpoint {
++ clock-lanes = <0>;
++ data-lanes = <1 2 3 4>;
++ remote-endpoint = <&vin2ep0>;
++ };
++ };
++ port@1 {
++ ov106xx_max9286_des0ep2: endpoint@0 {
++ remote-endpoint = <&max9286_des0ep2>;
++ };
++ };
++ };
++
++ ov106xx@3 {
++ compatible = "ovti,ov106xx";
++ reg = <0x63>;
++
++ port@0 {
++ ov106xx_in3: endpoint {
++ clock-lanes = <0>;
++ data-lanes = <1 2 3 4>;
++ remote-endpoint = <&vin3ep0>;
++ };
++ };
++ port@1 {
++ ov106xx_des0ep3: endpoint {
++ remote-endpoint = <&max9286_des0ep3>;
++ };
++ };
++ };
++
++ max9286@0 {
++ compatible = "maxim,max9286";
++ reg = <0x4c>;
++ gpios = <&gpio2 6 GPIO_ACTIVE_HIGH>;
++ maxim,links = <4>;
++ maxim,lanes = <4>;
++ maxim,resetb-gpio = <1>;
++ maxim,fsync-mode = "automatic";
++ maxim,timeout = <100>;
++ maxim,i2c-quirk = <0x6c>;
++
++ port@0 {
++ max9286_des0ep0: endpoint@0 {
++ max9271-addr = <0x50>;
++ dvp-order = <1>;
++ remote-endpoint = <&ov106xx_in0>;
++ };
++ max9286_des0ep1: endpoint@1 {
++ max9271-addr = <0x51>;
++ dvp-order = <1>;
++ remote-endpoint = <&ov106xx_in1>;
++ };
++ max9286_des0ep2: endpoint@2 {
++ max9271-addr = <0x52>;
++ dvp-order = <1>;
++ remote-endpoint = <&ov106xx_in2>;
++ };
++ max9286_des0ep3: endpoint@3 {
++ max9271-addr = <0x53>;
++ dvp-order = <1>;
++ remote-endpoint = <&ov106xx_in3>;
++ };
++ };
++ port@1 {
++ max9286_csi0ep0: endpoint {
++ csi-rate = <700>;
++ remote-endpoint = <&csi40_ep>;
++ };
++ };
++ };
++};
++
++&pcie_bus_clk {
++ clock-frequency = <100000000>;
++ status = "okay";
++};
++
++&pciec1 {
++ status = "okay";
++};
++
++&vin0 {
++ status = "okay";
++
++ ports {
++ #address-cells = <1>;
++ #size-cells = <0>;
++
++ port@0 {
++ vin0ep0: endpoint {
++ csi,select = "csi40";
++ virtual,channel = <0>;
++ data-lanes = <1 2 3 4>;
++ remote-endpoint = <&ov106xx_in0>;
++ };
++ };
++ port@1 {
++ csi0ep0: endpoint {
++ remote-endpoint = <&csi40_ep>;
++ };
++ };
++ port@2 {
++ vin0_max9286_des0ep0: endpoint@0 {
++ remote-endpoint = <&max9286_des0ep0>;
++ };
++ };
++ };
++};
++
++&vin1 {
++ status = "okay";
++
++ ports {
++ #address-cells = <1>;
++ #size-cells = <0>;
++
++ port@0 {
++ vin1ep0: endpoint {
++ csi,select = "csi40";
++ virtual,channel = <1>;
++ data-lanes = <1 2 3 4>;
++ remote-endpoint = <&ov106xx_in1>;
++ };
++ };
++ port@1 {
++ csi0ep1: endpoint {
++ remote-endpoint = <&csi40_ep>;
++ };
++ };
++ port@2 {
++ vin1_max9286_des0ep1: endpoint@0 {
++ remote-endpoint = <&max9286_des0ep1>;
++ };
++ };
++ };
++};
++
++&vin2 {
++ status = "okay";
++
++ ports {
++ #address-cells = <1>;
++ #size-cells = <0>;
++
++ port@0 {
++ vin2ep0: endpoint {
++ csi,select = "csi40";
++ virtual,channel = <2>;
++ data-lanes = <1 2 3 4>;
++ remote-endpoint = <&ov106xx_in2>;
++ };
++ };
++ port@1 {
++ csi0ep2: endpoint {
++ remote-endpoint = <&csi40_ep>;
++ };
++ };
++ port@2 {
++ vin2_max9286_des0ep2: endpoint@0 {
++ remote-endpoint = <&max9286_des0ep2>;
++ };
++ };
++ };
++};
++
++&vin3 {
++ status = "okay";
++
++ ports {
++ #address-cells = <1>;
++ #size-cells = <0>;
++
++ port@0 {
++ vin3ep0: endpoint {
++ csi,select = "csi40";
++ virtual,channel = <3>;
++ data-lanes = <1 2 3 4>;
++ remote-endpoint = <&ov106xx_in3>;
++ };
++ };
++ port@1 {
++ csi0ep3: endpoint {
++ remote-endpoint = <&csi40_ep>;
++ };
++ };
++ port@2 {
++ vin3_max9286_des0ep3: endpoint@0 {
++ remote-endpoint = <&max9286_des0ep3>;
++ };
++ };
++ };
++};
++
++&csi40 {
++ status = "okay";
++
++ virtual,channel {
++ csi2_vc0 {
++ data,type = "ycbcr422";
++ receive,vc = <0>;
++ };
++ csi2_vc1 {
++ data,type = "ycbcr422";
++ receive,vc = <1>;
++ };
++ csi2_vc2 {
++ data,type = "ycbcr422";
++ receive,vc = <2>;
++ };
++ csi2_vc3 {
++ data,type = "ycbcr422";
++ receive,vc = <3>;
++ };
++ };
++
++ port {
++ #address-cells = <1>;
++ #size-cells = <0>;
++
++ csi40_ep: endpoint {
++ clock-lanes = <0>;
++ data-lanes = <1 2 3 4>;
++ csi-rate = <300>;
++ };
++ };
++};
+diff --git a/arch/arm64/boot/dts/renesas/r8a7796-salvator-x-view.dts b/arch/arm64/boot/dts/renesas/r8a7796-salvator-x-view.dts
+new file mode 100644
+index 0000000..f734437
+--- /dev/null
++++ b/arch/arm64/boot/dts/renesas/r8a7796-salvator-x-view.dts
+@@ -0,0 +1,317 @@
++/*
++ * Device Tree Source for the Salvator-X.View board
++ *
++ * Copyright (C) 2016-2017 Renesas Electronics Corp.
++ * Copyright (C) 2016-2017 Cogent Embedded, Inc
++ *
++ * This file is licensed under the terms of the GNU General Public License
++ * version 2. This program is licensed "as is" without any warranty of any
++ * kind, whether express or implied.
++ */
++
++#include "r8a7796-salvator-x.dts"
++
++/ {
++ model = "Renesas Salvator-X.View board based on r8a7796";
++};
++
++&pfc {
++ can0_pins: can0 {
++ groups = "can0_data_a";
++ function = "can0";
++ };
++
++ can1_pins: can1 {
++ groups = "can1_data";
++ function = "can1";
++ };
++};
++
++&i2c4 {
++ /delete-node/hdmi-in@34;
++ /delete-node/composite-in@70;
++
++ ov106xx@0 {
++ compatible = "ovti,ov106xx";
++ reg = <0x60>;
++
++ port@0 {
++ ov106xx_in0: endpoint {
++ clock-lanes = <0>;
++ data-lanes = <1 2 3 4>;
++ remote-endpoint = <&vin0ep0>;
++ };
++ };
++ port@1 {
++ ov106xx_max9286_des0ep0: endpoint@0 {
++ remote-endpoint = <&max9286_des0ep0>;
++ };
++ };
++ };
++
++ ov106xx@1 {
++ compatible = "ovti,ov106xx";
++ reg = <0x61>;
++
++ port@0 {
++ ov106xx_in1: endpoint {
++ clock-lanes = <0>;
++ data-lanes = <1 2 3 4>;
++ remote-endpoint = <&vin1ep0>;
++ };
++ };
++ port@1 {
++ ov106xx_max9286_des0ep1: endpoint@0 {
++ remote-endpoint = <&max9286_des0ep1>;
++ };
++ };
++ };
++
++ ov106xx@2 {
++ compatible = "ovti,ov106xx";
++ reg = <0x62>;
++
++ port@0 {
++ ov106xx_in2: endpoint {
++ clock-lanes = <0>;
++ data-lanes = <1 2 3 4>;
++ remote-endpoint = <&vin2ep0>;
++ };
++ };
++ port@1 {
++ ov106xx_max9286_des0ep2: endpoint@0 {
++ remote-endpoint = <&max9286_des0ep2>;
++ };
++ };
++ };
++
++ ov106xx@3 {
++ compatible = "ovti,ov106xx";
++ reg = <0x63>;
++
++ port@0 {
++ ov106xx_in3: endpoint {
++ clock-lanes = <0>;
++ data-lanes = <1 2 3 4>;
++ remote-endpoint = <&vin3ep0>;
++ };
++ };
++ port@1 {
++ ov106xx_des0ep3: endpoint {
++ remote-endpoint = <&max9286_des0ep3>;
++ };
++ };
++ };
++
++ max9286@0 {
++ compatible = "maxim,max9286";
++ reg = <0x4c>;
++ gpios = <&gpio6 30 GPIO_ACTIVE_LOW>;
++ maxim,links = <4>;
++ maxim,lanes = <4>;
++ maxim,resetb-gpio = <1>;
++ maxim,fsync-mode = "automatic";
++ maxim,timeout = <100>;
++ maxim,i2c-quirk = <0x6c>;
++
++ port@0 {
++ max9286_des0ep0: endpoint@0 {
++ max9271-addr = <0x50>;
++ dvp-order = <1>;
++ remote-endpoint = <&ov106xx_in0>;
++ };
++ max9286_des0ep1: endpoint@1 {
++ max9271-addr = <0x51>;
++ dvp-order = <1>;
++ remote-endpoint = <&ov106xx_in1>;
++ };
++ max9286_des0ep2: endpoint@2 {
++ max9271-addr = <0x52>;
++ dvp-order = <1>;
++ remote-endpoint = <&ov106xx_in2>;
++ };
++ max9286_des0ep3: endpoint@3 {
++ max9271-addr = <0x53>;
++ dvp-order = <1>;
++ remote-endpoint = <&ov106xx_in3>;
++ };
++ };
++ port@1 {
++ max9286_csi0ep0: endpoint {
++ csi-rate = <700>;
++ remote-endpoint = <&csi40_ep>;
++ };
++ };
++ };
++};
++
++&vin0 {
++ ports {
++ #address-cells = <1>;
++ #size-cells = <0>;
++
++ port@0 {
++ vin0ep0: endpoint {
++ csi,select = "csi40";
++ virtual,channel = <0>;
++ data-lanes = <1 2 3 4>;
++ remote-endpoint = <&ov106xx_in0>;
++ };
++ };
++ port@1 {
++ csi0ep0: endpoint {
++ remote-endpoint = <&csi40_ep>;
++ };
++ };
++ port@2 {
++ vin0_max9286_des0ep0: endpoint@0 {
++ remote-endpoint = <&max9286_des0ep0>;
++ };
++ };
++ };
++};
++
++&vin1 {
++ ports {
++ #address-cells = <1>;
++ #size-cells = <0>;
++
++ port@0 {
++ vin1ep0: endpoint {
++ csi,select = "csi40";
++ virtual,channel = <1>;
++ data-lanes = <1 2 3 4>;
++ remote-endpoint = <&ov106xx_in1>;
++ };
++ };
++ port@1 {
++ csi0ep1: endpoint {
++ remote-endpoint = <&csi40_ep>;
++ };
++ };
++ port@2 {
++ vin1_max9286_des0ep1: endpoint@0 {
++ remote-endpoint = <&max9286_des0ep1>;
++ };
++ };
++ };
++};
++
++&vin2 {
++ ports {
++ #address-cells = <1>;
++ #size-cells = <0>;
++
++ port@0 {
++ vin2ep0: endpoint {
++ csi,select = "csi40";
++ virtual,channel = <2>;
++ data-lanes = <1 2 3 4>;
++ remote-endpoint = <&ov106xx_in2>;
++ };
++ };
++ port@1 {
++ csi0ep2: endpoint {
++ remote-endpoint = <&csi40_ep>;
++ };
++ };
++ port@2 {
++ vin2_max9286_des0ep2: endpoint@0 {
++ remote-endpoint = <&max9286_des0ep2>;
++ };
++ };
++ };
++};
++
++&vin3 {
++ ports {
++ #address-cells = <1>;
++ #size-cells = <0>;
++
++ port@0 {
++ vin3ep0: endpoint {
++ csi,select = "csi40";
++ virtual,channel = <3>;
++ data-lanes = <1 2 3 4>;
++ remote-endpoint = <&ov106xx_in3>;
++ };
++ };
++ port@1 {
++ csi0ep3: endpoint {
++ remote-endpoint = <&csi40_ep>;
++ };
++ };
++ port@2 {
++ vin3_max9286_des0ep3: endpoint@0 {
++ remote-endpoint = <&max9286_des0ep3>;
++ };
++ };
++ };
++};
++
++&vin4 {
++ status = "disabled";
++};
++
++&vin5 {
++ status = "disabled";
++};
++
++&vin6 {
++ status = "disabled";
++};
++
++&vin7 {
++ status = "disabled";
++};
++
++&csi20 {
++ status = "disabled";
++ /delete-node/ports;
++};
++
++&csi40 {
++ /delete-node/ports;
++
++ virtual,channel {
++ csi2_vc0 {
++ data,type = "ycbcr422";
++ receive,vc = <0>;
++ };
++ csi2_vc1 {
++ data,type = "ycbcr422";
++ receive,vc = <1>;
++ };
++ csi2_vc2 {
++ data,type = "ycbcr422";
++ receive,vc = <2>;
++ };
++ csi2_vc3 {
++ data,type = "ycbcr422";
++ receive,vc = <3>;
++ };
++ };
++
++ port {
++ #address-cells = <1>;
++ #size-cells = <0>;
++
++ csi40_ep: endpoint {
++ clock-lanes = <0>;
++ data-lanes = <1 2 3 4>;
++ csi-rate = <300>;
++ };
++ };
++};
++
++&can0 {
++ pinctrl-0 = <&can0_pins>;
++ pinctrl-names = "default";
++ status = "okay";
++};
++
++&can1 {
++ pinctrl-0 = <&can1_pins>;
++ pinctrl-names = "default";
++ status = "okay";
++};
+diff --git a/arch/arm64/boot/dts/renesas/r8a77965-m3nulcb-kf.dts b/arch/arm64/boot/dts/renesas/r8a77965-m3nulcb-kf.dts
+new file mode 100644
+index 0000000..806c873
+--- /dev/null
++++ b/arch/arm64/boot/dts/renesas/r8a77965-m3nulcb-kf.dts
+@@ -0,0 +1,41 @@
++/*
++ * Device Tree Source for the M3NULCB Kingfisher board
++ *
++ * Copyright (C) 2017 Renesas Electronics Corp.
++ * Copyright (C) 2017 Cogent Embedded, Inc.
++ *
++ * This file is licensed under the terms of the GNU General Public License
++ * version 2. This program is licensed "as is" without any warranty of any
++ * kind, whether express or implied.
++ */
++
++#include "r8a77965-m3nulcb.dts"
++#include "ulcb-kf.dtsi"
++
++/ {
++ model = "Renesas M3NULCB Kingfisher board based on r8a77965 ES1.1";
++ compatible = "shimafuji,kingfisher", "renesas,m3nulcb",
++ "renesas,r8a77965";
++};
++
++&du {
++ ports {
++ port@0 {
++ endpoint {
++ remote-endpoint = <&adv7513_in>;
++ };
++ };
++ };
++};
++
++&lvds0 {
++ status = "okay";
++
++ ports {
++ port@1 {
++ lvds0_out: endpoint {
++ remote-endpoint = <&lvds_in>;
++ };
++ };
++ };
++};
+diff --git a/arch/arm64/boot/dts/renesas/r8a77970-eagle-function.dts b/arch/arm64/boot/dts/renesas/r8a77970-eagle-function.dts
+new file mode 100644
+index 0000000..9043a07
+--- /dev/null
++++ b/arch/arm64/boot/dts/renesas/r8a77970-eagle-function.dts
+@@ -0,0 +1,62 @@
++/*
++ * Device Tree Source for the Eagle Function board on r8a7797
++ *
++ * Copyright (C) 2017 Renesas Electronics Corp.
++ * Copyright (C) 2017 Cogent Embedded, Inc.
++ *
++ * This file is licensed under the terms of the GNU General Public License
++ * version 2. This program is licensed "as is" without any warranty of any
++ * kind, whether express or implied.
++ */
++
++#include "r8a77970-eagle.dts"
++
++/ {
++ model = "Renesas Eagle Function board based on r8a7797";
++
++ vcc_3v3: regulator0 {
++ compatible = "regulator-fixed";
++ regulator-name = "fixed-VCC3V3";
++ regulator-min-microvolt = <3300000>;
++ regulator-max-microvolt = <3300000>;
++ regulator-boot-on;
++ regulator-always-on;
++ };
++
++ vcc_vddq_vin0: regulator1 {
++ compatible = "regulator-fixed";
++ regulator-name = "VCC-VDDQ-VIN0";
++ regulator-min-microvolt = <1800000>;
++ regulator-max-microvolt = <1800000>;
++ regulator-boot-on;
++ regulator-always-on;
++ };
++};
++
++&pfc {
++ sdhi2_pins_1v8: sdhi2_1v8 {
++ groups = "mmc_data8", "mmc_ctrl";
++ function = "mmc";
++ power-source = <1800>;
++ };
++
++ sdhi2_pins_3v3: sdhi2_3v3 {
++ groups = "mmc_data8", "mmc_ctrl";
++ function = "mmc";
++ power-source = <3300>;
++ };
++};
++
++&sdhi2 {
++ /* used for on-board eMMC */
++ pinctrl-0 = <&sdhi2_pins_3v3>;
++ pinctrl-1 = <&sdhi2_pins_1v8>;
++ pinctrl-names = "default", "state_uhs";
++
++ vmmc-supply = <&vcc_3v3>;
++ vqmmc-supply = <&vcc_vddq_vin0>;
++ mmc-hs200-1_8v;
++ bus-width = <8>;
++ non-removable;
++ status = "okay";
++};
+diff --git a/arch/arm64/boot/dts/renesas/r8a77970-eagle.dts b/arch/arm64/boot/dts/renesas/r8a77970-eagle.dts
+index b6d5332..6338ab3 100644
+--- a/arch/arm64/boot/dts/renesas/r8a77970-eagle.dts
++++ b/arch/arm64/boot/dts/renesas/r8a77970-eagle.dts
+@@ -8,6 +8,7 @@
+
+ /dts-v1/;
+ #include "r8a77970.dtsi"
++#include <dt-bindings/gpio/gpio.h>
+
+ / {
+ model = "Renesas Eagle board based on r8a77970";
+@@ -29,6 +30,58 @@
+ reg = <0x0 0x48000000 0x0 0x38000000>;
+ };
+
++ reserved-memory {
++ #address-cells = <2>;
++ #size-cells = <2>;
++ ranges;
++
++ /* device specific region for Lossy Decompression */
++ lossy_decompress: linux,lossy_decompress {
++ no-map;
++ reg = <0x00000000 0x6c000000 0x0 0x03000000>;
++ };
++
++ /* global autoconfigured region for contiguous allocations */
++ linux,cma {
++ compatible = "shared-dma-pool";
++ reusable;
++ reg = <0x00000000 0x6f000000 0x0 0x10000000>;
++ linux,cma-default;
++ };
++
++ /* device specific region for contiguous allocations */
++ linux,multimedia {
++ compatible = "shared-dma-pool";
++ reusable;
++ reg = <0x00000000 0x7f000000 0x0 0x01000000>;
++ };
++ };
++
++ mmngr {
++ compatible = "renesas,mmngr";
++ memory-region = <&lossy_decompress>;
++ };
++
++ mmngrbuf {
++ compatible = "renesas,mmngrbuf";
++ };
++
++ vspm_if {
++ compatible = "renesas,vspm_if";
++ };
++
++ dclkin_p0: clock-out0 {
++ compatible = "fixed-clock";
++ #clock-cells = <0>;
++ clock-frequency = <148500000>;
++ };
++
++ msiof_ref_clk: msiof-ref-clock {
++ compatible = "fixed-clock";
++ #clock-cells = <0>;
++ clock-frequency = <66666666>;
++ };
++
+ hdmi-out {
+ compatible = "hdmi-connector";
+ type = "a";
+@@ -102,6 +155,40 @@
+ };
+ };
+
++&csi40 {
++ status = "okay";
++
++ virtual,channel {
++ csi2_vc0 {
++ data,type = "ycbcr422";
++ receive,vc = <0>;
++ };
++ csi2_vc1 {
++ data,type = "ycbcr422";
++ receive,vc = <1>;
++ };
++ csi2_vc2 {
++ data,type = "ycbcr422";
++ receive,vc = <2>;
++ };
++ csi2_vc3 {
++ data,type = "ycbcr422";
++ receive,vc = <3>;
++ };
++ };
++
++ port {
++ #address-cells = <1>;
++ #size-cells = <0>;
++
++ csi2_40_ep: endpoint {
++ clock-lanes = <0>;
++ data-lanes = <1 2 3 4>;
++ csi-rate = <300>;
++ };
++ };
++};
++
+ &extal_clk {
+ clock-frequency = <16666666>;
+ };
+@@ -155,6 +242,158 @@
+ };
+ };
+ };
++
++ pmic@5A {
++ compatible = "dlg,da9063";
++ reg = <0x5A>;
++ interrupt-parent = <&intc_ex>;
++ interrupts = <0 IRQ_TYPE_LEVEL_LOW>;
++ interrupt-controller;
++
++ rtc {
++ compatible = "dlg,da9063-rtc";
++ };
++
++ wdt {
++ compatible = "dlg,da9063-watchdog";
++ };
++
++ regulators {
++ DA9063_LDO11: bmem {
++ regulator-name = "bmem";
++ regulator-min-microvolt = <3300000>;
++ regulator-max-microvolt = <3300000>;
++ regulator-always-on;
++ regulator-boot-on;
++ };
++ };
++
++ onkey {
++ compatible = "dlg,da9063-onkey";
++ };
++ };
++};
++
++&i2c3 {
++ pinctrl-0 = <&i2c3_pins>;
++ pinctrl-names = "default";
++
++ status = "okay";
++ clock-frequency = <400000>;
++
++ ov106xx@0 {
++ compatible = "ovti,ov106xx";
++ reg = <0x60>;
++
++ port@0 {
++ ov106xx_in0: endpoint {
++ clock-lanes = <0>;
++ data-lanes = <1 2 3 4>;
++ remote-endpoint = <&vin0ep0>;
++ };
++ };
++ port@1 {
++ ov106xx_max9286_des0ep0: endpoint@0 {
++ remote-endpoint = <&max9286_des0ep0>;
++ };
++ };
++ };
++
++ ov106xx@1 {
++ compatible = "ovti,ov106xx";
++ reg = <0x61>;
++
++ port@0 {
++ ov106xx_in1: endpoint {
++ clock-lanes = <0>;
++ data-lanes = <1 2 3 4>;
++ remote-endpoint = <&vin1ep0>;
++ };
++ };
++ port@1 {
++ ov106xx_max9286_des0ep1: endpoint@0 {
++ remote-endpoint = <&max9286_des0ep1>;
++ };
++ };
++ };
++
++ ov106xx@2 {
++ compatible = "ovti,ov106xx";
++ reg = <0x62>;
++
++ port@0 {
++ ov106xx_in2: endpoint {
++ clock-lanes = <0>;
++ data-lanes = <1 2 3 4>;
++ remote-endpoint = <&vin2ep0>;
++ };
++ };
++ port@1 {
++ ov106xx_max9286_des0ep2: endpoint@0 {
++ remote-endpoint = <&max9286_des0ep2>;
++ };
++ };
++ };
++
++ ov106xx@3 {
++ compatible = "ovti,ov106xx";
++ reg = <0x63>;
++
++ port@0 {
++ ov106xx_in3: endpoint {
++ clock-lanes = <0>;
++ data-lanes = <1 2 3 4>;
++ remote-endpoint = <&vin3ep0>;
++ };
++ };
++ port@1 {
++ ov106xx_des0ep3: endpoint {
++ remote-endpoint = <&max9286_des0ep3>;
++ };
++ };
++ };
++
++ max9286@0 {
++ compatible = "maxim,max9286";
++ reg = <0x48>;
++ gpios = <&io_expander 0 GPIO_ACTIVE_LOW>; /* CSI0 DE_PDn */
++ maxim,gpio0 = <0>;
++ maxim,sensor_delay = <100>;
++ maxim,links = <4>;
++ maxim,lanes = <4>;
++ maxim,resetb-gpio = <1>;
++ maxim,fsync-mode = "automatic";
++ maxim,timeout = <100>;
++
++ port@0 {
++ max9286_des0ep0: endpoint@0 {
++ max9271-addr = <0x50>;
++ dvp-order = <1>;
++ remote-endpoint = <&ov106xx_in0>;
++ };
++ max9286_des0ep1: endpoint@1 {
++ max9271-addr = <0x51>;
++ dvp-order = <1>;
++ remote-endpoint = <&ov106xx_in1>;
++ };
++ max9286_des0ep2: endpoint@2 {
++ max9271-addr = <0x52>;
++ dvp-order = <1>;
++ remote-endpoint = <&ov106xx_in2>;
++ };
++ max9286_des0ep3: endpoint@3 {
++ max9271-addr = <0x53>;
++ dvp-order = <1>;
++ remote-endpoint = <&ov106xx_in3>;
++ };
++ };
++ port@1 {
++ max9286_csi0ep0: endpoint {
++ csi-rate = <700>;
++ remote-endpoint = <&csi2_40_ep>;
++ };
++ };
++ };
+ };
+
+ &pfc {
+@@ -173,6 +412,11 @@
+ function = "i2c0";
+ };
+
++ i2c3_pins: i2c3 {
++ groups = "i2c3";
++ function = "i2c3";
++ };
++
+ scif0_pins: scif0 {
+ groups = "scif0_data";
+ function = "scif0";
+@@ -191,6 +435,118 @@
+ status = "okay";
+ };
+
++&vin0 {
++ status = "okay";
++
++ ports {
++ #address-cells = <1>;
++ #size-cells = <0>;
++
++ port@0 {
++ vin0ep0: endpoint {
++ csi,select = "csi40";
++ virtual,channel = <0>;
++ data-lanes = <1 2 3 4>;
++ remote-endpoint = <&ov106xx_in0>;
++ };
++ };
++ port@1 {
++ csi0ep0: endpoint {
++ remote-endpoint = <&csi2_40_ep>;
++ };
++ };
++ port@2 {
++ vin0_max9286_des0ep0: endpoint@0 {
++ remote-endpoint = <&max9286_des0ep0>;
++ };
++ };
++ };
++};
++
++&vin1 {
++ status = "okay";
++
++ ports {
++ #address-cells = <1>;
++ #size-cells = <0>;
++
++ port@0 {
++ vin1ep0: endpoint {
++ csi,select = "csi40";
++ virtual,channel = <1>;
++ data-lanes = <1 2 3 4>;
++ remote-endpoint = <&ov106xx_in1>;
++ };
++ };
++ port@1 {
++ csi0ep1: endpoint {
++ remote-endpoint = <&csi2_40_ep>;
++ };
++ };
++ port@2 {
++ vin1_max9286_des0ep1: endpoint@0 {
++ remote-endpoint = <&max9286_des0ep1>;
++ };
++ };
++ };
++};
++
++&vin2 {
++ status = "okay";
++
++ ports {
++ #address-cells = <1>;
++ #size-cells = <0>;
++
++ port@0 {
++ vin2ep0: endpoint {
++ csi,select = "csi40";
++ virtual,channel = <2>;
++ data-lanes = <1 2 3 4>;
++ remote-endpoint = <&ov106xx_in2>;
++ };
++ };
++ port@1 {
++ csi0ep2: endpoint {
++ remote-endpoint = <&csi2_40_ep>;
++ };
++ };
++ port@2 {
++ vin2_max9286_des0ep2: endpoint@0 {
++ remote-endpoint = <&max9286_des0ep2>;
++ };
++ };
++ };
++};
++
++&vin3 {
++ status = "okay";
++
++ ports {
++ #address-cells = <1>;
++ #size-cells = <0>;
++
++ port@0 {
++ vin3ep0: endpoint {
++ csi,select = "csi40";
++ virtual,channel = <3>;
++ data-lanes = <1 2 3 4>;
++ remote-endpoint = <&ov106xx_in3>;
++ };
++ };
++ port@1 {
++ csi0ep3: endpoint {
++ remote-endpoint = <&csi2_40_ep>;
++ };
++ };
++ port@2 {
++ vin3_max9286_des0ep3: endpoint@0 {
++ remote-endpoint = <&max9286_des0ep3>;
++ };
++ };
++ };
++};
++
+ &du {
+ status = "okay";
+ };
+diff --git a/arch/arm64/boot/dts/renesas/r8a77970-es1-eagle-function.dts b/arch/arm64/boot/dts/renesas/r8a77970-es1-eagle-function.dts
+new file mode 100644
+index 0000000..b7e74f3
+--- /dev/null
++++ b/arch/arm64/boot/dts/renesas/r8a77970-es1-eagle-function.dts
+@@ -0,0 +1,17 @@
++/*
++ * Device Tree Source for the Eagle Function board on r8a7797 ES1.0
++ *
++ * Copyright (C) 2018 Renesas Electronics Corp.
++ * Copyright (C) 2018 Cogent Embedded, Inc.
++ *
++ * This file is licensed under the terms of the GNU General Public License
++ * version 2. This program is licensed "as is" without any warranty of any
++ * kind, whether express or implied.
++ */
++
++#include "r8a77970-eagle-function.dts"
++#include "r8a77970-es1.dtsi"
++
++/ {
++ model = "Renesas Eagle Function board based on r8a7797 ES1.0";
++};
+diff --git a/arch/arm64/boot/dts/renesas/r8a77970-es1-eagle.dts b/arch/arm64/boot/dts/renesas/r8a77970-es1-eagle.dts
+new file mode 100644
+index 0000000..13e0a19
+--- /dev/null
++++ b/arch/arm64/boot/dts/renesas/r8a77970-es1-eagle.dts
+@@ -0,0 +1,17 @@
++/*
++ * Device Tree Source for the Eagle board on r8a7797 ES1.0
++ *
++ * Copyright (C) 2018 Renesas Electronics Corp.
++ * Copyright (C) 2018 Cogent Embedded, Inc.
++ *
++ * This file is licensed under the terms of the GNU General Public License
++ * version 2. This program is licensed "as is" without any warranty of any
++ * kind, whether express or implied.
++ */
++
++#include "r8a77970-eagle.dts"
++#include "r8a77970-es1.dtsi"
++
++/ {
++ model = "Renesas Eagle board based on r8a7797 ES1.0";
++};
+diff --git a/arch/arm64/boot/dts/renesas/r8a77970-es1-v3msk-kf.dts b/arch/arm64/boot/dts/renesas/r8a77970-es1-v3msk-kf.dts
+new file mode 100644
+index 0000000..8266db1
+--- /dev/null
++++ b/arch/arm64/boot/dts/renesas/r8a77970-es1-v3msk-kf.dts
+@@ -0,0 +1,17 @@
++/*
++ * Device Tree Source for the V3MSK Kingfisher board on r8a7797 ES1.0
++ *
++ * Copyright (C) 2018 Renesas Electronics Corp.
++ * Copyright (C) 2018 Cogent Embedded, Inc.
++ *
++ * This file is licensed under the terms of the GNU General Public License
++ * version 2. This program is licensed "as is" without any warranty of any
++ * kind, whether express or implied.
++ */
++
++#include "r8a77970-v3msk-kf.dts"
++#include "r8a77970-es1.dtsi"
++
++/ {
++ model = "Renesas V3MSK Kingfisher board based on r8a7797 ES1.0";
++};
+diff --git a/arch/arm64/boot/dts/renesas/r8a77970-es1-v3msk-vbm-v2.dts b/arch/arm64/boot/dts/renesas/r8a77970-es1-v3msk-vbm-v2.dts
+new file mode 100644
+index 0000000..3b6f1ae
+--- /dev/null
++++ b/arch/arm64/boot/dts/renesas/r8a77970-es1-v3msk-vbm-v2.dts
+@@ -0,0 +1,17 @@
++/*
++ * Device Tree Source for the V3MSK Videobox Mini V2 board on r8a7797 ES1.0
++ *
++ * Copyright (C) 2018 Renesas Electronics Corp.
++ * Copyright (C) 2018 Cogent Embedded, Inc.
++ *
++ * This file is licensed under the terms of the GNU General Public License
++ * version 2. This program is licensed "as is" without any warranty of any
++ * kind, whether express or implied.
++ */
++
++#include "r8a77970-v3msk-vbm-v2.dts"
++#include "r8a77970-es1.dtsi"
++
++/ {
++ model = "Renesas V3MSK Videobox Mini V2 board based on r8a7797 ES1.0";
++};
+diff --git a/arch/arm64/boot/dts/renesas/r8a77970-es1-v3msk-vbm.dts b/arch/arm64/boot/dts/renesas/r8a77970-es1-v3msk-vbm.dts
+new file mode 100644
+index 0000000..7c1c554
+--- /dev/null
++++ b/arch/arm64/boot/dts/renesas/r8a77970-es1-v3msk-vbm.dts
+@@ -0,0 +1,17 @@
++/*
++ * Device Tree Source for the V3MSK Videobox Mini board on r8a7797 ES1.0
++ *
++ * Copyright (C) 2018 Renesas Electronics Corp.
++ * Copyright (C) 2018 Cogent Embedded, Inc.
++ *
++ * This file is licensed under the terms of the GNU General Public License
++ * version 2. This program is licensed "as is" without any warranty of any
++ * kind, whether express or implied.
++ */
++
++#include "r8a77970-v3msk-vbm.dts"
++#include "r8a77970-es1.dtsi"
++
++/ {
++ model = "Renesas V3MSK Videobox Mini board based on r8a7797 ES1.0";
++};
+diff --git a/arch/arm64/boot/dts/renesas/r8a77970-es1-v3msk-view.dts b/arch/arm64/boot/dts/renesas/r8a77970-es1-v3msk-view.dts
+new file mode 100644
+index 0000000..8f93e31
+--- /dev/null
++++ b/arch/arm64/boot/dts/renesas/r8a77970-es1-v3msk-view.dts
+@@ -0,0 +1,17 @@
++/*
++ * Device Tree Source for the V3MSK View board on r8a7797 ES1.0
++ *
++ * Copyright (C) 2018 Renesas Electronics Corp.
++ * Copyright (C) 2018 Cogent Embedded, Inc.
++ *
++ * This file is licensed under the terms of the GNU General Public License
++ * version 2. This program is licensed "as is" without any warranty of any
++ * kind, whether express or implied.
++ */
++
++#include "r8a77970-v3msk-view.dts"
++#include "r8a77970-es1.dtsi"
++
++/ {
++ model = "Renesas V3MSK View board based on r8a7797 ES1.0";
++};
+diff --git a/arch/arm64/boot/dts/renesas/r8a77970-es1-v3msk.dts b/arch/arm64/boot/dts/renesas/r8a77970-es1-v3msk.dts
+new file mode 100644
+index 0000000..1d955f3
+--- /dev/null
++++ b/arch/arm64/boot/dts/renesas/r8a77970-es1-v3msk.dts
+@@ -0,0 +1,17 @@
++/*
++ * Device Tree Source for the V3M Starter Kit board on r8a7797 ES1.0
++ *
++ * Copyright (C) 2018 Renesas Electronics Corp.
++ * Copyright (C) 2018 Cogent Embedded, Inc.
++ *
++ * This file is licensed under the terms of the GNU General Public License
++ * version 2. This program is licensed "as is" without any warranty of any
++ * kind, whether express or implied.
++ */
++
++#include "r8a77970-v3msk.dts"
++#include "r8a77970-es1.dtsi"
++
++/ {
++ model = "Renesas V3M Starter Kit board based on r8a7797 ES1.0";
++};
+diff --git a/arch/arm64/boot/dts/renesas/r8a77970-es1.dtsi b/arch/arm64/boot/dts/renesas/r8a77970-es1.dtsi
+new file mode 100644
+index 0000000..dab9adc
+--- /dev/null
++++ b/arch/arm64/boot/dts/renesas/r8a77970-es1.dtsi
+@@ -0,0 +1,116 @@
++/*
++ * Device Tree Source for the r8a7797 SoC ES1.0 SoC
++ * (append to r8a7797 SoC ES2.0 SoC)
++ *
++ * Copyright (C) 2018 Renesas Electronics Corp.
++ * Copyright (C) 2018 Cogent Embedded, Inc.
++ *
++ * This file is licensed under the terms of the GNU General Public License
++ * version 2. This program is licensed "as is" without any warranty of any
++ * kind, whether express or implied.
++ */
++
++/ {
++ soc {
++ imp_distributer: impdes0 {
++ compatible = "renesas,impx4-distributer";
++ reg = <0 0xffa00000 0 0x10000>;
++ interrupts = <GIC_SPI 281 IRQ_TYPE_LEVEL_HIGH>;
++ clocks = <&cpg CPG_MOD 830>;
++ power-domains = <&sysc R8A7797_PD_A3IR>;
++ interrupt-controller;
++ #interrupt-cells = <1>;
++ };
++
++ imp0 {
++ compatible = "renesas,impx4-legacy";
++ reg = <0 0xff900000 0 0x20000>;
++ interrupt-parent = <&imp_distributer>;
++ interrupts = <0>;
++ clocks = <&cpg CPG_MOD 827>;
++ power-domains = <&sysc R8A7797_PD_A2IR0>;
++ };
++
++ imp1 {
++ compatible = "renesas,impx4-legacy";
++ reg = <0 0xff920000 0 0x20000>;
++ interrupt-parent = <&imp_distributer>;
++ interrupts = <1>;
++ clocks = <&cpg CPG_MOD 826>;
++ power-domains = <&sysc R8A7797_PD_A2IR1>;
++ };
++
++ imp2 {
++ compatible = "renesas,impx4-legacy";
++ reg = <0 0xff940000 0 0x20000>;
++ interrupt-parent = <&imp_distributer>;
++ interrupts = <2>;
++ clocks = <&cpg CPG_MOD 825>;
++ power-domains = <&sysc R8A7797_PD_A2IR2>;
++ };
++
++ imp3 {
++ compatible = "renesas,impx4-legacy";
++ reg = <0 0xff960000 0 0x20000>;
++ interrupt-parent = <&imp_distributer>;
++ interrupts = <3>;
++ clocks = <&cpg CPG_MOD 824>;
++ power-domains = <&sysc R8A7797_PD_A2IR3>;
++ };
++
++ impsc0 {
++ compatible = "renesas,impx4-shader";
++ reg = <0 0xff980000 0 0x10000>;
++ interrupt-parent = <&imp_distributer>;
++ interrupts = <4>;
++ clocks = <&cpg CPG_MOD 829>;
++ power-domains = <&sysc R8A7797_PD_A2SC0>;
++ };
++
++ impsc1 {
++ compatible = "renesas,impx4-shader";
++ reg = <0 0xff990000 0 0x10000>;
++ interrupt-parent = <&imp_distributer>;
++ interrupts = <5>;
++ clocks = <&cpg CPG_MOD 828>;
++ power-domains = <&sysc R8A7797_PD_A2SC1>;
++ };
++
++ impdm0 {
++ compatible = "renesas,impx5-dmac";
++ reg = <0 0xffa10000 0 0x1000>;
++ interrupt-parent = <&imp_distributer>;
++ interrupts = <16>;
++ clocks = <&cpg CPG_MOD 830>;
++ power-domains = <&sysc R8A7797_PD_A3IR>;
++ };
++
++ impdm1 {
++ compatible = "renesas,impx5-dmac";
++ reg = <0 0xffa10000 0 0x1000>,
++ <0 0xffa10800 0 0x0800>;
++ interrupt-parent = <&imp_distributer>;
++ interrupts = <17>;
++ clocks = <&cpg CPG_MOD 830>;
++ power-domains = <&sysc R8A7797_PD_A3IR>;
++ };
++
++ imppsc0 {
++ compatible = "renesas,impx5+-psc";
++ reg = <0 0xffa20000 0 0x4000>;
++ interrupt-parent = <&imp_distributer>;
++ interrupts = <12>;
++ clocks = <&cpg CPG_MOD 830>;
++ power-domains = <&sysc R8A7797_PD_A3IR>;
++ };
++
++ /delete-node/impcnn0;
++
++ impc0 {
++ compatible = "renesas,impx4-memory";
++ reg = <0 0xed000000 0 0xe0000>;
++ clocks = <&cpg CPG_MOD 830>;
++ power-domains = <&sysc R8A7797_PD_A3IR>;
++ };
++ };
++};
+diff --git a/arch/arm64/boot/dts/renesas/r8a77970-v3msk-kf.dts b/arch/arm64/boot/dts/renesas/r8a77970-v3msk-kf.dts
+new file mode 100644
+index 0000000..29ae871
+--- /dev/null
++++ b/arch/arm64/boot/dts/renesas/r8a77970-v3msk-kf.dts
+@@ -0,0 +1,519 @@
++/*
++ * Device Tree Source for the V3MSK Kingfisher board on r8a7797
++ *
++ * Copyright (C) 2017 Renesas Electronics Corp.
++ * Copyright (C) 2017 Cogent Embedded, Inc.
++ *
++ * This file is licensed under the terms of the GNU General Public License
++ * version 2. This program is licensed "as is" without any warranty of any
++ * kind, whether express or implied.
++ */
++
++#include "r8a77970-v3msk.dts"
++
++/ {
++ model = "Renesas V3MSK Kingfisher board based on r8a7797";
++};
++
++&canfd {
++ pinctrl-0 = <&canfd0_pins &canfd1_pins>;
++ pinctrl-names = "default";
++ status = "okay";
++
++ channel0 {
++ status = "okay";
++ };
++
++ channel1 {
++ status = "okay";
++ };
++};
++
++&csi40 {
++ status = "okay";
++
++ virtual,channel {
++ csi2_vc0 {
++ data,type = "ycbcr422";
++ receive,vc = <0>;
++ };
++ csi2_vc1 {
++ data,type = "ycbcr422";
++ receive,vc = <1>;
++ };
++ csi2_vc2 {
++ data,type = "ycbcr422";
++ receive,vc = <2>;
++ };
++ csi2_vc3 {
++ data,type = "ycbcr422";
++ receive,vc = <3>;
++ };
++ };
++
++ port {
++ #address-cells = <1>;
++ #size-cells = <0>;
++
++ csi40_ep: endpoint {
++ clock-lanes = <0>;
++ data-lanes = <1 2 3 4>;
++ csi-rate = <300>;
++ };
++ };
++};
++
++&i2c0 {
++ /* i2c0 might conflict with pc9548 reset pin on Kingfisher (uncomment if h/w not patched) */
++// status = "disabled";
++};
++
++&i2c3 {
++ pinctrl-0 = <&i2c3_pins>;
++ pinctrl-names = "default";
++ status = "okay";
++
++ clock-frequency = <400000>;
++
++ i2cswitch4: pca9548@71 {
++ compatible = "nxp,pca9548";
++ #address-cells = <1>;
++ #size-cells = <0>;
++ reg = <0x71>;
++// reset-gpios= <&gpio3 15 GPIO_ACTIVE_LOW>;
++
++ i2c@2 {
++ #address-cells = <1>;
++ #size-cells = <0>;
++ reg = <2>;
++ /* Slot B (CN11) */
++
++ ov106xx@0 {
++ compatible = "ovti,ov106xx";
++ reg = <0x60>;
++
++ port@0 {
++ ov106xx_in0: endpoint {
++ clock-lanes = <0>;
++ data-lanes = <1 2 3 4>;
++ remote-endpoint = <&vin0ep0>;
++ };
++ };
++ port@1 {
++ ov106xx_max9286_des0ep0: endpoint@0 {
++ remote-endpoint = <&max9286_des0ep0>;
++ };
++ ov106xx_ti9x4_des0ep0: endpoint@1 {
++ remote-endpoint = <&ti9x4_des0ep0>;
++ };
++ };
++ };
++
++ ov106xx@1 {
++ compatible = "ovti,ov106xx";
++ reg = <0x61>;
++
++ port@0 {
++ ov106xx_in1: endpoint {
++ clock-lanes = <0>;
++ data-lanes = <1 2 3 4>;
++ remote-endpoint = <&vin1ep0>;
++ };
++ };
++ port@1 {
++ ov106xx_max9286_des0ep1: endpoint@0 {
++ remote-endpoint = <&max9286_des0ep1>;
++ };
++ ov106xx_ti9x4_des0ep1: endpoint@1 {
++ remote-endpoint = <&ti9x4_des0ep1>;
++ };
++ };
++ };
++
++ ov106xx@2 {
++ compatible = "ovti,ov106xx";
++ reg = <0x62>;
++
++ port@0 {
++ ov106xx_in2: endpoint {
++ clock-lanes = <0>;
++ data-lanes = <1 2 3 4>;
++ remote-endpoint = <&vin2ep0>;
++ };
++ };
++ port@1 {
++ ov106xx_max9286_des0ep2: endpoint@0 {
++ remote-endpoint = <&max9286_des0ep2>;
++ };
++ ov106xx_ti9x4_des0ep2: endpoint@1 {
++ remote-endpoint = <&ti9x4_des0ep2>;
++ };
++ };
++ };
++
++ ov106xx@3 {
++ compatible = "ovti,ov106xx";
++ reg = <0x63>;
++
++ port@0 {
++ ov106xx_in3: endpoint {
++ clock-lanes = <0>;
++ data-lanes = <1 2 3 4>;
++ remote-endpoint = <&vin3ep0>;
++ };
++ };
++ port@1 {
++ ov106xx_max9286_des0ep3: endpoint@0 {
++ remote-endpoint = <&max9286_des0ep3>;
++ };
++ ov106xx_ti9x4_des0ep3: endpoint@1 {
++ remote-endpoint = <&ti9x4_des0ep3>;
++ };
++ };
++ };
++
++ /* DS90UB9x4 @ 0x3a */
++ ti9x4@0 {
++ compatible = "ti,ti9x4";
++ reg = <0x3a>;
++ ti,links = <4>;
++ ti,lanes = <4>;
++ ti,forwarding-mode = "round-robin";
++
++ POC0-gpios = <&gpio_exp_a_5c 8 GPIO_ACTIVE_HIGH>;
++ POC1-gpios = <&gpio_exp_a_5c 9 GPIO_ACTIVE_HIGH>;
++ POC2-gpios = <&gpio_exp_a_5c 10 GPIO_ACTIVE_HIGH>;
++ POC3-gpios = <&gpio_exp_a_5c 11 GPIO_ACTIVE_HIGH>;
++
++ port@0 {
++ ti9x4_des0ep0: endpoint@0 {
++ ti9x3-addr = <0x0c>;
++ dvp-order = <0>;
++ remote-endpoint = <&ov106xx_in0>;
++ };
++ ti9x4_des0ep1: endpoint@1 {
++ ti9x3-addr = <0x0d>;
++ dvp-order = <0>;
++ remote-endpoint = <&ov106xx_in1>;
++ };
++ ti9x4_des0ep2: endpoint@2 {
++ ti9x3-addr = <0x0e>;
++ dvp-order = <0>;
++ remote-endpoint = <&ov106xx_in2>;
++ };
++ ti9x4_des0ep3: endpoint@3 {
++ ti9x3-addr = <0x0f>;
++ dvp-order = <0>;
++ remote-endpoint = <&ov106xx_in3>;
++ };
++ };
++ port@1 {
++ ti9x4_csi0ep0: endpoint {
++ csi-rate = <800>;
++ remote-endpoint = <&csi40_ep>;
++ };
++ };
++ };
++
++ /* MAX9286 @ 0x2c */
++ max9286@0 {
++ compatible = "maxim,max9286";
++ reg = <0x2c>;
++ maxim,links = <4>;
++ maxim,lanes = <4>;
++ maxim,resetb-gpio = <1>;
++ maxim,fsync-mode = "automatic";
++ maxim,timeout = <100>;
++
++ POC0-gpios = <&gpio_exp_a_5c 9 GPIO_ACTIVE_HIGH>;
++ POC1-gpios = <&gpio_exp_a_5c 8 GPIO_ACTIVE_HIGH>;
++ POC2-gpios = <&gpio_exp_a_5c 11 GPIO_ACTIVE_HIGH>;
++ POC3-gpios = <&gpio_exp_a_5c 10 GPIO_ACTIVE_HIGH>;
++
++ port@0 {
++ max9286_des0ep0: endpoint@0 {
++ max9271-addr = <0x50>;
++ dvp-order = <1>;
++ remote-endpoint = <&ov106xx_in0>;
++ };
++ max9286_des0ep1: endpoint@1 {
++ max9271-addr = <0x51>;
++ dvp-order = <1>;
++ remote-endpoint = <&ov106xx_in1>;
++ };
++ max9286_des0ep2: endpoint@2 {
++ max9271-addr = <0x52>;
++ dvp-order = <1>;
++ remote-endpoint = <&ov106xx_in2>;
++ };
++ max9286_des0ep3: endpoint@3 {
++ max9271-addr = <0x53>;
++ dvp-order = <1>;
++ remote-endpoint = <&ov106xx_in3>;
++ };
++ };
++ port@1 {
++ max9286_csi0ep0: endpoint {
++ csi-rate = <700>;
++ remote-endpoint = <&csi40_ep>;
++ };
++ };
++ };
++ };
++
++ i2c@6 {
++ #address-cells = <1>;
++ #size-cells = <0>;
++ reg = <6>;
++ /* Slot B (CN11) */
++
++ /* PCA9535 is a redundant/deprecated card */
++ gpio_exp_a_26: gpio@26 {
++ compatible = "nxp,pca9535";
++ reg = <0x26>;
++ gpio-controller;
++ #gpio-cells = <2>;
++
++ video_a_des_cfg1 {
++ gpio-hog;
++ gpios = <5 GPIO_ACTIVE_HIGH>;
++ input;
++ line-name = "Video-A cfg1";
++ };
++ video_a_des_cfg0 {
++ gpio-hog;
++ gpios = <6 GPIO_ACTIVE_HIGH>;
++ input;
++ line-name = "Video-A cfg0";
++ };
++ video_a_pwr_shdn {
++ gpio-hog;
++ gpios = <3 GPIO_ACTIVE_HIGH>;
++ output-high;
++ line-name = "Video-A PWR_SHDN";
++ };
++ video_a_cam_pwr0 {
++ gpio-hog;
++ gpios = <12 GPIO_ACTIVE_HIGH>;
++ output-high;
++ line-name = "Video-A PWR0";
++ };
++ video_a_cam_pwr1 {
++ gpio-hog;
++ gpios = <13 GPIO_ACTIVE_HIGH>;
++ output-high;
++ line-name = "Video-A PWR1";
++ };
++ video_a_cam_pwr2 {
++ gpio-hog;
++ gpios = <14 GPIO_ACTIVE_HIGH>;
++ output-high;
++ line-name = "Video-A PWR2";
++ };
++ video_a_cam_pwr3 {
++ gpio-hog;
++ gpios = <15 GPIO_ACTIVE_HIGH>;
++ output-high;
++ line-name = "Video-A PWR3";
++ };
++ video_a_des_shdn {
++ gpio-hog;
++ gpios = <4 GPIO_ACTIVE_HIGH>;
++ output-high;
++ line-name = "Video-A DES_SHDN";
++ };
++ video_a_des_led {
++ gpio-hog;
++ gpios = <7 GPIO_ACTIVE_HIGH>;
++ output-low;
++ line-name = "Video-A led";
++ };
++ };
++
++ gpio_exp_a_5c: gpio@5c {
++ compatible = "maxim,max7325";
++ reg = <0x5c>;
++ gpio-controller;
++ #gpio-cells = <2>;
++
++ video_a_des_cfg2 {
++ gpio-hog;
++ gpios = <4 GPIO_ACTIVE_HIGH>;
++ input;
++ line-name = "Video-A cfg2";
++ };
++ video_a_des_cfg1 {
++ gpio-hog;
++ gpios = <6 GPIO_ACTIVE_HIGH>;
++ input;
++ line-name = "Video-A cfg1";
++ };
++ video_a_des_cfg0 {
++ gpio-hog;
++ gpios = <7 GPIO_ACTIVE_HIGH>;
++ input;
++ line-name = "Video-A cfg0";
++ };
++ video_a_pwr_shdn {
++ gpio-hog;
++ gpios = <14 GPIO_ACTIVE_HIGH>;
++ output-high;
++ line-name = "Video-A PWR_SHDN";
++ };
++ video_a_des_shdn {
++ gpio-hog;
++ gpios = <13 GPIO_ACTIVE_HIGH>;
++ output-high;
++ line-name = "Video-A DES_SHDN";
++ };
++ video_a_led {
++ gpio-hog;
++ gpios = <12 GPIO_ACTIVE_HIGH>;
++ output-low;
++ line-name = "Video-A LED";
++ };
++ };
++ };
++ };
++};
++
++&pfc {
++ canfd0_pins: canfd0 {
++ groups = "canfd0_data_a";
++ function = "canfd0";
++ };
++
++ canfd1_pins: canfd1 {
++ groups = "canfd1_data";
++ function = "canfd1";
++ };
++
++ i2c3_pins: i2c3 {
++ groups = "i2c3";
++ function = "i2c3";
++ };
++};
++
++&vin0 {
++ status = "okay";
++
++ ports {
++ #address-cells = <1>;
++ #size-cells = <0>;
++
++ port@0 {
++ vin0ep0: endpoint {
++ csi,select = "csi40";
++ virtual,channel = <0>;
++ data-lanes = <1 2 3 4>;
++ remote-endpoint = <&ov106xx_in0>;
++ };
++ };
++ port@1 {
++ csi0ep0: endpoint {
++ remote-endpoint = <&csi40_ep>;
++ };
++ };
++ port@2 {
++ vin0_max9286_des0ep0: endpoint@0 {
++ remote-endpoint = <&max9286_des0ep0>;
++ };
++ vin0_ti9x4_des0ep0: endpoint@1 {
++ remote-endpoint = <&ti9x4_des0ep0>;
++ };
++ };
++ };
++};
++
++&vin1 {
++ status = "okay";
++
++ ports {
++ #address-cells = <1>;
++ #size-cells = <0>;
++
++ port@0 {
++ vin1ep0: endpoint {
++ csi,select = "csi40";
++ virtual,channel = <1>;
++ data-lanes = <1 2 3 4>;
++ remote-endpoint = <&ov106xx_in1>;
++ };
++ };
++ port@1 {
++ csi0ep1: endpoint {
++ remote-endpoint = <&csi40_ep>;
++ };
++ };
++ port@2 {
++ vin1_max9286_des0ep1: endpoint@0 {
++ remote-endpoint = <&max9286_des0ep1>;
++ };
++ vin1_ti9x4_des0ep1: endpoint@1 {
++ remote-endpoint = <&ti9x4_des0ep1>;
++ };
++ };
++ };
++};
++
++&vin2 {
++ status = "okay";
++
++ ports {
++ #address-cells = <1>;
++ #size-cells = <0>;
++
++ port@0 {
++ vin2ep0: endpoint {
++ csi,select = "csi40";
++ virtual,channel = <2>;
++ data-lanes = <1 2 3 4>;
++ remote-endpoint = <&ov106xx_in2>;
++ };
++ };
++ port@1 {
++ csi0ep2: endpoint {
++ remote-endpoint = <&csi40_ep>;
++ };
++ };
++ port@2 {
++ vin2_max9286_des0ep2: endpoint@0 {
++ remote-endpoint = <&max9286_des0ep2>;
++ };
++ vin2_ti9x4_des0ep2: endpoint@1 {
++ remote-endpoint = <&ti9x4_des0ep2>;
++ };
++ };
++ };
++};
++
++&vin3 {
++ status = "okay";
++
++ ports {
++ #address-cells = <1>;
++ #size-cells = <0>;
++
++ port@0 {
++ vin3ep0: endpoint {
++ csi,select = "csi40";
++ virtual,channel = <3>;
++ data-lanes = <1 2 3 4>;
++ remote-endpoint = <&ov106xx_in3>;
++ };
++ };
++ port@1 {
++ csi0ep3: endpoint {
++ remote-endpoint = <&csi40_ep>;
++ };
++ };
++ port@2 {
++ vin3_max9286_des0ep3: endpoint@0 {
++ remote-endpoint = <&max9286_des0ep3>;
++ };
++ vin3_ti9x4_des0ep3: endpoint@1 {
++ remote-endpoint = <&ti9x4_des0ep3>;
++ };
++ };
++ };
++};
+diff --git a/arch/arm64/boot/dts/renesas/r8a77970-v3msk-vbm-v2.dts b/arch/arm64/boot/dts/renesas/r8a77970-v3msk-vbm-v2.dts
+new file mode 100644
+index 0000000..e20f4a6
+--- /dev/null
++++ b/arch/arm64/boot/dts/renesas/r8a77970-v3msk-vbm-v2.dts
+@@ -0,0 +1,82 @@
++/*
++ * Device Tree Source for the V3MSK Videobox Mini board V2 on r8a7797
++ *
++ * Copyright (C) 2018 Cogent Embedded, Inc.
++ *
++ * This file is licensed under the terms of the GNU General Public License
++ * version 2. This program is licensed "as is" without any warranty of any
++ * kind, whether express or implied.
++ */
++
++#include "r8a77970-v3msk-vbm.dts"
++
++/ {
++ model = "Renesas V3MSK Videobox Mini board V2 based on r8a7797";
++
++ leds {
++ compatible = "gpio-leds";
++
++ led5 {
++ label = "board:status";
++ gpios = <&gpio3 16 GPIO_ACTIVE_HIGH>;
++ linux,default-trigger = "heartbeat";
++ };
++ };
++};
++
++&gpio0 {
++ /delete-node/can0stby;
++
++ can0_stby {
++ gpio-hog;
++ gpios = <12 GPIO_ACTIVE_HIGH>;
++ output-low;
++ line-name = "CAN0STBY";
++ };
++
++ can1_stby {
++ gpio-hog;
++ gpios = <14 GPIO_ACTIVE_HIGH>;
++ output-low;
++ line-name = "CAN1STBY";
++ };
++};
++
++&pfc {
++ msiof1_pins: msiof1 {
++ groups = "msiof1_clk", "msiof1_txd", "msiof1_rxd";
++ function = "msiof1";
++ };
++
++ msiof2_pins: msiof2 {
++ groups = "msiof2_clk", "msiof2_sync", "msiof2_txd", "msiof2_rxd";
++ function = "msiof2";
++ };
++};
++
++&scif3 {
++ /* pin conflict with msiof2 */
++ /* set R240 and remove R241 before enabling */
++ status = "disabled";
++};
++
++&msiof1 {
++ pinctrl-0 = <&msiof1_pins>;
++ pinctrl-names = "default";
++ cs-gpios = <&gpio3 3 0>;
++
++ status = "okay";
++ spidev@0 {
++ compatible = "renesas,sh-msiof";
++ reg = <0>;
++ spi-max-frequency = <66666666>;
++ };
++};
++
++&msiof2 {
++ pinctrl-0 = <&msiof2_pins>;
++ pinctrl-names = "default";
++
++ status = "okay";
++ slave;
++};
+diff --git a/arch/arm64/boot/dts/renesas/r8a77970-v3msk-vbm.dts b/arch/arm64/boot/dts/renesas/r8a77970-v3msk-vbm.dts
+new file mode 100644
+index 0000000..a37ccaa
+--- /dev/null
++++ b/arch/arm64/boot/dts/renesas/r8a77970-v3msk-vbm.dts
+@@ -0,0 +1,507 @@
++/*
++ * Device Tree Source for the V3MSK Videobox Mini board on r8a7797
++ *
++ * Copyright (C) 2017 Cogent Embedded, Inc.
++ *
++ * This file is licensed under the terms of the GNU General Public License
++ * version 2. This program is licensed "as is" without any warranty of any
++ * kind, whether express or implied.
++ */
++
++#include "r8a77970-v3msk.dts"
++
++/ {
++ model = "Renesas V3MSK Videobox Mini board based on r8a7797";
++
++ aliases {
++ serial1 = &scif3;
++ };
++};
++
++&canfd {
++ pinctrl-0 = <&canfd0_pins &canfd1_pins>;
++ pinctrl-names = "default";
++ status = "okay";
++
++ channel0 {
++ status = "okay";
++ };
++
++ channel1 {
++ status = "okay";
++ };
++};
++
++&csi40 {
++ status = "okay";
++
++ virtual,channel {
++ csi2_vc0 {
++ data,type = "ycbcr422";
++ receive,vc = <0>;
++ };
++ csi2_vc1 {
++ data,type = "ycbcr422";
++ receive,vc = <1>;
++ };
++ csi2_vc2 {
++ data,type = "ycbcr422";
++ receive,vc = <2>;
++ };
++ csi2_vc3 {
++ data,type = "ycbcr422";
++ receive,vc = <3>;
++ };
++ };
++
++ port {
++ #address-cells = <1>;
++ #size-cells = <0>;
++
++ csi40_ep: endpoint {
++ clock-lanes = <0>;
++ data-lanes = <1 2 3 4>;
++ csi-rate = <300>;
++ };
++ };
++};
++
++&i2c1 {
++ pinctrl-0 = <&i2c1_pins>;
++ pinctrl-names = "default";
++ status = "okay";
++
++ clock-frequency = <400000>;
++
++ i2cswitch1: i2c-switch@74 {
++ compatible = "nxp,pca9548";
++ #address-cells = <1>;
++ #size-cells = <0>;
++ reg = <0x74>;
++ reset-gpios = <&gpio0 9 GPIO_ACTIVE_LOW>;
++
++ i2c@0 {
++ #address-cells = <1>;
++ #size-cells = <0>;
++ reg = <0>;
++
++ ov106xx@0 {
++ compatible = "ovti,ov106xx";
++ reg = <0x60>;
++
++ port@0 {
++ ov106xx_in0: endpoint {
++ clock-lanes = <0>;
++ data-lanes = <1 2 3 4>;
++ remote-endpoint = <&vin0ep0>;
++ };
++ };
++ port@1 {
++ ov106xx_max9286_des0ep0: endpoint@0 {
++ remote-endpoint = <&max9286_des0ep0>;
++ };
++ ov106xx_ti9x4_des0ep0: endpoint@1 {
++ remote-endpoint = <&ti9x4_des0ep0>;
++ };
++ };
++ };
++
++ ov106xx@1 {
++ compatible = "ovti,ov106xx";
++ reg = <0x61>;
++
++ port@0 {
++ ov106xx_in1: endpoint {
++ clock-lanes = <0>;
++ data-lanes = <1 2 3 4>;
++ remote-endpoint = <&vin1ep0>;
++ };
++ };
++ port@1 {
++ ov106xx_max9286_des0ep1: endpoint@0 {
++ remote-endpoint = <&max9286_des0ep1>;
++ };
++ ov106xx_ti9x4_des0ep1: endpoint@1 {
++ remote-endpoint = <&ti9x4_des0ep1>;
++ };
++ };
++ };
++
++ ov106xx@2 {
++ compatible = "ovti,ov106xx";
++ reg = <0x62>;
++
++ port@0 {
++ ov106xx_in2: endpoint {
++ clock-lanes = <0>;
++ data-lanes = <1 2 3 4>;
++ remote-endpoint = <&vin2ep0>;
++ };
++ };
++ port@1 {
++ ov106xx_max9286_des0ep2: endpoint@0 {
++ remote-endpoint = <&max9286_des0ep2>;
++ };
++ ov106xx_ti9x4_des0ep2: endpoint@1 {
++ remote-endpoint = <&ti9x4_des0ep2>;
++ };
++ };
++ };
++
++ ov106xx@3 {
++ compatible = "ovti,ov106xx";
++ reg = <0x63>;
++
++ port@0 {
++ ov106xx_in3: endpoint {
++ clock-lanes = <0>;
++ data-lanes = <1 2 3 4>;
++ remote-endpoint = <&vin3ep0>;
++ };
++ };
++ port@1 {
++ ov106xx_max9286_des0ep3: endpoint@0 {
++ remote-endpoint = <&max9286_des0ep3>;
++ };
++ ov106xx_ti9x4_des0ep3: endpoint@1 {
++ remote-endpoint = <&ti9x4_des0ep3>;
++ };
++ };
++ };
++
++ max9286@0 {
++ compatible = "maxim,max9286";
++ reg = <0x2c>;
++ maxim,links = <4>;
++ maxim,lanes = <4>;
++ maxim,resetb-gpio = <1>;
++ maxim,fsync-mode = "automatic";
++ maxim,timeout = <100>;
++
++ POC0-gpios = <&gpio_exp_6c 8 GPIO_ACTIVE_HIGH>;
++ POC1-gpios = <&gpio_exp_6c 9 GPIO_ACTIVE_HIGH>;
++ POC2-gpios = <&gpio_exp_6c 10 GPIO_ACTIVE_HIGH>;
++ POC3-gpios = <&gpio_exp_6c 11 GPIO_ACTIVE_HIGH>;
++
++ port@0 {
++ max9286_des0ep0: endpoint@0 {
++ max9271-addr = <0x50>;
++ dvp-order = <1>;
++ remote-endpoint = <&ov106xx_in0>;
++ };
++ max9286_des0ep1: endpoint@1 {
++ max9271-addr = <0x51>;
++ dvp-order = <1>;
++ remote-endpoint = <&ov106xx_in1>;
++ };
++ max9286_des0ep2: endpoint@2 {
++ max9271-addr = <0x52>;
++ dvp-order = <1>;
++ remote-endpoint = <&ov106xx_in2>;
++ };
++ max9286_des0ep3: endpoint@3 {
++ max9271-addr = <0x53>;
++ dvp-order = <1>;
++ remote-endpoint = <&ov106xx_in3>;
++ };
++ };
++ port@1 {
++ max9286_csi0ep0: endpoint {
++ csi-rate = <700>;
++ remote-endpoint = <&csi40_ep>;
++ };
++ };
++ };
++
++ ti9x4@0 {
++ compatible = "ti,ti9x4";
++ reg = <0x3a>;
++ ti,links = <4>;
++ ti,lanes = <4>;
++ ti,forwarding-mode = "round-robin";
++
++ POC0-gpios = <&gpio_exp_6c 8 GPIO_ACTIVE_HIGH>;
++ POC1-gpios = <&gpio_exp_6c 9 GPIO_ACTIVE_HIGH>;
++ POC2-gpios = <&gpio_exp_6c 10 GPIO_ACTIVE_HIGH>;
++ POC3-gpios = <&gpio_exp_6c 11 GPIO_ACTIVE_HIGH>;
++
++ port@0 {
++ ti9x4_des0ep0: endpoint@0 {
++ ti9x3-addr = <0x0c>;
++ dvp-order = <0>;
++ remote-endpoint = <&ov106xx_in0>;
++ };
++ ti9x4_des0ep1: endpoint@1 {
++ ti9x3-addr = <0x0d>;
++ dvp-order = <0>;
++ remote-endpoint = <&ov106xx_in1>;
++ };
++ ti9x4_des0ep2: endpoint@2 {
++ ti9x3-addr = <0x0e>;
++ dvp-order = <0>;
++ remote-endpoint = <&ov106xx_in2>;
++ };
++ ti9x4_des0ep3: endpoint@3 {
++ ti9x3-addr = <0x0f>;
++ dvp-order = <0>;
++ remote-endpoint = <&ov106xx_in3>;
++ };
++ };
++ port@1 {
++ ti9x4_csi0ep0: endpoint {
++ csi-rate = <700>;
++ remote-endpoint = <&csi40_ep>;
++ };
++ };
++ };
++ };
++
++ i2c@1 {
++ #address-cells = <1>;
++ #size-cells = <0>;
++ reg = <1>;
++
++ gpio_exp_6c: gpio@6c {
++ compatible = "maxim,max7325";
++ reg = <0x6c>;
++ gpio-controller;
++ #gpio-cells = <2>;
++
++ virq {
++ gpio-hog;
++ gpios = <5 GPIO_ACTIVE_HIGH>;
++ input;
++ line-name = "VIRQ";
++ };
++ des_cfg {
++ gpio-hog;
++ gpios = <6 GPIO_ACTIVE_HIGH>;
++ input;
++ line-name = "CNFG0";
++ };
++ pwr_shdn {
++ gpio-hog;
++ gpios = <14 GPIO_ACTIVE_HIGH>;
++ output-high;
++ line-name = "PWR_SHDN";
++ };
++ des_shdn {
++ gpio-hog;
++ gpios = <13 GPIO_ACTIVE_HIGH>;
++ output-high;
++ line-name = "Des_SHDN";
++ };
++ fpdl_shdn {
++ gpio-hog;
++ gpios = <15 GPIO_ACTIVE_HIGH>;
++ output-high;
++ line-name = "FPDL_SHDN";
++ };
++ };
++ };
++
++ i2c@3 {
++ #address-cells = <1>;
++ #size-cells = <0>;
++ reg = <3>;
++
++ /* fan node - lm96063 */
++ fan_ctrl: lm96063@4c {
++ compatible = "lm96163";
++ reg = <0x4c>;
++ };
++ };
++ };
++};
++
++&gpio0 {
++ can0stby {
++ gpio-hog;
++ gpios = <12 GPIO_ACTIVE_HIGH>;
++ output-low;
++ line-name = "CAN0STBY";
++ };
++
++ can1_load {
++ gpio-hog;
++ gpios = <13 GPIO_ACTIVE_HIGH>;
++ output-low;
++ line-name = "can1_120R_load";
++ };
++};
++
++&gpio2 {
++ can0_load {
++ gpio-hog;
++ gpios = <16 GPIO_ACTIVE_HIGH>;
++ output-low;
++ line-name = "can0_120R_load";
++ };
++
++ wake_pin_7 {
++ gpio-hog;
++ gpios = <8 GPIO_ACTIVE_HIGH>;
++ input;
++ line-name = "WAKE INPUT PIN 7";
++ };
++
++ wake_pin_8 {
++ gpio-hog;
++ gpios = <9 GPIO_ACTIVE_HIGH>;
++ input;
++ line-name = "WAKE INPUT PIN 8";
++ };
++};
++
++&pfc {
++ canfd0_pins: canfd0 {
++ groups = "canfd0_data_a";
++ function = "canfd0";
++ };
++
++ canfd1_pins: canfd1 {
++ groups = "canfd1_data";
++ function = "canfd1";
++ };
++
++ i2c1_pins: i2c1 {
++ groups = "i2c1";
++ function = "i2c1";
++ };
++
++ scif3_pins: scif3 {
++ groups = "scif3_data";
++ function = "scif3";
++ };
++};
++
++&scif3 {
++ pinctrl-0 = <&scif3_pins>;
++ pinctrl-names = "default";
++
++ status = "okay";
++};
++
++&vin0 {
++ status = "okay";
++
++ ports {
++ #address-cells = <1>;
++ #size-cells = <0>;
++
++ port@0 {
++ vin0ep0: endpoint {
++ csi,select = "csi40";
++ virtual,channel = <0>;
++ data-lanes = <1 2 3 4>;
++ remote-endpoint = <&ov106xx_in0>;
++ };
++ };
++ port@1 {
++ csi0ep0: endpoint {
++ remote-endpoint = <&csi40_ep>;
++ };
++ };
++ port@2 {
++ vin0_max9286_des0ep0: endpoint@0 {
++ remote-endpoint = <&max9286_des0ep0>;
++ };
++ vin0_ti9x4_des0ep0: endpoint@1 {
++ remote-endpoint = <&ti9x4_des0ep0>;
++ };
++ };
++ };
++};
++
++&vin1 {
++ status = "okay";
++
++ ports {
++ #address-cells = <1>;
++ #size-cells = <0>;
++
++ port@0 {
++ vin1ep0: endpoint {
++ csi,select = "csi40";
++ virtual,channel = <1>;
++ data-lanes = <1 2 3 4>;
++ remote-endpoint = <&ov106xx_in1>;
++ };
++ };
++ port@1 {
++ csi0ep1: endpoint {
++ remote-endpoint = <&csi40_ep>;
++ };
++ };
++ port@2 {
++ vin1_max9286_des0ep1: endpoint@0 {
++ remote-endpoint = <&max9286_des0ep1>;
++ };
++ vin1_ti9x4_des0ep1: endpoint@1 {
++ remote-endpoint = <&ti9x4_des0ep1>;
++ };
++ };
++ };
++};
++
++&vin2 {
++ status = "okay";
++
++ ports {
++ #address-cells = <1>;
++ #size-cells = <0>;
++
++ port@0 {
++ vin2ep0: endpoint {
++ csi,select = "csi40";
++ virtual,channel = <2>;
++ data-lanes = <1 2 3 4>;
++ remote-endpoint = <&ov106xx_in2>;
++ };
++ };
++ port@1 {
++ csi0ep2: endpoint {
++ remote-endpoint = <&csi40_ep>;
++ };
++ };
++ port@2 {
++ vin2_max9286_des0ep2: endpoint@0 {
++ remote-endpoint = <&max9286_des0ep2>;
++ };
++ vin2_ti9x4_des0ep2: endpoint@1 {
++ remote-endpoint = <&ti9x4_des0ep2>;
++ };
++ };
++ };
++};
++
++&vin3 {
++ status = "okay";
++
++ ports {
++ #address-cells = <1>;
++ #size-cells = <0>;
++
++ port@0 {
++ vin3ep0: endpoint {
++ csi,select = "csi40";
++ virtual,channel = <3>;
++ data-lanes = <1 2 3 4>;
++ remote-endpoint = <&ov106xx_in3>;
++ };
++ };
++ port@1 {
++ csi0ep3: endpoint {
++ remote-endpoint = <&csi40_ep>;
++ };
++ };
++ port@2 {
++ vin3_max9286_des0ep3: endpoint@0 {
++ remote-endpoint = <&max9286_des0ep3>;
++ };
++ vin3_ti9x4_des0ep3: endpoint@1 {
++ remote-endpoint = <&ti9x4_des0ep3>;
++ };
++ };
++ };
++};
+diff --git a/arch/arm64/boot/dts/renesas/r8a77970-v3msk-view.dts b/arch/arm64/boot/dts/renesas/r8a77970-v3msk-view.dts
+new file mode 100644
+index 0000000..75631fb
+--- /dev/null
++++ b/arch/arm64/boot/dts/renesas/r8a77970-v3msk-view.dts
+@@ -0,0 +1,297 @@
++/*
++ * Device Tree Source for the V3MSK View board on r8a7797
++ *
++ * Copyright (C) 2017 Cogent Embedded, Inc.
++ *
++ * This file is licensed under the terms of the GNU General Public License
++ * version 2. This program is licensed "as is" without any warranty of any
++ * kind, whether express or implied.
++ */
++
++#include "r8a77970-v3msk.dts"
++
++/ {
++ model = "Renesas V3MSK View board based on r8a7797";
++};
++
++&csi40 {
++ status = "okay";
++
++ virtual,channel {
++ csi2_vc0 {
++ data,type = "ycbcr422";
++ receive,vc = <0>;
++ };
++ csi2_vc1 {
++ data,type = "ycbcr422";
++ receive,vc = <1>;
++ };
++ csi2_vc2 {
++ data,type = "ycbcr422";
++ receive,vc = <2>;
++ };
++ csi2_vc3 {
++ data,type = "ycbcr422";
++ receive,vc = <3>;
++ };
++ };
++
++ port {
++ #address-cells = <1>;
++ #size-cells = <0>;
++
++ csi40_ep: endpoint {
++ clock-lanes = <0>;
++ data-lanes = <1 2 3 4>;
++ csi-rate = <300>;
++ };
++ };
++};
++
++&i2c3 {
++ pinctrl-0 = <&i2c3_pins>;
++ pinctrl-names = "default";
++ status = "okay";
++
++ clock-frequency = <400000>;
++
++ ov106xx@0 {
++ compatible = "ovti,ov106xx";
++ reg = <0x60>;
++
++ port@0 {
++ ov106xx_in0: endpoint {
++ clock-lanes = <0>;
++ data-lanes = <1 2 3 4>;
++ remote-endpoint = <&vin0ep0>;
++ };
++ };
++ port@1 {
++ ov106xx_max9286_des0ep0: endpoint@0 {
++ remote-endpoint = <&max9286_des0ep0>;
++ };
++ };
++ };
++
++ ov106xx@1 {
++ compatible = "ovti,ov106xx";
++ reg = <0x61>;
++
++ port@0 {
++ ov106xx_in1: endpoint {
++ clock-lanes = <0>;
++ data-lanes = <1 2 3 4>;
++ remote-endpoint = <&vin1ep0>;
++ };
++ };
++ port@1 {
++ ov106xx_max9286_des0ep1: endpoint@0 {
++ remote-endpoint = <&max9286_des0ep1>;
++ };
++ };
++ };
++
++ ov106xx@2 {
++ compatible = "ovti,ov106xx";
++ reg = <0x62>;
++
++ port@0 {
++ ov106xx_in2: endpoint {
++ clock-lanes = <0>;
++ data-lanes = <1 2 3 4>;
++ remote-endpoint = <&vin2ep0>;
++ };
++ };
++ port@1 {
++ ov106xx_max9286_des0ep2: endpoint@0 {
++ remote-endpoint = <&max9286_des0ep2>;
++ };
++ };
++ };
++
++ ov106xx@3 {
++ compatible = "ovti,ov106xx";
++ reg = <0x63>;
++
++ port@0 {
++ ov106xx_in3: endpoint {
++ clock-lanes = <0>;
++ data-lanes = <1 2 3 4>;
++ remote-endpoint = <&vin3ep0>;
++ };
++ };
++ port@1 {
++ ov106xx_max9286_des0ep3: endpoint@0 {
++ remote-endpoint = <&max9286_des0ep3>;
++ };
++ };
++ };
++
++ max9286@0 {
++ compatible = "maxim,max9286";
++ reg = <0x6c>;
++ gpios = <&gpio0 9 GPIO_ACTIVE_HIGH>;
++ maxim,links = <4>;
++ maxim,lanes = <4>;
++ maxim,resetb-gpio = <1>;
++ maxim,fsync-mode = "automatic";
++ maxim,timeout = <100>;
++
++ port@0 {
++ max9286_des0ep0: endpoint@0 {
++ max9271-addr = <0x50>;
++ dvp-order = <1>;
++ remote-endpoint = <&ov106xx_in0>;
++ };
++ max9286_des0ep1: endpoint@1 {
++ max9271-addr = <0x51>;
++ dvp-order = <1>;
++ remote-endpoint = <&ov106xx_in1>;
++ };
++ max9286_des0ep2: endpoint@2 {
++ max9271-addr = <0x52>;
++ dvp-order = <1>;
++ remote-endpoint = <&ov106xx_in2>;
++ };
++ max9286_des0ep3: endpoint@3 {
++ max9271-addr = <0x53>;
++ dvp-order = <1>;
++ remote-endpoint = <&ov106xx_in3>;
++ };
++ };
++ port@1 {
++ max9286_csi0ep0: endpoint {
++ csi-rate = <700>;
++ remote-endpoint = <&csi40_ep>;
++ };
++ };
++ };
++};
++
++&gpio2 {
++ gpio_pwdn1 {
++ gpio-hog;
++ gpios = <12 GPIO_ACTIVE_HIGH>;
++ output-low;
++ line-name = "GPIO_PWDN1#";
++ };
++};
++
++&pfc {
++ i2c3_pins: i2c3 {
++ groups = "i2c3";
++ function = "i2c3";
++ };
++};
++
++&vin0 {
++ status = "okay";
++
++ ports {
++ #address-cells = <1>;
++ #size-cells = <0>;
++
++ port@0 {
++ vin0ep0: endpoint {
++ csi,select = "csi40";
++ virtual,channel = <0>;
++ data-lanes = <1 2 3 4>;
++ remote-endpoint = <&ov106xx_in0>;
++ };
++ };
++ port@1 {
++ csi0ep0: endpoint {
++ remote-endpoint = <&csi40_ep>;
++ };
++ };
++ port@2 {
++ vin0_max9286_des0ep0: endpoint@0 {
++ remote-endpoint = <&max9286_des0ep0>;
++ };
++ };
++ };
++};
++
++&vin1 {
++ status = "okay";
++
++ ports {
++ #address-cells = <1>;
++ #size-cells = <0>;
++
++ port@0 {
++ vin1ep0: endpoint {
++ csi,select = "csi40";
++ virtual,channel = <1>;
++ data-lanes = <1 2 3 4>;
++ remote-endpoint = <&ov106xx_in1>;
++ };
++ };
++ port@1 {
++ csi0ep1: endpoint {
++ remote-endpoint = <&csi40_ep>;
++ };
++ };
++ port@2 {
++ vin1_max9286_des0ep1: endpoint@0 {
++ remote-endpoint = <&max9286_des0ep1>;
++ };
++ };
++ };
++};
++
++&vin2 {
++ status = "okay";
++
++ ports {
++ #address-cells = <1>;
++ #size-cells = <0>;
++
++ port@0 {
++ vin2ep0: endpoint {
++ csi,select = "csi40";
++ virtual,channel = <2>;
++ data-lanes = <1 2 3 4>;
++ remote-endpoint = <&ov106xx_in2>;
++ };
++ };
++ port@1 {
++ csi0ep2: endpoint {
++ remote-endpoint = <&csi40_ep>;
++ };
++ };
++ port@2 {
++ vin2_max9286_des0ep2: endpoint@0 {
++ remote-endpoint = <&max9286_des0ep2>;
++ };
++ };
++ };
++};
++
++&vin3 {
++ status = "okay";
++
++ ports {
++ #address-cells = <1>;
++ #size-cells = <0>;
++
++ port@0 {
++ vin3ep0: endpoint {
++ csi,select = "csi40";
++ virtual,channel = <3>;
++ data-lanes = <1 2 3 4>;
++ remote-endpoint = <&ov106xx_in3>;
++ };
++ };
++ port@1 {
++ csi0ep3: endpoint {
++ remote-endpoint = <&csi40_ep>;
++ };
++ };
++ port@2 {
++ vin3_max9286_des0ep3: endpoint@0 {
++ remote-endpoint = <&max9286_des0ep3>;
++ };
++ };
++ };
++};
+diff --git a/arch/arm64/boot/dts/renesas/r8a77970-v3msk.dts b/arch/arm64/boot/dts/renesas/r8a77970-v3msk.dts
+index 8eac8ca..2b614e4 100644
+--- a/arch/arm64/boot/dts/renesas/r8a77970-v3msk.dts
++++ b/arch/arm64/boot/dts/renesas/r8a77970-v3msk.dts
+@@ -27,6 +27,46 @@
+ reg = <0x0 0x48000000 0x0 0x38000000>;
+ };
+
++ reserved-memory {
++ #address-cells = <2>;
++ #size-cells = <2>;
++ ranges;
++
++ /* device specific region for Lossy Decompression */
++ lossy_decompress: linux,lossy_decompress {
++ no-map;
++ reg = <0x00000000 0x6c000000 0x0 0x03000000>;
++ };
++
++ /* global autoconfigured region for contiguous allocations */
++ linux,cma {
++ compatible = "shared-dma-pool";
++ reusable;
++ reg = <0x00000000 0x6f000000 0x0 0x10000000>;
++ linux,cma-default;
++ };
++
++ /* device specific region for contiguous allocations */
++ linux,multimedia {
++ compatible = "shared-dma-pool";
++ reusable;
++ reg = <0x00000000 0x7f000000 0x0 0x01000000>;
++ };
++ };
++
++ mmngr {
++ compatible = "renesas,mmngr";
++ memory-region = <&lossy_decompress>;
++ };
++
++ mmngrbuf {
++ compatible = "renesas,mmngrbuf";
++ };
++
++ vspm_if {
++ compatible = "renesas,vspm_if";
++ };
++
+ osc5_clk: osc5-clock {
+ compatible = "fixed-clock";
+ #clock-cells = <0>;
+@@ -178,6 +218,37 @@
+ };
+ };
+ };
++
++ pmic@5A {
++ compatible = "dlg,da9063";
++ reg = <0x5A>;
++ interrupt-parent = <&intc_ex>;
++ interrupts = <0 IRQ_TYPE_LEVEL_LOW>;
++ interrupt-controller;
++
++ rtc {
++ compatible = "dlg,da9063-rtc";
++ };
++
++ wdt {
++ compatible = "dlg,da9063-watchdog";
++ };
++
++ regulators {
++ DA9063_LDO11: bmem {
++ regulator-name = "bmem";
++ regulator-min-microvolt = <3300000>;
++ regulator-max-microvolt = <3300000>;
++ regulator-always-on;
++ regulator-boot-on;
++ };
++ };
++
++ onkey {
++ compatible = "dlg,da9063-onkey";
++ };
++ };
++
+ };
+
+ &lvds0 {
+diff --git a/arch/arm64/boot/dts/renesas/r8a77970-v3mzf.dts b/arch/arm64/boot/dts/renesas/r8a77970-v3mzf.dts
+new file mode 100644
+index 0000000..2087364
+--- /dev/null
++++ b/arch/arm64/boot/dts/renesas/r8a77970-v3mzf.dts
+@@ -0,0 +1,442 @@
++/*
++ * Device Tree Source for the V3MZF board
++ *
++ * Copyright (C) 2018 Cogent Embedded, Inc.
++ *
++ * This file is licensed under the terms of the GNU General Public License
++ * version 2. This program is licensed "as is" without any warranty of any
++ * kind, whether express or implied.
++ */
++
++/dts-v1/;
++#include "r8a77970.dtsi"
++#include <dt-bindings/gpio/gpio.h>
++
++/ {
++ model = "Renesas V3MZF board based on r8a7797";
++ compatible = "renesas,v3mzf", "renesas,r8a7797";
++
++ aliases {
++ serial0 = &scif0;
++ ethernet0 = &avb;
++ };
++
++ chosen {
++ bootargs = "ignore_loglevel rw root=/dev/nfs ip=dhcp";
++ stdout-path = "serial0:115200n8";
++ };
++
++ memory@48000000 {
++ device_type = "memory";
++ /* first 128MB is reserved for secure area. */
++ reg = <0x0 0x48000000 0x0 0x38000000>;
++ };
++
++ reserved-memory {
++ #address-cells = <2>;
++ #size-cells = <2>;
++ ranges;
++
++ /* device specific region for Lossy Decompression */
++ lossy_decompress: linux,lossy_decompress {
++ no-map;
++ reg = <0x00000000 0x6c000000 0x0 0x03000000>;
++ };
++
++ /* global autoconfigured region for contiguous allocations */
++ linux,cma {
++ compatible = "shared-dma-pool";
++ reusable;
++ reg = <0x00000000 0x6f000000 0x0 0x11000000>;
++ linux,cma-default;
++ };
++ };
++
++ mmngr {
++ compatible = "renesas,mmngr";
++ memory-region = <&lossy_decompress>;
++ };
++
++ mmngrbuf {
++ compatible = "renesas,mmngrbuf";
++ };
++
++ vspm_if {
++ compatible = "renesas,vspm_if";
++ };
++
++ lvds {
++ compatible = "panel-lvds";
++
++ width-mm = <210>;
++ height-mm = <158>;
++
++ data-mapping = "jeida-24";
++
++ panel-timing {
++ clock-frequency = <65000000>;
++ hactive = <1280>;
++ vactive = <800>;
++ hsync-len = <40>;
++ hfront-porch = <80>;
++ hback-porch = <40>;
++ vfront-porch = <14>;
++ vback-porch = <14>;
++ vsync-len = <4>;
++ };
++
++ port {
++ lvds_in: endpoint {
++ remote-endpoint = <&du_out_lvds0>;
++ };
++ };
++ };
++
++ dclkin_p0: clock-out0 {
++ compatible = "fixed-clock";
++ #clock-cells = <0>;
++ clock-frequency = <148500000>;
++ };
++
++ msiof_ref_clk: msiof-ref-clock {
++ compatible = "fixed-clock";
++ #clock-cells = <0>;
++ clock-frequency = <66666666>;
++ };
++
++ vcc_3v3: regulator0 {
++ compatible = "regulator-fixed";
++ regulator-name = "fixed-VCC3V3";
++ regulator-min-microvolt = <3300000>;
++ regulator-max-microvolt = <3300000>;
++ regulator-boot-on;
++ regulator-always-on;
++ };
++
++ vcc_vddq_vin0: regulator1 {
++ compatible = "regulator-fixed";
++ regulator-name = "VCC-VDDQ-VIN0";
++ regulator-min-microvolt = <3300000>;
++ regulator-max-microvolt = <3300000>;
++ regulator-boot-on;
++ regulator-always-on;
++ };
++};
++
++&avb {
++ pinctrl-0 = <&avb_pins>;
++ pinctrl-names = "default";
++ renesas,no-ether-link;
++ phy-handle = <&phy0>;
++ status = "okay";
++ phy-int-gpio = <&gpio1 17 GPIO_ACTIVE_LOW>;
++
++ phy0: ethernet-phy@0 {
++ rxc-skew-ps = <1500>;
++ rxdv-skew-ps = <420>; /* default */
++ rxd0-skew-ps = <420>; /* default */
++ rxd1-skew-ps = <420>; /* default */
++ rxd2-skew-ps = <420>; /* default */
++ rxd3-skew-ps = <420>; /* default */
++ txc-skew-ps = <900>; /* default */
++ txen-skew-ps = <420>; /* default */
++ txd0-skew-ps = <420>; /* default */
++ txd1-skew-ps = <420>; /* default */
++ txd2-skew-ps = <420>; /* default */
++ txd3-skew-ps = <420>; /* default */
++ reg = <0>;
++ interrupt-parent = <&gpio1>;
++ interrupts = <17 IRQ_TYPE_LEVEL_LOW>;
++ max-speed = <1000>;
++ };
++};
++
++&canfd {
++ pinctrl-0 = <&canfd0_pins &canfd1_pins>;
++ pinctrl-names = "default";
++ status = "okay";
++
++ channel0 {
++ status = "okay";
++ };
++
++ channel1 {
++ status = "okay";
++ };
++};
++
++&csi40 {
++ status = "okay";
++
++ virtual,channel {
++ csi2_vc0 {
++ data,type = "raw8";
++ receive,vc = <0>;
++ };
++ };
++
++ port {
++ #address-cells = <1>;
++ #size-cells = <0>;
++
++ csi40_ep: endpoint {
++ clock-lanes = <0>;
++ data-lanes = <1 2 3 4>;
++ csi-rate = <300>;
++ };
++ };
++};
++
++&du {
++ status = "okay";
++
++ ports {
++ port@0 {
++ endpoint {
++ remote-endpoint = <&lvds_in>;
++ };
++ };
++ };
++};
++
++&extal_clk {
++ clock-frequency = <16666666>;
++};
++
++&extalr_clk {
++ clock-frequency = <32768>;
++};
++
++&gpio1 {
++ pdb_ser_enable {
++ gpio-hog;
++ gpios = <26 GPIO_ACTIVE_HIGH>;
++ output-high;
++ line-name = "PDB_SER_Enable";
++ };
++
++ lvds_sw_sel {
++ gpio-hog;
++ gpios = <27 GPIO_ACTIVE_HIGH>;
++ output-low;
++ line-name = "LVDS_SW_SEL";
++ };
++};
++
++&gpio2 {
++ can0_inh_v3m {
++ gpio-hog;
++ gpios = <14 GPIO_ACTIVE_HIGH>;
++ output-low;
++ line-name = "CAN0_INH_V3M";
++ };
++
++ can1_inh_v3m {
++ gpio-hog;
++ gpios = <15 GPIO_ACTIVE_HIGH>;
++ output-low;
++ line-name = "CAN1_INH_V3M";
++ };
++};
++
++&gpio3 {
++ pdb_des_enable {
++ gpio-hog;
++ gpios = <0 GPIO_ACTIVE_HIGH>;
++ output-high;
++ line-name = "PDB_DES_Enable";
++ };
++};
++
++&i2c0 {
++ pinctrl-0 = <&i2c0_pins>;
++ pinctrl-names = "default";
++
++ status = "okay";
++ clock-frequency = <400000>;
++};
++
++&i2c3 {
++ pinctrl-0 = <&i2c3_pins>;
++ pinctrl-names = "default";
++
++ status = "okay";
++ clock-frequency = <400000>;
++
++ ov106xx@0 {
++ compatible = "ovti,ov106xx";
++ reg = <0x60>;
++
++ port@0 {
++ ov106xx_in0: endpoint {
++ clock-lanes = <0>;
++ data-lanes = <1 2 3 4>;
++ remote-endpoint = <&vin0ep0>;
++ };
++ };
++ port@1 {
++ ov106xx_ti9x4_des0ep0: endpoint@0 {
++ remote-endpoint = <&ti9x4_des0ep0>;
++ };
++ };
++ };
++
++ ti9x4@30 {
++ compatible = "ti,ti9x4";
++ reg = <0x30>;
++ ti,links = <1>;
++ ti,lanes = <4>;
++ ti,forwarding-mode = "round-robin";
++ ti,dvp_bus = <0>;
++ ti,ser_id = <0x30>;
++
++ port@0 {
++ ti9x4_des0ep0: endpoint@0 {
++ ti9x3-addr = <0x0c>;
++ dvp-order = <0>;
++ remote-endpoint = <&ov106xx_in0>;
++ };
++ };
++ port@1 {
++ ti9x4_csi0ep0: endpoint {
++ csi-rate = <800>;
++ remote-endpoint = <&csi40_ep>;
++ };
++ };
++ };
++};
++
++&msiof2 {
++ pinctrl-0 = <&msiof2_pins>;
++ pinctrl-names = "default";
++ cs-gpios = <&gpio2 4 0>;
++
++ status = "okay";
++ spidev@0 {
++ compatible = "renesas,sh-msiof";
++ reg = <0>;
++ spi-max-frequency = <66666666>;
++ };
++};
++
++&msiof3 {
++ pinctrl-0 = <&msiof3_pins>;
++ pinctrl-names = "default";
++
++ status = "okay";
++ slave;
++};
++
++&pfc {
++ pinctrl-0 = <&scif_clk_pins>;
++ pinctrl-names = "default";
++
++ avb_pins: avb {
++ groups = "avb0_mdc";
++ function = "avb0";
++ };
++
++ canfd0_pins: canfd0 {
++ groups = "canfd0_data_a";
++ function = "canfd0";
++ };
++
++ canfd1_pins: canfd1 {
++ groups = "canfd1_data";
++ function = "canfd1";
++ };
++
++ i2c0_pins: i2c0 {
++ groups = "i2c0";
++ function = "i2c0";
++ };
++
++ i2c3_pins: i2c3 {
++ groups = "i2c3";
++ function = "i2c3";
++ };
++
++ msiof2_pins: msiof2 {
++ groups = "msiof2_clk", "msiof2_txd", "msiof2_rxd";
++ function = "msiof2";
++ };
++
++ msiof3_pins: msiof3 {
++ groups = "msiof3_clk", "msiof3_txd", "msiof3_rxd", "msiof3_sync";
++ function = "msiof3";
++ };
++
++ scif0_pins: scif0 {
++ groups = "scif0_data";
++ function = "scif0";
++ };
++
++ scif_clk_pins: scif_clk {
++ groups = "scif_clk_b";
++ function = "scif_clk";
++ };
++
++ sdhi2_pins_3v3: sdhi2_3v3 {
++ groups = "mmc_data8", "mmc_ctrl";
++ function = "mmc";
++ power-source = <3300>;
++ };
++};
++
++&scif0 {
++ pinctrl-0 = <&scif0_pins>;
++ pinctrl-names = "default";
++
++ status = "okay";
++};
++
++&scif_clk {
++ clock-frequency = <14745600>;
++ status = "okay";
++};
++
++&sdhi2 {
++ /* used for on-board eMMC */
++ pinctrl-0 = <&sdhi2_pins_3v3>;
++ pinctrl-names = "default";
++
++ vmmc-supply = <&vcc_3v3>;
++ vqmmc-supply = <&vcc_vddq_vin0>;
++ no-1-8-v;
++ cap-mmc-highspeed;
++ bus-width = <8>;
++ non-removable;
++ status = "okay";
++};
++
++&vin0 {
++ status = "okay";
++
++ ports {
++ #address-cells = <1>;
++ #size-cells = <0>;
++
++ port@0 {
++ vin0ep0: endpoint {
++ csi,select = "csi40";
++ virtual,channel = <0>;
++ data-lanes = <1 2 3 4>;
++ remote-endpoint = <&ov106xx_in0>;
++ };
++ };
++ port@1 {
++ csi0ep0: endpoint {
++ remote-endpoint = <&csi40_ep>;
++ };
++ };
++ port@2 {
++ vin0_ti9x4_des0ep0: endpoint@0 {
++ remote-endpoint = <&ti9x4_des0ep0>;
++ };
++ };
++ };
++};
++
++&wdt0 {
++ status = "okay";
++};
+diff --git a/arch/arm64/boot/dts/renesas/r8a77980-condor.dts b/arch/arm64/boot/dts/renesas/r8a77980-condor.dts
+index 0b93a7d..e270cc0 100644
+--- a/arch/arm64/boot/dts/renesas/r8a77980-condor.dts
++++ b/arch/arm64/boot/dts/renesas/r8a77980-condor.dts
+@@ -28,6 +28,46 @@
+ reg = <0 0x48000000 0 0x78000000>;
+ };
+
++ reserved-memory {
++ #address-cells = <2>;
++ #size-cells = <2>;
++ ranges;
++
++ /* device specific region for Lossy Decompression */
++ lossy_decompress: linux,lossy_decompress {
++ no-map;
++ reg = <0x00000000 0x6c000000 0x0 0x03000000>;
++ };
++
++ /* global autoconfigured region for contiguous allocations */
++ linux,cma {
++ compatible = "shared-dma-pool";
++ reusable;
++ reg = <0x00000000 0x6f000000 0x0 0x10000000>;
++ linux,cma-default;
++ };
++
++ /* device specific region for contiguous allocations */
++ linux,multimedia {
++ compatible = "shared-dma-pool";
++ reusable;
++ reg = <0x00000000 0x7f000000 0x0 0x01000000>;
++ };
++ };
++
++ mmngr {
++ compatible = "renesas,mmngr";
++ memory-region = <&lossy_decompress>;
++ };
++
++ mmngrbuf {
++ compatible = "renesas,mmngrbuf";
++ };
++
++ vspm_if {
++ compatible = "renesas,vspm_if";
++ };
++
+ d3_3v: regulator-0 {
+ compatible = "regulator-fixed";
+ regulator-name = "D3.3V";
+diff --git a/arch/arm64/boot/dts/renesas/r8a77980-v3hsk-vbm-v2.dts b/arch/arm64/boot/dts/renesas/r8a77980-v3hsk-vbm-v2.dts
+new file mode 100644
+index 0000000..56d4253
+--- /dev/null
++++ b/arch/arm64/boot/dts/renesas/r8a77980-v3hsk-vbm-v2.dts
+@@ -0,0 +1,73 @@
++/*
++ * Device Tree Source for the V3HSK Videobox Mini board V2 on r8a7798
++ *
++ * Copyright (C) 2018 Cogent Embedded, Inc.
++ *
++ * This file is licensed under the terms of the GNU General Public License
++ * version 2. This program is licensed "as is" without any warranty of any
++ * kind, whether express or implied.
++ */
++
++#include "r8a7798-v3hsk-vbm.dts"
++
++/ {
++ model = "Renesas V3HSK Videobox Mini board V2 based on r8a7798";
++
++ leds {
++ compatible = "gpio-leds";
++
++ led5 {
++ label = "board:status";
++ gpios = <&gpio2 26 GPIO_ACTIVE_HIGH>;
++ linux,default-trigger = "heartbeat";
++ };
++ };
++};
++
++&gpio0 {
++ can1_stby {
++ gpio-hog;
++ gpios = <21 GPIO_ACTIVE_HIGH>;
++ output-low;
++ line-name = "CAN1STBY";
++ };
++};
++
++&pfc {
++ msiof1_pins: msiof1 {
++ groups = "msiof1_clk", "msiof1_txd", "msiof1_rxd";
++ function = "msiof1";
++ };
++
++ msiof2_pins: msiof2 {
++ groups = "msiof2_clk", "msiof2_sync", "msiof2_txd", "msiof2_rxd";
++ function = "msiof2";
++ };
++};
++
++&scif3 {
++ /* pin conflict with msiof2 */
++ /* set R240 and remove R241 before enabling */
++ status = "disabled";
++};
++
++&msiof1 {
++ pinctrl-0 = <&msiof1_pins>;
++ pinctrl-names = "default";
++ cs-gpios = <&gpio3 3 0>;
++
++ status = "okay";
++ spidev@0 {
++ compatible = "renesas,sh-msiof";
++ reg = <0>;
++ spi-max-frequency = <66666666>;
++ };
++};
++
++&msiof2 {
++ pinctrl-0 = <&msiof2_pins>;
++ pinctrl-names = "default";
++
++ status = "okay";
++ slave;
++};
+diff --git a/arch/arm64/boot/dts/renesas/r8a77980-v3hsk-vbm.dts b/arch/arm64/boot/dts/renesas/r8a77980-v3hsk-vbm.dts
+new file mode 100644
+index 0000000..9a54554
+--- /dev/null
++++ b/arch/arm64/boot/dts/renesas/r8a77980-v3hsk-vbm.dts
+@@ -0,0 +1,505 @@
++/*
++ * Device Tree Source for the V3HSK Videobox Mini board on r8a7798
++ *
++ * Copyright (C) 2018 Cogent Embedded, Inc.
++ *
++ * This file is licensed under the terms of the GNU General Public License
++ * version 2. This program is licensed "as is" without any warranty of any
++ * kind, whether express or implied.
++ */
++
++#include "r8a7798-v3hsk.dts"
++
++/ {
++ model = "Renesas V3HSK Videobox Mini board based on r8a7798";
++
++ aliases {
++ serial1 = &scif3;
++ };
++};
++
++&canfd {
++ pinctrl-0 = <&canfd0_pins &canfd1_pins>;
++ pinctrl-names = "default";
++ status = "okay";
++
++ channel0 {
++ status = "okay";
++ };
++
++ channel1 {
++ status = "okay";
++ };
++};
++
++&csi41 {
++ status = "okay";
++
++ virtual,channel {
++ csi2_vc0 {
++ data,type = "ycbcr422";
++ receive,vc = <0>;
++ };
++ csi2_vc1 {
++ data,type = "ycbcr422";
++ receive,vc = <1>;
++ };
++ csi2_vc2 {
++ data,type = "ycbcr422";
++ receive,vc = <2>;
++ };
++ csi2_vc3 {
++ data,type = "ycbcr422";
++ receive,vc = <3>;
++ };
++ };
++
++ port {
++ #address-cells = <1>;
++ #size-cells = <0>;
++
++ csi41_ep: endpoint {
++ clock-lanes = <0>;
++ data-lanes = <1 2 3 4>;
++ csi-rate = <300>;
++ };
++ };
++};
++
++&i2c1 {
++ pinctrl-0 = <&i2c1_pins>;
++ pinctrl-names = "default";
++ status = "okay";
++
++ clock-frequency = <400000>;
++
++ i2cswitch1: i2c-switch@74 {
++ compatible = "nxp,pca9548";
++ #address-cells = <1>;
++ #size-cells = <0>;
++ reg = <0x74>;
++ reset-gpios = <&gpio2 28 GPIO_ACTIVE_LOW>;
++
++ i2c@0 {
++ #address-cells = <1>;
++ #size-cells = <0>;
++ reg = <0>;
++
++ ov106xx@0 {
++ compatible = "ovti,ov106xx";
++ reg = <0x60>;
++
++ port@0 {
++ ov106xx_in0: endpoint {
++ clock-lanes = <0>;
++ data-lanes = <1 2 3 4>;
++ remote-endpoint = <&vin4ep0>;
++ };
++ };
++ port@1 {
++ ov106xx_max9286_des0ep0: endpoint@0 {
++ remote-endpoint = <&max9286_des0ep0>;
++ };
++ ov106xx_ti9x4_des0ep0: endpoint@1 {
++ remote-endpoint = <&ti9x4_des0ep0>;
++ };
++ };
++ };
++
++ ov106xx@1 {
++ compatible = "ovti,ov106xx";
++ reg = <0x61>;
++
++ port@0 {
++ ov106xx_in1: endpoint {
++ clock-lanes = <0>;
++ data-lanes = <1 2 3 4>;
++ remote-endpoint = <&vin5ep0>;
++ };
++ };
++ port@1 {
++ ov106xx_max9286_des0ep1: endpoint@0 {
++ remote-endpoint = <&max9286_des0ep1>;
++ };
++ ov106xx_ti9x4_des0ep1: endpoint@1 {
++ remote-endpoint = <&ti9x4_des0ep1>;
++ };
++ };
++ };
++
++ ov106xx@2 {
++ compatible = "ovti,ov106xx";
++ reg = <0x62>;
++
++ port@0 {
++ ov106xx_in2: endpoint {
++ clock-lanes = <0>;
++ data-lanes = <1 2 3 4>;
++ remote-endpoint = <&vin6ep0>;
++ };
++ };
++ port@1 {
++ ov106xx_max9286_des0ep2: endpoint@0 {
++ remote-endpoint = <&max9286_des0ep2>;
++ };
++ ov106xx_ti9x4_des0ep2: endpoint@1 {
++ remote-endpoint = <&ti9x4_des0ep2>;
++ };
++ };
++ };
++
++ ov106xx@3 {
++ compatible = "ovti,ov106xx";
++ reg = <0x63>;
++
++ port@0 {
++ ov106xx_in3: endpoint {
++ clock-lanes = <0>;
++ data-lanes = <1 2 3 4>;
++ remote-endpoint = <&vin7ep0>;
++ };
++ };
++ port@1 {
++ ov106xx_max9286_des0ep3: endpoint@0 {
++ remote-endpoint = <&max9286_des0ep3>;
++ };
++ ov106xx_ti9x4_des0ep3: endpoint@1 {
++ remote-endpoint = <&ti9x4_des0ep3>;
++ };
++ };
++ };
++
++ max9286@0 {
++ compatible = "maxim,max9286";
++ reg = <0x2c>;
++ maxim,links = <4>;
++ maxim,lanes = <4>;
++ maxim,resetb-gpio = <1>;
++ maxim,fsync-mode = "automatic";
++ maxim,timeout = <100>;
++
++ POC0-gpios = <&gpio_exp_6c 8 GPIO_ACTIVE_HIGH>;
++ POC1-gpios = <&gpio_exp_6c 9 GPIO_ACTIVE_HIGH>;
++ POC2-gpios = <&gpio_exp_6c 10 GPIO_ACTIVE_HIGH>;
++ POC3-gpios = <&gpio_exp_6c 11 GPIO_ACTIVE_HIGH>;
++
++ port@0 {
++ max9286_des0ep0: endpoint@0 {
++ max9271-addr = <0x50>;
++ dvp-order = <1>;
++ remote-endpoint = <&ov106xx_in0>;
++ };
++ max9286_des0ep1: endpoint@1 {
++ max9271-addr = <0x51>;
++ dvp-order = <1>;
++ remote-endpoint = <&ov106xx_in1>;
++ };
++ max9286_des0ep2: endpoint@2 {
++ max9271-addr = <0x52>;
++ dvp-order = <1>;
++ remote-endpoint = <&ov106xx_in2>;
++ };
++ max9286_des0ep3: endpoint@3 {
++ max9271-addr = <0x53>;
++ dvp-order = <1>;
++ remote-endpoint = <&ov106xx_in3>;
++ };
++ };
++ port@1 {
++ max9286_csi1ep0: endpoint {
++ csi-rate = <700>;
++ remote-endpoint = <&csi41_ep>;
++ };
++ };
++ };
++
++ ti9x4@0 {
++ compatible = "ti,ti9x4";
++ reg = <0x3a>;
++ ti,links = <4>;
++ ti,lanes = <4>;
++ ti,forwarding-mode = "round-robin";
++
++ POC0-gpios = <&gpio_exp_6c 8 GPIO_ACTIVE_HIGH>;
++ POC1-gpios = <&gpio_exp_6c 9 GPIO_ACTIVE_HIGH>;
++ POC2-gpios = <&gpio_exp_6c 10 GPIO_ACTIVE_HIGH>;
++ POC3-gpios = <&gpio_exp_6c 11 GPIO_ACTIVE_HIGH>;
++
++ port@0 {
++ ti9x4_des0ep0: endpoint@0 {
++ ti9x3-addr = <0x0c>;
++ dvp-order = <0>;
++ remote-endpoint = <&ov106xx_in0>;
++ };
++ ti9x4_des0ep1: endpoint@1 {
++ ti9x3-addr = <0x0d>;
++ dvp-order = <0>;
++ remote-endpoint = <&ov106xx_in1>;
++ };
++ ti9x4_des0ep2: endpoint@2 {
++ ti9x3-addr = <0x0e>;
++ dvp-order = <0>;
++ remote-endpoint = <&ov106xx_in2>;
++ };
++ ti9x4_des0ep3: endpoint@3 {
++ ti9x3-addr = <0x0f>;
++ dvp-order = <0>;
++ remote-endpoint = <&ov106xx_in3>;
++ };
++ };
++ port@1 {
++ ti9x4_csi0ep0: endpoint {
++ csi-rate = <700>;
++ remote-endpoint = <&csi41_ep>;
++ };
++ };
++ };
++ };
++
++ i2c@1 {
++ #address-cells = <1>;
++ #size-cells = <0>;
++ reg = <1>;
++
++ gpio_exp_6c: gpio@6c {
++ compatible = "maxim,max7325";
++ reg = <0x6c>;
++ gpio-controller;
++ #gpio-cells = <2>;
++
++ virq {
++ gpio-hog;
++ gpios = <5 GPIO_ACTIVE_HIGH>;
++ input;
++ line-name = "VIRQ";
++ };
++ des_cfg {
++ gpio-hog;
++ gpios = <6 GPIO_ACTIVE_HIGH>;
++ input;
++ line-name = "CNFG0";
++ };
++ pwr_shdn {
++ gpio-hog;
++ gpios = <14 GPIO_ACTIVE_HIGH>;
++ output-high;
++ line-name = "PWR_SHDN";
++ };
++ des_shdn {
++ gpio-hog;
++ gpios = <13 GPIO_ACTIVE_HIGH>;
++ output-high;
++ line-name = "Des_SHDN";
++ };
++ fpdl_shdn {
++ gpio-hog;
++ gpios = <15 GPIO_ACTIVE_HIGH>;
++ output-high;
++ line-name = "FPDL_SHDN";
++ };
++ };
++ };
++
++ i2c@3 {
++ #address-cells = <1>;
++ #size-cells = <0>;
++ reg = <3>;
++
++ /* fan node - lm96063 */
++ fan_ctrl: lm96063@4c {
++ compatible = "lm96163";
++ reg = <0x4c>;
++ };
++ };
++ };
++};
++
++&gpio2 {
++ can0_load {
++ gpio-hog;
++ gpios = <16 GPIO_ACTIVE_HIGH>;
++ output-low;
++ line-name = "can0_120R_load";
++ };
++
++ can0stby {
++ gpio-hog;
++ gpios = <27 GPIO_ACTIVE_HIGH>;
++ output-low;
++ line-name = "CAN0STBY";
++ };
++
++ can1_load {
++ gpio-hog;
++ gpios = <29 GPIO_ACTIVE_HIGH>;
++ output-low;
++ line-name = "can1_120R_load";
++ };
++
++ wake_pin_7 {
++ gpio-hog;
++ gpios = <8 GPIO_ACTIVE_HIGH>;
++ input;
++ line-name = "WAKE INPUT PIN 7";
++ };
++
++ wake_pin_8 {
++ gpio-hog;
++ gpios = <9 GPIO_ACTIVE_HIGH>;
++ input;
++ line-name = "WAKE INPUT PIN 8";
++ };
++};
++
++&pfc {
++ canfd0_pins: canfd0 {
++ groups = "canfd0_data_a";
++ function = "canfd0";
++ };
++
++ canfd1_pins: canfd1 {
++ groups = "canfd1_data";
++ function = "canfd1";
++ };
++
++ i2c1_pins: i2c1 {
++ groups = "i2c1";
++ function = "i2c1";
++ };
++
++ scif3_pins: scif3 {
++ groups = "scif3_data";
++ function = "scif3";
++ };
++};
++
++&scif3 {
++ pinctrl-0 = <&scif3_pins>;
++ pinctrl-names = "default";
++
++ status = "okay";
++};
++
++&vin4 {
++ status = "okay";
++
++ ports {
++ #address-cells = <1>;
++ #size-cells = <0>;
++
++ port@0 {
++ vin4ep0: endpoint {
++ csi,select = "csi41";
++ virtual,channel = <0>;
++ data-lanes = <1 2 3 4>;
++ remote-endpoint = <&ov106xx_in0>;
++ };
++ };
++ port@1 {
++ csi1ep0: endpoint {
++ remote-endpoint = <&csi41_ep>;
++ };
++ };
++ port@2 {
++ vin4_max9286_des0ep0: endpoint@0 {
++ remote-endpoint = <&max9286_des0ep0>;
++ };
++ vin4_ti9x4_des0ep0: endpoint@1 {
++ remote-endpoint = <&ti9x4_des0ep0>;
++ };
++ };
++ };
++};
++
++&vin5 {
++ status = "okay";
++
++ ports {
++ #address-cells = <1>;
++ #size-cells = <0>;
++
++ port@0 {
++ vin5ep0: endpoint {
++ csi,select = "csi41";
++ virtual,channel = <1>;
++ data-lanes = <1 2 3 4>;
++ remote-endpoint = <&ov106xx_in1>;
++ };
++ };
++ port@1 {
++ csi1ep1: endpoint {
++ remote-endpoint = <&csi41_ep>;
++ };
++ };
++ port@2 {
++ vin5_max9286_des0ep1: endpoint@0 {
++ remote-endpoint = <&max9286_des0ep1>;
++ };
++ vin5_ti9x4_des0ep1: endpoint@1 {
++ remote-endpoint = <&ti9x4_des0ep1>;
++ };
++ };
++ };
++};
++
++&vin6 {
++ status = "okay";
++
++ ports {
++ #address-cells = <1>;
++ #size-cells = <0>;
++
++ port@0 {
++ vin6ep0: endpoint {
++ csi,select = "csi41";
++ virtual,channel = <2>;
++ data-lanes = <1 2 3 4>;
++ remote-endpoint = <&ov106xx_in2>;
++ };
++ };
++ port@1 {
++ csi1ep2: endpoint {
++ remote-endpoint = <&csi41_ep>;
++ };
++ };
++ port@2 {
++ vin6_max9286_des0ep2: endpoint@0 {
++ remote-endpoint = <&max9286_des0ep2>;
++ };
++ vin6_ti9x4_des0ep2: endpoint@1 {
++ remote-endpoint = <&ti9x4_des0ep2>;
++ };
++ };
++ };
++};
++
++&vin7 {
++ status = "okay";
++
++ ports {
++ #address-cells = <1>;
++ #size-cells = <0>;
++
++ port@0 {
++ vin7ep0: endpoint {
++ csi,select = "csi41";
++ virtual,channel = <3>;
++ data-lanes = <1 2 3 4>;
++ remote-endpoint = <&ov106xx_in3>;
++ };
++ };
++ port@1 {
++ csi1ep3: endpoint {
++ remote-endpoint = <&csi41_ep>;
++ };
++ };
++ port@2 {
++ vin7_max9286_des0ep3: endpoint@0 {
++ remote-endpoint = <&max9286_des0ep3>;
++ };
++ vin7_ti9x4_des0ep3: endpoint@1 {
++ remote-endpoint = <&ti9x4_des0ep3>;
++ };
++ };
++ };
++};
+diff --git a/arch/arm64/boot/dts/renesas/r8a77980-v3hsk.dts b/arch/arm64/boot/dts/renesas/r8a77980-v3hsk.dts
+index c968099..dff7d02 100644
+--- a/arch/arm64/boot/dts/renesas/r8a77980-v3hsk.dts
++++ b/arch/arm64/boot/dts/renesas/r8a77980-v3hsk.dts
+@@ -26,6 +26,47 @@
+ /* first 128MB is reserved for secure area. */
+ reg = <0 0x48000000 0 0x78000000>;
+ };
++
++ reserved-memory {
++ #address-cells = <2>;
++ #size-cells = <2>;
++ ranges;
++
++ /* device specific region for Lossy Decompression */
++ lossy_decompress: linux,lossy_decompress {
++ no-map;
++ reg = <0x00000000 0x6c000000 0x0 0x03000000>;
++ };
++
++ /* global autoconfigured region for contiguous allocations */
++ linux,cma {
++ compatible = "shared-dma-pool";
++ reusable;
++ reg = <0x00000000 0x6f000000 0x0 0x10000000>;
++ linux,cma-default;
++ };
++
++ /* device specific region for contiguous allocations */
++ linux,multimedia {
++ compatible = "shared-dma-pool";
++ reusable;
++ reg = <0x00000000 0x7f000000 0x0 0x01000000>;
++ };
++ };
++
++ mmngr {
++ compatible = "renesas,mmngr";
++ memory-region = <&lossy_decompress>;
++ };
++
++ mmngrbuf {
++ compatible = "renesas,mmngrbuf";
++ };
++
++ vspm_if {
++ compatible = "renesas,vspm_if";
++ };
++
+ };
+
+ &extal_clk {
+diff --git a/arch/arm64/boot/dts/renesas/ulcb-kf-cn11.dtsi b/arch/arm64/boot/dts/renesas/ulcb-kf-cn11.dtsi
+new file mode 100644
+index 0000000..c5384ca
+--- /dev/null
++++ b/arch/arm64/boot/dts/renesas/ulcb-kf-cn11.dtsi
+@@ -0,0 +1,462 @@
++/*
++ * Device Tree Source for the H3ULCB Kingfisher board:
++ * this adding conflicting resource on VIN4/VIN5/VIN6/VIN7 for CN11
++ * use CN11 instead default CN29/CN48
++ *
++ * Copyright (C) 2017 Renesas Electronics Corp.
++ * Copyright (C) 2017 Cogent Embedded, Inc.
++ *
++ * This file is licensed under the terms of the GNU General Public License
++ * version 2. This program is licensed "as is" without any warranty of any
++ * kind, whether express or implied.
++ */
++
++&i2cswitch4 {
++ i2c@2 {
++ #address-cells = <1>;
++ #size-cells = <0>;
++ reg = <2>;
++ /* Slot B (CN11) */
++
++ ov106xx@4 {
++ compatible = "ovti,ov106xx";
++ reg = <0x64>;
++
++ port@0 {
++ ov106xx_in4: endpoint {
++ clock-lanes = <0>;
++ data-lanes = <1 2 3 4>;
++ remote-endpoint = <&vin4ep0>;
++ };
++ };
++ port@1 {
++ ov106xx_max9286_des1ep0: endpoint@0 {
++ remote-endpoint = <&max9286_des1ep0>;
++ };
++ ov106xx_ti9x4_des1ep0: endpoint@1 {
++ remote-endpoint = <&ti9x4_des1ep0>;
++ };
++ };
++ };
++
++ ov106xx@5 {
++ compatible = "ovti,ov106xx";
++ reg = <0x65>;
++
++ port@0 {
++ ov106xx_in5: endpoint {
++ clock-lanes = <0>;
++ data-lanes = <1 2 3 4>;
++ remote-endpoint = <&vin5ep0>;
++ };
++ };
++ port@1 {
++ ov106xx_max9286_des1ep1: endpoint@0 {
++ remote-endpoint = <&max9286_des1ep1>;
++ };
++ ov106xx_ti9x4_des1ep1: endpoint@1 {
++ remote-endpoint = <&ti9x4_des1ep1>;
++ };
++ };
++ };
++
++ ov106xx@6 {
++ compatible = "ovti,ov106xx";
++ reg = <0x66>;
++ port@0 {
++ ov106xx_in6: endpoint {
++ clock-lanes = <0>;
++ data-lanes = <1 2 3 4>;
++ remote-endpoint = <&vin6ep0>;
++ };
++ };
++ port@1 {
++ ov106xx_max9286_des1ep2: endpoint@0 {
++ remote-endpoint = <&max9286_des1ep2>;
++ };
++ ov106xx_ti9x4_des1ep2: endpoint@1 {
++ remote-endpoint = <&ti9x4_des1ep2>;
++ };
++ };
++ };
++
++ ov106xx@7 {
++ compatible = "ovti,ov106xx";
++ reg = <0x67>;
++ port@0 {
++ ov106xx_in7: endpoint {
++ clock-lanes = <0>;
++ data-lanes = <1 2 3 4>;
++ remote-endpoint = <&vin7ep0>;
++ };
++ };
++ port@1 {
++ ov106xx_max9286_des1ep3: endpoint@0 {
++ remote-endpoint = <&max9286_des1ep3>;
++ };
++ ov106xx_ti9x4_des1ep3: endpoint@1 {
++ remote-endpoint = <&ti9x4_des1ep3>;
++ };
++ };
++ };
++
++ /* DS90UB9x4 @ 0x3a */
++ ti9x4@1 {
++ compatible = "ti,ti9x4";
++ reg = <0x3a>;
++ ti,sensor_delay = <350>;
++ ti,links = <4>;
++ ti,lanes = <4>;
++ ti,forwarding-mode = "round-robin";
++ ti,cable-mode = "coax";
++
++ POC0-gpios = <&gpio_exp_b_5c 8 GPIO_ACTIVE_HIGH>;
++ POC1-gpios = <&gpio_exp_b_5c 9 GPIO_ACTIVE_HIGH>;
++ POC2-gpios = <&gpio_exp_b_5c 10 GPIO_ACTIVE_HIGH>;
++ POC3-gpios = <&gpio_exp_b_5c 11 GPIO_ACTIVE_HIGH>;
++
++ port@0 {
++ ti9x4_des1ep0: endpoint@0 {
++ ti9x3-addr = <0x0c>;
++ dvp-order = <0>;
++ remote-endpoint = <&ov106xx_in4>;
++ };
++ ti9x4_des1ep1: endpoint@1 {
++ ti9x3-addr = <0x0d>;
++ dvp-order = <0>;
++ remote-endpoint = <&ov106xx_in5>;
++ };
++ ti9x4_des1ep2: endpoint@2 {
++ ti9x3-addr = <0x0e>;
++ dvp-order = <0>;
++ remote-endpoint = <&ov106xx_in6>;
++ };
++ ti9x4_des1ep3: endpoint@3 {
++ ti9x3-addr = <0x0f>;
++ dvp-order = <0>;
++ remote-endpoint = <&ov106xx_in7>;
++ };
++ };
++ port@1 {
++ ti9x4_csi2ep0: endpoint {
++ csi-rate = <1450>;
++ remote-endpoint = <&csi41_ep>;
++ };
++ };
++ };
++
++ /* MAX9286 @ 0x2c */
++ max9286@1 {
++ compatible = "maxim,max9286";
++ reg = <0x2c>;
++ maxim,sensor_delay = <350>;
++ maxim,links = <4>;
++ maxim,lanes = <4>;
++ maxim,resetb-gpio = <1>;
++ maxim,fsync-mode = "automatic";
++ maxim,timeout = <100>;
++
++ POC0-gpios = <&gpio_exp_b_5c 9 GPIO_ACTIVE_HIGH>;
++ POC1-gpios = <&gpio_exp_b_5c 8 GPIO_ACTIVE_HIGH>;
++ POC2-gpios = <&gpio_exp_b_5c 11 GPIO_ACTIVE_HIGH>;
++ POC3-gpios = <&gpio_exp_b_5c 10 GPIO_ACTIVE_HIGH>;
++
++ port@0 {
++ max9286_des1ep0: endpoint@0 {
++ max9271-addr = <0x50>;
++ dvp-order = <1>;
++ remote-endpoint = <&ov106xx_in4>;
++ };
++ max9286_des1ep1: endpoint@1 {
++ max9271-addr = <0x51>;
++ dvp-order = <1>;
++ remote-endpoint = <&ov106xx_in5>;
++ };
++ max9286_des1ep2: endpoint@2 {
++ max9271-addr = <0x52>;
++ dvp-order = <1>;
++ remote-endpoint = <&ov106xx_in6>;
++ };
++ max9286_des1ep3: endpoint@3 {
++ max9271-addr = <0x53>;
++ dvp-order = <1>;
++ remote-endpoint = <&ov106xx_in7>;
++ };
++ };
++ port@1 {
++ max9286_csi2ep0: endpoint {
++ csi-rate = <700>;
++ remote-endpoint = <&csi41_ep>;
++ };
++ };
++ };
++ };
++
++ i2c@6 {
++ #address-cells = <1>;
++ #size-cells = <0>;
++ reg = <6>;
++ /* Slot B (CN11) */
++
++ /* PCA9535 is a redundand/deprecated card */
++ gpio_exp_b_27: gpio@27 {
++ compatible = "nxp,pca9535";
++ reg = <0x27>;
++ gpio-controller;
++ #gpio-cells = <2>;
++
++ video_b_des_cfg1 {
++ gpio-hog;
++ gpios = <5 GPIO_ACTIVE_HIGH>;
++ input;
++ line-name = "Video-B cfg1";
++ };
++ video_b_des_cfg0 {
++ gpio-hog;
++ gpios = <6 GPIO_ACTIVE_HIGH>;
++ input;
++ line-name = "Video-B cfg0";
++ };
++ video_b_pwr_shdn {
++ gpio-hog;
++ gpios = <3 GPIO_ACTIVE_HIGH>;
++ output-high;
++ line-name = "Video-B PWR_SHDN";
++ };
++ video_b_cam_pwr0 {
++ gpio-hog;
++ gpios = <12 GPIO_ACTIVE_HIGH>;
++ output-high;
++ line-name = "Video-B PWR0";
++ };
++ video_b_cam_pwr1 {
++ gpio-hog;
++ gpios = <13 GPIO_ACTIVE_HIGH>;
++ output-high;
++ line-name = "Video-B PWR1";
++ };
++ video_b_cam_pwr2 {
++ gpio-hog;
++ gpios = <14 GPIO_ACTIVE_HIGH>;
++ output-high;
++ line-name = "Video-B PWR2";
++ };
++ video_b_cam_pwr3 {
++ gpio-hog;
++ gpios = <15 GPIO_ACTIVE_HIGH>;
++ output-high;
++ line-name = "Video-B PWR3";
++ };
++ video_b_des_shdn {
++ gpio-hog;
++ gpios = <4 GPIO_ACTIVE_HIGH>;
++ output-high;
++ line-name = "Video-B DES_SHDN";
++ };
++ video_b_des_led {
++ gpio-hog;
++ gpios = <7 GPIO_ACTIVE_HIGH>;
++ output-low;
++ line-name = "Video-B led";
++ };
++ };
++
++ gpio_exp_b_5c: gpio@5c {
++ compatible = "maxim,max7325";
++ reg = <0x5c>;
++ gpio-controller;
++ #gpio-cells = <2>;
++
++ video_b_des_cfg2 {
++ gpio-hog;
++ gpios = <4 GPIO_ACTIVE_HIGH>;
++ input;
++ line-name = "Video-B cfg2";
++ };
++ video_b_des_cfg1 {
++ gpio-hog;
++ gpios = <6 GPIO_ACTIVE_HIGH>;
++ input;
++ line-name = "Video-B cfg1";
++ };
++ video_b_des_cfg0 {
++ gpio-hog;
++ gpios = <7 GPIO_ACTIVE_HIGH>;
++ input;
++ line-name = "Video-B cfg0";
++ };
++ video_b_pwr_shdn {
++ gpio-hog;
++ gpios = <14 GPIO_ACTIVE_HIGH>;
++ output-high;
++ line-name = "Video-B PWR_SHDN";
++ };
++ video_b_des_shdn {
++ gpio-hog;
++ gpios = <13 GPIO_ACTIVE_HIGH>;
++ output-high;
++ line-name = "Video-B DES_SHDN";
++ };
++ video_b_led {
++ gpio-hog;
++ gpios = <12 GPIO_ACTIVE_HIGH>;
++ output-low;
++ line-name = "Video-B LED";
++ };
++ };
++ };
++};
++
++&vin4 {
++ ports {
++ #address-cells = <1>;
++ #size-cells = <0>;
++
++ port@0 {
++ vin4ep0: endpoint {
++ csi,select = "csi41";
++ virtual,channel = <0>;
++ remote-endpoint = <&ov106xx_in4>;
++ data-lanes = <1 2 3 4>;
++ };
++ };
++ port@1 {
++ csi2ep0: endpoint {
++ remote-endpoint = <&csi41_ep>;
++ };
++ };
++ port@2 {
++ vin4_max9286_des1ep0: endpoint@0 {
++ remote-endpoint = <&max9286_des1ep0>;
++ };
++ vin4_ti9x4_des1ep0: endpoint@1 {
++ remote-endpoint = <&ti9x4_des1ep0>;
++ };
++ };
++ };
++};
++
++&vin5 {
++ ports {
++ #address-cells = <1>;
++ #size-cells = <0>;
++
++ port@0 {
++ vin5ep0: endpoint@0 {
++ csi,select = "csi41";
++ virtual,channel = <1>;
++ remote-endpoint = <&ov106xx_in5>;
++ data-lanes = <1 2 3 4>;
++ };
++ };
++ port@1 {
++ csi2ep1: endpoint {
++ remote-endpoint = <&csi41_ep>;
++ };
++ };
++ port@2 {
++ vin5_max9286_des1ep1: endpoint@0 {
++ remote-endpoint = <&max9286_des1ep1>;
++ };
++ vin5_ti9x4_des1ep1: endpoint@1 {
++ remote-endpoint = <&ti9x4_des1ep1>;
++ };
++ };
++ };
++};
++
++&vin6 {
++ status = "okay";
++
++ ports {
++ #address-cells = <1>;
++ #size-cells = <0>;
++
++ port@0 {
++ vin6ep0: endpoint@0 {
++ csi,select = "csi41";
++ virtual,channel = <2>;
++ remote-endpoint = <&ov106xx_in6>;
++ data-lanes = <1 2 3 4>;
++ };
++ };
++ port@1 {
++ csi2ep2: endpoint {
++ remote-endpoint = <&csi41_ep>;
++ };
++ };
++ port@2 {
++ vin6_max9286_des1ep2: endpoint@0 {
++ remote-endpoint = <&max9286_des1ep2>;
++ };
++ vin6_ti9x4_des1ep2: endpoint@1 {
++ remote-endpoint = <&ti9x4_des1ep2>;
++ };
++ };
++ };
++};
++
++&vin7 {
++ status = "okay";
++
++ ports {
++ #address-cells = <1>;
++ #size-cells = <0>;
++
++ port@0 {
++ vin7ep0: endpoint@0 {
++ csi,select = "csi41";
++ virtual,channel = <3>;
++ remote-endpoint = <&ov106xx_in7>;
++ data-lanes = <1 2 3 4>;
++ };
++ };
++ port@1 {
++ csi2ep3: endpoint {
++ remote-endpoint = <&csi41_ep>;
++ };
++ };
++ port@2 {
++ vin7_max9286_des1ep3: endpoint@0 {
++ remote-endpoint = <&max9286_des1ep3>;
++ };
++ vin7_ti9x4_des1ep3: endpoint@1 {
++ remote-endpoint = <&ti9x4_des1ep3>;
++ };
++ };
++ };
++};
++
++&csi41 {
++ status = "okay";
++
++ virtual,channel {
++ csi2_vc0 {
++ data,type = "ycbcr422";
++ receive,vc = <0>;
++ };
++ csi2_vc1 {
++ data,type = "ycbcr422";
++ receive,vc = <1>;
++ };
++ csi2_vc2 {
++ data,type = "ycbcr422";
++ receive,vc = <2>;
++ };
++ csi2_vc3 {
++ data,type = "ycbcr422";
++ receive,vc = <3>;
++ };
++ };
++
++ port {
++ #address-cells = <1>;
++ #size-cells = <0>;
++
++ csi41_ep: endpoint {
++ clock-lanes = <0>;
++ data-lanes = <1 2 3 4>;
++ csi-rate = <300>;
++ };
++ };
++};
+diff --git a/arch/arm64/boot/dts/renesas/ulcb-kf-most.dtsi b/arch/arm64/boot/dts/renesas/ulcb-kf-most.dtsi
+new file mode 100644
+index 0000000..4af5ca0
+--- /dev/null
++++ b/arch/arm64/boot/dts/renesas/ulcb-kf-most.dtsi
+@@ -0,0 +1,30 @@
++/*
++ * Device Tree Source for the H3/M3ULCB Kingfisher board:
++ * this overrides GPS in favour MOST on GP5_24/GP5_25 R-CAR pins
++ *
++ * Copyright (C) 2017 Renesas Electronics Corp.
++ * Copyright (C) 2017 Cogent Embedded, Inc.
++ *
++ * This file is licensed under the terms of the GNU General Public License
++ * version 2. This program is licensed "as is" without any warranty of any
++ * kind, whether express or implied.
++ */
++
++&pfc {
++ mlp_pins: mlp {
++ groups = "mlb_3pin";
++ function = "mlb_3pin";
++ };
++};
++
++&scif1 {
++ status = "disabled";
++};
++
++&mlp {
++ pinctrl-0 = <&mlp_pins>;
++ pinctrl-names = "default";
++ status = "okay";
++
++ clock-speed = "1024fs";
++};
+diff --git a/arch/arm64/boot/dts/renesas/ulcb-kf-sd3.dtsi b/arch/arm64/boot/dts/renesas/ulcb-kf-sd3.dtsi
+new file mode 100644
+index 0000000..b854216
+--- /dev/null
++++ b/arch/arm64/boot/dts/renesas/ulcb-kf-sd3.dtsi
+@@ -0,0 +1,46 @@
++/*
++ * Device Tree Source for the H3/M3ULCB Kingfisher board:
++ * this overrides WIFI in favour SD on SDHI3
++ *
++ * Copyright (C) 2017 Renesas Electronics Corp.
++ * Copyright (C) 2017 Cogent Embedded, Inc.
++ *
++ * This file is licensed under the terms of the GNU General Public License
++ * version 2. This program is licensed "as is" without any warranty of any
++ * kind, whether express or implied.
++ */
++
++&sdio_switch {
++ regulator-name = "sd_on";
++ enable-active-high;
++};
++
++&vccq_sdhi3 {
++ compatible = "regulator-gpio";
++
++ regulator-min-microvolt = <1800000>;
++
++ gpios = <&gpio3 14 GPIO_ACTIVE_HIGH>;
++ gpios-states = <1>;
++ states = <3300000 1
++ 1800000 0>;
++};
++
++&sdhi3 {
++ /delete-property/non-removable;
++ /delete-property/cap-power-off-card;
++ /delete-property/keep-power-in-suspend;
++ /delete-property/enable-sdio-wakeup;
++ /delete-property/max-frequency;
++ /delete-property/no-1-8-v;
++
++ vmmc-supply = <&vcc_sdhi3>;
++ cd-gpios = <&gpio4 15 GPIO_ACTIVE_LOW>;
++ wp-gpios = <&gpio4 16 GPIO_ACTIVE_HIGH>;
++// sd-uhs-sdr50;
++// sd-uhs-sdr104;
++};
++
++&wlcore {
++ status = "disabled";
++};
+diff --git a/arch/arm64/boot/dts/renesas/ulcb-kf.dtsi b/arch/arm64/boot/dts/renesas/ulcb-kf.dtsi
+index 1b316d79..a70636e 100644
+--- a/arch/arm64/boot/dts/renesas/ulcb-kf.dtsi
++++ b/arch/arm64/boot/dts/renesas/ulcb-kf.dtsi
+@@ -10,7 +10,239 @@
+ aliases {
+ serial1 = &hscif0;
+ serial2 = &scif1;
++ serial3 = &hscif1;
+ };
++
++ snd_clk: snd_clk {
++ compatible = "fixed-clock";
++ #clock-cells = <0>;
++ clock-frequency = <24576000>;
++ clock-output-names = "scki";
++ };
++
++ wlan_en: regulator@4 {
++ compatible = "regulator-fixed";
++ regulator-name = "wlan-en-regulator";
++
++ regulator-min-microvolt = <3300000>;
++ regulator-max-microvolt = <3300000>;
++
++ gpio = <&gpio_exp_74 4 GPIO_ACTIVE_HIGH>;
++ enable-active-high;
++ };
++
++ vcc_sdhi3: regulator@41 {
++ compatible = "regulator-fixed";
++
++ regulator-name = "SDHI3 Vcc";
++ regulator-min-microvolt = <3300000>;
++ regulator-max-microvolt = <3300000>;
++
++ gpio = <&gpio4 17 GPIO_ACTIVE_HIGH>;
++ enable-active-high;
++ };
++
++ vccq_sdhi3: regulator@5 {
++ compatible = "regulator-fixed";
++
++ regulator-name = "SDHI3 VccQ";
++ regulator-min-microvolt = <3300000>;
++ regulator-max-microvolt = <3300000>;
++ };
++
++ codec_en_reg: regulator@6 {
++ compatible = "regulator-fixed";
++ regulator-name = "codec-en-regulator";
++ regulator-min-microvolt = <3300000>;
++ regulator-max-microvolt = <3300000>;
++
++ gpio = <&gpio_exp_74 15 0>;
++
++ /* delay - CHECK */
++ startup-delay-us = <70000>;
++ enable-active-high;
++ };
++
++ amp_en_reg: regulator@7 {
++ compatible = "regulator-fixed";
++ regulator-name = "amp-en-regulator";
++ regulator-min-microvolt = <3300000>;
++ regulator-max-microvolt = <3300000>;
++
++ gpio = <&gpio_exp_74 0 0>;
++
++ startup-delay-us = <0>;
++ enable-active-high;
++ };
++
++ sdio_switch: regulator@9 {
++ compatible = "regulator-fixed";
++ regulator-name = "wifi_on";
++ regulator-min-microvolt = <3300000>;
++ regulator-max-microvolt = <3300000>;
++ gpio = <&gpio_exp_74 5 0>;
++ enable-active-low;
++ regulator-always-on;
++ };
++
++ radio_switch: regulator@11 {
++ compatible = "regulator-fixed";
++ regulator-name = "radio_on";
++ regulator-min-microvolt = <3300000>;
++ regulator-max-microvolt = <3300000>;
++ gpio = <&gpio_exp_74 13 GPIO_ACTIVE_HIGH>;
++ enable-active-high;
++ regulator-always-on;
++ };
++
++ mpcie_3v3: regulator@12 {
++ compatible = "regulator-fixed";
++ regulator-name = "mPCIe 3v3";
++ regulator-min-microvolt = <3300000>;
++ regulator-max-microvolt = <3300000>;
++ gpio = <&gpio_exp_77 14 GPIO_ACTIVE_HIGH>;
++ enable-active-high;
++ };
++
++ mpcie_1v8: regulator@13 {
++ compatible = "regulator-fixed";
++ regulator-name = "mPCIe 1v8";
++ regulator-min-microvolt = <1800000>;
++ regulator-max-microvolt = <1800000>;
++ gpio = <&gpio_exp_77 15 GPIO_ACTIVE_HIGH>;
++ startup-delay-us = <200000>;
++ enable-active-high;
++ };
++
++ kim {
++ compatible = "kim";
++ shutdown-gpios = <&gpio_exp_74 3 GPIO_ACTIVE_HIGH>;
++ /* serial1 */
++ dev_name = "/dev/ttySC1";
++ flow_cntrl = <1>;
++ /* int div 8 hscif@26.6666656MHz */
++ baud_rate = <3333332>;
++ };
++
++ btwilink {
++ compatible = "btwilink";
++ };
++
++ sound_ext: sound@0 {
++ pinctrl-0 = <&sound_0_pins>;
++ pinctrl-names = "default";
++
++ compatible = "audio-graph-card";
++
++ label = "pcm3168a";
++
++ dais = <&rsnd_port0>;
++ };
++
++ /delete-node/sound;
++
++ rsnd_ak4613: sound@1 {
++ compatible = "audio-graph-card";
++
++ label = "ak4613";
++
++ dais = <&rsnd_port1>;
++ };
++
++ sound_radio: sound@2 {
++ pinctrl-0 = <&sound_2_pins>;
++ pinctrl-names = "default";
++
++ compatible = "audio-graph-card";
++
++ label = "radio";
++
++ dais = <&rsnd_port2>;
++ };
++
++ sound_wl18xx: sound@3 {
++ pinctrl-0 = <&sound_3_pins>;
++ pinctrl-names = "default";
++
++ compatible = "audio-graph-card";
++
++ label = "wl18xx";
++
++ dais = <&rsnd_port3>;
++ };
++
++ lvds {
++ compatible = "panel-lvds";
++
++ width-mm = <210>;
++ height-mm = <158>;
++
++ data-mapping = "jeida-24";
++
++ panel-timing {
++ /* 1280x800 @60Hz */
++ clock-frequency = <65000000>;
++ hactive = <1280>;
++ vactive = <800>;
++ hsync-len = <40>;
++ hfront-porch = <80>;
++ hback-porch = <40>;
++ vfront-porch = <14>;
++ vback-porch = <14>;
++ vsync-len = <4>;
++ };
++
++ port {
++ lvds_in: endpoint {
++ remote-endpoint = <&lvds0_out>;
++ };
++ };
++ };
++
++ hdmi-out {
++ compatible = "hdmi-connector";
++ type = "a";
++
++ port {
++ hdmi_con: endpoint {
++ remote-endpoint = <&adv7513_out>;
++ };
++ };
++ };
++
++ radio: si468x@0 {
++ compatible = "si,si468x-pcm";
++ status = "okay";
++
++ port {
++ radio_endpoint: endpoint {
++ remote-endpoint = <&rsnd_endpoint2>;
++ system-clock-frequency = <12288000>;
++ };
++ };
++ };
++
++ wl18xx_pcm: wl18xx_pcm@0 {
++ compatible = "ti,wl18xx-pcm";
++ status = "okay";
++
++ port {
++ wl18xx_pcm_endpoint: endpoint {
++ remote-endpoint = <&rsnd_endpoint3>;
++ };
++ };
++ };
++
++ camera_clk: camera_clk {
++ compatible = "fixed-clock";
++ #clock-cells = <0>;
++ clock-frequency = <24000000>;
++ clock-output-names = "mclk";
++ };
++};
++
++&ak4613_endpoint {
++ remote-endpoint = <&rsnd_endpoint1>;
+ };
+
+ &can0 {
+@@ -25,11 +257,113 @@
+ status = "okay";
+ };
+
++&canfd {
++ pinctrl-0 = <&canfd0_pins &canfd1_pins>;
++ pinctrl-names = "default";
++ status = "disabled";
++
++ channel0 {
++ status = "okay";
++ };
++
++ channel1 {
++ status = "okay";
++ };
++};
++
++&csi40 {
++ status = "okay";
++
++ virtual,channel {
++ csi2_vc0 {
++ data,type = "ycbcr422";
++ receive,vc = <0>;
++ };
++ csi2_vc1 {
++ data,type = "ycbcr422";
++ receive,vc = <1>;
++ };
++ csi2_vc2 {
++ data,type = "ycbcr422";
++ receive,vc = <2>;
++ };
++ csi2_vc3 {
++ data,type = "ycbcr422";
++ receive,vc = <3>;
++ };
++ };
++
++ port {
++ #address-cells = <1>;
++ #size-cells = <0>;
++
++ csi40_ep: endpoint {
++ clock-lanes = <0>;
++ data-lanes = <1 2 3 4>;
++ csi-rate = <300>;
++ };
++ };
++};
++
++&csi20 {
++ status = "okay";
++
++ virtual,channel {
++ csi2_vc0 {
++ data,type = "raw8";
++ receive,vc = <0>;
++ };
++ };
++
++ port {
++ #address-cells = <1>;
++ #size-cells = <0>;
++
++ csi20_ep: endpoint {
++ clock-lanes = <0>;
++ data-lanes = <1 2>;
++ csi-rate = <280>;
++ };
++ };
++};
++
++&du {
++ pinctrl-0 = <&du_pins>;
++ pinctrl-names = "default";
++};
++
+ &ehci0 {
+ dr_mode = "otg";
+ status = "okay";
+ };
+
++&gpio2 {
++ bl_pwm {
++ gpio-hog;
++ gpios = <3 GPIO_ACTIVE_HIGH>;
++ output-high;
++ line-name = "BL PWM 100%";
++ };
++};
++
++&gpio4 {
++ most_rst {
++ gpio-hog;
++ gpios = <14 GPIO_ACTIVE_HIGH>;
++ output-high;
++ line-name = "MOST RST";
++ };
++};
++
++&gpio6 {
++ audio_sw {
++ gpio-hog;
++ gpios = <21 GPIO_ACTIVE_HIGH>;
++ output-high;
++ line-name = "Onboard MCh Audio";
++ };
++};
++
+ &hscif0 {
+ pinctrl-0 = <&hscif0_pins>;
+ pinctrl-names = "default";
+@@ -38,21 +372,31 @@
+ status = "okay";
+ };
+
++&hscif1 {
++ pinctrl-0 = <&hscif1_pins>;
++ pinctrl-names = "default";
++
++ status = "okay";
++};
++
+ &hsusb {
+ dr_mode = "otg";
+ status = "okay";
+ };
+
+ &i2c2 {
++ clock-frequency = <100000>;
++
+ gpio_exp_74: gpio@74 {
+ compatible = "ti,tca9539";
+ reg = <0x74>;
+ gpio-controller;
+ #gpio-cells = <2>;
++/*
+ interrupt-controller;
+ interrupt-parent = <&gpio6>;
+ interrupts = <8 IRQ_TYPE_EDGE_FALLING>;
+-
++*/
+ hub_pwen {
+ gpio-hog;
+ gpios = <6 GPIO_ACTIVE_HIGH>;
+@@ -90,6 +434,19 @@
+ interrupt-controller;
+ interrupt-parent = <&gpio6>;
+ interrupts = <4 IRQ_TYPE_EDGE_FALLING>;
++
++ gps_rst {
++ gpio-hog;
++ gpios = <6 GPIO_ACTIVE_HIGH>;
++ output-high;
++ line-name = "GPS rst";
++ };
++ fpdl_shdn {
++ gpio-hog;
++ gpios = <9 GPIO_ACTIVE_HIGH>;
++ output-high;
++ line-name = "FPDLink shdn";
++ };
+ };
+
+ i2cswitch2: i2c-switch@71 {
+@@ -98,6 +455,142 @@
+ #size-cells = <0>;
+ reg = <0x71>;
+ reset-gpios = <&gpio5 3 GPIO_ACTIVE_LOW>;
++
++ i2c@0 {
++ #address-cells = <1>;
++ #size-cells = <0>;
++ reg = <0>;
++ /* BCM node(s) */
++ };
++
++ i2c@1 {
++ #address-cells = <1>;
++ #size-cells = <0>;
++ reg = <1>;
++ /* USB3.0 HUB node(s) */
++ };
++
++ i2c@2 {
++ #address-cells = <1>;
++ #size-cells = <0>;
++ reg = <2>;
++ /* Power amp node(s) */
++ };
++
++ i2c@3 {
++ #address-cells = <1>;
++ #size-cells = <0>;
++ reg = <3>;
++ /* Radio node(s) */
++ };
++
++ i2c@4 {
++ #address-cells = <1>;
++ #size-cells = <0>;
++ reg = <4>;
++
++ hdmi@3d {
++ compatible = "adi,adv7513";
++ reg = <0x3d>;
++// interrupt-parent = <&gpio2>;
++// interrupts = <0 IRQ_TYPE_EDGE_BOTH>;
++ pd-gpios = <&gpio_exp_75 5 GPIO_ACTIVE_LOW>;
++
++ interlace-allowed;
++ adi,input-depth = <8>;
++ adi,input-colorspace = "rgb";
++ adi,input-clock = "1x";
++ adi,input-style = <1>;
++ adi,input-justification = "evenly";
++ adi,clock-delay = <1200>;
++
++ limit-frequency = <100000000>;
++// lower-refresh = <50>;
++
++ ports {
++ #address-cells = <1>;
++ #size-cells = <0>;
++
++ port@0 {
++ reg = <0>;
++ adv7513_in: endpoint {
++ remote-endpoint = <&du_out_rgb>;
++ };
++ };
++
++ port@1 {
++ reg = <1>;
++ adv7513_out: endpoint {
++ remote-endpoint = <&hdmi_con>;
++ };
++ };
++ };
++ };
++ };
++
++ i2c@5 {
++ #address-cells = <1>;
++ #size-cells = <0>;
++ reg = <5>;
++ /* PCIe node(s) */
++ };
++
++ i2c@6 {
++ #address-cells = <1>;
++ #size-cells = <0>;
++ reg = <6>;
++ /* LVDS display node(s) */
++
++ polytouch: edt-ft5x06@38 {
++ compatible = "edt,edt-ft5x06";
++ reg = <0x38>;
++ interrupt-parent = <&gpio5>;
++ interrupts = <6 IRQ_TYPE_EDGE_FALLING>;
++ };
++ };
++
++ i2c@7 {
++ #address-cells = <1>;
++ #size-cells = <0>;
++ reg = <7>;
++ /* Audio, GPS and Gyro node(s) */
++
++ pcm3168a: audio-codec@44 {
++ #sound-dai-cells = <0>;
++ compatible = "ti,pcm3168a";
++ reg = <0x44>;
++ clocks = <&snd_clk>;
++ clock-names = "scki";
++ tdm;
++ VDD1-supply = <&codec_en_reg>;
++ VDD2-supply = <&codec_en_reg>;
++ VCCAD1-supply = <&codec_en_reg>;
++ VCCAD2-supply = <&codec_en_reg>;
++ VCCDA1-supply = <&amp_en_reg>;
++ VCCDA2-supply = <&amp_en_reg>;
++
++ port {
++ pcm3168a_endpoint: endpoint {
++ remote-endpoint = <&rsnd_endpoint0>;
++ dai-tdm-slot-num = <8>;
++ dai-tdm-slot-width = <32>;
++ system-clock-frequency = <24576000>;
++ };
++ };
++ };
++
++ lsm9ds0_acc_mag@1d {
++ compatible = "st,lsm9ds0_accel_magn";
++ reg = <0x1d>;
++ };
++
++ lsm9ds0_gyr@6b {
++ compatible = "st,lsm9ds0_gyro";
++ reg = <0x6b>;
++ };
++
++ /* GPS@ 0x42 */
++ };
+ };
+ };
+
+@@ -110,6 +603,76 @@
+ interrupt-controller;
+ interrupt-parent = <&gpio7>;
+ interrupts = <3 IRQ_TYPE_EDGE_FALLING>;
++
++ port_b_a0 {
++ gpio-hog;
++ gpios = <0 GPIO_ACTIVE_HIGH>;
++ output-low;
++ line-name = "Video-B A0";
++ };
++ port_b_a1 {
++ gpio-hog;
++ gpios = <1 GPIO_ACTIVE_HIGH>;
++ output-high;
++ line-name = "Video-B A1";
++ };
++ port_a_a0 {
++ gpio-hog;
++ gpios = <2 GPIO_ACTIVE_HIGH>;
++ output-low;
++ line-name = "Video-A A0";
++ };
++ port_a_a1 {
++ gpio-hog;
++ gpios = <3 GPIO_ACTIVE_HIGH>;
++ output-high;
++ line-name = "Video-A A1";
++ };
++ cmos_pwdn {
++ gpio-hog;
++ gpios = <8 GPIO_ACTIVE_HIGH>;
++ output-high;
++ line-name = "CMOS PWDN";
++ };
++ cmos_rst {
++ gpio-hog;
++ gpios = <9 GPIO_ACTIVE_HIGH>;
++ output-high;
++ line-name = "CMOS RST";
++ };
++ /* pin 12 - CAM_CLK */
++ rpi_cam_io_1 {
++ gpio-hog;
++ gpios = <10 GPIO_ACTIVE_HIGH>;
++ output-high;
++ line-name = "RaspB_IO1";
++ };
++ /* pin 11 - CAM_GPIO - assume pwdn */
++ rpi_cam_io_0 {
++ gpio-hog;
++ gpios = <11 GPIO_ACTIVE_HIGH>;
++ output-high;
++ line-name = "RaspB_IO0";
++ };
++ sam_rst {
++ gpio-hog;
++ gpios = <4 GPIO_ACTIVE_HIGH>;
++ output-high;
++ line-name = "SAM RST";
++ };
++ sam_pwr {
++ gpio-hog;
++ gpios = <5 GPIO_ACTIVE_HIGH>;
++ output-low;
++ line-name = "SAM PWR";
++ };
++ /* 0 - FPDLink output, 1 - LVDS output */
++ lvds_vs_fpdl {
++ gpio-hog;
++ gpios = <14 GPIO_ACTIVE_HIGH>;
++ output-high;
++ line-name = "LVDS switch";
++ };
+ };
+
+ gpio_exp_77: gpio@77 {
+@@ -120,6 +683,31 @@
+ interrupt-controller;
+ interrupt-parent = <&gpio5>;
+ interrupts = <9 IRQ_TYPE_EDGE_FALLING>;
++
++ mpcie_wake {
++ gpio-hog;
++ gpios = <0 GPIO_ACTIVE_HIGH>;
++ output-low;
++ line-name = "mPCIe WAKE#";
++ };
++ mpcie_wdisable {
++ gpio-hog;
++ gpios = <1 GPIO_ACTIVE_HIGH>;
++ output-high;
++ line-name = "mPCIe W_DISABLE";
++ };
++ mpcie_clreq {
++ gpio-hog;
++ gpios = <2 GPIO_ACTIVE_HIGH>;
++ input;
++ line-name = "mPCIe CLKREQ#";
++ };
++ mpcie_ovc {
++ gpio-hog;
++ gpios = <3 GPIO_ACTIVE_HIGH>;
++ input;
++ line-name = "mPCIe OVC";
++ };
+ };
+
+ i2cswitch4: i2c-switch@71 {
+@@ -128,9 +716,359 @@
+ #size-cells = <0>;
+ reg = <0x71>;
+ reset-gpios = <&gpio3 15 GPIO_ACTIVE_LOW>;
++
++ i2c@0 {
++ #address-cells = <1>;
++ #size-cells = <0>;
++ reg = <0>;
++ /* SAM node(s) */
++ };
++
++ i2c@1 {
++ #address-cells = <1>;
++ #size-cells = <0>;
++ reg = <1>;
++ /* Slot A (CN10) */
++
++ ov106xx@0 {
++ compatible = "ovti,ov106xx";
++ reg = <0x60>;
++
++ port@0 {
++ ov106xx_in0: endpoint {
++ clock-lanes = <0>;
++ data-lanes = <1 2 3 4>;
++ remote-endpoint = <&vin0ep0>;
++ };
++ };
++ port@1 {
++ ov106xx_max9286_des0ep0: endpoint@0 {
++ remote-endpoint = <&max9286_des0ep0>;
++ };
++ ov106xx_ti9x4_des0ep0: endpoint@1 {
++ remote-endpoint = <&ti9x4_des0ep0>;
++ };
++ };
++ };
++
++ ov106xx@1 {
++ compatible = "ovti,ov106xx";
++ reg = <0x61>;
++
++ port@0 {
++ ov106xx_in1: endpoint {
++ clock-lanes = <0>;
++ data-lanes = <1 2 3 4>;
++ remote-endpoint = <&vin1ep0>;
++ };
++ };
++ port@1 {
++ ov106xx_max9286_des0ep1: endpoint@0 {
++ remote-endpoint = <&max9286_des0ep1>;
++ };
++ ov106xx_ti9x4_des0ep1: endpoint@1 {
++ remote-endpoint = <&ti9x4_des0ep1>;
++ };
++ };
++ };
++
++ ov106xx@2 {
++ compatible = "ovti,ov106xx";
++ reg = <0x62>;
++
++ port@0 {
++ ov106xx_in2: endpoint {
++ clock-lanes = <0>;
++ data-lanes = <1 2 3 4>;
++ remote-endpoint = <&vin2ep0>;
++ };
++ };
++ port@1 {
++ ov106xx_max9286_des0ep2: endpoint@0 {
++ remote-endpoint = <&max9286_des0ep2>;
++ };
++ ov106xx_ti9x4_des0ep2: endpoint@1 {
++ remote-endpoint = <&ti9x4_des0ep2>;
++ };
++ };
++ };
++
++ ov106xx@3 {
++ compatible = "ovti,ov106xx";
++ reg = <0x63>;
++
++ port@0 {
++ ov106xx_in3: endpoint {
++ clock-lanes = <0>;
++ data-lanes = <1 2 3 4>;
++ remote-endpoint = <&vin3ep0>;
++ };
++ };
++ port@1 {
++ ov106xx_max9286_des0ep3: endpoint@0 {
++ remote-endpoint = <&max9286_des0ep3>;
++ };
++ ov106xx_ti9x4_des0ep3: endpoint@1 {
++ remote-endpoint = <&ti9x4_des0ep3>;
++ };
++ };
++ };
++
++ /* DS90UB9x4 @ 0x3a */
++ ti9x4@0 {
++ compatible = "ti,ti9x4";
++ reg = <0x3a>;
++ ti,links = <4>;
++ ti,lanes = <4>;
++ ti,forwarding-mode = "round-robin";
++ ti,cable-mode = "coax";
++
++ POC0-gpios = <&gpio_exp_a_5c 8 GPIO_ACTIVE_HIGH>;
++ POC1-gpios = <&gpio_exp_a_5c 9 GPIO_ACTIVE_HIGH>;
++ POC2-gpios = <&gpio_exp_a_5c 10 GPIO_ACTIVE_HIGH>;
++ POC3-gpios = <&gpio_exp_a_5c 11 GPIO_ACTIVE_HIGH>;
++
++ port@0 {
++ ti9x4_des0ep0: endpoint@0 {
++ ti9x3-addr = <0x0c>;
++ dvp-order = <0>;
++ remote-endpoint = <&ov106xx_in0>;
++ };
++ ti9x4_des0ep1: endpoint@1 {
++ ti9x3-addr = <0x0d>;
++ dvp-order = <0>;
++ remote-endpoint = <&ov106xx_in1>;
++ };
++ ti9x4_des0ep2: endpoint@2 {
++ ti9x3-addr = <0x0e>;
++ dvp-order = <0>;
++ remote-endpoint = <&ov106xx_in2>;
++ };
++ ti9x4_des0ep3: endpoint@3 {
++ ti9x3-addr = <0x0f>;
++ dvp-order = <0>;
++ remote-endpoint = <&ov106xx_in3>;
++ };
++ };
++ port@1 {
++ ti9x4_csi0ep0: endpoint {
++ csi-rate = <1450>;
++ remote-endpoint = <&csi40_ep>;
++ };
++ };
++ };
++
++ /* MAX9286 @ 0x2c */
++ max9286@0 {
++ compatible = "maxim,max9286";
++ reg = <0x2c>;
++ maxim,links = <4>;
++ maxim,lanes = <4>;
++ maxim,resetb-gpio = <1>;
++ maxim,fsync-mode = "automatic";
++ maxim,timeout = <100>;
++
++ POC0-gpios = <&gpio_exp_a_5c 9 GPIO_ACTIVE_HIGH>;
++ POC1-gpios = <&gpio_exp_a_5c 8 GPIO_ACTIVE_HIGH>;
++ POC2-gpios = <&gpio_exp_a_5c 11 GPIO_ACTIVE_HIGH>;
++ POC3-gpios = <&gpio_exp_a_5c 10 GPIO_ACTIVE_HIGH>;
++
++ port@0 {
++ max9286_des0ep0: endpoint@0 {
++ max9271-addr = <0x50>;
++ dvp-order = <1>;
++ remote-endpoint = <&ov106xx_in0>;
++ };
++ max9286_des0ep1: endpoint@1 {
++ max9271-addr = <0x51>;
++ dvp-order = <1>;
++ remote-endpoint = <&ov106xx_in1>;
++ };
++ max9286_des0ep2: endpoint@2 {
++ max9271-addr = <0x52>;
++ dvp-order = <1>;
++ remote-endpoint = <&ov106xx_in2>;
++ };
++ max9286_des0ep3: endpoint@3 {
++ max9271-addr = <0x53>;
++ dvp-order = <1>;
++ remote-endpoint = <&ov106xx_in3>;
++ };
++ };
++ port@1 {
++ max9286_csi0ep0: endpoint {
++ csi-rate = <700>;
++ remote-endpoint = <&csi40_ep>;
++ };
++ };
++ };
++ };
++
++ i2c@3 {
++ #address-cells = <1>;
++ #size-cells = <0>;
++ reg = <3>;
++ /* MOST node(s) */
++ };
++
++ i2c@4 {
++ #address-cells = <1>;
++ #size-cells = <0>;
++ reg = <4>;
++
++ rpi_camera: ov5647@36 {
++ compatible = "ovti,ov5647";
++ reg = <0x36>;
++
++ port@0 {
++ rpi_camera_in: endpoint {
++ clock-lanes = <0>;
++ data-lanes = <1 2>;
++ remote-endpoint = <&vin4ep0>;
++ };
++ };
++ };
++ };
++
++ i2c@5 {
++ #address-cells = <1>;
++ #size-cells = <0>;
++ reg = <5>;
++
++ cmos_camera: ov5642@3c {
++ compatible = "ovti,ov5642";
++ reg = <0x3c>;
++ clocks = <&camera_clk>;
++ clock-names = "mclk";
++
++ port@0 {
++ cmos_camera_in: endpoint {
++ remote-endpoint = <&vin5ep0>;
++ };
++ };
++ };
++ };
++
++ i2c@7 {
++ #address-cells = <1>;
++ #size-cells = <0>;
++ reg = <7>;
++ /* Slot A (CN10) */
++
++ /* PCA9535 is a redundant/deprecated card */
++ gpio_exp_a_26: gpio@26 {
++ compatible = "nxp,pca9535";
++ reg = <0x26>;
++ gpio-controller;
++ #gpio-cells = <2>;
++
++ video_a_des_cfg1 {
++ gpio-hog;
++ gpios = <5 GPIO_ACTIVE_HIGH>;
++ input;
++ line-name = "Video-A cfg1";
++ };
++ video_a_des_cfg0 {
++ gpio-hog;
++ gpios = <6 GPIO_ACTIVE_HIGH>;
++ input;
++ line-name = "Video-A cfg0";
++ };
++ video_a_pwr_shdn {
++ gpio-hog;
++ gpios = <3 GPIO_ACTIVE_HIGH>;
++ output-high;
++ line-name = "Video-A PWR_SHDN";
++ };
++ video_a_cam_pwr0 {
++ gpio-hog;
++ gpios = <12 GPIO_ACTIVE_HIGH>;
++ output-high;
++ line-name = "Video-A PWR0";
++ };
++ video_a_cam_pwr1 {
++ gpio-hog;
++ gpios = <13 GPIO_ACTIVE_HIGH>;
++ output-high;
++ line-name = "Video-A PWR1";
++ };
++ video_a_cam_pwr2 {
++ gpio-hog;
++ gpios = <14 GPIO_ACTIVE_HIGH>;
++ output-high;
++ line-name = "Video-A PWR2";
++ };
++ video_a_cam_pwr3 {
++ gpio-hog;
++ gpios = <15 GPIO_ACTIVE_HIGH>;
++ output-high;
++ line-name = "Video-A PWR3";
++ };
++ video_a_des_shdn {
++ gpio-hog;
++ gpios = <4 GPIO_ACTIVE_HIGH>;
++ output-high;
++ line-name = "Video-A DES_SHDN";
++ };
++ video_a_des_led {
++ gpio-hog;
++ gpios = <7 GPIO_ACTIVE_HIGH>;
++ output-low;
++ line-name = "Video-A led";
++ };
++ };
++
++ gpio_exp_a_5c: gpio@5c {
++ compatible = "maxim,max7325";
++ reg = <0x5c>;
++ gpio-controller;
++ #gpio-cells = <2>;
++
++ video_a_des_cfg2 {
++ gpio-hog;
++ gpios = <4 GPIO_ACTIVE_HIGH>;
++ input;
++ line-name = "Video-A cfg2";
++ };
++ video_a_des_cfg1 {
++ gpio-hog;
++ gpios = <6 GPIO_ACTIVE_HIGH>;
++ input;
++ line-name = "Video-A cfg1";
++ };
++ video_a_des_cfg0 {
++ gpio-hog;
++ gpios = <7 GPIO_ACTIVE_HIGH>;
++ input;
++ line-name = "Video-A cfg0";
++ };
++ video_a_pwr_shdn {
++ gpio-hog;
++ gpios = <14 GPIO_ACTIVE_HIGH>;
++ output-high;
++ line-name = "Video-A PWR_SHDN";
++ };
++ video_a_des_shdn {
++ gpio-hog;
++ gpios = <13 GPIO_ACTIVE_HIGH>;
++ output-high;
++ line-name = "Video-A DES_SHDN";
++ };
++ video_a_led {
++ gpio-hog;
++ gpios = <12 GPIO_ACTIVE_HIGH>;
++ output-low;
++ line-name = "Video-A LED";
++ };
++ };
++ };
+ };
+ };
+
++&msiof1 {
++ status = "disabled";
++};
++
+ &ohci0 {
+ dr_mode = "otg";
+ status = "okay";
+@@ -138,6 +1076,7 @@
+
+ &pcie_bus_clk {
+ clock-frequency = <100000000>;
++ status = "okay";
+ };
+
+ &pciec0 {
+@@ -146,6 +1085,9 @@
+
+ &pciec1 {
+ status = "okay";
++
++ pcie3v3-supply = <&mpcie_3v3>;
++ pcie1v8-supply = <&mpcie_1v8>;
+ };
+
+ &pfc {
+@@ -159,30 +1101,183 @@
+ function = "can1";
+ };
+
++ canfd0_pins: canfd0 {
++ groups = "canfd0_data_a";
++ function = "canfd0";
++ };
++
++ canfd1_pins: canfd1 {
++ groups = "canfd1_data";
++ function = "canfd1";
++ };
++
++ du_pins: du {
++ groups = "du_rgb888", "du_sync", "du_clk_out_0", "du_disp";
++ function = "du";
++ };
++
+ hscif0_pins: hscif0 {
+ groups = "hscif0_data", "hscif0_ctrl";
+ function = "hscif0";
+ };
+
++ hscif1_pins: hscif1 {
++ groups = "hscif1_data_a", "hscif1_ctrl_a";
++ function = "hscif1";
++ };
++
+ scif1_pins: scif1 {
+- groups = "scif1_data_b", "scif1_ctrl";
++ groups = "scif1_data_b";
+ function = "scif1";
+ };
+
++ sdhi3_pins_3v3: sd3_3v3 {
++ groups = "sdhi3_data4", "sdhi3_ctrl";
++ function = "sdhi3";
++ power-source = <3300>;
++ };
++
++ sdhi3_pins_1v8: sd3_1v8 {
++ groups = "sdhi3_data4", "sdhi3_ctrl";
++ function = "sdhi3";
++ power-source = <1800>;
++ };
++
++ sound_0_pins: sound0 {
++ groups = "ssi349_ctrl", "ssi3_data", "ssi4_data";
++ function = "ssi";
++ };
++
++ /* sound_pins defined in H3 or M3 ulsb file */
++
++ sound_2_pins: sound2 {
++ groups = "ssi6_ctrl", "ssi6_data";
++ function = "ssi";
++ };
++
++ sound_3_pins: sound3 {
++ groups = "ssi78_ctrl", "ssi7_data", "ssi8_data";
++ function = "ssi";
++ };
++
+ usb0_pins: usb0 {
+ groups = "usb0";
+ function = "usb0";
+ };
++
++ vin5_pins: vin5 {
++ groups = "vin5_data8", "vin5_sync", "vin5_clk";
++ function = "vin5";
++ };
++};
++
++&rcar_sound {
++ pinctrl-0 = <&sound_clk_pins>;
++ pinctrl-names = "default";
++
++ /* Multi DAI */
++ #sound-dai-cells = <1>;
++
++ ports {
++ #address-cells = <1>;
++ #size-cells = <0>;
++ rsnd_port0: port@0 {
++ reg = <0>;
++ rsnd_endpoint0: endpoint {
++ remote-endpoint = <&pcm3168a_endpoint>;
++
++ dai-format = "left_j";
++ bitclock-master = <&pcm3168a_endpoint>;
++ frame-master = <&pcm3168a_endpoint>;
++ dai-tdm-slot-num = <8>;
++ dai-tdm-slot-width = <32>;
++
++ playback = <&ssi3>;
++ capture = <&ssi4>;
++ };
++ };
++ rsnd_port1: port@1 {
++ reg = <1>;
++ rsnd_endpoint1: endpoint {
++ remote-endpoint = <&ak4613_endpoint>;
++
++ dai-format = "left_j";
++ bitclock-master = <&rsnd_endpoint1>;
++ frame-master = <&rsnd_endpoint1>;
++
++ playback = <&ssi0 &src0 &dvc0>;
++ capture = <&ssi1 &src1 &dvc1>;
++ };
++ };
++ rsnd_port2: port@2 {
++ reg = <2>;
++ rsnd_endpoint2: endpoint {
++ remote-endpoint = <&radio_endpoint>;
++
++ dai-format = "i2s";
++ bitclock-master = <&radio_endpoint>;
++ frame-master = <&radio_endpoint>;
++
++ capture = <&ssi6>;
++ };
++ };
++ rsnd_port3: port@3 {
++ reg = <3>;
++ rsnd_endpoint3: enpoint {
++ remote-endpoint = <&wl18xx_pcm_endpoint>;
++
++ simple-audio-card,format = "i2s";
++ bitclock-master = <&wl18xx_pcm_endpoint>;
++ frame-master = <&wl18xx_pcm_endpoint>;
++
++ playback = <&ssi7>;
++ capture = <&ssi8>;
++ };
++ };
++ };
+ };
+
+ &scif1 {
+ pinctrl-0 = <&scif1_pins>;
+ pinctrl-names = "default";
+- uart-has-rtscts;
+
+ status = "okay";
+ };
+
++&sdhi3 {
++ pinctrl-0 = <&sdhi3_pins_3v3>;
++ pinctrl-1 = <&sdhi3_pins_1v8>;
++ pinctrl-names = "default", "state_uhs";
++
++ vmmc-supply = <&wlan_en>;
++ vqmmc-supply = <&vccq_sdhi3>;
++ keep-power-in-suspend;
++ enable-sdio-wakeup;
++ bus-width = <4>;
++ no-1-8-v;
++ non-removable;
++ cap-power-off-card;
++ max-frequency = <26000000>;
++ status = "okay";
++
++ #address-cells = <1>;
++ #size-cells = <0>;
++ wlcore: wlcore@2 {
++ compatible = "ti,wl1837";
++ reg = <2>;
++ interrupt-parent = <&gpio1>;
++ interrupts = <25 IRQ_TYPE_EDGE_FALLING>;
++ };
++};
++
++&ssi4 {
++ shared-pin;
++};
++
++&ssi8 {
++ shared-pin;
++};
++
+ &usb2_phy0 {
+ pinctrl-0 = <&usb0_pins>;
+ pinctrl-names = "default";
+@@ -190,6 +1285,177 @@
+ status = "okay";
+ };
+
++&vin0 {
++ status = "okay";
++
++ ports {
++ #address-cells = <1>;
++ #size-cells = <0>;
++
++ port@0 {
++ vin0ep0: endpoint {
++ csi,select = "csi40";
++ virtual,channel = <0>;
++ data-lanes = <1 2 3 4>;
++ remote-endpoint = <&ov106xx_in0>;
++ };
++ };
++ port@1 {
++ csi0ep0: endpoint {
++ remote-endpoint = <&csi40_ep>;
++ };
++ };
++ port@2 {
++ vin0_max9286_des0ep0: endpoint@0 {
++ remote-endpoint = <&max9286_des0ep0>;
++ };
++ vin0_ti9x4_des0ep0: endpoint@1 {
++ remote-endpoint = <&ti9x4_des0ep0>;
++ };
++ };
++ };
++};
++
++&vin1 {
++ status = "okay";
++
++ ports {
++ #address-cells = <1>;
++ #size-cells = <0>;
++
++ port@0 {
++ vin1ep0: endpoint {
++ csi,select = "csi40";
++ virtual,channel = <1>;
++ data-lanes = <1 2 3 4>;
++ remote-endpoint = <&ov106xx_in1>;
++ };
++ };
++ port@1 {
++ csi0ep1: endpoint {
++ remote-endpoint = <&csi40_ep>;
++ };
++ };
++ port@2 {
++ vin1_max9286_des0ep1: endpoint@0 {
++ remote-endpoint = <&max9286_des0ep1>;
++ };
++ vin1_ti9x4_des0ep1: endpoint@1 {
++ remote-endpoint = <&ti9x4_des0ep1>;
++ };
++ };
++ };
++};
++
++&vin2 {
++ status = "okay";
++
++ ports {
++ #address-cells = <1>;
++ #size-cells = <0>;
++
++ port@0 {
++ vin2ep0: endpoint {
++ csi,select = "csi40";
++ virtual,channel = <2>;
++ data-lanes = <1 2 3 4>;
++ remote-endpoint = <&ov106xx_in2>;
++ };
++ };
++ port@1 {
++ csi0ep2: endpoint {
++ remote-endpoint = <&csi40_ep>;
++ };
++ };
++ port@2 {
++ vin2_max9286_des0ep2: endpoint@0 {
++ remote-endpoint = <&max9286_des0ep2>;
++ };
++ vin2_ti9x4_des0ep2: endpoint@1 {
++ remote-endpoint = <&ti9x4_des0ep2>;
++ };
++ };
++ };
++};
++
++&vin3 {
++ status = "okay";
++
++ ports {
++ #address-cells = <1>;
++ #size-cells = <0>;
++
++ port@0 {
++ vin3ep0: endpoint {
++ csi,select = "csi40";
++ virtual,channel = <3>;
++ data-lanes = <1 2 3 4>;
++ remote-endpoint = <&ov106xx_in3>;
++ };
++ };
++ port@1 {
++ csi0ep3: endpoint {
++ remote-endpoint = <&csi40_ep>;
++ };
++ };
++ port@2 {
++ vin3_max9286_des0ep3: endpoint@0 {
++ remote-endpoint = <&max9286_des0ep3>;
++ };
++ vin3_ti9x4_des0ep3: endpoint@1 {
++ remote-endpoint = <&ti9x4_des0ep3>;
++ };
++ };
++ };
++};
++
++&vin4 {
++ status = "okay";
++
++ ports {
++ #address-cells = <1>;
++ #size-cells = <0>;
++
++ port@0 {
++ vin4ep0: endpoint {
++ csi,select = "csi20";
++ virtual,channel = <0>;
++ remote-endpoint = <&rpi_camera_in>;
++ data-lanes = <1 2>;
++ };
++ };
++ port@1 {
++ csi2ep0: endpoint {
++ remote-endpoint = <&csi20_ep>;
++ };
++ };
++ };
++};
++
++&vin5 {
++ pinctrl-0 = <&vin5_pins>;
++ pinctrl-names = "default";
++ status = "okay";
++
++ ports {
++ #address-cells = <1>;
++ #size-cells = <0>;
++
++ port@0 {
++ vin5ep0: endpoint@0 {
++ bus-width = <8>;
++ /* #HSYNC, #VSYNC */
++ vsync-active = <1>;
++ hsync-active = <0>;
++ remote-endpoint = <&cmos_camera_in>;
++ };
++ };
++ };
++};
++
+ &xhci0 {
+ status = "okay";
+ };
++
++
++
+diff --git a/arch/arm64/boot/dts/renesas/ulcb-vb-cn12.dtsi b/arch/arm64/boot/dts/renesas/ulcb-vb-cn12.dtsi
+new file mode 100644
+index 0000000..abf4669
+--- /dev/null
++++ b/arch/arm64/boot/dts/renesas/ulcb-vb-cn12.dtsi
+@@ -0,0 +1,459 @@
++/*
++ * Device Tree Source for the H3ULCB Videobox board:
++ * this adding conflicting resource on VIN4/VIN5/VIN6/VIN7 for CN12
++ *
++ * Copyright (C) 2017 Renesas Electronics Corp.
++ * Copyright (C) 2017 Cogent Embedded, Inc.
++ *
++ * This file is licensed under the terms of the GNU General Public License
++ * version 2. This program is licensed "as is" without any warranty of any
++ * kind, whether express or implied.
++ */
++
++&i2cswitch2 {
++ i2c@3 {
++ #address-cells = <1>;
++ #size-cells = <0>;
++ reg = <3>;
++ /* Slot C (CN12) */
++
++ ov106xx@8 {
++ compatible = "ovti,ov106xx";
++ reg = <0x68>;
++
++ port@0 {
++ ov106xx_in8: endpoint {
++ clock-lanes = <0>;
++ data-lanes = <1 2>;
++ remote-endpoint = <&vin4ep0>;
++ };
++ };
++ port@1 {
++ ov106xx_max9286_des2ep0: endpoint@0 {
++ remote-endpoint = <&max9286_des2ep0>;
++ };
++ ov106xx_ti9x4_des2ep0: endpoint@1 {
++ remote-endpoint = <&ti9x4_des2ep0>;
++ };
++ };
++ };
++
++ ov106xx@9 {
++ compatible = "ovti,ov106xx";
++ reg = <0x69>;
++
++ port@0 {
++ ov106xx_in9: endpoint {
++ clock-lanes = <0>;
++ data-lanes = <1 2>;
++ remote-endpoint = <&vin5ep0>;
++ };
++ };
++ port@1 {
++ ov106xx_max9286_des2ep1: endpoint@0 {
++ remote-endpoint = <&max9286_des2ep1>;
++ };
++ ov106xx_ti9x4_des2ep1: endpoint@1 {
++ remote-endpoint = <&ti9x4_des2ep1>;
++ };
++ };
++ };
++
++ ov106xx@10 {
++ compatible = "ovti,ov106xx";
++ reg = <0x6a>;
++
++ port@0 {
++ ov106xx_in10: endpoint {
++ clock-lanes = <0>;
++ data-lanes = <1 2>;
++ remote-endpoint = <&vin6ep0>;
++ };
++ };
++ port@1 {
++ ov106xx_max9286_des2ep2: endpoint@0 {
++ remote-endpoint = <&max9286_des2ep2>;
++ };
++ ov106xx_ti9x4_des2ep2: endpoint@1 {
++ remote-endpoint = <&ti9x4_des2ep2>;
++ };
++ };
++ };
++
++ ov106xx@11 {
++ compatible = "ovti,ov106xx";
++ reg = <0x6b>;
++
++ port@0 {
++ ov106xx_in11: endpoint {
++ clock-lanes = <0>;
++ data-lanes = <1 2>;
++ remote-endpoint = <&vin7ep0>;
++ };
++ };
++ port@1 {
++ ov106xx_max9286_des2ep3: endpoint@0 {
++ remote-endpoint = <&max9286_des2ep3>;
++ };
++ ov106xx_ti9x4_des2ep3: endpoint@1 {
++ remote-endpoint = <&ti9x4_des2ep3>;
++ };
++ };
++ };
++
++ /* DS90UB9x4 @ 0x3a */
++ ti9x4@2 {
++ compatible = "ti,ti9x4";
++ reg = <0x3a>;
++ ti,sensor_delay = <350>;
++ ti,links = <4>;
++ ti,lanes = <2>;
++ ti,forwarding-mode = "round-robin";
++ ti,cable-mode = "coax";
++
++ POC0-gpios = <&gpio_exp_c_5c 8 GPIO_ACTIVE_HIGH>;
++ POC1-gpios = <&gpio_exp_c_5c 9 GPIO_ACTIVE_HIGH>;
++ POC2-gpios = <&gpio_exp_c_5c 10 GPIO_ACTIVE_HIGH>;
++ POC3-gpios = <&gpio_exp_c_5c 11 GPIO_ACTIVE_HIGH>;
++
++ port@0 {
++ ti9x4_des2ep0: endpoint@0 {
++ ti9x3-addr = <0x0c>;
++ dvp-order = <0>;
++ remote-endpoint = <&ov106xx_in8>;
++ };
++ ti9x4_des2ep1: endpoint@1 {
++ ti9x3-addr = <0x0d>;
++ dvp-order = <0>;
++ remote-endpoint = <&ov106xx_in9>;
++ };
++ ti9x4_des2ep2: endpoint@2 {
++ ti9x3-addr = <0x0e>;
++ dvp-order = <0>;
++ remote-endpoint = <&ov106xx_in10>;
++ };
++ ti9x4_des2ep3: endpoint@3 {
++ ti9x3-addr = <0x0f>;
++ dvp-order = <0>;
++ remote-endpoint = <&ov106xx_in11>;
++ };
++ };
++ port@1 {
++ ti9x4_csi1ep0: endpoint {
++ csi-rate = <1450>;
++ remote-endpoint = <&csi20_ep>;
++ };
++ };
++ };
++
++ /* MAX9286 @ 0x2c */
++ max9286@2 {
++ compatible = "maxim,max9286";
++ reg = <0x2c>;
++ maxim,sensor_delay = <350>;
++ maxim,links = <4>;
++ maxim,lanes = <2>;
++ maxim,resetb-gpio = <1>;
++ maxim,fsync-mode = "automatic";
++ maxim,timeout = <100>;
++
++ POC0-gpios = <&gpio_exp_c_5c 9 GPIO_ACTIVE_HIGH>;
++ POC1-gpios = <&gpio_exp_c_5c 8 GPIO_ACTIVE_HIGH>;
++ POC2-gpios = <&gpio_exp_c_5c 11 GPIO_ACTIVE_HIGH>;
++ POC3-gpios = <&gpio_exp_c_5c 10 GPIO_ACTIVE_HIGH>;
++
++ port@0 {
++ max9286_des2ep0: endpoint@0 {
++ max9271-addr = <0x50>;
++ dvp-order = <1>;
++ remote-endpoint = <&ov106xx_in8>;
++ };
++ max9286_des2ep1: endpoint@1 {
++ max9271-addr = <0x51>;
++ dvp-order = <1>;
++ remote-endpoint = <&ov106xx_in9>;
++ };
++ max9286_des2ep2: endpoint@2 {
++ max9271-addr = <0x52>;
++ dvp-order = <1>;
++ remote-endpoint = <&ov106xx_in10>;
++ };
++ max9286_des2ep3: endpoint@3 {
++ max9271-addr = <0x53>;
++ dvp-order = <1>;
++ remote-endpoint = <&ov106xx_in11>;
++ };
++ };
++ port@1 {
++ max9286_csi1ep0: endpoint {
++ csi-rate = <700>;
++ remote-endpoint = <&csi20_ep>;
++ };
++ };
++ };
++ };
++
++ i2c@4 {
++ #address-cells = <1>;
++ #size-cells = <0>;
++ reg = <4>;
++ /* Slot C (CN12) */
++
++ /* PCA9535 is a redundand/deprecated card */
++ gpio_exp_c_27: gpio@27 {
++ compatible = "nxp,pca9535";
++ reg = <0x26>;
++ gpio-controller;
++ #gpio-cells = <2>;
++
++ video_c_des_cfg1 {
++ gpio-hog;
++ gpios = <5 GPIO_ACTIVE_HIGH>;
++ input;
++ line-name = "Video-C cfg1";
++ };
++ video_c_des_cfg0 {
++ gpio-hog;
++ gpios = <6 GPIO_ACTIVE_HIGH>;
++ input;
++ line-name = "Video-C cfg0";
++ };
++ video_c_pwr_shdn {
++ gpio-hog;
++ gpios = <3 GPIO_ACTIVE_HIGH>;
++ output-high;
++ line-name = "Video-C PWR_SHDN";
++ };
++ video_c_cam_pwr0 {
++ gpio-hog;
++ gpios = <12 GPIO_ACTIVE_HIGH>;
++ output-high;
++ line-name = "Video-C PWR0";
++ };
++ video_c_cam_pwr1 {
++ gpio-hog;
++ gpios = <13 GPIO_ACTIVE_HIGH>;
++ output-high;
++ line-name = "Video-C PWR1";
++ };
++ video_c_cam_pwr2 {
++ gpio-hog;
++ gpios = <14 GPIO_ACTIVE_HIGH>;
++ output-high;
++ line-name = "Video-C PWR2";
++ };
++ video_c_cam_pwr3 {
++ gpio-hog;
++ gpios = <15 GPIO_ACTIVE_HIGH>;
++ output-high;
++ line-name = "Video-C PWR3";
++ };
++ video_c_des_shdn {
++ gpio-hog;
++ gpios = <4 GPIO_ACTIVE_HIGH>;
++ output-high;
++ line-name = "Video-C DES_SHDN";
++ };
++ video_c_des_led {
++ gpio-hog;
++ gpios = <7 GPIO_ACTIVE_HIGH>;
++ output-low;
++ line-name = "Video-C led";
++ };
++ };
++
++ gpio_exp_c_5c: gpio@5c {
++ compatible = "maxim,max7325";
++ reg = <0x5c>;
++ gpio-controller;
++ #gpio-cells = <2>;
++
++ video_c_des_cfg2 {
++ gpio-hog;
++ gpios = <4 GPIO_ACTIVE_HIGH>;
++ input;
++ line-name = "Video-C cfg2";
++ };
++ video_c_des_cfg1 {
++ gpio-hog;
++ gpios = <6 GPIO_ACTIVE_HIGH>;
++ input;
++ line-name = "Video-C cfg1";
++ };
++ video_c_des_cfg0 {
++ gpio-hog;
++ gpios = <7 GPIO_ACTIVE_HIGH>;
++ input;
++ line-name = "Video-C cfg0";
++ };
++ video_c_pwr_shdn {
++ gpio-hog;
++ gpios = <14 GPIO_ACTIVE_HIGH>;
++ output-high;
++ line-name = "Video-C PWR_SHDN";
++ };
++ video_c_des_shdn {
++ gpio-hog;
++ gpios = <13 GPIO_ACTIVE_HIGH>;
++ output-high;
++ line-name = "Video-C DES_SHDN";
++ };
++ video_c_led {
++ gpio-hog;
++ gpios = <12 GPIO_ACTIVE_HIGH>;
++ output-low;
++ line-name = "Video-C LED";
++ };
++ };
++ };
++};
++
++&vin4 {
++ ports {
++ #address-cells = <1>;
++ #size-cells = <0>;
++
++ port@0 {
++ vin4ep0: endpoint {
++ csi,select = "csi20";
++ virtual,channel = <0>;
++ remote-endpoint = <&ov106xx_in8>;
++ data-lanes = <1 2>;
++ };
++ };
++ port@1 {
++ csi2ep0: endpoint {
++ remote-endpoint = <&csi20_ep>;
++ };
++ };
++ port@2 {
++ vin4_max9286_des2ep0: endpoint@0 {
++ remote-endpoint = <&max9286_des2ep0>;
++ };
++ vin4_ti9x4_des2ep0: endpoint@1 {
++ remote-endpoint = <&ti9x4_des2ep0>;
++ };
++ };
++ };
++};
++
++&vin5 {
++ ports {
++ #address-cells = <1>;
++ #size-cells = <0>;
++
++ port@0 {
++ vin5ep0: endpoint@0 {
++ csi,select = "csi20";
++ virtual,channel = <1>;
++ remote-endpoint = <&ov106xx_in9>;
++ data-lanes = <1 2>;
++ };
++ };
++ port@1 {
++ csi2ep1: endpoint {
++ remote-endpoint = <&csi20_ep>;
++ };
++ };
++ port@2 {
++ vin5_max9286_des2ep1: endpoint@0 {
++ remote-endpoint = <&max9286_des2ep1>;
++ };
++ vin5_ti9x4_des2ep1: endpoint@1 {
++ remote-endpoint = <&ti9x4_des2ep1>;
++ };
++ };
++ };
++};
++
++&vin6 {
++ ports {
++ #address-cells = <1>;
++ #size-cells = <0>;
++
++ port@0 {
++ vin6ep0: endpoint@0 {
++ csi,select = "csi20";
++ virtual,channel = <2>;
++ remote-endpoint = <&ov106xx_in10>;
++ data-lanes = <1 2>;
++ };
++ };
++ port@1 {
++ csi2ep2: endpoint {
++ remote-endpoint = <&csi20_ep>;
++ };
++ };
++ port@2 {
++ vin6_max9286_des2ep2: endpoint@0 {
++ remote-endpoint = <&max9286_des2ep2>;
++ };
++ vin6_ti9x4_des2ep2: endpoint@1 {
++ remote-endpoint = <&ti9x4_des2ep2>;
++ };
++ };
++ };
++};
++
++&vin7 {
++ ports {
++ #address-cells = <1>;
++ #size-cells = <0>;
++
++ port@0 {
++ vin7ep0: endpoint@0 {
++ csi,select = "csi20";
++ virtual,channel = <3>;
++ remote-endpoint = <&ov106xx_in11>;
++ data-lanes = <1 2>;
++ };
++ };
++ port@1 {
++ csi2ep3: endpoint {
++ remote-endpoint = <&csi20_ep>;
++ };
++ };
++ port@2 {
++ vin7_max9286_des2ep3: endpoint@0 {
++ remote-endpoint = <&max9286_des2ep3>;
++ };
++ vin7_ti9x4_des2ep3: endpoint@1 {
++ remote-endpoint = <&ti9x4_des2ep3>;
++ };
++ };
++ };
++};
++
++&csi20 {
++ status = "okay";
++
++ virtual,channel {
++ csi2_vc0 {
++ data,type = "ycbcr422";
++ receive,vc = <0>;
++ };
++ csi2_vc1 {
++ data,type = "ycbcr422";
++ receive,vc = <1>;
++ };
++ csi2_vc2 {
++ data,type = "ycbcr422";
++ receive,vc = <2>;
++ };
++ csi2_vc3 {
++ data,type = "ycbcr422";
++ receive,vc = <3>;
++ };
++ };
++
++ port {
++ #address-cells = <1>;
++ #size-cells = <0>;
++
++ csi20_ep: endpoint {
++ clock-lanes = <0>;
++ data-lanes = <1 2>;
++ csi-rate = <300>;
++ };
++ };
++};
+diff --git a/arch/arm64/boot/dts/renesas/ulcb-vb.dtsi b/arch/arm64/boot/dts/renesas/ulcb-vb.dtsi
+new file mode 100644
+index 0000000..67903db
+--- /dev/null
++++ b/arch/arm64/boot/dts/renesas/ulcb-vb.dtsi
+@@ -0,0 +1,1591 @@
++/*
++ * Device Tree Source for the ULCB Videobox board
++ *
++ * Copyright (C) 2017 Cogent Embedded, Inc.
++ *
++ * This file is licensed under the terms of the GNU General Public License
++ * version 2. This program is licensed "as is" without any warranty of any
++ * kind, whether express or implied.
++ */
++
++/ {
++ leds {
++ compatible = "gpio-leds";
++
++ led5 {
++ gpios = <&gpio6 12 GPIO_ACTIVE_HIGH>;
++ };
++ led6 {
++ gpios = <&gpio6 13 GPIO_ACTIVE_HIGH>;
++ };
++ /* D13 - status 0 */
++ led_ext00 {
++ gpios = <&gpio_ext_led 0 GPIO_ACTIVE_LOW>;
++ /* linux,default-trigger = "heartbeat"; */
++ };
++ /* D14 - status 1 */
++ led_ext01 {
++ gpios = <&gpio_ext_led 1 GPIO_ACTIVE_LOW>;
++ /* linux,default-trigger = "mmc1"; */
++ };
++ /* D16 - HDMI1 */
++ led_ext02 {
++ gpios = <&gpio_ext_led 2 GPIO_ACTIVE_LOW>;
++ };
++ /* D18 - HDMI0 */
++ led_ext03 {
++ gpios = <&gpio_ext_led 3 GPIO_ACTIVE_LOW>;
++ };
++ /* D20 - USB3.0 - 0.1 */
++ led_ext04 {
++ gpios = <&gpio_ext_led 4 GPIO_ACTIVE_LOW>;
++ };
++ /* D21 - USB3.0 - 0.2 */
++ led_ext05 {
++ gpios = <&gpio_ext_led 5 GPIO_ACTIVE_LOW>;
++ };
++ /* D24 - USB3.0 - 1.1 */
++ led6_ext06 {
++ gpios = <&gpio_ext_led 6 GPIO_ACTIVE_LOW>;
++ };
++ /* D25 - USB3.0 - 1.2 */
++ led_ext07 {
++ gpios = <&gpio_ext_led 7 GPIO_ACTIVE_LOW>;
++ };
++ };
++
++ snd_clk: snd_clk {
++ compatible = "fixed-clock";
++ #clock-cells = <0>;
++ clock-frequency = <24576000>;
++ clock-output-names = "scki";
++ };
++
++ vccq_sdhi3: regulator@5 {
++ compatible = "regulator-fixed";
++
++ regulator-name = "SDHI3 VccQ";
++ /* external voltage translator to 1.8V */
++ regulator-min-microvolt = <3300000>;
++ regulator-max-microvolt = <3300000>;
++ };
++
++ fpdlink_switch: regulator@8 {
++ compatible = "regulator-fixed";
++ regulator-name = "fpdlink_on";
++ regulator-min-microvolt = <3300000>;
++ regulator-max-microvolt = <3300000>;
++ gpio = <&gpio1 20 0>;
++ enable-active-high;
++ regulator-always-on;
++ };
++
++ hub_reset: regulator@9 {
++ compatible = "regulator-fixed";
++ regulator-name = "hub_reset";
++ regulator-min-microvolt = <3300000>;
++ regulator-max-microvolt = <3300000>;
++ gpio = <&gpio5 5 0>;
++ enable-active-high;
++ regulator-always-on;
++ };
++
++ hub_power: regulator@10 {
++ compatible = "regulator-fixed";
++ regulator-name = "hub_power";
++ regulator-min-microvolt = <5000000>;
++ regulator-max-microvolt = <5000000>;
++ gpio = <&gpio6 28 0>;
++ enable-active-high;
++ regulator-always-on;
++ };
++
++ /delete-node/sound;
++
++ rsnd_ak4613: sound@0 {
++ pinctrl-0 = <&sound_0_pins>;
++ pinctrl-names = "default";
++ compatible = "simple-audio-card";
++
++ simple-audio-card,format = "left_j";
++ simple-audio-card,name = "ak4613";
++
++ simple-audio-card,bitclock-master = <&sndcpu>;
++ simple-audio-card,frame-master = <&sndcpu>;
++
++ sndcpu: simple-audio-card,cpu@1 {
++ sound-dai = <&rcar_sound>;
++ };
++
++ sndcodec: simple-audio-card,codec@1 {
++ sound-dai = <&ak4613>;
++ };
++ };
++
++ lvds {
++ compatible = "panel-lvds";
++
++ width-mm = <210>;
++ height-mm = <158>;
++
++ data-mapping = "jeida-24";
++
++ panel-timing {
++ /* 1280x800 @60Hz */
++ clock-frequency = <65000000>;
++ hactive = <1280>;
++ vactive = <800>;
++ hsync-len = <40>;
++ hfront-porch = <80>;
++ hback-porch = <40>;
++ vfront-porch = <14>;
++ vback-porch = <14>;
++ vsync-len = <4>;
++ };
++
++ port {
++ lvds_in: endpoint {
++ remote-endpoint = <&du_out_lvds0>;
++ };
++ };
++ };
++
++ excan_ref_clk: excan-ref-clock {
++ compatible = "fixed-clock";
++ #clock-cells = <0>;
++ clock-frequency = <16000000>;
++ };
++
++ radio: si468x@0 {
++ compatible = "si,si468x-pcm";
++ status = "okay";
++
++ #sound-dai-cells = <0>;
++ };
++
++ spi_gpio_sw {
++ compatible = "spi-gpio";
++ #address-cells = <0x1>;
++ #size-cells = <0x0>;
++ gpio-sck = <&gpio0 8 GPIO_ACTIVE_HIGH>;
++ gpio-miso = <&gpio0 10 GPIO_ACTIVE_HIGH>;
++ gpio-mosi = <&gpio0 11 GPIO_ACTIVE_HIGH>;
++ cs-gpios = <&gpio0 9 GPIO_ACTIVE_HIGH>;
++ num-chipselects = <1>;
++
++ spidev: spidev@0 {
++ compatible = "spidev", "spi-gpio";
++ reg = <0>;
++ spi-max-frequency = <25000000>;
++ spi-cpha;
++ spi-cpol;
++ };
++ };
++
++ spi_gpio_can {
++ compatible = "spi-gpio";
++ #address-cells = <0x1>;
++ #size-cells = <0x0>;
++ gpio-sck = <&gpio1 2 GPIO_ACTIVE_HIGH>;
++ gpio-miso = <&gpio1 3 GPIO_ACTIVE_HIGH>;
++ gpio-mosi = <&gpio1 1 GPIO_ACTIVE_HIGH>;
++ cs-gpios = <&gpio1 0 GPIO_ACTIVE_HIGH
++ &gpio1 4 GPIO_ACTIVE_HIGH>;
++ num-chipselects = <2>;
++
++ spican0: spidev@0 {
++ compatible = "microchip,mcp2515";
++ reg = <0>;
++ clocks = <&excan_ref_clk>;
++ interrupt-parent = <&gpio0>;
++ interrupts = <15 GPIO_ACTIVE_LOW>;
++ spi-max-frequency = <10000000>;
++ };
++ spican1: spidev@1 {
++ compatible = "microchip,mcp2515";
++ reg = <1>;
++ clocks = <&excan_ref_clk>;
++ interrupt-parent = <&gpio1>;
++ interrupts = <5 GPIO_ACTIVE_LOW>;
++ spi-max-frequency = <10000000>;
++ };
++ };
++};
++
++&pfc {
++ hscif4_pins: hscif4 {
++ groups = "hscif4_data_a", "hscif4_ctrl";
++ function = "hscif4";
++ };
++
++ sdhi3_pins_3v3: sd3_3v3 {
++ groups = "sdhi3_data4", "sdhi3_ctrl";
++ function = "sdhi3";
++ power-source = <3300>;
++ };
++
++ /delete-node/sound;
++
++ sound_0_pins: sound1 {
++ groups = "ssi01239_ctrl", "ssi0_data", "ssi1_data_a";
++ function = "ssi";
++ };
++
++ usb0_pins: usb0 {
++ groups = "usb0";
++ function = "usb0";
++ };
++
++ can0_pins: can0 {
++ groups = "can0_data_a";
++ function = "can0";
++ };
++
++ can1_pins: can1 {
++ groups = "can1_data";
++ function = "can1";
++ };
++
++ canfd0_pins: canfd0 {
++ groups = "canfd0_data_a";
++ function = "canfd0";
++ };
++
++ canfd1_pins: canfd1 {
++ groups = "canfd1_data";
++ function = "canfd1";
++ };
++};
++
++&gpio0 {
++ video_a_irq {
++ gpio-hog;
++ gpios = <12 GPIO_ACTIVE_HIGH>;
++ input;
++ line-name = "Video-A irq";
++ };
++
++ video_b_irq {
++ gpio-hog;
++ gpios = <13 GPIO_ACTIVE_HIGH>;
++ input;
++ line-name = "Video-B irq";
++ };
++
++ video_c_irq {
++ gpio-hog;
++ gpios = <14 GPIO_ACTIVE_HIGH>;
++ input;
++ line-name = "Video-C irq";
++ };
++};
++
++&gpio1 {
++ gpioext_4_22_irq {
++ gpio-hog;
++ gpios = <25 GPIO_ACTIVE_HIGH>;
++ input;
++ line-name = "0x22@i2c4 irq";
++ };
++ pcie_disable {
++ gpio-hog;
++ gpios = <11 GPIO_ACTIVE_HIGH>;
++ output-high;
++ line-name = "mPCIe W_DISABLE";
++ };
++ m2_sleep {
++ gpio-hog;
++ gpios = <6 GPIO_ACTIVE_HIGH>;
++ output-high;
++ line-name = "M.2 SLEEP#";
++ };
++ m2_pres {
++ gpio-hog;
++ gpios = <7 GPIO_ACTIVE_HIGH>;
++ input;
++ line-name = "M.2 Present";
++ };
++ m2_pcie_det {
++ gpio-hog;
++ gpios = <18 GPIO_ACTIVE_HIGH>;
++ input;
++ line-name = "M.2 PCIe detected";
++ };
++ m2_usb_det {
++ gpio-hog;
++ gpios = <19 GPIO_ACTIVE_HIGH>;
++ input;
++ line-name = "M.2 USB30 detected";
++ };
++ m2_usb_det {
++ gpio-hog;
++ gpios = <27 GPIO_ACTIVE_HIGH>;
++ input;
++ line-name = "M.2 SSD detected";
++ };
++ eth_phy_reset {
++ gpio-hog;
++ gpios = <16 GPIO_ACTIVE_HIGH>;
++ output-high;
++ line-name = "BR phy reset";
++ };
++ eth_sw_reset {
++ gpio-hog;
++ gpios = <17 GPIO_ACTIVE_HIGH>;
++ output-high;
++ line-name = "BR switch reset";
++ };
++};
++
++&gpio2 {
++ m2_wake {
++ gpio-hog;
++ gpios = <1 GPIO_ACTIVE_HIGH>;
++ input;
++ line-name = "M.2 WAKE#";
++ };
++ m2_pcie_en {
++ gpio-hog;
++ gpios = <4 GPIO_ACTIVE_HIGH>;
++ output-high;
++ line-name = "M.2 PCIe enable";
++ };
++};
++
++&gpio3 {
++ m2_power_off {
++ gpio-hog;
++ gpios = <15 GPIO_ACTIVE_HIGH>;
++ output-high;
++ line-name = "M.2 FULL_CARD_POWER_OFF#";
++ };
++};
++
++&gpio6 {
++ pcie_wake {
++ gpio-hog;
++ gpios = <4 GPIO_ACTIVE_HIGH>;
++ input;
++ line-name = "mPCIe WAKE#";
++ };
++ pcie_clkreq {
++ gpio-hog;
++ gpios = <10 GPIO_ACTIVE_HIGH>;
++ input;
++ line-name = "mPCIe CLKREQ#";
++ };
++ m2_rst {
++ gpio-hog;
++ gpios = <21 GPIO_ACTIVE_HIGH>;
++ output-high;
++ line-name = "M.2 RESET#";
++ };
++};
++
++&hscif4 {
++ pinctrl-0 = <&hscif4_pins>;
++ pinctrl-names = "default";
++ uart-has-rtscts;
++
++ status = "okay";
++};
++
++&i2c2 {
++ clock-frequency = <400000>;
++
++ i2cswitch2: pca9548@74 {
++ compatible = "nxp,pca9548";
++ #address-cells = <1>;
++ #size-cells = <0>;
++ reg = <0x74>;
++ reset-gpios = <&gpio6 5 GPIO_ACTIVE_LOW>;
++
++ i2c@0 {
++ #address-cells = <1>;
++ #size-cells = <0>;
++ reg = <0>;
++ /* USB3.0 HUB node(s) */
++ };
++
++ i2c@6 {
++ #address-cells = <1>;
++ #size-cells = <0>;
++ reg = <6>;
++ /* PCIe node(s) */
++ };
++
++ i2c@7 {
++ #address-cells = <1>;
++ #size-cells = <0>;
++ reg = <7>;
++ /* Slot A (CN10) */
++
++ ov106xx@0 {
++ compatible = "ovti,ov106xx";
++ reg = <0x60>;
++
++ port@0 {
++ ov106xx_in0: endpoint {
++ clock-lanes = <0>;
++ data-lanes = <1 2 3 4>;
++ remote-endpoint = <&vin0ep0>;
++ };
++ };
++ port@1 {
++ ov106xx_max9286_des0ep0: endpoint@0 {
++ remote-endpoint = <&max9286_des0ep0>;
++ };
++ ov106xx_ti9x4_des0ep0: endpoint@1 {
++ remote-endpoint = <&ti9x4_des0ep0>;
++ };
++ };
++ };
++
++ ov106xx@1 {
++ compatible = "ovti,ov106xx";
++ reg = <0x61>;
++
++ port@0 {
++ ov106xx_in1: endpoint {
++ clock-lanes = <0>;
++ data-lanes = <1 2 3 4>;
++ remote-endpoint = <&vin1ep0>;
++ };
++ };
++ port@1 {
++ ov106xx_max9286_des0ep1: endpoint@0 {
++ remote-endpoint = <&max9286_des0ep1>;
++ };
++ ov106xx_ti9x4_des0ep1: endpoint@1 {
++ remote-endpoint = <&ti9x4_des0ep1>;
++ };
++ };
++ };
++
++ ov106xx@2 {
++ compatible = "ovti,ov106xx";
++ reg = <0x62>;
++
++ port@0 {
++ ov106xx_in2: endpoint {
++ clock-lanes = <0>;
++ data-lanes = <1 2 3 4>;
++ remote-endpoint = <&vin2ep0>;
++ };
++ };
++ port@1 {
++ ov106xx_max9286_des0ep2: endpoint@0 {
++ remote-endpoint = <&max9286_des0ep2>;
++ };
++ ov106xx_ti9x4_des0ep2: endpoint@1 {
++ remote-endpoint = <&ti9x4_des0ep2>;
++ };
++ };
++ };
++
++ ov106xx@3 {
++ compatible = "ovti,ov106xx";
++ reg = <0x63>;
++
++ port@0 {
++ ov106xx_in3: endpoint {
++ clock-lanes = <0>;
++ data-lanes = <1 2 3 4>;
++ remote-endpoint = <&vin3ep0>;
++ };
++ };
++ port@1 {
++ ov106xx_max9286_des0ep3: endpoint@0 {
++ remote-endpoint = <&max9286_des0ep3>;
++ };
++ ov106xx_ti9x4_des0ep3: endpoint@1 {
++ remote-endpoint = <&ti9x4_des0ep3>;
++ };
++ };
++ };
++
++ /* DS90UB9x4 @ 0x3a */
++ ti9x4@0 {
++ compatible = "ti,ti9x4";
++ reg = <0x3a>;
++ ti,links = <4>;
++ ti,lanes = <4>;
++ ti,forwarding-mode = "round-robin";
++ ti,cable-mode = "stp";
++
++ POC0-gpios = <&gpio_exp_a_5c 8 GPIO_ACTIVE_HIGH>;
++ POC1-gpios = <&gpio_exp_a_5c 9 GPIO_ACTIVE_HIGH>;
++ POC2-gpios = <&gpio_exp_a_5c 10 GPIO_ACTIVE_HIGH>;
++ POC3-gpios = <&gpio_exp_a_5c 11 GPIO_ACTIVE_HIGH>;
++
++ port@0 {
++ ti9x4_des0ep0: endpoint@0 {
++ ti9x3-addr = <0x0c>;
++ dvp-order = <0>;
++ remote-endpoint = <&ov106xx_in0>;
++ };
++ ti9x4_des0ep1: endpoint@1 {
++ ti9x3-addr = <0x0d>;
++ dvp-order = <0>;
++ remote-endpoint = <&ov106xx_in1>;
++ };
++ ti9x4_des0ep2: endpoint@2 {
++ ti9x3-addr = <0x0e>;
++ dvp-order = <0>;
++ remote-endpoint = <&ov106xx_in2>;
++ };
++ ti9x4_des0ep3: endpoint@3 {
++ ti9x3-addr = <0x0f>;
++ dvp-order = <0>;
++ remote-endpoint = <&ov106xx_in3>;
++ };
++ };
++ port@1 {
++ ti9x4_csi0ep0: endpoint {
++ csi-rate = <1450>;
++ remote-endpoint = <&csi40_ep>;
++ };
++ };
++ };
++
++ /* MAX9286 @ 0x2c */
++ max9286@0 {
++ compatible = "maxim,max9286";
++ reg = <0x2c>;
++ maxim,links = <4>;
++ maxim,lanes = <4>;
++ maxim,resetb-gpio = <1>;
++ maxim,fsync-mode = "automatic";
++ maxim,timeout = <100>;
++
++ POC0-gpios = <&gpio_exp_a_5c 9 GPIO_ACTIVE_HIGH>;
++ POC1-gpios = <&gpio_exp_a_5c 8 GPIO_ACTIVE_HIGH>;
++ POC2-gpios = <&gpio_exp_a_5c 11 GPIO_ACTIVE_HIGH>;
++ POC3-gpios = <&gpio_exp_a_5c 10 GPIO_ACTIVE_HIGH>;
++
++ port@0 {
++ max9286_des0ep0: endpoint@0 {
++ max9271-addr = <0x50>;
++ dvp-order = <1>;
++ remote-endpoint = <&ov106xx_in0>;
++ };
++ max9286_des0ep1: endpoint@1 {
++ max9271-addr = <0x51>;
++ dvp-order = <1>;
++ remote-endpoint = <&ov106xx_in1>;
++ };
++ max9286_des0ep2: endpoint@2 {
++ max9271-addr = <0x52>;
++ dvp-order = <1>;
++ remote-endpoint = <&ov106xx_in2>;
++ };
++ max9286_des0ep3: endpoint@3 {
++ max9271-addr = <0x53>;
++ dvp-order = <1>;
++ remote-endpoint = <&ov106xx_in3>;
++ };
++ };
++ port@1 {
++ max9286_csi0ep0: endpoint {
++ csi-rate = <700>;
++ remote-endpoint = <&csi40_ep>;
++ };
++ };
++ };
++ };
++
++ i2c@2 {
++ #address-cells = <1>;
++ #size-cells = <0>;
++ reg = <2>;
++ /* Slot B (CN11) */
++
++ ov106xx@4 {
++ compatible = "ovti,ov106xx";
++ reg = <0x64>;
++
++ port@0 {
++ ov106xx_in4: endpoint {
++ clock-lanes = <0>;
++ data-lanes = <1 2 3 4>;
++ remote-endpoint = <&vin4ep0>;
++ };
++ };
++ port@1 {
++ ov106xx_max9286_des1ep0: endpoint@0 {
++ remote-endpoint = <&max9286_des1ep0>;
++ };
++ ov106xx_ti9x4_des1ep0: endpoint@1 {
++ remote-endpoint = <&ti9x4_des1ep0>;
++ };
++ };
++ };
++
++ ov106xx@5 {
++ compatible = "ovti,ov106xx";
++ reg = <0x65>;
++
++ port@0 {
++ ov106xx_in5: endpoint {
++ clock-lanes = <0>;
++ data-lanes = <1 2 3 4>;
++ remote-endpoint = <&vin5ep0>;
++ };
++ };
++ port@1 {
++ ov106xx_max9286_des1ep1: endpoint@0 {
++ remote-endpoint = <&max9286_des1ep1>;
++ };
++ ov106xx_ti9x4_des1ep1: endpoint@1 {
++ remote-endpoint = <&ti9x4_des1ep1>;
++ };
++ };
++ };
++
++ ov106xx@6 {
++ compatible = "ovti,ov106xx";
++ reg = <0x66>;
++
++ port@0 {
++ ov106xx_in6: endpoint {
++ clock-lanes = <0>;
++ data-lanes = <1 2 3 4>;
++ remote-endpoint = <&vin6ep0>;
++ };
++ };
++ port@1 {
++ ov106xx_max9286_des1ep2: endpoint@0 {
++ remote-endpoint = <&max9286_des1ep2>;
++ };
++ ov106xx_ti9x4_des1ep2: endpoint@1 {
++ remote-endpoint = <&ti9x4_des1ep2>;
++ };
++ };
++ };
++
++ ov106xx@7 {
++ compatible = "ovti,ov106xx";
++ reg = <0x67>;
++
++ port@0 {
++ ov106xx_in7: endpoint {
++ clock-lanes = <0>;
++ data-lanes = <1 2 3 4>;
++ remote-endpoint = <&vin7ep0>;
++ };
++ };
++ port@1 {
++ ov106xx_max9286_des1ep3: endpoint@0 {
++ remote-endpoint = <&max9286_des1ep3>;
++ };
++ ov106xx_ti9x4_des1ep3: endpoint@1 {
++ remote-endpoint = <&ti9x4_des1ep3>;
++ };
++ };
++ };
++
++ /* DS90UB9x4 @ 0x3a */
++ ti9x4@1 {
++ compatible = "ti,ti9x4";
++ reg = <0x3a>;
++ ti,links = <4>;
++ ti,lanes = <4>;
++ ti,forwarding-mode = "round-robin";
++ ti,cable-mode = "stp";
++
++ POC0-gpios = <&gpio_exp_b_5c 8 GPIO_ACTIVE_HIGH>;
++ POC1-gpios = <&gpio_exp_b_5c 9 GPIO_ACTIVE_HIGH>;
++ POC2-gpios = <&gpio_exp_b_5c 10 GPIO_ACTIVE_HIGH>;
++ POC3-gpios = <&gpio_exp_b_5c 11 GPIO_ACTIVE_HIGH>;
++
++ port@0 {
++ ti9x4_des1ep0: endpoint@0 {
++ ti9x3-addr = <0x0c>;
++ dvp-order = <0>;
++ remote-endpoint = <&ov106xx_in4>;
++ };
++ ti9x4_des1ep1: endpoint@1 {
++ ti9x3-addr = <0x0d>;
++ dvp-order = <0>;
++ remote-endpoint = <&ov106xx_in5>;
++ };
++ ti9x4_des1ep2: endpoint@2 {
++ ti9x3-addr = <0x0e>;
++ dvp-order = <0>;
++ remote-endpoint = <&ov106xx_in6>;
++ };
++ ti9x4_des1ep3: endpoint@3 {
++ ti9x3-addr = <0x0f>;
++ dvp-order = <0>;
++ remote-endpoint = <&ov106xx_in7>;
++ };
++ };
++ port@1 {
++ ti9x4_csi2ep0: endpoint {
++ csi-rate = <1450>;
++ remote-endpoint = <&csi41_ep>;
++ };
++ };
++ };
++
++ /* MAX9286 @ 0x2c */
++ max9286@1 {
++ compatible = "maxim,max9286";
++ reg = <0x2c>;
++ maxim,links = <4>;
++ maxim,lanes = <4>;
++ maxim,resetb-gpio = <1>;
++ maxim,fsync-mode = "automatic";
++ maxim,timeout = <100>;
++
++ POC0-gpios = <&gpio_exp_b_5c 9 GPIO_ACTIVE_HIGH>;
++ POC1-gpios = <&gpio_exp_b_5c 8 GPIO_ACTIVE_HIGH>;
++ POC2-gpios = <&gpio_exp_b_5c 11 GPIO_ACTIVE_HIGH>;
++ POC3-gpios = <&gpio_exp_b_5c 10 GPIO_ACTIVE_HIGH>;
++
++ port@0 {
++ max9286_des1ep0: endpoint@0 {
++ max9271-addr = <0x50>;
++ dvp-order = <1>;
++ remote-endpoint = <&ov106xx_in4>;
++ };
++ max9286_des1ep1: endpoint@1 {
++ max9271-addr = <0x51>;
++ dvp-order = <1>;
++ remote-endpoint = <&ov106xx_in5>;
++ };
++ max9286_des1ep2: endpoint@2 {
++ max9271-addr = <0x52>;
++ dvp-order = <1>;
++ remote-endpoint = <&ov106xx_in6>;
++ };
++ max9286_des1ep3: endpoint@3 {
++ max9271-addr = <0x53>;
++ dvp-order = <1>;
++ remote-endpoint = <&ov106xx_in7>;
++ };
++ };
++ port@1 {
++ max9286_csi2ep0: endpoint {
++ csi-rate = <700>;
++ remote-endpoint = <&csi41_ep>;
++ };
++ };
++ };
++ };
++
++ i2c@3 {
++ #address-cells = <1>;
++ #size-cells = <0>;
++ reg = <3>;
++ /* Slot C (CN12) */
++ };
++
++ i2c@1 {
++ #address-cells = <1>;
++ #size-cells = <0>;
++ reg = <1>;
++ /* Slot A (CN10) */
++
++ /* PCA9535 is a redundant/deprecated card */
++ gpio_exp_a_26: gpio@26 {
++ compatible = "nxp,pca9535";
++ reg = <0x26>;
++ gpio-controller;
++ #gpio-cells = <2>;
++
++ video_a_des_cfg1 {
++ gpio-hog;
++ gpios = <5 GPIO_ACTIVE_HIGH>;
++ input;
++ line-name = "Video-A cfg1";
++ };
++ video_a_des_cfg0 {
++ gpio-hog;
++ gpios = <6 GPIO_ACTIVE_HIGH>;
++ input;
++ line-name = "Video-A cfg0";
++ };
++ video_a_pwr_shdn {
++ gpio-hog;
++ gpios = <3 GPIO_ACTIVE_HIGH>;
++ output-high;
++ line-name = "Video-A PWR_SHDN";
++ };
++ video_a_cam_pwr0 {
++ gpio-hog;
++ gpios = <12 GPIO_ACTIVE_HIGH>;
++ output-high;
++ line-name = "Video-A PWR0";
++ };
++ video_a_cam_pwr1 {
++ gpio-hog;
++ gpios = <13 GPIO_ACTIVE_HIGH>;
++ output-high;
++ line-name = "Video-A PWR1";
++ };
++ video_a_cam_pwr2 {
++ gpio-hog;
++ gpios = <14 GPIO_ACTIVE_HIGH>;
++ output-high;
++ line-name = "Video-A PWR2";
++ };
++ video_a_cam_pwr3 {
++ gpio-hog;
++ gpios = <15 GPIO_ACTIVE_HIGH>;
++ output-high;
++ line-name = "Video-A PWR3";
++ };
++ video_a_des_shdn {
++ gpio-hog;
++ gpios = <4 GPIO_ACTIVE_HIGH>;
++ output-high;
++ line-name = "Video-A DES_SHDN";
++ };
++ video_a_des_led {
++ gpio-hog;
++ gpios = <7 GPIO_ACTIVE_HIGH>;
++ output-low;
++ line-name = "Video-A led";
++ };
++ };
++
++ gpio_exp_a_5c: gpio@5c {
++ compatible = "maxim,max7325";
++ reg = <0x5c>;
++ gpio-controller;
++ #gpio-cells = <2>;
++
++ video_a_des_cfg2 {
++ gpio-hog;
++ gpios = <4 GPIO_ACTIVE_HIGH>;
++ input;
++ line-name = "Video-A cfg2";
++ };
++ video_a_des_cfg1 {
++ gpio-hog;
++ gpios = <6 GPIO_ACTIVE_HIGH>;
++ input;
++ line-name = "Video-A cfg1";
++ };
++ video_a_des_cfg0 {
++ gpio-hog;
++ gpios = <7 GPIO_ACTIVE_HIGH>;
++ input;
++ line-name = "Video-A cfg0";
++ };
++ video_a_pwr_shdn {
++ gpio-hog;
++ gpios = <14 GPIO_ACTIVE_HIGH>;
++ output-high;
++ line-name = "Video-A PWR_SHDN";
++ };
++ video_a_des_shdn {
++ gpio-hog;
++ gpios = <13 GPIO_ACTIVE_HIGH>;
++ output-high;
++ line-name = "Video-A DES_SHDN";
++ };
++ video_a_led {
++ gpio-hog;
++ gpios = <12 GPIO_ACTIVE_HIGH>;
++ output-low;
++ line-name = "Video-A LED";
++ };
++ };
++ };
++
++ i2c@5 {
++ #address-cells = <1>;
++ #size-cells = <0>;
++ reg = <5>;
++ /* Slot B (CN11) */
++
++ /* PCA9535 is a redundant/deprecated card */
++ gpio_exp_b_26: gpio@26 {
++ compatible = "nxp,pca9535";
++ reg = <0x26>;
++ gpio-controller;
++ #gpio-cells = <2>;
++
++ video_b_des_cfg1 {
++ gpio-hog;
++ gpios = <5 GPIO_ACTIVE_HIGH>;
++ input;
++ line-name = "Video-B cfg1";
++ };
++ video_b_des_cfg0 {
++ gpio-hog;
++ gpios = <6 GPIO_ACTIVE_HIGH>;
++ input;
++ line-name = "Video-B cfg0";
++ };
++ video_b_pwr_shdn {
++ gpio-hog;
++ gpios = <3 GPIO_ACTIVE_HIGH>;
++ output-high;
++ line-name = "Video-B PWR_SHDN";
++ };
++ video_b_cam_pwr0 {
++ gpio-hog;
++ gpios = <12 GPIO_ACTIVE_HIGH>;
++ output-high;
++ line-name = "Video-B PWR0";
++ };
++ video_b_cam_pwr1 {
++ gpio-hog;
++ gpios = <13 GPIO_ACTIVE_HIGH>;
++ output-high;
++ line-name = "Video-B PWR1";
++ };
++ video_b_cam_pwr2 {
++ gpio-hog;
++ gpios = <14 GPIO_ACTIVE_HIGH>;
++ output-high;
++ line-name = "Video-B PWR2";
++ };
++ video_b_cam_pwr3 {
++ gpio-hog;
++ gpios = <15 GPIO_ACTIVE_HIGH>;
++ output-high;
++ line-name = "Video-B PWR3";
++ };
++ video_b_des_shdn {
++ gpio-hog;
++ gpios = <4 GPIO_ACTIVE_HIGH>;
++ output-high;
++ line-name = "Video-B DES_SHDN";
++ };
++ video_b_des_led {
++ gpio-hog;
++ gpios = <7 GPIO_ACTIVE_HIGH>;
++ output-low;
++ line-name = "Video-B led";
++ };
++ };
++
++ gpio_exp_b_5c: gpio@5c {
++ compatible = "maxim,max7325";
++ reg = <0x5c>;
++ gpio-controller;
++ #gpio-cells = <2>;
++
++ video_b_des_cfg2 {
++ gpio-hog;
++ gpios = <4 GPIO_ACTIVE_HIGH>;
++ input;
++ line-name = "Video-B cfg2";
++ };
++ video_b_des_cfg1 {
++ gpio-hog;
++ gpios = <6 GPIO_ACTIVE_HIGH>;
++ input;
++ line-name = "Video-B cfg1";
++ };
++ video_b_des_cfg0 {
++ gpio-hog;
++ gpios = <7 GPIO_ACTIVE_HIGH>;
++ input;
++ line-name = "Video-B cfg0";
++ };
++ video_b_pwr_shdn {
++ gpio-hog;
++ gpios = <14 GPIO_ACTIVE_HIGH>;
++ output-high;
++ line-name = "Video-B PWR_SHDN";
++ };
++ video_b_des_shdn {
++ gpio-hog;
++ gpios = <13 GPIO_ACTIVE_HIGH>;
++ output-high;
++ line-name = "Video-B DES_SHDN";
++ };
++ video_b_led {
++ gpio-hog;
++ gpios = <12 GPIO_ACTIVE_HIGH>;
++ output-low;
++ line-name = "Video-B LED";
++ };
++ };
++ };
++
++ i2c@4 {
++ #address-cells = <1>;
++ #size-cells = <0>;
++ reg = <4>;
++ /* Slot C (CN12) */
++ };
++ };
++};
++
++&i2c4 {
++ i2cswitch4: pca9548@74 {
++ compatible = "nxp,pca9548";
++ #address-cells = <1>;
++ #size-cells = <0>;
++ reg = <0x74>;
++ reset-gpios= <&gpio5 15 GPIO_ACTIVE_LOW>;
++
++ i2c@0 {
++ #address-cells = <1>;
++ #size-cells = <0>;
++ reg = <0>;
++ /* FAN node - EMC2103 */
++ fan_ctrl:ecm2103@2e {
++ compatible = "emc2103";
++ reg = <0x2e>;
++ };
++ };
++
++ i2c@1 {
++ #address-cells = <1>;
++ #size-cells = <0>;
++ reg = <1>;
++ /* Power nodes - 2 x TPS544x20 */
++ };
++
++ i2c@2 {
++ #address-cells = <1>;
++ #size-cells = <0>;
++ reg = <2>;
++ /* CAN and power board nodes */
++
++ gpio_ext_pwr: pca9535@22 {
++ compatible = "nxp,pca9535";
++ reg = <0x22>;
++ gpio-controller;
++ #gpio-cells = <2>;
++ interrupt-controller;
++ interrupt-parent = <&gpio1>;
++ interrupts = <25 IRQ_TYPE_EDGE_FALLING>;
++
++ /* enable input DCDC after wake-up signal released */
++ pwr_hold {
++ gpio-hog;
++ gpios = <11 GPIO_ACTIVE_HIGH>;
++ output-high;
++ line-name = "pwr_hold";
++ };
++
++ /* CAN0 */
++ can0_stby {
++ gpio-hog;
++ gpios = <4 GPIO_ACTIVE_HIGH>;
++ output-low;
++ line-name = "can0_stby";
++ };
++ can0_load {
++ gpio-hog;
++ gpios = <0 GPIO_ACTIVE_HIGH>;
++ output-low;
++ line-name = "can0_120R_load";
++ };
++ /* CAN1 */
++ can1_stby {
++ gpio-hog;
++ gpios = <5 GPIO_ACTIVE_HIGH>;
++ output-low;
++ line-name = "can1_stby";
++ };
++ can1_load {
++ gpio-hog;
++ gpios = <1 GPIO_ACTIVE_HIGH>;
++ output-low;
++ line-name = "can1_120R_load";
++ };
++ /* CAN2 */
++ can2_stby {
++ gpio-hog;
++ gpios = <6 GPIO_ACTIVE_HIGH>;
++ output-low;
++ line-name = "can2_stby";
++ };
++ can2_load {
++ gpio-hog;
++ gpios = <2 GPIO_ACTIVE_HIGH>;
++ output-low;
++ line-name = "can2_120R_load";
++ };
++ can2_rst {
++ gpio-hog;
++ gpios = <8 GPIO_ACTIVE_HIGH>;
++ output-high;
++ line-name = "can2_rst";
++ };
++ /* CAN3 */
++ can3_stby {
++ gpio-hog;
++ gpios = <7 GPIO_ACTIVE_HIGH>;
++ output-low;
++ line-name = "can3_stby";
++ };
++ can3_load {
++ gpio-hog;
++ gpios = <3 GPIO_ACTIVE_HIGH>;
++ output-low;
++ line-name = "can3_120R_load";
++ };
++ can3_rst {
++ gpio-hog;
++ gpios = <9 GPIO_ACTIVE_HIGH>;
++ output-high;
++ line-name = "can3_rst";
++ };
++ };
++ };
++
++ i2c@3 {
++ #address-cells = <1>;
++ #size-cells = <0>;
++ reg = <3>;
++ /* FPDLink output node - DS90UH947 */
++ };
++
++ i2c@4 {
++ #address-cells = <1>;
++ #size-cells = <0>;
++ reg = <4>;
++ /* BCM switch node */
++ };
++
++ i2c@5 {
++ #address-cells = <1>;
++ #size-cells = <0>;
++ reg = <5>;
++ /* LED board node(s) */
++
++ gpio_ext_led: pca9535@22 {
++ compatible = "nxp,pca9535";
++ reg = <0x22>;
++ gpio-controller;
++ #gpio-cells = <2>;
++
++ /* gpios 0..7 are used for indication LEDs, low-active */
++ };
++ };
++
++ i2c@6 {
++ #address-cells = <1>;
++ #size-cells = <0>;
++ reg = <6>;
++ /* M2 connector i2c node(s) */
++ };
++
++ /* port 7 is not used */
++ };
++};
++
++&pcie_bus_clk {
++ clock-frequency = <100000000>;
++ status = "okay";
++};
++
++&pciec0 {
++ status = "okay";
++};
++
++&pciec1 {
++ status = "okay";
++};
++
++&vin0 {
++ status = "okay";
++
++ ports {
++ #address-cells = <1>;
++ #size-cells = <0>;
++
++ port@0 {
++ vin0ep0: endpoint {
++ csi,select = "csi40";
++ virtual,channel = <0>;
++ data-lanes = <1 2 3 4>;
++ remote-endpoint = <&ov106xx_in0>;
++ };
++ };
++ port@1 {
++ csi0ep0: endpoint {
++ remote-endpoint = <&csi40_ep>;
++ };
++ };
++ port@2 {
++ vin0_max9286_des0ep0: endpoint@0 {
++ remote-endpoint = <&max9286_des0ep0>;
++ };
++ vin0_ti9x4_des0ep0: endpoint@1 {
++ remote-endpoint = <&ti9x4_des0ep0>;
++ };
++ };
++ };
++};
++
++&vin1 {
++ status = "okay";
++
++ ports {
++ #address-cells = <1>;
++ #size-cells = <0>;
++
++ port@0 {
++ vin1ep0: endpoint {
++ csi,select = "csi40";
++ virtual,channel = <1>;
++ data-lanes = <1 2 3 4>;
++ remote-endpoint = <&ov106xx_in1>;
++ };
++ };
++ port@1 {
++ csi0ep1: endpoint {
++ remote-endpoint = <&csi40_ep>;
++ };
++ };
++ port@2 {
++ vin1_max9286_des0ep1: endpoint@0 {
++ remote-endpoint = <&max9286_des0ep1>;
++ };
++ vin1_ti9x4_des0ep1: endpoint@1 {
++ remote-endpoint = <&ti9x4_des0ep1>;
++ };
++ };
++ };
++};
++
++&vin2 {
++ status = "okay";
++
++ ports {
++ #address-cells = <1>;
++ #size-cells = <0>;
++
++ port@0 {
++ vin2ep0: endpoint {
++ csi,select = "csi40";
++ virtual,channel = <2>;
++ data-lanes = <1 2 3 4>;
++ remote-endpoint = <&ov106xx_in2>;
++ };
++ };
++ port@1 {
++ csi0ep2: endpoint {
++ remote-endpoint = <&csi40_ep>;
++ };
++ };
++ port@2 {
++ vin2_max9286_des0ep2: endpoint@0 {
++ remote-endpoint = <&max9286_des0ep2>;
++ };
++ vin2_ti9x4_des0ep2: endpoint@1 {
++ remote-endpoint = <&ti9x4_des0ep2>;
++ };
++ };
++ };
++};
++
++&vin3 {
++ status = "okay";
++
++ ports {
++ #address-cells = <1>;
++ #size-cells = <0>;
++
++ port@0 {
++ vin3ep0: endpoint {
++ csi,select = "csi40";
++ virtual,channel = <3>;
++ data-lanes = <1 2 3 4>;
++ remote-endpoint = <&ov106xx_in3>;
++ };
++ };
++ port@1 {
++ csi0ep3: endpoint {
++ remote-endpoint = <&csi40_ep>;
++ };
++ };
++ port@2 {
++ vin3_max9286_des0ep3: endpoint@0 {
++ remote-endpoint = <&max9286_des0ep3>;
++ };
++ vin3_ti9x4_des0ep3: endpoint@1 {
++ remote-endpoint = <&ti9x4_des0ep3>;
++ };
++ };
++ };
++};
++
++&vin4 {
++ status = "okay";
++
++ ports {
++ #address-cells = <1>;
++ #size-cells = <0>;
++
++ port@0 {
++ vin4ep0: endpoint {
++ csi,select = "csi41";
++ virtual,channel = <0>;
++ remote-endpoint = <&ov106xx_in4>;
++ data-lanes = <1 2 3 4>;
++ };
++ };
++ port@1 {
++ csi2ep0: endpoint {
++ remote-endpoint = <&csi41_ep>;
++ };
++ };
++ port@2 {
++ vin4_max9286_des1ep0: endpoint@0 {
++ remote-endpoint = <&max9286_des1ep0>;
++ };
++ vin4_ti9x4_des1ep0: endpoint@1 {
++ remote-endpoint = <&ti9x4_des1ep0>;
++ };
++ };
++ };
++};
++
++&vin5 {
++ status = "okay";
++
++ ports {
++ #address-cells = <1>;
++ #size-cells = <0>;
++
++ port@0 {
++ vin5ep0: endpoint@0 {
++ csi,select = "csi41";
++ virtual,channel = <1>;
++ remote-endpoint = <&ov106xx_in5>;
++ data-lanes = <1 2 3 4>;
++ };
++ };
++ port@1 {
++ csi2ep1: endpoint {
++ remote-endpoint = <&csi41_ep>;
++ };
++ };
++ port@2 {
++ vin5_max9286_des1ep1: endpoint@0 {
++ remote-endpoint = <&max9286_des1ep1>;
++ };
++ vin5_ti9x4_des1ep1: endpoint@1 {
++ remote-endpoint = <&ti9x4_des1ep1>;
++ };
++ };
++ };
++};
++
++&vin6 {
++ status = "okay";
++
++ ports {
++ #address-cells = <1>;
++ #size-cells = <0>;
++
++ port@0 {
++ vin6ep0: endpoint@0 {
++ csi,select = "csi41";
++ virtual,channel = <2>;
++ remote-endpoint = <&ov106xx_in6>;
++ data-lanes = <1 2 3 4>;
++ };
++ };
++ port@1 {
++ csi2ep2: endpoint {
++ remote-endpoint = <&csi41_ep>;
++ };
++ };
++ port@2 {
++ vin6_max9286_des1ep2: endpoint@0 {
++ remote-endpoint = <&max9286_des1ep2>;
++ };
++ vin6_ti9x4_des1ep2: endpoint@1 {
++ remote-endpoint = <&ti9x4_des1ep2>;
++ };
++ };
++ };
++};
++
++&vin7 {
++ status = "okay";
++
++ ports {
++ #address-cells = <1>;
++ #size-cells = <0>;
++
++ port@0 {
++ vin7ep0: endpoint@0 {
++ csi,select = "csi41";
++ virtual,channel = <3>;
++ remote-endpoint = <&ov106xx_in7>;
++ data-lanes = <1 2 3 4>;
++ };
++ };
++ port@1 {
++ csi2ep3: endpoint {
++ remote-endpoint = <&csi41_ep>;
++ };
++ };
++ port@2 {
++ vin7_max9286_des1ep3: endpoint@0 {
++ remote-endpoint = <&max9286_des1ep3>;
++ };
++ vin7_ti9x4_des1ep3: endpoint@1 {
++ remote-endpoint = <&ti9x4_des1ep3>;
++ };
++ };
++ };
++};
++
++&csi40 {
++ status = "okay";
++
++ virtual,channel {
++ csi2_vc0 {
++ data,type = "ycbcr422";
++ receive,vc = <0>;
++ };
++ csi2_vc1 {
++ data,type = "ycbcr422";
++ receive,vc = <1>;
++ };
++ csi2_vc2 {
++ data,type = "ycbcr422";
++ receive,vc = <2>;
++ };
++ csi2_vc3 {
++ data,type = "ycbcr422";
++ receive,vc = <3>;
++ };
++ };
++
++ port {
++ #address-cells = <1>;
++ #size-cells = <0>;
++
++ csi40_ep: endpoint {
++ clock-lanes = <0>;
++ data-lanes = <1 2 3 4>;
++ csi-rate = <300>;
++ };
++ };
++};
++
++&csi41 {
++ status = "okay";
++
++ virtual,channel {
++ csi2_vc0 {
++ data,type = "ycbcr422";
++ receive,vc = <0>;
++ };
++ csi2_vc1 {
++ data,type = "ycbcr422";
++ receive,vc = <1>;
++ };
++ csi2_vc2 {
++ data,type = "ycbcr422";
++ receive,vc = <2>;
++ };
++ csi2_vc3 {
++ data,type = "ycbcr422";
++ receive,vc = <3>;
++ };
++ };
++
++ port {
++ #address-cells = <1>;
++ #size-cells = <0>;
++
++ csi41_ep: endpoint {
++ clock-lanes = <0>;
++ data-lanes = <1 2 3 4>;
++ csi-rate = <300>;
++ };
++ };
++};
++
++&rcar_sound {
++ pinctrl-0 = <&sound_clk_pins>;
++
++ /* Multi DAI */
++ #sound-dai-cells = <1>;
++};
++
++&sata {
++ status = "okay";
++};
++
++&ssi1 {
++ /delete-property/shared-pin;
++};
++
++&avb {
++ /delete-property/phy-handle;
++ /delete-property/phy-gpios;
++ phy-mode = "rgmii";
++
++ /delete-node/ethernet-phy@0;
++
++ fixed-link {
++ speed = <100>;
++ full-duplex;
++ };
++};
++
++&msiof1 {
++ status = "disabled";
++};
++
++&usb2_phy0 {
++ pinctrl-0 = <&usb0_pins>;
++ pinctrl-names = "default";
++
++ status = "okay";
++};
++
++&xhci0 {
++ status = "okay";
++};
++
++&ehci0 {
++ status = "okay";
++};
++
++&ohci0 {
++ status = "okay";
++};
++
++&can0 {
++ pinctrl-0 = <&can0_pins>;
++ pinctrl-names = "default";
++ status = "okay";
++
++ renesas,can-clock-select = <0x0>;
++};
++
++&can1 {
++ pinctrl-0 = <&can1_pins>;
++ pinctrl-names = "default";
++ status = "okay";
++
++ renesas,can-clock-select = <0x0>;
++};
++
++&canfd {
++ pinctrl-0 = <&canfd0_pins &canfd1_pins>;
++ pinctrl-names = "default";
++ status = "disabled";
++
++ renesas,can-clock-select = <0x0>;
++
++ channel0 {
++ status = "okay";
++ };
++
++ channel1 {
++ status = "okay";
++ };
++};
++
++/* uncomment to enable CN12 on VIN4-7 */
++//#include "ulcb-vb-cn12.dtsi"
+diff --git a/arch/arm64/boot/dts/renesas/ulcb-vb2.dtsi b/arch/arm64/boot/dts/renesas/ulcb-vb2.dtsi
+new file mode 100644
+index 0000000..0f49b44
+--- /dev/null
++++ b/arch/arm64/boot/dts/renesas/ulcb-vb2.dtsi
+@@ -0,0 +1,1641 @@
++/*
++ * Device Tree Source for the ULCB Videobox V2 board
++ *
++ * Copyright (C) 2018 Cogent Embedded, Inc.
++ *
++ * This file is licensed under the terms of the GNU General Public License
++ * version 2. This program is licensed "as is" without any warranty of any
++ * kind, whether express or implied.
++ */
++
++/ {
++ leds {
++ compatible = "gpio-leds";
++
++ led5 {
++ gpios = <&gpio6 12 GPIO_ACTIVE_HIGH>;
++ };
++ led6 {
++ gpios = <&gpio6 13 GPIO_ACTIVE_HIGH>;
++ };
++ /* D13 - status 0 */
++ led_ext00 {
++ gpios = <&gpio_ext_led 0 GPIO_ACTIVE_LOW>;
++ /* linux,default-trigger = "heartbeat"; */
++ };
++ /* D14 - status 1 */
++ led_ext01 {
++ gpios = <&gpio_ext_led 1 GPIO_ACTIVE_LOW>;
++ /* linux,default-trigger = "mmc1"; */
++ };
++ /* D16 - HDMI0 */
++ led_ext02 {
++ gpios = <&gpio_ext_led 2 GPIO_ACTIVE_LOW>;
++ };
++ /* D18 - HDMI1 */
++ led_ext03 {
++ gpios = <&gpio_ext_led 3 GPIO_ACTIVE_LOW>;
++ };
++ };
++
++ snd_clk: snd_clk {
++ compatible = "fixed-clock";
++ #clock-cells = <0>;
++ clock-frequency = <24576000>;
++ clock-output-names = "scki";
++ };
++
++ vcc_sdhi3: regulator-vcc-sdhi3 {
++ compatible = "regulator-fixed";
++
++ regulator-name = "SDHI3 Vcc";
++ regulator-min-microvolt = <3300000>;
++ regulator-max-microvolt = <3300000>;
++
++ gpio = <&gpio4 17 GPIO_ACTIVE_HIGH>;
++ enable-active-high;
++ };
++
++ vccq_sdhi3: regulator-vccq-sdhi3 {
++ compatible = "regulator-fixed";
++
++ regulator-name = "SDHI3 VccQ";
++ regulator-min-microvolt = <3300000>;
++ regulator-max-microvolt = <3300000>;
++ };
++
++ fpdlink_switch: regulator@8 {
++ compatible = "regulator-fixed";
++ regulator-name = "fpdlink_on";
++ regulator-min-microvolt = <3300000>;
++ regulator-max-microvolt = <3300000>;
++ gpio = <&gpio1 20 0>;
++ enable-active-high;
++ regulator-always-on;
++ };
++
++ hub_reset: regulator@9 {
++ compatible = "regulator-fixed";
++ regulator-name = "hub_reset";
++ regulator-min-microvolt = <3300000>;
++ regulator-max-microvolt = <3300000>;
++ gpio = <&gpio5 5 0>;
++ enable-active-high;
++ regulator-always-on;
++ };
++
++ hub_power: regulator@10 {
++ compatible = "regulator-fixed";
++ regulator-name = "hub_power";
++ regulator-min-microvolt = <5000000>;
++ regulator-max-microvolt = <5000000>;
++ gpio = <&gpio6 28 0>;
++ enable-active-high;
++ regulator-always-on;
++ };
++
++ /delete-node/sound;
++
++ rsnd_ak4613: sound@0 {
++ pinctrl-0 = <&sound_0_pins>;
++ pinctrl-names = "default";
++ compatible = "simple-audio-card";
++
++ simple-audio-card,format = "left_j";
++ simple-audio-card,name = "ak4613";
++
++ simple-audio-card,bitclock-master = <&sndcpu>;
++ simple-audio-card,frame-master = <&sndcpu>;
++
++ sndcpu: simple-audio-card,cpu@1 {
++ sound-dai = <&rcar_sound>;
++ };
++
++ sndcodec: simple-audio-card,codec@1 {
++ sound-dai = <&ak4613>;
++ };
++ };
++
++ lvds {
++ compatible = "panel-lvds";
++
++ width-mm = <210>;
++ height-mm = <158>;
++
++ data-mapping = "jeida-24";
++
++ panel-timing {
++ /* 1280x800 @60Hz */
++ clock-frequency = <65000000>;
++ hactive = <1280>;
++ vactive = <800>;
++ hsync-len = <40>;
++ hfront-porch = <80>;
++ hback-porch = <40>;
++ vfront-porch = <14>;
++ vback-porch = <14>;
++ vsync-len = <4>;
++ };
++
++ port {
++ lvds_in: endpoint {
++ remote-endpoint = <&du_out_lvds0>;
++ };
++ };
++ };
++
++ excan_ref_clk: excan-ref-clock {
++ compatible = "fixed-clock";
++ #clock-cells = <0>;
++ clock-frequency = <16000000>;
++ };
++
++ spi_gpio_sw {
++ compatible = "spi-gpio";
++ #address-cells = <0x1>;
++ #size-cells = <0x0>;
++ gpio-sck = <&gpio0 8 GPIO_ACTIVE_HIGH>;
++ gpio-miso = <&gpio0 10 GPIO_ACTIVE_HIGH>;
++ gpio-mosi = <&gpio0 11 GPIO_ACTIVE_HIGH>;
++ cs-gpios = <&gpio0 9 GPIO_ACTIVE_HIGH>;
++ num-chipselects = <1>;
++
++ spidev: spidev@0 {
++ compatible = "spidev", "spi-gpio";
++ reg = <0>;
++ spi-max-frequency = <25000000>;
++ spi-cpha;
++ spi-cpol;
++ };
++ };
++
++ spi_gpio_can {
++ compatible = "spi-gpio";
++ #address-cells = <0x1>;
++ #size-cells = <0x0>;
++ gpio-sck = <&gpio1 2 GPIO_ACTIVE_HIGH>;
++ gpio-miso = <&gpio1 3 GPIO_ACTIVE_HIGH>;
++ gpio-mosi = <&gpio1 1 GPIO_ACTIVE_HIGH>;
++ cs-gpios = <&gpio1 0 GPIO_ACTIVE_HIGH
++ &gpio1 4 GPIO_ACTIVE_HIGH>;
++ num-chipselects = <2>;
++
++ spican0: spidev@0 {
++ compatible = "microchip,mcp2515";
++ reg = <0>;
++ clocks = <&excan_ref_clk>;
++ interrupt-parent = <&gpio0>;
++ interrupts = <15 GPIO_ACTIVE_LOW>;
++ spi-max-frequency = <10000000>;
++ };
++ spican1: spidev@1 {
++ compatible = "microchip,mcp2515";
++ reg = <1>;
++ clocks = <&excan_ref_clk>;
++ interrupt-parent = <&gpio1>;
++ interrupts = <5 GPIO_ACTIVE_LOW>;
++ spi-max-frequency = <10000000>;
++ };
++ };
++};
++
++&pfc {
++ hscif4_pins: hscif4 {
++ groups = "hscif4_data_a", "hscif4_ctrl";
++ function = "hscif4";
++ };
++
++ /delete-node/sound;
++
++ sound_0_pins: sound1 {
++ groups = "ssi01239_ctrl", "ssi0_data", "ssi1_data_a";
++ function = "ssi";
++ };
++
++ usb0_pins: usb0 {
++ groups = "usb0";
++ function = "usb0";
++ };
++
++ usb2_pins: usb2 {
++ groups = "usb2";
++ function = "usb2";
++ };
++
++ can0_pins: can0 {
++ groups = "can0_data_a";
++ function = "can0";
++ };
++
++ can1_pins: can1 {
++ groups = "can1_data";
++ function = "can1";
++ };
++
++ canfd0_pins: canfd0 {
++ groups = "canfd0_data_a";
++ function = "canfd0";
++ };
++
++ canfd1_pins: canfd1 {
++ groups = "canfd1_data";
++ function = "canfd1";
++ };
++
++ sdhi3_pins: sd3 {
++ groups = "sdhi3_data4", "sdhi3_ctrl";
++ function = "sdhi3";
++ power-source = <3300>;
++ };
++
++ sdhi3_pins_uhs: sd3_uhs {
++ groups = "sdhi3_data4", "sdhi3_ctrl";
++ function = "sdhi3";
++ power-source = <1800>;
++ };
++};
++
++&gpio0 {
++ video_a_irq {
++ gpio-hog;
++ gpios = <12 GPIO_ACTIVE_HIGH>;
++ input;
++ line-name = "Video-A irq";
++ };
++
++ video_b_irq {
++ gpio-hog;
++ gpios = <13 GPIO_ACTIVE_HIGH>;
++ input;
++ line-name = "Video-B irq";
++ };
++
++ video_c_irq {
++ gpio-hog;
++ gpios = <14 GPIO_ACTIVE_HIGH>;
++ input;
++ line-name = "Video-C irq";
++ };
++ can2_irq {
++ gpio-hog;
++ gpios = <15 GPIO_ACTIVE_HIGH>;
++ input;
++ line-name = "CAN2 irq";
++ };
++};
++
++&gpio1 {
++ can3_irq {
++ gpio-hog;
++ gpios = <5 GPIO_ACTIVE_HIGH>;
++ input;
++ line-name = "CAN3 irq";
++ };
++ gpioext_4_22_irq {
++ gpio-hog;
++ gpios = <25 GPIO_ACTIVE_HIGH>;
++ input;
++ line-name = "0x22@i2c4 irq";
++ };
++ m2_0_sleep {
++ gpio-hog;
++ gpios = <6 GPIO_ACTIVE_HIGH>;
++ output-high;
++ line-name = "M2 0 SLEEP#";
++ };
++ m2_1_sleep {
++ gpio-hog;
++ gpios = <7 GPIO_ACTIVE_HIGH>;
++ output-high;
++ line-name = "M2 1 SLEEP#";
++ };
++ m2_0_pcie_det {
++ gpio-hog;
++ gpios = <18 GPIO_ACTIVE_HIGH>;
++ input;
++ line-name = "M.2 0 PCIe/SATA";
++ };
++ m2_1_pcie_det {
++ gpio-hog;
++ gpios = <19 GPIO_ACTIVE_HIGH>;
++ input;
++ line-name = "M.2 1 PCIe/SATA";
++ };
++ m2_1_rst {
++ gpio-hog;
++ gpios = <11 GPIO_ACTIVE_HIGH>;
++ output-high;
++ line-name = "M.2 1 RST#";
++ };
++ switch_ext_phy_reset {
++ gpio-hog;
++ gpios = <16 GPIO_ACTIVE_HIGH>;
++ output-high;
++ line-name = "BR ext phy reset";
++ };
++ switch_sw_reset {
++ gpio-hog;
++ gpios = <17 GPIO_ACTIVE_HIGH>;
++ output-high;
++ line-name = "BR switch reset";
++ };
++ switch_1v2_en {
++ gpio-hog;
++ gpios = <27 GPIO_ACTIVE_HIGH>;
++ output-high;
++ line-name = "BR 1.2V en";
++ };
++};
++
++&gpio2 {
++ m2_0_wake {
++ gpio-hog;
++ gpios = <1 GPIO_ACTIVE_HIGH>;
++ input;
++ line-name = "M.2 0 WAKE#";
++ };
++ m2_0_clkreq {
++ gpio-hog;
++ gpios = <5 GPIO_ACTIVE_HIGH>;
++ input;
++ line-name = "M.2 0 CLKREQ#";
++ };
++ switch_3v3_en {
++ gpio-hog;
++ gpios = <4 GPIO_ACTIVE_HIGH>;
++ output-high;
++ line-name = "BR 3.3V en";
++ };
++};
++
++&gpio3 {
++ switch_int_phy_reset {
++ gpio-hog;
++ gpios = <15 GPIO_ACTIVE_HIGH>;
++ output-high;
++ line-name = "BR int phy reset";
++ };
++};
++
++&gpio5 {
++ switch_2v5_en {
++ gpio-hog;
++ gpios = <7 GPIO_ACTIVE_HIGH>;
++ output-high;
++ line-name = "BR 2.5V en";
++ };
++ switch_25mhz_en {
++ gpio-hog;
++ gpios = <8 GPIO_ACTIVE_HIGH>;
++ output-high;
++ line-name = "BR 25MHz clk en";
++ };
++};
++
++&gpio6 {
++ m2_1_wake {
++ gpio-hog;
++ gpios = <4 GPIO_ACTIVE_HIGH>;
++ input;
++ line-name = "M.2 1 WAKE#";
++ };
++ m2_1_clkreq {
++ gpio-hog;
++ gpios = <10 GPIO_ACTIVE_HIGH>;
++ input;
++ line-name = "M.2 1 CLKREQ#";
++ };
++
++ m2_0_rst {
++ gpio-hog;
++ gpios = <7 GPIO_ACTIVE_HIGH>;
++ output-high;
++ line-name = "M.2 0 RST#";
++ };
++};
++
++&i2c2 {
++ clock-frequency = <400000>;
++
++ i2cswitch2: pca9548@74 {
++ compatible = "nxp,pca9548";
++ #address-cells = <1>;
++ #size-cells = <0>;
++ reg = <0x74>;
++ reset-gpios = <&gpio6 5 GPIO_ACTIVE_LOW>;
++
++ i2c@4 {
++ #address-cells = <1>;
++ #size-cells = <0>;
++ reg = <4>;
++ /* USB3.0 HUB node(s) */
++ /* addr of TUSB8041 is 100.0100 = 0x44 */
++ };
++
++ i2c@1 {
++ #address-cells = <1>;
++ #size-cells = <0>;
++ reg = <1>;
++ /* Slot A (CN10) */
++
++ ov106xx@0 {
++ compatible = "ovti,ov106xx";
++ reg = <0x60>;
++
++ port@0 {
++ ov106xx_in0: endpoint {
++ clock-lanes = <0>;
++ data-lanes = <1 2 3 4>;
++ remote-endpoint = <&vin0ep0>;
++ };
++ };
++ port@1 {
++ ov106xx_max9286_des0ep0: endpoint@0 {
++ remote-endpoint = <&max9286_des0ep0>;
++ };
++ ov106xx_ti9x4_des0ep0: endpoint@1 {
++ remote-endpoint = <&ti9x4_des0ep0>;
++ };
++ };
++ };
++
++ ov106xx@1 {
++ compatible = "ovti,ov106xx";
++ reg = <0x61>;
++
++ port@0 {
++ ov106xx_in1: endpoint {
++ clock-lanes = <0>;
++ data-lanes = <1 2 3 4>;
++ remote-endpoint = <&vin1ep0>;
++ };
++ };
++ port@1 {
++ ov106xx_max9286_des0ep1: endpoint@0 {
++ remote-endpoint = <&max9286_des0ep1>;
++ };
++ ov106xx_ti9x4_des0ep1: endpoint@1 {
++ remote-endpoint = <&ti9x4_des0ep1>;
++ };
++ };
++ };
++
++ ov106xx@2 {
++ compatible = "ovti,ov106xx";
++ reg = <0x62>;
++
++ port@0 {
++ ov106xx_in2: endpoint {
++ clock-lanes = <0>;
++ data-lanes = <1 2 3 4>;
++ remote-endpoint = <&vin2ep0>;
++ };
++ };
++ port@1 {
++ ov106xx_max9286_des0ep2: endpoint@0 {
++ remote-endpoint = <&max9286_des0ep2>;
++ };
++ ov106xx_ti9x4_des0ep2: endpoint@1 {
++ remote-endpoint = <&ti9x4_des0ep2>;
++ };
++ };
++ };
++
++ ov106xx@3 {
++ compatible = "ovti,ov106xx";
++ reg = <0x63>;
++
++ port@0 {
++ ov106xx_in3: endpoint {
++ clock-lanes = <0>;
++ data-lanes = <1 2 3 4>;
++ remote-endpoint = <&vin3ep0>;
++ };
++ };
++ port@1 {
++ ov106xx_max9286_des0ep3: endpoint@0 {
++ remote-endpoint = <&max9286_des0ep3>;
++ };
++ ov106xx_ti9x4_des0ep3: endpoint@1 {
++ remote-endpoint = <&ti9x4_des0ep3>;
++ };
++ };
++ };
++
++ /* DS90UB9x4 @ 0x3a */
++ ti9x4@0 {
++ compatible = "ti,ti9x4";
++ reg = <0x3a>;
++ ti,links = <4>;
++ ti,lanes = <4>;
++ ti,forwarding-mode = "round-robin";
++ ti,cable-mode = "stp";
++
++ POC0-gpios = <&gpio_exp_a_5c 8 GPIO_ACTIVE_HIGH>;
++ POC1-gpios = <&gpio_exp_a_5c 9 GPIO_ACTIVE_HIGH>;
++ POC2-gpios = <&gpio_exp_a_5c 10 GPIO_ACTIVE_HIGH>;
++ POC3-gpios = <&gpio_exp_a_5c 11 GPIO_ACTIVE_HIGH>;
++
++ port@0 {
++ ti9x4_des0ep0: endpoint@0 {
++ ti9x3-addr = <0x0c>;
++ dvp-order = <0>;
++ remote-endpoint = <&ov106xx_in0>;
++ };
++ ti9x4_des0ep1: endpoint@1 {
++ ti9x3-addr = <0x0d>;
++ dvp-order = <0>;
++ remote-endpoint = <&ov106xx_in1>;
++ };
++ ti9x4_des0ep2: endpoint@2 {
++ ti9x3-addr = <0x0e>;
++ dvp-order = <0>;
++ remote-endpoint = <&ov106xx_in2>;
++ };
++ ti9x4_des0ep3: endpoint@3 {
++ ti9x3-addr = <0x0f>;
++ dvp-order = <0>;
++ remote-endpoint = <&ov106xx_in3>;
++ };
++ };
++ port@1 {
++ ti9x4_csi0ep0: endpoint {
++ csi-rate = <1450>;
++ remote-endpoint = <&csi40_ep>;
++ };
++ };
++ };
++
++ /* MAX9286 @ 0x2c */
++ max9286@0 {
++ compatible = "maxim,max9286";
++ reg = <0x2c>;
++ maxim,links = <4>;
++ maxim,lanes = <4>;
++ maxim,resetb-gpio = <1>;
++ maxim,fsync-mode = "automatic";
++ maxim,timeout = <100>;
++
++ POC0-gpios = <&gpio_exp_a_5c 9 GPIO_ACTIVE_HIGH>;
++ POC1-gpios = <&gpio_exp_a_5c 8 GPIO_ACTIVE_HIGH>;
++ POC2-gpios = <&gpio_exp_a_5c 11 GPIO_ACTIVE_HIGH>;
++ POC3-gpios = <&gpio_exp_a_5c 10 GPIO_ACTIVE_HIGH>;
++
++ port@0 {
++ max9286_des0ep0: endpoint@0 {
++ max9271-addr = <0x50>;
++ dvp-order = <1>;
++ remote-endpoint = <&ov106xx_in0>;
++ };
++ max9286_des0ep1: endpoint@1 {
++ max9271-addr = <0x51>;
++ dvp-order = <1>;
++ remote-endpoint = <&ov106xx_in1>;
++ };
++ max9286_des0ep2: endpoint@2 {
++ max9271-addr = <0x52>;
++ dvp-order = <1>;
++ remote-endpoint = <&ov106xx_in2>;
++ };
++ max9286_des0ep3: endpoint@3 {
++ max9271-addr = <0x53>;
++ dvp-order = <1>;
++ remote-endpoint = <&ov106xx_in3>;
++ };
++ };
++ port@1 {
++ max9286_csi0ep0: endpoint {
++ csi-rate = <700>;
++ remote-endpoint = <&csi40_ep>;
++ };
++ };
++ };
++ };
++
++ i2c@3 {
++ #address-cells = <1>;
++ #size-cells = <0>;
++ reg = <3>;
++ /* Slot B (CN11) */
++
++ ov106xx@4 {
++ compatible = "ovti,ov106xx";
++ reg = <0x64>;
++
++ port@0 {
++ ov106xx_in4: endpoint {
++ clock-lanes = <0>;
++ data-lanes = <1 2 3 4>;
++ remote-endpoint = <&vin4ep0>;
++ };
++ };
++ port@1 {
++ ov106xx_max9286_des1ep0: endpoint@0 {
++ remote-endpoint = <&max9286_des1ep0>;
++ };
++ ov106xx_ti9x4_des1ep0: endpoint@1 {
++ remote-endpoint = <&ti9x4_des1ep0>;
++ };
++ };
++ };
++
++ ov106xx@5 {
++ compatible = "ovti,ov106xx";
++ reg = <0x65>;
++
++ port@0 {
++ ov106xx_in5: endpoint {
++ clock-lanes = <0>;
++ data-lanes = <1 2 3 4>;
++ remote-endpoint = <&vin5ep0>;
++ };
++ };
++ port@1 {
++ ov106xx_max9286_des1ep1: endpoint@0 {
++ remote-endpoint = <&max9286_des1ep1>;
++ };
++ ov106xx_ti9x4_des1ep1: endpoint@1 {
++ remote-endpoint = <&ti9x4_des1ep1>;
++ };
++ };
++ };
++
++ ov106xx@6 {
++ compatible = "ovti,ov106xx";
++ reg = <0x66>;
++
++ port@0 {
++ ov106xx_in6: endpoint {
++ clock-lanes = <0>;
++ data-lanes = <1 2 3 4>;
++ remote-endpoint = <&vin6ep0>;
++ };
++ };
++ port@1 {
++ ov106xx_max9286_des1ep2: endpoint@0 {
++ remote-endpoint = <&max9286_des1ep2>;
++ };
++ ov106xx_ti9x4_des1ep2: endpoint@1 {
++ remote-endpoint = <&ti9x4_des1ep2>;
++ };
++ };
++ };
++
++ ov106xx@7 {
++ compatible = "ovti,ov106xx";
++ reg = <0x67>;
++
++ port@0 {
++ ov106xx_in7: endpoint {
++ clock-lanes = <0>;
++ data-lanes = <1 2 3 4>;
++ remote-endpoint = <&vin7ep0>;
++ };
++ };
++ port@1 {
++ ov106xx_max9286_des1ep3: endpoint@0 {
++ remote-endpoint = <&max9286_des1ep3>;
++ };
++ ov106xx_ti9x4_des1ep3: endpoint@1 {
++ remote-endpoint = <&ti9x4_des1ep3>;
++ };
++ };
++ };
++
++ /* DS90UB9x4 @ 0x3a */
++ ti9x4@1 {
++ compatible = "ti,ti9x4";
++ reg = <0x3a>;
++ ti,links = <4>;
++ ti,lanes = <4>;
++ ti,forwarding-mode = "round-robin";
++ ti,cable-mode = "stp";
++
++ POC0-gpios = <&gpio_exp_b_5c 8 GPIO_ACTIVE_HIGH>;
++ POC1-gpios = <&gpio_exp_b_5c 9 GPIO_ACTIVE_HIGH>;
++ POC2-gpios = <&gpio_exp_b_5c 10 GPIO_ACTIVE_HIGH>;
++ POC3-gpios = <&gpio_exp_b_5c 11 GPIO_ACTIVE_HIGH>;
++
++ port@0 {
++ ti9x4_des1ep0: endpoint@0 {
++ ti9x3-addr = <0x0c>;
++ dvp-order = <0>;
++ remote-endpoint = <&ov106xx_in4>;
++ };
++ ti9x4_des1ep1: endpoint@1 {
++ ti9x3-addr = <0x0d>;
++ dvp-order = <0>;
++ remote-endpoint = <&ov106xx_in5>;
++ };
++ ti9x4_des1ep2: endpoint@2 {
++ ti9x3-addr = <0x0e>;
++ dvp-order = <0>;
++ remote-endpoint = <&ov106xx_in6>;
++ };
++ ti9x4_des1ep3: endpoint@3 {
++ ti9x3-addr = <0x0f>;
++ dvp-order = <0>;
++ remote-endpoint = <&ov106xx_in7>;
++ };
++ };
++ port@1 {
++ ti9x4_csi2ep0: endpoint {
++ csi-rate = <1450>;
++ remote-endpoint = <&csi41_ep>;
++ };
++ };
++ };
++
++ /* MAX9286 @ 0x2c */
++ max9286@1 {
++ compatible = "maxim,max9286";
++ reg = <0x2c>;
++ maxim,links = <4>;
++ maxim,lanes = <4>;
++ maxim,resetb-gpio = <1>;
++ maxim,fsync-mode = "automatic";
++ maxim,timeout = <100>;
++
++ POC0-gpios = <&gpio_exp_b_5c 9 GPIO_ACTIVE_HIGH>;
++ POC1-gpios = <&gpio_exp_b_5c 8 GPIO_ACTIVE_HIGH>;
++ POC2-gpios = <&gpio_exp_b_5c 11 GPIO_ACTIVE_HIGH>;
++ POC3-gpios = <&gpio_exp_b_5c 10 GPIO_ACTIVE_HIGH>;
++
++ port@0 {
++ max9286_des1ep0: endpoint@0 {
++ max9271-addr = <0x50>;
++ dvp-order = <1>;
++ remote-endpoint = <&ov106xx_in4>;
++ };
++ max9286_des1ep1: endpoint@1 {
++ max9271-addr = <0x51>;
++ dvp-order = <1>;
++ remote-endpoint = <&ov106xx_in5>;
++ };
++ max9286_des1ep2: endpoint@2 {
++ max9271-addr = <0x52>;
++ dvp-order = <1>;
++ remote-endpoint = <&ov106xx_in6>;
++ };
++ max9286_des1ep3: endpoint@3 {
++ max9271-addr = <0x53>;
++ dvp-order = <1>;
++ remote-endpoint = <&ov106xx_in7>;
++ };
++ };
++ port@1 {
++ max9286_csi2ep0: endpoint {
++ csi-rate = <700>;
++ remote-endpoint = <&csi41_ep>;
++ };
++ };
++ };
++ };
++
++ i2c@7 {
++ #address-cells = <1>;
++ #size-cells = <0>;
++ reg = <7>;
++ /* Slot C (CN12) */
++ };
++
++ i2c@0 {
++ #address-cells = <1>;
++ #size-cells = <0>;
++ reg = <0>;
++ /* Slot A (CN10) */
++
++ /* PCA9535 is a redundant/deprecated card */
++ gpio_exp_a_26: gpio@26 {
++ compatible = "nxp,pca9535";
++ reg = <0x26>;
++ gpio-controller;
++ #gpio-cells = <2>;
++
++ video_a_pwr_shdn {
++ gpio-hog;
++ gpios = <3 GPIO_ACTIVE_HIGH>;
++ output-high;
++ line-name = "Video-A PWR_SHDN";
++ };
++ video_a_cam_pwr0 {
++ gpio-hog;
++ gpios = <12 GPIO_ACTIVE_HIGH>;
++ output-high;
++ line-name = "Video-A PWR0";
++ };
++ video_a_cam_pwr1 {
++ gpio-hog;
++ gpios = <13 GPIO_ACTIVE_HIGH>;
++ output-high;
++ line-name = "Video-A PWR1";
++ };
++ video_a_cam_pwr2 {
++ gpio-hog;
++ gpios = <14 GPIO_ACTIVE_HIGH>;
++ output-high;
++ line-name = "Video-A PWR2";
++ };
++ video_a_cam_pwr3 {
++ gpio-hog;
++ gpios = <15 GPIO_ACTIVE_HIGH>;
++ output-high;
++ line-name = "Video-A PWR3";
++ };
++ video_a_des_shdn {
++ gpio-hog;
++ gpios = <4 GPIO_ACTIVE_HIGH>;
++ output-high;
++ line-name = "Video-A DES_SHDN";
++ };
++ video_a_des_led {
++ gpio-hog;
++ gpios = <7 GPIO_ACTIVE_HIGH>;
++ output-low;
++ line-name = "Video-A led";
++ };
++ };
++
++ gpio_exp_a_5c: gpio@5c {
++ compatible = "maxim,max7325";
++ reg = <0x5c>;
++ gpio-controller;
++ #gpio-cells = <2>;
++
++ video_a_des_cfg0 {
++ gpio-hog;
++ gpios = <7 GPIO_ACTIVE_HIGH>;
++ input;
++ line-name = "Video-A cfg0";
++ };
++ video_a_pwr_shdn {
++ gpio-hog;
++ gpios = <14 GPIO_ACTIVE_HIGH>;
++ output-high;
++ line-name = "Video-A PWR_SHDN";
++ };
++ video_a_des_shdn {
++ gpio-hog;
++ gpios = <13 GPIO_ACTIVE_HIGH>;
++ output-high;
++ line-name = "Video-A DES_SHDN";
++ };
++ video_a_led {
++ gpio-hog;
++ gpios = <12 GPIO_ACTIVE_HIGH>;
++ output-low;
++ line-name = "Video-A LED";
++ };
++ };
++ };
++
++ i2c@2 {
++ #address-cells = <1>;
++ #size-cells = <0>;
++ reg = <2>;
++ /* Slot B (CN11) */
++
++ /* PCA9535 is a redundant/deprecated card */
++ gpio_exp_b_26: gpio@26 {
++ compatible = "nxp,pca9535";
++ reg = <0x26>;
++ gpio-controller;
++ #gpio-cells = <2>;
++
++ video_b_des_cfg1 {
++ gpio-hog;
++ gpios = <5 GPIO_ACTIVE_HIGH>;
++ input;
++ line-name = "Video-B cfg1";
++ };
++ video_b_des_cfg0 {
++ gpio-hog;
++ gpios = <6 GPIO_ACTIVE_HIGH>;
++ input;
++ line-name = "Video-B cfg0";
++ };
++ video_b_pwr_shdn {
++ gpio-hog;
++ gpios = <3 GPIO_ACTIVE_HIGH>;
++ output-high;
++ line-name = "Video-B PWR_SHDN";
++ };
++ video_b_cam_pwr0 {
++ gpio-hog;
++ gpios = <12 GPIO_ACTIVE_HIGH>;
++ output-high;
++ line-name = "Video-B PWR0";
++ };
++ video_b_cam_pwr1 {
++ gpio-hog;
++ gpios = <13 GPIO_ACTIVE_HIGH>;
++ output-high;
++ line-name = "Video-B PWR1";
++ };
++ video_b_cam_pwr2 {
++ gpio-hog;
++ gpios = <14 GPIO_ACTIVE_HIGH>;
++ output-high;
++ line-name = "Video-B PWR2";
++ };
++ video_b_cam_pwr3 {
++ gpio-hog;
++ gpios = <15 GPIO_ACTIVE_HIGH>;
++ output-high;
++ line-name = "Video-B PWR3";
++ };
++ video_b_des_shdn {
++ gpio-hog;
++ gpios = <4 GPIO_ACTIVE_HIGH>;
++ output-high;
++ line-name = "Video-B DES_SHDN";
++ };
++ video_b_des_led {
++ gpio-hog;
++ gpios = <7 GPIO_ACTIVE_HIGH>;
++ output-low;
++ line-name = "Video-B led";
++ };
++ };
++
++ gpio_exp_b_5c: gpio@5c {
++ compatible = "maxim,max7325";
++ reg = <0x5c>;
++ gpio-controller;
++ #gpio-cells = <2>;
++
++ video_b_des_cfg2 {
++ gpio-hog;
++ gpios = <4 GPIO_ACTIVE_HIGH>;
++ input;
++ line-name = "Video-B cfg2";
++ };
++ video_b_des_cfg1 {
++ gpio-hog;
++ gpios = <6 GPIO_ACTIVE_HIGH>;
++ input;
++ line-name = "Video-B cfg1";
++ };
++ video_b_des_cfg0 {
++ gpio-hog;
++ gpios = <7 GPIO_ACTIVE_HIGH>;
++ input;
++ line-name = "Video-B cfg0";
++ };
++ video_b_pwr_shdn {
++ gpio-hog;
++ gpios = <14 GPIO_ACTIVE_HIGH>;
++ output-high;
++ line-name = "Video-B PWR_SHDN";
++ };
++ video_b_des_shdn {
++ gpio-hog;
++ gpios = <13 GPIO_ACTIVE_HIGH>;
++ output-high;
++ line-name = "Video-B DES_SHDN";
++ };
++ video_b_led {
++ gpio-hog;
++ gpios = <12 GPIO_ACTIVE_HIGH>;
++ output-low;
++ line-name = "Video-B LED";
++ };
++ };
++ };
++
++ i2c@5 {
++ #address-cells = <1>;
++ #size-cells = <0>;
++ reg = <5>;
++ /* Slot C (CN12) */
++ };
++ };
++};
++
++&i2c4 {
++ i2cswitch4: pca9548@74 {
++ compatible = "nxp,pca9548";
++ #address-cells = <1>;
++ #size-cells = <0>;
++ reg = <0x74>;
++ reset-gpios= <&gpio5 15 GPIO_ACTIVE_LOW>;
++
++ i2c@0 {
++ #address-cells = <1>;
++ #size-cells = <0>;
++ reg = <0>;
++ /* FAN1 node - lm96063 */
++ fan_ctrl_1:lm96063-1@4c {
++ compatible = "lm96163";
++ reg = <0x4c>;
++ };
++ };
++
++ i2c@6 {
++ /* FAN2 */
++ #address-cells = <1>;
++ #size-cells = <0>;
++ reg = <6>;
++ /* FAN2 node - lm96063 */
++ fan_ctrl_2:lm96063-2@4c {
++ compatible = "lm96163";
++ reg = <0x4c>;
++ };
++ };
++
++ i2c@1 {
++ #address-cells = <1>;
++ #size-cells = <0>;
++ reg = <1>;
++
++ /* Power nodes - 2 x TPS544x20 */
++ tps_5v: tps544c20@0x2a {
++ compatible = "tps544c20";
++ reg = <0x2c>;
++ status = "disabled";
++ };
++ tps_3v3: tps544c20@0x22 {
++ compatible = "tps544c20";
++ reg = <0x24>;
++ status = "disabled";
++ };
++ };
++
++ i2c@2 {
++ #address-cells = <1>;
++ #size-cells = <0>;
++ reg = <2>;
++ /* CAN and power board nodes */
++
++ gpio_ext_pwr: pca9535@22 {
++ compatible = "nxp,pca9535";
++ reg = <0x22>;
++ gpio-controller;
++ #gpio-cells = <2>;
++ interrupt-controller;
++ interrupt-parent = <&gpio1>;
++ interrupts = <25 IRQ_TYPE_EDGE_FALLING>;
++
++ /* enable input DCDC after wake-up signal released */
++ pwr_hold {
++ gpio-hog;
++ gpios = <11 GPIO_ACTIVE_HIGH>;
++ output-high;
++ line-name = "pwr_hold";
++ };
++ pwr_5v_out {
++ gpio-hog;
++ gpios = <14 GPIO_ACTIVE_HIGH>;
++ output-high;
++ line-name = "pwr_5v_out";
++ };
++ pwr_5v_oc {
++ gpio-hog;
++ gpios = <15 GPIO_ACTIVE_HIGH>;
++ input;
++ line-name = "pwr_5v_oc";
++ };
++ pwr_wake8 {
++ gpio-hog;
++ gpios = <12 GPIO_ACTIVE_HIGH>;
++ input;
++ line-name = "wake8";
++ };
++ pwr_wake7 {
++ gpio-hog;
++ gpios = <13 GPIO_ACTIVE_HIGH>;
++ input;
++ line-name = "wake7";
++ };
++
++ /* CAN0 */
++ can0_stby {
++ gpio-hog;
++ gpios = <4 GPIO_ACTIVE_HIGH>;
++ output-low;
++ line-name = "can0_stby";
++ };
++ can0_load {
++ gpio-hog;
++ gpios = <0 GPIO_ACTIVE_HIGH>;
++ output-high;
++ line-name = "can0_120R_load";
++ };
++ /* CAN1 */
++ can1_stby {
++ gpio-hog;
++ gpios = <5 GPIO_ACTIVE_HIGH>;
++ output-low;
++ line-name = "can1_stby";
++ };
++ can1_load {
++ gpio-hog;
++ gpios = <1 GPIO_ACTIVE_HIGH>;
++ output-high;
++ line-name = "can1_120R_load";
++ };
++ /* CAN2 */
++ can2_stby {
++ gpio-hog;
++ gpios = <6 GPIO_ACTIVE_HIGH>;
++ output-low;
++ line-name = "can2_stby";
++ };
++ can2_load {
++ gpio-hog;
++ gpios = <2 GPIO_ACTIVE_HIGH>;
++ output-high;
++ line-name = "can2_120R_load";
++ };
++ can2_rst {
++ gpio-hog;
++ gpios = <8 GPIO_ACTIVE_HIGH>;
++ output-high;
++ line-name = "can2_rst";
++ };
++ /* CAN3 */
++ can3_stby {
++ gpio-hog;
++ gpios = <7 GPIO_ACTIVE_HIGH>;
++ output-low;
++ line-name = "can3_stby";
++ };
++ can3_load {
++ gpio-hog;
++ gpios = <3 GPIO_ACTIVE_HIGH>;
++ output-high;
++ line-name = "can3_120R_load";
++ };
++ can3_rst {
++ gpio-hog;
++ gpios = <9 GPIO_ACTIVE_HIGH>;
++ output-high;
++ line-name = "can3_rst";
++ };
++ };
++ };
++
++ i2c@3 {
++ #address-cells = <1>;
++ #size-cells = <0>;
++ reg = <3>;
++ /* FPDLink output node - DS90UH947 */
++ };
++
++ i2c@4 {
++ #address-cells = <1>;
++ #size-cells = <0>;
++ reg = <4>;
++ /* BCM switch node */
++ };
++
++ i2c@5 {
++ #address-cells = <1>;
++ #size-cells = <0>;
++ reg = <5>;
++ /* LED board node(s) */
++
++ gpio_ext_led: pca9535@22 {
++ compatible = "nxp,pca9535";
++ reg = <0x22>;
++ gpio-controller;
++ #gpio-cells = <2>;
++
++ /* gpios 0..7 are used for indication LEDs, low-active */
++ };
++ rtc: mcp79411@6f {
++ compatible = "microchip,mcp7941x";
++ reg = <0x6f>;
++ };
++ };
++
++ /* port 7 is not used */
++ };
++};
++
++&pcie_bus_clk {
++ clock-frequency = <100000000>;
++ status = "okay";
++};
++
++&pciec0 {
++ status = "okay";
++};
++
++&pciec1 {
++ status = "okay";
++};
++
++&vin0 {
++ status = "okay";
++
++ ports {
++ #address-cells = <1>;
++ #size-cells = <0>;
++
++ port@0 {
++ vin0ep0: endpoint {
++ csi,select = "csi40";
++ virtual,channel = <0>;
++ data-lanes = <1 2 3 4>;
++ remote-endpoint = <&ov106xx_in0>;
++ };
++ };
++ port@1 {
++ csi0ep0: endpoint {
++ remote-endpoint = <&csi40_ep>;
++ };
++ };
++ port@2 {
++ vin0_max9286_des0ep0: endpoint@0 {
++ remote-endpoint = <&max9286_des0ep0>;
++ };
++ vin0_ti9x4_des0ep0: endpoint@1 {
++ remote-endpoint = <&ti9x4_des0ep0>;
++ };
++ };
++ };
++};
++
++&vin1 {
++ status = "okay";
++
++ ports {
++ #address-cells = <1>;
++ #size-cells = <0>;
++
++ port@0 {
++ vin1ep0: endpoint {
++ csi,select = "csi40";
++ virtual,channel = <1>;
++ data-lanes = <1 2 3 4>;
++ remote-endpoint = <&ov106xx_in1>;
++ };
++ };
++ port@1 {
++ csi0ep1: endpoint {
++ remote-endpoint = <&csi40_ep>;
++ };
++ };
++ port@2 {
++ vin1_max9286_des0ep1: endpoint@0 {
++ remote-endpoint = <&max9286_des0ep1>;
++ };
++ vin1_ti9x4_des0ep1: endpoint@1 {
++ remote-endpoint = <&ti9x4_des0ep1>;
++ };
++ };
++ };
++};
++
++&vin2 {
++ status = "okay";
++
++ ports {
++ #address-cells = <1>;
++ #size-cells = <0>;
++
++ port@0 {
++ vin2ep0: endpoint {
++ csi,select = "csi40";
++ virtual,channel = <2>;
++ data-lanes = <1 2 3 4>;
++ remote-endpoint = <&ov106xx_in2>;
++ };
++ };
++ port@1 {
++ csi0ep2: endpoint {
++ remote-endpoint = <&csi40_ep>;
++ };
++ };
++ port@2 {
++ vin2_max9286_des0ep2: endpoint@0 {
++ remote-endpoint = <&max9286_des0ep2>;
++ };
++ vin2_ti9x4_des0ep2: endpoint@1 {
++ remote-endpoint = <&ti9x4_des0ep2>;
++ };
++ };
++ };
++};
++
++&vin3 {
++ status = "okay";
++
++ ports {
++ #address-cells = <1>;
++ #size-cells = <0>;
++
++ port@0 {
++ vin3ep0: endpoint {
++ csi,select = "csi40";
++ virtual,channel = <3>;
++ data-lanes = <1 2 3 4>;
++ remote-endpoint = <&ov106xx_in3>;
++ };
++ };
++ port@1 {
++ csi0ep3: endpoint {
++ remote-endpoint = <&csi40_ep>;
++ };
++ };
++ port@2 {
++ vin3_max9286_des0ep3: endpoint@0 {
++ remote-endpoint = <&max9286_des0ep3>;
++ };
++ vin3_ti9x4_des0ep3: endpoint@1 {
++ remote-endpoint = <&ti9x4_des0ep3>;
++ };
++ };
++ };
++};
++
++&vin4 {
++ status = "okay";
++
++ ports {
++ #address-cells = <1>;
++ #size-cells = <0>;
++
++ port@0 {
++ vin4ep0: endpoint {
++ csi,select = "csi41";
++ virtual,channel = <0>;
++ remote-endpoint = <&ov106xx_in4>;
++ data-lanes = <1 2 3 4>;
++ };
++ };
++ port@1 {
++ csi2ep0: endpoint {
++ remote-endpoint = <&csi41_ep>;
++ };
++ };
++ port@2 {
++ vin4_max9286_des1ep0: endpoint@0 {
++ remote-endpoint = <&max9286_des1ep0>;
++ };
++ vin4_ti9x4_des1ep0: endpoint@1 {
++ remote-endpoint = <&ti9x4_des1ep0>;
++ };
++ };
++ };
++};
++
++&vin5 {
++ status = "okay";
++
++ ports {
++ #address-cells = <1>;
++ #size-cells = <0>;
++
++ port@0 {
++ vin5ep0: endpoint@0 {
++ csi,select = "csi41";
++ virtual,channel = <1>;
++ remote-endpoint = <&ov106xx_in5>;
++ data-lanes = <1 2 3 4>;
++ };
++ };
++ port@1 {
++ csi2ep1: endpoint {
++ remote-endpoint = <&csi41_ep>;
++ };
++ };
++ port@2 {
++ vin5_max9286_des1ep1: endpoint@0 {
++ remote-endpoint = <&max9286_des1ep1>;
++ };
++ vin5_ti9x4_des1ep1: endpoint@1 {
++ remote-endpoint = <&ti9x4_des1ep1>;
++ };
++ };
++ };
++};
++
++&vin6 {
++ status = "okay";
++
++ ports {
++ #address-cells = <1>;
++ #size-cells = <0>;
++
++ port@0 {
++ vin6ep0: endpoint@0 {
++ csi,select = "csi41";
++ virtual,channel = <2>;
++ remote-endpoint = <&ov106xx_in6>;
++ data-lanes = <1 2 3 4>;
++ };
++ };
++ port@1 {
++ csi2ep2: endpoint {
++ remote-endpoint = <&csi41_ep>;
++ };
++ };
++ port@2 {
++ vin6_max9286_des1ep2: endpoint@0 {
++ remote-endpoint = <&max9286_des1ep2>;
++ };
++ vin6_ti9x4_des1ep2: endpoint@1 {
++ remote-endpoint = <&ti9x4_des1ep2>;
++ };
++ };
++ };
++};
++
++&vin7 {
++ status = "okay";
++
++ ports {
++ #address-cells = <1>;
++ #size-cells = <0>;
++
++ port@0 {
++ vin7ep0: endpoint@0 {
++ csi,select = "csi41";
++ virtual,channel = <3>;
++ remote-endpoint = <&ov106xx_in7>;
++ data-lanes = <1 2 3 4>;
++ };
++ };
++ port@1 {
++ csi2ep3: endpoint {
++ remote-endpoint = <&csi41_ep>;
++ };
++ };
++ port@2 {
++ vin7_max9286_des1ep3: endpoint@0 {
++ remote-endpoint = <&max9286_des1ep3>;
++ };
++ vin7_ti9x4_des1ep3: endpoint@1 {
++ remote-endpoint = <&ti9x4_des1ep3>;
++ };
++ };
++ };
++};
++
++&csi40 {
++ status = "okay";
++
++ virtual,channel {
++ csi2_vc0 {
++ data,type = "ycbcr422";
++ receive,vc = <0>;
++ };
++ csi2_vc1 {
++ data,type = "ycbcr422";
++ receive,vc = <1>;
++ };
++ csi2_vc2 {
++ data,type = "ycbcr422";
++ receive,vc = <2>;
++ };
++ csi2_vc3 {
++ data,type = "ycbcr422";
++ receive,vc = <3>;
++ };
++ };
++
++ port {
++ #address-cells = <1>;
++ #size-cells = <0>;
++
++ csi40_ep: endpoint {
++ clock-lanes = <0>;
++ data-lanes = <1 2 3 4>;
++ csi-rate = <300>;
++ };
++ };
++};
++
++&csi41 {
++ status = "okay";
++
++ virtual,channel {
++ csi2_vc0 {
++ data,type = "ycbcr422";
++ receive,vc = <0>;
++ };
++ csi2_vc1 {
++ data,type = "ycbcr422";
++ receive,vc = <1>;
++ };
++ csi2_vc2 {
++ data,type = "ycbcr422";
++ receive,vc = <2>;
++ };
++ csi2_vc3 {
++ data,type = "ycbcr422";
++ receive,vc = <3>;
++ };
++ };
++
++ port {
++ #address-cells = <1>;
++ #size-cells = <0>;
++
++ csi41_ep: endpoint {
++ clock-lanes = <0>;
++ data-lanes = <1 2 3 4>;
++ csi-rate = <300>;
++ };
++ };
++};
++
++&rcar_sound {
++ pinctrl-0 = <&sound_clk_pins>;
++
++ /* Multi DAI */
++ #sound-dai-cells = <1>;
++};
++
++&ssi1 {
++ /delete-property/shared-pin;
++};
++
++&sdhi3 {
++ pinctrl-0 = <&sdhi3_pins>;
++ pinctrl-1 = <&sdhi3_pins_uhs>;
++ pinctrl-names = "default", "state_uhs";
++
++ vmmc-supply = <&vcc_sdhi3>;
++ vqmmc-supply = <&vccq_sdhi3>;
++ cd-gpios = <&gpio4 15 GPIO_ACTIVE_LOW>;
++ wp-gpios = <&gpio4 16 GPIO_ACTIVE_HIGH>;
++ bus-width = <4>;
++ sd-uhs-sdr50;
++ status = "okay";
++};
++
++&msiof1 {
++ status = "disabled";
++};
++
++&usb2_phy0 {
++ pinctrl-0 = <&usb0_pins>;
++ pinctrl-names = "default";
++
++ status = "okay";
++};
++
++&usb2_phy2 {
++ pinctrl-0 = <&usb2_pins>;
++ pinctrl-names = "default";
++
++ status = "okay";
++};
++
++&xhci0 {
++ status = "okay";
++};
++
++&ehci0 {
++ status = "okay";
++};
++
++&ehci2 {
++ status = "okay";
++};
++
++&ohci0 {
++ status = "okay";
++};
++
++&ohci2 {
++ status = "okay";
++};
++
++&can0 {
++ pinctrl-0 = <&can0_pins>;
++ pinctrl-names = "default";
++ status = "okay";
++
++ renesas,can-clock-select = <0x0>;
++};
++
++&can1 {
++ pinctrl-0 = <&can1_pins>;
++ pinctrl-names = "default";
++ status = "okay";
++
++ renesas,can-clock-select = <0x0>;
++};
++
++&canfd {
++ pinctrl-0 = <&canfd0_pins &canfd1_pins>;
++ pinctrl-names = "default";
++ status = "disabled";
++
++ renesas,can-clock-select = <0x0>;
++
++ channel0 {
++ status = "okay";
++ };
++
++ channel1 {
++ status = "okay";
++ };
++};
++
++/* uncomment to enable CN12 on VIN4-7 */
++//#include "ulcb-vb2-cn12.dtsi"
+diff --git a/arch/arm64/boot/dts/renesas/ulcb-vbm.dtsi b/arch/arm64/boot/dts/renesas/ulcb-vbm.dtsi
+new file mode 100644
+index 0000000..067607a
+--- /dev/null
++++ b/arch/arm64/boot/dts/renesas/ulcb-vbm.dtsi
+@@ -0,0 +1,523 @@
++/*
++ * Device Tree Source for the ULCB Videobox Mini board
++ *
++ * Copyright (C) 2017 Cogent Embedded, Inc.
++ *
++ * This file is licensed under the terms of the GNU General Public License
++ * version 2. This program is licensed "as is" without any warranty of any
++ * kind, whether express or implied.
++ */
++
++/ {
++ aliases {
++ serial1 = &scif1;
++ };
++
++ lvds {
++ compatible = "panel-lvds";
++
++ width-mm = <210>;
++ height-mm = <158>;
++
++ data-mapping = "jeida-24";
++
++ panel-timing {
++ /* 1280x800 @60Hz */
++ clock-frequency = <65000000>;
++ hactive = <1280>;
++ vactive = <800>;
++ hsync-len = <40>;
++ hfront-porch = <80>;
++ hback-porch = <40>;
++ vfront-porch = <14>;
++ vback-porch = <14>;
++ vsync-len = <4>;
++ };
++
++ port {
++ lvds_in: endpoint {
++ remote-endpoint = <&du_out_lvds0>;
++ };
++ };
++ };
++};
++
++&can0 {
++ pinctrl-0 = <&can0_pins>;
++ pinctrl-names = "default";
++ status = "okay";
++};
++
++&can1 {
++ pinctrl-0 = <&can1_pins>;
++ pinctrl-names = "default";
++ status = "okay";
++};
++
++&canfd {
++ pinctrl-0 = <&canfd0_pins &canfd1_pins>;
++ pinctrl-names = "default";
++ status = "disabled";
++
++ channel0 {
++ status = "okay";
++ };
++
++ channel1 {
++ status = "okay";
++ };
++};
++
++&csi41 {
++ status = "okay";
++
++ virtual,channel {
++ csi2_vc0 {
++ data,type = "ycbcr422";
++ receive,vc = <0>;
++ };
++ csi2_vc1 {
++ data,type = "ycbcr422";
++ receive,vc = <1>;
++ };
++ csi2_vc2 {
++ data,type = "ycbcr422";
++ receive,vc = <2>;
++ };
++ csi2_vc3 {
++ data,type = "ycbcr422";
++ receive,vc = <3>;
++ };
++ };
++
++ port {
++ #address-cells = <1>;
++ #size-cells = <0>;
++
++ csi41_ep: endpoint {
++ clock-lanes = <0>;
++ data-lanes = <1 2 3 4>;
++ csi-rate = <300>;
++ };
++ };
++};
++
++&i2c1 {
++ pinctrl-0 = <&i2c1_pins>;
++ pinctrl-names = "default";
++ status = "okay";
++
++ clock-frequency = <400000>;
++
++ i2cswitch1: i2c-switch@74 {
++ compatible = "nxp,pca9548";
++ #address-cells = <1>;
++ #size-cells = <0>;
++ reg = <0x74>;
++ reset-gpios = <&gpio5 25 GPIO_ACTIVE_LOW>;
++
++ i2c@0 {
++ #address-cells = <1>;
++ #size-cells = <0>;
++ reg = <0>;
++
++ ov106xx@0 {
++ compatible = "ovti,ov106xx";
++ reg = <0x60>;
++
++ port@0 {
++ ov106xx_in0: endpoint {
++ clock-lanes = <0>;
++ data-lanes = <1 2 3 4>;
++ remote-endpoint = <&vin4ep0>;
++ };
++ };
++ port@1 {
++ ov106xx_max9286_des0ep0: endpoint@0 {
++ remote-endpoint = <&max9286_des0ep0>;
++ };
++ ov106xx_ti9x4_des0ep0: endpoint@1 {
++ remote-endpoint = <&ti9x4_des0ep0>;
++ };
++ };
++ };
++
++ ov106xx@1 {
++ compatible = "ovti,ov106xx";
++ reg = <0x61>;
++
++ port@0 {
++ ov106xx_in1: endpoint {
++ clock-lanes = <0>;
++ data-lanes = <1 2 3 4>;
++ remote-endpoint = <&vin5ep0>;
++ };
++ };
++ port@1 {
++ ov106xx_max9286_des0ep1: endpoint@0 {
++ remote-endpoint = <&max9286_des0ep1>;
++ };
++ ov106xx_ti9x4_des0ep1: endpoint@1 {
++ remote-endpoint = <&ti9x4_des0ep1>;
++ };
++ };
++ };
++
++ ov106xx@2 {
++ compatible = "ovti,ov106xx";
++ reg = <0x62>;
++
++ port@0 {
++ ov106xx_in2: endpoint {
++ clock-lanes = <0>;
++ data-lanes = <1 2 3 4>;
++ remote-endpoint = <&vin6ep0>;
++ };
++ };
++ port@1 {
++ ov106xx_max9286_des0ep2: endpoint@0 {
++ remote-endpoint = <&max9286_des0ep2>;
++ };
++ ov106xx_ti9x4_des0ep2: endpoint@1 {
++ remote-endpoint = <&ti9x4_des0ep2>;
++ };
++ };
++ };
++
++ ov106xx@3 {
++ compatible = "ovti,ov106xx";
++ reg = <0x63>;
++
++ port@0 {
++ ov106xx_in3: endpoint {
++ clock-lanes = <0>;
++ data-lanes = <1 2 3 4>;
++ remote-endpoint = <&vin7ep0>;
++ };
++ };
++ port@1 {
++ ov106xx_max9286_des0ep3: endpoint@0 {
++ remote-endpoint = <&max9286_des0ep3>;
++ };
++ ov106xx_ti9x4_des0ep3: endpoint@1 {
++ remote-endpoint = <&ti9x4_des0ep3>;
++ };
++ };
++ };
++
++ max9286@0 {
++ compatible = "maxim,max9286";
++ reg = <0x2c>;
++ maxim,links = <4>;
++ maxim,lanes = <4>;
++ maxim,resetb-gpio = <1>;
++ maxim,fsync-mode = "automatic";
++ maxim,timeout = <100>;
++
++ POC0-gpios = <&gpio_exp_6c 8 GPIO_ACTIVE_HIGH>;
++ POC1-gpios = <&gpio_exp_6c 9 GPIO_ACTIVE_HIGH>;
++ POC2-gpios = <&gpio_exp_6c 10 GPIO_ACTIVE_HIGH>;
++ POC3-gpios = <&gpio_exp_6c 11 GPIO_ACTIVE_HIGH>;
++
++ port@0 {
++ max9286_des0ep0: endpoint@0 {
++ max9271-addr = <0x50>;
++ dvp-order = <1>;
++ remote-endpoint = <&ov106xx_in0>;
++ };
++ max9286_des0ep1: endpoint@1 {
++ max9271-addr = <0x51>;
++ dvp-order = <1>;
++ remote-endpoint = <&ov106xx_in1>;
++ };
++ max9286_des0ep2: endpoint@2 {
++ max9271-addr = <0x52>;
++ dvp-order = <1>;
++ remote-endpoint = <&ov106xx_in2>;
++ };
++ max9286_des0ep3: endpoint@3 {
++ max9271-addr = <0x53>;
++ dvp-order = <1>;
++ remote-endpoint = <&ov106xx_in3>;
++ };
++ };
++ port@1 {
++ max9286_csi0ep0: endpoint {
++ csi-rate = <700>;
++ remote-endpoint = <&csi41_ep>;
++ };
++ };
++ };
++
++ ti9x4@0 {
++ compatible = "ti,ti9x4";
++ reg = <0x3a>;
++ ti,sensor_delay = <350>;
++ ti,links = <4>;
++ ti,lanes = <4>;
++ ti,forwarding-mode = "round-robin";
++ ti,cable-mode = "coax";
++
++ POC0-gpios = <&gpio_exp_6c 8 GPIO_ACTIVE_HIGH>;
++ POC1-gpios = <&gpio_exp_6c 9 GPIO_ACTIVE_HIGH>;
++ POC2-gpios = <&gpio_exp_6c 10 GPIO_ACTIVE_HIGH>;
++ POC3-gpios = <&gpio_exp_6c 11 GPIO_ACTIVE_HIGH>;
++
++ port@0 {
++ ti9x4_des0ep0: endpoint@0 {
++ ti9x3-addr = <0x0c>;
++ dvp-order = <0>;
++ remote-endpoint = <&ov106xx_in0>;
++ };
++ ti9x4_des0ep1: endpoint@1 {
++ ti9x3-addr = <0x0d>;
++ dvp-order = <0>;
++ remote-endpoint = <&ov106xx_in1>;
++ };
++ ti9x4_des0ep2: endpoint@2 {
++ ti9x3-addr = <0x0e>;
++ dvp-order = <0>;
++ remote-endpoint = <&ov106xx_in2>;
++ };
++ ti9x4_des0ep3: endpoint@3 {
++ ti9x3-addr = <0x0f>;
++ dvp-order = <0>;
++ remote-endpoint = <&ov106xx_in3>;
++ };
++ };
++ port@1 {
++ ti9x4_csi0ep0: endpoint {
++ csi-rate = <1450>;
++ remote-endpoint = <&csi41_ep>;
++ };
++ };
++ };
++ };
++
++ i2c@1 {
++ #address-cells = <1>;
++ #size-cells = <0>;
++ reg = <1>;
++
++ gpio_exp_6c: gpio@6c {
++ compatible = "maxim,max7325";
++ reg = <0x6c>;
++ gpio-controller;
++ #gpio-cells = <2>;
++
++ virq {
++ gpio-hog;
++ gpios = <5 GPIO_ACTIVE_HIGH>;
++ input;
++ line-name = "VIRQ";
++ };
++ des_cfg {
++ gpio-hog;
++ gpios = <6 GPIO_ACTIVE_HIGH>;
++ input;
++ line-name = "CNFG0";
++ };
++ pwr_shdn {
++ gpio-hog;
++ gpios = <14 GPIO_ACTIVE_HIGH>;
++ output-high;
++ line-name = "PWR_SHDN";
++ };
++ des_shdn {
++ gpio-hog;
++ gpios = <13 GPIO_ACTIVE_HIGH>;
++ output-high;
++ line-name = "Des_SHDN";
++ };
++ fpdl_shdn {
++ gpio-hog;
++ gpios = <15 GPIO_ACTIVE_HIGH>;
++ output-high;
++ line-name = "FPDL_SHDN";
++ };
++ };
++ };
++ };
++};
++
++&gpio1 {
++ can0stby {
++ gpio-hog;
++ gpios = <8 GPIO_ACTIVE_HIGH>;
++ output-low;
++ line-name = "CAN0STBY";
++ };
++};
++
++&gpio2 {
++ can0_load {
++ gpio-hog;
++ gpios = <3 GPIO_ACTIVE_HIGH>;
++ output-low;
++ line-name = "CAN0Loff";
++ };
++};
++
++&pfc {
++ can0_pins: can0 {
++ groups = "can0_data_a";
++ function = "can0";
++ };
++
++ can1_pins: can1 {
++ groups = "can1_data";
++ function = "can1";
++ };
++
++ canfd0_pins: canfd0 {
++ groups = "canfd0_data_a";
++ function = "canfd0";
++ };
++
++ canfd1_pins: canfd1 {
++ groups = "canfd1_data";
++ function = "canfd1";
++ };
++
++ i2c1_pins: i2c1 {
++ groups = "i2c1_b";
++ function = "i2c1";
++ };
++
++ scif1_pins: scif1 {
++ groups = "scif1_data_a";
++ function = "scif1";
++ };
++};
++
++&scif1 {
++ pinctrl-0 = <&scif1_pins>;
++ pinctrl-names = "default";
++
++ status = "okay";
++};
++
++&vin4 {
++ status = "okay";
++
++ ports {
++ #address-cells = <1>;
++ #size-cells = <0>;
++
++ port@0 {
++ vin4ep0: endpoint {
++ csi,select = "csi41";
++ virtual,channel = <0>;
++ data-lanes = <1 2 3 4>;
++ remote-endpoint = <&ov106xx_in0>;
++ };
++ };
++ port@1 {
++ csi0ep0: endpoint {
++ remote-endpoint = <&csi41_ep>;
++ };
++ };
++ port@2 {
++ vin4_max9286_des0ep0: endpoint@0 {
++ remote-endpoint = <&max9286_des0ep0>;
++ };
++ vin4_ti9x4_des0ep0: endpoint@1 {
++ remote-endpoint = <&ti9x4_des0ep0>;
++ };
++ };
++ };
++};
++
++&vin5 {
++ status = "okay";
++
++ ports {
++ #address-cells = <1>;
++ #size-cells = <0>;
++
++ port@0 {
++ vin5ep0: endpoint {
++ csi,select = "csi41";
++ virtual,channel = <1>;
++ data-lanes = <1 2 3 4>;
++ remote-endpoint = <&ov106xx_in1>;
++ };
++ };
++ port@1 {
++ csi0ep1: endpoint {
++ remote-endpoint = <&csi41_ep>;
++ };
++ };
++ port@2 {
++ vin5_max9286_des0ep1: endpoint@0 {
++ remote-endpoint = <&max9286_des0ep1>;
++ };
++ vin5_ti9x4_des0ep1: endpoint@1 {
++ remote-endpoint = <&ti9x4_des0ep1>;
++ };
++ };
++ };
++};
++
++&vin6 {
++ status = "okay";
++
++ ports {
++ #address-cells = <1>;
++ #size-cells = <0>;
++
++ port@0 {
++ vin6ep0: endpoint {
++ csi,select = "csi41";
++ virtual,channel = <2>;
++ data-lanes = <1 2 3 4>;
++ remote-endpoint = <&ov106xx_in2>;
++ };
++ };
++ port@1 {
++ csi0ep2: endpoint {
++ remote-endpoint = <&csi41_ep>;
++ };
++ };
++ port@2 {
++ vin6_max9286_des0ep2: endpoint@0 {
++ remote-endpoint = <&max9286_des0ep2>;
++ };
++ vin6_ti9x4_des0ep2: endpoint@1 {
++ remote-endpoint = <&ti9x4_des0ep2>;
++ };
++ };
++ };
++};
++
++&vin7 {
++ status = "okay";
++
++ ports {
++ #address-cells = <1>;
++ #size-cells = <0>;
++
++ port@0 {
++ vin7ep0: endpoint {
++ csi,select = "csi41";
++ virtual,channel = <3>;
++ data-lanes = <1 2 3 4>;
++ remote-endpoint = <&ov106xx_in3>;
++ };
++ };
++ port@1 {
++ csi0ep3: endpoint {
++ remote-endpoint = <&csi41_ep>;
++ };
++ };
++ port@2 {
++ vin7_max9286_des0ep3: endpoint@0 {
++ remote-endpoint = <&max9286_des0ep3>;
++ };
++ vin7_ti9x4_des0ep3: endpoint@1 {
++ remote-endpoint = <&ti9x4_des0ep3>;
++ };
++ };
++ };
++};
++
+--
+2.7.4
+
diff --git a/bsp/meta-rcar/meta-rcar-gen3-adas/recipes-kernel/linux/linux-renesas/0041-arm64-dts-renesas-ulcb-kf-Move-panel-configuration-t.patch b/bsp/meta-rcar/meta-rcar-gen3-adas/recipes-kernel/linux/linux-renesas/0041-arm64-dts-renesas-ulcb-kf-Move-panel-configuration-t.patch
new file mode 100644
index 00000000..d640d26e
--- /dev/null
+++ b/bsp/meta-rcar/meta-rcar-gen3-adas/recipes-kernel/linux/linux-renesas/0041-arm64-dts-renesas-ulcb-kf-Move-panel-configuration-t.patch
@@ -0,0 +1,125 @@
+From 4345b900761a169590891eb1946aae7d55b0c749 Mon Sep 17 00:00:00 2001
+From: Valentine Barshak <valentine.barshak@cogentembedded.com>
+Date: Mon, 17 Dec 2018 16:47:51 +0300
+Subject: [PATCH 032/122] arm64: dts: renesas: ulcb-kf: Move panel
+ configuration to ulcb-kf-panel.dtsi
+
+This moves LVDS panel configuration from ulcb-kf.dtsi
+to ulcb-kf-panel.dtsi. This various LVDS panel setup
+a bit easier.
+
+Signed-off-by: Valentine Barshak <valentine.barshak@cogentembedded.com>
+---
+ arch/arm64/boot/dts/renesas/ulcb-kf-panel.dtsi | 41 ++++++++++++++++++++++++++
+ arch/arm64/boot/dts/renesas/ulcb-kf.dtsi | 34 +++------------------
+ 2 files changed, 45 insertions(+), 30 deletions(-)
+ create mode 100644 arch/arm64/boot/dts/renesas/ulcb-kf-panel.dtsi
+
+diff --git a/arch/arm64/boot/dts/renesas/ulcb-kf-panel.dtsi b/arch/arm64/boot/dts/renesas/ulcb-kf-panel.dtsi
+new file mode 100644
+index 0000000..b54c935
+--- /dev/null
++++ b/arch/arm64/boot/dts/renesas/ulcb-kf-panel.dtsi
+@@ -0,0 +1,41 @@
++/*
++ * Device Tree Source for the Kingfisher (ULCB extension) LVDS panel
++ *
++ * Copyright (C) 2018 Renesas Electronics Corp.
++ * Copyright (C) 2018 Cogent Embedded, Inc.
++ *
++ * This file is licensed under the terms of the GNU General Public License
++ * version 2. This program is licensed "as is" without any warranty of any
++ * kind, whether express or implied.
++ */
++
++&lvds {
++ compatible = "panel-lvds";
++
++ width-mm = <210>;
++ height-mm = <158>;
++
++ data-mapping = "jeida-24";
++
++ panel-timing {
++ /* 1280x800 @60Hz Boundary Devices BD101LCC1 compatible panel */
++ clock-frequency = <65000000>;
++ hactive = <1280>;
++ vactive = <800>;
++ hsync-len = <40>;
++ hfront-porch = <80>;
++ hback-porch = <40>;
++ vfront-porch = <14>;
++ vback-porch = <14>;
++ vsync-len = <4>;
++ };
++};
++
++&gpio2 {
++ bl_pwm {
++ gpio-hog;
++ gpios = <3 GPIO_ACTIVE_HIGH>;
++ output-high;
++ line-name = "BL PWM 100%";
++ };
++};
+diff --git a/arch/arm64/boot/dts/renesas/ulcb-kf.dtsi b/arch/arm64/boot/dts/renesas/ulcb-kf.dtsi
+index a70636e..4ab8d60 100644
+--- a/arch/arm64/boot/dts/renesas/ulcb-kf.dtsi
++++ b/arch/arm64/boot/dts/renesas/ulcb-kf.dtsi
+@@ -171,27 +171,7 @@
+ dais = <&rsnd_port3>;
+ };
+
+- lvds {
+- compatible = "panel-lvds";
+-
+- width-mm = <210>;
+- height-mm = <158>;
+-
+- data-mapping = "jeida-24";
+-
+- panel-timing {
+- /* 1280x800 @60Hz */
+- clock-frequency = <65000000>;
+- hactive = <1280>;
+- vactive = <800>;
+- hsync-len = <40>;
+- hfront-porch = <80>;
+- hback-porch = <40>;
+- vfront-porch = <14>;
+- vback-porch = <14>;
+- vsync-len = <4>;
+- };
+-
++ lvds: lvds {
+ port {
+ lvds_in: endpoint {
+ remote-endpoint = <&lvds0_out>;
+@@ -337,15 +317,6 @@
+ status = "okay";
+ };
+
+-&gpio2 {
+- bl_pwm {
+- gpio-hog;
+- gpios = <3 GPIO_ACTIVE_HIGH>;
+- output-high;
+- line-name = "BL PWM 100%";
+- };
+-};
+-
+ &gpio4 {
+ most_rst {
+ gpio-hog;
+@@ -1457,5 +1428,8 @@
+ status = "okay";
+ };
+
++/* set LVDS panel timings and pins */
++#include "ulcb-kf-panel.dtsi"
++
+
+
+--
+2.7.4
+
diff --git a/bsp/meta-rcar/meta-rcar-gen3-adas/recipes-kernel/linux/linux-renesas/0042-arm64-dts-renesas-r8a7795-es1-h3ulcb-disable-eMMC.patch b/bsp/meta-rcar/meta-rcar-gen3-adas/recipes-kernel/linux/linux-renesas/0042-arm64-dts-renesas-r8a7795-es1-h3ulcb-disable-eMMC.patch
new file mode 100644
index 00000000..8811c9f6
--- /dev/null
+++ b/bsp/meta-rcar/meta-rcar-gen3-adas/recipes-kernel/linux/linux-renesas/0042-arm64-dts-renesas-r8a7795-es1-h3ulcb-disable-eMMC.patch
@@ -0,0 +1,27 @@
+From cee42d4e680e0d4f3485eb772371d26b769a5cec Mon Sep 17 00:00:00 2001
+From: Vladimir Barinov <vladimir.barinov@cogentembedded.com>
+Date: Sat, 15 Jul 2017 00:44:12 +0300
+Subject: [PATCH 033/122] arm64: dts: renesas: r8a7795-es1-h3ulcb: disable eMMC
+
+Disable eMMC due to ES1.x silicon bug
+
+Signed-off-by: Vladimir Barinov <vladimir.barinov@cogentembedded.com>
+---
+ arch/arm64/boot/dts/renesas/r8a7795-es1-h3ulcb.dts | 1 +
+ 1 file changed, 1 insertion(+)
+
+diff --git a/arch/arm64/boot/dts/renesas/r8a7795-es1-h3ulcb.dts b/arch/arm64/boot/dts/renesas/r8a7795-es1-h3ulcb.dts
+index 119f06c..658cc0f 100644
+--- a/arch/arm64/boot/dts/renesas/r8a7795-es1-h3ulcb.dts
++++ b/arch/arm64/boot/dts/renesas/r8a7795-es1-h3ulcb.dts
+@@ -78,6 +78,7 @@
+
+ &sdhi2 {
+ /delete-property/ mmc-hs400-1_8v;
++ status = "disabled";
+ };
+
+ &vspbc {
+--
+2.7.4
+
diff --git a/bsp/meta-rcar/meta-rcar-gen3-adas/recipes-kernel/linux/linux-renesas/0043-pinctrl-sh-pfc-pfc-r8a77965-Add-missing-avb_mii-pin-.patch b/bsp/meta-rcar/meta-rcar-gen3-adas/recipes-kernel/linux/linux-renesas/0043-pinctrl-sh-pfc-pfc-r8a77965-Add-missing-avb_mii-pin-.patch
new file mode 100644
index 00000000..adea08fe
--- /dev/null
+++ b/bsp/meta-rcar/meta-rcar-gen3-adas/recipes-kernel/linux/linux-renesas/0043-pinctrl-sh-pfc-pfc-r8a77965-Add-missing-avb_mii-pin-.patch
@@ -0,0 +1,154 @@
+From dda649f6888394cfdd469167c2976eee2c4f64e7 Mon Sep 17 00:00:00 2001
+From: Andrey Gusakov <andrey.gusakov@cogentembedded.com>
+Date: Fri, 7 Jul 2017 16:22:40 +0300
+Subject: [PATCH 034/122] pinctrl: r8a779x: add mlb pinmux
+
+Signed-off-by: Andrey Gusakov <andrey.gusakov@cogentembedded.com>
+Signed-off-by: Vladimir Barinov <vladimir.barinov@cogentembedded.com>
+---
+ drivers/pinctrl/sh-pfc/pfc-r8a7795-es1.c | 14 ++++++++++++++
+ drivers/pinctrl/sh-pfc/pfc-r8a7795.c | 14 ++++++++++++++
+ drivers/pinctrl/sh-pfc/pfc-r8a7796.c | 14 ++++++++++++++
+ 3 files changed, 42 insertions(+)
+
+diff --git a/drivers/pinctrl/sh-pfc/pfc-r8a7795-es1.c b/drivers/pinctrl/sh-pfc/pfc-r8a7795-es1.c
+index 9f302f6..827155c1 100644
+--- a/drivers/pinctrl/sh-pfc/pfc-r8a7795-es1.c
++++ b/drivers/pinctrl/sh-pfc/pfc-r8a7795-es1.c
+@@ -2387,6 +2387,14 @@ static const unsigned int intc_ex_irq5_mux[] = {
+ IRQ5_MARK,
+ };
+
++/* - MLB+ ------------------------------------------------------------------- */
++static const unsigned int mlb_3pin_pins[] = {
++ RCAR_GP_PIN(5, 23), RCAR_GP_PIN(5, 24), RCAR_GP_PIN(5, 25),
++};
++static const unsigned int mlb_3pin_mux[] = {
++ MLB_CLK_MARK, MLB_SIG_MARK, MLB_DAT_MARK,
++};
++
+ /* - MSIOF0 ----------------------------------------------------------------- */
+ static const unsigned int msiof0_clk_pins[] = {
+ /* SCK */
+@@ -4289,6 +4297,7 @@ static const struct sh_pfc_pin_group pinmux_groups[] = {
+ SH_PFC_PIN_GROUP(intc_ex_irq3),
+ SH_PFC_PIN_GROUP(intc_ex_irq4),
+ SH_PFC_PIN_GROUP(intc_ex_irq5),
++ SH_PFC_PIN_GROUP(mlb_3pin),
+ SH_PFC_PIN_GROUP(msiof0_clk),
+ SH_PFC_PIN_GROUP(msiof0_sync),
+ SH_PFC_PIN_GROUP(msiof0_ss1),
+@@ -4698,6 +4707,10 @@ static const char * const intc_ex_groups[] = {
+ "intc_ex_irq5",
+ };
+
++static const char * const mlb_3pin_groups[] = {
++ "mlb_3pin",
++};
++
+ static const char * const msiof0_groups[] = {
+ "msiof0_clk",
+ "msiof0_sync",
+@@ -5046,6 +5059,7 @@ static const struct sh_pfc_function pinmux_functions[] = {
+ SH_PFC_FUNCTION(i2c5),
+ SH_PFC_FUNCTION(i2c6),
+ SH_PFC_FUNCTION(intc_ex),
++ SH_PFC_FUNCTION(mlb_3pin),
+ SH_PFC_FUNCTION(msiof0),
+ SH_PFC_FUNCTION(msiof1),
+ SH_PFC_FUNCTION(msiof2),
+diff --git a/drivers/pinctrl/sh-pfc/pfc-r8a7795.c b/drivers/pinctrl/sh-pfc/pfc-r8a7795.c
+index 3ebe8de..b0fde0d 100644
+--- a/drivers/pinctrl/sh-pfc/pfc-r8a7795.c
++++ b/drivers/pinctrl/sh-pfc/pfc-r8a7795.c
+@@ -2469,6 +2469,14 @@ static const unsigned int intc_ex_irq5_mux[] = {
+ IRQ5_MARK,
+ };
+
++/* - MLB+ ------------------------------------------------------------------- */
++static const unsigned int mlb_3pin_pins[] = {
++ RCAR_GP_PIN(5, 23), RCAR_GP_PIN(5, 24), RCAR_GP_PIN(5, 25),
++};
++static const unsigned int mlb_3pin_mux[] = {
++ MLB_CLK_MARK, MLB_SIG_MARK, MLB_DAT_MARK,
++};
++
+ /* - MSIOF0 ----------------------------------------------------------------- */
+ static const unsigned int msiof0_clk_pins[] = {
+ /* SCK */
+@@ -4329,6 +4337,7 @@ static const struct sh_pfc_pin_group pinmux_groups[] = {
+ SH_PFC_PIN_GROUP(intc_ex_irq3),
+ SH_PFC_PIN_GROUP(intc_ex_irq4),
+ SH_PFC_PIN_GROUP(intc_ex_irq5),
++ SH_PFC_PIN_GROUP(mlb_3pin),
+ SH_PFC_PIN_GROUP(msiof0_clk),
+ SH_PFC_PIN_GROUP(msiof0_sync),
+ SH_PFC_PIN_GROUP(msiof0_ss1),
+@@ -4751,6 +4760,10 @@ static const char * const intc_ex_groups[] = {
+ "intc_ex_irq5",
+ };
+
++static const char * const mlb_3pin_groups[] = {
++ "mlb_3pin",
++};
++
+ static const char * const msiof0_groups[] = {
+ "msiof0_clk",
+ "msiof0_sync",
+@@ -5103,6 +5116,7 @@ static const struct sh_pfc_function pinmux_functions[] = {
+ SH_PFC_FUNCTION(i2c5),
+ SH_PFC_FUNCTION(i2c6),
+ SH_PFC_FUNCTION(intc_ex),
++ SH_PFC_FUNCTION(mlb_3pin),
+ SH_PFC_FUNCTION(msiof0),
+ SH_PFC_FUNCTION(msiof1),
+ SH_PFC_FUNCTION(msiof2),
+diff --git a/drivers/pinctrl/sh-pfc/pfc-r8a7796.c b/drivers/pinctrl/sh-pfc/pfc-r8a7796.c
+index 1617559..43cb931 100644
+--- a/drivers/pinctrl/sh-pfc/pfc-r8a7796.c
++++ b/drivers/pinctrl/sh-pfc/pfc-r8a7796.c
+@@ -2478,6 +2478,14 @@ static const unsigned int intc_ex_irq5_mux[] = {
+ IRQ5_MARK,
+ };
+
++/* - MLB+ ------------------------------------------------------------------- */
++static const unsigned int mlb_3pin_pins[] = {
++ RCAR_GP_PIN(5, 23), RCAR_GP_PIN(5, 24), RCAR_GP_PIN(5, 25),
++};
++static const unsigned int mlb_3pin_mux[] = {
++ MLB_CLK_MARK, MLB_SIG_MARK, MLB_DAT_MARK,
++};
++
+ /* - MSIOF0 ----------------------------------------------------------------- */
+ static const unsigned int msiof0_clk_pins[] = {
+ /* SCK */
+@@ -4307,6 +4315,7 @@ static const struct sh_pfc_pin_group pinmux_groups[] = {
+ SH_PFC_PIN_GROUP(intc_ex_irq3),
+ SH_PFC_PIN_GROUP(intc_ex_irq4),
+ SH_PFC_PIN_GROUP(intc_ex_irq5),
++ SH_PFC_PIN_GROUP(mlb_3pin),
+ SH_PFC_PIN_GROUP(msiof0_clk),
+ SH_PFC_PIN_GROUP(msiof0_sync),
+ SH_PFC_PIN_GROUP(msiof0_ss1),
+@@ -4725,6 +4734,10 @@ static const char * const intc_ex_groups[] = {
+ "intc_ex_irq5",
+ };
+
++static const char * const mlb_3pin_groups[] = {
++ "mlb_3pin",
++};
++
+ static const char * const msiof0_groups[] = {
+ "msiof0_clk",
+ "msiof0_sync",
+@@ -5064,6 +5077,7 @@ static const struct sh_pfc_function pinmux_functions[] = {
+ SH_PFC_FUNCTION(i2c5),
+ SH_PFC_FUNCTION(i2c6),
+ SH_PFC_FUNCTION(intc_ex),
++ SH_PFC_FUNCTION(mlb_3pin),
+ SH_PFC_FUNCTION(msiof0),
+ SH_PFC_FUNCTION(msiof1),
+ SH_PFC_FUNCTION(msiof2),
+--
+2.7.4
+
diff --git a/bsp/meta-rcar/meta-rcar-gen3-adas/recipes-kernel/linux/linux-renesas/0045-clk-r8a779x-add-mlp-clock.patch b/bsp/meta-rcar/meta-rcar-gen3-adas/recipes-kernel/linux/linux-renesas/0045-clk-r8a779x-add-mlp-clock.patch
new file mode 100644
index 00000000..6a5b9082
--- /dev/null
+++ b/bsp/meta-rcar/meta-rcar-gen3-adas/recipes-kernel/linux/linux-renesas/0045-clk-r8a779x-add-mlp-clock.patch
@@ -0,0 +1,38 @@
+From 9bb19c618df3b036672f9abb0261960ba0c4966b Mon Sep 17 00:00:00 2001
+From: Andrey Gusakov <andrey.gusakov@cogentembedded.com>
+Date: Fri, 7 Jul 2017 16:23:44 +0300
+Subject: [PATCH 035/122] clk: r8a779x: add mlp clock
+
+Signed-off-by: Andrey Gusakov <andrey.gusakov@cogentembedded.com>
+---
+ drivers/clk/renesas/r8a7795-cpg-mssr.c | 1 +
+ drivers/clk/renesas/r8a7796-cpg-mssr.c | 1 +
+ 2 files changed, 2 insertions(+)
+
+diff --git a/drivers/clk/renesas/r8a7795-cpg-mssr.c b/drivers/clk/renesas/r8a7795-cpg-mssr.c
+index 5b09453..fc033cc 100644
+--- a/drivers/clk/renesas/r8a7795-cpg-mssr.c
++++ b/drivers/clk/renesas/r8a7795-cpg-mssr.c
+@@ -218,6 +218,7 @@ static struct mssr_mod_clk r8a7795_mod_clks[] __initdata = {
+ DEF_MOD("lvds", 727, R8A7795_CLK_S0D4),
+ DEF_MOD("hdmi1", 728, R8A7795_CLK_HDMI),
+ DEF_MOD("hdmi0", 729, R8A7795_CLK_HDMI),
++ DEF_MOD("mlp", 802, R8A7795_CLK_S2D1),
+ DEF_MOD("vin7", 804, R8A7795_CLK_S0D2),
+ DEF_MOD("vin6", 805, R8A7795_CLK_S0D2),
+ DEF_MOD("vin5", 806, R8A7795_CLK_S0D2),
+diff --git a/drivers/clk/renesas/r8a7796-cpg-mssr.c b/drivers/clk/renesas/r8a7796-cpg-mssr.c
+index ad1e3f8..aeb435f 100644
+--- a/drivers/clk/renesas/r8a7796-cpg-mssr.c
++++ b/drivers/clk/renesas/r8a7796-cpg-mssr.c
+@@ -194,6 +194,7 @@ static struct mssr_mod_clk r8a7796_mod_clks[] __initdata = {
+ DEF_MOD("du0", 724, R8A7796_CLK_S2D1),
+ DEF_MOD("lvds", 727, R8A7796_CLK_S2D1),
+ DEF_MOD("hdmi0", 729, R8A7796_CLK_HDMI),
++ DEF_MOD("mlp", 802, R8A7796_CLK_S2D1),
+ DEF_MOD("vin7", 804, R8A7796_CLK_S0D2),
+ DEF_MOD("vin6", 805, R8A7796_CLK_S0D2),
+ DEF_MOD("vin5", 806, R8A7796_CLK_S0D2),
+--
+2.7.4
+
diff --git a/bsp/meta-rcar/meta-rcar-gen3-adas/recipes-kernel/linux/linux-renesas/0046-arm64-dts-renesas-r8a779x-add-mlp-nodes.patch b/bsp/meta-rcar/meta-rcar-gen3-adas/recipes-kernel/linux/linux-renesas/0046-arm64-dts-renesas-r8a779x-add-mlp-nodes.patch
new file mode 100644
index 00000000..672afefa
--- /dev/null
+++ b/bsp/meta-rcar/meta-rcar-gen3-adas/recipes-kernel/linux/linux-renesas/0046-arm64-dts-renesas-r8a779x-add-mlp-nodes.patch
@@ -0,0 +1,62 @@
+From decad395fffdd4b5426434696596c908dbb6ca3a Mon Sep 17 00:00:00 2001
+From: Andrey Gusakov <andrey.gusakov@cogentembedded.com>
+Date: Fri, 7 Jul 2017 16:25:06 +0300
+Subject: [PATCH 036/122] arm64: dts: renesas: r8a779x: add mlp nodes
+
+Signed-off-by: Andrey Gusakov <andrey.gusakov@cogentembedded.com>
+---
+ arch/arm64/boot/dts/renesas/r8a7795.dtsi | 13 +++++++++++++
+ arch/arm64/boot/dts/renesas/r8a7796.dtsi | 13 +++++++++++++
+ 2 files changed, 26 insertions(+)
+
+diff --git a/arch/arm64/boot/dts/renesas/r8a7795.dtsi b/arch/arm64/boot/dts/renesas/r8a7795.dtsi
+index f15d587..b9c4a39 100644
+--- a/arch/arm64/boot/dts/renesas/r8a7795.dtsi
++++ b/arch/arm64/boot/dts/renesas/r8a7795.dtsi
+@@ -1868,6 +1868,19 @@
+ status = "disabled";
+ };
+
++ mlp: mlp@ec520000 {
++ compatible = "rcar,medialb-dim2";
++ reg = <0 0xec520000 0 0x800>;
++ interrupts = <GIC_SPI 385 IRQ_TYPE_LEVEL_HIGH>,
++ <GIC_SPI 386 IRQ_TYPE_LEVEL_HIGH>,
++ <GIC_SPI 384 IRQ_TYPE_LEVEL_HIGH>,
++ <GIC_SPI 387 IRQ_TYPE_LEVEL_HIGH>,
++ <GIC_SPI 388 IRQ_TYPE_LEVEL_HIGH>;
++ clocks = <&cpg CPG_MOD 802>;
++ power-domains = <&sysc R8A7795_PD_ALWAYS_ON>;
++ status = "disabled";
++ };
++
+ msiof0: spi@e6e90000 {
+ compatible = "renesas,msiof-r8a7795",
+ "renesas,rcar-gen3-msiof";
+diff --git a/arch/arm64/boot/dts/renesas/r8a7796.dtsi b/arch/arm64/boot/dts/renesas/r8a7796.dtsi
+index 00433dc..c41d1c2 100644
+--- a/arch/arm64/boot/dts/renesas/r8a7796.dtsi
++++ b/arch/arm64/boot/dts/renesas/r8a7796.dtsi
+@@ -1791,6 +1791,19 @@
+ status = "disabled";
+ };
+
++ mlp: mlp@ec520000 {
++ compatible = "rcar,medialb-dim2";
++ reg = <0 0xec520000 0 0x800>;
++ interrupts = <GIC_SPI 385 IRQ_TYPE_LEVEL_HIGH>,
++ <GIC_SPI 386 IRQ_TYPE_LEVEL_HIGH>,
++ <GIC_SPI 384 IRQ_TYPE_LEVEL_HIGH>,
++ <GIC_SPI 387 IRQ_TYPE_LEVEL_HIGH>,
++ <GIC_SPI 388 IRQ_TYPE_LEVEL_HIGH>;
++ clocks = <&cpg CPG_MOD 802>;
++ power-domains = <&sysc R8A7796_PD_ALWAYS_ON>;
++ status = "disabled";
++ };
++
+ msiof1: spi@e6ea0000 {
+ compatible = "renesas,msiof-r8a7796",
+ "renesas,rcar-gen3-msiof";
+--
+2.7.4
+
diff --git a/bsp/meta-rcar/meta-rcar-gen3-adas/recipes-kernel/linux/linux-renesas/0047-arm64-dts-renesas-ulcb-kf-enable-sd3.patch b/bsp/meta-rcar/meta-rcar-gen3-adas/recipes-kernel/linux/linux-renesas/0047-arm64-dts-renesas-ulcb-kf-enable-sd3.patch
new file mode 100644
index 00000000..cf309759
--- /dev/null
+++ b/bsp/meta-rcar/meta-rcar-gen3-adas/recipes-kernel/linux/linux-renesas/0047-arm64-dts-renesas-ulcb-kf-enable-sd3.patch
@@ -0,0 +1,28 @@
+From 92895c4d38f2a9e03217ffc4fa3fc7d143205d93 Mon Sep 17 00:00:00 2001
+From: Vladimir Barinov <vladimir.barinov@cogentembedded.com>
+Date: Fri, 27 Oct 2017 20:54:47 +0300
+Subject: [PATCH 037/122] arm64: dts: renesas: ulcb-kf: enable sd3
+
+This enables SD3 on CN47 instead wifi
+
+Signed-off-by: Vladimir Barinov <vladimir.barinov@cogentembedded.com>
+---
+ arch/arm64/boot/dts/renesas/ulcb-kf.dtsi | 5 +++++
+ 1 file changed, 5 insertions(+)
+
+diff --git a/arch/arm64/boot/dts/renesas/ulcb-kf.dtsi b/arch/arm64/boot/dts/renesas/ulcb-kf.dtsi
+index 4ab8d60..da522a2 100644
+--- a/arch/arm64/boot/dts/renesas/ulcb-kf.dtsi
++++ b/arch/arm64/boot/dts/renesas/ulcb-kf.dtsi
+@@ -1433,3 +1433,8 @@
+
+
+
++/* enable CN47: SD on SDHI3 */
++#include "ulcb-kf-sd3.dtsi"
++
++
++
+--
+2.7.4
+
diff --git a/bsp/meta-rcar/meta-rcar-gen3-adas/recipes-kernel/linux/linux-renesas/0048-arm64-dts-renesas-ulcb-kf-enable-most.patch b/bsp/meta-rcar/meta-rcar-gen3-adas/recipes-kernel/linux/linux-renesas/0048-arm64-dts-renesas-ulcb-kf-enable-most.patch
new file mode 100644
index 00000000..d26cfc68
--- /dev/null
+++ b/bsp/meta-rcar/meta-rcar-gen3-adas/recipes-kernel/linux/linux-renesas/0048-arm64-dts-renesas-ulcb-kf-enable-most.patch
@@ -0,0 +1,28 @@
+From 93c3ef73d1b9fdab33a2e875b50a94840ff6cd31 Mon Sep 17 00:00:00 2001
+From: Vladimir Barinov <vladimir.barinov@cogentembedded.com>
+Date: Fri, 27 Oct 2017 20:58:21 +0300
+Subject: [PATCH 038/122] arm64: dts: renesas: ulcb-kf: enable most
+
+This enables MOST on CN22 instead GPS
+
+Signed-off-by: Vladimir Barinov <vladimir.barinov@cogentembedded.com>
+---
+ arch/arm64/boot/dts/renesas/ulcb-kf.dtsi | 5 +++++
+ 1 file changed, 5 insertions(+)
+
+diff --git a/arch/arm64/boot/dts/renesas/ulcb-kf.dtsi b/arch/arm64/boot/dts/renesas/ulcb-kf.dtsi
+index da522a2..61b7851 100644
+--- a/arch/arm64/boot/dts/renesas/ulcb-kf.dtsi
++++ b/arch/arm64/boot/dts/renesas/ulcb-kf.dtsi
+@@ -1438,3 +1438,8 @@
+
+
+
++/* enable CN22: enable MOST and disable GPS (move R661->R660, R663->R662) */
++#include "ulcb-kf-most.dtsi"
++
++
++
+--
+2.7.4
+
diff --git a/bsp/meta-rcar/meta-rcar-gen3-adas/recipes-kernel/linux/linux-renesas/0049-clk-r8a779x-add-IMP-clock.patch b/bsp/meta-rcar/meta-rcar-gen3-adas/recipes-kernel/linux/linux-renesas/0049-clk-r8a779x-add-IMP-clock.patch
new file mode 100644
index 00000000..28737061
--- /dev/null
+++ b/bsp/meta-rcar/meta-rcar-gen3-adas/recipes-kernel/linux/linux-renesas/0049-clk-r8a779x-add-IMP-clock.patch
@@ -0,0 +1,40 @@
+From 2ba0b0a944c433438730c3dd78985dd43abb51c4 Mon Sep 17 00:00:00 2001
+From: Vladimir Barinov <vladimir.barinov@cogentembedded.com>
+Date: Mon, 27 Nov 2017 16:53:06 +0300
+Subject: [PATCH 039/122] clk: r8a779x: add IMP clock
+
+This adds IMP clock sources for Gen3 SoCs
+
+Signed-off-by: Vladimir Barinov <vladimir.barinov@cogentembedded.com>
+---
+ drivers/clk/renesas/r8a7795-cpg-mssr.c | 1 +
+ drivers/clk/renesas/r8a7796-cpg-mssr.c | 1 +
+ 2 files changed, 2 insertions(+)
+
+diff --git a/drivers/clk/renesas/r8a7795-cpg-mssr.c b/drivers/clk/renesas/r8a7795-cpg-mssr.c
+index fc033cc..bd5a73f 100644
+--- a/drivers/clk/renesas/r8a7795-cpg-mssr.c
++++ b/drivers/clk/renesas/r8a7795-cpg-mssr.c
+@@ -233,6 +233,7 @@ static struct mssr_mod_clk r8a7795_mod_clks[] __initdata = {
+ DEF_MOD("imr2", 821, R8A7795_CLK_S0D2),
+ DEF_MOD("imr1", 822, R8A7795_CLK_S0D2),
+ DEF_MOD("imr0", 823, R8A7795_CLK_S0D2),
++ DEF_MOD("imp", 824, R8A7795_CLK_S1D1),
+ DEF_MOD("gpio7", 905, R8A7795_CLK_S3D4),
+ DEF_MOD("gpio6", 906, R8A7795_CLK_S3D4),
+ DEF_MOD("gpio5", 907, R8A7795_CLK_S3D4),
+diff --git a/drivers/clk/renesas/r8a7796-cpg-mssr.c b/drivers/clk/renesas/r8a7796-cpg-mssr.c
+index aeb435f..f4f1350 100644
+--- a/drivers/clk/renesas/r8a7796-cpg-mssr.c
++++ b/drivers/clk/renesas/r8a7796-cpg-mssr.c
+@@ -206,6 +206,7 @@ static struct mssr_mod_clk r8a7796_mod_clks[] __initdata = {
+ DEF_MOD("etheravb", 812, R8A7796_CLK_S0D6),
+ DEF_MOD("imr1", 822, R8A7796_CLK_S0D2),
+ DEF_MOD("imr0", 823, R8A7796_CLK_S0D2),
++ DEF_MOD("imp", 824, R8A7796_CLK_S1D1),
+ DEF_MOD("gpio7", 905, R8A7796_CLK_S3D4),
+ DEF_MOD("gpio6", 906, R8A7796_CLK_S3D4),
+ DEF_MOD("gpio5", 907, R8A7796_CLK_S3D4),
+--
+2.7.4
+
diff --git a/bsp/meta-rcar/meta-rcar-gen3-adas/recipes-kernel/linux/linux-renesas/0050-arm64-dts-renesas-r8a779x-add-IMP-nodes.patch b/bsp/meta-rcar/meta-rcar-gen3-adas/recipes-kernel/linux/linux-renesas/0050-arm64-dts-renesas-r8a779x-add-IMP-nodes.patch
new file mode 100644
index 00000000..f0f8ff8b
--- /dev/null
+++ b/bsp/meta-rcar/meta-rcar-gen3-adas/recipes-kernel/linux/linux-renesas/0050-arm64-dts-renesas-r8a779x-add-IMP-nodes.patch
@@ -0,0 +1,198 @@
+From 853eb0ced4522f2d93f4b26abf656f358fd7a80e Mon Sep 17 00:00:00 2001
+From: Vladimir Barinov <vladimir.barinov@cogentembedded.com>
+Date: Tue, 28 Nov 2017 14:47:12 +0300
+Subject: [PATCH 040/122] arm64: dts: renesas: r8a779x: add IMP nodes
+
+This adds IMP resource nodes for Gen3 SoCs
+
+Signed-off-by: Vladimir Barinov <vladimir.barinov@cogentembedded.com>
+---
+ arch/arm64/boot/dts/renesas/r8a7795.dtsi | 98 ++++++++++++++++++++++++++++++++
+ arch/arm64/boot/dts/renesas/r8a7796.dtsi | 62 ++++++++++++++++++++
+ 2 files changed, 160 insertions(+)
+
+diff --git a/arch/arm64/boot/dts/renesas/r8a7795.dtsi b/arch/arm64/boot/dts/renesas/r8a7795.dtsi
+index b9c4a39..536deef 100644
+--- a/arch/arm64/boot/dts/renesas/r8a7795.dtsi
++++ b/arch/arm64/boot/dts/renesas/r8a7795.dtsi
+@@ -3265,6 +3265,104 @@
+ };
+ };
+
++ imp_distributer: impdes0 {
++ compatible = "renesas,impx4-distributer";
++ reg = <0 0xffa00000 0 0x4000>;
++ interrupts = <GIC_SPI 439 IRQ_TYPE_LEVEL_HIGH>;
++ clocks = <&cpg CPG_MOD 824>;
++ power-domains = <&sysc R8A7795_PD_A3IR>;
++ interrupt-controller;
++ #interrupt-cells = <1>;
++ };
++
++ imp0 {
++ compatible = "renesas,impx4-legacy";
++ reg = <0 0xff900000 0 0x20000>;
++ interrupt-parent = <&imp_distributer>;
++ interrupts = <0>;
++ clocks = <&cpg CPG_MOD 824>;
++ power-domains = <&sysc R8A7795_PD_A3IR>;
++ };
++
++ imp1 {
++ compatible = "renesas,impx4-legacy";
++ reg = <0 0xff920000 0 0x20000>;
++ interrupt-parent = <&imp_distributer>;
++ interrupts = <1>;
++ clocks = <&cpg CPG_MOD 824>;
++ power-domains = <&sysc R8A7795_PD_A3IR>;
++ };
++
++ imp2 {
++ compatible = "renesas,impx4-legacy";
++ reg = <0 0xff940000 0 0x20000>;
++ interrupt-parent = <&imp_distributer>;
++ interrupts = <2>;
++ clocks = <&cpg CPG_MOD 824>;
++ power-domains = <&sysc R8A7795_PD_A3IR>;
++ };
++
++ imp3 {
++ compatible = "renesas,impx4-legacy";
++ reg = <0 0xff960000 0 0x20000>;
++ interrupt-parent = <&imp_distributer>;
++ interrupts = <3>;
++ clocks = <&cpg CPG_MOD 824>;
++ power-domains = <&sysc R8A7795_PD_A3IR>;
++ };
++
++ impsc0 {
++ compatible = "renesas,impx4-shader";
++ reg = <0 0xff980000 0 0x10000>;
++ interrupt-parent = <&imp_distributer>;
++ interrupts = <4>;
++ clocks = <&cpg CPG_MOD 824>;
++ power-domains = <&sysc R8A7795_PD_A3IR>;
++ };
++
++ impsc1 {
++ compatible = "renesas,impx4-shader";
++ reg = <0 0xff990000 0 0x10000>;
++ interrupt-parent = <&imp_distributer>;
++ interrupts = <5>;
++ clocks = <&cpg CPG_MOD 824>;
++ power-domains = <&sysc R8A7795_PD_A3IR>;
++ };
++
++ impsl0 {
++ compatible = "renesas,impx4-legacy";
++ reg = <0 0xff9c0000 0 0x10000>;
++ interrupt-parent = <&imp_distributer>;
++ interrupts = <12>;
++ clocks = <&cpg CPG_MOD 824>;
++ power-domains = <&sysc R8A7795_PD_A3IR>;
++ };
++
++ impdm0 {
++ compatible = "renesas,impx5-dmac";
++ reg = <0 0xffa10000 0 0x4000>;
++ interrupt-parent = <&imp_distributer>;
++ interrupts = <16>;
++ clocks = <&cpg CPG_MOD 824>;
++ power-domains = <&sysc R8A7795_PD_A3IR>;
++ };
++
++ impc0 {
++ compatible = "renesas,impx4-memory";
++ reg = <0 0xffa40000 0 0x20000>;
++ clocks = <&cpg CPG_MOD 824>;
++ power-domains = <&sysc R8A7795_PD_A3IR>;
++ };
++
++ imprtt {
++ compatible = "renesas,impx5-rtt";
++ reg = <0 0xff8d0000 0 0x1000>,
++ <0 0xe6150000 0 0x1000>;
++ interrupts = <GIC_SPI 393 IRQ_TYPE_LEVEL_HIGH>;
++ clocks = <&cpg CPG_MOD 824>;
++ power-domains = <&sysc R8A7795_PD_A3IR>;
++ };
++
+ thermal-zones {
+ emergency {
+ polling-delay = <1000>;
+diff --git a/arch/arm64/boot/dts/renesas/r8a7796.dtsi b/arch/arm64/boot/dts/renesas/r8a7796.dtsi
+index c41d1c2..383639b 100644
+--- a/arch/arm64/boot/dts/renesas/r8a7796.dtsi
++++ b/arch/arm64/boot/dts/renesas/r8a7796.dtsi
+@@ -2638,6 +2638,68 @@
+ resets = <&cpg 822>;
+ };
+
++ imp_distributer: impdes0 {
++ compatible = "renesas,impx4-distributer";
++ reg = <0 0xffa00000 0 0x4000>;
++ interrupts = <GIC_SPI 439 IRQ_TYPE_LEVEL_HIGH>;
++ clocks = <&cpg CPG_MOD 824>;
++ power-domains = <&sysc R8A7796_PD_A3IR>;
++ interrupt-controller;
++ #interrupt-cells = <1>;
++ };
++
++ imp0 {
++ compatible = "renesas,impx4-legacy";
++ reg = <0 0xff900000 0 0x20000>;
++ interrupt-parent = <&imp_distributer>;
++ interrupts = <0>;
++ clocks = <&cpg CPG_MOD 824>;
++ power-domains = <&sysc R8A7796_PD_A3IR>;
++ };
++
++ imp1 {
++ compatible = "renesas,impx4-legacy";
++ reg = <0 0xff920000 0 0x20000>;
++ interrupt-parent = <&imp_distributer>;
++ interrupts = <1>;
++ clocks = <&cpg CPG_MOD 824>;
++ power-domains = <&sysc R8A7796_PD_A3IR>;
++ };
++
++ impsc0 {
++ compatible = "renesas,impx4-shader";
++ reg = <0 0xff980000 0 0x10000>;
++ interrupt-parent = <&imp_distributer>;
++ interrupts = <4>;
++ clocks = <&cpg CPG_MOD 824>;
++ power-domains = <&sysc R8A7796_PD_A3IR>;
++ };
++
++ impdm0 {
++ compatible = "renesas,impx5-dmac";
++ reg = <0 0xffa10000 0 0x4000>;
++ interrupt-parent = <&imp_distributer>;
++ interrupts = <16>;
++ clocks = <&cpg CPG_MOD 824>;
++ power-domains = <&sysc R8A7796_PD_A3IR>;
++ };
++
++ impc0 {
++ compatible = "renesas,impx4-memory";
++ reg = <0 0xffa40000 0 0x20000>;
++ clocks = <&cpg CPG_MOD 824>;
++ power-domains = <&sysc R8A7796_PD_A3IR>;
++ };
++
++ imprtt {
++ compatible = "renesas,impx5-rtt";
++ reg = <0 0xff8d0000 0 0x1000>,
++ <0 0xe6150000 0 0x1000>;
++ interrupts = <GIC_SPI 393 IRQ_TYPE_LEVEL_HIGH>;
++ clocks = <&cpg CPG_MOD 824>;
++ power-domains = <&sysc R8A7796_PD_A3IR>;
++ };
++
+ fcpcs: vcp4@fe90f000 {
+ compatible = "renesas,vcp4-fcpcs";
+ reg = <0 0xfe90f000 0 0x200>;
+--
+2.7.4
+
diff --git a/bsp/meta-rcar/meta-rcar-gen3-adas/recipes-kernel/linux/linux-renesas/0051-arm64-renesas-r8a7798-Add-Renesas-R8A7798-SoC-suppor.patch b/bsp/meta-rcar/meta-rcar-gen3-adas/recipes-kernel/linux/linux-renesas/0051-arm64-renesas-r8a7798-Add-Renesas-R8A7798-SoC-suppor.patch
new file mode 100644
index 00000000..7d57c38d
--- /dev/null
+++ b/bsp/meta-rcar/meta-rcar-gen3-adas/recipes-kernel/linux/linux-renesas/0051-arm64-renesas-r8a7798-Add-Renesas-R8A7798-SoC-suppor.patch
@@ -0,0 +1,6490 @@
+From e8fd03e53c50c67a2aebf19f39a9f14b583f0e2d Mon Sep 17 00:00:00 2001
+From: Vladimir Barinov <vladimir.barinov@cogentembedded.com>
+Date: Sun, 14 May 2017 14:48:08 +0300
+Subject: [PATCH] arm64: renesas: r8a7798: Add Renesas R8A7798 SoC support
+
+This adds Renesas R8A7798 SoC support
+
+Signed-off-by: Vladimir Barinov <vladimir.barinov@cogentembedded.com>
+Signed-off-by: Mikhail Ulyanov <mikhail.ulyanov@cogentembedded.com>
+---
+ arch/arm64/Kconfig.platforms | 8 +
+ arch/arm64/boot/dts/renesas/r8a7798.dtsi | 1700 +++++++++++++
+ drivers/clk/renesas/Kconfig | 1 +
+ drivers/clk/renesas/Makefile | 1 +
+ drivers/clk/renesas/r8a7798-cpg-mssr.c | 292 +++
+ drivers/clk/renesas/rcar-gen3-cpg.c | 19 +-
+ drivers/clk/renesas/renesas-cpg-mssr.c | 6 +
+ drivers/clk/renesas/renesas-cpg-mssr.h | 1 +
+ drivers/cpufreq/cpufreq-dt-platdev.c | 1 +
+ drivers/gpio/gpio-rcar.c | 4 +
+ drivers/gpu/drm/rcar-du/rcar_du_drv.c | 1 +
+ drivers/gpu/drm/rcar-du/rcar_du_group.c | 5 +-
+ drivers/i2c/busses/i2c-rcar.c | 1 +
+ drivers/iommu/ipmmu-vmsa.c | 3 +
+ drivers/media/platform/soc_camera/Kconfig | 2 +-
+ drivers/media/platform/soc_camera/rcar_csi2.c | 15 +-
+ drivers/media/platform/soc_camera/rcar_vin.c | 97 +-
+ drivers/media/platform/vsp1/vsp1_lif.c | 8 +-
+ drivers/mmc/host/sh_mobile_sdhi.c | 1 +
+ drivers/net/ethernet/renesas/ravb_main.c | 1 +
+ drivers/net/ethernet/renesas/sh_eth.c | 53 +-
+ drivers/net/ethernet/renesas/sh_eth.h | 5 +-
+ drivers/pci/host/pcie-rcar.c | 59 +-
+ drivers/pinctrl/sh-pfc/Kconfig | 5 +
+ drivers/pinctrl/sh-pfc/Makefile | 1 +
+ drivers/pinctrl/sh-pfc/core.c | 6 +
+ drivers/pinctrl/sh-pfc/pfc-r8a7798.c | 3151 +++++++++++++++++++++++++
+ drivers/pinctrl/sh-pfc/sh_pfc.h | 9 +-
+ drivers/soc/renesas/Makefile | 4 +
+ drivers/soc/renesas/r8a7798-sysc.c | 57 +
+ drivers/soc/renesas/rcar-rst.c | 1 +
+ drivers/soc/renesas/rcar-sysc.c | 3 +
+ drivers/soc/renesas/rcar-sysc.h | 1 +
+ drivers/soc/renesas/rcar_ems_ctrl.c | 5 +-
+ drivers/soc/renesas/renesas-soc.c | 8 +
+ drivers/spi/spi-sh-msiof.c | 4 +-
+ drivers/thermal/rcar_gen3_thermal.c | 10 +
+ include/dt-bindings/clock/r8a7798-cpg-mssr.h | 56 +
+ include/dt-bindings/power/r8a7798-sysc.h | 46 +
+ 39 files changed, 5618 insertions(+), 33 deletions(-)
+ create mode 100644 arch/arm64/boot/dts/renesas/r8a7798.dtsi
+ create mode 100644 drivers/clk/renesas/r8a7798-cpg-mssr.c
+ create mode 100644 drivers/pinctrl/sh-pfc/pfc-r8a7798.c
+ create mode 100644 drivers/soc/renesas/r8a7798-sysc.c
+ create mode 100644 include/dt-bindings/clock/r8a7798-cpg-mssr.h
+ create mode 100644 include/dt-bindings/power/r8a7798-sysc.h
+
+diff --git a/arch/arm64/Kconfig.platforms b/arch/arm64/Kconfig.platforms
+index 9cebaad..3646b6e 100644
+--- a/arch/arm64/Kconfig.platforms
++++ b/arch/arm64/Kconfig.platforms
+@@ -174,6 +174,14 @@ config ARCH_R8A7797
+ help
+ This enables support for the Renesas R-Car V3M SoC.
+
++config ARCH_R8A7798
++ bool "Renesas R-Car V3H SoC Platform"
++ select SYS_SUPPORTS_SH_TMU
++ select SYS_SUPPORTS_SH_CMT
++ depends on ARCH_RENESAS
++ help
++ This enables support for the Renesas R-Car V3H SoC.
++
+ config ARCH_STRATIX10
+ bool "Altera's Stratix 10 SoCFPGA Family"
+ help
+diff --git a/arch/arm64/boot/dts/renesas/r8a7798.dtsi b/arch/arm64/boot/dts/renesas/r8a7798.dtsi
+new file mode 100644
+index 0000000..6412a24
+--- /dev/null
++++ b/arch/arm64/boot/dts/renesas/r8a7798.dtsi
+@@ -0,0 +1,1700 @@
++/*
++ * Device Tree Source for the r8a7798 SoC
++ *
++ * Copyright (C) 2018 Renesas Electronics Corp.
++ * Copyright (C) 2018 Cogent Embedded, Inc.
++ *
++ * This file is licensed under the terms of the GNU General Public License
++ * version 2. This program is licensed "as is" without any warranty of any
++ * kind, whether express or implied.
++ */
++
++#include <dt-bindings/clock/r8a7798-cpg-mssr.h>
++#include <dt-bindings/interrupt-controller/arm-gic.h>
++#include <dt-bindings/power/r8a7798-sysc.h>
++
++/ {
++ compatible = "renesas,r8a7798";
++ #address-cells = <2>;
++ #size-cells = <2>;
++
++ aliases {
++ csi2_40 = &csi2_40;
++ csi2_41 = &csi2_41;
++ i2c0 = &i2c0;
++ i2c1 = &i2c1;
++ i2c2 = &i2c2;
++ i2c3 = &i2c3;
++ i2c4 = &i2c4;
++ i2c5 = &i2c5;
++ spi1 = &msiof0;
++ spi2 = &msiof1;
++ spi3 = &msiof2;
++ spi4 = &msiof3;
++ vin0 = &vin0;
++ vin1 = &vin1;
++ vin2 = &vin2;
++ vin3 = &vin3;
++ vin4 = &vin4;
++ vin5 = &vin5;
++ vin6 = &vin6;
++ vin7 = &vin7;
++ vin8 = &vin8;
++ vin9 = &vin9;
++ vin10 = &vin10;
++ vin11 = &vin11;
++ vin12 = &vin12;
++ vin13 = &vin13;
++ vin14 = &vin14;
++ vin15 = &vin15;
++ tsc0 = &tsc1;
++ tsc1 = &tsc2;
++ };
++
++ psci {
++ compatible = "arm,psci-1.0";
++ method = "smc";
++ };
++
++ cpus {
++ #address-cells = <1>;
++ #size-cells = <0>;
++
++ a53_0: cpu@0 {
++ compatible = "arm,cortex-a53", "arm,armv8";
++ reg = <0x0>;
++ device_type = "cpu";
++ power-domains = <&sysc R8A7798_PD_CA53_CPU0>;
++ next-level-cache = <&L2_CA53>;
++ enable-method = "psci";
++ cpu-idle-states = <&CPU_SLEEP_0>;
++ #cooling-cells = <2>;
++ dynamic-power-coefficient = <277>;
++ cooling-min-level = <0>;
++ cooling-max-level = <2>;
++ clocks =<&cpg CPG_CORE R8A7798_CLK_Z2>;
++ operating-points-v2 = <&cluster0_opp_tb0>;
++ /*cpu-supply = <&vdd_dvfs>;*/
++ };
++
++ a53_1: cpu@1 {
++ compatible = "arm,cortex-a53","arm,armv8";
++ reg = <0x1>;
++ device_type = "cpu";
++ power-domains = <&sysc R8A7798_PD_CA53_CPU1>;
++ next-level-cache = <&L2_CA53>;
++ enable-method = "psci";
++ cpu-idle-states = <&CPU_SLEEP_0>;
++ operating-points-v2 = <&cluster0_opp_tb0>;
++ };
++
++ a53_2: cpu@2 {
++ compatible = "arm,cortex-a53","arm,armv8";
++ reg = <0x2>;
++ device_type = "cpu";
++ power-domains = <&sysc R8A7798_PD_CA53_CPU2>;
++ next-level-cache = <&L2_CA53>;
++ enable-method = "psci";
++ cpu-idle-states = <&CPU_SLEEP_0>;
++ operating-points-v2 = <&cluster0_opp_tb0>;
++ };
++
++ a53_3: cpu@3 {
++ compatible = "arm,cortex-a53","arm,armv8";
++ reg = <0x3>;
++ device_type = "cpu";
++ power-domains = <&sysc R8A7798_PD_CA53_CPU3>;
++ next-level-cache = <&L2_CA53>;
++ enable-method = "psci";
++ cpu-idle-states = <&CPU_SLEEP_0>;
++ operating-points-v2 = <&cluster0_opp_tb0>;
++ };
++
++ idle-states {
++ entry-method = "psci";
++
++ CPU_SLEEP_0: cpu-sleep-0 {
++ compatible = "arm,idle-state";
++ arm,psci-suspend-param = <0x0010000>;
++ local-timer-stop;
++ entry-latency-us = <639>;
++ exit-latency-us = <680>;
++ min-residency-us = <1088>;
++ status = "disabled";
++ };
++ };
++ };
++
++ L2_CA53: cache-controller@1 {
++ compatible = "cache";
++ power-domains = <&sysc R8A7798_PD_CA53_SCU>;
++ cache-unified;
++ cache-level = <2>;
++ };
++
++ cluster0_opp_tb0: opp_table0 {
++ compatible = "operating-points-v2";
++ opp-shared;
++
++ opp@1000000000 {
++ opp-hz = /bits/ 64 <1000000000>;
++ opp-microvolt = <850000>; /* TBD; section 87.2 */
++ clock-latency-ns = <300000>;
++ };
++ };
++
++ extal_clk: extal {
++ compatible = "fixed-clock";
++ #clock-cells = <0>;
++ /* This value must be overridden by the board */
++ clock-frequency = <0>;
++ };
++
++ extalr_clk: extalr {
++ compatible = "fixed-clock";
++ #clock-cells = <0>;
++ /* This value must be overridden by the board */
++ clock-frequency = <0>;
++ };
++
++ can_clk: can {
++ compatible = "fixed-clock";
++ #clock-cells = <0>;
++ clock-frequency = <0>;
++ };
++
++ /* MSIOF reference clock - to be overridden by boards that provide it */
++ msiof_ref_clk: msiof-ref-clock {
++ compatible = "fixed-clock";
++ #clock-cells = <0>;
++ clock-frequency = <0>;
++ };
++
++ /* External PCIe clock - can be overridden by the board */
++ pcie_bus_clk: pcie_bus {
++ compatible = "fixed-clock";
++ #clock-cells = <0>;
++ clock-frequency = <0>;
++ };
++
++ /* External SCIF clock - to be overridden by boards that provide it */
++ scif_clk: scif {
++ compatible = "fixed-clock";
++ #clock-cells = <0>;
++ clock-frequency = <0>;
++ };
++
++ /* DU input dot clock - tob be overriden by boards that provide it */
++ du_dotclkin0: dclkin-0 {
++ compatible = "fixed-clock";
++ #clock-cells = <0>;
++ clock-frequency = <148500000>;
++ };
++
++ soc {
++ compatible = "simple-bus";
++ interrupt-parent = <&gic>;
++
++ #address-cells = <2>;
++ #size-cells = <2>;
++ ranges;
++
++ gic: interrupt-controller@0xf1010000 {
++ compatible = "arm,gic-400";
++ #interrupt-cells = <3>;
++ #address-cells = <0>;
++ interrupt-controller;
++ reg = <0x0 0xf1010000 0 0x1000>,
++ <0x0 0xf1020000 0 0x20000>,
++ <0x0 0xf1040000 0 0x20000>,
++ <0x0 0xf1060000 0 0x20000>;
++ interrupts = <GIC_PPI 9
++ (GIC_CPU_MASK_SIMPLE(8) | IRQ_TYPE_LEVEL_HIGH)>;
++ };
++
++ gpio0: gpio@e6050000 {
++ compatible = "renesas,gpio-r8a7798",
++ "renesas,gpio-rcar";
++ reg = <0 0xe6050000 0 0x50>;
++ interrupts = <GIC_SPI 4 IRQ_TYPE_LEVEL_HIGH>;
++ #gpio-cells = <2>;
++ gpio-controller;
++ gpio-ranges = <&pfc 0 0 22>;
++ #interrupt-cells = <2>;
++ interrupt-controller;
++ clocks = <&cpg CPG_MOD 912>;
++ power-domains = <&sysc R8A7798_PD_ALWAYS_ON>;
++ };
++
++ gpio1: gpio@e6051000 {
++ compatible = "renesas,gpio-r8a7798",
++ "renesas,gpio-rcar";
++ reg = <0 0xe6051000 0 0x50>;
++ interrupts = <GIC_SPI 5 IRQ_TYPE_LEVEL_HIGH>;
++ #gpio-cells = <2>;
++ gpio-controller;
++ gpio-ranges = <&pfc 0 32 28>;
++ #interrupt-cells = <2>;
++ interrupt-controller;
++ clocks = <&cpg CPG_MOD 911>;
++ power-domains = <&sysc R8A7798_PD_ALWAYS_ON>;
++ };
++
++ gpio2: gpio@e6052000 {
++ compatible = "renesas,gpio-r8a7798",
++ "renesas,gpio-rcar";
++ reg = <0 0xe6052000 0 0x50>;
++ interrupts = <GIC_SPI 6 IRQ_TYPE_LEVEL_HIGH>;
++ #gpio-cells = <2>;
++ gpio-controller;
++ gpio-ranges = <&pfc 0 64 29>;
++ #interrupt-cells = <2>;
++ interrupt-controller;
++ clocks = <&cpg CPG_MOD 910>;
++ power-domains = <&sysc R8A7798_PD_ALWAYS_ON>;
++ };
++
++ gpio3: gpio@e6053000 {
++ compatible = "renesas,gpio-r8a7798",
++ "renesas,gpio-rcar";
++ reg = <0 0xe6053000 0 0x50>;
++ interrupts = <GIC_SPI 7 IRQ_TYPE_LEVEL_HIGH>;
++ #gpio-cells = <2>;
++ gpio-controller;
++ gpio-ranges = <&pfc 0 96 17>;
++ #interrupt-cells = <2>;
++ interrupt-controller;
++ clocks = <&cpg CPG_MOD 909>;
++ power-domains = <&sysc R8A7798_PD_ALWAYS_ON>;
++ };
++
++ gpio4: gpio@e6054000 {
++ compatible = "renesas,gpio-r8a7798",
++ "renesas,gpio-rcar";
++ reg = <0 0xe6054000 0 0x50>;
++ interrupts = <GIC_SPI 8 IRQ_TYPE_LEVEL_HIGH>;
++ #gpio-cells = <2>;
++ gpio-controller;
++ gpio-ranges = <&pfc 0 128 25>;
++ #interrupt-cells = <2>;
++ interrupt-controller;
++ clocks = <&cpg CPG_MOD 908>;
++ power-domains = <&sysc R8A7798_PD_ALWAYS_ON>;
++ };
++
++ gpio5: gpio@e6055000 {
++ compatible = "renesas,gpio-r8a7798",
++ "renesas,gpio-rcar";
++ reg = <0 0xe6055000 0 0x50>;
++ interrupts = <GIC_SPI 9 IRQ_TYPE_LEVEL_HIGH>;
++ #gpio-cells = <2>;
++ gpio-controller;
++ gpio-ranges = <&pfc 0 160 15>;
++ #interrupt-cells = <2>;
++ interrupt-controller;
++ clocks = <&cpg CPG_MOD 907>;
++ power-domains = <&sysc R8A7798_PD_ALWAYS_ON>;
++ };
++
++ pmu_a53 {
++ compatible = "arm,cortex-a53-pmu";
++ interrupts = <GIC_SPI 84 IRQ_TYPE_LEVEL_HIGH>,
++ <GIC_SPI 85 IRQ_TYPE_LEVEL_HIGH>,
++ <GIC_SPI 86 IRQ_TYPE_LEVEL_HIGH>,
++ <GIC_SPI 87 IRQ_TYPE_LEVEL_HIGH>;
++ interrupt-affinity = <&a53_0>,
++ <&a53_1>,
++ <&a53_2>,
++ <&a53_3>;
++ };
++
++ timer {
++ compatible = "arm,armv8-timer";
++ interrupts = <GIC_PPI 13
++ (GIC_CPU_MASK_SIMPLE(8) | IRQ_TYPE_LEVEL_LOW)>,
++ <GIC_PPI 14
++ (GIC_CPU_MASK_SIMPLE(8) | IRQ_TYPE_LEVEL_LOW)>,
++ <GIC_PPI 11
++ (GIC_CPU_MASK_SIMPLE(8) | IRQ_TYPE_LEVEL_LOW)>,
++ <GIC_PPI 10
++ (GIC_CPU_MASK_SIMPLE(8) | IRQ_TYPE_LEVEL_LOW)>;
++ };
++
++ wdt0: wdt@e6020000 {
++ compatible = "renesas,r8a7798-wdt", "renesas,rcar-gen3-wdt";
++ reg = <0 0xe6020000 0 0x0c>;
++ clocks = <&cpg CPG_MOD 402>;
++ power-domains = <&sysc R8A7798_PD_ALWAYS_ON>;
++ status = "disabled";
++ };
++
++ cpg: clock-controller@e6150000 {
++ compatible = "renesas,r8a7798-cpg-mssr";
++ reg = <0 0xe6150000 0 0x1000>;
++ clocks = <&extal_clk>, <&extalr_clk>;
++ clock-names = "extal", "extalr";
++ #clock-cells = <2>;
++ #power-domain-cells = <0>;
++ };
++
++ csi2_40: csi2@feaa0000 {
++ compatible = "renesas,r8a7798-csi2";
++ reg = <0 0xfeaa0000 0 0x10000>;
++ interrupts = <GIC_SPI 246 IRQ_TYPE_LEVEL_HIGH>;
++ clocks = <&cpg CPG_MOD 716>;
++ power-domains = <&sysc R8A7798_PD_ALWAYS_ON>;
++ status = "disabled";
++ };
++
++ csi2_41: csi2@feab0000 {
++ compatible = "renesas,r8a7798-csi2";
++ reg = <0 0xfeab0000 0 0x10000>;
++ interrupts = <GIC_SPI 247 IRQ_TYPE_LEVEL_HIGH>;
++ clocks = <&cpg CPG_MOD 715>;
++ power-domains = <&sysc R8A7798_PD_ALWAYS_ON>;
++ status = "disabled";
++ };
++
++ prr: chipid@fff00044 {
++ compatible = "renesas,prr";
++ reg = <0 0xfff00044 0 4>;
++ };
++
++ rst: reset-controller@e6160000 {
++ compatible = "renesas,r8a7798-rst";
++ reg = <0 0xe6160000 0 0x0200>;
++ };
++
++ sysc: system-controller@e6180000 {
++ compatible = "renesas,r8a7798-sysc";
++ reg = <0 0xe6180000 0 0x0440>;
++ #power-domain-cells = <1>;
++ };
++
++ pfc: pfc@e6060000 {
++ compatible = "renesas,pfc-r8a7798";
++ reg = <0 0xe6060000 0 0x50c>;
++ };
++
++ intc_ex: interrupt-controller@e61c0000 {
++ compatible = "renesas,intc-ex-r8a7798", "renesas,irqc";
++ #interrupt-cells = <2>;
++ interrupt-controller;
++ reg = <0 0xe61c0000 0 0x200>;
++ interrupts = <GIC_SPI 0 IRQ_TYPE_LEVEL_HIGH
++ GIC_SPI 1 IRQ_TYPE_LEVEL_HIGH
++ GIC_SPI 2 IRQ_TYPE_LEVEL_HIGH
++ GIC_SPI 3 IRQ_TYPE_LEVEL_HIGH
++ GIC_SPI 18 IRQ_TYPE_LEVEL_HIGH
++ GIC_SPI 161 IRQ_TYPE_LEVEL_HIGH>; /* SPI1:IRQ1, SPI2:IRQ2, SPI3:IRQ3, SPI18:IRQ4, SPI161:IRQ5 */
++ clocks = <&cpg CPG_MOD 407>; /* RMSTPCR4/bit7:INTC-EX */
++ power-domains = <&sysc R8A7798_PD_ALWAYS_ON>;
++ };
++
++ ipmmu_vi: mmu@febd0000 {
++ compatible = "renesas,ipmmu-r8a7798";
++ reg = <0 0xfebd0000 0 0x1000>; /* IPMMU-VI */
++ renesas,ipmmu-main = <&ipmmu_mm 14>;
++ #iommu-cells = <1>;
++ status = "disabled";
++ };
++
++ ipmmu_vc: mmu@fe6b0000 {
++ compatible = "renesas,ipmmu-r8a7798";
++ reg = <0 0xfe6b0000 0 0x1000>; /* IPMMU-VC */
++ renesas,ipmmu-main = <&ipmmu_mm 12>;
++ #iommu-cells = <1>;
++ status = "disabled";
++ };
++
++ ipmmu_ir: mmu@ff8b0000 {
++ compatible = "renesas,ipmmu-r8a7798";
++ reg = <0 0xff8b0000 0 0x1000>; /* IPMMU-IR */
++ renesas,ipmmu-main = <&ipmmu_mm 3>;
++ #iommu-cells = <1>;
++ status = "disabled";
++ };
++
++ ipmmu_rt: mmu@ffc80000 {
++ compatible = "renesas,ipmmu-r8a7798";
++ reg = <0 0xffc80000 0 0x1000>; /* IPMMU-RT */
++ renesas,ipmmu-main = <&ipmmu_mm 10>;
++ #iommu-cells = <1>;
++ status = "disabled";
++ };
++
++ ipmmu_ds0: mmu@e6740000 {
++ compatible = "renesas,ipmmu-r8a7798";
++ reg = <0 0xe6740000 0 0x1000>; /* IPMMU-DS1 */
++ renesas,ipmmu-main = <&ipmmu_mm 0>;
++ #iommu-cells = <1>;
++ status = "disabled";
++ };
++
++ ipmmu_vip0: mmu@e7b00000 {
++ compatible = "renesas,ipmmu-r8a7798";
++ reg = <0 0xe7b00000 0 0x1000>; /* IPMMU-VIP0 */
++ renesas,ipmmu-main = <&ipmmu_mm 0>; /* FIXME missing in datasheet */
++ #iommu-cells = <1>;
++ status = "disabled";
++ };
++
++ ipmmu_vip1: mmu@e7960000 {
++ compatible = "renesas,ipmmu-r8a7798";
++ reg = <0 0xe7960000 0 0x1000>; /* IPMMU-VIP1 */
++ renesas,ipmmu-main = <&ipmmu_mm 0>; /* FIXME missing in datasheet */
++ #iommu-cells = <1>;
++ status = "disabled";
++ };
++
++ ipmmu_mm: mmu@e67b0000 {
++ compatible = "renesas,ipmmu-r8a7798";
++ reg = <0 0xe67b0000 0 0x1000>; /* IPMMU-MM */
++ interrupts = <GIC_SPI 196 IRQ_TYPE_LEVEL_HIGH>,
++ <GIC_SPI 197 IRQ_TYPE_LEVEL_HIGH>;
++ #iommu-cells = <1>;
++ status = "disabled";
++ };
++
++ dmac1: dma-controller@e7300000 {
++ compatible = "renesas,dmac-r8a7798",
++ "renesas,rcar-dmac";
++ reg = <0 0xe7300000 0 0x10000>;
++ interrupts = <GIC_SPI 220 IRQ_TYPE_LEVEL_HIGH
++ GIC_SPI 216 IRQ_TYPE_LEVEL_HIGH
++ GIC_SPI 217 IRQ_TYPE_LEVEL_HIGH
++ GIC_SPI 218 IRQ_TYPE_LEVEL_HIGH
++ GIC_SPI 219 IRQ_TYPE_LEVEL_HIGH
++ GIC_SPI 308 IRQ_TYPE_LEVEL_HIGH
++ GIC_SPI 309 IRQ_TYPE_LEVEL_HIGH
++ GIC_SPI 310 IRQ_TYPE_LEVEL_HIGH
++ GIC_SPI 311 IRQ_TYPE_LEVEL_HIGH
++ GIC_SPI 353 IRQ_TYPE_LEVEL_HIGH
++ GIC_SPI 354 IRQ_TYPE_LEVEL_HIGH
++ GIC_SPI 355 IRQ_TYPE_LEVEL_HIGH
++ GIC_SPI 356 IRQ_TYPE_LEVEL_HIGH
++ GIC_SPI 357 IRQ_TYPE_LEVEL_HIGH
++ GIC_SPI 358 IRQ_TYPE_LEVEL_HIGH
++ GIC_SPI 359 IRQ_TYPE_LEVEL_HIGH
++ GIC_SPI 360 IRQ_TYPE_LEVEL_HIGH>;
++
++ interrupt-names = "error",
++ "ch0", "ch1", "ch2", "ch3",
++ "ch4", "ch5", "ch6", "ch7",
++ "ch8", "ch9", "ch10", "ch11",
++ "ch12", "ch13", "ch14", "ch15";
++ clocks = <&cpg CPG_MOD 218>;
++ clock-names = "fck";
++ power-domains = <&sysc R8A7798_PD_ALWAYS_ON>;
++ #dma-cells = <1>;
++ dma-channels = <16>;
++ iommus = <&ipmmu_ds0 0>, <&ipmmu_ds0 1>,
++ <&ipmmu_ds0 2>, <&ipmmu_ds0 3>,
++ <&ipmmu_ds0 4>, <&ipmmu_ds0 5>,
++ <&ipmmu_ds0 6>, <&ipmmu_ds0 7>,
++ <&ipmmu_ds0 8>, <&ipmmu_ds0 9>,
++ <&ipmmu_ds0 10>, <&ipmmu_ds0 11>,
++ <&ipmmu_ds0 12>, <&ipmmu_ds0 13>,
++ <&ipmmu_ds0 14>, <&ipmmu_ds0 15>;
++ };
++
++ dmac2: dma-controller@e7310000 {
++ compatible = "renesas,dmac-r8a7798",
++ "renesas,rcar-dmac";
++ reg = <0 0xe7310000 0 0x10000>;
++ interrupts = <GIC_SPI 307 IRQ_TYPE_LEVEL_HIGH
++ GIC_SPI 312 IRQ_TYPE_LEVEL_HIGH
++ GIC_SPI 313 IRQ_TYPE_LEVEL_HIGH
++ GIC_SPI 314 IRQ_TYPE_LEVEL_HIGH
++ GIC_SPI 315 IRQ_TYPE_LEVEL_HIGH
++ GIC_SPI 316 IRQ_TYPE_LEVEL_HIGH
++ GIC_SPI 317 IRQ_TYPE_LEVEL_HIGH
++ GIC_SPI 318 IRQ_TYPE_LEVEL_HIGH
++ GIC_SPI 319 IRQ_TYPE_LEVEL_HIGH
++ GIC_SPI 361 IRQ_TYPE_LEVEL_HIGH
++ GIC_SPI 362 IRQ_TYPE_LEVEL_HIGH
++ GIC_SPI 363 IRQ_TYPE_LEVEL_HIGH
++ GIC_SPI 364 IRQ_TYPE_LEVEL_HIGH
++ GIC_SPI 365 IRQ_TYPE_LEVEL_HIGH
++ GIC_SPI 366 IRQ_TYPE_LEVEL_HIGH
++ GIC_SPI 367 IRQ_TYPE_LEVEL_HIGH
++ GIC_SPI 368 IRQ_TYPE_LEVEL_HIGH>; /* SPI307::SYS-DMAC2 err,
++ SPI312~319:SYS-DMAC2.ch0~SYS-DMAC1.ch7 */
++ interrupt-names = "error",
++ "ch0", "ch1", "ch2", "ch3",
++ "ch4", "ch5", "ch6", "ch7",
++ "ch8", "ch9", "ch10", "ch11",
++ "ch12", "ch13", "ch14", "ch15";
++ clocks = <&cpg CPG_MOD 217>; /* RMSTPCR2/bit17:SYS-DMAC2 */
++ clock-names = "fck";
++ power-domains = <&sysc R8A7798_PD_ALWAYS_ON>;
++ #dma-cells = <1>;
++ dma-channels = <16>;
++ iommus = <&ipmmu_ds0 16>, <&ipmmu_ds0 17>,
++ <&ipmmu_ds0 18>, <&ipmmu_ds0 19>,
++ <&ipmmu_ds0 20>, <&ipmmu_ds0 21>,
++ <&ipmmu_ds0 22>, <&ipmmu_ds0 23>,
++ <&ipmmu_ds0 24>, <&ipmmu_ds0 25>,
++ <&ipmmu_ds0 26>, <&ipmmu_ds0 27>,
++ <&ipmmu_ds0 28>, <&ipmmu_ds0 29>,
++ <&ipmmu_ds0 30>, <&ipmmu_ds0 31>;
++ };
++
++ avb: ethernet@e6800000 {
++ compatible = "renesas,etheravb-r8a7798",
++ "renesas,etheravb-rcar-gen3";
++ reg = <0 0xe6800000 0 0x800>, <0 0xe6a00000 0 0x10000>;
++ interrupts = <GIC_SPI 39 IRQ_TYPE_LEVEL_HIGH>,
++ <GIC_SPI 40 IRQ_TYPE_LEVEL_HIGH>,
++ <GIC_SPI 41 IRQ_TYPE_LEVEL_HIGH>,
++ <GIC_SPI 42 IRQ_TYPE_LEVEL_HIGH>,
++ <GIC_SPI 43 IRQ_TYPE_LEVEL_HIGH>,
++ <GIC_SPI 44 IRQ_TYPE_LEVEL_HIGH>,
++ <GIC_SPI 45 IRQ_TYPE_LEVEL_HIGH>,
++ <GIC_SPI 46 IRQ_TYPE_LEVEL_HIGH>,
++ <GIC_SPI 47 IRQ_TYPE_LEVEL_HIGH>,
++ <GIC_SPI 48 IRQ_TYPE_LEVEL_HIGH>,
++ <GIC_SPI 49 IRQ_TYPE_LEVEL_HIGH>,
++ <GIC_SPI 50 IRQ_TYPE_LEVEL_HIGH>,
++ <GIC_SPI 51 IRQ_TYPE_LEVEL_HIGH>,
++ <GIC_SPI 52 IRQ_TYPE_LEVEL_HIGH>,
++ <GIC_SPI 53 IRQ_TYPE_LEVEL_HIGH>,
++ <GIC_SPI 54 IRQ_TYPE_LEVEL_HIGH>,
++ <GIC_SPI 55 IRQ_TYPE_LEVEL_HIGH>,
++ <GIC_SPI 56 IRQ_TYPE_LEVEL_HIGH>,
++ <GIC_SPI 57 IRQ_TYPE_LEVEL_HIGH>,
++ <GIC_SPI 58 IRQ_TYPE_LEVEL_HIGH>,
++ <GIC_SPI 59 IRQ_TYPE_LEVEL_HIGH>,
++ <GIC_SPI 60 IRQ_TYPE_LEVEL_HIGH>,
++ <GIC_SPI 61 IRQ_TYPE_LEVEL_HIGH>,
++ <GIC_SPI 62 IRQ_TYPE_LEVEL_HIGH>,
++ <GIC_SPI 63 IRQ_TYPE_LEVEL_HIGH>; /* SPI39~63:Ethernet AVB.ch0~24 */
++ /* @@ errreq_avb_p[0]~[3] add (T.B.D) */
++ interrupt-names = "ch0", "ch1", "ch2", "ch3",
++ "ch4", "ch5", "ch6", "ch7",
++ "ch8", "ch9", "ch10", "ch11",
++ "ch12", "ch13", "ch14", "ch15",
++ "ch16", "ch17", "ch18", "ch19",
++ "ch20", "ch21", "ch22", "ch23",
++ "ch24";
++ clocks = <&cpg CPG_MOD 812>; /* RMSTPCR8/bit12:EAVB-IF */
++ power-domains = <&sysc R8A7798_PD_ALWAYS_ON>;
++ phy-mode = "rgmii-id";
++ #address-cells = <1>;
++ #size-cells = <0>;
++ };
++
++ gether: ethernet@e7400000 {
++ compatible = "renesas,gether-r8a7798";
++ reg = <0 0xe7400000 0 0x1000>;
++ interrupts = <GIC_SPI 21 IRQ_TYPE_LEVEL_HIGH>;
++ clocks = <&cpg CPG_MOD 813>;
++ power-domains = <&sysc R8A7798_PD_ALWAYS_ON>;
++ phy-mode = "rgmii";
++ #address-cells = <1>;
++ #size-cells = <0>;
++ };
++
++ canfd: canfd@e66c0000 {
++ compatible = "renesas,r8a7798-canfd",
++ "renesas,rcar-gen3-canfd";
++ reg = <0 0xe66c0000 0 0x8000>;
++ interrupts = <GIC_SPI 29 IRQ_TYPE_LEVEL_HIGH>,
++ <GIC_SPI 30 IRQ_TYPE_LEVEL_HIGH>;
++ clocks = <&cpg CPG_MOD 914>,
++ <&cpg CPG_CORE R8A7798_CLK_CANFD>,
++ <&can_clk>;
++ clock-names = "fck", "canfd", "can_clk";
++ assigned-clocks = <&cpg CPG_CORE R8A7798_CLK_CANFD>;
++ assigned-clock-rates = <40000000>;
++ power-domains = <&sysc R8A7798_PD_ALWAYS_ON>;
++ status = "disabled";
++
++ channel0 {
++ status = "disabled";
++ };
++
++ channel1 {
++ status = "disabled";
++ };
++ };
++
++
++ cmt0: timer@e60f0000 {
++ compatible = "renesas,cmt-48-r8a7798", "renesas,cmt-48-gen2";
++ reg = <0 0xe60f0000 0 0x1004>;
++ interrupts = <GIC_SPI 142 IRQ_TYPE_LEVEL_HIGH>,
++ <GIC_SPI 143 IRQ_TYPE_LEVEL_HIGH>;
++ clocks = <&cpg CPG_MOD 303>;
++ clock-names = "fck";
++ power-domains = <&sysc R8A7798_PD_ALWAYS_ON>;
++
++ renesas,channels-mask = <0x60>;
++
++ status = "disabled";
++ };
++
++ cmt1: timer@e6130000 {
++ compatible = "renesas,cmt-48-r8a7798", "renesas,cmt-48-gen2";
++ reg = <0 0xe6130000 0 0x1004>;
++ interrupts = <GIC_SPI 120 IRQ_TYPE_LEVEL_HIGH>,
++ <GIC_SPI 121 IRQ_TYPE_LEVEL_HIGH>,
++ <GIC_SPI 122 IRQ_TYPE_LEVEL_HIGH>,
++ <GIC_SPI 123 IRQ_TYPE_LEVEL_HIGH>,
++ <GIC_SPI 124 IRQ_TYPE_LEVEL_HIGH>,
++ <GIC_SPI 125 IRQ_TYPE_LEVEL_HIGH>,
++ <GIC_SPI 126 IRQ_TYPE_LEVEL_HIGH>,
++ <GIC_SPI 127 IRQ_TYPE_LEVEL_HIGH>;
++ clocks = <&cpg CPG_MOD 302>;
++ clock-names = "fck";
++ power-domains = <&sysc R8A7798_PD_ALWAYS_ON>;
++
++ renesas,channels-mask = <0xff>;
++
++ status = "disabled";
++ };
++
++ cmt2: timer@e6140000 {
++ compatible = "renesas,cmt-48-r8a7798", "renesas,cmt-48-gen2";
++ reg = <0 0xe6140000 0 0x1004>;
++ interrupts = <GIC_SPI 258 IRQ_TYPE_LEVEL_HIGH>,
++ <GIC_SPI 259 IRQ_TYPE_LEVEL_HIGH>,
++ <GIC_SPI 260 IRQ_TYPE_LEVEL_HIGH>,
++ <GIC_SPI 261 IRQ_TYPE_LEVEL_HIGH>,
++ <GIC_SPI 262 IRQ_TYPE_LEVEL_HIGH>,
++ <GIC_SPI 263 IRQ_TYPE_LEVEL_HIGH>,
++ <GIC_SPI 264 IRQ_TYPE_LEVEL_HIGH>,
++ <GIC_SPI 265 IRQ_TYPE_LEVEL_HIGH>;
++ clocks = <&cpg CPG_MOD 301>;
++ clock-names = "fck";
++ power-domains = <&sysc R8A7798_PD_ALWAYS_ON>;
++
++ renesas,channels-mask = <0xff>;
++
++ status = "disabled";
++ };
++
++ cmt3: timer@e6148000 {
++ compatible = "renesas,cmt-48-r8a7798", "renesas,cmt-48-gen2";
++ reg = <0 0xe6148000 0 0x1004>;
++ interrupts = <GIC_SPI 273 IRQ_TYPE_LEVEL_HIGH>,
++ <GIC_SPI 274 IRQ_TYPE_LEVEL_HIGH>,
++ <GIC_SPI 275 IRQ_TYPE_LEVEL_HIGH>,
++ <GIC_SPI 276 IRQ_TYPE_LEVEL_HIGH>,
++ <GIC_SPI 277 IRQ_TYPE_LEVEL_HIGH>,
++ <GIC_SPI 278 IRQ_TYPE_LEVEL_HIGH>,
++ <GIC_SPI 279 IRQ_TYPE_LEVEL_HIGH>,
++ <GIC_SPI 280 IRQ_TYPE_LEVEL_HIGH>;
++ clocks = <&cpg CPG_MOD 300>;
++ clock-names = "fck";
++ power-domains = <&sysc R8A7798_PD_ALWAYS_ON>;
++
++ renesas,channels-mask = <0xff>;
++
++ status = "disabled";
++ };
++
++ tpu: pwm@e6e80000 {
++ compatible = "renesas,tpu-r8a7798", "renesas,tpu";
++ reg = <0 0xe6e80000 0 0x100>;
++ clocks = <&cpg CPG_MOD 304>;
++ power-domains = <&sysc R8A7798_PD_ALWAYS_ON>;
++ status = "disabled";
++ #pwm-cells = <4>;
++ };
++
++ tmu0: timer@e61e0000 {
++ compatible = "renesas,tmu-r8a7798", "renesas,tmu";
++ reg = <0 0xe61e0000 0 0x30>;
++ interrupts = <GIC_SPI 136 IRQ_TYPE_LEVEL_HIGH>,
++ <GIC_SPI 137 IRQ_TYPE_LEVEL_HIGH>,
++ <GIC_SPI 138 IRQ_TYPE_LEVEL_HIGH>;
++ clocks = <&cpg CPG_MOD 125>;
++ clock-names = "fck";
++ power-domains = <&sysc R8A7798_PD_ALWAYS_ON>;
++ #renesas,channels = <3>;
++ status = "disabled";
++ };
++
++ tmu1: timer@e6fc0000 {
++ compatible = "renesas,tmu-r8a7798", "renesas,tmu";
++ reg = <0 0xe6fc0000 0 0x30>;
++ interrupts = <GIC_SPI 128 IRQ_TYPE_LEVEL_HIGH>,
++ <GIC_SPI 129 IRQ_TYPE_LEVEL_HIGH>,
++ <GIC_SPI 130 IRQ_TYPE_LEVEL_HIGH>,
++ <GIC_SPI 147 IRQ_TYPE_LEVEL_HIGH>;
++ clocks = <&cpg CPG_MOD 124>;
++ clock-names = "fck";
++ power-domains = <&sysc R8A7798_PD_ALWAYS_ON>;
++ #renesas,channels = <3>;
++ status = "disabled";
++ };
++
++ tmu2: timer@e6fd0000 {
++ compatible = "renesas,tmu-r8a7798", "renesas,tmu";
++ reg = <0 0xe6fd0000 0 0x30>;
++ interrupts = <GIC_SPI 303 IRQ_TYPE_LEVEL_HIGH>,
++ <GIC_SPI 304 IRQ_TYPE_LEVEL_HIGH>,
++ <GIC_SPI 305 IRQ_TYPE_LEVEL_HIGH>,
++ <GIC_SPI 306 IRQ_TYPE_LEVEL_HIGH>;
++ clocks = <&cpg CPG_MOD 123>;
++ clock-names = "fck";
++ power-domains = <&sysc R8A7798_PD_ALWAYS_ON>;
++ #renesas,channels = <3>;
++ status = "disabled";
++ };
++
++ tmu3: timer@e6fe0000 {
++ compatible = "renesas,tmu-r8a7798", "renesas,tmu";
++ reg = <0 0xe6fe0000 0 0x30>;
++ interrupts = <GIC_SPI 131 IRQ_TYPE_LEVEL_HIGH>,
++ <GIC_SPI 132 IRQ_TYPE_LEVEL_HIGH>,
++ <GIC_SPI 133 IRQ_TYPE_LEVEL_HIGH>,
++ <GIC_SPI 146 IRQ_TYPE_LEVEL_HIGH>;
++ clocks = <&cpg CPG_MOD 122>;
++ clock-names = "fck";
++ power-domains = <&sysc R8A7798_PD_ALWAYS_ON>;
++ #renesas,channels = <3>;
++ status = "disabled";
++ };
++
++ tmu4: timer@ffc00000 {
++ compatible = "renesas,tmu-r8a7798", "renesas,tmu";
++ reg = <0 0xffc00000 0 0x30>;
++ interrupts = <GIC_SPI 116 IRQ_TYPE_LEVEL_HIGH>,
++ <GIC_SPI 117 IRQ_TYPE_LEVEL_HIGH>,
++ <GIC_SPI 118 IRQ_TYPE_LEVEL_HIGH>,
++ <GIC_SPI 369 IRQ_TYPE_LEVEL_HIGH>;
++ clocks = <&cpg CPG_MOD 121>;
++ clock-names = "fck";
++ power-domains = <&sysc R8A7798_PD_ALWAYS_ON>;
++ #renesas,channels = <3>;
++ status = "disabled";
++ };
++
++ pwm0: pwm@e6e30000 {
++ compatible = "renesas,pwm-r8a7798", "renesas,pwm-rcar";
++ reg = <0 0xe6e30000 0 0x10>;
++ #pwm-cells = <2>;
++ clocks = <&cpg CPG_MOD 523>; /* RMSTPCR5/bit23:PWM */
++ power-domains = <&sysc R8A7798_PD_ALWAYS_ON>;
++ status = "disabled";
++ };
++
++ pwm1: pwm@e6e31000 {
++ compatible = "renesas,pwm-r8a7798", "renesas,pwm-rcar";
++ reg = <0 0xe6e31000 0 0x10>;
++ #pwm-cells = <2>;
++ clocks = <&cpg CPG_MOD 523>; /* RMSTPCR5/bit23:PWM */
++ power-domains = <&sysc R8A7798_PD_ALWAYS_ON>;
++ status = "disabled";
++ };
++
++ pwm2: pwm@e6e32000 {
++ compatible = "renesas,pwm-r8a7798", "renesas,pwm-rcar";
++ reg = <0 0xe6e32000 0 0x10>;
++ #pwm-cells = <2>;
++ clocks = <&cpg CPG_MOD 523>; /* RMSTPCR5/bit23:PWM */
++ power-domains = <&sysc R8A7798_PD_ALWAYS_ON>;
++ status = "disabled";
++ };
++
++ pwm3: pwm@e6e33000 {
++ compatible = "renesas,pwm-r8a7798", "renesas,pwm-rcar";
++ reg = <0 0xe6e33000 0 0x10>;
++ #pwm-cells = <2>;
++ clocks = <&cpg CPG_MOD 523>; /* RMSTPCR5/bit23:PWM */
++ power-domains = <&sysc R8A7798_PD_ALWAYS_ON>;
++ status = "disabled";
++ };
++
++ pwm4: pwm@e6e34000 {
++ compatible = "renesas,pwm-r8a7798", "renesas,pwm-rcar";
++ reg = <0 0xe6e34000 0 0x10>;
++ #pwm-cells = <2>;
++ clocks = <&cpg CPG_MOD 523>; /* RMSTPCR5/bit23:PWM */
++ power-domains = <&sysc R8A7798_PD_ALWAYS_ON>;
++ status = "disabled";
++ };
++
++ hscif0: serial@e6540000 {
++ compatible = "renesas,hscif-r8a7798",
++ "renesas,rcar-gen3-hscif",
++ "renesas,hscif";
++ reg = <0 0xe6540000 0 96>;
++ interrupts = <GIC_SPI 154 IRQ_TYPE_LEVEL_HIGH>; /* SPI154:HSCIF.ch0 */
++ clocks = <&cpg CPG_MOD 520>,
++ <&cpg CPG_CORE R8A7798_CLK_S2D1>,
++ <&scif_clk>; /* RMSTPCR5/bit20:HSCIF0 */
++ clock-names = "fck", "brg_int", "scif_clk";
++ dmas = <&dmac1 0x31>, <&dmac1 0x30>;
++ dma-names = "tx", "rx";
++ power-domains = <&sysc R8A7798_PD_ALWAYS_ON>;
++ status = "disabled";
++ };
++
++ hscif1: serial@e6550000 {
++ compatible = "renesas,hscif-r8a7798",
++ "renesas,rcar-gen3-hscif",
++ "renesas,hscif";
++ reg = <0 0xe6550000 0 96>;
++ interrupts = <GIC_SPI 155 IRQ_TYPE_LEVEL_HIGH>; /* SPI155:HSCIF.ch1 */
++ clocks = <&cpg CPG_MOD 519>,
++ <&cpg CPG_CORE R8A7798_CLK_S2D1>,
++ <&scif_clk>; /* RMSTPCR5/bit19:HSCIF1 */
++ clock-names = "fck", "brg_int", "scif_clk";
++ dmas = <&dmac1 0x33>, <&dmac1 0x32>;
++ dma-names = "tx", "rx";
++ power-domains = <&sysc R8A7798_PD_ALWAYS_ON>;
++ status = "disabled";
++ };
++
++ hscif2: serial@e6560000 {
++ compatible = "renesas,hscif-r8a7798",
++ "renesas,rcar-gen3-hscif",
++ "renesas,hscif";
++ reg = <0 0xe6560000 0 96>;
++ interrupts = <GIC_SPI 144 IRQ_TYPE_LEVEL_HIGH>; /* SPI144:HSCIF.ch2 */
++ clocks = <&cpg CPG_MOD 518>,
++ <&cpg CPG_CORE R8A7798_CLK_S2D1>,
++ <&scif_clk>; /* RMSTPCR5/bit18:HSCIF2 */
++ clock-names = "fck", "brg_int", "scif_clk";
++ dmas = <&dmac1 0x35>, <&dmac1 0x34>;
++ dma-names = "tx", "rx";
++ power-domains = <&sysc R8A7798_PD_ALWAYS_ON>;
++ status = "disabled";
++ };
++
++ hscif3: serial@e66a0000 {
++ compatible = "renesas,hscif-r8a7798",
++ "renesas,rcar-gen3-hscif",
++ "renesas,hscif";
++ reg = <0 0xe66a0000 0 96>;
++ //interrupts = <GIC_SPI 145 IRQ_TYPE_LEVEL_HIGH>; /* SPI145:HSCIF.ch3 */
++ clocks = <&cpg CPG_MOD 517>,
++ <&cpg CPG_CORE R8A7798_CLK_S2D1>,
++ <&scif_clk>; /* RMSTPCR5/bit17:HSCIF3 */
++ clock-names = "fck", "brg_int", "scif_clk";
++ dmas = <&dmac1 0x37>, <&dmac1 0x36>;
++ dma-names = "tx", "rx";
++ power-domains = <&sysc R8A7798_PD_ALWAYS_ON>;
++ status = "disabled";
++ };
++
++ scif0: serial@e6e60000 {
++ compatible = "renesas,scif-r8a7798",
++ "renesas,rcar-gen3-scif", "renesas,scif";
++ reg = <0 0xe6e60000 0 64>;
++ interrupts = <GIC_SPI 152 IRQ_TYPE_LEVEL_HIGH>; /* SPI152:SCIF.ch0 */
++ clocks = <&cpg CPG_MOD 207>,
++ <&cpg CPG_CORE R8A7798_CLK_S2D1>,
++ <&scif_clk>; /* RMSTPCR2/bit7:SCIF0 */
++ /*clock-names = "fck", "sck", "brg_int", "scif_clk"; */
++ clock-names = "fck";
++ dmas = <&dmac1 0x51>, <&dmac1 0x50>;
++ dma-names = "tx", "rx";
++ power-domains = <&sysc R8A7798_PD_ALWAYS_ON>;
++ status = "disabled";
++ };
++
++ scif1: serial@e6e68000 {
++ compatible = "renesas,scif-r8a7798",
++ "renesas,rcar-gen3-scif", "renesas,scif";
++ reg = <0 0xe6e68000 0 64>;
++ interrupts = <GIC_SPI 153 IRQ_TYPE_LEVEL_HIGH>; /* SPI153:SCIF.ch1 */
++ clocks = <&cpg CPG_MOD 206>,
++ <&cpg CPG_CORE R8A7798_CLK_S2D1>,
++ <&scif_clk>; /* RMSTPCR2/bit6:SCIF1 */
++ clock-names = "fck", "brg_int", "scif_clk";
++ dmas = <&dmac1 0x53>, <&dmac1 0x52>;
++ dma-names = "tx", "rx";
++ power-domains = <&sysc R8A7798_PD_ALWAYS_ON>;
++ status = "disabled";
++ };
++
++ scif3: serial@e6c50000 {
++ compatible = "renesas,scif-r8a7798",
++ "renesas,rcar-gen3-scif", "renesas,scif";
++ reg = <0 0xe6c50000 0 64>;
++ interrupts = <GIC_SPI 23 IRQ_TYPE_LEVEL_HIGH>; /* SPI23:SCIF.ch3 */
++ clocks = <&cpg CPG_MOD 204>,
++ <&cpg CPG_CORE R8A7798_CLK_S2D1>,
++ <&scif_clk>; /* RMSTPCR2/bit4:SCIF3 */
++ clock-names = "fck", "brg_int", "scif_clk";
++ dmas = <&dmac1 0x57>, <&dmac1 0x56>;
++ dma-names = "tx", "rx";
++ power-domains = <&sysc R8A7798_PD_ALWAYS_ON>;
++ status = "disabled";
++ };
++
++ scif4: serial@e6c40000 {
++ compatible = "renesas,scif-r8a7798",
++ "renesas,rcar-gen3-scif", "renesas,scif";
++ reg = <0 0xe6c40000 0 64>;
++ interrupts = <GIC_SPI 16 IRQ_TYPE_LEVEL_HIGH>; /* SPI16:SCIF.ch4 */
++ clocks = <&cpg CPG_MOD 203>,
++ <&cpg CPG_CORE R8A7798_CLK_S2D1>,
++ <&scif_clk>; /* RMSTPCR2/bit3:SCIF4 */
++ clock-names = "fck", "brg_int", "scif_clk";
++ dmas = <&dmac1 0x59>, <&dmac1 0x58>;
++ dma-names = "tx", "rx";
++ power-domains = <&sysc R8A7798_PD_ALWAYS_ON>;
++ status = "disabled";
++ };
++
++ i2c0: i2c@e6500000 {
++ #address-cells = <1>;
++ #size-cells = <0>;
++ compatible = "renesas,i2c-r8a7798";
++ reg = <0 0xe6500000 0 0x40>;
++ interrupts = <GIC_SPI 287 IRQ_TYPE_LEVEL_HIGH>;
++ clocks = <&cpg CPG_MOD 931>;
++ power-domains = <&sysc R8A7798_PD_ALWAYS_ON>;
++ dmas = <&dmac1 0x91>, <&dmac1 0x90>;
++ dma-names = "tx", "rx";
++ i2c-scl-internal-delay-ns = <6>;
++ status = "disabled";
++ };
++
++ i2c1: i2c@e6508000 {
++ #address-cells = <1>;
++ #size-cells = <0>;
++ compatible = "renesas,i2c-r8a7798";
++ reg = <0 0xe6508000 0 0x40>;
++ interrupts = <GIC_SPI 288 IRQ_TYPE_LEVEL_HIGH>;
++ clocks = <&cpg CPG_MOD 930>;
++ power-domains = <&sysc R8A7798_PD_ALWAYS_ON>;
++ dmas = <&dmac1 0x93>, <&dmac1 0x92>;
++ dma-names = "tx", "rx";
++ i2c-scl-internal-delay-ns = <6>;
++ status = "disabled";
++ };
++
++ i2c2: i2c@e6510000 {
++ #address-cells = <1>;
++ #size-cells = <0>;
++ compatible = "renesas,i2c-r8a7798";
++ reg = <0 0xe6510000 0 0x40>;
++ interrupts = <GIC_SPI 286 IRQ_TYPE_LEVEL_HIGH>;
++ clocks = <&cpg CPG_MOD 929>;
++ power-domains = <&sysc R8A7798_PD_ALWAYS_ON>;
++ dmas = <&dmac1 0x95>, <&dmac1 0x94>;
++ dma-names = "tx", "rx";
++ i2c-scl-internal-delay-ns = <6>;
++ status = "disabled";
++ };
++
++ i2c3: i2c@e66d0000 {
++ #address-cells = <1>;
++ #size-cells = <0>;
++ compatible = "renesas,i2c-r8a7798";
++ reg = <0 0xe66d0000 0 0x40>;
++ interrupts = <GIC_SPI 290 IRQ_TYPE_LEVEL_HIGH>;
++ clocks = <&cpg CPG_MOD 928>;
++ power-domains = <&sysc R8A7798_PD_ALWAYS_ON>;
++ dmas = <&dmac1 0x97>, <&dmac1 0x96>;
++ dma-names = "tx", "rx";
++ i2c-scl-internal-delay-ns = <6>;
++ status = "disabled";
++ };
++
++ i2c4: i2c@e66d8000 {
++ #address-cells = <1>;
++ #size-cells = <0>;
++ compatible = "renesas,i2c-r8a7798";
++ reg = <0 0xe66d8000 0 0x40>;
++ interrupts = <GIC_SPI 19 IRQ_TYPE_LEVEL_HIGH>;
++ clocks = <&cpg CPG_MOD 927>;
++ power-domains = <&sysc R8A7798_PD_ALWAYS_ON>;
++ dmas = <&dmac1 0x99>, <&dmac1 0x98>;
++ dma-names = "tx", "rx";
++ i2c-scl-internal-delay-ns = <6>;
++ status = "disabled";
++ };
++
++ i2c5: i2c@e66e0000 {
++ #address-cells = <1>;
++ #size-cells = <0>;
++ compatible = "renesas,i2c-r8a7798";
++ reg = <0 0xe66e0000 0 0x40>;
++ interrupts = <GIC_SPI 20 IRQ_TYPE_LEVEL_HIGH>;
++ clocks = <&cpg CPG_MOD 00>; /* FIXME missing entry in MSSR */
++ power-domains = <&sysc R8A7798_PD_ALWAYS_ON>;
++ dmas = <&dmac1 0x99>, <&dmac1 0x98>;
++ dma-names = "tx", "rx";
++ i2c-scl-internal-delay-ns = <6>;
++ status = "disabled";
++ };
++
++ msiof0: spi@e6e90000 {
++ #address-cells = <1>;
++ #size-cells = <0>;
++ compatible = "renesas,msiof-r8a7798";
++ reg = <0 0xe6e90000 0 0x64>;
++ interrupts = <GIC_SPI 156 IRQ_TYPE_LEVEL_HIGH>;
++ clocks = <&cpg CPG_MOD 211>, <&msiof_ref_clk>;
++ clock-names = "msiof_clk", "msiof_ref_clk";
++ dmas = <&dmac1 0x41>, <&dmac1 0x40>;
++ dma-names = "tx", "rx";
++ power-domains = <&sysc R8A7798_PD_ALWAYS_ON>;
++ status = "disabled";
++ };
++
++ msiof1: spi@e6ea0000 {
++ #address-cells = <1>;
++ #size-cells = <0>;
++ compatible = "renesas,msiof-r8a7798";
++ reg = <0 0xe6ea0000 0 0x0064>;
++ interrupts = <GIC_SPI 157 IRQ_TYPE_LEVEL_HIGH>;
++ clocks = <&cpg CPG_MOD 210>, <&msiof_ref_clk>;
++ clock-names = "msiof_clk", "msiof_ref_clk";
++ dmas = <&dmac1 0x43>, <&dmac1 0x42>;
++ dma-names = "tx", "rx";
++ power-domains = <&sysc R8A7798_PD_ALWAYS_ON>;
++ status = "disabled";
++ };
++
++ msiof2: spi@e6c00000 {
++ #address-cells = <1>;
++ #size-cells = <0>;
++ compatible = "renesas,msiof-r8a7798";
++ reg = <0 0xe6c00000 0 0x0064>;
++ interrupts = <GIC_SPI 158 IRQ_TYPE_LEVEL_HIGH>;
++ clocks = <&cpg CPG_MOD 209>, <&msiof_ref_clk>;
++ clock-names = "msiof_clk", "msiof_ref_clk";
++ dmas = <&dmac1 0x45>, <&dmac1 0x44>;
++ dma-names = "tx", "rx";
++ power-domains = <&sysc R8A7798_PD_ALWAYS_ON>;
++ status = "disabled";
++ };
++
++ msiof3: spi@e6c10000 {
++ #address-cells = <1>;
++ #size-cells = <0>;
++ compatible = "renesas,msiof-r8a7798";
++ reg = <0 0xe6c10000 0 0x0064>;
++ interrupts = <GIC_SPI 159 IRQ_TYPE_LEVEL_HIGH>;
++ clocks = <&cpg CPG_MOD 208>, <&msiof_ref_clk>;
++ clock-names = "msiof_clk", "msiof_ref_clk";
++ dmas = <&dmac1 0x47>, <&dmac1 0x46>;
++ dma-names = "tx", "rx";
++ power-domains = <&sysc R8A7798_PD_ALWAYS_ON>;
++ status = "disabled";
++ };
++
++
++ pciec: pcie@fe000000 {
++ compatible = "renesas,pcie-r8a7798",
++ "renesas,pcie-rcar-gen3";
++ reg = <0 0xfe000000 0 0x80000>,
++ <0 0xe65d0000 0 0x8000>;
++ #address-cells = <3>;
++ #size-cells = <2>;
++ bus-range = <0x00 0xff>;
++ device_type = "pci";
++ ranges = <0x01000000 0 0x00000000 0 0xfe100000 0 0x00100000
++ 0x02000000 0 0xfe200000 0 0xfe200000 0 0x00200000
++ 0x02000000 0 0x30000000 0 0x30000000 0 0x08000000
++ 0x42000000 0 0x38000000 0 0x38000000 0 0x08000000>;
++ dma-ranges = <0x42000000 0 0x40000000 0 0x40000000 0 0x80000000>;
++ interrupts = <GIC_SPI 148 IRQ_TYPE_LEVEL_HIGH>,
++ <GIC_SPI 149 IRQ_TYPE_LEVEL_HIGH>,
++ <GIC_SPI 150 IRQ_TYPE_LEVEL_HIGH>;
++ #interrupt-cells = <1>;
++ interrupt-map-mask = <0 0 0 0>;
++ interrupt-map = <0 0 0 0 &gic GIC_SPI 148 IRQ_TYPE_LEVEL_HIGH>;
++ clocks = <&cpg CPG_MOD 319>, <&pcie_bus_clk>;
++ clock-names = "pcie", "pcie_bus";
++ power-domains = <&sysc R8A7798_PD_ALWAYS_ON>;
++ status = "disabled";
++ };
++
++ vin0: video@e6ef0000 {
++ compatible = "renesas,vin-r8a7798";
++ reg = <0 0xe6ef0000 0 0x1000>;
++ interrupts = <GIC_SPI 188 IRQ_TYPE_LEVEL_HIGH>;
++ clocks = <&cpg CPG_MOD 811>;
++ power-domains = <&sysc R8A7798_PD_ALWAYS_ON>;
++ status = "disabled";
++ };
++
++ vin1: video@e6ef1000 {
++ compatible = "renesas,vin-r8a7798";
++ reg = <0 0xe6ef1000 0 0x1000>;
++ interrupts = <GIC_SPI 189 IRQ_TYPE_LEVEL_HIGH>;
++ clocks = <&cpg CPG_MOD 810>;
++ power-domains = <&sysc R8A7798_PD_ALWAYS_ON>;
++ status = "disabled";
++ };
++
++ vin2: video@e6ef2000 {
++ compatible = "renesas,vin-r8a7798";
++ reg = <0 0xe6ef2000 0 0x1000>;
++ interrupts = <GIC_SPI 190 IRQ_TYPE_LEVEL_HIGH>;
++ clocks = <&cpg CPG_MOD 809>;
++ power-domains = <&sysc R8A7798_PD_ALWAYS_ON>;
++ status = "disabled";
++ };
++
++ vin3: video@e6ef3000 {
++ compatible = "renesas,vin-r8a7798";
++ reg = <0 0xe6ef3000 0 0x1000>;
++ interrupts = <GIC_SPI 191 IRQ_TYPE_LEVEL_HIGH>;
++ clocks = <&cpg CPG_MOD 808>;
++ power-domains = <&sysc R8A7798_PD_ALWAYS_ON>;
++ status = "disabled";
++ };
++
++ vin4: video@e6ef4000 {
++ compatible = "renesas,vin-r8a7798";
++ reg = <0 0xe6ef4000 0 0x1000>;
++ interrupts = <GIC_SPI 174 IRQ_TYPE_LEVEL_HIGH>;
++ clocks = <&cpg CPG_MOD 807>;
++ power-domains = <&sysc R8A7798_PD_ALWAYS_ON>;
++ status = "disabled";
++ };
++
++ vin5: video@e6ef5000 {
++ compatible = "renesas,vin-r8a7798";
++ reg = <0 0xe6ef5000 0 0x1000>;
++ interrupts = <GIC_SPI 175 IRQ_TYPE_LEVEL_HIGH>;
++ clocks = <&cpg CPG_MOD 806>;
++ power-domains = <&sysc R8A7798_PD_ALWAYS_ON>;
++ status = "disabled";
++ };
++
++ vin6: video@e6ef6000 {
++ compatible = "renesas,vin-r8a7798";
++ reg = <0 0xe6ef6000 0 0x1000>;
++ interrupts = <GIC_SPI 176 IRQ_TYPE_LEVEL_HIGH>;
++ clocks = <&cpg CPG_MOD 805>;
++ power-domains = <&sysc R8A7798_PD_ALWAYS_ON>;
++ status = "disabled";
++ };
++
++ vin7: video@e6ef7000 {
++ compatible = "renesas,vin-r8a7798";
++ reg = <0 0xe6ef7000 0 0x1000>;
++ interrupts = <GIC_SPI 171 IRQ_TYPE_LEVEL_HIGH>;
++ clocks = <&cpg CPG_MOD 804>;
++ power-domains = <&sysc R8A7798_PD_ALWAYS_ON>;
++ status = "disabled";
++ };
++
++ vin8: video@e6ef8000 {
++ compatible = "renesas,vin-r8a7798";
++ reg = <0 0xe6ef8000 0 0x1000>;
++ interrupts = <GIC_SPI 268 IRQ_TYPE_LEVEL_HIGH>;
++ clocks = <&cpg CPG_MOD 628>;
++ power-domains = <&sysc R8A7798_PD_ALWAYS_ON>;
++ status = "disabled";
++ };
++
++ vin9: video@e6ef9000 {
++ compatible = "renesas,vin-r8a7798";
++ reg = <0 0xe6ef9000 0 0x1000>;
++ interrupts = <GIC_SPI 269 IRQ_TYPE_LEVEL_HIGH>;
++ clocks = <&cpg CPG_MOD 627>;
++ power-domains = <&sysc R8A7798_PD_ALWAYS_ON>;
++ status = "disabled";
++ };
++
++ vin10: video@e6efa000 {
++ compatible = "renesas,vin-r8a7798";
++ reg = <0 0xe6efa000 0 0x1000>;
++ interrupts = <GIC_SPI 289 IRQ_TYPE_LEVEL_HIGH>;
++ clocks = <&cpg CPG_MOD 625>;
++ power-domains = <&sysc R8A7798_PD_ALWAYS_ON>;
++ status = "disabled";
++ };
++
++ vin11: video@e6efb000 {
++ compatible = "renesas,vin-r8a7798";
++ reg = <0 0xe6efb000 0 0x1000>;
++ interrupts = <GIC_SPI 296 IRQ_TYPE_LEVEL_HIGH>;
++ clocks = <&cpg CPG_MOD 618>;
++ power-domains = <&sysc R8A7798_PD_ALWAYS_ON>;
++ status = "disabled";
++ };
++
++ vin12: video@e6efc000 {
++ compatible = "renesas,vin-r8a7798";
++ reg = <0 0xe6efc000 0 0x1000>;
++ interrupts = <GIC_SPI 298 IRQ_TYPE_LEVEL_HIGH>;
++ clocks = <&cpg CPG_MOD 612>;
++ power-domains = <&sysc R8A7798_PD_ALWAYS_ON>;
++ status = "disabled";
++ };
++
++ vin13: video@e6efd000 {
++ compatible = "renesas,vin-r8a7798";
++ reg = <0 0xe6efd000 0 0x1000>;
++ interrupts = <GIC_SPI 299 IRQ_TYPE_LEVEL_HIGH>;
++ clocks = <&cpg CPG_MOD 608>;
++ power-domains = <&sysc R8A7798_PD_ALWAYS_ON>;
++ status = "disabled";
++ };
++
++ vin14: video@e6efe000 {
++ compatible = "renesas,vin-r8a7798";
++ reg = <0 0xe6efe000 0 0x1000>;
++ interrupts = <GIC_SPI 000 IRQ_TYPE_LEVEL_HIGH>; /* FIXME no info in datasheet */
++ clocks = <&cpg CPG_MOD 605>;
++ power-domains = <&sysc R8A7798_PD_ALWAYS_ON>;
++ status = "disabled";
++ };
++
++ vin15: video@e6eff000 {
++ compatible = "renesas,vin-r8a7798";
++ reg = <0 0xe6eff000 0 0x1000>;
++ interrupts = <GIC_SPI 000 IRQ_TYPE_LEVEL_HIGH>; /* FIXME no info in datasheet */
++ clocks = <&cpg CPG_MOD 604>;
++ power-domains = <&sysc R8A7798_PD_ALWAYS_ON>;
++ status = "disabled";
++ };
++
++ sdhi2: sd@ee140000 {
++ compatible = "renesas,sdhi-r8a7798";
++ reg = <0 0xee140000 0 0x2000>;
++ interrupts = <GIC_SPI 165 IRQ_TYPE_LEVEL_HIGH>;
++ clocks = <&cpg CPG_MOD 314>;
++ power-domains = <&sysc R8A7798_PD_ALWAYS_ON>;
++ renesas,clk-rate = <200000000>;
++ status = "disabled";
++ };
++
++ qos@e67e0000 {
++ compatible = "renesas,qos";
++ };
++
++ vspd0: vsp@fea20000 {
++ compatible = "renesas,vsp2";
++ reg = <0 0xfea20000 0 0x4000>;
++
++ interrupts = <GIC_SPI 169 IRQ_TYPE_LEVEL_HIGH>;
++ clocks = <&cpg CPG_MOD 623>;
++ power-domains = <&sysc R8A7798_PD_ALWAYS_ON>;
++
++ renesas,fcp = <&fcpvd0>;
++ };
++
++ fcpvd0: fcp@fea27000 {
++ compatible = "renesas,r8a7798-fcpv", "renesas,fcpv";
++ reg = <0 0xfea27000 0 0x200>;
++ clocks = <&cpg CPG_MOD 603>;
++ power-domains = <&sysc R8A7798_PD_ALWAYS_ON>;
++ };
++
++ du: display@feb00000 {
++ compatible = "renesas,du-r8a7798";
++ reg = <0 0xfeb00000 0 0x80000>,
++ <0 0xfeb90000 0 0x14>;
++ reg-names = "du", "lvds.0";
++ interrupts = <GIC_SPI 256 IRQ_TYPE_LEVEL_HIGH>;
++ clocks = <&cpg CPG_MOD 724>,
++ <&cpg CPG_MOD 727>,
++ <&dclkin_p0>;
++ clock-names = "du.0", "lvds.0", "dclkin.0";
++ status = "disabled";
++
++ vsps = <&vspd0>;
++
++ interlaced = <1>;
++
++ ports {
++ #address-cells = <1>;
++ #size-cells = <0>;
++
++ port@0 {
++ reg = <0>;
++ du_out_lvds0: endpoint {
++ };
++ };
++ };
++ };
++
++ tsc1: thermal@0xe6198000 {
++ compatible = "renesas,thermal-r8a7798";
++ reg = <0 0xe6198000 0 0x5c>;
++ interrupts = <GIC_SPI 67 IRQ_TYPE_LEVEL_HIGH>,
++ <GIC_SPI 68 IRQ_TYPE_LEVEL_HIGH>,
++ <GIC_SPI 69 IRQ_TYPE_LEVEL_HIGH>;
++ clocks = <&cpg CPG_MOD 522>;
++ power-domains = <&sysc R8A7798_PD_ALWAYS_ON>;
++ #thermal-sensor-cells = <0>;
++ status = "okay";
++ };
++
++ tsc2: thermal@0xe61a0000 {
++ compatible = "renesas,thermal-r8a7798";
++ reg = <0 0xe61a0000 0 0x5c>;
++ interrupts = <GIC_SPI 67 IRQ_TYPE_LEVEL_HIGH>,
++ <GIC_SPI 68 IRQ_TYPE_LEVEL_HIGH>,
++ <GIC_SPI 69 IRQ_TYPE_LEVEL_HIGH>;
++ clocks = <&cpg CPG_MOD 522>;
++ power-domains = <&sysc R8A7798_PD_ALWAYS_ON>;
++ #thermal-sensor-cells = <0>;
++ status = "okay";
++ };
++
++ thermal-zones {
++ emergency {
++ polling-delay = <1000>;
++ on-temperature = <110000>;
++ off-temperature = <95000>;
++ target_cpus = <&a53_1>,
++ <&a53_2>,
++ <&a53_3>;
++ status = "disabled";
++ };
++
++ sensor_thermal1: sensor-thermal1 {
++ polling-delay-passive = <250>;
++ polling-delay = <0>;
++ sustainable-power = <0>; /* TBD; HWM 87.4 */
++
++ thermal-sensors = <&tsc1>;
++
++ trips {
++ sensor1_crit: sensor1-crit {
++ temperature = <120000>;
++ hysteresis = <2000>;
++ type = "critical";
++ };
++ };
++ };
++
++ sensor_thermal2: sensor-thermal2 {
++ polling-delay-passive = <250>;
++ polling-delay = <0>;
++ sustainable-power = <0>; /* TBD; HWM 87.4 */
++
++ thermal-sensors = <&tsc2>;
++
++ trips {
++ sensor2_crit: sensor2-crit {
++ temperature = <120000>;
++ hysteresis = <2000>;
++ type = "critical";
++ };
++ };
++ };
++ };
++
++ mfis: mfis@e6260000 {
++ compatible = "renesas,mfis-r8a7798", "renesas,mfis";
++ reg = <0 0xe6260000 0 0x0200>;
++ clocks = <&cpg CPG_MOD 213>;
++ clock-names = "mfis";
++ interrupts = <GIC_SPI 180 IRQ_TYPE_LEVEL_HIGH>;
++ interrupt-names = "eicr0";
++ status = "okay";
++ };
++
++ mfis_lock: mfis-lock@e62600c0 {
++ compatible = "renesas,mfis-lock-r8a7798",
++ "renesas,mfis-lock";
++ reg = <0 0xe62600c0 0 0x0020>;
++ status = "okay";
++ };
++
++ imp_distributer: impdes0 {
++ compatible = "renesas,impx5+-distributer";
++ reg = <0 0xffa00000 0 0x10000>;
++ interrupts = <GIC_SPI 281 IRQ_TYPE_LEVEL_HIGH>;
++ clocks = <&cpg CPG_MOD 830>;
++ power-domains = <&sysc R8A7798_PD_A3IR>;
++ interrupt-controller;
++ #interrupt-cells = <1>;
++ };
++
++ imp0 {
++ compatible = "renesas,impx4-legacy";
++ reg = <0 0xff900000 0 0x20000>;
++ interrupt-parent = <&imp_distributer>;
++ interrupts = <0>;
++ clocks = <&cpg CPG_MOD 827>;
++ power-domains = <&sysc R8A7798_PD_A2IR0>;
++ };
++
++ imp1 {
++ compatible = "renesas,impx4-legacy";
++ reg = <0 0xff920000 0 0x20000>;
++ interrupt-parent = <&imp_distributer>;
++ interrupts = <1>;
++ clocks = <&cpg CPG_MOD 826>;
++ power-domains = <&sysc R8A7798_PD_A2IR1>;
++ };
++
++ imp2 {
++ compatible = "renesas,impx4-legacy";
++ reg = <0 0xff940000 0 0x20000>;
++ interrupt-parent = <&imp_distributer>;
++ interrupts = <2>;
++ clocks = <&cpg CPG_MOD 825>;
++ power-domains = <&sysc R8A7798_PD_A2IR2>;
++ };
++
++ imp3 {
++ compatible = "renesas,impx4-legacy";
++ reg = <0 0xff960000 0 0x20000>;
++ interrupt-parent = <&imp_distributer>;
++ interrupts = <3>;
++ clocks = <&cpg CPG_MOD 824>;
++ power-domains = <&sysc R8A7798_PD_A2IR3>;
++ };
++
++ imp4 {
++ compatible = "renesas,impx4-legacy";
++ reg = <0 0xffa80000 0 0x20000>;
++ interrupt-parent = <&imp_distributer>;
++ interrupts = <4>;
++ clocks = <&cpg CPG_MOD 521>;
++ power-domains = <&sysc R8A7798_PD_A2IR4>;
++ };
++
++ impslc0 {
++ compatible = "renesas,impx4-legacy";
++ reg = <0 0xff9c0000 0 0x10000>;
++ interrupt-parent = <&imp_distributer>;
++ interrupts = <5>;
++ clocks = <&cpg CPG_MOD 500>;
++ power-domains = <&sysc R8A7798_PD_A2IR5>;
++ };
++
++ impsc0 {
++ compatible = "renesas,impx4-shader";
++ reg = <0 0xff980000 0 0x10000>;
++ interrupt-parent = <&imp_distributer>;
++ interrupts = <6>;
++ clocks = <&cpg CPG_MOD 829>;
++ power-domains = <&sysc R8A7798_PD_A2SC0>;
++ };
++
++ impsc1 {
++ compatible = "renesas,impx4-shader";
++ reg = <0 0xff990000 0 0x10000>;
++ interrupt-parent = <&imp_distributer>;
++ interrupts = <7>;
++ clocks = <&cpg CPG_MOD 828>;
++ power-domains = <&sysc R8A7798_PD_A2SC1>;
++ };
++
++ impsc2 {
++ compatible = "renesas,impx4-shader";
++ reg = <0 0xff9a0000 0 0x10000>;
++ interrupt-parent = <&imp_distributer>;
++ interrupts = <8>;
++ clocks = <&cpg CPG_MOD 531>;
++ power-domains = <&sysc R8A7798_PD_A2SC2>;
++ };
++
++ impsc3 {
++ compatible = "renesas,impx4-shader";
++ reg = <0 0xff9b0000 0 0x10000>;
++ interrupt-parent = <&imp_distributer>;
++ interrupts = <9>;
++ clocks = <&cpg CPG_MOD 529>;
++ power-domains = <&sysc R8A7798_PD_A2SC3>;
++ };
++
++ impsc4 {
++ compatible = "renesas,impx4-shader";
++ reg = <0 0xffa40000 0 0x10000>;
++ interrupt-parent = <&imp_distributer>;
++ interrupts = <10>;
++ clocks = <&cpg CPG_MOD 528>;
++ power-domains = <&sysc R8A7798_PD_A2SC4>;
++ };
++
++ impdm0 {
++ compatible = "renesas,impx5-dmac";
++ reg = <0 0xffa10000 0 0x1000>;
++ interrupt-parent = <&imp_distributer>;
++ interrupts = <11>;
++ clocks = <&cpg CPG_MOD 527>;
++ power-domains = <&sysc R8A7798_PD_A2PD0>;
++ };
++
++ impdm1 {
++ compatible = "renesas,impx5-dmac";
++ reg = <0 0xffa11000 0 0x1000>;
++ interrupt-parent = <&imp_distributer>;
++ interrupts = <12>;
++ clocks = <&cpg CPG_MOD 527>;
++ power-domains = <&sysc R8A7798_PD_A2PD0>;
++ };
++
++ impdm2 {
++ compatible = "renesas,impx5-dmac";
++ reg = <0 0xffa14000 0 0x1000>;
++ interrupt-parent = <&imp_distributer>;
++ interrupts = <13>;
++ clocks = <&cpg CPG_MOD 526>;
++ power-domains = <&sysc R8A7798_PD_A2PD1>;
++ };
++
++ impdm3 {
++ compatible = "renesas,impx5-dmac";
++ reg = <0 0xffa15000 0 0x1000>;
++ interrupt-parent = <&imp_distributer>;
++ interrupts = <14>;
++ clocks = <&cpg CPG_MOD 526>;
++ power-domains = <&sysc R8A7798_PD_A2PD1>;
++ };
++
++ imppsc0 {
++ compatible = "renesas,impx5+-psc";
++ reg = <0 0xffa20000 0 0x4000>;
++ interrupt-parent = <&imp_distributer>;
++ interrupts = <15>;
++ clocks = <&cpg CPG_MOD 525>;
++ power-domains = <&sysc R8A7798_PD_A2PD0>;
++ };
++
++ imppsc1 {
++ compatible = "renesas,impx5+-psc";
++ reg = <0 0xffa24000 0 0x4000>;
++ interrupt-parent = <&imp_distributer>;
++ interrupts = <16>;
++ clocks = <&cpg CPG_MOD 524>;
++ power-domains = <&sysc R8A7798_PD_A2PD1>;
++ };
++
++ impcnn0 {
++ compatible = "renesas,impx5+-cnn";
++ reg = <0 0xff9e0000 0 0x10000>;
++ interrupt-parent = <&imp_distributer>;
++ interrupts = <17>;
++ clocks = <&cpg CPG_MOD 831>;
++ power-domains = <&sysc R8A7798_PD_A2CN>;
++ };
++
++ impc0 {
++ compatible = "renesas,impx4-memory";
++ reg = <0 0xed000000 0 0x200000>;
++ clocks = <&cpg CPG_MOD 830>;
++ power-domains = <&sysc R8A7798_PD_A3IR>;
++ };
++
++ imrlx4_ch0: imr-lx4@fe860000 {
++ compatible = "renesas,imr-lx4";
++ reg = <0 0xfe860000 0 0x2000>;
++ interrupts = <GIC_SPI 192 IRQ_TYPE_LEVEL_HIGH>;
++ clocks = <&cpg CPG_MOD 823>;
++ power-domains = <&sysc R8A7798_PD_ALWAYS_ON>;
++ };
++
++ imrlx4_ch1: imr-lx4@fe870000 {
++ compatible = "renesas,imr-lx4";
++ reg = <0 0xfe870000 0 0x2000>;
++ interrupts = <GIC_SPI 193 IRQ_TYPE_LEVEL_HIGH>;
++ clocks = <&cpg CPG_MOD 822>;
++ power-domains = <&sysc R8A7798_PD_ALWAYS_ON>;
++ };
++
++ imrlx4_ch2: imr-lx4@fe880000 {
++ compatible = "renesas,imr-lx4";
++ reg = <0 0xfe880000 0 0x2000>;
++ interrupts = <GIC_SPI 194 IRQ_TYPE_LEVEL_HIGH>;
++ clocks = <&cpg CPG_MOD 821>;
++ power-domains = <&sysc R8A7798_PD_ALWAYS_ON>;
++ };
++
++ imrlx4_ch3: imr-lx4@fe890000 {
++ compatible = "renesas,imr-lx4";
++ reg = <0 0xfe890000 0 0x2000>;
++ interrupts = <GIC_SPI 195 IRQ_TYPE_LEVEL_HIGH>;
++ clocks = <&cpg CPG_MOD 820>;
++ power-domains = <&sysc R8A7798_PD_ALWAYS_ON>;
++ };
++
++ imrlx4_ch4: imr-lx4@fe8a0000 {
++ compatible = "renesas,imr-lx4";
++ reg = <0 0xfe8a0000 0 0x2000>;
++ interrupts = <GIC_SPI 254 IRQ_TYPE_LEVEL_HIGH>;
++ clocks = <&cpg CPG_MOD 707>;
++ power-domains = <&sysc R8A7798_PD_ALWAYS_ON>;
++ rse;
++ };
++
++ imrlx4_ch5: imr-lx4@fe8b0000 {
++ compatible = "renesas,imr-lx4";
++ reg = <0 0xfe8b0000 0 0x2000>;
++ interrupts = <GIC_SPI 255 IRQ_TYPE_LEVEL_HIGH>;
++ clocks = <&cpg CPG_MOD 706>;
++ power-domains = <&sysc R8A7798_PD_ALWAYS_ON>;
++ rse;
++ };
++
++ disp {
++ compatible = "generic-uio";
++ reg = <0 0xe7a00000 0 0x10000>;
++ clocks = <&cpg CPG_MOD 101>;
++ power-domains = <&sysc R8A7798_PD_A3VIP>;
++ };
++
++ umf {
++ compatible = "generic-uio";
++ reg = <0 0xe7a10000 0 0x10000>;
++ clocks = <&cpg CPG_MOD 102>;
++ power-domains = <&sysc R8A7798_PD_A3VIP1>;
++ };
++
++ smd_ps {
++ compatible = "generic-uio";
++ reg = <0 0xe7a20000 0 0x10000>;
++ clocks = <&cpg CPG_MOD 1102>;
++ power-domains = <&sysc R8A7798_PD_A3VIP1>;
++ };
++
++ smd_est {
++ compatible = "generic-uio";
++ reg = <0 0xe7a30000 0 0x10000>;
++ clocks = <&cpg CPG_MOD 1101>;
++ power-domains = <&sysc R8A7798_PD_A3VIP1>;
++ };
++
++ smd_post {
++ compatible = "generic-uio";
++ reg = <0 0xe7a40000 0 0x10000>;
++ clocks = <&cpg CPG_MOD 1100>;
++ power-domains = <&sysc R8A7798_PD_A3VIP1>;
++ };
++
++ cle0 {
++ compatible = "generic-uio";
++ reg = <0 0xe7a50000 0 0x10000>;
++ clocks = <&cpg CPG_MOD 1004>;
++ power-domains = <&sysc R8A7798_PD_A3VIP2>;
++ };
++
++ cle1 {
++ compatible = "generic-uio";
++ reg = <0 0xe7a60000 0 0x10000>;
++ clocks = <&cpg CPG_MOD 1003>;
++ power-domains = <&sysc R8A7798_PD_A3VIP2>;
++ };
++
++ cle2 {
++ compatible = "generic-uio";
++ reg = <0 0xe7a70000 0 0x10000>;
++ clocks = <&cpg CPG_MOD 1002>;
++ power-domains = <&sysc R8A7798_PD_A3VIP2>;
++ };
++
++ cle3 {
++ compatible = "generic-uio";
++ reg = <0 0xe7a80000 0 0x10000>;
++ clocks = <&cpg CPG_MOD 1001>;
++ power-domains = <&sysc R8A7798_PD_A3VIP2>;
++ };
++
++ cle4 {
++ compatible = "generic-uio";
++ reg = <0 0xe7a90000 0 0x10000>;
++ clocks = <&cpg CPG_MOD 1000>;
++ power-domains = <&sysc R8A7798_PD_A3VIP2>;
++ };
++ };
++};
+diff --git a/drivers/clk/renesas/Kconfig b/drivers/clk/renesas/Kconfig
+index b52e907..4e6d24d 100644
+--- a/drivers/clk/renesas/Kconfig
++++ b/drivers/clk/renesas/Kconfig
+@@ -6,6 +6,7 @@ config CLK_RENESAS_CPG_MSSR
+ default y if ARCH_R8A7796
+ default y if ARCH_R8A77965
+ default y if ARCH_R8A7797
++ default y if ARCH_R8A7798
+
+ config CLK_RENESAS_CPG_MSTP
+ bool
+diff --git a/drivers/clk/renesas/Makefile b/drivers/clk/renesas/Makefile
+index c2ef11e..9f659d5 100644
+--- a/drivers/clk/renesas/Makefile
++++ b/drivers/clk/renesas/Makefile
+@@ -15,6 +15,7 @@ obj-$(CONFIG_ARCH_R8A7795) += r8a7795-cpg-mssr.o rcar-gen3-cpg.o
+ obj-$(CONFIG_ARCH_R8A7796) += r8a7796-cpg-mssr.o rcar-gen3-cpg.o
+ obj-$(CONFIG_ARCH_R8A77965) += r8a77965-cpg-mssr.o rcar-gen3-cpg.o
+ obj-$(CONFIG_ARCH_R8A7797) += r8a7797-cpg-mssr.o rcar-gen3-cpg.o
++obj-$(CONFIG_ARCH_R8A7798) += r8a7798-cpg-mssr.o rcar-gen3-cpg.o
+ obj-$(CONFIG_ARCH_SH73A0) += clk-sh73a0.o clk-div6.o
+
+ obj-$(CONFIG_CLK_RENESAS_CPG_MSSR) += renesas-cpg-mssr.o clk-div6.o
+diff --git a/drivers/clk/renesas/r8a7798-cpg-mssr.c b/drivers/clk/renesas/r8a7798-cpg-mssr.c
+new file mode 100644
+index 0000000..40ad314
+--- /dev/null
++++ b/drivers/clk/renesas/r8a7798-cpg-mssr.c
+@@ -0,0 +1,292 @@
++/*
++ * r8a7798 Clock Pulse Generator / Module Standby and Software Reset
++ *
++ * Copyright (C) 2018 Renesas Electronics Corp.
++ * Copyright (C) 2018 Cogent Embedded, Inc.
++ *
++ * This program is free software; you can redistribute it and/or modify
++ * it under the terms of the GNU General Public License as published by
++ * the Free Software Foundation; version 2 of the License.
++ */
++
++#include <linux/device.h>
++#include <linux/init.h>
++#include <linux/kernel.h>
++#include <linux/soc/renesas/rcar-rst.h>
++#include <linux/sys_soc.h>
++
++#include <dt-bindings/clock/r8a7798-cpg-mssr.h>
++
++#include "renesas-cpg-mssr.h"
++#include "rcar-gen3-cpg.h"
++
++enum clk_ids {
++ /* Core Clock Outputs exported to DT */
++ LAST_DT_CORE_CLK = R8A7798_CLK_OSC,
++
++ /* External Input Clocks */
++ CLK_EXTAL,
++ CLK_EXTALR,
++
++ /* Internal Core Clocks */
++ CLK_MAIN,
++ CLK_PLL1,
++ CLK_PLL2,
++ CLK_PLL3,
++ CLK_PLL1_DIV2,
++ CLK_PLL1_DIV4,
++ CLK_S0,
++ CLK_S1,
++ CLK_S2,
++ CLK_S3,
++ CLK_SDSRC,
++ CLK_RINT,
++
++ /* Module Clocks */
++ MOD_CLK_BASE
++};
++
++static const struct cpg_core_clk r8a7798_core_clks[] __initconst = {
++ /* External Clock Inputs */
++ DEF_INPUT("extal", CLK_EXTAL),
++ DEF_INPUT("extalr", CLK_EXTALR),
++
++ /* Internal Core Clocks */
++ DEF_BASE(".main", CLK_MAIN, CLK_TYPE_GEN3_MAIN, CLK_EXTAL),
++ DEF_BASE(".pll1", CLK_PLL1, CLK_TYPE_GEN3_PLL1, CLK_MAIN),
++ DEF_BASE(".pll2", CLK_PLL2, CLK_TYPE_GEN3_PLL2, CLK_MAIN),
++ DEF_BASE(".pll3", CLK_PLL3, CLK_TYPE_GEN3_PLL3, CLK_MAIN),
++
++ DEF_FIXED(".pll1_div2", CLK_PLL1_DIV2, CLK_PLL1, 2, 1),
++ DEF_FIXED(".pll1_div4", CLK_PLL1_DIV4, CLK_PLL1_DIV2, 2, 1),
++ DEF_FIXED(".s0", CLK_S0, CLK_PLL1_DIV2, 2, 1),
++ DEF_FIXED(".s1", CLK_S1, CLK_PLL1_DIV2, 3, 1),
++ DEF_FIXED(".s2", CLK_S2, CLK_PLL1_DIV2, 4, 1),
++ DEF_FIXED(".s3", CLK_S3, CLK_PLL1_DIV2, 6, 1),
++ DEF_FIXED(".sdsrc", CLK_SDSRC, CLK_PLL1_DIV2, 2, 1),
++
++ /* Core Clock Outputs */
++ DEF_BASE("z2", R8A7798_CLK_Z2, CLK_TYPE_GEN3_Z2, CLK_PLL2),
++ DEF_FIXED("ztr", R8A7798_CLK_ZTR, CLK_PLL1_DIV2, 6, 1),
++ DEF_FIXED("ztrd2", R8A7798_CLK_ZTRD2, CLK_PLL1_DIV2, 12, 1),
++ DEF_FIXED("zt", R8A7798_CLK_ZT, CLK_PLL1_DIV2, 4, 1),
++ DEF_FIXED("zx", R8A7798_CLK_ZX, CLK_PLL1_DIV2, 3, 1),
++ DEF_FIXED("s0d1", R8A7798_CLK_S0D1, CLK_S0, 1, 1),
++ DEF_FIXED("s0d2", R8A7798_CLK_S0D2, CLK_S0, 2, 1),
++ DEF_FIXED("s0d3", R8A7798_CLK_S0D3, CLK_S0, 3, 1),
++ DEF_FIXED("s0d4", R8A7798_CLK_S0D4, CLK_S0, 4, 1),
++ DEF_FIXED("s0d6", R8A7798_CLK_S0D6, CLK_S0, 6, 1),
++ DEF_FIXED("s0d12", R8A7798_CLK_S0D12, CLK_S0, 12, 1),
++ DEF_FIXED("s0d24", R8A7798_CLK_S0D24, CLK_S0, 24, 1),
++ DEF_FIXED("s1d1", R8A7798_CLK_S1D1, CLK_S1, 1, 1),
++ DEF_FIXED("s1d2", R8A7798_CLK_S1D2, CLK_S1, 2, 1),
++ DEF_FIXED("s1d4", R8A7798_CLK_S1D4, CLK_S1, 4, 1),
++ DEF_FIXED("s2d1", R8A7798_CLK_S2D1, CLK_S2, 1, 1),
++ DEF_FIXED("s2d2", R8A7798_CLK_S2D2, CLK_S2, 2, 1),
++ DEF_FIXED("s2d4", R8A7798_CLK_S2D4, CLK_S2, 4, 1),
++ DEF_FIXED("s3d1", R8A7798_CLK_S3D1, CLK_S3, 1, 1),
++ DEF_FIXED("s3d2", R8A7798_CLK_S3D2, CLK_S3, 2, 1),
++ DEF_FIXED("s3d4", R8A7798_CLK_S3D4, CLK_S3, 4, 1),
++
++ DEF_GEN3_SD("sd0", R8A7798_CLK_SD0, CLK_SDSRC, 0x0074), /* OK? */
++
++ DEF_FIXED("cl", R8A7798_CLK_CL, CLK_PLL1_DIV2, 48, 1),
++ DEF_FIXED("cp", R8A7798_CLK_CP, CLK_EXTAL, 2, 1),
++
++ DEF_DIV6P1("canfd", R8A7798_CLK_CANFD, CLK_PLL1_DIV4, 0x244),
++ DEF_DIV6P1("csi0", R8A7798_CLK_CSI0, CLK_PLL1_DIV4, 0x00c),
++ DEF_DIV6P1("mso", R8A7798_CLK_MSO, CLK_PLL1_DIV4, 0x014),
++
++ DEF_BASE("osc", R8A7798_CLK_OSC, CLK_TYPE_GEN3_OSC, CLK_EXTAL),
++ DEF_BASE("r_int", CLK_RINT, CLK_TYPE_GEN3_RINT, CLK_EXTAL),
++
++ DEF_BASE("r", R8A7798_CLK_R, CLK_TYPE_GEN3_R, CLK_RINT),
++};
++
++static const struct mssr_mod_clk r8a7798_mod_clks[] __initconst = {
++ /*... skip crc, umf, disp, rt-sram, cle, smd_ */
++ DEF_MOD("disp", 101, R8A7798_CLK_S1D1),
++ DEF_MOD("umf", 102, R8A7798_CLK_S1D1),
++ DEF_MOD("tmu4", 121, R8A7798_CLK_S0D6),
++ DEF_MOD("tmu3", 122, R8A7798_CLK_S0D6),
++ DEF_MOD("tmu2", 123, R8A7798_CLK_S0D6),
++ DEF_MOD("tmu1", 124, R8A7798_CLK_S0D6),
++ DEF_MOD("tmu0", 125, R8A7798_CLK_CP),
++ DEF_MOD("ivcp1e", 127, R8A7798_CLK_S3D1), /* FIXME parent clk? */
++ DEF_MOD("scif4", 203, R8A7798_CLK_S3D4),
++ DEF_MOD("scif3", 204, R8A7798_CLK_S3D4),
++ DEF_MOD("scif1", 206, R8A7798_CLK_S3D4),
++ DEF_MOD("scif0", 207, R8A7798_CLK_S3D4),
++ DEF_MOD("msiof3", 208, R8A7798_CLK_MSO),
++ DEF_MOD("msiof2", 209, R8A7798_CLK_MSO),
++ DEF_MOD("msiof1", 210, R8A7798_CLK_MSO),
++ DEF_MOD("msiof0", 211, R8A7798_CLK_MSO),
++ DEF_MOD("mfis", 213, R8A7798_CLK_S2D2), /* FIXME parent clk? */
++ DEF_MOD("sys-dmac2", 217, R8A7798_CLK_S0D3), /* OK? */
++ DEF_MOD("sys-dmac1", 218, R8A7798_CLK_S0D3), /* OK? */
++ DEF_MOD("cmt3", 300, R8A7798_CLK_R),
++ DEF_MOD("cmt2", 301, R8A7798_CLK_R),
++ DEF_MOD("cmt1", 302, R8A7798_CLK_R),
++ DEF_MOD("cmt0", 303, R8A7798_CLK_R),
++ DEF_MOD("tpu", 304, R8A7798_CLK_S3D4),
++ DEF_MOD("sdif", 314, R8A7798_CLK_SD0), /* OK */
++ DEF_MOD("pciec", 319, R8A7798_CLK_S3D1),
++ DEF_MOD("rwdt0", 402, R8A7798_CLK_R),
++ DEF_MOD("intc-ex", 407, R8A7798_CLK_CP), /* OK */
++ DEF_MOD("intc-ap", 408, R8A7798_CLK_S0D3),
++ DEF_MOD("simp", 500, R8A7798_CLK_S1D1),
++ DEF_MOD("hscif3", 517, R8A7798_CLK_S3D1),
++ DEF_MOD("hscif2", 518, R8A7798_CLK_S3D1),
++ DEF_MOD("hscif1", 519, R8A7798_CLK_S3D1),
++ DEF_MOD("hscif0", 520, R8A7798_CLK_S3D1),
++ DEF_MOD("imp4", 521, R8A7798_CLK_S1D1), /* OK? */
++ DEF_MOD("thermal", 522, R8A7798_CLK_CP),
++ DEF_MOD("pwm", 523, R8A7798_CLK_S0D12),
++ DEF_MOD("imppsc1", 524, R8A7798_CLK_S1D1),
++ DEF_MOD("imppsc0", 525, R8A7798_CLK_S1D1),
++ DEF_MOD("impdma1", 526, R8A7798_CLK_S1D1), /* OK? */
++ DEF_MOD("impdma0", 527, R8A7798_CLK_S1D1), /* OK? */
++ DEF_MOD("imp-ocv4", 528, R8A7798_CLK_S1D1), /* OK? */
++ DEF_MOD("imp-ocv3", 529, R8A7798_CLK_S1D1), /* OK? */
++ DEF_MOD("imp-ocv2", 531, R8A7798_CLK_S1D1), /* OK? */
++ DEF_MOD("fcpvd0", 603, R8A7798_CLK_S3D1),
++ DEF_MOD("vin15", 604, R8A7798_CLK_S2D1), /* FIXME parent clk? */
++ DEF_MOD("vin14", 605, R8A7798_CLK_S2D1), /* FIXME parent clk? */
++ DEF_MOD("vin13", 608, R8A7798_CLK_S2D1), /* FIXME parent clk? */
++ DEF_MOD("vin12", 612, R8A7798_CLK_S2D1), /* FIXME parent clk? */
++ DEF_MOD("vin11", 618, R8A7798_CLK_S2D1), /* FIXME parent clk? */
++ DEF_MOD("vspd0", 623, R8A7798_CLK_S3D1),
++ DEF_MOD("vin10", 625, R8A7798_CLK_S2D1), /* FIXME parent clk? */
++ DEF_MOD("vin9", 627, R8A7798_CLK_S2D1), /* FIXME parent clk? */
++ DEF_MOD("vin8", 628, R8A7798_CLK_S2D1), /* FIXME parent clk? */
++ DEF_MOD("imr5", 706, R8A7798_CLK_S2D1), /* FIXME parent clk? */
++ DEF_MOD("imr4", 707, R8A7798_CLK_S2D1), /* FIXME parent clk? */
++ DEF_MOD("csi41", 715, R8A7798_CLK_CSI0),
++ DEF_MOD("csi40", 716, R8A7798_CLK_CSI0),
++ DEF_MOD("du0", 724, R8A7798_CLK_S2D1),
++ DEF_MOD("lvds", 727, R8A7798_CLK_S2D1),
++ DEF_MOD("vin7", 804, R8A7798_CLK_S0D2), /* FIXME parent clk? */
++ DEF_MOD("vin6", 805, R8A7798_CLK_S0D2), /* FIXME parent clk? */
++ DEF_MOD("vin5", 806, R8A7798_CLK_S0D2), /* FIXME parent clk? */
++ DEF_MOD("vin4", 807, R8A7798_CLK_S0D2), /* FIXME parent clk? */
++ DEF_MOD("vin3", 808, R8A7798_CLK_S0D2), /* FIXME parent clk? */
++ DEF_MOD("vin2", 809, R8A7798_CLK_S0D2), /* FIXME parent clk? */
++ DEF_MOD("vin1", 810, R8A7798_CLK_S0D2), /* FIXME parent clk? */
++ DEF_MOD("vin0", 811, R8A7798_CLK_S0D2), /* FIXME parent clk? */
++ DEF_MOD("etheravb", 812, R8A7798_CLK_S3D2), /* OK */
++ DEF_MOD("gether", 813, R8A7798_CLK_S3D2), /* OK */
++ DEF_MOD("isp1", 814, R8A7798_CLK_S3D1), /* FIXME parent clk? */
++ DEF_MOD("isp0", 817, R8A7798_CLK_S3D1), /* FIXME parent clk? */
++ DEF_MOD("imr3", 820, R8A7798_CLK_S2D1), /* FIXME check clk? */
++ DEF_MOD("imr2", 821, R8A7798_CLK_S2D1), /* FIXME check clk? */
++ DEF_MOD("imr1", 822, R8A7798_CLK_S2D1), /* FIXME check clk? */
++ DEF_MOD("imr0", 823, R8A7798_CLK_S2D1), /* FIXME check clk? */
++ DEF_MOD("imp3", 824, R8A7798_CLK_S1D1), /* OK? figure 8.1e CPG block diag */
++ DEF_MOD("imp2", 825, R8A7798_CLK_S1D1), /* OK? */
++ DEF_MOD("imp1", 826, R8A7798_CLK_S1D1), /* OK? */
++ DEF_MOD("imp0", 827, R8A7798_CLK_S1D1), /* OK? */
++ DEF_MOD("imp-ocv1", 828, R8A7798_CLK_S1D1), /* OK? */
++ DEF_MOD("imp-ocv0", 829, R8A7798_CLK_S1D1), /* OK? */
++ DEF_MOD("impram", 830, R8A7798_CLK_S1D1), /* OK? */
++ DEF_MOD("impcnn", 831, R8A7798_CLK_S1D1), /* OK? */
++ DEF_MOD("gpio5", 907, R8A7798_CLK_CP),
++ DEF_MOD("gpio4", 908, R8A7798_CLK_CP),
++ DEF_MOD("gpio3", 909, R8A7798_CLK_CP),
++ DEF_MOD("gpio2", 910, R8A7798_CLK_CP),
++ DEF_MOD("gpio1", 911, R8A7798_CLK_CP),
++ DEF_MOD("gpio0", 912, R8A7798_CLK_CP),
++ DEF_MOD("can-fd", 914, R8A7798_CLK_S3D2),
++ /* FIXME missing MSSR for i2c5; should it be 919 as in H3/M3? */
++ /* DEF_MOD("i2c4", 919, R8A7798_CLK_S3D2), */
++ DEF_MOD("i2c4", 927, R8A7798_CLK_S0D6),
++ DEF_MOD("i2c3", 928, R8A7798_CLK_S0D6),
++ DEF_MOD("i2c2", 929, R8A7798_CLK_S3D2),
++ DEF_MOD("i2c1", 930, R8A7798_CLK_S3D2),
++ DEF_MOD("i2c0", 931, R8A7798_CLK_S3D2),
++ DEF_MOD("cle4", 1000, R8A7798_CLK_S1D1),
++ DEF_MOD("cle3", 1001, R8A7798_CLK_S1D1),
++ DEF_MOD("cle2", 1002, R8A7798_CLK_S1D1),
++ DEF_MOD("cle1", 1003, R8A7798_CLK_S1D1),
++ DEF_MOD("cle0", 1004, R8A7798_CLK_S1D1),
++ DEF_MOD("smd_post", 1100, R8A7798_CLK_S0D3),
++ DEF_MOD("smd_est", 1101, R8A7798_CLK_S0D3),
++ DEF_MOD("smd_ps", 1102, R8A7798_CLK_S0D3),
++};
++
++static const unsigned int r8a7798_crit_mod_clks[] __initconst = {
++ MOD_CLK_ID(408), /* INTC-AP (GIC) */
++};
++
++
++/*
++ * CPG Clock Data
++ */
++
++/*
++ * MD EXTAL PLL2 PLL1 PLL3
++ * 14 13 19 (MHz)
++ *-------------------------------------------------
++ * 0 0 0 16.66 x 1 x240 x192 x192
++ * 0 0 1 16.66 x 1 x240 x192 x192
++ * 0 1 0 20 x 1 x200 x160 x160
++ * 0 1 1 20 x 1 x200 x160 x160
++ * 1 0 0 27 x 1 x148 x118 x118
++ * 1 0 1 27 x 1 x148 x118 x118
++ * 1 1 0 33.33 / 2 x240 x192 x192
++ * 1 1 1 33.33 / 2 x240 x192 x192
++ */
++#define CPG_PLL_CONFIG_INDEX(md) ((((md) & BIT(14)) >> 12) | \
++ (((md) & BIT(13)) >> 12) | \
++ (((md) & BIT(19)) >> 19))
++
++static const struct rcar_gen3_cpg_pll_config cpg_pll_configs[8] __initconst = {
++ /* EXTAL div PLL1 mult PLL3 mult */
++ { 1, 192, 192,},
++ { 1, 192, 192,},
++ { 1, 160, 160,},
++ { 1, 160, 160,},
++ { 1, 118, 118,},
++ { 1, 118, 118,},
++ { 2, 192, 192,},
++ { 2, 192, 192,},
++};
++
++static int __init r8a7798_cpg_mssr_init(struct device *dev)
++{
++ const struct rcar_gen3_cpg_pll_config *cpg_pll_config;
++ u32 cpg_mode;
++ int error;
++
++ error = rcar_rst_read_mode_pins(&cpg_mode);
++ if (error)
++ return error;
++
++ cpg_pll_config = &cpg_pll_configs[CPG_PLL_CONFIG_INDEX(cpg_mode)];
++ if (!cpg_pll_config->extal_div) {
++ dev_err(dev, "Prohibited setting (cpg_mode=0x%x)\n", cpg_mode);
++ return -EINVAL;
++ }
++
++ return rcar_gen3_cpg_init(cpg_pll_config, CLK_EXTALR, cpg_mode);
++}
++
++const struct cpg_mssr_info r8a7798_cpg_mssr_info __initconst = {
++ /* Core Clocks */
++ .core_clks = r8a7798_core_clks,
++ .num_core_clks = ARRAY_SIZE(r8a7798_core_clks),
++ .last_dt_core_clk = LAST_DT_CORE_CLK,
++ .num_total_core_clks = MOD_CLK_BASE,
++
++ /* Module Clocks */
++ .mod_clks = r8a7798_mod_clks,
++ .num_mod_clks = ARRAY_SIZE(r8a7798_mod_clks),
++ .num_hw_mod_clks = 12 * 32,
++
++ /* Critical Module Clocks */
++ .crit_mod_clks = r8a7798_crit_mod_clks,
++ .num_crit_mod_clks = ARRAY_SIZE(r8a7798_crit_mod_clks),
++
++ /* Callbacks */
++ .init = r8a7798_cpg_mssr_init,
++ .cpg_clk_register = rcar_gen3_cpg_clk_register,
++};
+diff --git a/drivers/clk/renesas/rcar-gen3-cpg.c b/drivers/clk/renesas/rcar-gen3-cpg.c
+index b145f14..930fa3d 100644
+--- a/drivers/clk/renesas/rcar-gen3-cpg.c
++++ b/drivers/clk/renesas/rcar-gen3-cpg.c
+@@ -33,6 +33,11 @@
+ { /* sentinel */ }
+ };
+
++static const struct soc_device_attribute r8a7798[] = {
++ { .soc_id = "r8a7798" },
++ { }
++};
++
+ #define CPG_PLL0CR 0x00d8
+ #define CPG_PLL2CR 0x002c
+ #define CPG_PLL4CR 0x01f4
+@@ -242,6 +247,10 @@ static unsigned long cpg_z2_clk_recalc_rate(struct clk_hw *hw,
+ mult = 32 - val;
+
+ rate = div_u64((u64)parent_rate * mult + 16, 32);
++
++ if (soc_device_match(r8a7798))
++ rate /= 2;
++
+ /* Round to closest value at 100MHz unit */
+ rate = 100000000*DIV_ROUND_CLOSEST(rate, 100000000);
+ return rate;
+@@ -303,6 +312,9 @@ static long cpg_z2_clk_round_rate(struct clk_hw *hw, unsigned long rate,
+ unsigned long prate = *parent_rate;
+ unsigned int mult;
+
++ if (soc_device_match(r8a7798))
++ prate /= 2;
++
+ mult = div_u64((u64)rate * 32 + prate/2, prate);
+ mult = clamp(mult, 1U, 32U);
+
+@@ -382,7 +394,7 @@ static int cpg_z2_clk_set_rate(struct clk_hw *hw, unsigned long rate,
+ u32 val, kick;
+ unsigned int i;
+
+- if (soc_device_match(r8a7797)){
++ if (soc_device_match(r8a7797) || soc_device_match(r8a7798)){
+ pr_info("Do not support V3M's Z2 clock changing\n");
+ return 0;
+ }
+@@ -916,6 +928,11 @@ struct clk * __init rcar_gen3_cpg_clk_register(struct device *dev,
+ if (cpg_quirks & RCLK_CKSEL_RESEVED)
+ break;
+
++ if (soc_device_match(r8a7798) && (cpg_mode ^ BIT(29))) {
++ parent = clks[cpg_clk_extalr];
++ break;
++ }
++
+ /* Select parent clock of RCLK by MD28 */
+ if (cpg_mode & BIT(28))
+ parent = clks[cpg_clk_extalr];
+diff --git a/drivers/clk/renesas/renesas-cpg-mssr.c b/drivers/clk/renesas/renesas-cpg-mssr.c
+index bd901a6..f1a81ed 100644
+--- a/drivers/clk/renesas/renesas-cpg-mssr.c
++++ b/drivers/clk/renesas/renesas-cpg-mssr.c
+@@ -600,6 +600,12 @@ static int __init cpg_mssr_add_clk_domain(struct device *dev,
+ .data = &r8a7797_cpg_mssr_info,
+ },
+ #endif
++#ifdef CONFIG_ARCH_R8A7798
++ {
++ .compatible = "renesas,r8a7798-cpg-mssr",
++ .data = &r8a7798_cpg_mssr_info,
++ },
++#endif
+ { /* sentinel */ }
+ };
+
+diff --git a/drivers/clk/renesas/renesas-cpg-mssr.h b/drivers/clk/renesas/renesas-cpg-mssr.h
+index ce3546a..70cb4cb 100644
+--- a/drivers/clk/renesas/renesas-cpg-mssr.h
++++ b/drivers/clk/renesas/renesas-cpg-mssr.h
+@@ -136,6 +136,7 @@ struct cpg_mssr_info {
+ extern const struct cpg_mssr_info r8a7796_cpg_mssr_info;
+ extern const struct cpg_mssr_info r8a77965_cpg_mssr_info;
+ extern const struct cpg_mssr_info r8a7797_cpg_mssr_info;
++extern const struct cpg_mssr_info r8a7798_cpg_mssr_info;
+
+
+ /*
+diff --git a/drivers/cpufreq/cpufreq-dt-platdev.c b/drivers/cpufreq/cpufreq-dt-platdev.c
+index 5a2ec23..2d7d41c 100644
+--- a/drivers/cpufreq/cpufreq-dt-platdev.c
++++ b/drivers/cpufreq/cpufreq-dt-platdev.c
+@@ -61,6 +61,7 @@
+ { .compatible = "renesas,r8a7796", },
+ { .compatible = "renesas,r8a77965", },
+ { .compatible = "renesas,r8a7797", },
++ { .compatible = "renesas,r8a7798", },
+ { .compatible = "renesas,sh73a0", },
+
+ { .compatible = "rockchip,rk2928", },
+diff --git a/drivers/gpio/gpio-rcar.c b/drivers/gpio/gpio-rcar.c
+index fd15649..11044cd 100644
+--- a/drivers/gpio/gpio-rcar.c
++++ b/drivers/gpio/gpio-rcar.c
+@@ -371,6 +371,10 @@ struct gpio_rcar_info {
+ /* Gen3 GPIO is identical to Gen2. */
+ .data = &gpio_rcar_info_gen2,
+ }, {
++ .compatible = "renesas,gpio-r8a7798",
++ /* Gen3 GPIO is identical to Gen2. */
++ .data = &gpio_rcar_info_gen2,
++ }, {
+ .compatible = "renesas,gpio-rcar",
+ .data = &gpio_rcar_info_gen1,
+ }, {
+diff --git a/drivers/gpu/drm/rcar-du/rcar_du_drv.c b/drivers/gpu/drm/rcar-du/rcar_du_drv.c
+index f74f264..6fea1e2 100644
+--- a/drivers/gpu/drm/rcar-du/rcar_du_drv.c
++++ b/drivers/gpu/drm/rcar-du/rcar_du_drv.c
+@@ -360,6 +360,7 @@
+ { .compatible = "renesas,du-r8a7796", .data = &rcar_du_r8a7796_info },
+ { .compatible = "renesas,du-r8a77965", .data = &rcar_du_r8a77965_info },
+ { .compatible = "renesas,du-r8a7797", .data = &rcar_du_r8a7797_info },
++ { .compatible = "renesas,du-r8a7798", .data = &rcar_du_r8a7797_info },
+ { }
+ };
+
+diff --git a/drivers/gpu/drm/rcar-du/rcar_du_group.c b/drivers/gpu/drm/rcar-du/rcar_du_group.c
+index 3916b63..22c7713 100644
+--- a/drivers/gpu/drm/rcar-du/rcar_du_group.c
++++ b/drivers/gpu/drm/rcar-du/rcar_du_group.c
+@@ -35,8 +35,9 @@
+ #include "rcar_du_group.h"
+ #include "rcar_du_regs.h"
+
+-static const struct soc_device_attribute r8a7797[] = {
++static const struct soc_device_attribute r8a7797_8[] = {
+ { .soc_id = "r8a7797" },
++ { .soc_id = "r8a7798" },
+ { }
+ };
+
+@@ -161,7 +162,7 @@ static void rcar_du_group_setup(struct rcar_du_group *rgrp)
+
+ /* Apply planes to CRTCs association. */
+ mutex_lock(&rgrp->lock);
+- if (!soc_device_match(r8a7797))
++ if (!soc_device_match(r8a7797_8))
+ rcar_du_group_write(rgrp, DPTSR, (rgrp->dptsr_planes << 16) |
+ rgrp->dptsr_planes);
+
+diff --git a/drivers/i2c/busses/i2c-rcar.c b/drivers/i2c/busses/i2c-rcar.c
+index 149c107..0ad583a 100644
+--- a/drivers/i2c/busses/i2c-rcar.c
++++ b/drivers/i2c/busses/i2c-rcar.c
+@@ -808,6 +808,7 @@ static u32 rcar_i2c_func(struct i2c_adapter *adap)
+ { .compatible = "renesas,i2c-r8a7796", .data = (void *)I2C_RCAR_GEN3 },
+ { .compatible = "renesas,i2c-r8a77965", .data = (void *)I2C_RCAR_GEN3 },
+ { .compatible = "renesas,i2c-r8a7797", .data = (void *)I2C_RCAR_GEN3 },
++ { .compatible = "renesas,i2c-r8a7798", .data = (void *)I2C_RCAR_GEN3 },
+ {},
+ };
+ MODULE_DEVICE_TABLE(of, rcar_i2c_dt_ids);
+diff --git a/drivers/iommu/ipmmu-vmsa.c b/drivers/iommu/ipmmu-vmsa.c
+index 1ae9174..41e14fa 100644
+--- a/drivers/iommu/ipmmu-vmsa.c
++++ b/drivers/iommu/ipmmu-vmsa.c
+@@ -1280,6 +1280,9 @@ static void ipmmu_device_reset(struct ipmmu_vmsa_device *mmu)
+ .compatible = "renesas,ipmmu-r8a7797",
+ .data = &ipmmu_features_rcar_gen3,
+ }, {
++ .compatible = "renesas,ipmmu-r8a7798",
++ .data = &ipmmu_features_rcar_gen3,
++ }, {
+ /* Terminator */
+ },
+ };
+diff --git a/drivers/media/platform/soc_camera/Kconfig b/drivers/media/platform/soc_camera/Kconfig
+index 5539c5d..fc7d829 100644
+--- a/drivers/media/platform/soc_camera/Kconfig
++++ b/drivers/media/platform/soc_camera/Kconfig
+@@ -39,7 +39,7 @@ config VIDEO_RCAR_VIN_LEGACY_DEBUG
+ config VIDEO_RCAR_CSI2_LEGACY
+ tristate "R-Car MIPI CSI-2 Interface driver"
+ depends on VIDEO_DEV && SOC_CAMERA && HAVE_CLK
+- depends on ARCH_R8A7795 || ARCH_R8A7796 || ARCH_R8A7797 || COMPILE_TEST
++ depends on ARCH_R8A7795 || ARCH_R8A7796 || ARCH_R8A7797 || ARCH_R8A7798 || COMPILE_TEST
+ ---help---
+ This is a v4l2 driver for the R-Car CSI-2 Interface
+
+diff --git a/drivers/media/platform/soc_camera/rcar_csi2.c b/drivers/media/platform/soc_camera/rcar_csi2.c
+index 2ef27e8..98f271f 100644
+--- a/drivers/media/platform/soc_camera/rcar_csi2.c
++++ b/drivers/media/platform/soc_camera/rcar_csi2.c
+@@ -163,6 +163,11 @@
+ #define RCAR_CSI2_INTSTATE_ERRSYNCESC (1 << 1)
+ #define RCAR_CSI2_INTSTATE_ERRCONTROL (1 << 0)
+
++static const struct soc_device_attribute r8a7798[] = {
++ { .soc_id = "r8a7798" },
++ { }
++};
++
+ static const struct soc_device_attribute r8a7797[] = {
+ { .soc_id = "r8a7797" },
+ { }
+@@ -410,7 +415,7 @@ static int rcar_csi2_set_phy_freq(struct rcar_csi2 *priv)
+ iowrite32((hs_freq_range_v3m[bps_per_lane] << 16) |
+ RCAR_CSI2_PHTW_DWEN | RCAR_CSI2_PHTW_CWEN | 0x44,
+ priv->base + RCAR_CSI2_PHTW);
+- else if (soc_device_match(r8a7795))
++ else if (soc_device_match(r8a7795) || soc_device_match(r8a7798))
+ iowrite32(hs_freq_range_h3[bps_per_lane] << 16,
+ priv->base + RCAR_CSI2_PHYPLL);
+ else
+@@ -497,8 +502,8 @@ static int rcar_csi2_hwinit(struct rcar_csi2 *priv)
+ return -EINVAL;
+ }
+
+- if (soc_device_match(r8a7795)) {
+- /* Set PHY Test Interface Write Register in R-Car H3(ES2.0) */
++ if (soc_device_match(r8a7795) || soc_device_match(r8a7798)) {
++ /* Set PHY Test Interface Write Register in R-Car H3(ES2.0)/V3H */
+ iowrite32(0x01cc01e2, priv->base + RCAR_CSI2_PHTW);
+ iowrite32(0x010101e3, priv->base + RCAR_CSI2_PHTW);
+ iowrite32(0x010101e4, priv->base + RCAR_CSI2_PHTW);
+@@ -515,7 +520,7 @@ static int rcar_csi2_hwinit(struct rcar_csi2 *priv)
+ /* Set CSI0CLK Frequency Configuration Preset Register
+ * in R-Car H3(ES2.0)
+ */
+- if (soc_device_match(r8a7795))
++ if (soc_device_match(r8a7795) || soc_device_match(r8a7798))
+ iowrite32(CSI0CLKFREQRANGE(32), priv->base + RCAR_CSI2_CSI0CLKFCPR);
+
+ /* Enable lanes */
+@@ -609,6 +614,7 @@ static int rcar_csi2_s_power(struct v4l2_subdev *sd, int on)
+
+ #ifdef CONFIG_OF
+ static const struct of_device_id rcar_csi2_of_table[] = {
++ { .compatible = "renesas,r8a7798-csi2", .data = (void *)RCAR_GEN3 },
+ { .compatible = "renesas,r8a7797-csi2", .data = (void *)RCAR_GEN3 },
+ { .compatible = "renesas,r8a7796-csi2", .data = (void *)RCAR_GEN3 },
+ { .compatible = "renesas,r8a7795-csi2", .data = (void *)RCAR_GEN3 },
+@@ -618,6 +624,7 @@ static int rcar_csi2_s_power(struct v4l2_subdev *sd, int on)
+ #endif
+
+ static struct platform_device_id rcar_csi2_id_table[] = {
++ { "r8a7798-csi2", RCAR_GEN3 },
+ { "r8a7797-csi2", RCAR_GEN3 },
+ { "r8a7796-csi2", RCAR_GEN3 },
+ { "r8a7795-csi2", RCAR_GEN3 },
+diff --git a/drivers/media/platform/soc_camera/rcar_vin.c b/drivers/media/platform/soc_camera/rcar_vin.c
+index b7ec03c..37f1a11 100644
+--- a/drivers/media/platform/soc_camera/rcar_vin.c
++++ b/drivers/media/platform/soc_camera/rcar_vin.c
+@@ -162,7 +162,7 @@
+ #define VNCSI_IFMD_REG 0x20 /* Video n CSI2 Interface Mode Register */
+
+ #define VNCSI_IFMD_DES1 (1 << 26) /* CSI20 */
+-#define VNCSI_IFMD_DES0 (1 << 25) /* H3:CSI40/41, M3:CSI40, V3M:CSI40 */
++#define VNCSI_IFMD_DES0 (1 << 25) /* H3,V3H:CSI40/41, M3:CSI40, V3M:CSI40 */
+
+ #define VNCSI_IFMD_CSI_CHSEL(n) (n << 0)
+ #define VNCSI_IFMD_SEL_NUMBER 5
+@@ -197,6 +197,7 @@
+
+ enum chip_id {
+ RCAR_GEN3,
++ RCAR_V3H,
+ RCAR_V3M,
+ RCAR_M3,
+ RCAR_H3,
+@@ -416,6 +417,69 @@ struct vin_gen3_ifmd {
+ },
+ };
+
++static const struct vin_gen3_ifmd vin_v3h_vc_ifmd[] = {
++ { 0x0000,
++ {
++ {RCAR_CSI40, RCAR_VIRTUAL_CH0},
++ {RCAR_CSI_CH_NONE, RCAR_VIN_CH_NONE},
++ {RCAR_CSI_CH_NONE, RCAR_VIN_CH_NONE},
++ {RCAR_CSI40, RCAR_VIRTUAL_CH1},
++ {RCAR_CSI41, RCAR_VIRTUAL_CH0},
++ {RCAR_CSI_CH_NONE, RCAR_VIN_CH_NONE},
++ {RCAR_CSI_CH_NONE, RCAR_VIN_CH_NONE},
++ {RCAR_CSI41, RCAR_VIRTUAL_CH1},
++ }
++ },
++ { 0x0001,
++ {
++ {RCAR_CSI_CH_NONE, RCAR_VIN_CH_NONE},
++ {RCAR_CSI40, RCAR_VIRTUAL_CH1},
++ {RCAR_CSI40, RCAR_VIRTUAL_CH0},
++ {RCAR_CSI_CH_NONE, RCAR_VIN_CH_NONE},
++ {RCAR_CSI_CH_NONE, RCAR_VIN_CH_NONE},
++ {RCAR_CSI41, RCAR_VIRTUAL_CH1},
++ {RCAR_CSI41, RCAR_VIRTUAL_CH0},
++ {RCAR_CSI_CH_NONE, RCAR_VIN_CH_NONE},
++ }
++ },
++ { 0x0002,
++ {
++ {RCAR_CSI40, RCAR_VIRTUAL_CH1},
++ {RCAR_CSI40, RCAR_VIRTUAL_CH0},
++ {RCAR_CSI_CH_NONE, RCAR_VIN_CH_NONE},
++ {RCAR_CSI_CH_NONE, RCAR_VIN_CH_NONE},
++ {RCAR_CSI41, RCAR_VIRTUAL_CH1},
++ {RCAR_CSI41, RCAR_VIRTUAL_CH0},
++ {RCAR_CSI_CH_NONE, RCAR_VIN_CH_NONE},
++ {RCAR_CSI_CH_NONE, RCAR_VIN_CH_NONE},
++ }
++ },
++ { 0x0003,
++ {
++ {RCAR_CSI40, RCAR_VIRTUAL_CH0},
++ {RCAR_CSI40, RCAR_VIRTUAL_CH1},
++ {RCAR_CSI40, RCAR_VIRTUAL_CH2},
++ {RCAR_CSI40, RCAR_VIRTUAL_CH3},
++ {RCAR_CSI41, RCAR_VIRTUAL_CH0},
++ {RCAR_CSI41, RCAR_VIRTUAL_CH1},
++ {RCAR_CSI41, RCAR_VIRTUAL_CH2},
++ {RCAR_CSI41, RCAR_VIRTUAL_CH3},
++ }
++ },
++ { 0x0004,
++ {
++ {RCAR_CSI_CH_NONE, RCAR_VIN_CH_NONE},
++ {RCAR_CSI_CH_NONE, RCAR_VIN_CH_NONE},
++ {RCAR_CSI_CH_NONE, RCAR_VIN_CH_NONE},
++ {RCAR_CSI_CH_NONE, RCAR_VIN_CH_NONE},
++ {RCAR_CSI_CH_NONE, RCAR_VIN_CH_NONE},
++ {RCAR_CSI_CH_NONE, RCAR_VIN_CH_NONE},
++ {RCAR_CSI_CH_NONE, RCAR_VIN_CH_NONE},
++ {RCAR_CSI_CH_NONE, RCAR_VIN_CH_NONE},
++ }
++ },
++};
++
+ enum csi2_fmt {
+ RCAR_CSI_FMT_NONE = -1,
+ RCAR_CSI_RGB888,
+@@ -911,7 +975,7 @@ static int rcar_vin_videobuf_setup(struct vb2_queue *vq,
+ struct rcar_vin_cam *cam = icd->host_priv;
+
+ if (priv->chip == RCAR_H3 || priv->chip == RCAR_M3 ||
+- priv->chip == RCAR_V3M) {
++ priv->chip == RCAR_V3M || priv->chip == RCAR_V3H) {
+ if ((priv->ratio_h > 0x10000) || (priv->ratio_v > 0x10000)) {
+ dev_err(icd->parent, "Scaling rate parameter error\n");
+ return -EINVAL;
+@@ -1020,7 +1084,7 @@ static int rcar_vin_setup(struct rcar_vin_priv *priv)
+ switch (icd->current_fmt->host_fmt->fourcc) {
+ case V4L2_PIX_FMT_NV12:
+ if (priv->chip == RCAR_H3 || priv->chip == RCAR_M3 ||
+- priv->chip == RCAR_V3M) {
++ priv->chip == RCAR_V3M || priv->chip == RCAR_V3H) {
+ iowrite32(ALIGN((cam->out_width * cam->out_height),
+ 0x80), priv->base + VNUVAOF_REG);
+ dmr = VNDMR_DTMD_YCSEP_YCBCR420;
+@@ -1056,7 +1120,7 @@ static int rcar_vin_setup(struct rcar_vin_priv *priv)
+ break;
+ case V4L2_PIX_FMT_XBGR32:
+ if (priv->chip != RCAR_H3 && priv->chip != RCAR_M3 &&
+- priv->chip != RCAR_V3M &&
++ priv->chip != RCAR_V3M && priv->chip != RCAR_V3H &&
+ priv->chip != RCAR_GEN2 && priv->chip != RCAR_H1 &&
+ priv->chip != RCAR_E1)
+ goto e_format;
+@@ -1065,7 +1129,7 @@ static int rcar_vin_setup(struct rcar_vin_priv *priv)
+ break;
+ case V4L2_PIX_FMT_ABGR32:
+ if (priv->chip != RCAR_H3 && priv->chip != RCAR_M3 &&
+- priv->chip != RCAR_V3M)
++ priv->chip != RCAR_V3M && priv->chip != RCAR_V3H)
+ goto e_format;
+
+ dmr = VNDMR_EXRGB | VNDMR_DTMD_ARGB;
+@@ -1086,7 +1150,7 @@ static int rcar_vin_setup(struct rcar_vin_priv *priv)
+ vnmc |= VNMC_BPS;
+
+ if (priv->chip == RCAR_H3 || priv->chip == RCAR_M3 ||
+- priv->chip == RCAR_V3M) {
++ priv->chip == RCAR_V3M || priv->chip == RCAR_V3H) {
+ if (priv->pdata_flags & RCAR_VIN_CSI2)
+ vnmc &= ~VNMC_DPINE;
+ else
+@@ -1457,7 +1521,7 @@ static int rcar_vin_add_device(struct soc_camera_device *icd)
+ pm_runtime_get_sync(ici->v4l2_dev.dev);
+
+ if (priv->chip == RCAR_H3 || priv->chip == RCAR_M3 ||
+- priv->chip == RCAR_V3M) {
++ priv->chip == RCAR_V3M || priv->chip == RCAR_V3H) {
+ struct v4l2_subdev *csi2_sd = find_csi2(priv);
+ struct v4l2_subdev *deser_sd = find_deser(priv);
+ int ret = 0;
+@@ -1720,7 +1784,7 @@ static int rcar_vin_set_rect(struct soc_camera_device *icd)
+ }
+
+ if (priv->chip == RCAR_H3 || priv->chip == RCAR_M3 ||
+- priv->chip == RCAR_V3M) {
++ priv->chip == RCAR_V3M || priv->chip == RCAR_V3H) {
+ if ((icd->current_fmt->host_fmt->fourcc != V4L2_PIX_FMT_NV12) &&
+ (icd->current_fmt->host_fmt->fourcc != V4L2_PIX_FMT_SBGGR8) &&
+ (icd->current_fmt->host_fmt->fourcc != V4L2_PIX_FMT_SBGGR12)
+@@ -1878,7 +1942,7 @@ static int rcar_vin_set_bus_param(struct soc_camera_device *icd)
+ return ret;
+
+ if (priv->chip == RCAR_H3 || priv->chip == RCAR_M3 ||
+- priv->chip == RCAR_V3M) {
++ priv->chip == RCAR_V3M || priv->chip == RCAR_V3H) {
+ if (cfg.type == V4L2_MBUS_CSI2)
+ vnmc &= ~VNMC_DPINE;
+ else
+@@ -1886,7 +1950,7 @@ static int rcar_vin_set_bus_param(struct soc_camera_device *icd)
+ }
+
+ if (priv->chip == RCAR_H3 || priv->chip == RCAR_M3 ||
+- priv->chip == RCAR_V3M)
++ priv->chip == RCAR_V3M || priv->chip == RCAR_V3H)
+ val = VNDMR2_FTEV;
+ else
+ val = VNDMR2_FTEV | VNDMR2_VLV(1);
+@@ -2484,7 +2548,7 @@ static int rcar_vin_try_fmt(struct soc_camera_device *icd,
+ return ret;
+
+ if (priv->chip == RCAR_H3 || priv->chip == RCAR_M3 ||
+- priv->chip == RCAR_V3M) {
++ priv->chip == RCAR_V3M || priv->chip == RCAR_V3H) {
+ /* Adjust max scaling size for Gen3 */
+ if (pix->width > 4096)
+ pix->width = priv->max_width;
+@@ -2663,6 +2727,7 @@ static int rcar_vin_get_edid(struct soc_camera_device *icd,
+
+ #ifdef CONFIG_OF
+ static const struct of_device_id rcar_vin_of_table[] = {
++ { .compatible = "renesas,vin-r8a7798", .data = (void *)RCAR_V3H },
+ { .compatible = "renesas,vin-r8a7797", .data = (void *)RCAR_V3M },
+ { .compatible = "renesas,vin-r8a7796", .data = (void *)RCAR_M3 },
+ { .compatible = "renesas,vin-r8a7795", .data = (void *)RCAR_H3 },
+@@ -2978,7 +3043,7 @@ static int rcar_vin_probe(struct platform_device *pdev)
+ }
+
+ if (priv->chip == RCAR_H3 || priv->chip == RCAR_M3 ||
+- priv->chip == RCAR_V3M) {
++ priv->chip == RCAR_V3M || priv->chip == RCAR_V3H) {
+ priv->max_width = 4096;
+ priv->max_height = 4096;
+ } else {
+@@ -2987,7 +3052,8 @@ static int rcar_vin_probe(struct platform_device *pdev)
+ }
+
+ if ((priv->chip == RCAR_H3 || priv->chip == RCAR_M3 ||
+- priv->chip == RCAR_V3M) && !of_property_read_string(np, "csi,select", &str)) {
++ priv->chip == RCAR_V3M || priv->chip == RCAR_V3H) &&
++ !of_property_read_string(np, "csi,select", &str)) {
+ u32 ifmd = 0;
+ bool match_flag = false;
+ const struct vin_gen3_ifmd *gen3_ifmd_table = NULL;
+@@ -3062,6 +3128,8 @@ static int rcar_vin_probe(struct platform_device *pdev)
+ gen3_ifmd_table = vin_m3_vc_ifmd;
+ else if (priv->chip == RCAR_V3M)
+ gen3_ifmd_table = vin_v3_vc_ifmd;
++ else if (priv->chip == RCAR_V3H)
++ gen3_ifmd_table = vin_v3h_vc_ifmd;
+
+ for (i = 0; i < num; i++) {
+ if ((gen3_ifmd_table[i].v_sel[priv->index].csi2_ch
+@@ -3219,6 +3287,9 @@ static int rcar_vin_resume(struct device *dev)
+ } else if (priv->chip == RCAR_V3M) {
+ ifmd = VNCSI_IFMD_DES1;
+ gen3_ifmd_table = vin_v3_vc_ifmd;
++ } else if (priv->chip == RCAR_V3H) {
++ ifmd = VNCSI_IFMD_DES0;
++ gen3_ifmd_table = vin_v3h_vc_ifmd;
+ }
+
+ for (i = 0; i < num; i++) {
+diff --git a/drivers/media/platform/vsp1/vsp1_lif.c b/drivers/media/platform/vsp1/vsp1_lif.c
+index e79f9e6..22fb76a 100644
+--- a/drivers/media/platform/vsp1/vsp1_lif.c
++++ b/drivers/media/platform/vsp1/vsp1_lif.c
+@@ -29,6 +29,11 @@
+ { }
+ };
+
++static const struct soc_device_attribute r8a7798[] = {
++ { .soc_id = "r8a7798" },
++ { }
++};
++
+ /* -----------------------------------------------------------------------------
+ * Device Access
+ */
+@@ -151,7 +156,8 @@ static void lif_configure(struct vsp1_entity *entity,
+ format = vsp1_entity_get_pad_format(&lif->entity, lif->entity.config,
+ LIF_PAD_SOURCE);
+
+- if (vsp1_gen3_vspdl_check(vsp1) || soc_device_match(r8a7797))
++ if (vsp1_gen3_vspdl_check(vsp1) ||
++ soc_device_match(r8a7797) || soc_device_match(r8a7798))
+ obth = 1500;
+ else
+ obth = 3000;
+diff --git a/drivers/mmc/host/sh_mobile_sdhi.c b/drivers/mmc/host/sh_mobile_sdhi.c
+index 040f474..72b46bb 100644
+--- a/drivers/mmc/host/sh_mobile_sdhi.c
++++ b/drivers/mmc/host/sh_mobile_sdhi.c
+@@ -141,6 +141,7 @@ struct sh_mobile_sdhi_of_data {
+ { .compatible = "renesas,sdhi-r8a77965",
+ .data = &of_rcar_gen3_compatible, },
+ { .compatible = "renesas,sdhi-r8a7797", .data = &of_rcar_gen3_compatible, },
++ { .compatible = "renesas,sdhi-r8a7798", .data = &of_rcar_gen3_compatible, },
+ {},
+ };
+ MODULE_DEVICE_TABLE(of, sh_mobile_sdhi_of_match);
+diff --git a/drivers/net/ethernet/renesas/ravb_main.c b/drivers/net/ethernet/renesas/ravb_main.c
+index 73fa286..c539234 100644
+--- a/drivers/net/ethernet/renesas/ravb_main.c
++++ b/drivers/net/ethernet/renesas/ravb_main.c
+@@ -1921,6 +1921,7 @@ static int ravb_mdio_release(struct ravb_private *priv)
+ { .compatible = "renesas,etheravb-r8a7796", .data = (void *)RCAR_GEN3 },
+ { .compatible = "renesas,etheravb-r8a77965", .data = (void *)RCAR_GEN3 },
+ { .compatible = "renesas,etheravb-r8a7797", .data = (void *)RCAR_GEN3 },
++ { .compatible = "renesas,etheravb-r8a7798", .data = (void *)RCAR_GEN3 },
+ { .compatible = "renesas,etheravb-rcar-gen3", .data = (void *)RCAR_GEN3 },
+ { }
+ };
+diff --git a/drivers/net/ethernet/renesas/sh_eth.c b/drivers/net/ethernet/renesas/sh_eth.c
+index d18b452..f87cae6 100644
+--- a/drivers/net/ethernet/renesas/sh_eth.c
++++ b/drivers/net/ethernet/renesas/sh_eth.c
+@@ -456,6 +456,9 @@ static void sh_eth_select_mii(struct net_device *ndev)
+ u32 value;
+
+ switch (mdp->phy_interface) {
++ case PHY_INTERFACE_MODE_RGMII:
++ value = 0x3;
++ break;
+ case PHY_INTERFACE_MODE_GMII:
+ value = 0x2;
+ break;
+@@ -645,6 +648,36 @@ static void sh_eth_set_rate_r8a777x(struct net_device *ndev)
+ .rmiimode = 1,
+ .magic = 1,
+ };
++
++/* R8A7798 */
++static struct sh_eth_cpu_data r8a7798_data = {
++ .set_duplex = sh_eth_set_duplex,
++ .set_rate = sh_eth_set_rate_gether,
++
++ .register_type = SH_ETH_REG_GIGABIT,
++
++ .ecsr_value = ECSR_PSRTO | ECSR_LCHNG | ECSR_ICD | ECSR_MPD,
++ .ecsipr_value = ECSIPR_PSRTOIP | ECSIPR_LCHNGIP | ECSIPR_ICDIP |
++ ECSIPR_MPDIP,
++ .eesipr_value = 0x01ff009f,
++
++ .tx_check = EESR_FTC | EESR_CND | EESR_DLC | EESR_CD | EESR_RTO,
++ .eesr_err_check = EESR_TWB1 | EESR_TWB | EESR_TABT | EESR_RABT |
++ EESR_RFE | EESR_RDE | EESR_RFRMER | EESR_TFE |
++ EESR_TDE | EESR_ECI,
++ .fdr_value = 0x0000070f,
++
++ .apr = 1,
++ .mpr = 1,
++ .tpauser = 1,
++ .nbst = 1,
++ .hw_swap = 1,
++ .no_trimd = 1,
++ .no_ade = 1,
++ .select_mii = 1,
++ .shift_rd0 = 1,
++ .magic = 1,
++};
+ #endif /* CONFIG_OF */
+
+ static void sh_eth_set_rate_sh7724(struct net_device *ndev)
+@@ -1088,14 +1121,14 @@ static void sh_eth_ring_free(struct net_device *ndev)
+
+ if (mdp->rx_ring) {
+ ringsize = sizeof(struct sh_eth_rxdesc) * mdp->num_rx_ring;
+- dma_free_coherent(NULL, ringsize, mdp->rx_ring,
++ dma_free_coherent(&ndev->dev, ringsize, mdp->rx_ring,
+ mdp->rx_desc_dma);
+ mdp->rx_ring = NULL;
+ }
+
+ if (mdp->tx_ring) {
+ ringsize = sizeof(struct sh_eth_txdesc) * mdp->num_tx_ring;
+- dma_free_coherent(NULL, ringsize, mdp->tx_ring,
++ dma_free_coherent(&ndev->dev, ringsize, mdp->tx_ring,
+ mdp->tx_desc_dma);
+ mdp->tx_ring = NULL;
+ }
+@@ -1209,9 +1242,16 @@ static int sh_eth_ring_init(struct net_device *ndev)
+ if (!mdp->tx_skbuff)
+ goto ring_free;
+
++#ifdef CONFIG_ARM64
++ {
++ struct device_node *np;
++ np = of_find_compatible_node(NULL, NULL, "shared-dma-pool");
++ of_dma_configure(&ndev->dev, np);
++ }
++#endif
+ /* Allocate all Rx descriptors. */
+ rx_ringsize = sizeof(struct sh_eth_rxdesc) * mdp->num_rx_ring;
+- mdp->rx_ring = dma_alloc_coherent(NULL, rx_ringsize, &mdp->rx_desc_dma,
++ mdp->rx_ring = dma_alloc_coherent(&ndev->dev, rx_ringsize, &mdp->rx_desc_dma,
+ GFP_KERNEL);
+ if (!mdp->rx_ring)
+ goto ring_free;
+@@ -1220,7 +1260,7 @@ static int sh_eth_ring_init(struct net_device *ndev)
+
+ /* Allocate all Tx descriptors. */
+ tx_ringsize = sizeof(struct sh_eth_txdesc) * mdp->num_tx_ring;
+- mdp->tx_ring = dma_alloc_coherent(NULL, tx_ringsize, &mdp->tx_desc_dma,
++ mdp->tx_ring = dma_alloc_coherent(&ndev->dev, tx_ringsize, &mdp->tx_desc_dma,
+ GFP_KERNEL);
+ if (!mdp->tx_ring)
+ goto ring_free;
+@@ -1261,6 +1301,10 @@ static int sh_eth_dev_init(struct net_device *ndev)
+ #endif
+ sh_eth_write(ndev, 0, EDMR);
+
++ /* DMA transfer burst mode */
++ if (mdp->cd->nbst)
++ sh_eth_modify(ndev, EDMR, EDMR_NBST, EDMR_NBST);
++
+ /* FIFO size set */
+ sh_eth_write(ndev, mdp->cd->fdr_value, FDR);
+ sh_eth_write(ndev, 0, TFTR);
+@@ -3001,6 +3045,7 @@ static struct sh_eth_plat_data *sh_eth_parse_dt(struct device *dev)
+ { .compatible = "renesas,ether-r8a7791", .data = &r8a779x_data },
+ { .compatible = "renesas,ether-r8a7793", .data = &r8a779x_data },
+ { .compatible = "renesas,ether-r8a7794", .data = &r8a779x_data },
++ { .compatible = "renesas,gether-r8a7798", .data = &r8a7798_data },
+ { .compatible = "renesas,ether-r7s72100", .data = &r7s72100_data },
+ { }
+ };
+diff --git a/drivers/net/ethernet/renesas/sh_eth.h b/drivers/net/ethernet/renesas/sh_eth.h
+index 4ceed00..2c4ddd6 100644
+--- a/drivers/net/ethernet/renesas/sh_eth.h
++++ b/drivers/net/ethernet/renesas/sh_eth.h
+@@ -163,7 +163,8 @@ enum {
+ };
+
+ /* Driver's parameters */
+-#if defined(CONFIG_CPU_SH4) || defined(CONFIG_ARCH_SHMOBILE)
++#if defined(CONFIG_CPU_SH4) || defined(CONFIG_ARCH_SHMOBILE) || \
++ defined(CONFIG_ARCH_R8A7798)
+ #define SH_ETH_RX_ALIGN 32
+ #else
+ #define SH_ETH_RX_ALIGN 2
+@@ -184,6 +185,7 @@ enum GECMR_BIT {
+
+ /* EDMR */
+ enum DMAC_M_BIT {
++ EDMR_NBST = 0x80,
+ EDMR_EL = 0x40, /* Litte endian */
+ EDMR_DL1 = 0x20, EDMR_DL0 = 0x10,
+ EDMR_SRST_GETHER = 0x03,
+@@ -484,6 +486,7 @@ struct sh_eth_cpu_data {
+ unsigned tpauser:1; /* EtherC have TPAUSER */
+ unsigned bculr:1; /* EtherC have BCULR */
+ unsigned tsu:1; /* EtherC have TSU */
++ unsigned nbst:1; /* E-DMAC have NBST bit in EDMR */
+ unsigned hw_swap:1; /* E-DMAC have DE bit in EDMR */
+ unsigned rpadir:1; /* E-DMAC have RPADIR */
+ unsigned no_trimd:1; /* E-DMAC DO NOT have TRIMD */
+diff --git a/drivers/pci/host/pcie-rcar.c b/drivers/pci/host/pcie-rcar.c
+index ccc29b3..ebe7e92 100644
+--- a/drivers/pci/host/pcie-rcar.c
++++ b/drivers/pci/host/pcie-rcar.c
+@@ -30,6 +30,7 @@
+ #include <linux/platform_device.h>
+ #include <linux/pm_runtime.h>
+ #include <linux/slab.h>
++#include <linux/sys_soc.h>
+
+ #define PCIECAR 0x000010
+ #define PCIECCTLR 0x000018
+@@ -41,6 +42,8 @@
+ #define PCIEINTXR 0x000400
+ #define PCIEMSITXR 0x000840
+
++#define GEN3_PCIEPHYSR 0x07f0
++
+ /* Transfer control */
+ #define PCIETCTLR 0x02000
+ #define DL_DOWN (1 << 3)
+@@ -118,6 +121,9 @@
+ #define GEN2_PCIEPHYDATA 0x784
+ #define GEN2_PCIEPHYCTRL 0x78c
+
++/* R-Car Gen3 R8A7798 */
++#define R8A7798_PCIEPHYCTL 0x4000
++
+ #define INT_PCI_MSI_NR 32
+
+ #define RCONF(x) (PCICONF(0)+(x))
+@@ -132,6 +138,11 @@
+ #define RCAR_PCI_MAX_RESOURCES 4
+ #define MAX_NR_INBOUND_MAPS 6
+
++static const struct soc_device_attribute r8a7798[] = {
++ { .soc_id = "r8a7798" },
++ { }
++};
++
+ struct rcar_msi {
+ DECLARE_BITMAP(used, INT_PCI_MSI_NR);
+ struct irq_domain *domain;
+@@ -151,6 +162,7 @@ static inline struct rcar_msi *to_rcar_msi(struct msi_controller *chip)
+ struct rcar_pcie {
+ struct device *dev;
+ void __iomem *base;
++ void __iomem *phy_base;
+ struct list_head resources;
+ int root_bus_nr;
+ struct clk *clk;
+@@ -160,6 +172,18 @@ struct rcar_pcie {
+
+ static int rcar_pcie_wait_for_dl(struct rcar_pcie *pcie);
+
++static void rcar_pci_phy_write_reg(struct rcar_pcie *pcie, unsigned long val,
++ unsigned long reg)
++{
++ writel(val, pcie->phy_base + reg);
++}
++
++static unsigned long rcar_pci_phy_read_reg(struct rcar_pcie *pcie,
++ unsigned long reg)
++{
++ return readl(pcie->phy_base + reg);
++}
++
+ static void rcar_pci_write_reg(struct rcar_pcie *pcie, unsigned long val,
+ unsigned long reg)
+ {
+@@ -672,6 +696,22 @@ static int rcar_pcie_hw_init(struct rcar_pcie *pcie)
+ return 0;
+ }
+
++static int rcar_pcie_hw_init_r8a7798(struct rcar_pcie *pcie)
++{
++ unsigned int timeout = 10;
++
++ rcar_pci_phy_write_reg(pcie, 0, R8A7798_PCIEPHYCTL);
++
++ while (timeout--) {
++ if (rcar_pci_read_reg(pcie, GEN3_PCIEPHYSR))
++ return rcar_pcie_hw_init(pcie);
++
++ msleep(5);
++ }
++
++ return -ETIMEDOUT;
++}
++
+ static int rcar_pcie_hw_init_h1(struct rcar_pcie *pcie)
+ {
+ unsigned int timeout = 10;
+@@ -998,6 +1038,16 @@ static int rcar_pcie_get_resources(struct rcar_pcie *pcie)
+ if (IS_ERR(pcie->base))
+ return PTR_ERR(pcie->base);
+
++ if (soc_device_match(r8a7798)) {
++ err = of_address_to_resource(dev->of_node, 1, &res);
++ if (err)
++ return err;
++
++ pcie->phy_base = devm_ioremap_resource(dev, &res);
++ if (IS_ERR(pcie->phy_base))
++ return PTR_ERR(pcie->base);
++ }
++
+ pcie->bus_clk = devm_clk_get(dev, "pcie_bus");
+ if (IS_ERR(pcie->bus_clk)) {
+ dev_err(dev, "cannot get pcie bus clock\n");
+@@ -1153,6 +1203,7 @@ static int rcar_pcie_parse_map_dma_ranges(struct rcar_pcie *pcie,
+ { .compatible = "renesas,pcie-r8a7795", .data = rcar_pcie_hw_init },
+ { .compatible = "renesas,pcie-r8a7796", .data = rcar_pcie_hw_init },
+ { .compatible = "renesas,pcie-r8a77965", .data = rcar_pcie_hw_init },
++ { .compatible = "renesas,pcie-r8a7798", .data = rcar_pcie_hw_init_r8a7798 },
+ {},
+ };
+
+@@ -1347,7 +1398,13 @@ static SIMPLE_DEV_PM_OPS(rcar_pcie_pm_ops,
+ },
+ .probe = rcar_pcie_probe,
+ };
+-builtin_platform_driver(rcar_pcie_driver);
++/* builtin_platform_driver(rcar_pcie_driver); */
++
++static int __init rcar_pcie_init(void)
++{
++ return platform_driver_register(&rcar_pcie_driver);
++}
++late_initcall(rcar_pcie_init);
+
+ static int rcar_pcie_pci_notifier(struct notifier_block *nb,
+ unsigned long action, void *data)
+diff --git a/drivers/pinctrl/sh-pfc/Kconfig b/drivers/pinctrl/sh-pfc/Kconfig
+index 4aaf0be..6ae17af 100644
+--- a/drivers/pinctrl/sh-pfc/Kconfig
++++ b/drivers/pinctrl/sh-pfc/Kconfig
+@@ -89,6 +89,11 @@ config PINCTRL_PFC_R8A7797
+ depends on ARCH_R8A7797
+ select PINCTRL_SH_PFC
+
++config PINCTRL_PFC_R8A7798
++ def_bool y
++ depends on ARCH_R8A7798
++ select PINCTRL_SH_PFC
++
+ config PINCTRL_PFC_SH7203
+ def_bool y
+ depends on CPU_SUBTYPE_SH7203
+diff --git a/drivers/pinctrl/sh-pfc/Makefile b/drivers/pinctrl/sh-pfc/Makefile
+index e263c14..5f2f619 100644
+--- a/drivers/pinctrl/sh-pfc/Makefile
++++ b/drivers/pinctrl/sh-pfc/Makefile
+@@ -15,6 +15,7 @@ obj-$(CONFIG_PINCTRL_PFC_R8A7795) += pfc-r8a7795-es1.o
+ obj-$(CONFIG_PINCTRL_PFC_R8A7796) += pfc-r8a7796.o
+ obj-$(CONFIG_PINCTRL_PFC_R8A77965) += pfc-r8a77965.o
+ obj-$(CONFIG_PINCTRL_PFC_R8A7797) += pfc-r8a7797.o
++obj-$(CONFIG_PINCTRL_PFC_R8A7798) += pfc-r8a7798.o
+ obj-$(CONFIG_PINCTRL_PFC_SH7203) += pfc-sh7203.o
+ obj-$(CONFIG_PINCTRL_PFC_SH7264) += pfc-sh7264.o
+ obj-$(CONFIG_PINCTRL_PFC_SH7269) += pfc-sh7269.o
+diff --git a/drivers/pinctrl/sh-pfc/core.c b/drivers/pinctrl/sh-pfc/core.c
+index 9aba933..d685090 100644
+--- a/drivers/pinctrl/sh-pfc/core.c
++++ b/drivers/pinctrl/sh-pfc/core.c
+@@ -552,6 +552,12 @@ static int sh_pfc_init_ranges(struct sh_pfc *pfc)
+ .data = &r8a7797_pinmux_info,
+ },
+ #endif
++#ifdef CONFIG_PINCTRL_PFC_R8A7798
++ {
++ .compatible = "renesas,pfc-r8a7798",
++ .data = &r8a7798_pinmux_info,
++ },
++#endif
+ #ifdef CONFIG_PINCTRL_PFC_SH73A0
+ {
+ .compatible = "renesas,pfc-sh73a0",
+diff --git a/drivers/pinctrl/sh-pfc/pfc-r8a7798.c b/drivers/pinctrl/sh-pfc/pfc-r8a7798.c
+new file mode 100644
+index 0000000..39aba74
+--- /dev/null
++++ b/drivers/pinctrl/sh-pfc/pfc-r8a7798.c
+@@ -0,0 +1,3151 @@
++/*
++ * R8A7798 processor support - PFC hardware block.
++ *
++ * Copyright (C) 2018 Renesas Electronics Corp.
++ * Copyright (C) 2018 Cogent Embedded, Inc.
++ *
++ * This file is based on the drivers/pinctrl/sh-pfc/pfc-r8a7795.c
++ *
++ * R-Car Gen3 processor support - PFC hardware block.
++ *
++ * Copyright (C) 2015 Renesas Electronics Corporation
++ *
++ * This program is free software; you can redistribute it and/or modify
++ * it under the terms of the GNU General Public License as published by
++ * the Free Software Foundation; version 2 of the License.
++ */
++
++#include <linux/io.h>
++#include <linux/kernel.h>
++#include <linux/sys_soc.h>
++
++#include "core.h"
++#include "sh_pfc.h"
++
++/* mmc in gpsr3, so do POC; check if any other reg needs it */
++#define CPU_ALL_PORT(fn, sfx) \
++ PORT_GP_CFG_22(0, fn, sfx, SH_PFC_PIN_CFG_DRIVE_STRENGTH), \
++ PORT_GP_CFG_28(1, fn, sfx, SH_PFC_PIN_CFG_DRIVE_STRENGTH), \
++ PORT_GP_CFG_30(2, fn, sfx, SH_PFC_PIN_CFG_DRIVE_STRENGTH), \
++ PORT_GP_CFG_17(3, fn, sfx, SH_PFC_PIN_CFG_DRIVE_STRENGTH | \
++ SH_PFC_PIN_CFG_IO_VOLTAGE), \
++ PORT_GP_CFG_25(4, fn, sfx, SH_PFC_PIN_CFG_DRIVE_STRENGTH), \
++ PORT_GP_CFG_15(5, fn, sfx, SH_PFC_PIN_CFG_DRIVE_STRENGTH)
++/*
++ * F_() : just information
++ * FM() : macro for FN_xxx / xxx_MARK
++ */
++
++/* GPSR0 */
++#define GPSR0_21 F_(DU_EXODDF_DU_ODDF_DISP_CDE, IP2_23_20)
++#define GPSR0_20 F_(DU_EXVSYNC_DU_VSYNC, IP2_19_16)
++#define GPSR0_19 F_(DU_EXHSYNC_DU_HSYNC, IP2_15_12)
++#define GPSR0_18 F_(DU_DOTCLKOUT, IP2_11_8)
++#define GPSR0_17 F_(DU_DB7, IP2_7_4)
++#define GPSR0_16 F_(DU_DB6, IP2_3_0)
++#define GPSR0_15 F_(DU_DB5, IP1_31_28)
++#define GPSR0_14 F_(DU_DB4, IP1_27_24)
++#define GPSR0_13 F_(DU_DB3, IP1_23_20)
++#define GPSR0_12 F_(DU_DB2, IP1_19_16)
++#define GPSR0_11 F_(DU_DG7, IP1_15_12)
++#define GPSR0_10 F_(DU_DG6, IP1_11_8)
++#define GPSR0_9 F_(DU_DG5, IP1_7_4)
++#define GPSR0_8 F_(DU_DG4, IP1_3_0)
++#define GPSR0_7 F_(DU_DG3, IP0_31_28)
++#define GPSR0_6 F_(DU_DG2, IP0_27_24)
++#define GPSR0_5 F_(DU_DR7, IP0_23_20)
++#define GPSR0_4 F_(DU_DR6, IP0_19_16)
++#define GPSR0_3 F_(DU_DR5, IP0_15_12)
++#define GPSR0_2 F_(DU_DR4, IP0_11_8)
++#define GPSR0_1 F_(DU_DR3, IP0_7_4)
++#define GPSR0_0 F_(DU_DR2, IP0_3_0)
++
++/* GPSR1 */
++#define GPSR1_27 F_(DIGRF_CLKOUT, IP8_31_28)
++#define GPSR1_26 F_(DIGRF_CLKIN, IP8_27_24)
++#define GPSR1_25 F_(CANFD_CLK_A, IP8_23_20) /* OK? */
++#define GPSR1_24 F_(CANFD1_RX, IP8_19_16)
++#define GPSR1_23 F_(CANFD1_TX, IP8_15_12)
++#define GPSR1_22 F_(CANFD0_RX_A, IP8_11_8)
++#define GPSR1_21 F_(CANFD0_TX_A, IP8_7_4)
++#define GPSR1_20 F_(AVB_AVTP_CAPTURE, IP8_3_0)
++#define GPSR1_19 F_(AVB_AVTP_MATCH, IP7_31_28)
++#define GPSR1_18 FM(AVB_LINK)
++#define GPSR1_17 FM(AVB_PHY_INT)
++#define GPSR1_16 FM(AVB_MAGIC)
++#define GPSR1_15 FM(AVB_MDC)
++#define GPSR1_14 FM(AVB_MDIO)
++#define GPSR1_13 FM(AVB_TXCREFCLK)
++#define GPSR1_12 FM(AVB_TD3)
++#define GPSR1_11 FM(AVB_TD2)
++#define GPSR1_10 FM(AVB_TD1)
++#define GPSR1_9 FM(AVB_TD0)
++#define GPSR1_8 FM(AVB_TXC)
++#define GPSR1_7 FM(AVB_TX_CTL)
++#define GPSR1_6 FM(AVB_RD3)
++#define GPSR1_5 FM(AVB_RD2)
++#define GPSR1_4 FM(AVB_RD1)
++#define GPSR1_3 FM(AVB_RD0)
++#define GPSR1_2 FM(AVB_RXC)
++#define GPSR1_1 FM(AVB_RX_CTL)
++#define GPSR1_0 F_(IRQ0, IP2_27_24)
++
++/* GPSR2 */
++#define GPSR2_29 F_(FSO_TOE_N, IP10_19_16)
++#define GPSR2_28 F_(FSO_CFE_1_N, IP10_15_12)
++#define GPSR2_27 F_(FSO_CFE_0_N, IP10_11_8)
++#define GPSR2_26 F_(SDA3, IP10_7_4)
++#define GPSR2_25 F_(SCL3, IP10_3_0)
++#define GPSR2_24 F_(MSIOF0_SS2, IP9_31_28)
++#define GPSR2_23 F_(MSIOF0_SS1, IP9_27_24)
++#define GPSR2_22 F_(MSIOF0_SYNC, IP9_23_20)
++#define GPSR2_21 F_(MSIOF0_SCK, IP9_19_16)
++#define GPSR2_20 F_(MSIOF0_TXD, IP9_15_12)
++#define GPSR2_19 F_(MSIOF0_RXD, IP9_11_8)
++#define GPSR2_18 F_(IRQ5, IP9_7_4)
++#define GPSR2_17 F_(IRQ4, IP9_3_0)
++#define GPSR2_16 F_(VI0_FIELD, IP4_31_28)
++#define GPSR2_15 F_(VI0_DATA11, IP4_27_24)
++#define GPSR2_14 F_(VI0_DATA10, IP4_23_20)
++#define GPSR2_13 F_(VI0_DATA9, IP4_19_16)
++#define GPSR2_12 F_(VI0_DATA8, IP4_15_12)
++#define GPSR2_11 F_(VI0_DATA7, IP4_11_8)
++#define GPSR2_10 F_(VI0_DATA6, IP4_7_4)
++#define GPSR2_9 F_(VI0_DATA5, IP4_3_0)
++#define GPSR2_8 F_(VI0_DATA4, IP3_31_28)
++#define GPSR2_7 F_(VI0_DATA3, IP3_27_24)
++#define GPSR2_6 F_(VI0_DATA2, IP3_23_20)
++#define GPSR2_5 F_(VI0_DATA1, IP3_19_16)
++#define GPSR2_4 F_(VI0_DATA0, IP3_15_12)
++#define GPSR2_3 F_(VI0_VSYNC_N, IP3_11_8)
++#define GPSR2_2 F_(VI0_HSYNC_N, IP3_7_4)
++#define GPSR2_1 F_(VI0_CLKENB, IP3_3_0)
++#define GPSR2_0 F_(VI0_CLK, IP2_31_28)
++
++/* GPSR3 */
++#define GPSR3_16 F_(VI1_FIELD, IP7_3_0)
++#define GPSR3_15 F_(VI1_DATA11, IP6_31_28)
++#define GPSR3_14 F_(VI1_DATA10, IP6_27_24)
++#define GPSR3_13 F_(VI1_DATA9, IP6_23_20)
++#define GPSR3_12 F_(VI1_DATA8, IP6_19_16)
++#define GPSR3_11 F_(VI1_DATA7, IP6_15_12)
++#define GPSR3_10 F_(VI1_DATA6, IP6_11_8)
++#define GPSR3_9 F_(VI1_DATA5, IP6_7_4)
++#define GPSR3_8 F_(VI1_DATA4, IP6_3_0)
++#define GPSR3_7 F_(VI1_DATA3, IP5_31_28)
++#define GPSR3_6 F_(VI1_DATA2, IP5_27_24)
++#define GPSR3_5 F_(VI1_DATA1, IP5_23_20)
++#define GPSR3_4 F_(VI1_DATA0, IP5_19_16)
++#define GPSR3_3 F_(VI1_VSYNC_N, IP5_15_12)
++#define GPSR3_2 F_(VI1_HSYNC_N, IP5_11_8)
++#define GPSR3_1 F_(VI1_CLKENB, IP5_7_4)
++#define GPSR3_0 F_(VI1_CLK, IP5_3_0)
++
++/* GPSR4 */
++#define GPSR4_24 FM(GETHER_LINK_A)
++#define GPSR4_23 FM(GETHER_PHY_INT_A)
++#define GPSR4_22 FM(GETHER_MAGIC)
++#define GPSR4_21 FM(GETHER_MDC_A)
++#define GPSR4_20 FM(GETHER_MDIO_A)
++#define GPSR4_19 FM(GETHER_TXCREFCLK_MEGA)
++#define GPSR4_18 FM(GETHER_TXCREFCLK)
++#define GPSR4_17 FM(GETHER_TD3)
++#define GPSR4_16 FM(GETHER_TD2)
++#define GPSR4_15 FM(GETHER_TD1)
++#define GPSR4_14 FM(GETHER_TD0)
++#define GPSR4_13 FM(GETHER_TXC)
++#define GPSR4_12 FM(GETHER_TX_CTL)
++#define GPSR4_11 FM(GETHER_RD3)
++#define GPSR4_10 FM(GETHER_RD2)
++#define GPSR4_9 FM(GETHER_RD1)
++#define GPSR4_8 FM(GETHER_RD0)
++#define GPSR4_7 FM(GETHER_RXC)
++#define GPSR4_6 FM(GETHER_RX_CTL)
++#define GPSR4_5 F_(SDA2, IP7_27_24)
++#define GPSR4_4 F_(SCL2, IP7_23_20)
++#define GPSR4_3 F_(SDA1, IP7_19_16)
++#define GPSR4_2 F_(SCL1, IP7_15_12)
++#define GPSR4_1 F_(SDA0, IP7_11_8)
++#define GPSR4_0 F_(SCL0, IP7_7_4)
++
++/* GPSR5 */
++#define GPSR5_14 FM(RPC_INT_N)
++#define GPSR5_13 FM(RPC_WP_N)
++#define GPSR5_12 FM(RPC_RESET_N)
++#define GPSR5_11 FM(QSPI1_SSL)
++#define GPSR5_10 FM(QSPI1_IO3)
++#define GPSR5_9 FM(QSPI1_IO2)
++#define GPSR5_8 FM(QSPI1_MISO_IO1)
++#define GPSR5_7 FM(QSPI1_MOSI_IO0)
++#define GPSR5_6 FM(QSPI1_SPCLK)
++#define GPSR5_5 FM(QSPI0_SSL)
++#define GPSR5_4 FM(QSPI0_IO3)
++#define GPSR5_3 FM(QSPI0_IO2)
++#define GPSR5_2 FM(QSPI0_MISO_IO1)
++#define GPSR5_1 FM(QSPI0_MOSI_IO0)
++#define GPSR5_0 FM(QSPI0_SPCLK)
++
++
++/* IPSRx */ /* 0 */ /* 1 */ /* 2 */ /* 3 */ /* 4 */ /* 5 */ /* 6 */ /* 7 */ /* 8 */ /* 9 */ /* A */ /* B */ /* C */ /* D */ /* E */ /* F */
++#define IP0_3_0 FM(DU_DR2) FM(SCK4) FM(GETHER_RMII_CRS_DV) FM(A0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0)
++#define IP0_7_4 FM(DU_DR3) FM(RX4) FM(GETHER_RMII_RX_ER) FM(A1) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0)
++#define IP0_11_8 FM(DU_DR4) FM(TX4) FM(GETHER_RMII_RXD0) FM(A2) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0)
++#define IP0_15_12 FM(DU_DR5) FM(CTS4_N) FM(GETHER_RMII_RXD1) FM(A3) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0)
++#define IP0_19_16 FM(DU_DR6) FM(RTS4_N_TANS) FM(GETHER_RMII_TXD_EN) FM(A4) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0)
++#define IP0_23_20 FM(DU_DR7) F_(0, 0) FM(GETHER_RMII_TXD0) FM(A5) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0)
++#define IP0_27_24 FM(DU_DG2) F_(0, 0) FM(GETHER_RMII_TXD1) FM(A6) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0)
++#define IP0_31_28 FM(DU_DG3) FM(CPG_CPCKOUT) FM(GETHER_RMII_REFCLK) FM(A7) FM(PWMFSW0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0)
++#define IP1_3_0 FM(DU_DG4) FM(SCL5) F_(0, 0) FM(A8) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0)
++#define IP1_7_4 FM(DU_DG5) FM(SDA5) FM(GETHER_MDC_B) FM(A9) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0)
++#define IP1_11_8 FM(DU_DG6) FM(SCIF_CLK_A) FM(GETHER_MDIO_B) FM(A10) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0)
++#define IP1_15_12 FM(DU_DG7) FM(HRX0_A) F_(0, 0) FM(A11) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0)
++#define IP1_19_16 FM(DU_DB2) FM(HSCK0_A) F_(0, 0) FM(A12) FM(IRQ1) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0)
++#define IP1_23_20 FM(DU_DB3) FM(HRTS0_N_A) F_(0, 0) FM(A13) FM(IRQ2) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0)
++#define IP1_27_24 FM(DU_DB4) FM(HCTS0_N_A) F_(0, 0) FM(A14) FM(IRQ3) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0)
++#define IP1_31_28 FM(DU_DB5) FM(HTX0_A) FM(PWM0_A) FM(A15) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0)
++#define IP2_3_0 FM(DU_DB6) FM(MSIOF3_RXD) F_(0, 0) FM(A16) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0)
++#define IP2_7_4 FM(DU_DB7) FM(MSIOF3_TXD) F_(0, 0) FM(A17) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0)
++#define IP2_11_8 FM(DU_DOTCLKOUT) FM(MSIOF3_SS1) FM(GETHER_LINK_B) FM(A18) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0)
++#define IP2_15_12 FM(DU_EXHSYNC_DU_HSYNC) FM(MSIOF3_SS2) FM(GETHER_PHY_INT_B) FM(A19) FM(FXR_TXENA_N) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0)
++#define IP2_19_16 FM(DU_EXVSYNC_DU_VSYNC) FM(MSIOF3_SCK) F_(0, 0) F_(0, 0) FM(FXR_TXENB_N) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0)
++#define IP2_23_20 FM(DU_EXODDF_DU_ODDF_DISP_CDE) FM(MSIOF3_SYNC) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0)
++#define IP2_27_24 FM(IRQ0) FM(CC5_OSCOUT) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0)
++#define IP2_31_28 FM(VI0_CLK) FM(MSIOF2_SCK) FM(SCK3) F_(0, 0) FM(HSCK3) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0)
++#define IP3_3_0 FM(VI0_CLKENB) FM(MSIOF2_RXD) FM(RX3) FM(RD_WR_N) FM(HCTS3_N) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0)
++#define IP3_7_4 FM(VI0_HSYNC_N) FM(MSIOF2_TXD) FM(TX3) F_(0, 0) FM(HRTS3_N) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0)
++#define IP3_11_8 FM(VI0_VSYNC_N) FM(MSIOF2_SYNC) FM(CTS3_N) F_(0, 0) FM(HTX3) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0)
++#define IP3_15_12 FM(VI0_DATA0) FM(MSIOF2_SS1) FM(RTS3_N_TANS) F_(0, 0) FM(HRX3) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0)
++#define IP3_19_16 FM(VI0_DATA1) FM(MSIOF2_SS2) FM(SCK1) F_(0, 0) FM(SPEEDIN_A) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0)
++#define IP3_23_20 FM(VI0_DATA2) FM(AVB_AVTP_PPS) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0)
++#define IP3_27_24 FM(VI0_DATA3) FM(HSCK1) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0)
++#define IP3_31_28 FM(VI0_DATA4) FM(HRTS1_N) FM(RX1_A) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0)
++#define IP4_3_0 FM(VI0_DATA5) FM(HCTS1_N) FM(TX1_A) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0)
++#define IP4_7_4 FM(VI0_DATA6) FM(HTX1) FM(CTS1_N) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0)
++#define IP4_11_8 FM(VI0_DATA7) FM(HRX1) FM(RTS1_N_TANS) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0)
++#define IP4_15_12 FM(VI0_DATA8) FM(HSCK2) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0)
++#define IP4_19_16 FM(VI0_DATA9) FM(HCTS2_N) FM(PWM1_A) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0)
++#define IP4_23_20 FM(VI0_DATA10) FM(HRTS2_N) FM(PWM2_A) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0)
++#define IP4_27_24 FM(VI0_DATA11) FM(HTX2) FM(PWM3_A) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0)
++#define IP4_31_28 FM(VI0_FIELD) FM(HRX2) FM(PWM4_A) FM(CS1_N) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0)
++#define IP5_3_0 FM(VI1_CLK) FM(MSIOF1_RXD) F_(0, 0) FM(CS0_N) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0)
++#define IP5_7_4 FM(VI1_CLKENB) FM(MSIOF1_TXD) F_(0, 0) FM(D0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0)
++#define IP5_11_8 FM(VI1_HSYNC_N) FM(MSIOF1_SCK) F_(0, 0) FM(D1) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0)
++#define IP5_15_12 FM(VI1_VSYNC_N) FM(MSIOF1_SYNC) F_(0, 0) FM(D2) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0)
++#define IP5_19_16 FM(VI1_DATA0) FM(MSIOF1_SS1) F_(0, 0) FM(D3) FM(MMC_WP) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0)
++#define IP5_23_20 FM(VI1_DATA1) FM(MSIOF1_SS2) F_(0, 0) FM(D4) FM(MMC_CD) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0)
++#define IP5_27_24 FM(VI1_DATA2) FM(CANFD0_TX_B) F_(0, 0) FM(D5) FM(MMC_DS) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0)
++#define IP5_31_28 FM(VI1_DATA3) FM(CANFD0_RX_B) F_(0, 0) FM(D6) FM(MMC_CMD) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0)
++#define IP6_3_0 FM(VI1_DATA4) FM(CANFD_CLK_B) F_(0, 0) FM(D7) FM(MMC_D0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0)
++#define IP6_7_4 FM(VI1_DATA5) F_(0, 0) F_(0, 0) FM(D8) FM(MMC_D1) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0)
++#define IP6_11_8 FM(VI1_DATA6) F_(0, 0) F_(0, 0) FM(D9) FM(MMC_D2) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0)
++#define IP6_15_12 FM(VI1_DATA7) F_(0, 0) F_(0, 0) FM(D10) FM(MMC_D3) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0)
++#define IP6_19_16 FM(VI1_DATA8) F_(0, 0) F_(0, 0) FM(D11) FM(MMC_CLK) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0)
++#define IP6_23_20 FM(VI1_DATA9) FM(TCLK1_A) F_(0, 0) FM(D12) FM(MMC_D4) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0)
++#define IP6_27_24 FM(VI1_DATA10) FM(TCLK2_A) F_(0, 0) FM(D13) FM(MMC_D5) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0)
++#define IP6_31_28 FM(VI1_DATA11) FM(SCL4) F_(0, 0) FM(D14) FM(MMC_D6) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0)
++#define IP7_3_0 FM(VI1_FIELD) FM(SDA4) F_(0, 0) FM(D15) FM(MMC_D7) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0)
++#define IP7_7_4 FM(SCL0) F_(0, 0) F_(0, 0) FM(CLKOUT) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0)
++#define IP7_11_8 FM(SDA0) F_(0, 0) F_(0, 0) FM(BS_N) FM(SCK0) FM(HSCK0_B) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0)
++#define IP7_15_12 FM(SCL1) F_(0, 0) FM(TPU0TO2) FM(RD_N) FM(CTS0_N) FM(HCTS0_N_B) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0)
++#define IP7_19_16 FM(SDA1) F_(0, 0) FM(TPU0TO3) FM(WE0_N) FM(RTS0_N_TANS) FM(HRTS0_N_B) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0)
++#define IP7_23_20 FM(SCL2) F_(0, 0) F_(0, 0) FM(WE1_N) FM(RX0) FM(HRX0_B) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0)
++#define IP7_27_24 FM(SDA2) F_(0, 0) F_(0, 0) FM(EX_WAIT0) FM(TX0) FM(HTX0_B) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0)
++#define IP7_31_28 FM(AVB_AVTP_MATCH) FM(TPU0TO0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0)
++#define IP8_3_0 FM(AVB_AVTP_CAPTURE) FM(TPU0TO1) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0)
++#define IP8_7_4 FM(CANFD0_TX_A) FM(FXR_TXDA) FM(PWM0_B) FM(DU_DISP) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0)
++#define IP8_11_8 FM(CANFD0_RX_A) FM(RXDA_EXTFXR) FM(PWM1_B) FM(DU_CDE) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0)
++#define IP8_15_12 FM(CANFD1_TX) FM(FXR_TXDB) FM(PWM2_B) FM(TCLK1_B) FM(TX1_B) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0)
++#define IP8_19_16 FM(CANFD1_RX) FM(RXDB_EXTFXR) FM(PWM3_B) FM(TCLK2_B) FM(RX1_B) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0)
++#define IP8_23_20 FM(CANFD_CLK_A) FM(CLK_EXTFXR) FM(PWM4_B) FM(SPEEDIN_B) FM(SCIF_CLK_B) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0)
++#define IP8_27_24 FM(DIGRF_CLKIN) FM(DIGRF_CLKEN_IN) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0)
++#define IP8_31_28 FM(DIGRF_CLKOUT) FM(DIGRF_CLKEN_OUT) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0)
++#define IP9_3_0 FM(IRQ4) F_(0, 0) F_(0, 0) FM(VI0_DATA12) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0)
++#define IP9_7_4 FM(IRQ5) F_(0, 0) F_(0, 0) FM(VI0_DATA13) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0)
++#define IP9_11_8 FM(MSIOF0_RXD) FM(DU_DR0) F_(0, 0) FM(VI0_DATA14) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0)
++#define IP9_15_12 FM(MSIOF0_TXD) FM(DU_DR1) F_(0, 0) FM(VI0_DATA15) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0)
++#define IP9_19_16 FM(MSIOF0_SCK) FM(DU_DG0) F_(0, 0) FM(VI0_DATA16) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0)
++#define IP9_23_20 FM(MSIOF0_SYNC) FM(DU_DG1) F_(0, 0) FM(VI0_DATA17) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0)
++#define IP9_27_24 FM(MSIOF0_SS1) FM(DU_DB0) FM(TCLK3) FM(VI0_DATA18) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0)
++#define IP9_31_28 FM(MSIOF0_SS2) FM(DU_DB1) FM(TCLK4) FM(VI0_DATA19) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0)
++#define IP10_3_0 FM(SCL3) F_(0, 0) F_(0, 0) FM(VI0_DATA20) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0)
++#define IP10_7_4 FM(SDA3) F_(0, 0) F_(0, 0) FM(VI0_DATA21) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0)
++#define IP10_11_8 FM(FSO_CFE_0_N) F_(0, 0) F_(0, 0) FM(VI0_DATA22) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0)
++#define IP10_15_12 FM(FSO_CFE_1_N) F_(0, 0) F_(0, 0) FM(VI0_DATA23) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0)
++#define IP10_19_16 FM(FSO_TOE_N) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0)
++#define IP10_23_20 F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0)
++#define IP10_27_24 F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0)
++#define IP10_31_28 F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0) F_(0, 0)
++
++#define PINMUX_GPSR \
++\
++ GPSR2_29 \
++ GPSR2_28 \
++ GPSR1_27 GPSR2_27 \
++ GPSR1_26 GPSR2_26 \
++ GPSR1_25 GPSR2_25 \
++ GPSR1_24 GPSR2_24 GPSR4_24 \
++ GPSR1_23 GPSR2_23 GPSR4_23 \
++ GPSR1_22 GPSR2_22 GPSR4_22 \
++GPSR0_21 GPSR1_21 GPSR2_21 GPSR4_21 \
++GPSR0_20 GPSR1_20 GPSR2_20 GPSR4_20 \
++GPSR0_19 GPSR1_19 GPSR2_19 GPSR4_19 \
++GPSR0_18 GPSR1_18 GPSR2_18 GPSR4_18 \
++GPSR0_17 GPSR1_17 GPSR2_17 GPSR4_17 \
++GPSR0_16 GPSR1_16 GPSR2_16 GPSR3_16 GPSR4_16 \
++GPSR0_15 GPSR1_15 GPSR2_15 GPSR3_15 GPSR4_15 \
++GPSR0_14 GPSR1_14 GPSR2_14 GPSR3_14 GPSR4_14 GPSR5_14 \
++GPSR0_13 GPSR1_13 GPSR2_13 GPSR3_13 GPSR4_13 GPSR5_13 \
++GPSR0_12 GPSR1_12 GPSR2_12 GPSR3_12 GPSR4_12 GPSR5_12 \
++GPSR0_11 GPSR1_11 GPSR2_11 GPSR3_11 GPSR4_11 GPSR5_11 \
++GPSR0_10 GPSR1_10 GPSR2_10 GPSR3_10 GPSR4_10 GPSR5_10 \
++GPSR0_9 GPSR1_9 GPSR2_9 GPSR3_9 GPSR4_9 GPSR5_9 \
++GPSR0_8 GPSR1_8 GPSR2_8 GPSR3_8 GPSR4_8 GPSR5_8 \
++GPSR0_7 GPSR1_7 GPSR2_7 GPSR3_7 GPSR4_7 GPSR5_7 \
++GPSR0_6 GPSR1_6 GPSR2_6 GPSR3_6 GPSR4_6 GPSR5_6 \
++GPSR0_5 GPSR1_5 GPSR2_5 GPSR3_5 GPSR4_5 GPSR5_5 \
++GPSR0_4 GPSR1_4 GPSR2_4 GPSR3_4 GPSR4_4 GPSR5_4 \
++GPSR0_3 GPSR1_3 GPSR2_3 GPSR3_3 GPSR4_3 GPSR5_3 \
++GPSR0_2 GPSR1_2 GPSR2_2 GPSR3_2 GPSR4_2 GPSR5_2 \
++GPSR0_1 GPSR1_1 GPSR2_1 GPSR3_1 GPSR4_1 GPSR5_1 \
++GPSR0_0 GPSR1_0 GPSR2_0 GPSR3_0 GPSR4_0 GPSR5_0
++
++#define PINMUX_IPSR \
++\
++FM(IP0_3_0) IP0_3_0 FM(IP1_3_0) IP1_3_0 FM(IP2_3_0) IP2_3_0 FM(IP3_3_0) IP3_3_0 \
++FM(IP0_7_4) IP0_7_4 FM(IP1_7_4) IP1_7_4 FM(IP2_7_4) IP2_7_4 FM(IP3_7_4) IP3_7_4 \
++FM(IP0_11_8) IP0_11_8 FM(IP1_11_8) IP1_11_8 FM(IP2_11_8) IP2_11_8 FM(IP3_11_8) IP3_11_8 \
++FM(IP0_15_12) IP0_15_12 FM(IP1_15_12) IP1_15_12 FM(IP2_15_12) IP2_15_12 FM(IP3_15_12) IP3_15_12 \
++FM(IP0_19_16) IP0_19_16 FM(IP1_19_16) IP1_19_16 FM(IP2_19_16) IP2_19_16 FM(IP3_19_16) IP3_19_16 \
++FM(IP0_23_20) IP0_23_20 FM(IP1_23_20) IP1_23_20 FM(IP2_23_20) IP2_23_20 FM(IP3_23_20) IP3_23_20 \
++FM(IP0_27_24) IP0_27_24 FM(IP1_27_24) IP1_27_24 FM(IP2_27_24) IP2_27_24 FM(IP3_27_24) IP3_27_24 \
++FM(IP0_31_28) IP0_31_28 FM(IP1_31_28) IP1_31_28 FM(IP2_31_28) IP2_31_28 FM(IP3_31_28) IP3_31_28 \
++\
++FM(IP4_3_0) IP4_3_0 FM(IP5_3_0) IP5_3_0 FM(IP6_3_0) IP6_3_0 FM(IP7_3_0) IP7_3_0 \
++FM(IP4_7_4) IP4_7_4 FM(IP5_7_4) IP5_7_4 FM(IP6_7_4) IP6_7_4 FM(IP7_7_4) IP7_7_4 \
++FM(IP4_11_8) IP4_11_8 FM(IP5_11_8) IP5_11_8 FM(IP6_11_8) IP6_11_8 FM(IP7_11_8) IP7_11_8 \
++FM(IP4_15_12) IP4_15_12 FM(IP5_15_12) IP5_15_12 FM(IP6_15_12) IP6_15_12 FM(IP7_15_12) IP7_15_12 \
++FM(IP4_19_16) IP4_19_16 FM(IP5_19_16) IP5_19_16 FM(IP6_19_16) IP6_19_16 FM(IP7_19_16) IP7_19_16 \
++FM(IP4_23_20) IP4_23_20 FM(IP5_23_20) IP5_23_20 FM(IP6_23_20) IP6_23_20 FM(IP7_23_20) IP7_23_20 \
++FM(IP4_27_24) IP4_27_24 FM(IP5_27_24) IP5_27_24 FM(IP6_27_24) IP6_27_24 FM(IP7_27_24) IP7_27_24 \
++FM(IP4_31_28) IP4_31_28 FM(IP5_31_28) IP5_31_28 FM(IP6_31_28) IP6_31_28 FM(IP7_31_28) IP7_31_28 \
++\
++FM(IP8_3_0) IP8_3_0 FM(IP9_3_0) IP9_3_0 FM(IP10_3_0) IP10_3_0 \
++FM(IP8_7_4) IP8_7_4 FM(IP9_7_4) IP9_7_4 FM(IP10_7_4) IP10_7_4 \
++FM(IP8_11_8) IP8_11_8 FM(IP9_11_8) IP9_11_8 FM(IP10_11_8) IP10_11_8 \
++FM(IP8_15_12) IP8_15_12 FM(IP9_15_12) IP9_15_12 FM(IP10_15_12) IP10_15_12 \
++FM(IP8_19_16) IP8_19_16 FM(IP9_19_16) IP9_19_16 FM(IP10_19_16) IP10_19_16 \
++FM(IP8_23_20) IP8_23_20 FM(IP9_23_20) IP9_23_20 FM(IP10_23_20) IP10_23_20 \
++FM(IP8_27_24) IP8_27_24 FM(IP9_27_24) IP9_27_24 FM(IP10_27_24) IP10_27_24 \
++FM(IP8_31_28) IP8_31_28 FM(IP9_31_28) IP9_31_28 FM(IP10_31_28) IP10_31_28
++
++/*
++ Set Value = H'0 Set Value = H'1
++Register Function Pin Function Pin
++------------------------------------------------------------
++sel_canfd0 CANFD0_TX_A CANFD0_TX_A CANFD0_TX_B VI1_DATA2
++ CANFD0_RX_A CANFD0_RX_A CANFD0_TX_B VI1_DATA3
++ CANFD_CLK_A CANFD_CLK_A CANFD_CLK_B VI1_DATA4
++sel_gether GETHER_MDC_A GETHER_MDC_A GETHER_MDC_B DU_DG5
++ GETHER_MDIO_A GETHER_MDIO_A GETHER_MDIO_B DU_DG6
++ GETHER_LINK_A GETHER_LINK_A GETHER_LINK_B DU_DOTCLKOUT
++ GETHER_PHY_INT_A GETHER_PHY_INT_A GETHER_PHY_INT_B DU_EXHSYNC_DU_HSYNC
++sel_hscif0 HSCK0_A DU_DB2 HSCK0_B SDA0
++ HCTS0_N_A DU_DB4 HCTS_N_B SCL1
++ HRTS0_N_A DU_DB3 HRTS_N_B SDA1
++ HRX0_A DU_DG7 HRX0_B SCL2
++ HTX0_A DU_DB5 HTX0_B SDA2
++ SCIF_CLK_A DU_DG6 SCIF_CLK_B CANFD_CLK_A
++sel_pwm0 PWM0_A DU_DB5 PWM0_B CANFD0_TX_A
++sel_pwm1 PWM1_A VI0_DATA9 PWM1_B CANFD0_RX_A
++sel_pwm2 PWM2_A VI0_DATA10 PWM2_B CANFD1_TX
++sel_pwm3 PWM3_A VI0_DATA11 PWM3_B CANFD1_RX
++sel_pwm4 PWM4_A VI0_FIELD PWM4_B CANFD_CLK_A
++sel_rsp SPEEDIN_A VI0_DATA1 SPEEDIN_B CANFD_CLK_A
++sel_scif1 RX1_A VI0_DATA4 RX1_B CANFD1_RX
++ TX1_A VI0_DATA5 TX1_B CANFD1_TX
++sel_tmu TCLK1_A VI1_DATA9 TCLK1_B CANFD1_TX
++ TCLK2_A VI1_DATA10 TCLK2_B CANFD1_RX
++*/
++/* MOD_SEL0 */ /* 0 */ /* 1 */ /* 2 */ /* 3 */ /* 4 */ /* 5 */ /* 6 */ /* 7 */
++#define MOD_SEL0_11 FM(SEL_CANFD0_0) FM(SEL_CANFD0_1)
++#define MOD_SEL0_10 FM(SEL_GETHER_0) FM(SEL_GETHER_1)
++#define MOD_SEL0_9 FM(SEL_HSCIF0_0) FM(SEL_HSCIF0_1)
++#define MOD_SEL0_8 FM(SEL_PWM0_0) FM(SEL_PWM0_1)
++#define MOD_SEL0_7 FM(SEL_PWM1_0) FM(SEL_PWM1_1)
++#define MOD_SEL0_6 FM(SEL_PWM2_0) FM(SEL_PWM2_1)
++#define MOD_SEL0_5 FM(SEL_PWM3_0) FM(SEL_PWM3_1)
++#define MOD_SEL0_4 FM(SEL_PWM4_0) FM(SEL_PWM4_1)
++#define MOD_SEL0_2 FM(SEL_RSP_0) FM(SEL_RSP_1)
++#define MOD_SEL0_1 FM(SEL_SCIF1_0) FM(SEL_SCIF1_1)
++#define MOD_SEL0_0 FM(SEL_TMU1_0) FM(SEL_TMU1_1)
++
++#define PINMUX_MOD_SELS \
++\
++MOD_SEL0_11 \
++MOD_SEL0_10 \
++MOD_SEL0_9 \
++MOD_SEL0_8 \
++MOD_SEL0_7 \
++MOD_SEL0_6 \
++MOD_SEL0_5 \
++MOD_SEL0_4 \
++MOD_SEL0_2 \
++MOD_SEL0_1 \
++MOD_SEL0_0
++
++enum {
++ PINMUX_RESERVED = 0,
++
++ PINMUX_DATA_BEGIN,
++ GP_ALL(DATA),
++ PINMUX_DATA_END,
++
++#define F_(x, y)
++#define FM(x) FN_##x,
++ PINMUX_FUNCTION_BEGIN,
++ GP_ALL(FN),
++ PINMUX_GPSR
++ PINMUX_IPSR
++ PINMUX_MOD_SELS
++ PINMUX_FUNCTION_END,
++#undef F_
++#undef FM
++
++#define F_(x, y)
++#define FM(x) x##_MARK,
++ PINMUX_MARK_BEGIN,
++ PINMUX_GPSR
++ PINMUX_IPSR
++ PINMUX_MOD_SELS
++ PINMUX_MARK_END,
++#undef F_
++#undef FM
++};
++
++static const u16 pinmux_data[] = {
++ PINMUX_DATA_GP_ALL(),
++
++ PINMUX_SINGLE(AVB_RX_CTL),
++ PINMUX_SINGLE(AVB_RXC),
++ PINMUX_SINGLE(AVB_RD0),
++ PINMUX_SINGLE(AVB_RD1),
++ PINMUX_SINGLE(AVB_RD2),
++ PINMUX_SINGLE(AVB_RD3),
++ PINMUX_SINGLE(AVB_TX_CTL),
++ PINMUX_SINGLE(AVB_TXC),
++ PINMUX_SINGLE(AVB_TD0),
++ PINMUX_SINGLE(AVB_TD1),
++ PINMUX_SINGLE(AVB_TD2),
++ PINMUX_SINGLE(AVB_TD3),
++ PINMUX_SINGLE(AVB_TXCREFCLK),
++ PINMUX_SINGLE(AVB_MDIO),
++ PINMUX_SINGLE(AVB_MDC),
++ PINMUX_SINGLE(AVB_MAGIC),
++ PINMUX_SINGLE(AVB_PHY_INT),
++ PINMUX_SINGLE(AVB_LINK),
++
++ PINMUX_SINGLE(GETHER_RX_CTL),
++ PINMUX_SINGLE(GETHER_RXC),
++ PINMUX_SINGLE(GETHER_RD0),
++ PINMUX_SINGLE(GETHER_RD1),
++ PINMUX_SINGLE(GETHER_RD2),
++ PINMUX_SINGLE(GETHER_RD3),
++ PINMUX_SINGLE(GETHER_TX_CTL),
++ PINMUX_SINGLE(GETHER_TXC),
++ PINMUX_SINGLE(GETHER_TD0),
++ PINMUX_SINGLE(GETHER_TD1),
++ PINMUX_SINGLE(GETHER_TD2),
++ PINMUX_SINGLE(GETHER_TD3),
++ PINMUX_SINGLE(GETHER_TXCREFCLK),
++ PINMUX_SINGLE(GETHER_TXCREFCLK_MEGA),
++ PINMUX_SINGLE(GETHER_MDIO_A),
++ PINMUX_SINGLE(GETHER_MDC_A),
++ PINMUX_SINGLE(GETHER_MAGIC),
++ PINMUX_SINGLE(GETHER_PHY_INT_A),
++ PINMUX_SINGLE(GETHER_LINK_A),
++
++ PINMUX_SINGLE(QSPI0_SPCLK),
++ PINMUX_SINGLE(QSPI0_MOSI_IO0),
++ PINMUX_SINGLE(QSPI0_MISO_IO1),
++ PINMUX_SINGLE(QSPI0_IO2),
++ PINMUX_SINGLE(QSPI0_IO3),
++ PINMUX_SINGLE(QSPI0_SSL),
++ PINMUX_SINGLE(QSPI1_SPCLK),
++ PINMUX_SINGLE(QSPI1_MOSI_IO0),
++ PINMUX_SINGLE(QSPI1_MISO_IO1),
++ PINMUX_SINGLE(QSPI1_IO2),
++ PINMUX_SINGLE(QSPI1_IO3),
++ PINMUX_SINGLE(QSPI1_SSL),
++ PINMUX_SINGLE(RPC_RESET_N),
++ PINMUX_SINGLE(RPC_WP_N),
++ PINMUX_SINGLE(RPC_INT_N),
++
++ /* IPSR0 */
++ PINMUX_IPSR_GPSR(IP0_3_0, DU_DR2),
++ PINMUX_IPSR_GPSR(IP0_3_0, SCK4),
++ PINMUX_IPSR_GPSR(IP0_3_0, GETHER_RMII_CRS_DV),
++ PINMUX_IPSR_GPSR(IP0_3_0, A0),
++
++ PINMUX_IPSR_GPSR(IP0_7_4, DU_DR3),
++ PINMUX_IPSR_GPSR(IP0_7_4, RX4),
++ PINMUX_IPSR_GPSR(IP0_7_4, GETHER_RMII_RX_ER),
++ PINMUX_IPSR_GPSR(IP0_7_4, A1),
++
++ PINMUX_IPSR_GPSR(IP0_11_8, DU_DR4),
++ PINMUX_IPSR_GPSR(IP0_11_8, TX4),
++ PINMUX_IPSR_GPSR(IP0_11_8, GETHER_RMII_RXD0),
++ PINMUX_IPSR_GPSR(IP0_11_8, A2),
++
++ PINMUX_IPSR_GPSR(IP0_15_12, DU_DR5),
++ PINMUX_IPSR_GPSR(IP0_15_12, CTS4_N),
++ PINMUX_IPSR_GPSR(IP0_15_12, GETHER_RMII_RXD1),
++ PINMUX_IPSR_GPSR(IP0_15_12, A3),
++
++ PINMUX_IPSR_GPSR(IP0_19_16, DU_DR6),
++ PINMUX_IPSR_GPSR(IP0_19_16, RTS4_N_TANS),
++ PINMUX_IPSR_GPSR(IP0_19_16, GETHER_RMII_TXD_EN),
++ PINMUX_IPSR_GPSR(IP0_19_16, A4),
++
++ PINMUX_IPSR_GPSR(IP0_23_20, DU_DR7),
++ PINMUX_IPSR_GPSR(IP0_23_20, GETHER_RMII_TXD0),
++ PINMUX_IPSR_GPSR(IP0_23_20, A5),
++
++ PINMUX_IPSR_GPSR(IP0_27_24, DU_DG2),
++ PINMUX_IPSR_GPSR(IP0_27_24, GETHER_RMII_TXD1),
++ PINMUX_IPSR_GPSR(IP0_27_24, A6),
++
++ PINMUX_IPSR_GPSR(IP0_31_28, DU_DG3),
++ PINMUX_IPSR_GPSR(IP0_31_28, CPG_CPCKOUT),
++ PINMUX_IPSR_GPSR(IP0_31_28, GETHER_RMII_REFCLK),
++ PINMUX_IPSR_GPSR(IP0_31_28, A7),
++ PINMUX_IPSR_GPSR(IP0_31_28, PWMFSW0),
++
++ /* IPSR1 */
++ PINMUX_IPSR_GPSR(IP1_3_0, DU_DG4),
++ PINMUX_IPSR_GPSR(IP1_3_0, SCL5),
++ PINMUX_IPSR_GPSR(IP1_3_0, A8),
++
++ PINMUX_IPSR_GPSR(IP1_7_4, DU_DG5),
++ PINMUX_IPSR_GPSR(IP1_7_4, SDA5),
++ PINMUX_IPSR_MSEL(IP1_7_4, GETHER_MDC_B, SEL_GETHER_1),
++ PINMUX_IPSR_GPSR(IP1_7_4, A9),
++
++ PINMUX_IPSR_GPSR(IP1_11_8, DU_DG6),
++ PINMUX_IPSR_MSEL(IP1_11_8, SCIF_CLK_A, SEL_HSCIF0_0),
++ PINMUX_IPSR_MSEL(IP1_11_8, GETHER_MDIO_B, SEL_GETHER_1),
++ PINMUX_IPSR_GPSR(IP1_11_8, A10),
++
++ PINMUX_IPSR_GPSR(IP1_15_12, DU_DG7),
++ PINMUX_IPSR_MSEL(IP1_15_12, HRX0_A, SEL_HSCIF0_0),
++ PINMUX_IPSR_GPSR(IP1_15_12, A11),
++
++ PINMUX_IPSR_GPSR(IP1_19_16, DU_DB2),
++ PINMUX_IPSR_MSEL(IP1_19_16, HSCK0_A, SEL_HSCIF0_0),
++ PINMUX_IPSR_GPSR(IP1_19_16, A12),
++ PINMUX_IPSR_GPSR(IP1_19_16, IRQ1),
++
++ PINMUX_IPSR_GPSR(IP1_23_20, DU_DB3),
++ PINMUX_IPSR_MSEL(IP1_23_20, HRTS0_N_A, SEL_HSCIF0_0),
++ PINMUX_IPSR_GPSR(IP1_23_20, A13),
++ PINMUX_IPSR_GPSR(IP1_23_20, IRQ2),
++
++ PINMUX_IPSR_GPSR(IP1_27_24, DU_DB4),
++ PINMUX_IPSR_MSEL(IP1_27_24, HCTS0_N_A, SEL_HSCIF0_0),
++ PINMUX_IPSR_GPSR(IP1_27_24, A14),
++ PINMUX_IPSR_GPSR(IP1_27_24, IRQ3),
++
++ PINMUX_IPSR_GPSR(IP1_31_28, DU_DB5),
++ PINMUX_IPSR_MSEL(IP1_31_28, HTX0_A, SEL_HSCIF0_0),
++ PINMUX_IPSR_MSEL(IP1_31_28, PWM0_A, SEL_PWM0_0),
++ PINMUX_IPSR_GPSR(IP1_31_28, A15),
++
++ /* IPSR2 */
++ PINMUX_IPSR_GPSR(IP2_3_0, DU_DB6),
++ PINMUX_IPSR_GPSR(IP2_3_0, MSIOF3_RXD),
++ PINMUX_IPSR_GPSR(IP2_3_0, A16),
++
++ PINMUX_IPSR_GPSR(IP2_7_4, DU_DB7),
++ PINMUX_IPSR_GPSR(IP2_7_4, MSIOF3_TXD),
++ PINMUX_IPSR_GPSR(IP2_7_4, A17),
++
++ PINMUX_IPSR_GPSR(IP2_11_8, DU_DOTCLKOUT),
++ PINMUX_IPSR_GPSR(IP2_11_8, MSIOF3_SS1),
++ PINMUX_IPSR_MSEL(IP2_11_8, GETHER_LINK_B, SEL_GETHER_1),
++ PINMUX_IPSR_GPSR(IP2_11_8, A18),
++
++ PINMUX_IPSR_GPSR(IP2_15_12, DU_EXHSYNC_DU_HSYNC),
++ PINMUX_IPSR_GPSR(IP2_15_12, MSIOF3_SS2),
++ PINMUX_IPSR_MSEL(IP2_15_12, GETHER_PHY_INT_B, SEL_GETHER_1),
++ PINMUX_IPSR_GPSR(IP2_15_12, A19),
++ PINMUX_IPSR_GPSR(IP2_15_12, FXR_TXENA_N),
++
++ PINMUX_IPSR_GPSR(IP2_19_16, DU_EXVSYNC_DU_VSYNC),
++ PINMUX_IPSR_GPSR(IP2_19_16, MSIOF3_SCK),
++ PINMUX_IPSR_GPSR(IP2_19_16, FXR_TXENB_N),
++
++ PINMUX_IPSR_GPSR(IP2_23_20, DU_EXODDF_DU_ODDF_DISP_CDE),
++ PINMUX_IPSR_GPSR(IP2_23_20, MSIOF3_SYNC),
++
++ PINMUX_IPSR_GPSR(IP2_27_24, IRQ0),
++ PINMUX_IPSR_GPSR(IP2_27_24, CC5_OSCOUT),
++
++ PINMUX_IPSR_GPSR(IP2_31_28, VI0_CLK),
++ PINMUX_IPSR_GPSR(IP2_31_28, MSIOF2_SCK),
++ PINMUX_IPSR_GPSR(IP2_31_28, SCK3),
++ PINMUX_IPSR_GPSR(IP2_31_28, HSCK3),
++
++ /* IPSR3 */
++ PINMUX_IPSR_GPSR(IP3_3_0, VI0_CLKENB),
++ PINMUX_IPSR_GPSR(IP3_3_0, MSIOF2_RXD),
++ PINMUX_IPSR_GPSR(IP3_3_0, RX3),
++ PINMUX_IPSR_GPSR(IP3_3_0, RD_WR_N),
++ PINMUX_IPSR_GPSR(IP3_3_0, HCTS3_N),
++
++ PINMUX_IPSR_GPSR(IP3_7_4, VI0_HSYNC_N),
++ PINMUX_IPSR_GPSR(IP3_7_4, MSIOF2_TXD),
++ PINMUX_IPSR_GPSR(IP3_7_4, TX3),
++ PINMUX_IPSR_GPSR(IP3_7_4, HRTS3_N),
++
++ PINMUX_IPSR_GPSR(IP3_11_8, VI0_VSYNC_N),
++ PINMUX_IPSR_GPSR(IP3_11_8, MSIOF2_SYNC),
++ PINMUX_IPSR_GPSR(IP3_11_8, CTS3_N),
++ PINMUX_IPSR_GPSR(IP3_11_8, HTX3),
++
++ PINMUX_IPSR_GPSR(IP3_15_12, VI0_DATA0),
++ PINMUX_IPSR_GPSR(IP3_15_12, MSIOF2_SS1),
++ PINMUX_IPSR_GPSR(IP3_15_12, RTS3_N_TANS),
++ PINMUX_IPSR_GPSR(IP3_15_12, HRX3),
++
++ PINMUX_IPSR_GPSR(IP3_19_16, VI0_DATA1),
++ PINMUX_IPSR_GPSR(IP3_19_16, MSIOF2_SS2),
++ PINMUX_IPSR_GPSR(IP3_19_16, SCK1),
++ PINMUX_IPSR_MSEL(IP3_19_16, SPEEDIN_A, SEL_RSP_0),
++
++ PINMUX_IPSR_GPSR(IP3_23_20, VI0_DATA2),
++ PINMUX_IPSR_GPSR(IP3_23_20, AVB_AVTP_PPS),
++
++ PINMUX_IPSR_GPSR(IP3_27_24, VI0_DATA3),
++ PINMUX_IPSR_GPSR(IP3_27_24, HSCK1),
++
++ PINMUX_IPSR_GPSR(IP3_31_28, VI0_DATA4),
++ PINMUX_IPSR_GPSR(IP3_31_28, HRTS1_N),
++ PINMUX_IPSR_MSEL(IP3_31_28, RX1_A, SEL_SCIF1_0),
++
++ /* IPSR4 */
++ PINMUX_IPSR_GPSR(IP4_3_0, VI0_DATA5),
++ PINMUX_IPSR_GPSR(IP4_3_0, HCTS1_N),
++ PINMUX_IPSR_MSEL(IP4_3_0, TX1_A, SEL_SCIF1_0),
++
++ PINMUX_IPSR_GPSR(IP4_7_4, VI0_DATA6),
++ PINMUX_IPSR_GPSR(IP4_7_4, HTX1),
++ PINMUX_IPSR_GPSR(IP4_7_4, CTS1_N),
++
++ PINMUX_IPSR_GPSR(IP4_11_8, VI0_DATA7),
++ PINMUX_IPSR_GPSR(IP4_11_8, HRX1),
++ PINMUX_IPSR_GPSR(IP4_11_8, RTS1_N_TANS),
++
++ PINMUX_IPSR_GPSR(IP4_15_12, VI0_DATA8),
++ PINMUX_IPSR_GPSR(IP4_15_12, HSCK2),
++
++ PINMUX_IPSR_GPSR(IP4_19_16, VI0_DATA9),
++ PINMUX_IPSR_GPSR(IP4_19_16, HCTS2_N),
++ PINMUX_IPSR_MSEL(IP4_19_16, PWM1_A, SEL_PWM1_0),
++
++ PINMUX_IPSR_GPSR(IP4_23_20, VI0_DATA10),
++ PINMUX_IPSR_GPSR(IP4_23_20, HRTS2_N),
++ PINMUX_IPSR_MSEL(IP4_23_20, PWM2_A, SEL_PWM2_0),
++
++ PINMUX_IPSR_GPSR(IP4_27_24, VI0_DATA11),
++ PINMUX_IPSR_GPSR(IP4_27_24, HTX2),
++ PINMUX_IPSR_MSEL(IP4_27_24, PWM3_A, SEL_PWM3_0),
++
++ PINMUX_IPSR_GPSR(IP4_31_28, VI0_FIELD),
++ PINMUX_IPSR_GPSR(IP4_31_28, HRX2),
++ PINMUX_IPSR_MSEL(IP4_31_28, PWM4_A, SEL_PWM4_0),
++ PINMUX_IPSR_GPSR(IP4_31_28, CS1_N),
++
++ /* IPSR5 */
++ PINMUX_IPSR_GPSR(IP5_3_0, VI1_CLK),
++ PINMUX_IPSR_GPSR(IP5_3_0, MSIOF1_RXD),
++ PINMUX_IPSR_GPSR(IP5_3_0, CS0_N),
++
++ PINMUX_IPSR_GPSR(IP5_7_4, VI1_CLKENB),
++ PINMUX_IPSR_GPSR(IP5_7_4, MSIOF1_TXD),
++ PINMUX_IPSR_GPSR(IP5_7_4, D0),
++
++ PINMUX_IPSR_GPSR(IP5_11_8, VI1_HSYNC_N),
++ PINMUX_IPSR_GPSR(IP5_11_8, MSIOF1_SCK),
++ PINMUX_IPSR_GPSR(IP5_11_8, D1),
++
++ PINMUX_IPSR_GPSR(IP5_15_12, VI1_VSYNC_N),
++ PINMUX_IPSR_GPSR(IP5_15_12, MSIOF1_SYNC),
++ PINMUX_IPSR_GPSR(IP5_15_12, D2),
++
++ PINMUX_IPSR_GPSR(IP5_19_16, VI1_DATA0),
++ PINMUX_IPSR_GPSR(IP5_19_16, MSIOF1_SS1),
++ PINMUX_IPSR_GPSR(IP5_19_16, D3),
++ PINMUX_IPSR_GPSR(IP5_19_16, MMC_WP),
++
++ PINMUX_IPSR_GPSR(IP5_23_20, VI1_DATA1),
++ PINMUX_IPSR_GPSR(IP5_23_20, MSIOF1_SS2),
++ PINMUX_IPSR_GPSR(IP5_23_20, D4),
++ PINMUX_IPSR_GPSR(IP5_23_20, MMC_CD),
++
++ PINMUX_IPSR_GPSR(IP5_27_24, VI1_DATA2),
++ PINMUX_IPSR_MSEL(IP5_27_24, CANFD0_TX_B, SEL_CANFD0_1),
++ PINMUX_IPSR_GPSR(IP5_27_24, D5),
++ PINMUX_IPSR_GPSR(IP5_27_24, MMC_DS),
++
++ PINMUX_IPSR_GPSR(IP5_31_28, VI1_DATA3),
++ PINMUX_IPSR_MSEL(IP5_31_28, CANFD0_RX_B, SEL_CANFD0_1),
++ PINMUX_IPSR_GPSR(IP5_31_28, D6),
++ PINMUX_IPSR_GPSR(IP5_31_28, MMC_CMD),
++
++ /* IPSR6 */
++ PINMUX_IPSR_GPSR(IP6_3_0, VI1_DATA4),
++ PINMUX_IPSR_MSEL(IP6_3_0, CANFD_CLK_B, SEL_CANFD0_1),
++ PINMUX_IPSR_GPSR(IP6_3_0, D7),
++ PINMUX_IPSR_GPSR(IP6_3_0, MMC_D0),
++
++ PINMUX_IPSR_GPSR(IP6_7_4, VI1_DATA5),
++ PINMUX_IPSR_GPSR(IP6_7_4, D8),
++ PINMUX_IPSR_GPSR(IP6_7_4, MMC_D1),
++
++ PINMUX_IPSR_GPSR(IP6_11_8, VI1_DATA6),
++ PINMUX_IPSR_GPSR(IP6_11_8, D9),
++ PINMUX_IPSR_GPSR(IP6_11_8, MMC_D2),
++
++ PINMUX_IPSR_GPSR(IP6_15_12, VI1_DATA7),
++ PINMUX_IPSR_GPSR(IP6_15_12, D10),
++ PINMUX_IPSR_GPSR(IP6_15_12, MMC_D3),
++
++ PINMUX_IPSR_GPSR(IP6_19_16, VI1_DATA8),
++ PINMUX_IPSR_GPSR(IP6_19_16, D11),
++ PINMUX_IPSR_GPSR(IP6_19_16, MMC_CLK),
++
++ PINMUX_IPSR_GPSR(IP6_23_20, VI1_DATA9),
++ PINMUX_IPSR_MSEL(IP6_23_20, TCLK1_A, SEL_TMU1_0),
++ PINMUX_IPSR_GPSR(IP6_23_20, D12),
++ PINMUX_IPSR_GPSR(IP6_23_20, MMC_D4),
++
++ PINMUX_IPSR_GPSR(IP6_27_24, VI1_DATA10),
++ PINMUX_IPSR_MSEL(IP6_27_24, TCLK2_A, SEL_TMU1_0),
++ PINMUX_IPSR_GPSR(IP6_27_24, D13),
++ PINMUX_IPSR_GPSR(IP6_27_24, MMC_D5),
++
++ PINMUX_IPSR_GPSR(IP6_31_28, VI1_DATA11),
++ PINMUX_IPSR_GPSR(IP6_31_28, SCL4),
++ PINMUX_IPSR_GPSR(IP6_31_28, D14),
++ PINMUX_IPSR_GPSR(IP6_31_28, MMC_D6),
++
++ /* IPSR7 */
++ PINMUX_IPSR_GPSR(IP7_3_0, VI1_FIELD),
++ PINMUX_IPSR_GPSR(IP7_3_0, SDA4),
++ PINMUX_IPSR_GPSR(IP7_3_0, D15),
++ PINMUX_IPSR_GPSR(IP7_3_0, MMC_D7),
++
++ PINMUX_IPSR_GPSR(IP7_7_4, SCL0),
++ PINMUX_IPSR_GPSR(IP7_7_4, CLKOUT),
++
++ PINMUX_IPSR_GPSR(IP7_11_8, SDA0),
++ PINMUX_IPSR_GPSR(IP7_11_8, BS_N),
++ PINMUX_IPSR_GPSR(IP7_11_8, SCK0),
++ PINMUX_IPSR_MSEL(IP7_11_8, HSCK0_B, SEL_HSCIF0_1),
++
++ PINMUX_IPSR_GPSR(IP7_15_12, SCL1),
++ PINMUX_IPSR_GPSR(IP7_15_12, TPU0TO2),
++ PINMUX_IPSR_GPSR(IP7_15_12, RD_N),
++ PINMUX_IPSR_GPSR(IP7_15_12, CTS0_N),
++ PINMUX_IPSR_GPSR(IP7_15_12, HCTS0_N_B),
++
++ PINMUX_IPSR_GPSR(IP7_19_16, SDA1),
++ PINMUX_IPSR_GPSR(IP7_19_16, TPU0TO3),
++ PINMUX_IPSR_GPSR(IP7_19_16, WE0_N),
++ PINMUX_IPSR_GPSR(IP7_19_16, RTS0_N_TANS),
++ PINMUX_IPSR_GPSR(IP7_19_16, HRTS0_N_B),
++
++ PINMUX_IPSR_GPSR(IP7_23_20, SCL2),
++ PINMUX_IPSR_GPSR(IP7_23_20, WE1_N),
++ PINMUX_IPSR_GPSR(IP7_23_20, RX0),
++ PINMUX_IPSR_MSEL(IP7_23_20, HRX0_B, SEL_HSCIF0_1),
++
++ PINMUX_IPSR_GPSR(IP7_27_24, SDA2),
++ PINMUX_IPSR_GPSR(IP7_27_24, EX_WAIT0),
++ PINMUX_IPSR_GPSR(IP7_27_24, TX0),
++ PINMUX_IPSR_MSEL(IP7_27_24, HTX0_B, SEL_HSCIF0_1),
++
++ PINMUX_IPSR_GPSR(IP7_31_28, AVB_AVTP_MATCH),
++ PINMUX_IPSR_GPSR(IP7_31_28, TPU0TO0),
++
++ /* IPSR8 */
++ PINMUX_IPSR_GPSR(IP8_3_0, AVB_AVTP_CAPTURE),
++ PINMUX_IPSR_GPSR(IP8_3_0, TPU0TO1),
++
++ PINMUX_IPSR_MSEL(IP8_7_4, CANFD0_TX_A, SEL_CANFD0_0),
++ PINMUX_IPSR_GPSR(IP8_7_4, FXR_TXDA),
++ PINMUX_IPSR_MSEL(IP8_7_4, PWM0_B, SEL_PWM0_1),
++ PINMUX_IPSR_GPSR(IP8_7_4, DU_DISP),
++
++ PINMUX_IPSR_MSEL(IP8_11_8, CANFD0_RX_A, SEL_CANFD0_0),
++ PINMUX_IPSR_GPSR(IP8_11_8, RXDA_EXTFXR),
++ PINMUX_IPSR_MSEL(IP8_11_8, PWM1_B, SEL_PWM1_1),
++ PINMUX_IPSR_GPSR(IP8_11_8, DU_CDE),
++
++ PINMUX_IPSR_GPSR(IP8_15_12, CANFD1_TX),
++ PINMUX_IPSR_GPSR(IP8_15_12, FXR_TXDB),
++ PINMUX_IPSR_MSEL(IP8_15_12, PWM2_B, SEL_PWM2_1),
++ PINMUX_IPSR_MSEL(IP8_15_12, TCLK1_B, SEL_TMU1_1),
++ PINMUX_IPSR_MSEL(IP8_15_12, TX1_B, SEL_SCIF1_1),
++
++ PINMUX_IPSR_GPSR(IP8_19_16, CANFD1_RX),
++ PINMUX_IPSR_GPSR(IP8_19_16, RXDB_EXTFXR),
++ PINMUX_IPSR_MSEL(IP8_19_16, PWM3_B, SEL_PWM3_1),
++ PINMUX_IPSR_MSEL(IP8_19_16, TCLK2_B, SEL_TMU1_1),
++ PINMUX_IPSR_MSEL(IP8_19_16, RX1_B, SEL_SCIF1_1),
++
++ PINMUX_IPSR_MSEL(IP8_23_20, CANFD_CLK_A, SEL_CANFD0_0),
++ PINMUX_IPSR_GPSR(IP8_23_20, CLK_EXTFXR),
++ PINMUX_IPSR_MSEL(IP8_23_20, PWM4_B, SEL_PWM4_1),
++ PINMUX_IPSR_MSEL(IP8_23_20, SPEEDIN_B, SEL_RSP_1),
++ PINMUX_IPSR_MSEL(IP8_23_20, SCIF_CLK_B, SEL_HSCIF0_1),
++
++ PINMUX_IPSR_GPSR(IP8_27_24, DIGRF_CLKIN),
++ PINMUX_IPSR_GPSR(IP8_27_24, DIGRF_CLKEN_IN),
++
++ PINMUX_IPSR_GPSR(IP8_31_28, DIGRF_CLKOUT),
++ PINMUX_IPSR_GPSR(IP8_31_28, DIGRF_CLKEN_OUT),
++
++ /* IPSR9 */
++ PINMUX_IPSR_GPSR(IP9_3_0, IRQ4),
++ PINMUX_IPSR_GPSR(IP9_3_0, VI0_DATA12),
++
++ PINMUX_IPSR_GPSR(IP9_7_4, IRQ5),
++ PINMUX_IPSR_GPSR(IP9_7_4, VI0_DATA13),
++
++ PINMUX_IPSR_GPSR(IP9_11_8, MSIOF0_RXD),
++ PINMUX_IPSR_GPSR(IP9_11_8, DU_DR0),
++ PINMUX_IPSR_GPSR(IP9_11_8, VI0_DATA14),
++
++ PINMUX_IPSR_GPSR(IP9_15_12, MSIOF0_TXD),
++ PINMUX_IPSR_GPSR(IP9_15_12, DU_DR1),
++ PINMUX_IPSR_GPSR(IP9_15_12, VI0_DATA15),
++
++ PINMUX_IPSR_GPSR(IP9_19_16, MSIOF0_SCK),
++ PINMUX_IPSR_GPSR(IP9_19_16, DU_DG0),
++ PINMUX_IPSR_GPSR(IP9_19_16, VI0_DATA16),
++
++ PINMUX_IPSR_GPSR(IP9_23_20, MSIOF0_SYNC),
++ PINMUX_IPSR_GPSR(IP9_23_20, DU_DG1),
++ PINMUX_IPSR_GPSR(IP9_23_20, VI0_DATA17),
++
++ PINMUX_IPSR_GPSR(IP9_27_24, MSIOF0_SS1),
++ PINMUX_IPSR_GPSR(IP9_27_24, DU_DB0),
++ PINMUX_IPSR_GPSR(IP9_27_24, TCLK3),
++ PINMUX_IPSR_GPSR(IP9_27_24, VI0_DATA18),
++
++ PINMUX_IPSR_GPSR(IP9_31_28, MSIOF0_SS2),
++ PINMUX_IPSR_GPSR(IP9_31_28, DU_DB1),
++ PINMUX_IPSR_GPSR(IP9_31_28, TCLK4),
++ PINMUX_IPSR_GPSR(IP9_31_28, VI0_DATA19),
++
++ /* IPSR10 */
++ PINMUX_IPSR_GPSR(IP10_3_0, SCL3),
++ PINMUX_IPSR_GPSR(IP10_3_0, VI0_DATA20),
++
++ PINMUX_IPSR_GPSR(IP10_7_4, SDA3),
++ PINMUX_IPSR_GPSR(IP10_7_4, VI0_DATA21),
++
++ PINMUX_IPSR_GPSR(IP10_11_8, FSO_CFE_0_N),
++ PINMUX_IPSR_GPSR(IP10_11_8, VI0_DATA22),
++
++ PINMUX_IPSR_GPSR(IP10_15_12, FSO_CFE_1_N),
++ PINMUX_IPSR_GPSR(IP10_15_12, VI0_DATA23),
++
++ PINMUX_IPSR_GPSR(IP10_19_16, FSO_TOE_N),
++};
++
++static const struct sh_pfc_pin pinmux_pins[] = {
++ PINMUX_GPIO_GP_ALL(),
++};
++
++/* - EtherAVB --------------------------------------------------------------- */
++static const unsigned int avb_rx_ctrl_pins[] = {
++ /* AVB_RX_CTL */
++ RCAR_GP_PIN(1, 1),
++};
++static const unsigned int avb_rx_ctrl_mux[] = {
++ AVB_RX_CTL_MARK,
++};
++static const unsigned int avb_rxc_pins[] = {
++ /* AVB_RXC */
++ RCAR_GP_PIN(1, 2),
++};
++static const unsigned int avb_rxc_mux[] = {
++ AVB_RXC_MARK,
++};
++static const unsigned int avb_rd0_pins[] = {
++ /* AVB_RD[0] */
++ RCAR_GP_PIN(1, 3),
++};
++static const unsigned int avb_rd0_mux[] = {
++ AVB_RD0_MARK,
++};
++static const unsigned int avb_rd1_pins[] = {
++ /* AVB_RD[1] */
++ RCAR_GP_PIN(1, 4),
++};
++static const unsigned int avb_rd1_mux[] = {
++ AVB_RD1_MARK,
++};
++static const unsigned int avb_rd2_pins[] = {
++ /* AVB_RD[2] */
++ RCAR_GP_PIN(1, 5),
++};
++static const unsigned int avb_rd2_mux[] = {
++ AVB_RD2_MARK,
++};
++static const unsigned int avb_rd3_pins[] = {
++ /* AVB_RD[3] */
++ RCAR_GP_PIN(1, 6),
++};
++static const unsigned int avb_rd3_mux[] = {
++ AVB_RD3_MARK,
++};
++static const unsigned int avb_rd4_pins[] = {
++ /* AVB_RD[3:0] */
++ RCAR_GP_PIN(1, 3), RCAR_GP_PIN(1, 4),
++ RCAR_GP_PIN(1, 5), RCAR_GP_PIN(1, 6),
++};
++static const unsigned int avb_rd4_mux[] = {
++ AVB_RD0_MARK, AVB_RD1_MARK,
++ AVB_RD2_MARK, AVB_RD3_MARK,
++};
++static const unsigned int avb_tx_ctrl_pins[] = {
++ /* AVB_TX_CTL */
++ RCAR_GP_PIN(1, 7),
++};
++static const unsigned int avb_tx_ctrl_mux[] = {
++ AVB_TX_CTL_MARK,
++};
++static const unsigned int avb_txc_pins[] = {
++ /* AVB_TXC */
++ RCAR_GP_PIN(1, 8),
++};
++static const unsigned int avb_txc_mux[] = {
++ AVB_TXC_MARK,
++};
++static const unsigned int avb_td0_pins[] = {
++ /* AVB_TD[0] */
++ RCAR_GP_PIN(1, 9),
++};
++static const unsigned int avb_td0_mux[] = {
++ AVB_TD0_MARK,
++};
++static const unsigned int avb_td1_pins[] = {
++ /* AVB_TD[1] */
++ RCAR_GP_PIN(1, 10),
++};
++static const unsigned int avb_td1_mux[] = {
++ AVB_TD1_MARK,
++};
++static const unsigned int avb_td2_pins[] = {
++ /* AVB_TD[2] */
++ RCAR_GP_PIN(1, 11),
++};
++static const unsigned int avb_td2_mux[] = {
++ AVB_TD2_MARK,
++};
++static const unsigned int avb_td3_pins[] = {
++ /* AVB_TD[3] */
++ RCAR_GP_PIN(1, 12),
++};
++static const unsigned int avb_td3_mux[] = {
++ AVB_TD3_MARK,
++};
++static const unsigned int avb_td4_pins[] = {
++ /* AVB_TD[3:0] */
++ RCAR_GP_PIN(1, 9), RCAR_GP_PIN(1, 10),
++ RCAR_GP_PIN(1, 11), RCAR_GP_PIN(1, 12),
++};
++static const unsigned int avb_td4_mux[] = {
++ AVB_TD0_MARK, AVB_TD1_MARK,
++ AVB_TD2_MARK, AVB_TD3_MARK,
++};
++static const unsigned int avb_txcrefclk_pins[] = {
++ /* AVB_TXCREFCLK */
++ RCAR_GP_PIN(1, 13),
++};
++static const unsigned int avb_txcrefclk_mux[] = {
++ AVB_TXCREFCLK_MARK,
++};
++static const unsigned int avb_mdio_pins[] = {
++ /* AVB_MDIO */
++ RCAR_GP_PIN(1, 14),
++};
++static const unsigned int avb_mdio_mux[] = {
++ AVB_MDIO_MARK,
++};
++static const unsigned int avb_mdc_pins[] = {
++ /* AVB_MDC */
++ RCAR_GP_PIN(1, 15),
++};
++static const unsigned int avb_mdc_mux[] = {
++ AVB_MDC_MARK,
++};
++static const unsigned int avb_magic_pins[] = {
++ /* AVB_MAGIC */
++ RCAR_GP_PIN(1, 16),
++};
++static const unsigned int avb_magic_mux[] = {
++ AVB_MAGIC_MARK,
++};
++static const unsigned int avb_phy_int_pins[] = {
++ /* AVB_PHY_INT */
++ RCAR_GP_PIN(1, 17),
++};
++static const unsigned int avb_phy_int_mux[] = {
++ AVB_PHY_INT_MARK,
++};
++static const unsigned int avb_link_pins[] = {
++ /* AVB_LINK */
++ RCAR_GP_PIN(1, 18),
++};
++static const unsigned int avb_link_mux[] = {
++ AVB_LINK_MARK,
++};
++static const unsigned int avb_avtp_match_pins[] = {
++ /* AVB_AVTP_MATCH */
++ RCAR_GP_PIN(1, 19),
++};
++static const unsigned int avb_avtp_match_mux[] = {
++ AVB_AVTP_MATCH_MARK,
++};
++static const unsigned int avb_avtp_capture_pins[] = {
++ /* AVB_AVTP_CAPTURE */
++ RCAR_GP_PIN(1, 20),
++};
++static const unsigned int avb_avtp_capture_mux[] = {
++ AVB_AVTP_CAPTURE_MARK,
++};
++static const unsigned int avb_avtp_pps_pins[] = {
++ /* AVB_AVTP_PPS */
++ RCAR_GP_PIN(2, 6),
++};
++static const unsigned int avb_avtp_pps_mux[] = {
++ AVB_AVTP_PPS_MARK,
++};
++
++/* - GETHER ----------------------------------------------------------------- */
++static const unsigned int gether_rx_ctrl_pins[] = {
++ /* GETHER_RX_CTL */
++ RCAR_GP_PIN(4, 6),
++};
++static const unsigned int gether_rx_ctrl_mux[] = {
++ GETHER_RX_CTL_MARK,
++};
++static const unsigned int gether_rxc_pins[] = {
++ /* GETHER_RXC */
++ RCAR_GP_PIN(4, 7),
++};
++static const unsigned int gether_rxc_mux[] = {
++ GETHER_RXC_MARK,
++};
++static const unsigned int gether_rd0_pins[] = {
++ /* GETHER_RD[0] */
++ RCAR_GP_PIN(4, 8),
++};
++static const unsigned int gether_rd0_mux[] = {
++ GETHER_RD0_MARK,
++};
++static const unsigned int gether_rd1_pins[] = {
++ /* GETHER_RD[1] */
++ RCAR_GP_PIN(4, 9),
++};
++static const unsigned int gether_rd1_mux[] = {
++ GETHER_RD1_MARK,
++};
++static const unsigned int gether_rd2_pins[] = {
++ /* GETHER_RD[2] */
++ RCAR_GP_PIN(4, 10),
++};
++static const unsigned int gether_rd2_mux[] = {
++ GETHER_RD2_MARK,
++};
++static const unsigned int gether_rd3_pins[] = {
++ /* GETHER_RD[3] */
++ RCAR_GP_PIN(4, 11),
++};
++static const unsigned int gether_rd3_mux[] = {
++ GETHER_RD3_MARK,
++};
++static const unsigned int gether_rd4_pins[] = {
++ /* GETHER_RD[3:0] */
++ RCAR_GP_PIN(4, 8), RCAR_GP_PIN(4, 9),
++ RCAR_GP_PIN(4, 10), RCAR_GP_PIN(4, 11),
++};
++static const unsigned int gether_rd4_mux[] = {
++ GETHER_RD0_MARK, AVB_RD1_MARK,
++ GETHER_RD2_MARK, AVB_RD3_MARK,
++};
++static const unsigned int gether_tx_ctrl_pins[] = {
++ /* GETHER_TX_CTL */
++ RCAR_GP_PIN(4, 12),
++};
++static const unsigned int gether_tx_ctrl_mux[] = {
++ GETHER_TX_CTL_MARK,
++};
++static const unsigned int gether_txc_pins[] = {
++ /* GETHER_TXC */
++ RCAR_GP_PIN(4, 13),
++};
++static const unsigned int gether_txc_mux[] = {
++ GETHER_TXC_MARK,
++};
++static const unsigned int gether_td0_pins[] = {
++ /* GETHER_TD[0] */
++ RCAR_GP_PIN(4, 14),
++};
++static const unsigned int gether_td0_mux[] = {
++ GETHER_TD0_MARK,
++};
++static const unsigned int gether_td1_pins[] = {
++ /* GETHER_TD[1] */
++ RCAR_GP_PIN(4, 15),
++};
++static const unsigned int gether_td1_mux[] = {
++ GETHER_TD1_MARK,
++};
++static const unsigned int gether_td2_pins[] = {
++ /* GETHER_TD[2] */
++ RCAR_GP_PIN(4, 16),
++};
++static const unsigned int gether_td2_mux[] = {
++ GETHER_TD2_MARK,
++};
++static const unsigned int gether_td3_pins[] = {
++ /* GETHER_TD[3] */
++ RCAR_GP_PIN(4, 17),
++};
++static const unsigned int gether_td3_mux[] = {
++ GETHER_TD3_MARK,
++};
++static const unsigned int gether_td4_pins[] = {
++ /* GETHER_TD[3:0] */
++ RCAR_GP_PIN(4, 14), RCAR_GP_PIN(4, 15),
++ RCAR_GP_PIN(4, 16), RCAR_GP_PIN(1, 17),
++};
++static const unsigned int gether_td4_mux[] = {
++ GETHER_TD0_MARK, GETHER_TD1_MARK,
++ GETHER_TD2_MARK, GETHER_TD3_MARK,
++};
++static const unsigned int gether_txcrefclk_pins[] = {
++ /* GETHER_TXCREFCLK */
++ RCAR_GP_PIN(4, 18),
++};
++static const unsigned int gether_txcrefclk_mux[] = {
++ GETHER_TXCREFCLK_MARK,
++};
++static const unsigned int gether_txcrefclk_mega_pins[] = {
++ /* GETHER_TXCREFCLK_MEGA */
++ RCAR_GP_PIN(4, 19),
++};
++static const unsigned int gether_txcrefclk_mega_mux[] = {
++ GETHER_TXCREFCLK_MEGA_MARK,
++};
++static const unsigned int gether_mdio_a_pins[] = {
++ /* GETHER_MDIO_A */
++ RCAR_GP_PIN(4, 20),
++};
++static const unsigned int gether_mdio_a_mux[] = {
++ GETHER_MDIO_A_MARK,
++};
++static const unsigned int gether_mdc_a_pins[] = {
++ /* GETHER_MDC_A */
++ RCAR_GP_PIN(4, 21),
++};
++static const unsigned int gether_mdc_a_mux[] = {
++ GETHER_MDC_A_MARK,
++};
++static const unsigned int gether_magic_pins[] = {
++ /* GETHER_MAGIC */
++ RCAR_GP_PIN(4, 22),
++};
++static const unsigned int gether_magic_mux[] = {
++ GETHER_MAGIC_MARK,
++};
++static const unsigned int gether_phy_int_a_pins[] = {
++ /* GETHER_PHY_INT_A */
++ RCAR_GP_PIN(4, 23),
++};
++static const unsigned int gether_phy_int_a_mux[] = {
++ GETHER_PHY_INT_A_MARK,
++};
++static const unsigned int gether_link_a_pins[] = {
++ /* GETHER_LINK_A */
++ RCAR_GP_PIN(4, 24),
++};
++static const unsigned int gether_link_a_mux[] = {
++ GETHER_LINK_A_MARK,
++};
++
++static const unsigned int gether_mdio_b_pins[] = {
++ /* GETHER_MDIO_B */
++ RCAR_GP_PIN(0, 10),
++};
++static const unsigned int gether_mdio_b_mux[] = {
++ GETHER_MDIO_B_MARK,
++};
++static const unsigned int gether_mdc_b_pins[] = {
++ /* GETHER_MDC_B */
++ RCAR_GP_PIN(0, 9),
++};
++static const unsigned int gether_mdc_b_mux[] = {
++ GETHER_MDC_B_MARK,
++};
++static const unsigned int gether_phy_int_b_pins[] = {
++ /* GETHER_PHY_INT_B */
++ RCAR_GP_PIN(0, 19),
++};
++static const unsigned int gether_phy_int_b_mux[] = {
++ GETHER_PHY_INT_B_MARK,
++};
++static const unsigned int gether_link_b_pins[] = {
++ /* GETHER_LINK_B */
++ RCAR_GP_PIN(0, 18),
++};
++static const unsigned int gether_link_b_mux[] = {
++ GETHER_LINK_B_MARK,
++};
++
++/* OK? */
++static const unsigned int gether_rmii_pins[] = {
++ /* GETHER_RMII_CRS_DV GETHER_RMII_RX_ER GETHER_RMII_RXD0 GETHER_RMII_RXD1 */
++ /* GETHER_RMII_TXD_EN GETHER_RMII_TXD0 GETHER_RMII_TXD1 GETHER_RMII_REFCLK */
++ RCAR_GP_PIN(0, 0), RCAR_GP_PIN(0, 1),
++ RCAR_GP_PIN(0, 2), RCAR_GP_PIN(0, 3),
++ RCAR_GP_PIN(0, 4), RCAR_GP_PIN(0, 5),
++ RCAR_GP_PIN(0, 6), RCAR_GP_PIN(0, 7),
++};
++static const unsigned int gether_rmii_mux[] = {
++ GETHER_RMII_CRS_DV_MARK, GETHER_RMII_RX_ER_MARK,
++ GETHER_RMII_RXD0_MARK, GETHER_RMII_RXD1_MARK,
++ GETHER_RMII_TXD_EN_MARK, GETHER_RMII_TXD0_MARK,
++ GETHER_RMII_TXD1_MARK, GETHER_RMII_REFCLK_MARK,
++};
++
++/* - CANFD0 ----------------------------------------------------------------- */
++static const unsigned int canfd0_data_a_pins[] = {
++ /* TX, RX */
++ RCAR_GP_PIN(1, 21), RCAR_GP_PIN(1, 22),
++};
++static const unsigned int canfd0_data_a_mux[] = {
++ CANFD0_TX_A_MARK, CANFD0_RX_A_MARK,
++};
++static const unsigned int canfd_clk_a_pins[] = {
++ /* CLK */
++ RCAR_GP_PIN(1, 25),
++};
++static const unsigned int canfd_clk_a_mux[] = {
++ CANFD_CLK_A_MARK,
++};
++static const unsigned int canfd0_data_b_pins[] = {
++ /* TX, RX */
++ RCAR_GP_PIN(3, 6), RCAR_GP_PIN(3, 7),
++};
++static const unsigned int canfd0_data_b_mux[] = {
++ CANFD0_TX_B_MARK, CANFD0_RX_B_MARK,
++};
++static const unsigned int canfd_clk_b_pins[] = {
++ /* CLK */
++ RCAR_GP_PIN(3, 8),
++};
++static const unsigned int canfd_clk_b_mux[] = {
++ CANFD_CLK_B_MARK,
++};
++
++/* - CANFD1 ----------------------------------------------------------------- */
++static const unsigned int canfd1_data_pins[] = {
++ /* TX, RX */
++ RCAR_GP_PIN(1, 23), RCAR_GP_PIN(1, 24),
++};
++static const unsigned int canfd1_data_mux[] = {
++ CANFD1_TX_MARK, CANFD1_RX_MARK,
++};
++
++/* - DU --------------------------------------------------------------------- */
++/* D_[1:0] ??? */
++static const unsigned int du_rgb666_pins[] = {
++ /* R[7:0] */
++ RCAR_GP_PIN(0, 5), RCAR_GP_PIN(0, 4),
++ RCAR_GP_PIN(0, 3), RCAR_GP_PIN(0, 2),
++ RCAR_GP_PIN(0, 1), RCAR_GP_PIN(0, 0),
++ /* G[7:0] */
++ RCAR_GP_PIN(0, 11), RCAR_GP_PIN(0, 10),
++ RCAR_GP_PIN(0, 9), RCAR_GP_PIN(0, 8),
++ RCAR_GP_PIN(0, 7), RCAR_GP_PIN(0, 6),
++ /* B[7:0] */
++ RCAR_GP_PIN(0, 17), RCAR_GP_PIN(0, 16),
++ RCAR_GP_PIN(0, 15), RCAR_GP_PIN(0, 14),
++ RCAR_GP_PIN(0, 13), RCAR_GP_PIN(0, 12),
++};
++static const unsigned int du_rgb666_mux[] = {
++ DU_DR7_MARK, DU_DR6_MARK,
++ DU_DR5_MARK, DU_DR4_MARK,
++ DU_DR3_MARK, DU_DR2_MARK,
++ DU_DG7_MARK, DU_DG6_MARK,
++ DU_DG5_MARK, DU_DG4_MARK,
++ DU_DG3_MARK, DU_DG2_MARK,
++ DU_DB7_MARK, DU_DB6_MARK,
++ DU_DB5_MARK, DU_DB4_MARK,
++ DU_DB3_MARK, DU_DB2_MARK,
++};
++static const unsigned int du_clk_out_0_pins[] = {
++ /* CLKOUT0 */
++ RCAR_GP_PIN(0, 18),
++};
++static const unsigned int du_clk_out_0_mux[] = {
++ DU_DOTCLKOUT_MARK,
++};
++static const unsigned int du_clk_out_1_pins[] = {
++ /* CLKOUT1 */
++ RCAR_GP_PIN(0, 18), /* @@ */
++};
++static const unsigned int du_clk_out_1_mux[] = {
++ DU_DOTCLKOUT_MARK,
++};
++static const unsigned int du_sync_pins[] = {
++ /* EXVSYNC/VSYNC, EXHSYNC/HSYNC */
++ RCAR_GP_PIN(0, 20), RCAR_GP_PIN(0, 19),
++};
++static const unsigned int du_sync_mux[] = {
++ DU_EXVSYNC_DU_VSYNC_MARK, DU_EXHSYNC_DU_HSYNC_MARK,
++};
++static const unsigned int du_oddf_pins[] = {
++ /* EXDISP/EXODDF/EXCDE */
++ RCAR_GP_PIN(0, 21),
++};
++static const unsigned int du_oddf_mux[] = {
++ DU_EXODDF_DU_ODDF_DISP_CDE_MARK,
++};
++static const unsigned int du_cde_pins[] = {
++ /* CDE */
++ RCAR_GP_PIN(1, 22),
++};
++static const unsigned int du_cde_mux[] = {
++ DU_CDE_MARK,
++};
++static const unsigned int du_disp_pins[] = {
++ /* DISP */
++ RCAR_GP_PIN(1, 21),
++};
++static const unsigned int du_disp_mux[] = {
++ DU_DISP_MARK,
++};
++
++/* - HSCIF0 ----------------------------------------------------------------- */
++static const unsigned int hscif0_data_a_pins[] = {
++ /* HRX0_A, HTX0_A */
++ RCAR_GP_PIN(0, 11), RCAR_GP_PIN(0, 15),
++};
++static const unsigned int hscif0_data_a_mux[] = {
++ HRX0_A_MARK, HTX0_A_MARK,
++};
++static const unsigned int hscif0_clk_a_pins[] = {
++ /* HSCK0_A */
++ RCAR_GP_PIN(0, 12),
++};
++static const unsigned int hscif0_clk_a_mux[] = {
++ HSCK0_A_MARK,
++};
++static const unsigned int hscif0_ctrl_a_pins[] = {
++ /* HRTS0#_A, HCTS0#_A */
++ RCAR_GP_PIN(0, 13), RCAR_GP_PIN(0, 14),
++};
++static const unsigned int hscif0_ctrl_a_mux[] = {
++ HRTS0_N_A_MARK, HCTS0_N_A_MARK,
++};
++
++static const unsigned int hscif0_data_b_pins[] = {
++ /* HRX0_B, HTX0_B */
++ RCAR_GP_PIN(0, 11), RCAR_GP_PIN(0, 15),
++};
++static const unsigned int hscif0_data_b_mux[] = {
++ HRX0_B_MARK, HTX0_B_MARK,
++};
++static const unsigned int hscif0_clk_b_pins[] = {
++ /* HSCK0_B */
++ RCAR_GP_PIN(0, 12),
++};
++static const unsigned int hscif0_clk_b_mux[] = {
++ HSCK0_B_MARK,
++};
++static const unsigned int hscif0_ctrl_b_pins[] = {
++ /* HRTS0#_B, HCTS0#_B */
++ RCAR_GP_PIN(0, 13), RCAR_GP_PIN(0, 14),
++};
++static const unsigned int hscif0_ctrl_b_mux[] = {
++ HRTS0_N_B_MARK, HCTS0_N_B_MARK,
++};
++
++/* - HSCIF1 ----------------------------------------------------------------- */
++static const unsigned int hscif1_data_pins[] = {
++ /* HRX1, HTX1 */
++ RCAR_GP_PIN(2, 11), RCAR_GP_PIN(2, 10),
++};
++static const unsigned int hscif1_data_mux[] = {
++ HRX1_MARK, HTX1_MARK,
++};
++static const unsigned int hscif1_clk_pins[] = {
++ /* HSCK1 */
++ RCAR_GP_PIN(2, 7),
++};
++static const unsigned int hscif1_clk_mux[] = {
++ HSCK1_MARK,
++};
++static const unsigned int hscif1_ctrl_pins[] = {
++ /* HRTS1#, HCTS1# */
++ RCAR_GP_PIN(2, 8), RCAR_GP_PIN(2, 9),
++};
++static const unsigned int hscif1_ctrl_mux[] = {
++ HRTS1_N_MARK, HCTS1_N_MARK,
++};
++
++/* - HSCIF2 ----------------------------------------------------------------- */
++static const unsigned int hscif2_data_pins[] = {
++ /* HRX2, HTX2 */
++ RCAR_GP_PIN(2, 16), RCAR_GP_PIN(2, 15),
++};
++static const unsigned int hscif2_data_mux[] = {
++ HRX2_MARK, HTX2_MARK,
++};
++static const unsigned int hscif2_clk_pins[] = {
++ /* HSCK2 */
++ RCAR_GP_PIN(2, 12),
++};
++static const unsigned int hscif2_clk_mux[] = {
++ HSCK2_MARK,
++};
++static const unsigned int hscif2_ctrl_pins[] = {
++ /* HRTS2#, HCTS2# */
++ RCAR_GP_PIN(2, 14), RCAR_GP_PIN(2, 13),
++};
++static const unsigned int hscif2_ctrl_mux[] = {
++ HRTS2_N_MARK, HCTS2_N_MARK,
++};
++
++/* - HSCIF3 ----------------------------------------------------------------- */
++static const unsigned int hscif3_data_pins[] = {
++ /* HRX3, HTX3 */
++ RCAR_GP_PIN(2, 4), RCAR_GP_PIN(2, 3),
++};
++static const unsigned int hscif3_data_mux[] = {
++ HRX3_MARK, HTX3_MARK,
++};
++static const unsigned int hscif3_clk_pins[] = {
++ /* HSCK3 */
++ RCAR_GP_PIN(2, 0),
++};
++static const unsigned int hscif3_clk_mux[] = {
++ HSCK3_MARK,
++};
++static const unsigned int hscif3_ctrl_pins[] = {
++ /* HRTS3#, HCTS3# */
++ RCAR_GP_PIN(2, 2), RCAR_GP_PIN(2, 1),
++};
++static const unsigned int hscif3_ctrl_mux[] = {
++ HRTS3_N_MARK, HCTS3_N_MARK,
++};
++
++/* - SCIF Clock ------------------------------------------------------------- */
++static const unsigned int scif_clk_a_pins[] = {
++ /* SCIF_CLK */
++ RCAR_GP_PIN(0, 10),
++};
++static const unsigned int scif_clk_a_mux[] = {
++ SCIF_CLK_A_MARK,
++};
++static const unsigned int scif_clk_b_pins[] = {
++ /* SCIF_CLK */
++ RCAR_GP_PIN(1, 25),
++};
++static const unsigned int scif_clk_b_mux[] = {
++ SCIF_CLK_B_MARK,
++};
++
++/* - I2C -------------------------------------------------------------------- */
++static const unsigned int i2c0_pins[] = {
++ /* SDA0, SCL0 */
++ RCAR_GP_PIN(4, 1), RCAR_GP_PIN(4, 0),
++};
++static const unsigned int i2c0_mux[] = {
++ SDA0_MARK, SCL0_MARK,
++};
++static const unsigned int i2c1_pins[] = {
++ /* SDA1, SCL1 */
++ RCAR_GP_PIN(4, 3), RCAR_GP_PIN(4, 2),
++};
++static const unsigned int i2c1_mux[] = {
++ SDA1_MARK, SCL1_MARK,
++};
++static const unsigned int i2c2_pins[] = {
++ /* SDA2, SCL2 */
++ RCAR_GP_PIN(4, 5), RCAR_GP_PIN(4, 4),
++};
++static const unsigned int i2c2_mux[] = {
++ SDA2_MARK, SCL2_MARK,
++};
++static const unsigned int i2c3_pins[] = {
++ /* SDA3, SCL3 */
++ RCAR_GP_PIN(2, 26), RCAR_GP_PIN(2, 25),
++};
++static const unsigned int i2c3_mux[] = {
++ SDA3_MARK, SCL3_MARK,
++};
++static const unsigned int i2c4_pins[] = {
++ /* SDA4, SCL4 */
++ RCAR_GP_PIN(3, 16), RCAR_GP_PIN(3, 15),
++};
++static const unsigned int i2c4_mux[] = {
++ SDA4_MARK, SCL4_MARK,
++};
++static const unsigned int i2c5_pins[] = {
++ /* SDA5, SCL5 */
++ RCAR_GP_PIN(0, 9), RCAR_GP_PIN(0, 8),
++};
++static const unsigned int i2c5_mux[] = {
++ SDA5_MARK, SCL5_MARK,
++};
++
++/* - INTC-EX ---------------------------------------------------------------- */
++static const unsigned int intc_ex_irq0_pins[] = {
++ /* IRQ0 */
++ RCAR_GP_PIN(1, 0),
++};
++static const unsigned int intc_ex_irq0_mux[] = {
++ IRQ0_MARK,
++};
++static const unsigned int intc_ex_irq1_pins[] = {
++ /* IRQ1 */
++ RCAR_GP_PIN(0, 12),
++};
++static const unsigned int intc_ex_irq1_mux[] = {
++ IRQ1_MARK,
++};
++static const unsigned int intc_ex_irq2_pins[] = {
++ /* IRQ2 */
++ RCAR_GP_PIN(0, 13),
++};
++static const unsigned int intc_ex_irq2_mux[] = {
++ IRQ2_MARK,
++};
++static const unsigned int intc_ex_irq3_pins[] = {
++ /* IRQ3 */
++ RCAR_GP_PIN(0, 14),
++};
++static const unsigned int intc_ex_irq3_mux[] = {
++ IRQ3_MARK,
++};
++static const unsigned int intc_ex_irq4_pins[] = {
++ /* IRQ4 */
++ RCAR_GP_PIN(2, 17),
++};
++static const unsigned int intc_ex_irq4_mux[] = {
++ IRQ4_MARK,
++};
++static const unsigned int intc_ex_irq5_pins[] = {
++ /* IRQ5 */
++ RCAR_GP_PIN(2, 18),
++};
++static const unsigned int intc_ex_irq5_mux[] = {
++ IRQ5_MARK,
++};
++
++/* - MSIOF0 ----------------------------------------------------------------- */
++static const unsigned int msiof0_clk_pins[] = {
++ /* SCK */
++ RCAR_GP_PIN(2, 21),
++};
++static const unsigned int msiof0_clk_mux[] = {
++ MSIOF0_SCK_MARK,
++};
++static const unsigned int msiof0_sync_pins[] = {
++ /* SYNC */
++ RCAR_GP_PIN(2, 22),
++};
++static const unsigned int msiof0_sync_mux[] = {
++ MSIOF0_SYNC_MARK,
++};
++static const unsigned int msiof0_ss1_pins[] = {
++ /* SS1 */
++ RCAR_GP_PIN(2, 23),
++};
++static const unsigned int msiof0_ss1_mux[] = {
++ MSIOF0_SS1_MARK,
++};
++static const unsigned int msiof0_ss2_pins[] = {
++ /* SS2 */
++ RCAR_GP_PIN(2, 24),
++};
++static const unsigned int msiof0_ss2_mux[] = {
++ MSIOF0_SS2_MARK,
++};
++static const unsigned int msiof0_txd_pins[] = {
++ /* TXD */
++ RCAR_GP_PIN(2, 20),
++};
++static const unsigned int msiof0_txd_mux[] = {
++ MSIOF0_TXD_MARK,
++};
++static const unsigned int msiof0_rxd_pins[] = {
++ /* RXD */
++ RCAR_GP_PIN(2, 19),
++};
++static const unsigned int msiof0_rxd_mux[] = {
++ MSIOF0_RXD_MARK,
++};
++
++/* - MSIOF1 ----------------------------------------------------------------- */
++static const unsigned int msiof1_clk_pins[] = {
++ /* SCK */
++ RCAR_GP_PIN(3, 2),
++};
++static const unsigned int msiof1_clk_mux[] = {
++ MSIOF1_SCK_MARK,
++};
++static const unsigned int msiof1_sync_pins[] = {
++ /* SYNC */
++ RCAR_GP_PIN(3, 3),
++};
++static const unsigned int msiof1_sync_mux[] = {
++ MSIOF1_SYNC_MARK,
++};
++static const unsigned int msiof1_ss1_pins[] = {
++ /* SS1 */
++ RCAR_GP_PIN(3, 4),
++};
++static const unsigned int msiof1_ss1_mux[] = {
++ MSIOF1_SS1_MARK,
++};
++static const unsigned int msiof1_ss2_pins[] = {
++ /* SS2 */
++ RCAR_GP_PIN(3, 5),
++};
++static const unsigned int msiof1_ss2_mux[] = {
++ MSIOF1_SS2_MARK,
++};
++static const unsigned int msiof1_txd_pins[] = {
++ /* TXD */
++ RCAR_GP_PIN(3, 1),
++};
++static const unsigned int msiof1_txd_mux[] = {
++ MSIOF1_TXD_MARK,
++};
++static const unsigned int msiof1_rxd_pins[] = {
++ /* RXD */
++ RCAR_GP_PIN(3, 0),
++};
++static const unsigned int msiof1_rxd_mux[] = {
++ MSIOF1_RXD_MARK,
++};
++
++/* - MSIOF2 ----------------------------------------------------------------- */
++static const unsigned int msiof2_clk_pins[] = {
++ /* SCK */
++ RCAR_GP_PIN(2, 0),
++};
++static const unsigned int msiof2_clk_mux[] = {
++ MSIOF2_SCK_MARK,
++};
++static const unsigned int msiof2_sync_pins[] = {
++ /* SYNC */
++ RCAR_GP_PIN(2, 3),
++};
++static const unsigned int msiof2_sync_mux[] = {
++ MSIOF2_SYNC_MARK,
++};
++static const unsigned int msiof2_ss1_pins[] = {
++ /* SS1 */
++ RCAR_GP_PIN(2, 4),
++};
++static const unsigned int msiof2_ss1_mux[] = {
++ MSIOF2_SS1_MARK,
++};
++static const unsigned int msiof2_ss2_pins[] = {
++ /* SS2 */
++ RCAR_GP_PIN(2, 5),
++};
++static const unsigned int msiof2_ss2_mux[] = {
++ MSIOF2_SS2_MARK,
++};
++static const unsigned int msiof2_txd_pins[] = {
++ /* TXD */
++ RCAR_GP_PIN(2, 2),
++};
++static const unsigned int msiof2_txd_mux[] = {
++ MSIOF2_TXD_MARK,
++};
++static const unsigned int msiof2_rxd_pins[] = {
++ /* RXD */
++ RCAR_GP_PIN(2, 1),
++};
++static const unsigned int msiof2_rxd_mux[] = {
++ MSIOF2_RXD_MARK,
++};
++
++/* - MSIOF3 ----------------------------------------------------------------- */
++static const unsigned int msiof3_clk_pins[] = {
++ /* SCK */
++ RCAR_GP_PIN(0, 20),
++};
++static const unsigned int msiof3_clk_mux[] = {
++ MSIOF3_SCK_MARK,
++};
++static const unsigned int msiof3_sync_pins[] = {
++ /* SYNC */
++ RCAR_GP_PIN(0, 21),
++};
++static const unsigned int msiof3_sync_mux[] = {
++ MSIOF3_SYNC_MARK,
++};
++static const unsigned int msiof3_ss1_pins[] = {
++ /* SS1 */
++ RCAR_GP_PIN(0, 18),
++};
++static const unsigned int msiof3_ss1_mux[] = {
++ MSIOF3_SS1_MARK,
++};
++static const unsigned int msiof3_ss2_pins[] = {
++ /* SS2 */
++ RCAR_GP_PIN(0, 19),
++};
++static const unsigned int msiof3_ss2_mux[] = {
++ MSIOF3_SS2_MARK,
++};
++static const unsigned int msiof3_txd_pins[] = {
++ /* TXD */
++ RCAR_GP_PIN(0, 17),
++};
++static const unsigned int msiof3_txd_mux[] = {
++ MSIOF3_TXD_MARK,
++};
++static const unsigned int msiof3_rxd_pins[] = {
++ /* RXD */
++ RCAR_GP_PIN(0, 16),
++};
++static const unsigned int msiof3_rxd_mux[] = {
++ MSIOF3_RXD_MARK,
++};
++
++/* - TPU ------------------------------------------------------------------- */
++static const unsigned int tpu_to0_pins[] = {
++ /* TPU0TO0 */
++ RCAR_GP_PIN(1, 19),
++};
++static const unsigned int tpu_to0_mux[] = {
++ TPU0TO0_MARK,
++};
++static const unsigned int tpu_to1_pins[] = {
++ /* TPU0TO1 */
++ RCAR_GP_PIN(1, 20),
++};
++static const unsigned int tpu_to1_mux[] = {
++ TPU0TO1_MARK,
++};
++static const unsigned int tpu_to2_pins[] = {
++ /* TPU0TO2 */
++ RCAR_GP_PIN(4, 2),
++};
++static const unsigned int tpu_to2_mux[] = {
++ TPU0TO2_MARK,
++};
++static const unsigned int tpu_to3_pins[] = {
++ /* TPU0TO3 */
++ RCAR_GP_PIN(4, 3),
++};
++static const unsigned int tpu_to3_mux[] = {
++ TPU0TO3_MARK,
++};
++
++/* - PWM0 ------------------------------------------------------------------- */
++static const unsigned int pwm0_a_pins[] = {
++ /* PWM0 */
++ RCAR_GP_PIN(0, 15),
++};
++static const unsigned int pwm0_a_mux[] = {
++ PWM0_A_MARK,
++};
++static const unsigned int pwm0_b_pins[] = {
++ /* PWM0 */
++ RCAR_GP_PIN(1, 21),
++};
++static const unsigned int pwm0_b_mux[] = {
++ PWM0_B_MARK,
++};
++
++/* - PWM1 ------------------------------------------------------------------- */
++static const unsigned int pwm1_a_pins[] = {
++ /* PWM1 */
++ RCAR_GP_PIN(2, 13),
++};
++static const unsigned int pwm1_a_mux[] = {
++ PWM1_A_MARK,
++};
++static const unsigned int pwm1_b_pins[] = {
++ /* PWM1 */
++ RCAR_GP_PIN(1, 22),
++};
++static const unsigned int pwm1_b_mux[] = {
++ PWM1_B_MARK,
++};
++
++/* - PWM2 ------------------------------------------------------------------- */
++static const unsigned int pwm2_a_pins[] = {
++ /* PWM2 */
++ RCAR_GP_PIN(2, 14),
++};
++static const unsigned int pwm2_a_mux[] = {
++ PWM2_A_MARK,
++};
++static const unsigned int pwm2_b_pins[] = {
++ /* PWM2 */
++ RCAR_GP_PIN(1, 23),
++};
++static const unsigned int pwm2_b_mux[] = {
++ PWM2_B_MARK,
++};
++
++/* - PWM3 ------------------------------------------------------------------- */
++static const unsigned int pwm3_a_pins[] = {
++ /* PWM3 */
++ RCAR_GP_PIN(2, 15),
++};
++static const unsigned int pwm3_a_mux[] = {
++ PWM3_A_MARK,
++};
++static const unsigned int pwm3_b_pins[] = {
++ /* PWM3 */
++ RCAR_GP_PIN(1, 24),
++};
++static const unsigned int pwm3_b_mux[] = {
++ PWM3_B_MARK,
++};
++
++/* - PWM4 ------------------------------------------------------------------- */
++static const unsigned int pwm4_a_pins[] = {
++ /* PWM4 */
++ RCAR_GP_PIN(2, 16),
++};
++static const unsigned int pwm4_a_mux[] = {
++ PWM4_A_MARK,
++};
++static const unsigned int pwm4_b_pins[] = {
++ /* PWM4 */
++ RCAR_GP_PIN(1, 25),
++};
++static const unsigned int pwm4_b_mux[] = {
++ PWM4_B_MARK,
++};
++
++/* - SCIF0 ------------------------------------------------------------------ */
++static const unsigned int scif0_data_pins[] = {
++ /* RX, TX */
++ RCAR_GP_PIN(4, 4), RCAR_GP_PIN(4, 5),
++};
++static const unsigned int scif0_data_mux[] = {
++ RX0_MARK, TX0_MARK,
++};
++static const unsigned int scif0_clk_pins[] = {
++ /* SCK */
++ RCAR_GP_PIN(4, 1),
++};
++static const unsigned int scif0_clk_mux[] = {
++ SCK0_MARK,
++};
++static const unsigned int scif0_ctrl_pins[] = {
++ /* RTS, CTS */
++ RCAR_GP_PIN(4, 3), RCAR_GP_PIN(4, 2),
++};
++static const unsigned int scif0_ctrl_mux[] = {
++ RTS0_N_TANS_MARK, CTS0_N_MARK,
++};
++
++/* - SCIF1 ------------------------------------------------------------------ */
++static const unsigned int scif1_data_a_pins[] = {
++ /* RX, TX */
++ RCAR_GP_PIN(2, 8), RCAR_GP_PIN(2, 9),
++};
++static const unsigned int scif1_data_a_mux[] = {
++ RX1_A_MARK, TX1_A_MARK,
++};
++static const unsigned int scif1_clk_pins[] = {
++ /* SCK */
++ RCAR_GP_PIN(2, 5),
++};
++static const unsigned int scif1_clk_mux[] = {
++ SCK1_MARK,
++};
++static const unsigned int scif1_ctrl_pins[] = {
++ /* RTS, CTS */
++ RCAR_GP_PIN(2, 11), RCAR_GP_PIN(2, 10),
++};
++static const unsigned int scif1_ctrl_mux[] = {
++ RTS1_N_TANS_MARK, CTS1_N_MARK,
++};
++static const unsigned int scif1_data_b_pins[] = {
++ /* RX, TX */
++ RCAR_GP_PIN(1, 24), RCAR_GP_PIN(1, 23),
++};
++static const unsigned int scif1_data_b_mux[] = {
++ RX1_B_MARK, TX1_B_MARK,
++};
++
++/* - SCIF3 ------------------------------------------------------------------ */
++static const unsigned int scif3_data_pins[] = {
++ /* RX, TX */
++ RCAR_GP_PIN(2, 1), RCAR_GP_PIN(2, 2),
++};
++static const unsigned int scif3_data_mux[] = {
++ RX3_MARK, TX3_MARK,
++};
++static const unsigned int scif3_clk_pins[] = {
++ /* SCK */
++ RCAR_GP_PIN(2, 0),
++};
++static const unsigned int scif3_clk_mux[] = {
++ SCK3_MARK,
++};
++static const unsigned int scif3_ctrl_pins[] = {
++ /* RTS, CTS */
++ RCAR_GP_PIN(2, 4), RCAR_GP_PIN(2, 3),
++};
++static const unsigned int scif3_ctrl_mux[] = {
++ RTS3_N_TANS_MARK, CTS3_N_MARK,
++};
++
++/* - SCIF4 ------------------------------------------------------------------ */
++static const unsigned int scif4_data_pins[] = {
++ /* RX, TX */
++ RCAR_GP_PIN(0, 1), RCAR_GP_PIN(0, 2),
++};
++static const unsigned int scif4_data_mux[] = {
++ RX4_MARK, TX4_MARK,
++};
++static const unsigned int scif4_clk_pins[] = {
++ /* SCK */
++ RCAR_GP_PIN(0, 0),
++};
++static const unsigned int scif4_clk_mux[] = {
++ SCK4_MARK,
++};
++static const unsigned int scif4_ctrl_pins[] = {
++ /* RTS, CTS */
++ RCAR_GP_PIN(0, 4), RCAR_GP_PIN(0, 3),
++};
++static const unsigned int scif4_ctrl_mux[] = {
++ RTS4_N_TANS_MARK, CTS4_N_MARK,
++};
++
++/* - MMC -------------------------------------------------------------------- */
++static const unsigned int mmc_data1_pins[] = {
++ /* D0 */
++ RCAR_GP_PIN(3, 8),
++};
++static const unsigned int mmc_data1_mux[] = {
++ MMC_D0_MARK,
++};
++static const unsigned int mmc_data4_pins[] = {
++ /* D[0:3] */
++ RCAR_GP_PIN(3, 8), RCAR_GP_PIN(3, 9),
++ RCAR_GP_PIN(3, 10), RCAR_GP_PIN(3, 11),
++};
++static const unsigned int mmc_data4_mux[] = {
++ MMC_D0_MARK, MMC_D1_MARK,
++ MMC_D2_MARK, MMC_D3_MARK,
++};
++static const unsigned int mmc_data8_pins[] = {
++ /* D[0:7] */
++ RCAR_GP_PIN(3, 8), RCAR_GP_PIN(3, 9),
++ RCAR_GP_PIN(3, 10), RCAR_GP_PIN(3, 11),
++ RCAR_GP_PIN(3, 13), RCAR_GP_PIN(3, 14),
++ RCAR_GP_PIN(3, 15), RCAR_GP_PIN(3, 16),
++};
++static const unsigned int mmc_data8_mux[] = {
++ MMC_D0_MARK, MMC_D1_MARK,
++ MMC_D2_MARK, MMC_D3_MARK,
++ MMC_D4_MARK, MMC_D5_MARK,
++ MMC_D6_MARK, MMC_D7_MARK,
++};
++static const unsigned int mmc_ctrl_pins[] = {
++ /* CLK, CMD */
++ RCAR_GP_PIN(3, 12), RCAR_GP_PIN(3, 7),
++};
++static const unsigned int mmc_ctrl_mux[] = {
++ MMC_CLK_MARK, MMC_CMD_MARK,
++};
++static const unsigned int mmc_cd_pins[] = {
++ /* CD */
++ RCAR_GP_PIN(3, 5),
++};
++static const unsigned int mmc_cd_mux[] = {
++ MMC_CD_MARK,
++};
++static const unsigned int mmc_wp_pins[] = {
++ /* WP */
++ RCAR_GP_PIN(3, 4),
++};
++static const unsigned int mmc_wp_mux[] = {
++ MMC_WP_MARK,
++};
++static const unsigned int mmc_ds_pins[] = {
++ /* DS */
++ RCAR_GP_PIN(3, 6),
++};
++static const unsigned int mmc_ds_mux[] = {
++ MMC_DS_MARK,
++};
++
++/* - TMU -------------------------------------------------------------------- */
++static const unsigned int tmu_tclk1_a_pins[] = {
++ /* TCLK1 */
++ RCAR_GP_PIN(3, 13),
++};
++static const unsigned int tmu_tclk1_a_mux[] = {
++ TCLK1_A_MARK,
++};
++static const unsigned int tmu_tclk1_b_pins[] = {
++ /* TCLK1 */
++ RCAR_GP_PIN(1, 23),
++};
++static const unsigned int tmu_tclk1_b_mux[] = {
++ TCLK1_B_MARK,
++};
++static const unsigned int tmu_tclk2_a_pins[] = {
++ /* TCLK2 */
++ RCAR_GP_PIN(3, 14),
++};
++static const unsigned int tmu_tclk2_a_mux[] = {
++ TCLK2_A_MARK,
++};
++static const unsigned int tmu_tclk2_b_pins[] = {
++ /* TCLK2 */
++ RCAR_GP_PIN(1, 24),
++};
++static const unsigned int tmu_tclk2_b_mux[] = {
++ TCLK2_B_MARK,
++};
++
++/* - VIN0 ------------------------------------------------------------------- */
++static const unsigned int vin0_data8_pins[] = {
++ RCAR_GP_PIN(2, 4), RCAR_GP_PIN(2, 5),
++ RCAR_GP_PIN(2, 6), RCAR_GP_PIN(2, 7),
++ RCAR_GP_PIN(2, 8), RCAR_GP_PIN(2, 9),
++ RCAR_GP_PIN(2, 10), RCAR_GP_PIN(2, 11),
++};
++static const unsigned int vin0_data8_mux[] = {
++ VI0_DATA0_MARK, VI0_DATA1_MARK,
++ VI0_DATA2_MARK, VI0_DATA3_MARK,
++ VI0_DATA4_MARK, VI0_DATA5_MARK,
++ VI0_DATA6_MARK, VI0_DATA7_MARK,
++};
++static const unsigned int vin0_data10_pins[] = {
++ RCAR_GP_PIN(2, 4), RCAR_GP_PIN(2, 5),
++ RCAR_GP_PIN(2, 6), RCAR_GP_PIN(2, 7),
++ RCAR_GP_PIN(2, 8), RCAR_GP_PIN(2, 9),
++ RCAR_GP_PIN(2, 10), RCAR_GP_PIN(2, 11),
++ RCAR_GP_PIN(2, 12), RCAR_GP_PIN(2, 13),
++};
++static const unsigned int vin0_data10_mux[] = {
++ VI0_DATA0_MARK, VI0_DATA1_MARK,
++ VI0_DATA2_MARK, VI0_DATA3_MARK,
++ VI0_DATA4_MARK, VI0_DATA5_MARK,
++ VI0_DATA6_MARK, VI0_DATA7_MARK,
++ VI0_DATA8_MARK, VI0_DATA9_MARK,
++};
++static const unsigned int vin0_data12_pins[] = {
++ RCAR_GP_PIN(2, 4), RCAR_GP_PIN(2, 5),
++ RCAR_GP_PIN(2, 6), RCAR_GP_PIN(2, 7),
++ RCAR_GP_PIN(2, 8), RCAR_GP_PIN(2, 9),
++ RCAR_GP_PIN(2, 10), RCAR_GP_PIN(2, 11),
++ RCAR_GP_PIN(2, 12), RCAR_GP_PIN(2, 13),
++ RCAR_GP_PIN(2, 14), RCAR_GP_PIN(2, 15),
++};
++static const unsigned int vin0_data12_mux[] = {
++ VI0_DATA0_MARK, VI0_DATA1_MARK,
++ VI0_DATA2_MARK, VI0_DATA3_MARK,
++ VI0_DATA4_MARK, VI0_DATA5_MARK,
++ VI0_DATA6_MARK, VI0_DATA7_MARK,
++ VI0_DATA8_MARK, VI0_DATA9_MARK,
++ VI0_DATA10_MARK, VI0_DATA11_MARK,
++};
++static const unsigned int vin0_data16_pins[] = {
++ RCAR_GP_PIN(2, 4), RCAR_GP_PIN(2, 5),
++ RCAR_GP_PIN(2, 6), RCAR_GP_PIN(2, 7),
++ RCAR_GP_PIN(2, 8), RCAR_GP_PIN(2, 9),
++ RCAR_GP_PIN(2, 10), RCAR_GP_PIN(2, 11),
++ RCAR_GP_PIN(2, 12), RCAR_GP_PIN(2, 13),
++ RCAR_GP_PIN(2, 14), RCAR_GP_PIN(2, 15),
++ RCAR_GP_PIN(2, 17), RCAR_GP_PIN(2, 18),
++ RCAR_GP_PIN(2, 19), RCAR_GP_PIN(2, 20),
++};
++static const unsigned int vin0_data16_mux[] = {
++ VI0_DATA0_MARK, VI0_DATA1_MARK,
++ VI0_DATA2_MARK, VI0_DATA3_MARK,
++ VI0_DATA4_MARK, VI0_DATA5_MARK,
++ VI0_DATA6_MARK, VI0_DATA7_MARK,
++ VI0_DATA8_MARK, VI0_DATA9_MARK,
++ VI0_DATA10_MARK, VI0_DATA11_MARK,
++ VI0_DATA12_MARK, VI0_DATA13_MARK,
++ VI0_DATA14_MARK, VI0_DATA15_MARK,
++};
++static const unsigned int vin0_data20_pins[] = {
++ RCAR_GP_PIN(2, 4), RCAR_GP_PIN(2, 5),
++ RCAR_GP_PIN(2, 6), RCAR_GP_PIN(2, 7),
++ RCAR_GP_PIN(2, 8), RCAR_GP_PIN(2, 9),
++ RCAR_GP_PIN(2, 10), RCAR_GP_PIN(2, 11),
++ RCAR_GP_PIN(2, 12), RCAR_GP_PIN(2, 13),
++ RCAR_GP_PIN(2, 14), RCAR_GP_PIN(2, 15),
++ RCAR_GP_PIN(2, 17), RCAR_GP_PIN(2, 18),
++ RCAR_GP_PIN(2, 19), RCAR_GP_PIN(2, 20),
++ RCAR_GP_PIN(2, 21), RCAR_GP_PIN(2, 22),
++ RCAR_GP_PIN(2, 23), RCAR_GP_PIN(2, 24),
++};
++static const unsigned int vin0_data20_mux[] = {
++ VI0_DATA0_MARK, VI0_DATA1_MARK,
++ VI0_DATA2_MARK, VI0_DATA3_MARK,
++ VI0_DATA4_MARK, VI0_DATA5_MARK,
++ VI0_DATA6_MARK, VI0_DATA7_MARK,
++ VI0_DATA8_MARK, VI0_DATA9_MARK,
++ VI0_DATA10_MARK, VI0_DATA11_MARK,
++ VI0_DATA12_MARK, VI0_DATA13_MARK,
++ VI0_DATA14_MARK, VI0_DATA15_MARK,
++ VI0_DATA16_MARK, VI0_DATA17_MARK,
++ VI0_DATA18_MARK, VI0_DATA19_MARK,
++};
++static const unsigned int vin0_data24_pins[] = {
++ RCAR_GP_PIN(2, 4), RCAR_GP_PIN(2, 5),
++ RCAR_GP_PIN(2, 6), RCAR_GP_PIN(2, 7),
++ RCAR_GP_PIN(2, 8), RCAR_GP_PIN(2, 9),
++ RCAR_GP_PIN(2, 10), RCAR_GP_PIN(2, 11),
++ RCAR_GP_PIN(2, 12), RCAR_GP_PIN(2, 13),
++ RCAR_GP_PIN(2, 14), RCAR_GP_PIN(2, 15),
++ RCAR_GP_PIN(2, 17), RCAR_GP_PIN(2, 18),
++ RCAR_GP_PIN(2, 19), RCAR_GP_PIN(2, 20),
++ RCAR_GP_PIN(2, 21), RCAR_GP_PIN(2, 22),
++ RCAR_GP_PIN(2, 23), RCAR_GP_PIN(2, 24),
++ RCAR_GP_PIN(2, 25), RCAR_GP_PIN(2, 26),
++ RCAR_GP_PIN(2, 27), RCAR_GP_PIN(2, 28),
++};
++static const unsigned int vin0_data24_mux[] = {
++ VI0_DATA0_MARK, VI0_DATA1_MARK,
++ VI0_DATA2_MARK, VI0_DATA3_MARK,
++ VI0_DATA4_MARK, VI0_DATA5_MARK,
++ VI0_DATA6_MARK, VI0_DATA7_MARK,
++ VI0_DATA8_MARK, VI0_DATA9_MARK,
++ VI0_DATA10_MARK, VI0_DATA11_MARK,
++ VI0_DATA12_MARK, VI0_DATA13_MARK,
++ VI0_DATA14_MARK, VI0_DATA15_MARK,
++ VI0_DATA16_MARK, VI0_DATA17_MARK,
++ VI0_DATA18_MARK, VI0_DATA19_MARK,
++ VI0_DATA20_MARK, VI0_DATA21_MARK,
++ VI0_DATA22_MARK, VI0_DATA23_MARK,
++};
++static const unsigned int vin0_sync_pins[] = {
++ /* VSYNC_N, HSYNC_N */
++ RCAR_GP_PIN(2, 3), RCAR_GP_PIN(2, 2),
++};
++static const unsigned int vin0_sync_mux[] = {
++ VI0_HSYNC_N_MARK, VI0_VSYNC_N_MARK,
++};
++static const unsigned int vin0_field_pins[] = {
++ /* FIELD */
++ RCAR_GP_PIN(2, 16),
++};
++static const unsigned int vin0_field_mux[] = {
++ VI0_FIELD_MARK,
++};
++static const unsigned int vin0_clkenb_pins[] = {
++ /* CLKENB */
++ RCAR_GP_PIN(2, 1),
++};
++static const unsigned int vin0_clkenb_mux[] = {
++ VI0_CLKENB_MARK,
++};
++static const unsigned int vin0_clk_pins[] = {
++ /* CLK */
++ RCAR_GP_PIN(2, 0),
++};
++static const unsigned int vin0_clk_mux[] = {
++ VI0_CLK_MARK,
++};
++/* - VIN1 ------------------------------------------------------------------- */
++static const unsigned int vin1_data8_pins[] = {
++ RCAR_GP_PIN(3, 4), RCAR_GP_PIN(3, 5),
++ RCAR_GP_PIN(3, 6), RCAR_GP_PIN(3, 7),
++ RCAR_GP_PIN(3, 8), RCAR_GP_PIN(3, 9),
++ RCAR_GP_PIN(3, 10), RCAR_GP_PIN(3, 11),
++};
++static const unsigned int vin1_data8_mux[] = {
++ VI1_DATA0_MARK, VI1_DATA1_MARK,
++ VI1_DATA2_MARK, VI1_DATA3_MARK,
++ VI1_DATA4_MARK, VI1_DATA5_MARK,
++ VI1_DATA6_MARK, VI1_DATA7_MARK,
++};
++static const unsigned int vin1_data10_pins[] = {
++ RCAR_GP_PIN(3, 4), RCAR_GP_PIN(3, 5),
++ RCAR_GP_PIN(3, 6), RCAR_GP_PIN(3, 7),
++ RCAR_GP_PIN(3, 8), RCAR_GP_PIN(3, 9),
++ RCAR_GP_PIN(3, 10), RCAR_GP_PIN(3, 11),
++ RCAR_GP_PIN(3, 12), RCAR_GP_PIN(3, 13),
++};
++static const unsigned int vin1_data10_mux[] = {
++ VI1_DATA0_MARK, VI1_DATA1_MARK,
++ VI1_DATA2_MARK, VI1_DATA3_MARK,
++ VI1_DATA4_MARK, VI1_DATA5_MARK,
++ VI1_DATA6_MARK, VI1_DATA7_MARK,
++ VI1_DATA8_MARK, VI1_DATA9_MARK,
++};
++static const unsigned int vin1_data12_pins[] = {
++ RCAR_GP_PIN(3, 4), RCAR_GP_PIN(3, 5),
++ RCAR_GP_PIN(3, 6), RCAR_GP_PIN(3, 7),
++ RCAR_GP_PIN(3, 8), RCAR_GP_PIN(3, 9),
++ RCAR_GP_PIN(3, 10), RCAR_GP_PIN(3, 11),
++ RCAR_GP_PIN(3, 12), RCAR_GP_PIN(3, 13),
++ RCAR_GP_PIN(3, 14), RCAR_GP_PIN(3, 15),
++};
++static const unsigned int vin1_data12_mux[] = {
++ VI1_DATA0_MARK, VI1_DATA1_MARK,
++ VI1_DATA2_MARK, VI1_DATA3_MARK,
++ VI1_DATA4_MARK, VI1_DATA5_MARK,
++ VI1_DATA6_MARK, VI1_DATA7_MARK,
++ VI1_DATA8_MARK, VI1_DATA9_MARK,
++ VI1_DATA10_MARK, VI1_DATA11_MARK,
++};
++static const unsigned int vin1_sync_pins[] = {
++ /* VSYNC_N, HSYNC_N */
++ RCAR_GP_PIN(3, 3), RCAR_GP_PIN(3, 2),
++};
++static const unsigned int vin1_sync_mux[] = {
++ VI1_HSYNC_N_MARK, VI1_VSYNC_N_MARK,
++};
++static const unsigned int vin1_field_pins[] = {
++ /* FIELD */
++ RCAR_GP_PIN(3, 16),
++};
++static const unsigned int vin1_field_mux[] = {
++ VI1_FIELD_MARK,
++};
++static const unsigned int vin1_clkenb_pins[] = {
++ /* CLKENB */
++ RCAR_GP_PIN(3, 1),
++};
++static const unsigned int vin1_clkenb_mux[] = {
++ VI1_CLKENB_MARK,
++};
++static const unsigned int vin1_clk_pins[] = {
++ /* CLK */
++ RCAR_GP_PIN(3, 0),
++};
++static const unsigned int vin1_clk_mux[] = {
++ VI1_CLK_MARK,
++};
++
++static const struct sh_pfc_pin_group pinmux_groups[] = {
++ SH_PFC_PIN_GROUP(avb_rx_ctrl),
++ SH_PFC_PIN_GROUP(avb_rxc),
++ SH_PFC_PIN_GROUP(avb_rd0),
++ SH_PFC_PIN_GROUP(avb_rd1),
++ SH_PFC_PIN_GROUP(avb_rd2),
++ SH_PFC_PIN_GROUP(avb_rd3),
++ SH_PFC_PIN_GROUP(avb_rd4),
++ SH_PFC_PIN_GROUP(avb_tx_ctrl),
++ SH_PFC_PIN_GROUP(avb_txc),
++ SH_PFC_PIN_GROUP(avb_td0),
++ SH_PFC_PIN_GROUP(avb_td1),
++ SH_PFC_PIN_GROUP(avb_td2),
++ SH_PFC_PIN_GROUP(avb_td3),
++ SH_PFC_PIN_GROUP(avb_td4),
++ SH_PFC_PIN_GROUP(avb_txcrefclk),
++ SH_PFC_PIN_GROUP(avb_mdio),
++ SH_PFC_PIN_GROUP(avb_mdc),
++ SH_PFC_PIN_GROUP(avb_magic),
++ SH_PFC_PIN_GROUP(avb_phy_int),
++ SH_PFC_PIN_GROUP(avb_link),
++ SH_PFC_PIN_GROUP(avb_avtp_match),
++ SH_PFC_PIN_GROUP(avb_avtp_capture),
++ SH_PFC_PIN_GROUP(avb_avtp_pps),
++ SH_PFC_PIN_GROUP(gether_rx_ctrl),
++ SH_PFC_PIN_GROUP(gether_rxc),
++ SH_PFC_PIN_GROUP(gether_rd0),
++ SH_PFC_PIN_GROUP(gether_rd1),
++ SH_PFC_PIN_GROUP(gether_rd2),
++ SH_PFC_PIN_GROUP(gether_rd3),
++ SH_PFC_PIN_GROUP(gether_rd4),
++ SH_PFC_PIN_GROUP(gether_tx_ctrl),
++ SH_PFC_PIN_GROUP(gether_txc),
++ SH_PFC_PIN_GROUP(gether_td0),
++ SH_PFC_PIN_GROUP(gether_td1),
++ SH_PFC_PIN_GROUP(gether_td2),
++ SH_PFC_PIN_GROUP(gether_td3),
++ SH_PFC_PIN_GROUP(gether_td4),
++ SH_PFC_PIN_GROUP(gether_txcrefclk),
++ SH_PFC_PIN_GROUP(gether_txcrefclk_mega),
++ SH_PFC_PIN_GROUP(gether_mdio_a),
++ SH_PFC_PIN_GROUP(gether_mdio_b),
++ SH_PFC_PIN_GROUP(gether_mdc_a),
++ SH_PFC_PIN_GROUP(gether_mdc_b),
++ SH_PFC_PIN_GROUP(gether_magic),
++ SH_PFC_PIN_GROUP(gether_phy_int_a),
++ SH_PFC_PIN_GROUP(gether_phy_int_b),
++ SH_PFC_PIN_GROUP(gether_link_a),
++ SH_PFC_PIN_GROUP(gether_link_b),
++ SH_PFC_PIN_GROUP(gether_rmii),
++ SH_PFC_PIN_GROUP(canfd0_data_a),
++ SH_PFC_PIN_GROUP(canfd_clk_a),
++ SH_PFC_PIN_GROUP(canfd0_data_b),
++ SH_PFC_PIN_GROUP(canfd_clk_b),
++ SH_PFC_PIN_GROUP(canfd1_data),
++ SH_PFC_PIN_GROUP(du_rgb666),
++ SH_PFC_PIN_GROUP(du_clk_out_0),
++ SH_PFC_PIN_GROUP(du_clk_out_1),
++ SH_PFC_PIN_GROUP(du_sync),
++ SH_PFC_PIN_GROUP(du_oddf),
++ SH_PFC_PIN_GROUP(du_cde),
++ SH_PFC_PIN_GROUP(du_disp),
++ SH_PFC_PIN_GROUP(hscif0_data_a),
++ SH_PFC_PIN_GROUP(hscif0_clk_a),
++ SH_PFC_PIN_GROUP(hscif0_ctrl_a),
++ SH_PFC_PIN_GROUP(hscif0_data_b),
++ SH_PFC_PIN_GROUP(hscif0_clk_b),
++ SH_PFC_PIN_GROUP(hscif0_ctrl_b),
++ SH_PFC_PIN_GROUP(hscif1_data),
++ SH_PFC_PIN_GROUP(hscif1_clk),
++ SH_PFC_PIN_GROUP(hscif1_ctrl),
++ SH_PFC_PIN_GROUP(hscif2_data),
++ SH_PFC_PIN_GROUP(hscif2_clk),
++ SH_PFC_PIN_GROUP(hscif2_ctrl),
++ SH_PFC_PIN_GROUP(hscif3_data),
++ SH_PFC_PIN_GROUP(hscif3_clk),
++ SH_PFC_PIN_GROUP(hscif3_ctrl),
++ SH_PFC_PIN_GROUP(scif_clk_a),
++ SH_PFC_PIN_GROUP(scif_clk_b),
++ SH_PFC_PIN_GROUP(i2c0),
++ SH_PFC_PIN_GROUP(i2c1),
++ SH_PFC_PIN_GROUP(i2c2),
++ SH_PFC_PIN_GROUP(i2c3),
++ SH_PFC_PIN_GROUP(i2c4),
++ SH_PFC_PIN_GROUP(i2c5),
++ SH_PFC_PIN_GROUP(intc_ex_irq0),
++ SH_PFC_PIN_GROUP(intc_ex_irq1),
++ SH_PFC_PIN_GROUP(intc_ex_irq2),
++ SH_PFC_PIN_GROUP(intc_ex_irq3),
++ SH_PFC_PIN_GROUP(intc_ex_irq4),
++ SH_PFC_PIN_GROUP(intc_ex_irq5),
++ SH_PFC_PIN_GROUP(msiof0_clk),
++ SH_PFC_PIN_GROUP(msiof0_sync),
++ SH_PFC_PIN_GROUP(msiof0_ss1),
++ SH_PFC_PIN_GROUP(msiof0_ss2),
++ SH_PFC_PIN_GROUP(msiof0_txd),
++ SH_PFC_PIN_GROUP(msiof0_rxd),
++ SH_PFC_PIN_GROUP(msiof1_clk),
++ SH_PFC_PIN_GROUP(msiof1_sync),
++ SH_PFC_PIN_GROUP(msiof1_ss1),
++ SH_PFC_PIN_GROUP(msiof1_ss2),
++ SH_PFC_PIN_GROUP(msiof1_txd),
++ SH_PFC_PIN_GROUP(msiof1_rxd),
++ SH_PFC_PIN_GROUP(msiof2_clk),
++ SH_PFC_PIN_GROUP(msiof2_sync),
++ SH_PFC_PIN_GROUP(msiof2_ss1),
++ SH_PFC_PIN_GROUP(msiof2_ss2),
++ SH_PFC_PIN_GROUP(msiof2_txd),
++ SH_PFC_PIN_GROUP(msiof2_rxd),
++ SH_PFC_PIN_GROUP(msiof3_clk),
++ SH_PFC_PIN_GROUP(msiof3_sync),
++ SH_PFC_PIN_GROUP(msiof3_ss1),
++ SH_PFC_PIN_GROUP(msiof3_ss2),
++ SH_PFC_PIN_GROUP(msiof3_txd),
++ SH_PFC_PIN_GROUP(msiof3_rxd),
++ SH_PFC_PIN_GROUP(tpu_to0),
++ SH_PFC_PIN_GROUP(tpu_to1),
++ SH_PFC_PIN_GROUP(tpu_to2),
++ SH_PFC_PIN_GROUP(tpu_to3),
++ SH_PFC_PIN_GROUP(pwm0_a),
++ SH_PFC_PIN_GROUP(pwm0_b),
++ SH_PFC_PIN_GROUP(pwm1_a),
++ SH_PFC_PIN_GROUP(pwm1_b),
++ SH_PFC_PIN_GROUP(pwm2_a),
++ SH_PFC_PIN_GROUP(pwm2_b),
++ SH_PFC_PIN_GROUP(pwm3_a),
++ SH_PFC_PIN_GROUP(pwm3_b),
++ SH_PFC_PIN_GROUP(pwm4_a),
++ SH_PFC_PIN_GROUP(pwm4_b),
++ SH_PFC_PIN_GROUP(scif0_data),
++ SH_PFC_PIN_GROUP(scif0_clk),
++ SH_PFC_PIN_GROUP(scif0_ctrl),
++ SH_PFC_PIN_GROUP(scif1_data_a),
++ SH_PFC_PIN_GROUP(scif1_clk),
++ SH_PFC_PIN_GROUP(scif1_ctrl),
++ SH_PFC_PIN_GROUP(scif1_data_b),
++ SH_PFC_PIN_GROUP(scif3_data),
++ SH_PFC_PIN_GROUP(scif3_clk),
++ SH_PFC_PIN_GROUP(scif3_ctrl),
++ SH_PFC_PIN_GROUP(scif4_data),
++ SH_PFC_PIN_GROUP(scif4_clk),
++ SH_PFC_PIN_GROUP(scif4_ctrl),
++ SH_PFC_PIN_GROUP(mmc_data1),
++ SH_PFC_PIN_GROUP(mmc_data4),
++ SH_PFC_PIN_GROUP(mmc_data8),
++ SH_PFC_PIN_GROUP(mmc_ctrl),
++ SH_PFC_PIN_GROUP(mmc_cd),
++ SH_PFC_PIN_GROUP(mmc_wp),
++ SH_PFC_PIN_GROUP(mmc_ds),
++ SH_PFC_PIN_GROUP(tmu_tclk1_a),
++ SH_PFC_PIN_GROUP(tmu_tclk1_b),
++ SH_PFC_PIN_GROUP(tmu_tclk2_a),
++ SH_PFC_PIN_GROUP(tmu_tclk2_b),
++ SH_PFC_PIN_GROUP(vin0_data8),
++ SH_PFC_PIN_GROUP(vin0_data10),
++ SH_PFC_PIN_GROUP(vin0_data12),
++ SH_PFC_PIN_GROUP(vin0_data16),
++ SH_PFC_PIN_GROUP(vin0_data20),
++ SH_PFC_PIN_GROUP(vin0_data24),
++ SH_PFC_PIN_GROUP(vin0_sync),
++ SH_PFC_PIN_GROUP(vin0_field),
++ SH_PFC_PIN_GROUP(vin0_clkenb),
++ SH_PFC_PIN_GROUP(vin0_clk),
++ SH_PFC_PIN_GROUP(vin1_data8),
++ SH_PFC_PIN_GROUP(vin1_data10),
++ SH_PFC_PIN_GROUP(vin1_data12),
++ SH_PFC_PIN_GROUP(vin1_sync),
++ SH_PFC_PIN_GROUP(vin1_field),
++ SH_PFC_PIN_GROUP(vin1_clkenb),
++ SH_PFC_PIN_GROUP(vin1_clk),
++};
++
++static const char * const avb_groups[] = {
++ "avb_rx_ctrl",
++ "avb_rxc",
++ "avb_rd1",
++ "avb_rd4",
++ "avb_tx_ctrl",
++ "avb_txc",
++ "avb_td1",
++ "avb_td4",
++ "avb_txcrefclk",
++ "avb_mdio",
++ "avb_mdc",
++ "avb_magic",
++ "avb_phy_int",
++ "avb_link",
++ "avb_avtp_match",
++ "avb_avtp_capture",
++ "avb_avtp_pps",
++};
++
++static const char * const gether_groups[] = {
++ "gether_rx_ctrl",
++ "gether_rxc",
++ "gether_rd1",
++ "gether_rd4",
++ "gether_tx_ctrl",
++ "gether_txc",
++ "gether_td1",
++ "gether_td4",
++ "gether_txcrefclk",
++ "gether_txcrefclk_mega",
++ "gether_mdio_a",
++ "gether_mdc_a",
++ "gether_mdio_b",
++ "gether_mdc_b",
++ "gether_magic",
++ "gether_phy_int_a",
++ "gether_link_a",
++ "gether_phy_int_b",
++ "gether_link_b",
++ "gether_rmii",
++};
++
++static const char * const canfd0_groups[] = {
++ "canfd0_data_a",
++ "canfd_clk_a",
++ "canfd0_data_b",
++ "canfd_clk_b",
++};
++
++static const char * const canfd1_groups[] = {
++ "canfd1_data",
++};
++
++static const char * const du_groups[] = {
++ "du_rgb666",
++ "du_clk_out_0",
++ "du_clk_out_1",
++ "du_sync",
++ "du_oddf",
++ "du_cde",
++ "du_disp",
++};
++
++static const char * const hscif0_groups[] = {
++ "hscif0_data_a",
++ "hscif0_clk_a",
++ "hscif0_ctrl_a",
++ "hscif0_data_b",
++ "hscif0_clk_b",
++ "hscif0_ctrl_b",
++};
++
++static const char * const hscif1_groups[] = {
++ "hscif1_data",
++ "hscif1_clk",
++ "hscif1_ctrl",
++};
++
++static const char * const hscif2_groups[] = {
++ "hscif2_data",
++ "hscif2_clk",
++ "hscif2_ctrl",
++};
++
++static const char * const hscif3_groups[] = {
++ "hscif3_data",
++ "hscif3_clk",
++ "hscif3_ctrl",
++};
++
++static const char * const scif_clk_groups[] = {
++ "scif_clk_a",
++ "scif_clk_b",
++};
++
++static const char * const i2c0_groups[] = {
++ "i2c0",
++};
++
++static const char * const i2c1_groups[] = {
++ "i2c1",
++};
++
++static const char * const i2c2_groups[] = {
++ "i2c2",
++};
++
++static const char * const i2c3_groups[] = {
++ "i2c3",
++};
++
++static const char * const i2c4_groups[] = {
++ "i2c4",
++};
++
++static const char * const i2c5_groups[] = {
++ "i2c5",
++};
++
++static const char * const intc_ex_groups[] = {
++ "intc_ex_irq0",
++ "intc_ex_irq1",
++ "intc_ex_irq2",
++ "intc_ex_irq3",
++ "intc_ex_irq4",
++ "intc_ex_irq5",
++};
++
++static const char * const msiof0_groups[] = {
++ "msiof0_clk",
++ "msiof0_sync",
++ "msiof0_ss1",
++ "msiof0_ss2",
++ "msiof0_txd",
++ "msiof0_rxd",
++};
++
++static const char * const msiof1_groups[] = {
++ "msiof1_clk",
++ "msiof1_sync",
++ "msiof1_ss1",
++ "msiof1_ss2",
++ "msiof1_txd",
++ "msiof1_rxd",
++};
++
++static const char * const msiof2_groups[] = {
++ "msiof2_clk",
++ "msiof2_sync",
++ "msiof2_ss1",
++ "msiof2_ss2",
++ "msiof2_txd",
++ "msiof2_rxd",
++};
++
++static const char * const msiof3_groups[] = {
++ "msiof3_clk",
++ "msiof3_sync",
++ "msiof3_ss1",
++ "msiof3_ss2",
++ "msiof3_txd",
++ "msiof3_rxd",
++};
++
++static const char * const tpu_groups[] = {
++ "tpu_to0",
++ "tpu_to1",
++ "tpu_to2",
++ "tpu_to3",
++};
++
++static const char * const pwm0_groups[] = {
++ "pwm0_a",
++ "pwm0_b",
++};
++
++static const char * const pwm1_groups[] = {
++ "pwm1_a",
++ "pwm1_b",
++};
++
++static const char * const pwm2_groups[] = {
++ "pwm2_a",
++ "pwm2_b",
++};
++
++static const char * const pwm3_groups[] = {
++ "pwm3_a",
++ "pwm3_b",
++};
++
++static const char * const pwm4_groups[] = {
++ "pwm4_a",
++ "pwm4_b",
++};
++
++static const char * const scif0_groups[] = {
++ "scif0_data",
++// "scif0_clk",
++// "scif0_ctrl",
++};
++
++static const char * const scif1_groups[] = {
++ "scif1_data_a",
++ "scif1_clk",
++ "scif1_ctrl",
++ "scif1_data_b",
++};
++
++static const char * const scif3_groups[] = {
++ "scif3_data",
++ "scif3_clk",
++ "scif3_ctrl",
++};
++
++static const char * const scif4_groups[] = {
++ "scif4_data",
++ "scif4_clk",
++ "scif4_ctrl",
++};
++
++static const char * const mmc_groups[] = {
++ "mmc_data1",
++ "mmc_data4",
++ "mmc_data8",
++ "mmc_ctrl",
++ "mmc_cd",
++ "mmc_wp",
++ "mmc_ds",
++};
++
++static const char * const tmu_groups[] = {
++ "tmu_tclk1_a",
++ "tmu_tclk1_b",
++ "tmu_tclk2_a",
++ "tmu_tclk2_b",
++};
++
++static const char * const vin0_groups[] = {
++ "vin0_data8",
++ "vin0_data10",
++ "vin0_data12",
++ "vin0_data16",
++ "vin0_data20",
++ "vin0_data24",
++ "vin0_sync",
++ "vin0_field",
++ "vin0_clkenb",
++ "vin0_clk",
++};
++
++static const char * const vin1_groups[] = {
++ "vin1_data8",
++ "vin1_data10",
++ "vin1_data12",
++ "vin1_sync",
++ "vin1_field",
++ "vin1_clkenb",
++ "vin1_clk",
++};
++
++static const struct sh_pfc_function pinmux_functions[] = {
++ SH_PFC_FUNCTION(avb),
++ SH_PFC_FUNCTION(gether),
++ SH_PFC_FUNCTION(canfd0),
++ SH_PFC_FUNCTION(canfd1),
++ SH_PFC_FUNCTION(du),
++ SH_PFC_FUNCTION(hscif0),
++ SH_PFC_FUNCTION(hscif1),
++ SH_PFC_FUNCTION(hscif2),
++ SH_PFC_FUNCTION(hscif3),
++ SH_PFC_FUNCTION(scif_clk),
++ SH_PFC_FUNCTION(i2c0),
++ SH_PFC_FUNCTION(i2c1),
++ SH_PFC_FUNCTION(i2c2),
++ SH_PFC_FUNCTION(i2c3),
++ SH_PFC_FUNCTION(i2c4),
++ SH_PFC_FUNCTION(i2c5),
++ SH_PFC_FUNCTION(intc_ex),
++ SH_PFC_FUNCTION(msiof0),
++ SH_PFC_FUNCTION(msiof1),
++ SH_PFC_FUNCTION(msiof2),
++ SH_PFC_FUNCTION(msiof3),
++ SH_PFC_FUNCTION(tpu),
++ SH_PFC_FUNCTION(pwm0),
++ SH_PFC_FUNCTION(pwm1),
++ SH_PFC_FUNCTION(pwm2),
++ SH_PFC_FUNCTION(pwm3),
++ SH_PFC_FUNCTION(pwm4),
++ SH_PFC_FUNCTION(scif0),
++ SH_PFC_FUNCTION(scif1),
++ SH_PFC_FUNCTION(scif3),
++ SH_PFC_FUNCTION(scif4),
++ SH_PFC_FUNCTION(mmc),
++ SH_PFC_FUNCTION(tmu),
++ SH_PFC_FUNCTION(vin0),
++ SH_PFC_FUNCTION(vin1),
++};
++
++static const struct pinmux_cfg_reg pinmux_config_regs[] = {
++#define F_(x, y) FN_##y
++#define FM(x) FN_##x
++ { PINMUX_CFG_REG("GPSR0", 0xe6060100, 32, 1) {
++ 0, 0,
++ 0, 0,
++ 0, 0,
++ 0, 0,
++ 0, 0,
++ 0, 0,
++ 0, 0,
++ 0, 0,
++ 0, 0,
++ 0, 0,
++ GP_0_21_FN, GPSR0_21,
++ GP_0_20_FN, GPSR0_20,
++ GP_0_19_FN, GPSR0_19,
++ GP_0_18_FN, GPSR0_18,
++ GP_0_17_FN, GPSR0_17,
++ GP_0_16_FN, GPSR0_16,
++ GP_0_15_FN, GPSR0_15,
++ GP_0_14_FN, GPSR0_14,
++ GP_0_13_FN, GPSR0_13,
++ GP_0_12_FN, GPSR0_12,
++ GP_0_11_FN, GPSR0_11,
++ GP_0_10_FN, GPSR0_10,
++ GP_0_9_FN, GPSR0_9,
++ GP_0_8_FN, GPSR0_8,
++ GP_0_7_FN, GPSR0_7,
++ GP_0_6_FN, GPSR0_6,
++ GP_0_5_FN, GPSR0_5,
++ GP_0_4_FN, GPSR0_4,
++ GP_0_3_FN, GPSR0_3,
++ GP_0_2_FN, GPSR0_2,
++ GP_0_1_FN, GPSR0_1,
++ GP_0_0_FN, GPSR0_0, }
++ },
++ { PINMUX_CFG_REG("GPSR1", 0xe6060104, 32, 1) {
++ 0, 0,
++ 0, 0,
++ 0, 0,
++ 0, 0,
++ GP_1_27_FN, GPSR1_27,
++ GP_1_26_FN, GPSR1_26,
++ GP_1_25_FN, GPSR1_25,
++ GP_1_24_FN, GPSR1_24,
++ GP_1_23_FN, GPSR1_23,
++ GP_1_22_FN, GPSR1_22,
++ GP_1_21_FN, GPSR1_21,
++ GP_1_20_FN, GPSR1_20,
++ GP_1_19_FN, GPSR1_19,
++ GP_1_18_FN, GPSR1_18,
++ GP_1_17_FN, GPSR1_17,
++ GP_1_16_FN, GPSR1_16,
++ GP_1_15_FN, GPSR1_15,
++ GP_1_14_FN, GPSR1_14,
++ GP_1_13_FN, GPSR1_13,
++ GP_1_12_FN, GPSR1_12,
++ GP_1_11_FN, GPSR1_11,
++ GP_1_10_FN, GPSR1_10,
++ GP_1_9_FN, GPSR1_9,
++ GP_1_8_FN, GPSR1_8,
++ GP_1_7_FN, GPSR1_7,
++ GP_1_6_FN, GPSR1_6,
++ GP_1_5_FN, GPSR1_5,
++ GP_1_4_FN, GPSR1_4,
++ GP_1_3_FN, GPSR1_3,
++ GP_1_2_FN, GPSR1_2,
++ GP_1_1_FN, GPSR1_1,
++ GP_1_0_FN, GPSR1_0, }
++ },
++ { PINMUX_CFG_REG("GPSR2", 0xe6060108, 32, 1) {
++ 0, 0,
++ 0, 0,
++ GP_2_29_FN, GPSR2_29,
++ GP_2_28_FN, GPSR2_28,
++ GP_2_27_FN, GPSR2_27,
++ GP_2_26_FN, GPSR2_26,
++ GP_2_25_FN, GPSR2_25,
++ GP_2_24_FN, GPSR2_24,
++ GP_2_23_FN, GPSR2_23,
++ GP_2_22_FN, GPSR2_22,
++ GP_2_21_FN, GPSR2_21,
++ GP_2_20_FN, GPSR2_20,
++ GP_2_19_FN, GPSR2_19,
++ GP_2_18_FN, GPSR2_18,
++ GP_2_17_FN, GPSR2_17,
++ GP_2_16_FN, GPSR2_16,
++ GP_2_15_FN, GPSR2_15,
++ GP_2_14_FN, GPSR2_14,
++ GP_2_13_FN, GPSR2_13,
++ GP_2_12_FN, GPSR2_12,
++ GP_2_11_FN, GPSR2_11,
++ GP_2_10_FN, GPSR2_10,
++ GP_2_9_FN, GPSR2_9,
++ GP_2_8_FN, GPSR2_8,
++ GP_2_7_FN, GPSR2_7,
++ GP_2_6_FN, GPSR2_6,
++ GP_2_5_FN, GPSR2_5,
++ GP_2_4_FN, GPSR2_4,
++ GP_2_3_FN, GPSR2_3,
++ GP_2_2_FN, GPSR2_2,
++ GP_2_1_FN, GPSR2_1,
++ GP_2_0_FN, GPSR2_0, }
++ },
++ { PINMUX_CFG_REG("GPSR3", 0xe606010c, 32, 1) {
++ 0, 0,
++ 0, 0,
++ 0, 0,
++ 0, 0,
++ 0, 0,
++ 0, 0,
++ 0, 0,
++ 0, 0,
++ 0, 0,
++ 0, 0,
++ 0, 0,
++ 0, 0,
++ 0, 0,
++ 0, 0,
++ 0, 0,
++ GP_3_16_FN, GPSR3_16,
++ GP_3_15_FN, GPSR3_15,
++ GP_3_14_FN, GPSR3_14,
++ GP_3_13_FN, GPSR3_13,
++ GP_3_12_FN, GPSR3_12,
++ GP_3_11_FN, GPSR3_11,
++ GP_3_10_FN, GPSR3_10,
++ GP_3_9_FN, GPSR3_9,
++ GP_3_8_FN, GPSR3_8,
++ GP_3_7_FN, GPSR3_7,
++ GP_3_6_FN, GPSR3_6,
++ GP_3_5_FN, GPSR3_5,
++ GP_3_4_FN, GPSR3_4,
++ GP_3_3_FN, GPSR3_3,
++ GP_3_2_FN, GPSR3_2,
++ GP_3_1_FN, GPSR3_1,
++ GP_3_0_FN, GPSR3_0, }
++ },
++ { PINMUX_CFG_REG("GPSR4", 0xe6060110, 32, 1) {
++ 0, 0,
++ 0, 0,
++ 0, 0,
++ 0, 0,
++ 0, 0,
++ 0, 0,
++ 0, 0,
++ GP_4_24_FN, GPSR4_24,
++ GP_4_23_FN, GPSR4_23,
++ GP_4_22_FN, GPSR4_22,
++ GP_4_21_FN, GPSR4_21,
++ GP_4_20_FN, GPSR4_20,
++ GP_4_19_FN, GPSR4_19,
++ GP_4_18_FN, GPSR4_18,
++ GP_4_17_FN, GPSR4_17,
++ GP_4_16_FN, GPSR4_16,
++ GP_4_15_FN, GPSR4_15,
++ GP_4_14_FN, GPSR4_14,
++ GP_4_13_FN, GPSR4_13,
++ GP_4_12_FN, GPSR4_12,
++ GP_4_11_FN, GPSR4_11,
++ GP_4_10_FN, GPSR4_10,
++ GP_4_9_FN, GPSR4_9,
++ GP_4_8_FN, GPSR4_8,
++ GP_4_7_FN, GPSR4_7,
++ GP_4_6_FN, GPSR4_6,
++ GP_4_5_FN, GPSR4_5,
++ GP_4_4_FN, GPSR4_4,
++ GP_4_3_FN, GPSR4_3,
++ GP_4_2_FN, GPSR4_2,
++ GP_4_1_FN, GPSR4_1,
++ GP_4_0_FN, GPSR4_0, }
++ },
++ { PINMUX_CFG_REG("GPSR5", 0xe6060114, 32, 1) {
++ 0, 0,
++ 0, 0,
++ 0, 0,
++ 0, 0,
++ 0, 0,
++ 0, 0,
++ 0, 0,
++ 0, 0,
++ 0, 0,
++ 0, 0,
++ 0, 0,
++ 0, 0,
++ 0, 0,
++ 0, 0,
++ 0, 0,
++ 0, 0,
++ 0, 0,
++ GP_5_14_FN, GPSR5_14,
++ GP_5_13_FN, GPSR5_13,
++ GP_5_12_FN, GPSR5_12,
++ GP_5_11_FN, GPSR5_11,
++ GP_5_10_FN, GPSR5_10,
++ GP_5_9_FN, GPSR5_9,
++ GP_5_8_FN, GPSR5_8,
++ GP_5_7_FN, GPSR5_7,
++ GP_5_6_FN, GPSR5_6,
++ GP_5_5_FN, GPSR5_5,
++ GP_5_4_FN, GPSR5_4,
++ GP_5_3_FN, GPSR5_3,
++ GP_5_2_FN, GPSR5_2,
++ GP_5_1_FN, GPSR5_1,
++ GP_5_0_FN, GPSR5_0, }
++ },
++#undef F_
++#undef FM
++
++#define F_(x, y) x,
++#define FM(x) FN_##x,
++ { PINMUX_CFG_REG("IPSR0", 0xe6060200, 32, 4) {
++ IP0_31_28
++ IP0_27_24
++ IP0_23_20
++ IP0_19_16
++ IP0_15_12
++ IP0_11_8
++ IP0_7_4
++ IP0_3_0 }
++ },
++ { PINMUX_CFG_REG("IPSR1", 0xe6060204, 32, 4) {
++ IP1_31_28
++ IP1_27_24
++ IP1_23_20
++ IP1_19_16
++ IP1_15_12
++ IP1_11_8
++ IP1_7_4
++ IP1_3_0 }
++ },
++ { PINMUX_CFG_REG("IPSR2", 0xe6060208, 32, 4) {
++ IP2_31_28
++ IP2_27_24
++ IP2_23_20
++ IP2_19_16
++ IP2_15_12
++ IP2_11_8
++ IP2_7_4
++ IP2_3_0 }
++ },
++ { PINMUX_CFG_REG("IPSR3", 0xe606020c, 32, 4) {
++ IP3_31_28
++ IP3_27_24
++ IP3_23_20
++ IP3_19_16
++ IP3_15_12
++ IP3_11_8
++ IP3_7_4
++ IP3_3_0 }
++ },
++ { PINMUX_CFG_REG("IPSR4", 0xe6060210, 32, 4) {
++ IP4_31_28
++ IP4_27_24
++ IP4_23_20
++ IP4_19_16
++ IP4_15_12
++ IP4_11_8
++ IP4_7_4
++ IP4_3_0 }
++ },
++ { PINMUX_CFG_REG("IPSR5", 0xe6060214, 32, 4) {
++ IP5_31_28
++ IP5_27_24
++ IP5_23_20
++ IP5_19_16
++ IP5_15_12
++ IP5_11_8
++ IP5_7_4
++ IP5_3_0 }
++ },
++ { PINMUX_CFG_REG("IPSR6", 0xe6060218, 32, 4) {
++ IP6_31_28
++ IP6_27_24
++ IP6_23_20
++ IP6_19_16
++ IP6_15_12
++ IP6_11_8
++ IP6_7_4
++ IP6_3_0 }
++ },
++ { PINMUX_CFG_REG("IPSR7", 0xe606021c, 32, 4) {
++ IP7_31_28
++ IP7_27_24
++ IP7_23_20
++ IP7_19_16
++ IP7_15_12
++ IP7_11_8
++ IP7_7_4
++ IP7_3_0 }
++ },
++ { PINMUX_CFG_REG("IPSR8", 0xe6060220, 32, 4) {
++ IP8_31_28
++ IP8_27_24
++ IP8_23_20
++ IP8_19_16
++ IP8_15_12
++ IP8_11_8
++ IP8_7_4
++ IP8_3_0 }
++ },
++ { PINMUX_CFG_REG("IPSR9", 0xe6060224, 32, 4) {
++ IP8_31_28
++ IP8_27_24
++ IP8_23_20
++ IP8_19_16
++ IP8_15_12
++ IP8_11_8
++ IP8_7_4
++ IP8_3_0 }
++ },
++ { PINMUX_CFG_REG("IPSR10", 0xe6060228, 32, 4) {
++ IP8_31_28
++ IP8_27_24
++ IP8_23_20
++ IP8_19_16
++ IP8_15_12
++ IP8_11_8
++ IP8_7_4
++ IP8_3_0 }
++ },
++#undef F_
++#undef FM
++
++#define F_(x, y) x,
++#define FM(x) FN_##x,
++ { PINMUX_CFG_REG("MOD_SEL0", 0xe6060500, 32, 1) {
++ /* RESERVED 31..12 */
++ 0, 0,
++ 0, 0,
++ 0, 0,
++ 0, 0,
++ 0, 0,
++ 0, 0,
++ 0, 0,
++ 0, 0,
++ 0, 0,
++ 0, 0,
++ 0, 0,
++ 0, 0,
++ 0, 0,
++ 0, 0,
++ 0, 0,
++ 0, 0,
++ 0, 0,
++ 0, 0,
++ 0, 0,
++ 0, 0,
++ MOD_SEL0_11
++ MOD_SEL0_10
++ MOD_SEL0_9
++ MOD_SEL0_8
++ MOD_SEL0_7
++ MOD_SEL0_6
++ MOD_SEL0_5
++ MOD_SEL0_4
++ 0, 0,
++ MOD_SEL0_2
++ MOD_SEL0_1
++ MOD_SEL0_0 }
++ },
++ { },
++};
++
++#define POC0 0xe6060380
++#define POC1 0xe6060384
++#define POC2 0xe6060388
++
++/* TODO make it nice */
++static int r8a7798_pin_to_pocctrl(struct sh_pfc *pfc, unsigned int pin, u32 *pocctrl)
++{
++ int bit = -EINVAL;
++
++ *pocctrl = POC0;
++
++ if (pin >= RCAR_GP_PIN(0, 0) && pin <= RCAR_GP_PIN(0, 21))
++ bit = pin & 0x1f;
++ else if (pin >= RCAR_GP_PIN(2, 0) && pin <= RCAR_GP_PIN(2, 9))
++ bit = (pin & 0x1f) + 22;
++
++ if (bit != -EINVAL)
++ goto out;
++
++ *pocctrl = POC1;
++
++ if (pin >= RCAR_GP_PIN(2, 10) && pin <= RCAR_GP_PIN(2, 16))
++ bit = (pin & 0x1f) - 10;
++ else if (pin >= RCAR_GP_PIN(3, 0) && pin <= RCAR_GP_PIN(3, 16))
++ bit = (pin & 0x1f) + 7;
++ else if (pin >= RCAR_GP_PIN(2, 17) && pin <= RCAR_GP_PIN(2, 24))
++ bit = (pin & 0x1f) + 7;
++
++ if (bit != -EINVAL)
++ goto out;
++
++ *pocctrl = POC2;
++
++ if (pin >= RCAR_GP_PIN(2, 25) && pin <= RCAR_GP_PIN(2, 29))
++ bit = (pin & 0x1f) - 25;
++
++out:
++ return bit;
++}
++
++static const struct sh_pfc_soc_operations pinmux_ops = {
++ .pin_to_pocctrl = r8a7798_pin_to_pocctrl,
++};
++
++const struct sh_pfc_soc_info r8a7798_pinmux_info = {
++ .name = "r8a77980_pfc",
++ .ops = &pinmux_ops,
++ .unlock_reg = 0xe6060000, /* PMMR */
++
++ .function = { PINMUX_FUNCTION_BEGIN, PINMUX_FUNCTION_END },
++
++ .pins = pinmux_pins,
++ .nr_pins = ARRAY_SIZE(pinmux_pins),
++ .groups = pinmux_groups,
++ .nr_groups = ARRAY_SIZE(pinmux_groups),
++ .functions = pinmux_functions,
++ .nr_functions = ARRAY_SIZE(pinmux_functions),
++
++ .cfg_regs = pinmux_config_regs,
++
++ .pinmux_data = pinmux_data,
++ .pinmux_data_size = ARRAY_SIZE(pinmux_data),
++};
+diff --git a/drivers/pinctrl/sh-pfc/sh_pfc.h b/drivers/pinctrl/sh-pfc/sh_pfc.h
+index 062af89..eaf052d 100644
+--- a/drivers/pinctrl/sh-pfc/sh_pfc.h
++++ b/drivers/pinctrl/sh-pfc/sh_pfc.h
+@@ -289,6 +289,7 @@ struct sh_pfc_soc_info {
+ extern const struct sh_pfc_soc_info r8a7796_pinmux_info;
+ extern const struct sh_pfc_soc_info r8a77965_pinmux_info;
+ extern const struct sh_pfc_soc_info r8a7797_pinmux_info;
++extern const struct sh_pfc_soc_info r8a7798_pinmux_info;
+ extern const struct sh_pfc_soc_info sh7203_pinmux_info;
+ extern const struct sh_pfc_soc_info sh7264_pinmux_info;
+ extern const struct sh_pfc_soc_info sh7269_pinmux_info;
+@@ -465,9 +466,13 @@ struct sh_pfc_soc_info {
+ PORT_GP_CFG_1(bank, 23, fn, sfx, cfg)
+ #define PORT_GP_24(bank, fn, sfx) PORT_GP_CFG_24(bank, fn, sfx, 0)
+
+-#define PORT_GP_CFG_26(bank, fn, sfx, cfg) \
++#define PORT_GP_CFG_25(bank, fn, sfx, cfg) \
+ PORT_GP_CFG_24(bank, fn, sfx, cfg), \
+- PORT_GP_CFG_1(bank, 24, fn, sfx, cfg), \
++ PORT_GP_CFG_1(bank, 24, fn, sfx, cfg)
++#define PORT_GP_24(bank, fn, sfx) PORT_GP_CFG_24(bank, fn, sfx, 0)
++
++#define PORT_GP_CFG_26(bank, fn, sfx, cfg) \
++ PORT_GP_CFG_25(bank, fn, sfx, cfg), \
+ PORT_GP_CFG_1(bank, 25, fn, sfx, cfg)
+ #define PORT_GP_26(bank, fn, sfx) PORT_GP_CFG_26(bank, fn, sfx, 0)
+
+diff --git a/drivers/soc/renesas/Makefile b/drivers/soc/renesas/Makefile
+index 2ba6a76..164b3e7 100644
+--- a/drivers/soc/renesas/Makefile
++++ b/drivers/soc/renesas/Makefile
+@@ -6,6 +6,7 @@ obj-$(CONFIG_ARCH_R8A7795) += rcar-rst.o
+ obj-$(CONFIG_ARCH_R8A7796) += rcar-rst.o
+ obj-$(CONFIG_ARCH_R8A77965) += rcar-rst.o
+ obj-$(CONFIG_ARCH_R8A7797) += rcar-rst.o
++obj-$(CONFIG_ARCH_R8A7798) += rcar-rst.o
+
+ obj-$(CONFIG_ARCH_R8A7743) += rcar-sysc.o r8a7743-sysc.o
+ obj-$(CONFIG_ARCH_R8A7745) += rcar-sysc.o r8a7745-sysc.o
+@@ -20,15 +21,18 @@ obj-$(CONFIG_ARCH_R8A7795) += rcar-sysc.o r8a7795-sysc.o
+ obj-$(CONFIG_ARCH_R8A7796) += rcar-sysc.o r8a7796-sysc.o
+ obj-$(CONFIG_ARCH_R8A77965) += rcar-sysc.o r8a77965-sysc.o
+ obj-$(CONFIG_ARCH_R8A7797) += rcar-sysc.o r8a7797-sysc.o
++obj-$(CONFIG_ARCH_R8A7798) += rcar-sysc.o r8a7798-sysc.o
+
+ obj-$(CONFIG_ARCH_R8A7795) += rcar-avs.o
+ obj-$(CONFIG_ARCH_R8A7796) += rcar-avs.o
+ obj-$(CONFIG_ARCH_R8A77965) += rcar-avs.o
+ obj-$(CONFIG_ARCH_R8A7797) += rcar-avs.o
++obj-$(CONFIG_ARCH_R8A7798) += rcar-avs.o
+ # EMS for R-Car Gen3
+ obj-$(CONFIG_ARCH_R8A7795) += rcar_ems_ctrl.o
+ obj-$(CONFIG_ARCH_R8A7796) += rcar_ems_ctrl.o
+ obj-$(CONFIG_ARCH_R8A77965) += rcar_ems_ctrl.o
+ obj-$(CONFIG_ARCH_R8A7797) += rcar_ems_ctrl.o
++obj-$(CONFIG_ARCH_R8A7798) += rcar_ems_ctrl.o
+
+ obj-$(CONFIG_RCAR_DDR_BACKUP) += s2ram_ddr_backup.o
+diff --git a/drivers/soc/renesas/r8a7798-sysc.c b/drivers/soc/renesas/r8a7798-sysc.c
+new file mode 100644
+index 0000000..128e79d
+--- /dev/null
++++ b/drivers/soc/renesas/r8a7798-sysc.c
+@@ -0,0 +1,57 @@
++/*
++ * Renesas R-Car V3H System Controller
++ *
++ * Copyright (C) 2018 Renesas Electronics Corp.
++ * Copyright (C) 2018 Cogent Embedded, Inc.
++ *
++ * This program is free software; you can redistribute it and/or modify
++ * it under the terms of the GNU General Public License as published by
++ * the Free Software Foundation; version 2 of the License.
++ */
++
++#include <linux/bug.h>
++#include <linux/kernel.h>
++
++#include <dt-bindings/power/r8a7798-sysc.h>
++
++#include "rcar-sysc.h"
++
++static const struct rcar_sysc_area r8a7798_areas[] __initconst = {
++ { "always-on", 0, 0, R8A7798_PD_ALWAYS_ON, -1, PD_ALWAYS_ON },
++ { "ca53-scu", 0x140, 0, R8A7798_PD_CA53_SCU, R8A7798_PD_ALWAYS_ON,
++ PD_SCU },
++ { "ca53-cpu0", 0x200, 0, R8A7798_PD_CA53_CPU0, R8A7798_PD_CA53_SCU,
++ PD_CPU_NOCR },
++ { "ca53-cpu1", 0x200, 1, R8A7798_PD_CA53_CPU1, R8A7798_PD_CA53_SCU,
++ PD_CPU_NOCR },
++ { "ca53-cpu2", 0x200, 2, R8A7798_PD_CA53_CPU2, R8A7798_PD_CA53_SCU,
++ PD_CPU_NOCR },
++ { "ca53-cpu3", 0x200, 3, R8A7798_PD_CA53_CPU3, R8A7798_PD_CA53_SCU,
++ PD_CPU_NOCR },
++ { "cr7", 0x240, 0, R8A7798_PD_CR7, R8A7798_PD_ALWAYS_ON },
++
++ { "a3ir", 0x180, 0, R8A7798_PD_A3IR, R8A7798_PD_ALWAYS_ON },
++ { "a2ir0", 0x400, 0, R8A7798_PD_A2IR0, R8A7798_PD_A3IR },
++ { "a2ir1", 0x400, 1, R8A7798_PD_A2IR1, R8A7798_PD_A3IR },
++ { "a2ir2", 0x400, 2, R8A7798_PD_A2IR2, R8A7798_PD_A3IR },
++ { "a2ir3", 0x400, 3, R8A7798_PD_A2IR3, R8A7798_PD_A3IR },
++ { "a2ir4", 0x400, 4, R8A7798_PD_A2IR4, R8A7798_PD_A3IR },
++ { "a2ir5", 0x400, 5, R8A7798_PD_A2IR5, R8A7798_PD_A3IR },
++ { "a2sc0", 0x400, 6, R8A7798_PD_A2SC0, R8A7798_PD_A3IR },
++ { "a2sc1", 0x400, 7, R8A7798_PD_A2SC1, R8A7798_PD_A3IR },
++ { "a2sc2", 0x400, 8, R8A7798_PD_A2SC2, R8A7798_PD_A3IR },
++ { "a2sc3", 0x400, 9, R8A7798_PD_A2SC3, R8A7798_PD_A3IR },
++ { "a2sc4", 0x400, 10, R8A7798_PD_A2SC4, R8A7798_PD_A3IR },
++ { "a2pd0", 0x400, 11, R8A7798_PD_A2PD0, R8A7798_PD_A3IR },
++ { "a2pd1", 0x400, 12, R8A7798_PD_A2PD1, R8A7798_PD_A3IR },
++ { "a2cn", 0x400, 13, R8A7798_PD_A2CN, R8A7798_PD_A3IR },
++
++ { "a3vip", 0x2c0, 0, R8A7798_PD_A3VIP, R8A7798_PD_ALWAYS_ON },
++ { "a3vip1", 0x300, 0, R8A7798_PD_A3VIP1, R8A7798_PD_ALWAYS_ON },
++ { "a3vip2", 0x280, 0, R8A7798_PD_A3VIP2, R8A7798_PD_ALWAYS_ON },
++};
++
++const struct rcar_sysc_info r8a7798_sysc_info __initconst = {
++ .areas = r8a7798_areas,
++ .num_areas = ARRAY_SIZE(r8a7798_areas),
++};
+diff --git a/drivers/soc/renesas/rcar-rst.c b/drivers/soc/renesas/rcar-rst.c
+index bc3632b..8906817 100644
+--- a/drivers/soc/renesas/rcar-rst.c
++++ b/drivers/soc/renesas/rcar-rst.c
+@@ -43,6 +43,7 @@ struct rst_config {
+ { .compatible = "renesas,r8a7796-rst", .data = &rcar_rst_gen2 },
+ { .compatible = "renesas,r8a77965-rst", .data = &rcar_rst_gen2 },
+ { .compatible = "renesas,r8a7797-rst", .data = &rcar_rst_gen2 },
++ { .compatible = "renesas,r8a7798-rst", .data = &rcar_rst_gen2 },
+ { /* sentinel */ }
+ };
+
+diff --git a/drivers/soc/renesas/rcar-sysc.c b/drivers/soc/renesas/rcar-sysc.c
+index 1d5d440..bfde184 100644
+--- a/drivers/soc/renesas/rcar-sysc.c
++++ b/drivers/soc/renesas/rcar-sysc.c
+@@ -327,6 +327,9 @@ static void __init rcar_sysc_pd_setup(struct rcar_sysc_pd *pd)
+ #ifdef CONFIG_ARCH_R8A7797
+ { .compatible = "renesas,r8a7797-sysc", .data = &r8a7797_sysc_info },
+ #endif
++#ifdef CONFIG_ARCH_R8A7798
++ { .compatible = "renesas,r8a7798-sysc", .data = &r8a7798_sysc_info },
++#endif
+ { /* sentinel */ }
+ };
+
+diff --git a/drivers/soc/renesas/rcar-sysc.h b/drivers/soc/renesas/rcar-sysc.h
+index 1eb4e6d..dc58a58 100644
+--- a/drivers/soc/renesas/rcar-sysc.h
++++ b/drivers/soc/renesas/rcar-sysc.h
+@@ -62,4 +62,5 @@ struct rcar_sysc_info {
+ extern const struct rcar_sysc_info r8a7796_sysc_info;
+ extern const struct rcar_sysc_info r8a77965_sysc_info;
+ extern const struct rcar_sysc_info r8a7797_sysc_info;
++extern const struct rcar_sysc_info r8a7798_sysc_info;
+ #endif /* __SOC_RENESAS_RCAR_SYSC_H__ */
+diff --git a/drivers/soc/renesas/rcar_ems_ctrl.c b/drivers/soc/renesas/rcar_ems_ctrl.c
+index 388c570..516858d 100644
+--- a/drivers/soc/renesas/rcar_ems_ctrl.c
++++ b/drivers/soc/renesas/rcar_ems_ctrl.c
+@@ -30,8 +30,9 @@
+
+ #define EMS_THERMAL_ZONE_MAX 10
+
+-static const struct soc_device_attribute r8a7797[] = {
++static const struct soc_device_attribute r8a7797_8[] = {
+ { .soc_id = "r8a7797" },
++ { .soc_id = "r8a7798" },
+ { }
+ };
+
+@@ -274,7 +275,7 @@ static int __init rcar_ems_cpu_shutdown_init(void)
+
+ for_each_online_cpu(cpu) {
+ tmp_node = of_get_cpu_node(cpu, NULL);
+- if (soc_device_match(r8a7797)) {
++ if (soc_device_match(r8a7797_8)) {
+ if (!of_device_is_compatible(tmp_node, "arm,cortex-a53"))
+ continue;
+ }
+diff --git a/drivers/soc/renesas/renesas-soc.c b/drivers/soc/renesas/renesas-soc.c
+index 63f943d..b1fcae1 100644
+--- a/drivers/soc/renesas/renesas-soc.c
++++ b/drivers/soc/renesas/renesas-soc.c
+@@ -144,6 +144,11 @@ struct renesas_soc {
+ .id = 0x54,
+ };
+
++static const struct renesas_soc soc_rcar_v3h __initconst __maybe_unused = {
++ .family = &fam_rcar_gen3,
++ .id = 0x56,
++};
++
+ static const struct renesas_soc soc_shmobile_ag5 __initconst __maybe_unused = {
+ .family = &fam_shmobile,
+ .id = 0x37,
+@@ -199,6 +204,9 @@ struct renesas_soc {
+ #ifdef CONFIG_ARCH_R8A7797
+ { .compatible = "renesas,r8a7797", .data = &soc_rcar_v3m },
+ #endif
++#ifdef CONFIG_ARCH_R8A7798
++ { .compatible = "renesas,r8a7798", .data = &soc_rcar_v3h },
++#endif
+ #ifdef CONFIG_ARCH_SH73A0
+ { .compatible = "renesas,sh73a0", .data = &soc_shmobile_ag5 },
+ #endif
+diff --git a/drivers/spi/spi-sh-msiof.c b/drivers/spi/spi-sh-msiof.c
+index a2606fe..13fd706 100644
+--- a/drivers/spi/spi-sh-msiof.c
++++ b/drivers/spi/spi-sh-msiof.c
+@@ -217,7 +217,8 @@ static int msiof_rcar_is_gen3(struct device *dev)
+ return of_device_is_compatible(node, "renesas,msiof-r8a7795") ||
+ of_device_is_compatible(node, "renesas,msiof-r8a7796") ||
+ of_device_is_compatible(node, "renesas,msiof-r8a77965") ||
+- of_device_is_compatible(node, "renesas,msiof-r8a7797");
++ of_device_is_compatible(node, "renesas,msiof-r8a7797") ||
++ of_device_is_compatible(node, "renesas,msiof-r8a7798");
+ }
+
+ static u32 sh_msiof_read(struct sh_msiof_spi_priv *p, int reg_offs)
+@@ -1192,6 +1193,7 @@ static int sh_msiof_transfer_one(struct spi_master *master,
+ { .compatible = "renesas,msiof-r8a7796", .data = &r8a779x_data },
+ { .compatible = "renesas,msiof-r8a77965", .data = &r8a779x_data },
+ { .compatible = "renesas,msiof-r8a7797", .data = &r8a779x_data },
++ { .compatible = "renesas,msiof-r8a7798", .data = &r8a779x_data },
+ {},
+ };
+ MODULE_DEVICE_TABLE(of, sh_msiof_match);
+diff --git a/drivers/thermal/rcar_gen3_thermal.c b/drivers/thermal/rcar_gen3_thermal.c
+index a23dd44..90978c2 100644
+--- a/drivers/thermal/rcar_gen3_thermal.c
++++ b/drivers/thermal/rcar_gen3_thermal.c
+@@ -415,6 +415,11 @@ static int rcar_gen3_r8a7797_thermal_init(struct rcar_thermal_priv *priv)
+ return 0;
+ }
+
++static int rcar_gen3_r8a7798_thermal_init(struct rcar_thermal_priv *priv)
++{
++ return rcar_gen3_r8a7796_thermal_init(priv);
++}
++
+ /*
+ * Interrupt
+ */
+@@ -500,11 +505,16 @@ static int rcar_gen3_thermal_remove(struct platform_device *pdev)
+ .thermal_init = rcar_gen3_r8a7797_thermal_init,
+ };
+
++static const struct rcar_thermal_data r8a7798_data = {
++ .thermal_init = rcar_gen3_r8a7798_thermal_init,
++};
++
+ static const struct of_device_id rcar_thermal_dt_ids[] = {
+ { .compatible = "renesas,thermal-r8a7795", .data = &r8a7795_data},
+ { .compatible = "renesas,thermal-r8a7796", .data = &r8a7796_data},
+ { .compatible = "renesas,thermal-r8a77965", .data = &r8a7796_data},
+ { .compatible = "renesas,thermal-r8a7797", .data = &r8a7797_data},
++ { .compatible = "renesas,thermal-r8a7798", .data = &r8a7798_data},
+ {},
+ };
+ MODULE_DEVICE_TABLE(of, rcar_thermal_dt_ids);
+diff --git a/include/dt-bindings/clock/r8a7798-cpg-mssr.h b/include/dt-bindings/clock/r8a7798-cpg-mssr.h
+new file mode 100644
+index 0000000..3d85730
+--- /dev/null
++++ b/include/dt-bindings/clock/r8a7798-cpg-mssr.h
+@@ -0,0 +1,56 @@
++/*
++ * Copyright (C) 2018 Renesas Electronics Corp.
++ * Copyright (C) 2018 Cogent Embedded, Inc.
++ *
++ * This program is free software; you can redistribute it and/or modify
++ * it under the terms of the GNU General Public License as published by
++ * the Free Software Foundation; either version 2 of the License, or
++ * (at your option) any later version.
++ */
++#ifndef __DT_BINDINGS_CLOCK_R8A7798_CPG_MSSR_H__
++#define __DT_BINDINGS_CLOCK_R8A7798_CPG_MSSR_H__
++
++#include <dt-bindings/clock/renesas-cpg-mssr.h>
++
++/* r8a7798 CPG Core Clocks */
++#define R8A7798_CLK_Z2 0
++#define R8A7798_CLK_ZR 1
++#define R8A7798_CLK_ZTR 2
++#define R8A7798_CLK_ZTRD2 3
++#define R8A7798_CLK_ZT 4
++#define R8A7798_CLK_ZX 5
++#define R8A7798_CLK_S0D1 6
++#define R8A7798_CLK_S0D2 7
++#define R8A7798_CLK_S0D3 8
++#define R8A7798_CLK_S0D4 9
++#define R8A7798_CLK_S0D6 10
++#define R8A7798_CLK_S0D12 11
++#define R8A7798_CLK_S0D24 12
++#define R8A7798_CLK_S1D1 13
++#define R8A7798_CLK_S1D2 14
++#define R8A7798_CLK_S1D4 15
++#define R8A7798_CLK_S2D1 16
++#define R8A7798_CLK_S2D2 17
++#define R8A7798_CLK_S2D4 18
++#define R8A7798_CLK_S3D1 19
++#define R8A7798_CLK_S3D2 20
++#define R8A7798_CLK_S3D4 21
++#define R8A7798_CLK_LB 22
++#define R8A7798_CLK_CL 23
++#define R8A7798_CLK_ZB3 24
++#define R8A7798_CLK_ZB3D2 25
++#define R8A7798_CLK_ZB3D4 26
++#define R8A7798_CLK_SD0H 27
++#define R8A7798_CLK_SD0 28
++#define R8A7798_CLK_RPC 29
++#define R8A7798_CLK_RPCD2 30
++#define R8A7798_CLK_MSO 31
++#define R8A7798_CLK_CANFD 32
++#define R8A7798_CLK_CSI0 33
++#define R8A7798_CLK_CSIREF 34
++#define R8A7798_CLK_CP 35
++#define R8A7798_CLK_CPEX 36
++#define R8A7798_CLK_R 37
++#define R8A7798_CLK_OSC 38
++
++#endif /* __DT_BINDINGS_CLOCK_R8A7798_CPG_MSSR_H__ */
+diff --git a/include/dt-bindings/power/r8a7798-sysc.h b/include/dt-bindings/power/r8a7798-sysc.h
+new file mode 100644
+index 0000000..c10d60e
+--- /dev/null
++++ b/include/dt-bindings/power/r8a7798-sysc.h
+@@ -0,0 +1,46 @@
++/*
++ * Copyright (C) 2018 Renesas Electronics Corp.
++ * Copyright (C) 2018 Cogent Embedded, Inc.
++ *
++ * This program is free software; you can redistribute it and/or modify
++ * it under the terms of the GNU General Public License as published by
++ * the Free Software Foundation; version 2 of the License.
++ */
++#ifndef __DT_BINDINGS_POWER_R8A7798_SYSC_H__
++#define __DT_BINDINGS_POWER_R8A7798_SYSC_H__
++
++/*
++ * These power domain indices match the numbers of the interrupt bits
++ * representing the power areas in the various Interrupt Registers
++ * (e.g. SYSCISR, Interrupt Status Register)
++ */
++
++#define R8A7798_PD_A2SC2 0
++#define R8A7798_PD_A2SC3 1
++#define R8A7798_PD_A2SC4 2
++#define R8A7798_PD_A2PD0 3
++#define R8A7798_PD_A2PD1 4
++#define R8A7798_PD_CA53_CPU0 5
++#define R8A7798_PD_CA53_CPU1 6
++#define R8A7798_PD_CA53_CPU2 7
++#define R8A7798_PD_CA53_CPU3 8
++#define R8A7798_PD_A2CN 10
++#define R8A7798_PD_A3VIP 11
++#define R8A7798_PD_A2IR5 12
++#define R8A7798_PD_CR7 13
++#define R8A7798_PD_A2IR4 15
++#define R8A7798_PD_CA53_SCU 21
++#define R8A7798_PD_A2IR0 23
++#define R8A7798_PD_A3IR 24
++#define R8A7798_PD_A3VIP1 25
++#define R8A7798_PD_A3VIP2 26
++#define R8A7798_PD_A2IR1 27
++#define R8A7798_PD_A2IR2 28
++#define R8A7798_PD_A2IR3 29
++#define R8A7798_PD_A2SC0 30
++#define R8A7798_PD_A2SC1 31
++
++/* Always-on power area */
++#define R8A7798_PD_ALWAYS_ON 32
++
++#endif /* __DT_BINDINGS_POWER_R8A7798_SYSC_H__ */
+--
+1.9.1
+
diff --git a/bsp/meta-rcar/meta-rcar-gen3-adas/recipes-kernel/linux/linux-renesas/0052-soc-renesas-rcar-sysc-Add-workaround-for-A3-PD-issue.patch b/bsp/meta-rcar/meta-rcar-gen3-adas/recipes-kernel/linux/linux-renesas/0052-soc-renesas-rcar-sysc-Add-workaround-for-A3-PD-issue.patch
new file mode 100644
index 00000000..9cad5002
--- /dev/null
+++ b/bsp/meta-rcar/meta-rcar-gen3-adas/recipes-kernel/linux/linux-renesas/0052-soc-renesas-rcar-sysc-Add-workaround-for-A3-PD-issue.patch
@@ -0,0 +1,278 @@
+From 01fdcd06bd73807c03a6c8cf077fa53841861b58 Mon Sep 17 00:00:00 2001
+From: Shinyu Ninomiya <shinyu.ninomiya.pd@renesas.com>
+Date: Fri, 26 Jan 2018 21:38:58 +0900
+Subject: [PATCH] soc: renesas: rcar-sysc: Add workaround for A3 PD issue
+
+Before turning ON/OFF power domain of A3VIP0, A3VIP1, A3VIP2 the clock is supplied for BoschIP
+by deactivating MSTP assigned for BoschIP before. This issue is also occurred at A3IR.
+MSTP for impdes0 and impc0 should be deactivated before turning off A3IR domain.
+This implements workaround to implement the sequence above.
+
+Signed-off-by: Shinyu Ninomiya <shinyu.ninomiya.pd@renesas.com>
+---
+ drivers/soc/renesas/r8a7797-sysc.c | 3 +-
+ drivers/soc/renesas/r8a7798-sysc.c | 12 +++--
+ drivers/soc/renesas/rcar-sysc.c | 108 ++++++++++++++++++++++++++++++++++++-
+ drivers/soc/renesas/rcar-sysc.h | 6 +++
+ 4 files changed, 123 insertions(+), 6 deletions(-)
+
+diff --git a/drivers/soc/renesas/r8a7797-sysc.c b/drivers/soc/renesas/r8a7797-sysc.c
+index cde7d9e..5725ad0 100644
+--- a/drivers/soc/renesas/r8a7797-sysc.c
++++ b/drivers/soc/renesas/r8a7797-sysc.c
+@@ -24,7 +24,8 @@ static const struct rcar_sysc_area r8a7797_areas[] __initconst = {
+ { "ca53-cpu1", 0x200, 1, R8A7797_PD_CA53_CPU1, R8A7797_PD_CA53_SCU,
+ PD_CPU_NOCR },
+ { "cr7", 0x240, 0, R8A7797_PD_CR7, R8A7797_PD_ALWAYS_ON },
+- { "a3ir", 0x180, 0, R8A7797_PD_A3IR, R8A7797_PD_ALWAYS_ON },
++ { "a3ir", 0x180, 0, R8A7797_PD_A3IR, R8A7797_PD_ALWAYS_ON,
++ PD_WA_CLK, {"impram"} },
+ { "a2ir0", 0x400, 0, R8A7797_PD_A2IR0, R8A7797_PD_A3IR },
+ { "a2ir1", 0x400, 1, R8A7797_PD_A2IR1, R8A7797_PD_A3IR },
+ { "a2ir2", 0x400, 2, R8A7797_PD_A2IR2, R8A7797_PD_A3IR },
+diff --git a/drivers/soc/renesas/r8a7798-sysc.c b/drivers/soc/renesas/r8a7798-sysc.c
+index 128e79d..2affaa2 100644
+--- a/drivers/soc/renesas/r8a7798-sysc.c
++++ b/drivers/soc/renesas/r8a7798-sysc.c
+@@ -30,7 +30,8 @@ static const struct rcar_sysc_area r8a7798_areas[] __initconst = {
+ PD_CPU_NOCR },
+ { "cr7", 0x240, 0, R8A7798_PD_CR7, R8A7798_PD_ALWAYS_ON },
+
+- { "a3ir", 0x180, 0, R8A7798_PD_A3IR, R8A7798_PD_ALWAYS_ON },
++ { "a3ir", 0x180, 0, R8A7798_PD_A3IR, R8A7798_PD_ALWAYS_ON,
++ PD_WA_CLK, {"impram"} },
+ { "a2ir0", 0x400, 0, R8A7798_PD_A2IR0, R8A7798_PD_A3IR },
+ { "a2ir1", 0x400, 1, R8A7798_PD_A2IR1, R8A7798_PD_A3IR },
+ { "a2ir2", 0x400, 2, R8A7798_PD_A2IR2, R8A7798_PD_A3IR },
+@@ -46,9 +47,12 @@ static const struct rcar_sysc_area r8a7798_areas[] __initconst = {
+ { "a2pd1", 0x400, 12, R8A7798_PD_A2PD1, R8A7798_PD_A3IR },
+ { "a2cn", 0x400, 13, R8A7798_PD_A2CN, R8A7798_PD_A3IR },
+
+- { "a3vip", 0x2c0, 0, R8A7798_PD_A3VIP, R8A7798_PD_ALWAYS_ON },
+- { "a3vip1", 0x300, 0, R8A7798_PD_A3VIP1, R8A7798_PD_ALWAYS_ON },
+- { "a3vip2", 0x280, 0, R8A7798_PD_A3VIP2, R8A7798_PD_ALWAYS_ON },
++ { "a3vip", 0x2c0, 0, R8A7798_PD_A3VIP, R8A7798_PD_ALWAYS_ON,
++ PD_WA_CLK, {"disp"} },
++ { "a3vip1", 0x300, 0, R8A7798_PD_A3VIP1, R8A7798_PD_ALWAYS_ON,
++ PD_WA_CLK, {"umf", "smd_post", "smd_est", "smd_ps"} },
++ { "a3vip2", 0x280, 0, R8A7798_PD_A3VIP2, R8A7798_PD_ALWAYS_ON,
++ PD_WA_CLK, {"cle0", "cle1", "cle2", "cle3", "cle4"} },
+ };
+
+ const struct rcar_sysc_info r8a7798_sysc_info __initconst = {
+diff --git a/drivers/soc/renesas/rcar-sysc.c b/drivers/soc/renesas/rcar-sysc.c
+index bfde184..f3f18d0 100644
+--- a/drivers/soc/renesas/rcar-sysc.c
++++ b/drivers/soc/renesas/rcar-sysc.c
+@@ -20,6 +20,8 @@
+ #include <linux/syscore_ops.h>
+ #include <linux/io.h>
+ #include <linux/soc/renesas/rcar-sysc.h>
++#include <linux/clk.h>
++#include <linux/clk-provider.h>
+
+ #include "rcar-sysc.h"
+
+@@ -64,6 +66,7 @@ static DEFINE_SPINLOCK(rcar_sysc_lock); /* SMP CPUs + I/O devices */
+
+
+ static const char *to_pd_name(const struct rcar_sysc_ch *sysc_ch);
++static int rcar_sysc_wa_clk(const struct rcar_sysc_ch *sysc_ch, int en);
+
+ static int rcar_sysc_pwr_on_off(const struct rcar_sysc_ch *sysc_ch, bool on)
+ {
+@@ -110,6 +113,12 @@ static int rcar_sysc_power(const struct rcar_sysc_ch *sysc_ch, bool on)
+ int ret = 0;
+ int k;
+
++ ret = rcar_sysc_wa_clk(sysc_ch, 1);
++ if (ret) {
++ pr_err("%s: Failed to enable clock for workaround\n", to_pd_name(sysc_ch));
++ return ret;
++ }
++
+ spin_lock_irqsave(&rcar_sysc_lock, flags);
+
+ iowrite32(isr_mask, rcar_sysc_base + SYSCISCR);
+@@ -148,6 +157,8 @@ static int rcar_sysc_power(const struct rcar_sysc_ch *sysc_ch, bool on)
+ out:
+ spin_unlock_irqrestore(&rcar_sysc_lock, flags);
+
++ rcar_sysc_wa_clk(sysc_ch, 0);
++
+ pr_debug("sysc power %s domain %d: %08x -> %d\n", on ? "on" : "off",
+ sysc_ch->isr_bit, ioread32(rcar_sysc_base + SYSCISR), ret);
+ return ret;
+@@ -178,9 +189,35 @@ struct rcar_sysc_pd {
+ struct generic_pm_domain genpd;
+ struct rcar_sysc_ch ch;
+ unsigned int flags;
++ struct clk *wa_clk[RCAR_SYSC_MAX_WA_CLKS];
+ char name[0];
+ };
+
++static int rcar_sysc_wa_clk(const struct rcar_sysc_ch *sysc_ch, int en)
++{
++ int i, ret;
++ struct rcar_sysc_pd *pd = container_of(sysc_ch, struct rcar_sysc_pd, ch);
++
++ if (pd->flags & PD_WA_CLK) {
++ if (!(pd->flags & PD_WA_CLK_RDY))
++ return -EBUSY;
++
++ for (i = 0; i < RCAR_SYSC_MAX_WA_CLKS; i++) {
++ if (!pd->wa_clk[i])
++ break;
++
++ if (en) {
++ ret = clk_enable(pd->wa_clk[i]);
++ if (ret)
++ return ret;
++ } else
++ clk_disable(pd->wa_clk[i]);
++ }
++ }
++
++ return 0;
++}
++
+ static inline struct rcar_sysc_pd *to_rcar_pd(struct generic_pm_domain *d)
+ {
+ return container_of(d, struct rcar_sysc_pd, genpd);
+@@ -231,6 +268,7 @@ static void __init rcar_sysc_pd_setup(struct rcar_sysc_pd *pd)
+ struct generic_pm_domain *genpd = &pd->genpd;
+ const char *name = pd->genpd.name;
+ struct dev_power_governor *gov = &simple_qos_governor;
++ bool is_off = false;
+
+ if (pd->flags & PD_CPU) {
+ /*
+@@ -278,6 +316,12 @@ static void __init rcar_sysc_pd_setup(struct rcar_sysc_pd *pd)
+ goto finalize;
+ }
+
++ if (pd->flags & PD_NO_INIT_ON) {
++ is_off = rcar_sysc_power_is_off(&pd->ch);
++ pr_debug("%s: %s is initialy %s\n", __func__, genpd->name, is_off ? "off" : "on");
++ goto finalize;
++ }
++
+ if (!rcar_sysc_power_is_off(&pd->ch)) {
+ pr_debug("%s: %s is already powered\n", __func__, genpd->name);
+ goto finalize;
+@@ -286,7 +330,7 @@ static void __init rcar_sysc_pd_setup(struct rcar_sysc_pd *pd)
+ rcar_sysc_power_up(&pd->ch);
+
+ finalize:
+- pm_genpd_init(genpd, gov, false);
++ pm_genpd_init(genpd, gov, is_off);
+ }
+
+ static const struct of_device_id rcar_sysc_matches[] = {
+@@ -442,6 +486,12 @@ static int __init rcar_sysc_pd_init(void)
+ pd->ch.isr_bit = area->isr_bit;
+ pd->flags = area->flags;
+
++ if ((pd->flags & PD_WA_CLK) ||
++ (area->parent >= 0 && (container_of(domains->domains[area->parent],
++ struct rcar_sysc_pd, genpd)->flags & PD_NO_INIT_ON))
++ )
++ pd->flags |= PD_NO_INIT_ON;
++
+ rcar_sysc_pd_setup(pd);
+ if (area->parent >= 0)
+ pm_genpd_add_subdomain(domains->domains[area->parent],
+@@ -479,6 +529,62 @@ static int __init rcar_sysc_pd_init2(void)
+ postcore_initcall(rcar_sysc_pd_init2);
+ #endif
+
++#if IS_ENABLED(CONFIG_ARCH_R8A7797) || \
++ IS_ENABLED(CONFIG_ARCH_R8A7798)
++static int __init rcar_sysc_pd_init3(void)
++{
++ const struct rcar_sysc_info *info;
++ const struct of_device_id *match;
++ struct device_node *np;
++ unsigned int i, j;
++
++ np = of_find_matching_node_and_match(NULL, rcar_sysc_matches, &match);
++ if (!np)
++ return -ENODEV;
++
++ info = match->data;
++
++ for (i = 0; i < info->num_areas; i++) {
++ const struct rcar_sysc_area *area = &info->areas[i];
++ struct rcar_sysc_pd *pd = rcar_domains[i];
++
++ if (pd->flags & PD_WA_CLK) {
++ int err = 0;
++
++ for (j = 0; j < RCAR_SYSC_MAX_WA_CLKS; j++) {
++ struct clk *wa_clk;
++ const char *wa_clk_name = area->wa_clk_names[j];
++
++ if (!wa_clk_name)
++ break;
++
++ wa_clk = __clk_lookup(wa_clk_name);
++ if (!wa_clk) {
++ err = -ENODEV;
++ pr_err("%s: Unable to get clock %s for workaround\n", pd->name, wa_clk_name);
++ break;
++ }
++
++ err = clk_prepare(wa_clk);
++ if (err) {
++ pr_err("%s: Unable to prepare clock %s for workaround\n", pd->name, wa_clk_name);
++ break;
++ }
++
++ pd->wa_clk[j] = wa_clk;
++ }
++
++ if (!err)
++ pd->flags |= PD_WA_CLK_RDY;
++ }
++ }
++
++ return 0;
++}
++/* Should be called after cpg_mssr_driver is initialized */
++subsys_initcall_sync(rcar_sysc_pd_init3);
++#endif
++
+ void __init rcar_sysc_init(phys_addr_t base, u32 syscier)
+ {
+ u32 syscimr;
+diff --git a/drivers/soc/renesas/rcar-sysc.h b/drivers/soc/renesas/rcar-sysc.h
+index dc58a58..b991103 100644
+--- a/drivers/soc/renesas/rcar-sysc.h
++++ b/drivers/soc/renesas/rcar-sysc.h
+@@ -23,10 +23,15 @@
+ #define PD_BUSY BIT(3) /* Busy, for internal use only */
+ #define PD_ON_ONCE BIT(4) /* Turned on once at boot */
+
++#define PD_WA_CLK BIT(5) /* Use clocks for workaround */
++#define PD_WA_CLK_RDY BIT(6) /* Clock ready, for internal use only */
++#define PD_NO_INIT_ON BIT(7) /* Do not power on at initialization, for internal use */
++
+ #define PD_CPU_CR PD_CPU /* CPU area has CR (R-Car H1) */
+ #define PD_CPU_NOCR PD_CPU | PD_NO_CR /* CPU area lacks CR (R-Car Gen2/3) */
+ #define PD_ALWAYS_ON PD_NO_CR /* Always-on area */
+
++#define RCAR_SYSC_MAX_WA_CLKS 8
+
+ /*
+ * Description of a Power Area
+@@ -39,6 +44,7 @@ struct rcar_sysc_area {
+ u8 isr_bit; /* Bit in SYSCI*R */
+ int parent; /* -1 if none */
+ unsigned int flags; /* See PD_* */
++ const char* wa_clk_names[RCAR_SYSC_MAX_WA_CLKS]; /* Clocks needed by workaround for A3 PD issue */
+ };
+
+
+--
+2.7.4
+
diff --git a/bsp/meta-rcar/meta-rcar-gen3-adas/recipes-kernel/linux/linux-renesas/0062-IIO-lsm9ds0-add-IMU-driver.patch b/bsp/meta-rcar/meta-rcar-gen3-adas/recipes-kernel/linux/linux-renesas/0062-IIO-lsm9ds0-add-IMU-driver.patch
new file mode 100644
index 00000000..f108ad74
--- /dev/null
+++ b/bsp/meta-rcar/meta-rcar-gen3-adas/recipes-kernel/linux/linux-renesas/0062-IIO-lsm9ds0-add-IMU-driver.patch
@@ -0,0 +1,958 @@
+From cc9a9418d5147aba469ff9a69c17e13514021b5e Mon Sep 17 00:00:00 2001
+From: Andrey Gusakov <andrey.gusakov@cogentembedded.com>
+Date: Wed, 7 Jun 2017 13:35:52 +0300
+Subject: [PATCH 041/122] IIO: lsm9ds0: add IMU driver
+
+Taken from:
+https://github.com/mpod/kernel-playground
+
+Signed-off-by: Andrey Gusakov <andrey.gusakov@cogentembedded.com>
+---
+ drivers/iio/imu/Kconfig | 11 +
+ drivers/iio/imu/Makefile | 2 +
+ drivers/iio/imu/lsm9ds0.c | 898 ++++++++++++++++++++++++++++++++++++++++++++++
+ 3 files changed, 911 insertions(+)
+ create mode 100644 drivers/iio/imu/lsm9ds0.c
+
+diff --git a/drivers/iio/imu/Kconfig b/drivers/iio/imu/Kconfig
+index 156630a..6fd8490 100644
+--- a/drivers/iio/imu/Kconfig
++++ b/drivers/iio/imu/Kconfig
+@@ -38,6 +38,17 @@ config KMX61
+ To compile this driver as module, choose M here: the module will
+ be called kmx61.
+
++config LSM9DS0
++ tristate "ST LSM9DS0 9-axis IMU"
++ depends on I2C
++ select IIO_BUFFER
++ select IIO_TRIGGERED_BUFFER
++ help
++ Say Y here if you want to build a driver for ST LSM9DS0
++ system-in-package featuring a 3D digital linear acceleration
++ sensor, a 3D digital angular rate sensor, and a 3D digital magnetic
++ sensor.
++
+ source "drivers/iio/imu/inv_mpu6050/Kconfig"
+ source "drivers/iio/imu/st_lsm6dsx/Kconfig"
+
+diff --git a/drivers/iio/imu/Makefile b/drivers/iio/imu/Makefile
+index 68629c68..5ca2537 100644
+--- a/drivers/iio/imu/Makefile
++++ b/drivers/iio/imu/Makefile
+@@ -14,6 +14,8 @@ adis_lib-$(CONFIG_IIO_ADIS_LIB_BUFFER) += adis_trigger.o
+ adis_lib-$(CONFIG_IIO_ADIS_LIB_BUFFER) += adis_buffer.o
+ obj-$(CONFIG_IIO_ADIS_LIB) += adis_lib.o
+
++obj-$(CONFIG_LSM9DS0) += lsm9ds0.o
++
+ obj-y += bmi160/
+ obj-y += inv_mpu6050/
+
+diff --git a/drivers/iio/imu/lsm9ds0.c b/drivers/iio/imu/lsm9ds0.c
+new file mode 100644
+index 0000000..d1c81f6
+--- /dev/null
++++ b/drivers/iio/imu/lsm9ds0.c
+@@ -0,0 +1,898 @@
++/*
++ * lsm9ds0_gyro.c
++ *
++ * Copyright (C) 2016 Matija Podravec <matija_podravec@fastmail.fm>
++ *
++ * This program is free software: you can redistribute it and/or modify
++ * it under the terms of the GNU General Public License as published by
++ * the Free Software Foundation, either version 3 of the License, or
++ * (at your option) any later version.
++ *
++ * This program is distributed in the hope that it will be useful,
++ * but WITHOUT ANY WARRANTY; without even the implied warranty of
++ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
++ * GNU General Public License for more details.
++
++ * You should have received a copy of the GNU General Public License
++ * along with this program. If not, see <http://www.gnu.org/licenses/>.
++ *
++ *
++ * Driver for ST LSM9DS0 gyroscope, accelerometer, and magnetometer sensor.
++ *
++ */
++
++#include <linux/kernel.h>
++#include <linux/module.h>
++#include <linux/slab.h>
++#include <linux/i2c.h>
++#include <linux/bitops.h>
++#include <linux/iio/buffer.h>
++#include <linux/iio/iio.h>
++#include <linux/iio/sysfs.h>
++#include <linux/iio/triggered_buffer.h>
++#include <linux/iio/trigger_consumer.h>
++#include <linux/iio/kfifo_buf.h>
++
++#define LSM9DS0_WHO_AM_I_REG (0x0F)
++#define LSM9DS0_CTRL_REG1_G_REG (0x20)
++#define LSM9DS0_CTRL_REG2_G_REG (0x21)
++#define LSM9DS0_CTRL_REG3_G_REG (0x22)
++#define LSM9DS0_CTRL_REG4_G_REG (0x23)
++#define LSM9DS0_CTRL_REG5_G_REG (0x24)
++#define LSM9DS0_REFERENCE_G_REG (0x25)
++#define LSM9DS0_STATUS_REG_G_REG (0x27)
++#define LSM9DS0_OUT_X_L_G_REG (0x28)
++#define LSM9DS0_OUT_X_H_G_REG (0x29)
++#define LSM9DS0_OUT_Y_L_G_REG (0x2A)
++#define LSM9DS0_OUT_Y_H_G_REG (0x2B)
++#define LSM9DS0_OUT_Z_L_G_REG (0x2C)
++#define LSM9DS0_OUT_Z_H_G_REG (0x2D)
++#define LSM9DS0_FIFO_CTRL_REG_G_REG (0x2E)
++#define LSM9DS0_FIFO_SRC_REG_G_REG (0x2F)
++#define LSM9DS0_INT1_CFG_G_REG (0x30)
++#define LSM9DS0_INT1_SRC_G_REG (0x31)
++#define LSM9DS0_INT1_TSH_XH_G_REG (0x32)
++#define LSM9DS0_INT1_TSH_XL_G_REG (0x33)
++#define LSM9DS0_INT1_TSH_YH_G_REG (0x34)
++#define LSM9DS0_INT1_TSH_YL_G_REG (0x35)
++#define LSM9DS0_INT1_TSH_ZH_G_REG (0x36)
++#define LSM9DS0_INT1_TSH_ZL_G_REG (0x37)
++#define LSM9DS0_INT1_DURATION_G_REG (0x38)
++#define LSM9DS0_OUT_TEMP_L_XM_REG (0x05)
++#define LSM9DS0_OUT_TEMP_H_XM_REG (0x06)
++#define LSM9DS0_STATUS_REG_M_REG (0x07)
++#define LSM9DS0_OUT_X_L_M_REG (0x08)
++#define LSM9DS0_OUT_X_H_M_REG (0x09)
++#define LSM9DS0_OUT_Y_L_M_REG (0x0A)
++#define LSM9DS0_OUT_Y_H_M_REG (0x0B)
++#define LSM9DS0_OUT_Z_L_M_REG (0x0C)
++#define LSM9DS0_OUT_Z_H_M_REG (0x0D)
++#define LSM9DS0_INT_CTRL_REG_M_REG (0x12)
++#define LSM9DS0_INT_SRC_REG_M_REG (0x13)
++#define LSM9DS0_INT_THS_L_M_REG (0x14)
++#define LSM9DS0_INT_THS_H_M_REG (0x15)
++#define LSM9DS0_OFFSET_X_L_M_REG (0x16)
++#define LSM9DS0_OFFSET_X_H_M_REG (0x17)
++#define LSM9DS0_OFFSET_Y_L_M_REG (0x18)
++#define LSM9DS0_OFFSET_Y_H_M_REG (0x19)
++#define LSM9DS0_OFFSET_Z_L_M_REG (0x1A)
++#define LSM9DS0_OFFSET_Z_H_M_REG (0x1B)
++#define LSM9DS0_REFERENCE_X_REG (0x1C)
++#define LSM9DS0_REFERENCE_Y_REG (0x1D)
++#define LSM9DS0_REFERENCE_Z_REG (0x1E)
++#define LSM9DS0_CTRL_REG0_XM_REG (0x1F)
++#define LSM9DS0_CTRL_REG1_XM_REG (0x20)
++#define LSM9DS0_CTRL_REG2_XM_REG (0x21)
++#define LSM9DS0_CTRL_REG3_XM_REG (0x22)
++#define LSM9DS0_CTRL_REG4_XM_REG (0x23)
++#define LSM9DS0_CTRL_REG5_XM_REG (0x24)
++#define LSM9DS0_CTRL_REG6_XM_REG (0x25)
++#define LSM9DS0_CTRL_REG7_XM_REG (0x26)
++#define LSM9DS0_STATUS_REG_A_REG (0x27)
++#define LSM9DS0_OUT_X_L_A_REG (0x28)
++#define LSM9DS0_OUT_X_H_A_REG (0x29)
++#define LSM9DS0_OUT_Y_L_A_REG (0x2A)
++#define LSM9DS0_OUT_Y_H_A_REG (0x2B)
++#define LSM9DS0_OUT_Z_L_A_REG (0x2C)
++#define LSM9DS0_OUT_Z_H_A_REG (0x2D)
++#define LSM9DS0_FIFO_CTRL_REG_REG (0x2E)
++#define LSM9DS0_FIFO_SRC_REG_REG (0x2F)
++#define LSM9DS0_INT_GEN_1_REG_REG (0x30)
++#define LSM9DS0_INT_GEN_1_SRC_REG (0x31)
++#define LSM9DS0_INT_GEN_1_THS_REG (0x32)
++#define LSM9DS0_INT_GEN_1_DURATION_REG (0x33)
++#define LSM9DS0_INT_GEN_2_REG_REG (0x34)
++#define LSM9DS0_INT_GEN_2_SRC_REG (0x35)
++#define LSM9DS0_INT_GEN_2_THS_REG (0x36)
++#define LSM9DS0_INT_GEN_2_DURATION_REG (0x37)
++#define LSM9DS0_CLICK_CFG_REG (0x38)
++#define LSM9DS0_CLICK_SRC_REG (0x39)
++#define LSM9DS0_CLICK_THS_REG (0x3A)
++#define LSM9DS0_TIME_LIMIT_REG (0x3B)
++#define LSM9DS0_TIME_LATENCY_REG (0x3C)
++#define LSM9DS0_TIME_WINDOW_REG (0x3D)
++#define LSM9DS0_ACT_THS_REG (0x3E)
++#define LSM9DS0_ACT_DUR_REG (0x3F)
++
++#define LSM9DS0_GYRO_ODR_95HZ_VAL (0x00 << 6)
++#define LSM9DS0_GYRO_ODR_190HZ_VAL (0x01 << 6)
++#define LSM9DS0_GYRO_ODR_380HZ_VAL (0x02 << 6)
++#define LSM9DS0_GYRO_ODR_760HZ_VAL (0x03 << 6)
++
++#define LSM9DS0_ACCEL_POWER_DOWN (0x00 << 4)
++#define LSM9DS0_ACCEL_ODR_3_125HZ_VAL (0x01 << 4)
++#define LSM9DS0_ACCEL_ODR_6_25HZ_VAL (0x02 << 4)
++#define LSM9DS0_ACCEL_ODR_12_5HZ_VAL (0x03 << 4)
++#define LSM9DS0_ACCEL_ODR_25HZ_VAL (0x04 << 4)
++#define LSM9DS0_ACCEL_ODR_50HZ_VAL (0x05 << 4)
++#define LSM9DS0_ACCEL_ODR_100HZ_VAL (0x06 << 4)
++#define LSM9DS0_ACCEL_ODR_200HZ_VAL (0x07 << 4)
++#define LSM9DS0_ACCEL_ODR_400HZ_VAL (0x08 << 4)
++#define LSM9DS0_ACCEL_ODR_800HZ_VAL (0x09 << 4)
++#define LSM9DS0_ACCEL_ODR_1600HZ_VAL (0x0A << 4)
++
++#define LSM9DS0_ACCEL_FS_MASK (0x03 << 3)
++#define LSM9DS0_ACCEL_FS_2G_VAL (0x00 << 3)
++#define LSM9DS0_ACCEL_FS_4G_VAL (0x01 << 3)
++#define LSM9DS0_ACCEL_FS_6G_VAL (0x02 << 3)
++#define LSM9DS0_ACCEL_FS_8G_VAL (0x03 << 3)
++#define LSM9DS0_ACCEL_FS_16G_VAL (0x04 << 3)
++#define LSM9DS0_ACCEL_FS_2G_GAIN 61 /* ug/LSB */
++#define LSM9DS0_ACCEL_FS_4G_GAIN 122 /* ug/LSB */
++#define LSM9DS0_ACCEL_FS_6G_GAIN 183 /* ug/LSB */
++#define LSM9DS0_ACCEL_FS_8G_GAIN 244 /* ug/LSB */
++#define LSM9DS0_ACCEL_FS_16G_GAIN 732 /* ug/LSB */
++
++#define LSM9DS0_MAGN_ODR_3_125HZ_VAL (0x00 << 2)
++#define LSM9DS0_MAGN_ODR_6_25HZ_VAL (0x01 << 2)
++#define LSM9DS0_MAGN_ODR_12_5HZ_VAL (0x02 << 2)
++#define LSM9DS0_MAGN_ODR_25HZ_VAL (0x03 << 2)
++#define LSM9DS0_MAGN_ODR_50HZ_VAL (0x04 << 2)
++#define LSM9DS0_MAGN_ODR_100HZ_VAL (0x05 << 2)
++
++#define LSM9DS0_MAGN_FS_MASK (0x03 << 5)
++#define LSM9DS0_MAGN_FS_2GAUSS_VAL (0x00 << 5)
++#define LSM9DS0_MAGN_FS_4GAUSS_VAL (0x01 << 5)
++#define LSM9DS0_MAGN_FS_8GAUSS_VAL (0x02 << 5)
++#define LSM9DS0_MAGN_FS_12GAUSS_VAL (0x03 << 5)
++#define LSM9DS0_MAGN_FS_2GAUSS_GAIN 80 /* ugauss/LSB */
++#define LSM9DS0_MAGN_FS_4GAUSS_GAIN 160 /* ugauss/LSB */
++#define LSM9DS0_MAGN_FS_8GAUSS_GAIN 320 /* ugauss/LSB */
++#define LSM9DS0_MAGN_FS_12GAUSS_GAIN 480 /* ugauss/LSB */
++
++#define LSM9DS0_GYRO_FS_MASK (0x03 << 4)
++#define LSM9DS0_GYRO_FS_245DPS_VAL (0x00 << 4)
++#define LSM9DS0_GYRO_FS_500DPS_VAL (0x01 << 4)
++#define LSM9DS0_GYRO_FS_2000DPS_VAL (0x02 << 4)
++#define LSM9DS0_GYRO_FS_245DPS_GAIN 8750 /* udps/LSB */
++#define LSM9DS0_GYRO_FS_500DPS_GAIN 17500 /* udps/LSB */
++#define LSM9DS0_GYRO_FS_2000DPS_GAIN 70000 /* udps/LSB */
++
++#define LSM9DS0_GYRO_X_EN BIT(1)
++#define LSM9DS0_GYRO_Y_EN BIT(0)
++#define LSM9DS0_GYRO_Z_EN BIT(2)
++#define LSM9DS0_GYRO_POWER_DOWN (0x00 << 3)
++#define LSM9DS0_GYRO_NORMAL_MODE BIT(3)
++#define LSM9DS0_ACCEL_X_EN BIT(0)
++#define LSM9DS0_ACCEL_Y_EN BIT(1)
++#define LSM9DS0_ACCEL_Z_EN BIT(2)
++#define LSM9DS0_TEMP_EN BIT(7)
++#define LSM9DS0_MAGN_LOW_RES_VAL (0x00 << 5)
++#define LSM9DS0_MAGN_HIGH_RES_VAL (0x03 << 5)
++#define LSM9DS0_MAGN_POWER_DOWN (0x02)
++#define LSM9DS0_MAGN_CONT_CONV_MODE (0x00)
++#define LSM9DS0_MAGN_SINGLE_CONV_MODE (0x01)
++
++#define LSM9DS0_GYRO_ID 0xD4
++#define LSM9DS0_ACCEL_MAGN_ID 0x49
++
++enum { SCAN_INDEX_X, SCAN_INDEX_Y, SCAN_INDEX_Z };
++enum {
++ SCAN_INDEX_ACCEL_X, SCAN_INDEX_ACCEL_Y, SCAN_INDEX_ACCEL_Z,
++ SCAN_INDEX_MAGN_X, SCAN_INDEX_MAGN_Y, SCAN_INDEX_MAGN_Z
++};
++enum { GYRO, ACCEL_MAGN };
++
++struct lsm9ds0_data {
++ struct i2c_client *client;
++ struct mutex lock;
++ int sensor_type;
++ int gyro_scale;
++ int accel_scale;
++ int magn_scale;
++};
++
++struct sensor_fs_avl {
++ unsigned int num;
++ u8 value;
++ unsigned int gain;
++};
++
++static const struct sensor_fs_avl lsm9ds0_gyro_fs_avl[3] = {
++ {245, LSM9DS0_GYRO_FS_245DPS_VAL, LSM9DS0_GYRO_FS_245DPS_GAIN},
++ {500, LSM9DS0_GYRO_FS_500DPS_VAL, LSM9DS0_GYRO_FS_500DPS_GAIN},
++ {2000, LSM9DS0_GYRO_FS_2000DPS_VAL, LSM9DS0_GYRO_FS_2000DPS_GAIN},
++};
++
++static const struct sensor_fs_avl lsm9ds0_accel_fs_avl[5] = {
++ {2, LSM9DS0_ACCEL_FS_2G_VAL, LSM9DS0_ACCEL_FS_2G_GAIN},
++ {4, LSM9DS0_ACCEL_FS_4G_VAL, LSM9DS0_ACCEL_FS_4G_GAIN},
++ {6, LSM9DS0_ACCEL_FS_6G_VAL, LSM9DS0_ACCEL_FS_6G_GAIN},
++ {8, LSM9DS0_ACCEL_FS_8G_VAL, LSM9DS0_ACCEL_FS_8G_GAIN},
++ {16, LSM9DS0_ACCEL_FS_16G_VAL, LSM9DS0_ACCEL_FS_16G_GAIN},
++};
++
++static const struct sensor_fs_avl lsm9ds0_magn_fs_avl[4] = {
++ {2, LSM9DS0_MAGN_FS_2GAUSS_VAL, LSM9DS0_MAGN_FS_2GAUSS_GAIN},
++ {4, LSM9DS0_MAGN_FS_4GAUSS_VAL, LSM9DS0_MAGN_FS_4GAUSS_GAIN},
++ {8, LSM9DS0_MAGN_FS_8GAUSS_VAL, LSM9DS0_MAGN_FS_8GAUSS_GAIN},
++ {12, LSM9DS0_MAGN_FS_12GAUSS_VAL, LSM9DS0_MAGN_FS_12GAUSS_GAIN},
++};
++
++static ssize_t lsm9ds0_show_scale_avail(struct device *dev,
++ struct device_attribute *attr, char *buf)
++{
++ //struct iio_dev *indio_dev = dev_to_iio_dev(dev);
++ //struct lsm9ds0_data *data = iio_priv(indio_dev);
++ size_t len = 0;
++ int n;
++ const struct sensor_fs_avl (*avl)[];
++
++ if (strcmp(attr->attr.name, "in_gyro_scale_available") == 0) {
++ avl = &lsm9ds0_gyro_fs_avl;
++ n = ARRAY_SIZE(lsm9ds0_gyro_fs_avl);
++ } else if (strcmp(attr->attr.name, "in_accel_scale_available") == 0) {
++ avl = &lsm9ds0_accel_fs_avl;
++ n = ARRAY_SIZE(lsm9ds0_accel_fs_avl);
++ } else if (strcmp(attr->attr.name, "in_magn_scale_available") == 0) {
++ avl = &lsm9ds0_magn_fs_avl;
++ n = ARRAY_SIZE(lsm9ds0_magn_fs_avl);
++ } else {
++ return -EINVAL;
++ }
++
++ while (n-- > 0)
++ len += scnprintf(buf + len, PAGE_SIZE - len,
++ "0.%06u ", (*avl)[n].gain);
++ buf[len - 1] = '\n';
++
++ return len;
++}
++
++static IIO_DEVICE_ATTR(in_accel_scale_available, S_IRUGO,
++ lsm9ds0_show_scale_avail, NULL, 0);
++static IIO_DEVICE_ATTR(in_magn_scale_available, S_IRUGO,
++ lsm9ds0_show_scale_avail, NULL, 0);
++static IIO_DEVICE_ATTR(in_gyro_scale_available, S_IRUGO,
++ lsm9ds0_show_scale_avail, NULL, 0);
++
++static struct attribute *lsm9ds0_gyro_attributes[] = {
++ &iio_dev_attr_in_gyro_scale_available.dev_attr.attr,
++ NULL
++};
++
++static struct attribute *lsm9ds0_accel_magn_attributes[] = {
++ &iio_dev_attr_in_accel_scale_available.dev_attr.attr,
++ &iio_dev_attr_in_magn_scale_available.dev_attr.attr,
++ NULL
++};
++
++static const struct attribute_group lsm9ds0_gyro_group = {
++ .attrs = lsm9ds0_gyro_attributes,
++};
++
++static const struct attribute_group lsm9ds0_accel_magn_group = {
++ .attrs = lsm9ds0_accel_magn_attributes,
++};
++
++static const struct iio_buffer_setup_ops lsm9ds0_buffer_setup_ops = {
++ .postenable = &iio_triggered_buffer_postenable,
++ .predisable = &iio_triggered_buffer_predisable,
++};
++
++static const struct iio_chan_spec lsm9ds0_gyro_channels[] = {
++ {
++ .type = IIO_ANGL_VEL,
++ .info_mask_separate = BIT(IIO_CHAN_INFO_RAW),
++ .info_mask_shared_by_type = BIT(IIO_CHAN_INFO_SCALE),
++ .modified = 1,
++ .channel2 = IIO_MOD_X,
++ .scan_index = SCAN_INDEX_X,
++ .scan_type = {
++ .sign = 's',
++ .realbits = 16,
++ .storagebits = 16,
++ .shift = 0,
++ .endianness = IIO_LE,
++ },
++ }, {
++ .type = IIO_ANGL_VEL,
++ .info_mask_separate = BIT(IIO_CHAN_INFO_RAW),
++ .info_mask_shared_by_type = BIT(IIO_CHAN_INFO_SCALE),
++ .modified = 1,
++ .channel2 = IIO_MOD_Y,
++ .scan_index = SCAN_INDEX_Y,
++ .scan_type = {
++ .sign = 's',
++ .realbits = 16,
++ .storagebits = 16,
++ .shift = 0,
++ .endianness = IIO_LE,
++ },
++ }, {
++ .type = IIO_ANGL_VEL,
++ .info_mask_separate = BIT(IIO_CHAN_INFO_RAW),
++ .info_mask_shared_by_type = BIT(IIO_CHAN_INFO_SCALE),
++ .modified = 1,
++ .channel2 = IIO_MOD_Z,
++ .scan_index = SCAN_INDEX_Z,
++ .scan_type = {
++ .sign = 's',
++ .realbits = 16,
++ .storagebits = 16,
++ .shift = 0,
++ .endianness = IIO_LE,
++ },
++ },
++ IIO_CHAN_SOFT_TIMESTAMP(3),
++};
++
++static const struct iio_chan_spec lsm9ds0_accel_magn_channels[] = {
++ {
++ .type = IIO_ACCEL,
++ .info_mask_separate = BIT(IIO_CHAN_INFO_RAW),
++ .info_mask_shared_by_type = BIT(IIO_CHAN_INFO_SCALE),
++ .modified = 1,
++ .channel2 = IIO_MOD_X,
++ .scan_index = SCAN_INDEX_ACCEL_X,
++ .scan_type = {
++ .sign = 's',
++ .realbits = 16,
++ .storagebits = 16,
++ .shift = 0,
++ .endianness = IIO_LE,
++ },
++ }, {
++ .type = IIO_ACCEL,
++ .info_mask_separate = BIT(IIO_CHAN_INFO_RAW),
++ .info_mask_shared_by_type = BIT(IIO_CHAN_INFO_SCALE),
++ .modified = 1,
++ .channel2 = IIO_MOD_Y,
++ .scan_index = SCAN_INDEX_ACCEL_Y,
++ .scan_type = {
++ .sign = 's',
++ .realbits = 16,
++ .storagebits = 16,
++ .shift = 0,
++ .endianness = IIO_LE,
++ },
++ }, {
++ .type = IIO_ACCEL,
++ .info_mask_separate = BIT(IIO_CHAN_INFO_RAW),
++ .info_mask_shared_by_type = BIT(IIO_CHAN_INFO_SCALE),
++ .modified = 1,
++ .channel2 = IIO_MOD_Z,
++ .scan_index = SCAN_INDEX_ACCEL_Z,
++ .scan_type = {
++ .sign = 's',
++ .realbits = 16,
++ .storagebits = 16,
++ .shift = 0,
++ .endianness = IIO_LE,
++ },
++ }, {
++ .type = IIO_MAGN,
++ .info_mask_separate = BIT(IIO_CHAN_INFO_RAW),
++ .info_mask_shared_by_type = BIT(IIO_CHAN_INFO_SCALE),
++ .modified = 1,
++ .channel2 = IIO_MOD_X,
++ .scan_index = SCAN_INDEX_MAGN_X,
++ .scan_type = {
++ .sign = 's',
++ .realbits = 16,
++ .storagebits = 16,
++ .shift = 0,
++ .endianness = IIO_LE,
++ },
++ }, {
++ .type = IIO_MAGN,
++ .info_mask_separate = BIT(IIO_CHAN_INFO_RAW),
++ .info_mask_shared_by_type = BIT(IIO_CHAN_INFO_SCALE),
++ .modified = 1,
++ .channel2 = IIO_MOD_Y,
++ .scan_index = SCAN_INDEX_MAGN_Y,
++ .scan_type = {
++ .sign = 's',
++ .realbits = 16,
++ .storagebits = 16,
++ .shift = 0,
++ .endianness = IIO_LE,
++ },
++ }, {
++ .type = IIO_MAGN,
++ .info_mask_separate = BIT(IIO_CHAN_INFO_RAW),
++ .info_mask_shared_by_type = BIT(IIO_CHAN_INFO_SCALE),
++ .modified = 1,
++ .channel2 = IIO_MOD_Z,
++ .scan_index = SCAN_INDEX_MAGN_Z,
++ .scan_type = {
++ .sign = 's',
++ .realbits = 16,
++ .storagebits = 16,
++ .shift = 0,
++ .endianness = IIO_LE,
++ },
++ },
++ IIO_CHAN_SOFT_TIMESTAMP(6),
++};
++
++static int lsm9ds0_read_measurements(struct i2c_client *client,
++ u8 reg_address, s16 *x, s16 *y, s16 *z)
++{
++ int ret;
++ u8 buf[6] = {0};
++
++ buf[0] = 0x80 | reg_address;
++ ret = i2c_master_send(client, buf, 1);
++ if (ret < 0)
++ return ret;
++
++ ret = i2c_master_recv(client, buf, 6);
++ if (ret < 0)
++ return ret;
++
++ *x = (buf[1] << 8) | buf[0];
++ *y = (buf[3] << 8) | buf[2];
++ *z = (buf[5] << 8) | buf[4];
++ return ret;
++}
++
++static int lsm9ds0_read_raw(struct iio_dev *iio_dev,
++ struct iio_chan_spec const *channel,
++ int *val, int *val2, long mask)
++{
++ struct lsm9ds0_data *data = iio_priv(iio_dev);
++ int err = 0;
++ s16 x = 0, y = 0, z = 0;
++ int scale = 0;
++
++ switch (mask) {
++ case IIO_CHAN_INFO_RAW:
++ mutex_lock(&data->lock);
++ switch (channel->type) {
++ case IIO_ANGL_VEL:
++ err = lsm9ds0_read_measurements(data->client,
++ LSM9DS0_OUT_X_L_G_REG, &x, &y, &z);
++ scale = data->gyro_scale;
++ break;
++ case IIO_ACCEL:
++ err = lsm9ds0_read_measurements(data->client,
++ LSM9DS0_OUT_X_L_A_REG, &x, &y, &z);
++ scale = data->accel_scale;
++ break;
++ case IIO_MAGN:
++ err = lsm9ds0_read_measurements(data->client,
++ LSM9DS0_OUT_X_L_M_REG, &x, &y, &z);
++ scale = data->magn_scale;
++ break;
++ default:
++ return -EINVAL;
++ }
++ mutex_unlock(&data->lock);
++ if (err < 0)
++ goto read_error;
++
++ switch (channel->channel2) {
++ case IIO_MOD_X:
++ *val = x;
++ break;
++ case IIO_MOD_Y:
++ *val = y;
++ break;
++ case IIO_MOD_Z:
++ *val = z;
++ break;
++ }
++ return IIO_VAL_INT;
++ case IIO_CHAN_INFO_SCALE:
++ *val = 0;
++ switch (channel->type) {
++ case IIO_ANGL_VEL:
++ *val2 = data->gyro_scale;
++ break;
++ case IIO_ACCEL:
++ *val2 = data->accel_scale;
++ break;
++ case IIO_MAGN:
++ *val2 = data->magn_scale;
++ break;
++ default:
++ return -EINVAL;
++ }
++ return IIO_VAL_INT_PLUS_MICRO;
++ default:
++ return -EINVAL;
++ }
++
++read_error:
++ return err;
++}
++
++static int lsm9ds0_write_config(struct i2c_client *client,
++ u8 reg_address, u8 mask, u8 value)
++{
++ u8 reg;
++ s32 ret;
++ ret = i2c_smbus_read_byte_data(client, reg_address);
++ if (ret < 0)
++ return -EINVAL;
++
++ reg = (u8)ret;
++ reg &= ~mask;
++ reg |= value;
++
++ ret = i2c_smbus_write_byte_data(client, reg_address, reg);
++
++ return ret;
++}
++
++static int lsm9ds0_write_raw(struct iio_dev *indio_dev,
++ struct iio_chan_spec const *channel,
++ int val, int val2, long mask)
++{
++ struct lsm9ds0_data *data = iio_priv(indio_dev);
++ struct i2c_client *client = data->client;
++ const struct sensor_fs_avl (*avl)[];
++ int n, i, ret;
++ u8 reg_address, reg_mask, new_value;
++ int *scale_in_data;
++
++ mutex_lock(&data->lock);
++ switch (mask) {
++ case IIO_CHAN_INFO_SCALE:
++ dev_info(&client->dev, "Vals %d %d\n", val, val2);
++ switch (channel->type) {
++ case IIO_ANGL_VEL:
++ avl = &lsm9ds0_gyro_fs_avl;
++ n = ARRAY_SIZE(lsm9ds0_gyro_fs_avl);
++ reg_address = LSM9DS0_CTRL_REG4_G_REG;
++ reg_mask = LSM9DS0_GYRO_FS_MASK;
++ scale_in_data = &(data->gyro_scale);
++ break;
++ case IIO_ACCEL:
++ avl = &lsm9ds0_accel_fs_avl;
++ n = ARRAY_SIZE(lsm9ds0_accel_fs_avl);
++ reg_address = LSM9DS0_CTRL_REG2_XM_REG;
++ reg_mask = LSM9DS0_ACCEL_FS_MASK;
++ scale_in_data = &(data->accel_scale);
++ break;
++ case IIO_MAGN:
++ avl = &lsm9ds0_magn_fs_avl;
++ n = ARRAY_SIZE(lsm9ds0_magn_fs_avl);
++ reg_address = LSM9DS0_CTRL_REG6_XM_REG;
++ reg_mask = LSM9DS0_MAGN_FS_MASK;
++ scale_in_data = &(data->magn_scale);
++ break;
++ default:
++ ret = -EINVAL;
++ goto done;
++ }
++ ret = -EINVAL;
++ for (i = 0; i < n; i++) {
++ if ((*avl)[i].gain == val2) {
++ ret = 0;
++ new_value = (*avl)[i].value;
++ break;
++ }
++ }
++ if (ret < 0)
++ goto done;
++
++ ret = lsm9ds0_write_config(client, reg_address, reg_mask, new_value);
++ if (ret < 0)
++ goto done;
++
++ *scale_in_data = (*avl)[i].gain;
++ break;
++ default:
++ ret = -EINVAL;
++ }
++
++done:
++ mutex_unlock(&data->lock);
++ return ret;
++}
++
++static irqreturn_t lsm9ds0_trigger_h(int irq, void *p)
++{
++ struct iio_poll_func *pf = p;
++ struct iio_dev *indio_dev = pf->indio_dev;
++ struct lsm9ds0_data *data = iio_priv(indio_dev);
++ u32 *buf_data;
++ int i, j;
++ s16 x1, y1, z1, x2, y2, z2;
++ int err;
++
++ buf_data = kmalloc(indio_dev->scan_bytes, GFP_KERNEL);
++ if (!buf_data)
++ goto done;
++
++ mutex_lock(&data->lock);
++ if (!bitmap_empty(indio_dev->active_scan_mask, indio_dev->masklength)) {
++
++ if (data->sensor_type == GYRO) {
++ err = lsm9ds0_read_measurements(data->client,
++ LSM9DS0_OUT_X_L_G_REG, &x1, &y1, &z1);
++ if (err < 0)
++ goto free_buf;
++ } else if (data->sensor_type == ACCEL_MAGN) {
++ err = lsm9ds0_read_measurements(data->client,
++ LSM9DS0_OUT_X_L_A_REG, &x1, &y1, &z1);
++ if (err < 0)
++ goto free_buf;
++ err = lsm9ds0_read_measurements(data->client,
++ LSM9DS0_OUT_X_L_M_REG, &x2, &y2, &z2);
++ if (err < 0)
++ goto free_buf;
++ } else
++ goto free_buf;
++
++ for (i = 0, j = 0;
++ i < bitmap_weight(indio_dev->active_scan_mask, indio_dev->masklength);
++ i++, j++) {
++ j = find_next_bit(indio_dev->active_scan_mask, indio_dev->masklength, j);
++
++ if (data->sensor_type == GYRO) {
++ switch (j) {
++ case SCAN_INDEX_X:
++ buf_data[i] = x1;
++ break;
++ case SCAN_INDEX_Y:
++ buf_data[i] = y1;
++ break;
++ case SCAN_INDEX_Z:
++ buf_data[i] = z1;
++ break;
++ default:
++ break;
++ }
++ } else {
++ switch (j) {
++ case SCAN_INDEX_ACCEL_X:
++ buf_data[i] = x1;
++ break;
++ case SCAN_INDEX_ACCEL_Y:
++ buf_data[i] = y1;
++ break;
++ case SCAN_INDEX_ACCEL_Z:
++ buf_data[i] = z1;
++ break;
++ case SCAN_INDEX_MAGN_X:
++ buf_data[i] = x2;
++ break;
++ case SCAN_INDEX_MAGN_Y:
++ buf_data[i] = y2;
++ break;
++ case SCAN_INDEX_MAGN_Z:
++ buf_data[i] = z2;
++ break;
++ default:
++ break;
++ }
++ }
++ }
++ }
++
++ iio_push_to_buffers_with_timestamp(indio_dev, buf_data, iio_get_time_ns(indio_dev));
++
++free_buf:
++ kfree(buf_data);
++ mutex_unlock(&data->lock);
++
++done:
++ iio_trigger_notify_done(indio_dev->trig);
++
++ return IRQ_HANDLED;
++}
++
++static const struct iio_info lsm9ds0_gyro_info = {
++ .attrs = &lsm9ds0_gyro_group,
++ .read_raw = lsm9ds0_read_raw,
++ .write_raw = lsm9ds0_write_raw,
++ .driver_module = THIS_MODULE,
++};
++
++static const struct iio_info lsm9ds0_accel_magn_info = {
++ .attrs = &lsm9ds0_accel_magn_group,
++ .read_raw = lsm9ds0_read_raw,
++ .write_raw = lsm9ds0_write_raw,
++ .driver_module = THIS_MODULE,
++};
++
++static int lsm9ds0_gyro_init(struct i2c_client *client)
++{
++ int ret;
++ struct iio_dev *indio_dev;
++ struct lsm9ds0_data *data;
++
++ ret = i2c_smbus_write_byte_data(client, LSM9DS0_CTRL_REG1_G_REG,
++ LSM9DS0_GYRO_NORMAL_MODE | LSM9DS0_GYRO_X_EN |
++ LSM9DS0_GYRO_Y_EN | LSM9DS0_GYRO_Z_EN);
++ if (ret < 0) {
++ dev_err(&client->dev, "Failed to write control register 5.\n");
++ return ret;
++ }
++ ret = i2c_smbus_write_byte_data(client, LSM9DS0_CTRL_REG4_G_REG,
++ LSM9DS0_GYRO_FS_245DPS_VAL);
++ if (ret < 0) {
++ dev_err(&client->dev, "Failed to write control register 4.\n");
++ return ret;
++ }
++
++ indio_dev = i2c_get_clientdata(client);
++ data = iio_priv(indio_dev);
++
++ data->gyro_scale = LSM9DS0_GYRO_FS_245DPS_GAIN;
++
++ return 0;
++}
++
++static int lsm9ds0_accel_magn_init(struct i2c_client *client)
++{
++ int ret;
++ struct iio_dev *indio_dev;
++ struct lsm9ds0_data *data;
++
++ ret = i2c_smbus_write_byte_data(client, LSM9DS0_CTRL_REG1_XM_REG,
++ LSM9DS0_ACCEL_ODR_100HZ_VAL | LSM9DS0_ACCEL_X_EN |
++ LSM9DS0_ACCEL_Y_EN | LSM9DS0_ACCEL_Z_EN);
++ if (ret < 0) {
++ dev_err(&client->dev, "Failed to write control register 1.\n");
++ return ret;
++ }
++ ret = i2c_smbus_write_byte_data(client, LSM9DS0_CTRL_REG5_XM_REG,
++ LSM9DS0_TEMP_EN | LSM9DS0_MAGN_HIGH_RES_VAL | LSM9DS0_MAGN_ODR_50HZ_VAL);
++ if (ret < 0) {
++ dev_err(&client->dev, "Failed to write control register 5.\n");
++ return ret;
++ }
++ ret = i2c_smbus_write_byte_data(client, LSM9DS0_CTRL_REG7_XM_REG,
++ LSM9DS0_MAGN_CONT_CONV_MODE);
++ if (ret < 0) {
++ dev_err(&client->dev, "Failed to write control register 7.\n");
++ return ret;
++ }
++ ret = i2c_smbus_write_byte_data(client, LSM9DS0_CTRL_REG2_XM_REG,
++ LSM9DS0_ACCEL_FS_2G_VAL);
++ if (ret < 0) {
++ dev_err(&client->dev, "Failed to write control register 2.\n");
++ return ret;
++ }
++ ret = i2c_smbus_write_byte_data(client, LSM9DS0_CTRL_REG6_XM_REG,
++ LSM9DS0_MAGN_FS_2GAUSS_VAL);
++ if (ret < 0) {
++ dev_err(&client->dev, "Failed to write control register 6.\n");
++ return ret;
++ }
++
++ indio_dev = i2c_get_clientdata(client);
++ data = iio_priv(indio_dev);
++
++ data->accel_scale = LSM9DS0_ACCEL_FS_2G_GAIN;
++ data->magn_scale = LSM9DS0_MAGN_FS_2GAUSS_GAIN;
++
++ return 0;
++}
++
++static int lsm9ds0_probe(struct i2c_client *client,
++ const struct i2c_device_id *id)
++{
++ struct iio_dev *indio_dev;
++ struct lsm9ds0_data *data;
++ int sensor_type;
++ int ret;
++
++
++ if (!i2c_check_functionality(client->adapter, I2C_FUNC_SMBUS_WORD_DATA)) {
++ ret = -ENODEV;
++ goto error_ret;
++ }
++
++ ret = i2c_smbus_read_byte_data(client, LSM9DS0_WHO_AM_I_REG);
++ if (ret < 0) {
++ ret = -EINVAL;
++ goto error_ret;
++ }
++ if (ret == LSM9DS0_GYRO_ID) {
++ dev_info(&client->dev, "Gyroscope found.\n");
++ sensor_type = GYRO;
++ } else if (ret == LSM9DS0_ACCEL_MAGN_ID) {
++ dev_info(&client->dev, "Accelerometer and magnetometer found.\n");
++ sensor_type = ACCEL_MAGN;
++ } else {
++ dev_err(&client->dev, "No LSM9DS0 sensor found.\n");
++ ret = -ENODEV;
++ goto error_ret;
++ }
++
++ indio_dev = devm_iio_device_alloc(&client->dev, sizeof(*data));
++ if (!indio_dev) {
++ ret = -ENOMEM;
++ goto error_ret;
++ }
++
++ data = iio_priv(indio_dev);
++ mutex_init(&data->lock);
++ i2c_set_clientdata(client, indio_dev);
++ data->client = client;
++ data->sensor_type = sensor_type;
++
++ indio_dev->dev.parent = &client->dev;
++ indio_dev->name = dev_name(&client->dev);
++ indio_dev->modes = INDIO_DIRECT_MODE | INDIO_BUFFER_TRIGGERED;
++
++
++ if (sensor_type == GYRO) {
++ ret = lsm9ds0_gyro_init(client);
++ indio_dev->info = &lsm9ds0_gyro_info;
++ indio_dev->channels = lsm9ds0_gyro_channels;
++ indio_dev->num_channels = ARRAY_SIZE(lsm9ds0_gyro_channels);
++ } else {
++ ret = lsm9ds0_accel_magn_init(client);
++ indio_dev->info = &lsm9ds0_accel_magn_info;
++ indio_dev->channels = lsm9ds0_accel_magn_channels;
++ indio_dev->num_channels = ARRAY_SIZE(lsm9ds0_accel_magn_channels);
++ }
++ if (ret < 0)
++ goto error_free_device;
++
++ ret = devm_iio_triggered_buffer_setup(&client->dev,
++ indio_dev,
++ NULL,
++ &lsm9ds0_trigger_h,
++ &lsm9ds0_buffer_setup_ops);
++ if (ret < 0)
++ goto error_free_device;
++
++ ret = iio_device_register(indio_dev);
++ if (ret < 0)
++ goto error_free_device;
++
++ return 0;
++
++error_free_device:
++ iio_device_free(indio_dev);
++error_ret:
++ return ret;
++}
++
++static int lsm9ds0_remove(struct i2c_client *client)
++{
++ struct iio_dev *indio_dev = i2c_get_clientdata(client);
++ iio_device_unregister(indio_dev);
++ iio_device_free(indio_dev);
++ dev_info(&client->dev, "Driver removed.");
++ return 0;
++}
++
++static const struct i2c_device_id lsm9ds0_id[] = {
++ { "lsm9ds0_gyro", 0 },
++ { "lsm9ds0_accel_magn", 0 },
++ { }
++};
++MODULE_DEVICE_TABLE(i2c, lsm9ds0_id);
++
++static struct i2c_driver lsm9ds0_driver = {
++ .driver = {
++ .name = "lsm9ds0",
++ .owner = THIS_MODULE,
++ },
++ .probe = lsm9ds0_probe,
++ .remove = lsm9ds0_remove,
++ .id_table = lsm9ds0_id,
++};
++module_i2c_driver(lsm9ds0_driver);
++
++MODULE_AUTHOR("Matija Podravec <matija_podravec@fastmail.fm>");
++MODULE_DESCRIPTION("LSM9DS0 gyroscope, accelerometer, and magnetometer sensor");
++MODULE_LICENSE("GPL");
+--
+2.7.4
+
diff --git a/bsp/meta-rcar/meta-rcar-gen3-adas/recipes-kernel/linux/linux-renesas/0063-ASoC-PCM3168A-add-TDM-modes-merge-ADC-and-DAC.patch b/bsp/meta-rcar/meta-rcar-gen3-adas/recipes-kernel/linux/linux-renesas/0063-ASoC-PCM3168A-add-TDM-modes-merge-ADC-and-DAC.patch
new file mode 100644
index 00000000..83b00b71
--- /dev/null
+++ b/bsp/meta-rcar/meta-rcar-gen3-adas/recipes-kernel/linux/linux-renesas/0063-ASoC-PCM3168A-add-TDM-modes-merge-ADC-and-DAC.patch
@@ -0,0 +1,474 @@
+From a6d896b91938493193cfd0546a14f5c84b73ef8a Mon Sep 17 00:00:00 2001
+From: Andrey Gusakov <andrey.gusakov@cogentembedded.com>
+Date: Wed, 13 Apr 2016 15:32:38 +0300
+Subject: [PATCH 042/122] ASoC: PCM3168A: add TDM modes, merge ADC and DAC
+
+Also disable 16 bit format and enable at start
+
+Signed-off-by: Andrey Gusakov <andrey.gusakov@cogentembedded.com>
+---
+ sound/soc/codecs/pcm3168a.c | 314 ++++++++++++++++++++++++++++----------------
+ sound/soc/codecs/pcm3168a.h | 2 +-
+ 2 files changed, 202 insertions(+), 114 deletions(-)
+
+diff --git a/sound/soc/codecs/pcm3168a.c b/sound/soc/codecs/pcm3168a.c
+index b9d1207..28975f1 100644
+--- a/sound/soc/codecs/pcm3168a.c
++++ b/sound/soc/codecs/pcm3168a.c
+@@ -22,7 +22,7 @@
+
+ #include "pcm3168a.h"
+
+-#define PCM3168A_FORMATS (SNDRV_PCM_FMTBIT_S16_LE | \
++#define PCM3168A_FORMATS (/*SNDRV_PCM_FMTBIT_S16_LE | */\
+ SNDRV_PCM_FMTBIT_S24_3LE | \
+ SNDRV_PCM_FMTBIT_S24_LE | \
+ SNDRV_PCM_FMTBIT_S32_LE)
+@@ -33,7 +33,11 @@
+ #define PCM3168A_FMT_RIGHT_J_16 0x3
+ #define PCM3168A_FMT_DSP_A 0x4
+ #define PCM3168A_FMT_DSP_B 0x5
+-#define PCM3168A_FMT_DSP_MASK 0x4
++#define PCM3168A_FMT_I2S_TDM 0x6
++#define PCM3168A_FMT_LEFT_J_TDM 0x7
++/* High speed */
++#define PCM3168A_FMT_I2S_TDMHS 0x8
++#define PCM3168A_FMT_LEFT_J_TDMHS 0x9
+
+ #define PCM3168A_NUM_SUPPLIES 6
+ static const char *const pcm3168a_supply_names[PCM3168A_NUM_SUPPLIES] = {
+@@ -45,12 +49,18 @@ static const char *const pcm3168a_supply_names[PCM3168A_NUM_SUPPLIES] = {
+ "VCCDA2"
+ };
+
++#define TDM_MODE_NONE 0
++#define TDM_MODE_NORM 1
++#define TDM_MODE_HS 2
++
+ struct pcm3168a_priv {
+ struct regulator_bulk_data supplies[PCM3168A_NUM_SUPPLIES];
+ struct regmap *regmap;
+ struct clk *scki;
+- bool adc_master_mode;
+- bool dac_master_mode;
++ bool master_mode;
++ unsigned int tdm;
++ unsigned int slots;
++ unsigned int slot_width;
+ unsigned long sysclk;
+ unsigned int adc_fmt;
+ unsigned int dac_fmt;
+@@ -313,32 +323,43 @@ static int pcm3168a_set_dai_sysclk(struct snd_soc_dai *dai,
+ return 0;
+ }
+
+-static int pcm3168a_set_dai_fmt(struct snd_soc_dai *dai,
++int format_table[3][6] = {
++ [TDM_MODE_NONE] = {
++ [0] = -1,
++ [SND_SOC_DAIFMT_I2S] = PCM3168A_FMT_I2S,
++ [SND_SOC_DAIFMT_LEFT_J] = PCM3168A_FMT_LEFT_J,
++ [SND_SOC_DAIFMT_RIGHT_J] = PCM3168A_FMT_RIGHT_J,
++ [SND_SOC_DAIFMT_DSP_A] = PCM3168A_FMT_DSP_A,
++ [SND_SOC_DAIFMT_DSP_B] = PCM3168A_FMT_DSP_B},
++ [TDM_MODE_NORM] = {
++ [0] = -1,
++ [SND_SOC_DAIFMT_I2S] = PCM3168A_FMT_I2S_TDM,
++ [SND_SOC_DAIFMT_LEFT_J] = PCM3168A_FMT_LEFT_J_TDM,
++ [SND_SOC_DAIFMT_RIGHT_J] = -1,
++ [SND_SOC_DAIFMT_DSP_A] = -1,
++ [SND_SOC_DAIFMT_DSP_B] = -1},
++ [TDM_MODE_HS] = {
++ [0] = -1,
++ [SND_SOC_DAIFMT_I2S] = PCM3168A_FMT_I2S_TDMHS,
++ [SND_SOC_DAIFMT_LEFT_J] = PCM3168A_FMT_LEFT_J_TDMHS,
++ [SND_SOC_DAIFMT_RIGHT_J] = -1,
++ [SND_SOC_DAIFMT_DSP_A] = -1,
++ [SND_SOC_DAIFMT_DSP_B] = -1},
++};
++
++static int __pcm3168a_set_dai_fmt(struct snd_soc_dai *dai,
+ unsigned int format, bool dac)
+ {
+ struct snd_soc_codec *codec = dai->codec;
+ struct pcm3168a_priv *pcm3168a = snd_soc_codec_get_drvdata(codec);
+- u32 fmt, reg, mask, shift;
++ u32 reg, mask, shift;
++ int fmt;
+ bool master_mode;
+
+- switch (format & SND_SOC_DAIFMT_FORMAT_MASK) {
+- case SND_SOC_DAIFMT_LEFT_J:
+- fmt = PCM3168A_FMT_LEFT_J;
+- break;
+- case SND_SOC_DAIFMT_I2S:
+- fmt = PCM3168A_FMT_I2S;
+- break;
+- case SND_SOC_DAIFMT_RIGHT_J:
+- fmt = PCM3168A_FMT_RIGHT_J;
+- break;
+- case SND_SOC_DAIFMT_DSP_A:
+- fmt = PCM3168A_FMT_DSP_A;
+- break;
+- case SND_SOC_DAIFMT_DSP_B:
+- fmt = PCM3168A_FMT_DSP_B;
+- break;
+- default:
+- dev_err(codec->dev, "unsupported dai format\n");
++ fmt = format_table[pcm3168a->tdm][format & SND_SOC_DAIFMT_FORMAT_MASK];
++
++ if (fmt < 0) {
++ dev_err(codec->dev, "unsupported dai format of TDM mode\n");
+ return -EINVAL;
+ }
+
+@@ -354,6 +375,16 @@ static int pcm3168a_set_dai_fmt(struct snd_soc_dai *dai,
+ return -EINVAL;
+ }
+
++ if ((pcm3168a->tdm == TDM_MODE_HS) && (master_mode)) {
++ dev_err(codec->dev, "TDM high speed supported only in slave mode\n");
++ return -EINVAL;
++ }
++
++ if ((pcm3168a->tdm == TDM_MODE_HS) && (!dac)) {
++ dev_err(codec->dev, "TDM high speed not supported for ADC\n");
++ return -EINVAL;
++ }
++
+ switch (format & SND_SOC_DAIFMT_INV_MASK) {
+ case SND_SOC_DAIFMT_NB_NF:
+ break;
+@@ -365,31 +396,32 @@ static int pcm3168a_set_dai_fmt(struct snd_soc_dai *dai,
+ reg = PCM3168A_DAC_PWR_MST_FMT;
+ mask = PCM3168A_DAC_FMT_MASK;
+ shift = PCM3168A_DAC_FMT_SHIFT;
+- pcm3168a->dac_master_mode = master_mode;
+ pcm3168a->dac_fmt = fmt;
+ } else {
+ reg = PCM3168A_ADC_MST_FMT;
+ mask = PCM3168A_ADC_FMTAD_MASK;
+ shift = PCM3168A_ADC_FMTAD_SHIFT;
+- pcm3168a->adc_master_mode = master_mode;
+ pcm3168a->adc_fmt = fmt;
+ }
+
++ pcm3168a->master_mode = master_mode;
++
+ regmap_update_bits(pcm3168a->regmap, reg, mask, fmt << shift);
+
+ return 0;
+ }
+
+-static int pcm3168a_set_dai_fmt_dac(struct snd_soc_dai *dai,
++static int pcm3168a_set_dai_fmt(struct snd_soc_dai *dai,
+ unsigned int format)
+ {
+- return pcm3168a_set_dai_fmt(dai, format, true);
+-}
++ int ret;
+
+-static int pcm3168a_set_dai_fmt_adc(struct snd_soc_dai *dai,
+- unsigned int format)
+-{
+- return pcm3168a_set_dai_fmt(dai, format, false);
++ /* dac */
++ ret = __pcm3168a_set_dai_fmt(dai, format, false);
++ if (ret)
++ return ret;
++ /* adc */
++ return __pcm3168a_set_dai_fmt(dai, format, true);
+ }
+
+ static int pcm3168a_hw_params(struct snd_pcm_substream *substream,
+@@ -398,125 +430,168 @@ static int pcm3168a_hw_params(struct snd_pcm_substream *substream,
+ {
+ struct snd_soc_codec *codec = dai->codec;
+ struct pcm3168a_priv *pcm3168a = snd_soc_codec_get_drvdata(codec);
+- bool tx, master_mode;
++ int bits;
++ bool tx;
+ u32 val, mask, shift, reg;
+- unsigned int rate, fmt, ratio, max_ratio;
++ u32 sample_rate = 0; /* auto */
++ unsigned int rate, channels, fmt, ratio, max_ratio;
+ int i, min_frame_size;
+
+ rate = params_rate(params);
+-
+- ratio = pcm3168a->sysclk / rate;
++ channels = params_channels(params);
++ bits = params->msbits;
+
+ tx = substream->stream == SNDRV_PCM_STREAM_PLAYBACK;
++
+ if (tx) {
+ max_ratio = PCM3168A_NUM_SCKI_RATIOS_DAC;
+- reg = PCM3168A_DAC_PWR_MST_FMT;
+- mask = PCM3168A_DAC_MSDA_MASK;
+- shift = PCM3168A_DAC_MSDA_SHIFT;
+- master_mode = pcm3168a->dac_master_mode;
+ fmt = pcm3168a->dac_fmt;
+ } else {
+ max_ratio = PCM3168A_NUM_SCKI_RATIOS_ADC;
+- reg = PCM3168A_ADC_MST_FMT;
+- mask = PCM3168A_ADC_MSAD_MASK;
+- shift = PCM3168A_ADC_MSAD_SHIFT;
+- master_mode = pcm3168a->adc_master_mode;
+ fmt = pcm3168a->adc_fmt;
+ }
+
+- for (i = 0; i < max_ratio; i++) {
+- if (pcm3168a_scki_ratios[i] == ratio)
+- break;
+- }
++ if (pcm3168a->master_mode) {
++ ratio = pcm3168a->sysclk / rate;
++ for (i = 0; i < max_ratio; i++)
++ if (pcm3168a_scki_ratios[i] == ratio)
++ break;
+
+- if (i == max_ratio) {
+- dev_err(codec->dev, "unsupported sysclk ratio\n");
+- return -EINVAL;
++ if (i == max_ratio) {
++ dev_err(codec->dev, "unsupported sysclk ratio: %d\n", ratio);
++ return -EINVAL;
++ }
++ val = i + 1;
++ } else {
++ /* slave mode */
++ val = 0;
+ }
+
+- min_frame_size = params_width(params) * 2;
+- switch (min_frame_size) {
+- case 32:
+- if (master_mode || (fmt != PCM3168A_FMT_RIGHT_J)) {
+- dev_err(codec->dev, "32-bit frames are supported only for slave mode using right justified\n");
++ if (pcm3168a->tdm == TDM_MODE_NONE) {
++ /* one stereo frame size */
++ min_frame_size = bits * 2;
++ switch (min_frame_size) {
++ case 32:
++ if (pcm3168a->master_mode ||
++ (fmt != PCM3168A_FMT_RIGHT_J)) {
++ dev_err(codec->dev, "32-bit frames are supported only for slave mode using right justified\n");
++ return -EINVAL;
++ }
++ fmt = PCM3168A_FMT_RIGHT_J_16;
++ break;
++ case 48:
++ if (pcm3168a->master_mode ||
++ (fmt == PCM3168A_FMT_DSP_A) ||
++ (fmt == PCM3168A_FMT_DSP_B)) {
++ dev_err(codec->dev, "48-bit frames not supported in master mode, or slave mode using DSP\n");
++ return -EINVAL;
++ }
++ break;
++ case 64:
++ break;
++ default:
++ dev_err(codec->dev, "unsupported frame size: %d\n", min_frame_size);
+ return -EINVAL;
+ }
+- fmt = PCM3168A_FMT_RIGHT_J_16;
+- break;
+- case 48:
+- if (master_mode || (fmt & PCM3168A_FMT_DSP_MASK)) {
+- dev_err(codec->dev, "48-bit frames not supported in master mode, or slave mode using DSP\n");
++ }
++ if ((pcm3168a->tdm == TDM_MODE_NORM) ||
++ (pcm3168a->tdm == TDM_MODE_HS)) {
++ /* all channels over one or two line */
++ min_frame_size = bits * channels;
++
++ /* single rate */
++ sample_rate = 1;
++
++ /*
++ * 256fs for single line DIN0/DOUT0
++ * 128fs for two lines DIN01/DOU01
++ */
++ if ((min_frame_size != 256) &&
++ (min_frame_size != 128)) {
++ dev_err(codec->dev, "256/128-bit frames only supported in TDM formats\n");
+ return -EINVAL;
+ }
+- break;
+- case 64:
+- break;
+- default:
+- dev_err(codec->dev, "unsupported frame size: %d\n", min_frame_size);
+- return -EINVAL;
+ }
+-
+- if (master_mode)
+- val = ((i + 1) << shift);
+- else
++
++ /* Setup ADC in master mode, couse it drives ADC */
++ if ((pcm3168a->master_mode) || (tx)) {
++ fmt = pcm3168a->dac_fmt;
++ reg = PCM3168A_DAC_PWR_MST_FMT;
++ mask = PCM3168A_DAC_MSDA_MASK | PCM3168A_DAC_FMT_MASK;
++ shift = PCM3168A_DAC_MSDA_SHIFT;
++ /* start DAC */
++ regmap_update_bits(pcm3168a->regmap, reg, mask, (val << shift) | fmt);
++ }
++ /* Do we need also ADC? */
++ if (!tx) {
++ fmt = pcm3168a->adc_fmt;
++ reg = PCM3168A_ADC_MST_FMT;
++ mask = PCM3168A_ADC_MSAD_MASK | PCM3168A_ADC_FMTAD_MASK;
++ shift = PCM3168A_ADC_MSAD_SHIFT;
++ /* ADC slave mode only, driven by DAC or CPU DAI */
+ val = 0;
++ regmap_update_bits(pcm3168a->regmap, reg, mask, (val << shift) | fmt);
++ }
+
+- regmap_update_bits(pcm3168a->regmap, reg, mask, val);
++ regmap_update_bits(pcm3168a->regmap, PCM3168A_RST_SMODE,
++ PCM3168A_DAC_SRDA_MASK,
++ sample_rate << PCM3168A_DAC_SRDA_SHIFT);
+
+- if (tx) {
+- mask = PCM3168A_DAC_FMT_MASK;
+- shift = PCM3168A_DAC_FMT_SHIFT;
+- } else {
+- mask = PCM3168A_ADC_FMTAD_MASK;
+- shift = PCM3168A_ADC_FMTAD_SHIFT;
+- }
++ return 0;
++}
+
+- regmap_update_bits(pcm3168a->regmap, reg, mask, fmt << shift);
++static int pcm3168a_set_tdm_slot(struct snd_soc_dai *dai,
++ unsigned int tx_mask,
++ unsigned int rx_mask,
++ int slots,
++ int slot_width)
++{
++ struct snd_soc_codec *codec = dai->codec;
++ struct pcm3168a_priv *pcm3168a = snd_soc_codec_get_drvdata(codec);
++
++ if ((slots != 8) && (slots != 4))
++ return -EINVAL;
++
++ if ((slot_width != 32) && (slot_width != 24))
++ return -EINVAL;
++
++ pcm3168a->slots = slots;
++ pcm3168a->slot_width = slot_width;
+
+ return 0;
+ }
+
+-static const struct snd_soc_dai_ops pcm3168a_dac_dai_ops = {
+- .set_fmt = pcm3168a_set_dai_fmt_dac,
++static const struct snd_soc_dai_ops pcm3168a_dai_ops = {
++ .set_fmt = pcm3168a_set_dai_fmt,
+ .set_sysclk = pcm3168a_set_dai_sysclk,
++ .set_tdm_slot = pcm3168a_set_tdm_slot,
+ .hw_params = pcm3168a_hw_params,
+ .digital_mute = pcm3168a_digital_mute
+ };
+
+-static const struct snd_soc_dai_ops pcm3168a_adc_dai_ops = {
+- .set_fmt = pcm3168a_set_dai_fmt_adc,
+- .set_sysclk = pcm3168a_set_dai_sysclk,
+- .hw_params = pcm3168a_hw_params
+-};
+-
+-static struct snd_soc_dai_driver pcm3168a_dais[] = {
+- {
+- .name = "pcm3168a-dac",
+- .playback = {
+- .stream_name = "Playback",
+- .channels_min = 1,
+- .channels_max = 8,
+- .rates = SNDRV_PCM_RATE_8000_192000,
+- .formats = PCM3168A_FORMATS
+- },
+- .ops = &pcm3168a_dac_dai_ops
++static struct snd_soc_dai_driver pcm3168a_dai = {
++ .name = "pcm3168a",
++ .playback = {
++ .stream_name = "Playback",
++ .channels_min = 1,
++ .channels_max = 8,
++ .rates = SNDRV_PCM_RATE_8000_192000,
++ .formats = PCM3168A_FORMATS
+ },
+- {
+- .name = "pcm3168a-adc",
+- .capture = {
+- .stream_name = "Capture",
+- .channels_min = 1,
+- .channels_max = 6,
+- .rates = SNDRV_PCM_RATE_8000_96000,
+- .formats = PCM3168A_FORMATS
+- },
+- .ops = &pcm3168a_adc_dai_ops
++ .capture = {
++ .stream_name = "Capture",
++ .channels_min = 1,
++ .channels_max = 8,
++ .rates = SNDRV_PCM_RATE_8000_96000,
++ .formats = PCM3168A_FORMATS
+ },
++ .ops = &pcm3168a_dai_ops,
++ .symmetric_rates = 1,
+ };
+
+ static const struct reg_default pcm3168a_reg_default[] = {
+ { PCM3168A_RST_SMODE, PCM3168A_MRST_MASK | PCM3168A_SRST_MASK },
+- { PCM3168A_DAC_PWR_MST_FMT, 0x00 },
++ { PCM3168A_DAC_PWR_MST_FMT, 0x80 },
+ { PCM3168A_DAC_OP_FLT, 0x00 },
+ { PCM3168A_DAC_INV, 0x00 },
+ { PCM3168A_DAC_MUTE, 0x00 },
+@@ -665,12 +740,25 @@ int pcm3168a_probe(struct device *dev, struct regmap *regmap)
+ goto err_regulator;
+ }
+
++ /* get TDM mode */
++ if (dev->of_node) {
++ if (of_get_property(dev->of_node, "tdm", NULL))
++ pcm3168a->tdm = TDM_MODE_NORM;
++ else if (of_get_property(dev->of_node, "tdmhs", NULL))
++ pcm3168a->tdm = TDM_MODE_HS;
++ }
++
+ pm_runtime_set_active(dev);
+ pm_runtime_enable(dev);
+ pm_runtime_idle(dev);
+
+- ret = snd_soc_register_codec(dev, &pcm3168a_driver, pcm3168a_dais,
+- ARRAY_SIZE(pcm3168a_dais));
++ if (pcm3168a->tdm != TDM_MODE_NONE) {
++ pcm3168a_dai.playback.channels_min = 8;
++ pcm3168a_dai.capture.channels_min = 8;
++ }
++
++ ret = snd_soc_register_codec(dev, &pcm3168a_driver,
++ &pcm3168a_dai, 1);
+ if (ret) {
+ dev_err(dev, "failed to register codec: %d\n", ret);
+ goto err_regulator;
+diff --git a/sound/soc/codecs/pcm3168a.h b/sound/soc/codecs/pcm3168a.h
+index 56c8332..658507f 100644
+--- a/sound/soc/codecs/pcm3168a.h
++++ b/sound/soc/codecs/pcm3168a.h
+@@ -69,7 +69,7 @@ extern void pcm3168a_remove(struct device *dev);
+ #define PCM3168A_ADC_MSAD_SHIFT 4
+ #define PCM3168A_ADC_MSAD_MASK 0x70
+ #define PCM3168A_ADC_FMTAD_SHIFT 0
+-#define PCM3168A_ADC_FMTAD_MASK 0x7
++#define PCM3168A_ADC_FMTAD_MASK 0xf
+
+ #define PCM3168A_ADC_PWR_HPFB 0x52
+ #define PCM3168A_ADC_PSVAD_SHIFT 4
+--
+2.7.4
+
diff --git a/bsp/meta-rcar/meta-rcar-gen3-adas/recipes-kernel/linux/linux-renesas/0064-drm-bridge-adv7511-Add-frequency-and-vrefresh-limita.patch b/bsp/meta-rcar/meta-rcar-gen3-adas/recipes-kernel/linux/linux-renesas/0064-drm-bridge-adv7511-Add-frequency-and-vrefresh-limita.patch
new file mode 100644
index 00000000..fffd5c6a
--- /dev/null
+++ b/bsp/meta-rcar/meta-rcar-gen3-adas/recipes-kernel/linux/linux-renesas/0064-drm-bridge-adv7511-Add-frequency-and-vrefresh-limita.patch
@@ -0,0 +1,96 @@
+From 1b9c44163036d1c28e55d508ffe6d33492e92569 Mon Sep 17 00:00:00 2001
+From: Koji Matsuoka <koji.matsuoka.xm@renesas.com>
+Date: Thu, 7 Dec 2017 20:10:39 +0900
+Subject: [PATCH 043/122] drm/bridge: adv7511: Add frequency and vrefresh
+ limitation option
+
+This patch adds processing of frequency and vrefresh to ADV7511.
+
+Signed-off-by: Koji Matsuoka <koji.matsuoka.xm@renesas.com>
+---
+ drivers/gpu/drm/bridge/adv7511/adv7511.h | 7 +++++++
+ drivers/gpu/drm/bridge/adv7511/adv7511_drv.c | 22 ++++++++++++++++++++++
+ 2 files changed, 29 insertions(+)
+
+diff --git a/drivers/gpu/drm/bridge/adv7511/adv7511.h b/drivers/gpu/drm/bridge/adv7511/adv7511.h
+index 73d8ccb..8a30267 100644
+--- a/drivers/gpu/drm/bridge/adv7511/adv7511.h
++++ b/drivers/gpu/drm/bridge/adv7511/adv7511.h
+@@ -271,6 +271,8 @@ enum adv7511_sync_polarity {
+ * @sync_pulse: Select the sync pulse
+ * @vsync_polarity: vsync input signal configuration
+ * @hsync_polarity: hsync input signal configuration
++ * @limit_vrefresh_option: limit vrefresh option
++ * @limit_freq_option: limit frequency option
+ */
+ struct adv7511_link_config {
+ unsigned int input_color_depth;
+@@ -285,6 +287,9 @@ struct adv7511_link_config {
+ enum adv7511_input_sync_pulse sync_pulse;
+ enum adv7511_sync_polarity vsync_polarity;
+ enum adv7511_sync_polarity hsync_polarity;
++
++ unsigned int limit_vrefresh_option;
++ unsigned int limit_freq_option;
+ };
+
+ /**
+@@ -354,6 +359,8 @@ struct adv7511 {
+ enum adv7511_sync_polarity vsync_polarity;
+ enum adv7511_sync_polarity hsync_polarity;
+ bool rgb;
++ unsigned int limit_vref;
++ unsigned int limit_freq;
+
+ struct gpio_desc *gpio_pd;
+
+diff --git a/drivers/gpu/drm/bridge/adv7511/adv7511_drv.c b/drivers/gpu/drm/bridge/adv7511/adv7511_drv.c
+index 808021f..470be69 100644
+--- a/drivers/gpu/drm/bridge/adv7511/adv7511_drv.c
++++ b/drivers/gpu/drm/bridge/adv7511/adv7511_drv.c
+@@ -323,6 +323,8 @@ static void adv7511_set_link_config(struct adv7511 *adv7511,
+ adv7511->hsync_polarity = config->hsync_polarity;
+ adv7511->vsync_polarity = config->vsync_polarity;
+ adv7511->rgb = config->input_colorspace == HDMI_COLORSPACE_RGB;
++ adv7511->limit_vref = config->limit_freq_option;
++ adv7511->limit_freq = config->limit_vrefresh_option;
+ }
+
+ static void __adv7511_power_on(struct adv7511 *adv7511)
+@@ -672,6 +674,16 @@ static enum drm_mode_status adv7511_mode_valid(struct adv7511 *adv7511,
+ if (mode->clock > 165000)
+ return MODE_CLOCK_HIGH;
+
++ if (adv7511->limit_freq) {
++ if (mode->clock > (adv7511->limit_freq / 1000))
++ return MODE_CLOCK_HIGH;
++ }
++
++ if (adv7511->limit_vref) {
++ if (drm_mode_vrefresh(mode) < adv7511->limit_vref)
++ return MODE_BAD;
++ }
++
+ return MODE_OK;
+ }
+
+@@ -1089,6 +1101,16 @@ static int adv7511_parse_dt(struct device_node *np,
+ config->vsync_polarity = ADV7511_SYNC_POLARITY_PASSTHROUGH;
+ config->hsync_polarity = ADV7511_SYNC_POLARITY_PASSTHROUGH;
+
++ ret = of_property_read_u32(np, "limit-frequency",
++ &config->limit_vrefresh_option);
++ if (ret < 0)
++ config->limit_vrefresh_option = 0;
++
++ ret = of_property_read_u32(np, "lower-refresh",
++ &config->limit_freq_option);
++ if (ret < 0)
++ config->limit_freq_option = 0;
++
+ return 0;
+ }
+
+--
+2.7.4
+
diff --git a/bsp/meta-rcar/meta-rcar-gen3-adas/recipes-kernel/linux/linux-renesas/0066-pci-pcie-rcar-add-regulators-support.patch b/bsp/meta-rcar/meta-rcar-gen3-adas/recipes-kernel/linux/linux-renesas/0066-pci-pcie-rcar-add-regulators-support.patch
new file mode 100644
index 00000000..7536dd6a
--- /dev/null
+++ b/bsp/meta-rcar/meta-rcar-gen3-adas/recipes-kernel/linux/linux-renesas/0066-pci-pcie-rcar-add-regulators-support.patch
@@ -0,0 +1,100 @@
+From 78ade93086080c37638af492c567e049a0ee51e7 Mon Sep 17 00:00:00 2001
+From: Andrey Gusakov <andrey.gusakov@cogentembedded.com>
+Date: Mon, 24 Jul 2017 20:22:03 +0300
+Subject: [PATCH 044/122] pci: pcie-rcar: add regulators support
+
+Add PCIE regulators
+
+Signed-off-by: Andrey Gusakov <andrey.gusakov@cogentembedded.com>
+---
+ drivers/pci/host/pcie-rcar.c | 53 ++++++++++++++++++++++++++++++++++++++++++++
+ 1 file changed, 53 insertions(+)
+
+diff --git a/drivers/pci/host/pcie-rcar.c b/drivers/pci/host/pcie-rcar.c
+index 46b2622..276d011 100644
+--- a/drivers/pci/host/pcie-rcar.c
++++ b/drivers/pci/host/pcie-rcar.c
+@@ -17,6 +17,7 @@
+ #include <linux/bitops.h>
+ #include <linux/clk.h>
+ #include <linux/delay.h>
++#include <linux/regulator/consumer.h>
+ #include <linux/interrupt.h>
+ #include <linux/irq.h>
+ #include <linux/irqdomain.h>
+@@ -158,6 +159,8 @@ struct rcar_pcie {
+ struct list_head resources;
+ int root_bus_nr;
+ struct clk *bus_clk;
++ struct regulator *pcie3v3; /* 3.3V power supply */
++ struct regulator *pcie1v8; /* 1.8V power supply */
+ struct rcar_msi msi;
+ };
+
+@@ -1199,6 +1202,36 @@ static const struct of_device_id rcar_pcie_of_match[] = {
+ {},
+ };
+
++static int rcar_pcie_set_vpcie(struct rcar_pcie *pcie)
++{
++ struct device *dev = pcie->dev;
++ int err;
++
++ if (!IS_ERR(pcie->pcie3v3)) {
++ err = regulator_enable(pcie->pcie3v3);
++ if (err) {
++ dev_err(dev, "fail to enable vpcie3v3 regulator\n");
++ goto err_out;
++ }
++ }
++
++ if (!IS_ERR(pcie->pcie1v8)) {
++ err = regulator_enable(pcie->pcie1v8);
++ if (err) {
++ dev_err(dev, "fail to enable vpcie1v8 regulator\n");
++ goto err_disable_3v3;
++ }
++ }
++
++ return 0;
++
++err_disable_3v3:
++ if (!IS_ERR(pcie->pcie3v3))
++ regulator_disable(pcie->pcie3v3);
++err_out:
++ return err;
++}
++
+ static int rcar_pcie_probe(struct platform_device *pdev)
+ {
+ struct device *dev = &pdev->dev;
+@@ -1217,6 +1250,26 @@ static int rcar_pcie_probe(struct platform_device *pdev)
+ pcie->dev = dev;
+ platform_set_drvdata(pdev, pcie);
+
++ pcie->pcie3v3 = devm_regulator_get_optional(dev, "pcie3v3");
++ if (IS_ERR(pcie->pcie3v3)) {
++ if (PTR_ERR(pcie->pcie3v3) == -EPROBE_DEFER)
++ return -EPROBE_DEFER;
++ dev_info(dev, "no pcie3v3 regulator found\n");
++ }
++
++ pcie->pcie1v8 = devm_regulator_get_optional(dev, "pcie1v8");
++ if (IS_ERR(pcie->pcie1v8)) {
++ if (PTR_ERR(pcie->pcie1v8) == -EPROBE_DEFER)
++ return -EPROBE_DEFER;
++ dev_info(dev, "no pcie1v8 regulator found\n");
++ }
++
++ err = rcar_pcie_set_vpcie(pcie);
++ if (err) {
++ dev_err(dev, "failed to set pcie regulators\n");
++ return err;
++ }
++
+ err = pci_parse_request_of_pci_ranges(dev, &pcie->resources, NULL);
+ if (err)
+ goto err_free_bridge;
+--
+2.7.4
+
diff --git a/bsp/meta-rcar/meta-rcar-gen3-adas/recipes-kernel/linux/linux-renesas/0067-ti-st-use-proper-way-to-get-shutdown-gpio.patch b/bsp/meta-rcar/meta-rcar-gen3-adas/recipes-kernel/linux/linux-renesas/0067-ti-st-use-proper-way-to-get-shutdown-gpio.patch
new file mode 100644
index 00000000..f5c10681
--- /dev/null
+++ b/bsp/meta-rcar/meta-rcar-gen3-adas/recipes-kernel/linux/linux-renesas/0067-ti-st-use-proper-way-to-get-shutdown-gpio.patch
@@ -0,0 +1,61 @@
+From 1a54ccbce2a39adc024ca62e75d5e2bbefeb8a0f Mon Sep 17 00:00:00 2001
+From: Andrey Gusakov <andrey.gusakov@cogentembedded.com>
+Date: Wed, 2 Aug 2017 17:39:56 +0300
+Subject: [PATCH 045/122] ti-st: use proper way to get shutdown gpio
+
+Signed-off-by: Andrey Gusakov <andrey.gusakov@cogentembedded.com>
+---
+ drivers/misc/ti-st/st_kim.c | 23 ++++++++++++++++++-----
+ 1 file changed, 18 insertions(+), 5 deletions(-)
+
+diff --git a/drivers/misc/ti-st/st_kim.c b/drivers/misc/ti-st/st_kim.c
+index 01edf9d..06ebdf5 100644
+--- a/drivers/misc/ti-st/st_kim.c
++++ b/drivers/misc/ti-st/st_kim.c
+@@ -32,6 +32,8 @@
+ #include <linux/sched.h>
+ #include <linux/sysfs.h>
+ #include <linux/tty.h>
++#include <linux/of_device.h>
++#include <linux/of_gpio.h>
+
+ #include <linux/skbuff.h>
+ #include <linux/ti_wilink_st.h>
+@@ -749,18 +751,29 @@ static struct ti_st_plat_data *get_platform_data(struct device *dev)
+
+ dt_pdata = kzalloc(sizeof(*dt_pdata), GFP_KERNEL);
+
+- if (!dt_pdata)
++ if (!dt_pdata) {
+ pr_err("Can't allocate device_tree platform data\n");
++ return NULL;
++ }
+
+ dt_property = of_get_property(np, "dev_name", &len);
+- if (dt_property)
+- memcpy(&dt_pdata->dev_name, dt_property, len);
+- of_property_read_u32(np, "nshutdown_gpio",
+- (u32 *)&dt_pdata->nshutdown_gpio);
++ if (!dt_property) {
++ dev_err(dev, "failed to get tty name\n");
++ goto err;
++ }
++ memcpy(&dt_pdata->dev_name, dt_property, len);
++ dt_pdata->nshutdown_gpio = of_get_named_gpio(np, "shutdown-gpios", 0);
++ if (!gpio_is_valid(dt_pdata->nshutdown_gpio)) {
++ dev_err(dev, "failed to get shutdown gpio\n");
++ goto err;
++ }
+ of_property_read_u32(np, "flow_cntrl", (u32 *)&dt_pdata->flow_cntrl);
+ of_property_read_u32(np, "baud_rate", (u32 *)&dt_pdata->baud_rate);
+
+ return dt_pdata;
++err:
++ kfree(dt_pdata);
++ return NULL;
+ }
+
+ static struct dentry *kim_debugfs_dir;
+--
+2.7.4
+
diff --git a/bsp/meta-rcar/meta-rcar-gen3-adas/recipes-kernel/linux/linux-renesas/0068-drm-adv7511-use-smbus-to-retrieve-edid.patch b/bsp/meta-rcar/meta-rcar-gen3-adas/recipes-kernel/linux/linux-renesas/0068-drm-adv7511-use-smbus-to-retrieve-edid.patch
new file mode 100644
index 00000000..56aa71a3
--- /dev/null
+++ b/bsp/meta-rcar/meta-rcar-gen3-adas/recipes-kernel/linux/linux-renesas/0068-drm-adv7511-use-smbus-to-retrieve-edid.patch
@@ -0,0 +1,53 @@
+From d8e286fd757432df78121151e5174ff64d902add Mon Sep 17 00:00:00 2001
+From: Vladimir Barinov <vladimir.barinov@cogentembedded.com>
+Date: Wed, 9 Aug 2017 11:52:22 +0300
+Subject: [PATCH 046/122] drm: adv7511: use smbus to retrieve edid
+
+Get EDID using smbus protocol instead block i2c transfer
+This fixes often checksum errors while retriving EDID at 400kHz bus speed
+
+Signed-off-by: Vladimir Barinov <vladimir.barinov@cogentembedded.com>
+---
+ drivers/gpu/drm/bridge/adv7511/adv7511_drv.c | 9 +++++----
+ 1 file changed, 5 insertions(+), 4 deletions(-)
+
+diff --git a/drivers/gpu/drm/bridge/adv7511/adv7511_drv.c b/drivers/gpu/drm/bridge/adv7511/adv7511_drv.c
+index 470be69..06a70f0 100644
+--- a/drivers/gpu/drm/bridge/adv7511/adv7511_drv.c
++++ b/drivers/gpu/drm/bridge/adv7511/adv7511_drv.c
+@@ -553,18 +553,19 @@ static int adv7511_get_edid_block(void *data, u8 *buf, unsigned int block,
+ * support 64 byte transfers than 256 byte transfers
+ */
+
++#define CHUNK_SIZE 1
+ xfer[0].addr = adv7511->i2c_edid->addr;
+ xfer[0].flags = 0;
+ xfer[0].len = 1;
+ xfer[0].buf = &offset;
+ xfer[1].addr = adv7511->i2c_edid->addr;
+ xfer[1].flags = I2C_M_RD;
+- xfer[1].len = 64;
++ xfer[1].len = CHUNK_SIZE;
+ xfer[1].buf = adv7511->edid_buf;
+
+ offset = 0;
+
+- for (i = 0; i < 4; ++i) {
++ for (i = 0; i < 256/CHUNK_SIZE; ++i) {
+ ret = i2c_transfer(adv7511->i2c_edid->adapter, xfer,
+ ARRAY_SIZE(xfer));
+ if (ret < 0)
+@@ -572,8 +573,8 @@ static int adv7511_get_edid_block(void *data, u8 *buf, unsigned int block,
+ else if (ret != 2)
+ return -EIO;
+
+- xfer[1].buf += 64;
+- offset += 64;
++ xfer[1].buf += CHUNK_SIZE;
++ offset += CHUNK_SIZE;
+ }
+
+ adv7511->current_edid_segment = block / 2;
+--
+2.7.4
+
diff --git a/bsp/meta-rcar/meta-rcar-gen3-adas/recipes-kernel/linux/linux-renesas/0071-ASoC-add-dummy-device-for-WL18xx-PCM-audio.patch b/bsp/meta-rcar/meta-rcar-gen3-adas/recipes-kernel/linux/linux-renesas/0071-ASoC-add-dummy-device-for-WL18xx-PCM-audio.patch
new file mode 100644
index 00000000..b9ca6b8e
--- /dev/null
+++ b/bsp/meta-rcar/meta-rcar-gen3-adas/recipes-kernel/linux/linux-renesas/0071-ASoC-add-dummy-device-for-WL18xx-PCM-audio.patch
@@ -0,0 +1,128 @@
+From 6a414c0d01edc607fee65f5f026011d8d57ffc22 Mon Sep 17 00:00:00 2001
+From: Andrey Gusakov <andrey.gusakov@cogentembedded.com>
+Date: Thu, 10 Aug 2017 16:29:01 +0300
+Subject: [PATCH 047/122] ASoC: add dummy device for WL18xx PCM audio
+
+Signed-off-by: Andrey Gusakov <andrey.gusakov@cogentembedded.com>
+---
+ sound/soc/codecs/Kconfig | 3 ++
+ sound/soc/codecs/Makefile | 2 ++
+ sound/soc/codecs/wl18xx.c | 72 +++++++++++++++++++++++++++++++++++++++++++++++
+ 3 files changed, 77 insertions(+)
+ create mode 100644 sound/soc/codecs/wl18xx.c
+
+diff --git a/sound/soc/codecs/Kconfig b/sound/soc/codecs/Kconfig
+index 8d52af2..bf4f606 100644
+--- a/sound/soc/codecs/Kconfig
++++ b/sound/soc/codecs/Kconfig
+@@ -682,6 +682,9 @@ config SND_SOC_PCM3168A_SPI
+ config SND_SOC_SI468X
+ tristate "Dummy sound driver for Si468x radio"
+
++config SND_SOC_WL18XX
++ tristate "Dummy sound driver for WL18xx BT"
++
+ config SND_SOC_PCM5102A
+ tristate
+
+diff --git a/sound/soc/codecs/Makefile b/sound/soc/codecs/Makefile
+index 79b4386..57e81a9 100644
+--- a/sound/soc/codecs/Makefile
++++ b/sound/soc/codecs/Makefile
+@@ -140,6 +140,7 @@ snd-soc-sigmadsp-i2c-objs := sigmadsp-i2c.o
+ snd-soc-sigmadsp-regmap-objs := sigmadsp-regmap.o
+ snd-soc-si476x-objs := si476x.o
+ snd-soc-si468x-objs := si468x.o
++snd-soc-wl18xx-objs := wl18xx.o
+ snd-soc-sirf-audio-codec-objs := sirf-audio-codec.o
+ snd-soc-sn95031-objs := sn95031.o
+ snd-soc-spdif-tx-objs := spdif_transmitter.o
+@@ -379,6 +380,7 @@ obj-$(CONFIG_SND_SOC_SIGMADSP_I2C) += snd-soc-sigmadsp-i2c.o
+ obj-$(CONFIG_SND_SOC_SIGMADSP_REGMAP) += snd-soc-sigmadsp-regmap.o
+ obj-$(CONFIG_SND_SOC_SI476X) += snd-soc-si476x.o
+ obj-$(CONFIG_SND_SOC_SI468X) += snd-soc-si468x.o
++obj-$(CONFIG_SND_SOC_WL18XX) += snd-soc-wl18xx.o
+ obj-$(CONFIG_SND_SOC_SN95031) +=snd-soc-sn95031.o
+ obj-$(CONFIG_SND_SOC_SPDIF) += snd-soc-spdif-rx.o snd-soc-spdif-tx.o
+ obj-$(CONFIG_SND_SOC_SIRF_AUDIO_CODEC) += sirf-audio-codec.o
+diff --git a/sound/soc/codecs/wl18xx.c b/sound/soc/codecs/wl18xx.c
+new file mode 100644
+index 0000000..6e52b0f
+--- /dev/null
++++ b/sound/soc/codecs/wl18xx.c
+@@ -0,0 +1,72 @@
++/*
++ * Dummy sound driver for wl18xx BT modules
++ * Copyright 2016 Andrey Gusakov <andrey.gusakov@cogentembedded.com>
++ *
++ * Based on: Driver for the DFBM-CS320 bluetooth module
++ * Copyright 2011 Lars-Peter Clausen <lars@metafoo.de>
++ *
++ * This program is free software; you can redistribute it and/or modify it
++ * under the terms of the GNU General Public License as published by the
++ * Free Software Foundation; either version 2 of the License, or (at your
++ * option) any later version.
++ *
++ */
++
++#include <linux/init.h>
++#include <linux/module.h>
++#include <linux/platform_device.h>
++
++#include <sound/soc.h>
++
++static struct snd_soc_dai_driver wl18xx_dai = {
++ .name = "wl18xx-pcm",
++ .capture = {
++ .channels_min = 2,
++ .channels_max = 2,
++ .rates = SNDRV_PCM_RATE_48000,
++ .formats = SNDRV_PCM_FMTBIT_S16_LE,
++ },
++ .playback = {
++ .channels_min = 2,
++ .channels_max = 2,
++ .rates = SNDRV_PCM_RATE_48000,
++ .formats = SNDRV_PCM_FMTBIT_S16_LE,
++ },
++};
++
++static struct snd_soc_codec_driver soc_codec_dev_wl18xx;
++
++static int wl18xx_probe(struct platform_device *pdev)
++{
++ return snd_soc_register_codec(&pdev->dev, &soc_codec_dev_wl18xx,
++ &wl18xx_dai, 1);
++}
++
++static int wl18xx_remove(struct platform_device *pdev)
++{
++ snd_soc_unregister_codec(&pdev->dev);
++
++ return 0;
++}
++
++static const struct of_device_id wl18xx_of_match[] = {
++ { .compatible = "ti,wl18xx-pcm", },
++ { }
++};
++MODULE_DEVICE_TABLE(of, wl18xx_of_match);
++
++static struct platform_driver wl18xx_driver = {
++ .driver = {
++ .name = "wl18xx-codec",
++ .of_match_table = wl18xx_of_match,
++ .owner = THIS_MODULE,
++ },
++ .probe = wl18xx_probe,
++ .remove = wl18xx_remove,
++};
++
++module_platform_driver(wl18xx_driver);
++
++MODULE_AUTHOR("Andrey Gusakov <andrey.gusakov@cogentembedded.com>");
++MODULE_DESCRIPTION("ASoC wl18xx driver");
++MODULE_LICENSE("GPL");
+--
+2.7.4
+
diff --git a/bsp/meta-rcar/meta-rcar-gen3-adas/recipes-kernel/linux/linux-renesas/0072-usb-hub-disable-autosuspend-for-SMSC-hubs.patch b/bsp/meta-rcar/meta-rcar-gen3-adas/recipes-kernel/linux/linux-renesas/0072-usb-hub-disable-autosuspend-for-SMSC-hubs.patch
new file mode 100644
index 00000000..138c59af
--- /dev/null
+++ b/bsp/meta-rcar/meta-rcar-gen3-adas/recipes-kernel/linux/linux-renesas/0072-usb-hub-disable-autosuspend-for-SMSC-hubs.patch
@@ -0,0 +1,51 @@
+From 2cba40e9f31caf67fccbec8310a1c9a1e53b2c79 Mon Sep 17 00:00:00 2001
+From: Vladimir Barinov <vladimir.barinov@cogentembedded.com>
+Date: Fri, 11 Aug 2017 17:30:40 +0300
+Subject: [PATCH 048/122] usb: hub: disable autosuspend for SMSC hubs
+
+Disable autosuspend for SMSC hubs (USB5534B/USB2134B devices)
+This is a workaround for RCar Gen3 XHCI
+
+Signed-off-by: Vladimir Barinov <vladimir.barinov@cogentembedded.com>
+---
+ drivers/usb/core/hub.c | 9 +++++++++
+ 1 file changed, 9 insertions(+)
+
+diff --git a/drivers/usb/core/hub.c b/drivers/usb/core/hub.c
+index a9db088..b5e602f 100644
+--- a/drivers/usb/core/hub.c
++++ b/drivers/usb/core/hub.c
+@@ -36,7 +36,9 @@
+ #include "otg_whitelist.h"
+
+ #define USB_VENDOR_GENESYS_LOGIC 0x05e3
++#define USB_VENDOR_SMSC 0x0424
+ #define HUB_QUIRK_CHECK_PORT_AUTOSUSPEND 0x01
++#define HUB_QUIRK_DISABLE_AUTOSUSPEND 0x02
+
+ /* Protect struct usb_device->state and ->children members
+ * Note: Both are also protected by ->dev.sem, except that ->state can
+@@ -1797,6 +1799,9 @@ static int hub_probe(struct usb_interface *intf, const struct usb_device_id *id)
+ if (id->driver_info & HUB_QUIRK_CHECK_PORT_AUTOSUSPEND)
+ hub->quirk_check_port_auto_suspend = 1;
+
++ if (id->driver_info & HUB_QUIRK_DISABLE_AUTOSUSPEND)
++ pm_runtime_set_autosuspend_delay(&hdev->dev, -1);
++
+ if (hub_configure(hub, &desc->endpoint[0].desc) >= 0)
+ return 0;
+
+@@ -5269,6 +5274,10 @@ static void hub_event(struct work_struct *work)
+ }
+
+ static const struct usb_device_id hub_id_table[] = {
++ { .match_flags = USB_DEVICE_ID_MATCH_VENDOR | USB_DEVICE_ID_MATCH_INT_CLASS,
++ .idVendor = USB_VENDOR_SMSC,
++ .bInterfaceClass = USB_CLASS_HUB,
++ .driver_info = HUB_QUIRK_DISABLE_AUTOSUSPEND},
+ { .match_flags = USB_DEVICE_ID_MATCH_VENDOR
+ | USB_DEVICE_ID_MATCH_INT_CLASS,
+ .idVendor = USB_VENDOR_GENESYS_LOGIC,
+--
+2.7.4
+
diff --git a/bsp/meta-rcar/meta-rcar-gen3-adas/recipes-kernel/linux/linux-renesas/0073-MOST-dim2-add-device-tree-support.patch b/bsp/meta-rcar/meta-rcar-gen3-adas/recipes-kernel/linux/linux-renesas/0073-MOST-dim2-add-device-tree-support.patch
new file mode 100644
index 00000000..18eafcce
--- /dev/null
+++ b/bsp/meta-rcar/meta-rcar-gen3-adas/recipes-kernel/linux/linux-renesas/0073-MOST-dim2-add-device-tree-support.patch
@@ -0,0 +1,169 @@
+From 951c781c8f921d5e8fc46752fba05f0ffb2f85cd Mon Sep 17 00:00:00 2001
+From: Andrey Gusakov <andrey.gusakov@cogentembedded.com>
+Date: Fri, 7 Jul 2017 20:42:36 +0300
+Subject: [PATCH 049/122] MOST: dim2: add device tree support
+
+Signed-off-by: Andrey Gusakov <andrey.gusakov@cogentembedded.com>
+---
+ drivers/staging/most/hdm-dim2/dim2_hdm.c | 72 ++++++++++++++++++++++----------
+ 1 file changed, 50 insertions(+), 22 deletions(-)
+
+diff --git a/drivers/staging/most/hdm-dim2/dim2_hdm.c b/drivers/staging/most/hdm-dim2/dim2_hdm.c
+index df7021c..e3ce23c 100644
+--- a/drivers/staging/most/hdm-dim2/dim2_hdm.c
++++ b/drivers/staging/most/hdm-dim2/dim2_hdm.c
+@@ -14,6 +14,7 @@
+ #define pr_fmt(fmt) KBUILD_MODNAME ": " fmt
+
+ #include <linux/module.h>
++#include <linux/of_platform.h>
+ #include <linux/printk.h>
+ #include <linux/kernel.h>
+ #include <linux/init.h>
+@@ -21,6 +22,7 @@
+ #include <linux/interrupt.h>
+ #include <linux/slab.h>
+ #include <linux/io.h>
++#include <linux/clk.h>
+ #include <linux/dma-mapping.h>
+ #include <linux/sched.h>
+ #include <linux/kthread.h>
+@@ -98,6 +100,7 @@ struct dim2_hdm {
+ struct most_interface most_iface;
+ char name[16 + sizeof "dim2-"];
+ void __iomem *io_base;
++ struct clk *clk;
+ int clk_speed;
+ struct task_struct *netinfo_task;
+ wait_queue_head_t netinfo_waitq;
+@@ -160,6 +163,27 @@ void dimcb_on_error(u8 error_id, const char *error_message)
+ error_message);
+ }
+
++static int dim_parce_speed(const char *clock_speed)
++{
++ if (!strcmp(clock_speed, "256fs"))
++ return CLK_256FS;
++ else if (!strcmp(clock_speed, "512fs"))
++ return CLK_512FS;
++ else if (!strcmp(clock_speed, "1024fs"))
++ return CLK_1024FS;
++ else if (!strcmp(clock_speed, "2048fs"))
++ return CLK_2048FS;
++ else if (!strcmp(clock_speed, "3072fs"))
++ return CLK_3072FS;
++ else if (!strcmp(clock_speed, "4096fs"))
++ return CLK_4096FS;
++ else if (!strcmp(clock_speed, "6144fs"))
++ return CLK_6144FS;
++ else if (!strcmp(clock_speed, "8192fs"))
++ return CLK_8192FS;
++ return -1;
++}
++
+ /**
+ * startup_dim - initialize the dim2 interface
+ * @pdev: platform device
+@@ -173,32 +197,12 @@ static int startup_dim(struct platform_device *pdev)
+ struct dim2_platform_data *pdata = pdev->dev.platform_data;
+ u8 hal_ret;
+
+- dev->clk_speed = -1;
+-
+- if (clock_speed) {
+- if (!strcmp(clock_speed, "256fs"))
+- dev->clk_speed = CLK_256FS;
+- else if (!strcmp(clock_speed, "512fs"))
+- dev->clk_speed = CLK_512FS;
+- else if (!strcmp(clock_speed, "1024fs"))
+- dev->clk_speed = CLK_1024FS;
+- else if (!strcmp(clock_speed, "2048fs"))
+- dev->clk_speed = CLK_2048FS;
+- else if (!strcmp(clock_speed, "3072fs"))
+- dev->clk_speed = CLK_3072FS;
+- else if (!strcmp(clock_speed, "4096fs"))
+- dev->clk_speed = CLK_4096FS;
+- else if (!strcmp(clock_speed, "6144fs"))
+- dev->clk_speed = CLK_6144FS;
+- else if (!strcmp(clock_speed, "8192fs"))
+- dev->clk_speed = CLK_8192FS;
+- }
++ if (clock_speed)
++ dev->clk_speed = dim_parce_speed(clock_speed);
+
+ if (dev->clk_speed == -1) {
+ pr_info("Bad or missing clock speed parameter, using default value: 3072fs\n");
+ dev->clk_speed = CLK_3072FS;
+- } else {
+- pr_info("Selected clock speed: %s\n", clock_speed);
+ }
+ if (pdata && pdata->init) {
+ int ret = pdata->init(pdata, dev->io_base, dev->clk_speed);
+@@ -746,6 +750,7 @@ static int dim2_probe(struct platform_device *pdev)
+ int ret, i;
+ struct kobject *kobj;
+ int irq;
++ struct device_node *np = pdev->dev.of_node;
+
+ dev = devm_kzalloc(&pdev->dev, sizeof(*dev), GFP_KERNEL);
+ if (!dev)
+@@ -785,6 +790,14 @@ static int dim2_probe(struct platform_device *pdev)
+ return ret;
+ }
+
++ dev->clk = devm_clk_get(&pdev->dev, NULL);
++ if (IS_ERR(dev->clk)) {
++ dev_err(&pdev->dev, "cannot get clock\n");
++ ret = PTR_ERR(dev->clk);
++ return ret;
++ }
++ clk_prepare_enable(dev->clk);
++
+ init_waitqueue_head(&dev->netinfo_waitq);
+ dev->deliver_netinfo = 0;
+ dev->netinfo_task = kthread_run(&deliver_netinfo_thread, (void *)dev,
+@@ -833,6 +846,12 @@ static int dim2_probe(struct platform_device *pdev)
+ dev->most_iface.poison_channel = poison_channel;
+ dev->most_iface.request_netinfo = request_netinfo;
+
++ if (np) {
++ const char *tmp;
++ if (!of_property_read_string(np, "clock-speed", &tmp))
++ dev->clk_speed = dim_parce_speed(tmp);
++ }
++
+ kobj = most_register_interface(&dev->most_iface);
+ if (IS_ERR(kobj)) {
+ ret = PTR_ERR(kobj);
+@@ -885,6 +904,8 @@ static int dim2_remove(struct platform_device *pdev)
+ most_deregister_interface(&dev->most_iface);
+ kthread_stop(dev->netinfo_task);
+
++ clk_disable_unprepare(dev->clk);
++
+ /*
+ * break link to local platform_device_id struct
+ * to prevent crash by unload platform device module
+@@ -901,12 +922,19 @@ static const struct platform_device_id dim2_id[] = {
+
+ MODULE_DEVICE_TABLE(platform, dim2_id);
+
++static const struct of_device_id dim2_of_match[] = {
++ { .compatible = "rcar,medialb-dim2", },
++ {},
++};
++MODULE_DEVICE_TABLE(of, dim2_of_match);
++
+ static struct platform_driver dim2_driver = {
+ .probe = dim2_probe,
+ .remove = dim2_remove,
+ .id_table = dim2_id,
+ .driver = {
+ .name = "hdm_dim2",
++ .of_match_table = dim2_of_match,
+ },
+ };
+
+--
+2.7.4
+
diff --git a/bsp/meta-rcar/meta-rcar-gen3-adas/recipes-kernel/linux/linux-renesas/0074-MOST-dim2-add-R-Car3-related-initialization.patch b/bsp/meta-rcar/meta-rcar-gen3-adas/recipes-kernel/linux/linux-renesas/0074-MOST-dim2-add-R-Car3-related-initialization.patch
new file mode 100644
index 00000000..2e496e03
--- /dev/null
+++ b/bsp/meta-rcar/meta-rcar-gen3-adas/recipes-kernel/linux/linux-renesas/0074-MOST-dim2-add-R-Car3-related-initialization.patch
@@ -0,0 +1,63 @@
+From acc636a3603d2c541bfc758eea3dfa245a13cc46 Mon Sep 17 00:00:00 2001
+From: Andrey Gusakov <andrey.gusakov@cogentembedded.com>
+Date: Fri, 7 Jul 2017 20:43:33 +0300
+Subject: [PATCH 050/122] MOST: dim2: add R-Car3 related initialization
+
+Signed-off-by: Andrey Gusakov <andrey.gusakov@cogentembedded.com>
+---
+ drivers/staging/most/hdm-dim2/dim2_hdm.c | 25 +++++++++++++++++++++++++
+ 1 file changed, 25 insertions(+)
+
+diff --git a/drivers/staging/most/hdm-dim2/dim2_hdm.c b/drivers/staging/most/hdm-dim2/dim2_hdm.c
+index e3ce23c..0e5855d 100644
+--- a/drivers/staging/most/hdm-dim2/dim2_hdm.c
++++ b/drivers/staging/most/hdm-dim2/dim2_hdm.c
+@@ -26,6 +26,7 @@
+ #include <linux/dma-mapping.h>
+ #include <linux/sched.h>
+ #include <linux/kthread.h>
++#include <linux/delay.h>
+
+ #include <mostcore.h>
+ #include "dim2_hal.h"
+@@ -184,6 +185,26 @@ static int dim_parce_speed(const char *clock_speed)
+ return -1;
+ }
+
++static int dim_rcar_init(struct dim2_hdm *dev)
++{
++ /* PLL */
++ __raw_writel(0x04, dev->io_base + 0x600);
++
++ /* 512FS Enable Register */
++ if (dev->clk_speed == CLK_512FS)
++ __raw_writel(0x01, dev->io_base + 0x604);
++ else
++ __raw_writel(0x00, dev->io_base + 0x604);
++
++ udelay(200);
++
++ /* BBCR = 0b11 */
++ __raw_writel(0x03, dev->io_base + 0x500);
++ __raw_writel(0x0002FF02, dev->io_base + 0x508);
++
++ return 0;
++}
++
+ /**
+ * startup_dim - initialize the dim2 interface
+ * @pdev: platform device
+@@ -211,6 +232,10 @@ static int startup_dim(struct platform_device *pdev)
+ return ret;
+ }
+
++ if (1 /* renesas */) {
++ dim_rcar_init(dev);
++ }
++
+ pr_info("sync: num of frames per sub-buffer: %u\n", fcnt);
+ hal_ret = dim_startup(dev->io_base, dev->clk_speed, fcnt);
+ if (hal_ret != DIM_NO_ERROR) {
+--
+2.7.4
+
diff --git a/bsp/meta-rcar/meta-rcar-gen3-adas/recipes-kernel/linux/linux-renesas/0075-MOST-core-fix-memory-allocation-at-arm64.patch b/bsp/meta-rcar/meta-rcar-gen3-adas/recipes-kernel/linux/linux-renesas/0075-MOST-core-fix-memory-allocation-at-arm64.patch
new file mode 100644
index 00000000..870754de
--- /dev/null
+++ b/bsp/meta-rcar/meta-rcar-gen3-adas/recipes-kernel/linux/linux-renesas/0075-MOST-core-fix-memory-allocation-at-arm64.patch
@@ -0,0 +1,54 @@
+From edcebac286e677c3ac5043540bc36fd7c850b9be Mon Sep 17 00:00:00 2001
+From: Andrey Gusakov <andrey.gusakov@cogentembedded.com>
+Date: Fri, 7 Jul 2017 20:45:01 +0300
+Subject: [PATCH 051/122] MOST: core: fix memory allocation at arm64
+
+Provide valid dev pointer to dma_alloc_coherent
+
+Signed-off-by: Andrey Gusakov <andrey.gusakov@cogentembedded.com>
+---
+ drivers/staging/most/hdm-dim2/dim2_hdm.c | 1 +
+ drivers/staging/most/mostcore/core.c | 2 +-
+ drivers/staging/most/mostcore/mostcore.h | 1 +
+ 3 files changed, 3 insertions(+), 1 deletion(-)
+
+diff --git a/drivers/staging/most/hdm-dim2/dim2_hdm.c b/drivers/staging/most/hdm-dim2/dim2_hdm.c
+index 0e5855d..349eb66 100644
+--- a/drivers/staging/most/hdm-dim2/dim2_hdm.c
++++ b/drivers/staging/most/hdm-dim2/dim2_hdm.c
+@@ -870,6 +870,7 @@ static int dim2_probe(struct platform_device *pdev)
+ dev->most_iface.enqueue = enqueue;
+ dev->most_iface.poison_channel = poison_channel;
+ dev->most_iface.request_netinfo = request_netinfo;
++ dev->most_iface.dev = &pdev->dev;
+
+ if (np) {
+ const char *tmp;
+diff --git a/drivers/staging/most/mostcore/core.c b/drivers/staging/most/mostcore/core.c
+index 069269d..6952ce6 100644
+--- a/drivers/staging/most/mostcore/core.c
++++ b/drivers/staging/most/mostcore/core.c
+@@ -1272,7 +1272,7 @@ static int arm_mbo_chain(struct most_c_obj *c, int dir,
+ mbo->context = c;
+ mbo->ifp = c->iface;
+ mbo->hdm_channel_id = c->channel_id;
+- mbo->virt_address = dma_alloc_coherent(NULL,
++ mbo->virt_address = dma_alloc_coherent(c->iface->dev,
+ coherent_buf_size,
+ &mbo->bus_address,
+ GFP_KERNEL);
+diff --git a/drivers/staging/most/mostcore/mostcore.h b/drivers/staging/most/mostcore/mostcore.h
+index 915e515..19f5d2c 100644
+--- a/drivers/staging/most/mostcore/mostcore.h
++++ b/drivers/staging/most/mostcore/mostcore.h
+@@ -252,6 +252,7 @@ struct most_interface {
+ void (*on_netinfo)(struct most_interface *iface,
+ unsigned char link_stat,
+ unsigned char *mac_addr));
++ struct device *dev;
+ void *priv;
+ };
+
+--
+2.7.4
+
diff --git a/bsp/meta-rcar/meta-rcar-gen3-adas/recipes-kernel/linux/linux-renesas/0076-MOST-dim2-Renesas-R-Car3-variant.patch b/bsp/meta-rcar/meta-rcar-gen3-adas/recipes-kernel/linux/linux-renesas/0076-MOST-dim2-Renesas-R-Car3-variant.patch
new file mode 100644
index 00000000..43cabb36
--- /dev/null
+++ b/bsp/meta-rcar/meta-rcar-gen3-adas/recipes-kernel/linux/linux-renesas/0076-MOST-dim2-Renesas-R-Car3-variant.patch
@@ -0,0 +1,120 @@
+From 77503a746d91ad4bb637c907640d3576e1943e1c Mon Sep 17 00:00:00 2001
+From: Andrey Gusakov <andrey.gusakov@cogentembedded.com>
+Date: Mon, 25 Sep 2017 07:16:25 +0300
+Subject: [PATCH 052/122] MOST: dim2: Renesas R-Car3 variant
+
+- R-Car H3 has 8 FPSB
+- remove not existing registers access
+
+Signed-off-by: Andrey Gusakov <andrey.gusakov@cogentembedded.com>
+Signed-off-by: Vladimir Barinov <vladimir.barinov@cogentembedded.com>
+---
+ drivers/staging/most/hdm-dim2/dim2_hal.c | 8 ++++----
+ drivers/staging/most/hdm-dim2/dim2_hdm.c | 2 +-
+ drivers/staging/most/hdm-dim2/dim2_reg.h | 18 +++++++++---------
+ 3 files changed, 14 insertions(+), 14 deletions(-)
+
+diff --git a/drivers/staging/most/hdm-dim2/dim2_hal.c b/drivers/staging/most/hdm-dim2/dim2_hal.c
+index 9148464..a685c5a 100644
+--- a/drivers/staging/most/hdm-dim2/dim2_hal.c
++++ b/drivers/staging/most/hdm-dim2/dim2_hal.c
+@@ -532,11 +532,11 @@ static void dim2_cleanup(void)
+
+ /* clear status for all dma channels */
+ dimcb_io_write(&g.dim2->ACSR0, 0xFFFFFFFF);
+- dimcb_io_write(&g.dim2->ACSR1, 0xFFFFFFFF);
++// dimcb_io_write(&g.dim2->ACSR1, 0xFFFFFFFF);
+
+ /* mask interrupts for all channels */
+ dimcb_io_write(&g.dim2->ACMR0, 0);
+- dimcb_io_write(&g.dim2->ACMR1, 0);
++// dimcb_io_write(&g.dim2->ACMR1, 0);
+ }
+
+ static void dim2_initialize(bool enable_6pin, u8 mlb_clock)
+@@ -552,7 +552,7 @@ static void dim2_initialize(bool enable_6pin, u8 mlb_clock)
+
+ /* activate all HBI channels */
+ dimcb_io_write(&g.dim2->HCMR0, 0xFFFFFFFF);
+- dimcb_io_write(&g.dim2->HCMR1, 0xFFFFFFFF);
++// dimcb_io_write(&g.dim2->HCMR1, 0xFFFFFFFF);
+
+ /* enable HBI */
+ dimcb_io_write(&g.dim2->HCTL, bit_mask(HCTL_EN_BIT));
+@@ -782,7 +782,7 @@ static u8 init_ctrl_async(struct dim_channel *ch, u8 type, u8 is_tx,
+ void dim_service_mlb_int_irq(void)
+ {
+ dimcb_io_write(&g.dim2->MS0, 0);
+- dimcb_io_write(&g.dim2->MS1, 0);
++// dimcb_io_write(&g.dim2->MS1, 0);
+ }
+
+ u16 dim_norm_ctrl_async_buffer_size(u16 buf_size)
+diff --git a/drivers/staging/most/hdm-dim2/dim2_hdm.c b/drivers/staging/most/hdm-dim2/dim2_hdm.c
+index 349eb66..2731398 100644
+--- a/drivers/staging/most/hdm-dim2/dim2_hdm.c
++++ b/drivers/staging/most/hdm-dim2/dim2_hdm.c
+@@ -53,7 +53,7 @@ MODULE_PARM_DESC(clock_speed, "MediaLB Clock Speed");
+ * The values 0, 1, 2, 3, 4, 5, 6 represent corresponding number of frames per
+ * sub-buffer 1, 2, 4, 8, 16, 32, 64.
+ */
+-static u8 fcnt = 4; /* (1 << fcnt) frames per subbuffer */
++static u8 fcnt = 3; /* (1 << fcnt) frames per subbuffer */
+ module_param(fcnt, byte, 0000);
+ MODULE_PARM_DESC(fcnt, "Num of frames per sub-buffer for sync channels as a power of 2");
+
+diff --git a/drivers/staging/most/hdm-dim2/dim2_reg.h b/drivers/staging/most/hdm-dim2/dim2_reg.h
+index f7d9fbc..30a0f27 100644
+--- a/drivers/staging/most/hdm-dim2/dim2_reg.h
++++ b/drivers/staging/most/hdm-dim2/dim2_reg.h
+@@ -20,28 +20,28 @@
+ struct dim2_regs {
+ /* 0x00 */ u32 MLBC0;
+ /* 0x01 */ u32 rsvd0[1];
+- /* 0x02 */ u32 MLBPC0;
++ /* 0x02 */ u32 MLBPC0; /* no at R-Car3 */
+ /* 0x03 */ u32 MS0;
+ /* 0x04 */ u32 rsvd1[1];
+- /* 0x05 */ u32 MS1;
++ /* 0x05 */ u32 MS1; /* no at R-Car3 */
+ /* 0x06 */ u32 rsvd2[2];
+ /* 0x08 */ u32 MSS;
+ /* 0x09 */ u32 MSD;
+ /* 0x0A */ u32 rsvd3[1];
+ /* 0x0B */ u32 MIEN;
+ /* 0x0C */ u32 rsvd4[1];
+- /* 0x0D */ u32 MLBPC2;
+- /* 0x0E */ u32 MLBPC1;
++ /* 0x0D */ u32 MLBPC2; /* no at R-Car3 */
++ /* 0x0E */ u32 MLBPC1; /* no at R-Car3 */
+ /* 0x0F */ u32 MLBC1;
+ /* 0x10 */ u32 rsvd5[0x10];
+ /* 0x20 */ u32 HCTL;
+ /* 0x21 */ u32 rsvd6[1];
+ /* 0x22 */ u32 HCMR0;
+- /* 0x23 */ u32 HCMR1;
++ /* 0x23 */ u32 HCMR1; /* no at R-Car3 */
+ /* 0x24 */ u32 HCER0;
+- /* 0x25 */ u32 HCER1;
++ /* 0x25 */ u32 HCER1; /* no at R-Car3 */
+ /* 0x26 */ u32 HCBR0;
+- /* 0x27 */ u32 HCBR1;
++ /* 0x27 */ u32 HCBR1; /* no at R-Car3 */
+ /* 0x28 */ u32 rsvd7[8];
+ /* 0x30 */ u32 MDAT0;
+ /* 0x31 */ u32 MDAT1;
+@@ -57,9 +57,9 @@ struct dim2_regs {
+ /* 0xF0 */ u32 ACTL;
+ /* 0xF1 */ u32 rsvd9[3];
+ /* 0xF4 */ u32 ACSR0;
+- /* 0xF5 */ u32 ACSR1;
++ /* 0xF5 */ u32 ACSR1; /* no at R-Car3 */
+ /* 0xF6 */ u32 ACMR0;
+- /* 0xF7 */ u32 ACMR1;
++ /* 0xF7 */ u32 ACMR1; /* no at R-Car3 */
+ };
+
+ #define DIM2_MASK(n) (~((~(u32)0) << (n)))
+--
+2.7.4
+
diff --git a/bsp/meta-rcar/meta-rcar-gen3-adas/recipes-kernel/linux/linux-renesas/0077-MOST-dim2-add-timeouts.patch b/bsp/meta-rcar/meta-rcar-gen3-adas/recipes-kernel/linux/linux-renesas/0077-MOST-dim2-add-timeouts.patch
new file mode 100644
index 00000000..6939d0e9
--- /dev/null
+++ b/bsp/meta-rcar/meta-rcar-gen3-adas/recipes-kernel/linux/linux-renesas/0077-MOST-dim2-add-timeouts.patch
@@ -0,0 +1,46 @@
+From 19b051580b0d5665ff2ac66cd753b2e7b6bd05b9 Mon Sep 17 00:00:00 2001
+From: Andrey Gusakov <andrey.gusakov@cogentembedded.com>
+Date: Mon, 25 Sep 2017 07:13:29 +0300
+Subject: [PATCH 053/122] MOST: dim2: add timeouts
+
+Get rid from loop hang if device not functional
+
+Signed-off-by: Andrey Gusakov <andrey.gusakov@cogentembedded.com>
+Signed-off-by: Vladimir Barinov <vladimir.barinov@cogentembedded.com>
+---
+ drivers/staging/most/hdm-dim2/dim2_hal.c | 8 +++++++-
+ 1 file changed, 7 insertions(+), 1 deletion(-)
+
+diff --git a/drivers/staging/most/hdm-dim2/dim2_hal.c b/drivers/staging/most/hdm-dim2/dim2_hal.c
+index a685c5a..d0f78ac 100644
+--- a/drivers/staging/most/hdm-dim2/dim2_hal.c
++++ b/drivers/staging/most/hdm-dim2/dim2_hal.c
+@@ -19,6 +19,7 @@
+ #include "dim2_reg.h"
+ #include <linux/stddef.h>
+ #include <linux/kernel.h>
++#include <linux/delay.h>
+
+ /*
+ * Size factor for isochronous DBR buffer.
+@@ -149,11 +150,16 @@ static void free_dbr(int offs, int size)
+
+ static void dim2_transfer_madr(u32 val)
+ {
++ int timeout = 1000;
+ dimcb_io_write(&g.dim2->MADR, val);
+
+ /* wait for transfer completion */
+- while ((dimcb_io_read(&g.dim2->MCTL) & 1) != 1)
++ while ((dimcb_io_read(&g.dim2->MCTL) & 1) != 1) {
++ if (--timeout == 0)
++ break;
++ udelay(1);
+ continue;
++ }
+
+ dimcb_io_write(&g.dim2->MCTL, 0); /* clear transfer complete */
+ }
+--
+2.7.4
+
diff --git a/bsp/meta-rcar/meta-rcar-gen3-adas/recipes-kernel/linux/linux-renesas/0078-MOST-aim-fix-null-pointer-crash.patch b/bsp/meta-rcar/meta-rcar-gen3-adas/recipes-kernel/linux/linux-renesas/0078-MOST-aim-fix-null-pointer-crash.patch
new file mode 100644
index 00000000..790be166
--- /dev/null
+++ b/bsp/meta-rcar/meta-rcar-gen3-adas/recipes-kernel/linux/linux-renesas/0078-MOST-aim-fix-null-pointer-crash.patch
@@ -0,0 +1,29 @@
+From a68299f4a29874aee83938274100b323a72d4c3f Mon Sep 17 00:00:00 2001
+From: Vladimir Barinov <vladimir.barinov@cogentembedded.com>
+Date: Fri, 27 Oct 2017 17:34:05 +0300
+Subject: [PATCH 054/122] MOST: aim: fix null pointer crash
+
+The snd_card_new now crashes if first argument NULL
+
+Signed-off-by: Andrey Gusakov <andrey.gusakov@cogentembedded.com>
+Signed-off-by: Vladimir Barinov <vladimir.barinov@cogentembedded.com>
+---
+ drivers/staging/most/aim-sound/sound.c | 2 +-
+ 1 file changed, 1 insertion(+), 1 deletion(-)
+
+diff --git a/drivers/staging/most/aim-sound/sound.c b/drivers/staging/most/aim-sound/sound.c
+index ea1366a..71f5a15 100644
+--- a/drivers/staging/most/aim-sound/sound.c
++++ b/drivers/staging/most/aim-sound/sound.c
+@@ -595,7 +595,7 @@ static int audio_probe_channel(struct most_interface *iface, int channel_id,
+ return ret;
+ }
+
+- ret = snd_card_new(NULL, -1, card_name, THIS_MODULE,
++ ret = snd_card_new(iface->dev, -1, card_name, THIS_MODULE,
+ sizeof(*channel), &card);
+ if (ret < 0)
+ return ret;
+--
+2.7.4
+
diff --git a/bsp/meta-rcar/meta-rcar-gen3-adas/recipes-kernel/linux/linux-renesas/0079-Revert-dmaengine-rcar-dmac-use-TCRB-instead-of-TCR-f.patch b/bsp/meta-rcar/meta-rcar-gen3-adas/recipes-kernel/linux/linux-renesas/0079-Revert-dmaengine-rcar-dmac-use-TCRB-instead-of-TCR-f.patch
new file mode 100644
index 00000000..ccddaa8f
--- /dev/null
+++ b/bsp/meta-rcar/meta-rcar-gen3-adas/recipes-kernel/linux/linux-renesas/0079-Revert-dmaengine-rcar-dmac-use-TCRB-instead-of-TCR-f.patch
@@ -0,0 +1,31 @@
+From 462132b2edb18653be39b96fa6168c503d87fa6e Mon Sep 17 00:00:00 2001
+From: Valentine Barshak <valentine.barshak@cogentembedded.com>
+Date: Thu, 22 Nov 2018 18:19:30 +0300
+Subject: [PATCH 52/61] Revert "dmaengine: rcar-dmac: use TCRB instead of TCR
+ for "residue"
+
+The patch breaks SCIF DMA support.
+
+This partially reverts commit f5927ca87de38ab81a19cbb03e774b57c0e46fed.
+
+Signed-off-by: Valentine Barshak <valentine.barshak@cogentembedded.com>
+---
+ drivers/dma/sh/rcar-dmac.c | 2 +-
+ 1 file changed, 1 insertion(+), 1 deletion(-)
+
+diff --git a/drivers/dma/sh/rcar-dmac.c b/drivers/dma/sh/rcar-dmac.c
+index 218c5b0e..f487ceb 100644
+--- a/drivers/dma/sh/rcar-dmac.c
++++ b/drivers/dma/sh/rcar-dmac.c
+@@ -1364,7 +1364,7 @@ static unsigned int rcar_dmac_chan_get_residue(struct rcar_dmac_chan *chan,
+ }
+
+ /* Add the residue for the current chunk. */
+- residue += rcar_dmac_chan_read(chan, RCAR_DMATCRB) << desc->xfer_shift;
++ residue += rcar_dmac_chan_read(chan, RCAR_DMATCR) << desc->xfer_shift;
+
+ return residue;
+ }
+--
+2.7.4
+
diff --git a/bsp/meta-rcar/meta-rcar-gen3-adas/recipes-kernel/linux/linux-renesas/0082-gpio-pca953x-fix-interrupt-trigger.patch b/bsp/meta-rcar/meta-rcar-gen3-adas/recipes-kernel/linux/linux-renesas/0082-gpio-pca953x-fix-interrupt-trigger.patch
new file mode 100644
index 00000000..f5767590
--- /dev/null
+++ b/bsp/meta-rcar/meta-rcar-gen3-adas/recipes-kernel/linux/linux-renesas/0082-gpio-pca953x-fix-interrupt-trigger.patch
@@ -0,0 +1,28 @@
+From 03708e8a6c537752528d865964fd37be56453995 Mon Sep 17 00:00:00 2001
+From: Vladimir Barinov <vladimir.barinov@cogentembedded.com>
+Date: Fri, 15 Dec 2017 02:23:49 +0300
+Subject: [PATCH] gpio: pca953x: fix interrupt trigger
+
+The PCA9539 chip has edge sensitive interrupt
+
+Signed-off-by: Vladimir Barinov <vladimir.barinov@cogentembedded.com>
+---
+ drivers/gpio/gpio-pca953x.c | 2 +-
+ 1 file changed, 1 insertion(+), 1 deletion(-)
+
+diff --git a/drivers/gpio/gpio-pca953x.c b/drivers/gpio/gpio-pca953x.c
+index fe731f0..0b3f0d8 100644
+--- a/drivers/gpio/gpio-pca953x.c
++++ b/drivers/gpio/gpio-pca953x.c
+@@ -626,7 +626,7 @@ static int pca953x_irq_setup(struct pca953x_chip *chip,
+ client->irq,
+ NULL,
+ pca953x_irq_handler,
+- IRQF_TRIGGER_LOW | IRQF_ONESHOT |
++ IRQF_TRIGGER_RISING | IRQF_TRIGGER_FALLING | IRQF_ONESHOT |
+ IRQF_SHARED,
+ dev_name(&client->dev), chip);
+ if (ret) {
+--
+1.9.1
+
diff --git a/bsp/meta-rcar/meta-rcar-gen3-adas/recipes-kernel/linux/linux-renesas/0090-ASoC-rsnd-fixup-rsnd_ssi_master_clk_start-user-count.patch b/bsp/meta-rcar/meta-rcar-gen3-adas/recipes-kernel/linux/linux-renesas/0090-ASoC-rsnd-fixup-rsnd_ssi_master_clk_start-user-count.patch
new file mode 100644
index 00000000..eab7b2f9
--- /dev/null
+++ b/bsp/meta-rcar/meta-rcar-gen3-adas/recipes-kernel/linux/linux-renesas/0090-ASoC-rsnd-fixup-rsnd_ssi_master_clk_start-user-count.patch
@@ -0,0 +1,41 @@
+From 5c621fb5ee767836a56fb1f1f73087d494c2e196 Mon Sep 17 00:00:00 2001
+From: Kuninori Morimoto <kuninori.morimoto.gx@renesas.com>
+Date: Wed, 30 Jan 2019 14:11:21 +0300
+Subject: [PATCH] ASoC: rsnd: fixup rsnd_ssi_master_clk_start() user count
+ check
+
+commit 4d230d1271064 ("ASoC: rsnd: fixup not to call clk_get/set
+under non-atomic") added new rsnd_ssi_prepare() and moved
+rsnd_ssi_master_clk_start() to .prepare.
+But, ssi user count (= ssi->usrcnt) is incremented at .init
+(= rsnd_ssi_init()).
+Because of these timing exchange, ssi->usrcnt check at
+rsnd_ssi_master_clk_start() should be adjusted.
+Otherwise, 2nd master clock setup will be no check.
+This patch fixup this issue.
+
+Fixes: commit 4d230d1271064 ("ASoC: rsnd: fixup not to call clk_get/set under non-atomic")
+Reported-by: Yusuke Goda <yusuke.goda.sx@renesas.com>
+Reported-by: Valentine Barshak <valentine.barshak@cogentembedded.com>
+Signed-off-by: Kuninori Morimoto <kuninori.morimoto.gx@renesas.com>
+Tested-by: Yusuke Goda <yusuke.goda.sx@renesas.com>
+---
+ sound/soc/sh/rcar/ssi.c | 2 +-
+ 1 file changed, 1 insertion(+), 1 deletion(-)
+
+diff --git a/sound/soc/sh/rcar/ssi.c b/sound/soc/sh/rcar/ssi.c
+index a9d0692..d9f02b0 100644
+--- a/sound/soc/sh/rcar/ssi.c
++++ b/sound/soc/sh/rcar/ssi.c
+@@ -287,7 +287,7 @@ static int rsnd_ssi_master_clk_start(struct rsnd_mod *mod,
+ if (rsnd_ssi_is_multi_slave(mod, io))
+ return 0;
+
+- if (ssi->usrcnt > 1) {
++ if (ssi->usrcnt > 0) {
+ if (ssi->rate != rate) {
+ dev_err(dev, "SSI parent/child should use same rate\n");
+ return -EINVAL;
+--
+2.7.4
+
diff --git a/bsp/meta-rcar/meta-rcar-gen3-adas/recipes-kernel/linux/linux-renesas/0100-LVDS-ar0132-use-raw12.patch b/bsp/meta-rcar/meta-rcar-gen3-adas/recipes-kernel/linux/linux-renesas/0100-LVDS-ar0132-use-raw12.patch
new file mode 100644
index 00000000..7822b359
--- /dev/null
+++ b/bsp/meta-rcar/meta-rcar-gen3-adas/recipes-kernel/linux/linux-renesas/0100-LVDS-ar0132-use-raw12.patch
@@ -0,0 +1,152 @@
+From 2869ff3002560ee637f905ed684aaccfac53372e Mon Sep 17 00:00:00 2001
+From: Vladimir Barinov <vladimir.barinov@cogentembedded.com>
+Date: Mon, 28 Aug 2017 03:16:21 +0300
+Subject: [PATCH] LVDS: ar0132: use raw12
+
+Set CSI2 type raw8 in RCAR CSI2 and set raw12 in ti960
+
+Signed-off-by: Vladimir Barinov <vladimir.barinov@cogentembedded.com>
+---
+ arch/arm64/boot/dts/renesas/legacy/r8a7795-es1-h3ulcb-kf-v0.dts | 8 ++++----
+ arch/arm64/boot/dts/renesas/legacy/r8a7795-h3ulcb-kf-v0.dts | 8 ++++----
+ arch/arm64/boot/dts/renesas/r8a7797-v3msk-kf.dts | 8 ++++----
+ arch/arm64/boot/dts/renesas/ulcb-kf.dtsi | 8 ++++----
+ drivers/media/i2c/soc_camera/ti964_ti9x3.c | 5 +++--
+ 5 files changed, 19 insertions(+), 18 deletions(-)
+
+diff --git a/arch/arm64/boot/dts/renesas/legacy/r8a7795-es1-h3ulcb-kf-v0.dts b/arch/arm64/boot/dts/renesas/legacy/r8a7795-es1-h3ulcb-kf-v0.dts
+index cd23797..5dc5144 100644
+--- a/arch/arm64/boot/dts/renesas/legacy/r8a7795-es1-h3ulcb-kf-v0.dts
++++ b/arch/arm64/boot/dts/renesas/legacy/r8a7795-es1-h3ulcb-kf-v0.dts
+@@ -1571,19 +1571,19 @@
+
+ virtual,channel {
+ csi2_vc0 {
+- data,type = "ycbcr422";
++ data,type = "raw8";
+ receive,vc = <0>;
+ };
+ csi2_vc1 {
+- data,type = "ycbcr422";
++ data,type = "raw8";
+ receive,vc = <1>;
+ };
+ csi2_vc2 {
+- data,type = "ycbcr422";
++ data,type = "raw8";
+ receive,vc = <2>;
+ };
+ csi2_vc3 {
+- data,type = "ycbcr422";
++ data,type = "raw8";
+ receive,vc = <3>;
+ };
+ };
+diff --git a/arch/arm64/boot/dts/renesas/legacy/r8a7795-h3ulcb-kf-v0.dts b/arch/arm64/boot/dts/renesas/legacy/r8a7795-h3ulcb-kf-v0.dts
+index f640350..b26ca3a 100644
+--- a/arch/arm64/boot/dts/renesas/legacy/r8a7795-h3ulcb-kf-v0.dts
++++ b/arch/arm64/boot/dts/renesas/legacy/r8a7795-h3ulcb-kf-v0.dts
+@@ -1578,19 +1578,19 @@
+
+ virtual,channel {
+ csi2_vc0 {
+- data,type = "ycbcr422";
++ data,type = "raw8";
+ receive,vc = <0>;
+ };
+ csi2_vc1 {
+- data,type = "ycbcr422";
++ data,type = "raw8";
+ receive,vc = <1>;
+ };
+ csi2_vc2 {
+- data,type = "ycbcr422";
++ data,type = "raw8";
+ receive,vc = <2>;
+ };
+ csi2_vc3 {
+- data,type = "ycbcr422";
++ data,type = "raw8";
+ receive,vc = <3>;
+ };
+ };
+diff --git a/arch/arm64/boot/dts/renesas/r8a7797-v3msk-kf.dts b/arch/arm64/boot/dts/renesas/r8a7797-v3msk-kf.dts
+index 9837e17..402e894 100644
+--- a/arch/arm64/boot/dts/renesas/r8a7797-v3msk-kf.dts
++++ b/arch/arm64/boot/dts/renesas/r8a7797-v3msk-kf.dts
+@@ -511,19 +511,19 @@
+
+ virtual,channel {
+ csi2_vc0 {
+- data,type = "ycbcr422";
++ data,type = "raw8";
+ receive,vc = <0>;
+ };
+ csi2_vc1 {
+- data,type = "ycbcr422";
++ data,type = "raw8";
+ receive,vc = <1>;
+ };
+ csi2_vc2 {
+- data,type = "ycbcr422";
++ data,type = "raw8";
+ receive,vc = <2>;
+ };
+ csi2_vc3 {
+- data,type = "ycbcr422";
++ data,type = "raw8";
+ receive,vc = <3>;
+ };
+ };
+diff --git a/arch/arm64/boot/dts/renesas/ulcb-kf.dtsi b/arch/arm64/boot/dts/renesas/ulcb-kf.dtsi
+index 4ead97a..6dbcf7f 100644
+--- a/arch/arm64/boot/dts/renesas/ulcb-kf.dtsi
++++ b/arch/arm64/boot/dts/renesas/ulcb-kf.dtsi
+@@ -1346,19 +1346,19 @@
+
+ virtual,channel {
+ csi2_vc0 {
+- data,type = "ycbcr422";
++ data,type = "raw8";
+ receive,vc = <0>;
+ };
+ csi2_vc1 {
+- data,type = "ycbcr422";
++ data,type = "raw8";
+ receive,vc = <1>;
+ };
+ csi2_vc2 {
+- data,type = "ycbcr422";
++ data,type = "raw8";
+ receive,vc = <2>;
+ };
+ csi2_vc3 {
+- data,type = "ycbcr422";
++ data,type = "raw8";
+ receive,vc = <3>;
+ };
+ };
+diff --git a/drivers/media/i2c/soc_camera/ti964_ti9x3.c b/drivers/media/i2c/soc_camera/ti964_ti9x3.c
+index 8dd0f99..caa3f74 100644
+--- a/drivers/media/i2c/soc_camera/ti964_ti9x3.c
++++ b/drivers/media/i2c/soc_camera/ti964_ti9x3.c
+@@ -122,12 +122,14 @@ static void ti964_ti9x3_fpdlink3_setup(struct i2c_client *client, int idx)
+ // reg8_write(client, 0x5d, SENSOR_ID << 1); /* SENSOR I2C native - must be set by sensor driver */
+ // reg8_write(client, 0x65, (0x60 + idx) << 1); /* SENSOR I2C translated - must be set by sensor driver */
+ if (strcmp(priv->cable_mode, "coax") == 0) {
+- reg8_write(client, 0x6d, 0x7f); /* Coax, RAW10 */
++ reg8_write(client, 0x6d, 0x7e); /* Coax, RAW12 */
+ } else if (strcmp(priv->cable_mode, "stp") == 0) {
+ reg8_write(client, 0x6d, 0x78); /* STP, CSI */
+ }
+ reg8_write(client, 0x70, (idx << 6) | 0x1e); /* CSI data type: yuv422 8-bit, assign VC */
+- reg8_write(client, 0x7c, 0x81); /* BIT(7) - magic to Use RAW10 as 8-bit mode */
++ reg8_write(client, 0x71, (idx << 6) | 0x2a); /* CSI data type: RAW8 (for RAW12 and bits reodering), assign VC */
++ reg8_write(client, 0x7c, 0x00); /* RAW12 mode */
++ reg8_write(client, 0xbc, 0x00); /* Setup minimal time between FV and LV to 3 PCLKs */
+ reg8_write(client, 0x6e, 0x88); /* Sensor reset: backchannel GPIO0/GPIO1 set low */
+ }
+
+--
+1.9.1
+
diff --git a/bsp/meta-rcar/meta-rcar-gen3-adas/recipes-kernel/linux/linux-renesas/0101-LVDS-ar0132-use-context-swwitch.patch b/bsp/meta-rcar/meta-rcar-gen3-adas/recipes-kernel/linux/linux-renesas/0101-LVDS-ar0132-use-context-swwitch.patch
new file mode 100644
index 00000000..00b62e8c
--- /dev/null
+++ b/bsp/meta-rcar/meta-rcar-gen3-adas/recipes-kernel/linux/linux-renesas/0101-LVDS-ar0132-use-context-swwitch.patch
@@ -0,0 +1,119 @@
+From d9b811e183d9cae753929cb55e627a29c6a971a8 Mon Sep 17 00:00:00 2001
+From: Vladimir Barinov <vladimir.barinov@cogentembedded.com>
+Date: Wed, 30 Aug 2017 14:44:29 +0300
+Subject: [PATCH] LVDS: ar0132 use context swwitch
+
+This enabled context-A-B switch on every frame
+
+Signed-off-by: Vladimir Barinov <vladimir.barinov@cogentembedded.com>
+---
+ drivers/media/i2c/soc_camera/ar0132.c | 19 +++++++++++++++++++
+ drivers/media/platform/soc_camera/rcar_vin.c | 23 ++++++++++++++++++-----
+ 2 files changed, 37 insertions(+), 5 deletions(-)
+
+diff --git a/drivers/media/i2c/soc_camera/ar0132.c b/drivers/media/i2c/soc_camera/ar0132.c
+index 284c522..2c21fa9 100644
+--- a/drivers/media/i2c/soc_camera/ar0132.c
++++ b/drivers/media/i2c/soc_camera/ar0132.c
+@@ -238,11 +238,30 @@ static int ar0132_s_register(struct v4l2_subdev *sd,
+ }
+ #endif
+
++static int ar0132_isr(struct v4l2_subdev *sd, u32 status, bool *handled)
++{
++ struct i2c_client *client = v4l2_get_subdevdata(sd);
++#if 1
++ u16 frame_count = 0;
++ /* read frame counter from sensor */
++ reg16_read16(client, 0x303a, &frame_count);
++#else
++ static int frame_count = 0;
++ /* get cached frame counter */
++ frame_count++;
++#endif
++ /* odd frame -> Mode A, even frame -> Mode B */
++ reg16_write16(client, 0x30b0, frame_count & 1 ? 0x2 : 0x2002);
++
++ return 0;
++};
++
+ static struct v4l2_subdev_core_ops ar0132_core_ops = {
+ #ifdef CONFIG_VIDEO_ADV_DEBUG
+ .g_register = ar0132_g_register,
+ .s_register = ar0132_s_register,
+ #endif
++ .interrupt_service_routine = ar0132_isr,
+ };
+
+ static int ar0132_s_ctrl(struct v4l2_ctrl *ctrl)
+diff --git a/drivers/media/platform/soc_camera/rcar_vin.c b/drivers/media/platform/soc_camera/rcar_vin.c
+index c39fe63..9ab6f00 100644
+--- a/drivers/media/platform/soc_camera/rcar_vin.c
++++ b/drivers/media/platform/soc_camera/rcar_vin.c
+@@ -1292,13 +1292,24 @@ static void rcar_vin_stop_streaming(struct vb2_queue *vq)
+ .wait_finish = vb2_ops_wait_finish,
+ };
+
++static irqreturn_t rcar_vin_threaded_irq(int irq, void *data)
++{
++ struct rcar_vin_priv *priv = data;
++ struct soc_camera_device *icd = priv->ici.icd;
++ struct v4l2_subdev *sd = soc_camera_to_subdev(icd);
++
++ v4l2_subdev_call(sd, core, interrupt_service_routine, 0, NULL);
++
++ return IRQ_HANDLED;
++};
++
+ static irqreturn_t rcar_vin_irq(int irq, void *data)
+ {
+ struct rcar_vin_priv *priv = data;
+ u32 int_status;
+ bool can_run = false, hw_stopped;
+ int slot;
+- unsigned int handled = 0;
++ unsigned int handled = IRQ_NONE;
+ int vin_ovr_cnt = 0;
+
+ spin_lock(&priv->lock);
+@@ -1309,7 +1320,7 @@ static irqreturn_t rcar_vin_irq(int irq, void *data)
+
+ /* ack interrupts */
+ iowrite32(int_status, priv->base + VNINTS_REG);
+- handled = 1;
++ handled = IRQ_HANDLED;
+
+ /* overflow occurs */
+ if (vin_debug && (int_status & VNINTS_FOS)) {
+@@ -1342,6 +1353,8 @@ static irqreturn_t rcar_vin_irq(int irq, void *data)
+ priv->queue_buf[slot] = NULL;
+
+ can_run = rcar_vin_fill_hw_slot(priv);
++
++ handled = IRQ_WAKE_THREAD;
+ }
+
+ if (is_continuous_transfer(priv)) {
+@@ -1370,7 +1383,7 @@ static irqreturn_t rcar_vin_irq(int irq, void *data)
+ done:
+ spin_unlock(&priv->lock);
+
+- return IRQ_RETVAL(handled);
++ return handled;
+ }
+
+ static struct v4l2_subdev *find_csi2(struct rcar_vin_priv *pcdev)
+@@ -2930,8 +2943,8 @@ static int rcar_vin_probe(struct platform_device *pdev)
+ if (IS_ERR(priv->base))
+ return PTR_ERR(priv->base);
+
+- ret = devm_request_irq(&pdev->dev, irq, rcar_vin_irq, IRQF_SHARED,
+- dev_name(&pdev->dev), priv);
++ ret = devm_request_threaded_irq(&pdev->dev, irq, rcar_vin_irq, rcar_vin_threaded_irq,
++ IRQF_SHARED, dev_name(&pdev->dev), priv);
+ if (ret)
+ return ret;
+
+--
+1.9.1
+
diff --git a/bsp/meta-rcar/meta-rcar-gen3-adas/recipes-kernel/linux/linux-renesas/0103-gpu-drm-rcar-du-Extend-VSP1-DRM-interface.patch b/bsp/meta-rcar/meta-rcar-gen3-adas/recipes-kernel/linux/linux-renesas/0103-gpu-drm-rcar-du-Extend-VSP1-DRM-interface.patch
new file mode 100644
index 00000000..e3f24a67
--- /dev/null
+++ b/bsp/meta-rcar/meta-rcar-gen3-adas/recipes-kernel/linux/linux-renesas/0103-gpu-drm-rcar-du-Extend-VSP1-DRM-interface.patch
@@ -0,0 +1,546 @@
+From b6176e313aea415b83d5762db275b2f364f08820 Mon Sep 17 00:00:00 2001
+From: Konstantin Kozhevnikov <Konstantin.Kozhevnikov@cogentembedded.com>
+Date: Tue, 14 Nov 2017 01:38:51 -0800
+Subject: [PATCH] gpu: drm: rcar-du: Extend VSP1-DRM interface
+
+Extend VSP1-DRM interface
+
+Signed-off-by: Konstantin Kozhevnikov <Konstantin.Kozhevnikov@cogentembedded.com>
+---
+ drivers/gpu/drm/drm_framebuffer.c | 1 +
+ drivers/gpu/drm/rcar-du/rcar_du_drv.h | 5 +
+ drivers/gpu/drm/rcar-du/rcar_du_kms.c | 42 ++++++-
+ drivers/gpu/drm/rcar-du/rcar_du_plane.c | 3 +-
+ drivers/gpu/drm/rcar-du/rcar_du_plane.h | 5 +
+ drivers/gpu/drm/rcar-du/rcar_du_vsp.c | 209 ++++++++++++++++++++++++++------
+ drivers/gpu/drm/rcar-du/rcar_du_vsp.h | 7 +-
+ 7 files changed, 232 insertions(+), 40 deletions(-)
+
+diff --git a/drivers/gpu/drm/drm_framebuffer.c b/drivers/gpu/drm/drm_framebuffer.c
+index 398efd6..4a43e15 100644
+--- a/drivers/gpu/drm/drm_framebuffer.c
++++ b/drivers/gpu/drm/drm_framebuffer.c
+@@ -192,6 +192,7 @@ static int format_check(const struct drm_mode_fb_cmd2 *r)
+ case DRM_FORMAT_YVU422:
+ case DRM_FORMAT_YUV444:
+ case DRM_FORMAT_YVU444:
++ case DRM_FORMAT_R8:
+ return 0;
+ default:
+ format_name = drm_get_format_name(r->pixel_format);
+diff --git a/drivers/gpu/drm/rcar-du/rcar_du_drv.h b/drivers/gpu/drm/rcar-du/rcar_du_drv.h
+index 45d6e7e..bdf2612 100644
+--- a/drivers/gpu/drm/rcar-du/rcar_du_drv.h
++++ b/drivers/gpu/drm/rcar-du/rcar_du_drv.h
+@@ -104,6 +104,11 @@ struct rcar_du_device {
+ struct {
+ struct drm_property *alpha;
+ struct drm_property *colorkey;
++ struct drm_property *alphaplane;
++ struct drm_property *blend;
++ struct drm_property *ckey;
++ struct drm_property *ckey_set0;
++ struct drm_property *ckey_set1;
+ } props;
+
+ unsigned int dpad0_source;
+diff --git a/drivers/gpu/drm/rcar-du/rcar_du_kms.c b/drivers/gpu/drm/rcar-du/rcar_du_kms.c
+index e955e92..31b48bc 100644
+--- a/drivers/gpu/drm/rcar-du/rcar_du_kms.c
++++ b/drivers/gpu/drm/rcar-du/rcar_du_kms.c
+@@ -10,7 +10,7 @@
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ */
+-
++//#define DEBUG
+ #include <drm/drmP.h>
+ #include <drm/drm_atomic.h>
+ #include <drm/drm_atomic_helper.h>
+@@ -101,6 +101,12 @@ static const struct rcar_du_format_info rcar_du_format_infos[] = {
+ .planes = 2,
+ .pnmr = PnMR_SPIM_TP_OFF | PnMR_DDDF_YC,
+ .edf = PnDDCR4_EDF_NONE,
++ }, {
++ .fourcc = DRM_FORMAT_R8,
++ .bpp = 8,
++ .planes = 1,
++ .pnmr = PnMR_SPIM_TP_OFF | PnMR_DDDF_8BPP,
++ .edf = PnDDCR4_EDF_NONE,
+ },
+ };
+
+@@ -169,6 +175,10 @@ static const struct rcar_du_format_info rcar_vsp_format_infos[] = {
+ .fourcc = DRM_FORMAT_YVU444,
+ .bpp = 24,
+ .planes = 3,
++ }, {
++ .fourcc = DRM_FORMAT_R8,
++ .bpp = 8,
++ .planes = 1,
+ },
+ };
+
+@@ -565,6 +575,36 @@ static int rcar_du_properties_init(struct rcar_du_device *rcdu)
+ if (rcdu->props.colorkey == NULL)
+ return -ENOMEM;
+
++ rcdu->props.alphaplane =
++ drm_property_create(rcdu->ddev, DRM_MODE_PROP_OBJECT, "alphaplane", 1);
++ if (rcdu->props.alphaplane == NULL)
++ return -ENOMEM;
++ rcdu->props.alphaplane->values[0] = DRM_MODE_OBJECT_FB;
++
++ rcdu->props.blend =
++ drm_property_create_range(rcdu->ddev, 0, "blend",
++ 0, 0xffffffff);
++ if (rcdu->props.blend == NULL)
++ return -ENOMEM;
++
++ rcdu->props.ckey =
++ drm_property_create_range(rcdu->ddev, 0, "ckey",
++ 0, 0xffffffff);
++ if (rcdu->props.ckey == NULL)
++ return -ENOMEM;
++
++ rcdu->props.ckey_set0 =
++ drm_property_create_range(rcdu->ddev, 0, "ckey_set0",
++ 0, 0xffffffff);
++ if (rcdu->props.ckey_set0 == NULL)
++ return -ENOMEM;
++
++ rcdu->props.ckey_set1 =
++ drm_property_create_range(rcdu->ddev, 0, "ckey_set1",
++ 0, 0xffffffff);
++ if (rcdu->props.ckey_set1 == NULL)
++ return -ENOMEM;
++
+ return 0;
+ }
+
+diff --git a/drivers/gpu/drm/rcar-du/rcar_du_plane.c b/drivers/gpu/drm/rcar-du/rcar_du_plane.c
+index e408aa3..2b57f09 100644
+--- a/drivers/gpu/drm/rcar-du/rcar_du_plane.c
++++ b/drivers/gpu/drm/rcar-du/rcar_du_plane.c
+@@ -10,7 +10,7 @@
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ */
+-
++//#define DEBUG
+ #include <drm/drmP.h>
+ #include <drm/drm_atomic.h>
+ #include <drm/drm_atomic_helper.h>
+@@ -719,6 +719,7 @@ static const uint32_t formats[] = {
+ DRM_FORMAT_NV12,
+ DRM_FORMAT_NV21,
+ DRM_FORMAT_NV16,
++ DRM_FORMAT_R8,
+ };
+
+ int rcar_du_planes_init(struct rcar_du_group *rgrp)
+diff --git a/drivers/gpu/drm/rcar-du/rcar_du_plane.h b/drivers/gpu/drm/rcar-du/rcar_du_plane.h
+index c1de338..a6065ef 100644
+--- a/drivers/gpu/drm/rcar-du/rcar_du_plane.h
++++ b/drivers/gpu/drm/rcar-du/rcar_du_plane.h
+@@ -66,6 +66,11 @@ struct rcar_du_plane_state {
+
+ unsigned int alpha;
+ unsigned int colorkey;
++ struct drm_framebuffer *alphaplane;
++ unsigned int blend;
++ unsigned int ckey;
++ unsigned int ckey_set0;
++ unsigned int ckey_set1;
+ };
+
+ static inline struct rcar_du_plane_state *
+diff --git a/drivers/gpu/drm/rcar-du/rcar_du_vsp.c b/drivers/gpu/drm/rcar-du/rcar_du_vsp.c
+index 770238a..910e0f0 100644
+--- a/drivers/gpu/drm/rcar-du/rcar_du_vsp.c
++++ b/drivers/gpu/drm/rcar-du/rcar_du_vsp.c
+@@ -10,7 +10,7 @@
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ */
+-
++//#define DEBUG
+ #include <drm/drmP.h>
+ #include <drm/drm_atomic.h>
+ #include <drm/drm_atomic_helper.h>
+@@ -91,6 +91,16 @@ void rcar_du_vsp_enable(struct rcar_du_crtc *crtc)
+
+ void rcar_du_vsp_disable(struct rcar_du_crtc *crtc)
+ {
++ struct rcar_du_vsp *vsp = crtc->vsp;
++ struct rcar_du_vsp_plane *primary = &vsp->planes[0];
++ struct rcar_du_vsp_plane_state *rstate = to_rcar_vsp_plane_state(primary->plane.state);
++
++ /* ...drop alpha-plane associated with primary plane (why only primary? - tbd) */
++ if (rstate->alphaplane) {
++ drm_framebuffer_unreference(rstate->alphaplane);
++ rstate->alphaplane = NULL;
++ }
++
+ vsp1_du_setup_lif(crtc->vsp->vsp, NULL, crtc->lif_index,
+ crtc->suspend);
+ }
+@@ -133,6 +143,7 @@ static const u32 formats_kms[] = {
+ DRM_FORMAT_YVU422,
+ DRM_FORMAT_YUV444,
+ DRM_FORMAT_YVU444,
++ DRM_FORMAT_R8,
+ };
+
+ static const u32 formats_v4l2[] = {
+@@ -162,6 +173,7 @@ static const u32 formats_v4l2[] = {
+ V4L2_PIX_FMT_YVU422M,
+ V4L2_PIX_FMT_YUV444M,
+ V4L2_PIX_FMT_YVU444M,
++ V4L2_PIX_FMT_GREY,
+ };
+
+ static const u32 formats_xlate[][2] = {
+@@ -184,6 +196,7 @@ static const u32 formats_xlate[][2] = {
+ { DRM_FORMAT_NV21, V4L2_PIX_FMT_NV21M },
+ { DRM_FORMAT_NV16, V4L2_PIX_FMT_NV16M },
+ { DRM_FORMAT_NV61, V4L2_PIX_FMT_NV61M },
++ { DRM_FORMAT_R8, V4L2_PIX_FMT_GREY },
+ };
+
+ static void rcar_du_vsp_plane_setup(struct rcar_du_vsp_plane *plane)
+@@ -226,6 +239,27 @@ static void rcar_du_vsp_plane_setup(struct rcar_du_vsp_plane *plane)
+ }
+ }
+
++ /* ...add alpha-plane as needed */
++ if (state->alphaplane) {
++ i = state->format->planes;
++ cfg.alpha_mem = sg_dma_address(state->sg_tables[i].sgl);
++ cfg.alpha_pitch = state->alphaplane->pitches[0];
++ pr_debug("alpha-%d: set alpha-mem address: %llx, pitch=%d\n", i, (unsigned long long)cfg.alpha_mem, cfg.alpha_pitch);
++ }
++
++ /* ...add blending formula as needed */
++ if (state->blend) {
++ cfg.blend = state->blend;
++ pr_debug("set blending formula: %X\n", cfg.blend);
++ }
++
++ /* ...add color key property as needed */
++ if (state->ckey) {
++ cfg.ckey = state->ckey;
++ cfg.ckey_set0 = state->ckey_set0;
++ cfg.ckey_set1 = state->ckey_set1;
++ }
++
+ vsp1_du_atomic_update(plane->vsp->vsp, plane->index, &cfg);
+ }
+
+@@ -259,6 +293,23 @@ static int rcar_du_vsp_plane_prepare_fb(struct drm_plane *plane,
+ }
+ }
+
++ /* ...check if we have alpha-plane attached */
++ if (rstate->alphaplane) {
++ struct drm_gem_cma_object *gem = drm_fb_cma_get_gem_obj(rstate->alphaplane, 0);
++ struct sg_table *sgt = &rstate->sg_tables[i++];
++
++ ret = dma_get_sgtable(rcdu->dev, sgt, gem->vaddr, gem->paddr, gem->base.size);
++ if (ret)
++ goto fail;
++
++ ret = vsp1_du_map_sg(vsp->vsp, sgt);
++ if (!ret) {
++ sg_free_table(sgt);
++ ret = -ENOMEM;
++ goto fail;
++ }
++ }
++
+ return 0;
+
+ fail:
+@@ -288,6 +339,14 @@ static void rcar_du_vsp_plane_cleanup_fb(struct drm_plane *plane,
+ vsp1_du_unmap_sg(vsp->vsp, sgt);
+ sg_free_table(sgt);
+ }
++
++ if (rstate->alphaplane) {
++ struct sg_table *sgt = &rstate->sg_tables[i];
++
++ vsp1_du_unmap_sg(vsp->vsp, sgt);
++ sg_free_table(sgt);
++ pr_debug("unmap alpha-plane\n");
++ }
+ }
+
+ static int rcar_du_vsp_plane_atomic_check(struct drm_plane *plane,
+@@ -369,6 +428,11 @@ rcar_du_vsp_plane_atomic_duplicate_state(struct drm_plane *plane)
+ if (copy == NULL)
+ return NULL;
+
++ if (copy->alphaplane) {
++ drm_framebuffer_reference(copy->alphaplane);
++ pr_debug("duplicate alpha-plane '%p' (refcount=%d)\n", copy->alphaplane, drm_framebuffer_read_refcount(copy->alphaplane));
++ }
++
+ __drm_atomic_helper_plane_duplicate_state(plane, &copy->state);
+
+ return &copy->state;
+@@ -377,8 +441,15 @@ rcar_du_vsp_plane_atomic_duplicate_state(struct drm_plane *plane)
+ static void rcar_du_vsp_plane_atomic_destroy_state(struct drm_plane *plane,
+ struct drm_plane_state *state)
+ {
++ struct rcar_du_vsp_plane_state *rstate = to_rcar_vsp_plane_state(state);
++
++ if (rstate->alphaplane) {
++ pr_debug("unref alpha-plane '%p' (refcount=%d)\n", rstate->alphaplane, drm_framebuffer_read_refcount(rstate->alphaplane));
++ drm_framebuffer_unreference(rstate->alphaplane);
++ }
++
+ __drm_atomic_helper_plane_destroy_state(state);
+- kfree(to_rcar_vsp_plane_state(state));
++ kfree(rstate);
+ }
+
+ static void rcar_du_vsp_plane_reset(struct drm_plane *plane)
+@@ -386,6 +457,7 @@ static void rcar_du_vsp_plane_reset(struct drm_plane *plane)
+ struct rcar_du_vsp_plane_state *state;
+
+ if (plane->state) {
++ pr_debug("reset plane '%p'\n", to_rcar_vsp_plane_state(plane->state)->alphaplane);
+ rcar_du_vsp_plane_atomic_destroy_state(plane, plane->state);
+ plane->state = NULL;
+ }
+@@ -410,7 +482,30 @@ static int rcar_du_vsp_plane_atomic_set_property(struct drm_plane *plane,
+
+ if (property == rcdu->props.alpha)
+ rstate->alpha = val;
+- else
++ else if (property == rcdu->props.blend)
++ rstate->blend = val;
++ else if (property == rcdu->props.ckey)
++ rstate->ckey = val;
++ else if (property == rcdu->props.ckey_set0)
++ rstate->ckey_set0 = val;
++ else if (property == rcdu->props.ckey_set1)
++ rstate->ckey_set1 = val;
++ else if (property == rcdu->props.alphaplane) {
++ if (rstate->alphaplane) {
++ pr_debug("unref alpha-plane '%p' (refcount=%d)\n", rstate->alphaplane, drm_framebuffer_read_refcount(rstate->alphaplane));
++ drm_framebuffer_unreference(rstate->alphaplane);
++ }
++ rstate->alphaplane = drm_framebuffer_lookup(plane->dev, val);
++ if (rstate->alphaplane) {
++ pr_debug("use alpha-plane '%p' (refcount=%d)\n", rstate->alphaplane, drm_framebuffer_read_refcount(rstate->alphaplane));
++ /* ...the way how we handle this leads to a "loss" of plane reference (it is acquired
++ * within "drm_property_change_valid_get" but not returned in symmetric "drm_property_change_valid_put")
++ * Whether it is a bug or was done intentionally, I don't know. For a moment just drop that
++ * extra reference right here
++ */
++ if (0) drm_framebuffer_unreference(rstate->alphaplane);
++ }
++ } else
+ return -EINVAL;
+
+ return 0;
+@@ -426,6 +521,16 @@ static int rcar_du_vsp_plane_atomic_get_property(struct drm_plane *plane,
+
+ if (property == rcdu->props.alpha)
+ *val = rstate->alpha;
++ else if (property == rcdu->props.alphaplane)
++ *val = (rstate->alphaplane ? rstate->alphaplane->base.id : 0);
++ else if (property == rcdu->props.blend)
++ *val = rstate->blend;
++ else if (property == rcdu->props.ckey)
++ *val = rstate->ckey;
++ else if (property == rcdu->props.ckey_set0)
++ *val = rstate->ckey_set0;
++ else if (property == rcdu->props.ckey_set1)
++ *val = rstate->ckey_set1;
+ else
+ return -EINVAL;
+
+@@ -442,9 +547,10 @@ int rcar_du_vsp_write_back(struct drm_device *dev, void *data,
+ struct rcar_du_crtc *rcrtc;
+ struct rcar_du_device *rcdu;
+ const struct drm_display_mode *mode;
+- u32 pixelformat, bpp;
+- unsigned int pitch;
++ struct drm_framebuffer *fb;
+ dma_addr_t mem[3];
++ struct sg_table sg_tables[3];
++ int i = 0;
+
+ obj = drm_mode_object_find(dev, sh->crtc_id, DRM_MODE_OBJECT_CRTC);
+ if (!obj)
+@@ -455,62 +561,79 @@ int rcar_du_vsp_write_back(struct drm_device *dev, void *data,
+ rcdu = rcrtc->group->dev;
+ mode = &rcrtc->crtc.state->adjusted_mode;
+
+- switch (sh->fmt) {
+- case DRM_FORMAT_RGB565:
+- bpp = 16;
+- pixelformat = V4L2_PIX_FMT_RGB565;
+- break;
+- case DRM_FORMAT_ARGB1555:
+- bpp = 16;
+- pixelformat = V4L2_PIX_FMT_ARGB555;
+- break;
+- case DRM_FORMAT_ARGB8888:
+- bpp = 32;
+- pixelformat = V4L2_PIX_FMT_ABGR32;
+- break;
+- default:
+- dev_err(rcdu->dev, "specified format is not supported.\n");
++ fb = drm_framebuffer_lookup(dev, sh->buff);
++ if (!fb) {
++ dev_err(dev->dev, "failed to lookup destination framebuffer '%lu'\n", sh->buff);
+ return -EINVAL;
+ }
+
+- pitch = mode->hdisplay * bpp / 8;
++ /* ...check framebuffer is okay */
++ if ((fb->width != (mode->hdisplay)) ||
++ (fb->height != (mode->vdisplay))) {
++ dev_err(dev->dev, "wrong fb mode: %d*%d vs %d*%d\n", fb->width, fb->height, mode->hdisplay, mode->vdisplay);
++ ret = -EINVAL;
++ goto done;
++ }
+
+- mem[0] = sh->buff;
+- mem[1] = 0;
+- mem[2] = 0;
++ /* ...need to verify compatibility of output format, I guess - tbd */
+
+- if ((sh->width != (mode->hdisplay)) ||
+- (sh->height != (mode->vdisplay)))
+- return -EINVAL;
++ /* ...fill memory planes addresses */
++ for (i = 0; i < 3; i++) {
++ struct drm_gem_cma_object *gem;
++ struct sg_table *sgt = &sg_tables[i];
++ gem = drm_fb_cma_get_gem_obj(fb, i);
++ if (!gem)
++ break;
++ ret = dma_get_sgtable(rcdu->dev, sgt, gem->vaddr, gem->paddr,
++ gem->base.size);
++ if (ret)
++ goto done;
+
+- if ((pitch * mode->vdisplay) > sh->buff_len)
+- return -EINVAL;
++ ret = vsp1_du_map_sg(rcrtc->vsp->vsp, sgt);
++ if (!ret) {
++ sg_free_table(sgt);
++ ret = -ENOMEM;
++ goto done;
++ }
++ mem[i] = sg_dma_address(sg_tables[i].sgl) + fb->offsets[i];
++ }
++
++ dev_info(dev->dev, "setup write-back (pixfmt=%X, %u*%u, planes: %d)\n", fb->pixel_format, fb->width, fb->height, i);
++
++ vsp1_du_setup_wb(rcrtc->vsp->vsp, fb->pixel_format, fb->pitches[0], mem, rcrtc->lif_index);
+
+- vsp1_du_setup_wb(rcrtc->vsp->vsp, pixelformat, pitch, mem,
+- rcrtc->lif_index);
+ ret = vsp1_du_wait_wb(rcrtc->vsp->vsp, WB_STAT_CATP_SET,
+ rcrtc->lif_index);
+ if (ret != 0)
+- return ret;
++ goto done;
+
+ ret = rcar_du_async_commit(dev, crtc);
+ if (ret != 0)
+- return ret;
++ goto done;
+
+ ret = vsp1_du_wait_wb(rcrtc->vsp->vsp, WB_STAT_CATP_START,
+ rcrtc->lif_index);
+ if (ret != 0)
+- return ret;
++ goto done;
+
+ ret = rcar_du_async_commit(dev, crtc);
+ if (ret != 0)
+- return ret;
++ goto done;
+
+ ret = vsp1_du_wait_wb(rcrtc->vsp->vsp, WB_STAT_CATP_DONE,
+ rcrtc->lif_index);
+ if (ret != 0)
+- return ret;
++ goto done;
++
++done:
++ /* ...unmap all tables */
++ while (i--) {
++ struct sg_table *sgt = &sg_tables[i];
++ vsp1_du_unmap_sg(rcrtc->vsp->vsp, sgt);
++ sg_free_table(sgt);
++ }
+
++ drm_framebuffer_unreference(fb);
+ return ret;
+ }
+
+@@ -574,6 +697,7 @@ static const uint32_t formats[] = {
+ DRM_FORMAT_NV21,
+ DRM_FORMAT_NV16,
+ DRM_FORMAT_NV61,
++ DRM_FORMAT_R8,
+ };
+
+ int rcar_du_vsp_init(struct rcar_du_vsp *vsp)
+@@ -653,13 +777,24 @@ int rcar_du_vsp_init(struct rcar_du_vsp *vsp)
+ drm_plane_helper_add(&plane->plane,
+ &rcar_du_vsp_plane_helper_funcs);
+
++#if 0 // ...use same set of properties for all planes
+ if (type == DRM_PLANE_TYPE_PRIMARY)
+ continue;
+-
++#endif
+ drm_object_attach_property(&plane->plane.base,
+ rcdu->props.alpha, 255);
+ drm_plane_create_zpos_property(&plane->plane, 1, 1,
+ vsp->num_planes - 1);
++ drm_object_attach_property(&plane->plane.base,
++ rcdu->props.alphaplane, 0);
++ drm_object_attach_property(&plane->plane.base,
++ rcdu->props.blend, 0);
++ drm_object_attach_property(&plane->plane.base,
++ rcdu->props.ckey, 0);
++ drm_object_attach_property(&plane->plane.base,
++ rcdu->props.ckey_set0, 0);
++ drm_object_attach_property(&plane->plane.base,
++ rcdu->props.ckey_set1, 0);
+ }
+
+ return 0;
+diff --git a/drivers/gpu/drm/rcar-du/rcar_du_vsp.h b/drivers/gpu/drm/rcar-du/rcar_du_vsp.h
+index 3fd9cef..2f4aa41 100644
+--- a/drivers/gpu/drm/rcar-du/rcar_du_vsp.h
++++ b/drivers/gpu/drm/rcar-du/rcar_du_vsp.h
+@@ -52,10 +52,15 @@ struct rcar_du_vsp_plane_state {
+ struct drm_plane_state state;
+
+ const struct rcar_du_format_info *format;
+- struct sg_table sg_tables[3];
++ struct sg_table sg_tables[4];
+
+ unsigned int alpha;
+ unsigned int zpos;
++ struct drm_framebuffer *alphaplane;
++ unsigned int blend;
++ unsigned int ckey;
++ unsigned int ckey_set0;
++ unsigned int ckey_set1;
+ };
+
+ static inline struct rcar_du_vsp_plane_state *
+--
+2.7.4
+
diff --git a/bsp/meta-rcar/meta-rcar-gen3-adas/recipes-kernel/linux/linux-renesas/0104-media-vsp1-extend-DRM-VSP1-interface.patch b/bsp/meta-rcar/meta-rcar-gen3-adas/recipes-kernel/linux/linux-renesas/0104-media-vsp1-extend-DRM-VSP1-interface.patch
new file mode 100644
index 00000000..2f6fa35f
--- /dev/null
+++ b/bsp/meta-rcar/meta-rcar-gen3-adas/recipes-kernel/linux/linux-renesas/0104-media-vsp1-extend-DRM-VSP1-interface.patch
@@ -0,0 +1,367 @@
+From 0cbfce87c1a16b80111cdcecdd703ad5f75cc6e7 Mon Sep 17 00:00:00 2001
+From: Konstantin Kozhevnikov <Konstantin.Kozhevnikov@cogentembedded.com>
+Date: Tue, 14 Nov 2017 01:41:06 -0800
+Subject: [PATCH] media: platform: vsp1: extend DRM-VSP1 interface
+
+- Extend DRM-VSP1 interface
+- Add alpha-plane support for VSP1
+
+Signed-off-by: Konstantin Kozhevnikov <Konstantin.Kozhevnikov@cogentembedded.com>
+---
+ drivers/media/platform/vsp1/vsp1_bru.c | 13 ++++++++++++-
+ drivers/media/platform/vsp1/vsp1_dl.c | 5 +++++
+ drivers/media/platform/vsp1/vsp1_drm.c | 34 ++++++++++++++++++++++++++-------
+ drivers/media/platform/vsp1/vsp1_lif.c | 2 +-
+ drivers/media/platform/vsp1/vsp1_pipe.c | 4 ++++
+ drivers/media/platform/vsp1/vsp1_rpf.c | 24 ++++++++++++++++++++---
+ drivers/media/platform/vsp1/vsp1_rwpf.c | 2 +-
+ drivers/media/platform/vsp1/vsp1_rwpf.h | 6 ++++++
+ drivers/media/platform/vsp1/vsp1_wpf.c | 4 +++-
+ include/media/vsp1.h | 6 ++++++
+ 10 files changed, 86 insertions(+), 14 deletions(-)
+
+diff --git a/drivers/media/platform/vsp1/vsp1_bru.c b/drivers/media/platform/vsp1/vsp1_bru.c
+index 8b3164a..2c131be 100644
+--- a/drivers/media/platform/vsp1/vsp1_bru.c
++++ b/drivers/media/platform/vsp1/vsp1_bru.c
+@@ -387,6 +387,16 @@ static void bru_configure(struct vsp1_entity *entity,
+ ctrl |= VI6_BRU_CTRL_SRCSEL_BRUIN(i);
+
+ vsp1_bru_write(bru, dl, VI6_BRU_CTRL(i), ctrl);
++ dev_dbg(entity->vsp1->dev, "bru#%d: ctrl=%X\n", i, ctrl);
++
++ /* ...set blending formula as defined by the input RPF */
++ if (bru->inputs[i].rpf) {
++ if (bru->inputs[i].rpf->blend) {
++ vsp1_bru_write(bru, dl, VI6_BRU_BLD(i), bru->inputs[i].rpf->blend);
++ dev_dbg(entity->vsp1->dev, "bru#%d(#%d): setup blending formula: %X\n", i, bru->inputs[i].rpf->entity.index, bru->inputs[i].rpf->blend);
++ continue;
++ }
++ }
+
+ /* Harcode the blending formula to
+ *
+@@ -441,7 +451,8 @@ struct vsp1_bru *vsp1_bru_create(struct vsp1_device *vsp1)
+ v4l2_ctrl_new_std(&bru->ctrls, &bru_ctrl_ops, V4L2_CID_BG_COLOR,
+ 0, 0xffffff, 1, 0);
+
+- bru->bgcolor = 0;
++ /* ...for YUV, set black background */
++ bru->bgcolor = 0x00800080;
+
+ bru->entity.subdev.ctrl_handler = &bru->ctrls;
+
+diff --git a/drivers/media/platform/vsp1/vsp1_dl.c b/drivers/media/platform/vsp1/vsp1_dl.c
+index 478e093..f9c6d09 100644
+--- a/drivers/media/platform/vsp1/vsp1_dl.c
++++ b/drivers/media/platform/vsp1/vsp1_dl.c
+@@ -272,6 +272,7 @@ void vsp1_dl_set_addr_auto_fld(struct vsp1_dl_list *dl, struct vsp1_rwpf *rpf)
+ u32 y_top_index, y_bot_index;
+ u32 u_top_index, u_bot_index;
+ u32 v_top_index, v_bot_index;
++ u32 alpha_index;
+ dma_addr_t y_top_addr, y_bot_addr;
+ dma_addr_t u_top_addr, u_bot_addr;
+ dma_addr_t v_top_addr, v_bot_addr;
+@@ -287,6 +288,7 @@ void vsp1_dl_set_addr_auto_fld(struct vsp1_dl_list *dl, struct vsp1_rwpf *rpf)
+ u_bot_index = rpf->entity.index * 8 + 3;
+ v_top_index = rpf->entity.index * 8 + 4;
+ v_bot_index = rpf->entity.index * 8 + 5;
++ alpha_index = rpf->entity.index * 8 + 6;
+
+ switch (rpf->fmtinfo->fourcc) {
+ case V4L2_PIX_FMT_YUV420M:
+@@ -359,6 +361,9 @@ void vsp1_dl_set_addr_auto_fld(struct vsp1_dl_list *dl, struct vsp1_rwpf *rpf)
+ dl->src_dst_addr[u_bot_index].addr = u_bot_addr;
+ dl->src_dst_addr[v_top_index].addr = v_top_addr;
+ dl->src_dst_addr[v_bot_index].addr = v_bot_addr;
++
++ /* ...set alpha-plane address as needed */
++ dl->src_dst_addr[alpha_index].addr = rpf->mem.alpha;
+ }
+
+ static struct vsp1_dl_list *vsp1_dl_list_alloc(struct vsp1_dl_manager *dlm)
+diff --git a/drivers/media/platform/vsp1/vsp1_drm.c b/drivers/media/platform/vsp1/vsp1_drm.c
+index 2681c8a..542ca5a 100644
+--- a/drivers/media/platform/vsp1/vsp1_drm.c
++++ b/drivers/media/platform/vsp1/vsp1_drm.c
+@@ -10,7 +10,7 @@
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ */
+-
++//#define DEBUG
+ #include <linux/device.h>
+ #include <linux/dma-mapping.h>
+ #include <linux/slab.h>
+@@ -201,7 +201,9 @@ int vsp1_du_setup_lif(struct device *dev, const struct vsp1_du_lif_config *cfg,
+
+ format.format.width = cfg->width;
+ format.format.height = cfg->height;
+- format.format.code = MEDIA_BUS_FMT_ARGB8888_1X32;
++ //format.format.code = MEDIA_BUS_FMT_ARGB8888_1X32;
++ /* ...always blend in YUV colorspace; apply conversion as needed */
++ format.format.code = MEDIA_BUS_FMT_AYUV8_1X32;
+ format.format.field = V4L2_FIELD_NONE;
+
+ ret = v4l2_subdev_call(&brs->entity.subdev, pad,
+@@ -222,7 +224,9 @@ int vsp1_du_setup_lif(struct device *dev, const struct vsp1_du_lif_config *cfg,
+
+ format.format.width = cfg->width;
+ format.format.height = cfg->height;
+- format.format.code = MEDIA_BUS_FMT_ARGB8888_1X32;
++ //format.format.code = MEDIA_BUS_FMT_ARGB8888_1X32;
++ /* ...always blend in YUV colorspace; apply conversion as needed */
++ format.format.code = MEDIA_BUS_FMT_AYUV8_1X32;
+ format.format.field = V4L2_FIELD_NONE;
+
+ ret = v4l2_subdev_call(&bru->entity.subdev, pad,
+@@ -241,7 +245,8 @@ int vsp1_du_setup_lif(struct device *dev, const struct vsp1_du_lif_config *cfg,
+
+ format.format.width = cfg->width;
+ format.format.height = cfg->height;
+- format.format.code = MEDIA_BUS_FMT_ARGB8888_1X32;
++ //format.format.code = MEDIA_BUS_FMT_ARGB8888_1X32;
++ format.format.code = MEDIA_BUS_FMT_AYUV8_1X32;
+ format.format.field = V4L2_FIELD_NONE;
+
+ if (lif_index == 1) {
+@@ -275,6 +280,13 @@ int vsp1_du_setup_lif(struct device *dev, const struct vsp1_du_lif_config *cfg,
+ format.format.code, lif_index);
+
+ format.pad = RWPF_PAD_SOURCE;
++ /* ...force conversion back to ARGB at the output */
++ format.format.code = MEDIA_BUS_FMT_ARGB8888_1X32;
++ ret = v4l2_subdev_call(&vsp1->wpf[0]->entity.subdev, pad, set_fmt, NULL,
++ &format);
++ if (ret < 0)
++ return ret;
++
+ ret = v4l2_subdev_call(&vsp1->wpf[lif_index]->entity.subdev,
+ pad, get_fmt, NULL, &format);
+ if (ret < 0)
+@@ -402,12 +414,12 @@ int vsp1_du_atomic_update(struct device *dev, unsigned int rpf_index,
+ }
+
+ dev_dbg(vsp1->dev,
+- "%s: RPF%u: (%u,%u)/%ux%u -> (%u,%u)/%ux%u (%08x), pitch %u dma { %pad, %pad, %pad } zpos %u\n",
++ "%s: RPF%u: (%u,%u)/%ux%u -> (%u,%u)/%ux%u (%08x), pitch %u dma { %pad, %pad, %pad } zpos %u, alpha %pad, ckey %x/%x/%x\n",
+ __func__, rpf_index,
+ cfg->src.left, cfg->src.top, cfg->src.width, cfg->src.height,
+ cfg->dst.left, cfg->dst.top, cfg->dst.width, cfg->dst.height,
+ cfg->pixelformat, cfg->pitch, &cfg->mem[0], &cfg->mem[1],
+- &cfg->mem[2], cfg->zpos);
++ &cfg->mem[2], cfg->zpos, &cfg->alpha_mem, cfg->ckey, cfg->ckey_set0, cfg->ckey_set1);
+
+ /*
+ * Store the format, stride, memory buffer address, crop and compose
+@@ -432,6 +444,11 @@ int vsp1_du_atomic_update(struct device *dev, unsigned int rpf_index,
+ rpf->format.plane_fmt[1].bytesperline = cfg->pitch;
+ rpf->alpha = cfg->alpha;
+ rpf->interlaced = cfg->interlaced;
++ rpf->alpha_pitch = cfg->alpha_pitch;
++ rpf->ckey = cfg->ckey;
++ rpf->ckey_set0 = cfg->ckey_set0;
++ rpf->ckey_set1 = cfg->ckey_set1;
++ rpf->blend = cfg->blend;
+
+ if ((vsp1->ths_quirks & VSP1_AUTO_FLD_NOT_SUPPORT) &&
+ rpf->interlaced) {
+@@ -443,6 +460,7 @@ int vsp1_du_atomic_update(struct device *dev, unsigned int rpf_index,
+ rpf->mem.addr[0] = cfg->mem[0];
+ rpf->mem.addr[1] = cfg->mem[1];
+ rpf->mem.addr[2] = cfg->mem[2];
++ rpf->mem.alpha = cfg->alpha_mem;
+
+ vsp1->drm->inputs[rpf_index].crop = cfg->src;
+ vsp1->drm->inputs[rpf_index].compose = cfg->dst;
+@@ -517,7 +535,9 @@ static int vsp1_du_setup_rpf_pipe(struct vsp1_device *vsp1,
+ __func__, format.format.width, format.format.height,
+ format.format.code, rpf->entity.index);
+
+- format.format.code = MEDIA_BUS_FMT_ARGB8888_1X32;
++ //format.format.code = MEDIA_BUS_FMT_ARGB8888_1X32;
++ /* ...do blending in YUV color-space; apply conversion as needed */
++ format.format.code = MEDIA_BUS_FMT_AYUV8_1X32;
+
+ ret = v4l2_subdev_call(&rpf->entity.subdev, pad, set_fmt, NULL,
+ &format);
+diff --git a/drivers/media/platform/vsp1/vsp1_lif.c b/drivers/media/platform/vsp1/vsp1_lif.c
+index e79f9e6..753763d 100644
+--- a/drivers/media/platform/vsp1/vsp1_lif.c
++++ b/drivers/media/platform/vsp1/vsp1_lif.c
+@@ -162,7 +162,7 @@ static void lif_configure(struct vsp1_entity *entity,
+
+ vsp1_lif_write(lif, dl, VI6_LIF_CTRL(lif->entity.index),
+ (obth << VI6_LIF_CTRL_OBTH_SHIFT) |
+- (format->code == 0 ? VI6_LIF_CTRL_CFMT : 0) |
++ (format->code != MEDIA_BUS_FMT_ARGB8888_1X32 ? VI6_LIF_CTRL_CFMT : 0) |
+ VI6_LIF_CTRL_REQSEL | VI6_LIF_CTRL_LIF_EN);
+
+ if (soc_device_match(r8a7797))
+diff --git a/drivers/media/platform/vsp1/vsp1_pipe.c b/drivers/media/platform/vsp1/vsp1_pipe.c
+index 8379962..86d4a85 100644
+--- a/drivers/media/platform/vsp1/vsp1_pipe.c
++++ b/drivers/media/platform/vsp1/vsp1_pipe.c
+@@ -137,6 +137,10 @@ static const struct vsp1_format_info vsp1_video_formats[] = {
+ VI6_FMT_Y_U_V_444, VI6_RPF_DSWAP_P_LLS | VI6_RPF_DSWAP_P_LWS |
+ VI6_RPF_DSWAP_P_WDS | VI6_RPF_DSWAP_P_BTS,
+ 3, { 8, 8, 8 }, false, false, 1, 1, false },
++ { V4L2_PIX_FMT_GREY, MEDIA_BUS_FMT_Y8_1X8,
++ /*VI6_FMT_Y_U_V_444*/0xDEAD, VI6_RPF_DSWAP_P_LLS | VI6_RPF_DSWAP_P_LWS |
++ VI6_RPF_DSWAP_P_WDS | VI6_RPF_DSWAP_P_BTS,
++ 1, { 8, 0, 0 }, false, false, 0, 0, false },
+ };
+
+ /**
+diff --git a/drivers/media/platform/vsp1/vsp1_rpf.c b/drivers/media/platform/vsp1/vsp1_rpf.c
+index ff25470..2cce294 100644
+--- a/drivers/media/platform/vsp1/vsp1_rpf.c
++++ b/drivers/media/platform/vsp1/vsp1_rpf.c
+@@ -10,7 +10,7 @@
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ */
+-
++//#define DEBUG
+ #include <linux/device.h>
+
+ #include <media/v4l2-subdev.h>
+@@ -253,8 +253,10 @@ static void rpf_configure(struct vsp1_entity *entity,
+ if (sink_format->code != source_format->code)
+ infmt |= VI6_RPF_INFMT_CSC;
+
++ dev_dbg(vsp1->dev, "rpf#%d: infmt=%x (csc=%d)\n", rpf->entity.index, infmt, !!(infmt & VI6_RPF_INFMT_CSC));
++
+ vsp1_rpf_write(rpf, dl, VI6_RPF_INFMT, infmt);
+- vsp1_rpf_write(rpf, dl, VI6_RPF_DSWAP, fmtinfo->swap);
++ vsp1_rpf_write(rpf, dl, VI6_RPF_DSWAP, fmtinfo->swap | 0xF00);
+
+ /* Output location */
+ if (pipe->bru) {
+@@ -288,6 +290,15 @@ static void rpf_configure(struct vsp1_entity *entity,
+ (left << VI6_RPF_LOC_HCOORD_SHIFT) |
+ (top << VI6_RPF_LOC_VCOORD_SHIFT));
+
++ // ...setup alpha-plane as required
++ if (rpf->mem.alpha) {
++ vsp1_rpf_write(rpf, dl, VI6_RPF_SRCM_ADDR_AI, rpf->mem.alpha);
++ vsp1_rpf_write(rpf, dl, VI6_RPF_ALPH_SEL, VI6_RPF_ALPH_SEL_ASEL_8B_PLANE);
++ vsp1_rpf_write(rpf, dl, VI6_RPF_SRCM_ASTRIDE, rpf->alpha_pitch);
++ dev_dbg(vsp1->dev, "rpf#%d: setup alpha-plane: buffer=%pad, stride=%u\n", rpf->entity.index, &rpf->mem.alpha, rpf->alpha_pitch);
++ goto out;
++ }
++
+ /* On Gen2 use the alpha channel (extended to 8 bits) when available or
+ * a fixed alpha value set through the V4L2_CID_ALPHA_COMPONENT control
+ * otherwise.
+@@ -342,7 +353,9 @@ static void rpf_configure(struct vsp1_entity *entity,
+ if (entity->vsp1->info->gen == 3) {
+ u32 mult;
+
+- if ((fmtinfo->alpha) &&
++ dev_dbg(vsp1->dev, "rpf#%d: alpha=%x, fourcc=%x\n", rpf->entity.index, fmtinfo->alpha, fmtinfo->fourcc);
++
++ if (0 && (fmtinfo->alpha) &&
+ (fmtinfo->fourcc != V4L2_PIX_FMT_ARGB555)) {
+ /* When the input contains an alpha channel enable the
+ * alpha multiplier. If the input is premultiplied we
+@@ -371,9 +384,14 @@ static void rpf_configure(struct vsp1_entity *entity,
+ rpf->mult_alpha = mult;
+ }
+
++out:
+ vsp1_rpf_write(rpf, dl, VI6_RPF_MSK_CTRL, 0);
+ vsp1_rpf_write(rpf, dl, VI6_RPF_CKEY_CTRL, 0);
+
++ /* ...set up color keying */
++ vsp1_rpf_write(rpf, dl, VI6_RPF_CKEY_CTRL, rpf->ckey);
++ vsp1_rpf_write(rpf, dl, VI6_RPF_CKEY_SET0, rpf->ckey_set0);
++ vsp1_rpf_write(rpf, dl, VI6_RPF_CKEY_SET1, rpf->ckey_set1);
+ }
+
+ static const struct vsp1_entity_operations rpf_entity_ops = {
+diff --git a/drivers/media/platform/vsp1/vsp1_rwpf.c b/drivers/media/platform/vsp1/vsp1_rwpf.c
+index 66e4d7e..d7e730f 100644
+--- a/drivers/media/platform/vsp1/vsp1_rwpf.c
++++ b/drivers/media/platform/vsp1/vsp1_rwpf.c
+@@ -10,7 +10,7 @@
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ */
+-
++//#define DEBUG
+ #include <media/v4l2-subdev.h>
+
+ #include "vsp1.h"
+diff --git a/drivers/media/platform/vsp1/vsp1_rwpf.h b/drivers/media/platform/vsp1/vsp1_rwpf.h
+index fbe6aa6..7553f2b 100644
+--- a/drivers/media/platform/vsp1/vsp1_rwpf.h
++++ b/drivers/media/platform/vsp1/vsp1_rwpf.h
+@@ -33,6 +33,7 @@ struct vsp1_video;
+
+ struct vsp1_rwpf_memory {
+ dma_addr_t addr[3];
++ dma_addr_t alpha;
+ };
+
+ struct vsp1_rwpf {
+@@ -72,6 +73,11 @@ struct vsp1_rwpf {
+
+ int write_back;
+ dma_addr_t buf_addr[3];
++ unsigned int alpha_pitch;
++ unsigned int ckey;
++ unsigned int ckey_set0;
++ unsigned int ckey_set1;
++ unsigned int blend;
+ };
+
+ static inline struct vsp1_rwpf *to_rwpf(struct v4l2_subdev *subdev)
+diff --git a/drivers/media/platform/vsp1/vsp1_wpf.c b/drivers/media/platform/vsp1/vsp1_wpf.c
+index e8b3cfb..cb81848 100644
+--- a/drivers/media/platform/vsp1/vsp1_wpf.c
++++ b/drivers/media/platform/vsp1/vsp1_wpf.c
+@@ -10,7 +10,7 @@
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ */
+-
++//#define DEBUG
+ #include <linux/device.h>
+
+ #include <media/v4l2-subdev.h>
+@@ -358,6 +358,8 @@ static void wpf_configure(struct vsp1_entity *entity,
+
+ wpf->outfmt = outfmt;
+
++ dev_dbg(vsp1->dev, "wpf#%d: outfmt=%x (csc=%d)\n", wpf->entity.index, outfmt, !!(outfmt & VI6_WPF_OUTFMT_CSC));
++
+ vsp1_dl_list_write(dl, VI6_DPR_WPF_FPORCH(wpf->entity.index),
+ VI6_DPR_WPF_FPORCH_FP_WPFN);
+
+diff --git a/include/media/vsp1.h b/include/media/vsp1.h
+index d5d93ed..c1c3201 100644
+--- a/include/media/vsp1.h
++++ b/include/media/vsp1.h
+@@ -53,11 +53,17 @@ struct vsp1_du_atomic_config {
+ u32 pixelformat;
+ unsigned int pitch;
+ dma_addr_t mem[3];
++ dma_addr_t alpha_mem;
++ unsigned int alpha_pitch;
++ unsigned int ckey;
++ unsigned int ckey_set0;
++ unsigned int ckey_set1;
+ struct v4l2_rect src;
+ struct v4l2_rect dst;
+ unsigned int alpha;
+ unsigned int zpos;
+ bool interlaced;
++ unsigned int blend;
+ };
+
+ void vsp1_du_atomic_begin(struct device *dev, unsigned int lif_index);
+--
+2.7.4
+
diff --git a/bsp/meta-rcar/meta-rcar-gen3-adas/recipes-kernel/linux/linux-renesas/0105-media-rcar-imr-IMR-driver-updates-for-raw-DL.patch b/bsp/meta-rcar/meta-rcar-gen3-adas/recipes-kernel/linux/linux-renesas/0105-media-rcar-imr-IMR-driver-updates-for-raw-DL.patch
new file mode 100644
index 00000000..42d2e32b
--- /dev/null
+++ b/bsp/meta-rcar/meta-rcar-gen3-adas/recipes-kernel/linux/linux-renesas/0105-media-rcar-imr-IMR-driver-updates-for-raw-DL.patch
@@ -0,0 +1,538 @@
+From a687bfb7343b33992f92e86c234718c3e21144a0 Mon Sep 17 00:00:00 2001
+From: Konstantin Kozhevnikov <Konstantin.Kozhevnikov@cogentembedded.com>
+Date: Tue, 14 Nov 2017 01:47:11 -0800
+Subject: [PATCH] media: rcar-imr: IMR driver updates for raw DL
+
+IMR driver updates for raw DL
+
+Signed-off-by: Konstantin Kozhevnikov <Konstantin.Kozhevnikov@cogentembedded.com>
+---
+ drivers/media/platform/rcar_imr.c | 209 ++++++++++++++++++++++++++++++--------
+ include/uapi/linux/rcar-imr.h | 16 +--
+ 2 files changed, 175 insertions(+), 50 deletions(-)
+
+diff --git a/drivers/media/platform/rcar_imr.c b/drivers/media/platform/rcar_imr.c
+index 30c6742..9b601da 100644
+--- a/drivers/media/platform/rcar_imr.c
++++ b/drivers/media/platform/rcar_imr.c
+@@ -94,6 +94,7 @@ struct imr_device {
+ struct v4l2_device v4l2_dev;
+ struct video_device video_dev;
+ struct v4l2_m2m_dev *m2m_dev;
++ struct device *alloc_dev;
+
+ /* ...do we need that counter really? framework counts fh structures for us - tbd */
+ int refcount;
+@@ -117,6 +118,9 @@ struct imr_ctx {
+ /* ...cropping parameters (in pixels) */
+ u16 crop[4];
+
++ /* ...solid color code */
++ u32 color;
++
+ /* ...number of active configurations (debugging) */
+ u32 cfg_num;
+ };
+@@ -192,6 +196,7 @@ struct imr_ctx {
+
+ #define IMR_TRICR 0x6C
+ #define IMR_TRIC_YCFORM (1 << 31)
++#define IMR_TRICR2 0xA0
+
+ #define IMR_UVDPOR 0x70
+ #define IMR_SUSR 0x74
+@@ -212,6 +217,8 @@ struct imr_ctx {
+ #define IMR_CPDP_UBDPO_SHIFT 4
+ #define IMR_CPDP_VRDPO_SHIFT 0
+
++#define IMR_TPOR 0xF0
++
+ /*******************************************************************************
+ * Auxiliary helpers
+ ******************************************************************************/
+@@ -404,11 +411,16 @@ static int imr_queue_setup(struct vb2_queue *vq,
+ return -EINVAL;
+ }
+
++ /* ...specify default allocator */
++ alloc_devs[0] = ctx->imr->alloc_dev;
++
+ return 0;
+ }
+
+ static int imr_buf_prepare(struct vb2_buffer *vb)
+ {
++ struct imr_ctx *ctx = vb2_get_drv_priv(vb->vb2_queue);
++
+ /* ...unclear yet if we want to prepare a buffer somehow (cache invalidation? - tbd) */
+ return 0;
+ }
+@@ -441,9 +453,10 @@ static void imr_buf_finish(struct vb2_buffer *vb)
+ WARN_ON(!mutex_is_locked(&ctx->imr->mutex));
+
+ /* ...any special processing of completed buffer? - tbd */
+- v4l2_dbg(3, debug, &ctx->imr->v4l2_dev, "%sput buffer <0x%08llx> done\n",
++ v4l2_dbg(3, debug, &ctx->imr->v4l2_dev, "%sput buffer <0x%08llx> done (err: %d) (ctx=%p)\n",
+ q->is_output ? "in" : "out",
+- vb2_dma_contig_plane_dma_addr(vb, 0));
++ vb2_dma_contig_plane_dma_addr(vb, 0),
++ vb->state, ctx);
+
+ /* ...unref configuration pointer as needed */
+ if (q->is_output)
+@@ -568,6 +581,11 @@ static inline u16 __imr_auto_sg_dg_tcm(u32 type)
+ (type & IMR_MAP_TCM ? IMR_TRIM_TCM : 0);
+ }
+
++static inline u16 __imr_bfe_tme(u32 type)
++{
++ return (type & IMR_MAP_TME ? IMR_TRIM_TME : 0) | (type & IMR_MAP_BFE ? IMR_TRIM_BFE : 0);
++}
++
+ static inline u16 __imr_uvdp(u32 type)
+ {
+ return __IMR_MAP_UVDPOR(type) | (type & IMR_MAP_DDP ? (1 << 8) : 0);
+@@ -674,15 +692,14 @@ static inline u32 * imr_tri_set_type_b(u32 *dl, void *map, struct imr_mesh *mesh
+ ******************************************************************************/
+
+ /* ...calculate length of a type "c" mapping */
+-static inline u32 imr_tri_type_c_get_length(struct imr_vbo *vbo, int item_size)
++static inline u32 imr_tri_type_c_get_length(int num, int item_size)
+ {
+- return ((4 + 3 * item_size) * vbo->num + 4);
++ return ((4 + 3 * item_size) * num + 4);
+ }
+
+ /* ...set a VBO mapping using absolute coordinates */
+-static inline u32 * imr_tri_set_type_c(u32 *dl, void *map, struct imr_vbo *vbo, int item_size)
++static inline u32 * imr_tri_set_type_c(u32 *dl, void *map, int num, int item_size)
+ {
+- int num = vbo->num;
+ int i;
+
+ /* ...prepare list of triangles to draw */
+@@ -732,6 +749,7 @@ static inline void imr_dl_program_setup(struct imr_ctx *ctx, struct imr_cfg *cfg
+ int h = ctx->queue[0].fmt.height;
+ int W = ctx->queue[1].fmt.width;
+ int H = ctx->queue[1].fmt.height;
++ u32 tricr = ctx->color & 0xFFFFFF;
+
+ v4l2_dbg(2, debug, &ctx->imr->v4l2_dev, "setup %u*%u -> %u*%u mapping (type=%x)\n", w, h, W, H, type);
+
+@@ -739,11 +757,17 @@ static inline void imr_dl_program_setup(struct imr_ctx *ctx, struct imr_cfg *cfg
+ *dl++ = IMR_OP_WTS(IMR_TRIMCR, 0xFFFF);
+
+ /* ...set automatic source / destination coordinates generation flags */
+- *dl++ = IMR_OP_WTS(IMR_TRIMSR, __imr_auto_sg_dg_tcm(type) | IMR_TRIM_BFE | IMR_TRIM_TME);
++ *dl++ = IMR_OP_WTS(IMR_TRIMSR, __imr_auto_sg_dg_tcm(type) | __imr_bfe_tme(type));
++
++ /* ...that's probably not needed? - tbd */
++ *dl++ = IMR_OP_SYNCM;
+
+ /* ...set source / destination coordinate precision */
+ *dl++ = IMR_OP_WTS(IMR_UVDPOR, __imr_uvdp(type));
+
++ /* ...that's probably not needed? - tbd */
++ *dl++ = IMR_OP_SYNCM;
++
+ /* ...set luminance/chromacity correction parameters precision */
+ *dl++ = IMR_OP_WTS(IMR_CPDPOR, __imr_cpdp(type));
+
+@@ -776,14 +800,12 @@ static inline void imr_dl_program_setup(struct imr_ctx *ctx, struct imr_cfg *cfg
+ }
+ } else {
+ u16 src_fmt = (iflags & IMR_F_UV_SWAP ? IMR_CMR2_UVFORM : 0) | (iflags & IMR_F_YUV_SWAP ? IMR_CMR2_YUV422FORM : 0);
+- u32 dst_fmt = (oflags & IMR_F_YUV_SWAP ? IMR_TRIC_YCFORM : 0);
+
+ /* ...interleaved input; output is either interleaved or planar */
+ *dl++ = IMR_OP_WTS(IMR_CMRCSR2, IMR_CMR2_YUV422E | src_fmt);
+
+ /* ...destination is always YUYV or UYVY */
+- *dl++ = IMR_OP_WTL(IMR_TRICR, 1);
+- *dl++ = dst_fmt;
++ tricr |= (oflags & IMR_F_YUV_SWAP ? IMR_TRIC_YCFORM : 0);
+
+ /* ...set precision of Y/UV planes and required correction */
+ *dl++ = IMR_OP_WTS(IMR_CMRCSR, src_y_fmt | src_uv_fmt | dst_y_fmt | dst_uv_fmt | __imr_clce(type) | __imr_luce(type));
+@@ -810,6 +832,10 @@ static inline void imr_dl_program_setup(struct imr_ctx *ctx, struct imr_cfg *cfg
+ *dl++ = ((w - 2) << 16) | (w - 1);
+ *dl++ = h - 1;
+
++ /* ...set triangle single color */
++ *dl++ = IMR_OP_WTL(IMR_TRICR, 1);
++ *dl++ = tricr;
++
+ /* ...invoke subroutine for triangles drawing */
+ *dl++ = IMR_OP_GOSUB;
+ *dl++ = subaddr;
+@@ -852,7 +878,7 @@ static int imr_ioctl_map(struct imr_ctx *ctx, struct imr_map_desc *desc)
+ {
+ struct imr_device *imr = ctx->imr;
+ struct imr_mesh *mesh;
+- struct imr_vbo *vbo;
++ int vbo_num;
+ struct imr_cfg *cfg;
+ void *buf, *map;
+ u32 type;
+@@ -925,13 +951,6 @@ static int imr_ioctl_map(struct imr_ctx *ctx, struct imr_map_desc *desc)
+ tri_length = imr_tri_type_a_get_length(mesh, item_size);
+ }
+ } else {
+- /* ...assure we have proper VBO descriptor */
+- if (length < sizeof(struct imr_vbo)) {
+- v4l2_err(&imr->v4l2_dev, "invalid vbo specification size: %u\n", length);
+- ret = -EINVAL;
+- goto out;
+- }
+-
+ /* ...make sure there is no automatic-generation flags */
+ if (type & (IMR_MAP_AUTODG | IMR_MAP_AUTOSG)) {
+ v4l2_err(&imr->v4l2_dev, "invalid auto-dg/sg flags: 0x%x\n", type);
+@@ -939,22 +958,23 @@ static int imr_ioctl_map(struct imr_ctx *ctx, struct imr_map_desc *desc)
+ goto out;
+ }
+
+- vbo = (struct imr_vbo *)buf;
+- length -= sizeof(struct imr_vbo);
+- map = buf + sizeof(struct imr_vbo);
++ map = buf;
+
+ /* ...vertex is given with absolute coordinates */
+ item_size += 8;
+
++ /* ...calculate total number of triangles */
++ vbo_num = length / (3 * item_size);
++
+ /* ...check the length is sane */
+- if (length != vbo->num * 3 * item_size) {
+- v4l2_err(&imr->v4l2_dev, "invalid vbo size: %u*%u*3 != %u\n", vbo->num, item_size, length);
++ if (length != vbo_num * 3 * item_size) {
++ v4l2_err(&imr->v4l2_dev, "invalid vbo size: %u*%u*3 != %u\n", vbo_num, item_size, length);
+ ret = -EINVAL;
+ goto out;
+ }
+
+ /* ...calculate size of trangles drawing subroutine */
+- tri_length = imr_tri_type_c_get_length(vbo, item_size);
++ tri_length = imr_tri_type_c_get_length(vbo_num, item_size);
+ }
+
+ /* ...DL main program shall start with 8-byte aligned address */
+@@ -975,13 +995,16 @@ static int imr_ioctl_map(struct imr_ctx *ctx, struct imr_map_desc *desc)
+ imr_cfg_unref(ctx, ctx->cfg);
+
+ /* ...create new configuration */
+- ctx->cfg = cfg = imr_cfg_create(ctx, dl_size, dl_start_offset);
++ cfg = imr_cfg_create(ctx, dl_size, dl_start_offset);
+ if (IS_ERR(cfg)) {
+ ret = PTR_ERR(cfg);
++ ctx->cfg = NULL;
+ v4l2_err(&imr->v4l2_dev, "failed to create configuration: %d\n", ret);
+ goto out;
+ }
+
++ ctx->cfg = cfg;
++
+ /* ...get pointer to the new display list */
+ dl_vaddr = cfg->dl_vaddr;
+ dl_dma_addr = cfg->dl_dma_addr;
+@@ -994,7 +1017,7 @@ static int imr_ioctl_map(struct imr_ctx *ctx, struct imr_map_desc *desc)
+ imr_tri_set_type_a(dl_vaddr, map, mesh, item_size);
+ }
+ } else {
+- imr_tri_set_type_c(dl_vaddr, map, vbo, item_size);
++ imr_tri_set_type_c(dl_vaddr, map, vbo_num, item_size);
+ }
+
+ /* ...prepare main DL-program */
+@@ -1020,6 +1043,66 @@ static int imr_ioctl_map(struct imr_ctx *ctx, struct imr_map_desc *desc)
+ return ret;
+ }
+
++/* ...set mapping data (function called with video device lock held) */
++static int imr_ioctl_map_raw(struct imr_ctx *ctx, struct imr_map_desc *desc)
++{
++ struct imr_device *imr = ctx->imr;
++ u32 type = desc->type;
++ u32 length = desc->size;
++ struct imr_cfg *cfg;
++ void *dl_vaddr;
++ u32 dl_size;
++ u32 dl_start_offset;
++ dma_addr_t dl_dma_addr;
++
++ /* ...calculate main routine length */
++ dl_size = imr_dl_program_length(ctx);
++ if (!dl_size) {
++ v4l2_err(&imr->v4l2_dev, "format configuration error\n");
++ return -EINVAL;
++ }
++
++ /* ...unref current configuration (will not be used by subsequent jobs) */
++ imr_cfg_unref(ctx, ctx->cfg);
++
++ /* ...create new configuration (starts with zero offset) */
++ cfg = imr_cfg_create(ctx, dl_size, 0);
++ if (IS_ERR(cfg)) {
++ ctx->cfg = NULL;
++ v4l2_err(&imr->v4l2_dev, "failed to create configuration: %ld\n", PTR_ERR(cfg));
++ return PTR_ERR(cfg);
++ }
++
++ ctx->cfg = cfg;
++
++ /* ...get pointer to the new display list */
++ dl_vaddr = cfg->dl_vaddr;
++
++ /* ...prepare main DL-program */
++ imr_dl_program_setup(ctx, cfg, type, dl_vaddr, (u32)(uintptr_t)desc->data);
++
++ /* ...update cropping parameters */
++ cfg->dst_subpixel = (type & IMR_MAP_DDP ? 2 : 0);
++
++ /* ...display list updated successfully */
++ v4l2_dbg(2, debug, &ctx->imr->v4l2_dev, "display-list created: #%u[%08X]:%u[%u]\n",
++ cfg->id, (u32)dl_dma_addr, dl_size, 0);
++
++ if (debug >= 4)
++ print_hex_dump_bytes("DL-", DUMP_PREFIX_OFFSET, dl_vaddr + dl_start_offset, dl_size - dl_start_offset);
++
++ /* ...success */
++ return 0;
++}
++
++/* ...set mapping data (function called with video device lock held) */
++static int imr_ioctl_color(struct imr_ctx *ctx, u32 color)
++{
++ ctx->color = color;
++
++ return 0;
++}
++
+ /*******************************************************************************
+ * V4L2 I/O controls
+ ******************************************************************************/
+@@ -1183,7 +1266,7 @@ static int imr_qbuf(struct file *file, void *priv, struct v4l2_buffer *buf)
+ WARN_ON(!mutex_is_locked(&ctx->imr->mutex));
+
+ /* ...verify the configuration is complete */
+- if (!V4L2_TYPE_IS_OUTPUT(buf->type) && !ctx->cfg) {
++ if (!ctx->cfg) {
+ v4l2_err(&ctx->imr->v4l2_dev, "stream configuration is not complete\n");
+ return -EINVAL;
+ }
+@@ -1265,6 +1348,14 @@ static long imr_default(struct file *file, void *fh, bool valid_prio, unsigned i
+ /* ...set mesh data */
+ return imr_ioctl_map(ctx, (struct imr_map_desc *)arg);
+
++ case VIDIOC_IMR_MESH_RAW:
++ /* ...set mesh data */
++ return imr_ioctl_map_raw(ctx, (struct imr_map_desc *)arg);
++
++ case VIDIOC_IMR_COLOR:
++ /* ...set solid color code */
++ return imr_ioctl_color(ctx, *(u32 *)arg);
++
+ default:
+ return -ENOIOCTLCMD;
+ }
+@@ -1326,6 +1417,9 @@ static int imr_open(struct file *file)
+ /* ...set default cropping parameters */
+ ctx->crop[1] = ctx->crop[3] = 0x3FF;
+
++ /* ...set default color */
++ ctx->color = 0x808080;
++
+ /* ...initialize M2M processing context */
+ ctx->m2m_ctx = v4l2_m2m_ctx_init(imr->m2m_dev, ctx, imr_queue_init);
+ if (IS_ERR(ctx->m2m_ctx)) {
+@@ -1418,8 +1512,11 @@ static unsigned int imr_poll(struct file *file, struct poll_table_struct *wait)
+ return -ERESTARTSYS;
+
+ res = v4l2_m2m_poll(file, ctx->m2m_ctx, wait);
++
+ mutex_unlock(&imr->mutex);
+
++ v4l2_dbg(3, debug, &imr->v4l2_dev, "poll result: %X (ctx=%p)\n", res, ctx);
++
+ return res;
+ }
+
+@@ -1453,7 +1550,6 @@ static const struct v4l2_file_operations imr_fops = {
+ * M2M device interface
+ ******************************************************************************/
+
+-#if 0
+ /* ...job cleanup function */
+ static void imr_cleanup(struct imr_ctx *ctx)
+ {
+@@ -1473,17 +1569,16 @@ static void imr_cleanup(struct imr_ctx *ctx)
+ /* ...release lock before we mark current job as finished */
+ spin_unlock_irqrestore(&imr->lock, flags);
+ }
+-#endif
+
+ /* ...job execution function */
+ static void imr_device_run(void *priv)
+ {
+- struct imr_ctx *ctx = priv;
+- struct imr_device *imr = ctx->imr;
+- struct imr_cfg *cfg;
+- struct vb2_buffer *src_buf, *dst_buf;
+- u32 src_addr, dst_addr;
+- unsigned long flags;
++ struct imr_ctx *ctx = priv;
++ struct imr_device *imr = ctx->imr;
++ struct imr_cfg *cfg;
++ struct vb2_v4l2_buffer *src_buf, *dst_buf;
++ u32 src_addr, dst_addr;
++ unsigned long flags;
+
+ v4l2_dbg(3, debug, &imr->v4l2_dev, "run next job...\n");
+
+@@ -1494,8 +1589,11 @@ static void imr_device_run(void *priv)
+ src_buf = v4l2_m2m_next_src_buf(ctx->m2m_ctx);
+ dst_buf = v4l2_m2m_next_dst_buf(ctx->m2m_ctx);
+
++ /* ...put source/destination buffers sequence numbers */
++ dst_buf->sequence = src_buf->sequence = ctx->sequence++;
++
+ /* ...take configuration pointer associated with input buffer */
+- cfg = to_imr_buffer(to_vb2_v4l2_buffer(src_buf))->cfg;
++ cfg = to_imr_buffer(src_buf)->cfg;
+
+ /* ...cancel software reset state as needed */
+ iowrite32(0, imr->mmio + IMR_CR);
+@@ -1507,8 +1605,8 @@ static void imr_device_run(void *priv)
+ iowrite32(ctx->crop[3] << cfg->dst_subpixel, imr->mmio + IMR_YMAXR);
+
+ /* ...adjust source/destination parameters of the program (interleaved / semiplanar) */
+- *cfg->src_pa_ptr[0] = src_addr = (u32)vb2_dma_contig_plane_dma_addr(src_buf, 0);
+- *cfg->dst_pa_ptr[0] = dst_addr = (u32)vb2_dma_contig_plane_dma_addr(dst_buf, 0);
++ *cfg->src_pa_ptr[0] = src_addr = (u32)vb2_dma_contig_plane_dma_addr(&src_buf->vb2_buf, 0);
++ *cfg->dst_pa_ptr[0] = dst_addr = (u32)vb2_dma_contig_plane_dma_addr(&dst_buf->vb2_buf, 0);
+
+ /* ...adjust source/destination parameters of the UV-plane as needed */
+ if (cfg->src_pa_ptr[1] && cfg->dst_pa_ptr[1]) {
+@@ -1529,6 +1627,9 @@ static void imr_device_run(void *priv)
+ /* ...set display list address */
+ iowrite32(cfg->dl_dma_addr + cfg->dl_start_offset, imr->mmio + IMR_DLSAR);
+
++ /* ...enable texture prefetching */
++ iowrite32(0xACCE5501, imr->mmio + IMR_TPOR);
++
+ /* ...explicitly flush any pending write operations (don't need that, I guess) */
+ wmb();
+
+@@ -1536,7 +1637,7 @@ static void imr_device_run(void *priv)
+ iowrite32(IMR_CR_RS, imr->mmio + IMR_CR);
+
+ /* ...timestamp input buffer */
+- src_buf->timestamp = ktime_get_ns();
++ src_buf->vb2_buf.timestamp = ktime_get_ns();
+
+ /* ...unlock device access */
+ spin_unlock_irqrestore(&imr->lock, flags);
+@@ -1633,13 +1734,14 @@ static irqreturn_t imr_irq_handler(int irq, void *data)
+ dst_buf->timecode = src_buf->timecode;
+ dst_buf->flags = src_buf->flags & (V4L2_BUF_FLAG_TIMECODE | V4L2_BUF_FLAG_KEYFRAME |
+ V4L2_BUF_FLAG_PFRAME | V4L2_BUF_FLAG_BFRAME | V4L2_BUF_FLAG_TSTAMP_SRC_MASK);
+- dst_buf->sequence = src_buf->sequence = ctx->sequence++;
++ //dst_buf->sequence = src_buf->sequence = ctx->sequence++;
++
+ v4l2_m2m_buf_done(src_buf, VB2_BUF_STATE_DONE);
+ v4l2_m2m_buf_done(dst_buf, VB2_BUF_STATE_DONE);
+
+- v4l2_dbg(3, debug, &imr->v4l2_dev, "buffers <0x%08x,0x%08x> done\n",
++ v4l2_dbg(3, debug, &imr->v4l2_dev, "buffers <0x%08x,0x%08x> done (ctx=%p)\n",
+ (u32)vb2_dma_contig_plane_dma_addr(&src_buf->vb2_buf, 0),
+- (u32)vb2_dma_contig_plane_dma_addr(&dst_buf->vb2_buf, 0));
++ (u32)vb2_dma_contig_plane_dma_addr(&dst_buf->vb2_buf, 0), ctx);
+ } else {
+ /* ...operation completed in error; no way to understand what exactly went wrong */
+ v4l2_m2m_buf_done(src_buf, VB2_BUF_STATE_ERROR);
+@@ -1668,6 +1770,8 @@ static irqreturn_t imr_irq_handler(int irq, void *data)
+ * Device probing / removal interface
+ ******************************************************************************/
+
++static struct class *imr_alloc_class;
++
+ static int imr_probe(struct platform_device *pdev)
+ {
+ struct imr_device *imr;
+@@ -1727,6 +1831,26 @@ static int imr_probe(struct platform_device *pdev)
+ goto device_register_rollback;
+ }
+
++ if (!imr_alloc_class) {
++ imr_alloc_class = class_create(THIS_MODULE, "imr-alloc");
++ if (IS_ERR(imr_alloc_class)) {
++ v4l2_err(&imr->v4l2_dev, "Failed to create alloc-device class\n");
++ ret = PTR_ERR(imr_alloc_class);
++ goto m2m_init_rollback;
++ }
++ }
++
++ struct device *adev = device_create(imr_alloc_class, imr->dev, MKDEV(0, 0), NULL, "%s_alloc", dev_name(&pdev->dev));
++ if (IS_ERR(adev)) {
++ v4l2_err(&imr->v4l2_dev, "Failed to create alloc-device\n");
++ ret = PTR_ERR(adev);
++ goto m2m_init_rollback;
++ }
++ adev->dma_mask = &adev->coherent_dma_mask;
++ adev->coherent_dma_mask = DMA_BIT_MASK(32);
++ arch_setup_dma_ops(adev, 0, DMA_BIT_MASK(32) + 1, NULL, true);
++ imr->alloc_dev = adev;
++
+ strlcpy(imr->video_dev.name, dev_name(&pdev->dev), sizeof(imr->video_dev.name));
+ imr->video_dev.fops = &imr_fops;
+ imr->video_dev.ioctl_ops = &imr_ioctl_ops;
+@@ -1765,6 +1889,7 @@ static int imr_remove(struct platform_device *pdev)
+
+ //pm_runtime_disable(imr->v4l2_dev.dev);
+ video_unregister_device(&imr->video_dev);
++ //device_destroy(imr->alloc_dev, MKDEV(0, 0));
+ v4l2_m2m_release(imr->m2m_dev);
+ v4l2_device_unregister(&imr->v4l2_dev);
+
+diff --git a/include/uapi/linux/rcar-imr.h b/include/uapi/linux/rcar-imr.h
+index d02082f..7b8ed0c 100644
+--- a/include/uapi/linux/rcar-imr.h
++++ b/include/uapi/linux/rcar-imr.h
+@@ -48,6 +48,12 @@ struct imr_map_desc {
+ /* ...vertex clockwise-mode order */
+ #define IMR_MAP_TCM (1 << 5)
+
++/* ...texture mapping enable flag */
++#define IMR_MAP_TME (1 << 6)
++
++/* ...bilinear filtration enable flag */
++#define IMR_MAP_BFE (1 << 7)
++
+ /* ...source coordinate decimal point position bit index */
+ #define __IMR_MAP_UVDPOR_SHIFT 8
+ #define __IMR_MAP_UVDPOR(v) (((v) >> __IMR_MAP_UVDPOR_SHIFT) & 0x7)
+@@ -81,18 +87,12 @@ struct imr_mesh {
+
+ } __attribute__((packed));
+
+-/* ...VBO descriptor */
+-struct imr_vbo {
+- /* ...number of triangles */
+- u16 num;
+-
+-} __attribute__((packed));
+-
+-
+ /*******************************************************************************
+ * Private IOCTL codes
+ ******************************************************************************/
+
+ #define VIDIOC_IMR_MESH _IOW('V', BASE_VIDIOC_PRIVATE + 0, struct imr_map_desc)
++#define VIDIOC_IMR_MESH_RAW _IOW('V', BASE_VIDIOC_PRIVATE + 1, struct imr_map_desc)
++#define VIDIOC_IMR_COLOR _IOW('V', BASE_VIDIOC_PRIVATE + 2, u32)
+
+ #endif /* RCAR_IMR_USER_H */
+--
+2.7.4
+
diff --git a/bsp/meta-rcar/meta-rcar-gen3-adas/recipes-kernel/linux/linux-renesas/0106-media-rcar-imr-Add-RSE-support.patch b/bsp/meta-rcar/meta-rcar-gen3-adas/recipes-kernel/linux/linux-renesas/0106-media-rcar-imr-Add-RSE-support.patch
new file mode 100644
index 00000000..1c8d800f
--- /dev/null
+++ b/bsp/meta-rcar/meta-rcar-gen3-adas/recipes-kernel/linux/linux-renesas/0106-media-rcar-imr-Add-RSE-support.patch
@@ -0,0 +1,327 @@
+From a6fd88487f2dda6f8c5ec28230129478711206fb Mon Sep 17 00:00:00 2001
+From: Andrey Dolnikov <andrey.dolnikov@cogentembedded.com>
+Date: Tue, 6 Feb 2018 13:38:34 +0300
+Subject: [PATCH] media: rcar-imr: Add RSE support
+
+This adds RSE support for V3H IMR
+
+Signed-off-by: Andrey Dolnikov <andrey.dolnikov@cogentembedded.com>
+---
+ drivers/media/platform/rcar_imr.c | 143 +++++++++++++++++++++++++++++++
+ include/uapi/linux/rcar-imr.h | 22 ++++-
+ 2 files changed, 165 insertions(+), 2 deletions(-)
+
+diff --git a/drivers/media/platform/rcar_imr.c b/drivers/media/platform/rcar_imr.c
+index 9b601da..7b16765 100644
+--- a/drivers/media/platform/rcar_imr.c
++++ b/drivers/media/platform/rcar_imr.c
+@@ -17,6 +17,7 @@
+ #include <linux/pm_runtime.h>
+ #include <linux/delay.h>
+ #include <linux/rcar-imr.h>
++#include <linux/of.h>
+ #include <media/v4l2-device.h>
+ #include <media/v4l2-ctrls.h>
+ #include <media/v4l2-fh.h>
+@@ -38,6 +39,9 @@ MODULE_PARM_DESC(debug, "Debug level (0-4)");
+ * Local types definitions
+ ******************************************************************************/
+
++/* Number of RSE planes on V3H (non scaled, 1/2, 1/4, 1/8) */
++#define RSE_PLANES_NUM 4
++
+ /* ...configuration data */
+ struct imr_cfg {
+ /* ...display-list main program data */
+@@ -49,6 +53,21 @@ struct imr_cfg {
+ /* ...pointers to the source/destination planes */
+ u32 *src_pa_ptr[2];
+ u32 *dst_pa_ptr[2];
++ /* ...pointers to the RSE destination planes */
++ u32 *dstn_pa_ptr[RSE_PLANES_NUM];
++ u32 *dstr_pa_ptr[RSE_PLANES_NUM];
++
++ /* ...offsets to RSE destination planes */
++ u32 dstnr_offsets[IMR_EXTDST_NUM];
++
++ /* ...RSE logical right shift data */
++ u32 *rscr_ptr;
++ u8 rscr_sc8, rscr_sc4, rscr_sc2;
++
++ /* ...RSE destination stride values */
++ u32 dstnr_strides[IMR_EXTDST_NUM];
++ u32 *striden_ptr[RSE_PLANES_NUM];
++ u32 *strider_ptr[RSE_PLANES_NUM];
+
+ /* ...subpixel destination coordinates space */
+ int dst_subpixel;
+@@ -96,6 +115,8 @@ struct imr_device {
+ struct v4l2_m2m_dev *m2m_dev;
+ struct device *alloc_dev;
+
++ bool rse;
++
+ /* ...do we need that counter really? framework counts fh structures for us - tbd */
+ int refcount;
+
+@@ -219,6 +240,18 @@ struct imr_ctx {
+
+ #define IMR_TPOR 0xF0
+
++#define IMR_RSCSR 0x204
++#define IMR_RSCCR 0x208
++#define IMR_RSCR_RSE 31
++#define IMR_RSCR_SC8 25
++#define IMR_RSCR_SC4 21
++#define IMR_RSCR_SC2 17
++
++#define IMR_DSANRR0 0x210
++#define IMR_DSTNRR0 0x214
++#define IMR_DSARR0 0x218
++#define IMR_DSTRR0 0x21C
++
+ /*******************************************************************************
+ * Auxiliary helpers
+ ******************************************************************************/
+@@ -398,6 +431,7 @@ static int imr_queue_setup(struct vb2_queue *vq,
+ case V4L2_PIX_FMT_YVYU:
+ case V4L2_PIX_FMT_NV16:
+ case V4L2_PIX_FMT_Y10:
++ case V4L2_PIX_FMT_Y12:
+ case V4L2_PIX_FMT_Y16:
+ sizes[0] = w * h * 2;
+ break;
+@@ -750,6 +784,7 @@ static inline void imr_dl_program_setup(struct imr_ctx *ctx, struct imr_cfg *cfg
+ int W = ctx->queue[1].fmt.width;
+ int H = ctx->queue[1].fmt.height;
+ u32 tricr = ctx->color & 0xFFFFFF;
++ int i;
+
+ v4l2_dbg(2, debug, &ctx->imr->v4l2_dev, "setup %u*%u -> %u*%u mapping (type=%x)\n", w, h, W, H, type);
+
+@@ -775,6 +810,38 @@ static inline void imr_dl_program_setup(struct imr_ctx *ctx, struct imr_cfg *cfg
+ *dl++ = IMR_OP_WTS(IMR_CMRCCR, 0xFFFF);
+ *dl++ = IMR_OP_WTS(IMR_CMRCCR2, 0xFFFF);
+
++ if (type & IMR_MAP_RSE) {
++ /* ...enable RSE */
++ *dl++ = IMR_OP_WTL(IMR_RSCCR, 1);
++ *dl++ = 0xffffffff;
++ *dl++ = IMR_OP_WTL(IMR_RSCSR, 1);
++ cfg->rscr_ptr = dl++;
++
++ for (i = 0; i < RSE_PLANES_NUM; i++) {
++ /* ...set destination planes base address and strides */
++ *dl++ = IMR_OP_WTL(IMR_DSANRR0 + i * 0x10, 4);
++ cfg->dstn_pa_ptr[i] = dl++;
++ cfg->striden_ptr[i] = dl++;
++ cfg->dstr_pa_ptr[i] = dl++;
++ cfg->strider_ptr[i] = dl++;
++ }
++
++ cfg->rscr_sc8 = cfg->rscr_sc4 = cfg->rscr_sc2 = 0;
++ memset(cfg->dstnr_offsets, 0, sizeof(cfg->dstnr_offsets));
++ memset(cfg->dstnr_strides, 0, sizeof(cfg->dstnr_strides));
++ } else {
++ /* ...disable RSE */
++ *dl++ = IMR_OP_WTL(IMR_RSCCR, 1);
++ *dl++ = 0xffffffff;
++
++ for (i = 0; i < RSE_PLANES_NUM; i++) {
++ cfg->dstn_pa_ptr[i] = NULL;
++ cfg->striden_ptr[i] = NULL;
++ cfg->dstr_pa_ptr[i] = NULL;
++ cfg->strider_ptr[i] = NULL;
++ }
++ cfg->rscr_ptr = NULL;
++ }
+ /* ...set source/destination addresses of Y/UV plane */
+ *dl++ = IMR_OP_WTL(IMR_DSAR, 2);
+ cfg->dst_pa_ptr[0] = dl++;
+@@ -907,6 +974,12 @@ static int imr_ioctl_map(struct imr_ctx *ctx, struct imr_map_desc *desc)
+
+ type = desc->type;
+
++ /* ...check for RSE */
++ if ((type & IMR_MAP_RSE) && !imr->rse) {
++ v4l2_err(&imr->v4l2_dev, "Rotator & Scaler extension not supported\n");
++ return -EINVAL;
++ }
++
+ /* ...mesh item size calculation */
+ item_size = (type & IMR_MAP_LUCE ? 4 : 0) + (type & IMR_MAP_CLCE ? 4 : 0);
+
+@@ -1055,6 +1128,12 @@ static int imr_ioctl_map_raw(struct imr_ctx *ctx, struct imr_map_desc *desc)
+ u32 dl_start_offset;
+ dma_addr_t dl_dma_addr;
+
++ /* ...check RSE */
++ if ((type & IMR_MAP_RSE) && !imr->rse) {
++ v4l2_err(&imr->v4l2_dev, "Rotator & Scaler extension not supported\n");
++ return -EINVAL;
++ }
++
+ /* ...calculate main routine length */
+ dl_size = imr_dl_program_length(ctx);
+ if (!dl_size) {
+@@ -1103,6 +1182,46 @@ static int imr_ioctl_color(struct imr_ctx *ctx, u32 color)
+ return 0;
+ }
+
++static int imr_extdst_set(struct imr_ctx *ctx, u32 *extdst)
++{
++ struct imr_device *imr = ctx->imr;
++ struct imr_cfg *cfg = ctx->cfg;
++
++ if (!cfg) {
++ v4l2_err(&imr->v4l2_dev, "failed to set V3H extension dst buffers: No active confguration.\n");
++ return -EINVAL;
++ }
++
++ if (copy_from_user((void *) cfg->dstnr_offsets, (void __user *) extdst, sizeof(cfg->dstnr_offsets))) {
++ v4l2_err(&imr->v4l2_dev, "failed to read V3H extension dst buffers\n");
++ return -EFAULT;
++ }
++
++ return 0;
++}
++
++static int imr_extstride_set(struct imr_ctx *ctx, struct imr_rse_param *param)
++{
++ struct imr_device *imr = ctx->imr;
++ struct imr_cfg *cfg = ctx->cfg;
++
++ if (!cfg) {
++ v4l2_err(&imr->v4l2_dev, "failed to set V3H extension buffers params: No active confguration.\n");
++ return -EINVAL;
++ }
++
++ cfg->rscr_sc8 = param->sc8;
++ cfg->rscr_sc4 = param->sc4;
++ cfg->rscr_sc2 = param->sc2;
++
++ if (copy_from_user((void *) cfg->dstnr_strides, (void __user *) param->strides, sizeof(cfg->dstnr_strides))) {
++ v4l2_err(&imr->v4l2_dev, "failed to read V3H extension buffers strides\n");
++ return -EFAULT;
++ }
++
++ return 0;
++}
++
+ /*******************************************************************************
+ * V4L2 I/O controls
+ ******************************************************************************/
+@@ -1356,6 +1475,14 @@ static long imr_default(struct file *file, void *fh, bool valid_prio, unsigned i
+ /* ...set solid color code */
+ return imr_ioctl_color(ctx, *(u32 *)arg);
+
++ case VIDIOC_IMR_EXTDST:
++ /* ...set V3H extension dst buffers */
++ return imr_extdst_set(ctx, *(u32 **)arg);
++
++ case VIDIOC_IMR_EXTSTRIDE:
++ /* ...set V3H extension dst strides */
++ return imr_extstride_set(ctx, (struct imr_rse_param *)arg);
++
+ default:
+ return -ENOIOCTLCMD;
+ }
+@@ -1579,6 +1706,7 @@ static void imr_device_run(void *priv)
+ struct vb2_v4l2_buffer *src_buf, *dst_buf;
+ u32 src_addr, dst_addr;
+ unsigned long flags;
++ int i;
+
+ v4l2_dbg(3, debug, &imr->v4l2_dev, "run next job...\n");
+
+@@ -1608,6 +1736,17 @@ static void imr_device_run(void *priv)
+ *cfg->src_pa_ptr[0] = src_addr = (u32)vb2_dma_contig_plane_dma_addr(&src_buf->vb2_buf, 0);
+ *cfg->dst_pa_ptr[0] = dst_addr = (u32)vb2_dma_contig_plane_dma_addr(&dst_buf->vb2_buf, 0);
+
++ for (i = 0; i < RSE_PLANES_NUM; i++) {
++ if (cfg->rscr_ptr) *cfg->rscr_ptr = (1 << IMR_RSCR_RSE) | (cfg->rscr_sc8 << IMR_RSCR_SC8) |
++ (cfg->rscr_sc4 << IMR_RSCR_SC4) |(cfg->rscr_sc2 << IMR_RSCR_SC2);
++
++ if (cfg->dstn_pa_ptr[i]) *cfg->dstn_pa_ptr[i] = dst_addr + cfg->dstnr_offsets[i];
++ if (cfg->dstr_pa_ptr[i]) *cfg->dstr_pa_ptr[i] = dst_addr + cfg->dstnr_offsets[i + RSE_PLANES_NUM];
++
++ if (cfg->striden_ptr[i]) *cfg->striden_ptr[i] = cfg->dstnr_strides[i];
++ if (cfg->strider_ptr[i]) *cfg->strider_ptr[i] = cfg->dstnr_strides[i + RSE_PLANES_NUM];
++ }
++
+ /* ...adjust source/destination parameters of the UV-plane as needed */
+ if (cfg->src_pa_ptr[1] && cfg->dst_pa_ptr[1]) {
+ *cfg->src_pa_ptr[1] = src_addr + ctx->queue[0].fmt.width * ctx->queue[0].fmt.height;
+@@ -1776,6 +1915,7 @@ static int imr_probe(struct platform_device *pdev)
+ {
+ struct imr_device *imr;
+ struct resource *res;
++ struct device_node *np = pdev->dev.of_node;
+ int ret;
+
+ imr = devm_kzalloc(&pdev->dev, sizeof(*imr), GFP_KERNEL);
+@@ -1786,6 +1926,9 @@ static int imr_probe(struct platform_device *pdev)
+ spin_lock_init(&imr->lock);
+ imr->dev = &pdev->dev;
+
++ /* Check RSE support */
++ imr->rse = of_property_read_bool(np, "rse");
++
+ /* ...memory-mapped registers */
+ res = platform_get_resource(pdev, IORESOURCE_MEM, 0);
+ if (!res) {
+diff --git a/include/uapi/linux/rcar-imr.h b/include/uapi/linux/rcar-imr.h
+index 7b8ed0c..19fdbae 100644
+--- a/include/uapi/linux/rcar-imr.h
++++ b/include/uapi/linux/rcar-imr.h
+@@ -25,8 +25,8 @@ struct imr_map_desc {
+ /* ...total size of the mesh structure */
+ u32 size;
+
+- /* ...map-specific user-pointer */
+- void *data;
++ /* ...map-specific user-pointer */
++ void *data;
+
+ } __attribute__((packed));
+
+@@ -54,6 +54,9 @@ struct imr_map_desc {
+ /* ...bilinear filtration enable flag */
+ #define IMR_MAP_BFE (1 << 7)
+
++/* ...extended functionality (rotation/scaling) enable flag */
++#define IMR_MAP_RSE (1 << 21)
++
+ /* ...source coordinate decimal point position bit index */
+ #define __IMR_MAP_UVDPOR_SHIFT 8
+ #define __IMR_MAP_UVDPOR(v) (((v) >> __IMR_MAP_UVDPOR_SHIFT) & 0x7)
+@@ -88,11 +91,26 @@ struct imr_mesh {
+ } __attribute__((packed));
+
+ /*******************************************************************************
++ * V3H Extension destination data
++ ******************************************************************************/
++/* ...number of V3H extension destination buffers (rotated/non-rotated, scaled 1/1, 1/2, 1/4, 1/8) */
++#define IMR_EXTDST_NUM 8
++
++struct imr_rse_param {
++ /* ...logical right shift data */
++ u8 sc8, sc4, sc2;
++ /* ...destination buffers stride */
++ u32 *strides;
++};
++
++/*******************************************************************************
+ * Private IOCTL codes
+ ******************************************************************************/
+
+ #define VIDIOC_IMR_MESH _IOW('V', BASE_VIDIOC_PRIVATE + 0, struct imr_map_desc)
+ #define VIDIOC_IMR_MESH_RAW _IOW('V', BASE_VIDIOC_PRIVATE + 1, struct imr_map_desc)
+ #define VIDIOC_IMR_COLOR _IOW('V', BASE_VIDIOC_PRIVATE + 2, u32)
++#define VIDIOC_IMR_EXTDST _IOW('V', BASE_VIDIOC_PRIVATE + 3, u32 *)
++#define VIDIOC_IMR_EXTSTRIDE _IOW('V', BASE_VIDIOC_PRIVATE + 4, struct imr_rse_param)
+
+ #endif /* RCAR_IMR_USER_H */
+--
+2.7.4
+
diff --git a/bsp/meta-rcar/meta-rcar-gen3-adas/recipes-kernel/linux/linux-renesas/0109-serial-sh-sci-Fix-minimal-rx_timeout-value.patch b/bsp/meta-rcar/meta-rcar-gen3-adas/recipes-kernel/linux/linux-renesas/0109-serial-sh-sci-Fix-minimal-rx_timeout-value.patch
new file mode 100644
index 00000000..5358670b
--- /dev/null
+++ b/bsp/meta-rcar/meta-rcar-gen3-adas/recipes-kernel/linux/linux-renesas/0109-serial-sh-sci-Fix-minimal-rx_timeout-value.patch
@@ -0,0 +1,34 @@
+From 8b5bbc523cf41fbb8e657f9c81d7821b04ac1b89 Mon Sep 17 00:00:00 2001
+From: Valentine Barshak <valentine.barshak@cogentembedded.com>
+Date: Mon, 26 Nov 2018 05:55:03 +0300
+Subject: [PATCH 055/122] serial: sh-sci: Fix minimal rx_timeout value
+
+Commit "serial: sh-sci: use hrtimer for receive timeout"
+breaks rx_timeout limit check. It used to be calculated
+in jiffies and the minimal value was msecs_to_jiffies(20).
+Since rx_timeout is now measured in uS, the minimal value
+should be 20000 instead of 20.
+
+Signed-off-by: Valentine Barshak <valentine.barshak@cogentembedded.com>
+---
+ drivers/tty/serial/sh-sci.c | 4 ++--
+ 1 file changed, 2 insertions(+), 2 deletions(-)
+
+diff --git a/drivers/tty/serial/sh-sci.c b/drivers/tty/serial/sh-sci.c
+index eba08cd..7ab614f 100644
+--- a/drivers/tty/serial/sh-sci.c
++++ b/drivers/tty/serial/sh-sci.c
+@@ -2523,8 +2523,8 @@ static void sci_set_termios(struct uart_port *port, struct ktermios *termios,
+ s->rx_frame = (10000 * bits) / (baud / 100);
+ #ifdef CONFIG_SERIAL_SH_SCI_DMA
+ s->rx_timeout = s->buf_len_rx * 2 * s->rx_frame;
+- if (s->rx_timeout < 20)
+- s->rx_timeout = 20;
++ if (s->rx_timeout < 20000)
++ s->rx_timeout = 20000;
+ #endif
+
+ if ((termios->c_cflag & CREAD) != 0)
+--
+2.7.4
+
diff --git a/bsp/meta-rcar/meta-rcar-gen3-adas/recipes-kernel/linux/linux-renesas/0110-mmc-tmio-Add-SDHI-SEQUENCER-support.patch b/bsp/meta-rcar/meta-rcar-gen3-adas/recipes-kernel/linux/linux-renesas/0110-mmc-tmio-Add-SDHI-SEQUENCER-support.patch
new file mode 100644
index 00000000..e6964f87
--- /dev/null
+++ b/bsp/meta-rcar/meta-rcar-gen3-adas/recipes-kernel/linux/linux-renesas/0110-mmc-tmio-Add-SDHI-SEQUENCER-support.patch
@@ -0,0 +1,295 @@
+From 39a2bccf80d801eb225b191f1e6ed7cd9ef872b4 Mon Sep 17 00:00:00 2001
+From: Masaharu Hayakawa <masaharu.hayakawa.ry@renesas.com>
+Date: Mon, 11 Dec 2017 20:51:50 +0900
+Subject: [PATCH 53/61] mmc: tmio: Add SDHI-SEQUENCER support
+
+This is Workaround for SDHI-DMAC restriction of R-Car H3(WS1.x)/M3(WS1.0).
+
+Restriction:
+ Mismatch of the transfer completion interrupt time and data transfer
+ completion time.
+
+Overview:
+ It does not take into account the bus response, the transfer completion
+ interrupt IP outputs is in the early out. Therefore, when carrying out
+ the data verification data read from the SD card, there is a possibility
+ that the data of the last sector might be missing.
+ (MMC Interface is also the same.)
+
+S/W Workaround:
+ The last sector data is preserved by reading data for 2 sectors extra
+ in the SDHI Driver of Linux kernel.
+
+SDHI Driver achieves a dummy read for 2 sectors by the SDHI-SEQ function.
+In case of CMD18(MMC_READ_MULTIPLE_BLOCK) were requested,
+1024 bytes are read additionally by CMD18.
+In other cases commands, CMD17 and CMD53(SD_IO_RW_EXTENDED) is
+carried out additionally twice.
+
+Signed-off-by: Masaharu Hayakawa <masaharu.hayakawa.ry@renesas.com>
+---
+ drivers/mmc/host/tmio_mmc.h | 8 ++
+ drivers/mmc/host/tmio_mmc_core.c | 157 +++++++++++++++++++++++++++++++++++++--
+ 2 files changed, 159 insertions(+), 6 deletions(-)
+
+diff --git a/drivers/mmc/host/tmio_mmc.h b/drivers/mmc/host/tmio_mmc.h
+index 815f650..a5d30b2 100644
+--- a/drivers/mmc/host/tmio_mmc.h
++++ b/drivers/mmc/host/tmio_mmc.h
+@@ -122,6 +122,7 @@
+ #define HS400_USE_4TAP BIT(1)
+ #define FORCE_HS200 BIT(2)
+ #define HS400_USE_MANUAL_CALIB BIT(3)
++#define USE_SEQUENCER BIT(4)
+ /* bit[31:16] reserved for HS400 manual calibration */
+ #define HS400_CALIB_MASK GENMASK_ULL(23, 16)
+ #define HS400_OFFSET_MASK GENMASK_ULL(31, 24)
+@@ -144,6 +145,8 @@ struct tmio_mmc_dma_ops {
+ void (*abort)(struct tmio_mmc_host *host);
+ void (*dataend)(struct tmio_mmc_host *host);
+ bool (*dma_irq)(struct tmio_mmc_host *host);
++ void (*seq_start)(struct tmio_mmc_host *host);
++ void (*seq_irq)(struct tmio_mmc_host *host, int status);
+ };
+
+ struct tmio_mmc_host {
+@@ -175,10 +178,15 @@ struct tmio_mmc_host {
+ struct dma_chan *chan_rx;
+ struct dma_chan *chan_tx;
+ struct tasklet_struct dma_issue;
++ struct tasklet_struct seq_complete;
++ bool bounce_sg_mapped;
+ struct scatterlist bounce_sg;
+ u8 *bounce_buf;
+ u32 dma_tranend1;
+
++ /* Sequencer support */
++ bool seq_enabled;
++
+ /* Track lost interrupts */
+ struct delayed_work delayed_reset_work;
+ struct work_struct done;
+diff --git a/drivers/mmc/host/tmio_mmc_core.c b/drivers/mmc/host/tmio_mmc_core.c
+index 2320183..5d3a12c 100644
+--- a/drivers/mmc/host/tmio_mmc_core.c
++++ b/drivers/mmc/host/tmio_mmc_core.c
+@@ -194,6 +194,13 @@ static int tmio_mmc_next_sg(struct tmio_mmc_host *host)
+ static void tmio_mmc_enable_sdio_irq(struct mmc_host *mmc, int enable)
+ {
+ struct tmio_mmc_host *host = mmc_priv(mmc);
++ unsigned int timeout = 1000;
++ unsigned long flags = 0;
++
++ if (host->seq_enabled)
++ spin_lock_irqsave(&host->lock, flags);
++ else
++ __acquire(&host->lock);
+
+ if (enable && !host->sdio_irq_enabled) {
+ u16 sdio_status;
+@@ -210,15 +217,52 @@ static void tmio_mmc_enable_sdio_irq(struct mmc_host *mmc, int enable)
+ sdio_status |= TMIO_SDIO_SETBITS_MASK;
+ sd_ctrl_write16(host, CTL_SDIO_STATUS, sdio_status);
+
+- sd_ctrl_write16(host, CTL_SDIO_IRQ_MASK, host->sdio_irq_mask);
++ if (host->seq_enabled) {
++ while (timeout) {
++ sd_ctrl_write16(host, CTL_SDIO_IRQ_MASK,
++ host->sdio_irq_mask);
++ if (sd_ctrl_read16(host, CTL_SDIO_IRQ_MASK) ==
++ host->sdio_irq_mask)
++ break;
++
++ udelay(1);
++ timeout--;
++ }
++ if (!timeout)
++ dev_warn(&host->pdev->dev,
++ "failed to write CTL_SDIO_IRQ_MASK\n");
++ } else {
++ sd_ctrl_write16(host, CTL_SDIO_IRQ_MASK,
++ host->sdio_irq_mask);
++ }
+ } else if (!enable && host->sdio_irq_enabled) {
+ host->sdio_irq_mask = TMIO_SDIO_MASK_ALL;
+- sd_ctrl_write16(host, CTL_SDIO_IRQ_MASK, host->sdio_irq_mask);
+-
++ if (host->seq_enabled) {
++ while (timeout) {
++ sd_ctrl_write16(host, CTL_SDIO_IRQ_MASK,
++ host->sdio_irq_mask);
++ if (sd_ctrl_read16(host, CTL_SDIO_IRQ_MASK) ==
++ host->sdio_irq_mask)
++ break;
++
++ udelay(1);
++ timeout--;
++ }
++ if (!timeout)
++ dev_warn(&host->pdev->dev,
++ "failed to write CTL_SDIO_IRQ_MASK\n");
++ } else {
++ sd_ctrl_write16(host, CTL_SDIO_IRQ_MASK,
++ host->sdio_irq_mask);
++ }
+ host->sdio_irq_enabled = false;
+ pm_runtime_mark_last_busy(mmc_dev(mmc));
+ pm_runtime_put_autosuspend(mmc_dev(mmc));
+ }
++ if (host->seq_enabled)
++ spin_unlock_irqrestore(&host->lock, flags);
++ else
++ __release(&host->lock);
+ }
+
+ static void tmio_mmc_clk_start(struct tmio_mmc_host *host)
+@@ -791,6 +835,11 @@ static void __tmio_mmc_sdio_irq(struct tmio_mmc_host *host)
+ if (!(pdata->flags & TMIO_MMC_SDIO_IRQ))
+ return;
+
++ if (host->seq_enabled)
++ spin_lock(&host->lock);
++ else
++ __acquire(&host->lock);
++
+ status = sd_ctrl_read16(host, CTL_SDIO_STATUS);
+ ireg = status & TMIO_SDIO_MASK_ALL & ~host->sdio_irq_mask;
+
+@@ -800,6 +849,11 @@ static void __tmio_mmc_sdio_irq(struct tmio_mmc_host *host)
+
+ sd_ctrl_write16(host, CTL_SDIO_STATUS, sdio_status);
+
++ if (host->seq_enabled)
++ spin_unlock(&host->lock);
++ else
++ __release(&host->lock);
++
+ if (mmc->caps & MMC_CAP_SDIO_IRQ && ireg & TMIO_SDIO_STAT_IOIRQ)
+ mmc_signal_sdio_irq(mmc);
+ }
+@@ -818,6 +872,17 @@ irqreturn_t tmio_mmc_irq(int irq, void *devid)
+
+ if (__tmio_mmc_card_detect_irq(host, ireg, status))
+ return IRQ_HANDLED;
++ /* Sequencer Operation End */
++ if (host->seq_enabled) {
++ if (host->dma_ops)
++ if (host->dma_ops->dma_irq(host)) {
++ tmio_mmc_ack_mmc_irqs(host, TMIO_MASK_IRQ &
++ ~(TMIO_STAT_CARD_REMOVE |
++ TMIO_STAT_CARD_INSERT));
++ host->dma_ops->seq_irq(host, status);
++ return IRQ_HANDLED;
++ }
++ }
+ if (__tmio_mmc_sdcard_irq(host, ireg, status))
+ return IRQ_HANDLED;
+ if (host->dma_ops)
+@@ -830,6 +895,60 @@ irqreturn_t tmio_mmc_irq(int irq, void *devid)
+ }
+ EXPORT_SYMBOL_GPL(tmio_mmc_irq);
+
++static int tmio_mmc_start_seq(struct tmio_mmc_host *host,
++ struct mmc_request *mrq)
++{
++ struct tmio_mmc_data *pdata = host->pdata;
++ struct mmc_data *data = mrq->data;
++
++ pr_debug("setup data transfer: blocksize %08x nr_blocks %d\n",
++ data->blksz, data->blocks);
++
++ if (!host->chan_rx || !host->chan_tx) {
++ host->force_pio = true;
++ return 0;
++ }
++
++ /* Some hardware cannot perform 2 byte requests in 4 bit mode */
++ if (host->mmc->ios.bus_width == MMC_BUS_WIDTH_4) {
++ int blksz_2bytes = pdata->flags & TMIO_MMC_BLKSZ_2BYTES;
++
++ if (data->blksz < 2 || (data->blksz < 4 && !blksz_2bytes)) {
++ pr_err("%s: %d byte block unsupported in 4 bit mode\n",
++ mmc_hostname(host->mmc), data->blksz);
++ return -EINVAL;
++ }
++ }
++
++ tmio_mmc_init_sg(host, data);
++ host->cmd = mrq->cmd;
++ host->data = data;
++
++ sd_ctrl_write16(host, CTL_STOP_INTERNAL_ACTION, 0);
++
++ if (host->dma_ops)
++ host->dma_ops->seq_start(host);
++
++ if (host->force_pio) {
++ host->cmd = NULL;
++ host->data = NULL;
++ }
++
++ return 0;
++}
++
++static void tmio_mmc_set_blklen_and_blkcnt(struct tmio_mmc_host *host,
++ struct mmc_data *data)
++{
++ host->force_pio = true;
++ tmio_mmc_init_sg(host, data);
++ host->data = data;
++
++ /* Set transfer length / blocksize */
++ sd_ctrl_write16(host, CTL_SD_XFER_LEN, data->blksz);
++ sd_ctrl_write16(host, CTL_XFER_BLK_COUNT, data->blocks);
++}
++
+ static int tmio_mmc_start_data(struct tmio_mmc_host *host,
+ struct mmc_data *data)
+ {
+@@ -958,14 +1077,40 @@ static void tmio_process_mrq(struct tmio_mmc_host *host,
+ struct mmc_command *cmd;
+ int ret;
+
++ if (host->seq_enabled) {
++ if (mrq->data) {
++ /* Start SEQ */
++ ret = tmio_mmc_start_seq(host, mrq);
++ if (ret) {
++ goto fail;
++ } else if (!host->force_pio) {
++ /*
++ * Succeeded to start SEQ
++ * Wait SEQ interrupt
++ */
++ schedule_delayed_work(
++ &host->delayed_reset_work,
++ msecs_to_jiffies(CMDREQ_TIMEOUT));
++ return;
++ }
++ }
++ }
+ if (mrq->sbc && host->cmd != mrq->sbc) {
+ cmd = mrq->sbc;
+ } else {
+ cmd = mrq->cmd;
+ if (mrq->data) {
+- ret = tmio_mmc_start_data(host, mrq->data);
+- if (ret)
+- goto fail;
++ if (host->seq_enabled) {
++ /*
++ * Failed to start SEQ
++ * Set blklen and blkcnt to transfer in PIO mode
++ */
++ tmio_mmc_set_blklen_and_blkcnt(host, mrq->data);
++ } else {
++ ret = tmio_mmc_start_data(host, mrq->data);
++ if (ret)
++ goto fail;
++ }
+ }
+ }
+
+--
+2.7.4
+
diff --git a/bsp/meta-rcar/meta-rcar-gen3-adas/recipes-kernel/linux/linux-renesas/0111-mmc-renesas_sdhi-Add-SDHI-SEQUENCER-support.patch b/bsp/meta-rcar/meta-rcar-gen3-adas/recipes-kernel/linux/linux-renesas/0111-mmc-renesas_sdhi-Add-SDHI-SEQUENCER-support.patch
new file mode 100644
index 00000000..814e58f5
--- /dev/null
+++ b/bsp/meta-rcar/meta-rcar-gen3-adas/recipes-kernel/linux/linux-renesas/0111-mmc-renesas_sdhi-Add-SDHI-SEQUENCER-support.patch
@@ -0,0 +1,747 @@
+From e7e0800e6b1c083355cbd0d5dccd3f6ad56a80a3 Mon Sep 17 00:00:00 2001
+From: Masaharu Hayakawa <masaharu.hayakawa.ry@renesas.com>
+Date: Mon, 11 Dec 2017 20:53:39 +0900
+Subject: [PATCH 54/61] mmc: renesas_sdhi: Add SDHI-SEQUENCER support
+
+This is Workaround for SDHI-DMAC restriction of R-Car H3(WS1.x)/M3(WS1.0).
+
+Restriction:
+ Mismatch of the transfer completion interrupt time and data transfer
+ completion time.
+
+Overview:
+ It does not take into account the bus response, the transfer completion
+ interrupt IP outputs is in the early out. Therefore, when carrying out
+ the data verification data read from the SD card, there is a possibility
+ that the data of the last sector might be missing.
+ (MMC Interface is also the same.)
+
+S/W Workaround:
+ The last sector data is preserved by reading data for 2 sectors extra
+ in the SDHI Driver of Linux kernel.
+
+SDHI Driver achieves a dummy read for 2 sectors by the SDHI-SEQ function.
+In case of CMD18(MMC_READ_MULTIPLE_BLOCK) were requested,
+1024 bytes are read additionally by CMD18.
+In other cases commands, CMD17 and CMD53(SD_IO_RW_EXTENDED) is
+carried out additionally twice.
+
+Signed-off-by: Masaharu Hayakawa <masaharu.hayakawa.ry@renesas.com>
+---
+ drivers/mmc/host/renesas_sdhi_core.c | 17 +-
+ drivers/mmc/host/renesas_sdhi_internal_dmac.c | 556 +++++++++++++++++++++++++-
+ 2 files changed, 570 insertions(+), 3 deletions(-)
+
+diff --git a/drivers/mmc/host/renesas_sdhi_core.c b/drivers/mmc/host/renesas_sdhi_core.c
+index e4d9dd1..6964161 100644
+--- a/drivers/mmc/host/renesas_sdhi_core.c
++++ b/drivers/mmc/host/renesas_sdhi_core.c
+@@ -259,12 +259,12 @@ static int renesas_sdhi_start_signal_voltage_switch(struct mmc_host *mmc,
+ static const struct soc_device_attribute sdhi_quirks_match[] = {
+ { .soc_id = "r8a7795", .revision = "ES1.*",
+ .data = (void *)(DTRAEND1_SET_BIT17 | HS400_USE_4TAP |
+- FORCE_HS200), },
++ FORCE_HS200 | USE_SEQUENCER), },
+ { .soc_id = "r8a7795", .revision = "ES2.0",
+ .data = (void *)HS400_USE_4TAP, },
+ { .soc_id = "r8a7796", .revision = "ES1.0",
+ .data = (void *)(DTRAEND1_SET_BIT17 | HS400_USE_4TAP |
+- FORCE_HS200), },
++ FORCE_HS200 | USE_SEQUENCER), },
+ { .soc_id = "r8a7796", .revision = "ES1.1",
+ .data = (void *)(HS400_USE_4TAP | FORCE_HS200), },
+ { .soc_id = "r8a77965",
+@@ -835,6 +835,9 @@ int renesas_sdhi_probe(struct platform_device *pdev,
+ host->hs400_use_4tap = (host->sdhi_quirks & HS400_USE_4TAP) ?
+ true : false;
+
++ host->seq_enabled = (host->sdhi_quirks & USE_SEQUENCER) ?
++ true : false;
++
+ if (of_data) {
+ mmc_data->flags |= of_data->tmio_flags;
+ mmc_data->ocr_mask = of_data->tmio_ocr_mask;
+@@ -848,6 +851,16 @@ int renesas_sdhi_probe(struct platform_device *pdev,
+ priv->scc_offset = of_data->scc_offset;
+ }
+
++ if (host->seq_enabled) {
++ mmc_data->max_blk_count = 0xffffffff / 512;
++#ifdef CONFIG_MMC_BLOCK_BOUNCE
++ /* (CMD23+CMD18)*1 + (dummy read command) */
++ mmc_data->max_segs = 1;
++#else
++ /* (CMD23+CMD18)*3 + (dummy read command) */
++ mmc_data->max_segs = 3;
++#endif
++ }
+ host->write16_hook = renesas_sdhi_write16_hook;
+ host->clk_enable = renesas_sdhi_clk_enable;
+ host->clk_update = renesas_sdhi_clk_update;
+diff --git a/drivers/mmc/host/renesas_sdhi_internal_dmac.c b/drivers/mmc/host/renesas_sdhi_internal_dmac.c
+index a563cea..069b3dc 100644
+--- a/drivers/mmc/host/renesas_sdhi_internal_dmac.c
++++ b/drivers/mmc/host/renesas_sdhi_internal_dmac.c
+@@ -15,6 +15,9 @@
+ #include <linux/io-64-nonatomic-hi-lo.h>
+ #include <linux/mfd/tmio.h>
+ #include <linux/mmc/host.h>
++#include <linux/mmc/mmc.h>
++#include <linux/mmc/sd.h>
++#include <linux/mmc/sdio.h>
+ #include <linux/mod_devicetable.h>
+ #include <linux/module.h>
+ #include <linux/pagemap.h>
+@@ -24,6 +27,9 @@
+ #include "renesas_sdhi.h"
+ #include "tmio_mmc.h"
+
++#define DM_CM_SEQ_REGSET 0x800
++#define DM_CM_SEQ_MODE 0x808
++#define DM_CM_SEQ_CTRL 0x810
+ #define DM_CM_DTRAN_MODE 0x820
+ #define DM_CM_DTRAN_CTRL 0x828
+ #define DM_CM_RST 0x830
+@@ -31,7 +37,16 @@
+ #define DM_CM_INFO1_MASK 0x848
+ #define DM_CM_INFO2 0x850
+ #define DM_CM_INFO2_MASK 0x858
++#define DM_CM_TUNING_STAT 0x860
++#define DM_CM_SEQ_STAT 0x868
+ #define DM_DTRAN_ADDR 0x880
++#define DM_SEQ_CMD 0x8a0
++#define DM_SEQ_ARG 0x8a8
++#define DM_SEQ_SIZE 0x8b0
++#define DM_SEQ_SECCNT 0x8b8
++#define DM_SEQ_RSP 0x8c0
++#define DM_SEQ_RSP_CHK 0x8c8
++#define DM_SEQ_ADDR 0x8d0
+
+ /* DM_CM_DTRAN_MODE */
+ #define DTRAN_MODE_CH_NUM_CH0 0 /* "downstream" = for write commands */
+@@ -45,6 +60,7 @@
+ /* DM_CM_RST */
+ #define RST_DTRANRST1 BIT(9)
+ #define RST_DTRANRST0 BIT(8)
++#define RST_SEQRST BIT(0)
+ #define RST_RESERVED_BITS GENMASK_ULL(31, 0)
+
+ /* DM_CM_INFO1 and DM_CM_INFO1_MASK */
+@@ -52,6 +68,8 @@
+ #define INFO1_DTRANEND1_BIT20 BIT(20)
+ #define INFO1_DTRANEND1_BIT17 BIT(17)
+ #define INFO1_DTRANEND0 BIT(16)
++#define INFO1_SEQSUSPEND BIT(8)
++#define INFO1_SEQEND BIT(0)
+
+ /* DM_CM_INFO2 and DM_CM_INFO2_MASK */
+ #define INFO2_DTRANERR1 BIT(17)
+@@ -133,7 +151,8 @@ renesas_sdhi_internal_dmac_enable_dma(struct tmio_mmc_host *host, bool enable)
+ INFO1_CLEAR);
+
+ if (priv->dma_priv.enable) {
+- host->dma_irq_mask = ~(host->dma_tranend1 | INFO1_DTRANEND0);
++ host->dma_irq_mask = host->seq_enabled ?
++ 0xffffffff : ~(host->dma_tranend1 | INFO1_DTRANEND0);
+ priv->dma_priv.enable(host, enable);
+ renesas_sdhi_internal_dmac_dm_write(host, DM_CM_INFO1_MASK,
+ host->dma_irq_mask);
+@@ -146,6 +165,9 @@ renesas_sdhi_internal_dmac_abort_dma(struct tmio_mmc_host *host) {
+
+ renesas_sdhi_internal_dmac_enable_dma(host, false);
+
++ if (host->seq_enabled)
++ val |= RST_SEQRST;
++
+ renesas_sdhi_internal_dmac_dm_write(host, DM_CM_RST,
+ RST_RESERVED_BITS & ~val);
+ renesas_sdhi_internal_dmac_dm_write(host, DM_CM_RST,
+@@ -154,6 +176,12 @@ renesas_sdhi_internal_dmac_abort_dma(struct tmio_mmc_host *host) {
+ clear_bit(SDHI_INTERNAL_DMAC_RX_IN_USE, &global_flags);
+
+ renesas_sdhi_internal_dmac_enable_dma(host, true);
++
++ if (host->bounce_sg_mapped) {
++ dma_unmap_sg(&host->pdev->dev, &host->bounce_sg, 1,
++ DMA_FROM_DEVICE);
++ host->bounce_sg_mapped = false;
++ }
+ }
+
+ static void
+@@ -229,6 +257,12 @@ static void renesas_sdhi_internal_dmac_complete_tasklet_fn(unsigned long arg)
+ host->data->host_cookie = COOKIE_UNMAPPED;
+ }
+
++ if (host->bounce_sg_mapped) {
++ dma_unmap_sg(&host->pdev->dev, &host->bounce_sg, 1,
++ DMA_FROM_DEVICE);
++ host->bounce_sg_mapped = false;
++ }
++
+ if (host->data->flags & MMC_DATA_READ)
+ clear_bit(SDHI_INTERNAL_DMAC_RX_IN_USE, &global_flags);
+
+@@ -237,11 +271,435 @@ static void renesas_sdhi_internal_dmac_complete_tasklet_fn(unsigned long arg)
+ spin_unlock_irq(&host->lock);
+ }
+
++static void
++renesas_sdhi_internal_dmac_seq_complete_tasklet_fn(unsigned long arg)
++{
++ renesas_sdhi_internal_dmac_complete_tasklet_fn(arg);
++}
++
++/* DM_CM_SEQ_REGSET bits */
++#define DM_CM_SEQ_REGSET_TABLE_NUM BIT(8)
++
++/* DM_CM_SEQ_CTRL bits */
++#define DM_CM_SEQ_CTRL_SEQ_TABLE BIT(28)
++#define DM_CM_SEQ_CTRL_T_NUM BIT(24)
++#define DM_CM_SEQ_CTRL_SEQ_TYPE_SD BIT(16)
++#define DM_CM_SEQ_CTRL_START_NUM(x) ((x) << 12)
++#define DM_CM_SEQ_CTRL_END_NUM(x) ((x) << 8)
++#define DM_CM_SEQ_CTRL_SEQ_START BIT(0)
++
++/* DM_SEQ_CMD bits */
++#define DM_SEQ_CMD_MULTI BIT(13)
++#define DM_SEQ_CMD_DIO BIT(12)
++#define DM_SEQ_CMD_CMDTYP BIT(11)
++#define DM_SEQ_CMD_RSP_NONE (BIT(9) | BIT(8))
++#define DM_SEQ_CMD_RSP_R1 BIT(10)
++#define DM_SEQ_CMD_RSP_R1B (BIT(10) | BIT(8))
++#define DM_SEQ_CMD_RSP_R2 (BIT(10) | BIT(9))
++#define DM_SEQ_CMD_RSP_R3 (BIT(10) | BIT(9) | BIT(8))
++#define DM_SEQ_CMD_NONAUTOSTP BIT(7)
++#define DM_SEQ_CMD_APP BIT(6)
++
++#define MAX_CONTEXT_NUM 8
++
++struct tmio_mmc_context {
++ u64 seq_cmd;
++ u64 seq_arg;
++ u64 seq_size;
++ u64 seq_seccnt;
++ u64 seq_rsp;
++ u64 seq_rsp_chk;
++ u64 seq_addr;
++};
++
++static void
++renesas_sdhi_internal_dmac_set_seq_context(struct tmio_mmc_host *host,
++ int ctxt_num,
++ struct tmio_mmc_context *ctxt)
++{
++ u64 val;
++
++ WARN_ON(ctxt_num >= MAX_CONTEXT_NUM);
++
++ /* set sequencer table/context number */
++ if (ctxt_num < 4)
++ val = ctxt_num;
++ else
++ val = DM_CM_SEQ_REGSET_TABLE_NUM | (ctxt_num - 4);
++ renesas_sdhi_internal_dmac_dm_write(host, DM_CM_SEQ_REGSET, val);
++
++ /* set command parameter */
++ renesas_sdhi_internal_dmac_dm_write(host, DM_SEQ_CMD, ctxt->seq_cmd);
++ renesas_sdhi_internal_dmac_dm_write(host, DM_SEQ_ARG, ctxt->seq_arg);
++ renesas_sdhi_internal_dmac_dm_write(host, DM_SEQ_SIZE, ctxt->seq_size);
++ renesas_sdhi_internal_dmac_dm_write(host, DM_SEQ_SECCNT,
++ ctxt->seq_seccnt);
++ renesas_sdhi_internal_dmac_dm_write(host, DM_SEQ_RSP, ctxt->seq_rsp);
++ renesas_sdhi_internal_dmac_dm_write(host, DM_SEQ_RSP_CHK,
++ ctxt->seq_rsp_chk);
++ renesas_sdhi_internal_dmac_dm_write(host, DM_SEQ_ADDR, ctxt->seq_addr);
++}
++
++static int renesas_sdhi_internal_dmac_set_seq_table(struct tmio_mmc_host *host,
++ struct mmc_request *mrq,
++ struct scatterlist *sg,
++ bool ipmmu_on)
++{
++ struct mmc_card *card = host->mmc->card;
++ struct mmc_data *data = mrq->data;
++ struct scatterlist *sg_tmp;
++ struct tmio_mmc_context ctxt;
++ unsigned int blksz, blocks;
++ u32 cmd_opcode, cmd_flag, cmd_arg;
++ u32 sbc_opcode = 0, sbc_arg = 0;
++ int i, ctxt_cnt = 0;
++
++ /* SD_COMBO media not tested */
++ cmd_opcode = (mrq->cmd->opcode & 0x3f);
++ cmd_flag = DM_SEQ_CMD_CMDTYP;
++ if (data->flags & MMC_DATA_READ)
++ cmd_flag |= DM_SEQ_CMD_DIO;
++ if (mmc_op_multi(mrq->cmd->opcode) ||
++ (cmd_opcode == SD_IO_RW_EXTENDED && mrq->cmd->arg & 0x08000000))
++ cmd_flag |= DM_SEQ_CMD_MULTI;
++ if (mrq->sbc || cmd_opcode == SD_IO_RW_EXTENDED)
++ cmd_flag |= DM_SEQ_CMD_NONAUTOSTP;
++
++ switch (mmc_resp_type(mrq->cmd)) {
++ case MMC_RSP_NONE:
++ cmd_flag |= DM_SEQ_CMD_RSP_NONE;
++ break;
++ case MMC_RSP_R1:
++ case MMC_RSP_R1 & ~MMC_RSP_CRC:
++ cmd_flag |= DM_SEQ_CMD_RSP_R1;
++ break;
++ case MMC_RSP_R1B:
++ cmd_flag |= DM_SEQ_CMD_RSP_R1B;
++ break;
++ case MMC_RSP_R2:
++ cmd_flag |= DM_SEQ_CMD_RSP_R2;
++ break;
++ case MMC_RSP_R3:
++ cmd_flag |= DM_SEQ_CMD_RSP_R3;
++ break;
++ default:
++ pr_debug("Unknown response type %d\n", mmc_resp_type(mrq->cmd));
++ return -EINVAL;
++ }
++
++ cmd_arg = mrq->cmd->arg;
++ if (cmd_opcode == SD_IO_RW_EXTENDED && cmd_arg & 0x08000000) {
++ /* SDIO CMD53 block mode */
++ cmd_arg &= ~0x1ff;
++ }
++
++ if (mrq->sbc) {
++ sbc_opcode = (mrq->sbc->opcode & 0x3f) | DM_SEQ_CMD_RSP_R1;
++ sbc_arg = mrq->sbc->arg & (MMC_CMD23_ARG_REL_WR |
++ MMC_CMD23_ARG_PACKED | MMC_CMD23_ARG_TAG_REQ);
++ }
++
++ blksz = data->blksz;
++ if (ipmmu_on) {
++ blocks = data->blocks;
++ memset(&ctxt, 0, sizeof(ctxt));
++
++ if (sbc_opcode) {
++ /* set CMD23 */
++ ctxt.seq_cmd = sbc_opcode;
++ ctxt.seq_arg = sbc_arg | blocks;
++ renesas_sdhi_internal_dmac_set_seq_context
++ (host, ctxt_cnt, &ctxt);
++ ctxt_cnt++;
++ }
++
++ /* set CMD */
++ ctxt.seq_cmd = cmd_opcode | cmd_flag;
++ ctxt.seq_arg = cmd_arg;
++ if (cmd_opcode == SD_IO_RW_EXTENDED && cmd_arg & 0x08000000) {
++ /* SDIO CMD53 block mode */
++ ctxt.seq_arg |= blocks;
++ }
++ ctxt.seq_size = blksz;
++ ctxt.seq_seccnt = blocks;
++ ctxt.seq_addr = sg_dma_address(sg);
++ renesas_sdhi_internal_dmac_set_seq_context
++ (host, ctxt_cnt, &ctxt);
++ } else {
++ for_each_sg(sg, sg_tmp, host->sg_len, i) {
++ blocks = sg_tmp->length / blksz;
++ memset(&ctxt, 0, sizeof(ctxt));
++
++ if (sbc_opcode) {
++ /* set CMD23 */
++ ctxt.seq_cmd = sbc_opcode;
++ ctxt.seq_arg = sbc_arg | blocks;
++ if (sbc_arg & MMC_CMD23_ARG_TAG_REQ && card &&
++ card->ext_csd.data_tag_unit_size &&
++ blksz * blocks <
++ card->ext_csd.data_tag_unit_size)
++ ctxt.seq_arg &= ~MMC_CMD23_ARG_TAG_REQ;
++ renesas_sdhi_internal_dmac_set_seq_context
++ (host, ctxt_cnt, &ctxt);
++ ctxt_cnt++;
++ }
++
++ /* set CMD */
++ ctxt.seq_cmd = cmd_opcode | cmd_flag;
++ ctxt.seq_arg = cmd_arg;
++ if (cmd_opcode == SD_IO_RW_EXTENDED &&
++ cmd_arg & 0x08000000) {
++ /* SDIO CMD53 block mode */
++ ctxt.seq_arg |= blocks;
++ }
++ ctxt.seq_size = blksz;
++ ctxt.seq_seccnt = blocks;
++ ctxt.seq_addr = sg_dma_address(sg_tmp);
++ renesas_sdhi_internal_dmac_set_seq_context
++ (host, ctxt_cnt, &ctxt);
++
++ if (i < (host->sg_len - 1)) {
++ /* increment address */
++ if (cmd_opcode == SD_IO_RW_EXTENDED) {
++ /*
++ * sg_len should be 1 in SDIO CMD53
++ * byte mode
++ */
++ WARN_ON(!(cmd_arg & 0x08000000));
++ if (cmd_arg & 0x04000000) {
++ /*
++ * SDIO CMD53 address
++ * increment mode
++ */
++ cmd_arg +=
++ (blocks * blksz) << 9;
++ }
++ } else {
++ /* card uses block-addressing */
++ if (card && !(card->state & 0x4))
++ cmd_arg += blocks * blksz;
++ else
++ cmd_arg += blocks;
++ }
++ ctxt_cnt++;
++ }
++ }
++ }
++
++ if (data->flags & MMC_DATA_READ) {
++ /* dummy read */
++ if (cmd_opcode == MMC_READ_MULTIPLE_BLOCK && card &&
++ blksz == 512 && data->blocks > 1) {
++ memset(&ctxt, 0, sizeof(ctxt));
++ if (sbc_opcode) {
++ /* set CMD23 */
++ ctxt.seq_cmd = sbc_opcode;
++ ctxt.seq_arg = sbc_arg | 2;
++ if (sbc_arg & MMC_CMD23_ARG_TAG_REQ &&
++ card->ext_csd.data_tag_unit_size &&
++ blksz * 2 <
++ card->ext_csd.data_tag_unit_size)
++ ctxt.seq_arg &= ~MMC_CMD23_ARG_TAG_REQ;
++ ctxt_cnt++;
++ renesas_sdhi_internal_dmac_set_seq_context
++ (host, ctxt_cnt, &ctxt);
++ }
++
++ /* set CMD18 */
++ ctxt.seq_cmd = cmd_opcode | cmd_flag;
++ ctxt.seq_arg = mrq->cmd->arg;
++ /* card uses block-addressing */
++ if (!(card->state & 0x4))
++ ctxt.seq_arg += (data->blocks - 2) * 512;
++ else
++ ctxt.seq_arg += data->blocks - 2;
++ ctxt.seq_size = 512;
++ ctxt.seq_seccnt = 2;
++ ctxt.seq_addr = sg_dma_address(&host->bounce_sg);
++ ctxt_cnt++;
++ renesas_sdhi_internal_dmac_set_seq_context
++ (host, ctxt_cnt, &ctxt);
++ } else {
++ if (cmd_opcode == SD_SWITCH) {
++ /* set SD CMD6 twice */
++ ctxt.seq_addr =
++ sg_dma_address(&host->bounce_sg);
++ } else if ((card && (mmc_card_sdio(card) ||
++ card->type == MMC_TYPE_SD_COMBO)) ||
++ cmd_opcode == SD_IO_RW_EXTENDED) {
++ /*
++ * In case of SDIO/SD_COMBO,
++ * read Common I/O Area 0x0-0x1FF twice.
++ */
++ memset(&ctxt, 0, sizeof(ctxt));
++ ctxt.seq_cmd = SD_IO_RW_EXTENDED |
++ DM_SEQ_CMD_CMDTYP |
++ DM_SEQ_CMD_DIO |
++ DM_SEQ_CMD_NONAUTOSTP |
++ DM_SEQ_CMD_RSP_R1;
++ /*
++ * SD_IO_RW_EXTENDED argument format:
++ * [31] R/W flag -> 0
++ * [30:28] Function number -> 0x0 selects
++ * Common I/O Area
++ * [27] Block mode -> 0
++ * [26] Increment address -> 1
++ * [25:9] Regiser address -> 0x0
++ * [8:0] Byte/block count -> 0x0 -> 512Bytes
++ */
++ ctxt.seq_arg = 0x04000000;
++ ctxt.seq_size = 512;
++ ctxt.seq_seccnt = 1;
++ ctxt.seq_addr =
++ sg_dma_address(&host->bounce_sg);
++ } else {
++ /* set CMD17 twice */
++ memset(&ctxt, 0, sizeof(ctxt));
++ ctxt.seq_cmd = MMC_READ_SINGLE_BLOCK |
++ DM_SEQ_CMD_CMDTYP |
++ DM_SEQ_CMD_DIO |
++ DM_SEQ_CMD_RSP_R1;
++ if ((cmd_opcode == MMC_READ_SINGLE_BLOCK ||
++ cmd_opcode == MMC_READ_MULTIPLE_BLOCK) &&
++ blksz == 512)
++ ctxt.seq_arg = mrq->cmd->arg;
++ else
++ ctxt.seq_arg = 0;
++ ctxt.seq_size = 512;
++ ctxt.seq_seccnt = 1;
++ ctxt.seq_addr =
++ sg_dma_address(&host->bounce_sg);
++ }
++
++ for (i = 0; i < 2; i++) {
++ ctxt_cnt++;
++ renesas_sdhi_internal_dmac_set_seq_context
++ (host, ctxt_cnt, &ctxt);
++ }
++ }
++ }
++
++ return ctxt_cnt;
++}
++
++void renesas_sdhi_internal_dmac_start_sequencer(struct tmio_mmc_host *host)
++{
++ struct mmc_card *card = host->mmc->card;
++ struct scatterlist *sg = host->sg_ptr;
++ struct mmc_host *mmc = host->mmc;
++ struct mmc_request *mrq = host->mrq;
++ struct mmc_data *data = mrq->data;
++ int ret, ctxt_num;
++ u64 val;
++ bool ipmmu_on = false;
++
++ /* This DMAC cannot handle if sg_len larger than max_segs */
++ if (mmc->max_segs == 1 || mmc->max_segs == 3)
++ WARN_ON(host->sg_len > mmc->max_segs);
++ else
++ ipmmu_on = true;
++
++ dev_dbg(&host->pdev->dev, "%s: %d, %x\n", __func__, host->sg_len,
++ data->flags);
++
++ if (!card && host->mrq->cmd->opcode == MMC_SEND_TUNING_BLOCK) {
++ /*
++ * workaround: if card is NULL,
++ * we can not decide a dummy read command to be added
++ * to the CMD19.
++ */
++ goto force_pio;
++ }
++
++ ret = tmio_mmc_pre_dma_transfer(host, data, COOKIE_MAPPED);
++ if (ret == 0)
++ goto force_pio;
++
++ if (ipmmu_on) {
++ /*
++ * workaround: if we use IPMMU, sometimes unhandled error
++ * happened
++ */
++ switch (host->mrq->cmd->opcode) {
++ case MMC_SEND_TUNING_BLOCK_HS200:
++ case MMC_SEND_TUNING_BLOCK:
++ goto force_pio;
++ default:
++ break;
++ }
++ }
++
++ if (data->flags & MMC_DATA_READ && !host->bounce_sg_mapped) {
++ if (dma_map_sg(&host->pdev->dev, &host->bounce_sg, 1,
++ DMA_FROM_DEVICE) <= 0) {
++ dev_err(&host->pdev->dev, "%s: bounce_sg map failed\n",
++ __func__);
++ goto force_pio;
++ }
++ host->bounce_sg_mapped = true;
++ }
++
++ renesas_sdhi_internal_dmac_enable_dma(host, true);
++ /* set context */
++ ctxt_num = renesas_sdhi_internal_dmac_set_seq_table(host, mrq, sg,
++ ipmmu_on);
++ if (ctxt_num < 0)
++ goto unmap_sg;
++ /* set dma mode */
++ renesas_sdhi_internal_dmac_dm_write(host, DM_CM_DTRAN_MODE,
++ DTRAN_MODE_BUS_WID_TH);
++ /* enable SEQEND irq */
++ renesas_sdhi_internal_dmac_dm_write(host, DM_CM_INFO1_MASK,
++ GENMASK_ULL(31, 0) & ~INFO1_SEQEND);
++
++ if (ctxt_num < 4) {
++ /* issue table0 commands */
++ val = DM_CM_SEQ_CTRL_SEQ_TYPE_SD |
++ DM_CM_SEQ_CTRL_START_NUM(0) |
++ DM_CM_SEQ_CTRL_END_NUM(ctxt_num) |
++ DM_CM_SEQ_CTRL_SEQ_START;
++ renesas_sdhi_internal_dmac_dm_write(host, DM_CM_SEQ_CTRL, val);
++ } else {
++ /* issue table0 commands */
++ val = DM_CM_SEQ_CTRL_SEQ_TYPE_SD |
++ DM_CM_SEQ_CTRL_T_NUM |
++ DM_CM_SEQ_CTRL_START_NUM(0) |
++ DM_CM_SEQ_CTRL_END_NUM(3) |
++ DM_CM_SEQ_CTRL_SEQ_START;
++ renesas_sdhi_internal_dmac_dm_write(host, DM_CM_SEQ_CTRL, val);
++ /* issue table1 commands */
++ val = DM_CM_SEQ_CTRL_SEQ_TABLE |
++ DM_CM_SEQ_CTRL_SEQ_TYPE_SD |
++ DM_CM_SEQ_CTRL_T_NUM |
++ DM_CM_SEQ_CTRL_START_NUM(0) |
++ DM_CM_SEQ_CTRL_END_NUM(ctxt_num - 4) |
++ DM_CM_SEQ_CTRL_SEQ_START;
++ renesas_sdhi_internal_dmac_dm_write(host, DM_CM_SEQ_CTRL, val);
++ }
++
++ return;
++
++unmap_sg:
++ if (host->bounce_sg_mapped) {
++ dma_unmap_sg(&host->pdev->dev, &host->bounce_sg, 1,
++ DMA_FROM_DEVICE);
++ host->bounce_sg_mapped = false;
++ }
++force_pio:
++ host->force_pio = true;
++ renesas_sdhi_internal_dmac_enable_dma(host, false);
++
++ return; /* return for PIO */
++}
++
+ static bool renesas_sdhi_internal_dmac_dma_irq(struct tmio_mmc_host *host)
+ {
+ unsigned int ireg, status;
+
+ status = renesas_sdhi_internal_dmac_dm_read(host, DM_CM_INFO1);
++ if (host->seq_enabled && status & INFO1_SEQEND)
++ return true;
++
+ ireg = status & ~host->dma_irq_mask;
+
+ if (ireg & INFO1_DTRANEND0) {
+@@ -260,6 +718,76 @@ static bool renesas_sdhi_internal_dmac_dma_irq(struct tmio_mmc_host *host)
+ return false;
+ }
+
++static void renesas_sdhi_internal_dmac_seq_irq(struct tmio_mmc_host *host,
++ int status)
++{
++ struct mmc_data *data;
++ struct mmc_command *cmd, *sbc;
++ u64 dm_cm_info2;
++
++ spin_lock(&host->lock);
++ data = host->data;
++ cmd = host->mrq->cmd;
++ sbc = host->mrq->sbc;
++
++ dm_cm_info2 = renesas_sdhi_internal_dmac_dm_read(host, DM_CM_INFO2);
++ renesas_sdhi_internal_dmac_dm_write(host, DM_CM_INFO1, 0x0);
++ renesas_sdhi_internal_dmac_dm_write(host, DM_CM_INFO2, 0x0);
++
++ if (dm_cm_info2) {
++ pr_debug("sequencer error, CMD%d SD_INFO2=0x%x\n",
++ cmd->opcode, status >> 16);
++ if (status & TMIO_STAT_CMDTIMEOUT) {
++ cmd->error = -ETIMEDOUT;
++ if (sbc)
++ sbc->error = -ETIMEDOUT;
++ } else if ((status & TMIO_STAT_CRCFAIL &&
++ cmd->flags & MMC_RSP_CRC) ||
++ status & TMIO_STAT_STOPBIT_ERR ||
++ status & TMIO_STAT_CMD_IDX_ERR) {
++ cmd->error = -EILSEQ;
++ if (sbc)
++ sbc->error = -EILSEQ;
++ }
++
++ if (status & TMIO_STAT_DATATIMEOUT)
++ data->error = -ETIMEDOUT;
++ else if (status & TMIO_STAT_CRCFAIL ||
++ status & TMIO_STAT_STOPBIT_ERR ||
++ status & TMIO_STAT_TXUNDERRUN)
++ data->error = -EILSEQ;
++ }
++
++ if (host->chan_tx && (data->flags & MMC_DATA_WRITE)) {
++ u32 status = sd_ctrl_read16_and_16_as_32(host, CTL_STATUS);
++ bool done = false;
++
++ /*
++ * Has all data been written out yet? Testing on SuperH showed,
++ * that in most cases the first interrupt comes already with the
++ * BUSY status bit clear, but on some operations, like mount or
++ * in the beginning of a write / sync / umount, there is one
++ * DATAEND interrupt with the BUSY bit set, in this cases
++ * waiting for one more interrupt fixes the problem.
++ */
++ if (host->pdata->flags & TMIO_MMC_HAS_IDLE_WAIT) {
++ if (status & TMIO_STAT_SCLKDIVEN)
++ done = true;
++ } else {
++ if (!(status & TMIO_STAT_CMD_BUSY))
++ done = true;
++ }
++ if (!done)
++ goto out;
++ }
++ /* mask sequencer irq */
++ renesas_sdhi_internal_dmac_dm_write(host, DM_CM_INFO1_MASK, 0xffffffff);
++ tasklet_schedule(&host->seq_complete);
++
++out:
++ spin_unlock(&host->lock);
++}
++
+ static void
+ renesas_sdhi_internal_dmac_request_dma(struct tmio_mmc_host *host,
+ struct tmio_mmc_data *pdata)
+@@ -278,6 +806,19 @@ renesas_sdhi_internal_dmac_request_dma(struct tmio_mmc_host *host,
+ tasklet_init(&host->dma_issue,
+ renesas_sdhi_internal_dmac_issue_tasklet_fn,
+ (unsigned long)host);
++ tasklet_init(&host->seq_complete,
++ renesas_sdhi_internal_dmac_seq_complete_tasklet_fn,
++ (unsigned long)host);
++ /* alloc bounce_buf for dummy read */
++ host->bounce_buf = (u8 *)__get_free_page(GFP_KERNEL | GFP_DMA);
++ if (!host->bounce_buf) {
++ host->chan_rx = NULL;
++ host->chan_tx = NULL;
++ return;
++ }
++ /* setup bounce_sg for dummy read */
++ sg_init_one(&host->bounce_sg, host->bounce_buf, 1024);
++ host->bounce_sg_mapped = false;
+ }
+
+ static void
+@@ -285,6 +826,17 @@ renesas_sdhi_internal_dmac_release_dma(struct tmio_mmc_host *host)
+ {
+ /* Each value is set to zero to assume "disabling" each DMA */
+ host->chan_rx = host->chan_tx = NULL;
++
++ /* free bounce_buf for dummy read */
++ if (host->bounce_buf) {
++ if (host->bounce_sg_mapped) {
++ dma_unmap_sg(&host->pdev->dev, &host->bounce_sg, 1,
++ DMA_FROM_DEVICE);
++ host->bounce_sg_mapped = false;
++ }
++ free_pages((unsigned long)host->bounce_buf, 0);
++ host->bounce_buf = NULL;
++ }
+ }
+
+ static const struct tmio_mmc_dma_ops renesas_sdhi_internal_dmac_dma_ops = {
+@@ -295,6 +847,8 @@ static const struct tmio_mmc_dma_ops renesas_sdhi_internal_dmac_dma_ops = {
+ .abort = renesas_sdhi_internal_dmac_abort_dma,
+ .dataend = renesas_sdhi_internal_dmac_dataend_dma,
+ .dma_irq = renesas_sdhi_internal_dmac_dma_irq,
++ .seq_start = renesas_sdhi_internal_dmac_start_sequencer,
++ .seq_irq = renesas_sdhi_internal_dmac_seq_irq,
+ };
+
+ /*
+--
+2.7.4
+
diff --git a/bsp/meta-rcar/meta-rcar-gen3-adas/recipes-kernel/linux/linux-renesas/0112-ARM64-dts-renesas-ulcb-Make-AK4613-sound-device-name.patch b/bsp/meta-rcar/meta-rcar-gen3-adas/recipes-kernel/linux/linux-renesas/0112-ARM64-dts-renesas-ulcb-Make-AK4613-sound-device-name.patch
new file mode 100644
index 00000000..aa56e172
--- /dev/null
+++ b/bsp/meta-rcar/meta-rcar-gen3-adas/recipes-kernel/linux/linux-renesas/0112-ARM64-dts-renesas-ulcb-Make-AK4613-sound-device-name.patch
@@ -0,0 +1,34 @@
+From 3d10977e9e9811efe110d90b725f3132f80112ae Mon Sep 17 00:00:00 2001
+From: Valentine Barshak <valentine.barshak@cogentembedded.com>
+Date: Fri, 18 Jan 2019 23:24:15 +0300
+Subject: [PATCH 056/122] ARM64: dts: renesas: ulcb: Make AK4613 sound device
+ name consistent
+
+This makes AK4613 sound device name consistent throughout all
+ULCB boards. This helps to avoid naming issues when pulseaudio
+fails to start because the device has different names on
+infotainment and starter boards. For example, "ak4613"
+on Kingfisher vs "rsnd-sound" on Starter Kit.
+Pulseaudio is expecting "ak4613" name.
+
+Signed-off-by: Valentine Barshak <valentine.barshak@cogentembedded.com>
+---
+ arch/arm64/boot/dts/renesas/ulcb.dtsi | 2 +-
+ 1 file changed, 1 insertion(+), 1 deletion(-)
+
+diff --git a/arch/arm64/boot/dts/renesas/ulcb.dtsi b/arch/arm64/boot/dts/renesas/ulcb.dtsi
+index b60fd45..7e546d3 100644
+--- a/arch/arm64/boot/dts/renesas/ulcb.dtsi
++++ b/arch/arm64/boot/dts/renesas/ulcb.dtsi
+@@ -97,7 +97,7 @@
+ sound_card: sound {
+ compatible = "audio-graph-card";
+
+- label = "rcar-sound";
++ label = "ak4613";
+
+ dais = <&rsnd_port0>;
+ };
+--
+2.7.4
+
diff --git a/bsp/meta-rcar/meta-rcar-gen3-adas/recipes-kernel/linux/linux-renesas/0113-arm64-dts-ulcb-kf-increase-SDIO-frequency-for-WLAN-c.patch b/bsp/meta-rcar/meta-rcar-gen3-adas/recipes-kernel/linux/linux-renesas/0113-arm64-dts-ulcb-kf-increase-SDIO-frequency-for-WLAN-c.patch
new file mode 100644
index 00000000..b3b4a745
--- /dev/null
+++ b/bsp/meta-rcar/meta-rcar-gen3-adas/recipes-kernel/linux/linux-renesas/0113-arm64-dts-ulcb-kf-increase-SDIO-frequency-for-WLAN-c.patch
@@ -0,0 +1,32 @@
+From 1729cb28cb311bd326cb4495a51c86813270540e Mon Sep 17 00:00:00 2001
+From: Nikita Yushchenko <nikita.yoush@cogentembedded.com>
+Date: Tue, 2 Oct 2018 10:01:06 +0300
+Subject: [PATCH 057/122] arm64: dts: ulcb-kf: increase SDIO frequency for WLAN
+ chip
+
+WL1837MOD supports up to 50 MHz on SDIO interface, increase max-frequency
+value up to that.
+
+This increases WLAN throughput.
+
+Signed-off-by: Nikita Yushchenko <nikita.yoush@cogentembedded.com>
+---
+ arch/arm64/boot/dts/renesas/ulcb-kf.dtsi | 2 +-
+ 1 file changed, 1 insertion(+), 1 deletion(-)
+
+diff --git a/arch/arm64/boot/dts/renesas/ulcb-kf.dtsi b/arch/arm64/boot/dts/renesas/ulcb-kf.dtsi
+index 61b7851..ccc84cb 100644
+--- a/arch/arm64/boot/dts/renesas/ulcb-kf.dtsi
++++ b/arch/arm64/boot/dts/renesas/ulcb-kf.dtsi
+@@ -1228,7 +1228,7 @@
+ no-1-8-v;
+ non-removable;
+ cap-power-off-card;
+- max-frequency = <26000000>;
++ max-frequency = <50000000>;
+ status = "okay";
+
+ #address-cells = <1>;
+--
+2.7.4
+
diff --git a/bsp/meta-rcar/meta-rcar-gen3-adas/recipes-kernel/linux/linux-renesas/0114-Sony-IMX219-driver.patch b/bsp/meta-rcar/meta-rcar-gen3-adas/recipes-kernel/linux/linux-renesas/0114-Sony-IMX219-driver.patch
new file mode 100644
index 00000000..ee21c701
--- /dev/null
+++ b/bsp/meta-rcar/meta-rcar-gen3-adas/recipes-kernel/linux/linux-renesas/0114-Sony-IMX219-driver.patch
@@ -0,0 +1,1115 @@
+From 1a0e23a15528eb2715c13706fe6d74a32640cbb2 Mon Sep 17 00:00:00 2001
+From: Sergey Lapin <sergey.lapin@cogentembedded.com>
+Date: Wed, 26 Sep 2018 03:48:08 +0200
+Subject: [PATCH 058/122] Sony IMX219 driver
+
+Signed-off-by: Sergey Lapin <sergey.lapin@cogentembedded.com>
+---
+ .../devicetree/bindings/media/i2c/imx219.txt | 35 +
+ drivers/media/i2c/soc_camera/Kconfig | 6 +
+ drivers/media/i2c/soc_camera/Makefile | 1 +
+ drivers/media/i2c/soc_camera/imx219.c | 1026 ++++++++++++++++++++
+ 4 files changed, 1068 insertions(+)
+ create mode 100644 Documentation/devicetree/bindings/media/i2c/imx219.txt
+ create mode 100644 drivers/media/i2c/soc_camera/imx219.c
+
+diff --git a/Documentation/devicetree/bindings/media/i2c/imx219.txt b/Documentation/devicetree/bindings/media/i2c/imx219.txt
+new file mode 100644
+index 0000000..bc2ccf3
+--- /dev/null
++++ b/Documentation/devicetree/bindings/media/i2c/imx219.txt
+@@ -0,0 +1,35 @@
++Sony IMX219 raw image sensor
++----------------------------
++
++IMX219 is a raw image sensor with MIPI CSI-2 image data interface
++and CCI (I2C compatible) control bus.
++
++Required properties:
++
++- compatible : "sony,imx219".
++- reg : I2C slave address of the sensor.
++
++The common video interfaces bindings (see video-interfaces.txt) should be
++used to specify link to the image data receiver. The IMX219 device node
++should contain one 'port' child node with an 'endpoint' subnode.
++
++Endpoint node mandatory properties:
++
++- remote-endpoint: A phandle to the bus receiver's endpoint node.
++
++Example:
++
++ ...
++ imx219_cam: imx219@10 {
++ compatible = "sony,imx219";
++ reg = <0x10>;
++
++ port@0 {
++ rpi_camera_in: endpoint {
++ clock-lanes = <0>;
++ data-lanes = <1 2>;
++ remote-endpoint = <&vin4ep0>;
++ };
++ };
++ };
++ };
+diff --git a/drivers/media/i2c/soc_camera/Kconfig b/drivers/media/i2c/soc_camera/Kconfig
+index 1db3c6b..627d8d9 100644
+--- a/drivers/media/i2c/soc_camera/Kconfig
++++ b/drivers/media/i2c/soc_camera/Kconfig
+@@ -100,3 +100,9 @@ config SOC_CAMERA_OV106XX
+ depends on SOC_CAMERA && I2C
+ help
+ This is a runtime detected GMSL/FPDLink3 sensors driver
++
++config SOC_CAMERA_IMX219
++ tristate "imx219 camera support"
++ depends on SOC_CAMERA && I2C
++ help
++ This is Sony IMX219 driver
+diff --git a/drivers/media/i2c/soc_camera/Makefile b/drivers/media/i2c/soc_camera/Makefile
+index 0d4242e..eed6e24 100644
+--- a/drivers/media/i2c/soc_camera/Makefile
++++ b/drivers/media/i2c/soc_camera/Makefile
+@@ -14,4 +14,5 @@ obj-$(CONFIG_SOC_CAMERA_TW9910) += tw9910.o
+ obj-$(CONFIG_SOC_CAMERA_MAX9286) += max9286.o
+ obj-$(CONFIG_SOC_CAMERA_TI9X4) += ti9x4.o
+ obj-$(CONFIG_SOC_CAMERA_OV106XX) += ov106xx.o
++obj-$(CONFIG_SOC_CAMERA_IMX219) += imx219.o
+
+diff --git a/drivers/media/i2c/soc_camera/imx219.c b/drivers/media/i2c/soc_camera/imx219.c
+new file mode 100644
+index 0000000..f0ce3f7
+--- /dev/null
++++ b/drivers/media/i2c/soc_camera/imx219.c
+@@ -0,0 +1,1026 @@
++/*
++ * V4L2 driver for Sony IMX219 cameras.
++ *
++ * Based on Samsung S5K6AAFX SXGA 1/6" 1.3M CMOS Image Sensor driver
++ * Copyright (C) 2011 Sylwester Nawrocki <s.nawrocki@samsung.com>
++ *
++ * Based on Omnivision OV7670 Camera Driver
++ * Copyright (C) 2006-7 Jonathan Corbet <corbet@lwn.net>
++ *
++ * Based on Omnivision OV5647 image sensor driver
++ * Copyright (C) 2016, Synopsys, Inc.
++ *
++ * Copyright (C) 2017-2018 Cogent Embedded, Inc
++ */
++
++#include <linux/init.h>
++#include <linux/module.h>
++#include <linux/slab.h>
++#include <linux/i2c.h>
++#include <linux/delay.h>
++#include <linux/videodev2.h>
++#include <media/v4l2-device.h>
++#include <media/v4l2-ctrls.h>
++#include <media/v4l2-mediabus.h>
++#include <media/v4l2-image-sizes.h>
++#include <linux/io.h>
++
++#define IMX219_REG_CHIPID_H 0x0
++#define IMX219_REG_CHIPID_L 0x1
++
++#define REG_DLY 0xffff
++
++#define CSI_STBY_ON 1
++#define CSI_STBY_OFF 0
++
++/* #define TEST_PATTERN */
++
++struct regval_list {
++ u16 addr;
++ u8 data;
++};
++
++enum power_seq_cmd {
++ CSI_SUBDEV_PWR_OFF = 0x00,
++ CSI_SUBDEV_PWR_ON = 0x01,
++};
++
++struct sensor_format_struct {
++ __u8 *desc;
++ u32 mbus_code;
++ enum v4l2_colorspace colorspace;
++};
++
++struct cfg_array {
++ struct regval_list *regs;
++ int size;
++};
++
++struct sensor_win_size {
++ int width;
++ int height;
++ void *regs;
++ int regs_size;
++};
++
++struct imx219 {
++ struct device *dev;
++ struct v4l2_subdev subdev;
++ struct media_pad pad;
++ struct mutex lock;
++ struct v4l2_mbus_framefmt format;
++ struct sensor_format_struct *fmt;
++ unsigned int width;
++ unsigned int height;
++ unsigned int capture_mode;
++ struct v4l2_fract tpf;
++ struct sensor_win_size *current_wins;
++};
++
++static inline struct imx219 *to_state(struct v4l2_subdev *subdev)
++{
++ return container_of(subdev, struct imx219, subdev);
++}
++
++static struct sensor_format_struct sensor_formats[] = {
++ {
++ .mbus_code = MEDIA_BUS_FMT_SBGGR8_1X8,
++ .colorspace = V4L2_COLORSPACE_SRGB,
++ },
++};
++
++/*
++Used the following sources for register data:
++Copyright (C) 2014, Andrew Chew <achew@nvidia.com>
++https://chromium.googlesource.com/chromiumos/third_party/kernel/+/factory-ryu-6486.14.B-chromeos-3.14/drivers/media/i2c/soc_camera/imx219.c
++
++Copyright (C) 2013 Broadcom Corporation
++https://android.googlesource.com/kernel/bcm/+/android-bcm-tetra-3.10-lollipop-wear-release/drivers/media/video/imx219.c
++
++Chomoly (looks like Allwinner corporation made this one)
++https://github.com/allwinner-zh/linux-3.4-sunxi/blob/master/drivers/media/video/sunxi-vfe/device/imx219.c
++
++https://github.com/rellimmot/Sony-IMX219-Raspberry-Pi-V2-CMOS
++
++Copyright (c) 2017, Raspberry Pi Foundation
++Copyright (c) 2017, Dave Stevenson
++https//github.com/6by9/raspiraw
++
++Register data was manually tuned and tweaked for use with Renesas
++RCar CSI driver.
++*/
++
++/* unlock vendor registers */
++static struct regval_list sensor_unlock_regs[] = {
++ {0x30EB, 0x05},
++ {0x30EB, 0x0C},
++ {0x300A, 0xFF},
++ {0x300B, 0xFF},
++ {0x30EB, 0x05},
++ {0x30EB, 0x09},
++ {REG_DLY, 30},
++};
++
++/* CIS tuning */
++static struct regval_list cis_tuning_regs[] = {
++ /* magic */
++ {0x455E, 0x00},
++ {0x471E, 0x4B},
++ {0x4767, 0x0F},
++ {0x4750, 0x14},
++ {0x4540, 0x00},
++ {0x47B4, 0x14},
++ {0x4713, 0x30},
++ {0x478B, 0x10},
++ {0x478F, 0x10},
++ {0x4793, 0x10},
++ {0x4797, 0x0E},
++ {0x479B, 0x0E},
++};
++
++static struct regval_list sensor_hxga_regs[] = {
++ /* 0x114: 03 = 4 lanes, 01 = 2 lanes */
++ {0x0114, 0x01},
++ /* manual phy control */
++ {0x0128, 0x01},
++ /* EXCK_FREQ */
++ {0x012A, 0x18},
++ {0x012B, 0x00},
++ /* gain */
++ {0x0157, 0xe8},
++ {0x0158, 0x01},
++ {0x0159, 0x00},
++ /* integration time */
++ {0x015a, 0x02},
++ {0x015b, 0x31},
++ /* frame length */
++ {0x0160, 0x0f},
++ {0x0161, 0xe0},
++ /* line length */
++ {0x0162, 0x0f},
++ {0x0163, 0xE8},
++ /* x addr start */
++ {0x0164, 0x00},
++ {0x0165, 0x00},
++ /* x addr end */
++ {0x0166, 0x0C},
++ {0x0167, 0xCF},
++ /* y addr start */
++ {0x0168, 0x00},
++ {0x0169, 0x00},
++ /* y addr end */
++ {0x016A, 0x09},
++ {0x016B, 0x9F},
++ /* Output X size */
++ {0x016C, 0x0C},
++ {0x016D, 0xD0},
++ /* Output Y size */
++ {0x016E, 0x09},
++ {0x016F, 0xA0},
++ /* pixel increment */
++ {0x0170, 0x01},
++ {0x0171, 0x01},
++ {0x0174, 0x00},
++ {0x0175, 0x00},
++ /* pixell data format */
++ {0x018C, 0x08},
++ {0x018D, 0x08},
++ /* pix clk div, */
++ {0x0301, 0x05},
++ {0x0303, 0x01},
++ {0x0304, 0x03},
++ {0x0305, 0x03},
++ /* PLL1 */
++ {0x0306, 0x00},
++ {0x0307, 0x39},
++ {0x0309, 0x08},
++ {0x030B, 0x01},
++ /* PLL2 */
++ {0x030C, 0x00},
++ {0x030D, 0x72},
++};
++
++static struct regval_list sensor_1080p_regs[] = {
++ /* 0x114: 03 = 4 lanes, 01 = 2 lanes */
++ {0x0114, 0x01},
++ /* manual phy control */
++ {0x0128, 0x01},
++ /* EXCK_FREQ */
++ {0x012A, 0x18},
++ {0x012B, 0x00},
++ /* gain */
++ {0x0157, 0xe8},
++ {0x0158, 0x01},
++ {0x0159, 0x00},
++ /* coarse integration time */
++ {0x015a, 0x05},
++ {0x015b, 0x3f},
++ {0x0160, 0x0A},
++ {0x0161, 0x2F},
++ {0x0162, 0x0D},
++ {0x0163, 0x78},
++ {0x0164, 0x02},
++ {0x0165, 0xA8},
++ {0x0166, 0x0A},
++ {0x0167, 0x27},
++ {0x0168, 0x02},
++ {0x0169, 0xB4},
++ {0x016A, 0x06},
++ {0x016B, 0xEB},
++ {0x016C, 0x07},
++ {0x016D, 0x80},
++ {0x016E, 0x04},
++ {0x016F, 0x38},
++ {0x0170, 0x01},
++ {0x0171, 0x01},
++ {0x0174, 0x00},
++ {0x0175, 0x00},
++ /* pixell data format */
++ {0x018C, 0x08},
++ {0x018D, 0x08},
++ /* pix clk div, */
++ {0x0301, 0x05},
++ {0x0303, 0x01},
++ {0x0304, 0x03},
++ {0x0305, 0x03},
++ /* PLL1 */
++ {0x0306, 0x00},
++ {0x0307, 0x39},
++ {0x0309, 0x08},
++ {0x030B, 0x01},
++ /* PLL2 */
++ {0x030C, 0x00},
++ {0x030D, 0x72},
++};
++
++static struct regval_list sensor_720p_regs[] = {
++ /* 0x114: 03 = 4 lanes, 01 = 2 lanes */
++ {0x0114, 0x01},
++ {0x0128, 0x01},
++ /* EXCK_FREQ */
++ {0x012A, 0x18},
++ {0x012B, 0x00},
++ /* gain */
++ {0x0157, 0xc8},
++ {0x0158, 0x01},
++ {0x0159, 0x00},
++ /* coarse integration time */
++ {0x015a, 0x01},
++ {0x015b, 0x7f},
++ {0x0160, 0x02},
++ {0x0161, 0x39},
++ {0x0162, 0x0d},
++ {0x0163, 0xe7},
++ {0x0164, 0x01},
++ {0x0165, 0x68},
++ {0x0166, 0x0b},
++ {0x0167, 0x67},
++ {0x0168, 0x02},
++ {0x0169, 0x00},
++ {0x016A, 0x07},
++ {0x016B, 0x9f},
++ {0x016C, 0x05},
++ {0x016D, 0x00},
++ {0x016E, 0x02},
++ {0x016F, 0xd0},
++ {0x0170, 0x01},
++ {0x0171, 0x01},
++ {0x0172, 0x03},
++ {0x0174, 0x03},
++ {0x0175, 0x03},
++ /* pixell data format */
++ {0x018C, 0x08},
++ {0x018D, 0x08},
++ /* pix clk div, */
++ {0x0301, 0x05},
++ {0x0303, 0x01},
++ {0x0304, 0x03},
++ {0x0305, 0x03},
++ /* PLL1 */
++ {0x0306, 0x00},
++ {0x0307, 0x39},
++ /* div2 */
++ {0x0309, 0x08},
++ {0x030B, 0x01},
++ /* PLL2 */
++ {0x030C, 0x00},
++ {0x030D, 0x72},
++};
++
++static struct regval_list sensor_480p_regs[] = {
++ /* 0x114: 03 = 4 lanes, 01 = 2 lanes */
++ {0x0114, 0x01},
++ {0x0128, 0x01},
++ /* EXCK_FREQ */
++ {0x012A, 0x18},
++ {0x012B, 0x00},
++ /* gain */
++ {0x0157, 0xe8},
++ {0x0158, 0x01},
++ {0x0159, 0x00},
++ /* coarse integration time */
++ {0x015a, 0x01},
++ {0x015b, 0x2f},
++ {0x0160, 0x02},
++ {0x0161, 0x39},
++ {0x0162, 0x0d},
++ {0x0163, 0xe7},
++ /* x start */
++ {0x0164, 0x03},
++ {0x0165, 0xe8},
++ /* x end */
++ {0x0166, 0x08},
++ {0x0167, 0xe7},
++ /* y start */
++ {0x0168, 0x02},
++ {0x0169, 0xf0},
++ /* y end */
++ {0x016A, 0x06},
++ {0x016B, 0xaf},
++ {0x016C, 0x02},
++ {0x016D, 0x80},
++ {0x016E, 0x01},
++ {0x016F, 0xe0},
++ {0x0170, 0x01},
++ {0x0171, 0x01},
++ {0x0172, 0x03},
++ {0x0174, 0x03},
++ {0x0175, 0x03},
++ /* pixell data format */
++ {0x018C, 0x08},
++ {0x018D, 0x08},
++ /* pix clk div, */
++ {0x0301, 0x05},
++ {0x0303, 0x01},
++ {0x0304, 0x03},
++ {0x0305, 0x03},
++ /* PLL1 */
++ {0x0306, 0x00},
++ {0x0307, 0x39},
++ /* div2 */
++ {0x0309, 0x08},
++ {0x030B, 0x01},
++ /* PLL2 */
++ {0x030C, 0x00},
++ {0x030D, 0x72},
++};
++
++static struct regval_list sensor_240p_regs[] = {
++ /* 0x114: 03 = 4 lanes, 01 = 2 lanes */
++ {0x0114, 0x01},
++ {0x0128, 0x01},
++ /* EXCK_FREQ */
++ {0x012A, 0x18},
++ {0x012B, 0x00},
++ /* gain */
++ {0x0157, 0xd4},
++ {0x0158, 0x01},
++ {0x0159, 0x00},
++ /* coarse integration time */
++ {0x015a, 0x01},
++ {0x015b, 0x30},
++ /* frame time size */
++ {0x0160, 0x02},
++ {0x0161, 0x39},
++ /* line time size */
++ {0x0162, 0x0d},
++ {0x0163, 0xE7},
++ /* x start */
++ {0x0164, 0x03},
++ {0x0165, 0xe8},
++ /* x end */
++ {0x0166, 0x06},
++ {0x0167, 0x67},
++ /* y start */
++ {0x0168, 0x03},
++ {0x0169, 0xde},
++ /* y end */
++ {0x016A, 0x05},
++ {0x016B, 0xbe},
++ /* x width */
++ {0x016C, 0x01},
++ {0x016D, 0x40},
++ /* x height */
++ {0x016E, 0x00},
++ {0x016F, 0xf0},
++ {0x0170, 0x01},
++ {0x0171, 0x01},
++ {0x0172, 0x03},
++ {0x0174, 0x03},
++ {0x0175, 0x03},
++ /* pixell data format */
++ {0x018C, 0x08},
++ {0x018D, 0x08},
++ /* pix clk div, */
++ {0x0301, 0x05},
++ {0x0303, 0x01},
++ {0x0304, 0x03},
++ {0x0305, 0x03},
++ /* PLL1 */
++ {0x0306, 0x00},
++ {0x0307, 0x39},
++ /* div2 */
++ {0x0309, 0x08},
++ {0x030B, 0x01},
++ /* PLL2 */
++ {0x030C, 0x00},
++ {0x030D, 0x72},
++};
++
++#define IMX219_DEFAULT_WIDTH 3296
++#define IMX219_DEFAULT_HEIGHT 2464
++
++static struct sensor_win_size sensor_win_sizes[] = {
++ {
++ /* 3296x2464 */
++ .width = 3296,
++ .height = 2464,
++ .regs = sensor_hxga_regs,
++ .regs_size = ARRAY_SIZE(sensor_hxga_regs),
++ },
++ /* 1920x1080 */
++ {
++ .width = 1920,
++ .height = 1080,
++ .regs = sensor_1080p_regs,
++ .regs_size = ARRAY_SIZE(sensor_1080p_regs),
++ },
++ /* 1280x720 */
++ {
++ .width = 1280,
++ .height = 720,
++ .regs = sensor_720p_regs,
++ .regs_size = ARRAY_SIZE(sensor_720p_regs),
++ },
++ /* 640x480 */
++ {
++ .width = 640,
++ .height = 480,
++ .regs = sensor_480p_regs,
++ .regs_size = ARRAY_SIZE(sensor_480p_regs),
++ },
++ /* 320x240 */
++ {
++ .width = 320,
++ .height = 240,
++ .regs = sensor_240p_regs,
++ .regs_size = ARRAY_SIZE(sensor_240p_regs),
++ },
++};
++
++#define N_FMTS ARRAY_SIZE(sensor_formats)
++#define N_WIN_SIZES ARRAY_SIZE(sensor_win_sizes)
++
++static int imx219_write(struct v4l2_subdev *sd, uint16_t reg, uint8_t val)
++{
++ int ret;
++ unsigned char data[3] = {reg >> 8, reg & 0xff, val};
++ struct i2c_client *client = v4l2_get_subdevdata(sd);
++
++ ret = i2c_master_send(client, data, 3);
++ if (ret < 3) {
++ v4l2_err(sd, "%s: i2c write error, reg: %x, %d\n",
++ __func__, reg, ret);
++ return ret < 0 ? ret : -EIO;
++ }
++ return 0;
++}
++
++static int imx219_read(struct v4l2_subdev *sd, uint16_t reg, uint8_t *val)
++{
++ int ret;
++ unsigned char data_w[2] = { reg >> 8, reg & 0xff };
++ struct i2c_client *client = v4l2_get_subdevdata(sd);
++
++ ret = i2c_master_send(client, data_w, 2);
++
++ if (ret < 2) {
++ v4l2_err(sd, "%s: i2c read error, reg: %x\n",
++ __func__, reg);
++ return ret < 0 ? ret : -EIO;
++ }
++
++ ret = i2c_master_recv(client, val, 1);
++
++ if (ret < 1) {
++ v4l2_err(sd, "%s: i2c read error, reg: %x\n",
++ __func__, reg);
++ return ret < 0 ? ret : -EIO;
++ }
++
++ return 0;
++}
++
++static int imx219_write_array(struct v4l2_subdev *subdev,
++ struct regval_list *regs, int array_size)
++{
++ int i = 0;
++ int ret = 0;
++
++ if (!regs)
++ return -EINVAL;
++
++ while (i < array_size) {
++ if (regs->addr == REG_DLY)
++ mdelay(regs->data);
++ else
++ ret = imx219_write(subdev, regs->addr, regs->data);
++
++ if (ret == -EIO) {
++ v4l2_err(subdev, "register write error at %d, %04x\n",
++ i, regs->addr);
++ return ret;
++ }
++
++ i++;
++ regs++;
++ }
++ return 0;
++}
++
++static int sensor_s_sw_stby(struct v4l2_subdev *subdev, int on_off)
++{
++ int ret;
++ unsigned char rdval;
++
++ ret = imx219_read(subdev, 0x0100, &rdval);
++ if (ret != 0)
++ return ret;
++
++ if (on_off == CSI_STBY_ON)
++ ret = imx219_write(subdev, 0x0100, rdval & 0xfe);
++ else
++ ret = imx219_write(subdev, 0x0100, rdval | 0x01);
++
++ msleep(30);
++ return ret;
++}
++
++static int sensor_power(struct v4l2_subdev *subdev, int on)
++{
++ int ret = 0;
++ struct imx219 *imx219 = to_state(subdev);
++
++ mutex_lock(&imx219->lock);
++
++ switch (on) {
++ case CSI_SUBDEV_PWR_OFF:
++ ret = sensor_s_sw_stby(subdev, CSI_STBY_ON);
++ if (ret < 0)
++ v4l2_err(subdev, "soft stby failed!\n");
++ break;
++ case CSI_SUBDEV_PWR_ON:
++ ret = sensor_s_sw_stby(subdev, CSI_STBY_OFF);
++ if (ret) {
++ /* soft reset */
++ imx219_write(subdev, 0x103, 1);
++ msleep(120);
++ ret = sensor_s_sw_stby(subdev, CSI_STBY_OFF);
++ }
++ if (ret < 0) {
++ v4l2_err(subdev,
++ "Camera not available, check power\n");
++ break;
++ }
++ break;
++ default:
++ return -EINVAL;
++ }
++
++ mutex_unlock(&imx219->lock);
++
++ return 0;
++}
++
++#ifdef CONFIG_VIDEO_ADV_DEBUG
++static int sensor_get_register(struct v4l2_subdev *subdev,
++ struct v4l2_dbg_register *reg)
++{
++ u8 val = 0;
++ int ret;
++
++ ret = imx219_read(subdev, (u16)reg->reg, &val);
++ if (ret < 0)
++ return ret;
++
++ reg->val = val;
++ reg->size = sizeof(u8);
++
++ return ret;
++}
++
++static int sensor_set_register(struct v4l2_subdev *subdev,
++ const struct v4l2_dbg_register *reg)
++{
++ imx219_write(subdev, (u16)reg->reg, (u8)reg->val);
++
++ return 0;
++}
++#endif
++
++static const struct v4l2_subdev_core_ops sensor_core_ops = {
++ .s_power = sensor_power,
++#ifdef CONFIG_VIDEO_ADV_DEBUG
++ .g_register = sensor_get_register,
++ .s_register = sensor_set_register,
++#endif
++};
++
++#ifdef DUMP_REGS
++static void sensor_dump_regs(struct v4l2_subdev *subdev)
++{
++ u8 val;
++
++ imx219_read(subdev, 0x18, &val);
++ pr_info("FRM_CNT %02x\n", val);
++ imx219_read(subdev, 0x19, &val);
++ pr_info("PX_ORDER %02x\n", val);
++ imx219_read(subdev, 0x1a, &val);
++ pr_info("DT_PEDESTAL1 %02x\n", val);
++ imx219_read(subdev, 0x1b, &val);
++ pr_info("DT_PEDESTAL0 %02x\n", val);
++ imx219_read(subdev, 0x104, &val);
++ pr_info("corrupted frame status %02x\n", val);
++ imx219_read(subdev, 0x111, &val);
++ pr_info("CSI_SIG_MODE %02x\n", val);
++ imx219_read(subdev, 0x114, &val);
++ pr_info("CSI_LANE_MODE %02x\n", val);
++ imx219_read(subdev, 0x140, &val);
++ pr_info("TEMPERATURE_VAL %02x\n", val);
++ imx219_read(subdev, 0x142, &val);
++ pr_info("READOUT_V_CNT1 %02x\n", val);
++ imx219_read(subdev, 0x143, &val);
++ pr_info("READOUT_V_CNT0 %02x\n", val);
++ imx219_read(subdev, 0x150, &val);
++ pr_info("FRAME_BANK_STATUS %02x\n", val);
++ imx219_read(subdev, 0x151, &val);
++ pr_info("FRAME_BANK_FRM_COUNT %02x\n", val);
++}
++#else
++#define sensor_dump_regs(x)
++#endif
++static int sensor_enum_fmt(struct v4l2_subdev *sd,
++ struct v4l2_subdev_pad_config *cfg,
++ struct v4l2_subdev_mbus_code_enum *code)
++{
++ if (code->pad || code->index >= N_FMTS)
++ return -EINVAL;
++
++ code->code = sensor_formats[code->index].mbus_code;
++ return 0;
++}
++
++static int sensor_try_fmt_internal(struct v4l2_subdev *subdev,
++ struct v4l2_mbus_framefmt *fmt,
++ struct sensor_format_struct **ret_fmt,
++ struct sensor_win_size **ret_wsize)
++{
++ int index;
++ struct sensor_win_size *wsize;
++ struct imx219 *imx219 = to_state(subdev);
++
++ for (index = 0; index < N_FMTS; index++)
++ if (sensor_formats[index].mbus_code == fmt->code)
++ break;
++
++ if (index >= N_FMTS)
++ return -EINVAL;
++
++ if (ret_fmt)
++ *ret_fmt = sensor_formats + index;
++
++ fmt->field = V4L2_FIELD_NONE;
++ for (wsize = sensor_win_sizes;
++ wsize < sensor_win_sizes + N_WIN_SIZES;
++ wsize++)
++ if (fmt->width >= wsize->width && fmt->height >= wsize->height)
++ break;
++ if (wsize >= sensor_win_sizes + N_WIN_SIZES)
++ wsize--;
++ if (ret_wsize)
++ *ret_wsize = wsize;
++ fmt->width = wsize->width;
++ fmt->height = wsize->height;
++ imx219->current_wins = wsize;
++
++ return 0;
++}
++
++static int sensor_s_fmt(struct v4l2_subdev *subdev,
++ struct v4l2_subdev_pad_config *cfg,
++ struct v4l2_subdev_format *fmt)
++{
++ int ret;
++ struct sensor_format_struct *sensor_fmt;
++ struct sensor_win_size *wsize = NULL;
++ struct imx219 *info = to_state(subdev);
++
++ ret = sensor_try_fmt_internal(subdev, &fmt->format,
++ &sensor_fmt, &wsize);
++ if (ret)
++ return ret;
++
++ info->fmt = sensor_fmt;
++ if (wsize->regs) {
++ /* putting sensor to sleep */
++ imx219_write(subdev, 0x100, 0);
++ msleep(30);
++ ret = imx219_write_array(subdev, sensor_unlock_regs,
++ ARRAY_SIZE(sensor_hxga_regs));
++ if (ret < 0)
++ return ret;
++ ret = imx219_write_array(subdev,
++ wsize->regs,
++ wsize->regs_size);
++ if (ret)
++ return ret;
++ ret = imx219_write_array(subdev, cis_tuning_regs,
++ ARRAY_SIZE(cis_tuning_regs));
++ if (ret)
++ return ret;
++#ifdef TEST_PATTERN
++ ret = imx219_write(subdev, 0x0600, 0x00);
++ ret |= imx219_write(subdev, 0x0601, 0x02);
++ ret |= imx219_write(subdev, 0x0620, 0x00);
++ ret |= imx219_write(subdev, 0x0621, 0x00);
++ ret |= imx219_write(subdev, 0x0622, 0x00);
++ ret |= imx219_write(subdev, 0x0623, 0x00);
++ ret |= imx219_write(subdev, 0x0624,
++ (wsize->width >> 8) & 0xff);
++ ret |= imx219_write(subdev, 0x0625,
++ wsize->width & 0xff);
++ ret |= imx219_write(subdev, 0x0626,
++ (wsize->height >> 8) & 0xff);
++ ret |= imx219_write(subdev, 0x0627,
++ wsize->height & 0xff);
++ if (ret) {
++ v4l2_err(subdev, "%s: i2c write error\n",
++ __func__);
++ return -EIO;
++ }
++#endif
++ /* putting sensor out of sleep */
++ imx219_write(subdev, 0x100, 1);
++ msleep(30);
++ sensor_dump_regs(sd);
++ }
++
++ return 0;
++}
++
++static int sensor_g_fmt(struct v4l2_subdev *sd,
++ struct v4l2_subdev_pad_config *cfg,
++ struct v4l2_subdev_format *format)
++{
++ struct imx219 *info = to_state(sd);
++ struct v4l2_mbus_framefmt *mf = &format->format;
++
++ if (format->pad != 0)
++ return -EINVAL;
++
++ mf->width = info->current_wins->width;
++ mf->height = info->current_wins->height;
++ mf->code = info->fmt->mbus_code;
++ mf->colorspace = info->fmt->colorspace;
++ mf->field = V4L2_FIELD_NONE;
++
++ return 0;
++}
++
++static int sensor_s_parm(struct v4l2_subdev *subdev,
++ struct v4l2_streamparm *parms)
++{
++ struct v4l2_captureparm *cp = &parms->parm.capture;
++ struct imx219 *info = to_state(subdev);
++
++ if (parms->type != V4L2_BUF_TYPE_VIDEO_CAPTURE)
++ return -EINVAL;
++
++ if (info->tpf.numerator == 0)
++ return -EINVAL;
++
++ info->capture_mode = cp->capturemode;
++
++ return 0;
++}
++
++static int sensor_g_parm(struct v4l2_subdev *subdev,
++ struct v4l2_streamparm *parms)
++{
++ struct v4l2_captureparm *cp = &parms->parm.capture;
++ struct imx219 *info = to_state(subdev);
++
++ if (parms->type != V4L2_BUF_TYPE_VIDEO_CAPTURE)
++ return -EINVAL;
++
++ memset(cp, 0, sizeof(struct v4l2_captureparm));
++ cp->capability = V4L2_CAP_TIMEPERFRAME;
++ cp->capturemode = info->capture_mode;
++
++ return 0;
++}
++
++static int sensor_g_mbus_config(struct v4l2_subdev *sd,
++ struct v4l2_mbus_config *cfg)
++{
++ cfg->flags = V4L2_MBUS_CSI2_2_LANE;
++ cfg->flags |= V4L2_MBUS_CSI2_CHANNEL_0;
++ cfg->flags |= V4L2_MBUS_CSI2_CONTINUOUS_CLOCK;
++ cfg->flags |= V4L2_MBUS_MASTER;
++ cfg->type = V4L2_MBUS_CSI2;
++
++ return 0;
++}
++
++static const struct v4l2_subdev_pad_ops sensor_pad_ops = {
++ .enum_mbus_code = sensor_enum_fmt,
++ .set_fmt = sensor_s_fmt,
++ .get_fmt = sensor_g_fmt,
++};
++
++static const struct v4l2_subdev_video_ops sensor_video_ops = {
++ .s_parm = sensor_s_parm,
++ .g_parm = sensor_g_parm,
++ .g_mbus_config = sensor_g_mbus_config,
++};
++
++static const struct v4l2_subdev_ops subdev_ops = {
++ .core = &sensor_core_ops,
++ .video = &sensor_video_ops,
++ .pad = &sensor_pad_ops,
++};
++
++static int imx219_detect(struct v4l2_subdev *sd)
++{
++ struct i2c_client *client = v4l2_get_subdevdata(sd);
++ unsigned char id_h, id_l;
++ int ret;
++
++ ret = sensor_power(sd, 1);
++ if (ret < 0)
++ return ret;
++ msleep(30);
++
++ ret = imx219_read(sd, IMX219_REG_CHIPID_H, &id_h);
++ if (ret < 0)
++ return ret;
++ ret = imx219_read(sd, IMX219_REG_CHIPID_L, &id_l);
++ if (ret < 0)
++ return ret;
++
++ if (id_h != 0x02 || id_l != 0x19) {
++ v4l2_info(sd, "Invalid device ID: %02x%02x\n", id_h, id_l);
++ return -ENODEV;
++ }
++
++ v4l2_info(sd, "IMX219 detected at address 0x%02x\n", client->addr);
++
++ ret = sensor_power(sd, 0);
++ if (ret < 0)
++ return ret;
++
++ return 0;
++}
++
++static int imx219_open(struct v4l2_subdev *subdev, struct v4l2_subdev_fh *fh)
++{
++ struct v4l2_mbus_framefmt *format =
++ v4l2_subdev_get_try_format(subdev, fh->pad, 0);
++ struct v4l2_rect *crop =
++ v4l2_subdev_get_try_crop(subdev, fh->pad, 0);
++
++ crop->left = 0;
++ crop->top = 0;
++ crop->width = IMX219_DEFAULT_WIDTH;
++ crop->height = IMX219_DEFAULT_HEIGHT;
++
++ format->code = MEDIA_BUS_FMT_SBGGR8_1X8;
++
++ format->width = IMX219_DEFAULT_WIDTH;
++ format->height = IMX219_DEFAULT_HEIGHT;
++ format->field = V4L2_FIELD_NONE;
++ format->colorspace = sensor_formats[0].colorspace;
++
++ return sensor_power(subdev, 1);
++}
++
++static int imx219_close(struct v4l2_subdev *subdev, struct v4l2_subdev_fh *fh)
++{
++ return sensor_power(subdev, 0);
++}
++
++static const struct v4l2_subdev_internal_ops imx219_subdev_internal_ops = {
++ .open = imx219_open,
++ .close = imx219_close,
++};
++
++static int imx219_probe(struct i2c_client *client,
++ const struct i2c_device_id *id)
++{
++ struct device *dev = &client->dev;
++ struct imx219 *sensor;
++ int ret = 0, i;
++ struct v4l2_subdev *sd;
++
++ sensor = devm_kzalloc(dev, sizeof(*sensor), GFP_KERNEL);
++ if (!sensor)
++ return -ENOMEM;
++
++ mutex_init(&sensor->lock);
++ sensor->dev = dev;
++ sensor->fmt = &sensor_formats[0];
++ sensor->width = sensor_win_sizes[0].width;
++ sensor->height = sensor_win_sizes[0].height;
++ sensor->current_wins = &sensor_win_sizes[0];
++
++ sd = &sensor->subdev;
++ v4l2_i2c_subdev_init(sd, client, &subdev_ops);
++ sensor->subdev.flags |= V4L2_SUBDEV_FL_HAS_DEVNODE;
++
++ ret = imx219_detect(sd);
++ if (ret < 0) {
++ v4l2_err(sd, "IMX219 not found!\n");
++ goto out;
++ }
++ /* soft reset sequence */
++ for (i = 0; i < 3; i++) {
++ imx219_write(sd, 0x103, 1);
++ mdelay(30);
++ }
++ msleep(60);
++
++ /* putting sensor to sleep */
++ imx219_write(sd, 0x100, 0);
++ msleep(30);
++ ret = imx219_write_array(sd, sensor_unlock_regs,
++ ARRAY_SIZE(sensor_hxga_regs));
++ if (ret < 0)
++ return ret;
++ ret = imx219_write_array(sd, sensor_win_sizes[0].regs,
++ sensor_win_sizes[0].regs_size);
++ if (ret < 0)
++ return ret;
++ ret = imx219_write_array(sd, cis_tuning_regs,
++ ARRAY_SIZE(cis_tuning_regs));
++ if (ret < 0)
++ return ret;
++ /* getting sensor out of sleep */
++ imx219_write(sd, 0x100, 1);
++ msleep(30);
++ sensor->pad.flags = MEDIA_PAD_FL_SOURCE;
++ sd->entity.function = MEDIA_ENT_F_CAM_SENSOR;
++ ret = media_entity_pads_init(&sd->entity, 1, &sensor->pad);
++ if (ret < 0)
++ return ret;
++
++ ret = v4l2_async_register_subdev(sd);
++ if (ret < 0)
++ media_entity_cleanup(&sd->entity);
++
++ /* putting sensor back to sleep to save power */
++ imx219_write(sd, 0x100, 0);
++out:
++ return ret;
++}
++
++static int imx219_remove(struct i2c_client *client)
++{
++ struct v4l2_subdev *subdev = i2c_get_clientdata(client);
++ struct imx219 *imx219 = to_state(subdev);
++
++ v4l2_async_unregister_subdev(&imx219->subdev);
++ media_entity_cleanup(&imx219->subdev.entity);
++ v4l2_device_unregister_subdev(subdev);
++
++ return 0;
++}
++
++static const struct i2c_device_id imx219_id[] = {
++ { "imx219", 0 },
++ { }
++};
++MODULE_DEVICE_TABLE(i2c, imx219_id);
++
++#if IS_ENABLED(CONFIG_OF)
++static const struct of_device_id imx219_of_match[] = {
++ { .compatible = "sony,imx219" },
++ { /* sentinel */ },
++};
++MODULE_DEVICE_TABLE(of, imx219_of_match);
++#endif
++
++static struct i2c_driver imx219_driver = {
++ .driver = {
++ .of_match_table = of_match_ptr(imx219_of_match),
++ .owner = THIS_MODULE,
++ .name = "imx219",
++ },
++ .probe = imx219_probe,
++ .remove = imx219_remove,
++ .id_table = imx219_id,
++};
++module_i2c_driver(imx219_driver);
++
++MODULE_AUTHOR("Sergey Lapin <sergey.lapin@cogentembedded.com>");
++MODULE_DESCRIPTION("A low-level driver for Sony imx219 sensors");
++MODULE_LICENSE("GPL");
+--
+2.7.4
+
diff --git a/bsp/meta-rcar/meta-rcar-gen3-adas/recipes-kernel/linux/linux-renesas/0115-arm64-dts-renesas-ulcb-kf-enable-enable-IMX219.patch b/bsp/meta-rcar/meta-rcar-gen3-adas/recipes-kernel/linux/linux-renesas/0115-arm64-dts-renesas-ulcb-kf-enable-enable-IMX219.patch
new file mode 100644
index 00000000..18ae14e0
--- /dev/null
+++ b/bsp/meta-rcar/meta-rcar-gen3-adas/recipes-kernel/linux/linux-renesas/0115-arm64-dts-renesas-ulcb-kf-enable-enable-IMX219.patch
@@ -0,0 +1,95 @@
+From f24ff97f1aad1bd121ef691d1b3294613e1646ea Mon Sep 17 00:00:00 2001
+From: Vladimir Barinov <vladimir.barinov@cogentembedded.com>
+Date: Wed, 3 Oct 2018 14:06:33 +0300
+Subject: [PATCH 059/122] arm64: dts: renesas: ulcb-kf: enable enable IMX219
+
+This enables IMX219 instead OV5647
+
+Signed-off-by: Sergey Lapin <slapinid@gmail.com>
+Signed-off-by: Vladimir Barinov <vladimir.barinov@cogentembedded.com>
+---
+ arch/arm64/boot/dts/renesas/ulcb-kf-imx219.dtsi | 58 +++++++++++++++++++++++++
+ arch/arm64/boot/dts/renesas/ulcb-kf.dtsi | 5 +++
+ 2 files changed, 63 insertions(+)
+ create mode 100644 arch/arm64/boot/dts/renesas/ulcb-kf-imx219.dtsi
+
+diff --git a/arch/arm64/boot/dts/renesas/ulcb-kf-imx219.dtsi b/arch/arm64/boot/dts/renesas/ulcb-kf-imx219.dtsi
+new file mode 100644
+index 0000000..1779a2b
+--- /dev/null
++++ b/arch/arm64/boot/dts/renesas/ulcb-kf-imx219.dtsi
+@@ -0,0 +1,58 @@
++/*
++ * Device Tree Source for the Kingfisher (ULCB extension) board:
++ * this overrides OV5647 RPI cameras with IMX219
++ *
++ * Copyright (C) 2018 Renesas Electronics Corp.
++ * Copyright (C) 2018 Cogent Embedded, Inc.
++ *
++ * This file is licensed under the terms of the GNU General Public License
++ * version 2. This program is licensed "as is" without any warranty of any
++ * kind, whether express or implied.
++ */
++
++/delete-node/ &rpi_camera_in;
++/delete-node/ &rpi_camera;
++
++&csi20_ep {
++ csi-rate = <860>;
++};
++
++&gpio_exp_76 {
++ /* pin 11 - CAM_GPIO - assume pwdn */
++ rpi_cam_io_0 {
++ gpio-hog;
++ gpios = <11 GPIO_ACTIVE_HIGH>;
++ output-high;
++ line-name = "RaspB_IO0";
++ };
++
++ /* pin 12 - CAM_CLK */
++ /* pin12 is output from camera to CPU, so it should be input */
++ rpi_cam_io_1 {
++ gpio-hog;
++ gpios = <10 GPIO_ACTIVE_HIGH>;
++ input;
++ line-name = "RaspB_IO1";
++ };
++};
++
++&i2cswitch4 {
++ i2c@4 {
++ #address-cells = <1>;
++ #size-cells = <0>;
++ reg = <4>;
++
++ rpi_camera: imx219@10 {
++ compatible = "sony,imx219";
++ reg = <0x10>;
++
++ port@0 {
++ rpi_camera_in: endpoint {
++ clock-lanes = <0>;
++ data-lanes = <1 2>;
++ remote-endpoint = <&vin4ep0>;
++ };
++ };
++ };
++ };
++};
+diff --git a/arch/arm64/boot/dts/renesas/ulcb-kf.dtsi b/arch/arm64/boot/dts/renesas/ulcb-kf.dtsi
+index ccc84cb..731300e 100644
+--- a/arch/arm64/boot/dts/renesas/ulcb-kf.dtsi
++++ b/arch/arm64/boot/dts/renesas/ulcb-kf.dtsi
+@@ -1443,3 +1443,8 @@
+
+
+
++/* enable IMX219 camera */
++#include "ulcb-kf-imx219.dtsi"
++
++
++
+--
+2.7.4
+
diff --git a/bsp/meta-rcar/meta-rcar-gen3-adas/recipes-kernel/linux/linux-renesas/0116-media-i2c-soc_camera-Fix-Bad-of_node_put-error.patch b/bsp/meta-rcar/meta-rcar-gen3-adas/recipes-kernel/linux/linux-renesas/0116-media-i2c-soc_camera-Fix-Bad-of_node_put-error.patch
new file mode 100644
index 00000000..6730d60c
--- /dev/null
+++ b/bsp/meta-rcar/meta-rcar-gen3-adas/recipes-kernel/linux/linux-renesas/0116-media-i2c-soc_camera-Fix-Bad-of_node_put-error.patch
@@ -0,0 +1,250 @@
+From e23740bbebec60b8f8076491745f0e30dfb80cf3 Mon Sep 17 00:00:00 2001
+From: Valentine Barshak <valentine.barshak@cogentembedded.com>
+Date: Mon, 13 Aug 2018 15:13:52 +0300
+Subject: [PATCH 060/122] media: i2c: soc_camera: Fix Bad of_node_put error
+
+This fixes "OF: ERROR: Bad of_node_put()" error and possible kernel
+crash when probing soc_camera sensor devices. When CONFIG_OF_DYNAMIC
+is not enabled, bad of_node_put error is not displayed and everything
+seems to work fine. However, there's an error in sensors' parse_dt
+callbacks which causes inconsistent node reference counter management.
+
+Move of_node_put() out of a loop scope to prevent bad of_node_put error.
+We don't need to call of_node_put() for every node since subsequent
+calls to of_graph_get_next_endpoint() decrement reference counter of
+the previous node. We only need to call of_node_put() for the last node.
+
+Signed-off-by: Valentine Barshak <valentine.barshak@cogentembedded.com>
+---
+ drivers/media/i2c/soc_camera/ap0101_ar014x.c | 4 ++--
+ drivers/media/i2c/soc_camera/ar0132.c | 4 ++--
+ drivers/media/i2c/soc_camera/ar0220.c | 3 ++-
+ drivers/media/i2c/soc_camera/max9286.c | 8 ++++----
+ drivers/media/i2c/soc_camera/ov10635.c | 4 ++--
+ drivers/media/i2c/soc_camera/ov2775.c | 4 ++--
+ drivers/media/i2c/soc_camera/ov490_ov10640.c | 4 ++--
+ drivers/media/i2c/soc_camera/ov495_ov2775.c | 4 ++--
+ drivers/media/i2c/soc_camera/ti9x4.c | 4 ++--
+ 9 files changed, 20 insertions(+), 19 deletions(-)
+
+diff --git a/drivers/media/i2c/soc_camera/ap0101_ar014x.c b/drivers/media/i2c/soc_camera/ap0101_ar014x.c
+index cae0b19..d8025a4 100644
+--- a/drivers/media/i2c/soc_camera/ap0101_ar014x.c
++++ b/drivers/media/i2c/soc_camera/ap0101_ar014x.c
+@@ -420,8 +420,6 @@ static int ap0101_parse_dt(struct device_node *np, struct ap0101_priv *priv)
+ if (!endpoint)
+ break;
+
+- of_node_put(endpoint);
+-
+ rendpoint = of_parse_phandle(endpoint, "remote-endpoint", 0);
+ if (!rendpoint)
+ continue;
+@@ -432,6 +430,8 @@ static int ap0101_parse_dt(struct device_node *np, struct ap0101_priv *priv)
+ break;
+ }
+
++ of_node_put(endpoint);
++
+ if (!priv->max9286_addr) {
+ dev_err(&client->dev, "deserializer does not present for AP0101\n");
+ return -EINVAL;
+diff --git a/drivers/media/i2c/soc_camera/ar0132.c b/drivers/media/i2c/soc_camera/ar0132.c
+index a7ee868..2865902 100644
+--- a/drivers/media/i2c/soc_camera/ar0132.c
++++ b/drivers/media/i2c/soc_camera/ar0132.c
+@@ -379,8 +379,6 @@ static int ar0132_parse_dt(struct device_node *np, struct ar0132_priv *priv)
+ if (!endpoint)
+ break;
+
+- of_node_put(endpoint);
+-
+ of_property_read_u32(endpoint, "dvp-order", &priv->dvp_order);
+
+ rendpoint = of_parse_phandle(endpoint, "remote-endpoint", 0);
+@@ -399,6 +397,8 @@ static int ar0132_parse_dt(struct device_node *np, struct ar0132_priv *priv)
+ break;
+ }
+
++ of_node_put(endpoint);
++
+ if (!priv->max9286_addr && !priv->ti9x4_addr) {
+ dev_err(&client->dev, "deserializer does not present for AR0132\n");
+ return -EINVAL;
+diff --git a/drivers/media/i2c/soc_camera/ar0220.c b/drivers/media/i2c/soc_camera/ar0220.c
+index e00fe4a..8813522 100644
+--- a/drivers/media/i2c/soc_camera/ar0220.c
++++ b/drivers/media/i2c/soc_camera/ar0220.c
+@@ -358,7 +358,6 @@ static int ar0220_parse_dt(struct device_node *np, struct ar0220_priv *priv)
+ if (!endpoint)
+ break;
+
+- of_node_put(endpoint);
+
+ rendpoint = of_parse_phandle(endpoint, "remote-endpoint", 0);
+ if (!rendpoint)
+@@ -371,6 +370,8 @@ static int ar0220_parse_dt(struct device_node *np, struct ar0220_priv *priv)
+ break;
+ }
+
++ of_node_put(endpoint);
++
+ if (!priv->ti9x4_addr) {
+ dev_err(&client->dev, "deserializer does not present\n");
+ return -EINVAL;
+diff --git a/drivers/media/i2c/soc_camera/max9286.c b/drivers/media/i2c/soc_camera/max9286.c
+index 6a5d0889..d01acdc 100644
+--- a/drivers/media/i2c/soc_camera/max9286.c
++++ b/drivers/media/i2c/soc_camera/max9286.c
+@@ -560,9 +560,8 @@ static int max9286_parse_dt(struct i2c_client *client)
+ if (!endpoint)
+ break;
+
+- of_node_put(endpoint);
+-
+ if (of_property_read_u32(endpoint, "max9271-addr", &priv->max9271_addr_map[i])) {
++ of_node_put(endpoint);
+ dev_err(&client->dev, "max9271-addr not set\n");
+ return -EINVAL;
+ }
+@@ -570,6 +569,7 @@ static int max9286_parse_dt(struct i2c_client *client)
+ priv->sd_fwnode[i] = of_fwnode_handle(endpoint);
+ }
+
++ of_node_put(endpoint);
+ return 0;
+ }
+
+@@ -586,8 +586,6 @@ static void max9286_setup_remote_endpoint(struct i2c_client *client)
+ if (!endpoint)
+ break;
+
+- of_node_put(endpoint);
+-
+ rendpoint = of_parse_phandle(endpoint, "remote-endpoint", 0);
+ if (!rendpoint)
+ continue;
+@@ -604,6 +602,8 @@ static void max9286_setup_remote_endpoint(struct i2c_client *client)
+ if (dvp_order_prop)
+ of_update_property(rendpoint, dvp_order_prop);
+ }
++
++ of_node_put(endpoint);
+ }
+
+ static int max9286_probe(struct i2c_client *client,
+diff --git a/drivers/media/i2c/soc_camera/ov10635.c b/drivers/media/i2c/soc_camera/ov10635.c
+index eacf015..8289b76 100644
+--- a/drivers/media/i2c/soc_camera/ov10635.c
++++ b/drivers/media/i2c/soc_camera/ov10635.c
+@@ -555,8 +555,6 @@ static int ov10635_parse_dt(struct device_node *np, struct ov10635_priv *priv)
+ if (!endpoint)
+ break;
+
+- of_node_put(endpoint);
+-
+ of_property_read_u32(endpoint, "dvp-order", &priv->dvp_order);
+
+ rendpoint = of_parse_phandle(endpoint, "remote-endpoint", 0);
+@@ -581,6 +579,8 @@ static int ov10635_parse_dt(struct device_node *np, struct ov10635_priv *priv)
+ break;
+ }
+
++ of_node_put(endpoint);
++
+ if (!priv->max9286_addr && !priv->ti964_addr && !priv->ti954_addr) {
+ dev_err(&client->dev, "deserializer does not present for OV10635\n");
+ return -EINVAL;
+diff --git a/drivers/media/i2c/soc_camera/ov2775.c b/drivers/media/i2c/soc_camera/ov2775.c
+index feb547f..cb41764 100644
+--- a/drivers/media/i2c/soc_camera/ov2775.c
++++ b/drivers/media/i2c/soc_camera/ov2775.c
+@@ -355,8 +355,6 @@ static int ov2775_parse_dt(struct device_node *np, struct ov2775_priv *priv)
+ if (!endpoint)
+ break;
+
+- of_node_put(endpoint);
+-
+ rendpoint = of_parse_phandle(endpoint, "remote-endpoint", 0);
+ if (!rendpoint)
+ continue;
+@@ -368,6 +366,8 @@ static int ov2775_parse_dt(struct device_node *np, struct ov2775_priv *priv)
+ break;
+ }
+
++ of_node_put(endpoint);
++
+ if (!priv->ti9x4_addr) {
+ dev_err(&client->dev, "deserializer does not present\n");
+ return -EINVAL;
+diff --git a/drivers/media/i2c/soc_camera/ov490_ov10640.c b/drivers/media/i2c/soc_camera/ov490_ov10640.c
+index e698f59..4b51a92 100644
+--- a/drivers/media/i2c/soc_camera/ov490_ov10640.c
++++ b/drivers/media/i2c/soc_camera/ov490_ov10640.c
+@@ -904,8 +904,6 @@ static int ov490_parse_dt(struct device_node *np, struct ov490_priv *priv)
+ if (!endpoint)
+ break;
+
+- of_node_put(endpoint);
+-
+ of_property_read_u32(endpoint, "dvp-order", &priv->dvp_order);
+
+ rendpoint = of_parse_phandle(endpoint, "remote-endpoint", 0);
+@@ -933,6 +931,8 @@ static int ov490_parse_dt(struct device_node *np, struct ov490_priv *priv)
+ break;
+ }
+
++ of_node_put(endpoint);
++
+ if (!priv->max9286_addr && !priv->ti9x4_addr) {
+ dev_err(&client->dev, "deserializer does not present for OV490\n");
+ return -EINVAL;
+diff --git a/drivers/media/i2c/soc_camera/ov495_ov2775.c b/drivers/media/i2c/soc_camera/ov495_ov2775.c
+index bb5991c..32b5078 100644
+--- a/drivers/media/i2c/soc_camera/ov495_ov2775.c
++++ b/drivers/media/i2c/soc_camera/ov495_ov2775.c
+@@ -464,8 +464,6 @@ static int ov495_parse_dt(struct device_node *np, struct ov495_priv *priv)
+ if (!endpoint)
+ break;
+
+- of_node_put(endpoint);
+-
+ rendpoint = of_parse_phandle(endpoint, "remote-endpoint", 0);
+ if (!rendpoint)
+ continue;
+@@ -477,6 +475,8 @@ static int ov495_parse_dt(struct device_node *np, struct ov495_priv *priv)
+ break;
+ }
+
++ of_node_put(endpoint);
++
+ if (!priv->ti9x4_addr) {
+ dev_err(&client->dev, "deserializer does not present for OV495\n");
+ return -EINVAL;
+diff --git a/drivers/media/i2c/soc_camera/ti9x4.c b/drivers/media/i2c/soc_camera/ti9x4.c
+index 2ce98b4..7704bfa 100644
+--- a/drivers/media/i2c/soc_camera/ti9x4.c
++++ b/drivers/media/i2c/soc_camera/ti9x4.c
+@@ -406,10 +406,9 @@ static int ti9x4_parse_dt(struct i2c_client *client)
+ if (!endpoint)
+ break;
+
+- of_node_put(endpoint);
+-
+ if (i < priv->links) {
+ if (of_property_read_u32(endpoint, "ti9x3-addr", &priv->ti9x3_addr_map[i])) {
++ of_node_put(endpoint);
+ dev_err(&client->dev, "ti9x3-addr not set\n");
+ return -EINVAL;
+ }
+@@ -431,6 +430,7 @@ static int ti9x4_parse_dt(struct i2c_client *client)
+ of_update_property(rendpoint, dvp_order_prop);
+ }
+
++ of_node_put(endpoint);
+ return 0;
+ }
+
+--
+2.7.4
+
diff --git a/bsp/meta-rcar/meta-rcar-gen3-adas/recipes-kernel/linux/linux-renesas/0117-rcar-vin-fix-get_selection-use.patch b/bsp/meta-rcar/meta-rcar-gen3-adas/recipes-kernel/linux/linux-renesas/0117-rcar-vin-fix-get_selection-use.patch
new file mode 100644
index 00000000..5a063c59
--- /dev/null
+++ b/bsp/meta-rcar/meta-rcar-gen3-adas/recipes-kernel/linux/linux-renesas/0117-rcar-vin-fix-get_selection-use.patch
@@ -0,0 +1,48 @@
+From e0a3dbada217b98610a00f6878bdf111c41b5475 Mon Sep 17 00:00:00 2001
+From: Vladimir Barinov <vladimir.barinov@cogentembedded.com>
+Date: Wed, 12 Sep 2018 22:06:53 +0300
+Subject: [PATCH 061/122] rcar-vin: fix get_selection use
+
+Get crop bounds from glue driver (imager)
+
+Signed-off-by: Vladimir Barinov <vladimir.barinov@cogentembedded.com>
+---
+ drivers/media/platform/soc_camera/rcar_vin.c | 20 ++++++++++++++++++--
+ 1 file changed, 18 insertions(+), 2 deletions(-)
+
+diff --git a/drivers/media/platform/soc_camera/rcar_vin.c b/drivers/media/platform/soc_camera/rcar_vin.c
+index 228bbf3..50d393b 100644
+--- a/drivers/media/platform/soc_camera/rcar_vin.c
++++ b/drivers/media/platform/soc_camera/rcar_vin.c
+@@ -2334,10 +2334,26 @@ static int rcar_vin_get_selection(struct soc_camera_device *icd,
+ struct v4l2_selection *sel)
+ {
+ struct rcar_vin_cam *cam = icd->host_priv;
++ struct v4l2_subdev *sd = soc_camera_to_subdev(icd);
++ struct v4l2_subdev_selection sdsel;
++ int ret;
+
+- sel->r = cam->subrect;
++ switch (sel->target) {
++ case V4L2_SEL_TGT_CROP_BOUNDS:
++ sdsel.which = V4L2_SUBDEV_FORMAT_ACTIVE;
++ sdsel.target = sel->target;
+
+- return 0;
++ ret = v4l2_subdev_call(sd, pad, get_selection, NULL, &sdsel);
++ if (!ret)
++ sel->r = sdsel.r;
++ return ret;
++ case V4L2_SEL_TGT_CROP_DEFAULT:
++ case V4L2_SEL_TGT_CROP:
++ sel->r = cam->subrect;
++ return 0;
++ default:
++ return -EINVAL;
++ }
+ }
+
+ /* Similar to set_crop multistage iterative algorithm */
+--
+2.7.4
+
diff --git a/bsp/meta-rcar/meta-rcar-gen3-adas/recipes-kernel/linux/linux-renesas/0118-clk-clk-gpio-Allow-GPIO-to-sleep-in-set-get_parent.patch b/bsp/meta-rcar/meta-rcar-gen3-adas/recipes-kernel/linux/linux-renesas/0118-clk-clk-gpio-Allow-GPIO-to-sleep-in-set-get_parent.patch
new file mode 100644
index 00000000..2aece053
--- /dev/null
+++ b/bsp/meta-rcar/meta-rcar-gen3-adas/recipes-kernel/linux/linux-renesas/0118-clk-clk-gpio-Allow-GPIO-to-sleep-in-set-get_parent.patch
@@ -0,0 +1,43 @@
+From 3ed86f45efc154e3a8e5ebd60beea30929b1c30c Mon Sep 17 00:00:00 2001
+From: Mike Looijmans <mike.looijmans@topic.nl>
+Date: Tue, 13 Mar 2018 09:54:03 +0100
+Subject: [PATCH 062/122] clk: clk-gpio: Allow GPIO to sleep in set/get_parent
+
+When changing or retrieving clock parents, the caller is in a sleepable
+state (like prepare) so the GPIO operation need not be atomic. Replace
+gpiod_{g|s}et_value with gpiod_{g|s}et_value_cansleep in the {g|s}et_parent
+calls for the GPIO based clock mux.
+
+This fixes a "slowpath" warning when the GPIO controller is an I2C expander
+or something similar.
+
+Signed-off-by: Mike Looijmans <mike.looijmans@topic.nl>
+Signed-off-by: Andrey Gusakov <andrey.gusakov@cogentembedded.com>
+---
+ drivers/clk/clk-gpio.c | 4 ++--
+ 1 file changed, 2 insertions(+), 2 deletions(-)
+
+diff --git a/drivers/clk/clk-gpio.c b/drivers/clk/clk-gpio.c
+index 86b2457..3441e9c 100644
+--- a/drivers/clk/clk-gpio.c
++++ b/drivers/clk/clk-gpio.c
+@@ -75,14 +75,14 @@ static u8 clk_gpio_mux_get_parent(struct clk_hw *hw)
+ {
+ struct clk_gpio *clk = to_clk_gpio(hw);
+
+- return gpiod_get_value(clk->gpiod);
++ return gpiod_get_value_cansleep(clk->gpiod);
+ }
+
+ static int clk_gpio_mux_set_parent(struct clk_hw *hw, u8 index)
+ {
+ struct clk_gpio *clk = to_clk_gpio(hw);
+
+- gpiod_set_value(clk->gpiod, index);
++ gpiod_set_value_cansleep(clk->gpiod, index);
+
+ return 0;
+ }
+--
+2.7.4
+
diff --git a/bsp/meta-rcar/meta-rcar-gen3-adas/recipes-kernel/linux/linux-renesas/0119-i2c-mix-pca954x-reset-mux-in-case-of-error-during-bu.patch b/bsp/meta-rcar/meta-rcar-gen3-adas/recipes-kernel/linux/linux-renesas/0119-i2c-mix-pca954x-reset-mux-in-case-of-error-during-bu.patch
new file mode 100644
index 00000000..1c817728
--- /dev/null
+++ b/bsp/meta-rcar/meta-rcar-gen3-adas/recipes-kernel/linux/linux-renesas/0119-i2c-mix-pca954x-reset-mux-in-case-of-error-during-bu.patch
@@ -0,0 +1,102 @@
+From d166aec2c769ae0ebc6bf54366d794469cec5122 Mon Sep 17 00:00:00 2001
+From: Andrey Gusakov <andrey.gusakov@cogentembedded.com>
+Date: Wed, 13 Jun 2018 14:06:59 +0300
+Subject: [PATCH 063/122] i2c: mix: pca954x: reset mux in case of error during
+ bus (de)select
+
+Signed-off-by: Andrey Gusakov <andrey.gusakov@cogentembedded.com>
+---
+ drivers/i2c/muxes/i2c-mux-pca954x.c | 36 ++++++++++++++++++++++++++++++------
+ 1 file changed, 30 insertions(+), 6 deletions(-)
+
+diff --git a/drivers/i2c/muxes/i2c-mux-pca954x.c b/drivers/i2c/muxes/i2c-mux-pca954x.c
+index 7b992db..0c8c965 100644
+--- a/drivers/i2c/muxes/i2c-mux-pca954x.c
++++ b/drivers/i2c/muxes/i2c-mux-pca954x.c
+@@ -35,6 +35,7 @@
+ * warranty of any kind, whether express or implied.
+ */
+
++#include <linux/delay.h>
+ #include <linux/device.h>
+ #include <linux/gpio/consumer.h>
+ #include <linux/i2c.h>
+@@ -78,6 +79,7 @@ struct chip_desc {
+ struct pca954x {
+ const struct chip_desc *chip;
+
++ struct gpio_desc *gpio; /* reset gpio */
+ u8 last_chan; /* last register value */
+ u8 deselect;
+ struct i2c_client *client;
+@@ -207,6 +209,15 @@ static int pca954x_select_chan(struct i2c_mux_core *muxc, u32 chan)
+ /* Only select the channel if its different from the last channel */
+ if (data->last_chan != regval) {
+ ret = pca954x_reg_write(muxc->parent, client, regval);
++ if (ret < 0) {
++ dev_err(&data->client->dev, "error selecting channed %d (was 0x%02x), reseting mux\n",
++ chan, data->last_chan);
++ gpiod_set_value(data->gpio, 1);
++ usleep_range(1, 10);
++ gpiod_set_value(data->gpio, 0);
++ /* retry */
++ ret = pca954x_reg_write(muxc->parent, client, regval);
++ }
+ data->last_chan = ret < 0 ? 0 : regval;
+ }
+
+@@ -217,13 +228,23 @@ static int pca954x_deselect_mux(struct i2c_mux_core *muxc, u32 chan)
+ {
+ struct pca954x *data = i2c_mux_priv(muxc);
+ struct i2c_client *client = data->client;
++ int ret;
+
+ if (!(data->deselect & (1 << chan)))
+ return 0;
+
+ /* Deselect active channel */
+ data->last_chan = 0;
+- return pca954x_reg_write(muxc->parent, client, data->last_chan);
++ ret = pca954x_reg_write(muxc->parent, client, data->last_chan);
++ if (ret < 0) {
++ dev_err(&data->client->dev, "error deselecting channed %d, reseting mux\n", chan);
++ gpiod_set_value(data->gpio, 1);
++ usleep_range(1, 10);
++ gpiod_set_value(data->gpio, 0);
++ /* retry */
++ ret = pca954x_reg_write(muxc->parent, client, data->last_chan);
++ }
++ return ret;
+ }
+
+ static irqreturn_t pca954x_irq_handler(int irq, void *dev_id)
+@@ -344,7 +365,6 @@ static int pca954x_probe(struct i2c_client *client,
+ struct pca954x_platform_data *pdata = dev_get_platdata(&client->dev);
+ struct device_node *of_node = client->dev.of_node;
+ bool idle_disconnect_dt;
+- struct gpio_desc *gpio;
+ int num, force, class;
+ struct i2c_mux_core *muxc;
+ struct pca954x *data;
+@@ -364,10 +384,14 @@ static int pca954x_probe(struct i2c_client *client,
+ i2c_set_clientdata(client, muxc);
+ data->client = client;
+
+- /* Get the mux out of reset if a reset GPIO is specified. */
+- gpio = devm_gpiod_get_optional(&client->dev, "reset", GPIOD_OUT_LOW);
+- if (IS_ERR(gpio))
+- return PTR_ERR(gpio);
++ /* Perform reset if a reset GPIO is specified. */
++ data->gpio = devm_gpiod_get_optional(&client->dev, "reset", GPIOD_OUT_HIGH);
++ if (IS_ERR(data->gpio)) {
++ return PTR_ERR(data->gpio);
++ } else {
++ usleep_range(1, 10);
++ gpiod_set_value(data->gpio, 0);
++ }
+
+ /* Write the mux register at addr to verify
+ * that the mux is in fact present. This also
+--
+2.7.4
+
diff --git a/bsp/meta-rcar/meta-rcar-gen3-adas/recipes-kernel/linux/linux-renesas/0120-arm64-dts-ulcb-kf-pcm3168a-reset-earlier-i2c-mux-dis.patch b/bsp/meta-rcar/meta-rcar-gen3-adas/recipes-kernel/linux/linux-renesas/0120-arm64-dts-ulcb-kf-pcm3168a-reset-earlier-i2c-mux-dis.patch
new file mode 100644
index 00000000..6aef8956
--- /dev/null
+++ b/bsp/meta-rcar/meta-rcar-gen3-adas/recipes-kernel/linux/linux-renesas/0120-arm64-dts-ulcb-kf-pcm3168a-reset-earlier-i2c-mux-dis.patch
@@ -0,0 +1,82 @@
+From ea5e8199be27ecd2271485294084513fa72d78ae Mon Sep 17 00:00:00 2001
+From: Andrey Gusakov <andrey.gusakov@cogentembedded.com>
+Date: Fri, 9 Nov 2018 17:40:06 +0300
+Subject: [PATCH 064/122] arm64: dts: ulcb-kf: pcm3168a reset earlier, i2c-mux
+ disconnect on idle
+
+Signed-off-by: Andrey Gusakov <andrey.gusakov@cogentembedded.com>
+---
+ arch/arm64/boot/dts/renesas/ulcb-kf.dtsi | 26 ++++++++++++++------------
+ 1 file changed, 14 insertions(+), 12 deletions(-)
+
+diff --git a/arch/arm64/boot/dts/renesas/ulcb-kf.dtsi b/arch/arm64/boot/dts/renesas/ulcb-kf.dtsi
+index 731300e..d4e17a2 100644
+--- a/arch/arm64/boot/dts/renesas/ulcb-kf.dtsi
++++ b/arch/arm64/boot/dts/renesas/ulcb-kf.dtsi
+@@ -13,11 +13,11 @@
+ serial3 = &hscif1;
+ };
+
+- snd_clk: snd_clk {
+- compatible = "fixed-clock";
++ pcm3168a_clk: pcm3168a_clk {
++ compatible = "gpio-mux-clock";
++ clocks = <&cs2000>, <&audio_clk_a>;
+ #clock-cells = <0>;
+- clock-frequency = <24576000>;
+- clock-output-names = "scki";
++ select-gpios = <&gpio_exp_75 13 GPIO_ACTIVE_HIGH>;
+ };
+
+ wlan_en: regulator@4 {
+@@ -52,15 +52,10 @@
+
+ codec_en_reg: regulator@6 {
+ compatible = "regulator-fixed";
+- regulator-name = "codec-en-regulator";
++
++ regulator-name = "PCM3168A Vcc Vdd";
+ regulator-min-microvolt = <3300000>;
+ regulator-max-microvolt = <3300000>;
+-
+- gpio = <&gpio_exp_74 15 0>;
+-
+- /* delay - CHECK */
+- startup-delay-us = <70000>;
+- enable-active-high;
+ };
+
+ amp_en_reg: regulator@7 {
+@@ -395,6 +390,12 @@
+ output-high;
+ line-name = "OTG EXTLPn";
+ };
++ snd_rst {
++ gpio-hog;
++ gpios = <15 GPIO_ACTIVE_HIGH>;
++ output-high;
++ line-name = "pcm3168a reset";
++ };
+ };
+
+ gpio_exp_75: gpio@75 {
+@@ -426,6 +427,7 @@
+ #size-cells = <0>;
+ reg = <0x71>;
+ reset-gpios = <&gpio5 3 GPIO_ACTIVE_LOW>;
++ i2c-mux-idle-disconnect;
+
+ i2c@0 {
+ #address-cells = <1>;
+@@ -530,7 +532,7 @@
+ #sound-dai-cells = <0>;
+ compatible = "ti,pcm3168a";
+ reg = <0x44>;
+- clocks = <&snd_clk>;
++ clocks = <&pcm3168a_clk>;
+ clock-names = "scki";
+ tdm;
+ VDD1-supply = <&codec_en_reg>;
+--
+2.7.4
+
diff --git a/bsp/meta-rcar/meta-rcar-gen3-adas/recipes-kernel/linux/linux-renesas/0121-arm64-dts-renesas-ulcb-kf-Set-KOE-TX31D200VM0BAA-128.patch b/bsp/meta-rcar/meta-rcar-gen3-adas/recipes-kernel/linux/linux-renesas/0121-arm64-dts-renesas-ulcb-kf-Set-KOE-TX31D200VM0BAA-128.patch
new file mode 100644
index 00000000..390ca584
--- /dev/null
+++ b/bsp/meta-rcar/meta-rcar-gen3-adas/recipes-kernel/linux/linux-renesas/0121-arm64-dts-renesas-ulcb-kf-Set-KOE-TX31D200VM0BAA-128.patch
@@ -0,0 +1,64 @@
+From 2a9c52ee2c53be87c62c841d5c4485cec4f35a60 Mon Sep 17 00:00:00 2001
+From: Valentine Barshak <valentine.barshak@cogentembedded.com>
+Date: Mon, 17 Dec 2018 17:48:17 +0300
+Subject: [PATCH 065/122] arm64: dts: renesas: ulcb-kf: Set KOE TX31D200VM0BAA
+ 1280x480 panel
+
+This sets LVDS LCD parameters for KOE TX31D200VM0BAA 1280x480 panel.
+
+Signed-off-by: Valentine Barshak <valentine.barshak@cogentembedded.com>
+---
+ arch/arm64/boot/dts/renesas/ulcb-kf-panel.dtsi | 27 ++++++++++++++++----------
+ 1 file changed, 17 insertions(+), 10 deletions(-)
+
+diff --git a/arch/arm64/boot/dts/renesas/ulcb-kf-panel.dtsi b/arch/arm64/boot/dts/renesas/ulcb-kf-panel.dtsi
+index b54c935..5b8748c 100644
+--- a/arch/arm64/boot/dts/renesas/ulcb-kf-panel.dtsi
++++ b/arch/arm64/boot/dts/renesas/ulcb-kf-panel.dtsi
+@@ -12,26 +12,33 @@
+ &lvds {
+ compatible = "panel-lvds";
+
+- width-mm = <210>;
+- height-mm = <158>;
++ width-mm = <291>;
++ height-mm = <109>;
+
+ data-mapping = "jeida-24";
+
+ panel-timing {
+- /* 1280x800 @60Hz Boundary Devices BD101LCC1 compatible panel */
+- clock-frequency = <65000000>;
++ /* 1280x480 @60Hz KOE TX31D200VM0BAA compatible panel */
++ clock-frequency = <43200000>;
+ hactive = <1280>;
+- vactive = <800>;
+- hsync-len = <40>;
+- hfront-porch = <80>;
++ vactive = <480>;
++ hsync-len = <20>;
++ hfront-porch = <20>;
+ hback-porch = <40>;
+- vfront-porch = <14>;
+- vback-porch = <14>;
+- vsync-len = <4>;
++ vsync-len = <15>;
++ vfront-porch = <15>;
++ vback-porch = <20>;
+ };
+ };
+
+ &gpio2 {
++ sd {
++ gpio-hog;
++ gpios = <2 GPIO_ACTIVE_HIGH>;
++ output-low;
++ line-name = "Scan Direction Normal";
++ };
++
+ bl_pwm {
+ gpio-hog;
+ gpios = <3 GPIO_ACTIVE_HIGH>;
+--
+2.7.4
+
diff --git a/bsp/meta-rcar/meta-rcar-gen3-adas/recipes-kernel/linux/linux-renesas/0121-arm64-dts-renesas-ulcb-kf-Set-Mitsubishi-AA104XD12-1.patch b/bsp/meta-rcar/meta-rcar-gen3-adas/recipes-kernel/linux/linux-renesas/0121-arm64-dts-renesas-ulcb-kf-Set-Mitsubishi-AA104XD12-1.patch
new file mode 100644
index 00000000..46a92a17
--- /dev/null
+++ b/bsp/meta-rcar/meta-rcar-gen3-adas/recipes-kernel/linux/linux-renesas/0121-arm64-dts-renesas-ulcb-kf-Set-Mitsubishi-AA104XD12-1.patch
@@ -0,0 +1,64 @@
+From a345757975a1cbb6910d97b98976cc54f102888e Mon Sep 17 00:00:00 2001
+From: Valentine Barshak <valentine.barshak@cogentembedded.com>
+Date: Mon, 17 Dec 2018 17:56:40 +0300
+Subject: [PATCH 067/122] arm64: dts: renesas: ulcb-kf: Set Mitsubishi
+ AA104XD12 1024x768 panel
+
+This sets LVDS LCD parameters for Mitsubishi AA104XD12 1024x768 panel.
+
+Signed-off-by: Valentine Barshak <valentine.barshak@cogentembedded.com>
+---
+ arch/arm64/boot/dts/renesas/ulcb-kf-panel.dtsi | 31 ++++++++++++++++----------
+ 1 file changed, 19 insertions(+), 12 deletions(-)
+
+diff --git a/arch/arm64/boot/dts/renesas/ulcb-kf-panel.dtsi b/arch/arm64/boot/dts/renesas/ulcb-kf-panel.dtsi
+index b54c935..73c2378 100644
+--- a/arch/arm64/boot/dts/renesas/ulcb-kf-panel.dtsi
++++ b/arch/arm64/boot/dts/renesas/ulcb-kf-panel.dtsi
+@@ -18,24 +18,31 @@
+ data-mapping = "jeida-24";
+
+ panel-timing {
+- /* 1280x800 @60Hz Boundary Devices BD101LCC1 compatible panel */
++ /* 1024x768 @60Hz Mitsubishi AA104XD12 compatible panel */
+ clock-frequency = <65000000>;
+- hactive = <1280>;
+- vactive = <800>;
+- hsync-len = <40>;
+- hfront-porch = <80>;
+- hback-porch = <40>;
+- vfront-porch = <14>;
+- vback-porch = <14>;
+- vsync-len = <4>;
++ hactive = <1024>;
++ vactive = <768>;
++ hsync-len = <136>;
++ hfront-porch = <20>;
++ hback-porch = <160>;
++ vfront-porch = <3>;
++ vback-porch = <29>;
++ vsync-len = <6>;
+ };
+ };
+
+ &gpio2 {
+- bl_pwm {
++ mode {
++ gpio-hog;
++ gpios = <2 GPIO_ACTIVE_HIGH>;
++ output-low;
++ line-name = "LVDS ISP 6-Bit Compatibility Mode";
++ };
++
++ sd {
+ gpio-hog;
+ gpios = <3 GPIO_ACTIVE_HIGH>;
+- output-high;
+- line-name = "BL PWM 100%";
++ output-low;
++ line-name = "LVDS Scan Direction Normal";
+ };
+ };
+--
+2.7.4
+
diff --git a/bsp/meta-rcar/meta-rcar-gen3-adas/recipes-kernel/linux/linux-renesas/0121-arm64-dts-renesas-ulcb-kf-Set-Mitsubishi-AA121TD01-1.patch b/bsp/meta-rcar/meta-rcar-gen3-adas/recipes-kernel/linux/linux-renesas/0121-arm64-dts-renesas-ulcb-kf-Set-Mitsubishi-AA121TD01-1.patch
new file mode 100644
index 00000000..26521b58
--- /dev/null
+++ b/bsp/meta-rcar/meta-rcar-gen3-adas/recipes-kernel/linux/linux-renesas/0121-arm64-dts-renesas-ulcb-kf-Set-Mitsubishi-AA121TD01-1.patch
@@ -0,0 +1,71 @@
+From 10517a5740e7b6f24fd5a45d8f9635ed13e94ddd Mon Sep 17 00:00:00 2001
+From: Valentine Barshak <valentine.barshak@cogentembedded.com>
+Date: Mon, 17 Dec 2018 17:56:40 +0300
+Subject: [PATCH 069/122] arm64: dts: renesas: ulcb-kf: Set Mitsubishi
+ AA121TD01 1280x800 panel
+
+This sets LVDS LCD parameters for Mitsubishi AA121TD01 1280x800 panel.
+
+Signed-off-by: Valentine Barshak <valentine.barshak@cogentembedded.com>
+---
+ arch/arm64/boot/dts/renesas/ulcb-kf-panel.dtsi | 33 ++++++++++++++++----------
+ 1 file changed, 20 insertions(+), 13 deletions(-)
+
+diff --git a/arch/arm64/boot/dts/renesas/ulcb-kf-panel.dtsi b/arch/arm64/boot/dts/renesas/ulcb-kf-panel.dtsi
+index b54c935..2fe2b6c 100644
+--- a/arch/arm64/boot/dts/renesas/ulcb-kf-panel.dtsi
++++ b/arch/arm64/boot/dts/renesas/ulcb-kf-panel.dtsi
+@@ -12,30 +12,37 @@
+ &lvds {
+ compatible = "panel-lvds";
+
+- width-mm = <210>;
+- height-mm = <158>;
++ width-mm = <261>;
++ height-mm = <163>;
+
+ data-mapping = "jeida-24";
+
+ panel-timing {
+- /* 1280x800 @60Hz Boundary Devices BD101LCC1 compatible panel */
+- clock-frequency = <65000000>;
++ /* 1280x800 @60Hz Mitsubishi AA121TD01 compatible panel */
++ clock-frequency = <71000000>;
+ hactive = <1280>;
+ vactive = <800>;
+- hsync-len = <40>;
+- hfront-porch = <80>;
+- hback-porch = <40>;
+- vfront-porch = <14>;
+- vback-porch = <14>;
+- vsync-len = <4>;
++ hsync-len = <70>;
++ hfront-porch = <20>;
++ hback-porch = <70>;
++ vsync-len = <5>;
++ vfront-porch = <3>;
++ vback-porch = <15>;
+ };
+ };
+
+ &gpio2 {
+- bl_pwm {
++ mode {
++ gpio-hog;
++ gpios = <2 GPIO_ACTIVE_HIGH>;
++ output-low;
++ line-name = "LVDS ISP 6-Bit Compatibility Mode";
++ };
++
++ sd {
+ gpio-hog;
+ gpios = <3 GPIO_ACTIVE_HIGH>;
+- output-high;
+- line-name = "BL PWM 100%";
++ output-low;
++ line-name = "LVDS Scan Direction Normal";
+ };
+ };
+--
+2.7.4
+
diff --git a/bsp/meta-rcar/meta-rcar-gen3-adas/recipes-kernel/linux/linux-renesas/0122-block-blk-mq-Fix-IO-hang.patch b/bsp/meta-rcar/meta-rcar-gen3-adas/recipes-kernel/linux/linux-renesas/0122-block-blk-mq-Fix-IO-hang.patch
new file mode 100644
index 00000000..6edbc24f
--- /dev/null
+++ b/bsp/meta-rcar/meta-rcar-gen3-adas/recipes-kernel/linux/linux-renesas/0122-block-blk-mq-Fix-IO-hang.patch
@@ -0,0 +1,78 @@
+From 67845bd98cd08aa18a07c884263aea0110273e51 Mon Sep 17 00:00:00 2001
+From: Valentine Barshak <valentine.barshak@cogentembedded.com>
+Date: Fri, 1 Mar 2019 22:22:04 +0300
+Subject: [PATCH 071/122] block: blk-mq: Fix IO hang
+
+Sometimes IO hangs are observed on Samsung Pro 960 NVME device.
+If driver returns BLK_STS_RESOURCE and SCHED_RESTART is set,
+rerun queue after a delay (BLK_MQ_DELAY_QUEUE) to avoid IO stalls.
+BLK_MQ_DELAY_QUEUE is 3 ms because both scsi-mq and nvmefc are using
+that magic value.
+
+This is part of the commit 86ff7c2a80cd357f6156a53b354f6a0b357dc0c9
+"blk-mq: introduce BLK_STS_DEV_RESOURCE" found in
+https://git.kernel.org/pub/scm/linux/kernel/git/horms/renesas.git.
+
+Signed-off-by: Valentine Barshak <valentine.barshak@cogentembedded.com>
+---
+ block/blk-mq.c | 15 +++++++++++++--
+ 1 file changed, 13 insertions(+), 2 deletions(-)
+
+diff --git a/block/blk-mq.c b/block/blk-mq.c
+index 49979c0..0d923ea 100644
+--- a/block/blk-mq.c
++++ b/block/blk-mq.c
+@@ -1037,11 +1037,14 @@ static bool blk_mq_dispatch_wait_add(struct blk_mq_hw_ctx *hctx)
+ return true;
+ }
+
++#define BLK_MQ_RESOURCE_DELAY 3 /* ms units */
++
+ bool blk_mq_dispatch_rq_list(struct request_queue *q, struct list_head *list)
+ {
+ struct blk_mq_hw_ctx *hctx;
+ struct request *rq;
+ int errors, queued;
++ blk_status_t ret = BLK_STS_OK;
+
+ if (list_empty(list))
+ return false;
+@@ -1052,7 +1055,6 @@ bool blk_mq_dispatch_rq_list(struct request_queue *q, struct list_head *list)
+ errors = queued = 0;
+ do {
+ struct blk_mq_queue_data bd;
+- blk_status_t ret;
+
+ rq = list_first_entry(list, struct request, queuelist);
+ if (!blk_mq_get_driver_tag(rq, &hctx, false)) {
+@@ -1116,6 +1118,8 @@ bool blk_mq_dispatch_rq_list(struct request_queue *q, struct list_head *list)
+ * that is where we will continue on next queue run.
+ */
+ if (!list_empty(list)) {
++ bool needs_restart;
++
+ /*
+ * If an I/O scheduler has been configured and we got a driver
+ * tag for the next request already, free it again.
+@@ -1146,10 +1150,17 @@ bool blk_mq_dispatch_rq_list(struct request_queue *q, struct list_head *list)
+ * - Some but not all block drivers stop a queue before
+ * returning BLK_STS_RESOURCE. Two exceptions are scsi-mq
+ * and dm-rq.
++ *
++ * If driver returns BLK_STS_RESOURCE and SCHED_RESTART
++ * bit is set, run queue after a delay to avoid IO stalls
++ * that could otherwise occur if the queue is idle.
+ */
+- if (!blk_mq_sched_needs_restart(hctx) &&
++ needs_restart = blk_mq_sched_needs_restart(hctx);
++ if (!needs_restart &&
+ !test_bit(BLK_MQ_S_TAG_WAITING, &hctx->state))
+ blk_mq_run_hw_queue(hctx, true);
++ else if (needs_restart && (ret == BLK_STS_RESOURCE))
++ blk_mq_delay_run_hw_queue(hctx, BLK_MQ_RESOURCE_DELAY);
+ }
+
+ return (queued + errors) != 0;
+--
+2.7.4
+
diff --git a/bsp/meta-rcar/meta-rcar-gen3-adas/recipes-kernel/linux/linux-renesas/0123-nvme-Workaround-Samsung-970-Pro-power-state-issues.patch b/bsp/meta-rcar/meta-rcar-gen3-adas/recipes-kernel/linux/linux-renesas/0123-nvme-Workaround-Samsung-970-Pro-power-state-issues.patch
new file mode 100644
index 00000000..86dcdf62
--- /dev/null
+++ b/bsp/meta-rcar/meta-rcar-gen3-adas/recipes-kernel/linux/linux-renesas/0123-nvme-Workaround-Samsung-970-Pro-power-state-issues.patch
@@ -0,0 +1,33 @@
+From 49e089f9173aaf001ed82a250f8ff0ce6f585ac4 Mon Sep 17 00:00:00 2001
+From: Valentine Barshak <valentine.barshak@cogentembedded.com>
+Date: Fri, 22 Feb 2019 02:55:02 +0300
+Subject: [PATCH 072/122] nvme: Workaround Samsung 970 Pro power state issues
+
+Sometimes Samsung 970 Pro NVME device just disappears.
+Looks like it drops into deep sleep mode during I/O.
+This behaviour has been observed at least on R-Car
+Gen3 H3ULCB and M3ULC Kingfisher boards.
+
+Add a quirk that disables deep sleep mode for the device.
+
+Signed-off-by: Valentine Barshak <valentine.barshak@cogentembedded.com>
+---
+ drivers/nvme/host/pci.c | 2 ++
+ 1 file changed, 2 insertions(+)
+
+diff --git a/drivers/nvme/host/pci.c b/drivers/nvme/host/pci.c
+index afb9987..a6c0789 100644
+--- a/drivers/nvme/host/pci.c
++++ b/drivers/nvme/host/pci.c
+@@ -2557,6 +2557,8 @@ static const struct pci_device_id nvme_id_table[] = {
+ .driver_data = NVME_QUIRK_DELAY_BEFORE_CHK_RDY, },
+ { PCI_DEVICE(0x1c5f, 0x0540), /* Memblaze Pblaze4 adapter */
+ .driver_data = NVME_QUIRK_DELAY_BEFORE_CHK_RDY, },
++ { PCI_DEVICE(0x144d, 0xa808), /* Samsung 970 Pro */
++ .driver_data = NVME_QUIRK_NO_DEEPEST_PS },
+ { PCI_DEVICE(0x144d, 0xa821), /* Samsung PM1725 */
+ .driver_data = NVME_QUIRK_DELAY_BEFORE_CHK_RDY, },
+ { PCI_DEVICE(0x144d, 0xa822), /* Samsung PM1725a */
+--
+2.7.4
+
diff --git a/bsp/meta-rcar/meta-rcar-gen3-adas/recipes-kernel/linux/linux-renesas/0124-nvme-pci-add-SGL-support.patch b/bsp/meta-rcar/meta-rcar-gen3-adas/recipes-kernel/linux/linux-renesas/0124-nvme-pci-add-SGL-support.patch
new file mode 100644
index 00000000..08e53b76
--- /dev/null
+++ b/bsp/meta-rcar/meta-rcar-gen3-adas/recipes-kernel/linux/linux-renesas/0124-nvme-pci-add-SGL-support.patch
@@ -0,0 +1,393 @@
+From 8e7e1db3e1807fe910d14bdfcd22794ce8d4fb68 Mon Sep 17 00:00:00 2001
+From: Chaitanya Kulkarni <chaitanya.kulkarni@wdc.com>
+Date: Mon, 16 Oct 2017 18:24:20 -0700
+Subject: [PATCH 073/122] nvme-pci: add SGL support
+
+This adds SGL support for NVMe PCIe driver, based on an earlier patch
+from Rajiv Shanmugam Madeswaran <smrajiv15 at gmail.com>. This patch
+refactors the original code and adds new module parameter sgl_threshold
+to determine whether to use SGL or PRP for IOs.
+
+The usage of SGLs is controlled by the sgl_threshold module parameter,
+which allows to conditionally use SGLs if average request segment
+size (avg_seg_size) is greater than sgl_threshold. In the original patch,
+the decision of using SGLs was dependent only on the IO size,
+with the new approach we consider not only IO size but also the
+number of physical segments present in the IO.
+
+We calculate avg_seg_size based on request payload bytes and number
+of physical segments present in the request.
+
+For e.g.:-
+
+1. blk_rq_nr_phys_segments = 2 blk_rq_payload_bytes = 8k
+avg_seg_size = 4K use sgl if avg_seg_size >= sgl_threshold.
+
+2. blk_rq_nr_phys_segments = 2 blk_rq_payload_bytes = 64k
+avg_seg_size = 32K use sgl if avg_seg_size >= sgl_threshold.
+
+3. blk_rq_nr_phys_segments = 16 blk_rq_payload_bytes = 64k
+avg_seg_size = 4K use sgl if avg_seg_size >= sgl_threshold.
+
+Signed-off-by: Chaitanya Kulkarni <chaitanya.kulkarni@wdc.com>
+Reviewed-by: Keith Busch <keith.busch@intel.com>
+Reviewed-by: Sagi Grimberg <sagi@grimberg.me>
+Signed-off-by: Christoph Hellwig <hch@lst.de>
+
+(cherry picked from commit a7a7cbe353a52665b8463e1822ce6ba46b0609d6
+https://git.kernel.org/pub/scm/linux/kernel/git/horms/renesas.git)
+
+Signed-off-by: Valentine Barshak <valentine.barshak@cogentembedded.com>
+---
+ drivers/nvme/host/pci.c | 214 ++++++++++++++++++++++++++++++++++++++++++------
+ 1 file changed, 187 insertions(+), 27 deletions(-)
+
+diff --git a/drivers/nvme/host/pci.c b/drivers/nvme/host/pci.c
+index a6c0789..433c6dc 100644
+--- a/drivers/nvme/host/pci.c
++++ b/drivers/nvme/host/pci.c
+@@ -45,6 +45,8 @@
+ */
+ #define NVME_AQ_BLKMQ_DEPTH (NVME_AQ_DEPTH - NVME_NR_AERS)
+
++#define SGES_PER_PAGE (PAGE_SIZE / sizeof(struct nvme_sgl_desc))
++
+ static int use_threaded_interrupts;
+ module_param(use_threaded_interrupts, int, 0);
+
+@@ -57,6 +59,12 @@ module_param(max_host_mem_size_mb, uint, 0444);
+ MODULE_PARM_DESC(max_host_mem_size_mb,
+ "Maximum Host Memory Buffer (HMB) size per controller (in MiB)");
+
++static unsigned int sgl_threshold = SZ_32K;
++module_param(sgl_threshold, uint, 0644);
++MODULE_PARM_DESC(sgl_threshold,
++ "Use SGLs when average request segment size is larger or equal to "
++ "this size. Use 0 to disable SGLs.");
++
+ static int io_queue_depth_set(const char *val, const struct kernel_param *kp);
+ static const struct kernel_param_ops io_queue_depth_ops = {
+ .set = io_queue_depth_set,
+@@ -178,6 +186,7 @@ struct nvme_queue {
+ struct nvme_iod {
+ struct nvme_request req;
+ struct nvme_queue *nvmeq;
++ bool use_sgl;
+ int aborted;
+ int npages; /* In the PRP list. 0 means small pool in use */
+ int nents; /* Used in scatterlist */
+@@ -339,17 +348,35 @@ static int nvme_npages(unsigned size, struct nvme_dev *dev)
+ return DIV_ROUND_UP(8 * nprps, PAGE_SIZE - 8);
+ }
+
+-static unsigned int nvme_iod_alloc_size(struct nvme_dev *dev,
+- unsigned int size, unsigned int nseg)
++/*
++ * Calculates the number of pages needed for the SGL segments. For example a 4k
++ * page can accommodate 256 SGL descriptors.
++ */
++static int nvme_pci_npages_sgl(unsigned int num_seg)
++{
++ return DIV_ROUND_UP(num_seg * sizeof(struct nvme_sgl_desc), PAGE_SIZE);
++}
++
++static unsigned int nvme_pci_iod_alloc_size(struct nvme_dev *dev,
++ unsigned int size, unsigned int nseg, bool use_sgl)
+ {
+- return sizeof(__le64 *) * nvme_npages(size, dev) +
+- sizeof(struct scatterlist) * nseg;
++ size_t alloc_size;
++
++ if (use_sgl)
++ alloc_size = sizeof(__le64 *) * nvme_pci_npages_sgl(nseg);
++ else
++ alloc_size = sizeof(__le64 *) * nvme_npages(size, dev);
++
++ return alloc_size + sizeof(struct scatterlist) * nseg;
+ }
+
+-static unsigned int nvme_cmd_size(struct nvme_dev *dev)
++static unsigned int nvme_pci_cmd_size(struct nvme_dev *dev, bool use_sgl)
+ {
+- return sizeof(struct nvme_iod) +
+- nvme_iod_alloc_size(dev, NVME_INT_BYTES(dev), NVME_INT_PAGES);
++ unsigned int alloc_size = nvme_pci_iod_alloc_size(dev,
++ NVME_INT_BYTES(dev), NVME_INT_PAGES,
++ use_sgl);
++
++ return sizeof(struct nvme_iod) + alloc_size;
+ }
+
+ static int nvme_admin_init_hctx(struct blk_mq_hw_ctx *hctx, void *data,
+@@ -433,10 +460,10 @@ static void __nvme_submit_cmd(struct nvme_queue *nvmeq,
+ nvmeq->sq_tail = tail;
+ }
+
+-static __le64 **iod_list(struct request *req)
++static void **nvme_pci_iod_list(struct request *req)
+ {
+ struct nvme_iod *iod = blk_mq_rq_to_pdu(req);
+- return (__le64 **)(iod->sg + blk_rq_nr_phys_segments(req));
++ return (void **)(iod->sg + blk_rq_nr_phys_segments(req));
+ }
+
+ static blk_status_t nvme_init_iod(struct request *rq, struct nvme_dev *dev)
+@@ -446,7 +473,10 @@ static blk_status_t nvme_init_iod(struct request *rq, struct nvme_dev *dev)
+ unsigned int size = blk_rq_payload_bytes(rq);
+
+ if (nseg > NVME_INT_PAGES || size > NVME_INT_BYTES(dev)) {
+- iod->sg = kmalloc(nvme_iod_alloc_size(dev, size, nseg), GFP_ATOMIC);
++ size_t alloc_size = nvme_pci_iod_alloc_size(dev, size, nseg,
++ iod->use_sgl);
++
++ iod->sg = kmalloc(alloc_size, GFP_ATOMIC);
+ if (!iod->sg)
+ return BLK_STS_RESOURCE;
+ } else {
+@@ -464,18 +494,31 @@ static blk_status_t nvme_init_iod(struct request *rq, struct nvme_dev *dev)
+ static void nvme_free_iod(struct nvme_dev *dev, struct request *req)
+ {
+ struct nvme_iod *iod = blk_mq_rq_to_pdu(req);
+- const int last_prp = dev->ctrl.page_size / 8 - 1;
++ const int last_prp = dev->ctrl.page_size / sizeof(__le64) - 1;
++ dma_addr_t dma_addr = iod->first_dma, next_dma_addr;
++
+ int i;
+- __le64 **list = iod_list(req);
+- dma_addr_t prp_dma = iod->first_dma;
+
+ if (iod->npages == 0)
+- dma_pool_free(dev->prp_small_pool, list[0], prp_dma);
++ dma_pool_free(dev->prp_small_pool, nvme_pci_iod_list(req)[0],
++ dma_addr);
++
+ for (i = 0; i < iod->npages; i++) {
+- __le64 *prp_list = list[i];
+- dma_addr_t next_prp_dma = le64_to_cpu(prp_list[last_prp]);
+- dma_pool_free(dev->prp_page_pool, prp_list, prp_dma);
+- prp_dma = next_prp_dma;
++ void *addr = nvme_pci_iod_list(req)[i];
++
++ if (iod->use_sgl) {
++ struct nvme_sgl_desc *sg_list = addr;
++
++ next_dma_addr =
++ le64_to_cpu((sg_list[SGES_PER_PAGE - 1]).addr);
++ } else {
++ __le64 *prp_list = addr;
++
++ next_dma_addr = le64_to_cpu(prp_list[last_prp]);
++ }
++
++ dma_pool_free(dev->prp_page_pool, addr, dma_addr);
++ dma_addr = next_dma_addr;
+ }
+
+ if (iod->sg != iod->inline_sg)
+@@ -563,7 +606,8 @@ static void nvme_print_sgl(struct scatterlist *sgl, int nents)
+ }
+ }
+
+-static blk_status_t nvme_setup_prps(struct nvme_dev *dev, struct request *req)
++static blk_status_t nvme_pci_setup_prps(struct nvme_dev *dev,
++ struct request *req, struct nvme_rw_command *cmnd)
+ {
+ struct nvme_iod *iod = blk_mq_rq_to_pdu(req);
+ struct dma_pool *pool;
+@@ -574,14 +618,16 @@ static blk_status_t nvme_setup_prps(struct nvme_dev *dev, struct request *req)
+ u32 page_size = dev->ctrl.page_size;
+ int offset = dma_addr & (page_size - 1);
+ __le64 *prp_list;
+- __le64 **list = iod_list(req);
++ void **list = nvme_pci_iod_list(req);
+ dma_addr_t prp_dma;
+ int nprps, i;
+
++ iod->use_sgl = false;
++
+ length -= (page_size - offset);
+ if (length <= 0) {
+ iod->first_dma = 0;
+- return BLK_STS_OK;
++ goto done;
+ }
+
+ dma_len -= (page_size - offset);
+@@ -595,7 +641,7 @@ static blk_status_t nvme_setup_prps(struct nvme_dev *dev, struct request *req)
+
+ if (length <= page_size) {
+ iod->first_dma = dma_addr;
+- return BLK_STS_OK;
++ goto done;
+ }
+
+ nprps = DIV_ROUND_UP(length, page_size);
+@@ -642,6 +688,10 @@ static blk_status_t nvme_setup_prps(struct nvme_dev *dev, struct request *req)
+ dma_len = sg_dma_len(sg);
+ }
+
++done:
++ cmnd->dptr.prp1 = cpu_to_le64(sg_dma_address(iod->sg));
++ cmnd->dptr.prp2 = cpu_to_le64(iod->first_dma);
++
+ return BLK_STS_OK;
+
+ bad_sgl:
+@@ -651,6 +701,110 @@ static blk_status_t nvme_setup_prps(struct nvme_dev *dev, struct request *req)
+ return BLK_STS_IOERR;
+ }
+
++static void nvme_pci_sgl_set_data(struct nvme_sgl_desc *sge,
++ struct scatterlist *sg)
++{
++ sge->addr = cpu_to_le64(sg_dma_address(sg));
++ sge->length = cpu_to_le32(sg_dma_len(sg));
++ sge->type = NVME_SGL_FMT_DATA_DESC << 4;
++}
++
++static void nvme_pci_sgl_set_seg(struct nvme_sgl_desc *sge,
++ dma_addr_t dma_addr, int entries)
++{
++ sge->addr = cpu_to_le64(dma_addr);
++ if (entries < SGES_PER_PAGE) {
++ sge->length = cpu_to_le32(entries * sizeof(*sge));
++ sge->type = NVME_SGL_FMT_LAST_SEG_DESC << 4;
++ } else {
++ sge->length = cpu_to_le32(PAGE_SIZE);
++ sge->type = NVME_SGL_FMT_SEG_DESC << 4;
++ }
++}
++
++static blk_status_t nvme_pci_setup_sgls(struct nvme_dev *dev,
++ struct request *req, struct nvme_rw_command *cmd)
++{
++ struct nvme_iod *iod = blk_mq_rq_to_pdu(req);
++ int length = blk_rq_payload_bytes(req);
++ struct dma_pool *pool;
++ struct nvme_sgl_desc *sg_list;
++ struct scatterlist *sg = iod->sg;
++ int entries = iod->nents, i = 0;
++ dma_addr_t sgl_dma;
++
++ iod->use_sgl = true;
++
++ /* setting the transfer type as SGL */
++ cmd->flags = NVME_CMD_SGL_METABUF;
++
++ if (length == sg_dma_len(sg)) {
++ nvme_pci_sgl_set_data(&cmd->dptr.sgl, sg);
++ return BLK_STS_OK;
++ }
++
++ if (entries <= (256 / sizeof(struct nvme_sgl_desc))) {
++ pool = dev->prp_small_pool;
++ iod->npages = 0;
++ } else {
++ pool = dev->prp_page_pool;
++ iod->npages = 1;
++ }
++
++ sg_list = dma_pool_alloc(pool, GFP_ATOMIC, &sgl_dma);
++ if (!sg_list) {
++ iod->npages = -1;
++ return BLK_STS_RESOURCE;
++ }
++
++ nvme_pci_iod_list(req)[0] = sg_list;
++ iod->first_dma = sgl_dma;
++
++ nvme_pci_sgl_set_seg(&cmd->dptr.sgl, sgl_dma, entries);
++
++ do {
++ if (i == SGES_PER_PAGE) {
++ struct nvme_sgl_desc *old_sg_desc = sg_list;
++ struct nvme_sgl_desc *link = &old_sg_desc[i - 1];
++
++ sg_list = dma_pool_alloc(pool, GFP_ATOMIC, &sgl_dma);
++ if (!sg_list)
++ return BLK_STS_RESOURCE;
++
++ i = 0;
++ nvme_pci_iod_list(req)[iod->npages++] = sg_list;
++ sg_list[i++] = *link;
++ nvme_pci_sgl_set_seg(link, sgl_dma, entries);
++ }
++
++ nvme_pci_sgl_set_data(&sg_list[i++], sg);
++
++ length -= sg_dma_len(sg);
++ sg = sg_next(sg);
++ entries--;
++ } while (length > 0);
++
++ WARN_ON(entries > 0);
++ return BLK_STS_OK;
++}
++
++static inline bool nvme_pci_use_sgls(struct nvme_dev *dev, struct request *req)
++{
++ struct nvme_iod *iod = blk_mq_rq_to_pdu(req);
++ unsigned int avg_seg_size;
++
++ avg_seg_size = DIV_ROUND_UP(blk_rq_payload_bytes(req),
++ blk_rq_nr_phys_segments(req));
++
++ if (!(dev->ctrl.sgls & ((1 << 0) | (1 << 1))))
++ return false;
++ if (!iod->nvmeq->qid)
++ return false;
++ if (!sgl_threshold || avg_seg_size < sgl_threshold)
++ return false;
++ return true;
++}
++
+ static blk_status_t nvme_map_data(struct nvme_dev *dev, struct request *req,
+ struct nvme_command *cmnd)
+ {
+@@ -670,7 +824,11 @@ static blk_status_t nvme_map_data(struct nvme_dev *dev, struct request *req,
+ DMA_ATTR_NO_WARN))
+ goto out;
+
+- ret = nvme_setup_prps(dev, req);
++ if (nvme_pci_use_sgls(dev, req))
++ ret = nvme_pci_setup_sgls(dev, req, &cmnd->rw);
++ else
++ ret = nvme_pci_setup_prps(dev, req, &cmnd->rw);
++
+ if (ret != BLK_STS_OK)
+ goto out_unmap;
+
+@@ -690,8 +848,6 @@ static blk_status_t nvme_map_data(struct nvme_dev *dev, struct request *req,
+ goto out_unmap;
+ }
+
+- cmnd->rw.dptr.prp1 = cpu_to_le64(sg_dma_address(iod->sg));
+- cmnd->rw.dptr.prp2 = cpu_to_le64(iod->first_dma);
+ if (blk_integrity_rq(req))
+ cmnd->rw.metadata = cpu_to_le64(sg_dma_address(&iod->meta_sg));
+ return BLK_STS_OK;
+@@ -1398,7 +1554,7 @@ static int nvme_alloc_admin_tags(struct nvme_dev *dev)
+ dev->admin_tagset.queue_depth = NVME_AQ_BLKMQ_DEPTH - 1;
+ dev->admin_tagset.timeout = ADMIN_TIMEOUT;
+ dev->admin_tagset.numa_node = dev_to_node(dev->dev);
+- dev->admin_tagset.cmd_size = nvme_cmd_size(dev);
++ dev->admin_tagset.cmd_size = nvme_pci_cmd_size(dev, false);
+ dev->admin_tagset.flags = BLK_MQ_F_NO_SCHED;
+ dev->admin_tagset.driver_data = dev;
+
+@@ -1924,7 +2080,11 @@ static int nvme_dev_add(struct nvme_dev *dev)
+ dev->tagset.numa_node = dev_to_node(dev->dev);
+ dev->tagset.queue_depth =
+ min_t(int, dev->q_depth, BLK_MQ_MAX_DEPTH) - 1;
+- dev->tagset.cmd_size = nvme_cmd_size(dev);
++ dev->tagset.cmd_size = nvme_pci_cmd_size(dev, false);
++ if ((dev->ctrl.sgls & ((1 << 0) | (1 << 1))) && sgl_threshold) {
++ dev->tagset.cmd_size = max(dev->tagset.cmd_size,
++ nvme_pci_cmd_size(dev, true));
++ }
+ dev->tagset.flags = BLK_MQ_F_SHOULD_MERGE;
+ dev->tagset.driver_data = dev;
+
+--
+2.7.4
+
diff --git a/bsp/meta-rcar/meta-rcar-gen3-adas/recipes-kernel/linux/linux-renesas/0125-nvme-pci-don-t-open-code-nvme_reset_ctrl.patch b/bsp/meta-rcar/meta-rcar-gen3-adas/recipes-kernel/linux/linux-renesas/0125-nvme-pci-don-t-open-code-nvme_reset_ctrl.patch
new file mode 100644
index 00000000..406d0f75
--- /dev/null
+++ b/bsp/meta-rcar/meta-rcar-gen3-adas/recipes-kernel/linux/linux-renesas/0125-nvme-pci-don-t-open-code-nvme_reset_ctrl.patch
@@ -0,0 +1,36 @@
+From 5814a8b9881d3280577d7ccf640b63bfee9822ae Mon Sep 17 00:00:00 2001
+From: Sagi Grimberg <sagi@grimberg.me>
+Date: Sun, 31 Dec 2017 14:01:19 +0200
+Subject: [PATCH 074/122] nvme-pci: don't open-code nvme_reset_ctrl
+
+Signed-off-by: Sagi Grimberg <sagi@grimberg.me>
+Signed-off-by: Christoph Hellwig <hch@lst.de>
+
+(cherry picked from commit 4caff8fc19f10ffb06f095a9cf5a9e755377112e
+https://git.kernel.org/pub/scm/linux/kernel/git/horms/renesas.git)
+
+Signed-off-by: Valentine Barshak <valentine.barshak@cogentembedded.com>
+---
+ drivers/nvme/host/pci.c | 4 ++--
+ 1 file changed, 2 insertions(+), 2 deletions(-)
+
+diff --git a/drivers/nvme/host/pci.c b/drivers/nvme/host/pci.c
+index 433c6dc..8f234b5 100644
+--- a/drivers/nvme/host/pci.c
++++ b/drivers/nvme/host/pci.c
+@@ -2533,10 +2533,10 @@ static int nvme_probe(struct pci_dev *pdev, const struct pci_device_id *id)
+ if (result)
+ goto release_pools;
+
+- nvme_change_ctrl_state(&dev->ctrl, NVME_CTRL_RESETTING);
+ dev_info(dev->ctrl.device, "pci function %s\n", dev_name(&pdev->dev));
+
+- queue_work(nvme_wq, &dev->ctrl.reset_work);
++ nvme_reset_ctrl(&dev->ctrl);
++
+ return 0;
+
+ release_pools:
+--
+2.7.4
+
diff --git a/bsp/meta-rcar/meta-rcar-gen3-adas/recipes-kernel/linux/linux-renesas/0126-nvme-pci-limit-max-IO-size-and-segments-to-avoid-hig.patch b/bsp/meta-rcar/meta-rcar-gen3-adas/recipes-kernel/linux/linux-renesas/0126-nvme-pci-limit-max-IO-size-and-segments-to-avoid-hig.patch
new file mode 100644
index 00000000..b56c0510
--- /dev/null
+++ b/bsp/meta-rcar/meta-rcar-gen3-adas/recipes-kernel/linux/linux-renesas/0126-nvme-pci-limit-max-IO-size-and-segments-to-avoid-hig.patch
@@ -0,0 +1,164 @@
+From 226592cd140ed5f1b08d2ceb51f1a1b2e629b506 Mon Sep 17 00:00:00 2001
+From: Valentine Barshak <valentine.barshak@cogentembedded.com>
+Date: Sun, 24 Feb 2019 01:05:24 +0300
+Subject: [PATCH 075/122] nvme-pci: limit max IO size and segments to avoid
+ high order allocations
+
+nvme requires an sg table allocation for each request. If the request
+is large, then the allocation can become quite large. For instance,
+with our default software settings of 1280KB IO size, we'll need
+10248 bytes of sg table. That turns into a 2nd order allocation,
+which we can't always guarantee. If we fail the allocation, blk-mq
+will retry it later. But there's no guarantee that we'll EVER be
+able to allocate that much contigious memory.
+
+Limit the IO size such that we never need more than a single page
+of memory. That's a lot faster and more reliable. Then back that
+allocation with a mempool, so that we know we'll always be able
+to succeed the allocation at some point.
+
+Signed-off-by: Jens Axboe <axboe@kernel.dk>
+Acked-by: Keith Busch <keith.busch@intel.com>
+Signed-off-by: Christoph Hellwig <hch@lst.de>
+
+(cherry picked from commit 943e942e6266f22babee5efeb00f8f672fbff5bd
+https://git.kernel.org/pub/scm/linux/kernel/git/horms/renesas.git)
+
+Slightly modified the original commit to make it apply with no fuzz.
+
+Signed-off-by: Valentine Barshak <valentine.barshak@cogentembedded.com>
+---
+ drivers/nvme/host/core.c | 1 +
+ drivers/nvme/host/nvme.h | 1 +
+ drivers/nvme/host/pci.c | 42 +++++++++++++++++++++++++++++++++++++-----
+ 3 files changed, 39 insertions(+), 5 deletions(-)
+
+diff --git a/drivers/nvme/host/core.c b/drivers/nvme/host/core.c
+index 3a63d58..adb9196 100644
+--- a/drivers/nvme/host/core.c
++++ b/drivers/nvme/host/core.c
+@@ -1513,6 +1513,7 @@ static void nvme_set_queue_limits(struct nvme_ctrl *ctrl,
+ u32 max_segments =
+ (ctrl->max_hw_sectors / (ctrl->page_size >> 9)) + 1;
+
++ max_segments = min_not_zero(max_segments, ctrl->max_segments);
+ blk_queue_max_hw_sectors(q, ctrl->max_hw_sectors);
+ blk_queue_max_segments(q, min_t(u32, max_segments, USHRT_MAX));
+ }
+diff --git a/drivers/nvme/host/nvme.h b/drivers/nvme/host/nvme.h
+index 7ef0a8e..d207ff1 100644
+--- a/drivers/nvme/host/nvme.h
++++ b/drivers/nvme/host/nvme.h
+@@ -159,6 +159,7 @@ struct nvme_ctrl {
+ u64 cap;
+ u32 page_size;
+ u32 max_hw_sectors;
++ u32 max_segments;
+ u16 oncs;
+ u16 vid;
+ u16 oacs;
+diff --git a/drivers/nvme/host/pci.c b/drivers/nvme/host/pci.c
+index 8f234b5..4c585e7 100644
+--- a/drivers/nvme/host/pci.c
++++ b/drivers/nvme/host/pci.c
+@@ -47,6 +47,13 @@
+
+ #define SGES_PER_PAGE (PAGE_SIZE / sizeof(struct nvme_sgl_desc))
+
++/*
++ * These can be higher, but we need to ensure that any command doesn't
++ * require an sg allocation that needs more than a page of data.
++ */
++#define NVME_MAX_KB_SZ 4096
++#define NVME_MAX_SEGS 127
++
+ static int use_threaded_interrupts;
+ module_param(use_threaded_interrupts, int, 0);
+
+@@ -109,6 +116,8 @@ struct nvme_dev {
+ struct nvme_ctrl ctrl;
+ struct completion ioq_wait;
+
++ mempool_t *iod_mempool;
++
+ /* shadow doorbell buffer support: */
+ u32 *dbbuf_dbs;
+ dma_addr_t dbbuf_dbs_dma_addr;
+@@ -473,10 +482,7 @@ static blk_status_t nvme_init_iod(struct request *rq, struct nvme_dev *dev)
+ unsigned int size = blk_rq_payload_bytes(rq);
+
+ if (nseg > NVME_INT_PAGES || size > NVME_INT_BYTES(dev)) {
+- size_t alloc_size = nvme_pci_iod_alloc_size(dev, size, nseg,
+- iod->use_sgl);
+-
+- iod->sg = kmalloc(alloc_size, GFP_ATOMIC);
++ iod->sg = mempool_alloc(dev->iod_mempool, GFP_ATOMIC);
+ if (!iod->sg)
+ return BLK_STS_RESOURCE;
+ } else {
+@@ -522,7 +528,7 @@ static void nvme_free_iod(struct nvme_dev *dev, struct request *req)
+ }
+
+ if (iod->sg != iod->inline_sg)
+- kfree(iod->sg);
++ mempool_free(iod->sg, dev->iod_mempool);
+ }
+
+ #ifdef CONFIG_BLK_DEV_INTEGRITY
+@@ -2303,6 +2309,7 @@ static void nvme_pci_free_ctrl(struct nvme_ctrl *ctrl)
+ blk_put_queue(dev->ctrl.admin_q);
+ kfree(dev->queues);
+ free_opal_dev(dev->ctrl.opal_dev);
++ mempool_destroy(dev->iod_mempool);
+ kfree(dev);
+ }
+
+@@ -2345,6 +2352,13 @@ static void nvme_reset_work(struct work_struct *work)
+ if (result)
+ goto out;
+
++ /*
++ * Limit the max command size to prevent iod->sg allocations going
++ * over a single page.
++ */
++ dev->ctrl.max_hw_sectors = NVME_MAX_KB_SZ << 1;
++ dev->ctrl.max_segments = NVME_MAX_SEGS;
++
+ result = nvme_init_identify(&dev->ctrl);
+ if (result)
+ goto out;
+@@ -2496,6 +2510,7 @@ static int nvme_probe(struct pci_dev *pdev, const struct pci_device_id *id)
+ int node, result = -ENOMEM;
+ struct nvme_dev *dev;
+ unsigned long quirks = id->driver_data;
++ size_t alloc_size;
+
+ node = dev_to_node(&pdev->dev);
+ if (node == NUMA_NO_NODE)
+@@ -2533,6 +2548,23 @@ static int nvme_probe(struct pci_dev *pdev, const struct pci_device_id *id)
+ if (result)
+ goto release_pools;
+
++ /*
++ * Double check that our mempool alloc size will cover the biggest
++ * command we support.
++ */
++ alloc_size = nvme_pci_iod_alloc_size(dev, NVME_MAX_KB_SZ,
++ NVME_MAX_SEGS, true);
++ WARN_ON_ONCE(alloc_size > PAGE_SIZE);
++
++ dev->iod_mempool = mempool_create_node(1, mempool_kmalloc,
++ mempool_kfree,
++ (void *) alloc_size,
++ GFP_KERNEL, node);
++ if (!dev->iod_mempool) {
++ result = -ENOMEM;
++ goto release_pools;
++ }
++
+ dev_info(dev->ctrl.device, "pci function %s\n", dev_name(&pdev->dev));
+
+ nvme_reset_ctrl(&dev->ctrl);
+--
+2.7.4
+
diff --git a/bsp/meta-rcar/meta-rcar-gen3-adas/recipes-kernel/linux/linux-renesas/0127-swiotlb-Respect-DMA_ATTR_NO_WARN-in-swiotlb_map_sg_a.patch b/bsp/meta-rcar/meta-rcar-gen3-adas/recipes-kernel/linux/linux-renesas/0127-swiotlb-Respect-DMA_ATTR_NO_WARN-in-swiotlb_map_sg_a.patch
new file mode 100644
index 00000000..c829fea1
--- /dev/null
+++ b/bsp/meta-rcar/meta-rcar-gen3-adas/recipes-kernel/linux/linux-renesas/0127-swiotlb-Respect-DMA_ATTR_NO_WARN-in-swiotlb_map_sg_a.patch
@@ -0,0 +1,33 @@
+From 33342c77defd9f19b91269521f6eda34fdf0410b Mon Sep 17 00:00:00 2001
+From: Valentine Barshak <valentine.barshak@cogentembedded.com>
+Date: Sat, 2 Mar 2019 01:18:25 +0300
+Subject: [PATCH 076/122] swiotlb: Respect DMA_ATTR_NO_WARN in
+ swiotlb_map_sg_attrs
+
+If DMA_ATTR_NO_WARN attribute is set, do not call swiotlb_full()
+to print a "swiotlb full" warning. The function is actually removed
+altogether in the later kernels since all properly written drivers
+have error handling in the dma_map_single / dma_map_page callers.
+
+Signed-off-by: Valentine Barshak <valentine.barshak@cogentembedded.com>
+---
+ lib/swiotlb.c | 3 ++-
+ 1 file changed, 2 insertions(+), 1 deletion(-)
+
+diff --git a/lib/swiotlb.c b/lib/swiotlb.c
+index 20df2fd..7b5666d 100644
+--- a/lib/swiotlb.c
++++ b/lib/swiotlb.c
+@@ -995,7 +995,8 @@ swiotlb_map_sg_attrs(struct device *hwdev, struct scatterlist *sgl, int nelems,
+ if (map == SWIOTLB_MAP_ERROR) {
+ /* Don't panic here, we expect map_sg users
+ to do proper error handling. */
+- swiotlb_full(hwdev, sg->length, dir, 0);
++ if (!(attrs & DMA_ATTR_NO_WARN))
++ swiotlb_full(hwdev, sg->length, dir, 0);
+ attrs |= DMA_ATTR_SKIP_CPU_SYNC;
+ swiotlb_unmap_sg_attrs(hwdev, sgl, i, dir,
+ attrs);
+--
+2.7.4
+
diff --git a/bsp/meta-rcar/meta-rcar-gen3-adas/recipes-kernel/linux/linux-renesas/0128-arm64-dts-Add-H3ULCB-VideoBox-2.1-support.patch b/bsp/meta-rcar/meta-rcar-gen3-adas/recipes-kernel/linux/linux-renesas/0128-arm64-dts-Add-H3ULCB-VideoBox-2.1-support.patch
new file mode 100644
index 00000000..93d88621
--- /dev/null
+++ b/bsp/meta-rcar/meta-rcar-gen3-adas/recipes-kernel/linux/linux-renesas/0128-arm64-dts-Add-H3ULCB-VideoBox-2.1-support.patch
@@ -0,0 +1,292 @@
+From 79d76546341424d3b712bfb65c96f5150386da72 Mon Sep 17 00:00:00 2001
+From: Andrey Gusakov <andrey.gusakov@cogentembedded.com>
+Date: Fri, 22 Feb 2019 19:45:04 +0300
+Subject: [PATCH 077/122] arm64: dts: Add H3ULCB VideoBox 2.1 support.
+
+This adds VideoBox 2.1 support for H3ULCB and H3ULCB 4x2G boards.
+
+Signed-off-by: Andrey Gusakov <andrey.gusakov@cogentembedded.com>
+Signed-off-by: Valentine Barshak <valentine.barshak@cogentembedded.com>
+---
+ arch/arm64/boot/dts/renesas/Makefile | 1 +
+ .../boot/dts/renesas/r8a7795-h3ulcb-4x2g-vb2.1.dts | 68 ++++++++++++++++
+ .../boot/dts/renesas/r8a7795-h3ulcb-vb2.1.dts | 68 ++++++++++++++++
+ arch/arm64/boot/dts/renesas/ulcb-vb2.1.dtsi | 90 ++++++++++++++++++++++
+ arch/arm64/boot/dts/renesas/ulcb-vb2.dtsi | 2 +-
+ 5 files changed, 228 insertions(+), 1 deletion(-)
+ create mode 100644 arch/arm64/boot/dts/renesas/r8a7795-h3ulcb-4x2g-vb2.1.dts
+ create mode 100644 arch/arm64/boot/dts/renesas/r8a7795-h3ulcb-vb2.1.dts
+ create mode 100644 arch/arm64/boot/dts/renesas/ulcb-vb2.1.dtsi
+
+diff --git a/arch/arm64/boot/dts/renesas/Makefile b/arch/arm64/boot/dts/renesas/Makefile
+index e7fc36e..f7f8638 100644
+--- a/arch/arm64/boot/dts/renesas/Makefile
++++ b/arch/arm64/boot/dts/renesas/Makefile
+@@ -30,6 +30,7 @@ dtb-$(CONFIG_ARCH_R8A7795) += r8a7795-h3ulcb-had-alfa.dtb r8a7795-h3ulcb-had-bet
+ dtb-$(CONFIG_ARCH_R8A7795) += r8a7795-h3ulcb-kf.dtb r8a7795-es1-h3ulcb-kf.dtb r8a7795-h3ulcb-4x2g-kf.dtb
+ dtb-$(CONFIG_ARCH_R8A7795) += r8a7795-h3ulcb-vb.dtb r8a7795-es1-h3ulcb-vb.dtb r8a7795-h3ulcb-4x2g-vb.dtb
+ dtb-$(CONFIG_ARCH_R8A7795) += r8a7795-h3ulcb-vb2.dtb r8a7795-es1-h3ulcb-vb2.dtb r8a7795-h3ulcb-4x2g-vb2.dtb
++dtb-$(CONFIG_ARCH_R8A7795) += r8a7795-h3ulcb-vb2.1.dtb r8a7795-h3ulcb-4x2g-vb2.1.dtb
+ dtb-$(CONFIG_ARCH_R8A7795) += r8a7795-h3ulcb-vbm.dtb r8a7795-es1-h3ulcb-vbm.dtb r8a7795-h3ulcb-4x2g-vbm.dtb
+ dtb-$(CONFIG_ARCH_R8A77965) += r8a77965-m3nulcb-kf.dtb
+ #dtb-$(CONFIG_ARCH_R8A77970) += r8a77970-eagle-function.dtb
+diff --git a/arch/arm64/boot/dts/renesas/r8a7795-h3ulcb-4x2g-vb2.1.dts b/arch/arm64/boot/dts/renesas/r8a7795-h3ulcb-4x2g-vb2.1.dts
+new file mode 100644
+index 0000000..1a9d0be
+--- /dev/null
++++ b/arch/arm64/boot/dts/renesas/r8a7795-h3ulcb-4x2g-vb2.1.dts
+@@ -0,0 +1,68 @@
++/*
++ * Device Tree Source for the H3ULCB Videobox board V2.1 on r8a7795
++ *
++ * Copyright (C) 2019 Cogent Embedded, Inc.
++ *
++ * This file is licensed under the terms of the GNU General Public License
++ * version 2. This program is licensed "as is" without any warranty of any
++ * kind, whether express or implied.
++ */
++
++#include "r8a7795-h3ulcb-4x2g.dts"
++#include "ulcb-vb2.1.dtsi"
++
++/ {
++ model = "Renesas H3ULCB with 8GiB (4 x 2 GiB) Videobox V2.1 board based on r8a7795";
++
++ hdmi1-out {
++ compatible = "hdmi-connector";
++ type = "a";
++
++ port {
++ hdmi1_con: endpoint {
++ remote-endpoint = <&rcar_dw_hdmi1_out>;
++ };
++ };
++ };
++};
++
++&du {
++ ports {
++ port@2 {
++ endpoint {
++ remote-endpoint = <&rcar_dw_hdmi1_in>;
++ };
++ };
++ port@3 {
++ endpoint {
++ remote-endpoint = <&lvds_in>;
++ };
++ };
++ };
++};
++
++&hdmi1 {
++ status = "okay";
++
++ ports {
++ #address-cells = <1>;
++ #size-cells = <0>;
++
++ port@0 {
++ reg = <0>;
++ rcar_dw_hdmi1_in: endpoint {
++ remote-endpoint = <&du_out_hdmi1>;
++ };
++ };
++ port@1 {
++ reg = <1>;
++ rcar_dw_hdmi1_out: endpoint {
++ remote-endpoint = <&hdmi1_con>;
++ };
++ };
++ };
++};
++
++&hsusb {
++ status = "okay";
++};
+diff --git a/arch/arm64/boot/dts/renesas/r8a7795-h3ulcb-vb2.1.dts b/arch/arm64/boot/dts/renesas/r8a7795-h3ulcb-vb2.1.dts
+new file mode 100644
+index 0000000..43c20b0
+--- /dev/null
++++ b/arch/arm64/boot/dts/renesas/r8a7795-h3ulcb-vb2.1.dts
+@@ -0,0 +1,68 @@
++/*
++ * Device Tree Source for the H3ULCB Videobox board V2.1 on r8a7795
++ *
++ * Copyright (C) 2019 Cogent Embedded, Inc.
++ *
++ * This file is licensed under the terms of the GNU General Public License
++ * version 2. This program is licensed "as is" without any warranty of any
++ * kind, whether express or implied.
++ */
++
++#include "r8a7795-h3ulcb.dts"
++#include "ulcb-vb2.1.dtsi"
++
++/ {
++ model = "Renesas H3ULCB Videobox V2.1 board based on r8a7795";
++
++ hdmi1-out {
++ compatible = "hdmi-connector";
++ type = "a";
++
++ port {
++ hdmi1_con: endpoint {
++ remote-endpoint = <&rcar_dw_hdmi1_out>;
++ };
++ };
++ };
++};
++
++&du {
++ ports {
++ port@2 {
++ endpoint {
++ remote-endpoint = <&rcar_dw_hdmi1_in>;
++ };
++ };
++ port@3 {
++ endpoint {
++ remote-endpoint = <&lvds_in>;
++ };
++ };
++ };
++};
++
++&hdmi1 {
++ status = "okay";
++
++ ports {
++ #address-cells = <1>;
++ #size-cells = <0>;
++
++ port@0 {
++ reg = <0>;
++ rcar_dw_hdmi1_in: endpoint {
++ remote-endpoint = <&du_out_hdmi1>;
++ };
++ };
++ port@1 {
++ reg = <1>;
++ rcar_dw_hdmi1_out: endpoint {
++ remote-endpoint = <&hdmi1_con>;
++ };
++ };
++ };
++};
++
++&hsusb {
++ status = "okay";
++};
+diff --git a/arch/arm64/boot/dts/renesas/ulcb-vb2.1.dtsi b/arch/arm64/boot/dts/renesas/ulcb-vb2.1.dtsi
+new file mode 100644
+index 0000000..0df720d
+--- /dev/null
++++ b/arch/arm64/boot/dts/renesas/ulcb-vb2.1.dtsi
+@@ -0,0 +1,90 @@
++/*
++ * Device Tree Source for the ULCB Videobox V2.1 board
++ *
++ * Copyright (C) 2019 Cogent Embedded, Inc.
++ *
++ * This file is licensed under the terms of the GNU General Public License
++ * version 2. This program is licensed "as is" without any warranty of any
++ * kind, whether express or implied.
++ */
++
++#include "ulcb-vb2.dtsi"
++
++/{
++ leds {
++ led_button {
++ gpios = <&gpio_ext_led 9 GPIO_ACTIVE_LOW>;
++ linux,default-trigger = "cpu";
++ };
++ };
++
++ gpio_keys_polled {
++ compatible = "gpio-keys-polled";
++ poll-interval = <100>;
++ autorepeat;
++
++ button_pwr {
++ label = "GPIO Key POWER";
++ linux,code = <116>;
++ gpios = <&gpio_ext_led 8 GPIO_ACTIVE_LOW>;
++ };
++ };
++};
++
++&i2c_power {
++ adc@48 {
++ reg = <0x48>;
++ compatible = "ti,ads1115";
++ #address-cells = <1>;
++ #size-cells = <0>;
++ wake7_voltage: channel@4 {
++ /* single endded AIN0 */
++ reg = <4>;
++ };
++ wake8_voltage: channel@5 {
++ /* single endded AIN1 */
++ reg = <5>;
++ };
++ dc_prot_voltage: channel@6 {
++ /* single endded AIN2 */
++ reg = <6>;
++ };
++ dcdc_voltage: channel@7 {
++ /* single endded AIN3 */
++ reg = <7>;
++ };
++ };
++};
++
++&gpio6 {
++ /delete-node/m2_0_rst;
++
++ m2_0_rst {
++ gpio-hog;
++ gpios = <6 GPIO_ACTIVE_HIGH>;
++ output-high;
++ line-name = "M.2 0 RST#";
++ };
++};
++
++&pfc {
++ usb1_pins: usb1 {
++ groups = "usb1";
++ function = "usb1";
++ };
++};
++
++&usb2_phy1 {
++ pinctrl-0 = <&usb1_pins>;
++ pinctrl-names = "default";
++
++ status = "okay";
++};
++
++&ehci1 {
++ status = "okay";
++};
++
++&ohci1 {
++ status = "okay";
++};
+diff --git a/arch/arm64/boot/dts/renesas/ulcb-vb2.dtsi b/arch/arm64/boot/dts/renesas/ulcb-vb2.dtsi
+index 0f49b44..1610949 100644
+--- a/arch/arm64/boot/dts/renesas/ulcb-vb2.dtsi
++++ b/arch/arm64/boot/dts/renesas/ulcb-vb2.dtsi
+@@ -1061,7 +1061,7 @@
+ };
+ };
+
+- i2c@2 {
++ i2c_power: i2c@2 {
+ #address-cells = <1>;
+ #size-cells = <0>;
+ reg = <2>;
+--
+2.7.4
+
diff --git a/bsp/meta-rcar/meta-rcar-gen3-adas/recipes-kernel/linux/linux-renesas/0129-can-rcar_canfd-fix-possible-IRQ-storm-on-high-load.patch b/bsp/meta-rcar/meta-rcar-gen3-adas/recipes-kernel/linux/linux-renesas/0129-can-rcar_canfd-fix-possible-IRQ-storm-on-high-load.patch
new file mode 100644
index 00000000..4de49573
--- /dev/null
+++ b/bsp/meta-rcar/meta-rcar-gen3-adas/recipes-kernel/linux/linux-renesas/0129-can-rcar_canfd-fix-possible-IRQ-storm-on-high-load.patch
@@ -0,0 +1,63 @@
+From 0c0b56e36d1b3479f5e3f6c2b8bf52b89caa3b78 Mon Sep 17 00:00:00 2001
+From: Nikita Yushchenko <nikita.yoush@cogentembedded.com>
+Date: Wed, 13 Mar 2019 18:49:28 +0300
+Subject: [PATCH 078/122] can: rcar_canfd: fix possible IRQ storm on high load
+
+We have observed rcar_canfd driver entering IRQ storm under high load,
+with following scenario:
+- rcar_canfd_global_interrupt() in entered due to Rx available,
+- napi_schedule_prep() is called, and sets NAPIF_STATE_SCHED in state
+- Rx fifo interrupts are masked,
+- rcar_canfd_global_interrupt() is entered again, this time due to
+ error interrupt (e.g. due to overflow),
+- since scheduled napi poller has not yet executed, condition for calling
+ napi_schedule_prep() from rcar_canfd_global_interrupt() remains true,
+ thus napi_schedule_prep() gets called and sets NAPIF_STATE_MISSED flag
+ in state,
+- later, napi poller function rcar_canfd_rx_poll() gets executed, and
+ calls napi_complete_done(),
+- due to NAPIF_STATE_MISSED flag in state, this call does not clear
+ NAPIF_STATE_SCHED flag from state,
+- on return from napi_complete_done(), rcar_canfd_rx_poll() unmasks Rx
+ interrutps,
+- Rx interrupt happens, rcar_canfd_global_interrupt() gets called
+ and calls napi_schedule_prep(),
+- since NAPIF_STATE_SCHED is set in state at this time, this call
+ returns false,
+- due to that false return, rcar_canfd_global_interrupt() returns
+ without masking Rx interrupt
+- and this results into IRQ storm: unmasked Rx interrupt happens again
+ and again is misprocessed in the same way.
+
+This patch fixes that scenario by unmasking Rx interrupts only when
+napi_complete_done() returns true, which means it has cleared
+NAPIF_STATE_SCHED in state.
+
+Signed-off-by: Nikita Yushchenko <nikita.yoush@cogentembedded.com>
+---
+ drivers/net/can/rcar/rcar_canfd.c | 9 +++++----
+ 1 file changed, 5 insertions(+), 4 deletions(-)
+
+diff --git a/drivers/net/can/rcar/rcar_canfd.c b/drivers/net/can/rcar/rcar_canfd.c
+index 5b98f8c..0017ab9 100644
+--- a/drivers/net/can/rcar/rcar_canfd.c
++++ b/drivers/net/can/rcar/rcar_canfd.c
+@@ -1522,10 +1522,11 @@ static int rcar_canfd_rx_poll(struct napi_struct *napi, int quota)
+
+ /* All packets processed */
+ if (num_pkts < quota) {
+- napi_complete_done(napi, num_pkts);
+- /* Enable Rx FIFO interrupts */
+- rcar_canfd_set_bit(priv->base, RCANFD_RFCC(ridx),
+- RCANFD_RFCC_RFIE);
++ if (napi_complete_done(napi, num_pkts)) {
++ /* Enable Rx FIFO interrupts */
++ rcar_canfd_set_bit(priv->base, RCANFD_RFCC(ridx),
++ RCANFD_RFCC_RFIE);
++ }
+ }
+ return num_pkts;
+ }
+--
+2.7.4
+
diff --git a/bsp/meta-rcar/meta-rcar-gen3-adas/recipes-kernel/linux/linux-renesas/0130-LVDS-ar0132-use-context-swwitch.patch b/bsp/meta-rcar/meta-rcar-gen3-adas/recipes-kernel/linux/linux-renesas/0130-LVDS-ar0132-use-context-swwitch.patch
new file mode 100644
index 00000000..bde202ed
--- /dev/null
+++ b/bsp/meta-rcar/meta-rcar-gen3-adas/recipes-kernel/linux/linux-renesas/0130-LVDS-ar0132-use-context-swwitch.patch
@@ -0,0 +1,119 @@
+From 4bf93979202bec78f922fa39728e0f00f8650b21 Mon Sep 17 00:00:00 2001
+From: Vladimir Barinov <vladimir.barinov@cogentembedded.com>
+Date: Wed, 30 Aug 2017 14:44:29 +0300
+Subject: [PATCH 079/122] LVDS: ar0132 use context swwitch
+
+This enabled context-A-B switch on every frame
+
+Signed-off-by: Vladimir Barinov <vladimir.barinov@cogentembedded.com>
+---
+ drivers/media/i2c/soc_camera/ar0132.c | 19 +++++++++++++++++++
+ drivers/media/platform/soc_camera/rcar_vin.c | 23 ++++++++++++++++++-----
+ 2 files changed, 37 insertions(+), 5 deletions(-)
+
+diff --git a/drivers/media/i2c/soc_camera/ar0132.c b/drivers/media/i2c/soc_camera/ar0132.c
+index 2865902..72dfbb4 100644
+--- a/drivers/media/i2c/soc_camera/ar0132.c
++++ b/drivers/media/i2c/soc_camera/ar0132.c
+@@ -254,11 +254,30 @@ static int ar0132_s_register(struct v4l2_subdev *sd,
+ }
+ #endif
+
++static int ar0132_isr(struct v4l2_subdev *sd, u32 status, bool *handled)
++{
++ struct i2c_client *client = v4l2_get_subdevdata(sd);
++#if 1
++ u16 frame_count = 0;
++ /* read frame counter from sensor */
++ reg16_read16(client, 0x303a, &frame_count);
++#else
++ static int frame_count = 0;
++ /* get cached frame counter */
++ frame_count++;
++#endif
++ /* odd frame -> Mode A, even frame -> Mode B */
++ reg16_write16(client, 0x30b0, frame_count & 1 ? 0x2 : 0x2002);
++
++ return 0;
++};
++
+ static struct v4l2_subdev_core_ops ar0132_core_ops = {
+ #ifdef CONFIG_VIDEO_ADV_DEBUG
+ .g_register = ar0132_g_register,
+ .s_register = ar0132_s_register,
+ #endif
++ .interrupt_service_routine = ar0132_isr,
+ };
+
+ static int ar0132_s_ctrl(struct v4l2_ctrl *ctrl)
+diff --git a/drivers/media/platform/soc_camera/rcar_vin.c b/drivers/media/platform/soc_camera/rcar_vin.c
+index 50d393b..5239938 100644
+--- a/drivers/media/platform/soc_camera/rcar_vin.c
++++ b/drivers/media/platform/soc_camera/rcar_vin.c
+@@ -1395,13 +1395,24 @@ static const struct vb2_ops rcar_vin_vb2_ops = {
+ .wait_finish = vb2_ops_wait_finish,
+ };
+
++static irqreturn_t rcar_vin_threaded_irq(int irq, void *data)
++{
++ struct rcar_vin_priv *priv = data;
++ struct soc_camera_device *icd = priv->ici.icd;
++ struct v4l2_subdev *sd = soc_camera_to_subdev(icd);
++
++ v4l2_subdev_call(sd, core, interrupt_service_routine, 0, NULL);
++
++ return IRQ_HANDLED;
++};
++
+ static irqreturn_t rcar_vin_irq(int irq, void *data)
+ {
+ struct rcar_vin_priv *priv = data;
+ u32 int_status;
+ bool can_run = false, hw_stopped;
+ int slot;
+- unsigned int handled = 0;
++ unsigned int handled = IRQ_NONE;
+ int vin_ovr_cnt = 0;
+
+ spin_lock(&priv->lock);
+@@ -1412,7 +1423,7 @@ static irqreturn_t rcar_vin_irq(int irq, void *data)
+
+ /* ack interrupts */
+ iowrite32(int_status, priv->base + VNINTS_REG);
+- handled = 1;
++ handled = IRQ_HANDLED;
+
+ /* overflow occurs */
+ if (vin_debug && (int_status & VNINTS_FOS)) {
+@@ -1445,6 +1456,8 @@ static irqreturn_t rcar_vin_irq(int irq, void *data)
+ priv->queue_buf[slot] = NULL;
+
+ can_run = rcar_vin_fill_hw_slot(priv);
++
++ handled = IRQ_WAKE_THREAD;
+ }
+
+ if (is_continuous_transfer(priv)) {
+@@ -1473,7 +1486,7 @@ static irqreturn_t rcar_vin_irq(int irq, void *data)
+ done:
+ spin_unlock(&priv->lock);
+
+- return IRQ_RETVAL(handled);
++ return handled;
+ }
+
+ static struct v4l2_subdev *find_csi2(struct rcar_vin_priv *pcdev)
+@@ -3043,8 +3056,8 @@ static int rcar_vin_probe(struct platform_device *pdev)
+ if (IS_ERR(priv->base))
+ return PTR_ERR(priv->base);
+
+- ret = devm_request_irq(&pdev->dev, irq, rcar_vin_irq, IRQF_SHARED,
+- dev_name(&pdev->dev), priv);
++ ret = devm_request_threaded_irq(&pdev->dev, irq, rcar_vin_irq, rcar_vin_threaded_irq,
++ IRQF_SHARED, dev_name(&pdev->dev), priv);
+ if (ret)
+ return ret;
+
+--
+2.7.4
+
diff --git a/bsp/meta-rcar/meta-rcar-gen3-adas/recipes-kernel/linux/linux-renesas/0131-media-i2c-soc_camera-Bunch-update-from-2.23.1.patch b/bsp/meta-rcar/meta-rcar-gen3-adas/recipes-kernel/linux/linux-renesas/0131-media-i2c-soc_camera-Bunch-update-from-2.23.1.patch
new file mode 100644
index 00000000..881079bf
--- /dev/null
+++ b/bsp/meta-rcar/meta-rcar-gen3-adas/recipes-kernel/linux/linux-renesas/0131-media-i2c-soc_camera-Bunch-update-from-2.23.1.patch
@@ -0,0 +1,13431 @@
+From 6509268d16bf6136907337a5101705449d4b844f Mon Sep 17 00:00:00 2001
+From: Andrey Dolnikov <andrey.dolnikov@cogentembedded.com>
+Date: Wed, 7 Nov 2018 22:42:50 +0300
+Subject: [PATCH 080/122] media: i2c: soc_camera: Bunch update from 2.23.1
+
+---
+ drivers/media/i2c/soc_camera/ap0101_ar014x.c | 78 +-
+ drivers/media/i2c/soc_camera/ar0132.c | 3 +-
+ drivers/media/i2c/soc_camera/ar0132.h | 9 +-
+ drivers/media/i2c/soc_camera/ar0140.c | 648 +++++
+ drivers/media/i2c/soc_camera/ar0140.h | 475 ++++
+ drivers/media/i2c/soc_camera/ar0143.c | 678 +++++
+ drivers/media/i2c/soc_camera/ar0143.h | 549 ++++
+ drivers/media/i2c/soc_camera/ar0220.c | 20 +-
+ drivers/media/i2c/soc_camera/ar0220.h | 18 +-
+ drivers/media/i2c/soc_camera/ar0231.c | 580 ++++
+ drivers/media/i2c/soc_camera/ar0231.h | 34 +
+ drivers/media/i2c/soc_camera/ar0231_rev4.h | 348 +++
+ drivers/media/i2c/soc_camera/ar0233.c | 579 ++++
+ drivers/media/i2c/soc_camera/ar0233.h | 409 +++
+ drivers/media/i2c/soc_camera/gw4200_ar014x.c | 592 ++++
+ drivers/media/i2c/soc_camera/gw4200_ar014x.h | 28 +
+ drivers/media/i2c/soc_camera/imx390.c | 574 ++++
+ drivers/media/i2c/soc_camera/imx390.h | 3818 ++++++++++++++++++++++++++
+ drivers/media/i2c/soc_camera/max9286.c | 406 ++-
+ drivers/media/i2c/soc_camera/max9286.h | 1 +
+ drivers/media/i2c/soc_camera/ov10635.c | 38 +-
+ drivers/media/i2c/soc_camera/ov10635.h | 10 +-
+ drivers/media/i2c/soc_camera/ov106xx.c | 79 +-
+ drivers/media/i2c/soc_camera/ov2775.c | 14 +-
+ drivers/media/i2c/soc_camera/ov2775.h | 32 +-
+ drivers/media/i2c/soc_camera/ov490_ov10640.c | 1 -
+ drivers/media/i2c/soc_camera/ov495_ov2775.c | 16 +-
+ drivers/media/i2c/soc_camera/ox03a.c | 589 ++++
+ drivers/media/i2c/soc_camera/ox03a.h | 1766 ++++++++++++
+ drivers/media/i2c/soc_camera/ti9x4.c | 94 +-
+ 30 files changed, 12305 insertions(+), 181 deletions(-)
+ create mode 100644 drivers/media/i2c/soc_camera/ar0140.c
+ create mode 100644 drivers/media/i2c/soc_camera/ar0140.h
+ create mode 100644 drivers/media/i2c/soc_camera/ar0143.c
+ create mode 100644 drivers/media/i2c/soc_camera/ar0143.h
+ create mode 100644 drivers/media/i2c/soc_camera/ar0231.c
+ create mode 100644 drivers/media/i2c/soc_camera/ar0231.h
+ create mode 100644 drivers/media/i2c/soc_camera/ar0231_rev4.h
+ create mode 100644 drivers/media/i2c/soc_camera/ar0233.c
+ create mode 100644 drivers/media/i2c/soc_camera/ar0233.h
+ create mode 100644 drivers/media/i2c/soc_camera/gw4200_ar014x.c
+ create mode 100644 drivers/media/i2c/soc_camera/gw4200_ar014x.h
+ create mode 100644 drivers/media/i2c/soc_camera/imx390.c
+ create mode 100644 drivers/media/i2c/soc_camera/imx390.h
+ create mode 100644 drivers/media/i2c/soc_camera/ox03a.c
+ create mode 100644 drivers/media/i2c/soc_camera/ox03a.h
+
+diff --git a/drivers/media/i2c/soc_camera/ap0101_ar014x.c b/drivers/media/i2c/soc_camera/ap0101_ar014x.c
+index d8025a4..142942d 100644
+--- a/drivers/media/i2c/soc_camera/ap0101_ar014x.c
++++ b/drivers/media/i2c/soc_camera/ap0101_ar014x.c
+@@ -19,11 +19,10 @@
+ #include <media/soc_camera.h>
+ #include <media/v4l2-common.h>
+ #include <media/v4l2-ctrls.h>
+-#include <media/v4l2-fwnode.h>
+
+ #include "ap0101_ar014x.h"
+
+-#define AP0101_I2C_ADDR 0x5d
++static const int ap0101_i2c_addr[] = {0x5d, 0x48};
+
+ #define AP0101_PID 0x0000
+ #define AP0101_VERSION_REG 0x0160
+@@ -37,6 +36,8 @@ struct ap0101_priv {
+ struct v4l2_ctrl_handler hdl;
+ struct media_pad pad;
+ struct v4l2_rect rect;
++ int max_width;
++ int max_height;
+ int init_complete;
+ u8 id[6];
+ int exposure;
+@@ -48,6 +49,9 @@ struct ap0101_priv {
+ int port;
+ int gpio_resetb;
+ int gpio_fsin;
++ int hts;
++ int vts;
++ int frame_preamble;
+ };
+
+ static inline struct ap0101_priv *to_ap0101(const struct i2c_client *client)
+@@ -207,8 +211,8 @@ static int ap0101_set_selection(struct v4l2_subdev *sd,
+ rect->width = ALIGN(rect->width, 2);
+ rect->height = ALIGN(rect->height, 2);
+
+- if ((rect->left + rect->width > AP0101_MAX_WIDTH) ||
+- (rect->top + rect->height > AP0101_MAX_HEIGHT))
++ if ((rect->left + rect->width > priv->max_width) ||
++ (rect->top + rect->height > priv->max_height))
+ *rect = priv->rect;
+
+ priv->rect.left = rect->left;
+@@ -233,14 +237,14 @@ static int ap0101_get_selection(struct v4l2_subdev *sd,
+ case V4L2_SEL_TGT_CROP_BOUNDS:
+ sel->r.left = 0;
+ sel->r.top = 0;
+- sel->r.width = AP0101_MAX_WIDTH;
+- sel->r.height = AP0101_MAX_HEIGHT;
++ sel->r.width = priv->max_width;
++ sel->r.height = priv->max_height;
+ return 0;
+ case V4L2_SEL_TGT_CROP_DEFAULT:
+ sel->r.left = 0;
+ sel->r.top = 0;
+- sel->r.width = AP0101_MAX_WIDTH;
+- sel->r.height = AP0101_MAX_HEIGHT;
++ sel->r.width = priv->max_width;
++ sel->r.height = priv->max_height;
+ return 0;
+ case V4L2_SEL_TGT_CROP:
+ sel->r = priv->rect;
+@@ -381,11 +385,29 @@ static DEVICE_ATTR(otp_id_ap0101, S_IRUGO, ap0101_otp_id_show, NULL);
+ static int ap0101_initialize(struct i2c_client *client)
+ {
+ struct ap0101_priv *priv = to_ap0101(client);
+- u16 pid = 0;
++ u16 pid = 0, val = 0;
+ int ret = 0;
++ int tmp_addr;
++ int i;
+
+ ap0101_s_port(client, 1);
+
++ for (i = 0; i < ARRAY_SIZE(ap0101_i2c_addr); i++) {
++ tmp_addr = client->addr;
++ if (priv->max9286_addr) {
++ client->addr = priv->max9271_addr; /* Serializer I2C address */
++ reg8_write(client, 0x0A, ap0101_i2c_addr[i] << 1); /* Sensor native I2C address */
++ usleep_range(2000, 2500); /* wait 2ms */
++ };
++ client->addr = tmp_addr;
++
++ /* check model ID */
++ reg16_read16(client, AP0101_PID, &pid);
++
++ if (pid == AP0101_VERSION_REG)
++ break;
++ }
++
+ /* check and show model ID */
+ reg16_read16(client, AP0101_PID, &pid);
+
+@@ -394,14 +416,42 @@ static int ap0101_initialize(struct i2c_client *client)
+ ret = -ENODEV;
+ goto err;
+ }
+-
++#if 1
++ /* read resolution used by current firmware */
++ reg16_read16(client, 0xca90, &val);
++ priv->max_width = val;
++ reg16_read16(client, 0xca92, &val);
++ priv->max_height = val;
++#else
++ priv->max_width = AP0101_MAX_WIDTH;
++ priv->max_height = AP0101_MAX_HEIGHT;
++#endif
+ /* Program wizard registers */
+ ap0101_set_regs(client, ap0101_regs_wizard, ARRAY_SIZE(ap0101_regs_wizard));
+ /* Read OTP IDs */
+ ap0101_otp_id_read(client);
+
++ tmp_addr = client->addr;
++ if (priv->max9271_addr) {
++ /* setup serializer HS generator */
++ client->addr = priv->max9271_addr; /* Serializer I2C address */
++ priv->frame_preamble = 5;
++ priv->hts = 1280 * 2 + 548;
++ priv->vts = 960;
++ reg8_write(client, 0x4e, priv->frame_preamble >> 16); /* HS delay */
++ reg8_write(client, 0x4f, (priv->frame_preamble >> 8) & 0xff);
++ reg8_write(client, 0x50, priv->frame_preamble & 0xff);
++ reg8_write(client, 0x54, (priv->max_width * 2) >> 8); /* HS high period */
++ reg8_write(client, 0x55, (priv->max_width * 2) & 0xff);
++ reg8_write(client, 0x56, (priv->hts - priv->max_width * 2) >> 8); /* HS low period */
++ reg8_write(client, 0x57, (priv->hts - priv->max_width * 2) & 0xff);
++ reg8_write(client, 0x58, priv->vts >> 8); /* HS count */
++ reg8_write(client, 0x59, priv->vts & 0xff);
++ }
++ client->addr = tmp_addr;
++
+ dev_info(&client->dev, "ap0101 PID %x, res %dx%d, OTP_ID %02x:%02x:%02x:%02x:%02x:%02x\n",
+- pid, AP0101_MAX_WIDTH, AP0101_MAX_HEIGHT, priv->id[0], priv->id[1], priv->id[2], priv->id[3], priv->id[4], priv->id[5]);
++ pid, priv->max_width, priv->max_height, priv->id[0], priv->id[1], priv->id[2], priv->id[3], priv->id[4], priv->id[5]);
+ err:
+ ap0101_s_port(client, 0);
+
+@@ -443,9 +493,7 @@ static int ap0101_parse_dt(struct device_node *np, struct ap0101_priv *priv)
+ tmp_addr = client->addr;
+ if (priv->max9286_addr) {
+ client->addr = priv->max9271_addr; /* Serializer I2C address */
+-
+ reg8_write(client, 0x09, tmp_addr << 1); /* Sensor translated I2C address */
+- reg8_write(client, 0x0A, AP0101_I2C_ADDR << 1); /* Sensor native I2C address */
+ usleep_range(2000, 2500); /* wait 2ms */
+ };
+ client->addr = tmp_addr;
+@@ -518,8 +566,8 @@ static int ap0101_probe(struct i2c_client *client,
+
+ priv->rect.left = 0;
+ priv->rect.top = 0;
+- priv->rect.width = AP0101_MAX_WIDTH;
+- priv->rect.height = AP0101_MAX_HEIGHT;
++ priv->rect.width = priv->max_width;
++ priv->rect.height = priv->max_height;
+
+ ret = v4l2_async_register_subdev(&priv->sd);
+ if (ret)
+diff --git a/drivers/media/i2c/soc_camera/ar0132.c b/drivers/media/i2c/soc_camera/ar0132.c
+index 72dfbb4..18bc5dc 100644
+--- a/drivers/media/i2c/soc_camera/ar0132.c
++++ b/drivers/media/i2c/soc_camera/ar0132.c
+@@ -19,7 +19,6 @@
+ #include <media/soc_camera.h>
+ #include <media/v4l2-common.h>
+ #include <media/v4l2-ctrls.h>
+-#include <media/v4l2-fwnode.h>
+
+ #include "ar0132.h"
+
+@@ -29,7 +28,7 @@
+ #define AR0132_PID 0x3000
+ #define AR0132_VERSION_REG 0x2400
+
+-#define AR0132_MEDIA_BUS_FMT MEDIA_BUS_FMT_SBGGR12_1X12
++#define AR0132_MEDIA_BUS_FMT MEDIA_BUS_FMT_SGRBG12_1X12
+
+ struct ar0132_priv {
+ struct v4l2_subdev sd;
+diff --git a/drivers/media/i2c/soc_camera/ar0132.h b/drivers/media/i2c/soc_camera/ar0132.h
+index bafa193..7dfc4e3 100644
+--- a/drivers/media/i2c/soc_camera/ar0132.h
++++ b/drivers/media/i2c/soc_camera/ar0132.h
+@@ -14,16 +14,15 @@
+
+ #define AR0132_EMBEDDED_LINE
+
+-#define AR0132_MAX_WIDTH 1665 // (1110*3/2)
++#define AR0132_MAX_WIDTH 1104
+ #define AR0132_MAX_HEIGHT 624
+
+ #define AR0132_DELAY 0xffff
+
+ #define AR0132_MAX_ROI_DIM_X 1288
+ #define AR0132_MAX_ROI_DIM_Y 968
+-#define AR0132_InfoLines 4
+
+-#define AR0132_ROI_DIM_X 1110 // 1104
++#define AR0132_ROI_DIM_X 1104
+ #define AR0132_ROI_DIM_Y 620 // AR0132_MAX_HEIGHT
+
+ #define AR0132_ROI_Y_START 0x00AE
+@@ -57,11 +56,11 @@ static const struct ar0132_reg ar0132_regs_wizard[] = {
+ //256: Walking 1 test pattern (12 bit)
+ #ifdef AR0132_DISPLAY_PATTERN_FIXED
+ {0x3070, 0x0001},
++#endif
+ {0x3072, 0x0123}, // R
+ {0x3074, 0x0456}, // G(GR row)
+ {0x3076, 0x0abc}, // B
+ {0x3078, 0x0def}, // G(GB row)
+-#endif
+ #ifdef AR0132_DISPLAY_PATTERN_COLOR_BAR
+ {0x3070, 0x0002},
+ #endif
+@@ -150,7 +149,7 @@ static const struct ar0132_reg ar0132_regs_wizard[] = {
+ {0x302E, AR0132_PLL_Pre_Clk_Div},
+ {0x3030, AR0132_PLL_Multiplier},
+ {0x3032, 0x0000}, // SCALING_MODE = 0
+-{0x3040, 0xC000}, // READ_MODE = read_mode_vert_flip | read_mode_horiz_mirror
++{0x3040, 0x0000}, // READ_MODE = read_mode_vert_flip | read_mode_horiz_mirror
+ {0x3044, 0x0404}, // Dark Control = 1028
+ {0x30A6, 0x0001}, // Y Odd Inc. (A) = 1
+ {0x30A8, 0x0001}, // Y Odd Inc. (B) = 1
+diff --git a/drivers/media/i2c/soc_camera/ar0140.c b/drivers/media/i2c/soc_camera/ar0140.c
+new file mode 100644
+index 0000000..807b6f8
+--- /dev/null
++++ b/drivers/media/i2c/soc_camera/ar0140.c
+@@ -0,0 +1,648 @@
++/*
++ * ON Semiconductor AR0140 sensor camera driver
++ *
++ * Copyright (C) 2018 Cogent Embedded, Inc.
++ *
++ * This program is free software; you can redistribute it and/or modify it
++ * under the terms of the GNU General Public License as published by the
++ * Free Software Foundation; either version 2 of the License, or (at your
++ * option) any later version.
++ */
++
++#include <linux/delay.h>
++#include <linux/init.h>
++#include <linux/i2c.h>
++#include <linux/module.h>
++#include <linux/of_graph.h>
++#include <linux/videodev2.h>
++
++#include <media/soc_camera.h>
++#include <media/v4l2-common.h>
++#include <media/v4l2-ctrls.h>
++
++#include "ar0140.h"
++
++#define AR0140_I2C_ADDR 0x10
++
++#define AR0140_PID 0x3000
++#define AR0140_VERSION_REG 0x0051
++
++#define AR0140_MEDIA_BUS_FMT MEDIA_BUS_FMT_SGRBG12_1X12
++
++struct ar0140_priv {
++ struct v4l2_subdev sd;
++ struct v4l2_ctrl_handler hdl;
++ struct media_pad pad;
++ struct v4l2_rect rect;
++ int init_complete;
++ u8 id[6];
++ /* serializers */
++ int max9286_addr;
++ int max9271_addr;
++ int ti9x4_addr;
++ int ti9x3_addr;
++ int port;
++ int gpio_resetb;
++ int gpio_fsin;
++ int hts;
++ int vts;
++ int frame_preamble;
++};
++
++static inline struct ar0140_priv *to_ar0140(const struct i2c_client *client)
++{
++ return container_of(i2c_get_clientdata(client), struct ar0140_priv, sd);
++}
++
++static void ar0140_s_port(struct i2c_client *client, int fwd_en)
++{
++ struct ar0140_priv *priv = to_ar0140(client);
++ int tmp_addr;
++
++ if (priv->max9286_addr) {
++ tmp_addr = client->addr;
++ client->addr = priv->max9286_addr; /* Deserializer I2C address */
++ reg8_write(client, 0x0a, fwd_en ? 0x11 << priv->port : 0); /* Enable/disable reverse/forward control for this port */
++ usleep_range(5000, 5500); /* wait 5ms */
++ client->addr = tmp_addr;
++ };
++}
++
++static int ar0140_set_regs(struct i2c_client *client,
++ const struct ar0140_reg *regs, int nr_regs)
++{
++ struct ar0140_priv *priv = to_ar0140(client);
++ int i;
++
++ for (i = 0; i < nr_regs; i++) {
++ if (regs[i].reg == AR0140_DELAY) {
++ mdelay(regs[i].val);
++ continue;
++ }
++ /* cache timings */
++ if (regs[i].reg == 0x300a)
++ priv->vts = regs[i].val;
++ if (regs[i].reg == 0x300c)
++ priv->hts = regs[i].val;
++ if (regs[i].reg == 0x31b0)
++ priv->frame_preamble = regs[i].val - 1;
++
++ reg16_write16(client, regs[i].reg, regs[i].val);
++ }
++
++ return 0;
++}
++
++static int ar0140_s_stream(struct v4l2_subdev *sd, int enable)
++{
++ return 0;
++}
++
++static int ar0140_set_window(struct v4l2_subdev *sd)
++{
++ struct i2c_client *client = v4l2_get_subdevdata(sd);
++ struct ar0140_priv *priv = to_ar0140(client);
++
++ dev_dbg(&client->dev, "L=%d T=%d %dx%d\n", priv->rect.left, priv->rect.top, priv->rect.width, priv->rect.height);
++
++ /* horiz crop start */
++ reg16_write16(client, 0x3004, priv->rect.left);
++ /* horiz crop end */
++ reg16_write16(client, 0x3008, priv->rect.left + priv->rect.width - 1);
++ /* vert crop start */
++ reg16_write16(client, 0x3002, priv->rect.top);
++ /* vert crop end */
++ reg16_write16(client, 0x3006, priv->rect.top + priv->rect.height + 1);
++
++ return 0;
++};
++
++static int ar0140_get_fmt(struct v4l2_subdev *sd,
++ struct v4l2_subdev_pad_config *cfg,
++ struct v4l2_subdev_format *format)
++{
++ struct v4l2_mbus_framefmt *mf = &format->format;
++ struct i2c_client *client = v4l2_get_subdevdata(sd);
++ struct ar0140_priv *priv = to_ar0140(client);
++
++ if (format->pad)
++ return -EINVAL;
++
++ mf->width = priv->rect.width;
++ mf->height = priv->rect.height;
++ mf->code = AR0140_MEDIA_BUS_FMT;
++ mf->colorspace = V4L2_COLORSPACE_SMPTE170M;
++ mf->field = V4L2_FIELD_NONE;
++
++ return 0;
++}
++
++static int ar0140_set_fmt(struct v4l2_subdev *sd,
++ struct v4l2_subdev_pad_config *cfg,
++ struct v4l2_subdev_format *format)
++{
++ struct v4l2_mbus_framefmt *mf = &format->format;
++
++ mf->code = AR0140_MEDIA_BUS_FMT;
++ mf->colorspace = V4L2_COLORSPACE_SMPTE170M;
++ mf->field = V4L2_FIELD_NONE;
++
++ if (format->which == V4L2_SUBDEV_FORMAT_TRY)
++ cfg->try_fmt = *mf;
++
++ return 0;
++}
++
++static int ar0140_enum_mbus_code(struct v4l2_subdev *sd,
++ struct v4l2_subdev_pad_config *cfg,
++ struct v4l2_subdev_mbus_code_enum *code)
++{
++ if (code->pad || code->index > 0)
++ return -EINVAL;
++
++ code->code = AR0140_MEDIA_BUS_FMT;
++
++ return 0;
++}
++
++static int ar0140_get_edid(struct v4l2_subdev *sd, struct v4l2_edid *edid)
++{
++ struct i2c_client *client = v4l2_get_subdevdata(sd);
++ struct ar0140_priv *priv = to_ar0140(client);
++
++ memcpy(edid->edid, priv->id, 6);
++
++ edid->edid[6] = 0xff;
++ edid->edid[7] = client->addr;
++ edid->edid[8] = AR0140_VERSION_REG >> 8;
++ edid->edid[9] = AR0140_VERSION_REG & 0xff;
++
++ return 0;
++}
++
++static int ar0140_set_selection(struct v4l2_subdev *sd,
++ struct v4l2_subdev_pad_config *cfg,
++ struct v4l2_subdev_selection *sel)
++{
++ struct v4l2_rect *rect = &sel->r;
++ struct i2c_client *client = v4l2_get_subdevdata(sd);
++ struct ar0140_priv *priv = to_ar0140(client);
++
++ if (sel->which != V4L2_SUBDEV_FORMAT_ACTIVE ||
++ sel->target != V4L2_SEL_TGT_CROP)
++ return -EINVAL;
++
++ rect->left = ALIGN(rect->left, 2);
++ rect->top = ALIGN(rect->top, 2);
++ rect->width = ALIGN(rect->width, 2);
++ rect->height = ALIGN(rect->height, 2);
++
++ if ((rect->left + rect->width > AR0140_MAX_WIDTH) ||
++ (rect->top + rect->height > AR0140_MAX_HEIGHT))
++ *rect = priv->rect;
++
++ priv->rect.left = rect->left;
++ priv->rect.top = rect->top;
++ priv->rect.width = rect->width;
++ priv->rect.height = rect->height;
++
++ ar0140_set_window(sd);
++
++ return 0;
++}
++
++static int ar0140_get_selection(struct v4l2_subdev *sd,
++ struct v4l2_subdev_pad_config *cfg,
++ struct v4l2_subdev_selection *sel)
++{
++ struct i2c_client *client = v4l2_get_subdevdata(sd);
++ struct ar0140_priv *priv = to_ar0140(client);
++
++ if (sel->which != V4L2_SUBDEV_FORMAT_ACTIVE)
++ return -EINVAL;
++
++ switch (sel->target) {
++ case V4L2_SEL_TGT_CROP_BOUNDS:
++ sel->r.left = 0;
++ sel->r.top = 0;
++ sel->r.width = AR0140_MAX_WIDTH;
++ sel->r.height = AR0140_MAX_HEIGHT;
++ return 0;
++ case V4L2_SEL_TGT_CROP_DEFAULT:
++ sel->r.left = 0;
++ sel->r.top = 0;
++ sel->r.width = AR0140_MAX_WIDTH;
++ sel->r.height = AR0140_MAX_HEIGHT;
++ return 0;
++ case V4L2_SEL_TGT_CROP:
++ sel->r = priv->rect;
++ return 0;
++ default:
++ return -EINVAL;
++ }
++}
++
++static int ar0140_g_mbus_config(struct v4l2_subdev *sd,
++ struct v4l2_mbus_config *cfg)
++{
++ cfg->flags = V4L2_MBUS_CSI2_1_LANE | V4L2_MBUS_CSI2_CHANNEL_0 |
++ V4L2_MBUS_CSI2_CONTINUOUS_CLOCK;
++ cfg->type = V4L2_MBUS_CSI2;
++
++ return 0;
++}
++
++#ifdef CONFIG_VIDEO_ADV_DEBUG
++static int ar0140_g_register(struct v4l2_subdev *sd,
++ struct v4l2_dbg_register *reg)
++{
++ struct i2c_client *client = v4l2_get_subdevdata(sd);
++ int ret;
++ u16 val = 0;
++
++ ret = reg16_read16(client, (u16)reg->reg, &val);
++ if (ret < 0)
++ return ret;
++
++ reg->val = val;
++ reg->size = sizeof(u16);
++
++ return 0;
++}
++
++static int ar0140_s_register(struct v4l2_subdev *sd,
++ const struct v4l2_dbg_register *reg)
++{
++ struct i2c_client *client = v4l2_get_subdevdata(sd);
++
++ return reg16_write16(client, (u16)reg->reg, (u16)reg->val);
++}
++#endif
++
++static struct v4l2_subdev_core_ops ar0140_core_ops = {
++#ifdef CONFIG_VIDEO_ADV_DEBUG
++ .g_register = ar0140_g_register,
++ .s_register = ar0140_s_register,
++#endif
++};
++
++static int ar0140_s_ctrl(struct v4l2_ctrl *ctrl)
++{
++ struct v4l2_subdev *sd = to_sd(ctrl);
++ struct i2c_client *client = v4l2_get_subdevdata(sd);
++ struct ar0140_priv *priv = to_ar0140(client);
++ int ret = -EINVAL;
++ u16 val = 0;
++
++ if (!priv->init_complete)
++ return 0;
++
++ switch (ctrl->id) {
++ case V4L2_CID_BRIGHTNESS:
++ case V4L2_CID_CONTRAST:
++ case V4L2_CID_SATURATION:
++ case V4L2_CID_HUE:
++ case V4L2_CID_GAMMA:
++ case V4L2_CID_SHARPNESS:
++ case V4L2_CID_AUTOGAIN:
++ break;
++ case V4L2_CID_GAIN:
++ /* Digital gain */
++ ret = reg16_write16(client, 0x305e, ctrl->val);
++ break;
++ case V4L2_CID_ANALOGUE_GAIN:
++ /* Analog gain */
++ ret = reg16_write16(client, 0x3060, ctrl->val);
++ break;
++ case V4L2_CID_EXPOSURE:
++ /* T1 exposure */
++ ret = reg16_write16(client, 0x3012, ctrl->val);
++ break;
++ case V4L2_CID_HFLIP:
++ ret = reg16_read16(client, 0x3040, &val);
++ if (ctrl->val)
++ val |= 0x4000;
++ else
++ val &= ~0x4000;
++ ret |= reg16_write16(client, 0x3040, val);
++ break;
++ case V4L2_CID_VFLIP:
++ ret = reg16_read16(client, 0x3040, &val);
++ if (ctrl->val)
++ val |= 0x8000;
++ else
++ val &= ~0x8000;
++ ret |= reg16_write16(client, 0x3040, val);
++ break;
++ case V4L2_CID_MIN_BUFFERS_FOR_CAPTURE:
++ ret = 0;
++ break;
++ }
++
++ return ret;
++}
++
++static const struct v4l2_ctrl_ops ar0140_ctrl_ops = {
++ .s_ctrl = ar0140_s_ctrl,
++};
++
++static struct v4l2_subdev_video_ops ar0140_video_ops = {
++ .s_stream = ar0140_s_stream,
++ .g_mbus_config = ar0140_g_mbus_config,
++};
++
++static const struct v4l2_subdev_pad_ops ar0140_subdev_pad_ops = {
++ .get_edid = ar0140_get_edid,
++ .enum_mbus_code = ar0140_enum_mbus_code,
++ .get_selection = ar0140_get_selection,
++ .set_selection = ar0140_set_selection,
++ .get_fmt = ar0140_get_fmt,
++ .set_fmt = ar0140_set_fmt,
++};
++
++static struct v4l2_subdev_ops ar0140_subdev_ops = {
++ .core = &ar0140_core_ops,
++ .video = &ar0140_video_ops,
++ .pad = &ar0140_subdev_pad_ops,
++};
++
++static void ar0140_otp_id_read(struct i2c_client *client)
++{
++ struct ar0140_priv *priv = to_ar0140(client);
++ int i;
++ u16 val = 0;
++
++ /* read camera id from ar014x OTP memory */
++ reg16_write16(client, 0x3054, 0x400);
++ reg16_write16(client, 0x304a, 0x110);
++ usleep_range(25000, 25500); /* wait 25 ms */
++
++ for (i = 0; i < 6; i += 2) {
++ /* first 4 bytes are equal on all ar014x */
++ reg16_read16(client, 0x3800 + i + 4, &val);
++ priv->id[i] = val >> 8;
++ priv->id[i + 1] = val & 0xff;
++ }
++}
++
++static ssize_t ar0140_otp_id_show(struct device *dev,
++ struct device_attribute *attr, char *buf)
++{
++ struct v4l2_subdev *sd = i2c_get_clientdata(to_i2c_client(dev));
++ struct i2c_client *client = v4l2_get_subdevdata(sd);
++ struct ar0140_priv *priv = to_ar0140(client);
++
++ ar0140_otp_id_read(client);
++
++ return snprintf(buf, 32, "%02x:%02x:%02x:%02x:%02x:%02x\n",
++ priv->id[0], priv->id[1], priv->id[2], priv->id[3], priv->id[4], priv->id[5]);
++}
++
++static DEVICE_ATTR(otp_id_ar0140, S_IRUGO, ar0140_otp_id_show, NULL);
++
++static int ar0140_initialize(struct i2c_client *client)
++{
++ struct ar0140_priv *priv = to_ar0140(client);
++ u16 val = 0;
++ u16 pid = 0;
++ int ret = 0;
++ int tmp_addr;
++
++ ar0140_s_port(client, 1);
++
++ /* check and show model ID */
++ reg16_read16(client, AR0140_PID, &pid);
++
++ if (pid != AR0140_VERSION_REG) {
++ dev_dbg(&client->dev, "Product ID error %x\n", pid);
++ ret = -ENODEV;
++ goto err;
++ }
++
++ tmp_addr = client->addr;
++ if (priv->max9271_addr) {
++ /* setup serializer HS generator */
++ client->addr = priv->max9271_addr; /* Serializer I2C address */
++ reg8_write(client, 0x4e, priv->frame_preamble >> 16); /* HS delay */
++ reg8_write(client, 0x4f, (priv->frame_preamble >> 8) & 0xff);
++ reg8_write(client, 0x50, priv->frame_preamble & 0xff);
++ reg8_write(client, 0x54, AR0140_MAX_WIDTH >> 8); /* HS high period */
++ reg8_write(client, 0x55, AR0140_MAX_WIDTH & 0xff);
++ reg8_write(client, 0x56, (priv->hts - AR0140_MAX_WIDTH) >> 8); /* HS low period */
++ reg8_write(client, 0x57, (priv->hts - AR0140_MAX_WIDTH) & 0xff);
++ reg8_write(client, 0x58, priv->vts >> 8); /* HS count */
++ reg8_write(client, 0x59, priv->vts & 0xff);
++ }
++ client->addr = tmp_addr;
++
++ /* Read OTP IDs */
++ ar0140_otp_id_read(client);
++ /* Program wizard registers */
++ ar0140_set_regs(client, ar0140_regs_wizard, ARRAY_SIZE(ar0140_regs_wizard));
++ /* Enable stream */
++ reg16_read16(client, 0x301a, &val); // read inital reset_register value
++ val |= (1 << 2); // Set streamOn bit
++ reg16_write16(client, 0x301a, val); // Start Streaming
++
++ dev_info(&client->dev, "ar0140 PID %x, res %dx%d, OTP_ID %02x:%02x:%02x:%02x:%02x:%02x\n",
++ pid, AR0140_MAX_WIDTH, AR0140_MAX_HEIGHT, priv->id[0], priv->id[1], priv->id[2], priv->id[3], priv->id[4], priv->id[5]);
++err:
++ ar0140_s_port(client, 0);
++
++ return ret;
++}
++
++static int ar0140_parse_dt(struct device_node *np, struct ar0140_priv *priv)
++{
++ struct i2c_client *client = v4l2_get_subdevdata(&priv->sd);
++ int i;
++ struct device_node *endpoint = NULL, *rendpoint = NULL;
++ int tmp_addr = 0;
++
++ for (i = 0; ; i++) {
++ endpoint = of_graph_get_next_endpoint(np, endpoint);
++ if (!endpoint)
++ break;
++
++ rendpoint = of_parse_phandle(endpoint, "remote-endpoint", 0);
++ if (!rendpoint)
++ continue;
++
++ if (!of_property_read_u32(rendpoint, "max9271-addr", &priv->max9271_addr) &&
++ !of_property_read_u32(rendpoint->parent->parent, "reg", &priv->max9286_addr) &&
++ !kstrtouint(strrchr(rendpoint->full_name, '@') + 1, 0, &priv->port))
++ break;
++
++ if (!of_property_read_u32(rendpoint, "ti9x3-addr", &priv->ti9x3_addr) &&
++ !of_property_match_string(rendpoint->parent->parent, "compatible", "ti,ti9x4") &&
++ !of_property_read_u32(rendpoint->parent->parent, "reg", &priv->ti9x4_addr) &&
++ !kstrtouint(strrchr(rendpoint->full_name, '@') + 1, 0, &priv->port))
++ break;
++ }
++
++ of_node_put(endpoint);
++
++ if (!priv->max9286_addr && !priv->ti9x4_addr) {
++ dev_err(&client->dev, "deserializer does not present for AR0140\n");
++ return -EINVAL;
++ }
++
++ ar0140_s_port(client, 1);
++
++ /* setup I2C translator address */
++ tmp_addr = client->addr;
++ if (priv->max9286_addr) {
++ client->addr = priv->max9271_addr; /* Serializer I2C address */
++
++ reg8_write(client, 0x09, tmp_addr << 1); /* Sensor translated I2C address */
++ reg8_write(client, 0x0A, AR0140_I2C_ADDR << 1); /* Sensor native I2C address */
++ usleep_range(2000, 2500); /* wait 2ms */
++ };
++ if (priv->ti9x4_addr) {
++ client->addr = priv->ti9x4_addr; /* Deserializer I2C address */
++
++ reg8_write(client, 0x4c, (priv->port << 4) | (1 << priv->port)); /* Select RX port number */
++ usleep_range(2000, 2500); /* wait 2ms */
++ reg8_write(client, 0x65, tmp_addr << 1); /* Sensor translated I2C address */
++ reg8_write(client, 0x5d, AR0140_I2C_ADDR << 1); /* Sensor native I2C address */
++
++ reg8_write(client, 0x6e, 0x9a); /* GPIO0 - fsin, GPIO1 - reset */
++ }
++ client->addr = tmp_addr;
++
++ mdelay(10);
++
++ return 0;
++}
++
++static int ar0140_probe(struct i2c_client *client,
++ const struct i2c_device_id *did)
++{
++ struct ar0140_priv *priv;
++ int ret;
++
++ priv = devm_kzalloc(&client->dev, sizeof(*priv), GFP_KERNEL);
++ if (!priv)
++ return -ENOMEM;
++
++ v4l2_i2c_subdev_init(&priv->sd, client, &ar0140_subdev_ops);
++ priv->sd.flags = V4L2_SUBDEV_FL_HAS_DEVNODE;
++
++ v4l2_ctrl_handler_init(&priv->hdl, 4);
++ v4l2_ctrl_new_std(&priv->hdl, &ar0140_ctrl_ops,
++ V4L2_CID_BRIGHTNESS, 0, 16, 1, 7);
++ v4l2_ctrl_new_std(&priv->hdl, &ar0140_ctrl_ops,
++ V4L2_CID_CONTRAST, 0, 16, 1, 7);
++ v4l2_ctrl_new_std(&priv->hdl, &ar0140_ctrl_ops,
++ V4L2_CID_SATURATION, 0, 7, 1, 2);
++ v4l2_ctrl_new_std(&priv->hdl, &ar0140_ctrl_ops,
++ V4L2_CID_HUE, 0, 23, 1, 12);
++ v4l2_ctrl_new_std(&priv->hdl, &ar0140_ctrl_ops,
++ V4L2_CID_GAMMA, -128, 128, 1, 0);
++ v4l2_ctrl_new_std(&priv->hdl, &ar0140_ctrl_ops,
++ V4L2_CID_SHARPNESS, 0, 10, 1, 3);
++ v4l2_ctrl_new_std(&priv->hdl, &ar0140_ctrl_ops,
++ V4L2_CID_AUTOGAIN, 0, 1, 1, 0);
++ v4l2_ctrl_new_std(&priv->hdl, &ar0140_ctrl_ops,
++ V4L2_CID_GAIN, 1, 0x7ff, 1, 0x80);
++ v4l2_ctrl_new_std(&priv->hdl, &ar0140_ctrl_ops,
++ V4L2_CID_ANALOGUE_GAIN, 1, 0x7ff, 1, 0x1);
++ v4l2_ctrl_new_std(&priv->hdl, &ar0140_ctrl_ops,
++ V4L2_CID_EXPOSURE, 1, 0x400, 1, 0x206);
++ v4l2_ctrl_new_std(&priv->hdl, &ar0140_ctrl_ops,
++ V4L2_CID_HFLIP, 0, 1, 1, 0);
++ v4l2_ctrl_new_std(&priv->hdl, &ar0140_ctrl_ops,
++ V4L2_CID_VFLIP, 0, 1, 1, 0);
++ priv->sd.ctrl_handler = &priv->hdl;
++
++ ret = priv->hdl.error;
++ if (ret)
++ goto cleanup;
++
++ v4l2_ctrl_handler_setup(&priv->hdl);
++
++ priv->pad.flags = MEDIA_PAD_FL_SOURCE;
++ priv->sd.entity.flags |= MEDIA_ENT_F_CAM_SENSOR;
++ ret = media_entity_pads_init(&priv->sd.entity, 1, &priv->pad);
++ if (ret < 0)
++ goto cleanup;
++
++ ret = ar0140_parse_dt(client->dev.of_node, priv);
++ if (ret)
++ goto cleanup;
++
++ ret = ar0140_initialize(client);
++ if (ret < 0)
++ goto cleanup;
++
++ priv->rect.left = 0;
++ priv->rect.top = 0;
++ priv->rect.width = AR0140_MAX_WIDTH;
++ priv->rect.height = AR0140_MAX_HEIGHT;
++
++ ret = v4l2_async_register_subdev(&priv->sd);
++ if (ret)
++ goto cleanup;
++
++ if (device_create_file(&client->dev, &dev_attr_otp_id_ar0140) != 0) {
++ dev_err(&client->dev, "sysfs otp_id entry creation failed\n");
++ goto cleanup;
++ }
++
++ priv->init_complete = 1;
++
++ return 0;
++
++cleanup:
++ media_entity_cleanup(&priv->sd.entity);
++ v4l2_ctrl_handler_free(&priv->hdl);
++ v4l2_device_unregister_subdev(&priv->sd);
++#ifdef CONFIG_SOC_CAMERA_AR0140
++ v4l_err(client, "failed to probe @ 0x%02x (%s)\n",
++ client->addr, client->adapter->name);
++#endif
++ return ret;
++}
++
++static int ar0140_remove(struct i2c_client *client)
++{
++ struct ar0140_priv *priv = i2c_get_clientdata(client);
++
++ device_remove_file(&client->dev, &dev_attr_otp_id_ar0140);
++ v4l2_async_unregister_subdev(&priv->sd);
++ media_entity_cleanup(&priv->sd.entity);
++ v4l2_ctrl_handler_free(&priv->hdl);
++ v4l2_device_unregister_subdev(&priv->sd);
++
++ return 0;
++}
++
++#ifdef CONFIG_SOC_CAMERA_AR0140
++static const struct i2c_device_id ar0140_id[] = {
++ { "ar0140", 0 },
++ { }
++};
++MODULE_DEVICE_TABLE(i2c, ar0140_id);
++
++static const struct of_device_id ar0140_of_ids[] = {
++ { .compatible = "aptina,ar0140", },
++ { }
++};
++MODULE_DEVICE_TABLE(of, ar0140_of_ids);
++
++static struct i2c_driver ar0140_i2c_driver = {
++ .driver = {
++ .name = "ar0140",
++ .of_match_table = ar0140_of_ids,
++ },
++ .probe = ar0140_probe,
++ .remove = ar0140_remove,
++ .id_table = ar0140_id,
++};
++
++module_i2c_driver(ar0140_i2c_driver);
++
++MODULE_DESCRIPTION("SoC Camera driver for AR0140");
++MODULE_AUTHOR("Vladimir Barinov");
++MODULE_LICENSE("GPL");
++#endif
+diff --git a/drivers/media/i2c/soc_camera/ar0140.h b/drivers/media/i2c/soc_camera/ar0140.h
+new file mode 100644
+index 0000000..f90762c
+--- /dev/null
++++ b/drivers/media/i2c/soc_camera/ar0140.h
+@@ -0,0 +1,475 @@
++/*
++ * ON Semiconductor AR0140 sensor camera wizard 1344x968@30/BGGR/BT601/RAW12
++ *
++ * Copyright (C) 2018 Cogent Embedded, Inc.
++ *
++ * This program is free software; you can redistribute it and/or modify it
++ * under the terms of the GNU General Public License as published by the
++ * Free Software Foundation; either version 2 of the License, or (at your
++ * option) any later version.
++ */
++
++//#define AR0140_DISPLAY_PATTERN_FIXED
++//#define AR0140_DISPLAY_PATTERN_COLOR_BAR
++
++//#define AR0140_EMBEDDED_LINE
++
++#define AR0140_MAX_WIDTH 1280
++#define AR0140_MAX_HEIGHT 800
++
++#define AR0140_DELAY 0xffff
++
++#define AR0140_SENSOR_WIDTH 1280
++#define AR0140_SENSOR_HEIGHT 800
++
++#define AR0140_X_START ((AR0140_SENSOR_WIDTH - AR0140_MAX_WIDTH) / 2)
++#define AR0140_Y_START ((AR0140_SENSOR_HEIGHT - AR0140_MAX_HEIGHT) / 2)
++#define AR0140_X_END (AR0140_X_START + AR0140_MAX_WIDTH - 1)
++#define AR0140_Y_END (AR0140_Y_START + AR0140_MAX_HEIGHT + 1) /* must be +1 and not -1 or 2 lines missed - bug in imager? */
++
++struct ar0140_reg {
++ u16 reg;
++ u16 val;
++};
++
++static const struct ar0140_reg ar0140_regs_wizard[] = {
++{0x301A, 0x0001}, // reset
++{AR0140_DELAY, 100},
++{0x301A, 0x10D8}, // Stream off and setup parallel
++{0x3070, 0x0001},
++{0x3070, 0x0000}, // 1: Solid color test pattern,
++ // 2: Full color bar test pattern,
++ // 3: Fade to grey color bar test pattern,
++ //256: Walking 1 test pattern (12 bit)
++#ifdef AR0140_DISPLAY_PATTERN_FIXED
++{0x3070, 0x0001},
++#endif
++{0x3072, 0x0fff}, // R
++{0x3074, 0x0fff}, // G(GR row)
++{0x3076, 0x0fff}, // B
++{0x3078, 0x0fff}, // G(GB row)
++#ifdef AR0140_DISPLAY_PATTERN_COLOR_BAR
++{0x3070, 0x0002},
++#endif
++{AR0140_DELAY, 250},
++/* SEQ_CTRL_PORT */
++{0x3088, 0x8000},
++/* SEQ_DATA_PORT */
++{0x3086, 0x4558},
++{0x3086, 0x6E9B},
++{0x3086, 0x4A31},
++{0x3086, 0x4342},
++{0x3086, 0x8E03},
++{0x3086, 0x2714},
++{0x3086, 0x4578},
++{0x3086, 0x7B3D},
++{0x3086, 0xFF3D},
++{0x3086, 0xFF3D},
++{0x3086, 0xEA27},
++{0x3086, 0x043D},
++{0x3086, 0x1027},
++{0x3086, 0x0527},
++{0x3086, 0x1535},
++{0x3086, 0x2705},
++{0x3086, 0x3D10},
++{0x3086, 0x4558},
++{0x3086, 0x2704},
++{0x3086, 0x2714},
++{0x3086, 0x3DFF},
++{0x3086, 0x3DFF},
++{0x3086, 0x3DEA},
++{0x3086, 0x2704},
++{0x3086, 0x6227},
++{0x3086, 0x288E},
++{0x3086, 0x0036},
++{0x3086, 0x2708},
++{0x3086, 0x3D64},
++{0x3086, 0x7A3D},
++{0x3086, 0x0444},
++{0x3086, 0x2C4B},
++{0x3086, 0x8F00},
++{0x3086, 0x4372},
++{0x3086, 0x719F},
++{0x3086, 0x6343},
++{0x3086, 0x166F},
++{0x3086, 0x9F92},
++{0x3086, 0x1244},
++{0x3086, 0x1663},
++{0x3086, 0x4316},
++{0x3086, 0x9326},
++{0x3086, 0x0426},
++{0x3086, 0x848E},
++{0x3086, 0x0327},
++{0x3086, 0xFC5C},
++{0x3086, 0x0D57},
++{0x3086, 0x5417},
++{0x3086, 0x0955},
++{0x3086, 0x5649},
++{0x3086, 0x5F53},
++{0x3086, 0x0553},
++{0x3086, 0x0728},
++{0x3086, 0x6C4C},
++{0x3086, 0x0928},
++{0x3086, 0x2C72},
++{0x3086, 0xAD7C},
++{0x3086, 0xA928},
++{0x3086, 0xA879},
++{0x3086, 0x6026},
++{0x3086, 0x9C5C},
++{0x3086, 0x1B45},
++{0x3086, 0x4845},
++{0x3086, 0x0845},
++{0x3086, 0x8826},
++{0x3086, 0xBE8E},
++{0x3086, 0x0127},
++{0x3086, 0xF817},
++{0x3086, 0x0227},
++{0x3086, 0xFA17},
++{0x3086, 0x095C},
++{0x3086, 0x0B17},
++{0x3086, 0x1026},
++{0x3086, 0xBA5C},
++{0x3086, 0x0317},
++{0x3086, 0x1026},
++{0x3086, 0xB217},
++{0x3086, 0x065F},
++{0x3086, 0x2888},
++{0x3086, 0x9060},
++{0x3086, 0x27F2},
++{0x3086, 0x1710},
++{0x3086, 0x26A2},
++{0x3086, 0x26A3},
++{0x3086, 0x5F4D},
++{0x3086, 0x2808},
++{0x3086, 0x1927},
++{0x3086, 0xFA84},
++{0x3086, 0x69A0},
++{0x3086, 0x785D},
++{0x3086, 0x2888},
++{0x3086, 0x8710},
++{0x3086, 0x8C82},
++{0x3086, 0x8926},
++{0x3086, 0xB217},
++{0x3086, 0x036B},
++{0x3086, 0x9C60},
++{0x3086, 0x9417},
++{0x3086, 0x2926},
++{0x3086, 0x8345},
++{0x3086, 0xA817},
++{0x3086, 0x0727},
++{0x3086, 0xFB17},
++{0x3086, 0x2945},
++{0x3086, 0x881F},
++{0x3086, 0x1708},
++{0x3086, 0x27FA},
++{0x3086, 0x5D87},
++{0x3086, 0x108C},
++{0x3086, 0x8289},
++{0x3086, 0x170E},
++{0x3086, 0x4826},
++{0x3086, 0x9A28},
++{0x3086, 0x884C},
++{0x3086, 0x0B79},
++{0x3086, 0x1730},
++{0x3086, 0x2692},
++{0x3086, 0x1709},
++{0x3086, 0x9160},
++{0x3086, 0x27F2},
++{0x3086, 0x1710},
++{0x3086, 0x2682},
++{0x3086, 0x2683},
++{0x3086, 0x5F4D},
++{0x3086, 0x2808},
++{0x3086, 0x1927},
++{0x3086, 0xFA84},
++{0x3086, 0x69A1},
++{0x3086, 0x785D},
++{0x3086, 0x2888},
++{0x3086, 0x8710},
++{0x3086, 0x8C80},
++{0x3086, 0x8A26},
++{0x3086, 0x9217},
++{0x3086, 0x036B},
++{0x3086, 0x9D95},
++{0x3086, 0x2603},
++{0x3086, 0x5C01},
++{0x3086, 0x4558},
++{0x3086, 0x8E00},
++{0x3086, 0x2798},
++{0x3086, 0x170A},
++{0x3086, 0x4A65},
++{0x3086, 0x4316},
++{0x3086, 0x6643},
++{0x3086, 0x165B},
++{0x3086, 0x4316},
++{0x3086, 0x5943},
++{0x3086, 0x168E},
++{0x3086, 0x0327},
++{0x3086, 0x9C45},
++{0x3086, 0x7817},
++{0x3086, 0x0727},
++{0x3086, 0x9D17},
++{0x3086, 0x225D},
++{0x3086, 0x8710},
++{0x3086, 0x2808},
++{0x3086, 0x530D},
++{0x3086, 0x8C80},
++{0x3086, 0x8A45},
++{0x3086, 0x5823},
++{0x3086, 0x1708},
++{0x3086, 0x8E01},
++{0x3086, 0x2798},
++{0x3086, 0x8E00},
++{0x3086, 0x2644},
++{0x3086, 0x5C05},
++{0x3086, 0x1244},
++{0x3086, 0x4B71},
++{0x3086, 0x759E},
++{0x3086, 0x8B85},
++{0x3086, 0x0143},
++{0x3086, 0x7271},
++{0x3086, 0xA346},
++{0x3086, 0x4316},
++{0x3086, 0x6FA3},
++{0x3086, 0x9612},
++{0x3086, 0x4416},
++{0x3086, 0x4643},
++{0x3086, 0x1697},
++{0x3086, 0x2604},
++{0x3086, 0x2684},
++{0x3086, 0x8E03},
++{0x3086, 0x27FC},
++{0x3086, 0x5C0D},
++{0x3086, 0x5754},
++{0x3086, 0x1709},
++{0x3086, 0x5556},
++{0x3086, 0x495F},
++{0x3086, 0x5305},
++{0x3086, 0x5307},
++{0x3086, 0x286C},
++{0x3086, 0x4C09},
++{0x3086, 0x282C},
++{0x3086, 0x72AE},
++{0x3086, 0x7CAA},
++{0x3086, 0x28A8},
++{0x3086, 0x7960},
++{0x3086, 0x269C},
++{0x3086, 0x5C1B},
++{0x3086, 0x4548},
++{0x3086, 0x4508},
++{0x3086, 0x4588},
++{0x3086, 0x26BE},
++{0x3086, 0x8E01},
++{0x3086, 0x27F8},
++{0x3086, 0x1702},
++{0x3086, 0x27FA},
++{0x3086, 0x1709},
++{0x3086, 0x5C0B},
++{0x3086, 0x1710},
++{0x3086, 0x26BA},
++{0x3086, 0x5C03},
++{0x3086, 0x1710},
++{0x3086, 0x26B2},
++{0x3086, 0x1706},
++{0x3086, 0x5F28},
++{0x3086, 0x8898},
++{0x3086, 0x6027},
++{0x3086, 0xF217},
++{0x3086, 0x1026},
++{0x3086, 0xA226},
++{0x3086, 0xA35F},
++{0x3086, 0x4D28},
++{0x3086, 0x081A},
++{0x3086, 0x27FA},
++{0x3086, 0x8469},
++{0x3086, 0xA578},
++{0x3086, 0x5D28},
++{0x3086, 0x8887},
++{0x3086, 0x108C},
++{0x3086, 0x8289},
++{0x3086, 0x26B2},
++{0x3086, 0x1703},
++{0x3086, 0x6BA4},
++{0x3086, 0x6099},
++{0x3086, 0x1729},
++{0x3086, 0x2683},
++{0x3086, 0x45A8},
++{0x3086, 0x1707},
++{0x3086, 0x27FB},
++{0x3086, 0x1729},
++{0x3086, 0x4588},
++{0x3086, 0x2017},
++{0x3086, 0x0827},
++{0x3086, 0xFA5D},
++{0x3086, 0x8710},
++{0x3086, 0x8C82},
++{0x3086, 0x8917},
++{0x3086, 0x0E48},
++{0x3086, 0x269A},
++{0x3086, 0x2888},
++{0x3086, 0x4C0B},
++{0x3086, 0x7917},
++{0x3086, 0x3026},
++{0x3086, 0x9217},
++{0x3086, 0x099A},
++{0x3086, 0x6027},
++{0x3086, 0xF217},
++{0x3086, 0x1026},
++{0x3086, 0x8226},
++{0x3086, 0x835F},
++{0x3086, 0x4D28},
++{0x3086, 0x081A},
++{0x3086, 0x27FA},
++{0x3086, 0x8469},
++{0x3086, 0xAB78},
++{0x3086, 0x5D28},
++{0x3086, 0x8887},
++{0x3086, 0x108C},
++{0x3086, 0x808A},
++{0x3086, 0x2692},
++{0x3086, 0x1703},
++{0x3086, 0x6BA6},
++{0x3086, 0xA726},
++{0x3086, 0x035C},
++{0x3086, 0x0145},
++{0x3086, 0x588E},
++{0x3086, 0x0027},
++{0x3086, 0x9817},
++{0x3086, 0x0A4A},
++{0x3086, 0x0A43},
++{0x3086, 0x160B},
++{0x3086, 0x438E},
++{0x3086, 0x0327},
++{0x3086, 0x9C45},
++{0x3086, 0x7817},
++{0x3086, 0x0727},
++{0x3086, 0x9D17},
++{0x3086, 0x225D},
++{0x3086, 0x8710},
++{0x3086, 0x2808},
++{0x3086, 0x530D},
++{0x3086, 0x8C80},
++{0x3086, 0x8A45},
++{0x3086, 0x5817},
++{0x3086, 0x088E},
++{0x3086, 0x0127},
++{0x3086, 0x988E},
++{0x3086, 0x0076},
++{0x3086, 0xAC77},
++{0x3086, 0xAC46},
++{0x3086, 0x4416},
++{0x3086, 0x16A8},
++{0x3086, 0x7A26},
++{0x3086, 0x445C},
++{0x3086, 0x0512},
++{0x3086, 0x444B},
++{0x3086, 0x7175},
++{0x3086, 0xA24A},
++{0x3086, 0x0343},
++{0x3086, 0x1604},
++{0x3086, 0x4316},
++{0x3086, 0x5843},
++{0x3086, 0x165A},
++{0x3086, 0x4316},
++{0x3086, 0x0643},
++{0x3086, 0x1607},
++{0x3086, 0x4316},
++{0x3086, 0x8E03},
++{0x3086, 0x279C},
++{0x3086, 0x4578},
++{0x3086, 0x7B17},
++{0x3086, 0x078B},
++{0x3086, 0x8627},
++{0x3086, 0x9D17},
++{0x3086, 0x2345},
++{0x3086, 0x5822},
++{0x3086, 0x1708},
++{0x3086, 0x8E01},
++{0x3086, 0x2798},
++{0x3086, 0x8E00},
++{0x3086, 0x2644},
++{0x3086, 0x5C05},
++{0x3086, 0x1244},
++{0x3086, 0x4B8D},
++{0x3086, 0x602C},
++{0x3086, 0x2C2C},
++{0x3086, 0x2C00},
++/* End Sequencer */
++#ifdef AR0140_EMBEDDED_LINE
++{0x3064, 0x1982}, // SMIA_TEST
++#else
++{0x3064, 0x1802}, // SMIA_TEST
++#endif
++/* PCLK=27Mhz/0x2 *0x30 /1/0x10 - TI serializers */
++{0x302A, 0x0010}, // vt_pix_clk_div
++{0x302E, 0x0002}, // pre_pll_clk_div
++{0x3030, 0x0030}, // pll_multiplier
++#if 0
++/* Resolution: 1284x804x29.98p */
++{0x3002, 0x001A}, // y_addr_start
++{0x3004, 0x0014}, // x_addr_start
++{0x3006, 0x033D}, // y_addr_end}, 804 lines
++{0x3008, 0x0517}, // x_addr_end}, 1284px
++{0x300A, 0x0344}, // frame_length_lines}, 840 lines
++{0x300C, 0x0648}, // line_length_pck}, 1608px
++#else
++{0x31B0, 0x0056}, // FRAME_PREAMBLE
++{0x31B2, 0x0045}, // LINE_PREAMBLE
++{0x3004, AR0140_X_START}, // X_ADDR_START_
++{0x3008, AR0140_X_END}, // X_ADDR_END_
++{0x3002, AR0140_Y_START}, // Y_ADDR_START_
++{0x3006, AR0140_Y_END}, // Y_ADDR_END_
++{0x3402, 0x0000 | AR0140_MAX_WIDTH}, // X_OUTPUT_CONTROL
++{0x3404, 0x0000 | AR0140_MAX_HEIGHT}, // Y_OUTPUT_CONTROL
++{0x300A, AR0140_SENSOR_HEIGHT + 36}, // FRAME_LENGTH_LINES_
++{0x300C, AR0140_SENSOR_WIDTH + 328}, // LINE_LENGTH_PCK_
++#endif
++/* Rev3 Optimized Settings */
++{0x3044, 0x0400},
++{0x3052, 0xA134},
++{0x3092, 0x010F},
++{0x30FE, 0x0080},
++{0x3ECE, 0x40FF},
++{0x3ED0, 0xFF40},
++{0x3ED2, 0xA906},
++{0x3ED4, 0x001F},
++{0x3ED6, 0x638F},
++{0x3ED8, 0xCC99},
++{0x3EDA, 0x0888},
++{0x3EDE, 0x8878},
++{0x3EE0, 0x7744},
++{0x3EE2, 0x5563},
++{0x3EE4, 0xAAE0},
++{0x3EE6, 0x3400},
++{0x3EEA, 0xA4FF},
++{0x3EEC, 0x80F0},
++{0x3EEE, 0x0000},
++{0x31E0, 0x1701},
++/* HDR mode */
++/* 2D Motion Compensation */
++{0x318A, 0x0E74}, // hdr_mc_ctrl1
++{0x318C, 0xC000}, // hdr_mc_ctrl2
++{0x318E, 0x0800}, // hdr_mc_ctrl3: Gain before DLO set to 1
++{0x3190, 0x0000}, // hdr_mc_ctrl4: if DLO enabled overrides 2D MC
++{0x3192, 0x0400}, // hdr_mc_ctrl5
++{0x3194, 0x0BB8}, // hdr_mc_ctrl6: T1 barrier set to 3000
++{0x3196, 0x0E74}, // hdr_mc_ctrl7: T2 barrier set to 3700
++{0x3198, 0x183C}, // hdr_mc_ctrl8: Motion detect Q1 set to 60}, Q2 set to 24
++{0x3200, 0x0002}, // adacd_control
++{0x3202, 0x00A0}, // adacd_noise_model1
++{0x3206, 0x0A06}, // adacd_noise_floor1
++{0x3208, 0x1A12}, // adacd_noise_floor2
++{0x320A, 0x0080}, // adacd_pedestal
++{0x306E, 0x9010}, // datapath select - LV noncontinuous
++{0x31AC, 0x100C}, // DATA_FORMAT_BITS: RAW12
++{0x31AE, 0x0301}, // SERIAL_FORMAT
++{0x301A, 0x11D8}, // RESET_REGISTER
++// patch start
++{0x3012, 0x0206}, // COARSE_INTEGRATION_TIME_: T1 exposure - max=0x400
++// patch end
++// enable trigger
++{0x340A, 0x0070}, // GPIO_CONTROL1: GPIO3 is trigger
++{0x340C, 0x0080}, // GPIO_CONTROL2: GPIO3 is trigger
++{0x30CE, 0x0120}, // TRIGGER_MODE
++//{0x30DC, 0x0120}, // TRIGGER_DELAY
++};
+diff --git a/drivers/media/i2c/soc_camera/ar0143.c b/drivers/media/i2c/soc_camera/ar0143.c
+new file mode 100644
+index 0000000..b51dcfc
+--- /dev/null
++++ b/drivers/media/i2c/soc_camera/ar0143.c
+@@ -0,0 +1,678 @@
++/*
++ * ON Semiconductor AR0143 sensor camera driver
++ *
++ * Copyright (C) 2018 Cogent Embedded, Inc.
++ *
++ * This program is free software; you can redistribute it and/or modify it
++ * under the terms of the GNU General Public License as published by the
++ * Free Software Foundation; either version 2 of the License, or (at your
++ * option) any later version.
++ */
++
++#include <linux/delay.h>
++#include <linux/init.h>
++#include <linux/i2c.h>
++#include <linux/module.h>
++#include <linux/of_graph.h>
++#include <linux/videodev2.h>
++
++#include <media/soc_camera.h>
++#include <media/v4l2-common.h>
++#include <media/v4l2-ctrls.h>
++
++#include "ar0143.h"
++
++#define AR0143_I2C_ADDR 0x10
++
++#define AR0143_PID 0x3000
++#define AR0143_VERSION_REG 0x0D54
++
++#define AR0143_MEDIA_BUS_FMT MEDIA_BUS_FMT_SGRBG12_1X12
++
++struct ar0143_priv {
++ struct v4l2_subdev sd;
++ struct v4l2_ctrl_handler hdl;
++ struct media_pad pad;
++ struct v4l2_rect rect;
++ int init_complete;
++ u8 id[6];
++ /* serializers */
++ int max9286_addr;
++ int max9271_addr;
++ int ti9x4_addr;
++ int ti9x3_addr;
++ int port;
++ int gpio_resetb;
++ int gpio_fsin;
++ int hts;
++ int vts;
++ int frame_preamble;
++};
++
++static inline struct ar0143_priv *to_ar0143(const struct i2c_client *client)
++{
++ return container_of(i2c_get_clientdata(client), struct ar0143_priv, sd);
++}
++
++static void ar0143_s_port(struct i2c_client *client, int fwd_en)
++{
++ struct ar0143_priv *priv = to_ar0143(client);
++ int tmp_addr;
++
++ if (priv->max9286_addr) {
++ tmp_addr = client->addr;
++ client->addr = priv->max9286_addr; /* Deserializer I2C address */
++ reg8_write(client, 0x0a, fwd_en ? 0x11 << priv->port : 0); /* Enable/disable reverse/forward control for this port */
++ usleep_range(5000, 5500); /* wait 5ms */
++ client->addr = tmp_addr;
++ };
++}
++
++static int ar0143_set_regs(struct i2c_client *client,
++ const struct ar0143_reg *regs, int nr_regs)
++{
++ struct ar0143_priv *priv = to_ar0143(client);
++ int i;
++
++ for (i = 0; i < nr_regs; i++) {
++ if (regs[i].reg == AR0143_DELAY) {
++ mdelay(regs[i].val);
++ continue;
++ }
++ /* cache timings */
++ if (regs[i].reg == 0x300a)
++ priv->vts = regs[i].val;
++ if (regs[i].reg == 0x300c)
++ priv->hts = regs[i].val;
++ if (regs[i].reg == 0x31b0)
++ priv->frame_preamble = regs[i].val - 1;
++
++ if (priv->ti9x4_addr) {
++ /* Override default (MAXIM serializer) table */
++ /* PCLK=16Mhz/2 *48/1/8= 48Mhz - TI serializers */
++ switch (regs[i].reg) {
++ case 0x302A:
++ reg16_write16(client, regs[i].reg, 8); // VT_PIX_CLK_DIV
++ continue;
++ case 0x302C:
++ reg16_write16(client, regs[i].reg, 1); // VT_SYS_CLK_DIV
++ continue;
++ case 0x302E:
++ reg16_write16(client, regs[i].reg, 2); // PRE_PLL_CLK_DIV
++ continue;
++ case 0x3030:
++ reg16_write16(client, regs[i].reg, 48); // PLL_MULTIPLIER
++ continue;
++ case 0x3036:
++ reg16_write16(client, regs[i].reg, 8); // OP_WORD_CLK_DIV
++ continue;
++ case 0x3038:
++ reg16_write16(client, regs[i].reg, 1); // OP_SYS_CLK_DIV
++ continue;
++ case 0x300A:
++ reg16_write16(client, regs[i].reg, AR0143_SENSOR_HEIGHT + 142); // FRAME_LENGTH_LINES_
++ continue;
++ }
++ }
++
++ reg16_write16(client, regs[i].reg, regs[i].val);
++ }
++
++ return 0;
++}
++
++static int ar0143_s_stream(struct v4l2_subdev *sd, int enable)
++{
++ return 0;
++}
++
++static int ar0143_set_window(struct v4l2_subdev *sd)
++{
++ struct i2c_client *client = v4l2_get_subdevdata(sd);
++ struct ar0143_priv *priv = to_ar0143(client);
++
++ dev_dbg(&client->dev, "L=%d T=%d %dx%d\n", priv->rect.left, priv->rect.top, priv->rect.width, priv->rect.height);
++
++ /* horiz crop start */
++ reg16_write16(client, 0x3004, priv->rect.left);
++ /* horiz crop end */
++ reg16_write16(client, 0x3008, priv->rect.left + priv->rect.width - 1);
++ /* vert crop start */
++ reg16_write16(client, 0x3002, priv->rect.top);
++ /* vert crop end */
++ reg16_write16(client, 0x3006, priv->rect.top + priv->rect.height + 1);
++
++ return 0;
++};
++
++static int ar0143_get_fmt(struct v4l2_subdev *sd,
++ struct v4l2_subdev_pad_config *cfg,
++ struct v4l2_subdev_format *format)
++{
++ struct v4l2_mbus_framefmt *mf = &format->format;
++ struct i2c_client *client = v4l2_get_subdevdata(sd);
++ struct ar0143_priv *priv = to_ar0143(client);
++
++ if (format->pad)
++ return -EINVAL;
++
++ mf->width = priv->rect.width;
++ mf->height = priv->rect.height;
++ mf->code = AR0143_MEDIA_BUS_FMT;
++ mf->colorspace = V4L2_COLORSPACE_SMPTE170M;
++ mf->field = V4L2_FIELD_NONE;
++
++ return 0;
++}
++
++static int ar0143_set_fmt(struct v4l2_subdev *sd,
++ struct v4l2_subdev_pad_config *cfg,
++ struct v4l2_subdev_format *format)
++{
++ struct v4l2_mbus_framefmt *mf = &format->format;
++
++ mf->code = AR0143_MEDIA_BUS_FMT;
++ mf->colorspace = V4L2_COLORSPACE_SMPTE170M;
++ mf->field = V4L2_FIELD_NONE;
++
++ if (format->which == V4L2_SUBDEV_FORMAT_TRY)
++ cfg->try_fmt = *mf;
++
++ return 0;
++}
++
++static int ar0143_enum_mbus_code(struct v4l2_subdev *sd,
++ struct v4l2_subdev_pad_config *cfg,
++ struct v4l2_subdev_mbus_code_enum *code)
++{
++ if (code->pad || code->index > 0)
++ return -EINVAL;
++
++ code->code = AR0143_MEDIA_BUS_FMT;
++
++ return 0;
++}
++
++static int ar0143_get_edid(struct v4l2_subdev *sd, struct v4l2_edid *edid)
++{
++ struct i2c_client *client = v4l2_get_subdevdata(sd);
++ struct ar0143_priv *priv = to_ar0143(client);
++
++ memcpy(edid->edid, priv->id, 6);
++
++ edid->edid[6] = 0xff;
++ edid->edid[7] = client->addr;
++ edid->edid[8] = AR0143_VERSION_REG >> 8;
++ edid->edid[9] = AR0143_VERSION_REG & 0xff;
++
++ return 0;
++}
++
++static int ar0143_set_selection(struct v4l2_subdev *sd,
++ struct v4l2_subdev_pad_config *cfg,
++ struct v4l2_subdev_selection *sel)
++{
++ struct v4l2_rect *rect = &sel->r;
++ struct i2c_client *client = v4l2_get_subdevdata(sd);
++ struct ar0143_priv *priv = to_ar0143(client);
++
++ if (sel->which != V4L2_SUBDEV_FORMAT_ACTIVE ||
++ sel->target != V4L2_SEL_TGT_CROP)
++ return -EINVAL;
++
++ rect->left = ALIGN(rect->left, 2);
++ rect->top = ALIGN(rect->top, 2);
++ rect->width = ALIGN(rect->width, 2);
++ rect->height = ALIGN(rect->height, 2);
++
++ if ((rect->left + rect->width > AR0143_MAX_WIDTH) ||
++ (rect->top + rect->height > AR0143_MAX_HEIGHT))
++ *rect = priv->rect;
++
++ priv->rect.left = rect->left;
++ priv->rect.top = rect->top;
++ priv->rect.width = rect->width;
++ priv->rect.height = rect->height;
++
++ ar0143_set_window(sd);
++
++ return 0;
++}
++
++static int ar0143_get_selection(struct v4l2_subdev *sd,
++ struct v4l2_subdev_pad_config *cfg,
++ struct v4l2_subdev_selection *sel)
++{
++ struct i2c_client *client = v4l2_get_subdevdata(sd);
++ struct ar0143_priv *priv = to_ar0143(client);
++
++ if (sel->which != V4L2_SUBDEV_FORMAT_ACTIVE)
++ return -EINVAL;
++
++ switch (sel->target) {
++ case V4L2_SEL_TGT_CROP_BOUNDS:
++ sel->r.left = 0;
++ sel->r.top = 0;
++ sel->r.width = AR0143_MAX_WIDTH;
++ sel->r.height = AR0143_MAX_HEIGHT;
++ return 0;
++ case V4L2_SEL_TGT_CROP_DEFAULT:
++ sel->r.left = 0;
++ sel->r.top = 0;
++ sel->r.width = AR0143_MAX_WIDTH;
++ sel->r.height = AR0143_MAX_HEIGHT;
++ return 0;
++ case V4L2_SEL_TGT_CROP:
++ sel->r = priv->rect;
++ return 0;
++ default:
++ return -EINVAL;
++ }
++}
++
++static int ar0143_g_mbus_config(struct v4l2_subdev *sd,
++ struct v4l2_mbus_config *cfg)
++{
++ cfg->flags = V4L2_MBUS_CSI2_1_LANE | V4L2_MBUS_CSI2_CHANNEL_0 |
++ V4L2_MBUS_CSI2_CONTINUOUS_CLOCK;
++ cfg->type = V4L2_MBUS_CSI2;
++
++ return 0;
++}
++
++#ifdef CONFIG_VIDEO_ADV_DEBUG
++static int ar0143_g_register(struct v4l2_subdev *sd,
++ struct v4l2_dbg_register *reg)
++{
++ struct i2c_client *client = v4l2_get_subdevdata(sd);
++ int ret;
++ u16 val = 0;
++
++ ret = reg16_read16(client, (u16)reg->reg, &val);
++ if (ret < 0)
++ return ret;
++
++ reg->val = val;
++ reg->size = sizeof(u16);
++
++ return 0;
++}
++
++static int ar0143_s_register(struct v4l2_subdev *sd,
++ const struct v4l2_dbg_register *reg)
++{
++ struct i2c_client *client = v4l2_get_subdevdata(sd);
++
++ return reg16_write16(client, (u16)reg->reg, (u16)reg->val);
++}
++#endif
++
++static struct v4l2_subdev_core_ops ar0143_core_ops = {
++#ifdef CONFIG_VIDEO_ADV_DEBUG
++ .g_register = ar0143_g_register,
++ .s_register = ar0143_s_register,
++#endif
++};
++
++static int ar0143_s_ctrl(struct v4l2_ctrl *ctrl)
++{
++ struct v4l2_subdev *sd = to_sd(ctrl);
++ struct i2c_client *client = v4l2_get_subdevdata(sd);
++ struct ar0143_priv *priv = to_ar0143(client);
++ int ret = -EINVAL;
++ u16 val = 0;
++
++ if (!priv->init_complete)
++ return 0;
++
++ switch (ctrl->id) {
++ case V4L2_CID_BRIGHTNESS:
++ case V4L2_CID_CONTRAST:
++ case V4L2_CID_SATURATION:
++ case V4L2_CID_HUE:
++ case V4L2_CID_GAMMA:
++ case V4L2_CID_SHARPNESS:
++ case V4L2_CID_AUTOGAIN:
++ break;
++ case V4L2_CID_GAIN:
++ /* Digital gain */
++ ret = reg16_write16(client, 0x3308, ctrl->val);
++ break;
++ case V4L2_CID_ANALOGUE_GAIN:
++ /* Analog gain */
++ ret = reg16_write16(client, 0x3366, ctrl->val);
++ break;
++ case V4L2_CID_EXPOSURE:
++ /* T1 exposure */
++ ret = reg16_write16(client, 0x3012, ctrl->val);
++ break;
++ case V4L2_CID_HFLIP:
++ ret = reg16_read16(client, 0x3040, &val);
++ if (ctrl->val)
++ val |= 0x4000;
++ else
++ val &= ~0x4000;
++ ret |= reg16_write16(client, 0x3040, val);
++ break;
++ case V4L2_CID_VFLIP:
++ ret = reg16_read16(client, 0x3040, &val);
++ if (ctrl->val)
++ val |= 0x8000;
++ else
++ val &= ~0x8000;
++ ret |= reg16_write16(client, 0x3040, val);
++ break;
++ case V4L2_CID_MIN_BUFFERS_FOR_CAPTURE:
++ ret = 0;
++ break;
++ }
++
++ return ret;
++}
++
++static const struct v4l2_ctrl_ops ar0143_ctrl_ops = {
++ .s_ctrl = ar0143_s_ctrl,
++};
++
++static struct v4l2_subdev_video_ops ar0143_video_ops = {
++ .s_stream = ar0143_s_stream,
++ .g_mbus_config = ar0143_g_mbus_config,
++};
++
++static const struct v4l2_subdev_pad_ops ar0143_subdev_pad_ops = {
++ .get_edid = ar0143_get_edid,
++ .enum_mbus_code = ar0143_enum_mbus_code,
++ .get_selection = ar0143_get_selection,
++ .set_selection = ar0143_set_selection,
++ .get_fmt = ar0143_get_fmt,
++ .set_fmt = ar0143_set_fmt,
++};
++
++static struct v4l2_subdev_ops ar0143_subdev_ops = {
++ .core = &ar0143_core_ops,
++ .video = &ar0143_video_ops,
++ .pad = &ar0143_subdev_pad_ops,
++};
++
++static void ar0143_otp_id_read(struct i2c_client *client)
++{
++ struct ar0143_priv *priv = to_ar0143(client);
++ int i;
++ u16 val = 0;
++
++ /* read camera id from ar014x OTP memory */
++ reg16_write16(client, 0x3054, 0x400);
++ reg16_write16(client, 0x304a, 0x110);
++ usleep_range(25000, 25500); /* wait 25 ms */
++
++ for (i = 0; i < 6; i += 2) {
++ /* first 4 bytes are equal on all ar014x */
++ reg16_read16(client, 0x3800 + i + 4, &val);
++ priv->id[i] = val >> 8;
++ priv->id[i + 1] = val & 0xff;
++ }
++}
++
++static ssize_t ar0143_otp_id_show(struct device *dev,
++ struct device_attribute *attr, char *buf)
++{
++ struct v4l2_subdev *sd = i2c_get_clientdata(to_i2c_client(dev));
++ struct i2c_client *client = v4l2_get_subdevdata(sd);
++ struct ar0143_priv *priv = to_ar0143(client);
++
++ ar0143_otp_id_read(client);
++
++ return snprintf(buf, 32, "%02x:%02x:%02x:%02x:%02x:%02x\n",
++ priv->id[0], priv->id[1], priv->id[2], priv->id[3], priv->id[4], priv->id[5]);
++}
++
++static DEVICE_ATTR(otp_id_ar0143, S_IRUGO, ar0143_otp_id_show, NULL);
++
++static int ar0143_initialize(struct i2c_client *client)
++{
++ struct ar0143_priv *priv = to_ar0143(client);
++ u16 val = 0;
++ u16 pid = 0;
++ int ret = 0;
++ int tmp_addr;
++
++ ar0143_s_port(client, 1);
++
++ /* check and show model ID */
++ reg16_read16(client, AR0143_PID, &pid);
++
++ if (pid != AR0143_VERSION_REG) {
++ dev_dbg(&client->dev, "Product ID error %x\n", pid);
++ ret = -ENODEV;
++ goto err;
++ }
++
++ /* Program wizard registers */
++ ar0143_set_regs(client, ar0143_regs_wizard, ARRAY_SIZE(ar0143_regs_wizard));
++
++ tmp_addr = client->addr;
++ if (priv->max9271_addr) {
++ /* setup serializer HS generator */
++ client->addr = priv->max9271_addr; /* Serializer I2C address */
++ reg8_write(client, 0x4e, priv->frame_preamble >> 16); /* HS delay */
++ reg8_write(client, 0x4f, (priv->frame_preamble >> 8) & 0xff);
++ reg8_write(client, 0x50, priv->frame_preamble & 0xff);
++ reg8_write(client, 0x54, AR0143_MAX_WIDTH >> 8); /* HS high period */
++ reg8_write(client, 0x55, AR0143_MAX_WIDTH & 0xff);
++ reg8_write(client, 0x56, (priv->hts - AR0143_MAX_WIDTH) >> 8); /* HS low period */
++ reg8_write(client, 0x57, (priv->hts - AR0143_MAX_WIDTH) & 0xff);
++ reg8_write(client, 0x58, priv->vts >> 8); /* HS count */
++ reg8_write(client, 0x59, priv->vts & 0xff);
++ }
++ client->addr = tmp_addr;
++
++ /* Enable stream */
++ reg16_read16(client, 0x301a, &val); // read inital reset_register value
++ val |= (1 << 2); // Set streamOn bit
++ reg16_write16(client, 0x301a, val); // Start Streaming
++
++ /* Read OTP IDs */
++ ar0143_otp_id_read(client);
++
++ dev_info(&client->dev, "ar0143 PID %x, res %dx%d, OTP_ID %02x:%02x:%02x:%02x:%02x:%02x\n",
++ pid, AR0143_MAX_WIDTH, AR0143_MAX_HEIGHT, priv->id[0], priv->id[1], priv->id[2], priv->id[3], priv->id[4], priv->id[5]);
++err:
++ ar0143_s_port(client, 0);
++
++ return ret;
++}
++
++static int ar0143_parse_dt(struct device_node *np, struct ar0143_priv *priv)
++{
++ struct i2c_client *client = v4l2_get_subdevdata(&priv->sd);
++ int i;
++ struct device_node *endpoint = NULL, *rendpoint = NULL;
++ int tmp_addr = 0;
++
++ for (i = 0; ; i++) {
++ endpoint = of_graph_get_next_endpoint(np, endpoint);
++ if (!endpoint)
++ break;
++
++ rendpoint = of_parse_phandle(endpoint, "remote-endpoint", 0);
++ if (!rendpoint)
++ continue;
++
++ if (!of_property_read_u32(rendpoint, "max9271-addr", &priv->max9271_addr) &&
++ !of_property_read_u32(rendpoint->parent->parent, "reg", &priv->max9286_addr) &&
++ !kstrtouint(strrchr(rendpoint->full_name, '@') + 1, 0, &priv->port))
++ break;
++
++ if (!of_property_read_u32(rendpoint, "ti9x3-addr", &priv->ti9x3_addr) &&
++ !of_property_match_string(rendpoint->parent->parent, "compatible", "ti,ti9x4") &&
++ !of_property_read_u32(rendpoint->parent->parent, "reg", &priv->ti9x4_addr) &&
++ !kstrtouint(strrchr(rendpoint->full_name, '@') + 1, 0, &priv->port))
++ break;
++ }
++
++ of_node_put(endpoint);
++
++ if (!priv->max9286_addr && !priv->ti9x4_addr) {
++ dev_err(&client->dev, "deserializer does not present for AR0143\n");
++ return -EINVAL;
++ }
++
++ ar0143_s_port(client, 1);
++
++ /* setup I2C translator address */
++ tmp_addr = client->addr;
++ if (priv->max9286_addr) {
++ client->addr = priv->max9271_addr; /* Serializer I2C address */
++
++ reg8_write(client, 0x09, tmp_addr << 1); /* Sensor translated I2C address */
++ reg8_write(client, 0x0A, AR0143_I2C_ADDR << 1); /* Sensor native I2C address */
++ usleep_range(2000, 2500); /* wait 2ms */
++ };
++ if (priv->ti9x4_addr) {
++ client->addr = priv->ti9x4_addr; /* Deserializer I2C address */
++
++ reg8_write(client, 0x4c, (priv->port << 4) | (1 << priv->port)); /* Select RX port number */
++ usleep_range(2000, 2500); /* wait 2ms */
++ reg8_write(client, 0x65, tmp_addr << 1); /* Sensor translated I2C address */
++ reg8_write(client, 0x5d, AR0143_I2C_ADDR << 1); /* Sensor native I2C address */
++
++ reg8_write(client, 0x6e, 0xa9); /* GPIO0 - reset, GPIO1 - fsin */
++ }
++ client->addr = tmp_addr;
++
++ mdelay(10);
++
++ return 0;
++}
++
++static int ar0143_probe(struct i2c_client *client,
++ const struct i2c_device_id *did)
++{
++ struct ar0143_priv *priv;
++ int ret;
++
++ priv = devm_kzalloc(&client->dev, sizeof(*priv), GFP_KERNEL);
++ if (!priv)
++ return -ENOMEM;
++
++ v4l2_i2c_subdev_init(&priv->sd, client, &ar0143_subdev_ops);
++ priv->sd.flags = V4L2_SUBDEV_FL_HAS_DEVNODE;
++
++ v4l2_ctrl_handler_init(&priv->hdl, 4);
++ v4l2_ctrl_new_std(&priv->hdl, &ar0143_ctrl_ops,
++ V4L2_CID_BRIGHTNESS, 0, 16, 1, 7);
++ v4l2_ctrl_new_std(&priv->hdl, &ar0143_ctrl_ops,
++ V4L2_CID_CONTRAST, 0, 16, 1, 7);
++ v4l2_ctrl_new_std(&priv->hdl, &ar0143_ctrl_ops,
++ V4L2_CID_SATURATION, 0, 7, 1, 2);
++ v4l2_ctrl_new_std(&priv->hdl, &ar0143_ctrl_ops,
++ V4L2_CID_HUE, 0, 23, 1, 12);
++ v4l2_ctrl_new_std(&priv->hdl, &ar0143_ctrl_ops,
++ V4L2_CID_GAMMA, -128, 128, 1, 0);
++ v4l2_ctrl_new_std(&priv->hdl, &ar0143_ctrl_ops,
++ V4L2_CID_SHARPNESS, 0, 10, 1, 3);
++ v4l2_ctrl_new_std(&priv->hdl, &ar0143_ctrl_ops,
++ V4L2_CID_AUTOGAIN, 0, 1, 1, 0);
++ v4l2_ctrl_new_std(&priv->hdl, &ar0143_ctrl_ops,
++ V4L2_CID_GAIN, 1, 0x7ff, 1, 0x200);
++ v4l2_ctrl_new_std(&priv->hdl, &ar0143_ctrl_ops,
++ V4L2_CID_ANALOGUE_GAIN, 1, 0xe, 1, 0x7);
++ v4l2_ctrl_new_std(&priv->hdl, &ar0143_ctrl_ops,
++ V4L2_CID_EXPOSURE, 1, 0x400, 1, 0x300);
++ v4l2_ctrl_new_std(&priv->hdl, &ar0143_ctrl_ops,
++ V4L2_CID_HFLIP, 0, 1, 1, 0);
++ v4l2_ctrl_new_std(&priv->hdl, &ar0143_ctrl_ops,
++ V4L2_CID_VFLIP, 0, 1, 1, 0);
++ priv->sd.ctrl_handler = &priv->hdl;
++
++ ret = priv->hdl.error;
++ if (ret)
++ goto cleanup;
++
++ v4l2_ctrl_handler_setup(&priv->hdl);
++
++ priv->pad.flags = MEDIA_PAD_FL_SOURCE;
++ priv->sd.entity.flags |= MEDIA_ENT_F_CAM_SENSOR;
++ ret = media_entity_pads_init(&priv->sd.entity, 1, &priv->pad);
++ if (ret < 0)
++ goto cleanup;
++
++ ret = ar0143_parse_dt(client->dev.of_node, priv);
++ if (ret)
++ goto cleanup;
++
++ ret = ar0143_initialize(client);
++ if (ret < 0)
++ goto cleanup;
++
++ priv->rect.left = 0;
++ priv->rect.top = 0;
++ priv->rect.width = AR0143_MAX_WIDTH;
++ priv->rect.height = AR0143_MAX_HEIGHT;
++
++ ret = v4l2_async_register_subdev(&priv->sd);
++ if (ret)
++ goto cleanup;
++
++ if (device_create_file(&client->dev, &dev_attr_otp_id_ar0143) != 0) {
++ dev_err(&client->dev, "sysfs otp_id entry creation failed\n");
++ goto cleanup;
++ }
++
++ priv->init_complete = 1;
++
++ return 0;
++
++cleanup:
++ media_entity_cleanup(&priv->sd.entity);
++ v4l2_ctrl_handler_free(&priv->hdl);
++ v4l2_device_unregister_subdev(&priv->sd);
++#ifdef CONFIG_SOC_CAMERA_AR0143
++ v4l_err(client, "failed to probe @ 0x%02x (%s)\n",
++ client->addr, client->adapter->name);
++#endif
++ return ret;
++}
++
++static int ar0143_remove(struct i2c_client *client)
++{
++ struct ar0143_priv *priv = i2c_get_clientdata(client);
++
++ device_remove_file(&client->dev, &dev_attr_otp_id_ar0143);
++ v4l2_async_unregister_subdev(&priv->sd);
++ media_entity_cleanup(&priv->sd.entity);
++ v4l2_ctrl_handler_free(&priv->hdl);
++ v4l2_device_unregister_subdev(&priv->sd);
++
++ return 0;
++}
++
++#ifdef CONFIG_SOC_CAMERA_AR0143
++static const struct i2c_device_id ar0143_id[] = {
++ { "ar0143", 0 },
++ { }
++};
++MODULE_DEVICE_TABLE(i2c, ar0143_id);
++
++static const struct of_device_id ar0143_of_ids[] = {
++ { .compatible = "aptina,ar0143", },
++ { }
++};
++MODULE_DEVICE_TABLE(of, ar0143_of_ids);
++
++static struct i2c_driver ar0143_i2c_driver = {
++ .driver = {
++ .name = "ar0143",
++ .of_match_table = ar0143_of_ids,
++ },
++ .probe = ar0143_probe,
++ .remove = ar0143_remove,
++ .id_table = ar0143_id,
++};
++
++module_i2c_driver(ar0143_i2c_driver);
++
++MODULE_DESCRIPTION("SoC Camera driver for AR0143");
++MODULE_AUTHOR("Vladimir Barinov");
++MODULE_LICENSE("GPL");
++#endif
+diff --git a/drivers/media/i2c/soc_camera/ar0143.h b/drivers/media/i2c/soc_camera/ar0143.h
+new file mode 100644
+index 0000000..774a438
+--- /dev/null
++++ b/drivers/media/i2c/soc_camera/ar0143.h
+@@ -0,0 +1,549 @@
++/*
++ * ON Semiconductor AR0143 sensor camera wizard 1344x968@30/BGGR/BT601/RAW12
++ *
++ * Copyright (C) 2018 Cogent Embedded, Inc.
++ *
++ * This program is free software; you can redistribute it and/or modify it
++ * under the terms of the GNU General Public License as published by the
++ * Free Software Foundation; either version 2 of the License, or (at your
++ * option) any later version.
++ */
++
++//#define AR0143_DISPLAY_PATTERN_FIXED
++//#define AR0143_DISPLAY_PATTERN_COLOR_BAR
++
++//#define AR0143_EMBEDDED_LINE
++
++#define AR0143_MAX_WIDTH 1344
++#define AR0143_MAX_HEIGHT 968
++
++#define AR0143_DELAY 0xffff
++
++#define AR0143_SENSOR_WIDTH 1344
++#define AR0143_SENSOR_HEIGHT 968
++
++#define AR0143_X_START ((AR0143_SENSOR_WIDTH - AR0143_MAX_WIDTH) / 2)
++#define AR0143_Y_START ((AR0143_SENSOR_HEIGHT - AR0143_MAX_HEIGHT) / 2)
++#define AR0143_X_END (AR0143_X_START + AR0143_MAX_WIDTH - 1)
++#define AR0143_Y_END (AR0143_Y_START + AR0143_MAX_HEIGHT + 1) /* must be +1 and not -1 or 2 lines missed - bug in imager? */
++
++struct ar0143_reg {
++ u16 reg;
++ u16 val;
++};
++
++static const struct ar0143_reg ar0143_regs_wizard[] = {
++{0x301A, 0x0001}, // reset
++{AR0143_DELAY, 100},
++{0x301A, 0x10D8}, // Stream off and setup parallel
++{0x3070, 0x0001},
++{0x3070, 0x0000}, // 1: Solid color test pattern,
++ // 2: Full color bar test pattern,
++ // 3: Fade to grey color bar test pattern,
++ //256: Walking 1 test pattern (12 bit)
++#ifdef AR0143_DISPLAY_PATTERN_FIXED
++{0x3070, 0x0001},
++#endif
++{0x3072, 0x0fff}, // R
++{0x3074, 0x0fff}, // G(GR row)
++{0x3076, 0x0fff}, // B
++{0x3078, 0x0fff}, // G(GB row)
++#ifdef AR0143_DISPLAY_PATTERN_COLOR_BAR
++{0x3070, 0x0002},
++#endif
++{AR0143_DELAY, 250},
++// start demo init
++{0x3100, 0x4000}, // DLO_CONTROL0
++{0x3102, 0x6060}, // RESERVED_MFR_3102
++{0x3104, 0x6060}, // RESERVED_MFR_3104
++{0x3106, 0x6060}, // RESERVED_MFR_3106
++{0x3108, 0x0F9F}, // RESERVED_MFR_3108
++{0x3280, 0x0FA0}, // T1_BARRIER_C0
++{0x3282, 0x0FA0}, // T1_BARRIER_C1
++{0x3284, 0x0FA0}, // T1_BARRIER_C2
++{0x3286, 0x0FA0}, // T1_BARRIER_C3
++{0x3288, 0x0FA0}, // T2_BARRIER_C0
++{0x328A, 0x0FA0}, // T2_BARRIER_C1
++{0x328C, 0x0FA0}, // T2_BARRIER_C2
++{0x328E, 0x0FA0}, // T2_BARRIER_C3
++{0x3290, 0x0FA0}, // T3_BARRIER_C0
++{0x3292, 0x0FA0}, // T3_BARRIER_C1
++{0x3294, 0x0FA0}, // T3_BARRIER_C2
++{0x3296, 0x0FA0}, // T3_BARRIER_C3
++{0x3298, 0x0FA0}, // T4_BARRIER_C0
++{0x329A, 0x0FA0}, // T4_BARRIER_C1
++{0x329C, 0x0FA0}, // T4_BARRIER_C2
++{0x329E, 0x0FA0}, // T4_BARRIER_C3
++{0x3110, 0x0011}, // HDR_CONTROL0
++{0x3112, 0x7FE7}, // RESERVED_MFR_3112
++{0x3114, 0x0000}, // RESERVED_MFR_3114
++{0x3116, 0xC000}, // HDR_CONTROL3
++{0x3120, 0x0BA0}, // HDR_SC_CONTROL0
++{0x3122, 0x0FA0}, // HDR_SC_CONTROL1
++{0x3124, 0x00B4}, // HDR_MD_CONTROL0
++{0x3126, 0x0030}, // HDR_MD_CONTROL1
++{0x3128, 0x6100}, // RESERVED_MFR_3128
++{0x3506, 0x3333}, // RESERVED_MFR_3506
++{0x3508, 0x3333}, // RESERVED_MFR_3508
++{0x350A, 0x3333}, // RESERVED_MFR_350A
++{0x350C, 0x035F}, // RESERVED_MFR_350C
++{0x350E, 0xEF14}, // RESERVED_MFR_350E
++{0x3086, 0x0600}, // RESERVED_MFR_3086
++{0x3C00, 0xDD67}, // RESERVED_MFR_3C00
++{0x3092, 0x1C24}, // RESERVED_MFR_3092
++{0x3096, 0x147E}, // RESERVED_MFR_3096
++{0x3750, 0x147E}, // RESERVED_MFR_3750
++{0x30B0, 0x0800}, // DIGITAL_TEST
++{0x30FE, 0x0000}, // NOISE_PEDESTAL
++{0x32D0, 0x3A02}, // RESERVED_MFR_32D0
++{0x32D6, 0x3C04}, // RESERVED_MFR_32D6
++{0x3C0C, 0x0516}, // DELAY_BUFFER_LLPCK_RD_WR_OVERLAP
++{0x3F94, 0x483e}, // TEMPVSENS0_FLAG_CTRL
++{0x3F96, 0xFFFE}, // TEMPVSENS1_FLAG_CTRL
++{0x3088, 0x6680}, // LFM_CTRL
++{0x33E2, 0x0000}, // SAMPLE_CTRL
++{0x3366, 0x7777}, // ANALOG_GAIN
++{0x3056, 0x0080}, // GREEN1_GAIN
++{0x305C, 0x0080}, // GREEN2_GAIN
++{0x3058, 0x0080}, // BLUE_GAIN
++{0x305A, 0x0080}, // RED_GAIN
++{0x306E, 0x9010}, // DATAPATH_SELECT
++{0x3044, 0x0400}, // DARK_CONTROL
++{0x30BA, 0x01E2}, // DIGITAL_CTRL
++{0x32EA, 0x3C0E}, // RESERVED_MFR_32EA
++{0x3362, 0x0000}, // DC_GAIN
++{0x3364, 0x005B}, // RESERVED_MFR_3364
++{0x3370, 0x0131}, // DBLC_CONTROL
++{0x3372, 0x700F}, // DBLC_FS0_CONTROL
++{0x3386, 0x0000}, // DBLC_PEDESTAL
++{0x3C04, 0x0E80}, // RESERVED_MFR_3C04
++{0x30B4, 0x01C7}, // TEMPSENS0_CTRL_REG
++{0x30B8, 0x0007}, // TEMPSENS1_CTRL_REG
++{0x3F90, 0x8D03}, // TEMPVSENS0_TMG_CTRL
++{0x3F92, 0x0D03}, // TEMPVSENS1_TMG_CTRL
++{0x3502, 0x0808}, // RESERVED_MFR_3502
++{0x3566, 0x1D28}, // RESERVED_MFR_3566
++{0x3518, 0x1FFE}, // RESERVED_MFR_3518
++{0x3526, 0x0F00}, // RESERVED_MFR_3526
++{0x3528, 0xDDDD}, // RESERVED_MFR_3528
++{0x352A, 0x089F}, // RESERVED_MFR_352A
++{0x352E, 0x0011}, // RESERVED_MFR_352E
++{0x3530, 0x4400}, // RESERVED_MFR_3530
++{0x3536, 0xFF07}, // RESERVED_MFR_3536
++{0x3538, 0xFFFF}, // RESERVED_MFR_3538
++{0x353A, 0x9000}, // RESERVED_MFR_353A
++{0x353C, 0x3F00}, // RESERVED_MFR_353C
++{0x32EC, 0x72A1}, // RESERVED_MFR_32EC
++{0x3540, 0xC637}, // RESERVED_MFR_3540
++{0x3542, 0x464B}, // RESERVED_MFR_3542
++{0x3544, 0x4B50}, // RESERVED_MFR_3544
++{0x3546, 0x545A}, // RESERVED_MFR_3546
++{0x3548, 0x5A00}, // RESERVED_MFR_3548
++{0x354A, 0x007F}, // RESERVED_MFR_354A
++{0x3556, 0x101F}, // RESERVED_MFR_3556
++{0x3566, 0x3328}, // RESERVED_MFR_3566
++{0x337A, 0x0CA3}, // DBLC_SCALE0
++{0x3372, 0x710F}, // DBLC_FS0_CONTROL
++{0x3520, 0x4688}, // RESERVED_MFR_3520
++{0x3522, 0x8840}, // RESERVED_MFR_3522
++{0x3524, 0x4046}, // RESERVED_MFR_3524
++{0x352C, 0x4646}, // RESERVED_MFR_352C
++{0x2512, 0x8000}, // SEQ_CTRL_PORT
++{0x2510, 0x0903}, // SEQ_DATA_PORT
++{0x2510, 0x3350}, // SEQ_DATA_PORT
++{0x2510, 0x2004}, // SEQ_DATA_PORT
++{0x2510, 0x1420}, // SEQ_DATA_PORT
++{0x2510, 0x1578}, // SEQ_DATA_PORT
++{0x2510, 0x087B}, // SEQ_DATA_PORT
++{0x2510, 0x24FF}, // SEQ_DATA_PORT
++{0x2510, 0x24FF}, // SEQ_DATA_PORT
++{0x2510, 0x24EA}, // SEQ_DATA_PORT
++{0x2510, 0x2410}, // SEQ_DATA_PORT
++{0x2510, 0x2224}, // SEQ_DATA_PORT
++{0x2510, 0x1015}, // SEQ_DATA_PORT
++{0x2510, 0x5813}, // SEQ_DATA_PORT
++{0x2510, 0x0214}, // SEQ_DATA_PORT
++{0x2510, 0x0024}, // SEQ_DATA_PORT
++{0x2510, 0xFF24}, // SEQ_DATA_PORT
++{0x2510, 0xFF24}, // SEQ_DATA_PORT
++{0x2510, 0xEA23}, // SEQ_DATA_PORT
++{0x2510, 0x2464}, // SEQ_DATA_PORT
++{0x2510, 0x7A24}, // SEQ_DATA_PORT
++{0x2510, 0x0405}, // SEQ_DATA_PORT
++{0x2510, 0x2C40}, // SEQ_DATA_PORT
++{0x2510, 0x0AFF}, // SEQ_DATA_PORT
++{0x2510, 0x0ACC}, // SEQ_DATA_PORT
++{0x2510, 0x0A07}, // SEQ_DATA_PORT
++{0x2510, 0x3851}, // SEQ_DATA_PORT
++{0x2510, 0x1440}, // SEQ_DATA_PORT
++{0x2510, 0x0004}, // SEQ_DATA_PORT
++{0x2510, 0x0801}, // SEQ_DATA_PORT
++{0x2510, 0x0408}, // SEQ_DATA_PORT
++{0x2510, 0x1180}, // SEQ_DATA_PORT
++{0x2510, 0x2652}, // SEQ_DATA_PORT
++{0x2510, 0x0815}, // SEQ_DATA_PORT
++{0x2510, 0x1813}, // SEQ_DATA_PORT
++{0x2510, 0xC810}, // SEQ_DATA_PORT
++{0x2510, 0x0210}, // SEQ_DATA_PORT
++{0x2510, 0x1611}, // SEQ_DATA_PORT
++{0x2510, 0x8111}, // SEQ_DATA_PORT
++{0x2510, 0x8910}, // SEQ_DATA_PORT
++{0x2510, 0x5612}, // SEQ_DATA_PORT
++{0x2510, 0x1009}, // SEQ_DATA_PORT
++{0x2510, 0x020D}, // SEQ_DATA_PORT
++{0x2510, 0x0905}, // SEQ_DATA_PORT
++{0x2510, 0x1588}, // SEQ_DATA_PORT
++{0x2510, 0x1388}, // SEQ_DATA_PORT
++{0x2510, 0x0938}, // SEQ_DATA_PORT
++{0x2510, 0x1199}, // SEQ_DATA_PORT
++{0x2510, 0x11D9}, // SEQ_DATA_PORT
++{0x2510, 0x091E}, // SEQ_DATA_PORT
++{0x2510, 0x1214}, // SEQ_DATA_PORT
++{0x2510, 0x10D6}, // SEQ_DATA_PORT
++{0x2510, 0x0901}, // SEQ_DATA_PORT
++{0x2510, 0x1210}, // SEQ_DATA_PORT
++{0x2510, 0x1212}, // SEQ_DATA_PORT
++{0x2510, 0x1210}, // SEQ_DATA_PORT
++{0x2510, 0x11DD}, // SEQ_DATA_PORT
++{0x2510, 0x11D9}, // SEQ_DATA_PORT
++{0x2510, 0x0901}, // SEQ_DATA_PORT
++{0x2510, 0x1441}, // SEQ_DATA_PORT
++{0x2510, 0x0904}, // SEQ_DATA_PORT
++{0x2510, 0x1056}, // SEQ_DATA_PORT
++{0x2510, 0x0811}, // SEQ_DATA_PORT
++{0x2510, 0xDB09}, // SEQ_DATA_PORT
++{0x2510, 0x0311}, // SEQ_DATA_PORT
++{0x2510, 0xFB11}, // SEQ_DATA_PORT
++{0x2510, 0xBB12}, // SEQ_DATA_PORT
++{0x2510, 0x1A12}, // SEQ_DATA_PORT
++{0x2510, 0x1008}, // SEQ_DATA_PORT
++{0x2510, 0x1250}, // SEQ_DATA_PORT
++{0x2510, 0x1076}, // SEQ_DATA_PORT
++{0x2510, 0x10E6}, // SEQ_DATA_PORT
++{0x2510, 0x1461}, // SEQ_DATA_PORT
++{0x2510, 0x0906}, // SEQ_DATA_PORT
++{0x2510, 0x1240}, // SEQ_DATA_PORT
++{0x2510, 0x1260}, // SEQ_DATA_PORT
++{0x2510, 0x091C}, // SEQ_DATA_PORT
++{0x2510, 0x1460}, // SEQ_DATA_PORT
++{0x2510, 0x090C}, // SEQ_DATA_PORT
++{0x2510, 0x0B09}, // SEQ_DATA_PORT
++{0x2510, 0x0515}, // SEQ_DATA_PORT
++{0x2510, 0xC813}, // SEQ_DATA_PORT
++{0x2510, 0xC808}, // SEQ_DATA_PORT
++{0x2510, 0x1066}, // SEQ_DATA_PORT
++{0x2510, 0x090B}, // SEQ_DATA_PORT
++{0x2510, 0x1588}, // SEQ_DATA_PORT
++{0x2510, 0x1388}, // SEQ_DATA_PORT
++{0x2510, 0x0913}, // SEQ_DATA_PORT
++{0x2510, 0x0C14}, // SEQ_DATA_PORT
++{0x2510, 0x4009}, // SEQ_DATA_PORT
++{0x2510, 0x0310}, // SEQ_DATA_PORT
++{0x2510, 0xE611}, // SEQ_DATA_PORT
++{0x2510, 0xFB12}, // SEQ_DATA_PORT
++{0x2510, 0x6212}, // SEQ_DATA_PORT
++{0x2510, 0x6011}, // SEQ_DATA_PORT
++{0x2510, 0xFF11}, // SEQ_DATA_PORT
++{0x2510, 0xFB14}, // SEQ_DATA_PORT
++{0x2510, 0x4109}, // SEQ_DATA_PORT
++{0x2510, 0x0210}, // SEQ_DATA_PORT
++{0x2510, 0x6609}, // SEQ_DATA_PORT
++{0x2510, 0x1211}, // SEQ_DATA_PORT
++{0x2510, 0xBB12}, // SEQ_DATA_PORT
++{0x2510, 0x6312}, // SEQ_DATA_PORT
++{0x2510, 0x6014}, // SEQ_DATA_PORT
++{0x2510, 0x0015}, // SEQ_DATA_PORT
++{0x2510, 0x1811}, // SEQ_DATA_PORT
++{0x2510, 0xB812}, // SEQ_DATA_PORT
++{0x2510, 0xA012}, // SEQ_DATA_PORT
++{0x2510, 0x0010}, // SEQ_DATA_PORT
++{0x2510, 0x2610}, // SEQ_DATA_PORT
++{0x2510, 0x0013}, // SEQ_DATA_PORT
++{0x2510, 0x0011}, // SEQ_DATA_PORT
++{0x2510, 0x8030}, // SEQ_DATA_PORT
++{0x2510, 0x5342}, // SEQ_DATA_PORT
++{0x2510, 0x1100}, // SEQ_DATA_PORT
++{0x2510, 0x1002}, // SEQ_DATA_PORT
++{0x2510, 0x1016}, // SEQ_DATA_PORT
++{0x2510, 0x1101}, // SEQ_DATA_PORT
++{0x2510, 0x1109}, // SEQ_DATA_PORT
++{0x2510, 0x1056}, // SEQ_DATA_PORT
++{0x2510, 0x1210}, // SEQ_DATA_PORT
++{0x2510, 0x0D09}, // SEQ_DATA_PORT
++{0x2510, 0x0614}, // SEQ_DATA_PORT
++{0x2510, 0x4009}, // SEQ_DATA_PORT
++{0x2510, 0x0214}, // SEQ_DATA_PORT
++{0x2510, 0x6009}, // SEQ_DATA_PORT
++{0x2510, 0x0615}, // SEQ_DATA_PORT
++{0x2510, 0x4C13}, // SEQ_DATA_PORT
++{0x2510, 0x0C09}, // SEQ_DATA_PORT
++{0x2510, 0x0713}, // SEQ_DATA_PORT
++{0x2510, 0x4C09}, // SEQ_DATA_PORT
++{0x2510, 0x0715}, // SEQ_DATA_PORT
++{0x2510, 0xCC09}, // SEQ_DATA_PORT
++{0x2510, 0x0211}, // SEQ_DATA_PORT
++{0x2510, 0x4908}, // SEQ_DATA_PORT
++{0x2510, 0x1461}, // SEQ_DATA_PORT
++{0x2510, 0x1460}, // SEQ_DATA_PORT
++{0x2510, 0x0903}, // SEQ_DATA_PORT
++{0x2510, 0x1588}, // SEQ_DATA_PORT
++{0x2510, 0x1308}, // SEQ_DATA_PORT
++{0x2510, 0x0905}, // SEQ_DATA_PORT
++{0x2510, 0x1388}, // SEQ_DATA_PORT
++{0x2510, 0x0913}, // SEQ_DATA_PORT
++{0x2510, 0x1159}, // SEQ_DATA_PORT
++{0x2510, 0x090B}, // SEQ_DATA_PORT
++{0x2510, 0x1214}, // SEQ_DATA_PORT
++{0x2510, 0x0901}, // SEQ_DATA_PORT
++{0x2510, 0x1210}, // SEQ_DATA_PORT
++{0x2510, 0x10D6}, // SEQ_DATA_PORT
++{0x2510, 0x1212}, // SEQ_DATA_PORT
++{0x2510, 0x1210}, // SEQ_DATA_PORT
++{0x2510, 0x115D}, // SEQ_DATA_PORT
++{0x2510, 0x1159}, // SEQ_DATA_PORT
++{0x2510, 0x1056}, // SEQ_DATA_PORT
++{0x2510, 0x0903}, // SEQ_DATA_PORT
++{0x2510, 0x115B}, // SEQ_DATA_PORT
++{0x2510, 0x0913}, // SEQ_DATA_PORT
++{0x2510, 0x111B}, // SEQ_DATA_PORT
++{0x2510, 0x113B}, // SEQ_DATA_PORT
++{0x2510, 0x121A}, // SEQ_DATA_PORT
++{0x2510, 0x1210}, // SEQ_DATA_PORT
++{0x2510, 0x0901}, // SEQ_DATA_PORT
++{0x2510, 0x1250}, // SEQ_DATA_PORT
++{0x2510, 0x10F6}, // SEQ_DATA_PORT
++{0x2510, 0x10E6}, // SEQ_DATA_PORT
++{0x2510, 0x0903}, // SEQ_DATA_PORT
++{0x2510, 0x15AB}, // SEQ_DATA_PORT
++{0x2510, 0x13AB}, // SEQ_DATA_PORT
++{0x2510, 0x1240}, // SEQ_DATA_PORT
++{0x2510, 0x1260}, // SEQ_DATA_PORT
++{0x2510, 0x0964}, // SEQ_DATA_PORT
++{0x2510, 0x1588}, // SEQ_DATA_PORT
++{0x2510, 0x0903}, // SEQ_DATA_PORT
++{0x2510, 0x0B08}, // SEQ_DATA_PORT
++{0x2510, 0x0813}, // SEQ_DATA_PORT
++{0x2510, 0x8809}, // SEQ_DATA_PORT
++{0x2510, 0x0715}, // SEQ_DATA_PORT
++{0x2510, 0x8D13}, // SEQ_DATA_PORT
++{0x2510, 0x8D09}, // SEQ_DATA_PORT
++{0x2510, 0x0D15}, // SEQ_DATA_PORT
++{0x2510, 0x8813}, // SEQ_DATA_PORT
++{0x2510, 0x8809}, // SEQ_DATA_PORT
++{0x2510, 0x0310}, // SEQ_DATA_PORT
++{0x2510, 0x6609}, // SEQ_DATA_PORT
++{0x2510, 0x030C}, // SEQ_DATA_PORT
++{0x2510, 0x0914}, // SEQ_DATA_PORT
++{0x2510, 0x10E6}, // SEQ_DATA_PORT
++{0x2510, 0x1262}, // SEQ_DATA_PORT
++{0x2510, 0x1260}, // SEQ_DATA_PORT
++{0x2510, 0x113F}, // SEQ_DATA_PORT
++{0x2510, 0x113B}, // SEQ_DATA_PORT
++{0x2510, 0x1066}, // SEQ_DATA_PORT
++{0x2510, 0x117B}, // SEQ_DATA_PORT
++{0x2510, 0x0927}, // SEQ_DATA_PORT
++{0x2510, 0x113B}, // SEQ_DATA_PORT
++{0x2510, 0x1263}, // SEQ_DATA_PORT
++{0x2510, 0x1260}, // SEQ_DATA_PORT
++{0x2510, 0x1400}, // SEQ_DATA_PORT
++{0x2510, 0x155A}, // SEQ_DATA_PORT
++{0x2510, 0x1138}, // SEQ_DATA_PORT
++{0x2510, 0x12A0}, // SEQ_DATA_PORT
++{0x2510, 0x1200}, // SEQ_DATA_PORT
++{0x2510, 0x1026}, // SEQ_DATA_PORT
++{0x2510, 0x1000}, // SEQ_DATA_PORT
++{0x2510, 0x1342}, // SEQ_DATA_PORT
++{0x2510, 0x1100}, // SEQ_DATA_PORT
++{0x2510, 0x437A}, // SEQ_DATA_PORT
++{0x2510, 0x0605}, // SEQ_DATA_PORT
++{0x2510, 0x0807}, // SEQ_DATA_PORT
++{0x2510, 0x4137}, // SEQ_DATA_PORT
++{0x2510, 0x502C}, // SEQ_DATA_PORT
++{0x2510, 0x2CFE}, // SEQ_DATA_PORT
++{0x2510, 0x16FE}, // SEQ_DATA_PORT
++{0x2510, 0x0C2C}, // SEQ_DATA_PORT
++{0x1008, 0x0338}, // FINE_INTEGRATION_TIME_MIN
++{0x100C, 0x051B}, // FINE_INTEGRATION_TIME2_MIN
++{0x100E, 0x06FE}, // FINE_INTEGRATION_TIME3_MIN
++{0x1010, 0x0155}, // FINE_INTEGRATION_TIME4_MIN
++{0x3230, 0x02D6}, // FINE_CORRECTION
++{0x3232, 0x04B9}, // FINE_CORRECTION2
++{0x3234, 0x069C}, // FINE_CORRECTION3
++{0x3236, 0x00F3}, // FINE_CORRECTION4
++{0x32E6, 0x00DA}, // RESERVED_MFR_32E6
++{0x350C, 0x035F}, // RESERVED_MFR_350C
++{0x32D0, 0x3A02}, // RESERVED_MFR_32D0
++{0x32D2, 0x3508}, // RESERVED_MFR_32D2
++{0x32D4, 0x3702}, // RESERVED_MFR_32D4
++{0x32D6, 0x3C04}, // RESERVED_MFR_32D6
++{0x32DC, 0x370A}, // RESERVED_MFR_32DC
++{0x302A, 0x0008}, // VT_PIX_CLK_DIV
++{0x302C, 0x0001}, // VT_SYS_CLK_DIV
++{0x302E, 0x0002}, // PRE_PLL_CLK_DIV
++{0x3030, 0x0034}, // PLL_MULTIPLIER
++{0x3036, 0x0008}, // OP_WORD_CLK_DIV
++{0x3038, 0x0001}, // OP_SYS_CLK_DIV
++{0x31DC, 0x0030}, // RESERVED_MFR_31DC
++{0x30A2, 0x0001}, // X_ODD_INC_
++{0x30A6, 0x0001}, // Y_ODD_INC_
++{0x3040, 0x0000}, // READ_MODE
++{0x3044, 0x0400}, // DARK_CONTROL
++{0x3180, 0x0080}, // RESERVED_MFR_3180
++{0x33E4, 0x0080}, // RESERVED_MFR_33E4
++{0x33E0, 0x0880}, // TEST_ASIL_ROWS
++#ifdef AR0143_EMBEDDED_LINE
++{0x3064, 0x1982}, // SMIA_TEST
++#else
++{0x3064, 0x1802}, // SMIA_TEST
++#endif
++{0x3004, 0x0000}, // X_ADDR_START_
++{0x3008, 0x053F}, // X_ADDR_END_
++{0x3002, 0x0000}, // Y_ADDR_START_
++{0x3006, 0x03C7}, // Y_ADDR_END_
++{0x3400, 0x0010}, // RESERVED_MFR_3400
++{0x3402, 0x0A80}, // X_OUTPUT_CONTROL
++{0x3404, 0x0790}, // Y_OUTPUT_CONTROL
++{0x3082, 0x0008}, // OPERATION_MODE_CTRL
++{0x30BA, 0x01E2}, // DIGITAL_CTRL
++{0x300C, 0x09A0}, // LINE_LENGTH_PCK_
++{0x300A, 0x041E}, // FRAME_LENGTH_LINES_
++{0x3042, 0x0000}, // EXTRA_DELAY
++{0x3238, 0x0333}, // EXPOSURE_RATIO
++{0x3012, 0x036E}, // COARSE_INTEGRATION_TIME_
++{0x3014, 0x0A7A}, // FINE_INTEGRATION_TIME_
++{0x321E, 0x0A7A}, // FINE_INTEGRATION_TIME2
++{0x3222, 0x0A7A}, // FINE_INTEGRATION_TIME3
++{0x32EA, 0x3C0E}, // RESERVED_MFR_32EA
++{0x32EA, 0x3C0E}, // RESERVED_MFR_32EA
++{0x32EA, 0x3C0E}, // RESERVED_MFR_32EA
++{0x32EC, 0x72A1}, // RESERVED_MFR_32EC
++{0x32EC, 0x72A1}, // RESERVED_MFR_32EC
++{0x32EC, 0x72A1}, // RESERVED_MFR_32EC
++{0x32EC, 0x72A1}, // RESERVED_MFR_32EC
++{0x32EC, 0x72A1}, // RESERVED_MFR_32EC
++{0x32EC, 0x72A1}, // RESERVED_MFR_32EC
++{0x3C06, 0x083C}, // RESERVED_MFR_3C06
++{0x3C08, 0x0100}, // RESERVED_MFR_3C08
++{0x31D0, 0x0001}, // COMPANDING
++{0x31AC, 0x1410}, // DATA_FORMAT_BITS: 2xRAW8
++{0x301A, 0x1098}, // RESET_REGISTER
++{0x301A, 0x1018}, // RESET_REGISTER
++{0x301A, 0x0018}, // RESET_REGISTER
++{0x31AE, 0x0204}, // SERIAL_FORMAT
++{0x3342, 0x122A}, // MIPI_F1_PDT_EDT
++{0x3346, 0x122A}, // MIPI_F2_PDT_EDT
++{0x334A, 0x122A}, // MIPI_F3_PDT_EDT
++{0x334E, 0x122A}, // MIPI_F4_PDT_EDT
++{0x3344, 0x0011}, // MIPI_F1_VDT_VC
++{0x3348, 0x0111}, // MIPI_F2_VDT_VC
++{0x334C, 0x0211}, // MIPI_F3_VDT_VC
++{0x3350, 0x0311}, // MIPI_F4_VDT_VC
++{0x31B0, 0x0061}, // FRAME_PREAMBLE
++{0x31B2, 0x004C}, // LINE_PREAMBLE
++{0x31B4, 0x51C8}, // RESERVED_MFR_31B4
++{0x31B6, 0x424B}, // RESERVED_MFR_31B6
++{0x31B8, 0x40CF}, // RESERVED_MFR_31B8
++{0x31BA, 0x028B}, // RESERVED_MFR_31BA
++{0x31BC, 0x0D09}, // RESERVED_MFR_31BC
++// end demo init
++// start reg wizard WIDTHxHEIGHT@30fps
++#define NEW_TBL
++#ifdef NEW_TBL
++/* PCLK=27Mhz/0x5 *0x5d /1/0xa - MAXIM serializers */
++{0x302A, 0x000A}, // VT_PIX_CLK_DIV
++{0x302C, 0x0001}, // VT_SYS_CLK_DIV
++{0x302E, 0x0005}, // PRE_PLL_CLK_DIV
++{0x3030, 0x005d}, // PLL_MULTIPLIER
++{0x3036, 0x000A}, // OP_WORD_CLK_DIV
++{0x3038, 0x0001}, // OP_SYS_CLK_DIV
++#else
++/* PCLK=27Mhz/0x9 *134 /1/8 - MAXIM serializers */
++{0x302A, 0x0008}, // VT_PIX_CLK_DIV
++{0x302C, 0x0001}, // VT_SYS_CLK_DIV
++{0x302E, 0x0009}, // PRE_PLL_CLK_DIV
++{0x3030, 134}, // PLL_MULTIPLIER
++{0x3036, 0x0008}, // OP_WORD_CLK_DIV
++{0x3038, 0x0001}, // OP_SYS_CLK_DIV
++#endif
++{0x31B0, 0x0056}, // FRAME_PREAMBLE
++{0x31B2, 0x0045}, // LINE_PREAMBLE
++{0x3004, AR0143_X_START}, // X_ADDR_START_
++{0x3008, AR0143_X_END}, // X_ADDR_END_
++{0x3002, AR0143_Y_START}, // Y_ADDR_START_
++{0x3006, AR0143_Y_END}, // Y_ADDR_END_
++{0x3402, 0x0000 | AR0143_MAX_WIDTH}, // X_OUTPUT_CONTROL
++{0x3404, 0x0000 | AR0143_MAX_HEIGHT}, // Y_OUTPUT_CONTROL
++{0x31B4, 0x2207}, // RESERVED_MFR_31B4
++{0x31B6, 0x220B}, // RESERVED_MFR_31B6
++{0x31B8, 0x404B}, // RESERVED_MFR_31B8
++{0x31BA, 0x020A}, // RESERVED_MFR_31BA
++{0x31BC, 0x0C08}, // RESERVED_MFR_31BC
++{0x3040, 0x0000}, // READ_MODE
++{0x30BA, 0x01E2}, // DIGITAL_CTRL
++{0x3082, 0x0008}, // OPERATION_MODE_CTRL
++{0x3044, 0x0400}, // DARK_CONTROL
++{0x33E0, 0x0880}, // TEST_ASIL_ROWS
++{0x3180, 0x0080}, // RESERVED_MFR_3180
++{0x33E4, 0x0080}, // RESERVED_MFR_33E4
++{0x3032, 0x0000}, // RESERVED_MFR_3032
++{0x3400, 0x0010}, // RESERVED_MFR_3400
++{0x31D0, 0x0001}, // COMPANDING
++//{0x31AC, 0x1410}, // DATA_FORMAT_BITS: 2xRAW8
++{0x31AC, 0x140C}, // DATA_FORMAT_BITS: RAW12
++{0x3C08, 0x0100}, // RESERVED_MFR_3C08
++{0x3C0C, 0x0518}, // DELAY_BUFFER_LLPCK_RD_WR_OVERLAP
++#ifdef NEW_TBL
++//{0x300A, 0x0438}, // FRAME_LENGTH_LINES_
++//{0x300C, 0x060e}, // LINE_LENGTH_PCK_
++{0x300A, AR0143_SENSOR_HEIGHT + 157}, // FRAME_LENGTH_LINES_
++{0x300C, AR0143_SENSOR_WIDTH + 144}, // LINE_LENGTH_PCK_
++#else
++{0x300A, 0x048A}, // FRAME_LENGTH_LINES_
++{0x300C, 0x05BA}, // LINE_LENGTH_PCK_
++#endif
++{0x3018, 0x0000}, // FINE_INTEGRATION_TIME_CB
++{0x1008, 0x0338}, // FINE_INTEGRATION_TIME_MIN
++{0x100C, 0x051B}, // FINE_INTEGRATION_TIME2_MIN
++{0x100E, 0x06FE}, // FINE_INTEGRATION_TIME3_MIN
++{0x1010, 0x0155}, // FINE_INTEGRATION_TIME4_MIN
++#ifdef NEW_TBL
++{0x3012, 0x0206}, // COARSE_INTEGRATION_TIME_
++{0x3014, 0x06e8}, // FINE_INTEGRATION_TIME_
++{0x321E, 0x06E8}, // FINE_INTEGRATION_TIME2
++{0x3222, 0x06E8}, // FINE_INTEGRATION_TIME3
++#else
++{0x3012, 0x0332}, // COARSE_INTEGRATION_TIME_
++{0x3014, 0x0694}, // FINE_INTEGRATION_TIME_
++{0x321E, 0x0694}, // FINE_INTEGRATION_TIME2
++{0x3222, 0x0694}, // FINE_INTEGRATION_TIME3
++#endif
++{0x32EC, 0x72A0}, // RESERVED_MFR_32EC
++{0x31C6, 0x0000}, // HISPI_CONTROL
++#ifdef NEW_TBL
++{0x3082, 0x0000}, // OPERATION_MODE_CTRL: 1 exposure
++{0x3238, 0x0222}, // auto exposure time ratio - Fixed!
++#else
++// patch start
++//{0x30BA, 0x01E2}, // DIGITAL_CTRL: 3 exposures
++//{0x3082, 0x0008}, // OPERATION_MODE_CTRL: 3 exposures
++{0x3082, 0x0000}, // OPERATION_MODE_CTRL: 1 exposure
++//{0x30fe, 0x07ff}, // NOISE PEDESTAL
++//{0x305e, 0x3333}, // DIGITAL COLOR GLOBAL GAIN
++{0x3308, 0x200}, // DIGITAL GLOBAL GAIN: max=0x7ff
++//{0x3060, 0x7777}, // ANALOG COLOR GAIN
++{0x3366, 0x0666}, // ANALOG_GAIN - Fixed!
++//{0x3238, 0x8000}, // manual exposure time
++{0x3238, 0x0222}, // auto exposure time ratio - Fixed!
++{0x3012, 0x0300}, // T1 exposure - max=0x400
++//{0x3212, 0x0004}, // T2 exposure - not used in auto
++//{0x3216, 0x0001}, // T3 exposure - not used in auto
++#endif
++// patch eof
++{0x301A, 0x01d8}, // RESET_REGISTER
++// enable trigger
++{0x340A, 0x0070}, // GPIO_CONTROL1: GPIO3 is trigger
++{0x340C, 0x0080}, // GPIO_CONTROL2: GPIO3 is trigger
++{0x30CE, 0x0120}, // TRIGGER_MODE
++//{0x30DC, 0x0120}, // TRIGGER_DELAY
++// end reg wizard WIDTHxHEIGHT@30fps
++};
+diff --git a/drivers/media/i2c/soc_camera/ar0220.c b/drivers/media/i2c/soc_camera/ar0220.c
+index 8813522..b1ca101 100644
+--- a/drivers/media/i2c/soc_camera/ar0220.c
++++ b/drivers/media/i2c/soc_camera/ar0220.c
+@@ -19,7 +19,6 @@
+ #include <media/soc_camera.h>
+ #include <media/v4l2-common.h>
+ #include <media/v4l2-ctrls.h>
+-#include <media/v4l2-fwnode.h>
+
+ #include "ar0220.h"
+
+@@ -29,7 +28,7 @@
+ #define AR0220_PID 0x3000
+ #define AR0220_VERSION_REG 0x0C54
+
+-#define AR0220_MEDIA_BUS_FMT MEDIA_BUS_FMT_SBGGR8_1X8
++#define AR0220_MEDIA_BUS_FMT MEDIA_BUS_FMT_SGRBG14_1X14
+
+ struct ar0220_priv {
+ struct v4l2_subdev sd;
+@@ -47,7 +46,6 @@ struct ar0220_priv {
+ int port;
+ int gpio_resetb;
+ int gpio_fsin;
+-
+ };
+
+ static inline struct ar0220_priv *to_ar0220(const struct i2c_client *client)
+@@ -319,6 +317,7 @@ static int ar0220_initialize(struct i2c_client *client)
+ u16 val = 0;
+ u16 pid = 0;
+ int ret = 0;
++ int tmp_addr;
+
+ /* check and show model ID */
+ reg16_read16(client, AR0220_PID, &pid);
+@@ -329,6 +328,16 @@ static int ar0220_initialize(struct i2c_client *client)
+ goto err;
+ }
+
++ /* setup XCLK */
++ tmp_addr = client->addr;
++ if (priv->ti9x4_addr) {
++ /* CLK_OUT=22.5792*160*M/N/CLKDIV -> CLK_OUT=27MHz: CLKDIV=2, M=15, N=251: 22.5792*160/8*15/251=26.987MHz=CLK_OUT */
++ client->addr = priv->ti9x3_addr; /* Serializer I2C address */
++ reg8_write(client, 0x06, 0x6f); /* Set CLKDIV and M */
++ reg8_write(client, 0x07, 0xfb); /* Set N */
++ }
++ client->addr = tmp_addr;
++
+ /* Program wizard registers */
+ ar0220_set_regs(client, ar0220_regs_wizard, ARRAY_SIZE(ar0220_regs_wizard));
+
+@@ -386,11 +395,8 @@ static int ar0220_parse_dt(struct device_node *np, struct ar0220_priv *priv)
+ usleep_range(2000, 2500); /* wait 2ms */
+ reg8_write(client, 0x65, tmp_addr << 1); /* Sensor translated I2C address */
+ reg8_write(client, 0x5d, AR0220_I2C_ADDR << 1); /* Sensor native I2C address */
+-// reg8_write(client, 0x6e, 0xa9); /* GPIO0 - reset, GPIO1 - fsin */
+
+- client->addr = priv->ti9x3_addr; /* Serializer I2C address */
+- reg8_write(client, 0x06, 0x41); /* Set clock divider M */
+- reg8_write(client, 0x07, 0x25); /* Set clock divider N = 27MHz */
++// reg8_write(client, 0x6e, 0xa9); /* GPIO0 - reset, GPIO1 - fsin */
+ }
+ client->addr = tmp_addr;
+
+diff --git a/drivers/media/i2c/soc_camera/ar0220.h b/drivers/media/i2c/soc_camera/ar0220.h
+index 8ef557d..205c351 100644
+--- a/drivers/media/i2c/soc_camera/ar0220.h
++++ b/drivers/media/i2c/soc_camera/ar0220.h
+@@ -12,7 +12,7 @@
+ //#define AR0220_DISPLAY_PATTERN_FIXED
+ //#define AR0220_DISPLAY_PATTERN_COLOR_BAR
+
+-#define AR0220_MAX_WIDTH 3648 // (1820*2=3640) <- must be multiple of 16 - requred by R-CAR VIN
++#define AR0220_MAX_WIDTH 1820
+ #define AR0220_MAX_HEIGHT 944
+
+ #define AR0220_DELAY 0xffff
+@@ -25,14 +25,14 @@ struct ar0220_reg {
+ static const struct ar0220_reg ar0220_regs_wizard[] = {
+ {0x301A, 0x0018}, // RESET_REGISTER
+ {AR0220_DELAY, 500}, // Wait 500ms
+-{0x3070, 0x0000}, // 1: Solid color test pattern,
+- // 2: Full color bar test pattern,
+- // 3: Fade to grey color bar test pattern,
+- //256: Walking 1 test pattern (12 bit)
+-{0x3072, 0x0123}, // R
+-{0x3074, 0x0456}, // G(GR row)
+-{0x3076, 0x0abc}, // B
+-{0x3078, 0x0def}, // G(GB row)
++{0x3070, 0x0000}, // 1: Solid color test pattern,
++ // 2: Full color bar test pattern,
++ // 3: Fade to grey color bar test pattern,
++ //256: Walking 1 test pattern (12 bit)
++{0x3072, 0x0123}, // R
++{0x3074, 0x0456}, // G(GR row)
++{0x3076, 0x0abc}, // B
++{0x3078, 0x0def}, // G(GB row)
+ #ifdef AR0220_DISPLAY_PATTERN_FIXED
+ {0x3070, 0x0001},
+ #endif
+diff --git a/drivers/media/i2c/soc_camera/ar0231.c b/drivers/media/i2c/soc_camera/ar0231.c
+new file mode 100644
+index 0000000..176e1bf
+--- /dev/null
++++ b/drivers/media/i2c/soc_camera/ar0231.c
+@@ -0,0 +1,580 @@
++/*
++ * ON Semiconductor AR0231 sensor camera driver
++ *
++ * Copyright (C) 2018 Cogent Embedded, Inc.
++ *
++ * This program is free software; you can redistribute it and/or modify it
++ * under the terms of the GNU General Public License as published by the
++ * Free Software Foundation; either version 2 of the License, or (at your
++ * option) any later version.
++ */
++
++#include <linux/delay.h>
++#include <linux/init.h>
++#include <linux/i2c.h>
++#include <linux/module.h>
++#include <linux/of_graph.h>
++#include <linux/videodev2.h>
++
++#include <media/soc_camera.h>
++#include <media/v4l2-common.h>
++#include <media/v4l2-ctrls.h>
++
++#include "ar0231.h"
++
++#define AR0231_I2C_ADDR 0x10
++
++#define AR0231_PID 0x3000
++#define AR0231_VERSION_REG 0x0354
++
++#define AR0231_MEDIA_BUS_FMT MEDIA_BUS_FMT_SGRBG12_1X12
++
++struct ar0231_priv {
++ struct v4l2_subdev sd;
++ struct v4l2_ctrl_handler hdl;
++ struct media_pad pad;
++ struct v4l2_rect rect;
++ int init_complete;
++ u8 id[6];
++ /* serializers */
++ int max9286_addr;
++ int max9271_addr;
++ int port;
++ int gpio_resetb;
++ int gpio_fsin;
++};
++
++static inline struct ar0231_priv *to_ar0231(const struct i2c_client *client)
++{
++ return container_of(i2c_get_clientdata(client), struct ar0231_priv, sd);
++}
++
++static void ar0231_s_port(struct i2c_client *client, int fwd_en)
++{
++ struct ar0231_priv *priv = to_ar0231(client);
++ int tmp_addr;
++
++ if (priv->max9286_addr) {
++ tmp_addr = client->addr;
++ client->addr = priv->max9286_addr; /* Deserializer I2C address */
++ reg8_write(client, 0x0a, fwd_en ? 0x11 << priv->port : 0); /* Enable/disable reverse/forward control for this port */
++ usleep_range(5000, 5500); /* wait 5ms */
++ client->addr = tmp_addr;
++ };
++}
++
++static int ar0231_set_regs(struct i2c_client *client,
++ const struct ar0231_reg *regs, int nr_regs)
++{
++ int i;
++
++ for (i = 0; i < nr_regs; i++) {
++ if (regs[i].reg == AR0231_DELAY) {
++ mdelay(regs[i].val);
++ continue;
++ }
++
++ reg16_write16(client, regs[i].reg, regs[i].val);
++ }
++
++ return 0;
++}
++
++static int ar0231_s_stream(struct v4l2_subdev *sd, int enable)
++{
++ return 0;
++}
++
++static int ar0231_get_fmt(struct v4l2_subdev *sd,
++ struct v4l2_subdev_pad_config *cfg,
++ struct v4l2_subdev_format *format)
++{
++ struct v4l2_mbus_framefmt *mf = &format->format;
++ struct i2c_client *client = v4l2_get_subdevdata(sd);
++ struct ar0231_priv *priv = to_ar0231(client);
++
++ if (format->pad)
++ return -EINVAL;
++
++ mf->width = priv->rect.width;
++ mf->height = priv->rect.height;
++ mf->code = AR0231_MEDIA_BUS_FMT;
++ mf->colorspace = V4L2_COLORSPACE_SMPTE170M;
++ mf->field = V4L2_FIELD_NONE;
++
++ return 0;
++}
++
++static int ar0231_set_fmt(struct v4l2_subdev *sd,
++ struct v4l2_subdev_pad_config *cfg,
++ struct v4l2_subdev_format *format)
++{
++ struct v4l2_mbus_framefmt *mf = &format->format;
++
++ mf->code = AR0231_MEDIA_BUS_FMT;
++ mf->colorspace = V4L2_COLORSPACE_SMPTE170M;
++ mf->field = V4L2_FIELD_NONE;
++
++ if (format->which == V4L2_SUBDEV_FORMAT_TRY)
++ cfg->try_fmt = *mf;
++
++ return 0;
++}
++
++static int ar0231_enum_mbus_code(struct v4l2_subdev *sd,
++ struct v4l2_subdev_pad_config *cfg,
++ struct v4l2_subdev_mbus_code_enum *code)
++{
++ if (code->pad || code->index > 0)
++ return -EINVAL;
++
++ code->code = AR0231_MEDIA_BUS_FMT;
++
++ return 0;
++}
++
++static int ar0231_get_edid(struct v4l2_subdev *sd, struct v4l2_edid *edid)
++{
++ struct i2c_client *client = v4l2_get_subdevdata(sd);
++ struct ar0231_priv *priv = to_ar0231(client);
++
++ memcpy(edid->edid, priv->id, 6);
++
++ edid->edid[6] = 0xff;
++ edid->edid[7] = client->addr;
++ edid->edid[8] = AR0231_VERSION_REG >> 8;
++ edid->edid[9] = AR0231_VERSION_REG & 0xff;
++
++ return 0;
++}
++
++static int ar0231_set_selection(struct v4l2_subdev *sd,
++ struct v4l2_subdev_pad_config *cfg,
++ struct v4l2_subdev_selection *sel)
++{
++ struct v4l2_rect *rect = &sel->r;
++ struct i2c_client *client = v4l2_get_subdevdata(sd);
++ struct ar0231_priv *priv = to_ar0231(client);
++
++ if (sel->which != V4L2_SUBDEV_FORMAT_ACTIVE ||
++ sel->target != V4L2_SEL_TGT_CROP)
++ return -EINVAL;
++
++ rect->left = ALIGN(rect->left, 2);
++ rect->top = ALIGN(rect->top, 2);
++ rect->width = ALIGN(rect->width, 2);
++ rect->height = ALIGN(rect->height, 2);
++
++ if ((rect->left + rect->width > AR0231_MAX_WIDTH) ||
++ (rect->top + rect->height > AR0231_MAX_HEIGHT))
++ *rect = priv->rect;
++
++ priv->rect.left = rect->left;
++ priv->rect.top = rect->top;
++ priv->rect.width = rect->width;
++ priv->rect.height = rect->height;
++
++ return 0;
++}
++
++static int ar0231_get_selection(struct v4l2_subdev *sd,
++ struct v4l2_subdev_pad_config *cfg,
++ struct v4l2_subdev_selection *sel)
++{
++ struct i2c_client *client = v4l2_get_subdevdata(sd);
++ struct ar0231_priv *priv = to_ar0231(client);
++
++ if (sel->which != V4L2_SUBDEV_FORMAT_ACTIVE)
++ return -EINVAL;
++
++ switch (sel->target) {
++ case V4L2_SEL_TGT_CROP_BOUNDS:
++ sel->r.left = 0;
++ sel->r.top = 0;
++ sel->r.width = AR0231_MAX_WIDTH;
++ sel->r.height = AR0231_MAX_HEIGHT;
++ return 0;
++ case V4L2_SEL_TGT_CROP_DEFAULT:
++ sel->r.left = 0;
++ sel->r.top = 0;
++ sel->r.width = AR0231_MAX_WIDTH;
++ sel->r.height = AR0231_MAX_HEIGHT;
++ return 0;
++ case V4L2_SEL_TGT_CROP:
++ sel->r = priv->rect;
++ return 0;
++ default:
++ return -EINVAL;
++ }
++}
++
++static int ar0231_g_mbus_config(struct v4l2_subdev *sd,
++ struct v4l2_mbus_config *cfg)
++{
++ cfg->flags = V4L2_MBUS_CSI2_1_LANE | V4L2_MBUS_CSI2_CHANNEL_0 |
++ V4L2_MBUS_CSI2_CONTINUOUS_CLOCK;
++ cfg->type = V4L2_MBUS_CSI2;
++
++ return 0;
++}
++
++#ifdef CONFIG_VIDEO_ADV_DEBUG
++static int ar0231_g_register(struct v4l2_subdev *sd,
++ struct v4l2_dbg_register *reg)
++{
++ struct i2c_client *client = v4l2_get_subdevdata(sd);
++ int ret;
++ u16 val = 0;
++
++ ret = reg16_read16(client, (u16)reg->reg, &val);
++ if (ret < 0)
++ return ret;
++
++ reg->val = val;
++ reg->size = sizeof(u16);
++
++ return 0;
++}
++
++static int ar0231_s_register(struct v4l2_subdev *sd,
++ const struct v4l2_dbg_register *reg)
++{
++ struct i2c_client *client = v4l2_get_subdevdata(sd);
++
++ return reg16_write16(client, (u16)reg->reg, (u16)reg->val);
++}
++#endif
++
++static struct v4l2_subdev_core_ops ar0231_core_ops = {
++#ifdef CONFIG_VIDEO_ADV_DEBUG
++ .g_register = ar0231_g_register,
++ .s_register = ar0231_s_register,
++#endif
++};
++
++static int ar0231_s_ctrl(struct v4l2_ctrl *ctrl)
++{
++ struct v4l2_subdev *sd = to_sd(ctrl);
++ struct i2c_client *client = v4l2_get_subdevdata(sd);
++ struct ar0231_priv *priv = to_ar0231(client);
++ int ret = -EINVAL;
++ u16 val = 0;
++
++ if (!priv->init_complete)
++ return 0;
++
++ switch (ctrl->id) {
++ case V4L2_CID_BRIGHTNESS:
++ case V4L2_CID_CONTRAST:
++ case V4L2_CID_SATURATION:
++ case V4L2_CID_HUE:
++ case V4L2_CID_GAMMA:
++ case V4L2_CID_SHARPNESS:
++ case V4L2_CID_AUTOGAIN:
++ break;
++ case V4L2_CID_GAIN:
++ /* Digital gain */
++ ret = reg16_write16(client, 0x3308, ctrl->val);
++ break;
++ case V4L2_CID_ANALOGUE_GAIN:
++ /* Analog gain */
++ ret = reg16_write16(client, 0x3366, (ctrl->val << 8) | (ctrl->val << 4) | ctrl->val);
++ break;
++ case V4L2_CID_EXPOSURE:
++ /* T1 exposure */
++ ret = reg16_write16(client, 0x3012, ctrl->val);
++ break;
++ case V4L2_CID_HFLIP:
++ ret = reg16_read16(client, 0x3040, &val);
++ if (ctrl->val)
++ val |= (1 << 14);
++ else
++ val &= ~(1 << 14);
++ ret |= reg16_write16(client, 0x3040, val);
++ break;
++ case V4L2_CID_VFLIP:
++ ret = reg16_read16(client, 0x3040, &val);
++ if (ctrl->val)
++ val |= (1 << 15);
++ else
++ val &= ~(1 << 15);
++ ret |= reg16_write16(client, 0x3040, val);
++ break;
++ case V4L2_CID_MIN_BUFFERS_FOR_CAPTURE:
++ ret = 0;
++ break;
++ }
++
++ return ret;
++}
++
++static const struct v4l2_ctrl_ops ar0231_ctrl_ops = {
++ .s_ctrl = ar0231_s_ctrl,
++};
++
++static struct v4l2_subdev_video_ops ar0231_video_ops = {
++ .s_stream = ar0231_s_stream,
++ .g_mbus_config = ar0231_g_mbus_config,
++};
++
++static const struct v4l2_subdev_pad_ops ar0231_subdev_pad_ops = {
++ .get_edid = ar0231_get_edid,
++ .enum_mbus_code = ar0231_enum_mbus_code,
++ .get_selection = ar0231_get_selection,
++ .set_selection = ar0231_set_selection,
++ .get_fmt = ar0231_get_fmt,
++ .set_fmt = ar0231_set_fmt,
++};
++
++static struct v4l2_subdev_ops ar0231_subdev_ops = {
++ .core = &ar0231_core_ops,
++ .video = &ar0231_video_ops,
++ .pad = &ar0231_subdev_pad_ops,
++};
++
++static void ar0231_otp_id_read(struct i2c_client *client)
++{
++ struct ar0231_priv *priv = to_ar0231(client);
++ int i;
++ u16 val = 0;
++
++ /* read camera id from ar014x OTP memory */
++ reg16_write16(client, 0x3054, 0x400);
++ reg16_write16(client, 0x304a, 0x110);
++ usleep_range(25000, 25500); /* wait 25 ms */
++
++ for (i = 0; i < 6; i += 2) {
++ /* first 4 bytes are equal on all ar014x */
++ reg16_read16(client, 0x3800 + i + 4, &val);
++ priv->id[i] = val >> 8;
++ priv->id[i + 1] = val & 0xff;
++ }
++}
++
++static ssize_t ar0231_otp_id_show(struct device *dev,
++ struct device_attribute *attr, char *buf)
++{
++ struct v4l2_subdev *sd = i2c_get_clientdata(to_i2c_client(dev));
++ struct i2c_client *client = v4l2_get_subdevdata(sd);
++ struct ar0231_priv *priv = to_ar0231(client);
++
++ ar0231_otp_id_read(client);
++
++ return snprintf(buf, 32, "%02x:%02x:%02x:%02x:%02x:%02x\n",
++ priv->id[0], priv->id[1], priv->id[2], priv->id[3], priv->id[4], priv->id[5]);
++}
++
++static DEVICE_ATTR(otp_id_ar0231, S_IRUGO, ar0231_otp_id_show, NULL);
++
++static int ar0231_initialize(struct i2c_client *client)
++{
++ struct ar0231_priv *priv = to_ar0231(client);
++ u16 val = 0;
++ u16 pid = 0;
++ int ret = 0;
++
++ /* check and show model ID */
++ reg16_read16(client, AR0231_PID, &pid);
++
++ if (pid != AR0231_VERSION_REG) {
++ dev_dbg(&client->dev, "Product ID error %x\n", pid);
++ ret = -ENODEV;
++ goto err;
++ }
++
++ /* Program wizard registers */
++ ar0231_set_regs(client, ar0231_regs_wizard_rev4, ARRAY_SIZE(ar0231_regs_wizard_rev4));
++
++ /* Enable stream */
++ reg16_read16(client, 0x301a, &val); // read inital reset_register value
++ val |= (1 << 2); // Set streamOn bit
++ reg16_write16(client, 0x301a, val); // Start Streaming
++
++ /* Read OTP IDs */
++ ar0231_otp_id_read(client);
++
++ dev_info(&client->dev, "ar0231 PID %x, res %dx%d, OTP_ID %02x:%02x:%02x:%02x:%02x:%02x\n",
++ pid, AR0231_MAX_WIDTH, AR0231_MAX_HEIGHT, priv->id[0], priv->id[1], priv->id[2], priv->id[3], priv->id[4], priv->id[5]);
++err:
++ ar0231_s_port(client, 0);
++ return ret;
++}
++
++static int ar0231_parse_dt(struct device_node *np, struct ar0231_priv *priv)
++{
++ struct i2c_client *client = v4l2_get_subdevdata(&priv->sd);
++ int i;
++ struct device_node *endpoint = NULL, *rendpoint = NULL;
++ int tmp_addr = 0;
++
++ for (i = 0; ; i++) {
++ endpoint = of_graph_get_next_endpoint(np, endpoint);
++ if (!endpoint)
++ break;
++
++ rendpoint = of_parse_phandle(endpoint, "remote-endpoint", 0);
++ if (!rendpoint)
++ continue;
++
++ if (!of_property_read_u32(rendpoint, "max9271-addr", &priv->max9271_addr) &&
++ !of_property_read_u32(rendpoint->parent->parent, "reg", &priv->max9286_addr) &&
++ !kstrtouint(strrchr(rendpoint->full_name, '@') + 1, 0, &priv->port))
++ break;
++ }
++
++ of_node_put(endpoint);
++
++ if (!priv->max9286_addr) {
++ dev_err(&client->dev, "deserializer does not present\n");
++ return -EINVAL;
++ }
++
++ ar0231_s_port(client, 1);
++
++ /* setup I2C translator address */
++ tmp_addr = client->addr;
++ if (priv->max9286_addr) {
++ client->addr = priv->max9271_addr; /* Serializer I2C address */
++
++ reg8_write(client, 0x09, tmp_addr << 1); /* Sensor translated I2C address */
++ reg8_write(client, 0x0A, AR0231_I2C_ADDR << 1); /* Sensor native I2C address */
++ usleep_range(2000, 2500); /* wait 2ms */
++ };
++ client->addr = tmp_addr;
++
++ mdelay(10);
++
++ return 0;
++}
++
++static int ar0231_probe(struct i2c_client *client,
++ const struct i2c_device_id *did)
++{
++ struct ar0231_priv *priv;
++ int ret;
++
++ priv = devm_kzalloc(&client->dev, sizeof(*priv), GFP_KERNEL);
++ if (!priv)
++ return -ENOMEM;
++
++ v4l2_i2c_subdev_init(&priv->sd, client, &ar0231_subdev_ops);
++ priv->sd.flags = V4L2_SUBDEV_FL_HAS_DEVNODE;
++
++ v4l2_ctrl_handler_init(&priv->hdl, 4);
++ v4l2_ctrl_new_std(&priv->hdl, &ar0231_ctrl_ops,
++ V4L2_CID_BRIGHTNESS, 0, 16, 1, 7);
++ v4l2_ctrl_new_std(&priv->hdl, &ar0231_ctrl_ops,
++ V4L2_CID_CONTRAST, 0, 16, 1, 7);
++ v4l2_ctrl_new_std(&priv->hdl, &ar0231_ctrl_ops,
++ V4L2_CID_SATURATION, 0, 7, 1, 2);
++ v4l2_ctrl_new_std(&priv->hdl, &ar0231_ctrl_ops,
++ V4L2_CID_HUE, 0, 23, 1, 12);
++ v4l2_ctrl_new_std(&priv->hdl, &ar0231_ctrl_ops,
++ V4L2_CID_GAMMA, -128, 128, 1, 0);
++ v4l2_ctrl_new_std(&priv->hdl, &ar0231_ctrl_ops,
++ V4L2_CID_SHARPNESS, 0, 10, 1, 3);
++ v4l2_ctrl_new_std(&priv->hdl, &ar0231_ctrl_ops,
++ V4L2_CID_AUTOGAIN, 0, 1, 1, 0);
++ v4l2_ctrl_new_std(&priv->hdl, &ar0231_ctrl_ops,
++ V4L2_CID_GAIN, 1, 0x7ff, 1, 0x200);
++ v4l2_ctrl_new_std(&priv->hdl, &ar0231_ctrl_ops,
++ V4L2_CID_ANALOGUE_GAIN, 1, 0xe, 1, 0xa);
++ v4l2_ctrl_new_std(&priv->hdl, &ar0231_ctrl_ops,
++ V4L2_CID_EXPOSURE, 1, 0x600, 1, 0x144);
++ v4l2_ctrl_new_std(&priv->hdl, &ar0231_ctrl_ops,
++ V4L2_CID_HFLIP, 0, 1, 1, 0);
++ v4l2_ctrl_new_std(&priv->hdl, &ar0231_ctrl_ops,
++ V4L2_CID_VFLIP, 0, 1, 1, 0);
++ priv->sd.ctrl_handler = &priv->hdl;
++
++ ret = priv->hdl.error;
++ if (ret)
++ goto cleanup;
++
++ v4l2_ctrl_handler_setup(&priv->hdl);
++
++ priv->pad.flags = MEDIA_PAD_FL_SOURCE;
++ priv->sd.entity.flags |= MEDIA_ENT_F_CAM_SENSOR;
++ ret = media_entity_pads_init(&priv->sd.entity, 1, &priv->pad);
++ if (ret < 0)
++ goto cleanup;
++
++ ret = ar0231_parse_dt(client->dev.of_node, priv);
++ if (ret)
++ goto cleanup;
++
++ ret = ar0231_initialize(client);
++ if (ret < 0)
++ goto cleanup;
++
++ priv->rect.left = 0;
++ priv->rect.top = 0;
++ priv->rect.width = AR0231_MAX_WIDTH;
++ priv->rect.height = AR0231_MAX_HEIGHT;
++
++ ret = v4l2_async_register_subdev(&priv->sd);
++ if (ret)
++ goto cleanup;
++
++ if (device_create_file(&client->dev, &dev_attr_otp_id_ar0231) != 0) {
++ dev_err(&client->dev, "sysfs otp_id entry creation failed\n");
++ goto cleanup;
++ }
++
++ priv->init_complete = 1;
++
++ return 0;
++
++cleanup:
++ media_entity_cleanup(&priv->sd.entity);
++ v4l2_ctrl_handler_free(&priv->hdl);
++ v4l2_device_unregister_subdev(&priv->sd);
++#ifdef CONFIG_SOC_CAMERA_AR0231
++ v4l_err(client, "failed to probe @ 0x%02x (%s)\n",
++ client->addr, client->adapter->name);
++#endif
++ return ret;
++}
++
++static int ar0231_remove(struct i2c_client *client)
++{
++ struct ar0231_priv *priv = i2c_get_clientdata(client);
++
++ device_remove_file(&client->dev, &dev_attr_otp_id_ar0231);
++ v4l2_async_unregister_subdev(&priv->sd);
++ media_entity_cleanup(&priv->sd.entity);
++ v4l2_ctrl_handler_free(&priv->hdl);
++ v4l2_device_unregister_subdev(&priv->sd);
++
++ return 0;
++}
++
++#ifdef CONFIG_SOC_CAMERA_AR0231
++static const struct i2c_device_id ar0231_id[] = {
++ { "ar0231", 0 },
++ { }
++};
++MODULE_DEVICE_TABLE(i2c, ar0231_id);
++
++static const struct of_device_id ar0231_of_ids[] = {
++ { .compatible = "aptina,ar0231", },
++ { }
++};
++MODULE_DEVICE_TABLE(of, ar0231_of_ids);
++
++static struct i2c_driver ar0231_i2c_driver = {
++ .driver = {
++ .name = "ar0231",
++ .of_match_table = ar0231_of_ids,
++ },
++ .probe = ar0231_probe,
++ .remove = ar0231_remove,
++ .id_table = ar0231_id,
++};
++
++module_i2c_driver(ar0231_i2c_driver);
++
++MODULE_DESCRIPTION("SoC Camera driver for AR0231");
++MODULE_AUTHOR("Vladimir Barinov");
++MODULE_LICENSE("GPL");
++#endif
+diff --git a/drivers/media/i2c/soc_camera/ar0231.h b/drivers/media/i2c/soc_camera/ar0231.h
+new file mode 100644
+index 0000000..b63dc91
+--- /dev/null
++++ b/drivers/media/i2c/soc_camera/ar0231.h
+@@ -0,0 +1,34 @@
++/*
++ * ON Semiconductor AR0231 sensor camera wizard 1928x1208@30/BGGR/BT601
++ *
++ * Copyright (C) 2018 Cogent Embedded, Inc.
++ *
++ * This program is free software; you can redistribute it and/or modify it
++ * under the terms of the GNU General Public License as published by the
++ * Free Software Foundation; either version 2 of the License, or (at your
++ * option) any later version.
++ */
++
++//#define AR0231_DISPLAY_PATTERN_FIXED
++//#define AR0231_DISPLAY_PATTERN_COLOR_BAR
++
++#define AR0231_MAX_WIDTH 1928
++#define AR0231_MAX_HEIGHT 1208
++
++#define AR0231_DELAY 0xffff
++
++#define AR0231_SENSOR_WIDTH 1928
++#define AR0231_SENSOR_HEIGHT 1208
++
++#define AR0231_X_START ((AR0231_SENSOR_WIDTH - AR0231_MAX_WIDTH) / 2)
++#define AR0231_Y_START ((AR0231_SENSOR_HEIGHT - AR0231_MAX_HEIGHT) / 2)
++#define AR0231_X_END (AR0231_X_START + AR0231_MAX_WIDTH - 1)
++#define AR0231_Y_END (AR0231_Y_START + AR0231_MAX_HEIGHT - 1)
++
++struct ar0231_reg {
++ u16 reg;
++ u16 val;
++};
++
++#include "ar0231_rev4.h"
++//#include "ar0231_rev6.h"
+diff --git a/drivers/media/i2c/soc_camera/ar0231_rev4.h b/drivers/media/i2c/soc_camera/ar0231_rev4.h
+new file mode 100644
+index 0000000..d4614ec
+--- /dev/null
++++ b/drivers/media/i2c/soc_camera/ar0231_rev4.h
+@@ -0,0 +1,348 @@
++/*
++ * ON Semiconductor AR0231 sensor camera wizard 1920x1080@30/BGGR/MIPI
++ *
++ * Copyright (C) 2018 Cogent Embedded, Inc.
++ *
++ * This program is free software; you can redistribute it and/or modify it
++ * under the terms of the GNU General Public License as published by the
++ * Free Software Foundation; either version 2 of the License, or (at your
++ * option) any later version.
++ */
++
++static const struct ar0231_reg ar0231_regs_wizard_rev4[] = {
++{0x301A, 0x0001}, // reset
++{0x301A, 0x10D8}, // Stream off and setup parallel
++{0x3070, 0x0000}, // 1: Solid color test pattern,
++ // 2: Full color bar test pattern,
++ // 3: Fade to grey color bar test pattern,
++ //256: Walking 1 test pattern (12 bit)
++{0x3072, 0x0123}, // R
++{0x3074, 0x0456}, // G(GR row)
++{0x3076, 0x0abc}, // B
++{0x3078, 0x0def}, // G(GB row)
++#ifdef AR0231_DISPLAY_PATTERN_FIXED
++{0x3070, 0x0001},
++#endif
++#ifdef AR0231_DISPLAY_PATTERN_COLOR_BAR
++{0x3070, 0x0002},
++#endif
++//Recommended Settings
++{0x3366, 0x6666}, // ANALOG_GAIN
++{0x3056, 0x0080}, // GREEN1_GAIN
++{0x305C, 0x0080}, // GREEN2_GAIN
++{0x3058, 0x0080}, // BLUE_GAIN
++{0x305A, 0x0080}, // RED_GAIN
++{0x3044, 0x0400}, // DARK_CONTROL
++{0x30BA, 0x1021}, // DIGITAL_CTRL
++{0x318E, 0x0200}, // DLO_CONTROL0
++{0x32EA, 0x3C0A}, // RESERVED_MFR_32EA
++{0x32EA, 0x3C0E}, // RESERVED_MFR_32EA
++{0x3362, 0x0000}, // DC_GAIN
++{0x3364, 0x0060}, // RESERVED_MFR_3364
++{0x3370, 0x0231}, // DBLC_CONTROL
++{0x3372, 0x700F}, // RESERVED_MFR_3372
++{0x3386, 0x0000}, // RESERVED_MFR_3386
++{0x3C04, 0x0E80}, // RESERVED_MFR_3C04
++{0x3F90, 0x06E1}, // TEMPVSENS0_TMG_CTRL
++{0x3F92, 0x06E1}, // TEMPVSENS1_TMG_CTRL
++{0x3502, 0x0808}, // RESERVED_MFR_3502
++{0x3502, 0x0808}, // RESERVED_MFR_3502
++{0x350E, 0xFF10}, // RESERVED_MFR_350E
++{0x3506, 0x4444}, // RESERVED_MFR_3506
++{0x3508, 0x4444}, // RESERVED_MFR_3508
++{0x350A, 0x4465}, // RESERVED_MFR_350A
++{0x350C, 0x055F}, // RESERVED_MFR_350C
++{0x3230, 0x0317}, // FINE_CORRECTION
++{0x3232, 0x0552}, // FINE_CORRECTION2
++{0x3234, 0x078D}, // FINE_CORRECTION3
++{0x3566, 0x9D38}, // RESERVED_MFR_3566
++{0x3518, 0x1FFE}, // RESERVED_MFR_3518
++{0x3520, 0xC688}, // RESERVED_MFR_3520
++{0x3522, 0x88C0}, // RESERVED_MFR_3522
++{0x3524, 0xC0C6}, // RESERVED_MFR_3524
++{0x352C, 0xC6C6}, // RESERVED_MFR_352C
++{0x3528, 0x0900}, // RESERVED_MFR_3528
++{0x3528, 0x9900}, // RESERVED_MFR_3528
++{0x3528, 0x9909}, // RESERVED_MFR_3528
++{0x3528, 0x9999}, // RESERVED_MFR_3528
++{0x352A, 0x081F}, // RESERVED_MFR_352A
++{0x352E, 0x0001}, // RESERVED_MFR_352E
++{0x352E, 0x0011}, // RESERVED_MFR_352E
++{0x3530, 0x0400}, // RESERVED_MFR_3530
++{0x3530, 0x4400}, // RESERVED_MFR_3530
++{0x3536, 0xFF00}, // RESERVED_MFR_3536
++{0x3536, 0xFF00}, // RESERVED_MFR_3536
++{0x3536, 0xFF00}, // RESERVED_MFR_3536
++{0x3536, 0xFF00}, // RESERVED_MFR_3536
++{0x3536, 0xFF00}, // RESERVED_MFR_3536
++{0x3536, 0xFF00}, // RESERVED_MFR_3536
++{0x3536, 0xFF00}, // RESERVED_MFR_3536
++{0x3536, 0xFF00}, // RESERVED_MFR_3536
++{0x3536, 0xFF02}, // RESERVED_MFR_3536
++{0x3536, 0xFF06}, // RESERVED_MFR_3536
++{0x3536, 0xFF06}, // RESERVED_MFR_3536
++{0x3538, 0xFFFF}, // RESERVED_MFR_3538
++{0x3538, 0xFFFF}, // RESERVED_MFR_3538
++{0x3538, 0xFFFF}, // RESERVED_MFR_3538
++{0x3538, 0xFFFF}, // RESERVED_MFR_3538
++{0x3538, 0xFFFF}, // RESERVED_MFR_3538
++{0x3538, 0xFFFF}, // RESERVED_MFR_3538
++{0x3538, 0xFFFF}, // RESERVED_MFR_3538
++{0x3538, 0xFFFF}, // RESERVED_MFR_3538
++{0x3538, 0xFFFF}, // RESERVED_MFR_3538
++{0x3538, 0xFFFF}, // RESERVED_MFR_3538
++{0x353A, 0x9000}, // RESERVED_MFR_353A
++{0x353C, 0x3F00}, // RESERVED_MFR_353C
++{0x353C, 0x3F00}, // RESERVED_MFR_353C
++{0x353C, 0x3F00}, // RESERVED_MFR_353C
++{0x353C, 0x3F00}, // RESERVED_MFR_353C
++{0x353C, 0x3F00}, // RESERVED_MFR_353C
++{0x353C, 0x3F00}, // RESERVED_MFR_353C
++{0x32EC, 0x72A1}, // RESERVED_MFR_32EC
++{0x3540, 0xC637}, // RESERVED_MFR_3540
++{0x3540, 0xC637}, // RESERVED_MFR_3540
++{0x3540, 0xC637}, // RESERVED_MFR_3540
++{0x3542, 0x584B}, // RESERVED_MFR_3542
++{0x3542, 0x464B}, // RESERVED_MFR_3542
++{0x3544, 0x565A}, // RESERVED_MFR_3544
++{0x3544, 0x4B5A}, // RESERVED_MFR_3544
++{0x3546, 0x545A}, // RESERVED_MFR_3546
++{0x3546, 0x5A5A}, // RESERVED_MFR_3546
++{0x3548, 0x6430}, // RESERVED_MFR_3548
++{0x3556, 0x101F}, // RESERVED_MFR_3556
++{0x3566, 0x9D38}, // RESERVED_MFR_3566
++{0x3566, 0x1D38}, // RESERVED_MFR_3566
++{0x3566, 0x1D28}, // RESERVED_MFR_3566
++{0x3566, 0x1128}, // RESERVED_MFR_3566
++{0x3566, 0x1328}, // RESERVED_MFR_3566
++{0x3566, 0x3328}, // RESERVED_MFR_3566
++//Sequencer Update
++{0x2512, 0x8000}, // SEQ_CTRL_PORT
++{0x2510, 0x0905}, // SEQ_DATA_PORT
++{0x2510, 0x3350}, // SEQ_DATA_PORT
++{0x2510, 0x2004}, // SEQ_DATA_PORT
++{0x2510, 0x1460}, // SEQ_DATA_PORT
++{0x2510, 0x1578}, // SEQ_DATA_PORT
++{0x2510, 0x1360}, // SEQ_DATA_PORT
++{0x2510, 0x7B24}, // SEQ_DATA_PORT
++{0x2510, 0xFF24}, // SEQ_DATA_PORT
++{0x2510, 0xFF24}, // SEQ_DATA_PORT
++{0x2510, 0xEA24}, // SEQ_DATA_PORT
++{0x2510, 0x1022}, // SEQ_DATA_PORT
++{0x2510, 0x2410}, // SEQ_DATA_PORT
++{0x2510, 0x155A}, // SEQ_DATA_PORT
++{0x2510, 0x1342}, // SEQ_DATA_PORT
++{0x2510, 0x1400}, // SEQ_DATA_PORT
++{0x2510, 0x24FF}, // SEQ_DATA_PORT
++{0x2510, 0x24FF}, // SEQ_DATA_PORT
++{0x2510, 0x24EA}, // SEQ_DATA_PORT
++{0x2510, 0x2324}, // SEQ_DATA_PORT
++{0x2510, 0x647A}, // SEQ_DATA_PORT
++{0x2510, 0x2404}, // SEQ_DATA_PORT
++{0x2510, 0x052C}, // SEQ_DATA_PORT
++{0x2510, 0x400A}, // SEQ_DATA_PORT
++{0x2510, 0xFF0A}, // SEQ_DATA_PORT
++{0x2510, 0xFF0A}, // SEQ_DATA_PORT
++{0x2510, 0x0408}, // SEQ_DATA_PORT
++{0x2510, 0x3851}, // SEQ_DATA_PORT
++{0x2510, 0x1440}, // SEQ_DATA_PORT
++{0x2510, 0x0004}, // SEQ_DATA_PORT
++{0x2510, 0x0801}, // SEQ_DATA_PORT
++{0x2510, 0x0408}, // SEQ_DATA_PORT
++{0x2510, 0x1180}, // SEQ_DATA_PORT
++{0x2510, 0x15DC}, // SEQ_DATA_PORT
++{0x2510, 0x134C}, // SEQ_DATA_PORT
++{0x2510, 0x1002}, // SEQ_DATA_PORT
++{0x2510, 0x1016}, // SEQ_DATA_PORT
++{0x2510, 0x1181}, // SEQ_DATA_PORT
++{0x2510, 0x1189}, // SEQ_DATA_PORT
++{0x2510, 0x1056}, // SEQ_DATA_PORT
++{0x2510, 0x1210}, // SEQ_DATA_PORT
++{0x2510, 0x0901}, // SEQ_DATA_PORT
++{0x2510, 0x0D08}, // SEQ_DATA_PORT
++{0x2510, 0x0913}, // SEQ_DATA_PORT
++{0x2510, 0x13C8}, // SEQ_DATA_PORT
++{0x2510, 0x092B}, // SEQ_DATA_PORT
++{0x2510, 0x1588}, // SEQ_DATA_PORT
++{0x2510, 0x1388}, // SEQ_DATA_PORT
++{0x2510, 0x090B}, // SEQ_DATA_PORT
++{0x2510, 0x11D9}, // SEQ_DATA_PORT
++{0x2510, 0x091D}, // SEQ_DATA_PORT
++{0x2510, 0x1441}, // SEQ_DATA_PORT
++{0x2510, 0x0903}, // SEQ_DATA_PORT
++{0x2510, 0x1214}, // SEQ_DATA_PORT
++{0x2510, 0x0901}, // SEQ_DATA_PORT
++{0x2510, 0x10D6}, // SEQ_DATA_PORT
++{0x2510, 0x1210}, // SEQ_DATA_PORT
++{0x2510, 0x1212}, // SEQ_DATA_PORT
++{0x2510, 0x1210}, // SEQ_DATA_PORT
++{0x2510, 0x11DD}, // SEQ_DATA_PORT
++{0x2510, 0x11D9}, // SEQ_DATA_PORT
++{0x2510, 0x1056}, // SEQ_DATA_PORT
++{0x2510, 0x090B}, // SEQ_DATA_PORT
++{0x2510, 0x11DB}, // SEQ_DATA_PORT
++{0x2510, 0x0915}, // SEQ_DATA_PORT
++{0x2510, 0x119B}, // SEQ_DATA_PORT
++{0x2510, 0x090F}, // SEQ_DATA_PORT
++{0x2510, 0x11BB}, // SEQ_DATA_PORT
++{0x2510, 0x121A}, // SEQ_DATA_PORT
++{0x2510, 0x1210}, // SEQ_DATA_PORT
++{0x2510, 0x1460}, // SEQ_DATA_PORT
++{0x2510, 0x1250}, // SEQ_DATA_PORT
++{0x2510, 0x1076}, // SEQ_DATA_PORT
++{0x2510, 0x10E6}, // SEQ_DATA_PORT
++{0x2510, 0x0901}, // SEQ_DATA_PORT
++{0x2510, 0x15AB}, // SEQ_DATA_PORT
++{0x2510, 0x0901}, // SEQ_DATA_PORT
++{0x2510, 0x13A8}, // SEQ_DATA_PORT
++{0x2510, 0x1240}, // SEQ_DATA_PORT
++{0x2510, 0x1260}, // SEQ_DATA_PORT
++{0x2510, 0x0923}, // SEQ_DATA_PORT
++{0x2510, 0x158D}, // SEQ_DATA_PORT
++{0x2510, 0x138D}, // SEQ_DATA_PORT
++{0x2510, 0x0901}, // SEQ_DATA_PORT
++{0x2510, 0x0B09}, // SEQ_DATA_PORT
++{0x2510, 0x0108}, // SEQ_DATA_PORT
++{0x2510, 0x0901}, // SEQ_DATA_PORT
++{0x2510, 0x1440}, // SEQ_DATA_PORT
++{0x2510, 0x091D}, // SEQ_DATA_PORT
++{0x2510, 0x1588}, // SEQ_DATA_PORT
++{0x2510, 0x1388}, // SEQ_DATA_PORT
++{0x2510, 0x092D}, // SEQ_DATA_PORT
++{0x2510, 0x1066}, // SEQ_DATA_PORT
++{0x2510, 0x0905}, // SEQ_DATA_PORT
++{0x2510, 0x0C08}, // SEQ_DATA_PORT
++{0x2510, 0x090B}, // SEQ_DATA_PORT
++{0x2510, 0x1441}, // SEQ_DATA_PORT
++{0x2510, 0x090D}, // SEQ_DATA_PORT
++{0x2510, 0x10E6}, // SEQ_DATA_PORT
++{0x2510, 0x0901}, // SEQ_DATA_PORT
++{0x2510, 0x1262}, // SEQ_DATA_PORT
++{0x2510, 0x1260}, // SEQ_DATA_PORT
++{0x2510, 0x11BF}, // SEQ_DATA_PORT
++{0x2510, 0x11BB}, // SEQ_DATA_PORT
++{0x2510, 0x1066}, // SEQ_DATA_PORT
++{0x2510, 0x11FB}, // SEQ_DATA_PORT
++{0x2510, 0x0935}, // SEQ_DATA_PORT
++{0x2510, 0x11BB}, // SEQ_DATA_PORT
++{0x2510, 0x1263}, // SEQ_DATA_PORT
++{0x2510, 0x1260}, // SEQ_DATA_PORT
++{0x2510, 0x1400}, // SEQ_DATA_PORT
++{0x2510, 0x1510}, // SEQ_DATA_PORT
++{0x2510, 0x11B8}, // SEQ_DATA_PORT
++{0x2510, 0x12A0}, // SEQ_DATA_PORT
++{0x2510, 0x1200}, // SEQ_DATA_PORT
++{0x2510, 0x1026}, // SEQ_DATA_PORT
++{0x2510, 0x1000}, // SEQ_DATA_PORT
++{0x2510, 0x1342}, // SEQ_DATA_PORT
++{0x2510, 0x1100}, // SEQ_DATA_PORT
++{0x2510, 0x7A06}, // SEQ_DATA_PORT
++{0x2510, 0x0926}, // SEQ_DATA_PORT
++{0x2510, 0x0507}, // SEQ_DATA_PORT
++{0x2510, 0x0841}, // SEQ_DATA_PORT
++{0x2510, 0x3750}, // SEQ_DATA_PORT
++{0x2510, 0x2C2C}, // SEQ_DATA_PORT
++{0x2510, 0xFE02}, // SEQ_DATA_PORT
++{0x2510, 0xFE14}, // SEQ_DATA_PORT
++{0x3566, 0x3328}, // RESERVED_MFR_3566
++{0x350C, 0x055F}, // RESERVED_MFR_350C
++{0x32D0, 0x3A02}, // RESERVED_MFR_32D0
++{0x32D2, 0x3508}, // RESERVED_MFR_32D2
++{0x32D4, 0x3702}, // RESERVED_MFR_32D4
++{0x32D6, 0x3C04}, // RESERVED_MFR_32D6
++{0x32DC, 0x370A}, // RESERVED_MFR_32DC
++//Parallel Timing Setup
++{0x302A, 0x0009}, // VT_PIX_CLK_DIV
++{0x302C, 0x0001}, // VT_SYS_CLK_DIV
++{0x302E, 0x0003}, // PRE_PLL_CLK_DIV
++{0x3030, 0x0058}, // PLL_MULTIPLIER
++{0x3036, 0x0008}, // OP_WORD_CLK_DIV
++{0x3038, 0x0001}, // OP_SYS_CLK_DIV
++{0x30B0, 0x0A00}, // DIGITAL_TEST
++//Readout Mode Configuration
++{0x30A2, 0x0001}, // X_ODD_INC_
++{0x30A6, 0x0001}, // Y_ODD_INC_
++{0x3040, 0x0000}, // READ_MODE
++{0x3044, 0x0400}, // DARK_CONTROL
++{0x33E0, 0x0880}, // RESERVED_MFR_33E0
++{0x3180, 0x0080}, // RESERVED_MFR_3180
++{0x33E4, 0x0080}, // RESERVED_MFR_33E4
++
++//HDR Readout Mode Configuration
++#ifdef AR0231_EMBEDDED_LINE
++{0x3064, 0x1982}, // SMIA_TEST
++#else
++{0x3064, 0x1802}, // SMIA_TEST
++#endif
++
++#if 1
++{0x3004, AR0231_X_START}, // X_ADDR_START_
++{0x3008, AR0231_X_END}, // X_ADDR_END_
++{0x3002, AR0231_Y_START}, // Y_ADDR_START_
++{0x3006, AR0231_Y_END}, // Y_ADDR_END_
++{0x3402, 0x0000 | AR0231_MAX_WIDTH}, // X_OUTPUT_CONTROL
++{0x3404, 0x0000 | AR0231_MAX_HEIGHT}, // Y_OUTPUT_CONTROL
++#else
++{0x3004, 0}, // X_ADDR_START_
++{0x3008, 0x0787}, // X_ADDR_END_
++{0x3002, 0x0000}, // Y_ADDR_START_
++{0x3006, 0x04B7}, // Y_ADDR_END_
++{0x3402, 0x0788}, // RESERVED_MFR_3402
++{0x3402, 0x0F10}, // RESERVED_MFR_3402
++{0x3404, 0x0440}, // RESERVED_MFR_3404
++{0x3404, 0x0970}, // RESERVED_MFR_3404
++#endif
++{0x3032, 0x0000}, // SCALING_MODE
++{0x3400, 0x0010}, // RESERVED_MFR_3400
++
++//3exp Timing and Exposure
++{0x3082, 0x0008}, // OPERATION_MODE_CTRL
++{0x30BA, 0x11E2}, // DIGITAL_CTRL
++
++//Row and Pixel Timing
++{0x300A, 0x5af},
++{0x300C, 0x7ba},
++
++//Exposure Settings
++{0x3042, 0x0000}, // EXTRA_DELAY
++{0x3238, 0x0222}, // EXPOSURE_RATIO
++{0x1008, 0x0374}, // FINE_INTEGRATION_TIME_MIN
++{0x100C, 0x05AF}, // FINE_INTEGRATION_TIME2_MIN
++{0x100E, 0x07EA}, // FINE_INTEGRATION_TIME3_MIN
++{0x1010, 0x0139}, // FINE_INTEGRATION_TIME4_MIN
++{0x3012, 0x0163}, // COARSE_INTEGRATION_TIME_
++{0x3014, 0x06A6}, // FINE_INTEGRATION_TIME_
++{0x321E, 0x06A6}, // FINE_INTEGRATION_TIME2
++{0x3222, 0x06A6}, // FINE_INTEGRATION_TIME3
++{0x30B0, 0x0B02}, // DIGITAL_TEST
++
++{0x32EA, 0x3C0E}, // RESERVED_MFR_32EA
++{0x32EC, 0x72A1}, // RESERVED_MFR_32EC
++//Parallel HDR 12 bit Output
++{0x31D0, 0x0001}, // COMPANDING
++{0x31AC, 0x140C}, // DATA_FORMAT_BITS
++
++//{0x301A, 0x01d8}, // RESET_REGISTER
++{0x301A, 0x01dc}, // RESET_REGISTER - stream on
++
++//{AR0231_DELAY, 100}, // Wait 100ms
++
++#if 0 // no need for front only camera
++/* Enable trigger input */
++{0x340A, 0x00E0}, // GPIO_CONTROL1: GPIO1 is trigger
++{0x340C, 0x0002}, // GPIO_CONTROL2: GPIO1 is trigger
++{0x30CE, 0x0120}, // TRIGGER_MODE
++//{0x30DC, 0x0120}, // TRIGGER_DELAY
++#endif
++
++#define NEW_TIMINGS
++#ifdef NEW_TIMINGS
++/* the sequence must be updated to use following timings, now it is a hack */
++{0x300A, AR0231_SENSOR_HEIGHT + 225}, // FRAME_LENGTH_LINES_
++{0x300C, AR0231_SENSOR_WIDTH + 120}, // LINE_LENGTH_PCK_
++{0x1008, 0x0fff}, // FINE_INTEGRATION_TIME_MIN
++{0x100C, 0x0fff}, // FINE_INTEGRATION_TIME2_MIN
++{0x100E, 0x0fff}, // FINE_INTEGRATION_TIME3_MIN
++{0x1010, 0x0fff}, // FINE_INTEGRATION_TIME4_MIN
++#endif
++};
+diff --git a/drivers/media/i2c/soc_camera/ar0233.c b/drivers/media/i2c/soc_camera/ar0233.c
+new file mode 100644
+index 0000000..6d034e2
+--- /dev/null
++++ b/drivers/media/i2c/soc_camera/ar0233.c
+@@ -0,0 +1,579 @@
++/*
++ * ON Semiconductor AR0233 sensor camera driver
++ *
++ * Copyright (C) 2018 Cogent Embedded, Inc.
++ *
++ * This program is free software; you can redistribute it and/or modify it
++ * under the terms of the GNU General Public License as published by the
++ * Free Software Foundation; either version 2 of the License, or (at your
++ * option) any later version.
++ */
++
++#include <linux/delay.h>
++#include <linux/init.h>
++#include <linux/i2c.h>
++#include <linux/module.h>
++#include <linux/of_graph.h>
++#include <linux/videodev2.h>
++
++#include <media/soc_camera.h>
++#include <media/v4l2-common.h>
++#include <media/v4l2-ctrls.h>
++
++#include "ar0233.h"
++
++#define AR0233_I2C_ADDR 0x10
++
++#define AR0233_PID 0x3000
++#define AR0233_VERSION_REG 0x0354
++
++#define AR0233_MEDIA_BUS_FMT MEDIA_BUS_FMT_SGRBG12_1X12
++
++struct ar0233_priv {
++ struct v4l2_subdev sd;
++ struct v4l2_ctrl_handler hdl;
++ struct media_pad pad;
++ struct v4l2_rect rect;
++ int init_complete;
++ u8 id[6];
++ /* serializers */
++ int ti9x4_addr;
++ int ti9x3_addr;
++ int port;
++ int gpio_resetb;
++ int gpio_fsin;
++};
++
++static inline struct ar0233_priv *to_ar0233(const struct i2c_client *client)
++{
++ return container_of(i2c_get_clientdata(client), struct ar0233_priv, sd);
++}
++
++static int ar0233_set_regs(struct i2c_client *client,
++ const struct ar0233_reg *regs, int nr_regs)
++{
++ int i;
++
++ for (i = 0; i < nr_regs; i++) {
++ if (regs[i].reg == AR0233_DELAY) {
++ mdelay(regs[i].val);
++ continue;
++ }
++
++ reg16_write16(client, regs[i].reg, regs[i].val);
++ }
++
++ return 0;
++}
++
++static int ar0233_s_stream(struct v4l2_subdev *sd, int enable)
++{
++ return 0;
++}
++
++static int ar0233_get_fmt(struct v4l2_subdev *sd,
++ struct v4l2_subdev_pad_config *cfg,
++ struct v4l2_subdev_format *format)
++{
++ struct v4l2_mbus_framefmt *mf = &format->format;
++ struct i2c_client *client = v4l2_get_subdevdata(sd);
++ struct ar0233_priv *priv = to_ar0233(client);
++
++ if (format->pad)
++ return -EINVAL;
++
++ mf->width = priv->rect.width;
++ mf->height = priv->rect.height;
++ mf->code = AR0233_MEDIA_BUS_FMT;
++ mf->colorspace = V4L2_COLORSPACE_SMPTE170M;
++ mf->field = V4L2_FIELD_NONE;
++
++ return 0;
++}
++
++static int ar0233_set_fmt(struct v4l2_subdev *sd,
++ struct v4l2_subdev_pad_config *cfg,
++ struct v4l2_subdev_format *format)
++{
++ struct v4l2_mbus_framefmt *mf = &format->format;
++
++ mf->code = AR0233_MEDIA_BUS_FMT;
++ mf->colorspace = V4L2_COLORSPACE_SMPTE170M;
++ mf->field = V4L2_FIELD_NONE;
++
++ if (format->which == V4L2_SUBDEV_FORMAT_TRY)
++ cfg->try_fmt = *mf;
++
++ return 0;
++}
++
++static int ar0233_enum_mbus_code(struct v4l2_subdev *sd,
++ struct v4l2_subdev_pad_config *cfg,
++ struct v4l2_subdev_mbus_code_enum *code)
++{
++ if (code->pad || code->index > 0)
++ return -EINVAL;
++
++ code->code = AR0233_MEDIA_BUS_FMT;
++
++ return 0;
++}
++
++static int ar0233_get_edid(struct v4l2_subdev *sd, struct v4l2_edid *edid)
++{
++ struct i2c_client *client = v4l2_get_subdevdata(sd);
++ struct ar0233_priv *priv = to_ar0233(client);
++
++ memcpy(edid->edid, priv->id, 6);
++
++ edid->edid[6] = 0xff;
++ edid->edid[7] = client->addr;
++ edid->edid[8] = AR0233_VERSION_REG >> 8;
++ edid->edid[9] = AR0233_VERSION_REG & 0xff;
++
++ return 0;
++}
++
++static int ar0233_set_selection(struct v4l2_subdev *sd,
++ struct v4l2_subdev_pad_config *cfg,
++ struct v4l2_subdev_selection *sel)
++{
++ struct v4l2_rect *rect = &sel->r;
++ struct i2c_client *client = v4l2_get_subdevdata(sd);
++ struct ar0233_priv *priv = to_ar0233(client);
++
++ if (sel->which != V4L2_SUBDEV_FORMAT_ACTIVE ||
++ sel->target != V4L2_SEL_TGT_CROP)
++ return -EINVAL;
++
++ rect->left = ALIGN(rect->left, 2);
++ rect->top = ALIGN(rect->top, 2);
++ rect->width = ALIGN(rect->width, 2);
++ rect->height = ALIGN(rect->height, 2);
++
++ if ((rect->left + rect->width > AR0233_MAX_WIDTH) ||
++ (rect->top + rect->height > AR0233_MAX_HEIGHT))
++ *rect = priv->rect;
++
++ priv->rect.left = rect->left;
++ priv->rect.top = rect->top;
++ priv->rect.width = rect->width;
++ priv->rect.height = rect->height;
++
++ return 0;
++}
++
++static int ar0233_get_selection(struct v4l2_subdev *sd,
++ struct v4l2_subdev_pad_config *cfg,
++ struct v4l2_subdev_selection *sel)
++{
++ struct i2c_client *client = v4l2_get_subdevdata(sd);
++ struct ar0233_priv *priv = to_ar0233(client);
++
++ if (sel->which != V4L2_SUBDEV_FORMAT_ACTIVE)
++ return -EINVAL;
++
++ switch (sel->target) {
++ case V4L2_SEL_TGT_CROP_BOUNDS:
++ sel->r.left = 0;
++ sel->r.top = 0;
++ sel->r.width = AR0233_MAX_WIDTH;
++ sel->r.height = AR0233_MAX_HEIGHT;
++ return 0;
++ case V4L2_SEL_TGT_CROP_DEFAULT:
++ sel->r.left = 0;
++ sel->r.top = 0;
++ sel->r.width = AR0233_MAX_WIDTH;
++ sel->r.height = AR0233_MAX_HEIGHT;
++ return 0;
++ case V4L2_SEL_TGT_CROP:
++ sel->r = priv->rect;
++ return 0;
++ default:
++ return -EINVAL;
++ }
++}
++
++static int ar0233_g_mbus_config(struct v4l2_subdev *sd,
++ struct v4l2_mbus_config *cfg)
++{
++ cfg->flags = V4L2_MBUS_CSI2_1_LANE | V4L2_MBUS_CSI2_CHANNEL_0 |
++ V4L2_MBUS_CSI2_CONTINUOUS_CLOCK;
++ cfg->type = V4L2_MBUS_CSI2;
++
++ return 0;
++}
++
++#ifdef CONFIG_VIDEO_ADV_DEBUG
++static int ar0233_g_register(struct v4l2_subdev *sd,
++ struct v4l2_dbg_register *reg)
++{
++ struct i2c_client *client = v4l2_get_subdevdata(sd);
++ int ret;
++ u16 val = 0;
++
++ ret = reg16_read16(client, (u16)reg->reg, &val);
++ if (ret < 0)
++ return ret;
++
++ reg->val = val;
++ reg->size = sizeof(u16);
++
++ return 0;
++}
++
++static int ar0233_s_register(struct v4l2_subdev *sd,
++ const struct v4l2_dbg_register *reg)
++{
++ struct i2c_client *client = v4l2_get_subdevdata(sd);
++
++ return reg16_write16(client, (u16)reg->reg, (u16)reg->val);
++}
++#endif
++
++static struct v4l2_subdev_core_ops ar0233_core_ops = {
++#ifdef CONFIG_VIDEO_ADV_DEBUG
++ .g_register = ar0233_g_register,
++ .s_register = ar0233_s_register,
++#endif
++};
++
++static int ar0233_s_ctrl(struct v4l2_ctrl *ctrl)
++{
++ struct v4l2_subdev *sd = to_sd(ctrl);
++ struct i2c_client *client = v4l2_get_subdevdata(sd);
++ struct ar0233_priv *priv = to_ar0233(client);
++ int ret = -EINVAL;
++ u16 val = 0;
++
++ if (!priv->init_complete)
++ return 0;
++
++ switch (ctrl->id) {
++ case V4L2_CID_BRIGHTNESS:
++ case V4L2_CID_CONTRAST:
++ case V4L2_CID_SATURATION:
++ case V4L2_CID_HUE:
++ case V4L2_CID_GAMMA:
++ case V4L2_CID_SHARPNESS:
++ case V4L2_CID_AUTOGAIN:
++ break;
++ case V4L2_CID_GAIN:
++ /* Digital gain */
++ ret = reg16_write16(client, 0x3308, ctrl->val);
++ break;
++ case V4L2_CID_ANALOGUE_GAIN:
++ /* Analog gain */
++ ret = reg16_write16(client, 0x3366, (ctrl->val << 8) | (ctrl->val << 4) | ctrl->val);
++ break;
++ case V4L2_CID_EXPOSURE:
++ /* T1 exposure */
++ ret = reg16_write16(client, 0x3012, ctrl->val);
++ break;
++ case V4L2_CID_HFLIP:
++ ret = reg16_read16(client, 0x3040, &val);
++ if (ctrl->val)
++ val |= (1 << 14);
++ else
++ val &= ~(1 << 14);
++ ret |= reg16_write16(client, 0x3040, val);
++ break;
++ case V4L2_CID_VFLIP:
++ ret = reg16_read16(client, 0x3040, &val);
++ if (ctrl->val)
++ val |= (1 << 15);
++ else
++ val &= ~(1 << 15);
++ ret |= reg16_write16(client, 0x3040, val);
++ break;
++ case V4L2_CID_MIN_BUFFERS_FOR_CAPTURE:
++ ret = 0;
++ break;
++ }
++
++ return ret;
++}
++
++static const struct v4l2_ctrl_ops ar0233_ctrl_ops = {
++ .s_ctrl = ar0233_s_ctrl,
++};
++
++static struct v4l2_subdev_video_ops ar0233_video_ops = {
++ .s_stream = ar0233_s_stream,
++ .g_mbus_config = ar0233_g_mbus_config,
++};
++
++static const struct v4l2_subdev_pad_ops ar0233_subdev_pad_ops = {
++ .get_edid = ar0233_get_edid,
++ .enum_mbus_code = ar0233_enum_mbus_code,
++ .get_selection = ar0233_get_selection,
++ .set_selection = ar0233_set_selection,
++ .get_fmt = ar0233_get_fmt,
++ .set_fmt = ar0233_set_fmt,
++};
++
++static struct v4l2_subdev_ops ar0233_subdev_ops = {
++ .core = &ar0233_core_ops,
++ .video = &ar0233_video_ops,
++ .pad = &ar0233_subdev_pad_ops,
++};
++
++static void ar0233_otp_id_read(struct i2c_client *client)
++{
++ struct ar0233_priv *priv = to_ar0233(client);
++ int i;
++ u16 val = 0;
++
++ /* read camera id from ar014x OTP memory */
++ reg16_write16(client, 0x3054, 0x400);
++ reg16_write16(client, 0x304a, 0x110);
++ usleep_range(25000, 25500); /* wait 25 ms */
++
++ for (i = 0; i < 6; i += 2) {
++ /* first 4 bytes are equal on all ar014x */
++ reg16_read16(client, 0x3800 + i + 4, &val);
++ priv->id[i] = val >> 8;
++ priv->id[i + 1] = val & 0xff;
++ }
++}
++
++static ssize_t ar0233_otp_id_show(struct device *dev,
++ struct device_attribute *attr, char *buf)
++{
++ struct v4l2_subdev *sd = i2c_get_clientdata(to_i2c_client(dev));
++ struct i2c_client *client = v4l2_get_subdevdata(sd);
++ struct ar0233_priv *priv = to_ar0233(client);
++
++ ar0233_otp_id_read(client);
++
++ return snprintf(buf, 32, "%02x:%02x:%02x:%02x:%02x:%02x\n",
++ priv->id[0], priv->id[1], priv->id[2], priv->id[3], priv->id[4], priv->id[5]);
++}
++
++static DEVICE_ATTR(otp_id_ar0233, S_IRUGO, ar0233_otp_id_show, NULL);
++
++static int ar0233_initialize(struct i2c_client *client)
++{
++ struct ar0233_priv *priv = to_ar0233(client);
++ u16 val = 0;
++ u16 pid = 0;
++ int ret = 0;
++ int tmp_addr;
++
++ /* check and show model ID */
++ reg16_read16(client, AR0233_PID, &pid);
++
++ if (pid != AR0233_VERSION_REG) {
++ dev_dbg(&client->dev, "Product ID error %x\n", pid);
++ ret = -ENODEV;
++ goto err;
++ }
++
++ /* setup XCLK */
++ tmp_addr = client->addr;
++ if (priv->ti9x4_addr) {
++ /* CLK_OUT=22.5792*160*M/N/CLKDIV -> CLK_OUT=27MHz: CLKDIV=2, M=15, N=251: 22.5792*160/8*15/251=26.987MHz=CLK_OUT */
++ client->addr = priv->ti9x3_addr; /* Serializer I2C address */
++ reg8_write(client, 0x06, 0x6f); /* Set CLKDIV and M */
++ reg8_write(client, 0x07, 0xfb); /* Set N */
++ reg8_write(client, 0x0e, 0x1f); /* Set FSIN GPIO to output */
++ }
++ client->addr = tmp_addr;
++
++ /* Program wizard registers */
++ ar0233_set_regs(client, ar0233_regs_wizard, ARRAY_SIZE(ar0233_regs_wizard));
++
++ /* Enable stream */
++ reg16_read16(client, 0x301a, &val); // read inital reset_register value
++ val |= (1 << 2); // Set streamOn bit
++ reg16_write16(client, 0x301a, val); // Start Streaming
++
++ /* Read OTP IDs */
++ ar0233_otp_id_read(client);
++
++ dev_info(&client->dev, "ar0233 PID %x, res %dx%d, OTP_ID %02x:%02x:%02x:%02x:%02x:%02x\n",
++ pid, AR0233_MAX_WIDTH, AR0233_MAX_HEIGHT, priv->id[0], priv->id[1], priv->id[2], priv->id[3], priv->id[4], priv->id[5]);
++err:
++ return ret;
++}
++
++static int ar0233_parse_dt(struct device_node *np, struct ar0233_priv *priv)
++{
++ struct i2c_client *client = v4l2_get_subdevdata(&priv->sd);
++ int i;
++ struct device_node *endpoint = NULL, *rendpoint = NULL;
++ int tmp_addr = 0;
++
++ for (i = 0; ; i++) {
++ endpoint = of_graph_get_next_endpoint(np, endpoint);
++ if (!endpoint)
++ break;
++
++ rendpoint = of_parse_phandle(endpoint, "remote-endpoint", 0);
++ if (!rendpoint)
++ continue;
++
++ if (!of_property_read_u32(rendpoint, "ti9x3-addr", &priv->ti9x3_addr) &&
++ !of_property_match_string(rendpoint->parent->parent, "compatible", "ti,ti9x4") &&
++ !of_property_read_u32(rendpoint->parent->parent, "reg", &priv->ti9x4_addr) &&
++ !kstrtouint(strrchr(rendpoint->full_name, '@') + 1, 0, &priv->port))
++ break;
++ }
++
++ of_node_put(endpoint);
++
++ if (!priv->ti9x4_addr) {
++ dev_err(&client->dev, "deserializer does not present\n");
++ return -EINVAL;
++ }
++
++ /* setup I2C translator address */
++ tmp_addr = client->addr;
++ if (priv->ti9x4_addr) {
++ client->addr = priv->ti9x4_addr; /* Deserializer I2C address */
++
++ reg8_write(client, 0x4c, (priv->port << 4) | (1 << priv->port)); /* Select RX port number */
++ usleep_range(2000, 2500); /* wait 2ms */
++ reg8_write(client, 0x65, tmp_addr << 1); /* Sensor translated I2C address */
++ reg8_write(client, 0x5d, AR0233_I2C_ADDR << 1); /* Sensor native I2C address */
++
++ reg8_write(client, 0x6e, 0x8a); /* GPIO0 - fsin, GPIO1 - NC */
++ }
++ client->addr = tmp_addr;
++
++ mdelay(10);
++
++ return 0;
++}
++
++static int ar0233_probe(struct i2c_client *client,
++ const struct i2c_device_id *did)
++{
++ struct ar0233_priv *priv;
++ int ret;
++
++ priv = devm_kzalloc(&client->dev, sizeof(*priv), GFP_KERNEL);
++ if (!priv)
++ return -ENOMEM;
++
++ v4l2_i2c_subdev_init(&priv->sd, client, &ar0233_subdev_ops);
++ priv->sd.flags = V4L2_SUBDEV_FL_HAS_DEVNODE;
++
++ v4l2_ctrl_handler_init(&priv->hdl, 4);
++ v4l2_ctrl_new_std(&priv->hdl, &ar0233_ctrl_ops,
++ V4L2_CID_BRIGHTNESS, 0, 16, 1, 7);
++ v4l2_ctrl_new_std(&priv->hdl, &ar0233_ctrl_ops,
++ V4L2_CID_CONTRAST, 0, 16, 1, 7);
++ v4l2_ctrl_new_std(&priv->hdl, &ar0233_ctrl_ops,
++ V4L2_CID_SATURATION, 0, 7, 1, 2);
++ v4l2_ctrl_new_std(&priv->hdl, &ar0233_ctrl_ops,
++ V4L2_CID_HUE, 0, 23, 1, 12);
++ v4l2_ctrl_new_std(&priv->hdl, &ar0233_ctrl_ops,
++ V4L2_CID_GAMMA, -128, 128, 1, 0);
++ v4l2_ctrl_new_std(&priv->hdl, &ar0233_ctrl_ops,
++ V4L2_CID_SHARPNESS, 0, 10, 1, 3);
++ v4l2_ctrl_new_std(&priv->hdl, &ar0233_ctrl_ops,
++ V4L2_CID_AUTOGAIN, 0, 1, 1, 0);
++ v4l2_ctrl_new_std(&priv->hdl, &ar0233_ctrl_ops,
++ V4L2_CID_GAIN, 1, 0x7ff, 1, 0x200);
++ v4l2_ctrl_new_std(&priv->hdl, &ar0233_ctrl_ops,
++ V4L2_CID_ANALOGUE_GAIN, 1, 0xe, 1, 0xa);
++ v4l2_ctrl_new_std(&priv->hdl, &ar0233_ctrl_ops,
++ V4L2_CID_EXPOSURE, 1, 0x600, 1, 0x144);
++ v4l2_ctrl_new_std(&priv->hdl, &ar0233_ctrl_ops,
++ V4L2_CID_HFLIP, 0, 1, 1, 0);
++ v4l2_ctrl_new_std(&priv->hdl, &ar0233_ctrl_ops,
++ V4L2_CID_VFLIP, 0, 1, 1, 0);
++ priv->sd.ctrl_handler = &priv->hdl;
++
++ ret = priv->hdl.error;
++ if (ret)
++ goto cleanup;
++
++ v4l2_ctrl_handler_setup(&priv->hdl);
++
++ priv->pad.flags = MEDIA_PAD_FL_SOURCE;
++ priv->sd.entity.flags |= MEDIA_ENT_F_CAM_SENSOR;
++ ret = media_entity_pads_init(&priv->sd.entity, 1, &priv->pad);
++ if (ret < 0)
++ goto cleanup;
++
++ ret = ar0233_parse_dt(client->dev.of_node, priv);
++ if (ret)
++ goto cleanup;
++
++ ret = ar0233_initialize(client);
++ if (ret < 0)
++ goto cleanup;
++
++ priv->rect.left = 0;
++ priv->rect.top = 0;
++ priv->rect.width = AR0233_MAX_WIDTH;
++ priv->rect.height = AR0233_MAX_HEIGHT;
++
++ ret = v4l2_async_register_subdev(&priv->sd);
++ if (ret)
++ goto cleanup;
++
++ if (device_create_file(&client->dev, &dev_attr_otp_id_ar0233) != 0) {
++ dev_err(&client->dev, "sysfs otp_id entry creation failed\n");
++ goto cleanup;
++ }
++
++ priv->init_complete = 1;
++
++ return 0;
++
++cleanup:
++ media_entity_cleanup(&priv->sd.entity);
++ v4l2_ctrl_handler_free(&priv->hdl);
++ v4l2_device_unregister_subdev(&priv->sd);
++#ifdef CONFIG_SOC_CAMERA_AR0233
++ v4l_err(client, "failed to probe @ 0x%02x (%s)\n",
++ client->addr, client->adapter->name);
++#endif
++ return ret;
++}
++
++static int ar0233_remove(struct i2c_client *client)
++{
++ struct ar0233_priv *priv = i2c_get_clientdata(client);
++
++ device_remove_file(&client->dev, &dev_attr_otp_id_ar0233);
++ v4l2_async_unregister_subdev(&priv->sd);
++ media_entity_cleanup(&priv->sd.entity);
++ v4l2_ctrl_handler_free(&priv->hdl);
++ v4l2_device_unregister_subdev(&priv->sd);
++
++ return 0;
++}
++
++#ifdef CONFIG_SOC_CAMERA_AR0233
++static const struct i2c_device_id ar0233_id[] = {
++ { "ar0233", 0 },
++ { }
++};
++MODULE_DEVICE_TABLE(i2c, ar0233_id);
++
++static const struct of_device_id ar0233_of_ids[] = {
++ { .compatible = "aptina,ar0233", },
++ { }
++};
++MODULE_DEVICE_TABLE(of, ar0233_of_ids);
++
++static struct i2c_driver ar0233_i2c_driver = {
++ .driver = {
++ .name = "ar0233",
++ .of_match_table = ar0233_of_ids,
++ },
++ .probe = ar0233_probe,
++ .remove = ar0233_remove,
++ .id_table = ar0233_id,
++};
++
++module_i2c_driver(ar0233_i2c_driver);
++
++MODULE_DESCRIPTION("SoC Camera driver for AR0233");
++MODULE_AUTHOR("Vladimir Barinov");
++MODULE_LICENSE("GPL");
++#endif
+diff --git a/drivers/media/i2c/soc_camera/ar0233.h b/drivers/media/i2c/soc_camera/ar0233.h
+new file mode 100644
+index 0000000..f88e5a3
+--- /dev/null
++++ b/drivers/media/i2c/soc_camera/ar0233.h
+@@ -0,0 +1,409 @@
++/*
++ * ON Semiconductor AR0233 sensor camera wizard 1920x1080@30/BGGR/MIPI
++ *
++ * Copyright (C) 2018 Cogent Embedded, Inc.
++ *
++ * This program is free software; you can redistribute it and/or modify it
++ * under the terms of the GNU General Public License as published by the
++ * Free Software Foundation; either version 2 of the License, or (at your
++ * option) any later version.
++ */
++
++//#define AR0233_DISPLAY_PATTERN_FIXED
++//#define AR0233_DISPLAY_PATTERN_COLOR_BAR
++
++#define AR0233_MAX_WIDTH 1792 //1920
++#define AR0233_MAX_HEIGHT 1080
++
++#define AR0233_DELAY 0xffff
++
++#define AR0233_SENSOR_WIDTH 1920
++#define AR0233_SENSOR_HEIGHT 1280
++
++#define AR0233_X_START ((AR0233_SENSOR_WIDTH - AR0233_MAX_WIDTH) / 2)
++#define AR0233_Y_START ((AR0233_SENSOR_HEIGHT - AR0233_MAX_HEIGHT) / 2)
++#define AR0233_X_END (AR0233_X_START + AR0233_MAX_WIDTH - 1)
++#define AR0233_Y_END (AR0233_Y_START + AR0233_MAX_HEIGHT - 1)
++
++struct ar0233_reg {
++ u16 reg;
++ u16 val;
++};
++
++static const struct ar0233_reg ar0233_regs_wizard[] = {
++{0x301A, 0x0018}, // RESET_REGISTER
++{AR0233_DELAY, 500}, // Wait 500ms
++{0x3070, 0x0000}, // 1: Solid color test pattern,
++ // 2: Full color bar test pattern,
++ // 3: Fade to grey color bar test pattern,
++ //256: Walking 1 test pattern (12 bit)
++{0x3072, 0x0123}, // R
++{0x3074, 0x0456}, // G(GR row)
++{0x3076, 0x0abc}, // B
++{0x3078, 0x0def}, // G(GB row)
++#ifdef AR0233_DISPLAY_PATTERN_FIXED
++{0x3070, 0x0001},
++#endif
++#ifdef AR0233_DISPLAY_PATTERN_COLOR_BAR
++{0x3070, 0x0002},
++#endif
++{AR0233_DELAY, 100}, // Wait 100ms
++
++{0x3092, 0x0C24},
++{0x337A, 0x0C80},
++{0x3520, 0x1288},
++{0x3522, 0x880C},
++{0x3524, 0x0C12},
++{0x352C, 0x1212},
++{0x354A, 0x007F},
++{0x350C, 0x0568},
++{0x3506, 0x3333},
++{0x3508, 0x3333},
++{0x3100, 0x4000},
++{0x3280, 0x0FA0},
++{0x3282, 0x0FA0},
++{0x3284, 0x0FA0},
++{0x3286, 0x0FA0},
++{0x3288, 0x0FA0},
++{0x328A, 0x0FA0},
++{0x328C, 0x0FA0},
++{0x328E, 0x0FA0},
++{0x3290, 0x0FA0},
++{0x3292, 0x0FA0},
++{0x3294, 0x0FA0},
++{0x3296, 0x0FA0},
++{0x3298, 0x0FA0},
++{0x329A, 0x0FA0},
++{0x329C, 0x0FA0},
++{0x329E, 0x0FA0},
++
++{AR0233_DELAY, 200}, // Wait 200ms
++
++{0x2512, 0x8000},
++{0x2510, 0x0905},
++{0x2510, 0x3350},
++{0x2510, 0x2004},
++{0x2510, 0x1460},
++{0x2510, 0x1578},
++{0x2510, 0x0901},
++{0x2510, 0x7B24},
++{0x2510, 0xFF24},
++{0x2510, 0xFF24},
++{0x2510, 0xEA24},
++{0x2510, 0x1022},
++{0x2510, 0x2410},
++{0x2510, 0x155A},
++{0x2510, 0x0901},
++{0x2510, 0x1400},
++{0x2510, 0x24FF},
++{0x2510, 0x24FF},
++{0x2510, 0x24EA},
++{0x2510, 0x2324},
++{0x2510, 0x647A},
++{0x2510, 0x2404},
++{0x2510, 0x052C},
++{0x2510, 0x400A},
++{0x2510, 0xFF0A},
++{0x2510, 0xFF0A},
++{0x2510, 0x1008},
++{0x2510, 0x3851},
++{0x2510, 0x1440},
++{0x2510, 0x0004},
++{0x2510, 0x0801},
++{0x2510, 0x0408},
++{0x2510, 0x1180},
++{0x2510, 0x2652},
++{0x2510, 0x1518},
++{0x2510, 0x0906},
++{0x2510, 0x1348},
++{0x2510, 0x1002},
++{0x2510, 0x1016},
++{0x2510, 0x1181},
++{0x2510, 0x1189},
++{0x2510, 0x1056},
++{0x2510, 0x1210},
++{0x2510, 0x0901},
++{0x2510, 0x0D09},
++{0x2510, 0x1413},
++{0x2510, 0x8809},
++{0x2510, 0x2B15},
++{0x2510, 0x8809},
++{0x2510, 0x0311},
++{0x2510, 0xD909},
++{0x2510, 0x1214},
++{0x2510, 0x4109},
++{0x2510, 0x0312},
++{0x2510, 0x1409},
++{0x2510, 0x0110},
++{0x2510, 0xD612},
++{0x2510, 0x1012},
++{0x2510, 0x1212},
++{0x2510, 0x1011},
++{0x2510, 0xDD11},
++{0x2510, 0xD910},
++{0x2510, 0x5609},
++{0x2510, 0x1511},
++{0x2510, 0xDB09},
++{0x2510, 0x1511},
++{0x2510, 0x9B09},
++{0x2510, 0x0F11},
++{0x2510, 0xBB12},
++{0x2510, 0x1A12},
++{0x2510, 0x1014},
++{0x2510, 0x6012},
++{0x2510, 0x5010},
++{0x2510, 0x7610},
++{0x2510, 0xE609},
++{0x2510, 0x0812},
++{0x2510, 0x4012},
++{0x2510, 0x6009},
++{0x2510, 0x290B},
++{0x2510, 0x0904},
++{0x2510, 0x1440},
++{0x2510, 0x0923},
++{0x2510, 0x15C8},
++{0x2510, 0x13C8},
++{0x2510, 0x092C},
++{0x2510, 0x1588},
++{0x2510, 0x1388},
++{0x2510, 0x0C09},
++{0x2510, 0x0C14},
++{0x2510, 0x4109},
++{0x2510, 0x1112},
++{0x2510, 0x6212},
++{0x2510, 0x6011},
++{0x2510, 0xBF11},
++{0x2510, 0xBB10},
++{0x2510, 0x6611},
++{0x2510, 0xFB09},
++{0x2510, 0x3511},
++{0x2510, 0xBB12},
++{0x2510, 0x6312},
++{0x2510, 0x6014},
++{0x2510, 0x0015},
++{0x2510, 0x0011},
++{0x2510, 0xB812},
++{0x2510, 0xA012},
++{0x2510, 0x0010},
++{0x2510, 0x2610},
++{0x2510, 0x0013},
++{0x2510, 0x0011},
++{0x2510, 0x0008},
++{0x2510, 0x3053},
++{0x2510, 0x4215},
++{0x2510, 0x4013},
++{0x2510, 0x4010},
++{0x2510, 0x0210},
++{0x2510, 0x1611},
++{0x2510, 0x8111},
++{0x2510, 0x8910},
++{0x2510, 0x5612},
++{0x2510, 0x1009},
++{0x2510, 0x010D},
++{0x2510, 0x0815},
++{0x2510, 0xC015},
++{0x2510, 0xD013},
++{0x2510, 0x5009},
++{0x2510, 0x1313},
++{0x2510, 0xD009},
++{0x2510, 0x0215},
++{0x2510, 0xC015},
++{0x2510, 0xC813},
++{0x2510, 0xC009},
++{0x2510, 0x0515},
++{0x2510, 0x8813},
++{0x2510, 0x8009},
++{0x2510, 0x0213},
++{0x2510, 0x8809},
++{0x2510, 0x0411},
++{0x2510, 0xC909},
++{0x2510, 0x0814},
++{0x2510, 0x0109},
++{0x2510, 0x0B11},
++{0x2510, 0xD908},
++{0x2510, 0x1400},
++{0x2510, 0x091A},
++{0x2510, 0x1440},
++{0x2510, 0x0903},
++{0x2510, 0x1214},
++{0x2510, 0x0901},
++{0x2510, 0x10D6},
++{0x2510, 0x1210},
++{0x2510, 0x1212},
++{0x2510, 0x1210},
++{0x2510, 0x11DD},
++{0x2510, 0x11D9},
++{0x2510, 0x1056},
++{0x2510, 0x0917},
++{0x2510, 0x11DB},
++{0x2510, 0x0913},
++{0x2510, 0x11FB},
++{0x2510, 0x0905},
++{0x2510, 0x11BB},
++{0x2510, 0x121A},
++{0x2510, 0x1210},
++{0x2510, 0x1460},
++{0x2510, 0x1250},
++{0x2510, 0x1076},
++{0x2510, 0x10E6},
++{0x2510, 0x0901},
++{0x2510, 0x15A8},
++{0x2510, 0x0901},
++{0x2510, 0x13A8},
++{0x2510, 0x1240},
++{0x2510, 0x1260},
++{0x2510, 0x0925},
++{0x2510, 0x13AD},
++{0x2510, 0x0902},
++{0x2510, 0x0907},
++{0x2510, 0x1588},
++{0x2510, 0x0901},
++{0x2510, 0x138D},
++{0x2510, 0x0B09},
++{0x2510, 0x0914},
++{0x2510, 0x4009},
++{0x2510, 0x0B13},
++{0x2510, 0x8809},
++{0x2510, 0x1C0C},
++{0x2510, 0x0920},
++{0x2510, 0x1262},
++{0x2510, 0x1260},
++{0x2510, 0x11BF},
++{0x2510, 0x11BB},
++{0x2510, 0x1066},
++{0x2510, 0x090A},
++{0x2510, 0x11FB},
++{0x2510, 0x093B},
++{0x2510, 0x11BB},
++{0x2510, 0x1263},
++{0x2510, 0x1260},
++{0x2510, 0x1400},
++{0x2510, 0x1508},
++{0x2510, 0x11B8},
++{0x2510, 0x12A0},
++{0x2510, 0x1200},
++{0x2510, 0x1026},
++{0x2510, 0x1000},
++{0x2510, 0x1300},
++{0x2510, 0x1100},
++{0x2510, 0x437A},
++{0x2510, 0x0609},
++{0x2510, 0x0B05},
++{0x2510, 0x0708},
++{0x2510, 0x4137},
++{0x2510, 0x502C},
++{0x2510, 0x2CFE},
++{0x2510, 0x15FE},
++{0x2510, 0x0C2C},
++{0x32E6, 0x00E0},
++{0x1008, 0x036F},
++{0x100C, 0x058F},
++{0x100E, 0x07AF},
++{0x1010, 0x014F},
++{0x3230, 0x0312},
++{0x3232, 0x0532},
++{0x3234, 0x0752},
++{0x3236, 0x00F2},
++{0x3566, 0x3328},
++{0x32D0, 0x3A02},
++{0x32D2, 0x3508},
++{0x32D4, 0x3702},
++{0x32D6, 0x3C04},
++{0x32DC, 0x370A},
++{0x30B0, 0x0800},
++{0x302A, 0x0006},
++{0x302C, 0x0001},
++{0x302E, 0x0002},
++{0x3030, 0x002C},
++{0x3036, 0x000C},
++{0x3038, 0x0001},
++{0x30B0, 0x0A00},
++{0x30A2, 0x0001},
++{0x30A6, 0x0001},
++{0x3040, 0x0000},
++{0x3040, 0x0000},
++{0x3044, 0x0400},
++{0x3044, 0x0400},
++{0x3044, 0x0400},
++{0x3044, 0x0400},
++{0x3064, 0x1882},
++{0x3064, 0x1802},
++{0x3064, 0x1802},
++{0x3064, 0x1802},
++{0x33E0, 0x0C80},
++{0x33E0, 0x0C80},
++{0x3180, 0x0080},
++{0x33E4, 0x0080},
++{0x33E0, 0x0C80},
++{0x33E0, 0x0C80},
++{0x3004, AR0233_X_START}, // X_ADDR_START_
++{0x3008, AR0233_X_END}, // X_ADDR_END_
++{0x3002, AR0233_Y_START}, // Y_ADDR_START_
++{0x3006, AR0233_Y_END}, // Y_ADDR_END_
++{0x3402, 0x0000 | AR0233_MAX_WIDTH}, // X_OUTPUT_CONTROL
++{0x3404, 0x0000 | AR0233_MAX_HEIGHT}, // Y_OUTPUT_CONTROL
++{0x3032, 0x0000},
++{0x3400, 0x0010},
++#if 1
++/* disable HDR */
++{0x3082, 0x0000},
++{0x30BA, 0x11F2},
++#endif
++{AR0233_DELAY, 100}, // Wait 100ms
++
++#if 0
++{0x300A, AR0233_SENSOR_HEIGHT + 356}, // FRAME_LENGTH_LINES_
++{0x300C, AR0233_SENSOR_WIDTH + 100}, // LINE_LENGTH_PCK_
++#else
++{0x300A, AR0233_SENSOR_HEIGHT + 208}, // FRAME_LENGTH_LINES_
++{0x300C, AR0233_SENSOR_WIDTH + 300}, // LINE_LENGTH_PCK_
++#endif
++{0x3042, 0x0000},
++{0x3238, 0x0222},
++{0x3012, 0x0144},
++{0x3014, AR0233_SENSOR_WIDTH + 100},
++{0x321E, AR0233_SENSOR_WIDTH + 100},
++{0x3222, AR0233_SENSOR_WIDTH + 100},
++{0x30B0, 0x0B00},
++{0x32EA, 0x3C0E},
++{0x32EA, 0x3C0E},
++{0x32EA, 0x3C0E},
++{0x32EC, 0x72A1},
++{0x32EC, 0x72A1},
++{0x32EC, 0x72A1},
++{0x32EC, 0x72A1},
++{0x32EC, 0x72A1},
++{0x32EC, 0x72A1},
++{0x31D0, 0x0001}, // COMPANDING
++{0x31AE, 0x0004},
++{0x31AE, 0x0304},
++{0x31AC, 0x140C}, // DATA_FORMAT_BITS: RAW12
++{0x301A, 0x1098},
++{0x301A, 0x1018},
++{0x301A, 0x1018},
++{0x31AE, 0x0204},
++{0x3342, 0x122C},
++{0x3346, 0x122C},
++{0x334A, 0x122C},
++{0x334E, 0x122C},
++{0x3344, 0x0011},
++{0x3348, 0x0111},
++{0x334C, 0x0211},
++{0x3350, 0x0311},
++{0x31B0, 0x0049},
++{0x31B2, 0x0033},
++{0x31B4, 0x2185},
++{0x31B6, 0x1146},
++{0x31B8, 0x3047},
++{0x31BA, 0x0186},
++{0x31BC, 0x0805},
++#if 1
++/* Enable trigger input */
++{0x340A, 0x00E0}, // GPIO_CONTROL1: GPIO1 is trigger
++{0x340C, 0x0002}, // GPIO_CONTROL2: GPIO1 is trigger
++{0x30CE, 0x0120}, // TRIGGER_MODE
++//{0x30DC, 0x0120}, // TRIGGER_DELAY
++#endif
++{0x3366, 0x0aaa}, // ANALOG_GAIN
++{0x301A, 0x011C},
++};
+diff --git a/drivers/media/i2c/soc_camera/gw4200_ar014x.c b/drivers/media/i2c/soc_camera/gw4200_ar014x.c
+new file mode 100644
+index 0000000..2de6fe7
+--- /dev/null
++++ b/drivers/media/i2c/soc_camera/gw4200_ar014x.c
+@@ -0,0 +1,592 @@
++/*
++ * ON Semiconductor GW4200-AR014X sensor camera driver
++ *
++ * Copyright (C) 2018 Cogent Embedded, Inc.
++ *
++ * This program is free software; you can redistribute it and/or modify it
++ * under the terms of the GNU General Public License as published by the
++ * Free Software Foundation; either version 2 of the License, or (at your
++ * option) any later version.
++ */
++
++#include <linux/delay.h>
++#include <linux/init.h>
++#include <linux/i2c.h>
++#include <linux/module.h>
++#include <linux/of_graph.h>
++#include <linux/videodev2.h>
++
++#include <media/soc_camera.h>
++#include <media/v4l2-common.h>
++#include <media/v4l2-ctrls.h>
++
++#include "gw4200_ar014x.h"
++
++#define GW4200_I2C_ADDR 0x6d
++
++#define GW4200_PID 0x00
++#define GW4200_VERSION_REG 0xda
++
++#define GW4200_MEDIA_BUS_FMT MEDIA_BUS_FMT_YUYV8_2X8
++
++static void gw4200_otp_id_read(struct i2c_client *client);
++
++struct gw4200_priv {
++ struct v4l2_subdev sd;
++ struct v4l2_ctrl_handler hdl;
++ struct media_pad pad;
++ struct v4l2_rect rect;
++ int init_complete;
++ u8 id[6];
++ int exposure;
++ int gain;
++ int autogain;
++ /* serializers */
++ int max9286_addr;
++ int max9271_addr;
++ int port;
++ int gpio_resetb;
++ int gpio_fsin;
++};
++
++static inline struct gw4200_priv *to_gw4200(const struct i2c_client *client)
++{
++ return container_of(i2c_get_clientdata(client), struct gw4200_priv, sd);
++}
++
++static void gw4200_s_port(struct i2c_client *client, int fwd_en)
++{
++ struct gw4200_priv *priv = to_gw4200(client);
++ int tmp_addr;
++
++ if (priv->max9286_addr) {
++ tmp_addr = client->addr;
++ client->addr = priv->max9286_addr; /* Deserializer I2C address */
++ reg8_write(client, 0x0a, fwd_en ? 0x11 << priv->port : 0); /* Enable/disable reverse/forward control for this port */
++ usleep_range(5000, 5500); /* wait 5ms */
++ client->addr = tmp_addr;
++ };
++}
++
++#if 0
++static int gw4200_set_regs(struct i2c_client *client,
++ const struct gw4200_reg *regs, int nr_regs)
++{
++ int i;
++
++ for (i = 0; i < nr_regs; i++) {
++ if (regs[i].reg == GW4200_DELAY) {
++ mdelay(regs[i].val);
++ continue;
++ }
++
++ reg16_write16(client, regs[i].reg, regs[i].val);
++ }
++
++ return 0;
++}
++#endif
++
++static u16 gw4200_ar014x_read(struct i2c_client *client, u16 addr)
++{
++ u16 reg_val = 0;
++
++ reg16_write16(client, 0x0040, 0x8d00);
++ usleep_range(100, 150); /* wait 100 us */
++ reg16_write16(client, 0xfc00, addr);
++ reg16_write16(client, 0xfc02, 0x0200); /* 2 bytes */
++ reg16_write16(client, 0x0040, 0x8d05);
++ usleep_range(100, 150); /* wait 100 us */
++ reg16_write16(client, 0x0040, 0x8d08);
++ usleep_range(100, 150); /* wait 100 us */
++ reg16_read16(client, 0xfc00, &reg_val);
++ reg16_write16(client, 0x0040, 0x8d02);
++ usleep_range(100, 150); /* wait 100 us */
++
++ return reg_val;
++}
++
++static void gw4200_ar014x_write(struct i2c_client *client, u16 addr, u16 val)
++{
++ reg16_write16(client, 0x0040, 0x8d00);
++ usleep_range(100, 150); /* wait 100 us */
++ reg16_write16(client, 0xfc00, addr);
++ reg16_write16(client, 0xfc02, 0x0200 | (val >> 8)); /* 2 bytes */
++ reg16_write16(client, 0xfc04, (val & 0xff) << 8);
++ reg16_write16(client, 0x0040, 0x8d06);
++ usleep_range(100, 150); /* wait 100 us */
++ reg16_write16(client, 0x0040, 0x8d08);
++ usleep_range(100, 150); /* wait 100 us */
++ reg16_write16(client, 0x0040, 0x8d02);
++ usleep_range(100, 150); /* wait 100 us */
++}
++
++static int gw4200_s_stream(struct v4l2_subdev *sd, int enable)
++{
++ return 0;
++}
++
++static int gw4200_get_fmt(struct v4l2_subdev *sd,
++ struct v4l2_subdev_pad_config *cfg,
++ struct v4l2_subdev_format *format)
++{
++ struct v4l2_mbus_framefmt *mf = &format->format;
++ struct i2c_client *client = v4l2_get_subdevdata(sd);
++ struct gw4200_priv *priv = to_gw4200(client);
++
++ if (format->pad)
++ return -EINVAL;
++
++ mf->width = priv->rect.width;
++ mf->height = priv->rect.height;
++ mf->code = GW4200_MEDIA_BUS_FMT;
++ mf->colorspace = V4L2_COLORSPACE_SMPTE170M;
++ mf->field = V4L2_FIELD_NONE;
++
++ return 0;
++}
++
++static int gw4200_set_fmt(struct v4l2_subdev *sd,
++ struct v4l2_subdev_pad_config *cfg,
++ struct v4l2_subdev_format *format)
++{
++ struct v4l2_mbus_framefmt *mf = &format->format;
++
++ mf->code = GW4200_MEDIA_BUS_FMT;
++ mf->colorspace = V4L2_COLORSPACE_SMPTE170M;
++ mf->field = V4L2_FIELD_NONE;
++
++ if (format->which == V4L2_SUBDEV_FORMAT_TRY)
++ cfg->try_fmt = *mf;
++
++ return 0;
++}
++
++static int gw4200_enum_mbus_code(struct v4l2_subdev *sd,
++ struct v4l2_subdev_pad_config *cfg,
++ struct v4l2_subdev_mbus_code_enum *code)
++{
++ if (code->pad || code->index > 0)
++ return -EINVAL;
++
++ code->code = GW4200_MEDIA_BUS_FMT;
++
++ return 0;
++}
++
++static int gw4200_get_edid(struct v4l2_subdev *sd, struct v4l2_edid *edid)
++{
++ struct i2c_client *client = v4l2_get_subdevdata(sd);
++ struct gw4200_priv *priv = to_gw4200(client);
++
++ gw4200_otp_id_read(client);
++
++ memcpy(edid->edid, priv->id, 6);
++
++ edid->edid[6] = 0xff;
++ edid->edid[7] = client->addr;
++ edid->edid[8] = GW4200_VERSION_REG >> 8;
++ edid->edid[9] = GW4200_VERSION_REG & 0xff;
++
++ return 0;
++}
++
++static int gw4200_set_selection(struct v4l2_subdev *sd,
++ struct v4l2_subdev_pad_config *cfg,
++ struct v4l2_subdev_selection *sel)
++{
++ struct v4l2_rect *rect = &sel->r;
++ struct i2c_client *client = v4l2_get_subdevdata(sd);
++ struct gw4200_priv *priv = to_gw4200(client);
++
++ if (sel->which != V4L2_SUBDEV_FORMAT_ACTIVE ||
++ sel->target != V4L2_SEL_TGT_CROP)
++ return -EINVAL;
++
++ rect->left = ALIGN(rect->left, 2);
++ rect->top = ALIGN(rect->top, 2);
++ rect->width = ALIGN(rect->width, 2);
++ rect->height = ALIGN(rect->height, 2);
++
++ if ((rect->left + rect->width > GW4200_MAX_WIDTH) ||
++ (rect->top + rect->height > GW4200_MAX_HEIGHT))
++ *rect = priv->rect;
++
++ priv->rect.left = rect->left;
++ priv->rect.top = rect->top;
++ priv->rect.width = rect->width;
++ priv->rect.height = rect->height;
++
++ return 0;
++}
++
++static int gw4200_get_selection(struct v4l2_subdev *sd,
++ struct v4l2_subdev_pad_config *cfg,
++ struct v4l2_subdev_selection *sel)
++{
++ struct i2c_client *client = v4l2_get_subdevdata(sd);
++ struct gw4200_priv *priv = to_gw4200(client);
++
++ if (sel->which != V4L2_SUBDEV_FORMAT_ACTIVE)
++ return -EINVAL;
++
++ switch (sel->target) {
++ case V4L2_SEL_TGT_CROP_BOUNDS:
++ sel->r.left = 0;
++ sel->r.top = 0;
++ sel->r.width = GW4200_MAX_WIDTH;
++ sel->r.height = GW4200_MAX_HEIGHT;
++ return 0;
++ case V4L2_SEL_TGT_CROP_DEFAULT:
++ sel->r.left = 0;
++ sel->r.top = 0;
++ sel->r.width = GW4200_MAX_WIDTH;
++ sel->r.height = GW4200_MAX_HEIGHT;
++ return 0;
++ case V4L2_SEL_TGT_CROP:
++ sel->r = priv->rect;
++ return 0;
++ default:
++ return -EINVAL;
++ }
++}
++
++static int gw4200_g_mbus_config(struct v4l2_subdev *sd,
++ struct v4l2_mbus_config *cfg)
++{
++ cfg->flags = V4L2_MBUS_CSI2_1_LANE | V4L2_MBUS_CSI2_CHANNEL_0 |
++ V4L2_MBUS_CSI2_CONTINUOUS_CLOCK;
++ cfg->type = V4L2_MBUS_CSI2;
++
++ return 0;
++}
++
++#ifdef CONFIG_VIDEO_ADV_DEBUG
++static int gw4200_g_register(struct v4l2_subdev *sd,
++ struct v4l2_dbg_register *reg)
++{
++ struct i2c_client *client = v4l2_get_subdevdata(sd);
++ int ret;
++ u16 val = 0;
++
++ ret = reg16_read16(client, (u16)reg->reg, &val);
++ if (ret < 0)
++ return ret;
++
++ reg->val = val;
++ reg->size = sizeof(u16);
++
++ return 0;
++}
++
++static int gw4200_s_register(struct v4l2_subdev *sd,
++ const struct v4l2_dbg_register *reg)
++{
++ struct i2c_client *client = v4l2_get_subdevdata(sd);
++
++ return reg16_write16(client, (u16)reg->reg, (u16)reg->val);
++}
++#endif
++
++static struct v4l2_subdev_core_ops gw4200_core_ops = {
++#ifdef CONFIG_VIDEO_ADV_DEBUG
++ .g_register = gw4200_g_register,
++ .s_register = gw4200_s_register,
++#endif
++};
++
++static int gw4200_s_ctrl(struct v4l2_ctrl *ctrl)
++{
++ struct v4l2_subdev *sd = to_sd(ctrl);
++ struct i2c_client *client = v4l2_get_subdevdata(sd);
++ struct gw4200_priv *priv = to_gw4200(client);
++ int ret = -EINVAL;
++
++ if (!priv->init_complete)
++ return 0;
++
++ switch (ctrl->id) {
++ case V4L2_CID_BRIGHTNESS:
++ case V4L2_CID_CONTRAST:
++ case V4L2_CID_SATURATION:
++ case V4L2_CID_HUE:
++ case V4L2_CID_GAMMA:
++ case V4L2_CID_SHARPNESS:
++ case V4L2_CID_AUTOGAIN:
++ case V4L2_CID_GAIN:
++ case V4L2_CID_EXPOSURE:
++ case V4L2_CID_HFLIP:
++ case V4L2_CID_VFLIP:
++ break;
++ }
++
++ return ret;
++}
++
++static const struct v4l2_ctrl_ops gw4200_ctrl_ops = {
++ .s_ctrl = gw4200_s_ctrl,
++};
++
++static struct v4l2_subdev_video_ops gw4200_video_ops = {
++ .s_stream = gw4200_s_stream,
++ .g_mbus_config = gw4200_g_mbus_config,
++};
++
++static const struct v4l2_subdev_pad_ops gw4200_subdev_pad_ops = {
++ .get_edid = gw4200_get_edid,
++ .enum_mbus_code = gw4200_enum_mbus_code,
++ .get_selection = gw4200_get_selection,
++ .set_selection = gw4200_set_selection,
++ .get_fmt = gw4200_get_fmt,
++ .set_fmt = gw4200_set_fmt,
++};
++
++static struct v4l2_subdev_ops gw4200_subdev_ops = {
++ .core = &gw4200_core_ops,
++ .video = &gw4200_video_ops,
++ .pad = &gw4200_subdev_pad_ops,
++};
++
++static void gw4200_otp_id_read(struct i2c_client *client)
++{
++ struct gw4200_priv *priv = to_gw4200(client);
++ int i;
++
++ /* read camera id from ar014x OTP memory */
++ gw4200_ar014x_write(client, 0x3054, 0x400);
++ gw4200_ar014x_write(client, 0x304a, 0x110);
++ usleep_range(25000, 25500); /* wait 25 ms */
++
++ for (i = 0; i < 6; i += 2) {
++ /* first 4 bytes are equal on all ar014x */
++ priv->id[i] = gw4200_ar014x_read(client, 0x3800 + i + 4) >> 8;
++ priv->id[i + 1] = gw4200_ar014x_read(client, 0x3800 + i + 4) & 0xff;
++ }
++}
++
++static ssize_t gw4200_otp_id_show(struct device *dev,
++ struct device_attribute *attr, char *buf)
++{
++ struct v4l2_subdev *sd = i2c_get_clientdata(to_i2c_client(dev));
++ struct i2c_client *client = v4l2_get_subdevdata(sd);
++ struct gw4200_priv *priv = to_gw4200(client);
++
++ gw4200_otp_id_read(client);
++
++ return snprintf(buf, 32, "%02x:%02x:%02x:%02x:%02x:%02x\n",
++ priv->id[0], priv->id[1], priv->id[2], priv->id[3], priv->id[4], priv->id[5]);
++}
++
++static DEVICE_ATTR(otp_id_gw4200, S_IRUGO, gw4200_otp_id_show, NULL);
++
++static int gw4200_initialize(struct i2c_client *client)
++{
++ struct gw4200_priv *priv = to_gw4200(client);
++ u8 pid = 0;
++ int ret = 0;
++
++ gw4200_s_port(client, 1);
++
++ /* check and show model ID */
++ reg8_read(client, GW4200_PID, &pid);
++
++ if (pid != GW4200_VERSION_REG) {
++ dev_err(&client->dev, "Product ID error %x\n", pid);
++ ret = -ENODEV;
++ goto err;
++ }
++
++#if 0
++ /* Program wizard registers */
++ gw4200_set_regs(client, gw4200_regs_wizard, ARRAY_SIZE(gw4200_regs_wizard));
++ /* Read OTP IDs */
++ gw4200_otp_id_read(client);
++#endif
++
++ dev_info(&client->dev, "gw4200 PID %x, res %dx%d, OTP_ID %02x:%02x:%02x:%02x:%02x:%02x\n",
++ pid, GW4200_MAX_WIDTH, GW4200_MAX_HEIGHT, priv->id[0], priv->id[1], priv->id[2], priv->id[3], priv->id[4], priv->id[5]);
++err:
++ gw4200_s_port(client, 0);
++
++ return ret;
++}
++
++static int gw4200_parse_dt(struct device_node *np, struct gw4200_priv *priv)
++{
++ struct i2c_client *client = v4l2_get_subdevdata(&priv->sd);
++ int i;
++ struct device_node *endpoint = NULL, *rendpoint = NULL;
++ int tmp_addr = 0;
++
++ for (i = 0; ; i++) {
++ endpoint = of_graph_get_next_endpoint(np, endpoint);
++ if (!endpoint)
++ break;
++
++ rendpoint = of_parse_phandle(endpoint, "remote-endpoint", 0);
++ if (!rendpoint)
++ continue;
++
++ if (!of_property_read_u32(rendpoint, "max9271-addr", &priv->max9271_addr) &&
++ !of_property_read_u32(rendpoint->parent->parent, "reg", &priv->max9286_addr) &&
++ !kstrtouint(strrchr(rendpoint->full_name, '@') + 1, 0, &priv->port))
++ break;
++ }
++
++ of_node_put(endpoint);
++
++ if (!priv->max9286_addr) {
++ dev_err(&client->dev, "deserializer does not present for GW4200\n");
++ return -EINVAL;
++ }
++
++ gw4200_s_port(client, 1);
++
++ /* setup I2C translator address */
++ tmp_addr = client->addr;
++ if (priv->max9286_addr) {
++ client->addr = priv->max9271_addr; /* Serializer I2C address */
++
++ reg8_write(client, 0x09, tmp_addr << 1); /* Sensor translated I2C address */
++ reg8_write(client, 0x0A, GW4200_I2C_ADDR << 1); /* Sensor native I2C address */
++ usleep_range(2000, 2500); /* wait 2ms */
++ };
++ client->addr = tmp_addr;
++
++ mdelay(10);
++
++ return 0;
++}
++
++static int gw4200_probe(struct i2c_client *client,
++ const struct i2c_device_id *did)
++{
++ struct gw4200_priv *priv;
++ int ret;
++
++ priv = devm_kzalloc(&client->dev, sizeof(*priv), GFP_KERNEL);
++ if (!priv)
++ return -ENOMEM;
++
++ v4l2_i2c_subdev_init(&priv->sd, client, &gw4200_subdev_ops);
++ priv->sd.flags = V4L2_SUBDEV_FL_HAS_DEVNODE;
++
++ priv->exposure = 0x100;
++ priv->gain = 0x100;
++ priv->autogain = 1;
++ v4l2_ctrl_handler_init(&priv->hdl, 4);
++ v4l2_ctrl_new_std(&priv->hdl, &gw4200_ctrl_ops,
++ V4L2_CID_BRIGHTNESS, 0, 16, 1, 7);
++ v4l2_ctrl_new_std(&priv->hdl, &gw4200_ctrl_ops,
++ V4L2_CID_CONTRAST, 0, 16, 1, 7);
++ v4l2_ctrl_new_std(&priv->hdl, &gw4200_ctrl_ops,
++ V4L2_CID_SATURATION, 0, 7, 1, 2);
++ v4l2_ctrl_new_std(&priv->hdl, &gw4200_ctrl_ops,
++ V4L2_CID_HUE, 0, 23, 1, 12);
++ v4l2_ctrl_new_std(&priv->hdl, &gw4200_ctrl_ops,
++ V4L2_CID_GAMMA, -128, 128, 1, 0);
++ v4l2_ctrl_new_std(&priv->hdl, &gw4200_ctrl_ops,
++ V4L2_CID_SHARPNESS, 0, 10, 1, 3);
++ v4l2_ctrl_new_std(&priv->hdl, &gw4200_ctrl_ops,
++ V4L2_CID_AUTOGAIN, 0, 1, 1, priv->autogain);
++ v4l2_ctrl_new_std(&priv->hdl, &gw4200_ctrl_ops,
++ V4L2_CID_GAIN, 0, 0xffff, 1, priv->gain);
++ v4l2_ctrl_new_std(&priv->hdl, &gw4200_ctrl_ops,
++ V4L2_CID_EXPOSURE, 0, 0xffff, 1, priv->exposure);
++ v4l2_ctrl_new_std(&priv->hdl, &gw4200_ctrl_ops,
++ V4L2_CID_HFLIP, 0, 1, 1, 1);
++ v4l2_ctrl_new_std(&priv->hdl, &gw4200_ctrl_ops,
++ V4L2_CID_VFLIP, 0, 1, 1, 0);
++ priv->sd.ctrl_handler = &priv->hdl;
++
++ ret = priv->hdl.error;
++ if (ret)
++ goto cleanup;
++
++ v4l2_ctrl_handler_setup(&priv->hdl);
++
++ priv->pad.flags = MEDIA_PAD_FL_SOURCE;
++ priv->sd.entity.flags |= MEDIA_ENT_F_CAM_SENSOR;
++ ret = media_entity_pads_init(&priv->sd.entity, 1, &priv->pad);
++ if (ret < 0)
++ goto cleanup;
++
++ ret = gw4200_parse_dt(client->dev.of_node, priv);
++ if (ret)
++ goto cleanup;
++
++ ret = gw4200_initialize(client);
++ if (ret < 0)
++ goto cleanup;
++
++ priv->rect.left = 0;
++ priv->rect.top = 0;
++ priv->rect.width = GW4200_MAX_WIDTH;
++ priv->rect.height = GW4200_MAX_HEIGHT;
++
++ ret = v4l2_async_register_subdev(&priv->sd);
++ if (ret)
++ goto cleanup;
++
++ if (device_create_file(&client->dev, &dev_attr_otp_id_gw4200) != 0) {
++ dev_err(&client->dev, "sysfs otp_id entry creation failed\n");
++ goto cleanup;
++ }
++
++ priv->init_complete = 1;
++
++ return 0;
++
++cleanup:
++ media_entity_cleanup(&priv->sd.entity);
++ v4l2_ctrl_handler_free(&priv->hdl);
++ v4l2_device_unregister_subdev(&priv->sd);
++#ifdef CONFIG_SOC_CAMERA_GW4200
++ v4l_err(client, "failed to probe @ 0x%02x (%s)\n",
++ client->addr, client->adapter->name);
++#endif
++ return ret;
++}
++
++static int gw4200_remove(struct i2c_client *client)
++{
++ struct gw4200_priv *priv = i2c_get_clientdata(client);
++
++ device_remove_file(&client->dev, &dev_attr_otp_id_gw4200);
++ v4l2_async_unregister_subdev(&priv->sd);
++ media_entity_cleanup(&priv->sd.entity);
++ v4l2_ctrl_handler_free(&priv->hdl);
++ v4l2_device_unregister_subdev(&priv->sd);
++
++ return 0;
++}
++
++#ifdef CONFIG_SOC_CAMERA_GW4200
++static const struct i2c_device_id gw4200_id[] = {
++ { "gw4200", 0 },
++ { }
++};
++MODULE_DEVICE_TABLE(i2c, gw4200_id);
++
++static const struct of_device_id gw4200_of_ids[] = {
++ { .compatible = "aptina,gw4200", },
++ { }
++};
++MODULE_DEVICE_TABLE(of, gw4200_of_ids);
++
++static struct i2c_driver gw4200_i2c_driver = {
++ .driver = {
++ .name = "gw4200",
++ .of_match_table = gw4200_of_ids,
++ },
++ .probe = gw4200_probe,
++ .remove = gw4200_remove,
++ .id_table = gw4200_id,
++};
++
++module_i2c_driver(gw4200_i2c_driver);
++
++MODULE_DESCRIPTION("SoC Camera driver for GW4200");
++MODULE_AUTHOR("Vladimir Barinov");
++MODULE_LICENSE("GPL");
++#endif
+diff --git a/drivers/media/i2c/soc_camera/gw4200_ar014x.h b/drivers/media/i2c/soc_camera/gw4200_ar014x.h
+new file mode 100644
+index 0000000..003f2a6
+--- /dev/null
++++ b/drivers/media/i2c/soc_camera/gw4200_ar014x.h
+@@ -0,0 +1,28 @@
++/*
++ * ON Semiconductor gw4200-ar014x sensor camera wizard 1280x720@30/UYVY/BT601/8bit
++ *
++ * Copyright (C) 2018 Cogent Embedded, Inc.
++ *
++ * This program is free software; you can redistribute it and/or modify it
++ * under the terms of the GNU General Public License as published by the
++ * Free Software Foundation; either version 2 of the License, or (at your
++ * option) any later version.
++ */
++
++#define GW4200_MAX_WIDTH 1280
++#define GW4200_MAX_HEIGHT 960
++
++#define GW4200_DELAY 0xffff
++
++struct gw4200_reg {
++ u16 reg;
++ u16 val;
++};
++
++static const struct gw4200_reg gw4200_regs_wizard[] = {
++/* enable FSIN */
++{0xc88c, 0x0303},
++{0xfc00, 0x2800},
++{0x0040, 0x8100},
++{GW4200_DELAY, 100},
++};
+diff --git a/drivers/media/i2c/soc_camera/imx390.c b/drivers/media/i2c/soc_camera/imx390.c
+new file mode 100644
+index 0000000..fc73b4b
+--- /dev/null
++++ b/drivers/media/i2c/soc_camera/imx390.c
+@@ -0,0 +1,574 @@
++/*
++ * OmniVision IMX390 sensor camera driver
++ *
++ * Copyright (C) 2018 Cogent Embedded, Inc.
++ *
++ * This program is free software; you can redistribute it and/or modify it
++ * under the terms of the GNU General Public License as published by the
++ * Free Software Foundation; either version 2 of the License, or (at your
++ * option) any later version.
++ */
++
++#include <linux/delay.h>
++#include <linux/init.h>
++#include <linux/i2c.h>
++#include <linux/module.h>
++#include <linux/of_graph.h>
++#include <linux/videodev2.h>
++
++#include <media/soc_camera.h>
++#include <media/v4l2-common.h>
++#include <media/v4l2-ctrls.h>
++
++#include "imx390.h"
++
++static const int imx390_i2c_addr[] = {0x21, 0x1a};
++
++#define IMX390_PID 0x0330
++#define IMX390_VER 0x0330
++#define IMX390_VERSION_REG 0x1515
++
++#define IMX390_MEDIA_BUS_FMT MEDIA_BUS_FMT_SRGGB12_1X12
++
++struct imx390_priv {
++ struct v4l2_subdev sd;
++ struct v4l2_ctrl_handler hdl;
++ struct media_pad pad;
++ struct v4l2_rect rect;
++ int init_complete;
++ u8 id[6];
++ int exposure;
++ int gain;
++ int autogain;
++ /* serializers */
++ int ti9x4_addr;
++ int ti9x3_addr;
++ int port;
++ int gpio_resetb;
++ int gpio_fsin;
++};
++
++static inline struct imx390_priv *to_imx390(const struct i2c_client *client)
++{
++ return container_of(i2c_get_clientdata(client), struct imx390_priv, sd);
++}
++
++static int imx390_set_regs(struct i2c_client *client,
++ const struct imx390_reg *regs, int nr_regs)
++{
++ int i;
++
++ for (i = 0; i < nr_regs; i++) {
++ if (regs[i].reg == IMX390_DELAY) {
++ mdelay(regs[i].val);
++ continue;
++ }
++
++ reg16_write(client, regs[i].reg, regs[i].val);
++ }
++
++ return 0;
++}
++
++static int imx390_s_stream(struct v4l2_subdev *sd, int enable)
++{
++ return 0;
++}
++
++static int imx390_get_fmt(struct v4l2_subdev *sd,
++ struct v4l2_subdev_pad_config *cfg,
++ struct v4l2_subdev_format *format)
++{
++ struct v4l2_mbus_framefmt *mf = &format->format;
++ struct i2c_client *client = v4l2_get_subdevdata(sd);
++ struct imx390_priv *priv = to_imx390(client);
++
++ if (format->pad)
++ return -EINVAL;
++
++ mf->width = priv->rect.width;
++ mf->height = priv->rect.height;
++ mf->code = IMX390_MEDIA_BUS_FMT;
++ mf->colorspace = V4L2_COLORSPACE_SMPTE170M;
++ mf->field = V4L2_FIELD_NONE;
++
++ return 0;
++}
++
++static int imx390_set_fmt(struct v4l2_subdev *sd,
++ struct v4l2_subdev_pad_config *cfg,
++ struct v4l2_subdev_format *format)
++{
++ struct v4l2_mbus_framefmt *mf = &format->format;
++
++ mf->code = IMX390_MEDIA_BUS_FMT;
++ mf->colorspace = V4L2_COLORSPACE_SMPTE170M;
++ mf->field = V4L2_FIELD_NONE;
++
++ if (format->which == V4L2_SUBDEV_FORMAT_TRY)
++ cfg->try_fmt = *mf;
++
++ return 0;
++}
++
++static int imx390_enum_mbus_code(struct v4l2_subdev *sd,
++ struct v4l2_subdev_pad_config *cfg,
++ struct v4l2_subdev_mbus_code_enum *code)
++{
++ if (code->pad || code->index > 0)
++ return -EINVAL;
++
++ code->code = IMX390_MEDIA_BUS_FMT;
++
++ return 0;
++}
++
++static int imx390_get_edid(struct v4l2_subdev *sd, struct v4l2_edid *edid)
++{
++ struct i2c_client *client = v4l2_get_subdevdata(sd);
++ struct imx390_priv *priv = to_imx390(client);
++
++ memcpy(edid->edid, priv->id, 6);
++
++ edid->edid[6] = 0xff;
++ edid->edid[7] = client->addr;
++ edid->edid[8] = IMX390_VERSION_REG >> 8;
++ edid->edid[9] = IMX390_VERSION_REG & 0xff;
++
++ return 0;
++}
++
++static int imx390_set_selection(struct v4l2_subdev *sd,
++ struct v4l2_subdev_pad_config *cfg,
++ struct v4l2_subdev_selection *sel)
++{
++ struct v4l2_rect *rect = &sel->r;
++ struct i2c_client *client = v4l2_get_subdevdata(sd);
++ struct imx390_priv *priv = to_imx390(client);
++
++ if (sel->which != V4L2_SUBDEV_FORMAT_ACTIVE ||
++ sel->target != V4L2_SEL_TGT_CROP)
++ return -EINVAL;
++
++ rect->left = ALIGN(rect->left, 2);
++ rect->top = ALIGN(rect->top, 2);
++ rect->width = ALIGN(rect->width, 2);
++ rect->height = ALIGN(rect->height, 2);
++
++ if ((rect->left + rect->width > IMX390_MAX_WIDTH) ||
++ (rect->top + rect->height > IMX390_MAX_HEIGHT))
++ *rect = priv->rect;
++
++ priv->rect.left = rect->left;
++ priv->rect.top = rect->top;
++ priv->rect.width = rect->width;
++ priv->rect.height = rect->height;
++
++ return 0;
++}
++
++static int imx390_get_selection(struct v4l2_subdev *sd,
++ struct v4l2_subdev_pad_config *cfg,
++ struct v4l2_subdev_selection *sel)
++{
++ struct i2c_client *client = v4l2_get_subdevdata(sd);
++ struct imx390_priv *priv = to_imx390(client);
++
++ if (sel->which != V4L2_SUBDEV_FORMAT_ACTIVE)
++ return -EINVAL;
++
++ switch (sel->target) {
++ case V4L2_SEL_TGT_CROP_BOUNDS:
++ sel->r.left = 0;
++ sel->r.top = 0;
++ sel->r.width = IMX390_MAX_WIDTH;
++ sel->r.height = IMX390_MAX_HEIGHT;
++ return 0;
++ case V4L2_SEL_TGT_CROP_DEFAULT:
++ sel->r.left = 0;
++ sel->r.top = 0;
++ sel->r.width = IMX390_MAX_WIDTH;
++ sel->r.height = IMX390_MAX_HEIGHT;
++ return 0;
++ case V4L2_SEL_TGT_CROP:
++ sel->r = priv->rect;
++ return 0;
++ default:
++ return -EINVAL;
++ }
++}
++
++static int imx390_g_mbus_config(struct v4l2_subdev *sd,
++ struct v4l2_mbus_config *cfg)
++{
++ cfg->flags = V4L2_MBUS_CSI2_1_LANE | V4L2_MBUS_CSI2_CHANNEL_0 |
++ V4L2_MBUS_CSI2_CONTINUOUS_CLOCK;
++ cfg->type = V4L2_MBUS_CSI2;
++
++ return 0;
++}
++
++#ifdef CONFIG_VIDEO_ADV_DEBUG
++static int imx390_g_register(struct v4l2_subdev *sd,
++ struct v4l2_dbg_register *reg)
++{
++ struct i2c_client *client = v4l2_get_subdevdata(sd);
++ int ret;
++ u8 val = 0;
++
++ ret = reg16_read(client, (u16)reg->reg, &val);
++ if (ret < 0)
++ return ret;
++
++ reg->val = val;
++ reg->size = sizeof(u8);
++
++ return 0;
++}
++
++static int imx390_s_register(struct v4l2_subdev *sd,
++ const struct v4l2_dbg_register *reg)
++{
++ struct i2c_client *client = v4l2_get_subdevdata(sd);
++
++ return reg16_write(client, (u16)reg->reg, (u8)reg->val);
++}
++#endif
++
++static struct v4l2_subdev_core_ops imx390_core_ops = {
++#ifdef CONFIG_VIDEO_ADV_DEBUG
++ .g_register = imx390_g_register,
++ .s_register = imx390_s_register,
++#endif
++};
++
++static int imx390_s_ctrl(struct v4l2_ctrl *ctrl)
++{
++ struct v4l2_subdev *sd = to_sd(ctrl);
++ struct i2c_client *client = v4l2_get_subdevdata(sd);
++ struct imx390_priv *priv = to_imx390(client);
++ int ret = -EINVAL;
++ int val;
++
++ if (!priv->init_complete)
++ return 0;
++
++ switch (ctrl->id) {
++ case V4L2_CID_BRIGHTNESS:
++ case V4L2_CID_CONTRAST:
++ case V4L2_CID_SATURATION:
++ case V4L2_CID_HUE:
++ case V4L2_CID_GAMMA:
++ case V4L2_CID_SHARPNESS:
++ case V4L2_CID_AUTOGAIN:
++ break;
++ case V4L2_CID_GAIN:
++ /* Digital gain */
++ ret = 0;
++ break;
++ case V4L2_CID_ANALOGUE_GAIN:
++ /* Analog gain */
++ ret = 0;
++ break;
++ case V4L2_CID_EXPOSURE:
++ val = 0xfff - ctrl->val;
++ ret = reg16_write(client, 0x0c, val); /* LSB */
++ ret |= reg16_write(client, 0x0d, val >> 8);
++// ret |= reg16_write(client, 0x0e, ctrl->val >> 16); /* MSB */
++ break;
++ case V4L2_CID_HFLIP:
++ case V4L2_CID_VFLIP:
++ break;
++ }
++
++ return ret;
++}
++
++static const struct v4l2_ctrl_ops imx390_ctrl_ops = {
++ .s_ctrl = imx390_s_ctrl,
++};
++
++static struct v4l2_subdev_video_ops imx390_video_ops = {
++ .s_stream = imx390_s_stream,
++ .g_mbus_config = imx390_g_mbus_config,
++};
++
++static const struct v4l2_subdev_pad_ops imx390_subdev_pad_ops = {
++ .get_edid = imx390_get_edid,
++ .enum_mbus_code = imx390_enum_mbus_code,
++ .get_selection = imx390_get_selection,
++ .set_selection = imx390_set_selection,
++ .get_fmt = imx390_get_fmt,
++ .set_fmt = imx390_set_fmt,
++};
++
++static struct v4l2_subdev_ops imx390_subdev_ops = {
++ .core = &imx390_core_ops,
++ .video = &imx390_video_ops,
++ .pad = &imx390_subdev_pad_ops,
++};
++
++static void imx390_otp_id_read(struct i2c_client *client)
++{
++ struct imx390_priv *priv = to_imx390(client);
++ int i;
++ u8 val = 0;
++
++ /* read camera id from imx390 OTP memory */
++ for (i = 0; i < 6; i++) {
++ reg16_read(client, 0x3050 + i, &val);
++ priv->id[i] = val;
++ }
++}
++
++static ssize_t imx390_otp_id_show(struct device *dev,
++ struct device_attribute *attr, char *buf)
++{
++ struct v4l2_subdev *sd = i2c_get_clientdata(to_i2c_client(dev));
++ struct i2c_client *client = v4l2_get_subdevdata(sd);
++ struct imx390_priv *priv = to_imx390(client);
++
++ imx390_otp_id_read(client);
++
++ return snprintf(buf, 32, "%02x:%02x:%02x:%02x:%02x:%02x\n",
++ priv->id[0], priv->id[1], priv->id[2], priv->id[3], priv->id[4], priv->id[5]);
++}
++
++static DEVICE_ATTR(otp_id_imx390, S_IRUGO, imx390_otp_id_show, NULL);
++
++static int imx390_initialize(struct i2c_client *client)
++{
++ struct imx390_priv *priv = to_imx390(client);
++ u8 val = 0;
++ u16 pid;
++ int ret = 0;
++ int tmp_addr;
++ int i;
++
++ for (i = 0; i < ARRAY_SIZE(imx390_i2c_addr); i++) {
++ tmp_addr = client->addr;
++ if (priv->ti9x4_addr) {
++ client->addr = priv->ti9x4_addr; /* Deserializer I2C address */
++ reg8_write(client, 0x5d, imx390_i2c_addr[i] << 1); /* Sensor native I2C address */
++ usleep_range(2000, 2500); /* wait 2ms */
++ }
++ client->addr = tmp_addr;
++
++ /* check model ID */
++ reg16_read(client, IMX390_PID, &val);
++ pid = val;
++ reg16_read(client, IMX390_VER, &val);
++ pid = (pid << 8) | val;
++
++ if (pid == IMX390_VERSION_REG)
++ break;
++ }
++
++ if (pid != IMX390_VERSION_REG) {
++ dev_dbg(&client->dev, "Product ID error %x\n", pid);
++ ret = -ENODEV;
++ goto err;
++ }
++
++#if 0
++ /* setup XCLK */
++ tmp_addr = client->addr;
++ if (priv->ti9x4_addr) {
++ /* CLK_OUT=22.5792*160*M/N/CLKDIV -> CLK_OUT=25MHz: CLKDIV=4, M=7, N=253: 22.5792*160/4*7/253=24.989MHz=CLK_OUT */
++ client->addr = priv->ti9x3_addr; /* Serializer I2C address */
++ reg8_write(client, 0x06, 0x47); /* Set CLKDIV and M */
++ reg8_write(client, 0x07, 0xfd); /* Set N */
++ }
++ client->addr = tmp_addr;
++#endif
++
++ /* Read OTP IDs */
++ imx390_otp_id_read(client);
++ /* Program wizard registers */
++ imx390_set_regs(client, imx390_regs_wizard, ARRAY_SIZE(imx390_regs_wizard));
++
++ dev_info(&client->dev, "imx390 PID %x, res %dx%d, OTP_ID %02x:%02x:%02x:%02x:%02x:%02x\n",
++ pid, IMX390_MAX_WIDTH, IMX390_MAX_HEIGHT, priv->id[0], priv->id[1], priv->id[2], priv->id[3], priv->id[4], priv->id[5]);
++
++err:
++ return ret;
++}
++
++static int imx390_parse_dt(struct device_node *np, struct imx390_priv *priv)
++{
++ struct i2c_client *client = v4l2_get_subdevdata(&priv->sd);
++ int i;
++ struct device_node *endpoint = NULL, *rendpoint = NULL;
++ int tmp_addr = 0;
++
++ for (i = 0; ; i++) {
++ endpoint = of_graph_get_next_endpoint(np, endpoint);
++ if (!endpoint)
++ break;
++
++ rendpoint = of_parse_phandle(endpoint, "remote-endpoint", 0);
++ if (!rendpoint)
++ continue;
++
++ if (!of_property_read_u32(rendpoint, "ti9x3-addr", &priv->ti9x3_addr) &&
++ !of_property_match_string(rendpoint->parent->parent, "compatible", "ti,ti9x4") &&
++ !of_property_read_u32(rendpoint->parent->parent, "reg", &priv->ti9x4_addr) &&
++ !kstrtouint(strrchr(rendpoint->full_name, '@') + 1, 0, &priv->port))
++ break;
++ }
++
++ of_node_put(endpoint);
++
++ if (!priv->ti9x4_addr) {
++ dev_err(&client->dev, "deserializer does not present\n");
++ return -EINVAL;
++ }
++
++ /* setup I2C translator address */
++ tmp_addr = client->addr;
++ if (priv->ti9x4_addr) {
++ client->addr = priv->ti9x4_addr; /* Deserializer I2C address */
++ reg8_write(client, 0x4c, (priv->port << 4) | (1 << priv->port)); /* Select RX port number */
++ usleep_range(2000, 2500); /* wait 2ms */
++ reg8_write(client, 0x65, tmp_addr << 1); /* Sensor translated I2C address */
++// reg8_write(client, 0x6e, 0xa9); /* GPIO0 - reset, GPIO1 - fsin */
++ }
++ client->addr = tmp_addr;
++
++ return 0;
++}
++
++static int imx390_probe(struct i2c_client *client,
++ const struct i2c_device_id *did)
++{
++ struct imx390_priv *priv;
++ int ret;
++
++ priv = devm_kzalloc(&client->dev, sizeof(*priv), GFP_KERNEL);
++ if (!priv)
++ return -ENOMEM;
++
++ v4l2_i2c_subdev_init(&priv->sd, client, &imx390_subdev_ops);
++ priv->sd.flags = V4L2_SUBDEV_FL_HAS_DEVNODE;
++
++ priv->exposure = 0x100;
++ priv->gain = 0x100;
++ priv->autogain = 1;
++ v4l2_ctrl_handler_init(&priv->hdl, 4);
++ v4l2_ctrl_new_std(&priv->hdl, &imx390_ctrl_ops,
++ V4L2_CID_BRIGHTNESS, 0, 16, 1, 7);
++ v4l2_ctrl_new_std(&priv->hdl, &imx390_ctrl_ops,
++ V4L2_CID_CONTRAST, 0, 16, 1, 7);
++ v4l2_ctrl_new_std(&priv->hdl, &imx390_ctrl_ops,
++ V4L2_CID_SATURATION, 0, 7, 1, 2);
++ v4l2_ctrl_new_std(&priv->hdl, &imx390_ctrl_ops,
++ V4L2_CID_HUE, 0, 23, 1, 12);
++ v4l2_ctrl_new_std(&priv->hdl, &imx390_ctrl_ops,
++ V4L2_CID_GAMMA, -128, 128, 1, 0);
++ v4l2_ctrl_new_std(&priv->hdl, &imx390_ctrl_ops,
++ V4L2_CID_SHARPNESS, 0, 10, 1, 3);
++ v4l2_ctrl_new_std(&priv->hdl, &imx390_ctrl_ops,
++ V4L2_CID_AUTOGAIN, 0, 1, 1, priv->autogain);
++ v4l2_ctrl_new_std(&priv->hdl, &imx390_ctrl_ops,
++ V4L2_CID_GAIN, 0, 0xffff, 1, priv->gain);
++ v4l2_ctrl_new_std(&priv->hdl, &imx390_ctrl_ops,
++ V4L2_CID_ANALOGUE_GAIN, 1, 0xe, 1, 0x7);
++ v4l2_ctrl_new_std(&priv->hdl, &imx390_ctrl_ops,
++ V4L2_CID_EXPOSURE, 0, 0xff0, 1, 0xfff - 0x2f2);
++ v4l2_ctrl_new_std(&priv->hdl, &imx390_ctrl_ops,
++ V4L2_CID_HFLIP, 0, 1, 1, 1);
++ v4l2_ctrl_new_std(&priv->hdl, &imx390_ctrl_ops,
++ V4L2_CID_VFLIP, 0, 1, 1, 0);
++ priv->sd.ctrl_handler = &priv->hdl;
++
++ ret = priv->hdl.error;
++ if (ret)
++ goto cleanup;
++
++ v4l2_ctrl_handler_setup(&priv->hdl);
++
++ priv->pad.flags = MEDIA_PAD_FL_SOURCE;
++ priv->sd.entity.flags |= MEDIA_ENT_F_CAM_SENSOR;
++ ret = media_entity_pads_init(&priv->sd.entity, 1, &priv->pad);
++ if (ret < 0)
++ goto cleanup;
++
++ ret = imx390_parse_dt(client->dev.of_node, priv);
++ if (ret)
++ goto cleanup;
++
++ ret = imx390_initialize(client);
++ if (ret < 0)
++ goto cleanup;
++
++ priv->rect.left = 0;
++ priv->rect.top = 0;
++ priv->rect.width = IMX390_MAX_WIDTH;
++ priv->rect.height = IMX390_MAX_HEIGHT;
++
++ ret = v4l2_async_register_subdev(&priv->sd);
++ if (ret)
++ goto cleanup;
++
++ if (device_create_file(&client->dev, &dev_attr_otp_id_imx390) != 0) {
++ dev_err(&client->dev, "sysfs otp_id entry creation failed\n");
++ goto cleanup;
++ }
++
++ priv->init_complete = 1;
++
++ return 0;
++
++cleanup:
++ media_entity_cleanup(&priv->sd.entity);
++ v4l2_ctrl_handler_free(&priv->hdl);
++ v4l2_device_unregister_subdev(&priv->sd);
++#ifdef CONFIG_SOC_CAMERA_IMX390
++ v4l_err(client, "failed to probe @ 0x%02x (%s)\n",
++ client->addr, client->adapter->name);
++#endif
++ return ret;
++}
++
++static int imx390_remove(struct i2c_client *client)
++{
++ struct imx390_priv *priv = i2c_get_clientdata(client);
++
++ device_remove_file(&client->dev, &dev_attr_otp_id_imx390);
++ v4l2_async_unregister_subdev(&priv->sd);
++ media_entity_cleanup(&priv->sd.entity);
++ v4l2_ctrl_handler_free(&priv->hdl);
++ v4l2_device_unregister_subdev(&priv->sd);
++
++ return 0;
++}
++
++#ifdef CONFIG_SOC_CAMERA_IMX390
++static const struct i2c_device_id imx390_id[] = {
++ { "imx390", 0 },
++ { }
++};
++MODULE_DEVICE_TABLE(i2c, imx390_id);
++
++static const struct of_device_id imx390_of_ids[] = {
++ { .compatible = "sony,imx390", },
++ { }
++};
++MODULE_DEVICE_TABLE(of, imx390_of_ids);
++
++static struct i2c_driver imx390_i2c_driver = {
++ .driver = {
++ .name = "imx390",
++ .of_match_table = imx390_of_ids,
++ },
++ .probe = imx390_probe,
++ .remove = imx390_remove,
++ .id_table = imx390_id,
++};
++
++module_i2c_driver(imx390_i2c_driver);
++
++MODULE_DESCRIPTION("SoC Camera driver for IMX390");
++MODULE_AUTHOR("Vladimir Barinov");
++MODULE_LICENSE("GPL");
++#endif
+diff --git a/drivers/media/i2c/soc_camera/imx390.h b/drivers/media/i2c/soc_camera/imx390.h
+new file mode 100644
+index 0000000..a7189e8
+--- /dev/null
++++ b/drivers/media/i2c/soc_camera/imx390.h
+@@ -0,0 +1,3818 @@
++/*
++ * OmniVision IMX390 sensor camera wizard 1920x1080@30/BGGR/MIPI
++ *
++ * Copyright (C) 2018 Cogent Embedded, Inc.
++ *
++ * This program is free software; you can redistribute it and/or modify it
++ * under the terms of the GNU General Public License as published by the
++ * Free Software Foundation; either version 2 of the License, or (at your
++ * option) any later version.
++ */
++
++//#define IMX390_DISPLAY_PATTERN_COLOR_BAR
++
++#define IMX390_MAX_WIDTH 1920
++#define IMX390_MAX_HEIGHT 1080
++
++#define IMX390_DELAY 0xffff
++#define IMX390_DT 0x2c /* MIPI Data Type RAW12 */
++
++struct imx390_reg {
++ u16 reg;
++ u8 val;
++};
++
++/* wizard: MIPI 1920x1080 RAW12 Linear 30fps 700Mbps */
++static const struct imx390_reg imx390_regs_wizard[] = {
++{0x000C, 0xF2},
++{0x000D, 0x02},
++{0x000E, 0x00},
++{0x0010, 0xF2},
++{0x0011, 0x02},
++{0x0012, 0x00},
++{0x0018, 0x15},
++{0x0019, 0x00},
++{0x001A, 0x0C},
++{0x001B, 0x00},
++{0x0038, 0x00},
++{0x003C, 0x00},
++{0x003D, 0x00},
++{0x003E, 0x00},
++{0x0040, 0x00},
++{0x0041, 0x00},
++{0x0042, 0x00},
++{0x0044, 0x00},
++{0x0045, 0x00},
++{0x0046, 0x00},
++{0x0048, 0x00},
++{0x0049, 0x00},
++{0x004A, 0x00},
++{0x004C, 0x00},
++{0x004D, 0x00},
++{0x004E, 0x00},
++{0x0050, 0x00},
++{0x0051, 0x00},
++{0x0052, 0x00},
++{0x0054, 0x00},
++{0x0055, 0x00},
++{0x0056, 0x00},
++{0x0058, 0x00},
++{0x0059, 0x00},
++{0x005A, 0x00},
++{0x005C, 0x00},
++{0x005D, 0x00},
++{0x005E, 0x00},
++{0x0060, 0x00},
++{0x0061, 0x00},
++{0x0062, 0x00},
++{0x0064, 0x00},
++{0x0065, 0x00},
++{0x0066, 0x00},
++{0x0068, 0x00},
++{0x0069, 0x00},
++{0x006A, 0x00},
++{0x0078, 0x00},
++{0x007C, 0x00},
++{0x007D, 0x00},
++{0x0080, 0x00},
++{0x0081, 0x00},
++{0x00F4, 0x1C},
++{0x00F5, 0xF8},
++{0x00F6, 0x01},
++{0x00F8, 0x03},
++{0x00F9, 0x00}, // non-HDR
++//{0x00F9, 0x01}, // HDR
++{0x00FA, 0x00},
++{0x00FB, 0x00},
++{0x0114, 0x00},
++{0x0115, 0x01},
++{0x0118, 0x20},
++{0x0119, 0x03},
++{0x011A, 0x00},
++{0x011B, 0x41},
++{0x011C, 0x80},
++{0x011D, 0x00},
++{0x0120, 0x20},
++{0x0121, 0x00},
++{0x0122, 0x00},
++{0x0123, 0x44},
++{0x0124, 0x00},
++{0x0125, 0x01},
++{0x0128, 0xAC},
++{0x0129, 0x0D},
++{0x012A, 0x00},
++{0x012B, 0xA4},
++{0x012C, 0x00},
++{0x012D, 0x01},
++{0x0130, 0xC4},
++{0x0131, 0x09},
++{0x0132, 0x00},
++{0x0133, 0xDA},
++//{0x013A, ,3},
++{0x013B, 0x01},
++//{0x013C, ,3},
++//{0x013D, ,3},
++//{0x013E, ,3},
++//{0x0140, ,3},
++//{0x0141, ,3},
++//{0x0142, ,3},
++//{0x0144, ,3},
++//{0x0145, ,3},
++//{0x0146, ,3},
++//{0x0148, ,3},
++//{0x0149, ,3},
++//{0x014A, ,3},
++//{0x014C, ,3},
++//{0x014D, ,3},
++//{0x014E, ,3},
++//{0x0150, ,3},
++//{0x0151, ,3},
++//{0x0152, ,3},
++//{0x0154, ,3},
++//{0x0155, ,3},
++//{0x0156, ,3},
++//{0x0158, ,3},
++//{0x0159, ,3},
++//{0x015A, ,3},
++//{0x015C, ,3},
++//{0x015D, ,3},
++//{0x015E, ,3},
++//{0x0160, ,3},
++//{0x0161, ,3},
++//{0x0162, ,3},
++//{0x0164, ,3},
++//{0x0165, ,3},
++//{0x0166, ,3},
++//{0x0168, ,3},
++//{0x0169, ,3},
++//{0x016A, ,3},
++//{0x016C, ,3},
++//{0x016D, ,3},
++//{0x016E, ,3},
++//{0x0170, ,3},
++//{0x0171, ,3},
++//{0x0172, ,3},
++//{0x0174, ,3},
++//{0x0175, ,3},
++//{0x0176, ,3},
++//{0x0178, ,3},
++//{0x0179, ,3},
++//{0x017A, ,3},
++//{0x017C, ,3},
++//{0x017D, ,3},
++//{0x017E, ,3},
++//{0x0180, ,3},
++//{0x0181, ,3},
++//{0x0182, ,3},
++//{0x0184, ,3},
++//{0x0185, ,3},
++//{0x0186, ,3},
++//{0x0188, ,3},
++//{0x0189, ,3},
++//{0x018A, ,3},
++//{0x018C, ,3},
++//{0x018D, ,3},
++//{0x018E, ,3},
++//{0x0190, ,3},
++//{0x0191, ,3},
++//{0x0192, ,3},
++//{0x0194, ,3},
++//{0x0195, ,3},
++//{0x0196, ,3},
++//{0x0198, ,3},
++//{0x0199, ,3},
++//{0x019A, ,3},
++//{0x019B, ,3},
++//{0x019C, ,3},
++//{0x019D, ,3},
++//{0x019E, ,3},
++//{0x019F, ,3},
++//{0x01A0, ,3},
++//{0x01A1, ,3},
++//{0x01A2, ,3},
++//{0x01A3, ,3},
++//{0x01A4, ,3},
++//{0x01A5, ,3},
++//{0x01A6, ,3},
++//{0x01A7, ,3},
++//{0x01A8, ,3},
++//{0x01A9, ,3},
++//{0x01AA, ,3},
++//{0x01AB, ,3},
++//{0x01AC, ,3},
++//{0x01AD, ,3},
++//{0x01AE, ,3},
++//{0x01AF, ,3},
++//{0x01B0, ,3},
++//{0x01B1, ,3},
++//{0x01B2, ,3},
++//{0x01B3, ,3},
++//{0x01B4, ,3},
++//{0x01B5, ,3},
++//{0x01B6, ,3},
++//{0x01B7, ,3},
++//{0x01B8, ,3},
++//{0x01B9, ,3},
++//{0x01BA, ,3},
++//{0x01BB, ,3},
++//{0x01BC, ,3},
++//{0x01BD, ,3},
++//{0x01BE, ,3},
++//{0x01BF, ,3},
++//{0x01C0, ,3},
++//{0x01C1, ,3},
++//{0x01C2, ,3},
++//{0x01C3, ,3},
++{0x01C4, 0x00},
++{0x01C5, 0x00},
++{0x01CC, 0x01},
++{0x01D0, 0x09},
++{0x01D4, 0x01},
++{0x0232, 0x7E},
++{0x0233, 0x00},
++{0x0390, 0x00},
++{0x0391, 0x00},
++{0x0392, 0x00},
++#ifdef IMX390_DISPLAY_PATTERN_COLOR_BAR
++{0x01DB, 0x32},
++{0x03C0, 0x02},
++#else
++{0x03C0, 0x00},
++#endif
++{0x2000, 0x55},
++{0x2001, 0x55},
++{0x2002, 0x55},
++{0x2003, 0x05},
++{0x2004, 0x02},
++{0x2008, 0x65},
++{0x2009, 0x04},
++{0x200A, 0x00},
++{0x200C, 0x30},
++{0x200D, 0x11},
++{0x2010, 0x04},
++{0x2014, 0x01},
++{0x2018, 0x02},
++{0x2019, 0x04},
++{0x201A, 0x00},
++{0x201C, 0x21},
++{0x201D, 0x11},
++{0x201E, 0x00},
++{0x201F, 0x00},
++{0x2020, 0xBC},
++{0x2021, 0x00},
++{0x2022, 0x7F},
++{0x2023, 0x00},
++{0x2024, 0xBA},
++{0x2025, 0x00},
++{0x2026, 0x81},
++{0x2027, 0x00},
++{0x2028, 0x7D},
++{0x2029, 0x90},
++{0x202A, 0x05},
++{0x202C, 0xFC},
++{0x202D, 0x02},
++{0x202E, 0x25},
++{0x202F, 0x03},
++{0x2030, 0x05},
++{0x2031, 0x02},
++{0x2032, 0xCA},
++{0x2033, 0x02},
++{0x2034, 0xFC},
++{0x2035, 0x02},
++{0x2036, 0x25},
++{0x2037, 0x03},
++{0x2038, 0x25},
++{0x2039, 0x97},
++{0x203A, 0xEC},
++{0x203B, 0x01},
++{0x203C, 0xF5},
++{0x203D, 0x8E},
++{0x203E, 0x0C},
++{0x203F, 0x2D},
++{0x2040, 0x69},
++{0x2041, 0x01},
++{0x2042, 0x8E},
++{0x2043, 0x01},
++{0x2044, 0x0C},
++{0x2045, 0x02},
++{0x2046, 0x31},
++{0x2047, 0x02},
++{0x2048, 0x6A},
++{0x2049, 0x01},
++{0x204A, 0x8E},
++{0x204B, 0x01},
++{0x204C, 0x0D},
++{0x204D, 0x02},
++{0x204E, 0x31},
++{0x204F, 0x02},
++{0x2050, 0x7B},
++{0x2051, 0x00},
++{0x2052, 0x7D},
++{0x2053, 0x00},
++{0x2054, 0x95},
++{0x2055, 0x00},
++{0x2056, 0x97},
++{0x2057, 0x00},
++{0x2058, 0xAD},
++{0x2059, 0x00},
++{0x205A, 0xAF},
++{0x205B, 0x00},
++{0x205C, 0x92},
++{0x205D, 0x00},
++{0x205E, 0x94},
++{0x205F, 0x00},
++{0x2060, 0x8E},
++{0x2061, 0x00},
++{0x2062, 0x90},
++{0x2063, 0x00},
++{0x2064, 0xB1},
++{0x2065, 0x00},
++{0x2066, 0xB3},
++{0x2067, 0x00},
++{0x2068, 0x08},
++{0x2069, 0x00},
++{0x206A, 0x04},
++{0x206B, 0x00},
++{0x206C, 0x84},
++{0x206D, 0x00},
++{0x206E, 0x80},
++{0x206F, 0x00},
++{0x2070, 0x04},
++{0x2071, 0x00},
++{0x2072, 0x46},
++{0x2073, 0x00},
++{0x2074, 0xE9},
++{0x2075, 0x01},
++{0x2076, 0x74},
++{0x2077, 0x02},
++{0x2078, 0x80},
++{0x2079, 0x00},
++{0x207A, 0xC1},
++{0x207B, 0x00},
++{0x207C, 0xFF},
++{0x207D, 0x03},
++{0x207E, 0xFF},
++{0x207F, 0x03},
++{0x2080, 0x78},
++{0x2081, 0x00},
++{0x2082, 0x6A},
++{0x2083, 0x01},
++{0x2084, 0xE4},
++{0x2085, 0x01},
++{0x2086, 0x2B},
++{0x2087, 0x03},
++{0x2088, 0x00},
++{0x2089, 0x00},
++{0x208A, 0xFF},
++{0x208B, 0x03},
++{0x208C, 0xFF},
++{0x208D, 0x03},
++{0x208E, 0xFF},
++{0x208F, 0x03},
++{0x2090, 0x7D},
++{0x2091, 0x00},
++{0x2092, 0x62},
++{0x2093, 0x01},
++{0x2094, 0xE9},
++{0x2095, 0x01},
++{0x2096, 0x00},
++{0x2097, 0x00},
++{0x2098, 0x7C},
++{0x2099, 0x00},
++{0x209A, 0x21},
++{0x209B, 0x03},
++{0x209C, 0xE9},
++{0x209D, 0x01},
++{0x209E, 0x21},
++{0x209F, 0x03},
++{0x20A0, 0xFF},
++{0x20A1, 0x03},
++{0x20A2, 0xFF},
++{0x20A3, 0x03},
++{0x20A4, 0xFF},
++{0x20A5, 0x03},
++{0x20A6, 0xFF},
++{0x20A7, 0x03},
++{0x20A8, 0xFF},
++{0x20A9, 0x03},
++{0x20AA, 0xFF},
++{0x20AB, 0x03},
++{0x20AC, 0xFF},
++{0x20AD, 0x03},
++{0x20AE, 0xFF},
++{0x20AF, 0x03},
++{0x20B0, 0xFF},
++{0x20B1, 0x03},
++{0x20B2, 0xFF},
++{0x20B3, 0x03},
++{0x20B4, 0x87},
++{0x20B5, 0xCC},
++{0x20B6, 0x87},
++{0x20B7, 0x08},
++{0x20B8, 0xF4},
++{0x20B9, 0xA5},
++{0x20BA, 0x07},
++{0x20BC, 0x1F},
++{0x20BD, 0x01},
++{0x20BE, 0xF6},
++{0x20BF, 0x00},
++{0x20C0, 0x90},
++{0x20C1, 0x01},
++{0x20C2, 0x67},
++{0x20C3, 0x01},
++{0x20C4, 0xFF},
++{0x20C5, 0x03},
++{0x20C6, 0xFF},
++{0x20C7, 0x03},
++{0x20C8, 0x33},
++{0x20C9, 0x02},
++{0x20CA, 0x0A},
++{0x20CB, 0x02},
++{0x20CC, 0x7F},
++{0x20CD, 0x00},
++{0x20CE, 0xD2},
++{0x20CF, 0x00},
++{0x20D0, 0x81},
++{0x20D1, 0x00},
++{0x20D2, 0x87},
++{0x20D3, 0x00},
++{0x20D4, 0x09},
++{0x20D5, 0x00},
++{0x20D8, 0x7F},
++{0x20D9, 0x00},
++{0x20DA, 0x62},
++{0x20DB, 0x01},
++{0x20DC, 0x7F},
++{0x20DD, 0x00},
++{0x20DE, 0x62},
++{0x20DF, 0x01},
++{0x20E0, 0x65},
++{0x20E1, 0x00},
++{0x20E2, 0x75},
++{0x20E3, 0x00},
++{0x20E4, 0xE0},
++{0x20E5, 0x00},
++{0x20E6, 0xF0},
++{0x20E7, 0x00},
++{0x20E8, 0x4C},
++{0x20E9, 0x01},
++{0x20EA, 0x5C},
++{0x20EB, 0x01},
++{0x20EC, 0xD1},
++{0x20ED, 0x01},
++{0x20EE, 0xE1},
++{0x20EF, 0x01},
++{0x20F0, 0x93},
++{0x20F1, 0x02},
++{0x20F2, 0xA3},
++{0x20F3, 0x02},
++{0x20F4, 0x0D},
++{0x20F5, 0x03},
++{0x20F6, 0x1D},
++{0x20F7, 0x03},
++{0x20F8, 0x57},
++{0x20F9, 0x00},
++{0x20FA, 0x7B},
++{0x20FB, 0x00},
++{0x20FC, 0xD2},
++{0x20FD, 0x00},
++{0x20FE, 0xF6},
++{0x20FF, 0x00},
++{0x2100, 0x3E},
++{0x2101, 0x01},
++{0x2102, 0x60},
++{0x2103, 0x01},
++{0x2104, 0xC3},
++{0x2105, 0x01},
++{0x2106, 0xE5},
++{0x2107, 0x01},
++{0x2108, 0x85},
++{0x2109, 0x02},
++{0x210A, 0xA9},
++{0x210B, 0x02},
++{0x210C, 0xFF},
++{0x210D, 0x02},
++{0x210E, 0x21},
++{0x210F, 0x03},
++{0x2110, 0xFF},
++{0x2111, 0x03},
++{0x2112, 0x00},
++{0x2113, 0x00},
++{0x2114, 0xFF},
++{0x2115, 0x03},
++{0x2116, 0xFF},
++{0x2117, 0x03},
++{0x2118, 0xFF},
++{0x2119, 0x03},
++{0x211A, 0xFF},
++{0x211B, 0x03},
++{0x211C, 0xFF},
++{0x211D, 0x03},
++{0x211E, 0xFF},
++{0x211F, 0x03},
++{0x2120, 0xFF},
++{0x2121, 0x03},
++{0x2122, 0xFF},
++{0x2123, 0x03},
++{0x2124, 0xFF},
++{0x2125, 0x03},
++{0x2126, 0xFF},
++{0x2127, 0x03},
++{0x2128, 0x7D},
++{0x2129, 0x90},
++{0x212A, 0xD5},
++{0x212B, 0x07},
++{0x212C, 0x64},
++{0x212D, 0x01},
++{0x2130, 0x5F},
++{0x2131, 0x7D},
++{0x2132, 0x05},
++{0x2134, 0x78},
++{0x2135, 0x00},
++{0x2136, 0x76},
++{0x2137, 0x00},
++{0x2138, 0xF3},
++{0x2139, 0x00},
++{0x213A, 0xF1},
++{0x213B, 0x00},
++{0x213C, 0xA6},
++{0x213D, 0x02},
++{0x213E, 0xA4},
++{0x213F, 0x02},
++{0x2140, 0x7D},
++{0x2141, 0x00},
++{0x2142, 0x8D},
++{0x2143, 0x00},
++{0x2144, 0xA1},
++{0x2145, 0x01},
++{0x2146, 0xB1},
++{0x2147, 0x01},
++{0x2148, 0xAB},
++{0x2149, 0x02},
++{0x214A, 0xBB},
++{0x214B, 0x02},
++{0x214C, 0x17},
++{0x214D, 0x5C},
++{0x214E, 0x00},
++{0x2150, 0x00},
++{0x2151, 0x00},
++{0x2152, 0xF8},
++{0x2153, 0x00},
++{0x2154, 0xBE},
++{0x2155, 0x00},
++{0x2156, 0x7D},
++{0x2157, 0x00},
++{0x2158, 0x25},
++{0x2159, 0x00},
++{0x215A, 0x7D},
++{0x215B, 0x00},
++{0x215C, 0x62},
++{0x215D, 0x01},
++{0x215E, 0xFF},
++{0x215F, 0x03},
++{0x2160, 0x26},
++{0x2161, 0x00},
++{0x2162, 0x7D},
++{0x2163, 0x00},
++{0x2164, 0x63},
++{0x2165, 0x01},
++{0x2166, 0xFF},
++{0x2167, 0x03},
++{0x2168, 0xCB},
++{0x2169, 0x02},
++{0x216A, 0xCF},
++{0x216B, 0x02},
++{0x216C, 0xFF},
++{0x216D, 0x03},
++{0x216E, 0xFF},
++{0x216F, 0x03},
++{0x2170, 0xFF},
++{0x2171, 0x03},
++{0x2172, 0xFF},
++{0x2173, 0x03},
++{0x2174, 0xFF},
++{0x2175, 0x03},
++{0x2176, 0xFF},
++{0x2177, 0x03},
++{0x2178, 0x7E},
++{0x2179, 0x00},
++{0x217A, 0xBD},
++{0x217B, 0x00},
++{0x217C, 0xEC},
++{0x217D, 0x01},
++{0x217E, 0x7B},
++{0x217F, 0x02},
++{0x2180, 0xD1},
++{0x2181, 0x02},
++{0x2182, 0x25},
++{0x2183, 0x03},
++{0x2184, 0x7F},
++{0x2185, 0x00},
++{0x2186, 0xBD},
++{0x2187, 0x00},
++{0x2188, 0xED},
++{0x2189, 0x01},
++{0x218A, 0x7B},
++{0x218B, 0x02},
++{0x218C, 0xD2},
++{0x218D, 0x02},
++{0x218E, 0x25},
++{0x218F, 0x03},
++{0x2190, 0xFF},
++{0x2191, 0x03},
++{0x2192, 0xFF},
++{0x2193, 0x03},
++{0x2194, 0xE9},
++{0x2195, 0x01},
++{0x2196, 0x21},
++{0x2197, 0x03},
++{0x2198, 0x17},
++{0x2199, 0xFC},
++{0x219A, 0x7F},
++{0x219B, 0x01},
++{0x219C, 0xFF},
++{0x219D, 0x03},
++{0x21A0, 0x1B},
++{0x21A1, 0x1B},
++{0x21A2, 0x1B},
++{0x21A3, 0x1B},
++{0x21A4, 0x2E},
++{0x21A5, 0x80},
++{0x21A6, 0x00},
++{0x21A8, 0x04},
++{0x21A9, 0x98},
++{0x21AA, 0x60},
++{0x21AB, 0x03},
++{0x21AC, 0x7F},
++{0x21AD, 0x80},
++{0x21AE, 0x09},
++{0x21B0, 0x1C},
++{0x21B1, 0x00},
++{0x21B2, 0xA0},
++{0x21B3, 0x00},
++{0x21B4, 0x0C},
++{0x21B5, 0x00},
++{0x21B6, 0x2D},
++{0x21B7, 0x00},
++{0x21B8, 0x20},
++{0x21B9, 0x00},
++{0x21BA, 0x02},
++{0x21BB, 0x00},
++{0x21BC, 0xCC},
++{0x21BD, 0x00},
++{0x21BE, 0x4A},
++{0x21BF, 0x00},
++{0x21C0, 0xD0},
++{0x21C1, 0x00},
++{0x21C2, 0x44},
++{0x21C3, 0x00},
++{0x21C4, 0x00},
++{0x21C5, 0xE0},
++{0x21C6, 0x00},
++{0x21C8, 0x11},
++{0x21C9, 0x00},
++{0x21CA, 0x02},
++{0x21CC, 0x08},
++{0x21CD, 0xC0},
++{0x21CE, 0x0C},
++{0x21D0, 0x44},
++{0x21D1, 0x00},
++{0x21D2, 0x02},
++{0x21D4, 0x02},
++{0x21D5, 0x20},
++{0x21D6, 0x2C},
++{0x21D8, 0xFE},
++{0x21D9, 0x9D},
++{0x21DA, 0xDF},
++{0x21DB, 0x03},
++{0x21DC, 0x62},
++{0x21DD, 0x01},
++{0x21DE, 0x7F},
++{0x21DF, 0x00},
++{0x21E0, 0xB7},
++{0x21E1, 0x01},
++{0x21E2, 0xB5},
++{0x21E3, 0x01},
++{0x21E4, 0xC1},
++{0x21E5, 0x02},
++{0x21E6, 0xBF},
++{0x21E7, 0x02},
++{0x21E8, 0xB3},
++{0x21E9, 0x0D},
++{0x21EA, 0x00},
++{0x21EB, 0x04},
++#if 1
++{0x21EC, 0x90},
++{0x21ED, 0x07},
++{0x21EE, 0x58},
++{0x21EF, 0x04},
++#else
++{0x21EC, 0x80},
++{0x21ED, 0x07},
++{0x21EE, 0x38},
++{0x21EF, 0x04},
++#endif
++{0x21F0, 0x54},
++{0x21F1, 0x04},
++{0x21F4, 0x02},
++{0x21F5, 0x00},
++{0x21F6, 0x00},
++{0x21F8, 0x3C},
++{0x21F9, 0x00},
++{0x21FC, 0x28},
++{0x21FD, 0x00},
++{0x21FE, 0x3C},
++{0x21FF, 0x00},
++{0x2200, 0x00},
++{0x2204, 0x4C},
++{0x2205, 0x04},
++{0x2206, 0x65},
++{0x2207, 0x04},
++{0x2208, 0x0A},
++{0x2209, 0x00},
++{0x220C, 0x47},
++{0x220D, 0x00},
++{0x220E, 0x1F},
++{0x220F, 0x00},
++{0x2210, 0x17},
++{0x2211, 0x00},
++{0x2212, 0x0F},
++{0x2213, 0x00},
++{0x2214, 0x17},
++{0x2215, 0x00},
++{0x2216, 0x47},
++{0x2217, 0x00},
++{0x2218, 0x0F},
++{0x2219, 0x00},
++{0x221A, 0x0F},
++{0x221B, 0x00},
++{0x221C, 0x03},
++{0x2220, 0x20},
++{0x2221, 0x20},
++{0x2222, 0x22},
++{0x2223, 0x02},
++{0x2224, 0xA7},
++{0x2225, 0xAA},
++{0x2226, 0x80},
++{0x2227, 0x08},
++{0x2228, 0x01},
++{0x22B2, 0x92},
++{0x22B4, 0x20},
++{0x22B5, 0x00},
++{0x22B6, 0x20},
++{0x22B7, 0x00},
++{0x22B8, 0x20},
++{0x22B9, 0x00},
++{0x22BA, 0x20},
++{0x22BB, 0x00},
++{0x22BC, 0x20},
++{0x22BD, 0x00},
++{0x22BE, 0x20},
++{0x22BF, 0x00},
++{0x22C0, 0x20},
++{0x22C1, 0x00},
++{0x22C2, 0x20},
++{0x22C3, 0x00},
++{0x22C4, 0x20},
++{0x22C5, 0x00},
++{0x22C6, 0x20},
++{0x22C7, 0x00},
++{0x22C8, 0x20},
++{0x22C9, 0x00},
++{0x22CA, 0x20},
++{0x22CB, 0x00},
++{0x22CC, 0x20},
++{0x22CD, 0x00},
++{0x22CE, 0x20},
++{0x22CF, 0x00},
++{0x22DA, 0x00},
++{0x2308, 0x01},
++{0x2311, 0x09},
++{0x2318, 0x40},
++{0x2319, 0xCD},
++{0x231A, 0x54},
++{0x2324, 0x20},
++{0x2325, 0x00},
++{0x2328, 0x00},
++{0x2354, 0x0C},
++{0x23C0, 0x5D},
++{0x244C, 0x00},
++{0x244D, 0x02},
++{0x244E, 0x54},
++{0x244F, 0x02},
++{0x24A0, 0x00},
++{0x24DA, 0x6F},
++{0x24DB, 0x00},
++{0x24DC, 0x62},
++{0x24DD, 0x01},
++{0x24EA, 0x32},
++{0x24EB, 0x00},
++{0x24EC, 0xDC},
++{0x24ED, 0x00},
++{0x24FA, 0x32},
++{0x24FB, 0x00},
++{0x24FC, 0xDD},
++{0x24FD, 0x00},
++{0x254A, 0x15},
++{0x254B, 0x01},
++{0x255A, 0x15},
++{0x255B, 0x01},
++{0x2560, 0x01},
++{0x2561, 0x00},
++{0x2562, 0x2A},
++{0x2563, 0x00},
++{0x2564, 0xF8},
++{0x2565, 0x00},
++{0x2566, 0x15},
++{0x2567, 0x01},
++{0x2568, 0x0C},
++{0x2569, 0x02},
++{0x256A, 0x31},
++{0x256B, 0x02},
++{0x2578, 0x90},
++{0x2579, 0x01},
++{0x257A, 0x92},
++{0x257B, 0x01},
++{0x257C, 0xB8},
++{0x257D, 0x02},
++{0x257E, 0xBA},
++{0x257F, 0x02},
++{0x2584, 0x90},
++{0x2585, 0x01},
++{0x2586, 0x92},
++{0x2587, 0x01},
++{0x2588, 0xB8},
++{0x2589, 0x02},
++{0x258A, 0xBA},
++{0x258B, 0x02},
++{0x26B8, 0x10},
++{0x26B9, 0x00},
++{0x26BA, 0x33},
++{0x26BB, 0x00},
++{0x26BC, 0x89},
++{0x26BD, 0x00},
++{0x26BE, 0xB0},
++{0x26BF, 0x00},
++{0x26C4, 0x4E},
++{0x26C5, 0x00},
++{0x26C8, 0xC9},
++{0x26C9, 0x00},
++{0x26CC, 0x35},
++{0x26CD, 0x01},
++{0x26D0, 0xBA},
++{0x26D1, 0x01},
++{0x26D4, 0x7C},
++{0x26D5, 0x02},
++{0x26D8, 0xF6},
++{0x26D9, 0x02},
++{0x26DE, 0x51},
++{0x26DF, 0x00},
++{0x26E0, 0x7F},
++{0x26E1, 0x00},
++{0x26E2, 0xCC},
++{0x26E3, 0x00},
++{0x26E4, 0xF8},
++{0x26E5, 0x00},
++{0x26E6, 0x38},
++{0x26E7, 0x01},
++{0x26E8, 0x65},
++{0x26E9, 0x01},
++{0x26EA, 0xBD},
++{0x26EB, 0x01},
++{0x26EE, 0x7F},
++{0x26EF, 0x02},
++{0x26F0, 0xAB},
++{0x26F1, 0x02},
++{0x26F2, 0xF9},
++{0x26F3, 0x02},
++{0x2722, 0x59},
++{0x2723, 0x02},
++{0x2938, 0x55},
++{0x2939, 0x00},
++{0x293A, 0x17},
++{0x293B, 0x00},
++{0x293C, 0xD0},
++{0x293D, 0x00},
++{0x293E, 0x91},
++{0x293F, 0x00},
++{0x2940, 0x3C},
++{0x2941, 0x01},
++{0x2942, 0x0C},
++{0x2943, 0x01},
++{0x2944, 0xC1},
++{0x2945, 0x01},
++{0x2946, 0x76},
++{0x2947, 0x01},
++{0x2948, 0x83},
++{0x2949, 0x02},
++{0x294A, 0xFB},
++{0x294B, 0x01},
++{0x294C, 0xFD},
++{0x294D, 0x02},
++{0x294E, 0xBF},
++{0x294F, 0x02},
++{0x2A06, 0xFF},
++{0x2A07, 0x03},
++{0x2A20, 0x00},
++{0x2A21, 0x00},
++{0x2A22, 0x7D},
++{0x2A23, 0x00},
++{0x2B11, 0x19},
++{0x2B13, 0x15},
++{0x2B14, 0x14},
++{0x2B15, 0x13},
++{0x2B16, 0x12},
++{0x2B17, 0x11},
++{0x2B18, 0x10},
++{0x2B19, 0x0F},
++{0x2B1A, 0x0E},
++{0x2B1B, 0x0D},
++{0x2B1C, 0x0C},
++{0x2B1D, 0x0B},
++{0x2B1E, 0x0A},
++{0x2B1F, 0x09},
++{0x2B20, 0x08},
++{0x2B21, 0x07},
++{0x2B22, 0x06},
++{0x2B23, 0x05},
++{0x2B24, 0x04},
++{0x2B25, 0x03},
++{0x2B26, 0x03},
++{0x2B38, 0x01},
++{0x2B45, 0xE3},
++{0x2B50, 0x01},
++{0x2B51, 0x00},
++//{0x2B62, ,3},
++{0x2B6D, 0x47},
++{0x2B70, 0x02},
++{0x2B71, 0x02},
++{0x2B72, 0x02},
++{0x2B7F, 0x7F},
++{0x2B80, 0x94},
++{0x2B81, 0x06},
++{0x2B87, 0x1B},
++{0x2B88, 0x1B},
++{0x2B89, 0x17},
++{0x2B8A, 0x12},
++{0x2B8B, 0x12},
++{0x2B8D, 0x2B},
++{0x2B8E, 0x2B},
++{0x2B8F, 0x2B},
++{0x2B90, 0x7F},
++{0x2B91, 0x1F},
++{0x2B94, 0x7F},
++{0x2B95, 0x27},
++{0x2B98, 0x7F},
++{0x2B99, 0x57},
++{0x2BA8, 0xBC},
++{0x2BA9, 0x62},
++{0x2BC1, 0x70},
++{0x2BC5, 0x80},
++{0x2BD5, 0x30},
++{0x2BD6, 0xF0},
++{0x2BD8, 0xDB},
++{0x2BD9, 0xF6},
++{0x2BDA, 0x63},
++{0x2BDB, 0x0C},
++{0x2BDC, 0x5C},
++{0x2C98, 0xE1},
++{0x2C99, 0x2E},
++{0x2C9B, 0x86},
++{0x2CA9, 0x80},
++{0x2CAA, 0x01},
++{0x2D39, 0x0E},
++{0x2D54, 0x00},
++{0x2D5B, 0x58},
++{0x3000, 0x00},
++{0x3001, 0x40},
++{0x3002, 0x23},
++{0x3003, 0xA1},
++{0x3004, 0x00},
++{0x3005, 0x20},
++{0x3006, 0x94},
++{0x3007, 0x00},
++{0x3008, 0x06},
++{0x3009, 0xB4},
++{0x300A, 0x1F},
++{0x300B, 0x28},
++{0x300C, 0x00},
++{0x300D, 0x18},
++{0x300E, 0x90},
++{0x300F, 0x97},
++{0x3010, 0x00},
++{0x3011, 0x40},
++{0x3012, 0x21},
++{0x3013, 0x21},
++{0x3014, 0x00},
++{0x3015, 0x20},
++{0x3016, 0x94},
++{0x3017, 0x00},
++{0x3018, 0x00},
++{0x3019, 0x09},
++{0x301A, 0x46},
++{0x301B, 0x28},
++//{0x3053, ,3},
++{0x3070, 0xC1},
++{0x3071, 0x81},
++{0x3072, 0x29},
++{0x3073, 0x81},
++//{0x3370, ,3},
++//{0x3374, ,3},
++//{0x3375, ,3},
++//{0x3376, ,3},
++//{0x3377, ,3},
++#if 1
++{0x3410, 0x90},
++{0x3411, 0x07},
++{0x3418, 0x48},
++{0x3419, 0x04},
++#else
++{0x3410, 0x80},
++{0x3411, 0x07},
++{0x3418, 0x38},
++{0x3419, 0x04},
++#endif
++//{0x34C0, ,3},
++//{0x34C1, ,3},
++//{0x34C2, ,3},
++//{0x34C3, ,3},
++//{0x34C4, ,3},
++//{0x34C5, ,3},
++//{0x34C6, ,3},
++//{0x34C7, ,3},
++//{0x34C8, ,3},
++//{0x34C9, ,3},
++//{0x34CA, ,3},
++//{0x34CB, ,3},
++//{0x34CC, ,3},
++//{0x34CD, ,3},
++//{0x34CE, ,3},
++//{0x34CF, ,3},
++{0x3584, 0x00},
++{0x3586, 0x00},
++{0x3587, 0x01},
++{0x3588, 0xE6},
++{0x3589, 0x00},
++{0x3590, 0x00},
++{0x3591, 0x00},
++{0x3594, 0x40},
++{0x3598, 0x03},
++{0x3599, 0x00},
++{0x359A, 0x80},
++{0x359B, 0x00},
++{0x359C, 0x00},
++{0x359D, 0x01},
++{0x359E, 0x00},
++{0x359F, 0x02},
++{0x35A0, 0x00},
++{0x35A1, 0x04},
++{0x35A2, 0x20},
++{0x35A3, 0x00},
++{0x35A4, 0x40},
++{0x35A5, 0x00},
++{0x35A6, 0x80},
++{0x35A7, 0x00},
++{0x35A8, 0x00},
++{0x35A9, 0x01},
++{0x35AA, 0x3A},
++{0x35AB, 0x00},
++{0x35AC, 0x80},
++{0x35AD, 0x00},
++{0x35AE, 0x00},
++{0x35AF, 0x01},
++{0x35B0, 0x00},
++{0x35B1, 0x02},
++{0x35B2, 0x00},
++{0x35B3, 0x04},
++{0x35B4, 0x02},
++{0x35B5, 0x00},
++{0x35B6, 0x04},
++{0x35B7, 0x00},
++{0x35B8, 0x08},
++{0x35B9, 0x00},
++{0x35BA, 0x10},
++{0x35BB, 0x00},
++{0x35BC, 0x03},
++{0x35BD, 0x00},
++{0x35C8, 0x00},
++{0x35C9, 0x01},
++{0x35CA, 0x00},
++{0x35CB, 0x04},
++{0x35CC, 0x00},
++{0x35CD, 0x10},
++{0x35CE, 0x00},
++{0x35CF, 0x40},
++{0x35D0, 0x00},
++{0x35D1, 0x0C},
++{0x35D2, 0x00},
++{0x35D3, 0x0C},
++{0x35D4, 0x00},
++{0x35D5, 0x0C},
++{0x35D6, 0x00},
++{0x35D7, 0x0C},
++{0x35D8, 0x00},
++{0x35D9, 0x00},
++{0x35DA, 0x08},
++{0x35DB, 0x00},
++{0x35DC, 0xD8},
++{0x35DD, 0x0E},
++{0x35F0, 0x00},
++{0x35F1, 0x10},
++{0x35F2, 0x00},
++{0x35F3, 0x10},
++{0x35F4, 0x00},
++{0x35F5, 0x10},
++{0x35F6, 0x00},
++{0x35F7, 0x03},
++{0x35F8, 0x00},
++{0x35F9, 0x01},
++{0x35FA, 0x38},
++{0x35FB, 0x00},
++{0x35FC, 0xB3},
++{0x35FD, 0x01},
++{0x35FE, 0x00},
++{0x35FF, 0x00},
++{0x3600, 0x04},
++{0x3601, 0x06},
++{0x3604, 0x03},
++{0x3605, 0x00},
++{0x3608, 0x03},
++{0x3609, 0x00},
++{0x360C, 0x00},
++{0x360D, 0x00},
++{0x3610, 0x10},
++{0x3611, 0x01},
++{0x3612, 0x00},
++{0x3613, 0x00},
++{0x3614, 0x00},
++{0x3615, 0x00},
++{0x361C, 0x00},
++{0x361D, 0x01},
++{0x361E, 0x00},
++{0x361F, 0x01},
++{0x3620, 0x01},
++{0x3621, 0x00},
++{0x3622, 0xB0},
++{0x3623, 0x04},
++{0x3624, 0xDC},
++{0x3625, 0x05},
++{0x3626, 0x00},
++{0x3627, 0x01},
++{0x3628, 0xFF},
++{0x3629, 0x0F},
++{0x362A, 0x00},
++{0x362B, 0x10},
++{0x362C, 0x00},
++{0x362D, 0x01},
++//{0x3630, ,3},
++//{0x3631, ,3},
++//{0x3632, ,3},
++//{0x3633, ,3},
++//{0x3634, ,3},
++//{0x3635, ,3},
++//{0x3636, ,3},
++//{0x3637, ,3},
++//{0x3638, ,3},
++//{0x3639, ,3},
++//{0x363A, ,3},
++//{0x363B, ,3},
++//{0x363C, ,3},
++//{0x363D, ,3},
++//{0x363E, ,3},
++//{0x363F, ,3},
++{0x36C4, 0x99},
++{0x36C5, 0x09},
++{0x36C6, 0x18},
++{0x36C7, 0x07},
++{0x36C8, 0x65},
++{0x36C9, 0x0E},
++{0x36CC, 0x99},
++{0x36CD, 0x01},
++{0x36CE, 0x47},
++{0x36CF, 0x00},
++{0x36D0, 0x04},
++{0x36D1, 0x00},
++{0x36D4, 0x65},
++{0x36D5, 0x0E},
++{0x36D6, 0xA4},
++{0x36D7, 0x0A},
++{0x36D8, 0x65},
++{0x36D9, 0x0E},
++{0x36DC, 0x65},
++{0x36DD, 0x0E},
++{0x36DE, 0xA4},
++{0x36DF, 0x0A},
++{0x36E0, 0x65},
++{0x36E1, 0x0E},
++{0x36E4, 0x65},
++{0x36E5, 0x0E},
++{0x36E6, 0xA4},
++{0x36E7, 0x0A},
++{0x36E8, 0x65},
++{0x36E9, 0x0E},
++{0x36EE, 0x00},
++{0x36EF, 0x00},
++{0x36F0, 0x00},
++{0x36F1, 0x80},
++{0x36F8, 0x00},
++{0x3702, 0x03},
++{0x3703, 0x04},
++{0x3704, 0x08},
++{0x370E, 0x0E},
++{0x3718, 0x62},
++{0x3719, 0x4A},
++{0x371A, 0x38},
++{0x371B, 0x20},
++{0x371C, 0x64},
++{0x371D, 0x42},
++{0x371E, 0x32},
++{0x371F, 0x1B},
++{0x3720, 0x98},
++{0x3721, 0xA0},
++{0x3722, 0xA8},
++{0x3723, 0xB0},
++{0x3748, 0xA5},
++{0x3749, 0x9B},
++{0x374A, 0x91},
++{0x374B, 0x7D},
++{0x37C0, 0x00},
++{0x37C1, 0x00},
++{0x37C2, 0x00},
++{0x37C4, 0x00},
++{0x37C5, 0x00},
++{0x37C6, 0x00},
++{0x37C8, 0x00},
++{0x37C9, 0x00},
++{0x37CA, 0x00},
++{0x37CC, 0x00},
++{0x37CD, 0x00},
++{0x37CE, 0x00},
++{0x37D0, 0x00},
++{0x37D1, 0x00},
++{0x37D2, 0x00},
++{0x37D4, 0x00},
++{0x37D5, 0x00},
++{0x37D6, 0x00},
++{0x37D8, 0x00},
++{0x37D9, 0x00},
++{0x37DA, 0x00},
++{0x37DC, 0x00},
++{0x37DD, 0x00},
++{0x37DE, 0x00},
++{0x37E0, 0x00},
++{0x37E1, 0x00},
++{0x37E2, 0x00},
++{0x37E4, 0x00},
++{0x37E5, 0x00},
++{0x37E6, 0x00},
++{0x37E8, 0x00},
++{0x37E9, 0x00},
++{0x37EA, 0x00},
++{0x37EC, 0x00},
++{0x37ED, 0x00},
++{0x37EE, 0x00},
++{0x37F0, 0x00},
++{0x37F4, 0x00},
++{0x37F5, 0x1E},
++{0x37F6, 0x34},
++{0x37F7, 0x00},
++{0x37F8, 0xFF},
++{0x37F9, 0xFF},
++{0x37FA, 0x03},
++{0x37FC, 0x00},
++{0x37FD, 0x00},
++{0x37FE, 0x04},
++{0x3800, 0xFF},
++{0x3801, 0xFF},
++{0x3802, 0x03},
++{0x3804, 0x00},
++{0x3805, 0x00},
++{0x3806, 0x04},
++{0x3808, 0x00},
++{0x3809, 0x00},
++{0x380A, 0x00},
++{0x380C, 0x00},
++{0x380D, 0x00},
++{0x380E, 0x00},
++{0x3810, 0x00},
++{0x3811, 0x00},
++{0x3812, 0x00},
++{0x3814, 0x00},
++{0x3815, 0x00},
++{0x3816, 0x00},
++{0x3818, 0x00},
++{0x3819, 0x00},
++{0x381A, 0x00},
++{0x381C, 0x00},
++{0x381D, 0x00},
++{0x381E, 0x00},
++{0x3820, 0x00},
++{0x3821, 0x00},
++{0x3822, 0x00},
++{0x3824, 0x00},
++{0x3825, 0x00},
++{0x3826, 0x00},
++{0x3828, 0x00},
++{0x3829, 0x00},
++{0x382A, 0x00},
++{0x382C, 0x00},
++{0x382D, 0x00},
++{0x382E, 0x00},
++{0x3830, 0x00},
++{0x3831, 0x00},
++{0x3832, 0x00},
++{0x3834, 0x00},
++{0x3835, 0x00},
++{0x3836, 0x00},
++{0x3838, 0x22},
++{0x3839, 0x00},
++{0x383A, 0x25},
++{0x383B, 0x00},
++{0x383C, 0x1A},
++{0x383D, 0x00},
++{0x383E, 0x26},
++{0x383F, 0x00},
++{0x3840, 0x07},
++{0x3841, 0x00},
++{0x3842, 0x06},
++{0x3843, 0x00},
++{0x3844, 0x03},
++{0x3845, 0x00},
++{0x3846, 0x02},
++{0x3847, 0x00},
++{0x3848, 0xFB},
++{0x3849, 0xFF},
++{0x384A, 0xFF},
++{0x384B, 0xFF},
++{0x384C, 0xF3},
++{0x384D, 0xFF},
++{0x384E, 0xF2},
++{0x384F, 0xFF},
++{0x3850, 0xFF},
++{0x3851, 0x0F},
++{0x3852, 0x00},
++{0x3853, 0x10},
++{0x3854, 0xFF},
++{0x3855, 0x0F},
++{0x3856, 0x00},
++{0x3857, 0x10},
++{0x3858, 0xFF},
++{0x3859, 0x0F},
++{0x385A, 0x00},
++{0x385B, 0x10},
++{0x385C, 0x02},
++{0x385D, 0x00},
++{0x385E, 0x06},
++{0x385F, 0x00},
++{0x3860, 0x06},
++{0x3861, 0x00},
++{0x3862, 0x08},
++{0x3863, 0x00},
++{0x3864, 0x02},
++{0x3865, 0x00},
++{0x38A0, 0x01},
++{0x38A1, 0x01},
++{0x38A2, 0x00},
++{0x38A3, 0x01},
++{0x38A4, 0x07},
++{0x38A5, 0x00},
++{0x38A6, 0x04},
++{0x38A7, 0x05},
++{0x38A8, 0x00},
++{0x38A9, 0x00},
++{0x38AC, 0x00},
++{0x38AD, 0x00},
++{0x38AE, 0x01},
++{0x38B0, 0x02},
++{0x38B2, 0x22},
++{0x38B3, 0x00},
++{0x38B4, 0x17},
++{0x38B5, 0x00},
++{0x38B6, 0x11},
++{0x38B7, 0x00},
++{0x38B8, 0x0E},
++{0x38B9, 0x00},
++{0x38BA, 0x2A},
++{0x38BB, 0x00},
++{0x38BC, 0x1C},
++{0x38BD, 0x00},
++{0x38BE, 0x14},
++{0x38BF, 0x00},
++{0x38C0, 0x10},
++{0x38C1, 0x00},
++{0x38C2, 0x31},
++{0x38C3, 0x00},
++{0x38C4, 0x21},
++{0x38C5, 0x00},
++{0x38C6, 0x18},
++{0x38C7, 0x00},
++{0x38C8, 0x12},
++{0x38C9, 0x00},
++{0x38CA, 0x3C},
++{0x38CB, 0x00},
++{0x38CC, 0x29},
++{0x38CD, 0x00},
++{0x38CE, 0x1D},
++{0x38CF, 0x00},
++{0x38D0, 0x15},
++{0x38D1, 0x00},
++{0x38D2, 0x4E},
++{0x38D3, 0x00},
++{0x38D4, 0x35},
++{0x38D5, 0x00},
++{0x38D6, 0x26},
++{0x38D7, 0x00},
++{0x38D8, 0x1A},
++{0x38D9, 0x00},
++{0x38DA, 0x69},
++{0x38DB, 0x00},
++{0x38DC, 0x48},
++{0x38DD, 0x00},
++{0x38DE, 0x33},
++{0x38DF, 0x00},
++{0x38E0, 0x22},
++{0x38E1, 0x00},
++{0x38E2, 0x93},
++{0x38E3, 0x00},
++{0x38E4, 0x64},
++{0x38E5, 0x00},
++{0x38E6, 0x48},
++{0x38E7, 0x00},
++{0x38E8, 0x30},
++{0x38E9, 0x00},
++{0x38EA, 0xD3},
++{0x38EB, 0x00},
++{0x38EC, 0x90},
++{0x38ED, 0x00},
++{0x38EE, 0x69},
++{0x38EF, 0x00},
++{0x38F0, 0x49},
++{0x38F1, 0x00},
++{0x38F2, 0x39},
++{0x38F3, 0x01},
++{0x38F4, 0xD5},
++{0x38F5, 0x00},
++{0x38F6, 0x9F},
++{0x38F7, 0x00},
++{0x38F8, 0x75},
++{0x38F9, 0x00},
++{0x38FA, 0x00},
++{0x38FB, 0x01},
++{0x38FC, 0x00},
++{0x38FD, 0x01},
++{0x38FE, 0x00},
++{0x38FF, 0x01},
++{0x3900, 0x00},
++{0x3901, 0x01},
++{0x3902, 0x60},
++{0x3903, 0x00},
++{0x3904, 0x25},
++{0x3905, 0x00},
++{0x3906, 0x18},
++{0x3907, 0x00},
++{0x3908, 0x10},
++{0x3909, 0x00},
++{0x390A, 0xFF},
++{0x390B, 0x00},
++{0x390C, 0xD5},
++{0x390D, 0x00},
++{0x390E, 0xAA},
++{0x390F, 0x00},
++{0x3910, 0x85},
++{0x3911, 0x00},
++{0x3912, 0xFF},
++{0x3913, 0x00},
++{0x3914, 0xD5},
++{0x3915, 0x00},
++{0x3916, 0xAA},
++{0x3917, 0x00},
++{0x3918, 0x85},
++{0x3919, 0x00},
++{0x391A, 0xFF},
++{0x391B, 0x00},
++{0x391C, 0xD5},
++{0x391D, 0x00},
++{0x391E, 0xAA},
++{0x391F, 0x00},
++{0x3920, 0x85},
++{0x3921, 0x00},
++{0x3922, 0x40},
++{0x3923, 0x00},
++{0x3924, 0x40},
++{0x3925, 0x00},
++{0x3926, 0x40},
++{0x3927, 0x00},
++{0x3928, 0x40},
++{0x3929, 0x00},
++{0x392A, 0x80},
++{0x392B, 0x00},
++{0x392C, 0x80},
++{0x392D, 0x00},
++{0x392E, 0x80},
++{0x392F, 0x00},
++{0x3930, 0x80},
++{0x3931, 0x00},
++{0x3932, 0x4C},
++{0x3933, 0x4C},
++{0x3934, 0x4C},
++{0x3940, 0x01},
++{0x3941, 0x01},
++{0x3942, 0x00},
++{0x3943, 0x01},
++{0x3944, 0x07},
++{0x3945, 0x00},
++{0x3946, 0x04},
++{0x3947, 0x05},
++{0x3948, 0x00},
++{0x3949, 0x00},
++{0x394C, 0x00},
++{0x394D, 0x00},
++{0x394E, 0x01},
++{0x3950, 0x03},
++{0x3952, 0x14},
++{0x3953, 0x00},
++{0x3954, 0x0F},
++{0x3955, 0x00},
++{0x3956, 0x0E},
++{0x3957, 0x00},
++{0x3958, 0x0E},
++{0x3959, 0x00},
++{0x395A, 0x19},
++{0x395B, 0x00},
++{0x395C, 0x11},
++{0x395D, 0x00},
++{0x395E, 0x0F},
++{0x395F, 0x00},
++{0x3960, 0x0E},
++{0x3961, 0x00},
++{0x3962, 0x1C},
++{0x3963, 0x00},
++{0x3964, 0x13},
++{0x3965, 0x00},
++{0x3966, 0x0F},
++{0x3967, 0x00},
++{0x3968, 0x0E},
++{0x3969, 0x00},
++{0x396A, 0x23},
++{0x396B, 0x00},
++{0x396C, 0x15},
++{0x396D, 0x00},
++{0x396E, 0x11},
++{0x396F, 0x00},
++{0x3970, 0x0E},
++{0x3971, 0x00},
++{0x3972, 0x2E},
++{0x3973, 0x00},
++{0x3974, 0x1A},
++{0x3975, 0x00},
++{0x3976, 0x14},
++{0x3977, 0x00},
++{0x3978, 0x0F},
++{0x3979, 0x00},
++{0x397A, 0x3E},
++{0x397B, 0x00},
++{0x397C, 0x23},
++{0x397D, 0x00},
++{0x397E, 0x1A},
++{0x397F, 0x00},
++{0x3980, 0x12},
++{0x3981, 0x00},
++{0x3982, 0x56},
++{0x3983, 0x00},
++{0x3984, 0x31},
++{0x3985, 0x00},
++{0x3986, 0x25},
++{0x3987, 0x00},
++{0x3988, 0x1A},
++{0x3989, 0x00},
++{0x398A, 0x7B},
++{0x398B, 0x00},
++{0x398C, 0x49},
++{0x398D, 0x00},
++{0x398E, 0x39},
++{0x398F, 0x00},
++{0x3990, 0x2C},
++{0x3991, 0x00},
++{0x3992, 0xB4},
++{0x3993, 0x00},
++{0x3994, 0x75},
++{0x3995, 0x00},
++{0x3996, 0x61},
++{0x3997, 0x00},
++{0x3998, 0x53},
++{0x3999, 0x00},
++{0x399A, 0x00},
++{0x399B, 0x01},
++{0x399C, 0x00},
++{0x399D, 0x01},
++{0x399E, 0x00},
++{0x399F, 0x01},
++{0x39A0, 0x00},
++{0x39A1, 0x01},
++{0x39A2, 0x60},
++{0x39A3, 0x00},
++{0x39A4, 0x20},
++{0x39A5, 0x00},
++{0x39A6, 0x15},
++{0x39A7, 0x00},
++{0x39A8, 0x10},
++{0x39A9, 0x00},
++{0x39AA, 0xFF},
++{0x39AB, 0x00},
++{0x39AC, 0xD5},
++{0x39AD, 0x00},
++{0x39AE, 0xAA},
++{0x39AF, 0x00},
++{0x39B0, 0x85},
++{0x39B1, 0x00},
++{0x39B2, 0xFF},
++{0x39B3, 0x00},
++{0x39B4, 0xD5},
++{0x39B5, 0x00},
++{0x39B6, 0xAA},
++{0x39B7, 0x00},
++{0x39B8, 0x85},
++{0x39B9, 0x00},
++{0x39BA, 0xFF},
++{0x39BB, 0x00},
++{0x39BC, 0xD5},
++{0x39BD, 0x00},
++{0x39BE, 0xAA},
++{0x39BF, 0x00},
++{0x39C0, 0x85},
++{0x39C1, 0x00},
++{0x39C2, 0x40},
++{0x39C3, 0x00},
++{0x39C4, 0x40},
++{0x39C5, 0x00},
++{0x39C6, 0x40},
++{0x39C7, 0x00},
++{0x39C8, 0x40},
++{0x39C9, 0x00},
++{0x39CA, 0x80},
++{0x39CB, 0x00},
++{0x39CC, 0x80},
++{0x39CD, 0x00},
++{0x39CE, 0x80},
++{0x39CF, 0x00},
++{0x39D0, 0x80},
++{0x39D1, 0x00},
++{0x39D2, 0x4C},
++{0x39D3, 0x4C},
++{0x39D4, 0x4C},
++{0x39E0, 0x01},
++{0x39E1, 0x00},
++{0x39E4, 0x40},
++{0x39E5, 0x01},
++{0x39E6, 0x01},
++{0x39E8, 0x00},
++{0x39E9, 0x01},
++{0x39EA, 0x00},
++{0x39EB, 0x00},
++{0x39EC, 0x01},
++{0x39ED, 0x00},
++{0x39EE, 0x01},
++{0x39F0, 0x03},
++{0x39F1, 0x04},
++{0x39F2, 0x0E},
++{0x39F4, 0x1C},
++{0x39F5, 0x00},
++{0x39F6, 0x13},
++{0x39F7, 0x00},
++{0x39F8, 0x0D},
++{0x39F9, 0x00},
++{0x39FA, 0x07},
++{0x39FB, 0x00},
++{0x39FC, 0x38},
++{0x39FD, 0x00},
++{0x39FE, 0x1C},
++{0x39FF, 0x00},
++{0x3A00, 0x11},
++{0x3A01, 0x00},
++{0x3A02, 0x08},
++{0x3A03, 0x00},
++{0x3A04, 0x4A},
++{0x3A05, 0x00},
++{0x3A06, 0x23},
++{0x3A07, 0x00},
++{0x3A08, 0x15},
++{0x3A09, 0x00},
++{0x3A0A, 0x09},
++{0x3A0B, 0x00},
++{0x3A0C, 0x65},
++{0x3A0D, 0x00},
++{0x3A0E, 0x2D},
++{0x3A0F, 0x00},
++{0x3A10, 0x1A},
++{0x3A11, 0x00},
++{0x3A12, 0x0B},
++{0x3A13, 0x00},
++{0x3A14, 0x8D},
++{0x3A15, 0x00},
++{0x3A16, 0x3D},
++{0x3A17, 0x00},
++{0x3A18, 0x23},
++{0x3A19, 0x00},
++{0x3A1A, 0x0E},
++{0x3A1B, 0x00},
++{0x3A1C, 0xC5},
++{0x3A1D, 0x00},
++{0x3A1E, 0x55},
++{0x3A1F, 0x00},
++{0x3A20, 0x30},
++{0x3A21, 0x00},
++{0x3A22, 0x13},
++{0x3A23, 0x00},
++{0x3A24, 0x16},
++{0x3A25, 0x01},
++{0x3A26, 0x76},
++{0x3A27, 0x00},
++{0x3A28, 0x42},
++{0x3A29, 0x00},
++{0x3A2A, 0x1A},
++{0x3A2B, 0x00},
++{0x3A2C, 0x88},
++{0x3A2D, 0x01},
++{0x3A2E, 0xA7},
++{0x3A2F, 0x00},
++{0x3A30, 0x5D},
++{0x3A31, 0x00},
++{0x3A32, 0x24},
++{0x3A33, 0x00},
++{0x3A34, 0x2A},
++{0x3A35, 0x02},
++{0x3A36, 0xEB},
++{0x3A37, 0x00},
++{0x3A38, 0x83},
++{0x3A39, 0x00},
++{0x3A3A, 0x32},
++{0x3A3B, 0x00},
++{0x3A3C, 0x00},
++{0x3A3D, 0x01},
++{0x3A3E, 0x00},
++{0x3A3F, 0x01},
++{0x3A40, 0x00},
++{0x3A41, 0x01},
++{0x3A42, 0x00},
++{0x3A43, 0x01},
++{0x3A44, 0x70},
++{0x3A45, 0x00},
++{0x3A46, 0x25},
++{0x3A47, 0x00},
++{0x3A48, 0x18},
++{0x3A49, 0x00},
++{0x3A4A, 0x10},
++{0x3A4B, 0x00},
++{0x3A4C, 0xFF},
++{0x3A4D, 0x00},
++{0x3A4E, 0xD5},
++{0x3A4F, 0x00},
++{0x3A50, 0xAA},
++{0x3A51, 0x00},
++{0x3A52, 0x85},
++{0x3A53, 0x00},
++{0x3A54, 0xFF},
++{0x3A55, 0x00},
++{0x3A56, 0xD5},
++{0x3A57, 0x00},
++{0x3A58, 0xAA},
++{0x3A59, 0x00},
++{0x3A5A, 0x85},
++{0x3A5B, 0x00},
++{0x3A5C, 0xFF},
++{0x3A5D, 0x00},
++{0x3A5E, 0xD5},
++{0x3A5F, 0x00},
++{0x3A60, 0xAA},
++{0x3A61, 0x00},
++{0x3A62, 0x85},
++{0x3A63, 0x00},
++{0x3A64, 0x1C},
++{0x3A65, 0x00},
++{0x3A66, 0x13},
++{0x3A67, 0x00},
++{0x3A68, 0x0D},
++{0x3A69, 0x00},
++{0x3A6A, 0x07},
++{0x3A6B, 0x00},
++{0x3A6C, 0x0D},
++{0x3A6D, 0x00},
++{0x3A6E, 0x0B},
++{0x3A6F, 0x00},
++{0x3A70, 0x06},
++{0x3A71, 0x00},
++{0x3A72, 0x05},
++{0x3A73, 0x00},
++{0x3A74, 0x19},
++{0x3A75, 0x00},
++{0x3A76, 0x14},
++{0x3A77, 0x00},
++{0x3A78, 0x0F},
++{0x3A79, 0x00},
++{0x3A7A, 0x0A},
++{0x3A7B, 0x00},
++{0x3A7C, 0x80},
++{0x3A7D, 0x00},
++{0x3A7E, 0x80},
++{0x3A7F, 0x00},
++{0x3A80, 0x80},
++{0x3A81, 0x00},
++{0x3A82, 0x80},
++{0x3A83, 0x00},
++{0x3A84, 0x08},
++{0x3A85, 0x00},
++{0x3A86, 0x05},
++{0x3A87, 0x00},
++{0x3A88, 0x04},
++{0x3A89, 0x00},
++{0x3A8A, 0x03},
++{0x3A8B, 0x00},
++{0x3A8C, 0xCD},
++{0x3A8D, 0x00},
++{0x3A8E, 0xAA},
++{0x3A8F, 0x00},
++{0x3A90, 0x8C},
++{0x3A91, 0x00},
++{0x3A92, 0x64},
++{0x3A93, 0x00},
++{0x3A94, 0xCD},
++{0x3A95, 0x00},
++{0x3A96, 0xAA},
++{0x3A97, 0x00},
++{0x3A98, 0x8C},
++{0x3A99, 0x00},
++{0x3A9A, 0x64},
++{0x3A9B, 0x00},
++{0x3A9C, 0x08},
++{0x3A9D, 0x10},
++{0x3A9E, 0x4C},
++{0x3A9F, 0x4C},
++{0x3AA0, 0x4C},
++{0x3AA1, 0x04},
++{0x3AA2, 0x05},
++{0x3AC0, 0x01},
++{0x3AC4, 0x81},
++{0x3AC5, 0x00},
++{0x3AC6, 0x00},
++{0x3AC7, 0x00},
++{0x3AC8, 0x00},
++{0x3AC9, 0x00},
++{0x3ACA, 0x00},
++{0x3ACB, 0x00},
++{0x3ACC, 0x02},
++{0x3ACD, 0x00},
++{0x3ACE, 0x81},
++{0x3ACF, 0x00},
++{0x3AD0, 0x00},
++{0x3AD1, 0x00},
++{0x3AD2, 0xFD},
++{0x3AD3, 0x03},
++{0x3AD4, 0x02},
++{0x3AD5, 0x00},
++{0x3AD6, 0x00},
++{0x3AD7, 0x00},
++{0x3AD8, 0x81},
++{0x3AD9, 0x00},
++{0x3ADA, 0xFD},
++{0x3ADB, 0x03},
++{0x3ADC, 0xFF},
++{0x3ADD, 0x03},
++{0x3ADE, 0x01},
++{0x3ADF, 0x00},
++{0x3AE0, 0x01},
++{0x3AE1, 0x00},
++{0x3AE2, 0x7E},
++{0x3AE3, 0x00},
++{0x3AF4, 0x00},
++{0x3AF6, 0x40},
++{0x3AF7, 0x1E},
++{0x3AF8, 0x01},
++{0x3AFA, 0x63},
++{0x3AFB, 0x09},
++{0x3AFC, 0x11},
++{0x3AFD, 0x09},
++{0x3AFE, 0x00},
++{0x3AFF, 0x00},
++{0x3B00, 0x00},
++{0x3B01, 0x00},
++{0x3B02, 0x84},
++{0x3B03, 0x06},
++{0x3B04, 0x30},
++{0x3B05, 0x06},
++{0x3B06, 0x00},
++{0x3B07, 0x00},
++{0x3B08, 0x00},
++{0x3B09, 0x00},
++{0x3B0A, 0x00},
++{0x3B0B, 0x00},
++{0x3B0C, 0x00},
++{0x3B0D, 0x00},
++{0x3B0E, 0x00},
++{0x3B0F, 0x00},
++{0x3B10, 0x00},
++{0x3B11, 0x00},
++{0x3B12, 0x00},
++{0x3B13, 0x00},
++{0x3B14, 0x00},
++{0x3B15, 0x00},
++{0x3B16, 0x00},
++{0x3B17, 0x00},
++{0x3B18, 0x00},
++{0x3B19, 0x00},
++{0x3B1A, 0x00},
++{0x3B1B, 0x00},
++{0x3B1C, 0x00},
++{0x3B1D, 0x00},
++{0x3B1E, 0x00},
++{0x3B1F, 0x00},
++{0x3B20, 0x00},
++{0x3B21, 0x00},
++{0x3B22, 0x00},
++{0x3B23, 0x00},
++{0x3B24, 0x00},
++{0x3B25, 0x00},
++{0x3B26, 0x00},
++{0x3B27, 0x00},
++{0x3B28, 0x00},
++{0x3B29, 0x00},
++{0x3B2A, 0x00},
++{0x3B2C, 0x00},
++{0x3B2E, 0x00},
++{0x3B30, 0x00},
++{0x3B32, 0x0C},
++{0x4000, 0xD1},
++{0x4001, 0xC0},
++{0x4002, 0xC0},
++{0x4003, 0xB8},
++{0x4004, 0xC0},
++{0x4005, 0xB8},
++{0x4006, 0xB9},
++{0x4007, 0xB7},
++{0x4008, 0xB0},
++{0x4009, 0xAB},
++{0x400A, 0xAC},
++{0x400B, 0xAB},
++{0x400C, 0xA8},
++{0x400D, 0xA6},
++{0x400E, 0xA6},
++{0x400F, 0xA5},
++{0x4010, 0xA2},
++{0x4011, 0xA0},
++{0x4012, 0xA0},
++{0x4013, 0x9F},
++{0x4014, 0xA4},
++{0x4015, 0xA2},
++{0x4016, 0xA2},
++{0x4017, 0x9C},
++{0x4018, 0xA8},
++{0x4019, 0xA6},
++{0x401A, 0xA8},
++{0x401B, 0xAA},
++{0x401C, 0xB0},
++{0x401D, 0xAE},
++{0x401E, 0xAE},
++{0x401F, 0xAE},
++{0x4020, 0xBA},
++{0x4021, 0xAE},
++{0x4022, 0xAF},
++{0x4023, 0xAE},
++{0x4024, 0xC6},
++{0x4025, 0xBD},
++{0x4026, 0xBD},
++{0x4027, 0xBA},
++{0x4028, 0xB0},
++{0x4029, 0xA9},
++{0x402A, 0xAA},
++{0x402B, 0xA8},
++{0x402C, 0x9F},
++{0x402D, 0x9C},
++{0x402E, 0x9C},
++{0x402F, 0x9B},
++{0x4030, 0x93},
++{0x4031, 0x91},
++{0x4032, 0x92},
++{0x4033, 0x91},
++{0x4034, 0x8D},
++{0x4035, 0x8C},
++{0x4036, 0x8C},
++{0x4037, 0x8C},
++{0x4038, 0x8F},
++{0x4039, 0x8E},
++{0x403A, 0x8E},
++{0x403B, 0x8E},
++{0x403C, 0x98},
++{0x403D, 0x96},
++{0x403E, 0x96},
++{0x403F, 0x95},
++{0x4040, 0xA4},
++{0x4041, 0xA0},
++{0x4042, 0xA0},
++{0x4043, 0x9E},
++{0x4044, 0xB3},
++{0x4045, 0xAE},
++{0x4046, 0xAF},
++{0x4047, 0xAB},
++{0x4048, 0xC2},
++{0x4049, 0xB7},
++{0x404A, 0xB8},
++{0x404B, 0xB5},
++{0x404C, 0xAB},
++{0x404D, 0xA4},
++{0x404E, 0xA5},
++{0x404F, 0xA3},
++{0x4050, 0x99},
++{0x4051, 0x96},
++{0x4052, 0x96},
++{0x4053, 0x96},
++{0x4054, 0x8B},
++{0x4055, 0x8A},
++{0x4056, 0x8A},
++{0x4057, 0x8A},
++{0x4058, 0x82},
++{0x4059, 0x81},
++{0x405A, 0x81},
++{0x405B, 0x81},
++{0x405C, 0x85},
++{0x405D, 0x86},
++{0x405E, 0x85},
++{0x405F, 0x85},
++{0x4060, 0x90},
++{0x4061, 0x90},
++{0x4062, 0x8F},
++{0x4063, 0x8F},
++{0x4064, 0x9D},
++{0x4065, 0x9B},
++{0x4066, 0x9B},
++{0x4067, 0x9A},
++{0x4068, 0xAF},
++{0x4069, 0xAA},
++{0x406A, 0xAC},
++{0x406B, 0xAA},
++{0x406C, 0xC2},
++{0x406D, 0xB7},
++{0x406E, 0xB8},
++{0x406F, 0xB5},
++{0x4070, 0xAB},
++{0x4071, 0xA4},
++{0x4072, 0xA4},
++{0x4073, 0xA3},
++{0x4074, 0x99},
++{0x4075, 0x96},
++{0x4076, 0x96},
++{0x4077, 0x96},
++{0x4078, 0x8B},
++{0x4079, 0x8A},
++{0x407A, 0x8A},
++{0x407B, 0x8A},
++{0x407C, 0x82},
++{0x407D, 0x82},
++{0x407E, 0x82},
++{0x407F, 0x82},
++{0x4080, 0x85},
++{0x4081, 0x86},
++{0x4082, 0x86},
++{0x4083, 0x86},
++{0x4084, 0x90},
++{0x4085, 0x90},
++{0x4086, 0x8F},
++{0x4087, 0x8F},
++{0x4088, 0x9D},
++{0x4089, 0x9B},
++{0x408A, 0x9B},
++{0x408B, 0x99},
++{0x408C, 0xAE},
++{0x408D, 0xAA},
++{0x408E, 0xAA},
++{0x408F, 0xA7},
++{0x4090, 0xC7},
++{0x4091, 0xBA},
++{0x4092, 0xBC},
++{0x4093, 0xB9},
++{0x4094, 0xB1},
++{0x4095, 0xA8},
++{0x4096, 0xA8},
++{0x4097, 0xA7},
++{0x4098, 0x9F},
++{0x4099, 0x9B},
++{0x409A, 0x9B},
++{0x409B, 0x9B},
++{0x409C, 0x93},
++{0x409D, 0x91},
++{0x409E, 0x91},
++{0x409F, 0x91},
++{0x40A0, 0x8D},
++{0x40A1, 0x8C},
++{0x40A2, 0x8C},
++{0x40A3, 0x8C},
++{0x40A4, 0x8E},
++{0x40A5, 0x8E},
++{0x40A6, 0x8D},
++{0x40A7, 0x8D},
++{0x40A8, 0x96},
++{0x40A9, 0x95},
++{0x40AA, 0x95},
++{0x40AB, 0x94},
++{0x40AC, 0xA2},
++{0x40AD, 0x9F},
++{0x40AE, 0x9F},
++{0x40AF, 0x9D},
++{0x40B0, 0xB1},
++{0x40B1, 0xAC},
++{0x40B2, 0xAB},
++{0x40B3, 0xAA},
++{0x40B4, 0xD3},
++{0x40B5, 0xBC},
++{0x40B6, 0xBD},
++{0x40B7, 0xBC},
++{0x40B8, 0xC1},
++{0x40B9, 0xB7},
++{0x40BA, 0xB7},
++{0x40BB, 0xB5},
++{0x40BC, 0xB0},
++{0x40BD, 0xAA},
++{0x40BE, 0xAA},
++{0x40BF, 0xAA},
++{0x40C0, 0xA8},
++{0x40C1, 0xA4},
++{0x40C2, 0xA4},
++{0x40C3, 0xA4},
++{0x40C4, 0xA2},
++{0x40C5, 0x9F},
++{0x40C6, 0x9F},
++{0x40C7, 0x9F},
++{0x40C8, 0xA3},
++{0x40C9, 0xA0},
++{0x40CA, 0xA0},
++{0x40CB, 0xA0},
++{0x40CC, 0xA6},
++{0x40CD, 0xA3},
++{0x40CE, 0xA3},
++{0x40CF, 0xA2},
++{0x40D0, 0xAF},
++{0x40D1, 0xAB},
++{0x40D2, 0xAA},
++{0x40D3, 0xA8},
++{0x40D4, 0xBA},
++{0x40D5, 0xAE},
++{0x40D6, 0xAE},
++{0x40D7, 0xAB},
++{0x4100, 0xBD},
++{0x4101, 0xBA},
++{0x4102, 0xBD},
++{0x4103, 0xB7},
++{0x4104, 0xB7},
++{0x4105, 0xB7},
++{0x4106, 0xB8},
++{0x4107, 0xB5},
++{0x4108, 0xAB},
++{0x4109, 0xAA},
++{0x410A, 0xAC},
++{0x410B, 0xAB},
++{0x410C, 0xA4},
++{0x410D, 0xA5},
++{0x410E, 0xA5},
++{0x410F, 0xA4},
++{0x4110, 0x9F},
++{0x4111, 0xA0},
++{0x4112, 0xA0},
++{0x4113, 0x9F},
++{0x4114, 0xA0},
++{0x4115, 0xA0},
++{0x4116, 0xA0},
++{0x4117, 0x9F},
++{0x4118, 0xA1},
++{0x4119, 0xA1},
++{0x411A, 0xA1},
++{0x411B, 0xA0},
++{0x411C, 0xA7},
++{0x411D, 0xA6},
++{0x411E, 0xA6},
++{0x411F, 0xA6},
++{0x4120, 0xA7},
++{0x4121, 0xA6},
++{0x4122, 0xA6},
++{0x4123, 0xA3},
++{0x4124, 0xB9},
++{0x4125, 0xB9},
++{0x4126, 0xBA},
++{0x4127, 0xB8},
++{0x4128, 0xA6},
++{0x4129, 0xA7},
++{0x412A, 0xA7},
++{0x412B, 0xA6},
++{0x412C, 0x9B},
++{0x412D, 0x9B},
++{0x412E, 0x9B},
++{0x412F, 0x9B},
++{0x4130, 0x91},
++{0x4131, 0x92},
++{0x4132, 0x92},
++{0x4133, 0x91},
++{0x4134, 0x8C},
++{0x4135, 0x8C},
++{0x4136, 0x8C},
++{0x4137, 0x8C},
++{0x4138, 0x8D},
++{0x4139, 0x8D},
++{0x413A, 0x8D},
++{0x413B, 0x8D},
++{0x413C, 0x93},
++{0x413D, 0x93},
++{0x413E, 0x93},
++{0x413F, 0x92},
++{0x4140, 0x9A},
++{0x4141, 0x9A},
++{0x4142, 0x9A},
++{0x4143, 0x99},
++{0x4144, 0xA7},
++{0x4145, 0xA5},
++{0x4146, 0xA6},
++{0x4147, 0xA6},
++{0x4148, 0xB8},
++{0x4149, 0xB4},
++{0x414A, 0xB4},
++{0x414B, 0xB3},
++{0x414C, 0xA3},
++{0x414D, 0xA2},
++{0x414E, 0xA3},
++{0x414F, 0xA2},
++{0x4150, 0x96},
++{0x4151, 0x96},
++{0x4152, 0x96},
++{0x4153, 0x96},
++{0x4154, 0x8A},
++{0x4155, 0x8A},
++{0x4156, 0x8A},
++{0x4157, 0x8A},
++{0x4158, 0x82},
++{0x4159, 0x82},
++{0x415A, 0x82},
++{0x415B, 0x82},
++{0x415C, 0x84},
++{0x415D, 0x85},
++{0x415E, 0x84},
++{0x415F, 0x84},
++{0x4160, 0x8D},
++{0x4161, 0x8D},
++{0x4162, 0x8D},
++{0x4163, 0x8D},
++{0x4164, 0x96},
++{0x4165, 0x96},
++{0x4166, 0x96},
++{0x4167, 0x95},
++{0x4168, 0xA5},
++{0x4169, 0xA2},
++{0x416A, 0xA3},
++{0x416B, 0xA2},
++{0x416C, 0xB7},
++{0x416D, 0xB3},
++{0x416E, 0xB5},
++{0x416F, 0xB4},
++{0x4170, 0xA4},
++{0x4171, 0xA2},
++{0x4172, 0xA3},
++{0x4173, 0xA2},
++{0x4174, 0x97},
++{0x4175, 0x96},
++{0x4176, 0x96},
++{0x4177, 0x96},
++{0x4178, 0x8B},
++{0x4179, 0x8A},
++{0x417A, 0x8A},
++{0x417B, 0x8A},
++{0x417C, 0x81},
++{0x417D, 0x81},
++{0x417E, 0x81},
++{0x417F, 0x81},
++{0x4180, 0x84},
++{0x4181, 0x84},
++{0x4182, 0x84},
++{0x4183, 0x84},
++{0x4184, 0x8C},
++{0x4185, 0x8D},
++{0x4186, 0x8D},
++{0x4187, 0x8D},
++{0x4188, 0x95},
++{0x4189, 0x96},
++{0x418A, 0x96},
++{0x418B, 0x95},
++{0x418C, 0xA1},
++{0x418D, 0xA1},
++{0x418E, 0xA1},
++{0x418F, 0xA0},
++{0x4190, 0xBC},
++{0x4191, 0xB8},
++{0x4192, 0xB8},
++{0x4193, 0xB9},
++{0x4194, 0xA8},
++{0x4195, 0xA5},
++{0x4196, 0xA6},
++{0x4197, 0xA5},
++{0x4198, 0x9C},
++{0x4199, 0x9A},
++{0x419A, 0x9A},
++{0x419B, 0x9A},
++{0x419C, 0x91},
++{0x419D, 0x91},
++{0x419E, 0x91},
++{0x419F, 0x91},
++{0x41A0, 0x8B},
++{0x41A1, 0x8B},
++{0x41A2, 0x8B},
++{0x41A3, 0x8B},
++{0x41A4, 0x8C},
++{0x41A5, 0x8C},
++{0x41A6, 0x8C},
++{0x41A7, 0x8C},
++{0x41A8, 0x91},
++{0x41A9, 0x92},
++{0x41AA, 0x91},
++{0x41AB, 0x91},
++{0x41AC, 0x98},
++{0x41AD, 0x99},
++{0x41AE, 0x99},
++{0x41AF, 0x98},
++{0x41B0, 0xA3},
++{0x41B1, 0xA3},
++{0x41B2, 0xA3},
++{0x41B3, 0xA2},
++{0x41B4, 0xC1},
++{0x41B5, 0xB8},
++{0x41B6, 0xB9},
++{0x41B7, 0xBA},
++{0x41B8, 0xB8},
++{0x41B9, 0xB4},
++{0x41BA, 0xB4},
++{0x41BB, 0xB4},
++{0x41BC, 0xAA},
++{0x41BD, 0xA7},
++{0x41BE, 0xA7},
++{0x41BF, 0xA8},
++{0x41C0, 0xA4},
++{0x41C1, 0xA2},
++{0x41C2, 0xA2},
++{0x41C3, 0xA3},
++{0x41C4, 0x9E},
++{0x41C5, 0x9D},
++{0x41C6, 0x9D},
++{0x41C7, 0x9D},
++{0x41C8, 0x9E},
++{0x41C9, 0x9D},
++{0x41CA, 0x9D},
++{0x41CB, 0x9D},
++{0x41CC, 0x9E},
++{0x41CD, 0x9E},
++{0x41CE, 0x9E},
++{0x41CF, 0x9E},
++{0x41D0, 0xA3},
++{0x41D1, 0xA3},
++{0x41D2, 0xA2},
++{0x41D3, 0xA1},
++{0x41D4, 0xA7},
++{0x41D5, 0xA7},
++{0x41D6, 0xA7},
++{0x41D7, 0xA3},
++{0x4200, 0xCE},
++{0x4201, 0xC0},
++{0x4202, 0xC1},
++{0x4203, 0xB9},
++{0x4204, 0xC3},
++{0x4205, 0xB9},
++{0x4206, 0xBC},
++{0x4207, 0xBD},
++{0x4208, 0xB3},
++{0x4209, 0xAE},
++{0x420A, 0xAF},
++{0x420B, 0xAE},
++{0x420C, 0xAA},
++{0x420D, 0xA8},
++{0x420E, 0xA8},
++{0x420F, 0xA6},
++{0x4210, 0xA4},
++{0x4211, 0xA2},
++{0x4212, 0xA2},
++{0x4213, 0xA0},
++{0x4214, 0xA4},
++{0x4215, 0xA3},
++{0x4216, 0xA2},
++{0x4217, 0xA0},
++{0x4218, 0xA7},
++{0x4219, 0xA5},
++{0x421A, 0xA3},
++{0x421B, 0xA1},
++{0x421C, 0xB0},
++{0x421D, 0xA8},
++{0x421E, 0xA8},
++{0x421F, 0xA6},
++{0x4220, 0xB4},
++{0x4221, 0xAA},
++{0x4222, 0xA5},
++{0x4223, 0xA3},
++{0x4224, 0xC7},
++{0x4225, 0xBC},
++{0x4226, 0xBE},
++{0x4227, 0xBC},
++{0x4228, 0xB0},
++{0x4229, 0xA9},
++{0x422A, 0xA9},
++{0x422B, 0xA8},
++{0x422C, 0xA0},
++{0x422D, 0x9D},
++{0x422E, 0x9D},
++{0x422F, 0x9C},
++{0x4230, 0x94},
++{0x4231, 0x93},
++{0x4232, 0x93},
++{0x4233, 0x92},
++{0x4234, 0x8E},
++{0x4235, 0x8D},
++{0x4236, 0x8D},
++{0x4237, 0x8C},
++{0x4238, 0x8F},
++{0x4239, 0x8E},
++{0x423A, 0x8E},
++{0x423B, 0x8D},
++{0x423C, 0x96},
++{0x423D, 0x94},
++{0x423E, 0x94},
++{0x423F, 0x92},
++{0x4240, 0xA1},
++{0x4241, 0x9C},
++{0x4242, 0x9C},
++{0x4243, 0x99},
++{0x4244, 0xB0},
++{0x4245, 0xA8},
++{0x4246, 0xAB},
++{0x4247, 0xA7},
++{0x4248, 0xC3},
++{0x4249, 0xB7},
++{0x424A, 0xB7},
++{0x424B, 0xBC},
++{0x424C, 0xAB},
++{0x424D, 0xA4},
++{0x424E, 0xA5},
++{0x424F, 0xA5},
++{0x4250, 0x9A},
++{0x4251, 0x97},
++{0x4252, 0x97},
++{0x4253, 0x98},
++{0x4254, 0x8C},
++{0x4255, 0x8B},
++{0x4256, 0x8B},
++{0x4257, 0x8B},
++{0x4258, 0x82},
++{0x4259, 0x82},
++{0x425A, 0x82},
++{0x425B, 0x82},
++{0x425C, 0x85},
++{0x425D, 0x85},
++{0x425E, 0x85},
++{0x425F, 0x84},
++{0x4260, 0x8F},
++{0x4261, 0x8E},
++{0x4262, 0x8E},
++{0x4263, 0x8D},
++{0x4264, 0x9B},
++{0x4265, 0x98},
++{0x4266, 0x98},
++{0x4267, 0x95},
++{0x4268, 0xAE},
++{0x4269, 0xA5},
++{0x426A, 0xA7},
++{0x426B, 0xA2},
++{0x426C, 0xC2},
++{0x426D, 0xB7},
++{0x426E, 0xB8},
++{0x426F, 0xB9},
++{0x4270, 0xAA},
++{0x4271, 0xA4},
++{0x4272, 0xA4},
++{0x4273, 0xA5},
++{0x4274, 0x99},
++{0x4275, 0x96},
++{0x4276, 0x97},
++{0x4277, 0x98},
++{0x4278, 0x8B},
++{0x4279, 0x8A},
++{0x427A, 0x8A},
++{0x427B, 0x8B},
++{0x427C, 0x81},
++{0x427D, 0x81},
++{0x427E, 0x81},
++{0x427F, 0x82},
++{0x4280, 0x84},
++{0x4281, 0x84},
++{0x4282, 0x84},
++{0x4283, 0x84},
++{0x4284, 0x8E},
++{0x4285, 0x8E},
++{0x4286, 0x8D},
++{0x4287, 0x8C},
++{0x4288, 0x9A},
++{0x4289, 0x97},
++{0x428A, 0x97},
++{0x428B, 0x95},
++{0x428C, 0xAA},
++{0x428D, 0xA3},
++{0x428E, 0xA3},
++{0x428F, 0xA2},
++{0x4290, 0xC7},
++{0x4291, 0xBA},
++{0x4292, 0xC0},
++{0x4293, 0xC3},
++{0x4294, 0xB0},
++{0x4295, 0xA7},
++{0x4296, 0xA7},
++{0x4297, 0xA9},
++{0x4298, 0x9F},
++{0x4299, 0x9B},
++{0x429A, 0x9B},
++{0x429B, 0x9D},
++{0x429C, 0x93},
++{0x429D, 0x91},
++{0x429E, 0x91},
++{0x429F, 0x92},
++{0x42A0, 0x8C},
++{0x42A1, 0x8B},
++{0x42A2, 0x8B},
++{0x42A3, 0x8C},
++{0x42A4, 0x8D},
++{0x42A5, 0x8C},
++{0x42A6, 0x8C},
++{0x42A7, 0x8C},
++{0x42A8, 0x94},
++{0x42A9, 0x93},
++{0x42AA, 0x92},
++{0x42AB, 0x91},
++{0x42AC, 0x9E},
++{0x42AD, 0x9B},
++{0x42AE, 0x9B},
++{0x42AF, 0x98},
++{0x42B0, 0xAC},
++{0x42B1, 0xA6},
++{0x42B2, 0xA6},
++{0x42B3, 0xA2},
++{0x42B4, 0xCE},
++{0x42B5, 0xBA},
++{0x42B6, 0xBC},
++{0x42B7, 0xB7},
++{0x42B8, 0xC5},
++{0x42B9, 0xB5},
++{0x42BA, 0xBA},
++{0x42BB, 0xC0},
++{0x42BC, 0xB1},
++{0x42BD, 0xA8},
++{0x42BE, 0xAE},
++{0x42BF, 0xAF},
++{0x42C0, 0xA7},
++{0x42C1, 0xA3},
++{0x42C2, 0xA3},
++{0x42C3, 0xA5},
++{0x42C4, 0xA0},
++{0x42C5, 0x9D},
++{0x42C6, 0x9D},
++{0x42C7, 0x9F},
++{0x42C8, 0xA0},
++{0x42C9, 0x9E},
++{0x42CA, 0x9E},
++{0x42CB, 0x9F},
++{0x42CC, 0xA2},
++{0x42CD, 0xA0},
++{0x42CE, 0xA0},
++{0x42CF, 0xA0},
++{0x42D0, 0xA8},
++{0x42D1, 0xA5},
++{0x42D2, 0xA5},
++{0x42D3, 0xA2},
++{0x42D4, 0xB3},
++{0x42D5, 0xAA},
++{0x42D6, 0xAB},
++{0x42D7, 0xA3},
++{0x42D8, 0x00},
++{0x42D9, 0x00},
++{0x4300, 0xA2},
++{0x4301, 0xAE},
++{0x4302, 0xAD},
++{0x4303, 0xB5},
++{0x4304, 0x95},
++{0x4305, 0x9A},
++{0x4306, 0x98},
++{0x4307, 0x9B},
++{0x4308, 0x8D},
++{0x4309, 0x90},
++{0x430A, 0x8F},
++{0x430B, 0x91},
++{0x430C, 0x86},
++{0x430D, 0x88},
++{0x430E, 0x87},
++{0x430F, 0x89},
++{0x4310, 0x86},
++{0x4311, 0x87},
++{0x4312, 0x86},
++{0x4313, 0x88},
++{0x4314, 0x89},
++{0x4315, 0x88},
++{0x4316, 0x88},
++{0x4317, 0x8E},
++{0x4318, 0x90},
++{0x4319, 0x8F},
++{0x431A, 0x8C},
++{0x431B, 0x8C},
++{0x431C, 0x9C},
++{0x431D, 0x99},
++{0x431E, 0x98},
++{0x431F, 0x99},
++{0x4320, 0xAB},
++{0x4321, 0xB0},
++{0x4322, 0xAD},
++{0x4323, 0xAF},
++{0x4324, 0x9B},
++{0x4325, 0x9F},
++{0x4326, 0x9E},
++{0x4327, 0xA1},
++{0x4328, 0x8E},
++{0x4329, 0x91},
++{0x432A, 0x90},
++{0x432B, 0x93},
++{0x432C, 0x86},
++{0x432D, 0x88},
++{0x432E, 0x87},
++{0x432F, 0x89},
++{0x4330, 0x82},
++{0x4331, 0x84},
++{0x4332, 0x83},
++{0x4333, 0x84},
++{0x4334, 0x82},
++{0x4335, 0x82},
++{0x4336, 0x82},
++{0x4337, 0x83},
++{0x4338, 0x85},
++{0x4339, 0x84},
++{0x433A, 0x84},
++{0x433B, 0x85},
++{0x433C, 0x8A},
++{0x433D, 0x89},
++{0x433E, 0x88},
++{0x433F, 0x89},
++{0x4340, 0x93},
++{0x4341, 0x91},
++{0x4342, 0x91},
++{0x4343, 0x93},
++{0x4344, 0xA0},
++{0x4345, 0x9E},
++{0x4346, 0x9D},
++{0x4347, 0xA1},
++{0x4348, 0x95},
++{0x4349, 0x9B},
++{0x434A, 0x9A},
++{0x434B, 0x9C},
++{0x434C, 0x8A},
++{0x434D, 0x8D},
++{0x434E, 0x8C},
++{0x434F, 0x8D},
++{0x4350, 0x83},
++{0x4351, 0x85},
++{0x4352, 0x84},
++{0x4353, 0x85},
++{0x4354, 0x80},
++{0x4355, 0x81},
++{0x4356, 0x81},
++{0x4357, 0x81},
++{0x4358, 0x80},
++{0x4359, 0x80},
++{0x435A, 0x80},
++{0x435B, 0x80},
++{0x435C, 0x82},
++{0x435D, 0x81},
++{0x435E, 0x81},
++{0x435F, 0x81},
++{0x4360, 0x85},
++{0x4361, 0x84},
++{0x4362, 0x84},
++{0x4363, 0x85},
++{0x4364, 0x8D},
++{0x4365, 0x8B},
++{0x4366, 0x8B},
++{0x4367, 0x8D},
++{0x4368, 0x98},
++{0x4369, 0x98},
++{0x436A, 0x95},
++{0x436B, 0x98},
++{0x436C, 0x95},
++{0x436D, 0x9A},
++{0x436E, 0x99},
++{0x436F, 0x9A},
++{0x4370, 0x8A},
++{0x4371, 0x8D},
++{0x4372, 0x8C},
++{0x4373, 0x8C},
++{0x4374, 0x83},
++{0x4375, 0x85},
++{0x4376, 0x84},
++{0x4377, 0x84},
++{0x4378, 0x80},
++{0x4379, 0x80},
++{0x437A, 0x80},
++{0x437B, 0x80},
++{0x437C, 0x7F},
++{0x437D, 0x7F},
++{0x437E, 0x7F},
++{0x437F, 0x7F},
++{0x4380, 0x81},
++{0x4381, 0x80},
++{0x4382, 0x80},
++{0x4383, 0x81},
++{0x4384, 0x84},
++{0x4385, 0x83},
++{0x4386, 0x83},
++{0x4387, 0x84},
++{0x4388, 0x8B},
++{0x4389, 0x8A},
++{0x438A, 0x8A},
++{0x438B, 0x8C},
++{0x438C, 0x97},
++{0x438D, 0x96},
++{0x438E, 0x96},
++{0x438F, 0x99},
++{0x4390, 0x99},
++{0x4391, 0x9F},
++{0x4392, 0x9E},
++{0x4393, 0x9D},
++{0x4394, 0x8D},
++{0x4395, 0x90},
++{0x4396, 0x90},
++{0x4397, 0x8F},
++{0x4398, 0x85},
++{0x4399, 0x87},
++{0x439A, 0x87},
++{0x439B, 0x86},
++{0x439C, 0x81},
++{0x439D, 0x83},
++{0x439E, 0x82},
++{0x439F, 0x82},
++{0x43A0, 0x80},
++{0x43A1, 0x81},
++{0x43A2, 0x81},
++{0x43A3, 0x81},
++{0x43A4, 0x82},
++{0x43A5, 0x82},
++{0x43A6, 0x82},
++{0x43A7, 0x82},
++{0x43A8, 0x86},
++{0x43A9, 0x85},
++{0x43AA, 0x85},
++{0x43AB, 0x87},
++{0x43AC, 0x8D},
++{0x43AD, 0x8D},
++{0x43AE, 0x8D},
++{0x43AF, 0x90},
++{0x43B0, 0x9A},
++{0x43B1, 0x9A},
++{0x43B2, 0x9B},
++{0x43B3, 0x9D},
++{0x43B4, 0xA0},
++{0x43B5, 0xAD},
++{0x43B6, 0xAC},
++{0x43B7, 0xAA},
++{0x43B8, 0x93},
++{0x43B9, 0x97},
++{0x43BA, 0x97},
++{0x43BB, 0x96},
++{0x43BC, 0x8B},
++{0x43BD, 0x8E},
++{0x43BE, 0x8E},
++{0x43BF, 0x8C},
++{0x43C0, 0x83},
++{0x43C1, 0x85},
++{0x43C2, 0x85},
++{0x43C3, 0x84},
++{0x43C4, 0x82},
++{0x43C5, 0x84},
++{0x43C6, 0x83},
++{0x43C7, 0x83},
++{0x43C8, 0x83},
++{0x43C9, 0x84},
++{0x43CA, 0x84},
++{0x43CB, 0x85},
++{0x43CC, 0x8A},
++{0x43CD, 0x8A},
++{0x43CE, 0x8A},
++{0x43CF, 0x8C},
++{0x43D0, 0x92},
++{0x43D1, 0x93},
++{0x43D2, 0x93},
++{0x43D3, 0x96},
++{0x43D4, 0x9F},
++{0x43D5, 0xA6},
++{0x43D6, 0xA5},
++{0x43D7, 0xAA},
++{0x4400, 0xA1},
++{0x4401, 0xAB},
++{0x4402, 0xA7},
++{0x4403, 0xB0},
++{0x4404, 0x91},
++{0x4405, 0x96},
++{0x4406, 0x94},
++{0x4407, 0x99},
++{0x4408, 0x8A},
++{0x4409, 0x8E},
++{0x440A, 0x8C},
++{0x440B, 0x8F},
++{0x440C, 0x85},
++{0x440D, 0x86},
++{0x440E, 0x86},
++{0x440F, 0x88},
++{0x4410, 0x85},
++{0x4411, 0x86},
++{0x4412, 0x85},
++{0x4413, 0x87},
++{0x4414, 0x88},
++{0x4415, 0x87},
++{0x4416, 0x87},
++{0x4417, 0x89},
++{0x4418, 0x91},
++{0x4419, 0x8F},
++{0x441A, 0x8F},
++{0x441B, 0x90},
++{0x441C, 0x9C},
++{0x441D, 0x9B},
++{0x441E, 0x9A},
++{0x441F, 0x9A},
++{0x4420, 0xB3},
++{0x4421, 0xB1},
++{0x4422, 0xB0},
++{0x4423, 0xB2},
++{0x4424, 0x96},
++{0x4425, 0x9C},
++{0x4426, 0x9A},
++{0x4427, 0x9E},
++{0x4428, 0x8B},
++{0x4429, 0x8F},
++{0x442A, 0x8E},
++{0x442B, 0x91},
++{0x442C, 0x84},
++{0x442D, 0x87},
++{0x442E, 0x86},
++{0x442F, 0x88},
++{0x4430, 0x82},
++{0x4431, 0x83},
++{0x4432, 0x82},
++{0x4433, 0x84},
++{0x4434, 0x82},
++{0x4435, 0x82},
++{0x4436, 0x82},
++{0x4437, 0x83},
++{0x4438, 0x84},
++{0x4439, 0x84},
++{0x443A, 0x84},
++{0x443B, 0x84},
++{0x443C, 0x8B},
++{0x443D, 0x89},
++{0x443E, 0x89},
++{0x443F, 0x89},
++{0x4440, 0x95},
++{0x4441, 0x93},
++{0x4442, 0x93},
++{0x4443, 0x93},
++{0x4444, 0xA2},
++{0x4445, 0xA2},
++{0x4446, 0xA1},
++{0x4447, 0xA0},
++{0x4448, 0x8F},
++{0x4449, 0x97},
++{0x444A, 0x97},
++{0x444B, 0x98},
++{0x444C, 0x87},
++{0x444D, 0x8B},
++{0x444E, 0x8A},
++{0x444F, 0x8B},
++{0x4450, 0x81},
++{0x4451, 0x83},
++{0x4452, 0x83},
++{0x4453, 0x84},
++{0x4454, 0x7F},
++{0x4455, 0x80},
++{0x4456, 0x80},
++{0x4457, 0x81},
++{0x4458, 0x80},
++{0x4459, 0x80},
++{0x445A, 0x80},
++{0x445B, 0x80},
++{0x445C, 0x82},
++{0x445D, 0x81},
++{0x445E, 0x81},
++{0x445F, 0x81},
++{0x4460, 0x87},
++{0x4461, 0x85},
++{0x4462, 0x85},
++{0x4463, 0x86},
++{0x4464, 0x90},
++{0x4465, 0x8E},
++{0x4466, 0x8E},
++{0x4467, 0x8E},
++{0x4468, 0x9B},
++{0x4469, 0x9C},
++{0x446A, 0x9A},
++{0x446B, 0x9A},
++{0x446C, 0x91},
++{0x446D, 0x97},
++{0x446E, 0x95},
++{0x446F, 0x95},
++{0x4470, 0x87},
++{0x4471, 0x8A},
++{0x4472, 0x8A},
++{0x4473, 0x89},
++{0x4474, 0x81},
++{0x4475, 0x83},
++{0x4476, 0x83},
++{0x4477, 0x83},
++{0x4478, 0x7F},
++{0x4479, 0x80},
++{0x447A, 0x80},
++{0x447B, 0x80},
++{0x447C, 0x80},
++{0x447D, 0x80},
++{0x447E, 0x80},
++{0x447F, 0x7F},
++{0x4480, 0x81},
++{0x4481, 0x81},
++{0x4482, 0x81},
++{0x4483, 0x81},
++{0x4484, 0x85},
++{0x4485, 0x85},
++{0x4486, 0x85},
++{0x4487, 0x85},
++{0x4488, 0x8E},
++{0x4489, 0x8D},
++{0x448A, 0x8D},
++{0x448B, 0x8E},
++{0x448C, 0x9D},
++{0x448D, 0x9C},
++{0x448E, 0x9C},
++{0x448F, 0x9C},
++{0x4490, 0x94},
++{0x4491, 0x9B},
++{0x4492, 0x9A},
++{0x4493, 0x97},
++{0x4494, 0x8A},
++{0x4495, 0x8E},
++{0x4496, 0x8E},
++{0x4497, 0x8C},
++{0x4498, 0x84},
++{0x4499, 0x86},
++{0x449A, 0x86},
++{0x449B, 0x84},
++{0x449C, 0x81},
++{0x449D, 0x83},
++{0x449E, 0x83},
++{0x449F, 0x81},
++{0x44A0, 0x81},
++{0x44A1, 0x82},
++{0x44A2, 0x82},
++{0x44A3, 0x81},
++{0x44A4, 0x83},
++{0x44A5, 0x83},
++{0x44A6, 0x83},
++{0x44A7, 0x83},
++{0x44A8, 0x88},
++{0x44A9, 0x88},
++{0x44AA, 0x88},
++{0x44AB, 0x88},
++{0x44AC, 0x91},
++{0x44AD, 0x91},
++{0x44AE, 0x91},
++{0x44AF, 0x92},
++{0x44B0, 0xA0},
++{0x44B1, 0xA0},
++{0x44B2, 0xA0},
++{0x44B3, 0xA0},
++{0x44B4, 0x9E},
++{0x44B5, 0xA9},
++{0x44B6, 0xA8},
++{0x44B7, 0xA3},
++{0x44B8, 0x90},
++{0x44B9, 0x95},
++{0x44BA, 0x95},
++{0x44BB, 0x92},
++{0x44BC, 0x8A},
++{0x44BD, 0x8E},
++{0x44BE, 0x8E},
++{0x44BF, 0x8B},
++{0x44C0, 0x84},
++{0x44C1, 0x86},
++{0x44C2, 0x86},
++{0x44C3, 0x84},
++{0x44C4, 0x84},
++{0x44C5, 0x85},
++{0x44C6, 0x85},
++{0x44C7, 0x84},
++{0x44C8, 0x86},
++{0x44C9, 0x87},
++{0x44CA, 0x87},
++{0x44CB, 0x86},
++{0x44CC, 0x8D},
++{0x44CD, 0x8E},
++{0x44CE, 0x8E},
++{0x44CF, 0x8D},
++{0x44D0, 0x98},
++{0x44D1, 0x98},
++{0x44D2, 0x99},
++{0x44D3, 0x9A},
++{0x44D4, 0xA9},
++{0x44D5, 0xAA},
++{0x44D6, 0xAA},
++{0x44D7, 0xAD},
++{0x4500, 0x9F},
++{0x4501, 0xA8},
++{0x4502, 0xA5},
++{0x4503, 0xAF},
++{0x4504, 0x8F},
++{0x4505, 0x96},
++{0x4506, 0x92},
++{0x4507, 0x94},
++{0x4508, 0x89},
++{0x4509, 0x8D},
++{0x450A, 0x8A},
++{0x450B, 0x8E},
++{0x450C, 0x84},
++{0x450D, 0x85},
++{0x450E, 0x84},
++{0x450F, 0x87},
++{0x4510, 0x84},
++{0x4511, 0x85},
++{0x4512, 0x84},
++{0x4513, 0x86},
++{0x4514, 0x87},
++{0x4515, 0x86},
++{0x4516, 0x86},
++{0x4517, 0x88},
++{0x4518, 0x8F},
++{0x4519, 0x8D},
++{0x451A, 0x8D},
++{0x451B, 0x8F},
++{0x451C, 0x9A},
++{0x451D, 0x9A},
++{0x451E, 0x98},
++{0x451F, 0x9A},
++{0x4520, 0xAF},
++{0x4521, 0xAF},
++{0x4522, 0xB2},
++{0x4523, 0xB1},
++{0x4524, 0x95},
++{0x4525, 0x9B},
++{0x4526, 0x97},
++{0x4527, 0x9C},
++{0x4528, 0x8A},
++{0x4529, 0x8E},
++{0x452A, 0x8D},
++{0x452B, 0x90},
++{0x452C, 0x84},
++{0x452D, 0x86},
++{0x452E, 0x85},
++{0x452F, 0x87},
++{0x4530, 0x81},
++{0x4531, 0x82},
++{0x4532, 0x82},
++{0x4533, 0x83},
++{0x4534, 0x81},
++{0x4535, 0x81},
++{0x4536, 0x81},
++{0x4537, 0x82},
++{0x4538, 0x84},
++{0x4539, 0x83},
++{0x453A, 0x83},
++{0x453B, 0x84},
++{0x453C, 0x8A},
++{0x453D, 0x88},
++{0x453E, 0x88},
++{0x453F, 0x89},
++{0x4540, 0x94},
++{0x4541, 0x92},
++{0x4542, 0x91},
++{0x4543, 0x92},
++{0x4544, 0xA1},
++{0x4545, 0xA0},
++{0x4546, 0x9C},
++{0x4547, 0x9D},
++{0x4548, 0x8F},
++{0x4549, 0x96},
++{0x454A, 0x95},
++{0x454B, 0x92},
++{0x454C, 0x87},
++{0x454D, 0x8A},
++{0x454E, 0x89},
++{0x454F, 0x8A},
++{0x4550, 0x81},
++{0x4551, 0x83},
++{0x4552, 0x82},
++{0x4553, 0x83},
++{0x4554, 0x7F},
++{0x4555, 0x80},
++{0x4556, 0x80},
++{0x4557, 0x81},
++{0x4558, 0x7F},
++{0x4559, 0x80},
++{0x455A, 0x7F},
++{0x455B, 0x80},
++{0x455C, 0x81},
++{0x455D, 0x81},
++{0x455E, 0x81},
++{0x455F, 0x81},
++{0x4560, 0x86},
++{0x4561, 0x85},
++{0x4562, 0x85},
++{0x4563, 0x85},
++{0x4564, 0x8F},
++{0x4565, 0x8D},
++{0x4566, 0x8D},
++{0x4567, 0x8D},
++{0x4568, 0x99},
++{0x4569, 0x9A},
++{0x456A, 0x97},
++{0x456B, 0x99},
++{0x456C, 0x90},
++{0x456D, 0x95},
++{0x456E, 0x93},
++{0x456F, 0x92},
++{0x4570, 0x87},
++{0x4571, 0x8A},
++{0x4572, 0x88},
++{0x4573, 0x87},
++{0x4574, 0x81},
++{0x4575, 0x83},
++{0x4576, 0x82},
++{0x4577, 0x82},
++{0x4578, 0x7F},
++{0x4579, 0x80},
++{0x457A, 0x80},
++{0x457B, 0x80},
++{0x457C, 0x80},
++{0x457D, 0x80},
++{0x457E, 0x80},
++{0x457F, 0x80},
++{0x4580, 0x81},
++{0x4581, 0x81},
++{0x4582, 0x81},
++{0x4583, 0x81},
++{0x4584, 0x85},
++{0x4585, 0x85},
++{0x4586, 0x84},
++{0x4587, 0x85},
++{0x4588, 0x8E},
++{0x4589, 0x8D},
++{0x458A, 0x8C},
++{0x458B, 0x8D},
++{0x458C, 0x9B},
++{0x458D, 0x9B},
++{0x458E, 0x9A},
++{0x458F, 0x98},
++{0x4590, 0x94},
++{0x4591, 0x9A},
++{0x4592, 0x94},
++{0x4593, 0x90},
++{0x4594, 0x8A},
++{0x4595, 0x8D},
++{0x4596, 0x8C},
++{0x4597, 0x89},
++{0x4598, 0x84},
++{0x4599, 0x86},
++{0x459A, 0x85},
++{0x459B, 0x83},
++{0x459C, 0x82},
++{0x459D, 0x83},
++{0x459E, 0x82},
++{0x459F, 0x80},
++{0x45A0, 0x81},
++{0x45A1, 0x82},
++{0x45A2, 0x81},
++{0x45A3, 0x80},
++{0x45A4, 0x83},
++{0x45A5, 0x83},
++{0x45A6, 0x83},
++{0x45A7, 0x83},
++{0x45A8, 0x88},
++{0x45A9, 0x87},
++{0x45AA, 0x87},
++{0x45AB, 0x88},
++{0x45AC, 0x91},
++{0x45AD, 0x90},
++{0x45AE, 0x90},
++{0x45AF, 0x91},
++{0x45B0, 0x9F},
++{0x45B1, 0x9F},
++{0x45B2, 0x9E},
++{0x45B3, 0x9F},
++{0x45B4, 0x9F},
++{0x45B5, 0xA8},
++{0x45B6, 0xA6},
++{0x45B7, 0xA7},
++{0x45B8, 0x8D},
++{0x45B9, 0x95},
++{0x45BA, 0x90},
++{0x45BB, 0x8A},
++{0x45BC, 0x89},
++{0x45BD, 0x8D},
++{0x45BE, 0x88},
++{0x45BF, 0x86},
++{0x45C0, 0x84},
++{0x45C1, 0x86},
++{0x45C2, 0x85},
++{0x45C3, 0x82},
++{0x45C4, 0x84},
++{0x45C5, 0x85},
++{0x45C6, 0x85},
++{0x45C7, 0x83},
++{0x45C8, 0x86},
++{0x45C9, 0x86},
++{0x45CA, 0x86},
++{0x45CB, 0x85},
++{0x45CC, 0x8E},
++{0x45CD, 0x8D},
++{0x45CE, 0x8D},
++{0x45CF, 0x8C},
++{0x45D0, 0x99},
++{0x45D1, 0x98},
++{0x45D2, 0x98},
++{0x45D3, 0x98},
++{0x45D4, 0xA6},
++{0x45D5, 0xA9},
++{0x45D6, 0xA7},
++{0x45D7, 0xAC},
++{0x7000, 0xAB},
++{0x7001, 0xBA},
++{0x7002, 0x40},
++{0x7003, 0x02},
++{0x7004, 0x00},
++{0x7005, 0x00},
++{0x7006, 0x00},
++{0x7007, 0x00},
++{0x7008, 0x00},
++{0x7009, 0x00},
++{0x700A, 0x00},
++{0x700B, 0x00},
++{0x700C, 0x00},
++{0x700D, 0x00},
++{0x700E, 0x00},
++{0x700F, 0x00},
++{0x7010, 0x55},
++{0x7011, 0x88},
++{0x7012, 0x40},
++{0x7013, 0x01},
++{0x7014, 0x72},
++{0x7015, 0xF1},
++{0x7016, 0x02},
++{0x7017, 0xF8},
++{0x7018, 0x00},
++{0x7019, 0x00},
++{0x701A, 0x00},
++{0x701B, 0x00},
++{0x701C, 0x00},
++{0x701D, 0x00},
++{0x701E, 0x00},
++{0x701F, 0x00},
++{0x7020, 0x00},
++{0x7021, 0x00},
++{0x7022, 0x00},
++{0x7023, 0x00},
++{0x7024, 0x00},
++{0x7025, 0x00},
++{0x7026, 0x00},
++{0x7027, 0x00},
++{0x7028, 0x00},
++{0x7029, 0x00},
++{0x702A, 0x00},
++{0x702B, 0x00},
++{0x702C, 0x00},
++{0x702D, 0x00},
++{0x702E, 0x00},
++{0x702F, 0x00},
++{0x7030, 0x00},
++{0x7031, 0x00},
++{0x7032, 0x00},
++{0x7033, 0x00},
++{0x7034, 0x00},
++{0x7035, 0x00},
++{0x7036, 0x00},
++{0x7037, 0x00},
++{0x7038, 0x00},
++{0x7039, 0x00},
++{0x703A, 0x00},
++{0x703B, 0x00},
++{0x703C, 0x00},
++{0x703D, 0x00},
++{0x703E, 0x00},
++{0x703F, 0x00},
++{0x7040, 0x00},
++{0x7041, 0x00},
++{0x7042, 0x00},
++{0x7043, 0x00},
++{0x7044, 0x00},
++{0x7045, 0x00},
++{0x7046, 0x00},
++{0x7047, 0x00},
++{0x7048, 0x00},
++{0x7049, 0x00},
++{0x704A, 0x00},
++{0x704B, 0x00},
++{0x704C, 0x00},
++{0x704D, 0x00},
++{0x704E, 0x00},
++{0x704F, 0x00},
++{0x7050, 0x00},
++{0x7051, 0x00},
++{0x7052, 0x00},
++{0x7053, 0x00},
++{0x7054, 0x00},
++{0x7055, 0x00},
++{0x7056, 0x00},
++{0x7057, 0x00},
++{0x7058, 0x00},
++{0x7059, 0x00},
++{0x705A, 0x00},
++{0x705B, 0x00},
++{0x705C, 0x00},
++{0x705D, 0x00},
++{0x705E, 0x00},
++{0x705F, 0x00},
++{0x7060, 0x00},
++{0x7061, 0x00},
++{0x7062, 0x00},
++{0x7063, 0x00},
++{0x7064, 0x00},
++{0x7065, 0x00},
++{0x7066, 0x00},
++{0x7067, 0x00},
++{0x7068, 0x00},
++{0x7069, 0x00},
++{0x706A, 0x00},
++{0x706B, 0x00},
++{0x706C, 0x00},
++{0x706D, 0x00},
++{0x706E, 0x00},
++{0x706F, 0x00},
++{0x7070, 0x00},
++{0x7071, 0x00},
++{0x7072, 0x00},
++{0x7073, 0x00},
++{0x7074, 0x00},
++{0x7075, 0x00},
++{0x7076, 0x00},
++{0x7077, 0x00},
++{0x7078, 0x00},
++{0x7079, 0x00},
++{0x707A, 0x00},
++{0x707B, 0x00},
++{0x707C, 0x00},
++{0x707D, 0x00},
++{0x707E, 0x00},
++{0x707F, 0x00},
++{0x7080, 0x00},
++{0x7081, 0x00},
++{0x7082, 0x00},
++{0x7083, 0x00},
++{0x7084, 0x00},
++{0x7085, 0x00},
++{0x7086, 0x00},
++{0x7087, 0x00},
++{0x7088, 0x00},
++{0x7089, 0x00},
++{0x708A, 0x00},
++{0x708B, 0x00},
++{0x708C, 0x00},
++{0x708D, 0x00},
++{0x708E, 0x00},
++{0x708F, 0x00},
++{0x7090, 0x00},
++{0x7091, 0xF0},
++{0x7092, 0x02},
++{0x7093, 0xF8},
++{0x7094, 0x8D},
++{0x7095, 0xF6},
++{0x7096, 0xFA},
++{0x7097, 0xFF},
++{0x7098, 0xF0},
++{0x7099, 0xB5},
++{0x709A, 0x04},
++{0x709B, 0x46},
++{0x709C, 0x8F},
++{0x709D, 0xB0},
++{0x709E, 0x5F},
++{0x709F, 0x48},
++{0x70A0, 0x0C},
++{0x70A1, 0x90},
++{0x70A2, 0x5F},
++{0x70A3, 0x48},
++{0x70A4, 0x06},
++{0x70A5, 0x90},
++{0x70A6, 0x20},
++{0x70A7, 0x46},
++{0x70A8, 0x34},
++{0x70A9, 0x30},
++{0x70AA, 0x0B},
++{0x70AB, 0x90},
++{0x70AC, 0x5B},
++{0x70AD, 0x48},
++{0x70AE, 0x5A},
++{0x70AF, 0x49},
++{0x70B0, 0x26},
++{0x70B1, 0x46},
++{0x70B2, 0x66},
++{0x70B3, 0x30},
++{0x70B4, 0x3A},
++{0x70B5, 0x31},
++{0x70B6, 0x3C},
++{0x70B7, 0x36},
++{0x70B8, 0x05},
++{0x70B9, 0x90},
++{0x70BA, 0x0A},
++{0x70BB, 0x30},
++{0x70BC, 0x04},
++{0x70BD, 0x90},
++{0x70BE, 0x59},
++{0x70BF, 0x48},
++{0x70C0, 0x55},
++{0x70C1, 0x4A},
++{0x70C2, 0x40},
++{0x70C3, 0x6E},
++{0x70C4, 0xC0},
++{0x70C5, 0x07},
++{0x70C6, 0x7D},
++{0x70C7, 0xD1},
++{0x70C8, 0x17},
++{0x70C9, 0x88},
++{0x70CA, 0x0A},
++{0x70CB, 0x5E},
++{0x70CC, 0x0D},
++{0x70CD, 0x92},
++{0x70CE, 0x53},
++{0x70CF, 0x49},
++{0x70D0, 0x55},
++{0x70D1, 0x48},
++{0x70D2, 0x94},
++{0x70D3, 0x31},
++{0x70D4, 0x89},
++{0x70D5, 0x6B},
++{0x70D6, 0x80},
++{0x70D7, 0x68},
++{0x70D8, 0x09},
++{0x70D9, 0x02},
++{0x70DA, 0x00},
++{0x70DB, 0x03},
++{0x70DC, 0x09},
++{0x70DD, 0x0E},
++{0x70DE, 0x00},
++{0x70DF, 0x0B},
++{0x70E0, 0x49},
++{0x70E1, 0x1C},
++{0x70E2, 0x48},
++{0x70E3, 0x43},
++{0x70E4, 0x4D},
++{0x70E5, 0x49},
++{0x70E6, 0x6C},
++{0x70E7, 0x39},
++{0x70E8, 0x8A},
++{0x70E9, 0x6A},
++{0x70EA, 0x07},
++{0x70EB, 0x92},
++{0x70EC, 0xCA},
++{0x70ED, 0x6A},
++{0x70EE, 0x00},
++{0x70EF, 0x21},
++{0x70F0, 0xC9},
++{0x70F1, 0x43},
++{0x70F2, 0x03},
++{0x70F3, 0x92},
++{0x70F4, 0x00},
++{0x70F5, 0x22},
++{0x70F6, 0x00},
++{0x70F7, 0x91},
++{0x70F8, 0x01},
++{0x70F9, 0x92},
++{0x70FA, 0x39},
++{0x70FB, 0x46},
++{0x70FC, 0x8F},
++{0x70FD, 0xF6},
++{0x70FE, 0xCE},
++{0x70FF, 0xFB},
++{0x7100, 0x01},
++{0x7101, 0x22},
++{0x7102, 0x00},
++{0x7103, 0x23},
++{0x7104, 0x8C},
++{0x7105, 0xF6},
++{0x7106, 0x02},
++{0x7107, 0xFA},
++{0x7108, 0x00},
++{0x7109, 0x21},
++{0x710A, 0x05},
++{0x710B, 0x46},
++{0x710C, 0x01},
++{0x710D, 0x91},
++{0x710E, 0x00},
++{0x710F, 0x90},
++{0x7110, 0x39},
++{0x7111, 0x46},
++{0x7112, 0x07},
++{0x7113, 0x98},
++{0x7114, 0x8F},
++{0x7115, 0xF6},
++{0x7116, 0xC2},
++{0x7117, 0xFB},
++{0x7118, 0x0D},
++{0x7119, 0x9A},
++{0x711A, 0xD3},
++{0x711B, 0x17},
++{0x711C, 0x80},
++{0x711D, 0x18},
++{0x711E, 0x59},
++{0x711F, 0x41},
++{0x7120, 0x01},
++{0x7121, 0x22},
++{0x7122, 0x00},
++{0x7123, 0x23},
++{0x7124, 0x8C},
++{0x7125, 0xF6},
++{0x7126, 0xCD},
++{0x7127, 0xF9},
++{0x7128, 0x07},
++{0x7129, 0x90},
++{0x712A, 0x00},
++{0x712B, 0x20},
++{0x712C, 0x01},
++{0x712D, 0x90},
++{0x712E, 0x00},
++{0x712F, 0x95},
++{0x7130, 0x39},
++{0x7131, 0x46},
++{0x7132, 0x03},
++{0x7133, 0x98},
++{0x7134, 0x8F},
++{0x7135, 0xF6},
++{0x7136, 0xB2},
++{0x7137, 0xFB},
++{0x7138, 0x01},
++{0x7139, 0x22},
++{0x713A, 0x00},
++{0x713B, 0x23},
++{0x713C, 0x8C},
++{0x713D, 0xF6},
++{0x713E, 0xE6},
++{0x713F, 0xF9},
++{0x7140, 0x02},
++{0x7141, 0x46},
++{0x7142, 0x07},
++{0x7143, 0x98},
++{0x7144, 0x00},
++{0x7145, 0x23},
++{0x7146, 0x81},
++{0x7147, 0x0B},
++{0x7148, 0x80},
++{0x7149, 0x04},
++{0x714A, 0x7A},
++{0x714B, 0xF6},
++{0x714C, 0x54},
++{0x714D, 0xF8},
++{0x714E, 0x37},
++{0x714F, 0x4A},
++{0x7150, 0x00},
++{0x7151, 0x23},
++{0x7152, 0x00},
++{0x7153, 0x92},
++{0x7154, 0x01},
++{0x7155, 0x93},
++{0x7156, 0x01},
++{0x7157, 0x22},
++{0x7158, 0x8C},
++{0x7159, 0xF6},
++{0x715A, 0xD8},
++{0x715B, 0xF9},
++{0x715C, 0x05},
++{0x715D, 0x46},
++{0x715E, 0x60},
++{0x715F, 0x68},
++{0x7160, 0x00},
++{0x7161, 0x23},
++{0x7162, 0x01},
++{0x7163, 0x0C},
++{0x7164, 0x00},
++{0x7165, 0x04},
++{0x7166, 0xE2},
++{0x7167, 0x68},
++{0x7168, 0x7A},
++{0x7169, 0xF6},
++{0x716A, 0x45},
++{0x716B, 0xF8},
++{0x716C, 0x00},
++{0x716D, 0x22},
++{0x716E, 0xD2},
++{0x716F, 0x43},
++{0x7170, 0x00},
++{0x7171, 0x23},
++{0x7172, 0x00},
++{0x7173, 0x92},
++{0x7174, 0x01},
++{0x7175, 0x93},
++{0x7176, 0x1A},
++{0x7177, 0x46},
++{0x7178, 0x8C},
++{0x7179, 0xF6},
++{0x717A, 0xC8},
++{0x717B, 0xF9},
++{0x717C, 0x29},
++{0x717D, 0x46},
++{0x717E, 0x8F},
++{0x717F, 0xF6},
++{0x7180, 0x8D},
++{0x7181, 0xFB},
++{0x7182, 0x8A},
++{0x7183, 0x03},
++{0x7184, 0x80},
++{0x7185, 0x0C},
++{0x7186, 0x10},
++{0x7187, 0x43},
++{0x7188, 0x00},
++{0x7189, 0x22},
++{0x718A, 0xD2},
++{0x718B, 0x43},
++{0x718C, 0x00},
++{0x718D, 0x23},
++{0x718E, 0x00},
++{0x718F, 0x92},
++{0x7190, 0x89},
++{0x7191, 0x0C},
++{0x7192, 0x01},
++{0x7193, 0x93},
++{0x7194, 0x1A},
++{0x7195, 0x46},
++{0x7196, 0x8C},
++{0x7197, 0xF6},
++{0x7198, 0xB9},
++{0x7199, 0xF9},
++{0x719A, 0x00},
++{0x719B, 0x24},
++{0x719C, 0x03},
++{0x719D, 0x90},
++{0x719E, 0x0C},
++{0x719F, 0x98},
++{0x71A0, 0x61},
++{0x71A1, 0x00},
++{0x71A2, 0x45},
++{0x71A3, 0x5A},
++{0x71A4, 0x06},
++{0x71A5, 0x98},
++{0x71A6, 0x22},
++{0x71A7, 0x4A},
++{0x71A8, 0x40},
++{0x71A9, 0x5A},
++{0x71AA, 0x00},
++{0x71AB, 0x21},
++{0x71AC, 0x8C},
++{0x71AD, 0xF6},
++{0x71AE, 0xBE},
++{0x71AF, 0xF9},
++{0x71B0, 0x07},
++{0x71B1, 0x46},
++{0x71B2, 0x28},
++{0x71B3, 0x46},
++{0x71B4, 0x03},
++{0x71B5, 0x99},
++{0x71B6, 0x8F},
++{0x71B7, 0xF6},
++{0x71B8, 0x71},
++{0x71B9, 0xFB},
++{0x71BA, 0x3A},
++{0x71BB, 0x46},
++{0x71BC, 0x00},
++{0x71BD, 0x23},
++{0x71BE, 0x79},
++{0x71BF, 0xF6},
++{0x71C0, 0xCA},
++{0x71C1, 0xFF},
++{0x71C2, 0x00},
++{0x71C3, 0xE0},
++{0x71C4, 0x0F},
++{0x71C5, 0xE0},
++{0x71C6, 0x8A},
++{0x71C7, 0x02},
++{0x71C8, 0x80},
++{0x71C9, 0x0D},
++{0x71CA, 0x10},
++{0x71CB, 0x43},
++{0x71CC, 0x19},
++{0x71CD, 0x4A},
++{0x71CE, 0x00},
++{0x71CF, 0x23},
++{0x71D0, 0x00},
++{0x71D1, 0x92},
++{0x71D2, 0x89},
++{0x71D3, 0x0D},
++{0x71D4, 0x01},
++{0x71D5, 0x93},
++{0x71D6, 0x40},
++{0x71D7, 0x22},
++{0x71D8, 0x8C},
++{0x71D9, 0xF6},
++{0x71DA, 0x98},
++{0x71DB, 0xF9},
++{0x71DC, 0xA1},
++{0x71DD, 0x00},
++{0x71DE, 0x64},
++{0x71DF, 0x1C},
++{0x71E0, 0x70},
++{0x71E1, 0x50},
++{0x71E2, 0x04},
++{0x71E3, 0x2C},
++{0x71E4, 0xDB},
++{0x71E5, 0xD3},
++{0x71E6, 0x14},
++{0x71E7, 0x4D},
++{0x71E8, 0x00},
++{0x71E9, 0x24},
++{0x71EA, 0x0B},
++{0x71EB, 0x98},
++{0x71EC, 0x67},
++{0x71ED, 0x00},
++{0x71EE, 0xC0},
++{0x71EF, 0x5B},
++{0x71F0, 0x2A},
++{0x71F1, 0x46},
++{0x71F2, 0x40},
++{0x71F3, 0x21},
++{0x71F4, 0x8C},
++{0x71F5, 0xF6},
++{0x71F6, 0x9A},
++{0x71F7, 0xF9},
++{0x71F8, 0x05},
++{0x71F9, 0x99},
++{0x71FA, 0x0E},
++{0x71FB, 0x4A},
++{0x71FC, 0xC8},
++{0x71FD, 0x53},
++{0x71FE, 0xA7},
++{0x71FF, 0x00},
++{0x7200, 0xF0},
++{0x7201, 0x59},
++{0x7202, 0x40},
++{0x7203, 0x21},
++{0x7204, 0x8C},
++{0x7205, 0xF6},
++{0x7206, 0x7B},
++{0x7207, 0xF9},
++{0x7208, 0x04},
++{0x7209, 0x99},
++{0x720A, 0x64},
++{0x720B, 0x1C},
++{0x720C, 0xC8},
++{0x720D, 0x51},
++{0x720E, 0x04},
++{0x720F, 0x2C},
++{0x7210, 0xEB},
++{0x7211, 0xD3},
++{0x7212, 0x0F},
++{0x7213, 0xB0},
++{0x7214, 0xF0},
++{0x7215, 0xBD},
++{0x7216, 0x00},
++{0x7217, 0x00},
++{0x7218, 0x76},
++{0x7219, 0x69},
++{0x721A, 0x18},
++{0x721B, 0x00},
++{0x721C, 0xEC},
++{0x721D, 0x58},
++{0x721E, 0x18},
++{0x721F, 0x00},
++{0x7220, 0x38},
++{0x7221, 0x36},
++{0x7222, 0x18},
++{0x7223, 0x00},
++{0x7224, 0x00},
++{0x7225, 0x35},
++{0x7226, 0x18},
++{0x7227, 0x00},
++{0x7228, 0x00},
++{0x7229, 0x20},
++{0x722A, 0x18},
++{0x722B, 0x00},
++{0x722C, 0xFF},
++{0x722D, 0xFF},
++{0x722E, 0xFF},
++{0x722F, 0x3F},
++{0x7230, 0xFF},
++{0x7231, 0x07},
++{0x7232, 0x00},
++{0x7233, 0x00},
++{0x7234, 0xFF},
++{0x7235, 0xFF},
++{0x7236, 0x07},
++{0x7237, 0x00},
++{0x7238, 0xFF},
++{0x7239, 0x1F},
++{0x723A, 0x00},
++{0x723B, 0x00},
++{0x723C, 0x01},
++{0x723D, 0xF6},
++{0x723E, 0x45},
++{0x723F, 0x12},
++{0x0000, 0x00},
++};
+diff --git a/drivers/media/i2c/soc_camera/max9286.c b/drivers/media/i2c/soc_camera/max9286.c
+index d01acdc..88eab02 100644
+--- a/drivers/media/i2c/soc_camera/max9286.c
++++ b/drivers/media/i2c/soc_camera/max9286.c
+@@ -17,10 +17,8 @@
+ #include <linux/of_graph.h>
+ #include <linux/videodev2.h>
+
+-#include <media/v4l2-async.h>
+ #include <media/v4l2-common.h>
+ #include <media/v4l2-device.h>
+-#include <media/v4l2-fwnode.h>
+ #include <media/v4l2-subdev.h>
+
+ #include "max9286.h"
+@@ -45,6 +43,7 @@ struct max9286_priv {
+ int csi_rate;
+ const char *fsync_mode;
+ int fsync_period;
++ int pclk;
+ char pclk_rising_edge;
+ int gpio_resetb;
+ int active_low_resetb;
+@@ -53,12 +52,26 @@ struct max9286_priv {
+ int vsync;
+ int timeout;
+ int poc_delay;
++ int bws;
++ int dbl;
++ int dt;
++ int hsgen;
++ int hts;
++ int vts;
++ int hts_delay;
++ int imager_width;
+ atomic_t use_count;
+ u32 csi2_outord;
++ u32 switchin;
+ struct i2c_client *client;
+ int max9271_addr_map[4];
+ int ser_id;
+ struct gpio_desc *poc_gpio[4]; /* PoC power supply */
++
++ /* link statistic */
++ int prbserr[4];
++ int deterr[4];
++ int correrr[4];
+ };
+
+ static char fsync_mode_default[20] = "manual"; /* manual, automatic, semi-automatic, external */
+@@ -95,9 +108,57 @@ static int active_low_resetb;
+ module_param(active_low_resetb, int, 0644);
+ MODULE_PARM_DESC(active_low_resetb, " Serializer GPIO reset level (default: 0 - active high)");
+
+-static int poc_delay;
++static int poc_delay = 50;
+ module_param(poc_delay, int, 0644);
+-MODULE_PARM_DESC(poc_delay, " Delay in ms after POC enable (default: 0 ms)");
++MODULE_PARM_DESC(poc_delay, " Delay in ms after POC enable (default: 50 ms)");
++
++static int bws;
++module_param(bws, int, 0644);
++MODULE_PARM_DESC(bws, " BWS mode (default: 0 - 24-bit gmsl packets)");
++
++static int dbl = 1;
++module_param(dbl, int, 0644);
++MODULE_PARM_DESC(dbl, " DBL mode (default: 1 - DBL mode enabled)");
++
++static int dt = 3;
++module_param(dt, int, 0644);
++MODULE_PARM_DESC(dt, " DataType (default: 3 - YUV8), 0 - RGB888, 5 - RAW8, 6 - RAW10, 7 - RAW12, 8 - RAW14");
++
++static int hsgen;
++module_param(hsgen, int, 0644);
++MODULE_PARM_DESC(hsgen, " Enable HS embedded generator (default: 0 - disabled)");
++
++static int pclk = 100;
++module_param(pclk, int, 0644);
++MODULE_PARM_DESC(pclk, " PCLK rate (default: 100MHz)");
++
++static int switchin = 0;
++module_param(switchin, int, 0644);
++MODULE_PARM_DESC(switchin, " COAX SWITCH IN+ and IN- (default: 0 - not switched)");
++
++enum {
++ RGB888_DT = 0,
++ RGB565_DT,
++ RGB666_DT,
++ YUV8_DT, /* default */
++ YUV10_DT,
++ RAW8_DT,
++ RAW10_DT,
++ RAW12_DT,
++ RAW14_DT,
++};
++
++static int dt2bpp [9] = {
++ 24, /* RGB888 */
++ 16, /* RGB565 */
++ 18, /* RGB666 */
++ 8, /* YUV8 - default */
++ 10, /* YUV10 */
++ 8, /* RAW8/RAW16 */
++ 10, /* RAW10 */
++ 12, /* RAW12 */
++ 14, /* RAW14 */
++};
+
+ static char* ser_name(int id)
+ {
+@@ -106,11 +167,42 @@ static char* ser_name(int id)
+ return "MAX9271";
+ case MAX96705_ID:
+ return "MAX96705";
++ case MAX96707_ID:
++ return "MAX96707";
+ default:
+ return "unknown";
+ }
+ }
+
++static void max9286_write_remote_verify(struct i2c_client *client, int idx, u8 reg, u8 val)
++{
++ struct max9286_priv *priv = i2c_get_clientdata(client);
++ int timeout;
++
++ for (timeout = 0; timeout < 10; timeout++) {
++ int tmp_addr;
++ u8 sts = 0;
++ u8 val2 = 0;
++
++ reg8_write(client, reg, val);
++
++ tmp_addr = client->addr;
++ client->addr = priv->des_addr; /* MAX9286-CAMx I2C */
++ reg8_read(client, 0x70, &sts);
++ client->addr = tmp_addr;
++ if (sts & BIT(idx)) /* if ACKed */ {
++ reg8_read(client, reg, &val2);
++ if (val2 == val)
++ break;
++ }
++
++ usleep_range(1000, 1500);
++ }
++
++ if (timeout >= 10)
++ dev_err(&client->dev, "timeout remote write acked\n");
++}
++
+ static void max9286_preinit(struct i2c_client *client, int addr)
+ {
+ struct max9286_priv *priv = i2c_get_clientdata(client);
+@@ -118,8 +210,9 @@ static void max9286_preinit(struct i2c_client *client, int addr)
+ client->addr = addr; /* MAX9286-CAMx I2C */
+ reg8_write(client, 0x0a, 0x00); /* disable reverse control for all cams */
+ reg8_write(client, 0x00, 0x00); /* disable all GMSL links [0:3] */
+- usleep_range(2000, 2500); /* wait 2ms after any change of reverse channel settings */
+- reg8_write(client, 0x1c, priv->him ? 0xf4 : 0x04); /* high-immunity or legacy mode */
++// usleep_range(2000, 2500); /* wait 2ms after any change of reverse channel settings */
++ reg8_write(client, 0x1b, priv->switchin); /* coax polarity (default - normal) */
++ reg8_write(client, 0x1c, priv->him ? 0xf4 : 0x04); /* high-immunity/legacy mode, BWS: 24-bit */
+ }
+
+ static void max9286_sensor_reset(struct i2c_client *client, int addr, int reset_on)
+@@ -142,11 +235,16 @@ static void max9286_postinit(struct i2c_client *client, int addr)
+ int idx;
+
+ for (idx = 0; idx < priv->links; idx++) {
++ if (priv->ser_id == MAX96705_ID || priv->ser_id == MAX96707_ID)
++ continue;
++
+ client->addr = priv->des_addr; /* MAX9286 I2C */
++ reg8_write(client, 0x00, 0xe0 | BIT(idx)); /* enable GMSL link for CAMx */
+ reg8_write(client, 0x0a, 0x11 << idx); /* enable reverse/forward control for CAMx */
++ usleep_range(5000, 5500); /* wait 2ms after any change of reverse channel settings */
+
+ client->addr = priv->max9271_addr_map[idx]; /* MAX9271-CAMx I2C */
+- max9286_sensor_reset(client, client->addr, 0); /* sensor unreset */
++ max9286_sensor_reset(client, client->addr, 0); /* sensor unreset using gpios. TODO: should be in imager driver */
+ }
+
+ client->addr = addr; /* MAX9286 I2C */
+@@ -154,7 +252,9 @@ static void max9286_postinit(struct i2c_client *client, int addr)
+ reg8_write(client, 0x00, 0xe0 | priv->links_mask); /* enable GMSL link for CAMs */
+ reg8_write(client, 0x0b, priv->csi2_outord); /* CSI2 output order */
+ reg8_write(client, 0x15, 0x9b); /* enable CSI output, VC is set accordingly to Link number, BIT7 magic must be set */
+- reg8_write(client, 0x1b, priv->links_mask); /* enable equalizer for CAMs */
++ reg8_write(client, 0x1b, priv->switchin | priv->links_mask); /* coax polarity, enable equalizer for CAMs */
++ reg8_write(client, 0x1c, (priv->him ? 0xf0 : 0x00) |
++ (priv->bws ? 0x05 : 0x04)); /* high-immunity/legacy mode, BWS 24/32-bit */
+ usleep_range(5000, 5500); /* wait 2ms after any change of reverse channel settings */
+
+ if (strcmp(priv->fsync_mode, "manual") == 0) {
+@@ -178,7 +278,6 @@ static int max9286_reverse_channel_setup(struct i2c_client *client, int idx)
+
+ /* Reverse channel enable */
+ client->addr = priv->des_addr; /* MAX9286-CAMx I2C */
+- reg8_write(client, 0x3f, 0x4f); /* enable custom reverse channel & first pulse length */
+ reg8_write(client, 0x34, 0xa2 | MAXIM_I2C_I2C_SPEED); /* enable artificial ACKs, I2C speed set */
+ usleep_range(2000, 2500); /* wait 2ms after any change of reverse channel settings */
+ reg8_write(client, 0x00, 0xe0 | BIT(idx)); /* enable GMSL link for CAMx */
+@@ -186,24 +285,35 @@ static int max9286_reverse_channel_setup(struct i2c_client *client, int idx)
+ usleep_range(2000, 2500); /* wait 2ms after any change of reverse channel settings */
+
+ for (;;) {
+- client->addr = priv->des_addr; /* MAX9286-CAMx I2C */
+- reg8_write(client, 0x3b, 0x1e); /* first pulse length rise time changed from 300ns to 200ns, amplitude 100mV */
+- usleep_range(2000, 2500); /* wait 2ms after any change of reverse channel settings */
++ if (priv->him) {
++ /* HIM mode setup */
++ client->addr = 0x40; /* MAX9271-CAMx I2C */
++ reg8_write(client, 0x4d, 0xc0);
++ usleep_range(2000, 2500); /* wait 2ms after any change of reverse channel settings */
++ reg8_write(client, 0x04, 0x43); /* wake-up, enable reverse_control/conf_link */
++ usleep_range(2000, 2500); /* wait 2ms after any change of reverse channel settings */
++ } else {
++ /* Legacy mode setup */
++ client->addr = priv->des_addr; /* MAX9286-CAMx I2C */
++ reg8_write(client, 0x3f, 0x4f); /* enable custom reverse channel & first pulse length */
++ reg8_write(client, 0x3b, 0x1e); /* first pulse length rise time changed from 300ns to 200ns, amplitude 100mV */
++ usleep_range(2000, 2500); /* wait 2ms after any change of reverse channel settings */
+
+- client->addr = 0x40; /* MAX9271-CAMx I2C */
+- reg8_write(client, 0x04, 0x43); /* wake-up, enable reverse_control/conf_link */
+- usleep_range(2000, 2500); /* wait 2ms after any change of reverse channel settings */
+- reg8_write(client, 0x08, 0x01); /* reverse channel receiver high threshold enable */
+- reg8_write(client, 0x97, priv->him ? 0xaf : 0x5f); /* enable reverse control channel programming (MAX96705-MAX96711 only) */
+- usleep_range(2000, 2500); /* wait 2ms after any change of reverse channel settings */
++ client->addr = 0x40; /* MAX9271-CAMx I2C */
++ reg8_write(client, 0x04, 0x43); /* wake-up, enable reverse_control/conf_link */
++ usleep_range(2000, 2500); /* wait 2ms after any change of reverse channel settings */
++ reg8_write(client, 0x08, 0x01); /* reverse channel receiver high threshold enable */
++ reg8_write(client, 0x97, 0x5f); /* enable reverse control channel programming (MAX96705-MAX96711 only) */
++ usleep_range(2000, 2500); /* wait 2ms after any change of reverse channel settings */
+
+- client->addr = priv->des_addr; /* MAX9286-CAMx I2C */
+- reg8_write(client, 0x3b, 0x19); /* reverse channel increase amplitude 170mV to compensate high threshold enabled */
+- usleep_range(2000, 2500); /* wait 2ms after any change of reverse channel settings */
++ client->addr = priv->des_addr; /* MAX9286-CAMx I2C */
++ reg8_write(client, 0x3b, 0x19); /* reverse channel increase amplitude 170mV to compensate high threshold enabled */
++ usleep_range(2000, 2500); /* wait 2ms after any change of reverse channel settings */
++ }
+
+ client->addr = 0x40; /* MAX9271-CAMx I2C */
+ reg8_read(client, 0x1e, &val); /* read max9271 ID */
+- if (val == MAX9271_ID || val == MAX96705_ID || --timeout == 0) {
++ if (val == MAX9271_ID || val == MAX96705_ID || val == MAX96707_ID || --timeout == 0) {
+ priv->ser_id = val;
+ break;
+ }
+@@ -211,7 +321,7 @@ static int max9286_reverse_channel_setup(struct i2c_client *client, int idx)
+ /* Check if already initialized (after reboot/reset ?) */
+ client->addr = priv->max9271_addr_map[idx]; /* MAX9271-CAMx I2C */
+ reg8_read(client, 0x1e, &val); /* read max9271 ID */
+- if (val == MAX9271_ID || val == MAX96705_ID) {
++ if (val == MAX9271_ID || val == MAX96705_ID || val == MAX96707_ID) {
+ priv->ser_id = val;
+ reg8_write(client, 0x04, 0x43); /* enable reverse_control/conf_link */
+ usleep_range(2000, 2500); /* wait 2ms after any change of reverse channel settings */
+@@ -258,22 +368,9 @@ static void max9286_initial_setup(struct i2c_client *client)
+ client->addr = priv->des_addr; /* MAX9286-CAMx I2C */
+ reg8_write(client, 0x15, 0x13); /* disable CSI output, VC is set accordingly to Link number */
+ reg8_write(client, 0x69, 0x0f); /* mask CSI forwarding from all links */
+- switch (priv->lanes) {
+- case 1:
+- reg8_write(client, 0x12, 0x33); /* enable CSI-2 Lane D0, DBL mode, YUV422 8-bit*/
+- break;
+- case 2:
+- reg8_write(client, 0x12, 0x73); /* enable CSI-2 Lanes D0,D1, DBL mode, YUV422 8-bit*/
+- break;
+- case 3:
+- reg8_write(client, 0x12, 0xd3); /* enable CSI-2 Lanes D0-D2, DBL mode, YUV422 8-bit*/
+- break;
+- case 4:
+- reg8_write(client, 0x12, 0xf3); /* enable CSI-2 Lanes D0-D3, DBL mode, YUV422 8-bit*/
+- break;
+- default:
+- dev_err(&client->dev, "CSI2 lanes number is invalid (%d)\n", priv->lanes);
+- }
++ reg8_write(client, 0x12, ((priv->lanes - 1) << 6) |
++ (priv->dbl ? 0x30 : 0) |
++ (priv->dt & 0xf)); /* setup lanes, DBL mode, DataType */
+
+ /* Start GMSL initialization with FSYNC disabled. This is required for some odd LVDS cameras */
+ reg8_write(client, 0x01, 0xc0); /* ECU (aka MCU) based FrameSync using GPI-to-GPO */
+@@ -294,30 +391,96 @@ static void max9286_gmsl_link_setup(struct i2c_client *client, int idx)
+ /* GMSL setup */
+ client->addr = 0x40; /* MAX9271-CAMx I2C */
+ reg8_write(client, 0x0d, 0x22 | MAXIM_I2C_I2C_SPEED); /* disable artificial ACK, I2C speed set */
+- reg8_write(client, 0x07, 0x84 | (priv->pclk_rising_edge ? 0 : 0x10)); /* RAW/YUV, PCLK edge, HS/VS encoding enabled */
++ reg8_write(client, 0x07, 0x04 | (priv->pclk_rising_edge ? 0 : 0x10) | (priv->dbl ? 0x80 : 0)); /* RAW/YUV, PCLK edge, HS/VS encoding enabled, DBL mode, BWS 24-bit */
+ usleep_range(2000, 2500); /* wait 2ms */
+ reg8_write(client, 0x02, 0xff); /* spread spectrum +-4%, pclk range automatic, Gbps automatic */
+ usleep_range(2000, 2500); /* wait 2ms */
+
+- if (priv->ser_id == MAX96705_ID) {
+- /* setup crossbar in DBL mode: reverse DVP bus */
+- reg8_write(client, 0x20, 0x07);
+- reg8_write(client, 0x21, 0x06);
+- reg8_write(client, 0x22, 0x05);
+- reg8_write(client, 0x23, 0x04);
+- reg8_write(client, 0x24, 0x03);
+- reg8_write(client, 0x25, 0x02);
+- reg8_write(client, 0x26, 0x01);
+- reg8_write(client, 0x27, 0x00);
+-
+- reg8_write(client, 0x30, 0x17);
+- reg8_write(client, 0x31, 0x16);
+- reg8_write(client, 0x32, 0x15);
+- reg8_write(client, 0x33, 0x14);
+- reg8_write(client, 0x34, 0x13);
+- reg8_write(client, 0x35, 0x12);
+- reg8_write(client, 0x36, 0x11);
+- reg8_write(client, 0x37, 0x10);
++ if (priv->ser_id == MAX96705_ID || priv->ser_id == MAX96707_ID) {
++ switch (priv->dt) {
++ case YUV8_DT:
++ /* setup crossbar for YUV8/RAW8: reverse DVP bus */
++ reg8_write(client, 0x20, 7);
++ reg8_write(client, 0x21, 6);
++ reg8_write(client, 0x22, 5);
++ reg8_write(client, 0x23, 4);
++ reg8_write(client, 0x24, 3);
++ reg8_write(client, 0x25, 2);
++ reg8_write(client, 0x26, 1);
++ reg8_write(client, 0x27, 0);
++
++ /* this is second byte if DBL=1 */
++ reg8_write(client, 0x30, 23);
++ reg8_write(client, 0x31, 22);
++ reg8_write(client, 0x32, 21);
++ reg8_write(client, 0x33, 20);
++ reg8_write(client, 0x34, 19);
++ reg8_write(client, 0x35, 18);
++ reg8_write(client, 0x36, 17);
++ reg8_write(client, 0x37, 16);
++
++ break;
++ case RAW12_DT:
++ /* setup crossbar for RAW12: reverse DVP bus */
++ reg8_write(client, 0x20, 11);
++ reg8_write(client, 0x21, 10);
++ reg8_write(client, 0x22, 9);
++ reg8_write(client, 0x23, 8);
++ reg8_write(client, 0x24, 7);
++ reg8_write(client, 0x25, 6);
++ reg8_write(client, 0x26, 5);
++ reg8_write(client, 0x27, 4);
++ reg8_write(client, 0x28, 3);
++ reg8_write(client, 0x29, 2);
++ reg8_write(client, 0x2a, 1);
++ reg8_write(client, 0x2b, 0);
++
++ /* this is second byte if DBL=1 */
++ reg8_write(client, 0x30, 27);
++ reg8_write(client, 0x31, 26);
++ reg8_write(client, 0x32, 25);
++ reg8_write(client, 0x33, 24);
++ reg8_write(client, 0x34, 23);
++ reg8_write(client, 0x35, 22);
++ reg8_write(client, 0x36, 21);
++ reg8_write(client, 0x37, 20);
++ reg8_write(client, 0x38, 19);
++ reg8_write(client, 0x39, 18);
++ reg8_write(client, 0x3a, 17);
++ reg8_write(client, 0x3b, 16);
++
++ if (!priv->bws && priv->dbl)
++ dev_err(&client->dev, " BWS must be 27/32-bit for RAW12 in DBL mode\n");
++
++ break;
++ }
++
++ if (priv->hsgen) {
++ /* HS/VS pins map */
++ reg8_write(client, 0x3f, 0x10); /* HS (NC) */
++ reg8_write(client, 0x41, 0x10); /* DE (NC) */
++ if (priv->ser_id == MAX96705_ID)
++ reg8_write(client, 0x40, 15); /* VS (DIN13) */
++ if (priv->ser_id == MAX96707_ID)
++ reg8_write(client, 0x40, 13); /* VS (DIN13) */
++#if 0
++ /* following must come from imager */
++#define SENSOR_WIDTH (1280*2)
++#define HTS (1288*2)
++#define VTS 960
++#define HTS_DELAY 0x9
++ reg8_write(client, 0x4e, HTS_DELAY >> 16); /* HS delay */
++ reg8_write(client, 0x4f, (HTS_DELAY >> 8) & 0xff);
++ reg8_write(client, 0x50, HTS_DELAY & 0xff);
++ reg8_write(client, 0x54, SENSOR_WIDTH >> 8); /* HS high period */
++ reg8_write(client, 0x55, SENSOR_WIDTH & 0xff);
++ reg8_write(client, 0x56, (HTS - SENSOR_WIDTH) >> 8); /* HS low period */
++ reg8_write(client, 0x57, (HTS - SENSOR_WIDTH) & 0xff);
++ reg8_write(client, 0x58, VTS >> 8); /* HS count */
++ reg8_write(client, 0x59, VTS & 0xff );
++#endif
++ reg8_write(client, 0x43, 0x15); /* enable HS generator */
++ }
+ }
+
+ client->addr = priv->des_addr; /* MAX9286-CAMx I2C */
+@@ -344,6 +507,9 @@ static void max9286_gmsl_link_setup(struct i2c_client *client, int idx)
+ client->addr = priv->max9271_addr_map[idx]; /* MAX9271-CAMx I2C new */
+ maxim_max927x_dump_regs(client);
+ #endif
++ reg8_write(client, 0x07, 0x04 | (priv->pclk_rising_edge ? 0 : 0x10) |
++ (priv->dbl ? 0x80 : 0) |
++ (priv->bws ? 0x20 : 0)); /* RAW/YUV, PCLK edge, HS/VS encoding enabled, DBL mode, BWS 24/32-bit */
+ }
+
+ static int max9286_initialize(struct i2c_client *client)
+@@ -439,8 +605,8 @@ static int max9286_registered_async(struct v4l2_subdev *sd)
+ reg8_write(client, 0x0a, 0x11 << idx); /* enable reverse/forward control for CAMx */
+
+ client->addr = priv->max9271_addr_map[idx]; /* MAX9271-CAMx */
+- reg8_write(client, 0x04, conf_link ? 0x43 : 0x83); /* enable serial_link */
+- usleep_range(2000, 2500); /* wait 2ms after changing reverse_control */
++ max9286_write_remote_verify(client, idx, 0x04, conf_link ? 0x43 : 0x83);
++// usleep_range(2000, 2500); /* wait 2ms after changing reverse_control */
+
+ client->addr = priv->des_addr; /* MAX9286 I2C */
+ reg8_write(client, 0x0a, (priv->links_mask << 4) | priv->links_mask); /* enable reverse/forward control for all CAMs */
+@@ -491,7 +657,7 @@ static int max9286_parse_dt(struct i2c_client *client)
+
+ for (i = 0; i < 4; i++) {
+ sprintf(poc_name, "POC%d", i);
+- priv->poc_gpio[i] = devm_gpiod_get_optional(&client->dev, poc_name, 0);
++ priv->poc_gpio[i] = devm_gpiod_get_optional(&client->dev, kstrdup(poc_name, GFP_KERNEL), 0);
+ }
+
+ reg8_read(client, 0x1e, &val); /* read max9286 ID */
+@@ -536,6 +702,19 @@ static int max9286_parse_dt(struct i2c_client *client)
+ priv->vsync = 1;
+ if (of_property_read_u32(np, "maxim,poc-delay", &priv->poc_delay))
+ priv->poc_delay = 50;
++ if (of_property_read_u32(np, "maxim,bws", &priv->bws))
++ priv->bws = 0;
++ if (of_property_read_u32(np, "maxim,dbl", &priv->dbl))
++ priv->dbl = 1;
++ if (of_property_read_u32(np, "maxim,dt", &priv->dt))
++ priv->dt = 3;
++ if (of_property_read_u32(np, "maxim,hsgen", &priv->hsgen))
++ priv->hsgen = 0;
++ if (of_property_read_u32(np, "maxim,pclk", &priv->pclk))
++ priv->pclk = pclk;
++ if (of_property_read_u32(np, "maxim,switchin", &priv->switchin))
++ priv->switchin = 0;
++
+
+ /* module params override dts */
+ if (him)
+@@ -554,6 +733,18 @@ static int max9286_parse_dt(struct i2c_client *client)
+ priv->active_low_resetb = active_low_resetb;
+ if (poc_delay)
+ priv->poc_delay = poc_delay;
++ if (bws)
++ priv->bws = bws;
++ if (!dbl)
++ priv->dbl = dbl;
++ if (dt != 3)
++ priv->dt = dt;
++ if (hsgen)
++ priv->hsgen = hsgen;
++ if (pclk != 100)
++ priv->pclk = pclk;
++ if (switchin)
++ priv->switchin = switchin;
+
+ for (i = 0; i < priv->links; i++) {
+ endpoint = of_graph_get_next_endpoint(np, endpoint);
+@@ -592,8 +783,8 @@ static void max9286_setup_remote_endpoint(struct i2c_client *client)
+
+ csi_rate_prop = of_find_property(endpoint, "csi-rate", NULL);
+ if (csi_rate_prop) {
+- /* CSI2_RATE = PCLK*sizeof(YUV8)*links/lanes */
+- priv->csi_rate = cpu_to_be32(100 * 8 * hweight8(priv->links_mask) / priv->lanes);
++ /* CSI2_RATE = PCLK*bpp*links/lanes */
++ priv->csi_rate = cpu_to_be32(priv->pclk * dt2bpp[priv->dt] * hweight8(priv->links_mask) / priv->lanes);
+ csi_rate_prop->value = &priv->csi_rate;
+ of_update_property(rendpoint, csi_rate_prop);
+ }
+@@ -606,6 +797,86 @@ static void max9286_setup_remote_endpoint(struct i2c_client *client)
+ of_node_put(endpoint);
+ }
+
++static const char *line_status[] =
++{
++ "BAT",
++ "GND",
++ "NORMAL",
++ "OPEN"
++};
++
++static ssize_t max9286_link_show(struct device *dev,
++ struct device_attribute *attr, char *buf)
++{
++ int i = -1;
++ u8 val = 0;
++ bool lenghterr, linebuffof, hlocked, prbsok, vsyncdet, configdet, videodet;
++ int lf;
++ u8 prbserr = 0, deterr = 0, correrr = 0;
++ struct i2c_client *client = to_i2c_client(dev);
++ struct max9286_priv *priv = i2c_get_clientdata(client);
++
++ if (!sscanf(attr->attr.name, "link_%d", &i))
++ return -EINVAL;
++
++ if ((i < 0) || (i > 3))
++ return -EINVAL;
++
++ reg8_read(client, 0x20, &val);
++ lf = (val >> (2 * i)) & 0x03;
++
++ reg8_read(client, 0x21, &val);
++ hlocked = !!(val & (1 << i));
++ prbsok = !!(val & (1 << (i + 4)));
++
++ reg8_read(client, 0x22, &val);
++ lenghterr = !!(val & (1 << i));
++ linebuffof = !!(val & (1 << (i + 4)));
++
++ reg8_read(client, 0x23 + i, &prbserr);
++ priv->prbserr[i] += prbserr;
++
++ reg8_read(client, 0x27, &val);
++ vsyncdet = !!(val & (1 << i));
++
++ reg8_read(client, 0x28 + i, &deterr);
++ priv->deterr[i] += deterr;
++
++ reg8_read(client, 0x2c + i, &correrr);
++ priv->correrr[i] += correrr;
++
++ reg8_read(client, 0x49, &val);
++ configdet = !!(val & (1 << i));
++ videodet = !!(val & (1 << (i + 4)));
++
++ return sprintf(buf, "LINK:%d LF:%s HLOCKED:%d PRBSOK:%d LINBUFFOF:%d"
++ " LENGHTERR:%d VSYNCDET:%d CONFIGDET:%d VIDEODET:%d"
++ " PRBSERR:%d(%d) DETEERR:%d(%d) CORRERR:%d(%d)\n",
++ i, line_status[lf], hlocked, prbsok, lenghterr,
++ linebuffof, vsyncdet, configdet, videodet,
++ priv->prbserr[i], prbserr,
++ priv->deterr[i], deterr,
++ priv->correrr[i], correrr);
++ return 0;
++}
++
++static DEVICE_ATTR(link_0, S_IRUGO, max9286_link_show, NULL);
++static DEVICE_ATTR(link_1, S_IRUGO, max9286_link_show, NULL);
++static DEVICE_ATTR(link_2, S_IRUGO, max9286_link_show, NULL);
++static DEVICE_ATTR(link_3, S_IRUGO, max9286_link_show, NULL);
++
++static struct attribute *max9286_attributes_links[] = {
++ &dev_attr_link_0.attr,
++ &dev_attr_link_1.attr,
++ &dev_attr_link_2.attr,
++ &dev_attr_link_3.attr,
++ NULL
++};
++
++static const struct attribute_group max9286_group = {
++ .attrs = max9286_attributes_links,
++};
++
+ static int max9286_probe(struct i2c_client *client,
+ const struct i2c_device_id *did)
+ {
+@@ -648,6 +919,11 @@ static int max9286_probe(struct i2c_client *client,
+ if (err < 0)
+ goto out;
+ }
++
++ err = sysfs_create_group(&client->dev.kobj,
++ &max9286_group);
++ if (err < 0)
++ dev_err(&client->dev, "Sysfs registration failed\n");
+ out:
+ return err;
+ }
+@@ -657,6 +933,8 @@ static int max9286_remove(struct i2c_client *client)
+ struct max9286_priv *priv = i2c_get_clientdata(client);
+ int i;
+
++ sysfs_remove_group(&client->dev.kobj, &max9286_group);
++
+ for (i = 0; i < 4; i++) {
+ v4l2_async_unregister_subdev(&priv->sd[i]);
+ v4l2_device_unregister_subdev(&priv->sd[i]);
+diff --git a/drivers/media/i2c/soc_camera/max9286.h b/drivers/media/i2c/soc_camera/max9286.h
+index 6c2a9e0..2875b3c 100644
+--- a/drivers/media/i2c/soc_camera/max9286.h
++++ b/drivers/media/i2c/soc_camera/max9286.h
+@@ -24,6 +24,7 @@
+ #define REG16_NUM_RETRIES 10 /* number of read/write retries */
+ #define MAX9271_ID 0x9
+ #define MAX96705_ID 0x41
++#define MAX96707_ID 0x45 /* MAX96715: there is no HS pin */
+ #define MAX9286_ID 0x40
+ #define BROADCAST 0x6f
+
+diff --git a/drivers/media/i2c/soc_camera/ov10635.c b/drivers/media/i2c/soc_camera/ov10635.c
+index 8289b76..916173c 100644
+--- a/drivers/media/i2c/soc_camera/ov10635.c
++++ b/drivers/media/i2c/soc_camera/ov10635.c
+@@ -19,7 +19,6 @@
+ #include <media/soc_camera.h>
+ #include <media/v4l2-common.h>
+ #include <media/v4l2-ctrls.h>
+-#include <media/v4l2-fwnode.h>
+
+ #include "max9286.h"
+ #include "ov10635.h"
+@@ -44,8 +43,7 @@ struct ov10635_priv {
+ /* serializers */
+ int max9286_addr;
+ int max9271_addr;
+- int ti964_addr;
+- int ti954_addr;
++ int ti9x4_addr;
+ int ti9x3_addr;
+ int port;
+ int gpio_resetb;
+@@ -429,13 +427,11 @@ static int ov10635_s_ctrl(struct v4l2_ctrl *ctrl)
+ break;
+ case V4L2_CID_HFLIP:
+ ret = reg16_read(client, 0x381d, &val);
+- if (ret < 0)
+- goto out;
+ if (ctrl->val)
+ val |= 0x3;
+ else
+ val &= ~0x3;
+- ret = reg16_write(client, 0x381d, val);
++ ret |= reg16_write(client, 0x381d, val);
+ break;
+ case V4L2_CID_VFLIP:
+ ret = reg16_read(client, 0x381c, &val);
+@@ -443,14 +439,13 @@ static int ov10635_s_ctrl(struct v4l2_ctrl *ctrl)
+ val |= 0xc0;
+ else
+ val &= ~0xc0;
+- ret = reg16_write(client, 0x381c, val);
++ ret |= reg16_write(client, 0x381c, val);
+ break;
+ case V4L2_CID_MIN_BUFFERS_FOR_CAPTURE:
+ ret = 0;
+ break;
+ }
+
+-out:
+ return ret;
+ }
+
+@@ -567,21 +562,15 @@ static int ov10635_parse_dt(struct device_node *np, struct ov10635_priv *priv)
+ break;
+
+ if (!of_property_read_u32(rendpoint, "ti9x3-addr", &priv->ti9x3_addr) &&
+- !of_property_match_string(rendpoint->parent->parent, "compatible", "ti,ti964-ti9x3") &&
+- !of_property_read_u32(rendpoint->parent->parent, "reg", &priv->ti964_addr) &&
+- !kstrtouint(strrchr(rendpoint->full_name, '@') + 1, 0, &priv->port))
+- break;
+-
+- if (!of_property_read_u32(rendpoint, "ti9x3-addr", &priv->ti9x3_addr) &&
+- !of_property_match_string(rendpoint->parent->parent, "compatible", "ti,ti954-ti9x3") &&
+- !of_property_read_u32(rendpoint->parent->parent, "reg", &priv->ti954_addr) &&
++ !of_property_match_string(rendpoint->parent->parent, "compatible", "ti,ti9x4") &&
++ !of_property_read_u32(rendpoint->parent->parent, "reg", &priv->ti9x4_addr) &&
+ !kstrtouint(strrchr(rendpoint->full_name, '@') + 1, 0, &priv->port))
+ break;
+ }
+
+ of_node_put(endpoint);
+
+- if (!priv->max9286_addr && !priv->ti964_addr && !priv->ti954_addr) {
++ if (!priv->max9286_addr && !priv->ti9x4_addr) {
+ dev_err(&client->dev, "deserializer does not present for OV10635\n");
+ return -EINVAL;
+ }
+@@ -598,19 +587,8 @@ static int ov10635_parse_dt(struct device_node *np, struct ov10635_priv *priv)
+ usleep_range(2000, 2500); /* wait 2ms */
+ };
+
+- if (priv->ti964_addr) {
+- client->addr = priv->ti964_addr; /* Deserializer I2C address */
+-
+- reg8_write(client, 0x4c, (priv->port << 4) | (1 << priv->port)); /* Select RX port number */
+- usleep_range(2000, 2500); /* wait 2ms */
+- reg8_write(client, 0x65, tmp_addr << 1); /* Sensor translated I2C address */
+- reg8_write(client, 0x5d, OV10635_I2C_ADDR << 1); /* Sensor native I2C address */
+-
+- reg8_write(client, 0x6e, 0xa9); /* GPIO0 - resetb, GPIO1 - fsin */
+- }
+-
+- if (priv->ti954_addr) {
+- client->addr = priv->ti954_addr; /* Deserializer I2C address */
++ if (priv->ti9x4_addr) {
++ client->addr = priv->ti9x4_addr; /* Deserializer I2C address */
+
+ reg8_write(client, 0x4c, (priv->port << 4) | (1 << priv->port)); /* Select RX port number */
+ usleep_range(2000, 2500); /* wait 2ms */
+diff --git a/drivers/media/i2c/soc_camera/ov10635.h b/drivers/media/i2c/soc_camera/ov10635.h
+index a0e510d..a74f360 100644
+--- a/drivers/media/i2c/soc_camera/ov10635.h
++++ b/drivers/media/i2c/soc_camera/ov10635.h
+@@ -17,13 +17,13 @@
+ #define OV10635_MAX_WIDTH 1280
+ #define OV10635_MAX_HEIGHT 800
+
+-//#define OV10635_PCLK_96MHZ
+-#define OV10635_PCLK_88MHZ
++#define OV10635_PCLK_96MHZ
++//#define OV10635_PCLK_88MHZ
+
+ #if defined(OV10635_PCLK_96MHZ)
+-/* VTS=PCLK/FPS/HTS/2 (=96MHz/30/1600/2) */
+- #define OV10635_HTS 1600
+- #define OV10635_VTS 1000 /* fps=30 */
++/* VTS=PCLK/FPS/HTS/2 (=96MHz/30/1750/2) */
++ #define OV10635_HTS 1750
++ #define OV10635_VTS 914 /* fps=30 */
+ #elif defined(OV10635_PCLK_88MHZ)
+ /* VTS=PCLK/FPS/HTS/2 (=88MHz/1572/30/2) */
+ #define OV10635_HTS 1572
+diff --git a/drivers/media/i2c/soc_camera/ov106xx.c b/drivers/media/i2c/soc_camera/ov106xx.c
+index fa775ae..c7bd92e 100644
+--- a/drivers/media/i2c/soc_camera/ov106xx.c
++++ b/drivers/media/i2c/soc_camera/ov106xx.c
+@@ -13,18 +13,32 @@
+ #include "ov490_ov10640.c"
+ #include "ov495_ov2775.c"
+ #include "ar0132.c"
++#include "ar0140.c"
++#include "ar0143.c"
+ #include "ar0220.c"
++#include "ar0231.c"
++#include "ar0233.c"
+ #include "ap0101_ar014x.c"
++#include "gw4200_ar014x.c"
+ #include "ov2775.c"
++#include "imx390.c"
++#include "ox03a.c"
+
+ static enum {
+ ID_OV10635,
+ ID_OV490_OV10640,
+ ID_OV495_OV2775,
+ ID_AR0132,
++ ID_AR0140,
++ ID_AR0143,
+ ID_AR0220,
++ ID_AR0231,
++ ID_AR0233,
+ ID_AP0101_AR014X,
++ ID_GW4200_AR014X,
+ ID_OV2775,
++ ID_IMX390,
++ ID_OX03A,
+ } chip_id;
+
+ static int ov106xx_probe(struct i2c_client *client,
+@@ -57,24 +71,66 @@ static int ov106xx_probe(struct i2c_client *client,
+ goto out;
+ }
+
++ ret = ar0140_probe(client, did);
++ if (!ret) {
++ chip_id = ID_AR0140;
++ goto out;
++ }
++
++ ret = ar0143_probe(client, did);
++ if (!ret) {
++ chip_id = ID_AR0143;
++ goto out;
++ }
++
+ ret = ar0220_probe(client, did);
+ if (!ret) {
+ chip_id = ID_AR0220;
+ goto out;
+ }
+
++ ret = ar0233_probe(client, did);
++ if (!ret) {
++ chip_id = ID_AR0233;
++ goto out;
++ }
++
++ ret = ar0231_probe(client, did);
++ if (!ret) {
++ chip_id = ID_AR0231;
++ goto out;
++ }
++
+ ret = ap0101_probe(client, did);
+ if (!ret) {
+ chip_id = ID_AP0101_AR014X;
+ goto out;
+ }
+
++ ret = gw4200_probe(client, did);
++ if (!ret) {
++ chip_id = ID_GW4200_AR014X;
++ goto out;
++ }
++
+ ret = ov2775_probe(client, did);
+ if (!ret) {
+ chip_id = ID_OV2775;
+ goto out;
+ }
+
++ ret = imx390_probe(client, did);
++ if (!ret) {
++ chip_id = ID_IMX390;
++ goto out;
++ }
++
++ ret = ox03a_probe(client, did);
++ if (!ret) {
++ chip_id = ID_OX03A;
++ goto out;
++ }
++
+ v4l_err(client, "failed to probe @ 0x%02x (%s)\n",
+ client->addr, client->adapter->name);
+ out:
+@@ -96,15 +152,36 @@ static int ov106xx_remove(struct i2c_client *client)
+ case ID_AR0132:
+ ar0132_remove(client);
+ break;
++ case ID_AR0140:
++ ar0140_remove(client);
++ break;
++ case ID_AR0143:
++ ar0143_remove(client);
++ break;
+ case ID_AR0220:
+ ar0220_remove(client);
+ break;
++ case ID_AR0231:
++ ar0231_remove(client);
++ break;
++ case ID_AR0233:
++ ar0233_remove(client);
++ break;
+ case ID_AP0101_AR014X:
+ ap0101_remove(client);
+ break;
++ case ID_GW4200_AR014X:
++ gw4200_remove(client);
++ break;
+ case ID_OV2775:
+ ov2775_remove(client);
+ break;
++ case ID_IMX390:
++ imx390_remove(client);
++ break;
++ case ID_OX03A:
++ ox03a_remove(client);
++ break;
+ };
+
+ return 0;
+@@ -134,6 +211,6 @@ static struct i2c_driver ov106xx_i2c_driver = {
+
+ module_i2c_driver(ov106xx_i2c_driver);
+
+-MODULE_DESCRIPTION("SoC Camera driver for OV10635, OV490/OV10640, OV495/OV2775, AR0132, AR0220, AP0101/AR014X");
++MODULE_DESCRIPTION("SoC Camera driver for OV10635, OV490+OV10640, OV495+OV2775, AR0132/140/143/220/223, AP0101+AR014X");
+ MODULE_AUTHOR("Vladimir Barinov");
+ MODULE_LICENSE("GPL");
+diff --git a/drivers/media/i2c/soc_camera/ov2775.c b/drivers/media/i2c/soc_camera/ov2775.c
+index cb41764..2022d47 100644
+--- a/drivers/media/i2c/soc_camera/ov2775.c
++++ b/drivers/media/i2c/soc_camera/ov2775.c
+@@ -19,7 +19,6 @@
+ #include <media/soc_camera.h>
+ #include <media/v4l2-common.h>
+ #include <media/v4l2-ctrls.h>
+-#include <media/v4l2-fwnode.h>
+
+ #include "ov2775.h"
+
+@@ -29,7 +28,7 @@
+ #define OV2775_VER 0x300b
+ #define OV2775_VERSION_REG 0x2770
+
+-#define OV2775_MEDIA_BUS_FMT MEDIA_BUS_FMT_SBGGR8_1X8
++#define OV2775_MEDIA_BUS_FMT MEDIA_BUS_FMT_SBGGR12_1X12
+
+ struct ov2775_priv {
+ struct v4l2_subdev sd;
+@@ -319,6 +318,7 @@ static int ov2775_initialize(struct i2c_client *client)
+ u8 val = 0;
+ u16 pid;
+ int ret = 0;
++ int tmp_addr;
+
+ /* check and show model ID */
+ reg16_read(client, OV2775_PID, &val);
+@@ -332,6 +332,16 @@ static int ov2775_initialize(struct i2c_client *client)
+ goto err;
+ }
+
++ /* setup XCLK */
++ tmp_addr = client->addr;
++ if (priv->ti9x4_addr) {
++ /* CLK_OUT=22.5792*160*M/N/CLKDIV -> CLK_OUT=25MHz: CLKDIV=4, M=7, N=253: 22.5792*160/4*7/253=24.989MHz=CLK_OUT */
++ client->addr = priv->ti9x3_addr; /* Serializer I2C address */
++ reg8_write(client, 0x06, 0x47); /* Set CLKDIV and M */
++ reg8_write(client, 0x07, 0xfd); /* Set N */
++ }
++ client->addr = tmp_addr;
++
+ /* Program wizard registers */
+ ov2775_set_regs(client, ov2775_regs_wizard, ARRAY_SIZE(ov2775_regs_wizard));
+ /* Read OTP IDs */
+diff --git a/drivers/media/i2c/soc_camera/ov2775.h b/drivers/media/i2c/soc_camera/ov2775.h
+index 1cdfb50..7e1ee31 100644
+--- a/drivers/media/i2c/soc_camera/ov2775.h
++++ b/drivers/media/i2c/soc_camera/ov2775.h
+@@ -1,5 +1,5 @@
+ /*
+- * OmniVision OV2775 sensor camera wizard 1928x1088@30/RGGB/MIPI
++ * OmniVision OV2775 sensor camera wizard 1920x1080@30/BGGR/MIPI
+ *
+ * Copyright (C) 2018 Cogent Embedded, Inc.
+ *
+@@ -9,29 +9,29 @@
+ * option) any later version.
+ */
+
+-//#define OV2775_DISPLAY_PATTERN_COLOR_BAR
++#define OV2775_DISPLAY_PATTERN_COLOR_BAR
+
+-#define OV2775_MAX_WIDTH 2880 // (1928*1.5=2892) <- must be multiple of 16 - requred by R-CAR VIN
+-#define OV2775_MAX_HEIGHT 1088
++#define OV2775_MAX_WIDTH 1920
++#define OV2775_MAX_HEIGHT 1080
+
+ #define OV2775_DELAY 0xffff
+-#define OV2775_DT 0x2c // MIPI Data Type
++#define OV2775_DT 0x2c /* MIPI Data Type RAW12 */
+
+ struct ov2775_reg {
+ u16 reg;
+ u8 val;
+ };
+
+-/* wizard: MIPI 1928x1088 RAW12 Linear 30fps 960Mbps */
++/* wizard: MIPI 1920x1080 RAW12 Linear 30fps 600Mbps XCLK=25MHz */
+ static const struct ov2775_reg ov2775_regs_wizard[] = {
+ {0x3013, 0x01}, // s/w reset
+ {OV2775_DELAY, 10}, // Wait 10ms
+-{0x3000, 0x02},
+-{0x3001, 0x28},
+-{0x3002, 0x03},
++{0x3000, 0x03},
++{0x3001, 0x18},
++{0x3002, 0x01},
+ {0x3003, 0x01},
+-{0x3004, 0x02},
+-{0x3005, 0x26},
++{0x3004, 0x03},
++{0x3005, 0x1c},
+ {0x3006, 0x00},
+ {0x3007, 0x07},
+ {0x3008, 0x01},
+@@ -41,7 +41,7 @@ static const struct ov2775_reg ov2775_regs_wizard[] = {
+ {0x300f, 0x00},
+ {0x3012, 0x00},
+ {0x3013, 0x00},
+-{0x3014, 0xc4},
++{0x3014, 0x44},
+ {0x3015, 0x00},
+ {0x3017, 0x00},
+ {0x3018, 0x00},
+@@ -328,7 +328,7 @@ static const struct ov2775_reg ov2775_regs_wizard[] = {
+ {0x320d, 0x1e},
+ {0x320e, 0x30},
+ {0x320f, 0x2d},
+-{0x3210, OV2775_DT},
++{0x3210, 0x2c},
+ {0x3211, 0x2b},
+ {0x3212, 0x2a},
+ {0x3213, 0x24},
+@@ -358,7 +358,7 @@ static const struct ov2775_reg ov2775_regs_wizard[] = {
+ {0x3251, 0x00},
+ {0x3252, 0x20},
+ #ifdef OV2775_DISPLAY_PATTERN_COLOR_BAR
+-{0x3253, 0x80},
++{0x3253, 0xC0},
+ #else
+ {0x3253, 0x00},
+ #endif
+@@ -1822,9 +1822,9 @@ static const struct ov2775_reg ov2775_regs_wizard[] = {
+ {0x30a9, 0x04},
+ {0x30aa, 0x00},
+ {0x30ab, 0x04},
+-{0x30ac, 0x07},
++{0x30ac, 0x07}, /* OV2775_MAX_WIDTH */
+ {0x30ad, 0x88},
+-{0x30ae, 0x04},
++{0x30ae, 0x04}, /* OV2775_MAX_HEIGHT */
+ {0x30af, 0x40},
+ {0x30b0, 0x0d},
+ {0x30b1, 0xde},
+diff --git a/drivers/media/i2c/soc_camera/ov490_ov10640.c b/drivers/media/i2c/soc_camera/ov490_ov10640.c
+index 4b51a92..1c8aac8 100644
+--- a/drivers/media/i2c/soc_camera/ov490_ov10640.c
++++ b/drivers/media/i2c/soc_camera/ov490_ov10640.c
+@@ -19,7 +19,6 @@
+ #include <media/soc_camera.h>
+ #include <media/v4l2-common.h>
+ #include <media/v4l2-ctrls.h>
+-#include <media/v4l2-fwnode.h>
+
+ #include "max9286.h"
+ #include "ov490_ov10640.h"
+diff --git a/drivers/media/i2c/soc_camera/ov495_ov2775.c b/drivers/media/i2c/soc_camera/ov495_ov2775.c
+index 32b5078..34b2f46 100644
+--- a/drivers/media/i2c/soc_camera/ov495_ov2775.c
++++ b/drivers/media/i2c/soc_camera/ov495_ov2775.c
+@@ -19,7 +19,6 @@
+ #include <media/soc_camera.h>
+ #include <media/v4l2-common.h>
+ #include <media/v4l2-ctrls.h>
+-#include <media/v4l2-fwnode.h>
+
+ #include "ov495_ov2775.h"
+
+@@ -403,6 +402,7 @@ static int ov495_initialize(struct i2c_client *client)
+ struct ov495_priv *priv = to_ov495(client);
+ u8 pid = 0, ver = 0;
+ int ret = 0;
++// int tmp_addr;
+
+ /* check and show product ID and manufacturer ID */
+ reg16_write(client, 0xFFFD, 0x80);
+@@ -417,6 +417,18 @@ static int ov495_initialize(struct i2c_client *client)
+ goto err;
+ }
+
++#if 0
++ /* setup XCLK */
++ tmp_addr = client->addr;
++ if (priv->ti9x4_addr) {
++ /* CLK_OUT=22.5792*160*M/N/CLKDIV -> CLK_OUT=25MHz: CLKDIV=4, M=7, N=253: 22.5792*160/4*7/253=24.989MHz=CLK_OUT */
++ client->addr = priv->ti9x3_addr; /* Serializer I2C address */
++ reg8_write(client, 0x06, 0x47); /* Set CLKDIV and M */
++ reg8_write(client, 0x07, 0xfd); /* Set N */
++ }
++ client->addr = tmp_addr;
++#endif
++
+ if (unlikely(force_conf_link))
+ goto out;
+
+@@ -439,7 +451,7 @@ static int ov495_initialize(struct i2c_client *client)
+ #endif
+
+ /* set virtual channel */
+- ov495_regs_wizard[3].val = 0x1e | (priv->port << 6);
++// ov495_regs_wizard[3].val = 0x1e | (priv->port << 6);
+ /* Program wizard registers */
+ ov495_set_regs(client, ov495_regs_wizard, ARRAY_SIZE(ov495_regs_wizard));
+ /* Read OTP IDs */
+diff --git a/drivers/media/i2c/soc_camera/ox03a.c b/drivers/media/i2c/soc_camera/ox03a.c
+new file mode 100644
+index 0000000..162c75b
+--- /dev/null
++++ b/drivers/media/i2c/soc_camera/ox03a.c
+@@ -0,0 +1,589 @@
++/*
++ * OmniVision OX03A sensor camera driver
++ *
++ * Copyright (C) 2018 Cogent Embedded, Inc.
++ *
++ * This program is free software; you can redistribute it and/or modify it
++ * under the terms of the GNU General Public License as published by the
++ * Free Software Foundation; either version 2 of the License, or (at your
++ * option) any later version.
++ */
++
++#include <linux/delay.h>
++#include <linux/init.h>
++#include <linux/i2c.h>
++#include <linux/module.h>
++#include <linux/of_graph.h>
++#include <linux/videodev2.h>
++
++#include <media/soc_camera.h>
++#include <media/v4l2-common.h>
++#include <media/v4l2-ctrls.h>
++
++#include "ox03a.h"
++
++#define OX03A_I2C_ADDR 0x36
++
++#define OX03A_PID 0x300A
++#define OX03A_VER 0x300B
++#define OX03A_VERSION_REG 0x5803
++
++#define OX03A_MEDIA_BUS_FMT MEDIA_BUS_FMT_SBGGR16_1X16
++
++struct ox03a_priv {
++ struct v4l2_subdev sd;
++ struct v4l2_ctrl_handler hdl;
++ struct media_pad pad;
++ struct v4l2_rect rect;
++ int init_complete;
++ u8 id[6];
++ int exposure;
++ int gain;
++ int autogain;
++ /* serializers */
++ int ti9x4_addr;
++ int ti9x3_addr;
++ int port;
++ int gpio_resetb;
++ int gpio_fsin;
++};
++
++static inline struct ox03a_priv *to_ox03a(const struct i2c_client *client)
++{
++ return container_of(i2c_get_clientdata(client), struct ox03a_priv, sd);
++}
++
++static int ox03a_set_regs(struct i2c_client *client,
++ const struct ox03a_reg *regs, int nr_regs)
++{
++ int i;
++
++ for (i = 0; i < nr_regs; i++) {
++ if (regs[i].reg == OX03A_DELAY) {
++ mdelay(regs[i].val);
++ continue;
++ }
++
++ reg16_write(client, regs[i].reg, regs[i].val);
++ }
++
++ return 0;
++}
++
++static int ox03a_s_stream(struct v4l2_subdev *sd, int enable)
++{
++ return 0;
++}
++
++static int ox03a_get_fmt(struct v4l2_subdev *sd,
++ struct v4l2_subdev_pad_config *cfg,
++ struct v4l2_subdev_format *format)
++{
++ struct v4l2_mbus_framefmt *mf = &format->format;
++ struct i2c_client *client = v4l2_get_subdevdata(sd);
++ struct ox03a_priv *priv = to_ox03a(client);
++
++ if (format->pad)
++ return -EINVAL;
++
++ mf->width = priv->rect.width;
++ mf->height = priv->rect.height;
++ mf->code = OX03A_MEDIA_BUS_FMT;
++ mf->colorspace = V4L2_COLORSPACE_SMPTE170M;
++ mf->field = V4L2_FIELD_NONE;
++
++ return 0;
++}
++
++static int ox03a_set_fmt(struct v4l2_subdev *sd,
++ struct v4l2_subdev_pad_config *cfg,
++ struct v4l2_subdev_format *format)
++{
++ struct v4l2_mbus_framefmt *mf = &format->format;
++
++ mf->code = OX03A_MEDIA_BUS_FMT;
++ mf->colorspace = V4L2_COLORSPACE_SMPTE170M;
++ mf->field = V4L2_FIELD_NONE;
++
++ if (format->which == V4L2_SUBDEV_FORMAT_TRY)
++ cfg->try_fmt = *mf;
++
++ return 0;
++}
++
++static int ox03a_enum_mbus_code(struct v4l2_subdev *sd,
++ struct v4l2_subdev_pad_config *cfg,
++ struct v4l2_subdev_mbus_code_enum *code)
++{
++ if (code->pad || code->index > 0)
++ return -EINVAL;
++
++ code->code = OX03A_MEDIA_BUS_FMT;
++
++ return 0;
++}
++
++static int ox03a_get_edid(struct v4l2_subdev *sd, struct v4l2_edid *edid)
++{
++ struct i2c_client *client = v4l2_get_subdevdata(sd);
++ struct ox03a_priv *priv = to_ox03a(client);
++
++ memcpy(edid->edid, priv->id, 6);
++
++ edid->edid[6] = 0xff;
++ edid->edid[7] = client->addr;
++ edid->edid[8] = OX03A_VERSION_REG >> 8;
++ edid->edid[9] = OX03A_VERSION_REG & 0xff;
++
++ return 0;
++}
++
++static int ox03a_set_selection(struct v4l2_subdev *sd,
++ struct v4l2_subdev_pad_config *cfg,
++ struct v4l2_subdev_selection *sel)
++{
++ struct v4l2_rect *rect = &sel->r;
++ struct i2c_client *client = v4l2_get_subdevdata(sd);
++ struct ox03a_priv *priv = to_ox03a(client);
++
++ if (sel->which != V4L2_SUBDEV_FORMAT_ACTIVE ||
++ sel->target != V4L2_SEL_TGT_CROP)
++ return -EINVAL;
++
++ rect->left = ALIGN(rect->left, 2);
++ rect->top = ALIGN(rect->top, 2);
++ rect->width = ALIGN(rect->width, 2);
++ rect->height = ALIGN(rect->height, 2);
++
++ if ((rect->left + rect->width > OX03A_MAX_WIDTH) ||
++ (rect->top + rect->height > OX03A_MAX_HEIGHT))
++ *rect = priv->rect;
++
++ priv->rect.left = rect->left;
++ priv->rect.top = rect->top;
++ priv->rect.width = rect->width;
++ priv->rect.height = rect->height;
++
++ return 0;
++}
++
++static int ox03a_get_selection(struct v4l2_subdev *sd,
++ struct v4l2_subdev_pad_config *cfg,
++ struct v4l2_subdev_selection *sel)
++{
++ struct i2c_client *client = v4l2_get_subdevdata(sd);
++ struct ox03a_priv *priv = to_ox03a(client);
++
++ if (sel->which != V4L2_SUBDEV_FORMAT_ACTIVE)
++ return -EINVAL;
++
++ switch (sel->target) {
++ case V4L2_SEL_TGT_CROP_BOUNDS:
++ sel->r.left = 0;
++ sel->r.top = 0;
++ sel->r.width = OX03A_MAX_WIDTH;
++ sel->r.height = OX03A_MAX_HEIGHT;
++ return 0;
++ case V4L2_SEL_TGT_CROP_DEFAULT:
++ sel->r.left = 0;
++ sel->r.top = 0;
++ sel->r.width = OX03A_MAX_WIDTH;
++ sel->r.height = OX03A_MAX_HEIGHT;
++ return 0;
++ case V4L2_SEL_TGT_CROP:
++ sel->r = priv->rect;
++ return 0;
++ default:
++ return -EINVAL;
++ }
++}
++
++static int ox03a_g_mbus_config(struct v4l2_subdev *sd,
++ struct v4l2_mbus_config *cfg)
++{
++ cfg->flags = V4L2_MBUS_CSI2_1_LANE | V4L2_MBUS_CSI2_CHANNEL_0 |
++ V4L2_MBUS_CSI2_CONTINUOUS_CLOCK;
++ cfg->type = V4L2_MBUS_CSI2;
++
++ return 0;
++}
++
++#ifdef CONFIG_VIDEO_ADV_DEBUG
++static int ox03a_g_register(struct v4l2_subdev *sd,
++ struct v4l2_dbg_register *reg)
++{
++ struct i2c_client *client = v4l2_get_subdevdata(sd);
++ int ret;
++ u8 val = 0;
++
++ ret = reg16_read(client, (u16)reg->reg, &val);
++ if (ret < 0)
++ return ret;
++
++ reg->val = val;
++ reg->size = sizeof(u8);
++
++ return 0;
++}
++
++static int ox03a_s_register(struct v4l2_subdev *sd,
++ const struct v4l2_dbg_register *reg)
++{
++ struct i2c_client *client = v4l2_get_subdevdata(sd);
++
++ return reg16_write(client, (u16)reg->reg, (u8)reg->val);
++}
++#endif
++
++static struct v4l2_subdev_core_ops ox03a_core_ops = {
++#ifdef CONFIG_VIDEO_ADV_DEBUG
++ .g_register = ox03a_g_register,
++ .s_register = ox03a_s_register,
++#endif
++};
++
++static int ox03a_s_ctrl(struct v4l2_ctrl *ctrl)
++{
++ struct v4l2_subdev *sd = to_sd(ctrl);
++ struct i2c_client *client = v4l2_get_subdevdata(sd);
++ struct ox03a_priv *priv = to_ox03a(client);
++ int ret = -EINVAL;
++ u8 val = 0;
++
++ if (!priv->init_complete)
++ return 0;
++
++ switch (ctrl->id) {
++ case V4L2_CID_BRIGHTNESS:
++ case V4L2_CID_CONTRAST:
++ case V4L2_CID_SATURATION:
++ case V4L2_CID_HUE:
++ case V4L2_CID_GAMMA:
++ case V4L2_CID_SHARPNESS:
++ case V4L2_CID_AUTOGAIN:
++ break;
++ case V4L2_CID_GAIN:
++ /* start recording group3 */
++ ret = reg16_write(client, 0x3208, 0x03);
++ /* HCG real gain */
++ ret |= reg16_write(client, 0x3508, ctrl->val >> 8);
++ ret |= reg16_write(client, 0x3509, ctrl->val & 0xff);
++ /* HCG digital gain */
++ ret |= reg16_write(client, 0x350a, ctrl->val >> 8);
++ ret |= reg16_write(client, 0x350b, ctrl->val & 0xff);
++ /* LCG real gain */
++ ret |= reg16_write(client, 0x3548, ctrl->val >> 8);
++ ret |= reg16_write(client, 0x3549, ctrl->val & 0xff);
++ /* LCG digital gain */
++ ret |= reg16_write(client, 0x354a, ctrl->val >> 8);
++ ret |= reg16_write(client, 0x354b, ctrl->val & 0xff);
++ /* VS real gain */
++ ret |= reg16_write(client, 0x3588, ctrl->val >> 8);
++ ret |= reg16_write(client, 0x3589, ctrl->val & 0xff);
++ /* VS digital gain */
++ ret |= reg16_write(client, 0x358a, ctrl->val >> 8);
++ ret |= reg16_write(client, 0x358b, ctrl->val & 0xff);
++ /* stop recording and launch group3 */
++ ret |= reg16_write(client, 0x3208, 0x13);
++ ret |= reg16_write(client, 0x3208, 0xe3);
++ break;
++ case V4L2_CID_EXPOSURE:
++ /* start recording group3 */
++ ret = reg16_write(client, 0x3208, 0x03);
++ /* HCG (long) exposure time */
++ ret |= reg16_write(client, 0x3501, ctrl->val >> 8);
++ ret |= reg16_write(client, 0x3502, ctrl->val & 0xff);
++ /* VS exposure time */
++// ret |= reg16_write(client, 0x3581, ctrl->val >> 8);
++// ret |= reg16_write(client, 0x3582, ctrl->val & 0xff);
++ /* stop recording and launch group3 */
++ ret |= reg16_write(client, 0x3208, 0x13);
++ ret |= reg16_write(client, 0x3208, 0xe3);
++ break;
++ case V4L2_CID_HFLIP:
++ /* start recording group3 */
++ ret = reg16_write(client, 0x3208, 0x03);
++ ret = reg16_read(client, 0x3821, &val);
++ if (ctrl->val)
++ val |= 0x04;
++ else
++ val &= ~0x04;
++ ret |= reg16_write(client, 0x3821, val);
++ /* hflip channges CFA, hence compensate it by moving crop window over bayer matrix */
++ ret |= reg16_read(client, 0x3811, &val);
++ if (ctrl->val)
++ val++;
++ else
++ val--;
++ ret |= reg16_write(client, 0x3811, val);
++ /* stop recording and launch group3 */
++ ret |= reg16_write(client, 0x3208, 0x13);
++ ret |= reg16_write(client, 0x3208, 0xe3);
++ break;
++ case V4L2_CID_VFLIP:
++ ret = reg16_read(client, 0x3820, &val);
++ if (ctrl->val)
++ val |= 0x44;
++ else
++ val &= ~0x44;
++ ret |= reg16_write(client, 0x3820, val);
++ break;
++ }
++
++ return ret;
++}
++
++static const struct v4l2_ctrl_ops ox03a_ctrl_ops = {
++ .s_ctrl = ox03a_s_ctrl,
++};
++
++static struct v4l2_subdev_video_ops ox03a_video_ops = {
++ .s_stream = ox03a_s_stream,
++ .g_mbus_config = ox03a_g_mbus_config,
++};
++
++static const struct v4l2_subdev_pad_ops ox03a_subdev_pad_ops = {
++ .get_edid = ox03a_get_edid,
++ .enum_mbus_code = ox03a_enum_mbus_code,
++ .get_selection = ox03a_get_selection,
++ .set_selection = ox03a_set_selection,
++ .get_fmt = ox03a_get_fmt,
++ .set_fmt = ox03a_set_fmt,
++};
++
++static struct v4l2_subdev_ops ox03a_subdev_ops = {
++ .core = &ox03a_core_ops,
++ .video = &ox03a_video_ops,
++ .pad = &ox03a_subdev_pad_ops,
++};
++
++static void ox03a_otp_id_read(struct i2c_client *client)
++{
++}
++
++static ssize_t ox03a_otp_id_show(struct device *dev,
++ struct device_attribute *attr, char *buf)
++{
++ struct v4l2_subdev *sd = i2c_get_clientdata(to_i2c_client(dev));
++ struct i2c_client *client = v4l2_get_subdevdata(sd);
++ struct ox03a_priv *priv = to_ox03a(client);
++
++ return snprintf(buf, 32, "%02x:%02x:%02x:%02x:%02x:%02x\n",
++ priv->id[0], priv->id[1], priv->id[2], priv->id[3], priv->id[4], priv->id[5]);
++}
++
++static DEVICE_ATTR(otp_id_ox03a, S_IRUGO, ox03a_otp_id_show, NULL);
++
++static int ox03a_initialize(struct i2c_client *client)
++{
++ struct ox03a_priv *priv = to_ox03a(client);
++ u8 val = 0;
++ u16 pid;
++ int ret = 0;
++
++ /* check and show model ID */
++ reg16_read(client, OX03A_PID, &val);
++ pid = val;
++ reg16_read(client, OX03A_VER, &val);
++ pid = (pid << 8) | val;
++
++ if (pid != OX03A_VERSION_REG) {
++ dev_dbg(&client->dev, "Product ID error %x\n", pid);
++ ret = -ENODEV;
++ goto err;
++ }
++
++ /* Program wizard registers */
++ ox03a_set_regs(client, ox03a_regs_wizard_r1a, ARRAY_SIZE(ox03a_regs_wizard_r1a));
++ /* Read OTP IDs */
++ ox03a_otp_id_read(client);
++
++ dev_info(&client->dev, "ox03a PID %x, res %dx%d, OTP_ID %02x:%02x:%02x:%02x:%02x:%02x\n",
++ pid, OX03A_MAX_WIDTH, OX03A_MAX_HEIGHT, priv->id[0], priv->id[1], priv->id[2], priv->id[3], priv->id[4], priv->id[5]);
++err:
++ return ret;
++}
++
++static int ox03a_parse_dt(struct device_node *np, struct ox03a_priv *priv)
++{
++ struct i2c_client *client = v4l2_get_subdevdata(&priv->sd);
++ int i;
++ struct device_node *endpoint = NULL, *rendpoint = NULL;
++ int tmp_addr = 0;
++
++ for (i = 0; ; i++) {
++ endpoint = of_graph_get_next_endpoint(np, endpoint);
++ if (!endpoint)
++ break;
++
++ rendpoint = of_parse_phandle(endpoint, "remote-endpoint", 0);
++ if (!rendpoint)
++ continue;
++
++ if (!of_property_read_u32(rendpoint, "ti9x3-addr", &priv->ti9x3_addr) &&
++ !of_property_match_string(rendpoint->parent->parent, "compatible", "ti,ti9x4") &&
++ !of_property_read_u32(rendpoint->parent->parent, "reg", &priv->ti9x4_addr) &&
++ !kstrtouint(strrchr(rendpoint->full_name, '@') + 1, 0, &priv->port))
++ break;
++ }
++
++ of_node_put(endpoint);
++
++ if (!priv->ti9x4_addr) {
++ dev_err(&client->dev, "deserializer does not present\n");
++ return -EINVAL;
++ }
++
++ /* setup I2C translator address */
++ tmp_addr = client->addr;
++ if (priv->ti9x4_addr) {
++ client->addr = priv->ti9x4_addr; /* Deserializer I2C address */
++ reg8_write(client, 0x4c, (priv->port << 4) | (1 << priv->port)); /* Select RX port number */
++ usleep_range(2000, 2500); /* wait 2ms */
++ reg8_write(client, 0x65, tmp_addr << 1); /* Sensor translated I2C address */
++ reg8_write(client, 0x5d, OX03A_I2C_ADDR << 1); /* Sensor native I2C address */
++// reg8_write(client, 0x6e, 0xa9); /* GPIO0 - reset, GPIO1 - fsin */
++
++ client->addr = priv->ti9x3_addr; /* Serializer I2C address */
++ reg8_write(client, 0x0d, 0x03); /* unreset gpios */
++ reg8_write(client, 0x0e, 0xf0); /* unreset gpios */
++ }
++ client->addr = tmp_addr;
++
++ mdelay(10);
++
++ return 0;
++}
++
++static int ox03a_probe(struct i2c_client *client,
++ const struct i2c_device_id *did)
++{
++ struct ox03a_priv *priv;
++ int ret;
++
++ priv = devm_kzalloc(&client->dev, sizeof(*priv), GFP_KERNEL);
++ if (!priv)
++ return -ENOMEM;
++
++ v4l2_i2c_subdev_init(&priv->sd, client, &ox03a_subdev_ops);
++ priv->sd.flags = V4L2_SUBDEV_FL_HAS_DEVNODE;
++
++ priv->exposure = 0x880;
++ priv->gain = 0x600;
++ priv->autogain = 1;
++ v4l2_ctrl_handler_init(&priv->hdl, 4);
++ v4l2_ctrl_new_std(&priv->hdl, &ox03a_ctrl_ops,
++ V4L2_CID_BRIGHTNESS, 0, 16, 1, 7);
++ v4l2_ctrl_new_std(&priv->hdl, &ox03a_ctrl_ops,
++ V4L2_CID_CONTRAST, 0, 16, 1, 7);
++ v4l2_ctrl_new_std(&priv->hdl, &ox03a_ctrl_ops,
++ V4L2_CID_SATURATION, 0, 7, 1, 2);
++ v4l2_ctrl_new_std(&priv->hdl, &ox03a_ctrl_ops,
++ V4L2_CID_HUE, 0, 23, 1, 12);
++ v4l2_ctrl_new_std(&priv->hdl, &ox03a_ctrl_ops,
++ V4L2_CID_GAMMA, -128, 128, 1, 0);
++ v4l2_ctrl_new_std(&priv->hdl, &ox03a_ctrl_ops,
++ V4L2_CID_SHARPNESS, 0, 10, 1, 3);
++ v4l2_ctrl_new_std(&priv->hdl, &ox03a_ctrl_ops,
++ V4L2_CID_AUTOGAIN, 0, 1, 1, priv->autogain);
++ v4l2_ctrl_new_std(&priv->hdl, &ox03a_ctrl_ops,
++ V4L2_CID_GAIN, 1, 0xfff, 1, priv->gain);
++ v4l2_ctrl_new_std(&priv->hdl, &ox03a_ctrl_ops,
++ V4L2_CID_EXPOSURE, 1, 0xffff, 1, priv->exposure);
++ v4l2_ctrl_new_std(&priv->hdl, &ox03a_ctrl_ops,
++ V4L2_CID_HFLIP, 0, 1, 1, 0);
++ v4l2_ctrl_new_std(&priv->hdl, &ox03a_ctrl_ops,
++ V4L2_CID_VFLIP, 0, 1, 1, 1);
++ priv->sd.ctrl_handler = &priv->hdl;
++
++ ret = priv->hdl.error;
++ if (ret)
++ goto cleanup;
++
++ v4l2_ctrl_handler_setup(&priv->hdl);
++
++ priv->pad.flags = MEDIA_PAD_FL_SOURCE;
++ priv->sd.entity.flags |= MEDIA_ENT_F_CAM_SENSOR;
++ ret = media_entity_pads_init(&priv->sd.entity, 1, &priv->pad);
++ if (ret < 0)
++ goto cleanup;
++
++ ret = ox03a_parse_dt(client->dev.of_node, priv);
++ if (ret)
++ goto cleanup;
++
++ ret = ox03a_initialize(client);
++ if (ret < 0)
++ goto cleanup;
++
++ priv->rect.left = 0;
++ priv->rect.top = 0;
++ priv->rect.width = OX03A_MAX_WIDTH;
++ priv->rect.height = OX03A_MAX_HEIGHT;
++
++ ret = v4l2_async_register_subdev(&priv->sd);
++ if (ret)
++ goto cleanup;
++
++ if (device_create_file(&client->dev, &dev_attr_otp_id_ox03a) != 0) {
++ dev_err(&client->dev, "sysfs otp_id entry creation failed\n");
++ goto cleanup;
++ }
++
++ priv->init_complete = 1;
++
++ return 0;
++
++cleanup:
++ media_entity_cleanup(&priv->sd.entity);
++ v4l2_ctrl_handler_free(&priv->hdl);
++ v4l2_device_unregister_subdev(&priv->sd);
++#ifdef CONFIG_SOC_CAMERA_OX03A
++ v4l_err(client, "failed to probe @ 0x%02x (%s)\n",
++ client->addr, client->adapter->name);
++#endif
++ return ret;
++}
++
++static int ox03a_remove(struct i2c_client *client)
++{
++ struct ox03a_priv *priv = i2c_get_clientdata(client);
++
++ device_remove_file(&client->dev, &dev_attr_otp_id_ox03a);
++ v4l2_async_unregister_subdev(&priv->sd);
++ media_entity_cleanup(&priv->sd.entity);
++ v4l2_ctrl_handler_free(&priv->hdl);
++ v4l2_device_unregister_subdev(&priv->sd);
++
++ return 0;
++}
++
++#ifdef CONFIG_SOC_CAMERA_OX03A
++static const struct i2c_device_id ox03a_id[] = {
++ { "ox03a", 0 },
++ { }
++};
++MODULE_DEVICE_TABLE(i2c, ox03a_id);
++
++static const struct of_device_id ox03a_of_ids[] = {
++ { .compatible = "ovti,ox03a", },
++ { }
++};
++MODULE_DEVICE_TABLE(of, ox03a_of_ids);
++
++static struct i2c_driver ox03a_i2c_driver = {
++ .driver = {
++ .name = "ox03a",
++ .of_match_table = ox03a_of_ids,
++ },
++ .probe = ox03a_probe,
++ .remove = ox03a_remove,
++ .id_table = ox03a_id,
++};
++
++module_i2c_driver(ox03a_i2c_driver);
++
++MODULE_DESCRIPTION("SoC Camera driver for OX03A");
++MODULE_AUTHOR("Vladimir Barinov");
++MODULE_LICENSE("GPL");
++#endif
+diff --git a/drivers/media/i2c/soc_camera/ox03a.h b/drivers/media/i2c/soc_camera/ox03a.h
+new file mode 100644
+index 0000000..4c20374
+--- /dev/null
++++ b/drivers/media/i2c/soc_camera/ox03a.h
+@@ -0,0 +1,1766 @@
++/*
++ * OmniVision OX03A sensor camera wizard 1920x1080@30/BGGR/MIPI
++ *
++ * Copyright (C) 2018 Cogent Embedded, Inc.
++ *
++ * This program is free software; you can redistribute it and/or modify it
++ * under the terms of the GNU General Public License as published by the
++ * Free Software Foundation; either version 2 of the License, or (at your
++ * option) any later version.
++ */
++
++//#define OX03A_DISPLAY_PATTERN_COLOR_BAR
++
++#define OX03A_MAX_WIDTH 1632
++#define OX03A_MAX_HEIGHT 1280
++
++#define OX03A_DELAY 0xffff
++//#define OX03A_DT 0x2c /* MIPI Data Type RAW12 */
++//#define DCG16_ONLY
++
++struct ox03a_reg {
++ u16 reg;
++ u8 val;
++};
++
++/* wizard: MIPI 1632x1280 16DCG+12VS 30fps 575MBPS R1A */
++static const struct ox03a_reg ox03a_regs_wizard_r1a[] = {
++{0x0103, 0x01}, // s/w reset
++{OX03A_DELAY, 10}, // Wait 10ms
++{0x4d09, 0x5f},
++{0x0100, 0x00},
++{0x0102, 0x00},
++{0x0103, 0x00},
++{0x0104, 0x04},
++{0x0105, 0x02},
++{0x0106, 0x00},
++{0x0107, 0x00},
++{0x0109, 0x00},
++{0x0300, 0x00},
++{0x0301, 0x01},
++{0x0302, 0x00},
++{0x0303, 0x02},
++{0x0304, 0x00},
++{0x0305, 0x2e},
++{0x0306, 0x00},
++{0x0307, 0x00},
++{0x0308, 0x04},
++{0x0309, 0x02},
++{0x030a, 0x00},
++{0x030c, 0x00},
++{0x030d, 0x00},
++{0x0310, 0x00},
++{0x0311, 0x00},
++{0x0312, 0x00},
++{0x0313, 0x00},
++{0x0314, 0x00},
++{0x0315, 0x00},
++{0x0316, 0x00},
++{0x0317, 0x12},
++{0x0318, 0x01},
++{0x0320, 0x00},
++{0x0321, 0x01},
++{0x0322, 0x00},
++{0x0323, 0x02},
++{0x0324, 0x00},
++{0x0325, 0x6c},
++{0x0326, 0x00},
++{0x0327, 0x05},
++{0x0328, 0x05},
++{0x0329, 0x01},
++{0x032a, 0x02},
++{0x032b, 0x00},
++{0x032c, 0x00},
++{0x0400, 0xe7},
++{0x0401, 0xff},
++{0x0404, 0x2b},
++{0x0405, 0x32},
++{0x0406, 0x33},
++{0x0407, 0x8f},
++{0x0408, 0x0c},
++{0x040a, 0x00},
++{0x0410, 0xe7},
++{0x0411, 0xff},
++{0x0414, 0x2b},
++{0x0415, 0x32},
++{0x0416, 0x33},
++{0x0417, 0x8f},
++{0x0418, 0x0c},
++{0x041a, 0x00},
++{0x2803, 0x00},
++{0x3000, 0x00},
++{0x3001, 0x03},
++{0x3002, 0x03},
++{0x3003, 0x00},
++{0x3004, 0x04},
++{0x3005, 0x00},
++{0x3006, 0x00},
++{0x3007, 0x04},
++{0x3008, 0x00},
++{0x3009, 0x06},
++{0x300d, 0x11},
++{0x300e, 0x11},
++{0x300f, 0x11},
++{0x3012, 0x41},
++{0x3016, 0xf0},
++{0x3017, 0xf0},
++{0x3018, 0xf0},
++{0x3019, 0xf0},
++{0x301a, 0xf0},
++{0x301b, 0xb4},
++{0x301c, 0x01},
++{0x301d, 0x02},
++{0x301e, 0xb8},
++{0x301f, 0xe1},
++{0x3020, 0x01},
++{0x3021, 0x00},
++{0x3022, 0xf8},
++{0x3023, 0xf0},
++{0x3024, 0xf0},
++{0x3025, 0x02},
++{0x3026, 0x00},
++{0x3027, 0x00},
++{0x3028, 0xf0},
++{0x3029, 0x80},
++{0x3035, 0x6c},
++{0x3036, 0x42},
++{0x3037, 0x20},
++{0x3038, 0x00},
++{0x3700, 0x26},
++{0x3701, 0x1e},
++{0x3702, 0x25},
++{0x3703, 0x28},
++{0x3704, 0x0f},
++{0x3705, 0x00},
++{0x3706, 0x39},
++{0x3707, 0x0a},
++{0x3708, 0x36},
++{0x3709, 0x41},
++{0x370a, 0x00},
++{0x370b, 0xa3},
++{0x370c, 0x0f},
++{0x370d, 0x00},
++{0x370e, 0xa6},
++{0x370f, 0x95},
++{0x3710, 0x15},
++{0x3711, 0x72},
++{0x3712, 0x12},
++{0x3713, 0x00},
++{0x3714, 0x22},
++{0x3715, 0x00},
++{0x3716, 0x04},
++{0x3717, 0x02},
++{0x3718, 0x09},
++{0x3719, 0x1f},
++{0x371a, 0x0c},
++{0x371b, 0x16},
++{0x371c, 0x00},
++{0x371d, 0x08},
++{0x371e, 0x00},
++{0x371f, 0x02},
++{0x3720, 0x03},
++{0x3721, 0x1c},
++{0x3722, 0x87},
++{0x3723, 0x08},
++{0x3724, 0x0d},
++{0x3725, 0x08},
++{0x3726, 0x0d},
++{0x3727, 0x08},
++{0x3728, 0x04},
++{0x3729, 0x0c},
++{0x372a, 0x01},
++{0x372b, 0x01},
++{0x372c, 0x17},
++{0x372d, 0x01},
++{0x372e, 0x35},
++{0x372f, 0x43},
++{0x3730, 0x04},
++{0x3731, 0x06},
++{0x3732, 0x01},
++{0x3733, 0x41},
++{0x3734, 0x0a},
++{0x3735, 0x11},
++{0x3736, 0x11},
++{0x3737, 0x00},
++{0x3738, 0x54},
++{0x3739, 0x54},
++{0x373a, 0x54},
++{0x373b, 0x54},
++{0x373c, 0x11},
++{0x373d, 0x11},
++{0x373e, 0x00},
++{0x373f, 0x4c},
++{0x3740, 0x4c},
++{0x3741, 0x44},
++{0x3742, 0x34},
++{0x3743, 0x01},
++{0x3744, 0x16},
++{0x3745, 0x08},
++{0x3746, 0x03},
++{0x3747, 0x01},
++{0x3748, 0x07},
++{0x3749, 0x01},
++{0x374a, 0x07},
++{0x374b, 0x03},
++{0x374c, 0xb1},
++{0x374d, 0x01},
++{0x374e, 0x01},
++{0x374f, 0x01},
++{0x3750, 0x07},
++{0x3751, 0x02},
++{0x3752, 0x03},
++{0x3753, 0xd0},
++{0x3754, 0x08},
++{0x3755, 0x00},
++{0x3758, 0xdd},
++{0x3759, 0x50},
++{0x375a, 0x49},
++{0x375b, 0x02},
++{0x375c, 0x2f},
++{0x375d, 0x00},
++{0x375e, 0x0f},
++{0x375f, 0x03},
++{0x3760, 0x13},
++{0x3761, 0x12},
++{0x3762, 0x1c},
++{0x3763, 0x03},
++{0x3764, 0x0d},
++{0x3765, 0x25},
++{0x3766, 0x08},
++{0x3767, 0x08},
++{0x3768, 0x21},
++{0x3769, 0x01},
++{0x376a, 0x01},
++{0x376b, 0x00},
++{0x376c, 0x15},
++{0x376d, 0x08},
++{0x376e, 0x08},
++{0x376f, 0x08},
++{0x3770, 0x91},
++{0x3771, 0x00},
++{0x3772, 0x00},
++{0x3773, 0x00},
++{0x3774, 0x82},
++{0x3775, 0x00},
++{0x3776, 0x00},
++{0x3777, 0x00},
++{0x3778, 0x00},
++{0x3779, 0x22},
++{0x377a, 0x00},
++{0x377b, 0x00},
++{0x377c, 0x48},
++{0x377d, 0x00},
++{0x377e, 0x00},
++{0x377f, 0x07},
++{0x3780, 0x00},
++{0x3781, 0x02},
++{0x3782, 0x04},
++{0x3783, 0x02},
++{0x3784, 0x08},
++{0x3785, 0x08},
++{0x3786, 0x00},
++{0x3787, 0x04},
++{0x3788, 0x02},
++{0x3789, 0x02},
++{0x378a, 0x04},
++{0x378b, 0x00},
++{0x378c, 0x00},
++{0x378d, 0x00},
++{0x378e, 0x00},
++{0x378f, 0x00},
++{0x3790, 0x10},
++{0x3791, 0x05},
++{0x3792, 0x31},
++#ifdef DCG16_ONLY
++{0x3793, 0x04}, /* DCG16 only */
++#else
++{0x3793, 0x00}, /* DCG16 + VS12*/
++#endif
++{0x3795, 0x00},
++{0x3796, 0x00},
++{0x3797, 0x00},
++{0x3798, 0x00},
++{0x3799, 0x00},
++{0x379a, 0x00},
++{0x379b, 0x10},
++{0x379c, 0x01},
++{0x379d, 0x00},
++{0x379e, 0x0d},
++{0x379f, 0x03},
++{0x37a0, 0x08},
++{0x37a1, 0x80},
++{0x37a2, 0x03},
++{0x37a3, 0x05},
++{0x37a4, 0x04},
++{0x37a5, 0x14},
++{0x37a6, 0x17},
++{0x37a7, 0x14},
++{0x37a8, 0x05},
++{0x37a9, 0x08},
++{0x37aa, 0x05},
++{0x37ab, 0x06},
++{0x37ac, 0x05},
++{0x37ad, 0x0d},
++{0x37ae, 0x0d},
++{0x37af, 0x01},
++{0x37b0, 0x0c},
++{0x37b1, 0x05},
++{0x37b2, 0x08},
++{0x37b3, 0x0a},
++{0x37b4, 0x08},
++{0x37b5, 0x08},
++{0x37b6, 0x08},
++{0x37b7, 0x08},
++{0x37b8, 0xff},
++{0x37b9, 0x01},
++{0x37ba, 0x08},
++{0x37bb, 0x08},
++{0x37bd, 0x01},
++{0x37be, 0xe0},
++{0x37bf, 0x00},
++{0x37c0, 0x01},
++{0x37c1, 0x11},
++{0x37c2, 0x11},
++{0x37c3, 0x00},
++{0x37c4, 0x63},
++{0x37c5, 0x63},
++{0x37c6, 0x48},
++{0x37c7, 0x38},
++{0x37c8, 0x21},
++{0x37c9, 0x00},
++{0x37ca, 0x08},
++{0x37cb, 0x00},
++{0x37cc, 0x40},
++{0x37cd, 0x00},
++{0x37ce, 0x01},
++{0x37cf, 0x08},
++{0x37d0, 0x00},
++{0x37d1, 0x39},
++{0x37d2, 0x00},
++{0x37d3, 0xa3},
++{0x37d4, 0x00},
++{0x37d5, 0x39},
++{0x37d6, 0x00},
++{0x37d7, 0xa3},
++{0x37da, 0x00},
++{0x37db, 0x00},
++{0x37dc, 0x00},
++{0x37dd, 0x00},
++{0x37de, 0x00},
++{0x37df, 0x00},
++{0x37e0, 0x00},
++{0x37e1, 0x00},
++{0x37e2, 0x00},
++{0x37e3, 0x00},
++{0x37e4, 0x00},
++{0x37e5, 0x00},
++{0x37e6, 0x00},
++{0x37e7, 0x00},
++{0x37e8, 0x00},
++{0x37e9, 0x00},
++{0x37ea, 0x00},
++{0x37eb, 0x00},
++{0x37ec, 0x00},
++{0x37ed, 0x00},
++{0x37ee, 0x00},
++{0x37ef, 0x00},
++{0x37f0, 0x00},
++{0x37f1, 0x00},
++{0x37f2, 0x00},
++{0x37f3, 0x00},
++{0x37f4, 0x00},
++{0x37f5, 0x00},
++{0x37f6, 0x00},
++{0x37f7, 0x00},
++{0x37f8, 0x00},
++{0x37f9, 0x00},
++{0x37fa, 0x00},
++{0x37fb, 0x00},
++{0x37fc, 0x00},
++{0x37fd, 0x00},
++{0x37fe, 0x00},
++{0x37ff, 0x00},
++{0x3c00, 0x00},
++{0x3c01, 0x11},
++{0x3c02, 0x20},
++{0x3c03, 0x04},
++{0x3c04, 0x04},
++{0x3c05, 0x00},
++{0x3c06, 0x29},
++{0x3c07, 0x01},
++{0x3c08, 0x05},
++{0x3c09, 0x0c},
++{0x3c0a, 0x04},
++{0x3c0b, 0xa8},
++{0x3c0c, 0x11},
++{0x3c0d, 0x08},
++{0x3c0e, 0x03},
++{0x3c0f, 0x02},
++{0x3c10, 0x01},
++{0x3c11, 0x08},
++{0x3c12, 0x89},
++{0x3c13, 0x21},
++{0x3c14, 0x81},
++{0x3c15, 0x21},
++{0x3c16, 0x11},
++{0x3c17, 0x01},
++{0x3c18, 0x0c},
++{0x3c19, 0x00},
++{0x3c1a, 0x16},
++{0x3c1b, 0x81},
++{0x3c1c, 0x04},
++{0x3c1d, 0x16},
++{0x3c1e, 0x11},
++{0x3c1f, 0x3a},
++{0x3c20, 0x20},
++{0x3c21, 0x00},
++{0x3c22, 0x17},
++{0x3c23, 0x07},
++{0x3c24, 0x1a},
++{0x3c25, 0x1e},
++{0x3c26, 0x24},
++{0x3c27, 0x37},
++{0x3c28, 0x0a},
++{0x3c29, 0x14},
++{0x3c2a, 0xd1},
++{0x3c2b, 0x27},
++{0x3c2c, 0x33},
++{0x3c2d, 0x0c},
++{0x3c2e, 0x12},
++{0x3c2f, 0x08},
++{0x3c30, 0x16},
++{0x3c31, 0x24},
++{0x3c32, 0x35},
++{0x3c33, 0x29},
++{0x3c34, 0x31},
++{0x3c35, 0x21},
++{0x3c36, 0x11},
++{0x3c37, 0x12},
++{0x3c38, 0x11},
++{0x3c39, 0x11},
++{0x3c3a, 0x08},
++{0x3c3b, 0x38},
++{0x3c3c, 0x03},
++{0x3c3d, 0x23},
++{0x3c3e, 0x05},
++{0x3c3f, 0x0a},
++{0x3c40, 0xc1},
++{0x3c41, 0x04},
++{0x3c42, 0x01},
++{0x3c43, 0x18},
++{0x3c44, 0x21},
++{0x3c45, 0x20},
++{0x3c46, 0x0b},
++{0x3c47, 0x11},
++{0x3c48, 0x11},
++{0x3c4a, 0x02},
++{0x3c4b, 0x63},
++{0x3c4c, 0x02},
++{0x3c4d, 0x63},
++{0x3c4e, 0x00},
++{0x3c4f, 0x2a},
++{0x3c50, 0x2a},
++{0x3c51, 0x2a},
++{0x3c52, 0x2a},
++{0x3c53, 0x08},
++{0x3c54, 0x1d},
++{0x3c55, 0xeb},
++{0x3c56, 0x24},
++{0x3c57, 0x10},
++{0x3c58, 0x10},
++{0x3c59, 0x16},
++{0x3c5a, 0x55},
++{0x3c5b, 0x25},
++{0x3c5c, 0x8e},
++{0x3ce0, 0x00},
++{0x3ce1, 0x00},
++{0x3ce2, 0x00},
++{0x3ce3, 0x00},
++{0x3ce4, 0x00},
++{0x3ce5, 0x00},
++{0x3ce6, 0x00},
++{0x3ce7, 0x00},
++{0x3ce8, 0x00},
++{0x3ce9, 0x00},
++{0x3cea, 0x00},
++{0x3ceb, 0x00},
++{0x3cec, 0x00},
++{0x3ced, 0x00},
++{0x3cee, 0x00},
++{0x3cef, 0x00},
++{0x3cf0, 0x00},
++{0x3cf1, 0x00},
++{0x3cf2, 0x00},
++{0x3cf3, 0x00},
++{0x3cf4, 0x00},
++{0x3cf5, 0x00},
++{0x3cf6, 0x00},
++{0x3cf7, 0x00},
++{0x3cf8, 0x00},
++{0x3cf9, 0x00},
++{0x3cfa, 0x00},
++{0x3cfb, 0x00},
++{0x3cfc, 0x00},
++{0x3cfd, 0x00},
++{0x3cfe, 0x00},
++{0x3cff, 0x00},
++{0x3100, 0x00},
++{0x3101, 0x32},
++{0x3102, 0x00},
++{0x3103, 0x25},
++{0x3104, 0x01},
++{0x3105, 0x11},
++{0x3106, 0x10},
++{0x3107, 0x01},
++{0x3108, 0x01},
++{0x3109, 0x00},
++{0x3182, 0x10},
++{0x3183, 0xff},
++{0x3184, 0xff},
++{0x3187, 0xff},
++{0x3189, 0x00},
++{0x318a, 0x00},
++{0x318b, 0x00},
++{0x318c, 0x00},
++{0x318d, 0x00},
++{0x318e, 0x00},
++{0x318f, 0x00},
++{0x3190, 0x00},
++{0x3191, 0x00},
++{0x3192, 0x00},
++{0x3193, 0x00},
++{0x3194, 0x00},
++{0x3200, 0x00},
++{0x3201, 0x08},
++{0x3202, 0x10},
++{0x3203, 0x18},
++{0x3204, 0x20},
++{0x3205, 0x30},
++{0x3206, 0xc0},
++{0x3209, 0x00},
++{0x320a, 0x00},
++{0x320b, 0x00},
++{0x320c, 0x00},
++{0x320d, 0x01},
++{0x3216, 0x02},
++{0x3217, 0x00},
++{0x3218, 0xf7},
++{0x3219, 0x55},
++{0x321b, 0x00},
++{0x3220, 0x1c},
++{0x3221, 0x00},
++{0x3304, 0x04},
++{0x3305, 0x00},
++{0x3306, 0x03},
++{0x3307, 0x00},
++{0x3308, 0x00},
++{0x3309, 0x00},
++{0x330a, 0x00},
++{0x330b, 0x00},
++{0x330c, 0x00},
++{0x330d, 0x00},
++{0x330e, 0x00},
++{0x330f, 0x00},
++{0x3310, 0x06},
++{0x3311, 0x05},
++{0x3312, 0x55},
++{0x3313, 0x0a},
++{0x3314, 0xaa},
++{0x3315, 0x0f},
++{0x3316, 0xf0},
++{0x3317, 0x00},
++{0x3400, 0x08},
++{0x3401, 0x00},
++{0x3402, 0x00},
++{0x3403, 0xb1},
++{0x3404, 0x00},
++{0x3405, 0x0f},
++{0x3406, 0x08},
++{0x3407, 0x08},
++{0x3408, 0x01},
++{0x3409, 0x02},
++{0x340a, 0x02},
++{0x340c, 0x10},
++{0x340d, 0x00},
++{0x3410, 0x00},
++{0x3412, 0x00},
++{0x3413, 0x00},
++{0x3414, 0x00},
++{0x3415, 0x00},
++{0x3416, 0x00},
++{0x3417, 0x00},
++{0x3420, 0x00},
++{0x3421, 0x00},
++{0x3422, 0x00},
++{0x3423, 0x00},
++{0x3424, 0x00},
++{0x3425, 0x00},
++{0x3426, 0x00},
++{0x3427, 0x00},
++{0x3428, 0x00},
++{0x3429, 0x00},
++{0x342a, 0x00},
++{0x342b, 0x00},
++{0x3501, 0x00},
++{0x3502, 0x24},
++{0x3503, 0xa8},
++{0x3504, 0x08},
++{0x3506, 0x00},
++{0x3507, 0x00},
++{0x3508, 0x01},
++{0x3509, 0x00},
++{0x350a, 0x01},
++{0x350b, 0x00},
++{0x350c, 0x00},
++{0x350d, 0x00},
++{0x3541, 0x00},
++{0x3542, 0x40},
++{0x3543, 0xa8},
++{0x3544, 0x08},
++{0x3546, 0x00},
++{0x3547, 0x00},
++{0x3548, 0x01},
++{0x3549, 0x00},
++{0x354a, 0x01},
++{0x354b, 0x00},
++{0x354c, 0x00},
++{0x354d, 0x00},
++{0x3581, 0x00},
++{0x3582, 0x24},
++{0x3583, 0xa8},
++{0x3584, 0x08},
++{0x3586, 0x00},
++{0x3587, 0x00},
++{0x3588, 0x01},
++{0x3589, 0x00},
++{0x358a, 0x01},
++{0x358b, 0x00},
++{0x358c, 0x00},
++{0x358d, 0x00},
++{0x3600, 0x00},
++{0x3601, 0x70},
++{0x3602, 0x42},
++{0x3603, 0xe3},
++{0x3604, 0x93},
++{0x3605, 0xff},
++{0x3606, 0x80},
++{0x3607, 0x4a},
++{0x3608, 0x98},
++{0x3609, 0x70},
++{0x360a, 0x90},
++{0x360b, 0x0a},
++{0x360c, 0x40},
++{0x360d, 0x88},
++{0x360e, 0x88},
++{0x360f, 0x88},
++{0x3610, 0x89},
++{0x3611, 0x4d},
++{0x3612, 0x4f},
++{0x3613, 0xba},
++{0x3614, 0x99},
++{0x3615, 0x99},
++{0x3616, 0x00},
++{0x3617, 0x00},
++{0x3618, 0x18},
++{0x3619, 0x00},
++{0x3620, 0x02},
++{0x3621, 0x80},
++{0x3622, 0x00},
++{0x3623, 0x00},
++{0x3624, 0x00},
++{0x3625, 0x00},
++{0x3626, 0x0e},
++{0x3627, 0x0f},
++{0x3628, 0x0a},
++{0x3629, 0x0a},
++{0x362a, 0x0e},
++{0x362b, 0x0e},
++{0x362c, 0x0e},
++{0x362d, 0x12},
++{0x362e, 0x00},
++{0x362f, 0x00},
++{0x3630, 0x00},
++{0x3631, 0x00},
++{0x3632, 0x99},
++{0x3633, 0x99},
++{0x3634, 0x30},
++{0x3635, 0x30},
++{0x3636, 0x30},
++{0x3637, 0x30},
++{0x3638, 0x00},
++{0x3639, 0x00},
++{0x363a, 0x00},
++{0x363b, 0x0f},
++{0x363c, 0x0f},
++{0x363d, 0x0a},
++{0x363e, 0x0a},
++{0x363f, 0x0a},
++{0x3640, 0x0a},
++{0x3641, 0x0a},
++{0x3642, 0x0a},
++{0x3643, 0x0e},
++{0x3644, 0x00},
++{0x3645, 0x10},
++{0x3646, 0x16},
++{0x3647, 0x0e},
++{0x3648, 0x00},
++{0x3649, 0x13},
++{0x364a, 0x13},
++{0x364b, 0x00},
++{0x364c, 0x0e},
++{0x364d, 0x0e},
++{0x364e, 0x0e},
++{0x364f, 0x0e},
++{0x3650, 0x00},
++{0x3651, 0x00},
++{0x3652, 0xc5},
++{0x3653, 0x00},
++{0x3654, 0x40},
++{0x3655, 0x00},
++{0x3656, 0xcf},
++{0x3657, 0x2b},
++{0x3658, 0x09},
++{0x3659, 0x00},
++{0x365a, 0x00},
++{0x365b, 0x00},
++{0x365c, 0x00},
++{0x365d, 0x00},
++{0x3660, 0x01},
++{0x3661, 0x07},
++{0x3662, 0x00},
++{0x3663, 0x20},
++{0x3664, 0x00},
++{0x3665, 0x12},
++{0x3666, 0x13},
++{0x3667, 0x54},
++{0x3668, 0x95},
++{0x3669, 0x16},
++{0x366a, 0x00},
++{0x366b, 0x00},
++{0x366c, 0x00},
++{0x366d, 0x00},
++{0x366e, 0x00},
++{0x366f, 0xf4},
++{0x3670, 0x6f},
++{0x3671, 0x0f},
++{0x3672, 0x1d},
++{0x3673, 0x6a},
++{0x3674, 0x6f},
++{0x3675, 0x1d},
++{0x3676, 0x6f},
++{0x3677, 0x1d},
++{0x3678, 0x80},
++{0x3679, 0x04},
++{0x367a, 0x00},
++{0x367b, 0x04},
++{0x367c, 0x00},
++{0x367d, 0x00},
++{0x367e, 0x00},
++{0x367f, 0x00},
++{0x3680, 0x00},
++/* window start */
++{0x3800, 0x00},
++{0x3801, 0x00},
++{0x3802, 0x00},
++{0x3803, 0x04},
++{0x3804, 0x07},
++{0x3805, 0x8f},
++{0x3806, 0x05},
++{0x3807, 0x0d},
++{0x3808, OX03A_MAX_WIDTH >> 8},
++{0x3809, OX03A_MAX_WIDTH & 0xff},
++{0x380a, OX03A_MAX_HEIGHT >> 8},
++{0x380b, OX03A_MAX_HEIGHT & 0xff},
++{0x380c, 0x06},
++{0x380d, 0xce},
++{0x380e, 0x05},
++{0x380f, 0x37},
++{0x3810, 0x00},
++{0x3811, 0x9c},
++{0x3812, 0x00},
++{0x3813, 0x04},
++/* window end */
++{0x3814, 0x01},
++{0x3815, 0x01},
++{0x3816, 0x01},
++{0x3817, 0x01},
++{0x3818, 0x00},
++{0x3819, 0x00},
++{0x381a, 0x00},
++{0x381b, 0x01},
++{0x381c, 0x08},
++{0x381d, 0x00},
++{0x3820, 0x44}, /* VPLIP on */
++{0x3821, 0x20}, /* HFLIP off */
++{0x3822, 0x14},
++{0x3823, 0x08},
++{0x3824, 0x00},
++{0x3825, 0x20},
++{0x3826, 0x00},
++{0x3827, 0x08},
++{0x3828, 0x38},
++{0x382a, 0x00},
++{0x382b, 0x00},
++{0x382c, 0x00},
++{0x382d, 0x00},
++{0x3832, 0x00},
++{0x3833, 0x00},
++{0x3834, 0x00},
++{0x3838, 0x00},
++{0x3839, 0x00},
++{0x383a, 0x00},
++{0x383b, 0x00},
++{0x383c, 0x48},
++{0x383d, 0x20},
++{0x383e, 0x00},
++{0x3842, 0x00},
++{0x3843, 0x00},
++{0x3844, 0x00},
++{0x384c, 0x03},
++{0x384d, 0xc2},
++{0x384e, 0x00},
++{0x384f, 0x40},
++{0x3850, 0x00},
++{0x3851, 0x42},
++{0x3852, 0x00},
++{0x3853, 0x40},
++{0x3854, 0x00},
++{0x3855, 0x05},
++{0x3856, 0x04},
++{0x3857, 0x6b},
++{0x3858, 0x3c},
++{0x3859, 0x00},
++{0x385a, 0x03},
++{0x385b, 0x04},
++{0x385c, 0x6a},
++{0x385d, 0x00},
++{0x385e, 0x12},
++{0x385f, 0x00},
++{0x3860, 0x10},
++{0x3861, 0x00},
++{0x3862, 0x40},
++{0x3863, 0x00},
++{0x3864, 0x40},
++{0x3865, 0x00},
++{0x3866, 0x40},
++{0x3881, 0x02},
++{0x3882, 0x00},
++{0x3883, 0x08},
++{0x3b40, 0x3e},
++{0x3b41, 0x00},
++{0x3b42, 0x02},
++{0x3b43, 0x00},
++{0x3b44, 0x03},
++{0x3b45, 0x00},
++{0x3b46, 0x03},
++{0x3b47, 0x00},
++{0x3b80, 0x00},
++{0x3b81, 0x00},
++{0x3b82, 0x07},
++{0x3b83, 0x87},
++{0x3b84, 0x36},
++{0x3b85, 0x00},
++{0x3b86, 0x00},
++{0x3b87, 0x04},
++{0x3b88, 0x00},
++{0x3b89, 0x04},
++{0x3b8a, 0x00},
++{0x3b8b, 0x0a},
++{0x3b8c, 0x00},
++{0x3b8d, 0x01},
++{0x3b8e, 0x03},
++{0x3b8f, 0xe8},
++{0x3d82, 0xbc},
++{0x3d83, 0x08},
++{0x3d84, 0x00},
++{0x3d85, 0x0b},
++{0x3d86, 0x02},
++{0x3d87, 0x0a},
++{0x3d88, 0x00},
++{0x3d89, 0x00},
++{0x3d8a, 0x03},
++{0x3d8b, 0xff},
++{0x3d8c, 0x70},
++{0x3d8d, 0x10},
++{0x3d90, 0x00},
++{0x3d91, 0x00},
++{0x3d92, 0xe2},
++{0x3d93, 0x46},
++{0x3d94, 0x14},
++{0x3d95, 0x06},
++{0x3d96, 0x01},
++{0x3d97, 0x00},
++{0x3d98, 0x00},
++{0x3d99, 0x00},
++{0x3d9a, 0x00},
++{0x3d9b, 0x00},
++{0x3d9c, 0x00},
++{0x3d9d, 0x00},
++{0x3d9e, 0x00},
++{0x3d9f, 0x00},
++{0x3da0, 0x00},
++{0x3da1, 0x00},
++{0x3da2, 0x00},
++{0x3da4, 0x00},
++{0x3e00, 0x00},
++{0x3e01, 0x00},
++{0x3e02, 0x0f},
++{0x3e03, 0xdb},
++{0x3e04, 0x14},
++{0x3e05, 0x00},
++{0x3e06, 0x03},
++{0x3e07, 0x40},
++{0x3e08, 0x00},
++{0x3e09, 0x00},
++{0x3e0a, 0x00},
++{0x3e0b, 0x00},
++{0x3e0c, 0x00},
++{0x3e0d, 0x00},
++{0x3e0e, 0x00},
++{0x3f00, 0x04},
++{0x3f01, 0x00},
++{0x3f02, 0x00},
++{0x3f03, 0x01},
++{0x4000, 0xf8},
++{0x4001, 0x2b},
++{0x4004, 0x00},
++{0x4005, 0x40},
++{0x4006, 0x00},
++{0x4007, 0x10},
++{0x4008, 0x02},
++{0x4009, 0x0d},
++{0x400a, 0x08},
++{0x400b, 0x00},
++{0x400c, 0x00},
++{0x400d, 0x10},
++{0x400e, 0x00},
++{0x400f, 0xa0},
++{0x4010, 0x10},
++{0x4011, 0xff},
++{0x4012, 0x08},
++{0x4013, 0x02},
++{0x4014, 0x02},
++{0x4015, 0x02},
++{0x4016, 0x00},
++{0x4017, 0x10},
++{0x4018, 0x18},
++{0x4019, 0x04},
++{0x401a, 0x58},
++{0x4020, 0x00},
++{0x4021, 0x00},
++{0x4022, 0x00},
++{0x4023, 0x00},
++{0x4024, 0x00},
++{0x4025, 0x00},
++{0x4026, 0x00},
++{0x4027, 0x00},
++{0x4028, 0x4f},
++{0x4029, 0x01},
++{0x402a, 0x00},
++{0x402b, 0x00},
++{0x402c, 0x00},
++{0x402d, 0x00},
++{0x402e, 0x00},
++{0x402f, 0x40},
++{0x4030, 0x00},
++{0x4031, 0x40},
++{0x4032, 0x9f},
++{0x4033, 0x00},
++{0x4034, 0x00},
++{0x4035, 0x80},
++{0x4036, 0x00},
++{0x4037, 0x80},
++{0x4038, 0x00},
++{0x4039, 0x80},
++{0x403a, 0x00},
++{0x403b, 0x80},
++{0x403c, 0x00},
++{0x403d, 0x00},
++{0x4040, 0x00},
++{0x4041, 0x00},
++{0x4042, 0x00},
++{0x4043, 0x00},
++{0x4044, 0x00},
++{0x4045, 0x00},
++{0x4046, 0x00},
++{0x4047, 0x00},
++{0x4048, 0x00},
++{0x4049, 0x00},
++{0x404a, 0x00},
++{0x404b, 0x00},
++{0x404c, 0x00},
++{0x404d, 0x00},
++{0x404e, 0x00},
++{0x404f, 0x00},
++{0x4050, 0x00},
++{0x4051, 0x05},
++{0x4052, 0x00},
++{0x4053, 0x80},
++{0x4054, 0x00},
++{0x4055, 0x80},
++{0x4056, 0x00},
++{0x4057, 0x80},
++{0x4058, 0x00},
++{0x4059, 0x80},
++{0x405a, 0x30},
++{0x405b, 0x18},
++{0x405c, 0x00},
++{0x405d, 0x00},
++{0x405e, 0x00},
++{0x405f, 0x00},
++{0x4060, 0x00},
++{0x4065, 0x00},
++{0x4066, 0x02},
++{0x406d, 0x00},
++{0x406e, 0x00},
++{0x406f, 0x00},
++{0x40a0, 0x00},
++{0x40a1, 0x00},
++{0x40a2, 0x00},
++{0x40a3, 0x00},
++{0x40a4, 0x00},
++{0x40a5, 0x00},
++{0x40a6, 0x00},
++{0x40a7, 0x00},
++{0x40c0, 0x00},
++{0x40c1, 0x00},
++{0x40c2, 0x00},
++{0x40c3, 0x00},
++{0x40c4, 0x00},
++{0x40c5, 0x00},
++{0x40c6, 0x00},
++{0x40c7, 0x00},
++{0x40c8, 0x00},
++{0x40c9, 0x00},
++{0x40ca, 0x00},
++{0x40cb, 0x00},
++{0x40cc, 0x00},
++{0x40cd, 0x00},
++{0x40ce, 0x00},
++{0x40cf, 0x00},
++{0x4200, 0x00},
++{0x4201, 0x00},
++{0x4202, 0x00},
++{0x4203, 0x00},
++{0x4204, 0x00},
++{0x4205, 0x00},
++{0x4206, 0x00},
++{0x4207, 0x00},
++{0x4208, 0x00},
++{0x4300, 0x00},
++{0x4301, 0x00},
++{0x4302, 0x00},
++{0x4303, 0x00},
++{0x4304, 0x00},
++{0x4305, 0x00},
++{0x4306, 0x00},
++{0x4307, 0x00},
++{0x4308, 0x00},
++{0x4309, 0x00},
++{0x430a, 0x00},
++{0x430b, 0xff},
++{0x430c, 0xff},
++{0x430d, 0x00},
++{0x430e, 0x00},
++{0x430f, 0x02},
++{0x4500, 0x16},
++{0x4501, 0x18},
++{0x4502, 0x00},
++{0x4503, 0x00},
++{0x4504, 0x01},
++{0x4505, 0x00},
++{0x4506, 0x32},
++{0x4507, 0x16},
++{0x4508, 0x1a},
++{0x4580, 0x68},
++{0x4581, 0xc7},
++{0x4582, 0x07},
++{0x4583, 0x07},
++{0x4584, 0xec},
++{0x4585, 0x09},
++{0x4586, 0xae},
++{0x4587, 0x04},
++{0x4588, 0x52},
++{0x4589, 0x05},
++{0x458a, 0x47},
++{0x458b, 0x02},
++{0x458c, 0xe2},
++{0x458d, 0x03},
++{0x458e, 0x85},
++{0x458f, 0x00},
++{0x4590, 0x20},
++{0x4591, 0x09},
++{0x4592, 0x60},
++{0x45a6, 0x18},
++{0x4600, 0x00},
++{0x4601, 0x30},
++{0x4602, 0x02},
++{0x4603, 0x01},
++{0x4604, 0x00},
++{0x4605, 0x03},
++{0x4609, 0x00},
++{0x460a, 0x36},
++{0x460b, 0x00},
++{0x460c, 0x60},
++{0x460d, 0x01},
++{0x460e, 0x00},
++{0x4700, 0x2a},
++{0x4702, 0x00},
++{0x4703, 0x80},
++{0x4704, 0x00},
++{0x4705, 0x10},
++{0x4706, 0xaa},
++{0x4707, 0x55},
++{0x4708, 0x99},
++{0x4709, 0x66},
++{0x470a, 0x08},
++{0x470b, 0x88},
++{0x470c, 0x00},
++{0x470d, 0x02},
++{0x470e, 0x00},
++{0x470f, 0x00},
++{0x4710, 0x00},
++{0x4711, 0x00},
++{0x4712, 0x00},
++{0x4713, 0x00},
++{0x4800, 0x04},
++{0x4802, 0x00},
++{0x4803, 0x00},
++{0x4804, 0x08},
++{0x4805, 0x00},
++{0x4806, 0x00},
++{0x4807, 0x03},
++{0x4808, 0x18},
++{0x480e, 0x04},
++{0x4810, 0xff},
++{0x4811, 0xff},
++{0x4813, 0x12}, // 0xVC
++{0x4814, 0x2a},
++{0x4815, 0x2b},
++{0x4816, 0x2b},
++{0x4818, 0x00},
++{0x4819, 0x70},
++{0x481a, 0x00},
++{0x481b, 0x3c},
++{0x481c, 0x01},
++{0x481d, 0x2c},
++{0x481e, 0x5f},
++{0x481f, 0x26},
++{0x4820, 0x00},
++{0x4821, 0x3c},
++{0x4822, 0x00},
++{0x4823, 0x3c},
++{0x4824, 0x00},
++{0x4825, 0x32},
++{0x4826, 0x32},
++{0x4827, 0x55},
++{0x4828, 0x00},
++{0x4829, 0x64},
++{0x482a, 0x06},
++{0x482b, 0x04},
++{0x482c, 0x00},
++{0x482d, 0x00},
++{0x482e, 0x34},
++{0x482f, 0x00},
++{0x4830, 0x00},
++{0x4831, 0x64},
++{0x4832, 0x00},
++{0x4833, 0x10},
++{0x4837, 0x18},
++{0x4838, 0x00},
++{0x4839, 0x00},
++{0x483c, 0x10},
++{0x483d, 0x00},
++{0x484a, 0x3f},
++{0x484b, 0x27},
++{0x484c, 0x00},
++{0x484e, 0x10},
++{0x4850, 0x40},
++{0x4851, 0xaa},
++{0x4852, 0xff},
++{0x4853, 0x8a},
++{0x4854, 0x08},
++{0x4855, 0x30},
++{0x4856, 0x01},
++{0x4860, 0x00},
++{0x4861, 0xa0},
++{0x4862, 0x01},
++{0x4863, 0x01},
++{0x4864, 0x02},
++{0x4865, 0x66},
++{0x4866, 0x99},
++{0x4867, 0x88},
++{0x4868, 0xaa},
++{0x4869, 0xff},
++{0x486a, 0x3f},
++{0x486b, 0x84},
++{0x486c, 0x36},
++{0x486d, 0x00},
++{0x486e, 0x84},
++{0x486f, 0x36},
++{0x4870, 0x00},
++{0x4880, 0x00},
++{0x4881, 0x00},
++{0x4882, 0x00},
++{0x4883, 0x00},
++{0x4884, 0x08},
++{0x4885, 0x00},
++{0x4886, 0x00},
++{0x4900, 0x08},
++{0x4901, 0x00},
++{0x4902, 0x00},
++{0x4903, 0x80},
++{0x4f00, 0xff},
++{0x4f01, 0xff},
++{0x4f04, 0x00},
++{0x4f05, 0x01},
++{0x5180, 0x04},
++{0x5181, 0x00},
++{0x5182, 0x04},
++{0x5183, 0x00},
++{0x5184, 0x04},
++{0x5185, 0x00},
++{0x5186, 0x04},
++{0x5187, 0x00},
++{0x5188, 0x00},
++{0x5189, 0x00},
++{0x518a, 0x00},
++{0x518b, 0x10},
++{0x51a0, 0x04},
++{0x51a1, 0x00},
++{0x51a2, 0x04},
++{0x51a3, 0x00},
++{0x51a4, 0x04},
++{0x51a5, 0x00},
++{0x51a6, 0x04},
++{0x51a7, 0x00},
++{0x51a8, 0x00},
++{0x51a9, 0x00},
++{0x51aa, 0x00},
++{0x51ab, 0x10},
++{0x51c0, 0x04},
++{0x51c1, 0x00},
++{0x51c2, 0x04},
++{0x51c3, 0x00},
++{0x51c4, 0x04},
++{0x51c5, 0x00},
++{0x51c6, 0x04},
++{0x51c7, 0x00},
++{0x51c8, 0x00},
++{0x51c9, 0x00},
++{0x51ca, 0x00},
++{0x51cb, 0x10},
++{0x5380, 0x19},
++{0x5381, 0x94},
++{0x5382, 0x2e},
++{0x5383, 0x24},
++{0x5384, 0x12},
++{0x5385, 0x41},
++{0x5386, 0x48},
++{0x5387, 0x84},
++{0x5388, 0x40},
++{0x5389, 0x00},
++{0x538a, 0x00},
++{0x538b, 0x03},
++{0x538c, 0x00},
++{0x538d, 0x0f},
++{0x538e, 0x00},
++{0x538f, 0x3f},
++{0x5390, 0x0f},
++{0x5391, 0xfd},
++{0x5392, 0xf5},
++{0x5393, 0xf5},
++{0x5394, 0x02},
++{0x5395, 0xff},
++{0x5396, 0x00},
++{0x5397, 0x00},
++{0x53a0, 0x41},
++{0x53a2, 0x04},
++{0x53a3, 0x00},
++{0x53a4, 0x04},
++{0x53a5, 0x00},
++{0x53a6, 0x04},
++{0x53a7, 0x00},
++{0x53ac, 0x04},
++{0x53ad, 0x00},
++{0x53ae, 0x04},
++{0x53af, 0x00},
++{0x53b0, 0x04},
++{0x53b1, 0x00},
++{0x5400, 0x19},
++{0x5401, 0x94},
++{0x5402, 0x2e},
++{0x5403, 0x24},
++{0x5404, 0x12},
++{0x5405, 0x41},
++{0x5406, 0x48},
++{0x5407, 0x84},
++{0x5408, 0x40},
++{0x5409, 0x00},
++{0x540a, 0x00},
++{0x540b, 0x03},
++{0x540c, 0x00},
++{0x540d, 0x0f},
++{0x540e, 0x00},
++{0x540f, 0x3f},
++{0x5410, 0x0f},
++{0x5411, 0xfd},
++{0x5412, 0xf5},
++{0x5413, 0xf5},
++{0x5414, 0x02},
++{0x5415, 0xff},
++{0x5416, 0x00},
++{0x5417, 0x00},
++{0x5420, 0x41},
++{0x5422, 0x04},
++{0x5423, 0x00},
++{0x5424, 0x04},
++{0x5425, 0x00},
++{0x5426, 0x04},
++{0x5427, 0x00},
++{0x542c, 0x04},
++{0x542d, 0x00},
++{0x542e, 0x04},
++{0x542f, 0x00},
++{0x5430, 0x04},
++{0x5431, 0x00},
++{0x5480, 0x19},
++{0x5481, 0x94},
++{0x5482, 0x2e},
++{0x5483, 0x24},
++{0x5484, 0x12},
++{0x5485, 0x41},
++{0x5486, 0x48},
++{0x5487, 0x84},
++{0x5488, 0x40},
++{0x5489, 0x00},
++{0x548a, 0x00},
++{0x548b, 0x03},
++{0x548c, 0x00},
++{0x548d, 0x0f},
++{0x548e, 0x00},
++{0x548f, 0x3f},
++{0x5490, 0x0f},
++{0x5491, 0xfd},
++{0x5492, 0xf5},
++{0x5493, 0xf5},
++{0x5494, 0x02},
++{0x5495, 0xff},
++{0x5496, 0x00},
++{0x5497, 0x00},
++{0x54a0, 0x41},
++{0x54a2, 0x04},
++{0x54a3, 0x00},
++{0x54a4, 0x04},
++{0x54a5, 0x00},
++{0x54a6, 0x04},
++{0x54a7, 0x00},
++{0x54ac, 0x04},
++{0x54ad, 0x00},
++{0x54ae, 0x04},
++{0x54af, 0x00},
++{0x54b0, 0x04},
++{0x54b1, 0x00},
++{0x5800, 0x39},
++{0x5801, 0x03},
++{0x5802, 0x60},
++{0x5803, 0xf0},
++{0x5804, 0x00},
++{0x5805, 0x40},
++{0x5806, 0x01},
++{0x5807, 0x00},
++{0x5808, 0x60},
++{0x5809, 0xf0},
++{0x580a, 0x33},
++{0x580b, 0x10},
++{0x580c, 0x04},
++{0x580d, 0x00},
++{0x580e, 0x10},
++{0x580f, 0x10},
++{0x5810, 0x02},
++{0x5811, 0x08},
++{0x5812, 0x38},
++{0x5813, 0x00},
++{0x5814, 0x00},
++{0x5815, 0x00},
++{0x5816, 0x00},
++{0x5000, 0x81},
++{0x5001, 0x42},
++{0x5002, 0x1b},
++{0x5003, 0xfe},
++{0x5004, 0x02},
++{0x5005, 0x00},
++{0x5006, 0x01},
++{0x5007, 0x00},
++{0x5008, 0x00},
++{0x5009, 0x40},
++{0x500a, 0x00},
++{0x500b, 0x00},
++{0x500c, 0x00},
++{0x500d, 0x00},
++{0x500e, 0x00},
++{0x500f, 0x00},
++{0x5010, 0x07},
++{0x5011, 0x8f},
++{0x5012, 0x05},
++{0x5013, 0x0f},
++{0x5014, 0x01},
++{0x5015, 0x01},
++{0x5016, 0x01},
++{0x5017, 0x01},
++{0x5018, 0x00},
++{0x5019, 0x00},
++{0x501a, 0x00},
++{0x501b, 0x10},
++{0x501c, 0x00},
++{0x501d, 0x10},
++{0x501e, 0x00},
++{0x501f, 0x10},
++{0x5020, 0x04},
++{0x5021, 0x00},
++{0x5022, 0x04},
++{0x5023, 0x00},
++{0x5024, 0x04},
++{0x5025, 0x00},
++{0x5026, 0x00},
++{0x5027, 0x10},
++{0x5028, 0x00},
++{0x5029, 0x10},
++{0x502a, 0x00},
++{0x502b, 0x10},
++{0x502c, 0x00},
++{0x502d, 0x10},
++{0x502e, 0x00},
++{0x502f, 0x10},
++{0x5030, 0x00},
++{0x5031, 0x10},
++{0x5032, 0x04},
++{0x5033, 0x00},
++{0x5034, 0x04},
++{0x5035, 0x00},
++{0x5036, 0x04},
++{0x5037, 0x00},
++{0x5038, 0x00},
++{0x5039, 0x10},
++{0x503a, 0x00},
++{0x503b, 0x10},
++{0x503c, 0x00},
++{0x503d, 0x10},
++{0x503e, 0x00},
++{0x503f, 0x00},
++{0x5040, 0x00},
++{0x5041, 0x01},
++{0x5042, 0x00},
++{0x5043, 0x00},
++{0x5600, 0x0f},
++{0x5601, 0xab},
++{0x5602, 0x02},
++{0x5603, 0x58},
++{0x5604, 0x03},
++{0x5605, 0x20},
++{0x5606, 0x02},
++{0x5607, 0x58},
++{0x5608, 0x03},
++{0x5609, 0x20},
++{0x560a, 0x02},
++{0x560b, 0x58},
++{0x560c, 0x03},
++{0x560d, 0x20},
++{0x560e, 0x02},
++{0x560f, 0x58},
++{0x5610, 0x03},
++{0x5611, 0x20},
++{0x5612, 0x02},
++{0x5613, 0x58},
++{0x5614, 0x03},
++{0x5615, 0x20},
++{0x5616, 0x02},
++{0x5617, 0x58},
++{0x5618, 0x03},
++{0x5619, 0x20},
++{0x5640, 0x0f},
++{0x5641, 0xab},
++{0x5642, 0x02},
++{0x5643, 0x58},
++{0x5644, 0x03},
++{0x5645, 0x20},
++{0x5646, 0x02},
++{0x5647, 0x58},
++{0x5648, 0x03},
++{0x5649, 0x20},
++{0x564a, 0x02},
++{0x564b, 0x58},
++{0x564c, 0x03},
++{0x564d, 0x20},
++{0x564e, 0x02},
++{0x564f, 0x58},
++{0x5650, 0x03},
++{0x5651, 0x20},
++{0x5652, 0x02},
++{0x5653, 0x58},
++{0x5654, 0x03},
++{0x5655, 0x20},
++{0x5656, 0x02},
++{0x5657, 0x58},
++{0x5658, 0x03},
++{0x5659, 0x20},
++{0x5680, 0x0f},
++{0x5681, 0xab},
++{0x5682, 0x02},
++{0x5683, 0x58},
++{0x5684, 0x03},
++{0x5685, 0x20},
++{0x5686, 0x02},
++{0x5687, 0x58},
++{0x5688, 0x03},
++{0x5689, 0x20},
++{0x568a, 0x02},
++{0x568b, 0x58},
++{0x568c, 0x03},
++{0x568d, 0x20},
++{0x568e, 0x02},
++{0x568f, 0x58},
++{0x5690, 0x03},
++{0x5691, 0x20},
++{0x5692, 0x02},
++{0x5693, 0x58},
++{0x5694, 0x03},
++{0x5695, 0x20},
++{0x5696, 0x02},
++{0x5697, 0x58},
++{0x5698, 0x03},
++{0x5699, 0x20},
++{0x5700, 0x00},
++{0x5701, 0x00},
++{0x5702, 0x00},
++{0x5703, 0x00},
++{0x5704, 0x02},
++{0x5705, 0x80},
++{0x5706, 0x01},
++{0x5707, 0xe0},
++{0x5708, 0x00},
++{0x5709, 0x0f},
++{0x5740, 0x00},
++{0x5741, 0x00},
++{0x5742, 0x00},
++{0x5743, 0x00},
++{0x5744, 0x02},
++{0x5745, 0x80},
++{0x5746, 0x01},
++{0x5747, 0xe0},
++{0x5748, 0x00},
++{0x5749, 0x0f},
++{0x5780, 0x00},
++{0x5781, 0x00},
++{0x5782, 0x00},
++{0x5783, 0x00},
++{0x5784, 0x02},
++{0x5785, 0x80},
++{0x5786, 0x01},
++{0x5787, 0xe0},
++{0x5788, 0x00},
++{0x5789, 0x0f},
++{0x5200, 0x70},
++{0x5201, 0x70},
++{0x5202, 0x73},
++{0x5203, 0xff},
++{0x5204, 0x02},
++{0x5205, 0x6c},
++{0x5206, 0x00},
++{0x5207, 0x00},
++{0x5209, 0x08},
++{0x520a, 0x00},
++{0x520b, 0x07},
++{0x520c, 0x01},
++{0x520d, 0x01},
++{0x520e, 0x01},
++{0x520f, 0x01},
++{0x5210, 0x00},
++{0x5211, 0x00},
++{0x5212, 0x00},
++{0x5213, 0x00},
++{0x5214, 0x00},
++{0x5215, 0x00},
++{0x5216, 0x07},
++{0x5217, 0x8b},
++{0x5218, 0x00},
++{0x5219, 0x00},
++{0x5280, 0x00},
++{0x5281, 0x00},
++{0x5282, 0xff},
++{0x5283, 0xff},
++{0x5284, 0x02},
++{0x5285, 0x6c},
++{0x5286, 0x00},
++{0x5287, 0x00},
++{0x5289, 0x08},
++{0x528a, 0x00},
++{0x528b, 0x07},
++{0x528c, 0x01},
++{0x528d, 0x01},
++{0x528e, 0x01},
++{0x528f, 0x01},
++{0x5290, 0x00},
++{0x5291, 0x00},
++{0x5292, 0x00},
++{0x5293, 0x00},
++{0x5294, 0x00},
++{0x5295, 0x00},
++{0x5296, 0x07},
++{0x5297, 0x8b},
++{0x5298, 0x00},
++{0x5299, 0x00},
++{0x5300, 0x00},
++{0x5301, 0x00},
++{0x5302, 0xff},
++{0x5303, 0xff},
++{0x5304, 0x02},
++{0x5305, 0x6c},
++{0x5306, 0x00},
++{0x5307, 0x00},
++{0x5309, 0x08},
++{0x530a, 0x00},
++{0x530b, 0x07},
++{0x530c, 0x01},
++{0x530d, 0x01},
++{0x530e, 0x01},
++{0x530f, 0x01},
++{0x5310, 0x00},
++{0x5311, 0x00},
++{0x5312, 0x00},
++{0x5313, 0x00},
++{0x5314, 0x00},
++{0x5315, 0x00},
++{0x5316, 0x07},
++{0x5317, 0x8b},
++{0x5318, 0x00},
++{0x5319, 0x00},
++#ifdef OX03A_DISPLAY_PATTERN_COLOR_BAR
++{0x5080, 0xc0}, /* Rolling test pattern for HCG */
++#else
++{0x5080, 0x00},
++#endif
++{0x5081, 0x01},
++{0x5082, 0xb0},
++{0x5083, 0x0f},
++{0x5084, 0x00},
++{0x5085, 0x00},
++{0x5086, 0x00},
++{0x5087, 0x01},
++{0x5088, 0x00},
++{0x5089, 0x00},
++{0x508a, 0x00},
++{0x508b, 0x00},
++{0x508c, 0x00},
++{0x508d, 0x00},
++{0x508e, 0x00},
++{0x508f, 0x00},
++{0x5090, 0x00},
++{0x5091, 0x00},
++{0x5092, 0x00},
++{0x5093, 0x00},
++{0x5094, 0x00},
++{0x5095, 0x00},
++{0x5096, 0x00},
++{0x5097, 0x00},
++#ifdef OX03A_DISPLAY_PATTERN_COLOR_BAR
++{0x50c0, 0xc0}, /* Rolling test pattern for LCG */
++#else
++{0x50c0, 0x00},
++#endif
++{0x50c1, 0x01},
++{0x50c2, 0xb0},
++{0x50c3, 0x0f},
++{0x50c4, 0x00},
++{0x50c5, 0x00},
++{0x50c6, 0x00},
++{0x50c7, 0x01},
++{0x50c8, 0x00},
++{0x50c9, 0x00},
++{0x50ca, 0x00},
++{0x50cb, 0x00},
++{0x50cc, 0x00},
++{0x50cd, 0x00},
++{0x50ce, 0x00},
++{0x50cf, 0x00},
++{0x50d0, 0x00},
++{0x50d1, 0x00},
++{0x50d2, 0x00},
++{0x50d3, 0x00},
++{0x50d4, 0x00},
++{0x50d5, 0x00},
++{0x50d6, 0x00},
++{0x50d7, 0x00},
++#ifdef OX03A_DISPLAY_PATTERN_COLOR_BAR
++{0x5100, 0xc0}, /* Rolling test pattern for VS */
++#else
++{0x5100, 0x00},
++#endif
++{0x5101, 0x01},
++{0x5102, 0xb0},
++{0x5103, 0x0f},
++{0x5104, 0x00},
++{0x5105, 0x00},
++{0x5106, 0x00},
++{0x5107, 0x01},
++{0x5108, 0x00},
++{0x5109, 0x00},
++{0x510a, 0x00},
++{0x510b, 0x00},
++{0x510c, 0x00},
++{0x510d, 0x00},
++{0x510e, 0x00},
++{0x510f, 0x00},
++{0x5110, 0x00},
++{0x5111, 0x00},
++{0x5112, 0x00},
++{0x5113, 0x00},
++{0x5114, 0x00},
++{0x5115, 0x00},
++{0x5116, 0x00},
++{0x5117, 0x00},
++/* patch start */
++{0x0325, 0x68},
++{0x0400, 0xe8},
++{0x0401, 0x00},
++{0x0406, 0x35},
++{0x0407, 0x8a},
++{0x0410, 0xe8},
++{0x0411, 0x00},
++{0x0416, 0x35},
++{0x0417, 0x8a},
++{0x3501, 0x01},
++{0x3502, 0x90},
++{0x3508, 0x04},
++{0x3549, 0x80},
++{0x3674, 0x7b},
++{0x3675, 0xb8},
++{0x3676, 0x3e},
++{0x3677, 0xa8},
++{0x384c, 0x03},
++{0x384d, 0xc2},
++{0x4d0e, 0x20},
++{0x3208, 0x04},
++{0x3501, 0x02},
++{0x3508, 0x04},
++{0x3208, 0x14},
++{0x3208, 0x05},
++{0x3501, 0x02},
++{0x3508, 0x04},
++{0x3208, 0x15},
++/* patch end */
++/* patch2 start */
++//{0x3208, 0x03}, // start recording group3
++{0x3501, 0x08}, // HCG exposure integration time MSB
++{0x3502, 0x80}, // HCG exposure integration time LSB
++{0x3508, 0x06}, // HCG real gain
++{0x350a, 0x06}, // HCG digital gain
++{0x3548, 0x06}, // LCG real gain
++{0x354a, 0x06}, // LCG digital gain
++{0x3588, 0x06}, // VS real gain
++{0x358a, 0x06}, // VS digital gain
++//{0x3208, 0x13}, // stop recording group3
++//{0x3208, 0xe3}, // launch group3
++/* patch2 end */
++{0x0100, 0x01},
++};
+diff --git a/drivers/media/i2c/soc_camera/ti9x4.c b/drivers/media/i2c/soc_camera/ti9x4.c
+index 7704bfa..e36ecdb 100644
+--- a/drivers/media/i2c/soc_camera/ti9x4.c
++++ b/drivers/media/i2c/soc_camera/ti9x4.c
+@@ -17,10 +17,9 @@
+ #include <linux/of_graph.h>
+ #include <linux/videodev2.h>
+
+-#include <media/v4l2-async.h>
+ #include <media/v4l2-common.h>
++#include <media/v4l2-clk.h>
+ #include <media/v4l2-device.h>
+-#include <media/v4l2-fwnode.h>
+ #include <media/v4l2-subdev.h>
+
+ #include "ti9x4.h"
+@@ -43,7 +42,11 @@ struct ti9x4_priv {
+ int ti9x3_addr_map[4];
+ char chip_id[6];
+ int ser_id;
++ int vc_map;
++ int csi_map;
++ struct gpio_desc *pwen; /* chip power en */
+ struct gpio_desc *poc_gpio[4]; /* PoC power supply */
++ struct v4l2_clk *ref_clk; /* ref clock */
+ };
+
+ static int ser_id;
+@@ -70,6 +73,14 @@ static int poc_delay;
+ module_param(poc_delay, int, 0644);
+ MODULE_PARM_DESC(poc_delay, " Delay in ms after POC enable (default: 0 ms)");
+
++static int vc_map = 0x3210;
++module_param(vc_map, int, 0644);
++MODULE_PARM_DESC(vc_map, " CSI VC MAP (default: 0xe4 - linear map VCx=LINKx)");
++
++static int csi_map = 0;
++module_param(csi_map, int, 0644);
++MODULE_PARM_DESC(csi_map, " CSI TX MAP (default: 0 - forwarding of all links to CSI0)");
++
+ #ifdef TI954_SILICON_ERRATA
+ static int indirect_write(struct i2c_client *client, unsigned int page, u8 reg, u8 val)
+ {
+@@ -121,29 +132,35 @@ static void ti9x4_initial_setup(struct i2c_client *client)
+ reg8_write(client, 0x0d, 0xb9); /* VDDIO 3.3V */
+ switch (priv->csi_rate) {
+ case 1600: /* REFCLK = 25MHZ */
++ case 1500: /* REFCLK = 23MHZ */
+ case 1450: /* REFCLK = 22.5MHZ */
+ reg8_write(client, 0x1f, 0x00); /* CSI rate 1.5/1.6Gbps */
+ break;
++ case 1200: /* REFCLK = 25MHZ */
++ case 1100: /* REFCLK = 22.5MHZ */
++ reg8_write(client, 0x1f, 0x01); /* CSI rate 1.1/1.2Gbps */
++ break;
+ case 800: /* REFCLK = 25MHZ */
+ case 700: /* REFCLK = 22.5MHZ */
+ reg8_write(client, 0x1f, 0x02); /* CSI rate 700/800Mbps */
+ break;
+ case 400: /* REFCLK = 25MHZ */
+- reg8_write(client, 0x1f, 0x03); /* CSI rate 400Mbps */
++ case 350: /* REFCLK = 22.5MHZ */
++ reg8_write(client, 0x1f, 0x03); /* CSI rate 350/400Mbps */
+ break;
+ default:
+ dev_err(&client->dev, "unsupported CSI rate %d\n", priv->csi_rate);
+ }
+
+ if (strcmp(priv->forwarding_mode, "round-robin") == 0) {
+- reg8_write(client, 0x21, 0x01); /* Round Robin forwarding enable */
++ reg8_write(client, 0x21, 0x03); /* Round Robin forwarding enable for CSI0/CSI1 */
+ } else if (strcmp(priv->forwarding_mode, "synchronized") == 0) {
+- reg8_write(client, 0x21, 0x44); /* Basic Syncronized forwarding enable (FrameSync must be enabled!!) */
++ reg8_write(client, 0x21, 0x54); /* Basic Syncronized forwarding enable (FrameSync must be enabled!!) for CSI0/CSI1 */
+ }
+
+- reg8_write(client, 0x32, 0x01); /* Select TX (CSI) port 0 */
++ reg8_write(client, 0x32, 0x03); /* Select TX for CSI0/CSI1, RX for CSI0 */
+ reg8_write(client, 0x33, ((priv->lanes - 1) ^ 0x3) << 4); /* disable CSI output, set CSI lane count, non-continuous CSI mode */
+- reg8_write(client, 0x20, 0xf0); /* disable port forwarding */
++ reg8_write(client, 0x20, 0xf0 | priv->csi_map); /* disable port forwarding */
+ #if 0
+ /* FrameSync setup for REFCLK=25MHz, FPS=30: period_counts=1/2/FPS*25MHz =1/2/30*25Mhz =416666 -> FS_TIME=416666 */
+ /* FrameSync setup for REFCLK=22.5MHz, FPS=30: period_counts=1/2/FPS*22.5Mhz=1/2/30*22.5Mhz=375000 -> FS_TIME=375000 */
+@@ -156,12 +173,15 @@ static void ti9x4_initial_setup(struct i2c_client *client)
+ #else
+ /* FrameSync setup for REFCLK=25MHz, FPS=30: period_counts=1/FPS/12mks=1/30/12e-6=2777 -> HI=2, LO=2775 */
+ /* FrameSync setup for REFCLK=22.5MHz, FPS=30: period_counts=1/FPS/13.333mks=1/30/13.333e-6=2500 -> HI=2, LO=2498 */
+- #define FS_TIME (priv->csi_rate == 1450 ? (2498+15) : (2775+15))
++// #define FS_TIME (priv->csi_rate == 1450 ? (2498+15) : (2775+15))
++// #define FS_TIME (2498+15)
++ #define FS_TIME (2498+15)
+ reg8_write(client, 0x19, 2 >> 8); /* FrameSync high time MSB */
+ reg8_write(client, 0x1a, 2 & 0xff); /* FrameSync high time LSB */
+ reg8_write(client, 0x1b, FS_TIME >> 8); /* FrameSync low time MSB */
+ reg8_write(client, 0x1c, FS_TIME & 0xff); /* FrameSync low time LSB */
+ reg8_write(client, 0x18, 0x01); /* Enable FrameSync, HI/LO mode, Frame clock from port0 */
++// reg8_write(client, 0x18, 0x80); /* Enable FrameSync, HI/LO mode, Frame clock from port0 */
+ #endif
+ }
+
+@@ -220,10 +240,11 @@ static void ti9x4_fpdlink3_setup(struct i2c_client *client, int idx)
+
+ reg8_write(client, 0x6d, port_config);
+ reg8_write(client, 0x7c, port_config2);
+- reg8_write(client, 0x70, (idx << 6) | 0x1e); /* CSI data type: yuv422 8-bit, assign VC */
+- reg8_write(client, 0x71, (idx << 6) | 0x2a); /* CSI data type: RAW8, assign VC */
++ reg8_write(client, 0x70, ((priv->vc_map >> (idx * 4)) << 6) | 0x1e); /* CSI data type: yuv422 8-bit, assign VC */
++ reg8_write(client, 0x71, ((priv->vc_map >> (idx * 4)) << 6) | 0x2c); /* CSI data type: RAW12, assign VC */
+ reg8_write(client, 0xbc, 0x00); /* Setup minimal time between FV and LV to 3 PCLKs */
+ reg8_write(client, 0x6e, 0x88); /* Sensor reset: backchannel GPIO0/GPIO1 set low */
++ reg8_write(client, 0x72, priv->vc_map >> (idx * 4)); /* CSI VC MAP */
+ }
+
+ static int ti9x4_initialize(struct i2c_client *client)
+@@ -286,10 +307,10 @@ static int ti9x4_s_power(struct v4l2_subdev *sd, int on)
+
+ if (on) {
+ if (atomic_inc_return(&priv->use_count) == 1)
+- reg8_write(client, 0x20, 0x00); /* enable port forwarding to CSI */
++ reg8_write(client, 0x20, 0x00 | priv->csi_map); /* enable port forwarding to CSI */
+ } else {
+ if (atomic_dec_return(&priv->use_count) == 0)
+- reg8_write(client, 0x20, 0xf0); /* disable port forwarding to CSI */
++ reg8_write(client, 0x20, 0xf0 | priv->csi_map); /* disable port forwarding to CSI */
+ }
+
+ return 0;
+@@ -324,7 +345,7 @@ static int ti9x4_parse_dt(struct i2c_client *client)
+ struct device_node *np = client->dev.of_node;
+ struct device_node *endpoint = NULL, *rendpoint = NULL;
+ struct property *prop;
+- int err, pwen, i;
++ int i;
+ int sensor_delay;
+ char forwarding_mode_default[20] = "round-robin"; /* round-robin, synchronized */
+ struct property *csi_rate_prop, *dvp_order_prop;
+@@ -337,18 +358,22 @@ static int ti9x4_parse_dt(struct i2c_client *client)
+ if (of_property_read_u32(np, "ti,lanes", &priv->lanes))
+ priv->lanes = 4;
+
+- pwen = of_get_gpio(np, 0);
+- if (pwen > 0) {
+- err = devm_gpio_request_one(&client->dev, pwen, GPIOF_OUT_INIT_LOW, dev_name(&client->dev));
+- if (err)
+- dev_err(&client->dev, "cannot request PWEN gpio %d: %d\n", pwen, err);
+- else
+- mdelay(250);
++ priv->ref_clk = v4l2_clk_get(&client->dev, "ref_clk");
++ if (!IS_ERR(priv->ref_clk)) {
++ dev_info(&client->dev, "ref_clk = %luKHz", v4l2_clk_get_rate(priv->ref_clk) / 1000);
++ v4l2_clk_enable(priv->ref_clk);
++ }
++
++ priv->pwen = devm_gpiod_get(&client->dev, NULL, GPIOF_OUT_INIT_HIGH);
++ if (!IS_ERR(priv->pwen)) {
++ mdelay(5);
++ gpiod_direction_output(priv->pwen, 0);
++ mdelay(5);
+ }
+
+ for (i = 0; i < 4; i++) {
+ sprintf(poc_name, "POC%d", i);
+- priv->poc_gpio[i] = devm_gpiod_get_optional(&client->dev, poc_name, 0);
++ priv->poc_gpio[i] = devm_gpiod_get_optional(&client->dev, kstrdup(poc_name, GFP_KERNEL), 0);
+ }
+
+ reg8_read(client, 0x00, &val); /* read TI9x4 I2C address */
+@@ -379,13 +404,34 @@ static int ti9x4_parse_dt(struct i2c_client *client)
+ if (of_property_read_u32(np, "ti,dvp_bus", &priv->dvp_bus))
+ priv->dvp_bus = 8;
+ if (of_property_read_u32(np, "ti,hsync", &priv->hsync))
+- priv->vsync = 0;
++ priv->hsync = 0;
+ if (of_property_read_u32(np, "ti,vsync", &priv->vsync))
+ priv->vsync = 1;
+ if (of_property_read_u32(np, "ti,ser_id", &priv->ser_id))
+ priv->ser_id = TI913_ID;
+ if (of_property_read_u32(np, "ti,poc-delay", &priv->poc_delay))
+ priv->poc_delay = 50;
++ if (of_property_read_u32(np, "ti,vc-map", &priv->vc_map))
++ priv->vc_map = 0x3210;
++
++ /*
++ * CSI forwarding of all links is to CSI0 by default.
++ * Decide if any link will be forwarded to CSI1 instead CSI0
++ */
++ prop = of_find_property(np, "ti,csi1-links", NULL);
++ if (prop) {
++ const __be32 *link = NULL;
++ u32 v;
++
++ for (i = 0; i < 4; i++) {
++ link = of_prop_next_u32(prop, link, &v);
++ if (!link)
++ break;
++ priv->csi_map |= BIT(v);
++ }
++ } else {
++ priv->csi_map = 0;
++ }
+
+ /* module params override dts */
+ if (is_stp)
+@@ -400,6 +446,10 @@ static int ti9x4_parse_dt(struct i2c_client *client)
+ priv->ser_id = ser_id;
+ if (poc_delay)
+ priv->poc_delay = poc_delay;
++ if (vc_map != 0x3210)
++ priv->vc_map = vc_map;
++ if (csi_map)
++ priv->csi_map = csi_map;
+
+ for (i = 0; ; i++) {
+ endpoint = of_graph_get_next_endpoint(np, endpoint);
+--
+2.7.4
+
diff --git a/bsp/meta-rcar/meta-rcar-gen3-adas/recipes-kernel/linux/linux-renesas/0132-lvds-ti960-fix-frame-sync-time-for-different-ref-clo.patch b/bsp/meta-rcar/meta-rcar-gen3-adas/recipes-kernel/linux/linux-renesas/0132-lvds-ti960-fix-frame-sync-time-for-different-ref-clo.patch
new file mode 100644
index 00000000..25d424f7
--- /dev/null
+++ b/bsp/meta-rcar/meta-rcar-gen3-adas/recipes-kernel/linux/linux-renesas/0132-lvds-ti960-fix-frame-sync-time-for-different-ref-clo.patch
@@ -0,0 +1,85 @@
+From a3dec1c8cc2b3de7116cede7aa7b2000b800a70d Mon Sep 17 00:00:00 2001
+From: Vladimir Barinov <vladimir.barinov@cogentembedded.com>
+Date: Thu, 8 Nov 2018 21:34:37 +0300
+Subject: [PATCH 081/122] lvds: ti960: fix frame sync time for different ref
+ clock
+
+This fixes frame sync signal for different reference clock
+
+Signed-off-by: Vladimir Barinov <vladimir.barinov@cogentembedded.com>
+---
+ drivers/media/i2c/soc_camera/ti9x4.c | 35 +++++++++++++++++++++++++++--------
+ 1 file changed, 27 insertions(+), 8 deletions(-)
+
+diff --git a/drivers/media/i2c/soc_camera/ti9x4.c b/drivers/media/i2c/soc_camera/ti9x4.c
+index e36ecdb..effcf6c 100644
+--- a/drivers/media/i2c/soc_camera/ti9x4.c
++++ b/drivers/media/i2c/soc_camera/ti9x4.c
+@@ -123,6 +123,7 @@ static void ti9x4_read_chipid(struct i2c_client *client)
+ static void ti9x4_initial_setup(struct i2c_client *client)
+ {
+ struct ti9x4_priv *priv = i2c_get_clientdata(client);
++ int fs_time = 0;
+
+ /* Initial setup */
+ client->addr = priv->des_addr; /* TI9x4 I2C */
+@@ -132,7 +133,7 @@ static void ti9x4_initial_setup(struct i2c_client *client)
+ reg8_write(client, 0x0d, 0xb9); /* VDDIO 3.3V */
+ switch (priv->csi_rate) {
+ case 1600: /* REFCLK = 25MHZ */
+- case 1500: /* REFCLK = 23MHZ */
++ case 1500: /* REFCLK = 23.5MHZ */
+ case 1450: /* REFCLK = 22.5MHZ */
+ reg8_write(client, 0x1f, 0x00); /* CSI rate 1.5/1.6Gbps */
+ break;
+@@ -152,6 +153,29 @@ static void ti9x4_initial_setup(struct i2c_client *client)
+ dev_err(&client->dev, "unsupported CSI rate %d\n", priv->csi_rate);
+ }
+
++ switch (priv->csi_rate) {
++ case 1600:
++ case 1200:
++ case 800:
++ case 400:
++ /* FrameSync setup for REFCLK=25MHz, FPS=30: period_counts=1/FPS/12mks=1/30/12e-6=2777 -> HI=2, LO=2775 */
++ fs_time = 2790;
++ break;
++ case 1500:
++ /* FrameSync setup for REFCLK=23.5MHz, FPS=30: period_counts=1/FPS/12.766mks=1/30/12.766e-6=2612 -> HI=2, LO=2610 */
++ fs_time = 2625;
++ break;
++ case 1450:
++ case 1100:
++ case 700:
++ case 350:
++ /* FrameSync setup for REFCLK=22.5MHz, FPS=30: period_counts=1/FPS/13.333mks=1/30/13.333e-6=2500 -> HI=2, LO=2498 */
++ fs_time = 2513;
++ break;
++ default:
++ dev_err(&client->dev, "unsupported CSI rate %d\n", priv->csi_rate);
++ }
++
+ if (strcmp(priv->forwarding_mode, "round-robin") == 0) {
+ reg8_write(client, 0x21, 0x03); /* Round Robin forwarding enable for CSI0/CSI1 */
+ } else if (strcmp(priv->forwarding_mode, "synchronized") == 0) {
+@@ -171,15 +195,10 @@ static void ti9x4_initial_setup(struct i2c_client *client)
+ reg8_write(client, 0x1c, FS_TIME & 0xff);
+ reg8_write(client, 0x18, 0x43); /* Enable FrameSync, 50/50 mode, Frame clock from 25MHz */
+ #else
+- /* FrameSync setup for REFCLK=25MHz, FPS=30: period_counts=1/FPS/12mks=1/30/12e-6=2777 -> HI=2, LO=2775 */
+- /* FrameSync setup for REFCLK=22.5MHz, FPS=30: period_counts=1/FPS/13.333mks=1/30/13.333e-6=2500 -> HI=2, LO=2498 */
+-// #define FS_TIME (priv->csi_rate == 1450 ? (2498+15) : (2775+15))
+-// #define FS_TIME (2498+15)
+- #define FS_TIME (2498+15)
+ reg8_write(client, 0x19, 2 >> 8); /* FrameSync high time MSB */
+ reg8_write(client, 0x1a, 2 & 0xff); /* FrameSync high time LSB */
+- reg8_write(client, 0x1b, FS_TIME >> 8); /* FrameSync low time MSB */
+- reg8_write(client, 0x1c, FS_TIME & 0xff); /* FrameSync low time LSB */
++ reg8_write(client, 0x1b, fs_time >> 8); /* FrameSync low time MSB */
++ reg8_write(client, 0x1c, fs_time & 0xff); /* FrameSync low time LSB */
+ reg8_write(client, 0x18, 0x01); /* Enable FrameSync, HI/LO mode, Frame clock from port0 */
+ // reg8_write(client, 0x18, 0x80); /* Enable FrameSync, HI/LO mode, Frame clock from port0 */
+ #endif
+--
+2.7.4
+
diff --git a/bsp/meta-rcar/meta-rcar-gen3-adas/recipes-kernel/linux/linux-renesas/0133-lvds-add-AR0323-imager.patch b/bsp/meta-rcar/meta-rcar-gen3-adas/recipes-kernel/linux/linux-renesas/0133-lvds-add-AR0323-imager.patch
new file mode 100644
index 00000000..332de5b9
--- /dev/null
+++ b/bsp/meta-rcar/meta-rcar-gen3-adas/recipes-kernel/linux/linux-renesas/0133-lvds-add-AR0323-imager.patch
@@ -0,0 +1,1998 @@
+From 0ae24c08919a48946c7a91762938ef2888d9ab90 Mon Sep 17 00:00:00 2001
+From: Vladimir Barinov <vladimir.barinov@cogentembedded.com>
+Date: Tue, 13 Nov 2018 02:06:40 +0300
+Subject: [PATCH 082/122] lvds: add AR0323 imager
+
+This adds AR0323 imager support
+
+Signed-off-by: Vladimir Barinov <vladimir.barinov@cogentembedded.com>
+---
+ drivers/media/i2c/soc_camera/ar0323.c | 581 ++++++++++++++
+ drivers/media/i2c/soc_camera/ar0323.h | 1335 ++++++++++++++++++++++++++++++++
+ drivers/media/i2c/soc_camera/ov106xx.c | 13 +-
+ 3 files changed, 1928 insertions(+), 1 deletion(-)
+ create mode 100644 drivers/media/i2c/soc_camera/ar0323.c
+ create mode 100644 drivers/media/i2c/soc_camera/ar0323.h
+
+diff --git a/drivers/media/i2c/soc_camera/ar0323.c b/drivers/media/i2c/soc_camera/ar0323.c
+new file mode 100644
+index 0000000..467367b
+--- /dev/null
++++ b/drivers/media/i2c/soc_camera/ar0323.c
+@@ -0,0 +1,581 @@
++/*
++ * ON Semiconductor AR0323 sensor camera driver
++ *
++ * Copyright (C) 2018 Cogent Embedded, Inc.
++ *
++ * This program is free software; you can redistribute it and/or modify it
++ * under the terms of the GNU General Public License as published by the
++ * Free Software Foundation; either version 2 of the License, or (at your
++ * option) any later version.
++ */
++
++#include <linux/delay.h>
++#include <linux/init.h>
++#include <linux/i2c.h>
++#include <linux/module.h>
++#include <linux/of_graph.h>
++#include <linux/videodev2.h>
++
++#include <media/soc_camera.h>
++#include <media/v4l2-common.h>
++#include <media/v4l2-ctrls.h>
++
++#include "ar0323.h"
++
++#define AR0323_I2C_ADDR 0x10
++
++#define AR0323_PID 0x3000
++#define AR0323_VERSION_REG 0x0D56
++
++#define AR0323_MEDIA_BUS_FMT MEDIA_BUS_FMT_SGRBG12_1X12
++
++struct ar0323_priv {
++ struct v4l2_subdev sd;
++ struct v4l2_ctrl_handler hdl;
++ struct media_pad pad;
++ struct v4l2_rect rect;
++ int init_complete;
++ u8 id[6];
++ /* serializers */
++ int ti9x4_addr;
++ int ti9x3_addr;
++ int port;
++ int gpio_resetb;
++ int gpio_fsin;
++};
++
++static inline struct ar0323_priv *to_ar0323(const struct i2c_client *client)
++{
++ return container_of(i2c_get_clientdata(client), struct ar0323_priv, sd);
++}
++
++static int ar0323_set_regs(struct i2c_client *client,
++ const struct ar0323_reg *regs, int nr_regs)
++{
++ int i;
++
++ for (i = 0; i < nr_regs; i++) {
++ if (regs[i].reg == AR0323_DELAY) {
++ mdelay(regs[i].val);
++ continue;
++ }
++
++ reg16_write16(client, regs[i].reg, regs[i].val);
++ }
++
++ return 0;
++}
++
++static int ar0323_s_stream(struct v4l2_subdev *sd, int enable)
++{
++ return 0;
++}
++
++static int ar0323_get_fmt(struct v4l2_subdev *sd,
++ struct v4l2_subdev_pad_config *cfg,
++ struct v4l2_subdev_format *format)
++{
++ struct v4l2_mbus_framefmt *mf = &format->format;
++ struct i2c_client *client = v4l2_get_subdevdata(sd);
++ struct ar0323_priv *priv = to_ar0323(client);
++
++ if (format->pad)
++ return -EINVAL;
++
++ mf->width = priv->rect.width;
++ mf->height = priv->rect.height;
++ mf->code = AR0323_MEDIA_BUS_FMT;
++ mf->colorspace = V4L2_COLORSPACE_SMPTE170M;
++ mf->field = V4L2_FIELD_NONE;
++
++ return 0;
++}
++
++static int ar0323_set_fmt(struct v4l2_subdev *sd,
++ struct v4l2_subdev_pad_config *cfg,
++ struct v4l2_subdev_format *format)
++{
++ struct v4l2_mbus_framefmt *mf = &format->format;
++
++ mf->code = AR0323_MEDIA_BUS_FMT;
++ mf->colorspace = V4L2_COLORSPACE_SMPTE170M;
++ mf->field = V4L2_FIELD_NONE;
++
++ if (format->which == V4L2_SUBDEV_FORMAT_TRY)
++ cfg->try_fmt = *mf;
++
++ return 0;
++}
++
++static int ar0323_enum_mbus_code(struct v4l2_subdev *sd,
++ struct v4l2_subdev_pad_config *cfg,
++ struct v4l2_subdev_mbus_code_enum *code)
++{
++ if (code->pad || code->index > 0)
++ return -EINVAL;
++
++ code->code = AR0323_MEDIA_BUS_FMT;
++
++ return 0;
++}
++
++static int ar0323_get_edid(struct v4l2_subdev *sd, struct v4l2_edid *edid)
++{
++ struct i2c_client *client = v4l2_get_subdevdata(sd);
++ struct ar0323_priv *priv = to_ar0323(client);
++
++ memcpy(edid->edid, priv->id, 6);
++
++ edid->edid[6] = 0xff;
++ edid->edid[7] = client->addr;
++ edid->edid[8] = AR0323_VERSION_REG >> 8;
++ edid->edid[9] = AR0323_VERSION_REG & 0xff;
++
++ return 0;
++}
++
++static int ar0323_set_selection(struct v4l2_subdev *sd,
++ struct v4l2_subdev_pad_config *cfg,
++ struct v4l2_subdev_selection *sel)
++{
++ struct v4l2_rect *rect = &sel->r;
++ struct i2c_client *client = v4l2_get_subdevdata(sd);
++ struct ar0323_priv *priv = to_ar0323(client);
++
++ if (sel->which != V4L2_SUBDEV_FORMAT_ACTIVE ||
++ sel->target != V4L2_SEL_TGT_CROP)
++ return -EINVAL;
++
++ rect->left = ALIGN(rect->left, 2);
++ rect->top = ALIGN(rect->top, 2);
++ rect->width = ALIGN(rect->width, 2);
++ rect->height = ALIGN(rect->height, 2);
++
++ if ((rect->left + rect->width > AR0323_MAX_WIDTH) ||
++ (rect->top + rect->height > AR0323_MAX_HEIGHT))
++ *rect = priv->rect;
++
++ priv->rect.left = rect->left;
++ priv->rect.top = rect->top;
++ priv->rect.width = rect->width;
++ priv->rect.height = rect->height;
++
++ return 0;
++}
++
++static int ar0323_get_selection(struct v4l2_subdev *sd,
++ struct v4l2_subdev_pad_config *cfg,
++ struct v4l2_subdev_selection *sel)
++{
++ struct i2c_client *client = v4l2_get_subdevdata(sd);
++ struct ar0323_priv *priv = to_ar0323(client);
++
++ if (sel->which != V4L2_SUBDEV_FORMAT_ACTIVE)
++ return -EINVAL;
++
++ switch (sel->target) {
++ case V4L2_SEL_TGT_CROP_BOUNDS:
++ sel->r.left = 0;
++ sel->r.top = 0;
++ sel->r.width = AR0323_MAX_WIDTH;
++ sel->r.height = AR0323_MAX_HEIGHT;
++ return 0;
++ case V4L2_SEL_TGT_CROP_DEFAULT:
++ sel->r.left = 0;
++ sel->r.top = 0;
++ sel->r.width = AR0323_MAX_WIDTH;
++ sel->r.height = AR0323_MAX_HEIGHT;
++ return 0;
++ case V4L2_SEL_TGT_CROP:
++ sel->r = priv->rect;
++ return 0;
++ default:
++ return -EINVAL;
++ }
++}
++
++static int ar0323_g_mbus_config(struct v4l2_subdev *sd,
++ struct v4l2_mbus_config *cfg)
++{
++ cfg->flags = V4L2_MBUS_CSI2_1_LANE | V4L2_MBUS_CSI2_CHANNEL_0 |
++ V4L2_MBUS_CSI2_CONTINUOUS_CLOCK;
++ cfg->type = V4L2_MBUS_CSI2;
++
++ return 0;
++}
++
++#ifdef CONFIG_VIDEO_ADV_DEBUG
++static int ar0323_g_register(struct v4l2_subdev *sd,
++ struct v4l2_dbg_register *reg)
++{
++ struct i2c_client *client = v4l2_get_subdevdata(sd);
++ int ret;
++ u16 val = 0;
++
++ ret = reg16_read16(client, (u16)reg->reg, &val);
++ if (ret < 0)
++ return ret;
++
++ reg->val = val;
++ reg->size = sizeof(u16);
++
++ return 0;
++}
++
++static int ar0323_s_register(struct v4l2_subdev *sd,
++ const struct v4l2_dbg_register *reg)
++{
++ struct i2c_client *client = v4l2_get_subdevdata(sd);
++
++ return reg16_write16(client, (u16)reg->reg, (u16)reg->val);
++}
++#endif
++
++static struct v4l2_subdev_core_ops ar0323_core_ops = {
++#ifdef CONFIG_VIDEO_ADV_DEBUG
++ .g_register = ar0323_g_register,
++ .s_register = ar0323_s_register,
++#endif
++};
++
++static int ar0323_s_ctrl(struct v4l2_ctrl *ctrl)
++{
++ struct v4l2_subdev *sd = to_sd(ctrl);
++ struct i2c_client *client = v4l2_get_subdevdata(sd);
++ struct ar0323_priv *priv = to_ar0323(client);
++ int ret = -EINVAL;
++ u16 val = 0;
++
++ if (!priv->init_complete)
++ return 0;
++
++ switch (ctrl->id) {
++ case V4L2_CID_BRIGHTNESS:
++ case V4L2_CID_CONTRAST:
++ case V4L2_CID_SATURATION:
++ case V4L2_CID_HUE:
++ case V4L2_CID_GAMMA:
++ case V4L2_CID_SHARPNESS:
++ case V4L2_CID_AUTOGAIN:
++ break;
++ case V4L2_CID_GAIN:
++ /* Digital gain */
++ ret = reg16_write16(client, 0x3308, ctrl->val);
++ break;
++ case V4L2_CID_ANALOGUE_GAIN:
++ /* Analog gain */
++ ret = reg16_write16(client, 0x3366, (ctrl->val << 8) | (ctrl->val << 4) | ctrl->val);
++ break;
++ case V4L2_CID_EXPOSURE:
++ /* T1 exposure */
++ ret = reg16_write16(client, 0x3012, ctrl->val);
++ break;
++ case V4L2_CID_HFLIP:
++ ret = reg16_read16(client, 0x3040, &val);
++ if (ctrl->val)
++ val |= (1 << 14);
++ else
++ val &= ~(1 << 14);
++ ret |= reg16_write16(client, 0x3040, val);
++ break;
++ case V4L2_CID_VFLIP:
++ ret = reg16_read16(client, 0x3040, &val);
++ if (ctrl->val)
++ val |= (1 << 15);
++ else
++ val &= ~(1 << 15);
++ ret |= reg16_write16(client, 0x3040, val);
++ break;
++ case V4L2_CID_MIN_BUFFERS_FOR_CAPTURE:
++ ret = 0;
++ break;
++ }
++
++ return ret;
++}
++
++static const struct v4l2_ctrl_ops ar0323_ctrl_ops = {
++ .s_ctrl = ar0323_s_ctrl,
++};
++
++static struct v4l2_subdev_video_ops ar0323_video_ops = {
++ .s_stream = ar0323_s_stream,
++ .g_mbus_config = ar0323_g_mbus_config,
++};
++
++static const struct v4l2_subdev_pad_ops ar0323_subdev_pad_ops = {
++ .get_edid = ar0323_get_edid,
++ .enum_mbus_code = ar0323_enum_mbus_code,
++ .get_selection = ar0323_get_selection,
++ .set_selection = ar0323_set_selection,
++ .get_fmt = ar0323_get_fmt,
++ .set_fmt = ar0323_set_fmt,
++};
++
++static struct v4l2_subdev_ops ar0323_subdev_ops = {
++ .core = &ar0323_core_ops,
++ .video = &ar0323_video_ops,
++ .pad = &ar0323_subdev_pad_ops,
++};
++
++static void ar0323_otp_id_read(struct i2c_client *client)
++{
++ struct ar0323_priv *priv = to_ar0323(client);
++ int i;
++ u16 val = 0;
++
++ /* read camera id from ar014x OTP memory */
++ reg16_write16(client, 0x3054, 0x400);
++ reg16_write16(client, 0x304a, 0x110);
++ usleep_range(25000, 25500); /* wait 25 ms */
++
++ for (i = 0; i < 6; i += 2) {
++ /* first 4 bytes are equal on all ar014x */
++ reg16_read16(client, 0x3800 + i + 4, &val);
++ priv->id[i] = val >> 8;
++ priv->id[i + 1] = val & 0xff;
++ }
++}
++
++static ssize_t ar0323_otp_id_show(struct device *dev,
++ struct device_attribute *attr, char *buf)
++{
++ struct v4l2_subdev *sd = i2c_get_clientdata(to_i2c_client(dev));
++ struct i2c_client *client = v4l2_get_subdevdata(sd);
++ struct ar0323_priv *priv = to_ar0323(client);
++
++ ar0323_otp_id_read(client);
++
++ return snprintf(buf, 32, "%02x:%02x:%02x:%02x:%02x:%02x\n",
++ priv->id[0], priv->id[1], priv->id[2], priv->id[3], priv->id[4], priv->id[5]);
++}
++
++static DEVICE_ATTR(otp_id_ar0323, S_IRUGO, ar0323_otp_id_show, NULL);
++
++static int ar0323_initialize(struct i2c_client *client)
++{
++ struct ar0323_priv *priv = to_ar0323(client);
++ u16 val = 0;
++ u16 pid = 0;
++ int ret = 0;
++// int tmp_addr;
++
++ /* check and show model ID */
++ reg16_read16(client, AR0323_PID, &pid);
++
++ if (pid != AR0323_VERSION_REG) {
++ dev_dbg(&client->dev, "Product ID error %x\n\n\n\n", pid);
++ ret = -ENODEV;
++ goto err;
++ }
++
++#if 0
++ /* setup XCLK */
++ tmp_addr = client->addr;
++ if (priv->ti9x4_addr) {
++ /* CLK_OUT=22.5792*160*M/N/CLKDIV -> CLK_OUT=27MHz: CLKDIV=2, M=15, N=251: 22.5792*160/8*15/251=26.987MHz=CLK_OUT */
++ client->addr = priv->ti9x3_addr; /* Serializer I2C address */
++ reg8_write(client, 0x06, 0x6f); /* Set CLKDIV and M */
++ reg8_write(client, 0x07, 0xfb); /* Set N */
++ reg8_write(client, 0x0e, 0x1f); /* Set FSIN GPIO to output */
++ }
++ client->addr = tmp_addr;
++#endif
++
++ /* Program wizard registers */
++ ar0323_set_regs(client, ar0323_regs_wizard, ARRAY_SIZE(ar0323_regs_wizard));
++
++ /* Enable stream */
++ reg16_read16(client, 0x301a, &val); // read inital reset_register value
++ val |= (1 << 2); // Set streamOn bit
++ reg16_write16(client, 0x301a, val); // Start Streaming
++
++ /* Read OTP IDs */
++ ar0323_otp_id_read(client);
++
++ dev_info(&client->dev, "ar0323 PID %x, res %dx%d, OTP_ID %02x:%02x:%02x:%02x:%02x:%02x\n",
++ pid, AR0323_MAX_WIDTH, AR0323_MAX_HEIGHT, priv->id[0], priv->id[1], priv->id[2], priv->id[3], priv->id[4], priv->id[5]);
++err:
++ return ret;
++}
++
++static int ar0323_parse_dt(struct device_node *np, struct ar0323_priv *priv)
++{
++ struct i2c_client *client = v4l2_get_subdevdata(&priv->sd);
++ int i;
++ struct device_node *endpoint = NULL, *rendpoint = NULL;
++ int tmp_addr = 0;
++
++ for (i = 0; ; i++) {
++ endpoint = of_graph_get_next_endpoint(np, endpoint);
++ if (!endpoint)
++ break;
++
++ of_node_put(endpoint);
++
++ rendpoint = of_parse_phandle(endpoint, "remote-endpoint", 0);
++ if (!rendpoint)
++ continue;
++
++ if (!of_property_read_u32(rendpoint, "ti9x3-addr", &priv->ti9x3_addr) &&
++ !of_property_match_string(rendpoint->parent->parent, "compatible", "ti,ti9x4") &&
++ !of_property_read_u32(rendpoint->parent->parent, "reg", &priv->ti9x4_addr) &&
++ !kstrtouint(strrchr(rendpoint->full_name, '@') + 1, 0, &priv->port))
++ break;
++ }
++
++ if (!priv->ti9x4_addr) {
++ dev_err(&client->dev, "deserializer does not present\n");
++ return -EINVAL;
++ }
++
++ /* setup I2C translator address */
++ tmp_addr = client->addr;
++ if (priv->ti9x4_addr) {
++ client->addr = priv->ti9x4_addr; /* Deserializer I2C address */
++
++ reg8_write(client, 0x4c, (priv->port << 4) | (1 << priv->port)); /* Select RX port number */
++ usleep_range(2000, 2500); /* wait 2ms */
++ reg8_write(client, 0x65, tmp_addr << 1); /* Sensor translated I2C address */
++ reg8_write(client, 0x5d, AR0323_I2C_ADDR << 1); /* Sensor native I2C address */
++
++// reg8_write(client, 0x6e, 0xa9); /* GPIO0 - reset, GPIO1 - fsin ??????? */
++ }
++ client->addr = tmp_addr;
++
++ mdelay(10);
++
++ return 0;
++}
++
++static int ar0323_probe(struct i2c_client *client,
++ const struct i2c_device_id *did)
++{
++ struct ar0323_priv *priv;
++ int ret;
++
++ priv = devm_kzalloc(&client->dev, sizeof(*priv), GFP_KERNEL);
++ if (!priv)
++ return -ENOMEM;
++
++ v4l2_i2c_subdev_init(&priv->sd, client, &ar0323_subdev_ops);
++ priv->sd.flags = V4L2_SUBDEV_FL_HAS_DEVNODE;
++
++ v4l2_ctrl_handler_init(&priv->hdl, 4);
++ v4l2_ctrl_new_std(&priv->hdl, &ar0323_ctrl_ops,
++ V4L2_CID_BRIGHTNESS, 0, 16, 1, 7);
++ v4l2_ctrl_new_std(&priv->hdl, &ar0323_ctrl_ops,
++ V4L2_CID_CONTRAST, 0, 16, 1, 7);
++ v4l2_ctrl_new_std(&priv->hdl, &ar0323_ctrl_ops,
++ V4L2_CID_SATURATION, 0, 7, 1, 2);
++ v4l2_ctrl_new_std(&priv->hdl, &ar0323_ctrl_ops,
++ V4L2_CID_HUE, 0, 23, 1, 12);
++ v4l2_ctrl_new_std(&priv->hdl, &ar0323_ctrl_ops,
++ V4L2_CID_GAMMA, -128, 128, 1, 0);
++ v4l2_ctrl_new_std(&priv->hdl, &ar0323_ctrl_ops,
++ V4L2_CID_SHARPNESS, 0, 10, 1, 3);
++ v4l2_ctrl_new_std(&priv->hdl, &ar0323_ctrl_ops,
++ V4L2_CID_AUTOGAIN, 0, 1, 1, 0);
++ v4l2_ctrl_new_std(&priv->hdl, &ar0323_ctrl_ops,
++ V4L2_CID_GAIN, 1, 0x7ff, 1, 0x200);
++ v4l2_ctrl_new_std(&priv->hdl, &ar0323_ctrl_ops,
++ V4L2_CID_ANALOGUE_GAIN, 1, 0xe, 1, 0xa);
++ v4l2_ctrl_new_std(&priv->hdl, &ar0323_ctrl_ops,
++ V4L2_CID_EXPOSURE, 1, 0x600, 1, 0x144);
++ v4l2_ctrl_new_std(&priv->hdl, &ar0323_ctrl_ops,
++ V4L2_CID_HFLIP, 0, 1, 1, 0);
++ v4l2_ctrl_new_std(&priv->hdl, &ar0323_ctrl_ops,
++ V4L2_CID_VFLIP, 0, 1, 1, 0);
++ priv->sd.ctrl_handler = &priv->hdl;
++
++ ret = priv->hdl.error;
++ if (ret)
++ goto cleanup;
++
++ v4l2_ctrl_handler_setup(&priv->hdl);
++
++ priv->pad.flags = MEDIA_PAD_FL_SOURCE;
++ priv->sd.entity.flags |= MEDIA_ENT_F_CAM_SENSOR;
++ ret = media_entity_pads_init(&priv->sd.entity, 1, &priv->pad);
++ if (ret < 0)
++ goto cleanup;
++
++ ret = ar0323_parse_dt(client->dev.of_node, priv);
++ if (ret)
++ goto cleanup;
++
++ ret = ar0323_initialize(client);
++ if (ret < 0)
++ goto cleanup;
++
++ priv->rect.left = 0;
++ priv->rect.top = 0;
++ priv->rect.width = AR0323_MAX_WIDTH;
++ priv->rect.height = AR0323_MAX_HEIGHT;
++
++ ret = v4l2_async_register_subdev(&priv->sd);
++ if (ret)
++ goto cleanup;
++
++ if (device_create_file(&client->dev, &dev_attr_otp_id_ar0323) != 0) {
++ dev_err(&client->dev, "sysfs otp_id entry creation failed\n");
++ goto cleanup;
++ }
++
++ priv->init_complete = 1;
++
++ return 0;
++
++cleanup:
++ media_entity_cleanup(&priv->sd.entity);
++ v4l2_ctrl_handler_free(&priv->hdl);
++ v4l2_device_unregister_subdev(&priv->sd);
++#ifdef CONFIG_SOC_CAMERA_AR0323
++ v4l_err(client, "failed to probe @ 0x%02x (%s)\n",
++ client->addr, client->adapter->name);
++#endif
++ return ret;
++}
++
++static int ar0323_remove(struct i2c_client *client)
++{
++ struct ar0323_priv *priv = i2c_get_clientdata(client);
++
++ device_remove_file(&client->dev, &dev_attr_otp_id_ar0323);
++ v4l2_async_unregister_subdev(&priv->sd);
++ media_entity_cleanup(&priv->sd.entity);
++ v4l2_ctrl_handler_free(&priv->hdl);
++ v4l2_device_unregister_subdev(&priv->sd);
++
++ return 0;
++}
++
++#ifdef CONFIG_SOC_CAMERA_AR0323
++static const struct i2c_device_id ar0323_id[] = {
++ { "ar0323", 0 },
++ { }
++};
++MODULE_DEVICE_TABLE(i2c, ar0323_id);
++
++static const struct of_device_id ar0323_of_ids[] = {
++ { .compatible = "aptina,ar0323", },
++ { }
++};
++MODULE_DEVICE_TABLE(of, ar0323_of_ids);
++
++static struct i2c_driver ar0323_i2c_driver = {
++ .driver = {
++ .name = "ar0323",
++ .of_match_table = ar0323_of_ids,
++ },
++ .probe = ar0323_probe,
++ .remove = ar0323_remove,
++ .id_table = ar0323_id,
++};
++
++module_i2c_driver(ar0323_i2c_driver);
++
++MODULE_DESCRIPTION("SoC Camera driver for AR0323");
++MODULE_AUTHOR("Vladimir Barinov");
++MODULE_LICENSE("GPL");
++#endif
+diff --git a/drivers/media/i2c/soc_camera/ar0323.h b/drivers/media/i2c/soc_camera/ar0323.h
+new file mode 100644
+index 0000000..0711dd8
+--- /dev/null
++++ b/drivers/media/i2c/soc_camera/ar0323.h
+@@ -0,0 +1,1335 @@
++/*
++ * ON Semiconductor AR0323 sensor camera wizard 1920x1080@30/BGGR/MIPI
++ *
++ * Copyright (C) 2018 Cogent Embedded, Inc.
++ *
++ * This program is free software; you can redistribute it and/or modify it
++ * under the terms of the GNU General Public License as published by the
++ * Free Software Foundation; either version 2 of the License, or (at your
++ * option) any later version.
++ */
++
++//#define AR0323_DISPLAY_PATTERN_FIXED
++//#define AR0323_DISPLAY_PATTERN_COLOR_BAR
++
++#define AR0323_MAX_WIDTH 2560
++#define AR0323_MAX_HEIGHT 1080
++
++#define AR0323_DELAY 0xffff
++
++#define AR0323_SENSOR_WIDTH 2880
++#define AR0323_SENSOR_HEIGHT 1080
++
++#define AR0323_X_START ((AR0323_SENSOR_WIDTH - AR0323_MAX_WIDTH) / 2)
++#define AR0323_Y_START ((AR0323_SENSOR_HEIGHT - AR0323_MAX_HEIGHT) / 2)
++#define AR0323_X_END (AR0323_X_START + AR0323_MAX_WIDTH - 1)
++#define AR0323_Y_END (AR0323_Y_START + AR0323_MAX_HEIGHT - 1)
++
++struct ar0323_reg {
++ u16 reg;
++ u16 val;
++};
++
++static const struct ar0323_reg ar0323_regs_wizard[] = {
++#if 0
++{0x301A, 0x0018}, // RESET_REGISTER
++{AR0323_DELAY, 500}, // Wait 500ms
++{0x3070, 0x0000}, // 1: Solid color test pattern,
++ // 2: Full color bar test pattern,
++ // 3: Fade to grey color bar test pattern,
++ //256: Walking 1 test pattern (12 bit)
++{0x3072, 0x0123}, // R
++{0x3074, 0x0456}, // G(GR row)
++{0x3076, 0x0abc}, // B
++{0x3078, 0x0def}, // G(GB row)
++#ifdef AR0323_DISPLAY_PATTERN_FIXED
++{0x3070, 0x0001},
++#endif
++#ifdef AR0323_DISPLAY_PATTERN_COLOR_BAR
++{0x3070, 0x0002},
++#endif
++{AR0323_DELAY, 100}, // Wait 100ms
++#endif
++
++{0x301A, 0x0059}, // RESET_REGISTER
++{0x301A, 0x0058}, // RESET_REGISTER
++{AR0323_DELAY, 200}, // Wait 200ms
++
++//continuous MIPI 12bit
++{0x3342, 0x122C}, // MIPI_F1_PDT_EDT
++{0x3346, 0x122C}, // MIPI_F2_PDT_EDT
++{0x334A, 0x122C}, // MIPI_F3_PDT_EDT
++{0x334E, 0x122C}, // MIPI_F4_PDT_EDT
++
++//PLL settings
++{0x302E, 0x0002}, // PRE_PLL_CLK_DIV
++{0x3030, 0x0052}, // PLL_MULTIPLIER
++{0x302C, 0x0001}, // VT_SYS_CLK_DIV
++{0x302A, 0x0008}, // VT_PIX_CLK_DIV
++{0x3038, 0x0004}, // OP_SYS_CLK_DIV
++{0x3036, 0x0006}, // OP_WORD_CLK_DIV
++
++//MIPI timing
++{0x31B0, 0x0059}, // FRAME_PREAMBLE
++{0x31B2, 0x003B}, // LINE_PREAMBLE
++{0x31B4, 0x31C5}, // MIPI_TIMING_0
++{0x31B6, 0x114E}, // MIPI_TIMING_1
++{0x31B8, 0x5048}, // MIPI_TIMING_2
++{0x31BA, 0x0186}, // MIPI_TIMING_3
++{0x31BC, 0x8885}, // MIPI_TIMING_4
++
++//HDR
++{0x3E00, 0x8000}, // LFM2_T1_CTRL
++{0x3082, 0x0004}, // OPERATION_MODE_CTRL
++{0x30BA, 0x1103}, // DIGITAL_CTRL
++
++//new sequencer
++{0x2512, 0x8000},
++{0x2510, 0x0712},
++{0x2510, 0x1314},
++{0x2510, 0x1518},
++{0x2510, 0xffff},
++{0x2510, 0xffff},
++{0x2510, 0xffff},
++{0x2510, 0xffff},
++{0x2510, 0xffff},
++{0x2510, 0x1b1d},
++{0x2510, 0x2224},
++{0x2510, 0x2628},
++{0x2510, 0xffff},
++{0x2510, 0x2a48},
++{0x2510, 0x5672},
++{0x2510, 0x7f85},
++{0x2510, 0x8991},
++{0x2510, 0xaeb3},
++{0x2510, 0xbdc4},
++{0x2510, 0xc5c8},
++{0x2510, 0xccd0},
++{0x2510, 0xd4d6},
++{0x2510, 0xd8dd},
++{0x2510, 0xdfe2},
++{0x2510, 0xe5e8},
++{0x2510, 0xffff},
++{0x2510, 0xffff},
++{0x2510, 0xffff},
++{0x2510, 0xffff},
++{0x2510, 0xc003},
++{0x2510, 0xa0e0},
++{0x2510, 0x3041},
++{0x2510, 0x3042},
++{0x2510, 0x2000},
++{0x2510, 0x3048},
++{0x2510, 0x3081},
++{0x2510, 0x3084},
++{0x2510, 0x3082},
++{0x2510, 0x2003},
++{0x2510, 0x3044},
++{0x2510, 0x2000},
++{0x2510, 0xa004},
++{0x2510, 0x20ff},
++{0x2510, 0x20ff},
++{0x2510, 0x20ff},
++{0x2510, 0x20ff},
++{0x2510, 0x20ff},
++{0x2510, 0x807c},
++{0x2510, 0xa0e0},
++{0x2510, 0x3041},
++{0x2510, 0x3042},
++{0x2510, 0x2000},
++{0x2510, 0xa0c0},
++{0x2510, 0x9008},
++{0x2510, 0x8802},
++{0x2510, 0x20ff},
++{0x2510, 0x20ff},
++{0x2510, 0x20ff},
++{0x2510, 0x20ff},
++{0x2510, 0x20ff},
++{0x2510, 0x9018},
++{0x2510, 0x891a},
++{0x2510, 0x807c},
++{0x2510, 0x20ff},
++{0x2510, 0x895b},
++{0x2510, 0x20ff},
++{0x2510, 0x897b},
++{0x2510, 0x20ff},
++{0x2510, 0x897f},
++{0x2510, 0x20ff},
++{0x2510, 0x7fff},
++{0x2510, 0x7fff},
++{0x2510, 0x7fff},
++{0x2510, 0x20ff},
++{0x2510, 0x7fff},
++{0x2510, 0x7fff},
++{0x2510, 0x7fff},
++{0x2510, 0x20ff},
++{0x2510, 0x7fff},
++{0x2510, 0x7fff},
++{0x2510, 0x7fff},
++{0x2510, 0x20ff},
++{0x2510, 0x7fff},
++{0x2510, 0x7fff},
++{0x2510, 0x7fff},
++{0x2510, 0xa0c4},
++{0x2510, 0x20ff},
++{0x2510, 0x8058},
++{0x2510, 0x9039},
++{0x2510, 0x20ff},
++{0x2510, 0x907f},
++{0x2510, 0x895b},
++{0x2510, 0x2064},
++{0x2510, 0x891b},
++{0x2510, 0x2010},
++{0x2510, 0x8803},
++{0x2510, 0x7fff},
++{0x2510, 0x3088},
++{0x2510, 0x3090},
++{0x2510, 0x20ff},
++{0x2510, 0x906b},
++{0x2510, 0x2064},
++{0x2510, 0x3084},
++{0x2510, 0x2003},
++{0x2510, 0x3044},
++{0x2510, 0x2000},
++{0x2510, 0xa004},
++{0x2510, 0x7fff},
++{0x2510, 0x7fff},
++{0x2510, 0x2400},
++{0x2510, 0x2401},
++{0x2510, 0x3244},
++{0x2510, 0x7fff},
++{0x2510, 0x7fff},
++{0x2510, 0x7fff},
++{0x2510, 0x7fff},
++{0x2510, 0x7fff},
++{0x2510, 0x2400},
++{0x2510, 0x2401},
++{0x2510, 0x2702},
++{0x2510, 0x3242},
++{0x2510, 0x2420},
++{0x2510, 0x2702},
++{0x2510, 0x2421},
++{0x2510, 0x2703},
++{0x2510, 0x3242},
++{0x2510, 0x2420},
++{0x2510, 0x2703},
++{0x2510, 0x2421},
++{0x2510, 0x2704},
++{0x2510, 0x3242},
++{0x2510, 0x2420},
++{0x2510, 0x2704},
++{0x2510, 0x2421},
++{0x2510, 0x3244},
++{0x2510, 0x7fff},
++{0x2510, 0x7fff},
++{0x2510, 0x2402},
++{0x2510, 0x2403},
++{0x2510, 0x3244},
++{0x2510, 0x7fff},
++{0x2510, 0x7fff},
++{0x2510, 0x7fff},
++{0x2510, 0x7fff},
++{0x2510, 0x7fff},
++{0x2510, 0x2741},
++{0x2510, 0x2429},
++{0x2510, 0x2740},
++{0x2510, 0x242a},
++{0x2510, 0x3244},
++{0x2510, 0x7fff},
++{0x2510, 0x7fff},
++{0x2510, 0x7fff},
++{0x2510, 0x2404},
++{0x2510, 0x2779},
++{0x2510, 0x242c},
++{0x2510, 0x2781},
++{0x2510, 0x242d},
++{0x2510, 0x3244},
++{0x2510, 0x7fff},
++{0x2510, 0x7fff},
++{0x2510, 0x2703},
++{0x2510, 0x2432},
++{0x2510, 0x3244},
++{0x2510, 0x7fff},
++{0x2510, 0x7fff},
++{0x2510, 0x7fff},
++{0x2510, 0x7fff},
++{0x2510, 0x7fff},
++{0x2510, 0xb800},
++{0x2510, 0x8058},
++{0x2510, 0xa005},
++{0x2510, 0x30c1},
++{0x2510, 0x3101},
++{0x2510, 0x3041},
++{0x2510, 0x3041},
++{0x2510, 0x3250},
++{0x2510, 0x3108},
++{0x2510, 0x3104},
++{0x2510, 0x3102},
++{0x2510, 0x3041},
++{0x2510, 0xf860},
++{0x2510, 0xb095},
++{0x2510, 0x3141},
++{0x2510, 0x3042},
++{0x2510, 0xb848},
++{0x2510, 0xb84c},
++{0x2510, 0x8843},
++{0x2510, 0x916f},
++{0x2510, 0x3110},
++{0x2510, 0x3042},
++{0x2510, 0xb84e},
++{0x2510, 0xf905},
++{0x2510, 0xf907},
++{0x2510, 0x3202},
++{0x2510, 0x885b},
++{0x2510, 0xa898},
++{0x2510, 0xa8d8},
++{0x2510, 0xb397},
++{0x2510, 0xf8e8},
++{0x2510, 0x80dc},
++{0x2510, 0x2206},
++{0x2510, 0xb137},
++{0x2510, 0xb808},
++{0x2510, 0xc800},
++{0x2510, 0xe809},
++{0x2510, 0xb177},
++{0x2510, 0x88df},
++{0x2510, 0xf8a8},
++{0x2510, 0xf888},
++{0x2510, 0x2203},
++{0x2510, 0xb07b},
++{0x2510, 0x2000},
++{0x2510, 0x80cc},
++{0x2510, 0x808c},
++{0x2510, 0x220b},
++{0x2510, 0xb06a},
++{0x2510, 0x88cf},
++{0x2510, 0x888f},
++{0x2510, 0x222f},
++{0x2510, 0x2771},
++{0x2510, 0x2512},
++{0x2510, 0xb04a},
++{0x2510, 0x2213},
++{0x2510, 0x2771},
++{0x2510, 0x2525},
++{0x2510, 0xb04b},
++{0x2510, 0x902f},
++{0x2510, 0xf880},
++{0x2510, 0x220e},
++{0x2510, 0x2201},
++{0x2510, 0x2201},
++{0x2510, 0x2204},
++{0x2510, 0xb043},
++{0x2510, 0x2201},
++{0x2510, 0xa8c9},
++{0x2510, 0x31c1},
++{0x2510, 0x80ac},
++{0x2510, 0x916f},
++{0x2510, 0x2112},
++{0x2510, 0x88af},
++{0x2510, 0x2440},
++{0x2510, 0xf110},
++{0x2510, 0xf804},
++{0x2510, 0x2000},
++{0x2510, 0x8088},
++{0x2510, 0xb838},
++{0x2510, 0xa8c8},
++{0x2510, 0xb04b},
++{0x2510, 0x2442},
++{0x2510, 0x3210},
++{0x2510, 0x3002},
++{0x2510, 0x220c},
++{0x2510, 0x888b},
++{0x2510, 0x2204},
++{0x2510, 0x3202},
++{0x2510, 0x2204},
++{0x2510, 0xf880},
++{0x2510, 0xb830},
++{0x2510, 0xc801},
++{0x2510, 0x30c2},
++{0x2510, 0xe80c},
++{0x2510, 0x2201},
++{0x2510, 0xb04a},
++{0x2510, 0x2229},
++{0x2510, 0x2771},
++{0x2510, 0x2513},
++{0x2510, 0x902f},
++{0x2510, 0x221f},
++{0x2510, 0x2201},
++{0x2510, 0x2204},
++{0x2510, 0xb042},
++{0x2510, 0x2201},
++{0x2510, 0xa9a1},
++{0x2510, 0x8008},
++{0x2510, 0xb093},
++{0x2510, 0x31c1},
++{0x2510, 0x916b},
++{0x2510, 0x2009},
++{0x2510, 0x8803},
++{0x2510, 0xa044},
++{0x2510, 0x3044},
++{0x2510, 0x2000},
++{0x2510, 0xa004},
++{0x2510, 0x7fff},
++{0x2510, 0x7fff},
++{0x2510, 0x7fff},
++{0x2510, 0x7fff},
++{0x2510, 0x7fff},
++{0x2510, 0xa084},
++{0x2510, 0x8078},
++{0x2510, 0x3141},
++{0x2510, 0x3041},
++{0x2510, 0x3042},
++{0x2510, 0x2000},
++{0x2510, 0x3142},
++{0x2510, 0x3041},
++{0x2510, 0x2000},
++{0x2510, 0x3110},
++{0x2510, 0x3041},
++{0x2510, 0x2000},
++{0x2510, 0x3120},
++{0x2510, 0x3041},
++{0x2510, 0x2000},
++{0x2510, 0x3144},
++{0x2510, 0x3041},
++{0x2510, 0x2000},
++{0x2510, 0x3148},
++{0x2510, 0x3041},
++{0x2510, 0x2000},
++{0x2510, 0x2206},
++{0x2510, 0x881b},
++{0x2510, 0x887b},
++{0x2510, 0x2440},
++{0x2510, 0xb095},
++{0x2510, 0xf110},
++{0x2510, 0xf804},
++{0x2510, 0xf90d},
++{0x2510, 0x3084},
++{0x2510, 0x3090},
++{0x2510, 0x3088},
++{0x2510, 0x8058},
++{0x2510, 0x3001},
++{0x2510, 0x2442},
++{0x2510, 0x3260},
++{0x2510, 0x3248},
++{0x2510, 0x3220},
++{0x2510, 0x2002},
++{0x2510, 0x8863},
++{0x2510, 0x2004},
++{0x2510, 0x8803},
++{0x2510, 0x2204},
++{0x2510, 0x30c2},
++{0x2510, 0xa9a0},
++{0x2510, 0xb094},
++{0x2510, 0x2201},
++{0x2510, 0xa0c4},
++{0x2510, 0x3044},
++{0x2510, 0x2000},
++{0x2510, 0xa004},
++{0x2510, 0x7fff},
++{0x2510, 0x7fff},
++{0x2510, 0x7fff},
++{0x2510, 0x7fff},
++{0x2510, 0x7fff},
++{0x2510, 0xb980},
++{0x2510, 0x8108},
++{0x2510, 0xa105},
++{0x2510, 0x30c1},
++{0x2510, 0x2000},
++{0x2510, 0x3101},
++{0x2510, 0x3041},
++{0x2510, 0x3250},
++{0x2510, 0x3108},
++{0x2510, 0x3104},
++{0x2510, 0x3102},
++{0x2510, 0x3041},
++{0x2510, 0xf860},
++{0x2510, 0xb095},
++{0x2510, 0x3141},
++{0x2510, 0x3042},
++{0x2510, 0xb9f8},
++{0x2510, 0xb9fc},
++{0x2510, 0x8803},
++{0x2510, 0x916f},
++{0x2510, 0x3110},
++{0x2510, 0x3042},
++{0x2510, 0xb9fe},
++{0x2510, 0xf905},
++{0x2510, 0xf907},
++{0x2510, 0x3202},
++{0x2510, 0x880b},
++{0x2510, 0xa888},
++{0x2510, 0xa8c8},
++{0x2510, 0xb397},
++{0x2510, 0xf8e8},
++{0x2510, 0x818c},
++{0x2510, 0x2206},
++{0x2510, 0xb137},
++{0x2510, 0xb9b8},
++{0x2510, 0xc801},
++{0x2510, 0xe809},
++{0x2510, 0xb177},
++{0x2510, 0x888f},
++{0x2510, 0xf8a8},
++{0x2510, 0xf888},
++{0x2510, 0x2203},
++{0x2510, 0xb07b},
++{0x2510, 0x2000},
++{0x2510, 0x2206},
++{0x2510, 0xb06a},
++{0x2510, 0x2210},
++{0x2510, 0x818c},
++{0x2510, 0x2204},
++{0x2510, 0x888f},
++{0x2510, 0x888f},
++{0x2510, 0x2215},
++{0x2510, 0xb04a},
++{0x2510, 0x2212},
++{0x2510, 0x2111},
++{0x2510, 0xb04b},
++{0x2510, 0x902f},
++{0x2510, 0xf880},
++{0x2510, 0x220e},
++{0x2510, 0x2201},
++{0x2510, 0x2204},
++{0x2510, 0xb043},
++{0x2510, 0x2201},
++{0x2510, 0xa8d9},
++{0x2510, 0x31c1},
++{0x2510, 0x80cc},
++{0x2510, 0x916f},
++{0x2510, 0x2110},
++{0x2510, 0x88cf},
++{0x2510, 0x2440},
++{0x2510, 0xf110},
++{0x2510, 0xf804},
++{0x2510, 0x2000},
++{0x2510, 0xb988},
++{0x2510, 0xa8d8},
++{0x2510, 0xb04b},
++{0x2510, 0x3002},
++{0x2510, 0x2442},
++{0x2510, 0x3210},
++{0x2510, 0x220a},
++{0x2510, 0x2204},
++{0x2510, 0x3202},
++{0x2510, 0x2204},
++{0x2510, 0xb980},
++{0x2510, 0xc800},
++{0x2510, 0x30c2},
++{0x2510, 0xe80c},
++{0x2510, 0x2201},
++{0x2510, 0xb04a},
++{0x2510, 0x221f},
++{0x2510, 0x8088},
++{0x2510, 0x220a},
++{0x2510, 0x888b},
++{0x2510, 0x902f},
++{0x2510, 0x221e},
++{0x2510, 0x2201},
++{0x2510, 0x2204},
++{0x2510, 0xb042},
++{0x2510, 0x2201},
++{0x2510, 0xa9a1},
++{0x2510, 0x8018},
++{0x2510, 0xb093},
++{0x2510, 0x31c1},
++{0x2510, 0x916b},
++{0x2510, 0x2009},
++{0x2510, 0x8803},
++{0x2510, 0x2000},
++{0x2510, 0xa004},
++{0x2510, 0xb800},
++{0x2510, 0x7fff},
++{0x2510, 0x7fff},
++{0x2510, 0x7fff},
++{0x2510, 0x8078},
++{0x2510, 0xa184},
++{0x2510, 0xb981},
++{0x2510, 0x3141},
++{0x2510, 0x3041},
++{0x2510, 0x3042},
++{0x2510, 0x2000},
++{0x2510, 0x3142},
++{0x2510, 0x3041},
++{0x2510, 0x2000},
++{0x2510, 0x3110},
++{0x2510, 0x3041},
++{0x2510, 0x2000},
++{0x2510, 0x3120},
++{0x2510, 0x3041},
++{0x2510, 0x2000},
++{0x2510, 0x30a0},
++{0x2510, 0x2206},
++{0x2510, 0x881b},
++{0x2510, 0x887b},
++{0x2510, 0x2282},
++{0x2510, 0xb095},
++{0x2510, 0xf110},
++{0x2510, 0xf804},
++{0x2510, 0xf90d},
++{0x2510, 0x3090},
++{0x2510, 0x3088},
++{0x2510, 0x8058},
++{0x2510, 0x2202},
++{0x2510, 0x3001},
++{0x2510, 0x3260},
++{0x2510, 0x3248},
++{0x2510, 0x2002},
++{0x2510, 0x885b},
++{0x2510, 0x2004},
++{0x2510, 0x2204},
++{0x2510, 0x8018},
++{0x2510, 0x2209},
++{0x2510, 0x881b},
++{0x2510, 0xa9a0},
++{0x2510, 0xb094},
++{0x2510, 0x2209},
++{0x2510, 0x8000},
++{0x2510, 0x2209},
++{0x2510, 0x8803},
++{0x2510, 0xa1c4},
++{0x2510, 0x3044},
++{0x2510, 0xb800},
++{0x2510, 0xa004},
++{0x2510, 0x7fff},
++{0x2510, 0x7fff},
++{0x2510, 0x7fff},
++{0x2510, 0x9818},
++{0x2510, 0xb800},
++{0x2510, 0x3101},
++{0x2510, 0x3041},
++{0x2510, 0x2200},
++{0x2510, 0x3102},
++{0x2510, 0x3041},
++{0x2510, 0x2200},
++{0x2510, 0x8018},
++{0x2510, 0x2002},
++{0x2510, 0x8038},
++{0x2510, 0x2205},
++{0x2510, 0x881b},
++{0x2510, 0x883b},
++{0x2510, 0x213e},
++{0x2510, 0x8018},
++{0x2510, 0x2202},
++{0x2510, 0x8000},
++{0x2510, 0x2202},
++{0x2510, 0x8803},
++{0x2510, 0x9800},
++{0x2510, 0xa004},
++{0x2510, 0x7fff},
++{0x2510, 0x7fff},
++{0x2510, 0x2440},
++{0x2510, 0xb095},
++{0x2510, 0xf110},
++{0x2510, 0xf804},
++{0x2510, 0xf90d},
++{0x2510, 0x2442},
++{0x2510, 0x3260},
++{0x2510, 0x3248},
++{0x2510, 0x3220},
++{0x2510, 0x2007},
++{0x2510, 0x2204},
++{0x2510, 0x30c2},
++{0x2510, 0xa9a0},
++{0x2510, 0xb094},
++{0x2510, 0x7fff},
++{0x2510, 0x7fff},
++{0x2510, 0xb981},
++{0x2510, 0x3101},
++{0x2510, 0x3041},
++{0x2510, 0x3102},
++{0x2510, 0x3041},
++{0x2510, 0x8028},
++{0x2510, 0x2212},
++{0x2510, 0x880b},
++{0x2510, 0x882b},
++{0x2510, 0x2440},
++{0x2510, 0xb095},
++{0x2510, 0xf110},
++{0x2510, 0xf804},
++{0x2510, 0xf90d},
++{0x2510, 0x8008},
++{0x2510, 0x2202},
++{0x2510, 0x3001},
++{0x2510, 0x3260},
++{0x2510, 0x3248},
++{0x2510, 0x2442},
++{0x2510, 0x8823},
++{0x2510, 0x3220},
++{0x2510, 0x2007},
++{0x2510, 0x8803},
++{0x2510, 0x2204},
++{0x2510, 0x30c2},
++{0x2510, 0xa8a0},
++{0x2510, 0xb094},
++{0x2510, 0x2201},
++{0x2510, 0x7fff},
++{0x2510, 0x7fff},
++{0x2510, 0x7fff},
++{0x2510, 0xb800},
++{0x2510, 0x8058},
++{0x2510, 0xa005},
++{0x2510, 0x30c1},
++{0x2510, 0x3101},
++{0x2510, 0x3041},
++{0x2510, 0x3041},
++{0x2510, 0x3250},
++{0x2510, 0x3108},
++{0x2510, 0x3104},
++{0x2510, 0x3102},
++{0x2510, 0x3041},
++{0x2510, 0xf860},
++{0x2510, 0xb095},
++{0x2510, 0x3141},
++{0x2510, 0x3042},
++{0x2510, 0xb848},
++{0x2510, 0xb84c},
++{0x2510, 0x8843},
++{0x2510, 0x916f},
++{0x2510, 0x3110},
++{0x2510, 0x3042},
++{0x2510, 0xb84e},
++{0x2510, 0xf905},
++{0x2510, 0xf907},
++{0x2510, 0x3202},
++{0x2510, 0x885b},
++{0x2510, 0xa898},
++{0x2510, 0xa8d8},
++{0x2510, 0xb397},
++{0x2510, 0xf8e8},
++{0x2510, 0x80dc},
++{0x2510, 0x2206},
++{0x2510, 0xb137},
++{0x2510, 0xb808},
++{0x2510, 0xc800},
++{0x2510, 0xe809},
++{0x2510, 0xb177},
++{0x2510, 0x88df},
++{0x2510, 0xf8a8},
++{0x2510, 0xf888},
++{0x2510, 0x2203},
++{0x2510, 0xb07b},
++{0x2510, 0x2000},
++{0x2510, 0x80cc},
++{0x2510, 0x808c},
++{0x2510, 0x220b},
++{0x2510, 0xb06a},
++{0x2510, 0x88cf},
++{0x2510, 0x888f},
++{0x2510, 0x222f},
++{0x2510, 0x2771},
++{0x2510, 0x251e},
++{0x2510, 0xb04a},
++{0x2510, 0x2213},
++{0x2510, 0x2771},
++{0x2510, 0x2525},
++{0x2510, 0xb04b},
++{0x2510, 0x902f},
++{0x2510, 0xf880},
++{0x2510, 0x221e},
++{0x2510, 0x2201},
++{0x2510, 0x2204},
++{0x2510, 0xb043},
++{0x2510, 0x2201},
++{0x2510, 0xa8c9},
++{0x2510, 0x31c1},
++{0x2510, 0x80ac},
++{0x2510, 0x916f},
++{0x2510, 0x2112},
++{0x2510, 0x88af},
++{0x2510, 0x2440},
++{0x2510, 0xf110},
++{0x2510, 0xf804},
++{0x2510, 0x2000},
++{0x2510, 0x8088},
++{0x2510, 0xb838},
++{0x2510, 0xa8c8},
++{0x2510, 0xb04b},
++{0x2510, 0x2442},
++{0x2510, 0x3210},
++{0x2510, 0x3002},
++{0x2510, 0x220c},
++{0x2510, 0x888b},
++{0x2510, 0x2204},
++{0x2510, 0x3202},
++{0x2510, 0xf880},
++{0x2510, 0xb830},
++{0x2510, 0xc801},
++{0x2510, 0x30c2},
++{0x2510, 0xe80c},
++{0x2510, 0x2201},
++{0x2510, 0xb04a},
++{0x2510, 0x2229},
++{0x2510, 0x2771},
++{0x2510, 0x2513},
++{0x2510, 0x902f},
++{0x2510, 0x221f},
++{0x2510, 0x2201},
++{0x2510, 0x2204},
++{0x2510, 0xb042},
++{0x2510, 0x2201},
++{0x2510, 0xa8e1},
++{0x2510, 0x8008},
++{0x2510, 0xb093},
++{0x2510, 0x31c1},
++{0x2510, 0x916b},
++{0x2510, 0x2009},
++{0x2510, 0x8803},
++{0x2510, 0x2000},
++{0x2510, 0xa004},
++{0x2510, 0x7fff},
++{0x2510, 0x7fff},
++{0x2510, 0x7fff},
++{0x2510, 0x7fff},
++{0x2510, 0x7fff},
++{0x2510, 0x2440},
++{0x2510, 0xb095},
++{0x2510, 0xf110},
++{0x2510, 0xf804},
++{0x2510, 0xf90d},
++{0x2510, 0x2442},
++{0x2510, 0x3220},
++{0x2510, 0x2002},
++{0x2510, 0x2204},
++{0x2510, 0x30c2},
++{0x2510, 0xa9a0},
++{0x2510, 0x2004},
++{0x2510, 0xb094},
++{0x2510, 0x2201},
++{0x2510, 0x3244},
++{0x2510, 0x7fff},
++{0x2510, 0x7fff},
++{0x2510, 0x7fff},
++{0x2510, 0x7fff},
++{0x2510, 0x7fff},
++{0x2510, 0x2749},
++{0x2510, 0x2422},
++{0x2510, 0x2749},
++{0x2510, 0x2423},
++{0x2510, 0x2709},
++{0x2510, 0x2420},
++{0x2510, 0x2729},
++{0x2510, 0x2423},
++{0x2510, 0x3242},
++{0x2510, 0x2722},
++{0x2510, 0x2422},
++{0x2510, 0x2769},
++{0x2510, 0x2421},
++{0x2510, 0x2702},
++{0x2510, 0x2421},
++{0x2510, 0x3242},
++{0x2510, 0x276a},
++{0x2510, 0x2420},
++{0x2510, 0x276a},
++{0x2510, 0x2421},
++{0x2510, 0x2703},
++{0x2510, 0x2420},
++{0x2510, 0x2703},
++{0x2510, 0x2421},
++{0x2510, 0x3242},
++{0x2510, 0x276b},
++{0x2510, 0x2420},
++{0x2510, 0x276b},
++{0x2510, 0x2421},
++{0x2510, 0x2704},
++{0x2510, 0x2420},
++{0x2510, 0x2704},
++{0x2510, 0x2421},
++{0x2510, 0x3242},
++{0x2510, 0x276c},
++{0x2510, 0x2420},
++{0x2510, 0x276c},
++{0x2510, 0x2421},
++{0x2510, 0x7fff},
++{0x2510, 0x7fff},
++{0x2510, 0x2759},
++{0x2510, 0x2422},
++{0x2510, 0x2758},
++{0x2510, 0x2420},
++{0x2510, 0x2403},
++{0x2510, 0x2712},
++{0x2510, 0x3242},
++{0x2510, 0x2422},
++{0x2510, 0x271a},
++{0x2510, 0x3242},
++{0x2510, 0x2420},
++{0x2510, 0x2702},
++{0x2510, 0x2423},
++{0x2510, 0x2703},
++{0x2510, 0x3242},
++{0x2510, 0x2420},
++{0x2510, 0x2703},
++{0x2510, 0x2423},
++{0x2510, 0x2704},
++{0x2510, 0x3242},
++{0x2510, 0x2420},
++{0x2510, 0x2704},
++{0x2510, 0x2423},
++{0x2510, 0x7fff},
++{0x2510, 0x7fff},
++{0x2510, 0x7fff},
++{0x2510, 0x7fff},
++{0x2510, 0x7fff},
++{0x2510, 0x7fff},
++{0x2510, 0x7fff},
++{0x2510, 0x7fff},
++{0x2510, 0x7fff},
++{0x2510, 0xc023},
++{0x2510, 0x2402},
++{0x2510, 0x2405},
++{0x2510, 0x2789},
++{0x2510, 0x242e},
++{0x2510, 0x2788},
++{0x2510, 0x242f},
++{0x2510, 0x3244},
++{0x2510, 0x7fff},
++{0x2510, 0x7fff},
++{0x2510, 0x7fff},
++{0x2510, 0x7fff},
++{0x2510, 0xc027},
++{0x2510, 0x2407},
++{0x2510, 0x2406},
++{0x2510, 0xc063},
++{0x2510, 0x2402},
++{0x2510, 0x2751},
++{0x2510, 0x2423},
++{0x2510, 0x2750},
++{0x2510, 0x2421},
++{0x2510, 0xc003},
++{0x2510, 0x3244},
++{0x2510, 0x7fff},
++{0x2510, 0x7fff},
++{0x2510, 0x7fff},
++{0x2510, 0x7fff},
++{0x2510, 0x7fff},
++{0x2510, 0xc021},
++{0x2510, 0x2400},
++{0x2510, 0x2405},
++{0x2510, 0xc062},
++{0x2510, 0x2400},
++{0x2510, 0xc063},
++{0x2510, 0x2751},
++{0x2510, 0x2423},
++{0x2510, 0x2750},
++{0x2510, 0x2421},
++{0x2510, 0xc003},
++{0x2510, 0x3244},
++{0x2510, 0x7fff},
++{0x2510, 0x7fff},
++{0x2510, 0x7fff},
++{0x2510, 0x7fff},
++{0x2510, 0xc0e3},
++{0x2510, 0x2400},
++{0x2510, 0x27b1},
++{0x2510, 0x2425},
++{0x2510, 0xc063},
++{0x2510, 0x2420},
++{0x2510, 0x2751},
++{0x2510, 0x2423},
++{0x2510, 0x2750},
++{0x2510, 0x2421},
++{0x2510, 0xc003},
++{0x2510, 0x3244},
++{0x2510, 0x7fff},
++{0x2510, 0x7fff},
++{0x2510, 0x7fff},
++{0x2510, 0x7fff},
++{0x2510, 0x2404},
++{0x2510, 0x2779},
++{0x2510, 0x242c},
++{0x2510, 0x2781},
++{0x2510, 0x242d},
++{0x2510, 0x3244},
++{0x2510, 0x7fff},
++{0x2510, 0x7fff},
++{0x2510, 0x2791},
++{0x2510, 0x2430},
++{0x2510, 0x2799},
++{0x2510, 0x2428},
++{0x2510, 0x3244},
++{0x2510, 0x7fff},
++{0x2510, 0x7fff},
++{0x2510, 0x7fff},
++{0x2510, 0x2417},
++{0x2510, 0xc023},
++{0x2510, 0x2403},
++{0x2510, 0x2703},
++{0x2510, 0x3242},
++{0x2510, 0x2404},
++{0x2510, 0x240d},
++{0x2510, 0xc003},
++{0x2510, 0x2703},
++{0x2510, 0x3242},
++{0x2510, 0x2400},
++{0x2510, 0x2408},
++{0x2510, 0x2703},
++{0x2510, 0x3242},
++{0x2510, 0x2417},
++{0x2510, 0x240b},
++{0x2510, 0x3244},
++{0x2510, 0x7fff},
++{0x2510, 0x7fff},
++{0x2510, 0x7fff},
++{0x2510, 0xc022},
++{0x2510, 0x2402},
++{0x2510, 0x2405},
++{0x2510, 0x2414},
++{0x2510, 0x3244},
++{0x2510, 0x7fff},
++{0x2510, 0x7fff},
++{0x2510, 0x7fff},
++{0x2510, 0xc022},
++{0x2510, 0x2407},
++{0x2510, 0x2405},
++{0x2510, 0xc061},
++{0x2510, 0x2400},
++{0x2510, 0xc023},
++{0x2510, 0x2403},
++{0x2510, 0xc003},
++{0x2510, 0x3244},
++{0x2510, 0x7fff},
++{0x2510, 0x7fff},
++{0x2510, 0x7fff},
++{0x2510, 0xc022},
++{0x2510, 0x2404},
++{0x2510, 0x2779},
++{0x2510, 0x2433},
++{0x2510, 0x2781},
++{0x2510, 0x2436},
++{0x2510, 0x3244},
++{0x2510, 0x7fff},
++{0x2510, 0x7fff},
++{0x2510, 0x7fff},
++{0x2510, 0x7fff},
++{0x2510, 0x7fff},
++{0x2510, 0xc126},
++{0x2510, 0x2407},
++{0x2510, 0xc022},
++{0x2510, 0x2406},
++{0x2510, 0x2402},
++{0x2510, 0xc023},
++{0x2510, 0x2405},
++{0x2510, 0x2417},
++{0x2510, 0x3244},
++{0x2510, 0x7fff},
++{0x2510, 0x7fff},
++{0x2510, 0x7fff},
++{0x2510, 0x3244},
++{0x2510, 0x7fff},
++{0x2510, 0x7fff},
++{0x2510, 0x7fff},
++{0x2510, 0xffff},
++{0x2510, 0xffff},
++{0x2510, 0xffff},
++{0x2510, 0xffff},
++{0x2510, 0xffff},
++{0x2510, 0xffff},
++{0x2510, 0xffff},
++{0x2510, 0xffff},
++{0x2510, 0xffff},
++{0x2510, 0xffff},
++{0x2510, 0xffff},
++{0x2510, 0xffff},
++{0x2510, 0xffff},
++{0x2510, 0xffff},
++{0x2510, 0xffff},
++{0x2510, 0xffff},
++{0x2510, 0xffff},
++{0x2510, 0xffff},
++{0x2510, 0xffff},
++{0x2510, 0xffff},
++{0x2510, 0xffff},
++{0x2510, 0xffff},
++{0x2510, 0xffff},
++{0x2510, 0xffff},
++{0x2510, 0xffff},
++{0x2510, 0xffff},
++{0x2510, 0xffff},
++{0x2510, 0xffff},
++{0x2510, 0xffff},
++{0x2510, 0xffff},
++{0x2510, 0xffff},
++{0x2510, 0xffff},
++{0x2510, 0xffff},
++{0x2510, 0xffff},
++{0x2510, 0xffff},
++{0x2510, 0xffff},
++{0x2510, 0xffff},
++{0x2510, 0xffff},
++{0x2510, 0xffff},
++{0x2510, 0xffff},
++{0x2510, 0xffff},
++{0x2510, 0xffff},
++{0x2510, 0xffff},
++{0x2510, 0xffff},
++{0x2510, 0xffff},
++{0x2510, 0xffff},
++{0x2510, 0xffff},
++{0x2510, 0xffff},
++{0x2510, 0xffff},
++{0x2510, 0xffff},
++{0x2510, 0xffff},
++{0x2510, 0xffff},
++{0x2510, 0xffff},
++{0x2510, 0xffff},
++{0x2510, 0xffff},
++{0x2510, 0xffff},
++{0x2510, 0xffff},
++{0x2510, 0xffff},
++{0x2510, 0xffff},
++{0x2510, 0xffff},
++{0x2510, 0xffff},
++{0x2510, 0xffff},
++{0x2510, 0xffff},
++{0x2510, 0xffff},
++{0x2510, 0xffff},
++{0x2510, 0xffff},
++{0x2510, 0xffff},
++{0x2510, 0xffff},
++{0x2510, 0xffff},
++{0x2510, 0xffff},
++{0x2510, 0xffff},
++{0x2510, 0xffff},
++{0x2510, 0xffff},
++{0x2510, 0xffff},
++{0x2510, 0xffff},
++{0x2510, 0xffff},
++{0x2510, 0xffff},
++{0x2510, 0xffff},
++{0x2510, 0xffff},
++{0x2510, 0xffff},
++{0x2510, 0xffff},
++{0x2510, 0xffff},
++{0x2510, 0xffff},
++{0x2510, 0xffff},
++{0x2510, 0xffff},
++{0x2510, 0xffff},
++{0x2510, 0xffff},
++{0x2510, 0xffff},
++{0x2510, 0xffff},
++{0x2510, 0xffff},
++{0x2510, 0xffff},
++
++{AR0323_DELAY, 100}, // Wait 100ms
++{0x301A, 0x0058}, // RESET_REGISTER
++
++{0x31AC, 0x140C}, // DATA_FORMAT_BITS
++{0x31D0, 0x0001}, // COMPANDING
++{0x336E, 0x01DF}, // DATAPATH_SELECT2
++{0x3238, 0x0666}, // EXPOSURE_RATIO
++#if 1
++{0x300C, 0x0A60}, // LINE_LENGTH_PCK_
++{0x300A, 0x04A0}, // FRAME_LENGTH_LINES_
++#else
++{0x300A, AR0323_SENSOR_HEIGHT + 208}, // FRAME_LENGTH_LINES_
++{0x300C, AR0323_SENSOR_WIDTH + 300}, // LINE_LENGTH_PCK_
++#endif
++
++#if 0
++//2880x1072 resolution
++{0x3004, 0x0008}, // X_ADDR_START_
++{0x3008, 0x0B47}, // X_ADDR_END_
++{0x3002, 0x010C}, // Y_ADDR_START_
++{0x3006, 0x053B}, // Y_ADDR_END_
++#else
++{0x3004, AR0323_X_START}, // X_ADDR_START_
++{0x3008, AR0323_X_END}, // X_ADDR_END_
++{0x3002, AR0323_Y_START}, // Y_ADDR_START_
++{0x3006, AR0323_Y_END}, // Y_ADDR_END_
++{0x3402, 0x0000 | AR0323_MAX_WIDTH}, // X_OUTPUT_CONTROL
++{0x3404, 0x0000 | AR0323_MAX_HEIGHT}, // Y_OUTPUT_CONTROL
++#endif
++
++{0x3534, 0xA282}, // DAC_LD_52_53
++{0x3524, 0x0FFF}, // DAC_LD_36_37
++{0x3180, 0x1001}, // DELTA_DK_CONTROL
++{0x3576, 0x1F09}, // DAC_LD_118_119
++
++{0x3548, 0x7878}, // DAC_LD_72_73
++{0x354C, 0x4141}, // DAC_LD_76_77
++{0x354E, 0x4B4B}, // DAC_LD_78_79
++{0x356E, 0x158A}, // DAC_LD_110_111
++
++//overflow},settings
++{0x3496, 0xCF0A}, // LFM_CONTROL
++{0x350E, 0x2181}, // DAC_LD_14_15
++{0x3E02, 0x0834}, // LFM2_T1_E1_A
++{0x3E04, 0x0000}, // LFM2_T1_E1_B
++{0x3E08, 0x1FFF}, // LFM2_T1_E2_A
++{0x3E14, 0x0020}, // LFM2_T1_SLOPE
++{0x3E16, 0x1F40}, // LFM2_T1_E1_THRESHOLD
++//
++{0x562A, 0x05DC}, // OCL_T1_E2_E1_SAT
++{0x563A, 0x0011}, // OCL_T1_GAIN_
++
++{0x3364, 0x068C}, // DCG_TRIM
++{0x3290, 0xD354}, // T3_BARRIER_C0
++{0x3292, 0xD354}, // T3_BARRIER_C1
++{0x3294, 0xD354}, // T3_BARRIER_C2
++{0x3296, 0xD354}, // T3_BARRIER_C3
++{0x3298, 0xD354}, // T4_BARRIER_C0
++{0x329A, 0xD354}, // T4_BARRIER_C1
++{0x329C, 0xD354}, // T4_BARRIER_C2
++{0x329E, 0xD354}, // T4_BARRIER_C3
++{0x33DA, 0x0001}, // OC_LUT_CONTROL
++{0x3D00, 0x6007}, // MEC_CTRL1
++
++{0x3040, 0xC005}, // READ_MODE
++{0x3352, 0x2000}, // MIPI_DT_VC_CONFIG
++{0x3064, 0x0180}, // SMIA_TEST
++
++{0x3D10, 0x0000}, // VIS_BOUND_X0
++{0x3D12, 0x0B40}, // VIS_BOUND_X1
++{0x3D14, 0x001E}, // VIS_BOUND_Y0
++{0x3D16, 0x045A}, // VIS_BOUND_Y1
++
++{0x3D08, 0x0000}, // DTR_BOUND_X0
++{0x3D0A, 0x0B40}, // DTR_BOUND_X1
++{0x3D0C, 0x0004}, // DTR_BOUND_Y0
++{0x3D0E, 0x000C}, // DTR_BOUND_Y1
++{AR0323_DELAY, 100}, // Wait 100ms
++
++//Pre HDR gain LG lens
++{0x3110, 0x0011}, // HDR_CONTROL0
++{0x3056, 0x0031}, // GREEN1_GAIN
++{0x3058, 0x0080}, // BLUE_GAIN
++{0x305A, 0x0070}, // RED_GAIN
++{0x305C, 0x0031}, // GREEN2_GAIN
++{0x3308, 0x0539}, // GLOBAL_GAIN2_
++{0x3D28, 0x3BD1}, // T1_STR_DEC_TH
++{0x3D2A, 0x4C2C}, // T1_END_DEC_TH
++
++//booster
++{0x352C, 0x8146}, // DAC_LD_44_45
++{0x352E, 0x1871}, // DAC_LD_46_47
++{0x3538, 0x81EA}, // DAC_LD_56_57
++
++{0x3576, 0x1F49}, // DAC_LD_118_119
++{0x3544, 0x03A1}, // DAC_LD_68_69
++
++{0x354C, 0x411E}, // DAC_LD_76_77
++//
++{0x351A, 0x7900},
++
++//Temp_sensor_read
++{0x3E94, 0x3010}, // TEMPVSENS1_SREG_TRIM0
++{0x30B8, 0x0003}, // TEMPSENS1_CTRL_REG
++{0x3F92, 0x4D00}, // TEMPVSENS1_TMG_CTRL
++{0x3F96, 0xFFFE}, //003E // TEMPVSENS1_FLAG_CTRL
++{0x3EE0, 0x0700}, //0000 // TEMPVSENS1_FLAG_CTRL_EXT
++{0x3E98, 0x4000}, // TEMPVSENS1_EN_CTRL
++
++//analog},1x
++{0x3022, 0x01}, // GROUPED_PARAMETER_HOLD_
++{0x3D34, 0x0562}, // T2_STR_DEC_TH
++{0x3D36, 0x0562}, // T2_END_DEC_TH
++{0x563A, 0x0011}, // OCL_T1_GAIN_
++{0x3E18, 0x0EEE}, // LFM2_T1_E2_GAIN_CTRL
++{0x3366, 0x1121}, // ANALOG_GAIN
++{0x3364, 700}, //2D0 // DCG_TRIM
++{0x336A, 0x0080}, // ANALOG_GAIN2
++{0x3E02, 0x09C4}, // LFM2_T1_E1_A
++{0x3022, 0x00}, // GROUPED_PARAMETER_HOLD_
++
++//updated},pink},reduction},settings
++{0x3D02, 0x6033}, // MEC_CTRL2
++{0x3534, 0xA284}, // DAC_LD_52_53
++{0x3546, 0x3601}, // DAC_LD_70_71
++{0x3518, 0x4444}, // DAC_LD_24_25
++
++{0x3494, 0x0C0C}, // LFM_TX_PATTERN_CTRL
++{0x34BC, 0x000C}, // LFM_PATTERN_CTRL
++{0x3E02, 0x09C4}, // LFM2_T1_E1_A
++
++//band},mitigation
++{0x3450, 0x00A4}, // LFM_PHASE0_PERIOD
++{0x3452, 0x004F}, // LFM_PHASE1_PERIOD
++{0x3454, 0x004F}, // LFM_PHASE2_PERIOD
++{0x3456, 0x004F}, // LFM_PHASE3_PERIOD
++{0x3458, 0x004F}, // LFM_PHASE4_PERIOD
++{0x345A, 0x004F}, // LFM_PHASE5_PERIOD
++{0x345C, 0x004F}, // LFM_PHASE6_PERIOD
++{0x345E, 0x004F}, // LFM_PHASE7_PERIOD
++{0x3460, 0x004F}, // LFM_PHASE8_PERIOD
++{0x3462, 0x004F}, // LFM_PHASE9_PERIOD
++{0x3464, 0x004F}, // LFM_PHASE10_PERIOD
++{0x3466, 0x004F}, // LFM_PHASE11_PERIOD
++{0x3468, 0x00A4}, // LFM_PHASE12_PERIOD
++{0x346A, 0x004F}, // LFM_PHASE13_PERIOD
++{0x346C, 0x004F}, // LFM_PHASE14_PERIOD
++{0x346E, 0x004F}, // LFM_PHASE15_PERIOD
++{0x3470, 0x004F}, // LFM_PHASE16_PERIOD
++{0x3472, 0x004F}, // LFM_PHASE17_PERIOD
++{0x3474, 0x004F}, // LFM_PHASE18_PERIOD
++{0x3476, 0x004F}, // LFM_PHASE19_PERIOD
++{0x3478, 0x004F}, // LFM_PHASE20_PERIOD
++{0x347A, 0x004F}, // LFM_PHASE21_PERIOD
++{0x347C, 0x004F}, // LFM_PHASE22_PERIOD
++{0x347E, 0x004F}, // LFM_PHASE23_PERIOD
++{0x3480, 0x004F}, // LFM_PHASE24_PERIOD
++{0x3482, 0x004F}, // LFM_PHASE25_PERIOD
++{0x3484, 0x00A4}, // LFM_PHASE26_PERIOD
++{0x3486, 0x004F}, // LFM_PHASE27_PERIOD
++{0x3488, 0x00A4}, // LFM_PHASE28_PERIOD
++{0x348A, 0x004F}, // LFM_PHASE29_PERIOD
++{0x348C, 0x004F}, // LFM_PHASE30_PERIOD
++{0x348E, 0x004F}, // LFM_PHASE31_PERIOD
++{0x3490, 0x004F}, // LFM_PHASE32_PERIOD
++
++{0x3496, 0xDF00}, // LFM_CONTROL
++{0x349A, 0x0001}, // LFM_TX_SHIFT_CLK_CTRL
++{0x349C, 0x0003}, // LFM_TX_DATA_CLK_CTRL
++{0x349E, 0x0002}, // LFM_TX_GOTO_LOROW_CLK_CTRL
++{0x34A0, 0x003E}, // LFM_TX_DATA_CLR_CLK_CTRL
++{0x34A2, 0x0012}, // LFM_BST_TX_CLK_CTRL
++{0x34A4, 0x003D}, // LFM_BST_TXLO_CLK_CTRL
++{0x34A6, 0x004E}, // LFM_BST_TXLOROW_EN_CLK_CTRL
++{0x34A8, 0x0044}, // LFM_AB_SHIFT_CLK_CTRL
++{0x34AA, 0x0001}, // LFM_BST_AB_CLK_CTRL
++{0x34AC, 0x0043}, // LFM_BST_ABLO_CLK_CTRL
++{0x34AE, 0x004E}, // LFM_BST_ABLOROW_EN_CLK_CTRL
++{0x34B0, 0x0002}, // LFM_DCG_DATA_CLK_CTRL
++{0x34B2, 0x003F}, // LFM_DCG_DATA_CLR_CLK_CTRL
++{0x34B4, 0x004E}, // LFM_BST_DCGLOROW_EN_CLK_CTRL
++{0x34B6, 0x0012}, // LFM_BST_DCG_CLK_CTRL
++
++{0x350E, 0x2189}, // DAC_LD_14_15
++//pixel recommended settings Feb5
++{0x352C, 0x8146}, // DAC_LD_44_45
++{0x3526, 0x9812}, // DAC_LD_38_39
++{0x3528, 0x99C0}, // DAC_LD_40_41
++{0x352E, 0x0B71}, // DAC_LD_46_47
++{0x352A, 0x0170}, // DAC_LD_42_43
++{0x3530, 0x07F0}, // DAC_LD_48_49
++{0x3514, 0xEEEE}, // DAC_LD_20_21
++{0x3578, 0xEEEE}, // DAC_LD_120_121
++{0x3518, 0x3333}, // DAC_LD_24_25
++{0x3540, 0x0033}, // DAC_LD_64_65
++{0x3542, 0x33F0}, // DAC_LD_66_67
++
++//CFPN},IMPROVEMENT
++{0x3568, 0x04BC},
++{0x356A, 0x81AA},
++{0x356E, 0x15E6},
++
++//E1-E2 Transision Noise Improvement
++{0x3E10, 0x000A}, // LFM2_T1_E2_OFFSET
++{0x3430, 0x070C}, // BST_MULTISHOT_CLK_0
++{0x3432, 0x008C}, // BST_MULTISHOT_CLK_1
++{0x37B2, 0x1F40}, // DBLC_OUT_CLIP_MAX
++
++{0x3550, 0xFF6C}, // DAC_LD_80_81
++{0x3546, 0x4201}, // DAC_LD_70_71
++
++//T2 white balance gains
++{0x30B0, 0x0880}, // DIGITAL_TEST
++{0x3300, 0x0030}, // GREEN1_GAIN2_
++{0x3302, 0x0080}, // BLUE_GAIN2_
++{0x3304, 0x0070}, // RED_GAIN2_
++{0x3306, 0x0030}, // GREEN2_GAIN2_
++{0x3056, 0x002F}, // GREEN1_GAIN
++{0x3058, 0x0080}, // BLUE_GAIN
++{0x305A, 0x0072}, // RED_GAIN
++{0x305C, 0x002F}, // GREEN2_GAIN
++
++{0x301A, 0x005C}, // RESET_REGISTER
++};
+diff --git a/drivers/media/i2c/soc_camera/ov106xx.c b/drivers/media/i2c/soc_camera/ov106xx.c
+index c7bd92e..906ec7e 100644
+--- a/drivers/media/i2c/soc_camera/ov106xx.c
++++ b/drivers/media/i2c/soc_camera/ov106xx.c
+@@ -18,6 +18,7 @@
+ #include "ar0220.c"
+ #include "ar0231.c"
+ #include "ar0233.c"
++#include "ar0323.c"
+ #include "ap0101_ar014x.c"
+ #include "gw4200_ar014x.c"
+ #include "ov2775.c"
+@@ -34,6 +35,7 @@ static enum {
+ ID_AR0220,
+ ID_AR0231,
+ ID_AR0233,
++ ID_AR0323,
+ ID_AP0101_AR014X,
+ ID_GW4200_AR014X,
+ ID_OV2775,
+@@ -95,6 +97,12 @@ static int ov106xx_probe(struct i2c_client *client,
+ goto out;
+ }
+
++ ret = ar0323_probe(client, did);
++ if (!ret) {
++ chip_id = ID_AR0323;
++ goto out;
++ }
++
+ ret = ar0231_probe(client, did);
+ if (!ret) {
+ chip_id = ID_AR0231;
+@@ -167,6 +175,9 @@ static int ov106xx_remove(struct i2c_client *client)
+ case ID_AR0233:
+ ar0233_remove(client);
+ break;
++ case ID_AR0323:
++ ar0323_remove(client);
++ break;
+ case ID_AP0101_AR014X:
+ ap0101_remove(client);
+ break;
+@@ -211,6 +222,6 @@ static struct i2c_driver ov106xx_i2c_driver = {
+
+ module_i2c_driver(ov106xx_i2c_driver);
+
+-MODULE_DESCRIPTION("SoC Camera driver for OV10635, OV490+OV10640, OV495+OV2775, AR0132/140/143/220/223, AP0101+AR014X");
++MODULE_DESCRIPTION("SoC Camera driver for OV10635, OV490+OV10640, OV495+OV2775, AR0132/140/143/220/223/323, AP0101+AR014X");
+ MODULE_AUTHOR("Vladimir Barinov");
+ MODULE_LICENSE("GPL");
+--
+2.7.4
+
diff --git a/bsp/meta-rcar/meta-rcar-gen3-adas/recipes-kernel/linux/linux-renesas/0134-lvds-add-ISX016-imager.patch b/bsp/meta-rcar/meta-rcar-gen3-adas/recipes-kernel/linux/linux-renesas/0134-lvds-add-ISX016-imager.patch
new file mode 100644
index 00000000..4cb8a11e
--- /dev/null
+++ b/bsp/meta-rcar/meta-rcar-gen3-adas/recipes-kernel/linux/linux-renesas/0134-lvds-add-ISX016-imager.patch
@@ -0,0 +1,729 @@
+From 5673a8e83d5cf9f345b2fbcbaf157ee00c60f521 Mon Sep 17 00:00:00 2001
+From: Vladimir Barinov <vladimir.barinov@cogentembedded.com>
+Date: Mon, 26 Nov 2018 23:28:23 +0300
+Subject: [PATCH 083/122] lvds: add ISX016 imager
+
+This adds ISX016 imager support
+
+Signed-off-by: Vladimir Barinov <vladimir.barinov@cogentembedded.com>
+---
+ drivers/media/i2c/soc_camera/isx016.c | 628 +++++++++++++++++++++++++++++++++
+ drivers/media/i2c/soc_camera/isx016.h | 27 ++
+ drivers/media/i2c/soc_camera/ov106xx.c | 11 +
+ 3 files changed, 666 insertions(+)
+ create mode 100644 drivers/media/i2c/soc_camera/isx016.c
+ create mode 100644 drivers/media/i2c/soc_camera/isx016.h
+
+diff --git a/drivers/media/i2c/soc_camera/isx016.c b/drivers/media/i2c/soc_camera/isx016.c
+new file mode 100644
+index 0000000..275bd8a
+--- /dev/null
++++ b/drivers/media/i2c/soc_camera/isx016.c
+@@ -0,0 +1,628 @@
++/*
++ * ON Semiconductor ISX016 sensor camera driver
++ *
++ * Copyright (C) 2018 Cogent Embedded, Inc.
++ *
++ * This program is free software; you can redistribute it and/or modify it
++ * under the terms of the GNU General Public License as published by the
++ * Free Software Foundation; either version 2 of the License, or (at your
++ * option) any later version.
++ */
++
++#include <linux/delay.h>
++#include <linux/init.h>
++#include <linux/i2c.h>
++#include <linux/module.h>
++#include <linux/of_graph.h>
++#include <linux/videodev2.h>
++
++#include <media/soc_camera.h>
++#include <media/v4l2-common.h>
++#include <media/v4l2-ctrls.h>
++
++#include "isx016.h"
++
++static const int isx016_i2c_addr[] = {0x1a};
++
++#define ISX016_PID 0x0000
++#define ISX016_VERSION_REG 0x0740
++
++#define ISX016_MEDIA_BUS_FMT MEDIA_BUS_FMT_YUYV8_2X8
++
++static void isx016_otp_id_read(struct i2c_client *client);
++
++struct isx016_priv {
++ struct v4l2_subdev sd;
++ struct v4l2_ctrl_handler hdl;
++ struct media_pad pad;
++ struct v4l2_rect rect;
++ int max_width;
++ int max_height;
++ int init_complete;
++ u8 id[6];
++ int exposure;
++ int gain;
++ int autogain;
++ /* serializers */
++ int max9286_addr;
++ int max9271_addr;
++ int port;
++ int gpio_resetb;
++ int gpio_fsin;
++};
++
++static inline struct isx016_priv *to_isx016(const struct i2c_client *client)
++{
++ return container_of(i2c_get_clientdata(client), struct isx016_priv, sd);
++}
++
++static void isx016_s_port(struct i2c_client *client, int fwd_en)
++{
++ struct isx016_priv *priv = to_isx016(client);
++ int tmp_addr;
++
++ if (priv->max9286_addr) {
++ tmp_addr = client->addr;
++ client->addr = priv->max9286_addr; /* Deserializer I2C address */
++ reg8_write(client, 0x0a, fwd_en ? 0x11 << priv->port : 0); /* Enable/disable reverse/forward control for this port */
++ usleep_range(5000, 5500); /* wait 5ms */
++ client->addr = tmp_addr;
++ };
++}
++
++static int isx016_read16(struct i2c_client *client, u8 category, u16 reg, u16 *val)
++{
++ int ret;
++ #define R_NUM_BYTES 9
++ #define R_NUM_CMDS 1
++ #define R_NUM_CMD_BYTES 6
++ #define R_CMD 1
++ #define R_BYTES 2
++ u8 buf[R_NUM_BYTES] = {R_NUM_BYTES, R_NUM_CMDS,
++ R_NUM_CMD_BYTES, R_CMD,
++ category, reg >> 8, reg & 0xff,
++ R_BYTES, 0x00};
++
++ /* calculate checksum */
++ buf[8] = R_NUM_BYTES + R_NUM_CMDS + R_NUM_CMD_BYTES + R_CMD +
++ category + (reg >> 8) + (reg & 0xff) + R_BYTES;
++
++ ret = i2c_master_send(client, buf, R_NUM_BYTES);
++ if (ret == R_NUM_BYTES)
++ ret = i2c_master_recv(client, buf, R_NUM_BYTES - 2);
++
++ if (ret < 0) {
++ dev_err(&client->dev,
++ "read fail: chip 0x%x register 0x%x: %d\n",
++ client->addr, reg, ret);
++ } else {
++ *val = ((u16)buf[4] << 8) | buf[5];
++ }
++
++ return ret < 0 ? ret : 0;
++}
++
++static int isx016_write16(struct i2c_client *client, u8 category, u16 reg, u16 val)
++{
++ int ret;
++ #define W_NUM_BYTES 10
++ #define W_NUM_CMDS 1
++ #define W_NUM_CMD_BYTES 7
++ #define W_CMD 2
++ u8 buf[W_NUM_BYTES] = {W_NUM_BYTES, W_NUM_CMDS,
++ W_NUM_CMD_BYTES, W_CMD,
++ category, reg >> 8, reg & 0xff,
++ val >> 8, val & 0xff};
++
++ /* calculate checksum */
++ buf[9] = W_NUM_BYTES + W_NUM_CMDS + W_NUM_CMD_BYTES + W_CMD +
++ category + (reg >> 8) + (reg & 0xff) + (val >> 8) + (val & 0xff);
++
++ ret = i2c_master_send(client, buf, W_NUM_BYTES);
++
++ if (ret < 0) {
++ dev_err(&client->dev,
++ "write fail: chip 0x%x register 0x%x: %d\n",
++ client->addr, reg, ret);
++ }
++
++ return ret < 0 ? ret : 0;
++}
++
++static int isx016_set_regs(struct i2c_client *client,
++ const struct isx016_reg *regs, int nr_regs)
++{
++ int i;
++
++ for (i = 0; i < nr_regs; i++) {
++ if (regs[i].reg == ISX016_DELAY) {
++ mdelay(regs[i].val);
++ continue;
++ }
++
++ isx016_write16(client, regs[i].reg >> 8, regs[i].reg & 0xff, regs[i].val);
++ }
++
++ return 0;
++}
++
++static int isx016_s_stream(struct v4l2_subdev *sd, int enable)
++{
++ return 0;
++}
++
++static int isx016_get_fmt(struct v4l2_subdev *sd,
++ struct v4l2_subdev_pad_config *cfg,
++ struct v4l2_subdev_format *format)
++{
++ struct v4l2_mbus_framefmt *mf = &format->format;
++ struct i2c_client *client = v4l2_get_subdevdata(sd);
++ struct isx016_priv *priv = to_isx016(client);
++
++ if (format->pad)
++ return -EINVAL;
++
++ mf->width = priv->rect.width;
++ mf->height = priv->rect.height;
++ mf->code = ISX016_MEDIA_BUS_FMT;
++ mf->colorspace = V4L2_COLORSPACE_SMPTE170M;
++ mf->field = V4L2_FIELD_NONE;
++
++ return 0;
++}
++
++static int isx016_set_fmt(struct v4l2_subdev *sd,
++ struct v4l2_subdev_pad_config *cfg,
++ struct v4l2_subdev_format *format)
++{
++ struct v4l2_mbus_framefmt *mf = &format->format;
++
++ mf->code = ISX016_MEDIA_BUS_FMT;
++ mf->colorspace = V4L2_COLORSPACE_SMPTE170M;
++ mf->field = V4L2_FIELD_NONE;
++
++ if (format->which == V4L2_SUBDEV_FORMAT_TRY)
++ cfg->try_fmt = *mf;
++
++ return 0;
++}
++
++static int isx016_enum_mbus_code(struct v4l2_subdev *sd,
++ struct v4l2_subdev_pad_config *cfg,
++ struct v4l2_subdev_mbus_code_enum *code)
++{
++ if (code->pad || code->index > 0)
++ return -EINVAL;
++
++ code->code = ISX016_MEDIA_BUS_FMT;
++
++ return 0;
++}
++
++static int isx016_get_edid(struct v4l2_subdev *sd, struct v4l2_edid *edid)
++{
++ struct i2c_client *client = v4l2_get_subdevdata(sd);
++ struct isx016_priv *priv = to_isx016(client);
++
++ isx016_otp_id_read(client);
++
++ memcpy(edid->edid, priv->id, 6);
++
++ edid->edid[6] = 0xff;
++ edid->edid[7] = client->addr;
++ edid->edid[8] = ISX016_VERSION_REG >> 8;
++ edid->edid[9] = ISX016_VERSION_REG & 0xff;
++
++ return 0;
++}
++
++static int isx016_set_selection(struct v4l2_subdev *sd,
++ struct v4l2_subdev_pad_config *cfg,
++ struct v4l2_subdev_selection *sel)
++{
++ struct v4l2_rect *rect = &sel->r;
++ struct i2c_client *client = v4l2_get_subdevdata(sd);
++ struct isx016_priv *priv = to_isx016(client);
++
++ if (sel->which != V4L2_SUBDEV_FORMAT_ACTIVE ||
++ sel->target != V4L2_SEL_TGT_CROP)
++ return -EINVAL;
++
++ rect->left = ALIGN(rect->left, 2);
++ rect->top = ALIGN(rect->top, 2);
++ rect->width = ALIGN(rect->width, 2);
++ rect->height = ALIGN(rect->height, 2);
++
++ if ((rect->left + rect->width > priv->max_width) ||
++ (rect->top + rect->height > priv->max_height))
++ *rect = priv->rect;
++
++ priv->rect.left = rect->left;
++ priv->rect.top = rect->top;
++ priv->rect.width = rect->width;
++ priv->rect.height = rect->height;
++
++ return 0;
++}
++
++static int isx016_get_selection(struct v4l2_subdev *sd,
++ struct v4l2_subdev_pad_config *cfg,
++ struct v4l2_subdev_selection *sel)
++{
++ struct i2c_client *client = v4l2_get_subdevdata(sd);
++ struct isx016_priv *priv = to_isx016(client);
++
++ if (sel->which != V4L2_SUBDEV_FORMAT_ACTIVE)
++ return -EINVAL;
++
++ switch (sel->target) {
++ case V4L2_SEL_TGT_CROP_BOUNDS:
++ sel->r.left = 0;
++ sel->r.top = 0;
++ sel->r.width = priv->max_width;
++ sel->r.height = priv->max_height;
++ return 0;
++ case V4L2_SEL_TGT_CROP_DEFAULT:
++ sel->r.left = 0;
++ sel->r.top = 0;
++ sel->r.width = priv->max_width;
++ sel->r.height = priv->max_height;
++ return 0;
++ case V4L2_SEL_TGT_CROP:
++ sel->r = priv->rect;
++ return 0;
++ default:
++ return -EINVAL;
++ }
++}
++
++static int isx016_g_mbus_config(struct v4l2_subdev *sd,
++ struct v4l2_mbus_config *cfg)
++{
++ cfg->flags = V4L2_MBUS_CSI2_1_LANE | V4L2_MBUS_CSI2_CHANNEL_0 |
++ V4L2_MBUS_CSI2_CONTINUOUS_CLOCK;
++ cfg->type = V4L2_MBUS_CSI2;
++
++ return 0;
++}
++
++#ifdef CONFIG_VIDEO_ADV_DEBUG
++static int isx016_g_register(struct v4l2_subdev *sd,
++ struct v4l2_dbg_register *reg)
++{
++ struct i2c_client *client = v4l2_get_subdevdata(sd);
++ int ret;
++ u16 val = 0;
++
++ ret = isx016_read16(client, (u16)reg->reg >> 8, (u16)reg->reg & 0xff, &val);
++ if (ret < 0)
++ return ret;
++
++ reg->val = val;
++ reg->size = sizeof(u16);
++
++ return 0;
++}
++
++static int isx016_s_register(struct v4l2_subdev *sd,
++ const struct v4l2_dbg_register *reg)
++{
++ struct i2c_client *client = v4l2_get_subdevdata(sd);
++
++ return isx016_write16(client, (u16)reg->reg >> 8, (u16)reg->reg & 0xff, (u16)reg->val);
++}
++#endif
++
++static struct v4l2_subdev_core_ops isx016_core_ops = {
++#ifdef CONFIG_VIDEO_ADV_DEBUG
++ .g_register = isx016_g_register,
++ .s_register = isx016_s_register,
++#endif
++};
++
++static int isx016_s_ctrl(struct v4l2_ctrl *ctrl)
++{
++ struct v4l2_subdev *sd = to_sd(ctrl);
++ struct i2c_client *client = v4l2_get_subdevdata(sd);
++ struct isx016_priv *priv = to_isx016(client);
++ int ret = -EINVAL;
++
++ if (!priv->init_complete)
++ return 0;
++
++ switch (ctrl->id) {
++ case V4L2_CID_BRIGHTNESS:
++ case V4L2_CID_CONTRAST:
++ case V4L2_CID_SATURATION:
++ case V4L2_CID_HUE:
++ case V4L2_CID_GAMMA:
++ case V4L2_CID_SHARPNESS:
++ case V4L2_CID_AUTOGAIN:
++ case V4L2_CID_GAIN:
++ case V4L2_CID_EXPOSURE:
++ case V4L2_CID_HFLIP:
++ case V4L2_CID_VFLIP:
++ break;
++ }
++
++ return ret;
++}
++
++static const struct v4l2_ctrl_ops isx016_ctrl_ops = {
++ .s_ctrl = isx016_s_ctrl,
++};
++
++static struct v4l2_subdev_video_ops isx016_video_ops = {
++ .s_stream = isx016_s_stream,
++ .g_mbus_config = isx016_g_mbus_config,
++};
++
++static const struct v4l2_subdev_pad_ops isx016_subdev_pad_ops = {
++ .get_edid = isx016_get_edid,
++ .enum_mbus_code = isx016_enum_mbus_code,
++ .get_selection = isx016_get_selection,
++ .set_selection = isx016_set_selection,
++ .get_fmt = isx016_get_fmt,
++ .set_fmt = isx016_set_fmt,
++};
++
++static struct v4l2_subdev_ops isx016_subdev_ops = {
++ .core = &isx016_core_ops,
++ .video = &isx016_video_ops,
++ .pad = &isx016_subdev_pad_ops,
++};
++
++static void isx016_otp_id_read(struct i2c_client *client)
++{
++ struct isx016_priv *priv = to_isx016(client);
++ int i;
++ u16 val = 0;
++
++ /* read camera id from isx016 OTP memory */
++ for (i = 0; i < 6; i+=2) {
++ isx016_read16(client, 8, 0x60 + i, &val);
++ priv->id[i] = val >> 8;
++ priv->id[i+1] = val & 0xff;
++ }
++}
++
++static ssize_t isx016_otp_id_show(struct device *dev,
++ struct device_attribute *attr, char *buf)
++{
++ struct v4l2_subdev *sd = i2c_get_clientdata(to_i2c_client(dev));
++ struct i2c_client *client = v4l2_get_subdevdata(sd);
++ struct isx016_priv *priv = to_isx016(client);
++
++ isx016_otp_id_read(client);
++
++ return snprintf(buf, 32, "%02x:%02x:%02x:%02x:%02x:%02x\n",
++ priv->id[0], priv->id[1], priv->id[2], priv->id[3], priv->id[4], priv->id[5]);
++}
++
++static DEVICE_ATTR(otp_id_isx016, S_IRUGO, isx016_otp_id_show, NULL);
++
++static int isx016_initialize(struct i2c_client *client)
++{
++ struct isx016_priv *priv = to_isx016(client);
++ u16 pid = 0;
++ int ret = 0;
++ int tmp_addr;
++ int i;
++
++ isx016_s_port(client, 1);
++
++ for (i = 0; i < ARRAY_SIZE(isx016_i2c_addr); i++) {
++ tmp_addr = client->addr;
++ if (priv->max9286_addr) {
++ client->addr = priv->max9271_addr; /* Serializer I2C address */
++ reg8_write(client, 0x0A, isx016_i2c_addr[i] << 1); /* Sensor native I2C address */
++ usleep_range(2000, 2500); /* wait 2ms */
++ };
++ client->addr = tmp_addr;
++
++ /* check model ID */
++ isx016_read16(client, 0, ISX016_PID, &pid);
++
++ if (pid == ISX016_VERSION_REG)
++ break;
++ }
++
++ if (pid != ISX016_VERSION_REG) {
++ dev_dbg(&client->dev, "Product ID error %x\n", pid);
++ ret = -ENODEV;
++ goto err;
++ }
++
++ priv->max_width = ISX016_MAX_WIDTH;
++ priv->max_height = ISX016_MAX_HEIGHT;
++
++ /* Read OTP IDs */
++ isx016_otp_id_read(client);
++ /* Program wizard registers */
++ isx016_set_regs(client, isx016_regs_wizard, ARRAY_SIZE(isx016_regs_wizard));
++
++ dev_info(&client->dev, "isx016 PID %x, res %dx%d, OTP_ID %02x:%02x:%02x:%02x:%02x:%02x\n",
++ pid, priv->max_width, priv->max_height, priv->id[0], priv->id[1], priv->id[2], priv->id[3], priv->id[4], priv->id[5]);
++err:
++ isx016_s_port(client, 0);
++
++ return ret;
++}
++
++static int isx016_parse_dt(struct device_node *np, struct isx016_priv *priv)
++{
++ struct i2c_client *client = v4l2_get_subdevdata(&priv->sd);
++ int i;
++ struct device_node *endpoint = NULL, *rendpoint = NULL;
++ int tmp_addr = 0;
++
++ for (i = 0; ; i++) {
++ endpoint = of_graph_get_next_endpoint(np, endpoint);
++ if (!endpoint)
++ break;
++
++ of_node_put(endpoint);
++
++ rendpoint = of_parse_phandle(endpoint, "remote-endpoint", 0);
++ if (!rendpoint)
++ continue;
++
++ if (!of_property_read_u32(rendpoint, "max9271-addr", &priv->max9271_addr) &&
++ !of_property_read_u32(rendpoint->parent->parent, "reg", &priv->max9286_addr) &&
++ !kstrtouint(strrchr(rendpoint->full_name, '@') + 1, 0, &priv->port))
++ break;
++ }
++
++ if (!priv->max9286_addr) {
++ dev_err(&client->dev, "deserializer does not present for ISX016\n");
++ return -EINVAL;
++ }
++
++ isx016_s_port(client, 1);
++
++ /* setup I2C translator address */
++ tmp_addr = client->addr;
++ if (priv->max9286_addr) {
++ client->addr = priv->max9271_addr; /* Serializer I2C address */
++ reg8_write(client, 0x09, tmp_addr << 1); /* Sensor translated I2C address */
++ usleep_range(2000, 2500); /* wait 2ms */
++ };
++ client->addr = tmp_addr;
++
++ mdelay(10);
++
++ return 0;
++}
++
++static int isx016_probe(struct i2c_client *client,
++ const struct i2c_device_id *did)
++{
++ struct isx016_priv *priv;
++ int ret;
++
++ priv = devm_kzalloc(&client->dev, sizeof(*priv), GFP_KERNEL);
++ if (!priv)
++ return -ENOMEM;
++
++ v4l2_i2c_subdev_init(&priv->sd, client, &isx016_subdev_ops);
++ priv->sd.flags = V4L2_SUBDEV_FL_HAS_DEVNODE;
++
++ priv->exposure = 0x100;
++ priv->gain = 0x100;
++ priv->autogain = 1;
++ v4l2_ctrl_handler_init(&priv->hdl, 4);
++ v4l2_ctrl_new_std(&priv->hdl, &isx016_ctrl_ops,
++ V4L2_CID_BRIGHTNESS, 0, 16, 1, 7);
++ v4l2_ctrl_new_std(&priv->hdl, &isx016_ctrl_ops,
++ V4L2_CID_CONTRAST, 0, 16, 1, 7);
++ v4l2_ctrl_new_std(&priv->hdl, &isx016_ctrl_ops,
++ V4L2_CID_SATURATION, 0, 7, 1, 2);
++ v4l2_ctrl_new_std(&priv->hdl, &isx016_ctrl_ops,
++ V4L2_CID_HUE, 0, 23, 1, 12);
++ v4l2_ctrl_new_std(&priv->hdl, &isx016_ctrl_ops,
++ V4L2_CID_GAMMA, -128, 128, 1, 0);
++ v4l2_ctrl_new_std(&priv->hdl, &isx016_ctrl_ops,
++ V4L2_CID_SHARPNESS, 0, 10, 1, 3);
++ v4l2_ctrl_new_std(&priv->hdl, &isx016_ctrl_ops,
++ V4L2_CID_AUTOGAIN, 0, 1, 1, priv->autogain);
++ v4l2_ctrl_new_std(&priv->hdl, &isx016_ctrl_ops,
++ V4L2_CID_GAIN, 0, 0xffff, 1, priv->gain);
++ v4l2_ctrl_new_std(&priv->hdl, &isx016_ctrl_ops,
++ V4L2_CID_EXPOSURE, 0, 0xffff, 1, priv->exposure);
++ v4l2_ctrl_new_std(&priv->hdl, &isx016_ctrl_ops,
++ V4L2_CID_HFLIP, 0, 1, 1, 1);
++ v4l2_ctrl_new_std(&priv->hdl, &isx016_ctrl_ops,
++ V4L2_CID_VFLIP, 0, 1, 1, 0);
++ priv->sd.ctrl_handler = &priv->hdl;
++
++ ret = priv->hdl.error;
++ if (ret)
++ goto cleanup;
++
++ v4l2_ctrl_handler_setup(&priv->hdl);
++
++ priv->pad.flags = MEDIA_PAD_FL_SOURCE;
++ priv->sd.entity.flags |= MEDIA_ENT_F_CAM_SENSOR;
++ ret = media_entity_pads_init(&priv->sd.entity, 1, &priv->pad);
++ if (ret < 0)
++ goto cleanup;
++
++ ret = isx016_parse_dt(client->dev.of_node, priv);
++ if (ret)
++ goto cleanup;
++
++ ret = isx016_initialize(client);
++ if (ret < 0)
++ goto cleanup;
++
++ priv->rect.left = 0;
++ priv->rect.top = 0;
++ priv->rect.width = priv->max_width;
++ priv->rect.height = priv->max_height;
++
++ ret = v4l2_async_register_subdev(&priv->sd);
++ if (ret)
++ goto cleanup;
++
++ if (device_create_file(&client->dev, &dev_attr_otp_id_isx016) != 0) {
++ dev_err(&client->dev, "sysfs otp_id entry creation failed\n");
++ goto cleanup;
++ }
++
++ priv->init_complete = 1;
++
++ return 0;
++
++cleanup:
++ media_entity_cleanup(&priv->sd.entity);
++ v4l2_ctrl_handler_free(&priv->hdl);
++ v4l2_device_unregister_subdev(&priv->sd);
++#ifdef CONFIG_SOC_CAMERA_ISX016
++ v4l_err(client, "failed to probe @ 0x%02x (%s)\n",
++ client->addr, client->adapter->name);
++#endif
++ return ret;
++}
++
++static int isx016_remove(struct i2c_client *client)
++{
++ struct isx016_priv *priv = i2c_get_clientdata(client);
++
++ device_remove_file(&client->dev, &dev_attr_otp_id_isx016);
++ v4l2_async_unregister_subdev(&priv->sd);
++ media_entity_cleanup(&priv->sd.entity);
++ v4l2_ctrl_handler_free(&priv->hdl);
++ v4l2_device_unregister_subdev(&priv->sd);
++
++ return 0;
++}
++
++#ifdef CONFIG_SOC_CAMERA_ISX016
++static const struct i2c_device_id isx016_id[] = {
++ { "isx016", 0 },
++ { }
++};
++MODULE_DEVICE_TABLE(i2c, isx016_id);
++
++static const struct of_device_id isx016_of_ids[] = {
++ { .compatible = "aptina,isx016", },
++ { }
++};
++MODULE_DEVICE_TABLE(of, isx016_of_ids);
++
++static struct i2c_driver isx016_i2c_driver = {
++ .driver = {
++ .name = "isx016",
++ .of_match_table = isx016_of_ids,
++ },
++ .probe = isx016_probe,
++ .remove = isx016_remove,
++ .id_table = isx016_id,
++};
++
++module_i2c_driver(isx016_i2c_driver);
++
++MODULE_DESCRIPTION("SoC Camera driver for ISX016");
++MODULE_AUTHOR("Vladimir Barinov");
++MODULE_LICENSE("GPL");
++#endif
+diff --git a/drivers/media/i2c/soc_camera/isx016.h b/drivers/media/i2c/soc_camera/isx016.h
+new file mode 100644
+index 0000000..f20d735
+--- /dev/null
++++ b/drivers/media/i2c/soc_camera/isx016.h
+@@ -0,0 +1,27 @@
++/*
++ * ON Semiconductor isx016 sensor camera wizard 1280x800@30/UYVY/BT601/8bit
++ *
++ * Copyright (C) 2018 Cogent Embedded, Inc.
++ *
++ * This program is free software; you can redistribute it and/or modify it
++ * under the terms of the GNU General Public License as published by the
++ * Free Software Foundation; either version 2 of the License, or (at your
++ * option) any later version.
++ */
++
++#define ISX016_MAX_WIDTH 1280
++#define ISX016_MAX_HEIGHT 800
++
++#define ISX016_DELAY 0xffff
++
++struct isx016_reg {
++ u16 reg;
++ u16 val;
++};
++
++static const struct isx016_reg isx016_regs_wizard[] = {
++#if 0
++/* enable FSIN */
++#endif
++{ISX016_DELAY, 100},
++};
+diff --git a/drivers/media/i2c/soc_camera/ov106xx.c b/drivers/media/i2c/soc_camera/ov106xx.c
+index 906ec7e..d6df193 100644
+--- a/drivers/media/i2c/soc_camera/ov106xx.c
++++ b/drivers/media/i2c/soc_camera/ov106xx.c
+@@ -24,6 +24,7 @@
+ #include "ov2775.c"
+ #include "imx390.c"
+ #include "ox03a.c"
++#include "isx016.c"
+
+ static enum {
+ ID_OV10635,
+@@ -41,6 +42,7 @@ static enum {
+ ID_OV2775,
+ ID_IMX390,
+ ID_OX03A,
++ ID_ISX016,
+ } chip_id;
+
+ static int ov106xx_probe(struct i2c_client *client,
+@@ -139,6 +141,12 @@ static int ov106xx_probe(struct i2c_client *client,
+ goto out;
+ }
+
++ ret = isx016_probe(client, did);
++ if (!ret) {
++ chip_id = ID_ISX016;
++ goto out;
++ }
++
+ v4l_err(client, "failed to probe @ 0x%02x (%s)\n",
+ client->addr, client->adapter->name);
+ out:
+@@ -193,6 +201,9 @@ static int ov106xx_remove(struct i2c_client *client)
+ case ID_OX03A:
+ ox03a_remove(client);
+ break;
++ case ID_ISX016:
++ isx016_remove(client);
++ break;
+ };
+
+ return 0;
+--
+2.7.4
+
diff --git a/bsp/meta-rcar/meta-rcar-gen3-adas/recipes-kernel/linux/linux-renesas/0135-LVDS-ar0233-set-frame-size-1920x1200.patch b/bsp/meta-rcar/meta-rcar-gen3-adas/recipes-kernel/linux/linux-renesas/0135-LVDS-ar0233-set-frame-size-1920x1200.patch
new file mode 100644
index 00000000..0796810a
--- /dev/null
+++ b/bsp/meta-rcar/meta-rcar-gen3-adas/recipes-kernel/linux/linux-renesas/0135-LVDS-ar0233-set-frame-size-1920x1200.patch
@@ -0,0 +1,104 @@
+From 6e4407c3dfdcb3694b860d09024020135071343e Mon Sep 17 00:00:00 2001
+From: Vladimir Barinov <vladimir.barinov@cogentembedded.com>
+Date: Sat, 15 Dec 2018 18:32:45 +0300
+Subject: [PATCH 084/122] LVDS: ar0233: set frame size 1920x1200
+
+1) Set default frame seze 1920x1200 accordingly to sequencer
+2) add crop possibility in imager
+---
+ drivers/media/i2c/soc_camera/ar0233.c | 21 +++++++++++++++++++++
+ drivers/media/i2c/soc_camera/ar0233.h | 21 +++++++++++----------
+ 2 files changed, 32 insertions(+), 10 deletions(-)
+
+diff --git a/drivers/media/i2c/soc_camera/ar0233.c b/drivers/media/i2c/soc_camera/ar0233.c
+index 6d034e2..7c1141c 100644
+--- a/drivers/media/i2c/soc_camera/ar0233.c
++++ b/drivers/media/i2c/soc_camera/ar0233.c
+@@ -71,6 +71,25 @@ static int ar0233_s_stream(struct v4l2_subdev *sd, int enable)
+ return 0;
+ }
+
++static int ar0233_set_window(struct v4l2_subdev *sd)
++{
++ struct i2c_client *client = v4l2_get_subdevdata(sd);
++ struct ar0233_priv *priv = to_ar0233(client);
++
++ dev_err(&client->dev, "L=%d T=%d %dx%d\n", priv->rect.left, priv->rect.top, priv->rect.width, priv->rect.height);
++
++ /* horiz crop start */
++ reg16_write16(client, 0x3004, priv->rect.left);
++ /* horiz crop end */
++ reg16_write16(client, 0x3008, priv->rect.left + priv->rect.width - 1);
++ /* vert crop start */
++ reg16_write16(client, 0x3002, priv->rect.top);
++ /* vert crop end */
++ reg16_write16(client, 0x3006, priv->rect.top + priv->rect.height + 1);
++
++ return 0;
++};
++
+ static int ar0233_get_fmt(struct v4l2_subdev *sd,
+ struct v4l2_subdev_pad_config *cfg,
+ struct v4l2_subdev_format *format)
+@@ -160,6 +179,8 @@ static int ar0233_set_selection(struct v4l2_subdev *sd,
+ priv->rect.width = rect->width;
+ priv->rect.height = rect->height;
+
++ ar0233_set_window(sd);
++
+ return 0;
+ }
+
+diff --git a/drivers/media/i2c/soc_camera/ar0233.h b/drivers/media/i2c/soc_camera/ar0233.h
+index f88e5a3..ad65390 100644
+--- a/drivers/media/i2c/soc_camera/ar0233.h
++++ b/drivers/media/i2c/soc_camera/ar0233.h
+@@ -12,13 +12,13 @@
+ //#define AR0233_DISPLAY_PATTERN_FIXED
+ //#define AR0233_DISPLAY_PATTERN_COLOR_BAR
+
+-#define AR0233_MAX_WIDTH 1792 //1920
+-#define AR0233_MAX_HEIGHT 1080
++#define AR0233_MAX_WIDTH 1920
++#define AR0233_MAX_HEIGHT 1200
+
+ #define AR0233_DELAY 0xffff
+
+ #define AR0233_SENSOR_WIDTH 1920
+-#define AR0233_SENSOR_HEIGHT 1280
++#define AR0233_SENSOR_HEIGHT 1200
+
+ #define AR0233_X_START ((AR0233_SENSOR_WIDTH - AR0233_MAX_WIDTH) / 2)
+ #define AR0233_Y_START ((AR0233_SENSOR_HEIGHT - AR0233_MAX_HEIGHT) / 2)
+@@ -311,12 +311,13 @@ static const struct ar0233_reg ar0233_regs_wizard[] = {
+ {0x32D6, 0x3C04},
+ {0x32DC, 0x370A},
+ {0x30B0, 0x0800},
+-{0x302A, 0x0006},
+-{0x302C, 0x0001},
+-{0x302E, 0x0002},
+-{0x3030, 0x002C},
+-{0x3036, 0x000C},
+-{0x3038, 0x0001},
++/* PCLK=22Mhz/2 *44/1/6= 88.6Mhz - TI serializers */
++{0x302A, 6}, // VT_PIX_CLK_DIV
++{0x302C, 1}, // VT_SYS_CLK_DIV
++{0x302E, 2}, // PRE_PLL_CLK_DIV
++{0x3030, 44}, // PLL_MULTIPLIER
++{0x3036, 0x000C}, // OP_WORD_CLK_DIV
++{0x3038, 0x0001}, // OP_SYS_CLK_DIV
+ {0x30B0, 0x0A00},
+ {0x30A2, 0x0001},
+ {0x30A6, 0x0001},
+@@ -355,7 +356,7 @@ static const struct ar0233_reg ar0233_regs_wizard[] = {
+ {0x300A, AR0233_SENSOR_HEIGHT + 356}, // FRAME_LENGTH_LINES_
+ {0x300C, AR0233_SENSOR_WIDTH + 100}, // LINE_LENGTH_PCK_
+ #else
+-{0x300A, AR0233_SENSOR_HEIGHT + 208}, // FRAME_LENGTH_LINES_
++{0x300A, AR0233_SENSOR_HEIGHT + 288}, // FRAME_LENGTH_LINES_
+ {0x300C, AR0233_SENSOR_WIDTH + 300}, // LINE_LENGTH_PCK_
+ #endif
+ {0x3042, 0x0000},
+--
+2.7.4
+
diff --git a/bsp/meta-rcar/meta-rcar-gen3-adas/recipes-kernel/linux/linux-renesas/0136-lvds-AR0233-add-different-vendor.patch b/bsp/meta-rcar/meta-rcar-gen3-adas/recipes-kernel/linux/linux-renesas/0136-lvds-AR0233-add-different-vendor.patch
new file mode 100644
index 00000000..34d07a86
--- /dev/null
+++ b/bsp/meta-rcar/meta-rcar-gen3-adas/recipes-kernel/linux/linux-renesas/0136-lvds-AR0233-add-different-vendor.patch
@@ -0,0 +1,258 @@
+From 805e485b11c5aafacd2ab16a2d699c904ba13372 Mon Sep 17 00:00:00 2001
+From: Vladimir Barinov <vladimir.barinov@cogentembedded.com>
+Date: Wed, 19 Dec 2018 00:02:17 +0300
+Subject: [PATCH 085/122] lvds: AR0233 add different vendor
+
+This adds possibility to setup cameras with different
+gpio connection using dts or command line:
+ti9x4.gpioX
+---
+ drivers/media/i2c/soc_camera/ar0233.c | 36 ++++++++++++++++++----------
+ drivers/media/i2c/soc_camera/ov106xx.c | 12 +++++-----
+ drivers/media/i2c/soc_camera/ti9x4.c | 44 +++++++++++++++++++++++++++-------
+ 3 files changed, 64 insertions(+), 28 deletions(-)
+
+diff --git a/drivers/media/i2c/soc_camera/ar0233.c b/drivers/media/i2c/soc_camera/ar0233.c
+index 7c1141c..74ecc85 100644
+--- a/drivers/media/i2c/soc_camera/ar0233.c
++++ b/drivers/media/i2c/soc_camera/ar0233.c
+@@ -22,7 +22,7 @@
+
+ #include "ar0233.h"
+
+-#define AR0233_I2C_ADDR 0x10
++static const int ar0233_i2c_addr[] = {0x10, 0x20};
+
+ #define AR0233_PID 0x3000
+ #define AR0233_VERSION_REG 0x0354
+@@ -380,9 +380,23 @@ static int ar0233_initialize(struct i2c_client *client)
+ u16 pid = 0;
+ int ret = 0;
+ int tmp_addr;
++ int i;
++
++ for (i = 0; i < ARRAY_SIZE(ar0233_i2c_addr); i++) {
++ tmp_addr = client->addr;
++ if (priv->ti9x4_addr) {
++ client->addr = priv->ti9x4_addr;/* Deserializer I2C address */
++ reg8_write(client, 0x5d, ar0233_i2c_addr[i] << 1); /* Sensor native I2C address */
++ usleep_range(2000, 2500); /* wait 2ms */
++ }
++ client->addr = tmp_addr;
+
+- /* check and show model ID */
+- reg16_read16(client, AR0233_PID, &pid);
++ /* check model ID */
++ reg16_read16(client, AR0233_PID, &pid);
++
++ if (pid == AR0233_VERSION_REG)
++ break;
++ }
+
+ if (pid != AR0233_VERSION_REG) {
+ dev_dbg(&client->dev, "Product ID error %x\n", pid);
+@@ -395,12 +409,16 @@ static int ar0233_initialize(struct i2c_client *client)
+ if (priv->ti9x4_addr) {
+ /* CLK_OUT=22.5792*160*M/N/CLKDIV -> CLK_OUT=27MHz: CLKDIV=2, M=15, N=251: 22.5792*160/8*15/251=26.987MHz=CLK_OUT */
+ client->addr = priv->ti9x3_addr; /* Serializer I2C address */
++#if 0
+ reg8_write(client, 0x06, 0x6f); /* Set CLKDIV and M */
+ reg8_write(client, 0x07, 0xfb); /* Set N */
+- reg8_write(client, 0x0e, 0x1f); /* Set FSIN GPIO to output */
++#endif
++ reg8_write(client, 0x0e, 0xf0); /* Enable all remote gpios */
+ }
+ client->addr = tmp_addr;
+
++ /* Read OTP IDs */
++ ar0233_otp_id_read(client);
+ /* Program wizard registers */
+ ar0233_set_regs(client, ar0233_regs_wizard, ARRAY_SIZE(ar0233_regs_wizard));
+
+@@ -409,9 +427,6 @@ static int ar0233_initialize(struct i2c_client *client)
+ val |= (1 << 2); // Set streamOn bit
+ reg16_write16(client, 0x301a, val); // Start Streaming
+
+- /* Read OTP IDs */
+- ar0233_otp_id_read(client);
+-
+ dev_info(&client->dev, "ar0233 PID %x, res %dx%d, OTP_ID %02x:%02x:%02x:%02x:%02x:%02x\n",
+ pid, AR0233_MAX_WIDTH, AR0233_MAX_HEIGHT, priv->id[0], priv->id[1], priv->id[2], priv->id[3], priv->id[4], priv->id[5]);
+ err:
+@@ -444,7 +459,7 @@ static int ar0233_parse_dt(struct device_node *np, struct ar0233_priv *priv)
+ of_node_put(endpoint);
+
+ if (!priv->ti9x4_addr) {
+- dev_err(&client->dev, "deserializer does not present\n");
++ dev_dbg(&client->dev, "deserializer does not present\n");
+ return -EINVAL;
+ }
+
+@@ -456,14 +471,9 @@ static int ar0233_parse_dt(struct device_node *np, struct ar0233_priv *priv)
+ reg8_write(client, 0x4c, (priv->port << 4) | (1 << priv->port)); /* Select RX port number */
+ usleep_range(2000, 2500); /* wait 2ms */
+ reg8_write(client, 0x65, tmp_addr << 1); /* Sensor translated I2C address */
+- reg8_write(client, 0x5d, AR0233_I2C_ADDR << 1); /* Sensor native I2C address */
+-
+- reg8_write(client, 0x6e, 0x8a); /* GPIO0 - fsin, GPIO1 - NC */
+ }
+ client->addr = tmp_addr;
+
+- mdelay(10);
+-
+ return 0;
+ }
+
+diff --git a/drivers/media/i2c/soc_camera/ov106xx.c b/drivers/media/i2c/soc_camera/ov106xx.c
+index d6df193..e5d6b67 100644
+--- a/drivers/media/i2c/soc_camera/ov106xx.c
++++ b/drivers/media/i2c/soc_camera/ov106xx.c
+@@ -51,6 +51,12 @@ static int ov106xx_probe(struct i2c_client *client,
+ int ret;
+ chip_id = -EINVAL;
+
++ ret = ar0233_probe(client, did);
++ if (!ret) {
++ chip_id = ID_AR0233;
++ goto out;
++ }
++
+ ret = ov10635_probe(client, did);
+ if (!ret) {
+ chip_id = ID_OV10635;
+@@ -93,12 +99,6 @@ static int ov106xx_probe(struct i2c_client *client,
+ goto out;
+ }
+
+- ret = ar0233_probe(client, did);
+- if (!ret) {
+- chip_id = ID_AR0233;
+- goto out;
+- }
+-
+ ret = ar0323_probe(client, did);
+ if (!ret) {
+ chip_id = ID_AR0323;
+diff --git a/drivers/media/i2c/soc_camera/ti9x4.c b/drivers/media/i2c/soc_camera/ti9x4.c
+index effcf6c..d03c0f9 100644
+--- a/drivers/media/i2c/soc_camera/ti9x4.c
++++ b/drivers/media/i2c/soc_camera/ti9x4.c
+@@ -44,6 +44,7 @@ struct ti9x4_priv {
+ int ser_id;
+ int vc_map;
+ int csi_map;
++ int gpio[4];
+ struct gpio_desc *pwen; /* chip power en */
+ struct gpio_desc *poc_gpio[4]; /* PoC power supply */
+ struct v4l2_clk *ref_clk; /* ref clock */
+@@ -81,6 +82,16 @@ static int csi_map = 0;
+ module_param(csi_map, int, 0644);
+ MODULE_PARM_DESC(csi_map, " CSI TX MAP (default: 0 - forwarding of all links to CSI0)");
+
++static int gpio0 = 0, gpio1 = 0, gpio2 = 0, gpio3 = 0;
++module_param(gpio0, int, 0644);
++MODULE_PARM_DESC(gpio0, " GPIO0 function select (default: GPIO0 low level)");
++module_param(gpio1, int, 0644);
++MODULE_PARM_DESC(gpio1, " GPIO1 function select (default: GPIO1 low level)");
++module_param(gpio2, int, 0644);
++MODULE_PARM_DESC(gpio2, " GPIO2 function select (default: GPIO2 low level)");
++module_param(gpio3, int, 0644);
++MODULE_PARM_DESC(gpio3, " GPIO3 function select (default: GPIO3 low level)");
++
+ #ifdef TI954_SILICON_ERRATA
+ static int indirect_write(struct i2c_client *client, unsigned int page, u8 reg, u8 val)
+ {
+@@ -204,9 +215,6 @@ static void ti9x4_initial_setup(struct i2c_client *client)
+ #endif
+ }
+
+-//#define SENSOR_ID 0x30 // ov10635
+-//#define SENSOR_ID 0x24 // ov490
+-
+ static void ti9x4_fpdlink3_setup(struct i2c_client *client, int idx)
+ {
+ struct ti9x4_priv *priv = i2c_get_clientdata(client);
+@@ -230,7 +238,7 @@ static void ti9x4_fpdlink3_setup(struct i2c_client *client, int idx)
+ }
+
+ reg8_write(client, 0x5c, priv->ti9x3_addr_map[idx] << 1); /* TI9X3 I2C addr */
+-// reg8_write(client, 0x5d, SENSOR_ID << 1); /* SENSOR I2C native - must be set by sensor driver */
++// reg8_write(client, 0x5d, 0x30 << 1); /* SENSOR I2C native - must be set by sensor driver */
+ // reg8_write(client, 0x65, (0x60 + idx) << 1); /* SENSOR I2C translated - must be set by sensor driver */
+
+ if (priv->is_coax)
+@@ -262,7 +270,8 @@ static void ti9x4_fpdlink3_setup(struct i2c_client *client, int idx)
+ reg8_write(client, 0x70, ((priv->vc_map >> (idx * 4)) << 6) | 0x1e); /* CSI data type: yuv422 8-bit, assign VC */
+ reg8_write(client, 0x71, ((priv->vc_map >> (idx * 4)) << 6) | 0x2c); /* CSI data type: RAW12, assign VC */
+ reg8_write(client, 0xbc, 0x00); /* Setup minimal time between FV and LV to 3 PCLKs */
+- reg8_write(client, 0x6e, 0x88); /* Sensor reset: backchannel GPIO0/GPIO1 set low */
++ reg8_write(client, 0x6e, 0x88 | (priv->gpio[1] << 4) | priv->gpio[0]); /* Remote GPIO1/GPIO0 setup */
++ reg8_write(client, 0x6f, 0x88 | (priv->gpio[3] << 4) | priv->gpio[2]); /* Remote GPIO3/GPIO2 setup */
+ reg8_write(client, 0x72, priv->vc_map >> (idx * 4)); /* CSI VC MAP */
+ }
+
+@@ -285,6 +294,10 @@ static int ti9x4_initialize(struct i2c_client *client)
+ ti9x4_fpdlink3_setup(client, idx);
+ }
+
++ /* extra delay to wait imager power up */
++ if (priv->poc_delay)
++ mdelay(350);
++
+ client->addr = priv->des_addr;
+
+ return 0;
+@@ -369,7 +382,7 @@ static int ti9x4_parse_dt(struct i2c_client *client)
+ char forwarding_mode_default[20] = "round-robin"; /* round-robin, synchronized */
+ struct property *csi_rate_prop, *dvp_order_prop;
+ u8 val = 0;
+- char poc_name[10];
++ char name[10];
+
+ if (of_property_read_u32(np, "ti,links", &priv->links))
+ priv->links = 4;
+@@ -391,8 +404,8 @@ static int ti9x4_parse_dt(struct i2c_client *client)
+ }
+
+ for (i = 0; i < 4; i++) {
+- sprintf(poc_name, "POC%d", i);
+- priv->poc_gpio[i] = devm_gpiod_get_optional(&client->dev, kstrdup(poc_name, GFP_KERNEL), 0);
++ sprintf(name, "POC%d", i);
++ priv->poc_gpio[i] = devm_gpiod_get_optional(&client->dev, kstrdup(name, GFP_KERNEL), 0);
+ }
+
+ reg8_read(client, 0x00, &val); /* read TI9x4 I2C address */
+@@ -429,9 +442,14 @@ static int ti9x4_parse_dt(struct i2c_client *client)
+ if (of_property_read_u32(np, "ti,ser_id", &priv->ser_id))
+ priv->ser_id = TI913_ID;
+ if (of_property_read_u32(np, "ti,poc-delay", &priv->poc_delay))
+- priv->poc_delay = 50;
++ priv->poc_delay = 10;
+ if (of_property_read_u32(np, "ti,vc-map", &priv->vc_map))
+ priv->vc_map = 0x3210;
++ for (i = 0; i < 4; i++) {
++ sprintf(name, "ti,gpio%d", i);
++ if (of_property_read_u32(np, name, &priv->gpio[i]))
++ priv->gpio[i] = 0;
++ }
+
+ /*
+ * CSI forwarding of all links is to CSI0 by default.
+@@ -469,6 +487,14 @@ static int ti9x4_parse_dt(struct i2c_client *client)
+ priv->vc_map = vc_map;
+ if (csi_map)
+ priv->csi_map = csi_map;
++ if (gpio0)
++ priv->gpio[0] = gpio0;
++ if (gpio1)
++ priv->gpio[1] = gpio1;
++ if (gpio2)
++ priv->gpio[2] = gpio2;
++ if (gpio3)
++ priv->gpio[3] = gpio3;
+
+ for (i = 0; ; i++) {
+ endpoint = of_graph_get_next_endpoint(np, endpoint);
+--
+2.7.4
+
diff --git a/bsp/meta-rcar/meta-rcar-gen3-adas/recipes-kernel/linux/linux-renesas/0137-lvds-poll-ub960-deserializer-lock-status.patch b/bsp/meta-rcar/meta-rcar-gen3-adas/recipes-kernel/linux/linux-renesas/0137-lvds-poll-ub960-deserializer-lock-status.patch
new file mode 100644
index 00000000..4d6ef176
--- /dev/null
+++ b/bsp/meta-rcar/meta-rcar-gen3-adas/recipes-kernel/linux/linux-renesas/0137-lvds-poll-ub960-deserializer-lock-status.patch
@@ -0,0 +1,70 @@
+From df920df1a7a26dd4b49f90d4ce4e94b2541348d6 Mon Sep 17 00:00:00 2001
+From: Vladimir Barinov <vladimir.barinov@cogentembedded.com>
+Date: Thu, 3 Jan 2019 23:24:03 +0300
+Subject: [PATCH 086/122] lvds: poll ub960 deserializer lock status
+
+Poll FPDLINK lock status instead delay
+
+Signed-off-by: Vladimir Barinov <vladimir.barinov@cogentembedded.com>
+---
+ drivers/media/i2c/soc_camera/ti9x4.c | 35 ++++++++++++++++++++++++++++++-----
+ 1 file changed, 30 insertions(+), 5 deletions(-)
+
+diff --git a/drivers/media/i2c/soc_camera/ti9x4.c b/drivers/media/i2c/soc_camera/ti9x4.c
+index d03c0f9..f0b782f 100644
+--- a/drivers/media/i2c/soc_camera/ti9x4.c
++++ b/drivers/media/i2c/soc_camera/ti9x4.c
+@@ -278,7 +278,9 @@ static void ti9x4_fpdlink3_setup(struct i2c_client *client, int idx)
+ static int ti9x4_initialize(struct i2c_client *client)
+ {
+ struct ti9x4_priv *priv = i2c_get_clientdata(client);
+- int idx;
++ int idx, timeout;
++ u8 port_sts1 = 0, port_sts2 = 0;
++ int tmp_addr;
+
+ dev_info(&client->dev, "LINKs=%d, LANES=%d, FORWARDING=%s, CABLE=%s, ID=%s\n",
+ priv->links, priv->lanes, priv->forwarding_mode, priv->is_coax ? "coax" : "stp", priv->chip_id);
+@@ -294,12 +296,35 @@ static int ti9x4_initialize(struct i2c_client *client)
+ ti9x4_fpdlink3_setup(client, idx);
+ }
+
+- /* extra delay to wait imager power up */
+- if (priv->poc_delay)
+- mdelay(350);
+-
+ client->addr = priv->des_addr;
+
++ /* check lock status */
++ for (timeout = 500 / priv->links; timeout > 0; timeout--) {
++ for (idx = 0; idx < priv->links; idx++) {
++ reg8_write(client, 0x4c, (idx << 4) | (1 << idx)); /* Select RX port number */
++ usleep_range(1000, 1500); /* wait 1ms */
++ reg8_read(client, 0x4d, &port_sts1); /* Lock status */
++ reg8_read(client, 0x4e, &port_sts2); /* Freq stable */
++
++ if (port_sts1 & 0x1) {
++ tmp_addr = client->addr;
++ client->addr = priv->ti9x3_addr_map[idx]; /* TI9X3 I2C addr */
++ reg8_write(client, 0x0d, 0xf0); /* Enable all remote GPIOs */
++ reg8_write(client, 0x0e, 0xf0); /* Enable serializer GPIOs */
++ client->addr = tmp_addr;
++ }
++
++ if ((port_sts1 & 0x1) && (port_sts2 & 0x4))
++ goto out;
++ }
++ }
++
++ if (!timeout)
++ dev_info(&client->dev, "Receiver is not locked\n");
++out:
++ if (priv->poc_delay)
++ mdelay(100);
++
+ return 0;
+ }
+
+--
+2.7.4
+
diff --git a/bsp/meta-rcar/meta-rcar-gen3-adas/recipes-kernel/linux/linux-renesas/0138-lvds-AR0231-modify-with-rev7-silicon.patch b/bsp/meta-rcar/meta-rcar-gen3-adas/recipes-kernel/linux/linux-renesas/0138-lvds-AR0231-modify-with-rev7-silicon.patch
new file mode 100644
index 00000000..41161415
--- /dev/null
+++ b/bsp/meta-rcar/meta-rcar-gen3-adas/recipes-kernel/linux/linux-renesas/0138-lvds-AR0231-modify-with-rev7-silicon.patch
@@ -0,0 +1,633 @@
+From 4b901263653537d51deedc2d078086ccf7f2cfb4 Mon Sep 17 00:00:00 2001
+From: Vladimir Barinov <vladimir.barinov@cogentembedded.com>
+Date: Thu, 3 Jan 2019 23:29:56 +0300
+Subject: [PATCH 087/122] lvds: AR0231 modify with rev7 silicon
+
+Use rev7 setup for AR0231.
+Use MAX9286 and UB960 deserializer.
+Use multiple sensor i2c addresses
+Add crop
+
+Signed-off-by: Vladimir Barinov <vladimir.barinov@cogentembedded.com>
+---
+ drivers/media/i2c/soc_camera/ar0231.c | 86 ++++--
+ drivers/media/i2c/soc_camera/ar0231_rev7.h | 418 +++++++++++++++++++++++++++++
+ drivers/media/i2c/soc_camera/ov106xx.c | 12 +-
+ 3 files changed, 493 insertions(+), 23 deletions(-)
+ create mode 100644 drivers/media/i2c/soc_camera/ar0231_rev7.h
+
+diff --git a/drivers/media/i2c/soc_camera/ar0231.c b/drivers/media/i2c/soc_camera/ar0231.c
+index 176e1bf..f575cb7 100644
+--- a/drivers/media/i2c/soc_camera/ar0231.c
++++ b/drivers/media/i2c/soc_camera/ar0231.c
+@@ -20,9 +20,9 @@
+ #include <media/v4l2-common.h>
+ #include <media/v4l2-ctrls.h>
+
+-#include "ar0231.h"
++#include "ar0231_rev7.h"
+
+-#define AR0231_I2C_ADDR 0x10
++static const int ar0231_i2c_addr[] = {0x10, 0x20};
+
+ #define AR0231_PID 0x3000
+ #define AR0231_VERSION_REG 0x0354
+@@ -39,6 +39,8 @@ struct ar0231_priv {
+ /* serializers */
+ int max9286_addr;
+ int max9271_addr;
++ int ti9x4_addr;
++ int ti9x3_addr;
+ int port;
+ int gpio_resetb;
+ int gpio_fsin;
+@@ -85,6 +87,25 @@ static int ar0231_s_stream(struct v4l2_subdev *sd, int enable)
+ return 0;
+ }
+
++static int ar0231_set_window(struct v4l2_subdev *sd)
++{
++ struct i2c_client *client = v4l2_get_subdevdata(sd);
++ struct ar0231_priv *priv = to_ar0231(client);
++
++ dev_err(&client->dev, "L=%d T=%d %dx%d\n", priv->rect.left, priv->rect.top, priv->rect.width, priv->rect.height);
++
++ /* horiz crop start */
++ reg16_write16(client, 0x3004, priv->rect.left);
++ /* horiz crop end */
++ reg16_write16(client, 0x3008, priv->rect.left + priv->rect.width - 1);
++ /* vert crop start */
++ reg16_write16(client, 0x3002, priv->rect.top);
++ /* vert crop end */
++ reg16_write16(client, 0x3006, priv->rect.top + priv->rect.height + 1);
++
++ return 0;
++};
++
+ static int ar0231_get_fmt(struct v4l2_subdev *sd,
+ struct v4l2_subdev_pad_config *cfg,
+ struct v4l2_subdev_format *format)
+@@ -174,6 +195,8 @@ static int ar0231_set_selection(struct v4l2_subdev *sd,
+ priv->rect.width = rect->width;
+ priv->rect.height = rect->height;
+
++ ar0231_set_window(sd);
++
+ return 0;
+ }
+
+@@ -372,9 +395,29 @@ static int ar0231_initialize(struct i2c_client *client)
+ u16 val = 0;
+ u16 pid = 0;
+ int ret = 0;
++ int tmp_addr;
++ int i;
++
++ for (i = 0; i < ARRAY_SIZE(ar0231_i2c_addr); i++) {
++ tmp_addr = client->addr;
++ if (priv->ti9x4_addr) {
++ client->addr = priv->ti9x4_addr; /* Deserializer I2C address */
++ reg8_write(client, 0x5d, ar0231_i2c_addr[i] << 1); /* Sensor native I2C address */
++ usleep_range(2000, 2500); /* wait 2ms */
++ }
++ if (priv->max9286_addr) {
++ client->addr = priv->max9271_addr; /* Serializer I2C address */
++ reg8_write(client, 0x0a, ar0231_i2c_addr[i] << 1); /* Sensor native I2C address */
++ usleep_range(2000, 2500); /* wait 2ms */
++ };
++ client->addr = tmp_addr;
+
+- /* check and show model ID */
+- reg16_read16(client, AR0231_PID, &pid);
++ /* check model ID */
++ reg16_read16(client, AR0231_PID, &pid);
++
++ if (pid == AR0231_VERSION_REG)
++ break;
++ }
+
+ if (pid != AR0231_VERSION_REG) {
+ dev_dbg(&client->dev, "Product ID error %x\n", pid);
+@@ -382,16 +425,15 @@ static int ar0231_initialize(struct i2c_client *client)
+ goto err;
+ }
+
++ /* Read OTP IDs */
++ ar0231_otp_id_read(client);
+ /* Program wizard registers */
+- ar0231_set_regs(client, ar0231_regs_wizard_rev4, ARRAY_SIZE(ar0231_regs_wizard_rev4));
++ ar0231_set_regs(client, ar0231_regs_wizard_rev7, ARRAY_SIZE(ar0231_regs_wizard_rev7));
+
+ /* Enable stream */
+- reg16_read16(client, 0x301a, &val); // read inital reset_register value
+- val |= (1 << 2); // Set streamOn bit
+- reg16_write16(client, 0x301a, val); // Start Streaming
+-
+- /* Read OTP IDs */
+- ar0231_otp_id_read(client);
++ reg16_read16(client, 0x301a, &val);
++ val |= (1 << 2);
++ reg16_write16(client, 0x301a, val);
+
+ dev_info(&client->dev, "ar0231 PID %x, res %dx%d, OTP_ID %02x:%02x:%02x:%02x:%02x:%02x\n",
+ pid, AR0231_MAX_WIDTH, AR0231_MAX_HEIGHT, priv->id[0], priv->id[1], priv->id[2], priv->id[3], priv->id[4], priv->id[5]);
+@@ -419,13 +461,19 @@ static int ar0231_parse_dt(struct device_node *np, struct ar0231_priv *priv)
+ if (!of_property_read_u32(rendpoint, "max9271-addr", &priv->max9271_addr) &&
+ !of_property_read_u32(rendpoint->parent->parent, "reg", &priv->max9286_addr) &&
+ !kstrtouint(strrchr(rendpoint->full_name, '@') + 1, 0, &priv->port))
+- break;
++ break;
++
++ if (!of_property_read_u32(rendpoint, "ti9x3-addr", &priv->ti9x3_addr) &&
++ !of_property_match_string(rendpoint->parent->parent, "compatible", "ti,ti9x4") &&
++ !of_property_read_u32(rendpoint->parent->parent, "reg", &priv->ti9x4_addr) &&
++ !kstrtouint(strrchr(rendpoint->full_name, '@') + 1, 0, &priv->port))
++ break;
+ }
+
+ of_node_put(endpoint);
+
+- if (!priv->max9286_addr) {
+- dev_err(&client->dev, "deserializer does not present\n");
++ if (!priv->ti9x4_addr && !priv->max9286_addr) {
++ dev_dbg(&client->dev, "deserializer does not present\n");
+ return -EINVAL;
+ }
+
+@@ -437,12 +485,16 @@ static int ar0231_parse_dt(struct device_node *np, struct ar0231_priv *priv)
+ client->addr = priv->max9271_addr; /* Serializer I2C address */
+
+ reg8_write(client, 0x09, tmp_addr << 1); /* Sensor translated I2C address */
+- reg8_write(client, 0x0A, AR0231_I2C_ADDR << 1); /* Sensor native I2C address */
+ usleep_range(2000, 2500); /* wait 2ms */
+ };
+- client->addr = tmp_addr;
++ if (priv->ti9x4_addr) {
++ client->addr = priv->ti9x4_addr; /* Deserializer I2C address */
+
+- mdelay(10);
++ reg8_write(client, 0x4c, (priv->port << 4) | (1 << priv->port)); /* Select RX port number */
++ usleep_range(2000, 2500); /* wait 2ms */
++ reg8_write(client, 0x65, tmp_addr << 1); /* Sensor translated I2C address */
++ }
++ client->addr = tmp_addr;
+
+ return 0;
+ }
+diff --git a/drivers/media/i2c/soc_camera/ar0231_rev7.h b/drivers/media/i2c/soc_camera/ar0231_rev7.h
+new file mode 100644
+index 0000000..c05c3ea
+--- /dev/null
++++ b/drivers/media/i2c/soc_camera/ar0231_rev7.h
+@@ -0,0 +1,418 @@
++/*
++ * ON Semiconductor AR0231 sensor camera wizard 1928x1208@30/BGGR/MIPI
++ *
++ * Copyright (C) 2018 Cogent Embedded, Inc.
++ *
++ * This program is free software; you can redistribute it and/or modify it
++ * under the terms of the GNU General Public License as published by the
++ * Free Software Foundation; either version 2 of the License, or (at your
++ * option) any later version.
++ */
++
++//#define AR0231_DISPLAY_PATTERN_FIXED
++//#define AR0231_DISPLAY_PATTERN_COLOR_BAR
++
++#define AR0231_MAX_WIDTH 1920
++#define AR0231_MAX_HEIGHT 1200
++
++#define AR0231_DELAY 0xffff
++
++#define AR0231_SENSOR_WIDTH 1928
++#define AR0231_SENSOR_HEIGHT 1208
++
++#define AR0231_X_START ((AR0231_SENSOR_WIDTH - AR0231_MAX_WIDTH) / 2)
++#define AR0231_Y_START ((AR0231_SENSOR_HEIGHT - AR0231_MAX_HEIGHT) / 2)
++#define AR0231_X_END (AR0231_X_START + AR0231_MAX_WIDTH - 1)
++#define AR0231_Y_END (AR0231_Y_START + AR0231_MAX_HEIGHT - 1)
++
++struct ar0231_reg {
++ u16 reg;
++ u16 val;
++};
++
++/* 3Exp HDR Full Resolution Mode MIPI 4lane 12bit 30FPS, XCLK=27MHz */
++static const struct ar0231_reg ar0231_regs_wizard_rev7[] = {
++{0x301A, 0x18}, // MIPI, stream OFF
++{AR0231_DELAY, 200}, // Wait 200ms
++
++{0x3070, 0x0000}, // 1: Solid color test pattern,
++ // 2: Full color bar test pattern,
++ // 3: Fade to grey color bar test pattern,
++ //256: Walking 1 test pattern (12 bit)
++{0x3072, 0x0123}, // R
++{0x3074, 0x0456}, // G(GR row)
++{0x3076, 0x0abc}, // B
++{0x3078, 0x0def}, // G(GB row)
++#ifdef AR0231_DISPLAY_PATTERN_FIXED
++{0x3070, 0x0001},
++#endif
++#ifdef AR0231_DISPLAY_PATTERN_COLOR_BAR
++{0x3070, 0x0002},
++#endif
++{AR0231_DELAY, 100}, // Wait 100ms
++
++#if 1 /* Sensor Setup */
++#if 1 /* Recommended Settings */
++{0x3092, 0x0C24},
++{0x337A, 0x0C80},
++{0x3520, 0x1288},
++{0x3522, 0x880C},
++{0x3524, 0x0C12},
++{0x352C, 0x1212},
++{0x354A, 0x007F},
++{0x350C, 0x055C},
++{0x3506, 0x3333},
++{0x3508, 0x3333},
++{0x3100, 0x4000},
++{0x3280, 0x0FA0},
++{0x3282, 0x0FA0},
++{0x3284, 0x0FA0},
++{0x3286, 0x0FA0},
++{0x3288, 0x0FA0},
++{0x328A, 0x0FA0},
++{0x328C, 0x0FA0},
++{0x328E, 0x0FA0},
++{0x3290, 0x0FA0},
++{0x3292, 0x0FA0},
++{0x3294, 0x0FA0},
++{0x3296, 0x0FA0},
++{0x3298, 0x0FA0},
++{0x329A, 0x0FA0},
++{0x329C, 0x0FA0},
++{0x329E, 0x0FA0},
++#endif /* Recommended Settings */
++
++#if 1 /* Sequencer Update */
++{0x2512, 0x8000},
++{0x2510, 0x0905},
++{0x2510, 0x3350},
++{0x2510, 0x2004},
++{0x2510, 0x1460},
++{0x2510, 0x1578},
++{0x2510, 0x0901},
++{0x2510, 0x7B24},
++{0x2510, 0xFF24},
++{0x2510, 0xFF24},
++{0x2510, 0xEA24},
++{0x2510, 0x1022},
++{0x2510, 0x2410},
++{0x2510, 0x155A},
++{0x2510, 0x0901},
++{0x2510, 0x1400},
++{0x2510, 0x24FF},
++{0x2510, 0x24FF},
++{0x2510, 0x24EA},
++{0x2510, 0x2324},
++{0x2510, 0x647A},
++{0x2510, 0x2404},
++{0x2510, 0x052C},
++{0x2510, 0x400A},
++{0x2510, 0xFF0A},
++{0x2510, 0xFF0A},
++{0x2510, 0x1008},
++{0x2510, 0x3851},
++{0x2510, 0x1440},
++{0x2510, 0x0004},
++{0x2510, 0x0801},
++{0x2510, 0x0408},
++{0x2510, 0x1180},
++{0x2510, 0x2652},
++{0x2510, 0x1518},
++{0x2510, 0x0906},
++{0x2510, 0x1348},
++{0x2510, 0x1002},
++{0x2510, 0x1016},
++{0x2510, 0x1181},
++{0x2510, 0x1189},
++{0x2510, 0x1056},
++{0x2510, 0x1210},
++{0x2510, 0x0901},
++{0x2510, 0x0D09},
++{0x2510, 0x1413},
++{0x2510, 0x8809},
++{0x2510, 0x2B15},
++{0x2510, 0x8809},
++{0x2510, 0x0311},
++{0x2510, 0xD909},
++{0x2510, 0x1214},
++{0x2510, 0x4109},
++{0x2510, 0x0312},
++{0x2510, 0x1409},
++{0x2510, 0x0110},
++{0x2510, 0xD612},
++{0x2510, 0x1012},
++{0x2510, 0x1212},
++{0x2510, 0x1011},
++{0x2510, 0xDD11},
++{0x2510, 0xD910},
++{0x2510, 0x5609},
++{0x2510, 0x1511},
++{0x2510, 0xDB09},
++{0x2510, 0x1511},
++{0x2510, 0x9B09},
++{0x2510, 0x0F11},
++{0x2510, 0xBB12},
++{0x2510, 0x1A12},
++{0x2510, 0x1014},
++{0x2510, 0x6012},
++{0x2510, 0x5010},
++{0x2510, 0x7610},
++{0x2510, 0xE609},
++{0x2510, 0x0812},
++{0x2510, 0x4012},
++{0x2510, 0x6009},
++{0x2510, 0x290B},
++{0x2510, 0x0904},
++{0x2510, 0x1440},
++{0x2510, 0x0923},
++{0x2510, 0x15C8},
++{0x2510, 0x13C8},
++{0x2510, 0x092C},
++{0x2510, 0x1588},
++{0x2510, 0x1388},
++{0x2510, 0x0C09},
++{0x2510, 0x0C14},
++{0x2510, 0x4109},
++{0x2510, 0x1112},
++{0x2510, 0x6212},
++{0x2510, 0x6011},
++{0x2510, 0xBF11},
++{0x2510, 0xBB10},
++{0x2510, 0x6611},
++{0x2510, 0xFB09},
++{0x2510, 0x3511},
++{0x2510, 0xBB12},
++{0x2510, 0x6312},
++{0x2510, 0x6014},
++{0x2510, 0x0015},
++{0x2510, 0x0011},
++{0x2510, 0xB812},
++{0x2510, 0xA012},
++{0x2510, 0x0010},
++{0x2510, 0x2610},
++{0x2510, 0x0013},
++{0x2510, 0x0011},
++{0x2510, 0x0008},
++{0x2510, 0x3053},
++{0x2510, 0x4215},
++{0x2510, 0x4013},
++{0x2510, 0x4010},
++{0x2510, 0x0210},
++{0x2510, 0x1611},
++{0x2510, 0x8111},
++{0x2510, 0x8910},
++{0x2510, 0x5612},
++{0x2510, 0x1009},
++{0x2510, 0x010D},
++{0x2510, 0x0815},
++{0x2510, 0xC015},
++{0x2510, 0xD013},
++{0x2510, 0x5009},
++{0x2510, 0x1313},
++{0x2510, 0xD009},
++{0x2510, 0x0215},
++{0x2510, 0xC015},
++{0x2510, 0xC813},
++{0x2510, 0xC009},
++{0x2510, 0x0515},
++{0x2510, 0x8813},
++{0x2510, 0x8009},
++{0x2510, 0x0213},
++{0x2510, 0x8809},
++{0x2510, 0x0411},
++{0x2510, 0xC909},
++{0x2510, 0x0814},
++{0x2510, 0x0109},
++{0x2510, 0x0B11},
++{0x2510, 0xD908},
++{0x2510, 0x1400},
++{0x2510, 0x091A},
++{0x2510, 0x1440},
++{0x2510, 0x0903},
++{0x2510, 0x1214},
++{0x2510, 0x0901},
++{0x2510, 0x10D6},
++{0x2510, 0x1210},
++{0x2510, 0x1212},
++{0x2510, 0x1210},
++{0x2510, 0x11DD},
++{0x2510, 0x11D9},
++{0x2510, 0x1056},
++{0x2510, 0x0917},
++{0x2510, 0x11DB},
++{0x2510, 0x0913},
++{0x2510, 0x11FB},
++{0x2510, 0x0905},
++{0x2510, 0x11BB},
++{0x2510, 0x121A},
++{0x2510, 0x1210},
++{0x2510, 0x1460},
++{0x2510, 0x1250},
++{0x2510, 0x1076},
++{0x2510, 0x10E6},
++{0x2510, 0x0901},
++{0x2510, 0x15A8},
++{0x2510, 0x0901},
++{0x2510, 0x13A8},
++{0x2510, 0x1240},
++{0x2510, 0x1260},
++{0x2510, 0x0925},
++{0x2510, 0x13AD},
++{0x2510, 0x0902},
++{0x2510, 0x0907},
++{0x2510, 0x1588},
++{0x2510, 0x0901},
++{0x2510, 0x138D},
++{0x2510, 0x0B09},
++{0x2510, 0x0914},
++{0x2510, 0x4009},
++{0x2510, 0x0B13},
++{0x2510, 0x8809},
++{0x2510, 0x1C0C},
++{0x2510, 0x0920},
++{0x2510, 0x1262},
++{0x2510, 0x1260},
++{0x2510, 0x11BF},
++{0x2510, 0x11BB},
++{0x2510, 0x1066},
++{0x2510, 0x090A},
++{0x2510, 0x11FB},
++{0x2510, 0x093B},
++{0x2510, 0x11BB},
++{0x2510, 0x1263},
++{0x2510, 0x1260},
++{0x2510, 0x1400},
++{0x2510, 0x1508},
++{0x2510, 0x11B8},
++{0x2510, 0x12A0},
++{0x2510, 0x1200},
++{0x2510, 0x1026},
++{0x2510, 0x1000},
++{0x2510, 0x1300},
++{0x2510, 0x1100},
++{0x2510, 0x437A},
++{0x2510, 0x0609},
++{0x2510, 0x0B05},
++{0x2510, 0x0708},
++{0x2510, 0x4137},
++{0x2510, 0x502C},
++{0x2510, 0x2CFE},
++{0x2510, 0x15FE},
++{0x2510, 0x0C2C},
++
++{0x32e6, 0xe0},
++{0x1008, 0x36f},
++{0x100c, 0x58f},
++{0x100e, 0x7af},
++{0x1010, 0x14f},
++
++{0x3230, 0x312},
++{0x3232, 0x532},
++{0x3234, 0x752},
++{0x3236, 0xf2},
++#endif /* Sequencer Update */
++
++//{0x3566, 0x3328}, // clear bit6
++{0x32D0, 0x3A02},
++{0x32D2, 0x3508},
++{0x32D4, 0x3702},
++{0x32D6, 0x3C04},
++{0x32DC, 0x370A},
++{0x30B0, 0x800}, // clear bit9
++#endif /* Sensor Setup */
++
++#if 1 /* Serial 12-bit Timing Setup */
++{0x302A, 6}, // vt_pix_clk_div
++{0x302C, 1}, // vt_sys_clk_div
++{0x302E, 2}, // pre_pll_clk_div
++{0x3030, 44}, // pll_multiplier
++{0x3036, 12}, // op_word_clk_div
++{0x3038, 1}, // op_sys_clk_div
++{0x30B0, 0x800}, // digital_test: pll_complete_bypass=0
++#endif /* Serial 12-bit Timing Setup */
++
++#if 1 /* Readout Mode Configuration */
++{0x30A2, 1}, // x_odd_inc_
++{0x30A6, 1}, // y_odd_inc_
++{0x3040, 0}, // read_mode
++//{0x3082, 0x8}, // operation_mode_ctrl
++//{0x30BA, 0x11E2}, // digital_ctrl
++{0x3044, 0x400}, // dark_control
++#ifdef AR0231_EMBEDDED_LINE
++{0x3064, 0x1982}, // SMIA_TEST
++#else
++{0x3064, 0x1802}, // SMIA_TEST
++#endif
++//{0x33E0, 0xC80},
++//{0x3180, 0x80},
++//{0x33E4, 0x80},
++#endif /* Readout Mode Configuration */
++
++#if 1 /* Full Res FOV */
++{0x3004, AR0231_X_START}, // X_ADDR_START_
++{0x3008, AR0231_X_END}, // X_ADDR_END_
++{0x3002, AR0231_Y_START}, // Y_ADDR_START_
++{0x3006, AR0231_Y_END}, // Y_ADDR_END_
++{0x3032, 0x0}, // scaling_mode
++{0x3400, 0x10},
++{0x3402, 0x0000 | AR0231_MAX_WIDTH}, // X_OUTPUT_CONTROL
++{0x3404, 0x0000 | AR0231_MAX_HEIGHT}, // Y_OUTPUT_CONTROL
++#endif /* Full Res FOV */
++
++#if 1 /* 3exp Timing and Exposure */
++{0x3082, 0x8}, // operation_mode_ctrl
++{0x30BA, 0x11E2}, // digital_ctrl: num_exp_max=2
++
++/* Row and Pixel Timing */
++{0x300C, 1674}, // line_length_pck_
++{0x300A, 1314}, // frame_length_lines_
++{0x3042, 0}, // extra_delay
++
++/* Exposure Settings */
++//{0x3238, 0x222}, // exposure_ratio
++{0x3012, 355}, // coarse_integration_time_
++{0x3014, 1874}, // fine_integration_time_
++{0x321E, 1874}, // fine_integration_time2
++{0x3222, 1874}, // fine_integration_time3
++{0x30B0, 0x800}, // digital_test: set bit11
++{0x32EA, 0x3C0E},
++{0x32EC, 0x72A1},
++#endif /* 3exp Timing and Exposure - Serial */
++
++#if 1 /* HDR 12 bit Output */
++{0x31D0, 1}, // companding
++{0x31AC, 0x140C}, // data_format_bits: RAW20, OUT12
++#endif /* HDR 12 bit Output */
++
++#if 1 /* MIPI 12 bit Settings */
++{0x31AE, 0x204}, // serial_format: MIPI 4 lanes
++//{0x3342, 0x122C}, // default, DT=0x12, DT=0x2C
++//{0x3346, 0x122C}, // default, DT=0x12, DT=0x2C
++//{0x334A, 0x122C}, // default, DT=0x12, DT=0x2C
++//{0x334E, 0x122C}, // default, DT=0x12, DT=0x2C
++//{0x3344, 0x0011}, // default, VC=0
++//{0x3348, 0x0111}, // default, VC=1
++//{0x334C, 0x0211}, // default, VC=2
++//{0x3350, 0x0311}, // default, VC=3
++//{0x31B0, 0x49}, // frame_preamble
++//{0x31B2, 0x33}, // line_preamble
++{0x31B4, 0x2185},
++{0x31B6, 0x1146},
++{0x31B8, 0x3047},
++{0x31BA, 0x186},
++{0x31BC, 0x805},
++#endif /* MIPI 12 bit Settings */
++
++/* FPS = 124.5MHz / reg0x300A / reg0x300C * (DES_XTAL/27MHz), DES_XTAL=23.5MHz */
++{0x300A, AR0231_SENSOR_HEIGHT + 100}, // Frame_length_Lines
++{0x300C, AR0231_SENSOR_WIDTH + 550}, // Line_length_pck
++{0x3012, 0x144}, //Integration_time
++
++#if 1 /* Enable trigger input */
++{0x340A, 0x00E0}, // GPIO_CONTROL1: GPIO1 is trigger
++{0x340C, 0x0002}, // GPIO_CONTROL2: GPIO1 is trigger
++{0x30CE, 0x0120}, // TRIGGER_MODE
++//{0x30DC, 0x0120}, // TRIGGER_DELAY
++{0x301A, 0x0118}, // GPI pins enable
++#endif
++};
+diff --git a/drivers/media/i2c/soc_camera/ov106xx.c b/drivers/media/i2c/soc_camera/ov106xx.c
+index e5d6b67..aaadcc2 100644
+--- a/drivers/media/i2c/soc_camera/ov106xx.c
++++ b/drivers/media/i2c/soc_camera/ov106xx.c
+@@ -51,6 +51,12 @@ static int ov106xx_probe(struct i2c_client *client,
+ int ret;
+ chip_id = -EINVAL;
+
++ ret = ar0231_probe(client, did);
++ if (!ret) {
++ chip_id = ID_AR0231;
++ goto out;
++ }
++
+ ret = ar0233_probe(client, did);
+ if (!ret) {
+ chip_id = ID_AR0233;
+@@ -105,12 +111,6 @@ static int ov106xx_probe(struct i2c_client *client,
+ goto out;
+ }
+
+- ret = ar0231_probe(client, did);
+- if (!ret) {
+- chip_id = ID_AR0231;
+- goto out;
+- }
+-
+ ret = ap0101_probe(client, did);
+ if (!ret) {
+ chip_id = ID_AP0101_AR014X;
+--
+2.7.4
+
diff --git a/bsp/meta-rcar/meta-rcar-gen3-adas/recipes-kernel/linux/linux-renesas/0139-lvds-AR0233-modify-with-rev2-silicon.patch b/bsp/meta-rcar/meta-rcar-gen3-adas/recipes-kernel/linux/linux-renesas/0139-lvds-AR0233-modify-with-rev2-silicon.patch
new file mode 100644
index 00000000..db5bffeb
--- /dev/null
+++ b/bsp/meta-rcar/meta-rcar-gen3-adas/recipes-kernel/linux/linux-renesas/0139-lvds-AR0233-modify-with-rev2-silicon.patch
@@ -0,0 +1,1349 @@
+From 23114c0a5904abe79b69129335dccf0c4aee0118 Mon Sep 17 00:00:00 2001
+From: Vladimir Barinov <vladimir.barinov@cogentembedded.com>
+Date: Thu, 3 Jan 2019 23:43:46 +0300
+Subject: [PATCH 088/122] lvds: AR0233 modify with rev2 silicon
+
+Use rev2 setup for AR0233.
+Remove code moved to ti9x4 driver
+
+Signed-off-by: Vladimir Barinov <vladimir.barinov@cogentembedded.com>
+---
+ drivers/media/i2c/soc_camera/ar0233.c | 19 +-
+ drivers/media/i2c/soc_camera/ar0233_rev2.h | 1281 ++++++++++++++++++++++++++++
+ 2 files changed, 1284 insertions(+), 16 deletions(-)
+ create mode 100644 drivers/media/i2c/soc_camera/ar0233_rev2.h
+
+diff --git a/drivers/media/i2c/soc_camera/ar0233.c b/drivers/media/i2c/soc_camera/ar0233.c
+index 74ecc85..2a0b7aa 100644
+--- a/drivers/media/i2c/soc_camera/ar0233.c
++++ b/drivers/media/i2c/soc_camera/ar0233.c
+@@ -20,12 +20,12 @@
+ #include <media/v4l2-common.h>
+ #include <media/v4l2-ctrls.h>
+
+-#include "ar0233.h"
++#include "ar0233_rev2.h"
+
+ static const int ar0233_i2c_addr[] = {0x10, 0x20};
+
+ #define AR0233_PID 0x3000
+-#define AR0233_VERSION_REG 0x0354
++#define AR0233_VERSION_REG 0x0956
+
+ #define AR0233_MEDIA_BUS_FMT MEDIA_BUS_FMT_SGRBG12_1X12
+
+@@ -404,23 +404,10 @@ static int ar0233_initialize(struct i2c_client *client)
+ goto err;
+ }
+
+- /* setup XCLK */
+- tmp_addr = client->addr;
+- if (priv->ti9x4_addr) {
+- /* CLK_OUT=22.5792*160*M/N/CLKDIV -> CLK_OUT=27MHz: CLKDIV=2, M=15, N=251: 22.5792*160/8*15/251=26.987MHz=CLK_OUT */
+- client->addr = priv->ti9x3_addr; /* Serializer I2C address */
+-#if 0
+- reg8_write(client, 0x06, 0x6f); /* Set CLKDIV and M */
+- reg8_write(client, 0x07, 0xfb); /* Set N */
+-#endif
+- reg8_write(client, 0x0e, 0xf0); /* Enable all remote gpios */
+- }
+- client->addr = tmp_addr;
+-
+ /* Read OTP IDs */
+ ar0233_otp_id_read(client);
+ /* Program wizard registers */
+- ar0233_set_regs(client, ar0233_regs_wizard, ARRAY_SIZE(ar0233_regs_wizard));
++ ar0233_set_regs(client, ar0233_regs_wizard_rev2, ARRAY_SIZE(ar0233_regs_wizard_rev2));
+
+ /* Enable stream */
+ reg16_read16(client, 0x301a, &val); // read inital reset_register value
+diff --git a/drivers/media/i2c/soc_camera/ar0233_rev2.h b/drivers/media/i2c/soc_camera/ar0233_rev2.h
+new file mode 100644
+index 0000000..fbc2649
+--- /dev/null
++++ b/drivers/media/i2c/soc_camera/ar0233_rev2.h
+@@ -0,0 +1,1281 @@
++/*
++ * ON Semiconductor AR0233 sensor camera wizard 2048x1280@30/BGGR/MIPI
++ *
++ * Copyright (C) 2018 Cogent Embedded, Inc.
++ *
++ * This program is free software; you can redistribute it and/or modify it
++ * under the terms of the GNU General Public License as published by the
++ * Free Software Foundation; either version 2 of the License, or (at your
++ * option) any later version.
++ */
++
++//#define AR0233_DISPLAY_PATTERN_FIXED
++//#define AR0233_DISPLAY_PATTERN_COLOR_BAR
++
++#define AR0233_MAX_WIDTH 2048
++#define AR0233_MAX_HEIGHT 1280
++
++#define AR0233_DELAY 0xffff
++
++#define AR0233_SENSOR_WIDTH 2058
++#define AR0233_SENSOR_HEIGHT 1284
++
++#define AR0233_X_START ((AR0233_SENSOR_WIDTH - AR0233_MAX_WIDTH) / 2)
++#define AR0233_Y_START ((AR0233_SENSOR_HEIGHT - AR0233_MAX_HEIGHT) / 2)
++#define AR0233_X_END (AR0233_X_START + AR0233_MAX_WIDTH - 1)
++#define AR0233_Y_END (AR0233_Y_START + AR0233_MAX_HEIGHT - 1)
++
++struct ar0233_reg {
++ u16 reg;
++ u16 val;
++};
++
++#define O1_Recommended_Defaults_LFM_HDR
++#ifdef O1_Recommended_Defaults_LFM_HDR
++ #define Design_recommended_settings_REV2_V9
++ #define Sequence_hidy_ar0233_REV2_V13
++ #define Pre_hdr_gain_enable
++ #define Tempsensor_init
++#endif
++#define disable_embed_data_stat
++#define HDR_3exp_12bit
++#if 0
++ #define pll_27_108_4lane_12b
++ #define mipi_108_12bit_4lane
++#else
++ #define pll_27_124p5_4lane_12b
++ #define mipi_124p5_12bit_4lane
++#endif
++#define MIPI_DT_bit12
++#define LUT_24_to_12
++#define HDR_ratio_gain_default
++#define Enable_trigger_input
++
++/* 3Exp HDR 1280P Mipi_12bit_4lane_30fps, XCLK=27MHz */
++static const struct ar0233_reg ar0233_regs_wizard_rev2[] = {
++{0x301A, 0x18}, // MIPI, stream OFF
++{AR0233_DELAY, 200}, // Wait 200ms
++
++{0x3070, 0x0000}, // 1: Solid color test pattern,
++ // 2: Full color bar test pattern,
++ // 3: Fade to grey color bar test pattern,
++ //256: Walking 1 test pattern (12 bit)
++{0x3072, 0x0123}, // R
++{0x3074, 0x0456}, // G(GR row)
++{0x3076, 0x0abc}, // B
++{0x3078, 0x0def}, // G(GB row)
++#ifdef AR0233_DISPLAY_PATTERN_FIXED
++{0x3070, 0x0001},
++#endif
++#ifdef AR0233_DISPLAY_PATTERN_COLOR_BAR
++{0x3070, 0x0002},
++#endif
++{AR0233_DELAY, 100}, // Wait 100ms
++
++#ifdef O1_Recommended_Defaults_LFM_HDR
++#ifdef Design_recommended_settings_REV2_V9
++{0x3C72, 0x0076},
++{0x3C74, 0x0031},
++{0x3C76, 0x00DC},
++{0x3C78, 0x01AA},
++{0x3C7A, 0x0352},
++{0x3C7C, 0x06AA},
++{0x3520, 0x0084},
++{0x3522, 0x7D19},
++{0x356A, 0x81AA},
++{0x3568, 0x0028},
++{0x351A, 0xF400},
++{0x3092, 0x000C},
++{0x37B2, 0x1FFF},
++{0x3562, 0x0C08},
++{0x3496, 0xDF80},
++{0x3492, 0x1001},
++{0x34BC, 0x1010},
++{0x3494, 0x1010},
++{0x3520, 0x0080},
++{0x3512, 0x0EDC},
++{0x3530, 0x5F18},
++{0x353C, 0x9A8A},
++{0x3576, 0x1DFF},
++{0x3544, 0x030F},
++{0x3534, 0x3898},
++{0x353A, 0x9A9A},
++{0x356E, 0x048A},
++{0x356C, 0x6A28},
++{0x3564, 0x1223},
++{0x3508, 0xAF1A},
++{0x3086, 0x0000},
++{0x34BA, 0x0001},
++{0x34B8, 0x0001},
++{0x3550, 0x806C},
++{0x3522, 0x0519},
++{0x34A0, 0x0036},
++{0x34A4, 0x0035},
++{0x34A6, 0x0040},
++{0x342E, 0x0017},
++{0x3E3E, 0x000C},
++{0x3092, 0x408C},
++{0x3530, 0x1F18},
++{0x351C, 0xC0F2},
++{0x3528, 0xE008},
++{0x352A, 0x0827},
++{0x352C, 0xA800},
++{0x352E, 0x0908},
++#endif /* Design_recommended_settings_REV2_V9 */
++
++#ifdef Sequence_hidy_ar0233_REV2_V13
++{0x2512, 0x8000},
++{0x2510, 0x070f},
++{0x2510, 0x1011},
++{0x2510, 0x1215},
++{0x2510, 0xffff},
++{0x2510, 0xffff},
++{0x2510, 0xffff},
++{0x2510, 0xffff},
++{0x2510, 0xffff},
++{0x2510, 0x1819},
++{0x2510, 0x1d1e},
++{0x2510, 0x2021},
++{0x2510, 0xffff},
++{0x2510, 0x2240},
++{0x2510, 0x5172},
++{0x2510, 0x8586},
++{0x2510, 0x8788},
++{0x2510, 0x898b},
++{0x2510, 0x959a},
++{0x2510, 0x9b9e},
++{0x2510, 0xa2a6},
++{0x2510, 0xaaac},
++{0x2510, 0xaeb0},
++{0x2510, 0xb3b5},
++{0x2510, 0xcfd1},
++{0x2510, 0xd9dd},
++{0x2510, 0xe0e3},
++{0x2510, 0xffff},
++{0x2510, 0xffff},
++{0x2510, 0xc003},
++{0x2510, 0x805a},
++{0x2510, 0xa0e0},
++{0x2510, 0x3041},
++{0x2510, 0x3042},
++{0x2510, 0x2000},
++{0x2510, 0x3048},
++{0x2510, 0x3088},
++{0x2510, 0x30a0},
++{0x2510, 0x3090},
++{0x2510, 0x32c2},
++{0x2510, 0xa0c0},
++{0x2510, 0x9008},
++{0x2510, 0x8802},
++{0x2510, 0x20ff},
++{0x2510, 0x20ff},
++{0x2510, 0x20ff},
++{0x2510, 0x20ff},
++{0x2510, 0x20ff},
++{0x2510, 0x9018},
++{0x2510, 0x891a},
++{0x2510, 0x807e},
++{0x2510, 0x20ff},
++{0x2510, 0x895b},
++{0x2510, 0x20ff},
++{0x2510, 0x897b},
++{0x2510, 0x20ff},
++{0x2510, 0x897f},
++{0x2510, 0x20ff},
++{0x2510, 0x7fff},
++{0x2510, 0x7fff},
++{0x2510, 0x7fff},
++{0x2510, 0x20ff},
++{0x2510, 0x7fff},
++{0x2510, 0x7fff},
++{0x2510, 0x7fff},
++{0x2510, 0x20ff},
++{0x2510, 0x7fff},
++{0x2510, 0x7fff},
++{0x2510, 0x7fff},
++{0x2510, 0x20ff},
++{0x2510, 0x7fff},
++{0x2510, 0x7fff},
++{0x2510, 0x7fff},
++{0x2510, 0xa0c4},
++{0x2510, 0x20ff},
++{0x2510, 0x805a},
++{0x2510, 0x9039},
++{0x2510, 0x20ff},
++{0x2510, 0x907f},
++{0x2510, 0x895b},
++{0x2510, 0x2064},
++{0x2510, 0x891b},
++{0x2510, 0x2010},
++{0x2510, 0x8803},
++{0x2510, 0x7fff},
++{0x2510, 0x20ff},
++{0x2510, 0x906b},
++{0x2510, 0x2064},
++{0x2510, 0x3084},
++{0x2510, 0x2003},
++{0x2510, 0x3044},
++{0x2510, 0x2000},
++{0x2510, 0xa004},
++{0x2510, 0x7fff},
++{0x2510, 0x7fff},
++{0x2510, 0x7fff},
++{0x2510, 0x7fff},
++{0x2510, 0x2400},
++{0x2510, 0x2401},
++{0x2510, 0x7fff},
++{0x2510, 0x7fff},
++{0x2510, 0x2400},
++{0x2510, 0x2401},
++{0x2510, 0x2702},
++{0x2510, 0x3242},
++{0x2510, 0x2420},
++{0x2510, 0x2421},
++{0x2510, 0x2703},
++{0x2510, 0x3242},
++{0x2510, 0x2420},
++{0x2510, 0x2421},
++{0x2510, 0x2704},
++{0x2510, 0x3242},
++{0x2510, 0x2420},
++{0x2510, 0x2421},
++{0x2510, 0x7fff},
++{0x2510, 0x7fff},
++{0x2510, 0x2402},
++{0x2510, 0x2403},
++{0x2510, 0x7fff},
++{0x2510, 0x7fff},
++{0x2510, 0x2741},
++{0x2510, 0x2429},
++{0x2510, 0x2740},
++{0x2510, 0x242a},
++{0x2510, 0x7fff},
++{0x2510, 0x7fff},
++{0x2510, 0x7fff},
++{0x2510, 0x7fff},
++{0x2510, 0x2201},
++{0x2510, 0x7fff},
++{0x2510, 0x7fff},
++{0x2510, 0x7fff},
++{0x2510, 0x2201},
++{0x2510, 0x7fff},
++{0x2510, 0x7fff},
++{0x2510, 0x7fff},
++{0x2510, 0xb800},
++{0x2510, 0x8058},
++{0x2510, 0xa005},
++{0x2510, 0x3101},
++{0x2510, 0x3041},
++{0x2510, 0x3104},
++{0x2510, 0xb035},
++{0x2510, 0xb075},
++{0x2510, 0x30c1},
++{0x2510, 0x3102},
++{0x2510, 0x3041},
++{0x2510, 0xb808},
++{0x2510, 0x3202},
++{0x2510, 0xb848},
++{0x2510, 0xb84c},
++{0x2510, 0x2201},
++{0x2510, 0xb377},
++{0x2510, 0x8843},
++{0x2510, 0x916f},
++{0x2510, 0x2201},
++{0x2510, 0xb84e},
++{0x2510, 0xf905},
++{0x2510, 0xf907},
++{0x2510, 0x2200},
++{0x2510, 0x885b},
++{0x2510, 0xa898},
++{0x2510, 0xa8d8},
++{0x2510, 0xf8e8},
++{0x2510, 0x80d8},
++{0x2510, 0x9007},
++{0x2510, 0x916f},
++{0x2510, 0x2206},
++{0x2510, 0xb808},
++{0x2510, 0xc800},
++{0x2510, 0xe809},
++{0x2510, 0x88db},
++{0x2510, 0xf8a8},
++{0x2510, 0xf888},
++{0x2510, 0x2203},
++{0x2510, 0xb07b},
++{0x2510, 0x2000},
++{0x2510, 0x80c8},
++{0x2510, 0x8088},
++{0x2510, 0x220b},
++{0x2510, 0xb06a},
++{0x2510, 0x88cb},
++{0x2510, 0x888b},
++{0x2510, 0x2224},
++{0x2510, 0xb04a},
++{0x2510, 0x2218},
++{0x2510, 0x210d},
++{0x2510, 0x2108},
++{0x2510, 0x902f},
++{0x2510, 0xb04b},
++{0x2510, 0xf880},
++{0x2510, 0x2205},
++{0x2510, 0x2205},
++{0x2510, 0x2203},
++{0x2510, 0x9800},
++{0x2510, 0xb043},
++{0x2510, 0xa8c9},
++{0x2510, 0x31c1},
++{0x2510, 0x80a8},
++{0x2510, 0x2205},
++{0x2510, 0x916f},
++{0x2510, 0x2104},
++{0x2510, 0x88ab},
++{0x2510, 0x2104},
++{0x2510, 0xb808},
++{0x2510, 0x9800},
++{0x2510, 0x2440},
++{0x2510, 0xf110},
++{0x2510, 0xf804},
++{0x2510, 0x2000},
++{0x2510, 0x8088},
++{0x2510, 0x3002},
++{0x2510, 0xb838},
++{0x2510, 0xa8c8},
++{0x2510, 0xb04b},
++{0x2510, 0x2442},
++{0x2510, 0x3210},
++{0x2510, 0x2206},
++{0x2510, 0x888b},
++{0x2510, 0x2203},
++{0x2510, 0xf1cb},
++{0x2510, 0xf1cc},
++{0x2510, 0xf1cc},
++{0x2510, 0x2201},
++{0x2510, 0x3202},
++{0x2510, 0xf880},
++{0x2510, 0xb830},
++{0x2510, 0xc801},
++{0x2510, 0x30c2},
++{0x2510, 0xe80c},
++{0x2510, 0x2201},
++{0x2510, 0xb04a},
++{0x2510, 0x2226},
++{0x2510, 0x2205},
++{0x2510, 0x3241},
++{0x2510, 0x2206},
++{0x2510, 0x902f},
++{0x2510, 0x220e},
++{0x2510, 0x2205},
++{0x2510, 0x2204},
++{0x2510, 0xb042},
++{0x2510, 0xa9a1},
++{0x2510, 0x8008},
++{0x2510, 0xb0d3},
++{0x2510, 0x31c1},
++{0x2510, 0x916b},
++{0x2510, 0x2008},
++{0x2510, 0x32c1},
++{0x2510, 0x8803},
++{0x2510, 0xa044},
++{0x2510, 0x3044},
++{0x2510, 0x2000},
++{0x2510, 0xa004},
++{0x2510, 0x2000},
++{0x2510, 0x7fff},
++{0x2510, 0x7fff},
++{0x2510, 0xa084},
++{0x2510, 0x30d0},
++{0x2510, 0x807c},
++{0x2510, 0x3141},
++{0x2510, 0x3041},
++{0x2510, 0x3042},
++{0x2510, 0x2000},
++{0x2510, 0x3142},
++{0x2510, 0x3041},
++{0x2510, 0x3042},
++{0x2510, 0x2000},
++{0x2510, 0x3281},
++{0x2510, 0x3041},
++{0x2510, 0x3042},
++{0x2510, 0x2000},
++{0x2510, 0x3290},
++{0x2510, 0x3041},
++{0x2510, 0x3042},
++{0x2510, 0x2000},
++{0x2510, 0x3110},
++{0x2510, 0x3041},
++{0x2510, 0x2000},
++{0x2510, 0x3120},
++{0x2510, 0x3041},
++{0x2510, 0x2000},
++{0x2510, 0x3282},
++{0x2510, 0x3041},
++{0x2510, 0x2000},
++{0x2510, 0x32a0},
++{0x2510, 0x3041},
++{0x2510, 0x2000},
++{0x2510, 0x881b},
++{0x2510, 0x887f},
++{0x2510, 0xa08c},
++{0x2510, 0x221f},
++{0x2510, 0xa084},
++{0x2510, 0x2440},
++{0x2510, 0x3260},
++{0x2510, 0x3248},
++{0x2510, 0xb095},
++{0x2510, 0xf110},
++{0x2510, 0xf864},
++{0x2510, 0xf90d},
++{0x2510, 0x3084},
++{0x2510, 0x32c1},
++{0x2510, 0x3090},
++{0x2510, 0x3088},
++{0x2510, 0x2443},
++{0x2510, 0x8058},
++{0x2510, 0x3001},
++{0x2510, 0x2442},
++{0x2510, 0x3220},
++{0x2510, 0x2002},
++{0x2510, 0x8867},
++{0x2510, 0x2004},
++{0x2510, 0x8803},
++{0x2510, 0x2441},
++{0x2510, 0x30c2},
++{0x2510, 0xa9a0},
++{0x2510, 0xb094},
++{0x2510, 0x2201},
++{0x2510, 0xa0c4},
++{0x2510, 0x3044},
++{0x2510, 0x2000},
++{0x2510, 0xa004},
++{0x2510, 0x7fff},
++{0x2510, 0x7fff},
++{0x2510, 0x7fff},
++{0x2510, 0xb980},
++{0x2510, 0xa881},
++{0x2510, 0xa8c1},
++{0x2510, 0x8108},
++{0x2510, 0xa105},
++{0x2510, 0x30c1},
++{0x2510, 0x2020},
++{0x2510, 0x3101},
++{0x2510, 0x3041},
++{0x2510, 0x3104},
++{0x2510, 0x3102},
++{0x2510, 0x3041},
++{0x2510, 0xf860},
++{0x2510, 0xb095},
++{0x2510, 0x2001},
++{0x2510, 0xb988},
++{0x2510, 0xb9f8},
++{0x2510, 0xb9fc},
++{0x2510, 0x8803},
++{0x2510, 0x916f},
++{0x2510, 0x2001},
++{0x2510, 0xb9fe},
++{0x2510, 0xf905},
++{0x2510, 0xf907},
++{0x2510, 0x3202},
++{0x2510, 0x880b},
++{0x2510, 0xb397},
++{0x2510, 0xf8e8},
++{0x2510, 0x8188},
++{0x2510, 0x9007},
++{0x2510, 0x916f},
++{0x2510, 0x2204},
++{0x2510, 0xb137},
++{0x2510, 0xb9b8},
++{0x2510, 0xc801},
++{0x2510, 0xe809},
++{0x2510, 0xb177},
++{0x2510, 0x888b},
++{0x2510, 0xf8a8},
++{0x2510, 0xf888},
++{0x2510, 0x2203},
++{0x2510, 0xa8c8},
++{0x2510, 0xb07b},
++{0x2510, 0x2000},
++{0x2510, 0x8188},
++{0x2510, 0x8088},
++{0x2510, 0x220b},
++{0x2510, 0xb06a},
++{0x2510, 0x888b},
++{0x2510, 0x888b},
++{0x2510, 0x2224},
++{0x2510, 0xb04a},
++{0x2510, 0x2218},
++{0x2510, 0x210a},
++{0x2510, 0x210a},
++{0x2510, 0xb04b},
++{0x2510, 0x902f},
++{0x2510, 0xf880},
++{0x2510, 0x2211},
++{0x2510, 0x2205},
++{0x2510, 0x2204},
++{0x2510, 0xb043},
++{0x2510, 0xa8c1},
++{0x2510, 0x31c1},
++{0x2510, 0x2200},
++{0x2510, 0x8048},
++{0x2510, 0x2103},
++{0x2510, 0x916f},
++{0x2510, 0x2106},
++{0x2510, 0x884b},
++{0x2510, 0x210a},
++{0x2510, 0xa8c1},
++{0x2510, 0x2440},
++{0x2510, 0xf110},
++{0x2510, 0xf804},
++{0x2510, 0x2000},
++{0x2510, 0x8008},
++{0x2510, 0x2002},
++{0x2510, 0x880b},
++{0x2510, 0x3002},
++{0x2510, 0xb988},
++{0x2510, 0x2442},
++{0x2510, 0x3210},
++{0x2510, 0x2206},
++{0x2510, 0x2441},
++{0x2510, 0xa8c1},
++{0x2510, 0xf1cb},
++{0x2510, 0xf1cc},
++{0x2510, 0xf1cc},
++{0x2510, 0x2010},
++{0x2510, 0x8088},
++{0x2510, 0x200c},
++{0x2510, 0x888b},
++{0x2510, 0x2005},
++{0x2510, 0xa8d0},
++{0x2510, 0xb04b},
++{0x2510, 0x3202},
++{0x2510, 0xf880},
++{0x2510, 0xb980},
++{0x2510, 0xc800},
++{0x2510, 0x30c2},
++{0x2510, 0xe80c},
++{0x2510, 0x2201},
++{0x2510, 0xb04a},
++{0x2510, 0x2213},
++{0x2510, 0x2225},
++{0x2510, 0x8088},
++{0x2510, 0x2205},
++{0x2510, 0x888b},
++{0x2510, 0x2203},
++{0x2510, 0x3241},
++{0x2510, 0x902f},
++{0x2510, 0x2206},
++{0x2510, 0x2204},
++{0x2510, 0xb042},
++{0x2510, 0xa9a1},
++{0x2510, 0x8058},
++{0x2510, 0xb093},
++{0x2510, 0x31c1},
++{0x2510, 0x916b},
++{0x2510, 0x2008},
++{0x2510, 0x32c1},
++{0x2510, 0x8803},
++{0x2510, 0xa144},
++{0x2510, 0x3044},
++{0x2510, 0x2000},
++{0x2510, 0xa004},
++{0x2510, 0xb800},
++{0x2510, 0x7fff},
++{0x2510, 0x7fff},
++{0x2510, 0x7fff},
++{0x2510, 0x7fff},
++{0x2510, 0x30d0},
++{0x2510, 0xa184},
++{0x2510, 0xb980},
++{0x2510, 0x807c},
++{0x2510, 0x3141},
++{0x2510, 0x3041},
++{0x2510, 0x3042},
++{0x2510, 0x2000},
++{0x2510, 0x3142},
++{0x2510, 0x3041},
++{0x2510, 0x3042},
++{0x2510, 0x2000},
++{0x2510, 0x3281},
++{0x2510, 0x3041},
++{0x2510, 0x3042},
++{0x2510, 0x2000},
++{0x2510, 0x3290},
++{0x2510, 0x3041},
++{0x2510, 0x3042},
++{0x2510, 0x2000},
++{0x2510, 0x3110},
++{0x2510, 0x3041},
++{0x2510, 0x2000},
++{0x2510, 0x3120},
++{0x2510, 0x3041},
++{0x2510, 0x2000},
++{0x2510, 0x3282},
++{0x2510, 0x3041},
++{0x2510, 0x2000},
++{0x2510, 0x32a0},
++{0x2510, 0x3041},
++{0x2510, 0x2000},
++{0x2510, 0x881b},
++{0x2510, 0x887f},
++{0x2510, 0x2440},
++{0x2510, 0x3260},
++{0x2510, 0x3248},
++{0x2510, 0xb095},
++{0x2510, 0xf110},
++{0x2510, 0xf864},
++{0x2510, 0xf90d},
++{0x2510, 0x32c2},
++{0x2510, 0x30a0},
++{0x2510, 0x3090},
++{0x2510, 0x3088},
++{0x2510, 0x2443},
++{0x2510, 0x8058},
++{0x2510, 0x3001},
++{0x2510, 0x2202},
++{0x2510, 0x885b},
++{0x2510, 0x2442},
++{0x2510, 0x3220},
++{0x2510, 0x2003},
++{0x2510, 0x8048},
++{0x2510, 0x2001},
++{0x2510, 0x884b},
++{0x2510, 0x2441},
++{0x2510, 0x30c2},
++{0x2510, 0x2007},
++{0x2510, 0x8008},
++{0x2510, 0x2000},
++{0x2510, 0x880b},
++{0x2510, 0x2008},
++{0x2510, 0x800a},
++{0x2510, 0x200a},
++{0x2510, 0x8002},
++{0x2510, 0xa9a1},
++{0x2510, 0xb094},
++{0x2510, 0x2201},
++{0x2510, 0x8803},
++{0x2510, 0xa1c4},
++{0x2510, 0x3044},
++{0x2510, 0xb800},
++{0x2510, 0xa004},
++{0x2510, 0x7fff},
++{0x2510, 0x7fff},
++{0x2510, 0x2201},
++{0x2510, 0x7fff},
++{0x2510, 0x7fff},
++{0x2510, 0x7fff},
++{0x2510, 0x2201},
++{0x2510, 0x7fff},
++{0x2510, 0x7fff},
++{0x2510, 0x7fff},
++{0x2510, 0x2201},
++{0x2510, 0x7fff},
++{0x2510, 0x7fff},
++{0x2510, 0x7fff},
++{0x2510, 0x2201},
++{0x2510, 0x7fff},
++{0x2510, 0x7fff},
++{0x2510, 0x7fff},
++{0x2510, 0x2400},
++{0x2510, 0x2751},
++{0x2510, 0x2423},
++{0x2510, 0x2750},
++{0x2510, 0x2421},
++{0x2510, 0x7fff},
++{0x2510, 0x7fff},
++{0x2510, 0x7fff},
++{0x2510, 0x2749},
++{0x2510, 0x2422},
++{0x2510, 0x2749},
++{0x2510, 0x2423},
++{0x2510, 0x2709},
++{0x2510, 0x2420},
++{0x2510, 0x2729},
++{0x2510, 0x2423},
++{0x2510, 0x3242},
++{0x2510, 0x2722},
++{0x2510, 0x2422},
++{0x2510, 0x2769},
++{0x2510, 0x2421},
++{0x2510, 0x2702},
++{0x2510, 0x2421},
++{0x2510, 0x3242},
++{0x2510, 0x276a},
++{0x2510, 0x2420},
++{0x2510, 0x276a},
++{0x2510, 0x2421},
++{0x2510, 0x2703},
++{0x2510, 0x2420},
++{0x2510, 0x2703},
++{0x2510, 0x2421},
++{0x2510, 0x3242},
++{0x2510, 0x276b},
++{0x2510, 0x2420},
++{0x2510, 0x276b},
++{0x2510, 0x2421},
++{0x2510, 0x2704},
++{0x2510, 0x2420},
++{0x2510, 0x2704},
++{0x2510, 0x2421},
++{0x2510, 0x3242},
++{0x2510, 0x276c},
++{0x2510, 0x2420},
++{0x2510, 0x276c},
++{0x2510, 0x2421},
++{0x2510, 0x7fff},
++{0x2510, 0x7fff},
++{0x2510, 0x2759},
++{0x2510, 0x2422},
++{0x2510, 0x2758},
++{0x2510, 0x2420},
++{0x2510, 0x2403},
++{0x2510, 0x2712},
++{0x2510, 0x3242},
++{0x2510, 0x2422},
++{0x2510, 0x271a},
++{0x2510, 0x3242},
++{0x2510, 0x2420},
++{0x2510, 0x2702},
++{0x2510, 0x2423},
++{0x2510, 0x2759},
++{0x2510, 0x2439},
++{0x2510, 0x2758},
++{0x2510, 0x243a},
++{0x2510, 0x7fff},
++{0x2510, 0x7fff},
++{0x2510, 0x7fff},
++{0x2510, 0x2400},
++{0x2510, 0x7fff},
++{0x2510, 0x7fff},
++{0x2510, 0x7fff},
++{0x2510, 0x3250},
++{0x2510, 0xc023},
++{0x2510, 0x2402},
++{0x2510, 0x2405},
++{0x2510, 0x2789},
++{0x2510, 0x242e},
++{0x2510, 0x2788},
++{0x2510, 0x242f},
++{0x2510, 0x7fff},
++{0x2510, 0x7fff},
++{0x2510, 0x7fff},
++{0x2510, 0x7fff},
++{0x2510, 0x3250},
++{0x2510, 0x27d8},
++{0x2510, 0x2433},
++{0x2510, 0x27d9},
++{0x2510, 0x2434},
++{0x2510, 0x3250},
++{0x2510, 0xc023},
++{0x2510, 0x2402},
++{0x2510, 0xc023},
++{0x2510, 0x2751},
++{0x2510, 0x2423},
++{0x2510, 0xc02b},
++{0x2510, 0x2750},
++{0x2510, 0x2421},
++{0x2510, 0xc003},
++{0x2510, 0x7fff},
++{0x2510, 0x3250},
++{0x2510, 0xc021},
++{0x2510, 0x2400},
++{0x2510, 0x2405},
++{0x2510, 0xc062},
++{0x2510, 0x3250},
++{0x2510, 0x2400},
++{0x2510, 0xc023},
++{0x2510, 0x2751},
++{0x2510, 0x2423},
++{0x2510, 0xc02b},
++{0x2510, 0x2750},
++{0x2510, 0x2421},
++{0x2510, 0xc003},
++{0x2510, 0x7fff},
++{0x2510, 0x7fff},
++{0x2510, 0x3250},
++{0x2510, 0xc0e3},
++{0x2510, 0x2400},
++{0x2510, 0x27b1},
++{0x2510, 0x2437},
++{0x2510, 0x3250},
++{0x2510, 0xc02b},
++{0x2510, 0x2422},
++{0x2510, 0xc023},
++{0x2510, 0x2751},
++{0x2510, 0x2423},
++{0x2510, 0xc02b},
++{0x2510, 0x2750},
++{0x2510, 0x2421},
++{0x2510, 0xc003},
++{0x2510, 0x7fff},
++{0x2510, 0x2404},
++{0x2510, 0x2779},
++{0x2510, 0x242c},
++{0x2510, 0x2781},
++{0x2510, 0x242d},
++{0x2510, 0x7fff},
++{0x2510, 0x7fff},
++{0x2510, 0x7fff},
++{0x2510, 0x2791},
++{0x2510, 0x2430},
++{0x2510, 0x2799},
++{0x2510, 0x2428},
++{0x2510, 0x7fff},
++{0x2510, 0x7fff},
++{0x2510, 0x7fff},
++{0x2510, 0x7fff},
++{0x2510, 0x27a1},
++{0x2510, 0x2430},
++{0x2510, 0x27a9},
++{0x2510, 0x2428},
++{0x2510, 0x7fff},
++{0x2510, 0x7fff},
++{0x2510, 0x7fff},
++{0x2510, 0x7fff},
++{0x2510, 0xc165},
++{0x2510, 0x2415},
++{0x2510, 0xc026},
++{0x2510, 0x2407},
++{0x2510, 0xc027},
++{0x2510, 0x2406},
++{0x2510, 0x2296},
++{0x2510, 0x2416},
++{0x2510, 0x7fff},
++{0x2510, 0x7fff},
++{0x2510, 0x7fff},
++{0x2510, 0x7fff},
++{0x2510, 0xc167},
++{0x2510, 0x2400},
++{0x2510, 0xc067},
++{0x2510, 0x2406},
++{0x2510, 0x2416},
++{0x2510, 0x7fff},
++{0x2510, 0x7fff},
++{0x2510, 0x7fff},
++{0x2510, 0xb800},
++{0x2510, 0x8058},
++{0x2510, 0xa005},
++{0x2510, 0x3101},
++{0x2510, 0x3041},
++{0x2510, 0x3104},
++{0x2510, 0xb035},
++{0x2510, 0xb075},
++{0x2510, 0x30c1},
++{0x2510, 0x3102},
++{0x2510, 0x3041},
++{0x2510, 0xb808},
++{0x2510, 0x3202},
++{0x2510, 0xb848},
++{0x2510, 0xb84c},
++{0x2510, 0x2201},
++{0x2510, 0xb377},
++{0x2510, 0x8843},
++{0x2510, 0x916f},
++{0x2510, 0x2201},
++{0x2510, 0xb84e},
++{0x2510, 0xf905},
++{0x2510, 0xf907},
++{0x2510, 0x2200},
++{0x2510, 0x885b},
++{0x2510, 0xa898},
++{0x2510, 0xa8d8},
++{0x2510, 0xf8e8},
++{0x2510, 0x80d8},
++{0x2510, 0x9007},
++{0x2510, 0x916f},
++{0x2510, 0x2206},
++{0x2510, 0xb808},
++{0x2510, 0xc800},
++{0x2510, 0xe809},
++{0x2510, 0x88db},
++{0x2510, 0xf8a8},
++{0x2510, 0xf888},
++{0x2510, 0x2203},
++{0x2510, 0xb07b},
++{0x2510, 0x2000},
++{0x2510, 0x80c8},
++{0x2510, 0x8088},
++{0x2510, 0x220b},
++{0x2510, 0xb06a},
++{0x2510, 0x88cb},
++{0x2510, 0x888b},
++{0x2510, 0x2224},
++{0x2510, 0xb04a},
++{0x2510, 0x2218},
++{0x2510, 0x210d},
++{0x2510, 0x2108},
++{0x2510, 0x902f},
++{0x2510, 0xb04b},
++{0x2510, 0xf880},
++{0x2510, 0x2211},
++{0x2510, 0x2205},
++{0x2510, 0x2204},
++{0x2510, 0xb043},
++{0x2510, 0xa8c9},
++{0x2510, 0x31c1},
++{0x2510, 0x80a8},
++{0x2510, 0x2205},
++{0x2510, 0x916f},
++{0x2510, 0x2104},
++{0x2510, 0x88ab},
++{0x2510, 0x2440},
++{0x2510, 0xf110},
++{0x2510, 0xf804},
++{0x2510, 0x2000},
++{0x2510, 0x8088},
++{0x2510, 0x3002},
++{0x2510, 0xb838},
++{0x2510, 0xa8c8},
++{0x2510, 0xb04b},
++{0x2510, 0x2442},
++{0x2510, 0x3210},
++{0x2510, 0x2206},
++{0x2510, 0x888b},
++{0x2510, 0x2441},
++{0x2510, 0x3202},
++{0x2510, 0xf880},
++{0x2510, 0xb830},
++{0x2510, 0xc801},
++{0x2510, 0x30c2},
++{0x2510, 0xe80c},
++{0x2510, 0x2201},
++{0x2510, 0xb04a},
++{0x2510, 0x2227},
++{0x2510, 0x2205},
++{0x2510, 0x3241},
++{0x2510, 0x2207},
++{0x2510, 0x902f},
++{0x2510, 0x220e},
++{0x2510, 0x2205},
++{0x2510, 0x2204},
++{0x2510, 0xb042},
++{0x2510, 0xa8c9},
++{0x2510, 0xb043},
++{0x2510, 0x31c1},
++{0x2510, 0x916f},
++{0x2510, 0x2009},
++{0x2510, 0xa004},
++{0x2510, 0x7fff},
++{0x2510, 0x30c2},
++{0x2510, 0xa9a0},
++{0x2510, 0xb094},
++{0x2510, 0x2201},
++{0x2510, 0x7fff},
++{0x2510, 0x7fff},
++{0x2510, 0x7fff},
++{0x2510, 0x7fff},
++{0x2510, 0xb980},
++{0x2510, 0x3260},
++{0x2510, 0x3101},
++{0x2510, 0x3041},
++{0x2510, 0x2000},
++{0x2510, 0x3102},
++{0x2510, 0x3041},
++{0x2510, 0x8038},
++{0x2510, 0x220a},
++{0x2510, 0x881b},
++{0x2510, 0x883b},
++{0x2510, 0x2440},
++{0x2510, 0xb095},
++{0x2510, 0xf110},
++{0x2510, 0xf864},
++{0x2510, 0xf90d},
++{0x2510, 0x8018},
++{0x2510, 0x3004},
++{0x2510, 0x2202},
++{0x2510, 0x2442},
++{0x2510, 0x883b},
++{0x2510, 0x3220},
++{0x2510, 0x2004},
++{0x2510, 0x881b},
++{0x2510, 0x2441},
++{0x2510, 0x30c2},
++{0x2510, 0xa9a0},
++{0x2510, 0xb094},
++{0x2510, 0x2201},
++{0x2510, 0x7fff},
++{0x2510, 0x7fff},
++{0x2510, 0x7fff},
++{0x2510, 0xa005},
++{0x2510, 0xc800},
++{0x2510, 0xe802},
++{0x2510, 0x31c1},
++{0x2510, 0x2440},
++{0x2510, 0x2442},
++{0x2510, 0xc801},
++{0x2510, 0x30c2},
++{0x2510, 0x31c1},
++{0x2510, 0xa044},
++{0x2510, 0x3044},
++{0x2510, 0x2000},
++{0x2510, 0xa004},
++{0x2510, 0x2000},
++{0x2510, 0x7fff},
++{0x2510, 0x7fff},
++{0x2510, 0x2703},
++{0x2510, 0x3242},
++{0x2510, 0x2438},
++{0x2510, 0x2703},
++{0x2510, 0x243b},
++{0x2510, 0x2704},
++{0x2510, 0x3242},
++{0x2510, 0x2438},
++{0x2510, 0x2704},
++{0x2510, 0x243b},
++{0x2510, 0x7fff},
++{0x2510, 0x7fff},
++{0x2510, 0x2703},
++{0x2510, 0x3242},
++{0x2510, 0x2420},
++{0x2510, 0x2703},
++{0x2510, 0x2421},
++{0x2510, 0x2704},
++{0x2510, 0x3242},
++{0x2510, 0x2420},
++{0x2510, 0x2704},
++{0x2510, 0x2421},
++{0x2510, 0x7fff},
++{0x2510, 0x7fff},
++{0x2510, 0xb095},
++{0x2510, 0xf110},
++{0x2510, 0xf864},
++{0x2510, 0xf90d},
++{0x2510, 0x3001},
++{0x2510, 0x2442},
++{0x2510, 0x30c2},
++{0x2510, 0xa9a0},
++{0x2510, 0xb094},
++{0x2510, 0xb800},
++{0x2510, 0x7fff},
++{0x2510, 0x7fff},
++{0x2510, 0xffff},
++{0x2510, 0xffff},
++{0x2510, 0xffff},
++{0x2510, 0xffff},
++{0x2510, 0xffff},
++{0x2510, 0xffff},
++{0x2510, 0xffff},
++{0x2510, 0xffff},
++{0x2510, 0xffff},
++{0x2510, 0xffff},
++{0x2510, 0xffff},
++{0x2510, 0xffff},
++{0x2510, 0xffff},
++{0x2510, 0xffff},
++{0x2510, 0xffff},
++{0x2510, 0xffff},
++{0x2510, 0xffff},
++{0x2510, 0xffff},
++{0x2510, 0xffff},
++{0x2510, 0xffff},
++{0x2510, 0xffff},
++{0x2510, 0xffff},
++{0x2510, 0xffff},
++{0x2510, 0xffff},
++{0x2510, 0xffff},
++{0x2510, 0xffff},
++{0x2510, 0xffff},
++{0x2510, 0xffff},
++{0x2510, 0xffff},
++{0x2510, 0xffff},
++{0x2510, 0xffff},
++{0x2510, 0xffff},
++{0x2510, 0xffff},
++{0x2510, 0xffff},
++{0x2510, 0xffff},
++{0x2510, 0xffff},
++{0x2510, 0xffff},
++{0x2510, 0xffff},
++{0x2510, 0xffff},
++{0x2510, 0xffff},
++{0x2510, 0xffff},
++{0x2510, 0xffff},
++{0x2510, 0xffff},
++{0x2510, 0xffff},
++{0x2510, 0xffff},
++{0x2510, 0xffff},
++{0x2510, 0xffff},
++{0x2510, 0xffff},
++{0x2510, 0xffff},
++{0x2510, 0xffff},
++{0x2510, 0xffff},
++{0x2510, 0xffff},
++{0x2510, 0xffff},
++{0x2510, 0xffff},
++{0x2510, 0xffff},
++{0x2510, 0xffff},
++{0x2510, 0xffff},
++{0x2510, 0xffff},
++{0x2510, 0xffff},
++{0x2510, 0xffff},
++{0x2510, 0xffff},
++{0x2510, 0xffff},
++{0x2510, 0xffff},
++{0x2510, 0xffff},
++{0x2510, 0xffff},
++{0x2510, 0xffff},
++{0x2510, 0xffff},
++{0x2510, 0xffff},
++{0x2510, 0xffff},
++{0x2510, 0xffff},
++{0x2510, 0xffff},
++{0x2510, 0xffff},
++{0x2510, 0xffff},
++{0x2510, 0xffff},
++{0x2510, 0xffff},
++{0x2510, 0xffff},
++{0x2510, 0xffff},
++{0x2510, 0xffff},
++{0x2510, 0xffff},
++{0x2510, 0xffff},
++{0x2510, 0xffff},
++{0x2510, 0xffff},
++{0x2510, 0xffff},
++{0x2510, 0xffff},
++{0x2510, 0xffff},
++{0x2510, 0xffff},
++{0x2510, 0xffff},
++{0x2510, 0xffff},
++{0x2510, 0xffff},
++{0x2510, 0xffff},
++{0x2510, 0xffff},
++{0x2510, 0xffff},
++{0x2510, 0xffff},
++{0x2510, 0xffff},
++{0x2510, 0xffff},
++{0x2510, 0xffff},
++{0x2510, 0xffff},
++{0x2510, 0xffff},
++{0x2510, 0xffff},
++{0x2510, 0xffff},
++{0x2510, 0xffff},
++{0x2510, 0x3426},
++{0x2510, 0x3614},
++{AR0233_DELAY, 100},
++#endif /* Sequence_hidy_ar0233_REV2_V13 */
++
++#ifdef Pre_hdr_gain_enable
++{0x3110, 0x0011},
++#endif /* Pre_hdr_gain_enable */
++
++#ifdef Tempsensor_init
++{0x3E94, 0x3007},
++{0x3E6E, 0xE200},
++{0x3E98, 0x1000},
++{0x3F92, 0x4C00},
++{0x30B8, 0x000B},
++{0x30B8, 0x0003},
++#endif /* Tempsensor_init */
++
++{0x3364, 0x0766}, //14.8
++#endif /* O1_Recommended_Defaults_LFM_HDR */
++
++#ifdef disable_embed_data_stat
++{0x3064, 0x0}, // Disable embedded data and stat
++#endif /* disable_embed_data_stat */
++
++#ifdef HDR_3exp_12bit
++{0x3082, 0x8}, //num_exp = 3
++{0x30BA, 0x1122}, //num_exp_max =3
++{0x31AC, 0x140C}, //12 bit output
++#endif /* HDR_3exp_12bit */
++
++#ifdef pll_27_124p5_4lane_12b
++// serial_data_rate was *2 in REV1. but not in REV2
++{0x3030, 0x53}, //PLL_MULTIPLIER
++{0x302E, 0x3}, //PRE_PLL_CLK_DIV
++{0x302C, 0x701}, //P1 divider (vt_sys_clk_div)
++{0x302A, 0x6}, //P2 divider (vt_pix_clk_div)
++{0x3038, 0x2}, //P3 divider (op_sys_clk_div)
++{0x3036, 0x6}, //P4 divider (op_word_clk_div)
++{0x31DC, 0x1FB0}, //vcodiv
++#endif /* pll_27_124p5_4lane_12b */
++
++#ifdef mipi_124p5_12bit_4lane
++{0x31AE, 0x204}, //serial type and lane
++{0x31B0, 0x67}, //frame_preamble
++{0x31B2, 0x30}, //line_preamble
++{0x31B4, 0x22CC}, //mipi_timing_0
++{0x31B6, 0x33D3}, //mipi_timing_1
++{0x31B8, 0xB04D}, //mipi_timing_2
++{0x31BA, 0x411}, //mipi_timing_3
++{0x31BC, 0x940E}, //mipi_timing_4
++#endif /* mipi_124p5_12bit_4lane */
++
++#ifdef pll_27_108_4lane_12b
++// serial_data_rate was *2 in REV1. but not in REV2
++/* PCLK=27Mhz/PRE_PLL_CLK_DIV *PLL_MULTIPLIER /P1 /P4 */
++/* PCLK=27Mhz/0x3 *0x48/1/6= 108Mhz - TI serializers */
++{0x3030, 0x48}, //PLL_MULTIPLIER
++{0x302E, 0x3}, //PRE_PLL_CLK_DIV
++{0x302C, 0x701}, //P1 divider (vt_sys_clk_div)
++{0x302A, 0x6}, //P2 divider (vt_pix_clk_div)
++{0x3038, 0x2}, //P3 divider (op_sys_clk_div)
++{0x3036, 0x6}, //P4 divider (op_word_clk_div)
++{0x31DC, 0x1FB0}, //vcodiv
++#endif /* pll_27_108_4lane_12b */
++
++#ifdef mipi_108_12bit_4lane
++{0x31AE, 0x204}, //MIPI_enable
++{0x31B0, 0x67}, //frame_preamble
++{0x31B2, 0x30}, //line_preamble
++{0x31B4, 0x22CC}, //mipi_timing_0
++{0x31B6, 0x33D3}, //mipi_timing_1
++{0x31B8, 0xB04D}, //mipi_timing_2
++{0x31BA, 0x411}, //mipi_timing_3
++{0x31BC, 0x940E}, //mipi_timing_4
++#endif /* mipi_108_12bit_4lane */
++
++#ifdef MIPI_DT_bit12
++{0x3342, 0x122C}, // MIPI_F1_PDT_EDT
++{0x3346, 0x122C}, // MIPI_F2_PDT_EDT
++{0x334A, 0x122C}, // MIPI_F3_PDT_EDT
++{0x334E, 0x122C}, // MIPI_F4_PDT_EDT
++#endif /* MIPI_DT_bit12 */
++
++#ifdef LUT_24_to_12
++{0x31AC, 0x180C},
++{0x31D0, 0x01}, //companding
++{0x33DA, 0},
++{0x33C0, 0x2000}, //LUT_00
++{0x33C2, 0x3450},
++{0x33C4, 0x48A0},
++{0x33C6, 0x5CF0},
++{0x33C8, 0x7140},
++{0x33CA, 0x8590},
++{0x33CC, 0x99E0},
++{0x33CE, 0xAE30},
++{0x33D0, 0xC280},
++{0x33D2, 0xD6D0},
++{0x33D4, 0xEB20},
++{0x33D6, 0xFF70},
++{0x33F4, 0xFF70},
++{0x33F6, 0xFF70},
++{0x33F8, 0xFF70},
++{0x33FA, 0xFF70}, //LUT_15
++#endif /* LUT_24_to_12 */
++
++/* resolution */
++{0x3004, AR0233_X_START}, // X_ADDR_START_
++{0x3008, AR0233_X_END}, // X_ADDR_END_
++{0x3002, AR0233_Y_START}, // Y_ADDR_START_
++{0x3006, AR0233_Y_END}, // Y_ADDR_END_
++
++{0x3044, 0x0400}, //Dark_control
++
++#ifdef HDR_ratio_gain_default
++{0x3362, 0x000F}, //HCG
++{0x3366, 0x1111}, //1x
++{0x3238, 0x0444}, // Ratio 16x, Use retio setting
++#endif /* HDR_ratio_gain_default */
++
++// FPS = 124.5MHz / reg0x300A / reg0x300C * (DES_REF_XTAL/27MHz)
++{0x300A, AR0233_SENSOR_HEIGHT + 100}, // Frame_length_Lines
++{0x300C, AR0233_SENSOR_WIDTH + 400}, // Line_length_pck
++{0x3012, 0x144}, //Integration_time
++
++#ifdef Enable_trigger_input
++{0x340A, 0x0070}, // GPIO_CONTROL1: GPIO1 is trigger
++{0x340C, 0x0080}, // GPIO_CONTROL2: GPIO1 is trigger
++{0x30CE, 0x0120}, // TRIGGER_MODE
++//{0x30DC, 0x0120}, // TRIGGER_DELAY
++{0x301A, 0x0118}, // GPI pins enable
++#endif /* Enable_trigger_input */
++};
+--
+2.7.4
+
diff --git a/bsp/meta-rcar/meta-rcar-gen3-adas/recipes-kernel/linux/linux-renesas/0140-lvds-ti9x4-fix-remote-gpio-enablement-for-4-cams.patch b/bsp/meta-rcar/meta-rcar-gen3-adas/recipes-kernel/linux/linux-renesas/0140-lvds-ti9x4-fix-remote-gpio-enablement-for-4-cams.patch
new file mode 100644
index 00000000..9aae7cb4
--- /dev/null
+++ b/bsp/meta-rcar/meta-rcar-gen3-adas/recipes-kernel/linux/linux-renesas/0140-lvds-ti9x4-fix-remote-gpio-enablement-for-4-cams.patch
@@ -0,0 +1,81 @@
+From f07aa0200ffd820fdceb9a06816927d81071cc61 Mon Sep 17 00:00:00 2001
+From: Vladimir Barinov <vladimir.barinov@cogentembedded.com>
+Date: Sun, 6 Jan 2019 18:18:23 +0300
+Subject: [PATCH 089/122] lvds: ti9x4: fix remote gpio enablement for 4 cams
+
+This fix enablemnet of remote gpio (ti953) on all 4 cams
+
+Signed-off-by: Vladimir Barinov <vladimir.barinov@cogentembedded.com>
+---
+ drivers/media/i2c/soc_camera/ti9x4.c | 39 ++++++++++++++++++++----------------
+ 1 file changed, 22 insertions(+), 17 deletions(-)
+
+diff --git a/drivers/media/i2c/soc_camera/ti9x4.c b/drivers/media/i2c/soc_camera/ti9x4.c
+index f0b782f..7b8209b 100644
+--- a/drivers/media/i2c/soc_camera/ti9x4.c
++++ b/drivers/media/i2c/soc_camera/ti9x4.c
+@@ -279,8 +279,7 @@ static int ti9x4_initialize(struct i2c_client *client)
+ {
+ struct ti9x4_priv *priv = i2c_get_clientdata(client);
+ int idx, timeout;
+- u8 port_sts1 = 0, port_sts2 = 0;
+- int tmp_addr;
++ u8 port_sts1[4] = {0, 0, 0, 0}, port_sts2[4] = {0, 0, 0, 0};
+
+ dev_info(&client->dev, "LINKs=%d, LANES=%d, FORWARDING=%s, CABLE=%s, ID=%s\n",
+ priv->links, priv->lanes, priv->forwarding_mode, priv->is_coax ? "coax" : "stp", priv->chip_id);
+@@ -301,30 +300,36 @@ static int ti9x4_initialize(struct i2c_client *client)
+ /* check lock status */
+ for (timeout = 500 / priv->links; timeout > 0; timeout--) {
+ for (idx = 0; idx < priv->links; idx++) {
++ if ((port_sts1[idx] & 0x1) && (port_sts2[idx] & 0x4))
++ continue;
++
+ reg8_write(client, 0x4c, (idx << 4) | (1 << idx)); /* Select RX port number */
+ usleep_range(1000, 1500); /* wait 1ms */
+- reg8_read(client, 0x4d, &port_sts1); /* Lock status */
+- reg8_read(client, 0x4e, &port_sts2); /* Freq stable */
+-
+- if (port_sts1 & 0x1) {
+- tmp_addr = client->addr;
+- client->addr = priv->ti9x3_addr_map[idx]; /* TI9X3 I2C addr */
+- reg8_write(client, 0x0d, 0xf0); /* Enable all remote GPIOs */
+- reg8_write(client, 0x0e, 0xf0); /* Enable serializer GPIOs */
+- client->addr = tmp_addr;
+- }
+-
+- if ((port_sts1 & 0x1) && (port_sts2 & 0x4))
+- goto out;
++ reg8_read(client, 0x4d, &port_sts1[idx]); /* Lock status */
++ reg8_read(client, 0x4e, &port_sts2[idx]); /* Freq stable */
+ }
+ }
+
+ if (!timeout)
+- dev_info(&client->dev, "Receiver is not locked\n");
+-out:
++ dev_info(&client->dev, "Receiver lock status [%d,%d,%d,%d]\n",
++ (port_sts1[0] & 0x1) && (port_sts2[0] & 0x4),
++ (port_sts1[1] & 0x1) && (port_sts2[1] & 0x4),
++ (port_sts1[2] & 0x1) && (port_sts2[2] & 0x4),
++ (port_sts1[3] & 0x1) && (port_sts2[3] & 0x4));
++
+ if (priv->poc_delay)
+ mdelay(100);
+
++ for (idx = 0; idx < priv->links; idx++) {
++ reg8_write(client, 0x4c, (idx << 4) | (1 << idx)); /* Select RX port number */
++ usleep_range(1000, 1500); /* wait 1ms */
++
++ client->addr = priv->ti9x3_addr_map[idx]; /* TI9X3 I2C addr */
++ reg8_write(client, 0x0d, 0xf0); /* Enable all remote GPIOs */
++ reg8_write(client, 0x0e, 0xf0); /* Enable serializer GPIOs */
++ client->addr = priv->des_addr;
++ }
++
+ return 0;
+ }
+
+--
+2.7.4
+
diff --git a/bsp/meta-rcar/meta-rcar-gen3-adas/recipes-kernel/linux/linux-renesas/0141-media-soc_camera-imx390-Add-new-V4L-controls.patch b/bsp/meta-rcar/meta-rcar-gen3-adas/recipes-kernel/linux/linux-renesas/0141-media-soc_camera-imx390-Add-new-V4L-controls.patch
new file mode 100644
index 00000000..ae3d3733
--- /dev/null
+++ b/bsp/meta-rcar/meta-rcar-gen3-adas/recipes-kernel/linux/linux-renesas/0141-media-soc_camera-imx390-Add-new-V4L-controls.patch
@@ -0,0 +1,122 @@
+From 4f8c6f74c5b107277a269ab559dabcb3ab574da8 Mon Sep 17 00:00:00 2001
+From: Andrey Dolnikov <andrey.dolnikov@cogentembedded.com>
+Date: Thu, 10 Jan 2019 18:15:44 +0300
+Subject: [PATCH 090/122] media: soc_camera: imx390: Add new V4L controls
+
+Add vertical and horizontal flips and digital and analog gains support.
+---
+ drivers/media/i2c/soc_camera/imx390.c | 62 +++++++++++++++++++++++++++++++----
+ 1 file changed, 56 insertions(+), 6 deletions(-)
+
+diff --git a/drivers/media/i2c/soc_camera/imx390.c b/drivers/media/i2c/soc_camera/imx390.c
+index fc73b4b..1834195 100644
+--- a/drivers/media/i2c/soc_camera/imx390.c
++++ b/drivers/media/i2c/soc_camera/imx390.c
+@@ -249,6 +249,7 @@ static int imx390_s_ctrl(struct v4l2_ctrl *ctrl)
+ struct imx390_priv *priv = to_imx390(client);
+ int ret = -EINVAL;
+ int val;
++ uint8_t val8;
+
+ if (!priv->init_complete)
+ return 0;
+@@ -264,11 +265,29 @@ static int imx390_s_ctrl(struct v4l2_ctrl *ctrl)
+ break;
+ case V4L2_CID_GAIN:
+ /* Digital gain */
+- ret = 0;
++ /* Set PGA_GAIN_SP1H as Normal SP1 HCG mode is configured in wizard */
++ val8 = ctrl->val & 0xff;
++ ret = reg16_write(client, 0x24, val8);
++#if 0 // stubs for other normal modes and HDR
++ /* Set PGA_GAIN_SP1L as Normal SP1 LCG mode is configured in wizard */
++ val8 = ctrl->val & 0xff;
++ ret = reg16_write(client, 0x26, val8);
++
++ /* Set PGA_GAIN_SP2 as Normal SP2 mode is configured in wizard */
++ val8 = ctrl->val & 0xff;
++ ret = reg16_write(client, 0x28, val8);
++#endif
+ break;
+ case V4L2_CID_ANALOGUE_GAIN:
+ /* Analog gain */
+- ret = 0;
++ /* Set AGAIN_SP1H as Normal SP1 HCG mode is configured in wizard */
++ val8 = ctrl->val & 0xff;
++ ret = reg16_write(client, 0x18, val8);
++#if 0 // stubs for other normal modes and HDR
++ /* Set AGAIN_SP1L as Normal SP1 LCG mode is configured in wizard */
++ val8 = ctrl->val & 0xff;
++ ret = reg16_write(client, 0x1A, val8);
++#endif
+ break;
+ case V4L2_CID_EXPOSURE:
+ val = 0xfff - ctrl->val;
+@@ -277,7 +296,38 @@ static int imx390_s_ctrl(struct v4l2_ctrl *ctrl)
+ // ret |= reg16_write(client, 0x0e, ctrl->val >> 16); /* MSB */
+ break;
+ case V4L2_CID_HFLIP:
++ /* hflip */
++ ret = reg16_read(client, 0x74, &val8);
++ if (ctrl->val)
++ val8 |= (1 << 1);
++ else
++ val8 &= ~(1 << 1);
++ ret |= reg16_write(client, 0x74, val8);
++
++ /* hflip app lock */
++ ret = reg16_read(client, 0x3c0, &val8);
++ if (ctrl->val)
++ val8 |= (1 << 3);
++ else
++ val8 &= ~(1 << 3);
++ ret |= reg16_write(client, 0x3c0, val8);
++ break;
+ case V4L2_CID_VFLIP:
++ /* vflip */
++ ret = reg16_read(client, 0x74, &val8);
++ if (ctrl->val)
++ val8 |= (1 << 0);
++ else
++ val8 &= ~(1 << 0);
++ ret |= reg16_write(client, 0x74, val8);
++
++ /* vflip app lock */
++ ret = reg16_read(client, 0x3c0, &val8);
++ if (ctrl->val)
++ val8 |= (1 << 2);
++ else
++ val8 &= ~(1 << 2);
++ ret |= reg16_write(client, 0x3c0, val8);
+ break;
+ }
+
+@@ -452,7 +502,7 @@ static int imx390_probe(struct i2c_client *client,
+ priv->sd.flags = V4L2_SUBDEV_FL_HAS_DEVNODE;
+
+ priv->exposure = 0x100;
+- priv->gain = 0x100;
++ priv->gain = 0;
+ priv->autogain = 1;
+ v4l2_ctrl_handler_init(&priv->hdl, 4);
+ v4l2_ctrl_new_std(&priv->hdl, &imx390_ctrl_ops,
+@@ -470,13 +520,13 @@ static int imx390_probe(struct i2c_client *client,
+ v4l2_ctrl_new_std(&priv->hdl, &imx390_ctrl_ops,
+ V4L2_CID_AUTOGAIN, 0, 1, 1, priv->autogain);
+ v4l2_ctrl_new_std(&priv->hdl, &imx390_ctrl_ops,
+- V4L2_CID_GAIN, 0, 0xffff, 1, priv->gain);
++ V4L2_CID_GAIN, 0, 140, 1, priv->gain);
+ v4l2_ctrl_new_std(&priv->hdl, &imx390_ctrl_ops,
+- V4L2_CID_ANALOGUE_GAIN, 1, 0xe, 1, 0x7);
++ V4L2_CID_ANALOGUE_GAIN, 0, 100, 1, 0x15);
+ v4l2_ctrl_new_std(&priv->hdl, &imx390_ctrl_ops,
+ V4L2_CID_EXPOSURE, 0, 0xff0, 1, 0xfff - 0x2f2);
+ v4l2_ctrl_new_std(&priv->hdl, &imx390_ctrl_ops,
+- V4L2_CID_HFLIP, 0, 1, 1, 1);
++ V4L2_CID_HFLIP, 0, 1, 1, 0);
+ v4l2_ctrl_new_std(&priv->hdl, &imx390_ctrl_ops,
+ V4L2_CID_VFLIP, 0, 1, 1, 0);
+ priv->sd.ctrl_handler = &priv->hdl;
+--
+2.7.4
+
diff --git a/bsp/meta-rcar/meta-rcar-gen3-adas/recipes-kernel/linux/linux-renesas/0142-lvds-AR233-add-rev1-silion-setup.patch b/bsp/meta-rcar/meta-rcar-gen3-adas/recipes-kernel/linux/linux-renesas/0142-lvds-AR233-add-rev1-silion-setup.patch
new file mode 100644
index 00000000..7600e6d6
--- /dev/null
+++ b/bsp/meta-rcar/meta-rcar-gen3-adas/recipes-kernel/linux/linux-renesas/0142-lvds-AR233-add-rev1-silion-setup.patch
@@ -0,0 +1,1788 @@
+From 7b5b06aaf1f0d1551096b39418bf0b77d1dcf658 Mon Sep 17 00:00:00 2001
+From: Vladimir Barinov <vladimir.barinov@cogentembedded.com>
+Date: Wed, 9 Jan 2019 04:38:34 +0300
+Subject: [PATCH 091/122] lvds: AR233: add rev1 silion setup
+
+Add silicon rev1 for AR0233 imager
+
+Signed-off-by: Vladimir Barinov <vladimir.barinov@cogentembedded.com>
+---
+ drivers/media/i2c/soc_camera/ar0233.c | 19 +-
+ drivers/media/i2c/soc_camera/ar0233.h | 392 +--------
+ drivers/media/i2c/soc_camera/ar0233_rev1.h | 1258 ++++++++++++++++++++++++++++
+ drivers/media/i2c/soc_camera/ar0233_rev2.h | 21 -
+ 4 files changed, 1280 insertions(+), 410 deletions(-)
+ create mode 100644 drivers/media/i2c/soc_camera/ar0233_rev1.h
+
+diff --git a/drivers/media/i2c/soc_camera/ar0233.c b/drivers/media/i2c/soc_camera/ar0233.c
+index 2a0b7aa..19386bb 100644
+--- a/drivers/media/i2c/soc_camera/ar0233.c
++++ b/drivers/media/i2c/soc_camera/ar0233.c
+@@ -20,11 +20,12 @@
+ #include <media/v4l2-common.h>
+ #include <media/v4l2-ctrls.h>
+
+-#include "ar0233_rev2.h"
++#include "ar0233.h"
+
+ static const int ar0233_i2c_addr[] = {0x10, 0x20};
+
+ #define AR0233_PID 0x3000
++#define AR0233_REV 0x300E
+ #define AR0233_VERSION_REG 0x0956
+
+ #define AR0233_MEDIA_BUS_FMT MEDIA_BUS_FMT_SGRBG12_1X12
+@@ -377,7 +378,7 @@ static int ar0233_initialize(struct i2c_client *client)
+ {
+ struct ar0233_priv *priv = to_ar0233(client);
+ u16 val = 0;
+- u16 pid = 0;
++ u16 pid = 0, rev = 0;
+ int ret = 0;
+ int tmp_addr;
+ int i;
+@@ -404,18 +405,26 @@ static int ar0233_initialize(struct i2c_client *client)
+ goto err;
+ }
+
++ /* check revision */
++ reg16_read16(client, AR0233_REV, &rev);
+ /* Read OTP IDs */
+ ar0233_otp_id_read(client);
+ /* Program wizard registers */
+- ar0233_set_regs(client, ar0233_regs_wizard_rev2, ARRAY_SIZE(ar0233_regs_wizard_rev2));
++ switch (rev) {
++ case 0x2015:
++ ar0233_set_regs(client, ar0233_regs_wizard_rev2, ARRAY_SIZE(ar0233_regs_wizard_rev2));
++ break;
++ default:
++ ar0233_set_regs(client, ar0233_regs_wizard_rev1, ARRAY_SIZE(ar0233_regs_wizard_rev1));
++ }
+
+ /* Enable stream */
+ reg16_read16(client, 0x301a, &val); // read inital reset_register value
+ val |= (1 << 2); // Set streamOn bit
+ reg16_write16(client, 0x301a, val); // Start Streaming
+
+- dev_info(&client->dev, "ar0233 PID %x, res %dx%d, OTP_ID %02x:%02x:%02x:%02x:%02x:%02x\n",
+- pid, AR0233_MAX_WIDTH, AR0233_MAX_HEIGHT, priv->id[0], priv->id[1], priv->id[2], priv->id[3], priv->id[4], priv->id[5]);
++ dev_info(&client->dev, "ar0233 PID %x (rev %x), res %dx%d, OTP_ID %02x:%02x:%02x:%02x:%02x:%02x\n",
++ pid, rev, AR0233_MAX_WIDTH, AR0233_MAX_HEIGHT, priv->id[0], priv->id[1], priv->id[2], priv->id[3], priv->id[4], priv->id[5]);
+ err:
+ return ret;
+ }
+diff --git a/drivers/media/i2c/soc_camera/ar0233.h b/drivers/media/i2c/soc_camera/ar0233.h
+index ad65390..f6ba245 100644
+--- a/drivers/media/i2c/soc_camera/ar0233.h
++++ b/drivers/media/i2c/soc_camera/ar0233.h
+@@ -1,7 +1,7 @@
+ /*
+- * ON Semiconductor AR0233 sensor camera wizard 1920x1080@30/BGGR/MIPI
++ * ON Semiconductor AR0233 sensor camera wizard 2048x1280@30/BGGR/MIPI
+ *
+- * Copyright (C) 2018 Cogent Embedded, Inc.
++ * Copyright (C) 2019 Cogent Embedded, Inc.
+ *
+ * This program is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License as published by the
+@@ -12,13 +12,13 @@
+ //#define AR0233_DISPLAY_PATTERN_FIXED
+ //#define AR0233_DISPLAY_PATTERN_COLOR_BAR
+
+-#define AR0233_MAX_WIDTH 1920
+-#define AR0233_MAX_HEIGHT 1200
++#define AR0233_MAX_WIDTH 2048
++#define AR0233_MAX_HEIGHT 1280
+
+ #define AR0233_DELAY 0xffff
+
+-#define AR0233_SENSOR_WIDTH 1920
+-#define AR0233_SENSOR_HEIGHT 1200
++#define AR0233_SENSOR_WIDTH 2058
++#define AR0233_SENSOR_HEIGHT 1284
+
+ #define AR0233_X_START ((AR0233_SENSOR_WIDTH - AR0233_MAX_WIDTH) / 2)
+ #define AR0233_Y_START ((AR0233_SENSOR_HEIGHT - AR0233_MAX_HEIGHT) / 2)
+@@ -30,381 +30,5 @@ struct ar0233_reg {
+ u16 val;
+ };
+
+-static const struct ar0233_reg ar0233_regs_wizard[] = {
+-{0x301A, 0x0018}, // RESET_REGISTER
+-{AR0233_DELAY, 500}, // Wait 500ms
+-{0x3070, 0x0000}, // 1: Solid color test pattern,
+- // 2: Full color bar test pattern,
+- // 3: Fade to grey color bar test pattern,
+- //256: Walking 1 test pattern (12 bit)
+-{0x3072, 0x0123}, // R
+-{0x3074, 0x0456}, // G(GR row)
+-{0x3076, 0x0abc}, // B
+-{0x3078, 0x0def}, // G(GB row)
+-#ifdef AR0233_DISPLAY_PATTERN_FIXED
+-{0x3070, 0x0001},
+-#endif
+-#ifdef AR0233_DISPLAY_PATTERN_COLOR_BAR
+-{0x3070, 0x0002},
+-#endif
+-{AR0233_DELAY, 100}, // Wait 100ms
+-
+-{0x3092, 0x0C24},
+-{0x337A, 0x0C80},
+-{0x3520, 0x1288},
+-{0x3522, 0x880C},
+-{0x3524, 0x0C12},
+-{0x352C, 0x1212},
+-{0x354A, 0x007F},
+-{0x350C, 0x0568},
+-{0x3506, 0x3333},
+-{0x3508, 0x3333},
+-{0x3100, 0x4000},
+-{0x3280, 0x0FA0},
+-{0x3282, 0x0FA0},
+-{0x3284, 0x0FA0},
+-{0x3286, 0x0FA0},
+-{0x3288, 0x0FA0},
+-{0x328A, 0x0FA0},
+-{0x328C, 0x0FA0},
+-{0x328E, 0x0FA0},
+-{0x3290, 0x0FA0},
+-{0x3292, 0x0FA0},
+-{0x3294, 0x0FA0},
+-{0x3296, 0x0FA0},
+-{0x3298, 0x0FA0},
+-{0x329A, 0x0FA0},
+-{0x329C, 0x0FA0},
+-{0x329E, 0x0FA0},
+-
+-{AR0233_DELAY, 200}, // Wait 200ms
+-
+-{0x2512, 0x8000},
+-{0x2510, 0x0905},
+-{0x2510, 0x3350},
+-{0x2510, 0x2004},
+-{0x2510, 0x1460},
+-{0x2510, 0x1578},
+-{0x2510, 0x0901},
+-{0x2510, 0x7B24},
+-{0x2510, 0xFF24},
+-{0x2510, 0xFF24},
+-{0x2510, 0xEA24},
+-{0x2510, 0x1022},
+-{0x2510, 0x2410},
+-{0x2510, 0x155A},
+-{0x2510, 0x0901},
+-{0x2510, 0x1400},
+-{0x2510, 0x24FF},
+-{0x2510, 0x24FF},
+-{0x2510, 0x24EA},
+-{0x2510, 0x2324},
+-{0x2510, 0x647A},
+-{0x2510, 0x2404},
+-{0x2510, 0x052C},
+-{0x2510, 0x400A},
+-{0x2510, 0xFF0A},
+-{0x2510, 0xFF0A},
+-{0x2510, 0x1008},
+-{0x2510, 0x3851},
+-{0x2510, 0x1440},
+-{0x2510, 0x0004},
+-{0x2510, 0x0801},
+-{0x2510, 0x0408},
+-{0x2510, 0x1180},
+-{0x2510, 0x2652},
+-{0x2510, 0x1518},
+-{0x2510, 0x0906},
+-{0x2510, 0x1348},
+-{0x2510, 0x1002},
+-{0x2510, 0x1016},
+-{0x2510, 0x1181},
+-{0x2510, 0x1189},
+-{0x2510, 0x1056},
+-{0x2510, 0x1210},
+-{0x2510, 0x0901},
+-{0x2510, 0x0D09},
+-{0x2510, 0x1413},
+-{0x2510, 0x8809},
+-{0x2510, 0x2B15},
+-{0x2510, 0x8809},
+-{0x2510, 0x0311},
+-{0x2510, 0xD909},
+-{0x2510, 0x1214},
+-{0x2510, 0x4109},
+-{0x2510, 0x0312},
+-{0x2510, 0x1409},
+-{0x2510, 0x0110},
+-{0x2510, 0xD612},
+-{0x2510, 0x1012},
+-{0x2510, 0x1212},
+-{0x2510, 0x1011},
+-{0x2510, 0xDD11},
+-{0x2510, 0xD910},
+-{0x2510, 0x5609},
+-{0x2510, 0x1511},
+-{0x2510, 0xDB09},
+-{0x2510, 0x1511},
+-{0x2510, 0x9B09},
+-{0x2510, 0x0F11},
+-{0x2510, 0xBB12},
+-{0x2510, 0x1A12},
+-{0x2510, 0x1014},
+-{0x2510, 0x6012},
+-{0x2510, 0x5010},
+-{0x2510, 0x7610},
+-{0x2510, 0xE609},
+-{0x2510, 0x0812},
+-{0x2510, 0x4012},
+-{0x2510, 0x6009},
+-{0x2510, 0x290B},
+-{0x2510, 0x0904},
+-{0x2510, 0x1440},
+-{0x2510, 0x0923},
+-{0x2510, 0x15C8},
+-{0x2510, 0x13C8},
+-{0x2510, 0x092C},
+-{0x2510, 0x1588},
+-{0x2510, 0x1388},
+-{0x2510, 0x0C09},
+-{0x2510, 0x0C14},
+-{0x2510, 0x4109},
+-{0x2510, 0x1112},
+-{0x2510, 0x6212},
+-{0x2510, 0x6011},
+-{0x2510, 0xBF11},
+-{0x2510, 0xBB10},
+-{0x2510, 0x6611},
+-{0x2510, 0xFB09},
+-{0x2510, 0x3511},
+-{0x2510, 0xBB12},
+-{0x2510, 0x6312},
+-{0x2510, 0x6014},
+-{0x2510, 0x0015},
+-{0x2510, 0x0011},
+-{0x2510, 0xB812},
+-{0x2510, 0xA012},
+-{0x2510, 0x0010},
+-{0x2510, 0x2610},
+-{0x2510, 0x0013},
+-{0x2510, 0x0011},
+-{0x2510, 0x0008},
+-{0x2510, 0x3053},
+-{0x2510, 0x4215},
+-{0x2510, 0x4013},
+-{0x2510, 0x4010},
+-{0x2510, 0x0210},
+-{0x2510, 0x1611},
+-{0x2510, 0x8111},
+-{0x2510, 0x8910},
+-{0x2510, 0x5612},
+-{0x2510, 0x1009},
+-{0x2510, 0x010D},
+-{0x2510, 0x0815},
+-{0x2510, 0xC015},
+-{0x2510, 0xD013},
+-{0x2510, 0x5009},
+-{0x2510, 0x1313},
+-{0x2510, 0xD009},
+-{0x2510, 0x0215},
+-{0x2510, 0xC015},
+-{0x2510, 0xC813},
+-{0x2510, 0xC009},
+-{0x2510, 0x0515},
+-{0x2510, 0x8813},
+-{0x2510, 0x8009},
+-{0x2510, 0x0213},
+-{0x2510, 0x8809},
+-{0x2510, 0x0411},
+-{0x2510, 0xC909},
+-{0x2510, 0x0814},
+-{0x2510, 0x0109},
+-{0x2510, 0x0B11},
+-{0x2510, 0xD908},
+-{0x2510, 0x1400},
+-{0x2510, 0x091A},
+-{0x2510, 0x1440},
+-{0x2510, 0x0903},
+-{0x2510, 0x1214},
+-{0x2510, 0x0901},
+-{0x2510, 0x10D6},
+-{0x2510, 0x1210},
+-{0x2510, 0x1212},
+-{0x2510, 0x1210},
+-{0x2510, 0x11DD},
+-{0x2510, 0x11D9},
+-{0x2510, 0x1056},
+-{0x2510, 0x0917},
+-{0x2510, 0x11DB},
+-{0x2510, 0x0913},
+-{0x2510, 0x11FB},
+-{0x2510, 0x0905},
+-{0x2510, 0x11BB},
+-{0x2510, 0x121A},
+-{0x2510, 0x1210},
+-{0x2510, 0x1460},
+-{0x2510, 0x1250},
+-{0x2510, 0x1076},
+-{0x2510, 0x10E6},
+-{0x2510, 0x0901},
+-{0x2510, 0x15A8},
+-{0x2510, 0x0901},
+-{0x2510, 0x13A8},
+-{0x2510, 0x1240},
+-{0x2510, 0x1260},
+-{0x2510, 0x0925},
+-{0x2510, 0x13AD},
+-{0x2510, 0x0902},
+-{0x2510, 0x0907},
+-{0x2510, 0x1588},
+-{0x2510, 0x0901},
+-{0x2510, 0x138D},
+-{0x2510, 0x0B09},
+-{0x2510, 0x0914},
+-{0x2510, 0x4009},
+-{0x2510, 0x0B13},
+-{0x2510, 0x8809},
+-{0x2510, 0x1C0C},
+-{0x2510, 0x0920},
+-{0x2510, 0x1262},
+-{0x2510, 0x1260},
+-{0x2510, 0x11BF},
+-{0x2510, 0x11BB},
+-{0x2510, 0x1066},
+-{0x2510, 0x090A},
+-{0x2510, 0x11FB},
+-{0x2510, 0x093B},
+-{0x2510, 0x11BB},
+-{0x2510, 0x1263},
+-{0x2510, 0x1260},
+-{0x2510, 0x1400},
+-{0x2510, 0x1508},
+-{0x2510, 0x11B8},
+-{0x2510, 0x12A0},
+-{0x2510, 0x1200},
+-{0x2510, 0x1026},
+-{0x2510, 0x1000},
+-{0x2510, 0x1300},
+-{0x2510, 0x1100},
+-{0x2510, 0x437A},
+-{0x2510, 0x0609},
+-{0x2510, 0x0B05},
+-{0x2510, 0x0708},
+-{0x2510, 0x4137},
+-{0x2510, 0x502C},
+-{0x2510, 0x2CFE},
+-{0x2510, 0x15FE},
+-{0x2510, 0x0C2C},
+-{0x32E6, 0x00E0},
+-{0x1008, 0x036F},
+-{0x100C, 0x058F},
+-{0x100E, 0x07AF},
+-{0x1010, 0x014F},
+-{0x3230, 0x0312},
+-{0x3232, 0x0532},
+-{0x3234, 0x0752},
+-{0x3236, 0x00F2},
+-{0x3566, 0x3328},
+-{0x32D0, 0x3A02},
+-{0x32D2, 0x3508},
+-{0x32D4, 0x3702},
+-{0x32D6, 0x3C04},
+-{0x32DC, 0x370A},
+-{0x30B0, 0x0800},
+-/* PCLK=22Mhz/2 *44/1/6= 88.6Mhz - TI serializers */
+-{0x302A, 6}, // VT_PIX_CLK_DIV
+-{0x302C, 1}, // VT_SYS_CLK_DIV
+-{0x302E, 2}, // PRE_PLL_CLK_DIV
+-{0x3030, 44}, // PLL_MULTIPLIER
+-{0x3036, 0x000C}, // OP_WORD_CLK_DIV
+-{0x3038, 0x0001}, // OP_SYS_CLK_DIV
+-{0x30B0, 0x0A00},
+-{0x30A2, 0x0001},
+-{0x30A6, 0x0001},
+-{0x3040, 0x0000},
+-{0x3040, 0x0000},
+-{0x3044, 0x0400},
+-{0x3044, 0x0400},
+-{0x3044, 0x0400},
+-{0x3044, 0x0400},
+-{0x3064, 0x1882},
+-{0x3064, 0x1802},
+-{0x3064, 0x1802},
+-{0x3064, 0x1802},
+-{0x33E0, 0x0C80},
+-{0x33E0, 0x0C80},
+-{0x3180, 0x0080},
+-{0x33E4, 0x0080},
+-{0x33E0, 0x0C80},
+-{0x33E0, 0x0C80},
+-{0x3004, AR0233_X_START}, // X_ADDR_START_
+-{0x3008, AR0233_X_END}, // X_ADDR_END_
+-{0x3002, AR0233_Y_START}, // Y_ADDR_START_
+-{0x3006, AR0233_Y_END}, // Y_ADDR_END_
+-{0x3402, 0x0000 | AR0233_MAX_WIDTH}, // X_OUTPUT_CONTROL
+-{0x3404, 0x0000 | AR0233_MAX_HEIGHT}, // Y_OUTPUT_CONTROL
+-{0x3032, 0x0000},
+-{0x3400, 0x0010},
+-#if 1
+-/* disable HDR */
+-{0x3082, 0x0000},
+-{0x30BA, 0x11F2},
+-#endif
+-{AR0233_DELAY, 100}, // Wait 100ms
+-
+-#if 0
+-{0x300A, AR0233_SENSOR_HEIGHT + 356}, // FRAME_LENGTH_LINES_
+-{0x300C, AR0233_SENSOR_WIDTH + 100}, // LINE_LENGTH_PCK_
+-#else
+-{0x300A, AR0233_SENSOR_HEIGHT + 288}, // FRAME_LENGTH_LINES_
+-{0x300C, AR0233_SENSOR_WIDTH + 300}, // LINE_LENGTH_PCK_
+-#endif
+-{0x3042, 0x0000},
+-{0x3238, 0x0222},
+-{0x3012, 0x0144},
+-{0x3014, AR0233_SENSOR_WIDTH + 100},
+-{0x321E, AR0233_SENSOR_WIDTH + 100},
+-{0x3222, AR0233_SENSOR_WIDTH + 100},
+-{0x30B0, 0x0B00},
+-{0x32EA, 0x3C0E},
+-{0x32EA, 0x3C0E},
+-{0x32EA, 0x3C0E},
+-{0x32EC, 0x72A1},
+-{0x32EC, 0x72A1},
+-{0x32EC, 0x72A1},
+-{0x32EC, 0x72A1},
+-{0x32EC, 0x72A1},
+-{0x32EC, 0x72A1},
+-{0x31D0, 0x0001}, // COMPANDING
+-{0x31AE, 0x0004},
+-{0x31AE, 0x0304},
+-{0x31AC, 0x140C}, // DATA_FORMAT_BITS: RAW12
+-{0x301A, 0x1098},
+-{0x301A, 0x1018},
+-{0x301A, 0x1018},
+-{0x31AE, 0x0204},
+-{0x3342, 0x122C},
+-{0x3346, 0x122C},
+-{0x334A, 0x122C},
+-{0x334E, 0x122C},
+-{0x3344, 0x0011},
+-{0x3348, 0x0111},
+-{0x334C, 0x0211},
+-{0x3350, 0x0311},
+-{0x31B0, 0x0049},
+-{0x31B2, 0x0033},
+-{0x31B4, 0x2185},
+-{0x31B6, 0x1146},
+-{0x31B8, 0x3047},
+-{0x31BA, 0x0186},
+-{0x31BC, 0x0805},
+-#if 1
+-/* Enable trigger input */
+-{0x340A, 0x00E0}, // GPIO_CONTROL1: GPIO1 is trigger
+-{0x340C, 0x0002}, // GPIO_CONTROL2: GPIO1 is trigger
+-{0x30CE, 0x0120}, // TRIGGER_MODE
+-//{0x30DC, 0x0120}, // TRIGGER_DELAY
+-#endif
+-{0x3366, 0x0aaa}, // ANALOG_GAIN
+-{0x301A, 0x011C},
+-};
++#include "ar0233_rev1.h"
++#include "ar0233_rev2.h"
+diff --git a/drivers/media/i2c/soc_camera/ar0233_rev1.h b/drivers/media/i2c/soc_camera/ar0233_rev1.h
+new file mode 100644
+index 0000000..c29ac6a
+--- /dev/null
++++ b/drivers/media/i2c/soc_camera/ar0233_rev1.h
+@@ -0,0 +1,1258 @@
++/*
++ * ON Semiconductor AR0233 sensor camera wizard 2048x1280@30/BGGR/MIPI
++ *
++ * Copyright (C) 2019 Cogent Embedded, Inc.
++ *
++ * This program is free software; you can redistribute it and/or modify it
++ * under the terms of the GNU General Public License as published by the
++ * Free Software Foundation; either version 2 of the License, or (at your
++ * option) any later version.
++ */
++
++/* 3Exp HDR 1080p Mode MIPI-4lane 12-bit 30FPS, XCLK=24MHz */
++static const struct ar0233_reg ar0233_regs_wizard_rev1[] = {
++{0x301A, 0x18}, // MIPI, stream OFF
++{AR0233_DELAY, 200}, // Wait 200ms
++
++{0x3070, 0x0000}, // 1: Solid color test pattern,
++ // 2: Full color bar test pattern,
++ // 3: Fade to grey color bar test pattern,
++ //256: Walking 1 test pattern (12 bit)
++{0x3072, 0x0123}, // R
++{0x3074, 0x0456}, // G(GR row)
++{0x3076, 0x0abc}, // B
++{0x3078, 0x0def}, // G(GB row)
++#ifdef AR0233_DISPLAY_PATTERN_FIXED
++{0x3070, 0x0001},
++#endif
++#ifdef AR0233_DISPLAY_PATTERN_COLOR_BAR
++{0x3070, 0x0002},
++#endif
++{AR0233_DELAY, 100}, // Wait 100ms
++
++#if 1 /* Sequencer Settings */
++#if 1 /* Design_recommended_settings_v5 */
++{0x356C, 0xEA55}, //mte.Sensor.Register("DAC_LD_108_109").Value = 0xEA55& -- ADC write Memory delay 7
++{0x3566, 0x2407}, //mte.Sensor.Register("DAC_LD_102_103").Value = 0x2407& -- Enable column amp bypass for 1x
++{0x3562, 0x1C08}, //mte.Sensor.Register("DAC_LD_98_99").Value = 0x1C08& -- Increase column amp current
++{0x3180, 0x1001}, //mte.Sensor.Register("DELTA_DK_CONTROL").Value = 0x1001& -- enable dither
++{0x3546, 0x4601}, //MTE.Sensor.Register("DAC_LD_70_71::ANA_SREG_VLN_CURR").Value = 17 -- VLN curr
++ //Sensor.Register(sbit_Dac_Ld_70_71_Ana_Sreg_Ae_Shs_Clamp_En).value = 0 ---- Eclipse
++{0x3548, 0x4141}, //MTE.Sensor.Register("DAC_LD_72_73::ANA_SREG_AE_SHR_HCG1").value = 65; //MTE.Sensor.Register("DAC_LD_72_73::ANA_SREG_AE_SHR_HCG0").value = 65
++{0x354A, 0x5958}, //MTE.Sensor.Register("DAC_LD_74_75::ANA_SREG_AE_SHR_HCG3TO7").value = 88; //MTE.Sensor.Register("DAC_LD_74_75::ANA_SREG_AE_SHR_HCG2").value = 89
++{0x3542, 0x44F0}, //MTE.Sensor.Register(sbit_Dac_Ld_66_67_Ana_Drstlo_Sel_Hcg_Lg_3_0).Value = 4, MTE.Sensor.Register(sbit_Dac_Ld_66_67_Ana_Drstlo_Sel_Hcg_Hg_3_0).Value = 4
++
++// Boosters_Hi_change settings for reduction in DSNU and hot pixels
++{0x3518, 0x4444}, //drstlo_lcg_lg(4), drstlo_hcg_lg(4), drstlo_lcg_hg(4), drstlo_hcg_hg(4)
++{0x3540, 0x44}, //drstlo_lcg_lg_3_0(4), lcg_hg_3_0(4)
++{0x3536, 0x9898}, //booster_ref_Vaa rsthi(1), dcghi(1)
++{0x3538, 0x981A}, //booster_ref_vaa rshi(1)
++{0x3530, 0x5F98}, //Boost_ref_Vaa Wellhi(1)
++{0x353C, 0x9A0A}, //Boost_ref_Vaa lfm_dcghi(1)
++{0x3526, 0x9000}, //DWellhi(16)
++{0x352E, 0x90D}, //Dlfm_Dcghi(13),(Dlfm_Txhi_Buffer) = 9
++#endif /* Design_recommended_settings_v5 */
++
++#if 1 /* Pixel_char_recommended_settings_v2 */
++//TXLO @HCG
++{0x3514, 0x555B}, //-0.85V
++{0x3578, 0x555B}, //-0.85V
++//TXLO @LCG
++{0x3514, 0x5B5B}, //-0.85V
++{0x3578, 0x5B5B}, //-0.85V
++//TXHI
++{0x3528, 0xE018}, //2.8V
++//RSHI
++{0x352A, 0x1533},//3.36V
++//DDCGHI
++{0x3528, 0xEB0D}, //Ddcghi(13), txhi(11)
++//DRSTHI, DRSHI
++{0x352A, 0xA27}, //Drsthi (10), Drshi(7)
++#endif /* Pixel_char_recommended_settings_v2 */
++
++#if 1 /* AR0233_Sequencer_LFM_HDR_v6 */
++{0x2512, 0x8000},
++{0x2510, 0x070f},
++{0x2510, 0x1011},
++{0x2510, 0x1216},
++{0x2510, 0xffff},
++{0x2510, 0xffff},
++{0x2510, 0xffff},
++{0x2510, 0xffff},
++{0x2510, 0xffff},
++{0x2510, 0x191b},
++{0x2510, 0x2123},
++{0x2510, 0x2528},
++{0x2510, 0xffff},
++{0x2510, 0x2e4a},
++{0x2510, 0x5874},
++{0x2510, 0x8187},
++{0x2510, 0x8b93},
++{0x2510, 0x9496},
++{0x2510, 0xa1a9},
++{0x2510, 0xaaad},
++{0x2510, 0xb1b5},
++{0x2510, 0xb9bb},
++{0x2510, 0xbdff},
++{0x2510, 0xffff},
++{0x2510, 0xffff},
++{0x2510, 0xffff},
++{0x2510, 0xffff},
++{0x2510, 0xffff},
++{0x2510, 0xffff},
++{0x2510, 0xc003},
++{0x2510, 0x8058},
++{0x2510, 0xa0e0},
++{0x2510, 0x3041},
++{0x2510, 0x3042},
++{0x2510, 0x2000},
++{0x2510, 0x3048},
++{0x2510, 0x3088},
++{0x2510, 0x30a0},
++{0x2510, 0x3090},
++{0x2510, 0xa0c0},
++{0x2510, 0x9008},
++{0x2510, 0x8802},
++{0x2510, 0x20ff},
++{0x2510, 0x20ff},
++{0x2510, 0x20ff},
++{0x2510, 0x20ff},
++{0x2510, 0x20ff},
++{0x2510, 0x9018},
++{0x2510, 0x891a},
++{0x2510, 0x807c},
++{0x2510, 0x20ff},
++{0x2510, 0x895b},
++{0x2510, 0x20ff},
++{0x2510, 0x897b},
++{0x2510, 0x20ff},
++{0x2510, 0x897f},
++{0x2510, 0x20ff},
++{0x2510, 0x7fff},
++{0x2510, 0x7fff},
++{0x2510, 0x7fff},
++{0x2510, 0x7fff},
++{0x2510, 0x20ff},
++{0x2510, 0x7fff},
++{0x2510, 0x7fff},
++{0x2510, 0x7fff},
++{0x2510, 0x20ff},
++{0x2510, 0x7fff},
++{0x2510, 0x7fff},
++{0x2510, 0x7fff},
++{0x2510, 0x20ff},
++{0x2510, 0x7fff},
++{0x2510, 0x7fff},
++{0x2510, 0x7fff},
++{0x2510, 0x3081},
++{0x2510, 0x3082},
++{0x2510, 0xa0c4},
++{0x2510, 0x20ff},
++{0x2510, 0x8058},
++{0x2510, 0x9039},
++{0x2510, 0x20ff},
++{0x2510, 0x907f},
++{0x2510, 0x895b},
++{0x2510, 0x2064},
++{0x2510, 0x891b},
++{0x2510, 0x2010},
++{0x2510, 0x8803},
++{0x2510, 0x7fff},
++{0x2510, 0x7fff},
++{0x2510, 0x7fff},
++{0x2510, 0x20ff},
++{0x2510, 0x906b},
++{0x2510, 0x2064},
++{0x2510, 0x3084},
++{0x2510, 0x2003},
++{0x2510, 0x3044},
++{0x2510, 0x2000},
++{0x2510, 0xa004},
++{0x2510, 0x7fff},
++{0x2510, 0x7fff},
++{0x2510, 0x7fff},
++{0x2510, 0x7fff},
++{0x2510, 0x3108},
++{0x2510, 0x2400},
++{0x2510, 0x2401},
++{0x2510, 0x3244},
++{0x2510, 0x7fff},
++{0x2510, 0x7fff},
++{0x2510, 0x7fff},
++{0x2510, 0x7fff},
++{0x2510, 0x3108},
++{0x2510, 0x2400},
++{0x2510, 0x2401},
++{0x2510, 0x2702},
++{0x2510, 0x3242},
++{0x2510, 0x3108},
++{0x2510, 0x2420},
++{0x2510, 0x2421},
++{0x2510, 0x2703},
++{0x2510, 0x3242},
++{0x2510, 0x3108},
++{0x2510, 0x2420},
++{0x2510, 0x2421},
++{0x2510, 0x2704},
++{0x2510, 0x3242},
++{0x2510, 0x3108},
++{0x2510, 0x2420},
++{0x2510, 0x2421},
++{0x2510, 0x3244},
++{0x2510, 0x7fff},
++{0x2510, 0x7fff},
++{0x2510, 0x7fff},
++{0x2510, 0x7fff},
++{0x2510, 0x7fff},
++{0x2510, 0x3108},
++{0x2510, 0x2402},
++{0x2510, 0x2403},
++{0x2510, 0x3244},
++{0x2510, 0x7fff},
++{0x2510, 0x7fff},
++{0x2510, 0x7fff},
++{0x2510, 0x7fff},
++{0x2510, 0x3108},
++{0x2510, 0x2741},
++{0x2510, 0x2429},
++{0x2510, 0x2740},
++{0x2510, 0x242a},
++{0x2510, 0x3244},
++{0x2510, 0x7fff},
++{0x2510, 0x7fff},
++{0x2510, 0x3108},
++{0x2510, 0x2404},
++{0x2510, 0x2779},
++{0x2510, 0x242c},
++{0x2510, 0x2781},
++{0x2510, 0x242d},
++{0x2510, 0x3244},
++{0x2510, 0x7fff},
++{0x2510, 0x7fff},
++{0x2510, 0x7fff},
++{0x2510, 0x7fff},
++{0x2510, 0x7fff},
++{0x2510, 0x3108},
++{0x2510, 0x2703},
++{0x2510, 0x2432},
++{0x2510, 0x2703},
++{0x2510, 0x3242},
++{0x2510, 0x3108},
++{0x2510, 0x27bb},
++{0x2510, 0x2430},
++{0x2510, 0x27bb},
++{0x2510, 0x3242},
++{0x2510, 0x3108},
++{0x2510, 0x2702},
++{0x2510, 0x2431},
++{0x2510, 0x2702},
++{0x2510, 0x3242},
++{0x2510, 0x3108},
++{0x2510, 0x27c3},
++{0x2510, 0x2430},
++{0x2510, 0x3244},
++{0x2510, 0x7fff},
++{0x2510, 0x7fff},
++{0x2510, 0x7fff},
++{0x2510, 0x7fff},
++{0x2510, 0x7fff},
++{0x2510, 0xb800},
++{0x2510, 0x8058},
++{0x2510, 0xa005},
++{0x2510, 0x3101},
++{0x2510, 0x3041},
++{0x2510, 0x3104},
++{0x2510, 0xb035},
++{0x2510, 0xb075},
++{0x2510, 0x30c1},
++{0x2510, 0x3102},
++{0x2510, 0x3041},
++{0x2510, 0x3202},
++{0x2510, 0xb848},
++{0x2510, 0xb84c},
++{0x2510, 0x2200},
++{0x2510, 0x3141},
++{0x2510, 0x3042},
++{0x2510, 0xb377},
++{0x2510, 0x8843},
++{0x2510, 0x916f},
++{0x2510, 0x3110},
++{0x2510, 0x3042},
++{0x2510, 0xb84e},
++{0x2510, 0xf905},
++{0x2510, 0xf907},
++{0x2510, 0x2200},
++{0x2510, 0x885b},
++{0x2510, 0xa898},
++{0x2510, 0xa8d8},
++{0x2510, 0xf8e8},
++{0x2510, 0x80dc},
++{0x2510, 0x9007},
++{0x2510, 0x916f},
++{0x2510, 0x2206},
++{0x2510, 0xb808},
++{0x2510, 0xc800},
++{0x2510, 0xe809},
++{0x2510, 0x88df},
++{0x2510, 0xf8a8},
++{0x2510, 0xf888},
++{0x2510, 0x2203},
++{0x2510, 0xb07b},
++{0x2510, 0x2000},
++{0x2510, 0x80cc},
++{0x2510, 0x808c},
++{0x2510, 0x220b},
++{0x2510, 0xb06a},
++{0x2510, 0x88cf},
++{0x2510, 0x888f},
++{0x2510, 0x2224},
++{0x2510, 0xb04a},
++{0x2510, 0x2218},
++{0x2510, 0x2116},
++{0x2510, 0x902f},
++{0x2510, 0xb04b},
++{0x2510, 0xf880},
++{0x2510, 0x2217},
++{0x2510, 0x2204},
++{0x2510, 0xb043},
++{0x2510, 0xa8c9},
++{0x2510, 0x31c1},
++{0x2510, 0x80ac},
++{0x2510, 0x2205},
++{0x2510, 0x916f},
++{0x2510, 0x2104},
++{0x2510, 0x88af},
++{0x2510, 0x2440},
++{0x2510, 0xf110},
++{0x2510, 0xf804},
++{0x2510, 0x2000},
++{0x2510, 0x8088},
++{0x2510, 0x3002},
++{0x2510, 0xb838},
++{0x2510, 0xa8c8},
++{0x2510, 0xb04b},
++{0x2510, 0x2442},
++{0x2510, 0x3210},
++{0x2510, 0x2206},
++{0x2510, 0x888b},
++{0x2510, 0x2441},
++{0x2510, 0x3202},
++{0x2510, 0xf108},
++{0x2510, 0xf0d7},
++{0x2510, 0xb830},
++{0x2510, 0xf880},
++{0x2510, 0xc801},
++{0x2510, 0x30c2},
++{0x2510, 0xe80c},
++{0x2510, 0x2201},
++{0x2510, 0xb04a},
++{0x2510, 0x222d},
++{0x2510, 0x3241},
++{0x2510, 0x2207},
++{0x2510, 0x902f},
++{0x2510, 0x2214},
++{0x2510, 0x2204},
++{0x2510, 0xb042},
++{0x2510, 0xa9a1},
++{0x2510, 0x8008},
++{0x2510, 0xb093},
++{0x2510, 0x31c1},
++{0x2510, 0x916b},
++{0x2510, 0x2009},
++{0x2510, 0x8803},
++{0x2510, 0xa044},
++{0x2510, 0x3044},
++{0x2510, 0x2000},
++{0x2510, 0xa004},
++{0x2510, 0x7fff},
++{0x2510, 0x7fff},
++{0x2510, 0x7fff},
++{0x2510, 0x7fff},
++{0x2510, 0xa084},
++{0x2510, 0x30d0},
++{0x2510, 0x8078},
++{0x2510, 0x3141},
++{0x2510, 0x3041},
++{0x2510, 0x3042},
++{0x2510, 0x2000},
++{0x2510, 0x3142},
++{0x2510, 0x3041},
++{0x2510, 0x2000},
++{0x2510, 0x3110},
++{0x2510, 0x3041},
++{0x2510, 0x2000},
++{0x2510, 0x3120},
++{0x2510, 0x3041},
++{0x2510, 0x2000},
++{0x2510, 0x3144},
++{0x2510, 0x3041},
++{0x2510, 0x2000},
++{0x2510, 0x3148},
++{0x2510, 0x3041},
++{0x2510, 0x2000},
++{0x2510, 0x2206},
++{0x2510, 0x881b},
++{0x2510, 0x887b},
++{0x2510, 0xa08c},
++{0x2510, 0x221f},
++{0x2510, 0xa084},
++{0x2510, 0x2440},
++{0x2510, 0xb095},
++{0x2510, 0xf110},
++{0x2510, 0xf864},
++{0x2510, 0xf90d},
++{0x2510, 0x3084},
++{0x2510, 0x3090},
++{0x2510, 0x3088},
++{0x2510, 0x8058},
++{0x2510, 0x3001},
++{0x2510, 0x2442},
++{0x2510, 0x3220},
++{0x2510, 0x2002},
++{0x2510, 0x8863},
++{0x2510, 0x2004},
++{0x2510, 0x8803},
++{0x2510, 0x2441},
++{0x2510, 0x30c2},
++{0x2510, 0xa9a0},
++{0x2510, 0xb094},
++{0x2510, 0x2201},
++{0x2510, 0xa0c4},
++{0x2510, 0x3044},
++{0x2510, 0x2000},
++{0x2510, 0xa004},
++{0x2510, 0x7fff},
++{0x2510, 0x7fff},
++{0x2510, 0x7fff},
++{0x2510, 0xb980},
++{0x2510, 0x8108},
++{0x2510, 0xa105},
++{0x2510, 0x30c1},
++{0x2510, 0x2000},
++{0x2510, 0x3101},
++{0x2510, 0x3041},
++{0x2510, 0x3104},
++{0x2510, 0x3102},
++{0x2510, 0x3041},
++{0x2510, 0xf860},
++{0x2510, 0xb095},
++{0x2510, 0x3141},
++{0x2510, 0x3042},
++{0x2510, 0xb9f8},
++{0x2510, 0xb9fc},
++{0x2510, 0x8803},
++{0x2510, 0x916f},
++{0x2510, 0x3110},
++{0x2510, 0x3042},
++{0x2510, 0xb9fe},
++{0x2510, 0xf905},
++{0x2510, 0xf907},
++{0x2510, 0x3202},
++{0x2510, 0x880b},
++{0x2510, 0xa888},
++{0x2510, 0xa8c8},
++{0x2510, 0xb397},
++{0x2510, 0xf8e8},
++{0x2510, 0x818c},
++{0x2510, 0x9007},
++{0x2510, 0x916f},
++{0x2510, 0x2204},
++{0x2510, 0xb137},
++{0x2510, 0xb9b8},
++{0x2510, 0xc801},
++{0x2510, 0xe809},
++{0x2510, 0xb177},
++{0x2510, 0x888f},
++{0x2510, 0xf8a8},
++{0x2510, 0xf888},
++{0x2510, 0x2203},
++{0x2510, 0xb07b},
++{0x2510, 0x2000},
++{0x2510, 0x818c},
++{0x2510, 0x808c},
++{0x2510, 0x220b},
++{0x2510, 0xb06a},
++{0x2510, 0x888f},
++{0x2510, 0x888f},
++{0x2510, 0x2224},
++{0x2510, 0xb04a},
++{0x2510, 0x2218},
++{0x2510, 0x2115},
++{0x2510, 0xb04b},
++{0x2510, 0x902f},
++{0x2510, 0xf880},
++{0x2510, 0x2217},
++{0x2510, 0x2204},
++{0x2510, 0xb043},
++{0x2510, 0xa8d9},
++{0x2510, 0x31c1},
++{0x2510, 0x80cc},
++{0x2510, 0x2103},
++{0x2510, 0x916f},
++{0x2510, 0x2106},
++{0x2510, 0x88cf},
++{0x2510, 0x2440},
++{0x2510, 0xf110},
++{0x2510, 0xf804},
++{0x2510, 0x2000},
++{0x2510, 0x8088},
++{0x2510, 0x3002},
++{0x2510, 0xb988},
++{0x2510, 0xa8d8},
++{0x2510, 0xb04b},
++{0x2510, 0x2442},
++{0x2510, 0x3210},
++{0x2510, 0x2206},
++{0x2510, 0x888b},
++{0x2510, 0x2441},
++{0x2510, 0x3202},
++{0x2510, 0xf108},
++{0x2510, 0xf0d7},
++{0x2510, 0xb980},
++{0x2510, 0xf880},
++{0x2510, 0xc800},
++{0x2510, 0x30c2},
++{0x2510, 0xe80c},
++{0x2510, 0x2201},
++{0x2510, 0xb04a},
++{0x2510, 0x2230},
++{0x2510, 0x3241},
++{0x2510, 0x902f},
++{0x2510, 0x221b},
++{0x2510, 0x2204},
++{0x2510, 0xb042},
++{0x2510, 0xa9a1},
++{0x2510, 0x8058},
++{0x2510, 0xb093},
++{0x2510, 0x31c1},
++{0x2510, 0x916b},
++{0x2510, 0x2009},
++{0x2510, 0x8803},
++{0x2510, 0xa144},
++{0x2510, 0x3044},
++{0x2510, 0x2000},
++{0x2510, 0xa004},
++{0x2510, 0xb800},
++{0x2510, 0x7fff},
++{0x2510, 0x7fff},
++{0x2510, 0x7fff},
++{0x2510, 0x8078},
++{0x2510, 0x30d0},
++{0x2510, 0xa184},
++{0x2510, 0xb980},
++{0x2510, 0x3141},
++{0x2510, 0x3041},
++{0x2510, 0x3042},
++{0x2510, 0x2000},
++{0x2510, 0x3142},
++{0x2510, 0x3041},
++{0x2510, 0x2000},
++{0x2510, 0x3110},
++{0x2510, 0x3041},
++{0x2510, 0x2000},
++{0x2510, 0x3120},
++{0x2510, 0x3041},
++{0x2510, 0x2000},
++{0x2510, 0x2206},
++{0x2510, 0x881b},
++{0x2510, 0x887b},
++{0x2510, 0x2440},
++{0x2510, 0xb095},
++{0x2510, 0xf110},
++{0x2510, 0xf864},
++{0x2510, 0xf90d},
++{0x2510, 0x30a0},
++{0x2510, 0x3090},
++{0x2510, 0x3088},
++{0x2510, 0x8058},
++{0x2510, 0x3001},
++{0x2510, 0x2202},
++{0x2510, 0x2442},
++{0x2510, 0x3220},
++{0x2510, 0x2002},
++{0x2510, 0x885b},
++{0x2510, 0x2441},
++{0x2510, 0x30c2},
++{0x2510, 0x8018},
++{0x2510, 0x2000},
++{0x2510, 0x881b},
++{0x2510, 0x2008},
++{0x2510, 0x8000},
++{0x2510, 0xa9a0},
++{0x2510, 0xb094},
++{0x2510, 0x2201},
++{0x2510, 0x8803},
++{0x2510, 0xa1c4},
++{0x2510, 0x3044},
++{0x2510, 0xb800},
++{0x2510, 0xa004},
++{0x2510, 0x7fff},
++{0x2510, 0x7fff},
++{0x2510, 0x9818},
++{0x2510, 0x3101},
++{0x2510, 0x3041},
++{0x2510, 0x2000},
++{0x2510, 0x3102},
++{0x2510, 0x3041},
++{0x2510, 0x8008},
++{0x2510, 0x2002},
++{0x2510, 0x8028},
++{0x2510, 0x2205},
++{0x2510, 0x880b},
++{0x2510, 0x882b},
++{0x2510, 0x213e},
++{0x2510, 0x8008},
++{0x2510, 0x2202},
++{0x2510, 0x8000},
++{0x2510, 0x2202},
++{0x2510, 0xa044},
++{0x2510, 0x3044},
++{0x2510, 0x8803},
++{0x2510, 0x9800},
++{0x2510, 0xa004},
++{0x2510, 0x7fff},
++{0x2510, 0x7fff},
++{0x2510, 0x2440},
++{0x2510, 0xb095},
++{0x2510, 0xf110},
++{0x2510, 0xf864},
++{0x2510, 0xf90d},
++{0x2510, 0x2442},
++{0x2510, 0x3220},
++{0x2510, 0x2007},
++{0x2510, 0x2441},
++{0x2510, 0x30c2},
++{0x2510, 0xa9a0},
++{0x2510, 0xb094},
++{0x2510, 0x7fff},
++{0x2510, 0x7fff},
++{0x2510, 0x7fff},
++{0x2510, 0x7fff},
++{0x2510, 0xb980},
++{0x2510, 0x3101},
++{0x2510, 0x3041},
++{0x2510, 0x2000},
++{0x2510, 0x3102},
++{0x2510, 0x3041},
++{0x2510, 0x8028},
++{0x2510, 0x220a},
++{0x2510, 0x880b},
++{0x2510, 0x882b},
++{0x2510, 0x2440},
++{0x2510, 0xb095},
++{0x2510, 0xf110},
++{0x2510, 0xf864},
++{0x2510, 0xf90d},
++{0x2510, 0x8008},
++{0x2510, 0x3001},
++{0x2510, 0x2202},
++{0x2510, 0x2442},
++{0x2510, 0x8823},
++{0x2510, 0x3220},
++{0x2510, 0x2000},
++{0x2510, 0x8803},
++{0x2510, 0x2441},
++{0x2510, 0x30c2},
++{0x2510, 0xa9a0},
++{0x2510, 0xb094},
++{0x2510, 0x2201},
++{0x2510, 0x7fff},
++{0x2510, 0x7fff},
++{0x2510, 0x7fff},
++{0x2510, 0x7fff},
++{0x2510, 0x2000},
++{0x2510, 0x3244},
++{0x2510, 0x7fff},
++{0x2510, 0x7fff},
++{0x2510, 0x2400},
++{0x2510, 0x2751},
++{0x2510, 0x2423},
++{0x2510, 0x2750},
++{0x2510, 0x2421},
++{0x2510, 0x3244},
++{0x2510, 0x7fff},
++{0x2510, 0x7fff},
++{0x2510, 0x2749},
++{0x2510, 0x2422},
++{0x2510, 0x2749},
++{0x2510, 0x2423},
++{0x2510, 0x2709},
++{0x2510, 0x2420},
++{0x2510, 0x2729},
++{0x2510, 0x2423},
++{0x2510, 0x3242},
++{0x2510, 0x3108},
++{0x2510, 0x2722},
++{0x2510, 0x2422},
++{0x2510, 0x2769},
++{0x2510, 0x2421},
++{0x2510, 0x2702},
++{0x2510, 0x2421},
++{0x2510, 0x3242},
++{0x2510, 0x3108},
++{0x2510, 0x276a},
++{0x2510, 0x2420},
++{0x2510, 0x276a},
++{0x2510, 0x2421},
++{0x2510, 0x2703},
++{0x2510, 0x2420},
++{0x2510, 0x2703},
++{0x2510, 0x2421},
++{0x2510, 0x3242},
++{0x2510, 0x3108},
++{0x2510, 0x276b},
++{0x2510, 0x2420},
++{0x2510, 0x276b},
++{0x2510, 0x2421},
++{0x2510, 0x2704},
++{0x2510, 0x2420},
++{0x2510, 0x2704},
++{0x2510, 0x2421},
++{0x2510, 0x3242},
++{0x2510, 0x3108},
++{0x2510, 0x276c},
++{0x2510, 0x2420},
++{0x2510, 0x276c},
++{0x2510, 0x2421},
++{0x2510, 0x7fff},
++{0x2510, 0x7fff},
++{0x2510, 0x2759},
++{0x2510, 0x2422},
++{0x2510, 0x2758},
++{0x2510, 0x2420},
++{0x2510, 0x2403},
++{0x2510, 0x2712},
++{0x2510, 0x3242},
++{0x2510, 0x3108},
++{0x2510, 0x2422},
++{0x2510, 0x271a},
++{0x2510, 0x3242},
++{0x2510, 0x3108},
++{0x2510, 0x2420},
++{0x2510, 0x2702},
++{0x2510, 0x2423},
++{0x2510, 0x2703},
++{0x2510, 0x3242},
++{0x2510, 0x3108},
++{0x2510, 0x2420},
++{0x2510, 0x2703},
++{0x2510, 0x2423},
++{0x2510, 0x2704},
++{0x2510, 0x3242},
++{0x2510, 0x3108},
++{0x2510, 0x2420},
++{0x2510, 0x2704},
++{0x2510, 0x2423},
++{0x2510, 0x7fff},
++{0x2510, 0x7fff},
++{0x2510, 0x7fff},
++{0x2510, 0x7fff},
++{0x2510, 0x7fff},
++{0x2510, 0x2400},
++{0x2510, 0x7fff},
++{0x2510, 0x7fff},
++{0x2510, 0x7fff},
++{0x2510, 0xc023},
++{0x2510, 0x2402},
++{0x2510, 0x2405},
++{0x2510, 0x2789},
++{0x2510, 0x242e},
++{0x2510, 0x2788},
++{0x2510, 0x242f},
++{0x2510, 0x3244},
++{0x2510, 0x7fff},
++{0x2510, 0x7fff},
++{0x2510, 0x7fff},
++{0x2510, 0x7fff},
++{0x2510, 0xc027},
++{0x2510, 0x2400},
++{0x2510, 0x2406},
++{0x2510, 0xc063},
++{0x2510, 0x2402},
++{0x2510, 0x2751},
++{0x2510, 0x2423},
++{0x2510, 0x2750},
++{0x2510, 0x2421},
++{0x2510, 0xc003},
++{0x2510, 0x3244},
++{0x2510, 0x7fff},
++{0x2510, 0x7fff},
++{0x2510, 0x7fff},
++{0x2510, 0x7fff},
++{0x2510, 0x7fff},
++{0x2510, 0xc021},
++{0x2510, 0x2400},
++{0x2510, 0x2405},
++{0x2510, 0xc062},
++{0x2510, 0x2400},
++{0x2510, 0xc063},
++{0x2510, 0x2751},
++{0x2510, 0x2423},
++{0x2510, 0x2750},
++{0x2510, 0x2421},
++{0x2510, 0xc003},
++{0x2510, 0x3244},
++{0x2510, 0x7fff},
++{0x2510, 0x7fff},
++{0x2510, 0x7fff},
++{0x2510, 0x7fff},
++{0x2510, 0xc0e3},
++{0x2510, 0x2400},
++{0x2510, 0x27b1},
++{0x2510, 0x2425},
++{0x2510, 0xc063},
++{0x2510, 0x2420},
++{0x2510, 0x2751},
++{0x2510, 0x2423},
++{0x2510, 0x2750},
++{0x2510, 0x2421},
++{0x2510, 0xc003},
++{0x2510, 0x3244},
++{0x2510, 0x7fff},
++{0x2510, 0x7fff},
++{0x2510, 0x7fff},
++{0x2510, 0x7fff},
++{0x2510, 0x2404},
++{0x2510, 0x2779},
++{0x2510, 0x242c},
++{0x2510, 0x2781},
++{0x2510, 0x242d},
++{0x2510, 0x3244},
++{0x2510, 0x7fff},
++{0x2510, 0x7fff},
++{0x2510, 0x2791},
++{0x2510, 0x2430},
++{0x2510, 0x2799},
++{0x2510, 0x2428},
++{0x2510, 0x3244},
++{0x2510, 0x7fff},
++{0x2510, 0x7fff},
++{0x2510, 0x7fff},
++{0x2510, 0x27a1},
++{0x2510, 0x2430},
++{0x2510, 0x27a9},
++{0x2510, 0x2428},
++{0x2510, 0x3244},
++{0x2510, 0x7fff},
++{0x2510, 0x7fff},
++{0x2510, 0x7fff},
++{0x2510, 0xffff},
++{0x2510, 0xffff},
++{0x2510, 0xffff},
++{0x2510, 0xffff},
++{0x2510, 0xffff},
++{0x2510, 0xffff},
++{0x2510, 0xffff},
++{0x2510, 0xffff},
++{0x2510, 0xffff},
++{0x2510, 0xffff},
++{0x2510, 0xffff},
++{0x2510, 0xffff},
++{0x2510, 0xffff},
++{0x2510, 0xffff},
++{0x2510, 0xffff},
++{0x2510, 0xffff},
++{0x2510, 0xffff},
++{0x2510, 0xffff},
++{0x2510, 0xffff},
++{0x2510, 0xffff},
++{0x2510, 0xffff},
++{0x2510, 0xffff},
++{0x2510, 0xffff},
++{0x2510, 0xffff},
++{0x2510, 0xffff},
++{0x2510, 0xffff},
++{0x2510, 0xffff},
++{0x2510, 0xffff},
++{0x2510, 0xffff},
++{0x2510, 0xffff},
++{0x2510, 0xffff},
++{0x2510, 0xffff},
++{0x2510, 0xffff},
++{0x2510, 0xffff},
++{0x2510, 0xffff},
++{0x2510, 0xffff},
++{0x2510, 0xffff},
++{0x2510, 0xffff},
++{0x2510, 0xffff},
++{0x2510, 0xffff},
++{0x2510, 0xffff},
++{0x2510, 0xffff},
++{0x2510, 0xffff},
++{0x2510, 0xffff},
++{0x2510, 0xffff},
++{0x2510, 0xffff},
++{0x2510, 0xffff},
++{0x2510, 0xffff},
++{0x2510, 0xffff},
++{0x2510, 0xffff},
++{0x2510, 0xffff},
++{0x2510, 0xffff},
++{0x2510, 0xffff},
++{0x2510, 0xffff},
++{0x2510, 0xffff},
++{0x2510, 0xffff},
++{0x2510, 0xffff},
++{0x2510, 0xffff},
++{0x2510, 0xffff},
++{0x2510, 0xffff},
++{0x2510, 0xffff},
++{0x2510, 0xffff},
++{0x2510, 0xffff},
++{0x2510, 0xffff},
++{0x2510, 0xffff},
++{0x2510, 0xffff},
++{0x2510, 0xffff},
++{0x2510, 0xffff},
++{0x2510, 0xffff},
++{0x2510, 0xffff},
++{0x2510, 0xffff},
++{0x2510, 0xffff},
++{0x2510, 0xffff},
++{0x2510, 0xffff},
++{0x2510, 0xffff},
++{0x2510, 0xffff},
++{0x2510, 0xffff},
++{0x2510, 0xffff},
++{0x2510, 0xffff},
++{0x2510, 0xffff},
++{0x2510, 0xffff},
++{0x2510, 0xffff},
++{0x2510, 0xffff},
++{0x2510, 0xffff},
++{0x2510, 0xffff},
++{0x2510, 0xffff},
++{0x2510, 0xffff},
++{0x2510, 0xffff},
++{0x2510, 0xffff},
++{0x2510, 0xffff},
++{0x2510, 0xffff},
++{0x2510, 0xffff},
++{0x2510, 0xffff},
++{0x2510, 0xffff},
++{0x2510, 0xffff},
++{0x2510, 0xffff},
++{0x2510, 0xffff},
++{0x2510, 0xffff},
++{0x2510, 0xffff},
++{0x2510, 0xffff},
++{0x2510, 0xffff},
++{0x2510, 0xffff},
++{0x2510, 0xffff},
++{0x2510, 0xffff},
++{0x2510, 0xffff},
++{0x2510, 0xffff},
++{0x2510, 0xffff},
++{0x2510, 0xffff},
++{0x2510, 0xffff},
++{0x2510, 0xffff},
++{0x2510, 0xffff},
++{0x2510, 0xffff},
++{0x2510, 0xffff},
++{0x2510, 0xffff},
++{0x2510, 0xffff},
++{0x2510, 0xffff},
++{0x2510, 0xffff},
++{0x2510, 0xffff},
++{0x2510, 0xffff},
++{0x2510, 0xffff},
++{0x2510, 0xffff},
++{0x2510, 0xffff},
++{0x2510, 0xffff},
++{0x2510, 0xffff},
++{0x2510, 0xffff},
++{0x2510, 0xffff},
++{0x2510, 0xffff},
++{0x2510, 0xffff},
++{0x2510, 0xffff},
++{0x2510, 0xffff},
++{0x2510, 0xffff},
++{0x2510, 0xffff},
++{0x2510, 0xffff},
++{0x2510, 0xffff},
++{0x2510, 0xffff},
++{0x2510, 0xffff},
++{0x2510, 0xffff},
++{0x2510, 0xffff},
++{0x2510, 0xffff},
++{0x2510, 0xffff},
++{0x2510, 0xffff},
++{0x2510, 0xffff},
++{0x2510, 0xffff},
++{0x2510, 0xffff},
++{0x2510, 0xffff},
++{0x2510, 0xffff},
++{0x2510, 0xffff},
++{0x2510, 0xffff},
++{0x2510, 0xffff},
++{0x2510, 0xffff},
++{0x2510, 0xffff},
++{0x2510, 0xffff},
++{0x2510, 0xffff},
++{0x2510, 0xffff},
++{0x2510, 0xffff},
++{0x2510, 0xffff},
++{0x2510, 0xffff},
++{0x2510, 0xffff},
++{0x2510, 0xffff},
++{0x2510, 0xffff},
++{0x2510, 0xffff},
++{0x2510, 0xffff},
++{0x2510, 0xffff},
++{0x2510, 0xffff},
++{0x2510, 0xffff},
++{0x2510, 0xffff},
++{0x2510, 0xffff},
++{0x2510, 0xffff},
++{0x2510, 0xffff},
++{0x2510, 0xffff},
++{0x2510, 0xffff},
++{0x2510, 0xffff},
++{0x2510, 0xffff},
++{0x2510, 0xffff},
++{0x2510, 0xffff},
++{0x2510, 0xffff},
++{0x2510, 0xffff},
++{0x2510, 0xffff},
++{0x2510, 0xffff},
++{0x2510, 0xffff},
++{0x2510, 0xffff},
++{0x2510, 0xffff},
++{0x2510, 0xffff},
++{0x2510, 0xffff},
++{0x2510, 0xffff},
++{0x2510, 0xffff},
++{0x2510, 0xffff},
++{0x2510, 0xffff},
++{0x2510, 0xffff},
++{0x2510, 0xffff},
++{0x2510, 0xffff},
++{0x2510, 0xffff},
++{0x2510, 0xffff},
++{0x2510, 0xffff},
++{0x2510, 0xffff},
++{0x2510, 0xffff},
++{0x2510, 0xffff},
++{0x2510, 0xffff},
++{0x2510, 0xffff},
++{0x2510, 0xffff},
++{0x2510, 0xffff},
++{0x2510, 0xffff},
++{0x2510, 0xffff},
++{0x2510, 0xffff},
++{0x2510, 0xffff},
++{0x2510, 0xffff},
++{0x2510, 0xffff},
++{0x2510, 0xffff},
++{0x2510, 0xffff},
++{0x2510, 0xffff},
++{0x2510, 0xffff},
++{0x2510, 0xffff},
++{0x2510, 0xffff},
++{0x2510, 0xffff},
++{0x2510, 0xffff},
++{0x2510, 0xffff},
++{0x2510, 0xffff},
++{0x2510, 0xffff},
++{0x2510, 0xffff},
++{0x2510, 0xffff},
++{0x2510, 0xffff},
++{0x2510, 0xffff},
++{0x2510, 0xffff},
++{0x2510, 0xffff},
++{0x2510, 0xffff},
++{0x2510, 0xffff},
++{0x2510, 0xffff},
++{0x2510, 0xffff},
++{0x2510, 0xffff},
++{0x2510, 0xffff},
++{0x2510, 0xffff},
++{0x2510, 0xffff},
++{0x2510, 0xffff},
++{0x2510, 0xffff},
++{0x2510, 0xffff},
++{0x2510, 0xffff},
++{0x2510, 0xffff},
++{0x2510, 0xffff},
++{0x2510, 0xffff},
++{0x2510, 0xffff},
++{0x2510, 0xffff},
++{0x2510, 0xffff},
++{0x2510, 0xffff},
++{0x2510, 0xffff},
++{0x2510, 0xffff},
++{0x2510, 0xffff},
++{0x2510, 0xffff},
++{0x2510, 0xffff},
++{0x2510, 0xffff},
++{0x2510, 0xffff},
++{0x2510, 0xffff},
++{0x2510, 0xffff},
++{0x2510, 0xffff},
++{0x2510, 0xffff},
++{0x2510, 0xffff},
++{0x2510, 0xffff},
++{0x2510, 0xffff},
++{0x2510, 0xffff},
++{0x2510, 0xffff},
++{AR0233_DELAY, 100},
++#endif /* AR0233_Sequencer_LFM_HDR_v6 */
++#endif /* Sequencer Settings */
++
++{0x3082, 0x8}, //0x3082 = 2, 3 exposures
++{0x3110, 0x11}, //Set bypass pix comb for HDR,Pre_hdr_gain_enable_07Jul
++{0x30BA, 0x1122}, //Num_exp_max
++{0x3012, 0x144}, //Integration_time
++
++#if 1 /* Serial 12-bit Timing Setup_108Mhz */
++/* PCLK=24Mhz/PRE_PLL_CLK_DIV *PLL_MULTIPLIER /P1 /P4 */
++/* PCLK=24Mhz/2 *54/1/6= 108Mhz - TI serializers */
++{0x3030, 54}, //PLL_MULTIPLIER ; 0x3030 [11:0]
++{0x302E, 2}, //PRE_PLL_CLK_DIV ; 0x302E [5:0]
++{0x302C, 1}, //P1 divider (vt_sys_clk_div)
++{0x302A, 6}, //P2 divider (vt_pix_clk_div); 0x302A [4:0]
++{0x3038, 2}, //P3 divider (op_sys_clk_div); 0x3038 [4:0]
++{0x3036, 6}, //P4 divider (op_word_clk_div); 0x3036 [4:0]
++{0x31DC, 0x1FB0},
++#endif /* Serial 12-bit Timing Setup_108Mhz */
++
++#if 1 /* MIPI 4 Lane 12BITS 30FPS_ext24_LIM */
++{0x31AE, 0x204}, //MIPI enable, 4 lanes
++{0x31B0, 0x4B}, //frame_preamble
++{0x31B2, 0x33}, //line_preamble
++{0x31B4, 0x1185}, //mipi_timing_0
++{0x31B6, 0x110B}, //mipi_timing_1
++{0x31B8, 0x4047}, //mipi_timing_2
++{0x31BA, 0x105}, //mipi_timing_3
++{0x31BC, 0x704}, //mipi_timing_4
++#endif /* MIPI 4 Lane 12BITS 30FPS_ext24_LIM */
++
++#if 1 /* MIPI_DT_bit12 */
++{0x3342, 0x122C}, // MIPI_F1_PDT_EDT
++{0x3346, 0x122C}, // MIPI_F2_PDT_EDT
++{0x334A, 0x122C}, // MIPI_F3_PDT_EDT
++{0x334E, 0x122C}, // MIPI_F4_PDT_EDT
++#endif /* MIPI_DT_bit12 */
++
++/* resolution */
++{0x3004, AR0233_X_START}, // X_ADDR_START_
++{0x3008, AR0233_X_END}, // X_ADDR_END_
++{0x3002, AR0233_Y_START}, // Y_ADDR_START_
++{0x3006, AR0233_Y_END}, // Y_ADDR_END_
++
++#ifdef AR0233_EMBEDDED_LINE
++{0x3040, 0x0000}, //Embedded stat2 and data2 rows
++{0x3064, 0x0180}, //Enable embedded data and stat
++#else
++{0x3064, 0x0}, //Disable embedded data and stat
++#endif
++
++// FPS = 108MHz / reg0x300A / reg0x300C * (DES_REF_XTAL/24MHz)
++{0x300A, AR0233_SENSOR_HEIGHT + 100}, // Frame_length_Lines
++{0x300C, AR0233_SENSOR_WIDTH + 400}, // Line_length_pck
++//{0x300C, 0x960}, //Line_lenth_pck_FRN AEF
++//{0x300A, 0x5DC}, //FLL
++
++#if 1 /* Gain_3.28x */
++{0x3022, 0x01}, // GROUPED_PARAMETER_HOLD_
++{0x3362, 0x000F}, // DC_GAIN
++{0x3366, 0x1111},
++{0x336A, 0x0000},
++{0x3022, 0x00}, // GROUPED_PARAMETER_HOLD_
++#endif /* Gain_3.28x */
++
++{0x31D0, 0x1}, // Companding
++{0x31AC, 0x140C}, // DLO20 to 12output
++
++#if 1 /* MEC DLO default */
++{0x3D00, 0x6F73}, // control
++{0x3D02, 0x0033},
++{0x3364, 0x068C}, // dcg_trim = 13.1
++{0x3D28, 0x09C4}, // weights
++{0x3D2A, 0x0DAC},
++{0x3D30, 0x0FFF},
++{0x3D32, 0x0FFF},
++{0x3D34, 0x09C4},
++{0x3D36, 0x0DAC},
++{0x3D3C, 0x0FFF},
++{0x3D3E, 0x0FFF},
++{0x3D40, 0x09C4},
++{0x3D42, 0x0DAC},
++{0x3D48, 0x0FFF},
++{0x3D4A, 0x0FFF},
++{0x3D4C, 0x0DAC},
++{0x3D64, 0x0DAC}, // clip
++{0x3D66, 0x0DAC},
++{0x3D68, 0x0DAC},
++{0x3D6A, 0x0DAC},
++{0x3D6C, 0x0DAC},
++{0x3D6E, 0x0DAC},
++{0x3D70, 0x0DAC},
++{0x3D72, 0x0DAC},
++{0x3D74, 0x0DAC},
++{0x3D76, 0x0DAC},
++{0x3D78, 0x0DAC},
++{0x3D7A, 0x0DAC},
++{0x3D7C, 0x0DAC},
++{0x3D7E, 0x0DAC},
++{0x3D80, 0x0DAC},
++{0x3D82, 0x0DAC},
++{0x3D84, 0x0DAC}, // motion_clip
++{0x3D86, 0x0DAC},
++{0x3D88, 0x0000},
++{0x3D8A, 0x0DAC},
++{0x3D8C, 0x0DAC},
++{0x3D8E, 0x0000},
++{0x3DB4, 0x0001}, // motion_q
++{0x3DB6, 0x000E},
++{0x3DB8, 0x0080},
++{0x3DBA, 0x3920}, // t?_s12_k
++{0x3DBC, 0x3920},
++{0x3DBE, 0x3920},
++{0x3DC0, 0x0080}, // wb_gain
++{0x3DC2, 0x0080},
++{0x3DC4, 0x0080},
++{0x3DC6, 0x0080},
++{0x3DC8, 0x0000}, // color_th
++{0x3DCA, 0x0000},
++{0x3DCC, 0x0000},
++{0x3DCE, 0x0000},
++{0x3DD0, 0x0000},
++{0x3DD2, 0x0000},
++{0x3DD4, 0x0000},
++{0x3DD6, 0x0000},
++{0x3DD8, 0x0000},
++{0x3DDA, 0x0000},
++{0x3DDC, 0x0000},
++{0x3DDE, 0x0000},
++{0x3DE0, 0x0000},
++{0x3290, 0x1B58}, // t3_barrier
++{0x3292, 0x1B58},
++{0x3294, 0x1B58},
++{0x3296, 0x1B58},
++{0x3298, 0x2904}, // t4_barrier
++{0x329A, 0x2904},
++{0x329C, 0x2904},
++{0x329E, 0x2904},
++{0x32A0, 0x0000},
++{0x32A2, 0x0000},
++{0x32A4, 0x0000},
++{0x32A6, 0x0000},
++{0x3D08, 0x0000}, // dtr_bound
++{0x3D0A, 0x0000},
++{0x3D0C, 0x0000},
++{0x3D0E, 0x0000},
++{0x3D10, 0x0000}, // vis_bound
++{0x3D12, 0x0798},
++{0x3D14, 0x001E},
++{0x3D16, 0x045E},
++#endif /* MEC DLO default */
++
++#if 1 /* Enable_trigger_input */
++{0x340A, 0x0070}, // GPIO_CONTROL1: GPIO1 is trigger
++{0x340C, 0x0080}, // GPIO_CONTROL2: GPIO1 is trigger
++{0x30CE, 0x0120}, // TRIGGER_MODE
++//{0x30DC, 0x0120}, // TRIGGER_DELAY
++{0x301A, 0x0118}, // GPI pins enable
++#endif /* Enable_trigger_input */
++};
+diff --git a/drivers/media/i2c/soc_camera/ar0233_rev2.h b/drivers/media/i2c/soc_camera/ar0233_rev2.h
+index fbc2649..f4b75a2 100644
+--- a/drivers/media/i2c/soc_camera/ar0233_rev2.h
++++ b/drivers/media/i2c/soc_camera/ar0233_rev2.h
+@@ -9,27 +9,6 @@
+ * option) any later version.
+ */
+
+-//#define AR0233_DISPLAY_PATTERN_FIXED
+-//#define AR0233_DISPLAY_PATTERN_COLOR_BAR
+-
+-#define AR0233_MAX_WIDTH 2048
+-#define AR0233_MAX_HEIGHT 1280
+-
+-#define AR0233_DELAY 0xffff
+-
+-#define AR0233_SENSOR_WIDTH 2058
+-#define AR0233_SENSOR_HEIGHT 1284
+-
+-#define AR0233_X_START ((AR0233_SENSOR_WIDTH - AR0233_MAX_WIDTH) / 2)
+-#define AR0233_Y_START ((AR0233_SENSOR_HEIGHT - AR0233_MAX_HEIGHT) / 2)
+-#define AR0233_X_END (AR0233_X_START + AR0233_MAX_WIDTH - 1)
+-#define AR0233_Y_END (AR0233_Y_START + AR0233_MAX_HEIGHT - 1)
+-
+-struct ar0233_reg {
+- u16 reg;
+- u16 val;
+-};
+-
+ #define O1_Recommended_Defaults_LFM_HDR
+ #ifdef O1_Recommended_Defaults_LFM_HDR
+ #define Design_recommended_settings_REV2_V9
+--
+2.7.4
+
diff --git a/bsp/meta-rcar/meta-rcar-gen3-adas/recipes-kernel/linux/linux-renesas/0143-LVDS-AR0231-add-rev6-rev4-on-max9286.patch b/bsp/meta-rcar/meta-rcar-gen3-adas/recipes-kernel/linux/linux-renesas/0143-LVDS-AR0231-add-rev6-rev4-on-max9286.patch
new file mode 100644
index 00000000..dae7a578
--- /dev/null
+++ b/bsp/meta-rcar/meta-rcar-gen3-adas/recipes-kernel/linux/linux-renesas/0143-LVDS-AR0231-add-rev6-rev4-on-max9286.patch
@@ -0,0 +1,663 @@
+From 209a765a09c2de8f24ffb0b8c78ccddac64bb849 Mon Sep 17 00:00:00 2001
+From: Vladimir Barinov <vladimir.barinov@cogentembedded.com>
+Date: Thu, 10 Jan 2019 21:50:07 +0300
+Subject: [PATCH 092/122] LVDS: AR0231: add rev6,rev4 on max9286
+
+This reenables support on MAX9286
+
+Signed-off-by: Vladimir Barinov <vladimir.barinov@cogentembedded.com>
+---
+ drivers/media/i2c/soc_camera/ar0231.c | 16 +-
+ drivers/media/i2c/soc_camera/ar0231.h | 7 +-
+ drivers/media/i2c/soc_camera/ar0231_rev4.h | 38 ++--
+ drivers/media/i2c/soc_camera/ar0231_rev6.h | 343 +++++++++++++++++++++++++++++
+ drivers/media/i2c/soc_camera/ar0231_rev7.h | 77 ++++---
+ 5 files changed, 427 insertions(+), 54 deletions(-)
+ create mode 100644 drivers/media/i2c/soc_camera/ar0231_rev6.h
+
+diff --git a/drivers/media/i2c/soc_camera/ar0231.c b/drivers/media/i2c/soc_camera/ar0231.c
+index f575cb7..07f2b5e 100644
+--- a/drivers/media/i2c/soc_camera/ar0231.c
++++ b/drivers/media/i2c/soc_camera/ar0231.c
+@@ -20,11 +20,12 @@
+ #include <media/v4l2-common.h>
+ #include <media/v4l2-ctrls.h>
+
+-#include "ar0231_rev7.h"
++#include "ar0231.h"
+
+ static const int ar0231_i2c_addr[] = {0x10, 0x20};
+
+ #define AR0231_PID 0x3000
++#define AR0231_REV 0x300E
+ #define AR0231_VERSION_REG 0x0354
+
+ #define AR0231_MEDIA_BUS_FMT MEDIA_BUS_FMT_SGRBG12_1X12
+@@ -393,7 +394,7 @@ static int ar0231_initialize(struct i2c_client *client)
+ {
+ struct ar0231_priv *priv = to_ar0231(client);
+ u16 val = 0;
+- u16 pid = 0;
++ u16 pid = 0, rev = 0;
+ int ret = 0;
+ int tmp_addr;
+ int i;
+@@ -425,18 +426,23 @@ static int ar0231_initialize(struct i2c_client *client)
+ goto err;
+ }
+
++ /* check revision */
++ reg16_read16(client, AR0231_REV, &rev);
+ /* Read OTP IDs */
+ ar0231_otp_id_read(client);
+ /* Program wizard registers */
+- ar0231_set_regs(client, ar0231_regs_wizard_rev7, ARRAY_SIZE(ar0231_regs_wizard_rev7));
++ if (priv->ti9x4_addr)
++ ar0231_set_regs(client, ar0231_regs_wizard_rev7, ARRAY_SIZE(ar0231_regs_wizard_rev7));
++ if (priv->max9286_addr)
++ ar0231_set_regs(client, ar0231_regs_wizard_rev6_dvp, ARRAY_SIZE(ar0231_regs_wizard_rev6_dvp));
+
+ /* Enable stream */
+ reg16_read16(client, 0x301a, &val);
+ val |= (1 << 2);
+ reg16_write16(client, 0x301a, val);
+
+- dev_info(&client->dev, "ar0231 PID %x, res %dx%d, OTP_ID %02x:%02x:%02x:%02x:%02x:%02x\n",
+- pid, AR0231_MAX_WIDTH, AR0231_MAX_HEIGHT, priv->id[0], priv->id[1], priv->id[2], priv->id[3], priv->id[4], priv->id[5]);
++ dev_info(&client->dev, "ar0231 PID %x (rev %x), res %dx%d, OTP_ID %02x:%02x:%02x:%02x:%02x:%02x\n",
++ pid, rev, AR0231_MAX_WIDTH, AR0231_MAX_HEIGHT, priv->id[0], priv->id[1], priv->id[2], priv->id[3], priv->id[4], priv->id[5]);
+ err:
+ ar0231_s_port(client, 0);
+ return ret;
+diff --git a/drivers/media/i2c/soc_camera/ar0231.h b/drivers/media/i2c/soc_camera/ar0231.h
+index b63dc91..09fc7d2d 100644
+--- a/drivers/media/i2c/soc_camera/ar0231.h
++++ b/drivers/media/i2c/soc_camera/ar0231.h
+@@ -12,8 +12,8 @@
+ //#define AR0231_DISPLAY_PATTERN_FIXED
+ //#define AR0231_DISPLAY_PATTERN_COLOR_BAR
+
+-#define AR0231_MAX_WIDTH 1928
+-#define AR0231_MAX_HEIGHT 1208
++#define AR0231_MAX_WIDTH 1920
++#define AR0231_MAX_HEIGHT 1200
+
+ #define AR0231_DELAY 0xffff
+
+@@ -31,4 +31,5 @@ struct ar0231_reg {
+ };
+
+ #include "ar0231_rev4.h"
+-//#include "ar0231_rev6.h"
++#include "ar0231_rev6.h"
++#include "ar0231_rev7.h"
+diff --git a/drivers/media/i2c/soc_camera/ar0231_rev4.h b/drivers/media/i2c/soc_camera/ar0231_rev4.h
+index d4614ec..0627d96 100644
+--- a/drivers/media/i2c/soc_camera/ar0231_rev4.h
++++ b/drivers/media/i2c/soc_camera/ar0231_rev4.h
+@@ -9,7 +9,7 @@
+ * option) any later version.
+ */
+
+-static const struct ar0231_reg ar0231_regs_wizard_rev4[] = {
++static const struct ar0231_reg ar0231_regs_wizard_rev4_dvp[] = {
+ {0x301A, 0x0001}, // reset
+ {0x301A, 0x10D8}, // Stream off and setup parallel
+ {0x3070, 0x0000}, // 1: Solid color test pattern,
+@@ -26,6 +26,7 @@ static const struct ar0231_reg ar0231_regs_wizard_rev4[] = {
+ #ifdef AR0231_DISPLAY_PATTERN_COLOR_BAR
+ {0x3070, 0x0002},
+ #endif
++
+ //Recommended Settings
+ {0x3366, 0x6666}, // ANALOG_GAIN
+ {0x3056, 0x0080}, // GREEN1_GAIN
+@@ -116,6 +117,7 @@ static const struct ar0231_reg ar0231_regs_wizard_rev4[] = {
+ {0x3566, 0x1128}, // RESERVED_MFR_3566
+ {0x3566, 0x1328}, // RESERVED_MFR_3566
+ {0x3566, 0x3328}, // RESERVED_MFR_3566
++
+ //Sequencer Update
+ {0x2512, 0x8000}, // SEQ_CTRL_PORT
+ {0x2510, 0x0905}, // SEQ_DATA_PORT
+@@ -251,6 +253,7 @@ static const struct ar0231_reg ar0231_regs_wizard_rev4[] = {
+ {0x32D4, 0x3702}, // RESERVED_MFR_32D4
+ {0x32D6, 0x3C04}, // RESERVED_MFR_32D6
+ {0x32DC, 0x370A}, // RESERVED_MFR_32DC
++
+ //Parallel Timing Setup
+ {0x302A, 0x0009}, // VT_PIX_CLK_DIV
+ {0x302C, 0x0001}, // VT_SYS_CLK_DIV
+@@ -259,21 +262,20 @@ static const struct ar0231_reg ar0231_regs_wizard_rev4[] = {
+ {0x3036, 0x0008}, // OP_WORD_CLK_DIV
+ {0x3038, 0x0001}, // OP_SYS_CLK_DIV
+ {0x30B0, 0x0A00}, // DIGITAL_TEST
++
+ //Readout Mode Configuration
+ {0x30A2, 0x0001}, // X_ODD_INC_
+ {0x30A6, 0x0001}, // Y_ODD_INC_
+ {0x3040, 0x0000}, // READ_MODE
+ {0x3044, 0x0400}, // DARK_CONTROL
+-{0x33E0, 0x0880}, // RESERVED_MFR_33E0
+-{0x3180, 0x0080}, // RESERVED_MFR_3180
+-{0x33E4, 0x0080}, // RESERVED_MFR_33E4
+-
+-//HDR Readout Mode Configuration
+ #ifdef AR0231_EMBEDDED_LINE
+ {0x3064, 0x1982}, // SMIA_TEST
+ #else
+ {0x3064, 0x1802}, // SMIA_TEST
+ #endif
++{0x33E0, 0x0880}, // RESERVED_MFR_33E0
++{0x3180, 0x0080}, // RESERVED_MFR_3180
++{0x33E4, 0x0080}, // RESERVED_MFR_33E4
+
+ #if 1
+ {0x3004, AR0231_X_START}, // X_ADDR_START_
+@@ -298,12 +300,8 @@ static const struct ar0231_reg ar0231_regs_wizard_rev4[] = {
+ //3exp Timing and Exposure
+ {0x3082, 0x0008}, // OPERATION_MODE_CTRL
+ {0x30BA, 0x11E2}, // DIGITAL_CTRL
+-
+-//Row and Pixel Timing
+-{0x300A, 0x5af},
+-{0x300C, 0x7ba},
+-
+-//Exposure Settings
++{0x300A, 0x05AF}, // FRAME_LENGTH_LINES_
++{0x300C, 0x07BA}, // LINE_LENGTH_PCK_
+ {0x3042, 0x0000}, // EXTRA_DELAY
+ {0x3238, 0x0222}, // EXPOSURE_RATIO
+ {0x1008, 0x0374}, // FINE_INTEGRATION_TIME_MIN
+@@ -315,31 +313,29 @@ static const struct ar0231_reg ar0231_regs_wizard_rev4[] = {
+ {0x321E, 0x06A6}, // FINE_INTEGRATION_TIME2
+ {0x3222, 0x06A6}, // FINE_INTEGRATION_TIME3
+ {0x30B0, 0x0B02}, // DIGITAL_TEST
+-
+ {0x32EA, 0x3C0E}, // RESERVED_MFR_32EA
+ {0x32EC, 0x72A1}, // RESERVED_MFR_32EC
++
+ //Parallel HDR 12 bit Output
+ {0x31D0, 0x0001}, // COMPANDING
++{0x31AE, 0x0001}, // SERIAL_FORMAT
+ {0x31AC, 0x140C}, // DATA_FORMAT_BITS
+
+-//{0x301A, 0x01d8}, // RESET_REGISTER
+-{0x301A, 0x01dc}, // RESET_REGISTER - stream on
+-
+-//{AR0231_DELAY, 100}, // Wait 100ms
+-
+ #if 0 // no need for front only camera
+ /* Enable trigger input */
+ {0x340A, 0x00E0}, // GPIO_CONTROL1: GPIO1 is trigger
+ {0x340C, 0x0002}, // GPIO_CONTROL2: GPIO1 is trigger
+ {0x30CE, 0x0120}, // TRIGGER_MODE
+ //{0x30DC, 0x0120}, // TRIGGER_DELAY
++{0x301A, 0x01D8}, // GPI pins enable
+ #endif
+
+-#define NEW_TIMINGS
+-#ifdef NEW_TIMINGS
+-/* the sequence must be updated to use following timings, now it is a hack */
++{0x301A, 0x01DC}, // RESET_REGISTER - stream on
++
++#if 1
+ {0x300A, AR0231_SENSOR_HEIGHT + 225}, // FRAME_LENGTH_LINES_
+ {0x300C, AR0231_SENSOR_WIDTH + 120}, // LINE_LENGTH_PCK_
++/* the sequence must be updated to use following timings, now it is a hack */
+ {0x1008, 0x0fff}, // FINE_INTEGRATION_TIME_MIN
+ {0x100C, 0x0fff}, // FINE_INTEGRATION_TIME2_MIN
+ {0x100E, 0x0fff}, // FINE_INTEGRATION_TIME3_MIN
+diff --git a/drivers/media/i2c/soc_camera/ar0231_rev6.h b/drivers/media/i2c/soc_camera/ar0231_rev6.h
+new file mode 100644
+index 0000000..12e0ce5
+--- /dev/null
++++ b/drivers/media/i2c/soc_camera/ar0231_rev6.h
+@@ -0,0 +1,343 @@
++/*
++ * ON Semiconductor AR0231 sensor camera wizard 1920x1080@30/BGGR/MIPI
++ *
++ * Copyright (C) 2018 Cogent Embedded, Inc.
++ *
++ * This program is free software; you can redistribute it and/or modify it
++ * under the terms of the GNU General Public License as published by the
++ * Free Software Foundation; either version 2 of the License, or (at your
++ * option) any later version.
++ */
++
++/* Parallel Timing Setup 27MHz In 88 MHz Out */
++static const struct ar0231_reg ar0231_regs_wizard_rev6_dvp[] = {
++{0x301A, 0x0001}, // reset
++{0x301A, 0x10D8}, // Stream off and setup parallel
++{0x3070, 0x0000}, // 1: Solid color test pattern,
++ // 2: Full color bar test pattern,
++ // 3: Fade to grey color bar test pattern,
++ //256: Walking 1 test pattern (12 bit)
++{0x3072, 0x0123}, // R
++{0x3074, 0x0456}, // G(GR row)
++{0x3076, 0x0abc}, // B
++{0x3078, 0x0def}, // G(GB row)
++#ifdef AR0231_DISPLAY_PATTERN_FIXED
++{0x3070, 0x0001},
++#endif
++#ifdef AR0231_DISPLAY_PATTERN_COLOR_BAR
++{0x3070, 0x0002},
++#endif
++
++//Recommended Settings
++{0x3056, 0x0080}, // GREEN1_GAIN
++{0x305C, 0x0080}, // GREEN2_GAIN
++{0x3058, 0x0080}, // BLUE_GAIN
++{0x305A, 0x0080}, // RED_GAIN
++{0x3138, 0x000B}, // OTPM_TCFG_OPT
++{0x3372, 0xF54F}, // RESERVED_MFR_3372
++{0x337A, 0x0D70}, // RESERVED_MFR_337A
++{0x337E, 0x1FFD}, // RESERVED_MFR_337E
++{0x3382, 0x00C0}, // RESERVED_MFR_3382
++{0x3C04, 0x0E80}, // RESERVED_MFR_3C04
++{0x3F90, 0x06E1}, // RESERVED_MFR_3F90
++{0x3F92, 0x06E1}, // RESERVED_MFR_3F92
++{0x350E, 0x1F14}, // RESERVED_MFR_350E
++{0x350E, 0xFF10}, // RESERVED_MFR_350E
++{0x3506, 0x4444}, // RESERVED_MFR_3506
++{0x3508, 0x4444}, // RESERVED_MFR_3508
++{0x350A, 0x4465}, // RESERVED_MFR_350A
++{0x350C, 0x055F}, // RESERVED_MFR_350C
++{0x3566, 0x9D38}, // RESERVED_MFR_3566
++{0x3518, 0x1FFE}, // RESERVED_MFR_3518
++{0x3520, 0xC688}, // RESERVED_MFR_3520
++{0x3522, 0x88C0}, // RESERVED_MFR_3522
++{0x3524, 0xC0C6}, // RESERVED_MFR_3524
++{0x352C, 0xC6C6}, // RESERVED_MFR_352C
++{0x3528, 0x0900}, // RESERVED_MFR_3528
++{0x3528, 0x9900}, // RESERVED_MFR_3528
++{0x3528, 0x9909}, // RESERVED_MFR_3528
++{0x3528, 0x9999}, // RESERVED_MFR_3528
++{0x352A, 0x089F}, // RESERVED_MFR_352A
++{0x352E, 0x0001}, // RESERVED_MFR_352E
++{0x352E, 0x0011}, // RESERVED_MFR_352E
++{0x3530, 0x0400}, // RESERVED_MFR_3530
++{0x3530, 0x4400}, // RESERVED_MFR_3530
++{0x3536, 0xFF00}, // RESERVED_MFR_3536
++{0x3536, 0xFF00}, // RESERVED_MFR_3536
++{0x3536, 0xFF00}, // RESERVED_MFR_3536
++{0x3536, 0xFF00}, // RESERVED_MFR_3536
++{0x3536, 0xFF00}, // RESERVED_MFR_3536
++{0x3536, 0xFF00}, // RESERVED_MFR_3536
++{0x3536, 0xFF00}, // RESERVED_MFR_3536
++{0x3536, 0xFF00}, // RESERVED_MFR_3536
++{0x3536, 0xFF02}, // RESERVED_MFR_3536
++{0x3536, 0xFF06}, // RESERVED_MFR_3536
++{0x3536, 0xFF06}, // RESERVED_MFR_3536
++{0x3538, 0xFFFF}, // RESERVED_MFR_3538
++{0x3538, 0xFFFF}, // RESERVED_MFR_3538
++{0x3538, 0xFFFF}, // RESERVED_MFR_3538
++{0x3538, 0xFFFF}, // RESERVED_MFR_3538
++{0x3538, 0xFFFF}, // RESERVED_MFR_3538
++{0x3538, 0xFFFF}, // RESERVED_MFR_3538
++{0x3538, 0xFFFF}, // RESERVED_MFR_3538
++{0x3538, 0xFFFF}, // RESERVED_MFR_3538
++{0x3538, 0xFFFF}, // RESERVED_MFR_3538
++{0x3538, 0xFFFF}, // RESERVED_MFR_3538
++{0x353A, 0x9000}, // RESERVED_MFR_353A
++{0x353C, 0x3F00}, // RESERVED_MFR_353C
++{0x353C, 0x3F00}, // RESERVED_MFR_353C
++{0x353C, 0x3F00}, // RESERVED_MFR_353C
++{0x353C, 0x3F00}, // RESERVED_MFR_353C
++{0x353C, 0x3F00}, // RESERVED_MFR_353C
++{0x353C, 0x3F00}, // RESERVED_MFR_353C
++{0x32EC, 0x72A1}, // RESERVED_MFR_32EC
++{0x3540, 0xC637}, // RESERVED_MFR_3540
++{0x3540, 0xC637}, // RESERVED_MFR_3540
++{0x3540, 0xC637}, // RESERVED_MFR_3540
++{0x3542, 0x584B}, // RESERVED_MFR_3542
++{0x3542, 0x464B}, // RESERVED_MFR_3542
++{0x3544, 0x565A}, // RESERVED_MFR_3544
++{0x3544, 0x4B5A}, // RESERVED_MFR_3544
++{0x3546, 0x545A}, // RESERVED_MFR_3546
++{0x3546, 0x5A5A}, // RESERVED_MFR_3546
++{0x3548, 0x6400}, // RESERVED_MFR_3548
++{0x3556, 0x101F}, // RESERVED_MFR_3556
++{0x3566, 0x9D38}, // RESERVED_MFR_3566
++{0x3566, 0x1D38}, // RESERVED_MFR_3566
++{0x3566, 0x1D28}, // RESERVED_MFR_3566
++{0x3566, 0x1128}, // RESERVED_MFR_3566
++{0x3566, 0x1328}, // RESERVED_MFR_3566
++{0x3566, 0x3328}, // RESERVED_MFR_3566
++{0x3528, 0xDDDD}, // RESERVED_MFR_3528
++
++//Sequencer Update
++{0x2512, 0x8000}, // SEQ_CTRL_PORT
++{0x2510, 0x0905}, // SEQ_DATA_PORT
++{0x2510, 0x3350}, // SEQ_DATA_PORT
++{0x2510, 0x2004}, // SEQ_DATA_PORT
++{0x2510, 0x1460}, // SEQ_DATA_PORT
++{0x2510, 0x1578}, // SEQ_DATA_PORT
++{0x2510, 0x1360}, // SEQ_DATA_PORT
++{0x2510, 0x7B24}, // SEQ_DATA_PORT
++{0x2510, 0xFF24}, // SEQ_DATA_PORT
++{0x2510, 0xFF24}, // SEQ_DATA_PORT
++{0x2510, 0xEA24}, // SEQ_DATA_PORT
++{0x2510, 0x1022}, // SEQ_DATA_PORT
++{0x2510, 0x2410}, // SEQ_DATA_PORT
++{0x2510, 0x155A}, // SEQ_DATA_PORT
++{0x2510, 0x1342}, // SEQ_DATA_PORT
++{0x2510, 0x1400}, // SEQ_DATA_PORT
++{0x2510, 0x24FF}, // SEQ_DATA_PORT
++{0x2510, 0x24FF}, // SEQ_DATA_PORT
++{0x2510, 0x24EA}, // SEQ_DATA_PORT
++{0x2510, 0x2324}, // SEQ_DATA_PORT
++{0x2510, 0x647A}, // SEQ_DATA_PORT
++{0x2510, 0x2404}, // SEQ_DATA_PORT
++{0x2510, 0x052C}, // SEQ_DATA_PORT
++{0x2510, 0x400A}, // SEQ_DATA_PORT
++{0x2510, 0xFF0A}, // SEQ_DATA_PORT
++{0x2510, 0xFF0A}, // SEQ_DATA_PORT
++{0x2510, 0x1808}, // SEQ_DATA_PORT
++{0x2510, 0x3851}, // SEQ_DATA_PORT
++{0x2510, 0x1440}, // SEQ_DATA_PORT
++{0x2510, 0x0004}, // SEQ_DATA_PORT
++{0x2510, 0x0801}, // SEQ_DATA_PORT
++{0x2510, 0x0408}, // SEQ_DATA_PORT
++{0x2510, 0x1180}, // SEQ_DATA_PORT
++{0x2510, 0x15DC}, // SEQ_DATA_PORT
++{0x2510, 0x134C}, // SEQ_DATA_PORT
++{0x2510, 0x1002}, // SEQ_DATA_PORT
++{0x2510, 0x1016}, // SEQ_DATA_PORT
++{0x2510, 0x1181}, // SEQ_DATA_PORT
++{0x2510, 0x1189}, // SEQ_DATA_PORT
++{0x2510, 0x1056}, // SEQ_DATA_PORT
++{0x2510, 0x1210}, // SEQ_DATA_PORT
++{0x2510, 0x0901}, // SEQ_DATA_PORT
++{0x2510, 0x0D08}, // SEQ_DATA_PORT
++{0x2510, 0x0913}, // SEQ_DATA_PORT
++{0x2510, 0x13C8}, // SEQ_DATA_PORT
++{0x2510, 0x092B}, // SEQ_DATA_PORT
++{0x2510, 0x1588}, // SEQ_DATA_PORT
++{0x2510, 0x1388}, // SEQ_DATA_PORT
++{0x2510, 0x090B}, // SEQ_DATA_PORT
++{0x2510, 0x11D9}, // SEQ_DATA_PORT
++{0x2510, 0x091D}, // SEQ_DATA_PORT
++{0x2510, 0x1441}, // SEQ_DATA_PORT
++{0x2510, 0x0903}, // SEQ_DATA_PORT
++{0x2510, 0x1214}, // SEQ_DATA_PORT
++{0x2510, 0x0901}, // SEQ_DATA_PORT
++{0x2510, 0x10D6}, // SEQ_DATA_PORT
++{0x2510, 0x1210}, // SEQ_DATA_PORT
++{0x2510, 0x1212}, // SEQ_DATA_PORT
++{0x2510, 0x1210}, // SEQ_DATA_PORT
++{0x2510, 0x11DD}, // SEQ_DATA_PORT
++{0x2510, 0x11D9}, // SEQ_DATA_PORT
++{0x2510, 0x1056}, // SEQ_DATA_PORT
++{0x2510, 0x090B}, // SEQ_DATA_PORT
++{0x2510, 0x11DB}, // SEQ_DATA_PORT
++{0x2510, 0x0915}, // SEQ_DATA_PORT
++{0x2510, 0x119B}, // SEQ_DATA_PORT
++{0x2510, 0x090F}, // SEQ_DATA_PORT
++{0x2510, 0x11BB}, // SEQ_DATA_PORT
++{0x2510, 0x121A}, // SEQ_DATA_PORT
++{0x2510, 0x1210}, // SEQ_DATA_PORT
++{0x2510, 0x1460}, // SEQ_DATA_PORT
++{0x2510, 0x1250}, // SEQ_DATA_PORT
++{0x2510, 0x1076}, // SEQ_DATA_PORT
++{0x2510, 0x10E6}, // SEQ_DATA_PORT
++{0x2510, 0x0901}, // SEQ_DATA_PORT
++{0x2510, 0x15AB}, // SEQ_DATA_PORT
++{0x2510, 0x0901}, // SEQ_DATA_PORT
++{0x2510, 0x13A8}, // SEQ_DATA_PORT
++{0x2510, 0x1240}, // SEQ_DATA_PORT
++{0x2510, 0x1260}, // SEQ_DATA_PORT
++{0x2510, 0x0923}, // SEQ_DATA_PORT
++{0x2510, 0x158D}, // SEQ_DATA_PORT
++{0x2510, 0x138D}, // SEQ_DATA_PORT
++{0x2510, 0x0901}, // SEQ_DATA_PORT
++{0x2510, 0x0B09}, // SEQ_DATA_PORT
++{0x2510, 0x0108}, // SEQ_DATA_PORT
++{0x2510, 0x0901}, // SEQ_DATA_PORT
++{0x2510, 0x1440}, // SEQ_DATA_PORT
++{0x2510, 0x091D}, // SEQ_DATA_PORT
++{0x2510, 0x1588}, // SEQ_DATA_PORT
++{0x2510, 0x1388}, // SEQ_DATA_PORT
++{0x2510, 0x092D}, // SEQ_DATA_PORT
++{0x2510, 0x1066}, // SEQ_DATA_PORT
++{0x2510, 0x0905}, // SEQ_DATA_PORT
++{0x2510, 0x0C08}, // SEQ_DATA_PORT
++{0x2510, 0x090B}, // SEQ_DATA_PORT
++{0x2510, 0x1441}, // SEQ_DATA_PORT
++{0x2510, 0x090D}, // SEQ_DATA_PORT
++{0x2510, 0x10E6}, // SEQ_DATA_PORT
++{0x2510, 0x0901}, // SEQ_DATA_PORT
++{0x2510, 0x1262}, // SEQ_DATA_PORT
++{0x2510, 0x1260}, // SEQ_DATA_PORT
++{0x2510, 0x11BF}, // SEQ_DATA_PORT
++{0x2510, 0x11BB}, // SEQ_DATA_PORT
++{0x2510, 0x1066}, // SEQ_DATA_PORT
++{0x2510, 0x11FB}, // SEQ_DATA_PORT
++{0x2510, 0x0935}, // SEQ_DATA_PORT
++{0x2510, 0x11BB}, // SEQ_DATA_PORT
++{0x2510, 0x1263}, // SEQ_DATA_PORT
++{0x2510, 0x1260}, // SEQ_DATA_PORT
++{0x2510, 0x1400}, // SEQ_DATA_PORT
++{0x2510, 0x1510}, // SEQ_DATA_PORT
++{0x2510, 0x11B8}, // SEQ_DATA_PORT
++{0x2510, 0x12A0}, // SEQ_DATA_PORT
++{0x2510, 0x1200}, // SEQ_DATA_PORT
++{0x2510, 0x1026}, // SEQ_DATA_PORT
++{0x2510, 0x1000}, // SEQ_DATA_PORT
++{0x2510, 0x1342}, // SEQ_DATA_PORT
++{0x2510, 0x1100}, // SEQ_DATA_PORT
++{0x2510, 0x7A06}, // SEQ_DATA_PORT
++{0x2510, 0x0915}, // SEQ_DATA_PORT
++{0x2510, 0x0507}, // SEQ_DATA_PORT
++{0x2510, 0x0841}, // SEQ_DATA_PORT
++{0x2510, 0x3750}, // SEQ_DATA_PORT
++{0x2510, 0x2C2C}, // SEQ_DATA_PORT
++{0x2510, 0xFE05}, // SEQ_DATA_PORT
++{0x2510, 0xFE13}, // SEQ_DATA_PORT
++{0x1008, 0x0361}, // FINE_INTEGRATION_TIME_MIN
++{0x100C, 0x0589}, // FINE_INTEGRATION_TIME2_MIN
++{0x100E, 0x07B1}, // FINE_INTEGRATION_TIME3_MIN
++{0x1010, 0x0139}, // FINE_INTEGRATION_TIME4_MIN
++{0x3230, 0x0304}, // FINE_CORRECTION
++{0x3232, 0x052C}, // FINE_CORRECTION2
++{0x3234, 0x0754}, // FINE_CORRECTION3
++{0x3236, 0x00DC}, // FINE_CORRECTION4
++{0x3566, 0x3328}, // RESERVED_MFR_3566
++{0x350C, 0x055F}, // RESERVED_MFR_350C
++{0x32D0, 0x3A02}, // RESERVED_MFR_32D0
++{0x32D2, 0x3508}, // RESERVED_MFR_32D2
++{0x32D4, 0x3702}, // RESERVED_MFR_32D4
++{0x32D6, 0x3C04}, // RESERVED_MFR_32D6
++{0x32DC, 0x370A}, // RESERVED_MFR_32DC
++
++//Parallel Timing Setup 27MHz In 88 MHz Out
++{0x302A, 0x0009}, // VT_PIX_CLK_DIV
++{0x302C, 0x0001}, // VT_SYS_CLK_DIV
++{0x302E, 0x0003}, // PRE_PLL_CLK_DIV
++{0x3030, 0x0058}, // PLL_MULTIPLIER
++{0x3036, 0x0008}, // OP_WORD_CLK_DIV
++{0x3038, 0x0001}, // OP_SYS_CLK_DIV
++{0x30B0, 0x0B02}, // DIGITAL_TEST
++
++//Readout Mode Configuration
++{0x30A2, 0x0001}, // X_ODD_INC_
++{0x30A6, 0x0001}, // Y_ODD_INC_
++{0x3040, 0x0000}, // READ_MODE
++{0x3082, 0x0008}, // OPERATION_MODE_CTRL
++{0x30BA, 0x11E2}, // DIGITAL_CTRL
++{0x3044, 0x0400}, // DARK_CONTROL
++#ifdef AR0231_EMBEDDED_LINE
++{0x3064, 0x1982}, // SMIA_TEST
++#else
++{0x3064, 0x1802}, // SMIA_TEST
++#endif
++{0x33E0, 0x0880}, // RESERVED_MFR_33E0
++{0x3180, 0x0080}, // RESERVED_MFR_3180
++{0x33E4, 0x0080}, // RESERVED_MFR_33E4
++{0x33E0, 0x0C80}, // RESERVED_MFR_33E0
++
++#if 1
++{0x3004, AR0231_X_START}, // X_ADDR_START_
++{0x3008, AR0231_X_END}, // X_ADDR_END_
++{0x3002, AR0231_Y_START}, // Y_ADDR_START_
++{0x3006, AR0231_Y_END}, // Y_ADDR_END_
++{0x3402, 0x0000 | AR0231_MAX_WIDTH}, // X_OUTPUT_CONTROL
++{0x3404, 0x0000 | AR0231_MAX_HEIGHT}, // Y_OUTPUT_CONTROL
++#else
++{0x3004, 0}, // X_ADDR_START_
++{0x3008, 0x0787}, // X_ADDR_END_
++{0x3002, 0x0000}, // Y_ADDR_START_
++{0x3006, 0x04B7}, // Y_ADDR_END_
++{0x3402, 0x0788}, // RESERVED_MFR_3402
++{0x3402, 0x0F10}, // RESERVED_MFR_3402
++{0x3404, 0x0440}, // RESERVED_MFR_3404
++{0x3404, 0x0970}, // RESERVED_MFR_3404
++#endif
++{0x3032, 0x0000}, // SCALING_MODE
++{0x3400, 0x0010}, // RESERVED_MFR_3400
++
++//3exp Timing and Exposure
++{0x3082, 0x0008}, // OPERATION_MODE_CTRL
++{0x30BA, 0x11E2}, // DIGITAL_CTRL
++{0x300A, 0x05CA}, // FRAME_LENGTH_LINES_
++{0x300C, 0x07BA}, // LINE_LENGTH_PCK_
++{0x3042, 0x0000}, // EXTRA_DELAY
++{0x3238, 0x0222}, // EXPOSURE_RATIO
++{0x3012, 0x0163}, // COARSE_INTEGRATION_TIME_
++{0x3014, 0x08CC}, // FINE_INTEGRATION_TIME_
++{0x321E, 0x08CC}, // FINE_INTEGRATION_TIME2
++{0x3222, 0x0254}, // FINE_INTEGRATION_TIME3
++{0x30B0, 0x0A00}, // DIGITAL_TEST
++{0x32EA, 0x3C0E}, // RESERVED_MFR_32EA
++{0x32EC, 0x72A1}, // RESERVED_MFR_32EC
++
++//Parallel HDR 12 bit Output
++{0x31D0, 0x0001}, // COMPANDING
++{0x31AE, 0x0001}, // SERIAL_FORMAT
++{0x31AC, 0x140C}, // DATA_FORMAT_BITS
++
++#if 0 // no need for front only camera
++/* Enable trigger input */
++{0x340A, 0x00E0}, // GPIO_CONTROL1: GPIO1 is trigger
++{0x340C, 0x0002}, // GPIO_CONTROL2: GPIO1 is trigger
++{0x30CE, 0x0120}, // TRIGGER_MODE
++//{0x30DC, 0x0120}, // TRIGGER_DELAY
++{0x301A, 0x01D8}, // GPI pins enable
++#endif
++
++{0x301A, 0x01DC}, // RESET_REGISTER - stream on
++
++#if 1
++{0x300A, AR0231_SENSOR_HEIGHT + 225}, // FRAME_LENGTH_LINES_
++{0x300C, AR0231_SENSOR_WIDTH + 120}, // LINE_LENGTH_PCK_
++/* the sequence must be updated to use following timings, now it is a hack */
++{0x1008, 0x0fff}, // FINE_INTEGRATION_TIME_MIN
++{0x100C, 0x0fff}, // FINE_INTEGRATION_TIME2_MIN
++{0x100E, 0x0fff}, // FINE_INTEGRATION_TIME3_MIN
++{0x1010, 0x0fff}, // FINE_INTEGRATION_TIME4_MIN
++#endif
++};
+diff --git a/drivers/media/i2c/soc_camera/ar0231_rev7.h b/drivers/media/i2c/soc_camera/ar0231_rev7.h
+index c05c3ea..885d34e 100644
+--- a/drivers/media/i2c/soc_camera/ar0231_rev7.h
++++ b/drivers/media/i2c/soc_camera/ar0231_rev7.h
+@@ -9,27 +9,6 @@
+ * option) any later version.
+ */
+
+-//#define AR0231_DISPLAY_PATTERN_FIXED
+-//#define AR0231_DISPLAY_PATTERN_COLOR_BAR
+-
+-#define AR0231_MAX_WIDTH 1920
+-#define AR0231_MAX_HEIGHT 1200
+-
+-#define AR0231_DELAY 0xffff
+-
+-#define AR0231_SENSOR_WIDTH 1928
+-#define AR0231_SENSOR_HEIGHT 1208
+-
+-#define AR0231_X_START ((AR0231_SENSOR_WIDTH - AR0231_MAX_WIDTH) / 2)
+-#define AR0231_Y_START ((AR0231_SENSOR_HEIGHT - AR0231_MAX_HEIGHT) / 2)
+-#define AR0231_X_END (AR0231_X_START + AR0231_MAX_WIDTH - 1)
+-#define AR0231_Y_END (AR0231_Y_START + AR0231_MAX_HEIGHT - 1)
+-
+-struct ar0231_reg {
+- u16 reg;
+- u16 val;
+-};
+-
+ /* 3Exp HDR Full Resolution Mode MIPI 4lane 12bit 30FPS, XCLK=27MHz */
+ static const struct ar0231_reg ar0231_regs_wizard_rev7[] = {
+ {0x301A, 0x18}, // MIPI, stream OFF
+@@ -322,12 +301,14 @@ static const struct ar0231_reg ar0231_regs_wizard_rev7[] = {
+ #endif /* Sensor Setup */
+
+ #if 1 /* Serial 12-bit Timing Setup */
+-{0x302A, 6}, // vt_pix_clk_div
+-{0x302C, 1}, // vt_sys_clk_div
++/* PCLK=27Mhz/PRE_PLL_CLK_DIV *PLL_MULTIPLIER /P1 /P4 *2 */
++/* PCLK=27Mhz/2 *44/1/12 *2= 99Mhz - TI serializers */
++{0x302A, 6}, // vt_pix_clk_div (P2 divider)
++{0x302C, 1}, // vt_sys_clk_div (P1 divider)
+ {0x302E, 2}, // pre_pll_clk_div
+ {0x3030, 44}, // pll_multiplier
+-{0x3036, 12}, // op_word_clk_div
+-{0x3038, 1}, // op_sys_clk_div
++{0x3036, 12}, // op_word_clk_div (P4 divider)
++{0x3038, 1}, // op_sys_clk_div (P3 divider)
+ {0x30B0, 0x800}, // digital_test: pll_complete_bypass=0
+ #endif /* Serial 12-bit Timing Setup */
+
+@@ -416,3 +397,49 @@ static const struct ar0231_reg ar0231_regs_wizard_rev7[] = {
+ {0x301A, 0x0118}, // GPI pins enable
+ #endif
+ };
++
++/* 3Exp HDR Full Resolution Mode Parallel 12bit 30FPS, XCLK=24MHz */
++static const struct ar0231_reg ar0231_regs_wizard_rev7_dvp[] = {
++#if 1 /* Parallel Timing Setup */
++/* PCLK=24Mhz/PRE_PLL_CLK_DIV *PLL_MULTIPLIER /P1 /P4 */
++/* PCLK=24Mhz/3 *88/1/8 = 88Mhz - TI serializers */
++{0x302A, 8}, // vt_pix_clk_div (P2 divider)
++{0x302C, 1}, // vt_sys_clk_div (P1 divider)
++{0x302E, 3}, // pre_pll_clk_div
++{0x3030, 88}, // pll_multiplier
++{0x3036, 8}, // op_word_clk_div (P4 divider)
++{0x3038, 1}, // op_sys_clk_div (P3 divider)
++{0x30B0, 0x800}, // digital_test: pll_complete_bypass=0
++#endif
++
++#if 1 /* 3exp Timing and Exposure - Parallel */
++{0x3082, 0x8}, // operation_mode_ctrl
++{0x30BA, 0x11E2}, // digital_ctrl: num_exp_max=2
++
++/* Row and Pixel Timing */
++#if 1
++{0x300A, AR0231_SENSOR_HEIGHT + 225}, // frame_length_lines_
++{0x300C, AR0231_SENSOR_WIDTH + 120}, // line_length_pck_
++#else
++{0x300C, 1978}, // line_length_pck_
++{0x300A, 1482}, // frame_length_lines_
++#endif
++{0x3042, 0}, // extra_delay
++
++/* Exposure Settings */
++//{0x3238, 0x222}, // exposure_ratio
++//{0x3012, 355}, // coarse_integration_time_
++{0x3014, 2178}, // fine_integration_time_
++{0x321E, 2178}, // fine_integration_time2
++{0x3222, 2178}, // fine_integration_time3
++{0x30B0, 0x800}, // digital_test: set bit11
++{0x32EA, 0x3C0E},
++{0x32EC, 0x72A1},
++#endif /* 3exp Timing and Exposure - Parallel */
++
++#if 1 /* Parallel HDR 12 bit Output */
++{0x31AE, 0x001}, // serial_format:
++#endif
++
++{0x301A, 0x01d8}, // RESET_REGISTER parallel pins enable
++};
+--
+2.7.4
+
diff --git a/bsp/meta-rcar/meta-rcar-gen3-adas/recipes-kernel/linux/linux-renesas/0144-lvds-add-OV10640-imager.patch b/bsp/meta-rcar/meta-rcar-gen3-adas/recipes-kernel/linux/linux-renesas/0144-lvds-add-OV10640-imager.patch
new file mode 100644
index 00000000..c2dce0a8
--- /dev/null
+++ b/bsp/meta-rcar/meta-rcar-gen3-adas/recipes-kernel/linux/linux-renesas/0144-lvds-add-OV10640-imager.patch
@@ -0,0 +1,3174 @@
+From e454ddd45aaf59fd3ad98a9ec35e70051270a579 Mon Sep 17 00:00:00 2001
+From: Vladimir Barinov <vladimir.barinov@cogentembedded.com>
+Date: Mon, 14 Jan 2019 16:36:37 +0300
+Subject: [PATCH 093/122] lvds: add OV10640 imager
+
+This adds OV10640 imager support (RDACM24B)
+
+Signed-off-by: Vladimir Barinov <vladimir.barinov@cogentembedded.com>
+---
+ drivers/media/i2c/soc_camera/ov10640.c | 685 +++++++++
+ drivers/media/i2c/soc_camera/ov10640.h | 2407 ++++++++++++++++++++++++++++++++
+ drivers/media/i2c/soc_camera/ov106xx.c | 13 +-
+ 3 files changed, 3104 insertions(+), 1 deletion(-)
+ create mode 100644 drivers/media/i2c/soc_camera/ov10640.c
+ create mode 100644 drivers/media/i2c/soc_camera/ov10640.h
+
+diff --git a/drivers/media/i2c/soc_camera/ov10640.c b/drivers/media/i2c/soc_camera/ov10640.c
+new file mode 100644
+index 0000000..8746988
+--- /dev/null
++++ b/drivers/media/i2c/soc_camera/ov10640.c
+@@ -0,0 +1,685 @@
++/*
++ * OmniVision ov10640 sensor camera driver
++ *
++ * Copyright (C) 2015-2017 Cogent Embedded, Inc.
++ *
++ * This program is free software; you can redistribute it and/or modify it
++ * under the terms of the GNU General Public License as published by the
++ * Free Software Foundation; either version 2 of the License, or (at your
++ * option) any later version.
++ */
++
++#include <linux/delay.h>
++#include <linux/init.h>
++#include <linux/i2c.h>
++#include <linux/module.h>
++#include <linux/of_graph.h>
++#include <linux/videodev2.h>
++
++#include <media/soc_camera.h>
++#include <media/v4l2-common.h>
++#include <media/v4l2-ctrls.h>
++
++#include "max9286.h"
++#include "ov10640.h"
++
++#define OV10640_I2C_ADDR 0x30
++
++#define OV10640_PID 0x300a
++#define OV10640_VER 0x300b
++#define OV10640_VERSION_REG 0xa640
++
++#define OV10640_MEDIA_BUS_FMT MEDIA_BUS_FMT_SBGGR12_1X12
++
++struct ov10640_priv {
++ struct v4l2_subdev sd;
++ struct v4l2_ctrl_handler hdl;
++ struct media_pad pad;
++ struct v4l2_rect rect;
++ int subsampling;
++ int fps_denominator;
++ int init_complete;
++ u8 id[6];
++ int dvp_order;
++ /* serializers */
++ int max9286_addr;
++ int max9271_addr;
++ int ti9x4_addr;
++ int ti9x3_addr;
++ int port;
++ int gpio_resetb;
++ int gpio_fsin;
++};
++
++static inline struct ov10640_priv *to_ov10640(const struct i2c_client *client)
++{
++ return container_of(i2c_get_clientdata(client), struct ov10640_priv, sd);
++}
++
++static inline struct v4l2_subdev *ov10640_to_sd(struct v4l2_ctrl *ctrl)
++{
++ return &container_of(ctrl->handler, struct ov10640_priv, hdl)->sd;
++}
++
++static void ov10640_s_port(struct i2c_client *client, int fwd_en)
++{
++ struct ov10640_priv *priv = to_ov10640(client);
++ int tmp_addr;
++
++ if (priv->max9286_addr) {
++ tmp_addr = client->addr;
++ client->addr = priv->max9286_addr; /* Deserializer I2C address */
++ reg8_write(client, 0x0a, fwd_en ? 0x11 << priv->port : 0); /* Enable/disable reverse/forward control for this port */
++ usleep_range(5000, 5500); /* wait 5ms */
++ client->addr = tmp_addr;
++ };
++}
++
++static int ov10640_set_regs(struct i2c_client *client,
++ const struct ov10640_reg *regs, int nr_regs)
++{
++ int i;
++
++ for (i = 0; i < nr_regs; i++) {
++ if (regs[i].reg == OV10640_DELAY) {
++ mdelay(regs[i].val);
++ continue;
++ }
++
++ if (reg16_write(client, regs[i].reg, regs[i].val)) {
++ usleep_range(100, 150); /* wait 100ns */
++ reg16_write(client, regs[i].reg, regs[i].val);
++ }
++ }
++
++ return 0;
++}
++
++static int ov10640_s_stream(struct v4l2_subdev *sd, int enable)
++{
++ return 0;
++}
++
++static int ov10640_set_window(struct v4l2_subdev *sd)
++{
++ struct i2c_client *client = v4l2_get_subdevdata(sd);
++ struct ov10640_priv *priv = to_ov10640(client);
++
++ dev_dbg(&client->dev, "L=%d T=%d %dx%d\n", priv->rect.left, priv->rect.top, priv->rect.width, priv->rect.height);
++
++ /* horiz crop start (reverse) */
++ reg16_write(client, 0x3074, (OV10640_MAX_WIDTH - priv->rect.width - priv->rect.left) >> 8);
++ reg16_write(client, 0x3075, (OV10640_MAX_WIDTH - priv->rect.width - priv->rect.left) & 0xff);
++ /* horiz crop end (reverse) */
++ reg16_write(client, 0x3078, (OV10640_MAX_WIDTH - priv->rect.left - 1) >> 8);
++ reg16_write(client, 0x3079, (OV10640_MAX_WIDTH - priv->rect.left - 1) & 0xff);
++ /* vert crop start */
++ reg16_write(client, 0x3076, priv->rect.top >> 8);
++ reg16_write(client, 0x3077, priv->rect.top & 0xff);
++ /* vert crop end */
++ reg16_write(client, 0x307a, (priv->rect.top + priv->rect.height + 1) >> 8);
++ reg16_write(client, 0x307b, (priv->rect.top + priv->rect.height + 1) & 0xff);
++ /* horiz output */
++ reg16_write(client, 0x307c, priv->rect.width >> 8);
++ reg16_write(client, 0x307d, priv->rect.width & 0xff);
++ /* vert output */
++ reg16_write(client, 0x307e, priv->rect.height >> 8);
++ reg16_write(client, 0x307f, priv->rect.height & 0xff);
++
++ return 0;
++};
++
++static int ov10640_get_fmt(struct v4l2_subdev *sd,
++ struct v4l2_subdev_pad_config *cfg,
++ struct v4l2_subdev_format *format)
++{
++ struct v4l2_mbus_framefmt *mf = &format->format;
++ struct i2c_client *client = v4l2_get_subdevdata(sd);
++ struct ov10640_priv *priv = to_ov10640(client);
++
++ if (format->pad)
++ return -EINVAL;
++
++ mf->width = priv->rect.width;
++ mf->height = priv->rect.height;
++ mf->code = OV10640_MEDIA_BUS_FMT;
++ mf->colorspace = V4L2_COLORSPACE_SMPTE170M;
++ mf->field = V4L2_FIELD_NONE;
++
++ return 0;
++}
++
++static int ov10640_set_fmt(struct v4l2_subdev *sd,
++ struct v4l2_subdev_pad_config *cfg,
++ struct v4l2_subdev_format *format)
++{
++ struct v4l2_mbus_framefmt *mf = &format->format;
++
++ mf->code = OV10640_MEDIA_BUS_FMT;
++ mf->colorspace = V4L2_COLORSPACE_SMPTE170M;
++ mf->field = V4L2_FIELD_NONE;
++
++ if (format->which == V4L2_SUBDEV_FORMAT_TRY)
++ cfg->try_fmt = *mf;
++
++ return 0;
++}
++
++static int ov10640_enum_mbus_code(struct v4l2_subdev *sd,
++ struct v4l2_subdev_pad_config *cfg,
++ struct v4l2_subdev_mbus_code_enum *code)
++{
++ if (code->pad || code->index > 0)
++ return -EINVAL;
++
++ code->code = OV10640_MEDIA_BUS_FMT;
++
++ return 0;
++}
++
++static int ov10640_get_edid(struct v4l2_subdev *sd, struct v4l2_edid *edid)
++{
++ struct i2c_client *client = v4l2_get_subdevdata(sd);
++ struct ov10640_priv *priv = to_ov10640(client);
++
++ memcpy(edid->edid, priv->id, 6);
++
++ edid->edid[6] = 0xff;
++ edid->edid[7] = client->addr;
++ edid->edid[8] = OV10640_VERSION_REG >> 8;
++ edid->edid[9] = OV10640_VERSION_REG & 0xff;
++
++ return 0;
++}
++
++static int ov10640_set_selection(struct v4l2_subdev *sd,
++ struct v4l2_subdev_pad_config *cfg,
++ struct v4l2_subdev_selection *sel)
++{
++ struct v4l2_rect *rect = &sel->r;
++ struct i2c_client *client = v4l2_get_subdevdata(sd);
++ struct ov10640_priv *priv = to_ov10640(client);
++
++ if (sel->which != V4L2_SUBDEV_FORMAT_ACTIVE ||
++ sel->target != V4L2_SEL_TGT_CROP)
++ return -EINVAL;
++
++ rect->left = ALIGN(rect->left, 2);
++ rect->top = ALIGN(rect->top, 2);
++ rect->width = ALIGN(rect->width, 2);
++ rect->height = ALIGN(rect->height, 2);
++
++ if ((rect->left + rect->width > OV10640_MAX_WIDTH) ||
++ (rect->top + rect->height > OV10640_MAX_HEIGHT))
++ *rect = priv->rect;
++
++ priv->rect.left = rect->left;
++ priv->rect.top = rect->top;
++ priv->rect.width = rect->width;
++ priv->rect.height = rect->height;
++
++ ov10640_set_window(sd);
++
++ return 0;
++}
++
++static int ov10640_get_selection(struct v4l2_subdev *sd,
++ struct v4l2_subdev_pad_config *cfg,
++ struct v4l2_subdev_selection *sel)
++{
++ struct i2c_client *client = v4l2_get_subdevdata(sd);
++ struct ov10640_priv *priv = to_ov10640(client);
++
++ if (sel->which != V4L2_SUBDEV_FORMAT_ACTIVE)
++ return -EINVAL;
++
++ switch (sel->target) {
++ case V4L2_SEL_TGT_CROP_BOUNDS:
++ sel->r.left = 0;
++ sel->r.top = 0;
++ sel->r.width = OV10640_MAX_WIDTH;
++ sel->r.height = OV10640_MAX_HEIGHT;
++ return 0;
++ case V4L2_SEL_TGT_CROP_DEFAULT:
++ sel->r.left = 0;
++ sel->r.top = 0;
++ sel->r.width = OV10640_MAX_WIDTH;
++ sel->r.height = OV10640_MAX_HEIGHT;
++ return 0;
++ case V4L2_SEL_TGT_CROP:
++ sel->r = priv->rect;
++ return 0;
++ default:
++ return -EINVAL;
++ }
++}
++
++static int ov10640_g_mbus_config(struct v4l2_subdev *sd,
++ struct v4l2_mbus_config *cfg)
++{
++ cfg->flags = V4L2_MBUS_CSI2_1_LANE | V4L2_MBUS_CSI2_CHANNEL_0 |
++ V4L2_MBUS_CSI2_CONTINUOUS_CLOCK;
++ cfg->type = V4L2_MBUS_CSI2;
++
++ return 0;
++}
++
++#ifdef CONFIG_VIDEO_ADV_DEBUG
++static int ov10640_g_register(struct v4l2_subdev *sd,
++ struct v4l2_dbg_register *reg)
++{
++ struct i2c_client *client = v4l2_get_subdevdata(sd);
++ int ret;
++ u8 val = 0;
++
++ ret = reg16_read(client, (u16)reg->reg, &val);
++ if (ret < 0)
++ return ret;
++
++ reg->val = val;
++ reg->size = sizeof(u16);
++
++ return 0;
++}
++
++static int ov10640_s_register(struct v4l2_subdev *sd,
++ const struct v4l2_dbg_register *reg)
++{
++ struct i2c_client *client = v4l2_get_subdevdata(sd);
++
++ return reg16_write(client, (u16)reg->reg, (u8)reg->val);
++}
++#endif
++
++static struct v4l2_subdev_core_ops ov10640_core_ops = {
++#ifdef CONFIG_VIDEO_ADV_DEBUG
++ .g_register = ov10640_g_register,
++ .s_register = ov10640_s_register,
++#endif
++};
++
++static int ov10640_s_ctrl(struct v4l2_ctrl *ctrl)
++{
++ struct v4l2_subdev *sd = ov10640_to_sd(ctrl);
++ struct i2c_client *client = v4l2_get_subdevdata(sd);
++ struct ov10640_priv *priv = to_ov10640(client);
++ int ret = -EINVAL;
++ u8 val = 0;
++ u16 val16 = 0;
++
++ if (!priv->init_complete)
++ return 0;
++
++ switch (ctrl->id) {
++ case V4L2_CID_BRIGHTNESS:
++ case V4L2_CID_CONTRAST:
++ case V4L2_CID_SATURATION:
++ case V4L2_CID_HUE:
++ case V4L2_CID_GAMMA:
++ break;
++ case V4L2_CID_GAIN:
++ reg16_write(client, 0x30EC, ctrl->val); // L
++ reg16_write(client, 0x30EE, ctrl->val); // S
++ reg16_write(client, 0x30F0, ctrl->val); // VS
++ break;
++ case V4L2_CID_ANALOGUE_GAIN:
++ reg16_read(client, 0x30EB, &val);
++ val &= ~(0x3f << 0); // VS, S, L - Gauss curve
++ val |= ((ctrl->val / 2) << 0); // L
++ val |= (ctrl->val << 2); // S
++ val |= ((ctrl->val / 2) << 4); // VS
++ reg16_write(client, 0x30EB, val);
++ break;
++ case V4L2_CID_EXPOSURE:
++ val16 = 0xfff - ctrl->val;
++
++ reg16_write(client, 0x30E6, val16 >> 8); // L
++ reg16_write(client, 0x30E7, val16 & 0xff); // L
++
++ reg16_write(client, 0x30E8, val16 >> 8); // S
++ reg16_write(client, 0x30E9, val16 & 0xff); // S
++
++// reg16_write(client, 0x30EA, val >> 8); // VS - fractional ...
++ break;
++ case V4L2_CID_EXPOSURE_AUTO:
++ reg16_read(client, 0x30FA, &val);
++ val &= ~(0x1 << 6);
++ val |= (ctrl->val << 6);
++ reg16_write(client, 0x30FA, val);
++ break;
++ case V4L2_CID_HFLIP:
++ reg16_read(client, 0x3128, &val);
++ val &= ~(0x1 << 0);
++ val |= (ctrl->val << 0);
++ reg16_write(client, 0x3128, val);
++
++ reg16_read(client, 0x3291, &val);
++ val &= ~(0x1 << 1);
++ val |= (ctrl->val << 1);
++ reg16_write(client, 0x3291, val);
++
++ reg16_read(client, 0x3090, &val);
++ val &= ~(0x1 << 2);
++ val |= (ctrl->val << 2);
++ ret = reg16_write(client, 0x3090, val);
++ break;
++ case V4L2_CID_VFLIP:
++ reg16_read(client, 0x3128, &val);
++ val &= ~(0x1 << 1);
++ val |= (ctrl->val << 1);
++ reg16_write(client, 0x3128, val);
++
++ reg16_read(client, 0x3291, &val);
++ val &= ~(0x1 << 2);
++ val |= (ctrl->val << 2);
++ reg16_write(client, 0x3291, val);
++
++ reg16_read(client, 0x3090, &val);
++ val &= ~(0x1 << 3);
++ val |= (ctrl->val << 3);
++ ret = reg16_write(client, 0x3090, val);
++ break;
++ case V4L2_CID_MIN_BUFFERS_FOR_CAPTURE:
++ ret = 0;
++ break;
++ }
++
++ return ret;
++}
++
++static const struct v4l2_ctrl_ops ov10640_ctrl_ops = {
++ .s_ctrl = ov10640_s_ctrl,
++};
++
++static struct v4l2_subdev_video_ops ov10640_video_ops = {
++ .s_stream = ov10640_s_stream,
++ .g_mbus_config = ov10640_g_mbus_config,
++};
++
++static const struct v4l2_subdev_pad_ops ov10640_subdev_pad_ops = {
++ .get_edid = ov10640_get_edid,
++ .enum_mbus_code = ov10640_enum_mbus_code,
++ .get_selection = ov10640_get_selection,
++ .set_selection = ov10640_set_selection,
++ .get_fmt = ov10640_get_fmt,
++ .set_fmt = ov10640_set_fmt,
++};
++
++static struct v4l2_subdev_ops ov10640_subdev_ops = {
++ .core = &ov10640_core_ops,
++ .video = &ov10640_video_ops,
++ .pad = &ov10640_subdev_pad_ops,
++};
++
++static void ov10640_otp_id_read(struct i2c_client *client)
++{
++ struct ov10640_priv *priv = to_ov10640(client);
++ int i;
++ int otp_bank0_allzero = 1;
++
++ reg16_write(client, 0x349C, 1);
++ usleep_range(25000, 25500); /* wait 25 ms */
++
++ for (i = 0; i < 6; i++) {
++ /* first 6 bytes are equal on all ov10640 */
++ reg16_read(client, 0x349e + i + 6, &priv->id[i]);
++ if (priv->id[i])
++ otp_bank0_allzero = 0;
++ }
++
++ if (otp_bank0_allzero) {
++ reg16_write(client, 0x3495, 0x41); /* bank#1 */
++ reg16_write(client, 0x349C, 1);
++ usleep_range(25000, 25500); /* wait 25 ms */
++
++ for (i = 0; i < 6; i++)
++ reg16_read(client, 0x34ae + i, &priv->id[i]);
++ }
++}
++
++static ssize_t ov10640_otp_id_show(struct device *dev,
++ struct device_attribute *attr, char *buf)
++{
++ struct v4l2_subdev *sd = i2c_get_clientdata(to_i2c_client(dev));
++ struct i2c_client *client = v4l2_get_subdevdata(sd);
++ struct ov10640_priv *priv = to_ov10640(client);
++
++ return snprintf(buf, 32, "%02x:%02x:%02x:%02x:%02x:%02x\n",
++ priv->id[0], priv->id[1], priv->id[2], priv->id[3], priv->id[4], priv->id[5]);
++}
++
++static DEVICE_ATTR(otp_id_ov10640, S_IRUGO, ov10640_otp_id_show, NULL);
++
++static int ov10640_initialize(struct i2c_client *client)
++{
++ struct ov10640_priv *priv = to_ov10640(client);
++ u16 pid;
++ u8 val = 0;
++ int ret = 0;
++
++ ov10640_s_port(client, 1);
++
++ /* check and show product ID and manufacturer ID */
++ reg16_read(client, OV10640_PID, &val);
++ pid = val;
++ reg16_read(client, OV10640_VER, &val);
++ pid = (pid << 8) | val;
++
++ if (pid != OV10640_VERSION_REG) {
++ dev_err(&client->dev, "Product ID error %x\n", pid);
++ ret = -ENODEV;
++ goto out;
++ }
++
++ /* Read OTP IDs */
++ ov10640_otp_id_read(client);
++ /* Program wizard registers */
++ ov10640_set_regs(client, ov10640_regs_wizard_r1e, ARRAY_SIZE(ov10640_regs_wizard_r1e));
++
++ dev_info(&client->dev, "ov10640 PID %x, res %dx%d, OTP_ID %02x:%02x:%02x:%02x:%02x:%02x\n",
++ pid, OV10640_MAX_WIDTH, OV10640_MAX_HEIGHT, priv->id[0], priv->id[1], priv->id[2], priv->id[3], priv->id[4], priv->id[5]);
++out:
++ ov10640_s_port(client, 0);
++
++ return ret;
++}
++
++static int ov10640_parse_dt(struct device_node *np, struct ov10640_priv *priv)
++{
++ struct i2c_client *client = v4l2_get_subdevdata(&priv->sd);
++ int i;
++ struct device_node *endpoint = NULL, *rendpoint = NULL;
++ int tmp_addr = 0;
++
++ for (i = 0; ; i++) {
++ endpoint = of_graph_get_next_endpoint(np, endpoint);
++ if (!endpoint)
++ break;
++
++ of_node_put(endpoint);
++
++ of_property_read_u32(endpoint, "dvp-order", &priv->dvp_order);
++
++ rendpoint = of_parse_phandle(endpoint, "remote-endpoint", 0);
++ if (!rendpoint)
++ continue;
++
++ if (!of_property_read_u32(rendpoint, "max9271-addr", &priv->max9271_addr) &&
++ !of_property_read_u32(rendpoint->parent->parent, "reg", &priv->max9286_addr) &&
++ !kstrtouint(strrchr(rendpoint->full_name, '@') + 1, 0, &priv->port))
++ break;
++
++ if (!of_property_read_u32(rendpoint, "ti9x3-addr", &priv->ti9x3_addr) &&
++ !of_property_match_string(rendpoint->parent->parent, "compatible", "ti,ti9x4") &&
++ !of_property_read_u32(rendpoint->parent->parent, "reg", &priv->ti9x4_addr) &&
++ !kstrtouint(strrchr(rendpoint->full_name, '@') + 1, 0, &priv->port))
++ break;
++ }
++
++ if (!priv->max9286_addr && !priv->ti9x4_addr) {
++ dev_err(&client->dev, "deserializer does not present for OV10640\n");
++ return -EINVAL;
++ }
++
++ ov10640_s_port(client, 1);
++
++ /* setup I2C translator address */
++ tmp_addr = client->addr;
++ if (priv->max9286_addr) {
++ client->addr = priv->max9271_addr; /* Serializer I2C address */
++
++ reg8_write(client, 0x09, tmp_addr << 1); /* Sensor translated I2C address */
++ reg8_write(client, 0x0A, OV10640_I2C_ADDR << 1); /* Sensor native I2C address */
++ usleep_range(2000, 2500); /* wait 2ms */
++ };
++
++ if (priv->ti9x4_addr) {
++ client->addr = priv->ti9x4_addr; /* Deserializer I2C address */
++
++ reg8_write(client, 0x4c, (priv->port << 4) | (1 << priv->port)); /* Select RX port number */
++ usleep_range(2000, 2500); /* wait 2ms */
++ reg8_write(client, 0x65, tmp_addr << 1); /* Sensor translated I2C address */
++ reg8_write(client, 0x5d, OV10640_I2C_ADDR << 1); /* Sensor native I2C address */
++
++// reg8_write(client, 0x6e, 0x9a); /* GPIO0 - fsin, GPIO1 - resetb */
++// udelay(100);
++ }
++ client->addr = tmp_addr;
++
++ return 0;
++}
++
++static int ov10640_probe(struct i2c_client *client,
++ const struct i2c_device_id *did)
++{
++ struct ov10640_priv *priv;
++ struct v4l2_ctrl *ctrl;
++ int ret;
++
++ priv = devm_kzalloc(&client->dev, sizeof(*priv), GFP_KERNEL);
++ if (!priv)
++ return -ENOMEM;
++
++ v4l2_i2c_subdev_init(&priv->sd, client, &ov10640_subdev_ops);
++ priv->sd.flags = V4L2_SUBDEV_FL_HAS_DEVNODE;
++ priv->rect.left = 0;
++ priv->rect.top = 0;
++ priv->rect.width = OV10640_MAX_WIDTH;
++ priv->rect.height = OV10640_MAX_HEIGHT;
++ priv->fps_denominator = 30;
++
++ v4l2_ctrl_handler_init(&priv->hdl, 4);
++ v4l2_ctrl_new_std(&priv->hdl, &ov10640_ctrl_ops,
++ V4L2_CID_BRIGHTNESS, 0, 0xff, 1, 0x30);
++ v4l2_ctrl_new_std(&priv->hdl, &ov10640_ctrl_ops,
++ V4L2_CID_CONTRAST, 0, 4, 1, 2);
++ v4l2_ctrl_new_std(&priv->hdl, &ov10640_ctrl_ops,
++ V4L2_CID_SATURATION, 0, 0xff, 1, 0xff);
++ v4l2_ctrl_new_std(&priv->hdl, &ov10640_ctrl_ops,
++ V4L2_CID_HUE, 0, 255, 1, 0);
++ v4l2_ctrl_new_std(&priv->hdl, &ov10640_ctrl_ops,
++ V4L2_CID_GAMMA, 0, 0xffff, 1, 0x233);
++ v4l2_ctrl_new_std(&priv->hdl, &ov10640_ctrl_ops,
++ V4L2_CID_GAIN, 0, 0x3f, 1, 0x1);
++ v4l2_ctrl_new_std(&priv->hdl, &ov10640_ctrl_ops,
++ V4L2_CID_ANALOGUE_GAIN, 0, 3, 1, 1);
++ v4l2_ctrl_new_std(&priv->hdl, &ov10640_ctrl_ops,
++ V4L2_CID_EXPOSURE, 0, 0xfff, 1, 0x448);
++ v4l2_ctrl_new_std(&priv->hdl, &ov10640_ctrl_ops,
++ V4L2_CID_EXPOSURE_AUTO, 0, 1, 1, 0);
++ v4l2_ctrl_new_std(&priv->hdl, &ov10640_ctrl_ops,
++ V4L2_CID_HFLIP, 0, 1, 1, 1);
++ v4l2_ctrl_new_std(&priv->hdl, &ov10640_ctrl_ops,
++ V4L2_CID_VFLIP, 0, 1, 1, 0);
++ ctrl = v4l2_ctrl_new_std(&priv->hdl, &ov10640_ctrl_ops,
++ V4L2_CID_MIN_BUFFERS_FOR_CAPTURE, 1, 32, 1, 9);
++ if (ctrl)
++ ctrl->flags &= ~V4L2_CTRL_FLAG_READ_ONLY;
++ priv->sd.ctrl_handler = &priv->hdl;
++
++ ret = priv->hdl.error;
++ if (ret)
++ goto cleanup;
++
++ v4l2_ctrl_handler_setup(&priv->hdl);
++
++ priv->pad.flags = MEDIA_PAD_FL_SOURCE;
++ priv->sd.entity.flags |= MEDIA_ENT_F_CAM_SENSOR;
++ ret = media_entity_pads_init(&priv->sd.entity, 1, &priv->pad);
++ if (ret < 0)
++ goto cleanup;
++
++ ret = ov10640_parse_dt(client->dev.of_node, priv);
++ if (ret)
++ goto cleanup;
++
++ ret = ov10640_initialize(client);
++ if (ret < 0)
++ goto cleanup;
++
++ ret = v4l2_async_register_subdev(&priv->sd);
++ if (ret)
++ goto cleanup;
++
++ if (device_create_file(&client->dev, &dev_attr_otp_id_ov10640) != 0) {
++ dev_err(&client->dev, "sysfs otp_id entry creation failed\n");
++ goto cleanup;
++ }
++
++ priv->init_complete = 1;
++
++ return 0;
++
++cleanup:
++ media_entity_cleanup(&priv->sd.entity);
++ v4l2_ctrl_handler_free(&priv->hdl);
++ v4l2_device_unregister_subdev(&priv->sd);
++#ifdef CONFIG_SOC_CAMERA_OV10640
++ v4l_err(client, "failed to probe @ 0x%02x (%s)\n",
++ client->addr, client->adapter->name);
++#endif
++ return ret;
++}
++
++static int ov10640_remove(struct i2c_client *client)
++{
++ struct ov10640_priv *priv = i2c_get_clientdata(client);
++
++ device_remove_file(&client->dev, &dev_attr_otp_id_ov10640);
++ v4l2_async_unregister_subdev(&priv->sd);
++ media_entity_cleanup(&priv->sd.entity);
++ v4l2_ctrl_handler_free(&priv->hdl);
++ v4l2_device_unregister_subdev(&priv->sd);
++
++ return 0;
++}
++
++#ifdef CONFIG_SOC_CAMERA_OV10640
++static const struct i2c_device_id ov10640_id[] = {
++ { "ov10640", 0 },
++ { }
++};
++MODULE_DEVICE_TABLE(i2c, ov10640_id);
++
++static const struct of_device_id ov10640_of_ids[] = {
++ { .compatible = "ovti,ov10640", },
++ { }
++};
++MODULE_DEVICE_TABLE(of, ov10640_of_ids);
++
++static struct i2c_driver ov10640_i2c_driver = {
++ .driver = {
++ .name = "ov10640",
++ .of_match_table = ov10640_of_ids,
++ },
++ .probe = ov10640_probe,
++ .remove = ov10640_remove,
++ .id_table = ov10640_id,
++};
++
++module_i2c_driver(ov10640_i2c_driver);
++
++MODULE_DESCRIPTION("SoC Camera driver for OV10640");
++MODULE_AUTHOR("Vladimir Barinov");
++MODULE_LICENSE("GPL");
++#endif
+diff --git a/drivers/media/i2c/soc_camera/ov10640.h b/drivers/media/i2c/soc_camera/ov10640.h
+new file mode 100644
+index 0000000..dbc6c0b
+--- /dev/null
++++ b/drivers/media/i2c/soc_camera/ov10640.h
+@@ -0,0 +1,2407 @@
++/*
++ * OmniVision ov10640 sensor camera wizard 1280x800@30/UYVY/BT601/8bit
++ *
++ * Copyright (C) 2015-2017 Cogent Embedded, Inc.
++ *
++ * This program is free software; you can redistribute it and/or modify it
++ * under the terms of the GNU General Public License as published by the
++ * Free Software Foundation; either version 2 of the License, or (at your
++ * option) any later version.
++ */
++
++//#define OV10640_DISPLAY_PATTERN
++#define OV10640_FSIN_ENABLE
++
++#define OV10640_MAX_WIDTH 1280
++#define OV10640_MAX_HEIGHT 1080
++
++#define OV10640_DELAY 0xffff
++
++#define OV10640_SENSOR_WIDTH 1292
++#define OV10640_SENSOR_HEIGHT 1092
++
++#define OV10640_X_START ((OV10640_SENSOR_WIDTH - OV10640_MAX_WIDTH) / 2)
++#define OV10640_Y_START ((OV10640_SENSOR_HEIGHT - OV10640_MAX_HEIGHT) / 2)
++#define OV10640_X_END (OV10640_X_START + OV10640_MAX_WIDTH - 1)
++#define OV10640_Y_END (OV10640_Y_START + OV10640_MAX_HEIGHT - 1)
++
++struct ov10640_reg {
++ u16 reg;
++ u8 val;
++};
++
++/* DVP_1280x1080_COMB12_raw 60fps */
++static const struct ov10640_reg ov10640_regs_wizard_r1f[] = {
++{0x3013, 0x01},
++{OV10640_DELAY, 10},
++{0x31be, 0x01},
++{0x3133, 0xb7},
++{0x3134, 0xca},
++{0x3135, 0xcc},
++{0x313f, 0x80},
++{0x3132, 0x24},
++{0x3000, 0x03},
++{0x3001, 0x62},
++{0x3002, 0x07},
++//{0x3002, 0x0f}, // for 30fps wizard
++{0x3004, 0x03},
++#if 0
++{0x3005, 0x62},
++#else
++{0x3005, 0x48},
++#endif
++{0x3006, 0x07},
++{0x3007, 0x01},
++{0x3023, 0x05},
++{0x3032, 0x35},
++{0x3033, 0x04},
++{0x3054, 0x00},
++{0x3055, 0x0f},
++{0x3056, 0x01},
++{0x3057, 0xff},
++{0x3058, 0xaf},
++{0x3059, 0x44},
++{0x305a, 0x02},
++{0x305b, 0x00},
++{0x305c, 0x30},
++{0x305d, 0x9e},
++{0x305e, 0x19},
++{0x305f, 0x18},
++{0x3060, 0xf9},
++{0x3061, 0xf0},
++#ifdef OV10640_FSIN_ENABLE
++{0x308c, 0xb2},
++#else
++{0x308c, 0x03},
++#endif
++{0x308f, 0x10},
++{0x3090, 0x00},
++{0x3091, 0x00},
++{0x30eb, 0x00},
++{0x30a3, 0x08},
++{0x30ad, 0x03},
++{0x30ae, 0x80},
++{0x30af, 0x80},
++{0x30b0, 0xff},
++{0x30b1, 0x3f},
++{0x30b2, 0x22},
++{0x30b9, 0x22},
++{0x30bb, 0x00},
++{0x30bc, 0x00},
++{0x30bd, 0x00},
++{0x30be, 0x00},
++{0x30bf, 0x00},
++{0x30c0, 0x00},
++{0x30c1, 0x00},
++{0x30c2, 0x00},
++{0x30c3, 0x00},
++{0x30c4, 0x80},
++{0x30c5, 0x00},
++{0x30c6, 0x80},
++{0x30c7, 0x00},
++{0x30c8, 0x80},
++{0x3119, 0x44},
++{0x311a, 0x01},
++{0x311b, 0x4a},
++{0x3074, 0x00},
++{0x3075, 0x00},
++{0x3076, 0x00},
++{0x3077, 0x02},
++{0x3078, 0x05},
++{0x3079, 0x07},
++{0x307a, 0x04},
++{0x307b, 0x41},
++{0x307c, 0x05},
++{0x307d, 0x00},
++{0x307e, 0x04},
++{0x307f, 0x38},
++#if 0
++{0x3080, 0x05},
++{0x3081, 0xbe},
++#else
++{0x3080, 0x06}, // minimal VTS for FPDLINK3
++{0x3081, 0xe0},
++#endif
++{0x3082, 0x04},
++{0x3083, 0x57},
++{0x3084, 0x00},
++{0x3085, 0x04},
++{0x3086, 0x00},
++{0x3087, 0x04},
++{0x3088, 0x00},
++{0x3089, 0x40},
++{0x308d, 0x92},
++{0x3094, 0xa5},
++{0x30e6, 0x04},
++{0x30e7, 0x48},
++{0x30e8, 0x04},
++{0x30e9, 0x48},
++{0x30ea, 0x11},
++{0x30ec, 0x01},
++{0x30fa, 0x06},
++{0x3120, 0x00},
++{0x3121, 0x01},
++{0x3122, 0x00},
++{0x3127, 0x63},
++{0x3128, 0xc0},
++#ifdef OV10640_DISPLAY_PATTERN
++{0x3129, 0x80},
++#else
++{0x3129, 0x00},
++#endif
++{0x31be, 0x01},
++{0x30a5, 0x78},
++{0x30a6, 0x40},
++{0x30a7, 0x78},
++{0x30a8, 0x80},
++{0x30a9, 0x79},
++{0x30aa, 0x00},
++{0x30ab, 0x79},
++{0x30ac, 0xf8},
++{0x3440, 0x04},
++{0x3444, 0x28},
++{0x344e, 0x2c},
++{0x3457, 0x33},
++{0x345e, 0x38},
++{0x3461, 0xa8},
++{0x7002, 0xaa},
++{0x7001, 0xdf},
++{0x7048, 0x00},
++{0x7049, 0x02},
++{0x704a, 0x02},
++{0x704b, 0x00},
++{0x704c, 0x01},
++{0x704d, 0x00},
++{0x7043, 0x04},
++{0x7040, 0x3c},
++{0x7047, 0x00},
++{0x7044, 0x01},
++{0x7000, 0x1f},
++{0x7084, 0x01},
++{0x7085, 0x03},
++{0x7086, 0x02},
++{0x7087, 0x40},
++{0x7088, 0x01},
++{0x7089, 0x20},
++{0x707f, 0x04},
++{0x707c, 0x3c},
++{0x7083, 0x00},
++{0x7080, 0x01},
++{0x7003, 0xdf},
++{0x70c0, 0x00},
++{0x70c1, 0x02},
++{0x70c2, 0x02},
++{0x70c3, 0x00},
++{0x70c4, 0x01},
++{0x70c5, 0x00},
++{0x70b8, 0x03},
++{0x70b9, 0x98},
++{0x70bc, 0x00},
++{0x70bd, 0x80},
++{0x7004, 0x02},
++{0x7005, 0x00},
++{0x7006, 0x01},
++{0x7007, 0x80},
++{0x7008, 0x02},
++{0x7009, 0x00},
++{0x700a, 0x04},
++{0x700b, 0x00},
++{0x700e, 0x00},
++{0x700f, 0x60},
++{0x701a, 0x02},
++{0x701b, 0x00},
++{0x701c, 0x01},
++{0x701d, 0x80},
++{0x701e, 0x02},
++{0x701f, 0x00},
++{0x7020, 0x04},
++{0x7021, 0x00},
++{0x7024, 0x00},
++{0x7025, 0x60},
++{0x70e7, 0x00},
++{0x70e4, 0x10},
++{0x70e5, 0x00},
++{0x70e6, 0x00},
++{0x70eb, 0x00},
++{0x70e8, 0x10},
++{0x70e9, 0x00},
++{0x70ea, 0x00},
++{0x70ef, 0x00},
++{0x70ec, 0xfd},
++{0x70ed, 0x00},
++{0x70ee, 0x00},
++{0x70eb, 0x00},
++{0x70f0, 0xfd},
++{0x70f1, 0x00},
++{0x70f2, 0x00},
++{0x30fb, 0x06},
++{0x30fc, 0x80},
++{0x30fd, 0x02},
++{0x30fe, 0x93},
++{0x6000, 0xc1},
++{0x6001, 0xb9},
++{0x6002, 0xba},
++{0x6003, 0xa4},
++{0x6004, 0xa4},
++{0x6005, 0xb5},
++{0x6006, 0xa0},
++{0x6007, 0x82},
++{0x6008, 0xa7},
++{0x6009, 0xa7},
++{0x600a, 0xb7},
++{0x600b, 0x5c},
++{0x600c, 0x9e},
++{0x600d, 0xc0},
++{0x600e, 0xd2},
++{0x600f, 0x33},
++{0x6010, 0xcc},
++{0x6011, 0xe2},
++{0x6012, 0xc1},
++{0x6013, 0xab},
++{0x6014, 0xab},
++{0x6015, 0xb7},
++{0x6016, 0x00},
++{0x6017, 0x00},
++{0x6018, 0x00},
++{0x6019, 0x00},
++{0x601a, 0x00},
++{0x601b, 0x00},
++{0x601c, 0x00},
++{0x601d, 0x00},
++{0x601e, 0x00},
++{0x601f, 0x00},
++{0x6020, 0x00},
++{0x6021, 0x00},
++{0x6022, 0x00},
++{0x6023, 0x9c},
++{0x6024, 0x94},
++{0x6025, 0x90},
++{0x6026, 0xc5},
++{0x6027, 0x00},
++{0x6028, 0x54},
++{0x6029, 0x2a},
++{0x602a, 0x61},
++{0x602b, 0xd2},
++{0x602c, 0xcc},
++{0x602d, 0x04},
++{0x602e, 0x35},
++{0x602f, 0xb1},
++{0x6030, 0xb2},
++{0x6031, 0xb3},
++{0x6032, 0xd2},
++{0x6033, 0xd3},
++{0x6034, 0x11},
++{0x6035, 0x31},
++{0x6036, 0xcc},
++{0x6037, 0x06},
++{0x6038, 0xd2},
++{0x6039, 0x00},
++{0x603a, 0xce},
++{0x603b, 0x18},
++{0x603c, 0xcf},
++{0x603d, 0x1e},
++{0x603e, 0xd0},
++{0x603f, 0x24},
++{0x6040, 0xc5},
++{0x6041, 0xd2},
++{0x6042, 0xbc},
++{0x6043, 0xcc},
++{0x6044, 0x52},
++{0x6045, 0x2b},
++{0x6046, 0xd2},
++{0x6047, 0xd3},
++{0x6048, 0x01},
++{0x6049, 0xcc},
++{0x604a, 0x0a},
++{0x604b, 0xd2},
++{0x604c, 0xd3},
++{0x604d, 0x0f},
++{0x604e, 0x1a},
++{0x604f, 0x2a},
++{0x6050, 0xd4},
++{0x6051, 0xe3},
++{0x6052, 0xba},
++{0x6053, 0x56},
++{0x6054, 0xd3},
++{0x6055, 0x2e},
++{0x6056, 0x54},
++{0x6057, 0x26},
++{0x6058, 0xd2},
++{0x6059, 0xcc},
++{0x605a, 0x60},
++{0x605b, 0xd2},
++{0x605c, 0xd3},
++{0x605d, 0x27},
++{0x605e, 0x27},
++{0x605f, 0x08},
++{0x6060, 0x1a},
++{0x6061, 0xcc},
++{0x6062, 0x88},
++{0x6063, 0x00},
++{0x6064, 0x12},
++{0x6065, 0x2c},
++{0x6066, 0x60},
++{0x6067, 0xc2},
++{0x6068, 0xb9},
++{0x6069, 0xa5},
++{0x606a, 0xa5},
++{0x606b, 0xb5},
++{0x606c, 0xa0},
++{0x606d, 0x82},
++{0x606e, 0x5c},
++{0x606f, 0xd4},
++{0x6070, 0xab},
++{0x6071, 0xd4},
++{0x6072, 0xab},
++{0x6073, 0xd3},
++{0x6074, 0x01},
++{0x6075, 0x7c},
++{0x6076, 0x74},
++{0x6077, 0x00},
++{0x6078, 0x61},
++{0x6079, 0x2a},
++{0x607a, 0xd2},
++{0x607b, 0xcc},
++{0x607c, 0xdf},
++{0x607d, 0xc6},
++{0x607e, 0x35},
++{0x607f, 0xd2},
++{0x6080, 0xcc},
++{0x6081, 0x06},
++{0x6082, 0x31},
++{0x6083, 0xd2},
++{0x6084, 0x00},
++{0x6085, 0xbb},
++{0x6086, 0xcc},
++{0x6087, 0x18},
++{0x6088, 0xc6},
++{0x6089, 0xd2},
++{0x608a, 0xbd},
++{0x608b, 0xcc},
++{0x608c, 0x52},
++{0x608d, 0x2b},
++{0x608e, 0xd2},
++{0x608f, 0xd3},
++{0x6090, 0x01},
++{0x6091, 0xcc},
++{0x6092, 0x0a},
++{0x6093, 0xd2},
++{0x6094, 0xd3},
++{0x6095, 0x0f},
++{0x6096, 0x1a},
++{0x6097, 0x71},
++{0x6098, 0x2a},
++{0x6099, 0xd4},
++{0x609a, 0xe3},
++{0x609b, 0xd3},
++{0x609c, 0x22},
++{0x609d, 0x70},
++{0x609e, 0xca},
++{0x609f, 0x26},
++{0x60a0, 0xd2},
++{0x60a1, 0xcc},
++{0x60a2, 0x60},
++{0x60a3, 0xd2},
++{0x60a4, 0xd3},
++{0x60a5, 0x27},
++{0x60a6, 0x27},
++{0x60a7, 0x08},
++{0x60a8, 0x1a},
++{0x60a9, 0xcc},
++{0x60aa, 0x88},
++{0x60ab, 0x00},
++{0x60ac, 0x12},
++{0x60ad, 0x2c},
++{0x60ae, 0x60},
++{0x60af, 0x00},
++{0x60b0, 0x00},
++{0x60b1, 0xc0},
++{0x60b2, 0xb9},
++{0x60b3, 0xa3},
++{0x60b4, 0xa3},
++{0x60b5, 0xb5},
++{0x60b6, 0x00},
++{0x60b7, 0xa0},
++{0x60b8, 0x82},
++{0x60b9, 0x5c},
++{0x60ba, 0xd4},
++{0x60bb, 0x8b},
++{0x60bc, 0x9d},
++{0x60bd, 0xd3},
++{0x60be, 0x21},
++{0x60bf, 0xb0},
++{0x60c0, 0xb0},
++{0x60c1, 0xb7},
++{0x60c2, 0x05},
++{0x60c3, 0xd3},
++{0x60c4, 0x0a},
++{0x60c5, 0xd3},
++{0x60c6, 0x10},
++{0x60c7, 0x9c},
++{0x60c8, 0x94},
++{0x60c9, 0x90},
++{0x60ca, 0xc8},
++{0x60cb, 0xba},
++{0x60cc, 0x7c},
++{0x60cd, 0x74},
++{0x60ce, 0x00},
++{0x60cf, 0x61},
++{0x60d0, 0x2a},
++{0x60d1, 0x00},
++{0x60d2, 0xd2},
++{0x60d3, 0xcc},
++{0x60d4, 0xdf},
++{0x60d5, 0xc4},
++{0x60d6, 0x35},
++{0x60d7, 0xd3},
++{0x60d8, 0x13},
++{0x60d9, 0xd2},
++{0x60da, 0xcc},
++{0x60db, 0x06},
++{0x60dc, 0x31},
++{0x60dd, 0xd2},
++{0x60de, 0xcc},
++{0x60df, 0x15},
++{0x60e0, 0xd2},
++{0x60e1, 0xbb},
++{0x60e2, 0xcc},
++{0x60e3, 0x1a},
++{0x60e4, 0xd2},
++{0x60e5, 0xbe},
++{0x60e6, 0xce},
++{0x60e7, 0x52},
++{0x60e8, 0xcf},
++{0x60e9, 0x56},
++{0x60ea, 0xd0},
++{0x60eb, 0x5b},
++{0x60ec, 0x2b},
++{0x60ed, 0xd2},
++{0x60ee, 0xd3},
++{0x60ef, 0x01},
++{0x60f0, 0xcc},
++{0x60f1, 0x0a},
++{0x60f2, 0xd2},
++{0x60f3, 0xd3},
++{0x60f4, 0x0f},
++{0x60f5, 0xd9},
++{0x60f6, 0xb4},
++{0x60f7, 0xda},
++{0x60f8, 0xbb},
++{0x60f9, 0x1a},
++{0x60fa, 0xd4},
++{0x60fb, 0xe3},
++{0x60fc, 0xd4},
++{0x60fd, 0x96},
++{0x60fe, 0x27},
++{0x60ff, 0x00},
++{0x6100, 0xd2},
++{0x6101, 0xcc},
++{0x6102, 0x60},
++{0x6103, 0xd2},
++{0x6104, 0xd3},
++{0x6105, 0x2d},
++{0x6106, 0xd9},
++{0x6107, 0xcc},
++{0x6108, 0xda},
++{0x6109, 0xd2},
++{0x610a, 0x1a},
++{0x610b, 0x12},
++{0x610c, 0xcc},
++{0x610d, 0x88},
++{0x610e, 0xd6},
++{0x610f, 0x9e},
++{0x6110, 0xb9},
++{0x6111, 0xba},
++{0x6112, 0xaf},
++{0x6113, 0xdc},
++{0x6114, 0x00},
++{0x6115, 0xd5},
++{0x6116, 0xba},
++{0x6117, 0x00},
++{0x6118, 0x00},
++{0x6119, 0x00},
++{0x611a, 0x00},
++{0x611b, 0x00},
++{0x611c, 0x00},
++{0x611d, 0x00},
++{0x611e, 0x00},
++{0x611f, 0xaa},
++{0x6120, 0xaa},
++{0x6121, 0xb7},
++{0x6122, 0x00},
++{0x6123, 0x00},
++{0x6124, 0x00},
++{0x6125, 0x00},
++{0x6126, 0x00},
++{0x6127, 0xa6},
++{0x6128, 0xa6},
++{0x6129, 0xb7},
++{0x612a, 0x00},
++{0x612b, 0xd5},
++{0x612c, 0x71},
++{0x612d, 0xd3},
++{0x612e, 0x30},
++{0x612f, 0xba},
++{0x6130, 0x00},
++{0x6131, 0x00},
++{0x6132, 0x00},
++{0x6133, 0x00},
++{0x6134, 0xd3},
++{0x6135, 0x10},
++{0x6136, 0x70},
++{0x6137, 0x00},
++{0x6138, 0x00},
++{0x6139, 0x00},
++{0x613a, 0x00},
++{0x613b, 0xd5},
++{0x613c, 0xba},
++{0x613d, 0xb0},
++{0x613e, 0xb0},
++{0x613f, 0xb7},
++{0x6140, 0x9d},
++{0x6141, 0x02},
++{0x6142, 0xd3},
++{0x6143, 0x0a},
++{0x6144, 0x9d},
++{0x6145, 0x9d},
++{0x6146, 0xd3},
++{0x6147, 0x10},
++{0x6148, 0x9c},
++{0x6149, 0x94},
++{0x614a, 0x90},
++{0x614b, 0xc8},
++{0x614c, 0xba},
++{0x614d, 0xd2},
++{0x614e, 0x60},
++{0x614f, 0x2c},
++{0x6150, 0x50},
++{0x6151, 0x11},
++{0x6152, 0xcc},
++{0x6153, 0x00},
++{0x6154, 0x30},
++{0x6155, 0xd5},
++{0x6156, 0xba},
++{0x6157, 0xb0},
++{0x6158, 0xb0},
++{0x6159, 0xb7},
++{0x615a, 0x9d},
++{0x615b, 0x02},
++{0x615c, 0xd3},
++{0x615d, 0x0a},
++{0x615e, 0x9d},
++{0x615f, 0x9d},
++{0x6160, 0xd3},
++{0x6161, 0x10},
++{0x6162, 0x9c},
++{0x6163, 0x94},
++{0x6164, 0x90},
++{0x6165, 0xc8},
++{0x6166, 0xba},
++{0x6167, 0xd5},
++{0x6168, 0x01},
++{0x6169, 0x1a},
++{0x616a, 0xcc},
++{0x616b, 0x12},
++{0x616c, 0x12},
++{0x616d, 0x00},
++{0x616e, 0xcc},
++{0x616f, 0x9c},
++{0x6170, 0xd2},
++{0x6171, 0xcc},
++{0x6172, 0x60},
++{0x6173, 0xd2},
++{0x6174, 0x04},
++{0x6175, 0xd5},
++{0x6176, 0x1a},
++{0x6177, 0xcc},
++{0x6178, 0x12},
++{0x6179, 0x00},
++{0x617a, 0x12},
++{0x617b, 0xcc},
++{0x617c, 0x9c},
++{0x617d, 0xd2},
++{0x617e, 0xcc},
++{0x617f, 0x60},
++{0x6180, 0xd2},
++{0x6181, 0x1a},
++{0x6182, 0xcc},
++{0x6183, 0x12},
++{0x6184, 0x00},
++{0x6185, 0x12},
++{0x6186, 0xcc},
++{0x6187, 0x9c},
++{0x6188, 0xd2},
++{0x6189, 0xcc},
++{0x618a, 0x60},
++{0x618b, 0xd2},
++{0x618c, 0x1a},
++{0x618d, 0xcc},
++{0x618e, 0x12},
++{0x618f, 0x00},
++{0x6190, 0x12},
++{0x6191, 0xcc},
++{0x6192, 0x9c},
++{0x6193, 0xd2},
++{0x6194, 0xcc},
++{0x6195, 0x60},
++{0x6196, 0xd2},
++{0x6197, 0xd5},
++{0x6198, 0x1a},
++{0x6199, 0xcc},
++{0x619a, 0x12},
++{0x619b, 0x12},
++{0x619c, 0x00},
++{0x619d, 0xcc},
++{0x619e, 0x8a},
++{0x619f, 0xd2},
++{0x61a0, 0xcc},
++{0x61a1, 0x74},
++{0x61a2, 0xd2},
++{0x61a3, 0xd5},
++{0x61a4, 0x1a},
++{0x61a5, 0xcc},
++{0x61a6, 0x12},
++{0x61a7, 0x00},
++{0x61a8, 0x12},
++{0x61a9, 0xcc},
++{0x61aa, 0x8a},
++{0x61ab, 0xd2},
++{0x61ac, 0xcc},
++{0x61ad, 0x74},
++{0x61ae, 0xd2},
++{0x61af, 0x1a},
++{0x61b0, 0xcc},
++{0x61b1, 0x12},
++{0x61b2, 0x00},
++{0x61b3, 0x12},
++{0x61b4, 0xcc},
++{0x61b5, 0x8a},
++{0x61b6, 0xd2},
++{0x61b7, 0xcc},
++{0x61b8, 0x74},
++{0x61b9, 0xd2},
++{0x61ba, 0x1a},
++{0x61bb, 0xcc},
++{0x61bc, 0x12},
++{0x61bd, 0x00},
++{0x61be, 0x12},
++{0x61bf, 0xcc},
++{0x61c0, 0x8a},
++{0x61c1, 0xd2},
++{0x61c2, 0xcc},
++{0x61c3, 0x74},
++{0x61c4, 0xd2},
++{0x61c5, 0xd5},
++{0x61c6, 0xcc},
++{0x61c7, 0x12},
++{0x61c8, 0x00},
++{0x61c9, 0x12},
++{0x61ca, 0xcc},
++{0x61cb, 0x9c},
++{0x61cc, 0xd5},
++{0x6400, 0x04},
++{0x6401, 0x04},
++{0x6402, 0x00},
++{0x6403, 0xff},
++{0x6404, 0x00},
++{0x6405, 0x08},
++{0x6406, 0x00},
++{0x6407, 0xff},
++{0x6408, 0x04},
++{0x6409, 0x70},
++{0x640a, 0x00},
++{0x640b, 0xff},
++{0x640c, 0x05},
++{0x640d, 0x14},
++{0x640e, 0x04},
++{0x640f, 0x71},
++{0x6410, 0x05},
++{0x6411, 0x74},
++{0x6412, 0x00},
++{0x6413, 0xff},
++{0x6414, 0x05},
++{0x6415, 0x54},
++{0x6416, 0x05},
++{0x6417, 0x44},
++{0x6418, 0x04},
++{0x6419, 0x30},
++{0x641a, 0x05},
++{0x641b, 0x46},
++{0x641c, 0x00},
++{0x641d, 0xff},
++{0x641e, 0x04},
++{0x641f, 0x31},
++{0x6420, 0x04},
++{0x6421, 0x30},
++{0x6422, 0x00},
++{0x6423, 0xff},
++{0x6424, 0x04},
++{0x6425, 0x20},
++{0x6426, 0x05},
++{0x6427, 0x06},
++{0x6428, 0x00},
++{0x6429, 0xff},
++{0x642a, 0x08},
++{0x642b, 0x2a},
++{0x642c, 0x08},
++{0x642d, 0x31},
++{0x642e, 0x00},
++{0x642f, 0xff},
++{0x6430, 0x08},
++{0x6431, 0x2a},
++{0x6432, 0x08},
++{0x6433, 0x31},
++{0x6434, 0x06},
++{0x6435, 0x20},
++{0x6436, 0x07},
++{0x6437, 0x00},
++{0x6438, 0x08},
++{0x6439, 0x40},
++{0x643a, 0x00},
++{0x643b, 0xff},
++{0x643c, 0x08},
++{0x643d, 0x2a},
++{0x643e, 0x08},
++{0x643f, 0x36},
++{0x6440, 0x06},
++{0x6441, 0x10},
++{0x6442, 0x07},
++{0x6443, 0x00},
++{0x6444, 0x08},
++{0x6445, 0x40},
++{0x6446, 0x00},
++{0x6447, 0xff},
++{0x6448, 0x08},
++{0x6449, 0x2a},
++{0x644a, 0x08},
++{0x644b, 0x3b},
++{0x644c, 0x06},
++{0x644d, 0x00},
++{0x644e, 0x07},
++{0x644f, 0x00},
++{0x6450, 0x08},
++{0x6451, 0x40},
++{0x6452, 0x00},
++{0x6453, 0xff},
++{0x6454, 0x06},
++{0x6455, 0x00},
++{0x6456, 0x07},
++{0x6457, 0x05},
++{0x6458, 0x01},
++{0x6459, 0xaf},
++{0x645a, 0x01},
++{0x645b, 0x0f},
++{0x645c, 0x01},
++{0x645d, 0x90},
++{0x645e, 0x01},
++{0x645f, 0xc8},
++{0x6460, 0x00},
++{0x6461, 0xff},
++{0x6462, 0x01},
++{0x6463, 0xac},
++{0x6464, 0x01},
++{0x6465, 0x0c},
++{0x6466, 0x01},
++{0x6467, 0x90},
++{0x6468, 0x01},
++{0x6469, 0xe8},
++{0x646a, 0x00},
++{0x646b, 0xff},
++{0x646c, 0x01},
++{0x646d, 0xad},
++{0x646e, 0x01},
++{0x646f, 0x0d},
++{0x6470, 0x01},
++{0x6471, 0x90},
++{0x6472, 0x01},
++{0x6473, 0xe8},
++{0x6474, 0x00},
++{0x6475, 0xff},
++{0x6476, 0x01},
++{0x6477, 0xae},
++{0x6478, 0x01},
++{0x6479, 0x0e},
++{0x647a, 0x01},
++{0x647b, 0x90},
++{0x647c, 0x01},
++{0x647d, 0xe8},
++{0x647e, 0x00},
++{0x647f, 0xff},
++{0x6480, 0x01},
++{0x6481, 0xb0},
++{0x6482, 0x01},
++{0x6483, 0xb1},
++{0x6484, 0x01},
++{0x6485, 0xb2},
++{0x6486, 0x01},
++{0x6487, 0xb3},
++{0x6488, 0x01},
++{0x6489, 0xb4},
++{0x648a, 0x01},
++{0x648b, 0xb5},
++{0x648c, 0x01},
++{0x648d, 0xb6},
++{0x648e, 0x01},
++{0x648f, 0xb7},
++{0x6490, 0x01},
++{0x6491, 0xb8},
++{0x6492, 0x01},
++{0x6493, 0xb9},
++{0x6494, 0x01},
++{0x6495, 0xba},
++{0x6496, 0x01},
++{0x6497, 0xbb},
++{0x6498, 0x01},
++{0x6499, 0xbc},
++{0x649a, 0x01},
++{0x649b, 0xbd},
++{0x649c, 0x01},
++{0x649d, 0xbe},
++{0x649e, 0x01},
++{0x649f, 0xbf},
++{0x64a0, 0x01},
++{0x64a1, 0xc0},
++{0x64a2, 0x00},
++{0x64a3, 0xff},
++{0x64a4, 0x06},
++{0x64a5, 0x00},
++{0x64a6, 0x01},
++{0x64a7, 0xf6},
++{0x64a8, 0x04},
++{0x64a9, 0x30},
++{0x64aa, 0x00},
++{0x64ab, 0xff},
++{0x64ac, 0x06},
++{0x64ad, 0x10},
++{0x64ae, 0x01},
++{0x64af, 0xf6},
++{0x64b0, 0x04},
++{0x64b1, 0x30},
++{0x64b2, 0x06},
++{0x64b3, 0x00},
++{0x64b4, 0x00},
++{0x64b5, 0xff},
++{0x64b6, 0x06},
++{0x64b7, 0x20},
++{0x64b8, 0x01},
++{0x64b9, 0xf6},
++{0x64ba, 0x04},
++{0x64bb, 0x30},
++{0x64bc, 0x06},
++{0x64bd, 0x00},
++{0x64be, 0x00},
++{0x64bf, 0xff},
++{0x64c0, 0x04},
++{0x64c1, 0x31},
++{0x64c2, 0x04},
++{0x64c3, 0x30},
++{0x64c4, 0x01},
++{0x64c5, 0x20},
++{0x64c6, 0x01},
++{0x64c7, 0x31},
++{0x64c8, 0x01},
++{0x64c9, 0x32},
++{0x64ca, 0x01},
++{0x64cb, 0x33},
++{0x64cc, 0x01},
++{0x64cd, 0x34},
++{0x64ce, 0x01},
++{0x64cf, 0x35},
++{0x64d0, 0x01},
++{0x64d1, 0x36},
++{0x64d2, 0x01},
++{0x64d3, 0x37},
++{0x64d4, 0x01},
++{0x64d5, 0x38},
++{0x64d6, 0x01},
++{0x64d7, 0x39},
++{0x64d8, 0x01},
++{0x64d9, 0x3a},
++{0x64da, 0x01},
++{0x64db, 0x3b},
++{0x64dc, 0x01},
++{0x64dd, 0x3c},
++{0x64de, 0x01},
++{0x64df, 0x3d},
++{0x64e0, 0x01},
++{0x64e1, 0x3e},
++{0x64e2, 0x01},
++{0x64e3, 0x3f},
++{0x64e4, 0x02},
++{0x64e5, 0xa0},
++{0x64e6, 0x00},
++{0x64e7, 0xff},
++{0x64e8, 0x04},
++{0x64e9, 0x31},
++{0x64ea, 0x04},
++{0x64eb, 0x30},
++{0x64ec, 0x01},
++{0x64ed, 0x00},
++{0x64ee, 0x01},
++{0x64ef, 0x11},
++{0x64f0, 0x01},
++{0x64f1, 0x12},
++{0x64f2, 0x01},
++{0x64f3, 0x13},
++{0x64f4, 0x01},
++{0x64f5, 0x14},
++{0x64f6, 0x01},
++{0x64f7, 0x15},
++{0x64f8, 0x01},
++{0x64f9, 0x16},
++{0x64fa, 0x01},
++{0x64fb, 0x17},
++{0x64fc, 0x01},
++{0x64fd, 0x18},
++{0x64fe, 0x01},
++{0x64ff, 0x19},
++{0x6500, 0x01},
++{0x6501, 0x1a},
++{0x6502, 0x01},
++{0x6503, 0x1b},
++{0x6504, 0x01},
++{0x6505, 0x1c},
++{0x6506, 0x01},
++{0x6507, 0x1d},
++{0x6508, 0x01},
++{0x6509, 0x1e},
++{0x650a, 0x01},
++{0x650b, 0x1f},
++{0x650c, 0x02},
++{0x650d, 0xa0},
++{0x650e, 0x00},
++{0x650f, 0xff},
++{0x6510, 0x04},
++{0x6511, 0x20},
++{0x6512, 0x05},
++{0x6513, 0x86},
++{0x6514, 0x03},
++{0x6515, 0x0b},
++{0x6516, 0x05},
++{0x6517, 0x86},
++{0x6518, 0x00},
++{0x6519, 0x00},
++{0x651a, 0x05},
++{0x651b, 0x06},
++{0x651c, 0x00},
++{0x651d, 0x04},
++{0x651e, 0x05},
++{0x651f, 0x04},
++{0x6520, 0x00},
++{0x6521, 0x04},
++{0x6522, 0x05},
++{0x6523, 0x00},
++{0x6524, 0x05},
++{0x6525, 0x0a},
++{0x6526, 0x03},
++{0x6527, 0x9a},
++{0x6528, 0x05},
++{0x6529, 0x86},
++{0x652a, 0x00},
++{0x652b, 0x00},
++{0x652c, 0x05},
++{0x652d, 0x06},
++{0x652e, 0x00},
++{0x652f, 0x01},
++{0x6530, 0x05},
++{0x6531, 0x04},
++{0x6532, 0x00},
++{0x6533, 0x04},
++{0x6534, 0x05},
++{0x6535, 0x00},
++{0x6536, 0x05},
++{0x6537, 0x0a},
++{0x6538, 0x03},
++{0x6539, 0x99},
++{0x653a, 0x05},
++{0x653b, 0x06},
++{0x653c, 0x00},
++{0x653d, 0x00},
++{0x653e, 0x05},
++{0x653f, 0x04},
++{0x6540, 0x00},
++{0x6541, 0x04},
++{0x6542, 0x05},
++{0x6543, 0x00},
++{0x6544, 0x05},
++{0x6545, 0x0a},
++{0x6546, 0x03},
++{0x6547, 0x98},
++{0x6548, 0x05},
++{0x6549, 0x06},
++{0x654a, 0x00},
++{0x654b, 0x00},
++{0x654c, 0x05},
++{0x654d, 0x04},
++{0x654e, 0x00},
++{0x654f, 0x04},
++{0x6550, 0x05},
++{0x6551, 0x00},
++{0x6552, 0x05},
++{0x6553, 0x0a},
++{0x6554, 0x03},
++{0x6555, 0x97},
++{0x6556, 0x05},
++{0x6557, 0x06},
++{0x6558, 0x05},
++{0x6559, 0x04},
++{0x655a, 0x00},
++{0x655b, 0x04},
++{0x655c, 0x05},
++{0x655d, 0x00},
++{0x655e, 0x05},
++{0x655f, 0x0a},
++{0x6560, 0x03},
++{0x6561, 0x96},
++{0x6562, 0x05},
++{0x6563, 0x06},
++{0x6564, 0x05},
++{0x6565, 0x04},
++{0x6566, 0x00},
++{0x6567, 0x04},
++{0x6568, 0x05},
++{0x6569, 0x00},
++{0x656a, 0x05},
++{0x656b, 0x0a},
++{0x656c, 0x03},
++{0x656d, 0x95},
++{0x656e, 0x05},
++{0x656f, 0x06},
++{0x6570, 0x05},
++{0x6571, 0x04},
++{0x6572, 0x00},
++{0x6573, 0x04},
++{0x6574, 0x05},
++{0x6575, 0x00},
++{0x6576, 0x05},
++{0x6577, 0x0a},
++{0x6578, 0x03},
++{0x6579, 0x94},
++{0x657a, 0x05},
++{0x657b, 0x06},
++{0x657c, 0x00},
++{0x657d, 0x00},
++{0x657e, 0x05},
++{0x657f, 0x04},
++{0x6580, 0x00},
++{0x6581, 0x04},
++{0x6582, 0x05},
++{0x6583, 0x00},
++{0x6584, 0x05},
++{0x6585, 0x0a},
++{0x6586, 0x03},
++{0x6587, 0x93},
++{0x6588, 0x05},
++{0x6589, 0x06},
++{0x658a, 0x00},
++{0x658b, 0x00},
++{0x658c, 0x05},
++{0x658d, 0x04},
++{0x658e, 0x00},
++{0x658f, 0x04},
++{0x6590, 0x05},
++{0x6591, 0x00},
++{0x6592, 0x05},
++{0x6593, 0x0a},
++{0x6594, 0x03},
++{0x6595, 0x92},
++{0x6596, 0x05},
++{0x6597, 0x06},
++{0x6598, 0x05},
++{0x6599, 0x04},
++{0x659a, 0x00},
++{0x659b, 0x04},
++{0x659c, 0x05},
++{0x659d, 0x00},
++{0x659e, 0x05},
++{0x659f, 0x0a},
++{0x65a0, 0x03},
++{0x65a1, 0x91},
++{0x65a2, 0x05},
++{0x65a3, 0x06},
++{0x65a4, 0x05},
++{0x65a5, 0x04},
++{0x65a6, 0x00},
++{0x65a7, 0x04},
++{0x65a8, 0x05},
++{0x65a9, 0x00},
++{0x65aa, 0x05},
++{0x65ab, 0x0a},
++{0x65ac, 0x03},
++{0x65ad, 0x90},
++{0x65ae, 0x05},
++{0x65af, 0x06},
++{0x65b0, 0x05},
++{0x65b1, 0x04},
++{0x65b2, 0x00},
++{0x65b3, 0x04},
++{0x65b4, 0x05},
++{0x65b5, 0x00},
++{0x65b6, 0x05},
++{0x65b7, 0x0a},
++{0x65b8, 0x02},
++{0x65b9, 0x90},
++{0x65ba, 0x05},
++{0x65bb, 0x06},
++{0x65bc, 0x00},
++{0x65bd, 0xff},
++{0x65be, 0x04},
++{0x65bf, 0x70},
++{0x65c0, 0x08},
++{0x65c1, 0x76},
++{0x65c2, 0x00},
++{0x65c3, 0xff},
++{0x65c4, 0x08},
++{0x65c5, 0x76},
++{0x65c6, 0x04},
++{0x65c7, 0x0c},
++{0x65c8, 0x05},
++{0x65c9, 0x07},
++{0x65ca, 0x04},
++{0x65cb, 0x04},
++{0x65cc, 0x00},
++{0x65cd, 0xff},
++{0x65ce, 0x00},
++{0x65cf, 0xff},
++{0x65d0, 0x00},
++{0x65d1, 0xff},
++{0x30eb, 0x04},
++{0x30ed, 0x5a},
++{0x30ee, 0x01},
++{0x30ef, 0x80},
++{0x30f1, 0x5a},
++{0x303a, 0x04},
++{0x303b, 0x7f},
++{0x303c, 0xfe},
++{0x303d, 0x19},
++{0x303e, 0xd7},
++{0x303f, 0x09},
++{0x3040, 0x78},
++{0x3042, 0x05},
++{0x328a, 0x10},
++{0x3012, 0x01}, // stream on
++};
++
++/* DVP_1280x1080_COMB12_raw 30fps */
++static const struct ov10640_reg ov10640_regs_wizard_r1e[] = {
++/* ov10640_R1E_setting_3x12_1280x1080_MIPIin_4lane_raw */
++{0x3013, 0x01},
++{OV10640_DELAY, 10},
++{0x328a, 0x11},
++{0x313f, 0x80},
++{0x3132, 0x24},
++
++/* PLL settings */
++{0x3000, 0x03},
++{0x3001, 0x60},
++{0x3002, 0x0f},
++{0x3004, 0x03},
++{0x3005, 0x44},
++{0x3006, 0x07},
++{0x3007, 0x01},
++
++{0x3014, 0x03},
++{0x3023, 0x05},
++{0x3032, 0x35},
++{0x3033, 0x04},
++{0x3054, 0x00},
++{0x3055, 0x03},
++{0x3056, 0x01},
++{0x3057, 0xff},
++{0x3058, 0xaf},
++{0x3059, 0x44},
++{0x305a, 0x02},
++{0x305b, 0x00},
++{0x305c, 0x30},
++{0x305d, 0x9c},
++{0x305e, 0x19},
++{0x305f, 0x18},
++{0x3060, 0xf9},
++{0x3061, 0xf0},
++{0x308a, 0x00},
++{0x308b, 0x00},
++#ifdef OV10640_FSIN_ENABLE
++{0x308c, 0xb2},
++#else
++{0x308c, 0x03},
++#endif
++{0x308f, 0x10},
++{0x3090, 0x04}, /* c:enable flip and mirror */
++{0x3091, 0x00},
++{0x30eb, 0x00},
++{0x30a3, 0x08},
++{0x30ad, 0x03},
++{0x30ae, 0x80},
++{0x30af, 0x80},
++{0x30b0, 0xff},
++{0x30b1, 0x3f},
++{0x30b2, 0x22},
++{0x30b9, 0x22},
++{0x30bb, 0x00},
++{0x30bc, 0x00},
++{0x30bd, 0x00},
++{0x30be, 0x00},
++{0x30bf, 0x00},
++{0x30c0, 0x00},
++{0x30c1, 0x00},
++{0x30c2, 0x00},
++{0x30c3, 0x00},
++{0x30c4, 0x80},
++{0x30c5, 0x00},
++{0x30c6, 0x80},
++{0x30c7, 0x00},
++{0x30c8, 0x80},
++{0x3119, 0x49},
++{0x311a, 0x01},
++{0x311b, 0x4a},
++
++/* Crop Setting */
++{0x3074, 0x00}, // crop_h_start
++{0x3075, 0x00},
++{0x3076, 0x00}, // crop_v_start
++{0x3077, 0xf0},
++{0x3078, 0x05}, // crop_h_end
++{0x3079, 0x09},
++{0x307a, 0x04}, // crop_v_end
++{0x307b, 0x18},
++{0x307c, 0x05}, // dvp_h_size
++{0x307d, 0x08},
++{0x307e, 0x03}, // dvp_v_size
++{0x307f, 0x28},
++{0x3080, 0x07}, // hts
++{0x3081, 0x44},
++{0x3082, 0x03}, // vts
++{0x3083, 0x5c},
++{0x3084, 0x00}, // win_hoffs
++{0x3085, 0x00},
++{0x3086, 0x00}, // win_voffs
++{0x3087, 0x00},
++
++{0x3088, 0x00},
++{0x3089, 0x40},
++{0x308d, 0x92},
++{0x3094, 0xa5},
++{0x30e6, 0x04},
++{0x30e7, 0x48},
++{0x30e8, 0x04},
++{0x30e9, 0x48},
++{0x30e9, 0x05},
++{0x30ec, 0x01},
++{0x30fa, 0x06},
++{0x3120, 0x00},
++{0x3121, 0x20}, /* VSYNC delay */
++{0x3122, 0x00},
++{0x3127, 0x43}, /* 43 :dpc off, 63 */
++{0x3128, 0xc0},
++#ifdef OV10640_DISPLAY_PATTERN
++{0x3129, 0x80},
++#else
++{0x3129, 0x00},
++#endif
++{0x31be, 0x00},
++{0x30a5, 0x78},
++{0x30a6, 0x40},
++{0x30a7, 0x78},
++{0x30a8, 0x80},
++{0x30a9, 0x78},
++{0x30aa, 0xe0},
++{0x30ab, 0xf9},
++{0x30ac, 0xc0},
++{0x3440, 0x04},
++{0x3444, 0x28},
++{0x344e, 0x2c},
++{0x3457, 0x33},
++{0x345e, 0x38},
++{0x3461, 0xa8},
++{0x7002, 0xaa},
++{0x7001, 0xdf},
++{0x7048, 0x00},
++{0x7049, 0x02},
++{0x704a, 0x02},
++{0x704b, 0x00},
++{0x704c, 0x01},
++{0x704d, 0x00},
++{0x7043, 0x04},
++{0x7040, 0x3c},
++{0x7047, 0x00},
++{0x7044, 0x01},
++{0x7000, 0x1f},
++{0x7084, 0x01},
++{0x7085, 0x03},
++{0x7086, 0x02},
++{0x7087, 0x40},
++{0x7088, 0x01},
++{0x7089, 0x20},
++{0x707f, 0x04},
++{0x707c, 0x3c},
++{0x7083, 0x00},
++{0x7080, 0x01},
++{0x7003, 0xdf},
++{0x70c0, 0x00},
++{0x70c1, 0x02},
++{0x70c2, 0x02},
++{0x70c3, 0x00},
++{0x70c4, 0x01},
++{0x70c5, 0x00},
++{0x70b8, 0x03},
++{0x70b9, 0x98},
++{0x70bc, 0x00},
++{0x70bd, 0x80},
++{0x7004, 0x02},
++{0x7005, 0x00},
++{0x7006, 0x01},
++{0x7007, 0x80},
++{0x7008, 0x02},
++{0x7009, 0x00},
++{0x700a, 0x04},
++{0x700b, 0x00},
++{0x700e, 0x00},
++{0x700f, 0x60},
++{0x701a, 0x02},
++{0x701b, 0x00},
++{0x701c, 0x01},
++{0x701d, 0x80},
++{0x701e, 0x02},
++{0x701f, 0x00},
++{0x7020, 0x04},
++{0x7021, 0x00},
++{0x7024, 0x00},
++{0x7025, 0x60},
++{0x70e7, 0x00},
++{0x70e4, 0x10},
++{0x70e5, 0x00},
++{0x70e6, 0x00},
++{0x70eb, 0x00},
++{0x70e8, 0x10},
++{0x70e9, 0x00},
++{0x70ea, 0x00},
++{0x70ef, 0x00},
++{0x70ec, 0xfd},
++{0x70ed, 0x00},
++{0x70ee, 0x00},
++{0x70eb, 0x00},
++{0x70f0, 0xfd},
++{0x70f1, 0x00},
++{0x70f2, 0x00},
++{0x30fb, 0x06},
++{0x30fc, 0x80},
++{0x30fd, 0x02},
++{0x30fe, 0x93},
++{0x6000, 0xc1},
++{0x6001, 0xb9},
++{0x6002, 0xba},
++{0x6003, 0xa4},
++{0x6004, 0xb5},
++{0x6005, 0xa0},
++{0x6006, 0x82},
++{0x6007, 0xa7},
++{0x6008, 0xb7},
++{0x6009, 0x5c},
++{0x600a, 0x9e},
++{0x600b, 0xc0},
++{0x600c, 0xd2},
++{0x600d, 0x33},
++{0x600e, 0xcc},
++{0x600f, 0xe2},
++{0x6010, 0xc1},
++{0x6011, 0xab},
++{0x6012, 0xb7},
++{0x6013, 0x00},
++{0x6014, 0x00},
++{0x6015, 0x00},
++{0x6016, 0x00},
++{0x6017, 0x00},
++{0x6018, 0x00},
++{0x6019, 0x00},
++{0x601a, 0x00},
++{0x601b, 0x00},
++{0x601c, 0x00},
++{0x601d, 0x00},
++{0x601e, 0x9c},
++{0x601f, 0x94},
++{0x6020, 0x90},
++{0x6021, 0xc5},
++{0x6022, 0x01},
++{0x6023, 0x54},
++{0x6024, 0x2a},
++{0x6025, 0x61},
++{0x6026, 0xd2},
++{0x6027, 0xcc},
++{0x6028, 0x04},
++{0x6029, 0x35},
++{0x602a, 0xb1},
++{0x602b, 0xb2},
++{0x602c, 0xb3},
++{0x602d, 0xd2},
++{0x602e, 0xd3},
++{0x602f, 0x12},
++{0x6030, 0x31},
++{0x6031, 0xcc},
++{0x6032, 0x06},
++{0x6033, 0xd2},
++{0x6034, 0xc4},
++{0x6035, 0xce},
++{0x6036, 0x18},
++{0x6037, 0xcf},
++{0x6038, 0x1e},
++{0x6039, 0xd0},
++{0x603a, 0x24},
++{0x603b, 0xc5},
++{0x603c, 0xd2},
++{0x603d, 0xbc},
++{0x603e, 0xcc},
++{0x603f, 0x52},
++{0x6040, 0x2b},
++{0x6041, 0xd2},
++{0x6042, 0xd3},
++{0x6043, 0x02},
++{0x6044, 0xcc},
++{0x6045, 0x0a},
++{0x6046, 0xd2},
++{0x6047, 0xd3},
++{0x6048, 0x0f},
++{0x6049, 0x1a},
++{0x604a, 0x2a},
++{0x604b, 0xd4},
++{0x604c, 0xf6},
++{0x604d, 0xba},
++{0x604e, 0x56},
++{0x604f, 0xd3},
++{0x6050, 0x2e},
++{0x6051, 0x54},
++{0x6052, 0x26},
++{0x6053, 0xd2},
++{0x6054, 0xcc},
++{0x6055, 0x60},
++{0x6056, 0xd2},
++{0x6057, 0xd3},
++{0x6058, 0x27},
++{0x6059, 0x27},
++{0x605a, 0x08},
++{0x605b, 0x1a},
++{0x605c, 0xcc},
++{0x605d, 0x88},
++{0x605e, 0x00},
++{0x605f, 0x12},
++{0x6060, 0x2c},
++{0x6061, 0x60},
++{0x6062, 0xc2},
++{0x6063, 0xb9},
++{0x6064, 0xa5},
++{0x6065, 0xb5},
++{0x6066, 0xa0},
++{0x6067, 0x82},
++{0x6068, 0x5c},
++{0x6069, 0xd4},
++{0x606a, 0xbe},
++{0x606b, 0xd4},
++{0x606c, 0xbe},
++{0x606d, 0xd3},
++{0x606e, 0x01},
++{0x606f, 0x7c},
++{0x6070, 0x74},
++{0x6071, 0x00},
++{0x6072, 0x61},
++{0x6073, 0x2a},
++{0x6074, 0xd2},
++{0x6075, 0xcc},
++{0x6076, 0xdf},
++{0x6077, 0xc6},
++{0x6078, 0x35},
++{0x6079, 0xd2},
++{0x607a, 0xcc},
++{0x607b, 0x06},
++{0x607c, 0x31},
++{0x607d, 0xd2},
++{0x607e, 0xc5},
++{0x607f, 0xbb},
++{0x6080, 0xcc},
++{0x6081, 0x18},
++{0x6082, 0xc6},
++{0x6083, 0xd2},
++{0x6084, 0xbd},
++{0x6085, 0xcc},
++{0x6086, 0x52},
++{0x6087, 0x2b},
++{0x6088, 0xd2},
++{0x6089, 0xd3},
++{0x608a, 0x01},
++{0x608b, 0xcc},
++{0x608c, 0x0a},
++{0x608d, 0xd2},
++{0x608e, 0xd3},
++{0x608f, 0x0f},
++{0x6090, 0x1a},
++{0x6091, 0x71},
++{0x6092, 0x2a},
++{0x6093, 0xd4},
++{0x6094, 0xf6},
++{0x6095, 0xd3},
++{0x6096, 0x22},
++{0x6097, 0x70},
++{0x6098, 0xca},
++{0x6099, 0x26},
++{0x609a, 0xd2},
++{0x609b, 0xcc},
++{0x609c, 0x60},
++{0x609d, 0xd2},
++{0x609e, 0xd3},
++{0x609f, 0x27},
++{0x60a0, 0x27},
++{0x60a1, 0x08},
++{0x60a2, 0x1a},
++{0x60a3, 0xcc},
++{0x60a4, 0x88},
++{0x60a5, 0x12},
++{0x60a6, 0x2c},
++{0x60a7, 0x60},
++{0x60a8, 0x00},
++{0x60a9, 0x00},
++{0x60aa, 0xc0},
++{0x60ab, 0xb9},
++{0x60ac, 0xa3},
++{0x60ad, 0xb5},
++{0x60ae, 0x00},
++{0x60af, 0xa0},
++{0x60b0, 0x82},
++{0x60b1, 0x5c},
++{0x60b2, 0xd4},
++{0x60b3, 0xa0},
++{0x60b4, 0x9d},
++{0x60b5, 0xd3},
++{0x60b6, 0x26},
++{0x60b7, 0xb0},
++{0x60b8, 0xb7},
++{0x60b9, 0x00},
++{0x60ba, 0xd3},
++{0x60bb, 0x0a},
++{0x60bc, 0xd3},
++{0x60bd, 0x10},
++{0x60be, 0x9c},
++{0x60bf, 0x94},
++{0x60c0, 0x90},
++{0x60c1, 0xc8},
++{0x60c2, 0xba},
++{0x60c3, 0x7c},
++{0x60c4, 0x74},
++{0x60c5, 0x00},
++{0x60c6, 0x61},
++{0x60c7, 0x2a},
++{0x60c8, 0x00},
++{0x60c9, 0xd2},
++{0x60ca, 0xcc},
++{0x60cb, 0xdf},
++{0x60cc, 0xc4},
++{0x60cd, 0x35},
++{0x60ce, 0xd2},
++{0x60cf, 0xcc},
++{0x60d0, 0x06},
++{0x60d1, 0x31},
++{0x60d2, 0xd2},
++{0x60d3, 0xcc},
++{0x60d4, 0x15},
++{0x60d5, 0xd2},
++{0x60d6, 0xbb},
++{0x60d7, 0xcc},
++{0x60d8, 0x1a},
++{0x60d9, 0xd2},
++{0x60da, 0xbe},
++{0x60db, 0xce},
++{0x60dc, 0x52},
++{0x60dd, 0xcf},
++{0x60de, 0x56},
++{0x60df, 0xd0},
++{0x60e0, 0x5b},
++{0x60e1, 0x2b},
++{0x60e2, 0xd2},
++{0x60e3, 0xd3},
++{0x60e4, 0x01},
++{0x60e5, 0xcc},
++{0x60e6, 0x0a},
++{0x60e7, 0xd2},
++{0x60e8, 0xd3},
++{0x60e9, 0x0f},
++{0x60ea, 0xd9},
++{0x60eb, 0xc7},
++{0x60ec, 0xda},
++{0x60ed, 0xce},
++{0x60ee, 0x1a},
++{0x60ef, 0xd4},
++{0x60f0, 0xf6},
++{0x60f1, 0xd4},
++{0x60f2, 0xa9},
++{0x60f3, 0x27},
++{0x60f4, 0x00},
++{0x60f5, 0xd2},
++{0x60f6, 0xcc},
++{0x60f7, 0x60},
++{0x60f8, 0xd2},
++{0x60f9, 0xd3},
++{0x60fa, 0x2d},
++{0x60fb, 0xd9},
++{0x60fc, 0xdf},
++{0x60fd, 0xda},
++{0x60fe, 0xe5},
++{0x60ff, 0x1a},
++{0x6100, 0x12},
++{0x6101, 0xcc},
++{0x6102, 0x88},
++{0x6103, 0xd6},
++{0x6104, 0xb1},
++{0x6105, 0xb9},
++{0x6106, 0xba},
++{0x6107, 0xaf},
++{0x6108, 0xdc},
++{0x6109, 0x00},
++{0x610a, 0xcb},
++{0x610b, 0xc3},
++{0x610c, 0xb9},
++{0x610d, 0xa4},
++{0x610e, 0xb5},
++{0x610f, 0x5c},
++{0x6110, 0x12},
++{0x6111, 0x2a},
++{0x6112, 0x61},
++{0x6113, 0xd2},
++{0x6114, 0xcc},
++{0x6115, 0xdf},
++{0x6116, 0xc7},
++{0x6117, 0x35},
++{0x6118, 0xd2},
++{0x6119, 0xcc},
++{0x611a, 0x06},
++{0x611b, 0x31},
++{0x611c, 0xc6},
++{0x611d, 0xbb},
++{0x611e, 0xd2},
++{0x611f, 0xcc},
++{0x6120, 0x18},
++{0x6121, 0xd2},
++{0x6122, 0xbe},
++{0x6123, 0xcc},
++{0x6124, 0x52},
++{0x6125, 0xc7},
++{0x6126, 0xd2},
++{0x6127, 0xcc},
++{0x6128, 0x0a},
++{0x6129, 0xb4},
++{0x612a, 0xb7},
++{0x612b, 0x94},
++{0x612c, 0xd2},
++{0x612d, 0x12},
++{0x612e, 0x26},
++{0x612f, 0x42},
++{0x6130, 0x46},
++{0x6131, 0x42},
++{0x6132, 0xd3},
++{0x6133, 0x20},
++{0x6134, 0x27},
++{0x6135, 0x00},
++{0x6136, 0x1a},
++{0x6137, 0xcc},
++{0x6138, 0x88},
++{0x6139, 0x60},
++{0x613a, 0x2c},
++{0x613b, 0x12},
++{0x613c, 0x40},
++{0x613d, 0xb8},
++{0x613e, 0x90},
++{0x613f, 0xd5},
++{0x6140, 0xba},
++{0x6141, 0x00},
++{0x6142, 0x00},
++{0x6143, 0x00},
++{0x6144, 0x00},
++{0x6145, 0x00},
++{0x6146, 0x00},
++{0x6147, 0xaa},
++{0x6148, 0xb7},
++{0x6149, 0x00},
++{0x614a, 0x00},
++{0x614b, 0x00},
++{0x614c, 0x00},
++{0x614d, 0xa6},
++{0x614e, 0xb7},
++{0x614f, 0x00},
++{0x6150, 0xd5},
++{0x6151, 0x00},
++{0x6152, 0x71},
++{0x6153, 0xd3},
++{0x6154, 0x30},
++{0x6155, 0xba},
++{0x6156, 0x00},
++{0x6157, 0x00},
++{0x6158, 0x00},
++{0x6159, 0x00},
++{0x615a, 0xd3},
++{0x615b, 0x10},
++{0x615c, 0x70},
++{0x615d, 0x00},
++{0x615e, 0x00},
++{0x615f, 0x00},
++{0x6160, 0x00},
++{0x6161, 0xd5},
++{0x6162, 0xba},
++{0x6163, 0xb0},
++{0x6164, 0xb7},
++{0x6165, 0x00},
++{0x6166, 0x9d},
++{0x6167, 0xd3},
++{0x6168, 0x0a},
++{0x6169, 0x9d},
++{0x616a, 0x9d},
++{0x616b, 0xd3},
++{0x616c, 0x10},
++{0x616d, 0x9c},
++{0x616e, 0x94},
++{0x616f, 0x90},
++{0x6170, 0xc8},
++{0x6171, 0xba},
++{0x6172, 0xd2},
++{0x6173, 0x60},
++{0x6174, 0x2c},
++{0x6175, 0x50},
++{0x6176, 0x11},
++{0x6177, 0xcc},
++{0x6178, 0x00},
++{0x6179, 0x30},
++{0x617a, 0xd5},
++{0x617b, 0x00},
++{0x617c, 0xba},
++{0x617d, 0xb0},
++{0x617e, 0xb7},
++{0x617f, 0x00},
++{0x6180, 0x9d},
++{0x6181, 0xd3},
++{0x6182, 0x0a},
++{0x6183, 0x9d},
++{0x6184, 0x9d},
++{0x6185, 0xd3},
++{0x6186, 0x10},
++{0x6187, 0x9c},
++{0x6188, 0x94},
++{0x6189, 0x90},
++{0x618a, 0xc8},
++{0x618b, 0xba},
++{0x618c, 0xd5},
++{0x618d, 0x00},
++{0x618e, 0x01},
++{0x618f, 0x1a},
++{0x6190, 0xcc},
++{0x6191, 0x12},
++{0x6192, 0x12},
++{0x6193, 0x00},
++{0x6194, 0xcc},
++{0x6195, 0x9c},
++{0x6196, 0xd2},
++{0x6197, 0xcc},
++{0x6198, 0x60},
++{0x6199, 0xd2},
++{0x619a, 0x04},
++{0x619b, 0xd5},
++{0x619c, 0x1a},
++{0x619d, 0xcc},
++{0x619e, 0x12},
++{0x619f, 0x00},
++{0x61a0, 0x12},
++{0x61a1, 0xcc},
++{0x61a2, 0x9c},
++{0x61a3, 0xd2},
++{0x61a4, 0xcc},
++{0x61a5, 0x60},
++{0x61a6, 0xd2},
++{0x61a7, 0x1a},
++{0x61a8, 0xcc},
++{0x61a9, 0x12},
++{0x61aa, 0x00},
++{0x61ab, 0x12},
++{0x61ac, 0xcc},
++{0x61ad, 0x9c},
++{0x61ae, 0xd2},
++{0x61af, 0xcc},
++{0x61b0, 0x60},
++{0x61b1, 0xd2},
++{0x61b2, 0x1a},
++{0x61b3, 0xcc},
++{0x61b4, 0x12},
++{0x61b5, 0x00},
++{0x61b6, 0x12},
++{0x61b7, 0xcc},
++{0x61b8, 0x9c},
++{0x61b9, 0xd2},
++{0x61ba, 0xcc},
++{0x61bb, 0x60},
++{0x61bc, 0xd2},
++{0x61bd, 0xd5},
++{0x61be, 0x1a},
++{0x61bf, 0xcc},
++{0x61c0, 0x12},
++{0x61c1, 0x12},
++{0x61c2, 0x00},
++{0x61c3, 0xcc},
++{0x61c4, 0x8a},
++{0x61c5, 0xd2},
++{0x61c6, 0xcc},
++{0x61c7, 0x74},
++{0x61c8, 0xd2},
++{0x61c9, 0xd5},
++{0x61ca, 0x1a},
++{0x61cb, 0xcc},
++{0x61cc, 0x12},
++{0x61cd, 0x00},
++{0x61ce, 0x12},
++{0x61cf, 0xcc},
++{0x61d0, 0x8a},
++{0x61d1, 0xd2},
++{0x61d2, 0xcc},
++{0x61d3, 0x74},
++{0x61d4, 0xd2},
++{0x61d5, 0x1a},
++{0x61d6, 0xcc},
++{0x61d7, 0x12},
++{0x61d8, 0x00},
++{0x61d9, 0x12},
++{0x61da, 0xcc},
++{0x61db, 0x8a},
++{0x61dc, 0xd2},
++{0x61dd, 0xcc},
++{0x61de, 0x74},
++{0x61df, 0xd2},
++{0x61e0, 0x1a},
++{0x61e1, 0xcc},
++{0x61e2, 0x12},
++{0x61e3, 0x00},
++{0x61e4, 0x12},
++{0x61e5, 0xcc},
++{0x61e6, 0x8a},
++{0x61e7, 0xd2},
++{0x61e8, 0xcc},
++{0x61e9, 0x74},
++{0x61ea, 0xd2},
++{0x61eb, 0xd5},
++{0x61ec, 0xcc},
++{0x61ed, 0x12},
++{0x61ee, 0x00},
++{0x61ef, 0x12},
++{0x61f0, 0xcc},
++{0x61f1, 0x9c},
++{0x61f2, 0xd5},
++{0x6400, 0x04},
++{0x6401, 0x04},
++{0x6402, 0x00},
++{0x6403, 0xff},
++{0x6404, 0x00},
++{0x6405, 0x08},
++{0x6406, 0x00},
++{0x6407, 0xff},
++{0x6408, 0x04},
++{0x6409, 0x70},
++{0x640a, 0x00},
++{0x640b, 0xff},
++{0x640c, 0x05},
++{0x640d, 0x14},
++{0x640e, 0x04},
++{0x640f, 0x71},
++{0x6410, 0x05},
++{0x6411, 0x74},
++{0x6412, 0x00},
++{0x6413, 0xff},
++{0x6414, 0x05},
++{0x6415, 0x54},
++{0x6416, 0x05},
++{0x6417, 0x44},
++{0x6418, 0x04},
++{0x6419, 0x30},
++{0x641a, 0x05},
++{0x641b, 0x46},
++{0x641c, 0x00},
++{0x641d, 0xff},
++{0x641e, 0x04},
++{0x641f, 0x31},
++{0x6420, 0x04},
++{0x6421, 0x30},
++{0x6422, 0x00},
++{0x6423, 0xff},
++{0x6424, 0x04},
++{0x6425, 0x20},
++{0x6426, 0x05},
++{0x6427, 0x06},
++{0x6428, 0x00},
++{0x6429, 0xff},
++{0x642a, 0x08},
++{0x642b, 0x2a},
++{0x642c, 0x08},
++{0x642d, 0x31},
++{0x642e, 0x00},
++{0x642f, 0xff},
++{0x6430, 0x08},
++{0x6431, 0x2a},
++{0x6432, 0x08},
++{0x6433, 0x31},
++{0x6434, 0x06},
++{0x6435, 0x20},
++{0x6436, 0x07},
++{0x6437, 0x00},
++{0x6438, 0x08},
++{0x6439, 0x40},
++{0x643a, 0x00},
++{0x643b, 0xff},
++{0x643c, 0x08},
++{0x643d, 0x2a},
++{0x643e, 0x08},
++{0x643f, 0x36},
++{0x6440, 0x06},
++{0x6441, 0x10},
++{0x6442, 0x07},
++{0x6443, 0x00},
++{0x6444, 0x08},
++{0x6445, 0x40},
++{0x6446, 0x00},
++{0x6447, 0xff},
++{0x6448, 0x08},
++{0x6449, 0x2a},
++{0x644a, 0x08},
++{0x644b, 0x3b},
++{0x644c, 0x06},
++{0x644d, 0x00},
++{0x644e, 0x07},
++{0x644f, 0x00},
++{0x6450, 0x08},
++{0x6451, 0x40},
++{0x6452, 0x00},
++{0x6453, 0xff},
++{0x6454, 0x06},
++{0x6455, 0x00},
++{0x6456, 0x07},
++{0x6457, 0x05},
++{0x6458, 0x01},
++{0x6459, 0xaf},
++{0x645a, 0x01},
++{0x645b, 0x0f},
++{0x645c, 0x01},
++{0x645d, 0x90},
++{0x645e, 0x01},
++{0x645f, 0xc8},
++{0x6460, 0x00},
++{0x6461, 0xff},
++{0x6462, 0x01},
++{0x6463, 0xac},
++{0x6464, 0x01},
++{0x6465, 0x0c},
++{0x6466, 0x01},
++{0x6467, 0x90},
++{0x6468, 0x01},
++{0x6469, 0xe8},
++{0x646a, 0x00},
++{0x646b, 0xff},
++{0x646c, 0x01},
++{0x646d, 0xad},
++{0x646e, 0x01},
++{0x646f, 0x0d},
++{0x6470, 0x01},
++{0x6471, 0x90},
++{0x6472, 0x01},
++{0x6473, 0xe8},
++{0x6474, 0x00},
++{0x6475, 0xff},
++{0x6476, 0x01},
++{0x6477, 0xae},
++{0x6478, 0x01},
++{0x6479, 0x0e},
++{0x647a, 0x01},
++{0x647b, 0x90},
++{0x647c, 0x01},
++{0x647d, 0xe8},
++{0x647e, 0x00},
++{0x647f, 0xff},
++{0x6480, 0x01},
++{0x6481, 0xb0},
++{0x6482, 0x01},
++{0x6483, 0xb1},
++{0x6484, 0x01},
++{0x6485, 0xb2},
++{0x6486, 0x01},
++{0x6487, 0xb3},
++{0x6488, 0x01},
++{0x6489, 0xb4},
++{0x648a, 0x01},
++{0x648b, 0xb5},
++{0x648c, 0x01},
++{0x648d, 0xb6},
++{0x648e, 0x01},
++{0x648f, 0xb7},
++{0x6490, 0x01},
++{0x6491, 0xb8},
++{0x6492, 0x01},
++{0x6493, 0xb9},
++{0x6494, 0x01},
++{0x6495, 0xba},
++{0x6496, 0x01},
++{0x6497, 0xbb},
++{0x6498, 0x01},
++{0x6499, 0xbc},
++{0x649a, 0x01},
++{0x649b, 0xbd},
++{0x649c, 0x01},
++{0x649d, 0xbe},
++{0x649e, 0x01},
++{0x649f, 0xbf},
++{0x64a0, 0x01},
++{0x64a1, 0xc0},
++{0x64a2, 0x00},
++{0x64a3, 0xff},
++{0x64a4, 0x06},
++{0x64a5, 0x00},
++{0x64a6, 0x01},
++{0x64a7, 0xf6},
++{0x64a8, 0x04},
++{0x64a9, 0x30},
++{0x64aa, 0x00},
++{0x64ab, 0xff},
++{0x64ac, 0x06},
++{0x64ad, 0x10},
++{0x64ae, 0x01},
++{0x64af, 0xf6},
++{0x64b0, 0x04},
++{0x64b1, 0x30},
++{0x64b2, 0x06},
++{0x64b3, 0x00},
++{0x64b4, 0x00},
++{0x64b5, 0xff},
++{0x64b6, 0x06},
++{0x64b7, 0x20},
++{0x64b8, 0x01},
++{0x64b9, 0xf6},
++{0x64ba, 0x04},
++{0x64bb, 0x30},
++{0x64bc, 0x06},
++{0x64bd, 0x00},
++{0x64be, 0x00},
++{0x64bf, 0xff},
++{0x64c0, 0x04},
++{0x64c1, 0x31},
++{0x64c2, 0x04},
++{0x64c3, 0x30},
++{0x64c4, 0x01},
++{0x64c5, 0x20},
++{0x64c6, 0x01},
++{0x64c7, 0x31},
++{0x64c8, 0x01},
++{0x64c9, 0x32},
++{0x64ca, 0x01},
++{0x64cb, 0x33},
++{0x64cc, 0x01},
++{0x64cd, 0x34},
++{0x64ce, 0x01},
++{0x64cf, 0x35},
++{0x64d0, 0x01},
++{0x64d1, 0x36},
++{0x64d2, 0x01},
++{0x64d3, 0x37},
++{0x64d4, 0x01},
++{0x64d5, 0x38},
++{0x64d6, 0x01},
++{0x64d7, 0x39},
++{0x64d8, 0x01},
++{0x64d9, 0x3a},
++{0x64da, 0x01},
++{0x64db, 0x3b},
++{0x64dc, 0x01},
++{0x64dd, 0x3c},
++{0x64de, 0x01},
++{0x64df, 0x3d},
++{0x64e0, 0x01},
++{0x64e1, 0x3e},
++{0x64e2, 0x01},
++{0x64e3, 0x3f},
++{0x64e4, 0x02},
++{0x64e5, 0xa0},
++{0x64e6, 0x00},
++{0x64e7, 0xff},
++{0x64e8, 0x04},
++{0x64e9, 0x31},
++{0x64ea, 0x04},
++{0x64eb, 0x30},
++{0x64ec, 0x01},
++{0x64ed, 0x00},
++{0x64ee, 0x01},
++{0x64ef, 0x11},
++{0x64f0, 0x01},
++{0x64f1, 0x12},
++{0x64f2, 0x01},
++{0x64f3, 0x13},
++{0x64f4, 0x01},
++{0x64f5, 0x14},
++{0x64f6, 0x01},
++{0x64f7, 0x15},
++{0x64f8, 0x01},
++{0x64f9, 0x16},
++{0x64fa, 0x01},
++{0x64fb, 0x17},
++{0x64fc, 0x01},
++{0x64fd, 0x18},
++{0x64fe, 0x01},
++{0x64ff, 0x19},
++{0x6500, 0x01},
++{0x6501, 0x1a},
++{0x6502, 0x01},
++{0x6503, 0x1b},
++{0x6504, 0x01},
++{0x6505, 0x1c},
++{0x6506, 0x01},
++{0x6507, 0x1d},
++{0x6508, 0x01},
++{0x6509, 0x1e},
++{0x650a, 0x01},
++{0x650b, 0x1f},
++{0x650c, 0x02},
++{0x650d, 0xa0},
++{0x650e, 0x00},
++{0x650f, 0xff},
++{0x6510, 0x04},
++{0x6511, 0x20},
++{0x6512, 0x05},
++{0x6513, 0x86},
++{0x6514, 0x03},
++{0x6515, 0x0b},
++{0x6516, 0x05},
++{0x6517, 0x86},
++{0x6518, 0x00},
++{0x6519, 0x00},
++{0x651a, 0x05},
++{0x651b, 0x06},
++{0x651c, 0x00},
++{0x651d, 0x04},
++{0x651e, 0x05},
++{0x651f, 0x04},
++{0x6520, 0x00},
++{0x6521, 0x04},
++{0x6522, 0x05},
++{0x6523, 0x00},
++{0x6524, 0x05},
++{0x6525, 0x0a},
++{0x6526, 0x03},
++{0x6527, 0x9a},
++{0x6528, 0x05},
++{0x6529, 0x86},
++{0x652a, 0x00},
++{0x652b, 0x00},
++{0x652c, 0x05},
++{0x652d, 0x06},
++{0x652e, 0x00},
++{0x652f, 0x01},
++{0x6530, 0x05},
++{0x6531, 0x04},
++{0x6532, 0x00},
++{0x6533, 0x04},
++{0x6534, 0x05},
++{0x6535, 0x00},
++{0x6536, 0x05},
++{0x6537, 0x0a},
++{0x6538, 0x03},
++{0x6539, 0x99},
++{0x653a, 0x05},
++{0x653b, 0x06},
++{0x653c, 0x00},
++{0x653d, 0x00},
++{0x653e, 0x05},
++{0x653f, 0x04},
++{0x6540, 0x00},
++{0x6541, 0x04},
++{0x6542, 0x05},
++{0x6543, 0x00},
++{0x6544, 0x05},
++{0x6545, 0x0a},
++{0x6546, 0x03},
++{0x6547, 0x98},
++{0x6548, 0x05},
++{0x6549, 0x06},
++{0x654a, 0x00},
++{0x654b, 0x00},
++{0x654c, 0x05},
++{0x654d, 0x04},
++{0x654e, 0x00},
++{0x654f, 0x04},
++{0x6550, 0x05},
++{0x6551, 0x00},
++{0x6552, 0x05},
++{0x6553, 0x0a},
++{0x6554, 0x03},
++{0x6555, 0x97},
++{0x6556, 0x05},
++{0x6557, 0x06},
++{0x6558, 0x05},
++{0x6559, 0x04},
++{0x655a, 0x00},
++{0x655b, 0x04},
++{0x655c, 0x05},
++{0x655d, 0x00},
++{0x655e, 0x05},
++{0x655f, 0x0a},
++{0x6560, 0x03},
++{0x6561, 0x96},
++{0x6562, 0x05},
++{0x6563, 0x06},
++{0x6564, 0x05},
++{0x6565, 0x04},
++{0x6566, 0x00},
++{0x6567, 0x04},
++{0x6568, 0x05},
++{0x6569, 0x00},
++{0x656a, 0x05},
++{0x656b, 0x0a},
++{0x656c, 0x03},
++{0x656d, 0x95},
++{0x656e, 0x05},
++{0x656f, 0x06},
++{0x6570, 0x05},
++{0x6571, 0x04},
++{0x6572, 0x00},
++{0x6573, 0x04},
++{0x6574, 0x05},
++{0x6575, 0x00},
++{0x6576, 0x05},
++{0x6577, 0x0a},
++{0x6578, 0x03},
++{0x6579, 0x94},
++{0x657a, 0x05},
++{0x657b, 0x06},
++{0x657c, 0x00},
++{0x657d, 0x00},
++{0x657e, 0x05},
++{0x657f, 0x04},
++{0x6580, 0x00},
++{0x6581, 0x04},
++{0x6582, 0x05},
++{0x6583, 0x00},
++{0x6584, 0x05},
++{0x6585, 0x0a},
++{0x6586, 0x03},
++{0x6587, 0x93},
++{0x6588, 0x05},
++{0x6589, 0x06},
++{0x658a, 0x00},
++{0x658b, 0x00},
++{0x658c, 0x05},
++{0x658d, 0x04},
++{0x658e, 0x00},
++{0x658f, 0x04},
++{0x6590, 0x05},
++{0x6591, 0x00},
++{0x6592, 0x05},
++{0x6593, 0x0a},
++{0x6594, 0x03},
++{0x6595, 0x92},
++{0x6596, 0x05},
++{0x6597, 0x06},
++{0x6598, 0x05},
++{0x6599, 0x04},
++{0x659a, 0x00},
++{0x659b, 0x04},
++{0x659c, 0x05},
++{0x659d, 0x00},
++{0x659e, 0x05},
++{0x659f, 0x0a},
++{0x65a0, 0x03},
++{0x65a1, 0x91},
++{0x65a2, 0x05},
++{0x65a3, 0x06},
++{0x65a4, 0x05},
++{0x65a5, 0x04},
++{0x65a6, 0x00},
++{0x65a7, 0x04},
++{0x65a8, 0x05},
++{0x65a9, 0x00},
++{0x65aa, 0x05},
++{0x65ab, 0x0a},
++{0x65ac, 0x03},
++{0x65ad, 0x90},
++{0x65ae, 0x05},
++{0x65af, 0x06},
++{0x65b0, 0x05},
++{0x65b1, 0x04},
++{0x65b2, 0x00},
++{0x65b3, 0x04},
++{0x65b4, 0x05},
++{0x65b5, 0x00},
++{0x65b6, 0x05},
++{0x65b7, 0x0a},
++{0x65b8, 0x02},
++{0x65b9, 0x90},
++{0x65ba, 0x05},
++{0x65bb, 0x06},
++{0x65bc, 0x00},
++{0x65bd, 0xff},
++{0x65be, 0x04},
++{0x65bf, 0x70},
++{0x65c0, 0x08},
++{0x65c1, 0x76},
++{0x65c2, 0x00},
++{0x65c3, 0xff},
++{0x65c4, 0x08},
++{0x65c5, 0x76},
++{0x65c6, 0x04},
++{0x65c7, 0x0c},
++{0x65c8, 0x05},
++{0x65c9, 0x07},
++{0x65ca, 0x04},
++{0x65cb, 0x04},
++{0x65cc, 0x00},
++{0x65cd, 0xff},
++{0x65ce, 0x00},
++{0x65cf, 0xff},
++{0x65d0, 0x00},
++{0x65d1, 0xff},
++{0x30eb, 0x04},
++{0x30ed, 0x5a},
++{0x30ee, 0x01},
++{0x30ef, 0x80},
++{0x30f1, 0x5a},
++{0x303a, 0x04},
++{0x303b, 0x7f},
++{0x303c, 0xfe},
++{0x303d, 0x19},
++{0x303e, 0xd7},
++{0x303f, 0x09},
++{0x3040, 0x78},
++{0x3042, 0x05},
++{0x328a, 0x10},
++
++{0x3291, 0x03}, /* 7:enable flip and mirror offset may on 20150330 */
++
++/* change settings to 1280x1080 COMB12 30 fps, 96MHz */
++{0x3012, 0x0},
++{0x3000, 0x3},
++{0x3001, 0x50},
++{0x3002, 0x0a},
++{0x3004, 0x3},
++{0x3005, 0x48},
++{0x3006, 0x7},
++{0x308f, 0x10},
++{0x3127, 0x63},
++{0x3074, OV10640_X_START >> 8},
++{0x3075, OV10640_X_START & 0xff},
++{0x3076, OV10640_Y_START >> 8},
++{0x3077, OV10640_Y_START & 0xff},
++{0x3078, OV10640_X_END >> 8},
++{0x3079, OV10640_X_END & 0xff},
++{0x307a, OV10640_Y_END >> 8},
++{0x307b, OV10640_Y_END & 0xff},
++{0x307c, OV10640_MAX_WIDTH >> 8},
++{0x307d, OV10640_MAX_WIDTH & 0xff},
++{0x307e, OV10640_MAX_HEIGHT >> 8},
++{0x307f, OV10640_MAX_HEIGHT & 0xff},
++{0x3080, (OV10640_SENSOR_WIDTH + 200) >> 8}, // HTS
++{0x3081, (OV10640_SENSOR_WIDTH + 200) & 0xff},
++{0x3082, (OV10640_SENSOR_HEIGHT + 208) >> 8}, //VTS
++{0x3083, (OV10640_SENSOR_HEIGHT + 208) & 0xff},
++{0x3084, 0x0},
++{0x3085, 0x0},
++{0x3086, 0x0},
++{0x3087, 0x0},
++{0x346d, 0x14},
++{0x3444, 0x28},
++{0x3091, 0x0},
++{0x3119, 0x44}, // COMB12
++{0x3012, 0x1},
++};
+diff --git a/drivers/media/i2c/soc_camera/ov106xx.c b/drivers/media/i2c/soc_camera/ov106xx.c
+index aaadcc2..b0a3c90 100644
+--- a/drivers/media/i2c/soc_camera/ov106xx.c
++++ b/drivers/media/i2c/soc_camera/ov106xx.c
+@@ -10,6 +10,7 @@
+ */
+
+ #include "ov10635.c"
++#include "ov10640.c"
+ #include "ov490_ov10640.c"
+ #include "ov495_ov2775.c"
+ #include "ar0132.c"
+@@ -28,6 +29,7 @@
+
+ static enum {
+ ID_OV10635,
++ ID_OV10640,
+ ID_OV490_OV10640,
+ ID_OV495_OV2775,
+ ID_AR0132,
+@@ -63,6 +65,12 @@ static int ov106xx_probe(struct i2c_client *client,
+ goto out;
+ }
+
++ ret = ov10640_probe(client, did);
++ if (!ret) {
++ chip_id = ID_OV10640;
++ goto out;
++ }
++
+ ret = ov10635_probe(client, did);
+ if (!ret) {
+ chip_id = ID_OV10635;
+@@ -159,6 +167,9 @@ static int ov106xx_remove(struct i2c_client *client)
+ case ID_OV10635:
+ ov10635_remove(client);
+ break;
++ case ID_OV10640:
++ ov10640_remove(client);
++ break;
+ case ID_OV490_OV10640:
+ ov490_remove(client);
+ break;
+@@ -233,6 +244,6 @@ static struct i2c_driver ov106xx_i2c_driver = {
+
+ module_i2c_driver(ov106xx_i2c_driver);
+
+-MODULE_DESCRIPTION("SoC Camera driver for OV10635, OV490+OV10640, OV495+OV2775, AR0132/140/143/220/223/323, AP0101+AR014X");
++MODULE_DESCRIPTION("SoC Camera driver for OV10635/10640/OV490/OV495, AR0132/140/143/220/223/323, AP0101");
+ MODULE_AUTHOR("Vladimir Barinov");
+ MODULE_LICENSE("GPL");
+--
+2.7.4
+
diff --git a/bsp/meta-rcar/meta-rcar-gen3-adas/recipes-kernel/linux/linux-renesas/0145-lvds-ti9x4-fix-remote-gpio-enablement-on-UB913.patch b/bsp/meta-rcar/meta-rcar-gen3-adas/recipes-kernel/linux/linux-renesas/0145-lvds-ti9x4-fix-remote-gpio-enablement-on-UB913.patch
new file mode 100644
index 00000000..f9addd09
--- /dev/null
+++ b/bsp/meta-rcar/meta-rcar-gen3-adas/recipes-kernel/linux/linux-renesas/0145-lvds-ti9x4-fix-remote-gpio-enablement-on-UB913.patch
@@ -0,0 +1,37 @@
+From 047c89263645b7ab71162b40f60815487662fbec Mon Sep 17 00:00:00 2001
+From: Vladimir Barinov <vladimir.barinov@cogentembedded.com>
+Date: Mon, 14 Jan 2019 16:41:09 +0300
+Subject: [PATCH 094/122] lvds: ti9x4: fix remote gpio enablement on UB913
+
+This fix enablemnet of remote gpios on UB913
+
+Signed-off-by: Vladimir Barinov <vladimir.barinov@cogentembedded.com>
+---
+ drivers/media/i2c/soc_camera/ti9x4.c | 11 +++++++++--
+ 1 file changed, 9 insertions(+), 2 deletions(-)
+
+diff --git a/drivers/media/i2c/soc_camera/ti9x4.c b/drivers/media/i2c/soc_camera/ti9x4.c
+index 7b8209b..db60ebd 100644
+--- a/drivers/media/i2c/soc_camera/ti9x4.c
++++ b/drivers/media/i2c/soc_camera/ti9x4.c
+@@ -325,8 +325,15 @@ static int ti9x4_initialize(struct i2c_client *client)
+ usleep_range(1000, 1500); /* wait 1ms */
+
+ client->addr = priv->ti9x3_addr_map[idx]; /* TI9X3 I2C addr */
+- reg8_write(client, 0x0d, 0xf0); /* Enable all remote GPIOs */
+- reg8_write(client, 0x0e, 0xf0); /* Enable serializer GPIOs */
++ switch (priv->ser_id) {
++ case TI913_ID:
++ reg8_write(client, 0x0d, 0x55); /* Enable remote GPIO0/1 */
++ break;
++ case TI953_ID:
++ reg8_write(client, 0x0d, 0xf0); /* Enable all remote GPIOs */
++ reg8_write(client, 0x0e, 0xf0); /* Enable serializer GPIOs */
++ break;
++ }
+ client->addr = priv->des_addr;
+ }
+
+--
+2.7.4
+
diff --git a/bsp/meta-rcar/meta-rcar-gen3-adas/recipes-kernel/linux/linux-renesas/0146-lvds-add-dummy-imager-driver.patch b/bsp/meta-rcar/meta-rcar-gen3-adas/recipes-kernel/linux/linux-renesas/0146-lvds-add-dummy-imager-driver.patch
new file mode 100644
index 00000000..34b35bb6
--- /dev/null
+++ b/bsp/meta-rcar/meta-rcar-gen3-adas/recipes-kernel/linux/linux-renesas/0146-lvds-add-dummy-imager-driver.patch
@@ -0,0 +1,350 @@
+From f44ff8e351a4c5447f3bcf7e0138e2373793a55a Mon Sep 17 00:00:00 2001
+From: Vladimir Barinov <vladimir.barinov@cogentembedded.com>
+Date: Thu, 17 Jan 2019 10:41:34 +0300
+Subject: [PATCH 095/122] lvds: add dummy imager driver
+
+Dummy imager glue driver
+
+Signed-off-by: Vladimir Barinov <vladimir.barinov@cogentembedded.com>
+---
+ drivers/media/i2c/soc_camera/Makefile | 1 +
+ drivers/media/i2c/soc_camera/dummy.c | 317 ++++++++++++++++++++++++++++++++++
+ 2 files changed, 318 insertions(+)
+ create mode 100644 drivers/media/i2c/soc_camera/dummy.c
+
+diff --git a/drivers/media/i2c/soc_camera/Makefile b/drivers/media/i2c/soc_camera/Makefile
+index eed6e24..4aa5046 100644
+--- a/drivers/media/i2c/soc_camera/Makefile
++++ b/drivers/media/i2c/soc_camera/Makefile
+@@ -15,4 +15,5 @@ obj-$(CONFIG_SOC_CAMERA_MAX9286) += max9286.o
+ obj-$(CONFIG_SOC_CAMERA_TI9X4) += ti9x4.o
+ obj-$(CONFIG_SOC_CAMERA_OV106XX) += ov106xx.o
+ obj-$(CONFIG_SOC_CAMERA_IMX219) += imx219.o
++obj-y += dummy.o
+
+diff --git a/drivers/media/i2c/soc_camera/dummy.c b/drivers/media/i2c/soc_camera/dummy.c
+new file mode 100644
+index 0000000..a38d7c4
+--- /dev/null
++++ b/drivers/media/i2c/soc_camera/dummy.c
+@@ -0,0 +1,317 @@
++/*
++ * Dummy sensor camera driver
++ *
++ * Copyright (C) 2019 Cogent Embedded, Inc.
++ *
++ * This program is free software; you can redistribute it and/or modify it
++ * under the terms of the GNU General Public License as published by the
++ * Free Software Foundation; either version 2 of the License, or (at your
++ * option) any later version.
++ */
++
++#include <linux/delay.h>
++#include <linux/init.h>
++#include <linux/i2c.h>
++#include <linux/module.h>
++#include <linux/of_graph.h>
++#include <linux/videodev2.h>
++
++#include <media/soc_camera.h>
++#include <media/v4l2-common.h>
++#include <media/v4l2-ctrls.h>
++
++#define MEDIA_BUS_FORMAT MEDIA_BUS_FMT_YUYV8_2X8
++
++struct dummy_priv {
++ struct v4l2_subdev sd;
++ struct v4l2_ctrl_handler hdl;
++ struct media_pad pad;
++ struct v4l2_rect rect;
++ int max_width;
++ int max_height;
++};
++
++static inline struct dummy_priv *to_dummy(const struct i2c_client *client)
++{
++ return container_of(i2c_get_clientdata(client), struct dummy_priv, sd);
++}
++
++static inline struct v4l2_subdev *to_sd(struct v4l2_ctrl *ctrl)
++{
++ return &container_of(ctrl->handler, struct dummy_priv, hdl)->sd;
++}
++
++static int dummy_s_stream(struct v4l2_subdev *sd, int enable)
++{
++ return 0;
++}
++
++static int dummy_get_fmt(struct v4l2_subdev *sd,
++ struct v4l2_subdev_pad_config *cfg,
++ struct v4l2_subdev_format *format)
++{
++ struct v4l2_mbus_framefmt *mf = &format->format;
++ struct i2c_client *client = v4l2_get_subdevdata(sd);
++ struct dummy_priv *priv = to_dummy(client);
++
++ if (format->pad)
++ return -EINVAL;
++
++ mf->width = priv->rect.width;
++ mf->height = priv->rect.height;
++ mf->code = MEDIA_BUS_FORMAT;
++ mf->colorspace = V4L2_COLORSPACE_SMPTE170M;
++ mf->field = V4L2_FIELD_NONE;
++
++ return 0;
++}
++
++static int dummy_set_fmt(struct v4l2_subdev *sd,
++ struct v4l2_subdev_pad_config *cfg,
++ struct v4l2_subdev_format *format)
++{
++ struct v4l2_mbus_framefmt *mf = &format->format;
++
++ mf->code = MEDIA_BUS_FORMAT;
++ mf->colorspace = V4L2_COLORSPACE_SMPTE170M;
++ mf->field = V4L2_FIELD_NONE;
++
++ if (format->which == V4L2_SUBDEV_FORMAT_TRY)
++ cfg->try_fmt = *mf;
++
++ return 0;
++}
++
++static int dummy_enum_mbus_code(struct v4l2_subdev *sd,
++ struct v4l2_subdev_pad_config *cfg,
++ struct v4l2_subdev_mbus_code_enum *code)
++{
++ if (code->pad || code->index > 0)
++ return -EINVAL;
++
++ code->code = MEDIA_BUS_FORMAT;
++
++ return 0;
++}
++
++static int dummy_set_selection(struct v4l2_subdev *sd,
++ struct v4l2_subdev_pad_config *cfg,
++ struct v4l2_subdev_selection *sel)
++{
++ struct v4l2_rect *rect = &sel->r;
++ struct i2c_client *client = v4l2_get_subdevdata(sd);
++ struct dummy_priv *priv = to_dummy(client);
++
++ if (sel->which != V4L2_SUBDEV_FORMAT_ACTIVE ||
++ sel->target != V4L2_SEL_TGT_CROP)
++ return -EINVAL;
++
++ rect->left = ALIGN(rect->left, 2);
++ rect->top = ALIGN(rect->top, 2);
++ rect->width = ALIGN(rect->width, 2);
++ rect->height = ALIGN(rect->height, 2);
++
++ if ((rect->left + rect->width > priv->max_width) ||
++ (rect->top + rect->height > priv->max_height))
++ *rect = priv->rect;
++
++ priv->rect.left = rect->left;
++ priv->rect.top = rect->top;
++ priv->rect.width = rect->width;
++ priv->rect.height = rect->height;
++
++ return 0;
++}
++
++static int dummy_get_selection(struct v4l2_subdev *sd,
++ struct v4l2_subdev_pad_config *cfg,
++ struct v4l2_subdev_selection *sel)
++{
++ struct i2c_client *client = v4l2_get_subdevdata(sd);
++ struct dummy_priv *priv = to_dummy(client);
++
++ if (sel->which != V4L2_SUBDEV_FORMAT_ACTIVE)
++ return -EINVAL;
++
++ switch (sel->target) {
++ case V4L2_SEL_TGT_CROP_BOUNDS:
++ sel->r.left = 0;
++ sel->r.top = 0;
++ sel->r.width = priv->max_width;
++ sel->r.height = priv->max_height;
++ return 0;
++ case V4L2_SEL_TGT_CROP_DEFAULT:
++ sel->r.left = 0;
++ sel->r.top = 0;
++ sel->r.width = priv->max_width;
++ sel->r.height = priv->max_height;
++ return 0;
++ case V4L2_SEL_TGT_CROP:
++ sel->r = priv->rect;
++ return 0;
++ default:
++ return -EINVAL;
++ }
++}
++
++static int dummy_g_mbus_config(struct v4l2_subdev *sd,
++ struct v4l2_mbus_config *cfg)
++{
++ cfg->flags = V4L2_MBUS_CSI2_1_LANE | V4L2_MBUS_CSI2_CHANNEL_0 |
++ V4L2_MBUS_CSI2_CONTINUOUS_CLOCK;
++ cfg->type = V4L2_MBUS_CSI2;
++
++ return 0;
++}
++
++static int dummy_s_ctrl(struct v4l2_ctrl *ctrl)
++{
++ return -EINVAL;
++}
++
++static const struct v4l2_ctrl_ops dummy_ctrl_ops = {
++ .s_ctrl = dummy_s_ctrl,
++};
++
++static struct v4l2_subdev_video_ops dummy_video_ops = {
++ .s_stream = dummy_s_stream,
++ .g_mbus_config = dummy_g_mbus_config,
++};
++
++static const struct v4l2_subdev_pad_ops dummy_subdev_pad_ops = {
++ .enum_mbus_code = dummy_enum_mbus_code,
++ .get_selection = dummy_get_selection,
++ .set_selection = dummy_set_selection,
++ .get_fmt = dummy_get_fmt,
++ .set_fmt = dummy_set_fmt,
++};
++
++static struct v4l2_subdev_ops dummy_subdev_ops = {
++ .video = &dummy_video_ops,
++ .pad = &dummy_subdev_pad_ops,
++};
++
++static int dummy_initialize(struct i2c_client *client)
++{
++ struct dummy_priv *priv = to_dummy(client);
++
++ dev_info(&client->dev, "Dummy sensor res %dx%d\n", priv->max_width, priv->max_height);
++
++ return 0;
++}
++
++static int dummy_parse_dt(struct device_node *np, struct dummy_priv *priv)
++{
++ struct i2c_client *client = v4l2_get_subdevdata(&priv->sd);
++ int err;
++
++ err = of_property_read_u32(np, "dummy,width", &priv->max_width);
++ if (err) {
++ dev_err(&client->dev, "dummy,width must be defined\n");
++ goto out;
++ }
++
++ err = of_property_read_u32(np, "dummy,height", &priv->max_height);
++ if (err) {
++ dev_err(&client->dev, "dummy,height must be defined\n");
++ goto out;
++ }
++
++out:
++ return err;
++}
++
++static int dummy_probe(struct i2c_client *client,
++ const struct i2c_device_id *did)
++{
++ struct dummy_priv *priv;
++ int ret;
++
++ priv = devm_kzalloc(&client->dev, sizeof(*priv), GFP_KERNEL);
++ if (!priv)
++ return -ENOMEM;
++
++ v4l2_i2c_subdev_init(&priv->sd, client, &dummy_subdev_ops);
++ priv->sd.flags = V4L2_SUBDEV_FL_HAS_DEVNODE;
++
++ v4l2_ctrl_handler_init(&priv->hdl, 4);
++ priv->sd.ctrl_handler = &priv->hdl;
++
++ ret = priv->hdl.error;
++ if (ret)
++ goto cleanup;
++
++ v4l2_ctrl_handler_setup(&priv->hdl);
++
++ priv->pad.flags = MEDIA_PAD_FL_SOURCE;
++ priv->sd.entity.flags |= MEDIA_ENT_F_CAM_SENSOR;
++ ret = media_entity_pads_init(&priv->sd.entity, 1, &priv->pad);
++ if (ret < 0)
++ goto cleanup;
++
++ ret = dummy_parse_dt(client->dev.of_node, priv);
++ if (ret)
++ goto cleanup;
++
++ ret = dummy_initialize(client);
++ if (ret < 0)
++ goto cleanup;
++
++ priv->rect.left = 0;
++ priv->rect.top = 0;
++ priv->rect.width = priv->max_width;
++ priv->rect.height = priv->max_height;
++
++ ret = v4l2_async_register_subdev(&priv->sd);
++ if (ret)
++ goto cleanup;
++
++ return 0;
++
++cleanup:
++ media_entity_cleanup(&priv->sd.entity);
++ v4l2_ctrl_handler_free(&priv->hdl);
++ v4l2_device_unregister_subdev(&priv->sd);
++ v4l_err(client, "failed to probe @ 0x%02x (%s)\n",
++ client->addr, client->adapter->name);
++ return ret;
++}
++
++static int dummy_remove(struct i2c_client *client)
++{
++ struct dummy_priv *priv = i2c_get_clientdata(client);
++
++ v4l2_async_unregister_subdev(&priv->sd);
++ media_entity_cleanup(&priv->sd.entity);
++ v4l2_ctrl_handler_free(&priv->hdl);
++ v4l2_device_unregister_subdev(&priv->sd);
++
++ return 0;
++}
++
++static const struct i2c_device_id dummy_id[] = {
++ { "dummy-camera", 0 },
++ { }
++};
++MODULE_DEVICE_TABLE(i2c, dummy_id);
++
++static const struct of_device_id dummy_of_ids[] = {
++ { .compatible = "dummy-camera", },
++ { }
++};
++MODULE_DEVICE_TABLE(of, dummy_of_ids);
++
++static struct i2c_driver dummy_i2c_driver = {
++ .driver = {
++ .name = "dummy-camera",
++ .of_match_table = dummy_of_ids,
++ },
++ .probe = dummy_probe,
++ .remove = dummy_remove,
++ .id_table = dummy_id,
++};
++module_i2c_driver(dummy_i2c_driver);
++
++MODULE_DESCRIPTION("Dummy SoC camera driver");
++MODULE_AUTHOR("Vladimir Barinov");
++MODULE_LICENSE("GPL");
+--
+2.7.4
+
diff --git a/bsp/meta-rcar/meta-rcar-gen3-adas/recipes-kernel/linux/linux-renesas/0147-lvds-ti9x4-use-REFCLK-23.0MHz.patch b/bsp/meta-rcar/meta-rcar-gen3-adas/recipes-kernel/linux/linux-renesas/0147-lvds-ti9x4-use-REFCLK-23.0MHz.patch
new file mode 100644
index 00000000..eee6d9b6
--- /dev/null
+++ b/bsp/meta-rcar/meta-rcar-gen3-adas/recipes-kernel/linux/linux-renesas/0147-lvds-ti9x4-use-REFCLK-23.0MHz.patch
@@ -0,0 +1,39 @@
+From cd625ee08e7e815083795182c79521c13067321e Mon Sep 17 00:00:00 2001
+From: Vladimir Barinov <vladimir.barinov@cogentembedded.com>
+Date: Thu, 7 Feb 2019 11:49:46 +0300
+Subject: [PATCH 096/122] lvds: ti9x4: use REFCLK=23.0MHz
+
+This fixes data integrity on FPDLink channel
+
+Signed-off-by: Vladimir Barinov <vladimir.barinov@cogentembedded.com>
+---
+ drivers/media/i2c/soc_camera/ti9x4.c | 6 +++---
+ 1 file changed, 3 insertions(+), 3 deletions(-)
+
+diff --git a/drivers/media/i2c/soc_camera/ti9x4.c b/drivers/media/i2c/soc_camera/ti9x4.c
+index db60ebd..373652a 100644
+--- a/drivers/media/i2c/soc_camera/ti9x4.c
++++ b/drivers/media/i2c/soc_camera/ti9x4.c
+@@ -144,7 +144,7 @@ static void ti9x4_initial_setup(struct i2c_client *client)
+ reg8_write(client, 0x0d, 0xb9); /* VDDIO 3.3V */
+ switch (priv->csi_rate) {
+ case 1600: /* REFCLK = 25MHZ */
+- case 1500: /* REFCLK = 23.5MHZ */
++ case 1500: /* REFCLK = 23MHZ */
+ case 1450: /* REFCLK = 22.5MHZ */
+ reg8_write(client, 0x1f, 0x00); /* CSI rate 1.5/1.6Gbps */
+ break;
+@@ -173,8 +173,8 @@ static void ti9x4_initial_setup(struct i2c_client *client)
+ fs_time = 2790;
+ break;
+ case 1500:
+- /* FrameSync setup for REFCLK=23.5MHz, FPS=30: period_counts=1/FPS/12.766mks=1/30/12.766e-6=2612 -> HI=2, LO=2610 */
+- fs_time = 2625;
++ /* FrameSync setup for REFCLK=23MHz, FPS=30: period_counts=1/FPS/13.043mks=1/30/13.043e-6=2556 -> HI=2, LO=2554 */
++ fs_time = 2570;
+ break;
+ case 1450:
+ case 1100:
+--
+2.7.4
+
diff --git a/bsp/meta-rcar/meta-rcar-gen3-adas/recipes-kernel/linux/linux-renesas/0148-lvds-ar0231-fix-comments.patch b/bsp/meta-rcar/meta-rcar-gen3-adas/recipes-kernel/linux/linux-renesas/0148-lvds-ar0231-fix-comments.patch
new file mode 100644
index 00000000..df0a1748
--- /dev/null
+++ b/bsp/meta-rcar/meta-rcar-gen3-adas/recipes-kernel/linux/linux-renesas/0148-lvds-ar0231-fix-comments.patch
@@ -0,0 +1,48 @@
+From 85f8c9a60ec11fe59913cb93442e380249e95d13 Mon Sep 17 00:00:00 2001
+From: Vladimir Barinov <vladimir.barinov@cogentembedded.com>
+Date: Thu, 7 Feb 2019 11:55:03 +0300
+Subject: [PATCH 097/122] lvds: ar0231: fix comments
+
+This fixes comments on PLL calculation
+
+Signed-off-by: Vladimir Barinov <vladimir.barinov@cogentembedded.com>
+---
+ drivers/media/i2c/soc_camera/ar0231_rev7.h | 12 ++++++------
+ 1 file changed, 6 insertions(+), 6 deletions(-)
+
+diff --git a/drivers/media/i2c/soc_camera/ar0231_rev7.h b/drivers/media/i2c/soc_camera/ar0231_rev7.h
+index 885d34e..5f196e8 100644
+--- a/drivers/media/i2c/soc_camera/ar0231_rev7.h
++++ b/drivers/media/i2c/soc_camera/ar0231_rev7.h
+@@ -301,14 +301,14 @@ static const struct ar0231_reg ar0231_regs_wizard_rev7[] = {
+ #endif /* Sensor Setup */
+
+ #if 1 /* Serial 12-bit Timing Setup */
+-/* PCLK=27Mhz/PRE_PLL_CLK_DIV *PLL_MULTIPLIER /P1 /P4 *2 */
+-/* PCLK=27Mhz/2 *44/1/12 *2= 99Mhz - TI serializers */
+-{0x302A, 6}, // vt_pix_clk_div (P2 divider)
+-{0x302C, 1}, // vt_sys_clk_div (P1 divider)
++/* PCLK=24Mhz/PRE_PLL_CLK_DIV *PLL_MULTIPLIER /P1 /P4 *2 */
++/* PCLK=24Mhz/2 *44/1/12 *2= 88Mhz - TI serializers */
+ {0x302E, 2}, // pre_pll_clk_div
+ {0x3030, 44}, // pll_multiplier
+-{0x3036, 12}, // op_word_clk_div (P4 divider)
++{0x302C, 1}, // vt_sys_clk_div (P1 divider)
++{0x302A, 6}, // vt_pix_clk_div (P2 divider)
+ {0x3038, 1}, // op_sys_clk_div (P3 divider)
++{0x3036, 12}, // op_word_clk_div (P4 divider)
+ {0x30B0, 0x800}, // digital_test: pll_complete_bypass=0
+ #endif /* Serial 12-bit Timing Setup */
+
+@@ -384,7 +384,7 @@ static const struct ar0231_reg ar0231_regs_wizard_rev7[] = {
+ {0x31BC, 0x805},
+ #endif /* MIPI 12 bit Settings */
+
+-/* FPS = 124.5MHz / reg0x300A / reg0x300C * (DES_XTAL/27MHz), DES_XTAL=23.5MHz */
++/* FPS = 105MHz / reg0x300A / reg0x300C * (DES_XTAL/27MHz), DES_XTAL=23.5MHz */
+ {0x300A, AR0231_SENSOR_HEIGHT + 100}, // Frame_length_Lines
+ {0x300C, AR0231_SENSOR_WIDTH + 550}, // Line_length_pck
+ {0x3012, 0x144}, //Integration_time
+--
+2.7.4
+
diff --git a/bsp/meta-rcar/meta-rcar-gen3-adas/recipes-kernel/linux/linux-renesas/0149-lvds-ISX019-rename-isx016-to-isx019.patch b/bsp/meta-rcar/meta-rcar-gen3-adas/recipes-kernel/linux/linux-renesas/0149-lvds-ISX019-rename-isx016-to-isx019.patch
new file mode 100644
index 00000000..7f8a8898
--- /dev/null
+++ b/bsp/meta-rcar/meta-rcar-gen3-adas/recipes-kernel/linux/linux-renesas/0149-lvds-ISX019-rename-isx016-to-isx019.patch
@@ -0,0 +1,1402 @@
+From 2cf498aeeae73aa2d3719a5ab3dc47f2f4e29187 Mon Sep 17 00:00:00 2001
+From: Vladimir Barinov <vladimir.barinov@cogentembedded.com>
+Date: Thu, 7 Feb 2019 12:02:09 +0300
+Subject: [PATCH 098/122] lvds: ISX019: rename isx016 to isx019
+
+Rename misnamed imager
+
+Signed-off-by: Vladimir Barinov <vladimir.barinov@cogentembedded.com>
+---
+ drivers/media/i2c/soc_camera/isx016.c | 628 ---------------------------------
+ drivers/media/i2c/soc_camera/isx016.h | 27 --
+ drivers/media/i2c/soc_camera/isx019.c | 628 +++++++++++++++++++++++++++++++++
+ drivers/media/i2c/soc_camera/isx019.h | 27 ++
+ drivers/media/i2c/soc_camera/ov106xx.c | 12 +-
+ 5 files changed, 661 insertions(+), 661 deletions(-)
+ delete mode 100644 drivers/media/i2c/soc_camera/isx016.c
+ delete mode 100644 drivers/media/i2c/soc_camera/isx016.h
+ create mode 100644 drivers/media/i2c/soc_camera/isx019.c
+ create mode 100644 drivers/media/i2c/soc_camera/isx019.h
+
+diff --git a/drivers/media/i2c/soc_camera/isx016.c b/drivers/media/i2c/soc_camera/isx016.c
+deleted file mode 100644
+index 275bd8a..0000000
+--- a/drivers/media/i2c/soc_camera/isx016.c
++++ /dev/null
+@@ -1,628 +0,0 @@
+-/*
+- * ON Semiconductor ISX016 sensor camera driver
+- *
+- * Copyright (C) 2018 Cogent Embedded, Inc.
+- *
+- * This program is free software; you can redistribute it and/or modify it
+- * under the terms of the GNU General Public License as published by the
+- * Free Software Foundation; either version 2 of the License, or (at your
+- * option) any later version.
+- */
+-
+-#include <linux/delay.h>
+-#include <linux/init.h>
+-#include <linux/i2c.h>
+-#include <linux/module.h>
+-#include <linux/of_graph.h>
+-#include <linux/videodev2.h>
+-
+-#include <media/soc_camera.h>
+-#include <media/v4l2-common.h>
+-#include <media/v4l2-ctrls.h>
+-
+-#include "isx016.h"
+-
+-static const int isx016_i2c_addr[] = {0x1a};
+-
+-#define ISX016_PID 0x0000
+-#define ISX016_VERSION_REG 0x0740
+-
+-#define ISX016_MEDIA_BUS_FMT MEDIA_BUS_FMT_YUYV8_2X8
+-
+-static void isx016_otp_id_read(struct i2c_client *client);
+-
+-struct isx016_priv {
+- struct v4l2_subdev sd;
+- struct v4l2_ctrl_handler hdl;
+- struct media_pad pad;
+- struct v4l2_rect rect;
+- int max_width;
+- int max_height;
+- int init_complete;
+- u8 id[6];
+- int exposure;
+- int gain;
+- int autogain;
+- /* serializers */
+- int max9286_addr;
+- int max9271_addr;
+- int port;
+- int gpio_resetb;
+- int gpio_fsin;
+-};
+-
+-static inline struct isx016_priv *to_isx016(const struct i2c_client *client)
+-{
+- return container_of(i2c_get_clientdata(client), struct isx016_priv, sd);
+-}
+-
+-static void isx016_s_port(struct i2c_client *client, int fwd_en)
+-{
+- struct isx016_priv *priv = to_isx016(client);
+- int tmp_addr;
+-
+- if (priv->max9286_addr) {
+- tmp_addr = client->addr;
+- client->addr = priv->max9286_addr; /* Deserializer I2C address */
+- reg8_write(client, 0x0a, fwd_en ? 0x11 << priv->port : 0); /* Enable/disable reverse/forward control for this port */
+- usleep_range(5000, 5500); /* wait 5ms */
+- client->addr = tmp_addr;
+- };
+-}
+-
+-static int isx016_read16(struct i2c_client *client, u8 category, u16 reg, u16 *val)
+-{
+- int ret;
+- #define R_NUM_BYTES 9
+- #define R_NUM_CMDS 1
+- #define R_NUM_CMD_BYTES 6
+- #define R_CMD 1
+- #define R_BYTES 2
+- u8 buf[R_NUM_BYTES] = {R_NUM_BYTES, R_NUM_CMDS,
+- R_NUM_CMD_BYTES, R_CMD,
+- category, reg >> 8, reg & 0xff,
+- R_BYTES, 0x00};
+-
+- /* calculate checksum */
+- buf[8] = R_NUM_BYTES + R_NUM_CMDS + R_NUM_CMD_BYTES + R_CMD +
+- category + (reg >> 8) + (reg & 0xff) + R_BYTES;
+-
+- ret = i2c_master_send(client, buf, R_NUM_BYTES);
+- if (ret == R_NUM_BYTES)
+- ret = i2c_master_recv(client, buf, R_NUM_BYTES - 2);
+-
+- if (ret < 0) {
+- dev_err(&client->dev,
+- "read fail: chip 0x%x register 0x%x: %d\n",
+- client->addr, reg, ret);
+- } else {
+- *val = ((u16)buf[4] << 8) | buf[5];
+- }
+-
+- return ret < 0 ? ret : 0;
+-}
+-
+-static int isx016_write16(struct i2c_client *client, u8 category, u16 reg, u16 val)
+-{
+- int ret;
+- #define W_NUM_BYTES 10
+- #define W_NUM_CMDS 1
+- #define W_NUM_CMD_BYTES 7
+- #define W_CMD 2
+- u8 buf[W_NUM_BYTES] = {W_NUM_BYTES, W_NUM_CMDS,
+- W_NUM_CMD_BYTES, W_CMD,
+- category, reg >> 8, reg & 0xff,
+- val >> 8, val & 0xff};
+-
+- /* calculate checksum */
+- buf[9] = W_NUM_BYTES + W_NUM_CMDS + W_NUM_CMD_BYTES + W_CMD +
+- category + (reg >> 8) + (reg & 0xff) + (val >> 8) + (val & 0xff);
+-
+- ret = i2c_master_send(client, buf, W_NUM_BYTES);
+-
+- if (ret < 0) {
+- dev_err(&client->dev,
+- "write fail: chip 0x%x register 0x%x: %d\n",
+- client->addr, reg, ret);
+- }
+-
+- return ret < 0 ? ret : 0;
+-}
+-
+-static int isx016_set_regs(struct i2c_client *client,
+- const struct isx016_reg *regs, int nr_regs)
+-{
+- int i;
+-
+- for (i = 0; i < nr_regs; i++) {
+- if (regs[i].reg == ISX016_DELAY) {
+- mdelay(regs[i].val);
+- continue;
+- }
+-
+- isx016_write16(client, regs[i].reg >> 8, regs[i].reg & 0xff, regs[i].val);
+- }
+-
+- return 0;
+-}
+-
+-static int isx016_s_stream(struct v4l2_subdev *sd, int enable)
+-{
+- return 0;
+-}
+-
+-static int isx016_get_fmt(struct v4l2_subdev *sd,
+- struct v4l2_subdev_pad_config *cfg,
+- struct v4l2_subdev_format *format)
+-{
+- struct v4l2_mbus_framefmt *mf = &format->format;
+- struct i2c_client *client = v4l2_get_subdevdata(sd);
+- struct isx016_priv *priv = to_isx016(client);
+-
+- if (format->pad)
+- return -EINVAL;
+-
+- mf->width = priv->rect.width;
+- mf->height = priv->rect.height;
+- mf->code = ISX016_MEDIA_BUS_FMT;
+- mf->colorspace = V4L2_COLORSPACE_SMPTE170M;
+- mf->field = V4L2_FIELD_NONE;
+-
+- return 0;
+-}
+-
+-static int isx016_set_fmt(struct v4l2_subdev *sd,
+- struct v4l2_subdev_pad_config *cfg,
+- struct v4l2_subdev_format *format)
+-{
+- struct v4l2_mbus_framefmt *mf = &format->format;
+-
+- mf->code = ISX016_MEDIA_BUS_FMT;
+- mf->colorspace = V4L2_COLORSPACE_SMPTE170M;
+- mf->field = V4L2_FIELD_NONE;
+-
+- if (format->which == V4L2_SUBDEV_FORMAT_TRY)
+- cfg->try_fmt = *mf;
+-
+- return 0;
+-}
+-
+-static int isx016_enum_mbus_code(struct v4l2_subdev *sd,
+- struct v4l2_subdev_pad_config *cfg,
+- struct v4l2_subdev_mbus_code_enum *code)
+-{
+- if (code->pad || code->index > 0)
+- return -EINVAL;
+-
+- code->code = ISX016_MEDIA_BUS_FMT;
+-
+- return 0;
+-}
+-
+-static int isx016_get_edid(struct v4l2_subdev *sd, struct v4l2_edid *edid)
+-{
+- struct i2c_client *client = v4l2_get_subdevdata(sd);
+- struct isx016_priv *priv = to_isx016(client);
+-
+- isx016_otp_id_read(client);
+-
+- memcpy(edid->edid, priv->id, 6);
+-
+- edid->edid[6] = 0xff;
+- edid->edid[7] = client->addr;
+- edid->edid[8] = ISX016_VERSION_REG >> 8;
+- edid->edid[9] = ISX016_VERSION_REG & 0xff;
+-
+- return 0;
+-}
+-
+-static int isx016_set_selection(struct v4l2_subdev *sd,
+- struct v4l2_subdev_pad_config *cfg,
+- struct v4l2_subdev_selection *sel)
+-{
+- struct v4l2_rect *rect = &sel->r;
+- struct i2c_client *client = v4l2_get_subdevdata(sd);
+- struct isx016_priv *priv = to_isx016(client);
+-
+- if (sel->which != V4L2_SUBDEV_FORMAT_ACTIVE ||
+- sel->target != V4L2_SEL_TGT_CROP)
+- return -EINVAL;
+-
+- rect->left = ALIGN(rect->left, 2);
+- rect->top = ALIGN(rect->top, 2);
+- rect->width = ALIGN(rect->width, 2);
+- rect->height = ALIGN(rect->height, 2);
+-
+- if ((rect->left + rect->width > priv->max_width) ||
+- (rect->top + rect->height > priv->max_height))
+- *rect = priv->rect;
+-
+- priv->rect.left = rect->left;
+- priv->rect.top = rect->top;
+- priv->rect.width = rect->width;
+- priv->rect.height = rect->height;
+-
+- return 0;
+-}
+-
+-static int isx016_get_selection(struct v4l2_subdev *sd,
+- struct v4l2_subdev_pad_config *cfg,
+- struct v4l2_subdev_selection *sel)
+-{
+- struct i2c_client *client = v4l2_get_subdevdata(sd);
+- struct isx016_priv *priv = to_isx016(client);
+-
+- if (sel->which != V4L2_SUBDEV_FORMAT_ACTIVE)
+- return -EINVAL;
+-
+- switch (sel->target) {
+- case V4L2_SEL_TGT_CROP_BOUNDS:
+- sel->r.left = 0;
+- sel->r.top = 0;
+- sel->r.width = priv->max_width;
+- sel->r.height = priv->max_height;
+- return 0;
+- case V4L2_SEL_TGT_CROP_DEFAULT:
+- sel->r.left = 0;
+- sel->r.top = 0;
+- sel->r.width = priv->max_width;
+- sel->r.height = priv->max_height;
+- return 0;
+- case V4L2_SEL_TGT_CROP:
+- sel->r = priv->rect;
+- return 0;
+- default:
+- return -EINVAL;
+- }
+-}
+-
+-static int isx016_g_mbus_config(struct v4l2_subdev *sd,
+- struct v4l2_mbus_config *cfg)
+-{
+- cfg->flags = V4L2_MBUS_CSI2_1_LANE | V4L2_MBUS_CSI2_CHANNEL_0 |
+- V4L2_MBUS_CSI2_CONTINUOUS_CLOCK;
+- cfg->type = V4L2_MBUS_CSI2;
+-
+- return 0;
+-}
+-
+-#ifdef CONFIG_VIDEO_ADV_DEBUG
+-static int isx016_g_register(struct v4l2_subdev *sd,
+- struct v4l2_dbg_register *reg)
+-{
+- struct i2c_client *client = v4l2_get_subdevdata(sd);
+- int ret;
+- u16 val = 0;
+-
+- ret = isx016_read16(client, (u16)reg->reg >> 8, (u16)reg->reg & 0xff, &val);
+- if (ret < 0)
+- return ret;
+-
+- reg->val = val;
+- reg->size = sizeof(u16);
+-
+- return 0;
+-}
+-
+-static int isx016_s_register(struct v4l2_subdev *sd,
+- const struct v4l2_dbg_register *reg)
+-{
+- struct i2c_client *client = v4l2_get_subdevdata(sd);
+-
+- return isx016_write16(client, (u16)reg->reg >> 8, (u16)reg->reg & 0xff, (u16)reg->val);
+-}
+-#endif
+-
+-static struct v4l2_subdev_core_ops isx016_core_ops = {
+-#ifdef CONFIG_VIDEO_ADV_DEBUG
+- .g_register = isx016_g_register,
+- .s_register = isx016_s_register,
+-#endif
+-};
+-
+-static int isx016_s_ctrl(struct v4l2_ctrl *ctrl)
+-{
+- struct v4l2_subdev *sd = to_sd(ctrl);
+- struct i2c_client *client = v4l2_get_subdevdata(sd);
+- struct isx016_priv *priv = to_isx016(client);
+- int ret = -EINVAL;
+-
+- if (!priv->init_complete)
+- return 0;
+-
+- switch (ctrl->id) {
+- case V4L2_CID_BRIGHTNESS:
+- case V4L2_CID_CONTRAST:
+- case V4L2_CID_SATURATION:
+- case V4L2_CID_HUE:
+- case V4L2_CID_GAMMA:
+- case V4L2_CID_SHARPNESS:
+- case V4L2_CID_AUTOGAIN:
+- case V4L2_CID_GAIN:
+- case V4L2_CID_EXPOSURE:
+- case V4L2_CID_HFLIP:
+- case V4L2_CID_VFLIP:
+- break;
+- }
+-
+- return ret;
+-}
+-
+-static const struct v4l2_ctrl_ops isx016_ctrl_ops = {
+- .s_ctrl = isx016_s_ctrl,
+-};
+-
+-static struct v4l2_subdev_video_ops isx016_video_ops = {
+- .s_stream = isx016_s_stream,
+- .g_mbus_config = isx016_g_mbus_config,
+-};
+-
+-static const struct v4l2_subdev_pad_ops isx016_subdev_pad_ops = {
+- .get_edid = isx016_get_edid,
+- .enum_mbus_code = isx016_enum_mbus_code,
+- .get_selection = isx016_get_selection,
+- .set_selection = isx016_set_selection,
+- .get_fmt = isx016_get_fmt,
+- .set_fmt = isx016_set_fmt,
+-};
+-
+-static struct v4l2_subdev_ops isx016_subdev_ops = {
+- .core = &isx016_core_ops,
+- .video = &isx016_video_ops,
+- .pad = &isx016_subdev_pad_ops,
+-};
+-
+-static void isx016_otp_id_read(struct i2c_client *client)
+-{
+- struct isx016_priv *priv = to_isx016(client);
+- int i;
+- u16 val = 0;
+-
+- /* read camera id from isx016 OTP memory */
+- for (i = 0; i < 6; i+=2) {
+- isx016_read16(client, 8, 0x60 + i, &val);
+- priv->id[i] = val >> 8;
+- priv->id[i+1] = val & 0xff;
+- }
+-}
+-
+-static ssize_t isx016_otp_id_show(struct device *dev,
+- struct device_attribute *attr, char *buf)
+-{
+- struct v4l2_subdev *sd = i2c_get_clientdata(to_i2c_client(dev));
+- struct i2c_client *client = v4l2_get_subdevdata(sd);
+- struct isx016_priv *priv = to_isx016(client);
+-
+- isx016_otp_id_read(client);
+-
+- return snprintf(buf, 32, "%02x:%02x:%02x:%02x:%02x:%02x\n",
+- priv->id[0], priv->id[1], priv->id[2], priv->id[3], priv->id[4], priv->id[5]);
+-}
+-
+-static DEVICE_ATTR(otp_id_isx016, S_IRUGO, isx016_otp_id_show, NULL);
+-
+-static int isx016_initialize(struct i2c_client *client)
+-{
+- struct isx016_priv *priv = to_isx016(client);
+- u16 pid = 0;
+- int ret = 0;
+- int tmp_addr;
+- int i;
+-
+- isx016_s_port(client, 1);
+-
+- for (i = 0; i < ARRAY_SIZE(isx016_i2c_addr); i++) {
+- tmp_addr = client->addr;
+- if (priv->max9286_addr) {
+- client->addr = priv->max9271_addr; /* Serializer I2C address */
+- reg8_write(client, 0x0A, isx016_i2c_addr[i] << 1); /* Sensor native I2C address */
+- usleep_range(2000, 2500); /* wait 2ms */
+- };
+- client->addr = tmp_addr;
+-
+- /* check model ID */
+- isx016_read16(client, 0, ISX016_PID, &pid);
+-
+- if (pid == ISX016_VERSION_REG)
+- break;
+- }
+-
+- if (pid != ISX016_VERSION_REG) {
+- dev_dbg(&client->dev, "Product ID error %x\n", pid);
+- ret = -ENODEV;
+- goto err;
+- }
+-
+- priv->max_width = ISX016_MAX_WIDTH;
+- priv->max_height = ISX016_MAX_HEIGHT;
+-
+- /* Read OTP IDs */
+- isx016_otp_id_read(client);
+- /* Program wizard registers */
+- isx016_set_regs(client, isx016_regs_wizard, ARRAY_SIZE(isx016_regs_wizard));
+-
+- dev_info(&client->dev, "isx016 PID %x, res %dx%d, OTP_ID %02x:%02x:%02x:%02x:%02x:%02x\n",
+- pid, priv->max_width, priv->max_height, priv->id[0], priv->id[1], priv->id[2], priv->id[3], priv->id[4], priv->id[5]);
+-err:
+- isx016_s_port(client, 0);
+-
+- return ret;
+-}
+-
+-static int isx016_parse_dt(struct device_node *np, struct isx016_priv *priv)
+-{
+- struct i2c_client *client = v4l2_get_subdevdata(&priv->sd);
+- int i;
+- struct device_node *endpoint = NULL, *rendpoint = NULL;
+- int tmp_addr = 0;
+-
+- for (i = 0; ; i++) {
+- endpoint = of_graph_get_next_endpoint(np, endpoint);
+- if (!endpoint)
+- break;
+-
+- of_node_put(endpoint);
+-
+- rendpoint = of_parse_phandle(endpoint, "remote-endpoint", 0);
+- if (!rendpoint)
+- continue;
+-
+- if (!of_property_read_u32(rendpoint, "max9271-addr", &priv->max9271_addr) &&
+- !of_property_read_u32(rendpoint->parent->parent, "reg", &priv->max9286_addr) &&
+- !kstrtouint(strrchr(rendpoint->full_name, '@') + 1, 0, &priv->port))
+- break;
+- }
+-
+- if (!priv->max9286_addr) {
+- dev_err(&client->dev, "deserializer does not present for ISX016\n");
+- return -EINVAL;
+- }
+-
+- isx016_s_port(client, 1);
+-
+- /* setup I2C translator address */
+- tmp_addr = client->addr;
+- if (priv->max9286_addr) {
+- client->addr = priv->max9271_addr; /* Serializer I2C address */
+- reg8_write(client, 0x09, tmp_addr << 1); /* Sensor translated I2C address */
+- usleep_range(2000, 2500); /* wait 2ms */
+- };
+- client->addr = tmp_addr;
+-
+- mdelay(10);
+-
+- return 0;
+-}
+-
+-static int isx016_probe(struct i2c_client *client,
+- const struct i2c_device_id *did)
+-{
+- struct isx016_priv *priv;
+- int ret;
+-
+- priv = devm_kzalloc(&client->dev, sizeof(*priv), GFP_KERNEL);
+- if (!priv)
+- return -ENOMEM;
+-
+- v4l2_i2c_subdev_init(&priv->sd, client, &isx016_subdev_ops);
+- priv->sd.flags = V4L2_SUBDEV_FL_HAS_DEVNODE;
+-
+- priv->exposure = 0x100;
+- priv->gain = 0x100;
+- priv->autogain = 1;
+- v4l2_ctrl_handler_init(&priv->hdl, 4);
+- v4l2_ctrl_new_std(&priv->hdl, &isx016_ctrl_ops,
+- V4L2_CID_BRIGHTNESS, 0, 16, 1, 7);
+- v4l2_ctrl_new_std(&priv->hdl, &isx016_ctrl_ops,
+- V4L2_CID_CONTRAST, 0, 16, 1, 7);
+- v4l2_ctrl_new_std(&priv->hdl, &isx016_ctrl_ops,
+- V4L2_CID_SATURATION, 0, 7, 1, 2);
+- v4l2_ctrl_new_std(&priv->hdl, &isx016_ctrl_ops,
+- V4L2_CID_HUE, 0, 23, 1, 12);
+- v4l2_ctrl_new_std(&priv->hdl, &isx016_ctrl_ops,
+- V4L2_CID_GAMMA, -128, 128, 1, 0);
+- v4l2_ctrl_new_std(&priv->hdl, &isx016_ctrl_ops,
+- V4L2_CID_SHARPNESS, 0, 10, 1, 3);
+- v4l2_ctrl_new_std(&priv->hdl, &isx016_ctrl_ops,
+- V4L2_CID_AUTOGAIN, 0, 1, 1, priv->autogain);
+- v4l2_ctrl_new_std(&priv->hdl, &isx016_ctrl_ops,
+- V4L2_CID_GAIN, 0, 0xffff, 1, priv->gain);
+- v4l2_ctrl_new_std(&priv->hdl, &isx016_ctrl_ops,
+- V4L2_CID_EXPOSURE, 0, 0xffff, 1, priv->exposure);
+- v4l2_ctrl_new_std(&priv->hdl, &isx016_ctrl_ops,
+- V4L2_CID_HFLIP, 0, 1, 1, 1);
+- v4l2_ctrl_new_std(&priv->hdl, &isx016_ctrl_ops,
+- V4L2_CID_VFLIP, 0, 1, 1, 0);
+- priv->sd.ctrl_handler = &priv->hdl;
+-
+- ret = priv->hdl.error;
+- if (ret)
+- goto cleanup;
+-
+- v4l2_ctrl_handler_setup(&priv->hdl);
+-
+- priv->pad.flags = MEDIA_PAD_FL_SOURCE;
+- priv->sd.entity.flags |= MEDIA_ENT_F_CAM_SENSOR;
+- ret = media_entity_pads_init(&priv->sd.entity, 1, &priv->pad);
+- if (ret < 0)
+- goto cleanup;
+-
+- ret = isx016_parse_dt(client->dev.of_node, priv);
+- if (ret)
+- goto cleanup;
+-
+- ret = isx016_initialize(client);
+- if (ret < 0)
+- goto cleanup;
+-
+- priv->rect.left = 0;
+- priv->rect.top = 0;
+- priv->rect.width = priv->max_width;
+- priv->rect.height = priv->max_height;
+-
+- ret = v4l2_async_register_subdev(&priv->sd);
+- if (ret)
+- goto cleanup;
+-
+- if (device_create_file(&client->dev, &dev_attr_otp_id_isx016) != 0) {
+- dev_err(&client->dev, "sysfs otp_id entry creation failed\n");
+- goto cleanup;
+- }
+-
+- priv->init_complete = 1;
+-
+- return 0;
+-
+-cleanup:
+- media_entity_cleanup(&priv->sd.entity);
+- v4l2_ctrl_handler_free(&priv->hdl);
+- v4l2_device_unregister_subdev(&priv->sd);
+-#ifdef CONFIG_SOC_CAMERA_ISX016
+- v4l_err(client, "failed to probe @ 0x%02x (%s)\n",
+- client->addr, client->adapter->name);
+-#endif
+- return ret;
+-}
+-
+-static int isx016_remove(struct i2c_client *client)
+-{
+- struct isx016_priv *priv = i2c_get_clientdata(client);
+-
+- device_remove_file(&client->dev, &dev_attr_otp_id_isx016);
+- v4l2_async_unregister_subdev(&priv->sd);
+- media_entity_cleanup(&priv->sd.entity);
+- v4l2_ctrl_handler_free(&priv->hdl);
+- v4l2_device_unregister_subdev(&priv->sd);
+-
+- return 0;
+-}
+-
+-#ifdef CONFIG_SOC_CAMERA_ISX016
+-static const struct i2c_device_id isx016_id[] = {
+- { "isx016", 0 },
+- { }
+-};
+-MODULE_DEVICE_TABLE(i2c, isx016_id);
+-
+-static const struct of_device_id isx016_of_ids[] = {
+- { .compatible = "aptina,isx016", },
+- { }
+-};
+-MODULE_DEVICE_TABLE(of, isx016_of_ids);
+-
+-static struct i2c_driver isx016_i2c_driver = {
+- .driver = {
+- .name = "isx016",
+- .of_match_table = isx016_of_ids,
+- },
+- .probe = isx016_probe,
+- .remove = isx016_remove,
+- .id_table = isx016_id,
+-};
+-
+-module_i2c_driver(isx016_i2c_driver);
+-
+-MODULE_DESCRIPTION("SoC Camera driver for ISX016");
+-MODULE_AUTHOR("Vladimir Barinov");
+-MODULE_LICENSE("GPL");
+-#endif
+diff --git a/drivers/media/i2c/soc_camera/isx016.h b/drivers/media/i2c/soc_camera/isx016.h
+deleted file mode 100644
+index f20d735..0000000
+--- a/drivers/media/i2c/soc_camera/isx016.h
++++ /dev/null
+@@ -1,27 +0,0 @@
+-/*
+- * ON Semiconductor isx016 sensor camera wizard 1280x800@30/UYVY/BT601/8bit
+- *
+- * Copyright (C) 2018 Cogent Embedded, Inc.
+- *
+- * This program is free software; you can redistribute it and/or modify it
+- * under the terms of the GNU General Public License as published by the
+- * Free Software Foundation; either version 2 of the License, or (at your
+- * option) any later version.
+- */
+-
+-#define ISX016_MAX_WIDTH 1280
+-#define ISX016_MAX_HEIGHT 800
+-
+-#define ISX016_DELAY 0xffff
+-
+-struct isx016_reg {
+- u16 reg;
+- u16 val;
+-};
+-
+-static const struct isx016_reg isx016_regs_wizard[] = {
+-#if 0
+-/* enable FSIN */
+-#endif
+-{ISX016_DELAY, 100},
+-};
+diff --git a/drivers/media/i2c/soc_camera/isx019.c b/drivers/media/i2c/soc_camera/isx019.c
+new file mode 100644
+index 0000000..8064789
+--- /dev/null
++++ b/drivers/media/i2c/soc_camera/isx019.c
+@@ -0,0 +1,628 @@
++/*
++ * ON Semiconductor ISX019 (isp) camera driver
++ *
++ * Copyright (C) 2018 Cogent Embedded, Inc.
++ *
++ * This program is free software; you can redistribute it and/or modify it
++ * under the terms of the GNU General Public License as published by the
++ * Free Software Foundation; either version 2 of the License, or (at your
++ * option) any later version.
++ */
++
++#include <linux/delay.h>
++#include <linux/init.h>
++#include <linux/i2c.h>
++#include <linux/module.h>
++#include <linux/of_graph.h>
++#include <linux/videodev2.h>
++
++#include <media/soc_camera.h>
++#include <media/v4l2-common.h>
++#include <media/v4l2-ctrls.h>
++
++#include "isx019.h"
++
++static const int isx019_i2c_addr[] = {0x1a};
++
++#define ISX019_PID 0x0000
++#define ISX019_VERSION_REG 0x0740
++
++#define ISX019_MEDIA_BUS_FMT MEDIA_BUS_FMT_YUYV8_2X8
++
++static void isx019_otp_id_read(struct i2c_client *client);
++
++struct isx019_priv {
++ struct v4l2_subdev sd;
++ struct v4l2_ctrl_handler hdl;
++ struct media_pad pad;
++ struct v4l2_rect rect;
++ int max_width;
++ int max_height;
++ int init_complete;
++ u8 id[6];
++ int exposure;
++ int gain;
++ int autogain;
++ /* serializers */
++ int max9286_addr;
++ int max9271_addr;
++ int port;
++ int gpio_resetb;
++ int gpio_fsin;
++};
++
++static inline struct isx019_priv *to_isx019(const struct i2c_client *client)
++{
++ return container_of(i2c_get_clientdata(client), struct isx019_priv, sd);
++}
++
++static void isx019_s_port(struct i2c_client *client, int fwd_en)
++{
++ struct isx019_priv *priv = to_isx019(client);
++ int tmp_addr;
++
++ if (priv->max9286_addr) {
++ tmp_addr = client->addr;
++ client->addr = priv->max9286_addr; /* Deserializer I2C address */
++ reg8_write(client, 0x0a, fwd_en ? 0x11 << priv->port : 0); /* Enable/disable reverse/forward control for this port */
++ usleep_range(5000, 5500); /* wait 5ms */
++ client->addr = tmp_addr;
++ };
++}
++
++static int isx019_read16(struct i2c_client *client, u8 category, u16 reg, u16 *val)
++{
++ int ret;
++ #define R_NUM_BYTES 9
++ #define R_NUM_CMDS 1
++ #define R_NUM_CMD_BYTES 6
++ #define R_CMD 1
++ #define R_BYTES 2
++ u8 buf[R_NUM_BYTES] = {R_NUM_BYTES, R_NUM_CMDS,
++ R_NUM_CMD_BYTES, R_CMD,
++ category, reg >> 8, reg & 0xff,
++ R_BYTES, 0x00};
++
++ /* calculate checksum */
++ buf[8] = R_NUM_BYTES + R_NUM_CMDS + R_NUM_CMD_BYTES + R_CMD +
++ category + (reg >> 8) + (reg & 0xff) + R_BYTES;
++
++ ret = i2c_master_send(client, buf, R_NUM_BYTES);
++ if (ret == R_NUM_BYTES)
++ ret = i2c_master_recv(client, buf, R_NUM_BYTES - 2);
++
++ if (ret < 0) {
++ dev_err(&client->dev,
++ "read fail: chip 0x%x register 0x%x: %d\n",
++ client->addr, reg, ret);
++ } else {
++ *val = ((u16)buf[4] << 8) | buf[5];
++ }
++
++ return ret < 0 ? ret : 0;
++}
++
++static int isx019_write16(struct i2c_client *client, u8 category, u16 reg, u16 val)
++{
++ int ret;
++ #define W_NUM_BYTES 10
++ #define W_NUM_CMDS 1
++ #define W_NUM_CMD_BYTES 7
++ #define W_CMD 2
++ u8 buf[W_NUM_BYTES] = {W_NUM_BYTES, W_NUM_CMDS,
++ W_NUM_CMD_BYTES, W_CMD,
++ category, reg >> 8, reg & 0xff,
++ val >> 8, val & 0xff};
++
++ /* calculate checksum */
++ buf[9] = W_NUM_BYTES + W_NUM_CMDS + W_NUM_CMD_BYTES + W_CMD +
++ category + (reg >> 8) + (reg & 0xff) + (val >> 8) + (val & 0xff);
++
++ ret = i2c_master_send(client, buf, W_NUM_BYTES);
++
++ if (ret < 0) {
++ dev_err(&client->dev,
++ "write fail: chip 0x%x register 0x%x: %d\n",
++ client->addr, reg, ret);
++ }
++
++ return ret < 0 ? ret : 0;
++}
++
++static int isx019_set_regs(struct i2c_client *client,
++ const struct isx019_reg *regs, int nr_regs)
++{
++ int i;
++
++ for (i = 0; i < nr_regs; i++) {
++ if (regs[i].reg == ISX019_DELAY) {
++ mdelay(regs[i].val);
++ continue;
++ }
++
++ isx019_write16(client, regs[i].reg >> 8, regs[i].reg & 0xff, regs[i].val);
++ }
++
++ return 0;
++}
++
++static int isx019_s_stream(struct v4l2_subdev *sd, int enable)
++{
++ return 0;
++}
++
++static int isx019_get_fmt(struct v4l2_subdev *sd,
++ struct v4l2_subdev_pad_config *cfg,
++ struct v4l2_subdev_format *format)
++{
++ struct v4l2_mbus_framefmt *mf = &format->format;
++ struct i2c_client *client = v4l2_get_subdevdata(sd);
++ struct isx019_priv *priv = to_isx019(client);
++
++ if (format->pad)
++ return -EINVAL;
++
++ mf->width = priv->rect.width;
++ mf->height = priv->rect.height;
++ mf->code = ISX019_MEDIA_BUS_FMT;
++ mf->colorspace = V4L2_COLORSPACE_SMPTE170M;
++ mf->field = V4L2_FIELD_NONE;
++
++ return 0;
++}
++
++static int isx019_set_fmt(struct v4l2_subdev *sd,
++ struct v4l2_subdev_pad_config *cfg,
++ struct v4l2_subdev_format *format)
++{
++ struct v4l2_mbus_framefmt *mf = &format->format;
++
++ mf->code = ISX019_MEDIA_BUS_FMT;
++ mf->colorspace = V4L2_COLORSPACE_SMPTE170M;
++ mf->field = V4L2_FIELD_NONE;
++
++ if (format->which == V4L2_SUBDEV_FORMAT_TRY)
++ cfg->try_fmt = *mf;
++
++ return 0;
++}
++
++static int isx019_enum_mbus_code(struct v4l2_subdev *sd,
++ struct v4l2_subdev_pad_config *cfg,
++ struct v4l2_subdev_mbus_code_enum *code)
++{
++ if (code->pad || code->index > 0)
++ return -EINVAL;
++
++ code->code = ISX019_MEDIA_BUS_FMT;
++
++ return 0;
++}
++
++static int isx019_get_edid(struct v4l2_subdev *sd, struct v4l2_edid *edid)
++{
++ struct i2c_client *client = v4l2_get_subdevdata(sd);
++ struct isx019_priv *priv = to_isx019(client);
++
++ isx019_otp_id_read(client);
++
++ memcpy(edid->edid, priv->id, 6);
++
++ edid->edid[6] = 0xff;
++ edid->edid[7] = client->addr;
++ edid->edid[8] = ISX019_VERSION_REG >> 8;
++ edid->edid[9] = ISX019_VERSION_REG & 0xff;
++
++ return 0;
++}
++
++static int isx019_set_selection(struct v4l2_subdev *sd,
++ struct v4l2_subdev_pad_config *cfg,
++ struct v4l2_subdev_selection *sel)
++{
++ struct v4l2_rect *rect = &sel->r;
++ struct i2c_client *client = v4l2_get_subdevdata(sd);
++ struct isx019_priv *priv = to_isx019(client);
++
++ if (sel->which != V4L2_SUBDEV_FORMAT_ACTIVE ||
++ sel->target != V4L2_SEL_TGT_CROP)
++ return -EINVAL;
++
++ rect->left = ALIGN(rect->left, 2);
++ rect->top = ALIGN(rect->top, 2);
++ rect->width = ALIGN(rect->width, 2);
++ rect->height = ALIGN(rect->height, 2);
++
++ if ((rect->left + rect->width > priv->max_width) ||
++ (rect->top + rect->height > priv->max_height))
++ *rect = priv->rect;
++
++ priv->rect.left = rect->left;
++ priv->rect.top = rect->top;
++ priv->rect.width = rect->width;
++ priv->rect.height = rect->height;
++
++ return 0;
++}
++
++static int isx019_get_selection(struct v4l2_subdev *sd,
++ struct v4l2_subdev_pad_config *cfg,
++ struct v4l2_subdev_selection *sel)
++{
++ struct i2c_client *client = v4l2_get_subdevdata(sd);
++ struct isx019_priv *priv = to_isx019(client);
++
++ if (sel->which != V4L2_SUBDEV_FORMAT_ACTIVE)
++ return -EINVAL;
++
++ switch (sel->target) {
++ case V4L2_SEL_TGT_CROP_BOUNDS:
++ sel->r.left = 0;
++ sel->r.top = 0;
++ sel->r.width = priv->max_width;
++ sel->r.height = priv->max_height;
++ return 0;
++ case V4L2_SEL_TGT_CROP_DEFAULT:
++ sel->r.left = 0;
++ sel->r.top = 0;
++ sel->r.width = priv->max_width;
++ sel->r.height = priv->max_height;
++ return 0;
++ case V4L2_SEL_TGT_CROP:
++ sel->r = priv->rect;
++ return 0;
++ default:
++ return -EINVAL;
++ }
++}
++
++static int isx019_g_mbus_config(struct v4l2_subdev *sd,
++ struct v4l2_mbus_config *cfg)
++{
++ cfg->flags = V4L2_MBUS_CSI2_1_LANE | V4L2_MBUS_CSI2_CHANNEL_0 |
++ V4L2_MBUS_CSI2_CONTINUOUS_CLOCK;
++ cfg->type = V4L2_MBUS_CSI2;
++
++ return 0;
++}
++
++#ifdef CONFIG_VIDEO_ADV_DEBUG
++static int isx019_g_register(struct v4l2_subdev *sd,
++ struct v4l2_dbg_register *reg)
++{
++ struct i2c_client *client = v4l2_get_subdevdata(sd);
++ int ret;
++ u16 val = 0;
++
++ ret = isx019_read16(client, (u16)reg->reg >> 8, (u16)reg->reg & 0xff, &val);
++ if (ret < 0)
++ return ret;
++
++ reg->val = val;
++ reg->size = sizeof(u16);
++
++ return 0;
++}
++
++static int isx019_s_register(struct v4l2_subdev *sd,
++ const struct v4l2_dbg_register *reg)
++{
++ struct i2c_client *client = v4l2_get_subdevdata(sd);
++
++ return isx019_write16(client, (u16)reg->reg >> 8, (u16)reg->reg & 0xff, (u16)reg->val);
++}
++#endif
++
++static struct v4l2_subdev_core_ops isx019_core_ops = {
++#ifdef CONFIG_VIDEO_ADV_DEBUG
++ .g_register = isx019_g_register,
++ .s_register = isx019_s_register,
++#endif
++};
++
++static int isx019_s_ctrl(struct v4l2_ctrl *ctrl)
++{
++ struct v4l2_subdev *sd = to_sd(ctrl);
++ struct i2c_client *client = v4l2_get_subdevdata(sd);
++ struct isx019_priv *priv = to_isx019(client);
++ int ret = -EINVAL;
++
++ if (!priv->init_complete)
++ return 0;
++
++ switch (ctrl->id) {
++ case V4L2_CID_BRIGHTNESS:
++ case V4L2_CID_CONTRAST:
++ case V4L2_CID_SATURATION:
++ case V4L2_CID_HUE:
++ case V4L2_CID_GAMMA:
++ case V4L2_CID_SHARPNESS:
++ case V4L2_CID_AUTOGAIN:
++ case V4L2_CID_GAIN:
++ case V4L2_CID_EXPOSURE:
++ case V4L2_CID_HFLIP:
++ case V4L2_CID_VFLIP:
++ break;
++ }
++
++ return ret;
++}
++
++static const struct v4l2_ctrl_ops isx019_ctrl_ops = {
++ .s_ctrl = isx019_s_ctrl,
++};
++
++static struct v4l2_subdev_video_ops isx019_video_ops = {
++ .s_stream = isx019_s_stream,
++ .g_mbus_config = isx019_g_mbus_config,
++};
++
++static const struct v4l2_subdev_pad_ops isx019_subdev_pad_ops = {
++ .get_edid = isx019_get_edid,
++ .enum_mbus_code = isx019_enum_mbus_code,
++ .get_selection = isx019_get_selection,
++ .set_selection = isx019_set_selection,
++ .get_fmt = isx019_get_fmt,
++ .set_fmt = isx019_set_fmt,
++};
++
++static struct v4l2_subdev_ops isx019_subdev_ops = {
++ .core = &isx019_core_ops,
++ .video = &isx019_video_ops,
++ .pad = &isx019_subdev_pad_ops,
++};
++
++static void isx019_otp_id_read(struct i2c_client *client)
++{
++ struct isx019_priv *priv = to_isx019(client);
++ int i;
++ u16 val = 0;
++
++ /* read camera id from isx019 OTP memory */
++ for (i = 0; i < 6; i+=2) {
++ isx019_read16(client, 8, 0x60 + i, &val);
++ priv->id[i] = val >> 8;
++ priv->id[i+1] = val & 0xff;
++ }
++}
++
++static ssize_t isx019_otp_id_show(struct device *dev,
++ struct device_attribute *attr, char *buf)
++{
++ struct v4l2_subdev *sd = i2c_get_clientdata(to_i2c_client(dev));
++ struct i2c_client *client = v4l2_get_subdevdata(sd);
++ struct isx019_priv *priv = to_isx019(client);
++
++ isx019_otp_id_read(client);
++
++ return snprintf(buf, 32, "%02x:%02x:%02x:%02x:%02x:%02x\n",
++ priv->id[0], priv->id[1], priv->id[2], priv->id[3], priv->id[4], priv->id[5]);
++}
++
++static DEVICE_ATTR(otp_id_isx019, S_IRUGO, isx019_otp_id_show, NULL);
++
++static int isx019_initialize(struct i2c_client *client)
++{
++ struct isx019_priv *priv = to_isx019(client);
++ u16 pid = 0;
++ int ret = 0;
++ int tmp_addr;
++ int i;
++
++ isx019_s_port(client, 1);
++
++ for (i = 0; i < ARRAY_SIZE(isx019_i2c_addr); i++) {
++ tmp_addr = client->addr;
++ if (priv->max9286_addr) {
++ client->addr = priv->max9271_addr; /* Serializer I2C address */
++ reg8_write(client, 0x0A, isx019_i2c_addr[i] << 1); /* Sensor native I2C address */
++ usleep_range(2000, 2500); /* wait 2ms */
++ };
++ client->addr = tmp_addr;
++
++ /* check model ID */
++ isx019_read16(client, 0, ISX019_PID, &pid);
++
++ if (pid == ISX019_VERSION_REG)
++ break;
++ }
++
++ if (pid != ISX019_VERSION_REG) {
++ dev_dbg(&client->dev, "Product ID error %x\n", pid);
++ ret = -ENODEV;
++ goto err;
++ }
++
++ priv->max_width = ISX019_MAX_WIDTH;
++ priv->max_height = ISX019_MAX_HEIGHT;
++
++ /* Read OTP IDs */
++ isx019_otp_id_read(client);
++ /* Program wizard registers */
++ isx019_set_regs(client, isx019_regs_wizard, ARRAY_SIZE(isx019_regs_wizard));
++
++ dev_info(&client->dev, "isx019 PID %x, res %dx%d, OTP_ID %02x:%02x:%02x:%02x:%02x:%02x\n",
++ pid, priv->max_width, priv->max_height, priv->id[0], priv->id[1], priv->id[2], priv->id[3], priv->id[4], priv->id[5]);
++err:
++ isx019_s_port(client, 0);
++
++ return ret;
++}
++
++static int isx019_parse_dt(struct device_node *np, struct isx019_priv *priv)
++{
++ struct i2c_client *client = v4l2_get_subdevdata(&priv->sd);
++ int i;
++ struct device_node *endpoint = NULL, *rendpoint = NULL;
++ int tmp_addr = 0;
++
++ for (i = 0; ; i++) {
++ endpoint = of_graph_get_next_endpoint(np, endpoint);
++ if (!endpoint)
++ break;
++
++ of_node_put(endpoint);
++
++ rendpoint = of_parse_phandle(endpoint, "remote-endpoint", 0);
++ if (!rendpoint)
++ continue;
++
++ if (!of_property_read_u32(rendpoint, "max9271-addr", &priv->max9271_addr) &&
++ !of_property_read_u32(rendpoint->parent->parent, "reg", &priv->max9286_addr) &&
++ !kstrtouint(strrchr(rendpoint->full_name, '@') + 1, 0, &priv->port))
++ break;
++ }
++
++ if (!priv->max9286_addr) {
++ dev_err(&client->dev, "deserializer does not present for ISX019\n");
++ return -EINVAL;
++ }
++
++ isx019_s_port(client, 1);
++
++ /* setup I2C translator address */
++ tmp_addr = client->addr;
++ if (priv->max9286_addr) {
++ client->addr = priv->max9271_addr; /* Serializer I2C address */
++ reg8_write(client, 0x09, tmp_addr << 1); /* Sensor translated I2C address */
++ usleep_range(2000, 2500); /* wait 2ms */
++ };
++ client->addr = tmp_addr;
++
++ mdelay(10);
++
++ return 0;
++}
++
++static int isx019_probe(struct i2c_client *client,
++ const struct i2c_device_id *did)
++{
++ struct isx019_priv *priv;
++ int ret;
++
++ priv = devm_kzalloc(&client->dev, sizeof(*priv), GFP_KERNEL);
++ if (!priv)
++ return -ENOMEM;
++
++ v4l2_i2c_subdev_init(&priv->sd, client, &isx019_subdev_ops);
++ priv->sd.flags = V4L2_SUBDEV_FL_HAS_DEVNODE;
++
++ priv->exposure = 0x100;
++ priv->gain = 0x100;
++ priv->autogain = 1;
++ v4l2_ctrl_handler_init(&priv->hdl, 4);
++ v4l2_ctrl_new_std(&priv->hdl, &isx019_ctrl_ops,
++ V4L2_CID_BRIGHTNESS, 0, 16, 1, 7);
++ v4l2_ctrl_new_std(&priv->hdl, &isx019_ctrl_ops,
++ V4L2_CID_CONTRAST, 0, 16, 1, 7);
++ v4l2_ctrl_new_std(&priv->hdl, &isx019_ctrl_ops,
++ V4L2_CID_SATURATION, 0, 7, 1, 2);
++ v4l2_ctrl_new_std(&priv->hdl, &isx019_ctrl_ops,
++ V4L2_CID_HUE, 0, 23, 1, 12);
++ v4l2_ctrl_new_std(&priv->hdl, &isx019_ctrl_ops,
++ V4L2_CID_GAMMA, -128, 128, 1, 0);
++ v4l2_ctrl_new_std(&priv->hdl, &isx019_ctrl_ops,
++ V4L2_CID_SHARPNESS, 0, 10, 1, 3);
++ v4l2_ctrl_new_std(&priv->hdl, &isx019_ctrl_ops,
++ V4L2_CID_AUTOGAIN, 0, 1, 1, priv->autogain);
++ v4l2_ctrl_new_std(&priv->hdl, &isx019_ctrl_ops,
++ V4L2_CID_GAIN, 0, 0xffff, 1, priv->gain);
++ v4l2_ctrl_new_std(&priv->hdl, &isx019_ctrl_ops,
++ V4L2_CID_EXPOSURE, 0, 0xffff, 1, priv->exposure);
++ v4l2_ctrl_new_std(&priv->hdl, &isx019_ctrl_ops,
++ V4L2_CID_HFLIP, 0, 1, 1, 1);
++ v4l2_ctrl_new_std(&priv->hdl, &isx019_ctrl_ops,
++ V4L2_CID_VFLIP, 0, 1, 1, 0);
++ priv->sd.ctrl_handler = &priv->hdl;
++
++ ret = priv->hdl.error;
++ if (ret)
++ goto cleanup;
++
++ v4l2_ctrl_handler_setup(&priv->hdl);
++
++ priv->pad.flags = MEDIA_PAD_FL_SOURCE;
++ priv->sd.entity.flags |= MEDIA_ENT_F_CAM_SENSOR;
++ ret = media_entity_pads_init(&priv->sd.entity, 1, &priv->pad);
++ if (ret < 0)
++ goto cleanup;
++
++ ret = isx019_parse_dt(client->dev.of_node, priv);
++ if (ret)
++ goto cleanup;
++
++ ret = isx019_initialize(client);
++ if (ret < 0)
++ goto cleanup;
++
++ priv->rect.left = 0;
++ priv->rect.top = 0;
++ priv->rect.width = priv->max_width;
++ priv->rect.height = priv->max_height;
++
++ ret = v4l2_async_register_subdev(&priv->sd);
++ if (ret)
++ goto cleanup;
++
++ if (device_create_file(&client->dev, &dev_attr_otp_id_isx019) != 0) {
++ dev_err(&client->dev, "sysfs otp_id entry creation failed\n");
++ goto cleanup;
++ }
++
++ priv->init_complete = 1;
++
++ return 0;
++
++cleanup:
++ media_entity_cleanup(&priv->sd.entity);
++ v4l2_ctrl_handler_free(&priv->hdl);
++ v4l2_device_unregister_subdev(&priv->sd);
++#ifdef CONFIG_SOC_CAMERA_ISX019
++ v4l_err(client, "failed to probe @ 0x%02x (%s)\n",
++ client->addr, client->adapter->name);
++#endif
++ return ret;
++}
++
++static int isx019_remove(struct i2c_client *client)
++{
++ struct isx019_priv *priv = i2c_get_clientdata(client);
++
++ device_remove_file(&client->dev, &dev_attr_otp_id_isx019);
++ v4l2_async_unregister_subdev(&priv->sd);
++ media_entity_cleanup(&priv->sd.entity);
++ v4l2_ctrl_handler_free(&priv->hdl);
++ v4l2_device_unregister_subdev(&priv->sd);
++
++ return 0;
++}
++
++#ifdef CONFIG_SOC_CAMERA_ISX019
++static const struct i2c_device_id isx019_id[] = {
++ { "isx019", 0 },
++ { }
++};
++MODULE_DEVICE_TABLE(i2c, isx019_id);
++
++static const struct of_device_id isx019_of_ids[] = {
++ { .compatible = "aptina,isx019", },
++ { }
++};
++MODULE_DEVICE_TABLE(of, isx019_of_ids);
++
++static struct i2c_driver isx019_i2c_driver = {
++ .driver = {
++ .name = "isx019",
++ .of_match_table = isx019_of_ids,
++ },
++ .probe = isx019_probe,
++ .remove = isx019_remove,
++ .id_table = isx019_id,
++};
++
++module_i2c_driver(isx019_i2c_driver);
++
++MODULE_DESCRIPTION("SoC Camera driver for ISX019");
++MODULE_AUTHOR("Vladimir Barinov");
++MODULE_LICENSE("GPL");
++#endif
+diff --git a/drivers/media/i2c/soc_camera/isx019.h b/drivers/media/i2c/soc_camera/isx019.h
+new file mode 100644
+index 0000000..0593be1
+--- /dev/null
++++ b/drivers/media/i2c/soc_camera/isx019.h
+@@ -0,0 +1,27 @@
++/*
++ * ON Semiconductor isx019 (isp) camera wizard 1280x800@30/UYVY/BT601/8bit
++ *
++ * Copyright (C) 2018 Cogent Embedded, Inc.
++ *
++ * This program is free software; you can redistribute it and/or modify it
++ * under the terms of the GNU General Public License as published by the
++ * Free Software Foundation; either version 2 of the License, or (at your
++ * option) any later version.
++ */
++
++#define ISX019_MAX_WIDTH 1280
++#define ISX019_MAX_HEIGHT 800
++
++#define ISX019_DELAY 0xffff
++
++struct isx019_reg {
++ u16 reg;
++ u16 val;
++};
++
++static const struct isx019_reg isx019_regs_wizard[] = {
++#if 0
++/* enable FSIN */
++#endif
++{ISX019_DELAY, 100},
++};
+diff --git a/drivers/media/i2c/soc_camera/ov106xx.c b/drivers/media/i2c/soc_camera/ov106xx.c
+index b0a3c90..79a69a0 100644
+--- a/drivers/media/i2c/soc_camera/ov106xx.c
++++ b/drivers/media/i2c/soc_camera/ov106xx.c
+@@ -25,7 +25,7 @@
+ #include "ov2775.c"
+ #include "imx390.c"
+ #include "ox03a.c"
+-#include "isx016.c"
++#include "isx019.c"
+
+ static enum {
+ ID_OV10635,
+@@ -44,7 +44,7 @@ static enum {
+ ID_OV2775,
+ ID_IMX390,
+ ID_OX03A,
+- ID_ISX016,
++ ID_ISX019,
+ } chip_id;
+
+ static int ov106xx_probe(struct i2c_client *client,
+@@ -149,9 +149,9 @@ static int ov106xx_probe(struct i2c_client *client,
+ goto out;
+ }
+
+- ret = isx016_probe(client, did);
++ ret = isx019_probe(client, did);
+ if (!ret) {
+- chip_id = ID_ISX016;
++ chip_id = ID_ISX019;
+ goto out;
+ }
+
+@@ -212,8 +212,8 @@ static int ov106xx_remove(struct i2c_client *client)
+ case ID_OX03A:
+ ox03a_remove(client);
+ break;
+- case ID_ISX016:
+- isx016_remove(client);
++ case ID_ISX019:
++ isx019_remove(client);
+ break;
+ };
+
+--
+2.7.4
+
diff --git a/bsp/meta-rcar/meta-rcar-gen3-adas/recipes-kernel/linux/linux-renesas/0150-lvds-add-ISX016-imager.patch b/bsp/meta-rcar/meta-rcar-gen3-adas/recipes-kernel/linux/linux-renesas/0150-lvds-add-ISX016-imager.patch
new file mode 100644
index 00000000..b4468e7e
--- /dev/null
+++ b/bsp/meta-rcar/meta-rcar-gen3-adas/recipes-kernel/linux/linux-renesas/0150-lvds-add-ISX016-imager.patch
@@ -0,0 +1,705 @@
+From b22b3f2f5d7a5d112451569df9e81d842bd5af02 Mon Sep 17 00:00:00 2001
+From: Vladimir Barinov <vladimir.barinov@cogentembedded.com>
+Date: Thu, 7 Feb 2019 12:07:05 +0300
+Subject: [PATCH 099/122] lvds: add ISX016 imager
+
+This adds ISX016 imager support
+
+Signed-off-by: Vladimir Barinov <vladimir.barinov@cogentembedded.com>
+---
+ drivers/media/i2c/soc_camera/isx016.c | 604 +++++++++++++++++++++++++++++++++
+ drivers/media/i2c/soc_camera/isx016.h | 27 ++
+ drivers/media/i2c/soc_camera/ov106xx.c | 11 +
+ 3 files changed, 642 insertions(+)
+ create mode 100644 drivers/media/i2c/soc_camera/isx016.c
+ create mode 100644 drivers/media/i2c/soc_camera/isx016.h
+
+diff --git a/drivers/media/i2c/soc_camera/isx016.c b/drivers/media/i2c/soc_camera/isx016.c
+new file mode 100644
+index 0000000..4002008
+--- /dev/null
++++ b/drivers/media/i2c/soc_camera/isx016.c
+@@ -0,0 +1,604 @@
++/*
++ * ON Semiconductor ISX016 (isp) camera driver
++ *
++ * Copyright (C) 2019 Cogent Embedded, Inc.
++ *
++ * This program is free software; you can redistribute it and/or modify it
++ * under the terms of the GNU General Public License as published by the
++ * Free Software Foundation; either version 2 of the License, or (at your
++ * option) any later version.
++ */
++
++#include <linux/delay.h>
++#include <linux/init.h>
++#include <linux/i2c.h>
++#include <linux/module.h>
++#include <linux/of_graph.h>
++#include <linux/videodev2.h>
++
++#include <media/soc_camera.h>
++#include <media/v4l2-common.h>
++#include <media/v4l2-ctrls.h>
++
++#include "isx016.h"
++
++static const int isx016_i2c_addr[] = {0x1a};
++
++#define ISX016_PID 0x0000
++#define ISX016_VERSION_REG 0x0D20
++
++#define ISX016_MEDIA_BUS_FMT MEDIA_BUS_FMT_YUYV8_2X8
++
++static void isx016_otp_id_read(struct i2c_client *client);
++
++struct isx016_priv {
++ struct v4l2_subdev sd;
++ struct v4l2_ctrl_handler hdl;
++ struct media_pad pad;
++ struct v4l2_rect rect;
++ int max_width;
++ int max_height;
++ int init_complete;
++ u8 id[6];
++ int exposure;
++ int gain;
++ int autogain;
++ /* serializers */
++ int max9286_addr;
++ int max9271_addr;
++ int ti9x4_addr;
++ int ti9x3_addr;
++ int port;
++ int gpio_resetb;
++ int gpio_fsin;
++};
++
++static inline struct isx016_priv *to_isx016(const struct i2c_client *client)
++{
++ return container_of(i2c_get_clientdata(client), struct isx016_priv, sd);
++}
++
++static void isx016_s_port(struct i2c_client *client, int fwd_en)
++{
++ struct isx016_priv *priv = to_isx016(client);
++ int tmp_addr;
++
++ if (priv->max9286_addr) {
++ tmp_addr = client->addr;
++ client->addr = priv->max9286_addr; /* Deserializer I2C address */
++ reg8_write(client, 0x0a, fwd_en ? 0x11 << priv->port : 0); /* Enable/disable reverse/forward control for this port */
++ usleep_range(5000, 5500); /* wait 5ms */
++ client->addr = tmp_addr;
++ };
++}
++
++static int isx016_read16(struct i2c_client *client, u8 category, u16 reg, u16 *val)
++{
++ reg16_write(client, 0xFFFF, category);
++ reg16_read16(client, reg, val);
++
++ return 0;
++}
++
++static int isx016_write16(struct i2c_client *client, u8 category, u16 reg, u16 val)
++{
++ reg16_write(client, 0xFFFF, category);
++ reg16_write16(client, reg, val);
++
++ return 0;
++}
++
++static int isx016_set_regs(struct i2c_client *client,
++ const struct isx016_reg *regs, int nr_regs)
++{
++ int i;
++
++ for (i = 0; i < nr_regs; i++) {
++ if (regs[i].reg == ISX016_DELAY) {
++ mdelay(regs[i].val);
++ continue;
++ }
++
++ isx016_write16(client, regs[i].reg >> 8, regs[i].reg & 0xff, regs[i].val);
++ }
++
++ return 0;
++}
++
++static int isx016_s_stream(struct v4l2_subdev *sd, int enable)
++{
++ return 0;
++}
++
++static int isx016_get_fmt(struct v4l2_subdev *sd,
++ struct v4l2_subdev_pad_config *cfg,
++ struct v4l2_subdev_format *format)
++{
++ struct v4l2_mbus_framefmt *mf = &format->format;
++ struct i2c_client *client = v4l2_get_subdevdata(sd);
++ struct isx016_priv *priv = to_isx016(client);
++
++ if (format->pad)
++ return -EINVAL;
++
++ mf->width = priv->rect.width;
++ mf->height = priv->rect.height;
++ mf->code = ISX016_MEDIA_BUS_FMT;
++ mf->colorspace = V4L2_COLORSPACE_SMPTE170M;
++ mf->field = V4L2_FIELD_NONE;
++
++ return 0;
++}
++
++static int isx016_set_fmt(struct v4l2_subdev *sd,
++ struct v4l2_subdev_pad_config *cfg,
++ struct v4l2_subdev_format *format)
++{
++ struct v4l2_mbus_framefmt *mf = &format->format;
++
++ mf->code = ISX016_MEDIA_BUS_FMT;
++ mf->colorspace = V4L2_COLORSPACE_SMPTE170M;
++ mf->field = V4L2_FIELD_NONE;
++
++ if (format->which == V4L2_SUBDEV_FORMAT_TRY)
++ cfg->try_fmt = *mf;
++
++ return 0;
++}
++
++static int isx016_enum_mbus_code(struct v4l2_subdev *sd,
++ struct v4l2_subdev_pad_config *cfg,
++ struct v4l2_subdev_mbus_code_enum *code)
++{
++ if (code->pad || code->index > 0)
++ return -EINVAL;
++
++ code->code = ISX016_MEDIA_BUS_FMT;
++
++ return 0;
++}
++
++static int isx016_get_edid(struct v4l2_subdev *sd, struct v4l2_edid *edid)
++{
++ struct i2c_client *client = v4l2_get_subdevdata(sd);
++ struct isx016_priv *priv = to_isx016(client);
++
++ isx016_otp_id_read(client);
++
++ memcpy(edid->edid, priv->id, 6);
++
++ edid->edid[6] = 0xff;
++ edid->edid[7] = client->addr;
++ edid->edid[8] = ISX016_VERSION_REG >> 8;
++ edid->edid[9] = ISX016_VERSION_REG & 0xff;
++
++ return 0;
++}
++
++static int isx016_set_selection(struct v4l2_subdev *sd,
++ struct v4l2_subdev_pad_config *cfg,
++ struct v4l2_subdev_selection *sel)
++{
++ struct v4l2_rect *rect = &sel->r;
++ struct i2c_client *client = v4l2_get_subdevdata(sd);
++ struct isx016_priv *priv = to_isx016(client);
++
++ if (sel->which != V4L2_SUBDEV_FORMAT_ACTIVE ||
++ sel->target != V4L2_SEL_TGT_CROP)
++ return -EINVAL;
++
++ rect->left = ALIGN(rect->left, 2);
++ rect->top = ALIGN(rect->top, 2);
++ rect->width = ALIGN(rect->width, 2);
++ rect->height = ALIGN(rect->height, 2);
++
++ if ((rect->left + rect->width > priv->max_width) ||
++ (rect->top + rect->height > priv->max_height))
++ *rect = priv->rect;
++
++ priv->rect.left = rect->left;
++ priv->rect.top = rect->top;
++ priv->rect.width = rect->width;
++ priv->rect.height = rect->height;
++
++ return 0;
++}
++
++static int isx016_get_selection(struct v4l2_subdev *sd,
++ struct v4l2_subdev_pad_config *cfg,
++ struct v4l2_subdev_selection *sel)
++{
++ struct i2c_client *client = v4l2_get_subdevdata(sd);
++ struct isx016_priv *priv = to_isx016(client);
++
++ if (sel->which != V4L2_SUBDEV_FORMAT_ACTIVE)
++ return -EINVAL;
++
++ switch (sel->target) {
++ case V4L2_SEL_TGT_CROP_BOUNDS:
++ sel->r.left = 0;
++ sel->r.top = 0;
++ sel->r.width = priv->max_width;
++ sel->r.height = priv->max_height;
++ return 0;
++ case V4L2_SEL_TGT_CROP_DEFAULT:
++ sel->r.left = 0;
++ sel->r.top = 0;
++ sel->r.width = priv->max_width;
++ sel->r.height = priv->max_height;
++ return 0;
++ case V4L2_SEL_TGT_CROP:
++ sel->r = priv->rect;
++ return 0;
++ default:
++ return -EINVAL;
++ }
++}
++
++static int isx016_g_mbus_config(struct v4l2_subdev *sd,
++ struct v4l2_mbus_config *cfg)
++{
++ cfg->flags = V4L2_MBUS_CSI2_1_LANE | V4L2_MBUS_CSI2_CHANNEL_0 |
++ V4L2_MBUS_CSI2_CONTINUOUS_CLOCK;
++ cfg->type = V4L2_MBUS_CSI2;
++
++ return 0;
++}
++
++#ifdef CONFIG_VIDEO_ADV_DEBUG
++static int isx016_g_register(struct v4l2_subdev *sd,
++ struct v4l2_dbg_register *reg)
++{
++ struct i2c_client *client = v4l2_get_subdevdata(sd);
++ int ret;
++ u16 val = 0;
++
++ ret = isx016_read16(client, (u16)reg->reg >> 8, (u16)reg->reg & 0xff, &val);
++ if (ret < 0)
++ return ret;
++
++ reg->val = val;
++ reg->size = sizeof(u16);
++
++ return 0;
++}
++
++static int isx016_s_register(struct v4l2_subdev *sd,
++ const struct v4l2_dbg_register *reg)
++{
++ struct i2c_client *client = v4l2_get_subdevdata(sd);
++
++ return isx016_write16(client, (u16)reg->reg >> 8, (u16)reg->reg & 0xff, (u16)reg->val);
++}
++#endif
++
++static struct v4l2_subdev_core_ops isx016_core_ops = {
++#ifdef CONFIG_VIDEO_ADV_DEBUG
++ .g_register = isx016_g_register,
++ .s_register = isx016_s_register,
++#endif
++};
++
++static int isx016_s_ctrl(struct v4l2_ctrl *ctrl)
++{
++ struct v4l2_subdev *sd = to_sd(ctrl);
++ struct i2c_client *client = v4l2_get_subdevdata(sd);
++ struct isx016_priv *priv = to_isx016(client);
++ int ret = -EINVAL;
++
++ if (!priv->init_complete)
++ return 0;
++
++ switch (ctrl->id) {
++ case V4L2_CID_BRIGHTNESS:
++ case V4L2_CID_CONTRAST:
++ case V4L2_CID_SATURATION:
++ case V4L2_CID_HUE:
++ case V4L2_CID_GAMMA:
++ case V4L2_CID_SHARPNESS:
++ case V4L2_CID_AUTOGAIN:
++ case V4L2_CID_GAIN:
++ case V4L2_CID_EXPOSURE:
++ case V4L2_CID_HFLIP:
++ case V4L2_CID_VFLIP:
++ break;
++ }
++
++ return ret;
++}
++
++static const struct v4l2_ctrl_ops isx016_ctrl_ops = {
++ .s_ctrl = isx016_s_ctrl,
++};
++
++static struct v4l2_subdev_video_ops isx016_video_ops = {
++ .s_stream = isx016_s_stream,
++ .g_mbus_config = isx016_g_mbus_config,
++};
++
++static const struct v4l2_subdev_pad_ops isx016_subdev_pad_ops = {
++ .get_edid = isx016_get_edid,
++ .enum_mbus_code = isx016_enum_mbus_code,
++ .get_selection = isx016_get_selection,
++ .set_selection = isx016_set_selection,
++ .get_fmt = isx016_get_fmt,
++ .set_fmt = isx016_set_fmt,
++};
++
++static struct v4l2_subdev_ops isx016_subdev_ops = {
++ .core = &isx016_core_ops,
++ .video = &isx016_video_ops,
++ .pad = &isx016_subdev_pad_ops,
++};
++
++static void isx016_otp_id_read(struct i2c_client *client)
++{
++ struct isx016_priv *priv = to_isx016(client);
++ int i;
++ u16 val = 0;
++
++ /* read camera id from isx016 FUSEs */
++ for (i = 0; i < 6; i+=2) {
++ isx016_read16(client, 92, 0x0a + i, &val);
++ priv->id[i] = val >> 8;
++ priv->id[i+1] = val & 0xff;
++ }
++}
++
++static ssize_t isx016_otp_id_show(struct device *dev,
++ struct device_attribute *attr, char *buf)
++{
++ struct v4l2_subdev *sd = i2c_get_clientdata(to_i2c_client(dev));
++ struct i2c_client *client = v4l2_get_subdevdata(sd);
++ struct isx016_priv *priv = to_isx016(client);
++
++ isx016_otp_id_read(client);
++
++ return snprintf(buf, 32, "%02x:%02x:%02x:%02x:%02x:%02x\n",
++ priv->id[0], priv->id[1], priv->id[2], priv->id[3], priv->id[4], priv->id[5]);
++}
++
++static DEVICE_ATTR(otp_id_isx016, S_IRUGO, isx016_otp_id_show, NULL);
++
++static int isx016_initialize(struct i2c_client *client)
++{
++ struct isx016_priv *priv = to_isx016(client);
++ u16 pid = 0;
++ int ret = 0;
++ int tmp_addr;
++ int i;
++
++ isx016_s_port(client, 1);
++
++ for (i = 0; i < ARRAY_SIZE(isx016_i2c_addr); i++) {
++ tmp_addr = client->addr;
++ if (priv->max9286_addr) {
++ client->addr = priv->max9271_addr; /* Serializer I2C address */
++ reg8_write(client, 0x0A, isx016_i2c_addr[i] << 1); /* Sensor native I2C address */
++ usleep_range(2000, 2500); /* wait 2ms */
++ };
++ if (priv->ti9x4_addr) {
++ client->addr = priv->ti9x4_addr; /* Deserializer I2C address */
++ reg8_write(client, 0x5d, isx016_i2c_addr[i] << 1); /* Sensor native I2C address */
++ usleep_range(2000, 2500); /* wait 2ms */
++ }
++ client->addr = tmp_addr;
++
++ /* check model ID */
++ isx016_read16(client, 0, ISX016_PID, &pid);
++
++ if (pid == ISX016_VERSION_REG)
++ break;
++ }
++
++ if (pid != ISX016_VERSION_REG) {
++ dev_err(&client->dev, "Product ID error %x\n", pid);
++ ret = -ENODEV;
++ goto err;
++ }
++
++ priv->max_width = ISX016_MAX_WIDTH;
++ priv->max_height = ISX016_MAX_HEIGHT;
++
++ /* Read OTP IDs */
++ isx016_otp_id_read(client);
++ /* Program wizard registers */
++ isx016_set_regs(client, isx016_regs_wizard, ARRAY_SIZE(isx016_regs_wizard));
++
++ dev_info(&client->dev, "isx016 PID %x, res %dx%d, OTP_ID %02x:%02x:%02x:%02x:%02x:%02x\n",
++ pid, priv->max_width, priv->max_height, priv->id[0], priv->id[1], priv->id[2], priv->id[3], priv->id[4], priv->id[5]);
++err:
++ isx016_s_port(client, 0);
++
++ return ret;
++}
++
++static int isx016_parse_dt(struct device_node *np, struct isx016_priv *priv)
++{
++ struct i2c_client *client = v4l2_get_subdevdata(&priv->sd);
++ int i;
++ struct device_node *endpoint = NULL, *rendpoint = NULL;
++ int tmp_addr = 0;
++
++ for (i = 0; ; i++) {
++ endpoint = of_graph_get_next_endpoint(np, endpoint);
++ if (!endpoint)
++ break;
++
++ of_node_put(endpoint);
++
++ rendpoint = of_parse_phandle(endpoint, "remote-endpoint", 0);
++ if (!rendpoint)
++ continue;
++
++ if (!of_property_read_u32(rendpoint, "max9271-addr", &priv->max9271_addr) &&
++ !of_property_read_u32(rendpoint->parent->parent, "reg", &priv->max9286_addr) &&
++ !kstrtouint(strrchr(rendpoint->full_name, '@') + 1, 0, &priv->port))
++ break;
++
++ if (!of_property_read_u32(rendpoint, "ti9x3-addr", &priv->ti9x3_addr) &&
++ !of_property_match_string(rendpoint->parent->parent, "compatible", "ti,ti9x4") &&
++ !of_property_read_u32(rendpoint->parent->parent, "reg", &priv->ti9x4_addr) &&
++ !kstrtouint(strrchr(rendpoint->full_name, '@') + 1, 0, &priv->port))
++ break;
++ }
++
++ if (!priv->max9286_addr && !priv->ti9x4_addr) {
++ dev_err(&client->dev, "deserializer does not present for ISX016\n");
++ return -EINVAL;
++ }
++
++ isx016_s_port(client, 1);
++
++ /* setup I2C translator address */
++ tmp_addr = client->addr;
++ if (priv->max9286_addr) {
++ client->addr = priv->max9271_addr; /* Serializer I2C address */
++
++ reg8_write(client, 0x09, tmp_addr << 1); /* Sensor translated I2C address */
++ usleep_range(2000, 2500); /* wait 2ms */
++ };
++ if (priv->ti9x4_addr) {
++ client->addr = priv->ti9x4_addr; /* Deserializer I2C address */
++
++ reg8_write(client, 0x4c, (priv->port << 4) | (1 << priv->port)); /* Select RX port number */
++ usleep_range(2000, 2500); /* wait 2ms */
++ reg8_write(client, 0x65, tmp_addr << 1); /* Sensor translated I2C address */
++ }
++ client->addr = tmp_addr;
++
++ return 0;
++}
++
++static int isx016_probe(struct i2c_client *client,
++ const struct i2c_device_id *did)
++{
++ struct isx016_priv *priv;
++ int ret;
++
++ priv = devm_kzalloc(&client->dev, sizeof(*priv), GFP_KERNEL);
++ if (!priv)
++ return -ENOMEM;
++
++ v4l2_i2c_subdev_init(&priv->sd, client, &isx016_subdev_ops);
++ priv->sd.flags = V4L2_SUBDEV_FL_HAS_DEVNODE;
++
++ priv->exposure = 0x100;
++ priv->gain = 0x100;
++ priv->autogain = 1;
++ v4l2_ctrl_handler_init(&priv->hdl, 4);
++ v4l2_ctrl_new_std(&priv->hdl, &isx016_ctrl_ops,
++ V4L2_CID_BRIGHTNESS, 0, 16, 1, 7);
++ v4l2_ctrl_new_std(&priv->hdl, &isx016_ctrl_ops,
++ V4L2_CID_CONTRAST, 0, 16, 1, 7);
++ v4l2_ctrl_new_std(&priv->hdl, &isx016_ctrl_ops,
++ V4L2_CID_SATURATION, 0, 7, 1, 2);
++ v4l2_ctrl_new_std(&priv->hdl, &isx016_ctrl_ops,
++ V4L2_CID_HUE, 0, 23, 1, 12);
++ v4l2_ctrl_new_std(&priv->hdl, &isx016_ctrl_ops,
++ V4L2_CID_GAMMA, -128, 128, 1, 0);
++ v4l2_ctrl_new_std(&priv->hdl, &isx016_ctrl_ops,
++ V4L2_CID_SHARPNESS, 0, 10, 1, 3);
++ v4l2_ctrl_new_std(&priv->hdl, &isx016_ctrl_ops,
++ V4L2_CID_AUTOGAIN, 0, 1, 1, priv->autogain);
++ v4l2_ctrl_new_std(&priv->hdl, &isx016_ctrl_ops,
++ V4L2_CID_GAIN, 0, 0xffff, 1, priv->gain);
++ v4l2_ctrl_new_std(&priv->hdl, &isx016_ctrl_ops,
++ V4L2_CID_EXPOSURE, 0, 0xffff, 1, priv->exposure);
++ v4l2_ctrl_new_std(&priv->hdl, &isx016_ctrl_ops,
++ V4L2_CID_HFLIP, 0, 1, 1, 1);
++ v4l2_ctrl_new_std(&priv->hdl, &isx016_ctrl_ops,
++ V4L2_CID_VFLIP, 0, 1, 1, 0);
++ priv->sd.ctrl_handler = &priv->hdl;
++
++ ret = priv->hdl.error;
++ if (ret)
++ goto cleanup;
++
++ v4l2_ctrl_handler_setup(&priv->hdl);
++
++ priv->pad.flags = MEDIA_PAD_FL_SOURCE;
++ priv->sd.entity.flags |= MEDIA_ENT_F_CAM_SENSOR;
++ ret = media_entity_pads_init(&priv->sd.entity, 1, &priv->pad);
++ if (ret < 0)
++ goto cleanup;
++
++ ret = isx016_parse_dt(client->dev.of_node, priv);
++ if (ret)
++ goto cleanup;
++
++ ret = isx016_initialize(client);
++ if (ret < 0)
++ goto cleanup;
++
++ priv->rect.left = 0;
++ priv->rect.top = 0;
++ priv->rect.width = priv->max_width;
++ priv->rect.height = priv->max_height;
++
++ ret = v4l2_async_register_subdev(&priv->sd);
++ if (ret)
++ goto cleanup;
++
++ if (device_create_file(&client->dev, &dev_attr_otp_id_isx016) != 0) {
++ dev_err(&client->dev, "sysfs otp_id entry creation failed\n");
++ goto cleanup;
++ }
++
++ priv->init_complete = 1;
++
++ return 0;
++
++cleanup:
++ media_entity_cleanup(&priv->sd.entity);
++ v4l2_ctrl_handler_free(&priv->hdl);
++ v4l2_device_unregister_subdev(&priv->sd);
++#ifdef CONFIG_SOC_CAMERA_ISX016
++ v4l_err(client, "failed to probe @ 0x%02x (%s)\n",
++ client->addr, client->adapter->name);
++#endif
++ return ret;
++}
++
++static int isx016_remove(struct i2c_client *client)
++{
++ struct isx016_priv *priv = i2c_get_clientdata(client);
++
++ device_remove_file(&client->dev, &dev_attr_otp_id_isx016);
++ v4l2_async_unregister_subdev(&priv->sd);
++ media_entity_cleanup(&priv->sd.entity);
++ v4l2_ctrl_handler_free(&priv->hdl);
++ v4l2_device_unregister_subdev(&priv->sd);
++
++ return 0;
++}
++
++#ifdef CONFIG_SOC_CAMERA_ISX016
++static const struct i2c_device_id isx016_id[] = {
++ { "isx016", 0 },
++ { }
++};
++MODULE_DEVICE_TABLE(i2c, isx016_id);
++
++static const struct of_device_id isx016_of_ids[] = {
++ { .compatible = "aptina,isx016", },
++ { }
++};
++MODULE_DEVICE_TABLE(of, isx016_of_ids);
++
++static struct i2c_driver isx016_i2c_driver = {
++ .driver = {
++ .name = "isx016",
++ .of_match_table = isx016_of_ids,
++ },
++ .probe = isx016_probe,
++ .remove = isx016_remove,
++ .id_table = isx016_id,
++};
++
++module_i2c_driver(isx016_i2c_driver);
++
++MODULE_DESCRIPTION("SoC Camera driver for ISX016");
++MODULE_AUTHOR("Vladimir Barinov");
++MODULE_LICENSE("GPL");
++#endif
+diff --git a/drivers/media/i2c/soc_camera/isx016.h b/drivers/media/i2c/soc_camera/isx016.h
+new file mode 100644
+index 0000000..8ca35a10
+--- /dev/null
++++ b/drivers/media/i2c/soc_camera/isx016.h
+@@ -0,0 +1,27 @@
++/*
++ * ON Semiconductor isx016 (isp) camera wizard 1280x960@30/UYVY/BT601/8bit
++ *
++ * Copyright (C) 2019 Cogent Embedded, Inc.
++ *
++ * This program is free software; you can redistribute it and/or modify it
++ * under the terms of the GNU General Public License as published by the
++ * Free Software Foundation; either version 2 of the License, or (at your
++ * option) any later version.
++ */
++
++#define ISX016_MAX_WIDTH 1280
++#define ISX016_MAX_HEIGHT 960
++
++#define ISX016_DELAY 0xffff
++
++struct isx016_reg {
++ u16 reg;
++ u16 val;
++};
++
++static const struct isx016_reg isx016_regs_wizard[] = {
++#if 0
++/* enable FSIN */
++#endif
++{ISX016_DELAY, 100},
++};
+diff --git a/drivers/media/i2c/soc_camera/ov106xx.c b/drivers/media/i2c/soc_camera/ov106xx.c
+index 79a69a0..d06c1f0 100644
+--- a/drivers/media/i2c/soc_camera/ov106xx.c
++++ b/drivers/media/i2c/soc_camera/ov106xx.c
+@@ -25,6 +25,7 @@
+ #include "ov2775.c"
+ #include "imx390.c"
+ #include "ox03a.c"
++#include "isx016.c"
+ #include "isx019.c"
+
+ static enum {
+@@ -44,6 +45,7 @@ static enum {
+ ID_OV2775,
+ ID_IMX390,
+ ID_OX03A,
++ ID_ISX016,
+ ID_ISX019,
+ } chip_id;
+
+@@ -149,6 +151,12 @@ static int ov106xx_probe(struct i2c_client *client,
+ goto out;
+ }
+
++ ret = isx016_probe(client, did);
++ if (!ret) {
++ chip_id = ID_ISX016;
++ goto out;
++ }
++
+ ret = isx019_probe(client, did);
+ if (!ret) {
+ chip_id = ID_ISX019;
+@@ -212,6 +220,9 @@ static int ov106xx_remove(struct i2c_client *client)
+ case ID_OX03A:
+ ox03a_remove(client);
+ break;
++ case ID_ISX016:
++ isx016_remove(client);
++ break;
+ case ID_ISX019:
+ isx019_remove(client);
+ break;
+--
+2.7.4
+
diff --git a/bsp/meta-rcar/meta-rcar-gen3-adas/recipes-kernel/linux/linux-renesas/0151-lvds-ti9x4-add-DVP-LSB-MSB-selection.patch b/bsp/meta-rcar/meta-rcar-gen3-adas/recipes-kernel/linux/linux-renesas/0151-lvds-ti9x4-add-DVP-LSB-MSB-selection.patch
new file mode 100644
index 00000000..384997d0
--- /dev/null
+++ b/bsp/meta-rcar/meta-rcar-gen3-adas/recipes-kernel/linux/linux-renesas/0151-lvds-ti9x4-add-DVP-LSB-MSB-selection.patch
@@ -0,0 +1,67 @@
+From ad5be16342cea9a6bb17f8f9c8d2635a0d6b027f Mon Sep 17 00:00:00 2001
+From: Vladimir Barinov <vladimir.barinov@cogentembedded.com>
+Date: Thu, 7 Feb 2019 17:33:53 +0300
+Subject: [PATCH 100/122] lvds: ti9x4: add DVP LSB/MSB selection
+
+This add DVP 8bits LSB/MSB selection from 12bit bus
+
+Signed-off-by: Vladimir Barinov <vladimir.barinov@cogentembedded.com>
+---
+ drivers/media/i2c/soc_camera/ti9x4.c | 13 ++++++++++++-
+ 1 file changed, 12 insertions(+), 1 deletion(-)
+
+diff --git a/drivers/media/i2c/soc_camera/ti9x4.c b/drivers/media/i2c/soc_camera/ti9x4.c
+index 373652a..fdb50e5 100644
+--- a/drivers/media/i2c/soc_camera/ti9x4.c
++++ b/drivers/media/i2c/soc_camera/ti9x4.c
+@@ -34,6 +34,7 @@ struct ti9x4_priv {
+ const char *forwarding_mode;
+ int is_coax;
+ int dvp_bus;
++ int dvp_lsb;
+ int hsync;
+ int vsync;
+ int poc_delay;
+@@ -62,6 +63,10 @@ static int dvp_bus = 8;
+ module_param(dvp_bus, int, 0644);
+ MODULE_PARM_DESC(dvp_bus, " DVP/CSI over FPDLink (default: DVP 8-bit)");
+
++static int dvp_lsb = 0;
++module_param(dvp_lsb, int, 0644);
++MODULE_PARM_DESC(dvp_lsb, " DVP 8-bit LSB/MSB selection (default: DVP 8-bit MSB)");
++
+ static int hsync;
+ module_param(hsync, int, 0644);
+ MODULE_PARM_DESC(hsync, " HSYNC invertion (default: 0 - not inverted)");
+@@ -248,7 +253,7 @@ static void ti9x4_fpdlink3_setup(struct i2c_client *client, int idx)
+
+ switch (priv->dvp_bus) {
+ case 8:
+- port_config2 |= 0x80; /* RAW10 as 8-bit prosessing using upper bits */
++ port_config2 |= (priv->dvp_lsb ? 0xC0 : 0x80); /* RAW10 as 8-bit prosessing using LSB/MSB bits */
+ /* fall through */
+ case 10:
+ port_config |= 0x03; /* DVP over FPDLink (TI913 compatible) RAW10/RAW8 */
+@@ -472,6 +477,10 @@ static int ti9x4_parse_dt(struct i2c_client *client)
+ priv->is_coax = 1;
+ if (of_property_read_u32(np, "ti,dvp_bus", &priv->dvp_bus))
+ priv->dvp_bus = 8;
++ if (of_property_read_bool(np, "ti,dvp_lsb"))
++ priv->dvp_lsb = 1;
++ else
++ priv->dvp_lsb = 0;
+ if (of_property_read_u32(np, "ti,hsync", &priv->hsync))
+ priv->hsync = 0;
+ if (of_property_read_u32(np, "ti,vsync", &priv->vsync))
+@@ -512,6 +521,8 @@ static int ti9x4_parse_dt(struct i2c_client *client)
+ priv->is_coax = 0;
+ if (dvp_bus != 8)
+ priv->dvp_bus = dvp_bus;
++ if (dvp_lsb)
++ priv->dvp_lsb = dvp_lsb;
+ if (hsync)
+ priv->hsync = hsync;
+ if (!vsync)
+--
+2.7.4
+
diff --git a/bsp/meta-rcar/meta-rcar-gen3-adas/recipes-kernel/linux/linux-renesas/0152-lvds-AR323-fix-reset-gpio-nadling.patch b/bsp/meta-rcar/meta-rcar-gen3-adas/recipes-kernel/linux/linux-renesas/0152-lvds-AR323-fix-reset-gpio-nadling.patch
new file mode 100644
index 00000000..9aebe463
--- /dev/null
+++ b/bsp/meta-rcar/meta-rcar-gen3-adas/recipes-kernel/linux/linux-renesas/0152-lvds-AR323-fix-reset-gpio-nadling.patch
@@ -0,0 +1,145 @@
+From 26540d896b8fed3869f426de37c01fa2a913e09d Mon Sep 17 00:00:00 2001
+From: Vladimir Barinov <vladimir.barinov@cogentembedded.com>
+Date: Tue, 12 Feb 2019 17:45:59 +0300
+Subject: [PATCH 101/122] lvds: AR323: fix reset gpio nadling
+
+This fixes gpio reset handling on AR0323 imager
+GPIO0 - NRESET
+GPIO1 - FSIN
+kernel parameter requred: ti9x4.gpio0=1
+
+Signed-off-by: Vladimir Barinov <vladimir.barinov@cogentembedded.com>
+---
+ drivers/media/i2c/soc_camera/ar0323.c | 45 ++++++++++++++++++++--------------
+ drivers/media/i2c/soc_camera/ov106xx.c | 12 ++++-----
+ 2 files changed, 33 insertions(+), 24 deletions(-)
+
+diff --git a/drivers/media/i2c/soc_camera/ar0323.c b/drivers/media/i2c/soc_camera/ar0323.c
+index 467367b..d29f4ad 100644
+--- a/drivers/media/i2c/soc_camera/ar0323.c
++++ b/drivers/media/i2c/soc_camera/ar0323.c
+@@ -22,9 +22,10 @@
+
+ #include "ar0323.h"
+
+-#define AR0323_I2C_ADDR 0x10
++static const int ar0323_i2c_addr[] = {0x10, 0x20};
+
+ #define AR0323_PID 0x3000
++#define AR0323_REV 0x300E
+ #define AR0323_VERSION_REG 0x0D56
+
+ #define AR0323_MEDIA_BUS_FMT MEDIA_BUS_FMT_SGRBG12_1X12
+@@ -356,19 +357,32 @@ static int ar0323_initialize(struct i2c_client *client)
+ {
+ struct ar0323_priv *priv = to_ar0323(client);
+ u16 val = 0;
+- u16 pid = 0;
++ u16 pid = 0, rev = 0;
+ int ret = 0;
+-// int tmp_addr;
++ int tmp_addr;
++ int i;
++
++ for (i = 0; i < ARRAY_SIZE(ar0323_i2c_addr); i++) {
++ tmp_addr = client->addr;
++ if (priv->ti9x4_addr) {
++ client->addr = priv->ti9x4_addr;/* Deserializer I2C address */
++ reg8_write(client, 0x5d, ar0323_i2c_addr[i] << 1); /* Sensor native I2C address */
++ usleep_range(2000, 2500); /* wait 2ms */
++ }
++ client->addr = tmp_addr;
++
++ /* check model ID */
++ reg16_read16(client, AR0323_PID, &pid);
+
+- /* check and show model ID */
+- reg16_read16(client, AR0323_PID, &pid);
++ if (pid == AR0323_VERSION_REG)
++ break;
++ }
+
+ if (pid != AR0323_VERSION_REG) {
+- dev_dbg(&client->dev, "Product ID error %x\n\n\n\n", pid);
++ dev_dbg(&client->dev, "Product ID error %x\n", pid);
+ ret = -ENODEV;
+ goto err;
+ }
+-
+ #if 0
+ /* setup XCLK */
+ tmp_addr = client->addr;
+@@ -381,7 +395,10 @@ static int ar0323_initialize(struct i2c_client *client)
+ }
+ client->addr = tmp_addr;
+ #endif
+-
++ /* check revision */
++ reg16_read16(client, AR0323_REV, &rev);
++ /* Read OTP IDs */
++ ar0323_otp_id_read(client);
+ /* Program wizard registers */
+ ar0323_set_regs(client, ar0323_regs_wizard, ARRAY_SIZE(ar0323_regs_wizard));
+
+@@ -390,11 +407,8 @@ static int ar0323_initialize(struct i2c_client *client)
+ val |= (1 << 2); // Set streamOn bit
+ reg16_write16(client, 0x301a, val); // Start Streaming
+
+- /* Read OTP IDs */
+- ar0323_otp_id_read(client);
+-
+- dev_info(&client->dev, "ar0323 PID %x, res %dx%d, OTP_ID %02x:%02x:%02x:%02x:%02x:%02x\n",
+- pid, AR0323_MAX_WIDTH, AR0323_MAX_HEIGHT, priv->id[0], priv->id[1], priv->id[2], priv->id[3], priv->id[4], priv->id[5]);
++ dev_info(&client->dev, "ar0323 PID %x (rev %x), res %dx%d, OTP_ID %02x:%02x:%02x:%02x:%02x:%02x\n",
++ pid, rev, AR0323_MAX_WIDTH, AR0323_MAX_HEIGHT, priv->id[0], priv->id[1], priv->id[2], priv->id[3], priv->id[4], priv->id[5]);
+ err:
+ return ret;
+ }
+@@ -437,14 +451,9 @@ static int ar0323_parse_dt(struct device_node *np, struct ar0323_priv *priv)
+ reg8_write(client, 0x4c, (priv->port << 4) | (1 << priv->port)); /* Select RX port number */
+ usleep_range(2000, 2500); /* wait 2ms */
+ reg8_write(client, 0x65, tmp_addr << 1); /* Sensor translated I2C address */
+- reg8_write(client, 0x5d, AR0323_I2C_ADDR << 1); /* Sensor native I2C address */
+-
+-// reg8_write(client, 0x6e, 0xa9); /* GPIO0 - reset, GPIO1 - fsin ??????? */
+ }
+ client->addr = tmp_addr;
+
+- mdelay(10);
+-
+ return 0;
+ }
+
+diff --git a/drivers/media/i2c/soc_camera/ov106xx.c b/drivers/media/i2c/soc_camera/ov106xx.c
+index d06c1f0..8962ab9 100644
+--- a/drivers/media/i2c/soc_camera/ov106xx.c
++++ b/drivers/media/i2c/soc_camera/ov106xx.c
+@@ -67,6 +67,12 @@ static int ov106xx_probe(struct i2c_client *client,
+ goto out;
+ }
+
++ ret = ar0323_probe(client, did);
++ if (!ret) {
++ chip_id = ID_AR0323;
++ goto out;
++ }
++
+ ret = ov10640_probe(client, did);
+ if (!ret) {
+ chip_id = ID_OV10640;
+@@ -115,12 +121,6 @@ static int ov106xx_probe(struct i2c_client *client,
+ goto out;
+ }
+
+- ret = ar0323_probe(client, did);
+- if (!ret) {
+- chip_id = ID_AR0323;
+- goto out;
+- }
+-
+ ret = ap0101_probe(client, did);
+ if (!ret) {
+ chip_id = ID_AP0101_AR014X;
+--
+2.7.4
+
diff --git a/bsp/meta-rcar/meta-rcar-gen3-adas/recipes-kernel/linux/linux-renesas/0153-lvds-OV495-fix-reset-gpio-handling.patch b/bsp/meta-rcar/meta-rcar-gen3-adas/recipes-kernel/linux/linux-renesas/0153-lvds-OV495-fix-reset-gpio-handling.patch
new file mode 100644
index 00000000..3535dd86
--- /dev/null
+++ b/bsp/meta-rcar/meta-rcar-gen3-adas/recipes-kernel/linux/linux-renesas/0153-lvds-OV495-fix-reset-gpio-handling.patch
@@ -0,0 +1,65 @@
+From 8241a96db8e7365a23b5ba76a33af47fcc6b7ee8 Mon Sep 17 00:00:00 2001
+From: Vladimir Barinov <vladimir.barinov@cogentembedded.com>
+Date: Tue, 12 Feb 2019 22:29:24 +0300
+Subject: [PATCH 102/122] lvds: OV495: fix reset gpio handling
+
+This fixes gpio reset handling on OV495 imager
+GPIO0 - NRESET
+GPIO1 - NC (no FSIN!)
+kernel parameter requred: ti9x4.gpio0=1
+
+Signed-off-by: Vladimir Barinov <vladimir.barinov@cogentembedded.com>
+---
+ drivers/media/i2c/soc_camera/ov106xx.c | 12 ++++++------
+ drivers/media/i2c/soc_camera/ov495_ov2775.c | 5 +----
+ 2 files changed, 7 insertions(+), 10 deletions(-)
+
+diff --git a/drivers/media/i2c/soc_camera/ov106xx.c b/drivers/media/i2c/soc_camera/ov106xx.c
+index 8962ab9..d641907 100644
+--- a/drivers/media/i2c/soc_camera/ov106xx.c
++++ b/drivers/media/i2c/soc_camera/ov106xx.c
+@@ -73,6 +73,12 @@ static int ov106xx_probe(struct i2c_client *client,
+ goto out;
+ }
+
++ ret = ov495_probe(client, did);
++ if (!ret) {
++ chip_id = ID_OV495_OV2775;
++ goto out;
++ }
++
+ ret = ov10640_probe(client, did);
+ if (!ret) {
+ chip_id = ID_OV10640;
+@@ -91,12 +97,6 @@ static int ov106xx_probe(struct i2c_client *client,
+ goto out;
+ }
+
+- ret = ov495_probe(client, did);
+- if (!ret) {
+- chip_id = ID_OV495_OV2775;
+- goto out;
+- }
+-
+ ret = ar0132_probe(client, did);
+ if (!ret) {
+ chip_id = ID_AR0132;
+diff --git a/drivers/media/i2c/soc_camera/ov495_ov2775.c b/drivers/media/i2c/soc_camera/ov495_ov2775.c
+index 34b2f46..aee8145 100644
+--- a/drivers/media/i2c/soc_camera/ov495_ov2775.c
++++ b/drivers/media/i2c/soc_camera/ov495_ov2775.c
+@@ -503,10 +503,7 @@ static int ov495_parse_dt(struct device_node *np, struct ov495_priv *priv)
+ usleep_range(2000, 2500); /* wait 2ms */
+ reg8_write(client, 0x65, tmp_addr << 1); /* Sensor translated I2C address */
+ reg8_write(client, 0x5d, OV495_I2C_ADDR << 1); /* Sensor native I2C address */
+-
+- reg8_write(client, 0x6e, 0x9a); /* GPIO0 - fsin, GPIO1 - resetb */
+- /* TODO: why too long? move logic to workqueue? */
+- mdelay(350); /* time needed to boot all sensor IPs */
++ usleep_range(2000, 2500); /* wait 2ms */
+ }
+ client->addr = tmp_addr;
+
+--
+2.7.4
+
diff --git a/bsp/meta-rcar/meta-rcar-gen3-adas/recipes-kernel/linux/linux-renesas/0154-lvds-AR0323-replace-with-REV2-setup-table.patch b/bsp/meta-rcar/meta-rcar-gen3-adas/recipes-kernel/linux/linux-renesas/0154-lvds-AR0323-replace-with-REV2-setup-table.patch
new file mode 100644
index 00000000..01f93c7c
--- /dev/null
+++ b/bsp/meta-rcar/meta-rcar-gen3-adas/recipes-kernel/linux/linux-renesas/0154-lvds-AR0323-replace-with-REV2-setup-table.patch
@@ -0,0 +1,2888 @@
+From d28f2cdef61df4e852a25667ba2a82c0cc6fb52b Mon Sep 17 00:00:00 2001
+From: Vladimir Barinov <vladimir.barinov@cogentembedded.com>
+Date: Thu, 14 Feb 2019 13:07:27 +0300
+Subject: [PATCH 103/122] lvds: AR0323: replace with REV2 setup table
+
+Superseed wizard table with REV2 setup
+
+Signed-off-by: Vladimir Barinov <vladimir.barinov@cogentembedded.com>
+---
+ drivers/media/i2c/soc_camera/ar0323.h | 2840 ++++++++++++++++++---------------
+ 1 file changed, 1578 insertions(+), 1262 deletions(-)
+
+diff --git a/drivers/media/i2c/soc_camera/ar0323.h b/drivers/media/i2c/soc_camera/ar0323.h
+index 0711dd8..b30d0d5 100644
+--- a/drivers/media/i2c/soc_camera/ar0323.h
++++ b/drivers/media/i2c/soc_camera/ar0323.h
+@@ -13,7 +13,7 @@
+ //#define AR0323_DISPLAY_PATTERN_COLOR_BAR
+
+ #define AR0323_MAX_WIDTH 2560
+-#define AR0323_MAX_HEIGHT 1080
++#define AR0323_MAX_HEIGHT 992
+
+ #define AR0323_DELAY 0xffff
+
+@@ -52,1084 +52,17 @@ static const struct ar0323_reg ar0323_regs_wizard[] = {
+ #endif
+
+ {0x301A, 0x0059}, // RESET_REGISTER
+-{0x301A, 0x0058}, // RESET_REGISTER
+-{AR0323_DELAY, 200}, // Wait 200ms
+-
+-//continuous MIPI 12bit
+-{0x3342, 0x122C}, // MIPI_F1_PDT_EDT
+-{0x3346, 0x122C}, // MIPI_F2_PDT_EDT
+-{0x334A, 0x122C}, // MIPI_F3_PDT_EDT
+-{0x334E, 0x122C}, // MIPI_F4_PDT_EDT
+-
+-//PLL settings
+-{0x302E, 0x0002}, // PRE_PLL_CLK_DIV
+-{0x3030, 0x0052}, // PLL_MULTIPLIER
+-{0x302C, 0x0001}, // VT_SYS_CLK_DIV
+-{0x302A, 0x0008}, // VT_PIX_CLK_DIV
+-{0x3038, 0x0004}, // OP_SYS_CLK_DIV
+-{0x3036, 0x0006}, // OP_WORD_CLK_DIV
+-
+-//MIPI timing
+-{0x31B0, 0x0059}, // FRAME_PREAMBLE
+-{0x31B2, 0x003B}, // LINE_PREAMBLE
+-{0x31B4, 0x31C5}, // MIPI_TIMING_0
+-{0x31B6, 0x114E}, // MIPI_TIMING_1
+-{0x31B8, 0x5048}, // MIPI_TIMING_2
+-{0x31BA, 0x0186}, // MIPI_TIMING_3
+-{0x31BC, 0x8885}, // MIPI_TIMING_4
+-
+-//HDR
+-{0x3E00, 0x8000}, // LFM2_T1_CTRL
+-{0x3082, 0x0004}, // OPERATION_MODE_CTRL
+-{0x30BA, 0x1103}, // DIGITAL_CTRL
+-
+-//new sequencer
+-{0x2512, 0x8000},
+-{0x2510, 0x0712},
+-{0x2510, 0x1314},
+-{0x2510, 0x1518},
+-{0x2510, 0xffff},
+-{0x2510, 0xffff},
+-{0x2510, 0xffff},
+-{0x2510, 0xffff},
+-{0x2510, 0xffff},
+-{0x2510, 0x1b1d},
+-{0x2510, 0x2224},
+-{0x2510, 0x2628},
+-{0x2510, 0xffff},
+-{0x2510, 0x2a48},
+-{0x2510, 0x5672},
+-{0x2510, 0x7f85},
+-{0x2510, 0x8991},
+-{0x2510, 0xaeb3},
+-{0x2510, 0xbdc4},
+-{0x2510, 0xc5c8},
+-{0x2510, 0xccd0},
+-{0x2510, 0xd4d6},
+-{0x2510, 0xd8dd},
+-{0x2510, 0xdfe2},
+-{0x2510, 0xe5e8},
+-{0x2510, 0xffff},
+-{0x2510, 0xffff},
+-{0x2510, 0xffff},
+-{0x2510, 0xffff},
+-{0x2510, 0xc003},
+-{0x2510, 0xa0e0},
+-{0x2510, 0x3041},
+-{0x2510, 0x3042},
+-{0x2510, 0x2000},
+-{0x2510, 0x3048},
+-{0x2510, 0x3081},
+-{0x2510, 0x3084},
+-{0x2510, 0x3082},
+-{0x2510, 0x2003},
+-{0x2510, 0x3044},
+-{0x2510, 0x2000},
+-{0x2510, 0xa004},
+-{0x2510, 0x20ff},
+-{0x2510, 0x20ff},
+-{0x2510, 0x20ff},
+-{0x2510, 0x20ff},
+-{0x2510, 0x20ff},
+-{0x2510, 0x807c},
+-{0x2510, 0xa0e0},
+-{0x2510, 0x3041},
+-{0x2510, 0x3042},
+-{0x2510, 0x2000},
+-{0x2510, 0xa0c0},
+-{0x2510, 0x9008},
+-{0x2510, 0x8802},
+-{0x2510, 0x20ff},
+-{0x2510, 0x20ff},
+-{0x2510, 0x20ff},
+-{0x2510, 0x20ff},
+-{0x2510, 0x20ff},
+-{0x2510, 0x9018},
+-{0x2510, 0x891a},
+-{0x2510, 0x807c},
+-{0x2510, 0x20ff},
+-{0x2510, 0x895b},
+-{0x2510, 0x20ff},
+-{0x2510, 0x897b},
+-{0x2510, 0x20ff},
+-{0x2510, 0x897f},
+-{0x2510, 0x20ff},
+-{0x2510, 0x7fff},
+-{0x2510, 0x7fff},
+-{0x2510, 0x7fff},
+-{0x2510, 0x20ff},
+-{0x2510, 0x7fff},
+-{0x2510, 0x7fff},
+-{0x2510, 0x7fff},
+-{0x2510, 0x20ff},
+-{0x2510, 0x7fff},
+-{0x2510, 0x7fff},
+-{0x2510, 0x7fff},
+-{0x2510, 0x20ff},
+-{0x2510, 0x7fff},
+-{0x2510, 0x7fff},
+-{0x2510, 0x7fff},
+-{0x2510, 0xa0c4},
+-{0x2510, 0x20ff},
+-{0x2510, 0x8058},
+-{0x2510, 0x9039},
+-{0x2510, 0x20ff},
+-{0x2510, 0x907f},
+-{0x2510, 0x895b},
+-{0x2510, 0x2064},
+-{0x2510, 0x891b},
+-{0x2510, 0x2010},
+-{0x2510, 0x8803},
+-{0x2510, 0x7fff},
+-{0x2510, 0x3088},
+-{0x2510, 0x3090},
+-{0x2510, 0x20ff},
+-{0x2510, 0x906b},
+-{0x2510, 0x2064},
+-{0x2510, 0x3084},
+-{0x2510, 0x2003},
+-{0x2510, 0x3044},
+-{0x2510, 0x2000},
+-{0x2510, 0xa004},
+-{0x2510, 0x7fff},
+-{0x2510, 0x7fff},
+-{0x2510, 0x2400},
+-{0x2510, 0x2401},
+-{0x2510, 0x3244},
+-{0x2510, 0x7fff},
+-{0x2510, 0x7fff},
+-{0x2510, 0x7fff},
+-{0x2510, 0x7fff},
+-{0x2510, 0x7fff},
+-{0x2510, 0x2400},
+-{0x2510, 0x2401},
+-{0x2510, 0x2702},
+-{0x2510, 0x3242},
+-{0x2510, 0x2420},
+-{0x2510, 0x2702},
+-{0x2510, 0x2421},
+-{0x2510, 0x2703},
+-{0x2510, 0x3242},
+-{0x2510, 0x2420},
+-{0x2510, 0x2703},
+-{0x2510, 0x2421},
+-{0x2510, 0x2704},
+-{0x2510, 0x3242},
+-{0x2510, 0x2420},
+-{0x2510, 0x2704},
+-{0x2510, 0x2421},
+-{0x2510, 0x3244},
+-{0x2510, 0x7fff},
+-{0x2510, 0x7fff},
+-{0x2510, 0x2402},
+-{0x2510, 0x2403},
+-{0x2510, 0x3244},
+-{0x2510, 0x7fff},
+-{0x2510, 0x7fff},
+-{0x2510, 0x7fff},
+-{0x2510, 0x7fff},
+-{0x2510, 0x7fff},
+-{0x2510, 0x2741},
+-{0x2510, 0x2429},
+-{0x2510, 0x2740},
+-{0x2510, 0x242a},
+-{0x2510, 0x3244},
+-{0x2510, 0x7fff},
+-{0x2510, 0x7fff},
+-{0x2510, 0x7fff},
+-{0x2510, 0x2404},
+-{0x2510, 0x2779},
+-{0x2510, 0x242c},
+-{0x2510, 0x2781},
+-{0x2510, 0x242d},
+-{0x2510, 0x3244},
+-{0x2510, 0x7fff},
+-{0x2510, 0x7fff},
+-{0x2510, 0x2703},
+-{0x2510, 0x2432},
+-{0x2510, 0x3244},
+-{0x2510, 0x7fff},
+-{0x2510, 0x7fff},
+-{0x2510, 0x7fff},
+-{0x2510, 0x7fff},
+-{0x2510, 0x7fff},
+-{0x2510, 0xb800},
+-{0x2510, 0x8058},
+-{0x2510, 0xa005},
+-{0x2510, 0x30c1},
+-{0x2510, 0x3101},
+-{0x2510, 0x3041},
+-{0x2510, 0x3041},
+-{0x2510, 0x3250},
+-{0x2510, 0x3108},
+-{0x2510, 0x3104},
+-{0x2510, 0x3102},
+-{0x2510, 0x3041},
+-{0x2510, 0xf860},
+-{0x2510, 0xb095},
+-{0x2510, 0x3141},
+-{0x2510, 0x3042},
+-{0x2510, 0xb848},
+-{0x2510, 0xb84c},
+-{0x2510, 0x8843},
+-{0x2510, 0x916f},
+-{0x2510, 0x3110},
+-{0x2510, 0x3042},
+-{0x2510, 0xb84e},
+-{0x2510, 0xf905},
+-{0x2510, 0xf907},
+-{0x2510, 0x3202},
+-{0x2510, 0x885b},
+-{0x2510, 0xa898},
+-{0x2510, 0xa8d8},
+-{0x2510, 0xb397},
+-{0x2510, 0xf8e8},
+-{0x2510, 0x80dc},
+-{0x2510, 0x2206},
+-{0x2510, 0xb137},
+-{0x2510, 0xb808},
+-{0x2510, 0xc800},
+-{0x2510, 0xe809},
+-{0x2510, 0xb177},
+-{0x2510, 0x88df},
+-{0x2510, 0xf8a8},
+-{0x2510, 0xf888},
+-{0x2510, 0x2203},
+-{0x2510, 0xb07b},
+-{0x2510, 0x2000},
+-{0x2510, 0x80cc},
+-{0x2510, 0x808c},
+-{0x2510, 0x220b},
+-{0x2510, 0xb06a},
+-{0x2510, 0x88cf},
+-{0x2510, 0x888f},
+-{0x2510, 0x222f},
+-{0x2510, 0x2771},
+-{0x2510, 0x2512},
+-{0x2510, 0xb04a},
+-{0x2510, 0x2213},
+-{0x2510, 0x2771},
+-{0x2510, 0x2525},
+-{0x2510, 0xb04b},
+-{0x2510, 0x902f},
+-{0x2510, 0xf880},
+-{0x2510, 0x220e},
+-{0x2510, 0x2201},
+-{0x2510, 0x2201},
+-{0x2510, 0x2204},
+-{0x2510, 0xb043},
+-{0x2510, 0x2201},
+-{0x2510, 0xa8c9},
+-{0x2510, 0x31c1},
+-{0x2510, 0x80ac},
+-{0x2510, 0x916f},
+-{0x2510, 0x2112},
+-{0x2510, 0x88af},
+-{0x2510, 0x2440},
+-{0x2510, 0xf110},
+-{0x2510, 0xf804},
+-{0x2510, 0x2000},
+-{0x2510, 0x8088},
+-{0x2510, 0xb838},
+-{0x2510, 0xa8c8},
+-{0x2510, 0xb04b},
+-{0x2510, 0x2442},
+-{0x2510, 0x3210},
+-{0x2510, 0x3002},
+-{0x2510, 0x220c},
+-{0x2510, 0x888b},
+-{0x2510, 0x2204},
+-{0x2510, 0x3202},
+-{0x2510, 0x2204},
+-{0x2510, 0xf880},
+-{0x2510, 0xb830},
+-{0x2510, 0xc801},
+-{0x2510, 0x30c2},
+-{0x2510, 0xe80c},
+-{0x2510, 0x2201},
+-{0x2510, 0xb04a},
+-{0x2510, 0x2229},
+-{0x2510, 0x2771},
+-{0x2510, 0x2513},
+-{0x2510, 0x902f},
+-{0x2510, 0x221f},
+-{0x2510, 0x2201},
+-{0x2510, 0x2204},
+-{0x2510, 0xb042},
+-{0x2510, 0x2201},
+-{0x2510, 0xa9a1},
+-{0x2510, 0x8008},
+-{0x2510, 0xb093},
+-{0x2510, 0x31c1},
+-{0x2510, 0x916b},
+-{0x2510, 0x2009},
+-{0x2510, 0x8803},
+-{0x2510, 0xa044},
+-{0x2510, 0x3044},
+-{0x2510, 0x2000},
+-{0x2510, 0xa004},
+-{0x2510, 0x7fff},
+-{0x2510, 0x7fff},
+-{0x2510, 0x7fff},
+-{0x2510, 0x7fff},
+-{0x2510, 0x7fff},
+-{0x2510, 0xa084},
+-{0x2510, 0x8078},
+-{0x2510, 0x3141},
+-{0x2510, 0x3041},
+-{0x2510, 0x3042},
+-{0x2510, 0x2000},
+-{0x2510, 0x3142},
+-{0x2510, 0x3041},
+-{0x2510, 0x2000},
+-{0x2510, 0x3110},
+-{0x2510, 0x3041},
+-{0x2510, 0x2000},
+-{0x2510, 0x3120},
+-{0x2510, 0x3041},
+-{0x2510, 0x2000},
+-{0x2510, 0x3144},
+-{0x2510, 0x3041},
+-{0x2510, 0x2000},
+-{0x2510, 0x3148},
+-{0x2510, 0x3041},
+-{0x2510, 0x2000},
+-{0x2510, 0x2206},
+-{0x2510, 0x881b},
+-{0x2510, 0x887b},
+-{0x2510, 0x2440},
+-{0x2510, 0xb095},
+-{0x2510, 0xf110},
+-{0x2510, 0xf804},
+-{0x2510, 0xf90d},
+-{0x2510, 0x3084},
+-{0x2510, 0x3090},
+-{0x2510, 0x3088},
+-{0x2510, 0x8058},
+-{0x2510, 0x3001},
+-{0x2510, 0x2442},
+-{0x2510, 0x3260},
+-{0x2510, 0x3248},
+-{0x2510, 0x3220},
+-{0x2510, 0x2002},
+-{0x2510, 0x8863},
+-{0x2510, 0x2004},
+-{0x2510, 0x8803},
+-{0x2510, 0x2204},
+-{0x2510, 0x30c2},
+-{0x2510, 0xa9a0},
+-{0x2510, 0xb094},
+-{0x2510, 0x2201},
+-{0x2510, 0xa0c4},
+-{0x2510, 0x3044},
+-{0x2510, 0x2000},
+-{0x2510, 0xa004},
+-{0x2510, 0x7fff},
+-{0x2510, 0x7fff},
+-{0x2510, 0x7fff},
+-{0x2510, 0x7fff},
+-{0x2510, 0x7fff},
+-{0x2510, 0xb980},
+-{0x2510, 0x8108},
+-{0x2510, 0xa105},
+-{0x2510, 0x30c1},
+-{0x2510, 0x2000},
+-{0x2510, 0x3101},
+-{0x2510, 0x3041},
+-{0x2510, 0x3250},
+-{0x2510, 0x3108},
+-{0x2510, 0x3104},
+-{0x2510, 0x3102},
+-{0x2510, 0x3041},
+-{0x2510, 0xf860},
+-{0x2510, 0xb095},
+-{0x2510, 0x3141},
+-{0x2510, 0x3042},
+-{0x2510, 0xb9f8},
+-{0x2510, 0xb9fc},
+-{0x2510, 0x8803},
+-{0x2510, 0x916f},
+-{0x2510, 0x3110},
+-{0x2510, 0x3042},
+-{0x2510, 0xb9fe},
+-{0x2510, 0xf905},
+-{0x2510, 0xf907},
+-{0x2510, 0x3202},
+-{0x2510, 0x880b},
+-{0x2510, 0xa888},
+-{0x2510, 0xa8c8},
+-{0x2510, 0xb397},
+-{0x2510, 0xf8e8},
+-{0x2510, 0x818c},
+-{0x2510, 0x2206},
+-{0x2510, 0xb137},
+-{0x2510, 0xb9b8},
+-{0x2510, 0xc801},
+-{0x2510, 0xe809},
+-{0x2510, 0xb177},
+-{0x2510, 0x888f},
+-{0x2510, 0xf8a8},
+-{0x2510, 0xf888},
+-{0x2510, 0x2203},
+-{0x2510, 0xb07b},
+-{0x2510, 0x2000},
+-{0x2510, 0x2206},
+-{0x2510, 0xb06a},
+-{0x2510, 0x2210},
+-{0x2510, 0x818c},
+-{0x2510, 0x2204},
+-{0x2510, 0x888f},
+-{0x2510, 0x888f},
+-{0x2510, 0x2215},
+-{0x2510, 0xb04a},
+-{0x2510, 0x2212},
+-{0x2510, 0x2111},
+-{0x2510, 0xb04b},
+-{0x2510, 0x902f},
+-{0x2510, 0xf880},
+-{0x2510, 0x220e},
+-{0x2510, 0x2201},
+-{0x2510, 0x2204},
+-{0x2510, 0xb043},
+-{0x2510, 0x2201},
+-{0x2510, 0xa8d9},
+-{0x2510, 0x31c1},
+-{0x2510, 0x80cc},
+-{0x2510, 0x916f},
+-{0x2510, 0x2110},
+-{0x2510, 0x88cf},
+-{0x2510, 0x2440},
+-{0x2510, 0xf110},
+-{0x2510, 0xf804},
+-{0x2510, 0x2000},
+-{0x2510, 0xb988},
+-{0x2510, 0xa8d8},
+-{0x2510, 0xb04b},
+-{0x2510, 0x3002},
+-{0x2510, 0x2442},
+-{0x2510, 0x3210},
+-{0x2510, 0x220a},
+-{0x2510, 0x2204},
+-{0x2510, 0x3202},
+-{0x2510, 0x2204},
+-{0x2510, 0xb980},
+-{0x2510, 0xc800},
+-{0x2510, 0x30c2},
+-{0x2510, 0xe80c},
+-{0x2510, 0x2201},
+-{0x2510, 0xb04a},
+-{0x2510, 0x221f},
+-{0x2510, 0x8088},
+-{0x2510, 0x220a},
+-{0x2510, 0x888b},
+-{0x2510, 0x902f},
+-{0x2510, 0x221e},
+-{0x2510, 0x2201},
+-{0x2510, 0x2204},
+-{0x2510, 0xb042},
+-{0x2510, 0x2201},
+-{0x2510, 0xa9a1},
+-{0x2510, 0x8018},
+-{0x2510, 0xb093},
+-{0x2510, 0x31c1},
+-{0x2510, 0x916b},
+-{0x2510, 0x2009},
+-{0x2510, 0x8803},
+-{0x2510, 0x2000},
+-{0x2510, 0xa004},
+-{0x2510, 0xb800},
+-{0x2510, 0x7fff},
+-{0x2510, 0x7fff},
+-{0x2510, 0x7fff},
+-{0x2510, 0x8078},
+-{0x2510, 0xa184},
+-{0x2510, 0xb981},
+-{0x2510, 0x3141},
+-{0x2510, 0x3041},
+-{0x2510, 0x3042},
+-{0x2510, 0x2000},
+-{0x2510, 0x3142},
+-{0x2510, 0x3041},
+-{0x2510, 0x2000},
+-{0x2510, 0x3110},
+-{0x2510, 0x3041},
+-{0x2510, 0x2000},
+-{0x2510, 0x3120},
+-{0x2510, 0x3041},
+-{0x2510, 0x2000},
+-{0x2510, 0x30a0},
+-{0x2510, 0x2206},
+-{0x2510, 0x881b},
+-{0x2510, 0x887b},
+-{0x2510, 0x2282},
+-{0x2510, 0xb095},
+-{0x2510, 0xf110},
+-{0x2510, 0xf804},
+-{0x2510, 0xf90d},
+-{0x2510, 0x3090},
+-{0x2510, 0x3088},
+-{0x2510, 0x8058},
+-{0x2510, 0x2202},
+-{0x2510, 0x3001},
+-{0x2510, 0x3260},
+-{0x2510, 0x3248},
+-{0x2510, 0x2002},
+-{0x2510, 0x885b},
+-{0x2510, 0x2004},
+-{0x2510, 0x2204},
+-{0x2510, 0x8018},
+-{0x2510, 0x2209},
+-{0x2510, 0x881b},
+-{0x2510, 0xa9a0},
+-{0x2510, 0xb094},
+-{0x2510, 0x2209},
+-{0x2510, 0x8000},
+-{0x2510, 0x2209},
+-{0x2510, 0x8803},
+-{0x2510, 0xa1c4},
+-{0x2510, 0x3044},
+-{0x2510, 0xb800},
+-{0x2510, 0xa004},
+-{0x2510, 0x7fff},
+-{0x2510, 0x7fff},
+-{0x2510, 0x7fff},
+-{0x2510, 0x9818},
+-{0x2510, 0xb800},
+-{0x2510, 0x3101},
+-{0x2510, 0x3041},
+-{0x2510, 0x2200},
+-{0x2510, 0x3102},
+-{0x2510, 0x3041},
+-{0x2510, 0x2200},
+-{0x2510, 0x8018},
+-{0x2510, 0x2002},
+-{0x2510, 0x8038},
+-{0x2510, 0x2205},
+-{0x2510, 0x881b},
+-{0x2510, 0x883b},
+-{0x2510, 0x213e},
+-{0x2510, 0x8018},
+-{0x2510, 0x2202},
+-{0x2510, 0x8000},
+-{0x2510, 0x2202},
+-{0x2510, 0x8803},
+-{0x2510, 0x9800},
+-{0x2510, 0xa004},
+-{0x2510, 0x7fff},
+-{0x2510, 0x7fff},
+-{0x2510, 0x2440},
+-{0x2510, 0xb095},
+-{0x2510, 0xf110},
+-{0x2510, 0xf804},
+-{0x2510, 0xf90d},
+-{0x2510, 0x2442},
+-{0x2510, 0x3260},
+-{0x2510, 0x3248},
+-{0x2510, 0x3220},
+-{0x2510, 0x2007},
+-{0x2510, 0x2204},
+-{0x2510, 0x30c2},
+-{0x2510, 0xa9a0},
+-{0x2510, 0xb094},
+-{0x2510, 0x7fff},
+-{0x2510, 0x7fff},
+-{0x2510, 0xb981},
+-{0x2510, 0x3101},
+-{0x2510, 0x3041},
+-{0x2510, 0x3102},
+-{0x2510, 0x3041},
+-{0x2510, 0x8028},
+-{0x2510, 0x2212},
+-{0x2510, 0x880b},
+-{0x2510, 0x882b},
+-{0x2510, 0x2440},
+-{0x2510, 0xb095},
+-{0x2510, 0xf110},
+-{0x2510, 0xf804},
+-{0x2510, 0xf90d},
+-{0x2510, 0x8008},
+-{0x2510, 0x2202},
+-{0x2510, 0x3001},
+-{0x2510, 0x3260},
+-{0x2510, 0x3248},
+-{0x2510, 0x2442},
+-{0x2510, 0x8823},
+-{0x2510, 0x3220},
+-{0x2510, 0x2007},
+-{0x2510, 0x8803},
+-{0x2510, 0x2204},
+-{0x2510, 0x30c2},
+-{0x2510, 0xa8a0},
+-{0x2510, 0xb094},
+-{0x2510, 0x2201},
+-{0x2510, 0x7fff},
+-{0x2510, 0x7fff},
+-{0x2510, 0x7fff},
+-{0x2510, 0xb800},
+-{0x2510, 0x8058},
+-{0x2510, 0xa005},
+-{0x2510, 0x30c1},
+-{0x2510, 0x3101},
+-{0x2510, 0x3041},
+-{0x2510, 0x3041},
+-{0x2510, 0x3250},
+-{0x2510, 0x3108},
+-{0x2510, 0x3104},
+-{0x2510, 0x3102},
+-{0x2510, 0x3041},
+-{0x2510, 0xf860},
+-{0x2510, 0xb095},
+-{0x2510, 0x3141},
+-{0x2510, 0x3042},
+-{0x2510, 0xb848},
+-{0x2510, 0xb84c},
+-{0x2510, 0x8843},
+-{0x2510, 0x916f},
+-{0x2510, 0x3110},
+-{0x2510, 0x3042},
+-{0x2510, 0xb84e},
+-{0x2510, 0xf905},
+-{0x2510, 0xf907},
+-{0x2510, 0x3202},
+-{0x2510, 0x885b},
+-{0x2510, 0xa898},
+-{0x2510, 0xa8d8},
+-{0x2510, 0xb397},
+-{0x2510, 0xf8e8},
+-{0x2510, 0x80dc},
+-{0x2510, 0x2206},
+-{0x2510, 0xb137},
+-{0x2510, 0xb808},
+-{0x2510, 0xc800},
+-{0x2510, 0xe809},
+-{0x2510, 0xb177},
+-{0x2510, 0x88df},
+-{0x2510, 0xf8a8},
+-{0x2510, 0xf888},
+-{0x2510, 0x2203},
+-{0x2510, 0xb07b},
+-{0x2510, 0x2000},
+-{0x2510, 0x80cc},
+-{0x2510, 0x808c},
+-{0x2510, 0x220b},
+-{0x2510, 0xb06a},
+-{0x2510, 0x88cf},
+-{0x2510, 0x888f},
+-{0x2510, 0x222f},
+-{0x2510, 0x2771},
+-{0x2510, 0x251e},
+-{0x2510, 0xb04a},
+-{0x2510, 0x2213},
+-{0x2510, 0x2771},
+-{0x2510, 0x2525},
+-{0x2510, 0xb04b},
+-{0x2510, 0x902f},
+-{0x2510, 0xf880},
+-{0x2510, 0x221e},
+-{0x2510, 0x2201},
+-{0x2510, 0x2204},
+-{0x2510, 0xb043},
+-{0x2510, 0x2201},
+-{0x2510, 0xa8c9},
+-{0x2510, 0x31c1},
+-{0x2510, 0x80ac},
+-{0x2510, 0x916f},
+-{0x2510, 0x2112},
+-{0x2510, 0x88af},
+-{0x2510, 0x2440},
+-{0x2510, 0xf110},
+-{0x2510, 0xf804},
+-{0x2510, 0x2000},
+-{0x2510, 0x8088},
+-{0x2510, 0xb838},
+-{0x2510, 0xa8c8},
+-{0x2510, 0xb04b},
+-{0x2510, 0x2442},
+-{0x2510, 0x3210},
+-{0x2510, 0x3002},
+-{0x2510, 0x220c},
+-{0x2510, 0x888b},
+-{0x2510, 0x2204},
+-{0x2510, 0x3202},
+-{0x2510, 0xf880},
+-{0x2510, 0xb830},
+-{0x2510, 0xc801},
+-{0x2510, 0x30c2},
+-{0x2510, 0xe80c},
+-{0x2510, 0x2201},
+-{0x2510, 0xb04a},
+-{0x2510, 0x2229},
+-{0x2510, 0x2771},
+-{0x2510, 0x2513},
+-{0x2510, 0x902f},
+-{0x2510, 0x221f},
+-{0x2510, 0x2201},
+-{0x2510, 0x2204},
+-{0x2510, 0xb042},
+-{0x2510, 0x2201},
+-{0x2510, 0xa8e1},
+-{0x2510, 0x8008},
+-{0x2510, 0xb093},
+-{0x2510, 0x31c1},
+-{0x2510, 0x916b},
+-{0x2510, 0x2009},
+-{0x2510, 0x8803},
+-{0x2510, 0x2000},
+-{0x2510, 0xa004},
+-{0x2510, 0x7fff},
+-{0x2510, 0x7fff},
+-{0x2510, 0x7fff},
+-{0x2510, 0x7fff},
+-{0x2510, 0x7fff},
+-{0x2510, 0x2440},
+-{0x2510, 0xb095},
+-{0x2510, 0xf110},
+-{0x2510, 0xf804},
+-{0x2510, 0xf90d},
+-{0x2510, 0x2442},
+-{0x2510, 0x3220},
+-{0x2510, 0x2002},
+-{0x2510, 0x2204},
+-{0x2510, 0x30c2},
+-{0x2510, 0xa9a0},
+-{0x2510, 0x2004},
+-{0x2510, 0xb094},
+-{0x2510, 0x2201},
+-{0x2510, 0x3244},
+-{0x2510, 0x7fff},
+-{0x2510, 0x7fff},
+-{0x2510, 0x7fff},
+-{0x2510, 0x7fff},
+-{0x2510, 0x7fff},
+-{0x2510, 0x2749},
+-{0x2510, 0x2422},
+-{0x2510, 0x2749},
+-{0x2510, 0x2423},
+-{0x2510, 0x2709},
+-{0x2510, 0x2420},
+-{0x2510, 0x2729},
+-{0x2510, 0x2423},
+-{0x2510, 0x3242},
+-{0x2510, 0x2722},
+-{0x2510, 0x2422},
+-{0x2510, 0x2769},
+-{0x2510, 0x2421},
+-{0x2510, 0x2702},
+-{0x2510, 0x2421},
+-{0x2510, 0x3242},
+-{0x2510, 0x276a},
+-{0x2510, 0x2420},
+-{0x2510, 0x276a},
+-{0x2510, 0x2421},
+-{0x2510, 0x2703},
+-{0x2510, 0x2420},
+-{0x2510, 0x2703},
+-{0x2510, 0x2421},
+-{0x2510, 0x3242},
+-{0x2510, 0x276b},
+-{0x2510, 0x2420},
+-{0x2510, 0x276b},
+-{0x2510, 0x2421},
+-{0x2510, 0x2704},
+-{0x2510, 0x2420},
+-{0x2510, 0x2704},
+-{0x2510, 0x2421},
+-{0x2510, 0x3242},
+-{0x2510, 0x276c},
+-{0x2510, 0x2420},
+-{0x2510, 0x276c},
+-{0x2510, 0x2421},
+-{0x2510, 0x7fff},
+-{0x2510, 0x7fff},
+-{0x2510, 0x2759},
+-{0x2510, 0x2422},
+-{0x2510, 0x2758},
+-{0x2510, 0x2420},
+-{0x2510, 0x2403},
+-{0x2510, 0x2712},
+-{0x2510, 0x3242},
+-{0x2510, 0x2422},
+-{0x2510, 0x271a},
+-{0x2510, 0x3242},
+-{0x2510, 0x2420},
+-{0x2510, 0x2702},
+-{0x2510, 0x2423},
+-{0x2510, 0x2703},
+-{0x2510, 0x3242},
+-{0x2510, 0x2420},
+-{0x2510, 0x2703},
+-{0x2510, 0x2423},
+-{0x2510, 0x2704},
+-{0x2510, 0x3242},
+-{0x2510, 0x2420},
+-{0x2510, 0x2704},
+-{0x2510, 0x2423},
+-{0x2510, 0x7fff},
+-{0x2510, 0x7fff},
+-{0x2510, 0x7fff},
+-{0x2510, 0x7fff},
+-{0x2510, 0x7fff},
+-{0x2510, 0x7fff},
+-{0x2510, 0x7fff},
+-{0x2510, 0x7fff},
+-{0x2510, 0x7fff},
+-{0x2510, 0xc023},
+-{0x2510, 0x2402},
+-{0x2510, 0x2405},
+-{0x2510, 0x2789},
+-{0x2510, 0x242e},
+-{0x2510, 0x2788},
+-{0x2510, 0x242f},
+-{0x2510, 0x3244},
+-{0x2510, 0x7fff},
+-{0x2510, 0x7fff},
+-{0x2510, 0x7fff},
+-{0x2510, 0x7fff},
+-{0x2510, 0xc027},
+-{0x2510, 0x2407},
+-{0x2510, 0x2406},
+-{0x2510, 0xc063},
+-{0x2510, 0x2402},
+-{0x2510, 0x2751},
+-{0x2510, 0x2423},
+-{0x2510, 0x2750},
+-{0x2510, 0x2421},
+-{0x2510, 0xc003},
+-{0x2510, 0x3244},
+-{0x2510, 0x7fff},
+-{0x2510, 0x7fff},
+-{0x2510, 0x7fff},
+-{0x2510, 0x7fff},
+-{0x2510, 0x7fff},
+-{0x2510, 0xc021},
+-{0x2510, 0x2400},
+-{0x2510, 0x2405},
+-{0x2510, 0xc062},
+-{0x2510, 0x2400},
+-{0x2510, 0xc063},
+-{0x2510, 0x2751},
+-{0x2510, 0x2423},
+-{0x2510, 0x2750},
+-{0x2510, 0x2421},
+-{0x2510, 0xc003},
+-{0x2510, 0x3244},
+-{0x2510, 0x7fff},
+-{0x2510, 0x7fff},
+-{0x2510, 0x7fff},
+-{0x2510, 0x7fff},
+-{0x2510, 0xc0e3},
+-{0x2510, 0x2400},
+-{0x2510, 0x27b1},
+-{0x2510, 0x2425},
+-{0x2510, 0xc063},
+-{0x2510, 0x2420},
+-{0x2510, 0x2751},
+-{0x2510, 0x2423},
+-{0x2510, 0x2750},
+-{0x2510, 0x2421},
+-{0x2510, 0xc003},
+-{0x2510, 0x3244},
+-{0x2510, 0x7fff},
+-{0x2510, 0x7fff},
+-{0x2510, 0x7fff},
+-{0x2510, 0x7fff},
+-{0x2510, 0x2404},
+-{0x2510, 0x2779},
+-{0x2510, 0x242c},
+-{0x2510, 0x2781},
+-{0x2510, 0x242d},
+-{0x2510, 0x3244},
+-{0x2510, 0x7fff},
+-{0x2510, 0x7fff},
+-{0x2510, 0x2791},
+-{0x2510, 0x2430},
+-{0x2510, 0x2799},
+-{0x2510, 0x2428},
+-{0x2510, 0x3244},
+-{0x2510, 0x7fff},
+-{0x2510, 0x7fff},
+-{0x2510, 0x7fff},
+-{0x2510, 0x2417},
+-{0x2510, 0xc023},
+-{0x2510, 0x2403},
+-{0x2510, 0x2703},
+-{0x2510, 0x3242},
+-{0x2510, 0x2404},
+-{0x2510, 0x240d},
+-{0x2510, 0xc003},
+-{0x2510, 0x2703},
+-{0x2510, 0x3242},
+-{0x2510, 0x2400},
+-{0x2510, 0x2408},
+-{0x2510, 0x2703},
+-{0x2510, 0x3242},
+-{0x2510, 0x2417},
+-{0x2510, 0x240b},
+-{0x2510, 0x3244},
+-{0x2510, 0x7fff},
+-{0x2510, 0x7fff},
+-{0x2510, 0x7fff},
+-{0x2510, 0xc022},
+-{0x2510, 0x2402},
+-{0x2510, 0x2405},
+-{0x2510, 0x2414},
+-{0x2510, 0x3244},
+-{0x2510, 0x7fff},
+-{0x2510, 0x7fff},
+-{0x2510, 0x7fff},
+-{0x2510, 0xc022},
+-{0x2510, 0x2407},
+-{0x2510, 0x2405},
+-{0x2510, 0xc061},
+-{0x2510, 0x2400},
+-{0x2510, 0xc023},
+-{0x2510, 0x2403},
+-{0x2510, 0xc003},
+-{0x2510, 0x3244},
+-{0x2510, 0x7fff},
+-{0x2510, 0x7fff},
+-{0x2510, 0x7fff},
+-{0x2510, 0xc022},
+-{0x2510, 0x2404},
+-{0x2510, 0x2779},
+-{0x2510, 0x2433},
+-{0x2510, 0x2781},
+-{0x2510, 0x2436},
+-{0x2510, 0x3244},
+-{0x2510, 0x7fff},
+-{0x2510, 0x7fff},
+-{0x2510, 0x7fff},
+-{0x2510, 0x7fff},
+-{0x2510, 0x7fff},
+-{0x2510, 0xc126},
+-{0x2510, 0x2407},
+-{0x2510, 0xc022},
+-{0x2510, 0x2406},
+-{0x2510, 0x2402},
+-{0x2510, 0xc023},
+-{0x2510, 0x2405},
+-{0x2510, 0x2417},
+-{0x2510, 0x3244},
+-{0x2510, 0x7fff},
+-{0x2510, 0x7fff},
+-{0x2510, 0x7fff},
+-{0x2510, 0x3244},
+-{0x2510, 0x7fff},
+-{0x2510, 0x7fff},
+-{0x2510, 0x7fff},
+-{0x2510, 0xffff},
+-{0x2510, 0xffff},
+-{0x2510, 0xffff},
+-{0x2510, 0xffff},
+-{0x2510, 0xffff},
+-{0x2510, 0xffff},
+-{0x2510, 0xffff},
+-{0x2510, 0xffff},
+-{0x2510, 0xffff},
+-{0x2510, 0xffff},
+-{0x2510, 0xffff},
+-{0x2510, 0xffff},
+-{0x2510, 0xffff},
+-{0x2510, 0xffff},
+-{0x2510, 0xffff},
+-{0x2510, 0xffff},
+-{0x2510, 0xffff},
+-{0x2510, 0xffff},
+-{0x2510, 0xffff},
+-{0x2510, 0xffff},
+-{0x2510, 0xffff},
+-{0x2510, 0xffff},
+-{0x2510, 0xffff},
+-{0x2510, 0xffff},
+-{0x2510, 0xffff},
+-{0x2510, 0xffff},
+-{0x2510, 0xffff},
+-{0x2510, 0xffff},
+-{0x2510, 0xffff},
+-{0x2510, 0xffff},
+-{0x2510, 0xffff},
+-{0x2510, 0xffff},
+-{0x2510, 0xffff},
+-{0x2510, 0xffff},
+-{0x2510, 0xffff},
+-{0x2510, 0xffff},
+-{0x2510, 0xffff},
+-{0x2510, 0xffff},
+-{0x2510, 0xffff},
+-{0x2510, 0xffff},
+-{0x2510, 0xffff},
+-{0x2510, 0xffff},
+-{0x2510, 0xffff},
+-{0x2510, 0xffff},
+-{0x2510, 0xffff},
+-{0x2510, 0xffff},
+-{0x2510, 0xffff},
+-{0x2510, 0xffff},
+-{0x2510, 0xffff},
+-{0x2510, 0xffff},
+-{0x2510, 0xffff},
+-{0x2510, 0xffff},
+-{0x2510, 0xffff},
+-{0x2510, 0xffff},
+-{0x2510, 0xffff},
+-{0x2510, 0xffff},
+-{0x2510, 0xffff},
+-{0x2510, 0xffff},
+-{0x2510, 0xffff},
+-{0x2510, 0xffff},
+-{0x2510, 0xffff},
+-{0x2510, 0xffff},
+-{0x2510, 0xffff},
+-{0x2510, 0xffff},
+-{0x2510, 0xffff},
+-{0x2510, 0xffff},
+-{0x2510, 0xffff},
+-{0x2510, 0xffff},
+-{0x2510, 0xffff},
+-{0x2510, 0xffff},
+-{0x2510, 0xffff},
+-{0x2510, 0xffff},
+-{0x2510, 0xffff},
+-{0x2510, 0xffff},
+-{0x2510, 0xffff},
+-{0x2510, 0xffff},
+-{0x2510, 0xffff},
+-{0x2510, 0xffff},
+-{0x2510, 0xffff},
+-{0x2510, 0xffff},
+-{0x2510, 0xffff},
+-{0x2510, 0xffff},
+-{0x2510, 0xffff},
+-{0x2510, 0xffff},
+-{0x2510, 0xffff},
+-{0x2510, 0xffff},
+-{0x2510, 0xffff},
+-{0x2510, 0xffff},
+-{0x2510, 0xffff},
+-{0x2510, 0xffff},
+-{0x2510, 0xffff},
+-
+ {AR0323_DELAY, 100}, // Wait 100ms
+ {0x301A, 0x0058}, // RESET_REGISTER
++{AR0323_DELAY, 200}, // Wait 200ms
+
+-{0x31AC, 0x140C}, // DATA_FORMAT_BITS
+-{0x31D0, 0x0001}, // COMPANDING
+-{0x336E, 0x01DF}, // DATAPATH_SELECT2
+-{0x3238, 0x0666}, // EXPOSURE_RATIO
+ #if 1
+-{0x300C, 0x0A60}, // LINE_LENGTH_PCK_
+-{0x300A, 0x04A0}, // FRAME_LENGTH_LINES_
+-#else
+-{0x300A, AR0323_SENSOR_HEIGHT + 208}, // FRAME_LENGTH_LINES_
+-{0x300C, AR0323_SENSOR_WIDTH + 300}, // LINE_LENGTH_PCK_
+-#endif
++//2880x992 resolution
++{0x3004, 0x00A8}, // X_ADDR_START_
++{0x3008, 0x0AA7}, // X_ADDR_END_
++{0x3002, 0x0030}, // Y_ADDR_START_
++{0x3006, 0x040F}, // Y_ADDR_END_
+
+-#if 0
+-//2880x1072 resolution
+-{0x3004, 0x0008}, // X_ADDR_START_
+-{0x3008, 0x0B47}, // X_ADDR_END_
+-{0x3002, 0x010C}, // Y_ADDR_START_
+-{0x3006, 0x053B}, // Y_ADDR_END_
+ #else
+ {0x3004, AR0323_X_START}, // X_ADDR_START_
+ {0x3008, AR0323_X_END}, // X_ADDR_END_
+@@ -1139,197 +72,1580 @@ static const struct ar0323_reg ar0323_regs_wizard[] = {
+ {0x3404, 0x0000 | AR0323_MAX_HEIGHT}, // Y_OUTPUT_CONTROL
+ #endif
+
+-{0x3534, 0xA282}, // DAC_LD_52_53
+-{0x3524, 0x0FFF}, // DAC_LD_36_37
+-{0x3180, 0x1001}, // DELTA_DK_CONTROL
+-{0x3576, 0x1F09}, // DAC_LD_118_119
+-
+-{0x3548, 0x7878}, // DAC_LD_72_73
+-{0x354C, 0x4141}, // DAC_LD_76_77
+-{0x354E, 0x4B4B}, // DAC_LD_78_79
+-{0x356E, 0x158A}, // DAC_LD_110_111
+-
+-//overflow},settings
+-{0x3496, 0xCF0A}, // LFM_CONTROL
+-{0x350E, 0x2181}, // DAC_LD_14_15
+-{0x3E02, 0x0834}, // LFM2_T1_E1_A
+-{0x3E04, 0x0000}, // LFM2_T1_E1_B
+-{0x3E08, 0x1FFF}, // LFM2_T1_E2_A
+-{0x3E14, 0x0020}, // LFM2_T1_SLOPE
+-{0x3E16, 0x1F40}, // LFM2_T1_E1_THRESHOLD
+-//
+-{0x562A, 0x05DC}, // OCL_T1_E2_E1_SAT
+-{0x563A, 0x0011}, // OCL_T1_GAIN_
+-
+-{0x3364, 0x068C}, // DCG_TRIM
+-{0x3290, 0xD354}, // T3_BARRIER_C0
+-{0x3292, 0xD354}, // T3_BARRIER_C1
+-{0x3294, 0xD354}, // T3_BARRIER_C2
+-{0x3296, 0xD354}, // T3_BARRIER_C3
+-{0x3298, 0xD354}, // T4_BARRIER_C0
+-{0x329A, 0xD354}, // T4_BARRIER_C1
+-{0x329C, 0xD354}, // T4_BARRIER_C2
+-{0x329E, 0xD354}, // T4_BARRIER_C3
+-{0x33DA, 0x0001}, // OC_LUT_CONTROL
+-{0x3D00, 0x6007}, // MEC_CTRL1
+-
+-{0x3040, 0xC005}, // READ_MODE
+-{0x3352, 0x2000}, // MIPI_DT_VC_CONFIG
+-{0x3064, 0x0180}, // SMIA_TEST
+-
+-{0x3D10, 0x0000}, // VIS_BOUND_X0
+-{0x3D12, 0x0B40}, // VIS_BOUND_X1
+-{0x3D14, 0x001E}, // VIS_BOUND_Y0
+-{0x3D16, 0x045A}, // VIS_BOUND_Y1
+-
+-{0x3D08, 0x0000}, // DTR_BOUND_X0
+-{0x3D0A, 0x0B40}, // DTR_BOUND_X1
+-{0x3D0C, 0x0004}, // DTR_BOUND_Y0
+-{0x3D0E, 0x000C}, // DTR_BOUND_Y1
+-{AR0323_DELAY, 100}, // Wait 100ms
+-
+-//Pre HDR gain LG lens
++#if 1
++{0x300A, 0x047E}, // FRAME_LENGTH_LINES_
++{0x300C, 0x0A6E}, // LINE_LENGTH_PCK_
++#else
++{0x300A, AR0323_SENSOR_HEIGHT + 208}, // FRAME_LENGTH_LINES_
++{0x300C, AR0323_SENSOR_WIDTH + 300}, // LINE_LENGTH_PCK_
++#endif
++{0x3030, 0x0050}, // PLL_MULTIPLIER
++{0x302E, 0x0004}, // PRE_PLL_CLK_DIV
++{0x302C, 0x0001}, // VT_SYS_CLK_DIV
++{0x302A, 0x0004}, // VT_PIX_CLK_DIV
++{0x3038, 0x0002}, // OP_SYS_CLK_DIV
++{0x3036, 0x0006}, // OP_WORD_CLK_DIV
++{0x31DC, 0x1FA0}, // RESERVED_MFR_31DC
++{0x31B0, 0x0036}, // FRAME_PREAMBLE
++{0x31B2, 0x001F}, // LINE_PREAMBLE
++{0x31B4, 0x4145}, // RESERVED_MFR_31B4
++{0x31B6, 0x3184}, // RESERVED_MFR_31B6
++{0x31B8, 0x4048}, // RESERVED_MFR_31B8
++{0x31BA, 0x0206}, // RESERVED_MFR_31BA
++{0x31BC, 0x8705}, // RESERVED_MFR_31BC
++{0x3342, 0x122C}, // MIPI_F1_PDT_EDT
++{0x3346, 0x122C}, // MIPI_F2_PDT_EDT
++{0x334A, 0x122C}, // MIPI_F3_PDT_EDT
++{0x334E, 0x122C}, // MIPI_F4_PDT_EDT
++{0x3546, 0x4603}, // RESERVED_MFR_3546
++{0x342E, 0x0017}, // RESERVED_MFR_342E
++{0x3092, 0x400C}, // RESERVED_MFR_3092
++{0x3E3E, 0x000C}, // RESERVED_MFR_3E3E
++{0x3550, 0x806C}, // RESERVED_MFR_3550
++{0x356A, 0x81AA}, // RESERVED_MFR_356A
++{0x356E, 0x068A}, // RESERVED_MFR_356E
++{0x356C, 0x6A28}, // RESERVED_MFR_356C
++{0x3C72, 0x0076}, // ADC_DEC_CTRL7
++{0x3C74, 0x0031}, // ADC_DEC_CTRL8
++{0x3C76, 0x00DC}, // ADC_DEC_CTRL9
++{0x3C78, 0x01AA}, // ADC_DEC_CTRL10
++{0x3C7A, 0x0352}, // ADC_DEC_CTRL11
++{0x3C7C, 0x06AA}, // ADC_DEC_CTRL12
++{0x37B2, 0x1FFF}, // RESERVED_MFR_37B2
++{0x3562, 0x0C08}, // RESERVED_MFR_3562
++{0x3086, 0x0000}, // RESERVED_MFR_3086
++{0x3576, 0x1DFF}, // RESERVED_MFR_3576
++{0x3564, 0x1A23}, // RESERVED_MFR_3564
++{0x3508, 0xEF1A}, // RESERVED_MFR_3508
++{0x3544, 0x030F}, // RESERVED_MFR_3544
++{0x336E, 0x0147}, // DATAPATH_SELECT2
++{0x3E40, 0x00E0}, // RESERVED_MFR_3E40
++{0x3EF0, 0x0B70}, // BALANCER_CTRL_0
+ {0x3110, 0x0011}, // HDR_CONTROL0
+-{0x3056, 0x0031}, // GREEN1_GAIN
+-{0x3058, 0x0080}, // BLUE_GAIN
+-{0x305A, 0x0070}, // RED_GAIN
+-{0x305C, 0x0031}, // GREEN2_GAIN
+-{0x3308, 0x0539}, // GLOBAL_GAIN2_
+-{0x3D28, 0x3BD1}, // T1_STR_DEC_TH
+-{0x3D2A, 0x4C2C}, // T1_END_DEC_TH
+-
+-//booster
+-{0x352C, 0x8146}, // DAC_LD_44_45
+-{0x352E, 0x1871}, // DAC_LD_46_47
+-{0x3538, 0x81EA}, // DAC_LD_56_57
+-
+-{0x3576, 0x1F49}, // DAC_LD_118_119
+-{0x3544, 0x03A1}, // DAC_LD_68_69
+-
+-{0x354C, 0x411E}, // DAC_LD_76_77
+-//
+-{0x351A, 0x7900},
+-
+-//Temp_sensor_read
+-{0x3E94, 0x3010}, // TEMPVSENS1_SREG_TRIM0
++{0x350E, 0x2088}, // RESERVED_MFR_350E
++{0x3510, 0x780F}, // RESERVED_MFR_3510
++{0x351E, 0x7FDE}, // RESERVED_MFR_351E
++{0x3520, 0x0080}, // RESERVED_MFR_3520
++{0x3526, 0x5000}, // RESERVED_MFR_3526
++{0x3528, 0x200A}, // RESERVED_MFR_3528
++{0x352A, 0x0F27}, // RESERVED_MFR_352A
++{0x3530, 0x1010}, // RESERVED_MFR_3530
++{0x3532, 0x9000}, // RESERVED_MFR_3532
++{0x3534, 0x3098}, // RESERVED_MFR_3534
++{0x3536, 0x90C0}, // RESERVED_MFR_3536
++{0x3538, 0x0702}, // RESERVED_MFR_3538
++{0x353A, 0x02B2}, // RESERVED_MFR_353A
++{0x353C, 0x9A01}, // RESERVED_MFR_353C
++{0x3552, 0x0832}, // RESERVED_MFR_3552
++{0x3570, 0xAA6A}, // RESERVED_MFR_3570
++{0x357E, 0x5B5B}, // RESERVED_MFR_357E
++{0x3496, 0x6F00}, // RESERVED_MFR_3496
++{0x34BC, 0x0808}, // LFM_PATTERN_CTRL
++{0x3494, 0x0808}, // RESERVED_MFR_3494
++{0x3492, 0x0004}, // RESERVED_MFR_3492
++{0x34BA, 0x0001}, // RESERVED_MFR_34BA
++{0x34B8, 0x0001}, // RESERVED_MFR_34B8
++{0x3E00, 0x8000}, // LFM2_T1_CTRL
++{0x3E04, 0x0000}, // RESERVED_MFR_3E04
++{0x3E06, 0x0000}, // RESERVED_MFR_3E06
++{0x3E10, 0x0006}, // RESERVED_MFR_3E10
++{0x3E16, 0x1FFF}, // RESERVED_MFR_3E16
++{0x350E, 0x2090}, // RESERVED_MFR_350E
++{0x350E, 0x2091}, // RESERVED_MFR_350E
++{0x3450, 0x00D7}, // RESERVED_MFR_3450
++{0x3452, 0x00D7}, // RESERVED_MFR_3452
++{0x3454, 0x00D7}, // RESERVED_MFR_3454
++{0x3456, 0x00D7}, // RESERVED_MFR_3456
++{0x3458, 0x00D7}, // RESERVED_MFR_3458
++{0x345A, 0x00D7}, // RESERVED_MFR_345A
++{0x345C, 0x00D7}, // RESERVED_MFR_345C
++{0x345E, 0x00D7}, // RESERVED_MFR_345E
++{0x3460, 0x00D7}, // RESERVED_MFR_3460
++{0x3462, 0x00D7}, // RESERVED_MFR_3462
++{0x3464, 0x00D7}, // RESERVED_MFR_3464
++{0x3466, 0x00D7}, // RESERVED_MFR_3466
++{0x3468, 0x00D7}, // RESERVED_MFR_3468
++{0x346A, 0x00D7}, // RESERVED_MFR_346A
++{0x346C, 0x00D7}, // RESERVED_MFR_346C
++{0x346E, 0x00D7}, // RESERVED_MFR_346E
++{0x3470, 0x00D7}, // RESERVED_MFR_3470
++{0x3472, 0x00D7}, // RESERVED_MFR_3472
++{0x3474, 0x00D7}, // RESERVED_MFR_3474
++{0x3476, 0x00D7}, // RESERVED_MFR_3476
++{0x3478, 0x00D7}, // RESERVED_MFR_3478
++{0x347A, 0x00D7}, // RESERVED_MFR_347A
++{0x347C, 0x00D7}, // RESERVED_MFR_347C
++{0x347E, 0x00D7}, // RESERVED_MFR_347E
++{0x3480, 0x00D7}, // RESERVED_MFR_3480
++{0x3482, 0x00D7}, // RESERVED_MFR_3482
++{0x3484, 0x00D7}, // RESERVED_MFR_3484
++{0x3486, 0x00D7}, // RESERVED_MFR_3486
++{0x3488, 0x00D7}, // RESERVED_MFR_3488
++{0x348A, 0x00D7}, // RESERVED_MFR_348A
++{0x348C, 0x00D7}, // RESERVED_MFR_348C
++{0x348E, 0x00D7}, // RESERVED_MFR_348E
++{0x3490, 0x00D7}, // RESERVED_MFR_3490
++{0x357C, 0x4E00}, // RESERVED_MFR_357C
++{0x352C, 0xA004}, // RESERVED_MFR_352C
++{0x34AA, 0x0001}, // RESERVED_MFR_34AA
++{0x34AC, 0x0097}, // RESERVED_MFR_34AC
++{0x34A8, 0x0098}, // RESERVED_MFR_34A8
++{0x34AE, 0x00B6}, // RESERVED_MFR_34AE
++{0x349A, 0x0001}, // RESERVED_MFR_349A
++{0x349E, 0x0002}, // RESERVED_MFR_349E
++{0x35F0, 0x0002}, // LFM_BST_DCGBOT_SEL_CLK_CTRL
++{0x35F4, 0x0003}, // LFM_BST_DCGBOT_VAAPIX_CLK_CTRL
++{0x34B0, 0x0003}, // RESERVED_MFR_34B0
++{0x349C, 0x0004}, // RESERVED_MFR_349C
++{0x34B6, 0x001D}, // RESERVED_MFR_34B6
++{0x34A2, 0x001D}, // RESERVED_MFR_34A2
++{0x34A4, 0x0084}, // RESERVED_MFR_34A4
++{0x34A0, 0x0085}, // RESERVED_MFR_34A0
++{0x35F6, 0x0099}, // LFM_BST_DCGBOT_VAAPIX_CLR_CLK_CTRL
++{0x34A6, 0x0099}, // RESERVED_MFR_34A6
++{0x34B2, 0x00AD}, // RESERVED_MFR_34B2
++{0x34B4, 0x00C1}, // RESERVED_MFR_34B4
++{0x35F2, 0x00C1}, // LFM_BST_DCGBOT_DESEL_CLK_CTRL
++{0x351A, 0xE900}, // RESERVED_MFR_351A
++{0x357A, 0x0044}, // RESERVED_MFR_357A
++{0x3514, 0x5B5B}, // RESERVED_MFR_3514
++{0x3578, 0x5B5B}, // RESERVED_MFR_3578
++{0x3526, 0x5000}, // RESERVED_MFR_3526
++{0x352A, 0x0827}, // RESERVED_MFR_352A
++{0x3512, 0x0EDB}, // RESERVED_MFR_3512
++{0x3518, 0x4040}, // RESERVED_MFR_3518
++{0x352E, 0x080A}, // RESERVED_MFR_352E
++{0x3528, 0x200A}, // RESERVED_MFR_3528
++{0x353A, 0x02B2}, // RESERVED_MFR_353A
++{0x3496, 0x6B00}, // RESERVED_MFR_3496
++{0x3516, 0x8888}, // RESERVED_MFR_3516
++{0x351C, 0xCFF2}, // RESERVED_MFR_351C
++{0x353E, 0x2044}, // RESERVED_MFR_353E
++{0x3540, 0x4444}, // RESERVED_MFR_3540
++{0x3542, 0x448F}, // RESERVED_MFR_3542
++{0x2512, 0x8000}, // RESERVED_MFR2_2512
++{0x2510, 0x0409}, // RESERVED_MFR2_2510
++{0x2510, 0x0A0B}, // RESERVED_MFR2_2510
++{0x2510, 0x0C0E}, // RESERVED_MFR2_2510
++{0x2510, 0xFFFF}, // RESERVED_MFR2_2510
++{0x2510, 0xFFFF}, // RESERVED_MFR2_2510
++{0x2510, 0xFFFF}, // RESERVED_MFR2_2510
++{0x2510, 0xFFFF}, // RESERVED_MFR2_2510
++{0x2510, 0xFFFF}, // RESERVED_MFR2_2510
++{0x2510, 0x1011}, // RESERVED_MFR2_2510
++{0x2510, 0x1314}, // RESERVED_MFR2_2510
++{0x2510, 0x1516}, // RESERVED_MFR2_2510
++{0x2510, 0xFFFF}, // RESERVED_MFR2_2510
++{0x2510, 0x1827}, // RESERVED_MFR2_2510
++{0x2510, 0x2F3F}, // RESERVED_MFR2_2510
++{0x2510, 0x484B}, // RESERVED_MFR2_2510
++{0x2510, 0x4D51}, // RESERVED_MFR2_2510
++{0x2510, 0x5859}, // RESERVED_MFR2_2510
++{0x2510, 0x5E61}, // RESERVED_MFR2_2510
++{0x2510, 0x6263}, // RESERVED_MFR2_2510
++{0x2510, 0x6567}, // RESERVED_MFR2_2510
++{0x2510, 0x696A}, // RESERVED_MFR2_2510
++{0x2510, 0x6B6C}, // RESERVED_MFR2_2510
++{0x2510, 0x6E6F}, // RESERVED_MFR2_2510
++{0x2510, 0x7D7E}, // RESERVED_MFR2_2510
++{0x2510, 0x828C}, // RESERVED_MFR2_2510
++{0x2510, 0xFFFF}, // RESERVED_MFR2_2510
++{0x2510, 0xFFFF}, // RESERVED_MFR2_2510
++{0x2510, 0xFFFF}, // RESERVED_MFR2_2510
++{0x2510, 0xFFFF}, // RESERVED_MFR2_2510
++{0x2510, 0xFFFF}, // RESERVED_MFR2_2510
++{0x2510, 0xFFFF}, // RESERVED_MFR2_2510
++{0x2510, 0xFFFF}, // RESERVED_MFR2_2510
++{0x2510, 0xC003}, // RESERVED_MFR2_2510
++{0x2510, 0x8058}, // RESERVED_MFR2_2510
++{0x2510, 0xD802}, // RESERVED_MFR2_2510
++{0x2510, 0xA0E0}, // RESERVED_MFR2_2510
++{0x2510, 0x3041}, // RESERVED_MFR2_2510
++{0x2510, 0x3042}, // RESERVED_MFR2_2510
++{0x2510, 0x2000}, // RESERVED_MFR2_2510
++{0x2510, 0x3050}, // RESERVED_MFR2_2510
++{0x2510, 0x3088}, // RESERVED_MFR2_2510
++{0x2510, 0x30A0}, // RESERVED_MFR2_2510
++{0x2510, 0x3090}, // RESERVED_MFR2_2510
++{0x2510, 0x32C2}, // RESERVED_MFR2_2510
++{0x2510, 0xA0C0}, // RESERVED_MFR2_2510
++{0x2510, 0x9008}, // RESERVED_MFR2_2510
++{0x2510, 0x8802}, // RESERVED_MFR2_2510
++{0x2510, 0x20FF}, // RESERVED_MFR2_2510
++{0x2510, 0x20FF}, // RESERVED_MFR2_2510
++{0x2510, 0x20FF}, // RESERVED_MFR2_2510
++{0x2510, 0x20FF}, // RESERVED_MFR2_2510
++{0x2510, 0x20FF}, // RESERVED_MFR2_2510
++{0x2510, 0x9018}, // RESERVED_MFR2_2510
++{0x2510, 0x881A}, // RESERVED_MFR2_2510
++{0x2510, 0xD80A}, // RESERVED_MFR2_2510
++{0x2510, 0x8078}, // RESERVED_MFR2_2510
++{0x2510, 0xD80E}, // RESERVED_MFR2_2510
++{0x2510, 0x20FF}, // RESERVED_MFR2_2510
++{0x2510, 0x885B}, // RESERVED_MFR2_2510
++{0x2510, 0x20FF}, // RESERVED_MFR2_2510
++{0x2510, 0x887B}, // RESERVED_MFR2_2510
++{0x2510, 0x20FF}, // RESERVED_MFR2_2510
++{0x2510, 0x887F}, // RESERVED_MFR2_2510
++{0x2510, 0x20FF}, // RESERVED_MFR2_2510
++{0x2510, 0x7FFF}, // RESERVED_MFR2_2510
++{0x2510, 0x7FFF}, // RESERVED_MFR2_2510
++{0x2510, 0x7FFF}, // RESERVED_MFR2_2510
++{0x2510, 0x7FFF}, // RESERVED_MFR2_2510
++{0x2510, 0x7FFF}, // RESERVED_MFR2_2510
++{0x2510, 0x7FFF}, // RESERVED_MFR2_2510
++{0x2510, 0x7FFF}, // RESERVED_MFR2_2510
++{0x2510, 0x7FFF}, // RESERVED_MFR2_2510
++{0x2510, 0x20FF}, // RESERVED_MFR2_2510
++{0x2510, 0x7FFF}, // RESERVED_MFR2_2510
++{0x2510, 0x7FFF}, // RESERVED_MFR2_2510
++{0x2510, 0x7FFF}, // RESERVED_MFR2_2510
++{0x2510, 0x7FFF}, // RESERVED_MFR2_2510
++{0x2510, 0x7FFF}, // RESERVED_MFR2_2510
++{0x2510, 0x7FFF}, // RESERVED_MFR2_2510
++{0x2510, 0x7FFF}, // RESERVED_MFR2_2510
++{0x2510, 0x20FF}, // RESERVED_MFR2_2510
++{0x2510, 0x7FFF}, // RESERVED_MFR2_2510
++{0x2510, 0x7FFF}, // RESERVED_MFR2_2510
++{0x2510, 0x7FFF}, // RESERVED_MFR2_2510
++{0x2510, 0x7FFF}, // RESERVED_MFR2_2510
++{0x2510, 0x7FFF}, // RESERVED_MFR2_2510
++{0x2510, 0x7FFF}, // RESERVED_MFR2_2510
++{0x2510, 0x7FFF}, // RESERVED_MFR2_2510
++{0x2510, 0x20FF}, // RESERVED_MFR2_2510
++{0x2510, 0x7FFF}, // RESERVED_MFR2_2510
++{0x2510, 0x7FFF}, // RESERVED_MFR2_2510
++{0x2510, 0x7FFF}, // RESERVED_MFR2_2510
++{0x2510, 0x7FFF}, // RESERVED_MFR2_2510
++{0x2510, 0x7FFF}, // RESERVED_MFR2_2510
++{0x2510, 0x7FFF}, // RESERVED_MFR2_2510
++{0x2510, 0x7FFF}, // RESERVED_MFR2_2510
++{0x2510, 0xA0C4}, // RESERVED_MFR2_2510
++{0x2510, 0x20FF}, // RESERVED_MFR2_2510
++{0x2510, 0x8058}, // RESERVED_MFR2_2510
++{0x2510, 0xD80A}, // RESERVED_MFR2_2510
++{0x2510, 0x9039}, // RESERVED_MFR2_2510
++{0x2510, 0x20FF}, // RESERVED_MFR2_2510
++{0x2510, 0x907F}, // RESERVED_MFR2_2510
++{0x2510, 0x885B}, // RESERVED_MFR2_2510
++{0x2510, 0x2064}, // RESERVED_MFR2_2510
++{0x2510, 0x881B}, // RESERVED_MFR2_2510
++{0x2510, 0x2010}, // RESERVED_MFR2_2510
++{0x2510, 0x8803}, // RESERVED_MFR2_2510
++{0x2510, 0xD802}, // RESERVED_MFR2_2510
++{0x2510, 0x7FFF}, // RESERVED_MFR2_2510
++{0x2510, 0x7FFF}, // RESERVED_MFR2_2510
++{0x2510, 0x7FFF}, // RESERVED_MFR2_2510
++{0x2510, 0x20FF}, // RESERVED_MFR2_2510
++{0x2510, 0x906B}, // RESERVED_MFR2_2510
++{0x2510, 0x2064}, // RESERVED_MFR2_2510
++{0x2510, 0x3084}, // RESERVED_MFR2_2510
++{0x2510, 0x2003}, // RESERVED_MFR2_2510
++{0x2510, 0x3048}, // RESERVED_MFR2_2510
++{0x2510, 0x3044}, // RESERVED_MFR2_2510
++{0x2510, 0x2000}, // RESERVED_MFR2_2510
++{0x2510, 0xA004}, // RESERVED_MFR2_2510
++{0x2510, 0x7FFF}, // RESERVED_MFR2_2510
++{0x2510, 0x7FFF}, // RESERVED_MFR2_2510
++{0x2510, 0x7FFF}, // RESERVED_MFR2_2510
++{0x2510, 0x7FFF}, // RESERVED_MFR2_2510
++{0x2510, 0x7FFF}, // RESERVED_MFR2_2510
++{0x2510, 0x7FFF}, // RESERVED_MFR2_2510
++{0x2510, 0x7FFF}, // RESERVED_MFR2_2510
++{0x2510, 0x2400}, // RESERVED_MFR2_2510
++{0x2510, 0x2401}, // RESERVED_MFR2_2510
++{0x2510, 0x7FFF}, // RESERVED_MFR2_2510
++{0x2510, 0x7FFF}, // RESERVED_MFR2_2510
++{0x2510, 0x7FFF}, // RESERVED_MFR2_2510
++{0x2510, 0x7FFF}, // RESERVED_MFR2_2510
++{0x2510, 0x7FFF}, // RESERVED_MFR2_2510
++{0x2510, 0x7FFF}, // RESERVED_MFR2_2510
++{0x2510, 0x2400}, // RESERVED_MFR2_2510
++{0x2510, 0x2401}, // RESERVED_MFR2_2510
++{0x2510, 0x2702}, // RESERVED_MFR2_2510
++{0x2510, 0x3242}, // RESERVED_MFR2_2510
++{0x2510, 0x2420}, // RESERVED_MFR2_2510
++{0x2510, 0x2421}, // RESERVED_MFR2_2510
++{0x2510, 0x2703}, // RESERVED_MFR2_2510
++{0x2510, 0x3242}, // RESERVED_MFR2_2510
++{0x2510, 0x2420}, // RESERVED_MFR2_2510
++{0x2510, 0x2421}, // RESERVED_MFR2_2510
++{0x2510, 0x2704}, // RESERVED_MFR2_2510
++{0x2510, 0x3242}, // RESERVED_MFR2_2510
++{0x2510, 0x2420}, // RESERVED_MFR2_2510
++{0x2510, 0x2421}, // RESERVED_MFR2_2510
++{0x2510, 0x7FFF}, // RESERVED_MFR2_2510
++{0x2510, 0x7FFF}, // RESERVED_MFR2_2510
++{0x2510, 0x2402}, // RESERVED_MFR2_2510
++{0x2510, 0x2403}, // RESERVED_MFR2_2510
++{0x2510, 0x7FFF}, // RESERVED_MFR2_2510
++{0x2510, 0x7FFF}, // RESERVED_MFR2_2510
++{0x2510, 0x7FFF}, // RESERVED_MFR2_2510
++{0x2510, 0x7FFF}, // RESERVED_MFR2_2510
++{0x2510, 0x7FFF}, // RESERVED_MFR2_2510
++{0x2510, 0x7FFF}, // RESERVED_MFR2_2510
++{0x2510, 0x2741}, // RESERVED_MFR2_2510
++{0x2510, 0x2429}, // RESERVED_MFR2_2510
++{0x2510, 0x2740}, // RESERVED_MFR2_2510
++{0x2510, 0x242A}, // RESERVED_MFR2_2510
++{0x2510, 0x7FFF}, // RESERVED_MFR2_2510
++{0x2510, 0x7FFF}, // RESERVED_MFR2_2510
++{0x2510, 0x7FFF}, // RESERVED_MFR2_2510
++{0x2510, 0x7FFF}, // RESERVED_MFR2_2510
++{0x2510, 0x2779}, // RESERVED_MFR2_2510
++{0x2510, 0x242C}, // RESERVED_MFR2_2510
++{0x2510, 0x2781}, // RESERVED_MFR2_2510
++{0x2510, 0x242D}, // RESERVED_MFR2_2510
++{0x2510, 0x7FFF}, // RESERVED_MFR2_2510
++{0x2510, 0x7FFF}, // RESERVED_MFR2_2510
++{0x2510, 0x7FFF}, // RESERVED_MFR2_2510
++{0x2510, 0x7FFF}, // RESERVED_MFR2_2510
++{0x2510, 0x2703}, // RESERVED_MFR2_2510
++{0x2510, 0x2432}, // RESERVED_MFR2_2510
++{0x2510, 0x2703}, // RESERVED_MFR2_2510
++{0x2510, 0x3242}, // RESERVED_MFR2_2510
++{0x2510, 0x27BB}, // RESERVED_MFR2_2510
++{0x2510, 0x2430}, // RESERVED_MFR2_2510
++{0x2510, 0x27BB}, // RESERVED_MFR2_2510
++{0x2510, 0x3242}, // RESERVED_MFR2_2510
++{0x2510, 0x2702}, // RESERVED_MFR2_2510
++{0x2510, 0x2431}, // RESERVED_MFR2_2510
++{0x2510, 0x2702}, // RESERVED_MFR2_2510
++{0x2510, 0x3242}, // RESERVED_MFR2_2510
++{0x2510, 0x27C3}, // RESERVED_MFR2_2510
++{0x2510, 0x2430}, // RESERVED_MFR2_2510
++{0x2510, 0x7FFF}, // RESERVED_MFR2_2510
++{0x2510, 0x7FFF}, // RESERVED_MFR2_2510
++{0x2510, 0xB800}, // RESERVED_MFR2_2510
++{0x2510, 0x3250}, // RESERVED_MFR2_2510
++{0x2510, 0x3108}, // RESERVED_MFR2_2510
++{0x2510, 0x8058}, // RESERVED_MFR2_2510
++{0x2510, 0xD800}, // RESERVED_MFR2_2510
++{0x2510, 0xA005}, // RESERVED_MFR2_2510
++{0x2510, 0x3101}, // RESERVED_MFR2_2510
++{0x2510, 0x3041}, // RESERVED_MFR2_2510
++{0x2510, 0x3104}, // RESERVED_MFR2_2510
++{0x2510, 0xB035}, // RESERVED_MFR2_2510
++{0x2510, 0xB075}, // RESERVED_MFR2_2510
++{0x2510, 0x30C1}, // RESERVED_MFR2_2510
++{0x2510, 0x3102}, // RESERVED_MFR2_2510
++{0x2510, 0x3041}, // RESERVED_MFR2_2510
++{0x2510, 0xB808}, // RESERVED_MFR2_2510
++{0x2510, 0x3202}, // RESERVED_MFR2_2510
++{0x2510, 0xB848}, // RESERVED_MFR2_2510
++{0x2510, 0xB84C}, // RESERVED_MFR2_2510
++{0x2510, 0x2201}, // RESERVED_MFR2_2510
++{0x2510, 0xB377}, // RESERVED_MFR2_2510
++{0x2510, 0x8843}, // RESERVED_MFR2_2510
++{0x2510, 0x916F}, // RESERVED_MFR2_2510
++{0x2510, 0x2201}, // RESERVED_MFR2_2510
++{0x2510, 0xB84E}, // RESERVED_MFR2_2510
++{0x2510, 0xF905}, // RESERVED_MFR2_2510
++{0x2510, 0xF907}, // RESERVED_MFR2_2510
++{0x2510, 0x2200}, // RESERVED_MFR2_2510
++{0x2510, 0x885B}, // RESERVED_MFR2_2510
++{0x2510, 0xA898}, // RESERVED_MFR2_2510
++{0x2510, 0xA8D8}, // RESERVED_MFR2_2510
++{0x2510, 0xF8E8}, // RESERVED_MFR2_2510
++{0x2510, 0x80D8}, // RESERVED_MFR2_2510
++{0x2510, 0x9007}, // RESERVED_MFR2_2510
++{0x2510, 0x916F}, // RESERVED_MFR2_2510
++{0x2510, 0x2206}, // RESERVED_MFR2_2510
++{0x2510, 0xB808}, // RESERVED_MFR2_2510
++{0x2510, 0xC800}, // RESERVED_MFR2_2510
++{0x2510, 0xE807}, // RESERVED_MFR2_2510
++{0x2510, 0x88DB}, // RESERVED_MFR2_2510
++{0x2510, 0xF8A8}, // RESERVED_MFR2_2510
++{0x2510, 0xF888}, // RESERVED_MFR2_2510
++{0x2510, 0x2203}, // RESERVED_MFR2_2510
++{0x2510, 0xB07B}, // RESERVED_MFR2_2510
++{0x2510, 0x2000}, // RESERVED_MFR2_2510
++{0x2510, 0x80C8}, // RESERVED_MFR2_2510
++{0x2510, 0x8088}, // RESERVED_MFR2_2510
++{0x2510, 0x220B}, // RESERVED_MFR2_2510
++{0x2510, 0xB06A}, // RESERVED_MFR2_2510
++{0x2510, 0x88CB}, // RESERVED_MFR2_2510
++{0x2510, 0x888B}, // RESERVED_MFR2_2510
++{0x2510, 0x2224}, // RESERVED_MFR2_2510
++{0x2510, 0xB04A}, // RESERVED_MFR2_2510
++{0x2510, 0x2218}, // RESERVED_MFR2_2510
++{0x2510, 0x210D}, // RESERVED_MFR2_2510
++{0x2510, 0x2108}, // RESERVED_MFR2_2510
++{0x2510, 0x902F}, // RESERVED_MFR2_2510
++{0x2510, 0xB04B}, // RESERVED_MFR2_2510
++{0x2510, 0xF880}, // RESERVED_MFR2_2510
++{0x2510, 0x220F}, // RESERVED_MFR2_2510
++{0x2510, 0x2205}, // RESERVED_MFR2_2510
++{0x2510, 0x2203}, // RESERVED_MFR2_2510
++{0x2510, 0x9800}, // RESERVED_MFR2_2510
++{0x2510, 0xB043}, // RESERVED_MFR2_2510
++{0x2510, 0xA8C9}, // RESERVED_MFR2_2510
++{0x2510, 0x31C1}, // RESERVED_MFR2_2510
++{0x2510, 0x80A8}, // RESERVED_MFR2_2510
++{0x2510, 0x2205}, // RESERVED_MFR2_2510
++{0x2510, 0x916F}, // RESERVED_MFR2_2510
++{0x2510, 0x2104}, // RESERVED_MFR2_2510
++{0x2510, 0x88AB}, // RESERVED_MFR2_2510
++{0x2510, 0x2104}, // RESERVED_MFR2_2510
++{0x2510, 0xB808}, // RESERVED_MFR2_2510
++{0x2510, 0x9800}, // RESERVED_MFR2_2510
++{0x2510, 0x2440}, // RESERVED_MFR2_2510
++{0x2510, 0xF110}, // RESERVED_MFR2_2510
++{0x2510, 0xF804}, // RESERVED_MFR2_2510
++{0x2510, 0x2000}, // RESERVED_MFR2_2510
++{0x2510, 0x8088}, // RESERVED_MFR2_2510
++{0x2510, 0x3002}, // RESERVED_MFR2_2510
++{0x2510, 0xB838}, // RESERVED_MFR2_2510
++{0x2510, 0xA8C8}, // RESERVED_MFR2_2510
++{0x2510, 0xB04B}, // RESERVED_MFR2_2510
++{0x2510, 0x2442}, // RESERVED_MFR2_2510
++{0x2510, 0x3210}, // RESERVED_MFR2_2510
++{0x2510, 0x2206}, // RESERVED_MFR2_2510
++{0x2510, 0x888B}, // RESERVED_MFR2_2510
++{0x2510, 0x2441}, // RESERVED_MFR2_2510
++{0x2510, 0x3202}, // RESERVED_MFR2_2510
++{0x2510, 0xF880}, // RESERVED_MFR2_2510
++{0x2510, 0xB830}, // RESERVED_MFR2_2510
++{0x2510, 0xC801}, // RESERVED_MFR2_2510
++{0x2510, 0x30C2}, // RESERVED_MFR2_2510
++{0x2510, 0xE80C}, // RESERVED_MFR2_2510
++{0x2510, 0x2201}, // RESERVED_MFR2_2510
++{0x2510, 0xB04A}, // RESERVED_MFR2_2510
++{0x2510, 0x2227}, // RESERVED_MFR2_2510
++{0x2510, 0x2205}, // RESERVED_MFR2_2510
++{0x2510, 0x2207}, // RESERVED_MFR2_2510
++{0x2510, 0x902F}, // RESERVED_MFR2_2510
++{0x2510, 0x220E}, // RESERVED_MFR2_2510
++{0x2510, 0x2205}, // RESERVED_MFR2_2510
++{0x2510, 0x2204}, // RESERVED_MFR2_2510
++{0x2510, 0xB042}, // RESERVED_MFR2_2510
++{0x2510, 0xA9A1}, // RESERVED_MFR2_2510
++{0x2510, 0x8008}, // RESERVED_MFR2_2510
++{0x2510, 0xB093}, // RESERVED_MFR2_2510
++{0x2510, 0x31C1}, // RESERVED_MFR2_2510
++{0x2510, 0x916B}, // RESERVED_MFR2_2510
++{0x2510, 0x2008}, // RESERVED_MFR2_2510
++{0x2510, 0x32C1}, // RESERVED_MFR2_2510
++{0x2510, 0x8803}, // RESERVED_MFR2_2510
++{0x2510, 0xA044}, // RESERVED_MFR2_2510
++{0x2510, 0x3044}, // RESERVED_MFR2_2510
++{0x2510, 0x2000}, // RESERVED_MFR2_2510
++{0x2510, 0xA004}, // RESERVED_MFR2_2510
++{0x2510, 0x7FFF}, // RESERVED_MFR2_2510
++{0x2510, 0x7FFF}, // RESERVED_MFR2_2510
++{0x2510, 0x7FFF}, // RESERVED_MFR2_2510
++{0x2510, 0x7FFF}, // RESERVED_MFR2_2510
++{0x2510, 0x7FFF}, // RESERVED_MFR2_2510
++{0x2510, 0xA084}, // RESERVED_MFR2_2510
++{0x2510, 0x30D0}, // RESERVED_MFR2_2510
++{0x2510, 0x8107}, // RESERVED_MFR2_2510
++{0x2510, 0xD804}, // RESERVED_MFR2_2510
++{0x2510, 0x3141}, // RESERVED_MFR2_2510
++{0x2510, 0x3042}, // RESERVED_MFR2_2510
++{0x2510, 0x2000}, // RESERVED_MFR2_2510
++{0x2510, 0x3142}, // RESERVED_MFR2_2510
++{0x2510, 0x3042}, // RESERVED_MFR2_2510
++{0x2510, 0x2000}, // RESERVED_MFR2_2510
++{0x2510, 0x3281}, // RESERVED_MFR2_2510
++{0x2510, 0x3042}, // RESERVED_MFR2_2510
++{0x2510, 0x2000}, // RESERVED_MFR2_2510
++{0x2510, 0x3290}, // RESERVED_MFR2_2510
++{0x2510, 0x3042}, // RESERVED_MFR2_2510
++{0x2510, 0x2000}, // RESERVED_MFR2_2510
++{0x2510, 0x3110}, // RESERVED_MFR2_2510
++{0x2510, 0x3042}, // RESERVED_MFR2_2510
++{0x2510, 0x2000}, // RESERVED_MFR2_2510
++{0x2510, 0x3120}, // RESERVED_MFR2_2510
++{0x2510, 0x3042}, // RESERVED_MFR2_2510
++{0x2510, 0x2000}, // RESERVED_MFR2_2510
++{0x2510, 0x3282}, // RESERVED_MFR2_2510
++{0x2510, 0x3042}, // RESERVED_MFR2_2510
++{0x2510, 0x2000}, // RESERVED_MFR2_2510
++{0x2510, 0x32A0}, // RESERVED_MFR2_2510
++{0x2510, 0x3042}, // RESERVED_MFR2_2510
++{0x2510, 0x2000}, // RESERVED_MFR2_2510
++{0x2510, 0x881B}, // RESERVED_MFR2_2510
++{0x2510, 0x895F}, // RESERVED_MFR2_2510
++{0x2510, 0xA08C}, // RESERVED_MFR2_2510
++{0x2510, 0x2200}, // RESERVED_MFR2_2510
++{0x2510, 0xA084}, // RESERVED_MFR2_2510
++{0x2510, 0x2440}, // RESERVED_MFR2_2510
++{0x2510, 0xB095}, // RESERVED_MFR2_2510
++{0x2510, 0xF010}, // RESERVED_MFR2_2510
++{0x2510, 0xF864}, // RESERVED_MFR2_2510
++{0x2510, 0xF90D}, // RESERVED_MFR2_2510
++{0x2510, 0x3084}, // RESERVED_MFR2_2510
++{0x2510, 0x32C1}, // RESERVED_MFR2_2510
++{0x2510, 0x3090}, // RESERVED_MFR2_2510
++{0x2510, 0x3088}, // RESERVED_MFR2_2510
++{0x2510, 0x2443}, // RESERVED_MFR2_2510
++{0x2510, 0x8103}, // RESERVED_MFR2_2510
++{0x2510, 0xD800}, // RESERVED_MFR2_2510
++{0x2510, 0x3001}, // RESERVED_MFR2_2510
++{0x2510, 0x2442}, // RESERVED_MFR2_2510
++{0x2510, 0x3220}, // RESERVED_MFR2_2510
++{0x2510, 0x2002}, // RESERVED_MFR2_2510
++{0x2510, 0x8947}, // RESERVED_MFR2_2510
++{0x2510, 0x2004}, // RESERVED_MFR2_2510
++{0x2510, 0x8803}, // RESERVED_MFR2_2510
++{0x2510, 0x2441}, // RESERVED_MFR2_2510
++{0x2510, 0x30C2}, // RESERVED_MFR2_2510
++{0x2510, 0xA9A0}, // RESERVED_MFR2_2510
++{0x2510, 0xB094}, // RESERVED_MFR2_2510
++{0x2510, 0x2201}, // RESERVED_MFR2_2510
++{0x2510, 0xA0C4}, // RESERVED_MFR2_2510
++{0x2510, 0x3048}, // RESERVED_MFR2_2510
++{0x2510, 0x2000}, // RESERVED_MFR2_2510
++{0x2510, 0xA004}, // RESERVED_MFR2_2510
++{0x2510, 0x7FFF}, // RESERVED_MFR2_2510
++{0x2510, 0x7FFF}, // RESERVED_MFR2_2510
++{0x2510, 0x7FFF}, // RESERVED_MFR2_2510
++{0x2510, 0xB980}, // RESERVED_MFR2_2510
++{0x2510, 0x3250}, // RESERVED_MFR2_2510
++{0x2510, 0x3108}, // RESERVED_MFR2_2510
++{0x2510, 0xA881}, // RESERVED_MFR2_2510
++{0x2510, 0xA8C1}, // RESERVED_MFR2_2510
++{0x2510, 0x8008}, // RESERVED_MFR2_2510
++{0x2510, 0xD900}, // RESERVED_MFR2_2510
++{0x2510, 0xA105}, // RESERVED_MFR2_2510
++{0x2510, 0x30C1}, // RESERVED_MFR2_2510
++{0x2510, 0x2020}, // RESERVED_MFR2_2510
++{0x2510, 0x3101}, // RESERVED_MFR2_2510
++{0x2510, 0x3041}, // RESERVED_MFR2_2510
++{0x2510, 0x3104}, // RESERVED_MFR2_2510
++{0x2510, 0x3102}, // RESERVED_MFR2_2510
++{0x2510, 0x3041}, // RESERVED_MFR2_2510
++{0x2510, 0xF860}, // RESERVED_MFR2_2510
++{0x2510, 0xB095}, // RESERVED_MFR2_2510
++{0x2510, 0x2001}, // RESERVED_MFR2_2510
++{0x2510, 0xB988}, // RESERVED_MFR2_2510
++{0x2510, 0xB9F8}, // RESERVED_MFR2_2510
++{0x2510, 0xB9FC}, // RESERVED_MFR2_2510
++{0x2510, 0x8803}, // RESERVED_MFR2_2510
++{0x2510, 0x916F}, // RESERVED_MFR2_2510
++{0x2510, 0x2001}, // RESERVED_MFR2_2510
++{0x2510, 0xB9FE}, // RESERVED_MFR2_2510
++{0x2510, 0xF905}, // RESERVED_MFR2_2510
++{0x2510, 0xF907}, // RESERVED_MFR2_2510
++{0x2510, 0x3202}, // RESERVED_MFR2_2510
++{0x2510, 0x880B}, // RESERVED_MFR2_2510
++{0x2510, 0xB397}, // RESERVED_MFR2_2510
++{0x2510, 0xF8E8}, // RESERVED_MFR2_2510
++{0x2510, 0x8088}, // RESERVED_MFR2_2510
++{0x2510, 0x9007}, // RESERVED_MFR2_2510
++{0x2510, 0x916F}, // RESERVED_MFR2_2510
++{0x2510, 0x2204}, // RESERVED_MFR2_2510
++{0x2510, 0xB137}, // RESERVED_MFR2_2510
++{0x2510, 0xB9B8}, // RESERVED_MFR2_2510
++{0x2510, 0xC801}, // RESERVED_MFR2_2510
++{0x2510, 0xE809}, // RESERVED_MFR2_2510
++{0x2510, 0x3241}, // RESERVED_MFR2_2510
++{0x2510, 0xB177}, // RESERVED_MFR2_2510
++{0x2510, 0x888B}, // RESERVED_MFR2_2510
++{0x2510, 0xF8A8}, // RESERVED_MFR2_2510
++{0x2510, 0xF888}, // RESERVED_MFR2_2510
++{0x2510, 0x2203}, // RESERVED_MFR2_2510
++{0x2510, 0xA8C8}, // RESERVED_MFR2_2510
++{0x2510, 0xB07B}, // RESERVED_MFR2_2510
++{0x2510, 0x2000}, // RESERVED_MFR2_2510
++{0x2510, 0x8088}, // RESERVED_MFR2_2510
++{0x2510, 0x8088}, // RESERVED_MFR2_2510
++{0x2510, 0xD800}, // RESERVED_MFR2_2510
++{0x2510, 0x220B}, // RESERVED_MFR2_2510
++{0x2510, 0xB06A}, // RESERVED_MFR2_2510
++{0x2510, 0x888B}, // RESERVED_MFR2_2510
++{0x2510, 0x888B}, // RESERVED_MFR2_2510
++{0x2510, 0x2224}, // RESERVED_MFR2_2510
++{0x2510, 0xB04A}, // RESERVED_MFR2_2510
++{0x2510, 0x2218}, // RESERVED_MFR2_2510
++{0x2510, 0xB04B}, // RESERVED_MFR2_2510
++{0x2510, 0x902F}, // RESERVED_MFR2_2510
++{0x2510, 0xF880}, // RESERVED_MFR2_2510
++{0x2510, 0x2211}, // RESERVED_MFR2_2510
++{0x2510, 0x2205}, // RESERVED_MFR2_2510
++{0x2510, 0x2204}, // RESERVED_MFR2_2510
++{0x2510, 0xB043}, // RESERVED_MFR2_2510
++{0x2510, 0xA8C1}, // RESERVED_MFR2_2510
++{0x2510, 0x31C1}, // RESERVED_MFR2_2510
++{0x2510, 0x2200}, // RESERVED_MFR2_2510
++{0x2510, 0x8048}, // RESERVED_MFR2_2510
++{0x2510, 0x2103}, // RESERVED_MFR2_2510
++{0x2510, 0x916F}, // RESERVED_MFR2_2510
++{0x2510, 0x2106}, // RESERVED_MFR2_2510
++{0x2510, 0x884B}, // RESERVED_MFR2_2510
++{0x2510, 0xA8C1}, // RESERVED_MFR2_2510
++{0x2510, 0x2440}, // RESERVED_MFR2_2510
++{0x2510, 0xF010}, // RESERVED_MFR2_2510
++{0x2510, 0xF804}, // RESERVED_MFR2_2510
++{0x2510, 0x2000}, // RESERVED_MFR2_2510
++{0x2510, 0x8008}, // RESERVED_MFR2_2510
++{0x2510, 0x3002}, // RESERVED_MFR2_2510
++{0x2510, 0xB988}, // RESERVED_MFR2_2510
++{0x2510, 0x2442}, // RESERVED_MFR2_2510
++{0x2510, 0x3210}, // RESERVED_MFR2_2510
++{0x2510, 0x2206}, // RESERVED_MFR2_2510
++{0x2510, 0x2207}, // RESERVED_MFR2_2510
++{0x2510, 0x3202}, // RESERVED_MFR2_2510
++{0x2510, 0xA8C1}, // RESERVED_MFR2_2510
++{0x2510, 0x2013}, // RESERVED_MFR2_2510
++{0x2510, 0x8088}, // RESERVED_MFR2_2510
++{0x2510, 0x200C}, // RESERVED_MFR2_2510
++{0x2510, 0x888B}, // RESERVED_MFR2_2510
++{0x2510, 0x2005}, // RESERVED_MFR2_2510
++{0x2510, 0xA8D0}, // RESERVED_MFR2_2510
++{0x2510, 0xB04B}, // RESERVED_MFR2_2510
++{0x2510, 0xF880}, // RESERVED_MFR2_2510
++{0x2510, 0xB980}, // RESERVED_MFR2_2510
++{0x2510, 0xC800}, // RESERVED_MFR2_2510
++{0x2510, 0x30C2}, // RESERVED_MFR2_2510
++{0x2510, 0xE80C}, // RESERVED_MFR2_2510
++{0x2510, 0x2201}, // RESERVED_MFR2_2510
++{0x2510, 0xB04A}, // RESERVED_MFR2_2510
++{0x2510, 0x2213}, // RESERVED_MFR2_2510
++{0x2510, 0x2225}, // RESERVED_MFR2_2510
++{0x2510, 0x8088}, // RESERVED_MFR2_2510
++{0x2510, 0x2205}, // RESERVED_MFR2_2510
++{0x2510, 0x888B}, // RESERVED_MFR2_2510
++{0x2510, 0x2203}, // RESERVED_MFR2_2510
++{0x2510, 0x3241}, // RESERVED_MFR2_2510
++{0x2510, 0x902F}, // RESERVED_MFR2_2510
++{0x2510, 0x2215}, // RESERVED_MFR2_2510
++{0x2510, 0x2205}, // RESERVED_MFR2_2510
++{0x2510, 0x2204}, // RESERVED_MFR2_2510
++{0x2510, 0xB042}, // RESERVED_MFR2_2510
++{0x2510, 0xA9A1}, // RESERVED_MFR2_2510
++{0x2510, 0x8058}, // RESERVED_MFR2_2510
++{0x2510, 0xB093}, // RESERVED_MFR2_2510
++{0x2510, 0x31C1}, // RESERVED_MFR2_2510
++{0x2510, 0x916B}, // RESERVED_MFR2_2510
++{0x2510, 0x2008}, // RESERVED_MFR2_2510
++{0x2510, 0x32C1}, // RESERVED_MFR2_2510
++{0x2510, 0x8803}, // RESERVED_MFR2_2510
++{0x2510, 0xA144}, // RESERVED_MFR2_2510
++{0x2510, 0x3044}, // RESERVED_MFR2_2510
++{0x2510, 0x2000}, // RESERVED_MFR2_2510
++{0x2510, 0xA004}, // RESERVED_MFR2_2510
++{0x2510, 0xB800}, // RESERVED_MFR2_2510
++{0x2510, 0x7FFF}, // RESERVED_MFR2_2510
++{0x2510, 0x7FFF}, // RESERVED_MFR2_2510
++{0x2510, 0x30D0}, // RESERVED_MFR2_2510
++{0x2510, 0xA184}, // RESERVED_MFR2_2510
++{0x2510, 0xB980}, // RESERVED_MFR2_2510
++{0x2510, 0x8107}, // RESERVED_MFR2_2510
++{0x2510, 0xD804}, // RESERVED_MFR2_2510
++{0x2510, 0x3141}, // RESERVED_MFR2_2510
++{0x2510, 0x3042}, // RESERVED_MFR2_2510
++{0x2510, 0x2000}, // RESERVED_MFR2_2510
++{0x2510, 0x3142}, // RESERVED_MFR2_2510
++{0x2510, 0x3042}, // RESERVED_MFR2_2510
++{0x2510, 0x2000}, // RESERVED_MFR2_2510
++{0x2510, 0x3281}, // RESERVED_MFR2_2510
++{0x2510, 0x3042}, // RESERVED_MFR2_2510
++{0x2510, 0x2000}, // RESERVED_MFR2_2510
++{0x2510, 0x3290}, // RESERVED_MFR2_2510
++{0x2510, 0x3042}, // RESERVED_MFR2_2510
++{0x2510, 0x2000}, // RESERVED_MFR2_2510
++{0x2510, 0x3110}, // RESERVED_MFR2_2510
++{0x2510, 0x3042}, // RESERVED_MFR2_2510
++{0x2510, 0x2000}, // RESERVED_MFR2_2510
++{0x2510, 0x3120}, // RESERVED_MFR2_2510
++{0x2510, 0x3042}, // RESERVED_MFR2_2510
++{0x2510, 0x2000}, // RESERVED_MFR2_2510
++{0x2510, 0x3282}, // RESERVED_MFR2_2510
++{0x2510, 0x3042}, // RESERVED_MFR2_2510
++{0x2510, 0x2000}, // RESERVED_MFR2_2510
++{0x2510, 0x32A0}, // RESERVED_MFR2_2510
++{0x2510, 0x3042}, // RESERVED_MFR2_2510
++{0x2510, 0x2000}, // RESERVED_MFR2_2510
++{0x2510, 0x881B}, // RESERVED_MFR2_2510
++{0x2510, 0x895F}, // RESERVED_MFR2_2510
++{0x2510, 0x2440}, // RESERVED_MFR2_2510
++{0x2510, 0xB095}, // RESERVED_MFR2_2510
++{0x2510, 0xF010}, // RESERVED_MFR2_2510
++{0x2510, 0xF864}, // RESERVED_MFR2_2510
++{0x2510, 0xF90D}, // RESERVED_MFR2_2510
++{0x2510, 0x32C2}, // RESERVED_MFR2_2510
++{0x2510, 0x30A0}, // RESERVED_MFR2_2510
++{0x2510, 0x3090}, // RESERVED_MFR2_2510
++{0x2510, 0x3088}, // RESERVED_MFR2_2510
++{0x2510, 0x2443}, // RESERVED_MFR2_2510
++{0x2510, 0x8103}, // RESERVED_MFR2_2510
++{0x2510, 0xD860}, // RESERVED_MFR2_2510
++{0x2510, 0x3001}, // RESERVED_MFR2_2510
++{0x2510, 0x2202}, // RESERVED_MFR2_2510
++{0x2510, 0x2442}, // RESERVED_MFR2_2510
++{0x2510, 0x3220}, // RESERVED_MFR2_2510
++{0x2510, 0x2004}, // RESERVED_MFR2_2510
++{0x2510, 0x885B}, // RESERVED_MFR2_2510
++{0x2510, 0x2441}, // RESERVED_MFR2_2510
++{0x2510, 0x30C2}, // RESERVED_MFR2_2510
++{0x2510, 0x8003}, // RESERVED_MFR2_2510
++{0x2510, 0x2000}, // RESERVED_MFR2_2510
++{0x2510, 0x881B}, // RESERVED_MFR2_2510
++{0x2510, 0x2000}, // RESERVED_MFR2_2510
++{0x2510, 0xD840}, // RESERVED_MFR2_2510
++{0x2510, 0x2006}, // RESERVED_MFR2_2510
++{0x2510, 0xD842}, // RESERVED_MFR2_2510
++{0x2510, 0x200A}, // RESERVED_MFR2_2510
++{0x2510, 0x8000}, // RESERVED_MFR2_2510
++{0x2510, 0xA9A1}, // RESERVED_MFR2_2510
++{0x2510, 0xB094}, // RESERVED_MFR2_2510
++{0x2510, 0x2200}, // RESERVED_MFR2_2510
++{0x2510, 0xD802}, // RESERVED_MFR2_2510
++{0x2510, 0x8803}, // RESERVED_MFR2_2510
++{0x2510, 0xA1C4}, // RESERVED_MFR2_2510
++{0x2510, 0x3048}, // RESERVED_MFR2_2510
++{0x2510, 0xB800}, // RESERVED_MFR2_2510
++{0x2510, 0xA004}, // RESERVED_MFR2_2510
++{0x2510, 0x7FFF}, // RESERVED_MFR2_2510
++{0x2510, 0x7FFF}, // RESERVED_MFR2_2510
++{0x2510, 0x7FFF}, // RESERVED_MFR2_2510
++{0x2510, 0xD802}, // RESERVED_MFR2_2510
++{0x2510, 0x9818}, // RESERVED_MFR2_2510
++{0x2510, 0x3101}, // RESERVED_MFR2_2510
++{0x2510, 0x3041}, // RESERVED_MFR2_2510
++{0x2510, 0x2000}, // RESERVED_MFR2_2510
++{0x2510, 0x3102}, // RESERVED_MFR2_2510
++{0x2510, 0x3041}, // RESERVED_MFR2_2510
++{0x2510, 0x8018}, // RESERVED_MFR2_2510
++{0x2510, 0xD800}, // RESERVED_MFR2_2510
++{0x2510, 0x2002}, // RESERVED_MFR2_2510
++{0x2510, 0x8038}, // RESERVED_MFR2_2510
++{0x2510, 0x2205}, // RESERVED_MFR2_2510
++{0x2510, 0x881B}, // RESERVED_MFR2_2510
++{0x2510, 0x883B}, // RESERVED_MFR2_2510
++{0x2510, 0x213E}, // RESERVED_MFR2_2510
++{0x2510, 0x8018}, // RESERVED_MFR2_2510
++{0x2510, 0x2202}, // RESERVED_MFR2_2510
++{0x2510, 0x8000}, // RESERVED_MFR2_2510
++{0x2510, 0x2201}, // RESERVED_MFR2_2510
++{0x2510, 0x8803}, // RESERVED_MFR2_2510
++{0x2510, 0x9800}, // RESERVED_MFR2_2510
++{0x2510, 0x7FFF}, // RESERVED_MFR2_2510
++{0x2510, 0x7FFF}, // RESERVED_MFR2_2510
++{0x2510, 0x7FFF}, // RESERVED_MFR2_2510
++{0x2510, 0x2440}, // RESERVED_MFR2_2510
++{0x2510, 0xB095}, // RESERVED_MFR2_2510
++{0x2510, 0xF110}, // RESERVED_MFR2_2510
++{0x2510, 0xF864}, // RESERVED_MFR2_2510
++{0x2510, 0xF90D}, // RESERVED_MFR2_2510
++{0x2510, 0x2442}, // RESERVED_MFR2_2510
++{0x2510, 0x3220}, // RESERVED_MFR2_2510
++{0x2510, 0x2007}, // RESERVED_MFR2_2510
++{0x2510, 0x2441}, // RESERVED_MFR2_2510
++{0x2510, 0x30C2}, // RESERVED_MFR2_2510
++{0x2510, 0xA9A0}, // RESERVED_MFR2_2510
++{0x2510, 0xB094}, // RESERVED_MFR2_2510
++{0x2510, 0x7FFF}, // RESERVED_MFR2_2510
++{0x2510, 0x7FFF}, // RESERVED_MFR2_2510
++{0x2510, 0x7FFF}, // RESERVED_MFR2_2510
++{0x2510, 0x7FFF}, // RESERVED_MFR2_2510
++{0x2510, 0xB980}, // RESERVED_MFR2_2510
++{0x2510, 0x3101}, // RESERVED_MFR2_2510
++{0x2510, 0x3041}, // RESERVED_MFR2_2510
++{0x2510, 0x2000}, // RESERVED_MFR2_2510
++{0x2510, 0x3102}, // RESERVED_MFR2_2510
++{0x2510, 0x3041}, // RESERVED_MFR2_2510
++{0x2510, 0x8028}, // RESERVED_MFR2_2510
++{0x2510, 0xD800}, // RESERVED_MFR2_2510
++{0x2510, 0x220A}, // RESERVED_MFR2_2510
++{0x2510, 0x880B}, // RESERVED_MFR2_2510
++{0x2510, 0x882B}, // RESERVED_MFR2_2510
++{0x2510, 0x2440}, // RESERVED_MFR2_2510
++{0x2510, 0xB095}, // RESERVED_MFR2_2510
++{0x2510, 0xF110}, // RESERVED_MFR2_2510
++{0x2510, 0xF864}, // RESERVED_MFR2_2510
++{0x2510, 0xF90D}, // RESERVED_MFR2_2510
++{0x2510, 0x8008}, // RESERVED_MFR2_2510
++{0x2510, 0x3004}, // RESERVED_MFR2_2510
++{0x2510, 0x2202}, // RESERVED_MFR2_2510
++{0x2510, 0x2442}, // RESERVED_MFR2_2510
++{0x2510, 0x882B}, // RESERVED_MFR2_2510
++{0x2510, 0x3220}, // RESERVED_MFR2_2510
++{0x2510, 0x2004}, // RESERVED_MFR2_2510
++{0x2510, 0x880B}, // RESERVED_MFR2_2510
++{0x2510, 0x2441}, // RESERVED_MFR2_2510
++{0x2510, 0x7FFF}, // RESERVED_MFR2_2510
++{0x2510, 0x7FFF}, // RESERVED_MFR2_2510
++{0x2510, 0x7FFF}, // RESERVED_MFR2_2510
++{0x2510, 0x7FFF}, // RESERVED_MFR2_2510
++{0x2510, 0x7FFF}, // RESERVED_MFR2_2510
++{0x2510, 0x7FFF}, // RESERVED_MFR2_2510
++{0x2510, 0x7FFF}, // RESERVED_MFR2_2510
++{0x2510, 0x80A8}, // RESERVED_MFR2_2510
++{0x2510, 0xD800}, // RESERVED_MFR2_2510
++{0x2510, 0x220A}, // RESERVED_MFR2_2510
++{0x2510, 0x88AB}, // RESERVED_MFR2_2510
++{0x2510, 0x2440}, // RESERVED_MFR2_2510
++{0x2510, 0xB043}, // RESERVED_MFR2_2510
++{0x2510, 0x2200}, // RESERVED_MFR2_2510
++{0x2510, 0xF110}, // RESERVED_MFR2_2510
++{0x2510, 0xF804}, // RESERVED_MFR2_2510
++{0x2510, 0xF907}, // RESERVED_MFR2_2510
++{0x2510, 0x8088}, // RESERVED_MFR2_2510
++{0x2510, 0x3001}, // RESERVED_MFR2_2510
++{0x2510, 0x2202}, // RESERVED_MFR2_2510
++{0x2510, 0xA8C8}, // RESERVED_MFR2_2510
++{0x2510, 0xB04B}, // RESERVED_MFR2_2510
++{0x2510, 0x2442}, // RESERVED_MFR2_2510
++{0x2510, 0x88A3}, // RESERVED_MFR2_2510
++{0x2510, 0x3220}, // RESERVED_MFR2_2510
++{0x2510, 0x2004}, // RESERVED_MFR2_2510
++{0x2510, 0x8883}, // RESERVED_MFR2_2510
++{0x2510, 0x2441}, // RESERVED_MFR2_2510
++{0x2510, 0x3202}, // RESERVED_MFR2_2510
++{0x2510, 0xF880}, // RESERVED_MFR2_2510
++{0x2510, 0x30C2}, // RESERVED_MFR2_2510
++{0x2510, 0xE80C}, // RESERVED_MFR2_2510
++{0x2510, 0x2201}, // RESERVED_MFR2_2510
++{0x2510, 0xB04A}, // RESERVED_MFR2_2510
++{0x2510, 0x2227}, // RESERVED_MFR2_2510
++{0x2510, 0x2205}, // RESERVED_MFR2_2510
++{0x2510, 0x3241}, // RESERVED_MFR2_2510
++{0x2510, 0x2207}, // RESERVED_MFR2_2510
++{0x2510, 0x902F}, // RESERVED_MFR2_2510
++{0x2510, 0x220E}, // RESERVED_MFR2_2510
++{0x2510, 0x2205}, // RESERVED_MFR2_2510
++{0x2510, 0x2204}, // RESERVED_MFR2_2510
++{0x2510, 0xB042}, // RESERVED_MFR2_2510
++{0x2510, 0xA9A1}, // RESERVED_MFR2_2510
++{0x2510, 0x8008}, // RESERVED_MFR2_2510
++{0x2510, 0xB093}, // RESERVED_MFR2_2510
++{0x2510, 0x31C1}, // RESERVED_MFR2_2510
++{0x2510, 0x916B}, // RESERVED_MFR2_2510
++{0x2510, 0x2008}, // RESERVED_MFR2_2510
++{0x2510, 0x32C1}, // RESERVED_MFR2_2510
++{0x2510, 0x8803}, // RESERVED_MFR2_2510
++{0x2510, 0xA044}, // RESERVED_MFR2_2510
++{0x2510, 0x3044}, // RESERVED_MFR2_2510
++{0x2510, 0x2000}, // RESERVED_MFR2_2510
++{0x2510, 0xA004}, // RESERVED_MFR2_2510
++{0x2510, 0x7FFF}, // RESERVED_MFR2_2510
++{0x2510, 0x7FFF}, // RESERVED_MFR2_2510
++{0x2510, 0x7FFF}, // RESERVED_MFR2_2510
++{0x2510, 0x7FFF}, // RESERVED_MFR2_2510
++{0x2510, 0x7FFF}, // RESERVED_MFR2_2510
++{0x2510, 0x7FFF}, // RESERVED_MFR2_2510
++{0x2510, 0x7FFF}, // RESERVED_MFR2_2510
++{0x2510, 0x7FFF}, // RESERVED_MFR2_2510
++{0x2510, 0x2400}, // RESERVED_MFR2_2510
++{0x2510, 0x2751}, // RESERVED_MFR2_2510
++{0x2510, 0x2438}, // RESERVED_MFR2_2510
++{0x2510, 0x2750}, // RESERVED_MFR2_2510
++{0x2510, 0x2421}, // RESERVED_MFR2_2510
++{0x2510, 0x7FFF}, // RESERVED_MFR2_2510
++{0x2510, 0x7FFF}, // RESERVED_MFR2_2510
++{0x2510, 0x7FFF}, // RESERVED_MFR2_2510
++{0x2510, 0x2749}, // RESERVED_MFR2_2510
++{0x2510, 0x2422}, // RESERVED_MFR2_2510
++{0x2510, 0x2749}, // RESERVED_MFR2_2510
++{0x2510, 0x2423}, // RESERVED_MFR2_2510
++{0x2510, 0x2709}, // RESERVED_MFR2_2510
++{0x2510, 0x2420}, // RESERVED_MFR2_2510
++{0x2510, 0x2729}, // RESERVED_MFR2_2510
++{0x2510, 0x2423}, // RESERVED_MFR2_2510
++{0x2510, 0x3242}, // RESERVED_MFR2_2510
++{0x2510, 0x2722}, // RESERVED_MFR2_2510
++{0x2510, 0x2422}, // RESERVED_MFR2_2510
++{0x2510, 0x2769}, // RESERVED_MFR2_2510
++{0x2510, 0x2421}, // RESERVED_MFR2_2510
++{0x2510, 0x2702}, // RESERVED_MFR2_2510
++{0x2510, 0x2421}, // RESERVED_MFR2_2510
++{0x2510, 0x3242}, // RESERVED_MFR2_2510
++{0x2510, 0x276A}, // RESERVED_MFR2_2510
++{0x2510, 0x2420}, // RESERVED_MFR2_2510
++{0x2510, 0x276A}, // RESERVED_MFR2_2510
++{0x2510, 0x2421}, // RESERVED_MFR2_2510
++{0x2510, 0x2703}, // RESERVED_MFR2_2510
++{0x2510, 0x2420}, // RESERVED_MFR2_2510
++{0x2510, 0x2703}, // RESERVED_MFR2_2510
++{0x2510, 0x2421}, // RESERVED_MFR2_2510
++{0x2510, 0x3242}, // RESERVED_MFR2_2510
++{0x2510, 0x276B}, // RESERVED_MFR2_2510
++{0x2510, 0x2420}, // RESERVED_MFR2_2510
++{0x2510, 0x276B}, // RESERVED_MFR2_2510
++{0x2510, 0x2421}, // RESERVED_MFR2_2510
++{0x2510, 0x2704}, // RESERVED_MFR2_2510
++{0x2510, 0x2420}, // RESERVED_MFR2_2510
++{0x2510, 0x2704}, // RESERVED_MFR2_2510
++{0x2510, 0x2421}, // RESERVED_MFR2_2510
++{0x2510, 0x3242}, // RESERVED_MFR2_2510
++{0x2510, 0x276C}, // RESERVED_MFR2_2510
++{0x2510, 0x2420}, // RESERVED_MFR2_2510
++{0x2510, 0x276C}, // RESERVED_MFR2_2510
++{0x2510, 0x2421}, // RESERVED_MFR2_2510
++{0x2510, 0x7FFF}, // RESERVED_MFR2_2510
++{0x2510, 0x7FFF}, // RESERVED_MFR2_2510
++{0x2510, 0x2759}, // RESERVED_MFR2_2510
++{0x2510, 0x2422}, // RESERVED_MFR2_2510
++{0x2510, 0x2758}, // RESERVED_MFR2_2510
++{0x2510, 0x2420}, // RESERVED_MFR2_2510
++{0x2510, 0x2403}, // RESERVED_MFR2_2510
++{0x2510, 0x2712}, // RESERVED_MFR2_2510
++{0x2510, 0x3242}, // RESERVED_MFR2_2510
++{0x2510, 0x2422}, // RESERVED_MFR2_2510
++{0x2510, 0x271A}, // RESERVED_MFR2_2510
++{0x2510, 0x3242}, // RESERVED_MFR2_2510
++{0x2510, 0x2420}, // RESERVED_MFR2_2510
++{0x2510, 0x2702}, // RESERVED_MFR2_2510
++{0x2510, 0x2423}, // RESERVED_MFR2_2510
++{0x2510, 0x2703}, // RESERVED_MFR2_2510
++{0x2510, 0x3242}, // RESERVED_MFR2_2510
++{0x2510, 0x2420}, // RESERVED_MFR2_2510
++{0x2510, 0x2703}, // RESERVED_MFR2_2510
++{0x2510, 0x2423}, // RESERVED_MFR2_2510
++{0x2510, 0x2704}, // RESERVED_MFR2_2510
++{0x2510, 0x3242}, // RESERVED_MFR2_2510
++{0x2510, 0x2420}, // RESERVED_MFR2_2510
++{0x2510, 0x2704}, // RESERVED_MFR2_2510
++{0x2510, 0x2423}, // RESERVED_MFR2_2510
++{0x2510, 0x7FFF}, // RESERVED_MFR2_2510
++{0x2510, 0x2400}, // RESERVED_MFR2_2510
++{0x2510, 0x7FFF}, // RESERVED_MFR2_2510
++{0x2510, 0x7FFF}, // RESERVED_MFR2_2510
++{0x2510, 0x7FFF}, // RESERVED_MFR2_2510
++{0x2510, 0x7FFF}, // RESERVED_MFR2_2510
++{0x2510, 0x7FFF}, // RESERVED_MFR2_2510
++{0x2510, 0x7FFF}, // RESERVED_MFR2_2510
++{0x2510, 0x7FFF}, // RESERVED_MFR2_2510
++{0x2510, 0xC023}, // RESERVED_MFR2_2510
++{0x2510, 0x2402}, // RESERVED_MFR2_2510
++{0x2510, 0x2405}, // RESERVED_MFR2_2510
++{0x2510, 0x2789}, // RESERVED_MFR2_2510
++{0x2510, 0x242E}, // RESERVED_MFR2_2510
++{0x2510, 0x2788}, // RESERVED_MFR2_2510
++{0x2510, 0x242F}, // RESERVED_MFR2_2510
++{0x2510, 0x7FFF}, // RESERVED_MFR2_2510
++{0x2510, 0x27D8}, // RESERVED_MFR2_2510
++{0x2510, 0x2433}, // RESERVED_MFR2_2510
++{0x2510, 0x27D9}, // RESERVED_MFR2_2510
++{0x2510, 0x2434}, // RESERVED_MFR2_2510
++{0x2510, 0xC023}, // RESERVED_MFR2_2510
++{0x2510, 0x2402}, // RESERVED_MFR2_2510
++{0x2510, 0xC023}, // RESERVED_MFR2_2510
++{0x2510, 0x2751}, // RESERVED_MFR2_2510
++{0x2510, 0x2438}, // RESERVED_MFR2_2510
++{0x2510, 0xC02B}, // RESERVED_MFR2_2510
++{0x2510, 0x2750}, // RESERVED_MFR2_2510
++{0x2510, 0x2421}, // RESERVED_MFR2_2510
++{0x2510, 0xC003}, // RESERVED_MFR2_2510
++{0x2510, 0x7FFF}, // RESERVED_MFR2_2510
++{0x2510, 0x7FFF}, // RESERVED_MFR2_2510
++{0x2510, 0x7FFF}, // RESERVED_MFR2_2510
++{0x2510, 0x3250}, // RESERVED_MFR2_2510
++{0x2510, 0xC021}, // RESERVED_MFR2_2510
++{0x2510, 0x2400}, // RESERVED_MFR2_2510
++{0x2510, 0x2405}, // RESERVED_MFR2_2510
++{0x2510, 0xC062}, // RESERVED_MFR2_2510
++{0x2510, 0x3250}, // RESERVED_MFR2_2510
++{0x2510, 0x2400}, // RESERVED_MFR2_2510
++{0x2510, 0xC023}, // RESERVED_MFR2_2510
++{0x2510, 0x2751}, // RESERVED_MFR2_2510
++{0x2510, 0x2438}, // RESERVED_MFR2_2510
++{0x2510, 0xC02B}, // RESERVED_MFR2_2510
++{0x2510, 0x2750}, // RESERVED_MFR2_2510
++{0x2510, 0x2421}, // RESERVED_MFR2_2510
++{0x2510, 0xC003}, // RESERVED_MFR2_2510
++{0x2510, 0x7FFF}, // RESERVED_MFR2_2510
++{0x2510, 0x7FFF}, // RESERVED_MFR2_2510
++{0x2510, 0x3250}, // RESERVED_MFR2_2510
++{0x2510, 0xC0E3}, // RESERVED_MFR2_2510
++{0x2510, 0x2400}, // RESERVED_MFR2_2510
++{0x2510, 0x27B1}, // RESERVED_MFR2_2510
++{0x2510, 0x2437}, // RESERVED_MFR2_2510
++{0x2510, 0x3250}, // RESERVED_MFR2_2510
++{0x2510, 0xC02B}, // RESERVED_MFR2_2510
++{0x2510, 0x2422}, // RESERVED_MFR2_2510
++{0x2510, 0xC023}, // RESERVED_MFR2_2510
++{0x2510, 0x2751}, // RESERVED_MFR2_2510
++{0x2510, 0x2438}, // RESERVED_MFR2_2510
++{0x2510, 0xC02B}, // RESERVED_MFR2_2510
++{0x2510, 0x2750}, // RESERVED_MFR2_2510
++{0x2510, 0x2421}, // RESERVED_MFR2_2510
++{0x2510, 0xC003}, // RESERVED_MFR2_2510
++{0x2510, 0x7FFF}, // RESERVED_MFR2_2510
++{0x2510, 0x2779}, // RESERVED_MFR2_2510
++{0x2510, 0x242C}, // RESERVED_MFR2_2510
++{0x2510, 0x2781}, // RESERVED_MFR2_2510
++{0x2510, 0x242D}, // RESERVED_MFR2_2510
++{0x2510, 0x7FFF}, // RESERVED_MFR2_2510
++{0x2510, 0x7FFF}, // RESERVED_MFR2_2510
++{0x2510, 0x7FFF}, // RESERVED_MFR2_2510
++{0x2510, 0x7FFF}, // RESERVED_MFR2_2510
++{0x2510, 0x2791}, // RESERVED_MFR2_2510
++{0x2510, 0x2430}, // RESERVED_MFR2_2510
++{0x2510, 0x2799}, // RESERVED_MFR2_2510
++{0x2510, 0x2428}, // RESERVED_MFR2_2510
++{0x2510, 0x7FFF}, // RESERVED_MFR2_2510
++{0x2510, 0x7FFF}, // RESERVED_MFR2_2510
++{0x2510, 0x7FFF}, // RESERVED_MFR2_2510
++{0x2510, 0x7FFF}, // RESERVED_MFR2_2510
++{0x2510, 0x27A1}, // RESERVED_MFR2_2510
++{0x2510, 0x2430}, // RESERVED_MFR2_2510
++{0x2510, 0x27A9}, // RESERVED_MFR2_2510
++{0x2510, 0x2428}, // RESERVED_MFR2_2510
++{0x2510, 0x7FFF}, // RESERVED_MFR2_2510
++{0x2510, 0x7FFF}, // RESERVED_MFR2_2510
++{0x2510, 0x7FFF}, // RESERVED_MFR2_2510
++{0x2510, 0x7FFF}, // RESERVED_MFR2_2510
++{0x2510, 0xC165}, // RESERVED_MFR2_2510
++{0x2510, 0x2415}, // RESERVED_MFR2_2510
++{0x2510, 0xC026}, // RESERVED_MFR2_2510
++{0x2510, 0x2407}, // RESERVED_MFR2_2510
++{0x2510, 0xC027}, // RESERVED_MFR2_2510
++{0x2510, 0x2406}, // RESERVED_MFR2_2510
++{0x2510, 0x2296}, // RESERVED_MFR2_2510
++{0x2510, 0x2416}, // RESERVED_MFR2_2510
++{0x2510, 0x7FFF}, // RESERVED_MFR2_2510
++{0x2510, 0x7FFF}, // RESERVED_MFR2_2510
++{0x2510, 0x7FFF}, // RESERVED_MFR2_2510
++{0x2510, 0x7FFF}, // RESERVED_MFR2_2510
++{0x2510, 0x7FFF}, // RESERVED_MFR2_2510
++{0x2510, 0x7FFF}, // RESERVED_MFR2_2510
++{0x2510, 0x7FFF}, // RESERVED_MFR2_2510
++{0x2510, 0x7FFF}, // RESERVED_MFR2_2510
++{0x2510, 0xC167}, // RESERVED_MFR2_2510
++{0x2510, 0x2400}, // RESERVED_MFR2_2510
++{0x2510, 0xC067}, // RESERVED_MFR2_2510
++{0x2510, 0x2406}, // RESERVED_MFR2_2510
++{0x2510, 0x2416}, // RESERVED_MFR2_2510
++{0x2510, 0x7FFF}, // RESERVED_MFR2_2510
++{0x2510, 0x7FFF}, // RESERVED_MFR2_2510
++{0x2510, 0x7FFF}, // RESERVED_MFR2_2510
++{0x2510, 0xB800}, // RESERVED_MFR2_2510
++{0x2510, 0x8058}, // RESERVED_MFR2_2510
++{0x2510, 0xD800}, // RESERVED_MFR2_2510
++{0x2510, 0xA005}, // RESERVED_MFR2_2510
++{0x2510, 0x3101}, // RESERVED_MFR2_2510
++{0x2510, 0x3041}, // RESERVED_MFR2_2510
++{0x2510, 0x3104}, // RESERVED_MFR2_2510
++{0x2510, 0xB035}, // RESERVED_MFR2_2510
++{0x2510, 0xB075}, // RESERVED_MFR2_2510
++{0x2510, 0x30C1}, // RESERVED_MFR2_2510
++{0x2510, 0x3102}, // RESERVED_MFR2_2510
++{0x2510, 0x3041}, // RESERVED_MFR2_2510
++{0x2510, 0xB808}, // RESERVED_MFR2_2510
++{0x2510, 0x3202}, // RESERVED_MFR2_2510
++{0x2510, 0xB848}, // RESERVED_MFR2_2510
++{0x2510, 0xB84C}, // RESERVED_MFR2_2510
++{0x2510, 0x2201}, // RESERVED_MFR2_2510
++{0x2510, 0xB377}, // RESERVED_MFR2_2510
++{0x2510, 0x8843}, // RESERVED_MFR2_2510
++{0x2510, 0x916F}, // RESERVED_MFR2_2510
++{0x2510, 0x2201}, // RESERVED_MFR2_2510
++{0x2510, 0xB84E}, // RESERVED_MFR2_2510
++{0x2510, 0xF905}, // RESERVED_MFR2_2510
++{0x2510, 0xF907}, // RESERVED_MFR2_2510
++{0x2510, 0x2200}, // RESERVED_MFR2_2510
++{0x2510, 0x885B}, // RESERVED_MFR2_2510
++{0x2510, 0xA898}, // RESERVED_MFR2_2510
++{0x2510, 0xA8D8}, // RESERVED_MFR2_2510
++{0x2510, 0xF8E8}, // RESERVED_MFR2_2510
++{0x2510, 0x80D8}, // RESERVED_MFR2_2510
++{0x2510, 0x9007}, // RESERVED_MFR2_2510
++{0x2510, 0x916F}, // RESERVED_MFR2_2510
++{0x2510, 0x2206}, // RESERVED_MFR2_2510
++{0x2510, 0xB808}, // RESERVED_MFR2_2510
++{0x2510, 0xC800}, // RESERVED_MFR2_2510
++{0x2510, 0xE809}, // RESERVED_MFR2_2510
++{0x2510, 0x88DB}, // RESERVED_MFR2_2510
++{0x2510, 0xF8A8}, // RESERVED_MFR2_2510
++{0x2510, 0xF888}, // RESERVED_MFR2_2510
++{0x2510, 0x2203}, // RESERVED_MFR2_2510
++{0x2510, 0xB07B}, // RESERVED_MFR2_2510
++{0x2510, 0x2000}, // RESERVED_MFR2_2510
++{0x2510, 0x80C8}, // RESERVED_MFR2_2510
++{0x2510, 0x8088}, // RESERVED_MFR2_2510
++{0x2510, 0x220B}, // RESERVED_MFR2_2510
++{0x2510, 0xB06A}, // RESERVED_MFR2_2510
++{0x2510, 0x88CB}, // RESERVED_MFR2_2510
++{0x2510, 0x888B}, // RESERVED_MFR2_2510
++{0x2510, 0x2224}, // RESERVED_MFR2_2510
++{0x2510, 0xB04A}, // RESERVED_MFR2_2510
++{0x2510, 0x2218}, // RESERVED_MFR2_2510
++{0x2510, 0x210D}, // RESERVED_MFR2_2510
++{0x2510, 0x2108}, // RESERVED_MFR2_2510
++{0x2510, 0x902F}, // RESERVED_MFR2_2510
++{0x2510, 0xB04B}, // RESERVED_MFR2_2510
++{0x2510, 0xF880}, // RESERVED_MFR2_2510
++{0x2510, 0x2211}, // RESERVED_MFR2_2510
++{0x2510, 0x2205}, // RESERVED_MFR2_2510
++{0x2510, 0x2204}, // RESERVED_MFR2_2510
++{0x2510, 0xB043}, // RESERVED_MFR2_2510
++{0x2510, 0xA8C9}, // RESERVED_MFR2_2510
++{0x2510, 0x31C1}, // RESERVED_MFR2_2510
++{0x2510, 0x80A8}, // RESERVED_MFR2_2510
++{0x2510, 0x2205}, // RESERVED_MFR2_2510
++{0x2510, 0x916F}, // RESERVED_MFR2_2510
++{0x2510, 0x2104}, // RESERVED_MFR2_2510
++{0x2510, 0x88AB}, // RESERVED_MFR2_2510
++{0x2510, 0x2440}, // RESERVED_MFR2_2510
++{0x2510, 0xF110}, // RESERVED_MFR2_2510
++{0x2510, 0xF804}, // RESERVED_MFR2_2510
++{0x2510, 0x2000}, // RESERVED_MFR2_2510
++{0x2510, 0x8088}, // RESERVED_MFR2_2510
++{0x2510, 0x3002}, // RESERVED_MFR2_2510
++{0x2510, 0xB838}, // RESERVED_MFR2_2510
++{0x2510, 0xA8C8}, // RESERVED_MFR2_2510
++{0x2510, 0xB04B}, // RESERVED_MFR2_2510
++{0x2510, 0x2442}, // RESERVED_MFR2_2510
++{0x2510, 0x3210}, // RESERVED_MFR2_2510
++{0x2510, 0x2206}, // RESERVED_MFR2_2510
++{0x2510, 0x888B}, // RESERVED_MFR2_2510
++{0x2510, 0x2441}, // RESERVED_MFR2_2510
++{0x2510, 0x3202}, // RESERVED_MFR2_2510
++{0x2510, 0xF880}, // RESERVED_MFR2_2510
++{0x2510, 0xB830}, // RESERVED_MFR2_2510
++{0x2510, 0xC801}, // RESERVED_MFR2_2510
++{0x2510, 0x30C2}, // RESERVED_MFR2_2510
++{0x2510, 0xE80C}, // RESERVED_MFR2_2510
++{0x2510, 0x2201}, // RESERVED_MFR2_2510
++{0x2510, 0xB04A}, // RESERVED_MFR2_2510
++{0x2510, 0x2227}, // RESERVED_MFR2_2510
++{0x2510, 0x2205}, // RESERVED_MFR2_2510
++{0x2510, 0x3241}, // RESERVED_MFR2_2510
++{0x2510, 0x2207}, // RESERVED_MFR2_2510
++{0x2510, 0x902F}, // RESERVED_MFR2_2510
++{0x2510, 0x220E}, // RESERVED_MFR2_2510
++{0x2510, 0x2205}, // RESERVED_MFR2_2510
++{0x2510, 0x2204}, // RESERVED_MFR2_2510
++{0x2510, 0xB042}, // RESERVED_MFR2_2510
++{0x2510, 0xA8C9}, // RESERVED_MFR2_2510
++{0x2510, 0xB043}, // RESERVED_MFR2_2510
++{0x2510, 0x31C1}, // RESERVED_MFR2_2510
++{0x2510, 0x916F}, // RESERVED_MFR2_2510
++{0x2510, 0x2009}, // RESERVED_MFR2_2510
++{0x2510, 0xA004}, // RESERVED_MFR2_2510
++{0x2510, 0x7FFF}, // RESERVED_MFR2_2510
++{0x2510, 0x7FFF}, // RESERVED_MFR2_2510
++{0x2510, 0x7FFF}, // RESERVED_MFR2_2510
++{0x2510, 0x7FFF}, // RESERVED_MFR2_2510
++{0x2510, 0x7FFF}, // RESERVED_MFR2_2510
++{0x2510, 0x7FFF}, // RESERVED_MFR2_2510
++{0x2510, 0x7FFF}, // RESERVED_MFR2_2510
++{0x2510, 0x7FFF}, // RESERVED_MFR2_2510
++{0x2510, 0x30C2}, // RESERVED_MFR2_2510
++{0x2510, 0xA9A0}, // RESERVED_MFR2_2510
++{0x2510, 0xB094}, // RESERVED_MFR2_2510
++{0x2510, 0x2201}, // RESERVED_MFR2_2510
++{0x2510, 0x7FFF}, // RESERVED_MFR2_2510
++{0x2510, 0x7FFF}, // RESERVED_MFR2_2510
++{0x2510, 0x7FFF}, // RESERVED_MFR2_2510
++{0x2510, 0x7FFF}, // RESERVED_MFR2_2510
++{0x2510, 0xB980}, // RESERVED_MFR2_2510
++{0x2510, 0x3101}, // RESERVED_MFR2_2510
++{0x2510, 0x3041}, // RESERVED_MFR2_2510
++{0x2510, 0x2000}, // RESERVED_MFR2_2510
++{0x2510, 0x3102}, // RESERVED_MFR2_2510
++{0x2510, 0x3041}, // RESERVED_MFR2_2510
++{0x2510, 0x8038}, // RESERVED_MFR2_2510
++{0x2510, 0x220A}, // RESERVED_MFR2_2510
++{0x2510, 0x881B}, // RESERVED_MFR2_2510
++{0x2510, 0x883B}, // RESERVED_MFR2_2510
++{0x2510, 0x2440}, // RESERVED_MFR2_2510
++{0x2510, 0xB095}, // RESERVED_MFR2_2510
++{0x2510, 0xF110}, // RESERVED_MFR2_2510
++{0x2510, 0xF864}, // RESERVED_MFR2_2510
++{0x2510, 0xF90D}, // RESERVED_MFR2_2510
++{0x2510, 0x8018}, // RESERVED_MFR2_2510
++{0x2510, 0x3004}, // RESERVED_MFR2_2510
++{0x2510, 0x2202}, // RESERVED_MFR2_2510
++{0x2510, 0x2442}, // RESERVED_MFR2_2510
++{0x2510, 0x883B}, // RESERVED_MFR2_2510
++{0x2510, 0x3220}, // RESERVED_MFR2_2510
++{0x2510, 0x2004}, // RESERVED_MFR2_2510
++{0x2510, 0x881B}, // RESERVED_MFR2_2510
++{0x2510, 0x2441}, // RESERVED_MFR2_2510
++{0x2510, 0x30C2}, // RESERVED_MFR2_2510
++{0x2510, 0xA9A0}, // RESERVED_MFR2_2510
++{0x2510, 0xB094}, // RESERVED_MFR2_2510
++{0x2510, 0x2201}, // RESERVED_MFR2_2510
++{0x2510, 0x7FFF}, // RESERVED_MFR2_2510
++{0x2510, 0x7FFF}, // RESERVED_MFR2_2510
++{0x2510, 0x7FFF}, // RESERVED_MFR2_2510
++{0x2510, 0x7FFF}, // RESERVED_MFR2_2510
++{0x2510, 0x30D0}, // RESERVED_MFR2_2510
++{0x2510, 0xA184}, // RESERVED_MFR2_2510
++{0x2510, 0xB800}, // RESERVED_MFR2_2510
++{0x2510, 0x811F}, // RESERVED_MFR2_2510
++{0x2510, 0xD806}, // RESERVED_MFR2_2510
++{0x2510, 0x9810}, // RESERVED_MFR2_2510
++{0x2510, 0x32C4}, // RESERVED_MFR2_2510
++{0x2510, 0x3041}, // RESERVED_MFR2_2510
++{0x2510, 0x2000}, // RESERVED_MFR2_2510
++{0x2510, 0xD816}, // RESERVED_MFR2_2510
++{0x2510, 0xD814}, // RESERVED_MFR2_2510
++{0x2510, 0x3141}, // RESERVED_MFR2_2510
++{0x2510, 0x3042}, // RESERVED_MFR2_2510
++{0x2510, 0x2000}, // RESERVED_MFR2_2510
++{0x2510, 0x3142}, // RESERVED_MFR2_2510
++{0x2510, 0x3042}, // RESERVED_MFR2_2510
++{0x2510, 0x2000}, // RESERVED_MFR2_2510
++{0x2510, 0x3281}, // RESERVED_MFR2_2510
++{0x2510, 0x3042}, // RESERVED_MFR2_2510
++{0x2510, 0x2000}, // RESERVED_MFR2_2510
++{0x2510, 0x3290}, // RESERVED_MFR2_2510
++{0x2510, 0x3042}, // RESERVED_MFR2_2510
++{0x2510, 0x2000}, // RESERVED_MFR2_2510
++{0x2510, 0x3110}, // RESERVED_MFR2_2510
++{0x2510, 0x3042}, // RESERVED_MFR2_2510
++{0x2510, 0x2000}, // RESERVED_MFR2_2510
++{0x2510, 0x3120}, // RESERVED_MFR2_2510
++{0x2510, 0x3042}, // RESERVED_MFR2_2510
++{0x2510, 0x2000}, // RESERVED_MFR2_2510
++{0x2510, 0x3282}, // RESERVED_MFR2_2510
++{0x2510, 0x3042}, // RESERVED_MFR2_2510
++{0x2510, 0x2000}, // RESERVED_MFR2_2510
++{0x2510, 0x32A0}, // RESERVED_MFR2_2510
++{0x2510, 0x3042}, // RESERVED_MFR2_2510
++{0x2510, 0x2000}, // RESERVED_MFR2_2510
++{0x2510, 0x813F}, // RESERVED_MFR2_2510
++{0x2510, 0x881B}, // RESERVED_MFR2_2510
++{0x2510, 0x897F}, // RESERVED_MFR2_2510
++{0x2510, 0x2440}, // RESERVED_MFR2_2510
++{0x2510, 0xB095}, // RESERVED_MFR2_2510
++{0x2510, 0xF110}, // RESERVED_MFR2_2510
++{0x2510, 0xF864}, // RESERVED_MFR2_2510
++{0x2510, 0xF90D}, // RESERVED_MFR2_2510
++{0x2510, 0x32C2}, // RESERVED_MFR2_2510
++{0x2510, 0x30A0}, // RESERVED_MFR2_2510
++{0x2510, 0x3090}, // RESERVED_MFR2_2510
++{0x2510, 0x3088}, // RESERVED_MFR2_2510
++{0x2510, 0x2443}, // RESERVED_MFR2_2510
++{0x2510, 0x811B}, // RESERVED_MFR2_2510
++{0x2510, 0xD870}, // RESERVED_MFR2_2510
++{0x2510, 0x3001}, // RESERVED_MFR2_2510
++{0x2510, 0x2202}, // RESERVED_MFR2_2510
++{0x2510, 0x2442}, // RESERVED_MFR2_2510
++{0x2510, 0x3220}, // RESERVED_MFR2_2510
++{0x2510, 0x2004}, // RESERVED_MFR2_2510
++{0x2510, 0x885B}, // RESERVED_MFR2_2510
++{0x2510, 0x9800}, // RESERVED_MFR2_2510
++{0x2510, 0x2441}, // RESERVED_MFR2_2510
++{0x2510, 0x30C2}, // RESERVED_MFR2_2510
++{0x2510, 0x801B}, // RESERVED_MFR2_2510
++{0x2510, 0x2000}, // RESERVED_MFR2_2510
++{0x2510, 0x881B}, // RESERVED_MFR2_2510
++{0x2510, 0x2000}, // RESERVED_MFR2_2510
++{0x2510, 0xD850}, // RESERVED_MFR2_2510
++{0x2510, 0x2006}, // RESERVED_MFR2_2510
++{0x2510, 0xD852}, // RESERVED_MFR2_2510
++{0x2510, 0x200A}, // RESERVED_MFR2_2510
++{0x2510, 0x8018}, // RESERVED_MFR2_2510
++{0x2510, 0xA9A0}, // RESERVED_MFR2_2510
++{0x2510, 0xB094}, // RESERVED_MFR2_2510
++{0x2510, 0x2200}, // RESERVED_MFR2_2510
++{0x2510, 0xD812}, // RESERVED_MFR2_2510
++{0x2510, 0x8803}, // RESERVED_MFR2_2510
++{0x2510, 0xA1C4}, // RESERVED_MFR2_2510
++{0x2510, 0x3048}, // RESERVED_MFR2_2510
++{0x2510, 0xB800}, // RESERVED_MFR2_2510
++{0x2510, 0xA004}, // RESERVED_MFR2_2510
++{0x2510, 0xD810}, // RESERVED_MFR2_2510
++{0x2510, 0x7FFF}, // RESERVED_MFR2_2510
++{0x2510, 0x7FFF}, // RESERVED_MFR2_2510
++{0x2510, 0xC166}, // RESERVED_MFR2_2510
++{0x2510, 0x2400}, // RESERVED_MFR2_2510
++{0x2510, 0xC066}, // RESERVED_MFR2_2510
++{0x2510, 0x2406}, // RESERVED_MFR2_2510
++{0x2510, 0x2416}, // RESERVED_MFR2_2510
++{0x2510, 0xC022}, // RESERVED_MFR2_2510
++{0x2510, 0x2402}, // RESERVED_MFR2_2510
++{0x2510, 0x2405}, // RESERVED_MFR2_2510
++{0x2510, 0xC023}, // RESERVED_MFR2_2510
++{0x2510, 0x2400}, // RESERVED_MFR2_2510
++{0x2510, 0x2403}, // RESERVED_MFR2_2510
++{0x2510, 0xC003}, // RESERVED_MFR2_2510
++{0x2510, 0x7FFF}, // RESERVED_MFR2_2510
++{0x2510, 0x7FFF}, // RESERVED_MFR2_2510
++{0x2510, 0x7FFF}, // RESERVED_MFR2_2510
++{0x2510, 0x7FFF}, // RESERVED_MFR2_2510
++{0x2510, 0x7FFF}, // RESERVED_MFR2_2510
++{0x2510, 0x7FFF}, // RESERVED_MFR2_2510
++{0x2510, 0x7FFF}, // RESERVED_MFR2_2510
++{0x2510, 0x7FFF}, // RESERVED_MFR2_2510
++{0x2510, 0x7FFF}, // RESERVED_MFR2_2510
++{0x2510, 0x7FFF}, // RESERVED_MFR2_2510
++{0x2510, 0x7FFF}, // RESERVED_MFR2_2510
++{0x2510, 0x7FFF}, // RESERVED_MFR2_2510
++{0x2510, 0x7FFF}, // RESERVED_MFR2_2510
++{0x2510, 0x7FFF}, // RESERVED_MFR2_2510
++{0x2510, 0x7FFF}, // RESERVED_MFR2_2510
++{0x2510, 0x7FFF}, // RESERVED_MFR2_2510
++{0x2510, 0x7FFF}, // RESERVED_MFR2_2510
++{0x2510, 0x7FFF}, // RESERVED_MFR2_2510
++{0x2510, 0x7FFF}, // RESERVED_MFR2_2510
++{0x2510, 0x7FFF}, // RESERVED_MFR2_2510
++{0x2510, 0x7FFF}, // RESERVED_MFR2_2510
++{0x2510, 0x7FFF}, // RESERVED_MFR2_2510
++{0x2510, 0x7FFF}, // RESERVED_MFR2_2510
++{0x2510, 0x7FFF}, // RESERVED_MFR2_2510
++{0x2510, 0x7FFF}, // RESERVED_MFR2_2510
++{0x2510, 0x7FFF}, // RESERVED_MFR2_2510
++{0x2510, 0x7FFF}, // RESERVED_MFR2_2510
++{0x2510, 0x7FFF}, // RESERVED_MFR2_2510
++{0x2510, 0x7FFF}, // RESERVED_MFR2_2510
++{0x2510, 0x7FFF}, // RESERVED_MFR2_2510
++{0x2510, 0x7FFF}, // RESERVED_MFR2_2510
++{0x2510, 0x7FFF}, // RESERVED_MFR2_2510
++{0x2510, 0x7FFF}, // RESERVED_MFR2_2510
++{0x2510, 0x7FFF}, // RESERVED_MFR2_2510
++{0x2510, 0x7FFF}, // RESERVED_MFR2_2510
++{0x2510, 0x7FFF}, // RESERVED_MFR2_2510
++{0x2510, 0x7FFF}, // RESERVED_MFR2_2510
++{0x2510, 0x7FFF}, // RESERVED_MFR2_2510
++{0x2510, 0x7FFF}, // RESERVED_MFR2_2510
++{0x2510, 0x7FFF}, // RESERVED_MFR2_2510
++{0x2510, 0x7FFF}, // RESERVED_MFR2_2510
++{0x2510, 0x7FFF}, // RESERVED_MFR2_2510
++{0x2510, 0x7FFF}, // RESERVED_MFR2_2510
++{0x2510, 0x7FFF}, // RESERVED_MFR2_2510
++{0x2510, 0x7FFF}, // RESERVED_MFR2_2510
++{0x2510, 0x7FFF}, // RESERVED_MFR2_2510
++{0x2510, 0x7FFF}, // RESERVED_MFR2_2510
++{0x2510, 0x7FFF}, // RESERVED_MFR2_2510
++{0x2510, 0x7FFF}, // RESERVED_MFR2_2510
++{0x2510, 0x7FFF}, // RESERVED_MFR2_2510
++{0x2510, 0x7FFF}, // RESERVED_MFR2_2510
++{0x2510, 0x7FFF}, // RESERVED_MFR2_2510
++{0x2510, 0x7FFF}, // RESERVED_MFR2_2510
++{0x2510, 0x7FFF}, // RESERVED_MFR2_2510
++{0x2510, 0x7FFF}, // RESERVED_MFR2_2510
++{0x2510, 0x7FFF}, // RESERVED_MFR2_2510
++{0x2510, 0x7FFF}, // RESERVED_MFR2_2510
++{0x2510, 0x7FFF}, // RESERVED_MFR2_2510
++{0x2510, 0x7FFF}, // RESERVED_MFR2_2510
++{0x2510, 0x7FFF}, // RESERVED_MFR2_2510
++{0x2510, 0x7FFF}, // RESERVED_MFR2_2510
++{0x2510, 0x7FFF}, // RESERVED_MFR2_2510
++{0x2510, 0x7FFF}, // RESERVED_MFR2_2510
++{0x2510, 0x7FFF}, // RESERVED_MFR2_2510
++{0x2510, 0x7FFF}, // RESERVED_MFR2_2510
++{0x2510, 0x7FFF}, // RESERVED_MFR2_2510
++{0x2510, 0x7FFF}, // RESERVED_MFR2_2510
++{0x2510, 0x7FFF}, // RESERVED_MFR2_2510
++{0x2510, 0x7FFF}, // RESERVED_MFR2_2510
++{0x2510, 0x7FFF}, // RESERVED_MFR2_2510
++{0x2510, 0x7FFF}, // RESERVED_MFR2_2510
++{0x2510, 0x7FFF}, // RESERVED_MFR2_2510
++{0x2510, 0x7FFF}, // RESERVED_MFR2_2510
++{0x2510, 0x7FFF}, // RESERVED_MFR2_2510
++{0x2510, 0x7FFF}, // RESERVED_MFR2_2510
++{0x2510, 0x7FFF}, // RESERVED_MFR2_2510
++{0x2510, 0x7FFF}, // RESERVED_MFR2_2510
++{0x2510, 0x7FFF}, // RESERVED_MFR2_2510
++{0x2510, 0x7FFF}, // RESERVED_MFR2_2510
++{0x2510, 0x7FFF}, // RESERVED_MFR2_2510
++{0x2510, 0x7FFF}, // RESERVED_MFR2_2510
++{0x2510, 0x7FFF}, // RESERVED_MFR2_2510
++{0x2510, 0x7FFF}, // RESERVED_MFR2_2510
++{0x2510, 0x7FFF}, // RESERVED_MFR2_2510
++{0x2510, 0x7FFF}, // RESERVED_MFR2_2510
++{0x2510, 0x7FFF}, // RESERVED_MFR2_2510
++{0x2510, 0x7FFF}, // RESERVED_MFR2_2510
++{0x2510, 0x7FFF}, // RESERVED_MFR2_2510
++{0x2510, 0x7FFF}, // RESERVED_MFR2_2510
++{0x2510, 0x7FFF}, // RESERVED_MFR2_2510
++{0x2510, 0x7FFF}, // RESERVED_MFR2_2510
++{0x2510, 0x7FFF}, // RESERVED_MFR2_2510
++{0x2510, 0x7FFF}, // RESERVED_MFR2_2510
++{0x2510, 0x7FFF}, // RESERVED_MFR2_2510
++{0x2510, 0x7FFF}, // RESERVED_MFR2_2510
++{0x2510, 0x7FFF}, // RESERVED_MFR2_2510
++{0x2510, 0x7FFF}, // RESERVED_MFR2_2510
++{0x2510, 0x7FFF}, // RESERVED_MFR2_2510
++{0x2510, 0x7FFF}, // RESERVED_MFR2_2510
++{0x2510, 0x7FFF}, // RESERVED_MFR2_2510
++{0x2510, 0x7FFF}, // RESERVED_MFR2_2510
++{0x2510, 0x7FFF}, // RESERVED_MFR2_2510
++{0x2510, 0x7FFF}, // RESERVED_MFR2_2510
++{0x2510, 0x7FFF}, // RESERVED_MFR2_2510
++{0x2510, 0x7FFF}, // RESERVED_MFR2_2510
++{0x2510, 0x7FFF}, // RESERVED_MFR2_2510
++{0x2510, 0x7FFF}, // RESERVED_MFR2_2510
++{0x2510, 0x7FFF}, // RESERVED_MFR2_2510
++{0x2510, 0x7FFF}, // RESERVED_MFR2_2510
++{0x2510, 0x7FFF}, // RESERVED_MFR2_2510
++{0x2510, 0x7FFF}, // RESERVED_MFR2_2510
++{0x2510, 0x7FFF}, // RESERVED_MFR2_2510
++{0x2510, 0x7FFF}, // RESERVED_MFR2_2510
++{0x2510, 0x7FFF}, // RESERVED_MFR2_2510
++{0x2510, 0x7FFF}, // RESERVED_MFR2_2510
++{0x2510, 0x7FFF}, // RESERVED_MFR2_2510
++{0x2510, 0x7FFF}, // RESERVED_MFR2_2510
++{0x2510, 0x7FFF}, // RESERVED_MFR2_2510
++{0x2510, 0x7FFF}, // RESERVED_MFR2_2510
++{0x2510, 0x7FFF}, // RESERVED_MFR2_2510
++{0x2510, 0x7FFF}, // RESERVED_MFR2_2510
++{0x2510, 0x7FFF}, // RESERVED_MFR2_2510
++{0x2510, 0x7FFF}, // RESERVED_MFR2_2510
++{0x2510, 0x7FFF}, // RESERVED_MFR2_2510
++{0x2510, 0x7FFF}, // RESERVED_MFR2_2510
++{0x2510, 0x7FFF}, // RESERVED_MFR2_2510
++{0x2510, 0x7FFF}, // RESERVED_MFR2_2510
++{0x2510, 0x7FFF}, // RESERVED_MFR2_2510
++{0x2510, 0x7FFF}, // RESERVED_MFR2_2510
++{0x2510, 0x7FFF}, // RESERVED_MFR2_2510
++{0x2510, 0x7FFF}, // RESERVED_MFR2_2510
++{0x2510, 0x7FFF}, // RESERVED_MFR2_2510
++{0x2510, 0x7FFF}, // RESERVED_MFR2_2510
++{0x2510, 0x7FFF}, // RESERVED_MFR2_2510
++{0x2510, 0x7FFF}, // RESERVED_MFR2_2510
++{0x2510, 0x7FFF}, // RESERVED_MFR2_2510
++{0x2510, 0x7FFF}, // RESERVED_MFR2_2510
++{0x2510, 0x7FFF}, // RESERVED_MFR2_2510
++{0x2510, 0x7FFF}, // RESERVED_MFR2_2510
++{0x2510, 0x7FFF}, // RESERVED_MFR2_2510
++{0x2510, 0x7FFF}, // RESERVED_MFR2_2510
++{0x2510, 0x7FFF}, // RESERVED_MFR2_2510
++{0x2510, 0x7FFF}, // RESERVED_MFR2_2510
++{0x2510, 0x7FFF}, // RESERVED_MFR2_2510
++{0x2510, 0x7FFF}, // RESERVED_MFR2_2510
++{0x2510, 0x7FFF}, // RESERVED_MFR2_2510
++{0x2510, 0x342A}, // RESERVED_MFR2_2510
++{0x2510, 0x3618}, // RESERVED_MFR2_2510
++{0x301E, 0x80A8}, // DATA_PEDESTAL_
++{0x30FE, 0x00A8}, // RESERVED_MFR_30FE
++{0x37B4, 0x3F58}, // RESERVED_MFR_37B4
++{0x3064, 0x0180}, // SMIA_TEST
++{0x3352, 0x2000}, // MIPI_DT_VC_CONFIG
++{0x3E94, 0x2006}, // RESERVED_MFR_3E94
++{0x3E6E, 0xE200}, // TEMPVSENS1_TMG_CTRL_K0
++{0x3E98, 0x1000}, // TEMPVSENS1_EN_CTRL
++{0x3F92, 0x4C00}, // TEMPVSENS1_TMG_CTRL
++{0x30B8, 0x000B}, // TEMPSENS1_CTRL_REG
+ {0x30B8, 0x0003}, // TEMPSENS1_CTRL_REG
+-{0x3F92, 0x4D00}, // TEMPVSENS1_TMG_CTRL
+-{0x3F96, 0xFFFE}, //003E // TEMPVSENS1_FLAG_CTRL
+-{0x3EE0, 0x0700}, //0000 // TEMPVSENS1_FLAG_CTRL_EXT
+-{0x3E98, 0x4000}, // TEMPVSENS1_EN_CTRL
+-
+-//analog},1x
+-{0x3022, 0x01}, // GROUPED_PARAMETER_HOLD_
+-{0x3D34, 0x0562}, // T2_STR_DEC_TH
+-{0x3D36, 0x0562}, // T2_END_DEC_TH
+-{0x563A, 0x0011}, // OCL_T1_GAIN_
+-{0x3E18, 0x0EEE}, // LFM2_T1_E2_GAIN_CTRL
+-{0x3366, 0x1121}, // ANALOG_GAIN
+-{0x3364, 700}, //2D0 // DCG_TRIM
++{0x3112, 0x71E7}, // RESERVED_MFR_3112
++{0x31D0, 0x0001}, // COMPANDING
++{0x3082, 0x0004}, // OPERATION_MODE_CTRL
++{0x30BA, 0x1101}, // DIGITAL_CTRL
++{0x31AC, 0x180C}, // DATA_FORMAT_BITS
++{0x31AE, 0x0204}, // SERIAL_FORMAT
++{0x34D4, 0x0001}, // DISCRETE_FINE_INTEGRATION
++{0x3C08, 0x0104}, // RESERVED_MFR_3C08
++{0x3C06, 0x0C3C}, // RESERVED_MFR_3C06
++{0x3C06, 0x0C3C}, // RESERVED_MFR_3C06
++{0x3D28, 0xDAC0}, // RESERVED_MFR_3D28
++{0x3D2A, 0xDAC0}, // RESERVED_MFR_3D2A
++{0x3290, 0xE86C}, // RESERVED_MFR_3290
++{0x3292, 0xE86C}, // RESERVED_MFR_3292
++{0x3294, 0xE86C}, // RESERVED_MFR_3294
++{0x3296, 0xE86C}, // RESERVED_MFR_3296
++{0x3298, 0xF618}, // RESERVED_MFR_3298
++{0x329A, 0xF618}, // RESERVED_MFR_329A
++{0x329C, 0xF618}, // RESERVED_MFR_329C
++{0x329E, 0xF618}, // RESERVED_MFR_329E
++{0x31AC, 0x180C}, // DATA_FORMAT_BITS
++{0x31D0, 0x0001}, // COMPANDING
++{0x33DA, 0x0000}, // OC_LUT_CONTROL
++{0x33C0, 0x2000}, // OC_LUT_00
++{0x33C2, 0x4000}, // OC_LUT_01
++{0x33C4, 0x8000}, // OC_LUT_02
++{0x33C6, 0x8200}, // OC_LUT_03
++{0x33C8, 0x8600}, // OC_LUT_04
++{0x33CA, 0x8E00}, // OC_LUT_05
++{0x33CC, 0x9E00}, // OC_LUT_06
++{0x33CE, 0xBE00}, // OC_LUT_07
++{0x33D0, 0xC200}, // OC_LUT_08
++{0x33D2, 0xCA00}, // OC_LUT_09
++{0x33D4, 0xDA00}, // OC_LUT_10
++{0x33D6, 0xFA00}, // OC_LUT_11
++{0x33F4, 0xFA00}, // OC_LUT_12
++{0x33F6, 0xFA00}, // OC_LUT_13
++{0x33F8, 0xFA00}, // OC_LUT_14
++{0x33FA, 0xFA00}, // OC_LUT_15
++{0x300A, 0x047E}, // FRAME_LENGTH_LINES_
++{0x300C, 0x0A6E}, // LINE_LENGTH_PCK_
++{0x3362, 0x0001}, // DC_GAIN
++{0x3044, 0x0400}, // DARK_CONTROL
++{0x3238, 0x8446}, // EXPOSURE_RATIO
++{0x3012, 0x0286}, // COARSE_INTEGRATION_TIME_
++{0x3212, 0x0009}, // COARSE_INTEGRATION_TIME2
++{0x563A, 0x0111}, // RESERVED_MFR_563A
++{0x3366, 0x1131}, // ANALOG_GAIN
+ {0x336A, 0x0080}, // ANALOG_GAIN2
+-{0x3E02, 0x09C4}, // LFM2_T1_E1_A
+-{0x3022, 0x00}, // GROUPED_PARAMETER_HOLD_
+-
+-//updated},pink},reduction},settings
+-{0x3D02, 0x6033}, // MEC_CTRL2
+-{0x3534, 0xA284}, // DAC_LD_52_53
+-{0x3546, 0x3601}, // DAC_LD_70_71
+-{0x3518, 0x4444}, // DAC_LD_24_25
+-
+-{0x3494, 0x0C0C}, // LFM_TX_PATTERN_CTRL
+-{0x34BC, 0x000C}, // LFM_PATTERN_CTRL
+-{0x3E02, 0x09C4}, // LFM2_T1_E1_A
+-
+-//band},mitigation
+-{0x3450, 0x00A4}, // LFM_PHASE0_PERIOD
+-{0x3452, 0x004F}, // LFM_PHASE1_PERIOD
+-{0x3454, 0x004F}, // LFM_PHASE2_PERIOD
+-{0x3456, 0x004F}, // LFM_PHASE3_PERIOD
+-{0x3458, 0x004F}, // LFM_PHASE4_PERIOD
+-{0x345A, 0x004F}, // LFM_PHASE5_PERIOD
+-{0x345C, 0x004F}, // LFM_PHASE6_PERIOD
+-{0x345E, 0x004F}, // LFM_PHASE7_PERIOD
+-{0x3460, 0x004F}, // LFM_PHASE8_PERIOD
+-{0x3462, 0x004F}, // LFM_PHASE9_PERIOD
+-{0x3464, 0x004F}, // LFM_PHASE10_PERIOD
+-{0x3466, 0x004F}, // LFM_PHASE11_PERIOD
+-{0x3468, 0x00A4}, // LFM_PHASE12_PERIOD
+-{0x346A, 0x004F}, // LFM_PHASE13_PERIOD
+-{0x346C, 0x004F}, // LFM_PHASE14_PERIOD
+-{0x346E, 0x004F}, // LFM_PHASE15_PERIOD
+-{0x3470, 0x004F}, // LFM_PHASE16_PERIOD
+-{0x3472, 0x004F}, // LFM_PHASE17_PERIOD
+-{0x3474, 0x004F}, // LFM_PHASE18_PERIOD
+-{0x3476, 0x004F}, // LFM_PHASE19_PERIOD
+-{0x3478, 0x004F}, // LFM_PHASE20_PERIOD
+-{0x347A, 0x004F}, // LFM_PHASE21_PERIOD
+-{0x347C, 0x004F}, // LFM_PHASE22_PERIOD
+-{0x347E, 0x004F}, // LFM_PHASE23_PERIOD
+-{0x3480, 0x004F}, // LFM_PHASE24_PERIOD
+-{0x3482, 0x004F}, // LFM_PHASE25_PERIOD
+-{0x3484, 0x00A4}, // LFM_PHASE26_PERIOD
+-{0x3486, 0x004F}, // LFM_PHASE27_PERIOD
+-{0x3488, 0x00A4}, // LFM_PHASE28_PERIOD
+-{0x348A, 0x004F}, // LFM_PHASE29_PERIOD
+-{0x348C, 0x004F}, // LFM_PHASE30_PERIOD
+-{0x348E, 0x004F}, // LFM_PHASE31_PERIOD
+-{0x3490, 0x004F}, // LFM_PHASE32_PERIOD
+-
+-{0x3496, 0xDF00}, // LFM_CONTROL
+-{0x349A, 0x0001}, // LFM_TX_SHIFT_CLK_CTRL
+-{0x349C, 0x0003}, // LFM_TX_DATA_CLK_CTRL
+-{0x349E, 0x0002}, // LFM_TX_GOTO_LOROW_CLK_CTRL
+-{0x34A0, 0x003E}, // LFM_TX_DATA_CLR_CLK_CTRL
+-{0x34A2, 0x0012}, // LFM_BST_TX_CLK_CTRL
+-{0x34A4, 0x003D}, // LFM_BST_TXLO_CLK_CTRL
+-{0x34A6, 0x004E}, // LFM_BST_TXLOROW_EN_CLK_CTRL
+-{0x34A8, 0x0044}, // LFM_AB_SHIFT_CLK_CTRL
+-{0x34AA, 0x0001}, // LFM_BST_AB_CLK_CTRL
+-{0x34AC, 0x0043}, // LFM_BST_ABLO_CLK_CTRL
+-{0x34AE, 0x004E}, // LFM_BST_ABLOROW_EN_CLK_CTRL
+-{0x34B0, 0x0002}, // LFM_DCG_DATA_CLK_CTRL
+-{0x34B2, 0x003F}, // LFM_DCG_DATA_CLR_CLK_CTRL
+-{0x34B4, 0x004E}, // LFM_BST_DCGLOROW_EN_CLK_CTRL
+-{0x34B6, 0x0012}, // LFM_BST_DCG_CLK_CTRL
+-
+-{0x350E, 0x2189}, // DAC_LD_14_15
+-//pixel recommended settings Feb5
+-{0x352C, 0x8146}, // DAC_LD_44_45
+-{0x3526, 0x9812}, // DAC_LD_38_39
+-{0x3528, 0x99C0}, // DAC_LD_40_41
+-{0x352E, 0x0B71}, // DAC_LD_46_47
+-{0x352A, 0x0170}, // DAC_LD_42_43
+-{0x3530, 0x07F0}, // DAC_LD_48_49
+-{0x3514, 0xEEEE}, // DAC_LD_20_21
+-{0x3578, 0xEEEE}, // DAC_LD_120_121
+-{0x3518, 0x3333}, // DAC_LD_24_25
+-{0x3540, 0x0033}, // DAC_LD_64_65
+-{0x3542, 0x33F0}, // DAC_LD_66_67
+-
+-//CFPN},IMPROVEMENT
+-{0x3568, 0x04BC},
+-{0x356A, 0x81AA},
+-{0x356E, 0x15E6},
+-
+-//E1-E2 Transision Noise Improvement
+-{0x3E10, 0x000A}, // LFM2_T1_E2_OFFSET
+-{0x3430, 0x070C}, // BST_MULTISHOT_CLK_0
+-{0x3432, 0x008C}, // BST_MULTISHOT_CLK_1
+-{0x37B2, 0x1F40}, // DBLC_OUT_CLIP_MAX
+-
+-{0x3550, 0xFF6C}, // DAC_LD_80_81
+-{0x3546, 0x4201}, // DAC_LD_70_71
+-
+-//T2 white balance gains
++{0x3E18, 0x0F68}, // RESERVED_MFR_3E18
++{0x3E02, 0x0B61}, // RESERVED_MFR_3E02
++{0x562A, 0x0361}, // RESERVED_MFR_562A
++{0x3E10, 0x0002}, // RESERVED_MFR_3E10
++{0x3364, 0x072E}, // RESERVED_MFR_3364
++{0x37B0, 0x8080}, // RESERVED_MFR_37B0
++{0x37B0, 0x8080}, // RESERVED_MFR_37B0
++{0x37B6, 0x8080}, // DBLC_OUT_PIX_GAIN_GB_B
++{0x37B6, 0x8080}, // DBLC_OUT_PIX_GAIN_GB_B
++{0x3D28, 0xDAC0}, // RESERVED_MFR_3D28
++{0x3D2A, 0xDAC0}, // RESERVED_MFR_3D2A
++{0x3D34, 0x09C4}, // RESERVED_MFR_3D34
++{0x3D36, 0x0DAC}, // RESERVED_MFR_3D36
++{0x3364, 0x072E}, // RESERVED_MFR_3364
++{0x3E14, 0x003F}, // RESERVED_MFR_3E14
++{0x3568, 0x0228}, // RESERVED_MFR_3568
++{0x3548, 0x2323}, // RESERVED_MFR_3548
++{0x354C, 0x3219}, // RESERVED_MFR_354C
++{0x3040, 0xC005}, // READ_MODE
+ {0x30B0, 0x0880}, // DIGITAL_TEST
+-{0x3300, 0x0030}, // GREEN1_GAIN2_
+-{0x3302, 0x0080}, // BLUE_GAIN2_
+-{0x3304, 0x0070}, // RED_GAIN2_
+-{0x3306, 0x0030}, // GREEN2_GAIN2_
+-{0x3056, 0x002F}, // GREEN1_GAIN
+-{0x3058, 0x0080}, // BLUE_GAIN
+-{0x305A, 0x0072}, // RED_GAIN
+-{0x305C, 0x002F}, // GREEN2_GAIN
+-
++{0x3056, 0x0080}, // GREEN1_GAIN
++{0x3058, 0x016E}, // BLUE_GAIN
++{0x305A, 0x011D}, // RED_GAIN
++{0x305C, 0x0080}, // GREEN2_GAIN
++{0x3300, 0x0080}, // GREEN1_GAIN2_
++{0x3302, 0x0162}, // BLUE_GAIN2_
++{0x3304, 0x0121}, // RED_GAIN2_
++{0x3306, 0x0080}, // GREEN2_GAIN2_
+ {0x301A, 0x005C}, // RESET_REGISTER
++{AR0323_DELAY, 33}, // Wait 33ms
++{0x301A, 0x0058}, // RESET_REGISTER
++{AR0323_DELAY, 33}, // Wait 33ms
++{0x3044, 0x3400}, // DARK_CONTROL
++{0x3112, 0x7FE7}, // RESERVED_MFR_3112
++{0x3352, 0x2000}, // MIPI_DT_VC_CONFIG
++{0x33E0, 0x0F80}, // TEST_ASIL_ROWS
++{0x3E3E, 0x000C}, // RESERVED_MFR_3E3E
++{0x3562, 0x0C48}, // RESERVED_MFR_3562
++{0x33E6, 0x3220}, // RESERVED_MFR_33E6
++{0x33EC, 0xEFDC}, // RESERVED_MFR_33EC
++{0x3558, 0x7F3B}, // RESERVED_MFR_3558
++{0x3554, 0x0101}, // RESERVED_MFR_3554
++{0x357C, 0x3E00}, // RESERVED_MFR_357C
++{0x3358, 0x0000}, // CRC_DTR_CALC_CHECKSUM_LOW
++{0x335C, 0x0000}, // CRC_FR_DTR_CALC_CHECKSUM_HIGH
++{0x3388, 0x0009}, // TPG_CONTROL
++{0x338A, 0x0000}, // TPG_COLOR0_GR1_HI
++{0x338C, 0x000A}, // TPG_COLOR0_GR1_LO
++{0x338E, 0x0000}, // TPG_COLOR0_RED_HI
++{0x3390, 0x000B}, // TPG_COLOR0_RED_LO
++{0x3392, 0x0000}, // TPG_COLOR0_BLU_HI
++{0x3394, 0x000C}, // TPG_COLOR0_BLU_LO
++{0x3396, 0x0000}, // TPG_COLOR0_GR2_HI
++{0x3398, 0x000D}, // TPG_COLOR0_GR2_LO
++{0x339A, 0x0000}, // TPG_COLOR1_GR1_HI
++{0x339C, 0x0010}, // TPG_COLOR1_GR1_LO
++{0x339E, 0x0000}, // TPG_COLOR1_RED_HI
++{0x33A0, 0x0020}, // TPG_COLOR1_RED_LO
++{0x33A2, 0x0000}, // TPG_COLOR1_BLU_HI
++{0x33A4, 0x0030}, // TPG_COLOR1_BLU_LO
++{0x33A6, 0x0000}, // TPG_COLOR1_GR2_HI
++{0x33A8, 0x0040}, // TPG_COLOR1_GR2_LO
++{0x33AA, 0x1001}, // TPG_STDPAT_REGION1
++{0x33AC, 0x1001}, // TPG_STDPAT_REGION2
++{0x33BC, 0x0000}, // TPG_HDR_RATIOS
++{0x3E64, 0x0000}, // TPG_PD0_PD1_RATIOS
++{0x3E6A, 0x0000}, // RESERVED_MFR_3E6A
++{0x3180, 0x0000}, // RESERVED_MFR_3180
++{0x3F70, 0x06BA}, // PROCESS_DTR
++{0x3D08, 0x0000}, // DTR_BOUND_X0
++{0x3D0A, 0x0000}, // DTR_BOUND_X1
++{0x3D0C, 0x0000}, // DTR_BOUND_Y0
++{0x3D0E, 0x0000}, // DTR_BOUND_Y1
++{0x3092, 0x000C}, // RESERVED_MFR_3092
++{0x3F64, 0x2000}, // ASIL_CHECK_ENABLES_02
++{0x3F6C, 0x2000}, // ASIL_PIN_ENABLES_02
++{0x3356, 0xBC39}, // CRC_DTR_WRT_CHECKSUM_LOW
++{0x335E, 0x0500}, // CRC_FR_DTR_WRT_CHECKSUM_HIGH
++{0x31F8, 0x0001}, // MIPI_CONFIG_2
++{0x31FA, 0x1212}, // MIPI_F1_F2_ADT
++{0x31FC, 0x1212}, // MIPI_F3_F4_ADT
++{0x301A, 0x005C}, // RESET_REGISTER
++
++{AR0323_DELAY, 33}, // Wait 33ms
+ };
+--
+2.7.4
+
diff --git a/bsp/meta-rcar/meta-rcar-gen3-adas/recipes-kernel/linux/linux-renesas/0155-AR0143-add-original-ONSEMI-setup.patch b/bsp/meta-rcar/meta-rcar-gen3-adas/recipes-kernel/linux/linux-renesas/0155-AR0143-add-original-ONSEMI-setup.patch
new file mode 100644
index 00000000..cae8f645
--- /dev/null
+++ b/bsp/meta-rcar/meta-rcar-gen3-adas/recipes-kernel/linux/linux-renesas/0155-AR0143-add-original-ONSEMI-setup.patch
@@ -0,0 +1,1552 @@
+From 5edb91334b70ed3df3466830b94f3bbe9f93e48d Mon Sep 17 00:00:00 2001
+From: Vladimir Barinov <vladimir.barinov@cogentembedded.com>
+Date: Tue, 19 Mar 2019 13:42:28 +0300
+Subject: [PATCH 104/122] AR0143: add original ONSEMI setup
+
+This adds ONSEMI rev1 setup
+
+Signed-off-by: Vladimir Barinov <vladimir.barinov@cogentembedded.com>
+---
+ drivers/media/i2c/soc_camera/ar0143.c | 2 +-
+ drivers/media/i2c/soc_camera/ar0143.h | 517 +-------------------------
+ drivers/media/i2c/soc_camera/ar0143_custom.h | 526 +++++++++++++++++++++++++++
+ drivers/media/i2c/soc_camera/ar0143_rev1.h | 456 +++++++++++++++++++++++
+ 4 files changed, 985 insertions(+), 516 deletions(-)
+ create mode 100644 drivers/media/i2c/soc_camera/ar0143_custom.h
+ create mode 100644 drivers/media/i2c/soc_camera/ar0143_rev1.h
+
+diff --git a/drivers/media/i2c/soc_camera/ar0143.c b/drivers/media/i2c/soc_camera/ar0143.c
+index b51dcfc..65dc4fb 100644
+--- a/drivers/media/i2c/soc_camera/ar0143.c
++++ b/drivers/media/i2c/soc_camera/ar0143.c
+@@ -448,7 +448,7 @@ static int ar0143_initialize(struct i2c_client *client)
+ }
+
+ /* Program wizard registers */
+- ar0143_set_regs(client, ar0143_regs_wizard, ARRAY_SIZE(ar0143_regs_wizard));
++ ar0143_set_regs(client, ar0143_regs_wizard_rev1, ARRAY_SIZE(ar0143_regs_wizard_rev1));
+
+ tmp_addr = client->addr;
+ if (priv->max9271_addr) {
+diff --git a/drivers/media/i2c/soc_camera/ar0143.h b/drivers/media/i2c/soc_camera/ar0143.h
+index 774a438..042dd50 100644
+--- a/drivers/media/i2c/soc_camera/ar0143.h
++++ b/drivers/media/i2c/soc_camera/ar0143.h
+@@ -32,518 +32,5 @@ struct ar0143_reg {
+ u16 val;
+ };
+
+-static const struct ar0143_reg ar0143_regs_wizard[] = {
+-{0x301A, 0x0001}, // reset
+-{AR0143_DELAY, 100},
+-{0x301A, 0x10D8}, // Stream off and setup parallel
+-{0x3070, 0x0001},
+-{0x3070, 0x0000}, // 1: Solid color test pattern,
+- // 2: Full color bar test pattern,
+- // 3: Fade to grey color bar test pattern,
+- //256: Walking 1 test pattern (12 bit)
+-#ifdef AR0143_DISPLAY_PATTERN_FIXED
+-{0x3070, 0x0001},
+-#endif
+-{0x3072, 0x0fff}, // R
+-{0x3074, 0x0fff}, // G(GR row)
+-{0x3076, 0x0fff}, // B
+-{0x3078, 0x0fff}, // G(GB row)
+-#ifdef AR0143_DISPLAY_PATTERN_COLOR_BAR
+-{0x3070, 0x0002},
+-#endif
+-{AR0143_DELAY, 250},
+-// start demo init
+-{0x3100, 0x4000}, // DLO_CONTROL0
+-{0x3102, 0x6060}, // RESERVED_MFR_3102
+-{0x3104, 0x6060}, // RESERVED_MFR_3104
+-{0x3106, 0x6060}, // RESERVED_MFR_3106
+-{0x3108, 0x0F9F}, // RESERVED_MFR_3108
+-{0x3280, 0x0FA0}, // T1_BARRIER_C0
+-{0x3282, 0x0FA0}, // T1_BARRIER_C1
+-{0x3284, 0x0FA0}, // T1_BARRIER_C2
+-{0x3286, 0x0FA0}, // T1_BARRIER_C3
+-{0x3288, 0x0FA0}, // T2_BARRIER_C0
+-{0x328A, 0x0FA0}, // T2_BARRIER_C1
+-{0x328C, 0x0FA0}, // T2_BARRIER_C2
+-{0x328E, 0x0FA0}, // T2_BARRIER_C3
+-{0x3290, 0x0FA0}, // T3_BARRIER_C0
+-{0x3292, 0x0FA0}, // T3_BARRIER_C1
+-{0x3294, 0x0FA0}, // T3_BARRIER_C2
+-{0x3296, 0x0FA0}, // T3_BARRIER_C3
+-{0x3298, 0x0FA0}, // T4_BARRIER_C0
+-{0x329A, 0x0FA0}, // T4_BARRIER_C1
+-{0x329C, 0x0FA0}, // T4_BARRIER_C2
+-{0x329E, 0x0FA0}, // T4_BARRIER_C3
+-{0x3110, 0x0011}, // HDR_CONTROL0
+-{0x3112, 0x7FE7}, // RESERVED_MFR_3112
+-{0x3114, 0x0000}, // RESERVED_MFR_3114
+-{0x3116, 0xC000}, // HDR_CONTROL3
+-{0x3120, 0x0BA0}, // HDR_SC_CONTROL0
+-{0x3122, 0x0FA0}, // HDR_SC_CONTROL1
+-{0x3124, 0x00B4}, // HDR_MD_CONTROL0
+-{0x3126, 0x0030}, // HDR_MD_CONTROL1
+-{0x3128, 0x6100}, // RESERVED_MFR_3128
+-{0x3506, 0x3333}, // RESERVED_MFR_3506
+-{0x3508, 0x3333}, // RESERVED_MFR_3508
+-{0x350A, 0x3333}, // RESERVED_MFR_350A
+-{0x350C, 0x035F}, // RESERVED_MFR_350C
+-{0x350E, 0xEF14}, // RESERVED_MFR_350E
+-{0x3086, 0x0600}, // RESERVED_MFR_3086
+-{0x3C00, 0xDD67}, // RESERVED_MFR_3C00
+-{0x3092, 0x1C24}, // RESERVED_MFR_3092
+-{0x3096, 0x147E}, // RESERVED_MFR_3096
+-{0x3750, 0x147E}, // RESERVED_MFR_3750
+-{0x30B0, 0x0800}, // DIGITAL_TEST
+-{0x30FE, 0x0000}, // NOISE_PEDESTAL
+-{0x32D0, 0x3A02}, // RESERVED_MFR_32D0
+-{0x32D6, 0x3C04}, // RESERVED_MFR_32D6
+-{0x3C0C, 0x0516}, // DELAY_BUFFER_LLPCK_RD_WR_OVERLAP
+-{0x3F94, 0x483e}, // TEMPVSENS0_FLAG_CTRL
+-{0x3F96, 0xFFFE}, // TEMPVSENS1_FLAG_CTRL
+-{0x3088, 0x6680}, // LFM_CTRL
+-{0x33E2, 0x0000}, // SAMPLE_CTRL
+-{0x3366, 0x7777}, // ANALOG_GAIN
+-{0x3056, 0x0080}, // GREEN1_GAIN
+-{0x305C, 0x0080}, // GREEN2_GAIN
+-{0x3058, 0x0080}, // BLUE_GAIN
+-{0x305A, 0x0080}, // RED_GAIN
+-{0x306E, 0x9010}, // DATAPATH_SELECT
+-{0x3044, 0x0400}, // DARK_CONTROL
+-{0x30BA, 0x01E2}, // DIGITAL_CTRL
+-{0x32EA, 0x3C0E}, // RESERVED_MFR_32EA
+-{0x3362, 0x0000}, // DC_GAIN
+-{0x3364, 0x005B}, // RESERVED_MFR_3364
+-{0x3370, 0x0131}, // DBLC_CONTROL
+-{0x3372, 0x700F}, // DBLC_FS0_CONTROL
+-{0x3386, 0x0000}, // DBLC_PEDESTAL
+-{0x3C04, 0x0E80}, // RESERVED_MFR_3C04
+-{0x30B4, 0x01C7}, // TEMPSENS0_CTRL_REG
+-{0x30B8, 0x0007}, // TEMPSENS1_CTRL_REG
+-{0x3F90, 0x8D03}, // TEMPVSENS0_TMG_CTRL
+-{0x3F92, 0x0D03}, // TEMPVSENS1_TMG_CTRL
+-{0x3502, 0x0808}, // RESERVED_MFR_3502
+-{0x3566, 0x1D28}, // RESERVED_MFR_3566
+-{0x3518, 0x1FFE}, // RESERVED_MFR_3518
+-{0x3526, 0x0F00}, // RESERVED_MFR_3526
+-{0x3528, 0xDDDD}, // RESERVED_MFR_3528
+-{0x352A, 0x089F}, // RESERVED_MFR_352A
+-{0x352E, 0x0011}, // RESERVED_MFR_352E
+-{0x3530, 0x4400}, // RESERVED_MFR_3530
+-{0x3536, 0xFF07}, // RESERVED_MFR_3536
+-{0x3538, 0xFFFF}, // RESERVED_MFR_3538
+-{0x353A, 0x9000}, // RESERVED_MFR_353A
+-{0x353C, 0x3F00}, // RESERVED_MFR_353C
+-{0x32EC, 0x72A1}, // RESERVED_MFR_32EC
+-{0x3540, 0xC637}, // RESERVED_MFR_3540
+-{0x3542, 0x464B}, // RESERVED_MFR_3542
+-{0x3544, 0x4B50}, // RESERVED_MFR_3544
+-{0x3546, 0x545A}, // RESERVED_MFR_3546
+-{0x3548, 0x5A00}, // RESERVED_MFR_3548
+-{0x354A, 0x007F}, // RESERVED_MFR_354A
+-{0x3556, 0x101F}, // RESERVED_MFR_3556
+-{0x3566, 0x3328}, // RESERVED_MFR_3566
+-{0x337A, 0x0CA3}, // DBLC_SCALE0
+-{0x3372, 0x710F}, // DBLC_FS0_CONTROL
+-{0x3520, 0x4688}, // RESERVED_MFR_3520
+-{0x3522, 0x8840}, // RESERVED_MFR_3522
+-{0x3524, 0x4046}, // RESERVED_MFR_3524
+-{0x352C, 0x4646}, // RESERVED_MFR_352C
+-{0x2512, 0x8000}, // SEQ_CTRL_PORT
+-{0x2510, 0x0903}, // SEQ_DATA_PORT
+-{0x2510, 0x3350}, // SEQ_DATA_PORT
+-{0x2510, 0x2004}, // SEQ_DATA_PORT
+-{0x2510, 0x1420}, // SEQ_DATA_PORT
+-{0x2510, 0x1578}, // SEQ_DATA_PORT
+-{0x2510, 0x087B}, // SEQ_DATA_PORT
+-{0x2510, 0x24FF}, // SEQ_DATA_PORT
+-{0x2510, 0x24FF}, // SEQ_DATA_PORT
+-{0x2510, 0x24EA}, // SEQ_DATA_PORT
+-{0x2510, 0x2410}, // SEQ_DATA_PORT
+-{0x2510, 0x2224}, // SEQ_DATA_PORT
+-{0x2510, 0x1015}, // SEQ_DATA_PORT
+-{0x2510, 0x5813}, // SEQ_DATA_PORT
+-{0x2510, 0x0214}, // SEQ_DATA_PORT
+-{0x2510, 0x0024}, // SEQ_DATA_PORT
+-{0x2510, 0xFF24}, // SEQ_DATA_PORT
+-{0x2510, 0xFF24}, // SEQ_DATA_PORT
+-{0x2510, 0xEA23}, // SEQ_DATA_PORT
+-{0x2510, 0x2464}, // SEQ_DATA_PORT
+-{0x2510, 0x7A24}, // SEQ_DATA_PORT
+-{0x2510, 0x0405}, // SEQ_DATA_PORT
+-{0x2510, 0x2C40}, // SEQ_DATA_PORT
+-{0x2510, 0x0AFF}, // SEQ_DATA_PORT
+-{0x2510, 0x0ACC}, // SEQ_DATA_PORT
+-{0x2510, 0x0A07}, // SEQ_DATA_PORT
+-{0x2510, 0x3851}, // SEQ_DATA_PORT
+-{0x2510, 0x1440}, // SEQ_DATA_PORT
+-{0x2510, 0x0004}, // SEQ_DATA_PORT
+-{0x2510, 0x0801}, // SEQ_DATA_PORT
+-{0x2510, 0x0408}, // SEQ_DATA_PORT
+-{0x2510, 0x1180}, // SEQ_DATA_PORT
+-{0x2510, 0x2652}, // SEQ_DATA_PORT
+-{0x2510, 0x0815}, // SEQ_DATA_PORT
+-{0x2510, 0x1813}, // SEQ_DATA_PORT
+-{0x2510, 0xC810}, // SEQ_DATA_PORT
+-{0x2510, 0x0210}, // SEQ_DATA_PORT
+-{0x2510, 0x1611}, // SEQ_DATA_PORT
+-{0x2510, 0x8111}, // SEQ_DATA_PORT
+-{0x2510, 0x8910}, // SEQ_DATA_PORT
+-{0x2510, 0x5612}, // SEQ_DATA_PORT
+-{0x2510, 0x1009}, // SEQ_DATA_PORT
+-{0x2510, 0x020D}, // SEQ_DATA_PORT
+-{0x2510, 0x0905}, // SEQ_DATA_PORT
+-{0x2510, 0x1588}, // SEQ_DATA_PORT
+-{0x2510, 0x1388}, // SEQ_DATA_PORT
+-{0x2510, 0x0938}, // SEQ_DATA_PORT
+-{0x2510, 0x1199}, // SEQ_DATA_PORT
+-{0x2510, 0x11D9}, // SEQ_DATA_PORT
+-{0x2510, 0x091E}, // SEQ_DATA_PORT
+-{0x2510, 0x1214}, // SEQ_DATA_PORT
+-{0x2510, 0x10D6}, // SEQ_DATA_PORT
+-{0x2510, 0x0901}, // SEQ_DATA_PORT
+-{0x2510, 0x1210}, // SEQ_DATA_PORT
+-{0x2510, 0x1212}, // SEQ_DATA_PORT
+-{0x2510, 0x1210}, // SEQ_DATA_PORT
+-{0x2510, 0x11DD}, // SEQ_DATA_PORT
+-{0x2510, 0x11D9}, // SEQ_DATA_PORT
+-{0x2510, 0x0901}, // SEQ_DATA_PORT
+-{0x2510, 0x1441}, // SEQ_DATA_PORT
+-{0x2510, 0x0904}, // SEQ_DATA_PORT
+-{0x2510, 0x1056}, // SEQ_DATA_PORT
+-{0x2510, 0x0811}, // SEQ_DATA_PORT
+-{0x2510, 0xDB09}, // SEQ_DATA_PORT
+-{0x2510, 0x0311}, // SEQ_DATA_PORT
+-{0x2510, 0xFB11}, // SEQ_DATA_PORT
+-{0x2510, 0xBB12}, // SEQ_DATA_PORT
+-{0x2510, 0x1A12}, // SEQ_DATA_PORT
+-{0x2510, 0x1008}, // SEQ_DATA_PORT
+-{0x2510, 0x1250}, // SEQ_DATA_PORT
+-{0x2510, 0x1076}, // SEQ_DATA_PORT
+-{0x2510, 0x10E6}, // SEQ_DATA_PORT
+-{0x2510, 0x1461}, // SEQ_DATA_PORT
+-{0x2510, 0x0906}, // SEQ_DATA_PORT
+-{0x2510, 0x1240}, // SEQ_DATA_PORT
+-{0x2510, 0x1260}, // SEQ_DATA_PORT
+-{0x2510, 0x091C}, // SEQ_DATA_PORT
+-{0x2510, 0x1460}, // SEQ_DATA_PORT
+-{0x2510, 0x090C}, // SEQ_DATA_PORT
+-{0x2510, 0x0B09}, // SEQ_DATA_PORT
+-{0x2510, 0x0515}, // SEQ_DATA_PORT
+-{0x2510, 0xC813}, // SEQ_DATA_PORT
+-{0x2510, 0xC808}, // SEQ_DATA_PORT
+-{0x2510, 0x1066}, // SEQ_DATA_PORT
+-{0x2510, 0x090B}, // SEQ_DATA_PORT
+-{0x2510, 0x1588}, // SEQ_DATA_PORT
+-{0x2510, 0x1388}, // SEQ_DATA_PORT
+-{0x2510, 0x0913}, // SEQ_DATA_PORT
+-{0x2510, 0x0C14}, // SEQ_DATA_PORT
+-{0x2510, 0x4009}, // SEQ_DATA_PORT
+-{0x2510, 0x0310}, // SEQ_DATA_PORT
+-{0x2510, 0xE611}, // SEQ_DATA_PORT
+-{0x2510, 0xFB12}, // SEQ_DATA_PORT
+-{0x2510, 0x6212}, // SEQ_DATA_PORT
+-{0x2510, 0x6011}, // SEQ_DATA_PORT
+-{0x2510, 0xFF11}, // SEQ_DATA_PORT
+-{0x2510, 0xFB14}, // SEQ_DATA_PORT
+-{0x2510, 0x4109}, // SEQ_DATA_PORT
+-{0x2510, 0x0210}, // SEQ_DATA_PORT
+-{0x2510, 0x6609}, // SEQ_DATA_PORT
+-{0x2510, 0x1211}, // SEQ_DATA_PORT
+-{0x2510, 0xBB12}, // SEQ_DATA_PORT
+-{0x2510, 0x6312}, // SEQ_DATA_PORT
+-{0x2510, 0x6014}, // SEQ_DATA_PORT
+-{0x2510, 0x0015}, // SEQ_DATA_PORT
+-{0x2510, 0x1811}, // SEQ_DATA_PORT
+-{0x2510, 0xB812}, // SEQ_DATA_PORT
+-{0x2510, 0xA012}, // SEQ_DATA_PORT
+-{0x2510, 0x0010}, // SEQ_DATA_PORT
+-{0x2510, 0x2610}, // SEQ_DATA_PORT
+-{0x2510, 0x0013}, // SEQ_DATA_PORT
+-{0x2510, 0x0011}, // SEQ_DATA_PORT
+-{0x2510, 0x8030}, // SEQ_DATA_PORT
+-{0x2510, 0x5342}, // SEQ_DATA_PORT
+-{0x2510, 0x1100}, // SEQ_DATA_PORT
+-{0x2510, 0x1002}, // SEQ_DATA_PORT
+-{0x2510, 0x1016}, // SEQ_DATA_PORT
+-{0x2510, 0x1101}, // SEQ_DATA_PORT
+-{0x2510, 0x1109}, // SEQ_DATA_PORT
+-{0x2510, 0x1056}, // SEQ_DATA_PORT
+-{0x2510, 0x1210}, // SEQ_DATA_PORT
+-{0x2510, 0x0D09}, // SEQ_DATA_PORT
+-{0x2510, 0x0614}, // SEQ_DATA_PORT
+-{0x2510, 0x4009}, // SEQ_DATA_PORT
+-{0x2510, 0x0214}, // SEQ_DATA_PORT
+-{0x2510, 0x6009}, // SEQ_DATA_PORT
+-{0x2510, 0x0615}, // SEQ_DATA_PORT
+-{0x2510, 0x4C13}, // SEQ_DATA_PORT
+-{0x2510, 0x0C09}, // SEQ_DATA_PORT
+-{0x2510, 0x0713}, // SEQ_DATA_PORT
+-{0x2510, 0x4C09}, // SEQ_DATA_PORT
+-{0x2510, 0x0715}, // SEQ_DATA_PORT
+-{0x2510, 0xCC09}, // SEQ_DATA_PORT
+-{0x2510, 0x0211}, // SEQ_DATA_PORT
+-{0x2510, 0x4908}, // SEQ_DATA_PORT
+-{0x2510, 0x1461}, // SEQ_DATA_PORT
+-{0x2510, 0x1460}, // SEQ_DATA_PORT
+-{0x2510, 0x0903}, // SEQ_DATA_PORT
+-{0x2510, 0x1588}, // SEQ_DATA_PORT
+-{0x2510, 0x1308}, // SEQ_DATA_PORT
+-{0x2510, 0x0905}, // SEQ_DATA_PORT
+-{0x2510, 0x1388}, // SEQ_DATA_PORT
+-{0x2510, 0x0913}, // SEQ_DATA_PORT
+-{0x2510, 0x1159}, // SEQ_DATA_PORT
+-{0x2510, 0x090B}, // SEQ_DATA_PORT
+-{0x2510, 0x1214}, // SEQ_DATA_PORT
+-{0x2510, 0x0901}, // SEQ_DATA_PORT
+-{0x2510, 0x1210}, // SEQ_DATA_PORT
+-{0x2510, 0x10D6}, // SEQ_DATA_PORT
+-{0x2510, 0x1212}, // SEQ_DATA_PORT
+-{0x2510, 0x1210}, // SEQ_DATA_PORT
+-{0x2510, 0x115D}, // SEQ_DATA_PORT
+-{0x2510, 0x1159}, // SEQ_DATA_PORT
+-{0x2510, 0x1056}, // SEQ_DATA_PORT
+-{0x2510, 0x0903}, // SEQ_DATA_PORT
+-{0x2510, 0x115B}, // SEQ_DATA_PORT
+-{0x2510, 0x0913}, // SEQ_DATA_PORT
+-{0x2510, 0x111B}, // SEQ_DATA_PORT
+-{0x2510, 0x113B}, // SEQ_DATA_PORT
+-{0x2510, 0x121A}, // SEQ_DATA_PORT
+-{0x2510, 0x1210}, // SEQ_DATA_PORT
+-{0x2510, 0x0901}, // SEQ_DATA_PORT
+-{0x2510, 0x1250}, // SEQ_DATA_PORT
+-{0x2510, 0x10F6}, // SEQ_DATA_PORT
+-{0x2510, 0x10E6}, // SEQ_DATA_PORT
+-{0x2510, 0x0903}, // SEQ_DATA_PORT
+-{0x2510, 0x15AB}, // SEQ_DATA_PORT
+-{0x2510, 0x13AB}, // SEQ_DATA_PORT
+-{0x2510, 0x1240}, // SEQ_DATA_PORT
+-{0x2510, 0x1260}, // SEQ_DATA_PORT
+-{0x2510, 0x0964}, // SEQ_DATA_PORT
+-{0x2510, 0x1588}, // SEQ_DATA_PORT
+-{0x2510, 0x0903}, // SEQ_DATA_PORT
+-{0x2510, 0x0B08}, // SEQ_DATA_PORT
+-{0x2510, 0x0813}, // SEQ_DATA_PORT
+-{0x2510, 0x8809}, // SEQ_DATA_PORT
+-{0x2510, 0x0715}, // SEQ_DATA_PORT
+-{0x2510, 0x8D13}, // SEQ_DATA_PORT
+-{0x2510, 0x8D09}, // SEQ_DATA_PORT
+-{0x2510, 0x0D15}, // SEQ_DATA_PORT
+-{0x2510, 0x8813}, // SEQ_DATA_PORT
+-{0x2510, 0x8809}, // SEQ_DATA_PORT
+-{0x2510, 0x0310}, // SEQ_DATA_PORT
+-{0x2510, 0x6609}, // SEQ_DATA_PORT
+-{0x2510, 0x030C}, // SEQ_DATA_PORT
+-{0x2510, 0x0914}, // SEQ_DATA_PORT
+-{0x2510, 0x10E6}, // SEQ_DATA_PORT
+-{0x2510, 0x1262}, // SEQ_DATA_PORT
+-{0x2510, 0x1260}, // SEQ_DATA_PORT
+-{0x2510, 0x113F}, // SEQ_DATA_PORT
+-{0x2510, 0x113B}, // SEQ_DATA_PORT
+-{0x2510, 0x1066}, // SEQ_DATA_PORT
+-{0x2510, 0x117B}, // SEQ_DATA_PORT
+-{0x2510, 0x0927}, // SEQ_DATA_PORT
+-{0x2510, 0x113B}, // SEQ_DATA_PORT
+-{0x2510, 0x1263}, // SEQ_DATA_PORT
+-{0x2510, 0x1260}, // SEQ_DATA_PORT
+-{0x2510, 0x1400}, // SEQ_DATA_PORT
+-{0x2510, 0x155A}, // SEQ_DATA_PORT
+-{0x2510, 0x1138}, // SEQ_DATA_PORT
+-{0x2510, 0x12A0}, // SEQ_DATA_PORT
+-{0x2510, 0x1200}, // SEQ_DATA_PORT
+-{0x2510, 0x1026}, // SEQ_DATA_PORT
+-{0x2510, 0x1000}, // SEQ_DATA_PORT
+-{0x2510, 0x1342}, // SEQ_DATA_PORT
+-{0x2510, 0x1100}, // SEQ_DATA_PORT
+-{0x2510, 0x437A}, // SEQ_DATA_PORT
+-{0x2510, 0x0605}, // SEQ_DATA_PORT
+-{0x2510, 0x0807}, // SEQ_DATA_PORT
+-{0x2510, 0x4137}, // SEQ_DATA_PORT
+-{0x2510, 0x502C}, // SEQ_DATA_PORT
+-{0x2510, 0x2CFE}, // SEQ_DATA_PORT
+-{0x2510, 0x16FE}, // SEQ_DATA_PORT
+-{0x2510, 0x0C2C}, // SEQ_DATA_PORT
+-{0x1008, 0x0338}, // FINE_INTEGRATION_TIME_MIN
+-{0x100C, 0x051B}, // FINE_INTEGRATION_TIME2_MIN
+-{0x100E, 0x06FE}, // FINE_INTEGRATION_TIME3_MIN
+-{0x1010, 0x0155}, // FINE_INTEGRATION_TIME4_MIN
+-{0x3230, 0x02D6}, // FINE_CORRECTION
+-{0x3232, 0x04B9}, // FINE_CORRECTION2
+-{0x3234, 0x069C}, // FINE_CORRECTION3
+-{0x3236, 0x00F3}, // FINE_CORRECTION4
+-{0x32E6, 0x00DA}, // RESERVED_MFR_32E6
+-{0x350C, 0x035F}, // RESERVED_MFR_350C
+-{0x32D0, 0x3A02}, // RESERVED_MFR_32D0
+-{0x32D2, 0x3508}, // RESERVED_MFR_32D2
+-{0x32D4, 0x3702}, // RESERVED_MFR_32D4
+-{0x32D6, 0x3C04}, // RESERVED_MFR_32D6
+-{0x32DC, 0x370A}, // RESERVED_MFR_32DC
+-{0x302A, 0x0008}, // VT_PIX_CLK_DIV
+-{0x302C, 0x0001}, // VT_SYS_CLK_DIV
+-{0x302E, 0x0002}, // PRE_PLL_CLK_DIV
+-{0x3030, 0x0034}, // PLL_MULTIPLIER
+-{0x3036, 0x0008}, // OP_WORD_CLK_DIV
+-{0x3038, 0x0001}, // OP_SYS_CLK_DIV
+-{0x31DC, 0x0030}, // RESERVED_MFR_31DC
+-{0x30A2, 0x0001}, // X_ODD_INC_
+-{0x30A6, 0x0001}, // Y_ODD_INC_
+-{0x3040, 0x0000}, // READ_MODE
+-{0x3044, 0x0400}, // DARK_CONTROL
+-{0x3180, 0x0080}, // RESERVED_MFR_3180
+-{0x33E4, 0x0080}, // RESERVED_MFR_33E4
+-{0x33E0, 0x0880}, // TEST_ASIL_ROWS
+-#ifdef AR0143_EMBEDDED_LINE
+-{0x3064, 0x1982}, // SMIA_TEST
+-#else
+-{0x3064, 0x1802}, // SMIA_TEST
+-#endif
+-{0x3004, 0x0000}, // X_ADDR_START_
+-{0x3008, 0x053F}, // X_ADDR_END_
+-{0x3002, 0x0000}, // Y_ADDR_START_
+-{0x3006, 0x03C7}, // Y_ADDR_END_
+-{0x3400, 0x0010}, // RESERVED_MFR_3400
+-{0x3402, 0x0A80}, // X_OUTPUT_CONTROL
+-{0x3404, 0x0790}, // Y_OUTPUT_CONTROL
+-{0x3082, 0x0008}, // OPERATION_MODE_CTRL
+-{0x30BA, 0x01E2}, // DIGITAL_CTRL
+-{0x300C, 0x09A0}, // LINE_LENGTH_PCK_
+-{0x300A, 0x041E}, // FRAME_LENGTH_LINES_
+-{0x3042, 0x0000}, // EXTRA_DELAY
+-{0x3238, 0x0333}, // EXPOSURE_RATIO
+-{0x3012, 0x036E}, // COARSE_INTEGRATION_TIME_
+-{0x3014, 0x0A7A}, // FINE_INTEGRATION_TIME_
+-{0x321E, 0x0A7A}, // FINE_INTEGRATION_TIME2
+-{0x3222, 0x0A7A}, // FINE_INTEGRATION_TIME3
+-{0x32EA, 0x3C0E}, // RESERVED_MFR_32EA
+-{0x32EA, 0x3C0E}, // RESERVED_MFR_32EA
+-{0x32EA, 0x3C0E}, // RESERVED_MFR_32EA
+-{0x32EC, 0x72A1}, // RESERVED_MFR_32EC
+-{0x32EC, 0x72A1}, // RESERVED_MFR_32EC
+-{0x32EC, 0x72A1}, // RESERVED_MFR_32EC
+-{0x32EC, 0x72A1}, // RESERVED_MFR_32EC
+-{0x32EC, 0x72A1}, // RESERVED_MFR_32EC
+-{0x32EC, 0x72A1}, // RESERVED_MFR_32EC
+-{0x3C06, 0x083C}, // RESERVED_MFR_3C06
+-{0x3C08, 0x0100}, // RESERVED_MFR_3C08
+-{0x31D0, 0x0001}, // COMPANDING
+-{0x31AC, 0x1410}, // DATA_FORMAT_BITS: 2xRAW8
+-{0x301A, 0x1098}, // RESET_REGISTER
+-{0x301A, 0x1018}, // RESET_REGISTER
+-{0x301A, 0x0018}, // RESET_REGISTER
+-{0x31AE, 0x0204}, // SERIAL_FORMAT
+-{0x3342, 0x122A}, // MIPI_F1_PDT_EDT
+-{0x3346, 0x122A}, // MIPI_F2_PDT_EDT
+-{0x334A, 0x122A}, // MIPI_F3_PDT_EDT
+-{0x334E, 0x122A}, // MIPI_F4_PDT_EDT
+-{0x3344, 0x0011}, // MIPI_F1_VDT_VC
+-{0x3348, 0x0111}, // MIPI_F2_VDT_VC
+-{0x334C, 0x0211}, // MIPI_F3_VDT_VC
+-{0x3350, 0x0311}, // MIPI_F4_VDT_VC
+-{0x31B0, 0x0061}, // FRAME_PREAMBLE
+-{0x31B2, 0x004C}, // LINE_PREAMBLE
+-{0x31B4, 0x51C8}, // RESERVED_MFR_31B4
+-{0x31B6, 0x424B}, // RESERVED_MFR_31B6
+-{0x31B8, 0x40CF}, // RESERVED_MFR_31B8
+-{0x31BA, 0x028B}, // RESERVED_MFR_31BA
+-{0x31BC, 0x0D09}, // RESERVED_MFR_31BC
+-// end demo init
+-// start reg wizard WIDTHxHEIGHT@30fps
+-#define NEW_TBL
+-#ifdef NEW_TBL
+-/* PCLK=27Mhz/0x5 *0x5d /1/0xa - MAXIM serializers */
+-{0x302A, 0x000A}, // VT_PIX_CLK_DIV
+-{0x302C, 0x0001}, // VT_SYS_CLK_DIV
+-{0x302E, 0x0005}, // PRE_PLL_CLK_DIV
+-{0x3030, 0x005d}, // PLL_MULTIPLIER
+-{0x3036, 0x000A}, // OP_WORD_CLK_DIV
+-{0x3038, 0x0001}, // OP_SYS_CLK_DIV
+-#else
+-/* PCLK=27Mhz/0x9 *134 /1/8 - MAXIM serializers */
+-{0x302A, 0x0008}, // VT_PIX_CLK_DIV
+-{0x302C, 0x0001}, // VT_SYS_CLK_DIV
+-{0x302E, 0x0009}, // PRE_PLL_CLK_DIV
+-{0x3030, 134}, // PLL_MULTIPLIER
+-{0x3036, 0x0008}, // OP_WORD_CLK_DIV
+-{0x3038, 0x0001}, // OP_SYS_CLK_DIV
+-#endif
+-{0x31B0, 0x0056}, // FRAME_PREAMBLE
+-{0x31B2, 0x0045}, // LINE_PREAMBLE
+-{0x3004, AR0143_X_START}, // X_ADDR_START_
+-{0x3008, AR0143_X_END}, // X_ADDR_END_
+-{0x3002, AR0143_Y_START}, // Y_ADDR_START_
+-{0x3006, AR0143_Y_END}, // Y_ADDR_END_
+-{0x3402, 0x0000 | AR0143_MAX_WIDTH}, // X_OUTPUT_CONTROL
+-{0x3404, 0x0000 | AR0143_MAX_HEIGHT}, // Y_OUTPUT_CONTROL
+-{0x31B4, 0x2207}, // RESERVED_MFR_31B4
+-{0x31B6, 0x220B}, // RESERVED_MFR_31B6
+-{0x31B8, 0x404B}, // RESERVED_MFR_31B8
+-{0x31BA, 0x020A}, // RESERVED_MFR_31BA
+-{0x31BC, 0x0C08}, // RESERVED_MFR_31BC
+-{0x3040, 0x0000}, // READ_MODE
+-{0x30BA, 0x01E2}, // DIGITAL_CTRL
+-{0x3082, 0x0008}, // OPERATION_MODE_CTRL
+-{0x3044, 0x0400}, // DARK_CONTROL
+-{0x33E0, 0x0880}, // TEST_ASIL_ROWS
+-{0x3180, 0x0080}, // RESERVED_MFR_3180
+-{0x33E4, 0x0080}, // RESERVED_MFR_33E4
+-{0x3032, 0x0000}, // RESERVED_MFR_3032
+-{0x3400, 0x0010}, // RESERVED_MFR_3400
+-{0x31D0, 0x0001}, // COMPANDING
+-//{0x31AC, 0x1410}, // DATA_FORMAT_BITS: 2xRAW8
+-{0x31AC, 0x140C}, // DATA_FORMAT_BITS: RAW12
+-{0x3C08, 0x0100}, // RESERVED_MFR_3C08
+-{0x3C0C, 0x0518}, // DELAY_BUFFER_LLPCK_RD_WR_OVERLAP
+-#ifdef NEW_TBL
+-//{0x300A, 0x0438}, // FRAME_LENGTH_LINES_
+-//{0x300C, 0x060e}, // LINE_LENGTH_PCK_
+-{0x300A, AR0143_SENSOR_HEIGHT + 157}, // FRAME_LENGTH_LINES_
+-{0x300C, AR0143_SENSOR_WIDTH + 144}, // LINE_LENGTH_PCK_
+-#else
+-{0x300A, 0x048A}, // FRAME_LENGTH_LINES_
+-{0x300C, 0x05BA}, // LINE_LENGTH_PCK_
+-#endif
+-{0x3018, 0x0000}, // FINE_INTEGRATION_TIME_CB
+-{0x1008, 0x0338}, // FINE_INTEGRATION_TIME_MIN
+-{0x100C, 0x051B}, // FINE_INTEGRATION_TIME2_MIN
+-{0x100E, 0x06FE}, // FINE_INTEGRATION_TIME3_MIN
+-{0x1010, 0x0155}, // FINE_INTEGRATION_TIME4_MIN
+-#ifdef NEW_TBL
+-{0x3012, 0x0206}, // COARSE_INTEGRATION_TIME_
+-{0x3014, 0x06e8}, // FINE_INTEGRATION_TIME_
+-{0x321E, 0x06E8}, // FINE_INTEGRATION_TIME2
+-{0x3222, 0x06E8}, // FINE_INTEGRATION_TIME3
+-#else
+-{0x3012, 0x0332}, // COARSE_INTEGRATION_TIME_
+-{0x3014, 0x0694}, // FINE_INTEGRATION_TIME_
+-{0x321E, 0x0694}, // FINE_INTEGRATION_TIME2
+-{0x3222, 0x0694}, // FINE_INTEGRATION_TIME3
+-#endif
+-{0x32EC, 0x72A0}, // RESERVED_MFR_32EC
+-{0x31C6, 0x0000}, // HISPI_CONTROL
+-#ifdef NEW_TBL
+-{0x3082, 0x0000}, // OPERATION_MODE_CTRL: 1 exposure
+-{0x3238, 0x0222}, // auto exposure time ratio - Fixed!
+-#else
+-// patch start
+-//{0x30BA, 0x01E2}, // DIGITAL_CTRL: 3 exposures
+-//{0x3082, 0x0008}, // OPERATION_MODE_CTRL: 3 exposures
+-{0x3082, 0x0000}, // OPERATION_MODE_CTRL: 1 exposure
+-//{0x30fe, 0x07ff}, // NOISE PEDESTAL
+-//{0x305e, 0x3333}, // DIGITAL COLOR GLOBAL GAIN
+-{0x3308, 0x200}, // DIGITAL GLOBAL GAIN: max=0x7ff
+-//{0x3060, 0x7777}, // ANALOG COLOR GAIN
+-{0x3366, 0x0666}, // ANALOG_GAIN - Fixed!
+-//{0x3238, 0x8000}, // manual exposure time
+-{0x3238, 0x0222}, // auto exposure time ratio - Fixed!
+-{0x3012, 0x0300}, // T1 exposure - max=0x400
+-//{0x3212, 0x0004}, // T2 exposure - not used in auto
+-//{0x3216, 0x0001}, // T3 exposure - not used in auto
+-#endif
+-// patch eof
+-{0x301A, 0x01d8}, // RESET_REGISTER
+-// enable trigger
+-{0x340A, 0x0070}, // GPIO_CONTROL1: GPIO3 is trigger
+-{0x340C, 0x0080}, // GPIO_CONTROL2: GPIO3 is trigger
+-{0x30CE, 0x0120}, // TRIGGER_MODE
+-//{0x30DC, 0x0120}, // TRIGGER_DELAY
+-// end reg wizard WIDTHxHEIGHT@30fps
+-};
++//#include "ar0143_custom.h"
++#include "ar0143_rev1.h"
+diff --git a/drivers/media/i2c/soc_camera/ar0143_custom.h b/drivers/media/i2c/soc_camera/ar0143_custom.h
+new file mode 100644
+index 0000000..2d4aa1c
+--- /dev/null
++++ b/drivers/media/i2c/soc_camera/ar0143_custom.h
+@@ -0,0 +1,526 @@
++/*
++ * ON Semiconductor AR0143 sensor camera wizard 1344x968@30/BGGR/BT601/RAW12
++ *
++ * Copyright (C) 2018 Cogent Embedded, Inc.
++ *
++ * This program is free software; you can redistribute it and/or modify it
++ * under the terms of the GNU General Public License as published by the
++ * Free Software Foundation; either version 2 of the License, or (at your
++ * option) any later version.
++ */
++
++static const struct ar0143_reg ar0143_regs_wizard_custom[] = {
++{0x301A, 0x0001}, // reset
++{AR0143_DELAY, 100},
++{0x301A, 0x10D8}, // Stream off and setup parallel
++{0x3070, 0x0001},
++{0x3070, 0x0000}, // 1: Solid color test pattern,
++ // 2: Full color bar test pattern,
++ // 3: Fade to grey color bar test pattern,
++ //256: Walking 1 test pattern (12 bit)
++#ifdef AR0143_DISPLAY_PATTERN_FIXED
++{0x3070, 0x0001},
++#endif
++{0x3072, 0x0fff}, // R
++{0x3074, 0x0fff}, // G(GR row)
++{0x3076, 0x0fff}, // B
++{0x3078, 0x0fff}, // G(GB row)
++#ifdef AR0143_DISPLAY_PATTERN_COLOR_BAR
++{0x3070, 0x0002},
++#endif
++{AR0143_DELAY, 250},
++// start demo init
++{0x3100, 0x4000}, // DLO_CONTROL0
++{0x3102, 0x6060}, // RESERVED_MFR_3102
++{0x3104, 0x6060}, // RESERVED_MFR_3104
++{0x3106, 0x6060}, // RESERVED_MFR_3106
++{0x3108, 0x0F9F}, // RESERVED_MFR_3108
++{0x3280, 0x0FA0}, // T1_BARRIER_C0
++{0x3282, 0x0FA0}, // T1_BARRIER_C1
++{0x3284, 0x0FA0}, // T1_BARRIER_C2
++{0x3286, 0x0FA0}, // T1_BARRIER_C3
++{0x3288, 0x0FA0}, // T2_BARRIER_C0
++{0x328A, 0x0FA0}, // T2_BARRIER_C1
++{0x328C, 0x0FA0}, // T2_BARRIER_C2
++{0x328E, 0x0FA0}, // T2_BARRIER_C3
++{0x3290, 0x0FA0}, // T3_BARRIER_C0
++{0x3292, 0x0FA0}, // T3_BARRIER_C1
++{0x3294, 0x0FA0}, // T3_BARRIER_C2
++{0x3296, 0x0FA0}, // T3_BARRIER_C3
++{0x3298, 0x0FA0}, // T4_BARRIER_C0
++{0x329A, 0x0FA0}, // T4_BARRIER_C1
++{0x329C, 0x0FA0}, // T4_BARRIER_C2
++{0x329E, 0x0FA0}, // T4_BARRIER_C3
++{0x3110, 0x0011}, // HDR_CONTROL0
++{0x3112, 0x7FE7}, // RESERVED_MFR_3112
++{0x3114, 0x0000}, // RESERVED_MFR_3114
++{0x3116, 0xC000}, // HDR_CONTROL3
++{0x3120, 0x0BA0}, // HDR_SC_CONTROL0
++{0x3122, 0x0FA0}, // HDR_SC_CONTROL1
++{0x3124, 0x00B4}, // HDR_MD_CONTROL0
++{0x3126, 0x0030}, // HDR_MD_CONTROL1
++{0x3128, 0x6100}, // RESERVED_MFR_3128
++{0x3506, 0x3333}, // RESERVED_MFR_3506
++{0x3508, 0x3333}, // RESERVED_MFR_3508
++{0x350A, 0x3333}, // RESERVED_MFR_350A
++{0x350C, 0x035F}, // RESERVED_MFR_350C
++{0x350E, 0xEF14}, // RESERVED_MFR_350E
++{0x3086, 0x0600}, // RESERVED_MFR_3086
++{0x3C00, 0xDD67}, // RESERVED_MFR_3C00
++{0x3092, 0x1C24}, // RESERVED_MFR_3092
++{0x3096, 0x147E}, // RESERVED_MFR_3096
++{0x3750, 0x147E}, // RESERVED_MFR_3750
++{0x30B0, 0x0800}, // DIGITAL_TEST
++{0x30FE, 0x0000}, // NOISE_PEDESTAL
++{0x32D0, 0x3A02}, // RESERVED_MFR_32D0
++{0x32D6, 0x3C04}, // RESERVED_MFR_32D6
++{0x3C0C, 0x0516}, // DELAY_BUFFER_LLPCK_RD_WR_OVERLAP
++{0x3F94, 0x483e}, // TEMPVSENS0_FLAG_CTRL
++{0x3F96, 0xFFFE}, // TEMPVSENS1_FLAG_CTRL
++{0x3088, 0x6680}, // LFM_CTRL
++{0x33E2, 0x0000}, // SAMPLE_CTRL
++{0x3366, 0x7777}, // ANALOG_GAIN
++{0x3056, 0x0080}, // GREEN1_GAIN
++{0x305C, 0x0080}, // GREEN2_GAIN
++{0x3058, 0x0080}, // BLUE_GAIN
++{0x305A, 0x0080}, // RED_GAIN
++{0x306E, 0x9010}, // DATAPATH_SELECT
++{0x3044, 0x0400}, // DARK_CONTROL
++{0x30BA, 0x01E2}, // DIGITAL_CTRL
++{0x32EA, 0x3C0E}, // RESERVED_MFR_32EA
++{0x3362, 0x0000}, // DC_GAIN
++{0x3364, 0x005B}, // RESERVED_MFR_3364
++{0x3370, 0x0131}, // DBLC_CONTROL
++{0x3372, 0x700F}, // DBLC_FS0_CONTROL
++{0x3386, 0x0000}, // DBLC_PEDESTAL
++{0x3C04, 0x0E80}, // RESERVED_MFR_3C04
++{0x30B4, 0x01C7}, // TEMPSENS0_CTRL_REG
++{0x30B8, 0x0007}, // TEMPSENS1_CTRL_REG
++{0x3F90, 0x8D03}, // TEMPVSENS0_TMG_CTRL
++{0x3F92, 0x0D03}, // TEMPVSENS1_TMG_CTRL
++{0x3502, 0x0808}, // RESERVED_MFR_3502
++{0x3566, 0x1D28}, // RESERVED_MFR_3566
++{0x3518, 0x1FFE}, // RESERVED_MFR_3518
++{0x3526, 0x0F00}, // RESERVED_MFR_3526
++{0x3528, 0xDDDD}, // RESERVED_MFR_3528
++{0x352A, 0x089F}, // RESERVED_MFR_352A
++{0x352E, 0x0011}, // RESERVED_MFR_352E
++{0x3530, 0x4400}, // RESERVED_MFR_3530
++{0x3536, 0xFF07}, // RESERVED_MFR_3536
++{0x3538, 0xFFFF}, // RESERVED_MFR_3538
++{0x353A, 0x9000}, // RESERVED_MFR_353A
++{0x353C, 0x3F00}, // RESERVED_MFR_353C
++{0x32EC, 0x72A1}, // RESERVED_MFR_32EC
++{0x3540, 0xC637}, // RESERVED_MFR_3540
++{0x3542, 0x464B}, // RESERVED_MFR_3542
++{0x3544, 0x4B50}, // RESERVED_MFR_3544
++{0x3546, 0x545A}, // RESERVED_MFR_3546
++{0x3548, 0x5A00}, // RESERVED_MFR_3548
++{0x354A, 0x007F}, // RESERVED_MFR_354A
++{0x3556, 0x101F}, // RESERVED_MFR_3556
++{0x3566, 0x3328}, // RESERVED_MFR_3566
++{0x337A, 0x0CA3}, // DBLC_SCALE0
++{0x3372, 0x710F}, // DBLC_FS0_CONTROL
++{0x3520, 0x4688}, // RESERVED_MFR_3520
++{0x3522, 0x8840}, // RESERVED_MFR_3522
++{0x3524, 0x4046}, // RESERVED_MFR_3524
++{0x352C, 0x4646}, // RESERVED_MFR_352C
++{0x2512, 0x8000}, // SEQ_CTRL_PORT
++{0x2510, 0x0903}, // SEQ_DATA_PORT
++{0x2510, 0x3350}, // SEQ_DATA_PORT
++{0x2510, 0x2004}, // SEQ_DATA_PORT
++{0x2510, 0x1420}, // SEQ_DATA_PORT
++{0x2510, 0x1578}, // SEQ_DATA_PORT
++{0x2510, 0x087B}, // SEQ_DATA_PORT
++{0x2510, 0x24FF}, // SEQ_DATA_PORT
++{0x2510, 0x24FF}, // SEQ_DATA_PORT
++{0x2510, 0x24EA}, // SEQ_DATA_PORT
++{0x2510, 0x2410}, // SEQ_DATA_PORT
++{0x2510, 0x2224}, // SEQ_DATA_PORT
++{0x2510, 0x1015}, // SEQ_DATA_PORT
++{0x2510, 0x5813}, // SEQ_DATA_PORT
++{0x2510, 0x0214}, // SEQ_DATA_PORT
++{0x2510, 0x0024}, // SEQ_DATA_PORT
++{0x2510, 0xFF24}, // SEQ_DATA_PORT
++{0x2510, 0xFF24}, // SEQ_DATA_PORT
++{0x2510, 0xEA23}, // SEQ_DATA_PORT
++{0x2510, 0x2464}, // SEQ_DATA_PORT
++{0x2510, 0x7A24}, // SEQ_DATA_PORT
++{0x2510, 0x0405}, // SEQ_DATA_PORT
++{0x2510, 0x2C40}, // SEQ_DATA_PORT
++{0x2510, 0x0AFF}, // SEQ_DATA_PORT
++{0x2510, 0x0ACC}, // SEQ_DATA_PORT
++{0x2510, 0x0A07}, // SEQ_DATA_PORT
++{0x2510, 0x3851}, // SEQ_DATA_PORT
++{0x2510, 0x1440}, // SEQ_DATA_PORT
++{0x2510, 0x0004}, // SEQ_DATA_PORT
++{0x2510, 0x0801}, // SEQ_DATA_PORT
++{0x2510, 0x0408}, // SEQ_DATA_PORT
++{0x2510, 0x1180}, // SEQ_DATA_PORT
++{0x2510, 0x2652}, // SEQ_DATA_PORT
++{0x2510, 0x0815}, // SEQ_DATA_PORT
++{0x2510, 0x1813}, // SEQ_DATA_PORT
++{0x2510, 0xC810}, // SEQ_DATA_PORT
++{0x2510, 0x0210}, // SEQ_DATA_PORT
++{0x2510, 0x1611}, // SEQ_DATA_PORT
++{0x2510, 0x8111}, // SEQ_DATA_PORT
++{0x2510, 0x8910}, // SEQ_DATA_PORT
++{0x2510, 0x5612}, // SEQ_DATA_PORT
++{0x2510, 0x1009}, // SEQ_DATA_PORT
++{0x2510, 0x020D}, // SEQ_DATA_PORT
++{0x2510, 0x0905}, // SEQ_DATA_PORT
++{0x2510, 0x1588}, // SEQ_DATA_PORT
++{0x2510, 0x1388}, // SEQ_DATA_PORT
++{0x2510, 0x0938}, // SEQ_DATA_PORT
++{0x2510, 0x1199}, // SEQ_DATA_PORT
++{0x2510, 0x11D9}, // SEQ_DATA_PORT
++{0x2510, 0x091E}, // SEQ_DATA_PORT
++{0x2510, 0x1214}, // SEQ_DATA_PORT
++{0x2510, 0x10D6}, // SEQ_DATA_PORT
++{0x2510, 0x0901}, // SEQ_DATA_PORT
++{0x2510, 0x1210}, // SEQ_DATA_PORT
++{0x2510, 0x1212}, // SEQ_DATA_PORT
++{0x2510, 0x1210}, // SEQ_DATA_PORT
++{0x2510, 0x11DD}, // SEQ_DATA_PORT
++{0x2510, 0x11D9}, // SEQ_DATA_PORT
++{0x2510, 0x0901}, // SEQ_DATA_PORT
++{0x2510, 0x1441}, // SEQ_DATA_PORT
++{0x2510, 0x0904}, // SEQ_DATA_PORT
++{0x2510, 0x1056}, // SEQ_DATA_PORT
++{0x2510, 0x0811}, // SEQ_DATA_PORT
++{0x2510, 0xDB09}, // SEQ_DATA_PORT
++{0x2510, 0x0311}, // SEQ_DATA_PORT
++{0x2510, 0xFB11}, // SEQ_DATA_PORT
++{0x2510, 0xBB12}, // SEQ_DATA_PORT
++{0x2510, 0x1A12}, // SEQ_DATA_PORT
++{0x2510, 0x1008}, // SEQ_DATA_PORT
++{0x2510, 0x1250}, // SEQ_DATA_PORT
++{0x2510, 0x1076}, // SEQ_DATA_PORT
++{0x2510, 0x10E6}, // SEQ_DATA_PORT
++{0x2510, 0x1461}, // SEQ_DATA_PORT
++{0x2510, 0x0906}, // SEQ_DATA_PORT
++{0x2510, 0x1240}, // SEQ_DATA_PORT
++{0x2510, 0x1260}, // SEQ_DATA_PORT
++{0x2510, 0x091C}, // SEQ_DATA_PORT
++{0x2510, 0x1460}, // SEQ_DATA_PORT
++{0x2510, 0x090C}, // SEQ_DATA_PORT
++{0x2510, 0x0B09}, // SEQ_DATA_PORT
++{0x2510, 0x0515}, // SEQ_DATA_PORT
++{0x2510, 0xC813}, // SEQ_DATA_PORT
++{0x2510, 0xC808}, // SEQ_DATA_PORT
++{0x2510, 0x1066}, // SEQ_DATA_PORT
++{0x2510, 0x090B}, // SEQ_DATA_PORT
++{0x2510, 0x1588}, // SEQ_DATA_PORT
++{0x2510, 0x1388}, // SEQ_DATA_PORT
++{0x2510, 0x0913}, // SEQ_DATA_PORT
++{0x2510, 0x0C14}, // SEQ_DATA_PORT
++{0x2510, 0x4009}, // SEQ_DATA_PORT
++{0x2510, 0x0310}, // SEQ_DATA_PORT
++{0x2510, 0xE611}, // SEQ_DATA_PORT
++{0x2510, 0xFB12}, // SEQ_DATA_PORT
++{0x2510, 0x6212}, // SEQ_DATA_PORT
++{0x2510, 0x6011}, // SEQ_DATA_PORT
++{0x2510, 0xFF11}, // SEQ_DATA_PORT
++{0x2510, 0xFB14}, // SEQ_DATA_PORT
++{0x2510, 0x4109}, // SEQ_DATA_PORT
++{0x2510, 0x0210}, // SEQ_DATA_PORT
++{0x2510, 0x6609}, // SEQ_DATA_PORT
++{0x2510, 0x1211}, // SEQ_DATA_PORT
++{0x2510, 0xBB12}, // SEQ_DATA_PORT
++{0x2510, 0x6312}, // SEQ_DATA_PORT
++{0x2510, 0x6014}, // SEQ_DATA_PORT
++{0x2510, 0x0015}, // SEQ_DATA_PORT
++{0x2510, 0x1811}, // SEQ_DATA_PORT
++{0x2510, 0xB812}, // SEQ_DATA_PORT
++{0x2510, 0xA012}, // SEQ_DATA_PORT
++{0x2510, 0x0010}, // SEQ_DATA_PORT
++{0x2510, 0x2610}, // SEQ_DATA_PORT
++{0x2510, 0x0013}, // SEQ_DATA_PORT
++{0x2510, 0x0011}, // SEQ_DATA_PORT
++{0x2510, 0x8030}, // SEQ_DATA_PORT
++{0x2510, 0x5342}, // SEQ_DATA_PORT
++{0x2510, 0x1100}, // SEQ_DATA_PORT
++{0x2510, 0x1002}, // SEQ_DATA_PORT
++{0x2510, 0x1016}, // SEQ_DATA_PORT
++{0x2510, 0x1101}, // SEQ_DATA_PORT
++{0x2510, 0x1109}, // SEQ_DATA_PORT
++{0x2510, 0x1056}, // SEQ_DATA_PORT
++{0x2510, 0x1210}, // SEQ_DATA_PORT
++{0x2510, 0x0D09}, // SEQ_DATA_PORT
++{0x2510, 0x0614}, // SEQ_DATA_PORT
++{0x2510, 0x4009}, // SEQ_DATA_PORT
++{0x2510, 0x0214}, // SEQ_DATA_PORT
++{0x2510, 0x6009}, // SEQ_DATA_PORT
++{0x2510, 0x0615}, // SEQ_DATA_PORT
++{0x2510, 0x4C13}, // SEQ_DATA_PORT
++{0x2510, 0x0C09}, // SEQ_DATA_PORT
++{0x2510, 0x0713}, // SEQ_DATA_PORT
++{0x2510, 0x4C09}, // SEQ_DATA_PORT
++{0x2510, 0x0715}, // SEQ_DATA_PORT
++{0x2510, 0xCC09}, // SEQ_DATA_PORT
++{0x2510, 0x0211}, // SEQ_DATA_PORT
++{0x2510, 0x4908}, // SEQ_DATA_PORT
++{0x2510, 0x1461}, // SEQ_DATA_PORT
++{0x2510, 0x1460}, // SEQ_DATA_PORT
++{0x2510, 0x0903}, // SEQ_DATA_PORT
++{0x2510, 0x1588}, // SEQ_DATA_PORT
++{0x2510, 0x1308}, // SEQ_DATA_PORT
++{0x2510, 0x0905}, // SEQ_DATA_PORT
++{0x2510, 0x1388}, // SEQ_DATA_PORT
++{0x2510, 0x0913}, // SEQ_DATA_PORT
++{0x2510, 0x1159}, // SEQ_DATA_PORT
++{0x2510, 0x090B}, // SEQ_DATA_PORT
++{0x2510, 0x1214}, // SEQ_DATA_PORT
++{0x2510, 0x0901}, // SEQ_DATA_PORT
++{0x2510, 0x1210}, // SEQ_DATA_PORT
++{0x2510, 0x10D6}, // SEQ_DATA_PORT
++{0x2510, 0x1212}, // SEQ_DATA_PORT
++{0x2510, 0x1210}, // SEQ_DATA_PORT
++{0x2510, 0x115D}, // SEQ_DATA_PORT
++{0x2510, 0x1159}, // SEQ_DATA_PORT
++{0x2510, 0x1056}, // SEQ_DATA_PORT
++{0x2510, 0x0903}, // SEQ_DATA_PORT
++{0x2510, 0x115B}, // SEQ_DATA_PORT
++{0x2510, 0x0913}, // SEQ_DATA_PORT
++{0x2510, 0x111B}, // SEQ_DATA_PORT
++{0x2510, 0x113B}, // SEQ_DATA_PORT
++{0x2510, 0x121A}, // SEQ_DATA_PORT
++{0x2510, 0x1210}, // SEQ_DATA_PORT
++{0x2510, 0x0901}, // SEQ_DATA_PORT
++{0x2510, 0x1250}, // SEQ_DATA_PORT
++{0x2510, 0x10F6}, // SEQ_DATA_PORT
++{0x2510, 0x10E6}, // SEQ_DATA_PORT
++{0x2510, 0x0903}, // SEQ_DATA_PORT
++{0x2510, 0x15AB}, // SEQ_DATA_PORT
++{0x2510, 0x13AB}, // SEQ_DATA_PORT
++{0x2510, 0x1240}, // SEQ_DATA_PORT
++{0x2510, 0x1260}, // SEQ_DATA_PORT
++{0x2510, 0x0964}, // SEQ_DATA_PORT
++{0x2510, 0x1588}, // SEQ_DATA_PORT
++{0x2510, 0x0903}, // SEQ_DATA_PORT
++{0x2510, 0x0B08}, // SEQ_DATA_PORT
++{0x2510, 0x0813}, // SEQ_DATA_PORT
++{0x2510, 0x8809}, // SEQ_DATA_PORT
++{0x2510, 0x0715}, // SEQ_DATA_PORT
++{0x2510, 0x8D13}, // SEQ_DATA_PORT
++{0x2510, 0x8D09}, // SEQ_DATA_PORT
++{0x2510, 0x0D15}, // SEQ_DATA_PORT
++{0x2510, 0x8813}, // SEQ_DATA_PORT
++{0x2510, 0x8809}, // SEQ_DATA_PORT
++{0x2510, 0x0310}, // SEQ_DATA_PORT
++{0x2510, 0x6609}, // SEQ_DATA_PORT
++{0x2510, 0x030C}, // SEQ_DATA_PORT
++{0x2510, 0x0914}, // SEQ_DATA_PORT
++{0x2510, 0x10E6}, // SEQ_DATA_PORT
++{0x2510, 0x1262}, // SEQ_DATA_PORT
++{0x2510, 0x1260}, // SEQ_DATA_PORT
++{0x2510, 0x113F}, // SEQ_DATA_PORT
++{0x2510, 0x113B}, // SEQ_DATA_PORT
++{0x2510, 0x1066}, // SEQ_DATA_PORT
++{0x2510, 0x117B}, // SEQ_DATA_PORT
++{0x2510, 0x0927}, // SEQ_DATA_PORT
++{0x2510, 0x113B}, // SEQ_DATA_PORT
++{0x2510, 0x1263}, // SEQ_DATA_PORT
++{0x2510, 0x1260}, // SEQ_DATA_PORT
++{0x2510, 0x1400}, // SEQ_DATA_PORT
++{0x2510, 0x155A}, // SEQ_DATA_PORT
++{0x2510, 0x1138}, // SEQ_DATA_PORT
++{0x2510, 0x12A0}, // SEQ_DATA_PORT
++{0x2510, 0x1200}, // SEQ_DATA_PORT
++{0x2510, 0x1026}, // SEQ_DATA_PORT
++{0x2510, 0x1000}, // SEQ_DATA_PORT
++{0x2510, 0x1342}, // SEQ_DATA_PORT
++{0x2510, 0x1100}, // SEQ_DATA_PORT
++{0x2510, 0x437A}, // SEQ_DATA_PORT
++{0x2510, 0x0605}, // SEQ_DATA_PORT
++{0x2510, 0x0807}, // SEQ_DATA_PORT
++{0x2510, 0x4137}, // SEQ_DATA_PORT
++{0x2510, 0x502C}, // SEQ_DATA_PORT
++{0x2510, 0x2CFE}, // SEQ_DATA_PORT
++{0x2510, 0x16FE}, // SEQ_DATA_PORT
++{0x2510, 0x0C2C}, // SEQ_DATA_PORT
++{0x1008, 0x0338}, // FINE_INTEGRATION_TIME_MIN
++{0x100C, 0x051B}, // FINE_INTEGRATION_TIME2_MIN
++{0x100E, 0x06FE}, // FINE_INTEGRATION_TIME3_MIN
++{0x1010, 0x0155}, // FINE_INTEGRATION_TIME4_MIN
++{0x3230, 0x02D6}, // FINE_CORRECTION
++{0x3232, 0x04B9}, // FINE_CORRECTION2
++{0x3234, 0x069C}, // FINE_CORRECTION3
++{0x3236, 0x00F3}, // FINE_CORRECTION4
++{0x32E6, 0x00DA}, // RESERVED_MFR_32E6
++{0x350C, 0x035F}, // RESERVED_MFR_350C
++{0x32D0, 0x3A02}, // RESERVED_MFR_32D0
++{0x32D2, 0x3508}, // RESERVED_MFR_32D2
++{0x32D4, 0x3702}, // RESERVED_MFR_32D4
++{0x32D6, 0x3C04}, // RESERVED_MFR_32D6
++{0x32DC, 0x370A}, // RESERVED_MFR_32DC
++{0x302A, 0x0008}, // VT_PIX_CLK_DIV
++{0x302C, 0x0001}, // VT_SYS_CLK_DIV
++{0x302E, 0x0002}, // PRE_PLL_CLK_DIV
++{0x3030, 0x0034}, // PLL_MULTIPLIER
++{0x3036, 0x0008}, // OP_WORD_CLK_DIV
++{0x3038, 0x0001}, // OP_SYS_CLK_DIV
++{0x31DC, 0x0030}, // RESERVED_MFR_31DC
++{0x30A2, 0x0001}, // X_ODD_INC_
++{0x30A6, 0x0001}, // Y_ODD_INC_
++{0x3040, 0x0000}, // READ_MODE
++{0x3044, 0x0400}, // DARK_CONTROL
++{0x3180, 0x0080}, // RESERVED_MFR_3180
++{0x33E4, 0x0080}, // RESERVED_MFR_33E4
++{0x33E0, 0x0880}, // TEST_ASIL_ROWS
++#ifdef AR0143_EMBEDDED_LINE
++{0x3064, 0x1982}, // SMIA_TEST
++#else
++{0x3064, 0x1802}, // SMIA_TEST
++#endif
++{0x3004, 0x0000}, // X_ADDR_START_
++{0x3008, 0x053F}, // X_ADDR_END_
++{0x3002, 0x0000}, // Y_ADDR_START_
++{0x3006, 0x03C7}, // Y_ADDR_END_
++{0x3400, 0x0010}, // RESERVED_MFR_3400
++{0x3402, 0x0A80}, // X_OUTPUT_CONTROL
++{0x3404, 0x0790}, // Y_OUTPUT_CONTROL
++{0x3082, 0x0008}, // OPERATION_MODE_CTRL
++{0x30BA, 0x01E2}, // DIGITAL_CTRL
++{0x300C, 0x09A0}, // LINE_LENGTH_PCK_
++{0x300A, 0x041E}, // FRAME_LENGTH_LINES_
++{0x3042, 0x0000}, // EXTRA_DELAY
++{0x3238, 0x0333}, // EXPOSURE_RATIO
++{0x3012, 0x036E}, // COARSE_INTEGRATION_TIME_
++{0x3014, 0x0A7A}, // FINE_INTEGRATION_TIME_
++{0x321E, 0x0A7A}, // FINE_INTEGRATION_TIME2
++{0x3222, 0x0A7A}, // FINE_INTEGRATION_TIME3
++{0x32EA, 0x3C0E}, // RESERVED_MFR_32EA
++{0x32EA, 0x3C0E}, // RESERVED_MFR_32EA
++{0x32EA, 0x3C0E}, // RESERVED_MFR_32EA
++{0x32EC, 0x72A1}, // RESERVED_MFR_32EC
++{0x32EC, 0x72A1}, // RESERVED_MFR_32EC
++{0x32EC, 0x72A1}, // RESERVED_MFR_32EC
++{0x32EC, 0x72A1}, // RESERVED_MFR_32EC
++{0x32EC, 0x72A1}, // RESERVED_MFR_32EC
++{0x32EC, 0x72A1}, // RESERVED_MFR_32EC
++{0x3C06, 0x083C}, // RESERVED_MFR_3C06
++{0x3C08, 0x0100}, // RESERVED_MFR_3C08
++{0x31D0, 0x0001}, // COMPANDING
++{0x31AC, 0x1410}, // DATA_FORMAT_BITS: 2xRAW8
++{0x301A, 0x1098}, // RESET_REGISTER
++{0x301A, 0x1018}, // RESET_REGISTER
++{0x301A, 0x0018}, // RESET_REGISTER
++{0x31AE, 0x0204}, // SERIAL_FORMAT
++{0x3342, 0x122A}, // MIPI_F1_PDT_EDT
++{0x3346, 0x122A}, // MIPI_F2_PDT_EDT
++{0x334A, 0x122A}, // MIPI_F3_PDT_EDT
++{0x334E, 0x122A}, // MIPI_F4_PDT_EDT
++{0x3344, 0x0011}, // MIPI_F1_VDT_VC
++{0x3348, 0x0111}, // MIPI_F2_VDT_VC
++{0x334C, 0x0211}, // MIPI_F3_VDT_VC
++{0x3350, 0x0311}, // MIPI_F4_VDT_VC
++{0x31B0, 0x0061}, // FRAME_PREAMBLE
++{0x31B2, 0x004C}, // LINE_PREAMBLE
++{0x31B4, 0x51C8}, // RESERVED_MFR_31B4
++{0x31B6, 0x424B}, // RESERVED_MFR_31B6
++{0x31B8, 0x40CF}, // RESERVED_MFR_31B8
++{0x31BA, 0x028B}, // RESERVED_MFR_31BA
++{0x31BC, 0x0D09}, // RESERVED_MFR_31BC
++// end demo init
++// start reg wizard WIDTHxHEIGHT@30fps
++#define NEW_TBL
++#ifdef NEW_TBL
++/* PCLK=27Mhz/0x5 *0x5d /1/0xa - MAXIM serializers */
++{0x302A, 0x000A}, // VT_PIX_CLK_DIV
++{0x302C, 0x0001}, // VT_SYS_CLK_DIV
++{0x302E, 0x0005}, // PRE_PLL_CLK_DIV
++{0x3030, 0x005d}, // PLL_MULTIPLIER
++{0x3036, 0x000A}, // OP_WORD_CLK_DIV
++{0x3038, 0x0001}, // OP_SYS_CLK_DIV
++#else
++/* PCLK=27Mhz/0x9 *134 /1/8 - MAXIM serializers */
++{0x302A, 0x0008}, // VT_PIX_CLK_DIV
++{0x302C, 0x0001}, // VT_SYS_CLK_DIV
++{0x302E, 0x0009}, // PRE_PLL_CLK_DIV
++{0x3030, 134}, // PLL_MULTIPLIER
++{0x3036, 0x0008}, // OP_WORD_CLK_DIV
++{0x3038, 0x0001}, // OP_SYS_CLK_DIV
++#endif
++{0x31B0, 0x0056}, // FRAME_PREAMBLE
++{0x31B2, 0x0045}, // LINE_PREAMBLE
++{0x3004, AR0143_X_START}, // X_ADDR_START_
++{0x3008, AR0143_X_END}, // X_ADDR_END_
++{0x3002, AR0143_Y_START}, // Y_ADDR_START_
++{0x3006, AR0143_Y_END}, // Y_ADDR_END_
++{0x3402, 0x0000 | AR0143_MAX_WIDTH}, // X_OUTPUT_CONTROL
++{0x3404, 0x0000 | AR0143_MAX_HEIGHT}, // Y_OUTPUT_CONTROL
++{0x31B4, 0x2207}, // RESERVED_MFR_31B4
++{0x31B6, 0x220B}, // RESERVED_MFR_31B6
++{0x31B8, 0x404B}, // RESERVED_MFR_31B8
++{0x31BA, 0x020A}, // RESERVED_MFR_31BA
++{0x31BC, 0x0C08}, // RESERVED_MFR_31BC
++{0x3040, 0x0000}, // READ_MODE
++{0x30BA, 0x01E2}, // DIGITAL_CTRL
++{0x3082, 0x0008}, // OPERATION_MODE_CTRL
++{0x3044, 0x0400}, // DARK_CONTROL
++{0x33E0, 0x0880}, // TEST_ASIL_ROWS
++{0x3180, 0x0080}, // RESERVED_MFR_3180
++{0x33E4, 0x0080}, // RESERVED_MFR_33E4
++{0x3032, 0x0000}, // RESERVED_MFR_3032
++{0x3400, 0x0010}, // RESERVED_MFR_3400
++{0x31D0, 0x0001}, // COMPANDING
++//{0x31AC, 0x1410}, // DATA_FORMAT_BITS: 2xRAW8
++{0x31AC, 0x140C}, // DATA_FORMAT_BITS: RAW12
++{0x3C08, 0x0100}, // RESERVED_MFR_3C08
++{0x3C0C, 0x0518}, // DELAY_BUFFER_LLPCK_RD_WR_OVERLAP
++#ifdef NEW_TBL
++//{0x300A, 0x0438}, // FRAME_LENGTH_LINES_
++//{0x300C, 0x060e}, // LINE_LENGTH_PCK_
++{0x300A, AR0143_SENSOR_HEIGHT + 157}, // FRAME_LENGTH_LINES_
++{0x300C, AR0143_SENSOR_WIDTH + 144}, // LINE_LENGTH_PCK_
++#else
++{0x300A, 0x048A}, // FRAME_LENGTH_LINES_
++{0x300C, 0x05BA}, // LINE_LENGTH_PCK_
++#endif
++{0x3018, 0x0000}, // FINE_INTEGRATION_TIME_CB
++{0x1008, 0x0338}, // FINE_INTEGRATION_TIME_MIN
++{0x100C, 0x051B}, // FINE_INTEGRATION_TIME2_MIN
++{0x100E, 0x06FE}, // FINE_INTEGRATION_TIME3_MIN
++{0x1010, 0x0155}, // FINE_INTEGRATION_TIME4_MIN
++#ifdef NEW_TBL
++{0x3012, 0x0206}, // COARSE_INTEGRATION_TIME_
++{0x3014, 0x06e8}, // FINE_INTEGRATION_TIME_
++{0x321E, 0x06E8}, // FINE_INTEGRATION_TIME2
++{0x3222, 0x06E8}, // FINE_INTEGRATION_TIME3
++#else
++{0x3012, 0x0332}, // COARSE_INTEGRATION_TIME_
++{0x3014, 0x0694}, // FINE_INTEGRATION_TIME_
++{0x321E, 0x0694}, // FINE_INTEGRATION_TIME2
++{0x3222, 0x0694}, // FINE_INTEGRATION_TIME3
++#endif
++{0x32EC, 0x72A0}, // RESERVED_MFR_32EC
++{0x31C6, 0x0000}, // HISPI_CONTROL
++#ifdef NEW_TBL
++{0x3082, 0x0000}, // OPERATION_MODE_CTRL: 1 exposure
++{0x3238, 0x0222}, // auto exposure time ratio - Fixed!
++#else
++// patch start
++//{0x30BA, 0x01E2}, // DIGITAL_CTRL: 3 exposures
++//{0x3082, 0x0008}, // OPERATION_MODE_CTRL: 3 exposures
++{0x3082, 0x0000}, // OPERATION_MODE_CTRL: 1 exposure
++//{0x30fe, 0x07ff}, // NOISE PEDESTAL
++//{0x305e, 0x3333}, // DIGITAL COLOR GLOBAL GAIN
++{0x3308, 0x200}, // DIGITAL GLOBAL GAIN: max=0x7ff
++//{0x3060, 0x7777}, // ANALOG COLOR GAIN
++{0x3366, 0x0666}, // ANALOG_GAIN - Fixed!
++//{0x3238, 0x8000}, // manual exposure time
++{0x3238, 0x0222}, // auto exposure time ratio - Fixed!
++{0x3012, 0x0300}, // T1 exposure - max=0x400
++//{0x3212, 0x0004}, // T2 exposure - not used in auto
++//{0x3216, 0x0001}, // T3 exposure - not used in auto
++#endif
++// patch eof
++{0x301A, 0x01d8}, // RESET_REGISTER
++// enable trigger
++{0x340A, 0x0070}, // GPIO_CONTROL1: GPIO3 is trigger
++{0x340C, 0x0080}, // GPIO_CONTROL2: GPIO3 is trigger
++{0x30CE, 0x0120}, // TRIGGER_MODE
++//{0x30DC, 0x0120}, // TRIGGER_DELAY
++// end reg wizard WIDTHxHEIGHT@30fps
++};
+diff --git a/drivers/media/i2c/soc_camera/ar0143_rev1.h b/drivers/media/i2c/soc_camera/ar0143_rev1.h
+new file mode 100644
+index 0000000..ec941d8
+--- /dev/null
++++ b/drivers/media/i2c/soc_camera/ar0143_rev1.h
+@@ -0,0 +1,456 @@
++/*
++ * ON Semiconductor AR0143 sensor camera wizard 1344x968@30/BGGR/BT601/RAW12
++ *
++ * Copyright (C) 2018-2019 Cogent Embedded, Inc.
++ *
++ * This program is free software; you can redistribute it and/or modify it
++ * under the terms of the GNU General Public License as published by the
++ * Free Software Foundation; either version 2 of the License, or (at your
++ * option) any later version.
++ */
++
++#define AR0143_Sensor_Setup
++#define AR0143_Recommended_Settings
++#define AR0143_Sequencer_Update
++#define AR0143_Parallel_Timing_Setup
++#define AR0143_Readout_Mode_Configuration
++#define AR0143_HDR_Readout_Mode_Configuration
++#define AR0143_Full_Res_FOV
++#define AR0143_3exp_30FPS_Timing_and_Exposure
++#define AR0143_Parallel_HDR_12_bit_Output
++#define AR0143_Trigger_Enable
++
++/* 3-Exp HDR Mode Full Resolution Parallel Mode 30FPS PLL Enable, XCLK=27MHz */
++static const struct ar0143_reg ar0143_regs_wizard_rev1[] = {
++//{0x301A, 0x0001}, // reset (broken)
++//{AR0143_DELAY, 100},
++
++#ifdef AR0143_Sensor_Setup
++{0x301A, 0x10D8}, // Stream off and setup parallel
++{0x3070, 0x0001},
++{0x3070, 0x0000}, // 1: Solid color test pattern,
++ // 2: Full color bar test pattern,
++ // 3: Fade to grey color bar test pattern,
++ //256: Walking 1 test pattern (12 bit)
++#ifdef AR0143_DISPLAY_PATTERN_FIXED
++{0x3070, 0x0001},
++#endif
++{0x3072, 0x0fff}, // R
++{0x3074, 0x0fff}, // G(GR row)
++{0x3076, 0x0fff}, // B
++{0x3078, 0x0fff}, // G(GB row)
++#ifdef AR0143_DISPLAY_PATTERN_COLOR_BAR
++{0x3070, 0x0002},
++#endif
++{AR0143_DELAY, 250},
++
++#ifdef AR0143_Recommended_Settings
++{0x3100, 0x4000},
++{0x3102, 0x6060},
++{0x3104, 0x6060},
++{0x3106, 0x6060},
++{0x3108, 0x0F9F},
++{0x3280, 0x0FA0},
++{0x3282, 0x0FA0},
++{0x3284, 0x0FA0},
++{0x3286, 0x0FA0},
++{0x3288, 0x0FA0},
++{0x328A, 0x0FA0},
++{0x328C, 0x0FA0},
++{0x328E, 0x0FA0},
++{0x3290, 0x0FA0},
++{0x3292, 0x0FA0},
++{0x3294, 0x0FA0},
++{0x3296, 0x0FA0},
++{0x3298, 0x0FA0},
++{0x329A, 0x0FA0},
++{0x329C, 0x0FA0},
++{0x329E, 0x0FA0},
++{0x3110, 0x0011},
++{0x3112, 0x7FE7},
++{0x3114, 0x0000},
++{0x3116, 0xC000},
++{0x3120, 0x0BA0},
++{0x3122, 0x0FA0},
++{0x3124, 0x00B4},
++{0x3126, 0x0030},
++{0x3128, 0x6100},
++{0x3506, 0x3333},
++{0x3508, 0x3333},
++{0x350A, 0x3333},
++{0x350C, 0x035F},
++{0x350E, 0xEF14},
++{0x3086, 0x0600},
++{0x3C00, 0xDD67},
++{0x3092, 0x1C24},
++{0x3096, 0x147E},
++{0x3750, 0x147E},
++{0x30B0, 0x0800},
++{0x30FE, 0x0020},
++{0x32D0, 0x3A02},
++{0x32D6, 0x3C04},
++{0x3C0C, 0x0516},
++{0x3F96, 0xFFFE},
++{0x3088, 0x6680},
++{0x33E2, 0x0000},
++{0x3366, 0x7777},
++{0x3056, 0x0080},
++{0x305C, 0x0080},
++{0x3058, 0x0080},
++{0x305A, 0x0080},
++{0x306E, 0x9010},
++{0x3044, 0x0400},
++{0x30BA, 0x01E0},
++{0x32EA, 0x3C0E},
++{0x3362, 0x0000},
++{0x3364, 0x005B},
++{0x3370, 0x0131},
++{0x3372, 0x700F},
++{0x3386, 0x0000},
++{0x3C04, 0x0E80},
++{0x30B4, 0x0007},
++{0x30B8, 0x0007},
++{0x3F90, 0x0403},
++{0x3F92, 0x0403},
++{0x3502, 0x0808},
++{0x3566, 0x1D28},
++{0x3518, 0x1FFE},
++{0x3520, 0x4688},
++{0x3522, 0x8840},
++{0x3524, 0x4046},
++{0x3526, 0x0F00},
++{0x3528, 0xDDDD},
++{0x352C, 0x4646},
++{0x352A, 0x089F},
++{0x352E, 0x0011},
++{0x3530, 0x4400},
++{0x3536, 0xFF07},
++{0x3538, 0xFFFF},
++{0x353A, 0x9000},
++{0x353C, 0x3F00},
++{0x32EC, 0x72A1},
++{0x3540, 0xC637},
++{0x3542, 0x464B},
++{0x3544, 0x4B50},
++{0x3546, 0x545A},
++{0x3548, 0x5500},
++{0x354A, 0x007F},
++{0x3556, 0x101F},
++{0x3566, 0x3328},
++{0x337A, 0x0B74},
++{0x3372, 0x710F},
++#endif /* AR0143_Recommended_Settings */
++
++#ifdef AR0143_Sequencer_Update
++{0x2512, 0x8000},
++{0x2510, 0x0903},
++{0x2510, 0x3350},
++{0x2510, 0x2004},
++{0x2510, 0x1420},
++{0x2510, 0x1578},
++{0x2510, 0x087B},
++{0x2510, 0x24FF},
++{0x2510, 0x24FF},
++{0x2510, 0x24EA},
++{0x2510, 0x2410},
++{0x2510, 0x2224},
++{0x2510, 0x1015},
++{0x2510, 0x5813},
++{0x2510, 0x0214},
++{0x2510, 0x0024},
++{0x2510, 0xFF24},
++{0x2510, 0xFF24},
++{0x2510, 0xEA23},
++{0x2510, 0x2464},
++{0x2510, 0x7A24},
++{0x2510, 0x0405},
++{0x2510, 0x2C40},
++{0x2510, 0x0AFF},
++{0x2510, 0x0A75},
++{0x2510, 0x0A07},
++{0x2510, 0x3851},
++{0x2510, 0x1440},
++{0x2510, 0x0004},
++{0x2510, 0x0801},
++{0x2510, 0x0408},
++{0x2510, 0x1180},
++{0x2510, 0x2652},
++{0x2510, 0x0815},
++{0x2510, 0x1813},
++{0x2510, 0xC810},
++{0x2510, 0x0210},
++{0x2510, 0x1611},
++{0x2510, 0x8111},
++{0x2510, 0x8910},
++{0x2510, 0x5612},
++{0x2510, 0x1009},
++{0x2510, 0x020D},
++{0x2510, 0x0905},
++{0x2510, 0x1588},
++{0x2510, 0x1388},
++{0x2510, 0x0938},
++{0x2510, 0x1199},
++{0x2510, 0x11D9},
++{0x2510, 0x091E},
++{0x2510, 0x1214},
++{0x2510, 0x10D6},
++{0x2510, 0x0901},
++{0x2510, 0x1210},
++{0x2510, 0x1212},
++{0x2510, 0x1210},
++{0x2510, 0x11DD},
++{0x2510, 0x11D9},
++{0x2510, 0x0901},
++{0x2510, 0x1441},
++{0x2510, 0x0904},
++{0x2510, 0x1056},
++{0x2510, 0x0811},
++{0x2510, 0xDB09},
++{0x2510, 0x0311},
++{0x2510, 0xFB11},
++{0x2510, 0xBB12},
++{0x2510, 0x1A12},
++{0x2510, 0x1008},
++{0x2510, 0x1250},
++{0x2510, 0x1076},
++{0x2510, 0x10E6},
++{0x2510, 0x1461},
++{0x2510, 0x0906},
++{0x2510, 0x1240},
++{0x2510, 0x1260},
++{0x2510, 0x091C},
++{0x2510, 0x1460},
++{0x2510, 0x090C},
++{0x2510, 0x0B09},
++{0x2510, 0x0515},
++{0x2510, 0xC813},
++{0x2510, 0xC808},
++{0x2510, 0x1066},
++{0x2510, 0x090B},
++{0x2510, 0x1588},
++{0x2510, 0x1388},
++{0x2510, 0x0913},
++{0x2510, 0x0C14},
++{0x2510, 0x4009},
++{0x2510, 0x0310},
++{0x2510, 0xE611},
++{0x2510, 0xFB12},
++{0x2510, 0x6212},
++{0x2510, 0x6011},
++{0x2510, 0xFF11},
++{0x2510, 0xFB14},
++{0x2510, 0x4109},
++{0x2510, 0x0210},
++{0x2510, 0x6609},
++{0x2510, 0x1211},
++{0x2510, 0xBB12},
++{0x2510, 0x6312},
++{0x2510, 0x6014},
++{0x2510, 0x0015},
++{0x2510, 0x1811},
++{0x2510, 0xB812},
++{0x2510, 0xA012},
++{0x2510, 0x0010},
++{0x2510, 0x2610},
++{0x2510, 0x0013},
++{0x2510, 0x0011},
++{0x2510, 0x8030},
++{0x2510, 0x5342},
++{0x2510, 0x1100},
++{0x2510, 0x1002},
++{0x2510, 0x1016},
++{0x2510, 0x1101},
++{0x2510, 0x1109},
++{0x2510, 0x1056},
++{0x2510, 0x1210},
++{0x2510, 0x0D09},
++{0x2510, 0x0614},
++{0x2510, 0x4109},
++{0x2510, 0x0714},
++{0x2510, 0x4009},
++{0x2510, 0x0115},
++{0x2510, 0xCC13},
++{0x2510, 0xCC09},
++{0x2510, 0x1611},
++{0x2510, 0x4909},
++{0x2510, 0x0815},
++{0x2510, 0x8813},
++{0x2510, 0x8809},
++{0x2510, 0x1B11},
++{0x2510, 0x5909},
++{0x2510, 0x0B12},
++{0x2510, 0x1409},
++{0x2510, 0x0112},
++{0x2510, 0x1010},
++{0x2510, 0xD612},
++{0x2510, 0x1212},
++{0x2510, 0x1011},
++{0x2510, 0x5D11},
++{0x2510, 0x5910},
++{0x2510, 0x5609},
++{0x2510, 0x0311},
++{0x2510, 0x5B08},
++{0x2510, 0x1441},
++{0x2510, 0x0901},
++{0x2510, 0x1440},
++{0x2510, 0x090C},
++{0x2510, 0x117B},
++{0x2510, 0x113B},
++{0x2510, 0x121A},
++{0x2510, 0x1210},
++{0x2510, 0x0901},
++{0x2510, 0x1250},
++{0x2510, 0x10F6},
++{0x2510, 0x10E6},
++{0x2510, 0x1460},
++{0x2510, 0x0901},
++{0x2510, 0x15AB},
++{0x2510, 0x13AB},
++{0x2510, 0x1240},
++{0x2510, 0x1260},
++{0x2510, 0x0924},
++{0x2510, 0x1588},
++{0x2510, 0x0902},
++{0x2510, 0x1066},
++{0x2510, 0x0B08},
++{0x2510, 0x1388},
++{0x2510, 0x0907},
++{0x2510, 0x158D},
++{0x2510, 0x138D},
++{0x2510, 0x090D},
++{0x2510, 0x1588},
++{0x2510, 0x1388},
++{0x2510, 0x0909},
++{0x2510, 0x0C09},
++{0x2510, 0x0214},
++{0x2510, 0x4009},
++{0x2510, 0x0710},
++{0x2510, 0xE612},
++{0x2510, 0x6212},
++{0x2510, 0x6011},
++{0x2510, 0x7F11},
++{0x2510, 0x7B10},
++{0x2510, 0x6609},
++{0x2510, 0x0614},
++{0x2510, 0x4109},
++{0x2510, 0x0114},
++{0x2510, 0x4009},
++{0x2510, 0x0D11},
++{0x2510, 0x3B12},
++{0x2510, 0x6312},
++{0x2510, 0x6014},
++{0x2510, 0x0015},
++{0x2510, 0x5A11},
++{0x2510, 0x3812},
++{0x2510, 0xA012},
++{0x2510, 0x0010},
++{0x2510, 0x2610},
++{0x2510, 0x0013},
++{0x2510, 0x4211},
++{0x2510, 0x0043},
++{0x2510, 0x7A06},
++{0x2510, 0x0508},
++{0x2510, 0x0741},
++{0x2510, 0x3750},
++{0x2510, 0x2C2C},
++{0x2510, 0xFE11},
++{0x2510, 0xFE05},
++{0x2510, 0x2C2C},
++
++{0x1008, 0x02A1},
++{0x100C, 0x042D},
++{0x100E, 0x05B9},
++{0x1010, 0x0115},
++
++{0x3230, 0x023F},
++{0x3232, 0x03CB},
++{0x3234, 0x0557},
++{0x3236, 0x00B3},
++{0x32E6, 0x009A},
++#endif /* AR0143_Sequencer_Update */
++
++{0x350C, 0x035F},
++{0x32D0, 0x3A02},
++{0x32D2, 0x3508},
++{0x32D4, 0x3702},
++{0x32D6, 0x3C04},
++{0x32DC, 0x370A},
++#endif /* AR0143_Sensor_Setup */
++
++#ifdef AR0143_Parallel_Timing_Setup
++/* PCLK=27MHz/5 *93 /1/10 = 50.22MHz - MAXIM serializers */
++{0x302A, 10}, // VT_PIX_CLK_DIV
++{0x302C, 1}, // VT_SYS_CLK_DIV
++{0x302E, 5}, // PRE_PLL_CLK_DIV
++{0x3030, 93}, // PLL_MULTIPLIER
++{0x3036, 10}, // OP_WORD_CLK_DIV
++{0x3038, 1}, // OP_SYS_CLK_DIV
++#endif /* AR0143_Parallel_Timing_Setup */
++
++#ifdef AR0143_Readout_Mode_Configuration
++{0x30A2, 0x0001}, // X_ODD_INC_
++{0x30A6, 0x0001}, // Y_ODD_INC_
++{0x3040, 0x0000}, // READ_MODE
++{0x3082, 0x0008}, // OPERATION_MODE_CTRL: 3exp
++{0x30BA, 0x01E2}, // DIGITAL_CTRL: 3exp max
++{0x3044, 0x0400}, // DARK_CONTROL
++{0x3064, 0x1802}, // SMIA_TEST: disable emb data and stats
++{0x33E0, 0x0880}, // TEST_ASIL_ROWS
++{0x3180, 0x0080}, // RESERVED_MFR_3180
++{0x33E4, 0x0080}, // RESERVED_MFR_33E4
++#endif /* AR0143_Readout_Mode_Configuration */
++
++#ifdef AR0143_HDR_Readout_Mode_Configuration
++#ifdef AR0143_EMBEDDED_LINE
++{0x3064, 0x1982}, // SMIA_TEST: enable emb data and stats
++#endif
++#endif /* AR0143_HDR_Readout_Mode_Configuration */
++
++#ifdef AR0143_Full_Res_FOV
++{0x31B0, 0x0006}, // FRAME_PREAMBLE
++{0x31B2, 0x0045}, // LINE_PREAMBLE
++{0x3004, AR0143_X_START}, // X_ADDR_START_
++{0x3008, AR0143_X_END}, // X_ADDR_END_
++{0x3002, AR0143_Y_START}, // Y_ADDR_START_
++{0x3006, AR0143_Y_END}, // Y_ADDR_END_
++{0x3400, 0x10},
++{0x3402, 0x0000 | AR0143_MAX_WIDTH}, // X_OUTPUT_CONTROL
++{0x3404, 0x0000 | AR0143_MAX_HEIGHT}, // Y_OUTPUT_CONTROL
++#endif /* AR0143_Full_Res_FOV */
++
++#ifdef AR0143_3exp_30FPS_Timing_and_Exposure
++{0x3082, 0x0008}, // OPERATION_MODE_CTRL: 3exp
++{0x30BA, 0x01E2}, // DIGITAL_CTRL: 3exp max
++/* Row and Pixel Timing */
++{0x300C, AR0143_SENSOR_WIDTH + 144}, // LINE_LENGTH_PCK_
++{0x300A, AR0143_SENSOR_HEIGHT + 157}, // FRAME_LENGTH_LINES_
++{0x3042, 0}, // EXTRA_DELAY
++/* Exposure Settings */
++{0x3238, 0x0222}, // EXPOSURE_RATIO
++{0x3012, 0x0300}, // COARSE_INTEGRATION_TIME_
++
++{0x3014, AR0143_SENSOR_WIDTH + 144 + 154}, // FINE_INTEGRATION_TIME_ = LINE_LENGTH_PCK_ + 154
++{0x321E, AR0143_SENSOR_WIDTH + 144 + 154}, // FINE_INTEGRATION_TIME2
++{0x3222, AR0143_SENSOR_WIDTH + 144 + 154}, // FINE_INTEGRATION_TIME3
++
++{0x30B0, 0x0800}, // DIGITAL_TEST
++{0x32EA, 0x3C0E},
++{0x32EC, 0x72A1},
++{0x3C06, 0x083C},
++{0x3C08, 0x0100},
++#endif /* AR0143_3exp_30FPS_Timing_and_Exposure */
++
++#ifdef AR0143_Parallel_HDR_12_bit_Output
++{0x31D0, 0x0001}, // COMPANDING
++{0x31AE, 0x0001}, // SERIAL_FORMAT
++{0x31AC, 0x140C}, // DATA_FORMAT_BITS: ADC20, RAW12
++{0x301A, 0x11d8}, // RESET_REGISTER
++#endif /* AR0143_Parallel_HDR_12_bit_Output */
++
++#ifdef AR0143_Trigger_Enable
++{0x340A, 0x0070}, // GPIO_CONTROL1: GPIO3 is trigger
++{0x340C, 0x0080}, // GPIO_CONTROL2: GPIO3 is trigger
++{0x30CE, 0x0120}, // TRIGGER_MODE
++//{0x30DC, 0x0120}, // TRIGGER_DELAY
++#endif
++};
+--
+2.7.4
+
diff --git a/bsp/meta-rcar/meta-rcar-gen3-adas/recipes-kernel/linux/linux-renesas/0156-AR0143-enable-3exp-in-custom-setup.patch b/bsp/meta-rcar/meta-rcar-gen3-adas/recipes-kernel/linux/linux-renesas/0156-AR0143-enable-3exp-in-custom-setup.patch
new file mode 100644
index 00000000..b6f930c2
--- /dev/null
+++ b/bsp/meta-rcar/meta-rcar-gen3-adas/recipes-kernel/linux/linux-renesas/0156-AR0143-enable-3exp-in-custom-setup.patch
@@ -0,0 +1,61 @@
+From cc691c2648df88a97908cb8d689267db82d0055d Mon Sep 17 00:00:00 2001
+From: Vladimir Barinov <vladimir.barinov@cogentembedded.com>
+Date: Tue, 19 Mar 2019 13:43:32 +0300
+Subject: [PATCH 105/122] AR0143: enable 3exp in custom setup
+
+This enabled 3exp in custom setup
+
+Signed-off-by: Vladimir Barinov <vladimir.barinov@cogentembedded.com>
+---
+ drivers/media/i2c/soc_camera/ar0143_custom.h | 22 ++++++++++++----------
+ 1 file changed, 12 insertions(+), 10 deletions(-)
+
+diff --git a/drivers/media/i2c/soc_camera/ar0143_custom.h b/drivers/media/i2c/soc_camera/ar0143_custom.h
+index 2d4aa1c..e5bc37a 100644
+--- a/drivers/media/i2c/soc_camera/ar0143_custom.h
++++ b/drivers/media/i2c/soc_camera/ar0143_custom.h
+@@ -10,8 +10,8 @@
+ */
+
+ static const struct ar0143_reg ar0143_regs_wizard_custom[] = {
+-{0x301A, 0x0001}, // reset
+-{AR0143_DELAY, 100},
++//{0x301A, 0x0001}, // reset (broken)
++//{AR0143_DELAY, 100},
+ {0x301A, 0x10D8}, // Stream off and setup parallel
+ {0x3070, 0x0001},
+ {0x3070, 0x0000}, // 1: Solid color test pattern,
+@@ -485,20 +485,22 @@ static const struct ar0143_reg ar0143_regs_wizard_custom[] = {
+ {0x1010, 0x0155}, // FINE_INTEGRATION_TIME4_MIN
+ #ifdef NEW_TBL
+ {0x3012, 0x0206}, // COARSE_INTEGRATION_TIME_
+-{0x3014, 0x06e8}, // FINE_INTEGRATION_TIME_
+-{0x321E, 0x06E8}, // FINE_INTEGRATION_TIME2
+-{0x3222, 0x06E8}, // FINE_INTEGRATION_TIME3
++{0x3014, AR0143_SENSOR_WIDTH + 144 + 154}, // FINE_INTEGRATION_TIME_
++{0x321E, AR0143_SENSOR_WIDTH + 144 + 154}, // FINE_INTEGRATION_TIME2
++{0x3222, AR0143_SENSOR_WIDTH + 144 + 154}, // FINE_INTEGRATION_TIME3
+ #else
+ {0x3012, 0x0332}, // COARSE_INTEGRATION_TIME_
+-{0x3014, 0x0694}, // FINE_INTEGRATION_TIME_
+-{0x321E, 0x0694}, // FINE_INTEGRATION_TIME2
+-{0x3222, 0x0694}, // FINE_INTEGRATION_TIME3
++{0x3014, AR0143_SENSOR_WIDTH + 144 + 154}, // FINE_INTEGRATION_TIME_
++{0x321E, AR0143_SENSOR_WIDTH + 144 + 154}, // FINE_INTEGRATION_TIME2
++{0x3222, AR0143_SENSOR_WIDTH + 144 + 154}, // FINE_INTEGRATION_TIME3
+ #endif
+ {0x32EC, 0x72A0}, // RESERVED_MFR_32EC
+ {0x31C6, 0x0000}, // HISPI_CONTROL
+ #ifdef NEW_TBL
+-{0x3082, 0x0000}, // OPERATION_MODE_CTRL: 1 exposure
+-{0x3238, 0x0222}, // auto exposure time ratio - Fixed!
++{0x3082, 0x0008}, // OPERATION_MODE_CTRL: 3 exposures
++{0x3238, 0x0444}, // auto exposure time ratio
++{0x33DA, 0x0001}, // OC_LUT_CONTROL: OC_LEGACY_COMPANDNG
++{0x301E, 0x00A8}, // DATA_PEDESTAL
+ #else
+ // patch start
+ //{0x30BA, 0x01E2}, // DIGITAL_CTRL: 3 exposures
+--
+2.7.4
+
diff --git a/bsp/meta-rcar/meta-rcar-gen3-adas/recipes-kernel/linux/linux-renesas/0157-AR0143-add-choose-of-imager-setup.patch b/bsp/meta-rcar/meta-rcar-gen3-adas/recipes-kernel/linux/linux-renesas/0157-AR0143-add-choose-of-imager-setup.patch
new file mode 100644
index 00000000..ff076cf0
--- /dev/null
+++ b/bsp/meta-rcar/meta-rcar-gen3-adas/recipes-kernel/linux/linux-renesas/0157-AR0143-add-choose-of-imager-setup.patch
@@ -0,0 +1,132 @@
+From fa541006e93ceccfbee6a8b89026c3aa96036c16 Mon Sep 17 00:00:00 2001
+From: Vladimir Barinov <vladimir.barinov@cogentembedded.com>
+Date: Sat, 16 Mar 2019 10:28:42 +0300
+Subject: [PATCH 106/122] AR0143: add choose of imager setup
+
+in command line:
+ar0143.setup=0 - choose custom setup
+ar0143.setup=1 - choose ONSEMI rev1 setup (default)
+
+Signed-off-by: Vladimir Barinov <vladimir.barinov@cogentembedded.com>
+---
+ drivers/media/i2c/soc_camera/ar0143.c | 41 ++++++++++++++++++++++++++---------
+ drivers/media/i2c/soc_camera/ar0143.h | 2 +-
+ 2 files changed, 32 insertions(+), 11 deletions(-)
+
+diff --git a/drivers/media/i2c/soc_camera/ar0143.c b/drivers/media/i2c/soc_camera/ar0143.c
+index 65dc4fb..b0ed9ff 100644
+--- a/drivers/media/i2c/soc_camera/ar0143.c
++++ b/drivers/media/i2c/soc_camera/ar0143.c
+@@ -25,6 +25,7 @@
+ #define AR0143_I2C_ADDR 0x10
+
+ #define AR0143_PID 0x3000
++#define AR0143_REV 0x300E
+ #define AR0143_VERSION_REG 0x0D54
+
+ #define AR0143_MEDIA_BUS_FMT MEDIA_BUS_FMT_SGRBG12_1X12
+@@ -36,6 +37,7 @@ struct ar0143_priv {
+ struct v4l2_rect rect;
+ int init_complete;
+ u8 id[6];
++ int setup;
+ /* serializers */
+ int max9286_addr;
+ int max9271_addr;
+@@ -49,6 +51,10 @@ struct ar0143_priv {
+ int frame_preamble;
+ };
+
++static int setup = 1;
++module_param(setup, int, 0644);
++MODULE_PARM_DESC(setup, " Forse setup (default: 1 - rev1)");
++
+ static inline struct ar0143_priv *to_ar0143(const struct i2c_client *client)
+ {
+ return container_of(i2c_get_clientdata(client), struct ar0143_priv, sd);
+@@ -432,7 +438,7 @@ static int ar0143_initialize(struct i2c_client *client)
+ {
+ struct ar0143_priv *priv = to_ar0143(client);
+ u16 val = 0;
+- u16 pid = 0;
++ u16 pid = 0, rev = 0;
+ int ret = 0;
+ int tmp_addr;
+
+@@ -447,8 +453,19 @@ static int ar0143_initialize(struct i2c_client *client)
+ goto err;
+ }
+
++ /* check revision */
++ reg16_read16(client, AR0143_REV, &rev);
++ /* Read OTP IDs */
++ ar0143_otp_id_read(client);
+ /* Program wizard registers */
+- ar0143_set_regs(client, ar0143_regs_wizard_rev1, ARRAY_SIZE(ar0143_regs_wizard_rev1));
++ switch (priv->setup) {
++ case 0:
++ ar0143_set_regs(client, ar0143_regs_wizard_custom, ARRAY_SIZE(ar0143_regs_wizard_custom));
++ break;
++ case 1:
++ default:
++ ar0143_set_regs(client, ar0143_regs_wizard_rev1, ARRAY_SIZE(ar0143_regs_wizard_rev1));
++ }
+
+ tmp_addr = client->addr;
+ if (priv->max9271_addr) {
+@@ -467,15 +484,12 @@ static int ar0143_initialize(struct i2c_client *client)
+ client->addr = tmp_addr;
+
+ /* Enable stream */
+- reg16_read16(client, 0x301a, &val); // read inital reset_register value
+- val |= (1 << 2); // Set streamOn bit
+- reg16_write16(client, 0x301a, val); // Start Streaming
++ reg16_read16(client, 0x301a, &val);
++ val |= (1 << 2);
++ reg16_write16(client, 0x301a, val);
+
+- /* Read OTP IDs */
+- ar0143_otp_id_read(client);
+-
+- dev_info(&client->dev, "ar0143 PID %x, res %dx%d, OTP_ID %02x:%02x:%02x:%02x:%02x:%02x\n",
+- pid, AR0143_MAX_WIDTH, AR0143_MAX_HEIGHT, priv->id[0], priv->id[1], priv->id[2], priv->id[3], priv->id[4], priv->id[5]);
++ dev_info(&client->dev, "ar0143 PID %x (rev %x), res %dx%d, OTP_ID %02x:%02x:%02x:%02x:%02x:%02x\n",
++ pid, rev, AR0143_MAX_WIDTH, AR0143_MAX_HEIGHT, priv->id[0], priv->id[1], priv->id[2], priv->id[3], priv->id[4], priv->id[5]);
+ err:
+ ar0143_s_port(client, 0);
+
+@@ -489,6 +503,9 @@ static int ar0143_parse_dt(struct device_node *np, struct ar0143_priv *priv)
+ struct device_node *endpoint = NULL, *rendpoint = NULL;
+ int tmp_addr = 0;
+
++ if (of_property_read_u32(np, "onnn,setup", &priv->setup))
++ priv->setup = 1;
++
+ for (i = 0; ; i++) {
+ endpoint = of_graph_get_next_endpoint(np, endpoint);
+ if (!endpoint)
+@@ -542,6 +559,10 @@ static int ar0143_parse_dt(struct device_node *np, struct ar0143_priv *priv)
+
+ mdelay(10);
+
++ /* module params override dts */
++ if (setup != 1)
++ priv->setup = setup;
++
+ return 0;
+ }
+
+diff --git a/drivers/media/i2c/soc_camera/ar0143.h b/drivers/media/i2c/soc_camera/ar0143.h
+index 042dd50..14d8175 100644
+--- a/drivers/media/i2c/soc_camera/ar0143.h
++++ b/drivers/media/i2c/soc_camera/ar0143.h
+@@ -32,5 +32,5 @@ struct ar0143_reg {
+ u16 val;
+ };
+
+-//#include "ar0143_custom.h"
++#include "ar0143_custom.h"
+ #include "ar0143_rev1.h"
+--
+2.7.4
+
diff --git a/bsp/meta-rcar/meta-rcar-gen3-adas/recipes-kernel/linux/linux-renesas/0158-MAX9286-fix-BWS-setup-to-reserve-reboot.patch b/bsp/meta-rcar/meta-rcar-gen3-adas/recipes-kernel/linux/linux-renesas/0158-MAX9286-fix-BWS-setup-to-reserve-reboot.patch
new file mode 100644
index 00000000..1c8cd843
--- /dev/null
+++ b/bsp/meta-rcar/meta-rcar-gen3-adas/recipes-kernel/linux/linux-renesas/0158-MAX9286-fix-BWS-setup-to-reserve-reboot.patch
@@ -0,0 +1,85 @@
+From 7684c917aba38e78e8ded754662de7ee5bec18be Mon Sep 17 00:00:00 2001
+From: Vladimir Barinov <vladimir.barinov@cogentembedded.com>
+Date: Tue, 19 Mar 2019 13:49:20 +0300
+Subject: [PATCH 107/122] MAX9286: fix BWS setup to reserve reboot
+
+This fixes reset/reboot for BWS=1 mode
+
+Signed-off-by: Vladimir Barinov <vladimir.barinov@cogentembedded.com>
+---
+ drivers/media/i2c/soc_camera/max9286.c | 24 +++++++++++++++++-------
+ 1 file changed, 17 insertions(+), 7 deletions(-)
+
+diff --git a/drivers/media/i2c/soc_camera/max9286.c b/drivers/media/i2c/soc_camera/max9286.c
+index 88eab02..c69be50 100644
+--- a/drivers/media/i2c/soc_camera/max9286.c
++++ b/drivers/media/i2c/soc_camera/max9286.c
+@@ -212,7 +212,8 @@ static void max9286_preinit(struct i2c_client *client, int addr)
+ reg8_write(client, 0x00, 0x00); /* disable all GMSL links [0:3] */
+ // usleep_range(2000, 2500); /* wait 2ms after any change of reverse channel settings */
+ reg8_write(client, 0x1b, priv->switchin); /* coax polarity (default - normal) */
+- reg8_write(client, 0x1c, priv->him ? 0xf4 : 0x04); /* high-immunity/legacy mode, BWS: 24-bit */
++ reg8_write(client, 0x1c, (priv->him ? 0xf0 : 0x00) |
++ (priv->bws ? 0x05 : 0x04)); /* high-immunity/legacy mode, BWS 24bit */
+ }
+
+ static void max9286_sensor_reset(struct i2c_client *client, int addr, int reset_on)
+@@ -253,8 +254,6 @@ static void max9286_postinit(struct i2c_client *client, int addr)
+ reg8_write(client, 0x0b, priv->csi2_outord); /* CSI2 output order */
+ reg8_write(client, 0x15, 0x9b); /* enable CSI output, VC is set accordingly to Link number, BIT7 magic must be set */
+ reg8_write(client, 0x1b, priv->switchin | priv->links_mask); /* coax polarity, enable equalizer for CAMs */
+- reg8_write(client, 0x1c, (priv->him ? 0xf0 : 0x00) |
+- (priv->bws ? 0x05 : 0x04)); /* high-immunity/legacy mode, BWS 24/32-bit */
+ usleep_range(5000, 5500); /* wait 2ms after any change of reverse channel settings */
+
+ if (strcmp(priv->fsync_mode, "manual") == 0) {
+@@ -292,6 +291,12 @@ static int max9286_reverse_channel_setup(struct i2c_client *client, int idx)
+ usleep_range(2000, 2500); /* wait 2ms after any change of reverse channel settings */
+ reg8_write(client, 0x04, 0x43); /* wake-up, enable reverse_control/conf_link */
+ usleep_range(2000, 2500); /* wait 2ms after any change of reverse channel settings */
++ if (priv->bws) {
++ reg8_write(client, 0x07, 0x04 | (priv->pclk_rising_edge ? 0 : 0x10) |
++ (priv->dbl ? 0x80 : 0) |
++ (priv->bws ? 0x20 : 0)); /* RAW/YUV, PCLK edge, HS/VS encoding enabled, DBL mode, BWS 24/32-bit */
++ usleep_range(2000, 2500); /* wait 2ms after any change of reverse channel settings */
++ }
+ } else {
+ /* Legacy mode setup */
+ client->addr = priv->des_addr; /* MAX9286-CAMx I2C */
+@@ -305,6 +310,12 @@ static int max9286_reverse_channel_setup(struct i2c_client *client, int idx)
+ reg8_write(client, 0x08, 0x01); /* reverse channel receiver high threshold enable */
+ reg8_write(client, 0x97, 0x5f); /* enable reverse control channel programming (MAX96705-MAX96711 only) */
+ usleep_range(2000, 2500); /* wait 2ms after any change of reverse channel settings */
++ if (priv->bws) {
++ reg8_write(client, 0x07, 0x04 | (priv->pclk_rising_edge ? 0 : 0x10) |
++ (priv->dbl ? 0x80 : 0) |
++ (priv->bws ? 0x20 : 0)); /* RAW/YUV, PCLK edge, HS/VS encoding enabled, DBL mode, BWS 24/32-bit */
++ usleep_range(2000, 2500); /* wait 2ms after any change of reverse channel settings */
++ }
+
+ client->addr = priv->des_addr; /* MAX9286-CAMx I2C */
+ reg8_write(client, 0x3b, 0x19); /* reverse channel increase amplitude 170mV to compensate high threshold enabled */
+@@ -391,7 +402,9 @@ static void max9286_gmsl_link_setup(struct i2c_client *client, int idx)
+ /* GMSL setup */
+ client->addr = 0x40; /* MAX9271-CAMx I2C */
+ reg8_write(client, 0x0d, 0x22 | MAXIM_I2C_I2C_SPEED); /* disable artificial ACK, I2C speed set */
+- reg8_write(client, 0x07, 0x04 | (priv->pclk_rising_edge ? 0 : 0x10) | (priv->dbl ? 0x80 : 0)); /* RAW/YUV, PCLK edge, HS/VS encoding enabled, DBL mode, BWS 24-bit */
++ reg8_write(client, 0x07, 0x04 | (priv->pclk_rising_edge ? 0 : 0x10) |
++ (priv->dbl ? 0x80 : 0) |
++ (priv->bws ? 0x20 : 0)); /* RAW/YUV, PCLK edge, HS/VS encoding enabled, DBL mode, BWS 24/32-bit */
+ usleep_range(2000, 2500); /* wait 2ms */
+ reg8_write(client, 0x02, 0xff); /* spread spectrum +-4%, pclk range automatic, Gbps automatic */
+ usleep_range(2000, 2500); /* wait 2ms */
+@@ -507,9 +520,6 @@ static void max9286_gmsl_link_setup(struct i2c_client *client, int idx)
+ client->addr = priv->max9271_addr_map[idx]; /* MAX9271-CAMx I2C new */
+ maxim_max927x_dump_regs(client);
+ #endif
+- reg8_write(client, 0x07, 0x04 | (priv->pclk_rising_edge ? 0 : 0x10) |
+- (priv->dbl ? 0x80 : 0) |
+- (priv->bws ? 0x20 : 0)); /* RAW/YUV, PCLK edge, HS/VS encoding enabled, DBL mode, BWS 24/32-bit */
+ }
+
+ static int max9286_initialize(struct i2c_client *client)
+--
+2.7.4
+
diff --git a/bsp/meta-rcar/meta-rcar-gen3-adas/recipes-kernel/linux/linux-renesas/0159-MAX9286-adjust-POC-trigger-for-unstable-link.patch b/bsp/meta-rcar/meta-rcar-gen3-adas/recipes-kernel/linux/linux-renesas/0159-MAX9286-adjust-POC-trigger-for-unstable-link.patch
new file mode 100644
index 00000000..0084006a
--- /dev/null
+++ b/bsp/meta-rcar/meta-rcar-gen3-adas/recipes-kernel/linux/linux-renesas/0159-MAX9286-adjust-POC-trigger-for-unstable-link.patch
@@ -0,0 +1,88 @@
+From 3eb6986dcd340226956239c94adceff9e7a4f7af Mon Sep 17 00:00:00 2001
+From: Vladimir Barinov <vladimir.barinov@cogentembedded.com>
+Date: Tue, 19 Mar 2019 13:51:26 +0300
+Subject: [PATCH 108/122] MAX9286: adjust POC trigger for unstable link
+
+Enhance POC trgger on camera detect fails
+Add lock/link status show
+
+Signed-off-by: Vladimir Barinov <vladimir.barinov@cogentembedded.com>
+---
+ drivers/media/i2c/soc_camera/max9286.c | 22 ++++++++++++++++------
+ 1 file changed, 16 insertions(+), 6 deletions(-)
+
+diff --git a/drivers/media/i2c/soc_camera/max9286.c b/drivers/media/i2c/soc_camera/max9286.c
+index c69be50..3184ff1 100644
+--- a/drivers/media/i2c/soc_camera/max9286.c
++++ b/drivers/media/i2c/soc_camera/max9286.c
+@@ -108,6 +108,10 @@ static int active_low_resetb;
+ module_param(active_low_resetb, int, 0644);
+ MODULE_PARM_DESC(active_low_resetb, " Serializer GPIO reset level (default: 0 - active high)");
+
++static int timeout_n = 100;
++module_param(timeout_n, int, 0644);
++MODULE_PARM_DESC(timeout_n, " Timeout of link detection (default: 100 retries)");
++
+ static int poc_delay = 50;
+ module_param(poc_delay, int, 0644);
+ MODULE_PARM_DESC(poc_delay, " Delay in ms after POC enable (default: 50 ms)");
+@@ -270,9 +274,9 @@ static void max9286_postinit(struct i2c_client *client, int addr)
+ static int max9286_reverse_channel_setup(struct i2c_client *client, int idx)
+ {
+ struct max9286_priv *priv = i2c_get_clientdata(client);
+- u8 val = 0;
++ u8 val = 0, lock_sts = 0, link_sts = 0;
+ int timeout = priv->timeout;
+- char timeout_str[10];
++ char timeout_str[40];
+ int ret = 0;
+
+ /* Reverse channel enable */
+@@ -340,8 +344,8 @@ static int max9286_reverse_channel_setup(struct i2c_client *client, int idx)
+ break;
+ }
+
+- if (timeout == priv->timeout / 2 && poc_trig) {
+- if (!IS_ERR(priv->poc_gpio[idx])) {
++ if (poc_trig) {
++ if (!IS_ERR(priv->poc_gpio[idx]) && (timeout % poc_trig == 0)) {
+ gpiod_direction_output(priv->poc_gpio[idx], 0); /* POC power off */
+ mdelay(200);
+ gpiod_direction_output(priv->poc_gpio[idx], 1); /* POC power on */
+@@ -352,6 +356,10 @@ static int max9286_reverse_channel_setup(struct i2c_client *client, int idx)
+
+ max9286_sensor_reset(client, client->addr, 1); /* sensor reset */
+
++ client->addr = priv->des_addr; /* MAX9286-CAMx I2C */
++ reg8_read(client, 0x27, &lock_sts); /* LOCK status */
++ reg8_read(client, 0x49, &link_sts); /* LINK status */
++
+ if (!timeout) {
+ ret = -ETIMEDOUT;
+ goto out;
+@@ -362,11 +370,11 @@ static int max9286_reverse_channel_setup(struct i2c_client *client, int idx)
+ priv->csi2_outord |= ((hweight8(priv->links_mask) - 1) << (idx * 2));
+
+ out:
+- sprintf(timeout_str, "retries=%d", priv->timeout - timeout);
++ sprintf(timeout_str, "retries=%d lock_sts=%d link_sts=0x%x", priv->timeout - timeout, !!(lock_sts & 0x80), link_sts & (0x11 << idx));
+ dev_info(&client->dev, "link%d %s %sat 0x%x %s %s\n", idx, ser_name(priv->ser_id),
+ ret == -EADDRINUSE ? "already " : "", priv->max9271_addr_map[idx],
+ ret == -ETIMEDOUT ? "not found: timeout GMSL link establish" : "",
+- priv->timeout - timeout? timeout_str : "");
++ priv->timeout - timeout ? timeout_str : "");
+
+ return ret;
+ }
+@@ -741,6 +749,8 @@ static int max9286_parse_dt(struct i2c_client *client)
+ priv->gpio_resetb = gpio_resetb;
+ if (active_low_resetb)
+ priv->active_low_resetb = active_low_resetb;
++ if (timeout_n)
++ priv->timeout = timeout_n;
+ if (poc_delay)
+ priv->poc_delay = poc_delay;
+ if (bws)
+--
+2.7.4
+
diff --git a/bsp/meta-rcar/meta-rcar-gen3-adas/recipes-kernel/linux/linux-renesas/0160-lvds-onsemi-fix-revsion-parsing.patch b/bsp/meta-rcar/meta-rcar-gen3-adas/recipes-kernel/linux/linux-renesas/0160-lvds-onsemi-fix-revsion-parsing.patch
new file mode 100644
index 00000000..fa302da8
--- /dev/null
+++ b/bsp/meta-rcar/meta-rcar-gen3-adas/recipes-kernel/linux/linux-renesas/0160-lvds-onsemi-fix-revsion-parsing.patch
@@ -0,0 +1,89 @@
+From 9a42f3263afe102eb8573f68a20054235a32b3c6 Mon Sep 17 00:00:00 2001
+From: Vladimir Barinov <vladimir.barinov@cogentembedded.com>
+Date: Thu, 25 Apr 2019 12:38:47 +0300
+Subject: [PATCH 109/122] lvds: onsemi: fix revsion parsing
+
+Fix revision parsing on ONSEMI imagers
+
+Signed-off-by: Vladimir Barinov <vladimir.barinov@cogentembedded.com>
+---
+ drivers/media/i2c/soc_camera/ar0143.c | 2 +-
+ drivers/media/i2c/soc_camera/ar0231.c | 2 +-
+ drivers/media/i2c/soc_camera/ar0233.c | 11 +++++++----
+ drivers/media/i2c/soc_camera/ar0323.c | 2 +-
+ 4 files changed, 10 insertions(+), 7 deletions(-)
+
+diff --git a/drivers/media/i2c/soc_camera/ar0143.c b/drivers/media/i2c/soc_camera/ar0143.c
+index b0ed9ff..01494fe 100644
+--- a/drivers/media/i2c/soc_camera/ar0143.c
++++ b/drivers/media/i2c/soc_camera/ar0143.c
+@@ -25,7 +25,7 @@
+ #define AR0143_I2C_ADDR 0x10
+
+ #define AR0143_PID 0x3000
+-#define AR0143_REV 0x300E
++#define AR0143_REV 0x31FE
+ #define AR0143_VERSION_REG 0x0D54
+
+ #define AR0143_MEDIA_BUS_FMT MEDIA_BUS_FMT_SGRBG12_1X12
+diff --git a/drivers/media/i2c/soc_camera/ar0231.c b/drivers/media/i2c/soc_camera/ar0231.c
+index 07f2b5e..05037c7 100644
+--- a/drivers/media/i2c/soc_camera/ar0231.c
++++ b/drivers/media/i2c/soc_camera/ar0231.c
+@@ -25,7 +25,7 @@
+ static const int ar0231_i2c_addr[] = {0x10, 0x20};
+
+ #define AR0231_PID 0x3000
+-#define AR0231_REV 0x300E
++#define AR0231_REV 0x31FE
+ #define AR0231_VERSION_REG 0x0354
+
+ #define AR0231_MEDIA_BUS_FMT MEDIA_BUS_FMT_SGRBG12_1X12
+diff --git a/drivers/media/i2c/soc_camera/ar0233.c b/drivers/media/i2c/soc_camera/ar0233.c
+index 19386bb..e18fa55 100644
+--- a/drivers/media/i2c/soc_camera/ar0233.c
++++ b/drivers/media/i2c/soc_camera/ar0233.c
+@@ -25,7 +25,7 @@
+ static const int ar0233_i2c_addr[] = {0x10, 0x20};
+
+ #define AR0233_PID 0x3000
+-#define AR0233_REV 0x300E
++#define AR0233_REV 0x31FE
+ #define AR0233_VERSION_REG 0x0956
+
+ #define AR0233_MEDIA_BUS_FMT MEDIA_BUS_FMT_SGRBG12_1X12
+@@ -410,12 +410,15 @@ static int ar0233_initialize(struct i2c_client *client)
+ /* Read OTP IDs */
+ ar0233_otp_id_read(client);
+ /* Program wizard registers */
+- switch (rev) {
+- case 0x2015:
++ switch (rev & 0xf) {
++ case 0x1:
++ ar0233_set_regs(client, ar0233_regs_wizard_rev1, ARRAY_SIZE(ar0233_regs_wizard_rev1));
++ break;
++ case 0x2:
+ ar0233_set_regs(client, ar0233_regs_wizard_rev2, ARRAY_SIZE(ar0233_regs_wizard_rev2));
+ break;
+ default:
+- ar0233_set_regs(client, ar0233_regs_wizard_rev1, ARRAY_SIZE(ar0233_regs_wizard_rev1));
++ dev_err(&client->dev, "Unsupported chip revision\n");
+ }
+
+ /* Enable stream */
+diff --git a/drivers/media/i2c/soc_camera/ar0323.c b/drivers/media/i2c/soc_camera/ar0323.c
+index d29f4ad..2ee5526 100644
+--- a/drivers/media/i2c/soc_camera/ar0323.c
++++ b/drivers/media/i2c/soc_camera/ar0323.c
+@@ -25,7 +25,7 @@
+ static const int ar0323_i2c_addr[] = {0x10, 0x20};
+
+ #define AR0323_PID 0x3000
+-#define AR0323_REV 0x300E
++#define AR0323_REV 0x31FE
+ #define AR0323_VERSION_REG 0x0D56
+
+ #define AR0323_MEDIA_BUS_FMT MEDIA_BUS_FMT_SGRBG12_1X12
+--
+2.7.4
+
diff --git a/bsp/meta-rcar/meta-rcar-gen3-adas/recipes-kernel/linux/linux-renesas/0161-lvds-AR0233-add-module-trigger-parameter.patch b/bsp/meta-rcar/meta-rcar-gen3-adas/recipes-kernel/linux/linux-renesas/0161-lvds-AR0233-add-module-trigger-parameter.patch
new file mode 100644
index 00000000..192a637d
--- /dev/null
+++ b/bsp/meta-rcar/meta-rcar-gen3-adas/recipes-kernel/linux/linux-renesas/0161-lvds-AR0233-add-module-trigger-parameter.patch
@@ -0,0 +1,116 @@
+From 86f4fd9830600c2ffe9fbdb169a356a5a623fb0c Mon Sep 17 00:00:00 2001
+From: Vladimir Barinov <vladimir.barinov@cogentembedded.com>
+Date: Thu, 25 Apr 2019 22:33:55 +0300
+Subject: [PATCH 110/122] lvds: AR0233: add module trigger parameter
+
+This add trigger as module parameter or dts since this is hardware
+dependent
+
+Signed-off-by: Vladimir Barinov <vladimir.barinov@cogentembedded.com>
+---
+ drivers/media/i2c/soc_camera/ar0233.c | 20 ++++++++++++++++++--
+ drivers/media/i2c/soc_camera/ar0233_rev1.h | 8 --------
+ drivers/media/i2c/soc_camera/ar0233_rev2.h | 9 ---------
+ 3 files changed, 18 insertions(+), 19 deletions(-)
+
+diff --git a/drivers/media/i2c/soc_camera/ar0233.c b/drivers/media/i2c/soc_camera/ar0233.c
+index e18fa55..8257cf1 100644
+--- a/drivers/media/i2c/soc_camera/ar0233.c
++++ b/drivers/media/i2c/soc_camera/ar0233.c
+@@ -41,10 +41,13 @@ struct ar0233_priv {
+ int ti9x4_addr;
+ int ti9x3_addr;
+ int port;
+- int gpio_resetb;
+- int gpio_fsin;
++ int trigger;
+ };
+
++static int trigger = 0;
++module_param(trigger, int, 0644);
++MODULE_PARM_DESC(trigger, " Trigger gpio number (default: 0 - GPIO0) ");
++
+ static inline struct ar0233_priv *to_ar0233(const struct i2c_client *client)
+ {
+ return container_of(i2c_get_clientdata(client), struct ar0233_priv, sd);
+@@ -421,8 +424,15 @@ static int ar0233_initialize(struct i2c_client *client)
+ dev_err(&client->dev, "Unsupported chip revision\n");
+ }
+
++ /* Enable trigger*/
++ reg16_write16(client, 0x340A, (~(BIT(priv->trigger) << 4)) & 0xf0); /* GPIO_CONTROL1: GPIOn input enable */
++ reg16_write16(client, 0x340C, (0x2 << 2*priv->trigger)); /* GPIO_CONTROL2: GPIOn is trigger */
++ reg16_write16(client, 0x30CE, 0x0120); /* TRIGGER_MODE */
++ //reg16_write16(client, 0x30DC, 0x0120); /* TRIGGER_DELAY */
++
+ /* Enable stream */
+ reg16_read16(client, 0x301a, &val); // read inital reset_register value
++ val |= (1 << 8); /* GPI pins enable */
+ val |= (1 << 2); // Set streamOn bit
+ reg16_write16(client, 0x301a, val); // Start Streaming
+
+@@ -444,6 +454,8 @@ static int ar0233_parse_dt(struct device_node *np, struct ar0233_priv *priv)
+ if (!endpoint)
+ break;
+
++ of_property_read_u32(endpoint, "trigger", &priv->trigger);
++
+ rendpoint = of_parse_phandle(endpoint, "remote-endpoint", 0);
+ if (!rendpoint)
+ continue;
+@@ -473,6 +485,10 @@ static int ar0233_parse_dt(struct device_node *np, struct ar0233_priv *priv)
+ }
+ client->addr = tmp_addr;
+
++ /* module params override dts */
++ if (trigger)
++ priv->trigger = trigger;
++
+ return 0;
+ }
+
+diff --git a/drivers/media/i2c/soc_camera/ar0233_rev1.h b/drivers/media/i2c/soc_camera/ar0233_rev1.h
+index c29ac6a..288b465 100644
+--- a/drivers/media/i2c/soc_camera/ar0233_rev1.h
++++ b/drivers/media/i2c/soc_camera/ar0233_rev1.h
+@@ -1247,12 +1247,4 @@ static const struct ar0233_reg ar0233_regs_wizard_rev1[] = {
+ {0x3D14, 0x001E},
+ {0x3D16, 0x045E},
+ #endif /* MEC DLO default */
+-
+-#if 1 /* Enable_trigger_input */
+-{0x340A, 0x0070}, // GPIO_CONTROL1: GPIO1 is trigger
+-{0x340C, 0x0080}, // GPIO_CONTROL2: GPIO1 is trigger
+-{0x30CE, 0x0120}, // TRIGGER_MODE
+-//{0x30DC, 0x0120}, // TRIGGER_DELAY
+-{0x301A, 0x0118}, // GPI pins enable
+-#endif /* Enable_trigger_input */
+ };
+diff --git a/drivers/media/i2c/soc_camera/ar0233_rev2.h b/drivers/media/i2c/soc_camera/ar0233_rev2.h
+index f4b75a2..0dea2dd 100644
+--- a/drivers/media/i2c/soc_camera/ar0233_rev2.h
++++ b/drivers/media/i2c/soc_camera/ar0233_rev2.h
+@@ -28,7 +28,6 @@
+ #define MIPI_DT_bit12
+ #define LUT_24_to_12
+ #define HDR_ratio_gain_default
+-#define Enable_trigger_input
+
+ /* 3Exp HDR 1280P Mipi_12bit_4lane_30fps, XCLK=27MHz */
+ static const struct ar0233_reg ar0233_regs_wizard_rev2[] = {
+@@ -1249,12 +1248,4 @@ static const struct ar0233_reg ar0233_regs_wizard_rev2[] = {
+ {0x300A, AR0233_SENSOR_HEIGHT + 100}, // Frame_length_Lines
+ {0x300C, AR0233_SENSOR_WIDTH + 400}, // Line_length_pck
+ {0x3012, 0x144}, //Integration_time
+-
+-#ifdef Enable_trigger_input
+-{0x340A, 0x0070}, // GPIO_CONTROL1: GPIO1 is trigger
+-{0x340C, 0x0080}, // GPIO_CONTROL2: GPIO1 is trigger
+-{0x30CE, 0x0120}, // TRIGGER_MODE
+-//{0x30DC, 0x0120}, // TRIGGER_DELAY
+-{0x301A, 0x0118}, // GPI pins enable
+-#endif /* Enable_trigger_input */
+ };
+--
+2.7.4
+
diff --git a/bsp/meta-rcar/meta-rcar-gen3-adas/recipes-kernel/linux/linux-renesas/0162-lvds-AR0233-migrate-to-composed-tables.patch b/bsp/meta-rcar/meta-rcar-gen3-adas/recipes-kernel/linux/linux-renesas/0162-lvds-AR0233-migrate-to-composed-tables.patch
new file mode 100644
index 00000000..f6475b00
--- /dev/null
+++ b/bsp/meta-rcar/meta-rcar-gen3-adas/recipes-kernel/linux/linux-renesas/0162-lvds-AR0233-migrate-to-composed-tables.patch
@@ -0,0 +1,539 @@
+From 31f98f9d7765dca4405ccf7b982d094bcd56e9d3 Mon Sep 17 00:00:00 2001
+From: Vladimir Barinov <vladimir.barinov@cogentembedded.com>
+Date: Mon, 6 May 2019 22:51:09 +0300
+Subject: [PATCH 111/122] lvds: AR0233: migrate to composed tables
+
+Migrate to composed table
+Add seperate EXTCLK (coming not from CLKOUT)
+---
+ drivers/media/i2c/soc_camera/ar0233.c | 49 +++++++---
+ drivers/media/i2c/soc_camera/ar0233_rev1.h | 104 ++++++++++++--------
+ drivers/media/i2c/soc_camera/ar0233_rev2.h | 147 ++++++++++++++---------------
+ 3 files changed, 171 insertions(+), 129 deletions(-)
+
+diff --git a/drivers/media/i2c/soc_camera/ar0233.c b/drivers/media/i2c/soc_camera/ar0233.c
+index 8257cf1..54cc38a 100644
+--- a/drivers/media/i2c/soc_camera/ar0233.c
++++ b/drivers/media/i2c/soc_camera/ar0233.c
+@@ -48,23 +48,42 @@ static int trigger = 0;
+ module_param(trigger, int, 0644);
+ MODULE_PARM_DESC(trigger, " Trigger gpio number (default: 0 - GPIO0) ");
+
++static int extclk = 23;
++module_param(extclk, int, 0644);
++MODULE_PARM_DESC(extclk, " EXTCLK value in MHz (default: 23) ");
++
++static char *mode = "hdr";
++module_param(mode, charp, 0644);
++MODULE_PARM_DESC(mode, " Modes linear,hdr,seplus (default: hdr)");
++
+ static inline struct ar0233_priv *to_ar0233(const struct i2c_client *client)
+ {
+ return container_of(i2c_get_clientdata(client), struct ar0233_priv, sd);
+ }
+
+-static int ar0233_set_regs(struct i2c_client *client,
+- const struct ar0233_reg *regs, int nr_regs)
++static int ar0233_set_regs(struct i2c_client *client, const struct ar0233_reg **pregs)
+ {
+- int i;
++ struct ar0233_priv *priv = to_ar0233(client);
++ const struct ar0233_reg *regs;
++ int i, j;
+
+- for (i = 0; i < nr_regs; i++) {
+- if (regs[i].reg == AR0233_DELAY) {
+- mdelay(regs[i].val);
+- continue;
+- }
++ for (j = 0; ; j++) {
++ regs = pregs[j];
+
+- reg16_write16(client, regs[i].reg, regs[i].val);
++ if (!pregs[j])
++ break;
++
++ for (i = 0; ; i++) {
++ if (!regs[i].reg && !regs[i].val)
++ break;
++
++ if (regs[i].reg == AR0233_DELAY) {
++ mdelay(regs[i].val);
++ continue;
++ }
++
++ reg16_write16(client, regs[i].reg, regs[i].val);
++ }
+ }
+
+ return 0;
+@@ -415,16 +434,22 @@ static int ar0233_initialize(struct i2c_client *client)
+ /* Program wizard registers */
+ switch (rev & 0xf) {
+ case 0x1:
+- ar0233_set_regs(client, ar0233_regs_wizard_rev1, ARRAY_SIZE(ar0233_regs_wizard_rev1));
++ ar0233_set_regs(client, ar0233_regs_hdr_mipi_12bit_30fps_rev1);
+ break;
+ case 0x2:
+- ar0233_set_regs(client, ar0233_regs_wizard_rev2, ARRAY_SIZE(ar0233_regs_wizard_rev2));
++ if (extclk == 27)
++ ar0233_regs_hdr_mipi_12bit_30fps_rev2[4] = ar0233_rev2_pll_27_102_4lane_12b;
++
++ if (strcmp(mode, "hdr") == 0)
++ ar0233_set_regs(client, ar0233_regs_hdr_mipi_12bit_30fps_rev2);
++ else
++ dev_err(&client->dev, "Unsupported mode %s\n", mode);
+ break;
+ default:
+ dev_err(&client->dev, "Unsupported chip revision\n");
+ }
+
+- /* Enable trigger*/
++ /* Enable trigger */
+ reg16_write16(client, 0x340A, (~(BIT(priv->trigger) << 4)) & 0xf0); /* GPIO_CONTROL1: GPIOn input enable */
+ reg16_write16(client, 0x340C, (0x2 << 2*priv->trigger)); /* GPIO_CONTROL2: GPIOn is trigger */
+ reg16_write16(client, 0x30CE, 0x0120); /* TRIGGER_MODE */
+diff --git a/drivers/media/i2c/soc_camera/ar0233_rev1.h b/drivers/media/i2c/soc_camera/ar0233_rev1.h
+index 288b465..7b6370b 100644
+--- a/drivers/media/i2c/soc_camera/ar0233_rev1.h
++++ b/drivers/media/i2c/soc_camera/ar0233_rev1.h
+@@ -9,11 +9,9 @@
+ * option) any later version.
+ */
+
+-/* 3Exp HDR 1080p Mode MIPI-4lane 12-bit 30FPS, XCLK=24MHz */
+-static const struct ar0233_reg ar0233_regs_wizard_rev1[] = {
+-{0x301A, 0x18}, // MIPI, stream OFF
+-{AR0233_DELAY, 200}, // Wait 200ms
+-
++static const struct ar0233_reg ar0233_rev1_Reset[] = {
++{0x301A, 0x0018}, // Stream off and setup MIPI
++{AR0233_DELAY, 200},
+ {0x3070, 0x0000}, // 1: Solid color test pattern,
+ // 2: Full color bar test pattern,
+ // 3: Fade to grey color bar test pattern,
+@@ -28,10 +26,12 @@ static const struct ar0233_reg ar0233_regs_wizard_rev1[] = {
+ #ifdef AR0233_DISPLAY_PATTERN_COLOR_BAR
+ {0x3070, 0x0002},
+ #endif
+-{AR0233_DELAY, 100}, // Wait 100ms
++{AR0233_DELAY, 100},
++{ }
++}; /* Reset */
+
+-#if 1 /* Sequencer Settings */
+-#if 1 /* Design_recommended_settings_v5 */
++static const struct ar0233_reg ar0233_rev1_Sequencer_Settings[] = {
++/* Design_recommended_settings_v5 */
+ {0x356C, 0xEA55}, //mte.Sensor.Register("DAC_LD_108_109").Value = 0xEA55& -- ADC write Memory delay 7
+ {0x3566, 0x2407}, //mte.Sensor.Register("DAC_LD_102_103").Value = 0x2407& -- Enable column amp bypass for 1x
+ {0x3562, 0x1C08}, //mte.Sensor.Register("DAC_LD_98_99").Value = 0x1C08& -- Increase column amp current
+@@ -51,9 +51,9 @@ static const struct ar0233_reg ar0233_regs_wizard_rev1[] = {
+ {0x353C, 0x9A0A}, //Boost_ref_Vaa lfm_dcghi(1)
+ {0x3526, 0x9000}, //DWellhi(16)
+ {0x352E, 0x90D}, //Dlfm_Dcghi(13),(Dlfm_Txhi_Buffer) = 9
+-#endif /* Design_recommended_settings_v5 */
++/* Design_recommended_settings_v5 */
+
+-#if 1 /* Pixel_char_recommended_settings_v2 */
++/* Pixel_char_recommended_settings_v2 */
+ //TXLO @HCG
+ {0x3514, 0x555B}, //-0.85V
+ {0x3578, 0x555B}, //-0.85V
+@@ -68,9 +68,9 @@ static const struct ar0233_reg ar0233_regs_wizard_rev1[] = {
+ {0x3528, 0xEB0D}, //Ddcghi(13), txhi(11)
+ //DRSTHI, DRSHI
+ {0x352A, 0xA27}, //Drsthi (10), Drshi(7)
+-#endif /* Pixel_char_recommended_settings_v2 */
++/* Pixel_char_recommended_settings_v2 */
+
+-#if 1 /* AR0233_Sequencer_LFM_HDR_v6 */
++/* Sequencer_LFM_HDR_v6 */
+ {0x2512, 0x8000},
+ {0x2510, 0x070f},
+ {0x2510, 0x1011},
+@@ -1096,17 +1096,29 @@ static const struct ar0233_reg ar0233_regs_wizard_rev1[] = {
+ {0x2510, 0xffff},
+ {0x2510, 0xffff},
+ {AR0233_DELAY, 100},
+-#endif /* AR0233_Sequencer_LFM_HDR_v6 */
+-#endif /* Sequencer Settings */
++/* Sequencer_LFM_HDR_v6 */
++{ }
++}; /* Sequencer_Settings */
++
++static const struct ar0233_reg ar0233_rev1_HDR_3exp_12bit[] = {
++{0x3082, 0x8}, //num_exp = 3
++{0x3110, 0x11}, //Set bypass pix comb for HDR,Pre_hdr_gain_enable_07Jul
++{0x30BA, 0x1122}, //num_exp_max =3
++{0x31AC, 0x140C}, //12 bit output
++{0x31D0, 0x1}, // Companding
+
+-{0x3082, 0x8}, //0x3082 = 2, 3 exposures
+-{0x3110, 0x11}, //Set bypass pix comb for HDR,Pre_hdr_gain_enable_07Jul
+-{0x30BA, 0x1122}, //Num_exp_max
++{0x3044, 0x0400}, //Dark_control
++
++// FPS = 103.5MHz / reg0x300A / reg0x300C
++{0x300A, AR0233_SENSOR_HEIGHT + 100}, // Frame_length_Lines
++{0x300C, AR0233_SENSOR_WIDTH + 400}, // Line_length_pck
+ {0x3012, 0x144}, //Integration_time
++{ }
++}; /* HDR_3exp_12bit */
+
+-#if 1 /* Serial 12-bit Timing Setup_108Mhz */
+-/* PCLK=24Mhz/PRE_PLL_CLK_DIV *PLL_MULTIPLIER /P1 /P4 */
+-/* PCLK=24Mhz/2 *54/1/6= 108Mhz - TI serializers */
++static const struct ar0233_reg ar0233_rev1_Serial_12bit_Timing_Setup_103p5[] = {
++/* PCLK=DES_REFCLK /PRE_PLL_CLK_DIV *PLL_MULTIPLIER /P1 /P4 */
++/* PCLK=23MHz/2 *54/1/6= 103.5Mhz - TI serializers */
+ {0x3030, 54}, //PLL_MULTIPLIER ; 0x3030 [11:0]
+ {0x302E, 2}, //PRE_PLL_CLK_DIV ; 0x302E [5:0]
+ {0x302C, 1}, //P1 divider (vt_sys_clk_div)
+@@ -1114,9 +1126,10 @@ static const struct ar0233_reg ar0233_regs_wizard_rev1[] = {
+ {0x3038, 2}, //P3 divider (op_sys_clk_div); 0x3038 [4:0]
+ {0x3036, 6}, //P4 divider (op_word_clk_div); 0x3036 [4:0]
+ {0x31DC, 0x1FB0},
+-#endif /* Serial 12-bit Timing Setup_108Mhz */
++{ }
++}; /* Serial_12bit_Timing_Setup_103p5 */
+
+-#if 1 /* MIPI 4 Lane 12BITS 30FPS_ext24_LIM */
++static const struct ar0233_reg ar0233_rev1_MIPI_4Lane_12BITS[] = {
+ {0x31AE, 0x204}, //MIPI enable, 4 lanes
+ {0x31B0, 0x4B}, //frame_preamble
+ {0x31B2, 0x33}, //line_preamble
+@@ -1125,46 +1138,43 @@ static const struct ar0233_reg ar0233_regs_wizard_rev1[] = {
+ {0x31B8, 0x4047}, //mipi_timing_2
+ {0x31BA, 0x105}, //mipi_timing_3
+ {0x31BC, 0x704}, //mipi_timing_4
+-#endif /* MIPI 4 Lane 12BITS 30FPS_ext24_LIM */
+-
+-#if 1 /* MIPI_DT_bit12 */
+ {0x3342, 0x122C}, // MIPI_F1_PDT_EDT
+ {0x3346, 0x122C}, // MIPI_F2_PDT_EDT
+ {0x334A, 0x122C}, // MIPI_F3_PDT_EDT
+ {0x334E, 0x122C}, // MIPI_F4_PDT_EDT
+-#endif /* MIPI_DT_bit12 */
++{ }
++}; /* MIPI_4Lane_12BITS */
+
+-/* resolution */
++static const struct ar0233_reg ar0233_rev1_Full_resolution[] = {
+ {0x3004, AR0233_X_START}, // X_ADDR_START_
+ {0x3008, AR0233_X_END}, // X_ADDR_END_
+ {0x3002, AR0233_Y_START}, // Y_ADDR_START_
+ {0x3006, AR0233_Y_END}, // Y_ADDR_END_
++{0x3402, (0x8000 & 0) | AR0233_MAX_WIDTH}, // X_OUTPUT_CONTROL
++{0x3404, (0x8000 & 0) | AR0233_MAX_HEIGHT}, // Y_OUTPUT_CONTROL
++{ }
++}; /* Full_resolution */
+
++static const struct ar0233_reg ar0233_rev1_disable_embed_data_stat[] = {
+ #ifdef AR0233_EMBEDDED_LINE
+ {0x3040, 0x0000}, //Embedded stat2 and data2 rows
+ {0x3064, 0x0180}, //Enable embedded data and stat
+ #else
+ {0x3064, 0x0}, //Disable embedded data and stat
+ #endif
++{ }
++}; /* disable_embed_data_stat */
+
+-// FPS = 108MHz / reg0x300A / reg0x300C * (DES_REF_XTAL/24MHz)
+-{0x300A, AR0233_SENSOR_HEIGHT + 100}, // Frame_length_Lines
+-{0x300C, AR0233_SENSOR_WIDTH + 400}, // Line_length_pck
+-//{0x300C, 0x960}, //Line_lenth_pck_FRN AEF
+-//{0x300A, 0x5DC}, //FLL
+-
+-#if 1 /* Gain_3.28x */
++static const struct ar0233_reg ar0233_rev1_Gain_3p28x[] = {
+ {0x3022, 0x01}, // GROUPED_PARAMETER_HOLD_
+ {0x3362, 0x000F}, // DC_GAIN
+ {0x3366, 0x1111},
+ {0x336A, 0x0000},
+ {0x3022, 0x00}, // GROUPED_PARAMETER_HOLD_
+-#endif /* Gain_3.28x */
++{ }
++}; /* Gain_3.28x */
+
+-{0x31D0, 0x1}, // Companding
+-{0x31AC, 0x140C}, // DLO20 to 12output
+-
+-#if 1 /* MEC DLO default */
++static const struct ar0233_reg ar0233_rev1_MEC_DLO_default[] = {
+ {0x3D00, 0x6F73}, // control
+ {0x3D02, 0x0033},
+ {0x3364, 0x068C}, // dcg_trim = 13.1
+@@ -1246,5 +1256,19 @@ static const struct ar0233_reg ar0233_regs_wizard_rev1[] = {
+ {0x3D12, 0x0798},
+ {0x3D14, 0x001E},
+ {0x3D16, 0x045E},
+-#endif /* MEC DLO default */
++{ }
++}; /* MEC_DLO_default */
++
++/* 3Exp HDR, 1280P, MIPI 4-lane 12-bit, 30fps, EXTCLK=23MHz (comes from deser) */
++static const struct ar0233_reg *ar0233_regs_hdr_mipi_12bit_30fps_rev1[] = {
++ ar0233_rev1_Reset,
++ ar0233_rev1_Sequencer_Settings,
++ ar0233_rev1_disable_embed_data_stat,
++ ar0233_rev1_HDR_3exp_12bit,
++ ar0233_rev1_Serial_12bit_Timing_Setup_103p5,
++ ar0233_rev1_MIPI_4Lane_12BITS,
++ ar0233_rev1_Full_resolution,
++ ar0233_rev1_Gain_3p28x,
++ ar0233_rev1_MEC_DLO_default,
++ NULL,
+ };
+diff --git a/drivers/media/i2c/soc_camera/ar0233_rev2.h b/drivers/media/i2c/soc_camera/ar0233_rev2.h
+index 0dea2dd..c821d35 100644
+--- a/drivers/media/i2c/soc_camera/ar0233_rev2.h
++++ b/drivers/media/i2c/soc_camera/ar0233_rev2.h
+@@ -1,7 +1,7 @@
+ /*
+ * ON Semiconductor AR0233 sensor camera wizard 2048x1280@30/BGGR/MIPI
+ *
+- * Copyright (C) 2018 Cogent Embedded, Inc.
++ * Copyright (C) 2018-2019 Cogent Embedded, Inc.
+ *
+ * This program is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License as published by the
+@@ -9,31 +9,9 @@
+ * option) any later version.
+ */
+
+-#define O1_Recommended_Defaults_LFM_HDR
+-#ifdef O1_Recommended_Defaults_LFM_HDR
+- #define Design_recommended_settings_REV2_V9
+- #define Sequence_hidy_ar0233_REV2_V13
+- #define Pre_hdr_gain_enable
+- #define Tempsensor_init
+-#endif
+-#define disable_embed_data_stat
+-#define HDR_3exp_12bit
+-#if 0
+- #define pll_27_108_4lane_12b
+- #define mipi_108_12bit_4lane
+-#else
+- #define pll_27_124p5_4lane_12b
+- #define mipi_124p5_12bit_4lane
+-#endif
+-#define MIPI_DT_bit12
+-#define LUT_24_to_12
+-#define HDR_ratio_gain_default
+-
+-/* 3Exp HDR 1280P Mipi_12bit_4lane_30fps, XCLK=27MHz */
+-static const struct ar0233_reg ar0233_regs_wizard_rev2[] = {
+-{0x301A, 0x18}, // MIPI, stream OFF
+-{AR0233_DELAY, 200}, // Wait 200ms
+-
++static const struct ar0233_reg ar0233_rev2_Reset[] = {
++{0x301A, 0x0018}, // Stream off and setup MIPI
++{AR0233_DELAY, 200},
+ {0x3070, 0x0000}, // 1: Solid color test pattern,
+ // 2: Full color bar test pattern,
+ // 3: Fade to grey color bar test pattern,
+@@ -48,10 +26,12 @@ static const struct ar0233_reg ar0233_regs_wizard_rev2[] = {
+ #ifdef AR0233_DISPLAY_PATTERN_COLOR_BAR
+ {0x3070, 0x0002},
+ #endif
+-{AR0233_DELAY, 100}, // Wait 100ms
++{AR0233_DELAY, 100},
++{ }
++}; /* Reset */
+
+-#ifdef O1_Recommended_Defaults_LFM_HDR
+-#ifdef Design_recommended_settings_REV2_V9
++static const struct ar0233_reg ar0233_rev2_O1_Recommended_Defaults_LFM_HDR[] = {
++/* Design_recommended_settings_REV2_V9 */
+ {0x3C72, 0x0076},
+ {0x3C74, 0x0031},
+ {0x3C76, 0x00DC},
+@@ -99,9 +79,9 @@ static const struct ar0233_reg ar0233_regs_wizard_rev2[] = {
+ {0x352A, 0x0827},
+ {0x352C, 0xA800},
+ {0x352E, 0x0908},
+-#endif /* Design_recommended_settings_REV2_V9 */
++/* Design_recommended_settings_REV2_V9 */
+
+-#ifdef Sequence_hidy_ar0233_REV2_V13
++/* Sequence_hidy_ar0233_REV2_V13 */
+ {0x2512, 0x8000},
+ {0x2510, 0x070f},
+ {0x2510, 0x1011},
+@@ -1127,71 +1107,74 @@ static const struct ar0233_reg ar0233_regs_wizard_rev2[] = {
+ {0x2510, 0x3426},
+ {0x2510, 0x3614},
+ {AR0233_DELAY, 100},
+-#endif /* Sequence_hidy_ar0233_REV2_V13 */
++/* Sequence_hidy_ar0233_REV2_V13 */
+
+-#ifdef Pre_hdr_gain_enable
++/* Pre_hdr_gain_enable */
+ {0x3110, 0x0011},
+-#endif /* Pre_hdr_gain_enable */
+
+-#ifdef Tempsensor_init
++/* Tempsensor_init */
+ {0x3E94, 0x3007},
+ {0x3E6E, 0xE200},
+ {0x3E98, 0x1000},
+ {0x3F92, 0x4C00},
+ {0x30B8, 0x000B},
+ {0x30B8, 0x0003},
+-#endif /* Tempsensor_init */
+
+ {0x3364, 0x0766}, //14.8
+-#endif /* O1_Recommended_Defaults_LFM_HDR */
++{ }
++}; /* O1_Recommended_Defaults_LFM_HDR */
+
+-#ifdef disable_embed_data_stat
++static const struct ar0233_reg ar0233_rev2_disable_embed_data_stat[] = {
+ {0x3064, 0x0}, // Disable embedded data and stat
+-#endif /* disable_embed_data_stat */
++#ifdef AR0233_EMBEDDED_LINE
++{0x3064, 0x0180}, // SMIA_TEST: enable emb data and stats
++#endif
++{ }
++}; /* disable_embed_data_stat */
+
+-#ifdef HDR_3exp_12bit
++static const struct ar0233_reg ar0233_rev2_HDR_3exp_12bit[] = {
+ {0x3082, 0x8}, //num_exp = 3
+ {0x30BA, 0x1122}, //num_exp_max =3
+ {0x31AC, 0x140C}, //12 bit output
+-#endif /* HDR_3exp_12bit */
+
+-#ifdef pll_27_124p5_4lane_12b
++{0x3044, 0x0400}, //Dark_control
++
++// FPS = 102MHz / reg0x300A / reg0x300C
++{0x300A, AR0233_SENSOR_HEIGHT + 100}, // Frame_length_Lines
++{0x300C, AR0233_SENSOR_WIDTH + 400}, // Line_length_pck
++{0x3012, 0x144}, //Integration_time
++{ }
++}; /* HDR_3exp_12bit */
++
++static const struct ar0233_reg ar0233_rev2_pll_23_102_4lane_12b[] = {
+ // serial_data_rate was *2 in REV1. but not in REV2
+-{0x3030, 0x53}, //PLL_MULTIPLIER
++/* PCLK=DES_REFCLK/PRE_PLL_CLK_DIV *PLL_MULTIPLIER /P1 /P4 */
++/* PCLK=23Mhz/0x3 *0x50/1/6= 102Mhz - TI serializers */
++{0x3030, 0x50}, //PLL_MULTIPLIER
+ {0x302E, 0x3}, //PRE_PLL_CLK_DIV
+ {0x302C, 0x701}, //P1 divider (vt_sys_clk_div)
+ {0x302A, 0x6}, //P2 divider (vt_pix_clk_div)
+ {0x3038, 0x2}, //P3 divider (op_sys_clk_div)
+ {0x3036, 0x6}, //P4 divider (op_word_clk_div)
+ {0x31DC, 0x1FB0}, //vcodiv
+-#endif /* pll_27_124p5_4lane_12b */
+-
+-#ifdef mipi_124p5_12bit_4lane
+-{0x31AE, 0x204}, //serial type and lane
+-{0x31B0, 0x67}, //frame_preamble
+-{0x31B2, 0x30}, //line_preamble
+-{0x31B4, 0x22CC}, //mipi_timing_0
+-{0x31B6, 0x33D3}, //mipi_timing_1
+-{0x31B8, 0xB04D}, //mipi_timing_2
+-{0x31BA, 0x411}, //mipi_timing_3
+-{0x31BC, 0x940E}, //mipi_timing_4
+-#endif /* mipi_124p5_12bit_4lane */
++{ }
++}; /* pll_23_102_4lane_12b */
+
+-#ifdef pll_27_108_4lane_12b
++static const struct ar0233_reg ar0233_rev2_pll_27_102_4lane_12b[] = {
+ // serial_data_rate was *2 in REV1. but not in REV2
+-/* PCLK=27Mhz/PRE_PLL_CLK_DIV *PLL_MULTIPLIER /P1 /P4 */
+-/* PCLK=27Mhz/0x3 *0x48/1/6= 108Mhz - TI serializers */
+-{0x3030, 0x48}, //PLL_MULTIPLIER
++/* PCLK=27Mhz/0x3 *0x44/1/6= 102Mhz - TI serializers */
++{0x3030, 0x44}, //PLL_MULTIPLIER
+ {0x302E, 0x3}, //PRE_PLL_CLK_DIV
+ {0x302C, 0x701}, //P1 divider (vt_sys_clk_div)
+ {0x302A, 0x6}, //P2 divider (vt_pix_clk_div)
+ {0x3038, 0x2}, //P3 divider (op_sys_clk_div)
+ {0x3036, 0x6}, //P4 divider (op_word_clk_div)
+ {0x31DC, 0x1FB0}, //vcodiv
+-#endif /* pll_27_108_4lane_12b */
++{ }
++}; /* pll_27_102_4lane_12b */
+
+-#ifdef mipi_108_12bit_4lane
+-{0x31AE, 0x204}, //MIPI_enable
++static const struct ar0233_reg ar0233_rev2_mipi_12bit_4lane[] = {
++{0x31AE, 0x204}, //serial type and lane
+ {0x31B0, 0x67}, //frame_preamble
+ {0x31B2, 0x30}, //line_preamble
+ {0x31B4, 0x22CC}, //mipi_timing_0
+@@ -1199,16 +1182,14 @@ static const struct ar0233_reg ar0233_regs_wizard_rev2[] = {
+ {0x31B8, 0xB04D}, //mipi_timing_2
+ {0x31BA, 0x411}, //mipi_timing_3
+ {0x31BC, 0x940E}, //mipi_timing_4
+-#endif /* mipi_108_12bit_4lane */
+-
+-#ifdef MIPI_DT_bit12
+ {0x3342, 0x122C}, // MIPI_F1_PDT_EDT
+ {0x3346, 0x122C}, // MIPI_F2_PDT_EDT
+ {0x334A, 0x122C}, // MIPI_F3_PDT_EDT
+ {0x334E, 0x122C}, // MIPI_F4_PDT_EDT
+-#endif /* MIPI_DT_bit12 */
++{ }
++}; /* mipi_12bit_4lane */
+
+-#ifdef LUT_24_to_12
++static const struct ar0233_reg ar0233_rev2_LUT_24_to_12[] = {
+ {0x31AC, 0x180C},
+ {0x31D0, 0x01}, //companding
+ {0x33DA, 0},
+@@ -1228,24 +1209,36 @@ static const struct ar0233_reg ar0233_regs_wizard_rev2[] = {
+ {0x33F6, 0xFF70},
+ {0x33F8, 0xFF70},
+ {0x33FA, 0xFF70}, //LUT_15
+-#endif /* LUT_24_to_12 */
++{ }
++}; /* LUT_24_to_12 */
+
+-/* resolution */
++static const struct ar0233_reg ar0233_rev2_Full_resolution[] = {
+ {0x3004, AR0233_X_START}, // X_ADDR_START_
+ {0x3008, AR0233_X_END}, // X_ADDR_END_
+ {0x3002, AR0233_Y_START}, // Y_ADDR_START_
+ {0x3006, AR0233_Y_END}, // Y_ADDR_END_
++{0x3402, (0x8000 & 0) | AR0233_MAX_WIDTH}, // X_OUTPUT_CONTROL
++{0x3404, (0x8000 & 0) | AR0233_MAX_HEIGHT}, // Y_OUTPUT_CONTROL
++{ }
++}; /* Full_resolution */
+
+-{0x3044, 0x0400}, //Dark_control
+-
+-#ifdef HDR_ratio_gain_default
++static const struct ar0233_reg ar0233_rev2_HDR_ratio_gain_default[] = {
+ {0x3362, 0x000F}, //HCG
+ {0x3366, 0x1111}, //1x
+ {0x3238, 0x0444}, // Ratio 16x, Use retio setting
+-#endif /* HDR_ratio_gain_default */
++{ }
++}; /* HDR_ratio_gain_default */
+
+-// FPS = 124.5MHz / reg0x300A / reg0x300C * (DES_REF_XTAL/27MHz)
+-{0x300A, AR0233_SENSOR_HEIGHT + 100}, // Frame_length_Lines
+-{0x300C, AR0233_SENSOR_WIDTH + 400}, // Line_length_pck
+-{0x3012, 0x144}, //Integration_time
++/* 3Exp HDR, 1280P, MIPI 4-lane 12-bit, 30fps, EXTCLK=23MHz (comes from deser) */
++static const struct ar0233_reg *ar0233_regs_hdr_mipi_12bit_30fps_rev2[] = {
++ ar0233_rev2_Reset,
++ ar0233_rev2_O1_Recommended_Defaults_LFM_HDR,
++ ar0233_rev2_disable_embed_data_stat,
++ ar0233_rev2_HDR_3exp_12bit,
++ ar0233_rev2_pll_23_102_4lane_12b,
++ ar0233_rev2_mipi_12bit_4lane,
++ ar0233_rev2_LUT_24_to_12,
++ ar0233_rev2_Full_resolution,
++ ar0233_rev2_HDR_ratio_gain_default,
++ NULL,
+ };
+--
+2.7.4
+
diff --git a/bsp/meta-rcar/meta-rcar-gen3-adas/recipes-kernel/linux/linux-renesas/0163-lvds-AP0101-AR014X-add-TI-serializers.patch b/bsp/meta-rcar/meta-rcar-gen3-adas/recipes-kernel/linux/linux-renesas/0163-lvds-AP0101-AR014X-add-TI-serializers.patch
new file mode 100644
index 00000000..568e8843
--- /dev/null
+++ b/bsp/meta-rcar/meta-rcar-gen3-adas/recipes-kernel/linux/linux-renesas/0163-lvds-AP0101-AR014X-add-TI-serializers.patch
@@ -0,0 +1,76 @@
+From f0063d3e6918319b9817e2074bcf0ffefde1e2ea Mon Sep 17 00:00:00 2001
+From: Vladimir Barinov <vladimir.barinov@cogentembedded.com>
+Date: Tue, 7 May 2019 13:00:24 +0300
+Subject: [PATCH 112/122] lvds: AP0101-AR014X: add TI serializers
+
+Add TI UB913 support
+
+Signed-off-by: Vladimir Barinov <vladimir.barinov@cogentembedded.com>
+---
+ drivers/media/i2c/soc_camera/ap0101_ar014x.c | 23 ++++++++++++++++++++---
+ 1 file changed, 20 insertions(+), 3 deletions(-)
+
+diff --git a/drivers/media/i2c/soc_camera/ap0101_ar014x.c b/drivers/media/i2c/soc_camera/ap0101_ar014x.c
+index 142942d..e4f2bda 100644
+--- a/drivers/media/i2c/soc_camera/ap0101_ar014x.c
++++ b/drivers/media/i2c/soc_camera/ap0101_ar014x.c
+@@ -46,6 +46,8 @@ struct ap0101_priv {
+ /* serializers */
+ int max9286_addr;
+ int max9271_addr;
++ int ti9x4_addr;
++ int ti9x3_addr;
+ int port;
+ int gpio_resetb;
+ int gpio_fsin;
+@@ -390,10 +392,13 @@ static int ap0101_initialize(struct i2c_client *client)
+ int tmp_addr;
+ int i;
+
+- ap0101_s_port(client, 1);
+-
+ for (i = 0; i < ARRAY_SIZE(ap0101_i2c_addr); i++) {
+ tmp_addr = client->addr;
++ if (priv->ti9x4_addr) {
++ client->addr = priv->ti9x4_addr; /* Deserializer I2C address */
++ reg8_write(client, 0x5d, ap0101_i2c_addr[i] << 1); /* Sensor native I2C address */
++ usleep_range(2000, 2500); /* wait 2ms */
++ }
+ if (priv->max9286_addr) {
+ client->addr = priv->max9271_addr; /* Serializer I2C address */
+ reg8_write(client, 0x0A, ap0101_i2c_addr[i] << 1); /* Sensor native I2C address */
+@@ -478,11 +483,17 @@ static int ap0101_parse_dt(struct device_node *np, struct ap0101_priv *priv)
+ !of_property_read_u32(rendpoint->parent->parent, "reg", &priv->max9286_addr) &&
+ !kstrtouint(strrchr(rendpoint->full_name, '@') + 1, 0, &priv->port))
+ break;
++
++ if (!of_property_read_u32(rendpoint, "ti9x3-addr", &priv->ti9x3_addr) &&
++ !of_property_match_string(rendpoint->parent->parent, "compatible", "ti,ti9x4") &&
++ !of_property_read_u32(rendpoint->parent->parent, "reg", &priv->ti9x4_addr) &&
++ !kstrtouint(strrchr(rendpoint->full_name, '@') + 1, 0, &priv->port))
++ break;
+ }
+
+ of_node_put(endpoint);
+
+- if (!priv->max9286_addr) {
++ if (!priv->max9286_addr && !priv->ti9x4_addr) {
+ dev_err(&client->dev, "deserializer does not present for AP0101\n");
+ return -EINVAL;
+ }
+@@ -496,6 +507,12 @@ static int ap0101_parse_dt(struct device_node *np, struct ap0101_priv *priv)
+ reg8_write(client, 0x09, tmp_addr << 1); /* Sensor translated I2C address */
+ usleep_range(2000, 2500); /* wait 2ms */
+ };
++ if (priv->ti9x4_addr) {
++ client->addr = priv->ti9x4_addr; /* Deserializer I2C address */
++ reg8_write(client, 0x4c, (priv->port << 4) | (1 << priv->port)); /* Select RX port number */
++ usleep_range(2000, 2500); /* wait 2ms */
++ reg8_write(client, 0x65, tmp_addr << 1); /* Sensor translated I2C address */
++ }
+ client->addr = tmp_addr;
+
+ mdelay(10);
+--
+2.7.4
+
diff --git a/bsp/meta-rcar/meta-rcar-gen3-adas/recipes-kernel/linux/linux-renesas/0164-lvds-fix-vendor-names.patch b/bsp/meta-rcar/meta-rcar-gen3-adas/recipes-kernel/linux/linux-renesas/0164-lvds-fix-vendor-names.patch
new file mode 100644
index 00000000..14e9aa3f
--- /dev/null
+++ b/bsp/meta-rcar/meta-rcar-gen3-adas/recipes-kernel/linux/linux-renesas/0164-lvds-fix-vendor-names.patch
@@ -0,0 +1,125 @@
+From b7c746dad25e649fc4990805c12b2f51817acf0c Mon Sep 17 00:00:00 2001
+From: Vladimir Barinov <vladimir.barinov@cogentembedded.com>
+Date: Tue, 7 May 2019 18:11:34 +0300
+Subject: [PATCH 113/122] lvds: fix vendor names
+
+Fix vendor names
+
+Signed-off-by: Vladimir Barinov <vladimir.barinov@cogentembedded.com>
+---
+ drivers/media/i2c/soc_camera/gw4200_ar014x.c | 4 ++--
+ drivers/media/i2c/soc_camera/imx390.c | 2 +-
+ drivers/media/i2c/soc_camera/imx390.h | 2 +-
+ drivers/media/i2c/soc_camera/isx016.c | 4 ++--
+ drivers/media/i2c/soc_camera/isx016.h | 2 +-
+ drivers/media/i2c/soc_camera/isx019.c | 4 ++--
+ drivers/media/i2c/soc_camera/isx019.h | 2 +-
+ 7 files changed, 10 insertions(+), 10 deletions(-)
+
+diff --git a/drivers/media/i2c/soc_camera/gw4200_ar014x.c b/drivers/media/i2c/soc_camera/gw4200_ar014x.c
+index 2de6fe7..674e409 100644
+--- a/drivers/media/i2c/soc_camera/gw4200_ar014x.c
++++ b/drivers/media/i2c/soc_camera/gw4200_ar014x.c
+@@ -1,5 +1,5 @@
+ /*
+- * ON Semiconductor GW4200-AR014X sensor camera driver
++ * GEO Semiconductor GW4200-AR014X sensor camera driver
+ *
+ * Copyright (C) 2018 Cogent Embedded, Inc.
+ *
+@@ -569,7 +569,7 @@ static const struct i2c_device_id gw4200_id[] = {
+ MODULE_DEVICE_TABLE(i2c, gw4200_id);
+
+ static const struct of_device_id gw4200_of_ids[] = {
+- { .compatible = "aptina,gw4200", },
++ { .compatible = "geosemi,gw4200", },
+ { }
+ };
+ MODULE_DEVICE_TABLE(of, gw4200_of_ids);
+diff --git a/drivers/media/i2c/soc_camera/imx390.c b/drivers/media/i2c/soc_camera/imx390.c
+index 1834195..7171d70 100644
+--- a/drivers/media/i2c/soc_camera/imx390.c
++++ b/drivers/media/i2c/soc_camera/imx390.c
+@@ -1,5 +1,5 @@
+ /*
+- * OmniVision IMX390 sensor camera driver
++ * Sony IMX390 sensor camera driver
+ *
+ * Copyright (C) 2018 Cogent Embedded, Inc.
+ *
+diff --git a/drivers/media/i2c/soc_camera/imx390.h b/drivers/media/i2c/soc_camera/imx390.h
+index a7189e8..efd75a7 100644
+--- a/drivers/media/i2c/soc_camera/imx390.h
++++ b/drivers/media/i2c/soc_camera/imx390.h
+@@ -1,5 +1,5 @@
+ /*
+- * OmniVision IMX390 sensor camera wizard 1920x1080@30/BGGR/MIPI
++ * Sony IMX390 sensor camera wizard 1920x1080@30/BGGR/MIPI
+ *
+ * Copyright (C) 2018 Cogent Embedded, Inc.
+ *
+diff --git a/drivers/media/i2c/soc_camera/isx016.c b/drivers/media/i2c/soc_camera/isx016.c
+index 4002008..eab155c 100644
+--- a/drivers/media/i2c/soc_camera/isx016.c
++++ b/drivers/media/i2c/soc_camera/isx016.c
+@@ -1,5 +1,5 @@
+ /*
+- * ON Semiconductor ISX016 (isp) camera driver
++ * Sony ISX016 (isp) camera driver
+ *
+ * Copyright (C) 2019 Cogent Embedded, Inc.
+ *
+@@ -581,7 +581,7 @@ static const struct i2c_device_id isx016_id[] = {
+ MODULE_DEVICE_TABLE(i2c, isx016_id);
+
+ static const struct of_device_id isx016_of_ids[] = {
+- { .compatible = "aptina,isx016", },
++ { .compatible = "sony,isx016", },
+ { }
+ };
+ MODULE_DEVICE_TABLE(of, isx016_of_ids);
+diff --git a/drivers/media/i2c/soc_camera/isx016.h b/drivers/media/i2c/soc_camera/isx016.h
+index 8ca35a10..379766f 100644
+--- a/drivers/media/i2c/soc_camera/isx016.h
++++ b/drivers/media/i2c/soc_camera/isx016.h
+@@ -1,5 +1,5 @@
+ /*
+- * ON Semiconductor isx016 (isp) camera wizard 1280x960@30/UYVY/BT601/8bit
++ * Sony isx016 (isp) camera wizard 1280x960@30/UYVY/BT601/8bit
+ *
+ * Copyright (C) 2019 Cogent Embedded, Inc.
+ *
+diff --git a/drivers/media/i2c/soc_camera/isx019.c b/drivers/media/i2c/soc_camera/isx019.c
+index 8064789..650b533 100644
+--- a/drivers/media/i2c/soc_camera/isx019.c
++++ b/drivers/media/i2c/soc_camera/isx019.c
+@@ -1,5 +1,5 @@
+ /*
+- * ON Semiconductor ISX019 (isp) camera driver
++ * Sony ISX019 (isp) camera driver
+ *
+ * Copyright (C) 2018 Cogent Embedded, Inc.
+ *
+@@ -605,7 +605,7 @@ static const struct i2c_device_id isx019_id[] = {
+ MODULE_DEVICE_TABLE(i2c, isx019_id);
+
+ static const struct of_device_id isx019_of_ids[] = {
+- { .compatible = "aptina,isx019", },
++ { .compatible = "sony,isx019", },
+ { }
+ };
+ MODULE_DEVICE_TABLE(of, isx019_of_ids);
+diff --git a/drivers/media/i2c/soc_camera/isx019.h b/drivers/media/i2c/soc_camera/isx019.h
+index 0593be1..edaa767 100644
+--- a/drivers/media/i2c/soc_camera/isx019.h
++++ b/drivers/media/i2c/soc_camera/isx019.h
+@@ -1,5 +1,5 @@
+ /*
+- * ON Semiconductor isx019 (isp) camera wizard 1280x800@30/UYVY/BT601/8bit
++ * Sony isx019 (isp) camera wizard 1280x800@30/UYVY/BT601/8bit
+ *
+ * Copyright (C) 2018 Cogent Embedded, Inc.
+ *
+--
+2.7.4
+
diff --git a/bsp/meta-rcar/meta-rcar-gen3-adas/recipes-kernel/linux/linux-renesas/0165-LVDS-add-GW5200-IMX390-camera.patch b/bsp/meta-rcar/meta-rcar-gen3-adas/recipes-kernel/linux/linux-renesas/0165-LVDS-add-GW5200-IMX390-camera.patch
new file mode 100644
index 00000000..92456a06
--- /dev/null
+++ b/bsp/meta-rcar/meta-rcar-gen3-adas/recipes-kernel/linux/linux-renesas/0165-LVDS-add-GW5200-IMX390-camera.patch
@@ -0,0 +1,673 @@
+From ef4f0fb34567958cba956e2292216e370fc982c1 Mon Sep 17 00:00:00 2001
+From: Vladimir Barinov <vladimir.barinov@cogentembedded.com>
+Date: Tue, 7 May 2019 19:30:06 +0300
+Subject: [PATCH 114/122] LVDS: add GW5200-IMX390 camera
+
+This add GW5200 isp with IMX390 imager
+
+Signed-off-by: Vladimir Barinov <vladimir.barinov@cogentembedded.com>
+---
+ drivers/media/i2c/soc_camera/gw5200_imx390.c | 574 +++++++++++++++++++++++++++
+ drivers/media/i2c/soc_camera/gw5200_imx390.h | 25 ++
+ drivers/media/i2c/soc_camera/ov106xx.c | 11 +
+ 3 files changed, 610 insertions(+)
+ create mode 100644 drivers/media/i2c/soc_camera/gw5200_imx390.c
+ create mode 100644 drivers/media/i2c/soc_camera/gw5200_imx390.h
+
+diff --git a/drivers/media/i2c/soc_camera/gw5200_imx390.c b/drivers/media/i2c/soc_camera/gw5200_imx390.c
+new file mode 100644
+index 0000000..0703c3d
+--- /dev/null
++++ b/drivers/media/i2c/soc_camera/gw5200_imx390.c
+@@ -0,0 +1,574 @@
++/*
++ * GEO Semiconductor GW5200-IMX390 sensor camera driver
++ *
++ * Copyright (C) 2019 Cogent Embedded, Inc.
++ *
++ * This program is free software; you can redistribute it and/or modify it
++ * under the terms of the GNU General Public License as published by the
++ * Free Software Foundation; either version 2 of the License, or (at your
++ * option) any later version.
++ */
++
++#include <linux/delay.h>
++#include <linux/init.h>
++#include <linux/i2c.h>
++#include <linux/module.h>
++#include <linux/of_graph.h>
++#include <linux/videodev2.h>
++
++#include <media/soc_camera.h>
++#include <media/v4l2-common.h>
++#include <media/v4l2-ctrls.h>
++
++#include "gw5200_imx390.h"
++
++static const int gw5200_i2c_addr[] = {0x18};
++
++#define GW5200_PID 0x00
++#define GW5200_VERSION_REG 0x30
++
++#define GW5200_MEDIA_BUS_FMT MEDIA_BUS_FMT_YUYV8_2X8
++
++static void gw5200_otp_id_read(struct i2c_client *client);
++
++struct gw5200_priv {
++ struct v4l2_subdev sd;
++ struct v4l2_ctrl_handler hdl;
++ struct media_pad pad;
++ struct v4l2_rect rect;
++ int init_complete;
++ u8 id[6];
++ int exposure;
++ int gain;
++ int autogain;
++ /* serializers */
++ int max9286_addr;
++ int max9271_addr;
++ int ti9x4_addr;
++ int ti9x3_addr;
++ int port;
++ int gpio_resetb;
++ int gpio_fsin;
++};
++
++static inline struct gw5200_priv *to_gw5200(const struct i2c_client *client)
++{
++ return container_of(i2c_get_clientdata(client), struct gw5200_priv, sd);
++}
++
++static void gw5200_s_port(struct i2c_client *client, int fwd_en)
++{
++ struct gw5200_priv *priv = to_gw5200(client);
++ int tmp_addr;
++
++ if (priv->max9286_addr) {
++ tmp_addr = client->addr;
++ client->addr = priv->max9286_addr; /* Deserializer I2C address */
++ reg8_write(client, 0x0a, fwd_en ? 0x11 << priv->port : 0); /* Enable/disable reverse/forward control for this port */
++ usleep_range(5000, 5500); /* wait 5ms */
++ client->addr = tmp_addr;
++ };
++}
++
++#if 0
++static int gw5200_set_regs(struct i2c_client *client,
++ const struct gw5200_reg *regs, int nr_regs)
++{
++ int i;
++
++ for (i = 0; i < nr_regs; i++) {
++ if (regs[i].reg == GW5200_DELAY) {
++ mdelay(regs[i].val);
++ continue;
++ }
++
++ reg16_write16(client, regs[i].reg, regs[i].val);
++ }
++
++ return 0;
++}
++#endif
++
++static int gw5200_s_stream(struct v4l2_subdev *sd, int enable)
++{
++ return 0;
++}
++
++static int gw5200_get_fmt(struct v4l2_subdev *sd,
++ struct v4l2_subdev_pad_config *cfg,
++ struct v4l2_subdev_format *format)
++{
++ struct v4l2_mbus_framefmt *mf = &format->format;
++ struct i2c_client *client = v4l2_get_subdevdata(sd);
++ struct gw5200_priv *priv = to_gw5200(client);
++
++ if (format->pad)
++ return -EINVAL;
++
++ mf->width = priv->rect.width;
++ mf->height = priv->rect.height;
++ mf->code = GW5200_MEDIA_BUS_FMT;
++ mf->colorspace = V4L2_COLORSPACE_SMPTE170M;
++ mf->field = V4L2_FIELD_NONE;
++
++ return 0;
++}
++
++static int gw5200_set_fmt(struct v4l2_subdev *sd,
++ struct v4l2_subdev_pad_config *cfg,
++ struct v4l2_subdev_format *format)
++{
++ struct v4l2_mbus_framefmt *mf = &format->format;
++
++ mf->code = GW5200_MEDIA_BUS_FMT;
++ mf->colorspace = V4L2_COLORSPACE_SMPTE170M;
++ mf->field = V4L2_FIELD_NONE;
++
++ if (format->which == V4L2_SUBDEV_FORMAT_TRY)
++ cfg->try_fmt = *mf;
++
++ return 0;
++}
++
++static int gw5200_enum_mbus_code(struct v4l2_subdev *sd,
++ struct v4l2_subdev_pad_config *cfg,
++ struct v4l2_subdev_mbus_code_enum *code)
++{
++ if (code->pad || code->index > 0)
++ return -EINVAL;
++
++ code->code = GW5200_MEDIA_BUS_FMT;
++
++ return 0;
++}
++
++static int gw5200_get_edid(struct v4l2_subdev *sd, struct v4l2_edid *edid)
++{
++ struct i2c_client *client = v4l2_get_subdevdata(sd);
++ struct gw5200_priv *priv = to_gw5200(client);
++
++ gw5200_otp_id_read(client);
++
++ memcpy(edid->edid, priv->id, 6);
++
++ edid->edid[6] = 0xff;
++ edid->edid[7] = client->addr;
++ edid->edid[8] = GW5200_VERSION_REG >> 8;
++ edid->edid[9] = GW5200_VERSION_REG & 0xff;
++
++ return 0;
++}
++
++static int gw5200_set_selection(struct v4l2_subdev *sd,
++ struct v4l2_subdev_pad_config *cfg,
++ struct v4l2_subdev_selection *sel)
++{
++ struct v4l2_rect *rect = &sel->r;
++ struct i2c_client *client = v4l2_get_subdevdata(sd);
++ struct gw5200_priv *priv = to_gw5200(client);
++
++ if (sel->which != V4L2_SUBDEV_FORMAT_ACTIVE ||
++ sel->target != V4L2_SEL_TGT_CROP)
++ return -EINVAL;
++
++ rect->left = ALIGN(rect->left, 2);
++ rect->top = ALIGN(rect->top, 2);
++ rect->width = ALIGN(rect->width, 2);
++ rect->height = ALIGN(rect->height, 2);
++
++ if ((rect->left + rect->width > GW5200_MAX_WIDTH) ||
++ (rect->top + rect->height > GW5200_MAX_HEIGHT))
++ *rect = priv->rect;
++
++ priv->rect.left = rect->left;
++ priv->rect.top = rect->top;
++ priv->rect.width = rect->width;
++ priv->rect.height = rect->height;
++
++ return 0;
++}
++
++static int gw5200_get_selection(struct v4l2_subdev *sd,
++ struct v4l2_subdev_pad_config *cfg,
++ struct v4l2_subdev_selection *sel)
++{
++ struct i2c_client *client = v4l2_get_subdevdata(sd);
++ struct gw5200_priv *priv = to_gw5200(client);
++
++ if (sel->which != V4L2_SUBDEV_FORMAT_ACTIVE)
++ return -EINVAL;
++
++ switch (sel->target) {
++ case V4L2_SEL_TGT_CROP_BOUNDS:
++ sel->r.left = 0;
++ sel->r.top = 0;
++ sel->r.width = GW5200_MAX_WIDTH;
++ sel->r.height = GW5200_MAX_HEIGHT;
++ return 0;
++ case V4L2_SEL_TGT_CROP_DEFAULT:
++ sel->r.left = 0;
++ sel->r.top = 0;
++ sel->r.width = GW5200_MAX_WIDTH;
++ sel->r.height = GW5200_MAX_HEIGHT;
++ return 0;
++ case V4L2_SEL_TGT_CROP:
++ sel->r = priv->rect;
++ return 0;
++ default:
++ return -EINVAL;
++ }
++}
++
++static int gw5200_g_mbus_config(struct v4l2_subdev *sd,
++ struct v4l2_mbus_config *cfg)
++{
++ cfg->flags = V4L2_MBUS_CSI2_1_LANE | V4L2_MBUS_CSI2_CHANNEL_0 |
++ V4L2_MBUS_CSI2_CONTINUOUS_CLOCK;
++ cfg->type = V4L2_MBUS_CSI2;
++
++ return 0;
++}
++
++#ifdef CONFIG_VIDEO_ADV_DEBUG
++static int gw5200_g_register(struct v4l2_subdev *sd,
++ struct v4l2_dbg_register *reg)
++{
++ struct i2c_client *client = v4l2_get_subdevdata(sd);
++ int ret;
++ u16 val = 0;
++
++ ret = reg16_read16(client, (u16)reg->reg, &val);
++ if (ret < 0)
++ return ret;
++
++ reg->val = val;
++ reg->size = sizeof(u16);
++
++ return 0;
++}
++
++static int gw5200_s_register(struct v4l2_subdev *sd,
++ const struct v4l2_dbg_register *reg)
++{
++ struct i2c_client *client = v4l2_get_subdevdata(sd);
++
++ return reg16_write16(client, (u16)reg->reg, (u16)reg->val);
++}
++#endif
++
++static struct v4l2_subdev_core_ops gw5200_core_ops = {
++#ifdef CONFIG_VIDEO_ADV_DEBUG
++ .g_register = gw5200_g_register,
++ .s_register = gw5200_s_register,
++#endif
++};
++
++static int gw5200_s_ctrl(struct v4l2_ctrl *ctrl)
++{
++ struct v4l2_subdev *sd = to_sd(ctrl);
++ struct i2c_client *client = v4l2_get_subdevdata(sd);
++ struct gw5200_priv *priv = to_gw5200(client);
++ int ret = -EINVAL;
++
++ if (!priv->init_complete)
++ return 0;
++
++ switch (ctrl->id) {
++ case V4L2_CID_BRIGHTNESS:
++ case V4L2_CID_CONTRAST:
++ case V4L2_CID_SATURATION:
++ case V4L2_CID_HUE:
++ case V4L2_CID_GAMMA:
++ case V4L2_CID_SHARPNESS:
++ case V4L2_CID_AUTOGAIN:
++ case V4L2_CID_GAIN:
++ case V4L2_CID_EXPOSURE:
++ case V4L2_CID_HFLIP:
++ case V4L2_CID_VFLIP:
++ break;
++ }
++
++ return ret;
++}
++
++static const struct v4l2_ctrl_ops gw5200_ctrl_ops = {
++ .s_ctrl = gw5200_s_ctrl,
++};
++
++static struct v4l2_subdev_video_ops gw5200_video_ops = {
++ .s_stream = gw5200_s_stream,
++ .g_mbus_config = gw5200_g_mbus_config,
++};
++
++static const struct v4l2_subdev_pad_ops gw5200_subdev_pad_ops = {
++ .get_edid = gw5200_get_edid,
++ .enum_mbus_code = gw5200_enum_mbus_code,
++ .get_selection = gw5200_get_selection,
++ .set_selection = gw5200_set_selection,
++ .get_fmt = gw5200_get_fmt,
++ .set_fmt = gw5200_set_fmt,
++};
++
++static struct v4l2_subdev_ops gw5200_subdev_ops = {
++ .core = &gw5200_core_ops,
++ .video = &gw5200_video_ops,
++ .pad = &gw5200_subdev_pad_ops,
++};
++
++static void gw5200_otp_id_read(struct i2c_client *client)
++{
++}
++
++static ssize_t gw5200_otp_id_show(struct device *dev,
++ struct device_attribute *attr, char *buf)
++{
++ struct v4l2_subdev *sd = i2c_get_clientdata(to_i2c_client(dev));
++ struct i2c_client *client = v4l2_get_subdevdata(sd);
++ struct gw5200_priv *priv = to_gw5200(client);
++
++ gw5200_otp_id_read(client);
++
++ return snprintf(buf, 32, "%02x:%02x:%02x:%02x:%02x:%02x\n",
++ priv->id[0], priv->id[1], priv->id[2], priv->id[3], priv->id[4], priv->id[5]);
++}
++
++static DEVICE_ATTR(otp_id_gw5200, S_IRUGO, gw5200_otp_id_show, NULL);
++
++static int gw5200_initialize(struct i2c_client *client)
++{
++ struct gw5200_priv *priv = to_gw5200(client);
++ u8 pid = 0;
++ int ret = 0;
++ int tmp_addr;
++ int i;
++
++ for (i = 0; i < ARRAY_SIZE(gw5200_i2c_addr); i++) {
++ tmp_addr = client->addr;
++ if (priv->ti9x4_addr) {
++ client->addr = priv->ti9x4_addr; /* Deserializer I2C address */
++ reg8_write(client, 0x5d, gw5200_i2c_addr[i] << 1); /* Sensor native I2C address */
++ usleep_range(2000, 2500); /* wait 2ms */
++ }
++ if (priv->max9286_addr) {
++ client->addr = priv->max9271_addr; /* Serializer I2C address */
++ reg8_write(client, 0x0a, gw5200_i2c_addr[i] << 1); /* Sensor native I2C address */
++ usleep_range(2000, 2500); /* wait 2ms */
++ };
++ client->addr = tmp_addr;
++
++ /* check model ID */
++ reg8_read(client, GW5200_PID, &pid);
++
++ if (pid == GW5200_VERSION_REG)
++ break;
++ }
++
++ if (pid != GW5200_VERSION_REG) {
++ dev_dbg(&client->dev, "Product ID error %x\n", pid);
++ ret = -ENODEV;
++ goto err;
++ }
++#if 0
++ /* Program wizard registers */
++ gw5200_set_regs(client, gw5200_regs_wizard, ARRAY_SIZE(gw5200_regs_wizard));
++ /* Read OTP IDs */
++ gw5200_otp_id_read(client);
++#endif
++ dev_info(&client->dev, "gw5200 PID %x, res %dx%d, OTP_ID %02x:%02x:%02x:%02x:%02x:%02x\n",
++ pid, GW5200_MAX_WIDTH, GW5200_MAX_HEIGHT, priv->id[0], priv->id[1], priv->id[2], priv->id[3], priv->id[4], priv->id[5]);
++err:
++ gw5200_s_port(client, 0);
++ return ret;
++}
++
++static int gw5200_parse_dt(struct device_node *np, struct gw5200_priv *priv)
++{
++ struct i2c_client *client = v4l2_get_subdevdata(&priv->sd);
++ int i;
++ struct device_node *endpoint = NULL, *rendpoint = NULL;
++ int tmp_addr = 0;
++
++ for (i = 0; ; i++) {
++ endpoint = of_graph_get_next_endpoint(np, endpoint);
++ if (!endpoint)
++ break;
++
++ rendpoint = of_parse_phandle(endpoint, "remote-endpoint", 0);
++ if (!rendpoint)
++ continue;
++
++ if (!of_property_read_u32(rendpoint, "max9271-addr", &priv->max9271_addr) &&
++ !of_property_read_u32(rendpoint->parent->parent, "reg", &priv->max9286_addr) &&
++ !kstrtouint(strrchr(rendpoint->full_name, '@') + 1, 0, &priv->port))
++ break;
++
++ if (!of_property_read_u32(rendpoint, "ti9x3-addr", &priv->ti9x3_addr) &&
++ !of_property_match_string(rendpoint->parent->parent, "compatible", "ti,ti9x4") &&
++ !of_property_read_u32(rendpoint->parent->parent, "reg", &priv->ti9x4_addr) &&
++ !kstrtouint(strrchr(rendpoint->full_name, '@') + 1, 0, &priv->port))
++ break;
++ }
++
++ of_node_put(endpoint);
++
++ if (!priv->ti9x4_addr && !priv->max9286_addr) {
++ dev_dbg(&client->dev, "deserializer does not present\n");
++ return -EINVAL;
++ }
++
++ gw5200_s_port(client, 1);
++
++ /* setup I2C translator address */
++ tmp_addr = client->addr;
++ if (priv->max9286_addr) {
++ client->addr = priv->max9271_addr; /* Serializer I2C address */
++
++ reg8_write(client, 0x09, tmp_addr << 1); /* Sensor translated I2C address */
++ usleep_range(2000, 2500); /* wait 2ms */
++ };
++ if (priv->ti9x4_addr) {
++ client->addr = priv->ti9x4_addr; /* Deserializer I2C address */
++
++ reg8_write(client, 0x4c, (priv->port << 4) | (1 << priv->port)); /* Select RX port number */
++ usleep_range(2000, 2500); /* wait 2ms */
++ reg8_write(client, 0x65, tmp_addr << 1); /* Sensor translated I2C address */
++ }
++ client->addr = tmp_addr;
++
++ mdelay(10);
++
++ return 0;
++}
++
++static int gw5200_probe(struct i2c_client *client,
++ const struct i2c_device_id *did)
++{
++ struct gw5200_priv *priv;
++ int ret;
++
++ priv = devm_kzalloc(&client->dev, sizeof(*priv), GFP_KERNEL);
++ if (!priv)
++ return -ENOMEM;
++
++ v4l2_i2c_subdev_init(&priv->sd, client, &gw5200_subdev_ops);
++ priv->sd.flags = V4L2_SUBDEV_FL_HAS_DEVNODE;
++
++ priv->exposure = 0x100;
++ priv->gain = 0x100;
++ priv->autogain = 1;
++ v4l2_ctrl_handler_init(&priv->hdl, 4);
++ v4l2_ctrl_new_std(&priv->hdl, &gw5200_ctrl_ops,
++ V4L2_CID_BRIGHTNESS, 0, 16, 1, 7);
++ v4l2_ctrl_new_std(&priv->hdl, &gw5200_ctrl_ops,
++ V4L2_CID_CONTRAST, 0, 16, 1, 7);
++ v4l2_ctrl_new_std(&priv->hdl, &gw5200_ctrl_ops,
++ V4L2_CID_SATURATION, 0, 7, 1, 2);
++ v4l2_ctrl_new_std(&priv->hdl, &gw5200_ctrl_ops,
++ V4L2_CID_HUE, 0, 23, 1, 12);
++ v4l2_ctrl_new_std(&priv->hdl, &gw5200_ctrl_ops,
++ V4L2_CID_GAMMA, -128, 128, 1, 0);
++ v4l2_ctrl_new_std(&priv->hdl, &gw5200_ctrl_ops,
++ V4L2_CID_SHARPNESS, 0, 10, 1, 3);
++ v4l2_ctrl_new_std(&priv->hdl, &gw5200_ctrl_ops,
++ V4L2_CID_AUTOGAIN, 0, 1, 1, priv->autogain);
++ v4l2_ctrl_new_std(&priv->hdl, &gw5200_ctrl_ops,
++ V4L2_CID_GAIN, 0, 0xffff, 1, priv->gain);
++ v4l2_ctrl_new_std(&priv->hdl, &gw5200_ctrl_ops,
++ V4L2_CID_EXPOSURE, 0, 0xffff, 1, priv->exposure);
++ v4l2_ctrl_new_std(&priv->hdl, &gw5200_ctrl_ops,
++ V4L2_CID_HFLIP, 0, 1, 1, 1);
++ v4l2_ctrl_new_std(&priv->hdl, &gw5200_ctrl_ops,
++ V4L2_CID_VFLIP, 0, 1, 1, 0);
++ priv->sd.ctrl_handler = &priv->hdl;
++
++ ret = priv->hdl.error;
++ if (ret)
++ goto cleanup;
++
++ v4l2_ctrl_handler_setup(&priv->hdl);
++
++ priv->pad.flags = MEDIA_PAD_FL_SOURCE;
++ priv->sd.entity.flags |= MEDIA_ENT_F_CAM_SENSOR;
++ ret = media_entity_pads_init(&priv->sd.entity, 1, &priv->pad);
++ if (ret < 0)
++ goto cleanup;
++
++ ret = gw5200_parse_dt(client->dev.of_node, priv);
++ if (ret)
++ goto cleanup;
++
++ ret = gw5200_initialize(client);
++ if (ret < 0)
++ goto cleanup;
++
++ priv->rect.left = 0;
++ priv->rect.top = 0;
++ priv->rect.width = GW5200_MAX_WIDTH;
++ priv->rect.height = GW5200_MAX_HEIGHT;
++
++ ret = v4l2_async_register_subdev(&priv->sd);
++ if (ret)
++ goto cleanup;
++
++ if (device_create_file(&client->dev, &dev_attr_otp_id_gw5200) != 0) {
++ dev_err(&client->dev, "sysfs otp_id entry creation failed\n");
++ goto cleanup;
++ }
++
++ priv->init_complete = 1;
++
++ return 0;
++
++cleanup:
++ media_entity_cleanup(&priv->sd.entity);
++ v4l2_ctrl_handler_free(&priv->hdl);
++ v4l2_device_unregister_subdev(&priv->sd);
++#ifdef CONFIG_SOC_CAMERA_GW5200
++ v4l_err(client, "failed to probe @ 0x%02x (%s)\n",
++ client->addr, client->adapter->name);
++#endif
++ return ret;
++}
++
++static int gw5200_remove(struct i2c_client *client)
++{
++ struct gw5200_priv *priv = i2c_get_clientdata(client);
++
++ device_remove_file(&client->dev, &dev_attr_otp_id_gw5200);
++ v4l2_async_unregister_subdev(&priv->sd);
++ media_entity_cleanup(&priv->sd.entity);
++ v4l2_ctrl_handler_free(&priv->hdl);
++ v4l2_device_unregister_subdev(&priv->sd);
++
++ return 0;
++}
++
++#ifdef CONFIG_SOC_CAMERA_GW5200
++static const struct i2c_device_id gw5200_id[] = {
++ { "gw5200", 0 },
++ { }
++};
++MODULE_DEVICE_TABLE(i2c, gw5200_id);
++
++static const struct of_device_id gw5200_of_ids[] = {
++ { .compatible = "geosemi,gw5200", },
++ { }
++};
++MODULE_DEVICE_TABLE(of, gw5200_of_ids);
++
++static struct i2c_driver gw5200_i2c_driver = {
++ .driver = {
++ .name = "gw5200",
++ .of_match_table = gw5200_of_ids,
++ },
++ .probe = gw5200_probe,
++ .remove = gw5200_remove,
++ .id_table = gw5200_id,
++};
++
++module_i2c_driver(gw5200_i2c_driver);
++
++MODULE_DESCRIPTION("SoC Camera driver for GW5200");
++MODULE_AUTHOR("Vladimir Barinov");
++MODULE_LICENSE("GPL");
++#endif
+diff --git a/drivers/media/i2c/soc_camera/gw5200_imx390.h b/drivers/media/i2c/soc_camera/gw5200_imx390.h
+new file mode 100644
+index 0000000..6c0bf5f
+--- /dev/null
++++ b/drivers/media/i2c/soc_camera/gw5200_imx390.h
+@@ -0,0 +1,25 @@
++/*
++ * GEO Semiconductor GW5200-IMX390 sensor camera wizard 1920x1080@30/UYVY/BT601/8bit
++ *
++ * Copyright (C) 2019 Cogent Embedded, Inc.
++ *
++ * This program is free software; you can redistribute it and/or modify it
++ * under the terms of the GNU General Public License as published by the
++ * Free Software Foundation; either version 2 of the License, or (at your
++ * option) any later version.
++ */
++
++#define GW5200_MAX_WIDTH 1920
++#define GW5200_MAX_HEIGHT 1080
++
++#define GW5200_DELAY 0xffff
++
++struct gw5200_reg {
++ u16 reg;
++ u16 val;
++};
++
++static const struct gw5200_reg gw5200_regs_wizard[] = {
++/* enable FSIN */
++{GW5200_DELAY, 100},
++};
+diff --git a/drivers/media/i2c/soc_camera/ov106xx.c b/drivers/media/i2c/soc_camera/ov106xx.c
+index d641907..442e54a 100644
+--- a/drivers/media/i2c/soc_camera/ov106xx.c
++++ b/drivers/media/i2c/soc_camera/ov106xx.c
+@@ -22,6 +22,7 @@
+ #include "ar0323.c"
+ #include "ap0101_ar014x.c"
+ #include "gw4200_ar014x.c"
++#include "gw5200_imx390.c"
+ #include "ov2775.c"
+ #include "imx390.c"
+ #include "ox03a.c"
+@@ -42,6 +43,7 @@ static enum {
+ ID_AR0323,
+ ID_AP0101_AR014X,
+ ID_GW4200_AR014X,
++ ID_GW5200_IMX390,
+ ID_OV2775,
+ ID_IMX390,
+ ID_OX03A,
+@@ -133,6 +135,12 @@ static int ov106xx_probe(struct i2c_client *client,
+ goto out;
+ }
+
++ ret = gw5200_probe(client, did);
++ if (!ret) {
++ chip_id = ID_GW5200_IMX390;
++ goto out;
++ }
++
+ ret = ov2775_probe(client, did);
+ if (!ret) {
+ chip_id = ID_OV2775;
+@@ -211,6 +219,9 @@ static int ov106xx_remove(struct i2c_client *client)
+ case ID_GW4200_AR014X:
+ gw4200_remove(client);
+ break;
++ case ID_GW5200_IMX390:
++ gw5200_remove(client);
++ break;
+ case ID_OV2775:
+ ov2775_remove(client);
+ break;
+--
+2.7.4
+
diff --git a/bsp/meta-rcar/meta-rcar-gen3-adas/recipes-kernel/linux/linux-renesas/0166-lvds-AR0233-add-superexposure-plus.patch b/bsp/meta-rcar/meta-rcar-gen3-adas/recipes-kernel/linux/linux-renesas/0166-lvds-AR0233-add-superexposure-plus.patch
new file mode 100644
index 00000000..841b08cc
--- /dev/null
+++ b/bsp/meta-rcar/meta-rcar-gen3-adas/recipes-kernel/linux/linux-renesas/0166-lvds-AR0233-add-superexposure-plus.patch
@@ -0,0 +1,1251 @@
+From d16da38f64e935e60d82356f2f9c35f82aa51a4a Mon Sep 17 00:00:00 2001
+From: Vladimir Barinov <vladimir.barinov@cogentembedded.com>
+Date: Wed, 8 May 2019 16:45:54 +0300
+Subject: [PATCH 115/122] lvds: AR0233: add superexposure plus
+
+This adds superexposure plus T2
+
+Signed-off-by: Vladimir Barinov <vladimir.barinov@cogentembedded.com>
+---
+ drivers/media/i2c/soc_camera/ar0233.c | 6 +-
+ drivers/media/i2c/soc_camera/ar0233_rev2.h | 1182 ++++++++++++++++++++++++++++
+ 2 files changed, 1186 insertions(+), 2 deletions(-)
+
+diff --git a/drivers/media/i2c/soc_camera/ar0233.c b/drivers/media/i2c/soc_camera/ar0233.c
+index 54cc38a..5c3d4e1 100644
+--- a/drivers/media/i2c/soc_camera/ar0233.c
++++ b/drivers/media/i2c/soc_camera/ar0233.c
+@@ -442,6 +442,8 @@ static int ar0233_initialize(struct i2c_client *client)
+
+ if (strcmp(mode, "hdr") == 0)
+ ar0233_set_regs(client, ar0233_regs_hdr_mipi_12bit_30fps_rev2);
++ else if (strcmp(mode, "seplus") == 0)
++ ar0233_set_regs(client, ar0233_regs_seplus_mipi_12bit_30fps_rev2);
+ else
+ dev_err(&client->dev, "Unsupported mode %s\n", mode);
+ break;
+@@ -461,8 +463,8 @@ static int ar0233_initialize(struct i2c_client *client)
+ val |= (1 << 2); // Set streamOn bit
+ reg16_write16(client, 0x301a, val); // Start Streaming
+
+- dev_info(&client->dev, "ar0233 PID %x (rev %x), res %dx%d, OTP_ID %02x:%02x:%02x:%02x:%02x:%02x\n",
+- pid, rev, AR0233_MAX_WIDTH, AR0233_MAX_HEIGHT, priv->id[0], priv->id[1], priv->id[2], priv->id[3], priv->id[4], priv->id[5]);
++ dev_info(&client->dev, "ar0233 PID %x (rev %x), res %dx%d, mode=%s, OTP_ID %02x:%02x:%02x:%02x:%02x:%02x\n",
++ pid, rev, AR0233_MAX_WIDTH, AR0233_MAX_HEIGHT, mode, priv->id[0], priv->id[1], priv->id[2], priv->id[3], priv->id[4], priv->id[5]);
+ err:
+ return ret;
+ }
+diff --git a/drivers/media/i2c/soc_camera/ar0233_rev2.h b/drivers/media/i2c/soc_camera/ar0233_rev2.h
+index c821d35..02d9af1 100644
+--- a/drivers/media/i2c/soc_camera/ar0233_rev2.h
++++ b/drivers/media/i2c/soc_camera/ar0233_rev2.h
+@@ -1124,6 +1124,1146 @@ static const struct ar0233_reg ar0233_rev2_O1_Recommended_Defaults_LFM_HDR[] = {
+ { }
+ }; /* O1_Recommended_Defaults_LFM_HDR */
+
++static const struct ar0233_reg ar0233_rev2_O1_Recommended_Defaults_SE_T1_LIN_T2[] = {
++/* Design_recommended_settings_REV2_seplus */
++{0x3086, 0x0000},
++{0x3092, 0x400C},
++{0x3362, 0x0001}, // DC_GAIN
++{0x342E, 0x0014},
++{0x34B8, 0x0001},
++{0x34BA, 0x0001},
++{0x3508, 0xAF1A},
++{0x351A, 0xF400},
++{0x3520, 0x0080},
++{0x3522, 0x7D19},
++{0x3524, 0xFF9F},
++{0x3528, 0xF02D},
++{0x352C, 0x0F02},
++{0x3530, 0x1F18},
++{0x3534, 0x3898},
++{0x353A, 0x9ABA},
++{0x353C, 0x9A8A},
++{0x3544, 0x030F},
++{0x3550, 0x806C},
++{0x3562, 0x0C08},
++{0x3564, 0x1223},
++{0x3568, 0x0028},
++{0x356A, 0x81AA},
++{0x356C, 0x6A7F},
++{0x356E, 0x068A},
++{0x3576, 0x1DFF},
++{0x37B2, 0x1FFF}, // DBLC_OUT_CLIP_MAX
++{0x3C72, 0x0076}, // ADC_DEC_CTRL7
++{0x3C74, 0x0031}, // ADC_DEC_CTRL8
++{0x3C76, 0x00DC}, // ADC_DEC_CTRL9
++{0x3C78, 0x01AA}, // ADC_DEC_CTRL10
++{0x3C7A, 0x0352}, // ADC_DEC_CTRL11
++{0x3C7C, 0x06AA}, // ADC_DEC_CTRL12
++{0x3E3E, 0x004A},
++{0x3044, 0x0400}, // DARK_CONTROL
++{0x336E, 0x0147}, // DATAPATH_SELECT2
++{0x3192, 0x2249},
++{0x3194, 0x1AA6},
++{0x3198, 0xB691},
++{0x3546, 0x5203},
++{0x34D4, 0x0001}, // DISCRETE_FINE_INTEGRATION
++{0x3E00, 0x8000}, // LFM2_T1_CTRL
++{0x34BC, 0x0808}, // LFM_PATTERN_CTRL
++{0x3494, 0x0808}, // LFM_TX_PATTERN_CTRL
++{0x3496, 0x5F00}, // LFM_CONTROL
++{0x3474, 0x006F},
++{0x3458, 0x008D},
++{0x3490, 0x0045},
++{0x3C08, 0x0104},
++{0x3C06, 0x0C3C},
++{0x3C08, 0x0104},
++{0x3D28, 0xEA60},
++{0x3D2A, 0xEA60},
++{0x3290, 0xF80C},
++{0x3292, 0xF80C},
++{0x3294, 0xF80C},
++{0x3296, 0xF80C},
++{0x3298, 0xFFFF},
++{0x329A, 0xFFFF},
++{0x329C, 0xFFFF},
++{0x329E, 0xFFFF},
++{0x3110, 0x0011}, // HDR_CONTROL0
++{0x3492, 0x0004},
++{0x3496, 0x5B00}, // LFM_CONTROL
++{0x34A0, 0x0036},
++{0x34A4, 0x0035},
++{0x34A6, 0x0040},
++{0x3512, 0x0ED6},
++{0x3516, 0x8888},
++{0x3518, 0x4040},
++{0x351C, 0xCFF6},
++{0x3528, 0xE00A},
++{0x352A, 0x0827},
++{0x352E, 0x060A},
++{0x353A, 0x1ABA},
++{0x353E, 0x2044},
++{0x3540, 0x4444},
++{0x3542, 0x448F},
++{0x3548, 0x3A3C},
++{0x354A, 0x3C3C},
++{0x354C, 0x321E},
++{0x354E, 0x1E1E},
++{0x3E02, 0x0F32},
++{0x3E04, 0x0000},
++{0x3E06, 0x0000},
++{0x3E10, 0x0000},
++{0x3E14, 0x003F},
++{0x3E16, 0x1FFF},
++{0x3E18, 0x0F52},
++{0x562A, 0x03E8}, // OCL_T1_E2_E1_SAT
++/* Design_recommended_settings_REV2_seplus */
++
++/* Sequence_hidy_ar0233_REV2_seplus */
++{0x2512, 0x8000},
++{0x2510, 0x070F},
++{0x2510, 0x1011},
++{0x2510, 0x1216},
++{0x2510, 0xFFFF},
++{0x2510, 0xFFFF},
++{0x2510, 0xFFFF},
++{0x2510, 0xFFFF},
++{0x2510, 0xFFFF},
++{0x2510, 0x191A},
++{0x2510, 0x1E1F},
++{0x2510, 0x2022},
++{0x2510, 0xFFFF},
++{0x2510, 0x2644},
++{0x2510, 0x5574},
++{0x2510, 0x878D},
++{0x2510, 0x9496},
++{0x2510, 0x9B9D},
++{0x2510, 0x9FA1},
++{0x2510, 0xA3A5},
++{0x2510, 0xFFFF},
++{0x2510, 0xFFFF},
++{0x2510, 0xFFFF},
++{0x2510, 0xFFFF},
++{0x2510, 0xFFFF},
++{0x2510, 0xFFFF},
++{0x2510, 0xFFFF},
++{0x2510, 0xFFFF},
++{0x2510, 0xFFFF},
++{0x2510, 0xC003},
++{0x2510, 0x805A},
++{0x2510, 0xA0E0},
++{0x2510, 0x3041},
++{0x2510, 0x3042},
++{0x2510, 0x2000},
++{0x2510, 0x3048},
++{0x2510, 0x3088},
++{0x2510, 0x30A0},
++{0x2510, 0x3090},
++{0x2510, 0x32C2},
++{0x2510, 0xA0C0},
++{0x2510, 0x9008},
++{0x2510, 0x8802},
++{0x2510, 0x20FF},
++{0x2510, 0x20FF},
++{0x2510, 0x20FF},
++{0x2510, 0x20FF},
++{0x2510, 0x20FF},
++{0x2510, 0x9018},
++{0x2510, 0x891A},
++{0x2510, 0x807E},
++{0x2510, 0x20FF},
++{0x2510, 0x895B},
++{0x2510, 0x20FF},
++{0x2510, 0x897B},
++{0x2510, 0x20FF},
++{0x2510, 0x897F},
++{0x2510, 0x20FF},
++{0x2510, 0x7FFF},
++{0x2510, 0x7FFF},
++{0x2510, 0x7FFF},
++{0x2510, 0x20FF},
++{0x2510, 0x7FFF},
++{0x2510, 0x7FFF},
++{0x2510, 0x7FFF},
++{0x2510, 0x20FF},
++{0x2510, 0x7FFF},
++{0x2510, 0x7FFF},
++{0x2510, 0x7FFF},
++{0x2510, 0x20FF},
++{0x2510, 0x7FFF},
++{0x2510, 0x7FFF},
++{0x2510, 0x7FFF},
++{0x2510, 0xA0C4},
++{0x2510, 0x20FF},
++{0x2510, 0x805A},
++{0x2510, 0x9039},
++{0x2510, 0x20FF},
++{0x2510, 0x907F},
++{0x2510, 0x895B},
++{0x2510, 0x2064},
++{0x2510, 0x891B},
++{0x2510, 0x2010},
++{0x2510, 0x8803},
++{0x2510, 0x7FFF},
++{0x2510, 0x7FFF},
++{0x2510, 0x7FFF},
++{0x2510, 0x7FFF},
++{0x2510, 0x7FFF},
++{0x2510, 0x20FF},
++{0x2510, 0x906B},
++{0x2510, 0x2064},
++{0x2510, 0x3084},
++{0x2510, 0x2003},
++{0x2510, 0x3044},
++{0x2510, 0x2000},
++{0x2510, 0xA004},
++{0x2510, 0x7FFF},
++{0x2510, 0x7FFF},
++{0x2510, 0x7FFF},
++{0x2510, 0x7FFF},
++{0x2510, 0x2400},
++{0x2510, 0x2401},
++{0x2510, 0x7FFF},
++{0x2510, 0x7FFF},
++{0x2510, 0x2400},
++{0x2510, 0x2401},
++{0x2510, 0x2702},
++{0x2510, 0x3242},
++{0x2510, 0x2420},
++{0x2510, 0x2421},
++{0x2510, 0x2703},
++{0x2510, 0x3242},
++{0x2510, 0x2420},
++{0x2510, 0x2421},
++{0x2510, 0x2704},
++{0x2510, 0x3242},
++{0x2510, 0x2420},
++{0x2510, 0x2421},
++{0x2510, 0x7FFF},
++{0x2510, 0x7FFF},
++{0x2510, 0x2201},
++{0x2510, 0x7FFF},
++{0x2510, 0x7FFF},
++{0x2510, 0x7FFF},
++{0x2510, 0x2201},
++{0x2510, 0x7FFF},
++{0x2510, 0x7FFF},
++{0x2510, 0x7FFF},
++{0x2510, 0x2404},
++{0x2510, 0x2779},
++{0x2510, 0x2427},
++{0x2510, 0x2781},
++{0x2510, 0x2427},
++{0x2510, 0x7FFF},
++{0x2510, 0x7FFF},
++{0x2510, 0x7FFF},
++{0x2510, 0x2703},
++{0x2510, 0x242A},
++{0x2510, 0x2703},
++{0x2510, 0x3242},
++{0x2510, 0x27BB},
++{0x2510, 0x2428},
++{0x2510, 0x27BB},
++{0x2510, 0x3242},
++{0x2510, 0x2702},
++{0x2510, 0x2429},
++{0x2510, 0x2702},
++{0x2510, 0x3242},
++{0x2510, 0x27C3},
++{0x2510, 0x2428},
++{0x2510, 0x7FFF},
++{0x2510, 0x7FFF},
++{0x2510, 0xB800},
++{0x2510, 0x8058},
++{0x2510, 0xA005},
++{0x2510, 0x3101},
++{0x2510, 0x3041},
++{0x2510, 0x3104},
++{0x2510, 0xB035},
++{0x2510, 0xB075},
++{0x2510, 0x30C1},
++{0x2510, 0x3102},
++{0x2510, 0x3041},
++{0x2510, 0xB808},
++{0x2510, 0x3202},
++{0x2510, 0xB848},
++{0x2510, 0xB84C},
++{0x2510, 0x2201},
++{0x2510, 0xB377},
++{0x2510, 0x8843},
++{0x2510, 0x916F},
++{0x2510, 0x2201},
++{0x2510, 0xB84E},
++{0x2510, 0xF905},
++{0x2510, 0xF907},
++{0x2510, 0x2200},
++{0x2510, 0x885B},
++{0x2510, 0xA898},
++{0x2510, 0xA8D8},
++{0x2510, 0xF8E8},
++{0x2510, 0x80D8},
++{0x2510, 0x9007},
++{0x2510, 0x916F},
++{0x2510, 0x2206},
++{0x2510, 0xB808},
++{0x2510, 0xC800},
++{0x2510, 0xE807},
++{0x2510, 0x88DB},
++{0x2510, 0xF8A8},
++{0x2510, 0xF888},
++{0x2510, 0x2203},
++{0x2510, 0xB07B},
++{0x2510, 0x2000},
++{0x2510, 0x80C8},
++{0x2510, 0x8088},
++{0x2510, 0x220B},
++{0x2510, 0xB06A},
++{0x2510, 0x88CB},
++{0x2510, 0x888B},
++{0x2510, 0x2224},
++{0x2510, 0xB04A},
++{0x2510, 0x2218},
++{0x2510, 0x210D},
++{0x2510, 0x2108},
++{0x2510, 0x902F},
++{0x2510, 0xB04B},
++{0x2510, 0xF880},
++{0x2510, 0x2205},
++{0x2510, 0x2205},
++{0x2510, 0x2203},
++{0x2510, 0x9800},
++{0x2510, 0xB043},
++{0x2510, 0xA8C9},
++{0x2510, 0x31C1},
++{0x2510, 0x80A8},
++{0x2510, 0x2205},
++{0x2510, 0x916F},
++{0x2510, 0x2104},
++{0x2510, 0x88AB},
++{0x2510, 0x2104},
++{0x2510, 0xB808},
++{0x2510, 0x9800},
++{0x2510, 0x2440},
++{0x2510, 0xF110},
++{0x2510, 0xF804},
++{0x2510, 0x2000},
++{0x2510, 0x8088},
++{0x2510, 0x3002},
++{0x2510, 0xB838},
++{0x2510, 0xA8C8},
++{0x2510, 0xB04B},
++{0x2510, 0x2442},
++{0x2510, 0x3210},
++{0x2510, 0x2206},
++{0x2510, 0x888B},
++{0x2510, 0x2203},
++{0x2510, 0xF1CB},
++{0x2510, 0x2201},
++{0x2510, 0x3202},
++{0x2510, 0xF880},
++{0x2510, 0xB830},
++{0x2510, 0xC801},
++{0x2510, 0x30C2},
++{0x2510, 0xE80C},
++{0x2510, 0x2201},
++{0x2510, 0xB04A},
++{0x2510, 0x2227},
++{0x2510, 0x2205},
++{0x2510, 0x2200},
++{0x2510, 0x2207},
++{0x2510, 0x902F},
++{0x2510, 0x220E},
++{0x2510, 0x2205},
++{0x2510, 0x2204},
++{0x2510, 0xB042},
++{0x2510, 0xA9A1},
++{0x2510, 0x8008},
++{0x2510, 0xB0D3},
++{0x2510, 0x31C1},
++{0x2510, 0x916B},
++{0x2510, 0x2008},
++{0x2510, 0x32C1},
++{0x2510, 0x8803},
++{0x2510, 0xA044},
++{0x2510, 0x3044},
++{0x2510, 0x2000},
++{0x2510, 0xA004},
++{0x2510, 0x2000},
++{0x2510, 0x7FFF},
++{0x2510, 0x7FFF},
++{0x2510, 0x7FFF},
++{0x2510, 0x7FFF},
++{0x2510, 0xA084},
++{0x2510, 0x30D0},
++{0x2510, 0x807C},
++{0x2510, 0x3141},
++{0x2510, 0x3041},
++{0x2510, 0x3042},
++{0x2510, 0x2000},
++{0x2510, 0x3142},
++{0x2510, 0x3041},
++{0x2510, 0x3042},
++{0x2510, 0x2000},
++{0x2510, 0x3281},
++{0x2510, 0x3041},
++{0x2510, 0x3042},
++{0x2510, 0x2000},
++{0x2510, 0x3290},
++{0x2510, 0x3041},
++{0x2510, 0x3042},
++{0x2510, 0x2000},
++{0x2510, 0x3110},
++{0x2510, 0x3041},
++{0x2510, 0x2000},
++{0x2510, 0x3120},
++{0x2510, 0x3041},
++{0x2510, 0x2000},
++{0x2510, 0x3282},
++{0x2510, 0x3041},
++{0x2510, 0x2000},
++{0x2510, 0x32A0},
++{0x2510, 0x3041},
++{0x2510, 0x2000},
++{0x2510, 0x881B},
++{0x2510, 0x887F},
++{0x2510, 0xA08C},
++{0x2510, 0x221F},
++{0x2510, 0xA084},
++{0x2510, 0x2440},
++{0x2510, 0x3260},
++{0x2510, 0x3248},
++{0x2510, 0xB095},
++{0x2510, 0xF110},
++{0x2510, 0xF864},
++{0x2510, 0xF90D},
++{0x2510, 0x3084},
++{0x2510, 0x32C1},
++{0x2510, 0x3090},
++{0x2510, 0x3088},
++{0x2510, 0x2443},
++{0x2510, 0x8058},
++{0x2510, 0x3001},
++{0x2510, 0x2442},
++{0x2510, 0x3220},
++{0x2510, 0x2002},
++{0x2510, 0x8867},
++{0x2510, 0x2004},
++{0x2510, 0x8803},
++{0x2510, 0x2002},
++{0x2510, 0x30C2},
++{0x2510, 0xA9A0},
++{0x2510, 0xB094},
++{0x2510, 0x2201},
++{0x2510, 0xA0C4},
++{0x2510, 0x3044},
++{0x2510, 0x2000},
++{0x2510, 0xA004},
++{0x2510, 0x7FFF},
++{0x2510, 0x7FFF},
++{0x2510, 0x7FFF},
++{0x2510, 0xB980},
++{0x2510, 0xA881},
++{0x2510, 0xA8C1},
++{0x2510, 0x8108},
++{0x2510, 0xA105},
++{0x2510, 0x30C1},
++{0x2510, 0x2020},
++{0x2510, 0x3101},
++{0x2510, 0x3041},
++{0x2510, 0x3104},
++{0x2510, 0x3102},
++{0x2510, 0x3041},
++{0x2510, 0xF860},
++{0x2510, 0xB095},
++{0x2510, 0x2001},
++{0x2510, 0xB988},
++{0x2510, 0xB9F8},
++{0x2510, 0xB9FC},
++{0x2510, 0x8803},
++{0x2510, 0x916F},
++{0x2510, 0x2001},
++{0x2510, 0xB9FE},
++{0x2510, 0xF905},
++{0x2510, 0xF907},
++{0x2510, 0x3202},
++{0x2510, 0x880B},
++{0x2510, 0xB397},
++{0x2510, 0xF8E8},
++{0x2510, 0x8188},
++{0x2510, 0x9007},
++{0x2510, 0x916F},
++{0x2510, 0x2204},
++{0x2510, 0xB137},
++{0x2510, 0xB9B8},
++{0x2510, 0xC801},
++{0x2510, 0xE807},
++{0x2510, 0xB177},
++{0x2510, 0x888B},
++{0x2510, 0xF8A8},
++{0x2510, 0xF888},
++{0x2510, 0x2203},
++{0x2510, 0xA8C8},
++{0x2510, 0xB07B},
++{0x2510, 0x2000},
++{0x2510, 0x8188},
++{0x2510, 0x8088},
++{0x2510, 0x220B},
++{0x2510, 0xB06A},
++{0x2510, 0x888B},
++{0x2510, 0x888B},
++{0x2510, 0x2224},
++{0x2510, 0xB04A},
++{0x2510, 0x2214},
++{0x2510, 0xB04B},
++{0x2510, 0x902F},
++{0x2510, 0xF880},
++{0x2510, 0x2211},
++{0x2510, 0x2205},
++{0x2510, 0x2204},
++{0x2510, 0xB043},
++{0x2510, 0xA8C1},
++{0x2510, 0x31C1},
++{0x2510, 0x2200},
++{0x2510, 0x80C8},
++{0x2510, 0x2103},
++{0x2510, 0x916F},
++{0x2510, 0x2106},
++{0x2510, 0x88CB},
++{0x2510, 0x210A},
++{0x2510, 0xA8C1},
++{0x2510, 0x2440},
++{0x2510, 0xF110},
++{0x2510, 0xF804},
++{0x2510, 0x2000},
++{0x2510, 0x8088},
++{0x2510, 0x2002},
++{0x2510, 0x888B},
++{0x2510, 0x3002},
++{0x2510, 0xB988},
++{0x2510, 0x2442},
++{0x2510, 0x3210},
++{0x2510, 0x2206},
++{0x2510, 0x2207},
++{0x2510, 0x3202},
++{0x2510, 0xA8C1},
++{0x2510, 0x2013},
++{0x2510, 0x8088},
++{0x2510, 0x200C},
++{0x2510, 0x888B},
++{0x2510, 0x2005},
++{0x2510, 0xA8D0},
++{0x2510, 0xB04B},
++{0x2510, 0xF880},
++{0x2510, 0xB980},
++{0x2510, 0xC800},
++{0x2510, 0x30C2},
++{0x2510, 0xE80C},
++{0x2510, 0x2201},
++{0x2510, 0xB04A},
++{0x2510, 0x2213},
++{0x2510, 0x2225},
++{0x2510, 0x8088},
++{0x2510, 0x2205},
++{0x2510, 0x888B},
++{0x2510, 0x2203},
++{0x2510, 0x902F},
++{0x2510, 0x2206},
++{0x2510, 0x2204},
++{0x2510, 0xB042},
++{0x2510, 0xA9A1},
++{0x2510, 0x8058},
++{0x2510, 0xB093},
++{0x2510, 0x31C1},
++{0x2510, 0x916B},
++{0x2510, 0x2007},
++{0x2510, 0x3084},
++{0x2510, 0x32C1},
++{0x2510, 0x8803},
++{0x2510, 0xA144},
++{0x2510, 0x3044},
++{0x2510, 0x2000},
++{0x2510, 0xA004},
++{0x2510, 0xB800},
++{0x2510, 0x7FFF},
++{0x2510, 0x30D0},
++{0x2510, 0xA981},
++{0x2510, 0xA9C1},
++{0x2510, 0x2006},
++{0x2510, 0xA184},
++{0x2510, 0xB800},
++{0x2510, 0x80FC},
++{0x2510, 0x3141},
++{0x2510, 0x3041},
++{0x2510, 0x3042},
++{0x2510, 0x2000},
++{0x2510, 0x3142},
++{0x2510, 0x3041},
++{0x2510, 0x3042},
++{0x2510, 0x2000},
++{0x2510, 0x3281},
++{0x2510, 0x3041},
++{0x2510, 0x3042},
++{0x2510, 0x2000},
++{0x2510, 0x3290},
++{0x2510, 0x3041},
++{0x2510, 0x3042},
++{0x2510, 0x2000},
++{0x2510, 0x3110},
++{0x2510, 0x3041},
++{0x2510, 0x2000},
++{0x2510, 0x3120},
++{0x2510, 0x3041},
++{0x2510, 0x2000},
++{0x2510, 0x3282},
++{0x2510, 0x3041},
++{0x2510, 0x2000},
++{0x2510, 0x32A0},
++{0x2510, 0x3041},
++{0x2510, 0x2000},
++{0x2510, 0x889B},
++{0x2510, 0x88FF},
++{0x2510, 0x2440},
++{0x2510, 0x3260},
++{0x2510, 0x3248},
++{0x2510, 0xB095},
++{0x2510, 0xF110},
++{0x2510, 0xF864},
++{0x2510, 0xF90D},
++{0x2510, 0x32C2},
++{0x2510, 0x30A0},
++{0x2510, 0x3090},
++{0x2510, 0x3088},
++{0x2510, 0x2443},
++{0x2510, 0x80D8},
++{0x2510, 0x3001},
++{0x2510, 0x2206},
++{0x2510, 0x88DB},
++{0x2510, 0x2442},
++{0x2510, 0x3220},
++{0x2510, 0x2010},
++{0x2510, 0x2001},
++{0x2510, 0x30C2},
++{0x2510, 0x8098},
++{0x2510, 0x2010},
++{0x2510, 0x889B},
++{0x2510, 0x2008},
++{0x2510, 0x809A},
++{0x2510, 0x200A},
++{0x2510, 0x8002},
++{0x2510, 0xA9A1},
++{0x2510, 0xB094},
++{0x2510, 0x2201},
++{0x2510, 0x8803},
++{0x2510, 0xA1C4},
++{0x2510, 0x3044},
++{0x2510, 0xB800},
++{0x2510, 0xA004},
++{0x2510, 0x7FFF},
++{0x2510, 0x7FFF},
++{0x2510, 0x7FFF},
++{0x2510, 0x8002},
++{0x2510, 0x9818},
++{0x2510, 0x3101},
++{0x2510, 0x3041},
++{0x2510, 0x2000},
++{0x2510, 0x3102},
++{0x2510, 0x3041},
++{0x2510, 0x8018},
++{0x2510, 0x2002},
++{0x2510, 0x8038},
++{0x2510, 0x2205},
++{0x2510, 0x881B},
++{0x2510, 0x883B},
++{0x2510, 0x2119},
++{0x2510, 0x8018},
++{0x2510, 0x2202},
++{0x2510, 0x8000},
++{0x2510, 0x2201},
++{0x2510, 0x8803},
++{0x2510, 0x9800},
++{0x2510, 0x7FFF},
++{0x2510, 0x7FFF},
++{0x2510, 0x7FFF},
++{0x2510, 0x7FFF},
++{0x2510, 0xB980},
++{0x2510, 0x3260},
++{0x2510, 0x3101},
++{0x2510, 0x3041},
++{0x2510, 0x2000},
++{0x2510, 0x3102},
++{0x2510, 0x3041},
++{0x2510, 0x8028},
++{0x2510, 0x220A},
++{0x2510, 0x880B},
++{0x2510, 0x882B},
++{0x2510, 0x2440},
++{0x2510, 0xB095},
++{0x2510, 0xF110},
++{0x2510, 0xF864},
++{0x2510, 0xF90D},
++{0x2510, 0x8008},
++{0x2510, 0x3004},
++{0x2510, 0x2202},
++{0x2510, 0x2442},
++{0x2510, 0x882B},
++{0x2510, 0x3220},
++{0x2510, 0x2004},
++{0x2510, 0x880B},
++{0x2510, 0x2004},
++{0x2510, 0x7FFF},
++{0x2510, 0x7FFF},
++{0x2510, 0x7FFF},
++{0x2510, 0x240D},
++{0x2510, 0x2751},
++{0x2510, 0x2423},
++{0x2510, 0x2750},
++{0x2510, 0x2421},
++{0x2510, 0x7FFF},
++{0x2510, 0x7FFF},
++{0x2510, 0x7FFF},
++{0x2510, 0x3250},
++{0x2510, 0x27D8},
++{0x2510, 0x242B},
++{0x2510, 0x27D9},
++{0x2510, 0x242B},
++{0x2510, 0x3250},
++{0x2510, 0xC023},
++{0x2510, 0x2402},
++{0x2510, 0xC023},
++{0x2510, 0x2751},
++{0x2510, 0x2423},
++{0x2510, 0xC02B},
++{0x2510, 0x2750},
++{0x2510, 0x2421},
++{0x2510, 0xC003},
++{0x2510, 0x7FFF},
++{0x2510, 0x7FFF},
++{0x2510, 0x7FFF},
++{0x2510, 0x7FFF},
++{0x2510, 0x7FFF},
++{0x2510, 0x2404},
++{0x2510, 0x2779},
++{0x2510, 0x2427},
++{0x2510, 0x2781},
++{0x2510, 0x2427},
++{0x2510, 0x7FFF},
++{0x2510, 0x7FFF},
++{0x2510, 0x7FFF},
++{0x2510, 0x2791},
++{0x2510, 0x2428},
++{0x2510, 0x2799},
++{0x2510, 0x2426},
++{0x2510, 0x7FFF},
++{0x2510, 0x7FFF},
++{0x2510, 0x7FFF},
++{0x2510, 0x7FFF},
++{0x2510, 0x27A1},
++{0x2510, 0x2428},
++{0x2510, 0x27A9},
++{0x2510, 0x2426},
++{0x2510, 0x7FFF},
++{0x2510, 0x7FFF},
++{0x2510, 0x7FFF},
++{0x2510, 0x7FFF},
++{0x2510, 0xC167},
++{0x2510, 0x2400},
++{0x2510, 0xC067},
++{0x2510, 0x2405},
++{0x2510, 0x240C},
++{0x2510, 0x7FFF},
++{0x2510, 0x7FFF},
++{0x2510, 0x7FFF},
++{0x2510, 0x30C2},
++{0x2510, 0xA9A0},
++{0x2510, 0xB094},
++{0x2510, 0x2201},
++{0x2510, 0x7FFF},
++{0x2510, 0x7FFF},
++{0x2510, 0x7FFF},
++{0x2510, 0x7FFF},
++{0x2510, 0xB800},
++{0x2510, 0x8058},
++{0x2510, 0xA005},
++{0x2510, 0x3101},
++{0x2510, 0x3041},
++{0x2510, 0x3104},
++{0x2510, 0xB035},
++{0x2510, 0xB075},
++{0x2510, 0x30C1},
++{0x2510, 0x3102},
++{0x2510, 0x3041},
++{0x2510, 0xB808},
++{0x2510, 0x3202},
++{0x2510, 0xB848},
++{0x2510, 0xB84C},
++{0x2510, 0x2201},
++{0x2510, 0xB377},
++{0x2510, 0x8843},
++{0x2510, 0x916F},
++{0x2510, 0x2201},
++{0x2510, 0xB84E},
++{0x2510, 0xF905},
++{0x2510, 0xF907},
++{0x2510, 0x2200},
++{0x2510, 0x885B},
++{0x2510, 0xA898},
++{0x2510, 0xA8D8},
++{0x2510, 0xF8E8},
++{0x2510, 0x80D8},
++{0x2510, 0x9007},
++{0x2510, 0x916F},
++{0x2510, 0x2206},
++{0x2510, 0xB808},
++{0x2510, 0xC800},
++{0x2510, 0xE807},
++{0x2510, 0x88DB},
++{0x2510, 0xF8A8},
++{0x2510, 0xF888},
++{0x2510, 0x2203},
++{0x2510, 0xB07B},
++{0x2510, 0x2000},
++{0x2510, 0x80C8},
++{0x2510, 0x8088},
++{0x2510, 0x220B},
++{0x2510, 0xB06A},
++{0x2510, 0x88CB},
++{0x2510, 0x888B},
++{0x2510, 0x221F},
++{0x2510, 0xB04A},
++{0x2510, 0x2213},
++{0x2510, 0x210D},
++{0x2510, 0x2108},
++{0x2510, 0x902F},
++{0x2510, 0xB04B},
++{0x2510, 0xF880},
++{0x2510, 0x2205},
++{0x2510, 0x2205},
++{0x2510, 0x2203},
++{0x2510, 0x9800},
++{0x2510, 0xB043},
++{0x2510, 0xA8C9},
++{0x2510, 0x31C1},
++{0x2510, 0x80A8},
++{0x2510, 0x2205},
++{0x2510, 0x916F},
++{0x2510, 0x2104},
++{0x2510, 0x88AB},
++{0x2510, 0x2104},
++{0x2510, 0xB808},
++{0x2510, 0x9800},
++{0x2510, 0x2440},
++{0x2510, 0xF110},
++{0x2510, 0xF804},
++{0x2510, 0x2000},
++{0x2510, 0x8088},
++{0x2510, 0x3002},
++{0x2510, 0xB838},
++{0x2510, 0xA8C8},
++{0x2510, 0xB04B},
++{0x2510, 0x2442},
++{0x2510, 0x3210},
++{0x2510, 0x2206},
++{0x2510, 0x888B},
++{0x2510, 0x2203},
++{0x2510, 0xF1CB},
++{0x2510, 0x2201},
++{0x2510, 0x3202},
++{0x2510, 0xF880},
++{0x2510, 0xB830},
++{0x2510, 0xC801},
++{0x2510, 0x30C2},
++{0x2510, 0xE80C},
++{0x2510, 0x2201},
++{0x2510, 0xB04A},
++{0x2510, 0x2217},
++{0x2510, 0x2205},
++{0x2510, 0x2207},
++{0x2510, 0x902F},
++{0x2510, 0x220E},
++{0x2510, 0x2205},
++{0x2510, 0x2204},
++{0x2510, 0xB042},
++{0x2510, 0xA9A1},
++{0x2510, 0x8008},
++{0x2510, 0xB0D3},
++{0x2510, 0x31C1},
++{0x2510, 0x916B},
++{0x2510, 0x2008},
++{0x2510, 0x32C1},
++{0x2510, 0x8803},
++{0x2510, 0xA044},
++{0x2510, 0x3044},
++{0x2510, 0x2000},
++{0x2510, 0xA004},
++{0x2510, 0x2000},
++{0x2510, 0x7FFF},
++{0x2510, 0xFFFF},
++{0x2510, 0xFFFF},
++{0x2510, 0xFFFF},
++{0x2510, 0xFFFF},
++{0x2510, 0xFFFF},
++{0x2510, 0xFFFF},
++{0x2510, 0xFFFF},
++{0x2510, 0xFFFF},
++{0x2510, 0xFFFF},
++{0x2510, 0xFFFF},
++{0x2510, 0xFFFF},
++{0x2510, 0xFFFF},
++{0x2510, 0xFFFF},
++{0x2510, 0xFFFF},
++{0x2510, 0xFFFF},
++{0x2510, 0xFFFF},
++{0x2510, 0xFFFF},
++{0x2510, 0xFFFF},
++{0x2510, 0xFFFF},
++{0x2510, 0xFFFF},
++{0x2510, 0xFFFF},
++{0x2510, 0xFFFF},
++{0x2510, 0xFFFF},
++{0x2510, 0xFFFF},
++{0x2510, 0xFFFF},
++{0x2510, 0xFFFF},
++{0x2510, 0xFFFF},
++{0x2510, 0xFFFF},
++{0x2510, 0xFFFF},
++{0x2510, 0xFFFF},
++{0x2510, 0xFFFF},
++{0x2510, 0xFFFF},
++{0x2510, 0xFFFF},
++{0x2510, 0xFFFF},
++{0x2510, 0xFFFF},
++{0x2510, 0xFFFF},
++{0x2510, 0xFFFF},
++{0x2510, 0xFFFF},
++{0x2510, 0xFFFF},
++{0x2510, 0xFFFF},
++{0x2510, 0xFFFF},
++{0x2510, 0xFFFF},
++{0x2510, 0xFFFF},
++{0x2510, 0xFFFF},
++{0x2510, 0xFFFF},
++{0x2510, 0xFFFF},
++{0x2510, 0xFFFF},
++{0x2510, 0xFFFF},
++{0x2510, 0xFFFF},
++{0x2510, 0xFFFF},
++{0x2510, 0xFFFF},
++{0x2510, 0xFFFF},
++{0x2510, 0xFFFF},
++{0x2510, 0xFFFF},
++{0x2510, 0xFFFF},
++{0x2510, 0xFFFF},
++{0x2510, 0xFFFF},
++{0x2510, 0xFFFF},
++{0x2510, 0xFFFF},
++{0x2510, 0xFFFF},
++{0x2510, 0xFFFF},
++{0x2510, 0xFFFF},
++{0x2510, 0xFFFF},
++{0x2510, 0xFFFF},
++{0x2510, 0xFFFF},
++{0x2510, 0xFFFF},
++{0x2510, 0xFFFF},
++{0x2510, 0xFFFF},
++{0x2510, 0xFFFF},
++{0x2510, 0xFFFF},
++{0x2510, 0xFFFF},
++{0x2510, 0xFFFF},
++{0x2510, 0xFFFF},
++{0x2510, 0xFFFF},
++{0x2510, 0xFFFF},
++{0x2510, 0xFFFF},
++{0x2510, 0xFFFF},
++{0x2510, 0xFFFF},
++{0x2510, 0xFFFF},
++{0x2510, 0xFFFF},
++{0x2510, 0xFFFF},
++{0x2510, 0xFFFF},
++{0x2510, 0xFFFF},
++{0x2510, 0xFFFF},
++{0x2510, 0xFFFF},
++{0x2510, 0xFFFF},
++{0x2510, 0xFFFF},
++{0x2510, 0xFFFF},
++{0x2510, 0xFFFF},
++{0x2510, 0xFFFF},
++{0x2510, 0xFFFF},
++{0x2510, 0xFFFF},
++{0x2510, 0xFFFF},
++{0x2510, 0xFFFF},
++{0x2510, 0xFFFF},
++{0x2510, 0xFFFF},
++{0x2510, 0xFFFF},
++{0x2510, 0xFFFF},
++{0x2510, 0xFFFF},
++{0x2510, 0xFFFF},
++{0x2510, 0xFFFF},
++{0x2510, 0xFFFF},
++{0x2510, 0xFFFF},
++{0x2510, 0xFFFF},
++{0x2510, 0xFFFF},
++{0x2510, 0xFFFF},
++{0x2510, 0xFFFF},
++{0x2510, 0xFFFF},
++{0x2510, 0xFFFF},
++{0x2510, 0xFFFF},
++{0x2510, 0xFFFF},
++{0x2510, 0xFFFF},
++{0x2510, 0xFFFF},
++{0x2510, 0xFFFF},
++{0x2510, 0xFFFF},
++{0x2510, 0xFFFF},
++{0x2510, 0xFFFF},
++{0x2510, 0xFFFF},
++{0x2510, 0xFFFF},
++{0x2510, 0xFFFF},
++{0x2510, 0xFFFF},
++{0x2510, 0xFFFF},
++{0x2510, 0xFFFF},
++{0x2510, 0xFFFF},
++{0x2510, 0xFFFF},
++{0x2510, 0xFFFF},
++{0x2510, 0xFFFF},
++{0x2510, 0xFFFF},
++{0x2510, 0xFFFF},
++{0x2510, 0xFFFF},
++{0x2510, 0xFFFF},
++{0x2510, 0xFFFF},
++{0x2510, 0xFFFF},
++{0x2510, 0xFFFF},
++{0x2510, 0xFFFF},
++{0x2510, 0xFFFF},
++{0x2510, 0xFFFF},
++{0x2510, 0xFFFF},
++{0x2510, 0xFFFF},
++{0x2510, 0xFFFF},
++{0x2510, 0xFFFF},
++{0x2510, 0xFFFF},
++{0x2510, 0xFFFF},
++{0x2510, 0xFFFF},
++{0x2510, 0xFFFF},
++{0x2510, 0xFFFF},
++{0x2510, 0xFFFF},
++{0x2510, 0xFFFF},
++{0x2510, 0xFFFF},
++{0x2510, 0xFFFF},
++{0x2510, 0xFFFF},
++{0x2510, 0xFFFF},
++{0x2510, 0xFFFF},
++{0x2510, 0xFFFF},
++{0x2510, 0xFFFF},
++{0x2510, 0xFFFF},
++{0x2510, 0xFFFF},
++{0x2510, 0xFFFF},
++{0x2510, 0xFFFF},
++{0x2510, 0xFFFF},
++{0x2510, 0xFFFF},
++{0x2510, 0xFFFF},
++{0x2510, 0xFFFF},
++{0x2510, 0xFFFF},
++{0x2510, 0xFFFF},
++{0x2510, 0xFFFF},
++{0x2510, 0xFFFF},
++{0x2510, 0xFFFF},
++{0x2510, 0xFFFF},
++{0x2510, 0xFFFF},
++{0x2510, 0xFFFF},
++{0x2510, 0xFFFF},
++{0x2510, 0xFFFF},
++{0x2510, 0xFFFF},
++{0x2510, 0xFFFF},
++{0x2510, 0xFFFF},
++{0x2510, 0xFFFF},
++{0x2510, 0xFFFF},
++{0x2510, 0xFFFF},
++{0x2510, 0xFFFF},
++{0x2510, 0xFFFF},
++{0x2510, 0xFFFF},
++{0x2510, 0xFFFF},
++{0x2510, 0xFFFF},
++{0x2510, 0xFFFF},
++{0x2510, 0xFFFF},
++{0x2510, 0xFFFF},
++{0x2510, 0xFFFF},
++{0x2510, 0xFFFF},
++{0x2510, 0xFFFF},
++{0x2510, 0xFFFF},
++{0x2510, 0xFFFF},
++{0x2510, 0xFFFF},
++{0x2510, 0xFFFF},
++{0x2510, 0xFFFF},
++{0x2510, 0xFFFF},
++{0x2510, 0xFFFF},
++{0x2510, 0xFFFF},
++{0x2510, 0xFFFF},
++{0x2510, 0xFFFF},
++{0x2510, 0xFFFF},
++{0x2510, 0xFFFF},
++{0x2510, 0xFFFF},
++{0x2510, 0xFFFF},
++{0x2510, 0xFFFF},
++{0x2510, 0xFFFF},
++{0x2510, 0xFFFF},
++{0x2510, 0xFFFF},
++{0x2510, 0xFFFF},
++{0x2510, 0xFFFF},
++{0x2510, 0xFFFF},
++{0x2510, 0xFFFF},
++{0x2510, 0xFFFF},
++{0x2510, 0xFFFF},
++{0x2510, 0xFFFF},
++{0x2510, 0xFFFF},
++{0x2510, 0xFFFF},
++{0x2510, 0xFFFF},
++{0x2510, 0xFFFF},
++{0x2510, 0xFFFF},
++{0x2510, 0xFFFF},
++{0x2510, 0xFFFF},
++{0x2510, 0xFFFF},
++{0x2510, 0xFFFF},
++{0x2510, 0xFFFF},
++{0x2510, 0xFFFF},
++{0x2510, 0xFFFF},
++{0x2510, 0xFFFF},
++{0x2510, 0xFFFF},
++{0x2510, 0xFFFF},
++{0x2510, 0xFFFF},
++{0x2510, 0xFFFF},
++{0x2510, 0xFFFF},
++{0x2510, 0xFFFF},
++{0x2510, 0xFFFF},
++{0x2510, 0xFFFF},
++{0x2510, 0xFFFF},
++{0x2510, 0xFFFF},
++{0x2510, 0xFFFF},
++{0x2510, 0xFFFF},
++{0x2510, 0xFFFF},
++{0x2510, 0xFFFF},
++{0x2510, 0xFFFF},
++{0x2510, 0xFFFF},
++{0x2510, 0xFFFF},
++{0x2510, 0xFFFF},
++{0x2510, 0xFFFF},
++{AR0233_DELAY, 100},
++/* Sequence_hidy_ar0233_REV2_seplus */
++
++{0x3E14, 0x003F},
++{0x3E14, 0x003F},
++{0x3E18, 0x0F52},
++{0x3E18, 0x0F52},
++{0x562A, 0x03E8}, // OCL_T1_E2_E1_SAT
++
++{0x3364, 0x06F4},
++
++/* Tempsensor_init */
++{0x3E94, 0x3007},
++{0x3E6E, 0xE200}, // TEMPVSENS1_TMG_CTRL_K0
++{0x3E98, 0x1000}, // TEMPVSENS1_EN_CTRL
++{0x3F92, 0x4C00}, // TEMPVSENS1_TMG_CTRL
++{0x30B8, 0x000B}, // TEMPSENS1_CTRL_REG
++{0x30B8, 0x0003}, // TEMPSENS1_CTRL_REG
++{ }
++}; /* O1_Recommended_Defaults_SE_T1_LIN_T2 */
++
+ static const struct ar0233_reg ar0233_rev2_disable_embed_data_stat[] = {
+ {0x3064, 0x0}, // Disable embedded data and stat
+ #ifdef AR0233_EMBEDDED_LINE
+@@ -1146,6 +2286,22 @@ static const struct ar0233_reg ar0233_rev2_HDR_3exp_12bit[] = {
+ { }
+ }; /* HDR_3exp_12bit */
+
++static const struct ar0233_reg ar0233_rev2_SEPLUS_12bit[] = {
++{0x3082, 0x4}, //num_exp = 2
++{0x30BA, 0x1121}, //num_exp_max =2
++{0x31AC, 0x140C}, //12 bit output
++
++{0x3044, 0x0400}, //Dark_control
++
++// FPS = 102MHz / reg0x300A / reg0x300C
++{0x300A, AR0233_SENSOR_HEIGHT + 100}, // Frame_length_Lines
++{0x300C, AR0233_SENSOR_WIDTH + 400}, // Line_length_pck
++{0x3012, 0x0299}, // COARSE_INTEGRATION_TIME_
++{0x3212, 0x0006}, // COARSE_INTEGRATION_TIME2
++{0x3112, 0x71E7},
++{ }
++}; /* HDR_3exp_12bit */
++
+ static const struct ar0233_reg ar0233_rev2_pll_23_102_4lane_12b[] = {
+ // serial_data_rate was *2 in REV1. but not in REV2
+ /* PCLK=DES_REFCLK/PRE_PLL_CLK_DIV *PLL_MULTIPLIER /P1 /P4 */
+@@ -1229,6 +2385,18 @@ static const struct ar0233_reg ar0233_rev2_HDR_ratio_gain_default[] = {
+ { }
+ }; /* HDR_ratio_gain_default */
+
++static const struct ar0233_reg ar0233_rev2_SEPLUS_ratio_gain_default[] = {
++{0x3362, 0x0001}, // DC_GAIN
++{0x3238, 0x8446}, // EXPOSURE_RATIO
++{0x562E, 0x0111}, // OCL_T1_GAIN_
++{0x562E, 0x0111}, // OCL_T1_GAIN_
++{0x3366, 0x4441}, // ANALOG_GAIN
++{0x3366, 0x4431}, // ANALOG_GAIN
++{0x336A, 0x0000}, // ANALOG_GAIN2
++{0x336A, 0x00C0}, // ANALOG_GAIN2
++{ }
++}; /* SEPLUS_ratio_gain_default */
++
+ /* 3Exp HDR, 1280P, MIPI 4-lane 12-bit, 30fps, EXTCLK=23MHz (comes from deser) */
+ static const struct ar0233_reg *ar0233_regs_hdr_mipi_12bit_30fps_rev2[] = {
+ ar0233_rev2_Reset,
+@@ -1242,3 +2410,17 @@ static const struct ar0233_reg *ar0233_regs_hdr_mipi_12bit_30fps_rev2[] = {
+ ar0233_rev2_HDR_ratio_gain_default,
+ NULL,
+ };
++
++/* SE_T1 + Lin_T2, 1280P, MIPI 750MBPS 4-lane 12-bit, 30fps, EXTCLK=23MHz (comes from deser) */
++static const struct ar0233_reg *ar0233_regs_seplus_mipi_12bit_30fps_rev2[] = {
++ ar0233_rev2_Reset,
++ ar0233_rev2_Full_resolution,
++ ar0233_rev2_pll_23_102_4lane_12b,
++ ar0233_rev2_mipi_12bit_4lane,
++ ar0233_rev2_O1_Recommended_Defaults_SE_T1_LIN_T2,
++ ar0233_rev2_disable_embed_data_stat,
++ ar0233_rev2_SEPLUS_12bit,
++ ar0233_rev2_LUT_24_to_12,
++ ar0233_rev2_SEPLUS_ratio_gain_default,
++ NULL,
++};
+--
+2.7.4
+
diff --git a/bsp/meta-rcar/meta-rcar-gen3-adas/recipes-kernel/linux/linux-renesas/0167-lvds-AR0233-fix-matrix-size-set-default-h-vflip.patch b/bsp/meta-rcar/meta-rcar-gen3-adas/recipes-kernel/linux/linux-renesas/0167-lvds-AR0233-fix-matrix-size-set-default-h-vflip.patch
new file mode 100644
index 00000000..3659060d
--- /dev/null
+++ b/bsp/meta-rcar/meta-rcar-gen3-adas/recipes-kernel/linux/linux-renesas/0167-lvds-AR0233-fix-matrix-size-set-default-h-vflip.patch
@@ -0,0 +1,90 @@
+From 42172a5124173f1c30ac097f2d788a1beaacbe3d Mon Sep 17 00:00:00 2001
+From: Vladimir Barinov <vladimir.barinov@cogentembedded.com>
+Date: Thu, 9 May 2019 23:09:53 +0300
+Subject: [PATCH 116/122] lvds: AR0233: fix matrix size, set default h/vflip
+
+AR0233 matrix array 2072x1296
+set default hflip and vflip as perspecitve view i.e. flipped
+
+Signed-off-by: Vladimir Barinov <vladimir.barinov@cogentembedded.com>
+---
+ drivers/media/i2c/soc_camera/ar0233.c | 6 +++---
+ drivers/media/i2c/soc_camera/ar0233.h | 4 ++--
+ drivers/media/i2c/soc_camera/ar0233_rev1.h | 2 +-
+ drivers/media/i2c/soc_camera/ar0233_rev2.h | 4 +++-
+ 4 files changed, 9 insertions(+), 7 deletions(-)
+
+diff --git a/drivers/media/i2c/soc_camera/ar0233.c b/drivers/media/i2c/soc_camera/ar0233.c
+index 5c3d4e1..862c820 100644
+--- a/drivers/media/i2c/soc_camera/ar0233.c
++++ b/drivers/media/i2c/soc_camera/ar0233.c
+@@ -99,7 +99,7 @@ static int ar0233_set_window(struct v4l2_subdev *sd)
+ struct i2c_client *client = v4l2_get_subdevdata(sd);
+ struct ar0233_priv *priv = to_ar0233(client);
+
+- dev_err(&client->dev, "L=%d T=%d %dx%d\n", priv->rect.left, priv->rect.top, priv->rect.width, priv->rect.height);
++ dev_dbg(&client->dev, "L=%d T=%d %dx%d\n", priv->rect.left, priv->rect.top, priv->rect.width, priv->rect.height);
+
+ /* horiz crop start */
+ reg16_write16(client, 0x3004, priv->rect.left);
+@@ -554,9 +554,9 @@ static int ar0233_probe(struct i2c_client *client,
+ v4l2_ctrl_new_std(&priv->hdl, &ar0233_ctrl_ops,
+ V4L2_CID_EXPOSURE, 1, 0x600, 1, 0x144);
+ v4l2_ctrl_new_std(&priv->hdl, &ar0233_ctrl_ops,
+- V4L2_CID_HFLIP, 0, 1, 1, 0);
++ V4L2_CID_HFLIP, 0, 1, 1, 1);
+ v4l2_ctrl_new_std(&priv->hdl, &ar0233_ctrl_ops,
+- V4L2_CID_VFLIP, 0, 1, 1, 0);
++ V4L2_CID_VFLIP, 0, 1, 1, 1);
+ priv->sd.ctrl_handler = &priv->hdl;
+
+ ret = priv->hdl.error;
+diff --git a/drivers/media/i2c/soc_camera/ar0233.h b/drivers/media/i2c/soc_camera/ar0233.h
+index f6ba245..5f2bada 100644
+--- a/drivers/media/i2c/soc_camera/ar0233.h
++++ b/drivers/media/i2c/soc_camera/ar0233.h
+@@ -17,8 +17,8 @@
+
+ #define AR0233_DELAY 0xffff
+
+-#define AR0233_SENSOR_WIDTH 2058
+-#define AR0233_SENSOR_HEIGHT 1284
++#define AR0233_SENSOR_WIDTH 2072
++#define AR0233_SENSOR_HEIGHT 1296
+
+ #define AR0233_X_START ((AR0233_SENSOR_WIDTH - AR0233_MAX_WIDTH) / 2)
+ #define AR0233_Y_START ((AR0233_SENSOR_HEIGHT - AR0233_MAX_HEIGHT) / 2)
+diff --git a/drivers/media/i2c/soc_camera/ar0233_rev1.h b/drivers/media/i2c/soc_camera/ar0233_rev1.h
+index 7b6370b..ddc1612 100644
+--- a/drivers/media/i2c/soc_camera/ar0233_rev1.h
++++ b/drivers/media/i2c/soc_camera/ar0233_rev1.h
+@@ -1156,8 +1156,8 @@ static const struct ar0233_reg ar0233_rev1_Full_resolution[] = {
+ }; /* Full_resolution */
+
+ static const struct ar0233_reg ar0233_rev1_disable_embed_data_stat[] = {
++{0x3040, 0xC000}, //Embedded stat2 and data2 rows, hflip/vflip=1
+ #ifdef AR0233_EMBEDDED_LINE
+-{0x3040, 0x0000}, //Embedded stat2 and data2 rows
+ {0x3064, 0x0180}, //Enable embedded data and stat
+ #else
+ {0x3064, 0x0}, //Disable embedded data and stat
+diff --git a/drivers/media/i2c/soc_camera/ar0233_rev2.h b/drivers/media/i2c/soc_camera/ar0233_rev2.h
+index 02d9af1..66c79ca 100644
+--- a/drivers/media/i2c/soc_camera/ar0233_rev2.h
++++ b/drivers/media/i2c/soc_camera/ar0233_rev2.h
+@@ -2265,9 +2265,11 @@ static const struct ar0233_reg ar0233_rev2_O1_Recommended_Defaults_SE_T1_LIN_T2[
+ }; /* O1_Recommended_Defaults_SE_T1_LIN_T2 */
+
+ static const struct ar0233_reg ar0233_rev2_disable_embed_data_stat[] = {
+-{0x3064, 0x0}, // Disable embedded data and stat
++{0x3040, 0xC000}, //Embedded stat2 and data2 rows, hflip/vflip=1
+ #ifdef AR0233_EMBEDDED_LINE
+ {0x3064, 0x0180}, // SMIA_TEST: enable emb data and stats
++#else
++{0x3064, 0x0}, // Disable embedded data and stat
+ #endif
+ { }
+ }; /* disable_embed_data_stat */
+--
+2.7.4
+
diff --git a/bsp/meta-rcar/meta-rcar-gen3-adas/recipes-kernel/linux/linux-renesas/0168-lvds-ISX019-fix-add-address-intf-fix-read-write.patch b/bsp/meta-rcar/meta-rcar-gen3-adas/recipes-kernel/linux/linux-renesas/0168-lvds-ISX019-fix-add-address-intf-fix-read-write.patch
new file mode 100644
index 00000000..efe99fbd
--- /dev/null
+++ b/bsp/meta-rcar/meta-rcar-gen3-adas/recipes-kernel/linux/linux-renesas/0168-lvds-ISX019-fix-add-address-intf-fix-read-write.patch
@@ -0,0 +1,228 @@
+From 95a48f63ed8839cce6d91c53a72f67551c2f7a92 Mon Sep 17 00:00:00 2001
+From: Vladimir Barinov <vladimir.barinov@cogentembedded.com>
+Date: Mon, 13 May 2019 16:38:48 +0300
+Subject: [PATCH 117/122] lvds: ISX019: fix add address intf, fix read/write
+
+- Add command/address register access interfaces
+- fix endianess of data
+- read resolution from registers
+---
+ drivers/media/i2c/soc_camera/isx019.c | 112 ++++++++++++++++++++--------------
+ drivers/media/i2c/soc_camera/isx019.h | 9 ++-
+ 2 files changed, 73 insertions(+), 48 deletions(-)
+
+diff --git a/drivers/media/i2c/soc_camera/isx019.c b/drivers/media/i2c/soc_camera/isx019.c
+index 650b533..c2f5a4a 100644
+--- a/drivers/media/i2c/soc_camera/isx019.c
++++ b/drivers/media/i2c/soc_camera/isx019.c
+@@ -25,7 +25,7 @@
+ static const int isx019_i2c_addr[] = {0x1a};
+
+ #define ISX019_PID 0x0000
+-#define ISX019_VERSION_REG 0x0740
++#define ISX019_VERSION_REG 0x4000
+
+ #define ISX019_MEDIA_BUS_FMT MEDIA_BUS_FMT_YUYV8_2X8
+
+@@ -51,6 +51,10 @@ struct isx019_priv {
+ int gpio_fsin;
+ };
+
++static char *intf = "command";
++module_param(intf, charp, 0644);
++MODULE_PARM_DESC(intf, " Registers access interface command,address (default: command)");
++
+ static inline struct isx019_priv *to_isx019(const struct i2c_client *client)
+ {
+ return container_of(i2c_get_clientdata(client), struct isx019_priv, sd);
+@@ -72,31 +76,40 @@ static void isx019_s_port(struct i2c_client *client, int fwd_en)
+
+ static int isx019_read16(struct i2c_client *client, u8 category, u16 reg, u16 *val)
+ {
+- int ret;
++ int ret = -1;
++
++ if (strcmp(intf, "command") == 0) {
+ #define R_NUM_BYTES 9
+ #define R_NUM_CMDS 1
+ #define R_NUM_CMD_BYTES 6
+ #define R_CMD 1
+ #define R_BYTES 2
+- u8 buf[R_NUM_BYTES] = {R_NUM_BYTES, R_NUM_CMDS,
+- R_NUM_CMD_BYTES, R_CMD,
+- category, reg >> 8, reg & 0xff,
+- R_BYTES, 0x00};
+-
+- /* calculate checksum */
+- buf[8] = R_NUM_BYTES + R_NUM_CMDS + R_NUM_CMD_BYTES + R_CMD +
+- category + (reg >> 8) + (reg & 0xff) + R_BYTES;
+-
+- ret = i2c_master_send(client, buf, R_NUM_BYTES);
+- if (ret == R_NUM_BYTES)
+- ret = i2c_master_recv(client, buf, R_NUM_BYTES - 2);
+-
+- if (ret < 0) {
+- dev_err(&client->dev,
+- "read fail: chip 0x%x register 0x%x: %d\n",
+- client->addr, reg, ret);
++ u8 buf[R_NUM_BYTES] = {R_NUM_BYTES, R_NUM_CMDS,
++ R_NUM_CMD_BYTES, R_CMD,
++ category, reg >> 8, reg & 0xff,
++ R_BYTES, 0x00};
++
++ /* calculate checksum */
++ buf[8] = R_NUM_BYTES + R_NUM_CMDS + R_NUM_CMD_BYTES + R_CMD +
++ category + (reg >> 8) + (reg & 0xff) + R_BYTES;
++
++ ret = i2c_master_send(client, buf, R_NUM_BYTES);
++ if (ret == R_NUM_BYTES)
++ ret = i2c_master_recv(client, buf, R_NUM_BYTES - 2);
++
++ if (ret < 0) {
++ dev_err(&client->dev,
++ "read fail: chip 0x%x register 0x%x: %d\n",
++ client->addr, reg, ret);
++ } else {
++ *val = buf[4] | ((u16)buf[5] << 8);
++ }
++ } else if (strcmp(intf, "address") == 0) {
++ reg16_write(client, 0xFFFF, category);
++ ret = reg16_read16(client, reg, val);
++ *val = swab16p(val);
+ } else {
+- *val = ((u16)buf[4] << 8) | buf[5];
++ dev_err(&client->dev, "invalid register access interface %s\n", intf);
+ }
+
+ return ret < 0 ? ret : 0;
+@@ -104,26 +117,35 @@ static int isx019_read16(struct i2c_client *client, u8 category, u16 reg, u16 *v
+
+ static int isx019_write16(struct i2c_client *client, u8 category, u16 reg, u16 val)
+ {
+- int ret;
++ int ret = -1;
++
++ if (strcmp(intf, "command") == 0) {
+ #define W_NUM_BYTES 10
+ #define W_NUM_CMDS 1
+ #define W_NUM_CMD_BYTES 7
+ #define W_CMD 2
+- u8 buf[W_NUM_BYTES] = {W_NUM_BYTES, W_NUM_CMDS,
+- W_NUM_CMD_BYTES, W_CMD,
+- category, reg >> 8, reg & 0xff,
+- val >> 8, val & 0xff};
++ u8 buf[W_NUM_BYTES] = {W_NUM_BYTES, W_NUM_CMDS,
++ W_NUM_CMD_BYTES, W_CMD,
++ category, reg >> 8, reg & 0xff,
++ val & 0xff, val >> 8};
+
+- /* calculate checksum */
+- buf[9] = W_NUM_BYTES + W_NUM_CMDS + W_NUM_CMD_BYTES + W_CMD +
+- category + (reg >> 8) + (reg & 0xff) + (val >> 8) + (val & 0xff);
++ /* calculate checksum */
++ buf[9] = W_NUM_BYTES + W_NUM_CMDS + W_NUM_CMD_BYTES + W_CMD +
++ category + (reg >> 8) + (reg & 0xff) + (val >> 8) + (val & 0xff);
+
+- ret = i2c_master_send(client, buf, W_NUM_BYTES);
++ ret = i2c_master_send(client, buf, W_NUM_BYTES);
+
+- if (ret < 0) {
+- dev_err(&client->dev,
+- "write fail: chip 0x%x register 0x%x: %d\n",
+- client->addr, reg, ret);
++ if (ret < 0) {
++ dev_err(&client->dev,
++ "write fail: chip 0x%x register 0x%x: %d\n",
++ client->addr, reg, ret);
++ }
++ } else if (strcmp(intf, "address") == 0) {
++ val = swab16(val);
++ reg16_write(client, 0xFFFF, category);
++ ret = reg16_write16(client, reg, val);
++ } else {
++ dev_err(&client->dev, "invalid register acces interface %s\n", intf);
+ }
+
+ return ret < 0 ? ret : 0;
+@@ -404,13 +426,11 @@ static DEVICE_ATTR(otp_id_isx019, S_IRUGO, isx019_otp_id_show, NULL);
+ static int isx019_initialize(struct i2c_client *client)
+ {
+ struct isx019_priv *priv = to_isx019(client);
+- u16 pid = 0;
++ u16 pid = 0, val = 0;
+ int ret = 0;
+ int tmp_addr;
+ int i;
+
+- isx019_s_port(client, 1);
+-
+ for (i = 0; i < ARRAY_SIZE(isx019_i2c_addr); i++) {
+ tmp_addr = client->addr;
+ if (priv->max9286_addr) {
+@@ -423,26 +443,28 @@ static int isx019_initialize(struct i2c_client *client)
+ /* check model ID */
+ isx019_read16(client, 0, ISX019_PID, &pid);
+
+- if (pid == ISX019_VERSION_REG)
++ if ((pid & 0xff00) == ISX019_VERSION_REG)
+ break;
+ }
+
+- if (pid != ISX019_VERSION_REG) {
+- dev_dbg(&client->dev, "Product ID error %x\n", pid);
++ if ((pid & 0xff00) != ISX019_VERSION_REG) {
++ dev_err(&client->dev, "Product ID error %x\n", pid);
+ ret = -ENODEV;
+ goto err;
+ }
+
+- priv->max_width = ISX019_MAX_WIDTH;
+- priv->max_height = ISX019_MAX_HEIGHT;
+-
+ /* Read OTP IDs */
+ isx019_otp_id_read(client);
+ /* Program wizard registers */
+ isx019_set_regs(client, isx019_regs_wizard, ARRAY_SIZE(isx019_regs_wizard));
+-
+- dev_info(&client->dev, "isx019 PID %x, res %dx%d, OTP_ID %02x:%02x:%02x:%02x:%02x:%02x\n",
+- pid, priv->max_width, priv->max_height, priv->id[0], priv->id[1], priv->id[2], priv->id[3], priv->id[4], priv->id[5]);
++ /* read resolution used by current firmware */
++ isx019_read16(client, 86, 0x8, &val);
++ priv->max_width = val;
++ isx019_read16(client, 86, 0xa, &val);
++ priv->max_height = val;
++
++ dev_info(&client->dev, "isx019 PID %x (rev %x), res %dx%d, if=%s, OTP_ID %02x:%02x:%02x:%02x:%02x:%02x\n",
++ pid & 0xff00, pid & 0xff, priv->max_width, priv->max_height, intf, priv->id[0], priv->id[1], priv->id[2], priv->id[3], priv->id[4], priv->id[5]);
+ err:
+ isx019_s_port(client, 0);
+
+diff --git a/drivers/media/i2c/soc_camera/isx019.h b/drivers/media/i2c/soc_camera/isx019.h
+index edaa767..c7072a3 100644
+--- a/drivers/media/i2c/soc_camera/isx019.h
++++ b/drivers/media/i2c/soc_camera/isx019.h
+@@ -9,8 +9,8 @@
+ * option) any later version.
+ */
+
+-#define ISX019_MAX_WIDTH 1280
+-#define ISX019_MAX_HEIGHT 800
++//#define ISX019_MAX_WIDTH 1280
++//#define ISX019_MAX_HEIGHT 960
+
+ #define ISX019_DELAY 0xffff
+
+@@ -22,6 +22,9 @@ struct isx019_reg {
+ static const struct isx019_reg isx019_regs_wizard[] = {
+ #if 0
+ /* enable FSIN */
+-#endif
+ {ISX019_DELAY, 100},
++#endif
++/* disable embedded data */
++{0x504c, 0x0},
++{0x504e, 0x0},
+ };
+--
+2.7.4
+
diff --git a/bsp/meta-rcar/meta-rcar-gen3-adas/recipes-kernel/linux/linux-renesas/0169-lvds-OVT-add-dvp_order-parameter-for-ov10635.patch b/bsp/meta-rcar/meta-rcar-gen3-adas/recipes-kernel/linux/linux-renesas/0169-lvds-OVT-add-dvp_order-parameter-for-ov10635.patch
new file mode 100644
index 00000000..8b8a8385
--- /dev/null
+++ b/bsp/meta-rcar/meta-rcar-gen3-adas/recipes-kernel/linux/linux-renesas/0169-lvds-OVT-add-dvp_order-parameter-for-ov10635.patch
@@ -0,0 +1,67 @@
+From ec363617669effd4e49f0b27ab12015a60455930 Mon Sep 17 00:00:00 2001
+From: Vladimir Barinov <vladimir.barinov@cogentembedded.com>
+Date: Tue, 14 May 2019 16:33:15 +0300
+Subject: [PATCH 118/122] lvds: OVT: add dvp_order parameter for ov10635
+
+Fix dvp_order for both ov490 and ov10635
+
+Signed-off-by: Vladimir Barinov <vladimir.barinov@cogentembedded.com>
+---
+ drivers/media/i2c/soc_camera/ov10635.c | 9 +++++++++
+ drivers/media/i2c/soc_camera/ov490_ov10640.c | 6 +-----
+ 2 files changed, 10 insertions(+), 5 deletions(-)
+
+diff --git a/drivers/media/i2c/soc_camera/ov10635.c b/drivers/media/i2c/soc_camera/ov10635.c
+index 916173c..1bbde91 100644
+--- a/drivers/media/i2c/soc_camera/ov10635.c
++++ b/drivers/media/i2c/soc_camera/ov10635.c
+@@ -50,6 +50,11 @@ struct ov10635_priv {
+ int gpio_fsin;
+ };
+
++
++static int dvp_order = -1;
++module_param(dvp_order, int, 0644);
++MODULE_PARM_DESC(dvp_order, " DVP bus bits order");
++
+ static inline struct ov10635_priv *to_ov10635(const struct i2c_client *client)
+ {
+ return container_of(i2c_get_clientdata(client), struct ov10635_priv, sd);
+@@ -601,6 +606,10 @@ static int ov10635_parse_dt(struct device_node *np, struct ov10635_priv *priv)
+
+ udelay(100);
+
++ /* module params override dts */
++ if (dvp_order != -1)
++ priv->dvp_order = dvp_order;
++
+ return 0;
+ }
+
+diff --git a/drivers/media/i2c/soc_camera/ov490_ov10640.c b/drivers/media/i2c/soc_camera/ov490_ov10640.c
+index 1c8aac8..0ea9a54 100644
+--- a/drivers/media/i2c/soc_camera/ov490_ov10640.c
++++ b/drivers/media/i2c/soc_camera/ov490_ov10640.c
+@@ -69,10 +69,6 @@ static int conf_link;
+ module_param(conf_link, int, 0644);
+ MODULE_PARM_DESC(conf_link, " Force configuration link. Used only if robust firmware flashing required (f.e. recovery)");
+
+-static int dvp_order;
+-module_param(dvp_order, int, 0644);
+-MODULE_PARM_DESC(dvp_order, " DVP bus bits order");
+-
+ static int max_width;
+ module_param(max_width, int, 0644);
+ MODULE_PARM_DESC(max_width, " Fixed sensor width");
+@@ -972,7 +968,7 @@ static int ov490_parse_dt(struct device_node *np, struct ov490_priv *priv)
+ }
+
+ /* module params override dts */
+- if (dvp_order)
++ if (dvp_order != -1)
+ priv->dvp_order = dvp_order;
+ if (max_width && max_height) {
+ priv->max_width = max_width;
+--
+2.7.4
+
diff --git a/bsp/meta-rcar/meta-rcar-gen3-adas/recipes-kernel/linux/linux-renesas/0170-media-i2c-add-AR0147-imager.patch b/bsp/meta-rcar/meta-rcar-gen3-adas/recipes-kernel/linux/linux-renesas/0170-media-i2c-add-AR0147-imager.patch
new file mode 100644
index 00000000..b07b7b87
--- /dev/null
+++ b/bsp/meta-rcar/meta-rcar-gen3-adas/recipes-kernel/linux/linux-renesas/0170-media-i2c-add-AR0147-imager.patch
@@ -0,0 +1,2224 @@
+From 0901b9accc0ee11072daebedbc385cf38364144a Mon Sep 17 00:00:00 2001
+From: Vladimir Barinov <vladimir.barinov@cogentembedded.com>
+Date: Sun, 21 Apr 2019 19:44:00 +0300
+Subject: [PATCH 119/122] media: i2c: add AR0147 imager
+
+This adds AR0147 imager
+
+Signed-off-by: Vladimir Barinov <vladimir.barinov@cogentembedded.com>
+---
+ drivers/media/i2c/soc_camera/Kconfig | 6 +
+ drivers/media/i2c/soc_camera/Makefile | 1 +
+ drivers/media/i2c/soc_camera/ar0147.c | 714 ++++++++++++++++++++++++++
+ drivers/media/i2c/soc_camera/ar0147.h | 36 ++
+ drivers/media/i2c/soc_camera/ar0147_rev1.h | 607 ++++++++++++++++++++++
+ drivers/media/i2c/soc_camera/ar0147_rev2.h | 796 +++++++++++++++++++++++++++++
+ 6 files changed, 2160 insertions(+)
+ create mode 100644 drivers/media/i2c/soc_camera/ar0147.c
+ create mode 100644 drivers/media/i2c/soc_camera/ar0147.h
+ create mode 100644 drivers/media/i2c/soc_camera/ar0147_rev1.h
+ create mode 100644 drivers/media/i2c/soc_camera/ar0147_rev2.h
+
+diff --git a/drivers/media/i2c/soc_camera/Kconfig b/drivers/media/i2c/soc_camera/Kconfig
+index 627d8d9..edff0b0 100644
+--- a/drivers/media/i2c/soc_camera/Kconfig
++++ b/drivers/media/i2c/soc_camera/Kconfig
+@@ -106,3 +106,9 @@ config SOC_CAMERA_IMX219
+ depends on SOC_CAMERA && I2C
+ help
+ This is Sony IMX219 driver
++
++config SOC_CAMERA_AR0147
++ tristate "AR0147 camera support"
++ depends on SOC_CAMERA && I2C
++ help
++ This is an AR0147 imager glue
+diff --git a/drivers/media/i2c/soc_camera/Makefile b/drivers/media/i2c/soc_camera/Makefile
+index 4aa5046..367674b 100644
+--- a/drivers/media/i2c/soc_camera/Makefile
++++ b/drivers/media/i2c/soc_camera/Makefile
+@@ -17,3 +17,4 @@ obj-$(CONFIG_SOC_CAMERA_OV106XX) += ov106xx.o
+ obj-$(CONFIG_SOC_CAMERA_IMX219) += imx219.o
+ obj-y += dummy.o
+
++obj-$(CONFIG_SOC_CAMERA_AR0147) += ar0147.o
+diff --git a/drivers/media/i2c/soc_camera/ar0147.c b/drivers/media/i2c/soc_camera/ar0147.c
+new file mode 100644
+index 0000000..cc7face
+--- /dev/null
++++ b/drivers/media/i2c/soc_camera/ar0147.c
+@@ -0,0 +1,714 @@
++/*
++ * ON Semiconductor AR0147 sensor camera driver
++ *
++ * Copyright (C) 2019 Cogent Embedded, Inc.
++ *
++ * This program is free software; you can redistribute it and/or modify it
++ * under the terms of the GNU General Public License as published by the
++ * Free Software Foundation; either version 2 of the License, or (at your
++ * option) any later version.
++ */
++
++#include <linux/delay.h>
++#include <linux/init.h>
++#include <linux/i2c.h>
++#include <linux/module.h>
++#include <linux/of_graph.h>
++#include <linux/videodev2.h>
++
++#include <media/soc_camera.h>
++#include <media/v4l2-common.h>
++#include <media/v4l2-ctrls.h>
++
++#include "max9286.h"
++#include "ar0147.h"
++
++#define AR0147_I2C_ADDR 0x10
++
++#define AR0147_PID 0x3000
++#define AR0147_REV 0x31FE
++#define AR0147_VERSION_REG 0x1D54
++
++#define AR0147_MEDIA_BUS_FMT MEDIA_BUS_FMT_SGRBG12_1X12
++
++struct ar0147_priv {
++ struct v4l2_subdev sd;
++ struct v4l2_ctrl_handler hdl;
++ struct media_pad pad;
++ struct v4l2_rect rect;
++ int init_complete;
++ u8 id[6];
++ /* serializers */
++ int max9286_addr;
++ int max9271_addr;
++ int ti9x4_addr;
++ int ti9x3_addr;
++ int port;
++ int gpio_resetb;
++ int gpio_fsin;
++ int hts;
++ int vts;
++ int frame_preamble;
++};
++
++static char *mode = "hdr";
++module_param(mode, charp, 0644);
++MODULE_PARM_DESC(mode, " Modes linear,hdr,se,seplus (default: hdr)");
++
++static inline struct ar0147_priv *to_ar0147(const struct i2c_client *client)
++{
++ return container_of(i2c_get_clientdata(client), struct ar0147_priv, sd);
++}
++
++static inline struct v4l2_subdev *to_sd(struct v4l2_ctrl *ctrl)
++{
++ return &container_of(ctrl->handler, struct ar0147_priv, hdl)->sd;
++}
++
++static void ar0147_s_port(struct i2c_client *client, int fwd_en)
++{
++ struct ar0147_priv *priv = to_ar0147(client);
++ int tmp_addr;
++
++ if (priv->max9286_addr) {
++ tmp_addr = client->addr;
++ client->addr = priv->max9286_addr; /* Deserializer I2C address */
++ reg8_write(client, 0x0a, fwd_en ? 0x11 << priv->port : 0); /* Enable/disable reverse/forward control for this port */
++ usleep_range(5000, 5500); /* wait 5ms */
++ client->addr = tmp_addr;
++ };
++}
++
++static int ar0147_set_regs(struct i2c_client *client, const struct ar0147_reg **pregs)
++{
++ struct ar0147_priv *priv = to_ar0147(client);
++ const struct ar0147_reg *regs;
++ int i, j;
++
++ for (j = 0; ; j++) {
++ regs = pregs[j];
++
++ if (!pregs[j])
++ break;
++
++ for (i = 0; ; i++) {
++ if (!regs[i].reg && !regs[i].val)
++ break;
++
++ if (regs[i].reg == AR0147_DELAY) {
++ mdelay(regs[i].val);
++ continue;
++ }
++ /* cache timings */
++ if (regs[i].reg == 0x300a)
++ priv->vts = regs[i].val;
++ if (regs[i].reg == 0x300c)
++ priv->hts = regs[i].val;
++ if (regs[i].reg == 0x31b0)
++ priv->frame_preamble = regs[i].val - 1;
++
++ if (priv->ti9x4_addr) {
++ /* Override default (MAXIM serializer) table */
++ /* PCLK=16Mhz/2 *48/1/8= 48Mhz - TI serializers */
++ switch (regs[i].reg) {
++ case 0x302A:
++ reg16_write16(client, regs[i].reg, 8); // VT_PIX_CLK_DIV
++ continue;
++ case 0x302C:
++ reg16_write16(client, regs[i].reg, 1); // VT_SYS_CLK_DIV
++ continue;
++ case 0x302E:
++ reg16_write16(client, regs[i].reg, 2); // PRE_PLL_CLK_DIV
++ continue;
++ case 0x3030:
++ reg16_write16(client, regs[i].reg, 48); // PLL_MULTIPLIER
++ continue;
++ case 0x3036:
++ reg16_write16(client, regs[i].reg, 8); // OP_WORD_CLK_DIV
++ continue;
++ case 0x3038:
++ reg16_write16(client, regs[i].reg, 1); // OP_SYS_CLK_DIV
++ continue;
++ case 0x300A:
++ reg16_write16(client, regs[i].reg, AR0147_SENSOR_HEIGHT + 142); // FRAME_LENGTH_LINES_
++ continue;
++ }
++ }
++
++ reg16_write16(client, regs[i].reg, regs[i].val);
++ }
++ }
++
++ return 0;
++}
++
++static int ar0147_s_stream(struct v4l2_subdev *sd, int enable)
++{
++ return 0;
++}
++
++static int ar0147_set_window(struct v4l2_subdev *sd)
++{
++ struct i2c_client *client = v4l2_get_subdevdata(sd);
++ struct ar0147_priv *priv = to_ar0147(client);
++
++ dev_dbg(&client->dev, "L=%d T=%d %dx%d\n", priv->rect.left, priv->rect.top, priv->rect.width, priv->rect.height);
++
++ /* horiz crop start */
++ reg16_write16(client, 0x3004, priv->rect.left);
++ /* horiz crop end */
++ reg16_write16(client, 0x3008, priv->rect.left + priv->rect.width - 1);
++ /* vert crop start */
++ reg16_write16(client, 0x3002, priv->rect.top);
++ /* vert crop end */
++ reg16_write16(client, 0x3006, priv->rect.top + priv->rect.height - 1);
++
++ return 0;
++};
++
++static int ar0147_get_fmt(struct v4l2_subdev *sd,
++ struct v4l2_subdev_pad_config *cfg,
++ struct v4l2_subdev_format *format)
++{
++ struct v4l2_mbus_framefmt *mf = &format->format;
++ struct i2c_client *client = v4l2_get_subdevdata(sd);
++ struct ar0147_priv *priv = to_ar0147(client);
++
++ if (format->pad)
++ return -EINVAL;
++
++ mf->width = priv->rect.width;
++ mf->height = priv->rect.height;
++ mf->code = AR0147_MEDIA_BUS_FMT;
++ mf->colorspace = V4L2_COLORSPACE_SMPTE170M;
++ mf->field = V4L2_FIELD_NONE;
++
++ return 0;
++}
++
++static int ar0147_set_fmt(struct v4l2_subdev *sd,
++ struct v4l2_subdev_pad_config *cfg,
++ struct v4l2_subdev_format *format)
++{
++ struct v4l2_mbus_framefmt *mf = &format->format;
++
++ mf->code = AR0147_MEDIA_BUS_FMT;
++ mf->colorspace = V4L2_COLORSPACE_SMPTE170M;
++ mf->field = V4L2_FIELD_NONE;
++
++ if (format->which == V4L2_SUBDEV_FORMAT_TRY)
++ cfg->try_fmt = *mf;
++
++ return 0;
++}
++
++static int ar0147_enum_mbus_code(struct v4l2_subdev *sd,
++ struct v4l2_subdev_pad_config *cfg,
++ struct v4l2_subdev_mbus_code_enum *code)
++{
++ if (code->pad || code->index > 0)
++ return -EINVAL;
++
++ code->code = AR0147_MEDIA_BUS_FMT;
++
++ return 0;
++}
++
++static int ar0147_get_edid(struct v4l2_subdev *sd, struct v4l2_edid *edid)
++{
++ struct i2c_client *client = v4l2_get_subdevdata(sd);
++ struct ar0147_priv *priv = to_ar0147(client);
++
++ memcpy(edid->edid, priv->id, 6);
++
++ edid->edid[6] = 0xff;
++ edid->edid[7] = client->addr;
++ edid->edid[8] = AR0147_VERSION_REG >> 8;
++ edid->edid[9] = AR0147_VERSION_REG & 0xff;
++
++ return 0;
++}
++
++static int ar0147_set_selection(struct v4l2_subdev *sd,
++ struct v4l2_subdev_pad_config *cfg,
++ struct v4l2_subdev_selection *sel)
++{
++ struct v4l2_rect *rect = &sel->r;
++ struct i2c_client *client = v4l2_get_subdevdata(sd);
++ struct ar0147_priv *priv = to_ar0147(client);
++
++ if (sel->which != V4L2_SUBDEV_FORMAT_ACTIVE ||
++ sel->target != V4L2_SEL_TGT_CROP)
++ return -EINVAL;
++
++ rect->left = ALIGN(rect->left, 2);
++ rect->top = ALIGN(rect->top, 2);
++ rect->width = ALIGN(rect->width, 2);
++ rect->height = ALIGN(rect->height, 2);
++
++ if ((rect->left + rect->width > AR0147_MAX_WIDTH) ||
++ (rect->top + rect->height > AR0147_MAX_HEIGHT))
++ *rect = priv->rect;
++
++ priv->rect.left = rect->left;
++ priv->rect.top = rect->top;
++ priv->rect.width = rect->width;
++ priv->rect.height = rect->height;
++
++ ar0147_set_window(sd);
++
++ return 0;
++}
++
++static int ar0147_get_selection(struct v4l2_subdev *sd,
++ struct v4l2_subdev_pad_config *cfg,
++ struct v4l2_subdev_selection *sel)
++{
++ struct i2c_client *client = v4l2_get_subdevdata(sd);
++ struct ar0147_priv *priv = to_ar0147(client);
++
++ if (sel->which != V4L2_SUBDEV_FORMAT_ACTIVE)
++ return -EINVAL;
++
++ switch (sel->target) {
++ case V4L2_SEL_TGT_CROP_BOUNDS:
++ sel->r.left = 0;
++ sel->r.top = 0;
++ sel->r.width = AR0147_MAX_WIDTH;
++ sel->r.height = AR0147_MAX_HEIGHT;
++ return 0;
++ case V4L2_SEL_TGT_CROP_DEFAULT:
++ sel->r.left = 0;
++ sel->r.top = 0;
++ sel->r.width = AR0147_MAX_WIDTH;
++ sel->r.height = AR0147_MAX_HEIGHT;
++ return 0;
++ case V4L2_SEL_TGT_CROP:
++ sel->r = priv->rect;
++ return 0;
++ default:
++ return -EINVAL;
++ }
++}
++
++static int ar0147_g_mbus_config(struct v4l2_subdev *sd,
++ struct v4l2_mbus_config *cfg)
++{
++ cfg->flags = V4L2_MBUS_CSI2_1_LANE | V4L2_MBUS_CSI2_CHANNEL_0 |
++ V4L2_MBUS_CSI2_CONTINUOUS_CLOCK;
++ cfg->type = V4L2_MBUS_CSI2;
++
++ return 0;
++}
++
++#ifdef CONFIG_VIDEO_ADV_DEBUG
++static int ar0147_g_register(struct v4l2_subdev *sd,
++ struct v4l2_dbg_register *reg)
++{
++ struct i2c_client *client = v4l2_get_subdevdata(sd);
++ int ret;
++ u16 val = 0;
++
++ ret = reg16_read16(client, (u16)reg->reg, &val);
++ if (ret < 0)
++ return ret;
++
++ reg->val = val;
++ reg->size = sizeof(u16);
++
++ return 0;
++}
++
++static int ar0147_s_register(struct v4l2_subdev *sd,
++ const struct v4l2_dbg_register *reg)
++{
++ struct i2c_client *client = v4l2_get_subdevdata(sd);
++
++ return reg16_write16(client, (u16)reg->reg, (u16)reg->val);
++}
++#endif
++
++static struct v4l2_subdev_core_ops ar0147_core_ops = {
++#ifdef CONFIG_VIDEO_ADV_DEBUG
++ .g_register = ar0147_g_register,
++ .s_register = ar0147_s_register,
++#endif
++};
++
++static int ar0147_s_ctrl(struct v4l2_ctrl *ctrl)
++{
++ struct v4l2_subdev *sd = to_sd(ctrl);
++ struct i2c_client *client = v4l2_get_subdevdata(sd);
++ struct ar0147_priv *priv = to_ar0147(client);
++ int ret = -EINVAL;
++ u16 val = 0;
++
++ if (!priv->init_complete)
++ return 0;
++
++ switch (ctrl->id) {
++ case V4L2_CID_BRIGHTNESS:
++ case V4L2_CID_CONTRAST:
++ case V4L2_CID_SATURATION:
++ case V4L2_CID_HUE:
++ case V4L2_CID_GAMMA:
++ case V4L2_CID_SHARPNESS:
++ case V4L2_CID_AUTOGAIN:
++ break;
++ case V4L2_CID_GAIN:
++ /* Digital gain */
++ ret = reg16_write16(client, 0x3308, ctrl->val);
++ break;
++ case V4L2_CID_ANALOGUE_GAIN:
++ /* Analog gain */
++ ret = reg16_write16(client, 0x3366, ctrl->val);
++ break;
++ case V4L2_CID_EXPOSURE:
++ /* T1 exposure */
++ ret = reg16_write16(client, 0x3012, ctrl->val);
++ break;
++ case V4L2_CID_HFLIP:
++ ret = reg16_read16(client, 0x3040, &val);
++ if (ctrl->val)
++ val |= 0x4000;
++ else
++ val &= ~0x4000;
++ ret |= reg16_write16(client, 0x3040, val);
++ break;
++ case V4L2_CID_VFLIP:
++ ret = reg16_read16(client, 0x3040, &val);
++ if (ctrl->val)
++ val |= 0x8000;
++ else
++ val &= ~0x8000;
++ ret |= reg16_write16(client, 0x3040, val);
++ break;
++ case V4L2_CID_MIN_BUFFERS_FOR_CAPTURE:
++ ret = 0;
++ break;
++ }
++
++ return ret;
++}
++
++static const struct v4l2_ctrl_ops ar0147_ctrl_ops = {
++ .s_ctrl = ar0147_s_ctrl,
++};
++
++static struct v4l2_subdev_video_ops ar0147_video_ops = {
++ .s_stream = ar0147_s_stream,
++ .g_mbus_config = ar0147_g_mbus_config,
++};
++
++static const struct v4l2_subdev_pad_ops ar0147_subdev_pad_ops = {
++ .get_edid = ar0147_get_edid,
++ .enum_mbus_code = ar0147_enum_mbus_code,
++ .get_selection = ar0147_get_selection,
++ .set_selection = ar0147_set_selection,
++ .get_fmt = ar0147_get_fmt,
++ .set_fmt = ar0147_set_fmt,
++};
++
++static struct v4l2_subdev_ops ar0147_subdev_ops = {
++ .core = &ar0147_core_ops,
++ .video = &ar0147_video_ops,
++ .pad = &ar0147_subdev_pad_ops,
++};
++
++static void ar0147_otp_id_read(struct i2c_client *client)
++{
++ struct ar0147_priv *priv = to_ar0147(client);
++ int i;
++ u16 val = 0;
++
++ /* read camera id from ar014x OTP memory */
++ reg16_write16(client, 0x3054, 0x400);
++ reg16_write16(client, 0x304a, 0x110);
++ usleep_range(25000, 25500); /* wait 25 ms */
++
++ for (i = 0; i < 6; i += 2) {
++ /* first 4 bytes are equal on all ar014x */
++ reg16_read16(client, 0x3800 + i + 4, &val);
++ priv->id[i] = val >> 8;
++ priv->id[i + 1] = val & 0xff;
++ }
++}
++
++static ssize_t ar0147_otp_id_show(struct device *dev,
++ struct device_attribute *attr, char *buf)
++{
++ struct v4l2_subdev *sd = i2c_get_clientdata(to_i2c_client(dev));
++ struct i2c_client *client = v4l2_get_subdevdata(sd);
++ struct ar0147_priv *priv = to_ar0147(client);
++
++ ar0147_otp_id_read(client);
++
++ return snprintf(buf, 32, "%02x:%02x:%02x:%02x:%02x:%02x\n",
++ priv->id[0], priv->id[1], priv->id[2], priv->id[3], priv->id[4], priv->id[5]);
++}
++
++static DEVICE_ATTR(otp_id_ar0147, S_IRUGO, ar0147_otp_id_show, NULL);
++
++static int ar0147_initialize(struct i2c_client *client)
++{
++ struct ar0147_priv *priv = to_ar0147(client);
++ u16 val = 0;
++ u16 pid = 0, rev = 0;
++ int ret = 0;
++ int tmp_addr;
++
++ ar0147_s_port(client, 1);
++
++ /* check and show model ID */
++ reg16_read16(client, AR0147_PID, &pid);
++
++ if (pid != AR0147_VERSION_REG) {
++ dev_dbg(&client->dev, "Product ID error %x\n\n\n", pid);
++ ret = -ENODEV;
++ goto err;
++ }
++
++ /* check revision */
++ reg16_read16(client, AR0147_REV, &rev);
++ /* Read OTP IDs */
++ ar0147_otp_id_read(client);
++ /* Program wizard registers */
++ switch (rev & 0xf) {
++ case 0x1:
++ ar0147_set_regs(client, ar0147_regs_hdr_mipi450mbps_12bit_30fps_rev1);
++ break;
++ case 0x2:
++ if (strcmp(mode, "hdr") == 0)
++ ar0147_set_regs(client, ar0147_regs_hdr_mipi450mbps_12bit_30fps_rev2);
++ else if (strcmp(mode, "seplus") == 0)
++ ar0147_set_regs(client, ar0147_regs_seplus_mipi450mbps_12bit_30fps_rev2);
++ else
++ dev_err(&client->dev, "Unsupported mode %s\n", mode);
++ break;
++ default:
++ dev_err(&client->dev, "Unsupported chip revision\n");
++ }
++
++ tmp_addr = client->addr;
++ if (priv->max9271_addr) {
++ /* setup serializer HS generator */
++ client->addr = priv->max9271_addr; /* Serializer I2C address */
++ reg8_write(client, 0x4e, priv->frame_preamble >> 16); /* HS delay */
++ reg8_write(client, 0x4f, (priv->frame_preamble >> 8) & 0xff);
++ reg8_write(client, 0x50, priv->frame_preamble & 0xff);
++ reg8_write(client, 0x54, AR0147_MAX_WIDTH >> 8); /* HS high period */
++ reg8_write(client, 0x55, AR0147_MAX_WIDTH & 0xff);
++ reg8_write(client, 0x56, (priv->hts - AR0147_MAX_WIDTH) >> 8); /* HS low period */
++ reg8_write(client, 0x57, (priv->hts - AR0147_MAX_WIDTH) & 0xff);
++ reg8_write(client, 0x58, priv->vts >> 8); /* HS count */
++ reg8_write(client, 0x59, priv->vts & 0xff);
++ }
++ client->addr = tmp_addr;
++
++ /* Enable stream */
++ reg16_read16(client, 0x301a, &val);
++ val |= (1 << 2);
++ reg16_write16(client, 0x301a, val);
++
++ dev_info(&client->dev, "ar0147 PID %x (rev %x), res %dx%d, mode=%s, OTP_ID %02x:%02x:%02x:%02x:%02x:%02x\n",
++ pid, rev, AR0147_MAX_WIDTH, AR0147_MAX_HEIGHT, mode, priv->id[0], priv->id[1], priv->id[2], priv->id[3], priv->id[4], priv->id[5]);
++err:
++ ar0147_s_port(client, 0);
++
++ return ret;
++}
++
++static int ar0147_parse_dt(struct device_node *np, struct ar0147_priv *priv)
++{
++ struct i2c_client *client = v4l2_get_subdevdata(&priv->sd);
++ int i;
++ struct device_node *endpoint = NULL, *rendpoint = NULL;
++ int tmp_addr = 0;
++
++ for (i = 0; ; i++) {
++ endpoint = of_graph_get_next_endpoint(np, endpoint);
++ if (!endpoint)
++ break;
++
++ rendpoint = of_parse_phandle(endpoint, "remote-endpoint", 0);
++ if (!rendpoint)
++ continue;
++
++ if (!of_property_read_u32(rendpoint, "max9271-addr", &priv->max9271_addr) &&
++ !of_property_read_u32(rendpoint->parent->parent, "reg", &priv->max9286_addr) &&
++ !kstrtouint(strrchr(rendpoint->full_name, '@') + 1, 0, &priv->port))
++ break;
++
++ if (!of_property_read_u32(rendpoint, "ti9x3-addr", &priv->ti9x3_addr) &&
++ !of_property_match_string(rendpoint->parent->parent, "compatible", "ti,ti9x4") &&
++ !of_property_read_u32(rendpoint->parent->parent, "reg", &priv->ti9x4_addr) &&
++ !kstrtouint(strrchr(rendpoint->full_name, '@') + 1, 0, &priv->port))
++ break;
++ }
++
++ of_node_put(endpoint);
++
++ if (!priv->max9286_addr && !priv->ti9x4_addr) {
++ dev_err(&client->dev, "deserializer does not present for AR0147\n");
++// return -EINVAL;
++ }
++
++ ar0147_s_port(client, 1);
++
++ /* setup I2C translator address */
++ tmp_addr = client->addr;
++ if (priv->max9286_addr) {
++ client->addr = priv->max9271_addr; /* Serializer I2C address */
++
++ reg8_write(client, 0x09, tmp_addr << 1); /* Sensor translated I2C address */
++ reg8_write(client, 0x0A, AR0147_I2C_ADDR << 1); /* Sensor native I2C address */
++ usleep_range(2000, 2500); /* wait 2ms */
++ };
++ if (priv->ti9x4_addr) {
++ client->addr = priv->ti9x4_addr; /* Deserializer I2C address */
++
++ reg8_write(client, 0x4c, (priv->port << 4) | (1 << priv->port)); /* Select RX port number */
++ usleep_range(2000, 2500); /* wait 2ms */
++ reg8_write(client, 0x65, tmp_addr << 1); /* Sensor translated I2C address */
++ reg8_write(client, 0x5d, AR0147_I2C_ADDR << 1); /* Sensor native I2C address */
++
++ reg8_write(client, 0x6e, 0xa9); /* GPIO0 - reset, GPIO1 - fsin */
++ }
++ client->addr = tmp_addr;
++
++ mdelay(10);
++
++ return 0;
++}
++
++static int ar0147_probe(struct i2c_client *client,
++ const struct i2c_device_id *did)
++{
++ struct ar0147_priv *priv;
++ int ret;
++
++ priv = devm_kzalloc(&client->dev, sizeof(*priv), GFP_KERNEL);
++ if (!priv)
++ return -ENOMEM;
++
++ v4l2_i2c_subdev_init(&priv->sd, client, &ar0147_subdev_ops);
++ priv->sd.flags = V4L2_SUBDEV_FL_HAS_DEVNODE;
++
++ v4l2_ctrl_handler_init(&priv->hdl, 4);
++ v4l2_ctrl_new_std(&priv->hdl, &ar0147_ctrl_ops,
++ V4L2_CID_BRIGHTNESS, 0, 16, 1, 7);
++ v4l2_ctrl_new_std(&priv->hdl, &ar0147_ctrl_ops,
++ V4L2_CID_CONTRAST, 0, 16, 1, 7);
++ v4l2_ctrl_new_std(&priv->hdl, &ar0147_ctrl_ops,
++ V4L2_CID_SATURATION, 0, 7, 1, 2);
++ v4l2_ctrl_new_std(&priv->hdl, &ar0147_ctrl_ops,
++ V4L2_CID_HUE, 0, 23, 1, 12);
++ v4l2_ctrl_new_std(&priv->hdl, &ar0147_ctrl_ops,
++ V4L2_CID_GAMMA, -128, 128, 1, 0);
++ v4l2_ctrl_new_std(&priv->hdl, &ar0147_ctrl_ops,
++ V4L2_CID_SHARPNESS, 0, 10, 1, 3);
++ v4l2_ctrl_new_std(&priv->hdl, &ar0147_ctrl_ops,
++ V4L2_CID_AUTOGAIN, 0, 1, 1, 0);
++ v4l2_ctrl_new_std(&priv->hdl, &ar0147_ctrl_ops,
++ V4L2_CID_GAIN, 1, 0x7ff, 1, 0x200);
++ v4l2_ctrl_new_std(&priv->hdl, &ar0147_ctrl_ops,
++ V4L2_CID_ANALOGUE_GAIN, 1, 0xe, 1, 0x7);
++ v4l2_ctrl_new_std(&priv->hdl, &ar0147_ctrl_ops,
++ V4L2_CID_EXPOSURE, 1, 0x400, 1, 0x300);
++ v4l2_ctrl_new_std(&priv->hdl, &ar0147_ctrl_ops,
++ V4L2_CID_HFLIP, 0, 1, 1, 0);
++ v4l2_ctrl_new_std(&priv->hdl, &ar0147_ctrl_ops,
++ V4L2_CID_VFLIP, 0, 1, 1, 0);
++ priv->sd.ctrl_handler = &priv->hdl;
++
++ ret = priv->hdl.error;
++ if (ret)
++ goto cleanup;
++
++ v4l2_ctrl_handler_setup(&priv->hdl);
++
++ priv->pad.flags = MEDIA_PAD_FL_SOURCE;
++ priv->sd.entity.flags |= MEDIA_ENT_F_CAM_SENSOR;
++ ret = media_entity_pads_init(&priv->sd.entity, 1, &priv->pad);
++ if (ret < 0)
++ goto cleanup;
++
++ ret = ar0147_parse_dt(client->dev.of_node, priv);
++ if (ret)
++ goto cleanup;
++
++ ret = ar0147_initialize(client);
++ if (ret < 0)
++ goto cleanup;
++
++ priv->rect.left = 0;
++ priv->rect.top = 0;
++ priv->rect.width = AR0147_MAX_WIDTH;
++ priv->rect.height = AR0147_MAX_HEIGHT;
++
++ ret = v4l2_async_register_subdev(&priv->sd);
++ if (ret)
++ goto cleanup;
++
++ if (device_create_file(&client->dev, &dev_attr_otp_id_ar0147) != 0) {
++ dev_err(&client->dev, "sysfs otp_id entry creation failed\n");
++ goto cleanup;
++ }
++
++ priv->init_complete = 1;
++
++ return 0;
++
++cleanup:
++ media_entity_cleanup(&priv->sd.entity);
++ v4l2_ctrl_handler_free(&priv->hdl);
++ v4l2_device_unregister_subdev(&priv->sd);
++#ifdef CONFIG_SOC_CAMERA_AR0147
++ v4l_err(client, "failed to probe @ 0x%02x (%s)\n",
++ client->addr, client->adapter->name);
++#endif
++ return ret;
++}
++
++static int ar0147_remove(struct i2c_client *client)
++{
++ struct ar0147_priv *priv = i2c_get_clientdata(client);
++
++ device_remove_file(&client->dev, &dev_attr_otp_id_ar0147);
++ v4l2_async_unregister_subdev(&priv->sd);
++ media_entity_cleanup(&priv->sd.entity);
++ v4l2_ctrl_handler_free(&priv->hdl);
++ v4l2_device_unregister_subdev(&priv->sd);
++
++ return 0;
++}
++
++#ifdef CONFIG_SOC_CAMERA_AR0147
++static const struct i2c_device_id ar0147_id[] = {
++ { "ar0147", 0 },
++ { }
++};
++MODULE_DEVICE_TABLE(i2c, ar0147_id);
++
++static const struct of_device_id ar0147_of_ids[] = {
++ { .compatible = "onnn,ar0147", },
++ { }
++};
++MODULE_DEVICE_TABLE(of, ar0147_of_ids);
++
++static struct i2c_driver ar0147_i2c_driver = {
++ .driver = {
++ .name = "ar0147",
++ .of_match_table = ar0147_of_ids,
++ },
++ .probe = ar0147_probe,
++ .remove = ar0147_remove,
++ .id_table = ar0147_id,
++};
++
++module_i2c_driver(ar0147_i2c_driver);
++
++MODULE_DESCRIPTION("SoC Camera driver for AR0147");
++MODULE_AUTHOR("Vladimir Barinov");
++MODULE_LICENSE("GPL");
++#endif
+diff --git a/drivers/media/i2c/soc_camera/ar0147.h b/drivers/media/i2c/soc_camera/ar0147.h
+new file mode 100644
+index 0000000..0f7ce31
+--- /dev/null
++++ b/drivers/media/i2c/soc_camera/ar0147.h
+@@ -0,0 +1,36 @@
++/*
++ * ON Semiconductor AR0147 sensor camera wizard 1344x968@30/BGGR/BT601/RAW12
++ *
++ * Copyright (C) 2019 Cogent Embedded, Inc.
++ *
++ * This program is free software; you can redistribute it and/or modify it
++ * under the terms of the GNU General Public License as published by the
++ * Free Software Foundation; either version 2 of the License, or (at your
++ * option) any later version.
++ */
++
++//#define AR0147_DISPLAY_PATTERN_FIXED
++//#define AR0147_DISPLAY_PATTERN_COLOR_BAR
++
++//#define AR0147_EMBEDDED_LINE
++
++#define AR0147_MAX_WIDTH 1344
++#define AR0147_MAX_HEIGHT 968
++
++#define AR0147_DELAY 0xffff
++
++#define AR0147_SENSOR_WIDTH 1344
++#define AR0147_SENSOR_HEIGHT 968
++
++#define AR0147_X_START ((AR0147_SENSOR_WIDTH - AR0147_MAX_WIDTH) / 2)
++#define AR0147_Y_START ((AR0147_SENSOR_HEIGHT - AR0147_MAX_HEIGHT) / 2)
++#define AR0147_X_END (AR0147_X_START + AR0147_MAX_WIDTH - 1)
++#define AR0147_Y_END (AR0147_Y_START + AR0147_MAX_HEIGHT - 1)
++
++struct ar0147_reg {
++ u16 reg;
++ u16 val;
++};
++
++#include "ar0147_rev1.h"
++#include "ar0147_rev2.h"
+diff --git a/drivers/media/i2c/soc_camera/ar0147_rev1.h b/drivers/media/i2c/soc_camera/ar0147_rev1.h
+new file mode 100644
+index 0000000..430e265
+--- /dev/null
++++ b/drivers/media/i2c/soc_camera/ar0147_rev1.h
+@@ -0,0 +1,607 @@
++/*
++ * ON Semiconductor AR0147 sensor camera wizard 1344x968@30/BGGR/BT601/RAW12
++ *
++ * Copyright (C) 2019 Cogent Embedded, Inc.
++ *
++ * This program is free software; you can redistribute it and/or modify it
++ * under the terms of the GNU General Public License as published by the
++ * Free Software Foundation; either version 2 of the License, or (at your
++ * option) any later version.
++ */
++
++// #define AR0147_REV1_2_Recommended_Settings
++
++static const struct ar0147_reg ar0147_rev1_Reset[] = {
++{0x301A, 0x0001}, // reset
++{AR0147_DELAY, 100},
++{0x301A, 0x10D8}, // Stream off and setup parallel
++{0x3070, 0x0001},
++{0x3070, 0x0000}, // 1: Solid color test pattern,
++ // 2: Full color bar test pattern,
++ // 3: Fade to grey color bar test pattern,
++ //256: Walking 1 test pattern (12 bit)
++#ifdef AR0147_DISPLAY_PATTERN_FIXED
++{0x3070, 0x0001},
++#endif
++{0x3072, 0x0fff}, // R
++{0x3074, 0x0fff}, // G(GR row)
++{0x3076, 0x0fff}, // B
++{0x3078, 0x0fff}, // G(GB row)
++#ifdef AR0147_DISPLAY_PATTERN_COLOR_BAR
++{0x3070, 0x0002},
++#endif
++{AR0147_DELAY, 250},
++{ }
++}; /* Reset */
++
++static const struct ar0147_reg ar0147_rev1_Sensor_Setup[] = {
++/* Recommended_Settings */
++{0x30B0, 0x980C}, // DIGITAL_TEST
++{0x3C08, 0x0100},
++{0x3C0C, 0x0518},
++{0x3092, 0x1A24},
++{0x30B4, 0x01C7}, // TEMPSENS0_CTRL_REG
++{0x30B8, 0x0007}, // TEMPSENS1_CTRL_REG
++{0x3364, 0x0680},
++{0x3372, 0x700F},
++{0x350C, 0x035A},
++{0x350E, 0x0514},
++{0x3518, 0x14FE},
++{0x351A, 0x6000},
++{0x3520, 0x08CC},
++{0x3522, 0xCC08},
++{0x3524, 0x0C00},
++{0x3526, 0x0F00},
++{0x3528, 0xFFFF},
++{0x352A, 0x0897},
++{0x352C, 0x0012},
++{0x352E, 0x00FF},
++{0x3530, 0xFF00},
++{0x3536, 0xFF24},
++{0x3538, 0x3CFF},
++{0x353A, 0x90E0},
++{0x353C, 0x3F00},
++{0x3540, 0xC63C},
++{0x3542, 0x3C3C},
++{0x3544, 0x3C46},
++{0x3546, 0x5458},
++{0x3548, 0x5800},
++{0x354A, 0x007F},
++{0x3556, 0x1010},
++{0x3F90, 0x0800}, // TEMPVSENS0_TMG_CTRL
++{0x3F9A, 0x0000}, // TEMPVSENS0_BOOST_SAMP_CTRL
++{0x3116, 0x0001}, // HDR_CONTROL3
++{0x3102, 0x60A0},
++{0x3104, 0x60A0},
++{0x3106, 0x60A0},
++
++//Set REV1 Minimum Analog Gain to LCG 3.5X
++{0x3366, 0xCCCC},
++{0x3362, 0x0000},
++#ifdef AR0147_REV1_REV1_2_Recommended_Settings
++//Set REV1.2 Default Analog Gain to LCG 8X (minimum recommended)
++{0x3366, 0xEEEE},
++#endif /* REV1.2_Recommended_Settings */
++/* Recommended_Settings */
++
++/* Sequencer_Update */
++{0x2512, 0x8000},
++{0x2510, 0x0901},
++{0x2510, 0x3350},
++{0x2510, 0x2004},
++{0x2510, 0x1420},
++{0x2510, 0x1578},
++{0x2510, 0x087B},
++{0x2510, 0x24FF},
++{0x2510, 0x24FF},
++{0x2510, 0x24EA},
++{0x2510, 0x2410},
++{0x2510, 0x2224},
++{0x2510, 0x1015},
++{0x2510, 0x5813},
++{0x2510, 0x0214},
++{0x2510, 0x0024},
++{0x2510, 0xFF24},
++{0x2510, 0xFF24},
++{0x2510, 0xEA23},
++{0x2510, 0x2464},
++{0x2510, 0x7A24},
++{0x2510, 0x0405},
++{0x2510, 0x2C40},
++{0x2510, 0x2A54},
++{0x2510, 0x0AFF},
++{0x2510, 0x0A78},
++{0x2510, 0x4538},
++{0x2510, 0x5114},
++{0x2510, 0x4000},
++{0x2510, 0x0408},
++{0x2510, 0x0104},
++{0x2510, 0x0826},
++{0x2510, 0x5208},
++{0x2510, 0x1518},
++{0x2510, 0x13C8},
++{0x2510, 0x1002},
++{0x2510, 0x1016},
++{0x2510, 0x1181},
++{0x2510, 0x1189},
++{0x2510, 0x1056},
++{0x2510, 0x1210},
++{0x2510, 0x0902},
++{0x2510, 0x0D09},
++{0x2510, 0x0515},
++{0x2510, 0x8813},
++{0x2510, 0x8809},
++{0x2510, 0x3811},
++{0x2510, 0x9911},
++{0x2510, 0xD909},
++{0x2510, 0x1E12},
++{0x2510, 0x1410},
++{0x2510, 0xD609},
++{0x2510, 0x0112},
++{0x2510, 0x1012},
++{0x2510, 0x1212},
++{0x2510, 0x1011},
++{0x2510, 0xDD11},
++{0x2510, 0xD909},
++{0x2510, 0x0114},
++{0x2510, 0x4109},
++{0x2510, 0x0410},
++{0x2510, 0x5608},
++{0x2510, 0x11DB},
++{0x2510, 0x0903},
++{0x2510, 0x11FB},
++{0x2510, 0x11BB},
++{0x2510, 0x121A},
++{0x2510, 0x1210},
++{0x2510, 0x0812},
++{0x2510, 0x5010},
++{0x2510, 0x7610},
++{0x2510, 0xE614},
++{0x2510, 0x6109},
++{0x2510, 0x0612},
++{0x2510, 0x4012},
++{0x2510, 0x6009},
++{0x2510, 0x1C14},
++{0x2510, 0x6009},
++{0x2510, 0x0C0B},
++{0x2510, 0x0905},
++{0x2510, 0x15C8},
++{0x2510, 0x13C8},
++{0x2510, 0x0810},
++{0x2510, 0x6609},
++{0x2510, 0x0B15},
++{0x2510, 0x8813},
++{0x2510, 0x8809},
++{0x2510, 0x130C},
++{0x2510, 0x1440},
++{0x2510, 0x0903},
++{0x2510, 0x10E6},
++{0x2510, 0x11FB},
++{0x2510, 0x1262},
++{0x2510, 0x1260},
++{0x2510, 0x11FF},
++{0x2510, 0x11FB},
++{0x2510, 0x1441},
++{0x2510, 0x0902},
++{0x2510, 0x1066},
++{0x2510, 0x0912},
++{0x2510, 0x11BB},
++{0x2510, 0x1263},
++{0x2510, 0x1260},
++{0x2510, 0x1400},
++{0x2510, 0x1518},
++{0x2510, 0x11B8},
++{0x2510, 0x12A0},
++{0x2510, 0x1200},
++{0x2510, 0x1026},
++{0x2510, 0x1000},
++{0x2510, 0x1300},
++{0x2510, 0x1100},
++{0x2510, 0x3053},
++{0x2510, 0x4211},
++{0x2510, 0x0010},
++{0x2510, 0x0210},
++{0x2510, 0x1611},
++{0x2510, 0x0111},
++{0x2510, 0x0910},
++{0x2510, 0x5612},
++{0x2510, 0x100D},
++{0x2510, 0x0905},
++{0x2510, 0x1441},
++{0x2510, 0x0907},
++{0x2510, 0x1440},
++{0x2510, 0x0901},
++{0x2510, 0x15C8},
++{0x2510, 0x13C8},
++{0x2510, 0x091A},
++{0x2510, 0x1149},
++{0x2510, 0x0908},
++{0x2510, 0x1588},
++{0x2510, 0x1388},
++{0x2510, 0x091B},
++{0x2510, 0x1159},
++{0x2510, 0x090B},
++{0x2510, 0x1214},
++{0x2510, 0x0901},
++{0x2510, 0x1210},
++{0x2510, 0x10D6},
++{0x2510, 0x1212},
++{0x2510, 0x1210},
++{0x2510, 0x115D},
++{0x2510, 0x1159},
++{0x2510, 0x1056},
++{0x2510, 0x0903},
++{0x2510, 0x115B},
++{0x2510, 0x0814},
++{0x2510, 0x4109},
++{0x2510, 0x0114},
++{0x2510, 0x4009},
++{0x2510, 0x0C11},
++{0x2510, 0x7B11},
++{0x2510, 0x3B12},
++{0x2510, 0x1A12},
++{0x2510, 0x1009},
++{0x2510, 0x0112},
++{0x2510, 0x5010},
++{0x2510, 0xF610},
++{0x2510, 0xE614},
++{0x2510, 0x6009},
++{0x2510, 0x0115},
++{0x2510, 0xA813},
++{0x2510, 0xA812},
++{0x2510, 0x4012},
++{0x2510, 0x6009},
++{0x2510, 0x2415},
++{0x2510, 0x8809},
++{0x2510, 0x0110},
++{0x2510, 0x660B},
++{0x2510, 0x0813},
++{0x2510, 0x8809},
++{0x2510, 0x250C},
++{0x2510, 0x0902},
++{0x2510, 0x1440},
++{0x2510, 0x0907},
++{0x2510, 0x10E6},
++{0x2510, 0x1262},
++{0x2510, 0x1260},
++{0x2510, 0x117F},
++{0x2510, 0x117B},
++{0x2510, 0x1066},
++{0x2510, 0x0906},
++{0x2510, 0x1441},
++{0x2510, 0x0901},
++{0x2510, 0x1440},
++{0x2510, 0x090D},
++{0x2510, 0x113B},
++{0x2510, 0x1263},
++{0x2510, 0x1260},
++{0x2510, 0x1400},
++{0x2510, 0x1518},
++{0x2510, 0x1138},
++{0x2510, 0x12A0},
++{0x2510, 0x1200},
++{0x2510, 0x1026},
++{0x2510, 0x1000},
++{0x2510, 0x1300},
++{0x2510, 0x1100},
++{0x2510, 0x437A},
++{0x2510, 0x0605},
++{0x2510, 0x0741},
++{0x2510, 0x0E02},
++{0x2510, 0x3750},
++{0x2510, 0x2C44},
++{0x2510, 0x3714},
++{0x2510, 0x4000},
++{0x2510, 0x0408},
++{0x2510, 0x0104},
++{0x2510, 0x0811},
++{0x2510, 0x0010},
++{0x2510, 0x0210},
++{0x2510, 0x1611},
++{0x2510, 0x0111},
++{0x2510, 0x0910},
++{0x2510, 0x5612},
++{0x2510, 0x100D},
++{0x2510, 0x0906},
++{0x2510, 0x1441},
++{0x2510, 0x0907},
++{0x2510, 0x1440},
++{0x2510, 0x0901},
++{0x2510, 0x1588},
++{0x2510, 0x1388},
++{0x2510, 0x0921},
++{0x2510, 0x1149},
++{0x2510, 0x0908},
++{0x2510, 0x1588},
++{0x2510, 0x1388},
++{0x2510, 0x091B},
++{0x2510, 0x1159},
++{0x2510, 0x090B},
++{0x2510, 0x1214},
++{0x2510, 0x0901},
++{0x2510, 0x1210},
++{0x2510, 0x10D6},
++{0x2510, 0x1212},
++{0x2510, 0x1210},
++{0x2510, 0x115D},
++{0x2510, 0x1159},
++{0x2510, 0x1056},
++{0x2510, 0x0903},
++{0x2510, 0x115B},
++{0x2510, 0x0814},
++{0x2510, 0x4109},
++{0x2510, 0x0114},
++{0x2510, 0x4009},
++{0x2510, 0x0C11},
++{0x2510, 0x7B11},
++{0x2510, 0x3B12},
++{0x2510, 0x1A12},
++{0x2510, 0x1009},
++{0x2510, 0x0112},
++{0x2510, 0x5010},
++{0x2510, 0xF610},
++{0x2510, 0xE614},
++{0x2510, 0x6009},
++{0x2510, 0x0115},
++{0x2510, 0xA813},
++{0x2510, 0xA812},
++{0x2510, 0x4012},
++{0x2510, 0x6009},
++{0x2510, 0x2415},
++{0x2510, 0x8809},
++{0x2510, 0x0110},
++{0x2510, 0x660B},
++{0x2510, 0x0813},
++{0x2510, 0x8809},
++{0x2510, 0x250C},
++{0x2510, 0x0902},
++{0x2510, 0x1440},
++{0x2510, 0x0907},
++{0x2510, 0x10E6},
++{0x2510, 0x1262},
++{0x2510, 0x1260},
++{0x2510, 0x117F},
++{0x2510, 0x117B},
++{0x2510, 0x1066},
++{0x2510, 0x0906},
++{0x2510, 0x1441},
++{0x2510, 0x0901},
++{0x2510, 0x1440},
++{0x2510, 0x090D},
++{0x2510, 0x113B},
++{0x2510, 0x1263},
++{0x2510, 0x1260},
++{0x2510, 0x1440},
++{0x2510, 0x1598},
++{0x2510, 0x1139},
++{0x2510, 0x12A0},
++{0x2510, 0x1200},
++{0x2510, 0x1066},
++{0x2510, 0x1066},
++{0x2510, 0x1380},
++{0x2510, 0x1109},
++{0x2510, 0x0E02},
++{0x2510, 0x0920},
++{0x2510, 0x3708},
++{0x2510, 0x0015},
++{0x2510, 0x9813},
++{0x2510, 0x9810},
++{0x2510, 0x6610},
++{0x2510, 0x6611},
++{0x2510, 0x8911},
++{0x2510, 0x8910},
++{0x2510, 0x5612},
++{0x2510, 0x1009},
++{0x2510, 0x020D},
++{0x2510, 0x0905},
++{0x2510, 0x15A8},
++{0x2510, 0x13A8},
++{0x2510, 0x0934},
++{0x2510, 0x1588},
++{0x2510, 0x1388},
++{0x2510, 0x1199},
++{0x2510, 0x11D9},
++{0x2510, 0x091E},
++{0x2510, 0x1214},
++{0x2510, 0x10D6},
++{0x2510, 0x0901},
++{0x2510, 0x1210},
++{0x2510, 0x1212},
++{0x2510, 0x1210},
++{0x2510, 0x11DD},
++{0x2510, 0x11D9},
++{0x2510, 0x0901},
++{0x2510, 0x1441},
++{0x2510, 0x0904},
++{0x2510, 0x1056},
++{0x2510, 0x0811},
++{0x2510, 0xDB09},
++{0x2510, 0x0311},
++{0x2510, 0xFB11},
++{0x2510, 0xBB12},
++{0x2510, 0x1A12},
++{0x2510, 0x1008},
++{0x2510, 0x1250},
++{0x2510, 0x1076},
++{0x2510, 0x10E6},
++{0x2510, 0x1461},
++{0x2510, 0x0906},
++{0x2510, 0x1240},
++{0x2510, 0x1260},
++{0x2510, 0x091C},
++{0x2510, 0x1460},
++{0x2510, 0x090C},
++{0x2510, 0x0B09},
++{0x2510, 0x0515},
++{0x2510, 0xC813},
++{0x2510, 0xC808},
++{0x2510, 0x1066},
++{0x2510, 0x090B},
++{0x2510, 0x1588},
++{0x2510, 0x1388},
++{0x2510, 0x0913},
++{0x2510, 0x0C14},
++{0x2510, 0x4009},
++{0x2510, 0x0310},
++{0x2510, 0xE611},
++{0x2510, 0xFB12},
++{0x2510, 0x6212},
++{0x2510, 0x6011},
++{0x2510, 0xFF11},
++{0x2510, 0xFB14},
++{0x2510, 0x4109},
++{0x2510, 0x0210},
++{0x2510, 0x6609},
++{0x2510, 0x1211},
++{0x2510, 0xBB12},
++{0x2510, 0x6312},
++{0x2510, 0x6014},
++{0x2510, 0x0015},
++{0x2510, 0x1811},
++{0x2510, 0xB812},
++{0x2510, 0xA012},
++{0x2510, 0x0010},
++{0x2510, 0x2610},
++{0x2510, 0x0013},
++{0x2510, 0x0011},
++{0x2510, 0x007A},
++{0x2510, 0x0605},
++{0x2510, 0x0807},
++{0x2510, 0x0E02},
++{0x2510, 0x3709},
++{0x2510, 0x0655},
++{0x2510, 0x2CFE},
++{0x2510, 0x12FE},
++{0x2510, 0x062C},
++
++{0x1010, 0x0115},
++{0x3236, 0x00b3},
++{0x32e6, 0x009a},
++{0x322e, 0x258c},
++/* Sequencer_Update */
++
++{0x32D0, 0x3A02},
++{0x32D2, 0x3508},
++{0x32D4, 0x3702},
++{0x32D6, 0x3C04},
++{0x32DC, 0x370A},
++{ }
++}; /* Sensor_Setup */
++
++static const struct ar0147_reg ar0147_rev1_Serial_12_bit_Timing_Setup[] = {
++#if 0
++/* PCLK=24Mhz/3 *50 /1/8 = 50MHz */
++{0x302A, 8}, // VT_PIX_CLK_DIV
++{0x302C, 1}, // VT_SYS_CLK_DIV
++{0x302E, 3}, // PRE_PLL_CLK_DIV
++{0x3030, 50}, // PLL_MULTIPLIER
++{0x3036, 8}, // OP_WORD_CLK_DIV
++{0x3038, 1}, // OP_SYS_CLK_DIV
++#else
++/* PCLK=24Mhz/4 *75 /1/9 = 50MHz */
++{0x302A, 9}, // VT_PIX_CLK_DIV
++{0x302C, 1}, // VT_SYS_CLK_DIV
++{0x302E, 4}, // PRE_PLL_CLK_DIV
++{0x3030, 75}, // PLL_MULTIPLIER
++{0x3036, 12}, // OP_WORD_CLK_DIV
++{0x3038, 1}, // OP_SYS_CLK_DIV
++#endif
++{0x30B0, 0x980C}, // DIGITAL_TEST
++{0x31DC, 0x1FB0},
++{ }
++}; /* Serial_12_bit_Timing_Setup */
++
++static const struct ar0147_reg ar0147_rev1_Readout_Mode_Configuration[] = {
++{0x30A2, 0x0001}, // X_ODD_INC_
++{0x30A6, 0x0001}, // Y_ODD_INC_
++{0x3040, 0x0000}, // READ_MODE
++{0x3082, 0x0008}, // OPERATION_MODE_CTRL: 3exp
++{0x3044, 0x0400}, // DARK_CONTROL
++{0x3064, 0x0000}, // SMIA_TEST: disable emb data and stats
++{0x33E0, 0x0C80}, // TEST_ASIL_ROWS
++{0x3180, 0x0080}, // RESERVED_MFR_3180
++{0x33E4, 0x0080}, // RESERVED_MFR_33E4
++#ifdef AR0147_EMBEDDED_LINE
++{0x3064, 0x0180}, // SMIA_TEST: enable emb data and stats
++#endif /* HDR_Readout_Mode_Configuration */
++{ }
++}; /* Readout_Mode_Configuration */
++
++static const struct ar0147_reg ar0147_rev1_Full_Res_FOV[] = {
++{0x31B0, 0x0056}, // FRAME_PREAMBLE
++{0x31B2, 0x0045}, // LINE_PREAMBLE
++{0x3004, AR0147_X_START}, // X_ADDR_START_
++{0x3008, AR0147_X_END}, // X_ADDR_END_
++{0x3002, AR0147_Y_START}, // Y_ADDR_START_
++{0x3006, AR0147_Y_END}, // Y_ADDR_END_
++{0x3400, 0x10},
++{0x3402, (0x8000 & 0) | AR0147_MAX_WIDTH}, // X_OUTPUT_CONTROL
++{0x3404, (0x8000 & 0) | AR0147_MAX_HEIGHT}, // Y_OUTPUT_CONTROL
++{ }
++}; /* Full_Res_FOV */
++
++static const struct ar0147_reg ar0147_rev1_3exp_30FPS_Timing_and_Exposure[] = {
++{0x3082, 0x0008}, // OPERATION_MODE_CTRL: 3exp
++{0x30BA, 0x1002}, // DIGITAL_CTRL: 3exp max
++/* Row and Pixel Timing */
++{0x300C, AR0147_SENSOR_WIDTH + 52}, // LINE_LENGTH_PCK_ (1396)
++{0x300A, AR0147_SENSOR_HEIGHT + 226}, // FRAME_LENGTH_LINES_
++{0x3042, 0x0000}, // EXTRA_DELAY
++/* Exposure Settings */
++{0x3238, 0x0222}, // EXPOSURE_RATIO
++{0x3012, 0x0300}, // COARSE_INTEGRATION_TIME_
++
++{0x3014, 1550}, // FINE_INTEGRATION_TIME_
++{0x321E, 1550}, // FINE_INTEGRATION_TIME2
++{0x3222, 1550}, // FINE_INTEGRATION_TIME3
++
++{0x30B0, 0x980C}, // DIGITAL_TEST (MIPI ...)
++{0x32EA, 0x3C0E},
++{0x32EC, 0x72A1},
++{0x3C06, 0x083C},
++{0x3C08, 0x0100},
++{ }
++}; /* 3exp_30FPS_Timing_and_Exposure */
++
++static const struct ar0147_reg ar0147_rev1_Serial_HDR_12_bit_Output[] = {
++{0x31D0, 0x0001}, // COMPANDING
++{0x31AE, 0x0304}, // SERIAL_FORMAT: HISPI 4-lanes
++{0x31AC, 0x140C}, // DATA_FORMAT_BITS: ADC20, RAW12
++//{0x301A, 0x0118}, // RESET_REGISTER
++{0x301A, 0x0018}, // RESET_REGISTER
++{ }
++}; /* Serial_HDR_12_bit_Output */
++
++static const struct ar0147_reg ar0147_rev1_MIPI_12_bit_450MBps_Settings[] = {
++{0x31AE, 0x0204}, // SERIAL_FORMAT: MIPI 4-lanes
++{0x3342, 0x122C}, // exposure1 DT=0x2c emb=0x12
++{0x3346, 0x122C}, // exposure2 DT=0x2c emb=0x12
++{0x334A, 0x122C}, // exposure3 DT=0x2c emb=0x12
++{0x334E, 0x122C}, // exposure4 DT=0x2c emb=0x12
++{0x3344, 0x0011}, // exposure1 VC=0
++{0x3348, 0x0111}, // exposure1 VC=1
++{0x334C, 0x0211}, // exposure1 VC=2
++{0x3350, 0x0311}, // exposure1 VC=3
++{0x31B0, 0x41}, // frame_preamble
++{0x31B2, 0x2e}, // line_preamble
++
++{0x31B4, 0x2185},
++{0x31B6, 0x1105},
++{0x31B8, 0x2047},
++{0x31BA, 0x105},
++{0x31BC, 0x704},
++{ }
++}; /* MIPI_12_bit_450MBps_Settings */
++
++/* 3 Exp HDR, Full Resolution, MIPI 450MBps 4 lane 12-bit, 30FPS, XMCLK=24MHz */
++static const struct ar0147_reg *ar0147_regs_hdr_mipi450mbps_12bit_30fps_rev1[] = {
++ ar0147_rev1_Reset,
++ ar0147_rev1_Sensor_Setup,
++ ar0147_rev1_Serial_12_bit_Timing_Setup,
++ ar0147_rev1_Readout_Mode_Configuration,
++ ar0147_rev1_Full_Res_FOV,
++ ar0147_rev1_3exp_30FPS_Timing_and_Exposure,
++ ar0147_rev1_Serial_HDR_12_bit_Output,
++ ar0147_rev1_MIPI_12_bit_450MBps_Settings,
++ NULL
++};
+diff --git a/drivers/media/i2c/soc_camera/ar0147_rev2.h b/drivers/media/i2c/soc_camera/ar0147_rev2.h
+new file mode 100644
+index 0000000..e5ccb8f
+--- /dev/null
++++ b/drivers/media/i2c/soc_camera/ar0147_rev2.h
+@@ -0,0 +1,796 @@
++/*
++ * ON Semiconductor AR0147 sensor camera wizard 1344x968@30/BGGR/BT601/RAW12
++ *
++ * Copyright (C) 2019 Cogent Embedded, Inc.
++ *
++ * This program is free software; you can redistribute it and/or modify it
++ * under the terms of the GNU General Public License as published by the
++ * Free Software Foundation; either version 2 of the License, or (at your
++ * option) any later version.
++ */
++
++static const struct ar0147_reg ar0147_rev2_Reset[] = {
++{0x301A, 0x0001}, // reset
++{AR0147_DELAY, 100},
++{0x301A, 0x10D8}, // Stream off and setup parallel
++{0x3070, 0x0001},
++{0x3070, 0x0000}, // 1: Solid color test pattern,
++ // 2: Full color bar test pattern,
++ // 3: Fade to grey color bar test pattern,
++ //256: Walking 1 test pattern (12 bit)
++#ifdef AR0147_DISPLAY_PATTERN_FIXED
++{0x3070, 0x0001},
++#endif
++{0x3072, 0x0fff}, // R
++{0x3074, 0x0fff}, // G(GR row)
++{0x3076, 0x0fff}, // B
++{0x3078, 0x0fff}, // G(GB row)
++#ifdef AR0147_DISPLAY_PATTERN_COLOR_BAR
++{0x3070, 0x0002},
++#endif
++{AR0147_DELAY, 250},
++{ }
++}; /* Reset */
++
++static const struct ar0147_reg ar0147_rev2_Sensor_Setup[] = {
++/* Recommended_Settings */
++{0x30B0, 0x980E}, // DIGITAL_TEST
++{0x3C08, 0x0000},
++{0x3C0C, 0x0518}, // DELAY_BUFFER_LLPCK_RD_WR_OVERLAP
++{0x3092, 0x1A24},
++{0x30B4, 0x01C7}, // TEMPSENS0_CTRL_REG
++{0x3372, 0x700F}, // DBLC_FS0_CONTROL
++{0x33EE, 0x0344},
++{0x350C, 0x035A},
++{0x350E, 0x0514},
++{0x3518, 0x14FE},
++{0x351A, 0x6000},
++{0x3520, 0x08CC},
++{0x3522, 0xCC08},
++{0x3524, 0x0C00},
++{0x3526, 0x0F00},
++{0x3528, 0xEEEE},
++{0x352A, 0x089F},
++{0x352C, 0x0012},
++{0x352E, 0x00EE},
++{0x3530, 0xEE00},
++{0x3536, 0xFF20},
++{0x3538, 0x3CFF},
++{0x353A, 0x9000},
++{0x353C, 0x7F00},
++{0x3540, 0xC62C},
++{0x3542, 0x4B4B},
++{0x3544, 0x3C46},
++{0x3546, 0x5A5A},
++{0x3548, 0x6400},
++{0x354A, 0x007F},
++{0x3556, 0x1010},
++{0x3566, 0x7328},
++{0x3F90, 0x0800}, // TEMPVSENS0_TMG_CTRL
++{0x3510, 0x011F},
++{0x353E, 0x801F},
++{0x3F9A, 0x0001}, // TEMPVSENS0_BOOST_SAMP_CTRL
++{0x3116, 0x0001}, // HDR_CONTROL3
++{0x3102, 0x60A0},
++{0x3104, 0x60A0},
++{0x3106, 0x60A0},
++{0x3362, 0x0000}, // DC_GAIN
++{0x3366, 0xCCCC}, // ANALOG_GAIN
++
++// Writes to bitfield R0x3552[5:4].
++// Be sure not to overwrite the other bitfields in this register.
++{0x3552, 0x0FB0},
++/* Recommended_Settings */
++
++/* Sequencer_Update */
++{0x2512, 0x8000},
++{0x2510, 0x0901},
++{0x2510, 0x3350},
++{0x2510, 0x2004},
++{0x2510, 0x1420},
++{0x2510, 0x1578},
++{0x2510, 0x087B},
++{0x2510, 0x24FF},
++{0x2510, 0x24FF},
++{0x2510, 0x24EA},
++{0x2510, 0x2410},
++{0x2510, 0x2224},
++{0x2510, 0x1015},
++{0x2510, 0xD813},
++{0x2510, 0x0214},
++{0x2510, 0x0024},
++{0x2510, 0xFF24},
++{0x2510, 0xFF24},
++{0x2510, 0xEA23},
++{0x2510, 0x2464},
++{0x2510, 0x7A24},
++{0x2510, 0x0405},
++{0x2510, 0x2C40},
++{0x2510, 0x0AFF},
++{0x2510, 0x0A78},
++{0x2510, 0x3851},
++{0x2510, 0x2A54},
++{0x2510, 0x1440},
++{0x2510, 0x0015},
++{0x2510, 0x0804},
++{0x2510, 0x0801},
++{0x2510, 0x0408},
++{0x2510, 0x2652},
++{0x2510, 0x0813},
++{0x2510, 0xC810},
++{0x2510, 0x0210},
++{0x2510, 0x1611},
++{0x2510, 0x8111},
++{0x2510, 0x8910},
++{0x2510, 0x5612},
++{0x2510, 0x1009},
++{0x2510, 0x020D},
++{0x2510, 0x0903},
++{0x2510, 0x1402},
++{0x2510, 0x15A8},
++{0x2510, 0x1388},
++{0x2510, 0x0938},
++{0x2510, 0x1199},
++{0x2510, 0x11D9},
++{0x2510, 0x091E},
++{0x2510, 0x1214},
++{0x2510, 0x10D6},
++{0x2510, 0x0901},
++{0x2510, 0x1210},
++{0x2510, 0x1212},
++{0x2510, 0x1210},
++{0x2510, 0x11DD},
++{0x2510, 0x11D9},
++{0x2510, 0x0901},
++{0x2510, 0x1441},
++{0x2510, 0x0904},
++{0x2510, 0x1056},
++{0x2510, 0x0811},
++{0x2510, 0xDB09},
++{0x2510, 0x0311},
++{0x2510, 0xFB11},
++{0x2510, 0xBB12},
++{0x2510, 0x1A12},
++{0x2510, 0x1008},
++{0x2510, 0x1250},
++{0x2510, 0x0B10},
++{0x2510, 0x7610},
++{0x2510, 0xE614},
++{0x2510, 0x6109},
++{0x2510, 0x0612},
++{0x2510, 0x4012},
++{0x2510, 0x6009},
++{0x2510, 0x1C14},
++{0x2510, 0x6009},
++{0x2510, 0x1215},
++{0x2510, 0xC813},
++{0x2510, 0xC808},
++{0x2510, 0x1066},
++{0x2510, 0x090B},
++{0x2510, 0x1588},
++{0x2510, 0x1388},
++{0x2510, 0x0913},
++{0x2510, 0x0C14},
++{0x2510, 0x4009},
++{0x2510, 0x0310},
++{0x2510, 0xE611},
++{0x2510, 0xFB12},
++{0x2510, 0x6212},
++{0x2510, 0x6011},
++{0x2510, 0xFF11},
++{0x2510, 0xFB14},
++{0x2510, 0x4109},
++{0x2510, 0x0210},
++{0x2510, 0x6609},
++{0x2510, 0x1211},
++{0x2510, 0xBB12},
++{0x2510, 0x6312},
++{0x2510, 0x6014},
++{0x2510, 0x0015},
++{0x2510, 0x1811},
++{0x2510, 0xB812},
++{0x2510, 0xA012},
++{0x2510, 0x0010},
++{0x2510, 0x2610},
++{0x2510, 0x0013},
++{0x2510, 0x0011},
++{0x2510, 0x0030},
++{0x2510, 0x5342},
++{0x2510, 0x1100},
++{0x2510, 0x1002},
++{0x2510, 0x1016},
++{0x2510, 0x1101},
++{0x2510, 0x1109},
++{0x2510, 0x1056},
++{0x2510, 0x1210},
++{0x2510, 0x0D09},
++{0x2510, 0x0314},
++{0x2510, 0x0214},
++{0x2510, 0x4309},
++{0x2510, 0x0514},
++{0x2510, 0x4009},
++{0x2510, 0x0115},
++{0x2510, 0xC813},
++{0x2510, 0xC809},
++{0x2510, 0x1A11},
++{0x2510, 0x4909},
++{0x2510, 0x0815},
++{0x2510, 0x8813},
++{0x2510, 0x8809},
++{0x2510, 0x1B11},
++{0x2510, 0x5909},
++{0x2510, 0x0B12},
++{0x2510, 0x1409},
++{0x2510, 0x0112},
++{0x2510, 0x1010},
++{0x2510, 0xD612},
++{0x2510, 0x1212},
++{0x2510, 0x1011},
++{0x2510, 0x5D11},
++{0x2510, 0x5910},
++{0x2510, 0x5609},
++{0x2510, 0x0311},
++{0x2510, 0x5B08},
++{0x2510, 0x1441},
++{0x2510, 0x0901},
++{0x2510, 0x1440},
++{0x2510, 0x090C},
++{0x2510, 0x117B},
++{0x2510, 0x113B},
++{0x2510, 0x121A},
++{0x2510, 0x1210},
++{0x2510, 0x0901},
++{0x2510, 0x1250},
++{0x2510, 0x10F6},
++{0x2510, 0x10E6},
++{0x2510, 0x1460},
++{0x2510, 0x0901},
++{0x2510, 0x15A8},
++{0x2510, 0x13A8},
++{0x2510, 0x1240},
++{0x2510, 0x1260},
++{0x2510, 0x0924},
++{0x2510, 0x1588},
++{0x2510, 0x0901},
++{0x2510, 0x1066},
++{0x2510, 0x0B08},
++{0x2510, 0x1388},
++{0x2510, 0x0925},
++{0x2510, 0x0C09},
++{0x2510, 0x0214},
++{0x2510, 0x4009},
++{0x2510, 0x0710},
++{0x2510, 0xE612},
++{0x2510, 0x6212},
++{0x2510, 0x6011},
++{0x2510, 0x7F11},
++{0x2510, 0x7B10},
++{0x2510, 0x6609},
++{0x2510, 0x0614},
++{0x2510, 0x4109},
++{0x2510, 0x0114},
++{0x2510, 0x4009},
++{0x2510, 0x0D11},
++{0x2510, 0x3B12},
++{0x2510, 0x6312},
++{0x2510, 0x6014},
++{0x2510, 0x0015},
++{0x2510, 0x1811},
++{0x2510, 0x3812},
++{0x2510, 0xA012},
++{0x2510, 0x0010},
++{0x2510, 0x2610},
++{0x2510, 0x0013},
++{0x2510, 0x0011},
++{0x2510, 0x0043},
++{0x2510, 0x7A06},
++{0x2510, 0x0507},
++{0x2510, 0x410E},
++{0x2510, 0x0237},
++{0x2510, 0x502C},
++{0x2510, 0x4414},
++{0x2510, 0x4000},
++{0x2510, 0x1508},
++{0x2510, 0x0408},
++{0x2510, 0x0104},
++{0x2510, 0x0826},
++{0x2510, 0x5508},
++{0x2510, 0x13C8},
++{0x2510, 0x1002},
++{0x2510, 0x1016},
++{0x2510, 0x1181},
++{0x2510, 0x1189},
++{0x2510, 0x1056},
++{0x2510, 0x1210},
++{0x2510, 0x0902},
++{0x2510, 0x0D09},
++{0x2510, 0x0314},
++{0x2510, 0x0215},
++{0x2510, 0xA813},
++{0x2510, 0xA814},
++{0x2510, 0x0309},
++{0x2510, 0x0614},
++{0x2510, 0x0209},
++{0x2510, 0x1F15},
++{0x2510, 0x8813},
++{0x2510, 0x8809},
++{0x2510, 0x0B11},
++{0x2510, 0x9911},
++{0x2510, 0xD909},
++{0x2510, 0x1E12},
++{0x2510, 0x1409},
++{0x2510, 0x0312},
++{0x2510, 0x1012},
++{0x2510, 0x1212},
++{0x2510, 0x1011},
++{0x2510, 0xDD11},
++{0x2510, 0xD909},
++{0x2510, 0x0114},
++{0x2510, 0x4009},
++{0x2510, 0x0711},
++{0x2510, 0xDB09},
++{0x2510, 0x0311},
++{0x2510, 0xFB11},
++{0x2510, 0xBB12},
++{0x2510, 0x1A12},
++{0x2510, 0x1009},
++{0x2510, 0x0112},
++{0x2510, 0x500B},
++{0x2510, 0x1076},
++{0x2510, 0x1066},
++{0x2510, 0x1460},
++{0x2510, 0x0901},
++{0x2510, 0x15C8},
++{0x2510, 0x0901},
++{0x2510, 0x1240},
++{0x2510, 0x1260},
++{0x2510, 0x0901},
++{0x2510, 0x13C8},
++{0x2510, 0x0956},
++{0x2510, 0x1588},
++{0x2510, 0x0901},
++{0x2510, 0x0C14},
++{0x2510, 0x4009},
++{0x2510, 0x0511},
++{0x2510, 0xFB12},
++{0x2510, 0x6212},
++{0x2510, 0x6011},
++{0x2510, 0xFF11},
++{0x2510, 0xFB09},
++{0x2510, 0x1911},
++{0x2510, 0xBB12},
++{0x2510, 0x6312},
++{0x2510, 0x6014},
++{0x2510, 0x0015},
++{0x2510, 0x1811},
++{0x2510, 0xB812},
++{0x2510, 0xA012},
++{0x2510, 0x0010},
++{0x2510, 0x2610},
++{0x2510, 0x0013},
++{0x2510, 0x0011},
++{0x2510, 0x0030},
++{0x2510, 0x5345},
++{0x2510, 0x1444},
++{0x2510, 0x1002},
++{0x2510, 0x1016},
++{0x2510, 0x1101},
++{0x2510, 0x1109},
++{0x2510, 0x1056},
++{0x2510, 0x1210},
++{0x2510, 0x0D09},
++{0x2510, 0x0314},
++{0x2510, 0x0614},
++{0x2510, 0x4709},
++{0x2510, 0x0514},
++{0x2510, 0x4409},
++{0x2510, 0x0115},
++{0x2510, 0x9813},
++{0x2510, 0x9809},
++{0x2510, 0x1A11},
++{0x2510, 0x4909},
++{0x2510, 0x0815},
++{0x2510, 0x8813},
++{0x2510, 0x8809},
++{0x2510, 0x1B11},
++{0x2510, 0x5909},
++{0x2510, 0x0B12},
++{0x2510, 0x1409},
++{0x2510, 0x0112},
++{0x2510, 0x1009},
++{0x2510, 0x0112},
++{0x2510, 0x1212},
++{0x2510, 0x1011},
++{0x2510, 0x5D11},
++{0x2510, 0x5909},
++{0x2510, 0x0511},
++{0x2510, 0x5B09},
++{0x2510, 0x1311},
++{0x2510, 0x7B11},
++{0x2510, 0x3B12},
++{0x2510, 0x1A12},
++{0x2510, 0x1009},
++{0x2510, 0x0112},
++{0x2510, 0x5010},
++{0x2510, 0x7610},
++{0x2510, 0x6614},
++{0x2510, 0x6409},
++{0x2510, 0x0115},
++{0x2510, 0xA813},
++{0x2510, 0xA812},
++{0x2510, 0x4012},
++{0x2510, 0x6009},
++{0x2510, 0x2015},
++{0x2510, 0x8809},
++{0x2510, 0x020B},
++{0x2510, 0x0901},
++{0x2510, 0x1388},
++{0x2510, 0x0925},
++{0x2510, 0x0C09},
++{0x2510, 0x0214},
++{0x2510, 0x4409},
++{0x2510, 0x0912},
++{0x2510, 0x6212},
++{0x2510, 0x6011},
++{0x2510, 0x7F11},
++{0x2510, 0x7B09},
++{0x2510, 0x1C11},
++{0x2510, 0x3B12},
++{0x2510, 0x6312},
++{0x2510, 0x6014},
++{0x2510, 0x0015},
++{0x2510, 0x1811},
++{0x2510, 0x3812},
++{0x2510, 0xA012},
++{0x2510, 0x0010},
++{0x2510, 0x2610},
++{0x2510, 0x0013},
++{0x2510, 0x0011},
++{0x2510, 0x0008},
++{0x2510, 0x7A06},
++{0x2510, 0x0508},
++{0x2510, 0x070E},
++{0x2510, 0x0237},
++{0x2510, 0x502C},
++{0x2510, 0xFE32},
++{0x2510, 0xFE06},
++{0x2510, 0x2C2C},
++
++{AR0147_DELAY, 200},
++
++{0x32e6, 0x009a}, //min_subrow
++{0x322e, 0x258c}, //clks_per_sample 396
++/* Sequencer_Update */
++
++{0x32D0, 0x3A02},
++{0x32D2, 0x3508},
++{0x32D4, 0x3702},
++{0x32D6, 0x3C04},
++{0x32DC, 0x370A},
++{0x32EA, 0x3CA8},
++{0x351E, 0x0000},
++{0x3510, 0x811F},
++
++//settings to rev1 default for non-Super Exposure mode settings
++//Super Exposure mode settings have additional settings
++{0x1010, 0x0155}, // FINE_INTEGRATION_TIME4_MIN
++{0x3236, 0x00B2}, // FINE_CORRECTION4
++{0x32EA, 0x3C0E},
++{0x32EC, 0x7151},
++{0x3116, 0x0001}, // HDR_CONTROL3
++{0x33E2, 0x0000}, // SAMPLE_CTRL
++{0x3088, 0x0400}, // LFM_CTRL
++{0x322A, 0x0039}, // FINE_INTEGRATION_CTRL
++{0x3238, 0x0333}, // EXPOSURE_RATIO
++{ }
++}; /* Sensor_Setup */
++
++static const struct ar0147_reg ar0147_rev2_Super_Exposure_Default_Plus_T2_Setup[] = {
++{0x3082, 0x0008}, // OPERATION_MODE_CTRL
++{0x30BA, 0x1003}, // DIGITAL_CTRL
++{0x3C06, 0x2024}, // CONFIGURE_BUFFERS1
++{0x3C08, 0x2100}, // CONFIGURE_BUFFERS2
++{0x3088, 0x0400},
++{0x32EA, 0x3CA9},
++{0x3510, 0x814F},
++{0x351E, 0x0100},
++{0x32EA, 0x3CA9},
++{0x32EC, 0x7281},
++{0x3212, 0x0000}, // COARSE_INTEGRATION_TIME2
++{0x3216, 0x0004}, // COARSE_INTEGRATION_TIME3
++{0x3238, 0x8222}, // EXPOSURE_RATIO
++{0x33E2, 0x0A10}, // SAMPLE_CTRL
++{0x3362, 0x0001}, // DC_GAIN
++{0x322A, 0x0539}, // FINE_INTEGRATION_CTRL
++{0x3014, 0x0123}, // FINE_INTEGRATION_TIME_
++{0x3222, 0x0490}, // FINE_INTEGRATION_TIME3
++{0x1008, 0x0123}, // FINE_INTEGRATION_TIME_MIN
++{0x100E, 0x043B}, // FINE_INTEGRATION_TIME3_MIN
++{0x3230, 0x00C7}, // FINE_CORRECTION
++{0x3234, 0x03DF}, // FINE_CORRECTION3
++{0x32D0, 0x3A02},
++{0x32D2, 0x3508},
++{0x32D4, 0x3702},
++{0x32D6, 0x3C04},
++{0x32DC, 0x370A},
++{0x3528, 0x99EE},
++{0x30FE, 0x0040}, // NOISE_PEDESTAL
++{0x3096, 0x0000}, // ROW_NOISE_ADJUST_1X_LCG_T2
++
++/* Digital_Lateral_Overflow_for_SE */
++{0x3116, 0x0001},
++{0x3100, 0xC001}, // FIELD_WR= DLO_CONTROL0, 0xE001
++{0x3102, 0x6100},
++{0x3104, 0x6100},
++{0x3106, 0x6100},
++{0x3108, 0x0CB1},
++{0x312A, 0x83E8},
++{0x3C82, 0x0FFF},
++/* Digital_Lateral_Overflow_for_SE */
++
++/* Other_Super_Exposure_Setup */
++{0x3536, 0xFF20},
++{0x3520, 0x0800},
++{0x3522, 0x0008},
++{0x3536, 0xFF20},
++{0x350C, 0x034A},
++{0x350E, 0x051C},
++{0x3540, 0xC62C},
++{0x3542, 0x4B4B},
++{0x3544, 0x4B46},
++{0x3546, 0x5A5A},
++{0x3548, 0x6400},
++{0x354A, 0x007F},
++{0x3524, 0x0600},
++{0x3372, 0xF40F}, // DBLC_FS0_CONTROL
++{0x3180, 0x0188},
++{0x3280, 0x0CB2}, // T1_BARRIER_C0
++{0x3282, 0x0CB2}, // T1_BARRIER_C1
++{0x3284, 0x0CB2}, // T1_BARRIER_C2
++{0x3286, 0x0CB2}, // T1_BARRIER_C3
++{0x3288, 0x0CB2}, // T2_BARRIER_C0
++{0x328A, 0x0CB2}, // T2_BARRIER_C1
++{0x328C, 0x0CB2}, // T2_BARRIER_C2
++{0x328E, 0x0CB2}, // T2_BARRIER_C3
++{0x3290, 0x0CB2}, // T3_BARRIER_C0
++{0x3292, 0x0CB2}, // T3_BARRIER_C1
++{0x3294, 0x0CB2}, // T3_BARRIER_C2
++{0x3296, 0x0CB2}, // T3_BARRIER_C3
++{0x3298, 0x0CB2}, // T4_BARRIER_C0
++{0x329A, 0x0CB2}, // T4_BARRIER_C1
++{0x329C, 0x0CB2}, // T4_BARRIER_C2
++{0x329E, 0x0CB2}, // T4_BARRIER_C3
++{0x3108, 0x0CB1},
++{0x312A, 0x83E8},
++{0x3C82, 0x0FFF},
++{0x3102, 0x6100},
++{0x3104, 0x6100},
++{0x3106, 0x6100},
++{0x3120, 0x0AF0},
++{0x3122, 0x0CB2},
++/* Other_Super_Exposure_Setup */
++{ }
++}; /* Super_Exposure_Default_Plus_T2_Setup */
++
++static const struct ar0147_reg ar0147_rev2_Serial_12_bit_Timing_Setup[] = {
++#if 0
++/* PCLK=24Mhz/3 *50 /1/8 = 50MHz */
++{0x302A, 8}, // VT_PIX_CLK_DIV
++{0x302C, 1}, // VT_SYS_CLK_DIV
++{0x302E, 3}, // PRE_PLL_CLK_DIV
++{0x3030, 50}, // PLL_MULTIPLIER
++{0x3036, 8}, // OP_WORD_CLK_DIV
++{0x3038, 1}, // OP_SYS_CLK_DIV
++#else
++/* PCLK=24Mhz/4 *75 /1/9 = 50MHz */
++{0x302A, 9}, // VT_PIX_CLK_DIV
++{0x302C, 1}, // VT_SYS_CLK_DIV
++{0x302E, 4}, // PRE_PLL_CLK_DIV
++{0x3030, 75}, // PLL_MULTIPLIER
++{0x3036, 12}, // OP_WORD_CLK_DIV
++{0x3038, 1}, // OP_SYS_CLK_DIV
++#endif
++{0x30B0, 0x980C}, // DIGITAL_TEST
++{0x31DC, 0x1FB0},
++{ }
++}; /* Serial_12_bit_Timing_Setup */
++
++static const struct ar0147_reg ar0147_rev2_Readout_Mode_Configuration[] = {
++{0x30A2, 0x0001}, // X_ODD_INC_
++{0x30A6, 0x0001}, // Y_ODD_INC_
++{0x3040, 0x0000}, // READ_MODE
++{0x3082, 0x0008}, // OPERATION_MODE_CTRL: 3exp
++{0x3044, 0x0400}, // DARK_CONTROL
++{0x3064, 0x0000}, // SMIA_TEST: disable emb data and stats
++{0x33E0, 0x0C80}, // TEST_ASIL_ROWS
++{0x3180, 0x0080}, // RESERVED_MFR_3180
++{0x33E4, 0x0080}, // RESERVED_MFR_33E4
++#ifdef AR0147_EMBEDDED_LINE
++{0x3064, 0x0180}, // SMIA_TEST: enable emb data and stats
++#endif
++{ }
++}; /* Readout_Mode_Configuration */
++
++static const struct ar0147_reg ar0147_rev2_Full_Res_FOV[] = {
++{0x31B0, 0x0056}, // FRAME_PREAMBLE
++{0x31B2, 0x0045}, // LINE_PREAMBLE
++{0x3004, AR0147_X_START}, // X_ADDR_START_
++{0x3008, AR0147_X_END}, // X_ADDR_END_
++{0x3002, AR0147_Y_START}, // Y_ADDR_START_
++{0x3006, AR0147_Y_END}, // Y_ADDR_END_
++{0x3400, 0x10},
++{0x3402, (0x8000 & 0) | AR0147_MAX_WIDTH}, // X_OUTPUT_CONTROL
++{0x3404, (0x8000 & 0) | AR0147_MAX_HEIGHT}, // Y_OUTPUT_CONTROL
++{ }
++}; /* Full_Res_FOV */
++
++static const struct ar0147_reg ar0147_rev2_3exp_30FPS_Timing_and_Exposure[] = {
++{0x3082, 0x0008}, // OPERATION_MODE_CTRL: 3exp
++{0x30BA, 0x1002}, // DIGITAL_CTRL: 3exp max
++
++/* Row and Pixel Timing */
++{0x300C, AR0147_SENSOR_WIDTH + 52}, // LINE_LENGTH_PCK_ (1396)
++{0x300A, AR0147_SENSOR_HEIGHT + 226}, // FRAME_LENGTH_LINES_
++{0x3042, 0x0000}, // EXTRA_DELAY
++
++/* Exposure Settings */
++{0x3238, 0x0222}, // EXPOSURE_RATIO
++{0x3012, 0x0300}, // COARSE_INTEGRATION_TIME_
++
++{0x3014, 1550}, // FINE_INTEGRATION_TIME_
++{0x321E, 1550}, // FINE_INTEGRATION_TIME2
++{0x3222, 1550}, // FINE_INTEGRATION_TIME3
++{0x30B0, 0x980C}, // DIGITAL_TEST (MIPI ...)
++{0x32EA, 0x3C0E},
++{0x32EC, 0x72A1},
++{0x3362, 0x0000}, // DC_GAIN
++{0x3366, 0xCCCC}, // ANALOG_GAIN
++{0x3364, 0x01CF}, // DCG_TRIM
++{0x3C06, 0x083C},
++{0x3C08, 0x0100},
++{ }
++}; /* 3exp_30FPS_Timing_and_Exposure */
++
++static const struct ar0147_reg ar0147_rev2_SE_Plus_T2_Default_Mode_30FPS_Timing_and_Exposure[] = {
++{0x3082, 0x0008}, // OPERATION_MODE_CTRL: 3exp
++{0x30BA, 0x1003}, // DIGITAL_CTRL: 4exp max
++
++/* Row and Pixel Timing */
++{0x300C, AR0147_SENSOR_WIDTH + 52}, // LINE_LENGTH_PCK_ (1396)
++{0x300A, AR0147_SENSOR_HEIGHT + 226}, // FRAME_LENGTH_LINES_
++{0x3042, 0x0000}, // EXTRA_DELAY
++
++/* Exposure Settings */
++{0x3238, 0x8222}, // EXPOSURE_RATIO: separate integartion time!?
++{0x3012, 0x0300}, // COARSE_INTEGRATION_TIME_
++
++{0x322A, 0x0539}, // FINE_INTEGRATION_CTRL
++{0x3014, 0x0123}, // FINE_INTEGRATION_TIME_
++{0x3222, 0x0490}, // FINE_INTEGRATION_TIME3
++{0x3362, 0x0001}, // DC_GAIN
++{0x3366, 0xFDF7}, // ANALOG_GAIN
++{0x3364, 0x01CF}, // DCG_TRIM
++
++{0x30B0, 0x980C}, // DIGITAL_TEST (MIPI ...)
++{0x32EC, 0x7281},
++{ }
++}; /* SE_Plus_T2_Default_Mode_30FPS_Timing_and_Exposure */
++
++static const struct ar0147_reg ar0147_rev2_Serial_4_Lane_20_to_12_bit_Output[] = {
++{0x31D0, 0x0001}, // COMPANDING
++{0x31AE, 0x0304}, // SERIAL_FORMAT: HISPI 4-lanes
++{0x31AC, 0x140C}, // DATA_FORMAT_BITS: ADC20, RAW12
++//{0x301A, 0x0118}, // RESET_REGISTER
++{0x301A, 0x0018}, // RESET_REGISTER
++{ }
++}; /* Serial_4_Lane_20_to_12_bit_Output */
++
++static const struct ar0147_reg ar0147_rev2_MIPI_12_bit_450MBps_Settings[] = {
++{0x31AE, 0x0204}, // SERIAL_FORMAT: MIPI 4-lanes
++{0x3342, 0x122C}, // exposure1 DT=0x2c emb=0x12
++{0x3346, 0x122C}, // exposure2 DT=0x2c emb=0x12
++{0x334A, 0x122C}, // exposure3 DT=0x2c emb=0x12
++{0x334E, 0x122C}, // exposure4 DT=0x2c emb=0x12
++{0x3344, 0x0011}, // exposure1 VC=0
++{0x3348, 0x0111}, // exposure1 VC=1
++{0x334C, 0x0211}, // exposure1 VC=2
++{0x3350, 0x0311}, // exposure1 VC=3
++{0x31B0, 0x41}, // frame_preamble
++{0x31B2, 0x2e}, // line_preamble
++
++{0x31B4, 0x2185},
++{0x31B6, 0x1105},
++{0x31B8, 0x2047},
++{0x31BA, 0x105},
++{0x31BC, 0x704},
++{ }
++}; /* MIPI_12_bit_450MBps_Settings */
++
++static const struct ar0147_reg ar0147_rev2_shutter_and_booster_settings[] = {
++{0x32EA, 0x3CA8},
++{0x32F6, 0x3A01},
++{0x32D2, 0x200A},
++{0x32D0, 0x3005},
++{0x32D4, 0x3505},
++{0x32F8, 0x3C03},
++{0x32DC, 0x220C},
++{0x32D6, 0x3207},
++{0x32E2, 0x3707},
++{0x3260, 0x00FF},
++{0x3262, 0x00FF},
++{0x3528, 0xEEEE},
++{0x353E, 0x801F},
++{0x3532, 0x8F4C},
++{0x3250, 0x0005},
++{0x3252, 0x0107},
++{0x3256, 0x03E8},
++{0x3258, 0x0300},
++{0x325A, 0x0A13},
++{0x325E, 0x0186},
++{0x3524, 0x0C00},
++{0x3536, 0xFF38},
++{0x3532, 0x8F48},
++{0x3526, 0x8F00},
++{0x3536, 0xDF18},
++{0x3520, 0x0C00},
++{0x352E, 0x00FF},
++{0x3530, 0xFF00},
++{0x3532, 0x8F68},
++{0x3536, 0xDF18},
++{0x3252, 0x0107},
++{0x325E, 0x0186},
++{0x3096, 0x0000},
++{0x3504, 0x9100},
++{0x354E, 0x1480},
++{0x355A, 0x0B0E},
++{0x3372, 0xF50F},
++{0x337A, 0x100E},
++{0x3554, 0x1599},
++{0x32EA, 0x3CA9},
++{0x3510, 0x9753},
++{0x3520, 0x0800},
++{0x3522, 0x0008},
++{0x3524, 0x0C00},
++{0x3526, 0x0F00},
++{0x3528, 0xDDDD},
++{0x352A, 0x089F},
++{0x352C, 0x0012},
++{0x352E, 0x00FF},
++{0x3530, 0xFF00},
++{0x3532, 0x8F48},
++{0x3536, 0xFF38},
++{0x3538, 0x24FF},
++{0x353A, 0x9000},
++{0x353C, 0x7F00},
++{0x312A, 0x83E8},
++{0x3C82, 0x0FFF},
++{ }
++}; /* shutter_and_booster_settings */
++
++/* 3 Exp HDR, Full Resolution, MIPI 450MBPS 4 lane 12-bit, 30FPS, XMCLK=24MHz */
++static const struct ar0147_reg *ar0147_regs_hdr_mipi450mbps_12bit_30fps_rev2[] = {
++ ar0147_rev2_Reset,
++ ar0147_rev2_Sensor_Setup,
++ ar0147_rev2_Serial_12_bit_Timing_Setup,
++ ar0147_rev2_Readout_Mode_Configuration,
++ ar0147_rev2_Full_Res_FOV,
++ ar0147_rev2_3exp_30FPS_Timing_and_Exposure,
++ ar0147_rev2_Serial_4_Lane_20_to_12_bit_Output,
++ ar0147_rev2_MIPI_12_bit_450MBps_Settings,
++ NULL
++};
++
++/* Super-Exposure Plus T2, Full Resolution, MIPI 450MBPS 4 lane 12-bit, 30FPS, XMCLK=24MHz */
++static const struct ar0147_reg *ar0147_regs_seplus_mipi450mbps_12bit_30fps_rev2[] = {
++ ar0147_rev2_Reset,
++ ar0147_rev2_Sensor_Setup,
++ ar0147_rev2_Super_Exposure_Default_Plus_T2_Setup,
++ ar0147_rev2_Serial_12_bit_Timing_Setup,
++ ar0147_rev2_Readout_Mode_Configuration,
++ ar0147_rev2_Full_Res_FOV,
++ ar0147_rev2_SE_Plus_T2_Default_Mode_30FPS_Timing_and_Exposure,
++ ar0147_rev2_Serial_4_Lane_20_to_12_bit_Output,
++ ar0147_rev2_MIPI_12_bit_450MBps_Settings,
++ ar0147_rev2_shutter_and_booster_settings,
++ NULL
++};
+--
+2.7.4
+
diff --git a/bsp/meta-rcar/meta-rcar-gen3-adas/recipes-kernel/linux/linux-renesas/0171-lvds-ONSEMI-fix-matrix-position-during-crop.patch b/bsp/meta-rcar/meta-rcar-gen3-adas/recipes-kernel/linux/linux-renesas/0171-lvds-ONSEMI-fix-matrix-position-during-crop.patch
new file mode 100644
index 00000000..4142f489
--- /dev/null
+++ b/bsp/meta-rcar/meta-rcar-gen3-adas/recipes-kernel/linux/linux-renesas/0171-lvds-ONSEMI-fix-matrix-position-during-crop.patch
@@ -0,0 +1,130 @@
+From 7d4a772671d98789186d9c1eb7b44cb22c1d9981 Mon Sep 17 00:00:00 2001
+From: Vladimir Barinov <vladimir.barinov@cogentembedded.com>
+Date: Fri, 17 May 2019 23:18:30 +0300
+Subject: [PATCH 120/122] lvds: ONSEMI: fix matrix position during crop
+
+This preserves the centered window poition on imager
+matrix during crop
+
+Signed-off-by: Vladimir Barinov <vladimir.barinov@cogentembedded.com>
+---
+ drivers/media/i2c/soc_camera/ar0140.c | 8 ++++----
+ drivers/media/i2c/soc_camera/ar0143.c | 8 ++++----
+ drivers/media/i2c/soc_camera/ar0147.c | 8 ++++----
+ drivers/media/i2c/soc_camera/ar0231.c | 8 ++++----
+ drivers/media/i2c/soc_camera/ar0233.c | 8 ++++----
+ 5 files changed, 20 insertions(+), 20 deletions(-)
+
+diff --git a/drivers/media/i2c/soc_camera/ar0140.c b/drivers/media/i2c/soc_camera/ar0140.c
+index 807b6f8..c52ca4e 100644
+--- a/drivers/media/i2c/soc_camera/ar0140.c
++++ b/drivers/media/i2c/soc_camera/ar0140.c
+@@ -106,13 +106,13 @@ static int ar0140_set_window(struct v4l2_subdev *sd)
+ dev_dbg(&client->dev, "L=%d T=%d %dx%d\n", priv->rect.left, priv->rect.top, priv->rect.width, priv->rect.height);
+
+ /* horiz crop start */
+- reg16_write16(client, 0x3004, priv->rect.left);
++ reg16_write16(client, 0x3004, priv->rect.left + AR0140_X_START);
+ /* horiz crop end */
+- reg16_write16(client, 0x3008, priv->rect.left + priv->rect.width - 1);
++ reg16_write16(client, 0x3008, priv->rect.left + priv->rect.width - 1 + AR0140_X_START);
+ /* vert crop start */
+- reg16_write16(client, 0x3002, priv->rect.top);
++ reg16_write16(client, 0x3002, priv->rect.top + AR0140_Y_START);
+ /* vert crop end */
+- reg16_write16(client, 0x3006, priv->rect.top + priv->rect.height + 1);
++ reg16_write16(client, 0x3006, priv->rect.top + priv->rect.height - 1 + AR0140_Y_START);
+
+ return 0;
+ };
+diff --git a/drivers/media/i2c/soc_camera/ar0143.c b/drivers/media/i2c/soc_camera/ar0143.c
+index 01494fe..b61c7eb 100644
+--- a/drivers/media/i2c/soc_camera/ar0143.c
++++ b/drivers/media/i2c/soc_camera/ar0143.c
+@@ -140,13 +140,13 @@ static int ar0143_set_window(struct v4l2_subdev *sd)
+ dev_dbg(&client->dev, "L=%d T=%d %dx%d\n", priv->rect.left, priv->rect.top, priv->rect.width, priv->rect.height);
+
+ /* horiz crop start */
+- reg16_write16(client, 0x3004, priv->rect.left);
++ reg16_write16(client, 0x3004, priv->rect.left + AR0143_X_START);
+ /* horiz crop end */
+- reg16_write16(client, 0x3008, priv->rect.left + priv->rect.width - 1);
++ reg16_write16(client, 0x3008, priv->rect.left + priv->rect.width - 1 + AR0143_X_START);
+ /* vert crop start */
+- reg16_write16(client, 0x3002, priv->rect.top);
++ reg16_write16(client, 0x3002, priv->rect.top + AR0143_Y_START);
+ /* vert crop end */
+- reg16_write16(client, 0x3006, priv->rect.top + priv->rect.height + 1);
++ reg16_write16(client, 0x3006, priv->rect.top + priv->rect.height + 1 + AR0143_Y_START);
+
+ return 0;
+ };
+diff --git a/drivers/media/i2c/soc_camera/ar0147.c b/drivers/media/i2c/soc_camera/ar0147.c
+index cc7face..cc4e761 100644
+--- a/drivers/media/i2c/soc_camera/ar0147.c
++++ b/drivers/media/i2c/soc_camera/ar0147.c
+@@ -155,13 +155,13 @@ static int ar0147_set_window(struct v4l2_subdev *sd)
+ dev_dbg(&client->dev, "L=%d T=%d %dx%d\n", priv->rect.left, priv->rect.top, priv->rect.width, priv->rect.height);
+
+ /* horiz crop start */
+- reg16_write16(client, 0x3004, priv->rect.left);
++ reg16_write16(client, 0x3004, priv->rect.left + AR0147_X_START);
+ /* horiz crop end */
+- reg16_write16(client, 0x3008, priv->rect.left + priv->rect.width - 1);
++ reg16_write16(client, 0x3008, priv->rect.left + priv->rect.width - 1 + AR0147_X_START);
+ /* vert crop start */
+- reg16_write16(client, 0x3002, priv->rect.top);
++ reg16_write16(client, 0x3002, priv->rect.top + AR0147_Y_START);
+ /* vert crop end */
+- reg16_write16(client, 0x3006, priv->rect.top + priv->rect.height - 1);
++ reg16_write16(client, 0x3006, priv->rect.top + priv->rect.height - 1 + AR0147_Y_START);
+
+ return 0;
+ };
+diff --git a/drivers/media/i2c/soc_camera/ar0231.c b/drivers/media/i2c/soc_camera/ar0231.c
+index 05037c7..b239f56 100644
+--- a/drivers/media/i2c/soc_camera/ar0231.c
++++ b/drivers/media/i2c/soc_camera/ar0231.c
+@@ -96,13 +96,13 @@ static int ar0231_set_window(struct v4l2_subdev *sd)
+ dev_err(&client->dev, "L=%d T=%d %dx%d\n", priv->rect.left, priv->rect.top, priv->rect.width, priv->rect.height);
+
+ /* horiz crop start */
+- reg16_write16(client, 0x3004, priv->rect.left);
++ reg16_write16(client, 0x3004, priv->rect.left + AR0231_X_START);
+ /* horiz crop end */
+- reg16_write16(client, 0x3008, priv->rect.left + priv->rect.width - 1);
++ reg16_write16(client, 0x3008, priv->rect.left + priv->rect.width - 1 + AR0231_X_START);
+ /* vert crop start */
+- reg16_write16(client, 0x3002, priv->rect.top);
++ reg16_write16(client, 0x3002, priv->rect.top + AR0231_Y_START);
+ /* vert crop end */
+- reg16_write16(client, 0x3006, priv->rect.top + priv->rect.height + 1);
++ reg16_write16(client, 0x3006, priv->rect.top + priv->rect.height - 1 + AR0231_Y_START);
+
+ return 0;
+ };
+diff --git a/drivers/media/i2c/soc_camera/ar0233.c b/drivers/media/i2c/soc_camera/ar0233.c
+index 862c820..543b8a6 100644
+--- a/drivers/media/i2c/soc_camera/ar0233.c
++++ b/drivers/media/i2c/soc_camera/ar0233.c
+@@ -102,13 +102,13 @@ static int ar0233_set_window(struct v4l2_subdev *sd)
+ dev_dbg(&client->dev, "L=%d T=%d %dx%d\n", priv->rect.left, priv->rect.top, priv->rect.width, priv->rect.height);
+
+ /* horiz crop start */
+- reg16_write16(client, 0x3004, priv->rect.left);
++ reg16_write16(client, 0x3004, priv->rect.left + AR0233_X_START);
+ /* horiz crop end */
+- reg16_write16(client, 0x3008, priv->rect.left + priv->rect.width - 1);
++ reg16_write16(client, 0x3008, priv->rect.left + priv->rect.width - 1 + AR0233_X_START);
+ /* vert crop start */
+- reg16_write16(client, 0x3002, priv->rect.top);
++ reg16_write16(client, 0x3002, priv->rect.top + AR0233_Y_START);
+ /* vert crop end */
+- reg16_write16(client, 0x3006, priv->rect.top + priv->rect.height + 1);
++ reg16_write16(client, 0x3006, priv->rect.top + priv->rect.height - 1 + AR0233_Y_START);
+
+ return 0;
+ };
+--
+2.7.4
+
diff --git a/bsp/meta-rcar/meta-rcar-gen3-adas/recipes-kernel/linux/linux-renesas/0172-media-i2c-ar0147-fix-super-exposure-artifact-line.patch b/bsp/meta-rcar/meta-rcar-gen3-adas/recipes-kernel/linux/linux-renesas/0172-media-i2c-ar0147-fix-super-exposure-artifact-line.patch
new file mode 100644
index 00000000..a1191ede
--- /dev/null
+++ b/bsp/meta-rcar/meta-rcar-gen3-adas/recipes-kernel/linux/linux-renesas/0172-media-i2c-ar0147-fix-super-exposure-artifact-line.patch
@@ -0,0 +1,28 @@
+From 21a04e5800c8114edd5e4459cae4154eaaa71388 Mon Sep 17 00:00:00 2001
+From: Vladimir Barinov <vladimir.barinov@cogentembedded.com>
+Date: Tue, 21 May 2019 14:36:29 +0300
+Subject: [PATCH 121/122] media: i2c: ar0147: fix super exposure artifact line
+
+This fixes artifact line at SE+T2 mode
+
+Signed-off-by: Vladimir Barinov <vladimir.barinov@cogentembedded.com>
+---
+ drivers/media/i2c/soc_camera/ar0147_rev2.h | 2 +-
+ 1 file changed, 1 insertion(+), 1 deletion(-)
+
+diff --git a/drivers/media/i2c/soc_camera/ar0147_rev2.h b/drivers/media/i2c/soc_camera/ar0147_rev2.h
+index e5ccb8f..04d8e5e 100644
+--- a/drivers/media/i2c/soc_camera/ar0147_rev2.h
++++ b/drivers/media/i2c/soc_camera/ar0147_rev2.h
+@@ -747,7 +747,7 @@ static const struct ar0147_reg ar0147_rev2_shutter_and_booster_settings[] = {
+ {0x337A, 0x100E},
+ {0x3554, 0x1599},
+ {0x32EA, 0x3CA9},
+-{0x3510, 0x9753},
++//{0x3510, 0x9753},
+ {0x3520, 0x0800},
+ {0x3522, 0x0008},
+ {0x3524, 0x0C00},
+--
+2.7.4
+
diff --git a/bsp/meta-rcar/meta-rcar-gen3-adas/recipes-kernel/linux/linux-renesas/0173-lvds-ti9x4-fix-remote-gpio-setup.patch b/bsp/meta-rcar/meta-rcar-gen3-adas/recipes-kernel/linux/linux-renesas/0173-lvds-ti9x4-fix-remote-gpio-setup.patch
new file mode 100644
index 00000000..b7c39af0
--- /dev/null
+++ b/bsp/meta-rcar/meta-rcar-gen3-adas/recipes-kernel/linux/linux-renesas/0173-lvds-ti9x4-fix-remote-gpio-setup.patch
@@ -0,0 +1,132 @@
+From 76e798d5f852d1551474a27a519cd008ff29f4f1 Mon Sep 17 00:00:00 2001
+From: Vladimir Barinov <vladimir.barinov@cogentembedded.com>
+Date: Tue, 28 May 2019 16:07:28 +0300
+Subject: [PATCH 122/122] lvds: ti9x4: fix remote gpio setup
+
+The remote gpio must be set after remote gpio enablement on
+serializer side.
+Fix compilation warnings.
+GEOEMI registers addresing is 1 byte.
+
+Signed-off-by: Vladimir Barinov <vladimir.barinov@cogentembedded.com>
+---
+ drivers/media/i2c/soc_camera/ar0233.c | 1 -
+ drivers/media/i2c/soc_camera/gw4200_ar014x.c | 8 ++++----
+ drivers/media/i2c/soc_camera/gw5200_imx390.c | 8 ++++----
+ drivers/media/i2c/soc_camera/imx390.c | 2 +-
+ drivers/media/i2c/soc_camera/ti9x4.c | 5 +++--
+ 5 files changed, 12 insertions(+), 12 deletions(-)
+
+diff --git a/drivers/media/i2c/soc_camera/ar0233.c b/drivers/media/i2c/soc_camera/ar0233.c
+index 543b8a6..f3b899e 100644
+--- a/drivers/media/i2c/soc_camera/ar0233.c
++++ b/drivers/media/i2c/soc_camera/ar0233.c
+@@ -63,7 +63,6 @@ static inline struct ar0233_priv *to_ar0233(const struct i2c_client *client)
+
+ static int ar0233_set_regs(struct i2c_client *client, const struct ar0233_reg **pregs)
+ {
+- struct ar0233_priv *priv = to_ar0233(client);
+ const struct ar0233_reg *regs;
+ int i, j;
+
+diff --git a/drivers/media/i2c/soc_camera/gw4200_ar014x.c b/drivers/media/i2c/soc_camera/gw4200_ar014x.c
+index 674e409..45123ae 100644
+--- a/drivers/media/i2c/soc_camera/gw4200_ar014x.c
++++ b/drivers/media/i2c/soc_camera/gw4200_ar014x.c
+@@ -267,14 +267,14 @@ static int gw4200_g_register(struct v4l2_subdev *sd,
+ {
+ struct i2c_client *client = v4l2_get_subdevdata(sd);
+ int ret;
+- u16 val = 0;
++ u8 val = 0;
+
+- ret = reg16_read16(client, (u16)reg->reg, &val);
++ ret = reg8_read(client, (u8)reg->reg, &val);
+ if (ret < 0)
+ return ret;
+
+ reg->val = val;
+- reg->size = sizeof(u16);
++ reg->size = sizeof(u8);
+
+ return 0;
+ }
+@@ -284,7 +284,7 @@ static int gw4200_s_register(struct v4l2_subdev *sd,
+ {
+ struct i2c_client *client = v4l2_get_subdevdata(sd);
+
+- return reg16_write16(client, (u16)reg->reg, (u16)reg->val);
++ return reg8_write(client, (u8)reg->reg, (u8)reg->val);
+ }
+ #endif
+
+diff --git a/drivers/media/i2c/soc_camera/gw5200_imx390.c b/drivers/media/i2c/soc_camera/gw5200_imx390.c
+index 0703c3d..90de41f 100644
+--- a/drivers/media/i2c/soc_camera/gw5200_imx390.c
++++ b/drivers/media/i2c/soc_camera/gw5200_imx390.c
+@@ -235,14 +235,14 @@ static int gw5200_g_register(struct v4l2_subdev *sd,
+ {
+ struct i2c_client *client = v4l2_get_subdevdata(sd);
+ int ret;
+- u16 val = 0;
++ u8 val = 0;
+
+- ret = reg16_read16(client, (u16)reg->reg, &val);
++ ret = reg8_read(client, (u8)reg->reg, &val);
+ if (ret < 0)
+ return ret;
+
+ reg->val = val;
+- reg->size = sizeof(u16);
++ reg->size = sizeof(u8);
+
+ return 0;
+ }
+@@ -252,7 +252,7 @@ static int gw5200_s_register(struct v4l2_subdev *sd,
+ {
+ struct i2c_client *client = v4l2_get_subdevdata(sd);
+
+- return reg16_write16(client, (u16)reg->reg, (u16)reg->val);
++ return reg8_write(client, (u8)reg->reg, (u8)reg->val);
+ }
+ #endif
+
+diff --git a/drivers/media/i2c/soc_camera/imx390.c b/drivers/media/i2c/soc_camera/imx390.c
+index 7171d70..87279d0 100644
+--- a/drivers/media/i2c/soc_camera/imx390.c
++++ b/drivers/media/i2c/soc_camera/imx390.c
+@@ -249,7 +249,7 @@ static int imx390_s_ctrl(struct v4l2_ctrl *ctrl)
+ struct imx390_priv *priv = to_imx390(client);
+ int ret = -EINVAL;
+ int val;
+- uint8_t val8;
++ uint8_t val8 = 0;
+
+ if (!priv->init_complete)
+ return 0;
+diff --git a/drivers/media/i2c/soc_camera/ti9x4.c b/drivers/media/i2c/soc_camera/ti9x4.c
+index fdb50e5..0cfcfaa 100644
+--- a/drivers/media/i2c/soc_camera/ti9x4.c
++++ b/drivers/media/i2c/soc_camera/ti9x4.c
+@@ -275,8 +275,6 @@ static void ti9x4_fpdlink3_setup(struct i2c_client *client, int idx)
+ reg8_write(client, 0x70, ((priv->vc_map >> (idx * 4)) << 6) | 0x1e); /* CSI data type: yuv422 8-bit, assign VC */
+ reg8_write(client, 0x71, ((priv->vc_map >> (idx * 4)) << 6) | 0x2c); /* CSI data type: RAW12, assign VC */
+ reg8_write(client, 0xbc, 0x00); /* Setup minimal time between FV and LV to 3 PCLKs */
+- reg8_write(client, 0x6e, 0x88 | (priv->gpio[1] << 4) | priv->gpio[0]); /* Remote GPIO1/GPIO0 setup */
+- reg8_write(client, 0x6f, 0x88 | (priv->gpio[3] << 4) | priv->gpio[2]); /* Remote GPIO3/GPIO2 setup */
+ reg8_write(client, 0x72, priv->vc_map >> (idx * 4)); /* CSI VC MAP */
+ }
+
+@@ -340,6 +338,9 @@ static int ti9x4_initialize(struct i2c_client *client)
+ break;
+ }
+ client->addr = priv->des_addr;
++
++ reg8_write(client, 0x6e, 0x88 | (priv->gpio[1] << 4) | priv->gpio[0]); /* Remote GPIO1/GPIO0 setup */
++ reg8_write(client, 0x6f, 0x88 | (priv->gpio[3] << 4) | priv->gpio[2]); /* Remote GPIO3/GPIO2 setup */
+ }
+
+ return 0;
+--
+2.7.4
+
diff --git a/bsp/meta-rcar/meta-rcar-gen3-adas/recipes-kernel/linux/linux-renesas/0174-arm64-dts-renesas-ulcb-vb2-Drive-CAN-controller-rese.patch b/bsp/meta-rcar/meta-rcar-gen3-adas/recipes-kernel/linux/linux-renesas/0174-arm64-dts-renesas-ulcb-vb2-Drive-CAN-controller-rese.patch
new file mode 100644
index 00000000..ae8eb8b0
--- /dev/null
+++ b/bsp/meta-rcar/meta-rcar-gen3-adas/recipes-kernel/linux/linux-renesas/0174-arm64-dts-renesas-ulcb-vb2-Drive-CAN-controller-rese.patch
@@ -0,0 +1,89 @@
+From fb760e67e0336587583eb32cf77bbdf4b4e1fc74 Mon Sep 17 00:00:00 2001
+From: Andrey Gusakov <andrey.gusakov@cogentembedded.com>
+Date: Tue, 28 May 2019 19:55:13 +0300
+Subject: [PATCH] arm64: dts: renesas: ulcb-vb2: Drive CAN controller reset
+ through regulators
+
+This uses regulators instead of GPIO hogs for controlling CAN
+reset pins on VideoBox v2 which fixes CAN cold-start issues.
+
+Signed-off-by: Andrey Gusakov <andrey.gusakov@cogentembedded.com>
+Signed-off-by: Valentine Barshak <valentine.barshak@cogentembedded.com>
+---
+ arch/arm64/boot/dts/renesas/ulcb-vb2.dtsi | 32 +++++++++++++++++++------------
+ 1 file changed, 20 insertions(+), 12 deletions(-)
+
+diff --git a/arch/arm64/boot/dts/renesas/ulcb-vb2.dtsi b/arch/arm64/boot/dts/renesas/ulcb-vb2.dtsi
+index 1610949..5831d12 100644
+--- a/arch/arm64/boot/dts/renesas/ulcb-vb2.dtsi
++++ b/arch/arm64/boot/dts/renesas/ulcb-vb2.dtsi
+@@ -94,6 +94,24 @@
+ regulator-always-on;
+ };
+
++ can2_power: regulator@11 {
++ compatible = "regulator-fixed";
++ regulator-name = "can2_power";
++ regulator-min-microvolt = <3300000>;
++ regulator-max-microvolt = <3300000>;
++ gpio = <&gpio_ext_pwr 8 GPIO_ACTIVE_HIGH>;
++ enable-active-high;
++ };
++
++ can3_power: regulator@12 {
++ compatible = "regulator-fixed";
++ regulator-name = "can3_power";
++ regulator-min-microvolt = <3300000>;
++ regulator-max-microvolt = <3300000>;
++ gpio = <&gpio_ext_pwr 9 GPIO_ACTIVE_HIGH>;
++ enable-active-high;
++ };
++
+ /delete-node/sound;
+
+ rsnd_ak4613: sound@0 {
+@@ -187,6 +205,7 @@
+ interrupt-parent = <&gpio0>;
+ interrupts = <15 GPIO_ACTIVE_LOW>;
+ spi-max-frequency = <10000000>;
++ vdd-supply = <&can2_power>;
+ };
+ spican1: spidev@1 {
+ compatible = "microchip,mcp2515";
+@@ -195,6 +214,7 @@
+ interrupt-parent = <&gpio1>;
+ interrupts = <5 GPIO_ACTIVE_LOW>;
+ spi-max-frequency = <10000000>;
++ vdd-supply = <&can3_power>;
+ };
+ };
+ };
+@@ -1147,12 +1167,6 @@
+ output-high;
+ line-name = "can2_120R_load";
+ };
+- can2_rst {
+- gpio-hog;
+- gpios = <8 GPIO_ACTIVE_HIGH>;
+- output-high;
+- line-name = "can2_rst";
+- };
+ /* CAN3 */
+ can3_stby {
+ gpio-hog;
+@@ -1166,12 +1180,6 @@
+ output-high;
+ line-name = "can3_120R_load";
+ };
+- can3_rst {
+- gpio-hog;
+- gpios = <9 GPIO_ACTIVE_HIGH>;
+- output-high;
+- line-name = "can3_rst";
+- };
+ };
+ };
+
+--
+2.7.4
+
diff --git a/bsp/meta-rcar/meta-rcar-gen3-adas/recipes-kernel/linux/linux-renesas/0175-lvds-ov2775-add-exposure-gain.patch b/bsp/meta-rcar/meta-rcar-gen3-adas/recipes-kernel/linux/linux-renesas/0175-lvds-ov2775-add-exposure-gain.patch
new file mode 100644
index 00000000..5d257116
--- /dev/null
+++ b/bsp/meta-rcar/meta-rcar-gen3-adas/recipes-kernel/linux/linux-renesas/0175-lvds-ov2775-add-exposure-gain.patch
@@ -0,0 +1,76 @@
+From 2abfbc0f83952075f87a9eaf8ea239a260ca2a60 Mon Sep 17 00:00:00 2001
+From: Vladimir Barinov <vladimir.barinov@cogentembedded.com>
+Date: Tue, 4 Jun 2019 19:44:00 +0300
+Subject: [PATCH 1/5] lvds: ov2775: add exposure, gain
+
+This add exposure and gain for ov2775 imager
+
+Signed-off-by: Vladimir Barinov <vladimir.barinov@cogentembedded.com>
+---
+ drivers/media/i2c/soc_camera/ov2775.c | 20 +++++++++++++++++---
+ drivers/media/i2c/soc_camera/ov2775.h | 2 +-
+ 2 files changed, 18 insertions(+), 4 deletions(-)
+
+diff --git a/drivers/media/i2c/soc_camera/ov2775.c b/drivers/media/i2c/soc_camera/ov2775.c
+index 2022d47..989e7ca 100644
+--- a/drivers/media/i2c/soc_camera/ov2775.c
++++ b/drivers/media/i2c/soc_camera/ov2775.c
+@@ -262,7 +262,21 @@ static int ov2775_s_ctrl(struct v4l2_ctrl *ctrl)
+ case V4L2_CID_SHARPNESS:
+ case V4L2_CID_AUTOGAIN:
+ case V4L2_CID_GAIN:
++ /* HCG digital gain */
++ ret = reg16_write(client, 0x315a, ctrl->val >> 8);
++ ret |= reg16_write(client, 0x315b, ctrl->val & 0xff);
++ /* LCG digital gain */
++ ret |= reg16_write(client, 0x315c, ctrl->val >> 8);
++ ret |= reg16_write(client, 0x315d, ctrl->val & 0xff);
++ /* VS digital gain */
++ ret |= reg16_write(client, 0x315e, ctrl->val >> 8);
++ ret |= reg16_write(client, 0x315f, ctrl->val & 0xff);
++ break;
+ case V4L2_CID_EXPOSURE:
++ /* HCG/LCG exposure time */
++ ret = reg16_write(client, 0x30B6, ctrl->val >> 8);
++ ret |= reg16_write(client, 0x30B7, ctrl->val & 0xff);
++ break;
+ case V4L2_CID_HFLIP:
+ case V4L2_CID_VFLIP:
+ break;
+@@ -418,7 +432,7 @@ static int ov2775_probe(struct i2c_client *client,
+ priv->sd.flags = V4L2_SUBDEV_FL_HAS_DEVNODE;
+
+ priv->exposure = 0x100;
+- priv->gain = 0x100;
++ priv->gain = 0x200;
+ priv->autogain = 1;
+ v4l2_ctrl_handler_init(&priv->hdl, 4);
+ v4l2_ctrl_new_std(&priv->hdl, &ov2775_ctrl_ops,
+@@ -436,9 +450,9 @@ static int ov2775_probe(struct i2c_client *client,
+ v4l2_ctrl_new_std(&priv->hdl, &ov2775_ctrl_ops,
+ V4L2_CID_AUTOGAIN, 0, 1, 1, priv->autogain);
+ v4l2_ctrl_new_std(&priv->hdl, &ov2775_ctrl_ops,
+- V4L2_CID_GAIN, 0, 0xffff, 1, priv->gain);
++ V4L2_CID_GAIN, 0, 0x3fff, 1, priv->gain);
+ v4l2_ctrl_new_std(&priv->hdl, &ov2775_ctrl_ops,
+- V4L2_CID_EXPOSURE, 0, 0xffff, 1, priv->exposure);
++ V4L2_CID_EXPOSURE, 0, 0x7ff, 1, priv->exposure);
+ v4l2_ctrl_new_std(&priv->hdl, &ov2775_ctrl_ops,
+ V4L2_CID_HFLIP, 0, 1, 1, 1);
+ v4l2_ctrl_new_std(&priv->hdl, &ov2775_ctrl_ops,
+diff --git a/drivers/media/i2c/soc_camera/ov2775.h b/drivers/media/i2c/soc_camera/ov2775.h
+index 7e1ee31..9ff8968 100644
+--- a/drivers/media/i2c/soc_camera/ov2775.h
++++ b/drivers/media/i2c/soc_camera/ov2775.h
+@@ -9,7 +9,7 @@
+ * option) any later version.
+ */
+
+-#define OV2775_DISPLAY_PATTERN_COLOR_BAR
++//#define OV2775_DISPLAY_PATTERN_COLOR_BAR
+
+ #define OV2775_MAX_WIDTH 1920
+ #define OV2775_MAX_HEIGHT 1080
+--
+2.7.4
+
diff --git a/bsp/meta-rcar/meta-rcar-gen3-adas/recipes-kernel/linux/linux-renesas/0176-lvds-geosemi-put-imager-to-autodetect-tail.patch b/bsp/meta-rcar/meta-rcar-gen3-adas/recipes-kernel/linux/linux-renesas/0176-lvds-geosemi-put-imager-to-autodetect-tail.patch
new file mode 100644
index 00000000..a3413667
--- /dev/null
+++ b/bsp/meta-rcar/meta-rcar-gen3-adas/recipes-kernel/linux/linux-renesas/0176-lvds-geosemi-put-imager-to-autodetect-tail.patch
@@ -0,0 +1,58 @@
+From a0b6b13ecaa44559b02574814e941d5fbbf6589c Mon Sep 17 00:00:00 2001
+From: Vladimir Barinov <vladimir.barinov@cogentembedded.com>
+Date: Tue, 4 Jun 2019 20:03:35 +0300
+Subject: [PATCH 2/5] lvds: geosemi: put imager to autodetect tail
+
+Put Geosemi cameras to tail since their produce ID is
+just an i2c address
+
+Signed-off-by: Vladimir Barinov <vladimir.barinov@cogentembedded.com>
+---
+ drivers/media/i2c/soc_camera/ov106xx.c | 24 ++++++++++++------------
+ 1 file changed, 12 insertions(+), 12 deletions(-)
+
+diff --git a/drivers/media/i2c/soc_camera/ov106xx.c b/drivers/media/i2c/soc_camera/ov106xx.c
+index 442e54a..36aa88a 100644
+--- a/drivers/media/i2c/soc_camera/ov106xx.c
++++ b/drivers/media/i2c/soc_camera/ov106xx.c
+@@ -129,18 +129,6 @@ static int ov106xx_probe(struct i2c_client *client,
+ goto out;
+ }
+
+- ret = gw4200_probe(client, did);
+- if (!ret) {
+- chip_id = ID_GW4200_AR014X;
+- goto out;
+- }
+-
+- ret = gw5200_probe(client, did);
+- if (!ret) {
+- chip_id = ID_GW5200_IMX390;
+- goto out;
+- }
+-
+ ret = ov2775_probe(client, did);
+ if (!ret) {
+ chip_id = ID_OV2775;
+@@ -171,6 +159,18 @@ static int ov106xx_probe(struct i2c_client *client,
+ goto out;
+ }
+
++ ret = gw4200_probe(client, did);
++ if (!ret) {
++ chip_id = ID_GW4200_AR014X;
++ goto out;
++ }
++
++ ret = gw5200_probe(client, did);
++ if (!ret) {
++ chip_id = ID_GW5200_IMX390;
++ goto out;
++ }
++
+ v4l_err(client, "failed to probe @ 0x%02x (%s)\n",
+ client->addr, client->adapter->name);
+ out:
+--
+2.7.4
+
diff --git a/bsp/meta-rcar/meta-rcar-gen3-adas/recipes-kernel/linux/linux-renesas/0177-media-rcar_vin-add-GREY-Y8-bypass.patch b/bsp/meta-rcar/meta-rcar-gen3-adas/recipes-kernel/linux/linux-renesas/0177-media-rcar_vin-add-GREY-Y8-bypass.patch
new file mode 100644
index 00000000..3a1278d9
--- /dev/null
+++ b/bsp/meta-rcar/meta-rcar-gen3-adas/recipes-kernel/linux/linux-renesas/0177-media-rcar_vin-add-GREY-Y8-bypass.patch
@@ -0,0 +1,85 @@
+From 59876245439d2c5602bccdd454d1ef0a72cdb571 Mon Sep 17 00:00:00 2001
+From: Vladimir Barinov <vladimir.barinov@cogentembedded.com>
+Date: Fri, 7 Jun 2019 19:18:51 +0300
+Subject: [PATCH 3/5] media: rcar_vin: add GREY (Y8) bypass
+
+This adds bypass of luma Y8 stream
+
+Signed-off-by: Vladimir Barinov <vladimir.barinov@cogentembedded.com>
+---
+ drivers/media/platform/soc_camera/rcar_vin.c | 22 +++++++++++++++++-----
+ 1 file changed, 17 insertions(+), 5 deletions(-)
+
+diff --git a/drivers/media/platform/soc_camera/rcar_vin.c b/drivers/media/platform/soc_camera/rcar_vin.c
+index 5239938..291d115 100644
+--- a/drivers/media/platform/soc_camera/rcar_vin.c
++++ b/drivers/media/platform/soc_camera/rcar_vin.c
+@@ -1076,6 +1076,7 @@ static int rcar_vin_setup(struct rcar_vin_priv *priv)
+ break;
+ case MEDIA_BUS_FMT_SBGGR8_1X8:
+ case MEDIA_BUS_FMT_SBGGR12_1X12:
++ case MEDIA_BUS_FMT_Y8_1X8:
+ vnmc |= VNMC_INF_RAW8 | VNMC_BPS;
+ break;
+ default:
+@@ -1111,8 +1112,11 @@ static int rcar_vin_setup(struct rcar_vin_priv *priv)
+ output_is_yuv = true;
+ break;
+ case V4L2_PIX_FMT_GREY:
+- dmr = VNDMR_DTMD_YCSEP | VNDMR_YMODE_Y8;
+- output_is_yuv = true;
++ if (input_is_yuv) {
++ dmr = VNDMR_DTMD_YCSEP | VNDMR_YMODE_Y8;
++ output_is_yuv = true;
++ } else
++ dmr = 0;
+ break;
+ case V4L2_PIX_FMT_ARGB555:
+ dmr = VNDMR_DTMD_ARGB;
+@@ -1802,14 +1806,16 @@ static int rcar_vin_set_rect(struct soc_camera_device *icd)
+ priv->chip == RCAR_M3N || priv->chip == RCAR_V3M) {
+ if ((icd->current_fmt->host_fmt->fourcc != V4L2_PIX_FMT_NV12) &&
+ (icd->current_fmt->host_fmt->fourcc != V4L2_PIX_FMT_SBGGR8) &&
+- (icd->current_fmt->host_fmt->fourcc != V4L2_PIX_FMT_SBGGR12)
++ (icd->current_fmt->host_fmt->fourcc != V4L2_PIX_FMT_SBGGR12) &&
++ ((icd->current_fmt->host_fmt->fourcc == V4L2_PIX_FMT_GREY) && (icd->current_fmt->code == MEDIA_BUS_FMT_Y8_1X8))
+ && is_scaling(cam)) {
+ ret = rcar_vin_uds_set(priv, cam);
+ if (ret < 0)
+ return ret;
+ }
+ if ((icd->current_fmt->host_fmt->fourcc == V4L2_PIX_FMT_SBGGR8) ||
+- (icd->current_fmt->host_fmt->fourcc == V4L2_PIX_FMT_SBGGR12))
++ (icd->current_fmt->host_fmt->fourcc == V4L2_PIX_FMT_SBGGR12) ||
++ ((icd->current_fmt->host_fmt->fourcc == V4L2_PIX_FMT_GREY) && (icd->current_fmt->code == MEDIA_BUS_FMT_Y8_1X8)))
+ iowrite32(ALIGN(cam->out_width / 2, 0x10),
+ priv->base + VNIS_REG);
+ else if (is_scaling(cam) ||
+@@ -2228,6 +2234,7 @@ static int rcar_vin_get_formats(struct soc_camera_device *icd, unsigned int idx,
+ case MEDIA_BUS_FMT_RGB888_1X24:
+ case MEDIA_BUS_FMT_SBGGR8_1X8:
+ case MEDIA_BUS_FMT_SBGGR12_1X12:
++ case MEDIA_BUS_FMT_Y8_1X8:
+ if (cam->extra_fmt)
+ break;
+
+@@ -2447,10 +2454,15 @@ static int rcar_vin_set_fmt(struct soc_camera_device *icd,
+ case V4L2_PIX_FMT_XBGR32:
+ can_scale = priv->chip != RCAR_E1;
+ break;
++ case V4L2_PIX_FMT_GREY:
++ if (icd->current_fmt->code == MEDIA_BUS_FMT_Y8_1X8)
++ can_scale = false;
++ else
++ can_scale = true;
++ break;
+ case V4L2_PIX_FMT_ABGR32:
+ case V4L2_PIX_FMT_UYVY:
+ case V4L2_PIX_FMT_YUYV:
+- case V4L2_PIX_FMT_GREY:
+ case V4L2_PIX_FMT_RGB565:
+ case V4L2_PIX_FMT_ARGB555:
+ case V4L2_PIX_FMT_NV16:
+--
+2.7.4
+
diff --git a/bsp/meta-rcar/meta-rcar-gen3-adas/recipes-kernel/linux/linux-renesas/0178-lvds-add-OV2311-imager.patch b/bsp/meta-rcar/meta-rcar-gen3-adas/recipes-kernel/linux/linux-renesas/0178-lvds-add-OV2311-imager.patch
new file mode 100644
index 00000000..9f773f70
--- /dev/null
+++ b/bsp/meta-rcar/meta-rcar-gen3-adas/recipes-kernel/linux/linux-renesas/0178-lvds-add-OV2311-imager.patch
@@ -0,0 +1,935 @@
+From 5c4b2dfb06a275237855fe86e6d3d7952a75d013 Mon Sep 17 00:00:00 2001
+From: Vladimir Barinov <vladimir.barinov@cogentembedded.com>
+Date: Fri, 7 Jun 2019 20:51:35 +0300
+Subject: [PATCH 4/5] lvds: add OV2311 imager
+
+This add OV2311 lvds imager
+
+Signed-off-by: Vladimir Barinov <vladimir.barinov@cogentembedded.com>
+---
+ drivers/media/i2c/soc_camera/ov106xx.c | 13 +-
+ drivers/media/i2c/soc_camera/ov2311.c | 637 +++++++++++++++++++++++++++++++++
+ drivers/media/i2c/soc_camera/ov2311.h | 217 +++++++++++
+ 3 files changed, 866 insertions(+), 1 deletion(-)
+ create mode 100644 drivers/media/i2c/soc_camera/ov2311.c
+ create mode 100644 drivers/media/i2c/soc_camera/ov2311.h
+
+diff --git a/drivers/media/i2c/soc_camera/ov106xx.c b/drivers/media/i2c/soc_camera/ov106xx.c
+index 36aa88a..70067d7 100644
+--- a/drivers/media/i2c/soc_camera/ov106xx.c
++++ b/drivers/media/i2c/soc_camera/ov106xx.c
+@@ -28,6 +28,7 @@
+ #include "ox03a.c"
+ #include "isx016.c"
+ #include "isx019.c"
++#include "ov2311.c"
+
+ static enum {
+ ID_OV10635,
+@@ -49,12 +50,13 @@ static enum {
+ ID_OX03A,
+ ID_ISX016,
+ ID_ISX019,
++ ID_OV2311,
+ } chip_id;
+
+ static int ov106xx_probe(struct i2c_client *client,
+ const struct i2c_device_id *did)
+ {
+- int ret;
++ int ret = -1;
+ chip_id = -EINVAL;
+
+ ret = ar0231_probe(client, did);
+@@ -135,6 +137,12 @@ static int ov106xx_probe(struct i2c_client *client,
+ goto out;
+ }
+
++ ret = ov2311_probe(client, did);
++ if (!ret) {
++ chip_id = ID_OV2311;
++ goto out;
++ }
++
+ ret = imx390_probe(client, did);
+ if (!ret) {
+ chip_id = ID_IMX390;
+@@ -237,6 +245,9 @@ static int ov106xx_remove(struct i2c_client *client)
+ case ID_ISX019:
+ isx019_remove(client);
+ break;
++ case ID_OV2311:
++ ov2311_remove(client);
++ break;
+ };
+
+ return 0;
+diff --git a/drivers/media/i2c/soc_camera/ov2311.c b/drivers/media/i2c/soc_camera/ov2311.c
+new file mode 100644
+index 0000000..06e57dd
+--- /dev/null
++++ b/drivers/media/i2c/soc_camera/ov2311.c
+@@ -0,0 +1,637 @@
++/*
++ * OmniVision ov2311 sensor camera driver
++ *
++ * Copyright (C) 2015-2019 Cogent Embedded, Inc.
++ *
++ * This program is free software; you can redistribute it and/or modify it
++ * under the terms of the GNU General Public License as published by the
++ * Free Software Foundation; either version 2 of the License, or (at your
++ * option) any later version.
++ */
++
++#include <linux/delay.h>
++#include <linux/init.h>
++#include <linux/i2c.h>
++#include <linux/module.h>
++#include <linux/of_graph.h>
++#include <linux/videodev2.h>
++
++#include <media/soc_camera.h>
++#include <media/v4l2-common.h>
++#include <media/v4l2-ctrls.h>
++
++#include "max9286.h"
++#include "ov2311.h"
++
++#define OV2311_I2C_ADDR 0x60
++
++#define OV2311_PID 0x300a
++#define OV2311_VER 0x300b
++#define OV2311_REV 0x300c
++#define OV2311_VERSION_REG 0x2311
++
++#define OV2311_MEDIA_BUS_FMT MEDIA_BUS_FMT_Y8_1X8
++
++struct ov2311_priv {
++ struct v4l2_subdev sd;
++ struct v4l2_ctrl_handler hdl;
++ struct media_pad pad;
++ struct v4l2_rect rect;
++ int subsampling;
++ int fps_denominator;
++ int init_complete;
++ u8 id[6];
++ int dvp_order;
++ /* serializers */
++ int max9286_addr;
++ int max9271_addr;
++ int ti9x4_addr;
++ int ti9x3_addr;
++ int port;
++ int gpio_resetb;
++ int gpio_fsin;
++};
++
++static inline struct ov2311_priv *to_ov2311(const struct i2c_client *client)
++{
++ return container_of(i2c_get_clientdata(client), struct ov2311_priv, sd);
++}
++
++static inline struct v4l2_subdev *ov2311_to_sd(struct v4l2_ctrl *ctrl)
++{
++ return &container_of(ctrl->handler, struct ov2311_priv, hdl)->sd;
++}
++
++static void ov2311_s_port(struct i2c_client *client, int fwd_en)
++{
++ struct ov2311_priv *priv = to_ov2311(client);
++ int tmp_addr;
++
++ if (priv->max9286_addr) {
++ tmp_addr = client->addr;
++ client->addr = priv->max9286_addr; /* Deserializer I2C address */
++ reg8_write(client, 0x0a, fwd_en ? 0x11 << priv->port : 0); /* Enable/disable reverse/forward control for this port */
++ usleep_range(5000, 5500); /* wait 5ms */
++ client->addr = tmp_addr;
++ };
++}
++
++static int ov2311_set_regs(struct i2c_client *client,
++ const struct ov2311_reg *regs, int nr_regs)
++{
++ int i;
++
++ for (i = 0; i < nr_regs; i++) {
++ if (regs[i].reg == OV2311_DELAY) {
++ mdelay(regs[i].val);
++ continue;
++ }
++
++ if (reg16_write(client, regs[i].reg, regs[i].val)) {
++ usleep_range(100, 150); /* wait 100ns */
++ reg16_write(client, regs[i].reg, regs[i].val);
++ }
++ }
++
++ return 0;
++}
++
++static int ov2311_s_stream(struct v4l2_subdev *sd, int enable)
++{
++ return 0;
++}
++
++static int ov2311_set_window(struct v4l2_subdev *sd)
++{
++ struct i2c_client *client = v4l2_get_subdevdata(sd);
++ struct ov2311_priv *priv = to_ov2311(client);
++
++ dev_dbg(&client->dev, "L=%d T=%d %dx%d\n", priv->rect.left, priv->rect.top, priv->rect.width, priv->rect.height);
++#if 0
++ /* setup resolution */
++ reg16_write(client, 0x3808, priv->rect.width >> 8);
++ reg16_write(client, 0x3809, priv->rect.width & 0xff);
++ reg16_write(client, 0x380a, priv->rect.height >> 8);
++ reg16_write(client, 0x380b, priv->rect.height & 0xff);
++
++ /* horiz isp windowstart */
++ reg16_write(client, 0x3810, priv->rect.left >> 8);
++ reg16_write(client, 0x3811, priv->rect.left & 0xff);
++ reg16_write(client, 0x3812, priv->rect.top >> 8);
++ reg16_write(client, 0x3813, priv->rect.top & 0xff);
++#endif
++ return 0;
++};
++
++static int ov2311_get_fmt(struct v4l2_subdev *sd,
++ struct v4l2_subdev_pad_config *cfg,
++ struct v4l2_subdev_format *format)
++{
++ struct v4l2_mbus_framefmt *mf = &format->format;
++ struct i2c_client *client = v4l2_get_subdevdata(sd);
++ struct ov2311_priv *priv = to_ov2311(client);
++
++ if (format->pad)
++ return -EINVAL;
++
++ mf->width = priv->rect.width;
++ mf->height = priv->rect.height;
++ mf->code = OV2311_MEDIA_BUS_FMT;
++ mf->colorspace = V4L2_COLORSPACE_SMPTE170M;
++ mf->field = V4L2_FIELD_NONE;
++
++ return 0;
++}
++
++static int ov2311_set_fmt(struct v4l2_subdev *sd,
++ struct v4l2_subdev_pad_config *cfg,
++ struct v4l2_subdev_format *format)
++{
++ struct v4l2_mbus_framefmt *mf = &format->format;
++
++ mf->code = OV2311_MEDIA_BUS_FMT;
++ mf->colorspace = V4L2_COLORSPACE_SMPTE170M;
++ mf->field = V4L2_FIELD_NONE;
++
++ if (format->which == V4L2_SUBDEV_FORMAT_TRY)
++ cfg->try_fmt = *mf;
++
++ return 0;
++}
++
++static int ov2311_enum_mbus_code(struct v4l2_subdev *sd,
++ struct v4l2_subdev_pad_config *cfg,
++ struct v4l2_subdev_mbus_code_enum *code)
++{
++ if (code->pad || code->index > 0)
++ return -EINVAL;
++
++ code->code = OV2311_MEDIA_BUS_FMT;
++
++ return 0;
++}
++
++static int ov2311_get_edid(struct v4l2_subdev *sd, struct v4l2_edid *edid)
++{
++ struct i2c_client *client = v4l2_get_subdevdata(sd);
++ struct ov2311_priv *priv = to_ov2311(client);
++
++ memcpy(edid->edid, priv->id, 6);
++
++ edid->edid[6] = 0xff;
++ edid->edid[7] = client->addr;
++ edid->edid[8] = OV2311_VERSION_REG >> 8;
++ edid->edid[9] = OV2311_VERSION_REG & 0xff;
++
++ return 0;
++}
++
++static int ov2311_set_selection(struct v4l2_subdev *sd,
++ struct v4l2_subdev_pad_config *cfg,
++ struct v4l2_subdev_selection *sel)
++{
++ struct v4l2_rect *rect = &sel->r;
++ struct i2c_client *client = v4l2_get_subdevdata(sd);
++ struct ov2311_priv *priv = to_ov2311(client);
++
++ if (sel->which != V4L2_SUBDEV_FORMAT_ACTIVE ||
++ sel->target != V4L2_SEL_TGT_CROP)
++ return -EINVAL;
++
++ rect->left = ALIGN(rect->left, 2);
++ rect->top = ALIGN(rect->top, 2);
++ rect->width = ALIGN(rect->width, 2);
++ rect->height = ALIGN(rect->height, 2);
++
++ if ((rect->left + rect->width > OV2311_MAX_WIDTH) ||
++ (rect->top + rect->height > OV2311_MAX_HEIGHT))
++ *rect = priv->rect;
++
++ priv->rect.left = rect->left;
++ priv->rect.top = rect->top;
++ priv->rect.width = rect->width;
++ priv->rect.height = rect->height;
++
++ ov2311_set_window(sd);
++
++ return 0;
++}
++
++static int ov2311_get_selection(struct v4l2_subdev *sd,
++ struct v4l2_subdev_pad_config *cfg,
++ struct v4l2_subdev_selection *sel)
++{
++ struct i2c_client *client = v4l2_get_subdevdata(sd);
++ struct ov2311_priv *priv = to_ov2311(client);
++
++ if (sel->which != V4L2_SUBDEV_FORMAT_ACTIVE)
++ return -EINVAL;
++
++ switch (sel->target) {
++ case V4L2_SEL_TGT_CROP_BOUNDS:
++ sel->r.left = 0;
++ sel->r.top = 0;
++ sel->r.width = OV2311_MAX_WIDTH;
++ sel->r.height = OV2311_MAX_HEIGHT;
++ return 0;
++ case V4L2_SEL_TGT_CROP_DEFAULT:
++ sel->r.left = 0;
++ sel->r.top = 0;
++ sel->r.width = OV2311_MAX_WIDTH;
++ sel->r.height = OV2311_MAX_HEIGHT;
++ return 0;
++ case V4L2_SEL_TGT_CROP:
++ sel->r = priv->rect;
++ return 0;
++ default:
++ return -EINVAL;
++ }
++}
++
++static int ov2311_g_mbus_config(struct v4l2_subdev *sd,
++ struct v4l2_mbus_config *cfg)
++{
++ cfg->flags = V4L2_MBUS_CSI2_1_LANE | V4L2_MBUS_CSI2_CHANNEL_0 |
++ V4L2_MBUS_CSI2_CONTINUOUS_CLOCK;
++ cfg->type = V4L2_MBUS_CSI2;
++
++ return 0;
++}
++
++#ifdef CONFIG_VIDEO_ADV_DEBUG
++static int ov2311_g_register(struct v4l2_subdev *sd,
++ struct v4l2_dbg_register *reg)
++{
++ struct i2c_client *client = v4l2_get_subdevdata(sd);
++ int ret;
++ u8 val = 0;
++
++ ret = reg16_read(client, (u16)reg->reg, &val);
++ if (ret < 0)
++ return ret;
++
++ reg->val = val;
++ reg->size = sizeof(u16);
++
++ return 0;
++}
++
++static int ov2311_s_register(struct v4l2_subdev *sd,
++ const struct v4l2_dbg_register *reg)
++{
++ struct i2c_client *client = v4l2_get_subdevdata(sd);
++
++ return reg16_write(client, (u16)reg->reg, (u8)reg->val);
++}
++#endif
++
++static struct v4l2_subdev_core_ops ov2311_core_ops = {
++#ifdef CONFIG_VIDEO_ADV_DEBUG
++ .g_register = ov2311_g_register,
++ .s_register = ov2311_s_register,
++#endif
++};
++
++static int ov2311_s_ctrl(struct v4l2_ctrl *ctrl)
++{
++ struct v4l2_subdev *sd = ov2311_to_sd(ctrl);
++ struct i2c_client *client = v4l2_get_subdevdata(sd);
++ struct ov2311_priv *priv = to_ov2311(client);
++ int ret = 0;
++ u8 val = 0;
++
++ if (!priv->init_complete)
++ return 0;
++
++ switch (ctrl->id) {
++ case V4L2_CID_BRIGHTNESS:
++ case V4L2_CID_CONTRAST:
++ case V4L2_CID_SATURATION:
++ case V4L2_CID_HUE:
++ case V4L2_CID_GAMMA:
++ break;
++ case V4L2_CID_GAIN:
++ reg16_write(client, 0x350A, ctrl->val / 0x3ff); // COARSE: 4.10 format
++ reg16_write(client, 0x350B, (ctrl->val % 0x3ff) >> 2); // FINE: 4.10 format
++ reg16_write(client, 0x350C, (ctrl->val % 0x3ff) << 6); // FINE: 4.10 format
++ break;
++ case V4L2_CID_ANALOGUE_GAIN:
++ reg16_write(client, 0x3508, ctrl->val / 0xf); // COARSE: 5.4 format
++ reg16_write(client, 0x3509, (ctrl->val % 0xf) << 4); // FINE: 5.4 format
++ break;
++ case V4L2_CID_EXPOSURE:
++ reg16_write(client, 0x3501, ctrl->val >> 8);
++ reg16_write(client, 0x3502, ctrl->val & 0xff);
++ break;
++ case V4L2_CID_HFLIP:
++ reg16_read(client, 0x3821, &val);
++ val &= ~0x04;
++ val |= (ctrl->val ? 0x04 : 0);
++ reg16_write(client, 0x3821, val);
++ break;
++ case V4L2_CID_VFLIP:
++ reg16_read(client, 0x3820, &val);
++ val &= ~0x44;
++ val |= (ctrl->val ? 0x44 : 0);
++ reg16_write(client, 0x3820, val);
++ break;
++ case V4L2_CID_MIN_BUFFERS_FOR_CAPTURE:
++ ret = 0;
++ break;
++ }
++
++ return ret;
++}
++
++static const struct v4l2_ctrl_ops ov2311_ctrl_ops = {
++ .s_ctrl = ov2311_s_ctrl,
++};
++
++static struct v4l2_subdev_video_ops ov2311_video_ops = {
++ .s_stream = ov2311_s_stream,
++ .g_mbus_config = ov2311_g_mbus_config,
++};
++
++static const struct v4l2_subdev_pad_ops ov2311_subdev_pad_ops = {
++ .get_edid = ov2311_get_edid,
++ .enum_mbus_code = ov2311_enum_mbus_code,
++ .get_selection = ov2311_get_selection,
++ .set_selection = ov2311_set_selection,
++ .get_fmt = ov2311_get_fmt,
++ .set_fmt = ov2311_set_fmt,
++};
++
++static struct v4l2_subdev_ops ov2311_subdev_ops = {
++ .core = &ov2311_core_ops,
++ .video = &ov2311_video_ops,
++ .pad = &ov2311_subdev_pad_ops,
++};
++
++static void ov2311_otp_id_read(struct i2c_client *client)
++{
++ struct ov2311_priv *priv = to_ov2311(client);
++ int i;
++
++ reg16_write(client, 0x100, 1);
++ reg16_write(client, 0x3d81, 1);
++ usleep_range(25000, 25500); /* wait 25 ms */
++
++ for (i = 0; i < 6; i++) {
++ /* first 6 bytes are equal on all ov2311 */
++ reg16_read(client, 0x7000 + i + 6, &priv->id[i]);
++ }
++
++ reg16_write(client, 0x100, 0);
++}
++
++static ssize_t ov2311_otp_id_show(struct device *dev,
++ struct device_attribute *attr, char *buf)
++{
++ struct v4l2_subdev *sd = i2c_get_clientdata(to_i2c_client(dev));
++ struct i2c_client *client = v4l2_get_subdevdata(sd);
++ struct ov2311_priv *priv = to_ov2311(client);
++
++ return snprintf(buf, 32, "%02x:%02x:%02x:%02x:%02x:%02x\n",
++ priv->id[0], priv->id[1], priv->id[2], priv->id[3], priv->id[4], priv->id[5]);
++}
++
++static DEVICE_ATTR(otp_id_ov2311, S_IRUGO, ov2311_otp_id_show, NULL);
++
++static int ov2311_initialize(struct i2c_client *client)
++{
++ struct ov2311_priv *priv = to_ov2311(client);
++ u16 pid;
++ u8 val = 0, rev = 0;
++ int ret = 0;
++ int tmp_addr = 0;
++
++ ov2311_s_port(client, 1);
++
++ /* check and show product ID and manufacturer ID */
++ reg16_read(client, OV2311_PID, &val);
++ pid = val;
++ reg16_read(client, OV2311_VER, &val);
++ pid = (pid << 8) | val;
++
++ if (pid != OV2311_VERSION_REG) {
++ dev_dbg(&client->dev, "Product ID error %x\n", pid);
++ ret = -ENODEV;
++ goto out;
++ }
++
++ tmp_addr = client->addr;
++ if (priv->ti9x4_addr) {
++ client->addr = priv->ti9x3_addr; /* Serializer I2C address */
++ reg8_write(client, 0x02, 0x13); /* MIPI 2-lanes */
++ }
++ client->addr = tmp_addr;
++
++ /* check revision */
++ reg16_read(client, OV2311_REV, &rev);
++ /* Read OTP IDs */
++ ov2311_otp_id_read(client);
++ /* Program wizard registers */
++ ov2311_set_regs(client, ov2311_regs_wizard_r1c, ARRAY_SIZE(ov2311_regs_wizard_r1c));
++
++ dev_info(&client->dev, "ov2311 PID %x (rev %x), res %dx%d, OTP_ID %02x:%02x:%02x:%02x:%02x:%02x\n",
++ pid, rev, OV2311_MAX_WIDTH, OV2311_MAX_HEIGHT, priv->id[0], priv->id[1], priv->id[2], priv->id[3], priv->id[4], priv->id[5]);
++out:
++ ov2311_s_port(client, 0);
++
++ return ret;
++}
++
++static int ov2311_parse_dt(struct device_node *np, struct ov2311_priv *priv)
++{
++ struct i2c_client *client = v4l2_get_subdevdata(&priv->sd);
++ int i;
++ struct device_node *endpoint = NULL, *rendpoint = NULL;
++ int tmp_addr = 0;
++
++ for (i = 0; ; i++) {
++ endpoint = of_graph_get_next_endpoint(np, endpoint);
++ if (!endpoint)
++ break;
++
++ of_node_put(endpoint);
++
++ of_property_read_u32(endpoint, "dvp-order", &priv->dvp_order);
++
++ rendpoint = of_parse_phandle(endpoint, "remote-endpoint", 0);
++ if (!rendpoint)
++ continue;
++
++ if (!of_property_read_u32(rendpoint, "max9271-addr", &priv->max9271_addr) &&
++ !of_property_read_u32(rendpoint->parent->parent, "reg", &priv->max9286_addr) &&
++ !kstrtouint(strrchr(rendpoint->full_name, '@') + 1, 0, &priv->port))
++ break;
++
++ if (!of_property_read_u32(rendpoint, "ti9x3-addr", &priv->ti9x3_addr) &&
++ !of_property_match_string(rendpoint->parent->parent, "compatible", "ti,ti9x4") &&
++ !of_property_read_u32(rendpoint->parent->parent, "reg", &priv->ti9x4_addr) &&
++ !kstrtouint(strrchr(rendpoint->full_name, '@') + 1, 0, &priv->port))
++ break;
++ }
++
++ if (!priv->max9286_addr && !priv->ti9x4_addr) {
++ dev_err(&client->dev, "deserializer does not present for OV2311\n");
++ return -EINVAL;
++ }
++
++ ov2311_s_port(client, 1);
++
++ /* setup I2C translator address */
++ tmp_addr = client->addr;
++ if (priv->max9286_addr) {
++ client->addr = priv->max9271_addr; /* Serializer I2C address */
++
++ reg8_write(client, 0x09, tmp_addr << 1); /* Sensor translated I2C address */
++ reg8_write(client, 0x0A, OV2311_I2C_ADDR << 1); /* Sensor native I2C address */
++ usleep_range(2000, 2500); /* wait 2ms */
++ };
++
++ if (priv->ti9x4_addr) {
++ client->addr = priv->ti9x4_addr; /* Deserializer I2C address */
++
++ reg8_write(client, 0x4c, (priv->port << 4) | (1 << priv->port)); /* Select RX port number */
++ usleep_range(2000, 2500); /* wait 2ms */
++ reg8_write(client, 0x65, tmp_addr << 1); /* Sensor translated I2C address */
++ reg8_write(client, 0x5d, OV2311_I2C_ADDR << 1); /* Sensor native I2C address */
++ }
++ client->addr = tmp_addr;
++
++ return 0;
++}
++
++static int ov2311_probe(struct i2c_client *client,
++ const struct i2c_device_id *did)
++{
++ struct ov2311_priv *priv;
++ struct v4l2_ctrl *ctrl;
++ int ret;
++
++ priv = devm_kzalloc(&client->dev, sizeof(*priv), GFP_KERNEL);
++ if (!priv)
++ return -ENOMEM;
++
++ v4l2_i2c_subdev_init(&priv->sd, client, &ov2311_subdev_ops);
++ priv->sd.flags = V4L2_SUBDEV_FL_HAS_DEVNODE;
++ priv->rect.left = 0;
++ priv->rect.top = 0;
++ priv->rect.width = OV2311_MAX_WIDTH;
++ priv->rect.height = OV2311_MAX_HEIGHT;
++ priv->fps_denominator = 30;
++
++ v4l2_ctrl_handler_init(&priv->hdl, 4);
++ v4l2_ctrl_new_std(&priv->hdl, &ov2311_ctrl_ops,
++ V4L2_CID_BRIGHTNESS, 0, 0xff, 1, 0x30);
++ v4l2_ctrl_new_std(&priv->hdl, &ov2311_ctrl_ops,
++ V4L2_CID_CONTRAST, 0, 4, 1, 2);
++ v4l2_ctrl_new_std(&priv->hdl, &ov2311_ctrl_ops,
++ V4L2_CID_SATURATION, 0, 0xff, 1, 0xff);
++ v4l2_ctrl_new_std(&priv->hdl, &ov2311_ctrl_ops,
++ V4L2_CID_HUE, 0, 255, 1, 0);
++ v4l2_ctrl_new_std(&priv->hdl, &ov2311_ctrl_ops,
++ V4L2_CID_GAMMA, 0, 0xffff, 1, 0x233);
++ v4l2_ctrl_new_std(&priv->hdl, &ov2311_ctrl_ops,
++ V4L2_CID_GAIN, 0, 0x3ff*4, 1, 0x3ff);
++ v4l2_ctrl_new_std(&priv->hdl, &ov2311_ctrl_ops,
++ V4L2_CID_ANALOGUE_GAIN, 0, 0xf*5, 1, 0xf);
++ v4l2_ctrl_new_std(&priv->hdl, &ov2311_ctrl_ops,
++ V4L2_CID_EXPOSURE, 0, 0x580, 1, 0x57c);
++ v4l2_ctrl_new_std(&priv->hdl, &ov2311_ctrl_ops,
++ V4L2_CID_HFLIP, 0, 1, 1, 0);
++ v4l2_ctrl_new_std(&priv->hdl, &ov2311_ctrl_ops,
++ V4L2_CID_VFLIP, 0, 1, 1, 0);
++ ctrl = v4l2_ctrl_new_std(&priv->hdl, &ov2311_ctrl_ops,
++ V4L2_CID_MIN_BUFFERS_FOR_CAPTURE, 1, 32, 1, 9);
++ if (ctrl)
++ ctrl->flags &= ~V4L2_CTRL_FLAG_READ_ONLY;
++ priv->sd.ctrl_handler = &priv->hdl;
++
++ ret = priv->hdl.error;
++ if (ret)
++ goto cleanup;
++
++ v4l2_ctrl_handler_setup(&priv->hdl);
++
++ priv->pad.flags = MEDIA_PAD_FL_SOURCE;
++ priv->sd.entity.flags |= MEDIA_ENT_F_CAM_SENSOR;
++ ret = media_entity_pads_init(&priv->sd.entity, 1, &priv->pad);
++ if (ret < 0)
++ goto cleanup;
++
++ ret = ov2311_parse_dt(client->dev.of_node, priv);
++ if (ret)
++ goto cleanup;
++
++ ret = ov2311_initialize(client);
++ if (ret < 0)
++ goto cleanup;
++
++ ret = v4l2_async_register_subdev(&priv->sd);
++ if (ret)
++ goto cleanup;
++
++ if (device_create_file(&client->dev, &dev_attr_otp_id_ov2311) != 0) {
++ dev_err(&client->dev, "sysfs otp_id entry creation failed\n");
++ goto cleanup;
++ }
++
++ priv->init_complete = 1;
++
++ return 0;
++
++cleanup:
++ media_entity_cleanup(&priv->sd.entity);
++ v4l2_ctrl_handler_free(&priv->hdl);
++ v4l2_device_unregister_subdev(&priv->sd);
++#ifdef CONFIG_SOC_CAMERA_OV2311
++ v4l_err(client, "failed to probe @ 0x%02x (%s)\n",
++ client->addr, client->adapter->name);
++#endif
++ return ret;
++}
++
++static int ov2311_remove(struct i2c_client *client)
++{
++ struct ov2311_priv *priv = i2c_get_clientdata(client);
++
++ device_remove_file(&client->dev, &dev_attr_otp_id_ov2311);
++ v4l2_async_unregister_subdev(&priv->sd);
++ media_entity_cleanup(&priv->sd.entity);
++ v4l2_ctrl_handler_free(&priv->hdl);
++ v4l2_device_unregister_subdev(&priv->sd);
++
++ return 0;
++}
++
++#ifdef CONFIG_SOC_CAMERA_OV2311
++static const struct i2c_device_id ov2311_id[] = {
++ { "ov2311", 0 },
++ { }
++};
++MODULE_DEVICE_TABLE(i2c, ov2311_id);
++
++static const struct of_device_id ov2311_of_ids[] = {
++ { .compatible = "ovti,ov2311", },
++ { }
++};
++MODULE_DEVICE_TABLE(of, ov2311_of_ids);
++
++static struct i2c_driver ov2311_i2c_driver = {
++ .driver = {
++ .name = "ov2311",
++ .of_match_table = ov2311_of_ids,
++ },
++ .probe = ov2311_probe,
++ .remove = ov2311_remove,
++ .id_table = ov2311_id,
++};
++
++module_i2c_driver(ov2311_i2c_driver);
++
++MODULE_DESCRIPTION("SoC Camera driver for OV2311");
++MODULE_AUTHOR("Vladimir Barinov");
++MODULE_LICENSE("GPL");
++#endif
+diff --git a/drivers/media/i2c/soc_camera/ov2311.h b/drivers/media/i2c/soc_camera/ov2311.h
+new file mode 100644
+index 0000000..3a56b0b
+--- /dev/null
++++ b/drivers/media/i2c/soc_camera/ov2311.h
+@@ -0,0 +1,217 @@
++/*
++ * OmniVision ov2311 sensor camera wizard 1600x130@30/GREY8/MIPI
++ *
++ * Copyright (C) 2015-2017 Cogent Embedded, Inc.
++ *
++ * This program is free software; you can redistribute it and/or modify it
++ * under the terms of the GNU General Public License as published by the
++ * Free Software Foundation; either version 2 of the License, or (at your
++ * option) any later version.
++ */
++
++//#define OV2311_DISPLAY_PATTERN
++//#define OV2311_FSIN_ENABLE
++
++#define OV2311_MAX_WIDTH 1600
++#define OV2311_MAX_HEIGHT 1300
++
++#define OV2311_DELAY 0xffff
++
++#define OV2311_SENSOR_WIDTH 1616
++#define OV2311_SENSOR_HEIGHT 1316
++
++#define OV2311_X_START ((OV2311_SENSOR_WIDTH - OV2311_MAX_WIDTH) / 2)
++#define OV2311_Y_START ((OV2311_SENSOR_HEIGHT - OV2311_MAX_HEIGHT) / 2)
++#define OV2311_X_END (OV2311_X_START + OV2311_MAX_WIDTH - 1)
++#define OV2311_Y_END (OV2311_Y_START + OV2311_MAX_HEIGHT - 1)
++
++struct ov2311_reg {
++ u16 reg;
++ u8 val;
++};
++
++/* R1600x1300 RAW10 MIPI 60fps */
++static const struct ov2311_reg ov2311_regs_wizard_r1c[] = {
++{0x0103, 0x01},
++{0x0100, 0x00},
++{0x010c, 0x02},
++{0x010b, 0x01},
++{0x0300, 0x01},
++{0x0302, 0x32},
++{0x0303, 0x00},
++{0x0304, 0x03},
++{0x0305, 0x02},
++{0x0306, 0x01},
++{0x030d, 0x5a},
++{0x030e, 0x04},
++{0x3001, 0x02},
++{0x3004, 0x00},
++{0x3005, 0x00},
++{0x3006, 0x0a},
++{0x3011, 0x0d},
++{0x3014, 0x04},
++{0x301c, 0xf0},
++{0x3020, 0x20},
++{0x302c, 0x00},
++{0x302d, 0x00},
++{0x302e, 0x00},
++{0x302f, 0x03},
++{0x3030, 0x10},
++{0x303f, 0x03},
++{0x3103, 0x00},
++{0x3106, 0x08},
++{0x31ff, 0x01},
++{0x3501, 0x05},
++{0x3502, 0x7c},
++{0x3506, 0x00},
++{0x3507, 0x00},
++{0x3620, 0x67},
++{0x3633, 0x78},
++{0x3662, 0x65},
++{0x3664, 0xb0},
++{0x3666, 0x70},
++{0x3670, 0x68},
++{0x3674, 0x10},
++{0x3675, 0x00},
++{0x367e, 0x90},
++{0x3680, 0x84},
++{0x36a2, 0x04},
++{0x36a3, 0x80},
++{0x36b0, 0x00},
++{0x3700, 0x35},
++{0x3704, 0x39},
++{0x370a, 0x50},
++{0x3712, 0x00},
++{0x3713, 0x02},
++{0x3778, 0x00},
++{0x379b, 0x01},
++{0x379c, 0x10},
++{0x3800, 0x00},
++{0x3801, 0x00},
++{0x3802, 0x00},
++{0x3803, 0x00},
++{0x3804, 0x06},
++{0x3805, 0x4f},
++{0x3806, 0x05},
++{0x3807, 0x23},
++{0x3808, OV2311_MAX_WIDTH >> 8},
++{0x3809, OV2311_MAX_WIDTH & 0xff},
++{0x380a, OV2311_MAX_HEIGHT >> 8},
++{0x380b, OV2311_MAX_HEIGHT & 0xff},
++{0x380c, 0x03},
++{0x380d, 0xa8},
++{0x380e, 0x05},
++{0x380f, 0x88},
++{0x3810, OV2311_X_START >> 8},
++{0x3811, OV2311_X_START & 0xff},
++{0x3812, OV2311_Y_START >> 8},
++{0x3813, OV2311_X_START & 0xff},
++{0x3814, 0x11},
++{0x3815, 0x11},
++{0x3816, 0x00},
++{0x3817, 0x01},
++{0x3818, 0x00},
++{0x3819, 0x05},
++{0x3820, 0x00},
++{0x3821, 0x00},
++{0x382b, 0x5a},
++{0x382c, 0x0a},
++{0x382d, 0xf8},
++{0x3881, 0x44},
++{0x3882, 0x02},
++{0x3883, 0x8c},
++{0x3885, 0x07},
++{0x389d, 0x03},
++{0x38a6, 0x00},
++{0x38a7, 0x01},
++{0x38b3, 0x07},
++{0x38b1, 0x00},
++{0x38e5, 0x02},
++{0x38e7, 0x00},
++{0x38e8, 0x00},
++{0x3910, 0xff},
++{0x3911, 0xff},
++{0x3912, 0x08},
++{0x3913, 0x00},
++{0x3914, 0x00},
++{0x3915, 0x00},
++{0x391c, 0x00},
++{0x3920, 0xff},
++{0x3921, 0x80},
++{0x3922, 0x00},
++{0x3923, 0x00},
++{0x3924, 0x05},
++{0x3925, 0x00},
++{0x3926, 0x00},
++{0x3927, 0x00},
++{0x3928, 0x1a},
++{0x392d, 0x03},
++{0x392e, 0xa8},
++{0x392f, 0x08},
++{0x4001, 0x00},
++{0x4003, 0x40},
++{0x4008, 0x04},
++{0x4009, 0x1b},
++{0x400c, 0x04},
++{0x400d, 0x1b},
++{0x4010, 0xf4},
++{0x4011, 0x00},
++{0x4016, 0x00},
++{0x4017, 0x04},
++{0x4042, 0x11},
++{0x4043, 0x70},
++{0x4045, 0x00},
++{0x4409, 0x5f},
++{0x4509, 0x00},
++{0x450b, 0x00},
++{0x4600, 0x00},
++{0x4601, 0xa0},
++{0x4708, 0x09},
++{0x470c, 0x81},
++{0x4710, 0x06},
++{0x4711, 0x00},
++{0x4800, 0x00},
++{0x481f, 0x30},
++{0x4837, 0x14},
++{0x4f00, 0x00},
++{0x4f07, 0x00},
++{0x4f08, 0x03},
++{0x4f09, 0x08},
++{0x4f0c, 0x05},
++{0x4f0d, 0xb4},
++{0x4f10, 0x00},
++{0x4f11, 0x00},
++{0x4f12, 0x07},
++{0x4f13, 0xe2},
++{0x5000, 0x9f},
++{0x5001, 0x20},
++{0x5026, 0x00},
++{0x5c00, 0x00},
++{0x5c01, 0x2c},
++{0x5c02, 0x00},
++{0x5c03, 0x7f},
++{0x5e00, 0x00},
++{0x5e01, 0x41},
++{0x38b1, 0x02},
++{0x3880, 0x00},
++
++#if 1 /* Y8 mode */
++{0x3016, 0xF1},
++{0x0100, 0x01},
++{0x4814, 0x6A}, //; dt_man en, both embed/image data type are 0x2A
++{0x3218, 0x32},
++{0x3216, 0x01},
++{0x3208, 0x04},
++{0x3D81, 0x01},
++{0x4605, 0x02},
++{0x4816, 0x0A},
++{0x3208, 0x14},
++{0x3662, 0x67}, //; [1] raw8
++{0x366F, 0x1A}, //; [6] MSB
++//{0x3674, 0x11}, //; [0] embed_en, add embed data before normal image
++{0x3674, 0x10}, //; [0] embed_dis, add embed data before normal image
++{0x3016, 0xF0},
++#endif
++
++{0x0100, 0x01},
++};
+--
+2.7.4
+
diff --git a/bsp/meta-rcar/meta-rcar-gen3-adas/recipes-kernel/linux/linux-renesas/0179-media-i2c-soc_camera-Fix-more-Bad-of_node_put-errors.patch b/bsp/meta-rcar/meta-rcar-gen3-adas/recipes-kernel/linux/linux-renesas/0179-media-i2c-soc_camera-Fix-more-Bad-of_node_put-errors.patch
new file mode 100644
index 00000000..b4d8f0f7
--- /dev/null
+++ b/bsp/meta-rcar/meta-rcar-gen3-adas/recipes-kernel/linux/linux-renesas/0179-media-i2c-soc_camera-Fix-more-Bad-of_node_put-errors.patch
@@ -0,0 +1,139 @@
+From 100251b8221f88cccb27ad3997a7010a77501a44 Mon Sep 17 00:00:00 2001
+From: Valentine Barshak <valentine.barshak@cogentembedded.com>
+Date: Mon, 17 Jun 2019 18:15:58 +0300
+Subject: [PATCH 5/5] media: i2c: soc_camera: Fix more "Bad of_node_put" errors
+
+This fixes "OF: ERROR: Bad of_node_put()" error and possible kernel crash
+when probing i2c soc_camera sensor devices in the recently added drivers.
+
+When CONFIG_OF_DYNAMIC is not enabled, the error message is not displayed,
+and everything seems to work fine. However, there's an error in the sensor
+parse_dt callbacks which causes inconsistent reference counter management.
+
+Move of_node_put() out of a loop scope to prevent bad of_node_put error.
+We don't need to call of_node_put() for every node since subsequent
+calls to of_graph_get_next_endpoint() decrement reference counter of
+the previous node. We only need to call of_node_put() for the last node.
+
+Signed-off-by: Valentine Barshak <valentine.barshak@cogentembedded.com>
+---
+ drivers/media/i2c/soc_camera/ar0323.c | 4 ++--
+ drivers/media/i2c/soc_camera/isx016.c | 4 ++--
+ drivers/media/i2c/soc_camera/isx019.c | 4 ++--
+ drivers/media/i2c/soc_camera/ov10640.c | 4 ++--
+ drivers/media/i2c/soc_camera/ov2311.c | 4 ++--
+ 5 files changed, 10 insertions(+), 10 deletions(-)
+
+diff --git a/drivers/media/i2c/soc_camera/ar0323.c b/drivers/media/i2c/soc_camera/ar0323.c
+index 2ee5526..2104d6a 100644
+--- a/drivers/media/i2c/soc_camera/ar0323.c
++++ b/drivers/media/i2c/soc_camera/ar0323.c
+@@ -425,8 +425,6 @@ static int ar0323_parse_dt(struct device_node *np, struct ar0323_priv *priv)
+ if (!endpoint)
+ break;
+
+- of_node_put(endpoint);
+-
+ rendpoint = of_parse_phandle(endpoint, "remote-endpoint", 0);
+ if (!rendpoint)
+ continue;
+@@ -438,6 +436,8 @@ static int ar0323_parse_dt(struct device_node *np, struct ar0323_priv *priv)
+ break;
+ }
+
++ of_node_put(endpoint);
++
+ if (!priv->ti9x4_addr) {
+ dev_err(&client->dev, "deserializer does not present\n");
+ return -EINVAL;
+diff --git a/drivers/media/i2c/soc_camera/isx016.c b/drivers/media/i2c/soc_camera/isx016.c
+index eab155c..ab85b7d 100644
+--- a/drivers/media/i2c/soc_camera/isx016.c
++++ b/drivers/media/i2c/soc_camera/isx016.c
+@@ -425,8 +425,6 @@ static int isx016_parse_dt(struct device_node *np, struct isx016_priv *priv)
+ if (!endpoint)
+ break;
+
+- of_node_put(endpoint);
+-
+ rendpoint = of_parse_phandle(endpoint, "remote-endpoint", 0);
+ if (!rendpoint)
+ continue;
+@@ -443,6 +441,8 @@ static int isx016_parse_dt(struct device_node *np, struct isx016_priv *priv)
+ break;
+ }
+
++ of_node_put(endpoint);
++
+ if (!priv->max9286_addr && !priv->ti9x4_addr) {
+ dev_err(&client->dev, "deserializer does not present for ISX016\n");
+ return -EINVAL;
+diff --git a/drivers/media/i2c/soc_camera/isx019.c b/drivers/media/i2c/soc_camera/isx019.c
+index c2f5a4a..188fd28 100644
+--- a/drivers/media/i2c/soc_camera/isx019.c
++++ b/drivers/media/i2c/soc_camera/isx019.c
+@@ -483,8 +483,6 @@ static int isx019_parse_dt(struct device_node *np, struct isx019_priv *priv)
+ if (!endpoint)
+ break;
+
+- of_node_put(endpoint);
+-
+ rendpoint = of_parse_phandle(endpoint, "remote-endpoint", 0);
+ if (!rendpoint)
+ continue;
+@@ -495,6 +493,8 @@ static int isx019_parse_dt(struct device_node *np, struct isx019_priv *priv)
+ break;
+ }
+
++ of_node_put(endpoint);
++
+ if (!priv->max9286_addr) {
+ dev_err(&client->dev, "deserializer does not present for ISX019\n");
+ return -EINVAL;
+diff --git a/drivers/media/i2c/soc_camera/ov10640.c b/drivers/media/i2c/soc_camera/ov10640.c
+index 8746988..31117e5 100644
+--- a/drivers/media/i2c/soc_camera/ov10640.c
++++ b/drivers/media/i2c/soc_camera/ov10640.c
+@@ -496,8 +496,6 @@ static int ov10640_parse_dt(struct device_node *np, struct ov10640_priv *priv)
+ if (!endpoint)
+ break;
+
+- of_node_put(endpoint);
+-
+ of_property_read_u32(endpoint, "dvp-order", &priv->dvp_order);
+
+ rendpoint = of_parse_phandle(endpoint, "remote-endpoint", 0);
+@@ -516,6 +514,8 @@ static int ov10640_parse_dt(struct device_node *np, struct ov10640_priv *priv)
+ break;
+ }
+
++ of_node_put(endpoint);
++
+ if (!priv->max9286_addr && !priv->ti9x4_addr) {
+ dev_err(&client->dev, "deserializer does not present for OV10640\n");
+ return -EINVAL;
+diff --git a/drivers/media/i2c/soc_camera/ov2311.c b/drivers/media/i2c/soc_camera/ov2311.c
+index 06e57dd..c8d260c 100644
+--- a/drivers/media/i2c/soc_camera/ov2311.c
++++ b/drivers/media/i2c/soc_camera/ov2311.c
+@@ -453,8 +453,6 @@ static int ov2311_parse_dt(struct device_node *np, struct ov2311_priv *priv)
+ if (!endpoint)
+ break;
+
+- of_node_put(endpoint);
+-
+ of_property_read_u32(endpoint, "dvp-order", &priv->dvp_order);
+
+ rendpoint = of_parse_phandle(endpoint, "remote-endpoint", 0);
+@@ -473,6 +471,8 @@ static int ov2311_parse_dt(struct device_node *np, struct ov2311_priv *priv)
+ break;
+ }
+
++ of_node_put(endpoint);
++
+ if (!priv->max9286_addr && !priv->ti9x4_addr) {
+ dev_err(&client->dev, "deserializer does not present for OV2311\n");
+ return -EINVAL;
+--
+2.7.4
+
diff --git a/bsp/meta-rcar/meta-rcar-gen3-adas/recipes-kernel/linux/linux-renesas/0180-media-i2c-ov490-add-LI-cameras.patch b/bsp/meta-rcar/meta-rcar-gen3-adas/recipes-kernel/linux/linux-renesas/0180-media-i2c-ov490-add-LI-cameras.patch
new file mode 100644
index 00000000..85389113
--- /dev/null
+++ b/bsp/meta-rcar/meta-rcar-gen3-adas/recipes-kernel/linux/linux-renesas/0180-media-i2c-ov490-add-LI-cameras.patch
@@ -0,0 +1,61 @@
+From 9611ea32f2db0150cc9d7e69110cb48df05af238 Mon Sep 17 00:00:00 2001
+From: Vladimir Barinov <vladimir.barinov@cogentembedded.com>
+Date: Fri, 28 Jun 2019 00:35:26 +0300
+Subject: [PATCH] media: i2c: ov490: add LI cameras
+
+This adds Leopard Imaging firmware support
+
+Signed-off-by: Vladimir Barinov <vladimir.barinov@cogentembedded.com>
+---
+ drivers/media/i2c/soc_camera/ov490_ov10640.c | 3 +++
+ drivers/media/i2c/soc_camera/ov490_ov10640.h | 10 +++++++++-
+ 2 files changed, 12 insertions(+), 1 deletion(-)
+
+diff --git a/drivers/media/i2c/soc_camera/ov490_ov10640.c b/drivers/media/i2c/soc_camera/ov490_ov10640.c
+index 0ea9a54..0f1a0d4 100644
+--- a/drivers/media/i2c/soc_camera/ov490_ov10640.c
++++ b/drivers/media/i2c/soc_camera/ov490_ov10640.c
+@@ -138,6 +138,9 @@ static int ov490_set_regs(struct i2c_client *client,
+ usleep_range(100, 150); /* wait 100 us */
+ reg16_write(client, regs[i].reg, regs[i].val);
+ }
++
++ if (regs[i].reg == 0xFFFE)
++ usleep_range(100, 150); /* wait 100 us */
+ }
+
+ return 0;
+diff --git a/drivers/media/i2c/soc_camera/ov490_ov10640.h b/drivers/media/i2c/soc_camera/ov490_ov10640.h
+index b22e93e..b00dc3ade 100644
+--- a/drivers/media/i2c/soc_camera/ov490_ov10640.h
++++ b/drivers/media/i2c/soc_camera/ov490_ov10640.h
+@@ -17,6 +17,12 @@ struct ov490_reg {
+ };
+
+ static const struct ov490_reg ov490_regs_wizard[] = {
++/* Firmware start (some firmwares need this to kick processing) */
++{0xfffd, 0x80},
++{0xfffe, 0x19},
++{0x5000, 0x05},
++{0xfffe, 0x80},
++{0x00c0, 0x3f},
+ /* The following registers should match firmware */
+ {0xfffd, 0x80},
+ {0xfffe, 0x82},
+@@ -93,10 +99,12 @@ static const struct ov490_reg ov490_regs_wizard[] = {
+ {0xfffe, 0x80},
+ {0x00c0, 0xdc},
+ #ifdef OV490_DISPLAY_PATTERN
+-{0xfffd, 0x80},
+ {0xfffe, 0x19},
+ {0x5000, 0x02},
+ {0xfffe, 0x80},
+ {0x00c0, 0xd6},
+ #endif
++/* respin register 0x6010 due to added firmware start HOST command */
++{0xfffe, 0x29},
++{0x6010, 0x01},
+ };
+--
+2.7.4
+
diff --git a/bsp/meta-rcar/meta-rcar-gen3-adas/recipes-kernel/linux/linux-renesas/0181-ARM64-dts-Remove-conflicting-with-mainline-V3M-and-V.patch b/bsp/meta-rcar/meta-rcar-gen3-adas/recipes-kernel/linux/linux-renesas/0181-ARM64-dts-Remove-conflicting-with-mainline-V3M-and-V.patch
new file mode 100644
index 00000000..d5862978
--- /dev/null
+++ b/bsp/meta-rcar/meta-rcar-gen3-adas/recipes-kernel/linux/linux-renesas/0181-ARM64-dts-Remove-conflicting-with-mainline-V3M-and-V.patch
@@ -0,0 +1,635 @@
+From 9f7a9e36a59ee22644202e590117f780ed58110e Mon Sep 17 00:00:00 2001
+From: Valentine Barshak <valentine.barshak@cogentembedded.com>
+Date: Tue, 4 Jun 2019 21:42:40 +0300
+Subject: [PATCH 001/211] ARM64: dts: Remove conflicting with mainline V3M and
+ V3H device tree parts
+
+This removes V3M and V3H device tree parts which conflict
+with the mainline renesas-devel-20190603-v5.2-rc3 tag.
+
+Signed-off-by: Valentine Barshak <valentine.barshak@cogentembedded.com>
+---
+ arch/arm64/boot/dts/renesas/Makefile | 10 -
+ arch/arm64/boot/dts/renesas/r8a77970-eagle.dts | 356 ------------------------
+ arch/arm64/boot/dts/renesas/r8a77970-v3msk.dts | 71 -----
+ arch/arm64/boot/dts/renesas/r8a77980-condor.dts | 40 ---
+ arch/arm64/boot/dts/renesas/r8a77980-v3hsk.dts | 41 ---
+ 5 files changed, 518 deletions(-)
+
+diff --git a/arch/arm64/boot/dts/renesas/Makefile b/arch/arm64/boot/dts/renesas/Makefile
+index f7f8638..294d38a 100644
+--- a/arch/arm64/boot/dts/renesas/Makefile
++++ b/arch/arm64/boot/dts/renesas/Makefile
+@@ -33,15 +33,5 @@ dtb-$(CONFIG_ARCH_R8A7795) += r8a7795-h3ulcb-vb2.dtb r8a7795-es1-h3ulcb-vb2.dtb
+ dtb-$(CONFIG_ARCH_R8A7795) += r8a7795-h3ulcb-vb2.1.dtb r8a7795-h3ulcb-4x2g-vb2.1.dtb
+ dtb-$(CONFIG_ARCH_R8A7795) += r8a7795-h3ulcb-vbm.dtb r8a7795-es1-h3ulcb-vbm.dtb r8a7795-h3ulcb-4x2g-vbm.dtb
+ dtb-$(CONFIG_ARCH_R8A77965) += r8a77965-m3nulcb-kf.dtb
+-#dtb-$(CONFIG_ARCH_R8A77970) += r8a77970-eagle-function.dtb
+-#dtb-$(CONFIG_ARCH_R8A77970) += r8a77970-es1-eagle.dtb r8a77970-es1-eagle-function.dtb
+-#dtb-$(CONFIG_ARCH_R8A77970) += r8a77970-es1-v3msk.dtb
+-#dtb-$(CONFIG_ARCH_R8A77970) += r8a77970-v3msk-view.dtb r8a77970-es1-v3msk-view.dtb
+-#dtb-$(CONFIG_ARCH_R8A77970) += r8a77970-v3msk-kf.dtb r8a77970-es1-v3msk-kf.dtb
+-#dtb-$(CONFIG_ARCH_R8A77970) += r8a77970-v3msk-vbm.dtb r8a77970-es1-v3msk-vbm.dtb
+-#dtb-$(CONFIG_ARCH_R8A77970) += r8a77970-v3msk-vbm-v2.dtb r8a77970-es1-v3msk-vbm-v2.dtb
+-#dtb-$(CONFIG_ARCH_R8A77970) += r8a77970-v3mzf.dtb
+-#dtb-$(CONFIG_ARCH_R8A77980) += r8a77980-v3hsk-vbm.dtb
+-#dtb-$(CONFIG_ARCH_R8A77980) += r8a77980-v3hsk-vbm-v2.dtb
+
+ always := $(dtb-y)
+diff --git a/arch/arm64/boot/dts/renesas/r8a77970-eagle.dts b/arch/arm64/boot/dts/renesas/r8a77970-eagle.dts
+index 6338ab3..b6d5332 100644
+--- a/arch/arm64/boot/dts/renesas/r8a77970-eagle.dts
++++ b/arch/arm64/boot/dts/renesas/r8a77970-eagle.dts
+@@ -8,7 +8,6 @@
+
+ /dts-v1/;
+ #include "r8a77970.dtsi"
+-#include <dt-bindings/gpio/gpio.h>
+
+ / {
+ model = "Renesas Eagle board based on r8a77970";
+@@ -30,58 +29,6 @@
+ reg = <0x0 0x48000000 0x0 0x38000000>;
+ };
+
+- reserved-memory {
+- #address-cells = <2>;
+- #size-cells = <2>;
+- ranges;
+-
+- /* device specific region for Lossy Decompression */
+- lossy_decompress: linux,lossy_decompress {
+- no-map;
+- reg = <0x00000000 0x6c000000 0x0 0x03000000>;
+- };
+-
+- /* global autoconfigured region for contiguous allocations */
+- linux,cma {
+- compatible = "shared-dma-pool";
+- reusable;
+- reg = <0x00000000 0x6f000000 0x0 0x10000000>;
+- linux,cma-default;
+- };
+-
+- /* device specific region for contiguous allocations */
+- linux,multimedia {
+- compatible = "shared-dma-pool";
+- reusable;
+- reg = <0x00000000 0x7f000000 0x0 0x01000000>;
+- };
+- };
+-
+- mmngr {
+- compatible = "renesas,mmngr";
+- memory-region = <&lossy_decompress>;
+- };
+-
+- mmngrbuf {
+- compatible = "renesas,mmngrbuf";
+- };
+-
+- vspm_if {
+- compatible = "renesas,vspm_if";
+- };
+-
+- dclkin_p0: clock-out0 {
+- compatible = "fixed-clock";
+- #clock-cells = <0>;
+- clock-frequency = <148500000>;
+- };
+-
+- msiof_ref_clk: msiof-ref-clock {
+- compatible = "fixed-clock";
+- #clock-cells = <0>;
+- clock-frequency = <66666666>;
+- };
+-
+ hdmi-out {
+ compatible = "hdmi-connector";
+ type = "a";
+@@ -155,40 +102,6 @@
+ };
+ };
+
+-&csi40 {
+- status = "okay";
+-
+- virtual,channel {
+- csi2_vc0 {
+- data,type = "ycbcr422";
+- receive,vc = <0>;
+- };
+- csi2_vc1 {
+- data,type = "ycbcr422";
+- receive,vc = <1>;
+- };
+- csi2_vc2 {
+- data,type = "ycbcr422";
+- receive,vc = <2>;
+- };
+- csi2_vc3 {
+- data,type = "ycbcr422";
+- receive,vc = <3>;
+- };
+- };
+-
+- port {
+- #address-cells = <1>;
+- #size-cells = <0>;
+-
+- csi2_40_ep: endpoint {
+- clock-lanes = <0>;
+- data-lanes = <1 2 3 4>;
+- csi-rate = <300>;
+- };
+- };
+-};
+-
+ &extal_clk {
+ clock-frequency = <16666666>;
+ };
+@@ -242,158 +155,6 @@
+ };
+ };
+ };
+-
+- pmic@5A {
+- compatible = "dlg,da9063";
+- reg = <0x5A>;
+- interrupt-parent = <&intc_ex>;
+- interrupts = <0 IRQ_TYPE_LEVEL_LOW>;
+- interrupt-controller;
+-
+- rtc {
+- compatible = "dlg,da9063-rtc";
+- };
+-
+- wdt {
+- compatible = "dlg,da9063-watchdog";
+- };
+-
+- regulators {
+- DA9063_LDO11: bmem {
+- regulator-name = "bmem";
+- regulator-min-microvolt = <3300000>;
+- regulator-max-microvolt = <3300000>;
+- regulator-always-on;
+- regulator-boot-on;
+- };
+- };
+-
+- onkey {
+- compatible = "dlg,da9063-onkey";
+- };
+- };
+-};
+-
+-&i2c3 {
+- pinctrl-0 = <&i2c3_pins>;
+- pinctrl-names = "default";
+-
+- status = "okay";
+- clock-frequency = <400000>;
+-
+- ov106xx@0 {
+- compatible = "ovti,ov106xx";
+- reg = <0x60>;
+-
+- port@0 {
+- ov106xx_in0: endpoint {
+- clock-lanes = <0>;
+- data-lanes = <1 2 3 4>;
+- remote-endpoint = <&vin0ep0>;
+- };
+- };
+- port@1 {
+- ov106xx_max9286_des0ep0: endpoint@0 {
+- remote-endpoint = <&max9286_des0ep0>;
+- };
+- };
+- };
+-
+- ov106xx@1 {
+- compatible = "ovti,ov106xx";
+- reg = <0x61>;
+-
+- port@0 {
+- ov106xx_in1: endpoint {
+- clock-lanes = <0>;
+- data-lanes = <1 2 3 4>;
+- remote-endpoint = <&vin1ep0>;
+- };
+- };
+- port@1 {
+- ov106xx_max9286_des0ep1: endpoint@0 {
+- remote-endpoint = <&max9286_des0ep1>;
+- };
+- };
+- };
+-
+- ov106xx@2 {
+- compatible = "ovti,ov106xx";
+- reg = <0x62>;
+-
+- port@0 {
+- ov106xx_in2: endpoint {
+- clock-lanes = <0>;
+- data-lanes = <1 2 3 4>;
+- remote-endpoint = <&vin2ep0>;
+- };
+- };
+- port@1 {
+- ov106xx_max9286_des0ep2: endpoint@0 {
+- remote-endpoint = <&max9286_des0ep2>;
+- };
+- };
+- };
+-
+- ov106xx@3 {
+- compatible = "ovti,ov106xx";
+- reg = <0x63>;
+-
+- port@0 {
+- ov106xx_in3: endpoint {
+- clock-lanes = <0>;
+- data-lanes = <1 2 3 4>;
+- remote-endpoint = <&vin3ep0>;
+- };
+- };
+- port@1 {
+- ov106xx_des0ep3: endpoint {
+- remote-endpoint = <&max9286_des0ep3>;
+- };
+- };
+- };
+-
+- max9286@0 {
+- compatible = "maxim,max9286";
+- reg = <0x48>;
+- gpios = <&io_expander 0 GPIO_ACTIVE_LOW>; /* CSI0 DE_PDn */
+- maxim,gpio0 = <0>;
+- maxim,sensor_delay = <100>;
+- maxim,links = <4>;
+- maxim,lanes = <4>;
+- maxim,resetb-gpio = <1>;
+- maxim,fsync-mode = "automatic";
+- maxim,timeout = <100>;
+-
+- port@0 {
+- max9286_des0ep0: endpoint@0 {
+- max9271-addr = <0x50>;
+- dvp-order = <1>;
+- remote-endpoint = <&ov106xx_in0>;
+- };
+- max9286_des0ep1: endpoint@1 {
+- max9271-addr = <0x51>;
+- dvp-order = <1>;
+- remote-endpoint = <&ov106xx_in1>;
+- };
+- max9286_des0ep2: endpoint@2 {
+- max9271-addr = <0x52>;
+- dvp-order = <1>;
+- remote-endpoint = <&ov106xx_in2>;
+- };
+- max9286_des0ep3: endpoint@3 {
+- max9271-addr = <0x53>;
+- dvp-order = <1>;
+- remote-endpoint = <&ov106xx_in3>;
+- };
+- };
+- port@1 {
+- max9286_csi0ep0: endpoint {
+- csi-rate = <700>;
+- remote-endpoint = <&csi2_40_ep>;
+- };
+- };
+- };
+ };
+
+ &pfc {
+@@ -412,11 +173,6 @@
+ function = "i2c0";
+ };
+
+- i2c3_pins: i2c3 {
+- groups = "i2c3";
+- function = "i2c3";
+- };
+-
+ scif0_pins: scif0 {
+ groups = "scif0_data";
+ function = "scif0";
+@@ -435,118 +191,6 @@
+ status = "okay";
+ };
+
+-&vin0 {
+- status = "okay";
+-
+- ports {
+- #address-cells = <1>;
+- #size-cells = <0>;
+-
+- port@0 {
+- vin0ep0: endpoint {
+- csi,select = "csi40";
+- virtual,channel = <0>;
+- data-lanes = <1 2 3 4>;
+- remote-endpoint = <&ov106xx_in0>;
+- };
+- };
+- port@1 {
+- csi0ep0: endpoint {
+- remote-endpoint = <&csi2_40_ep>;
+- };
+- };
+- port@2 {
+- vin0_max9286_des0ep0: endpoint@0 {
+- remote-endpoint = <&max9286_des0ep0>;
+- };
+- };
+- };
+-};
+-
+-&vin1 {
+- status = "okay";
+-
+- ports {
+- #address-cells = <1>;
+- #size-cells = <0>;
+-
+- port@0 {
+- vin1ep0: endpoint {
+- csi,select = "csi40";
+- virtual,channel = <1>;
+- data-lanes = <1 2 3 4>;
+- remote-endpoint = <&ov106xx_in1>;
+- };
+- };
+- port@1 {
+- csi0ep1: endpoint {
+- remote-endpoint = <&csi2_40_ep>;
+- };
+- };
+- port@2 {
+- vin1_max9286_des0ep1: endpoint@0 {
+- remote-endpoint = <&max9286_des0ep1>;
+- };
+- };
+- };
+-};
+-
+-&vin2 {
+- status = "okay";
+-
+- ports {
+- #address-cells = <1>;
+- #size-cells = <0>;
+-
+- port@0 {
+- vin2ep0: endpoint {
+- csi,select = "csi40";
+- virtual,channel = <2>;
+- data-lanes = <1 2 3 4>;
+- remote-endpoint = <&ov106xx_in2>;
+- };
+- };
+- port@1 {
+- csi0ep2: endpoint {
+- remote-endpoint = <&csi2_40_ep>;
+- };
+- };
+- port@2 {
+- vin2_max9286_des0ep2: endpoint@0 {
+- remote-endpoint = <&max9286_des0ep2>;
+- };
+- };
+- };
+-};
+-
+-&vin3 {
+- status = "okay";
+-
+- ports {
+- #address-cells = <1>;
+- #size-cells = <0>;
+-
+- port@0 {
+- vin3ep0: endpoint {
+- csi,select = "csi40";
+- virtual,channel = <3>;
+- data-lanes = <1 2 3 4>;
+- remote-endpoint = <&ov106xx_in3>;
+- };
+- };
+- port@1 {
+- csi0ep3: endpoint {
+- remote-endpoint = <&csi2_40_ep>;
+- };
+- };
+- port@2 {
+- vin3_max9286_des0ep3: endpoint@0 {
+- remote-endpoint = <&max9286_des0ep3>;
+- };
+- };
+- };
+-};
+-
+ &du {
+ status = "okay";
+ };
+diff --git a/arch/arm64/boot/dts/renesas/r8a77970-v3msk.dts b/arch/arm64/boot/dts/renesas/r8a77970-v3msk.dts
+index 2b614e4..8eac8ca 100644
+--- a/arch/arm64/boot/dts/renesas/r8a77970-v3msk.dts
++++ b/arch/arm64/boot/dts/renesas/r8a77970-v3msk.dts
+@@ -27,46 +27,6 @@
+ reg = <0x0 0x48000000 0x0 0x38000000>;
+ };
+
+- reserved-memory {
+- #address-cells = <2>;
+- #size-cells = <2>;
+- ranges;
+-
+- /* device specific region for Lossy Decompression */
+- lossy_decompress: linux,lossy_decompress {
+- no-map;
+- reg = <0x00000000 0x6c000000 0x0 0x03000000>;
+- };
+-
+- /* global autoconfigured region for contiguous allocations */
+- linux,cma {
+- compatible = "shared-dma-pool";
+- reusable;
+- reg = <0x00000000 0x6f000000 0x0 0x10000000>;
+- linux,cma-default;
+- };
+-
+- /* device specific region for contiguous allocations */
+- linux,multimedia {
+- compatible = "shared-dma-pool";
+- reusable;
+- reg = <0x00000000 0x7f000000 0x0 0x01000000>;
+- };
+- };
+-
+- mmngr {
+- compatible = "renesas,mmngr";
+- memory-region = <&lossy_decompress>;
+- };
+-
+- mmngrbuf {
+- compatible = "renesas,mmngrbuf";
+- };
+-
+- vspm_if {
+- compatible = "renesas,vspm_if";
+- };
+-
+ osc5_clk: osc5-clock {
+ compatible = "fixed-clock";
+ #clock-cells = <0>;
+@@ -218,37 +178,6 @@
+ };
+ };
+ };
+-
+- pmic@5A {
+- compatible = "dlg,da9063";
+- reg = <0x5A>;
+- interrupt-parent = <&intc_ex>;
+- interrupts = <0 IRQ_TYPE_LEVEL_LOW>;
+- interrupt-controller;
+-
+- rtc {
+- compatible = "dlg,da9063-rtc";
+- };
+-
+- wdt {
+- compatible = "dlg,da9063-watchdog";
+- };
+-
+- regulators {
+- DA9063_LDO11: bmem {
+- regulator-name = "bmem";
+- regulator-min-microvolt = <3300000>;
+- regulator-max-microvolt = <3300000>;
+- regulator-always-on;
+- regulator-boot-on;
+- };
+- };
+-
+- onkey {
+- compatible = "dlg,da9063-onkey";
+- };
+- };
+-
+ };
+
+ &lvds0 {
+diff --git a/arch/arm64/boot/dts/renesas/r8a77980-condor.dts b/arch/arm64/boot/dts/renesas/r8a77980-condor.dts
+index e270cc0..0b93a7d 100644
+--- a/arch/arm64/boot/dts/renesas/r8a77980-condor.dts
++++ b/arch/arm64/boot/dts/renesas/r8a77980-condor.dts
+@@ -28,46 +28,6 @@
+ reg = <0 0x48000000 0 0x78000000>;
+ };
+
+- reserved-memory {
+- #address-cells = <2>;
+- #size-cells = <2>;
+- ranges;
+-
+- /* device specific region for Lossy Decompression */
+- lossy_decompress: linux,lossy_decompress {
+- no-map;
+- reg = <0x00000000 0x6c000000 0x0 0x03000000>;
+- };
+-
+- /* global autoconfigured region for contiguous allocations */
+- linux,cma {
+- compatible = "shared-dma-pool";
+- reusable;
+- reg = <0x00000000 0x6f000000 0x0 0x10000000>;
+- linux,cma-default;
+- };
+-
+- /* device specific region for contiguous allocations */
+- linux,multimedia {
+- compatible = "shared-dma-pool";
+- reusable;
+- reg = <0x00000000 0x7f000000 0x0 0x01000000>;
+- };
+- };
+-
+- mmngr {
+- compatible = "renesas,mmngr";
+- memory-region = <&lossy_decompress>;
+- };
+-
+- mmngrbuf {
+- compatible = "renesas,mmngrbuf";
+- };
+-
+- vspm_if {
+- compatible = "renesas,vspm_if";
+- };
+-
+ d3_3v: regulator-0 {
+ compatible = "regulator-fixed";
+ regulator-name = "D3.3V";
+diff --git a/arch/arm64/boot/dts/renesas/r8a77980-v3hsk.dts b/arch/arm64/boot/dts/renesas/r8a77980-v3hsk.dts
+index dff7d02..c968099 100644
+--- a/arch/arm64/boot/dts/renesas/r8a77980-v3hsk.dts
++++ b/arch/arm64/boot/dts/renesas/r8a77980-v3hsk.dts
+@@ -26,47 +26,6 @@
+ /* first 128MB is reserved for secure area. */
+ reg = <0 0x48000000 0 0x78000000>;
+ };
+-
+- reserved-memory {
+- #address-cells = <2>;
+- #size-cells = <2>;
+- ranges;
+-
+- /* device specific region for Lossy Decompression */
+- lossy_decompress: linux,lossy_decompress {
+- no-map;
+- reg = <0x00000000 0x6c000000 0x0 0x03000000>;
+- };
+-
+- /* global autoconfigured region for contiguous allocations */
+- linux,cma {
+- compatible = "shared-dma-pool";
+- reusable;
+- reg = <0x00000000 0x6f000000 0x0 0x10000000>;
+- linux,cma-default;
+- };
+-
+- /* device specific region for contiguous allocations */
+- linux,multimedia {
+- compatible = "shared-dma-pool";
+- reusable;
+- reg = <0x00000000 0x7f000000 0x0 0x01000000>;
+- };
+- };
+-
+- mmngr {
+- compatible = "renesas,mmngr";
+- memory-region = <&lossy_decompress>;
+- };
+-
+- mmngrbuf {
+- compatible = "renesas,mmngrbuf";
+- };
+-
+- vspm_if {
+- compatible = "renesas,vspm_if";
+- };
+-
+ };
+
+ &extal_clk {
+--
+2.7.4
+
diff --git a/bsp/meta-rcar/meta-rcar-gen3-adas/recipes-kernel/linux/linux-renesas/0182-iommu-msm-Claim-bus-ops-on-probe.patch b/bsp/meta-rcar/meta-rcar-gen3-adas/recipes-kernel/linux/linux-renesas/0182-iommu-msm-Claim-bus-ops-on-probe.patch
new file mode 100644
index 00000000..5f2f7e29
--- /dev/null
+++ b/bsp/meta-rcar/meta-rcar-gen3-adas/recipes-kernel/linux/linux-renesas/0182-iommu-msm-Claim-bus-ops-on-probe.patch
@@ -0,0 +1,58 @@
+From feb15c008da506989868369195e3982ff8131fcd Mon Sep 17 00:00:00 2001
+From: Robin Murphy <robin.murphy@arm.com>
+Date: Tue, 9 Jan 2018 16:17:25 +0000
+Subject: [PATCH 002/211] iommu/msm: Claim bus ops on probe
+
+Since the MSM IOMMU driver now probes via DT exclusively rather than
+platform data, dependent masters should be deferred until the IOMMU
+itself is ready. Thus we can do away with the early initialisation
+hook to unconditionally claim the bus ops, and instead do that only
+once an IOMMU is actually probed. Furthermore, this should also make
+the driver safe for multiplatform kernels on non-MSM SoCs.
+
+Reviewed-by: Sricharan R <sricharan@codeaurora.org>
+Signed-off-by: Robin Murphy <robin.murphy@arm.com>
+Signed-off-by: Joerg Roedel <jroedel@suse.de>
+(cherry picked from commit 892d7aaddb24b0d3eaf05534ed29a264d3b52646)
+Signed-off-by: Valentine Barshak <valentine.barshak@cogentembedded.com>
+---
+ drivers/iommu/msm_iommu.c | 16 +++-------------
+ 1 file changed, 3 insertions(+), 13 deletions(-)
+
+diff --git a/drivers/iommu/msm_iommu.c b/drivers/iommu/msm_iommu.c
+index 92c8c83..350ed3d 100644
+--- a/drivers/iommu/msm_iommu.c
++++ b/drivers/iommu/msm_iommu.c
+@@ -817,6 +817,8 @@ static int msm_iommu_probe(struct platform_device *pdev)
+ goto fail;
+ }
+
++ bus_set_iommu(&platform_bus_type, &msm_iommu_ops);
++
+ pr_info("device mapped at %p, irq %d with %d ctx banks\n",
+ iommu->base, iommu->irq, iommu->ncb);
+
+@@ -869,19 +871,7 @@ static void __exit msm_iommu_driver_exit(void)
+ subsys_initcall(msm_iommu_driver_init);
+ module_exit(msm_iommu_driver_exit);
+
+-static int __init msm_iommu_init(void)
+-{
+- bus_set_iommu(&platform_bus_type, &msm_iommu_ops);
+- return 0;
+-}
+-
+-static int __init msm_iommu_of_setup(struct device_node *np)
+-{
+- msm_iommu_init();
+- return 0;
+-}
+-
+-IOMMU_OF_DECLARE(msm_iommu_of, "qcom,apq8064-iommu", msm_iommu_of_setup);
++IOMMU_OF_DECLARE(msm_iommu_of, "qcom,apq8064-iommu", NULL);
+
+ MODULE_LICENSE("GPL v2");
+ MODULE_AUTHOR("Stepan Moskovchenko <stepanm@codeaurora.org>");
+--
+2.7.4
+
diff --git a/bsp/meta-rcar/meta-rcar-gen3-adas/recipes-kernel/linux/linux-renesas/0183-iommu-Clean-up-of_iommu_init_fn.patch b/bsp/meta-rcar/meta-rcar-gen3-adas/recipes-kernel/linux/linux-renesas/0183-iommu-Clean-up-of_iommu_init_fn.patch
new file mode 100644
index 00000000..9afb101f
--- /dev/null
+++ b/bsp/meta-rcar/meta-rcar-gen3-adas/recipes-kernel/linux/linux-renesas/0183-iommu-Clean-up-of_iommu_init_fn.patch
@@ -0,0 +1,163 @@
+From 4badb868e01d346cd749536f8059d0972d3e258f Mon Sep 17 00:00:00 2001
+From: Robin Murphy <robin.murphy@arm.com>
+Date: Tue, 9 Jan 2018 16:17:27 +0000
+Subject: [PATCH 003/211] iommu: Clean up of_iommu_init_fn
+
+Now that no more drivers rely on arbitrary early initialisation via an
+of_iommu_init_fn hook, let's clean up the redundant remnants. The
+IOMMU_OF_DECLARE() macro needs to remain for now, as the probe-deferral
+mechanism has no other nice way to detect built-in drivers before they
+have registered themselves, such that it can make the right decision.
+
+Reviewed-by: Sricharan R <sricharan@codeaurora.org>
+Signed-off-by: Robin Murphy <robin.murphy@arm.com>
+Signed-off-by: Joerg Roedel <jroedel@suse.de>
+(cherry picked from commit b0c560f7d8a4b333bcc18f692d0af0d5cca90fe2)
+[valentine.barshak: resolved minor conflicts]
+Signed-off-by: Valentine Barshak <valentine.barshak@cogentembedded.com>
+---
+ drivers/iommu/arm-smmu-v3.c | 2 +-
+ drivers/iommu/arm-smmu.c | 12 ++++++------
+ drivers/iommu/exynos-iommu.c | 2 +-
+ drivers/iommu/ipmmu-vmsa.c | 10 +++++-----
+ drivers/iommu/msm_iommu.c | 2 +-
+ drivers/iommu/of_iommu.c | 16 ----------------
+ drivers/iommu/qcom_iommu.c | 2 +-
+ include/linux/of_iommu.h | 5 +----
+ 8 files changed, 16 insertions(+), 35 deletions(-)
+
+diff --git a/drivers/iommu/arm-smmu-v3.c b/drivers/iommu/arm-smmu-v3.c
+index 3d5851e..fb4e621 100644
+--- a/drivers/iommu/arm-smmu-v3.c
++++ b/drivers/iommu/arm-smmu-v3.c
+@@ -2898,7 +2898,7 @@ static struct platform_driver arm_smmu_driver = {
+ };
+ module_platform_driver(arm_smmu_driver);
+
+-IOMMU_OF_DECLARE(arm_smmuv3, "arm,smmu-v3", NULL);
++IOMMU_OF_DECLARE(arm_smmuv3, "arm,smmu-v3");
+
+ MODULE_DESCRIPTION("IOMMU API for ARM architected SMMUv3 implementations");
+ MODULE_AUTHOR("Will Deacon <will.deacon@arm.com>");
+diff --git a/drivers/iommu/arm-smmu.c b/drivers/iommu/arm-smmu.c
+index 335bcc1..21a0eb3 100644
+--- a/drivers/iommu/arm-smmu.c
++++ b/drivers/iommu/arm-smmu.c
+@@ -2222,12 +2222,12 @@ static struct platform_driver arm_smmu_driver = {
+ };
+ module_platform_driver(arm_smmu_driver);
+
+-IOMMU_OF_DECLARE(arm_smmuv1, "arm,smmu-v1", NULL);
+-IOMMU_OF_DECLARE(arm_smmuv2, "arm,smmu-v2", NULL);
+-IOMMU_OF_DECLARE(arm_mmu400, "arm,mmu-400", NULL);
+-IOMMU_OF_DECLARE(arm_mmu401, "arm,mmu-401", NULL);
+-IOMMU_OF_DECLARE(arm_mmu500, "arm,mmu-500", NULL);
+-IOMMU_OF_DECLARE(cavium_smmuv2, "cavium,smmu-v2", NULL);
++IOMMU_OF_DECLARE(arm_smmuv1, "arm,smmu-v1");
++IOMMU_OF_DECLARE(arm_smmuv2, "arm,smmu-v2");
++IOMMU_OF_DECLARE(arm_mmu400, "arm,mmu-400");
++IOMMU_OF_DECLARE(arm_mmu401, "arm,mmu-401");
++IOMMU_OF_DECLARE(arm_mmu500, "arm,mmu-500");
++IOMMU_OF_DECLARE(cavium_smmuv2, "cavium,smmu-v2");
+
+ MODULE_DESCRIPTION("IOMMU API for ARM architected SMMU implementations");
+ MODULE_AUTHOR("Will Deacon <will.deacon@arm.com>");
+diff --git a/drivers/iommu/exynos-iommu.c b/drivers/iommu/exynos-iommu.c
+index 13485a4..1fcb618 100644
+--- a/drivers/iommu/exynos-iommu.c
++++ b/drivers/iommu/exynos-iommu.c
+@@ -1392,4 +1392,4 @@ static int __init exynos_iommu_init(void)
+ }
+ core_initcall(exynos_iommu_init);
+
+-IOMMU_OF_DECLARE(exynos_iommu_of, "samsung,exynos-sysmmu", NULL);
++IOMMU_OF_DECLARE(exynos_iommu_of, "samsung,exynos-sysmmu");
+diff --git a/drivers/iommu/ipmmu-vmsa.c b/drivers/iommu/ipmmu-vmsa.c
+index e1aabb7..8b4e5d9 100644
+--- a/drivers/iommu/ipmmu-vmsa.c
++++ b/drivers/iommu/ipmmu-vmsa.c
+@@ -1853,11 +1853,11 @@ static void __exit ipmmu_exit(void)
+ subsys_initcall(ipmmu_init);
+ module_exit(ipmmu_exit);
+
+-IOMMU_OF_DECLARE(ipmmu_vmsa_iommu_of, "renesas,ipmmu-vmsa", NULL);
+-IOMMU_OF_DECLARE(ipmmu_r8a7795_iommu_of, "renesas,ipmmu-r8a7795", NULL);
+-IOMMU_OF_DECLARE(ipmmu_r8a7796_iommu_of, "renesas,ipmmu-r8a7796", NULL);
+-IOMMU_OF_DECLARE(ipmmu_r8a77965_iommu_of, "renesas,ipmmu-r8a77965", NULL);
+-IOMMU_OF_DECLARE(ipmmu_r8a77990_iommu_of, "renesas,ipmmu-r8a77990", NULL);
++IOMMU_OF_DECLARE(ipmmu_vmsa_iommu_of, "renesas,ipmmu-vmsa");
++IOMMU_OF_DECLARE(ipmmu_r8a7795_iommu_of, "renesas,ipmmu-r8a7795");
++IOMMU_OF_DECLARE(ipmmu_r8a7796_iommu_of, "renesas,ipmmu-r8a7796");
++IOMMU_OF_DECLARE(ipmmu_r8a77965_iommu_of, "renesas,ipmmu-r8a77965");
++IOMMU_OF_DECLARE(ipmmu_r8a77990_iommu_of, "renesas,ipmmu-r8a77990");
+
+ MODULE_DESCRIPTION("IOMMU API for Renesas VMSA-compatible IPMMU");
+ MODULE_AUTHOR("Laurent Pinchart <laurent.pinchart@ideasonboard.com>");
+diff --git a/drivers/iommu/msm_iommu.c b/drivers/iommu/msm_iommu.c
+index 350ed3d..9a95c9b 100644
+--- a/drivers/iommu/msm_iommu.c
++++ b/drivers/iommu/msm_iommu.c
+@@ -871,7 +871,7 @@ static void __exit msm_iommu_driver_exit(void)
+ subsys_initcall(msm_iommu_driver_init);
+ module_exit(msm_iommu_driver_exit);
+
+-IOMMU_OF_DECLARE(msm_iommu_of, "qcom,apq8064-iommu", NULL);
++IOMMU_OF_DECLARE(msm_iommu_of, "qcom,apq8064-iommu");
+
+ MODULE_LICENSE("GPL v2");
+ MODULE_AUTHOR("Stepan Moskovchenko <stepanm@codeaurora.org>");
+diff --git a/drivers/iommu/of_iommu.c b/drivers/iommu/of_iommu.c
+index 50947eb..5c36a8b 100644
+--- a/drivers/iommu/of_iommu.c
++++ b/drivers/iommu/of_iommu.c
+@@ -231,19 +231,3 @@ const struct iommu_ops *of_iommu_configure(struct device *dev,
+
+ return ops;
+ }
+-
+-static int __init of_iommu_init(void)
+-{
+- struct device_node *np;
+- const struct of_device_id *match, *matches = &__iommu_of_table;
+-
+- for_each_matching_node_and_match(np, matches, &match) {
+- const of_iommu_init_fn init_fn = match->data;
+-
+- if (init_fn && init_fn(np))
+- pr_err("Failed to initialise IOMMU %pOF\n", np);
+- }
+-
+- return 0;
+-}
+-postcore_initcall_sync(of_iommu_init);
+diff --git a/drivers/iommu/qcom_iommu.c b/drivers/iommu/qcom_iommu.c
+index c8a587d..37ecc49 100644
+--- a/drivers/iommu/qcom_iommu.c
++++ b/drivers/iommu/qcom_iommu.c
+@@ -924,7 +924,7 @@ static void __exit qcom_iommu_exit(void)
+ module_init(qcom_iommu_init);
+ module_exit(qcom_iommu_exit);
+
+-IOMMU_OF_DECLARE(qcom_iommu_dev, "qcom,msm-iommu-v1", NULL);
++IOMMU_OF_DECLARE(qcom_iommu_dev, "qcom,msm-iommu-v1");
+
+ MODULE_DESCRIPTION("IOMMU API for QCOM IOMMU v1 implementations");
+ MODULE_LICENSE("GPL v2");
+diff --git a/include/linux/of_iommu.h b/include/linux/of_iommu.h
+index cddfaff..4fa654e 100644
+--- a/include/linux/of_iommu.h
++++ b/include/linux/of_iommu.h
+@@ -34,9 +34,6 @@ static inline const struct iommu_ops *of_iommu_configure(struct device *dev,
+
+ extern struct of_device_id __iommu_of_table;
+
+-typedef int (*of_iommu_init_fn)(struct device_node *);
+-
+-#define IOMMU_OF_DECLARE(name, compat, fn) \
+- _OF_DECLARE(iommu, name, compat, fn, of_iommu_init_fn)
++#define IOMMU_OF_DECLARE(name, compat) OF_DECLARE_1(iommu, name, compat, NULL)
+
+ #endif /* __OF_IOMMU_H */
+--
+2.7.4
+
diff --git a/bsp/meta-rcar/meta-rcar-gen3-adas/recipes-kernel/linux/linux-renesas/0184-iommu-ipmmu-vmsa-Hook-up-r8a779-70-95-DT-matching-co.patch b/bsp/meta-rcar/meta-rcar-gen3-adas/recipes-kernel/linux/linux-renesas/0184-iommu-ipmmu-vmsa-Hook-up-r8a779-70-95-DT-matching-co.patch
new file mode 100644
index 00000000..31888216
--- /dev/null
+++ b/bsp/meta-rcar/meta-rcar-gen3-adas/recipes-kernel/linux/linux-renesas/0184-iommu-ipmmu-vmsa-Hook-up-r8a779-70-95-DT-matching-co.patch
@@ -0,0 +1,67 @@
+From 3f6395b17673c4fda770651c1d657457741ee65a Mon Sep 17 00:00:00 2001
+From: Simon Horman <horms+renesas@verge.net.au>
+Date: Thu, 14 Jun 2018 12:48:23 +0200
+Subject: [PATCH 004/211] iommu/ipmmu-vmsa: Hook up r8a779(70|95) DT matching
+ code
+
+Support the r8a77970 (R-Car V3M) and r8a77995 (R-Car D3) IPMMUs by sharing
+feature flags with r8a7795 (R-Car H3) and r8a7796 (R-Car M3-W). Also update
+IOMMU_OF_DECLARE to hook up the compat strings.
+
+Based on work for the r8a7796 by Magnus Damm
+
+[rebased on v4.17]
+Signed-off-by: Jacopo Mondi <jacopo+renesas@jmondi.org>
+Signed-off-by: Simon Horman <horms+renesas@verge.net.au>
+Reviewed-by: Geert Uytterhoeven <geert+renesas@glider.be>
+Signed-off-by: Joerg Roedel <jroedel@suse.de>
+(cherry picked from commit 3701c123e1c13cdf258e10b26df7ae4bef6a5a93)
+[valentine.barshak: resolved minor confilicts]
+Signed-off-by: Valentine Barshak <valentine.barshak@cogentembedded.com>
+---
+ drivers/iommu/ipmmu-vmsa.c | 10 ++++++++++
+ 1 file changed, 10 insertions(+)
+
+diff --git a/drivers/iommu/ipmmu-vmsa.c b/drivers/iommu/ipmmu-vmsa.c
+index 8b4e5d9..5844dc7 100644
+--- a/drivers/iommu/ipmmu-vmsa.c
++++ b/drivers/iommu/ipmmu-vmsa.c
+@@ -1122,7 +1122,9 @@ static const struct soc_device_attribute soc_rcar_gen3[] = {
+ { .soc_id = "r8a7795", },
+ { .soc_id = "r8a7796", },
+ { .soc_id = "r8a77965", },
++ { .soc_id = "r8a77970", },
+ { .soc_id = "r8a77990", },
++ { .soc_id = "r8a77995", },
+ { /* sentinel */ }
+ };
+
+@@ -1421,9 +1423,15 @@ static const struct of_device_id ipmmu_of_ids[] = {
+ .compatible = "renesas,ipmmu-r8a77965",
+ .data = &ipmmu_features_rcar_gen3,
+ }, {
++ .compatible = "renesas,ipmmu-r8a77970",
++ .data = &ipmmu_features_rcar_gen3,
++ }, {
+ .compatible = "renesas,ipmmu-r8a77990",
+ .data = &ipmmu_features_rcar_gen3,
+ }, {
++ .compatible = "renesas,ipmmu-r8a77995",
++ .data = &ipmmu_features_rcar_gen3,
++ }, {
+ /* Terminator */
+ },
+ };
+@@ -1857,7 +1865,9 @@ IOMMU_OF_DECLARE(ipmmu_vmsa_iommu_of, "renesas,ipmmu-vmsa");
+ IOMMU_OF_DECLARE(ipmmu_r8a7795_iommu_of, "renesas,ipmmu-r8a7795");
+ IOMMU_OF_DECLARE(ipmmu_r8a7796_iommu_of, "renesas,ipmmu-r8a7796");
+ IOMMU_OF_DECLARE(ipmmu_r8a77965_iommu_of, "renesas,ipmmu-r8a77965");
++IOMMU_OF_DECLARE(ipmmu_r8a77970_iommu_of, "renesas,ipmmu-r8a77970");
+ IOMMU_OF_DECLARE(ipmmu_r8a77990_iommu_of, "renesas,ipmmu-r8a77990");
++IOMMU_OF_DECLARE(ipmmu_r8a77995_iommu_of, "renesas,ipmmu-r8a77995");
+
+ MODULE_DESCRIPTION("IOMMU API for Renesas VMSA-compatible IPMMU");
+ MODULE_AUTHOR("Laurent Pinchart <laurent.pinchart@ideasonboard.com>");
+--
+2.7.4
+
diff --git a/bsp/meta-rcar/meta-rcar-gen3-adas/recipes-kernel/linux/linux-renesas/0185-dt-bindings-display-bridge-Document-THC63LVD1024-LVD.patch b/bsp/meta-rcar/meta-rcar-gen3-adas/recipes-kernel/linux/linux-renesas/0185-dt-bindings-display-bridge-Document-THC63LVD1024-LVD.patch
new file mode 100644
index 00000000..ddd19e33
--- /dev/null
+++ b/bsp/meta-rcar/meta-rcar-gen3-adas/recipes-kernel/linux/linux-renesas/0185-dt-bindings-display-bridge-Document-THC63LVD1024-LVD.patch
@@ -0,0 +1,96 @@
+From 339c404b36bb8461c63c36b4ade4c5cad9ac345d Mon Sep 17 00:00:00 2001
+From: Jacopo Mondi <jacopo+renesas@jmondi.org>
+Date: Wed, 18 Apr 2018 16:40:28 +0200
+Subject: [PATCH 005/211] dt-bindings: display: bridge: Document THC63LVD1024
+ LVDS decoder
+MIME-Version: 1.0
+Content-Type: text/plain; charset=UTF-8
+Content-Transfer-Encoding: 8bit
+
+Document Thine THC63LVD1024 LVDS decoder device tree bindings.
+
+Signed-off-by: Jacopo Mondi <jacopo+renesas@jmondi.org>
+Reviewed-by: Andrzej Hajda <a.hajda@samsung.com>
+Reviewed-by: Niklas Söderlund <niklas.soderlund+renesas@ragnatech.se>
+Reviewed-by: Laurent Pinchart <laurent.pinchart@ideasonboard.com>
+Reviewed-by: Rob Herring <robh@kernel.org>
+Reviewed-by: Vladimir Zapolskiy <vladimir_zapolskiy@mentor.com>
+Signed-off-by: Andrzej Hajda <a.hajda@samsung.com>
+Link: https://patchwork.freedesktop.org/patch/msgid/1524062429-325-2-git-send-email-jacopo+renesas@jmondi.org
+Link: https://patchwork.freedesktop.org/patch/msgid/1524062429-325-2-git-send-email-jacopo+renesas@jmondi.org
+(cherry picked from commit f2ce15c72ae8aae06ba22b23f90ccc7d5b5e087c)
+Signed-off-by: Valentine Barshak <valentine.barshak@cogentembedded.com>
+---
+ .../bindings/display/bridge/thine,thc63lvd1024.txt | 60 ++++++++++++++++++++++
+ 1 file changed, 60 insertions(+)
+ create mode 100644 Documentation/devicetree/bindings/display/bridge/thine,thc63lvd1024.txt
+
+diff --git a/Documentation/devicetree/bindings/display/bridge/thine,thc63lvd1024.txt b/Documentation/devicetree/bindings/display/bridge/thine,thc63lvd1024.txt
+new file mode 100644
+index 0000000..37f0c04
+--- /dev/null
++++ b/Documentation/devicetree/bindings/display/bridge/thine,thc63lvd1024.txt
+@@ -0,0 +1,60 @@
++Thine Electronics THC63LVD1024 LVDS decoder
++-------------------------------------------
++
++The THC63LVD1024 is a dual link LVDS receiver designed to convert LVDS streams
++to parallel data outputs. The chip supports single/dual input/output modes,
++handling up to two LVDS input streams and up to two digital CMOS/TTL outputs.
++
++Single or dual operation mode, output data mapping and DDR output modes are
++configured through input signals and the chip does not expose any control bus.
++
++Required properties:
++- compatible: Shall be "thine,thc63lvd1024"
++- vcc-supply: Power supply for TTL output, TTL CLOCKOUT signal, LVDS input,
++ PPL and digital circuitry
++
++Optional properties:
++- powerdown-gpios: Power down GPIO signal, pin name "/PDWN". Active low
++- oe-gpios: Output enable GPIO signal, pin name "OE". Active high
++
++The THC63LVD1024 video port connections are modeled according
++to OF graph bindings specified by Documentation/devicetree/bindings/graph.txt
++
++Required video port nodes:
++- port@0: First LVDS input port
++- port@2: First digital CMOS/TTL parallel output
++
++Optional video port nodes:
++- port@1: Second LVDS input port
++- port@3: Second digital CMOS/TTL parallel output
++
++Example:
++--------
++
++ thc63lvd1024: lvds-decoder {
++ compatible = "thine,thc63lvd1024";
++
++ vcc-supply = <&reg_lvds_vcc>;
++ powerdown-gpios = <&gpio4 15 GPIO_ACTIVE_LOW>;
++
++ ports {
++ #address-cells = <1>;
++ #size-cells = <0>;
++
++ port@0 {
++ reg = <0>;
++
++ lvds_dec_in_0: endpoint {
++ remote-endpoint = <&lvds_out>;
++ };
++ };
++
++ port@2{
++ reg = <2>;
++
++ lvds_dec_out_2: endpoint {
++ remote-endpoint = <&adv7511_in>;
++ };
++ };
++ };
++ };
+--
+2.7.4
+
diff --git a/bsp/meta-rcar/meta-rcar-gen3-adas/recipes-kernel/linux/linux-renesas/0186-gpio-rcar-document-R8A77980-bindings.patch b/bsp/meta-rcar/meta-rcar-gen3-adas/recipes-kernel/linux/linux-renesas/0186-gpio-rcar-document-R8A77980-bindings.patch
new file mode 100644
index 00000000..29276275
--- /dev/null
+++ b/bsp/meta-rcar/meta-rcar-gen3-adas/recipes-kernel/linux/linux-renesas/0186-gpio-rcar-document-R8A77980-bindings.patch
@@ -0,0 +1,32 @@
+From 47127037672bd4cafe38cc2984fb10b2edbfdb90 Mon Sep 17 00:00:00 2001
+From: Sergei Shtylyov <sergei.shtylyov@cogentembedded.com>
+Date: Fri, 1 Jun 2018 23:13:47 +0300
+Subject: [PATCH 006/211] gpio-rcar: document R8A77980 bindings
+
+Renesas R-Car V3H (R8A77980) SoC also has the R-Car gen3 compatible GPIO
+controllers, so document the SoC specific bindings.
+
+Signed-off-by: Sergei Shtylyov <sergei.shtylyov@cogentembedded.com>
+Reviewed-by: Geert Uytterhoeven <geert+renesas@glider.be>
+Signed-off-by: Linus Walleij <linus.walleij@linaro.org>
+(cherry picked from commit 29d43c22e480b150e00f1ac28a6653efca31cce4)
+Signed-off-by: Valentine Barshak <valentine.barshak@cogentembedded.com>
+---
+ Documentation/devicetree/bindings/gpio/renesas,gpio-rcar.txt | 1 +
+ 1 file changed, 1 insertion(+)
+
+diff --git a/Documentation/devicetree/bindings/gpio/renesas,gpio-rcar.txt b/Documentation/devicetree/bindings/gpio/renesas,gpio-rcar.txt
+index 378f132..cd5ccdc 100644
+--- a/Documentation/devicetree/bindings/gpio/renesas,gpio-rcar.txt
++++ b/Documentation/devicetree/bindings/gpio/renesas,gpio-rcar.txt
+@@ -17,6 +17,7 @@ Required Properties:
+ - "renesas,gpio-r8a7796": for R8A7796 (R-Car M3-W) compatible GPIO controller.
+ - "renesas,gpio-r8a77965": for R8A77965 (R-Car M3-N) compatible GPIO controller.
+ - "renesas,gpio-r8a77970": for R8A77970 (R-Car V3M) compatible GPIO controller.
++ - "renesas,gpio-r8a77980": for R8A77980 (R-Car V3H) compatible GPIO controller.
+ - "renesas,gpio-r8a77990": for R8A77990 (R-Car E3) compatible GPIO controller.
+ - "renesas,gpio-r8a77995": for R8A77995 (R-Car D3) compatible GPIO controller.
+ - "renesas,rcar-gen1-gpio": for a generic R-Car Gen1 GPIO controller.
+--
+2.7.4
+
diff --git a/bsp/meta-rcar/meta-rcar-gen3-adas/recipes-kernel/linux/linux-renesas/0187-arm64-dts-renesas-r8a77980-add-SMP-support.patch b/bsp/meta-rcar/meta-rcar-gen3-adas/recipes-kernel/linux/linux-renesas/0187-arm64-dts-renesas-r8a77980-add-SMP-support.patch
new file mode 100644
index 00000000..6a6e4b03
--- /dev/null
+++ b/bsp/meta-rcar/meta-rcar-gen3-adas/recipes-kernel/linux/linux-renesas/0187-arm64-dts-renesas-r8a77980-add-SMP-support.patch
@@ -0,0 +1,93 @@
+From e5c859035c3fd62ef27f14ec34a4dc0a2d736eff Mon Sep 17 00:00:00 2001
+From: Sergei Shtylyov <sergei.shtylyov@cogentembedded.com>
+Date: Thu, 17 May 2018 23:19:44 +0300
+Subject: [PATCH 007/211] arm64: dts: renesas: r8a77980: add SMP support
+
+Add the device nodes for 3 more Cortex-A53 CPU cores; adjust the interrupt
+delivery masks for the ARM GIC and Architectured Timer.
+
+Based on the original (and large) patch by Vladimir Barinov.
+
+Signed-off-by: Vladimir Barinov <vladimir.barinov@cogentembedded.com>
+Signed-off-by: Sergei Shtylyov <sergei.shtylyov@cogentembedded.com>
+Reviewed-by: Geert Uytterhoeven <geert+renesas@glider.be>
+[simon: corrected whitespace]
+Signed-off-by: Simon Horman <horms+renesas@verge.net.au>
+
+(cherry picked from commit 2ec1e4b4a815ee872fb29753f4872abf1a2e62a4)
+Signed-off-by: Valentine Barshak <valentine.barshak@cogentembedded.com>
+---
+ arch/arm64/boot/dts/renesas/r8a77980.dtsi | 40 +++++++++++++++++++++++++++----
+ 1 file changed, 35 insertions(+), 5 deletions(-)
+
+diff --git a/arch/arm64/boot/dts/renesas/r8a77980.dtsi b/arch/arm64/boot/dts/renesas/r8a77980.dtsi
+index 8ecda23..1920b86 100644
+--- a/arch/arm64/boot/dts/renesas/r8a77980.dtsi
++++ b/arch/arm64/boot/dts/renesas/r8a77980.dtsi
+@@ -30,6 +30,36 @@
+ enable-method = "psci";
+ };
+
++ a53_1: cpu@1 {
++ device_type = "cpu";
++ compatible = "arm,cortex-a53", "arm,armv8";
++ reg = <1>;
++ clocks = <&cpg CPG_CORE R8A77980_CLK_Z2>;
++ power-domains = <&sysc R8A77980_PD_CA53_CPU1>;
++ next-level-cache = <&L2_CA53>;
++ enable-method = "psci";
++ };
++
++ a53_2: cpu@2 {
++ device_type = "cpu";
++ compatible = "arm,cortex-a53", "arm,armv8";
++ reg = <2>;
++ clocks = <&cpg CPG_CORE R8A77980_CLK_Z2>;
++ power-domains = <&sysc R8A77980_PD_CA53_CPU2>;
++ next-level-cache = <&L2_CA53>;
++ enable-method = "psci";
++ };
++
++ a53_3: cpu@3 {
++ device_type = "cpu";
++ compatible = "arm,cortex-a53", "arm,armv8";
++ reg = <3>;
++ clocks = <&cpg CPG_CORE R8A77980_CLK_Z2>;
++ power-domains = <&sysc R8A77980_PD_CA53_CPU3>;
++ next-level-cache = <&L2_CA53>;
++ enable-method = "psci";
++ };
++
+ L2_CA53: cache-controller {
+ compatible = "cache";
+ power-domains = <&sysc R8A77980_PD_CA53_SCU>;
+@@ -471,7 +501,7 @@
+ <0x0 0xf1020000 0 0x20000>,
+ <0x0 0xf1040000 0 0x20000>,
+ <0x0 0xf1060000 0 0x20000>;
+- interrupts = <GIC_PPI 9 (GIC_CPU_MASK_SIMPLE(1) |
++ interrupts = <GIC_PPI 9 (GIC_CPU_MASK_SIMPLE(4) |
+ IRQ_TYPE_LEVEL_HIGH)>;
+ clocks = <&cpg CPG_MOD 408>;
+ clock-names = "clk";
+@@ -487,13 +517,13 @@
+
+ timer {
+ compatible = "arm,armv8-timer";
+- interrupts-extended = <&gic GIC_PPI 13 (GIC_CPU_MASK_SIMPLE(1) |
++ interrupts-extended = <&gic GIC_PPI 13 (GIC_CPU_MASK_SIMPLE(4) |
+ IRQ_TYPE_LEVEL_LOW)>,
+- <&gic GIC_PPI 14 (GIC_CPU_MASK_SIMPLE(1) |
++ <&gic GIC_PPI 14 (GIC_CPU_MASK_SIMPLE(4) |
+ IRQ_TYPE_LEVEL_LOW)>,
+- <&gic GIC_PPI 11 (GIC_CPU_MASK_SIMPLE(1) |
++ <&gic GIC_PPI 11 (GIC_CPU_MASK_SIMPLE(4) |
+ IRQ_TYPE_LEVEL_LOW)>,
+- <&gic GIC_PPI 10 (GIC_CPU_MASK_SIMPLE(1) |
++ <&gic GIC_PPI 10 (GIC_CPU_MASK_SIMPLE(4) |
+ IRQ_TYPE_LEVEL_LOW)>;
+ };
+ };
+--
+2.7.4
+
diff --git a/bsp/meta-rcar/meta-rcar-gen3-adas/recipes-kernel/linux/linux-renesas/0188-arm64-dts-renesas-r8a77980-add-GEther-support.patch b/bsp/meta-rcar/meta-rcar-gen3-adas/recipes-kernel/linux/linux-renesas/0188-arm64-dts-renesas-r8a77980-add-GEther-support.patch
new file mode 100644
index 00000000..a45e49ab
--- /dev/null
+++ b/bsp/meta-rcar/meta-rcar-gen3-adas/recipes-kernel/linux/linux-renesas/0188-arm64-dts-renesas-r8a77980-add-GEther-support.patch
@@ -0,0 +1,47 @@
+From a58a7ac394a82da1eec426fa9c016f686bb1767e Mon Sep 17 00:00:00 2001
+From: Sergei Shtylyov <sergei.shtylyov@cogentembedded.com>
+Date: Fri, 18 May 2018 22:45:36 +0300
+Subject: [PATCH 008/211] arm64: dts: renesas: r8a77980: add GEther support
+
+Define the generic R8A77980 part of the GEther device node.
+
+Based on the original (and large) patch by Vladimir Barinov.
+
+Signed-off-by: Vladimir Barinov <vladimir.barinov@cogentembedded.com>
+Signed-off-by: Sergei Shtylyov <sergei.shtylyov@cogentembedded.com>
+Reviewed-by: Geert Uytterhoeven <geert+renesas@glider.be>
+[simon: add resets property]
+Signed-off-by: Simon Horman <horms+renesas@verge.net.au>
+
+(cherry picked from commit 87bea6780b952dac7f58ed2395d2eaa434deb0fb)
+Signed-off-by: Valentine Barshak <valentine.barshak@cogentembedded.com>
+---
+ arch/arm64/boot/dts/renesas/r8a77980.dtsi | 12 ++++++++++++
+ 1 file changed, 12 insertions(+)
+
+diff --git a/arch/arm64/boot/dts/renesas/r8a77980.dtsi b/arch/arm64/boot/dts/renesas/r8a77980.dtsi
+index 1920b86..188f7e7 100644
+--- a/arch/arm64/boot/dts/renesas/r8a77980.dtsi
++++ b/arch/arm64/boot/dts/renesas/r8a77980.dtsi
+@@ -480,6 +480,18 @@
+ dma-channels = <16>;
+ };
+
++ gether: ethernet@e7400000 {
++ compatible = "renesas,gether-r8a77980";
++ reg = <0 0xe7400000 0 0x1000>;
++ interrupts = <GIC_SPI 21 IRQ_TYPE_LEVEL_HIGH>;
++ clocks = <&cpg CPG_MOD 813>;
++ power-domains = <&sysc R8A77980_PD_ALWAYS_ON>;
++ resets = <&cpg 813>;
++ #address-cells = <1>;
++ #size-cells = <0>;
++ status = "disabled";
++ };
++
+ mmc0: mmc@ee140000 {
+ compatible = "renesas,sdhi-r8a77980",
+ "renesas,rcar-gen3-sdhi";
+--
+2.7.4
+
diff --git a/bsp/meta-rcar/meta-rcar-gen3-adas/recipes-kernel/linux/linux-renesas/0189-arm64-dts-renesas-v3hsk-add-GEther-support.patch b/bsp/meta-rcar/meta-rcar-gen3-adas/recipes-kernel/linux/linux-renesas/0189-arm64-dts-renesas-v3hsk-add-GEther-support.patch
new file mode 100644
index 00000000..c79bd5d1
--- /dev/null
+++ b/bsp/meta-rcar/meta-rcar-gen3-adas/recipes-kernel/linux/linux-renesas/0189-arm64-dts-renesas-v3hsk-add-GEther-support.patch
@@ -0,0 +1,61 @@
+From feb40ba2154f898c74cad79f0f2f2a5112645782 Mon Sep 17 00:00:00 2001
+From: Sergei Shtylyov <sergei.shtylyov@cogentembedded.com>
+Date: Fri, 18 May 2018 22:46:19 +0300
+Subject: [PATCH 009/211] arm64: dts: renesas: v3hsk: add GEther support
+
+Define the V3H Starter Kit board dependent part of the GEther device node.
+
+Based on the original (and large) patch by Vladimir Barinov.
+
+Signed-off-by: Vladimir Barinov <vladimir.barinov@cogentembedded.com>
+Signed-off-by: Sergei Shtylyov <sergei.shtylyov@cogentembedded.com>
+Signed-off-by: Simon Horman <horms+renesas@verge.net.au>
+(cherry picked from commit c0f91cac37df2d6b7f2d6692552a2f16099f7755)
+Signed-off-by: Valentine Barshak <valentine.barshak@cogentembedded.com>
+---
+ arch/arm64/boot/dts/renesas/r8a77980-v3hsk.dts | 21 +++++++++++++++++++++
+ 1 file changed, 21 insertions(+)
+
+diff --git a/arch/arm64/boot/dts/renesas/r8a77980-v3hsk.dts b/arch/arm64/boot/dts/renesas/r8a77980-v3hsk.dts
+index c968099..bb7e0e5 100644
+--- a/arch/arm64/boot/dts/renesas/r8a77980-v3hsk.dts
++++ b/arch/arm64/boot/dts/renesas/r8a77980-v3hsk.dts
+@@ -15,6 +15,7 @@
+
+ aliases {
+ serial0 = &scif0;
++ ethernet0 = &gether;
+ };
+
+ chosen {
+@@ -36,7 +37,27 @@
+ clock-frequency = <32768>;
+ };
+
++&gether {
++ pinctrl-0 = <&gether_pins>;
++ pinctrl-names = "default";
++
++ phy-mode = "rgmii";
++ phy-handle = <&phy0>;
++ renesas,no-ether-link;
++ status = "okay";
++
++ phy0: ethernet-phy@0 {
++ reg = <0>;
++ };
++};
++
+ &pfc {
++ gether_pins: gether {
++ groups = "gether_mdio_a", "gether_rgmii",
++ "gether_txcrefclk", "gether_txcrefclk_mega";
++ function = "gether";
++ };
++
+ scif0_pins: scif0 {
+ groups = "scif0_data";
+ function = "scif0";
+--
+2.7.4
+
diff --git a/bsp/meta-rcar/meta-rcar-gen3-adas/recipes-kernel/linux/linux-renesas/0190-arm64-dts-renesas-r8a77980-add-I2C-support.patch b/bsp/meta-rcar/meta-rcar-gen3-adas/recipes-kernel/linux/linux-renesas/0190-arm64-dts-renesas-r8a77980-add-I2C-support.patch
new file mode 100644
index 00000000..1e617858
--- /dev/null
+++ b/bsp/meta-rcar/meta-rcar-gen3-adas/recipes-kernel/linux/linux-renesas/0190-arm64-dts-renesas-r8a77980-add-I2C-support.patch
@@ -0,0 +1,145 @@
+From 4d71784469e02f168c85262b1703f840a9f9da23 Mon Sep 17 00:00:00 2001
+From: Sergei Shtylyov <sergei.shtylyov@cogentembedded.com>
+Date: Thu, 31 May 2018 23:22:39 +0300
+Subject: [PATCH 010/211] arm64: dts: renesas: r8a77980: add I2C support
+
+Define the generic R8A77980 parts of the I2C[0-5] device nodes.
+
+Based on the original (and large) patch by Vladimir Barinov.
+
+Signed-off-by: Vladimir Barinov <vladimir.barinov@cogentembedded.com>
+Signed-off-by: Sergei Shtylyov <sergei.shtylyov@cogentembedded.com>
+Reviewed-by: Geert Uytterhoeven <geert+renesas@glider.be>
+Signed-off-by: Simon Horman <horms+renesas@verge.net.au>
+(cherry picked from commit bc620474c6e283c0e1e60796ed0ac9b04da9890c)
+Signed-off-by: Valentine Barshak <valentine.barshak@cogentembedded.com>
+---
+ arch/arm64/boot/dts/renesas/r8a77980.dtsi | 105 ++++++++++++++++++++++++++++++
+ 1 file changed, 105 insertions(+)
+
+diff --git a/arch/arm64/boot/dts/renesas/r8a77980.dtsi b/arch/arm64/boot/dts/renesas/r8a77980.dtsi
+index 188f7e7..15dde72 100644
+--- a/arch/arm64/boot/dts/renesas/r8a77980.dtsi
++++ b/arch/arm64/boot/dts/renesas/r8a77980.dtsi
+@@ -16,6 +16,15 @@
+ #address-cells = <2>;
+ #size-cells = <2>;
+
++ aliases {
++ i2c0 = &i2c0;
++ i2c1 = &i2c1;
++ i2c2 = &i2c2;
++ i2c3 = &i2c3;
++ i2c4 = &i2c4;
++ i2c5 = &i2c5;
++ };
++
+ cpus {
+ #address-cells = <1>;
+ #size-cells = <0>;
+@@ -135,6 +144,102 @@
+ #power-domain-cells = <1>;
+ };
+
++ i2c0: i2c@e6500000 {
++ compatible = "renesas,i2c-r8a77980",
++ "renesas,rcar-gen3-i2c";
++ reg = <0 0xe6500000 0 0x40>;
++ interrupts = <GIC_SPI 287 IRQ_TYPE_LEVEL_HIGH>;
++ clocks = <&cpg CPG_MOD 931>;
++ power-domains = <&sysc R8A77980_PD_ALWAYS_ON>;
++ resets = <&cpg 931>;
++ dmas = <&dmac1 0x91>, <&dmac1 0x90>,
++ <&dmac2 0x91>, <&dmac2 0x90>;
++ dma-names = "tx", "rx", "tx", "rx";
++ i2c-scl-internal-delay-ns = <6>;
++ #address-cells = <1>;
++ #size-cells = <0>;
++ status = "disabled";
++ };
++
++ i2c1: i2c@e6508000 {
++ compatible = "renesas,i2c-r8a77980",
++ "renesas,rcar-gen3-i2c";
++ reg = <0 0xe6508000 0 0x40>;
++ interrupts = <GIC_SPI 288 IRQ_TYPE_LEVEL_HIGH>;
++ clocks = <&cpg CPG_MOD 930>;
++ power-domains = <&sysc R8A77980_PD_ALWAYS_ON>;
++ resets = <&cpg 930>;
++ dmas = <&dmac1 0x93>, <&dmac1 0x92>,
++ <&dmac2 0x93>, <&dmac2 0x92>;
++ dma-names = "tx", "rx", "tx", "rx";
++ i2c-scl-internal-delay-ns = <6>;
++ #address-cells = <1>;
++ #size-cells = <0>;
++ status = "disabled";
++ };
++
++ i2c2: i2c@e6510000 {
++ compatible = "renesas,i2c-r8a77980",
++ "renesas,rcar-gen3-i2c";
++ reg = <0 0xe6510000 0 0x40>;
++ interrupts = <GIC_SPI 286 IRQ_TYPE_LEVEL_HIGH>;
++ clocks = <&cpg CPG_MOD 929>;
++ power-domains = <&sysc R8A77980_PD_ALWAYS_ON>;
++ resets = <&cpg 929>;
++ dmas = <&dmac1 0x95>, <&dmac1 0x94>,
++ <&dmac2 0x95>, <&dmac2 0x94>;
++ dma-names = "tx", "rx", "tx", "rx";
++ i2c-scl-internal-delay-ns = <6>;
++ #address-cells = <1>;
++ #size-cells = <0>;
++ status = "disabled";
++ };
++
++ i2c3: i2c@e66d0000 {
++ compatible = "renesas,i2c-r8a77980",
++ "renesas,rcar-gen3-i2c";
++ reg = <0 0xe66d0000 0 0x40>;
++ interrupts = <GIC_SPI 290 IRQ_TYPE_LEVEL_HIGH>;
++ clocks = <&cpg CPG_MOD 928>;
++ power-domains = <&sysc R8A77980_PD_ALWAYS_ON>;
++ resets = <&cpg 928>;
++ i2c-scl-internal-delay-ns = <6>;
++ #address-cells = <1>;
++ #size-cells = <0>;
++ status = "disabled";
++ };
++
++ i2c4: i2c@e66d8000 {
++ compatible = "renesas,i2c-r8a77980",
++ "renesas,rcar-gen3-i2c";
++ reg = <0 0xe66d8000 0 0x40>;
++ interrupts = <GIC_SPI 19 IRQ_TYPE_LEVEL_HIGH>;
++ clocks = <&cpg CPG_MOD 927>;
++ power-domains = <&sysc R8A77980_PD_ALWAYS_ON>;
++ resets = <&cpg 927>;
++ i2c-scl-internal-delay-ns = <6>;
++ #address-cells = <1>;
++ #size-cells = <0>;
++ status = "disabled";
++ };
++
++ i2c5: i2c@e66e0000 {
++ compatible = "renesas,i2c-r8a77980",
++ "renesas,rcar-gen3-i2c";
++ reg = <0 0xe66e0000 0 0x40>;
++ interrupts = <GIC_SPI 20 IRQ_TYPE_LEVEL_HIGH>;
++ clocks = <&cpg CPG_MOD 919>;
++ power-domains = <&sysc R8A77980_PD_ALWAYS_ON>;
++ resets = <&cpg 919>;
++ dmas = <&dmac1 0x9b>, <&dmac1 0x9a>,
++ <&dmac2 0x9b>, <&dmac2 0x9a>;
++ dma-names = "tx", "rx", "tx", "rx";
++ i2c-scl-internal-delay-ns = <6>;
++ #address-cells = <1>;
++ #size-cells = <0>;
++ status = "disabled";
++ };
++
+ hscif0: serial@e6540000 {
+ compatible = "renesas,hscif-r8a77980",
+ "renesas,rcar-gen3-hscif",
+--
+2.7.4
+
diff --git a/bsp/meta-rcar/meta-rcar-gen3-adas/recipes-kernel/linux/linux-renesas/0191-arm64-dts-renesas-condor-add-I2C0-support.patch b/bsp/meta-rcar/meta-rcar-gen3-adas/recipes-kernel/linux/linux-renesas/0191-arm64-dts-renesas-condor-add-I2C0-support.patch
new file mode 100644
index 00000000..443bdac4
--- /dev/null
+++ b/bsp/meta-rcar/meta-rcar-gen3-adas/recipes-kernel/linux/linux-renesas/0191-arm64-dts-renesas-condor-add-I2C0-support.patch
@@ -0,0 +1,67 @@
+From ef4b9080dc83f007f2b767d9176bae80d005b75c Mon Sep 17 00:00:00 2001
+From: Sergei Shtylyov <sergei.shtylyov@cogentembedded.com>
+Date: Thu, 31 May 2018 23:26:49 +0300
+Subject: [PATCH 011/211] arm64: dts: renesas: condor: add I2C0 support
+
+Define the Condor board dependent part of the I2C0 device node.
+
+The I2C0 bus is populated by 2 ON Semiconductor PCA9654 I/O expanders
+and Analog Devices ADV7511W HDMI transmitter (but we're only describing
+the former chips now).
+
+Signed-off-by: Sergei Shtylyov <sergei.shtylyov@cogentembedded.com>
+Signed-off-by: Simon Horman <horms+renesas@verge.net.au>
+(cherry picked from commit 45fde0d498dc77e5fc221960843fa377e0c70822)
+Signed-off-by: Valentine Barshak <valentine.barshak@cogentembedded.com>
+---
+ arch/arm64/boot/dts/renesas/r8a77980-condor.dts | 27 +++++++++++++++++++++++++
+ 1 file changed, 27 insertions(+)
+
+diff --git a/arch/arm64/boot/dts/renesas/r8a77980-condor.dts b/arch/arm64/boot/dts/renesas/r8a77980-condor.dts
+index 0b93a7d..cc3ee25 100644
+--- a/arch/arm64/boot/dts/renesas/r8a77980-condor.dts
++++ b/arch/arm64/boot/dts/renesas/r8a77980-condor.dts
+@@ -80,6 +80,28 @@
+ clock-frequency = <32768>;
+ };
+
++&i2c0 {
++ pinctrl-0 = <&i2c0_pins>;
++ pinctrl-names = "default";
++
++ status = "okay";
++ clock-frequency = <400000>;
++
++ io_expander0: gpio@20 {
++ compatible = "onnn,pca9654";
++ reg = <0x20>;
++ gpio-controller;
++ #gpio-cells = <2>;
++ };
++
++ io_expander1: gpio@21 {
++ compatible = "onnn,pca9654";
++ reg = <0x21>;
++ gpio-controller;
++ #gpio-cells = <2>;
++ };
++};
++
+ &mmc0 {
+ pinctrl-0 = <&mmc_pins>;
+ pinctrl-1 = <&mmc_pins_uhs>;
+@@ -104,6 +126,11 @@
+ function = "canfd0";
+ };
+
++ i2c0_pins: i2c0 {
++ groups = "i2c0";
++ function = "i2c0";
++ };
++
+ mmc_pins: mmc {
+ groups = "mmc_data8", "mmc_ctrl", "mmc_ds";
+ function = "mmc";
+--
+2.7.4
+
diff --git a/bsp/meta-rcar/meta-rcar-gen3-adas/recipes-kernel/linux/linux-renesas/0192-arm64-dts-renesas-r8a77980-add-GPIO-support.patch b/bsp/meta-rcar/meta-rcar-gen3-adas/recipes-kernel/linux/linux-renesas/0192-arm64-dts-renesas-r8a77980-add-GPIO-support.patch
new file mode 100644
index 00000000..0edfd83c
--- /dev/null
+++ b/bsp/meta-rcar/meta-rcar-gen3-adas/recipes-kernel/linux/linux-renesas/0192-arm64-dts-renesas-r8a77980-add-GPIO-support.patch
@@ -0,0 +1,123 @@
+From fdda1aa294ce0aa67f2966a2f7192f10a7220ce4 Mon Sep 17 00:00:00 2001
+From: Sergei Shtylyov <sergei.shtylyov@cogentembedded.com>
+Date: Fri, 1 Jun 2018 23:44:46 +0300
+Subject: [PATCH 012/211] arm64: dts: renesas: r8a77980: add GPIO support
+
+Describe all 6 GPIO controllers in the R8A77980 device tree.
+
+Based on the original (and large) patch by Vladimir Barinov.
+
+Signed-off-by: Vladimir Barinov <vladimir.barinov@cogentembedded.com>
+Signed-off-by: Sergei Shtylyov <sergei.shtylyov@cogentembedded.com>
+Reviewed-by: Geert Uytterhoeven <geert+renesas@glider.be>
+Signed-off-by: Simon Horman <horms+renesas@verge.net.au>
+(cherry picked from commit efcb52e35d162dc9104be56492b65049a17dc6a4)
+Signed-off-by: Valentine Barshak <valentine.barshak@cogentembedded.com>
+---
+ arch/arm64/boot/dts/renesas/r8a77980.dtsi | 90 +++++++++++++++++++++++++++++++
+ 1 file changed, 90 insertions(+)
+
+diff --git a/arch/arm64/boot/dts/renesas/r8a77980.dtsi b/arch/arm64/boot/dts/renesas/r8a77980.dtsi
+index 15dde72..682a782 100644
+--- a/arch/arm64/boot/dts/renesas/r8a77980.dtsi
++++ b/arch/arm64/boot/dts/renesas/r8a77980.dtsi
+@@ -118,6 +118,96 @@
+ #size-cells = <2>;
+ ranges;
+
++ gpio0: gpio@e6050000 {
++ compatible = "renesas,gpio-r8a77980",
++ "renesas,rcar-gen3-gpio";
++ reg = <0 0xe6050000 0 0x50>;
++ interrupts = <GIC_SPI 4 IRQ_TYPE_LEVEL_HIGH>;
++ #gpio-cells = <2>;
++ gpio-controller;
++ gpio-ranges = <&pfc 0 0 22>;
++ #interrupt-cells = <2>;
++ interrupt-controller;
++ clocks = <&cpg CPG_MOD 912>;
++ power-domains = <&sysc R8A77980_PD_ALWAYS_ON>;
++ resets = <&cpg 912>;
++ };
++
++ gpio1: gpio@e6051000 {
++ compatible = "renesas,gpio-r8a77980",
++ "renesas,rcar-gen3-gpio";
++ reg = <0 0xe6051000 0 0x50>;
++ interrupts = <GIC_SPI 5 IRQ_TYPE_LEVEL_HIGH>;
++ #gpio-cells = <2>;
++ gpio-controller;
++ gpio-ranges = <&pfc 0 32 28>;
++ #interrupt-cells = <2>;
++ interrupt-controller;
++ clocks = <&cpg CPG_MOD 911>;
++ power-domains = <&sysc R8A77980_PD_ALWAYS_ON>;
++ resets = <&cpg 911>;
++ };
++
++ gpio2: gpio@e6052000 {
++ compatible = "renesas,gpio-r8a77980",
++ "renesas,rcar-gen3-gpio";
++ reg = <0 0xe6052000 0 0x50>;
++ interrupts = <GIC_SPI 6 IRQ_TYPE_LEVEL_HIGH>;
++ #gpio-cells = <2>;
++ gpio-controller;
++ gpio-ranges = <&pfc 0 64 30>;
++ #interrupt-cells = <2>;
++ interrupt-controller;
++ clocks = <&cpg CPG_MOD 910>;
++ power-domains = <&sysc R8A77980_PD_ALWAYS_ON>;
++ resets = <&cpg 910>;
++ };
++
++ gpio3: gpio@e6053000 {
++ compatible = "renesas,gpio-r8a77980",
++ "renesas,rcar-gen3-gpio";
++ reg = <0 0xe6053000 0 0x50>;
++ interrupts = <GIC_SPI 7 IRQ_TYPE_LEVEL_HIGH>;
++ #gpio-cells = <2>;
++ gpio-controller;
++ gpio-ranges = <&pfc 0 96 17>;
++ #interrupt-cells = <2>;
++ interrupt-controller;
++ clocks = <&cpg CPG_MOD 909>;
++ power-domains = <&sysc R8A77980_PD_ALWAYS_ON>;
++ resets = <&cpg 909>;
++ };
++
++ gpio4: gpio@e6054000 {
++ compatible = "renesas,gpio-r8a77980",
++ "renesas,rcar-gen3-gpio";
++ reg = <0 0xe6054000 0 0x50>;
++ interrupts = <GIC_SPI 8 IRQ_TYPE_LEVEL_HIGH>;
++ #gpio-cells = <2>;
++ gpio-controller;
++ gpio-ranges = <&pfc 0 128 25>;
++ #interrupt-cells = <2>;
++ interrupt-controller;
++ clocks = <&cpg CPG_MOD 908>;
++ power-domains = <&sysc R8A77980_PD_ALWAYS_ON>;
++ resets = <&cpg 908>;
++ };
++
++ gpio5: gpio@e6055000 {
++ compatible = "renesas,gpio-r8a77980",
++ "renesas,rcar-gen3-gpio";
++ reg = <0 0xe6055000 0 0x50>;
++ interrupts = <GIC_SPI 9 IRQ_TYPE_LEVEL_HIGH>;
++ #gpio-cells = <2>;
++ gpio-controller;
++ gpio-ranges = <&pfc 0 160 15>;
++ #interrupt-cells = <2>;
++ interrupt-controller;
++ clocks = <&cpg CPG_MOD 907>;
++ power-domains = <&sysc R8A77980_PD_ALWAYS_ON>;
++ resets = <&cpg 907>;
++ };
++
+ pfc: pin-controller@e6060000 {
+ compatible = "renesas,pfc-r8a77980";
+ reg = <0 0xe6060000 0 0x50c>;
+--
+2.7.4
+
diff --git a/bsp/meta-rcar/meta-rcar-gen3-adas/recipes-kernel/linux/linux-renesas/0193-arm64-dts-renesas-condor-v3hsk-specify-Ethernet-PHY-.patch b/bsp/meta-rcar/meta-rcar-gen3-adas/recipes-kernel/linux/linux-renesas/0193-arm64-dts-renesas-condor-v3hsk-specify-Ethernet-PHY-.patch
new file mode 100644
index 00000000..cccc11ae
--- /dev/null
+++ b/bsp/meta-rcar/meta-rcar-gen3-adas/recipes-kernel/linux/linux-renesas/0193-arm64-dts-renesas-condor-v3hsk-specify-Ethernet-PHY-.patch
@@ -0,0 +1,50 @@
+From 37d10d9dca2423dc6482631d5b6477fc678326f9 Mon Sep 17 00:00:00 2001
+From: Sergei Shtylyov <sergei.shtylyov@cogentembedded.com>
+Date: Wed, 13 Jun 2018 19:42:15 +0300
+Subject: [PATCH 013/211] arm64: dts: renesas: condor/v3hsk: specify Ethernet
+ PHY IRQs
+
+Specify Ethernet PHY IRQs in the Condor/V3HSK board device trees, now that
+we have the GPIO support (previously phylib had to resort to polling).
+
+Based on the original (and large) patch by Vladimir Barinov.
+
+Signed-off-by: Vladimir Barinov <vladimir.barinov@cogentembedded.com>
+Signed-off-by: Sergei Shtylyov <sergei.shtylyov@cogentembedded.com>
+Signed-off-by: Simon Horman <horms+renesas@verge.net.au>
+(cherry picked from commit ffbd52352208534a30d5bbe2e15ee9e5cbb98c6d)
+Signed-off-by: Valentine Barshak <valentine.barshak@cogentembedded.com>
+---
+ arch/arm64/boot/dts/renesas/r8a77980-condor.dts | 2 ++
+ arch/arm64/boot/dts/renesas/r8a77980-v3hsk.dts | 2 ++
+ 2 files changed, 4 insertions(+)
+
+diff --git a/arch/arm64/boot/dts/renesas/r8a77980-condor.dts b/arch/arm64/boot/dts/renesas/r8a77980-condor.dts
+index cc3ee25..9f25c40 100644
+--- a/arch/arm64/boot/dts/renesas/r8a77980-condor.dts
++++ b/arch/arm64/boot/dts/renesas/r8a77980-condor.dts
+@@ -59,6 +59,8 @@
+ phy0: ethernet-phy@0 {
+ rxc-skew-ps = <1500>;
+ reg = <0>;
++ interrupt-parent = <&gpio1>;
++ interrupts = <17 IRQ_TYPE_LEVEL_LOW>;
+ };
+ };
+
+diff --git a/arch/arm64/boot/dts/renesas/r8a77980-v3hsk.dts b/arch/arm64/boot/dts/renesas/r8a77980-v3hsk.dts
+index bb7e0e5..9dac42f 100644
+--- a/arch/arm64/boot/dts/renesas/r8a77980-v3hsk.dts
++++ b/arch/arm64/boot/dts/renesas/r8a77980-v3hsk.dts
+@@ -48,6 +48,8 @@
+
+ phy0: ethernet-phy@0 {
+ reg = <0>;
++ interrupt-parent = <&gpio4>;
++ interrupts = <23 IRQ_TYPE_LEVEL_LOW>;
+ };
+ };
+
+--
+2.7.4
+
diff --git a/bsp/meta-rcar/meta-rcar-gen3-adas/recipes-kernel/linux/linux-renesas/0194-arm64-dts-renesas-r8a77980-add-FCPVD-VSPD-DU-LVDS-su.patch b/bsp/meta-rcar/meta-rcar-gen3-adas/recipes-kernel/linux/linux-renesas/0194-arm64-dts-renesas-r8a77980-add-FCPVD-VSPD-DU-LVDS-su.patch
new file mode 100644
index 00000000..4e69b8ac
--- /dev/null
+++ b/bsp/meta-rcar/meta-rcar-gen3-adas/recipes-kernel/linux/linux-renesas/0194-arm64-dts-renesas-r8a77980-add-FCPVD-VSPD-DU-LVDS-su.patch
@@ -0,0 +1,112 @@
+From 2131b446d83bfcf2d47af73ead18eec97990d82d Mon Sep 17 00:00:00 2001
+From: Sergei Shtylyov <sergei.shtylyov@cogentembedded.com>
+Date: Wed, 13 Jun 2018 23:11:27 +0300
+Subject: [PATCH 014/211] arm64: dts: renesas: r8a77980: add FCPVD/VSPD/DU/LVDS
+ support
+
+Describe the interconnected FCPVD0, VSPD0, DU, and LVDS0 devices in the
+R8A77980 device tree...
+
+Based on the original (and large) patch by Vladimir Barinov.
+
+Signed-off-by: Vladimir Barinov <vladimir.barinov@cogentembedded.com>
+Signed-off-by: Sergei Shtylyov <sergei.shtylyov@cogentembedded.com>
+Reviewed-by: Laurent Pinchart <laurent.pinchart@ideasonboard.com>
+Signed-off-by: Simon Horman <horms+renesas@verge.net.au>
+(cherry picked from commit a334e781e01afeb97634480ec0d9819287b79a68)
+Signed-off-by: Valentine Barshak <valentine.barshak@cogentembedded.com>
+---
+ arch/arm64/boot/dts/renesas/r8a77980.dtsi | 77 +++++++++++++++++++++++++++++++
+ 1 file changed, 77 insertions(+)
+
+diff --git a/arch/arm64/boot/dts/renesas/r8a77980.dtsi b/arch/arm64/boot/dts/renesas/r8a77980.dtsi
+index 682a782..873b80a 100644
+--- a/arch/arm64/boot/dts/renesas/r8a77980.dtsi
++++ b/arch/arm64/boot/dts/renesas/r8a77980.dtsi
+@@ -716,6 +716,83 @@
+ resets = <&cpg 408>;
+ };
+
++ vspd0: vsp@fea20000 {
++ compatible = "renesas,vsp2";
++ reg = <0 0xfea20000 0 0x5000>;
++ interrupts = <GIC_SPI 169 IRQ_TYPE_LEVEL_HIGH>;
++ clocks = <&cpg CPG_MOD 623>;
++ power-domains = <&sysc R8A77980_PD_ALWAYS_ON>;
++ resets = <&cpg 623>;
++ renesas,fcp = <&fcpvd0>;
++ };
++
++ fcpvd0: fcp@fea27000 {
++ compatible = "renesas,fcpv";
++ reg = <0 0xfea27000 0 0x200>;
++ clocks = <&cpg CPG_MOD 603>;
++ power-domains = <&sysc R8A77980_PD_ALWAYS_ON>;
++ resets = <&cpg 603>;
++ };
++
++ du: display@feb00000 {
++ compatible = "renesas,du-r8a77980",
++ "renesas,du-r8a77970";
++ reg = <0 0xfeb00000 0 0x80000>;
++ interrupts = <GIC_SPI 256 IRQ_TYPE_LEVEL_HIGH>;
++ clocks = <&cpg CPG_MOD 724>;
++ clock-names = "du.0";
++ power-domains = <&sysc R8A77980_PD_ALWAYS_ON>;
++ resets = <&cpg 724>;
++ vsps = <&vspd0>;
++ status = "disabled";
++
++ ports {
++ #address-cells = <1>;
++ #size-cells = <0>;
++
++ port@0 {
++ reg = <0>;
++ du_out_rgb: endpoint {
++ };
++ };
++
++ port@1 {
++ reg = <1>;
++ du_out_lvds0: endpoint {
++ remote-endpoint = <&lvds0_in>;
++ };
++ };
++ };
++ };
++
++ lvds0: lvds-encoder@feb90000 {
++ compatible = "renesas,r8a77980-lvds";
++ reg = <0 0xfeb90000 0 0x14>;
++ clocks = <&cpg CPG_MOD 727>;
++ power-domains = <&sysc R8A77980_PD_ALWAYS_ON>;
++ resets = <&cpg 727>;
++ status = "disabled";
++
++ ports {
++ #address-cells = <1>;
++ #size-cells = <0>;
++
++ port@0 {
++ reg = <0>;
++ lvds0_in: endpoint {
++ remote-endpoint =
++ <&du_out_lvds0>;
++ };
++ };
++
++ port@1 {
++ reg = <1>;
++ lvds0_out: endpoint {
++ };
++ };
++ };
++ };
++
+ prr: chipid@fff00044 {
+ compatible = "renesas,prr";
+ reg = <0 0xfff00044 0 4>;
+--
+2.7.4
+
diff --git a/bsp/meta-rcar/meta-rcar-gen3-adas/recipes-kernel/linux/linux-renesas/0195-sh_eth-fix-enum-RPADIR_BIT.patch b/bsp/meta-rcar/meta-rcar-gen3-adas/recipes-kernel/linux/linux-renesas/0195-sh_eth-fix-enum-RPADIR_BIT.patch
new file mode 100644
index 00000000..96a9be64
--- /dev/null
+++ b/bsp/meta-rcar/meta-rcar-gen3-adas/recipes-kernel/linux/linux-renesas/0195-sh_eth-fix-enum-RPADIR_BIT.patch
@@ -0,0 +1,38 @@
+From adad896f249ec55add54183120256250224caa11 Mon Sep 17 00:00:00 2001
+From: Sergei Shtylyov <sergei.shtylyov@cogentembedded.com>
+Date: Mon, 25 Jun 2018 23:36:21 +0300
+Subject: [PATCH 015/211] sh_eth: fix *enum* RPADIR_BIT
+
+The *enum* RPADIR_BIT was declared in the commit 86a74ff21a7a ("net:
+sh_eth: add support for Renesas SuperH Ethernet") adding SH771x support,
+however the SH771x manual doesn't have the RPADIR register described and,
+moreover, tells why the padding insertion must not be used. The newer SoC
+manuals do have RPADIR documented, though with somewhat different layout --
+update the *enum* according to these manuals...
+
+Signed-off-by: Sergei Shtylyov <sergei.shtylyov@cogentembedded.com>
+Reviewed-by: Geert Uytterhoeven <geert+renesas@glider.be>
+Signed-off-by: David S. Miller <davem@davemloft.net>
+(cherry picked from commit b13ca098fd35bb0cfbe027f2415a17a6ceb6f47f)
+Signed-off-by: Valentine Barshak <valentine.barshak@cogentembedded.com>
+---
+ drivers/net/ethernet/renesas/sh_eth.h | 3 +--
+ 1 file changed, 1 insertion(+), 2 deletions(-)
+
+diff --git a/drivers/net/ethernet/renesas/sh_eth.h b/drivers/net/ethernet/renesas/sh_eth.h
+index 726c55a..ae3ef5d 100644
+--- a/drivers/net/ethernet/renesas/sh_eth.h
++++ b/drivers/net/ethernet/renesas/sh_eth.h
+@@ -403,8 +403,7 @@ enum DESC_I_BIT {
+
+ /* RPADIR */
+ enum RPADIR_BIT {
+- RPADIR_PADS1 = 0x20000, RPADIR_PADS0 = 0x10000,
+- RPADIR_PADR = 0x0003f,
++ RPADIR_PADS = 0x1f0000, RPADIR_PADR = 0xffff,
+ };
+
+ /* FDR */
+--
+2.7.4
+
diff --git a/bsp/meta-rcar/meta-rcar-gen3-adas/recipes-kernel/linux/linux-renesas/0196-sh_eth-remove-sh_eth_cpu_data-rpadir_value.patch b/bsp/meta-rcar/meta-rcar-gen3-adas/recipes-kernel/linux/linux-renesas/0196-sh_eth-remove-sh_eth_cpu_data-rpadir_value.patch
new file mode 100644
index 00000000..db774e11
--- /dev/null
+++ b/bsp/meta-rcar/meta-rcar-gen3-adas/recipes-kernel/linux/linux-renesas/0196-sh_eth-remove-sh_eth_cpu_data-rpadir_value.patch
@@ -0,0 +1,95 @@
+From 3edb531642371a70dc3efbd3c468581521e03c9c Mon Sep 17 00:00:00 2001
+From: Sergei Shtylyov <sergei.shtylyov@cogentembedded.com>
+Date: Mon, 25 Jun 2018 23:37:06 +0300
+Subject: [PATCH 016/211] sh_eth: remove sh_eth_cpu_data::rpadir_value
+
+If RPADIR exists, the value written to it is always the same for all SoCs
+(and derived from NET_IP_ALIGN), so there has not been any need to store
+it in the *struct* sh_eth_cpu_data...
+
+Signed-off-by: Sergei Shtylyov <sergei.shtylyov@cogentembedded.com>
+Reviewed-by: Geert Uytterhoeven <geert+renesas@glider.be>
+Signed-off-by: David S. Miller <davem@davemloft.net>
+(cherry picked from commit 470103dc840ec9cda91b5049d82f4bb599cea759)
+Signed-off-by: Valentine Barshak <valentine.barshak@cogentembedded.com>
+---
+ drivers/net/ethernet/renesas/sh_eth.c | 8 +-------
+ drivers/net/ethernet/renesas/sh_eth.h | 1 -
+ 2 files changed, 1 insertion(+), 8 deletions(-)
+
+diff --git a/drivers/net/ethernet/renesas/sh_eth.c b/drivers/net/ethernet/renesas/sh_eth.c
+index 87a6bcd..981ea16 100644
+--- a/drivers/net/ethernet/renesas/sh_eth.c
++++ b/drivers/net/ethernet/renesas/sh_eth.c
+@@ -622,7 +622,6 @@ static struct sh_eth_cpu_data r7s72100_data = {
+ .tpauser = 1,
+ .hw_swap = 1,
+ .rpadir = 1,
+- .rpadir_value = 2 << 16,
+ .no_trimd = 1,
+ .no_ade = 1,
+ .xdfar_rw = 1,
+@@ -672,7 +671,6 @@ static struct sh_eth_cpu_data r8a7740_data = {
+ .bculr = 1,
+ .hw_swap = 1,
+ .rpadir = 1,
+- .rpadir_value = 2 << 16,
+ .no_trimd = 1,
+ .no_ade = 1,
+ .xdfar_rw = 1,
+@@ -798,7 +796,6 @@ static struct sh_eth_cpu_data r8a77980_data = {
+ .hw_swap = 1,
+ .nbst = 1,
+ .rpadir = 1,
+- .rpadir_value = 2 << 16,
+ .no_trimd = 1,
+ .no_ade = 1,
+ .xdfar_rw = 1,
+@@ -851,7 +848,6 @@ static struct sh_eth_cpu_data sh7724_data = {
+ .tpauser = 1,
+ .hw_swap = 1,
+ .rpadir = 1,
+- .rpadir_value = 0x00020000, /* NET_IP_ALIGN assumed to be 2 */
+ };
+
+ static void sh_eth_set_rate_sh7757(struct net_device *ndev)
+@@ -898,7 +894,6 @@ static struct sh_eth_cpu_data sh7757_data = {
+ .hw_swap = 1,
+ .no_ade = 1,
+ .rpadir = 1,
+- .rpadir_value = 2 << 16,
+ .rtrate = 1,
+ .dual_port = 1,
+ };
+@@ -978,7 +973,6 @@ static struct sh_eth_cpu_data sh7757_data_giga = {
+ .bculr = 1,
+ .hw_swap = 1,
+ .rpadir = 1,
+- .rpadir_value = 2 << 16,
+ .no_trimd = 1,
+ .no_ade = 1,
+ .xdfar_rw = 1,
+@@ -1467,7 +1461,7 @@ static int sh_eth_dev_init(struct net_device *ndev)
+ /* Descriptor format */
+ sh_eth_ring_format(ndev);
+ if (mdp->cd->rpadir)
+- sh_eth_write(ndev, mdp->cd->rpadir_value, RPADIR);
++ sh_eth_write(ndev, NET_IP_ALIGN << 16, RPADIR);
+
+ /* all sh_eth int mask */
+ sh_eth_write(ndev, 0, EESIPR);
+diff --git a/drivers/net/ethernet/renesas/sh_eth.h b/drivers/net/ethernet/renesas/sh_eth.h
+index ae3ef5d..a03d99f 100644
+--- a/drivers/net/ethernet/renesas/sh_eth.h
++++ b/drivers/net/ethernet/renesas/sh_eth.h
+@@ -487,7 +487,6 @@ struct sh_eth_cpu_data {
+ u32 ecsipr_value;
+ u32 fdr_value;
+ u32 fcftr_value;
+- u32 rpadir_value;
+
+ /* interrupt checking mask */
+ u32 tx_check;
+--
+2.7.4
+
diff --git a/bsp/meta-rcar/meta-rcar-gen3-adas/recipes-kernel/linux/linux-renesas/0197-sh_eth-fix-enum-A-M-PR_BIT.patch b/bsp/meta-rcar/meta-rcar-gen3-adas/recipes-kernel/linux/linux-renesas/0197-sh_eth-fix-enum-A-M-PR_BIT.patch
new file mode 100644
index 00000000..e3bf0199
--- /dev/null
+++ b/bsp/meta-rcar/meta-rcar-gen3-adas/recipes-kernel/linux/linux-renesas/0197-sh_eth-fix-enum-A-M-PR_BIT.patch
@@ -0,0 +1,62 @@
+From d511f84c6154eea75e1f00bc1806279a8aec4499 Mon Sep 17 00:00:00 2001
+From: Sergei Shtylyov <sergei.shtylyov@cogentembedded.com>
+Date: Tue, 26 Jun 2018 18:42:33 +0300
+Subject: [PATCH 017/211] sh_eth: fix *enum* {A|M}PR_BIT
+
+The *enum* {A|M}PR_BIT were declared in the commit 86a74ff21a7a ("net:
+sh_eth: add support for Renesas SuperH Ethernet") adding SH771x support,
+however the SH771x manual doesn't have the APR/MPR registers described
+and the code writing to them for SH7710 was later removed by the commit
+380af9e390ec ("net: sh_eth: CPU dependency code collect to "struct
+sh_eth_cpu_data""). All the newer SoC manuals have these registers
+documented as having a 16-bit TIME parameter of the PAUSE frame, not
+1-bit -- update the *enum* accordingly, fixing up the APR/MPR writes...
+
+Signed-off-by: Sergei Shtylyov <sergei.shtylyov@cogentembedded.com>
+Reviewed-by: Geert Uytterhoeven <geert+renesas@glider.be>
+Signed-off-by: David S. Miller <davem@davemloft.net>
+(cherry picked from commit 782e85c5f7aee0294cefb52a190b05e082c178d5)
+Signed-off-by: Valentine Barshak <valentine.barshak@cogentembedded.com>
+---
+ drivers/net/ethernet/renesas/sh_eth.c | 4 ++--
+ drivers/net/ethernet/renesas/sh_eth.h | 4 ++--
+ 2 files changed, 4 insertions(+), 4 deletions(-)
+
+diff --git a/drivers/net/ethernet/renesas/sh_eth.c b/drivers/net/ethernet/renesas/sh_eth.c
+index 981ea16..f11b12f 100644
+--- a/drivers/net/ethernet/renesas/sh_eth.c
++++ b/drivers/net/ethernet/renesas/sh_eth.c
+@@ -1521,9 +1521,9 @@ static int sh_eth_dev_init(struct net_device *ndev)
+
+ /* mask reset */
+ if (mdp->cd->apr)
+- sh_eth_write(ndev, APR_AP, APR);
++ sh_eth_write(ndev, 1, APR);
+ if (mdp->cd->mpr)
+- sh_eth_write(ndev, MPR_MP, MPR);
++ sh_eth_write(ndev, 1, MPR);
+ if (mdp->cd->tpauser)
+ sh_eth_write(ndev, TPAUSER_UNLIMITED, TPAUSER);
+
+diff --git a/drivers/net/ethernet/renesas/sh_eth.h b/drivers/net/ethernet/renesas/sh_eth.h
+index a03d99f..140ad2c 100644
+--- a/drivers/net/ethernet/renesas/sh_eth.h
++++ b/drivers/net/ethernet/renesas/sh_eth.h
+@@ -383,12 +383,12 @@ enum ECSIPR_STATUS_MASK_BIT {
+
+ /* APR */
+ enum APR_BIT {
+- APR_AP = 0x00000001,
++ APR_AP = 0x0000ffff,
+ };
+
+ /* MPR */
+ enum MPR_BIT {
+- MPR_MP = 0x00000001,
++ MPR_MP = 0x0000ffff,
+ };
+
+ /* TRSCER */
+--
+2.7.4
+
diff --git a/bsp/meta-rcar/meta-rcar-gen3-adas/recipes-kernel/linux/linux-renesas/0198-iommu-ipmmu-vmsa-Document-R-Car-V3H-and-E3-IPMMU-DT-.patch b/bsp/meta-rcar/meta-rcar-gen3-adas/recipes-kernel/linux/linux-renesas/0198-iommu-ipmmu-vmsa-Document-R-Car-V3H-and-E3-IPMMU-DT-.patch
new file mode 100644
index 00000000..116ee0f4
--- /dev/null
+++ b/bsp/meta-rcar/meta-rcar-gen3-adas/recipes-kernel/linux/linux-renesas/0198-iommu-ipmmu-vmsa-Document-R-Car-V3H-and-E3-IPMMU-DT-.patch
@@ -0,0 +1,36 @@
+From 3d4aa8d0b234e1aa000b027889126bc9f1ca1dbb Mon Sep 17 00:00:00 2001
+From: Magnus Damm <damm+renesas@opensource.se>
+Date: Thu, 14 Jun 2018 12:48:26 +0200
+Subject: [PATCH 018/211] iommu/ipmmu-vmsa: Document R-Car V3H and E3 IPMMU DT
+ bindings
+
+Update the IPMMU DT binding documentation to include the compat strings
+for the IPMMU devices included in the R-Car V3H and E3 SoCs.
+
+Signed-off-by: Magnus Damm <damm+renesas@opensource.se>
+Reviewed-by: Simon Horman <horms+renesas@verge.net.au>
+Acked-by: Rob Herring <robh@kernel.org>
+Reviewed-by: Geert Uytterhoeven <geert+renesas@glider.be>
+Signed-off-by: Joerg Roedel <jroedel@suse.de>
+(cherry picked from commit bc24f62bf8763660110f915cead86dd13840ed26)
+[valentine.barshak: resolved minor conflicts]
+Signed-off-by: Valentine Barshak <valentine.barshak@cogentembedded.com>
+---
+ Documentation/devicetree/bindings/iommu/renesas,ipmmu-vmsa.txt | 1 +
+ 1 file changed, 1 insertion(+)
+
+diff --git a/Documentation/devicetree/bindings/iommu/renesas,ipmmu-vmsa.txt b/Documentation/devicetree/bindings/iommu/renesas,ipmmu-vmsa.txt
+index 67d00c2..c6e2d85 100644
+--- a/Documentation/devicetree/bindings/iommu/renesas,ipmmu-vmsa.txt
++++ b/Documentation/devicetree/bindings/iommu/renesas,ipmmu-vmsa.txt
+@@ -21,6 +21,7 @@ Required Properties:
+ - "renesas,ipmmu-r8a7796" for the R8A7796 (R-Car M3-W) IPMMU.
+ - "renesas,ipmmu-r8a77965" for the R8A77965 (R-Car M3-N) IPMMU.
+ - "renesas,ipmmu-r8a77970" for the R8A77970 (R-Car V3M) IPMMU.
++ - "renesas,ipmmu-r8a77980" for the R8A77980 (R-Car V3H) IPMMU.
+ - "renesas,ipmmu-r8a77990" for the R8A77990 (R-Car E3) IPMMU.
+ - "renesas,ipmmu-r8a77995" for the R8A77995 (R-Car D3) IPMMU.
+ - "renesas,ipmmu-vmsa" for generic R-Car Gen2 or RZ/G1 VMSA-compatible
+--
+2.7.4
+
diff --git a/bsp/meta-rcar/meta-rcar-gen3-adas/recipes-kernel/linux/linux-renesas/0199-dt-bindings-phy-Renesas-R-Car-Gen3-PCIe-PHY-bindings.patch b/bsp/meta-rcar/meta-rcar-gen3-adas/recipes-kernel/linux/linux-renesas/0199-dt-bindings-phy-Renesas-R-Car-Gen3-PCIe-PHY-bindings.patch
new file mode 100644
index 00000000..42a7407e
--- /dev/null
+++ b/bsp/meta-rcar/meta-rcar-gen3-adas/recipes-kernel/linux/linux-renesas/0199-dt-bindings-phy-Renesas-R-Car-Gen3-PCIe-PHY-bindings.patch
@@ -0,0 +1,54 @@
+From d181283b4a17b6109aff85b02952f49642ec63e0 Mon Sep 17 00:00:00 2001
+From: Sergei Shtylyov <sergei.shtylyov@cogentembedded.com>
+Date: Sun, 10 Jun 2018 21:22:46 +0300
+Subject: [PATCH 019/211] dt-bindings: phy: Renesas R-Car Gen3 PCIe PHY
+ bindings
+
+This PHY is still mostly undocumented -- the only documented registers
+exist on R-Car V3H (R8A77980) SoC. Add the corresponding device tree
+bindings.
+
+Signed-off-by: Sergei Shtylyov <sergei.shtylyov@cogentembedded.com>
+Reviewed-by: Simon Horman <horms+renesas@verge.net.au>
+Reviewed-by: Rob Herring <robh@kernel.org>
+Signed-off-by: Kishon Vijay Abraham I <kishon@ti.com>
+(cherry picked from commit 4fa88cd3370ed33119863747a4db7f5e3f1dc308)
+Signed-off-by: Valentine Barshak <valentine.barshak@cogentembedded.com>
+---
+ .../devicetree/bindings/phy/rcar-gen3-phy-pcie.txt | 24 ++++++++++++++++++++++
+ 1 file changed, 24 insertions(+)
+ create mode 100644 Documentation/devicetree/bindings/phy/rcar-gen3-phy-pcie.txt
+
+diff --git a/Documentation/devicetree/bindings/phy/rcar-gen3-phy-pcie.txt b/Documentation/devicetree/bindings/phy/rcar-gen3-phy-pcie.txt
+new file mode 100644
+index 0000000..63853b3
+--- /dev/null
++++ b/Documentation/devicetree/bindings/phy/rcar-gen3-phy-pcie.txt
+@@ -0,0 +1,24 @@
++* Renesas R-Car generation 3 PCIe PHY
++
++This file provides information on what the device node for the R-Car
++generation 3 PCIe PHY contains.
++
++Required properties:
++- compatible: "renesas,r8a77980-pcie-phy" if the device is a part of the
++ R8A77980 SoC.
++- reg: offset and length of the register block.
++- clocks: clock phandle and specifier pair.
++- power-domains: power domain phandle and specifier pair.
++- resets: reset phandle and specifier pair.
++- #phy-cells: see phy-bindings.txt in the same directory, must be <0>.
++
++Example (R-Car V3H):
++
++ pcie-phy@e65d0000 {
++ compatible = "renesas,r8a77980-pcie-phy";
++ reg = <0 0xe65d0000 0 0x8000>;
++ #phy-cells = <0>;
++ clocks = <&cpg CPG_MOD 319>;
++ power-domains = <&sysc 32>;
++ resets = <&cpg 319>;
++ };
+--
+2.7.4
+
diff --git a/bsp/meta-rcar/meta-rcar-gen3-adas/recipes-kernel/linux/linux-renesas/0200-phy-Renesas-R-Car-gen3-PCIe-PHY-driver.patch b/bsp/meta-rcar/meta-rcar-gen3-adas/recipes-kernel/linux/linux-renesas/0200-phy-Renesas-R-Car-gen3-PCIe-PHY-driver.patch
new file mode 100644
index 00000000..c1146651
--- /dev/null
+++ b/bsp/meta-rcar/meta-rcar-gen3-adas/recipes-kernel/linux/linux-renesas/0200-phy-Renesas-R-Car-gen3-PCIe-PHY-driver.patch
@@ -0,0 +1,208 @@
+From 1136cf52385aa768427840ebcbc457284d42b8a2 Mon Sep 17 00:00:00 2001
+From: Sergei Shtylyov <sergei.shtylyov@cogentembedded.com>
+Date: Sun, 10 Jun 2018 21:24:13 +0300
+Subject: [PATCH 020/211] phy: Renesas R-Car gen3 PCIe PHY driver
+
+This PHY is still mostly undocumented -- the only documented registers
+exist on R-Car V3H (R8A77980) SoC where this PHY stays in a powered-down
+state after a reset and thus we must power it up for PCIe to work...
+
+Signed-off-by: Sergei Shtylyov <sergei.shtylyov@cogentembedded.com>
+Reviewed-by: Simon Horman <horms+renesas@verge.net.au>
+Signed-off-by: Kishon Vijay Abraham I <kishon@ti.com>
+(cherry picked from commit 2ce7f2f425ef7464a2a9a872d2e9acad49e6cb3e)
+Signed-off-by: Valentine Barshak <valentine.barshak@cogentembedded.com>
+---
+ drivers/phy/renesas/Kconfig | 7 ++
+ drivers/phy/renesas/Makefile | 1 +
+ drivers/phy/renesas/phy-rcar-gen3-pcie.c | 151 +++++++++++++++++++++++++++++++
+ 3 files changed, 159 insertions(+)
+ create mode 100644 drivers/phy/renesas/phy-rcar-gen3-pcie.c
+
+diff --git a/drivers/phy/renesas/Kconfig b/drivers/phy/renesas/Kconfig
+index c845fac..4bd390c 100644
+--- a/drivers/phy/renesas/Kconfig
++++ b/drivers/phy/renesas/Kconfig
+@@ -8,6 +8,13 @@ config PHY_RCAR_GEN2
+ help
+ Support for USB PHY found on Renesas R-Car generation 2 SoCs.
+
++config PHY_RCAR_GEN3_PCIE
++ tristate "Renesas R-Car generation 3 PCIe PHY driver"
++ depends on ARCH_RENESAS
++ select GENERIC_PHY
++ help
++ Support for the PCIe PHY found on Renesas R-Car generation 3 SoCs.
++
+ config PHY_RCAR_GEN3_USB2
+ tristate "Renesas R-Car generation 3 USB 2.0 PHY driver"
+ depends on ARCH_RENESAS
+diff --git a/drivers/phy/renesas/Makefile b/drivers/phy/renesas/Makefile
+index 8b60259..4b76fc4 100644
+--- a/drivers/phy/renesas/Makefile
++++ b/drivers/phy/renesas/Makefile
+@@ -1,3 +1,4 @@
+ obj-$(CONFIG_PHY_RCAR_GEN2) += phy-rcar-gen2.o
++obj-$(CONFIG_PHY_RCAR_GEN3_PCIE) += phy-rcar-gen3-pcie.o
+ obj-$(CONFIG_PHY_RCAR_GEN3_USB2) += phy-rcar-gen3-usb2.o
+ obj-$(CONFIG_PHY_RCAR_GEN3_USB3) += phy-rcar-gen3-usb3.o
+diff --git a/drivers/phy/renesas/phy-rcar-gen3-pcie.c b/drivers/phy/renesas/phy-rcar-gen3-pcie.c
+new file mode 100644
+index 0000000..c4e4aa2
+--- /dev/null
++++ b/drivers/phy/renesas/phy-rcar-gen3-pcie.c
+@@ -0,0 +1,151 @@
++// SPDX-License-Identifier: GPL-2.0
++/*
++ * Renesas R-Car Gen3 PCIe PHY driver
++ *
++ * Copyright (C) 2018 Cogent Embedded, Inc.
++ */
++
++#include <linux/clk.h>
++#include <linux/io.h>
++#include <linux/module.h>
++#include <linux/of.h>
++#include <linux/phy/phy.h>
++#include <linux/of_device.h>
++#include <linux/platform_device.h>
++#include <linux/spinlock.h>
++
++#define PHY_CTRL 0x4000 /* R8A77980 only */
++
++/* PHY control register (PHY_CTRL) */
++#define PHY_CTRL_PHY_PWDN BIT(2)
++
++struct rcar_gen3_phy {
++ struct phy *phy;
++ spinlock_t lock;
++ void __iomem *base;
++};
++
++static void rcar_gen3_phy_pcie_modify_reg(struct phy *p, unsigned int reg,
++ u32 clear, u32 set)
++{
++ struct rcar_gen3_phy *phy = phy_get_drvdata(p);
++ void __iomem *base = phy->base;
++ unsigned long flags;
++ u32 value;
++
++ spin_lock_irqsave(&phy->lock, flags);
++
++ value = readl(base + reg);
++ value &= ~clear;
++ value |= set;
++ writel(value, base + reg);
++
++ spin_unlock_irqrestore(&phy->lock, flags);
++}
++
++static int r8a77980_phy_pcie_power_on(struct phy *p)
++{
++ /* Power on the PCIe PHY */
++ rcar_gen3_phy_pcie_modify_reg(p, PHY_CTRL, PHY_CTRL_PHY_PWDN, 0);
++
++ return 0;
++}
++
++static int r8a77980_phy_pcie_power_off(struct phy *p)
++{
++ /* Power off the PCIe PHY */
++ rcar_gen3_phy_pcie_modify_reg(p, PHY_CTRL, 0, PHY_CTRL_PHY_PWDN);
++
++ return 0;
++}
++
++static const struct phy_ops r8a77980_phy_pcie_ops = {
++ .power_on = r8a77980_phy_pcie_power_on,
++ .power_off = r8a77980_phy_pcie_power_off,
++ .owner = THIS_MODULE,
++};
++
++static const struct of_device_id rcar_gen3_phy_pcie_match_table[] = {
++ { .compatible = "renesas,r8a77980-pcie-phy" },
++ { }
++};
++MODULE_DEVICE_TABLE(of, rcar_gen3_phy_pcie_match_table);
++
++static int rcar_gen3_phy_pcie_probe(struct platform_device *pdev)
++{
++ struct device *dev = &pdev->dev;
++ struct phy_provider *provider;
++ struct rcar_gen3_phy *phy;
++ struct resource *res;
++ void __iomem *base;
++ int error;
++
++ if (!dev->of_node) {
++ dev_err(dev,
++ "This driver must only be instantiated from the device tree\n");
++ return -EINVAL;
++ }
++
++ res = platform_get_resource(pdev, IORESOURCE_MEM, 0);
++ base = devm_ioremap_resource(dev, res);
++ if (IS_ERR(base))
++ return PTR_ERR(base);
++
++ phy = devm_kzalloc(dev, sizeof(*phy), GFP_KERNEL);
++ if (!phy)
++ return -ENOMEM;
++
++ spin_lock_init(&phy->lock);
++
++ phy->base = base;
++
++ /*
++ * devm_phy_create() will call pm_runtime_enable(&phy->dev);
++ * And then, phy-core will manage runtime PM for this device.
++ */
++ pm_runtime_enable(dev);
++
++ phy->phy = devm_phy_create(dev, NULL, &r8a77980_phy_pcie_ops);
++ if (IS_ERR(phy->phy)) {
++ dev_err(dev, "Failed to create PCIe PHY\n");
++ error = PTR_ERR(phy->phy);
++ goto error;
++ }
++ phy_set_drvdata(phy->phy, phy);
++
++ provider = devm_of_phy_provider_register(dev, of_phy_simple_xlate);
++ if (IS_ERR(provider)) {
++ dev_err(dev, "Failed to register PHY provider\n");
++ error = PTR_ERR(provider);
++ goto error;
++ }
++
++ return 0;
++
++error:
++ pm_runtime_disable(dev);
++
++ return error;
++}
++
++static int rcar_gen3_phy_pcie_remove(struct platform_device *pdev)
++{
++ pm_runtime_disable(&pdev->dev);
++
++ return 0;
++};
++
++static struct platform_driver rcar_gen3_phy_driver = {
++ .driver = {
++ .name = "phy_rcar_gen3_pcie",
++ .of_match_table = rcar_gen3_phy_pcie_match_table,
++ },
++ .probe = rcar_gen3_phy_pcie_probe,
++ .remove = rcar_gen3_phy_pcie_remove,
++};
++
++module_platform_driver(rcar_gen3_phy_driver);
++
++MODULE_LICENSE("GPL v2");
++MODULE_DESCRIPTION("Renesas R-Car Gen3 PCIe PHY");
++MODULE_AUTHOR("Sergei Shtylyov <sergei.shtylyov@cogentembedded.com>");
+--
+2.7.4
+
diff --git a/bsp/meta-rcar/meta-rcar-gen3-adas/recipes-kernel/linux/linux-renesas/0201-dt-bindings-irqchip-renesas-irqc-Document-r8a77980-s.patch b/bsp/meta-rcar/meta-rcar-gen3-adas/recipes-kernel/linux/linux-renesas/0201-dt-bindings-irqchip-renesas-irqc-Document-r8a77980-s.patch
new file mode 100644
index 00000000..7d337f0c
--- /dev/null
+++ b/bsp/meta-rcar/meta-rcar-gen3-adas/recipes-kernel/linux/linux-renesas/0201-dt-bindings-irqchip-renesas-irqc-Document-r8a77980-s.patch
@@ -0,0 +1,33 @@
+From ed1df4bb5937065d06cd7893d7ee3bdd5324eb7e Mon Sep 17 00:00:00 2001
+From: Sergei Shtylyov <sergei.shtylyov@cogentembedded.com>
+Date: Tue, 17 Jul 2018 22:23:17 +0300
+Subject: [PATCH 021/211] dt-bindings: irqchip: renesas-irqc: Document r8a77980
+ support
+
+Document R-Car V3H (AKA R8A77980) SoC bindings.
+
+Reviewed-by: Geert Uytterhoeven <geert+renesas@glider.be>
+Reviewed-by: Simon Horman <horms+renesas@verge.net.au>
+Signed-off-by: Sergei Shtylyov <sergei.shtylyov@cogentembedded.com>
+Signed-off-by: Marc Zyngier <marc.zyngier@arm.com>
+(cherry picked from commit d5fd14803573e57941100d11dd9cf3e84d17e180)
+Signed-off-by: Valentine Barshak <valentine.barshak@cogentembedded.com>
+---
+ Documentation/devicetree/bindings/interrupt-controller/renesas,irqc.txt | 1 +
+ 1 file changed, 1 insertion(+)
+
+diff --git a/Documentation/devicetree/bindings/interrupt-controller/renesas,irqc.txt b/Documentation/devicetree/bindings/interrupt-controller/renesas,irqc.txt
+index 20f121d..c389791 100644
+--- a/Documentation/devicetree/bindings/interrupt-controller/renesas,irqc.txt
++++ b/Documentation/devicetree/bindings/interrupt-controller/renesas,irqc.txt
+@@ -16,6 +16,7 @@ Required properties:
+ - "renesas,intc-ex-r8a7796" (R-Car M3-W)
+ - "renesas,intc-ex-r8a77965" (R-Car M3-N)
+ - "renesas,intc-ex-r8a77970" (R-Car V3M)
++ - "renesas,intc-ex-r8a77980" (R-Car V3H)
+ - "renesas,intc-ex-r8a77995" (R-Car D3)
+ - #interrupt-cells: has to be <2>: an interrupt index and flags, as defined in
+ interrupts.txt in this directory
+--
+2.7.4
+
diff --git a/bsp/meta-rcar/meta-rcar-gen3-adas/recipes-kernel/linux/linux-renesas/0202-arm64-dts-renesas-r8a77980-add-INTC-EX-support.patch b/bsp/meta-rcar/meta-rcar-gen3-adas/recipes-kernel/linux/linux-renesas/0202-arm64-dts-renesas-r8a77980-add-INTC-EX-support.patch
new file mode 100644
index 00000000..f8b0da52
--- /dev/null
+++ b/bsp/meta-rcar/meta-rcar-gen3-adas/recipes-kernel/linux/linux-renesas/0202-arm64-dts-renesas-r8a77980-add-INTC-EX-support.patch
@@ -0,0 +1,49 @@
+From 090f8ee8e91a9cde0b4bdc59800db219aaa83951 Mon Sep 17 00:00:00 2001
+From: Sergei Shtylyov <sergei.shtylyov@cogentembedded.com>
+Date: Tue, 17 Jul 2018 23:08:27 +0300
+Subject: [PATCH 022/211] arm64: dts: renesas: r8a77980: add INTC-EX support
+
+Describe the INTC-EX interrupt controller in the R8A77980 device tree.
+
+Based on the original (and large) patch by Vladimir Barinov.
+
+Signed-off-by: Vladimir Barinov <vladimir.barinov@cogentembedded.com>
+Signed-off-by: Sergei Shtylyov <sergei.shtylyov@cogentembedded.com>
+Reviewed-by: Geert Uytterhoeven <geert+renesas@glider.be>
+Signed-off-by: Simon Horman <horms+renesas@verge.net.au>
+(cherry picked from commit 9a6c158f62ccdd37c921ec8b1484418bad5f7984)
+Signed-off-by: Valentine Barshak <valentine.barshak@cogentembedded.com>
+---
+ arch/arm64/boot/dts/renesas/r8a77980.dtsi | 16 ++++++++++++++++
+ 1 file changed, 16 insertions(+)
+
+diff --git a/arch/arm64/boot/dts/renesas/r8a77980.dtsi b/arch/arm64/boot/dts/renesas/r8a77980.dtsi
+index 873b80a..5bd9628 100644
+--- a/arch/arm64/boot/dts/renesas/r8a77980.dtsi
++++ b/arch/arm64/boot/dts/renesas/r8a77980.dtsi
+@@ -234,6 +234,22 @@
+ #power-domain-cells = <1>;
+ };
+
++ intc_ex: interrupt-controller@e61c0000 {
++ compatible = "renesas,intc-ex-r8a77980", "renesas,irqc";
++ #interrupt-cells = <2>;
++ interrupt-controller;
++ reg = <0 0xe61c0000 0 0x200>;
++ interrupts = <GIC_SPI 0 IRQ_TYPE_LEVEL_HIGH
++ GIC_SPI 1 IRQ_TYPE_LEVEL_HIGH
++ GIC_SPI 2 IRQ_TYPE_LEVEL_HIGH
++ GIC_SPI 3 IRQ_TYPE_LEVEL_HIGH
++ GIC_SPI 18 IRQ_TYPE_LEVEL_HIGH
++ GIC_SPI 161 IRQ_TYPE_LEVEL_HIGH>;
++ clocks = <&cpg CPG_MOD 407>;
++ power-domains = <&sysc R8A77980_PD_ALWAYS_ON>;
++ resets = <&cpg 407>;
++ };
++
+ i2c0: i2c@e6500000 {
+ compatible = "renesas,i2c-r8a77980",
+ "renesas,rcar-gen3-i2c";
+--
+2.7.4
+
diff --git a/bsp/meta-rcar/meta-rcar-gen3-adas/recipes-kernel/linux/linux-renesas/0203-net-phy-allow-scanning-busses-with-missing-phys.patch b/bsp/meta-rcar/meta-rcar-gen3-adas/recipes-kernel/linux/linux-renesas/0203-net-phy-allow-scanning-busses-with-missing-phys.patch
new file mode 100644
index 00000000..5b80edca
--- /dev/null
+++ b/bsp/meta-rcar/meta-rcar-gen3-adas/recipes-kernel/linux/linux-renesas/0203-net-phy-allow-scanning-busses-with-missing-phys.patch
@@ -0,0 +1,50 @@
+From c6eac988444567bfb55644206d8a55f7e78b1df9 Mon Sep 17 00:00:00 2001
+From: Alexandre Belloni <alexandre.belloni@bootlin.com>
+Date: Tue, 24 Apr 2018 18:09:04 +0200
+Subject: [PATCH 023/211] net: phy: allow scanning busses with missing phys
+
+Some MDIO busses will error out when trying to read a phy address with no
+phy present at that address. In that case, probing the bus will fail
+because __mdiobus_register() is scanning the bus for all possible phys
+addresses.
+
+In case MII_PHYSID1 returns -EIO or -ENODEV, consider there is no phy at
+this address and set the phy ID to 0xffffffff which is then properly
+handled in get_phy_device().
+
+Suggested-by: Andrew Lunn <andrew@lunn.ch>
+Signed-off-by: Alexandre Belloni <alexandre.belloni@bootlin.com>
+Reviewed-by: Florian Fainelli <f.fainelli@gmail.com>
+Signed-off-by: David S. Miller <davem@davemloft.net>
+(cherry picked from commit 02a6efcab675fe32815d824837784c3f42a7d892)
+Signed-off-by: Valentine Barshak <valentine.barshak@cogentembedded.com>
+---
+ drivers/net/phy/phy_device.c | 11 ++++++++++-
+ 1 file changed, 10 insertions(+), 1 deletion(-)
+
+diff --git a/drivers/net/phy/phy_device.c b/drivers/net/phy/phy_device.c
+index eff5327..64e5ed9 100644
+--- a/drivers/net/phy/phy_device.c
++++ b/drivers/net/phy/phy_device.c
+@@ -536,8 +536,17 @@ static int get_phy_id(struct mii_bus *bus, int addr, u32 *phy_id,
+
+ /* Grab the bits from PHYIR1, and put them in the upper half */
+ phy_reg = mdiobus_read(bus, addr, MII_PHYSID1);
+- if (phy_reg < 0)
++ if (phy_reg < 0) {
++ /* if there is no device, return without an error so scanning
++ * the bus works properly
++ */
++ if (phy_reg == -EIO || phy_reg == -ENODEV) {
++ *phy_id = 0xffffffff;
++ return 0;
++ }
++
+ return -EIO;
++ }
+
+ *phy_id = (phy_reg & 0xffff) << 16;
+
+--
+2.7.4
+
diff --git a/bsp/meta-rcar/meta-rcar-gen3-adas/recipes-kernel/linux/linux-renesas/0204-arm64-dts-renesas-r8a77980-add-RWDT-support.patch b/bsp/meta-rcar/meta-rcar-gen3-adas/recipes-kernel/linux/linux-renesas/0204-arm64-dts-renesas-r8a77980-add-RWDT-support.patch
new file mode 100644
index 00000000..419cc988
--- /dev/null
+++ b/bsp/meta-rcar/meta-rcar-gen3-adas/recipes-kernel/linux/linux-renesas/0204-arm64-dts-renesas-r8a77980-add-RWDT-support.patch
@@ -0,0 +1,79 @@
+From 1193ccc27a8321a628c1003322c7bc093565817d Mon Sep 17 00:00:00 2001
+From: Sergei Shtylyov <sergei.shtylyov@cogentembedded.com>
+Date: Fri, 20 Jul 2018 22:21:45 +0300
+Subject: [PATCH 024/211] arm64: dts: renesas: r8a77980: add RWDT support
+
+Describe RWDT in the R8A77980 SoC device tree.
+
+Enable RWDT on the Condor and V3H Starter Kit boards.
+
+Based on the original (and large) patch by Vladimir Barinov.
+
+Signed-off-by: Vladimir Barinov <vladimir.barinov@cogentembedded.com>
+Signed-off-by: Sergei Shtylyov <sergei.shtylyov@cogentembedded.com>
+Reviewed-by: Geert Uytterhoeven <geert+renesas@glider.be>
+Signed-off-by: Simon Horman <horms+renesas@verge.net.au>
+(cherry picked from commit bcee502ceb6c0dcbc7ccd460ed7040c3d6998c3e)
+Signed-off-by: Valentine Barshak <valentine.barshak@cogentembedded.com>
+---
+ arch/arm64/boot/dts/renesas/r8a77980-condor.dts | 5 +++++
+ arch/arm64/boot/dts/renesas/r8a77980-v3hsk.dts | 5 +++++
+ arch/arm64/boot/dts/renesas/r8a77980.dtsi | 10 ++++++++++
+ 3 files changed, 20 insertions(+)
+
+diff --git a/arch/arm64/boot/dts/renesas/r8a77980-condor.dts b/arch/arm64/boot/dts/renesas/r8a77980-condor.dts
+index 9f25c40..494f4ef 100644
+--- a/arch/arm64/boot/dts/renesas/r8a77980-condor.dts
++++ b/arch/arm64/boot/dts/renesas/r8a77980-condor.dts
+@@ -156,6 +156,11 @@
+ };
+ };
+
++&rwdt {
++ timeout-sec = <60>;
++ status = "okay";
++};
++
+ &scif0 {
+ pinctrl-0 = <&scif0_pins>, <&scif_clk_pins>;
+ pinctrl-names = "default";
+diff --git a/arch/arm64/boot/dts/renesas/r8a77980-v3hsk.dts b/arch/arm64/boot/dts/renesas/r8a77980-v3hsk.dts
+index 9dac42f..9147d85 100644
+--- a/arch/arm64/boot/dts/renesas/r8a77980-v3hsk.dts
++++ b/arch/arm64/boot/dts/renesas/r8a77980-v3hsk.dts
+@@ -71,6 +71,11 @@
+ };
+ };
+
++&rwdt {
++ timeout-sec = <60>;
++ status = "okay";
++};
++
+ &scif0 {
+ pinctrl-0 = <&scif0_pins>, <&scif_clk_pins>;
+ pinctrl-names = "default";
+diff --git a/arch/arm64/boot/dts/renesas/r8a77980.dtsi b/arch/arm64/boot/dts/renesas/r8a77980.dtsi
+index 5bd9628..d3532fd 100644
+--- a/arch/arm64/boot/dts/renesas/r8a77980.dtsi
++++ b/arch/arm64/boot/dts/renesas/r8a77980.dtsi
+@@ -118,6 +118,16 @@
+ #size-cells = <2>;
+ ranges;
+
++ rwdt: watchdog@e6020000 {
++ compatible = "renesas,r8a77980-wdt",
++ "renesas,rcar-gen3-wdt";
++ reg = <0 0xe6020000 0 0x0c>;
++ clocks = <&cpg CPG_MOD 402>;
++ power-domains = <&sysc R8A77980_PD_ALWAYS_ON>;
++ resets = <&cpg 402>;
++ status = "disabled";
++ };
++
+ gpio0: gpio@e6050000 {
+ compatible = "renesas,gpio-r8a77980",
+ "renesas,rcar-gen3-gpio";
+--
+2.7.4
+
diff --git a/bsp/meta-rcar/meta-rcar-gen3-adas/recipes-kernel/linux/linux-renesas/0205-arm64-enable-CMT-TMU-support-for-Renesas-SoC.patch b/bsp/meta-rcar/meta-rcar-gen3-adas/recipes-kernel/linux/linux-renesas/0205-arm64-enable-CMT-TMU-support-for-Renesas-SoC.patch
new file mode 100644
index 00000000..7f044095
--- /dev/null
+++ b/bsp/meta-rcar/meta-rcar-gen3-adas/recipes-kernel/linux/linux-renesas/0205-arm64-enable-CMT-TMU-support-for-Renesas-SoC.patch
@@ -0,0 +1,33 @@
+From 777db7fda6f37341c0fca7afd0973c2196229453 Mon Sep 17 00:00:00 2001
+From: Sergei Shtylyov <sergei.shtylyov@cogentembedded.com>
+Date: Fri, 31 Aug 2018 22:54:42 +0300
+Subject: [PATCH 025/211] arm64: enable CMT/TMU support for Renesas SoC
+
+Renesas R-Car gen3 SoCs have both CMT and TMU timers, so we have to enable
+building them in Kconfig.platforms (as they don't normally have the prompts
+in Kconfig).
+
+Signed-off-by: Sergei Shtylyov <sergei.shtylyov@cogentembedded.com>
+Signed-off-by: Simon Horman <horms+renesas@verge.net.au>
+(cherry picked from commit c1801ad028456267dde2111e470ac43f7882debf)
+Signed-off-by: Valentine Barshak <valentine.barshak@cogentembedded.com>
+---
+ arch/arm64/Kconfig.platforms | 2 ++
+ 1 file changed, 2 insertions(+)
+
+diff --git a/arch/arm64/Kconfig.platforms b/arch/arm64/Kconfig.platforms
+index 20ef69a..aba998f 100644
+--- a/arch/arm64/Kconfig.platforms
++++ b/arch/arm64/Kconfig.platforms
+@@ -171,6 +171,8 @@ config ARCH_RENESAS
+ select PM_GENERIC_DOMAINS
+ select RENESAS_IRQC
+ select SOC_BUS
++ select SYS_SUPPORTS_SH_CMT
++ select SYS_SUPPORTS_SH_TMU
+ help
+ This enables support for the ARMv8 based Renesas SoCs.
+
+--
+2.7.4
+
diff --git a/bsp/meta-rcar/meta-rcar-gen3-adas/recipes-kernel/linux/linux-renesas/0206-arm64-dts-renesas-r8a77980-add-Cortex-A53-PMU-suppor.patch b/bsp/meta-rcar/meta-rcar-gen3-adas/recipes-kernel/linux/linux-renesas/0206-arm64-dts-renesas-r8a77980-add-Cortex-A53-PMU-suppor.patch
new file mode 100644
index 00000000..d2950867
--- /dev/null
+++ b/bsp/meta-rcar/meta-rcar-gen3-adas/recipes-kernel/linux/linux-renesas/0206-arm64-dts-renesas-r8a77980-add-Cortex-A53-PMU-suppor.patch
@@ -0,0 +1,44 @@
+From 9f3f0eecc9e1ff190aeffd4705b5fa0190c660c4 Mon Sep 17 00:00:00 2001
+From: Sergei Shtylyov <sergei.shtylyov@cogentembedded.com>
+Date: Wed, 25 Jul 2018 19:43:41 +0300
+Subject: [PATCH 026/211] arm64: dts: renesas: r8a77980: add Cortex-A53 PMU
+ support
+
+Describe the performance monitor unit (PMU) for the Cortex-A53 cores in
+the R8A77980 SoC's device tree.
+
+Based on the original (and large) patch by Vladimir Barinov.
+
+Signed-off-by: Vladimir Barinov <vladimir.barinov@cogentembedded.com>
+Signed-off-by: Sergei Shtylyov <sergei.shtylyov@cogentembedded.com>
+Reviewed-by: Geert Uytterhoeven <geert+renesas@glider.be>
+Signed-off-by: Simon Horman <horms+renesas@verge.net.au>
+(cherry picked from commit 0dba24a8e17dc60dba5882b907e923fcf0d3d1e7)
+Signed-off-by: Valentine Barshak <valentine.barshak@cogentembedded.com>
+---
+ arch/arm64/boot/dts/renesas/r8a77980.dtsi | 9 +++++++++
+ 1 file changed, 9 insertions(+)
+
+diff --git a/arch/arm64/boot/dts/renesas/r8a77980.dtsi b/arch/arm64/boot/dts/renesas/r8a77980.dtsi
+index d3532fd..1013da3 100644
+--- a/arch/arm64/boot/dts/renesas/r8a77980.dtsi
++++ b/arch/arm64/boot/dts/renesas/r8a77980.dtsi
+@@ -98,6 +98,15 @@
+ clock-frequency = <0>;
+ };
+
++ pmu_a53 {
++ compatible = "arm,cortex-a53-pmu";
++ interrupts-extended = <&gic GIC_SPI 84 IRQ_TYPE_LEVEL_HIGH>,
++ <&gic GIC_SPI 85 IRQ_TYPE_LEVEL_HIGH>,
++ <&gic GIC_SPI 86 IRQ_TYPE_LEVEL_HIGH>,
++ <&gic GIC_SPI 87 IRQ_TYPE_LEVEL_HIGH>;
++ interrupt-affinity = <&a53_0>, <&a53_1>, <&a53_2>, <&a53_3>;
++ };
++
+ psci {
+ compatible = "arm,psci-1.0", "arm,psci-0.2";
+ method = "smc";
+--
+2.7.4
+
diff --git a/bsp/meta-rcar/meta-rcar-gen3-adas/recipes-kernel/linux/linux-renesas/0207-arm64-dts-renesas-r8a77980-move-IPMMU-nodes.patch b/bsp/meta-rcar/meta-rcar-gen3-adas/recipes-kernel/linux/linux-renesas/0207-arm64-dts-renesas-r8a77980-move-IPMMU-nodes.patch
new file mode 100644
index 00000000..ab198e2e
--- /dev/null
+++ b/bsp/meta-rcar/meta-rcar-gen3-adas/recipes-kernel/linux/linux-renesas/0207-arm64-dts-renesas-r8a77980-move-IPMMU-nodes.patch
@@ -0,0 +1,164 @@
+From bca8873bffd97737ab712a4962ee12c48f5a0518 Mon Sep 17 00:00:00 2001
+From: Sergei Shtylyov <sergei.shtylyov@cogentembedded.com>
+Date: Thu, 26 Jul 2018 21:51:18 +0300
+Subject: [PATCH 027/211] arm64: dts: renesas: r8a77980: move IPMMU nodes
+
+The IPMMU nodes should follow the GEther node, not the CAN-FD node,
+according to the <unit-address> part of the startng IPMMU-DS1 node.
+While moving the nodes, also do sort them by label alphanumerically...
+
+Signed-off-by: Sergei Shtylyov <sergei.shtylyov@cogentembedded.com>
+Signed-off-by: Simon Horman <horms+renesas@verge.net.au>
+(cherry picked from commit f14bfabc5472ebc637a9ed8c5bc4ab7b77db209f)
+Signed-off-by: Valentine Barshak <valentine.barshak@cogentembedded.com>
+---
+ arch/arm64/boot/dts/renesas/r8a77980.dtsi | 126 +++++++++++++++---------------
+ 1 file changed, 63 insertions(+), 63 deletions(-)
+
+diff --git a/arch/arm64/boot/dts/renesas/r8a77980.dtsi b/arch/arm64/boot/dts/renesas/r8a77980.dtsi
+index 1013da3..fbfe654 100644
+--- a/arch/arm64/boot/dts/renesas/r8a77980.dtsi
++++ b/arch/arm64/boot/dts/renesas/r8a77980.dtsi
+@@ -462,69 +462,6 @@
+ };
+ };
+
+- ipmmu_ds1: mmu@e7740000 {
+- compatible = "renesas,ipmmu-r8a77980";
+- reg = <0 0xe7740000 0 0x1000>;
+- renesas,ipmmu-main = <&ipmmu_mm 0>;
+- power-domains = <&sysc R8A77980_PD_ALWAYS_ON>;
+- #iommu-cells = <1>;
+- };
+-
+- ipmmu_vip0: mmu@e7b00000 {
+- compatible = "renesas,ipmmu-r8a77980";
+- reg = <0 0xe7b00000 0 0x1000>;
+- power-domains = <&sysc R8A77980_PD_ALWAYS_ON>;
+- #iommu-cells = <1>;
+- };
+-
+- ipmmu_vip1: mmu@e7960000 {
+- compatible = "renesas,ipmmu-r8a77980";
+- reg = <0 0xe7960000 0 0x1000>;
+- power-domains = <&sysc R8A77980_PD_ALWAYS_ON>;
+- #iommu-cells = <1>;
+- };
+-
+- ipmmu_ir: mmu@ff8b0000 {
+- compatible = "renesas,ipmmu-r8a77980";
+- reg = <0 0xff8b0000 0 0x1000>;
+- renesas,ipmmu-main = <&ipmmu_mm 3>;
+- power-domains = <&sysc R8A77980_PD_A3IR>;
+- #iommu-cells = <1>;
+- };
+-
+- ipmmu_mm: mmu@e67b0000 {
+- compatible = "renesas,ipmmu-r8a77980";
+- reg = <0 0xe67b0000 0 0x1000>;
+- interrupts = <GIC_SPI 196 IRQ_TYPE_LEVEL_HIGH>,
+- <GIC_SPI 197 IRQ_TYPE_LEVEL_HIGH>;
+- power-domains = <&sysc R8A77980_PD_ALWAYS_ON>;
+- #iommu-cells = <1>;
+- };
+-
+- ipmmu_rt: mmu@ffc80000 {
+- compatible = "renesas,ipmmu-r8a77980";
+- reg = <0 0xffc80000 0 0x1000>;
+- renesas,ipmmu-main = <&ipmmu_mm 10>;
+- power-domains = <&sysc R8A77980_PD_ALWAYS_ON>;
+- #iommu-cells = <1>;
+- };
+-
+- ipmmu_vc0: mmu@fe6b0000 {
+- compatible = "renesas,ipmmu-r8a77980";
+- reg = <0 0xfe6b0000 0 0x1000>;
+- renesas,ipmmu-main = <&ipmmu_mm 12>;
+- power-domains = <&sysc R8A77980_PD_ALWAYS_ON>;
+- #iommu-cells = <1>;
+- };
+-
+- ipmmu_vi0: mmu@febd0000 {
+- compatible = "renesas,ipmmu-r8a77980";
+- reg = <0 0xfebd0000 0 0x1000>;
+- renesas,ipmmu-main = <&ipmmu_mm 14>;
+- power-domains = <&sysc R8A77980_PD_ALWAYS_ON>;
+- #iommu-cells = <1>;
+- };
+-
+ avb: ethernet@e6800000 {
+ compatible = "renesas,etheravb-r8a77980",
+ "renesas,etheravb-rcar-gen3";
+@@ -722,6 +659,69 @@
+ status = "disabled";
+ };
+
++ ipmmu_ds1: mmu@e7740000 {
++ compatible = "renesas,ipmmu-r8a77980";
++ reg = <0 0xe7740000 0 0x1000>;
++ renesas,ipmmu-main = <&ipmmu_mm 0>;
++ power-domains = <&sysc R8A77980_PD_ALWAYS_ON>;
++ #iommu-cells = <1>;
++ };
++
++ ipmmu_ir: mmu@ff8b0000 {
++ compatible = "renesas,ipmmu-r8a77980";
++ reg = <0 0xff8b0000 0 0x1000>;
++ renesas,ipmmu-main = <&ipmmu_mm 3>;
++ power-domains = <&sysc R8A77980_PD_A3IR>;
++ #iommu-cells = <1>;
++ };
++
++ ipmmu_mm: mmu@e67b0000 {
++ compatible = "renesas,ipmmu-r8a77980";
++ reg = <0 0xe67b0000 0 0x1000>;
++ interrupts = <GIC_SPI 196 IRQ_TYPE_LEVEL_HIGH>,
++ <GIC_SPI 197 IRQ_TYPE_LEVEL_HIGH>;
++ power-domains = <&sysc R8A77980_PD_ALWAYS_ON>;
++ #iommu-cells = <1>;
++ };
++
++ ipmmu_rt: mmu@ffc80000 {
++ compatible = "renesas,ipmmu-r8a77980";
++ reg = <0 0xffc80000 0 0x1000>;
++ renesas,ipmmu-main = <&ipmmu_mm 10>;
++ power-domains = <&sysc R8A77980_PD_ALWAYS_ON>;
++ #iommu-cells = <1>;
++ };
++
++ ipmmu_vc0: mmu@fe6b0000 {
++ compatible = "renesas,ipmmu-r8a77980";
++ reg = <0 0xfe6b0000 0 0x1000>;
++ renesas,ipmmu-main = <&ipmmu_mm 12>;
++ power-domains = <&sysc R8A77980_PD_ALWAYS_ON>;
++ #iommu-cells = <1>;
++ };
++
++ ipmmu_vi0: mmu@febd0000 {
++ compatible = "renesas,ipmmu-r8a77980";
++ reg = <0 0xfebd0000 0 0x1000>;
++ renesas,ipmmu-main = <&ipmmu_mm 14>;
++ power-domains = <&sysc R8A77980_PD_ALWAYS_ON>;
++ #iommu-cells = <1>;
++ };
++
++ ipmmu_vip0: mmu@e7b00000 {
++ compatible = "renesas,ipmmu-r8a77980";
++ reg = <0 0xe7b00000 0 0x1000>;
++ power-domains = <&sysc R8A77980_PD_ALWAYS_ON>;
++ #iommu-cells = <1>;
++ };
++
++ ipmmu_vip1: mmu@e7960000 {
++ compatible = "renesas,ipmmu-r8a77980";
++ reg = <0 0xe7960000 0 0x1000>;
++ power-domains = <&sysc R8A77980_PD_ALWAYS_ON>;
++ #iommu-cells = <1>;
++ };
++
+ mmc0: mmc@ee140000 {
+ compatible = "renesas,sdhi-r8a77980",
+ "renesas,rcar-gen3-sdhi";
+--
+2.7.4
+
diff --git a/bsp/meta-rcar/meta-rcar-gen3-adas/recipes-kernel/linux/linux-renesas/0208-arm64-dts-renesas-r8a779-7-8-0-move-CAN-clock-node.patch b/bsp/meta-rcar/meta-rcar-gen3-adas/recipes-kernel/linux/linux-renesas/0208-arm64-dts-renesas-r8a779-7-8-0-move-CAN-clock-node.patch
new file mode 100644
index 00000000..cddb5ab5
--- /dev/null
+++ b/bsp/meta-rcar/meta-rcar-gen3-adas/recipes-kernel/linux/linux-renesas/0208-arm64-dts-renesas-r8a779-7-8-0-move-CAN-clock-node.patch
@@ -0,0 +1,86 @@
+From d6867c17620e9e615af1aad9a100d94062ef917b Mon Sep 17 00:00:00 2001
+From: Sergei Shtylyov <sergei.shtylyov@cogentembedded.com>
+Date: Mon, 30 Jul 2018 21:22:37 +0300
+Subject: [PATCH 028/211] arm64: dts: renesas: r8a779{7|8}0: move CAN clock
+ node
+
+The CAN clock node should precede the "cpus" node in the R8A779{7|8}0
+device trees, according to the alphanumeric node sorting rule...
+
+Signed-off-by: Sergei Shtylyov <sergei.shtylyov@cogentembedded.com>
+Reviewed-by: Geert Uytterhoeven <geert+renesas@glider.be>
+Signed-off-by: Simon Horman <horms+renesas@verge.net.au>
+(cherry picked from commit 18281dec2ba086b93bee2dd5f9ee0e3633d25a8d)
+Signed-off-by: Valentine Barshak <valentine.barshak@cogentembedded.com>
+---
+ arch/arm64/boot/dts/renesas/r8a77970.dtsi | 14 +++++++-------
+ arch/arm64/boot/dts/renesas/r8a77980.dtsi | 14 +++++++-------
+ 2 files changed, 14 insertions(+), 14 deletions(-)
+
+diff --git a/arch/arm64/boot/dts/renesas/r8a77970.dtsi b/arch/arm64/boot/dts/renesas/r8a77970.dtsi
+index 3dc30a7..96feaa0 100644
+--- a/arch/arm64/boot/dts/renesas/r8a77970.dtsi
++++ b/arch/arm64/boot/dts/renesas/r8a77970.dtsi
+@@ -24,6 +24,13 @@
+ i2c4 = &i2c4;
+ };
+
++ /* External CAN clock - to be overridden by boards that provide it */
++ can_clk: can {
++ compatible = "fixed-clock";
++ #clock-cells = <0>;
++ clock-frequency = <0>;
++ };
++
+ cpus {
+ #address-cells = <1>;
+ #size-cells = <0>;
+@@ -82,13 +89,6 @@
+ method = "smc";
+ };
+
+- /* External CAN clock - to be overridden by boards that provide it */
+- can_clk: can {
+- compatible = "fixed-clock";
+- #clock-cells = <0>;
+- clock-frequency = <0>;
+- };
+-
+ /* External SCIF clock - to be overridden by boards that provide it */
+ scif_clk: scif {
+ compatible = "fixed-clock";
+diff --git a/arch/arm64/boot/dts/renesas/r8a77980.dtsi b/arch/arm64/boot/dts/renesas/r8a77980.dtsi
+index fbfe654..4bc99d6 100644
+--- a/arch/arm64/boot/dts/renesas/r8a77980.dtsi
++++ b/arch/arm64/boot/dts/renesas/r8a77980.dtsi
+@@ -25,6 +25,13 @@
+ i2c5 = &i2c5;
+ };
+
++ /* External CAN clock - to be overridden by boards that provide it */
++ can_clk: can {
++ compatible = "fixed-clock";
++ #clock-cells = <0>;
++ clock-frequency = <0>;
++ };
++
+ cpus {
+ #address-cells = <1>;
+ #size-cells = <0>;
+@@ -77,13 +84,6 @@
+ };
+ };
+
+- /* External CAN clock - to be overridden by boards that provide it */
+- can_clk: can {
+- compatible = "fixed-clock";
+- #clock-cells = <0>;
+- clock-frequency = <0>;
+- };
+-
+ extal_clk: extal {
+ compatible = "fixed-clock";
+ #clock-cells = <0>;
+--
+2.7.4
+
diff --git a/bsp/meta-rcar/meta-rcar-gen3-adas/recipes-kernel/linux/linux-renesas/0209-arm64-dts-renesas-r8a77980-add-CSI2-VIN-support.patch b/bsp/meta-rcar/meta-rcar-gen3-adas/recipes-kernel/linux/linux-renesas/0209-arm64-dts-renesas-r8a77980-add-CSI2-VIN-support.patch
new file mode 100644
index 00000000..929e9637
--- /dev/null
+++ b/bsp/meta-rcar/meta-rcar-gen3-adas/recipes-kernel/linux/linux-renesas/0209-arm64-dts-renesas-r8a77980-add-CSI2-VIN-support.patch
@@ -0,0 +1,411 @@
+From 54b520b432cd8d50d1c2a32a8f51dbef0d7a849f Mon Sep 17 00:00:00 2001
+From: Sergei Shtylyov <sergei.shtylyov@cogentembedded.com>
+Date: Mon, 6 Aug 2018 22:55:00 +0300
+Subject: [PATCH 029/211] arm64: dts: renesas: r8a77980: add CSI2/VIN support
+
+Describe the CSI2 and VIN (and their interconnections) in the R8A77980
+device tree.
+
+Signed-off-by: Sergei Shtylyov <sergei.shtylyov@cogentembedded.com>
+Signed-off-by: Simon Horman <horms+renesas@verge.net.au>
+(cherry picked from commit 3182aa4e0bf4d0ee0b29fea4b5ca21290d6d6251)
+Signed-off-by: Valentine Barshak <valentine.barshak@cogentembedded.com>
+---
+ arch/arm64/boot/dts/renesas/r8a77980.dtsi | 374 ++++++++++++++++++++++++++++++
+ 1 file changed, 374 insertions(+)
+
+diff --git a/arch/arm64/boot/dts/renesas/r8a77980.dtsi b/arch/arm64/boot/dts/renesas/r8a77980.dtsi
+index 4bc99d6..c099053 100644
+--- a/arch/arm64/boot/dts/renesas/r8a77980.dtsi
++++ b/arch/arm64/boot/dts/renesas/r8a77980.dtsi
+@@ -579,6 +579,302 @@
+ status = "disabled";
+ };
+
++ vin0: video@e6ef0000 {
++ compatible = "renesas,vin-r8a77980";
++ reg = <0 0xe6ef0000 0 0x1000>;
++ interrupts = <GIC_SPI 188 IRQ_TYPE_LEVEL_HIGH>;
++ clocks = <&cpg CPG_MOD 811>;
++ power-domains = <&sysc R8A77980_PD_ALWAYS_ON>;
++ resets = <&cpg 811>;
++ status = "disabled";
++
++ ports {
++ #address-cells = <1>;
++ #size-cells = <0>;
++
++ port@1 {
++ #address-cells = <1>;
++ #size-cells = <0>;
++
++ reg = <1>;
++
++ vin0csi40: endpoint@2 {
++ reg = <2>;
++ remote-endpoint= <&csi40vin0>;
++ };
++ };
++ };
++ };
++
++ vin1: video@e6ef1000 {
++ compatible = "renesas,vin-r8a77980";
++ reg = <0 0xe6ef1000 0 0x1000>;
++ interrupts = <GIC_SPI 189 IRQ_TYPE_LEVEL_HIGH>;
++ clocks = <&cpg CPG_MOD 810>;
++ power-domains = <&sysc R8A77980_PD_ALWAYS_ON>;
++ status = "disabled";
++ resets = <&cpg 810>;
++
++ ports {
++ #address-cells = <1>;
++ #size-cells = <0>;
++
++ port@1 {
++ #address-cells = <1>;
++ #size-cells = <0>;
++
++ reg = <1>;
++
++ vin1csi40: endpoint@2 {
++ reg = <2>;
++ remote-endpoint= <&csi40vin1>;
++ };
++ };
++ };
++ };
++
++ vin2: video@e6ef2000 {
++ compatible = "renesas,vin-r8a77980";
++ reg = <0 0xe6ef2000 0 0x1000>;
++ interrupts = <GIC_SPI 190 IRQ_TYPE_LEVEL_HIGH>;
++ clocks = <&cpg CPG_MOD 809>;
++ power-domains = <&sysc R8A77980_PD_ALWAYS_ON>;
++ resets = <&cpg 809>;
++ status = "disabled";
++
++ ports {
++ #address-cells = <1>;
++ #size-cells = <0>;
++
++ port@1 {
++ #address-cells = <1>;
++ #size-cells = <0>;
++
++ reg = <1>;
++
++ vin2csi40: endpoint@2 {
++ reg = <2>;
++ remote-endpoint= <&csi40vin2>;
++ };
++ };
++ };
++ };
++
++ vin3: video@e6ef3000 {
++ compatible = "renesas,vin-r8a77980";
++ reg = <0 0xe6ef3000 0 0x1000>;
++ interrupts = <GIC_SPI 191 IRQ_TYPE_LEVEL_HIGH>;
++ clocks = <&cpg CPG_MOD 808>;
++ power-domains = <&sysc R8A77980_PD_ALWAYS_ON>;
++ resets = <&cpg 808>;
++ status = "disabled";
++
++ ports {
++ #address-cells = <1>;
++ #size-cells = <0>;
++
++ port@1 {
++ #address-cells = <1>;
++ #size-cells = <0>;
++
++ reg = <1>;
++
++ vin3csi40: endpoint@2 {
++ reg = <2>;
++ remote-endpoint= <&csi40vin3>;
++ };
++ };
++ };
++ };
++
++ vin4: video@e6ef4000 {
++ compatible = "renesas,vin-r8a77980";
++ reg = <0 0xe6ef4000 0 0x1000>;
++ interrupts = <GIC_SPI 174 IRQ_TYPE_LEVEL_HIGH>;
++ clocks = <&cpg CPG_MOD 807>;
++ power-domains = <&sysc R8A77980_PD_ALWAYS_ON>;
++ resets = <&cpg 807>;
++ status = "disabled";
++
++ ports {
++ #address-cells = <1>;
++ #size-cells = <0>;
++
++ port@1 {
++ #address-cells = <1>;
++ #size-cells = <0>;
++
++ reg = <1>;
++
++ vin4csi41: endpoint@2 {
++ reg = <2>;
++ remote-endpoint= <&csi41vin4>;
++ };
++ };
++ };
++ };
++
++ vin5: video@e6ef5000 {
++ compatible = "renesas,vin-r8a77980";
++ reg = <0 0xe6ef5000 0 0x1000>;
++ interrupts = <GIC_SPI 175 IRQ_TYPE_LEVEL_HIGH>;
++ clocks = <&cpg CPG_MOD 806>;
++ power-domains = <&sysc R8A77980_PD_ALWAYS_ON>;
++ resets = <&cpg 806>;
++ status = "disabled";
++
++ ports {
++ #address-cells = <1>;
++ #size-cells = <0>;
++
++ port@1 {
++ #address-cells = <1>;
++ #size-cells = <0>;
++
++ reg = <1>;
++
++ vin5csi41: endpoint@2 {
++ reg = <2>;
++ remote-endpoint= <&csi41vin5>;
++ };
++ };
++ };
++ };
++
++ vin6: video@e6ef6000 {
++ compatible = "renesas,vin-r8a77980";
++ reg = <0 0xe6ef6000 0 0x1000>;
++ interrupts = <GIC_SPI 176 IRQ_TYPE_LEVEL_HIGH>;
++ clocks = <&cpg CPG_MOD 805>;
++ power-domains = <&sysc R8A77980_PD_ALWAYS_ON>;
++ resets = <&cpg 805>;
++ status = "disabled";
++
++ ports {
++ #address-cells = <1>;
++ #size-cells = <0>;
++
++ port@1 {
++ #address-cells = <1>;
++ #size-cells = <0>;
++
++ reg = <1>;
++
++ vin6csi41: endpoint@2 {
++ reg = <2>;
++ remote-endpoint= <&csi41vin6>;
++ };
++ };
++ };
++ };
++
++ vin7: video@e6ef7000 {
++ compatible = "renesas,vin-r8a77980";
++ reg = <0 0xe6ef7000 0 0x1000>;
++ interrupts = <GIC_SPI 171 IRQ_TYPE_LEVEL_HIGH>;
++ clocks = <&cpg CPG_MOD 804>;
++ power-domains = <&sysc R8A77980_PD_ALWAYS_ON>;
++ resets = <&cpg 804>;
++ status = "disabled";
++
++ ports {
++ #address-cells = <1>;
++ #size-cells = <0>;
++
++ port@1 {
++ #address-cells = <1>;
++ #size-cells = <0>;
++
++ reg = <1>;
++
++ vin7csi41: endpoint@2 {
++ reg = <2>;
++ remote-endpoint= <&csi41vin7>;
++ };
++ };
++ };
++ };
++
++ vin8: video@e6ef8000 {
++ compatible = "renesas,vin-r8a77980";
++ reg = <0 0xe6ef8000 0 0x1000>;
++ interrupts = <GIC_SPI 268 IRQ_TYPE_LEVEL_HIGH>;
++ clocks = <&cpg CPG_MOD 628>;
++ power-domains = <&sysc R8A77980_PD_ALWAYS_ON>;
++ resets = <&cpg 628>;
++ status = "disabled";
++ };
++
++ vin9: video@e6ef9000 {
++ compatible = "renesas,vin-r8a77980";
++ reg = <0 0xe6ef9000 0 0x1000>;
++ interrupts = <GIC_SPI 269 IRQ_TYPE_LEVEL_HIGH>;
++ clocks = <&cpg CPG_MOD 627>;
++ power-domains = <&sysc R8A77980_PD_ALWAYS_ON>;
++ resets = <&cpg 627>;
++ status = "disabled";
++ };
++
++ vin10: video@e6efa000 {
++ compatible = "renesas,vin-r8a77980";
++ reg = <0 0xe6efa000 0 0x1000>;
++ interrupts = <GIC_SPI 289 IRQ_TYPE_LEVEL_HIGH>;
++ clocks = <&cpg CPG_MOD 625>;
++ power-domains = <&sysc R8A77980_PD_ALWAYS_ON>;
++ resets = <&cpg 625>;
++ status = "disabled";
++ };
++
++ vin11: video@e6efb000 {
++ compatible = "renesas,vin-r8a77980";
++ reg = <0 0xe6efb000 0 0x1000>;
++ interrupts = <GIC_SPI 296 IRQ_TYPE_LEVEL_HIGH>;
++ clocks = <&cpg CPG_MOD 618>;
++ power-domains = <&sysc R8A77980_PD_ALWAYS_ON>;
++ resets = <&cpg 618>;
++ status = "disabled";
++ };
++
++ vin12: video@e6efc000 {
++ compatible = "renesas,vin-r8a77980";
++ reg = <0 0xe6efc000 0 0x1000>;
++ interrupts = <GIC_SPI 298 IRQ_TYPE_LEVEL_HIGH>;
++ clocks = <&cpg CPG_MOD 612>;
++ power-domains = <&sysc R8A77980_PD_ALWAYS_ON>;
++ resets = <&cpg 612>;
++ status = "disabled";
++ };
++
++ vin13: video@e6efd000 {
++ compatible = "renesas,vin-r8a77980";
++ reg = <0 0xe6efd000 0 0x1000>;
++ interrupts = <GIC_SPI 299 IRQ_TYPE_LEVEL_HIGH>;
++ clocks = <&cpg CPG_MOD 608>;
++ power-domains = <&sysc R8A77980_PD_ALWAYS_ON>;
++ resets = <&cpg 608>;
++ status = "disabled";
++ };
++
++ vin14: video@e6efe000 {
++ compatible = "renesas,vin-r8a77980";
++ reg = <0 0xe6efe000 0 0x1000>;
++ interrupts = <GIC_SPI 301 IRQ_TYPE_LEVEL_HIGH>;
++ clocks = <&cpg CPG_MOD 605>;
++ power-domains = <&sysc R8A77980_PD_ALWAYS_ON>;
++ resets = <&cpg 605>;
++ status = "disabled";
++ };
++
++ vin15: video@e6eff000 {
++ compatible = "renesas,vin-r8a77980";
++ reg = <0 0xe6eff000 0 0x1000>;
++ interrupts = <GIC_SPI 302 IRQ_TYPE_LEVEL_HIGH>;
++ clocks = <&cpg CPG_MOD 604>;
++ power-domains = <&sysc R8A77980_PD_ALWAYS_ON>;
++ resets = <&cpg 604>;
++ status = "disabled";
++ };
++
+ dmac1: dma-controller@e7300000 {
+ compatible = "renesas,dmac-r8a77980",
+ "renesas,rcar-dmac";
+@@ -769,6 +1065,84 @@
+ resets = <&cpg 603>;
+ };
+
++ csi40: csi2@feaa0000 {
++ compatible = "renesas,r8a77980-csi2";
++ reg = <0 0xfeaa0000 0 0x10000>;
++ interrupts = <GIC_SPI 246 IRQ_TYPE_LEVEL_HIGH>;
++ clocks = <&cpg CPG_MOD 716>;
++ power-domains = <&sysc R8A77980_PD_ALWAYS_ON>;
++ resets = <&cpg 716>;
++ status = "disabled";
++
++ ports {
++ #address-cells = <1>;
++ #size-cells = <0>;
++
++ port@1 {
++ #address-cells = <1>;
++ #size-cells = <0>;
++
++ reg = <1>;
++
++ csi40vin0: endpoint@0 {
++ reg = <0>;
++ remote-endpoint = <&vin0csi40>;
++ };
++ csi40vin1: endpoint@1 {
++ reg = <1>;
++ remote-endpoint = <&vin1csi40>;
++ };
++ csi40vin2: endpoint@2 {
++ reg = <2>;
++ remote-endpoint = <&vin2csi40>;
++ };
++ csi40vin3: endpoint@3 {
++ reg = <3>;
++ remote-endpoint = <&vin3csi40>;
++ };
++ };
++ };
++ };
++
++ csi41: csi2@feab0000 {
++ compatible = "renesas,r8a77980-csi2";
++ reg = <0 0xfeab0000 0 0x10000>;
++ interrupts = <GIC_SPI 241 IRQ_TYPE_LEVEL_HIGH>;
++ clocks = <&cpg CPG_MOD 715>;
++ power-domains = <&sysc R8A77980_PD_ALWAYS_ON>;
++ resets = <&cpg 715>;
++ status = "disabled";
++
++ ports {
++ #address-cells = <1>;
++ #size-cells = <0>;
++
++ port@1 {
++ #address-cells = <1>;
++ #size-cells = <0>;
++
++ reg = <1>;
++
++ csi41vin4: endpoint@0 {
++ reg = <0>;
++ remote-endpoint = <&vin4csi41>;
++ };
++ csi41vin5: endpoint@1 {
++ reg = <1>;
++ remote-endpoint = <&vin5csi41>;
++ };
++ csi41vin6: endpoint@2 {
++ reg = <2>;
++ remote-endpoint = <&vin6csi41>;
++ };
++ csi41vin7: endpoint@3 {
++ reg = <3>;
++ remote-endpoint = <&vin7csi41>;
++ };
++ };
++ };
++ };
++
+ du: display@feb00000 {
+ compatible = "renesas,du-r8a77980",
+ "renesas,du-r8a77970";
+--
+2.7.4
+
diff --git a/bsp/meta-rcar/meta-rcar-gen3-adas/recipes-kernel/linux/linux-renesas/0210-arm64-dts-renesas-r8a77970-add-MMC-support.patch b/bsp/meta-rcar/meta-rcar-gen3-adas/recipes-kernel/linux/linux-renesas/0210-arm64-dts-renesas-r8a77970-add-MMC-support.patch
new file mode 100644
index 00000000..a166973f
--- /dev/null
+++ b/bsp/meta-rcar/meta-rcar-gen3-adas/recipes-kernel/linux/linux-renesas/0210-arm64-dts-renesas-r8a77970-add-MMC-support.patch
@@ -0,0 +1,44 @@
+From 2b59da4cd554a6bbbd89f6417e0a188d1eba1118 Mon Sep 17 00:00:00 2001
+From: Sergei Shtylyov <sergei.shtylyov@cogentembedded.com>
+Date: Tue, 21 Aug 2018 22:49:26 +0300
+Subject: [PATCH 030/211] arm64: dts: renesas: r8a77970: add MMC support
+
+Define the generic R8A77970 part of the MMC0 (SDHI2) device node.
+
+Based on the original (and large) patches by Vladimir Barinov.
+
+Signed-off-by: Vladimir Barinov <vladimir.barinov@cogentembedded.com>
+Signed-off-by: Sergei Shtylyov <sergei.shtylyov@cogentembedded.com>
+Signed-off-by: Simon Horman <horms+renesas@verge.net.au>
+(cherry picked from commit 979e32b5265d6b42a568e950c5b5e2f6ab283ff3)
+Signed-off-by: Valentine Barshak <valentine.barshak@cogentembedded.com>
+---
+ arch/arm64/boot/dts/renesas/r8a77970.dtsi | 12 ++++++++++++
+ 1 file changed, 12 insertions(+)
+
+diff --git a/arch/arm64/boot/dts/renesas/r8a77970.dtsi b/arch/arm64/boot/dts/renesas/r8a77970.dtsi
+index 96feaa0..f4b0270 100644
+--- a/arch/arm64/boot/dts/renesas/r8a77970.dtsi
++++ b/arch/arm64/boot/dts/renesas/r8a77970.dtsi
+@@ -754,6 +754,18 @@
+ #iommu-cells = <1>;
+ };
+
++ mmc0: mmc@ee140000 {
++ compatible = "renesas,sdhi-r8a77970",
++ "renesas,rcar-gen3-sdhi";
++ reg = <0 0xee140000 0 0x2000>;
++ interrupts = <GIC_SPI 165 IRQ_TYPE_LEVEL_HIGH>;
++ clocks = <&cpg CPG_MOD 314>;
++ power-domains = <&sysc R8A77970_PD_ALWAYS_ON>;
++ resets = <&cpg 314>;
++ max-frequency = <200000000>;
++ status = "disabled";
++ };
++
+ gic: interrupt-controller@f1010000 {
+ compatible = "arm,gic-400";
+ #interrupt-cells = <3>;
+--
+2.7.4
+
diff --git a/bsp/meta-rcar/meta-rcar-gen3-adas/recipes-kernel/linux/linux-renesas/0211-arm64-dts-renesas-v3msk-add-eMMC-support.patch b/bsp/meta-rcar/meta-rcar-gen3-adas/recipes-kernel/linux/linux-renesas/0211-arm64-dts-renesas-v3msk-add-eMMC-support.patch
new file mode 100644
index 00000000..e27a8381
--- /dev/null
+++ b/bsp/meta-rcar/meta-rcar-gen3-adas/recipes-kernel/linux/linux-renesas/0211-arm64-dts-renesas-v3msk-add-eMMC-support.patch
@@ -0,0 +1,72 @@
+From 03b37015831c2f575276e140cf7b8ca6a3b31b22 Mon Sep 17 00:00:00 2001
+From: Sergei Shtylyov <sergei.shtylyov@cogentembedded.com>
+Date: Tue, 21 Aug 2018 22:50:31 +0300
+Subject: [PATCH 031/211] arm64: dts: renesas: v3msk: add eMMC support
+
+Add the eMMC chip support for the V3M Started Kit board.
+
+Based on the original (and large) patches by Vladimir Barinov.
+
+Signed-off-by: Vladimir Barinov <vladimir.barinov@cogentembedded.com>
+Signed-off-by: Sergei Shtylyov <sergei.shtylyov@cogentembedded.com>
+Signed-off-by: Simon Horman <horms+renesas@verge.net.au>
+(cherry picked from commit 8d9923b3a2f6c0e4ad3f9d9cad6e9010cf0d67e6)
+Signed-off-by: Valentine Barshak <valentine.barshak@cogentembedded.com>
+---
+ arch/arm64/boot/dts/renesas/r8a77970-v3msk.dts | 26 ++++++++++++++++++++++++++
+ 1 file changed, 26 insertions(+)
+
+diff --git a/arch/arm64/boot/dts/renesas/r8a77970-v3msk.dts b/arch/arm64/boot/dts/renesas/r8a77970-v3msk.dts
+index 8eac8ca..0dbcb4c 100644
+--- a/arch/arm64/boot/dts/renesas/r8a77970-v3msk.dts
++++ b/arch/arm64/boot/dts/renesas/r8a77970-v3msk.dts
+@@ -51,6 +51,15 @@
+ regulator-always-on;
+ };
+
++ vcc_vddq_vin0: regulator-2 {
++ compatible = "regulator-fixed";
++ regulator-name = "VCC_VDDQ_VIN0";
++ regulator-min-microvolt = <3300000>;
++ regulator-max-microvolt = <3300000>;
++ regulator-boot-on;
++ regulator-always-on;
++ };
++
+ lvds-decoder {
+ compatible = "thine,thc63lvd1024";
+ vcc-supply = <&vcc_d3_3v>;
+@@ -128,6 +137,12 @@
+ function = "i2c0";
+ };
+
++ mmc_pins: mmc_3_3v {
++ groups = "mmc_data8", "mmc_ctrl";
++ function = "mmc";
++ power-source = <3300>;
++ };
++
+ scif0_pins: scif0 {
+ groups = "scif0_data";
+ function = "scif0";
+@@ -192,6 +207,17 @@
+ };
+ };
+
++&mmc0 {
++ pinctrl-0 = <&mmc_pins>;
++ pinctrl-names = "default";
++
++ vmmc-supply = <&vcc_d3_3v>;
++ vqmmc-supply = <&vcc_vddq_vin0>;
++ bus-width = <8>;
++ non-removable;
++ status = "okay";
++};
++
+ &scif0 {
+ pinctrl-0 = <&scif0_pins>;
+ pinctrl-names = "default";
+--
+2.7.4
+
diff --git a/bsp/meta-rcar/meta-rcar-gen3-adas/recipes-kernel/linux/linux-renesas/0212-arm64-dts-renesas-condor-v3hsk-add-DU-LVDS-HDMI-supp.patch b/bsp/meta-rcar/meta-rcar-gen3-adas/recipes-kernel/linux/linux-renesas/0212-arm64-dts-renesas-condor-v3hsk-add-DU-LVDS-HDMI-supp.patch
new file mode 100644
index 00000000..6349fabf
--- /dev/null
+++ b/bsp/meta-rcar/meta-rcar-gen3-adas/recipes-kernel/linux/linux-renesas/0212-arm64-dts-renesas-condor-v3hsk-add-DU-LVDS-HDMI-supp.patch
@@ -0,0 +1,312 @@
+From 57a51e0b21a62757886386da60e8c0724b43e36a Mon Sep 17 00:00:00 2001
+From: Sergei Shtylyov <sergei.shtylyov@cogentembedded.com>
+Date: Thu, 23 Aug 2018 19:59:20 +0300
+Subject: [PATCH 032/211] arm64: dts: renesas: condor/v3hsk: add DU/LVDS/HDMI
+ support
+
+Define the Condor/V3HSK board dependent parts of the DU and LVDS device
+nodes. Also add the device nodes for Thine THC63LVD1024 LVDS decoder and
+Analog Devices ADV7511W HDMI transmitter...
+
+Based on the original (and large) patch by Vladimir Barinov.
+
+Signed-off-by: Vladimir Barinov <vladimir.barinov@cogentembedded.com>
+Signed-off-by: Sergei Shtylyov <sergei.shtylyov@cogentembedded.com>
+Reviewed-by: Ulrich Hecht <ulrich.hecht+renesas@gmail.com>
+Reviewed-by: Laurent Pinchart <laurent.pinchart@ideasonboard.com>
+Signed-off-by: Simon Horman <horms+renesas@verge.net.au>
+(cherry picked from commit 70fd8b6a4846362991ead7b68f951d519a9c71df)
+Signed-off-by: Valentine Barshak <valentine.barshak@cogentembedded.com>
+---
+ arch/arm64/boot/dts/renesas/r8a77980-condor.dts | 106 +++++++++++++++++++
+ arch/arm64/boot/dts/renesas/r8a77980-v3hsk.dts | 129 ++++++++++++++++++++++++
+ 2 files changed, 235 insertions(+)
+
+diff --git a/arch/arm64/boot/dts/renesas/r8a77980-condor.dts b/arch/arm64/boot/dts/renesas/r8a77980-condor.dts
+index 494f4ef..59db4c1 100644
+--- a/arch/arm64/boot/dts/renesas/r8a77980-condor.dts
++++ b/arch/arm64/boot/dts/renesas/r8a77980-condor.dts
+@@ -45,6 +45,56 @@
+ regulator-boot-on;
+ regulator-always-on;
+ };
++
++ d1_8v: regulator-2 {
++ compatible = "regulator-fixed";
++ regulator-name = "D1.8V";
++ regulator-min-microvolt = <1800000>;
++ regulator-max-microvolt = <1800000>;
++ regulator-boot-on;
++ regulator-always-on;
++ };
++
++ hdmi-out {
++ compatible = "hdmi-connector";
++ type = "a";
++
++ port {
++ hdmi_con: endpoint {
++ remote-endpoint = <&adv7511_out>;
++ };
++ };
++ };
++
++ lvds-decoder {
++ compatible = "thine,thc63lvd1024";
++ vcc-supply = <&d3_3v>;
++
++ ports {
++ #address-cells = <1>;
++ #size-cells = <0>;
++
++ port@0 {
++ reg = <0>;
++ thc63lvd1024_in: endpoint {
++ remote-endpoint = <&lvds0_out>;
++ };
++ };
++
++ port@2 {
++ reg = <2>;
++ thc63lvd1024_out: endpoint {
++ remote-endpoint = <&adv7511_in>;
++ };
++ };
++ };
++ };
++
++ x1_clk: x1-clock {
++ compatible = "fixed-clock";
++ #clock-cells = <0>;
++ clock-frequency = <148500000>;
++ };
+ };
+
+ &avb {
+@@ -74,6 +124,13 @@
+ };
+ };
+
++&du {
++ clocks = <&cpg CPG_MOD 724>,
++ <&x1_clk>;
++ clock-names = "du.0", "dclkin.0";
++ status = "okay";
++};
++
+ &extal_clk {
+ clock-frequency = <16666666>;
+ };
+@@ -102,6 +159,55 @@
+ gpio-controller;
+ #gpio-cells = <2>;
+ };
++
++ hdmi@39 {
++ compatible = "adi,adv7511w";
++ reg = <0x39>;
++ interrupt-parent = <&gpio1>;
++ interrupts = <20 IRQ_TYPE_LEVEL_LOW>;
++ avdd-supply = <&d1_8v>;
++ dvdd-supply = <&d1_8v>;
++ pvdd-supply = <&d1_8v>;
++ bgvdd-supply = <&d1_8v>;
++ dvdd-3v-supply = <&d3_3v>;
++
++ adi,input-depth = <8>;
++ adi,input-colorspace = "rgb";
++ adi,input-clock = "1x";
++ adi,input-style = <1>;
++ adi,input-justification = "evenly";
++
++ ports {
++ #address-cells = <1>;
++ #size-cells = <0>;
++
++ port@0 {
++ reg = <0>;
++ adv7511_in: endpoint {
++ remote-endpoint = <&thc63lvd1024_out>;
++ };
++ };
++
++ port@1 {
++ reg = <1>;
++ adv7511_out: endpoint {
++ remote-endpoint = <&hdmi_con>;
++ };
++ };
++ };
++ };
++};
++
++&lvds0 {
++ status = "okay";
++
++ ports {
++ port@1 {
++ lvds0_out: endpoint {
++ remote-endpoint = <&thc63lvd1024_in>;
++ };
++ };
++ };
+ };
+
+ &mmc0 {
+diff --git a/arch/arm64/boot/dts/renesas/r8a77980-v3hsk.dts b/arch/arm64/boot/dts/renesas/r8a77980-v3hsk.dts
+index 9147d85..44ab734 100644
+--- a/arch/arm64/boot/dts/renesas/r8a77980-v3hsk.dts
++++ b/arch/arm64/boot/dts/renesas/r8a77980-v3hsk.dts
+@@ -27,6 +27,72 @@
+ /* first 128MB is reserved for secure area. */
+ reg = <0 0x48000000 0 0x78000000>;
+ };
++
++ hdmi-out {
++ compatible = "hdmi-connector";
++ type = "a";
++
++ port {
++ hdmi_con: endpoint {
++ remote-endpoint = <&adv7511_out>;
++ };
++ };
++ };
++
++ lvds-decoder {
++ compatible = "thine,thc63lvd1024";
++ vcc-supply = <&vcc3v3_d5>;
++
++ ports {
++ #address-cells = <1>;
++ #size-cells = <0>;
++
++ port@0 {
++ reg = <0>;
++ thc63lvd1024_in: endpoint {
++ remote-endpoint = <&lvds0_out>;
++ };
++ };
++
++ port@2 {
++ reg = <2>;
++ thc63lvd1024_out: endpoint {
++ remote-endpoint = <&adv7511_in>;
++ };
++ };
++ };
++ };
++
++ osc1_clk: osc1-clock {
++ compatible = "fixed-clock";
++ #clock-cells = <0>;
++ clock-frequency = <148500000>;
++ };
++
++ vcc1v8_d4: regulator-0 {
++ compatible = "regulator-fixed";
++ regulator-name = "VCC1V8_D4";
++ regulator-min-microvolt = <1800000>;
++ regulator-max-microvolt = <1800000>;
++ regulator-boot-on;
++ regulator-always-on;
++ };
++
++ vcc3v3_d5: regulator-1 {
++ compatible = "regulator-fixed";
++ regulator-name = "VCC3V3_D5";
++ regulator-min-microvolt = <3300000>;
++ regulator-max-microvolt = <3300000>;
++ regulator-boot-on;
++ regulator-always-on;
++ };
++};
++
++&du {
++ clocks = <&cpg CPG_MOD 724>,
++ <&osc1_clk>;
++ clock-names = "du.0", "dclkin.0";
++ status = "okay";
+ };
+
+ &extal_clk {
+@@ -53,6 +119,64 @@
+ };
+ };
+
++&lvds0 {
++ status = "okay";
++
++ ports {
++ port@1 {
++ lvds0_out: endpoint {
++ remote-endpoint = <&thc63lvd1024_in>;
++ };
++ };
++ };
++};
++
++&i2c0 {
++ pinctrl-0 = <&i2c0_pins>;
++ pinctrl-names = "default";
++
++ status = "okay";
++ clock-frequency = <400000>;
++
++ hdmi@39 {
++ compatible = "adi,adv7511w";
++ #sound-dai-cells = <0>;
++ reg = <0x39>;
++ interrupt-parent = <&gpio1>;
++ interrupts = <20 IRQ_TYPE_LEVEL_LOW>;
++ avdd-supply = <&vcc1v8_d4>;
++ dvdd-supply = <&vcc1v8_d4>;
++ pvdd-supply = <&vcc1v8_d4>;
++ bgvdd-supply = <&vcc1v8_d4>;
++ dvdd-3v-supply = <&vcc3v3_d5>;
++
++ adi,input-depth = <8>;
++ adi,input-colorspace = "rgb";
++ adi,input-clock = "1x";
++ adi,input-style = <1>;
++ adi,input-justification = "evenly";
++
++ ports {
++ #address-cells = <1>;
++ #size-cells = <0>;
++
++ port@0 {
++ reg = <0>;
++ adv7511_in: endpoint {
++ remote-endpoint = <&thc63lvd1024_out>;
++ };
++ };
++
++ port@1 {
++ reg = <1>;
++ adv7511_out: endpoint {
++ remote-endpoint = <&hdmi_con>;
++ };
++ };
++ };
++ };
++};
++
+ &pfc {
+ gether_pins: gether {
+ groups = "gether_mdio_a", "gether_rgmii",
+@@ -60,6 +184,11 @@
+ function = "gether";
+ };
+
++ i2c0_pins: i2c0 {
++ groups = "i2c0";
++ function = "i2c0";
++ };
++
+ scif0_pins: scif0 {
+ groups = "scif0_data";
+ function = "scif0";
+--
+2.7.4
+
diff --git a/bsp/meta-rcar/meta-rcar-gen3-adas/recipes-kernel/linux/linux-renesas/0213-arm64-dts-renesas-r8a77980-add-PCIe-support.patch b/bsp/meta-rcar/meta-rcar-gen3-adas/recipes-kernel/linux/linux-renesas/0213-arm64-dts-renesas-r8a77980-add-PCIe-support.patch
new file mode 100644
index 00000000..7202c432
--- /dev/null
+++ b/bsp/meta-rcar/meta-rcar-gen3-adas/recipes-kernel/linux/linux-renesas/0213-arm64-dts-renesas-r8a77980-add-PCIe-support.patch
@@ -0,0 +1,96 @@
+From 3c2e68276ac116a525359c306f9ff76d83ad8fad Mon Sep 17 00:00:00 2001
+From: Sergei Shtylyov <sergei.shtylyov@cogentembedded.com>
+Date: Mon, 27 Aug 2018 21:53:40 +0300
+Subject: [PATCH 033/211] arm64: dts: renesas: r8a77980: add PCIe support
+
+Describe the PCIe PHY, PCIEC, and PCIe bus clock in the R8A77980 device
+tree.
+
+Based on the original (and large) patch by Vladimir Barinov.
+
+Signed-off-by: Vladimir Barinov <vladimir.barinov@cogentembedded.com>
+Signed-off-by: Sergei Shtylyov <sergei.shtylyov@cogentembedded.com>
+Signed-off-by: Simon Horman <horms+renesas@verge.net.au>
+(cherry picked from commit ffa967e24c5817b48a3d5ecea2c12b9cdd807f0c)
+Signed-off-by: Valentine Barshak <valentine.barshak@cogentembedded.com>
+---
+ arch/arm64/boot/dts/renesas/r8a77980.dtsi | 49 +++++++++++++++++++++++++++++++
+ 1 file changed, 49 insertions(+)
+
+diff --git a/arch/arm64/boot/dts/renesas/r8a77980.dtsi b/arch/arm64/boot/dts/renesas/r8a77980.dtsi
+index c099053..d58e9f2 100644
+--- a/arch/arm64/boot/dts/renesas/r8a77980.dtsi
++++ b/arch/arm64/boot/dts/renesas/r8a77980.dtsi
+@@ -98,6 +98,13 @@
+ clock-frequency = <0>;
+ };
+
++ /* External PCIe clock - can be overridden by the board */
++ pcie_bus_clk: pcie_bus {
++ compatible = "fixed-clock";
++ #clock-cells = <0>;
++ clock-frequency = <0>;
++ };
++
+ pmu_a53 {
+ compatible = "arm,cortex-a53-pmu";
+ interrupts-extended = <&gic GIC_SPI 84 IRQ_TYPE_LEVEL_HIGH>,
+@@ -437,6 +444,16 @@
+ status = "disabled";
+ };
+
++ pcie_phy: pcie-phy@e65d0000 {
++ compatible = "renesas,r8a77980-pcie-phy";
++ reg = <0 0xe65d0000 0 0x8000>;
++ #phy-cells = <0>;
++ clocks = <&cpg CPG_MOD 319>;
++ power-domains = <&sysc R8A77980_PD_ALWAYS_ON>;
++ resets = <&cpg 319>;
++ status = "disabled";
++ };
++
+ canfd: can@e66c0000 {
+ compatible = "renesas,r8a77980-canfd",
+ "renesas,rcar-gen3-canfd";
+@@ -1047,6 +1064,38 @@
+ resets = <&cpg 408>;
+ };
+
++ pciec: pcie@fe000000 {
++ compatible = "renesas,pcie-r8a77980",
++ "renesas,pcie-rcar-gen3";
++ reg = <0 0xfe000000 0 0x80000>;
++ #address-cells = <3>;
++ #size-cells = <2>;
++ bus-range = <0x00 0xff>;
++ device_type = "pci";
++ ranges = <
++ 0x01000000 0 0x00000000 0 0xfe100000 0 0x0100000
++ 0x02000000 0 0xfe200000 0 0xfe200000 0 0x0200000
++ 0x02000000 0 0x30000000 0 0x30000000 0 0x8000000
++ 0x42000000 0 0x38000000 0 0x38000000 0 0x8000000
++ >;
++ dma-ranges = <0x42000000 0 0x40000000 0 0x40000000
++ 0 0x80000000>;
++ interrupts = <GIC_SPI 148 IRQ_TYPE_LEVEL_HIGH>,
++ <GIC_SPI 149 IRQ_TYPE_LEVEL_HIGH>,
++ <GIC_SPI 150 IRQ_TYPE_LEVEL_HIGH>;
++ #interrupt-cells = <1>;
++ interrupt-map-mask = <0 0 0 0>;
++ interrupt-map = <0 0 0 0 &gic GIC_SPI 148
++ IRQ_TYPE_LEVEL_HIGH>;
++ clocks = <&cpg CPG_MOD 319>, <&pcie_bus_clk>;
++ clock-names = "pcie", "pcie_bus";
++ power-domains = <&sysc R8A77980_PD_ALWAYS_ON>;
++ resets = <&cpg 319>;
++ phys = <&pcie_phy>;
++ phy-names = "pcie";
++ status = "disabled";
++ };
++
+ vspd0: vsp@fea20000 {
+ compatible = "renesas,vsp2";
+ reg = <0 0xfea20000 0 0x5000>;
+--
+2.7.4
+
diff --git a/bsp/meta-rcar/meta-rcar-gen3-adas/recipes-kernel/linux/linux-renesas/0214-arm64-dts-renesas-condor-add-PCIe-support.patch b/bsp/meta-rcar/meta-rcar-gen3-adas/recipes-kernel/linux/linux-renesas/0214-arm64-dts-renesas-condor-add-PCIe-support.patch
new file mode 100644
index 00000000..6f4f4d64
--- /dev/null
+++ b/bsp/meta-rcar/meta-rcar-gen3-adas/recipes-kernel/linux/linux-renesas/0214-arm64-dts-renesas-condor-add-PCIe-support.patch
@@ -0,0 +1,45 @@
+From 61d409555937f91063cea81334fe8b7c89f7cdff Mon Sep 17 00:00:00 2001
+From: Sergei Shtylyov <sergei.shtylyov@cogentembedded.com>
+Date: Mon, 27 Aug 2018 21:54:35 +0300
+Subject: [PATCH 034/211] arm64: dts: renesas: condor: add PCIe support
+
+Enable PCIe PHY and PCIEC and specify the PCIe bus clock for the Condor
+board.
+
+Based on the original (and large) patch by Vladimir Barinov.
+
+Signed-off-by: Vladimir Barinov <vladimir.barinov@cogentembedded.com>
+Signed-off-by: Sergei Shtylyov <sergei.shtylyov@cogentembedded.com>
+Signed-off-by: Simon Horman <horms+renesas@verge.net.au>
+(cherry picked from commit c6eb20473f0b296c671dc6f7a7766ea6bedf2d59)
+Signed-off-by: Valentine Barshak <valentine.barshak@cogentembedded.com>
+---
+ arch/arm64/boot/dts/renesas/r8a77980-condor.dts | 12 ++++++++++++
+ 1 file changed, 12 insertions(+)
+
+diff --git a/arch/arm64/boot/dts/renesas/r8a77980-condor.dts b/arch/arm64/boot/dts/renesas/r8a77980-condor.dts
+index 59db4c1..fe2e2c0 100644
+--- a/arch/arm64/boot/dts/renesas/r8a77980-condor.dts
++++ b/arch/arm64/boot/dts/renesas/r8a77980-condor.dts
+@@ -223,6 +223,18 @@
+ status = "okay";
+ };
+
++&pciec {
++ status = "okay";
++};
++
++&pcie_bus_clk {
++ clock-frequency = <100000000>;
++};
++
++&pcie_phy {
++ status = "okay";
++};
++
+ &pfc {
+ avb_pins: avb {
+ groups = "avb_mdio", "avb_rgmii";
+--
+2.7.4
+
diff --git a/bsp/meta-rcar/meta-rcar-gen3-adas/recipes-kernel/linux/linux-renesas/0215-arm64-dts-renesas-v3hsk-Move-lvds0-node.patch b/bsp/meta-rcar/meta-rcar-gen3-adas/recipes-kernel/linux/linux-renesas/0215-arm64-dts-renesas-v3hsk-Move-lvds0-node.patch
new file mode 100644
index 00000000..df40fc43
--- /dev/null
+++ b/bsp/meta-rcar/meta-rcar-gen3-adas/recipes-kernel/linux/linux-renesas/0215-arm64-dts-renesas-v3hsk-Move-lvds0-node.patch
@@ -0,0 +1,61 @@
+From b681b5c0577d05ffa6bfbcd964d7128bd1407985 Mon Sep 17 00:00:00 2001
+From: Geert Uytterhoeven <geert+renesas@glider.be>
+Date: Tue, 28 Aug 2018 16:15:40 +0200
+Subject: [PATCH 035/211] arm64: dts: renesas: v3hsk: Move lvds0 node
+
+To preserve alphabetical sort order.
+
+Fixes: 4edac426aff11a37 ("arm64: dts: renesas: condor/v3hsk: add DU/LVDS/HDMI support")
+Signed-off-by: Geert Uytterhoeven <geert+renesas@glider.be>
+Signed-off-by: Simon Horman <horms+renesas@verge.net.au>
+(cherry picked from commit 47d7f6822864a8cf2f09d27cb1321bd36ab6d9e4)
+Signed-off-by: Valentine Barshak <valentine.barshak@cogentembedded.com>
+---
+ arch/arm64/boot/dts/renesas/r8a77980-v3hsk.dts | 24 ++++++++++++------------
+ 1 file changed, 12 insertions(+), 12 deletions(-)
+
+diff --git a/arch/arm64/boot/dts/renesas/r8a77980-v3hsk.dts b/arch/arm64/boot/dts/renesas/r8a77980-v3hsk.dts
+index 44ab734..dd14a41 100644
+--- a/arch/arm64/boot/dts/renesas/r8a77980-v3hsk.dts
++++ b/arch/arm64/boot/dts/renesas/r8a77980-v3hsk.dts
+@@ -119,18 +119,6 @@
+ };
+ };
+
+-&lvds0 {
+- status = "okay";
+-
+- ports {
+- port@1 {
+- lvds0_out: endpoint {
+- remote-endpoint = <&thc63lvd1024_in>;
+- };
+- };
+- };
+-};
+-
+ &i2c0 {
+ pinctrl-0 = <&i2c0_pins>;
+ pinctrl-names = "default";
+@@ -177,6 +165,18 @@
+ };
+ };
+
++&lvds0 {
++ status = "okay";
++
++ ports {
++ port@1 {
++ lvds0_out: endpoint {
++ remote-endpoint = <&thc63lvd1024_in>;
++ };
++ };
++ };
++};
++
+ &pfc {
+ gether_pins: gether {
+ groups = "gether_mdio_a", "gether_rgmii",
+--
+2.7.4
+
diff --git a/bsp/meta-rcar/meta-rcar-gen3-adas/recipes-kernel/linux/linux-renesas/0216-arm64-dts-renesas-r8a77980-Attach-the-SYS-DMAC-to-th.patch b/bsp/meta-rcar/meta-rcar-gen3-adas/recipes-kernel/linux/linux-renesas/0216-arm64-dts-renesas-r8a77980-Attach-the-SYS-DMAC-to-th.patch
new file mode 100644
index 00000000..7e47fe8d
--- /dev/null
+++ b/bsp/meta-rcar/meta-rcar-gen3-adas/recipes-kernel/linux/linux-renesas/0216-arm64-dts-renesas-r8a77980-Attach-the-SYS-DMAC-to-th.patch
@@ -0,0 +1,54 @@
+From 4ecddcb2708e1035d82808a315eee47f77d90805 Mon Sep 17 00:00:00 2001
+From: Magnus Damm <damm@opensource.se>
+Date: Mon, 17 Sep 2018 17:53:05 +0900
+Subject: [PATCH 036/211] arm64: dts: renesas: r8a77980: Attach the SYS-DMAC to
+ the IPMMU
+
+For R-Car V3H hook up SYS-DMAC1 and SYS-DMAC2 to IPMMU-DS1 to match
+information in the R-Car Gen3 Rev.1.00 (April 2018) datasheet.
+
+Signed-off-by: Magnus Damm <damm@opensource.se>
+Signed-off-by: Simon Horman <horms+renesas@verge.net.au>
+(cherry picked from commit d59b0784f1e64ad84756b485c622e3ee0712b946)
+Signed-off-by: Valentine Barshak <valentine.barshak@cogentembedded.com>
+---
+ arch/arm64/boot/dts/renesas/r8a77980.dtsi | 16 ++++++++++++++++
+ 1 file changed, 16 insertions(+)
+
+diff --git a/arch/arm64/boot/dts/renesas/r8a77980.dtsi b/arch/arm64/boot/dts/renesas/r8a77980.dtsi
+index d58e9f2..7dd4ad2 100644
+--- a/arch/arm64/boot/dts/renesas/r8a77980.dtsi
++++ b/arch/arm64/boot/dts/renesas/r8a77980.dtsi
+@@ -924,6 +924,14 @@
+ resets = <&cpg 218>;
+ #dma-cells = <1>;
+ dma-channels = <16>;
++ iommus = <&ipmmu_ds1 0>, <&ipmmu_ds1 1>,
++ <&ipmmu_ds1 2>, <&ipmmu_ds1 3>,
++ <&ipmmu_ds1 4>, <&ipmmu_ds1 5>,
++ <&ipmmu_ds1 6>, <&ipmmu_ds1 7>,
++ <&ipmmu_ds1 8>, <&ipmmu_ds1 9>,
++ <&ipmmu_ds1 10>, <&ipmmu_ds1 11>,
++ <&ipmmu_ds1 12>, <&ipmmu_ds1 13>,
++ <&ipmmu_ds1 14>, <&ipmmu_ds1 15>;
+ };
+
+ dmac2: dma-controller@e7310000 {
+@@ -958,6 +966,14 @@
+ resets = <&cpg 217>;
+ #dma-cells = <1>;
+ dma-channels = <16>;
++ iommus = <&ipmmu_ds1 16>, <&ipmmu_ds1 17>,
++ <&ipmmu_ds1 18>, <&ipmmu_ds1 19>,
++ <&ipmmu_ds1 20>, <&ipmmu_ds1 21>,
++ <&ipmmu_ds1 22>, <&ipmmu_ds1 23>,
++ <&ipmmu_ds1 24>, <&ipmmu_ds1 25>,
++ <&ipmmu_ds1 26>, <&ipmmu_ds1 27>,
++ <&ipmmu_ds1 28>, <&ipmmu_ds1 29>,
++ <&ipmmu_ds1 30>, <&ipmmu_ds1 31>;
+ };
+
+ gether: ethernet@e7400000 {
+--
+2.7.4
+
diff --git a/bsp/meta-rcar/meta-rcar-gen3-adas/recipes-kernel/linux/linux-renesas/0217-arm64-dts-renesas-r8a779-7-8-0-add-CMT-support.patch b/bsp/meta-rcar/meta-rcar-gen3-adas/recipes-kernel/linux/linux-renesas/0217-arm64-dts-renesas-r8a779-7-8-0-add-CMT-support.patch
new file mode 100644
index 00000000..b5bdf788
--- /dev/null
+++ b/bsp/meta-rcar/meta-rcar-gen3-adas/recipes-kernel/linux/linux-renesas/0217-arm64-dts-renesas-r8a779-7-8-0-add-CMT-support.patch
@@ -0,0 +1,185 @@
+From a0eacde243624af6648986c8f38caea744a4e5f8 Mon Sep 17 00:00:00 2001
+From: Sergei Shtylyov <sergei.shtylyov@cogentembedded.com>
+Date: Fri, 7 Sep 2018 21:58:41 +0300
+Subject: [PATCH 037/211] arm64: dts: renesas: r8a779{7|8}0: add CMT support
+
+Describe CMTs in the R8A779{7|8}0 device trees.
+
+Based on the original (and large) patches by Vladimir Barinov.
+
+Signed-off-by: Vladimir Barinov <vladimir.barinov@cogentembedded.com>
+Signed-off-by: Sergei Shtylyov <sergei.shtylyov@cogentembedded.com>
+Reviewed-by: Geert Uytterhoeven <geert+renesas@glider.be>
+Signed-off-by: Simon Horman <horms+renesas@verge.net.au>
+(cherry picked from commit a215af751dc5d24b4e3a8fc9976ae95737843934)
+Signed-off-by: Valentine Barshak <valentine.barshak@cogentembedded.com>
+---
+ arch/arm64/boot/dts/renesas/r8a77970.dtsi | 70 +++++++++++++++++++++++++++++++
+ arch/arm64/boot/dts/renesas/r8a77980.dtsi | 70 +++++++++++++++++++++++++++++++
+ 2 files changed, 140 insertions(+)
+
+diff --git a/arch/arm64/boot/dts/renesas/r8a77970.dtsi b/arch/arm64/boot/dts/renesas/r8a77970.dtsi
+index f4b0270..934a15f 100644
+--- a/arch/arm64/boot/dts/renesas/r8a77970.dtsi
++++ b/arch/arm64/boot/dts/renesas/r8a77970.dtsi
+@@ -209,6 +209,76 @@
+ reg = <0 0xe6060000 0 0x504>;
+ };
+
++ cmt0: timer@e60f0000 {
++ compatible = "renesas,r8a77970-cmt0",
++ "renesas,rcar-gen3-cmt0";
++ reg = <0 0xe60f0000 0 0x1004>;
++ interrupts = <GIC_SPI 142 IRQ_TYPE_LEVEL_HIGH>,
++ <GIC_SPI 143 IRQ_TYPE_LEVEL_HIGH>;
++ clocks = <&cpg CPG_MOD 303>;
++ clock-names = "fck";
++ power-domains = <&sysc R8A77970_PD_ALWAYS_ON>;
++ resets = <&cpg 303>;
++ status = "disabled";
++ };
++
++ cmt1: timer@e6130000 {
++ compatible = "renesas,r8a77970-cmt1",
++ "renesas,rcar-gen3-cmt1";
++ reg = <0 0xe6130000 0 0x1004>;
++ interrupts = <GIC_SPI 120 IRQ_TYPE_LEVEL_HIGH>,
++ <GIC_SPI 121 IRQ_TYPE_LEVEL_HIGH>,
++ <GIC_SPI 122 IRQ_TYPE_LEVEL_HIGH>,
++ <GIC_SPI 123 IRQ_TYPE_LEVEL_HIGH>,
++ <GIC_SPI 124 IRQ_TYPE_LEVEL_HIGH>,
++ <GIC_SPI 125 IRQ_TYPE_LEVEL_HIGH>,
++ <GIC_SPI 126 IRQ_TYPE_LEVEL_HIGH>,
++ <GIC_SPI 127 IRQ_TYPE_LEVEL_HIGH>;
++ clocks = <&cpg CPG_MOD 302>;
++ clock-names = "fck";
++ power-domains = <&sysc R8A77970_PD_ALWAYS_ON>;
++ resets = <&cpg 302>;
++ status = "disabled";
++ };
++
++ cmt2: timer@e6140000 {
++ compatible = "renesas,r8a77970-cmt1",
++ "renesas,rcar-gen3-cmt1";
++ reg = <0 0xe6140000 0 0x1004>;
++ interrupts = <GIC_SPI 258 IRQ_TYPE_LEVEL_HIGH>,
++ <GIC_SPI 259 IRQ_TYPE_LEVEL_HIGH>,
++ <GIC_SPI 260 IRQ_TYPE_LEVEL_HIGH>,
++ <GIC_SPI 261 IRQ_TYPE_LEVEL_HIGH>,
++ <GIC_SPI 262 IRQ_TYPE_LEVEL_HIGH>,
++ <GIC_SPI 263 IRQ_TYPE_LEVEL_HIGH>,
++ <GIC_SPI 264 IRQ_TYPE_LEVEL_HIGH>,
++ <GIC_SPI 265 IRQ_TYPE_LEVEL_HIGH>;
++ clocks = <&cpg CPG_MOD 301>;
++ clock-names = "fck";
++ power-domains = <&sysc R8A77970_PD_ALWAYS_ON>;
++ resets = <&cpg 301>;
++ status = "disabled";
++ };
++
++ cmt3: timer@e6148000 {
++ compatible = "renesas,r8a77970-cmt1",
++ "renesas,rcar-gen3-cmt1";
++ reg = <0 0xe6148000 0 0x1004>;
++ interrupts = <GIC_SPI 273 IRQ_TYPE_LEVEL_HIGH>,
++ <GIC_SPI 274 IRQ_TYPE_LEVEL_HIGH>,
++ <GIC_SPI 275 IRQ_TYPE_LEVEL_HIGH>,
++ <GIC_SPI 276 IRQ_TYPE_LEVEL_HIGH>,
++ <GIC_SPI 277 IRQ_TYPE_LEVEL_HIGH>,
++ <GIC_SPI 278 IRQ_TYPE_LEVEL_HIGH>,
++ <GIC_SPI 279 IRQ_TYPE_LEVEL_HIGH>,
++ <GIC_SPI 280 IRQ_TYPE_LEVEL_HIGH>;
++ clocks = <&cpg CPG_MOD 300>;
++ clock-names = "fck";
++ power-domains = <&sysc R8A77970_PD_ALWAYS_ON>;
++ resets = <&cpg 300>;
++ status = "disabled";
++ };
++
+ cpg: clock-controller@e6150000 {
+ compatible = "renesas,r8a77970-cpg-mssr";
+ reg = <0 0xe6150000 0 0x1000>;
+diff --git a/arch/arm64/boot/dts/renesas/r8a77980.dtsi b/arch/arm64/boot/dts/renesas/r8a77980.dtsi
+index 7dd4ad2..cb135f6 100644
+--- a/arch/arm64/boot/dts/renesas/r8a77980.dtsi
++++ b/arch/arm64/boot/dts/renesas/r8a77980.dtsi
+@@ -239,6 +239,76 @@
+ reg = <0 0xe6060000 0 0x50c>;
+ };
+
++ cmt0: timer@e60f0000 {
++ compatible = "renesas,r8a77980-cmt0",
++ "renesas,rcar-gen3-cmt0";
++ reg = <0 0xe60f0000 0 0x1004>;
++ interrupts = <GIC_SPI 142 IRQ_TYPE_LEVEL_HIGH>,
++ <GIC_SPI 143 IRQ_TYPE_LEVEL_HIGH>;
++ clocks = <&cpg CPG_MOD 303>;
++ clock-names = "fck";
++ power-domains = <&sysc R8A77980_PD_ALWAYS_ON>;
++ resets = <&cpg 303>;
++ status = "disabled";
++ };
++
++ cmt1: timer@e6130000 {
++ compatible = "renesas,r8a77980-cmt1",
++ "renesas,rcar-gen3-cmt1";
++ reg = <0 0xe6130000 0 0x1004>;
++ interrupts = <GIC_SPI 120 IRQ_TYPE_LEVEL_HIGH>,
++ <GIC_SPI 121 IRQ_TYPE_LEVEL_HIGH>,
++ <GIC_SPI 122 IRQ_TYPE_LEVEL_HIGH>,
++ <GIC_SPI 123 IRQ_TYPE_LEVEL_HIGH>,
++ <GIC_SPI 124 IRQ_TYPE_LEVEL_HIGH>,
++ <GIC_SPI 125 IRQ_TYPE_LEVEL_HIGH>,
++ <GIC_SPI 126 IRQ_TYPE_LEVEL_HIGH>,
++ <GIC_SPI 127 IRQ_TYPE_LEVEL_HIGH>;
++ clocks = <&cpg CPG_MOD 302>;
++ clock-names = "fck";
++ power-domains = <&sysc R8A77980_PD_ALWAYS_ON>;
++ resets = <&cpg 302>;
++ status = "disabled";
++ };
++
++ cmt2: timer@e6140000 {
++ compatible = "renesas,r8a77980-cmt1",
++ "renesas,rcar-gen3-cmt1";
++ reg = <0 0xe6140000 0 0x1004>;
++ interrupts = <GIC_SPI 258 IRQ_TYPE_LEVEL_HIGH>,
++ <GIC_SPI 259 IRQ_TYPE_LEVEL_HIGH>,
++ <GIC_SPI 260 IRQ_TYPE_LEVEL_HIGH>,
++ <GIC_SPI 261 IRQ_TYPE_LEVEL_HIGH>,
++ <GIC_SPI 262 IRQ_TYPE_LEVEL_HIGH>,
++ <GIC_SPI 263 IRQ_TYPE_LEVEL_HIGH>,
++ <GIC_SPI 264 IRQ_TYPE_LEVEL_HIGH>,
++ <GIC_SPI 265 IRQ_TYPE_LEVEL_HIGH>;
++ clocks = <&cpg CPG_MOD 301>;
++ clock-names = "fck";
++ power-domains = <&sysc R8A77980_PD_ALWAYS_ON>;
++ resets = <&cpg 301>;
++ status = "disabled";
++ };
++
++ cmt3: timer@e6148000 {
++ compatible = "renesas,r8a77980-cmt1",
++ "renesas,rcar-gen3-cmt1";
++ reg = <0 0xe6148000 0 0x1004>;
++ interrupts = <GIC_SPI 273 IRQ_TYPE_LEVEL_HIGH>,
++ <GIC_SPI 274 IRQ_TYPE_LEVEL_HIGH>,
++ <GIC_SPI 275 IRQ_TYPE_LEVEL_HIGH>,
++ <GIC_SPI 276 IRQ_TYPE_LEVEL_HIGH>,
++ <GIC_SPI 277 IRQ_TYPE_LEVEL_HIGH>,
++ <GIC_SPI 278 IRQ_TYPE_LEVEL_HIGH>,
++ <GIC_SPI 279 IRQ_TYPE_LEVEL_HIGH>,
++ <GIC_SPI 280 IRQ_TYPE_LEVEL_HIGH>;
++ clocks = <&cpg CPG_MOD 300>;
++ clock-names = "fck";
++ power-domains = <&sysc R8A77980_PD_ALWAYS_ON>;
++ resets = <&cpg 300>;
++ status = "disabled";
++ };
++
+ cpg: clock-controller@e6150000 {
+ compatible = "renesas,r8a77980-cpg-mssr";
+ reg = <0 0xe6150000 0 0x1000>;
+--
+2.7.4
+
diff --git a/bsp/meta-rcar/meta-rcar-gen3-adas/recipes-kernel/linux/linux-renesas/0218-dt-bindings-timer-renesas-tmu-document-R8A779-7-8-0-.patch b/bsp/meta-rcar/meta-rcar-gen3-adas/recipes-kernel/linux/linux-renesas/0218-dt-bindings-timer-renesas-tmu-document-R8A779-7-8-0-.patch
new file mode 100644
index 00000000..9bbd07e8
--- /dev/null
+++ b/bsp/meta-rcar/meta-rcar-gen3-adas/recipes-kernel/linux/linux-renesas/0218-dt-bindings-timer-renesas-tmu-document-R8A779-7-8-0-.patch
@@ -0,0 +1,34 @@
+From 5d6939bac638468832c76cf3564576a712542859 Mon Sep 17 00:00:00 2001
+From: Sergei Shtylyov <sergei.shtylyov@cogentembedded.com>
+Date: Fri, 7 Sep 2018 23:02:53 +0300
+Subject: [PATCH 038/211] dt-bindings: timer: renesas: tmu: document
+ R8A779{7|8}0 bindings
+
+Document the R-Car V3{M|H} (R8A779{7|8}0) SoC in the Renesas TMU bindings;
+the TMU hardware in those is the Renesas standard 3-channel timer unit.
+
+Signed-off-by: Sergei Shtylyov <sergei.shtylyov@cogentembedded.com>
+Reviewed-by: Geert Uytterhoeven <geert+renesas@glider.be>
+Signed-off-by: Simon Horman <horms+renesas@verge.net.au>
+(cherry picked from commit 5851fa4d088747af4a141110541594a2a4479b12)
+Signed-off-by: Valentine Barshak <valentine.barshak@cogentembedded.com>
+---
+ Documentation/devicetree/bindings/timer/renesas,tmu.txt | 2 ++
+ 1 file changed, 2 insertions(+)
+
+diff --git a/Documentation/devicetree/bindings/timer/renesas,tmu.txt b/Documentation/devicetree/bindings/timer/renesas,tmu.txt
+index cd5f20b..4ddff85 100644
+--- a/Documentation/devicetree/bindings/timer/renesas,tmu.txt
++++ b/Documentation/devicetree/bindings/timer/renesas,tmu.txt
+@@ -12,6 +12,8 @@ Required Properties:
+ - "renesas,tmu-r8a7740" for the r8a7740 TMU
+ - "renesas,tmu-r8a7778" for the r8a7778 TMU
+ - "renesas,tmu-r8a7779" for the r8a7779 TMU
++ - "renesas,tmu-r8a77970" for the r8a77970 TMU
++ - "renesas,tmu-r8a77980" for the r8a77980 TMU
+ - "renesas,tmu" for any TMU.
+ This is a fallback for the above renesas,tmu-* entries
+
+--
+2.7.4
+
diff --git a/bsp/meta-rcar/meta-rcar-gen3-adas/recipes-kernel/linux/linux-renesas/0219-arm64-dts-renesas-r8a779-7-8-0-add-TPU-support.patch b/bsp/meta-rcar/meta-rcar-gen3-adas/recipes-kernel/linux/linux-renesas/0219-arm64-dts-renesas-r8a779-7-8-0-add-TPU-support.patch
new file mode 100644
index 00000000..7f2a8b94
--- /dev/null
+++ b/bsp/meta-rcar/meta-rcar-gen3-adas/recipes-kernel/linux/linux-renesas/0219-arm64-dts-renesas-r8a779-7-8-0-add-TPU-support.patch
@@ -0,0 +1,66 @@
+From 09a60708855e01599deb5993dd4c2a89aa638e1e Mon Sep 17 00:00:00 2001
+From: Sergei Shtylyov <sergei.shtylyov@cogentembedded.com>
+Date: Mon, 24 Sep 2018 21:33:00 +0300
+Subject: [PATCH 039/211] arm64: dts: renesas: r8a779{7|8}0: add TPU support
+
+Describe TPU in the R8A779{7|8}0 device trees.
+
+Based on the original (and large) patches by Vladimir Barinov.
+
+Signed-off-by: Vladimir Barinov <vladimir.barinov@cogentembedded.com>
+Signed-off-by: Sergei Shtylyov <sergei.shtylyov@cogentembedded.com>
+Reviewed-by: Geert Uytterhoeven <geert+renesas@glider.be>
+Signed-off-by: Simon Horman <horms+renesas@verge.net.au>
+(cherry picked from commit dd809b7de27cff710658febdde65304ec1a3ea82)
+Signed-off-by: Valentine Barshak <valentine.barshak@cogentembedded.com>
+---
+ arch/arm64/boot/dts/renesas/r8a77970.dtsi | 10 ++++++++++
+ arch/arm64/boot/dts/renesas/r8a77980.dtsi | 11 +++++++++++
+ 2 files changed, 21 insertions(+)
+
+diff --git a/arch/arm64/boot/dts/renesas/r8a77970.dtsi b/arch/arm64/boot/dts/renesas/r8a77970.dtsi
+index 934a15f..cba7885 100644
+--- a/arch/arm64/boot/dts/renesas/r8a77970.dtsi
++++ b/arch/arm64/boot/dts/renesas/r8a77970.dtsi
+@@ -614,6 +614,16 @@
+ status = "disabled";
+ };
+
++ tpu: pwm@e6e80000 {
++ compatible = "renesas,tpu-r8a77970", "renesas,tpu";
++ reg = <0 0xe6e80000 0 0x148>;
++ interrupts = <GIC_SPI 135 IRQ_TYPE_LEVEL_HIGH>;
++ clocks = <&cpg CPG_MOD 304>;
++ power-domains = <&sysc R8A77970_PD_ALWAYS_ON>;
++ resets = <&cpg 304>;
++ #pwm-cells = <3>;
++ status = "disabled";
++ };
+
+ vin0: video@e6ef0000 {
+ compatible = "renesas,vin-r8a77970";
+diff --git a/arch/arm64/boot/dts/renesas/r8a77980.dtsi b/arch/arm64/boot/dts/renesas/r8a77980.dtsi
+index cb135f6..a5cba94 100644
+--- a/arch/arm64/boot/dts/renesas/r8a77980.dtsi
++++ b/arch/arm64/boot/dts/renesas/r8a77980.dtsi
+@@ -666,6 +666,17 @@
+ status = "disabled";
+ };
+
++ tpu: pwm@e6e80000 {
++ compatible = "renesas,tpu-r8a77980", "renesas,tpu";
++ reg = <0 0xe6e80000 0 0x148>;
++ interrupts = <GIC_SPI 135 IRQ_TYPE_LEVEL_HIGH>;
++ clocks = <&cpg CPG_MOD 304>;
++ power-domains = <&sysc R8A77980_PD_ALWAYS_ON>;
++ resets = <&cpg 304>;
++ #pwm-cells = <3>;
++ status = "disabled";
++ };
++
+ vin0: video@e6ef0000 {
+ compatible = "renesas,vin-r8a77980";
+ reg = <0 0xe6ef0000 0 0x1000>;
+--
+2.7.4
+
diff --git a/bsp/meta-rcar/meta-rcar-gen3-adas/recipes-kernel/linux/linux-renesas/0220-arm64-dts-renesas-r8a779-7-8-0-add-PWM-support.patch b/bsp/meta-rcar/meta-rcar-gen3-adas/recipes-kernel/linux/linux-renesas/0220-arm64-dts-renesas-r8a779-7-8-0-add-PWM-support.patch
new file mode 100644
index 00000000..3c6b2378
--- /dev/null
+++ b/bsp/meta-rcar/meta-rcar-gen3-adas/recipes-kernel/linux/linux-renesas/0220-arm64-dts-renesas-r8a779-7-8-0-add-PWM-support.patch
@@ -0,0 +1,145 @@
+From f91a8bff14bb02353e97de882a3dede67986165e Mon Sep 17 00:00:00 2001
+From: Sergei Shtylyov <sergei.shtylyov@cogentembedded.com>
+Date: Mon, 1 Oct 2018 23:25:43 +0300
+Subject: [PATCH 040/211] arm64: dts: renesas: r8a779{7|8}0: add PWM support
+
+Describe PWMs in the R8A779{7|8}0 device trees.
+
+Based on the original (and large) patches by Vladimir Barinov.
+
+Signed-off-by: Vladimir Barinov <vladimir.barinov@cogentembedded.com>
+Signed-off-by: Sergei Shtylyov <sergei.shtylyov@cogentembedded.com>
+Reviewed-by: Geert Uytterhoeven <geert+renesas@glider.be>
+Signed-off-by: Simon Horman <horms+renesas@verge.net.au>
+(cherry picked from commit b729c69f1d41b819f662e461f0ca793bb009f746)
+Signed-off-by: Valentine Barshak <valentine.barshak@cogentembedded.com>
+---
+ arch/arm64/boot/dts/renesas/r8a77970.dtsi | 50 +++++++++++++++++++++++++++++++
+ arch/arm64/boot/dts/renesas/r8a77980.dtsi | 50 +++++++++++++++++++++++++++++++
+ 2 files changed, 100 insertions(+)
+
+diff --git a/arch/arm64/boot/dts/renesas/r8a77970.dtsi b/arch/arm64/boot/dts/renesas/r8a77970.dtsi
+index cba7885..e58040e 100644
+--- a/arch/arm64/boot/dts/renesas/r8a77970.dtsi
++++ b/arch/arm64/boot/dts/renesas/r8a77970.dtsi
+@@ -543,6 +543,56 @@
+ status = "disabled";
+ };
+
++ pwm0: pwm@e6e30000 {
++ compatible = "renesas,pwm-r8a77970", "renesas,pwm-rcar";
++ reg = <0 0xe6e30000 0 8>;
++ #pwm-cells = <2>;
++ clocks = <&cpg CPG_MOD 523>;
++ power-domains = <&sysc R8A77970_PD_ALWAYS_ON>;
++ resets = <&cpg 523>;
++ status = "disabled";
++ };
++
++ pwm1: pwm@e6e31000 {
++ compatible = "renesas,pwm-r8a77970", "renesas,pwm-rcar";
++ reg = <0 0xe6e31000 0 8>;
++ #pwm-cells = <2>;
++ clocks = <&cpg CPG_MOD 523>;
++ power-domains = <&sysc R8A77970_PD_ALWAYS_ON>;
++ resets = <&cpg 523>;
++ status = "disabled";
++ };
++
++ pwm2: pwm@e6e32000 {
++ compatible = "renesas,pwm-r8a77970", "renesas,pwm-rcar";
++ reg = <0 0xe6e32000 0 8>;
++ #pwm-cells = <2>;
++ clocks = <&cpg CPG_MOD 523>;
++ power-domains = <&sysc R8A77970_PD_ALWAYS_ON>;
++ resets = <&cpg 523>;
++ status = "disabled";
++ };
++
++ pwm3: pwm@e6e33000 {
++ compatible = "renesas,pwm-r8a7790", "renesas,pwm-rcar";
++ reg = <0 0xe6e33000 0 8>;
++ #pwm-cells = <2>;
++ clocks = <&cpg CPG_MOD 523>;
++ power-domains = <&sysc R8A77970_PD_ALWAYS_ON>;
++ resets = <&cpg 523>;
++ status = "disabled";
++ };
++
++ pwm4: pwm@e6e34000 {
++ compatible = "renesas,pwm-r8a77970", "renesas,pwm-rcar";
++ reg = <0 0xe6e34000 0 8>;
++ #pwm-cells = <2>;
++ clocks = <&cpg CPG_MOD 523>;
++ power-domains = <&sysc R8A77970_PD_ALWAYS_ON>;
++ resets = <&cpg 523>;
++ status = "disabled";
++ };
++
+ scif0: serial@e6e60000 {
+ compatible = "renesas,scif-r8a77970",
+ "renesas,rcar-gen3-scif",
+diff --git a/arch/arm64/boot/dts/renesas/r8a77980.dtsi b/arch/arm64/boot/dts/renesas/r8a77980.dtsi
+index a5cba94..53d5dce 100644
+--- a/arch/arm64/boot/dts/renesas/r8a77980.dtsi
++++ b/arch/arm64/boot/dts/renesas/r8a77980.dtsi
+@@ -594,6 +594,56 @@
+ status = "disabled";
+ };
+
++ pwm0: pwm@e6e30000 {
++ compatible = "renesas,pwm-r8a77980", "renesas,pwm-rcar";
++ reg = <0 0xe6e30000 0 0x10>;
++ #pwm-cells = <2>;
++ clocks = <&cpg CPG_MOD 523>;
++ power-domains = <&sysc R8A77980_PD_ALWAYS_ON>;
++ resets = <&cpg 523>;
++ status = "disabled";
++ };
++
++ pwm1: pwm@e6e31000 {
++ compatible = "renesas,pwm-r8a77980", "renesas,pwm-rcar";
++ reg = <0 0xe6e31000 0 0x10>;
++ #pwm-cells = <2>;
++ clocks = <&cpg CPG_MOD 523>;
++ power-domains = <&sysc R8A77980_PD_ALWAYS_ON>;
++ resets = <&cpg 523>;
++ status = "disabled";
++ };
++
++ pwm2: pwm@e6e32000 {
++ compatible = "renesas,pwm-r8a77980", "renesas,pwm-rcar";
++ reg = <0 0xe6e32000 0 0x10>;
++ #pwm-cells = <2>;
++ clocks = <&cpg CPG_MOD 523>;
++ power-domains = <&sysc R8A77980_PD_ALWAYS_ON>;
++ resets = <&cpg 523>;
++ status = "disabled";
++ };
++
++ pwm3: pwm@e6e33000 {
++ compatible = "renesas,pwm-r8a77980", "renesas,pwm-rcar";
++ reg = <0 0xe6e33000 0 0x10>;
++ #pwm-cells = <2>;
++ clocks = <&cpg CPG_MOD 523>;
++ power-domains = <&sysc R8A77980_PD_ALWAYS_ON>;
++ resets = <&cpg 523>;
++ status = "disabled";
++ };
++
++ pwm4: pwm@e6e34000 {
++ compatible = "renesas,pwm-r8a77980", "renesas,pwm-rcar";
++ reg = <0 0xe6e34000 0 0x10>;
++ #pwm-cells = <2>;
++ clocks = <&cpg CPG_MOD 523>;
++ power-domains = <&sysc R8A77980_PD_ALWAYS_ON>;
++ resets = <&cpg 523>;
++ status = "disabled";
++ };
++
+ scif0: serial@e6e60000 {
+ compatible = "renesas,scif-r8a77980",
+ "renesas,rcar-gen3-scif",
+--
+2.7.4
+
diff --git a/bsp/meta-rcar/meta-rcar-gen3-adas/recipes-kernel/linux/linux-renesas/0221-media-vsp1-Use-header-display-lists-for-all-WPF-outp.patch b/bsp/meta-rcar/meta-rcar-gen3-adas/recipes-kernel/linux/linux-renesas/0221-media-vsp1-Use-header-display-lists-for-all-WPF-outp.patch
new file mode 100644
index 00000000..829a07d4
--- /dev/null
+++ b/bsp/meta-rcar/meta-rcar-gen3-adas/recipes-kernel/linux/linux-renesas/0221-media-vsp1-Use-header-display-lists-for-all-WPF-outp.patch
@@ -0,0 +1,274 @@
+From a35f2ec07393895a134d6ff993fa23454f3fbcad Mon Sep 17 00:00:00 2001
+From: Kieran Bingham <kieran.bingham+renesas@ideasonboard.com>
+Date: Fri, 3 Aug 2018 07:37:26 -0400
+Subject: [PATCH 041/211] media: vsp1: Use header display lists for all WPF
+ outputs linked to the DU
+
+Header mode display lists are now supported on all WPF outputs. To
+support extended headers and auto-fld capabilities for interlaced mode
+handling only header mode display lists can be used.
+
+Disable the headerless display list configuration, and remove the dead
+code.
+
+Signed-off-by: Kieran Bingham <kieran.bingham+renesas@ideasonboard.com>
+Signed-off-by: Laurent Pinchart <laurent.pinchart@ideasonboard.com>
+Signed-off-by: Mauro Carvalho Chehab <mchehab+samsung@kernel.org>
+(cherry picked from commit 08e41f6219c717d16bb22b53010ee7401c27fb11)
+[valentine.barshak: resolved conflicts due to commits: 693d3a9, 3469001]
+Signed-off-by: Valentine Barshak <valentine.barshak@cogentembedded.com>
+---
+ drivers/media/platform/vsp1/vsp1_dl.c | 127 ++++++++--------------------------
+ 1 file changed, 30 insertions(+), 97 deletions(-)
+
+diff --git a/drivers/media/platform/vsp1/vsp1_dl.c b/drivers/media/platform/vsp1/vsp1_dl.c
+index 925f8a7..48542854 100644
+--- a/drivers/media/platform/vsp1/vsp1_dl.c
++++ b/drivers/media/platform/vsp1/vsp1_dl.c
+@@ -129,7 +129,7 @@ struct vsp1_dl_body_pool {
+ * struct vsp1_dl_list - Display list
+ * @list: entry in the display list manager lists
+ * @dlm: the display list manager
+- * @header: display list header, NULL for headerless lists
++ * @header: display list header
+ * @dma: DMA address for the header
+ * @body0: first display list body
+ * @bodies: list of extra display list bodies
+@@ -153,15 +153,9 @@ struct vsp1_dl_list {
+ bool internal;
+ };
+
+-enum vsp1_dl_mode {
+- VSP1_DL_MODE_HEADER,
+- VSP1_DL_MODE_HEADERLESS,
+-};
+-
+ /**
+ * struct vsp1_dl_manager - Display List manager
+ * @index: index of the related WPF
+- * @mode: display list operation mode (header or headerless)
+ * @singleshot: execute the display list in single-shot mode
+ * @vsp1: the VSP1 device
+ * @lock: protects the free, active, queued, and pending lists
+@@ -173,7 +167,6 @@ enum vsp1_dl_mode {
+ */
+ struct vsp1_dl_manager {
+ unsigned int index;
+- enum vsp1_dl_mode mode;
+ bool singleshot;
+ struct vsp1_device *vsp1;
+
+@@ -448,6 +441,7 @@ void vsp1_dl_set_addr_auto_fld(struct vsp1_dl_body *dlb,
+ static struct vsp1_dl_list *vsp1_dl_list_alloc(struct vsp1_dl_manager *dlm)
+ {
+ struct vsp1_dl_list *dl;
++ size_t header_offset;
+
+ dl = kzalloc(sizeof(*dl), GFP_KERNEL);
+ if (!dl)
+@@ -460,16 +454,14 @@ static struct vsp1_dl_list *vsp1_dl_list_alloc(struct vsp1_dl_manager *dlm)
+ dl->body0 = vsp1_dl_body_get(dlm->pool);
+ if (!dl->body0)
+ return NULL;
+- if (dlm->mode == VSP1_DL_MODE_HEADER) {
+- size_t header_offset = dl->body0->max_entries
+- * sizeof(*dl->body0->entries);
+
+- dl->header = ((void *)dl->body0->entries) + header_offset;
+- dl->dma = dl->body0->dma + header_offset;
++ header_offset = dl->body0->max_entries * sizeof(*dl->body0->entries);
+
+- memset(dl->header, 0, sizeof(*dl->header));
+- dl->header->lists[0].addr = dl->body0->dma;
+- }
++ dl->header = ((void *)dl->body0->entries) + header_offset;
++ dl->dma = dl->body0->dma + header_offset;
++
++ memset(dl->header, 0, sizeof(*dl->header));
++ dl->header->lists[0].addr = dl->body0->dma;
+
+ return dl;
+ }
+@@ -601,16 +593,9 @@ struct vsp1_dl_body *vsp1_dl_list_get_body0(struct vsp1_dl_list *dl)
+ *
+ * The reference must be explicitly released by a call to vsp1_dl_body_put()
+ * when the body isn't needed anymore.
+- *
+- * Additional bodies are only usable for display lists in header mode.
+- * Attempting to add a body to a header-less display list will return an error.
+ */
+ int vsp1_dl_list_add_body(struct vsp1_dl_list *dl, struct vsp1_dl_body *dlb)
+ {
+- /* Multi-body lists are only available in header mode. */
+- if (dl->dlm->mode != VSP1_DL_MODE_HEADER)
+- return -EINVAL;
+-
+ refcount_inc(&dlb->refcnt);
+
+ list_add_tail(&dlb->list, &dl->bodies);
+@@ -631,17 +616,10 @@ int vsp1_dl_list_add_body(struct vsp1_dl_list *dl, struct vsp1_dl_body *dlb)
+ * Adding a display list to a chain passes ownership of the display list to
+ * the head display list item. The chain is released when the head dl item is
+ * put back with __vsp1_dl_list_put().
+- *
+- * Chained display lists are only usable in header mode. Attempts to add a
+- * display list to a chain in header-less mode will return an error.
+ */
+ int vsp1_dl_list_add_chain(struct vsp1_dl_list *head,
+ struct vsp1_dl_list *dl)
+ {
+- /* Chained lists are only available in header mode. */
+- if (head->dlm->mode != VSP1_DL_MODE_HEADER)
+- return -EINVAL;
+-
+ head->has_chain = true;
+ list_add_tail(&dl->chain, &head->chain);
+ return 0;
+@@ -744,17 +722,10 @@ static bool vsp1_dl_list_hw_update_pending(struct vsp1_dl_manager *dlm)
+ return false;
+
+ /*
+- * Check whether the VSP1 has taken the update. In headerless mode the
+- * hardware indicates this by clearing the UPD bit in the DL_BODY_SIZE
+- * register, and in header mode by clearing the UPDHDR bit in the CMD
+- * register.
++ * Check whether the VSP1 has taken the update. The hardware indicates
++ * this by clearing the UPDHDR bit in the CMD register.
+ */
+- if (dlm->mode == VSP1_DL_MODE_HEADERLESS)
+- return !!(vsp1_read(vsp1, VI6_DL_BODY_SIZE)
+- & VI6_DL_BODY_SIZE_UPD);
+- else
+- return !!(vsp1_read(vsp1, VI6_CMD(dlm->index))
+- & VI6_CMD_UPDHDR);
++ return !!(vsp1_read(vsp1, VI6_CMD(dlm->index)) & VI6_CMD_UPDHDR);
+ }
+
+ static void vsp1_dl_list_hw_enqueue(struct vsp1_dl_list *dl)
+@@ -762,34 +733,16 @@ static void vsp1_dl_list_hw_enqueue(struct vsp1_dl_list *dl)
+ struct vsp1_dl_manager *dlm = dl->dlm;
+ struct vsp1_device *vsp1 = dlm->vsp1;
+
+- if (dlm->mode == VSP1_DL_MODE_HEADERLESS) {
+- /*
+- * In headerless mode, program the hardware directly with the
+- * display list body address and size and set the UPD bit. The
+- * bit will be cleared by the hardware when the display list
+- * processing starts.
+- */
+- vsp1_write(vsp1, VI6_DL_HDR_ADDR(0), dl->body0->dma);
+- vsp1_write(vsp1, VI6_DL_BODY_SIZE, VI6_DL_BODY_SIZE_UPD |
+- (dl->body0->num_entries * sizeof(*dl->header->lists)));
+- if (vsp1->ths_quirks & VSP1_UNDERRUN_WORKAROUND) {
+- vsp1->dl_addr = dl->body0->dma;
+- vsp1->dl_body = VI6_DL_BODY_SIZE_UPD |
+- (dl->body0->num_entries *
+- sizeof(*dl->header->lists));
+- }
+- } else {
+- /*
+- * In header mode, program the display list header address. If
+- * the hardware is idle (single-shot mode or first frame in
+- * continuous mode) it will then be started independently. If
+- * the hardware is operating, the VI6_DL_HDR_REF_ADDR register
+- * will be updated with the display list address.
+- */
+- vsp1_write(vsp1, VI6_DL_HDR_ADDR(dlm->index), dl->dma);
+- if (vsp1->ths_quirks & VSP1_UNDERRUN_WORKAROUND)
+- vsp1->dl_addr = dl->dma;
+- }
++ /*
++ * Program the display list header address. If the hardware is idle
++ * (single-shot mode or first frame in continuous mode) it will then be
++ * started independently. If the hardware is operating, the
++ * VI6_DL_HDR_REF_ADDR register will be updated with the display list
++ * address.
++ */
++ vsp1_write(vsp1, VI6_DL_HDR_ADDR(dlm->index), dl->dma);
++ if (vsp1->ths_quirks & VSP1_UNDERRUN_WORKAROUND)
++ vsp1->dl_addr = dl->dma;
+ }
+
+ static void vsp1_dl_list_commit_continuous(struct vsp1_dl_list *dl)
+@@ -848,16 +801,14 @@ void vsp1_dl_list_commit(struct vsp1_dl_list *dl, bool internal,
+ struct vsp1_dl_list *dl_child;
+ unsigned long flags;
+
+- if (dlm->mode == VSP1_DL_MODE_HEADER) {
+- /* Fill the header for the head and chained display lists. */
+- vsp1_dl_list_fill_header(dl, list_empty(&dl->chain),
+- pipe_index);
++ /* Fill the header for the head and chained display lists. */
++ vsp1_dl_list_fill_header(dl, list_empty(&dl->chain),
++ pipe_index);
+
+- list_for_each_entry(dl_child, &dl->chain, chain) {
+- bool last = list_is_last(&dl_child->chain, &dl->chain);
++ list_for_each_entry(dl_child, &dl->chain, chain) {
++ bool last = list_is_last(&dl_child->chain, &dl->chain);
+
+- vsp1_dl_list_fill_header(dl_child, last, pipe_index);
+- }
++ vsp1_dl_list_fill_header(dl_child, last, pipe_index);
+ }
+
+ dl->internal = internal;
+@@ -886,7 +837,7 @@ void vsp1_dl_list_commit(struct vsp1_dl_list *dl, bool internal,
+ * has completed at frame end. If the flag is not returned display list
+ * completion has been delayed by one frame because the display list commit
+ * raced with the frame end interrupt. The function always returns with the flag
+- * set in header mode as display list processing is then not continuous and
++ * set in single-shot mode as display list processing is then not continuous and
+ * races never occur.
+ *
+ * The VSP1_DL_FRAME_END_INTERNAL flag indicates that the previous display list
+@@ -970,13 +921,6 @@ void vsp1_dlm_setup(struct vsp1_device *vsp1, unsigned int pipe_index)
+ (0x02 << VI6_DL_EXT_CTRL_POLINT_SHIFT) |
+ VI6_DL_EXT_CTRL_DLPRI | VI6_DL_EXT_CTRL_EXT);
+ }
+- /*
+- * The DRM pipeline operates with display lists in Continuous Frame
+- * Mode, all other pipelines use manual start.
+- */
+- if (vsp1->drm && vsp1->info->uapi)
+- ctrl |= VI6_DL_CTRL_CFM0 | VI6_DL_CTRL_NH0;
+-
+ vsp1_write(vsp1, VI6_DL_CTRL, ctrl);
+ vsp1_write(vsp1, VI6_DL_SWAP(pipe_index), VI6_DL_SWAP_LWS |
+ ((pipe_index == 1) ? VI6_DL_SWAP_IND : 0));
+@@ -1017,15 +961,6 @@ struct vsp1_dl_manager *vsp1_dlm_create(struct vsp1_device *vsp1,
+ return NULL;
+
+ dlm->index = index;
+- dlm->mode = index == 0 && !vsp1->info->uapi
+- ? VSP1_DL_MODE_HEADERLESS : VSP1_DL_MODE_HEADER;
+-
+- if (((vsp1->version & VI6_IP_VERSION_MODEL_MASK) ==
+- VI6_IP_VERSION_MODEL_VSPDL_GEN3) ||
+- (vsp1->version & VI6_IP_VERSION_MODEL_MASK) ==
+- VI6_IP_VERSION_MODEL_VSPD_GEN3)
+- dlm->mode = VSP1_DL_MODE_HEADER;
+-
+ dlm->singleshot = vsp1->info->uapi;
+ dlm->vsp1 = vsp1;
+
+@@ -1034,14 +969,12 @@ struct vsp1_dl_manager *vsp1_dlm_create(struct vsp1_device *vsp1,
+
+ /*
+ * Initialize the display list body and allocate DMA memory for the body
+- * and the optional header. Both are allocated together to avoid memory
++ * and the header. Both are allocated together to avoid memory
+ * fragmentation, with the header located right after the body in
+ * memory. An extra body is allocated on top of the prealloc to account
+ * for the cached body used by the vsp1_pipeline object.
+ */
+- header_size = dlm->mode == VSP1_DL_MODE_HEADER
+- ? ALIGN(sizeof(struct vsp1_dl_header), 8)
+- : 0;
++ header_size = ALIGN(sizeof(struct vsp1_dl_header), 8);
+
+ if (!vsp1->info->uapi &&
+ !(vsp1->ths_quirks & VSP1_AUTO_FLD_NOT_SUPPORT)) {
+--
+2.7.4
+
diff --git a/bsp/meta-rcar/meta-rcar-gen3-adas/recipes-kernel/linux/linux-renesas/0222-arm64-dts-renesas-r8a77970-add-thermal-support.patch b/bsp/meta-rcar/meta-rcar-gen3-adas/recipes-kernel/linux/linux-renesas/0222-arm64-dts-renesas-r8a77970-add-thermal-support.patch
new file mode 100644
index 00000000..ed894a51
--- /dev/null
+++ b/bsp/meta-rcar/meta-rcar-gen3-adas/recipes-kernel/linux/linux-renesas/0222-arm64-dts-renesas-r8a77970-add-thermal-support.patch
@@ -0,0 +1,72 @@
+From 1db57fb02780239e6f00e9c1083ee1caefb794c3 Mon Sep 17 00:00:00 2001
+From: Sergei Shtylyov <sergei.shtylyov@cogentembedded.com>
+Date: Tue, 9 Oct 2018 22:47:47 +0300
+Subject: [PATCH 042/211] arm64: dts: renesas: r8a77970: add thermal support
+
+Describe THS/CIVM in the R8A77970 device tree.
+
+Based on the original (and large) patches by Vladimir Barinov.
+
+Signed-off-by: Vladimir Barinov <vladimir.barinov@cogentembedded.com>
+Signed-off-by: Sergei Shtylyov <sergei.shtylyov@cogentembedded.com>
+Reviewed-by: Geert Uytterhoeven <geert+renesas@glider.be>
+Signed-off-by: Simon Horman <horms+renesas@verge.net.au>
+(cherry picked from commit c980ed422cd3e82accd1ca40be9501e5134aac5f)
+Signed-off-by: Valentine Barshak <valentine.barshak@cogentembedded.com>
+---
+ arch/arm64/boot/dts/renesas/r8a77970.dtsi | 32 +++++++++++++++++++++++++++++++
+ 1 file changed, 32 insertions(+)
+
+diff --git a/arch/arm64/boot/dts/renesas/r8a77970.dtsi b/arch/arm64/boot/dts/renesas/r8a77970.dtsi
+index e58040e..ba903fc 100644
+--- a/arch/arm64/boot/dts/renesas/r8a77970.dtsi
++++ b/arch/arm64/boot/dts/renesas/r8a77970.dtsi
+@@ -300,6 +300,19 @@
+ #power-domain-cells = <1>;
+ };
+
++ thermal: thermal@e6190000 {
++ compatible = "renesas,thermal-r8a77970";
++ reg = <0 0xe6190000 0 0x10
++ 0 0xe6190100 0 0x120>;
++ interrupts = <GIC_SPI 67 IRQ_TYPE_LEVEL_HIGH>,
++ <GIC_SPI 68 IRQ_TYPE_LEVEL_HIGH>,
++ <GIC_SPI 69 IRQ_TYPE_LEVEL_HIGH>;
++ clocks = <&cpg CPG_MOD 522>;
++ power-domains = <&sysc R8A77970_PD_ALWAYS_ON>;
++ resets = <&cpg 522>;
++ #thermal-sensor-cells = <0>;
++ };
++
+ intc_ex: interrupt-controller@e61c0000 {
+ compatible = "renesas,intc-ex-r8a77970", "renesas,irqc";
+ #interrupt-cells = <2>;
+@@ -1033,6 +1046,25 @@
+ };
+ };
+
++ thermal-zones {
++ cpu-thermal {
++ polling-delay-passive = <250>;
++ polling-delay = <1000>;
++ thermal-sensors = <&thermal>;
++
++ trips {
++ cpu-crit {
++ temperature = <120000>;
++ hysteresis = <2000>;
++ type = "critical";
++ };
++ };
++
++ cooling-maps {
++ };
++ };
++ };
++
+ timer {
+ compatible = "arm,armv8-timer";
+ interrupts-extended = <&gic GIC_PPI 13 (GIC_CPU_MASK_SIMPLE(2) | IRQ_TYPE_LEVEL_LOW)>,
+--
+2.7.4
+
diff --git a/bsp/meta-rcar/meta-rcar-gen3-adas/recipes-kernel/linux/linux-renesas/0223-arm64-dts-renesas-r8a77980-add-thermal-support.patch b/bsp/meta-rcar/meta-rcar-gen3-adas/recipes-kernel/linux/linux-renesas/0223-arm64-dts-renesas-r8a77980-add-thermal-support.patch
new file mode 100644
index 00000000..32e26b6f
--- /dev/null
+++ b/bsp/meta-rcar/meta-rcar-gen3-adas/recipes-kernel/linux/linux-renesas/0223-arm64-dts-renesas-r8a77980-add-thermal-support.patch
@@ -0,0 +1,93 @@
+From aedd723e67490511738a4da0c0065999eb8925cc Mon Sep 17 00:00:00 2001
+From: Sergei Shtylyov <sergei.shtylyov@cogentembedded.com>
+Date: Wed, 10 Oct 2018 22:18:11 +0300
+Subject: [PATCH 043/211] arm64: dts: renesas: r8a77980: add thermal support
+MIME-Version: 1.0
+Content-Type: text/plain; charset=UTF-8
+Content-Transfer-Encoding: 8bit
+
+Describe THS/CIVM in the R8A77980 device trees.
+
+Signed-off-by: Sergei Shtylyov <sergei.shtylyov@cogentembedded.com>
+Reviewed-by: Niklas Söderlund <niklas.soderlund+renesas@ragnatech.se>
+Signed-off-by: Simon Horman <horms+renesas@verge.net.au>
+(cherry picked from commit 4229ee439a2d8bead6c49145b1b2ca7b69e008c0)
+Signed-off-by: Valentine Barshak <valentine.barshak@cogentembedded.com>
+---
+ arch/arm64/boot/dts/renesas/r8a77980.dtsi | 53 +++++++++++++++++++++++++++++++
+ 1 file changed, 53 insertions(+)
+
+diff --git a/arch/arm64/boot/dts/renesas/r8a77980.dtsi b/arch/arm64/boot/dts/renesas/r8a77980.dtsi
+index 53d5dce..f2c32b5 100644
+--- a/arch/arm64/boot/dts/renesas/r8a77980.dtsi
++++ b/arch/arm64/boot/dts/renesas/r8a77980.dtsi
+@@ -330,6 +330,19 @@
+ #power-domain-cells = <1>;
+ };
+
++ tsc: thermal@e6198000 {
++ compatible = "renesas,r8a77980-thermal";
++ reg = <0 0xe6198000 0 0x100>,
++ <0 0xe61a0000 0 0x100>;
++ interrupts = <GIC_SPI 67 IRQ_TYPE_LEVEL_HIGH>,
++ <GIC_SPI 68 IRQ_TYPE_LEVEL_HIGH>,
++ <GIC_SPI 69 IRQ_TYPE_LEVEL_HIGH>;
++ clocks = <&cpg CPG_MOD 522>;
++ power-domains = <&sysc R8A77980_PD_ALWAYS_ON>;
++ resets = <&cpg 522>;
++ #thermal-sensor-cells = <1>;
++ };
++
+ intc_ex: interrupt-controller@e61c0000 {
+ compatible = "renesas,intc-ex-r8a77980", "renesas,irqc";
+ #interrupt-cells = <2>;
+@@ -1404,6 +1417,46 @@
+ };
+ };
+
++ thermal-zones {
++ thermal-sensor-1 {
++ polling-delay-passive = <250>;
++ polling-delay = <1000>;
++ thermal-sensors = <&tsc 0>;
++
++ trips {
++ sensor1-passive {
++ temperature = <95000>;
++ hysteresis = <1000>;
++ type = "passive";
++ };
++ sensor1-critical {
++ temperature = <120000>;
++ hysteresis = <1000>;
++ type = "critical";
++ };
++ };
++ };
++
++ thermal-sensor-2 {
++ polling-delay-passive = <250>;
++ polling-delay = <1000>;
++ thermal-sensors = <&tsc 1>;
++
++ trips {
++ sensor2-passive {
++ temperature = <95000>;
++ hysteresis = <1000>;
++ type = "passive";
++ };
++ sensor2-critical {
++ temperature = <120000>;
++ hysteresis = <1000>;
++ type = "critical";
++ };
++ };
++ };
++ };
++
+ timer {
+ compatible = "arm,armv8-timer";
+ interrupts-extended = <&gic GIC_PPI 13 (GIC_CPU_MASK_SIMPLE(4) |
+--
+2.7.4
+
diff --git a/bsp/meta-rcar/meta-rcar-gen3-adas/recipes-kernel/linux/linux-renesas/0224-arm64-dts-renesas-r8a779-7-8-0-add-TMU-support.patch b/bsp/meta-rcar/meta-rcar-gen3-adas/recipes-kernel/linux/linux-renesas/0224-arm64-dts-renesas-r8a779-7-8-0-add-TMU-support.patch
new file mode 100644
index 00000000..956716b4
--- /dev/null
+++ b/bsp/meta-rcar/meta-rcar-gen3-adas/recipes-kernel/linux/linux-renesas/0224-arm64-dts-renesas-r8a779-7-8-0-add-TMU-support.patch
@@ -0,0 +1,174 @@
+From 0d39e40c1c415f1912465f6b3d0ac35298499312 Mon Sep 17 00:00:00 2001
+From: Sergei Shtylyov <sergei.shtylyov@cogentembedded.com>
+Date: Mon, 24 Sep 2018 23:13:41 +0300
+Subject: [PATCH 044/211] arm64: dts: renesas: r8a779{7|8}0: add TMU support
+
+Describe TMUs in the R8A779{7|8}0 device trees.
+
+Based on the original (and large) patches by Vladimir Barinov.
+
+Signed-off-by: Vladimir Barinov <vladimir.barinov@cogentembedded.com>
+Signed-off-by: Sergei Shtylyov <sergei.shtylyov@cogentembedded.com>
+Signed-off-by: Simon Horman <horms+renesas@verge.net.au>
+(cherry picked from commit 09ff63cbc6a95f2d69d07e7a04883446ad710271)
+Signed-off-by: Valentine Barshak <valentine.barshak@cogentembedded.com>
+---
+ arch/arm64/boot/dts/renesas/r8a77970.dtsi | 65 +++++++++++++++++++++++++++++++
+ arch/arm64/boot/dts/renesas/r8a77980.dtsi | 65 +++++++++++++++++++++++++++++++
+ 2 files changed, 130 insertions(+)
+
+diff --git a/arch/arm64/boot/dts/renesas/r8a77970.dtsi b/arch/arm64/boot/dts/renesas/r8a77970.dtsi
+index ba903fc..65f3ad4 100644
+--- a/arch/arm64/boot/dts/renesas/r8a77970.dtsi
++++ b/arch/arm64/boot/dts/renesas/r8a77970.dtsi
+@@ -329,6 +329,71 @@
+ resets = <&cpg 407>;
+ };
+
++ tmu0: timer@e61e0000 {
++ compatible = "renesas,tmu-r8a77970", "renesas,tmu";
++ reg = <0 0xe61e0000 0 0x30>;
++ interrupts = <GIC_SPI 136 IRQ_TYPE_LEVEL_HIGH>,
++ <GIC_SPI 137 IRQ_TYPE_LEVEL_HIGH>,
++ <GIC_SPI 138 IRQ_TYPE_LEVEL_HIGH>;
++ clocks = <&cpg CPG_MOD 125>;
++ clock-names = "fck";
++ power-domains = <&sysc R8A77970_PD_ALWAYS_ON>;
++ resets = <&cpg 125>;
++ status = "disabled";
++ };
++
++ tmu1: timer@e6fc0000 {
++ compatible = "renesas,tmu-r8a77970", "renesas,tmu";
++ reg = <0 0xe6fc0000 0 0x30>;
++ interrupts = <GIC_SPI 128 IRQ_TYPE_LEVEL_HIGH>,
++ <GIC_SPI 129 IRQ_TYPE_LEVEL_HIGH>,
++ <GIC_SPI 130 IRQ_TYPE_LEVEL_HIGH>;
++ clocks = <&cpg CPG_MOD 124>;
++ clock-names = "fck";
++ power-domains = <&sysc R8A77970_PD_ALWAYS_ON>;
++ resets = <&cpg 124>;
++ status = "disabled";
++ };
++
++ tmu2: timer@e6fd0000 {
++ compatible = "renesas,tmu-r8a77970", "renesas,tmu";
++ reg = <0 0xe6fd0000 0 0x30>;
++ interrupts = <GIC_SPI 303 IRQ_TYPE_LEVEL_HIGH>,
++ <GIC_SPI 304 IRQ_TYPE_LEVEL_HIGH>,
++ <GIC_SPI 305 IRQ_TYPE_LEVEL_HIGH>;
++ clocks = <&cpg CPG_MOD 123>;
++ clock-names = "fck";
++ power-domains = <&sysc R8A77970_PD_ALWAYS_ON>;
++ resets = <&cpg 123>;
++ status = "disabled";
++ };
++
++ tmu3: timer@e6fe0000 {
++ compatible = "renesas,tmu-r8a77970", "renesas,tmu";
++ reg = <0 0xe6fe0000 0 0x30>;
++ interrupts = <GIC_SPI 131 IRQ_TYPE_LEVEL_HIGH>,
++ <GIC_SPI 132 IRQ_TYPE_LEVEL_HIGH>,
++ <GIC_SPI 133 IRQ_TYPE_LEVEL_HIGH>;
++ clocks = <&cpg CPG_MOD 122>;
++ clock-names = "fck";
++ power-domains = <&sysc R8A77970_PD_ALWAYS_ON>;
++ resets = <&cpg 122>;
++ status = "disabled";
++ };
++
++ tmu4: timer@ffc00000 {
++ compatible = "renesas,tmu-r8a77970", "renesas,tmu";
++ reg = <0 0xffc00000 0 0x30>;
++ interrupts = <GIC_SPI 116 IRQ_TYPE_LEVEL_HIGH>,
++ <GIC_SPI 117 IRQ_TYPE_LEVEL_HIGH>,
++ <GIC_SPI 118 IRQ_TYPE_LEVEL_HIGH>;
++ clocks = <&cpg CPG_MOD 121>;
++ clock-names = "fck";
++ power-domains = <&sysc R8A77970_PD_ALWAYS_ON>;
++ resets = <&cpg 121>;
++ status = "disabled";
++ };
++
+ i2c0: i2c@e6500000 {
+ compatible = "renesas,i2c-r8a77970",
+ "renesas,rcar-gen3-i2c";
+diff --git a/arch/arm64/boot/dts/renesas/r8a77980.dtsi b/arch/arm64/boot/dts/renesas/r8a77980.dtsi
+index f2c32b5..8e4cd1b 100644
+--- a/arch/arm64/boot/dts/renesas/r8a77980.dtsi
++++ b/arch/arm64/boot/dts/renesas/r8a77980.dtsi
+@@ -359,6 +359,71 @@
+ resets = <&cpg 407>;
+ };
+
++ tmu0: timer@e61e0000 {
++ compatible = "renesas,tmu-r8a77980", "renesas,tmu";
++ reg = <0 0xe61e0000 0 0x30>;
++ interrupts = <GIC_SPI 136 IRQ_TYPE_LEVEL_HIGH>,
++ <GIC_SPI 137 IRQ_TYPE_LEVEL_HIGH>,
++ <GIC_SPI 138 IRQ_TYPE_LEVEL_HIGH>;
++ clocks = <&cpg CPG_MOD 125>;
++ clock-names = "fck";
++ power-domains = <&sysc R8A77980_PD_ALWAYS_ON>;
++ resets = <&cpg 125>;
++ status = "disabled";
++ };
++
++ tmu1: timer@e6fc0000 {
++ compatible = "renesas,tmu-r8a77980", "renesas,tmu";
++ reg = <0 0xe6fc0000 0 0x30>;
++ interrupts = <GIC_SPI 128 IRQ_TYPE_LEVEL_HIGH>,
++ <GIC_SPI 129 IRQ_TYPE_LEVEL_HIGH>,
++ <GIC_SPI 130 IRQ_TYPE_LEVEL_HIGH>;
++ clocks = <&cpg CPG_MOD 124>;
++ clock-names = "fck";
++ power-domains = <&sysc R8A77980_PD_ALWAYS_ON>;
++ resets = <&cpg 124>;
++ status = "disabled";
++ };
++
++ tmu2: timer@e6fd0000 {
++ compatible = "renesas,tmu-r8a77980", "renesas,tmu";
++ reg = <0 0xe6fd0000 0 0x30>;
++ interrupts = <GIC_SPI 303 IRQ_TYPE_LEVEL_HIGH>,
++ <GIC_SPI 304 IRQ_TYPE_LEVEL_HIGH>,
++ <GIC_SPI 305 IRQ_TYPE_LEVEL_HIGH>;
++ clocks = <&cpg CPG_MOD 123>;
++ clock-names = "fck";
++ power-domains = <&sysc R8A77980_PD_ALWAYS_ON>;
++ resets = <&cpg 123>;
++ status = "disabled";
++ };
++
++ tmu3: timer@e6fe0000 {
++ compatible = "renesas,tmu-r8a77980", "renesas,tmu";
++ reg = <0 0xe6fe0000 0 0x30>;
++ interrupts = <GIC_SPI 131 IRQ_TYPE_LEVEL_HIGH>,
++ <GIC_SPI 132 IRQ_TYPE_LEVEL_HIGH>,
++ <GIC_SPI 133 IRQ_TYPE_LEVEL_HIGH>;
++ clocks = <&cpg CPG_MOD 122>;
++ clock-names = "fck";
++ power-domains = <&sysc R8A77980_PD_ALWAYS_ON>;
++ resets = <&cpg 122>;
++ status = "disabled";
++ };
++
++ tmu4: timer@ffc00000 {
++ compatible = "renesas,tmu-r8a77980", "renesas,tmu";
++ reg = <0 0xffc00000 0 0x30>;
++ interrupts = <GIC_SPI 116 IRQ_TYPE_LEVEL_HIGH>,
++ <GIC_SPI 117 IRQ_TYPE_LEVEL_HIGH>,
++ <GIC_SPI 118 IRQ_TYPE_LEVEL_HIGH>;
++ clocks = <&cpg CPG_MOD 121>;
++ clock-names = "fck";
++ power-domains = <&sysc R8A77980_PD_ALWAYS_ON>;
++ resets = <&cpg 121>;
++ status = "disabled";
++ };
++
+ i2c0: i2c@e6500000 {
+ compatible = "renesas,i2c-r8a77980",
+ "renesas,rcar-gen3-i2c";
+--
+2.7.4
+
diff --git a/bsp/meta-rcar/meta-rcar-gen3-adas/recipes-kernel/linux/linux-renesas/0225-arm64-dts-renesas-r8a779-7-8-0-add-MSIOF-support.patch b/bsp/meta-rcar/meta-rcar-gen3-adas/recipes-kernel/linux/linux-renesas/0225-arm64-dts-renesas-r8a779-7-8-0-add-MSIOF-support.patch
new file mode 100644
index 00000000..a5b90eb7
--- /dev/null
+++ b/bsp/meta-rcar/meta-rcar-gen3-adas/recipes-kernel/linux/linux-renesas/0225-arm64-dts-renesas-r8a779-7-8-0-add-MSIOF-support.patch
@@ -0,0 +1,163 @@
+From 8b6a59b481437fb9e2ec376d97213a2a38a392dd Mon Sep 17 00:00:00 2001
+From: Sergei Shtylyov <sergei.shtylyov@cogentembedded.com>
+Date: Fri, 19 Oct 2018 22:10:44 +0300
+Subject: [PATCH 045/211] arm64: dts: renesas: r8a779{7|8}0: add MSIOF support
+
+Describe MSIOF in the R8A779{7|8}0 device trees.
+
+The DMA props are omitted for R8A77980 as the RT-DMAC isn't supported
+(yet?)...
+
+Based on the original (and large) patches by Vladimir Barinov.
+
+Signed-off-by: Vladimir Barinov <vladimir.barinov@cogentembedded.com>
+Signed-off-by: Sergei Shtylyov <sergei.shtylyov@cogentembedded.com>
+Signed-off-by: Simon Horman <horms+renesas@verge.net.au>
+(cherry picked from commit 5af954f5b74ac43378fa47fb908d88147d4e3c41)
+Signed-off-by: Valentine Barshak <valentine.barshak@cogentembedded.com>
+---
+ arch/arm64/boot/dts/renesas/r8a77970.dtsi | 64 +++++++++++++++++++++++++++++++
+ arch/arm64/boot/dts/renesas/r8a77980.dtsi | 52 +++++++++++++++++++++++++
+ 2 files changed, 116 insertions(+)
+
+diff --git a/arch/arm64/boot/dts/renesas/r8a77970.dtsi b/arch/arm64/boot/dts/renesas/r8a77970.dtsi
+index 65f3ad4..563428d 100644
+--- a/arch/arm64/boot/dts/renesas/r8a77970.dtsi
++++ b/arch/arm64/boot/dts/renesas/r8a77970.dtsi
+@@ -753,6 +753,70 @@
+ status = "disabled";
+ };
+
++ msiof0: spi@e6e90000 {
++ compatible = "renesas,msiof-r8a77970",
++ "renesas,rcar-gen3-msiof";
++ reg = <0 0xe6e90000 0 0x64>;
++ interrupts = <GIC_SPI 156 IRQ_TYPE_LEVEL_HIGH>;
++ clocks = <&cpg CPG_MOD 211>;
++ power-domains = <&sysc R8A77970_PD_ALWAYS_ON>;
++ resets = <&cpg 211>;
++ dmas = <&dmac1 0x41>, <&dmac1 0x40>,
++ <&dmac2 0x41>, <&dmac2 0x40>;
++ dma-names = "tx", "rx", "tx", "rx";
++ #address-cells = <1>;
++ #size-cells = <0>;
++ status = "disabled";
++ };
++
++ msiof1: spi@e6ea0000 {
++ compatible = "renesas,msiof-r8a77970",
++ "renesas,rcar-gen3-msiof";
++ reg = <0 0xe6ea0000 0 0x0064>;
++ interrupts = <GIC_SPI 157 IRQ_TYPE_LEVEL_HIGH>;
++ clocks = <&cpg CPG_MOD 210>;
++ power-domains = <&sysc R8A77970_PD_ALWAYS_ON>;
++ resets = <&cpg 210>;
++ dmas = <&dmac1 0x43>, <&dmac1 0x42>,
++ <&dmac2 0x43>, <&dmac2 0x42>;
++ dma-names = "tx", "rx", "tx", "rx";
++ #address-cells = <1>;
++ #size-cells = <0>;
++ status = "disabled";
++ };
++
++ msiof2: spi@e6c00000 {
++ compatible = "renesas,msiof-r8a77970",
++ "renesas,rcar-gen3-msiof";
++ reg = <0 0xe6c00000 0 0x0064>;
++ interrupts = <GIC_SPI 158 IRQ_TYPE_LEVEL_HIGH>;
++ clocks = <&cpg CPG_MOD 209>;
++ power-domains = <&sysc R8A77970_PD_ALWAYS_ON>;
++ resets = <&cpg 209>;
++ dmas = <&dmac1 0x45>, <&dmac1 0x44>,
++ <&dmac2 0x45>, <&dmac2 0x44>;
++ dma-names = "tx", "rx", "tx", "rx";
++ #address-cells = <1>;
++ #size-cells = <0>;
++ status = "disabled";
++ };
++
++ msiof3: spi@e6c10000 {
++ compatible = "renesas,msiof-r8a77970",
++ "renesas,rcar-gen3-msiof";
++ reg = <0 0xe6c10000 0 0x0064>;
++ interrupts = <GIC_SPI 159 IRQ_TYPE_LEVEL_HIGH>;
++ clocks = <&cpg CPG_MOD 208>;
++ power-domains = <&sysc R8A77970_PD_ALWAYS_ON>;
++ resets = <&cpg 208>;
++ dmas = <&dmac1 0x47>, <&dmac1 0x46>,
++ <&dmac2 0x47>, <&dmac2 0x46>;
++ dma-names = "tx", "rx", "tx", "rx";
++ #address-cells = <1>;
++ #size-cells = <0>;
++ status = "disabled";
++ };
++
+ vin0: video@e6ef0000 {
+ compatible = "renesas,vin-r8a77970";
+ reg = <0 0xe6ef0000 0 0x1000>;
+diff --git a/arch/arm64/boot/dts/renesas/r8a77980.dtsi b/arch/arm64/boot/dts/renesas/r8a77980.dtsi
+index 8e4cd1b..c11ee04 100644
+--- a/arch/arm64/boot/dts/renesas/r8a77980.dtsi
++++ b/arch/arm64/boot/dts/renesas/r8a77980.dtsi
+@@ -805,6 +805,58 @@
+ status = "disabled";
+ };
+
++ msiof0: spi@e6e90000 {
++ compatible = "renesas,msiof-r8a77980",
++ "renesas,rcar-gen3-msiof";
++ reg = <0 0xe6e90000 0 0x64>;
++ interrupts = <GIC_SPI 156 IRQ_TYPE_LEVEL_HIGH>;
++ clocks = <&cpg CPG_MOD 211>;
++ power-domains = <&sysc R8A77980_PD_ALWAYS_ON>;
++ resets = <&cpg 211>;
++ #address-cells = <1>;
++ #size-cells = <0>;
++ status = "disabled";
++ };
++
++ msiof1: spi@e6ea0000 {
++ compatible = "renesas,msiof-r8a77980",
++ "renesas,rcar-gen3-msiof";
++ reg = <0 0xe6ea0000 0 0x0064>;
++ interrupts = <GIC_SPI 157 IRQ_TYPE_LEVEL_HIGH>;
++ clocks = <&cpg CPG_MOD 210>;
++ power-domains = <&sysc R8A77980_PD_ALWAYS_ON>;
++ resets = <&cpg 210>;
++ #address-cells = <1>;
++ #size-cells = <0>;
++ status = "disabled";
++ };
++
++ msiof2: spi@e6c00000 {
++ compatible = "renesas,msiof-r8a77980",
++ "renesas,rcar-gen3-msiof";
++ reg = <0 0xe6c00000 0 0x0064>;
++ interrupts = <GIC_SPI 158 IRQ_TYPE_LEVEL_HIGH>;
++ clocks = <&cpg CPG_MOD 209>;
++ power-domains = <&sysc R8A77980_PD_ALWAYS_ON>;
++ resets = <&cpg 209>;
++ #address-cells = <1>;
++ #size-cells = <0>;
++ status = "disabled";
++ };
++
++ msiof3: spi@e6c10000 {
++ compatible = "renesas,msiof-r8a77980",
++ "renesas,rcar-gen3-msiof";
++ reg = <0 0xe6c10000 0 0x0064>;
++ interrupts = <GIC_SPI 159 IRQ_TYPE_LEVEL_HIGH>;
++ clocks = <&cpg CPG_MOD 208>;
++ power-domains = <&sysc R8A77980_PD_ALWAYS_ON>;
++ resets = <&cpg 208>;
++ #address-cells = <1>;
++ #size-cells = <0>;
++ status = "disabled";
++ };
++
+ vin0: video@e6ef0000 {
+ compatible = "renesas,vin-r8a77980";
+ reg = <0 0xe6ef0000 0 0x1000>;
+--
+2.7.4
+
diff --git a/bsp/meta-rcar/meta-rcar-gen3-adas/recipes-kernel/linux/linux-renesas/0226-arm64-dts-renesas-r8a77980-Connect-R-Car-V3H-AVB-to-.patch b/bsp/meta-rcar/meta-rcar-gen3-adas/recipes-kernel/linux/linux-renesas/0226-arm64-dts-renesas-r8a77980-Connect-R-Car-V3H-AVB-to-.patch
new file mode 100644
index 00000000..ae883ead
--- /dev/null
+++ b/bsp/meta-rcar/meta-rcar-gen3-adas/recipes-kernel/linux/linux-renesas/0226-arm64-dts-renesas-r8a77980-Connect-R-Car-V3H-AVB-to-.patch
@@ -0,0 +1,32 @@
+From c4db27990ce2f5ec7b44351ca27f8a5550710a25 Mon Sep 17 00:00:00 2001
+From: Magnus Damm <damm@opensource.se>
+Date: Mon, 22 Oct 2018 02:14:54 +0900
+Subject: [PATCH 046/211] arm64: dts: renesas: r8a77980: Connect R-Car V3H AVB
+ to IPMMU
+
+Hook up the R-Car V3H AVB device to IPMMU-DS1 33 as described in
+the data sheet.
+
+Signed-off-by: Magnus Damm <damm@opensource.se>
+Signed-off-by: Simon Horman <horms+renesas@verge.net.au>
+(cherry picked from commit 8aa7fb3fee6b5105a612d49a10e06f8e64232fe8)
+Signed-off-by: Valentine Barshak <valentine.barshak@cogentembedded.com>
+---
+ arch/arm64/boot/dts/renesas/r8a77980.dtsi | 1 +
+ 1 file changed, 1 insertion(+)
+
+diff --git a/arch/arm64/boot/dts/renesas/r8a77980.dtsi b/arch/arm64/boot/dts/renesas/r8a77980.dtsi
+index c11ee04..4e019f7 100644
+--- a/arch/arm64/boot/dts/renesas/r8a77980.dtsi
++++ b/arch/arm64/boot/dts/renesas/r8a77980.dtsi
+@@ -667,6 +667,7 @@
+ power-domains = <&sysc R8A77980_PD_ALWAYS_ON>;
+ resets = <&cpg 812>;
+ phy-mode = "rgmii";
++ iommus = <&ipmmu_ds1 33>;
+ #address-cells = <1>;
+ #size-cells = <0>;
+ status = "disabled";
+--
+2.7.4
+
diff --git a/bsp/meta-rcar/meta-rcar-gen3-adas/recipes-kernel/linux/linux-renesas/0227-clk-renesas-r8a77980-Add-OSC-predivider-configuratio.patch b/bsp/meta-rcar/meta-rcar-gen3-adas/recipes-kernel/linux/linux-renesas/0227-clk-renesas-r8a77980-Add-OSC-predivider-configuratio.patch
new file mode 100644
index 00000000..403dbde9
--- /dev/null
+++ b/bsp/meta-rcar/meta-rcar-gen3-adas/recipes-kernel/linux/linux-renesas/0227-clk-renesas-r8a77980-Add-OSC-predivider-configuratio.patch
@@ -0,0 +1,72 @@
+From 0eea7261a8e6d24d118182820bad4136145a4b3c Mon Sep 17 00:00:00 2001
+From: Geert Uytterhoeven <geert+renesas@glider.be>
+Date: Wed, 11 Jul 2018 14:16:40 +0200
+Subject: [PATCH 047/211] clk: renesas: r8a77980: Add OSC predivider
+ configuration and clock
+
+R-Car Gen3 Hardware Manual Rev.0.54 documents the relation between the
+MD13 and MD14 mode pins, and the OSC EXTAL predivider, as used by the
+OSC clock. Hence augment the configuration structure with all
+documented predivider values.
+
+Add the OSC clock using the configured predivider.
+
+Signed-off-by: Geert Uytterhoeven <geert+renesas@glider.be>
+Reviewed-by: Simon Horman <horms+renesas@verge.net.au>
+(cherry picked from commit 3a251270e6c877092baded767eba07e9abb1e00d)
+Signed-off-by: Valentine Barshak <valentine.barshak@cogentembedded.com>
+---
+ drivers/clk/renesas/r8a77980-cpg-mssr.c | 24 +++++++++++++-----------
+ 1 file changed, 13 insertions(+), 11 deletions(-)
+
+diff --git a/drivers/clk/renesas/r8a77980-cpg-mssr.c b/drivers/clk/renesas/r8a77980-cpg-mssr.c
+index d7ebd9e..a8b8d86 100644
+--- a/drivers/clk/renesas/r8a77980-cpg-mssr.c
++++ b/drivers/clk/renesas/r8a77980-cpg-mssr.c
+@@ -96,6 +96,8 @@ static const struct cpg_core_clk r8a77980_core_clks[] __initconst = {
+ DEF_DIV6P1("canfd", R8A77980_CLK_CANFD, CLK_PLL1_DIV4, 0x244),
+ DEF_DIV6P1("csi0", R8A77980_CLK_CSI0, CLK_PLL1_DIV4, 0x00c),
+ DEF_DIV6P1("mso", R8A77980_CLK_MSO, CLK_PLL1_DIV4, 0x014),
++
++ DEF_GEN3_OSC("osc", R8A77980_CLK_OSC, CLK_EXTAL, 8),
+ };
+
+ static const struct mssr_mod_clk r8a77980_mod_clks[] __initconst = {
+@@ -171,23 +173,23 @@ static const unsigned int r8a77980_crit_mod_clks[] __initconst = {
+ */
+
+ /*
+- * MD EXTAL PLL2 PLL1 PLL3
++ * MD EXTAL PLL2 PLL1 PLL3 OSC
+ * 14 13 (MHz)
+- * --------------------------------------------------
+- * 0 0 16.66 x 1 x240 x192 x192
+- * 0 1 20 x 1 x200 x160 x160
+- * 1 0 27 x 1 x148 x118 x118
+- * 1 1 33.33 / 2 x240 x192 x192
++ * --------------------------------------------------------
++ * 0 0 16.66 x 1 x240 x192 x192 /16
++ * 0 1 20 x 1 x200 x160 x160 /19
++ * 1 0 27 x 1 x148 x118 x118 /26
++ * 1 1 33.33 / 2 x240 x192 x192 /32
+ */
+ #define CPG_PLL_CONFIG_INDEX(md) ((((md) & BIT(14)) >> 13) | \
+ (((md) & BIT(13)) >> 13))
+
+ static const struct rcar_gen3_cpg_pll_config cpg_pll_configs[4] __initconst = {
+- /* EXTAL div PLL1 mult/div PLL3 mult/div */
+- { 1, 192, 1, 192, 1, },
+- { 1, 160, 1, 160, 1, },
+- { 1, 118, 1, 118, 1, },
+- { 2, 192, 1, 192, 1, },
++ /* EXTAL div PLL1 mult/div PLL3 mult/div OSC prediv */
++ { 1, 192, 1, 192, 1, 16, },
++ { 1, 160, 1, 160, 1, 19, },
++ { 1, 118, 1, 118, 1, 26, },
++ { 2, 192, 1, 192, 1, 32, },
+ };
+
+ static int __init r8a77980_cpg_mssr_init(struct device *dev)
+--
+2.7.4
+
diff --git a/bsp/meta-rcar/meta-rcar-gen3-adas/recipes-kernel/linux/linux-renesas/0228-clk-renesas-r8a77980-Add-RCLK-for-watchdog-timer.patch b/bsp/meta-rcar/meta-rcar-gen3-adas/recipes-kernel/linux/linux-renesas/0228-clk-renesas-r8a77980-Add-RCLK-for-watchdog-timer.patch
new file mode 100644
index 00000000..359e9ae4
--- /dev/null
+++ b/bsp/meta-rcar/meta-rcar-gen3-adas/recipes-kernel/linux/linux-renesas/0228-clk-renesas-r8a77980-Add-RCLK-for-watchdog-timer.patch
@@ -0,0 +1,55 @@
+From 0e839c513201f880af754deeb8a6b8c000428c4c Mon Sep 17 00:00:00 2001
+From: Geert Uytterhoeven <geert+renesas@glider.be>
+Date: Wed, 11 Jul 2018 14:25:07 +0200
+Subject: [PATCH 048/211] clk: renesas: r8a77980: Add RCLK for watchdog timer
+
+On R-Car V3H, RCLK can be switched between EXTALR and the On-Chip
+Oscillator using mode pin MD19.
+
+Signed-off-by: Geert Uytterhoeven <geert+renesas@glider.be>
+Reviewed-by: Simon Horman <horms+renesas@verge.net.au>
+(cherry picked from commit f3824deb46332d1f037f9a26c8f01e3143e64c7e)
+Signed-off-by: Valentine Barshak <valentine.barshak@cogentembedded.com>
+---
+ drivers/clk/renesas/r8a77980-cpg-mssr.c | 4 ++++
+ 1 file changed, 4 insertions(+)
+
+diff --git a/drivers/clk/renesas/r8a77980-cpg-mssr.c b/drivers/clk/renesas/r8a77980-cpg-mssr.c
+index a8b8d86..acf2b4d 100644
+--- a/drivers/clk/renesas/r8a77980-cpg-mssr.c
++++ b/drivers/clk/renesas/r8a77980-cpg-mssr.c
+@@ -41,6 +41,7 @@ enum clk_ids {
+ CLK_S2,
+ CLK_S3,
+ CLK_SDSRC,
++ CLK_OCO,
+
+ /* Module Clocks */
+ MOD_CLK_BASE
+@@ -64,6 +65,7 @@ static const struct cpg_core_clk r8a77980_core_clks[] __initconst = {
+ DEF_FIXED(".s2", CLK_S2, CLK_PLL1_DIV2, 4, 1),
+ DEF_FIXED(".s3", CLK_S3, CLK_PLL1_DIV2, 6, 1),
+ DEF_FIXED(".sdsrc", CLK_SDSRC, CLK_PLL1_DIV2, 2, 1),
++ DEF_RATE(".oco", CLK_OCO, 32768),
+
+ /* Core Clock Outputs */
+ DEF_FIXED("ztr", R8A77980_CLK_ZTR, CLK_PLL1_DIV2, 6, 1),
+@@ -98,6 +100,7 @@ static const struct cpg_core_clk r8a77980_core_clks[] __initconst = {
+ DEF_DIV6P1("mso", R8A77980_CLK_MSO, CLK_PLL1_DIV4, 0x014),
+
+ DEF_GEN3_OSC("osc", R8A77980_CLK_OSC, CLK_EXTAL, 8),
++ DEF_GEN3_MDSEL("r", R8A77980_CLK_R, 29, CLK_EXTALR, 1, CLK_OCO, 1),
+ };
+
+ static const struct mssr_mod_clk r8a77980_mod_clks[] __initconst = {
+@@ -119,6 +122,7 @@ static const struct mssr_mod_clk r8a77980_mod_clks[] __initconst = {
+ DEF_MOD("tpu0", 304, R8A77980_CLK_S3D4),
+ DEF_MOD("sdif", 314, R8A77980_CLK_SD0),
+ DEF_MOD("pciec0", 319, R8A77980_CLK_S2D2),
++ DEF_MOD("rwdt", 402, R8A77980_CLK_R),
+ DEF_MOD("intc-ex", 407, R8A77980_CLK_CP),
+ DEF_MOD("intc-ap", 408, R8A77980_CLK_S0D3),
+ DEF_MOD("hscif3", 517, R8A77980_CLK_S3D1),
+--
+2.7.4
+
diff --git a/bsp/meta-rcar/meta-rcar-gen3-adas/recipes-kernel/linux/linux-renesas/0229-drm-rcar-du-lvds-add-R8A77980-support.patch b/bsp/meta-rcar/meta-rcar-gen3-adas/recipes-kernel/linux/linux-renesas/0229-drm-rcar-du-lvds-add-R8A77980-support.patch
new file mode 100644
index 00000000..920b72d5
--- /dev/null
+++ b/bsp/meta-rcar/meta-rcar-gen3-adas/recipes-kernel/linux/linux-renesas/0229-drm-rcar-du-lvds-add-R8A77980-support.patch
@@ -0,0 +1,31 @@
+From 8ee3b9cd4da329e900ac02f5f6ea9b39ea290c87 Mon Sep 17 00:00:00 2001
+From: Sergei Shtylyov <sergei.shtylyov@cogentembedded.com>
+Date: Tue, 5 Jun 2018 23:30:36 +0300
+Subject: [PATCH 049/211] drm: rcar-du: lvds: add R8A77980 support
+
+Add support for the R-Car V3H (R8A77980) SoC to the LVDS encoder driver.
+
+Signed-off-by: Sergei Shtylyov <sergei.shtylyov@cogentembedded.com>
+Reviewed-by: Laurent Pinchart <laurent.pinchart+renesas@ideasonboard.com>
+Signed-off-by: Laurent Pinchart <laurent.pinchart+renesas@ideasonboard.com>
+(cherry picked from commit c4341442acb14d8f1cec6999123a70f9d2bfe48f)
+Signed-off-by: Valentine Barshak <valentine.barshak@cogentembedded.com>
+---
+ drivers/gpu/drm/rcar-du/rcar_lvds.c | 1 +
+ 1 file changed, 1 insertion(+)
+
+diff --git a/drivers/gpu/drm/rcar-du/rcar_lvds.c b/drivers/gpu/drm/rcar-du/rcar_lvds.c
+index 03a74fa..c41c9ee6 100644
+--- a/drivers/gpu/drm/rcar-du/rcar_lvds.c
++++ b/drivers/gpu/drm/rcar-du/rcar_lvds.c
+@@ -1075,6 +1075,7 @@ static const struct of_device_id rcar_lvds_of_table[] = {
+ { .compatible = "renesas,r8a77990-lvds", .data = &rcar_lvds_r8a77990_info },
+ { .compatible = "renesas,r8a77995-lvds", .data = &rcar_lvds_r8a77995_info },
+ { .compatible = "renesas,r8a77970-lvds", .data = &rcar_lvds_r8a77970_info },
++ { .compatible = "renesas,r8a77980-lvds", .data = &rcar_lvds_gen3_info },
+ { }
+ };
+
+--
+2.7.4
+
diff --git a/bsp/meta-rcar/meta-rcar-gen3-adas/recipes-kernel/linux/linux-renesas/0230-drivers-flag-buses-which-demand-DMA-configuration.patch b/bsp/meta-rcar/meta-rcar-gen3-adas/recipes-kernel/linux/linux-renesas/0230-drivers-flag-buses-which-demand-DMA-configuration.patch
new file mode 100644
index 00000000..bcf79a0d
--- /dev/null
+++ b/bsp/meta-rcar/meta-rcar-gen3-adas/recipes-kernel/linux/linux-renesas/0230-drivers-flag-buses-which-demand-DMA-configuration.patch
@@ -0,0 +1,139 @@
+From 0d69d1e8b840a47bd72dd4b7ca873403a200db8d Mon Sep 17 00:00:00 2001
+From: Robin Murphy <robin.murphy@arm.com>
+Date: Thu, 12 Oct 2017 16:56:14 +0100
+Subject: [PATCH 050/211] drivers: flag buses which demand DMA configuration
+
+We do not want the common dma_configure() pathway to apply
+indiscriminately to all devices, since there are plenty of buses which
+do not have DMA capability, and if their child devices were used for
+DMA API calls it would only be indicative of a driver bug. However,
+there are a number of buses for which DMA is implicitly expected even
+when not described by firmware - those we whitelist with an automatic
+opt-in to dma_configure(), assuming that the DMA address space and the
+physical address space are equivalent if not otherwise specified.
+
+Commit 723288836628 ("of: restrict DMA configuration") introduced a
+short-term fix by comparing explicit bus types, but this approach is far
+from pretty, doesn't scale well, and fails to cope at all with bus
+drivers which may be built as modules, like host1x. Let's refine things
+by making that opt-in a property of the bus type, which neatly addresses
+those problems and lets the decision of whether firmware description of
+DMA capability should be optional or mandatory stay internal to the bus
+drivers themselves.
+
+Signed-off-by: Robin Murphy <robin.murphy@arm.com>
+Acked-by: Rob Herring <robh@kernel.org>
+Acked-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+Acked-by: Thierry Reding <treding@nvidia.com>
+Signed-off-by: Christoph Hellwig <hch@lst.de>
+(cherry picked from commit d89e2378a97fafdc74cbf997e7c88af75b81610a)
+Signed-off-by: Valentine Barshak <valentine.barshak@cogentembedded.com>
+---
+ drivers/amba/bus.c | 1 +
+ drivers/base/platform.c | 1 +
+ drivers/gpu/host1x/bus.c | 1 +
+ drivers/of/device.c | 8 +-------
+ drivers/pci/pci-driver.c | 1 +
+ include/linux/device.h | 4 ++++
+ 6 files changed, 9 insertions(+), 7 deletions(-)
+
+diff --git a/drivers/amba/bus.c b/drivers/amba/bus.c
+index 8a99fbe..4a3ac31 100644
+--- a/drivers/amba/bus.c
++++ b/drivers/amba/bus.c
+@@ -200,6 +200,7 @@ struct bus_type amba_bustype = {
+ .match = amba_match,
+ .uevent = amba_uevent,
+ .pm = &amba_pm,
++ .force_dma = true,
+ };
+
+ static int __init amba_init(void)
+diff --git a/drivers/base/platform.c b/drivers/base/platform.c
+index 9045c5f..c203fb9 100644
+--- a/drivers/base/platform.c
++++ b/drivers/base/platform.c
+@@ -1143,6 +1143,7 @@ struct bus_type platform_bus_type = {
+ .match = platform_match,
+ .uevent = platform_uevent,
+ .pm = &platform_dev_pm_ops,
++ .force_dma = true,
+ };
+ EXPORT_SYMBOL_GPL(platform_bus_type);
+
+diff --git a/drivers/gpu/host1x/bus.c b/drivers/gpu/host1x/bus.c
+index f9cde03..ed03b32 100644
+--- a/drivers/gpu/host1x/bus.c
++++ b/drivers/gpu/host1x/bus.c
+@@ -320,6 +320,7 @@ struct bus_type host1x_bus_type = {
+ .name = "host1x",
+ .match = host1x_device_match,
+ .pm = &host1x_device_pm_ops,
++ .force_dma = true,
+ };
+
+ static void __host1x_device_del(struct host1x_device *device)
+diff --git a/drivers/of/device.c b/drivers/of/device.c
+index 64b7102..25bddf9 100644
+--- a/drivers/of/device.c
++++ b/drivers/of/device.c
+@@ -9,9 +9,7 @@
+ #include <linux/module.h>
+ #include <linux/mod_devicetable.h>
+ #include <linux/slab.h>
+-#include <linux/pci.h>
+ #include <linux/platform_device.h>
+-#include <linux/amba/bus.h>
+
+ #include <asm/errno.h>
+ #include "of_private.h"
+@@ -101,11 +99,7 @@ int of_dma_configure(struct device *dev, struct device_node *np)
+ * DMA configuration regardless of whether "dma-ranges" is
+ * correctly specified or not.
+ */
+- if (!dev_is_pci(dev) &&
+-#ifdef CONFIG_ARM_AMBA
+- dev->bus != &amba_bustype &&
+-#endif
+- dev->bus != &platform_bus_type)
++ if (!dev->bus->force_dma)
+ return ret == -ENODEV ? 0 : ret;
+
+ dma_addr = offset = 0;
+diff --git a/drivers/pci/pci-driver.c b/drivers/pci/pci-driver.c
+index ea69b4d..e453f26 100644
+--- a/drivers/pci/pci-driver.c
++++ b/drivers/pci/pci-driver.c
+@@ -1476,6 +1476,7 @@ struct bus_type pci_bus_type = {
+ .drv_groups = pci_drv_groups,
+ .pm = PCI_PM_OPS_PTR,
+ .num_vf = pci_bus_num_vf,
++ .force_dma = true,
+ };
+ EXPORT_SYMBOL(pci_bus_type);
+
+diff --git a/include/linux/device.h b/include/linux/device.h
+index f232081..144ca07 100644
+--- a/include/linux/device.h
++++ b/include/linux/device.h
+@@ -97,6 +97,8 @@ extern void bus_remove_file(struct bus_type *, struct bus_attribute *);
+ * @p: The private data of the driver core, only the driver core can
+ * touch this.
+ * @lock_key: Lock class key for use by the lock validator
++ * @force_dma: Assume devices on this bus should be set up by dma_configure()
++ * even if DMA capability is not explicitly described by firmware.
+ *
+ * A bus is a channel between the processor and one or more devices. For the
+ * purposes of the device model, all devices are connected via a bus, even if
+@@ -135,6 +137,8 @@ struct bus_type {
+
+ struct subsys_private *p;
+ struct lock_class_key lock_key;
++
++ bool force_dma;
+ };
+
+ extern int __must_check bus_register(struct bus_type *bus);
+--
+2.7.4
+
diff --git a/bsp/meta-rcar/meta-rcar-gen3-adas/recipes-kernel/linux/linux-renesas/0231-gpu-host1x-Call-of_dma_configure-after-setting-bus.patch b/bsp/meta-rcar/meta-rcar-gen3-adas/recipes-kernel/linux/linux-renesas/0231-gpu-host1x-Call-of_dma_configure-after-setting-bus.patch
new file mode 100644
index 00000000..54344348
--- /dev/null
+++ b/bsp/meta-rcar/meta-rcar-gen3-adas/recipes-kernel/linux/linux-renesas/0231-gpu-host1x-Call-of_dma_configure-after-setting-bus.patch
@@ -0,0 +1,39 @@
+From de91461e14544bde491e9513733cb4e7dcac24aa Mon Sep 17 00:00:00 2001
+From: Mikko Perttunen <mperttunen@nvidia.com>
+Date: Sun, 24 Sep 2017 12:04:53 +0300
+Subject: [PATCH 051/211] gpu: host1x: Call of_dma_configure() after setting
+ bus
+
+of_dma_configure() now checks the device's bus before configuring it, so
+we need to set the device's bus before calling.
+
+Signed-off-by: Mikko Perttunen <mperttunen@nvidia.com>
+Signed-off-by: Thierry Reding <treding@nvidia.com>
+(cherry picked from commit 2fb0dceb69ce957f01bdb6fddf7baf4c4b9cbc0d)
+Signed-off-by: Valentine Barshak <valentine.barshak@cogentembedded.com>
+---
+ drivers/gpu/host1x/bus.c | 3 ++-
+ 1 file changed, 2 insertions(+), 1 deletion(-)
+
+diff --git a/drivers/gpu/host1x/bus.c b/drivers/gpu/host1x/bus.c
+index ed03b32..2e57c9ce 100644
+--- a/drivers/gpu/host1x/bus.c
++++ b/drivers/gpu/host1x/bus.c
+@@ -404,12 +404,13 @@ static int host1x_device_add(struct host1x *host1x,
+ device->dev.coherent_dma_mask = host1x->dev->coherent_dma_mask;
+ device->dev.dma_mask = &device->dev.coherent_dma_mask;
+ dev_set_name(&device->dev, "%s", driver->driver.name);
+- of_dma_configure(&device->dev, host1x->dev->of_node);
+ device->dev.release = host1x_device_release;
+ device->dev.of_node = host1x->dev->of_node;
+ device->dev.bus = &host1x_bus_type;
+ device->dev.parent = host1x->dev;
+
++ of_dma_configure(&device->dev, host1x->dev->of_node);
++
+ err = host1x_device_parse_dt(device, driver);
+ if (err < 0) {
+ kfree(device);
+--
+2.7.4
+
diff --git a/bsp/meta-rcar/meta-rcar-gen3-adas/recipes-kernel/linux/linux-renesas/0232-gpu-host1x-Cleanup-on-initialization-failure.patch b/bsp/meta-rcar/meta-rcar-gen3-adas/recipes-kernel/linux/linux-renesas/0232-gpu-host1x-Cleanup-on-initialization-failure.patch
new file mode 100644
index 00000000..018a3b1e
--- /dev/null
+++ b/bsp/meta-rcar/meta-rcar-gen3-adas/recipes-kernel/linux/linux-renesas/0232-gpu-host1x-Cleanup-on-initialization-failure.patch
@@ -0,0 +1,48 @@
+From e7cc9cf9ab044fcd12251f74905715d5415a12b3 Mon Sep 17 00:00:00 2001
+From: Thierry Reding <treding@nvidia.com>
+Date: Wed, 8 Nov 2017 13:08:21 +0100
+Subject: [PATCH 052/211] gpu: host1x: Cleanup on initialization failure
+
+When an error happens during the initialization of one of the sub-
+devices, make sure to properly cleanup all sub-devices that have been
+initialized up to that point.
+
+Signed-off-by: Thierry Reding <treding@nvidia.com>
+(cherry picked from commit 8f7da1578e90bf1af30269dc6dd8806c96e9c683)
+Signed-off-by: Valentine Barshak <valentine.barshak@cogentembedded.com>
+---
+ drivers/gpu/host1x/bus.c | 11 +++++++++--
+ 1 file changed, 9 insertions(+), 2 deletions(-)
+
+diff --git a/drivers/gpu/host1x/bus.c b/drivers/gpu/host1x/bus.c
+index 2e57c9ce..88a3558 100644
+--- a/drivers/gpu/host1x/bus.c
++++ b/drivers/gpu/host1x/bus.c
+@@ -211,8 +211,7 @@ int host1x_device_init(struct host1x_device *device)
+ dev_err(&device->dev,
+ "failed to initialize %s: %d\n",
+ dev_name(client->dev), err);
+- mutex_unlock(&device->clients_lock);
+- return err;
++ goto teardown;
+ }
+ }
+ }
+@@ -220,6 +219,14 @@ int host1x_device_init(struct host1x_device *device)
+ mutex_unlock(&device->clients_lock);
+
+ return 0;
++
++teardown:
++ list_for_each_entry_continue_reverse(client, &device->clients, list)
++ if (client->ops->exit)
++ client->ops->exit(client);
++
++ mutex_unlock(&device->clients_lock);
++ return err;
+ }
+ EXPORT_SYMBOL(host1x_device_init);
+
+--
+2.7.4
+
diff --git a/bsp/meta-rcar/meta-rcar-gen3-adas/recipes-kernel/linux/linux-renesas/0233-dma-mapping-move-dma-configuration-to-bus-infrastruc.patch b/bsp/meta-rcar/meta-rcar-gen3-adas/recipes-kernel/linux/linux-renesas/0233-dma-mapping-move-dma-configuration-to-bus-infrastruc.patch
new file mode 100644
index 00000000..ccb0354b
--- /dev/null
+++ b/bsp/meta-rcar/meta-rcar-gen3-adas/recipes-kernel/linux/linux-renesas/0233-dma-mapping-move-dma-configuration-to-bus-infrastruc.patch
@@ -0,0 +1,261 @@
+From 119a8b25ee3745650dc7205f2601acf4b3d32c2b Mon Sep 17 00:00:00 2001
+From: Nipun Gupta <nipun.gupta@nxp.com>
+Date: Sat, 28 Apr 2018 08:21:58 +0530
+Subject: [PATCH 053/211] dma-mapping: move dma configuration to bus
+ infrastructure
+
+ACPI/OF support for configuration of DMA is a bus specific aspect, and
+thus should be configured by the bus. Introduces a 'dma_configure' bus
+method so that busses can control their DMA capabilities.
+
+Also update the PCI, Platform, ACPI and host1x buses to use the new
+method.
+
+Suggested-by: Christoph Hellwig <hch@lst.de>
+Signed-off-by: Nipun Gupta <nipun.gupta@nxp.com>
+Acked-by: Bjorn Helgaas <bhelgaas@google.com> # PCI parts
+Acked-by: Thierry Reding <treding@nvidia.com>
+Reviewed-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+[hch: simplified host1x_dma_configure based on a comment from Thierry,
+ rewrote changelog]
+Signed-off-by: Christoph Hellwig <hch@lst.de>
+
+(cherry picked from commit 07397df29e57cde5799af16e8f148ae10ed75285)
+Signed-off-by: Valentine Barshak <valentine.barshak@cogentembedded.com>
+---
+ drivers/amba/bus.c | 4 ++++
+ drivers/base/dma-mapping.c | 31 ++++---------------------------
+ drivers/base/platform.c | 17 +++++++++++++++++
+ drivers/gpu/host1x/bus.c | 6 ++++++
+ drivers/pci/pci-driver.c | 32 ++++++++++++++++++++++++++++++++
+ include/linux/device.h | 4 ++++
+ include/linux/platform_device.h | 2 ++
+ 7 files changed, 69 insertions(+), 27 deletions(-)
+
+diff --git a/drivers/amba/bus.c b/drivers/amba/bus.c
+index 4a3ac31..b1f41f7 100644
+--- a/drivers/amba/bus.c
++++ b/drivers/amba/bus.c
+@@ -20,6 +20,7 @@
+ #include <linux/sizes.h>
+ #include <linux/limits.h>
+ #include <linux/clk/clk-conf.h>
++#include <linux/platform_device.h>
+
+ #include <asm/irq.h>
+
+@@ -193,12 +194,15 @@ static const struct dev_pm_ops amba_pm = {
+ /*
+ * Primecells are part of the Advanced Microcontroller Bus Architecture,
+ * so we call the bus "amba".
++ * DMA configuration for platform and AMBA bus is same. So here we reuse
++ * platform's DMA config routine.
+ */
+ struct bus_type amba_bustype = {
+ .name = "amba",
+ .dev_groups = amba_dev_groups,
+ .match = amba_match,
+ .uevent = amba_uevent,
++ .dma_configure = platform_dma_configure,
+ .pm = &amba_pm,
+ .force_dma = true,
+ };
+diff --git a/drivers/base/dma-mapping.c b/drivers/base/dma-mapping.c
+index e584edd..98f30b5 100644
+--- a/drivers/base/dma-mapping.c
++++ b/drivers/base/dma-mapping.c
+@@ -332,36 +332,13 @@ void dma_common_free_remap(void *cpu_addr, size_t size, unsigned long vm_flags)
+ #endif
+
+ /*
+- * Common configuration to enable DMA API use for a device
++ * enables DMA API use for a device
+ */
+-#include <linux/pci.h>
+-
+ int dma_configure(struct device *dev)
+ {
+- struct device *bridge = NULL, *dma_dev = dev;
+- enum dev_dma_attr attr;
+- int ret = 0;
+-
+- if (dev_is_pci(dev)) {
+- bridge = pci_get_host_bridge_device(to_pci_dev(dev));
+- dma_dev = bridge;
+- if (IS_ENABLED(CONFIG_OF) && dma_dev->parent &&
+- dma_dev->parent->of_node)
+- dma_dev = dma_dev->parent;
+- }
+-
+- if (dma_dev->of_node) {
+- ret = of_dma_configure(dev, dma_dev->of_node);
+- } else if (has_acpi_companion(dma_dev)) {
+- attr = acpi_get_dma_attr(to_acpi_device_node(dma_dev->fwnode));
+- if (attr != DEV_DMA_NOT_SUPPORTED)
+- ret = acpi_dma_configure(dev, attr);
+- }
+-
+- if (bridge)
+- pci_put_host_bridge_device(bridge);
+-
+- return ret;
++ if (dev->bus->dma_configure)
++ return dev->bus->dma_configure(dev);
++ return 0;
+ }
+
+ void dma_deconfigure(struct device *dev)
+diff --git a/drivers/base/platform.c b/drivers/base/platform.c
+index c203fb9..5b43ace 100644
+--- a/drivers/base/platform.c
++++ b/drivers/base/platform.c
+@@ -1131,6 +1131,22 @@ int platform_pm_restore(struct device *dev)
+
+ #endif /* CONFIG_HIBERNATE_CALLBACKS */
+
++int platform_dma_configure(struct device *dev)
++{
++ enum dev_dma_attr attr;
++ int ret = 0;
++
++ if (dev->of_node) {
++ ret = of_dma_configure(dev, dev->of_node);
++ } else if (has_acpi_companion(dev)) {
++ attr = acpi_get_dma_attr(to_acpi_device_node(dev->fwnode));
++ if (attr != DEV_DMA_NOT_SUPPORTED)
++ ret = acpi_dma_configure(dev, attr);
++ }
++
++ return ret;
++}
++
+ static const struct dev_pm_ops platform_dev_pm_ops = {
+ .runtime_suspend = pm_generic_runtime_suspend,
+ .runtime_resume = pm_generic_runtime_resume,
+@@ -1142,6 +1158,7 @@ struct bus_type platform_bus_type = {
+ .dev_groups = platform_dev_groups,
+ .match = platform_match,
+ .uevent = platform_uevent,
++ .dma_configure = platform_dma_configure,
+ .pm = &platform_dev_pm_ops,
+ .force_dma = true,
+ };
+diff --git a/drivers/gpu/host1x/bus.c b/drivers/gpu/host1x/bus.c
+index 88a3558..0c79baf 100644
+--- a/drivers/gpu/host1x/bus.c
++++ b/drivers/gpu/host1x/bus.c
+@@ -314,6 +314,11 @@ static int host1x_device_match(struct device *dev, struct device_driver *drv)
+ return strcmp(dev_name(dev), drv->name) == 0;
+ }
+
++static int host1x_dma_configure(struct device *dev)
++{
++ return of_dma_configure(dev, dev->of_node);
++}
++
+ static const struct dev_pm_ops host1x_device_pm_ops = {
+ .suspend = pm_generic_suspend,
+ .resume = pm_generic_resume,
+@@ -326,6 +331,7 @@ static const struct dev_pm_ops host1x_device_pm_ops = {
+ struct bus_type host1x_bus_type = {
+ .name = "host1x",
+ .match = host1x_device_match,
++ .dma_configure = host1x_dma_configure,
+ .pm = &host1x_device_pm_ops,
+ .force_dma = true,
+ };
+diff --git a/drivers/pci/pci-driver.c b/drivers/pci/pci-driver.c
+index e453f26..fddbb24 100644
+--- a/drivers/pci/pci-driver.c
++++ b/drivers/pci/pci-driver.c
+@@ -20,6 +20,8 @@
+ #include <linux/pm_runtime.h>
+ #include <linux/suspend.h>
+ #include <linux/kexec.h>
++#include <linux/of_device.h>
++#include <linux/acpi.h>
+ #include "pci.h"
+
+ struct pci_dynid {
+@@ -1464,6 +1466,35 @@ static int pci_bus_num_vf(struct device *dev)
+ return pci_num_vf(to_pci_dev(dev));
+ }
+
++/**
++ * pci_dma_configure - Setup DMA configuration
++ * @dev: ptr to dev structure
++ *
++ * Function to update PCI devices's DMA configuration using the same
++ * info from the OF node or ACPI node of host bridge's parent (if any).
++ */
++static int pci_dma_configure(struct device *dev)
++{
++ struct device *bridge;
++ int ret = 0;
++
++ bridge = pci_get_host_bridge_device(to_pci_dev(dev));
++
++ if (IS_ENABLED(CONFIG_OF) && bridge->parent &&
++ bridge->parent->of_node) {
++ ret = of_dma_configure(dev, bridge->parent->of_node);
++ } else if (has_acpi_companion(bridge)) {
++ struct acpi_device *adev = to_acpi_device_node(bridge->fwnode);
++ enum dev_dma_attr attr = acpi_get_dma_attr(adev);
++
++ if (attr != DEV_DMA_NOT_SUPPORTED)
++ ret = acpi_dma_configure(dev, attr);
++ }
++
++ pci_put_host_bridge_device(bridge);
++ return ret;
++}
++
+ struct bus_type pci_bus_type = {
+ .name = "pci",
+ .match = pci_bus_match,
+@@ -1476,6 +1507,7 @@ struct bus_type pci_bus_type = {
+ .drv_groups = pci_drv_groups,
+ .pm = PCI_PM_OPS_PTR,
+ .num_vf = pci_bus_num_vf,
++ .dma_configure = pci_dma_configure,
+ .force_dma = true,
+ };
+ EXPORT_SYMBOL(pci_bus_type);
+diff --git a/include/linux/device.h b/include/linux/device.h
+index 144ca07..012c4377 100644
+--- a/include/linux/device.h
++++ b/include/linux/device.h
+@@ -89,6 +89,8 @@ extern void bus_remove_file(struct bus_type *, struct bus_attribute *);
+ * @resume: Called to bring a device on this bus out of sleep mode.
+ * @num_vf: Called to find out how many virtual functions a device on this
+ * bus supports.
++ * @dma_configure: Called to setup DMA configuration on a device on
++ this bus.
+ * @pm: Power management operations of this bus, callback the specific
+ * device driver's pm-ops.
+ * @iommu_ops: IOMMU specific operations for this bus, used to attach IOMMU
+@@ -131,6 +133,8 @@ struct bus_type {
+
+ int (*num_vf)(struct device *dev);
+
++ int (*dma_configure)(struct device *dev);
++
+ const struct dev_pm_ops *pm;
+
+ const struct iommu_ops *iommu_ops;
+diff --git a/include/linux/platform_device.h b/include/linux/platform_device.h
+index 49f634d..3097c94 100644
+--- a/include/linux/platform_device.h
++++ b/include/linux/platform_device.h
+@@ -356,6 +356,8 @@ extern int platform_pm_restore(struct device *dev);
+ #define platform_pm_restore NULL
+ #endif
+
++extern int platform_dma_configure(struct device *dev);
++
+ #ifdef CONFIG_PM_SLEEP
+ #define USE_PLATFORM_PM_SLEEP_OPS \
+ .suspend = platform_pm_suspend, \
+--
+2.7.4
+
diff --git a/bsp/meta-rcar/meta-rcar-gen3-adas/recipes-kernel/linux/linux-renesas/0234-drivers-remove-force-dma-flag-from-buses.patch b/bsp/meta-rcar/meta-rcar-gen3-adas/recipes-kernel/linux/linux-renesas/0234-drivers-remove-force-dma-flag-from-buses.patch
new file mode 100644
index 00000000..65f8b500
--- /dev/null
+++ b/bsp/meta-rcar/meta-rcar-gen3-adas/recipes-kernel/linux/linux-renesas/0234-drivers-remove-force-dma-flag-from-buses.patch
@@ -0,0 +1,252 @@
+From 90ea8f9afa19363f0bb98e9fd243079159cb4ca4 Mon Sep 17 00:00:00 2001
+From: Christoph Hellwig <hch@lst.de>
+Date: Thu, 3 May 2018 16:25:08 +0200
+Subject: [PATCH 054/211] drivers: remove force dma flag from buses
+
+With each bus implementing its own DMA configuration callback, there is no
+need for bus to explicitly set the force_dma flag. Modify the
+of_dma_configure function to accept an input parameter which specifies if
+implicit DMA configuration is required when it is not described by the
+firmware.
+
+Signed-off-by: Nipun Gupta <nipun.gupta@nxp.com>
+Acked-by: Bjorn Helgaas <bhelgaas@google.com> # PCI parts
+Reviewed-by: Rob Herring <robh@kernel.org>
+[hch: tweaked the changelog a bit]
+Signed-off-by: Christoph Hellwig <hch@lst.de>
+
+(cherry picked from commit 3d6ce86ee79465e1b1b6e287f8ea26b553fc768e)
+[valentine.barshak: changed drivers/pci/endpoint/pci-epc-core.c as well]
+Signed-off-by: Valentine Barshak <valentine.barshak@cogentembedded.com>
+---
+ drivers/amba/bus.c | 1 -
+ drivers/base/platform.c | 3 +--
+ drivers/bcma/main.c | 2 +-
+ drivers/dma/qcom/hidma_mgmt.c | 2 +-
+ drivers/gpu/host1x/bus.c | 5 ++---
+ drivers/of/device.c | 6 ++++--
+ drivers/of/of_reserved_mem.c | 2 +-
+ drivers/pci/endpoint/pci-epc-core.c | 2 +-
+ drivers/pci/pci-driver.c | 3 +--
+ include/linux/device.h | 4 ----
+ include/linux/of_device.h | 8 ++++++--
+ 11 files changed, 18 insertions(+), 20 deletions(-)
+
+diff --git a/drivers/amba/bus.c b/drivers/amba/bus.c
+index b1f41f7..3b01187 100644
+--- a/drivers/amba/bus.c
++++ b/drivers/amba/bus.c
+@@ -204,7 +204,6 @@ struct bus_type amba_bustype = {
+ .uevent = amba_uevent,
+ .dma_configure = platform_dma_configure,
+ .pm = &amba_pm,
+- .force_dma = true,
+ };
+
+ static int __init amba_init(void)
+diff --git a/drivers/base/platform.c b/drivers/base/platform.c
+index 5b43ace..55e9456 100644
+--- a/drivers/base/platform.c
++++ b/drivers/base/platform.c
+@@ -1137,7 +1137,7 @@ int platform_dma_configure(struct device *dev)
+ int ret = 0;
+
+ if (dev->of_node) {
+- ret = of_dma_configure(dev, dev->of_node);
++ ret = of_dma_configure(dev, dev->of_node, true);
+ } else if (has_acpi_companion(dev)) {
+ attr = acpi_get_dma_attr(to_acpi_device_node(dev->fwnode));
+ if (attr != DEV_DMA_NOT_SUPPORTED)
+@@ -1160,7 +1160,6 @@ struct bus_type platform_bus_type = {
+ .uevent = platform_uevent,
+ .dma_configure = platform_dma_configure,
+ .pm = &platform_dev_pm_ops,
+- .force_dma = true,
+ };
+ EXPORT_SYMBOL_GPL(platform_bus_type);
+
+diff --git a/drivers/bcma/main.c b/drivers/bcma/main.c
+index e6986c7..fc1f4ac 100644
+--- a/drivers/bcma/main.c
++++ b/drivers/bcma/main.c
+@@ -207,7 +207,7 @@ static void bcma_of_fill_device(struct device *parent,
+
+ core->irq = bcma_of_get_irq(parent, core, 0);
+
+- of_dma_configure(&core->dev, node);
++ of_dma_configure(&core->dev, node, false);
+ }
+
+ unsigned int bcma_core_irq(struct bcma_device *core, int num)
+diff --git a/drivers/dma/qcom/hidma_mgmt.c b/drivers/dma/qcom/hidma_mgmt.c
+index 7335e2e..3a0e363 100644
+--- a/drivers/dma/qcom/hidma_mgmt.c
++++ b/drivers/dma/qcom/hidma_mgmt.c
+@@ -427,7 +427,7 @@ static int __init hidma_mgmt_of_populate_channels(struct device_node *np)
+ }
+ of_node_get(child);
+ new_pdev->dev.of_node = child;
+- of_dma_configure(&new_pdev->dev, child);
++ of_dma_configure(&new_pdev->dev, child, true);
+ /*
+ * It is assumed that calling of_msi_configure is safe on
+ * platforms with or without MSI support.
+diff --git a/drivers/gpu/host1x/bus.c b/drivers/gpu/host1x/bus.c
+index 0c79baf..815bdb4 100644
+--- a/drivers/gpu/host1x/bus.c
++++ b/drivers/gpu/host1x/bus.c
+@@ -316,7 +316,7 @@ static int host1x_device_match(struct device *dev, struct device_driver *drv)
+
+ static int host1x_dma_configure(struct device *dev)
+ {
+- return of_dma_configure(dev, dev->of_node);
++ return of_dma_configure(dev, dev->of_node, true);
+ }
+
+ static const struct dev_pm_ops host1x_device_pm_ops = {
+@@ -333,7 +333,6 @@ struct bus_type host1x_bus_type = {
+ .match = host1x_device_match,
+ .dma_configure = host1x_dma_configure,
+ .pm = &host1x_device_pm_ops,
+- .force_dma = true,
+ };
+
+ static void __host1x_device_del(struct host1x_device *device)
+@@ -422,7 +421,7 @@ static int host1x_device_add(struct host1x *host1x,
+ device->dev.bus = &host1x_bus_type;
+ device->dev.parent = host1x->dev;
+
+- of_dma_configure(&device->dev, host1x->dev->of_node);
++ of_dma_configure(&device->dev, host1x->dev->of_node, true);
+
+ err = host1x_device_parse_dt(device, driver);
+ if (err < 0) {
+diff --git a/drivers/of/device.c b/drivers/of/device.c
+index 25bddf9..4404903 100644
+--- a/drivers/of/device.c
++++ b/drivers/of/device.c
+@@ -75,6 +75,8 @@ int of_device_add(struct platform_device *ofdev)
+ * of_dma_configure - Setup DMA configuration
+ * @dev: Device to apply DMA configuration
+ * @np: Pointer to OF node having DMA configuration
++ * @force_dma: Whether device is to be set up by of_dma_configure() even if
++ * DMA capability is not explicitly described by firmware.
+ *
+ * Try to get devices's DMA configuration from DT and update it
+ * accordingly.
+@@ -83,7 +85,7 @@ int of_device_add(struct platform_device *ofdev)
+ * can use a platform bus notifier and handle BUS_NOTIFY_ADD_DEVICE events
+ * to fix up DMA configuration.
+ */
+-int of_dma_configure(struct device *dev, struct device_node *np)
++int of_dma_configure(struct device *dev, struct device_node *np, bool force_dma)
+ {
+ u64 dma_addr, paddr, size = 0;
+ int ret;
+@@ -99,7 +101,7 @@ int of_dma_configure(struct device *dev, struct device_node *np)
+ * DMA configuration regardless of whether "dma-ranges" is
+ * correctly specified or not.
+ */
+- if (!dev->bus->force_dma)
++ if (!force_dma)
+ return ret == -ENODEV ? 0 : ret;
+
+ dma_addr = offset = 0;
+diff --git a/drivers/of/of_reserved_mem.c b/drivers/of/of_reserved_mem.c
+index 32771c2..e36c119 100644
+--- a/drivers/of/of_reserved_mem.c
++++ b/drivers/of/of_reserved_mem.c
+@@ -357,7 +357,7 @@ int of_reserved_mem_device_init_by_idx(struct device *dev,
+ /* ensure that dma_ops is set for virtual devices
+ * using reserved memory
+ */
+- of_dma_configure(dev, np);
++ of_dma_configure(dev, np, true);
+
+ dev_info(dev, "assigned reserved memory node %s\n", rmem->name);
+ } else {
+diff --git a/drivers/pci/endpoint/pci-epc-core.c b/drivers/pci/endpoint/pci-epc-core.c
+index 42c2a11..c09e08c 100644
+--- a/drivers/pci/endpoint/pci-epc-core.c
++++ b/drivers/pci/endpoint/pci-epc-core.c
+@@ -384,7 +384,7 @@ int pci_epc_add_epf(struct pci_epc *epc, struct pci_epf *epf)
+
+ epf->epc = epc;
+ if (dev->of_node) {
+- of_dma_configure(&epf->dev, dev->of_node);
++ of_dma_configure(&epf->dev, dev->of_node, true);
+ } else {
+ dma_set_coherent_mask(&epf->dev, epc->dev.coherent_dma_mask);
+ epf->dev.dma_mask = epc->dev.dma_mask;
+diff --git a/drivers/pci/pci-driver.c b/drivers/pci/pci-driver.c
+index fddbb24..2d67f5f 100644
+--- a/drivers/pci/pci-driver.c
++++ b/drivers/pci/pci-driver.c
+@@ -1482,7 +1482,7 @@ static int pci_dma_configure(struct device *dev)
+
+ if (IS_ENABLED(CONFIG_OF) && bridge->parent &&
+ bridge->parent->of_node) {
+- ret = of_dma_configure(dev, bridge->parent->of_node);
++ ret = of_dma_configure(dev, bridge->parent->of_node, true);
+ } else if (has_acpi_companion(bridge)) {
+ struct acpi_device *adev = to_acpi_device_node(bridge->fwnode);
+ enum dev_dma_attr attr = acpi_get_dma_attr(adev);
+@@ -1508,7 +1508,6 @@ struct bus_type pci_bus_type = {
+ .pm = PCI_PM_OPS_PTR,
+ .num_vf = pci_bus_num_vf,
+ .dma_configure = pci_dma_configure,
+- .force_dma = true,
+ };
+ EXPORT_SYMBOL(pci_bus_type);
+
+diff --git a/include/linux/device.h b/include/linux/device.h
+index 012c4377..d57443b 100644
+--- a/include/linux/device.h
++++ b/include/linux/device.h
+@@ -99,8 +99,6 @@ extern void bus_remove_file(struct bus_type *, struct bus_attribute *);
+ * @p: The private data of the driver core, only the driver core can
+ * touch this.
+ * @lock_key: Lock class key for use by the lock validator
+- * @force_dma: Assume devices on this bus should be set up by dma_configure()
+- * even if DMA capability is not explicitly described by firmware.
+ *
+ * A bus is a channel between the processor and one or more devices. For the
+ * purposes of the device model, all devices are connected via a bus, even if
+@@ -141,8 +139,6 @@ struct bus_type {
+
+ struct subsys_private *p;
+ struct lock_class_key lock_key;
+-
+- bool force_dma;
+ };
+
+ extern int __must_check bus_register(struct bus_type *bus);
+diff --git a/include/linux/of_device.h b/include/linux/of_device.h
+index 8da5a1b..165fd30 100644
+--- a/include/linux/of_device.h
++++ b/include/linux/of_device.h
+@@ -55,7 +55,9 @@ static inline struct device_node *of_cpu_device_node_get(int cpu)
+ return of_node_get(cpu_dev->of_node);
+ }
+
+-int of_dma_configure(struct device *dev, struct device_node *np);
++int of_dma_configure(struct device *dev,
++ struct device_node *np,
++ bool force_dma);
+ void of_dma_deconfigure(struct device *dev);
+ #else /* CONFIG_OF */
+
+@@ -105,7 +107,9 @@ static inline struct device_node *of_cpu_device_node_get(int cpu)
+ return NULL;
+ }
+
+-static inline int of_dma_configure(struct device *dev, struct device_node *np)
++static inline int of_dma_configure(struct device *dev,
++ struct device_node *np,
++ bool force_dma)
+ {
+ return 0;
+ }
+--
+2.7.4
+
diff --git a/bsp/meta-rcar/meta-rcar-gen3-adas/recipes-kernel/linux/linux-renesas/0235-clk-renesas-r8a77980-Add-CMT-clocks.patch b/bsp/meta-rcar/meta-rcar-gen3-adas/recipes-kernel/linux/linux-renesas/0235-clk-renesas-r8a77980-Add-CMT-clocks.patch
new file mode 100644
index 00000000..2645cb56
--- /dev/null
+++ b/bsp/meta-rcar/meta-rcar-gen3-adas/recipes-kernel/linux/linux-renesas/0235-clk-renesas-r8a77980-Add-CMT-clocks.patch
@@ -0,0 +1,36 @@
+From 872df28a16628edbc81d821a4b54915baccbf467 Mon Sep 17 00:00:00 2001
+From: Sergei Shtylyov <sergei.shtylyov@cogentembedded.com>
+Date: Sat, 1 Sep 2018 21:54:27 +0300
+Subject: [PATCH 055/211] clk: renesas: r8a77980: Add CMT clocks
+
+Now that RCLK has been added by Geert, we can add the CMT module clocks.
+
+Based on the original (and large) patch by Vladimir Barinov.
+
+Signed-off-by: Vladimir Barinov <vladimir.barinov@cogentembedded.com>
+Signed-off-by: Sergei Shtylyov <sergei.shtylyov@cogentembedded.com>
+Signed-off-by: Geert Uytterhoeven <geert+renesas@glider.be>
+(cherry picked from commit 0a87bf6cd5297d8ae99f3560a7969a0b141f7350)
+Signed-off-by: Valentine Barshak <valentine.barshak@cogentembedded.com>
+---
+ drivers/clk/renesas/r8a77980-cpg-mssr.c | 4 ++++
+ 1 file changed, 4 insertions(+)
+
+diff --git a/drivers/clk/renesas/r8a77980-cpg-mssr.c b/drivers/clk/renesas/r8a77980-cpg-mssr.c
+index acf2b4d..25a3083 100644
+--- a/drivers/clk/renesas/r8a77980-cpg-mssr.c
++++ b/drivers/clk/renesas/r8a77980-cpg-mssr.c
+@@ -119,6 +119,10 @@ static const struct mssr_mod_clk r8a77980_mod_clks[] __initconst = {
+ DEF_MOD("msiof0", 211, R8A77980_CLK_MSO),
+ DEF_MOD("sys-dmac2", 217, R8A77980_CLK_S0D3),
+ DEF_MOD("sys-dmac1", 218, R8A77980_CLK_S0D3),
++ DEF_MOD("cmt3", 300, R8A77980_CLK_R),
++ DEF_MOD("cmt2", 301, R8A77980_CLK_R),
++ DEF_MOD("cmt1", 302, R8A77980_CLK_R),
++ DEF_MOD("cmt0", 303, R8A77980_CLK_R),
+ DEF_MOD("tpu0", 304, R8A77980_CLK_S3D4),
+ DEF_MOD("sdif", 314, R8A77980_CLK_SD0),
+ DEF_MOD("pciec0", 319, R8A77980_CLK_S2D2),
+--
+2.7.4
+
diff --git a/bsp/meta-rcar/meta-rcar-gen3-adas/recipes-kernel/linux/linux-renesas/0236-clk-renesas-r8a77970-Add-SD0H-SD0-clocks-for-SDHI.patch b/bsp/meta-rcar/meta-rcar-gen3-adas/recipes-kernel/linux/linux-renesas/0236-clk-renesas-r8a77970-Add-SD0H-SD0-clocks-for-SDHI.patch
new file mode 100644
index 00000000..adeb72eb
--- /dev/null
+++ b/bsp/meta-rcar/meta-rcar-gen3-adas/recipes-kernel/linux/linux-renesas/0236-clk-renesas-r8a77970-Add-SD0H-SD0-clocks-for-SDHI.patch
@@ -0,0 +1,169 @@
+From 5dce30d0e8c7b82b39e98b397c6ac9c741a8ed41 Mon Sep 17 00:00:00 2001
+From: Sergei Shtylyov <sergei.shtylyov@cogentembedded.com>
+Date: Sat, 1 Sep 2018 23:12:28 +0300
+Subject: [PATCH 056/211] clk: renesas: r8a77970: Add SD0H/SD0 clocks for SDHI
+
+On R-Car V3M (AKA R8A77970), the SD0CKCR is laid out differently than on
+the other R-Car gen3 SoCs. In fact, the layout is the same as on R-Car gen2
+SoCs, so we'll need to copy the divisor tables from the R-Car gen2 driver.
+We'll also need to support the SoC specific clock types, thus we're adding
+CLK_TYPE_GEN3_SOC_BASE at the end of 'enum rcar_gen3_clk_types', declare
+SD0H/SDH clocks in 'enum r8a77970_clk_types', and handle those clocks in
+the overridden cpg_clk_register() method; then, finally, add the SD-IF
+module clock (derived from the SD0 clock).
+
+Signed-off-by: Sergei Shtylyov <sergei.shtylyov@cogentembedded.com>
+Signed-off-by: Geert Uytterhoeven <geert+renesas@glider.be>
+(cherry picked from commit 381081ffc2948e1e1a7cbbafe3b91631530a1936)
+Signed-off-by: Valentine Barshak <valentine.barshak@cogentembedded.com>
+---
+ drivers/clk/renesas/r8a77970-cpg-mssr.c | 66 ++++++++++++++++++++++++++++++++-
+ drivers/clk/renesas/rcar-gen3-cpg.h | 3 ++
+ 2 files changed, 67 insertions(+), 2 deletions(-)
+
+diff --git a/drivers/clk/renesas/r8a77970-cpg-mssr.c b/drivers/clk/renesas/r8a77970-cpg-mssr.c
+index f558429..07d0ddc 100644
+--- a/drivers/clk/renesas/r8a77970-cpg-mssr.c
++++ b/drivers/clk/renesas/r8a77970-cpg-mssr.c
+@@ -1,7 +1,7 @@
+ /*
+ * r8a77970 Clock Pulse Generator / Module Standby and Software Reset
+ *
+- * Copyright (C) 2017 Cogent Embedded Inc.
++ * Copyright (C) 2017-2018 Cogent Embedded Inc.
+ *
+ * Based on r8a7795-cpg-mssr.c
+ *
+@@ -12,6 +12,7 @@
+ * the Free Software Foundation; version 2 of the License.
+ */
+
++#include <linux/clk-provider.h>
+ #include <linux/device.h>
+ #include <linux/init.h>
+ #include <linux/kernel.h>
+@@ -22,6 +23,13 @@
+ #include "renesas-cpg-mssr.h"
+ #include "rcar-gen3-cpg.h"
+
++#define CPG_SD0CKCR 0x0074
++
++enum r8a77970_clk_types {
++ CLK_TYPE_R8A77970_SD0H = CLK_TYPE_GEN3_SOC_BASE,
++ CLK_TYPE_R8A77970_SD0,
++};
++
+ enum clk_ids {
+ /* Core Clock Outputs exported to DT */
+ LAST_DT_CORE_CLK = R8A77970_CLK_OSC,
+@@ -42,6 +50,20 @@ enum clk_ids {
+ MOD_CLK_BASE
+ };
+
++static spinlock_t cpg_lock;
++
++static const struct clk_div_table cpg_sd0h_div_table[] = {
++ { 0, 2 }, { 1, 3 }, { 2, 4 }, { 3, 6 },
++ { 4, 8 }, { 5, 12 }, { 6, 16 }, { 7, 18 },
++ { 8, 24 }, { 10, 36 }, { 11, 48 }, { 0, 0 },
++};
++
++static const struct clk_div_table cpg_sd0_div_table[] = {
++ { 4, 8 }, { 5, 12 }, { 6, 16 }, { 7, 18 },
++ { 8, 24 }, { 10, 36 }, { 11, 48 }, { 12, 10 },
++ { 0, 0 },
++};
++
+ static const struct cpg_core_clk r8a77970_core_clks[] __initconst = {
+ /* External Clock Inputs */
+ DEF_INPUT("extal", CLK_EXTAL),
+@@ -68,6 +90,10 @@ static const struct cpg_core_clk r8a77970_core_clks[] __initconst = {
+ DEF_FIXED("s2d2", R8A77970_CLK_S2D2, CLK_PLL1_DIV2, 12, 1),
+ DEF_FIXED("s2d4", R8A77970_CLK_S2D4, CLK_PLL1_DIV2, 24, 1),
+
++ DEF_BASE("sd0h", R8A77970_CLK_SD0H, CLK_TYPE_R8A77970_SD0H,
++ CLK_PLL1_DIV2),
++ DEF_BASE("sd0", R8A77970_CLK_SD0, CLK_TYPE_R8A77970_SD0, CLK_PLL1_DIV2),
++
+ DEF_FIXED("cl", R8A77970_CLK_CL, CLK_PLL1_DIV2, 48, 1),
+ DEF_FIXED("cp", R8A77970_CLK_CP, CLK_EXTAL, 2, 1),
+
+@@ -92,6 +118,7 @@ static const struct mssr_mod_clk r8a77970_mod_clks[] __initconst = {
+ DEF_MOD("mfis", 213, R8A77970_CLK_S2D2),
+ DEF_MOD("sys-dmac2", 217, R8A77970_CLK_S2D1),
+ DEF_MOD("sys-dmac1", 218, R8A77970_CLK_S2D1),
++ DEF_MOD("sd-if", 314, R8A77970_CLK_SD0),
+ DEF_MOD("rwdt", 402, R8A77970_CLK_R),
+ DEF_MOD("intc-ex", 407, R8A77970_CLK_CP),
+ DEF_MOD("intc-ap", 408, R8A77970_CLK_S2D1),
+@@ -173,11 +200,46 @@ static int __init r8a77970_cpg_mssr_init(struct device *dev)
+ if (error)
+ return error;
+
++ spin_lock_init(&cpg_lock);
++
+ cpg_pll_config = &cpg_pll_configs[CPG_PLL_CONFIG_INDEX(cpg_mode)];
+
+ return rcar_gen3_cpg_init(cpg_pll_config, CLK_EXTALR, cpg_mode);
+ }
+
++static struct clk * __init r8a77970_cpg_clk_register(struct device *dev,
++ const struct cpg_core_clk *core, const struct cpg_mssr_info *info,
++ struct clk **clks, void __iomem *base,
++ struct raw_notifier_head *notifiers)
++{
++ const struct clk_div_table *table;
++ const struct clk *parent;
++ unsigned int shift;
++
++ switch (core->type) {
++ case CLK_TYPE_R8A77970_SD0H:
++ table = cpg_sd0h_div_table;
++ shift = 8;
++ break;
++ case CLK_TYPE_R8A77970_SD0:
++ table = cpg_sd0_div_table;
++ shift = 4;
++ break;
++ default:
++ return rcar_gen3_cpg_clk_register(dev, core, info, clks, base,
++ notifiers);
++ }
++
++ parent = clks[core->parent];
++ if (IS_ERR(parent))
++ return ERR_CAST(parent);
++
++ return clk_register_divider_table(NULL, core->name,
++ __clk_get_name(parent), 0,
++ base + CPG_SD0CKCR,
++ shift, 4, 0, table, &cpg_lock);
++}
++
+ const struct cpg_mssr_info r8a77970_cpg_mssr_info __initconst = {
+ /* Core Clocks */
+ .core_clks = r8a77970_core_clks,
+@@ -196,5 +258,5 @@ const struct cpg_mssr_info r8a77970_cpg_mssr_info __initconst = {
+
+ /* Callbacks */
+ .init = r8a77970_cpg_mssr_init,
+- .cpg_clk_register = rcar_gen3_cpg_clk_register,
++ .cpg_clk_register = r8a77970_cpg_clk_register,
+ };
+diff --git a/drivers/clk/renesas/rcar-gen3-cpg.h b/drivers/clk/renesas/rcar-gen3-cpg.h
+index 8bca3298..8834afe 100644
+--- a/drivers/clk/renesas/rcar-gen3-cpg.h
++++ b/drivers/clk/renesas/rcar-gen3-cpg.h
+@@ -27,6 +27,9 @@ enum rcar_gen3_clk_types {
+ CLK_TYPE_GEN3_ZG,
+ CLK_TYPE_GEN3_OSC, /* OSC EXTAL predivider and fixed divider */
+ CLK_TYPE_GEN3_RCKSEL, /* Select parent/divider using RCKCR.CKSEL */
++
++ /* SoC specific definitions start here */
++ CLK_TYPE_GEN3_SOC_BASE,
+ };
+
+ #define DEF_GEN3_SD(_name, _id, _parent, _offset) \
+--
+2.7.4
+
diff --git a/bsp/meta-rcar/meta-rcar-gen3-adas/recipes-kernel/linux/linux-renesas/0237-clk-renesas-r8a77970-Add-CMT-clocks.patch b/bsp/meta-rcar/meta-rcar-gen3-adas/recipes-kernel/linux/linux-renesas/0237-clk-renesas-r8a77970-Add-CMT-clocks.patch
new file mode 100644
index 00000000..ae2d085d
--- /dev/null
+++ b/bsp/meta-rcar/meta-rcar-gen3-adas/recipes-kernel/linux/linux-renesas/0237-clk-renesas-r8a77970-Add-CMT-clocks.patch
@@ -0,0 +1,37 @@
+From eb3fd6dd525a000338fb6c5c98c7b6abe2597aca Mon Sep 17 00:00:00 2001
+From: Sergei Shtylyov <sergei.shtylyov@cogentembedded.com>
+Date: Wed, 5 Sep 2018 19:59:48 +0300
+Subject: [PATCH 057/211] clk: renesas: r8a77970: Add CMT clocks
+
+Add the R8A77970 CMT module clocks.
+
+Based on the original (and large) patch by Vladimir Barinov.
+
+Signed-off-by: Vladimir Barinov <vladimir.barinov@cogentembedded.com>
+Signed-off-by: Sergei Shtylyov <sergei.shtylyov@cogentembedded.com>
+Reviewed-by: Chris Paterson <chris.paterson2@renesas.com>
+Signed-off-by: Geert Uytterhoeven <geert+renesas@glider.be>
+(cherry picked from commit 5986b503da614df3fccbf90edab3afa4c7550fa1)
+Signed-off-by: Valentine Barshak <valentine.barshak@cogentembedded.com>
+---
+ drivers/clk/renesas/r8a77970-cpg-mssr.c | 4 ++++
+ 1 file changed, 4 insertions(+)
+
+diff --git a/drivers/clk/renesas/r8a77970-cpg-mssr.c b/drivers/clk/renesas/r8a77970-cpg-mssr.c
+index 07d0ddc..f07a1ee 100644
+--- a/drivers/clk/renesas/r8a77970-cpg-mssr.c
++++ b/drivers/clk/renesas/r8a77970-cpg-mssr.c
+@@ -118,6 +118,10 @@ static const struct mssr_mod_clk r8a77970_mod_clks[] __initconst = {
+ DEF_MOD("mfis", 213, R8A77970_CLK_S2D2),
+ DEF_MOD("sys-dmac2", 217, R8A77970_CLK_S2D1),
+ DEF_MOD("sys-dmac1", 218, R8A77970_CLK_S2D1),
++ DEF_MOD("cmt3", 300, R8A77970_CLK_R),
++ DEF_MOD("cmt2", 301, R8A77970_CLK_R),
++ DEF_MOD("cmt1", 302, R8A77970_CLK_R),
++ DEF_MOD("cmt0", 303, R8A77970_CLK_R),
+ DEF_MOD("sd-if", 314, R8A77970_CLK_SD0),
+ DEF_MOD("rwdt", 402, R8A77970_CLK_R),
+ DEF_MOD("intc-ex", 407, R8A77970_CLK_CP),
+--
+2.7.4
+
diff --git a/bsp/meta-rcar/meta-rcar-gen3-adas/recipes-kernel/linux/linux-renesas/0238-clk-renesas-r8a77970-Add-TMU-clocks.patch b/bsp/meta-rcar/meta-rcar-gen3-adas/recipes-kernel/linux/linux-renesas/0238-clk-renesas-r8a77970-Add-TMU-clocks.patch
new file mode 100644
index 00000000..b4e03690
--- /dev/null
+++ b/bsp/meta-rcar/meta-rcar-gen3-adas/recipes-kernel/linux/linux-renesas/0238-clk-renesas-r8a77970-Add-TMU-clocks.patch
@@ -0,0 +1,38 @@
+From d70dba2e0a107d08b455bd47e31c2c8878b218df Mon Sep 17 00:00:00 2001
+From: Sergei Shtylyov <sergei.shtylyov@cogentembedded.com>
+Date: Thu, 6 Sep 2018 23:28:12 +0300
+Subject: [PATCH 058/211] clk: renesas: r8a77970: Add TMU clocks
+
+The TMU clocks weren't present in the original R8A77970 patch by Daisuke
+Matsushita, they were added in a later BSP version...
+
+Based on the original (and large) patch by Vladimir Barinov.
+
+Signed-off-by: Vladimir Barinov <vladimir.barinov@cogentembedded.com>
+Signed-off-by: Sergei Shtylyov <sergei.shtylyov@cogentembedded.com>
+Signed-off-by: Geert Uytterhoeven <geert+renesas@glider.be>
+(cherry picked from commit 6207ba04347705481d5e4021206179aadeb8e917)
+Signed-off-by: Valentine Barshak <valentine.barshak@cogentembedded.com>
+---
+ drivers/clk/renesas/r8a77970-cpg-mssr.c | 5 +++++
+ 1 file changed, 5 insertions(+)
+
+diff --git a/drivers/clk/renesas/r8a77970-cpg-mssr.c b/drivers/clk/renesas/r8a77970-cpg-mssr.c
+index f07a1ee..7a85e1a 100644
+--- a/drivers/clk/renesas/r8a77970-cpg-mssr.c
++++ b/drivers/clk/renesas/r8a77970-cpg-mssr.c
+@@ -106,6 +106,11 @@ static const struct cpg_core_clk r8a77970_core_clks[] __initconst = {
+ };
+
+ static const struct mssr_mod_clk r8a77970_mod_clks[] __initconst = {
++ DEF_MOD("tmu4", 121, R8A77970_CLK_S2D2),
++ DEF_MOD("tmu3", 122, R8A77970_CLK_S2D2),
++ DEF_MOD("tmu2", 123, R8A77970_CLK_S2D2),
++ DEF_MOD("tmu1", 124, R8A77970_CLK_S2D2),
++ DEF_MOD("tmu0", 125, R8A77970_CLK_CP),
+ DEF_MOD("ivcp1e", 127, R8A77970_CLK_S2D1),
+ DEF_MOD("scif4", 203, R8A77970_CLK_S2D4),
+ DEF_MOD("scif3", 204, R8A77970_CLK_S2D4),
+--
+2.7.4
+
diff --git a/bsp/meta-rcar/meta-rcar-gen3-adas/recipes-kernel/linux/linux-renesas/0239-dt-bindings-display-renesas-du-document-R8A77980-bin.patch b/bsp/meta-rcar/meta-rcar-gen3-adas/recipes-kernel/linux/linux-renesas/0239-dt-bindings-display-renesas-du-document-R8A77980-bin.patch
new file mode 100644
index 00000000..f20394f0
--- /dev/null
+++ b/bsp/meta-rcar/meta-rcar-gen3-adas/recipes-kernel/linux/linux-renesas/0239-dt-bindings-display-renesas-du-document-R8A77980-bin.patch
@@ -0,0 +1,43 @@
+From 9c2fc01ec6af67cbe69d61e15caf98f620cff08a Mon Sep 17 00:00:00 2001
+From: Sergei Shtylyov <sergei.shtylyov@cogentembedded.com>
+Date: Mon, 4 Jun 2018 22:04:59 +0300
+Subject: [PATCH 059/211] dt-bindings: display: renesas: du: document R8A77980
+ bindings
+
+Document the R-Car V3H (R8A77980) SoC in the R-Car DU bindings; the DU
+hardware has the same topology as in the R-Car V3M (R8A77970).
+
+Signed-off-by: Sergei Shtylyov <sergei.shtylyov@cogentembedded.com>
+Reviewed-by: Simon Horman <horms+renesas@verge.net.au>
+Reviewed-by: Laurent Pinchart <laurent.pinchart+renesas@ideasonboard.com>
+Signed-off-by: Laurent Pinchart <laurent.pinchart+renesas@ideasonboard.com>
+(cherry picked from commit 4ffe5aa53791ac5ab2c29e99f23c07cb85922dd5)
+[valentine.barshak: resolved minor conflicts]
+Signed-off-by: Valentine Barshak <valentine.barshak@cogentembedded.com>
+---
+ Documentation/devicetree/bindings/display/renesas,du.txt | 2 ++
+ 1 file changed, 2 insertions(+)
+
+diff --git a/Documentation/devicetree/bindings/display/renesas,du.txt b/Documentation/devicetree/bindings/display/renesas,du.txt
+index 7110432..101614c 100644
+--- a/Documentation/devicetree/bindings/display/renesas,du.txt
++++ b/Documentation/devicetree/bindings/display/renesas,du.txt
+@@ -15,6 +15,7 @@ Required Properties:
+ - "renesas,du-r8a7796" for R8A7796 (R-Car M3-W) compatible DU
+ - "renesas,du-r8a77965" for R8A77965 (R-Car M3-N) compatible DU
+ - "renesas,du-r8a77970" for R8A77970 (R-Car V3M) compatible DU
++ - "renesas,du-r8a77980" for R8A77980 (R-Car V3H) compatible DU
+ - "renesas,du-r8a77990" for R8A77990 (R-Car E3) compatible DU
+ - "renesas,du-r8a77995" for R8A77995 (R-Car D3) compatible DU
+
+@@ -63,6 +64,7 @@ corresponding to each DU output.
+ R8A7796 (R-Car M3-W) DPAD 0 HDMI 0 LVDS 0 -
+ R8A77965 (R-Car M3-N) DPAD 0 HDMI 0 LVDS 0 -
+ R8A77970 (R-Car V3M) DPAD 0 LVDS 0 - -
++ R8A77980 (R-Car V3H) DPAD 0 LVDS 0 - -
+ R8A77990 (R-Car E3) DPAD 0 LVDS 0 LVDS 1 -
+ R8A77995 (R-Car D3) DPAD 0 LVDS 0 LVDS 1 -
+
+--
+2.7.4
+
diff --git a/bsp/meta-rcar/meta-rcar-gen3-adas/recipes-kernel/linux/linux-renesas/0240-dt-bindings-display-renesas-lvds-document-R8A77980-b.patch b/bsp/meta-rcar/meta-rcar-gen3-adas/recipes-kernel/linux/linux-renesas/0240-dt-bindings-display-renesas-lvds-document-R8A77980-b.patch
new file mode 100644
index 00000000..6d5977e0
--- /dev/null
+++ b/bsp/meta-rcar/meta-rcar-gen3-adas/recipes-kernel/linux/linux-renesas/0240-dt-bindings-display-renesas-lvds-document-R8A77980-b.patch
@@ -0,0 +1,34 @@
+From 4200cbf65e9462e8cf342a2feb25361f3939f8d0 Mon Sep 17 00:00:00 2001
+From: Sergei Shtylyov <sergei.shtylyov@cogentembedded.com>
+Date: Tue, 5 Jun 2018 23:28:58 +0300
+Subject: [PATCH 060/211] dt-bindings: display: renesas: lvds: document
+ R8A77980 bindings
+
+Document the R-Car V3H (R8A77980) SoC in the R-Car LVDS bindings.
+
+Signed-off-by: Sergei Shtylyov <sergei.shtylyov@cogentembedded.com>
+Acked-by: Rob Herring <robh@kernel.org>
+Reviewed-by: Laurent Pinchart <laurent.pinchart+renesas@ideasonboard.com>
+Signed-off-by: Laurent Pinchart <laurent.pinchart+renesas@ideasonboard.com>
+(cherry picked from commit ab77eb4c4de77a3095abbc213b8f191c58ebdca1)
+[valentine.barshak: resolved minor conflicts]
+Signed-off-by: Valentine Barshak <valentine.barshak@cogentembedded.com>
+---
+ Documentation/devicetree/bindings/display/bridge/renesas,lvds.txt | 1 +
+ 1 file changed, 1 insertion(+)
+
+diff --git a/Documentation/devicetree/bindings/display/bridge/renesas,lvds.txt b/Documentation/devicetree/bindings/display/bridge/renesas,lvds.txt
+index 3589e54..32df75a 100644
+--- a/Documentation/devicetree/bindings/display/bridge/renesas,lvds.txt
++++ b/Documentation/devicetree/bindings/display/bridge/renesas,lvds.txt
+@@ -15,6 +15,7 @@ Required properties:
+ - "renesas,r8a7796-lvds" for R8A7796 (R-Car M3-W) compatible LVDS encoders
+ - "renesas,r8a77965-lvds" for R8A77965 (R-Car M3-N) compatible LVDS encoders
+ - "renesas,r8a77970-lvds" for R8A77970 (R-Car V3M) compatible LVDS encoders
++ - "renesas,r8a77980-lvds" for R8A77980 (R-Car V3H) compatible LVDS encoders
+ - "renesas,r8a77990-lvds" for R8A77990 (R-Car E3) compatible LVDS encoders
+ - "renesas,r8a77995-lvds" for R8A77995 (R-Car D3) compatible LVDS encoders
+
+--
+2.7.4
+
diff --git a/bsp/meta-rcar/meta-rcar-gen3-adas/recipes-kernel/linux/linux-renesas/0241-clk-renesas-r8a77970-Add-TPU-clock.patch b/bsp/meta-rcar/meta-rcar-gen3-adas/recipes-kernel/linux/linux-renesas/0241-clk-renesas-r8a77970-Add-TPU-clock.patch
new file mode 100644
index 00000000..c6897487
--- /dev/null
+++ b/bsp/meta-rcar/meta-rcar-gen3-adas/recipes-kernel/linux/linux-renesas/0241-clk-renesas-r8a77970-Add-TPU-clock.patch
@@ -0,0 +1,35 @@
+From 09bc907bbaf56b2fdc8e917da0c98353ccb66ea4 Mon Sep 17 00:00:00 2001
+From: Sergei Shtylyov <sergei.shtylyov@cogentembedded.com>
+Date: Wed, 19 Sep 2018 21:10:40 +0300
+Subject: [PATCH 061/211] clk: renesas: r8a77970: Add TPU clock
+
+The TPU0 clock wasn't present in the original R8A77970 patch by Daisuke
+Matsushita, it was added in a later BSP version...
+
+Based on the original (and large) patch by Vladimir Barinov.
+
+Signed-off-by: Vladimir Barinov <vladimir.barinov@cogentembedded.com>
+Signed-off-by: Sergei Shtylyov <sergei.shtylyov@cogentembedded.com>
+Reviewed-by: Simon Horman <horms+renesas@verge.net.au>
+Signed-off-by: Geert Uytterhoeven <geert+renesas@glider.be>
+(cherry picked from commit 9ef5e0370d3834a1ff11e22ae0a3220330890d36)
+Signed-off-by: Valentine Barshak <valentine.barshak@cogentembedded.com>
+---
+ drivers/clk/renesas/r8a77970-cpg-mssr.c | 1 +
+ 1 file changed, 1 insertion(+)
+
+diff --git a/drivers/clk/renesas/r8a77970-cpg-mssr.c b/drivers/clk/renesas/r8a77970-cpg-mssr.c
+index 7a85e1a..71341ff 100644
+--- a/drivers/clk/renesas/r8a77970-cpg-mssr.c
++++ b/drivers/clk/renesas/r8a77970-cpg-mssr.c
+@@ -127,6 +127,7 @@ static const struct mssr_mod_clk r8a77970_mod_clks[] __initconst = {
+ DEF_MOD("cmt2", 301, R8A77970_CLK_R),
+ DEF_MOD("cmt1", 302, R8A77970_CLK_R),
+ DEF_MOD("cmt0", 303, R8A77970_CLK_R),
++ DEF_MOD("tpu0", 304, R8A77970_CLK_S2D4),
+ DEF_MOD("sd-if", 314, R8A77970_CLK_SD0),
+ DEF_MOD("rwdt", 402, R8A77970_CLK_R),
+ DEF_MOD("intc-ex", 407, R8A77970_CLK_CP),
+--
+2.7.4
+
diff --git a/bsp/meta-rcar/meta-rcar-gen3-adas/recipes-kernel/linux/linux-renesas/0242-mmc-renesas_sdhi_internal_dmac-add-R8A77970-to-white.patch b/bsp/meta-rcar/meta-rcar-gen3-adas/recipes-kernel/linux/linux-renesas/0242-mmc-renesas_sdhi_internal_dmac-add-R8A77970-to-white.patch
new file mode 100644
index 00000000..84b37ef4
--- /dev/null
+++ b/bsp/meta-rcar/meta-rcar-gen3-adas/recipes-kernel/linux/linux-renesas/0242-mmc-renesas_sdhi_internal_dmac-add-R8A77970-to-white.patch
@@ -0,0 +1,35 @@
+From bd790ed9192f0d4f0e3c18af05fb6a39e101fba6 Mon Sep 17 00:00:00 2001
+From: Sergei Shtylyov <sergei.shtylyov@cogentembedded.com>
+Date: Sat, 18 Aug 2018 21:08:26 +0300
+Subject: [PATCH 062/211] mmc: renesas_sdhi_internal_dmac: add R8A77970 to
+ whitelist
+
+I've successfully tested eMMC on the V3H Starter Kit board and since the
+R8A77970 SoC has a single SDHI core, it can't be a subject to the known RX
+DMA errata.
+
+Signed-off-by: Sergei Shtylyov <sergei.shtylyov@cogentembedded.com>
+Reviewed-by: Wolfram Sang <wsa+renesas@sang-engineering.com>
+Signed-off-by: Ulf Hansson <ulf.hansson@linaro.org>
+Reviewed-by: Simon Horman <horms+renesas@verge.net.au>
+(cherry picked from commit 16a129b3caacb9bf86187de8342986457e09faa9)
+Signed-off-by: Valentine Barshak <valentine.barshak@cogentembedded.com>
+---
+ drivers/mmc/host/renesas_sdhi_internal_dmac.c | 1 +
+ 1 file changed, 1 insertion(+)
+
+diff --git a/drivers/mmc/host/renesas_sdhi_internal_dmac.c b/drivers/mmc/host/renesas_sdhi_internal_dmac.c
+index 32acb7d..6c3f657 100644
+--- a/drivers/mmc/host/renesas_sdhi_internal_dmac.c
++++ b/drivers/mmc/host/renesas_sdhi_internal_dmac.c
+@@ -331,6 +331,7 @@ static const struct soc_device_attribute gen3_soc_whitelist[] = {
+ { .soc_id = "r8a7795" },
+ { .soc_id = "r8a7796" },
+ { .soc_id = "r8a77965" },
++ { .soc_id = "r8a77970" },
+ { .soc_id = "r8a77980" },
+ { .soc_id = "r8a77990" },
+ { .soc_id = "r8a77995" },
+--
+2.7.4
+
diff --git a/bsp/meta-rcar/meta-rcar-gen3-adas/recipes-kernel/linux/linux-renesas/0243-dt-bindings-mmc-tmio_mmc-document-Renesas-R8A77970-b.patch b/bsp/meta-rcar/meta-rcar-gen3-adas/recipes-kernel/linux/linux-renesas/0243-dt-bindings-mmc-tmio_mmc-document-Renesas-R8A77970-b.patch
new file mode 100644
index 00000000..a482dd6a
--- /dev/null
+++ b/bsp/meta-rcar/meta-rcar-gen3-adas/recipes-kernel/linux/linux-renesas/0243-dt-bindings-mmc-tmio_mmc-document-Renesas-R8A77970-b.patch
@@ -0,0 +1,33 @@
+From d8aa4c14b62f4a1b96677b4e3173a64cf0ced214 Mon Sep 17 00:00:00 2001
+From: Sergei Shtylyov <sergei.shtylyov@cogentembedded.com>
+Date: Tue, 21 Aug 2018 22:14:12 +0300
+Subject: [PATCH 063/211] dt-bindings: mmc: tmio_mmc: document Renesas R8A77970
+ bindings
+
+Document the R-Car V3M (R8A77970) SoC in the R-Car SDHI bindings -- it's
+the usual R-Car gen3 compatible controller with the internal DMA engine.
+
+Signed-off-by: Sergei Shtylyov <sergei.shtylyov@cogentembedded.com>
+Signed-off-by: Ulf Hansson <ulf.hansson@linaro.org>
+Reviewed-by: Simon Horman <horms+renesas@verge.net.au>
+(cherry picked from commit 00c6527b8311e598ad9bfec8415fe96a94fa1b1b)
+Signed-off-by: Valentine Barshak <valentine.barshak@cogentembedded.com>
+---
+ Documentation/devicetree/bindings/mmc/tmio_mmc.txt | 1 +
+ 1 file changed, 1 insertion(+)
+
+diff --git a/Documentation/devicetree/bindings/mmc/tmio_mmc.txt b/Documentation/devicetree/bindings/mmc/tmio_mmc.txt
+index c434200..9d0ea43 100644
+--- a/Documentation/devicetree/bindings/mmc/tmio_mmc.txt
++++ b/Documentation/devicetree/bindings/mmc/tmio_mmc.txt
+@@ -27,6 +27,7 @@ Required properties:
+ "renesas,sdhi-r8a7795" - SDHI IP on R8A7795 SoC
+ "renesas,sdhi-r8a7796" - SDHI IP on R8A7796 SoC
+ "renesas,sdhi-r8a77965" - SDHI IP on R8A77965 SoC
++ "renesas,sdhi-r8a77970" - SDHI IP on R8A77970 SoC
+ "renesas,sdhi-r8a77980" - SDHI IP on R8A77980 SoC
+ "renesas,sdhi-r8a77990" - SDHI IP on R8A77990 SoC
+ "renesas,sdhi-r8a77995" - SDHI IP on R8A77995 SoC
+--
+2.7.4
+
diff --git a/bsp/meta-rcar/meta-rcar-gen3-adas/recipes-kernel/linux/linux-renesas/0244-dt-bindings-thermal-rcar-gen3-thermal-document-R8A77.patch b/bsp/meta-rcar/meta-rcar-gen3-adas/recipes-kernel/linux/linux-renesas/0244-dt-bindings-thermal-rcar-gen3-thermal-document-R8A77.patch
new file mode 100644
index 00000000..34ff8a6c
--- /dev/null
+++ b/bsp/meta-rcar/meta-rcar-gen3-adas/recipes-kernel/linux/linux-renesas/0244-dt-bindings-thermal-rcar-gen3-thermal-document-R8A77.patch
@@ -0,0 +1,49 @@
+From f33694d540db9a8c5e0e736c22d764b85ec4eea8 Mon Sep 17 00:00:00 2001
+From: Sergei Shtylyov <sergei.shtylyov@cogentembedded.com>
+Date: Tue, 9 Oct 2018 22:10:14 +0300
+Subject: [PATCH 064/211] dt-bindings: thermal: rcar-gen3-thermal: document
+ R8A77980 bindings
+MIME-Version: 1.0
+Content-Type: text/plain; charset=UTF-8
+Content-Transfer-Encoding: 8bit
+
+Document the R-Car V3H (R8A77980) SoC in the Renesas R-Car gen3 thermal
+bindings.
+
+Signed-off-by: Sergei Shtylyov <sergei.shtylyov@cogentembedded.com>
+Reviewed-by: Simon Horman <horms+renesas@verge.net.au>
+Reviewed-by: Niklas Söderlund <niklas.soderlund+renesas@ragnatech.se>
+Reviewed-by: Rob Herring <robh@kernel.org>
+Signed-off-by: Eduardo Valentin <edubezval@gmail.com>
+(cherry picked from commit 8583d8d621eb7f38e388dfe53a45fff908ccf07d)
+[valentine.barshak: resolved a minor conflict]
+Signed-off-by: Valentine Barshak <valentine.barshak@cogentembedded.com>
+---
+ Documentation/devicetree/bindings/thermal/rcar-gen3-thermal.txt | 4 +++-
+ 1 file changed, 3 insertions(+), 1 deletion(-)
+
+diff --git a/Documentation/devicetree/bindings/thermal/rcar-gen3-thermal.txt b/Documentation/devicetree/bindings/thermal/rcar-gen3-thermal.txt
+index 261c3fe..7bb6d0b 100644
+--- a/Documentation/devicetree/bindings/thermal/rcar-gen3-thermal.txt
++++ b/Documentation/devicetree/bindings/thermal/rcar-gen3-thermal.txt
+@@ -11,6 +11,7 @@ Required properties:
+ - "renesas,r8a7796-thermal" (R-Car M3-W)
+ - "renesas,r8a77965-thermal" (R-Car M3-N)
+ - "renesas,r8a77990-thermal" (R-Car E3)
++ - "renesas,r8a77980-thermal" (R-Car V3H)
+ - reg : Address ranges of the thermal registers. Each sensor
+ needs one address range. Sorting must be done in
+ increasing order according to datasheet, i.e.
+@@ -20,7 +21,8 @@ Required properties:
+
+ Optional properties:
+
+-- interrupts : interrupts routed to the TSC (3 for H3, M3-W and M3-N)
++- interrupts : interrupts routed to the TSC (3 for H3, M3-W, M3-N,
++ and V3H)
+ - power-domain : Must contain a reference to the power domain. This
+ property is mandatory if the thermal sensor instance
+ is part of a controllable power domain.
+--
+2.7.4
+
diff --git a/bsp/meta-rcar/meta-rcar-gen3-adas/recipes-kernel/linux/linux-renesas/0245-thermal-rcar_gen3_thermal-add-R8A77980-support.patch b/bsp/meta-rcar/meta-rcar-gen3-adas/recipes-kernel/linux/linux-renesas/0245-thermal-rcar_gen3_thermal-add-R8A77980-support.patch
new file mode 100644
index 00000000..6b20a2b5
--- /dev/null
+++ b/bsp/meta-rcar/meta-rcar-gen3-adas/recipes-kernel/linux/linux-renesas/0245-thermal-rcar_gen3_thermal-add-R8A77980-support.patch
@@ -0,0 +1,39 @@
+From d156c8fc896a879704fcbbe87e2b923d84df89e9 Mon Sep 17 00:00:00 2001
+From: Sergei Shtylyov <sergei.shtylyov@cogentembedded.com>
+Date: Tue, 9 Oct 2018 22:11:51 +0300
+Subject: [PATCH 065/211] thermal: rcar_gen3_thermal: add R8A77980 support
+MIME-Version: 1.0
+Content-Type: text/plain; charset=UTF-8
+Content-Transfer-Encoding: 8bit
+
+Add the R-Car V3H (R8A77980) SoC support to the R-Car gen3 thermal driver.
+
+Signed-off-by: Sergei Shtylyov <sergei.shtylyov@cogentembedded.com>
+Reviewed-by: Simon Horman <horms+renesas@verge.net.au>
+Reviewed-by: Niklas Söderlund <niklas.soderlund+renesas@ragnatech.se>
+Signed-off-by: Eduardo Valentin <edubezval@gmail.com>
+(cherry picked from commit 853cbc1f2d3a6ef9d5f6f99fe7c4b7595eae9d3a)
+[valentine.barshak: resolved a minor conflict]
+Signed-off-by: Valentine Barshak <valentine.barshak@cogentembedded.com>
+---
+ drivers/thermal/rcar_gen3_thermal.c | 2 ++
+ 1 file changed, 2 insertions(+)
+
+diff --git a/drivers/thermal/rcar_gen3_thermal.c b/drivers/thermal/rcar_gen3_thermal.c
+index ae17e73..37e9308 100644
+--- a/drivers/thermal/rcar_gen3_thermal.c
++++ b/drivers/thermal/rcar_gen3_thermal.c
+@@ -516,8 +516,10 @@ static const struct of_device_id rcar_gen3_thermal_dt_ids[] = {
+ { .compatible = "renesas,r8a7795-thermal", },
+ { .compatible = "renesas,r8a7796-thermal", },
+ { .compatible = "renesas,r8a77965-thermal", },
++ { .compatible = "renesas,r8a77980-thermal", },
+ { .compatible = "renesas,r8a77990-thermal", },
+ { /*sentinel*/ },
++ {},
+ };
+ MODULE_DEVICE_TABLE(of, rcar_gen3_thermal_dt_ids);
+
+--
+2.7.4
+
diff --git a/bsp/meta-rcar/meta-rcar-gen3-adas/recipes-kernel/linux/linux-renesas/0246-dt-bindings-thermal-rcar-thermal-document-R8A77970-b.patch b/bsp/meta-rcar/meta-rcar-gen3-adas/recipes-kernel/linux/linux-renesas/0246-dt-bindings-thermal-rcar-thermal-document-R8A77970-b.patch
new file mode 100644
index 00000000..8f2da116
--- /dev/null
+++ b/bsp/meta-rcar/meta-rcar-gen3-adas/recipes-kernel/linux/linux-renesas/0246-dt-bindings-thermal-rcar-thermal-document-R8A77970-b.patch
@@ -0,0 +1,54 @@
+From 6a99288d90a45d6b92664a89ec5ab2939840ecf2 Mon Sep 17 00:00:00 2001
+From: Sergei Shtylyov <sergei.shtylyov@cogentembedded.com>
+Date: Fri, 5 Oct 2018 00:01:38 +0300
+Subject: [PATCH 066/211] dt-bindings: thermal: rcar-thermal: document R8A77970
+ bindings
+
+Document the R-Car V3M (R8A77970) SoC in the Renesas R-Car gen2 thermal
+bindings. The hardware is the same as in the R-Car D3 (R8A77995) plus an
+extra status register.
+
+Signed-off-by: Sergei Shtylyov <sergei.shtylyov@cogentembedded.com>
+Reviewed-by: Geert Uytterhoeven <geert+renesas@glider.be>
+Reviewed-by: Simon Horman <horms+renesas@verge.net.au>
+Reviewed-by: Rob Herring <robh@kernel.org>
+Signed-off-by: Eduardo Valentin <edubezval@gmail.com>
+(cherry picked from commit a14404a9f04b904bd0c22f34e2119afbf1425abe)
+Signed-off-by: Valentine Barshak <valentine.barshak@cogentembedded.com>
+---
+ Documentation/devicetree/bindings/thermal/rcar-thermal.txt | 5 +++--
+ 1 file changed, 3 insertions(+), 2 deletions(-)
+
+diff --git a/Documentation/devicetree/bindings/thermal/rcar-thermal.txt b/Documentation/devicetree/bindings/thermal/rcar-thermal.txt
+index 67c563f..6176558 100644
+--- a/Documentation/devicetree/bindings/thermal/rcar-thermal.txt
++++ b/Documentation/devicetree/bindings/thermal/rcar-thermal.txt
+@@ -4,7 +4,7 @@ Required properties:
+ - compatible : "renesas,thermal-<soctype>",
+ "renesas,rcar-gen2-thermal" (with thermal-zone) or
+ "renesas,rcar-thermal" (without thermal-zone) as
+- fallback except R-Car D3.
++ fallback except R-Car V3M/D3.
+ Examples with soctypes are:
+ - "renesas,thermal-r8a73a4" (R-Mobile APE6)
+ - "renesas,thermal-r8a7743" (RZ/G1M)
+@@ -13,6 +13,7 @@ Required properties:
+ - "renesas,thermal-r8a7791" (R-Car M2-W)
+ - "renesas,thermal-r8a7792" (R-Car V2H)
+ - "renesas,thermal-r8a7793" (R-Car M2-N)
++ - "renesas,thermal-r8a77970" (R-Car V3M)
+ - "renesas,thermal-r8a77995" (R-Car D3)
+ - reg : Address range of the thermal registers.
+ The 1st reg will be recognized as common register
+@@ -21,7 +22,7 @@ Required properties:
+ Option properties:
+
+ - interrupts : If present should contain 3 interrupts for
+- R-Car D3 or 1 interrupt otherwise.
++ R-Car V3M/D3 or 1 interrupt otherwise.
+
+ Example (non interrupt support):
+
+--
+2.7.4
+
diff --git a/bsp/meta-rcar/meta-rcar-gen3-adas/recipes-kernel/linux/linux-renesas/0247-thermal-rcar_thermal-add-R8A77970-support.patch b/bsp/meta-rcar/meta-rcar-gen3-adas/recipes-kernel/linux/linux-renesas/0247-thermal-rcar_thermal-add-R8A77970-support.patch
new file mode 100644
index 00000000..af4b3d6a
--- /dev/null
+++ b/bsp/meta-rcar/meta-rcar-gen3-adas/recipes-kernel/linux/linux-renesas/0247-thermal-rcar_thermal-add-R8A77970-support.patch
@@ -0,0 +1,37 @@
+From 02c9e06095279dff4a1a91b1aacfc21c184c6c53 Mon Sep 17 00:00:00 2001
+From: Sergei Shtylyov <sergei.shtylyov@cogentembedded.com>
+Date: Fri, 5 Oct 2018 00:03:13 +0300
+Subject: [PATCH 067/211] thermal: rcar_thermal: add R8A77970 support
+
+Add the R-Car V3M (R8A77970) SoC support to the R-Car gen2 thermal driver.
+The hardware is the same as in the R-Car D3 (R8A77995) plus the CIVM status
+register (we don't use).
+
+Signed-off-by: Sergei Shtylyov <sergei.shtylyov@cogentembedded.com>
+Reviewed-by: Geert Uytterhoeven <geert+renesas@glider.be>
+Reviewed-by: Simon Horman <horms+renesas@verge.net.au>
+Signed-off-by: Eduardo Valentin <edubezval@gmail.com>
+(cherry picked from commit 92ca366e9b835ada0bfe3c663da91ae44d7e8184)
+Signed-off-by: Valentine Barshak <valentine.barshak@cogentembedded.com>
+---
+ drivers/thermal/rcar_thermal.c | 4 ++++
+ 1 file changed, 4 insertions(+)
+
+diff --git a/drivers/thermal/rcar_thermal.c b/drivers/thermal/rcar_thermal.c
+index e77e6307..e3fd253 100644
+--- a/drivers/thermal/rcar_thermal.c
++++ b/drivers/thermal/rcar_thermal.c
+@@ -125,6 +125,10 @@ static const struct of_device_id rcar_thermal_dt_ids[] = {
+ .data = &rcar_gen2_thermal,
+ },
+ {
++ .compatible = "renesas,thermal-r8a77970",
++ .data = &rcar_gen3_thermal,
++ },
++ {
+ .compatible = "renesas,thermal-r8a77995",
+ .data = &rcar_gen3_thermal,
+ },
+--
+2.7.4
+
diff --git a/bsp/meta-rcar/meta-rcar-gen3-adas/recipes-kernel/linux/linux-renesas/0248-clk-renesas-r8a77970-Add-RPC-clocks.patch b/bsp/meta-rcar/meta-rcar-gen3-adas/recipes-kernel/linux/linux-renesas/0248-clk-renesas-r8a77970-Add-RPC-clocks.patch
new file mode 100644
index 00000000..3f885120
--- /dev/null
+++ b/bsp/meta-rcar/meta-rcar-gen3-adas/recipes-kernel/linux/linux-renesas/0248-clk-renesas-r8a77970-Add-RPC-clocks.patch
@@ -0,0 +1,41 @@
+From 75998e4d0480f8aba180df2c6da5b0b374487b6b Mon Sep 17 00:00:00 2001
+From: Sergei Shtylyov <sergei.shtylyov@cogentembedded.com>
+Date: Fri, 2 Nov 2018 22:25:54 +0300
+Subject: [PATCH 068/211] clk: renesas: r8a77970: Add RPC clocks
+
+On R-Car V3M (R8A77970), the RPC/RPCD2 clocks are output by the common
+divider. Describe them, as well as the RPC-IF module clock.
+
+Signed-off-by: Sergei Shtylyov <sergei.shtylyov@cogentembedded.com>
+Signed-off-by: Geert Uytterhoeven <geert+renesas@glider.be>
+(cherry picked from commit 6f44610c30c5f10a8ea06bd714015cc4d2e534f5)
+Signed-off-by: Valentine Barshak <valentine.barshak@cogentembedded.com>
+---
+ drivers/clk/renesas/r8a77970-cpg-mssr.c | 4 ++++
+ 1 file changed, 4 insertions(+)
+
+diff --git a/drivers/clk/renesas/r8a77970-cpg-mssr.c b/drivers/clk/renesas/r8a77970-cpg-mssr.c
+index 71341ff..6885c62 100644
+--- a/drivers/clk/renesas/r8a77970-cpg-mssr.c
++++ b/drivers/clk/renesas/r8a77970-cpg-mssr.c
+@@ -94,6 +94,9 @@ static const struct cpg_core_clk r8a77970_core_clks[] __initconst = {
+ CLK_PLL1_DIV2),
+ DEF_BASE("sd0", R8A77970_CLK_SD0, CLK_TYPE_R8A77970_SD0, CLK_PLL1_DIV2),
+
++ DEF_FIXED("rpc", R8A77970_CLK_RPC, CLK_PLL1_DIV2, 5, 1),
++ DEF_FIXED("rpcd2", R8A77970_CLK_RPCD2, CLK_PLL1_DIV2, 10, 1),
++
+ DEF_FIXED("cl", R8A77970_CLK_CL, CLK_PLL1_DIV2, 48, 1),
+ DEF_FIXED("cp", R8A77970_CLK_CP, CLK_EXTAL, 2, 1),
+
+@@ -155,6 +158,7 @@ static const struct mssr_mod_clk r8a77970_mod_clks[] __initconst = {
+ DEF_MOD("gpio1", 911, R8A77970_CLK_CP),
+ DEF_MOD("gpio0", 912, R8A77970_CLK_CP),
+ DEF_MOD("can-fd", 914, R8A77970_CLK_S2D2),
++ DEF_MOD("rpc-if", 917, R8A77970_CLK_RPC),
+ DEF_MOD("i2c4", 927, R8A77970_CLK_S2D2),
+ DEF_MOD("i2c3", 928, R8A77970_CLK_S2D2),
+ DEF_MOD("i2c2", 929, R8A77970_CLK_S2D2),
+--
+2.7.4
+
diff --git a/bsp/meta-rcar/meta-rcar-gen3-adas/recipes-kernel/linux/linux-renesas/0249-pinctrl-sh-pfc-r8a77970-Add-QSPI-pins-groups-and-fun.patch b/bsp/meta-rcar/meta-rcar-gen3-adas/recipes-kernel/linux/linux-renesas/0249-pinctrl-sh-pfc-r8a77970-Add-QSPI-pins-groups-and-fun.patch
new file mode 100644
index 00000000..50a25854
--- /dev/null
+++ b/bsp/meta-rcar/meta-rcar-gen3-adas/recipes-kernel/linux/linux-renesas/0249-pinctrl-sh-pfc-r8a77970-Add-QSPI-pins-groups-and-fun.patch
@@ -0,0 +1,128 @@
+From 41ae73397a4480f0061be5ac96c73ea73601fe40 Mon Sep 17 00:00:00 2001
+From: Dmitry Shifrin <dmitry.shifrin@cogentembedded.com>
+Date: Tue, 6 Nov 2018 21:52:55 +0300
+Subject: [PATCH 069/211] pinctrl: sh-pfc: r8a77970: Add QSPI pins, groups, and
+ functions
+
+Add the QSPI{0|1} pins/groups/functions to the R8A77970 PFC driver.
+
+[Sergei: ported to the upstream driver, fixed up the swapped QSPI0 SPCLK/
+SSL pins, fixed up the comments, moved the QSPI pins/groups/functions to
+be in the alphanumeric order, removed unneeded empty lines, renamed the
+patch.]
+
+Signed-off-by: Dmitry Shifrin <dmitry.shifrin@cogentembedded.com>
+Signed-off-by: Sergei Shtylyov <sergei.shtylyov@cogentembedded.com>
+Reviewed-by: Simon Horman <horms+renesas@verge.net.au>
+Signed-off-by: Geert Uytterhoeven <geert+renesas@glider.be>
+(cherry picked from commit 3ad8fbd83fab8125004c6953563779c89331fa25)
+Signed-off-by: Valentine Barshak <valentine.barshak@cogentembedded.com>
+---
+ drivers/pinctrl/sh-pfc/pfc-r8a77970.c | 70 +++++++++++++++++++++++++++++++++++
+ 1 file changed, 70 insertions(+)
+
+diff --git a/drivers/pinctrl/sh-pfc/pfc-r8a77970.c b/drivers/pinctrl/sh-pfc/pfc-r8a77970.c
+index eeb58b3..9b96e5d 100644
+--- a/drivers/pinctrl/sh-pfc/pfc-r8a77970.c
++++ b/drivers/pinctrl/sh-pfc/pfc-r8a77970.c
+@@ -1385,6 +1385,56 @@ static const unsigned int pwm4_b_mux[] = {
+ PWM4_B_MARK,
+ };
+
++/* - QSPI0 ------------------------------------------------------------------ */
++static const unsigned int qspi0_ctrl_pins[] = {
++ /* SPCLK, SSL */
++ RCAR_GP_PIN(5, 0), RCAR_GP_PIN(5, 5),
++};
++static const unsigned int qspi0_ctrl_mux[] = {
++ QSPI0_SPCLK_MARK, QSPI0_SSL_MARK,
++};
++static const unsigned int qspi0_data2_pins[] = {
++ /* MOSI_IO0, MISO_IO1 */
++ RCAR_GP_PIN(5, 1), RCAR_GP_PIN(5, 2),
++};
++static const unsigned int qspi0_data2_mux[] = {
++ QSPI0_MOSI_IO0_MARK, QSPI0_MISO_IO1_MARK,
++};
++static const unsigned int qspi0_data4_pins[] = {
++ /* MOSI_IO0, MISO_IO1, IO2, IO3 */
++ RCAR_GP_PIN(5, 1), RCAR_GP_PIN(5, 2),
++ RCAR_GP_PIN(5, 3), RCAR_GP_PIN(5, 4),
++};
++static const unsigned int qspi0_data4_mux[] = {
++ QSPI0_MOSI_IO0_MARK, QSPI0_MISO_IO1_MARK,
++ QSPI0_IO2_MARK, QSPI0_IO3_MARK
++};
++
++/* - QSPI1 ------------------------------------------------------------------ */
++static const unsigned int qspi1_ctrl_pins[] = {
++ /* SPCLK, SSL */
++ RCAR_GP_PIN(5, 6), RCAR_GP_PIN(5, 11),
++};
++static const unsigned int qspi1_ctrl_mux[] = {
++ QSPI1_SPCLK_MARK, QSPI1_SSL_MARK,
++};
++static const unsigned int qspi1_data2_pins[] = {
++ /* MOSI_IO0, MISO_IO1 */
++ RCAR_GP_PIN(5, 7), RCAR_GP_PIN(5, 8),
++};
++static const unsigned int qspi1_data2_mux[] = {
++ QSPI1_MOSI_IO0_MARK, QSPI1_MISO_IO1_MARK,
++};
++static const unsigned int qspi1_data4_pins[] = {
++ /* MOSI_IO0, MISO_IO1, IO2, IO3 */
++ RCAR_GP_PIN(5, 7), RCAR_GP_PIN(5, 8),
++ RCAR_GP_PIN(5, 9), RCAR_GP_PIN(5, 10),
++};
++static const unsigned int qspi1_data4_mux[] = {
++ QSPI1_MOSI_IO0_MARK, QSPI1_MISO_IO1_MARK,
++ QSPI1_IO2_MARK, QSPI1_IO3_MARK
++};
++
+ /* - SCIF Clock ------------------------------------------------------------- */
+ static const unsigned int scif_clk_a_pins[] = {
+ /* SCIF_CLK */
+@@ -1759,6 +1809,12 @@ static const struct sh_pfc_pin_group pinmux_groups[] = {
+ SH_PFC_PIN_GROUP(pwm3_b),
+ SH_PFC_PIN_GROUP(pwm4_a),
+ SH_PFC_PIN_GROUP(pwm4_b),
++ SH_PFC_PIN_GROUP(qspi0_ctrl),
++ SH_PFC_PIN_GROUP(qspi0_data2),
++ SH_PFC_PIN_GROUP(qspi0_data4),
++ SH_PFC_PIN_GROUP(qspi1_ctrl),
++ SH_PFC_PIN_GROUP(qspi1_data2),
++ SH_PFC_PIN_GROUP(qspi1_data4),
+ SH_PFC_PIN_GROUP(scif_clk_a),
+ SH_PFC_PIN_GROUP(scif_clk_b),
+ SH_PFC_PIN_GROUP(scif0_data),
+@@ -1953,6 +2009,18 @@ static const char * const pwm4_groups[] = {
+ "pwm4_b",
+ };
+
++static const char * const qspi0_groups[] = {
++ "qspi0_ctrl",
++ "qspi0_data2",
++ "qspi0_data4",
++};
++
++static const char * const qspi1_groups[] = {
++ "qspi1_ctrl",
++ "qspi1_data2",
++ "qspi1_data4",
++};
++
+ static const char * const scif_clk_groups[] = {
+ "scif_clk_a",
+ "scif_clk_b",
+@@ -2036,6 +2104,8 @@ static const struct sh_pfc_function pinmux_functions[] = {
+ SH_PFC_FUNCTION(pwm2),
+ SH_PFC_FUNCTION(pwm3),
+ SH_PFC_FUNCTION(pwm4),
++ SH_PFC_FUNCTION(qspi0),
++ SH_PFC_FUNCTION(qspi1),
+ SH_PFC_FUNCTION(scif_clk),
+ SH_PFC_FUNCTION(scif0),
+ SH_PFC_FUNCTION(scif1),
+--
+2.7.4
+
diff --git a/bsp/meta-rcar/meta-rcar-gen3-adas/recipes-kernel/linux/linux-renesas/0250-pinctrl-sh-pfc-r8a77980-Add-QSPI-pins-groups-and-fun.patch b/bsp/meta-rcar/meta-rcar-gen3-adas/recipes-kernel/linux/linux-renesas/0250-pinctrl-sh-pfc-r8a77980-Add-QSPI-pins-groups-and-fun.patch
new file mode 100644
index 00000000..3be45faf
--- /dev/null
+++ b/bsp/meta-rcar/meta-rcar-gen3-adas/recipes-kernel/linux/linux-renesas/0250-pinctrl-sh-pfc-r8a77980-Add-QSPI-pins-groups-and-fun.patch
@@ -0,0 +1,127 @@
+From 45a14984163349d8ea4db1463322944e54e7ce54 Mon Sep 17 00:00:00 2001
+From: Dmitry Shifrin <dmitry.shifrin@cogentembedded.com>
+Date: Mon, 19 Nov 2018 20:30:06 +0300
+Subject: [PATCH 070/211] pinctrl: sh-pfc: r8a77980: Add QSPI pins, groups, and
+ functions
+
+Add the QSPI{0|1} pins/groups/functions to the R8A77980 PFC driver.
+
+[Sergei: ported to the upstream driver, fixed up the swapped QSPI0 SPCLK/
+SSL pins, fixed up the comments, moved the QSPI pins/groups/functions to
+be in the alphanumeric order, removed unneeded empty lines, renamed the
+patch.]
+
+Signed-off-by: Dmitry Shifrin <dmitry.shifrin@cogentembedded.com>
+Signed-off-by: Sergei Shtylyov <sergei.shtylyov@cogentembedded.com>
+Signed-off-by: Geert Uytterhoeven <geert+renesas@glider.be>
+(cherry picked from commit c21b73235e1fa644dcc725078af38e13cdb778fb)
+Signed-off-by: Valentine Barshak <valentine.barshak@cogentembedded.com>
+---
+ drivers/pinctrl/sh-pfc/pfc-r8a77980.c | 70 +++++++++++++++++++++++++++++++++++
+ 1 file changed, 70 insertions(+)
+
+diff --git a/drivers/pinctrl/sh-pfc/pfc-r8a77980.c b/drivers/pinctrl/sh-pfc/pfc-r8a77980.c
+index 3f69673..aa1d50b 100644
+--- a/drivers/pinctrl/sh-pfc/pfc-r8a77980.c
++++ b/drivers/pinctrl/sh-pfc/pfc-r8a77980.c
+@@ -1660,6 +1660,56 @@ static const unsigned int pwm4_b_mux[] = {
+ PWM4_B_MARK,
+ };
+
++/* - QSPI0 ------------------------------------------------------------------ */
++static const unsigned int qspi0_ctrl_pins[] = {
++ /* SPCLK, SSL */
++ RCAR_GP_PIN(5, 0), RCAR_GP_PIN(5, 5),
++};
++static const unsigned int qspi0_ctrl_mux[] = {
++ QSPI0_SPCLK_MARK, QSPI0_SSL_MARK,
++};
++static const unsigned int qspi0_data2_pins[] = {
++ /* MOSI_IO0, MISO_IO1 */
++ RCAR_GP_PIN(5, 1), RCAR_GP_PIN(5, 2),
++};
++static const unsigned int qspi0_data2_mux[] = {
++ QSPI0_MOSI_IO0_MARK, QSPI0_MISO_IO1_MARK,
++};
++static const unsigned int qspi0_data4_pins[] = {
++ /* MOSI_IO0, MISO_IO1, IO2, IO3 */
++ RCAR_GP_PIN(5, 1), RCAR_GP_PIN(5, 2),
++ RCAR_GP_PIN(5, 3), RCAR_GP_PIN(5, 4),
++};
++static const unsigned int qspi0_data4_mux[] = {
++ QSPI0_MOSI_IO0_MARK, QSPI0_MISO_IO1_MARK,
++ QSPI0_IO2_MARK, QSPI0_IO3_MARK
++};
++
++/* - QSPI1 ------------------------------------------------------------------ */
++static const unsigned int qspi1_ctrl_pins[] = {
++ /* SPCLK, SSL */
++ RCAR_GP_PIN(5, 6), RCAR_GP_PIN(5, 11),
++};
++static const unsigned int qspi1_ctrl_mux[] = {
++ QSPI1_SPCLK_MARK, QSPI1_SSL_MARK,
++};
++static const unsigned int qspi1_data2_pins[] = {
++ /* MOSI_IO0, MISO_IO1 */
++ RCAR_GP_PIN(5, 7), RCAR_GP_PIN(5, 8),
++};
++static const unsigned int qspi1_data2_mux[] = {
++ QSPI1_MOSI_IO0_MARK, QSPI1_MISO_IO1_MARK,
++};
++static const unsigned int qspi1_data4_pins[] = {
++ /* MOSI_IO0, MISO_IO1, IO2, IO3 */
++ RCAR_GP_PIN(5, 7), RCAR_GP_PIN(5, 8),
++ RCAR_GP_PIN(5, 9), RCAR_GP_PIN(5, 10),
++};
++static const unsigned int qspi1_data4_mux[] = {
++ QSPI1_MOSI_IO0_MARK, QSPI1_MISO_IO1_MARK,
++ QSPI1_IO2_MARK, QSPI1_IO3_MARK
++};
++
+ /* - SCIF0 ------------------------------------------------------------------ */
+ static const unsigned int scif0_data_pins[] = {
+ /* RX0, TX0 */
+@@ -2092,6 +2142,12 @@ static const struct sh_pfc_pin_group pinmux_groups[] = {
+ SH_PFC_PIN_GROUP(pwm3_b),
+ SH_PFC_PIN_GROUP(pwm4_a),
+ SH_PFC_PIN_GROUP(pwm4_b),
++ SH_PFC_PIN_GROUP(qspi0_ctrl),
++ SH_PFC_PIN_GROUP(qspi0_data2),
++ SH_PFC_PIN_GROUP(qspi0_data4),
++ SH_PFC_PIN_GROUP(qspi1_ctrl),
++ SH_PFC_PIN_GROUP(qspi1_data2),
++ SH_PFC_PIN_GROUP(qspi1_data4),
+ SH_PFC_PIN_GROUP(scif0_data),
+ SH_PFC_PIN_GROUP(scif0_clk),
+ SH_PFC_PIN_GROUP(scif0_ctrl),
+@@ -2316,6 +2372,18 @@ static const char * const pwm4_groups[] = {
+ "pwm4_b",
+ };
+
++static const char * const qspi0_groups[] = {
++ "qspi0_ctrl",
++ "qspi0_data2",
++ "qspi0_data4",
++};
++
++static const char * const qspi1_groups[] = {
++ "qspi1_ctrl",
++ "qspi1_data2",
++ "qspi1_data4",
++};
++
+ static const char * const scif0_groups[] = {
+ "scif0_data",
+ "scif0_clk",
+@@ -2412,6 +2480,8 @@ static const struct sh_pfc_function pinmux_functions[] = {
+ SH_PFC_FUNCTION(pwm2),
+ SH_PFC_FUNCTION(pwm3),
+ SH_PFC_FUNCTION(pwm4),
++ SH_PFC_FUNCTION(qspi0),
++ SH_PFC_FUNCTION(qspi1),
+ SH_PFC_FUNCTION(scif0),
+ SH_PFC_FUNCTION(scif1),
+ SH_PFC_FUNCTION(scif3),
+--
+2.7.4
+
diff --git a/bsp/meta-rcar/meta-rcar-gen3-adas/recipes-kernel/linux/linux-renesas/0251-media-rcar-rcar-csi2-Update-V3M-E3-PHTW-tables.patch b/bsp/meta-rcar/meta-rcar-gen3-adas/recipes-kernel/linux/linux-renesas/0251-media-rcar-rcar-csi2-Update-V3M-E3-PHTW-tables.patch
new file mode 100644
index 00000000..3ea4c31f
--- /dev/null
+++ b/bsp/meta-rcar/meta-rcar-gen3-adas/recipes-kernel/linux/linux-renesas/0251-media-rcar-rcar-csi2-Update-V3M-E3-PHTW-tables.patch
@@ -0,0 +1,94 @@
+From edadae825e47850cdfeb8fe8c31dbf795a33ec8a Mon Sep 17 00:00:00 2001
+From: Jacopo Mondi <jacopo+renesas@jmondi.org>
+Date: Tue, 6 Nov 2018 05:54:26 -0500
+Subject: [PATCH 071/211] media: rcar: rcar-csi2: Update V3M/E3 PHTW tables
+
+Update PHTW tables for V3M and E3 SoCs to the latest datasheet release
+(R-Car Series, 3rd Generation manual rev1.00 20181017).
+
+Signed-off-by: Jacopo Mondi <jacopo+renesas@jmondi.org>
+Reviewed-by: Laurent Pinchart <laurent.pinchart@ideasonboard.com>
+Signed-off-by: Hans Verkuil <hansverk@cisco.com>
+Signed-off-by: Mauro Carvalho Chehab <mchehab+samsung@kernel.org>
+(cherry picked from commit 10c08812fe60ddfd480730a58bb78616262d659a)
+Signed-off-by: Valentine Barshak <valentine.barshak@cogentembedded.com>
+---
+ drivers/media/platform/rcar-vin/rcar-csi2.c | 62 ++++++++++++++---------------
+ 1 file changed, 31 insertions(+), 31 deletions(-)
+
+diff --git a/drivers/media/platform/rcar-vin/rcar-csi2.c b/drivers/media/platform/rcar-vin/rcar-csi2.c
+index 7cb1365..52a6d52 100644
+--- a/drivers/media/platform/rcar-vin/rcar-csi2.c
++++ b/drivers/media/platform/rcar-vin/rcar-csi2.c
+@@ -156,37 +156,37 @@ static const struct rcsi2_mbps_reg phtw_mbps_h3_v3h_m3n[] = {
+ };
+
+ static const struct rcsi2_mbps_reg phtw_mbps_v3m_e3[] = {
+- { .mbps = 80, .reg = 0x00 },
+- { .mbps = 90, .reg = 0x20 },
+- { .mbps = 100, .reg = 0x40 },
+- { .mbps = 110, .reg = 0x02 },
+- { .mbps = 130, .reg = 0x22 },
+- { .mbps = 140, .reg = 0x42 },
+- { .mbps = 150, .reg = 0x04 },
+- { .mbps = 170, .reg = 0x24 },
+- { .mbps = 180, .reg = 0x44 },
+- { .mbps = 200, .reg = 0x06 },
+- { .mbps = 220, .reg = 0x26 },
+- { .mbps = 240, .reg = 0x46 },
+- { .mbps = 250, .reg = 0x08 },
+- { .mbps = 270, .reg = 0x28 },
+- { .mbps = 300, .reg = 0x0a },
+- { .mbps = 330, .reg = 0x2a },
+- { .mbps = 360, .reg = 0x4a },
+- { .mbps = 400, .reg = 0x0c },
+- { .mbps = 450, .reg = 0x2c },
+- { .mbps = 500, .reg = 0x0e },
+- { .mbps = 550, .reg = 0x2e },
+- { .mbps = 600, .reg = 0x10 },
+- { .mbps = 650, .reg = 0x30 },
+- { .mbps = 700, .reg = 0x12 },
+- { .mbps = 750, .reg = 0x32 },
+- { .mbps = 800, .reg = 0x52 },
+- { .mbps = 850, .reg = 0x72 },
+- { .mbps = 900, .reg = 0x14 },
+- { .mbps = 950, .reg = 0x34 },
+- { .mbps = 1000, .reg = 0x54 },
+- { .mbps = 1050, .reg = 0x74 },
++ { .mbps = 89, .reg = 0x00 },
++ { .mbps = 99, .reg = 0x20 },
++ { .mbps = 109, .reg = 0x40 },
++ { .mbps = 129, .reg = 0x02 },
++ { .mbps = 139, .reg = 0x22 },
++ { .mbps = 149, .reg = 0x42 },
++ { .mbps = 169, .reg = 0x04 },
++ { .mbps = 179, .reg = 0x24 },
++ { .mbps = 199, .reg = 0x44 },
++ { .mbps = 219, .reg = 0x06 },
++ { .mbps = 239, .reg = 0x26 },
++ { .mbps = 249, .reg = 0x46 },
++ { .mbps = 269, .reg = 0x08 },
++ { .mbps = 299, .reg = 0x28 },
++ { .mbps = 329, .reg = 0x0a },
++ { .mbps = 359, .reg = 0x2a },
++ { .mbps = 399, .reg = 0x4a },
++ { .mbps = 449, .reg = 0x0c },
++ { .mbps = 499, .reg = 0x2c },
++ { .mbps = 549, .reg = 0x0e },
++ { .mbps = 599, .reg = 0x2e },
++ { .mbps = 649, .reg = 0x10 },
++ { .mbps = 699, .reg = 0x30 },
++ { .mbps = 749, .reg = 0x12 },
++ { .mbps = 799, .reg = 0x32 },
++ { .mbps = 849, .reg = 0x52 },
++ { .mbps = 899, .reg = 0x72 },
++ { .mbps = 949, .reg = 0x14 },
++ { .mbps = 999, .reg = 0x34 },
++ { .mbps = 1049, .reg = 0x54 },
++ { .mbps = 1099, .reg = 0x74 },
+ { .mbps = 1125, .reg = 0x16 },
+ { /* sentinel */ },
+ };
+--
+2.7.4
+
diff --git a/bsp/meta-rcar/meta-rcar-gen3-adas/recipes-kernel/linux/linux-renesas/0252-soc-renesas-r8a77970-sysc-Remove-non-existent-CR7-po.patch b/bsp/meta-rcar/meta-rcar-gen3-adas/recipes-kernel/linux/linux-renesas/0252-soc-renesas-r8a77970-sysc-Remove-non-existent-CR7-po.patch
new file mode 100644
index 00000000..f758b41d
--- /dev/null
+++ b/bsp/meta-rcar/meta-rcar-gen3-adas/recipes-kernel/linux/linux-renesas/0252-soc-renesas-r8a77970-sysc-Remove-non-existent-CR7-po.patch
@@ -0,0 +1,50 @@
+From 03b06b8d0210a6fd5f417515eb40af24c2a60878 Mon Sep 17 00:00:00 2001
+From: Geert Uytterhoeven <geert+renesas@glider.be>
+Date: Thu, 29 Nov 2018 11:56:15 +0100
+Subject: [PATCH 072/211] soc: renesas: r8a77970-sysc: Remove non-existent CR7
+ power domain
+
+The R-Car Gen3 HardWare Manual Errata for Rev. 0.80 (Feb 28, 2018)
+removed the CR7 power domain on R-Car V3M, as this SoC does not have an
+ARM Cortex-R7 Realtime Core.
+
+As this definition was never used from DT, it can just be removed.
+
+Fixes: 833bdb47c826a1a6 ("dt-bindings: power: add R8A77970 SYSC power domain definitions")
+Fixes: bab9b2a74fe9da96 ("soc: renesas: rcar-sysc: add R8A77970 support")
+Signed-off-by: Geert Uytterhoeven <geert+renesas@glider.be>
+Signed-off-by: Simon Horman <horms+renesas@verge.net.au>
+(cherry picked from commit da3e1c57caf93ed379f14686e877f806111abe7c)
+Signed-off-by: Valentine Barshak <valentine.barshak@cogentembedded.com>
+---
+ drivers/soc/renesas/r8a77970-sysc.c | 1 -
+ include/dt-bindings/power/r8a77970-sysc.h | 1 -
+ 2 files changed, 2 deletions(-)
+
+diff --git a/drivers/soc/renesas/r8a77970-sysc.c b/drivers/soc/renesas/r8a77970-sysc.c
+index a6ce15d..bd0263f 100644
+--- a/drivers/soc/renesas/r8a77970-sysc.c
++++ b/drivers/soc/renesas/r8a77970-sysc.c
+@@ -24,7 +24,6 @@ static const struct rcar_sysc_area r8a77970_areas[] __initconst = {
+ PD_CPU_NOCR },
+ { "ca53-cpu1", 0x200, 1, R8A77970_PD_CA53_CPU1, R8A77970_PD_CA53_SCU,
+ PD_CPU_NOCR },
+- { "cr7", 0x240, 0, R8A77970_PD_CR7, R8A77970_PD_ALWAYS_ON },
+ { "a3ir", 0x180, 0, R8A77970_PD_A3IR, R8A77970_PD_ALWAYS_ON },
+ { "a2ir0", 0x400, 0, R8A77970_PD_A2IR0, R8A77970_PD_A3IR },
+ { "a2ir1", 0x400, 1, R8A77970_PD_A2IR1, R8A77970_PD_A3IR },
+diff --git a/include/dt-bindings/power/r8a77970-sysc.h b/include/dt-bindings/power/r8a77970-sysc.h
+index bf54779..5c1ef13 100644
+--- a/include/dt-bindings/power/r8a77970-sysc.h
++++ b/include/dt-bindings/power/r8a77970-sysc.h
+@@ -16,7 +16,6 @@
+
+ #define R8A77970_PD_CA53_CPU0 5
+ #define R8A77970_PD_CA53_CPU1 6
+-#define R8A77970_PD_CR7 13
+ #define R8A77970_PD_CA53_SCU 21
+ #define R8A77970_PD_A2IR0 23
+ #define R8A77970_PD_A3IR 24
+--
+2.7.4
+
diff --git a/bsp/meta-rcar/meta-rcar-gen3-adas/recipes-kernel/linux/linux-renesas/0253-soc-renesas-r8a77970-sysc-Correct-names-of-A2DP-A2CN.patch b/bsp/meta-rcar/meta-rcar-gen3-adas/recipes-kernel/linux/linux-renesas/0253-soc-renesas-r8a77970-sysc-Correct-names-of-A2DP-A2CN.patch
new file mode 100644
index 00000000..1258d2b5
--- /dev/null
+++ b/bsp/meta-rcar/meta-rcar-gen3-adas/recipes-kernel/linux/linux-renesas/0253-soc-renesas-r8a77970-sysc-Correct-names-of-A2DP-A2CN.patch
@@ -0,0 +1,61 @@
+From d55cfce2c5247cef7e9b53a0552034d247a645c7 Mon Sep 17 00:00:00 2001
+From: Geert Uytterhoeven <geert+renesas@glider.be>
+Date: Thu, 29 Nov 2018 11:56:16 +0100
+Subject: [PATCH 073/211] soc: renesas: r8a77970-sysc: Correct names of
+ A2DP/A2CN power domains
+
+The R-Car Gen3 HardWare Manual Errata for Rev. 0.80 (Feb 28, 2018)
+renamed the A2IR2 and A2IR3 power domains on R-Car V3M to A2DP resp.
+A2CN.
+
+As these definitions are not yet used from DT, they can just be renamed.
+
+While at it, fix the indentation of the A3IR definition.
+
+Fixes: 833bdb47c826a1a6 ("dt-bindings: power: add R8A77970 SYSC power domain definitions")
+Fixes: bab9b2a74fe9da96 ("soc: renesas: rcar-sysc: add R8A77970 support")
+Signed-off-by: Geert Uytterhoeven <geert+renesas@glider.be>
+Signed-off-by: Simon Horman <horms+renesas@verge.net.au>
+(cherry picked from commit b5eb730e031acaba2d25e8f522ac5966a70885ae)
+Signed-off-by: Valentine Barshak <valentine.barshak@cogentembedded.com>
+---
+ drivers/soc/renesas/r8a77970-sysc.c | 4 ++--
+ include/dt-bindings/power/r8a77970-sysc.h | 6 +++---
+ 2 files changed, 5 insertions(+), 5 deletions(-)
+
+diff --git a/drivers/soc/renesas/r8a77970-sysc.c b/drivers/soc/renesas/r8a77970-sysc.c
+index bd0263f..e2c05c3 100644
+--- a/drivers/soc/renesas/r8a77970-sysc.c
++++ b/drivers/soc/renesas/r8a77970-sysc.c
+@@ -27,8 +27,8 @@ static const struct rcar_sysc_area r8a77970_areas[] __initconst = {
+ { "a3ir", 0x180, 0, R8A77970_PD_A3IR, R8A77970_PD_ALWAYS_ON },
+ { "a2ir0", 0x400, 0, R8A77970_PD_A2IR0, R8A77970_PD_A3IR },
+ { "a2ir1", 0x400, 1, R8A77970_PD_A2IR1, R8A77970_PD_A3IR },
+- { "a2ir2", 0x400, 2, R8A77970_PD_A2IR2, R8A77970_PD_A3IR },
+- { "a2ir3", 0x400, 3, R8A77970_PD_A2IR3, R8A77970_PD_A3IR },
++ { "a2dp", 0x400, 2, R8A77970_PD_A2DP, R8A77970_PD_A3IR },
++ { "a2cn", 0x400, 3, R8A77970_PD_A2CN, R8A77970_PD_A3IR },
+ { "a2sc0", 0x400, 4, R8A77970_PD_A2SC0, R8A77970_PD_A3IR },
+ { "a2sc1", 0x400, 5, R8A77970_PD_A2SC1, R8A77970_PD_A3IR },
+ };
+diff --git a/include/dt-bindings/power/r8a77970-sysc.h b/include/dt-bindings/power/r8a77970-sysc.h
+index 5c1ef13..85cc5f2 100644
+--- a/include/dt-bindings/power/r8a77970-sysc.h
++++ b/include/dt-bindings/power/r8a77970-sysc.h
+@@ -18,10 +18,10 @@
+ #define R8A77970_PD_CA53_CPU1 6
+ #define R8A77970_PD_CA53_SCU 21
+ #define R8A77970_PD_A2IR0 23
+-#define R8A77970_PD_A3IR 24
++#define R8A77970_PD_A3IR 24
+ #define R8A77970_PD_A2IR1 27
+-#define R8A77970_PD_A2IR2 28
+-#define R8A77970_PD_A2IR3 29
++#define R8A77970_PD_A2DP 28
++#define R8A77970_PD_A2CN 29
+ #define R8A77970_PD_A2SC0 30
+ #define R8A77970_PD_A2SC1 31
+
+--
+2.7.4
+
diff --git a/bsp/meta-rcar/meta-rcar-gen3-adas/recipes-kernel/linux/linux-renesas/0254-soc-renesas-r8a77980-sysc-Correct-names-of-A2DP-01-p.patch b/bsp/meta-rcar/meta-rcar-gen3-adas/recipes-kernel/linux/linux-renesas/0254-soc-renesas-r8a77980-sysc-Correct-names-of-A2DP-01-p.patch
new file mode 100644
index 00000000..c9628dd7
--- /dev/null
+++ b/bsp/meta-rcar/meta-rcar-gen3-adas/recipes-kernel/linux/linux-renesas/0254-soc-renesas-r8a77980-sysc-Correct-names-of-A2DP-01-p.patch
@@ -0,0 +1,56 @@
+From f7f151d46fd48005b16db98a00d38c83b9792c3d Mon Sep 17 00:00:00 2001
+From: Geert Uytterhoeven <geert+renesas@glider.be>
+Date: Thu, 29 Nov 2018 11:56:17 +0100
+Subject: [PATCH 074/211] soc: renesas: r8a77980-sysc: Correct names of
+ A2DP[01] power domains
+
+The R-Car Gen3 HardWare Manual Errata for Rev. 0.80 (Feb 28, 2018)
+renamed the A2PD0 and A2DP0 power domains on R-Car V3H to A2DP0 resp.
+A2DP1.
+
+As these definitions are not yet used from DT, they can just be renamed.
+
+Fixes: 7755b40d07a8dba7 ("dt-bindings: power: add R8A77980 SYSC power domain definitions")
+Fixes: 41d6d8bd8ae94ca9 ("soc: renesas: rcar-sysc: add R8A77980 support")
+Signed-off-by: Geert Uytterhoeven <geert+renesas@glider.be>
+Signed-off-by: Simon Horman <horms+renesas@verge.net.au>
+(cherry picked from commit 97473bc85b22ac610b1810b6a9a4669a6cb0b7b0)
+Signed-off-by: Valentine Barshak <valentine.barshak@cogentembedded.com>
+---
+ drivers/soc/renesas/r8a77980-sysc.c | 4 ++--
+ include/dt-bindings/power/r8a77980-sysc.h | 4 ++--
+ 2 files changed, 4 insertions(+), 4 deletions(-)
+
+diff --git a/drivers/soc/renesas/r8a77980-sysc.c b/drivers/soc/renesas/r8a77980-sysc.c
+index 9265fb5..dbb2621 100644
+--- a/drivers/soc/renesas/r8a77980-sysc.c
++++ b/drivers/soc/renesas/r8a77980-sysc.c
+@@ -38,8 +38,8 @@ static const struct rcar_sysc_area r8a77980_areas[] __initconst = {
+ { "a2sc2", 0x400, 8, R8A77980_PD_A2SC2, R8A77980_PD_A3IR },
+ { "a2sc3", 0x400, 9, R8A77980_PD_A2SC3, R8A77980_PD_A3IR },
+ { "a2sc4", 0x400, 10, R8A77980_PD_A2SC4, R8A77980_PD_A3IR },
+- { "a2pd0", 0x400, 11, R8A77980_PD_A2PD0, R8A77980_PD_A3IR },
+- { "a2pd1", 0x400, 12, R8A77980_PD_A2PD1, R8A77980_PD_A3IR },
++ { "a2dp0", 0x400, 11, R8A77980_PD_A2DP0, R8A77980_PD_A3IR },
++ { "a2dp1", 0x400, 12, R8A77980_PD_A2DP1, R8A77980_PD_A3IR },
+ { "a2cn", 0x400, 13, R8A77980_PD_A2CN, R8A77980_PD_A3IR },
+ { "a3vip", 0x2c0, 0, R8A77980_PD_A3VIP, R8A77980_PD_ALWAYS_ON },
+ { "a3vip1", 0x300, 0, R8A77980_PD_A3VIP1, R8A77980_PD_A3VIP },
+diff --git a/include/dt-bindings/power/r8a77980-sysc.h b/include/dt-bindings/power/r8a77980-sysc.h
+index 2c90c12..7bebe7e 100644
+--- a/include/dt-bindings/power/r8a77980-sysc.h
++++ b/include/dt-bindings/power/r8a77980-sysc.h
+@@ -15,8 +15,8 @@
+ #define R8A77980_PD_A2SC2 0
+ #define R8A77980_PD_A2SC3 1
+ #define R8A77980_PD_A2SC4 2
+-#define R8A77980_PD_A2PD0 3
+-#define R8A77980_PD_A2PD1 4
++#define R8A77980_PD_A2DP0 3
++#define R8A77980_PD_A2DP1 4
+ #define R8A77980_PD_CA53_CPU0 5
+ #define R8A77980_PD_CA53_CPU1 6
+ #define R8A77980_PD_CA53_CPU2 7
+--
+2.7.4
+
diff --git a/bsp/meta-rcar/meta-rcar-gen3-adas/recipes-kernel/linux/linux-renesas/0255-soc-renesas-r8a77980-sysc-Correct-A3VIP-012-power-do.patch b/bsp/meta-rcar/meta-rcar-gen3-adas/recipes-kernel/linux/linux-renesas/0255-soc-renesas-r8a77980-sysc-Correct-A3VIP-012-power-do.patch
new file mode 100644
index 00000000..6a793247
--- /dev/null
+++ b/bsp/meta-rcar/meta-rcar-gen3-adas/recipes-kernel/linux/linux-renesas/0255-soc-renesas-r8a77980-sysc-Correct-A3VIP-012-power-do.patch
@@ -0,0 +1,57 @@
+From bd93251ce884a70ef9596b078886417a9d47dd8c Mon Sep 17 00:00:00 2001
+From: Geert Uytterhoeven <geert+renesas@glider.be>
+Date: Thu, 29 Nov 2018 11:56:18 +0100
+Subject: [PATCH 075/211] soc: renesas: r8a77980-sysc: Correct A3VIP[012] power
+ domain hierarchy
+
+The R-Car Gen3 HardWare Manual Errata for Rev. 0.80 (Feb 28, 2018)
+renamed the A3VIP power domain on R-Car V3H to A3VIP0, and clarified the
+power domain hierarchy for the A3VIP[012] power domains.
+
+As the definition for the A3VIP0 domain is not yet used from DT, it can
+just be renamed.
+
+Fixes: 7755b40d07a8dba7 ("dt-bindings: power: add R8A77980 SYSC power domain definitions")
+Fixes: 41d6d8bd8ae94ca9 ("soc: renesas: rcar-sysc: add R8A77980 support")
+Signed-off-by: Geert Uytterhoeven <geert+renesas@glider.be>
+Signed-off-by: Simon Horman <horms+renesas@verge.net.au>
+(cherry picked from commit 160bfa7c724b348a90a12dd9694f351927a15b8e)
+Signed-off-by: Valentine Barshak <valentine.barshak@cogentembedded.com>
+---
+ drivers/soc/renesas/r8a77980-sysc.c | 6 +++---
+ include/dt-bindings/power/r8a77980-sysc.h | 2 +-
+ 2 files changed, 4 insertions(+), 4 deletions(-)
+
+diff --git a/drivers/soc/renesas/r8a77980-sysc.c b/drivers/soc/renesas/r8a77980-sysc.c
+index dbb2621..a8dbe55 100644
+--- a/drivers/soc/renesas/r8a77980-sysc.c
++++ b/drivers/soc/renesas/r8a77980-sysc.c
+@@ -41,9 +41,9 @@ static const struct rcar_sysc_area r8a77980_areas[] __initconst = {
+ { "a2dp0", 0x400, 11, R8A77980_PD_A2DP0, R8A77980_PD_A3IR },
+ { "a2dp1", 0x400, 12, R8A77980_PD_A2DP1, R8A77980_PD_A3IR },
+ { "a2cn", 0x400, 13, R8A77980_PD_A2CN, R8A77980_PD_A3IR },
+- { "a3vip", 0x2c0, 0, R8A77980_PD_A3VIP, R8A77980_PD_ALWAYS_ON },
+- { "a3vip1", 0x300, 0, R8A77980_PD_A3VIP1, R8A77980_PD_A3VIP },
+- { "a3vip2", 0x280, 0, R8A77980_PD_A3VIP2, R8A77980_PD_A3VIP },
++ { "a3vip0", 0x2c0, 0, R8A77980_PD_A3VIP0, R8A77980_PD_ALWAYS_ON },
++ { "a3vip1", 0x300, 0, R8A77980_PD_A3VIP1, R8A77980_PD_ALWAYS_ON },
++ { "a3vip2", 0x280, 0, R8A77980_PD_A3VIP2, R8A77980_PD_ALWAYS_ON },
+ };
+
+ const struct rcar_sysc_info r8a77980_sysc_info __initconst = {
+diff --git a/include/dt-bindings/power/r8a77980-sysc.h b/include/dt-bindings/power/r8a77980-sysc.h
+index 7bebe7e..e12c858 100644
+--- a/include/dt-bindings/power/r8a77980-sysc.h
++++ b/include/dt-bindings/power/r8a77980-sysc.h
+@@ -22,7 +22,7 @@
+ #define R8A77980_PD_CA53_CPU2 7
+ #define R8A77980_PD_CA53_CPU3 8
+ #define R8A77980_PD_A2CN 10
+-#define R8A77980_PD_A3VIP 11
++#define R8A77980_PD_A3VIP0 11
+ #define R8A77980_PD_A2IR5 12
+ #define R8A77980_PD_CR7 13
+ #define R8A77980_PD_A2IR4 15
+--
+2.7.4
+
diff --git a/bsp/meta-rcar/meta-rcar-gen3-adas/recipes-kernel/linux/linux-renesas/0256-clk-renesas-r8a77970-Add-CPEX-clock.patch b/bsp/meta-rcar/meta-rcar-gen3-adas/recipes-kernel/linux/linux-renesas/0256-clk-renesas-r8a77970-Add-CPEX-clock.patch
new file mode 100644
index 00000000..188b77a7
--- /dev/null
+++ b/bsp/meta-rcar/meta-rcar-gen3-adas/recipes-kernel/linux/linux-renesas/0256-clk-renesas-r8a77970-Add-CPEX-clock.patch
@@ -0,0 +1,31 @@
+From 3674769e16cf1368462cb8e57d111a0937c4d329 Mon Sep 17 00:00:00 2001
+From: Geert Uytterhoeven <geert+renesas@glider.be>
+Date: Wed, 21 Nov 2018 10:44:32 +0100
+Subject: [PATCH 076/211] clk: renesas: r8a77970: Add CPEX clock
+
+Implement support for the CPEX clock on R-Car V3M. This clock can be
+selected as a clock source for CMT1 (Compare Match Timer Type 1).
+
+Signed-off-by: Geert Uytterhoeven <geert+renesas@glider.be>
+Acked-by: Stephen Boyd <sboyd@kernel.org>
+(cherry picked from commit 396bc9d40d694befa1c2c88f9873afc62a189b5f)
+Signed-off-by: Valentine Barshak <valentine.barshak@cogentembedded.com>
+---
+ drivers/clk/renesas/r8a77970-cpg-mssr.c | 1 +
+ 1 file changed, 1 insertion(+)
+
+diff --git a/drivers/clk/renesas/r8a77970-cpg-mssr.c b/drivers/clk/renesas/r8a77970-cpg-mssr.c
+index 6885c62..cbac67e 100644
+--- a/drivers/clk/renesas/r8a77970-cpg-mssr.c
++++ b/drivers/clk/renesas/r8a77970-cpg-mssr.c
+@@ -99,6 +99,7 @@ static const struct cpg_core_clk r8a77970_core_clks[] __initconst = {
+
+ DEF_FIXED("cl", R8A77970_CLK_CL, CLK_PLL1_DIV2, 48, 1),
+ DEF_FIXED("cp", R8A77970_CLK_CP, CLK_EXTAL, 2, 1),
++ DEF_FIXED("cpex", R8A77970_CLK_CPEX, CLK_EXTAL, 2, 1),
+
+ DEF_DIV6P1("canfd", R8A77970_CLK_CANFD, CLK_PLL1_DIV4, 0x244),
+ DEF_DIV6P1("mso", R8A77970_CLK_MSO, CLK_PLL1_DIV4, 0x014),
+--
+2.7.4
+
diff --git a/bsp/meta-rcar/meta-rcar-gen3-adas/recipes-kernel/linux/linux-renesas/0257-media-rcar-csi2-add-R8A77980-support.patch b/bsp/meta-rcar/meta-rcar-gen3-adas/recipes-kernel/linux/linux-renesas/0257-media-rcar-csi2-add-R8A77980-support.patch
new file mode 100644
index 00000000..99530c73
--- /dev/null
+++ b/bsp/meta-rcar/meta-rcar-gen3-adas/recipes-kernel/linux/linux-renesas/0257-media-rcar-csi2-add-R8A77980-support.patch
@@ -0,0 +1,62 @@
+From 23b44555c526c046bd1ce117c6ea19f20ba6e57c Mon Sep 17 00:00:00 2001
+From: Sergei Shtylyov <sergei.shtylyov@cogentembedded.com>
+Date: Mon, 6 Aug 2018 12:56:27 -0400
+Subject: [PATCH 077/211] media: rcar-csi2: add R8A77980 support
+
+Add the R-Car V3H (AKA R8A77980) SoC support to the R-Car CSI2 driver.
+
+Signed-off-by: Sergei Shtylyov <sergei.shtylyov@cogentembedded.com>
+Acked-by: Rob Herring <robh@kernel.org>
+Signed-off-by: Hans Verkuil <hverkuil-cisco@xs4all.nl>
+Signed-off-by: Mauro Carvalho Chehab <mchehab+samsung@kernel.org>
+(cherry picked from commit 3ba37c2bcb0cb5dc9b278f730e520f61b2597fe3)
+Signed-off-by: Valentine Barshak <valentine.barshak@cogentembedded.com>
+---
+ Documentation/devicetree/bindings/media/renesas,rcar-csi2.txt | 1 +
+ drivers/media/platform/rcar-vin/rcar-csi2.c | 11 +++++++++++
+ 2 files changed, 12 insertions(+)
+
+diff --git a/Documentation/devicetree/bindings/media/renesas,rcar-csi2.txt b/Documentation/devicetree/bindings/media/renesas,rcar-csi2.txt
+index 2824489..541d936 100644
+--- a/Documentation/devicetree/bindings/media/renesas,rcar-csi2.txt
++++ b/Documentation/devicetree/bindings/media/renesas,rcar-csi2.txt
+@@ -12,6 +12,7 @@ Mandatory properties
+ - "renesas,r8a7796-csi2" for the R8A7796 device.
+ - "renesas,r8a77965-csi2" for the R8A77965 device.
+ - "renesas,r8a77970-csi2" for the R8A77970 device.
++ - "renesas,r8a77980-csi2" for the R8A77980 device.
+ - "renesas,r8a77990-csi2" for the R8A77990 device.
+
+ - reg: the register base and size for the device registers
+diff --git a/drivers/media/platform/rcar-vin/rcar-csi2.c b/drivers/media/platform/rcar-vin/rcar-csi2.c
+index 52a6d52..c21cc80 100644
+--- a/drivers/media/platform/rcar-vin/rcar-csi2.c
++++ b/drivers/media/platform/rcar-vin/rcar-csi2.c
+@@ -1037,6 +1037,13 @@ static const struct rcar_csi2_info rcar_csi2_info_r8a77970 = {
+ .init_v3m_e3_phtw = rcsi2_init_phtw_v3m_e3,
+ };
+
++static const struct rcar_csi2_info rcar_csi2_info_r8a77980 = {
++ .init_phtw = rcsi2_init_phtw_h3_v3h_m3n,
++ .hsfreqrange = hsfreqrange_h3_v3h_m3n,
++ .csi0clkfreqrange = 0x20,
++ .clear_ulps = true,
++};
++
+ static const struct rcar_csi2_info rcar_csi2_info_r8a77990 = {
+ .init_v3m_e3_phtw = rcsi2_init_phtw_v3m_e3,
+ };
+@@ -1059,6 +1066,10 @@ static const struct of_device_id rcar_csi2_of_table[] = {
+ .data = &rcar_csi2_info_r8a77970,
+ },
+ {
++ .compatible = "renesas,r8a77980-csi2",
++ .data = &rcar_csi2_info_r8a77980,
++ },
++ {
+ .compatible = "renesas,r8a77990-csi2",
+ .data = &rcar_csi2_info_r8a77990,
+ },
+--
+2.7.4
+
diff --git a/bsp/meta-rcar/meta-rcar-gen3-adas/recipes-kernel/linux/linux-renesas/0258-media-rcar-vin-add-R8A77980-support.patch b/bsp/meta-rcar/meta-rcar-gen3-adas/recipes-kernel/linux/linux-renesas/0258-media-rcar-vin-add-R8A77980-support.patch
new file mode 100644
index 00000000..0e351ed0
--- /dev/null
+++ b/bsp/meta-rcar/meta-rcar-gen3-adas/recipes-kernel/linux/linux-renesas/0258-media-rcar-vin-add-R8A77980-support.patch
@@ -0,0 +1,87 @@
+From 2c14590a9c414df1a74e96f4baa2ef8cd2005ae4 Mon Sep 17 00:00:00 2001
+From: Sergei Shtylyov <sergei.shtylyov@cogentembedded.com>
+Date: Mon, 6 Aug 2018 14:48:20 -0400
+Subject: [PATCH 078/211] media: rcar-vin: add R8A77980 support
+MIME-Version: 1.0
+Content-Type: text/plain; charset=UTF-8
+Content-Transfer-Encoding: 8bit
+
+Add the R8A77980 SoC support to the R-Car VIN driver.
+
+Signed-off-by: Sergei Shtylyov <sergei.shtylyov@cogentembedded.com>
+Acked-by: Niklas Söderlund <niklas.soderlund+renesas@ragnatech.se>
+Signed-off-by: Hans Verkuil <hverkuil-cisco@xs4all.nl>
+Signed-off-by: Mauro Carvalho Chehab <mchehab+samsung@kernel.org>
+(cherry picked from commit a383096c98b4b44151a9fde106b01500ccc2a060)
+[valentine.barshak: resolved minor conflicts in rcar_vin binding docs]
+Signed-off-by: Valentine Barshak <valentine.barshak@cogentembedded.com>
+---
+ .../devicetree/bindings/media/rcar_vin.txt | 1 +
+ drivers/media/platform/rcar-vin/rcar-core.c | 32 ++++++++++++++++++++++
+ 2 files changed, 33 insertions(+)
+
+diff --git a/Documentation/devicetree/bindings/media/rcar_vin.txt b/Documentation/devicetree/bindings/media/rcar_vin.txt
+index 845c786..bcd2e3a 100644
+--- a/Documentation/devicetree/bindings/media/rcar_vin.txt
++++ b/Documentation/devicetree/bindings/media/rcar_vin.txt
+@@ -23,6 +23,7 @@ on Gen3 platforms to a CSI-2 receiver.
+ - "renesas,vin-r8a7796" for the R8A7796 device
+ - "renesas,vin-r8a77970" for the R8A77970 device
+ - "renesas,vin-r8a77965" for the R8A77965 device
++ - "renesas,vin-r8a77980" for the R8A77980 device
+ - "renesas,vin-r8a77990" for the R8A77990 device
+ - "renesas,vin-r8a77995" for the R8A77995 device
+ - "renesas,rcar-gen2-vin" for a generic R-Car Gen2 or RZ/G1 compatible
+diff --git a/drivers/media/platform/rcar-vin/rcar-core.c b/drivers/media/platform/rcar-vin/rcar-core.c
+index d6f99db..adb4ac1 100644
+--- a/drivers/media/platform/rcar-vin/rcar-core.c
++++ b/drivers/media/platform/rcar-vin/rcar-core.c
+@@ -1055,6 +1055,34 @@ static const struct rvin_info rcar_info_r8a77965 = {
+ .routes = _rcar_info_r8a77965_routes,
+ };
+
++static const struct rvin_group_route rcar_info_r8a77980_routes[] = {
++ { .csi = RVIN_CSI40, .channel = 0, .vin = 0, .mask = BIT(0) | BIT(3) },
++ { .csi = RVIN_CSI40, .channel = 1, .vin = 0, .mask = BIT(2) },
++ { .csi = RVIN_CSI40, .channel = 0, .vin = 1, .mask = BIT(2) },
++ { .csi = RVIN_CSI40, .channel = 1, .vin = 1, .mask = BIT(1) | BIT(3) },
++ { .csi = RVIN_CSI40, .channel = 0, .vin = 2, .mask = BIT(1) },
++ { .csi = RVIN_CSI40, .channel = 2, .vin = 2, .mask = BIT(3) },
++ { .csi = RVIN_CSI40, .channel = 1, .vin = 3, .mask = BIT(0) },
++ { .csi = RVIN_CSI40, .channel = 3, .vin = 3, .mask = BIT(3) },
++ { .csi = RVIN_CSI41, .channel = 0, .vin = 4, .mask = BIT(0) | BIT(3) },
++ { .csi = RVIN_CSI41, .channel = 1, .vin = 4, .mask = BIT(2) },
++ { .csi = RVIN_CSI41, .channel = 0, .vin = 5, .mask = BIT(2) },
++ { .csi = RVIN_CSI41, .channel = 1, .vin = 5, .mask = BIT(1) | BIT(3) },
++ { .csi = RVIN_CSI41, .channel = 0, .vin = 6, .mask = BIT(1) },
++ { .csi = RVIN_CSI41, .channel = 2, .vin = 6, .mask = BIT(3) },
++ { .csi = RVIN_CSI41, .channel = 1, .vin = 7, .mask = BIT(0) },
++ { .csi = RVIN_CSI41, .channel = 3, .vin = 7, .mask = BIT(3) },
++ { /* Sentinel */ }
++};
++
++static const struct rvin_info rcar_info_r8a77980 = {
++ .model = RCAR_GEN3,
++ .use_mc = true,
++ .max_width = 4096,
++ .max_height = 4096,
++ .routes = rcar_info_r8a77980_routes,
++};
++
+ static const struct rvin_group_route rcar_info_r8a77990_routes[] = {
+ { .csi = RVIN_CSI40, .channel = 0, .vin = 4, .mask = BIT(0) | BIT(3) },
+ { .csi = RVIN_CSI40, .channel = 0, .vin = 5, .mask = BIT(2) },
+@@ -1148,6 +1176,10 @@ static const struct of_device_id rvin_of_id_table[] = {
+ .data = &rcar_info_r8a77970,
+ },
+ {
++ .compatible = "renesas,vin-r8a77980",
++ .data = &rcar_info_r8a77980,
++ },
++ {
+ .compatible = "renesas,vin-r8a77990",
+ .data = &rcar_info_r8a77990,
+ },
+--
+2.7.4
+
diff --git a/bsp/meta-rcar/meta-rcar-gen3-adas/recipes-kernel/linux/linux-renesas/0259-pinctrl-sh-pfc-r8a77970-Add-missing-MOD_SEL0-field.patch b/bsp/meta-rcar/meta-rcar-gen3-adas/recipes-kernel/linux/linux-renesas/0259-pinctrl-sh-pfc-r8a77970-Add-missing-MOD_SEL0-field.patch
new file mode 100644
index 00000000..4539d3de
--- /dev/null
+++ b/bsp/meta-rcar/meta-rcar-gen3-adas/recipes-kernel/linux/linux-renesas/0259-pinctrl-sh-pfc-r8a77970-Add-missing-MOD_SEL0-field.patch
@@ -0,0 +1,34 @@
+From e5217975e934d8f241c30df1cbda960d6378812a Mon Sep 17 00:00:00 2001
+From: Geert Uytterhoeven <geert+renesas@glider.be>
+Date: Wed, 12 Dec 2018 14:29:02 +0100
+Subject: [PATCH 079/211] pinctrl: sh-pfc: r8a77970: Add missing MOD_SEL0 field
+
+The Module Select Register 0 contains 20 (= 5 x 4) reserved bits, and 12
+single-bit fields, but the variable field descriptor lacks a field of 4
+reserved bits.
+
+Fixes: b92ac66a1819602b ("pinctrl: sh-pfc: Add R8A77970 PFC support")
+Signed-off-by: Geert Uytterhoeven <geert+renesas@glider.be>
+Reviewed-by: Simon Horman <horms+renesas@verge.net.au>
+(cherry picked from commit 67d7745bc78e16ec6b3af02bc1da6c8c868cbd89)
+Signed-off-by: Valentine Barshak <valentine.barshak@cogentembedded.com>
+---
+ drivers/pinctrl/sh-pfc/pfc-r8a77970.c | 2 +-
+ 1 file changed, 1 insertion(+), 1 deletion(-)
+
+diff --git a/drivers/pinctrl/sh-pfc/pfc-r8a77970.c b/drivers/pinctrl/sh-pfc/pfc-r8a77970.c
+index 9b96e5d..e331e93 100644
+--- a/drivers/pinctrl/sh-pfc/pfc-r8a77970.c
++++ b/drivers/pinctrl/sh-pfc/pfc-r8a77970.c
+@@ -2424,7 +2424,7 @@ static const struct pinmux_cfg_reg pinmux_config_regs[] = {
+ #define F_(x, y) x,
+ #define FM(x) FN_##x,
+ { PINMUX_CFG_REG_VAR("MOD_SEL0", 0xe6060500, 32,
+- 4, 4, 4, 4,
++ 4, 4, 4, 4, 4,
+ 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1) {
+ /* RESERVED 31, 30, 29, 28 */
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+--
+2.7.4
+
diff --git a/bsp/meta-rcar/meta-rcar-gen3-adas/recipes-kernel/linux/linux-renesas/0260-pinctrl-sh-pfc-r8a77980-Add-missing-MOD_SEL0-field.patch b/bsp/meta-rcar/meta-rcar-gen3-adas/recipes-kernel/linux/linux-renesas/0260-pinctrl-sh-pfc-r8a77980-Add-missing-MOD_SEL0-field.patch
new file mode 100644
index 00000000..a9a77550
--- /dev/null
+++ b/bsp/meta-rcar/meta-rcar-gen3-adas/recipes-kernel/linux/linux-renesas/0260-pinctrl-sh-pfc-r8a77980-Add-missing-MOD_SEL0-field.patch
@@ -0,0 +1,34 @@
+From 64f86bb82bfff30da4106d0d8b1a684da42edced Mon Sep 17 00:00:00 2001
+From: Geert Uytterhoeven <geert+renesas@glider.be>
+Date: Wed, 12 Dec 2018 14:36:54 +0100
+Subject: [PATCH 080/211] pinctrl: sh-pfc: r8a77980: Add missing MOD_SEL0 field
+
+The Module Select Register 0 contains 20 (= 5 x 4) reserved bits, and 12
+single-bit fields, but the variable field descriptor lacks a field of 4
+reserved bits.
+
+Fixes: f59125248a691dfe ("pinctrl: sh-pfc: Add R8A77980 PFC support")
+Signed-off-by: Geert Uytterhoeven <geert+renesas@glider.be>
+Reviewed-by: Simon Horman <horms+renesas@verge.net.au>
+(cherry picked from commit b0f77269f6bba385f1f4dce44e7756cf8fbc0176)
+Signed-off-by: Valentine Barshak <valentine.barshak@cogentembedded.com>
+---
+ drivers/pinctrl/sh-pfc/pfc-r8a77980.c | 2 +-
+ 1 file changed, 1 insertion(+), 1 deletion(-)
+
+diff --git a/drivers/pinctrl/sh-pfc/pfc-r8a77980.c b/drivers/pinctrl/sh-pfc/pfc-r8a77980.c
+index aa1d50b..8bef245 100644
+--- a/drivers/pinctrl/sh-pfc/pfc-r8a77980.c
++++ b/drivers/pinctrl/sh-pfc/pfc-r8a77980.c
+@@ -2821,7 +2821,7 @@ static const struct pinmux_cfg_reg pinmux_config_regs[] = {
+ #define F_(x, y) x,
+ #define FM(x) FN_##x,
+ { PINMUX_CFG_REG_VAR("MOD_SEL0", 0xe6060500, 32,
+- 4, 4, 4, 4,
++ 4, 4, 4, 4, 4,
+ 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1) {
+ /* RESERVED 31, 30, 29, 28 */
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+--
+2.7.4
+
diff --git a/bsp/meta-rcar/meta-rcar-gen3-adas/recipes-kernel/linux/linux-renesas/0261-media-rcar-csi2-Fix-PHTW-table-values-for-E3-V3M.patch b/bsp/meta-rcar/meta-rcar-gen3-adas/recipes-kernel/linux/linux-renesas/0261-media-rcar-csi2-Fix-PHTW-table-values-for-E3-V3M.patch
new file mode 100644
index 00000000..943d7037
--- /dev/null
+++ b/bsp/meta-rcar/meta-rcar-gen3-adas/recipes-kernel/linux/linux-renesas/0261-media-rcar-csi2-Fix-PHTW-table-values-for-E3-V3M.patch
@@ -0,0 +1,99 @@
+From 0bd47cde3778ac16d6b9d90579d3f40e0c0716db Mon Sep 17 00:00:00 2001
+From: Jacopo Mondi <jacopo+renesas@jmondi.org>
+Date: Mon, 10 Dec 2018 09:53:55 -0500
+Subject: [PATCH 081/211] media: rcar-csi2: Fix PHTW table values for E3/V3M
+MIME-Version: 1.0
+Content-Type: text/plain; charset=UTF-8
+Content-Transfer-Encoding: 8bit
+
+The PHTW selection algorithm implemented in rcsi2_phtw_write_mbps() checks for
+lower bound of the interval used to match the desired bandwidth. Use that
+in place of the currently used upper bound.
+
+Fixes: 10c08812fe60 ("media: rcar: rcar-csi2: Update V3M/E3 PHTW tables")
+
+Signed-off-by: Jacopo Mondi <jacopo+renesas@jmondi.org>
+Acked-by: Niklas Söderlund <niklas.soderlund+renesas@ragnatech.se>
+Signed-off-by: Mauro Carvalho Chehab <mchehab+samsung@kernel.org>
+(cherry picked from commit aa8a1012ba624e92fd1ab58463f22501bce78af8)
+Signed-off-by: Valentine Barshak <valentine.barshak@cogentembedded.com>
+---
+ drivers/media/platform/rcar-vin/rcar-csi2.c | 62 ++++++++++++++---------------
+ 1 file changed, 31 insertions(+), 31 deletions(-)
+
+diff --git a/drivers/media/platform/rcar-vin/rcar-csi2.c b/drivers/media/platform/rcar-vin/rcar-csi2.c
+index c21cc80..5d230b0 100644
+--- a/drivers/media/platform/rcar-vin/rcar-csi2.c
++++ b/drivers/media/platform/rcar-vin/rcar-csi2.c
+@@ -156,37 +156,37 @@ static const struct rcsi2_mbps_reg phtw_mbps_h3_v3h_m3n[] = {
+ };
+
+ static const struct rcsi2_mbps_reg phtw_mbps_v3m_e3[] = {
+- { .mbps = 89, .reg = 0x00 },
+- { .mbps = 99, .reg = 0x20 },
+- { .mbps = 109, .reg = 0x40 },
+- { .mbps = 129, .reg = 0x02 },
+- { .mbps = 139, .reg = 0x22 },
+- { .mbps = 149, .reg = 0x42 },
+- { .mbps = 169, .reg = 0x04 },
+- { .mbps = 179, .reg = 0x24 },
+- { .mbps = 199, .reg = 0x44 },
+- { .mbps = 219, .reg = 0x06 },
+- { .mbps = 239, .reg = 0x26 },
+- { .mbps = 249, .reg = 0x46 },
+- { .mbps = 269, .reg = 0x08 },
+- { .mbps = 299, .reg = 0x28 },
+- { .mbps = 329, .reg = 0x0a },
+- { .mbps = 359, .reg = 0x2a },
+- { .mbps = 399, .reg = 0x4a },
+- { .mbps = 449, .reg = 0x0c },
+- { .mbps = 499, .reg = 0x2c },
+- { .mbps = 549, .reg = 0x0e },
+- { .mbps = 599, .reg = 0x2e },
+- { .mbps = 649, .reg = 0x10 },
+- { .mbps = 699, .reg = 0x30 },
+- { .mbps = 749, .reg = 0x12 },
+- { .mbps = 799, .reg = 0x32 },
+- { .mbps = 849, .reg = 0x52 },
+- { .mbps = 899, .reg = 0x72 },
+- { .mbps = 949, .reg = 0x14 },
+- { .mbps = 999, .reg = 0x34 },
+- { .mbps = 1049, .reg = 0x54 },
+- { .mbps = 1099, .reg = 0x74 },
++ { .mbps = 80, .reg = 0x00 },
++ { .mbps = 90, .reg = 0x20 },
++ { .mbps = 100, .reg = 0x40 },
++ { .mbps = 110, .reg = 0x02 },
++ { .mbps = 130, .reg = 0x22 },
++ { .mbps = 140, .reg = 0x42 },
++ { .mbps = 150, .reg = 0x04 },
++ { .mbps = 170, .reg = 0x24 },
++ { .mbps = 180, .reg = 0x44 },
++ { .mbps = 200, .reg = 0x06 },
++ { .mbps = 220, .reg = 0x26 },
++ { .mbps = 240, .reg = 0x46 },
++ { .mbps = 250, .reg = 0x08 },
++ { .mbps = 270, .reg = 0x28 },
++ { .mbps = 300, .reg = 0x0a },
++ { .mbps = 330, .reg = 0x2a },
++ { .mbps = 360, .reg = 0x4a },
++ { .mbps = 400, .reg = 0x0c },
++ { .mbps = 450, .reg = 0x2c },
++ { .mbps = 500, .reg = 0x0e },
++ { .mbps = 550, .reg = 0x2e },
++ { .mbps = 600, .reg = 0x10 },
++ { .mbps = 650, .reg = 0x30 },
++ { .mbps = 700, .reg = 0x12 },
++ { .mbps = 750, .reg = 0x32 },
++ { .mbps = 800, .reg = 0x52 },
++ { .mbps = 850, .reg = 0x72 },
++ { .mbps = 900, .reg = 0x14 },
++ { .mbps = 950, .reg = 0x34 },
++ { .mbps = 1000, .reg = 0x54 },
++ { .mbps = 1050, .reg = 0x74 },
+ { .mbps = 1125, .reg = 0x16 },
+ { /* sentinel */ },
+ };
+--
+2.7.4
+
diff --git a/bsp/meta-rcar/meta-rcar-gen3-adas/recipes-kernel/linux/linux-renesas/0262-pinctrl-sh-pfc-Reduce-kernel-size-for-narrow-VIN-cha.patch b/bsp/meta-rcar/meta-rcar-gen3-adas/recipes-kernel/linux/linux-renesas/0262-pinctrl-sh-pfc-Reduce-kernel-size-for-narrow-VIN-cha.patch
new file mode 100644
index 00000000..d09795b9
--- /dev/null
+++ b/bsp/meta-rcar/meta-rcar-gen3-adas/recipes-kernel/linux/linux-renesas/0262-pinctrl-sh-pfc-Reduce-kernel-size-for-narrow-VIN-cha.patch
@@ -0,0 +1,165 @@
+From 429290a136aea89f4af18539b86fc3159d4573ab Mon Sep 17 00:00:00 2001
+From: Geert Uytterhoeven <geert+renesas@glider.be>
+Date: Tue, 16 Oct 2018 09:46:12 +0200
+Subject: [PATCH 082/211] pinctrl: sh-pfc: Reduce kernel size for narrow VIN
+ channels
+MIME-Version: 1.0
+Content-Type: text/plain; charset=UTF-8
+Content-Transfer-Encoding: 8bit
+
+Some VIN channels support less than 24 lanes. As union vin_data always
+consumes space for 24 lanes, this wastes memory.
+
+Hence introduce new smaller unions vin_data12 and vin_data16, to
+accommodate VIN channels with only 12 or 16 lanes.
+
+This reduces the static pin controller driver size by 320 bytes for
+R-Car V2H, and by 96 bytes for R-Car E2.
+
+Signed-off-by: Geert Uytterhoeven <geert+renesas@glider.be>
+Reviewed-by: Simon Horman <horms+renesas@verge.net.au>
+Reviewed-by: Niklas Söderlund <niklas.soderlund+renesas@ragnatech.se>
+(cherry picked from commit 50f3f2d73e3426ba5aac0fe62098870579a0b357)
+Signed-off-by: Valentine Barshak <valentine.barshak@cogentembedded.com>
+---
+ drivers/pinctrl/sh-pfc/pfc-r8a7792.c | 16 ++++++++--------
+ drivers/pinctrl/sh-pfc/pfc-r8a7794.c | 4 ++--
+ drivers/pinctrl/sh-pfc/sh_pfc.h | 17 +++++++++++++++--
+ 3 files changed, 25 insertions(+), 12 deletions(-)
+
+diff --git a/drivers/pinctrl/sh-pfc/pfc-r8a7792.c b/drivers/pinctrl/sh-pfc/pfc-r8a7792.c
+index cc3597f..a3acfd6 100644
+--- a/drivers/pinctrl/sh-pfc/pfc-r8a7792.c
++++ b/drivers/pinctrl/sh-pfc/pfc-r8a7792.c
+@@ -1477,7 +1477,7 @@ static const unsigned int vin1_clk_mux[] = {
+ VI1_CLK_MARK,
+ };
+ /* - VIN2 ------------------------------------------------------------------- */
+-static const union vin_data vin2_data_pins = {
++static const union vin_data16 vin2_data_pins = {
+ .data16 = {
+ RCAR_GP_PIN(6, 4), RCAR_GP_PIN(6, 5),
+ RCAR_GP_PIN(6, 6), RCAR_GP_PIN(6, 7),
+@@ -1489,7 +1489,7 @@ static const union vin_data vin2_data_pins = {
+ RCAR_GP_PIN(8, 11), RCAR_GP_PIN(8, 12),
+ },
+ };
+-static const union vin_data vin2_data_mux = {
++static const union vin_data16 vin2_data_mux = {
+ .data16 = {
+ VI2_D0_C0_MARK, VI2_D1_C1_MARK,
+ VI2_D2_C2_MARK, VI2_D3_C3_MARK,
+@@ -1527,7 +1527,7 @@ static const unsigned int vin2_clk_mux[] = {
+ VI2_CLK_MARK,
+ };
+ /* - VIN3 ------------------------------------------------------------------- */
+-static const union vin_data vin3_data_pins = {
++static const union vin_data16 vin3_data_pins = {
+ .data16 = {
+ RCAR_GP_PIN(7, 4), RCAR_GP_PIN(7, 5),
+ RCAR_GP_PIN(7, 6), RCAR_GP_PIN(7, 7),
+@@ -1539,7 +1539,7 @@ static const union vin_data vin3_data_pins = {
+ RCAR_GP_PIN(8, 15), RCAR_GP_PIN(8, 16),
+ },
+ };
+-static const union vin_data vin3_data_mux = {
++static const union vin_data16 vin3_data_mux = {
+ .data16 = {
+ VI3_D0_C0_MARK, VI3_D1_C1_MARK,
+ VI3_D2_C2_MARK, VI3_D3_C3_MARK,
+@@ -1577,7 +1577,7 @@ static const unsigned int vin3_clk_mux[] = {
+ VI3_CLK_MARK,
+ };
+ /* - VIN4 ------------------------------------------------------------------- */
+-static const union vin_data vin4_data_pins = {
++static const union vin_data12 vin4_data_pins = {
+ .data12 = {
+ RCAR_GP_PIN(8, 4), RCAR_GP_PIN(8, 5),
+ RCAR_GP_PIN(8, 6), RCAR_GP_PIN(8, 7),
+@@ -1587,7 +1587,7 @@ static const union vin_data vin4_data_pins = {
+ RCAR_GP_PIN(8, 14), RCAR_GP_PIN(8, 15),
+ },
+ };
+-static const union vin_data vin4_data_mux = {
++static const union vin_data12 vin4_data_mux = {
+ .data12 = {
+ VI4_D0_C0_MARK, VI4_D1_C1_MARK,
+ VI4_D2_C2_MARK, VI4_D3_C3_MARK,
+@@ -1623,7 +1623,7 @@ static const unsigned int vin4_clk_mux[] = {
+ VI4_CLK_MARK,
+ };
+ /* - VIN5 ------------------------------------------------------------------- */
+-static const union vin_data vin5_data_pins = {
++static const union vin_data12 vin5_data_pins = {
+ .data12 = {
+ RCAR_GP_PIN(9, 4), RCAR_GP_PIN(9, 5),
+ RCAR_GP_PIN(9, 6), RCAR_GP_PIN(9, 7),
+@@ -1633,7 +1633,7 @@ static const union vin_data vin5_data_pins = {
+ RCAR_GP_PIN(9, 14), RCAR_GP_PIN(9, 15),
+ },
+ };
+-static const union vin_data vin5_data_mux = {
++static const union vin_data12 vin5_data_mux = {
+ .data12 = {
+ VI5_D0_C0_MARK, VI5_D1_C1_MARK,
+ VI5_D2_C2_MARK, VI5_D3_C3_MARK,
+diff --git a/drivers/pinctrl/sh-pfc/pfc-r8a7794.c b/drivers/pinctrl/sh-pfc/pfc-r8a7794.c
+index 1640024..bbb1a37 100644
+--- a/drivers/pinctrl/sh-pfc/pfc-r8a7794.c
++++ b/drivers/pinctrl/sh-pfc/pfc-r8a7794.c
+@@ -3707,7 +3707,7 @@ static const unsigned int vin0_clk_mux[] = {
+ VI0_CLK_MARK,
+ };
+ /* - VIN1 ------------------------------------------------------------------- */
+-static const union vin_data vin1_data_pins = {
++static const union vin_data12 vin1_data_pins = {
+ .data12 = {
+ RCAR_GP_PIN(5, 12), RCAR_GP_PIN(5, 13),
+ RCAR_GP_PIN(5, 14), RCAR_GP_PIN(5, 15),
+@@ -3717,7 +3717,7 @@ static const union vin_data vin1_data_pins = {
+ RCAR_GP_PIN(1, 12), RCAR_GP_PIN(1, 13),
+ },
+ };
+-static const union vin_data vin1_data_mux = {
++static const union vin_data12 vin1_data_mux = {
+ .data12 = {
+ VI1_DATA0_MARK, VI1_DATA1_MARK,
+ VI1_DATA2_MARK, VI1_DATA3_MARK,
+diff --git a/drivers/pinctrl/sh-pfc/sh_pfc.h b/drivers/pinctrl/sh-pfc/sh_pfc.h
+index 3d0b316..e0c8245 100644
+--- a/drivers/pinctrl/sh-pfc/sh_pfc.h
++++ b/drivers/pinctrl/sh-pfc/sh_pfc.h
+@@ -56,8 +56,8 @@ struct sh_pfc_pin_group {
+ };
+
+ /*
+- * Using union vin_data saves memory occupied by the VIN data pins.
+- * VIN_DATA_PIN_GROUP() is a macro used to describe the VIN pin groups
++ * Using union vin_data{,12,16} saves memory occupied by the VIN data pins.
++ * VIN_DATA_PIN_GROUP() is a macro used to describe the VIN pin groups
+ * in this case.
+ */
+ #define VIN_DATA_PIN_GROUP(n, s) \
+@@ -68,6 +68,19 @@ struct sh_pfc_pin_group {
+ .nr_pins = ARRAY_SIZE(n##_pins.data##s), \
+ }
+
++union vin_data12 {
++ unsigned int data12[12];
++ unsigned int data10[10];
++ unsigned int data8[8];
++};
++
++union vin_data16 {
++ unsigned int data16[16];
++ unsigned int data12[12];
++ unsigned int data10[10];
++ unsigned int data8[8];
++};
++
+ union vin_data {
+ unsigned int data24[24];
+ unsigned int data20[20];
+--
+2.7.4
+
diff --git a/bsp/meta-rcar/meta-rcar-gen3-adas/recipes-kernel/linux/linux-renesas/0263-pinctrl-sh-pfc-r8a77970-Deduplicate-VIN-01-pin-defin.patch b/bsp/meta-rcar/meta-rcar-gen3-adas/recipes-kernel/linux/linux-renesas/0263-pinctrl-sh-pfc-r8a77970-Deduplicate-VIN-01-pin-defin.patch
new file mode 100644
index 00000000..79a5f81f
--- /dev/null
+++ b/bsp/meta-rcar/meta-rcar-gen3-adas/recipes-kernel/linux/linux-renesas/0263-pinctrl-sh-pfc-r8a77970-Deduplicate-VIN-01-pin-defin.patch
@@ -0,0 +1,186 @@
+From f551856450c9182f125d4b0989224f7d6720e1ff Mon Sep 17 00:00:00 2001
+From: Geert Uytterhoeven <geert+renesas@glider.be>
+Date: Wed, 9 Jan 2019 15:56:12 +0100
+Subject: [PATCH 083/211] pinctrl: sh-pfc: r8a77970: Deduplicate VIN[01] pin
+ definitions
+MIME-Version: 1.0
+Content-Type: text/plain; charset=UTF-8
+Content-Transfer-Encoding: 8bit
+
+Use union vin_data12 and VIN_DATA_PIN_GROUP() to reduce redundancies in
+pin definitions for the VIN0 and VIN1 channels.
+
+This reduces kernel size by 288 bytes.
+
+Signed-off-by: Geert Uytterhoeven <geert+renesas@glider.be>
+Reviewed-by: Jacopo Mondi <jacopo+renesas@jmondi.org>
+Reviewed-by: Simon Horman <horms+renesas@verge.net.au>
+Reviewed-by: Niklas Söderlund <niklas.soderlund+renesas@ragnatech.se>
+(cherry picked from commit 81c585c96b7dd47caede1bf6d2920a81498385dc)
+Signed-off-by: Valentine Barshak <valentine.barshak@cogentembedded.com>
+---
+ drivers/pinctrl/sh-pfc/pfc-r8a77970.c | 128 +++++++++++-----------------------
+ 1 file changed, 42 insertions(+), 86 deletions(-)
+
+diff --git a/drivers/pinctrl/sh-pfc/pfc-r8a77970.c b/drivers/pinctrl/sh-pfc/pfc-r8a77970.c
+index e331e93..53ad813 100644
+--- a/drivers/pinctrl/sh-pfc/pfc-r8a77970.c
++++ b/drivers/pinctrl/sh-pfc/pfc-r8a77970.c
+@@ -1581,47 +1581,25 @@ static const unsigned int tmu_tclk2_b_mux[] = {
+ };
+
+ /* - VIN0 ------------------------------------------------------------------- */
+-static const unsigned int vin0_data8_pins[] = {
+- RCAR_GP_PIN(2, 4), RCAR_GP_PIN(2, 5),
+- RCAR_GP_PIN(2, 6), RCAR_GP_PIN(2, 7),
+- RCAR_GP_PIN(2, 8), RCAR_GP_PIN(2, 9),
+- RCAR_GP_PIN(2, 10), RCAR_GP_PIN(2, 11),
+-};
+-static const unsigned int vin0_data8_mux[] = {
+- VI0_DATA0_MARK, VI0_DATA1_MARK,
+- VI0_DATA2_MARK, VI0_DATA3_MARK,
+- VI0_DATA4_MARK, VI0_DATA5_MARK,
+- VI0_DATA6_MARK, VI0_DATA7_MARK,
++static const union vin_data12 vin0_data_pins = {
++ .data12 = {
++ RCAR_GP_PIN(2, 4), RCAR_GP_PIN(2, 5),
++ RCAR_GP_PIN(2, 6), RCAR_GP_PIN(2, 7),
++ RCAR_GP_PIN(2, 8), RCAR_GP_PIN(2, 9),
++ RCAR_GP_PIN(2, 10), RCAR_GP_PIN(2, 11),
++ RCAR_GP_PIN(2, 12), RCAR_GP_PIN(2, 13),
++ RCAR_GP_PIN(2, 14), RCAR_GP_PIN(2, 15),
++ },
+ };
+-static const unsigned int vin0_data10_pins[] = {
+- RCAR_GP_PIN(2, 4), RCAR_GP_PIN(2, 5),
+- RCAR_GP_PIN(2, 6), RCAR_GP_PIN(2, 7),
+- RCAR_GP_PIN(2, 8), RCAR_GP_PIN(2, 9),
+- RCAR_GP_PIN(2, 10), RCAR_GP_PIN(2, 11),
+- RCAR_GP_PIN(2, 12), RCAR_GP_PIN(2, 13),
+-};
+-static const unsigned int vin0_data10_mux[] = {
+- VI0_DATA0_MARK, VI0_DATA1_MARK,
+- VI0_DATA2_MARK, VI0_DATA3_MARK,
+- VI0_DATA4_MARK, VI0_DATA5_MARK,
+- VI0_DATA6_MARK, VI0_DATA7_MARK,
+- VI0_DATA8_MARK, VI0_DATA9_MARK,
+-};
+-static const unsigned int vin0_data12_pins[] = {
+- RCAR_GP_PIN(2, 4), RCAR_GP_PIN(2, 5),
+- RCAR_GP_PIN(2, 6), RCAR_GP_PIN(2, 7),
+- RCAR_GP_PIN(2, 8), RCAR_GP_PIN(2, 9),
+- RCAR_GP_PIN(2, 10), RCAR_GP_PIN(2, 11),
+- RCAR_GP_PIN(2, 12), RCAR_GP_PIN(2, 13),
+- RCAR_GP_PIN(2, 14), RCAR_GP_PIN(2, 15),
+-};
+-static const unsigned int vin0_data12_mux[] = {
+- VI0_DATA0_MARK, VI0_DATA1_MARK,
+- VI0_DATA2_MARK, VI0_DATA3_MARK,
+- VI0_DATA4_MARK, VI0_DATA5_MARK,
+- VI0_DATA6_MARK, VI0_DATA7_MARK,
+- VI0_DATA8_MARK, VI0_DATA9_MARK,
+- VI0_DATA10_MARK, VI0_DATA11_MARK,
++static const union vin_data12 vin0_data_mux = {
++ .data12 = {
++ VI0_DATA0_MARK, VI0_DATA1_MARK,
++ VI0_DATA2_MARK, VI0_DATA3_MARK,
++ VI0_DATA4_MARK, VI0_DATA5_MARK,
++ VI0_DATA6_MARK, VI0_DATA7_MARK,
++ VI0_DATA8_MARK, VI0_DATA9_MARK,
++ VI0_DATA10_MARK, VI0_DATA11_MARK,
++ },
+ };
+ static const unsigned int vin0_sync_pins[] = {
+ /* HSYNC#, VSYNC# */
+@@ -1653,47 +1631,25 @@ static const unsigned int vin0_clk_mux[] = {
+ };
+
+ /* - VIN1 ------------------------------------------------------------------- */
+-static const unsigned int vin1_data8_pins[] = {
+- RCAR_GP_PIN(3, 4), RCAR_GP_PIN(3, 5),
+- RCAR_GP_PIN(3, 6), RCAR_GP_PIN(3, 7),
+- RCAR_GP_PIN(3, 8), RCAR_GP_PIN(3, 9),
+- RCAR_GP_PIN(3, 10), RCAR_GP_PIN(3, 11),
+-};
+-static const unsigned int vin1_data8_mux[] = {
+- VI1_DATA0_MARK, VI1_DATA1_MARK,
+- VI1_DATA2_MARK, VI1_DATA3_MARK,
+- VI1_DATA4_MARK, VI1_DATA5_MARK,
+- VI1_DATA6_MARK, VI1_DATA7_MARK,
+-};
+-static const unsigned int vin1_data10_pins[] = {
+- RCAR_GP_PIN(3, 4), RCAR_GP_PIN(3, 5),
+- RCAR_GP_PIN(3, 6), RCAR_GP_PIN(3, 7),
+- RCAR_GP_PIN(3, 8), RCAR_GP_PIN(3, 9),
+- RCAR_GP_PIN(3, 10), RCAR_GP_PIN(3, 11),
+- RCAR_GP_PIN(3, 12), RCAR_GP_PIN(3, 13),
+-};
+-static const unsigned int vin1_data10_mux[] = {
+- VI1_DATA0_MARK, VI1_DATA1_MARK,
+- VI1_DATA2_MARK, VI1_DATA3_MARK,
+- VI1_DATA4_MARK, VI1_DATA5_MARK,
+- VI1_DATA6_MARK, VI1_DATA7_MARK,
+- VI1_DATA8_MARK, VI1_DATA9_MARK,
+-};
+-static const unsigned int vin1_data12_pins[] = {
+- RCAR_GP_PIN(3, 4), RCAR_GP_PIN(3, 5),
+- RCAR_GP_PIN(3, 6), RCAR_GP_PIN(3, 7),
+- RCAR_GP_PIN(3, 8), RCAR_GP_PIN(3, 9),
+- RCAR_GP_PIN(3, 10), RCAR_GP_PIN(3, 11),
+- RCAR_GP_PIN(3, 12), RCAR_GP_PIN(3, 13),
+- RCAR_GP_PIN(3, 14), RCAR_GP_PIN(3, 15),
++static const union vin_data12 vin1_data_pins = {
++ .data12 = {
++ RCAR_GP_PIN(3, 4), RCAR_GP_PIN(3, 5),
++ RCAR_GP_PIN(3, 6), RCAR_GP_PIN(3, 7),
++ RCAR_GP_PIN(3, 8), RCAR_GP_PIN(3, 9),
++ RCAR_GP_PIN(3, 10), RCAR_GP_PIN(3, 11),
++ RCAR_GP_PIN(3, 12), RCAR_GP_PIN(3, 13),
++ RCAR_GP_PIN(3, 14), RCAR_GP_PIN(3, 15),
++ },
+ };
+-static const unsigned int vin1_data12_mux[] = {
+- VI1_DATA0_MARK, VI1_DATA1_MARK,
+- VI1_DATA2_MARK, VI1_DATA3_MARK,
+- VI1_DATA4_MARK, VI1_DATA5_MARK,
+- VI1_DATA6_MARK, VI1_DATA7_MARK,
+- VI1_DATA8_MARK, VI1_DATA9_MARK,
+- VI1_DATA10_MARK, VI1_DATA11_MARK,
++static const union vin_data12 vin1_data_mux = {
++ .data12 = {
++ VI1_DATA0_MARK, VI1_DATA1_MARK,
++ VI1_DATA2_MARK, VI1_DATA3_MARK,
++ VI1_DATA4_MARK, VI1_DATA5_MARK,
++ VI1_DATA6_MARK, VI1_DATA7_MARK,
++ VI1_DATA8_MARK, VI1_DATA9_MARK,
++ VI1_DATA10_MARK, VI1_DATA11_MARK,
++ },
+ };
+ static const unsigned int vin1_sync_pins[] = {
+ /* HSYNC#, VSYNC# */
+@@ -1834,16 +1790,16 @@ static const struct sh_pfc_pin_group pinmux_groups[] = {
+ SH_PFC_PIN_GROUP(tmu_tclk1_b),
+ SH_PFC_PIN_GROUP(tmu_tclk2_a),
+ SH_PFC_PIN_GROUP(tmu_tclk2_b),
+- SH_PFC_PIN_GROUP(vin0_data8),
+- SH_PFC_PIN_GROUP(vin0_data10),
+- SH_PFC_PIN_GROUP(vin0_data12),
++ VIN_DATA_PIN_GROUP(vin0_data, 8),
++ VIN_DATA_PIN_GROUP(vin0_data, 10),
++ VIN_DATA_PIN_GROUP(vin0_data, 12),
+ SH_PFC_PIN_GROUP(vin0_sync),
+ SH_PFC_PIN_GROUP(vin0_field),
+ SH_PFC_PIN_GROUP(vin0_clkenb),
+ SH_PFC_PIN_GROUP(vin0_clk),
+- SH_PFC_PIN_GROUP(vin1_data8),
+- SH_PFC_PIN_GROUP(vin1_data10),
+- SH_PFC_PIN_GROUP(vin1_data12),
++ VIN_DATA_PIN_GROUP(vin1_data, 8),
++ VIN_DATA_PIN_GROUP(vin1_data, 10),
++ VIN_DATA_PIN_GROUP(vin1_data, 12),
+ SH_PFC_PIN_GROUP(vin1_sync),
+ SH_PFC_PIN_GROUP(vin1_field),
+ SH_PFC_PIN_GROUP(vin1_clkenb),
+--
+2.7.4
+
diff --git a/bsp/meta-rcar/meta-rcar-gen3-adas/recipes-kernel/linux/linux-renesas/0264-pinctrl-sh-pfc-r8a77980-Deduplicate-VIN1-pin-definit.patch b/bsp/meta-rcar/meta-rcar-gen3-adas/recipes-kernel/linux/linux-renesas/0264-pinctrl-sh-pfc-r8a77980-Deduplicate-VIN1-pin-definit.patch
new file mode 100644
index 00000000..ace0561e
--- /dev/null
+++ b/bsp/meta-rcar/meta-rcar-gen3-adas/recipes-kernel/linux/linux-renesas/0264-pinctrl-sh-pfc-r8a77980-Deduplicate-VIN1-pin-definit.patch
@@ -0,0 +1,110 @@
+From 4a51481da796493b420fed4026b6643102997d05 Mon Sep 17 00:00:00 2001
+From: Geert Uytterhoeven <geert+renesas@glider.be>
+Date: Wed, 9 Jan 2019 15:57:57 +0100
+Subject: [PATCH 084/211] pinctrl: sh-pfc: r8a77980: Deduplicate VIN1 pin
+ definitions
+MIME-Version: 1.0
+Content-Type: text/plain; charset=UTF-8
+Content-Transfer-Encoding: 8bit
+
+Use union vin_data12 and VIN_DATA_PIN_GROUP() to reduce redundancies in
+pin definitions for the VIN1 channel.
+
+This reduces kernel size by 144 bytes.
+
+Signed-off-by: Geert Uytterhoeven <geert+renesas@glider.be>
+Reviewed-by: Jacopo Mondi <jacopo+renesas@jmondi.org>
+Reviewed-by: Simon Horman <horms+renesas@verge.net.au>
+Reviewed-by: Niklas Söderlund <niklas.soderlund+renesas@ragnatech.se>
+(cherry picked from commit 9dd1731306d90f08d726987d3d7e39ba6e23a015)
+Signed-off-by: Valentine Barshak <valentine.barshak@cogentembedded.com>
+---
+ drivers/pinctrl/sh-pfc/pfc-r8a77980.c | 64 ++++++++++++-----------------------
+ 1 file changed, 21 insertions(+), 43 deletions(-)
+
+diff --git a/drivers/pinctrl/sh-pfc/pfc-r8a77980.c b/drivers/pinctrl/sh-pfc/pfc-r8a77980.c
+index 8bef245..b807b67a 100644
+--- a/drivers/pinctrl/sh-pfc/pfc-r8a77980.c
++++ b/drivers/pinctrl/sh-pfc/pfc-r8a77980.c
+@@ -1970,47 +1970,25 @@ static const unsigned int vin0_clk_mux[] = {
+ };
+
+ /* - VIN1 ------------------------------------------------------------------- */
+-static const unsigned int vin1_data8_pins[] = {
+- RCAR_GP_PIN(3, 4), RCAR_GP_PIN(3, 5),
+- RCAR_GP_PIN(3, 6), RCAR_GP_PIN(3, 7),
+- RCAR_GP_PIN(3, 8), RCAR_GP_PIN(3, 9),
+- RCAR_GP_PIN(3, 10), RCAR_GP_PIN(3, 11),
+-};
+-static const unsigned int vin1_data8_mux[] = {
+- VI1_DATA0_MARK, VI1_DATA1_MARK,
+- VI1_DATA2_MARK, VI1_DATA3_MARK,
+- VI1_DATA4_MARK, VI1_DATA5_MARK,
+- VI1_DATA6_MARK, VI1_DATA7_MARK,
+-};
+-static const unsigned int vin1_data10_pins[] = {
+- RCAR_GP_PIN(3, 4), RCAR_GP_PIN(3, 5),
+- RCAR_GP_PIN(3, 6), RCAR_GP_PIN(3, 7),
+- RCAR_GP_PIN(3, 8), RCAR_GP_PIN(3, 9),
+- RCAR_GP_PIN(3, 10), RCAR_GP_PIN(3, 11),
+- RCAR_GP_PIN(3, 12), RCAR_GP_PIN(3, 13),
+-};
+-static const unsigned int vin1_data10_mux[] = {
+- VI1_DATA0_MARK, VI1_DATA1_MARK,
+- VI1_DATA2_MARK, VI1_DATA3_MARK,
+- VI1_DATA4_MARK, VI1_DATA5_MARK,
+- VI1_DATA6_MARK, VI1_DATA7_MARK,
+- VI1_DATA8_MARK, VI1_DATA9_MARK,
+-};
+-static const unsigned int vin1_data12_pins[] = {
+- RCAR_GP_PIN(3, 4), RCAR_GP_PIN(3, 5),
+- RCAR_GP_PIN(3, 6), RCAR_GP_PIN(3, 7),
+- RCAR_GP_PIN(3, 8), RCAR_GP_PIN(3, 9),
+- RCAR_GP_PIN(3, 10), RCAR_GP_PIN(3, 11),
+- RCAR_GP_PIN(3, 12), RCAR_GP_PIN(3, 13),
+- RCAR_GP_PIN(3, 14), RCAR_GP_PIN(3, 15),
++static const union vin_data12 vin1_data_pins = {
++ .data12 = {
++ RCAR_GP_PIN(3, 4), RCAR_GP_PIN(3, 5),
++ RCAR_GP_PIN(3, 6), RCAR_GP_PIN(3, 7),
++ RCAR_GP_PIN(3, 8), RCAR_GP_PIN(3, 9),
++ RCAR_GP_PIN(3, 10), RCAR_GP_PIN(3, 11),
++ RCAR_GP_PIN(3, 12), RCAR_GP_PIN(3, 13),
++ RCAR_GP_PIN(3, 14), RCAR_GP_PIN(3, 15),
++ },
+ };
+-static const unsigned int vin1_data12_mux[] = {
+- VI1_DATA0_MARK, VI1_DATA1_MARK,
+- VI1_DATA2_MARK, VI1_DATA3_MARK,
+- VI1_DATA4_MARK, VI1_DATA5_MARK,
+- VI1_DATA6_MARK, VI1_DATA7_MARK,
+- VI1_DATA8_MARK, VI1_DATA9_MARK,
+- VI1_DATA10_MARK, VI1_DATA11_MARK,
++static const union vin_data12 vin1_data_mux = {
++ .data12 = {
++ VI1_DATA0_MARK, VI1_DATA1_MARK,
++ VI1_DATA2_MARK, VI1_DATA3_MARK,
++ VI1_DATA4_MARK, VI1_DATA5_MARK,
++ VI1_DATA6_MARK, VI1_DATA7_MARK,
++ VI1_DATA8_MARK, VI1_DATA9_MARK,
++ VI1_DATA10_MARK, VI1_DATA11_MARK,
++ },
+ };
+ static const unsigned int vin1_sync_pins[] = {
+ /* VI1_VSYNC#, VI1_HSYNC# */
+@@ -2182,9 +2160,9 @@ static const struct sh_pfc_pin_group pinmux_groups[] = {
+ SH_PFC_PIN_GROUP(vin0_field),
+ SH_PFC_PIN_GROUP(vin0_clkenb),
+ SH_PFC_PIN_GROUP(vin0_clk),
+- SH_PFC_PIN_GROUP(vin1_data8),
+- SH_PFC_PIN_GROUP(vin1_data10),
+- SH_PFC_PIN_GROUP(vin1_data12),
++ VIN_DATA_PIN_GROUP(vin1_data, 8),
++ VIN_DATA_PIN_GROUP(vin1_data, 10),
++ VIN_DATA_PIN_GROUP(vin1_data, 12),
+ SH_PFC_PIN_GROUP(vin1_sync),
+ SH_PFC_PIN_GROUP(vin1_field),
+ SH_PFC_PIN_GROUP(vin1_clkenb),
+--
+2.7.4
+
diff --git a/bsp/meta-rcar/meta-rcar-gen3-adas/recipes-kernel/linux/linux-renesas/0265-arm64-dts-renesas-v3msk-specify-EtherAVB-PHY-IRQ.patch b/bsp/meta-rcar/meta-rcar-gen3-adas/recipes-kernel/linux/linux-renesas/0265-arm64-dts-renesas-v3msk-specify-EtherAVB-PHY-IRQ.patch
new file mode 100644
index 00000000..cd1de217
--- /dev/null
+++ b/bsp/meta-rcar/meta-rcar-gen3-adas/recipes-kernel/linux/linux-renesas/0265-arm64-dts-renesas-v3msk-specify-EtherAVB-PHY-IRQ.patch
@@ -0,0 +1,33 @@
+From ed37112995e8f12bb85a9b5b936336d81507511c Mon Sep 17 00:00:00 2001
+From: Sergei Shtylyov <sergei.shtylyov@cogentembedded.com>
+Date: Tue, 8 Jan 2019 22:56:50 +0300
+Subject: [PATCH 085/211] arm64: dts: renesas: v3msk: specify EtherAVB PHY IRQ
+
+Specify EtherAVB PHY IRQ in the V3M Starter Kit board's device tree, now
+that we have the GPIO support (previously phylib had to resort to polling).
+
+Signed-off-by: Sergei Shtylyov <sergei.shtylyov@cogentembedded.com>
+Reviewed-by: Geert Uytterhoeven <geert+renesas@glider.be>
+Signed-off-by: Simon Horman <horms+renesas@verge.net.au>
+(cherry picked from commit d5e5790c6ff0b6825f6d8b4baf67fa13810ce4fc)
+Signed-off-by: Valentine Barshak <valentine.barshak@cogentembedded.com>
+---
+ arch/arm64/boot/dts/renesas/r8a77970-v3msk.dts | 2 ++
+ 1 file changed, 2 insertions(+)
+
+diff --git a/arch/arm64/boot/dts/renesas/r8a77970-v3msk.dts b/arch/arm64/boot/dts/renesas/r8a77970-v3msk.dts
+index 0dbcb4c..15cc9fe 100644
+--- a/arch/arm64/boot/dts/renesas/r8a77970-v3msk.dts
++++ b/arch/arm64/boot/dts/renesas/r8a77970-v3msk.dts
+@@ -108,6 +108,8 @@
+ phy0: ethernet-phy@0 {
+ rxc-skew-ps = <1500>;
+ reg = <0>;
++ interrupt-parent = <&gpio1>;
++ interrupts = <17 IRQ_TYPE_LEVEL_LOW>;
+ };
+ };
+
+--
+2.7.4
+
diff --git a/bsp/meta-rcar/meta-rcar-gen3-adas/recipes-kernel/linux/linux-renesas/0266-sh_eth-rename-sh_eth_cpu_data-hw_checksum.patch b/bsp/meta-rcar/meta-rcar-gen3-adas/recipes-kernel/linux/linux-renesas/0266-sh_eth-rename-sh_eth_cpu_data-hw_checksum.patch
new file mode 100644
index 00000000..8f3283da
--- /dev/null
+++ b/bsp/meta-rcar/meta-rcar-gen3-adas/recipes-kernel/linux/linux-renesas/0266-sh_eth-rename-sh_eth_cpu_data-hw_checksum.patch
@@ -0,0 +1,104 @@
+From 3f271260224b6f9a242f4c9541f8d676e4cbbac8 Mon Sep 17 00:00:00 2001
+From: Sergei Shtylyov <sergei.shtylyov@cogentembedded.com>
+Date: Mon, 4 Feb 2019 21:05:55 +0300
+Subject: [PATCH 086/211] sh_eth: rename sh_eth_cpu_data::hw_checksum
+
+Commit 62e04b7e0e3c ("sh_eth: rename 'sh_eth_cpu_data::hw_crc'") renamed
+the field to 'hw_checksum' for the Ether DMAC "intelligent checksum",
+however some Ether MACs implement a simpler checksumming scheme, so that
+name now seems misleading. Rename that field to 'csmr' as the "intelligent
+checksum" is always controlled by the CSMR register.
+
+Signed-off-by: Sergei Shtylyov <sergei.shtylyov@cogentembedded.com>
+Reviewed-by: Geert Uytterhoeven <geert+renesas@glider.be>
+Signed-off-by: David S. Miller <davem@davemloft.net>
+(cherry picked from commit 2c2ab5af7d1470d7ba56525cc0c3eebe5ee2bad0)
+Signed-off-by: Valentine Barshak <valentine.barshak@cogentembedded.com>
+---
+ drivers/net/ethernet/renesas/sh_eth.c | 14 +++++++-------
+ drivers/net/ethernet/renesas/sh_eth.h | 2 +-
+ 2 files changed, 8 insertions(+), 8 deletions(-)
+
+diff --git a/drivers/net/ethernet/renesas/sh_eth.c b/drivers/net/ethernet/renesas/sh_eth.c
+index f11b12f..61b9fcb 100644
+--- a/drivers/net/ethernet/renesas/sh_eth.c
++++ b/drivers/net/ethernet/renesas/sh_eth.c
+@@ -561,7 +561,7 @@ static int sh_eth_soft_reset_gether(struct net_device *ndev)
+ sh_eth_write(ndev, 0, RDFFR);
+
+ /* Reset HW CRC register */
+- if (mdp->cd->hw_checksum)
++ if (mdp->cd->csmr)
+ sh_eth_write(ndev, 0, CSMR);
+
+ /* Select MII mode */
+@@ -625,7 +625,7 @@ static struct sh_eth_cpu_data r7s72100_data = {
+ .no_trimd = 1,
+ .no_ade = 1,
+ .xdfar_rw = 1,
+- .hw_checksum = 1,
++ .csmr = 1,
+ .tsu = 1,
+ .no_tx_cntrs = 1,
+ };
+@@ -674,7 +674,7 @@ static struct sh_eth_cpu_data r8a7740_data = {
+ .no_trimd = 1,
+ .no_ade = 1,
+ .xdfar_rw = 1,
+- .hw_checksum = 1,
++ .csmr = 1,
+ .tsu = 1,
+ .select_mii = 1,
+ .magic = 1,
+@@ -799,7 +799,7 @@ static struct sh_eth_cpu_data r8a77980_data = {
+ .no_trimd = 1,
+ .no_ade = 1,
+ .xdfar_rw = 1,
+- .hw_checksum = 1,
++ .csmr = 1,
+ .select_mii = 1,
+ .magic = 1,
+ .cexcr = 1,
+@@ -1016,7 +1016,7 @@ static struct sh_eth_cpu_data sh7734_data = {
+ .no_ade = 1,
+ .xdfar_rw = 1,
+ .tsu = 1,
+- .hw_checksum = 1,
++ .csmr = 1,
+ .select_mii = 1,
+ .magic = 1,
+ .cexcr = 1,
+@@ -1604,7 +1604,7 @@ static int sh_eth_rx(struct net_device *ndev, u32 intr_status, int *quota)
+ * the RFS bits are from bit 25 to bit 16. So, the
+ * driver needs right shifting by 16.
+ */
+- if (mdp->cd->hw_checksum)
++ if (mdp->cd->csmr)
+ desc_status >>= 16;
+
+ skb = mdp->rx_skbuff[entry];
+@@ -2144,7 +2144,7 @@ static size_t __sh_eth_get_regs(struct net_device *ndev, u32 *buf)
+ add_reg(MAFCR);
+ if (cd->rtrate)
+ add_reg(RTRATE);
+- if (cd->hw_checksum)
++ if (cd->csmr)
+ add_reg(CSMR);
+ if (cd->select_mii)
+ add_reg(RMII_MII);
+diff --git a/drivers/net/ethernet/renesas/sh_eth.h b/drivers/net/ethernet/renesas/sh_eth.h
+index 140ad2c..1e73433 100644
+--- a/drivers/net/ethernet/renesas/sh_eth.h
++++ b/drivers/net/ethernet/renesas/sh_eth.h
+@@ -510,7 +510,7 @@ struct sh_eth_cpu_data {
+ unsigned no_ade:1; /* E-DMAC DOES NOT have ADE bit in EESR */
+ unsigned no_xdfar:1; /* E-DMAC DOES NOT have RDFAR/TDFAR */
+ unsigned xdfar_rw:1; /* E-DMAC has writeable RDFAR/TDFAR */
+- unsigned hw_checksum:1; /* E-DMAC has CSMR */
++ unsigned csmr:1; /* E-DMAC has CSMR */
+ unsigned select_mii:1; /* EtherC has RMII_MII (MII select register) */
+ unsigned rmiimode:1; /* EtherC has RMIIMODE register */
+ unsigned rtrate:1; /* EtherC has RTRATE register */
+--
+2.7.4
+
diff --git a/bsp/meta-rcar/meta-rcar-gen3-adas/recipes-kernel/linux/linux-renesas/0267-sh_eth-RX-checksum-offload-support.patch b/bsp/meta-rcar/meta-rcar-gen3-adas/recipes-kernel/linux/linux-renesas/0267-sh_eth-RX-checksum-offload-support.patch
new file mode 100644
index 00000000..8abd0acb
--- /dev/null
+++ b/bsp/meta-rcar/meta-rcar-gen3-adas/recipes-kernel/linux/linux-renesas/0267-sh_eth-RX-checksum-offload-support.patch
@@ -0,0 +1,232 @@
+From d2a497014563885f67787a993118ab0e2597a4a8 Mon Sep 17 00:00:00 2001
+From: Sergei Shtylyov <sergei.shtylyov@cogentembedded.com>
+Date: Mon, 4 Feb 2019 21:06:52 +0300
+Subject: [PATCH 087/211] sh_eth: RX checksum offload support
+
+Add support for the RX checksum offload. This is enabled by default and
+may be disabled and re-enabled using 'ethtool':
+
+# ethtool -K eth0 rx off
+# ethtool -K eth0 rx on
+
+Some Ether MACs provide a simple checksumming scheme which appears to be
+completely compatible with CHECKSUM_COMPLETE: sum of all packet data after
+the L2 header is appended to packet data; this may be trivially read by
+the driver and used to update the skb accordingly. The same checksumming
+scheme is implemented in the EtherAVB MACs and now supported by the 'ravb'
+driver.
+
+In terms of performance, throughput is close to gigabit line rate with the
+RX checksum offload both enabled and disabled. The 'perf' output, however,
+appears to indicate that significantly less time is spent in do_csum() --
+this is as expected.
+
+Test results with RX checksum offload enabled:
+
+~/netperf-2.2pl4# perf record -a ./netperf -t TCP_MAERTS -H 192.168.2.4
+TCP MAERTS TEST to 192.168.2.4
+Recv Send Send
+Socket Socket Message Elapsed
+Size Size Size Time Throughput
+bytes bytes bytes secs. 10^6bits/sec
+
+131072 16384 16384 10.01 933.93
+[ perf record: Woken up 8 times to write data ]
+[ perf record: Captured and wrote 1.955 MB perf.data (41940 samples) ]
+~/netperf-2.2pl4# perf report
+Samples: 41K of event 'cycles:ppp', Event count (approx.): 9915302763
+Overhead Command Shared Object Symbol
+ 9.44% netperf [kernel.kallsyms] [k] __arch_copy_to_user
+ 7.75% swapper [kernel.kallsyms] [k] _raw_spin_unlock_irq
+ 6.31% swapper [kernel.kallsyms] [k] default_idle_call
+ 5.89% swapper [kernel.kallsyms] [k] arch_cpu_idle
+ 4.37% swapper [kernel.kallsyms] [k] tick_nohz_idle_exit
+ 4.02% netperf [kernel.kallsyms] [k] _raw_spin_unlock_irq
+ 2.52% netperf [kernel.kallsyms] [k] preempt_count_sub
+ 1.81% netperf [kernel.kallsyms] [k] tcp_recvmsg
+ 1.80% netperf [kernel.kallsyms] [k] _raw_spin_unlock_irqres
+ 1.78% netperf [kernel.kallsyms] [k] preempt_count_add
+ 1.36% netperf [kernel.kallsyms] [k] __tcp_transmit_skb
+ 1.20% netperf [kernel.kallsyms] [k] __local_bh_enable_ip
+ 1.10% netperf [kernel.kallsyms] [k] sh_eth_start_xmit
+
+Test results with RX checksum offload disabled:
+
+~/netperf-2.2pl4# perf record -a ./netperf -t TCP_MAERTS -H 192.168.2.4
+TCP MAERTS TEST to 192.168.2.4
+Recv Send Send
+Socket Socket Message Elapsed
+Size Size Size Time Throughput
+bytes bytes bytes secs. 10^6bits/sec
+131072 16384 16384 10.01 932.04
+[ perf record: Woken up 14 times to write data ]
+[ perf record: Captured and wrote 3.642 MB perf.data (78817 samples) ]
+~/netperf-2.2pl4# perf report
+Samples: 78K of event 'cycles:ppp', Event count (approx.): 18091442796
+Overhead Command Shared Object Symbol
+ 7.00% swapper [kernel.kallsyms] [k] do_csum
+ 3.94% swapper [kernel.kallsyms] [k] sh_eth_poll
+ 3.83% ksoftirqd/0 [kernel.kallsyms] [k] do_csum
+ 3.23% swapper [kernel.kallsyms] [k] _raw_spin_unlock_irq
+ 2.87% netperf [kernel.kallsyms] [k] __arch_copy_to_user
+ 2.86% swapper [kernel.kallsyms] [k] arch_cpu_idle
+ 2.13% swapper [kernel.kallsyms] [k] default_idle_call
+ 2.12% ksoftirqd/0 [kernel.kallsyms] [k] sh_eth_poll
+ 2.02% swapper [kernel.kallsyms] [k] _raw_spin_unlock_irqrestore
+ 1.84% swapper [kernel.kallsyms] [k] __softirqentry_text_start
+ 1.64% swapper [kernel.kallsyms] [k] tick_nohz_idle_exit
+ 1.53% netperf [kernel.kallsyms] [k] _raw_spin_unlock_irq
+ 1.32% netperf [kernel.kallsyms] [k] preempt_count_sub
+ 1.27% swapper [kernel.kallsyms] [k] __pi___inval_dcache_area
+ 1.22% swapper [kernel.kallsyms] [k] check_preemption_disabled
+ 1.01% ksoftirqd/0 [kernel.kallsyms] [k] _raw_spin_unlock_irqrestore
+
+The above results collected on the R-Car V3H Starter Kit board.
+
+Based on the commit 4d86d3818627 ("ravb: RX checksum offload")...
+
+Signed-off-by: Sergei Shtylyov <sergei.shtylyov@cogentembedded.com>
+Signed-off-by: David S. Miller <davem@davemloft.net>
+(cherry picked from commit f8e022db50564705e9e957a729a955f396a71093)
+Signed-off-by: Valentine Barshak <valentine.barshak@cogentembedded.com>
+---
+ drivers/net/ethernet/renesas/sh_eth.c | 60 +++++++++++++++++++++++++++++++++--
+ drivers/net/ethernet/renesas/sh_eth.h | 1 +
+ 2 files changed, 59 insertions(+), 2 deletions(-)
+
+diff --git a/drivers/net/ethernet/renesas/sh_eth.c b/drivers/net/ethernet/renesas/sh_eth.c
+index 61b9fcb..959e0cb 100644
+--- a/drivers/net/ethernet/renesas/sh_eth.c
++++ b/drivers/net/ethernet/renesas/sh_eth.c
+@@ -1503,8 +1503,9 @@ static int sh_eth_dev_init(struct net_device *ndev)
+ mdp->irq_enabled = true;
+ sh_eth_write(ndev, mdp->cd->eesipr_value, EESIPR);
+
+- /* PAUSE Prohibition */
++ /* EMAC Mode: PAUSE prohibition; Duplex; RX Checksum; TX; RX */
+ sh_eth_write(ndev, ECMR_ZPF | (mdp->duplex ? ECMR_DM : 0) |
++ (ndev->features & NETIF_F_RXCSUM ? ECMR_RCSC : 0) |
+ ECMR_TE | ECMR_RE, ECMR);
+
+ if (mdp->cd->set_rate)
+@@ -1563,6 +1564,19 @@ static void sh_eth_dev_exit(struct net_device *ndev)
+ update_mac_address(ndev);
+ }
+
++static void sh_eth_rx_csum(struct sk_buff *skb)
++{
++ u8 *hw_csum;
++
++ /* The hardware checksum is 2 bytes appended to packet data */
++ if (unlikely(skb->len < sizeof(__sum16)))
++ return;
++ hw_csum = skb_tail_pointer(skb) - sizeof(__sum16);
++ skb->csum = csum_unfold((__force __sum16)get_unaligned_le16(hw_csum));
++ skb->ip_summed = CHECKSUM_COMPLETE;
++ skb_trim(skb, skb->len - sizeof(__sum16));
++}
++
+ /* Packet receive function */
+ static int sh_eth_rx(struct net_device *ndev, u32 intr_status, int *quota)
+ {
+@@ -1637,6 +1651,8 @@ static int sh_eth_rx(struct net_device *ndev, u32 intr_status, int *quota)
+ DMA_FROM_DEVICE);
+ skb_put(skb, pkt_len);
+ skb->protocol = eth_type_trans(skb, ndev);
++ if (ndev->features & NETIF_F_RXCSUM)
++ sh_eth_rx_csum(skb);
+ netif_receive_skb(skb);
+ ndev->stats.rx_packets++;
+ ndev->stats.rx_bytes += pkt_len;
+@@ -2890,6 +2906,39 @@ static void sh_eth_set_rx_mode(struct net_device *ndev)
+ spin_unlock_irqrestore(&mdp->lock, flags);
+ }
+
++static void sh_eth_set_rx_csum(struct net_device *ndev, bool enable)
++{
++ struct sh_eth_private *mdp = netdev_priv(ndev);
++ unsigned long flags;
++
++ spin_lock_irqsave(&mdp->lock, flags);
++
++ /* Disable TX and RX */
++ sh_eth_rcv_snd_disable(ndev);
++
++ /* Modify RX Checksum setting */
++ sh_eth_modify(ndev, ECMR, ECMR_RCSC, enable ? ECMR_RCSC : 0);
++
++ /* Enable TX and RX */
++ sh_eth_rcv_snd_enable(ndev);
++
++ spin_unlock_irqrestore(&mdp->lock, flags);
++}
++
++static int sh_eth_set_features(struct net_device *ndev,
++ netdev_features_t features)
++{
++ netdev_features_t changed = ndev->features ^ features;
++ struct sh_eth_private *mdp = netdev_priv(ndev);
++
++ if (changed & NETIF_F_RXCSUM && mdp->cd->rx_csum)
++ sh_eth_set_rx_csum(ndev, features & NETIF_F_RXCSUM);
++
++ ndev->features = features;
++
++ return 0;
++}
++
+ static int sh_eth_get_vtag_index(struct sh_eth_private *mdp)
+ {
+ if (!mdp->port)
+@@ -3076,6 +3125,7 @@ static const struct net_device_ops sh_eth_netdev_ops = {
+ .ndo_change_mtu = sh_eth_change_mtu,
+ .ndo_validate_addr = eth_validate_addr,
+ .ndo_set_mac_address = eth_mac_addr,
++ .ndo_set_features = sh_eth_set_features,
+ };
+
+ static const struct net_device_ops sh_eth_netdev_ops_tsu = {
+@@ -3091,6 +3141,7 @@ static const struct net_device_ops sh_eth_netdev_ops_tsu = {
+ .ndo_change_mtu = sh_eth_change_mtu,
+ .ndo_validate_addr = eth_validate_addr,
+ .ndo_set_mac_address = eth_mac_addr,
++ .ndo_set_features = sh_eth_set_features,
+ };
+
+ #ifdef CONFIG_OF
+@@ -3218,6 +3269,11 @@ static int sh_eth_drv_probe(struct platform_device *pdev)
+ ndev->max_mtu = 2000 - (ETH_HLEN + VLAN_HLEN + ETH_FCS_LEN);
+ ndev->min_mtu = ETH_MIN_MTU;
+
++ if (mdp->cd->rx_csum) {
++ ndev->features = NETIF_F_RXCSUM;
++ ndev->hw_features = NETIF_F_RXCSUM;
++ }
++
+ /* set function */
+ if (mdp->cd->tsu)
+ ndev->netdev_ops = &sh_eth_netdev_ops_tsu;
+@@ -3267,7 +3323,7 @@ static int sh_eth_drv_probe(struct platform_device *pdev)
+ goto out_release;
+ }
+ mdp->port = port;
+- ndev->features = NETIF_F_HW_VLAN_CTAG_FILTER;
++ ndev->features |= NETIF_F_HW_VLAN_CTAG_FILTER;
+
+ /* Need to init only the first port of the two sharing a TSU */
+ if (port == 0) {
+diff --git a/drivers/net/ethernet/renesas/sh_eth.h b/drivers/net/ethernet/renesas/sh_eth.h
+index 1e73433..7a172c4 100644
+--- a/drivers/net/ethernet/renesas/sh_eth.h
++++ b/drivers/net/ethernet/renesas/sh_eth.h
+@@ -511,6 +511,7 @@ struct sh_eth_cpu_data {
+ unsigned no_xdfar:1; /* E-DMAC DOES NOT have RDFAR/TDFAR */
+ unsigned xdfar_rw:1; /* E-DMAC has writeable RDFAR/TDFAR */
+ unsigned csmr:1; /* E-DMAC has CSMR */
++ unsigned rx_csum:1; /* EtherC has ECMR.RCSC */
+ unsigned select_mii:1; /* EtherC has RMII_MII (MII select register) */
+ unsigned rmiimode:1; /* EtherC has RMIIMODE register */
+ unsigned rtrate:1; /* EtherC has RTRATE register */
+--
+2.7.4
+
diff --git a/bsp/meta-rcar/meta-rcar-gen3-adas/recipes-kernel/linux/linux-renesas/0268-sh_eth-offload-RX-checksum-on-R7S72100.patch b/bsp/meta-rcar/meta-rcar-gen3-adas/recipes-kernel/linux/linux-renesas/0268-sh_eth-offload-RX-checksum-on-R7S72100.patch
new file mode 100644
index 00000000..a40a7c56
--- /dev/null
+++ b/bsp/meta-rcar/meta-rcar-gen3-adas/recipes-kernel/linux/linux-renesas/0268-sh_eth-offload-RX-checksum-on-R7S72100.patch
@@ -0,0 +1,31 @@
+From 026258a2809e44f4e689e75b809d49f8d3865fc0 Mon Sep 17 00:00:00 2001
+From: Sergei Shtylyov <sergei.shtylyov@cogentembedded.com>
+Date: Mon, 4 Feb 2019 21:07:53 +0300
+Subject: [PATCH 088/211] sh_eth: offload RX checksum on R7S72100
+
+The RZ/A1H (R7S721000) SoC manual describes the Ether MAC's RX checksum
+offload the same way as it's implemented in the EtherAVB MACs...
+
+Signed-off-by: Sergei Shtylyov <sergei.shtylyov@cogentembedded.com>
+Signed-off-by: David S. Miller <davem@davemloft.net>
+(cherry picked from commit 48132cd0c6317701421df3232a77c0a642292859)
+Signed-off-by: Valentine Barshak <valentine.barshak@cogentembedded.com>
+---
+ drivers/net/ethernet/renesas/sh_eth.c | 1 +
+ 1 file changed, 1 insertion(+)
+
+diff --git a/drivers/net/ethernet/renesas/sh_eth.c b/drivers/net/ethernet/renesas/sh_eth.c
+index 959e0cb..e1ec382 100644
+--- a/drivers/net/ethernet/renesas/sh_eth.c
++++ b/drivers/net/ethernet/renesas/sh_eth.c
+@@ -626,6 +626,7 @@ static struct sh_eth_cpu_data r7s72100_data = {
+ .no_ade = 1,
+ .xdfar_rw = 1,
+ .csmr = 1,
++ .rx_csum = 1,
+ .tsu = 1,
+ .no_tx_cntrs = 1,
+ };
+--
+2.7.4
+
diff --git a/bsp/meta-rcar/meta-rcar-gen3-adas/recipes-kernel/linux/linux-renesas/0269-sh_eth-offload-RX-checksum-on-R8A7740.patch b/bsp/meta-rcar/meta-rcar-gen3-adas/recipes-kernel/linux/linux-renesas/0269-sh_eth-offload-RX-checksum-on-R8A7740.patch
new file mode 100644
index 00000000..a9dc1411
--- /dev/null
+++ b/bsp/meta-rcar/meta-rcar-gen3-adas/recipes-kernel/linux/linux-renesas/0269-sh_eth-offload-RX-checksum-on-R8A7740.patch
@@ -0,0 +1,32 @@
+From c3f40e9d9ab4794ad3bf74fa50a82a7bd08c7a80 Mon Sep 17 00:00:00 2001
+From: Sergei Shtylyov <sergei.shtylyov@cogentembedded.com>
+Date: Mon, 4 Feb 2019 21:08:54 +0300
+Subject: [PATCH 089/211] sh_eth: offload RX checksum on R8A7740
+
+The R-Mobile A1 (R8A7740) SoC manual describes the Ether MAC's RX checksum
+offload the same way as it's implemented in the EtherAVB MAC...
+
+Signed-off-by: Sergei Shtylyov <sergei.shtylyov@cogentembedded.com>
+Tested-by: Geert Uytterhoeven <geert+renesas@glider.be>
+Signed-off-by: David S. Miller <davem@davemloft.net>
+(cherry picked from commit 040c16fd5974a947bcfb2fe2e66fe4f42eeef08a)
+Signed-off-by: Valentine Barshak <valentine.barshak@cogentembedded.com>
+---
+ drivers/net/ethernet/renesas/sh_eth.c | 1 +
+ 1 file changed, 1 insertion(+)
+
+diff --git a/drivers/net/ethernet/renesas/sh_eth.c b/drivers/net/ethernet/renesas/sh_eth.c
+index e1ec382..63bf7ee 100644
+--- a/drivers/net/ethernet/renesas/sh_eth.c
++++ b/drivers/net/ethernet/renesas/sh_eth.c
+@@ -676,6 +676,7 @@ static struct sh_eth_cpu_data r8a7740_data = {
+ .no_ade = 1,
+ .xdfar_rw = 1,
+ .csmr = 1,
++ .rx_csum = 1,
+ .tsu = 1,
+ .select_mii = 1,
+ .magic = 1,
+--
+2.7.4
+
diff --git a/bsp/meta-rcar/meta-rcar-gen3-adas/recipes-kernel/linux/linux-renesas/0270-sh_eth-offload-RX-checksum-on-R8A77980.patch b/bsp/meta-rcar/meta-rcar-gen3-adas/recipes-kernel/linux/linux-renesas/0270-sh_eth-offload-RX-checksum-on-R8A77980.patch
new file mode 100644
index 00000000..c379959c
--- /dev/null
+++ b/bsp/meta-rcar/meta-rcar-gen3-adas/recipes-kernel/linux/linux-renesas/0270-sh_eth-offload-RX-checksum-on-R8A77980.patch
@@ -0,0 +1,31 @@
+From 87b96e342f43398a7fdde613c1dc420dfd05faec Mon Sep 17 00:00:00 2001
+From: Sergei Shtylyov <sergei.shtylyov@cogentembedded.com>
+Date: Mon, 4 Feb 2019 21:10:32 +0300
+Subject: [PATCH 090/211] sh_eth: offload RX checksum on R8A77980
+
+The R-Car V3H (R8A77980) SoC manual describes the Ether MAC's RX checksum
+offload the same way as it's implemented in the EtherAVB MAC...
+
+Signed-off-by: Sergei Shtylyov <sergei.shtylyov@cogentembedded.com>
+Signed-off-by: David S. Miller <davem@davemloft.net>
+(cherry picked from commit 0da843adeefb4953a1a73a24d5a8dfbbffcd9a47)
+Signed-off-by: Valentine Barshak <valentine.barshak@cogentembedded.com>
+---
+ drivers/net/ethernet/renesas/sh_eth.c | 1 +
+ 1 file changed, 1 insertion(+)
+
+diff --git a/drivers/net/ethernet/renesas/sh_eth.c b/drivers/net/ethernet/renesas/sh_eth.c
+index 63bf7ee..a08b800 100644
+--- a/drivers/net/ethernet/renesas/sh_eth.c
++++ b/drivers/net/ethernet/renesas/sh_eth.c
+@@ -802,6 +802,7 @@ static struct sh_eth_cpu_data r8a77980_data = {
+ .no_ade = 1,
+ .xdfar_rw = 1,
+ .csmr = 1,
++ .rx_csum = 1,
+ .select_mii = 1,
+ .magic = 1,
+ .cexcr = 1,
+--
+2.7.4
+
diff --git a/bsp/meta-rcar/meta-rcar-gen3-adas/recipes-kernel/linux/linux-renesas/0271-sh_eth-offload-RX-checksum-on-SH7734.patch b/bsp/meta-rcar/meta-rcar-gen3-adas/recipes-kernel/linux/linux-renesas/0271-sh_eth-offload-RX-checksum-on-SH7734.patch
new file mode 100644
index 00000000..de67c015
--- /dev/null
+++ b/bsp/meta-rcar/meta-rcar-gen3-adas/recipes-kernel/linux/linux-renesas/0271-sh_eth-offload-RX-checksum-on-SH7734.patch
@@ -0,0 +1,31 @@
+From 403ffdf4d56c06d4e83553da19d1081799681e77 Mon Sep 17 00:00:00 2001
+From: Sergei Shtylyov <sergei.shtylyov@cogentembedded.com>
+Date: Mon, 4 Feb 2019 21:11:32 +0300
+Subject: [PATCH 091/211] sh_eth: offload RX checksum on SH7734
+
+The SH7734 SoC manual describes the Ether MAC's RX checksum offload
+the same way as it's implemented in the EtherAVB MACs...
+
+Signed-off-by: Sergei Shtylyov <sergei.shtylyov@cogentembedded.com>
+Signed-off-by: David S. Miller <davem@davemloft.net>
+(cherry picked from commit 06240e1b526d426acfe7b21e673da49e12f5a225)
+Signed-off-by: Valentine Barshak <valentine.barshak@cogentembedded.com>
+---
+ drivers/net/ethernet/renesas/sh_eth.c | 1 +
+ 1 file changed, 1 insertion(+)
+
+diff --git a/drivers/net/ethernet/renesas/sh_eth.c b/drivers/net/ethernet/renesas/sh_eth.c
+index a08b800..95fd30b 100644
+--- a/drivers/net/ethernet/renesas/sh_eth.c
++++ b/drivers/net/ethernet/renesas/sh_eth.c
+@@ -1020,6 +1020,7 @@ static struct sh_eth_cpu_data sh7734_data = {
+ .xdfar_rw = 1,
+ .tsu = 1,
+ .csmr = 1,
++ .rx_csum = 1,
+ .select_mii = 1,
+ .magic = 1,
+ .cexcr = 1,
+--
+2.7.4
+
diff --git a/bsp/meta-rcar/meta-rcar-gen3-adas/recipes-kernel/linux/linux-renesas/0272-sh_eth-offload-RX-checksum-on-SH7763.patch b/bsp/meta-rcar/meta-rcar-gen3-adas/recipes-kernel/linux/linux-renesas/0272-sh_eth-offload-RX-checksum-on-SH7763.patch
new file mode 100644
index 00000000..40851dc3
--- /dev/null
+++ b/bsp/meta-rcar/meta-rcar-gen3-adas/recipes-kernel/linux/linux-renesas/0272-sh_eth-offload-RX-checksum-on-SH7763.patch
@@ -0,0 +1,31 @@
+From df34c845a5a29bdca6efdf4245e95329995dfb9a Mon Sep 17 00:00:00 2001
+From: Sergei Shtylyov <sergei.shtylyov@cogentembedded.com>
+Date: Mon, 4 Feb 2019 21:12:39 +0300
+Subject: [PATCH 092/211] sh_eth: offload RX checksum on SH7763
+
+The SH7763 SoC manual describes the Ether MAC's RX checksum offload
+the same way as it's implemented in the EtherAVB MACs...
+
+Signed-off-by: Sergei Shtylyov <sergei.shtylyov@cogentembedded.com>
+Signed-off-by: David S. Miller <davem@davemloft.net>
+(cherry picked from commit 997feb11b83bd1c3b0100587a773629cabb83ce2)
+Signed-off-by: Valentine Barshak <valentine.barshak@cogentembedded.com>
+---
+ drivers/net/ethernet/renesas/sh_eth.c | 1 +
+ 1 file changed, 1 insertion(+)
+
+diff --git a/drivers/net/ethernet/renesas/sh_eth.c b/drivers/net/ethernet/renesas/sh_eth.c
+index 95fd30b..f969aa4 100644
+--- a/drivers/net/ethernet/renesas/sh_eth.c
++++ b/drivers/net/ethernet/renesas/sh_eth.c
+@@ -1063,6 +1063,7 @@ static struct sh_eth_cpu_data sh7763_data = {
+ .irq_flags = IRQF_SHARED,
+ .magic = 1,
+ .cexcr = 1,
++ .rx_csum = 1,
+ .dual_port = 1,
+ };
+
+--
+2.7.4
+
diff --git a/bsp/meta-rcar/meta-rcar-gen3-adas/recipes-kernel/linux/linux-renesas/0273-clk-renesas-rcar-gen3-Factor-out-cpg_reg_modify.patch b/bsp/meta-rcar/meta-rcar-gen3-adas/recipes-kernel/linux/linux-renesas/0273-clk-renesas-rcar-gen3-Factor-out-cpg_reg_modify.patch
new file mode 100644
index 00000000..3ee6b267
--- /dev/null
+++ b/bsp/meta-rcar/meta-rcar-gen3-adas/recipes-kernel/linux/linux-renesas/0273-clk-renesas-rcar-gen3-Factor-out-cpg_reg_modify.patch
@@ -0,0 +1,119 @@
+From 934ce0eb9a13d26c8c46b8af9ceea5912357dd79 Mon Sep 17 00:00:00 2001
+From: Sergei Shtylyov <sergei.shtylyov@cogentembedded.com>
+Date: Tue, 22 Jan 2019 22:57:38 +0300
+Subject: [PATCH 093/211] clk: renesas: rcar-gen3: Factor out cpg_reg_modify()
+
+There's quite often repeated sequence of a CPG register read-modify-write,
+so it seems worth factoring it out into a function -- this saves 68 bytes
+of the object code (AArch64 gcc 4.8.5) and simplifies protecting all such
+sequences with a spinlock in the next patch...
+
+Signed-off-by: Sergei Shtylyov <sergei.shtylyov@cogentembedded.com>
+Signed-off-by: Geert Uytterhoeven <geert+renesas@glider.be>
+(cherry picked from commit 8cb8f16c62e5ea9c77ca7d25af761f4eaea670ba)
+[valentine.barshak: resolved a minor conflict with cpg_quirks]
+Signed-off-by: Valentine Barshak <valentine.barshak@cogentembedded.com>
+---
+ drivers/clk/renesas/rcar-gen3-cpg.c | 38 +++++++++++++++++++------------------
+ 1 file changed, 20 insertions(+), 18 deletions(-)
+
+diff --git a/drivers/clk/renesas/rcar-gen3-cpg.c b/drivers/clk/renesas/rcar-gen3-cpg.c
+index d45437d..d99b666 100644
+--- a/drivers/clk/renesas/rcar-gen3-cpg.c
++++ b/drivers/clk/renesas/rcar-gen3-cpg.c
+@@ -46,6 +46,16 @@ static u32 cpg_quirks;
+ #define Z2FC_BIT_MASK_SFT_8 BIT(2) /* Use Z2FC bit mask range to [12:8] */
+ #define ZG_PARENT_PLL0 BIT(3) /* Use PLL0 as ZG clock parent */
+
++static void cpg_reg_modify(void __iomem *reg, u32 clear, u32 set)
++{
++ u32 val;
++
++ val = readl(reg);
++ val &= ~clear;
++ val |= set;
++ writel(val, reg);
++};
++
+ struct cpg_simple_notifier {
+ struct notifier_block nb;
+ void __iomem *reg;
+@@ -269,7 +279,6 @@ static int cpg_z_clk_set_rate(struct clk_hw *hw, unsigned long rate,
+ unsigned long prate = parent_rate / zclk->fixed_div;
+ unsigned int mult;
+ unsigned int i;
+- u32 val, kick;
+
+ if (!zclk->max_freq)
+ mult = DIV_ROUND_CLOSEST_ULL(rate * 32ULL, prate);
+@@ -283,17 +292,14 @@ static int cpg_z_clk_set_rate(struct clk_hw *hw, unsigned long rate,
+ if (readl(zclk->kick_reg) & CPG_FRQCRB_KICK)
+ return -EBUSY;
+
+- val = readl(zclk->reg) & ~zclk->mask;
+- val |= ((32 - mult) << __ffs(zclk->mask)) & zclk->mask;
+- writel(val, zclk->reg);
++ cpg_reg_modify(zclk->reg, zclk->mask,
++ ((32 - mult) << __ffs(zclk->mask)) & zclk->mask);
+
+ /*
+ * Set KICK bit in FRQCRB to update hardware setting and wait for
+ * clock change completion.
+ */
+- kick = readl(zclk->kick_reg);
+- kick |= CPG_FRQCRB_KICK;
+- writel(kick, zclk->kick_reg);
++ cpg_reg_modify(zclk->kick_reg, 0, CPG_FRQCRB_KICK);
+
+ /*
+ * Note: There is no HW information about the worst case latency.
+@@ -568,12 +574,10 @@ static const struct sd_div_table cpg_sd_div_table[] = {
+ static int cpg_sd_clock_enable(struct clk_hw *hw)
+ {
+ struct sd_clock *clock = to_sd_clock(hw);
+- u32 val = readl(clock->csn.reg);
+
+- val &= ~(CPG_SD_STP_MASK);
+- val |= clock->div_table[clock->cur_div_idx].val & CPG_SD_STP_MASK;
+-
+- writel(val, clock->csn.reg);
++ cpg_reg_modify(clock->csn.reg, CPG_SD_STP_MASK,
++ clock->div_table[clock->cur_div_idx].val &
++ CPG_SD_STP_MASK);
+
+ return 0;
+ }
+@@ -582,7 +586,7 @@ static void cpg_sd_clock_disable(struct clk_hw *hw)
+ {
+ struct sd_clock *clock = to_sd_clock(hw);
+
+- writel(readl(clock->csn.reg) | CPG_SD_STP_MASK, clock->csn.reg);
++ cpg_reg_modify(clock->csn.reg, 0, CPG_SD_STP_MASK);
+ }
+
+ static int cpg_sd_clock_is_enabled(struct clk_hw *hw)
+@@ -635,7 +639,6 @@ static int cpg_sd_clock_set_rate(struct clk_hw *hw, unsigned long rate,
+ {
+ struct sd_clock *clock = to_sd_clock(hw);
+ unsigned int div = cpg_sd_clock_calc_div(clock, rate, parent_rate);
+- u32 val;
+ unsigned int i;
+
+ for (i = 0; i < clock->div_num; i++)
+@@ -647,10 +650,9 @@ static int cpg_sd_clock_set_rate(struct clk_hw *hw, unsigned long rate,
+
+ clock->cur_div_idx = i;
+
+- val = readl(clock->csn.reg);
+- val &= ~(CPG_SD_STP_MASK | CPG_SD_FC_MASK);
+- val |= clock->div_table[i].val & (CPG_SD_STP_MASK | CPG_SD_FC_MASK);
+- writel(val, clock->csn.reg);
++ cpg_reg_modify(clock->csn.reg, CPG_SD_STP_MASK | CPG_SD_FC_MASK,
++ clock->div_table[i].val &
++ (CPG_SD_STP_MASK | CPG_SD_FC_MASK));
+
+ return 0;
+ }
+--
+2.7.4
+
diff --git a/bsp/meta-rcar/meta-rcar-gen3-adas/recipes-kernel/linux/linux-renesas/0274-clk-renesas-rcar-gen3-Add-spinlock.patch b/bsp/meta-rcar/meta-rcar-gen3-adas/recipes-kernel/linux/linux-renesas/0274-clk-renesas-rcar-gen3-Add-spinlock.patch
new file mode 100644
index 00000000..b6b889c5
--- /dev/null
+++ b/bsp/meta-rcar/meta-rcar-gen3-adas/recipes-kernel/linux/linux-renesas/0274-clk-renesas-rcar-gen3-Add-spinlock.patch
@@ -0,0 +1,52 @@
+From da07480ffaecd44e65f4361dc375f428f8889e22 Mon Sep 17 00:00:00 2001
+From: Sergei Shtylyov <sergei.shtylyov@cogentembedded.com>
+Date: Tue, 22 Jan 2019 22:58:38 +0300
+Subject: [PATCH 094/211] clk: renesas: rcar-gen3: Add spinlock
+
+Protect the CPG register read-modify-write sequence with a spinlock.
+
+Signed-off-by: Sergei Shtylyov <sergei.shtylyov@cogentembedded.com>
+Signed-off-by: Geert Uytterhoeven <geert+renesas@glider.be>
+(cherry picked from commit 875e8f6b0156c0ad56fd0c29c78e3f2f67ec0b16)
+[valentine.barshak: resolved a minor conflict with cpg_quirks]
+Signed-off-by: Valentine Barshak <valentine.barshak@cogentembedded.com>
+---
+ drivers/clk/renesas/rcar-gen3-cpg.c | 8 ++++++++
+ 1 file changed, 8 insertions(+)
+
+diff --git a/drivers/clk/renesas/rcar-gen3-cpg.c b/drivers/clk/renesas/rcar-gen3-cpg.c
+index d99b666..8e41380 100644
+--- a/drivers/clk/renesas/rcar-gen3-cpg.c
++++ b/drivers/clk/renesas/rcar-gen3-cpg.c
+@@ -46,14 +46,19 @@ static u32 cpg_quirks;
+ #define Z2FC_BIT_MASK_SFT_8 BIT(2) /* Use Z2FC bit mask range to [12:8] */
+ #define ZG_PARENT_PLL0 BIT(3) /* Use PLL0 as ZG clock parent */
+
++static spinlock_t cpg_lock;
++
+ static void cpg_reg_modify(void __iomem *reg, u32 clear, u32 set)
+ {
++ unsigned long flags;
+ u32 val;
+
++ spin_lock_irqsave(&cpg_lock, flags);
+ val = readl(reg);
+ val &= ~clear;
+ val |= set;
+ writel(val, reg);
++ spin_unlock_irqrestore(&cpg_lock, flags);
+ };
+
+ struct cpg_simple_notifier {
+@@ -911,5 +916,8 @@ int __init rcar_gen3_cpg_init(const struct rcar_gen3_cpg_pll_config *config,
+ if (attr)
+ cpg_quirks = (uintptr_t)attr->data;
+ pr_debug("%s: mode = 0x%x quirks = 0x%x\n", __func__, mode, cpg_quirks);
++
++ spin_lock_init(&cpg_lock);
++
+ return 0;
+ }
+--
+2.7.4
+
diff --git a/bsp/meta-rcar/meta-rcar-gen3-adas/recipes-kernel/linux/linux-renesas/0275-clk-renesas-rcar-gen3-Add-RPC-clocks.patch b/bsp/meta-rcar/meta-rcar-gen3-adas/recipes-kernel/linux/linux-renesas/0275-clk-renesas-rcar-gen3-Add-RPC-clocks.patch
new file mode 100644
index 00000000..813e0c27
--- /dev/null
+++ b/bsp/meta-rcar/meta-rcar-gen3-adas/recipes-kernel/linux/linux-renesas/0275-clk-renesas-rcar-gen3-Add-RPC-clocks.patch
@@ -0,0 +1,169 @@
+From c4d21aa145e4a995725af98d273eb33f63013082 Mon Sep 17 00:00:00 2001
+From: Sergei Shtylyov <sergei.shtylyov@cogentembedded.com>
+Date: Tue, 22 Jan 2019 22:59:35 +0300
+Subject: [PATCH 095/211] clk: renesas: rcar-gen3: Add RPC clocks
+
+The RPCSRC internal clock is controlled by the RPCCKCR.DIV[4:3] on all
+the R-Car gen3 SoCs except V3M (R8A77970) but the encoding of this field
+is different between SoCs; it makes sense to support the most common case
+of this encoding in the R-Car gen3 CPG driver...
+
+After adding the RPCSRC clock, we can add the RPC[D2] clocks derived from
+it and controlled by the RPCCKCR register on all the R-Car gen3 SoCs except
+V3M (R8A77970); the composite clock driver seems handy for this task, using
+the spinlock added in the previous patch...
+
+Signed-off-by: Sergei Shtylyov <sergei.shtylyov@cogentembedded.com>
+Signed-off-by: Geert Uytterhoeven <geert+renesas@glider.be>
+(cherry picked from commit db4a0073cc82a95d8d1a9b05fde82355fcce77d8)
+[valentine.barshak: resolved minor conflicts]
+Signed-off-by: Valentine Barshak <valentine.barshak@cogentembedded.com>
+---
+ drivers/clk/renesas/rcar-gen3-cpg.c | 101 ++++++++++++++++++++++++++++++++++++
+ drivers/clk/renesas/rcar-gen3-cpg.h | 4 ++
+ 2 files changed, 105 insertions(+)
+
+diff --git a/drivers/clk/renesas/rcar-gen3-cpg.c b/drivers/clk/renesas/rcar-gen3-cpg.c
+index 8e41380..c73b269 100644
+--- a/drivers/clk/renesas/rcar-gen3-cpg.c
++++ b/drivers/clk/renesas/rcar-gen3-cpg.c
+@@ -720,6 +720,92 @@ static struct clk * __init cpg_sd_clk_register(const struct cpg_core_clk *core,
+ return clk;
+ }
+
++struct rpc_clock {
++ struct clk_divider div;
++ struct clk_gate gate;
++ /*
++ * One notifier covers both RPC and RPCD2 clocks as they are both
++ * controlled by the same RPCCKCR register...
++ */
++ struct cpg_simple_notifier csn;
++};
++
++static const struct clk_div_table cpg_rpcsrc_div_table[] = {
++ { 2, 5 }, { 3, 6 }, { 0, 0 },
++};
++
++static const struct clk_div_table cpg_rpc_div_table[] = {
++ { 1, 2 }, { 3, 4 }, { 5, 6 }, { 7, 8 }, { 0, 0 },
++};
++
++static struct clk * __init cpg_rpc_clk_register(const char *name,
++ void __iomem *base, const char *parent_name,
++ struct raw_notifier_head *notifiers)
++{
++ struct rpc_clock *rpc;
++ struct clk *clk;
++
++ rpc = kzalloc(sizeof(*rpc), GFP_KERNEL);
++ if (!rpc)
++ return ERR_PTR(-ENOMEM);
++
++ rpc->div.reg = base + CPG_RPCCKCR;
++ rpc->div.width = 3;
++ rpc->div.table = cpg_rpc_div_table;
++ rpc->div.lock = &cpg_lock;
++
++ rpc->gate.reg = base + CPG_RPCCKCR;
++ rpc->gate.bit_idx = 8;
++ rpc->gate.flags = CLK_GATE_SET_TO_DISABLE;
++ rpc->gate.lock = &cpg_lock;
++
++ rpc->csn.reg = base + CPG_RPCCKCR;
++
++ clk = clk_register_composite(NULL, name, &parent_name, 1, NULL, NULL,
++ &rpc->div.hw, &clk_divider_ops,
++ &rpc->gate.hw, &clk_gate_ops, 0);
++ if (IS_ERR(clk)) {
++ kfree(rpc);
++ return clk;
++ }
++
++ cpg_simple_notifier_register(notifiers, &rpc->csn);
++ return clk;
++}
++
++struct rpcd2_clock {
++ struct clk_fixed_factor fixed;
++ struct clk_gate gate;
++};
++
++static struct clk * __init cpg_rpcd2_clk_register(const char *name,
++ void __iomem *base,
++ const char *parent_name)
++{
++ struct rpcd2_clock *rpcd2;
++ struct clk *clk;
++
++ rpcd2 = kzalloc(sizeof(*rpcd2), GFP_KERNEL);
++ if (!rpcd2)
++ return ERR_PTR(-ENOMEM);
++
++ rpcd2->fixed.mult = 1;
++ rpcd2->fixed.div = 2;
++
++ rpcd2->gate.reg = base + CPG_RPCCKCR;
++ rpcd2->gate.bit_idx = 9;
++ rpcd2->gate.flags = CLK_GATE_SET_TO_DISABLE;
++ rpcd2->gate.lock = &cpg_lock;
++
++ clk = clk_register_composite(NULL, name, &parent_name, 1, NULL, NULL,
++ &rpcd2->fixed.hw, &clk_fixed_factor_ops,
++ &rpcd2->gate.hw, &clk_gate_ops, 0);
++ if (IS_ERR(clk))
++ kfree(rpcd2);
++
++ return clk;
++}
++
+ static const struct rcar_gen3_cpg_pll_config *cpg_pll_config __initdata;
+ static unsigned int cpg_clk_extalr __initdata;
+ static u32 cpg_mode __initdata;
+@@ -896,6 +982,21 @@ struct clk * __init rcar_gen3_cpg_clk_register(struct device *dev,
+ return cpg_zg_clk_register(core->name, __clk_get_name(parent),
+ base, core->div);
+
++ case CLK_TYPE_GEN3_RPCSRC:
++ return clk_register_divider_table(NULL, core->name,
++ __clk_get_name(parent), 0,
++ base + CPG_RPCCKCR, 3, 2, 0,
++ cpg_rpcsrc_div_table,
++ &cpg_lock);
++
++ case CLK_TYPE_GEN3_RPC:
++ return cpg_rpc_clk_register(core->name, base,
++ __clk_get_name(parent), notifiers);
++
++ case CLK_TYPE_GEN3_RPCD2:
++ return cpg_rpcd2_clk_register(core->name, base,
++ __clk_get_name(parent));
++
+ default:
+ return ERR_PTR(-EINVAL);
+ }
+diff --git a/drivers/clk/renesas/rcar-gen3-cpg.h b/drivers/clk/renesas/rcar-gen3-cpg.h
+index 8834afe..a39c11a 100644
+--- a/drivers/clk/renesas/rcar-gen3-cpg.h
++++ b/drivers/clk/renesas/rcar-gen3-cpg.h
+@@ -27,6 +27,9 @@ enum rcar_gen3_clk_types {
+ CLK_TYPE_GEN3_ZG,
+ CLK_TYPE_GEN3_OSC, /* OSC EXTAL predivider and fixed divider */
+ CLK_TYPE_GEN3_RCKSEL, /* Select parent/divider using RCKCR.CKSEL */
++ CLK_TYPE_GEN3_RPCSRC,
++ CLK_TYPE_GEN3_RPC,
++ CLK_TYPE_GEN3_RPCD2,
+
+ /* SoC specific definitions start here */
+ CLK_TYPE_GEN3_SOC_BASE,
+@@ -64,6 +67,7 @@ struct rcar_gen3_cpg_pll_config {
+ u8 osc_prediv;
+ };
+
++#define CPG_RPCCKCR 0x238
+ #define CPG_RCKCR 0x240
+
+ struct clk *rcar_gen3_cpg_clk_register(struct device *dev,
+--
+2.7.4
+
diff --git a/bsp/meta-rcar/meta-rcar-gen3-adas/recipes-kernel/linux/linux-renesas/0276-clk-renesas-r8a77980-Add-RPC-clocks.patch b/bsp/meta-rcar/meta-rcar-gen3-adas/recipes-kernel/linux/linux-renesas/0276-clk-renesas-r8a77980-Add-RPC-clocks.patch
new file mode 100644
index 00000000..a589bc56
--- /dev/null
+++ b/bsp/meta-rcar/meta-rcar-gen3-adas/recipes-kernel/linux/linux-renesas/0276-clk-renesas-r8a77980-Add-RPC-clocks.patch
@@ -0,0 +1,55 @@
+From a00e5d2291fba5c3df1164f33b9e75333a9697e0 Mon Sep 17 00:00:00 2001
+From: Sergei Shtylyov <sergei.shtylyov@cogentembedded.com>
+Date: Tue, 22 Jan 2019 23:01:07 +0300
+Subject: [PATCH 096/211] clk: renesas: r8a77980: Add RPC clocks
+
+Describe the RPCSRC internal clock and the RPC[D2] clocks derived from it,
+as well as the RPC-IF module clock, in the R-Car V3H (R8A77980) CPG/MSSR
+driver.
+
+Signed-off-by: Sergei Shtylyov <sergei.shtylyov@cogentembedded.com>
+Signed-off-by: Geert Uytterhoeven <geert+renesas@glider.be>
+(cherry picked from commit 94e3935b5756a790396b57c7a5116460db511b29)
+Signed-off-by: Valentine Barshak <valentine.barshak@cogentembedded.com>
+---
+ drivers/clk/renesas/r8a77980-cpg-mssr.c | 8 ++++++++
+ 1 file changed, 8 insertions(+)
+
+diff --git a/drivers/clk/renesas/r8a77980-cpg-mssr.c b/drivers/clk/renesas/r8a77980-cpg-mssr.c
+index 25a3083..f9e07fc 100644
+--- a/drivers/clk/renesas/r8a77980-cpg-mssr.c
++++ b/drivers/clk/renesas/r8a77980-cpg-mssr.c
+@@ -41,6 +41,7 @@ enum clk_ids {
+ CLK_S2,
+ CLK_S3,
+ CLK_SDSRC,
++ CLK_RPCSRC,
+ CLK_OCO,
+
+ /* Module Clocks */
+@@ -65,8 +66,14 @@ static const struct cpg_core_clk r8a77980_core_clks[] __initconst = {
+ DEF_FIXED(".s2", CLK_S2, CLK_PLL1_DIV2, 4, 1),
+ DEF_FIXED(".s3", CLK_S3, CLK_PLL1_DIV2, 6, 1),
+ DEF_FIXED(".sdsrc", CLK_SDSRC, CLK_PLL1_DIV2, 2, 1),
++ DEF_BASE(".rpcsrc", CLK_RPCSRC, CLK_TYPE_GEN3_RPCSRC, CLK_PLL1),
+ DEF_RATE(".oco", CLK_OCO, 32768),
+
++ DEF_BASE("rpc", R8A77980_CLK_RPC, CLK_TYPE_GEN3_RPC,
++ CLK_RPCSRC),
++ DEF_BASE("rpcd2", R8A77980_CLK_RPCD2, CLK_TYPE_GEN3_RPCD2,
++ R8A77980_CLK_RPC),
++
+ /* Core Clock Outputs */
+ DEF_FIXED("ztr", R8A77980_CLK_ZTR, CLK_PLL1_DIV2, 6, 1),
+ DEF_FIXED("ztrd2", R8A77980_CLK_ZTRD2, CLK_PLL1_DIV2, 12, 1),
+@@ -164,6 +171,7 @@ static const struct mssr_mod_clk r8a77980_mod_clks[] __initconst = {
+ DEF_MOD("gpio1", 911, R8A77980_CLK_CP),
+ DEF_MOD("gpio0", 912, R8A77980_CLK_CP),
+ DEF_MOD("can-fd", 914, R8A77980_CLK_S3D2),
++ DEF_MOD("rpc-if", 917, R8A77980_CLK_RPC),
+ DEF_MOD("i2c4", 927, R8A77980_CLK_S0D6),
+ DEF_MOD("i2c3", 928, R8A77980_CLK_S0D6),
+ DEF_MOD("i2c2", 929, R8A77980_CLK_S3D2),
+--
+2.7.4
+
diff --git a/bsp/meta-rcar/meta-rcar-gen3-adas/recipes-kernel/linux/linux-renesas/0277-pinctrl-sh-pfc-r8a77970-Rename-IOCTRLx-registers.patch b/bsp/meta-rcar/meta-rcar-gen3-adas/recipes-kernel/linux/linux-renesas/0277-pinctrl-sh-pfc-r8a77970-Rename-IOCTRLx-registers.patch
new file mode 100644
index 00000000..dcb23351
--- /dev/null
+++ b/bsp/meta-rcar/meta-rcar-gen3-adas/recipes-kernel/linux/linux-renesas/0277-pinctrl-sh-pfc-r8a77970-Rename-IOCTRLx-registers.patch
@@ -0,0 +1,65 @@
+From 7e60a2c1600ba242739092dba055235ca5be1872 Mon Sep 17 00:00:00 2001
+From: Geert Uytterhoeven <geert+renesas@glider.be>
+Date: Mon, 18 Feb 2019 10:35:39 +0100
+Subject: [PATCH 097/211] pinctrl: sh-pfc: r8a77970: Rename IOCTRLx registers
+
+The R-Car Gen3 HardWare Manual Errata for Rev. 1.00 (Jul 2, 2018)
+renamed the various miscellaneous I/O control registers (IOCTRLx) on
+R-Car V3M, to reflect better their actual purposes, and matching other
+SoCs.
+
+Update the code to match this.
+
+Signed-off-by: Geert Uytterhoeven <geert+renesas@glider.be>
+Reviewed-by: Ulrich Hecht <uli+renesas@fpond.eu>
+(cherry picked from commit 1c5c1101755c5ed9f1e74763dbf39c01c3dc7cf8)
+Signed-off-by: Valentine Barshak <valentine.barshak@cogentembedded.com>
+---
+ drivers/pinctrl/sh-pfc/pfc-r8a77970.c | 16 ++++++++--------
+ 1 file changed, 8 insertions(+), 8 deletions(-)
+
+diff --git a/drivers/pinctrl/sh-pfc/pfc-r8a77970.c b/drivers/pinctrl/sh-pfc/pfc-r8a77970.c
+index 53ad813..a609949 100644
+--- a/drivers/pinctrl/sh-pfc/pfc-r8a77970.c
++++ b/drivers/pinctrl/sh-pfc/pfc-r8a77970.c
+@@ -2409,15 +2409,15 @@ static const struct pinmux_cfg_reg pinmux_config_regs[] = {
+ };
+
+ enum ioctrl_regs {
+- IOCTRL30,
+- IOCTRL31,
+- IOCTRL32,
++ POCCTRL0,
++ POCCTRL1,
++ POCCTRL2,
+ };
+
+ static const struct pinmux_ioctrl_reg pinmux_ioctrl_regs[] = {
+- [IOCTRL30] = { 0xe6060380 },
+- [IOCTRL31] = { 0xe6060384 },
+- [IOCTRL32] = { 0xe6060388 },
++ [POCCTRL0] = { 0xe6060380 },
++ [POCCTRL1] = { 0xe6060384 },
++ [POCCTRL2] = { 0xe6060388 },
+ { /* sentinel */ },
+ };
+
+@@ -2426,13 +2426,13 @@ static int r8a77970_pin_to_pocctrl(struct sh_pfc *pfc, unsigned int pin,
+ {
+ int bit = pin & 0x1f;
+
+- *pocctrl = pinmux_ioctrl_regs[IOCTRL30].reg;
++ *pocctrl = pinmux_ioctrl_regs[POCCTRL0].reg;
+ if (pin >= RCAR_GP_PIN(0, 0) && pin <= RCAR_GP_PIN(0, 21))
+ return bit;
+ if (pin >= RCAR_GP_PIN(2, 0) && pin <= RCAR_GP_PIN(2, 9))
+ return bit + 22;
+
+- *pocctrl = pinmux_ioctrl_regs[IOCTRL31].reg;
++ *pocctrl = pinmux_ioctrl_regs[POCCTRL1].reg;
+ if (pin >= RCAR_GP_PIN(2, 10) && pin <= RCAR_GP_PIN(2, 16))
+ return bit - 10;
+ if (pin >= RCAR_GP_PIN(3, 0) && pin <= RCAR_GP_PIN(3, 16))
+--
+2.7.4
+
diff --git a/bsp/meta-rcar/meta-rcar-gen3-adas/recipes-kernel/linux/linux-renesas/0278-pinctrl-sh-pfc-r8a77980-Rename-IOCTRLx-registers.patch b/bsp/meta-rcar/meta-rcar-gen3-adas/recipes-kernel/linux/linux-renesas/0278-pinctrl-sh-pfc-r8a77980-Rename-IOCTRLx-registers.patch
new file mode 100644
index 00000000..c7ac6882
--- /dev/null
+++ b/bsp/meta-rcar/meta-rcar-gen3-adas/recipes-kernel/linux/linux-renesas/0278-pinctrl-sh-pfc-r8a77980-Rename-IOCTRLx-registers.patch
@@ -0,0 +1,77 @@
+From 8f0ff040259e8d24830c87cd8d2e5f262de9cb92 Mon Sep 17 00:00:00 2001
+From: Geert Uytterhoeven <geert+renesas@glider.be>
+Date: Mon, 18 Feb 2019 10:42:21 +0100
+Subject: [PATCH 098/211] pinctrl: sh-pfc: r8a77980: Rename IOCTRLx registers
+
+The R-Car Gen3 HardWare Manual Errata for Rev. 1.00 (Jul 2, 2018)
+renamed the various miscellaneous I/O control registers (IOCTRLx) on
+R-Car V3H, to reflect better their actual purposes, and matching other
+SoCs.
+
+Update the code to match this.
+
+Signed-off-by: Geert Uytterhoeven <geert+renesas@glider.be>
+Reviewed-by: Ulrich Hecht <uli+renesas@fpond.eu>
+(cherry picked from commit a8d728a0c59cd508b3cdcef8950409089156bf70)
+Signed-off-by: Valentine Barshak <valentine.barshak@cogentembedded.com>
+---
+ drivers/pinctrl/sh-pfc/pfc-r8a77980.c | 22 +++++++++++-----------
+ 1 file changed, 11 insertions(+), 11 deletions(-)
+
+diff --git a/drivers/pinctrl/sh-pfc/pfc-r8a77980.c b/drivers/pinctrl/sh-pfc/pfc-r8a77980.c
+index b807b67a..1dcc508 100644
+--- a/drivers/pinctrl/sh-pfc/pfc-r8a77980.c
++++ b/drivers/pinctrl/sh-pfc/pfc-r8a77980.c
+@@ -2828,17 +2828,17 @@ static const struct pinmux_cfg_reg pinmux_config_regs[] = {
+ };
+
+ enum ioctrl_regs {
+- IOCTRL30,
+- IOCTRL31,
+- IOCTRL32,
+- IOCTRL33,
++ POCCTRL0,
++ POCCTRL1,
++ POCCTRL2,
++ POCCTRL3,
+ };
+
+ static const struct pinmux_ioctrl_reg pinmux_ioctrl_regs[] = {
+- [IOCTRL30] = { 0xe6060380, },
+- [IOCTRL31] = { 0xe6060384, },
+- [IOCTRL32] = { 0xe6060388, },
+- [IOCTRL33] = { 0xe606038c, },
++ [POCCTRL0] = { 0xe6060380, },
++ [POCCTRL1] = { 0xe6060384, },
++ [POCCTRL2] = { 0xe6060388, },
++ [POCCTRL3] = { 0xe606038c, },
+ { /* sentinel */ },
+ };
+
+@@ -2847,20 +2847,20 @@ static int r8a77980_pin_to_pocctrl(struct sh_pfc *pfc, unsigned int pin,
+ {
+ int bit = pin & 0x1f;
+
+- *pocctrl = pinmux_ioctrl_regs[IOCTRL30].reg;
++ *pocctrl = pinmux_ioctrl_regs[POCCTRL0].reg;
+ if (pin >= RCAR_GP_PIN(0, 0) && pin <= RCAR_GP_PIN(0, 21))
+ return bit;
+ else if (pin >= RCAR_GP_PIN(2, 0) && pin <= RCAR_GP_PIN(2, 9))
+ return bit + 22;
+
+- *pocctrl = pinmux_ioctrl_regs[IOCTRL31].reg;
++ *pocctrl = pinmux_ioctrl_regs[POCCTRL1].reg;
+ if (pin >= RCAR_GP_PIN(2, 10) && pin <= RCAR_GP_PIN(2, 16))
+ return bit - 10;
+ if ((pin >= RCAR_GP_PIN(2, 17) && pin <= RCAR_GP_PIN(2, 24)) ||
+ (pin >= RCAR_GP_PIN(3, 0) && pin <= RCAR_GP_PIN(3, 16)))
+ return bit + 7;
+
+- *pocctrl = pinmux_ioctrl_regs[IOCTRL32].reg;
++ *pocctrl = pinmux_ioctrl_regs[POCCTRL2].reg;
+ if (pin >= RCAR_GP_PIN(2, 25) && pin <= RCAR_GP_PIN(2, 29))
+ return pin - 25;
+
+--
+2.7.4
+
diff --git a/bsp/meta-rcar/meta-rcar-gen3-adas/recipes-kernel/linux/linux-renesas/0279-clk-renesas-r8a77980-Fix-RPC-IF-module-clock-s-paren.patch b/bsp/meta-rcar/meta-rcar-gen3-adas/recipes-kernel/linux/linux-renesas/0279-clk-renesas-r8a77980-Fix-RPC-IF-module-clock-s-paren.patch
new file mode 100644
index 00000000..06387d96
--- /dev/null
+++ b/bsp/meta-rcar/meta-rcar-gen3-adas/recipes-kernel/linux/linux-renesas/0279-clk-renesas-r8a77980-Fix-RPC-IF-module-clock-s-paren.patch
@@ -0,0 +1,34 @@
+From 9ae10e7766a229a577973da7c2c04234a9772810 Mon Sep 17 00:00:00 2001
+From: Sergei Shtylyov <sergei.shtylyov@cogentembedded.com>
+Date: Thu, 7 Mar 2019 22:53:19 +0300
+Subject: [PATCH 099/211] clk: renesas: r8a77980: Fix RPC-IF module clock's
+ parent
+
+Testing has shown that the RPC-IF module clock's parent is the RPCD2
+clock, not the RPC one -- the RPC-IF register reads stall otherwise...
+
+Fixes: 94e3935b5756 ("clk: renesas: r8a77980: Add RPC clocks")
+Signed-off-by: Sergei Shtylyov <sergei.shtylyov@cogentembedded.com>
+Signed-off-by: Geert Uytterhoeven <geert+renesas@glider.be>
+(cherry picked from commit 21ab095cbc069a351fa9cef919f2dafc43a8fde7)
+Signed-off-by: Valentine Barshak <valentine.barshak@cogentembedded.com>
+---
+ drivers/clk/renesas/r8a77980-cpg-mssr.c | 2 +-
+ 1 file changed, 1 insertion(+), 1 deletion(-)
+
+diff --git a/drivers/clk/renesas/r8a77980-cpg-mssr.c b/drivers/clk/renesas/r8a77980-cpg-mssr.c
+index f9e07fc..7227f67 100644
+--- a/drivers/clk/renesas/r8a77980-cpg-mssr.c
++++ b/drivers/clk/renesas/r8a77980-cpg-mssr.c
+@@ -171,7 +171,7 @@ static const struct mssr_mod_clk r8a77980_mod_clks[] __initconst = {
+ DEF_MOD("gpio1", 911, R8A77980_CLK_CP),
+ DEF_MOD("gpio0", 912, R8A77980_CLK_CP),
+ DEF_MOD("can-fd", 914, R8A77980_CLK_S3D2),
+- DEF_MOD("rpc-if", 917, R8A77980_CLK_RPC),
++ DEF_MOD("rpc-if", 917, R8A77980_CLK_RPCD2),
+ DEF_MOD("i2c4", 927, R8A77980_CLK_S0D6),
+ DEF_MOD("i2c3", 928, R8A77980_CLK_S0D6),
+ DEF_MOD("i2c2", 929, R8A77980_CLK_S3D2),
+--
+2.7.4
+
diff --git a/bsp/meta-rcar/meta-rcar-gen3-adas/recipes-kernel/linux/linux-renesas/0280-arm64-dts-renesas-r8a77980-Add-renesas-id-to-VIN.patch b/bsp/meta-rcar/meta-rcar-gen3-adas/recipes-kernel/linux/linux-renesas/0280-arm64-dts-renesas-r8a77980-Add-renesas-id-to-VIN.patch
new file mode 100644
index 00000000..8b4ebecd
--- /dev/null
+++ b/bsp/meta-rcar/meta-rcar-gen3-adas/recipes-kernel/linux/linux-renesas/0280-arm64-dts-renesas-r8a77980-Add-renesas-id-to-VIN.patch
@@ -0,0 +1,157 @@
+From 5046390d1114d716fece7508cc199516df4ee610 Mon Sep 17 00:00:00 2001
+From: Jacopo Mondi <jacopo+renesas@jmondi.org>
+Date: Fri, 12 Apr 2019 13:38:32 +0200
+Subject: [PATCH 100/211] arm64: dts: renesas: r8a77980: Add "renesas,id" to
+ VIN
+MIME-Version: 1.0
+Content-Type: text/plain; charset=UTF-8
+Content-Transfer-Encoding: 8bit
+
+Add the "renesas,id" property to VIN nodes in the R-Car V3H R8A77980
+device tree.
+
+Fixes: 3182aa4e0bf4 ("arm64: dts: renesas: r8a77980: add CSI2/VIN support")
+Signed-off-by: Jacopo Mondi <jacopo+renesas@jmondi.org>
+Reviewed-by: Niklas Söderlund <niklas.soderlund@ragnatech.se>
+Signed-off-by: Simon Horman <horms+renesas@verge.net.au>
+(cherry picked from commit b7f5a8e435ecc7198407f44a2a5a6cdae1056b0d)
+Signed-off-by: Valentine Barshak <valentine.barshak@cogentembedded.com>
+---
+ arch/arm64/boot/dts/renesas/r8a77980.dtsi | 16 ++++++++++++++++
+ 1 file changed, 16 insertions(+)
+
+diff --git a/arch/arm64/boot/dts/renesas/r8a77980.dtsi b/arch/arm64/boot/dts/renesas/r8a77980.dtsi
+index 4e019f7..1b56b1f 100644
+--- a/arch/arm64/boot/dts/renesas/r8a77980.dtsi
++++ b/arch/arm64/boot/dts/renesas/r8a77980.dtsi
+@@ -865,6 +865,7 @@
+ clocks = <&cpg CPG_MOD 811>;
+ power-domains = <&sysc R8A77980_PD_ALWAYS_ON>;
+ resets = <&cpg 811>;
++ renesas,id = <0>;
+ status = "disabled";
+
+ ports {
+@@ -892,6 +893,7 @@
+ clocks = <&cpg CPG_MOD 810>;
+ power-domains = <&sysc R8A77980_PD_ALWAYS_ON>;
+ status = "disabled";
++ renesas,id = <1>;
+ resets = <&cpg 810>;
+
+ ports {
+@@ -919,6 +921,7 @@
+ clocks = <&cpg CPG_MOD 809>;
+ power-domains = <&sysc R8A77980_PD_ALWAYS_ON>;
+ resets = <&cpg 809>;
++ renesas,id = <2>;
+ status = "disabled";
+
+ ports {
+@@ -946,6 +949,7 @@
+ clocks = <&cpg CPG_MOD 808>;
+ power-domains = <&sysc R8A77980_PD_ALWAYS_ON>;
+ resets = <&cpg 808>;
++ renesas,id = <3>;
+ status = "disabled";
+
+ ports {
+@@ -973,6 +977,7 @@
+ clocks = <&cpg CPG_MOD 807>;
+ power-domains = <&sysc R8A77980_PD_ALWAYS_ON>;
+ resets = <&cpg 807>;
++ renesas,id = <4>;
+ status = "disabled";
+
+ ports {
+@@ -1000,6 +1005,7 @@
+ clocks = <&cpg CPG_MOD 806>;
+ power-domains = <&sysc R8A77980_PD_ALWAYS_ON>;
+ resets = <&cpg 806>;
++ renesas,id = <5>;
+ status = "disabled";
+
+ ports {
+@@ -1027,6 +1033,7 @@
+ clocks = <&cpg CPG_MOD 805>;
+ power-domains = <&sysc R8A77980_PD_ALWAYS_ON>;
+ resets = <&cpg 805>;
++ renesas,id = <6>;
+ status = "disabled";
+
+ ports {
+@@ -1054,6 +1061,7 @@
+ clocks = <&cpg CPG_MOD 804>;
+ power-domains = <&sysc R8A77980_PD_ALWAYS_ON>;
+ resets = <&cpg 804>;
++ renesas,id = <7>;
+ status = "disabled";
+
+ ports {
+@@ -1081,6 +1089,7 @@
+ clocks = <&cpg CPG_MOD 628>;
+ power-domains = <&sysc R8A77980_PD_ALWAYS_ON>;
+ resets = <&cpg 628>;
++ renesas,id = <8>;
+ status = "disabled";
+ };
+
+@@ -1091,6 +1100,7 @@
+ clocks = <&cpg CPG_MOD 627>;
+ power-domains = <&sysc R8A77980_PD_ALWAYS_ON>;
+ resets = <&cpg 627>;
++ renesas,id = <9>;
+ status = "disabled";
+ };
+
+@@ -1101,6 +1111,7 @@
+ clocks = <&cpg CPG_MOD 625>;
+ power-domains = <&sysc R8A77980_PD_ALWAYS_ON>;
+ resets = <&cpg 625>;
++ renesas,id = <10>;
+ status = "disabled";
+ };
+
+@@ -1111,6 +1122,7 @@
+ clocks = <&cpg CPG_MOD 618>;
+ power-domains = <&sysc R8A77980_PD_ALWAYS_ON>;
+ resets = <&cpg 618>;
++ renesas,id = <11>;
+ status = "disabled";
+ };
+
+@@ -1121,6 +1133,7 @@
+ clocks = <&cpg CPG_MOD 612>;
+ power-domains = <&sysc R8A77980_PD_ALWAYS_ON>;
+ resets = <&cpg 612>;
++ renesas,id = <12>;
+ status = "disabled";
+ };
+
+@@ -1131,6 +1144,7 @@
+ clocks = <&cpg CPG_MOD 608>;
+ power-domains = <&sysc R8A77980_PD_ALWAYS_ON>;
+ resets = <&cpg 608>;
++ renesas,id = <13>;
+ status = "disabled";
+ };
+
+@@ -1141,6 +1155,7 @@
+ clocks = <&cpg CPG_MOD 605>;
+ power-domains = <&sysc R8A77980_PD_ALWAYS_ON>;
+ resets = <&cpg 605>;
++ renesas,id = <14>;
+ status = "disabled";
+ };
+
+@@ -1151,6 +1166,7 @@
+ clocks = <&cpg CPG_MOD 604>;
+ power-domains = <&sysc R8A77980_PD_ALWAYS_ON>;
+ resets = <&cpg 604>;
++ renesas,id = <15>;
+ status = "disabled";
+ };
+
+--
+2.7.4
+
diff --git a/bsp/meta-rcar/meta-rcar-gen3-adas/recipes-kernel/linux/linux-renesas/0281-arm64-dts-renesas-eagle-Add-x1-clock.patch b/bsp/meta-rcar/meta-rcar-gen3-adas/recipes-kernel/linux/linux-renesas/0281-arm64-dts-renesas-eagle-Add-x1-clock.patch
new file mode 100644
index 00000000..6a87090a
--- /dev/null
+++ b/bsp/meta-rcar/meta-rcar-gen3-adas/recipes-kernel/linux/linux-renesas/0281-arm64-dts-renesas-eagle-Add-x1-clock.patch
@@ -0,0 +1,43 @@
+From d4f29ab5f63ca7e588e9f064e2d551b20c810c60 Mon Sep 17 00:00:00 2001
+From: Valentine Barshak <valentine.barshak@cogentembedded.com>
+Date: Mon, 10 Jun 2019 16:08:07 +0300
+Subject: [PATCH 101/211] arm64: dts: renesas: eagle: Add x1 clock
+
+This adds X1 clock which supplies a frequency of 148.5 MHz.
+This clock is connected to the external dot clock input signal.
+
+Signed-off-by: Valentine Barshak <valentine.barshak@cogentembedded.com>
+---
+ arch/arm64/boot/dts/renesas/r8a77970-eagle.dts | 9 +++++++++
+ 1 file changed, 9 insertions(+)
+
+diff --git a/arch/arm64/boot/dts/renesas/r8a77970-eagle.dts b/arch/arm64/boot/dts/renesas/r8a77970-eagle.dts
+index b6d5332..800643b 100644
+--- a/arch/arm64/boot/dts/renesas/r8a77970-eagle.dts
++++ b/arch/arm64/boot/dts/renesas/r8a77970-eagle.dts
+@@ -73,6 +73,12 @@
+ };
+ };
+ };
++
++ x1_clk: x1-clock {
++ compatible = "fixed-clock";
++ #clock-cells = <0>;
++ clock-frequency = <148500000>;
++ };
+ };
+
+ &avb {
+@@ -192,6 +198,9 @@
+ };
+
+ &du {
++ clocks = <&cpg CPG_MOD 724>,
++ <&x1_clk>;
++ clock-names = "du.0", "dclkin.0";
+ status = "okay";
+ };
+
+--
+2.7.4
+
diff --git a/bsp/meta-rcar/meta-rcar-gen3-adas/recipes-kernel/linux/linux-renesas/0282-arm64-dts-renesas-r8a77980-condor-Add-GEther-support.patch b/bsp/meta-rcar/meta-rcar-gen3-adas/recipes-kernel/linux/linux-renesas/0282-arm64-dts-renesas-r8a77980-condor-Add-GEther-support.patch
new file mode 100644
index 00000000..679b9d0b
--- /dev/null
+++ b/bsp/meta-rcar/meta-rcar-gen3-adas/recipes-kernel/linux/linux-renesas/0282-arm64-dts-renesas-r8a77980-condor-Add-GEther-support.patch
@@ -0,0 +1,80 @@
+From f42db72c483cddaefd0196a0070882d40eeb52a7 Mon Sep 17 00:00:00 2001
+From: Valentine Barshak <valentine.barshak@cogentembedded.com>
+Date: Wed, 17 Oct 2018 22:26:12 +0300
+Subject: [PATCH 102/211] arm64: dts: renesas: r8a77980: condor: Add GEther
+ support
+
+This is based on commit eab53fdfd60a84b0cc514d4f1f5d79226c76df01
+from Sergei Shtylyov, which adds GEther support to the R8A77980
+Condor board. The difference is that instead of removing AVB
+Ethernet we just disable it. The official Condor boards have
+GEther support by default, so we use ethernet0 alias to GEther.
+
+Signed-off-by: Valentine Barshak <valentine.barshak@cogentembedded.com>
+---
+ arch/arm64/boot/dts/renesas/r8a77980-condor.dts | 28 +++++++++++++++++++++++--
+ 1 file changed, 26 insertions(+), 2 deletions(-)
+
+diff --git a/arch/arm64/boot/dts/renesas/r8a77980-condor.dts b/arch/arm64/boot/dts/renesas/r8a77980-condor.dts
+index fe2e2c0..738edf0 100644
+--- a/arch/arm64/boot/dts/renesas/r8a77980-condor.dts
++++ b/arch/arm64/boot/dts/renesas/r8a77980-condor.dts
+@@ -15,7 +15,8 @@
+
+ aliases {
+ serial0 = &scif0;
+- ethernet0 = &avb;
++ ethernet0 = &gether;
++ ethernet1 = &avb;
+ };
+
+ chosen {
+@@ -104,7 +105,7 @@
+ phy-mode = "rgmii-id";
+ phy-handle = <&phy0>;
+ renesas,no-ether-link;
+- status = "okay";
++ status = "disabled";
+
+ phy0: ethernet-phy@0 {
+ rxc-skew-ps = <1500>;
+@@ -139,6 +140,23 @@
+ clock-frequency = <32768>;
+ };
+
++&gether {
++ pinctrl-0 = <&gether_pins>;
++ pinctrl-names = "default";
++
++ phy-mode = "rgmii-id";
++ phy-handle = <&phy1>;
++ renesas,no-ether-link;
++ status = "okay";
++
++ phy1: ethernet-phy@1 {
++ rxc-skew-ps = <1500>;
++ reg = <0>;
++ interrupt-parent = <&gpio4>;
++ interrupts = <23 IRQ_TYPE_LEVEL_LOW>;
++ };
++};
++
+ &i2c0 {
+ pinctrl-0 = <&i2c0_pins>;
+ pinctrl-names = "default";
+@@ -246,6 +264,12 @@
+ function = "canfd0";
+ };
+
++ gether_pins: gether {
++ groups = "gether_mdio_a", "gether_rgmii",
++ "gether_txcrefclk", "gether_txcrefclk_mega";
++ function = "gether";
++ };
++
+ i2c0_pins: i2c0 {
+ groups = "i2c0";
+ function = "i2c0";
+--
+2.7.4
+
diff --git a/bsp/meta-rcar/meta-rcar-gen3-adas/recipes-kernel/linux/linux-renesas/0283-iommu-ipmmu-vmsa-Add-r8a77980-support.patch b/bsp/meta-rcar/meta-rcar-gen3-adas/recipes-kernel/linux/linux-renesas/0283-iommu-ipmmu-vmsa-Add-r8a77980-support.patch
new file mode 100644
index 00000000..06c19a60
--- /dev/null
+++ b/bsp/meta-rcar/meta-rcar-gen3-adas/recipes-kernel/linux/linux-renesas/0283-iommu-ipmmu-vmsa-Add-r8a77980-support.patch
@@ -0,0 +1,45 @@
+From 64a70b1e21ac951c879fbc7d2200f692a0e58afa Mon Sep 17 00:00:00 2001
+From: Valentine Barshak <valentine.barshak@cogentembedded.com>
+Date: Fri, 26 Oct 2018 23:49:18 +0300
+Subject: [PATCH 103/211] iommu: ipmmu-vmsa: Add r8a77980 support
+
+This adds R-Car V3H support to IPMMU VMSA driver.
+
+Signed-off-by: Valentine Barshak <valentine.barshak@cogentembedded.com>
+---
+ drivers/iommu/ipmmu-vmsa.c | 5 +++++
+ 1 file changed, 5 insertions(+)
+
+diff --git a/drivers/iommu/ipmmu-vmsa.c b/drivers/iommu/ipmmu-vmsa.c
+index 5844dc7..4a3055f 100644
+--- a/drivers/iommu/ipmmu-vmsa.c
++++ b/drivers/iommu/ipmmu-vmsa.c
+@@ -1123,6 +1123,7 @@ static const struct soc_device_attribute soc_rcar_gen3[] = {
+ { .soc_id = "r8a7796", },
+ { .soc_id = "r8a77965", },
+ { .soc_id = "r8a77970", },
++ { .soc_id = "r8a77980", },
+ { .soc_id = "r8a77990", },
+ { .soc_id = "r8a77995", },
+ { /* sentinel */ }
+@@ -1426,6 +1427,9 @@ static const struct of_device_id ipmmu_of_ids[] = {
+ .compatible = "renesas,ipmmu-r8a77970",
+ .data = &ipmmu_features_rcar_gen3,
+ }, {
++ .compatible = "renesas,ipmmu-r8a77980",
++ .data = &ipmmu_features_rcar_gen3,
++ }, {
+ .compatible = "renesas,ipmmu-r8a77990",
+ .data = &ipmmu_features_rcar_gen3,
+ }, {
+@@ -1866,6 +1870,7 @@ IOMMU_OF_DECLARE(ipmmu_r8a7795_iommu_of, "renesas,ipmmu-r8a7795");
+ IOMMU_OF_DECLARE(ipmmu_r8a7796_iommu_of, "renesas,ipmmu-r8a7796");
+ IOMMU_OF_DECLARE(ipmmu_r8a77965_iommu_of, "renesas,ipmmu-r8a77965");
+ IOMMU_OF_DECLARE(ipmmu_r8a77970_iommu_of, "renesas,ipmmu-r8a77970");
++IOMMU_OF_DECLARE(ipmmu_r8a77980_iommu_of, "renesas,ipmmu-r8a77980");
+ IOMMU_OF_DECLARE(ipmmu_r8a77990_iommu_of, "renesas,ipmmu-r8a77990");
+ IOMMU_OF_DECLARE(ipmmu_r8a77995_iommu_of, "renesas,ipmmu-r8a77995");
+
+--
+2.7.4
+
diff --git a/bsp/meta-rcar/meta-rcar-gen3-adas/recipes-kernel/linux/linux-renesas/0284-iommu-ipmmu-vmsa-Fix-NULL-pointer-dereference.patch b/bsp/meta-rcar/meta-rcar-gen3-adas/recipes-kernel/linux/linux-renesas/0284-iommu-ipmmu-vmsa-Fix-NULL-pointer-dereference.patch
new file mode 100644
index 00000000..fadd0d73
--- /dev/null
+++ b/bsp/meta-rcar/meta-rcar-gen3-adas/recipes-kernel/linux/linux-renesas/0284-iommu-ipmmu-vmsa-Fix-NULL-pointer-dereference.patch
@@ -0,0 +1,29 @@
+From 500bf0198a7cdfc9dc2b854715728ce74944cfec Mon Sep 17 00:00:00 2001
+From: Valentine Barshak <valentine.barshak@cogentembedded.com>
+Date: Tue, 25 Jun 2019 22:43:44 +0300
+Subject: [PATCH 104/211] iommu: ipmmu-vmsa: Fix NULL pointer dereference
+
+This fixes possible NULL pointer dereference
+in case no whitelist is initialized.
+
+Signed-off-by: Valentine Barshak <valentine.barshak@cogentembedded.com>
+---
+ drivers/iommu/ipmmu-vmsa.c | 2 +-
+ 1 file changed, 1 insertion(+), 1 deletion(-)
+
+diff --git a/drivers/iommu/ipmmu-vmsa.c b/drivers/iommu/ipmmu-vmsa.c
+index 4a3055f..cdbfc53 100644
+--- a/drivers/iommu/ipmmu-vmsa.c
++++ b/drivers/iommu/ipmmu-vmsa.c
+@@ -1485,7 +1485,7 @@ static int ipmmu_whitelist_init(struct ipmmu_vmsa_device *mmu)
+ else
+ mmu->whitelist = NULL;
+
+- if (!mmu->whitelist[0])
++ if (!mmu->whitelist)
+ return -1;
+
+ return ipmmu_bm_init(mmu);
+--
+2.7.4
+
diff --git a/bsp/meta-rcar/meta-rcar-gen3-adas/recipes-kernel/linux/linux-renesas/0285-iommu-ipmmu-vmsa-Add-r8a779-7-8-0-whitelist.patch b/bsp/meta-rcar/meta-rcar-gen3-adas/recipes-kernel/linux/linux-renesas/0285-iommu-ipmmu-vmsa-Add-r8a779-7-8-0-whitelist.patch
new file mode 100644
index 00000000..8ec4be85
--- /dev/null
+++ b/bsp/meta-rcar/meta-rcar-gen3-adas/recipes-kernel/linux/linux-renesas/0285-iommu-ipmmu-vmsa-Add-r8a779-7-8-0-whitelist.patch
@@ -0,0 +1,65 @@
+From 48a84430fd00e74e4a380324acd3f96b7a2873ad Mon Sep 17 00:00:00 2001
+From: Valentine Barshak <valentine.barshak@cogentembedded.com>
+Date: Tue, 25 Jun 2019 22:40:40 +0300
+Subject: [PATCH 105/211] iommu: ipmmu-vmsa: Add r8a779{7|8}0 whitelist
+
+This adds empty r8a779{7|8}0 whitelist disabling
+IPMMU on R-Car V3M and V3H SoCs.
+
+Signed-off-by: Valentine Barshak <valentine.barshak@cogentembedded.com>
+---
+ drivers/iommu/ipmmu-vmsa.c | 24 ++++++++++++++++++++++++
+ 1 file changed, 24 insertions(+)
+
+diff --git a/drivers/iommu/ipmmu-vmsa.c b/drivers/iommu/ipmmu-vmsa.c
+index cdbfc53..52e292a 100644
+--- a/drivers/iommu/ipmmu-vmsa.c
++++ b/drivers/iommu/ipmmu-vmsa.c
+@@ -243,6 +243,16 @@ static struct ipmmu_whitelist *r8a77965_whitelist[] = {
+ NULL, /* Terminator */
+ };
+
++/* R-Car E3 (R8A77970) */
++static struct ipmmu_whitelist *r8a77970_whitelist[] = {
++ NULL, /* Terminator */
++};
++
++/* R-Car E3 (R8A77980) */
++static struct ipmmu_whitelist *r8a77980_whitelist[] = {
++ NULL, /* Terminator */
++};
++
+ /* R-Car E3 (R8A77990) */
+ static struct ipmmu_whitelist r8a77990_ipmmu_vi0 = {
+ .ipmmu_name = "febd0000.mmu",
+@@ -1145,6 +1155,16 @@ static const struct soc_device_attribute r8a77965[] = {
+ { /* sentinel */ }
+ };
+
++static const struct soc_device_attribute r8a77970[] = {
++ { .soc_id = "r8a77970" },
++ { /* sentinel */ }
++};
++
++static const struct soc_device_attribute r8a77980[] = {
++ { .soc_id = "r8a77980" },
++ { /* sentinel */ }
++};
++
+ static const struct soc_device_attribute r8a77990[] = {
+ { .soc_id = "r8a77990" },
+ { /* sentinel */ }
+@@ -1482,6 +1502,10 @@ static int ipmmu_whitelist_init(struct ipmmu_vmsa_device *mmu)
+ mmu->whitelist = r8a77965_whitelist;
+ else if (soc_device_match(r8a77990))
+ mmu->whitelist = r8a77990_whitelist;
++ else if (soc_device_match(r8a77970))
++ mmu->whitelist = r8a77970_whitelist;
++ else if (soc_device_match(r8a77980))
++ mmu->whitelist = r8a77980_whitelist;
+ else
+ mmu->whitelist = NULL;
+
+--
+2.7.4
+
diff --git a/bsp/meta-rcar/meta-rcar-gen3-adas/recipes-kernel/linux/linux-renesas/0286-clk-renesas-r8a77980-cpg-mssr-Add-VIN-clocks.patch b/bsp/meta-rcar/meta-rcar-gen3-adas/recipes-kernel/linux/linux-renesas/0286-clk-renesas-r8a77980-cpg-mssr-Add-VIN-clocks.patch
new file mode 100644
index 00000000..c8ac9d86
--- /dev/null
+++ b/bsp/meta-rcar/meta-rcar-gen3-adas/recipes-kernel/linux/linux-renesas/0286-clk-renesas-r8a77980-cpg-mssr-Add-VIN-clocks.patch
@@ -0,0 +1,34 @@
+From a8feccd1f7457b094dcb0cad572d661e7e470740 Mon Sep 17 00:00:00 2001
+From: Valentine Barshak <valentine.barshak@cogentembedded.com>
+Date: Fri, 26 Oct 2018 19:21:28 +0300
+Subject: [PATCH 106/211] clk: renesas: r8a77980: cpg-mssr: Add VIN clocks
+
+This adds VIN clocks to R8A77980 CPG MSSR driver.
+
+Signed-off-by: Valentine Barshak <valentine.barshak@cogentembedded.com>
+---
+ drivers/clk/renesas/r8a77980-cpg-mssr.c | 8 ++++++++
+ 1 file changed, 8 insertions(+)
+
+diff --git a/drivers/clk/renesas/r8a77980-cpg-mssr.c b/drivers/clk/renesas/r8a77980-cpg-mssr.c
+index 7227f67..711a1c5 100644
+--- a/drivers/clk/renesas/r8a77980-cpg-mssr.c
++++ b/drivers/clk/renesas/r8a77980-cpg-mssr.c
+@@ -154,6 +154,14 @@ static const struct mssr_mod_clk r8a77980_mod_clks[] __initconst = {
+ DEF_MOD("csi40", 716, R8A77980_CLK_CSI0),
+ DEF_MOD("du0", 724, R8A77980_CLK_S2D1),
+ DEF_MOD("lvds", 727, R8A77980_CLK_S2D1),
++ DEF_MOD("vin7", 804, R8A77980_CLK_S2D1),
++ DEF_MOD("vin6", 805, R8A77980_CLK_S2D1),
++ DEF_MOD("vin5", 806, R8A77980_CLK_S2D1),
++ DEF_MOD("vin4", 807, R8A77980_CLK_S2D1),
++ DEF_MOD("vin3", 808, R8A77980_CLK_S2D1),
++ DEF_MOD("vin2", 809, R8A77980_CLK_S2D1),
++ DEF_MOD("vin1", 810, R8A77980_CLK_S2D1),
++ DEF_MOD("vin0", 811, R8A77980_CLK_S2D1),
+ DEF_MOD("etheravb", 812, R8A77980_CLK_S3D2),
+ DEF_MOD("gether", 813, R8A77980_CLK_S3D2),
+ DEF_MOD("imp3", 824, R8A77980_CLK_S1D1),
+--
+2.7.4
+
diff --git a/bsp/meta-rcar/meta-rcar-gen3-adas/recipes-kernel/linux/linux-renesas/0287-clk-renesas-r8a77970-cpg-mssr-Add-IMR-clocks.patch b/bsp/meta-rcar/meta-rcar-gen3-adas/recipes-kernel/linux/linux-renesas/0287-clk-renesas-r8a77970-cpg-mssr-Add-IMR-clocks.patch
new file mode 100644
index 00000000..ef035f5e
--- /dev/null
+++ b/bsp/meta-rcar/meta-rcar-gen3-adas/recipes-kernel/linux/linux-renesas/0287-clk-renesas-r8a77970-cpg-mssr-Add-IMR-clocks.patch
@@ -0,0 +1,30 @@
+From ab197e0f74638e62a8619cbf085055f438df5e5f Mon Sep 17 00:00:00 2001
+From: Valentine Barshak <valentine.barshak@cogentembedded.com>
+Date: Fri, 26 Oct 2018 19:14:40 +0300
+Subject: [PATCH 107/211] clk: renesas: r8a77970: cpg-mssr: Add IMR clocks
+
+This adds IMR clocks to R8A7790 CPG MSSR driver.
+
+Signed-off-by: Valentine Barshak <valentine.barshak@cogentembedded.com>
+---
+ drivers/clk/renesas/r8a77970-cpg-mssr.c | 4 ++++
+ 1 file changed, 4 insertions(+)
+
+diff --git a/drivers/clk/renesas/r8a77970-cpg-mssr.c b/drivers/clk/renesas/r8a77970-cpg-mssr.c
+index cbac67e..ab847ee 100644
+--- a/drivers/clk/renesas/r8a77970-cpg-mssr.c
++++ b/drivers/clk/renesas/r8a77970-cpg-mssr.c
+@@ -152,6 +152,10 @@ static const struct mssr_mod_clk r8a77970_mod_clks[] __initconst = {
+ DEF_MOD("vin1", 810, R8A77970_CLK_S2D1),
+ DEF_MOD("vin0", 811, R8A77970_CLK_S2D1),
+ DEF_MOD("etheravb", 812, R8A77970_CLK_S2D2),
++ DEF_MOD("imr3", 820, R8A77970_CLK_S2D1),
++ DEF_MOD("imr2", 821, R8A77970_CLK_S2D1),
++ DEF_MOD("imr1", 822, R8A77970_CLK_S2D1),
++ DEF_MOD("imr0", 823, R8A77970_CLK_S2D1),
+ DEF_MOD("gpio5", 907, R8A77970_CLK_CP),
+ DEF_MOD("gpio4", 908, R8A77970_CLK_CP),
+ DEF_MOD("gpio3", 909, R8A77970_CLK_CP),
+--
+2.7.4
+
diff --git a/bsp/meta-rcar/meta-rcar-gen3-adas/recipes-kernel/linux/linux-renesas/0288-clk-renesas-r8a77980-cpg-mssr-Add-IMR-clocks.patch b/bsp/meta-rcar/meta-rcar-gen3-adas/recipes-kernel/linux/linux-renesas/0288-clk-renesas-r8a77980-cpg-mssr-Add-IMR-clocks.patch
new file mode 100644
index 00000000..2bc5a100
--- /dev/null
+++ b/bsp/meta-rcar/meta-rcar-gen3-adas/recipes-kernel/linux/linux-renesas/0288-clk-renesas-r8a77980-cpg-mssr-Add-IMR-clocks.patch
@@ -0,0 +1,39 @@
+From a971c62087b1ffe2e074b832c7b4a0a584ffe09f Mon Sep 17 00:00:00 2001
+From: Valentine Barshak <valentine.barshak@cogentembedded.com>
+Date: Fri, 26 Oct 2018 19:23:58 +0300
+Subject: [PATCH 108/211] clk: renesas: r8a77980: cpg-mssr: Add IMR clocks
+
+This adds IMR clocks to R8A77980 CPG MSSR driver.
+
+Signed-off-by: Valentine Barshak <valentine.barshak@cogentembedded.com>
+---
+ drivers/clk/renesas/r8a77980-cpg-mssr.c | 6 ++++++
+ 1 file changed, 6 insertions(+)
+
+diff --git a/drivers/clk/renesas/r8a77980-cpg-mssr.c b/drivers/clk/renesas/r8a77980-cpg-mssr.c
+index 711a1c5..dfa947a 100644
+--- a/drivers/clk/renesas/r8a77980-cpg-mssr.c
++++ b/drivers/clk/renesas/r8a77980-cpg-mssr.c
+@@ -150,6 +150,8 @@ static const struct mssr_mod_clk r8a77980_mod_clks[] __initconst = {
+ DEF_MOD("imp-ocv2", 531, R8A77980_CLK_S1D1),
+ DEF_MOD("fcpvd0", 603, R8A77980_CLK_S3D1),
+ DEF_MOD("vspd0", 623, R8A77980_CLK_S3D1),
++ DEF_MOD("imr5", 706, R8A77980_CLK_S2D1),
++ DEF_MOD("imr4", 707, R8A77980_CLK_S2D1),
+ DEF_MOD("csi41", 715, R8A77980_CLK_CSI0),
+ DEF_MOD("csi40", 716, R8A77980_CLK_CSI0),
+ DEF_MOD("du0", 724, R8A77980_CLK_S2D1),
+@@ -164,6 +166,10 @@ static const struct mssr_mod_clk r8a77980_mod_clks[] __initconst = {
+ DEF_MOD("vin0", 811, R8A77980_CLK_S2D1),
+ DEF_MOD("etheravb", 812, R8A77980_CLK_S3D2),
+ DEF_MOD("gether", 813, R8A77980_CLK_S3D2),
++ DEF_MOD("imr3", 820, R8A77980_CLK_S2D1),
++ DEF_MOD("imr2", 821, R8A77980_CLK_S2D1),
++ DEF_MOD("imr1", 822, R8A77980_CLK_S2D1),
++ DEF_MOD("imr0", 823, R8A77980_CLK_S2D1),
+ DEF_MOD("imp3", 824, R8A77980_CLK_S1D1),
+ DEF_MOD("imp2", 825, R8A77980_CLK_S1D1),
+ DEF_MOD("imp1", 826, R8A77980_CLK_S1D1),
+--
+2.7.4
+
diff --git a/bsp/meta-rcar/meta-rcar-gen3-adas/recipes-kernel/linux/linux-renesas/0289-clk-renesas-r8a77970-cpg-mssr-Add-ISP-clock.patch b/bsp/meta-rcar/meta-rcar-gen3-adas/recipes-kernel/linux/linux-renesas/0289-clk-renesas-r8a77970-cpg-mssr-Add-ISP-clock.patch
new file mode 100644
index 00000000..7a2c8e79
--- /dev/null
+++ b/bsp/meta-rcar/meta-rcar-gen3-adas/recipes-kernel/linux/linux-renesas/0289-clk-renesas-r8a77970-cpg-mssr-Add-ISP-clock.patch
@@ -0,0 +1,27 @@
+From 58543097fab7bfb26c3f81ebb8cdfe8a29161c16 Mon Sep 17 00:00:00 2001
+From: Valentine Barshak <valentine.barshak@cogentembedded.com>
+Date: Mon, 29 Oct 2018 13:37:25 +0300
+Subject: [PATCH 109/211] clk: renesas: r8a77970: cpg-mssr: Add ISP clock
+
+This adds ISP clock.
+
+Signed-off-by: Valentine Barshak <valentine.barshak@cogentembedded.com>
+---
+ drivers/clk/renesas/r8a77970-cpg-mssr.c | 1 +
+ 1 file changed, 1 insertion(+)
+
+diff --git a/drivers/clk/renesas/r8a77970-cpg-mssr.c b/drivers/clk/renesas/r8a77970-cpg-mssr.c
+index ab847ee..5ae694b 100644
+--- a/drivers/clk/renesas/r8a77970-cpg-mssr.c
++++ b/drivers/clk/renesas/r8a77970-cpg-mssr.c
+@@ -152,6 +152,7 @@ static const struct mssr_mod_clk r8a77970_mod_clks[] __initconst = {
+ DEF_MOD("vin1", 810, R8A77970_CLK_S2D1),
+ DEF_MOD("vin0", 811, R8A77970_CLK_S2D1),
+ DEF_MOD("etheravb", 812, R8A77970_CLK_S2D2),
++ DEF_MOD("isp", 817, R8A77970_CLK_S2D1),
+ DEF_MOD("imr3", 820, R8A77970_CLK_S2D1),
+ DEF_MOD("imr2", 821, R8A77970_CLK_S2D1),
+ DEF_MOD("imr1", 822, R8A77970_CLK_S2D1),
+--
+2.7.4
+
diff --git a/bsp/meta-rcar/meta-rcar-gen3-adas/recipes-kernel/linux/linux-renesas/0290-clk-renesas-r8a77980-cpg-mssr-Add-ISP-clocks.patch b/bsp/meta-rcar/meta-rcar-gen3-adas/recipes-kernel/linux/linux-renesas/0290-clk-renesas-r8a77980-cpg-mssr-Add-ISP-clocks.patch
new file mode 100644
index 00000000..d0aa7eab
--- /dev/null
+++ b/bsp/meta-rcar/meta-rcar-gen3-adas/recipes-kernel/linux/linux-renesas/0290-clk-renesas-r8a77980-cpg-mssr-Add-ISP-clocks.patch
@@ -0,0 +1,28 @@
+From 4636088d830f0cf114e50ed997dcd8cdaf80f12f Mon Sep 17 00:00:00 2001
+From: Valentine Barshak <valentine.barshak@cogentembedded.com>
+Date: Mon, 29 Oct 2018 13:58:17 +0300
+Subject: [PATCH 110/211] clk: renesas: r8a77980: cpg-mssr: Add ISP clocks
+
+This adds ISP clocks.
+
+Signed-off-by: Valentine Barshak <valentine.barshak@cogentembedded.com>
+---
+ drivers/clk/renesas/r8a77980-cpg-mssr.c | 2 ++
+ 1 file changed, 2 insertions(+)
+
+diff --git a/drivers/clk/renesas/r8a77980-cpg-mssr.c b/drivers/clk/renesas/r8a77980-cpg-mssr.c
+index dfa947a..61ffe60 100644
+--- a/drivers/clk/renesas/r8a77980-cpg-mssr.c
++++ b/drivers/clk/renesas/r8a77980-cpg-mssr.c
+@@ -166,6 +166,8 @@ static const struct mssr_mod_clk r8a77980_mod_clks[] __initconst = {
+ DEF_MOD("vin0", 811, R8A77980_CLK_S2D1),
+ DEF_MOD("etheravb", 812, R8A77980_CLK_S3D2),
+ DEF_MOD("gether", 813, R8A77980_CLK_S3D2),
++ DEF_MOD("isp1", 814, R8A77980_CLK_S3D1),
++ DEF_MOD("isp0", 817, R8A77980_CLK_S3D1),
+ DEF_MOD("imr3", 820, R8A77980_CLK_S2D1),
+ DEF_MOD("imr2", 821, R8A77980_CLK_S2D1),
+ DEF_MOD("imr1", 822, R8A77980_CLK_S2D1),
+--
+2.7.4
+
diff --git a/bsp/meta-rcar/meta-rcar-gen3-adas/recipes-kernel/linux/linux-renesas/0291-clk-renesas-r8a77980-cpg-mssr-Add-IMP-clocks.patch b/bsp/meta-rcar/meta-rcar-gen3-adas/recipes-kernel/linux/linux-renesas/0291-clk-renesas-r8a77980-cpg-mssr-Add-IMP-clocks.patch
new file mode 100644
index 00000000..6b6727ae
--- /dev/null
+++ b/bsp/meta-rcar/meta-rcar-gen3-adas/recipes-kernel/linux/linux-renesas/0291-clk-renesas-r8a77980-cpg-mssr-Add-IMP-clocks.patch
@@ -0,0 +1,36 @@
+From f259ce6a01dfc0ece91e461c050b74414649de20 Mon Sep 17 00:00:00 2001
+From: Valentine Barshak <valentine.barshak@cogentembedded.com>
+Date: Tue, 6 Nov 2018 02:54:57 +0300
+Subject: [PATCH 111/211] clk: renesas: r8a77980: cpg-mssr: Add IMP clocks
+
+This adds more IMP clocks.
+
+Signed-off-by: Valentine Barshak <valentine.barshak@cogentembedded.com>
+---
+ drivers/clk/renesas/r8a77980-cpg-mssr.c | 3 +++
+ 1 file changed, 3 insertions(+)
+
+diff --git a/drivers/clk/renesas/r8a77980-cpg-mssr.c b/drivers/clk/renesas/r8a77980-cpg-mssr.c
+index 61ffe60..feb5eab 100644
+--- a/drivers/clk/renesas/r8a77980-cpg-mssr.c
++++ b/drivers/clk/renesas/r8a77980-cpg-mssr.c
+@@ -136,6 +136,7 @@ static const struct mssr_mod_clk r8a77980_mod_clks[] __initconst = {
+ DEF_MOD("rwdt", 402, R8A77980_CLK_R),
+ DEF_MOD("intc-ex", 407, R8A77980_CLK_CP),
+ DEF_MOD("intc-ap", 408, R8A77980_CLK_S0D3),
++ DEF_MOD("simp", 500, R8A77980_CLK_S1D1),
+ DEF_MOD("hscif3", 517, R8A77980_CLK_S3D1),
+ DEF_MOD("hscif2", 518, R8A77980_CLK_S3D1),
+ DEF_MOD("hscif1", 519, R8A77980_CLK_S3D1),
+@@ -143,6 +144,8 @@ static const struct mssr_mod_clk r8a77980_mod_clks[] __initconst = {
+ DEF_MOD("imp4", 521, R8A77980_CLK_S1D1),
+ DEF_MOD("thermal", 522, R8A77980_CLK_CP),
+ DEF_MOD("pwm", 523, R8A77980_CLK_S0D12),
++ DEF_MOD("imppsc1", 524, R8A77980_CLK_S1D1),
++ DEF_MOD("imppsc0", 525, R8A77980_CLK_S1D1),
+ DEF_MOD("impdma1", 526, R8A77980_CLK_S1D1),
+ DEF_MOD("impdma0", 527, R8A77980_CLK_S1D1),
+ DEF_MOD("imp-ocv4", 528, R8A77980_CLK_S1D1),
+--
+2.7.4
+
diff --git a/bsp/meta-rcar/meta-rcar-gen3-adas/recipes-kernel/linux/linux-renesas/0292-clk-renesas-r8a77980-cpg-mssr-Add-VIP-clocks.patch b/bsp/meta-rcar/meta-rcar-gen3-adas/recipes-kernel/linux/linux-renesas/0292-clk-renesas-r8a77980-cpg-mssr-Add-VIP-clocks.patch
new file mode 100644
index 00000000..0039ccad
--- /dev/null
+++ b/bsp/meta-rcar/meta-rcar-gen3-adas/recipes-kernel/linux/linux-renesas/0292-clk-renesas-r8a77980-cpg-mssr-Add-VIP-clocks.patch
@@ -0,0 +1,43 @@
+From e9bc27fd3805d8ff37435ddc28e56eff017a8e2f Mon Sep 17 00:00:00 2001
+From: Valentine Barshak <valentine.barshak@cogentembedded.com>
+Date: Tue, 6 Nov 2018 02:59:39 +0300
+Subject: [PATCH 112/211] clk: renesas: r8a77980: cpg-mssr: Add VIP clocks
+
+This adds VIP clocks.
+
+Signed-off-by: Valentine Barshak <valentine.barshak@cogentembedded.com>
+---
+ drivers/clk/renesas/r8a77980-cpg-mssr.c | 10 ++++++++++
+ 1 file changed, 10 insertions(+)
+
+diff --git a/drivers/clk/renesas/r8a77980-cpg-mssr.c b/drivers/clk/renesas/r8a77980-cpg-mssr.c
+index feb5eab..5371c27 100644
+--- a/drivers/clk/renesas/r8a77980-cpg-mssr.c
++++ b/drivers/clk/renesas/r8a77980-cpg-mssr.c
+@@ -111,6 +111,8 @@ static const struct cpg_core_clk r8a77980_core_clks[] __initconst = {
+ };
+
+ static const struct mssr_mod_clk r8a77980_mod_clks[] __initconst = {
++ DEF_MOD("disp", 101, R8A77980_CLK_S1D1),
++ DEF_MOD("umf", 102, R8A77980_CLK_S1D1),
+ DEF_MOD("tmu4", 121, R8A77980_CLK_S0D6),
+ DEF_MOD("tmu3", 122, R8A77980_CLK_S0D6),
+ DEF_MOD("tmu2", 123, R8A77980_CLK_S0D6),
+@@ -196,6 +198,14 @@ static const struct mssr_mod_clk r8a77980_mod_clks[] __initconst = {
+ DEF_MOD("i2c2", 929, R8A77980_CLK_S3D2),
+ DEF_MOD("i2c1", 930, R8A77980_CLK_S3D2),
+ DEF_MOD("i2c0", 931, R8A77980_CLK_S3D2),
++ DEF_MOD("cle4", 1000, R8A77980_CLK_S1D1),
++ DEF_MOD("cle3", 1001, R8A77980_CLK_S1D1),
++ DEF_MOD("cle2", 1002, R8A77980_CLK_S1D1),
++ DEF_MOD("cle1", 1003, R8A77980_CLK_S1D1),
++ DEF_MOD("cle0", 1004, R8A77980_CLK_S1D1),
++ DEF_MOD("smd_post", 1100, R8A77980_CLK_S0D3),
++ DEF_MOD("smd_est", 1101, R8A77980_CLK_S0D3),
++ DEF_MOD("smd_ps", 1102, R8A77980_CLK_S0D3),
+ };
+
+ static const unsigned int r8a77980_crit_mod_clks[] __initconst = {
+--
+2.7.4
+
diff --git a/bsp/meta-rcar/meta-rcar-gen3-adas/recipes-kernel/linux/linux-renesas/0293-clk-renesas-r8a77970-cpg-mssr-Add-IMP-clocks.patch b/bsp/meta-rcar/meta-rcar-gen3-adas/recipes-kernel/linux/linux-renesas/0293-clk-renesas-r8a77970-cpg-mssr-Add-IMP-clocks.patch
new file mode 100644
index 00000000..7d8e7e2a
--- /dev/null
+++ b/bsp/meta-rcar/meta-rcar-gen3-adas/recipes-kernel/linux/linux-renesas/0293-clk-renesas-r8a77970-cpg-mssr-Add-IMP-clocks.patch
@@ -0,0 +1,33 @@
+From b55a082af8abefb51feedbecd20df65689302697 Mon Sep 17 00:00:00 2001
+From: Valentine Barshak <valentine.barshak@cogentembedded.com>
+Date: Tue, 6 Nov 2018 03:24:54 +0300
+Subject: [PATCH 113/211] clk: renesas: r8a77970: cpg-mssr: Add IMP clocks
+
+This adds IMP clocks.
+
+Signed-off-by: Valentine Barshak <valentine.barshak@cogentembedded.com>
+---
+ drivers/clk/renesas/r8a77970-cpg-mssr.c | 7 +++++++
+ 1 file changed, 7 insertions(+)
+
+diff --git a/drivers/clk/renesas/r8a77970-cpg-mssr.c b/drivers/clk/renesas/r8a77970-cpg-mssr.c
+index 5ae694b..29833b6 100644
+--- a/drivers/clk/renesas/r8a77970-cpg-mssr.c
++++ b/drivers/clk/renesas/r8a77970-cpg-mssr.c
+@@ -157,6 +157,13 @@ static const struct mssr_mod_clk r8a77970_mod_clks[] __initconst = {
+ DEF_MOD("imr2", 821, R8A77970_CLK_S2D1),
+ DEF_MOD("imr1", 822, R8A77970_CLK_S2D1),
+ DEF_MOD("imr0", 823, R8A77970_CLK_S2D1),
++ DEF_MOD("imp3", 824, R8A77970_CLK_S1D1),
++ DEF_MOD("imp2", 825, R8A77970_CLK_S1D1),
++ DEF_MOD("imp1", 826, R8A77970_CLK_S1D1),
++ DEF_MOD("imp0", 827, R8A77970_CLK_S1D1),
++ DEF_MOD("imp-ocv1", 828, R8A77970_CLK_S1D1),
++ DEF_MOD("imp-ocv0", 829, R8A77970_CLK_S1D1),
++ DEF_MOD("impram", 830, R8A77970_CLK_S1D1),
+ DEF_MOD("gpio5", 907, R8A77970_CLK_CP),
+ DEF_MOD("gpio4", 908, R8A77970_CLK_CP),
+ DEF_MOD("gpio3", 909, R8A77970_CLK_CP),
+--
+2.7.4
+
diff --git a/bsp/meta-rcar/meta-rcar-gen3-adas/recipes-kernel/linux/linux-renesas/0294-media-soc_camera-Add-CONFIG_VIDEO_ADV_DEBUG-support.patch b/bsp/meta-rcar/meta-rcar-gen3-adas/recipes-kernel/linux/linux-renesas/0294-media-soc_camera-Add-CONFIG_VIDEO_ADV_DEBUG-support.patch
new file mode 100644
index 00000000..879051f8
--- /dev/null
+++ b/bsp/meta-rcar/meta-rcar-gen3-adas/recipes-kernel/linux/linux-renesas/0294-media-soc_camera-Add-CONFIG_VIDEO_ADV_DEBUG-support.patch
@@ -0,0 +1,78 @@
+From 83c415759f5b2ebdd19e0e3e1932bac3a63206f9 Mon Sep 17 00:00:00 2001
+From: Andrey Dolnikov <andrey.dolnikov@cogentembedded.com>
+Date: Mon, 12 Nov 2018 15:43:59 +0300
+Subject: [PATCH 114/211] media: soc_camera: Add CONFIG_VIDEO_ADV_DEBUG
+ support.
+
+Signed-off-by: Vladimir Barinov <vladimir.barinov@cogentembedded.com>
+---
+ drivers/media/platform/soc_camera/soc_camera.c | 30 ++++++++++++++++++++++++++
+ include/media/soc_camera.h | 4 ++++
+ 2 files changed, 34 insertions(+)
+
+diff --git a/drivers/media/platform/soc_camera/soc_camera.c b/drivers/media/platform/soc_camera/soc_camera.c
+index 1f840cf..0fa1f52 100644
+--- a/drivers/media/platform/soc_camera/soc_camera.c
++++ b/drivers/media/platform/soc_camera/soc_camera.c
+@@ -1056,6 +1056,32 @@ static int soc_camera_g_edid(struct file *file, void *fh,
+ return -ENOIOCTLCMD;
+ }
+
++#ifdef CONFIG_VIDEO_ADV_DEBUG
++static int soc_camera_g_register(struct file *file, void *priv,
++ struct v4l2_dbg_register *reg)
++{
++ struct soc_camera_device *icd = file->private_data;
++ struct soc_camera_host *ici = to_soc_camera_host(icd->parent);
++
++ if (ici->ops->get_register)
++ return ici->ops->get_register(icd, reg);
++
++ return -ENOIOCTLCMD;
++}
++
++static int soc_camera_s_register(struct file *file, void *priv,
++ const struct v4l2_dbg_register *reg)
++{
++ struct soc_camera_device *icd = file->private_data;
++ struct soc_camera_host *ici = to_soc_camera_host(icd->parent);
++
++ if (ici->ops->set_register)
++ return ici->ops->set_register(icd, reg);
++
++ return -ENOIOCTLCMD;
++}
++#endif
++
+ static int soc_camera_probe(struct soc_camera_host *ici,
+ struct soc_camera_device *icd);
+
+@@ -2026,6 +2052,10 @@ static const struct v4l2_ioctl_ops soc_camera_ioctl_ops = {
+ .vidioc_g_parm = soc_camera_g_parm,
+ .vidioc_s_parm = soc_camera_s_parm,
+ .vidioc_g_edid = soc_camera_g_edid,
++#ifdef CONFIG_VIDEO_ADV_DEBUG
++ .vidioc_g_register = soc_camera_g_register,
++ .vidioc_s_register = soc_camera_s_register,
++#endif
+ };
+
+ static int video_dev_create(struct soc_camera_device *icd)
+diff --git a/include/media/soc_camera.h b/include/media/soc_camera.h
+index 4381be0..c2a7fc2 100644
+--- a/include/media/soc_camera.h
++++ b/include/media/soc_camera.h
+@@ -119,6 +119,10 @@ struct soc_camera_host_ops {
+ int (*enum_framesizes)(struct soc_camera_device *, struct v4l2_frmsizeenum *);
+ unsigned int (*poll)(struct file *, poll_table *);
+ int (*get_edid)(struct soc_camera_device *, struct v4l2_edid *);
++#ifdef CONFIG_VIDEO_ADV_DEBUG
++ int (*get_register)(struct soc_camera_device *, struct v4l2_dbg_register *reg);
++ int (*set_register)(struct soc_camera_device *, const struct v4l2_dbg_register *reg);
++#endif
+ };
+
+ #define SOCAM_SENSOR_INVERT_PCLK (1 << 0)
+--
+2.7.4
+
diff --git a/bsp/meta-rcar/meta-rcar-gen3-adas/recipes-kernel/linux/linux-renesas/0295-media-platform-soc_camera-Add-V4L2-R-Car-ISP-driver.patch b/bsp/meta-rcar/meta-rcar-gen3-adas/recipes-kernel/linux/linux-renesas/0295-media-platform-soc_camera-Add-V4L2-R-Car-ISP-driver.patch
new file mode 100644
index 00000000..05f180b7
--- /dev/null
+++ b/bsp/meta-rcar/meta-rcar-gen3-adas/recipes-kernel/linux/linux-renesas/0295-media-platform-soc_camera-Add-V4L2-R-Car-ISP-driver.patch
@@ -0,0 +1,2150 @@
+From 0b363ab08af71741db4eb51b31beab9f64e11dfe Mon Sep 17 00:00:00 2001
+From: Vladimir Barinov <vladimir.barinov@cogentembedded.com>
+Date: Tue, 15 May 2018 11:33:45 +0300
+Subject: [PATCH 115/211] media: platform: soc_camera: Add V4L2 R-Car ISP
+ driver
+
+This adds R-Car ISP driver.
+
+Signed-off-by: Vladimir Barinov <vladimir.barinov@cogentembedded.com>
+Signed-off-by: Valentine Barshak <valentine.barshak@cogentembedded.com>
+---
+ drivers/media/platform/soc_camera/Kconfig | 9 +
+ drivers/media/platform/soc_camera/Makefile | 1 +
+ drivers/media/platform/soc_camera/rcar_isp.c | 2094 ++++++++++++++++++++++++++
+ 3 files changed, 2104 insertions(+)
+ create mode 100644 drivers/media/platform/soc_camera/rcar_isp.c
+
+diff --git a/drivers/media/platform/soc_camera/Kconfig b/drivers/media/platform/soc_camera/Kconfig
+index 6616d59..61b0dcf 100644
+--- a/drivers/media/platform/soc_camera/Kconfig
++++ b/drivers/media/platform/soc_camera/Kconfig
+@@ -44,6 +44,15 @@ config VIDEO_RCAR_CSI2_LEGACY
+ ---help---
+ This is a v4l2 driver for the R-Car CSI-2 Interface
+
++config VIDEO_RCAR_ISP_LEGACY
++ tristate "R-Car Image Signal Processing (ISP) support"
++ depends on VIDEO_DEV && SOC_CAMERA
++ depends on ARCH_RENESAS || COMPILE_TEST
++ depends on HAS_DMA
++ select VIDEOBUF2_DMA_CONTIG
++ ---help---
++ This is a v4l2 driver for the R-Car ISP Interface
++
+ config VIDEO_SH_MOBILE_CEU
+ tristate "SuperH Mobile CEU Interface driver"
+ depends on VIDEO_DEV && SOC_CAMERA && HAS_DMA && HAVE_CLK
+diff --git a/drivers/media/platform/soc_camera/Makefile b/drivers/media/platform/soc_camera/Makefile
+index 1a70361..49449e1 100644
+--- a/drivers/media/platform/soc_camera/Makefile
++++ b/drivers/media/platform/soc_camera/Makefile
+@@ -8,4 +8,5 @@ obj-$(CONFIG_SOC_CAMERA_PLATFORM) += soc_camera_platform.o
+ # soc-camera host drivers have to be linked after camera drivers
+ obj-$(CONFIG_VIDEO_SH_MOBILE_CEU) += sh_mobile_ceu_camera.o
+ obj-$(CONFIG_VIDEO_RCAR_CSI2_LEGACY) += rcar_csi2.o
++obj-$(CONFIG_VIDEO_RCAR_ISP_LEGACY) += rcar_isp.o
+ obj-$(CONFIG_VIDEO_RCAR_VIN_LEGACY) += rcar_vin.o
+diff --git a/drivers/media/platform/soc_camera/rcar_isp.c b/drivers/media/platform/soc_camera/rcar_isp.c
+new file mode 100644
+index 0000000..878df95
+--- /dev/null
++++ b/drivers/media/platform/soc_camera/rcar_isp.c
+@@ -0,0 +1,2094 @@
++/*
++ * SoC-camera host driver for Renesas R-Car ISP unit
++ *
++ * Copyright (C) 2018 Renesas Electronics Corporation
++ * Copyright (C) 2018 Cogent Embedded
++ *
++ * Based on V4L2 Driver for R-Car VIN interface "rca_vin.c"
++ *
++ * This program is free software; you can redistribute it and/or modify it
++ * under the terms of the GNU General Public License as published by the
++ * Free Software Foundation; either version 2 of the License, or (at your
++ * option) any later version.
++ */
++
++//#define DEBUG
++
++#include <linux/delay.h>
++#include <linux/interrupt.h>
++#include <linux/io.h>
++#include <linux/kernel.h>
++#include <linux/module.h>
++#include <linux/of.h>
++#include <linux/of_device.h>
++#include <linux/of_graph.h>
++#include <linux/platform_device.h>
++#include <linux/pm_runtime.h>
++#include <linux/slab.h>
++#include <linux/videodev2.h>
++#include <linux/list.h>
++
++#include <media/soc_camera.h>
++#include <media/drv-intf/soc_mediabus.h>
++#include <media/v4l2-common.h>
++#include <media/v4l2-dev.h>
++#include <media/v4l2-device.h>
++#include <media/v4l2-fwnode.h>
++#include <media/v4l2-mediabus.h>
++#include <media/v4l2-subdev.h>
++#include <media/videobuf2-dma-contig.h>
++#include <media/rcar_csi2.h>
++
++#include "soc_scale_crop.h"
++
++#define DRV_NAME "rcar_isp"
++
++/* Register offsets for R-Car ISP Interface */
++/* Basic Control */
++#define ISPVCR_REG 0x0000
++#define ISPFIFOCTRL_REG 0x0004
++#define ISPINPUTSEL0_REG 0x0008
++#define ISPSTART_REG 0x0014
++#define ISPINT_STATUS_REG 0x0040
++#define ISPERR0_STATUS_REG 0x0044
++#define ISPERR1_STATUS_REG 0x0048
++#define ISPINT_CLEAR_REG 0x0050
++#define ISPERR0_CLEAR_REG 0x0054
++#define ISPERR1_CLEAR_REG 0x0058
++#define ISPINT_ENABLE_REG 0x0060
++#define ISPERR0_ENABLE_REG 0x0064
++#define ISPERR1_ENABLE_REG 0x0068
++#define ISP_PADDING_CTRL_REG 0x00C0
++
++/* Register offsets for R-Car ISP Core */
++/* Pipeline Frontend */
++#define PIPEFE_GFSMR_REG 0x0020
++
++/* Interrupts */
++#define INT_FSM_REG 0x0084
++#define INT_FSS_REG 0x0088
++#define INT_FSC_REG 0x008C
++#define INT_FEM_REG 0x0098
++#define INT_FES_REG 0x009C
++#define INT_FEC_REG 0x00A0
++#define INT_FEL0_REG 0x00A4
++#define INT_FEL1_REG 0x00A8
++#define INT_STM_REG 0x00B0
++#define INT_STS_REG 0x00B4
++#define INT_STC_REG 0x00B8
++
++/* Input Ports (Port n uses VC=n) */
++#define INP_HCSTART0_REG(n) (0x010C + (n << 6))
++#define INP_HCSIZE0_REG(n) (0x0110 + (n << 6))
++#define INP_HCSTART1_REG(n) (0x0114 + (n << 6))
++#define INP_HCSIZE1_REG(n) (0x0118 + (n << 6))
++#define INP_VCSTART_REG(n) (0x0120 + (n << 6))
++#define INP_VCSIZE_REG(n) (0x0124 + (n << 6))
++#define INP_MR_REG 0x01F0
++#define INP_MS_REG 0x01F4
++
++#define INP_MS(n) (1 << (n << 3))
++
++/* OUT_BUFFERS */
++#define OBUF_BV_REG(n) (0x0C00 + (n << 5))
++#define OBUF_BA_REG(n) (0x0C04 + (n << 5))
++#define OBUF_LO_REG(n) (0x0C08 + (n << 5))
++#define OBUF_AW_REG(n) (0x0C0C + (n << 5))
++#define OBUF_AH_REG(n) (0x0C10 + (n << 5))
++#define OBUF_HM_REG(n) (0x0C14 + (n << 5))
++#define OBUF_ST_REG(n) (0x0C18 + (n << 5))
++
++/* Stream Crossbar */
++#define SCB_SELECT_REG(n) (0x03E0 + (n << 2))
++
++/* Multichannel Frontend */
++#define MCFE_FIFOC_REG 0x0400
++#define MCFE_SCM_REG 0x0414
++#define MCFE_OWL_REG 0x041C
++#define MCFE_SLM0_REG 0x0420
++#define MCFE_SLM4_REG 0x0424
++#define MCFE_SLCFGV0_REG 0x0458
++#define MCFE_SLCFGV4_REG 0x045C
++#define MCFE_SLINP_REG(n) (0x04E0 + (n << 2))
++#define MCFE_SLOUTBUF1_REG(n) (0x0500 + (n << 2))
++#define MCFE_SLOUTBUF2_REG(n) (0x0520 + (n << 2))
++#define MCFE_INM_REG 0x0540
++#define MCFE_INAL_REG 0x0544
++#define MCFE_INDW_REG 0x054C
++#define MCFE_INSV_REG 0x0550
++
++#define MCFE_SCM_STOPPED (0 << 0)
++#define MCFE_SCM_MANUAL (1 << 0)
++#define MCFE_SCM_1STREAM (2 << 0)
++
++#define MCFE_SCM_SLOT(n) (n << 16)
++
++#define MCFE_SLM0_PASSTHR(n) (1 << (n << 3))
++
++/* Top */
++#define TOP_AW_REG 0xE010
++#define TOP_AH_REG 0xE014
++#define TOP_RGGB_REG 0xE018
++
++#define TOP_RGGB_RGrGbB (0 << 0)
++#define TOP_RGGB_GrRBGb (1 << 0)
++#define TOP_RGGB_GbBRGr (2 << 0)
++#define TOP_RGGB_BGbGrR (3 << 0)
++
++#define TOP_CFA_RGGB (0 << 8)
++
++/* Pipeline */
++#define PIPE_CHS_REG 0xE020
++#define PIPE_FSCHS_REG 0xE02C
++#define PIPE_CBM_REG 0xE030
++#define PIPE_BP_REG 0xE040
++
++#define PIPE_BP_INF (1 << 2)
++#define PIPE_BP_DEMOSAIC (1 << 19)
++#define PIPE_BP_OUTF (1 << 20)
++
++/* Input Formatter */
++#define INF_MI_REG 0xE140
++
++#define INF_MI_LINEAR (0 << 0)
++#define INF_MI_8BITS (0 << 16)
++#define INF_MI_MSB (1 << 24)
++
++/* Output Formatter */
++#define OUTF_BP_REG 0xE600
++#define OUTF_MODE_REG 0xE608
++
++#define OUTF_BP_RGB2YUV (1 << 9)
++#define OUTF_BP_RGB2YUV_SP (1 << 14)
++
++/* Out format MUX for AXI */
++#define AXIOUT_MS_REG 0xE740
++
++#define AXIOUT_MS_YUV_Y12 (4 << 0)
++#define AXIOUT_MS_YUV_UV8 (7 << 0)
++#define AXIOUT_MS_LUV_UV8 (12 << 0)
++#define AXIOUT_MS_RGB888 (15 << 0)
++#define AXIOUT_MS_RAW8 (24 << 0)
++#define AXIOUT_MS_RAW16 (27 << 0)
++
++#define AXIOUT_MSB_ALIGN (1 << 7)
++
++enum chip_id {
++ RCAR_GEN3,
++ RCAR_V3M,
++ RCAR_V3H,
++};
++
++enum csi2_ch {
++ RCAR_CSI_CH_NONE = -1,
++ RCAR_CSI40,
++ RCAR_CSI41,
++};
++
++enum gen3_isp_ch {
++ RCAR_ISP_CH_NONE = -1,
++ RCAR_ISP_CH_0,
++ RCAR_ISP_CH_1,
++};
++
++enum virtual_ch {
++ RCAR_VIRTUAL_NONE = -1,
++ RCAR_VIRTUAL_CH0,
++ RCAR_VIRTUAL_CH1,
++ RCAR_VIRTUAL_CH2,
++ RCAR_VIRTUAL_CH3,
++};
++
++enum rcar_isp_state {
++ STOPPED,
++ RUNNING,
++};
++
++struct isp_gen3_virtual_sel {
++ enum csi2_ch csi2_ch;
++ enum virtual_ch vc;
++};
++
++struct rcar_isp_async_client {
++ struct v4l2_async_subdev *sensor;
++ struct v4l2_async_notifier notifier;
++ struct platform_device *pdev;
++};
++
++struct soc_of_info {
++ struct soc_camera_async_subdev sasd;
++ struct rcar_isp_async_client sasc;
++ struct v4l2_async_subdev *subdev;
++};
++
++struct rcar_isp_interface {
++ void __iomem *base;
++};
++
++struct rcar_isp_priv {
++ struct device *dev;
++ void __iomem *base;
++ struct rcar_isp_interface interface;
++ spinlock_t lock;
++ int sequence;
++ /* State of the ISP module in capturing mode */
++ enum rcar_isp_state state;
++ struct soc_camera_host ici;
++ struct list_head capture;
++#define MAX_BUFFER_NUM 1
++ struct vb2_v4l2_buffer *queue_buf[MAX_BUFFER_NUM];
++ enum v4l2_field field;
++ unsigned int vb_count;
++ unsigned int nr_hw_slots;
++ enum chip_id chip;
++ unsigned int max_width;
++ unsigned int max_height;
++ enum csi2_ch csi_ch;
++ enum virtual_ch vc;
++ bool csi_sync;
++ bool deser_sync;
++
++ struct rcar_isp_async_client *async_client;
++ /* Asynchronous CSI2 linking */
++ struct v4l2_subdev *csi2_sd;
++ /* Asynchronous Deserializer linking */
++ struct v4l2_subdev *deser_sd;
++ /* ISP channel */
++ unsigned int index;
++};
++
++struct rcar_isp_buffer {
++ struct vb2_v4l2_buffer vb;
++ struct list_head list;
++};
++
++#define to_buf_list(vb2_buffer) (&container_of(vb2_buffer, struct rcar_isp_buffer, vb)->list)
++
++struct rcar_isp_cam {
++ /* ISP offsets within the camera output, before the ISP scaler */
++ unsigned int isp_left;
++ unsigned int isp_top;
++ /* Client output, as seen by the ISP */
++ unsigned int width;
++ unsigned int height;
++ unsigned int raw_bpp;
++ /* User window from S_FMT */
++ unsigned int out_width;
++ unsigned int out_height;
++ unsigned int out_bpp;
++ /*
++ * User window from S_SELECTION / G_SELECTION, produced by client cropping and
++ * scaling, ISP scaling and ISP cropping, mapped back onto the client
++ * input window
++ */
++ struct v4l2_rect subrect;
++ /* Camera cropping rectangle */
++ struct v4l2_rect rect;
++ const struct soc_mbus_pixelfmt *extra_fmt;
++};
++
++static void rcar_isp_open(struct rcar_isp_priv *priv)
++{
++ int timeout;
++ u32 val;
++ int inport = 0;
++
++ /* ISP version */
++ val = ioread32(priv->interface.base + ISPVCR_REG);
++// printk("ISP version =0x%x\n", val);
++ /* ISP Input CSI FIFO enable */
++ iowrite32(0x4, priv->interface.base + ISPFIFOCTRL_REG);
++ /* ISP Input select CSI */
++ iowrite32(0x800, priv->interface.base + ISPINPUTSEL0_REG);
++ /* ISP control start */
++ iowrite32(0xffff, priv->interface.base + ISPSTART_REG);
++
++ /* V3H CSI stream filter needs following */
++ if (priv->chip == RCAR_V3H) {
++ // select CSI2_41 channel for Cogent ECU
++// iowrite32(0x800 | BIT(31), priv->interface.base + ISPINPUTSEL0_REG);
++
++ iowrite32(0x02, priv->interface.base + 0x11b0);
++ iowrite32(0x01, priv->interface.base + 0x3000);
++ iowrite32(0xac, priv->interface.base + 0x3008);
++ }
++
++ /* PipelineIP: immediate update mode */
++ iowrite32(0, priv->base + PIPE_CBM_REG);
++
++ /* PipelineFE: reset/freeze all state machines (NOTE: does NOT reset ISP to defaults) */
++ iowrite32(1, priv->base + PIPEFE_GFSMR_REG);
++ udelay(10);
++ /* PipelineFE: unfreeze all state machines */
++ iowrite32(0, priv->base + PIPEFE_GFSMR_REG);
++
++ /* INP: safe stop */
++ iowrite32(0, priv->base + INP_MR_REG);
++ /* INP: poll status */
++ for (timeout = 0; timeout < 100; timeout++) {
++ val = ioread32(priv->base + INP_MS_REG);
++ if (!(val & (INP_MS(inport))))
++ break;
++ udelay(1000);
++ }
++ if (timeout >= 100)
++ pr_err("%s timeout input port stop\n", __func__);
++
++ /* MCFE: one FIFO on each input/output channel */
++ iowrite32(0, priv->base + MCFE_FIFOC_REG);
++
++ /* DMA/FIFO watermarks setup */
++ iowrite32(0x70004, priv->base + 0x0590);
++ iowrite32(0x70004, priv->base + 0x0598);
++ iowrite32(0x70004, priv->base + 0x05a4);
++ iowrite32(0x70004, priv->base + 0x05ac);
++ iowrite32(0x2800140, priv->base + 0x0404);
++ iowrite32(0x2800140, priv->base + 0x0408);
++ iowrite32(0x2800140, priv->base + 0x040c);
++ iowrite32(0x2800140, priv->base + 0x0410);
++ iowrite32(0x7000e, priv->base + 0x05c0);
++ iowrite32(0x72f681d9, priv->base + 0x05c4);
++ iowrite32(1, priv->base + 0x05c8);
++ iowrite32(0x800080, priv->base + 0x05cc);
++ iowrite32(0x400080, priv->base + 0x05d0);
++
++ /* Invalidate Slot cfg */
++ iowrite32(0, priv->base + MCFE_SLCFGV0_REG);
++ iowrite32(0, priv->base + MCFE_SLCFGV4_REG);
++
++ /* Pipeline: bypass all modules */
++ iowrite32(0xf93ffffc, priv->base + PIPE_BP_REG);
++ /* Pipeline: source select for RAW/VTPG */
++ iowrite32(0xe4, priv->base + PIPE_CHS_REG);
++ /* Pipeline: source select for frame stitch */
++ iowrite32(0xe4, priv->base + PIPE_FSCHS_REG);
++
++ /* PipelineIP: global update mode (during vertical blanking) */
++ iowrite32(3, priv->base + PIPE_CBM_REG);
++ /* Pipeline: tag# */
++ iowrite32(0, priv->base + 0xe060);
++ /* Pipeline: context# */
++ iowrite32(0, priv->base + 0xe064);
++
++ /* FAULTS_CFG: mask all errors */
++ iowrite32(0xffffffff, priv->base + 0x1000);
++ iowrite32(0xffffffff, priv->base + 0x1004);
++ iowrite32(0xffffffff, priv->base + 0x1008);
++ iowrite32(0xffffffff, priv->base + 0x100C);
++ iowrite32(0xffffffff, priv->base + 0x1010);
++ iowrite32(0xffffffff, priv->base + 0x1014);
++ iowrite32(0xffffffff, priv->base + 0x1018);
++ iowrite32(0xffffffff, priv->base + 0x101C);
++ iowrite32(0xffffffff, priv->base + 0x1020);
++ iowrite32(0xffffffff, priv->base + 0x1024);
++ iowrite32(0xffffffff, priv->base + 0x1028);
++ iowrite32(0xffffffff, priv->base + 0x102C);
++ iowrite32(0xffffffff, priv->base + 0x1030);
++}
++
++static void rcar_isp_close(struct rcar_isp_priv *priv)
++{
++ /* Pipeline FE: reset/freeze all state machines (NOTE: does NOT reset ISP to defaults) */
++ iowrite32(1, priv->base + PIPEFE_GFSMR_REG);
++ /* ISP control stop */
++ iowrite32(0, priv->interface.base + 0x14);
++}
++
++static void rcar_isp_start(struct rcar_isp_priv *priv)
++{
++ int timeout;
++ u32 val;
++ int slot = 0;
++ int inport = 0;
++
++ /* MCFE: disable scheduler, set slots IDLE state */
++ iowrite32(0xf << 16, priv->base + MCFE_SCM_REG);
++ /* INP: safe start */
++ iowrite32(0x1, priv->base + INP_MR_REG);
++ /* INP: poll status */
++ for (timeout = 0; timeout < 100; timeout++) {
++ val = ioread32(priv->base + INP_MS_REG);
++ if (val & (INP_MS(inport)))
++ break;
++ udelay(1000);
++ }
++ if (timeout >= 100)
++ pr_err("%s timeout input port start\n", __func__);
++ /* MCFE: enable scheduler, start slot#0 */
++ iowrite32(MCFE_SCM_1STREAM | MCFE_SCM_SLOT(slot), priv->base + MCFE_SCM_REG);
++
++ for (timeout = 0; timeout < 100; timeout++) {
++ val = ioread32(priv->base + MCFE_OWL_REG);
++ if (val != 0x3f3f3f3f)
++ break;
++ udelay(1000);
++ }
++ if (timeout >= 100)
++ pr_err("%s timeout out_buffer start\n", __func__);
++
++ /* disable interrupts */
++ iowrite32(0, priv->base + INT_FSM_REG);
++ iowrite32(0, priv->base + INT_FEM_REG);
++ iowrite32(0xffff, priv->base + INT_FEL0_REG);
++ iowrite32(0, priv->base + INT_FEL1_REG);
++ iowrite32(0, priv->base + INT_STM_REG);
++ /* ack interrupts */
++ iowrite32(ioread32(priv->base + INT_FSS_REG), priv->base + INT_FSC_REG);
++ iowrite32(ioread32(priv->base + INT_FES_REG), priv->base + INT_FEC_REG);
++ iowrite32(ioread32(priv->base + INT_STS_REG), priv->base + INT_STC_REG);
++ /* enable frame end interrupt */
++ iowrite32(BIT(15), priv->base + INT_FEM_REG);
++}
++
++static void rcar_isp_stop(struct rcar_isp_priv *priv)
++{
++ int timeout;
++ u32 val;
++ int inport = 0;
++
++ /* disable interrupts */
++ iowrite32(0, priv->base + INT_FEM_REG);
++ /* ack interrups */
++ iowrite32(ioread32(priv->base + INT_FES_REG), priv->base + INT_FEC_REG);
++
++ /* MCFE: disable all slots */
++ iowrite32(0, priv->base + MCFE_SLM0_REG);
++ iowrite32(0, priv->base + MCFE_SLM4_REG);
++ /* MCFE: input mode off */
++ iowrite32(0, priv->base + MCFE_INM_REG);
++ /* MCFE: stop scheduler */
++ iowrite32(0, priv->base + MCFE_SCM_REG);
++ /* INP: safe stop */
++ iowrite32(0, priv->base + INP_MR_REG);
++ /* INP: poll status */
++ for (timeout = 0; timeout < 100; timeout++) {
++ val = ioread32(priv->base + INP_MS_REG);
++ if (!(val & (INP_MS(inport))))
++ break;
++ udelay(1000);
++ }
++ if (timeout >= 100)
++ pr_err("%s timeout input port stop\n", __func__);
++}
++
++static void rcar_isp_setup_inputs(struct rcar_isp_priv *priv, int inport, int raw_bpp)
++{
++ struct rcar_isp_cam *cam = priv->ici.icd->host_priv;
++ int timeout;
++ u32 val;
++
++ /* MCFE: input mode off */
++ iowrite32(0, priv->base + MCFE_INM_REG);
++ /* INP: safe stop */
++ iowrite32(0, priv->base + INP_MR_REG);
++ /* INP: poll status */
++ for (timeout = 0; timeout < 100; timeout++) {
++ val = ioread32(priv->base + INP_MS_REG);
++ if (!(val & (INP_MS(inport))))
++ break;
++ udelay(1000);
++ }
++ if (timeout >= 100)
++ pr_err("%s timeout input port stop\n", __func__);
++
++ /* INP: freeze */
++ iowrite32(0x80, priv->base + INP_MR_REG);
++ udelay(100);
++
++ /* Stream Crossbar for MCFE INP#1 */
++ val = (0 << 16); /* virtual channel */
++ val |= (0 << 8); /* input video port1 */
++ val |= 1; /* select data from one input */
++ iowrite32(val, priv->base + SCB_SELECT_REG(inport));
++
++ /* window0 setup */
++ iowrite32(0, priv->base + INP_HCSTART0_REG(inport));
++ iowrite32(0, priv->base + INP_VCSTART_REG(inport));
++ iowrite32(cam->out_width, priv->base + INP_HCSIZE0_REG(inport));
++ iowrite32(cam->out_height, priv->base + INP_VCSIZE_REG(inport));
++ /* window1 setup */
++ iowrite32(0, priv->base + INP_HCSTART1_REG(inport));
++ iowrite32(cam->out_width, priv->base + INP_HCSIZE1_REG(inport));
++
++ /* MCFE: Invalidate Input stats */
++ iowrite32(0, priv->base + MCFE_INSV_REG);
++ /* MCFE: input data bpp */
++ val = (raw_bpp << 24) | (raw_bpp << 16) | (raw_bpp << 8) | raw_bpp;
++ iowrite32(val, priv->base + MCFE_INDW_REG);
++ /* MCFE: input data alignment LSB */
++ iowrite32(0, priv->base + MCFE_INAL_REG);
++ /* MCFE: input mode setup */
++ val = 1 << (inport * 8); /* direct through FIFO */
++ iowrite32(val, priv->base + MCFE_INM_REG);
++
++ /* INP: unfreeze, safe stop */
++ iowrite32(0, priv->base + INP_MR_REG);
++}
++
++static void rcar_isp_setup_mcfe(struct rcar_isp_priv *priv, int slot_mode)
++{
++ u32 val;
++ int slot = 0;
++ int slot_input = 0;
++
++ /* Slots cancel and clear errors */
++ iowrite32(0x06060606, priv->base + MCFE_SLM0_REG);
++ iowrite32(0x00000606, priv->base + MCFE_SLM4_REG);
++ /* Invalidate Slot cfg */
++ iowrite32(0, priv->base + MCFE_SLCFGV0_REG);
++ iowrite32(0, priv->base + MCFE_SLCFGV4_REG);
++ /* MCFE: input mode off */
++ iowrite32(0, priv->base + MCFE_INM_REG);
++ /* MCFE: Invalidate Input stats */
++ iowrite32(0, priv->base + MCFE_INSV_REG);
++ udelay(100); //100
++
++ /* input streams for this slot */
++ val = ioread32(priv->base + MCFE_SLINP_REG(slot));
++ val &= ~0xff;
++ val |= slot_input;
++ iowrite32(val, priv->base + MCFE_SLINP_REG(slot));
++ /* AXI out_buffers for this slot */
++ val = ioread32(priv->base + MCFE_SLOUTBUF1_REG(slot));
++ val &= ~0xff;
++ val |= 0; /* AXI buffer1 */
++ iowrite32(val, priv->base + MCFE_SLOUTBUF1_REG(slot));
++ val = ioread32(priv->base + MCFE_SLOUTBUF2_REG(slot));
++ val &= ~0xff;
++ val |= 1; /* AXI buffer2 */
++ iowrite32(val, priv->base + MCFE_SLOUTBUF2_REG(slot));
++ /* set slot mode */
++ val = ioread32(priv->base + MCFE_SLM0_REG);
++ val &= ~(0xff << (slot * 8));
++ val |= (slot_mode << (slot * 8));
++ iowrite32(val, priv->base + MCFE_SLM0_REG);
++ iowrite32(0, priv->base + MCFE_SLM4_REG);
++}
++
++static void rcar_isp_setup_pipeline(struct rcar_isp_priv *priv, int axi_colourspace, int axi_num, int is_yuv)
++{
++ u32 val;
++
++ /* Input formatter */
++#if 0
++ iowrite32(INF_MI_LINEAR | INF_MI_8BITS | INF_MI_MSB, priv->base + INF_MI_REG);
++#else
++ val = ioread32(priv->base + INF_MI_REG);
++ val &= ~(0x70007);
++ iowrite32(val, priv->base + INF_MI_REG);
++#endif
++ /* pipe input formatter, demosaic, output formatter */
++ val = ioread32(priv->base + PIPE_BP_REG);
++ val &= ~(PIPE_BP_DEMOSAIC | PIPE_BP_OUTF | PIPE_BP_INF);
++ iowrite32(val, priv->base + PIPE_BP_REG);
++ /* pipe output formatter RGB2YUV */
++ if (is_yuv)
++ iowrite32(~OUTF_BP_RGB2YUV, priv->base + OUTF_BP_REG);
++
++ /* AXI output colourspace */
++ val = ioread32(priv->base + AXIOUT_MS_REG);
++ val &= ~(0xff << axi_num);
++ val |= (axi_colourspace << axi_num);
++ iowrite32(val, priv->base + AXIOUT_MS_REG);
++}
++
++static void rcar_isp_setup_top(struct rcar_isp_priv *priv, int bayer_pattern)
++{
++ struct rcar_isp_cam *cam = priv->ici.icd->host_priv;
++
++ /* Top setup */
++ iowrite32(cam->out_width, priv->base + TOP_AW_REG);
++ iowrite32(cam->out_height, priv->base + TOP_AH_REG);
++ iowrite32(TOP_CFA_RGGB | bayer_pattern, priv->base + TOP_RGGB_REG);
++}
++
++static void rcar_isp_setup_out_buffer(struct rcar_isp_priv *priv, int slot, dma_addr_t phys_addr_top)
++{
++ struct soc_camera_device *icd = priv->ici.icd;
++ struct rcar_isp_cam *cam = icd->host_priv;
++
++ /* invalidate out_buffer */
++ iowrite32(0, priv->base + OBUF_BV_REG(slot));
++ /* setup phys addr */
++ iowrite32(phys_addr_top, priv->base + OBUF_BA_REG(slot));
++ /* setup frame params */
++ iowrite32(cam->out_width * (cam->out_bpp / 8), priv->base + OBUF_LO_REG(slot));
++ iowrite32(cam->out_width, priv->base + OBUF_AW_REG(slot));
++ iowrite32(cam->out_height, priv->base + OBUF_AH_REG(slot));
++ iowrite32(cam->out_height, priv->base + OBUF_HM_REG(slot));
++ /* empty and validate out_buffer */
++ iowrite32(0, priv->base + OBUF_ST_REG(slot));
++ iowrite32((cam->out_bpp << 8) | 0x1, priv->base + OBUF_BV_REG(slot));
++}
++
++static int rcar_isp_setup(struct rcar_isp_priv *priv)
++{
++ struct soc_camera_device *icd = priv->ici.icd;
++ int bayer_pattern, axi_colourspace, raw_bpp;
++ int slot = 0;
++ int inport = 0;
++ int is_yuv = 0;
++
++ /* input interface */
++ switch (icd->current_fmt->code) {
++ case MEDIA_BUS_FMT_SRGGB8_1X8:
++ case MEDIA_BUS_FMT_SBGGR8_1X8:
++ case MEDIA_BUS_FMT_SGRBG8_1X8:
++ raw_bpp = 8;
++ break;
++ case MEDIA_BUS_FMT_SRGGB12_1X12:
++ case MEDIA_BUS_FMT_SBGGR12_1X12:
++ case MEDIA_BUS_FMT_SGRBG12_1X12:
++ raw_bpp = 12;
++ break;
++ case MEDIA_BUS_FMT_SGRBG14_1X14:
++ raw_bpp = 14;
++ break;
++ case MEDIA_BUS_FMT_SRGGB16_1X16:
++ case MEDIA_BUS_FMT_SBGGR16_1X16:
++ case MEDIA_BUS_FMT_SGRBG16_1X16:
++ raw_bpp = 16;
++ break;
++ default:
++ goto e_format;
++ }
++
++ switch (icd->current_fmt->code) {
++ case MEDIA_BUS_FMT_SRGGB8_1X8:
++ case MEDIA_BUS_FMT_SRGGB12_1X12:
++ case MEDIA_BUS_FMT_SRGGB16_1X16:
++ bayer_pattern = TOP_RGGB_RGrGbB; /* IMX390, AR0143 */
++ break;
++ case MEDIA_BUS_FMT_SBGGR8_1X8:
++ case MEDIA_BUS_FMT_SBGGR12_1X12:
++ case MEDIA_BUS_FMT_SBGGR16_1X16:
++ bayer_pattern = TOP_RGGB_BGbGrR; /* OV2775, OX03A */
++ break;
++ case MEDIA_BUS_FMT_SGRBG8_1X8:
++ case MEDIA_BUS_FMT_SGRBG12_1X12:
++ case MEDIA_BUS_FMT_SGRBG14_1X14:
++ case MEDIA_BUS_FMT_SGRBG16_1X16:
++ bayer_pattern = TOP_RGGB_GrRBGb; /* AR0132, AR0220 */
++ break;
++ default:
++ goto e_format;
++ }
++
++ /* output format */
++ switch (icd->current_fmt->host_fmt->fourcc) {
++ case V4L2_PIX_FMT_NV16:
++ axi_colourspace = AXIOUT_MS_YUV_UV8;
++ is_yuv = 1;
++ break;
++ case V4L2_PIX_FMT_XBGR32:
++ axi_colourspace = AXIOUT_MS_RGB888;
++ axi_colourspace |= AXIOUT_MSB_ALIGN;
++ break;
++ case V4L2_PIX_FMT_SBGGR8:
++ axi_colourspace = AXIOUT_MS_RAW8;
++ break;
++ case V4L2_PIX_FMT_SBGGR16:
++ axi_colourspace = AXIOUT_MS_RAW16;
++ axi_colourspace |= AXIOUT_MSB_ALIGN;
++ break;
++ default:
++ goto e_format;
++ }
++
++ rcar_isp_setup_inputs(priv, inport, raw_bpp);
++ rcar_isp_setup_mcfe(priv, MCFE_SLM0_PASSTHR(slot));
++ rcar_isp_setup_top(priv, bayer_pattern);
++ rcar_isp_setup_pipeline(priv, axi_colourspace, 0, is_yuv);
++
++ return 0;
++
++e_format:
++ dev_warn(icd->parent, "Invalid fourcc format (0x%x)\n",
++ icd->current_fmt->host_fmt->fourcc);
++ return -EINVAL;
++}
++
++static int rcar_isp_get_free_hw_slot(struct rcar_isp_priv *priv)
++{
++ int slot;
++
++ for (slot = 0; slot < priv->nr_hw_slots; slot++)
++ if (priv->queue_buf[slot] == NULL)
++ return slot;
++
++ return -1;
++}
++
++static int rcar_isp_hw_ready(struct rcar_isp_priv *priv)
++{
++ /* Ensure all HW slots are filled */
++ return rcar_isp_get_free_hw_slot(priv) < 0 ? 1 : 0;
++}
++
++/* Moves a buffer from the queue to the HW slot */
++static int rcar_isp_fill_hw_slot(struct rcar_isp_priv *priv)
++{
++ struct rcar_isp_cam *cam = priv->ici.icd->host_priv;
++ struct vb2_v4l2_buffer *vbuf;
++ dma_addr_t phys_addr_top;
++ int slot;
++
++ if (list_empty(&priv->capture))
++ return 0;
++
++ /* Find a free HW slot */
++ slot = rcar_isp_get_free_hw_slot(priv);
++ if (slot < 0)
++ return 0;
++
++ vbuf = &list_entry(priv->capture.next, struct rcar_isp_buffer, list)->vb;
++ list_del_init(to_buf_list(vbuf));
++ priv->queue_buf[slot] = vbuf;
++ phys_addr_top = vb2_dma_contig_plane_dma_addr(&vbuf->vb2_buf, 0);
++#if 1
++ rcar_isp_setup_out_buffer(priv, slot, phys_addr_top);
++#else
++ rcar_isp_setup_out_buffer(priv, 0, phys_addr_top); // Y
++ rcar_isp_setup_out_buffer(priv, 1, phys_addr_top + cam->out_width * cam->out_height); // UV
++#endif
++ return 1;
++}
++
++static int rcar_isp_videobuf_setup(struct vb2_queue *vq, unsigned int *count,
++ unsigned int *num_planes,
++ unsigned int sizes[], struct device *alloc_devs[])
++{
++ struct soc_camera_device *icd = soc_camera_from_vb2q(vq);
++ struct soc_camera_host *ici = to_soc_camera_host(icd->parent);
++ struct rcar_isp_priv *priv = ici->priv;
++
++ if (!vq->num_buffers)
++ priv->sequence = 0;
++
++ if (!*count)
++ *count = 2;
++ priv->vb_count = *count;
++
++ /* Number of hardware slots */
++ priv->nr_hw_slots = MAX_BUFFER_NUM;
++
++ if (*num_planes)
++ return sizes[0] < icd->sizeimage ? -EINVAL : 0;
++
++ sizes[0] = icd->sizeimage;
++ *num_planes = 1;
++
++ dev_dbg(icd->parent, "count=%d, size=%u\n", *count, sizes[0]);
++
++ return 0;
++}
++
++static void rcar_isp_videobuf_queue(struct vb2_buffer *vb)
++{
++ struct vb2_v4l2_buffer *vbuf = to_vb2_v4l2_buffer(vb);
++ struct soc_camera_device *icd = soc_camera_from_vb2q(vb->vb2_queue);
++ struct soc_camera_host *ici = to_soc_camera_host(icd->parent);
++ struct rcar_isp_priv *priv = ici->priv;
++ unsigned long size;
++
++ size = icd->sizeimage;
++
++ if (vb2_plane_size(vb, 0) < size) {
++ dev_err(icd->parent, "Buffer #%d too small (%lu < %lu)\n",
++ vb->index, vb2_plane_size(vb, 0), size);
++ goto error;
++ }
++
++ vb2_set_plane_payload(vb, 0, size);
++
++ dev_dbg(icd->parent, "%s (vb=0x%p) 0x%p %lu\n", __func__,
++ vb, vb2_plane_vaddr(vb, 0), vb2_get_plane_payload(vb, 0));
++
++ spin_lock_irq(&priv->lock);
++
++ list_add_tail(to_buf_list(vbuf), &priv->capture);
++ rcar_isp_fill_hw_slot(priv);
++
++ /* If we weren't running, and have enough buffers, start capturing! */
++ if (priv->state != RUNNING && rcar_isp_hw_ready(priv)) {
++ if (rcar_isp_setup(priv)) {
++ /* Submit error */
++ list_del_init(to_buf_list(vbuf));
++ spin_unlock_irq(&priv->lock);
++ goto error;
++ }
++ priv->state = RUNNING;
++ rcar_isp_start(priv);
++ }
++
++ spin_unlock_irq(&priv->lock);
++
++ return;
++
++error:
++ vb2_buffer_done(vb, VB2_BUF_STATE_ERROR);
++}
++
++static void rcar_isp_stop_streaming(struct vb2_queue *vq)
++{
++ struct soc_camera_device *icd = soc_camera_from_vb2q(vq);
++ struct soc_camera_host *ici = to_soc_camera_host(icd->parent);
++ struct rcar_isp_priv *priv = ici->priv;
++ struct list_head *buf_head, *tmp;
++ int i;
++
++ spin_lock_irq(&priv->lock);
++
++ if (priv->state == RUNNING) {
++ rcar_isp_stop(priv);
++ priv->state = STOPPED;
++ }
++
++ for (i = 0; i < MAX_BUFFER_NUM; i++) {
++ /* invalidate and empty out_buffer */
++ iowrite32(0, priv->base + OBUF_BV_REG(i));
++ iowrite32(0, priv->base + OBUF_ST_REG(i));
++ if (priv->queue_buf[i]) {
++ vb2_buffer_done(&priv->queue_buf[i]->vb2_buf,
++ VB2_BUF_STATE_ERROR);
++ priv->queue_buf[i] = NULL;
++ }
++ }
++
++ list_for_each_safe(buf_head, tmp, &priv->capture) {
++ vb2_buffer_done(&list_entry(buf_head,
++ struct rcar_isp_buffer, list)->vb.vb2_buf,
++ VB2_BUF_STATE_ERROR);
++ list_del_init(buf_head);
++ }
++
++ spin_unlock_irq(&priv->lock);
++}
++
++static const struct vb2_ops rcar_isp_vb2_ops = {
++ .queue_setup = rcar_isp_videobuf_setup,
++ .buf_queue = rcar_isp_videobuf_queue,
++ .stop_streaming = rcar_isp_stop_streaming,
++ .wait_prepare = vb2_ops_wait_prepare,
++ .wait_finish = vb2_ops_wait_finish,
++};
++
++static irqreturn_t rcar_isp_irq(int irq, void *data)
++{
++ struct rcar_isp_priv *priv = data;
++ u32 int_status;
++ int slot;
++ unsigned int handled = 0;
++
++ spin_lock(&priv->lock);
++
++ int_status = ioread32(priv->base + INT_FES_REG);
++ if (!int_status)
++ goto done;
++
++ /* ack interrupts */
++ iowrite32(int_status, priv->base + INT_FEC_REG);
++ /* enable frame end interrupt */
++ iowrite32(BIT(15), priv->base + INT_FEM_REG);
++ handled = 1;
++
++ if (priv->state == STOPPED)
++ goto done;
++
++ /* out_buffer not filled */
++ slot = ioread32(priv->base + MCFE_OWL_REG);
++ if (slot == 0x3f3f3f3f)
++ goto done;
++ slot &= 0xff; // tnis is for 1 camera support
++
++ if (!list_empty(&priv->capture)) {
++ priv->queue_buf[slot]->field = priv->field;
++ priv->queue_buf[slot]->sequence = priv->sequence++;
++ priv->queue_buf[slot]->vb2_buf.timestamp = ktime_get_ns();
++ vb2_buffer_done(&priv->queue_buf[slot]->vb2_buf, VB2_BUF_STATE_DONE);
++ priv->queue_buf[slot] = NULL;
++
++ rcar_isp_fill_hw_slot(priv);
++ } else {
++ rcar_isp_stop(priv);
++ priv->state = STOPPED;
++ }
++
++done:
++ spin_unlock(&priv->lock);
++
++ return IRQ_RETVAL(handled);
++}
++
++static struct v4l2_subdev *find_csi2(struct rcar_isp_priv *pcdev)
++{
++ struct v4l2_subdev *sd;
++ char name[] = "rcar_csi2";
++
++ v4l2_device_for_each_subdev(sd, &pcdev->ici.v4l2_dev) {
++ if (!strncmp(name, sd->name, sizeof(name) - 1)) {
++ pcdev->csi2_sd = sd;
++ return sd;
++ }
++ }
++
++ return NULL;
++}
++
++static struct v4l2_subdev *find_deser(struct rcar_isp_priv *pcdev)
++{
++ struct v4l2_subdev *sd;
++ char name[] = "max9286";
++ char name2[] = "ti9x4";
++
++ v4l2_device_for_each_subdev(sd, &pcdev->ici.v4l2_dev) {
++ if (!strncmp(name, sd->name, sizeof(name) - 1)) {
++ pcdev->deser_sd = sd;
++ return sd;
++ }
++ if (!strncmp(name2, sd->name, sizeof(name2) - 1)) {
++ pcdev->deser_sd = sd;
++ return sd;
++ }
++ }
++
++ return NULL;
++}
++
++static int rcar_isp_add_device(struct soc_camera_device *icd)
++{
++ struct soc_camera_host *ici = to_soc_camera_host(icd->parent);
++ struct rcar_isp_priv *priv = ici->priv;
++ int i;
++
++ for (i = 0; i < MAX_BUFFER_NUM; i++)
++ priv->queue_buf[i] = NULL;
++
++ pm_runtime_get_sync(ici->v4l2_dev.dev);
++
++ if (priv->chip == RCAR_V3M || priv->chip == RCAR_V3H) {
++ struct v4l2_subdev *csi2_sd = find_csi2(priv);
++ struct v4l2_subdev *deser_sd = find_deser(priv);
++ int ret = 0;
++
++ if (csi2_sd) {
++ csi2_sd->grp_id = soc_camera_grp_id(icd);
++ v4l2_set_subdev_hostdata(csi2_sd, icd);
++
++ ret = v4l2_subdev_call(csi2_sd, core, s_power, 1);
++ priv->csi_sync = true;
++
++ if (ret < 0 && ret != -EINVAL)
++ priv->csi_sync = false;
++
++ if (ret < 0 && ret != -ENOIOCTLCMD && ret != -ENODEV)
++ return ret;
++ }
++ if (deser_sd) {
++ v4l2_set_subdev_hostdata(deser_sd, icd);
++
++ ret = v4l2_subdev_call(deser_sd, core, s_power, 1);
++ priv->deser_sync = true;
++
++ if (ret < 0 && ret != -EINVAL)
++ priv->deser_sync = false;
++
++ if (ret < 0 && ret != -ENOIOCTLCMD && ret != -ENODEV)
++ return ret;
++ }
++ /*
++ * -ENODEV is special:
++ * either csi2_sd == NULL or the CSI-2 driver
++ * has not found this soc-camera device among its clients
++ */
++ if (csi2_sd && ret == -ENODEV)
++ csi2_sd->grp_id = 0;
++
++ dev_dbg(icd->parent,
++ "R-Car ISP/CSI-2 driver attached to camera %d\n",
++ icd->devnum);
++
++ } else
++ dev_dbg(icd->parent, "R-Car ISP driver attached to camera %d\n",
++ icd->devnum);
++
++ rcar_isp_open(priv);
++
++ return 0;
++}
++
++static void rcar_isp_remove_device(struct soc_camera_device *icd)
++{
++ struct soc_camera_host *ici = to_soc_camera_host(icd->parent);
++ struct rcar_isp_priv *priv = ici->priv;
++ struct vb2_v4l2_buffer *vbuf;
++ struct v4l2_subdev *csi2_sd = find_csi2(priv);
++ struct v4l2_subdev *deser_sd = find_deser(priv);
++ int i;
++
++ /* make sure active buffer is cancelled */
++ spin_lock_irq(&priv->lock);
++ for (i = 0; i < MAX_BUFFER_NUM; i++) {
++ vbuf = priv->queue_buf[i];
++ if (vbuf) {
++ list_del_init(to_buf_list(vbuf));
++ vb2_buffer_done(&vbuf->vb2_buf, VB2_BUF_STATE_ERROR);
++ }
++ }
++ spin_unlock_irq(&priv->lock);
++
++ rcar_isp_close(priv);
++
++ pm_runtime_put(ici->v4l2_dev.dev);
++
++ if ((csi2_sd) && (priv->csi_sync))
++ v4l2_subdev_call(csi2_sd, core, s_power, 0);
++ if ((deser_sd) && (priv->deser_sync))
++ v4l2_subdev_call(deser_sd, core, s_power, 0);
++
++ dev_dbg(icd->parent, "R-Car ISP driver detached from camera %d\n",
++ icd->devnum);
++}
++
++/* rect is guaranteed to not exceed the scaled camera rectangle */
++static int rcar_isp_set_rect(struct soc_camera_device *icd)
++{
++ struct rcar_isp_cam *cam = icd->host_priv;
++ unsigned int left_offset, top_offset;
++ struct v4l2_rect *cam_subrect = &cam->subrect;
++
++ dev_dbg(icd->parent, "Crop %ux%u@%u:%u\n",
++ icd->user_width, icd->user_height, cam->isp_left, cam->isp_top);
++
++ left_offset = cam->isp_left;
++ top_offset = cam->isp_top;
++
++ dev_dbg(icd->parent, "Cam %ux%u@%u:%u\n",
++ cam->width, cam->height, cam->isp_left, cam->isp_top);
++ dev_dbg(icd->parent, "Cam subrect %ux%u@%u:%u\n",
++ cam_subrect->width, cam_subrect->height,
++ cam_subrect->left, cam_subrect->top);
++
++ return 0;
++}
++
++#define ISP_MBUS_FLAGS (V4L2_MBUS_CSI2_LANES | \
++ V4L2_MBUS_CSI2_CHANNELS | \
++ V4L2_MBUS_CSI2_CONTINUOUS_CLOCK | \
++ V4L2_MBUS_CSI2_NONCONTINUOUS_CLOCK)
++
++static int rcar_isp_set_bus_param(struct soc_camera_device *icd)
++{
++ struct v4l2_subdev *sd = soc_camera_to_subdev(icd);
++ struct v4l2_mbus_config cfg;
++ unsigned long common_flags;
++ int ret;
++
++ ret = v4l2_subdev_call(sd, video, g_mbus_config, &cfg);
++ if (!ret) {
++ common_flags = soc_mbus_config_compatible(&cfg, ISP_MBUS_FLAGS);
++ if (!common_flags) {
++ dev_warn(icd->parent,
++ "MBUS flags incompatible: camera 0x%x, host 0x%x\n",
++ cfg.flags, ISP_MBUS_FLAGS);
++ return -EINVAL;
++ }
++ } else if (ret != -ENOIOCTLCMD) {
++ return ret;
++ } else {
++ common_flags = ISP_MBUS_FLAGS;
++ }
++
++ return 0;
++}
++
++static int rcar_isp_try_bus_param(struct soc_camera_device *icd,
++ unsigned char buswidth)
++{
++ struct v4l2_subdev *sd = soc_camera_to_subdev(icd);
++ struct v4l2_mbus_config cfg;
++ int ret;
++
++ ret = v4l2_subdev_call(sd, video, g_mbus_config, &cfg);
++ if (ret == -ENOIOCTLCMD)
++ return 0;
++ else if (ret)
++ return ret;
++
++ /* check is there common mbus flags */
++ ret = soc_mbus_config_compatible(&cfg, ISP_MBUS_FLAGS);
++ if (ret)
++ return 0;
++
++ dev_warn(icd->parent,
++ "MBUS flags incompatible: camera 0x%x, host 0x%x\n",
++ cfg.flags, ISP_MBUS_FLAGS);
++
++ return -EINVAL;
++}
++
++static bool rcar_isp_packing_supported(const struct soc_mbus_pixelfmt *fmt)
++{
++ return fmt->packing == SOC_MBUS_PACKING_NONE ||
++ (fmt->bits_per_sample > 8 &&
++ fmt->packing == SOC_MBUS_PACKING_EXTEND16);
++}
++
++static const struct soc_mbus_pixelfmt rcar_isp_formats[] = {
++ {
++ .fourcc = V4L2_PIX_FMT_NV16,
++ .name = "NV16",
++ .bits_per_sample = 16,
++ .packing = SOC_MBUS_PACKING_NONE,
++ .order = SOC_MBUS_ORDER_LE,
++ .layout = SOC_MBUS_LAYOUT_PACKED,
++ },
++ {
++ .fourcc = V4L2_PIX_FMT_XBGR32,
++ .name = "RGBX8888",
++ .bits_per_sample = 32,
++ .packing = SOC_MBUS_PACKING_NONE,
++ .order = SOC_MBUS_ORDER_LE,
++ .layout = SOC_MBUS_LAYOUT_PACKED,
++ },
++ {
++ .fourcc = V4L2_PIX_FMT_ABGR32,
++ .name = "ARGB8888",
++ .bits_per_sample = 32,
++ .packing = SOC_MBUS_PACKING_NONE,
++ .order = SOC_MBUS_ORDER_LE,
++ .layout = SOC_MBUS_LAYOUT_PACKED,
++ },
++ {
++ .fourcc = V4L2_PIX_FMT_SBGGR8,
++ .name = "Bayer 8 BGGR",
++ .bits_per_sample = 8,
++ .packing = SOC_MBUS_PACKING_NONE,
++ .order = SOC_MBUS_ORDER_LE,
++ .layout = SOC_MBUS_LAYOUT_PACKED,
++ },
++ {
++ .fourcc = V4L2_PIX_FMT_SBGGR16,
++ .name = "Bayer 16 BGGR",
++ .bits_per_sample = 16,
++ .packing = SOC_MBUS_PACKING_NONE,
++ .order = SOC_MBUS_ORDER_LE,
++ .layout = SOC_MBUS_LAYOUT_PACKED,
++ },
++};
++
++static int rcar_isp_get_formats(struct soc_camera_device *icd, unsigned int idx,
++ struct soc_camera_format_xlate *xlate)
++{
++ struct v4l2_subdev *sd = soc_camera_to_subdev(icd);
++ struct device *dev = icd->parent;
++ int ret, k, n;
++ int formats = 0;
++ struct rcar_isp_cam *cam;
++ struct soc_camera_host *ici = to_soc_camera_host(icd->parent);
++ struct rcar_isp_priv *priv = ici->priv;
++ struct v4l2_subdev_mbus_code_enum code = {
++ .which = V4L2_SUBDEV_FORMAT_ACTIVE,
++ .index = idx,
++ };
++ const struct soc_mbus_pixelfmt *fmt;
++
++ ret = v4l2_subdev_call(sd, pad, enum_mbus_code, NULL, &code);
++ if (ret < 0)
++ return 0;
++
++ fmt = soc_mbus_get_fmtdesc(code.code);
++ if (!fmt) {
++ dev_warn(dev, "unsupported format code #%u: %d\n", idx, code.code);
++ return 0;
++ }
++
++ ret = rcar_isp_try_bus_param(icd, fmt->bits_per_sample);
++ if (ret < 0)
++ return 0;
++
++ if (!icd->host_priv) {
++ struct v4l2_subdev_format fmt = {
++ .which = V4L2_SUBDEV_FORMAT_ACTIVE,
++ };
++ struct v4l2_mbus_framefmt *mf = &fmt.format;
++ struct v4l2_rect rect;
++ struct device *dev = icd->parent;
++ int shift;
++
++ ret = v4l2_subdev_call(sd, pad, get_fmt, NULL, &fmt);
++ if (ret < 0)
++ return ret;
++
++ /* Cache current client geometry */
++ ret = soc_camera_client_g_rect(sd, &rect);
++ if (ret == -ENOIOCTLCMD) {
++ /* Sensor driver doesn't support cropping */
++ rect.left = 0;
++ rect.top = 0;
++ rect.width = mf->width;
++ rect.height = mf->height;
++ } else if (ret < 0) {
++ return ret;
++ }
++
++ /*
++ * If sensor proposes too large format then try smaller ones:
++ * 1280x960, 640x480, 320x240
++ */
++ for (shift = 0; shift < 3; shift++) {
++ if (mf->width <= priv->max_width &&
++ mf->height <= priv->max_height)
++ break;
++
++ mf->width = 1280 >> shift;
++ mf->height = 960 >> shift;
++ ret = v4l2_device_call_until_err(sd->v4l2_dev,
++ soc_camera_grp_id(icd),
++ pad, set_fmt, NULL,
++ &fmt);
++ if (ret < 0)
++ return ret;
++ }
++
++ if (shift == 3) {
++ dev_err(dev,
++ "Failed to configure the client below %ux%u\n",
++ mf->width, mf->height);
++ return -EIO;
++ }
++
++ dev_dbg(dev, "camera fmt %ux%u\n", mf->width, mf->height);
++
++ cam = kzalloc(sizeof(*cam), GFP_KERNEL);
++ if (!cam)
++ return -ENOMEM;
++ /*
++ * We are called with current camera crop,
++ * initialise subrect with it
++ */
++ cam->rect = rect;
++ cam->subrect = rect;
++ cam->width = mf->width;
++ cam->height = mf->height;
++ cam->out_width = mf->width;
++ cam->out_height = mf->height;
++
++ icd->host_priv = cam;
++ } else {
++ cam = icd->host_priv;
++ }
++
++ /* Beginning of a pass */
++ if (!idx)
++ cam->extra_fmt = NULL;
++
++ switch (code.code) {
++ case MEDIA_BUS_FMT_SBGGR8_1X8:
++ case MEDIA_BUS_FMT_SBGGR12_1X12:
++ case MEDIA_BUS_FMT_SBGGR16_1X16:
++ case MEDIA_BUS_FMT_SRGGB8_1X8:
++ case MEDIA_BUS_FMT_SRGGB12_1X12:
++ case MEDIA_BUS_FMT_SRGGB16_1X16:
++ case MEDIA_BUS_FMT_SGRBG8_1X8:
++ case MEDIA_BUS_FMT_SGRBG12_1X12:
++ case MEDIA_BUS_FMT_SGRBG14_1X14:
++ case MEDIA_BUS_FMT_SGRBG16_1X16:
++ if (cam->extra_fmt)
++ break;
++
++ /* Add all our formats that can be generated by ISP */
++ cam->extra_fmt = rcar_isp_formats;
++
++ n = ARRAY_SIZE(rcar_isp_formats);
++ formats += n;
++ for (k = 0; xlate && k < n; k++, xlate++) {
++ xlate->host_fmt = &rcar_isp_formats[k];
++ xlate->code = code.code;
++ dev_dbg(dev, "Providing format %s using code %d\n",
++ rcar_isp_formats[k].name, code.code);
++ }
++ break;
++ default:
++ if (!rcar_isp_packing_supported(fmt))
++ return 0;
++
++ dev_dbg(dev, "Providing format %s in pass-through mode\n",
++ fmt->name);
++ break;
++ }
++
++ /* Generic pass-through */
++ formats++;
++ if (xlate) {
++ xlate->host_fmt = fmt;
++ xlate->code = code.code;
++ xlate++;
++ }
++
++ return formats;
++}
++
++static void rcar_isp_put_formats(struct soc_camera_device *icd)
++{
++ kfree(icd->host_priv);
++ icd->host_priv = NULL;
++}
++
++static int rcar_isp_set_selection(struct soc_camera_device *icd,
++ struct v4l2_selection *sel)
++{
++ const struct v4l2_rect *rect = &sel->r;
++ struct soc_camera_host *ici = to_soc_camera_host(icd->parent);
++ struct rcar_isp_priv *priv = ici->priv;
++ struct v4l2_selection cam_sel;
++ struct rcar_isp_cam *cam = icd->host_priv;
++ struct v4l2_rect *cam_rect = &cam_sel.r;
++ struct v4l2_subdev *sd = soc_camera_to_subdev(icd);
++ struct device *dev = icd->parent;
++ struct v4l2_subdev_format fmt = {
++ .which = V4L2_SUBDEV_FORMAT_ACTIVE,
++ };
++ struct v4l2_mbus_framefmt *mf = &fmt.format;
++ int ret;
++
++ dev_dbg(dev, "S_SELECTION(%ux%u@%u:%u)\n", rect->width, rect->height,
++ rect->left, rect->top);
++
++ /* Apply iterative camera S_SELECTION for new input window. */
++ ret = soc_camera_client_s_selection(sd, sel, &cam_sel,
++ &cam->rect, &cam->subrect);
++ if (ret < 0)
++ return ret;
++
++ dev_dbg(dev, "camera cropped to %ux%u@%u:%u\n",
++ cam_rect->width, cam_rect->height,
++ cam_rect->left, cam_rect->top);
++
++ /* On success cam_crop contains current camera crop */
++
++ /* Retrieve camera output window */
++ ret = v4l2_subdev_call(sd, pad, get_fmt, NULL, &fmt);
++ if (ret < 0)
++ return ret;
++
++ if (mf->width > priv->max_width || mf->height > priv->max_height)
++ return -EINVAL;
++
++ /* Cache camera output window */
++ cam->width = mf->width;
++ cam->height = mf->height;
++
++ cam->isp_left = rect->left;
++ cam->isp_top = rect->top;
++
++ /* Use ISP cropping to crop to the new window. */
++ ret = rcar_isp_set_rect(icd);
++ if (ret < 0)
++ return ret;
++
++ dev_dbg(dev, "ISP cropped to %ux%u@%u:%u\n",
++ icd->user_width, icd->user_height,
++ cam->isp_left, cam->isp_top);
++
++ /* Even if only camera cropping succeeded */
++ return ret;
++}
++
++static int rcar_isp_get_selection(struct soc_camera_device *icd,
++ struct v4l2_selection *sel)
++{
++ struct rcar_isp_cam *cam = icd->host_priv;
++
++ sel->r = cam->subrect;
++
++ return 0;
++}
++
++static int rcar_isp_set_fmt(struct soc_camera_device *icd,
++ struct v4l2_format *f)
++{
++ struct rcar_isp_cam *cam = icd->host_priv;
++ struct v4l2_pix_format *pix = &f->fmt.pix;
++ struct v4l2_mbus_framefmt mf;
++ struct device *dev = icd->parent;
++ __u32 pixfmt = pix->pixelformat;
++ const struct soc_camera_format_xlate *xlate;
++ unsigned int isp_sub_width = 0, isp_sub_height = 0;
++ int ret;
++ bool can_scale = false;
++
++ dev_dbg(dev, "S_FMT(pix=0x%x, %ux%u)\n", pixfmt, pix->width, pix->height);
++
++ xlate = soc_camera_xlate_by_fourcc(icd, pixfmt);
++ if (!xlate) {
++ dev_warn(dev, "Format %x not found\n", pixfmt);
++ return -EINVAL;
++ }
++ /* Calculate client output geometry */
++ soc_camera_calc_client_output(icd, &cam->rect, &cam->subrect, pix, &mf, 12);
++ mf.field = pix->field;
++ mf.colorspace = pix->colorspace;
++ mf.code = xlate->code;
++
++ switch (pixfmt) {
++ case V4L2_PIX_FMT_XBGR32:
++ case V4L2_PIX_FMT_XRGB32:
++ cam->out_bpp = 32;
++ break;
++ case V4L2_PIX_FMT_NV16:
++ case V4L2_PIX_FMT_SBGGR16:
++ cam->out_bpp = 16;
++ break;
++ case V4L2_PIX_FMT_SBGGR8:
++ cam->out_bpp = 8;
++ break;
++ default:
++ break;
++ }
++
++ dev_dbg(dev, "request camera output %ux%u\n", mf.width, mf.height);
++
++ ret = soc_camera_client_scale(icd, &cam->rect, &cam->subrect,
++ &mf, &isp_sub_width, &isp_sub_height,
++ can_scale, 12);
++
++ /* Done with the camera. Now see if we can improve the result */
++ dev_dbg(dev, "Camera %d fmt %ux%u, requested %ux%u\n",
++ ret, mf.width, mf.height, pix->width, pix->height);
++
++ if (ret == -ENOIOCTLCMD)
++ dev_dbg(dev, "Sensor doesn't support scaling\n");
++ else if (ret < 0)
++ return ret;
++
++ if (mf.code != xlate->code)
++ return -EINVAL;
++
++ /* Prepare ISP crop */
++ cam->width = mf.width;
++ cam->height = mf.height;
++
++ /* We cannot scale up */
++ if (pix->width > isp_sub_width)
++ isp_sub_width = pix->width;
++
++ if (pix->height > isp_sub_height)
++ isp_sub_height = pix->height;
++
++ pix->colorspace = mf.colorspace;
++
++ if (!can_scale) {
++ pix->width = isp_sub_width;
++ pix->height = isp_sub_height;
++ }
++
++ dev_dbg(dev, "W: %u : %u, H: %u : %u\n",
++ isp_sub_width, pix->width, isp_sub_height, pix->height);
++
++ cam->out_width = pix->width;
++ cam->out_height = pix->height;
++
++ icd->current_fmt = xlate;
++
++ return 0;
++}
++
++static int rcar_isp_try_fmt(struct soc_camera_device *icd,
++ struct v4l2_format *f)
++{
++ const struct soc_camera_format_xlate *xlate;
++ struct v4l2_pix_format *pix = &f->fmt.pix;
++ struct v4l2_subdev *sd = soc_camera_to_subdev(icd);
++ struct v4l2_subdev_pad_config pad_cfg;
++ struct v4l2_subdev_format format = {
++ .which = V4L2_SUBDEV_FORMAT_TRY,
++ };
++ struct v4l2_mbus_framefmt *mf = &format.format;
++ __u32 pixfmt = pix->pixelformat;
++ int width, height;
++ int ret;
++
++ xlate = soc_camera_xlate_by_fourcc(icd, pixfmt);
++ if (!xlate) {
++ xlate = icd->current_fmt;
++ dev_dbg(icd->parent, "Format %x not found, keeping %x\n",
++ pixfmt, xlate->host_fmt->fourcc);
++ pixfmt = xlate->host_fmt->fourcc;
++ pix->pixelformat = pixfmt;
++ pix->colorspace = icd->colorspace;
++ }
++
++ width = pix->width;
++ height = pix->height;
++
++ /* let soc-camera calculate these values */
++ pix->bytesperline = 0;
++ pix->sizeimage = 0;
++
++ /* limit to sensor capabilities */
++ mf->width = pix->width;
++ mf->height = pix->height;
++ mf->field = pix->field;
++ mf->code = xlate->code;
++ mf->colorspace = pix->colorspace;
++
++ ret = v4l2_device_call_until_err(sd->v4l2_dev, soc_camera_grp_id(icd),
++ pad, set_fmt, &pad_cfg, &format);
++ if (ret < 0)
++ return ret;
++
++ pix->field = mf->field;
++ pix->colorspace = mf->colorspace;
++
++ return ret;
++}
++
++static unsigned int rcar_isp_poll(struct file *file, poll_table *pt)
++{
++ struct soc_camera_device *icd = file->private_data;
++
++ return vb2_poll(&icd->vb2_vidq, file, pt);
++}
++
++static int rcar_isp_querycap(struct soc_camera_host *ici,
++ struct v4l2_capability *cap)
++{
++ strlcpy(cap->card, "R_Car_ISP", sizeof(cap->card));
++ cap->device_caps = V4L2_CAP_VIDEO_CAPTURE | V4L2_CAP_STREAMING;
++ cap->capabilities = cap->device_caps | V4L2_CAP_DEVICE_CAPS;
++ snprintf(cap->bus_info, sizeof(cap->bus_info), "platform:%s%d", DRV_NAME, ici->nr);
++
++ return 0;
++}
++
++static int rcar_isp_init_videobuf2(struct vb2_queue *vq,
++ struct soc_camera_device *icd)
++{
++ struct soc_camera_host *ici = to_soc_camera_host(icd->parent);
++
++ vq->type = V4L2_BUF_TYPE_VIDEO_CAPTURE;
++ vq->io_modes = VB2_MMAP | VB2_USERPTR | VB2_DMABUF;
++ vq->drv_priv = icd;
++ vq->ops = &rcar_isp_vb2_ops;
++ vq->mem_ops = &vb2_dma_contig_memops;
++ vq->buf_struct_size = sizeof(struct rcar_isp_buffer);
++ vq->timestamp_flags = V4L2_BUF_FLAG_TIMESTAMP_MONOTONIC;
++ vq->lock = &ici->host_lock;
++ vq->dev = ici->v4l2_dev.dev;
++
++ return vb2_queue_init(vq);
++}
++
++static int rcar_isp_get_edid(struct soc_camera_device *icd,
++ struct v4l2_edid *edid)
++{
++ struct v4l2_subdev *sd = soc_camera_to_subdev(icd);
++ int ret;
++
++ ret = v4l2_subdev_call(sd, pad, get_edid, edid);
++ if (ret < 0)
++ return ret;
++
++ return 0;
++}
++
++#ifdef CONFIG_VIDEO_ADV_DEBUG
++static int rcar_isp_get_register(struct soc_camera_device *icd,
++ struct v4l2_dbg_register *reg)
++{
++ struct soc_camera_host *ici = to_soc_camera_host(icd->parent);
++ struct rcar_isp_priv *priv = ici->priv;
++
++ if (reg->reg > 0x1ffff)
++ return -ERANGE;
++
++ reg->val = ioread32(priv->base + reg->reg);
++// reg->val = ioread32(priv->interface.base + reg->reg);
++// reg->val = ioread32(slot_ctx[0].vaddr + reg->reg);
++ reg->size = sizeof(u32);
++
++ return 0;
++}
++
++static int rcar_isp_set_register(struct soc_camera_device *icd,
++ const struct v4l2_dbg_register *reg)
++{
++ struct soc_camera_host *ici = to_soc_camera_host(icd->parent);
++ struct rcar_isp_priv *priv = ici->priv;
++
++ if (reg->reg > 0x1ffff)
++ return -ERANGE;
++ iowrite32(reg->val, priv->base + reg->reg);
++// iowrite32(reg->val, priv->interface.base + reg->reg);
++// iowrite32(reg->val,slot_ctx[0].vaddr + reg->reg);
++
++ return 0;
++}
++#endif
++
++static struct soc_camera_host_ops rcar_isp_host_ops = {
++ .owner = THIS_MODULE,
++ .add = rcar_isp_add_device,
++ .remove = rcar_isp_remove_device,
++ .get_formats = rcar_isp_get_formats,
++ .put_formats = rcar_isp_put_formats,
++ .get_selection = rcar_isp_get_selection,
++ .set_selection = rcar_isp_set_selection,
++ .try_fmt = rcar_isp_try_fmt,
++ .set_fmt = rcar_isp_set_fmt,
++ .poll = rcar_isp_poll,
++ .querycap = rcar_isp_querycap,
++ .set_bus_param = rcar_isp_set_bus_param,
++ .init_videobuf2 = rcar_isp_init_videobuf2,
++ .get_edid = rcar_isp_get_edid,
++#ifdef CONFIG_VIDEO_ADV_DEBUG
++ .get_register = rcar_isp_get_register,
++ .set_register = rcar_isp_set_register,
++#endif
++};
++
++#ifdef CONFIG_OF
++static const struct of_device_id rcar_isp_of_table[] = {
++ { .compatible = "renesas,isp-r8a77980", .data = (void *)RCAR_V3H },
++ { .compatible = "renesas,isp-r8a77970", .data = (void *)RCAR_V3M },
++ { .compatible = "renesas,rcar-gen3-isp", .data = (void *)RCAR_GEN3 },
++ { },
++};
++MODULE_DEVICE_TABLE(of, rcar_isp_of_table);
++#endif
++
++#define MAP_MAX_NUM 128
++static DECLARE_BITMAP(device_map, MAP_MAX_NUM);
++static DEFINE_MUTEX(list_lock);
++
++static int rcar_isp_dyn_pdev(struct soc_camera_desc *sdesc,
++ struct rcar_isp_async_client *sasc)
++{
++ struct platform_device *pdev;
++ int ret, i;
++
++ mutex_lock(&list_lock);
++ i = find_first_zero_bit(device_map, MAP_MAX_NUM);
++ if (i < MAP_MAX_NUM)
++ set_bit(i, device_map);
++ mutex_unlock(&list_lock);
++ if (i >= MAP_MAX_NUM)
++ return -ENOMEM;
++
++ pdev = platform_device_alloc("soc-camera-pdrv", ((2 * i) + 1));
++ if (!pdev)
++ return -ENOMEM;
++
++ ret = platform_device_add_data(pdev, sdesc, sizeof(*sdesc));
++ if (ret < 0) {
++ platform_device_put(pdev);
++ return ret;
++ }
++
++ sasc->pdev = pdev;
++
++ return 0;
++}
++
++static int rcar_isp_async_bound(struct v4l2_async_notifier *notifier,
++ struct v4l2_subdev *sd,
++ struct v4l2_async_subdev *asd)
++{
++ return 0;
++}
++
++static void rcar_isp_async_unbind(struct v4l2_async_notifier *notifier,
++ struct v4l2_subdev *sd,
++ struct v4l2_async_subdev *asd)
++{
++}
++
++static int rcar_isp_async_probe(struct soc_camera_host *ici,
++ struct soc_camera_device *icd)
++{
++ struct soc_camera_desc *sdesc = to_soc_camera_desc(icd);
++ struct soc_camera_host_desc *shd = &sdesc->host_desc;
++ struct device *control = NULL;
++ int ret;
++
++ ret = v4l2_ctrl_handler_init(&icd->ctrl_handler, 16);
++ if (ret < 0)
++ return ret;
++
++ if (shd->module_name)
++ ret = request_module(shd->module_name);
++
++ ret = shd->add_device(icd);
++
++ control = to_soc_camera_control(icd);
++ if (!control || !control->driver || !dev_get_drvdata(control) ||
++ !try_module_get(control->driver->owner)) {
++ shd->del_device(icd);
++ ret = -ENODEV;
++ }
++
++ return ret;
++}
++
++static int rcar_isp_async_complete(struct v4l2_async_notifier *notifier)
++{
++ struct rcar_isp_async_client *sasc = container_of(notifier,
++ struct rcar_isp_async_client, notifier);
++ struct soc_camera_device *icd = platform_get_drvdata(sasc->pdev);
++
++ if (to_soc_camera_control(icd)) {
++ struct soc_camera_host *ici = to_soc_camera_host(icd->parent);
++ int ret;
++
++ mutex_lock(&list_lock);
++ ret = rcar_isp_async_probe(ici, icd);
++ mutex_unlock(&list_lock);
++ if (ret < 0)
++ return ret;
++ }
++
++ return 0;
++}
++
++static struct soc_camera_device *rcar_isp_add_pdev(struct rcar_isp_async_client *sasc)
++{
++ struct platform_device *pdev = sasc->pdev;
++ int ret;
++
++ ret = platform_device_add(pdev);
++
++ if (ret < 0 || !pdev->dev.driver)
++ return NULL;
++
++ return platform_get_drvdata(pdev);
++}
++
++static const struct v4l2_async_notifier_operations rcar_isp_notifier_ops = {
++ .bound = rcar_isp_async_bound,
++ .unbind = rcar_isp_async_unbind,
++ .complete = rcar_isp_async_complete,
++};
++
++static int rcar_isp_soc_of_bind(struct rcar_isp_priv *priv,
++ struct soc_camera_host *ici,
++ struct device_node *ep,
++ struct device_node *remote)
++{
++ struct soc_camera_device *icd;
++ struct soc_camera_desc sdesc = {.host_desc.bus_id = ici->nr,};
++ struct rcar_isp_async_client *sasc;
++ struct soc_of_info *info;
++ struct i2c_client *client;
++ char clk_name[V4L2_SUBDEV_NAME_SIZE];
++ int ret;
++
++ /* allocate a new subdev and add match info to it */
++ info = devm_kzalloc(ici->v4l2_dev.dev, sizeof(struct soc_of_info),
++ GFP_KERNEL);
++ if (!info)
++ return -ENOMEM;
++
++ info->sasd.asd.match.fwnode.fwnode = of_fwnode_handle(remote);
++ info->sasd.asd.match_type = V4L2_ASYNC_MATCH_FWNODE;
++ info->subdev = &info->sasd.asd;
++
++ /* Or shall this be managed by the soc-camera device? */
++ sasc = &info->sasc;
++
++ ret = rcar_isp_dyn_pdev(&sdesc, sasc);
++ if (ret < 0)
++ goto eallocpdev;
++
++ sasc->sensor = &info->sasd.asd;
++
++ icd = rcar_isp_add_pdev(sasc);
++ if (!icd) {
++ ret = -ENOMEM;
++ goto eaddpdev;
++ }
++
++ sasc->notifier.subdevs = &info->subdev;
++ sasc->notifier.num_subdevs = 1;
++ sasc->notifier.ops = &rcar_isp_notifier_ops;
++
++ priv->async_client = sasc;
++
++ client = of_find_i2c_device_by_node(remote);
++
++ if (client)
++ snprintf(clk_name, sizeof(clk_name), "%d-%04x",
++ client->adapter->nr, client->addr);
++ else
++ snprintf(clk_name, sizeof(clk_name), "of-%s",
++ of_node_full_name(remote));
++
++ ret = v4l2_async_notifier_register(&ici->v4l2_dev, &sasc->notifier);
++ if (!ret)
++ return 0;
++
++ platform_device_del(sasc->pdev);
++eaddpdev:
++ platform_device_put(sasc->pdev);
++eallocpdev:
++ devm_kfree(ici->v4l2_dev.dev, info);
++ dev_err(ici->v4l2_dev.dev, "group probe failed: %d\n", ret);
++
++ return ret;
++}
++
++static int rcar_isp_probe(struct platform_device *pdev)
++{
++ const struct of_device_id *match = NULL;
++ struct rcar_isp_priv *priv;
++ struct v4l2_fwnode_endpoint ep;
++ struct device_node *np;
++ struct resource *mem;
++ int irq, ret;
++ const char *str;
++ unsigned int i;
++ struct device_node *epn = NULL, *ren = NULL;
++ struct device_node *csi2_ren = NULL, *max9286_ren = NULL, *ti9x4_ren = NULL;
++ bool csi_use = false;
++ bool max9286_use = false;
++ bool ti9x4_use = false;
++
++ match = of_match_device(of_match_ptr(rcar_isp_of_table), &pdev->dev);
++
++ np = of_graph_get_next_endpoint(pdev->dev.of_node, NULL);
++ if (!np) {
++ dev_err(&pdev->dev, "could not find endpoint\n");
++ return -EINVAL;
++ }
++
++ for (i = 0; ; i++) {
++ epn = of_graph_get_next_endpoint(pdev->dev.of_node, epn);
++ if (!epn)
++ break;
++
++ ren = of_graph_get_remote_port(epn);
++ if (!ren) {
++ dev_notice(&pdev->dev, "no remote for %s\n",
++ of_node_full_name(epn));
++ continue;
++ }
++
++ dev_dbg(&pdev->dev, "node name:%s\n", of_node_full_name(ren->parent));
++
++ if (strcmp(ren->parent->name, "csi2") == 0) {
++ csi2_ren = ren;
++ csi_use = true;
++ }
++
++ if (strcmp(ren->parent->name, "max9286") == 0) {
++ max9286_ren = of_parse_phandle(epn, "remote-endpoint", 0);
++ max9286_use = true;
++ }
++
++ if (strcmp(ren->parent->name, "ti9x4") == 0) {
++ ti9x4_ren = of_parse_phandle(epn, "remote-endpoint", 0);
++ ti9x4_use = true;
++ }
++
++ of_node_put(ren);
++ }
++
++ ret = v4l2_fwnode_endpoint_parse(of_fwnode_handle(np), &ep);
++ if (ret) {
++ dev_err(&pdev->dev, "could not parse endpoint\n");
++ return ret;
++ }
++
++ of_node_put(np);
++
++ priv = devm_kzalloc(&pdev->dev, sizeof(struct rcar_isp_priv),
++ GFP_KERNEL);
++ if (!priv)
++ return -ENOMEM;
++
++ /* ISP Core */
++ mem = platform_get_resource(pdev, IORESOURCE_MEM, 0);
++ if (mem == NULL)
++ return -EINVAL;
++
++ irq = platform_get_irq(pdev, 0);
++ if (irq <= 0)
++ return -EINVAL;
++
++ priv->base = devm_ioremap_resource(&pdev->dev, mem);
++ if (IS_ERR(priv->base))
++ return PTR_ERR(priv->base);
++
++ ret = devm_request_irq(&pdev->dev, irq, rcar_isp_irq, IRQF_SHARED,
++ dev_name(&pdev->dev), priv);
++ if (ret)
++ return ret;
++
++ /* ISP Interface */
++ mem = platform_get_resource(pdev, IORESOURCE_MEM, 1);
++ if (mem == NULL)
++ return -EINVAL;
++
++ irq = platform_get_irq(pdev, 1);
++ if (irq <= 0)
++ return -EINVAL;
++
++ priv->interface.base = devm_ioremap_resource(&pdev->dev, mem);
++ if (IS_ERR(priv->base))
++ return PTR_ERR(priv->base);
++#if 0
++ ret = devm_request_irq(&pdev->dev, irq, rcar_isp_interface_irq, IRQF_SHARED,
++ dev_name(&pdev->dev), priv);
++ if (ret)
++ return ret;
++#endif
++ priv->ici.priv = priv;
++ priv->ici.v4l2_dev.dev = &pdev->dev;
++ priv->ici.drv_name = dev_name(&pdev->dev);
++ priv->ici.ops = &rcar_isp_host_ops;
++ priv->csi_sync = false;
++ priv->deser_sync = false;
++ priv->dev = &pdev->dev;
++
++ if (!match) {
++ priv->ici.nr = pdev->id;
++ priv->chip = pdev->id_entry->driver_data;
++ } else {
++ priv->ici.nr = of_alias_get_id(pdev->dev.of_node, "isp");
++ priv->chip = (enum chip_id)match->data;
++ }
++
++ priv->max_width = 4096;
++ priv->max_height = 4096;
++
++ if ((priv->chip == RCAR_V3M || priv->chip == RCAR_V3H) &&
++ !of_property_read_string(np, "csi,select", &str)) {
++ int vc;
++
++ if (strcmp(dev_name(priv->ici.v4l2_dev.dev),
++ "fec00000.isp") == 0)
++ priv->index = RCAR_ISP_CH_0;
++ else if (strcmp(dev_name(priv->ici.v4l2_dev.dev),
++ "fee00000.isp") == 0)
++ priv->index = RCAR_ISP_CH_1;
++ else
++ priv->index = RCAR_ISP_CH_NONE;
++
++ if (strcmp(str, "csi40") == 0)
++ priv->csi_ch = RCAR_CSI40;
++ else if (strcmp(str, "csi41") == 0)
++ priv->csi_ch = RCAR_CSI41;
++ else
++ priv->csi_ch = RCAR_CSI_CH_NONE;
++
++ ret = of_property_read_u32(np, "virtual,channel", &vc);
++ if (ret) {
++ dev_err(&pdev->dev,
++ "could not parse virtual,channel\n");
++ return ret;
++ }
++
++ if (vc == 0)
++ priv->vc = RCAR_VIRTUAL_CH0;
++ else if (vc == 1)
++ priv->vc = RCAR_VIRTUAL_CH1;
++ else if (vc == 2)
++ priv->vc = RCAR_VIRTUAL_CH2;
++ else if (vc == 3)
++ priv->vc = RCAR_VIRTUAL_CH3;
++ else
++ priv->vc = RCAR_VIRTUAL_NONE;
++
++ dev_dbg(&pdev->dev, "csi_ch:%d, vc:%d\n",
++ priv->csi_ch, priv->vc);
++ }
++
++ spin_lock_init(&priv->lock);
++ INIT_LIST_HEAD(&priv->capture);
++
++ priv->state = STOPPED;
++
++ pm_suspend_ignore_children(&pdev->dev, true);
++ pm_runtime_enable(&pdev->dev);
++
++ ret = soc_camera_host_register(&priv->ici);
++ if (ret)
++ goto cleanup;
++
++ if (csi_use) {
++ ret = rcar_isp_soc_of_bind(priv, &priv->ici, epn, csi2_ren->parent);
++ if (ret)
++ goto cleanup;
++ }
++
++ if (max9286_use) {
++ ret = rcar_isp_soc_of_bind(priv, &priv->ici, epn, max9286_ren);
++ if (ret)
++ goto cleanup;
++ }
++
++ if (ti9x4_use) {
++ ret = rcar_isp_soc_of_bind(priv, &priv->ici, epn, ti9x4_ren);
++ if (ret)
++ goto cleanup;
++ }
++
++ return 0;
++
++cleanup:
++ pm_runtime_disable(&pdev->dev);
++
++ return ret;
++}
++
++static int rcar_isp_remove(struct platform_device *pdev)
++{
++ struct soc_camera_host *soc_host = to_soc_camera_host(&pdev->dev);
++ struct rcar_isp_priv *priv = container_of(soc_host,
++ struct rcar_isp_priv, ici);
++
++ platform_device_del(priv->async_client->pdev);
++ platform_device_put(priv->async_client->pdev);
++
++ v4l2_async_notifier_unregister(&priv->async_client->notifier);
++
++ soc_camera_host_unregister(soc_host);
++ pm_runtime_disable(&pdev->dev);
++
++ return 0;
++}
++
++#ifdef CONFIG_PM_SLEEP
++static int rcar_isp_suspend(struct device *dev)
++{
++ return 0;
++}
++
++static int rcar_isp_resume(struct device *dev)
++{
++ return 0;
++}
++
++static SIMPLE_DEV_PM_OPS(rcar_isp_pm_ops,
++ rcar_isp_suspend, rcar_isp_resume);
++#define DEV_PM_OPS (&rcar_isp_pm_ops)
++#else
++#define DEV_PM_OPS NULL
++#endif /* CONFIG_PM_SLEEP */
++
++static struct platform_driver rcar_isp_driver = {
++ .probe = rcar_isp_probe,
++ .remove = rcar_isp_remove,
++ .driver = {
++ .name = DRV_NAME,
++ .pm = DEV_PM_OPS,
++ .of_match_table = of_match_ptr(rcar_isp_of_table),
++ },
++};
++
++module_platform_driver(rcar_isp_driver);
++
++MODULE_ALIAS("platform:rcar_isp");
++MODULE_AUTHOR("Cogent Embedded Inc. <sources@cogentembedded.com>");
++MODULE_DESCRIPTION("Renesas R-Car ISP camera host driver");
++MODULE_LICENSE("GPL");
+--
+2.7.4
+
diff --git a/bsp/meta-rcar/meta-rcar-gen3-adas/recipes-kernel/linux/linux-renesas/0296-media-platform-soc_camera-rcar_isp-Fix-unused-variab.patch b/bsp/meta-rcar/meta-rcar-gen3-adas/recipes-kernel/linux/linux-renesas/0296-media-platform-soc_camera-rcar_isp-Fix-unused-variab.patch
new file mode 100644
index 00000000..482cf44b
--- /dev/null
+++ b/bsp/meta-rcar/meta-rcar-gen3-adas/recipes-kernel/linux/linux-renesas/0296-media-platform-soc_camera-rcar_isp-Fix-unused-variab.patch
@@ -0,0 +1,51 @@
+From 050b4c8341386b0221c546b01ec30be9aaa6c897 Mon Sep 17 00:00:00 2001
+From: Valentine Barshak <valentine.barshak@cogentembedded.com>
+Date: Mon, 29 Oct 2018 11:57:06 +0300
+Subject: [PATCH 116/211] media: platform: soc_camera: rcar_isp: Fix unused
+ variable warning
+
+This fixes unused "cam" variable warning.
+
+Signed-off-by: Valentine Barshak <valentine.barshak@cogentembedded.com>
+---
+ drivers/media/platform/soc_camera/rcar_isp.c | 17 ++++++++++-------
+ 1 file changed, 10 insertions(+), 7 deletions(-)
+
+diff --git a/drivers/media/platform/soc_camera/rcar_isp.c b/drivers/media/platform/soc_camera/rcar_isp.c
+index 878df95..1127c7d 100644
+--- a/drivers/media/platform/soc_camera/rcar_isp.c
++++ b/drivers/media/platform/soc_camera/rcar_isp.c
+@@ -728,7 +728,6 @@ static int rcar_isp_hw_ready(struct rcar_isp_priv *priv)
+ /* Moves a buffer from the queue to the HW slot */
+ static int rcar_isp_fill_hw_slot(struct rcar_isp_priv *priv)
+ {
+- struct rcar_isp_cam *cam = priv->ici.icd->host_priv;
+ struct vb2_v4l2_buffer *vbuf;
+ dma_addr_t phys_addr_top;
+ int slot;
+@@ -745,12 +744,16 @@ static int rcar_isp_fill_hw_slot(struct rcar_isp_priv *priv)
+ list_del_init(to_buf_list(vbuf));
+ priv->queue_buf[slot] = vbuf;
+ phys_addr_top = vb2_dma_contig_plane_dma_addr(&vbuf->vb2_buf, 0);
+-#if 1
+- rcar_isp_setup_out_buffer(priv, slot, phys_addr_top);
+-#else
+- rcar_isp_setup_out_buffer(priv, 0, phys_addr_top); // Y
+- rcar_isp_setup_out_buffer(priv, 1, phys_addr_top + cam->out_width * cam->out_height); // UV
+-#endif
++
++ if (1) {
++ rcar_isp_setup_out_buffer(priv, slot, phys_addr_top);
++ } else {
++ struct rcar_isp_cam *cam = priv->ici.icd->host_priv;
++
++ rcar_isp_setup_out_buffer(priv, 0, phys_addr_top); // Y
++ rcar_isp_setup_out_buffer(priv, 1, phys_addr_top +
++ cam->out_width * cam->out_height); // UV
++ }
+ return 1;
+ }
+
+--
+2.7.4
+
diff --git a/bsp/meta-rcar/meta-rcar-gen3-adas/recipes-kernel/linux/linux-renesas/0297-media-platform-soc_camera-rcar_vin-Update-R-Car-V3M-.patch b/bsp/meta-rcar/meta-rcar-gen3-adas/recipes-kernel/linux/linux-renesas/0297-media-platform-soc_camera-rcar_vin-Update-R-Car-V3M-.patch
new file mode 100644
index 00000000..34c018f9
--- /dev/null
+++ b/bsp/meta-rcar/meta-rcar-gen3-adas/recipes-kernel/linux/linux-renesas/0297-media-platform-soc_camera-rcar_vin-Update-R-Car-V3M-.patch
@@ -0,0 +1,57 @@
+From 8091f1f8f716fb33ecfd67f9c2adb54e3a4ca883 Mon Sep 17 00:00:00 2001
+From: Valentine Barshak <valentine.barshak@cogentembedded.com>
+Date: Thu, 18 Oct 2018 15:24:59 +0300
+Subject: [PATCH 117/211] media: platform: soc_camera: rcar_vin: Update R-Car
+ V3M bindings
+
+This updates V3M compatible string to "renesas,vin-r8a77970".
+While at it use more descriptive name for the V3M ifmd array.
+
+Signed-off-by: Valentine Barshak <valentine.barshak@cogentembedded.com>
+---
+ drivers/media/platform/soc_camera/rcar_vin.c | 8 ++++----
+ 1 file changed, 4 insertions(+), 4 deletions(-)
+
+diff --git a/drivers/media/platform/soc_camera/rcar_vin.c b/drivers/media/platform/soc_camera/rcar_vin.c
+index 291d115..ff4e521 100644
+--- a/drivers/media/platform/soc_camera/rcar_vin.c
++++ b/drivers/media/platform/soc_camera/rcar_vin.c
+@@ -439,7 +439,7 @@ static const struct vin_gen3_ifmd vin_m3n_vc_ifmd[] = {
+ },
+ };
+
+-static const struct vin_gen3_ifmd vin_v3_vc_ifmd[] = {
++static const struct vin_gen3_ifmd vin_v3m_vc_ifmd[] = {
+ { 0x0000,
+ {
+ {RCAR_CSI40, RCAR_VIRTUAL_CH0},
+@@ -2770,7 +2770,7 @@ static struct soc_camera_host_ops rcar_vin_host_ops = {
+
+ #ifdef CONFIG_OF
+ static const struct of_device_id rcar_vin_of_table[] = {
+- { .compatible = "renesas,vin-r8a7797", .data = (void *)RCAR_V3M },
++ { .compatible = "renesas,vin-r8a77970", .data = (void *)RCAR_V3M },
+ { .compatible = "renesas,vin-r8a77965", .data = (void *)RCAR_M3N },
+ { .compatible = "renesas,vin-r8a7796", .data = (void *)RCAR_M3 },
+ { .compatible = "renesas,vin-r8a7795", .data = (void *)RCAR_H3 },
+@@ -3188,7 +3188,7 @@ static int rcar_vin_probe(struct platform_device *pdev)
+ ifmd = VNCSI_IFMD_DES1;
+ break;
+ case RCAR_V3M:
+- gen3_ifmd_table = vin_v3_vc_ifmd;
++ gen3_ifmd_table = vin_v3m_vc_ifmd;
+ break;
+ default:
+ BUG();
+@@ -3358,7 +3358,7 @@ static int rcar_vin_resume(struct device *dev)
+ ifmd = VNCSI_IFMD_DES1;
+ break;
+ case RCAR_V3M:
+- gen3_ifmd_table = vin_v3_vc_ifmd;
++ gen3_ifmd_table = vin_v3m_vc_ifmd;
+ break;
+ default:
+ return 0;
+--
+2.7.4
+
diff --git a/bsp/meta-rcar/meta-rcar-gen3-adas/recipes-kernel/linux/linux-renesas/0298-media-platform-soc_camera-rcar_vin-Add-r8a77980-supp.patch b/bsp/meta-rcar/meta-rcar-gen3-adas/recipes-kernel/linux/linux-renesas/0298-media-platform-soc_camera-rcar_vin-Add-r8a77980-supp.patch
new file mode 100644
index 00000000..a188de62
--- /dev/null
+++ b/bsp/meta-rcar/meta-rcar-gen3-adas/recipes-kernel/linux/linux-renesas/0298-media-platform-soc_camera-rcar_vin-Add-r8a77980-supp.patch
@@ -0,0 +1,256 @@
+From 166dc7905bc75f5e6682d47e2c2aa436c01f6cef Mon Sep 17 00:00:00 2001
+From: Valentine Barshak <valentine.barshak@cogentembedded.com>
+Date: Thu, 18 Oct 2018 15:37:29 +0300
+Subject: [PATCH 118/211] media: platform: soc_camera: rcar_vin: Add r8a77980
+ support
+
+This adds R-Car V3H support.
+
+Signed-off-by: Valentine Barshak <valentine.barshak@cogentembedded.com>
+---
+ drivers/media/platform/soc_camera/rcar_vin.c | 111 +++++++++++++++++++++++----
+ 1 file changed, 97 insertions(+), 14 deletions(-)
+
+diff --git a/drivers/media/platform/soc_camera/rcar_vin.c b/drivers/media/platform/soc_camera/rcar_vin.c
+index ff4e521..6ba94c3 100644
+--- a/drivers/media/platform/soc_camera/rcar_vin.c
++++ b/drivers/media/platform/soc_camera/rcar_vin.c
+@@ -164,7 +164,8 @@
+ #define VNCSI_IFMD_REG 0x20 /* Video n CSI2 Interface Mode Register */
+
+ #define VNCSI_IFMD_DES1 (1 << 26) /* CSI20 */
+-#define VNCSI_IFMD_DES0 (1 << 25) /* H3:CSI40/41, M3:CSI40, V3M:CSI40 */
++#define VNCSI_IFMD_DES0 (1 << 25) /* H3:CSI40/41, M3:CSI40,
++ * V3M:CSI40 V3H:CSI40 */
+
+ #define VNCSI_IFMD_CSI_CHSEL(n) (n << 0)
+ #define VNCSI_IFMD_SEL_NUMBER 5
+@@ -199,6 +200,7 @@ static int ifmd4_init = true;
+
+ enum chip_id {
+ RCAR_GEN3,
++ RCAR_V3H,
+ RCAR_V3M,
+ RCAR_M3N,
+ RCAR_M3,
+@@ -482,6 +484,69 @@ static const struct vin_gen3_ifmd vin_v3m_vc_ifmd[] = {
+ },
+ };
+
++static const struct vin_gen3_ifmd vin_v3h_vc_ifmd[] = {
++ { 0x0000,
++ {
++ {RCAR_CSI40, RCAR_VIRTUAL_CH0},
++ {RCAR_CSI_CH_NONE, RCAR_VIN_CH_NONE},
++ {RCAR_CSI_CH_NONE, RCAR_VIN_CH_NONE},
++ {RCAR_CSI40, RCAR_VIRTUAL_CH1},
++ {RCAR_CSI41, RCAR_VIRTUAL_CH0},
++ {RCAR_CSI_CH_NONE, RCAR_VIN_CH_NONE},
++ {RCAR_CSI_CH_NONE, RCAR_VIN_CH_NONE},
++ {RCAR_CSI41, RCAR_VIRTUAL_CH1},
++ }
++ },
++ { 0x0001,
++ {
++ {RCAR_CSI_CH_NONE, RCAR_VIN_CH_NONE},
++ {RCAR_CSI40, RCAR_VIRTUAL_CH1},
++ {RCAR_CSI40, RCAR_VIRTUAL_CH0},
++ {RCAR_CSI_CH_NONE, RCAR_VIN_CH_NONE},
++ {RCAR_CSI_CH_NONE, RCAR_VIN_CH_NONE},
++ {RCAR_CSI41, RCAR_VIRTUAL_CH1},
++ {RCAR_CSI41, RCAR_VIRTUAL_CH0},
++ {RCAR_CSI_CH_NONE, RCAR_VIN_CH_NONE},
++ }
++ },
++ { 0x0002,
++ {
++ {RCAR_CSI40, RCAR_VIRTUAL_CH1},
++ {RCAR_CSI40, RCAR_VIRTUAL_CH0},
++ {RCAR_CSI_CH_NONE, RCAR_VIN_CH_NONE},
++ {RCAR_CSI_CH_NONE, RCAR_VIN_CH_NONE},
++ {RCAR_CSI41, RCAR_VIRTUAL_CH1},
++ {RCAR_CSI41, RCAR_VIRTUAL_CH0},
++ {RCAR_CSI_CH_NONE, RCAR_VIN_CH_NONE},
++ {RCAR_CSI_CH_NONE, RCAR_VIN_CH_NONE},
++ }
++ },
++ { 0x0003,
++ {
++ {RCAR_CSI40, RCAR_VIRTUAL_CH0},
++ {RCAR_CSI40, RCAR_VIRTUAL_CH1},
++ {RCAR_CSI40, RCAR_VIRTUAL_CH2},
++ {RCAR_CSI40, RCAR_VIRTUAL_CH3},
++ {RCAR_CSI41, RCAR_VIRTUAL_CH0},
++ {RCAR_CSI41, RCAR_VIRTUAL_CH1},
++ {RCAR_CSI41, RCAR_VIRTUAL_CH2},
++ {RCAR_CSI41, RCAR_VIRTUAL_CH3},
++ }
++ },
++ { 0x0004,
++ {
++ {RCAR_CSI_CH_NONE, RCAR_VIN_CH_NONE},
++ {RCAR_CSI_CH_NONE, RCAR_VIN_CH_NONE},
++ {RCAR_CSI_CH_NONE, RCAR_VIN_CH_NONE},
++ {RCAR_CSI_CH_NONE, RCAR_VIN_CH_NONE},
++ {RCAR_CSI_CH_NONE, RCAR_VIN_CH_NONE},
++ {RCAR_CSI_CH_NONE, RCAR_VIN_CH_NONE},
++ {RCAR_CSI_CH_NONE, RCAR_VIN_CH_NONE},
++ {RCAR_CSI_CH_NONE, RCAR_VIN_CH_NONE},
++ }
++ },
++};
++
+ enum csi2_fmt {
+ RCAR_CSI_FMT_NONE = -1,
+ RCAR_CSI_RGB888,
+@@ -977,7 +1042,8 @@ static int rcar_vin_videobuf_setup(struct vb2_queue *vq,
+ struct rcar_vin_cam *cam = icd->host_priv;
+
+ if (priv->chip == RCAR_H3 || priv->chip == RCAR_M3 ||
+- priv->chip == RCAR_M3N || priv->chip == RCAR_V3M) {
++ priv->chip == RCAR_M3N || priv->chip == RCAR_V3M ||
++ priv->chip == RCAR_V3H) {
+ if ((priv->ratio_h > 0x10000) || (priv->ratio_v > 0x10000)) {
+ dev_err(icd->parent, "Scaling rate parameter error\n");
+ return -EINVAL;
+@@ -1087,7 +1153,8 @@ static int rcar_vin_setup(struct rcar_vin_priv *priv)
+ switch (icd->current_fmt->host_fmt->fourcc) {
+ case V4L2_PIX_FMT_NV12:
+ if (priv->chip == RCAR_H3 || priv->chip == RCAR_M3 ||
+- priv->chip == RCAR_M3N || priv->chip == RCAR_V3M) {
++ priv->chip == RCAR_M3N || priv->chip == RCAR_V3M ||
++ priv->chip == RCAR_V3H) {
+ iowrite32(ALIGN((cam->out_width * cam->out_height),
+ 0x80), priv->base + VNUVAOF_REG);
+ dmr = VNDMR_DTMD_YCSEP_YCBCR420;
+@@ -1127,15 +1194,16 @@ static int rcar_vin_setup(struct rcar_vin_priv *priv)
+ case V4L2_PIX_FMT_XBGR32:
+ if (priv->chip != RCAR_H3 && priv->chip != RCAR_M3 &&
+ priv->chip != RCAR_M3N && priv->chip != RCAR_V3M &&
+- priv->chip != RCAR_GEN2 && priv->chip != RCAR_H1 &&
+- priv->chip != RCAR_E1)
++ priv->chip != RCAR_V3H && priv->chip != RCAR_GEN2 &&
++ priv->chip != RCAR_H1 && priv->chip != RCAR_E1)
+ goto e_format;
+
+ dmr = VNDMR_EXRGB;
+ break;
+ case V4L2_PIX_FMT_ABGR32:
+ if (priv->chip != RCAR_H3 && priv->chip != RCAR_M3 &&
+- priv->chip != RCAR_M3N && priv->chip != RCAR_V3M)
++ priv->chip != RCAR_M3N && priv->chip != RCAR_V3M &&
++ priv->chip != RCAR_V3H)
+ goto e_format;
+
+ dmr = VNDMR_EXRGB | VNDMR_DTMD_ARGB;
+@@ -1156,7 +1224,8 @@ static int rcar_vin_setup(struct rcar_vin_priv *priv)
+ vnmc |= VNMC_BPS;
+
+ if (priv->chip == RCAR_H3 || priv->chip == RCAR_M3 ||
+- priv->chip == RCAR_M3N || priv->chip == RCAR_V3M) {
++ priv->chip == RCAR_M3N || priv->chip == RCAR_V3M ||
++ priv->chip == RCAR_V3H) {
+ if (priv->pdata_flags & RCAR_VIN_CSI2)
+ vnmc &= ~VNMC_DPINE;
+ else
+@@ -1540,7 +1609,8 @@ static int rcar_vin_add_device(struct soc_camera_device *icd)
+ pm_runtime_get_sync(ici->v4l2_dev.dev);
+
+ if (priv->chip == RCAR_H3 || priv->chip == RCAR_M3 ||
+- priv->chip == RCAR_M3N || priv->chip == RCAR_V3M) {
++ priv->chip == RCAR_M3N || priv->chip == RCAR_V3M ||
++ priv->chip == RCAR_V3H) {
+ struct v4l2_subdev *csi2_sd = find_csi2(priv);
+ struct v4l2_subdev *deser_sd = find_deser(priv);
+ int ret = 0;
+@@ -1803,7 +1873,8 @@ static int rcar_vin_set_rect(struct soc_camera_device *icd)
+ }
+
+ if (priv->chip == RCAR_H3 || priv->chip == RCAR_M3 ||
+- priv->chip == RCAR_M3N || priv->chip == RCAR_V3M) {
++ priv->chip == RCAR_M3N || priv->chip == RCAR_V3M ||
++ priv->chip == RCAR_V3H) {
+ if ((icd->current_fmt->host_fmt->fourcc != V4L2_PIX_FMT_NV12) &&
+ (icd->current_fmt->host_fmt->fourcc != V4L2_PIX_FMT_SBGGR8) &&
+ (icd->current_fmt->host_fmt->fourcc != V4L2_PIX_FMT_SBGGR12) &&
+@@ -1963,7 +2034,8 @@ static int rcar_vin_set_bus_param(struct soc_camera_device *icd)
+ return ret;
+
+ if (priv->chip == RCAR_H3 || priv->chip == RCAR_M3 ||
+- priv->chip == RCAR_M3N || priv->chip == RCAR_V3M) {
++ priv->chip == RCAR_M3N || priv->chip == RCAR_V3M ||
++ priv->chip == RCAR_V3H) {
+ if (cfg.type == V4L2_MBUS_CSI2)
+ vnmc &= ~VNMC_DPINE;
+ else
+@@ -1971,7 +2043,8 @@ static int rcar_vin_set_bus_param(struct soc_camera_device *icd)
+ }
+
+ if (priv->chip == RCAR_H3 || priv->chip == RCAR_M3 ||
+- priv->chip == RCAR_M3N || priv->chip == RCAR_V3M)
++ priv->chip == RCAR_M3N || priv->chip == RCAR_V3M ||
++ priv->chip == RCAR_V3H)
+ val = VNDMR2_FTEV;
+ else
+ val = VNDMR2_FTEV | VNDMR2_VLV(1);
+@@ -2591,7 +2664,8 @@ static int rcar_vin_try_fmt(struct soc_camera_device *icd,
+ return ret;
+
+ if (priv->chip == RCAR_H3 || priv->chip == RCAR_M3 ||
+- priv->chip == RCAR_M3N || priv->chip == RCAR_V3M) {
++ priv->chip == RCAR_M3N || priv->chip == RCAR_V3M ||
++ priv->chip == RCAR_V3H) {
+ /* Adjust max scaling size for Gen3 */
+ if (pix->width > 4096)
+ pix->width = priv->max_width;
+@@ -2770,6 +2844,7 @@ static struct soc_camera_host_ops rcar_vin_host_ops = {
+
+ #ifdef CONFIG_OF
+ static const struct of_device_id rcar_vin_of_table[] = {
++ { .compatible = "renesas,vin-r8a77980", .data = (void *)RCAR_V3H },
+ { .compatible = "renesas,vin-r8a77970", .data = (void *)RCAR_V3M },
+ { .compatible = "renesas,vin-r8a77965", .data = (void *)RCAR_M3N },
+ { .compatible = "renesas,vin-r8a7796", .data = (void *)RCAR_M3 },
+@@ -3095,7 +3170,8 @@ static int rcar_vin_probe(struct platform_device *pdev)
+ }
+
+ if (priv->chip == RCAR_H3 || priv->chip == RCAR_M3 ||
+- priv->chip == RCAR_M3N || priv->chip == RCAR_V3M) {
++ priv->chip == RCAR_M3N || priv->chip == RCAR_V3M ||
++ priv->chip == RCAR_V3H) {
+ priv->max_width = 4096;
+ priv->max_height = 4096;
+ } else {
+@@ -3104,7 +3180,8 @@ static int rcar_vin_probe(struct platform_device *pdev)
+ }
+
+ if ((priv->chip == RCAR_H3 || priv->chip == RCAR_M3 ||
+- priv->chip == RCAR_M3N || priv->chip == RCAR_V3M) &&
++ priv->chip == RCAR_M3N || priv->chip == RCAR_V3M ||
++ priv->chip == RCAR_V3H) &&
+ !of_property_read_string(np, "csi,select", &str)) {
+ u32 ifmd;
+ bool match_flag = false;
+@@ -3190,6 +3267,9 @@ static int rcar_vin_probe(struct platform_device *pdev)
+ case RCAR_V3M:
+ gen3_ifmd_table = vin_v3m_vc_ifmd;
+ break;
++ case RCAR_V3H:
++ gen3_ifmd_table = vin_v3h_vc_ifmd;
++ break;
+ default:
+ BUG();
+ break;
+@@ -3360,6 +3440,9 @@ static int rcar_vin_resume(struct device *dev)
+ case RCAR_V3M:
+ gen3_ifmd_table = vin_v3m_vc_ifmd;
+ break;
++ case RCAR_V3H:
++ gen3_ifmd_table = vin_v3h_vc_ifmd;
++ break;
+ default:
+ return 0;
+ }
+--
+2.7.4
+
diff --git a/bsp/meta-rcar/meta-rcar-gen3-adas/recipes-kernel/linux/linux-renesas/0299-media-platform-soc_camera-rcar_csi2-r8a77970-Update-.patch b/bsp/meta-rcar/meta-rcar-gen3-adas/recipes-kernel/linux/linux-renesas/0299-media-platform-soc_camera-rcar_csi2-r8a77970-Update-.patch
new file mode 100644
index 00000000..c4e8770e
--- /dev/null
+++ b/bsp/meta-rcar/meta-rcar-gen3-adas/recipes-kernel/linux/linux-renesas/0299-media-platform-soc_camera-rcar_csi2-r8a77970-Update-.patch
@@ -0,0 +1,73 @@
+From a5d325f3d587578aae5cae46dbdb2a7570b706fb Mon Sep 17 00:00:00 2001
+From: Valentine Barshak <valentine.barshak@cogentembedded.com>
+Date: Fri, 26 Oct 2018 19:40:35 +0300
+Subject: [PATCH 119/211] media: platform: soc_camera: rcar_csi2: r8a77970:
+ Update SoC id
+
+Use r8a77970 SoC id instead of r8a7797.
+
+Signed-off-by: Valentine Barshak <valentine.barshak@cogentembedded.com>
+---
+ drivers/media/platform/soc_camera/Kconfig | 3 ++-
+ drivers/media/platform/soc_camera/rcar_csi2.c | 10 +++++-----
+ 2 files changed, 7 insertions(+), 6 deletions(-)
+
+diff --git a/drivers/media/platform/soc_camera/Kconfig b/drivers/media/platform/soc_camera/Kconfig
+index 61b0dcf..ae9e0b3 100644
+--- a/drivers/media/platform/soc_camera/Kconfig
++++ b/drivers/media/platform/soc_camera/Kconfig
+@@ -39,7 +39,8 @@ config VIDEO_RCAR_VIN_LEGACY_DEBUG
+ config VIDEO_RCAR_CSI2_LEGACY
+ tristate "R-Car MIPI CSI-2 Interface driver"
+ depends on VIDEO_DEV && SOC_CAMERA && HAVE_CLK
+- depends on ARCH_R8A7795 || ARCH_R8A7796 || ARCH_R8A77965 || COMPILE_TEST
++ depends on ARCH_R8A7795 || ARCH_R8A7796 || ARCH_R8A77965 || \
++ ARCH_R8A77970 || COMPILE_TEST
+ select V4L2_FWNODE
+ ---help---
+ This is a v4l2 driver for the R-Car CSI-2 Interface
+diff --git a/drivers/media/platform/soc_camera/rcar_csi2.c b/drivers/media/platform/soc_camera/rcar_csi2.c
+index 384d7e9..838806d 100644
+--- a/drivers/media/platform/soc_camera/rcar_csi2.c
++++ b/drivers/media/platform/soc_camera/rcar_csi2.c
+@@ -166,8 +166,8 @@
+ #define RCAR_CSI2_INTSTATE_ERRSYNCESC (1 << 1)
+ #define RCAR_CSI2_INTSTATE_ERRCONTROL (1 << 0)
+
+-static const struct soc_device_attribute r8a7797[] = {
+- { .soc_id = "r8a7797" },
++static const struct soc_device_attribute r8a77970[] = {
++ { .soc_id = "r8a77970" },
+ { }
+ };
+
+@@ -409,7 +409,7 @@ static int rcar_csi2_set_phy_freq(struct rcar_csi2 *priv)
+
+ dev_dbg(&priv->pdev->dev, "bps_per_lane (%d)\n", bps_per_lane);
+
+- if (soc_device_match(r8a7797))
++ if (soc_device_match(r8a77970))
+ iowrite32((hs_freq_range_v3m[bps_per_lane] << 16) |
+ RCAR_CSI2_PHTW_DWEN | RCAR_CSI2_PHTW_CWEN | 0x44,
+ priv->base + RCAR_CSI2_PHTW);
+@@ -612,7 +612,7 @@ static struct v4l2_subdev_ops rcar_csi2_subdev_ops = {
+
+ #ifdef CONFIG_OF
+ static const struct of_device_id rcar_csi2_of_table[] = {
+- { .compatible = "renesas,r8a7797-csi2", .data = (void *)RCAR_GEN3 },
++ { .compatible = "renesas,r8a77970-csi2", .data = (void *)RCAR_GEN3 },
+ { .compatible = "renesas,r8a77965-csi2", .data = (void *)RCAR_GEN3 },
+ { .compatible = "renesas,r8a7796-csi2", .data = (void *)RCAR_GEN3 },
+ { .compatible = "renesas,r8a7795-csi2", .data = (void *)RCAR_GEN3 },
+@@ -622,7 +622,7 @@ MODULE_DEVICE_TABLE(of, rcar_csi2_of_table);
+ #endif
+
+ static struct platform_device_id rcar_csi2_id_table[] = {
+- { "r8a7797-csi2", RCAR_GEN3 },
++ { "r8a77970-csi2", RCAR_GEN3 },
+ { "r8a77965-csi2", RCAR_GEN3 },
+ { "r8a7796-csi2", RCAR_GEN3 },
+ { "r8a7795-csi2", RCAR_GEN3 },
+--
+2.7.4
+
diff --git a/bsp/meta-rcar/meta-rcar-gen3-adas/recipes-kernel/linux/linux-renesas/0300-media-platform-soc_camera-rcar_csi2-Add-r8a77980-sup.patch b/bsp/meta-rcar/meta-rcar-gen3-adas/recipes-kernel/linux/linux-renesas/0300-media-platform-soc_camera-rcar_csi2-Add-r8a77980-sup.patch
new file mode 100644
index 00000000..fbb9bedc
--- /dev/null
+++ b/bsp/meta-rcar/meta-rcar-gen3-adas/recipes-kernel/linux/linux-renesas/0300-media-platform-soc_camera-rcar_csi2-Add-r8a77980-sup.patch
@@ -0,0 +1,89 @@
+From 34bd7eb4d9826aa6229f797c57d4011d0beb995e Mon Sep 17 00:00:00 2001
+From: Valentine Barshak <valentine.barshak@cogentembedded.com>
+Date: Fri, 26 Oct 2018 19:52:08 +0300
+Subject: [PATCH 120/211] media: platform: soc_camera: rcar_csi2: Add r8a77980
+ support
+
+This adds R8A77980 support to the R-Car CSI2 driver.
+
+Signed-off-by: Valentine Barshak <valentine.barshak@cogentembedded.com>
+---
+ drivers/media/platform/soc_camera/Kconfig | 2 +-
+ drivers/media/platform/soc_camera/rcar_csi2.c | 13 ++++++++++---
+ 2 files changed, 11 insertions(+), 4 deletions(-)
+
+diff --git a/drivers/media/platform/soc_camera/Kconfig b/drivers/media/platform/soc_camera/Kconfig
+index ae9e0b3..19fd6c4 100644
+--- a/drivers/media/platform/soc_camera/Kconfig
++++ b/drivers/media/platform/soc_camera/Kconfig
+@@ -40,7 +40,7 @@ config VIDEO_RCAR_CSI2_LEGACY
+ tristate "R-Car MIPI CSI-2 Interface driver"
+ depends on VIDEO_DEV && SOC_CAMERA && HAVE_CLK
+ depends on ARCH_R8A7795 || ARCH_R8A7796 || ARCH_R8A77965 || \
+- ARCH_R8A77970 || COMPILE_TEST
++ ARCH_R8A77970 || ARCH_R8A77980 || COMPILE_TEST
+ select V4L2_FWNODE
+ ---help---
+ This is a v4l2 driver for the R-Car CSI-2 Interface
+diff --git a/drivers/media/platform/soc_camera/rcar_csi2.c b/drivers/media/platform/soc_camera/rcar_csi2.c
+index 838806d..737a686 100644
+--- a/drivers/media/platform/soc_camera/rcar_csi2.c
++++ b/drivers/media/platform/soc_camera/rcar_csi2.c
+@@ -166,6 +166,11 @@
+ #define RCAR_CSI2_INTSTATE_ERRSYNCESC (1 << 1)
+ #define RCAR_CSI2_INTSTATE_ERRCONTROL (1 << 0)
+
++static const struct soc_device_attribute r8a77980[] = {
++ { .soc_id = "r8a77980" },
++ { }
++};
++
+ static const struct soc_device_attribute r8a77970[] = {
+ { .soc_id = "r8a77970" },
+ { }
+@@ -413,7 +418,7 @@ static int rcar_csi2_set_phy_freq(struct rcar_csi2 *priv)
+ iowrite32((hs_freq_range_v3m[bps_per_lane] << 16) |
+ RCAR_CSI2_PHTW_DWEN | RCAR_CSI2_PHTW_CWEN | 0x44,
+ priv->base + RCAR_CSI2_PHTW);
+- else if (soc_device_match(r8a7795))
++ else if (soc_device_match(r8a7795) || soc_device_match(r8a77980))
+ iowrite32(hs_freq_range_h3[bps_per_lane] << 16,
+ priv->base + RCAR_CSI2_PHYPLL);
+ else
+@@ -500,7 +505,7 @@ static int rcar_csi2_hwinit(struct rcar_csi2 *priv)
+ return -EINVAL;
+ }
+
+- if (soc_device_match(r8a7795)) {
++ if (soc_device_match(r8a7795) || soc_device_match(r8a77980)) {
+ /* Set PHY Test Interface Write Register in R-Car H3(ES2.0) */
+ iowrite32(0x01cc01e2, priv->base + RCAR_CSI2_PHTW);
+ iowrite32(0x010101e3, priv->base + RCAR_CSI2_PHTW);
+@@ -518,7 +523,7 @@ static int rcar_csi2_hwinit(struct rcar_csi2 *priv)
+ /* Set CSI0CLK Frequency Configuration Preset Register
+ * in R-Car H3(ES2.0)
+ */
+- if (soc_device_match(r8a7795))
++ if (soc_device_match(r8a7795) || soc_device_match(r8a77980))
+ iowrite32(CSI0CLKFREQRANGE(32), priv->base + RCAR_CSI2_CSI0CLKFCPR);
+
+ /* Enable lanes */
+@@ -612,6 +617,7 @@ static struct v4l2_subdev_ops rcar_csi2_subdev_ops = {
+
+ #ifdef CONFIG_OF
+ static const struct of_device_id rcar_csi2_of_table[] = {
++ { .compatible = "renesas,r8a77980-csi2", .data = (void *)RCAR_GEN3 },
+ { .compatible = "renesas,r8a77970-csi2", .data = (void *)RCAR_GEN3 },
+ { .compatible = "renesas,r8a77965-csi2", .data = (void *)RCAR_GEN3 },
+ { .compatible = "renesas,r8a7796-csi2", .data = (void *)RCAR_GEN3 },
+@@ -622,6 +628,7 @@ MODULE_DEVICE_TABLE(of, rcar_csi2_of_table);
+ #endif
+
+ static struct platform_device_id rcar_csi2_id_table[] = {
++ { "r8a77980-csi2", RCAR_GEN3 },
+ { "r8a77970-csi2", RCAR_GEN3 },
+ { "r8a77965-csi2", RCAR_GEN3 },
+ { "r8a7796-csi2", RCAR_GEN3 },
+--
+2.7.4
+
diff --git a/bsp/meta-rcar/meta-rcar-gen3-adas/recipes-kernel/linux/linux-renesas/0301-arm64-dts-renesas-r8a77970-Convert-VIN-nodes-to-soc_.patch b/bsp/meta-rcar/meta-rcar-gen3-adas/recipes-kernel/linux/linux-renesas/0301-arm64-dts-renesas-r8a77970-Convert-VIN-nodes-to-soc_.patch
new file mode 100644
index 00000000..40f38c48
--- /dev/null
+++ b/bsp/meta-rcar/meta-rcar-gen3-adas/recipes-kernel/linux/linux-renesas/0301-arm64-dts-renesas-r8a77970-Convert-VIN-nodes-to-soc_.patch
@@ -0,0 +1,116 @@
+From 8132f65ee9e530c4af291eef6b2f54196953ce51 Mon Sep 17 00:00:00 2001
+From: Valentine Barshak <valentine.barshak@cogentembedded.com>
+Date: Tue, 25 Jun 2019 23:43:06 +0300
+Subject: [PATCH 121/211] arm64: dts: renesas: r8a77970: Convert VIN nodes to
+ soc_camera model
+
+This converts VIN nodes to soc_camera model.
+
+Signed-off-by: Valentine Barshak <valentine.barshak@cogentembedded.com>
+---
+ arch/arm64/boot/dts/renesas/r8a77970.dtsi | 68 -------------------------------
+ 1 file changed, 68 deletions(-)
+
+diff --git a/arch/arm64/boot/dts/renesas/r8a77970.dtsi b/arch/arm64/boot/dts/renesas/r8a77970.dtsi
+index 563428d..2a35025 100644
+--- a/arch/arm64/boot/dts/renesas/r8a77970.dtsi
++++ b/arch/arm64/boot/dts/renesas/r8a77970.dtsi
+@@ -826,23 +826,6 @@
+ resets = <&cpg 811>;
+ renesas,id = <0>;
+ status = "disabled";
+-
+- ports {
+- #address-cells = <1>;
+- #size-cells = <0>;
+-
+- port@1 {
+- #address-cells = <1>;
+- #size-cells = <0>;
+-
+- reg = <1>;
+-
+- vin0csi40: endpoint@2 {
+- reg = <2>;
+- remote-endpoint = <&csi40vin0>;
+- };
+- };
+- };
+ };
+
+ vin1: video@e6ef1000 {
+@@ -854,23 +837,6 @@
+ resets = <&cpg 810>;
+ renesas,id = <1>;
+ status = "disabled";
+-
+- ports {
+- #address-cells = <1>;
+- #size-cells = <0>;
+-
+- port@1 {
+- #address-cells = <1>;
+- #size-cells = <0>;
+-
+- reg = <1>;
+-
+- vin1csi40: endpoint@2 {
+- reg = <2>;
+- remote-endpoint = <&csi40vin1>;
+- };
+- };
+- };
+ };
+
+ vin2: video@e6ef2000 {
+@@ -882,23 +848,6 @@
+ resets = <&cpg 809>;
+ renesas,id = <2>;
+ status = "disabled";
+-
+- ports {
+- #address-cells = <1>;
+- #size-cells = <0>;
+-
+- port@1 {
+- #address-cells = <1>;
+- #size-cells = <0>;
+-
+- reg = <1>;
+-
+- vin2csi40: endpoint@2 {
+- reg = <2>;
+- remote-endpoint = <&csi40vin2>;
+- };
+- };
+- };
+ };
+
+ vin3: video@e6ef3000 {
+@@ -910,23 +859,6 @@
+ resets = <&cpg 808>;
+ renesas,id = <3>;
+ status = "disabled";
+-
+- ports {
+- #address-cells = <1>;
+- #size-cells = <0>;
+-
+- port@1 {
+- #address-cells = <1>;
+- #size-cells = <0>;
+-
+- reg = <1>;
+-
+- vin3csi40: endpoint@2 {
+- reg = <2>;
+- remote-endpoint = <&csi40vin3>;
+- };
+- };
+- };
+ };
+
+ dmac1: dma-controller@e7300000 {
+--
+2.7.4
+
diff --git a/bsp/meta-rcar/meta-rcar-gen3-adas/recipes-kernel/linux/linux-renesas/0302-arm64-dts-renesas-r8a77980-Convert-VIN-nodes-to-soc_.patch b/bsp/meta-rcar/meta-rcar-gen3-adas/recipes-kernel/linux/linux-renesas/0302-arm64-dts-renesas-r8a77980-Convert-VIN-nodes-to-soc_.patch
new file mode 100644
index 00000000..42b7a6ae
--- /dev/null
+++ b/bsp/meta-rcar/meta-rcar-gen3-adas/recipes-kernel/linux/linux-renesas/0302-arm64-dts-renesas-r8a77980-Convert-VIN-nodes-to-soc_.patch
@@ -0,0 +1,212 @@
+From 614a4a2f74e8a6d14a43853c2ce134358b5e86f3 Mon Sep 17 00:00:00 2001
+From: Valentine Barshak <valentine.barshak@cogentembedded.com>
+Date: Tue, 25 Jun 2019 23:45:40 +0300
+Subject: [PATCH 122/211] arm64: dts: renesas: r8a77980: Convert VIN nodes to
+ soc_camera model
+
+This converts VIN nodes to soc_camera model.
+
+Signed-off-by: Valentine Barshak <valentine.barshak@cogentembedded.com>
+---
+ arch/arm64/boot/dts/renesas/r8a77980.dtsi | 136 ------------------------------
+ 1 file changed, 136 deletions(-)
+
+diff --git a/arch/arm64/boot/dts/renesas/r8a77980.dtsi b/arch/arm64/boot/dts/renesas/r8a77980.dtsi
+index 1b56b1f..63c49a8 100644
+--- a/arch/arm64/boot/dts/renesas/r8a77980.dtsi
++++ b/arch/arm64/boot/dts/renesas/r8a77980.dtsi
+@@ -867,23 +867,6 @@
+ resets = <&cpg 811>;
+ renesas,id = <0>;
+ status = "disabled";
+-
+- ports {
+- #address-cells = <1>;
+- #size-cells = <0>;
+-
+- port@1 {
+- #address-cells = <1>;
+- #size-cells = <0>;
+-
+- reg = <1>;
+-
+- vin0csi40: endpoint@2 {
+- reg = <2>;
+- remote-endpoint= <&csi40vin0>;
+- };
+- };
+- };
+ };
+
+ vin1: video@e6ef1000 {
+@@ -895,23 +878,6 @@
+ status = "disabled";
+ renesas,id = <1>;
+ resets = <&cpg 810>;
+-
+- ports {
+- #address-cells = <1>;
+- #size-cells = <0>;
+-
+- port@1 {
+- #address-cells = <1>;
+- #size-cells = <0>;
+-
+- reg = <1>;
+-
+- vin1csi40: endpoint@2 {
+- reg = <2>;
+- remote-endpoint= <&csi40vin1>;
+- };
+- };
+- };
+ };
+
+ vin2: video@e6ef2000 {
+@@ -923,23 +889,6 @@
+ resets = <&cpg 809>;
+ renesas,id = <2>;
+ status = "disabled";
+-
+- ports {
+- #address-cells = <1>;
+- #size-cells = <0>;
+-
+- port@1 {
+- #address-cells = <1>;
+- #size-cells = <0>;
+-
+- reg = <1>;
+-
+- vin2csi40: endpoint@2 {
+- reg = <2>;
+- remote-endpoint= <&csi40vin2>;
+- };
+- };
+- };
+ };
+
+ vin3: video@e6ef3000 {
+@@ -951,23 +900,6 @@
+ resets = <&cpg 808>;
+ renesas,id = <3>;
+ status = "disabled";
+-
+- ports {
+- #address-cells = <1>;
+- #size-cells = <0>;
+-
+- port@1 {
+- #address-cells = <1>;
+- #size-cells = <0>;
+-
+- reg = <1>;
+-
+- vin3csi40: endpoint@2 {
+- reg = <2>;
+- remote-endpoint= <&csi40vin3>;
+- };
+- };
+- };
+ };
+
+ vin4: video@e6ef4000 {
+@@ -979,23 +911,6 @@
+ resets = <&cpg 807>;
+ renesas,id = <4>;
+ status = "disabled";
+-
+- ports {
+- #address-cells = <1>;
+- #size-cells = <0>;
+-
+- port@1 {
+- #address-cells = <1>;
+- #size-cells = <0>;
+-
+- reg = <1>;
+-
+- vin4csi41: endpoint@2 {
+- reg = <2>;
+- remote-endpoint= <&csi41vin4>;
+- };
+- };
+- };
+ };
+
+ vin5: video@e6ef5000 {
+@@ -1007,23 +922,6 @@
+ resets = <&cpg 806>;
+ renesas,id = <5>;
+ status = "disabled";
+-
+- ports {
+- #address-cells = <1>;
+- #size-cells = <0>;
+-
+- port@1 {
+- #address-cells = <1>;
+- #size-cells = <0>;
+-
+- reg = <1>;
+-
+- vin5csi41: endpoint@2 {
+- reg = <2>;
+- remote-endpoint= <&csi41vin5>;
+- };
+- };
+- };
+ };
+
+ vin6: video@e6ef6000 {
+@@ -1035,23 +933,6 @@
+ resets = <&cpg 805>;
+ renesas,id = <6>;
+ status = "disabled";
+-
+- ports {
+- #address-cells = <1>;
+- #size-cells = <0>;
+-
+- port@1 {
+- #address-cells = <1>;
+- #size-cells = <0>;
+-
+- reg = <1>;
+-
+- vin6csi41: endpoint@2 {
+- reg = <2>;
+- remote-endpoint= <&csi41vin6>;
+- };
+- };
+- };
+ };
+
+ vin7: video@e6ef7000 {
+@@ -1063,23 +944,6 @@
+ resets = <&cpg 804>;
+ renesas,id = <7>;
+ status = "disabled";
+-
+- ports {
+- #address-cells = <1>;
+- #size-cells = <0>;
+-
+- port@1 {
+- #address-cells = <1>;
+- #size-cells = <0>;
+-
+- reg = <1>;
+-
+- vin7csi41: endpoint@2 {
+- reg = <2>;
+- remote-endpoint= <&csi41vin7>;
+- };
+- };
+- };
+ };
+
+ vin8: video@e6ef8000 {
+--
+2.7.4
+
diff --git a/bsp/meta-rcar/meta-rcar-gen3-adas/recipes-kernel/linux/linux-renesas/0303-arm64-dts-renesas-r8a77970-Convert-SCI2-nodes-to-soc.patch b/bsp/meta-rcar/meta-rcar-gen3-adas/recipes-kernel/linux/linux-renesas/0303-arm64-dts-renesas-r8a77970-Convert-SCI2-nodes-to-soc.patch
new file mode 100644
index 00000000..eb9c3566
--- /dev/null
+++ b/bsp/meta-rcar/meta-rcar-gen3-adas/recipes-kernel/linux/linux-renesas/0303-arm64-dts-renesas-r8a77970-Convert-SCI2-nodes-to-soc.patch
@@ -0,0 +1,56 @@
+From 85de1cf6d945c4ad380bbd65e6f5fab58a272885 Mon Sep 17 00:00:00 2001
+From: Valentine Barshak <valentine.barshak@cogentembedded.com>
+Date: Fri, 26 Oct 2018 21:51:16 +0300
+Subject: [PATCH 123/211] arm64: dts: renesas: r8a77970: Convert SCI2 nodes to
+ soc_camera model
+
+This converts CSI2 nodes to soc_camera model.
+
+Signed-off-by: Valentine Barshak <valentine.barshak@cogentembedded.com>
+---
+ arch/arm64/boot/dts/renesas/r8a77970.dtsi | 29 -----------------------------
+ 1 file changed, 29 deletions(-)
+
+diff --git a/arch/arm64/boot/dts/renesas/r8a77970.dtsi b/arch/arm64/boot/dts/renesas/r8a77970.dtsi
+index 2a35025..883d811 100644
+--- a/arch/arm64/boot/dts/renesas/r8a77970.dtsi
++++ b/arch/arm64/boot/dts/renesas/r8a77970.dtsi
+@@ -1013,35 +1013,6 @@
+ power-domains = <&sysc R8A77970_PD_ALWAYS_ON>;
+ resets = <&cpg 716>;
+ status = "disabled";
+-
+- ports {
+- #address-cells = <1>;
+- #size-cells = <0>;
+-
+- port@1 {
+- #address-cells = <1>;
+- #size-cells = <0>;
+-
+- reg = <1>;
+-
+- csi40vin0: endpoint@0 {
+- reg = <0>;
+- remote-endpoint = <&vin0csi40>;
+- };
+- csi40vin1: endpoint@1 {
+- reg = <1>;
+- remote-endpoint = <&vin1csi40>;
+- };
+- csi40vin2: endpoint@2 {
+- reg = <2>;
+- remote-endpoint = <&vin2csi40>;
+- };
+- csi40vin3: endpoint@3 {
+- reg = <3>;
+- remote-endpoint = <&vin3csi40>;
+- };
+- };
+- };
+ };
+
+ du: display@feb00000 {
+--
+2.7.4
+
diff --git a/bsp/meta-rcar/meta-rcar-gen3-adas/recipes-kernel/linux/linux-renesas/0304-arm64-dts-renesas-r8a77980-Convert-CSI2-nodes-to-soc.patch b/bsp/meta-rcar/meta-rcar-gen3-adas/recipes-kernel/linux/linux-renesas/0304-arm64-dts-renesas-r8a77980-Convert-CSI2-nodes-to-soc.patch
new file mode 100644
index 00000000..190cce23
--- /dev/null
+++ b/bsp/meta-rcar/meta-rcar-gen3-adas/recipes-kernel/linux/linux-renesas/0304-arm64-dts-renesas-r8a77980-Convert-CSI2-nodes-to-soc.patch
@@ -0,0 +1,92 @@
+From 447ecfa0c2add1ff477ccf22bc27c8248738adaf Mon Sep 17 00:00:00 2001
+From: Valentine Barshak <valentine.barshak@cogentembedded.com>
+Date: Fri, 26 Oct 2018 21:52:31 +0300
+Subject: [PATCH 124/211] arm64: dts: renesas: r8a77980: Convert CSI2 nodes to
+ soc_camera model
+
+This converts CSI2 nodes to soc_camera model.
+
+Signed-off-by: Valentine Barshak <valentine.barshak@cogentembedded.com>
+---
+ arch/arm64/boot/dts/renesas/r8a77980.dtsi | 58 -------------------------------
+ 1 file changed, 58 deletions(-)
+
+diff --git a/arch/arm64/boot/dts/renesas/r8a77980.dtsi b/arch/arm64/boot/dts/renesas/r8a77980.dtsi
+index 63c49a8..5ddff7e 100644
+--- a/arch/arm64/boot/dts/renesas/r8a77980.dtsi
++++ b/arch/arm64/boot/dts/renesas/r8a77980.dtsi
+@@ -1280,35 +1280,6 @@
+ power-domains = <&sysc R8A77980_PD_ALWAYS_ON>;
+ resets = <&cpg 716>;
+ status = "disabled";
+-
+- ports {
+- #address-cells = <1>;
+- #size-cells = <0>;
+-
+- port@1 {
+- #address-cells = <1>;
+- #size-cells = <0>;
+-
+- reg = <1>;
+-
+- csi40vin0: endpoint@0 {
+- reg = <0>;
+- remote-endpoint = <&vin0csi40>;
+- };
+- csi40vin1: endpoint@1 {
+- reg = <1>;
+- remote-endpoint = <&vin1csi40>;
+- };
+- csi40vin2: endpoint@2 {
+- reg = <2>;
+- remote-endpoint = <&vin2csi40>;
+- };
+- csi40vin3: endpoint@3 {
+- reg = <3>;
+- remote-endpoint = <&vin3csi40>;
+- };
+- };
+- };
+ };
+
+ csi41: csi2@feab0000 {
+@@ -1319,35 +1290,6 @@
+ power-domains = <&sysc R8A77980_PD_ALWAYS_ON>;
+ resets = <&cpg 715>;
+ status = "disabled";
+-
+- ports {
+- #address-cells = <1>;
+- #size-cells = <0>;
+-
+- port@1 {
+- #address-cells = <1>;
+- #size-cells = <0>;
+-
+- reg = <1>;
+-
+- csi41vin4: endpoint@0 {
+- reg = <0>;
+- remote-endpoint = <&vin4csi41>;
+- };
+- csi41vin5: endpoint@1 {
+- reg = <1>;
+- remote-endpoint = <&vin5csi41>;
+- };
+- csi41vin6: endpoint@2 {
+- reg = <2>;
+- remote-endpoint = <&vin6csi41>;
+- };
+- csi41vin7: endpoint@3 {
+- reg = <3>;
+- remote-endpoint = <&vin7csi41>;
+- };
+- };
+- };
+ };
+
+ du: display@feb00000 {
+--
+2.7.4
+
diff --git a/bsp/meta-rcar/meta-rcar-gen3-adas/recipes-kernel/linux/linux-renesas/0305-arm64-dts-renesas-r8a77970-Add-IMR-nodes.patch b/bsp/meta-rcar/meta-rcar-gen3-adas/recipes-kernel/linux/linux-renesas/0305-arm64-dts-renesas-r8a77970-Add-IMR-nodes.patch
new file mode 100644
index 00000000..6ec213b6
--- /dev/null
+++ b/bsp/meta-rcar/meta-rcar-gen3-adas/recipes-kernel/linux/linux-renesas/0305-arm64-dts-renesas-r8a77970-Add-IMR-nodes.patch
@@ -0,0 +1,66 @@
+From bb5909a7796b78f28c00a721dc10d694e266c410 Mon Sep 17 00:00:00 2001
+From: Valentine Barshak <valentine.barshak@cogentembedded.com>
+Date: Fri, 26 Oct 2018 22:14:26 +0300
+Subject: [PATCH 125/211] arm64: dts: renesas: r8a77970: Add IMR nodes
+
+This adds IMR device nodes.
+
+Signed-off-by: Valentine Barshak <valentine.barshak@cogentembedded.com>
+---
+ arch/arm64/boot/dts/renesas/r8a77970.dtsi | 40 +++++++++++++++++++++++++++++++
+ 1 file changed, 40 insertions(+)
+
+diff --git a/arch/arm64/boot/dts/renesas/r8a77970.dtsi b/arch/arm64/boot/dts/renesas/r8a77970.dtsi
+index 883d811..782c49c 100644
+--- a/arch/arm64/boot/dts/renesas/r8a77970.dtsi
++++ b/arch/arm64/boot/dts/renesas/r8a77970.dtsi
+@@ -861,6 +861,46 @@
+ status = "disabled";
+ };
+
++ imr-lx4@fe860000 {
++ compatible = "renesas,r8a77970-imr-lx4",
++ "renesas,imr-lx4";
++ reg = <0 0xfe860000 0 0x2000>;
++ interrupts = <GIC_SPI 192 IRQ_TYPE_LEVEL_HIGH>;
++ clocks = <&cpg CPG_MOD 823>;
++ power-domains = <&sysc R8A77970_PD_ALWAYS_ON>;
++ resets = <&cpg 823>;
++ };
++
++ imr-lx4@fe870000 {
++ compatible = "renesas,r8a77970-imr-lx4",
++ "renesas,imr-lx4";
++ reg = <0 0xfe870000 0 0x2000>;
++ interrupts = <GIC_SPI 193 IRQ_TYPE_LEVEL_HIGH>;
++ clocks = <&cpg CPG_MOD 822>;
++ power-domains = <&sysc R8A77970_PD_ALWAYS_ON>;
++ resets = <&cpg 822>;
++ };
++
++ imr-lx4@fe880000 {
++ compatible = "renesas,r8a77970-imr-lx4",
++ "renesas,imr-lx4";
++ reg = <0 0xfe880000 0 0x2000>;
++ interrupts = <GIC_SPI 194 IRQ_TYPE_LEVEL_HIGH>;
++ clocks = <&cpg CPG_MOD 821>;
++ power-domains = <&sysc R8A77970_PD_ALWAYS_ON>;
++ resets = <&cpg 821>;
++ };
++
++ imr-lx4@fe890000 {
++ compatible = "renesas,r8a77970-imr-lx4",
++ "renesas,imr-lx4";
++ reg = <0 0xfe890000 0 0x2000>;
++ interrupts = <GIC_SPI 195 IRQ_TYPE_LEVEL_HIGH>;
++ clocks = <&cpg CPG_MOD 820>;
++ power-domains = <&sysc R8A77970_PD_ALWAYS_ON>;
++ resets = <&cpg 820>;
++ };
++
+ dmac1: dma-controller@e7300000 {
+ compatible = "renesas,dmac-r8a77970",
+ "renesas,rcar-dmac";
+--
+2.7.4
+
diff --git a/bsp/meta-rcar/meta-rcar-gen3-adas/recipes-kernel/linux/linux-renesas/0306-arm64-dts-renesas-r8a77980-Add-IMR-nodes.patch b/bsp/meta-rcar/meta-rcar-gen3-adas/recipes-kernel/linux/linux-renesas/0306-arm64-dts-renesas-r8a77980-Add-IMR-nodes.patch
new file mode 100644
index 00000000..bc454635
--- /dev/null
+++ b/bsp/meta-rcar/meta-rcar-gen3-adas/recipes-kernel/linux/linux-renesas/0306-arm64-dts-renesas-r8a77980-Add-IMR-nodes.patch
@@ -0,0 +1,84 @@
+From 6f5248fad39c19c87ed1e88df3e59e2e7667926c Mon Sep 17 00:00:00 2001
+From: Valentine Barshak <valentine.barshak@cogentembedded.com>
+Date: Fri, 26 Oct 2018 22:15:26 +0300
+Subject: [PATCH 126/211] arm64: dts: renesas: r8a77980: Add IMR nodes
+
+This adds IMR device nodes.
+
+Signed-off-by: Valentine Barshak <valentine.barshak@cogentembedded.com>
+---
+ arch/arm64/boot/dts/renesas/r8a77980.dtsi | 58 +++++++++++++++++++++++++++++++
+ 1 file changed, 58 insertions(+)
+
+diff --git a/arch/arm64/boot/dts/renesas/r8a77980.dtsi b/arch/arm64/boot/dts/renesas/r8a77980.dtsi
+index 5ddff7e..911a432 100644
+--- a/arch/arm64/boot/dts/renesas/r8a77980.dtsi
++++ b/arch/arm64/boot/dts/renesas/r8a77980.dtsi
+@@ -1034,6 +1034,64 @@
+ status = "disabled";
+ };
+
++ imr-lx4@fe860000 {
++ compatible = "renesas,r8a77980-imr-lx4",
++ "renesas,imr-lx4";
++ reg = <0 0xfe860000 0 0x2000>;
++ interrupts = <GIC_SPI 192 IRQ_TYPE_LEVEL_HIGH>;
++ clocks = <&cpg CPG_MOD 823>;
++ power-domains = <&sysc R8A77980_PD_ALWAYS_ON>;
++ resets = <&cpg 823>;
++ };
++
++ imr-lx4@fe870000 {
++ compatible = "renesas,r8a77980-imr-lx4",
++ "renesas,imr-lx4";
++ reg = <0 0xfe870000 0 0x2000>;
++ interrupts = <GIC_SPI 193 IRQ_TYPE_LEVEL_HIGH>;
++ clocks = <&cpg CPG_MOD 822>;
++ power-domains = <&sysc R8A77980_PD_ALWAYS_ON>;
++ resets = <&cpg 822>;
++ };
++
++ imr-lx4@fe880000 {
++ compatible = "renesas,r8a77980-imr-lx4",
++ "renesas,imr-lx4";
++ reg = <0 0xfe880000 0 0x2000>;
++ interrupts = <GIC_SPI 194 IRQ_TYPE_LEVEL_HIGH>;
++ clocks = <&cpg CPG_MOD 821>;
++ power-domains = <&sysc R8A77980_PD_ALWAYS_ON>;
++ resets = <&cpg 821>;
++ };
++
++ imr-lx4@fe890000 {
++ compatible = "renesas,r8a77980-imr-lx4",
++ "renesas,imr-lx4";
++ reg = <0 0xfe890000 0 0x2000>;
++ interrupts = <GIC_SPI 195 IRQ_TYPE_LEVEL_HIGH>;
++ clocks = <&cpg CPG_MOD 820>;
++ power-domains = <&sysc R8A77980_PD_ALWAYS_ON>;
++ resets = <&cpg 820>;
++ };
++
++ imr4@fe8a0000 {
++ compatible = "renesas,r8a77980-imr-lx4",
++ "renesas,imr-lx4";
++ reg = <0 0xfe8a0000 0 0x10000>;
++ interrupts = <GIC_SPI 254 IRQ_TYPE_LEVEL_HIGH>;
++ clocks = <&cpg CPG_MOD 707>;
++ power-domains = <&sysc R8A77980_PD_ALWAYS_ON>;
++ };
++
++ imr5@fe8b0000 {
++ compatible = "renesas,r8a77980-imr-lx4",
++ "renesas,imr-lx4";
++ reg = <0 0xfe8b0000 0 0x10000>;
++ interrupts = <GIC_SPI 255 IRQ_TYPE_LEVEL_HIGH>;
++ clocks = <&cpg CPG_MOD 706>;
++ power-domains = <&sysc R8A77980_PD_ALWAYS_ON>;
++ };
++
+ dmac1: dma-controller@e7300000 {
+ compatible = "renesas,dmac-r8a77980",
+ "renesas,rcar-dmac";
+--
+2.7.4
+
diff --git a/bsp/meta-rcar/meta-rcar-gen3-adas/recipes-kernel/linux/linux-renesas/0307-arm64-dts-renesas-r8a77970-Add-ISP-node.patch b/bsp/meta-rcar/meta-rcar-gen3-adas/recipes-kernel/linux/linux-renesas/0307-arm64-dts-renesas-r8a77970-Add-ISP-node.patch
new file mode 100644
index 00000000..be3e7ac4
--- /dev/null
+++ b/bsp/meta-rcar/meta-rcar-gen3-adas/recipes-kernel/linux/linux-renesas/0307-arm64-dts-renesas-r8a77970-Add-ISP-node.patch
@@ -0,0 +1,36 @@
+From 6d44f2c02108f34b81acb2e081d274160129fcd0 Mon Sep 17 00:00:00 2001
+From: Valentine Barshak <valentine.barshak@cogentembedded.com>
+Date: Mon, 29 Oct 2018 13:59:27 +0300
+Subject: [PATCH 127/211] arm64: dts: renesas: r8a77970: Add ISP node
+
+This adds ISP device node.
+
+Signed-off-by: Valentine Barshak <valentine.barshak@cogentembedded.com>
+---
+ arch/arm64/boot/dts/renesas/r8a77970.dtsi | 10 ++++++++++
+ 1 file changed, 10 insertions(+)
+
+diff --git a/arch/arm64/boot/dts/renesas/r8a77970.dtsi b/arch/arm64/boot/dts/renesas/r8a77970.dtsi
+index 782c49c..2585ba5 100644
+--- a/arch/arm64/boot/dts/renesas/r8a77970.dtsi
++++ b/arch/arm64/boot/dts/renesas/r8a77970.dtsi
+@@ -901,6 +901,16 @@
+ resets = <&cpg 820>;
+ };
+
++ isp@fec00000 {
++ compatible = "renesas,isp-r8a77970";
++ reg = <0 0xfec00000 0 0x20000>,
++ <0 0xfed00000 0 0x10000>;
++ interrupts = <GIC_SPI 26 IRQ_TYPE_LEVEL_HIGH>,
++ <GIC_SPI 25 IRQ_TYPE_LEVEL_HIGH>;
++ clocks = <&cpg CPG_MOD 817>;
++ power-domains = <&sysc R8A77970_PD_ALWAYS_ON>;
++ };
++
+ dmac1: dma-controller@e7300000 {
+ compatible = "renesas,dmac-r8a77970",
+ "renesas,rcar-dmac";
+--
+2.7.4
+
diff --git a/bsp/meta-rcar/meta-rcar-gen3-adas/recipes-kernel/linux/linux-renesas/0308-arm64-dts-renesas-r8a77980-Add-ISP-nodes.patch b/bsp/meta-rcar/meta-rcar-gen3-adas/recipes-kernel/linux/linux-renesas/0308-arm64-dts-renesas-r8a77980-Add-ISP-nodes.patch
new file mode 100644
index 00000000..80bdf6ca
--- /dev/null
+++ b/bsp/meta-rcar/meta-rcar-gen3-adas/recipes-kernel/linux/linux-renesas/0308-arm64-dts-renesas-r8a77980-Add-ISP-nodes.patch
@@ -0,0 +1,46 @@
+From f35ea5b06fd411aaf351c0bc52894637efe6f0ca Mon Sep 17 00:00:00 2001
+From: Valentine Barshak <valentine.barshak@cogentembedded.com>
+Date: Mon, 29 Oct 2018 14:00:09 +0300
+Subject: [PATCH 128/211] arm64: dts: renesas: r8a77980: Add ISP nodes
+
+This adds ISP device nodes.
+
+Signed-off-by: Valentine Barshak <valentine.barshak@cogentembedded.com>
+---
+ arch/arm64/boot/dts/renesas/r8a77980.dtsi | 20 ++++++++++++++++++++
+ 1 file changed, 20 insertions(+)
+
+diff --git a/arch/arm64/boot/dts/renesas/r8a77980.dtsi b/arch/arm64/boot/dts/renesas/r8a77980.dtsi
+index 911a432..8fba9c7 100644
+--- a/arch/arm64/boot/dts/renesas/r8a77980.dtsi
++++ b/arch/arm64/boot/dts/renesas/r8a77980.dtsi
+@@ -1092,6 +1092,26 @@
+ power-domains = <&sysc R8A77980_PD_ALWAYS_ON>;
+ };
+
++ isp@fec00000 {
++ compatible = "renesas,isp-r8a77980";
++ reg = <0 0xfec00000 0 0x20000>,
++ <0 0xfed00000 0 0x10000>;
++ interrupts = <GIC_SPI 26 IRQ_TYPE_LEVEL_HIGH>,
++ <GIC_SPI 25 IRQ_TYPE_LEVEL_HIGH>;
++ clocks = <&cpg CPG_MOD 817>;
++ power-domains = <&sysc R8A77980_PD_ALWAYS_ON>;
++ };
++
++ isp@fee00000 {
++ compatible = "renesas,isp-r8a77980";
++ reg = <0 0xfee00000 0 0x20000>,
++ <0 0xfed20000 0 0x10000>;
++ interrupts = <GIC_SPI 109 IRQ_TYPE_LEVEL_HIGH>,
++ <GIC_SPI 27 IRQ_TYPE_LEVEL_HIGH>;
++ clocks = <&cpg CPG_MOD 814>;
++ power-domains = <&sysc R8A77980_PD_ALWAYS_ON>;
++ };
++
+ dmac1: dma-controller@e7300000 {
+ compatible = "renesas,dmac-r8a77980",
+ "renesas,rcar-dmac";
+--
+2.7.4
+
diff --git a/bsp/meta-rcar/meta-rcar-gen3-adas/recipes-kernel/linux/linux-renesas/0309-arm64-dts-renesas-eagle-Add-video-input-support.patch b/bsp/meta-rcar/meta-rcar-gen3-adas/recipes-kernel/linux/linux-renesas/0309-arm64-dts-renesas-eagle-Add-video-input-support.patch
new file mode 100644
index 00000000..e8732bf7
--- /dev/null
+++ b/bsp/meta-rcar/meta-rcar-gen3-adas/recipes-kernel/linux/linux-renesas/0309-arm64-dts-renesas-eagle-Add-video-input-support.patch
@@ -0,0 +1,326 @@
+From 8198924fb7bd1d8b26f9e148bafeecc51a249e5e Mon Sep 17 00:00:00 2001
+From: Valentine Barshak <valentine.barshak@cogentembedded.com>
+Date: Wed, 26 Jun 2019 00:11:17 +0300
+Subject: [PATCH 129/211] arm64: dts: renesas: eagle: Add video input support
+
+This adds support of MAX9286 GMSL chip connected to the CSI40.
+Up to 4 video stream channels are routed to VIN[0-3] devices.
+
+Signed-off-by: Valentine Barshak <valentine.barshak@cogentembedded.com>
+---
+ arch/arm64/boot/dts/renesas/r8a77970-eagle.dts | 274 +++++++++++++++++++++++++
+ 1 file changed, 274 insertions(+)
+
+diff --git a/arch/arm64/boot/dts/renesas/r8a77970-eagle.dts b/arch/arm64/boot/dts/renesas/r8a77970-eagle.dts
+index 800643b..a70337b 100644
+--- a/arch/arm64/boot/dts/renesas/r8a77970-eagle.dts
++++ b/arch/arm64/boot/dts/renesas/r8a77970-eagle.dts
+@@ -8,6 +8,7 @@
+
+ /dts-v1/;
+ #include "r8a77970.dtsi"
++#include <dt-bindings/gpio/gpio.h>
+
+ / {
+ model = "Renesas Eagle board based on r8a77970";
+@@ -108,6 +109,40 @@
+ };
+ };
+
++&csi40 {
++ status = "okay";
++
++ virtual,channel {
++ csi2_vc0 {
++ data,type = "ycbcr422";
++ receive,vc = <0>;
++ };
++ csi2_vc1 {
++ data,type = "ycbcr422";
++ receive,vc = <1>;
++ };
++ csi2_vc2 {
++ data,type = "ycbcr422";
++ receive,vc = <2>;
++ };
++ csi2_vc3 {
++ data,type = "ycbcr422";
++ receive,vc = <3>;
++ };
++ };
++
++ port {
++ #address-cells = <1>;
++ #size-cells = <0>;
++
++ csi40_ep: endpoint {
++ clock-lanes = <0>;
++ data-lanes = <1 2 3 4>;
++ csi-rate = <300>;
++ };
++ };
++};
++
+ &extal_clk {
+ clock-frequency = <16666666>;
+ };
+@@ -163,6 +198,128 @@
+ };
+ };
+
++&i2c3 {
++ pinctrl-0 = <&i2c3_pins>;
++ pinctrl-names = "default";
++
++ status = "okay";
++ clock-frequency = <400000>;
++
++ ov106xx@0 {
++ compatible = "ovti,ov106xx";
++ reg = <0x60>;
++
++ port@0 {
++ ov106xx_in0: endpoint {
++ clock-lanes = <0>;
++ data-lanes = <1 2 3 4>;
++ remote-endpoint = <&vin0ep0>;
++ };
++ };
++ port@1 {
++ ov106xx_max9286_des0ep0: endpoint@0 {
++ remote-endpoint = <&max9286_des0ep0>;
++ };
++ };
++ };
++
++ ov106xx@1 {
++ compatible = "ovti,ov106xx";
++ reg = <0x61>;
++
++ port@0 {
++ ov106xx_in1: endpoint {
++ clock-lanes = <0>;
++ data-lanes = <1 2 3 4>;
++ remote-endpoint = <&vin1ep0>;
++ };
++ };
++ port@1 {
++ ov106xx_max9286_des0ep1: endpoint@0 {
++ remote-endpoint = <&max9286_des0ep1>;
++ };
++ };
++ };
++
++ ov106xx@2 {
++ compatible = "ovti,ov106xx";
++ reg = <0x62>;
++
++ port@0 {
++ ov106xx_in2: endpoint {
++ clock-lanes = <0>;
++ data-lanes = <1 2 3 4>;
++ remote-endpoint = <&vin2ep0>;
++ };
++ };
++ port@1 {
++ ov106xx_max9286_des0ep2: endpoint@0 {
++ remote-endpoint = <&max9286_des0ep2>;
++ };
++ };
++ };
++
++ ov106xx@3 {
++ compatible = "ovti,ov106xx";
++ reg = <0x63>;
++
++ port@0 {
++ ov106xx_in3: endpoint {
++ clock-lanes = <0>;
++ data-lanes = <1 2 3 4>;
++ remote-endpoint = <&vin3ep0>;
++ };
++ };
++ port@1 {
++ ov106xx_des0ep3: endpoint {
++ remote-endpoint = <&max9286_des0ep3>;
++ };
++ };
++ };
++
++ max9286@0 {
++ compatible = "maxim,max9286";
++ reg = <0x48>;
++ gpios = <&io_expander 0 GPIO_ACTIVE_LOW>; /* MAX9286 PWDN */
++ maxim,gpio0 = <0>;
++ maxim,sensor_delay = <100>;
++ maxim,links = <4>;
++ maxim,lanes = <4>;
++ maxim,resetb-gpio = <1>;
++ maxim,fsync-mode = "automatic";
++ maxim,timeout = <100>;
++
++ port@0 {
++ max9286_des0ep0: endpoint@0 {
++ max9271-addr = <0x50>;
++ dvp-order = <1>;
++ remote-endpoint = <&ov106xx_in0>;
++ };
++ max9286_des0ep1: endpoint@1 {
++ max9271-addr = <0x51>;
++ dvp-order = <1>;
++ remote-endpoint = <&ov106xx_in1>;
++ };
++ max9286_des0ep2: endpoint@2 {
++ max9271-addr = <0x52>;
++ dvp-order = <1>;
++ remote-endpoint = <&ov106xx_in2>;
++ };
++ max9286_des0ep3: endpoint@3 {
++ max9271-addr = <0x53>;
++ dvp-order = <1>;
++ remote-endpoint = <&ov106xx_in3>;
++ };
++ };
++ port@1 {
++ max9286_csi0ep0: endpoint {
++ csi-rate = <700>;
++ remote-endpoint = <&csi40_ep>;
++ };
++ };
++ };
++};
++
+ &pfc {
+ avb_pins: avb0 {
+ groups = "avb0_mdio", "avb0_rgmii", "avb0_txcrefclk";
+@@ -179,6 +336,11 @@
+ function = "i2c0";
+ };
+
++ i2c3_pins: i2c3 {
++ groups = "i2c3_a";
++ function = "i2c3";
++ };
++
+ scif0_pins: scif0 {
+ groups = "scif0_data";
+ function = "scif0";
+@@ -215,3 +377,115 @@
+ };
+ };
+ };
++
++&vin0 {
++ status = "okay";
++
++ ports {
++ #address-cells = <1>;
++ #size-cells = <0>;
++
++ port@0 {
++ vin0ep0: endpoint {
++ csi,select = "csi40";
++ virtual,channel = <0>;
++ data-lanes = <1 2 3 4>;
++ remote-endpoint = <&ov106xx_in0>;
++ };
++ };
++ port@1 {
++ csi0ep0: endpoint {
++ remote-endpoint = <&csi40_ep>;
++ };
++ };
++ port@2 {
++ vin0_max9286_des0ep0: endpoint@0 {
++ remote-endpoint = <&max9286_des0ep0>;
++ };
++ };
++ };
++};
++
++&vin1 {
++ status = "okay";
++
++ ports {
++ #address-cells = <1>;
++ #size-cells = <0>;
++
++ port@0 {
++ vin1ep0: endpoint {
++ csi,select = "csi40";
++ virtual,channel = <1>;
++ data-lanes = <1 2 3 4>;
++ remote-endpoint = <&ov106xx_in1>;
++ };
++ };
++ port@1 {
++ csi0ep1: endpoint {
++ remote-endpoint = <&csi40_ep>;
++ };
++ };
++ port@2 {
++ vin1_max9286_des0ep1: endpoint@0 {
++ remote-endpoint = <&max9286_des0ep1>;
++ };
++ };
++ };
++};
++
++&vin2 {
++ status = "okay";
++
++ ports {
++ #address-cells = <1>;
++ #size-cells = <0>;
++
++ port@0 {
++ vin2ep0: endpoint {
++ csi,select = "csi40";
++ virtual,channel = <2>;
++ data-lanes = <1 2 3 4>;
++ remote-endpoint = <&ov106xx_in2>;
++ };
++ };
++ port@1 {
++ csi0ep2: endpoint {
++ remote-endpoint = <&csi40_ep>;
++ };
++ };
++ port@2 {
++ vin2_max9286_des0ep2: endpoint@0 {
++ remote-endpoint = <&max9286_des0ep2>;
++ };
++ };
++ };
++};
++
++&vin3 {
++ status = "okay";
++
++ ports {
++ #address-cells = <1>;
++ #size-cells = <0>;
++
++ port@0 {
++ vin3ep0: endpoint {
++ csi,select = "csi40";
++ virtual,channel = <3>;
++ data-lanes = <1 2 3 4>;
++ remote-endpoint = <&ov106xx_in3>;
++ };
++ };
++ port@1 {
++ csi0ep3: endpoint {
++ remote-endpoint = <&csi40_ep>;
++ };
++ };
++ port@2 {
++ vin3_max9286_des0ep3: endpoint@0 {
++ remote-endpoint = <&max9286_des0ep3>;
++ };
++ };
++ };
++};
+--
+2.7.4
+
diff --git a/bsp/meta-rcar/meta-rcar-gen3-adas/recipes-kernel/linux/linux-renesas/0310-arm64-dts-renesas-condor-Add-video-input-support.patch b/bsp/meta-rcar/meta-rcar-gen3-adas/recipes-kernel/linux/linux-renesas/0310-arm64-dts-renesas-condor-Add-video-input-support.patch
new file mode 100644
index 00000000..02e64bcb
--- /dev/null
+++ b/bsp/meta-rcar/meta-rcar-gen3-adas/recipes-kernel/linux/linux-renesas/0310-arm64-dts-renesas-condor-Add-video-input-support.patch
@@ -0,0 +1,587 @@
+From 8bb0bdc0fcb1a8c128e936e993d81837e5ebae95 Mon Sep 17 00:00:00 2001
+From: Valentine Barshak <valentine.barshak@cogentembedded.com>
+Date: Wed, 26 Jun 2019 00:14:15 +0300
+Subject: [PATCH 130/211] arm64: dts: renesas: condor: Add video input support
+
+This adds support of two MAX9286 GMSL chips connected to the
+CSI40 and CSI41 channels. Each channel provides up to 4 video
+streams routed to VIN[0-3] and VIN[4-7] devices.
+
+Signed-off-by: Valentine Barshak <valentine.barshak@cogentembedded.com>
+---
+ arch/arm64/boot/dts/renesas/r8a77980-condor.dts | 534 ++++++++++++++++++++++++
+ 1 file changed, 534 insertions(+)
+
+diff --git a/arch/arm64/boot/dts/renesas/r8a77980-condor.dts b/arch/arm64/boot/dts/renesas/r8a77980-condor.dts
+index 738edf0..330a1a1 100644
+--- a/arch/arm64/boot/dts/renesas/r8a77980-condor.dts
++++ b/arch/arm64/boot/dts/renesas/r8a77980-condor.dts
+@@ -8,6 +8,7 @@
+
+ /dts-v1/;
+ #include "r8a77980.dtsi"
++#include <dt-bindings/gpio/gpio.h>
+
+ / {
+ model = "Renesas Condor board based on r8a77980";
+@@ -125,6 +126,74 @@
+ };
+ };
+
++&csi40 {
++ status = "okay";
++
++ virtual,channel {
++ csi2_vc0 {
++ data,type = "ycbcr422";
++ receive,vc = <0>;
++ };
++ csi2_vc1 {
++ data,type = "ycbcr422";
++ receive,vc = <1>;
++ };
++ csi2_vc2 {
++ data,type = "ycbcr422";
++ receive,vc = <2>;
++ };
++ csi2_vc3 {
++ data,type = "ycbcr422";
++ receive,vc = <3>;
++ };
++ };
++
++ port {
++ #address-cells = <1>;
++ #size-cells = <0>;
++
++ csi40_ep: endpoint {
++ clock-lanes = <0>;
++ data-lanes = <1 2 3 4>;
++ csi-rate = <300>;
++ };
++ };
++};
++
++&csi41 {
++ status = "okay";
++
++ virtual,channel {
++ csi2_vc0 {
++ data,type = "ycbcr422";
++ receive,vc = <0>;
++ };
++ csi2_vc1 {
++ data,type = "ycbcr422";
++ receive,vc = <1>;
++ };
++ csi2_vc2 {
++ data,type = "ycbcr422";
++ receive,vc = <2>;
++ };
++ csi2_vc3 {
++ data,type = "ycbcr422";
++ receive,vc = <3>;
++ };
++ };
++
++ port {
++ #address-cells = <1>;
++ #size-cells = <0>;
++
++ csi41_ep: endpoint {
++ clock-lanes = <0>;
++ data-lanes = <1 2 3 4>;
++ csi-rate = <300>;
++ };
++ };
++};
++
+ &du {
+ clocks = <&cpg CPG_MOD 724>,
+ <&x1_clk>;
+@@ -216,6 +285,242 @@
+ };
+ };
+
++&i2c1 {
++ pinctrl-0 = <&i2c1_pins>;
++ pinctrl-names = "default";
++
++ status = "okay";
++ clock-frequency = <400000>;
++
++ ov106xx@0 {
++ compatible = "ovti,ov106xx";
++ reg = <0x60>;
++
++ port@0 {
++ ov106xx_in0: endpoint {
++ clock-lanes = <0>;
++ data-lanes = <1 2 3 4>;
++ remote-endpoint = <&vin0ep0>;
++ };
++ };
++ port@1 {
++ ov106xx_max9286_des0ep0: endpoint@0 {
++ remote-endpoint = <&max9286_des0ep0>;
++ };
++ };
++ };
++
++ ov106xx@1 {
++ compatible = "ovti,ov106xx";
++ reg = <0x61>;
++
++ port@0 {
++ ov106xx_in1: endpoint {
++ clock-lanes = <0>;
++ data-lanes = <1 2 3 4>;
++ remote-endpoint = <&vin1ep0>;
++ };
++ };
++ port@1 {
++ ov106xx_max9286_des0ep1: endpoint@0 {
++ remote-endpoint = <&max9286_des0ep1>;
++ };
++ };
++ };
++
++ ov106xx@2 {
++ compatible = "ovti,ov106xx";
++ reg = <0x62>;
++
++ port@0 {
++ ov106xx_in2: endpoint {
++ clock-lanes = <0>;
++ data-lanes = <1 2 3 4>;
++ remote-endpoint = <&vin2ep0>;
++ };
++ };
++ port@1 {
++ ov106xx_max9286_des0ep2: endpoint@0 {
++ remote-endpoint = <&max9286_des0ep2>;
++ };
++ };
++ };
++
++ ov106xx@3 {
++ compatible = "ovti,ov106xx";
++ reg = <0x63>;
++
++ port@0 {
++ ov106xx_in3: endpoint {
++ clock-lanes = <0>;
++ data-lanes = <1 2 3 4>;
++ remote-endpoint = <&vin3ep0>;
++ };
++ };
++ port@1 {
++ ov106xx_des0ep3: endpoint {
++ remote-endpoint = <&max9286_des0ep3>;
++ };
++ };
++ };
++
++ ov106xx@4 {
++ compatible = "ovti,ov106xx";
++ reg = <0x64>;
++
++ port@0 {
++ ov106xx_in4: endpoint {
++ clock-lanes = <0>;
++ data-lanes = <1 2 3 4>;
++ remote-endpoint = <&vin4ep0>;
++ };
++ };
++ port@1 {
++ ov106xx_max9286_des1ep0: endpoint@0 {
++ remote-endpoint = <&max9286_des1ep0>;
++ };
++ };
++ };
++
++ ov106xx@5 {
++ compatible = "ovti,ov106xx";
++ reg = <0x65>;
++
++ port@0 {
++ ov106xx_in5: endpoint {
++ clock-lanes = <0>;
++ data-lanes = <1 2 3 4>;
++ remote-endpoint = <&vin5ep0>;
++ };
++ };
++ port@1 {
++ ov106xx_max9286_des1ep1: endpoint@0 {
++ remote-endpoint = <&max9286_des1ep1>;
++ };
++ };
++ };
++
++ ov106xx@6 {
++ compatible = "ovti,ov106xx";
++ reg = <0x66>;
++
++ port@0 {
++ ov106xx_in6: endpoint {
++ clock-lanes = <0>;
++ data-lanes = <1 2 3 4>;
++ remote-endpoint = <&vin6ep0>;
++ };
++ };
++ port@1 {
++ ov106xx_max9286_des1ep2: endpoint@0 {
++ remote-endpoint = <&max9286_des1ep2>;
++ };
++ };
++ };
++
++ ov106xx@7 {
++ compatible = "ovti,ov106xx";
++ reg = <0x67>;
++
++ port@0 {
++ ov106xx_in7: endpoint {
++ clock-lanes = <0>;
++ data-lanes = <1 2 3 4>;
++ remote-endpoint = <&vin7ep0>;
++ };
++ };
++ port@1 {
++ ov106xx_des1ep3: endpoint {
++ remote-endpoint = <&max9286_des1ep3>;
++ };
++ };
++ };
++
++ max9286@0 {
++ compatible = "maxim,max9286";
++ reg = <0x48>;
++ gpios = <&io_expander0 0 GPIO_ACTIVE_LOW>; /* MAX9286 PWDN */
++ maxim,gpio0 = <0>;
++ maxim,sensor_delay = <100>;
++ maxim,links = <4>;
++ maxim,lanes = <4>;
++ maxim,resetb-gpio = <1>;
++ maxim,fsync-mode = "automatic";
++ maxim,timeout = <100>;
++
++ port@0 {
++ max9286_des0ep0: endpoint@0 {
++ max9271-addr = <0x50>;
++ dvp-order = <1>;
++ remote-endpoint = <&ov106xx_in0>;
++ };
++ max9286_des0ep1: endpoint@1 {
++ max9271-addr = <0x51>;
++ dvp-order = <1>;
++ remote-endpoint = <&ov106xx_in1>;
++ };
++ max9286_des0ep2: endpoint@2 {
++ max9271-addr = <0x52>;
++ dvp-order = <1>;
++ remote-endpoint = <&ov106xx_in2>;
++ };
++ max9286_des0ep3: endpoint@3 {
++ max9271-addr = <0x53>;
++ dvp-order = <1>;
++ remote-endpoint = <&ov106xx_in3>;
++ };
++ };
++ port@1 {
++ max9286_csi0ep0: endpoint {
++ csi-rate = <700>;
++ remote-endpoint = <&csi40_ep>;
++ };
++ };
++ };
++
++ max9286@1 {
++ compatible = "maxim,max9286";
++ reg = <0x4a>;
++ gpios = <&io_expander1 0 GPIO_ACTIVE_LOW>; /* MAX9286 PWDN */
++ maxim,gpio0 = <0>;
++ maxim,sensor_delay = <100>;
++ maxim,links = <4>;
++ maxim,lanes = <4>;
++ maxim,resetb-gpio = <1>;
++ maxim,fsync-mode = "automatic";
++ maxim,timeout = <100>;
++
++ port@0 {
++ max9286_des1ep0: endpoint@0 {
++ max9271-addr = <0x54>;
++ dvp-order = <1>;
++ remote-endpoint = <&ov106xx_in4>;
++ };
++ max9286_des1ep1: endpoint@1 {
++ max9271-addr = <0x55>;
++ dvp-order = <1>;
++ remote-endpoint = <&ov106xx_in5>;
++ };
++ max9286_des1ep2: endpoint@2 {
++ max9271-addr = <0x56>;
++ dvp-order = <1>;
++ remote-endpoint = <&ov106xx_in6>;
++ };
++ max9286_des1ep3: endpoint@3 {
++ max9271-addr = <0x57>;
++ dvp-order = <1>;
++ remote-endpoint = <&ov106xx_in7>;
++ };
++ };
++ port@1 {
++ max9286_csi1ep0: endpoint {
++ csi-rate = <700>;
++ remote-endpoint = <&csi41_ep>;
++ };
++ };
++ };
++};
++
+ &lvds0 {
+ status = "okay";
+
+@@ -275,6 +580,11 @@
+ function = "i2c0";
+ };
+
++ i2c1_pins: i2c1 {
++ groups = "i2c1";
++ function = "i2c1";
++ };
++
+ mmc_pins: mmc {
+ groups = "mmc_data8", "mmc_ctrl", "mmc_ds";
+ function = "mmc";
+@@ -313,3 +623,227 @@
+ &scif_clk {
+ clock-frequency = <14745600>;
+ };
++
++&vin0 {
++ status = "okay";
++
++ ports {
++ #address-cells = <1>;
++ #size-cells = <0>;
++
++ port@0 {
++ vin0ep0: endpoint {
++ csi,select = "csi40";
++ virtual,channel = <0>;
++ data-lanes = <1 2 3 4>;
++ remote-endpoint = <&ov106xx_in0>;
++ };
++ };
++ port@1 {
++ csi0ep0: endpoint {
++ remote-endpoint = <&csi40_ep>;
++ };
++ };
++ port@2 {
++ vin0_max9286_des0ep0: endpoint@0 {
++ remote-endpoint = <&max9286_des0ep0>;
++ };
++ };
++ };
++};
++
++&vin1 {
++ status = "okay";
++
++ ports {
++ #address-cells = <1>;
++ #size-cells = <0>;
++
++ port@0 {
++ vin1ep0: endpoint {
++ csi,select = "csi40";
++ virtual,channel = <1>;
++ data-lanes = <1 2 3 4>;
++ remote-endpoint = <&ov106xx_in1>;
++ };
++ };
++ port@1 {
++ csi0ep1: endpoint {
++ remote-endpoint = <&csi40_ep>;
++ };
++ };
++ port@2 {
++ vin1_max9286_des0ep1: endpoint@0 {
++ remote-endpoint = <&max9286_des0ep1>;
++ };
++ };
++ };
++};
++
++&vin2 {
++ status = "okay";
++
++ ports {
++ #address-cells = <1>;
++ #size-cells = <0>;
++
++ port@0 {
++ vin2ep0: endpoint {
++ csi,select = "csi40";
++ virtual,channel = <2>;
++ data-lanes = <1 2 3 4>;
++ remote-endpoint = <&ov106xx_in2>;
++ };
++ };
++ port@1 {
++ csi0ep2: endpoint {
++ remote-endpoint = <&csi40_ep>;
++ };
++ };
++ port@2 {
++ vin2_max9286_des0ep2: endpoint@0 {
++ remote-endpoint = <&max9286_des0ep2>;
++ };
++ };
++ };
++};
++
++&vin3 {
++ status = "okay";
++
++ ports {
++ #address-cells = <1>;
++ #size-cells = <0>;
++
++ port@0 {
++ vin3ep0: endpoint {
++ csi,select = "csi40";
++ virtual,channel = <3>;
++ data-lanes = <1 2 3 4>;
++ remote-endpoint = <&ov106xx_in3>;
++ };
++ };
++ port@1 {
++ csi0ep3: endpoint {
++ remote-endpoint = <&csi40_ep>;
++ };
++ };
++ port@2 {
++ vin3_max9286_des0ep3: endpoint@0 {
++ remote-endpoint = <&max9286_des0ep3>;
++ };
++ };
++ };
++};
++
++&vin4 {
++ status = "okay";
++
++ ports {
++ #address-cells = <1>;
++ #size-cells = <0>;
++
++ port@0 {
++ vin4ep0: endpoint {
++ csi,select = "csi41";
++ virtual,channel = <0>;
++ data-lanes = <1 2 3 4>;
++ remote-endpoint = <&ov106xx_in4>;
++ };
++ };
++ port@1 {
++ csi1ep0: endpoint {
++ remote-endpoint = <&csi41_ep>;
++ };
++ };
++ port@2 {
++ vin4_max9286_des1ep0: endpoint@0 {
++ remote-endpoint = <&max9286_des1ep0>;
++ };
++ };
++ };
++};
++
++&vin5 {
++ status = "okay";
++
++ ports {
++ #address-cells = <1>;
++ #size-cells = <0>;
++
++ port@0 {
++ vin5ep0: endpoint {
++ csi,select = "csi41";
++ virtual,channel = <1>;
++ data-lanes = <1 2 3 4>;
++ remote-endpoint = <&ov106xx_in5>;
++ };
++ };
++ port@1 {
++ csi1ep1: endpoint {
++ remote-endpoint = <&csi41_ep>;
++ };
++ };
++ port@2 {
++ vin5_max9286_des1ep1: endpoint@0 {
++ remote-endpoint = <&max9286_des1ep1>;
++ };
++ };
++ };
++};
++
++&vin6 {
++ status = "okay";
++
++ ports {
++ #address-cells = <1>;
++ #size-cells = <0>;
++
++ port@0 {
++ vin6ep0: endpoint {
++ csi,select = "csi41";
++ virtual,channel = <2>;
++ data-lanes = <1 2 3 4>;
++ remote-endpoint = <&ov106xx_in6>;
++ };
++ };
++ port@1 {
++ csi1ep2: endpoint {
++ remote-endpoint = <&csi41_ep>;
++ };
++ };
++ port@2 {
++ vin6_max9286_des1ep2: endpoint@0 {
++ remote-endpoint = <&max9286_des1ep2>;
++ };
++ };
++ };
++};
++
++&vin7 {
++ status = "okay";
++
++ ports {
++ #address-cells = <1>;
++ #size-cells = <0>;
++
++ port@0 {
++ vin7ep0: endpoint {
++ csi,select = "csi41";
++ virtual,channel = <3>;
++ data-lanes = <1 2 3 4>;
++ remote-endpoint = <&ov106xx_in7>;
++ };
++ };
++ port@1 {
++ csi1ep3: endpoint {
++ remote-endpoint = <&csi41_ep>;
++ };
++ };
++ port@2 {
++ vin7_max9286_des1ep3: endpoint@0 {
++ remote-endpoint = <&max9286_des1ep3>;
++ };
++ };
++ };
++};
+--
+2.7.4
+
diff --git a/bsp/meta-rcar/meta-rcar-gen3-adas/recipes-kernel/linux/linux-renesas/0311-arm64-dts-renesas-v3msk-Add-reserved-memory-nodes.patch b/bsp/meta-rcar/meta-rcar-gen3-adas/recipes-kernel/linux/linux-renesas/0311-arm64-dts-renesas-v3msk-Add-reserved-memory-nodes.patch
new file mode 100644
index 00000000..bd55fbe1
--- /dev/null
+++ b/bsp/meta-rcar/meta-rcar-gen3-adas/recipes-kernel/linux/linux-renesas/0311-arm64-dts-renesas-v3msk-Add-reserved-memory-nodes.patch
@@ -0,0 +1,53 @@
+From 244b4bd18f4e0ee937503c8590d7bd0832fe438c Mon Sep 17 00:00:00 2001
+From: Valentine Barshak <valentine.barshak@cogentembedded.com>
+Date: Sat, 27 Oct 2018 00:00:15 +0300
+Subject: [PATCH 131/211] arm64: dts: renesas: v3msk: Add reserved memory nodes
+
+This adds reserved memory nodes.
+
+Signed-off-by: Valentine Barshak <valentine.barshak@cogentembedded.com>
+---
+ arch/arm64/boot/dts/renesas/r8a77970-v3msk.dts | 27 ++++++++++++++++++++++++++
+ 1 file changed, 27 insertions(+)
+
+diff --git a/arch/arm64/boot/dts/renesas/r8a77970-v3msk.dts b/arch/arm64/boot/dts/renesas/r8a77970-v3msk.dts
+index 15cc9fe..8e0dbd7 100644
+--- a/arch/arm64/boot/dts/renesas/r8a77970-v3msk.dts
++++ b/arch/arm64/boot/dts/renesas/r8a77970-v3msk.dts
+@@ -27,6 +27,33 @@
+ reg = <0x0 0x48000000 0x0 0x38000000>;
+ };
+
++ reserved-memory {
++ #address-cells = <2>;
++ #size-cells = <2>;
++ ranges;
++
++ /* device specific region for Lossy Decompression */
++ lossy_decompress: linux,lossy_decompress {
++ no-map;
++ reg = <0x00000000 0x6c000000 0x0 0x03000000>;
++ };
++
++ /* global autoconfigured region for contiguous allocations */
++ linux,cma {
++ compatible = "shared-dma-pool";
++ reusable;
++ reg = <0x00000000 0x6f000000 0x0 0x10000000>;
++ linux,cma-default;
++ };
++
++ /* device specific region for contiguous allocations */
++ linux,multimedia {
++ compatible = "shared-dma-pool";
++ reusable;
++ reg = <0x00000000 0x7f000000 0x0 0x01000000>;
++ };
++ };
++
+ osc5_clk: osc5-clock {
+ compatible = "fixed-clock";
+ #clock-cells = <0>;
+--
+2.7.4
+
diff --git a/bsp/meta-rcar/meta-rcar-gen3-adas/recipes-kernel/linux/linux-renesas/0312-arm64-dts-renesas-v3hsk-Add-reserved-memory-nodes.patch b/bsp/meta-rcar/meta-rcar-gen3-adas/recipes-kernel/linux/linux-renesas/0312-arm64-dts-renesas-v3hsk-Add-reserved-memory-nodes.patch
new file mode 100644
index 00000000..94a11f7e
--- /dev/null
+++ b/bsp/meta-rcar/meta-rcar-gen3-adas/recipes-kernel/linux/linux-renesas/0312-arm64-dts-renesas-v3hsk-Add-reserved-memory-nodes.patch
@@ -0,0 +1,53 @@
+From d5cd213aae89a74015614fb8882f8f84af13272e Mon Sep 17 00:00:00 2001
+From: Valentine Barshak <valentine.barshak@cogentembedded.com>
+Date: Sat, 27 Oct 2018 00:01:16 +0300
+Subject: [PATCH 132/211] arm64: dts: renesas: v3hsk: Add reserved memory nodes
+
+This adds reserved memory nodes.
+
+Signed-off-by: Valentine Barshak <valentine.barshak@cogentembedded.com>
+---
+ arch/arm64/boot/dts/renesas/r8a77980-v3hsk.dts | 27 ++++++++++++++++++++++++++
+ 1 file changed, 27 insertions(+)
+
+diff --git a/arch/arm64/boot/dts/renesas/r8a77980-v3hsk.dts b/arch/arm64/boot/dts/renesas/r8a77980-v3hsk.dts
+index dd14a41..eb7f03a 100644
+--- a/arch/arm64/boot/dts/renesas/r8a77980-v3hsk.dts
++++ b/arch/arm64/boot/dts/renesas/r8a77980-v3hsk.dts
+@@ -28,6 +28,33 @@
+ reg = <0 0x48000000 0 0x78000000>;
+ };
+
++ reserved-memory {
++ #address-cells = <2>;
++ #size-cells = <2>;
++ ranges;
++
++ /* device specific region for Lossy Decompression */
++ lossy_decompress: linux,lossy_decompress {
++ no-map;
++ reg = <0x00000000 0x6c000000 0x0 0x03000000>;
++ };
++
++ /* global autoconfigured region for contiguous allocations */
++ linux,cma {
++ compatible = "shared-dma-pool";
++ reusable;
++ reg = <0x00000000 0x6f000000 0x0 0x10000000>;
++ linux,cma-default;
++ };
++
++ /* device specific region for contiguous allocations */
++ linux,multimedia {
++ compatible = "shared-dma-pool";
++ reusable;
++ reg = <0x00000000 0x7f000000 0x0 0x01000000>;
++ };
++ };
++
+ hdmi-out {
+ compatible = "hdmi-connector";
+ type = "a";
+--
+2.7.4
+
diff --git a/bsp/meta-rcar/meta-rcar-gen3-adas/recipes-kernel/linux/linux-renesas/0313-arm64-dts-renesas-eagle-Add-reserved-memory-nodes.patch b/bsp/meta-rcar/meta-rcar-gen3-adas/recipes-kernel/linux/linux-renesas/0313-arm64-dts-renesas-eagle-Add-reserved-memory-nodes.patch
new file mode 100644
index 00000000..e96842d1
--- /dev/null
+++ b/bsp/meta-rcar/meta-rcar-gen3-adas/recipes-kernel/linux/linux-renesas/0313-arm64-dts-renesas-eagle-Add-reserved-memory-nodes.patch
@@ -0,0 +1,53 @@
+From d8bc79f65b3dc567c2c56e015602467d6466ed1e Mon Sep 17 00:00:00 2001
+From: Valentine Barshak <valentine.barshak@cogentembedded.com>
+Date: Sat, 27 Oct 2018 00:02:28 +0300
+Subject: [PATCH 133/211] arm64: dts: renesas: eagle: Add reserved memory nodes
+
+This adds reserved memory nodes.
+
+Signed-off-by: Valentine Barshak <valentine.barshak@cogentembedded.com>
+---
+ arch/arm64/boot/dts/renesas/r8a77970-eagle.dts | 27 ++++++++++++++++++++++++++
+ 1 file changed, 27 insertions(+)
+
+diff --git a/arch/arm64/boot/dts/renesas/r8a77970-eagle.dts b/arch/arm64/boot/dts/renesas/r8a77970-eagle.dts
+index a70337b..fcc6a83 100644
+--- a/arch/arm64/boot/dts/renesas/r8a77970-eagle.dts
++++ b/arch/arm64/boot/dts/renesas/r8a77970-eagle.dts
+@@ -30,6 +30,33 @@
+ reg = <0x0 0x48000000 0x0 0x38000000>;
+ };
+
++ reserved-memory {
++ #address-cells = <2>;
++ #size-cells = <2>;
++ ranges;
++
++ /* device specific region for Lossy Decompression */
++ lossy_decompress: linux,lossy_decompress {
++ no-map;
++ reg = <0x00000000 0x6c000000 0x0 0x03000000>;
++ };
++
++ /* global autoconfigured region for contiguous allocations */
++ linux,cma {
++ compatible = "shared-dma-pool";
++ reusable;
++ reg = <0x00000000 0x6f000000 0x0 0x10000000>;
++ linux,cma-default;
++ };
++
++ /* device specific region for contiguous allocations */
++ linux,multimedia {
++ compatible = "shared-dma-pool";
++ reusable;
++ reg = <0x00000000 0x7f000000 0x0 0x01000000>;
++ };
++ };
++
+ hdmi-out {
+ compatible = "hdmi-connector";
+ type = "a";
+--
+2.7.4
+
diff --git a/bsp/meta-rcar/meta-rcar-gen3-adas/recipes-kernel/linux/linux-renesas/0314-arm64-dts-renesas-condor-Add-reserved-memory-nodes.patch b/bsp/meta-rcar/meta-rcar-gen3-adas/recipes-kernel/linux/linux-renesas/0314-arm64-dts-renesas-condor-Add-reserved-memory-nodes.patch
new file mode 100644
index 00000000..446e7dab
--- /dev/null
+++ b/bsp/meta-rcar/meta-rcar-gen3-adas/recipes-kernel/linux/linux-renesas/0314-arm64-dts-renesas-condor-Add-reserved-memory-nodes.patch
@@ -0,0 +1,54 @@
+From 2129083f43a92d53a7eeb5828f088cc4a595bba7 Mon Sep 17 00:00:00 2001
+From: Valentine Barshak <valentine.barshak@cogentembedded.com>
+Date: Sat, 27 Oct 2018 00:03:04 +0300
+Subject: [PATCH 134/211] arm64: dts: renesas: condor: Add reserved memory
+ nodes
+
+This adds reserved memory nodes.
+
+Signed-off-by: Valentine Barshak <valentine.barshak@cogentembedded.com>
+---
+ arch/arm64/boot/dts/renesas/r8a77980-condor.dts | 27 +++++++++++++++++++++++++
+ 1 file changed, 27 insertions(+)
+
+diff --git a/arch/arm64/boot/dts/renesas/r8a77980-condor.dts b/arch/arm64/boot/dts/renesas/r8a77980-condor.dts
+index 330a1a1..c8bda5a 100644
+--- a/arch/arm64/boot/dts/renesas/r8a77980-condor.dts
++++ b/arch/arm64/boot/dts/renesas/r8a77980-condor.dts
+@@ -30,6 +30,33 @@
+ reg = <0 0x48000000 0 0x78000000>;
+ };
+
++ reserved-memory {
++ #address-cells = <2>;
++ #size-cells = <2>;
++ ranges;
++
++ /* device specific region for Lossy Decompression */
++ lossy_decompress: linux,lossy_decompress {
++ no-map;
++ reg = <0x00000000 0x6c000000 0x0 0x03000000>;
++ };
++
++ /* global autoconfigured region for contiguous allocations */
++ linux,cma {
++ compatible = "shared-dma-pool";
++ reusable;
++ reg = <0x00000000 0x6f000000 0x0 0x10000000>;
++ linux,cma-default;
++ };
++
++ /* device specific region for contiguous allocations */
++ linux,multimedia {
++ compatible = "shared-dma-pool";
++ reusable;
++ reg = <0x00000000 0x7f000000 0x0 0x01000000>;
++ };
++ };
++
+ d3_3v: regulator-0 {
+ compatible = "regulator-fixed";
+ regulator-name = "D3.3V";
+--
+2.7.4
+
diff --git a/bsp/meta-rcar/meta-rcar-gen3-adas/recipes-kernel/linux/linux-renesas/0315-arm64-dts-renesas-v3msk-Add-mmngr-and-mmngrbuf-nodes.patch b/bsp/meta-rcar/meta-rcar-gen3-adas/recipes-kernel/linux/linux-renesas/0315-arm64-dts-renesas-v3msk-Add-mmngr-and-mmngrbuf-nodes.patch
new file mode 100644
index 00000000..68967ff2
--- /dev/null
+++ b/bsp/meta-rcar/meta-rcar-gen3-adas/recipes-kernel/linux/linux-renesas/0315-arm64-dts-renesas-v3msk-Add-mmngr-and-mmngrbuf-nodes.patch
@@ -0,0 +1,36 @@
+From 24aeecff3debd8fcd167979867cf6abc1e5ba329 Mon Sep 17 00:00:00 2001
+From: Valentine Barshak <valentine.barshak@cogentembedded.com>
+Date: Sat, 27 Oct 2018 00:19:07 +0300
+Subject: [PATCH 135/211] arm64: dts: renesas: v3msk: Add mmngr and mmngrbuf
+ nodes
+
+This adds mmngr and mmngrbuf nodes.
+
+Signed-off-by: Valentine Barshak <valentine.barshak@cogentembedded.com>
+---
+ arch/arm64/boot/dts/renesas/r8a77970-v3msk.dts | 9 +++++++++
+ 1 file changed, 9 insertions(+)
+
+diff --git a/arch/arm64/boot/dts/renesas/r8a77970-v3msk.dts b/arch/arm64/boot/dts/renesas/r8a77970-v3msk.dts
+index 8e0dbd7..3deda9f 100644
+--- a/arch/arm64/boot/dts/renesas/r8a77970-v3msk.dts
++++ b/arch/arm64/boot/dts/renesas/r8a77970-v3msk.dts
+@@ -54,6 +54,15 @@
+ };
+ };
+
++ mmngr {
++ compatible = "renesas,mmngr";
++ memory-region = <&lossy_decompress>;
++ };
++
++ mmngrbuf {
++ compatible = "renesas,mmngrbuf";
++ };
++
+ osc5_clk: osc5-clock {
+ compatible = "fixed-clock";
+ #clock-cells = <0>;
+--
+2.7.4
+
diff --git a/bsp/meta-rcar/meta-rcar-gen3-adas/recipes-kernel/linux/linux-renesas/0316-arm64-dts-renesas-v3hsk-Add-mmngr-and-mmngrbuf-nodes.patch b/bsp/meta-rcar/meta-rcar-gen3-adas/recipes-kernel/linux/linux-renesas/0316-arm64-dts-renesas-v3hsk-Add-mmngr-and-mmngrbuf-nodes.patch
new file mode 100644
index 00000000..d78b8f07
--- /dev/null
+++ b/bsp/meta-rcar/meta-rcar-gen3-adas/recipes-kernel/linux/linux-renesas/0316-arm64-dts-renesas-v3hsk-Add-mmngr-and-mmngrbuf-nodes.patch
@@ -0,0 +1,36 @@
+From 3a5d6b62e7d8c993e3bad5594119519e54a73e3c Mon Sep 17 00:00:00 2001
+From: Valentine Barshak <valentine.barshak@cogentembedded.com>
+Date: Sat, 27 Oct 2018 00:20:52 +0300
+Subject: [PATCH 136/211] arm64: dts: renesas: v3hsk: Add mmngr and mmngrbuf
+ nodes
+
+This adds mmngr and mmngrbuf nodes.
+
+Signed-off-by: Valentine Barshak <valentine.barshak@cogentembedded.com>
+---
+ arch/arm64/boot/dts/renesas/r8a77980-v3hsk.dts | 9 +++++++++
+ 1 file changed, 9 insertions(+)
+
+diff --git a/arch/arm64/boot/dts/renesas/r8a77980-v3hsk.dts b/arch/arm64/boot/dts/renesas/r8a77980-v3hsk.dts
+index eb7f03a..4aa6b27 100644
+--- a/arch/arm64/boot/dts/renesas/r8a77980-v3hsk.dts
++++ b/arch/arm64/boot/dts/renesas/r8a77980-v3hsk.dts
+@@ -55,6 +55,15 @@
+ };
+ };
+
++ mmngr {
++ compatible = "renesas,mmngr";
++ memory-region = <&lossy_decompress>;
++ };
++
++ mmngrbuf {
++ compatible = "renesas,mmngrbuf";
++ };
++
+ hdmi-out {
+ compatible = "hdmi-connector";
+ type = "a";
+--
+2.7.4
+
diff --git a/bsp/meta-rcar/meta-rcar-gen3-adas/recipes-kernel/linux/linux-renesas/0317-arm64-dts-renesas-eagle-Add-mmngr-and-mmngrbuf-nodes.patch b/bsp/meta-rcar/meta-rcar-gen3-adas/recipes-kernel/linux/linux-renesas/0317-arm64-dts-renesas-eagle-Add-mmngr-and-mmngrbuf-nodes.patch
new file mode 100644
index 00000000..92b60e89
--- /dev/null
+++ b/bsp/meta-rcar/meta-rcar-gen3-adas/recipes-kernel/linux/linux-renesas/0317-arm64-dts-renesas-eagle-Add-mmngr-and-mmngrbuf-nodes.patch
@@ -0,0 +1,36 @@
+From 816cc7d4c3a4cd8db18b57cc4c39d09de2277b84 Mon Sep 17 00:00:00 2001
+From: Valentine Barshak <valentine.barshak@cogentembedded.com>
+Date: Sat, 27 Oct 2018 00:21:23 +0300
+Subject: [PATCH 137/211] arm64: dts: renesas: eagle: Add mmngr and mmngrbuf
+ nodes
+
+This adds mmngr and mmngrbuf nodes.
+
+Signed-off-by: Valentine Barshak <valentine.barshak@cogentembedded.com>
+---
+ arch/arm64/boot/dts/renesas/r8a77970-eagle.dts | 9 +++++++++
+ 1 file changed, 9 insertions(+)
+
+diff --git a/arch/arm64/boot/dts/renesas/r8a77970-eagle.dts b/arch/arm64/boot/dts/renesas/r8a77970-eagle.dts
+index fcc6a83..a59fd32 100644
+--- a/arch/arm64/boot/dts/renesas/r8a77970-eagle.dts
++++ b/arch/arm64/boot/dts/renesas/r8a77970-eagle.dts
+@@ -57,6 +57,15 @@
+ };
+ };
+
++ mmngr {
++ compatible = "renesas,mmngr";
++ memory-region = <&lossy_decompress>;
++ };
++
++ mmngrbuf {
++ compatible = "renesas,mmngrbuf";
++ };
++
+ hdmi-out {
+ compatible = "hdmi-connector";
+ type = "a";
+--
+2.7.4
+
diff --git a/bsp/meta-rcar/meta-rcar-gen3-adas/recipes-kernel/linux/linux-renesas/0318-arm64-dts-renesas-condor-Add-mmngr-and-mmngrbuf-node.patch b/bsp/meta-rcar/meta-rcar-gen3-adas/recipes-kernel/linux/linux-renesas/0318-arm64-dts-renesas-condor-Add-mmngr-and-mmngrbuf-node.patch
new file mode 100644
index 00000000..4fdc3f1d
--- /dev/null
+++ b/bsp/meta-rcar/meta-rcar-gen3-adas/recipes-kernel/linux/linux-renesas/0318-arm64-dts-renesas-condor-Add-mmngr-and-mmngrbuf-node.patch
@@ -0,0 +1,36 @@
+From 35eb2b4afcd348ca46c25e4c0f6fbac92193c9e9 Mon Sep 17 00:00:00 2001
+From: Valentine Barshak <valentine.barshak@cogentembedded.com>
+Date: Sat, 27 Oct 2018 00:21:48 +0300
+Subject: [PATCH 138/211] arm64: dts: renesas: condor: Add mmngr and mmngrbuf
+ nodes
+
+This adds mmngr and mmngrbuf nodes.
+
+Signed-off-by: Valentine Barshak <valentine.barshak@cogentembedded.com>
+---
+ arch/arm64/boot/dts/renesas/r8a77980-condor.dts | 9 +++++++++
+ 1 file changed, 9 insertions(+)
+
+diff --git a/arch/arm64/boot/dts/renesas/r8a77980-condor.dts b/arch/arm64/boot/dts/renesas/r8a77980-condor.dts
+index c8bda5a..9965b75 100644
+--- a/arch/arm64/boot/dts/renesas/r8a77980-condor.dts
++++ b/arch/arm64/boot/dts/renesas/r8a77980-condor.dts
+@@ -57,6 +57,15 @@
+ };
+ };
+
++ mmngr {
++ compatible = "renesas,mmngr";
++ memory-region = <&lossy_decompress>;
++ };
++
++ mmngrbuf {
++ compatible = "renesas,mmngrbuf";
++ };
++
+ d3_3v: regulator-0 {
+ compatible = "regulator-fixed";
+ regulator-name = "D3.3V";
+--
+2.7.4
+
diff --git a/bsp/meta-rcar/meta-rcar-gen3-adas/recipes-kernel/linux/linux-renesas/0319-arm64-dts-renesas-v3msk-Add-vspm_if-node.patch b/bsp/meta-rcar/meta-rcar-gen3-adas/recipes-kernel/linux/linux-renesas/0319-arm64-dts-renesas-v3msk-Add-vspm_if-node.patch
new file mode 100644
index 00000000..8c7b685d
--- /dev/null
+++ b/bsp/meta-rcar/meta-rcar-gen3-adas/recipes-kernel/linux/linux-renesas/0319-arm64-dts-renesas-v3msk-Add-vspm_if-node.patch
@@ -0,0 +1,30 @@
+From 947be79b6dfaa755efa98533f790b6edcf38321e Mon Sep 17 00:00:00 2001
+From: Valentine Barshak <valentine.barshak@cogentembedded.com>
+Date: Sat, 27 Oct 2018 00:24:04 +0300
+Subject: [PATCH 139/211] arm64: dts: renesas: v3msk: Add vspm_if node
+
+This adds vspm_if node.
+
+Signed-off-by: Valentine Barshak <valentine.barshak@cogentembedded.com>
+---
+ arch/arm64/boot/dts/renesas/r8a77970-v3msk.dts | 4 ++++
+ 1 file changed, 4 insertions(+)
+
+diff --git a/arch/arm64/boot/dts/renesas/r8a77970-v3msk.dts b/arch/arm64/boot/dts/renesas/r8a77970-v3msk.dts
+index 3deda9f..6847381 100644
+--- a/arch/arm64/boot/dts/renesas/r8a77970-v3msk.dts
++++ b/arch/arm64/boot/dts/renesas/r8a77970-v3msk.dts
+@@ -63,6 +63,10 @@
+ compatible = "renesas,mmngrbuf";
+ };
+
++ vspm_if {
++ compatible = "renesas,vspm_if";
++ };
++
+ osc5_clk: osc5-clock {
+ compatible = "fixed-clock";
+ #clock-cells = <0>;
+--
+2.7.4
+
diff --git a/bsp/meta-rcar/meta-rcar-gen3-adas/recipes-kernel/linux/linux-renesas/0320-arm64-dts-renesas-v3hsk-Add-vspm_if-node.patch b/bsp/meta-rcar/meta-rcar-gen3-adas/recipes-kernel/linux/linux-renesas/0320-arm64-dts-renesas-v3hsk-Add-vspm_if-node.patch
new file mode 100644
index 00000000..897277c0
--- /dev/null
+++ b/bsp/meta-rcar/meta-rcar-gen3-adas/recipes-kernel/linux/linux-renesas/0320-arm64-dts-renesas-v3hsk-Add-vspm_if-node.patch
@@ -0,0 +1,30 @@
+From b643f0f2b529e074683d884fd871ee7e64b2b337 Mon Sep 17 00:00:00 2001
+From: Valentine Barshak <valentine.barshak@cogentembedded.com>
+Date: Sat, 27 Oct 2018 00:25:29 +0300
+Subject: [PATCH 140/211] arm64: dts: renesas: v3hsk: Add vspm_if node
+
+This adds vspm_if node.
+
+Signed-off-by: Valentine Barshak <valentine.barshak@cogentembedded.com>
+---
+ arch/arm64/boot/dts/renesas/r8a77980-v3hsk.dts | 4 ++++
+ 1 file changed, 4 insertions(+)
+
+diff --git a/arch/arm64/boot/dts/renesas/r8a77980-v3hsk.dts b/arch/arm64/boot/dts/renesas/r8a77980-v3hsk.dts
+index 4aa6b27..51607d4 100644
+--- a/arch/arm64/boot/dts/renesas/r8a77980-v3hsk.dts
++++ b/arch/arm64/boot/dts/renesas/r8a77980-v3hsk.dts
+@@ -64,6 +64,10 @@
+ compatible = "renesas,mmngrbuf";
+ };
+
++ vspm_if {
++ compatible = "renesas,vspm_if";
++ };
++
+ hdmi-out {
+ compatible = "hdmi-connector";
+ type = "a";
+--
+2.7.4
+
diff --git a/bsp/meta-rcar/meta-rcar-gen3-adas/recipes-kernel/linux/linux-renesas/0321-arm64-dts-renesas-eagle-Add-vspm_if-node.patch b/bsp/meta-rcar/meta-rcar-gen3-adas/recipes-kernel/linux/linux-renesas/0321-arm64-dts-renesas-eagle-Add-vspm_if-node.patch
new file mode 100644
index 00000000..bbd9270c
--- /dev/null
+++ b/bsp/meta-rcar/meta-rcar-gen3-adas/recipes-kernel/linux/linux-renesas/0321-arm64-dts-renesas-eagle-Add-vspm_if-node.patch
@@ -0,0 +1,30 @@
+From 0bacbca79cc21cfe3a48c82abc0ed0c8a22aaba0 Mon Sep 17 00:00:00 2001
+From: Valentine Barshak <valentine.barshak@cogentembedded.com>
+Date: Sat, 27 Oct 2018 00:25:47 +0300
+Subject: [PATCH 141/211] arm64: dts: renesas: eagle: Add vspm_if node
+
+This adds vspm_if node.
+
+Signed-off-by: Valentine Barshak <valentine.barshak@cogentembedded.com>
+---
+ arch/arm64/boot/dts/renesas/r8a77970-eagle.dts | 4 ++++
+ 1 file changed, 4 insertions(+)
+
+diff --git a/arch/arm64/boot/dts/renesas/r8a77970-eagle.dts b/arch/arm64/boot/dts/renesas/r8a77970-eagle.dts
+index a59fd32..38e6aea 100644
+--- a/arch/arm64/boot/dts/renesas/r8a77970-eagle.dts
++++ b/arch/arm64/boot/dts/renesas/r8a77970-eagle.dts
+@@ -66,6 +66,10 @@
+ compatible = "renesas,mmngrbuf";
+ };
+
++ vspm_if {
++ compatible = "renesas,vspm_if";
++ };
++
+ hdmi-out {
+ compatible = "hdmi-connector";
+ type = "a";
+--
+2.7.4
+
diff --git a/bsp/meta-rcar/meta-rcar-gen3-adas/recipes-kernel/linux/linux-renesas/0322-arm64-dts-renesas-condor-Add-vspm_if-node.patch b/bsp/meta-rcar/meta-rcar-gen3-adas/recipes-kernel/linux/linux-renesas/0322-arm64-dts-renesas-condor-Add-vspm_if-node.patch
new file mode 100644
index 00000000..38118f14
--- /dev/null
+++ b/bsp/meta-rcar/meta-rcar-gen3-adas/recipes-kernel/linux/linux-renesas/0322-arm64-dts-renesas-condor-Add-vspm_if-node.patch
@@ -0,0 +1,30 @@
+From 18f60135619bf95bd51d4bb98a86cd5d00bb0513 Mon Sep 17 00:00:00 2001
+From: Valentine Barshak <valentine.barshak@cogentembedded.com>
+Date: Sat, 27 Oct 2018 00:26:01 +0300
+Subject: [PATCH 142/211] arm64: dts: renesas: condor: Add vspm_if node
+
+This adds vspm_if node.
+
+Signed-off-by: Valentine Barshak <valentine.barshak@cogentembedded.com>
+---
+ arch/arm64/boot/dts/renesas/r8a77980-condor.dts | 4 ++++
+ 1 file changed, 4 insertions(+)
+
+diff --git a/arch/arm64/boot/dts/renesas/r8a77980-condor.dts b/arch/arm64/boot/dts/renesas/r8a77980-condor.dts
+index 9965b75..5bd0640 100644
+--- a/arch/arm64/boot/dts/renesas/r8a77980-condor.dts
++++ b/arch/arm64/boot/dts/renesas/r8a77980-condor.dts
+@@ -66,6 +66,10 @@
+ compatible = "renesas,mmngrbuf";
+ };
+
++ vspm_if {
++ compatible = "renesas,vspm_if";
++ };
++
+ d3_3v: regulator-0 {
+ compatible = "regulator-fixed";
+ regulator-name = "D3.3V";
+--
+2.7.4
+
diff --git a/bsp/meta-rcar/meta-rcar-gen3-adas/recipes-kernel/linux/linux-renesas/0323-arm64-dts-renesas-eagle-Add-Dialog-DA9063-MFD.patch b/bsp/meta-rcar/meta-rcar-gen3-adas/recipes-kernel/linux/linux-renesas/0323-arm64-dts-renesas-eagle-Add-Dialog-DA9063-MFD.patch
new file mode 100644
index 00000000..24277344
--- /dev/null
+++ b/bsp/meta-rcar/meta-rcar-gen3-adas/recipes-kernel/linux/linux-renesas/0323-arm64-dts-renesas-eagle-Add-Dialog-DA9063-MFD.patch
@@ -0,0 +1,56 @@
+From 7384b86794cb38745ef06493527563406898387f Mon Sep 17 00:00:00 2001
+From: Valentine Barshak <valentine.barshak@cogentembedded.com>
+Date: Thu, 1 Nov 2018 16:28:11 +0300
+Subject: [PATCH 143/211] arm64: dts: renesas: eagle: Add Dialog DA9063 MFD
+
+This adds Dialog DA9063 device nodes.
+
+Signed-off-by: Valentine Barshak <valentine.barshak@cogentembedded.com>
+---
+ arch/arm64/boot/dts/renesas/r8a77970-eagle.dts | 30 ++++++++++++++++++++++++++
+ 1 file changed, 30 insertions(+)
+
+diff --git a/arch/arm64/boot/dts/renesas/r8a77970-eagle.dts b/arch/arm64/boot/dts/renesas/r8a77970-eagle.dts
+index 38e6aea..abf5470 100644
+--- a/arch/arm64/boot/dts/renesas/r8a77970-eagle.dts
++++ b/arch/arm64/boot/dts/renesas/r8a77970-eagle.dts
+@@ -236,6 +236,36 @@
+ };
+ };
+ };
++
++ pmic@5A {
++ compatible = "dlg,da9063";
++ reg = <0x5A>;
++ interrupt-parent = <&intc_ex>;
++ interrupts = <0 IRQ_TYPE_LEVEL_LOW>;
++ interrupt-controller;
++
++ rtc {
++ compatible = "dlg,da9063-rtc";
++ };
++
++ wdt {
++ compatible = "dlg,da9063-watchdog";
++ };
++
++ regulators {
++ DA9063_LDO11: bmem {
++ regulator-name = "bmem";
++ regulator-min-microvolt = <3300000>;
++ regulator-max-microvolt = <3300000>;
++ regulator-always-on;
++ regulator-boot-on;
++ };
++ };
++
++ onkey {
++ compatible = "dlg,da9063-onkey";
++ };
++ };
+ };
+
+ &i2c3 {
+--
+2.7.4
+
diff --git a/bsp/meta-rcar/meta-rcar-gen3-adas/recipes-kernel/linux/linux-renesas/0324-arm64-dts-renesas-Add-r8a77970-eagle-function-suppor.patch b/bsp/meta-rcar/meta-rcar-gen3-adas/recipes-kernel/linux/linux-renesas/0324-arm64-dts-renesas-Add-r8a77970-eagle-function-suppor.patch
new file mode 100644
index 00000000..1dc5dbde
--- /dev/null
+++ b/bsp/meta-rcar/meta-rcar-gen3-adas/recipes-kernel/linux/linux-renesas/0324-arm64-dts-renesas-Add-r8a77970-eagle-function-suppor.patch
@@ -0,0 +1,41 @@
+From 692f5ca25d74fae4e01927a12df571227d644234 Mon Sep 17 00:00:00 2001
+From: Valentine Barshak <valentine.barshak@cogentembedded.com>
+Date: Thu, 1 Nov 2018 17:21:09 +0300
+Subject: [PATCH 144/211] arm64: dts: renesas: Add r8a77970-eagle-function
+ support
+
+This adds r8a77970-eagle-function device tree support.
+
+Signed-off-by: Valentine Barshak <valentine.barshak@cogentembedded.com>
+---
+ arch/arm64/boot/dts/renesas/Makefile | 1 +
+ arch/arm64/boot/dts/renesas/r8a77970-eagle-function.dts | 2 +-
+ 2 files changed, 2 insertions(+), 1 deletion(-)
+
+diff --git a/arch/arm64/boot/dts/renesas/Makefile b/arch/arm64/boot/dts/renesas/Makefile
+index 294d38a..1714f94 100644
+--- a/arch/arm64/boot/dts/renesas/Makefile
++++ b/arch/arm64/boot/dts/renesas/Makefile
+@@ -33,5 +33,6 @@ dtb-$(CONFIG_ARCH_R8A7795) += r8a7795-h3ulcb-vb2.dtb r8a7795-es1-h3ulcb-vb2.dtb
+ dtb-$(CONFIG_ARCH_R8A7795) += r8a7795-h3ulcb-vb2.1.dtb r8a7795-h3ulcb-4x2g-vb2.1.dtb
+ dtb-$(CONFIG_ARCH_R8A7795) += r8a7795-h3ulcb-vbm.dtb r8a7795-es1-h3ulcb-vbm.dtb r8a7795-h3ulcb-4x2g-vbm.dtb
+ dtb-$(CONFIG_ARCH_R8A77965) += r8a77965-m3nulcb-kf.dtb
++dtb-$(CONFIG_ARCH_R8A77970) += r8a77970-eagle-function.dtb
+
+ always := $(dtb-y)
+diff --git a/arch/arm64/boot/dts/renesas/r8a77970-eagle-function.dts b/arch/arm64/boot/dts/renesas/r8a77970-eagle-function.dts
+index 9043a07..dab17bf 100644
+--- a/arch/arm64/boot/dts/renesas/r8a77970-eagle-function.dts
++++ b/arch/arm64/boot/dts/renesas/r8a77970-eagle-function.dts
+@@ -47,7 +47,7 @@
+ };
+ };
+
+-&sdhi2 {
++&mmc0 {
+ /* used for on-board eMMC */
+ pinctrl-0 = <&sdhi2_pins_3v3>;
+ pinctrl-1 = <&sdhi2_pins_1v8>;
+--
+2.7.4
+
diff --git a/bsp/meta-rcar/meta-rcar-gen3-adas/recipes-kernel/linux/linux-renesas/0325-arm64-dts-renesas-Add-r8a77970-es1-support.patch b/bsp/meta-rcar/meta-rcar-gen3-adas/recipes-kernel/linux/linux-renesas/0325-arm64-dts-renesas-Add-r8a77970-es1-support.patch
new file mode 100644
index 00000000..834ad7e7
--- /dev/null
+++ b/bsp/meta-rcar/meta-rcar-gen3-adas/recipes-kernel/linux/linux-renesas/0325-arm64-dts-renesas-Add-r8a77970-es1-support.patch
@@ -0,0 +1,131 @@
+From 469ecb40691eae805c28b6f821f1b6351c292008 Mon Sep 17 00:00:00 2001
+From: Valentine Barshak <valentine.barshak@cogentembedded.com>
+Date: Thu, 1 Nov 2018 17:23:12 +0300
+Subject: [PATCH 145/211] arm64: dts: renesas: Add r8a77970-es1 support
+
+This adds r8a77970-es1 device tree support.
+
+Signed-off-by: Valentine Barshak <valentine.barshak@cogentembedded.com>
+---
+ arch/arm64/boot/dts/renesas/Makefile | 2 ++
+ arch/arm64/boot/dts/renesas/r8a77970-es1.dtsi | 22 +++++++++++-----------
+ 2 files changed, 13 insertions(+), 11 deletions(-)
+
+diff --git a/arch/arm64/boot/dts/renesas/Makefile b/arch/arm64/boot/dts/renesas/Makefile
+index 1714f94..dad071d 100644
+--- a/arch/arm64/boot/dts/renesas/Makefile
++++ b/arch/arm64/boot/dts/renesas/Makefile
+@@ -34,5 +34,7 @@ dtb-$(CONFIG_ARCH_R8A7795) += r8a7795-h3ulcb-vb2.1.dtb r8a7795-h3ulcb-4x2g-vb2.1
+ dtb-$(CONFIG_ARCH_R8A7795) += r8a7795-h3ulcb-vbm.dtb r8a7795-es1-h3ulcb-vbm.dtb r8a7795-h3ulcb-4x2g-vbm.dtb
+ dtb-$(CONFIG_ARCH_R8A77965) += r8a77965-m3nulcb-kf.dtb
+ dtb-$(CONFIG_ARCH_R8A77970) += r8a77970-eagle-function.dtb
++dtb-$(CONFIG_ARCH_R8A77970) += r8a77970-es1-eagle.dtb r8a77970-es1-eagle-function.dtb
++dtb-$(CONFIG_ARCH_R8A77970) += r8a77970-es1-v3msk.dtb
+
+ always := $(dtb-y)
+diff --git a/arch/arm64/boot/dts/renesas/r8a77970-es1.dtsi b/arch/arm64/boot/dts/renesas/r8a77970-es1.dtsi
+index dab9adc..74a9243 100644
+--- a/arch/arm64/boot/dts/renesas/r8a77970-es1.dtsi
++++ b/arch/arm64/boot/dts/renesas/r8a77970-es1.dtsi
+@@ -17,7 +17,7 @@
+ reg = <0 0xffa00000 0 0x10000>;
+ interrupts = <GIC_SPI 281 IRQ_TYPE_LEVEL_HIGH>;
+ clocks = <&cpg CPG_MOD 830>;
+- power-domains = <&sysc R8A7797_PD_A3IR>;
++ power-domains = <&sysc R8A77970_PD_A3IR>;
+ interrupt-controller;
+ #interrupt-cells = <1>;
+ };
+@@ -28,7 +28,7 @@
+ interrupt-parent = <&imp_distributer>;
+ interrupts = <0>;
+ clocks = <&cpg CPG_MOD 827>;
+- power-domains = <&sysc R8A7797_PD_A2IR0>;
++ power-domains = <&sysc R8A77970_PD_A2IR0>;
+ };
+
+ imp1 {
+@@ -37,7 +37,7 @@
+ interrupt-parent = <&imp_distributer>;
+ interrupts = <1>;
+ clocks = <&cpg CPG_MOD 826>;
+- power-domains = <&sysc R8A7797_PD_A2IR1>;
++ power-domains = <&sysc R8A77970_PD_A2IR1>;
+ };
+
+ imp2 {
+@@ -46,7 +46,7 @@
+ interrupt-parent = <&imp_distributer>;
+ interrupts = <2>;
+ clocks = <&cpg CPG_MOD 825>;
+- power-domains = <&sysc R8A7797_PD_A2IR2>;
++ power-domains = <&sysc R8A77970_PD_A2DP>;
+ };
+
+ imp3 {
+@@ -55,7 +55,7 @@
+ interrupt-parent = <&imp_distributer>;
+ interrupts = <3>;
+ clocks = <&cpg CPG_MOD 824>;
+- power-domains = <&sysc R8A7797_PD_A2IR3>;
++ power-domains = <&sysc R8A77970_PD_A2CN>;
+ };
+
+ impsc0 {
+@@ -64,7 +64,7 @@
+ interrupt-parent = <&imp_distributer>;
+ interrupts = <4>;
+ clocks = <&cpg CPG_MOD 829>;
+- power-domains = <&sysc R8A7797_PD_A2SC0>;
++ power-domains = <&sysc R8A77970_PD_A2SC0>;
+ };
+
+ impsc1 {
+@@ -73,7 +73,7 @@
+ interrupt-parent = <&imp_distributer>;
+ interrupts = <5>;
+ clocks = <&cpg CPG_MOD 828>;
+- power-domains = <&sysc R8A7797_PD_A2SC1>;
++ power-domains = <&sysc R8A77970_PD_A2SC1>;
+ };
+
+ impdm0 {
+@@ -82,7 +82,7 @@
+ interrupt-parent = <&imp_distributer>;
+ interrupts = <16>;
+ clocks = <&cpg CPG_MOD 830>;
+- power-domains = <&sysc R8A7797_PD_A3IR>;
++ power-domains = <&sysc R8A77970_PD_A3IR>;
+ };
+
+ impdm1 {
+@@ -92,7 +92,7 @@
+ interrupt-parent = <&imp_distributer>;
+ interrupts = <17>;
+ clocks = <&cpg CPG_MOD 830>;
+- power-domains = <&sysc R8A7797_PD_A3IR>;
++ power-domains = <&sysc R8A77970_PD_A3IR>;
+ };
+
+ imppsc0 {
+@@ -101,7 +101,7 @@
+ interrupt-parent = <&imp_distributer>;
+ interrupts = <12>;
+ clocks = <&cpg CPG_MOD 830>;
+- power-domains = <&sysc R8A7797_PD_A3IR>;
++ power-domains = <&sysc R8A77970_PD_A3IR>;
+ };
+
+ /delete-node/impcnn0;
+@@ -110,7 +110,7 @@
+ compatible = "renesas,impx4-memory";
+ reg = <0 0xed000000 0 0xe0000>;
+ clocks = <&cpg CPG_MOD 830>;
+- power-domains = <&sysc R8A7797_PD_A3IR>;
++ power-domains = <&sysc R8A77970_PD_A3IR>;
+ };
+ };
+ };
+--
+2.7.4
+
diff --git a/bsp/meta-rcar/meta-rcar-gen3-adas/recipes-kernel/linux/linux-renesas/0326-arm64-dts-renesas-Add-r8a77970-v3msk-view-support.patch b/bsp/meta-rcar/meta-rcar-gen3-adas/recipes-kernel/linux/linux-renesas/0326-arm64-dts-renesas-Add-r8a77970-v3msk-view-support.patch
new file mode 100644
index 00000000..fc28259b
--- /dev/null
+++ b/bsp/meta-rcar/meta-rcar-gen3-adas/recipes-kernel/linux/linux-renesas/0326-arm64-dts-renesas-Add-r8a77970-v3msk-view-support.patch
@@ -0,0 +1,39 @@
+From 9112a9be8c58ccb96c2d261e63d1351120514588 Mon Sep 17 00:00:00 2001
+From: Valentine Barshak <valentine.barshak@cogentembedded.com>
+Date: Thu, 1 Nov 2018 17:25:30 +0300
+Subject: [PATCH 146/211] arm64: dts: renesas: Add r8a77970-v3msk-view support
+
+This adds r8a77970-v3msk-view device tree support.
+
+Signed-off-by: Valentine Barshak <valentine.barshak@cogentembedded.com>
+---
+ arch/arm64/boot/dts/renesas/Makefile | 1 +
+ arch/arm64/boot/dts/renesas/r8a77970-v3msk-view.dts | 1 +
+ 2 files changed, 2 insertions(+)
+
+diff --git a/arch/arm64/boot/dts/renesas/Makefile b/arch/arm64/boot/dts/renesas/Makefile
+index dad071d..3e52401 100644
+--- a/arch/arm64/boot/dts/renesas/Makefile
++++ b/arch/arm64/boot/dts/renesas/Makefile
+@@ -36,5 +36,6 @@ dtb-$(CONFIG_ARCH_R8A77965) += r8a77965-m3nulcb-kf.dtb
+ dtb-$(CONFIG_ARCH_R8A77970) += r8a77970-eagle-function.dtb
+ dtb-$(CONFIG_ARCH_R8A77970) += r8a77970-es1-eagle.dtb r8a77970-es1-eagle-function.dtb
+ dtb-$(CONFIG_ARCH_R8A77970) += r8a77970-es1-v3msk.dtb
++dtb-$(CONFIG_ARCH_R8A77970) += r8a77970-v3msk-view.dtb r8a77970-es1-v3msk-view.dtb
+
+ always := $(dtb-y)
+diff --git a/arch/arm64/boot/dts/renesas/r8a77970-v3msk-view.dts b/arch/arm64/boot/dts/renesas/r8a77970-v3msk-view.dts
+index 75631fb..2197bbe 100644
+--- a/arch/arm64/boot/dts/renesas/r8a77970-v3msk-view.dts
++++ b/arch/arm64/boot/dts/renesas/r8a77970-v3msk-view.dts
+@@ -9,6 +9,7 @@
+ */
+
+ #include "r8a77970-v3msk.dts"
++#include <dt-bindings/gpio/gpio.h>
+
+ / {
+ model = "Renesas V3MSK View board based on r8a7797";
+--
+2.7.4
+
diff --git a/bsp/meta-rcar/meta-rcar-gen3-adas/recipes-kernel/linux/linux-renesas/0327-arm64-dts-renesas-Add-r8a77970-v3msk-kf-support.patch b/bsp/meta-rcar/meta-rcar-gen3-adas/recipes-kernel/linux/linux-renesas/0327-arm64-dts-renesas-Add-r8a77970-v3msk-kf-support.patch
new file mode 100644
index 00000000..d1b15e56
--- /dev/null
+++ b/bsp/meta-rcar/meta-rcar-gen3-adas/recipes-kernel/linux/linux-renesas/0327-arm64-dts-renesas-Add-r8a77970-v3msk-kf-support.patch
@@ -0,0 +1,39 @@
+From 960431f5ff91366a3625d4696d83617e3d8b9419 Mon Sep 17 00:00:00 2001
+From: Valentine Barshak <valentine.barshak@cogentembedded.com>
+Date: Thu, 1 Nov 2018 17:28:40 +0300
+Subject: [PATCH 147/211] arm64: dts: renesas: Add r8a77970-v3msk-kf support
+
+This adds r8a77970-v3msk-kf device tree support.
+
+Signed-off-by: Valentine Barshak <valentine.barshak@cogentembedded.com>
+---
+ arch/arm64/boot/dts/renesas/Makefile | 1 +
+ arch/arm64/boot/dts/renesas/r8a77970-v3msk-kf.dts | 1 +
+ 2 files changed, 2 insertions(+)
+
+diff --git a/arch/arm64/boot/dts/renesas/Makefile b/arch/arm64/boot/dts/renesas/Makefile
+index 3e52401..98d1479 100644
+--- a/arch/arm64/boot/dts/renesas/Makefile
++++ b/arch/arm64/boot/dts/renesas/Makefile
+@@ -37,5 +37,6 @@ dtb-$(CONFIG_ARCH_R8A77970) += r8a77970-eagle-function.dtb
+ dtb-$(CONFIG_ARCH_R8A77970) += r8a77970-es1-eagle.dtb r8a77970-es1-eagle-function.dtb
+ dtb-$(CONFIG_ARCH_R8A77970) += r8a77970-es1-v3msk.dtb
+ dtb-$(CONFIG_ARCH_R8A77970) += r8a77970-v3msk-view.dtb r8a77970-es1-v3msk-view.dtb
++dtb-$(CONFIG_ARCH_R8A77970) += r8a77970-v3msk-kf.dtb r8a77970-es1-v3msk-kf.dtb
+
+ always := $(dtb-y)
+diff --git a/arch/arm64/boot/dts/renesas/r8a77970-v3msk-kf.dts b/arch/arm64/boot/dts/renesas/r8a77970-v3msk-kf.dts
+index 29ae871..8c001a5 100644
+--- a/arch/arm64/boot/dts/renesas/r8a77970-v3msk-kf.dts
++++ b/arch/arm64/boot/dts/renesas/r8a77970-v3msk-kf.dts
+@@ -10,6 +10,7 @@
+ */
+
+ #include "r8a77970-v3msk.dts"
++#include <dt-bindings/gpio/gpio.h>
+
+ / {
+ model = "Renesas V3MSK Kingfisher board based on r8a7797";
+--
+2.7.4
+
diff --git a/bsp/meta-rcar/meta-rcar-gen3-adas/recipes-kernel/linux/linux-renesas/0328-arm64-dts-renesas-Add-r8a77970-v3msk-vbm-support.patch b/bsp/meta-rcar/meta-rcar-gen3-adas/recipes-kernel/linux/linux-renesas/0328-arm64-dts-renesas-Add-r8a77970-v3msk-vbm-support.patch
new file mode 100644
index 00000000..2c2015cc
--- /dev/null
+++ b/bsp/meta-rcar/meta-rcar-gen3-adas/recipes-kernel/linux/linux-renesas/0328-arm64-dts-renesas-Add-r8a77970-v3msk-vbm-support.patch
@@ -0,0 +1,44 @@
+From 7e5d40d35e34010d650be7cb9a4d6aebca14cd73 Mon Sep 17 00:00:00 2001
+From: Valentine Barshak <valentine.barshak@cogentembedded.com>
+Date: Thu, 1 Nov 2018 17:30:38 +0300
+Subject: [PATCH 148/211] arm64: dts: renesas: Add r8a77970-v3msk-vbm support
+
+This adds r8a77970-v3msk-vbm device tree support.
+
+Signed-off-by: Valentine Barshak <valentine.barshak@cogentembedded.com>
+---
+ arch/arm64/boot/dts/renesas/Makefile | 2 ++
+ arch/arm64/boot/dts/renesas/r8a77970-v3msk-vbm.dts | 3 ++-
+ 2 files changed, 4 insertions(+), 1 deletion(-)
+
+diff --git a/arch/arm64/boot/dts/renesas/Makefile b/arch/arm64/boot/dts/renesas/Makefile
+index 98d1479..1679e8c 100644
+--- a/arch/arm64/boot/dts/renesas/Makefile
++++ b/arch/arm64/boot/dts/renesas/Makefile
+@@ -38,5 +38,7 @@ dtb-$(CONFIG_ARCH_R8A77970) += r8a77970-es1-eagle.dtb r8a77970-es1-eagle-functio
+ dtb-$(CONFIG_ARCH_R8A77970) += r8a77970-es1-v3msk.dtb
+ dtb-$(CONFIG_ARCH_R8A77970) += r8a77970-v3msk-view.dtb r8a77970-es1-v3msk-view.dtb
+ dtb-$(CONFIG_ARCH_R8A77970) += r8a77970-v3msk-kf.dtb r8a77970-es1-v3msk-kf.dtb
++dtb-$(CONFIG_ARCH_R8A77970) += r8a77970-v3msk-vbm.dtb r8a77970-es1-v3msk-vbm.dtb
++dtb-$(CONFIG_ARCH_R8A77970) += r8a77970-v3msk-vbm-v2.dtb r8a77970-es1-v3msk-vbm-v2.dtb
+
+ always := $(dtb-y)
+diff --git a/arch/arm64/boot/dts/renesas/r8a77970-v3msk-vbm.dts b/arch/arm64/boot/dts/renesas/r8a77970-v3msk-vbm.dts
+index a37ccaa..485de2a 100644
+--- a/arch/arm64/boot/dts/renesas/r8a77970-v3msk-vbm.dts
++++ b/arch/arm64/boot/dts/renesas/r8a77970-v3msk-vbm.dts
+@@ -9,9 +9,10 @@
+ */
+
+ #include "r8a77970-v3msk.dts"
++#include <dt-bindings/gpio/gpio.h>
+
+ / {
+- model = "Renesas V3MSK Videobox Mini board based on r8a7797";
++ model = "Renesas V3MSK Videobox Mini board based on r8a77970";
+
+ aliases {
+ serial1 = &scif3;
+--
+2.7.4
+
diff --git a/bsp/meta-rcar/meta-rcar-gen3-adas/recipes-kernel/linux/linux-renesas/0329-arm64-dts-renesas-Add-r8a77970-v3mzf-support.patch b/bsp/meta-rcar/meta-rcar-gen3-adas/recipes-kernel/linux/linux-renesas/0329-arm64-dts-renesas-Add-r8a77970-v3mzf-support.patch
new file mode 100644
index 00000000..534ac343
--- /dev/null
+++ b/bsp/meta-rcar/meta-rcar-gen3-adas/recipes-kernel/linux/linux-renesas/0329-arm64-dts-renesas-Add-r8a77970-v3mzf-support.patch
@@ -0,0 +1,114 @@
+From fa7923d1b823ee09defaf2f6740955f709f0f419 Mon Sep 17 00:00:00 2001
+From: Valentine Barshak <valentine.barshak@cogentembedded.com>
+Date: Thu, 1 Nov 2018 17:34:32 +0300
+Subject: [PATCH 149/211] arm64: dts: renesas: Add r8a77970-v3mzf support
+
+This adds r8a77970-v3mzf device tree support.
+
+Signed-off-by: Valentine Barshak <valentine.barshak@cogentembedded.com>
+---
+ arch/arm64/boot/dts/renesas/Makefile | 1 +
+ arch/arm64/boot/dts/renesas/r8a77970-v3mzf.dts | 34 +++++++++++++++-----------
+ 2 files changed, 21 insertions(+), 14 deletions(-)
+
+diff --git a/arch/arm64/boot/dts/renesas/Makefile b/arch/arm64/boot/dts/renesas/Makefile
+index 1679e8c..7698983d 100644
+--- a/arch/arm64/boot/dts/renesas/Makefile
++++ b/arch/arm64/boot/dts/renesas/Makefile
+@@ -40,5 +40,6 @@ dtb-$(CONFIG_ARCH_R8A77970) += r8a77970-v3msk-view.dtb r8a77970-es1-v3msk-view.d
+ dtb-$(CONFIG_ARCH_R8A77970) += r8a77970-v3msk-kf.dtb r8a77970-es1-v3msk-kf.dtb
+ dtb-$(CONFIG_ARCH_R8A77970) += r8a77970-v3msk-vbm.dtb r8a77970-es1-v3msk-vbm.dtb
+ dtb-$(CONFIG_ARCH_R8A77970) += r8a77970-v3msk-vbm-v2.dtb r8a77970-es1-v3msk-vbm-v2.dtb
++dtb-$(CONFIG_ARCH_R8A77970) += r8a77970-v3mzf.dtb
+
+ always := $(dtb-y)
+diff --git a/arch/arm64/boot/dts/renesas/r8a77970-v3mzf.dts b/arch/arm64/boot/dts/renesas/r8a77970-v3mzf.dts
+index 2087364..71a765a 100644
+--- a/arch/arm64/boot/dts/renesas/r8a77970-v3mzf.dts
++++ b/arch/arm64/boot/dts/renesas/r8a77970-v3mzf.dts
+@@ -13,8 +13,8 @@
+ #include <dt-bindings/gpio/gpio.h>
+
+ / {
+- model = "Renesas V3MZF board based on r8a7797";
+- compatible = "renesas,v3mzf", "renesas,r8a7797";
++ model = "Renesas V3MZF board based on r8a77970";
++ compatible = "renesas,v3mzf", "renesas,r8a77970";
+
+ aliases {
+ serial0 = &scif0;
+@@ -22,7 +22,6 @@
+ };
+
+ chosen {
+- bootargs = "ignore_loglevel rw root=/dev/nfs ip=dhcp";
+ stdout-path = "serial0:115200n8";
+ };
+
+@@ -87,7 +86,7 @@
+
+ port {
+ lvds_in: endpoint {
+- remote-endpoint = <&du_out_lvds0>;
++ remote-endpoint = <&lvds0_out>;
+ };
+ };
+ };
+@@ -188,15 +187,10 @@
+ };
+
+ &du {
++ clocks = <&cpg CPG_MOD 724>,
++ <&dclkin_p0>;
++ clock-names = "du.0", "dclkin.0";
+ status = "okay";
+-
+- ports {
+- port@0 {
+- endpoint {
+- remote-endpoint = <&lvds_in>;
+- };
+- };
+- };
+ };
+
+ &extal_clk {
+@@ -306,6 +300,18 @@
+ };
+ };
+
++&lvds0 {
++ status = "okay";
++
++ ports {
++ port@1 {
++ lvds0_out: endpoint {
++ remote-endpoint = <&lvds_in>;
++ };
++ };
++ };
++};
++
+ &msiof2 {
+ pinctrl-0 = <&msiof2_pins>;
+ pinctrl-names = "default";
+@@ -395,7 +401,7 @@
+ status = "okay";
+ };
+
+-&sdhi2 {
++&mmc0 {
+ /* used for on-board eMMC */
+ pinctrl-0 = <&sdhi2_pins_3v3>;
+ pinctrl-names = "default";
+@@ -437,6 +443,6 @@
+ };
+ };
+
+-&wdt0 {
++&rwdt {
+ status = "okay";
+ };
+--
+2.7.4
+
diff --git a/bsp/meta-rcar/meta-rcar-gen3-adas/recipes-kernel/linux/linux-renesas/0330-arm64-dts-renesas-Add-r8a77980-v3hsk-vbm-support.patch b/bsp/meta-rcar/meta-rcar-gen3-adas/recipes-kernel/linux/linux-renesas/0330-arm64-dts-renesas-Add-r8a77980-v3hsk-vbm-support.patch
new file mode 100644
index 00000000..d83e320f
--- /dev/null
+++ b/bsp/meta-rcar/meta-rcar-gen3-adas/recipes-kernel/linux/linux-renesas/0330-arm64-dts-renesas-Add-r8a77980-v3hsk-vbm-support.patch
@@ -0,0 +1,57 @@
+From 78e88f79266f3f8f954b308bd0274bf717a340b1 Mon Sep 17 00:00:00 2001
+From: Valentine Barshak <valentine.barshak@cogentembedded.com>
+Date: Thu, 1 Nov 2018 17:39:35 +0300
+Subject: [PATCH 150/211] arm64: dts: renesas: Add r8a77980-v3hsk-vbm support
+
+This adds r8a77980-v3hsk-vbm and r8a77980-v3hsk-vbm-v2
+device tree support.
+
+Signed-off-by: Valentine Barshak <valentine.barshak@cogentembedded.com>
+---
+ arch/arm64/boot/dts/renesas/Makefile | 2 ++
+ arch/arm64/boot/dts/renesas/r8a77980-v3hsk-vbm-v2.dts | 2 +-
+ arch/arm64/boot/dts/renesas/r8a77980-v3hsk-vbm.dts | 3 ++-
+ 3 files changed, 5 insertions(+), 2 deletions(-)
+
+diff --git a/arch/arm64/boot/dts/renesas/Makefile b/arch/arm64/boot/dts/renesas/Makefile
+index 7698983d..cac4b75 100644
+--- a/arch/arm64/boot/dts/renesas/Makefile
++++ b/arch/arm64/boot/dts/renesas/Makefile
+@@ -41,5 +41,7 @@ dtb-$(CONFIG_ARCH_R8A77970) += r8a77970-v3msk-kf.dtb r8a77970-es1-v3msk-kf.dtb
+ dtb-$(CONFIG_ARCH_R8A77970) += r8a77970-v3msk-vbm.dtb r8a77970-es1-v3msk-vbm.dtb
+ dtb-$(CONFIG_ARCH_R8A77970) += r8a77970-v3msk-vbm-v2.dtb r8a77970-es1-v3msk-vbm-v2.dtb
+ dtb-$(CONFIG_ARCH_R8A77970) += r8a77970-v3mzf.dtb
++dtb-$(CONFIG_ARCH_R8A77980) += r8a77980-v3hsk-vbm.dtb
++dtb-$(CONFIG_ARCH_R8A77980) += r8a77980-v3hsk-vbm-v2.dtb
+
+ always := $(dtb-y)
+diff --git a/arch/arm64/boot/dts/renesas/r8a77980-v3hsk-vbm-v2.dts b/arch/arm64/boot/dts/renesas/r8a77980-v3hsk-vbm-v2.dts
+index 56d4253..7a3f381 100644
+--- a/arch/arm64/boot/dts/renesas/r8a77980-v3hsk-vbm-v2.dts
++++ b/arch/arm64/boot/dts/renesas/r8a77980-v3hsk-vbm-v2.dts
+@@ -8,7 +8,7 @@
+ * kind, whether express or implied.
+ */
+
+-#include "r8a7798-v3hsk-vbm.dts"
++#include "r8a77980-v3hsk-vbm.dts"
+
+ / {
+ model = "Renesas V3HSK Videobox Mini board V2 based on r8a7798";
+diff --git a/arch/arm64/boot/dts/renesas/r8a77980-v3hsk-vbm.dts b/arch/arm64/boot/dts/renesas/r8a77980-v3hsk-vbm.dts
+index 9a54554..1b0649f 100644
+--- a/arch/arm64/boot/dts/renesas/r8a77980-v3hsk-vbm.dts
++++ b/arch/arm64/boot/dts/renesas/r8a77980-v3hsk-vbm.dts
+@@ -8,7 +8,8 @@
+ * kind, whether express or implied.
+ */
+
+-#include "r8a7798-v3hsk.dts"
++#include "r8a77980-v3hsk.dts"
++#include <dt-bindings/gpio/gpio.h>
+
+ / {
+ model = "Renesas V3HSK Videobox Mini board based on r8a7798";
+--
+2.7.4
+
diff --git a/bsp/meta-rcar/meta-rcar-gen3-adas/recipes-kernel/linux/linux-renesas/0331-arm64-dts-renesas-r8a779-7-8-0-Add-IMP-devices.patch b/bsp/meta-rcar/meta-rcar-gen3-adas/recipes-kernel/linux/linux-renesas/0331-arm64-dts-renesas-r8a779-7-8-0-Add-IMP-devices.patch
new file mode 100644
index 00000000..61bb917e
--- /dev/null
+++ b/bsp/meta-rcar/meta-rcar-gen3-adas/recipes-kernel/linux/linux-renesas/0331-arm64-dts-renesas-r8a779-7-8-0-Add-IMP-devices.patch
@@ -0,0 +1,321 @@
+From 24e14fe7c9ca79f3243694288e690780d720ca66 Mon Sep 17 00:00:00 2001
+From: Andrey Dolnikov <andrey.dolnikov@cogentembedded.com>
+Date: Sun, 4 Nov 2018 13:27:11 +0300
+Subject: [PATCH 151/211] arm64: dts: renesas: r8a779[7|8]0: Add IMP devices.
+
+---
+ arch/arm64/boot/dts/renesas/r8a77970.dtsi | 107 ++++++++++++++++++
+ arch/arm64/boot/dts/renesas/r8a77980.dtsi | 179 ++++++++++++++++++++++++++++++
+ 2 files changed, 286 insertions(+)
+
+diff --git a/arch/arm64/boot/dts/renesas/r8a77970.dtsi b/arch/arm64/boot/dts/renesas/r8a77970.dtsi
+index 2585ba5..aa4d3d6 100644
+--- a/arch/arm64/boot/dts/renesas/r8a77970.dtsi
++++ b/arch/arm64/boot/dts/renesas/r8a77970.dtsi
+@@ -861,6 +861,113 @@
+ status = "disabled";
+ };
+
++ imp_distributer: impdes0 {
++ compatible = "renesas,impx5+-distributer";
++ reg = <0 0xffa00000 0 0x10000>;
++ interrupts = <GIC_SPI 281 IRQ_TYPE_LEVEL_HIGH>;
++ clocks = <&cpg CPG_MOD 830>;
++ power-domains = <&sysc R8A77970_PD_A3IR>;
++ interrupt-controller;
++ #interrupt-cells = <1>;
++ };
++
++ imp0 {
++ compatible = "renesas,impx4-legacy";
++ reg = <0 0xff900000 0 0x20000>;
++ interrupt-parent = <&imp_distributer>;
++ interrupts = <0>;
++ clocks = <&cpg CPG_MOD 827>;
++ power-domains = <&sysc R8A77970_PD_A2IR0>;
++ };
++
++ imp1 {
++ compatible = "renesas,impx4-legacy";
++ reg = <0 0xff920000 0 0x20000>;
++ interrupt-parent = <&imp_distributer>;
++ interrupts = <1>;
++ clocks = <&cpg CPG_MOD 827>;
++ power-domains = <&sysc R8A77970_PD_A2IR0>;
++ };
++
++ imp2 {
++ compatible = "renesas,impx4-legacy";
++ reg = <0 0xff940000 0 0x20000>;
++ interrupt-parent = <&imp_distributer>;
++ interrupts = <2>;
++ clocks = <&cpg CPG_MOD 826>;
++ power-domains = <&sysc R8A77970_PD_A2IR1>;
++ };
++
++ imp3 {
++ compatible = "renesas,impx4-legacy";
++ reg = <0 0xff960000 0 0x20000>;
++ interrupt-parent = <&imp_distributer>;
++ interrupts = <3>;
++ clocks = <&cpg CPG_MOD 826>;
++ power-domains = <&sysc R8A77970_PD_A2IR1>;
++ };
++
++ impsc0 {
++ compatible = "renesas,impx4-shader";
++ reg = <0 0xff980000 0 0x10000>;
++ interrupt-parent = <&imp_distributer>;
++ interrupts = <4>;
++ clocks = <&cpg CPG_MOD 829>;
++ power-domains = <&sysc R8A77970_PD_A2SC0>;
++ };
++
++ impsc1 {
++ compatible = "renesas,impx4-shader";
++ reg = <0 0xff990000 0 0x10000>;
++ interrupt-parent = <&imp_distributer>;
++ interrupts = <5>;
++ clocks = <&cpg CPG_MOD 828>;
++ power-domains = <&sysc R8A77970_PD_A2SC1>;
++ };
++
++ impdm0 {
++ compatible = "renesas,impx5-dmac";
++ reg = <0 0xffa10000 0 0x1000>;
++ interrupt-parent = <&imp_distributer>;
++ interrupts = <6>;
++ clocks = <&cpg CPG_MOD 825>;
++ power-domains = <&sysc R8A77970_PD_A2DP>;
++ };
++
++ impdm1 {
++ compatible = "renesas,impx5-dmac";
++ reg = <0 0xffa11000 0 0x1000>;
++ interrupt-parent = <&imp_distributer>;
++ interrupts = <7>;
++ clocks = <&cpg CPG_MOD 825>;
++ power-domains = <&sysc R8A77970_PD_A2DP>;
++ };
++
++ imppsc0 {
++ compatible = "renesas,impx5+-psc";
++ reg = <0 0xffa20000 0 0x4000>;
++ interrupt-parent = <&imp_distributer>;
++ interrupts = <8>;
++ clocks = <&cpg CPG_MOD 825>;
++ power-domains = <&sysc R8A77970_PD_A2DP>;
++ };
++
++ impcnn0 {
++ compatible = "renesas,impx5+-cnn";
++ reg = <0 0xff9e0000 0 0x10000>;
++ interrupt-parent = <&imp_distributer>;
++ interrupts = <9>;
++ clocks = <&cpg CPG_MOD 824>;
++ power-domains = <&sysc R8A77970_PD_A2CN>;
++ };
++
++ impc0 {
++ compatible = "renesas,impx4-memory";
++ reg = <0 0xed000000 0 0xe0000>;
++ clocks = <&cpg CPG_MOD 830>;
++ power-domains = <&sysc R8A77970_PD_A3IR>;
++ };
++
+ imr-lx4@fe860000 {
+ compatible = "renesas,r8a77970-imr-lx4",
+ "renesas,imr-lx4";
+diff --git a/arch/arm64/boot/dts/renesas/r8a77980.dtsi b/arch/arm64/boot/dts/renesas/r8a77980.dtsi
+index 8fba9c7..87490ee 100644
+--- a/arch/arm64/boot/dts/renesas/r8a77980.dtsi
++++ b/arch/arm64/boot/dts/renesas/r8a77980.dtsi
+@@ -1034,6 +1034,185 @@
+ status = "disabled";
+ };
+
++ imp_distributer: impdes0 {
++ compatible = "renesas,impx5+-distributer";
++ reg = <0 0xffa00000 0 0x10000>;
++ interrupts = <GIC_SPI 281 IRQ_TYPE_LEVEL_HIGH>;
++ clocks = <&cpg CPG_MOD 830>;
++ power-domains = <&sysc R8A77980_PD_A3IR>;
++ interrupt-controller;
++ #interrupt-cells = <1>;
++ };
++
++ imp0 {
++ compatible = "renesas,impx4-legacy";
++ reg = <0 0xff900000 0 0x20000>;
++ interrupt-parent = <&imp_distributer>;
++ interrupts = <0>;
++ clocks = <&cpg CPG_MOD 827>;
++ power-domains = <&sysc R8A77980_PD_A2IR0>;
++ };
++
++ imp1 {
++ compatible = "renesas,impx4-legacy";
++ reg = <0 0xff920000 0 0x20000>;
++ interrupt-parent = <&imp_distributer>;
++ interrupts = <1>;
++ clocks = <&cpg CPG_MOD 826>;
++ power-domains = <&sysc R8A77980_PD_A2IR1>;
++ };
++
++ imp2 {
++ compatible = "renesas,impx4-legacy";
++ reg = <0 0xff940000 0 0x20000>;
++ interrupt-parent = <&imp_distributer>;
++ interrupts = <2>;
++ clocks = <&cpg CPG_MOD 825>;
++ power-domains = <&sysc R8A77980_PD_A2IR2>;
++ };
++
++ imp3 {
++ compatible = "renesas,impx4-legacy";
++ reg = <0 0xff960000 0 0x20000>;
++ interrupt-parent = <&imp_distributer>;
++ interrupts = <3>;
++ clocks = <&cpg CPG_MOD 824>;
++ power-domains = <&sysc R8A77980_PD_A2IR3>;
++ };
++
++ imp4 {
++ compatible = "renesas,impx4-legacy";
++ reg = <0 0xffa80000 0 0x20000>;
++ interrupt-parent = <&imp_distributer>;
++ interrupts = <4>;
++ clocks = <&cpg CPG_MOD 521>;
++ power-domains = <&sysc R8A77980_PD_A2IR4>;
++ };
++
++ impslc0 {
++ compatible = "renesas,impx4-legacy";
++ reg = <0 0xff9c0000 0 0x10000>;
++ interrupt-parent = <&imp_distributer>;
++ interrupts = <5>;
++ clocks = <&cpg CPG_MOD 500>;
++ power-domains = <&sysc R8A77980_PD_A2IR5>;
++ };
++
++ impsc0 {
++ compatible = "renesas,impx4-shader";
++ reg = <0 0xff980000 0 0x10000>;
++ interrupt-parent = <&imp_distributer>;
++ interrupts = <6>;
++ clocks = <&cpg CPG_MOD 829>;
++ power-domains = <&sysc R8A77980_PD_A2SC0>;
++ };
++
++ impsc1 {
++ compatible = "renesas,impx4-shader";
++ reg = <0 0xff990000 0 0x10000>;
++ interrupt-parent = <&imp_distributer>;
++ interrupts = <7>;
++ clocks = <&cpg CPG_MOD 828>;
++ power-domains = <&sysc R8A77980_PD_A2SC1>;
++ };
++
++ impsc2 {
++ compatible = "renesas,impx4-shader";
++ reg = <0 0xff9a0000 0 0x10000>;
++ interrupt-parent = <&imp_distributer>;
++ interrupts = <8>;
++ clocks = <&cpg CPG_MOD 531>;
++ power-domains = <&sysc R8A77980_PD_A2SC2>;
++ };
++
++ impsc3 {
++ compatible = "renesas,impx4-shader";
++ reg = <0 0xff9b0000 0 0x10000>;
++ interrupt-parent = <&imp_distributer>;
++ interrupts = <9>;
++ clocks = <&cpg CPG_MOD 529>;
++ power-domains = <&sysc R8A77980_PD_A2SC3>;
++ };
++
++ impsc4 {
++ compatible = "renesas,impx4-shader";
++ reg = <0 0xffa40000 0 0x10000>;
++ interrupt-parent = <&imp_distributer>;
++ interrupts = <10>;
++ clocks = <&cpg CPG_MOD 528>;
++ power-domains = <&sysc R8A77980_PD_A2SC4>;
++ };
++
++ impdm0 {
++ compatible = "renesas,impx5-dmac";
++ reg = <0 0xffa10000 0 0x1000>;
++ interrupt-parent = <&imp_distributer>;
++ interrupts = <11>;
++ clocks = <&cpg CPG_MOD 527>;
++ power-domains = <&sysc R8A77980_PD_A2DP0>;
++ };
++
++ impdm1 {
++ compatible = "renesas,impx5-dmac";
++ reg = <0 0xffa11000 0 0x1000>;
++ interrupt-parent = <&imp_distributer>;
++ interrupts = <12>;
++ clocks = <&cpg CPG_MOD 527>;
++ power-domains = <&sysc R8A77980_PD_A2DP0>;
++ };
++
++ impdm2 {
++ compatible = "renesas,impx5-dmac";
++ reg = <0 0xffa14000 0 0x1000>;
++ interrupt-parent = <&imp_distributer>;
++ interrupts = <13>;
++ clocks = <&cpg CPG_MOD 526>;
++ power-domains = <&sysc R8A77980_PD_A2DP1>;
++ };
++
++ impdm3 {
++ compatible = "renesas,impx5-dmac";
++ reg = <0 0xffa15000 0 0x1000>;
++ interrupt-parent = <&imp_distributer>;
++ interrupts = <14>;
++ clocks = <&cpg CPG_MOD 526>;
++ power-domains = <&sysc R8A77980_PD_A2DP1>;
++ };
++
++ imppsc0 {
++ compatible = "renesas,impx5+-psc";
++ reg = <0 0xffa20000 0 0x4000>;
++ interrupt-parent = <&imp_distributer>;
++ interrupts = <15>;
++ clocks = <&cpg CPG_MOD 525>;
++ power-domains = <&sysc R8A77980_PD_A2DP0>;
++ };
++
++ imppsc1 {
++ compatible = "renesas,impx5+-psc";
++ reg = <0 0xffa24000 0 0x4000>;
++ interrupt-parent = <&imp_distributer>;
++ interrupts = <16>;
++ clocks = <&cpg CPG_MOD 524>;
++ power-domains = <&sysc R8A77980_PD_A2DP1>;
++ };
++
++ impcnn0 {
++ compatible = "renesas,impx5+-cnn";
++ reg = <0 0xff9e0000 0 0x10000>;
++ interrupt-parent = <&imp_distributer>;
++ interrupts = <17>;
++ clocks = <&cpg CPG_MOD 831>;
++ power-domains = <&sysc R8A77980_PD_A2CN>;
++ };
++
++ impc0 {
++ compatible = "renesas,impx4-memory";
++ reg = <0 0xed000000 0 0x200000>;
++ clocks = <&cpg CPG_MOD 830>;
++ power-domains = <&sysc R8A77980_PD_A3IR>;
++ };
++
+ imr-lx4@fe860000 {
+ compatible = "renesas,r8a77980-imr-lx4",
+ "renesas,imr-lx4";
+--
+2.7.4
+
diff --git a/bsp/meta-rcar/meta-rcar-gen3-adas/recipes-kernel/linux/linux-renesas/0332-arm64-dts-renesas-r8a77980-Add-VIP-nodes.patch b/bsp/meta-rcar/meta-rcar-gen3-adas/recipes-kernel/linux/linux-renesas/0332-arm64-dts-renesas-r8a77980-Add-VIP-nodes.patch
new file mode 100644
index 00000000..a6c79aa6
--- /dev/null
+++ b/bsp/meta-rcar/meta-rcar-gen3-adas/recipes-kernel/linux/linux-renesas/0332-arm64-dts-renesas-r8a77980-Add-VIP-nodes.patch
@@ -0,0 +1,183 @@
+From a85326363b5c3f0608dcef3462b598507f405c19 Mon Sep 17 00:00:00 2001
+From: Andrey Dolnikov <andrey.dolnikov@cogentembedded.com>
+Date: Sun, 4 Nov 2018 13:30:25 +0300
+Subject: [PATCH 152/211] arm64: dts: renesas: r8a77980: Add VIP nodes.
+
+---
+ arch/arm64/boot/dts/renesas/r8a77980.dtsi | 160 ++++++++++++++++++++++++++++++
+ 1 file changed, 160 insertions(+)
+
+diff --git a/arch/arm64/boot/dts/renesas/r8a77980.dtsi b/arch/arm64/boot/dts/renesas/r8a77980.dtsi
+index 87490ee..947cf7a 100644
+--- a/arch/arm64/boot/dts/renesas/r8a77980.dtsi
++++ b/arch/arm64/boot/dts/renesas/r8a77980.dtsi
+@@ -1271,6 +1271,166 @@
+ power-domains = <&sysc R8A77980_PD_ALWAYS_ON>;
+ };
+
++ vip_disp_status {
++ compatible = "generic-uio";
++ reg = <0 0xe7a00000 0 0x10000>;
++ interrupts = <GIC_SPI 238 IRQ_TYPE_LEVEL_HIGH>;
++ clocks = <&cpg CPG_MOD 101>;
++ power-domains = <&sysc R8A77980_PD_A3VIP0>;
++ };
++
++ vip_disp_error {
++ compatible = "generic-uio";
++ reg = <0 0xe7a00000 0 0x10000>;
++ interrupts = <GIC_SPI 239 IRQ_TYPE_LEVEL_HIGH>;
++ clocks = <&cpg CPG_MOD 101>;
++ power-domains = <&sysc R8A77980_PD_A3VIP0>;
++ };
++
++ vip_umf_status {
++ compatible = "generic-uio";
++ reg = <0 0xe7a10000 0 0x10000>;
++ interrupts = <GIC_SPI 242 IRQ_TYPE_LEVEL_HIGH>;
++ clocks = <&cpg CPG_MOD 102>;
++ power-domains = <&sysc R8A77980_PD_A3VIP1>;
++ };
++
++ vip_umf_error {
++ compatible = "generic-uio";
++ reg = <0 0xe7a10000 0 0x10000>;
++ interrupts = <GIC_SPI 243 IRQ_TYPE_LEVEL_HIGH>;
++ clocks = <&cpg CPG_MOD 102>;
++ power-domains = <&sysc R8A77980_PD_A3VIP1>;
++ };
++
++ vip_smd_ps_status {
++ compatible = "generic-uio";
++ reg = <0 0xe7a20000 0 0x10000>;
++ interrupts = <GIC_SPI 112 IRQ_TYPE_LEVEL_HIGH>;
++ clocks = <&cpg CPG_MOD 1102>;
++ power-domains = <&sysc R8A77980_PD_A3VIP1>;
++ };
++
++ vip_smd_ps_error {
++ compatible = "generic-uio";
++ reg = <0 0xe7a20000 0 0x10000>;
++ interrupts = <GIC_SPI 151 IRQ_TYPE_LEVEL_HIGH>;
++ clocks = <&cpg CPG_MOD 1102>;
++ power-domains = <&sysc R8A77980_PD_A3VIP1>;
++ };
++
++ vip_smd_est_status {
++ compatible = "generic-uio";
++ reg = <0 0xe7a30000 0 0x10000>;
++ interrupts = <GIC_SPI 160 IRQ_TYPE_LEVEL_HIGH>;
++ clocks = <&cpg CPG_MOD 1101>;
++ power-domains = <&sysc R8A77980_PD_A3VIP1>;
++ };
++
++ vip_smd_est_error {
++ compatible = "generic-uio";
++ reg = <0 0xe7a30000 0 0x10000>;
++ interrupts = <GIC_SPI 164 IRQ_TYPE_LEVEL_HIGH>;
++ clocks = <&cpg CPG_MOD 1101>;
++ power-domains = <&sysc R8A77980_PD_A3VIP1>;
++ };
++
++ vip_smd_post_status {
++ compatible = "generic-uio";
++ reg = <0 0xe7a40000 0 0x10000>;
++ interrupts = <GIC_SPI 173 IRQ_TYPE_LEVEL_HIGH>;
++ clocks = <&cpg CPG_MOD 1100>;
++ power-domains = <&sysc R8A77980_PD_A3VIP1>;
++ };
++
++ vip_smd_post_error {
++ compatible = "generic-uio";
++ reg = <0 0xe7a40000 0 0x10000>;
++ interrupts = <GIC_SPI 235 IRQ_TYPE_LEVEL_HIGH>;
++ clocks = <&cpg CPG_MOD 1100>;
++ power-domains = <&sysc R8A77980_PD_A3VIP1>;
++ };
++
++ vip_cle0_status {
++ compatible = "generic-uio";
++ reg = <0 0xe7a50000 0 0x10000>;
++ interrupts = <GIC_SPI 71 IRQ_TYPE_LEVEL_HIGH>;
++ clocks = <&cpg CPG_MOD 1004>;
++ power-domains = <&sysc R8A77980_PD_A3VIP2>;
++ };
++
++ vip_cle0_error {
++ compatible = "generic-uio";
++ reg = <0 0xe7a50000 0 0x10000>;
++ interrupts = <GIC_SPI 97 IRQ_TYPE_LEVEL_HIGH>;
++ clocks = <&cpg CPG_MOD 1004>;
++ power-domains = <&sysc R8A77980_PD_A3VIP2>;
++ };
++
++ vip_cle1_status {
++ compatible = "generic-uio";
++ reg = <0 0xe7a60000 0 0x10000>;
++ interrupts = <GIC_SPI 98 IRQ_TYPE_LEVEL_HIGH>;
++ clocks = <&cpg CPG_MOD 1003>;
++ power-domains = <&sysc R8A77980_PD_A3VIP2>;
++ };
++
++ vip_cle1_error {
++ compatible = "generic-uio";
++ reg = <0 0xe7a60000 0 0x10000>;
++ interrupts = <GIC_SPI 99 IRQ_TYPE_LEVEL_HIGH>;
++ clocks = <&cpg CPG_MOD 1003>;
++ power-domains = <&sysc R8A77980_PD_A3VIP2>;
++ };
++
++ vip_cle2_status {
++ compatible = "generic-uio";
++ reg = <0 0xe7a70000 0 0x10000>;
++ interrupts = <GIC_SPI 100 IRQ_TYPE_LEVEL_HIGH>;
++ clocks = <&cpg CPG_MOD 1002>;
++ power-domains = <&sysc R8A77980_PD_A3VIP2>;
++ };
++
++ vip_cle2_error {
++ compatible = "generic-uio";
++ reg = <0 0xe7a70000 0 0x10000>;
++ interrupts = <GIC_SPI 101 IRQ_TYPE_LEVEL_HIGH>;
++ clocks = <&cpg CPG_MOD 1002>;
++ power-domains = <&sysc R8A77980_PD_A3VIP2>;
++ };
++
++ vip_cle3_status {
++ compatible = "generic-uio";
++ reg = <0 0xe7a80000 0 0x10000>;
++ interrupts = <GIC_SPI 102 IRQ_TYPE_LEVEL_HIGH>;
++ clocks = <&cpg CPG_MOD 1001>;
++ power-domains = <&sysc R8A77980_PD_A3VIP2>;
++ };
++
++ vip_cle3_error {
++ compatible = "generic-uio";
++ reg = <0 0xe7a80000 0 0x10000>;
++ interrupts = <GIC_SPI 103 IRQ_TYPE_LEVEL_HIGH>;
++ clocks = <&cpg CPG_MOD 1001>;
++ power-domains = <&sysc R8A77980_PD_A3VIP2>;
++ };
++
++ vip_cle4_status {
++ compatible = "generic-uio";
++ reg = <0 0xe7a90000 0 0x10000>;
++ interrupts = <GIC_SPI 104 IRQ_TYPE_LEVEL_HIGH>;
++ clocks = <&cpg CPG_MOD 1000>;
++ power-domains = <&sysc R8A77980_PD_A3VIP2>;
++ };
++
++ vip_cle4_error {
++ compatible = "generic-uio";
++ reg = <0 0xe7a90000 0 0x10000>;
++ interrupts = <GIC_SPI 108 IRQ_TYPE_LEVEL_HIGH>;
++ clocks = <&cpg CPG_MOD 1000>;
++ power-domains = <&sysc R8A77980_PD_A3VIP2>;
++ };
++
+ isp@fec00000 {
+ compatible = "renesas,isp-r8a77980";
+ reg = <0 0xfec00000 0 0x20000>,
+--
+2.7.4
+
diff --git a/bsp/meta-rcar/meta-rcar-gen3-adas/recipes-kernel/linux/linux-renesas/0333-arm64-dts-renesas-r8a779-78-0-Add-linux-multimedia-r.patch b/bsp/meta-rcar/meta-rcar-gen3-adas/recipes-kernel/linux/linux-renesas/0333-arm64-dts-renesas-r8a779-78-0-Add-linux-multimedia-r.patch
new file mode 100644
index 00000000..a39b0763
--- /dev/null
+++ b/bsp/meta-rcar/meta-rcar-gen3-adas/recipes-kernel/linux/linux-renesas/0333-arm64-dts-renesas-r8a779-78-0-Add-linux-multimedia-r.patch
@@ -0,0 +1,108 @@
+From 306eb2163f67cb89d492094425ec3c1e385b8b6a Mon Sep 17 00:00:00 2001
+From: Valentine Barshak <valentine.barshak@cogentembedded.com>
+Date: Mon, 5 Nov 2018 13:49:54 +0300
+Subject: [PATCH 153/211] arm64: dts: renesas: r8a779[78]0: Add
+ "linux,multimedia" region to mmngr
+
+This adds "linux,multimedia" reserved memory region to mmngr regions
+on all R-Car V3x boards which is needed for rgnmm device registration.
+
+Signed-off-by: Valentine Barshak <valentine.barshak@cogentembedded.com>
+---
+ arch/arm64/boot/dts/renesas/r8a77970-eagle.dts | 4 ++--
+ arch/arm64/boot/dts/renesas/r8a77970-v3msk.dts | 4 ++--
+ arch/arm64/boot/dts/renesas/r8a77980-condor.dts | 4 ++--
+ arch/arm64/boot/dts/renesas/r8a77980-v3hsk.dts | 4 ++--
+ 4 files changed, 8 insertions(+), 8 deletions(-)
+
+diff --git a/arch/arm64/boot/dts/renesas/r8a77970-eagle.dts b/arch/arm64/boot/dts/renesas/r8a77970-eagle.dts
+index abf5470..dd484d5 100644
+--- a/arch/arm64/boot/dts/renesas/r8a77970-eagle.dts
++++ b/arch/arm64/boot/dts/renesas/r8a77970-eagle.dts
+@@ -50,7 +50,7 @@
+ };
+
+ /* device specific region for contiguous allocations */
+- linux,multimedia {
++ mmp_reserved: linux,multimedia {
+ compatible = "shared-dma-pool";
+ reusable;
+ reg = <0x00000000 0x7f000000 0x0 0x01000000>;
+@@ -59,7 +59,7 @@
+
+ mmngr {
+ compatible = "renesas,mmngr";
+- memory-region = <&lossy_decompress>;
++ memory-region = <&mmp_reserved>, <&lossy_decompress>;
+ };
+
+ mmngrbuf {
+diff --git a/arch/arm64/boot/dts/renesas/r8a77970-v3msk.dts b/arch/arm64/boot/dts/renesas/r8a77970-v3msk.dts
+index 6847381..4cc11c9 100644
+--- a/arch/arm64/boot/dts/renesas/r8a77970-v3msk.dts
++++ b/arch/arm64/boot/dts/renesas/r8a77970-v3msk.dts
+@@ -47,7 +47,7 @@
+ };
+
+ /* device specific region for contiguous allocations */
+- linux,multimedia {
++ mmp_reserved: linux,multimedia {
+ compatible = "shared-dma-pool";
+ reusable;
+ reg = <0x00000000 0x7f000000 0x0 0x01000000>;
+@@ -56,7 +56,7 @@
+
+ mmngr {
+ compatible = "renesas,mmngr";
+- memory-region = <&lossy_decompress>;
++ memory-region = <&mmp_reserved>, <&lossy_decompress>;
+ };
+
+ mmngrbuf {
+diff --git a/arch/arm64/boot/dts/renesas/r8a77980-condor.dts b/arch/arm64/boot/dts/renesas/r8a77980-condor.dts
+index 5bd0640..f3b7ebe 100644
+--- a/arch/arm64/boot/dts/renesas/r8a77980-condor.dts
++++ b/arch/arm64/boot/dts/renesas/r8a77980-condor.dts
+@@ -50,7 +50,7 @@
+ };
+
+ /* device specific region for contiguous allocations */
+- linux,multimedia {
++ mmp_reserved: linux,multimedia {
+ compatible = "shared-dma-pool";
+ reusable;
+ reg = <0x00000000 0x7f000000 0x0 0x01000000>;
+@@ -59,7 +59,7 @@
+
+ mmngr {
+ compatible = "renesas,mmngr";
+- memory-region = <&lossy_decompress>;
++ memory-region = <&mmp_reserved>, <&lossy_decompress>;
+ };
+
+ mmngrbuf {
+diff --git a/arch/arm64/boot/dts/renesas/r8a77980-v3hsk.dts b/arch/arm64/boot/dts/renesas/r8a77980-v3hsk.dts
+index 51607d4..549ca5e 100644
+--- a/arch/arm64/boot/dts/renesas/r8a77980-v3hsk.dts
++++ b/arch/arm64/boot/dts/renesas/r8a77980-v3hsk.dts
+@@ -48,7 +48,7 @@
+ };
+
+ /* device specific region for contiguous allocations */
+- linux,multimedia {
++ mmp_reserved: linux,multimedia {
+ compatible = "shared-dma-pool";
+ reusable;
+ reg = <0x00000000 0x7f000000 0x0 0x01000000>;
+@@ -57,7 +57,7 @@
+
+ mmngr {
+ compatible = "renesas,mmngr";
+- memory-region = <&lossy_decompress>;
++ memory-region = <&mmp_reserved>, <&lossy_decompress>;
+ };
+
+ mmngrbuf {
+--
+2.7.4
+
diff --git a/bsp/meta-rcar/meta-rcar-gen3-adas/recipes-kernel/linux/linux-renesas/0334-IMR-UIO-Driver-initial-version.patch b/bsp/meta-rcar/meta-rcar-gen3-adas/recipes-kernel/linux/linux-renesas/0334-IMR-UIO-Driver-initial-version.patch
new file mode 100644
index 00000000..0abfefe3
--- /dev/null
+++ b/bsp/meta-rcar/meta-rcar-gen3-adas/recipes-kernel/linux/linux-renesas/0334-IMR-UIO-Driver-initial-version.patch
@@ -0,0 +1,816 @@
+From 4388b872be8d3b0d13c804d3cdb8ec9a4ddd5a97 Mon Sep 17 00:00:00 2001
+From: Andrey Dolnikov <andrey.dolnikov@cogentembedded.com>
+Date: Mon, 5 Nov 2018 23:01:21 +0300
+Subject: [PATCH 154/211] IMR UIO Driver initial version
+
+Signed-off-by: Toshiya Tamaki <toshiya.tamaki.ue@renesas.com>
+---
+ .../devicetree/bindings/imr/renesas,imr.txt | 55 +++
+ arch/arm64/boot/dts/renesas/r8a7795.dtsi | 16 +-
+ arch/arm64/boot/dts/renesas/r8a7796.dtsi | 8 +-
+ arch/arm64/boot/dts/renesas/r8a77970.dtsi | 16 +-
+ arch/arm64/boot/dts/renesas/r8a77980.dtsi | 20 +-
+ drivers/uio/Kconfig | 9 +
+ drivers/uio/Makefile | 1 +
+ drivers/uio/uio_imr.c | 495 +++++++++++++++++++++
+ 8 files changed, 590 insertions(+), 30 deletions(-)
+ create mode 100644 Documentation/devicetree/bindings/imr/renesas,imr.txt
+ create mode 100644 drivers/uio/uio_imr.c
+
+diff --git a/Documentation/devicetree/bindings/imr/renesas,imr.txt b/Documentation/devicetree/bindings/imr/renesas,imr.txt
+new file mode 100644
+index 0000000..4d5454a
+--- /dev/null
++++ b/Documentation/devicetree/bindings/imr/renesas,imr.txt
+@@ -0,0 +1,55 @@
++* Renesas Electronics IMR
++
++This file provides information on what the device node for the IMR
++interface contains.
++
++Required properties:
++- compatible: "renesas,r8a7795-imr-lx4" if the device is a part of R8A7795 SoC.
++ "renesas,r8a7796-imr-lx4" if the device is a part of R8A7796 SoC.
++ "renesas,r8a77970-imr-lx4" if the device is a part of R8A7797 SoC.
++
++ When compatible with the generic version, nodes must list the
++ SoC-specific version corresponding to the platform first
++ followed by the generic version.
++
++- reg: offset and length of (1) the register block and (2) the stream buffer.
++- interrupts: A list of interrupt-specifiers, one for each entry in
++ interrupt-names.
++ If interrupt-names is not present, an interrupt specifier
++ for a single muxed interrupt.
++- clocks: clock phandle and specifier pair.
++- power-domains: must contain a reference to the PM domain.
++
++Example:
++
++ imr0{
++ compatible = "renesas,r8a77970-imr-lx4";
++ reg = <0 0xfe860000 0 0x10000>;
++ interrupts = <GIC_SPI 192 IRQ_TYPE_LEVEL_HIGH>;
++ clocks = <&cpg CPG_MOD 823>;
++ power-domains = <&sysc R8A7797_PD_A3VC>;
++ };
++
++ imr1{
++ compatible = "renesas,r8a77970-imr-lx4";
++ reg = <0 0xfe870000 0 0x10000>;
++ interrupts = <GIC_SPI 193 IRQ_TYPE_LEVEL_HIGH>;
++ clocks = <&cpg CPG_MOD 822>;
++ power-domains = <&sysc R8A7797_PD_A3VC>;
++ };
++
++ imr2{
++ compatible = "renesas,r8a77970-imr-lx4";
++ reg = <0 0xfe880000 0 0x10000>;
++ interrupts = <GIC_SPI 194 IRQ_TYPE_LEVEL_HIGH>;
++ clocks = <&cpg CPG_MOD 821>;
++ power-domains = <&sysc R8A7797_PD_A3VC>;
++ };
++
++ imr3{
++ compatible = "renesas,r8a77970-imr-lx4";
++ reg = <0 0xfe890000 0 0x10000>;
++ interrupts = <GIC_SPI 195 IRQ_TYPE_LEVEL_HIGH>;
++ clocks = <&cpg CPG_MOD 820>;
++ power-domains = <&sysc R8A7797_PD_A3VC>;
++ };
+diff --git a/arch/arm64/boot/dts/renesas/r8a7795.dtsi b/arch/arm64/boot/dts/renesas/r8a7795.dtsi
+index 536deef..e749633 100644
+--- a/arch/arm64/boot/dts/renesas/r8a7795.dtsi
++++ b/arch/arm64/boot/dts/renesas/r8a7795.dtsi
+@@ -2785,40 +2785,40 @@
+ status = "disabled";
+ };
+
+- imr-lx4@fe860000 {
++ imrlx4_ch0: imr0@fe860000 {
+ compatible = "renesas,r8a7795-imr-lx4",
+ "renesas,imr-lx4";
+- reg = <0 0xfe860000 0 0x2000>;
++ reg = <0 0xfe860000 0 0x10000>;
+ interrupts = <GIC_SPI 192 IRQ_TYPE_LEVEL_HIGH>;
+ clocks = <&cpg CPG_MOD 823>;
+ power-domains = <&sysc R8A7795_PD_A3VC>;
+ resets = <&cpg 823>;
+ };
+
+- imr-lx4@fe870000 {
++ imrlx4_ch1: imr1@fe870000 {
+ compatible = "renesas,r8a7795-imr-lx4",
+ "renesas,imr-lx4";
+- reg = <0 0xfe870000 0 0x2000>;
++ reg = <0 0xfe870000 0 0x10000>;
+ interrupts = <GIC_SPI 193 IRQ_TYPE_LEVEL_HIGH>;
+ clocks = <&cpg CPG_MOD 822>;
+ power-domains = <&sysc R8A7795_PD_A3VC>;
+ resets = <&cpg 822>;
+ };
+
+- imr-lx4@fe880000 {
++ imrlx4_ch2: imr2@fe880000 {
+ compatible = "renesas,r8a7795-imr-lx4",
+ "renesas,imr-lx4";
+- reg = <0 0xfe880000 0 0x2000>;
++ reg = <0 0xfe880000 0 0x10000>;
+ interrupts = <GIC_SPI 194 IRQ_TYPE_LEVEL_HIGH>;
+ clocks = <&cpg CPG_MOD 821>;
+ power-domains = <&sysc R8A7795_PD_A3VC>;
+ resets = <&cpg 821>;
+ };
+
+- imr-lx4@fe890000 {
++ imrlx4_ch3: imr3@fe890000 {
+ compatible = "renesas,r8a7795-imr-lx4",
+ "renesas,imr-lx4";
+- reg = <0 0xfe890000 0 0x2000>;
++ reg = <0 0xfe890000 0 0x10000>;
+ interrupts = <GIC_SPI 195 IRQ_TYPE_LEVEL_HIGH>;
+ clocks = <&cpg CPG_MOD 820>;
+ power-domains = <&sysc R8A7795_PD_A3VC>;
+diff --git a/arch/arm64/boot/dts/renesas/r8a7796.dtsi b/arch/arm64/boot/dts/renesas/r8a7796.dtsi
+index 383639b..49068a8 100644
+--- a/arch/arm64/boot/dts/renesas/r8a7796.dtsi
++++ b/arch/arm64/boot/dts/renesas/r8a7796.dtsi
+@@ -2618,20 +2618,20 @@
+ status = "disabled";
+ };
+
+- imr-lx4@fe860000 {
++ imrlx4_ch0: imr0@fe860000 {
+ compatible = "renesas,r8a7796-imr-lx4",
+ "renesas,imr-lx4";
+- reg = <0 0xfe860000 0 0x2000>;
++ reg = <0 0xfe860000 0 0x10000>;
+ interrupts = <GIC_SPI 192 IRQ_TYPE_LEVEL_HIGH>;
+ clocks = <&cpg CPG_MOD 823>;
+ power-domains = <&sysc R8A7796_PD_A3VC>;
+ resets = <&cpg 823>;
+ };
+
+- imr-lx4@fe870000 {
++ imrlx4_ch1: imr1@fe870000 {
+ compatible = "renesas,r8a7796-imr-lx4",
+ "renesas,imr-lx4";
+- reg = <0 0xfe870000 0 0x2000>;
++ reg = <0 0xfe870000 0 0x10000>;
+ interrupts = <GIC_SPI 193 IRQ_TYPE_LEVEL_HIGH>;
+ clocks = <&cpg CPG_MOD 822>;
+ power-domains = <&sysc R8A7796_PD_A3VC>;
+diff --git a/arch/arm64/boot/dts/renesas/r8a77970.dtsi b/arch/arm64/boot/dts/renesas/r8a77970.dtsi
+index aa4d3d6..40e28338 100644
+--- a/arch/arm64/boot/dts/renesas/r8a77970.dtsi
++++ b/arch/arm64/boot/dts/renesas/r8a77970.dtsi
+@@ -968,40 +968,40 @@
+ power-domains = <&sysc R8A77970_PD_A3IR>;
+ };
+
+- imr-lx4@fe860000 {
++ imrlx4_ch0: imr0@fe860000 {
+ compatible = "renesas,r8a77970-imr-lx4",
+ "renesas,imr-lx4";
+- reg = <0 0xfe860000 0 0x2000>;
++ reg = <0 0xfe860000 0 0x10000>;
+ interrupts = <GIC_SPI 192 IRQ_TYPE_LEVEL_HIGH>;
+ clocks = <&cpg CPG_MOD 823>;
+ power-domains = <&sysc R8A77970_PD_ALWAYS_ON>;
+ resets = <&cpg 823>;
+ };
+
+- imr-lx4@fe870000 {
++ imrlx4_ch1: imr1@fe870000 {
+ compatible = "renesas,r8a77970-imr-lx4",
+ "renesas,imr-lx4";
+- reg = <0 0xfe870000 0 0x2000>;
++ reg = <0 0xfe870000 0 0x10000>;
+ interrupts = <GIC_SPI 193 IRQ_TYPE_LEVEL_HIGH>;
+ clocks = <&cpg CPG_MOD 822>;
+ power-domains = <&sysc R8A77970_PD_ALWAYS_ON>;
+ resets = <&cpg 822>;
+ };
+
+- imr-lx4@fe880000 {
++ imrlx4_ch2: imr2@fe880000 {
+ compatible = "renesas,r8a77970-imr-lx4",
+ "renesas,imr-lx4";
+- reg = <0 0xfe880000 0 0x2000>;
++ reg = <0 0xfe880000 0 0x10000>;
+ interrupts = <GIC_SPI 194 IRQ_TYPE_LEVEL_HIGH>;
+ clocks = <&cpg CPG_MOD 821>;
+ power-domains = <&sysc R8A77970_PD_ALWAYS_ON>;
+ resets = <&cpg 821>;
+ };
+
+- imr-lx4@fe890000 {
++ imrlx4_ch3: imr3@fe890000 {
+ compatible = "renesas,r8a77970-imr-lx4",
+ "renesas,imr-lx4";
+- reg = <0 0xfe890000 0 0x2000>;
++ reg = <0 0xfe890000 0 0x10000>;
+ interrupts = <GIC_SPI 195 IRQ_TYPE_LEVEL_HIGH>;
+ clocks = <&cpg CPG_MOD 820>;
+ power-domains = <&sysc R8A77970_PD_ALWAYS_ON>;
+diff --git a/arch/arm64/boot/dts/renesas/r8a77980.dtsi b/arch/arm64/boot/dts/renesas/r8a77980.dtsi
+index 947cf7a..302b346 100644
+--- a/arch/arm64/boot/dts/renesas/r8a77980.dtsi
++++ b/arch/arm64/boot/dts/renesas/r8a77980.dtsi
+@@ -1213,47 +1213,47 @@
+ power-domains = <&sysc R8A77980_PD_A3IR>;
+ };
+
+- imr-lx4@fe860000 {
++ imrlx4_ch0: imr0@fe860000 {
+ compatible = "renesas,r8a77980-imr-lx4",
+ "renesas,imr-lx4";
+- reg = <0 0xfe860000 0 0x2000>;
++ reg = <0 0xfe860000 0 0x10000>;
+ interrupts = <GIC_SPI 192 IRQ_TYPE_LEVEL_HIGH>;
+ clocks = <&cpg CPG_MOD 823>;
+ power-domains = <&sysc R8A77980_PD_ALWAYS_ON>;
+ resets = <&cpg 823>;
+ };
+
+- imr-lx4@fe870000 {
++ imrlx4_ch1: imr1@fe870000 {
+ compatible = "renesas,r8a77980-imr-lx4",
+ "renesas,imr-lx4";
+- reg = <0 0xfe870000 0 0x2000>;
++ reg = <0 0xfe870000 0 0x10000>;
+ interrupts = <GIC_SPI 193 IRQ_TYPE_LEVEL_HIGH>;
+ clocks = <&cpg CPG_MOD 822>;
+ power-domains = <&sysc R8A77980_PD_ALWAYS_ON>;
+ resets = <&cpg 822>;
+ };
+
+- imr-lx4@fe880000 {
++ imrlx4_ch2: imr2@fe880000 {
+ compatible = "renesas,r8a77980-imr-lx4",
+ "renesas,imr-lx4";
+- reg = <0 0xfe880000 0 0x2000>;
++ reg = <0 0xfe880000 0 0x10000>;
+ interrupts = <GIC_SPI 194 IRQ_TYPE_LEVEL_HIGH>;
+ clocks = <&cpg CPG_MOD 821>;
+ power-domains = <&sysc R8A77980_PD_ALWAYS_ON>;
+ resets = <&cpg 821>;
+ };
+
+- imr-lx4@fe890000 {
++ imrlx4_ch3: imr3@fe890000 {
+ compatible = "renesas,r8a77980-imr-lx4",
+ "renesas,imr-lx4";
+- reg = <0 0xfe890000 0 0x2000>;
++ reg = <0 0xfe890000 0 0x10000>;
+ interrupts = <GIC_SPI 195 IRQ_TYPE_LEVEL_HIGH>;
+ clocks = <&cpg CPG_MOD 820>;
+ power-domains = <&sysc R8A77980_PD_ALWAYS_ON>;
+ resets = <&cpg 820>;
+ };
+
+- imr4@fe8a0000 {
++ imrlx4_ch4: imr4@fe8a0000 {
+ compatible = "renesas,r8a77980-imr-lx4",
+ "renesas,imr-lx4";
+ reg = <0 0xfe8a0000 0 0x10000>;
+@@ -1262,7 +1262,7 @@
+ power-domains = <&sysc R8A77980_PD_ALWAYS_ON>;
+ };
+
+- imr5@fe8b0000 {
++ imrlx4_ch5: imr5@fe8b0000 {
+ compatible = "renesas,r8a77980-imr-lx4",
+ "renesas,imr-lx4";
+ reg = <0 0xfe8b0000 0 0x10000>;
+diff --git a/drivers/uio/Kconfig b/drivers/uio/Kconfig
+index 7e8dc78..46cd4b1 100644
+--- a/drivers/uio/Kconfig
++++ b/drivers/uio/Kconfig
+@@ -164,4 +164,13 @@ config UIO_HV_GENERIC
+ to network and storage devices from userspace.
+
+ If you compile this as a module, it will be called uio_hv_generic.
++
++config UIO_IMR
++ tristate "Renesas IMR support"
++
++ help
++ Renesas IMR device driver.
++ This driver supports the following SoCs:
++ - R8A7795, R8A7796, R8A77970, R8A77980.
++
+ endif
+diff --git a/drivers/uio/Makefile b/drivers/uio/Makefile
+index c285dd2..4ab2039 100644
+--- a/drivers/uio/Makefile
++++ b/drivers/uio/Makefile
+@@ -11,3 +11,4 @@ obj-$(CONFIG_UIO_PRUSS) += uio_pruss.o
+ obj-$(CONFIG_UIO_MF624) += uio_mf624.o
+ obj-$(CONFIG_UIO_FSL_ELBC_GPCM) += uio_fsl_elbc_gpcm.o
+ obj-$(CONFIG_UIO_HV_GENERIC) += uio_hv_generic.o
++obj-$(CONFIG_UIO_IMR) += uio_imr.o
+diff --git a/drivers/uio/uio_imr.c b/drivers/uio/uio_imr.c
+new file mode 100644
+index 0000000..a1ba788
+--- /dev/null
++++ b/drivers/uio/uio_imr.c
+@@ -0,0 +1,495 @@
++/*************************************************************************/ /*
++ IMR
++
++ Copyright (C) 2015-2017 Renesas Electronics Corporation
++
++ License Dual MIT/GPLv2
++
++ The contents of this file are subject to the MIT license as set out below.
++
++ Permission is hereby granted, free of charge, to any person obtaining a copy
++ of this software and associated documentation files (the "Software"), to deal
++ in the Software without restriction, including without limitation the rights
++ to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
++ copies of the Software, and to permit persons to whom the Software is
++ furnished to do so, subject to the following conditions:
++
++ The above copyright notice and this permission notice shall be included in
++ all copies or substantial portions of the Software.
++
++ Alternatively, the contents of this file may be used under the terms of
++ the GNU General Public License Version 2 ("GPL") in which case the provisions
++ of GPL are applicable instead of those above.
++
++ If you wish to allow use of your version of this file only under the terms of
++ GPL, and not to allow others to use your version of this file under the terms
++ of the MIT license, indicate your decision by deleting the provisions above
++ and replace them with the notice and other provisions required by GPL as set
++ out in the file called "GPL-COPYING" included in this distribution. If you do
++ not delete the provisions above, a recipient may use your version of this file
++ under the terms of either the MIT license or GPL.
++
++ This License is also included in this distribution in the file called
++ "MIT-COPYING".
++
++ EXCEPT AS OTHERWISE STATED IN A NEGOTIATED AGREEMENT: (A) THE SOFTWARE IS
++ PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING
++ BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR
++ PURPOSE AND NONINFRINGEMENT; AND (B) IN NO EVENT SHALL THE AUTHORS OR
++ COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER
++ IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
++ CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
++
++
++ GPLv2:
++ If you wish to use this file under the terms of GPL, following terms are
++ effective.
++
++ This program is free software; you can redistribute it and/or modify
++ it under the terms of the GNU General Public License as published by
++ the Free Software Foundation; version 2 of the License.
++
++ This program is distributed in the hope that it will be useful,
++ but WITHOUT ANY WARRANTY; without even the implied warranty of
++ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
++ GNU General Public License for more details.
++
++ You should have received a copy of the GNU General Public License
++ along with this program; if not, write to the Free Software
++ Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
++*/ /*************************************************************************/
++
++/* PRQA S 292,2212,2214 EOF */
++#include <linux/platform_device.h>
++#include <linux/uio_driver.h>
++#include <linux/interrupt.h>
++#include <linux/pm_runtime.h>
++#include <linux/slab.h>
++#include <linux/clk.h>
++#include <linux/io.h>
++#include <linux/module.h>
++
++#include <linux/of.h>
++#include <linux/of_irq.h>
++
++/* IMR uio driver name */
++#define DRIVER_NAME "uio_imr"
++
++/* IMR register definition */
++#define IMR_REG_IMR_ADDRESS (0x018U)
++#define IMR_REG_IMR_BIT_BASE (0x3U << 3)
++#define IMR_REG_IMR_BIT_INT (0x1U << 2)
++#define IMR_REG_IMR_BIT_IER (0x1U << 1)
++#define IMR_REG_IMR_BIT_TRA (0x1U << 0)
++
++/**
++ * struct uio_platdata - the uio platform data structure
++ * @uioinfo: UIO device capabilities
++ * @lock lock flag for irq.
++ * @flags: flags for request_irq.
++ * @pdev: IMR platform device data.
++ * @base_reg: IMR base register address.
++ * @clk: clock data.
++ *
++ * the uio platform data structure.
++ */
++struct uio_platdata {
++ struct uio_info *uioinfo;
++ spinlock_t lock;
++ unsigned long flags;
++ struct platform_device *pdev;
++ void __iomem *base_reg;
++ struct clk *clock;
++};
++
++static void write_register(struct uio_platdata *priv,
++ u32 reg_offs, u32 data);
++static int uio_imr_open(struct uio_info *info,
++ __attribute__((unused)) struct inode *inode);
++static int uio_imr_release(struct uio_info *info,
++ __attribute__((unused)) struct inode *inode);
++static irqreturn_t uio_imr_handler(__attribute__((unused)) int irq,
++ struct uio_info *dev_info);
++static int uio_imr_irqcontrol(struct uio_info *info, s32 irq_on);
++static int uio_imr_probe(struct platform_device *pdev);
++static int uio_imr_remove(struct platform_device *pdev);
++static int uio_runtime_imr_nop(__attribute__((unused)) struct device *dev);
++
++/**
++ * write_register() - register setting
++ * @priv: uio platform data.
++ * @reg_offs: register offset.
++ * @data: register value.
++ *
++ * register setting.
++ *
++ *
++ * Return: none
++ */
++static void write_register(struct uio_platdata *priv,
++ u32 reg_offs, u32 data)
++{
++ iowrite32(data, (u8 *)priv->base_reg + reg_offs); /* PRQA S 488 */
++}
++
++/**
++ * uio_imr_open() - open imr module
++ * @info: UIO device capabilities.
++ * @inode: inode.
++ *
++ * Open imr module.
++ *
++ *
++ * Return: 0 normal end.
++ */
++/* PRQA S 3206 2 */
++static int uio_imr_open(struct uio_info *info,
++ __attribute__((unused)) struct inode *inode)
++{
++ struct uio_platdata *pdata = info->priv;
++ /* PRQA S 3200 1 */
++ pr_debug("uio_imr_open enter. name=%s\n", pdata->uioinfo->name);
++
++ /* Wait until the Runtime PM code has woken up the device */
++ (void)pm_runtime_get_sync(&pdata->pdev->dev);
++
++ return 0;
++}
++
++/**
++ * uio_imr_release() - close imr module
++ * @info: UIO device capabilities.
++ * @inode: inode.
++ *
++ * Close imr module.
++ *
++ *
++ * Return: 0 normal end.
++ */
++/* PRQA S 3206 2 */
++static int uio_imr_release(struct uio_info *info,
++ __attribute__((unused)) struct inode *inode)
++{
++ struct uio_platdata *pdata = info->priv;
++
++ pr_debug("uio_imr_release enter\n"); /* PRQA S 3200 */
++
++ /* Tell the Runtime PM code that the device has become idle */
++ (void)pm_runtime_put_sync(&pdata->pdev->dev);
++
++ return 0;
++}
++
++/**
++ * uio_imr_handler() - IMR interrupt handler
++ * @irq: irq No.
++ * @dev_info: UIO device capabilities.
++ *
++ * IMR interrupt handler.
++ *
++ *
++ * Return: IRQ_HANDLED normal end.
++ */
++/* PRQA S 3206 1*/
++static irqreturn_t uio_imr_handler(__attribute__((unused))int irq,
++ struct uio_info *dev_info)
++{
++ struct uio_platdata *pdata = dev_info->priv;
++
++
++ pr_debug("uio_imr_handler enter\n"); /* PRQA S 3200 */
++
++ /* Mask interrupt */
++ write_register(pdata, IMR_REG_IMR_ADDRESS,
++ IMR_REG_IMR_BIT_BASE | (IMR_REG_IMR_BIT_INT |
++ IMR_REG_IMR_BIT_IER | IMR_REG_IMR_BIT_TRA));
++
++ return IRQ_HANDLED;
++}
++
++/**
++ * uio_imr_irqcontrol() - IMR irq controller
++ * @info: UIO device capabilities.
++ * @irq_on: irq enable/disable.
++ *
++ * IMR irq controller. Enable and disable the interrupt.
++ *
++ *
++ * Return: 0 normal end.
++ */
++static int uio_imr_irqcontrol(struct uio_info *info, s32 irq_on)
++{
++ struct uio_platdata *pdata = info->priv;
++ u64 flag;
++
++ pr_debug("uio_imr_irqcontrol enter\n"); /* PRQA S 3200 */
++
++ spin_lock_irqsave(&pdata->lock, flag);
++ if (irq_on != 0) {
++ if (test_and_clear_bit(0, &pdata->flags) != 0)
++ enable_irq((u32)info->irq);
++ } else {
++ if (test_and_set_bit(0, &pdata->flags) == 0)
++ disable_irq((u32)info->irq);
++ }
++ spin_unlock_irqrestore(&pdata->lock, flag);
++
++ return 0;
++}
++
++/* PRQA S 1053,1041,605 10 */
++static const struct of_device_id rcar_imr_dt_ids[] = {
++ { .compatible = "renesas,r8a7795-imr-lx4", .data = 0 },
++ { .compatible = "renesas,r8a7796-imr-lx4", .data = 0 },
++ { .compatible = "renesas,r8a77970-imr-lx4", .data = 0 },
++ { .compatible = "renesas,r8a77980-imr-lx4", .data = 0 },
++ {},
++};
++MODULE_DEVICE_TABLE(of, rcar_imr_dt_ids); /* PRQA S 605 */
++
++/**
++ * uio_imr_probe() - Initialize IMR module.
++ * @pdev: platform device data.
++ *
++ * Initialize IMR module.
++ *
++ *
++ * Return: 0 normal end.
++ * -EINVAL parameter error.
++ * -ENOMEM memory error.
++ * -ENODEV system error.
++ */
++static int uio_imr_probe(struct platform_device *pdev)
++{
++ struct uio_info *uioinfo_data = NULL;
++ struct uio_platdata *pdata;
++ struct uio_mem *uiomem;
++ int ret = 0;
++ unsigned int i;
++ struct resource *rsc;
++ unsigned int irq_l;
++ unsigned long remap_size;
++
++ if (pdev == NULL) {
++ pr_err("missing pdev\n");
++ ret = -EINVAL;
++ } else {
++ if (pdev->dev.of_node == NULL) {
++ dev_err(&pdev->dev, "missing pdev->dev.of_node\n");
++ ret = -EINVAL;
++ }
++ }
++
++ if (ret == 0) {
++ pr_debug("uio_imr_probe enter name = %s\n", /* PRQA S 3200 */
++ pdev->dev.of_node->name);
++
++ uioinfo_data = devm_kzalloc(&pdev->dev,
++ sizeof(*uioinfo_data),
++ GFP_KERNEL);
++ if (uioinfo_data == NULL)
++ ret = -ENOMEM;
++ }
++
++ if (ret == 0) {
++ uioinfo_data->name = pdev->dev.of_node->name;
++ uioinfo_data->version = "0.1";
++
++ /* get irq number */
++ irq_l = irq_of_parse_and_map(pdev->dev.of_node, 0);
++ if ((int)irq_l == -ENXIO)
++ uioinfo_data->irq = platform_get_irq(pdev, 0);
++ else
++ uioinfo_data->irq = (int)irq_l;
++
++ pdata = devm_kzalloc(&pdev->dev, sizeof(*pdata), GFP_KERNEL);
++ if (pdata == NULL)
++ ret = -ENOMEM;
++ }
++
++ if (ret == 0) {
++ pdata->uioinfo = uioinfo_data;
++ spin_lock_init(&pdata->lock); /* PRQA S 3200 */
++ pdata->flags = 0;
++ pdata->pdev = pdev;
++
++ uiomem = &uioinfo_data->mem[0];
++
++ for (i = 0; i < pdev->num_resources; ++i) {
++ /* PRQA S 491 1 */
++ struct resource *r = &pdev->resource[i];
++
++ if (r->flags == IORESOURCE_IRQ) {
++ uioinfo_data->irq = (long)r->start;
++ } else if (r->flags != IORESOURCE_MEM) {
++ ;
++ } else {
++ if (uiomem >=
++ &uioinfo_data->mem[MAX_UIO_MAPS]) {
++ dev_warn(&pdev->dev,
++ "device has more than "
++ __stringify(MAX_UIO_MAPS)
++ " I/O memory resources.\n");
++ break;
++ }
++
++ uiomem->memtype = UIO_MEM_PHYS;
++ uiomem->addr = r->start;
++ uiomem->size = (r->end - r->start) + 1;
++ ++uiomem; /* PRQA S 489 */
++ }
++ }
++
++ while (uiomem < &uioinfo_data->mem[MAX_UIO_MAPS]) {
++ uiomem->size = 0;
++ ++uiomem; /* PRQA S 489 */
++ }
++
++ uioinfo_data->handler = &uio_imr_handler;
++ uioinfo_data->irqcontrol = &uio_imr_irqcontrol;
++ uioinfo_data->open = &uio_imr_open;
++ uioinfo_data->release = &uio_imr_release;
++ uioinfo_data->priv = pdata;
++
++ pm_runtime_enable(&pdev->dev);
++
++ ret = uio_register_device(&pdev->dev, pdata->uioinfo);
++ if (ret != 0) {
++ pm_runtime_disable(&pdev->dev);
++ dev_err(&pdev->dev, "could not register uio device\n");
++ ret = -ENODEV;
++ }
++ }
++
++ if (ret == 0) {
++ platform_set_drvdata(pdev, pdata);
++ pdata->clock = devm_clk_get(&pdev->dev, NULL);
++ if (IS_ERR(pdata->clock)) {
++ pm_runtime_disable(&pdev->dev);
++ dev_err(&pdev->dev, "could not get clock\n");
++ ret = -ENODEV;
++ } else {
++ /* clock enable */
++ (void)clk_prepare_enable(pdata->clock);
++ }
++ }
++
++ if (ret == 0) {
++ rsc = platform_get_resource(pdev, IORESOURCE_MEM, 0);
++ if (rsc == 0) {
++ pm_runtime_disable(&pdev->dev);
++ dev_err(&pdev->dev, "could not platform_get_resource\n");
++ ret = -ENODEV;
++ }
++ }
++
++ if (ret == 0) {
++ remap_size = (rsc->end - rsc->start) + 1;
++ if (!request_mem_region(rsc->start,
++ remap_size,
++ uioinfo_data->name)) {
++ dev_err(&pdev->dev, "could not request IO\n");
++ pm_runtime_disable(&pdev->dev);
++ ret = -ENOMEM;
++ }
++ }
++
++ if (ret == 0) {
++ /* IMR Register Adderss */
++ pdata->base_reg = devm_ioremap_nocache(&pdev->dev,
++ rsc->start,
++ remap_size);
++ if (pdata->base_reg == NULL) {
++ release_mem_region(rsc->start, resource_size(rsc));
++ dev_err(&pdev->dev, "could not remap IMR register\n");
++ pm_runtime_disable(&pdev->dev);
++ ret = -ENOMEM;
++ } else {
++ /* PRQA S 3200 2 */
++ pr_debug("IMR reg_base = %x size = %x\n",
++ (uint32_t)(rsc->start), (uint32_t)remap_size);
++ }
++ }
++
++ return ret;
++}
++
++/**
++ * uio_imr_remove() - release IMR module.
++ * @pdev: platform device data.
++ *
++ * release IMR module.
++ *
++ *
++ * Return: 0 normal end.
++ */
++static int uio_imr_remove(struct platform_device *pdev)
++{
++ struct resource *rsc;
++ struct uio_platdata *pdata = platform_get_drvdata(pdev);
++
++ /* PRQA S 3200 1 */
++ pr_debug("uio_imr_remove enter name = %s\n", pdata->uioinfo->name);
++
++ clk_disable_unprepare(pdata->clock);
++
++ uio_unregister_device(pdata->uioinfo);
++
++ pm_runtime_disable(&pdev->dev);
++
++ irq_dispose_mapping((u32)pdata->uioinfo->irq);
++
++ pdata->uioinfo->handler = NULL;
++ pdata->uioinfo->irqcontrol = NULL;
++
++ platform_set_drvdata(pdev, NULL);
++
++ if (pdata->base_reg != NULL)
++ devm_iounmap(&pdev->dev, pdata->base_reg);
++
++ rsc = platform_get_resource(pdev, IORESOURCE_MEM, 0);
++ if (rsc != 0)
++ release_mem_region(rsc->start, resource_size(rsc));
++
++ return 0;
++}
++
++/**
++ * uio_runtime_imr_nop() - Runtime PM callback function.
++ * @dev: device data.
++ *
++ * Runtime PM callback function.
++ *
++ *
++ * Return: 0 normal end.
++ */
++ /* PRQA S 3206 1 */
++static int uio_runtime_imr_nop(__attribute__((unused)) struct device *dev)
++{
++ pr_debug("uio_runtime_imr_nop enter\n"); /* PRQA S 3200 */
++ return 0;
++}
++/* PRQA S 1053 4 */
++static const struct dev_pm_ops uio_dev_pm_imr_ops = {
++ .runtime_suspend = &uio_runtime_imr_nop,
++ .runtime_resume = &uio_runtime_imr_nop,
++};
++
++static struct platform_driver uio_imr_platform_driver = {
++ .probe = &uio_imr_probe,
++ .remove = &uio_imr_remove,
++ .driver = {
++ .name = DRIVER_NAME,
++ .owner = THIS_MODULE,
++ .pm = &uio_dev_pm_imr_ops,
++ .of_match_table = of_match_ptr(rcar_imr_dt_ids),
++ },
++};
++
++module_platform_driver(uio_imr_platform_driver);
++
++
++MODULE_AUTHOR("Renesas Electronics Corporation");
++MODULE_DESCRIPTION("Userspace I/O driver for IMR");
++MODULE_LICENSE("Dual MIT/GPL");
++MODULE_ALIAS("platform:" DRIVER_NAME);
+--
+2.7.4
+
diff --git a/bsp/meta-rcar/meta-rcar-gen3-adas/recipes-kernel/linux/linux-renesas/0335-media-rcar-imr-IMR-driver-updates-for-raw-DL.patch b/bsp/meta-rcar/meta-rcar-gen3-adas/recipes-kernel/linux/linux-renesas/0335-media-rcar-imr-IMR-driver-updates-for-raw-DL.patch
new file mode 100644
index 00000000..bb796eac
--- /dev/null
+++ b/bsp/meta-rcar/meta-rcar-gen3-adas/recipes-kernel/linux/linux-renesas/0335-media-rcar-imr-IMR-driver-updates-for-raw-DL.patch
@@ -0,0 +1,538 @@
+From cf92c2d86f2eec6477c6304527c5eeccd23e290c Mon Sep 17 00:00:00 2001
+From: Konstantin Kozhevnikov <Konstantin.Kozhevnikov@cogentembedded.com>
+Date: Tue, 14 Nov 2017 01:47:11 -0800
+Subject: [PATCH 155/211] media: rcar-imr: IMR driver updates for raw DL
+
+IMR driver updates for raw DL
+
+Signed-off-by: Konstantin Kozhevnikov <Konstantin.Kozhevnikov@cogentembedded.com>
+---
+ drivers/media/platform/rcar_imr.c | 209 ++++++++++++++++++++++++++++++--------
+ include/uapi/linux/rcar-imr.h | 16 +--
+ 2 files changed, 175 insertions(+), 50 deletions(-)
+
+diff --git a/drivers/media/platform/rcar_imr.c b/drivers/media/platform/rcar_imr.c
+index 30c6742..9b601da 100644
+--- a/drivers/media/platform/rcar_imr.c
++++ b/drivers/media/platform/rcar_imr.c
+@@ -94,6 +94,7 @@ struct imr_device {
+ struct v4l2_device v4l2_dev;
+ struct video_device video_dev;
+ struct v4l2_m2m_dev *m2m_dev;
++ struct device *alloc_dev;
+
+ /* ...do we need that counter really? framework counts fh structures for us - tbd */
+ int refcount;
+@@ -117,6 +118,9 @@ struct imr_ctx {
+ /* ...cropping parameters (in pixels) */
+ u16 crop[4];
+
++ /* ...solid color code */
++ u32 color;
++
+ /* ...number of active configurations (debugging) */
+ u32 cfg_num;
+ };
+@@ -192,6 +196,7 @@ struct imr_ctx {
+
+ #define IMR_TRICR 0x6C
+ #define IMR_TRIC_YCFORM (1 << 31)
++#define IMR_TRICR2 0xA0
+
+ #define IMR_UVDPOR 0x70
+ #define IMR_SUSR 0x74
+@@ -212,6 +217,8 @@ struct imr_ctx {
+ #define IMR_CPDP_UBDPO_SHIFT 4
+ #define IMR_CPDP_VRDPO_SHIFT 0
+
++#define IMR_TPOR 0xF0
++
+ /*******************************************************************************
+ * Auxiliary helpers
+ ******************************************************************************/
+@@ -404,11 +411,16 @@ static int imr_queue_setup(struct vb2_queue *vq,
+ return -EINVAL;
+ }
+
++ /* ...specify default allocator */
++ alloc_devs[0] = ctx->imr->alloc_dev;
++
+ return 0;
+ }
+
+ static int imr_buf_prepare(struct vb2_buffer *vb)
+ {
++ struct imr_ctx *ctx = vb2_get_drv_priv(vb->vb2_queue);
++
+ /* ...unclear yet if we want to prepare a buffer somehow (cache invalidation? - tbd) */
+ return 0;
+ }
+@@ -441,9 +453,10 @@ static void imr_buf_finish(struct vb2_buffer *vb)
+ WARN_ON(!mutex_is_locked(&ctx->imr->mutex));
+
+ /* ...any special processing of completed buffer? - tbd */
+- v4l2_dbg(3, debug, &ctx->imr->v4l2_dev, "%sput buffer <0x%08llx> done\n",
++ v4l2_dbg(3, debug, &ctx->imr->v4l2_dev, "%sput buffer <0x%08llx> done (err: %d) (ctx=%p)\n",
+ q->is_output ? "in" : "out",
+- vb2_dma_contig_plane_dma_addr(vb, 0));
++ vb2_dma_contig_plane_dma_addr(vb, 0),
++ vb->state, ctx);
+
+ /* ...unref configuration pointer as needed */
+ if (q->is_output)
+@@ -568,6 +581,11 @@ static inline u16 __imr_auto_sg_dg_tcm(u32 type)
+ (type & IMR_MAP_TCM ? IMR_TRIM_TCM : 0);
+ }
+
++static inline u16 __imr_bfe_tme(u32 type)
++{
++ return (type & IMR_MAP_TME ? IMR_TRIM_TME : 0) | (type & IMR_MAP_BFE ? IMR_TRIM_BFE : 0);
++}
++
+ static inline u16 __imr_uvdp(u32 type)
+ {
+ return __IMR_MAP_UVDPOR(type) | (type & IMR_MAP_DDP ? (1 << 8) : 0);
+@@ -674,15 +692,14 @@ static inline u32 * imr_tri_set_type_b(u32 *dl, void *map, struct imr_mesh *mesh
+ ******************************************************************************/
+
+ /* ...calculate length of a type "c" mapping */
+-static inline u32 imr_tri_type_c_get_length(struct imr_vbo *vbo, int item_size)
++static inline u32 imr_tri_type_c_get_length(int num, int item_size)
+ {
+- return ((4 + 3 * item_size) * vbo->num + 4);
++ return ((4 + 3 * item_size) * num + 4);
+ }
+
+ /* ...set a VBO mapping using absolute coordinates */
+-static inline u32 * imr_tri_set_type_c(u32 *dl, void *map, struct imr_vbo *vbo, int item_size)
++static inline u32 * imr_tri_set_type_c(u32 *dl, void *map, int num, int item_size)
+ {
+- int num = vbo->num;
+ int i;
+
+ /* ...prepare list of triangles to draw */
+@@ -732,6 +749,7 @@ static inline void imr_dl_program_setup(struct imr_ctx *ctx, struct imr_cfg *cfg
+ int h = ctx->queue[0].fmt.height;
+ int W = ctx->queue[1].fmt.width;
+ int H = ctx->queue[1].fmt.height;
++ u32 tricr = ctx->color & 0xFFFFFF;
+
+ v4l2_dbg(2, debug, &ctx->imr->v4l2_dev, "setup %u*%u -> %u*%u mapping (type=%x)\n", w, h, W, H, type);
+
+@@ -739,11 +757,17 @@ static inline void imr_dl_program_setup(struct imr_ctx *ctx, struct imr_cfg *cfg
+ *dl++ = IMR_OP_WTS(IMR_TRIMCR, 0xFFFF);
+
+ /* ...set automatic source / destination coordinates generation flags */
+- *dl++ = IMR_OP_WTS(IMR_TRIMSR, __imr_auto_sg_dg_tcm(type) | IMR_TRIM_BFE | IMR_TRIM_TME);
++ *dl++ = IMR_OP_WTS(IMR_TRIMSR, __imr_auto_sg_dg_tcm(type) | __imr_bfe_tme(type));
++
++ /* ...that's probably not needed? - tbd */
++ *dl++ = IMR_OP_SYNCM;
+
+ /* ...set source / destination coordinate precision */
+ *dl++ = IMR_OP_WTS(IMR_UVDPOR, __imr_uvdp(type));
+
++ /* ...that's probably not needed? - tbd */
++ *dl++ = IMR_OP_SYNCM;
++
+ /* ...set luminance/chromacity correction parameters precision */
+ *dl++ = IMR_OP_WTS(IMR_CPDPOR, __imr_cpdp(type));
+
+@@ -776,14 +800,12 @@ static inline void imr_dl_program_setup(struct imr_ctx *ctx, struct imr_cfg *cfg
+ }
+ } else {
+ u16 src_fmt = (iflags & IMR_F_UV_SWAP ? IMR_CMR2_UVFORM : 0) | (iflags & IMR_F_YUV_SWAP ? IMR_CMR2_YUV422FORM : 0);
+- u32 dst_fmt = (oflags & IMR_F_YUV_SWAP ? IMR_TRIC_YCFORM : 0);
+
+ /* ...interleaved input; output is either interleaved or planar */
+ *dl++ = IMR_OP_WTS(IMR_CMRCSR2, IMR_CMR2_YUV422E | src_fmt);
+
+ /* ...destination is always YUYV or UYVY */
+- *dl++ = IMR_OP_WTL(IMR_TRICR, 1);
+- *dl++ = dst_fmt;
++ tricr |= (oflags & IMR_F_YUV_SWAP ? IMR_TRIC_YCFORM : 0);
+
+ /* ...set precision of Y/UV planes and required correction */
+ *dl++ = IMR_OP_WTS(IMR_CMRCSR, src_y_fmt | src_uv_fmt | dst_y_fmt | dst_uv_fmt | __imr_clce(type) | __imr_luce(type));
+@@ -810,6 +832,10 @@ static inline void imr_dl_program_setup(struct imr_ctx *ctx, struct imr_cfg *cfg
+ *dl++ = ((w - 2) << 16) | (w - 1);
+ *dl++ = h - 1;
+
++ /* ...set triangle single color */
++ *dl++ = IMR_OP_WTL(IMR_TRICR, 1);
++ *dl++ = tricr;
++
+ /* ...invoke subroutine for triangles drawing */
+ *dl++ = IMR_OP_GOSUB;
+ *dl++ = subaddr;
+@@ -852,7 +878,7 @@ static int imr_ioctl_map(struct imr_ctx *ctx, struct imr_map_desc *desc)
+ {
+ struct imr_device *imr = ctx->imr;
+ struct imr_mesh *mesh;
+- struct imr_vbo *vbo;
++ int vbo_num;
+ struct imr_cfg *cfg;
+ void *buf, *map;
+ u32 type;
+@@ -925,13 +951,6 @@ static int imr_ioctl_map(struct imr_ctx *ctx, struct imr_map_desc *desc)
+ tri_length = imr_tri_type_a_get_length(mesh, item_size);
+ }
+ } else {
+- /* ...assure we have proper VBO descriptor */
+- if (length < sizeof(struct imr_vbo)) {
+- v4l2_err(&imr->v4l2_dev, "invalid vbo specification size: %u\n", length);
+- ret = -EINVAL;
+- goto out;
+- }
+-
+ /* ...make sure there is no automatic-generation flags */
+ if (type & (IMR_MAP_AUTODG | IMR_MAP_AUTOSG)) {
+ v4l2_err(&imr->v4l2_dev, "invalid auto-dg/sg flags: 0x%x\n", type);
+@@ -939,22 +958,23 @@ static int imr_ioctl_map(struct imr_ctx *ctx, struct imr_map_desc *desc)
+ goto out;
+ }
+
+- vbo = (struct imr_vbo *)buf;
+- length -= sizeof(struct imr_vbo);
+- map = buf + sizeof(struct imr_vbo);
++ map = buf;
+
+ /* ...vertex is given with absolute coordinates */
+ item_size += 8;
+
++ /* ...calculate total number of triangles */
++ vbo_num = length / (3 * item_size);
++
+ /* ...check the length is sane */
+- if (length != vbo->num * 3 * item_size) {
+- v4l2_err(&imr->v4l2_dev, "invalid vbo size: %u*%u*3 != %u\n", vbo->num, item_size, length);
++ if (length != vbo_num * 3 * item_size) {
++ v4l2_err(&imr->v4l2_dev, "invalid vbo size: %u*%u*3 != %u\n", vbo_num, item_size, length);
+ ret = -EINVAL;
+ goto out;
+ }
+
+ /* ...calculate size of trangles drawing subroutine */
+- tri_length = imr_tri_type_c_get_length(vbo, item_size);
++ tri_length = imr_tri_type_c_get_length(vbo_num, item_size);
+ }
+
+ /* ...DL main program shall start with 8-byte aligned address */
+@@ -975,13 +995,16 @@ static int imr_ioctl_map(struct imr_ctx *ctx, struct imr_map_desc *desc)
+ imr_cfg_unref(ctx, ctx->cfg);
+
+ /* ...create new configuration */
+- ctx->cfg = cfg = imr_cfg_create(ctx, dl_size, dl_start_offset);
++ cfg = imr_cfg_create(ctx, dl_size, dl_start_offset);
+ if (IS_ERR(cfg)) {
+ ret = PTR_ERR(cfg);
++ ctx->cfg = NULL;
+ v4l2_err(&imr->v4l2_dev, "failed to create configuration: %d\n", ret);
+ goto out;
+ }
+
++ ctx->cfg = cfg;
++
+ /* ...get pointer to the new display list */
+ dl_vaddr = cfg->dl_vaddr;
+ dl_dma_addr = cfg->dl_dma_addr;
+@@ -994,7 +1017,7 @@ static int imr_ioctl_map(struct imr_ctx *ctx, struct imr_map_desc *desc)
+ imr_tri_set_type_a(dl_vaddr, map, mesh, item_size);
+ }
+ } else {
+- imr_tri_set_type_c(dl_vaddr, map, vbo, item_size);
++ imr_tri_set_type_c(dl_vaddr, map, vbo_num, item_size);
+ }
+
+ /* ...prepare main DL-program */
+@@ -1020,6 +1043,66 @@ static int imr_ioctl_map(struct imr_ctx *ctx, struct imr_map_desc *desc)
+ return ret;
+ }
+
++/* ...set mapping data (function called with video device lock held) */
++static int imr_ioctl_map_raw(struct imr_ctx *ctx, struct imr_map_desc *desc)
++{
++ struct imr_device *imr = ctx->imr;
++ u32 type = desc->type;
++ u32 length = desc->size;
++ struct imr_cfg *cfg;
++ void *dl_vaddr;
++ u32 dl_size;
++ u32 dl_start_offset;
++ dma_addr_t dl_dma_addr;
++
++ /* ...calculate main routine length */
++ dl_size = imr_dl_program_length(ctx);
++ if (!dl_size) {
++ v4l2_err(&imr->v4l2_dev, "format configuration error\n");
++ return -EINVAL;
++ }
++
++ /* ...unref current configuration (will not be used by subsequent jobs) */
++ imr_cfg_unref(ctx, ctx->cfg);
++
++ /* ...create new configuration (starts with zero offset) */
++ cfg = imr_cfg_create(ctx, dl_size, 0);
++ if (IS_ERR(cfg)) {
++ ctx->cfg = NULL;
++ v4l2_err(&imr->v4l2_dev, "failed to create configuration: %ld\n", PTR_ERR(cfg));
++ return PTR_ERR(cfg);
++ }
++
++ ctx->cfg = cfg;
++
++ /* ...get pointer to the new display list */
++ dl_vaddr = cfg->dl_vaddr;
++
++ /* ...prepare main DL-program */
++ imr_dl_program_setup(ctx, cfg, type, dl_vaddr, (u32)(uintptr_t)desc->data);
++
++ /* ...update cropping parameters */
++ cfg->dst_subpixel = (type & IMR_MAP_DDP ? 2 : 0);
++
++ /* ...display list updated successfully */
++ v4l2_dbg(2, debug, &ctx->imr->v4l2_dev, "display-list created: #%u[%08X]:%u[%u]\n",
++ cfg->id, (u32)dl_dma_addr, dl_size, 0);
++
++ if (debug >= 4)
++ print_hex_dump_bytes("DL-", DUMP_PREFIX_OFFSET, dl_vaddr + dl_start_offset, dl_size - dl_start_offset);
++
++ /* ...success */
++ return 0;
++}
++
++/* ...set mapping data (function called with video device lock held) */
++static int imr_ioctl_color(struct imr_ctx *ctx, u32 color)
++{
++ ctx->color = color;
++
++ return 0;
++}
++
+ /*******************************************************************************
+ * V4L2 I/O controls
+ ******************************************************************************/
+@@ -1183,7 +1266,7 @@ static int imr_qbuf(struct file *file, void *priv, struct v4l2_buffer *buf)
+ WARN_ON(!mutex_is_locked(&ctx->imr->mutex));
+
+ /* ...verify the configuration is complete */
+- if (!V4L2_TYPE_IS_OUTPUT(buf->type) && !ctx->cfg) {
++ if (!ctx->cfg) {
+ v4l2_err(&ctx->imr->v4l2_dev, "stream configuration is not complete\n");
+ return -EINVAL;
+ }
+@@ -1265,6 +1348,14 @@ static long imr_default(struct file *file, void *fh, bool valid_prio, unsigned i
+ /* ...set mesh data */
+ return imr_ioctl_map(ctx, (struct imr_map_desc *)arg);
+
++ case VIDIOC_IMR_MESH_RAW:
++ /* ...set mesh data */
++ return imr_ioctl_map_raw(ctx, (struct imr_map_desc *)arg);
++
++ case VIDIOC_IMR_COLOR:
++ /* ...set solid color code */
++ return imr_ioctl_color(ctx, *(u32 *)arg);
++
+ default:
+ return -ENOIOCTLCMD;
+ }
+@@ -1326,6 +1417,9 @@ static int imr_open(struct file *file)
+ /* ...set default cropping parameters */
+ ctx->crop[1] = ctx->crop[3] = 0x3FF;
+
++ /* ...set default color */
++ ctx->color = 0x808080;
++
+ /* ...initialize M2M processing context */
+ ctx->m2m_ctx = v4l2_m2m_ctx_init(imr->m2m_dev, ctx, imr_queue_init);
+ if (IS_ERR(ctx->m2m_ctx)) {
+@@ -1418,8 +1512,11 @@ static unsigned int imr_poll(struct file *file, struct poll_table_struct *wait)
+ return -ERESTARTSYS;
+
+ res = v4l2_m2m_poll(file, ctx->m2m_ctx, wait);
++
+ mutex_unlock(&imr->mutex);
+
++ v4l2_dbg(3, debug, &imr->v4l2_dev, "poll result: %X (ctx=%p)\n", res, ctx);
++
+ return res;
+ }
+
+@@ -1453,7 +1550,6 @@ static const struct v4l2_file_operations imr_fops = {
+ * M2M device interface
+ ******************************************************************************/
+
+-#if 0
+ /* ...job cleanup function */
+ static void imr_cleanup(struct imr_ctx *ctx)
+ {
+@@ -1473,17 +1569,16 @@ static void imr_cleanup(struct imr_ctx *ctx)
+ /* ...release lock before we mark current job as finished */
+ spin_unlock_irqrestore(&imr->lock, flags);
+ }
+-#endif
+
+ /* ...job execution function */
+ static void imr_device_run(void *priv)
+ {
+- struct imr_ctx *ctx = priv;
+- struct imr_device *imr = ctx->imr;
+- struct imr_cfg *cfg;
+- struct vb2_buffer *src_buf, *dst_buf;
+- u32 src_addr, dst_addr;
+- unsigned long flags;
++ struct imr_ctx *ctx = priv;
++ struct imr_device *imr = ctx->imr;
++ struct imr_cfg *cfg;
++ struct vb2_v4l2_buffer *src_buf, *dst_buf;
++ u32 src_addr, dst_addr;
++ unsigned long flags;
+
+ v4l2_dbg(3, debug, &imr->v4l2_dev, "run next job...\n");
+
+@@ -1494,8 +1589,11 @@ static void imr_device_run(void *priv)
+ src_buf = v4l2_m2m_next_src_buf(ctx->m2m_ctx);
+ dst_buf = v4l2_m2m_next_dst_buf(ctx->m2m_ctx);
+
++ /* ...put source/destination buffers sequence numbers */
++ dst_buf->sequence = src_buf->sequence = ctx->sequence++;
++
+ /* ...take configuration pointer associated with input buffer */
+- cfg = to_imr_buffer(to_vb2_v4l2_buffer(src_buf))->cfg;
++ cfg = to_imr_buffer(src_buf)->cfg;
+
+ /* ...cancel software reset state as needed */
+ iowrite32(0, imr->mmio + IMR_CR);
+@@ -1507,8 +1605,8 @@ static void imr_device_run(void *priv)
+ iowrite32(ctx->crop[3] << cfg->dst_subpixel, imr->mmio + IMR_YMAXR);
+
+ /* ...adjust source/destination parameters of the program (interleaved / semiplanar) */
+- *cfg->src_pa_ptr[0] = src_addr = (u32)vb2_dma_contig_plane_dma_addr(src_buf, 0);
+- *cfg->dst_pa_ptr[0] = dst_addr = (u32)vb2_dma_contig_plane_dma_addr(dst_buf, 0);
++ *cfg->src_pa_ptr[0] = src_addr = (u32)vb2_dma_contig_plane_dma_addr(&src_buf->vb2_buf, 0);
++ *cfg->dst_pa_ptr[0] = dst_addr = (u32)vb2_dma_contig_plane_dma_addr(&dst_buf->vb2_buf, 0);
+
+ /* ...adjust source/destination parameters of the UV-plane as needed */
+ if (cfg->src_pa_ptr[1] && cfg->dst_pa_ptr[1]) {
+@@ -1529,6 +1627,9 @@ static void imr_device_run(void *priv)
+ /* ...set display list address */
+ iowrite32(cfg->dl_dma_addr + cfg->dl_start_offset, imr->mmio + IMR_DLSAR);
+
++ /* ...enable texture prefetching */
++ iowrite32(0xACCE5501, imr->mmio + IMR_TPOR);
++
+ /* ...explicitly flush any pending write operations (don't need that, I guess) */
+ wmb();
+
+@@ -1536,7 +1637,7 @@ static void imr_device_run(void *priv)
+ iowrite32(IMR_CR_RS, imr->mmio + IMR_CR);
+
+ /* ...timestamp input buffer */
+- src_buf->timestamp = ktime_get_ns();
++ src_buf->vb2_buf.timestamp = ktime_get_ns();
+
+ /* ...unlock device access */
+ spin_unlock_irqrestore(&imr->lock, flags);
+@@ -1633,13 +1734,14 @@ static irqreturn_t imr_irq_handler(int irq, void *data)
+ dst_buf->timecode = src_buf->timecode;
+ dst_buf->flags = src_buf->flags & (V4L2_BUF_FLAG_TIMECODE | V4L2_BUF_FLAG_KEYFRAME |
+ V4L2_BUF_FLAG_PFRAME | V4L2_BUF_FLAG_BFRAME | V4L2_BUF_FLAG_TSTAMP_SRC_MASK);
+- dst_buf->sequence = src_buf->sequence = ctx->sequence++;
++ //dst_buf->sequence = src_buf->sequence = ctx->sequence++;
++
+ v4l2_m2m_buf_done(src_buf, VB2_BUF_STATE_DONE);
+ v4l2_m2m_buf_done(dst_buf, VB2_BUF_STATE_DONE);
+
+- v4l2_dbg(3, debug, &imr->v4l2_dev, "buffers <0x%08x,0x%08x> done\n",
++ v4l2_dbg(3, debug, &imr->v4l2_dev, "buffers <0x%08x,0x%08x> done (ctx=%p)\n",
+ (u32)vb2_dma_contig_plane_dma_addr(&src_buf->vb2_buf, 0),
+- (u32)vb2_dma_contig_plane_dma_addr(&dst_buf->vb2_buf, 0));
++ (u32)vb2_dma_contig_plane_dma_addr(&dst_buf->vb2_buf, 0), ctx);
+ } else {
+ /* ...operation completed in error; no way to understand what exactly went wrong */
+ v4l2_m2m_buf_done(src_buf, VB2_BUF_STATE_ERROR);
+@@ -1668,6 +1770,8 @@ static irqreturn_t imr_irq_handler(int irq, void *data)
+ * Device probing / removal interface
+ ******************************************************************************/
+
++static struct class *imr_alloc_class;
++
+ static int imr_probe(struct platform_device *pdev)
+ {
+ struct imr_device *imr;
+@@ -1727,6 +1831,26 @@ static int imr_probe(struct platform_device *pdev)
+ goto device_register_rollback;
+ }
+
++ if (!imr_alloc_class) {
++ imr_alloc_class = class_create(THIS_MODULE, "imr-alloc");
++ if (IS_ERR(imr_alloc_class)) {
++ v4l2_err(&imr->v4l2_dev, "Failed to create alloc-device class\n");
++ ret = PTR_ERR(imr_alloc_class);
++ goto m2m_init_rollback;
++ }
++ }
++
++ struct device *adev = device_create(imr_alloc_class, imr->dev, MKDEV(0, 0), NULL, "%s_alloc", dev_name(&pdev->dev));
++ if (IS_ERR(adev)) {
++ v4l2_err(&imr->v4l2_dev, "Failed to create alloc-device\n");
++ ret = PTR_ERR(adev);
++ goto m2m_init_rollback;
++ }
++ adev->dma_mask = &adev->coherent_dma_mask;
++ adev->coherent_dma_mask = DMA_BIT_MASK(32);
++ arch_setup_dma_ops(adev, 0, DMA_BIT_MASK(32) + 1, NULL, true);
++ imr->alloc_dev = adev;
++
+ strlcpy(imr->video_dev.name, dev_name(&pdev->dev), sizeof(imr->video_dev.name));
+ imr->video_dev.fops = &imr_fops;
+ imr->video_dev.ioctl_ops = &imr_ioctl_ops;
+@@ -1765,6 +1889,7 @@ static int imr_remove(struct platform_device *pdev)
+
+ //pm_runtime_disable(imr->v4l2_dev.dev);
+ video_unregister_device(&imr->video_dev);
++ //device_destroy(imr->alloc_dev, MKDEV(0, 0));
+ v4l2_m2m_release(imr->m2m_dev);
+ v4l2_device_unregister(&imr->v4l2_dev);
+
+diff --git a/include/uapi/linux/rcar-imr.h b/include/uapi/linux/rcar-imr.h
+index d02082f..7b8ed0c 100644
+--- a/include/uapi/linux/rcar-imr.h
++++ b/include/uapi/linux/rcar-imr.h
+@@ -48,6 +48,12 @@ struct imr_map_desc {
+ /* ...vertex clockwise-mode order */
+ #define IMR_MAP_TCM (1 << 5)
+
++/* ...texture mapping enable flag */
++#define IMR_MAP_TME (1 << 6)
++
++/* ...bilinear filtration enable flag */
++#define IMR_MAP_BFE (1 << 7)
++
+ /* ...source coordinate decimal point position bit index */
+ #define __IMR_MAP_UVDPOR_SHIFT 8
+ #define __IMR_MAP_UVDPOR(v) (((v) >> __IMR_MAP_UVDPOR_SHIFT) & 0x7)
+@@ -81,18 +87,12 @@ struct imr_mesh {
+
+ } __attribute__((packed));
+
+-/* ...VBO descriptor */
+-struct imr_vbo {
+- /* ...number of triangles */
+- u16 num;
+-
+-} __attribute__((packed));
+-
+-
+ /*******************************************************************************
+ * Private IOCTL codes
+ ******************************************************************************/
+
+ #define VIDIOC_IMR_MESH _IOW('V', BASE_VIDIOC_PRIVATE + 0, struct imr_map_desc)
++#define VIDIOC_IMR_MESH_RAW _IOW('V', BASE_VIDIOC_PRIVATE + 1, struct imr_map_desc)
++#define VIDIOC_IMR_COLOR _IOW('V', BASE_VIDIOC_PRIVATE + 2, u32)
+
+ #endif /* RCAR_IMR_USER_H */
+--
+2.7.4
+
diff --git a/bsp/meta-rcar/meta-rcar-gen3-adas/recipes-kernel/linux/linux-renesas/0336-media-rcar-imr-Add-RSE-support.patch b/bsp/meta-rcar/meta-rcar-gen3-adas/recipes-kernel/linux/linux-renesas/0336-media-rcar-imr-Add-RSE-support.patch
new file mode 100644
index 00000000..a836dd9f
--- /dev/null
+++ b/bsp/meta-rcar/meta-rcar-gen3-adas/recipes-kernel/linux/linux-renesas/0336-media-rcar-imr-Add-RSE-support.patch
@@ -0,0 +1,348 @@
+From 4b93294c7d2ca2c6323dbb49c5447718d6503d2c Mon Sep 17 00:00:00 2001
+From: Andrey Dolnikov <andrey.dolnikov@cogentembedded.com>
+Date: Tue, 6 Feb 2018 13:38:34 +0300
+Subject: [PATCH 156/211] media: rcar-imr: Add RSE support
+
+This adds RSE support for V3H IMR
+
+Signed-off-by: Andrey Dolnikov <andrey.dolnikov@cogentembedded.com>
+---
+ arch/arm64/boot/dts/renesas/r8a77980.dtsi | 2 +
+ drivers/media/platform/rcar_imr.c | 143 ++++++++++++++++++++++++++++++
+ include/uapi/linux/rcar-imr.h | 22 ++++-
+ 3 files changed, 165 insertions(+), 2 deletions(-)
+
+diff --git a/arch/arm64/boot/dts/renesas/r8a77980.dtsi b/arch/arm64/boot/dts/renesas/r8a77980.dtsi
+index 302b346..fc0b008 100644
+--- a/arch/arm64/boot/dts/renesas/r8a77980.dtsi
++++ b/arch/arm64/boot/dts/renesas/r8a77980.dtsi
+@@ -1260,6 +1260,7 @@
+ interrupts = <GIC_SPI 254 IRQ_TYPE_LEVEL_HIGH>;
+ clocks = <&cpg CPG_MOD 707>;
+ power-domains = <&sysc R8A77980_PD_ALWAYS_ON>;
++ rse;
+ };
+
+ imrlx4_ch5: imr5@fe8b0000 {
+@@ -1269,6 +1270,7 @@
+ interrupts = <GIC_SPI 255 IRQ_TYPE_LEVEL_HIGH>;
+ clocks = <&cpg CPG_MOD 706>;
+ power-domains = <&sysc R8A77980_PD_ALWAYS_ON>;
++ rse;
+ };
+
+ vip_disp_status {
+diff --git a/drivers/media/platform/rcar_imr.c b/drivers/media/platform/rcar_imr.c
+index 9b601da..7b16765 100644
+--- a/drivers/media/platform/rcar_imr.c
++++ b/drivers/media/platform/rcar_imr.c
+@@ -17,6 +17,7 @@
+ #include <linux/pm_runtime.h>
+ #include <linux/delay.h>
+ #include <linux/rcar-imr.h>
++#include <linux/of.h>
+ #include <media/v4l2-device.h>
+ #include <media/v4l2-ctrls.h>
+ #include <media/v4l2-fh.h>
+@@ -38,6 +39,9 @@ MODULE_PARM_DESC(debug, "Debug level (0-4)");
+ * Local types definitions
+ ******************************************************************************/
+
++/* Number of RSE planes on V3H (non scaled, 1/2, 1/4, 1/8) */
++#define RSE_PLANES_NUM 4
++
+ /* ...configuration data */
+ struct imr_cfg {
+ /* ...display-list main program data */
+@@ -49,6 +53,21 @@ struct imr_cfg {
+ /* ...pointers to the source/destination planes */
+ u32 *src_pa_ptr[2];
+ u32 *dst_pa_ptr[2];
++ /* ...pointers to the RSE destination planes */
++ u32 *dstn_pa_ptr[RSE_PLANES_NUM];
++ u32 *dstr_pa_ptr[RSE_PLANES_NUM];
++
++ /* ...offsets to RSE destination planes */
++ u32 dstnr_offsets[IMR_EXTDST_NUM];
++
++ /* ...RSE logical right shift data */
++ u32 *rscr_ptr;
++ u8 rscr_sc8, rscr_sc4, rscr_sc2;
++
++ /* ...RSE destination stride values */
++ u32 dstnr_strides[IMR_EXTDST_NUM];
++ u32 *striden_ptr[RSE_PLANES_NUM];
++ u32 *strider_ptr[RSE_PLANES_NUM];
+
+ /* ...subpixel destination coordinates space */
+ int dst_subpixel;
+@@ -96,6 +115,8 @@ struct imr_device {
+ struct v4l2_m2m_dev *m2m_dev;
+ struct device *alloc_dev;
+
++ bool rse;
++
+ /* ...do we need that counter really? framework counts fh structures for us - tbd */
+ int refcount;
+
+@@ -219,6 +240,18 @@ struct imr_ctx {
+
+ #define IMR_TPOR 0xF0
+
++#define IMR_RSCSR 0x204
++#define IMR_RSCCR 0x208
++#define IMR_RSCR_RSE 31
++#define IMR_RSCR_SC8 25
++#define IMR_RSCR_SC4 21
++#define IMR_RSCR_SC2 17
++
++#define IMR_DSANRR0 0x210
++#define IMR_DSTNRR0 0x214
++#define IMR_DSARR0 0x218
++#define IMR_DSTRR0 0x21C
++
+ /*******************************************************************************
+ * Auxiliary helpers
+ ******************************************************************************/
+@@ -398,6 +431,7 @@ static int imr_queue_setup(struct vb2_queue *vq,
+ case V4L2_PIX_FMT_YVYU:
+ case V4L2_PIX_FMT_NV16:
+ case V4L2_PIX_FMT_Y10:
++ case V4L2_PIX_FMT_Y12:
+ case V4L2_PIX_FMT_Y16:
+ sizes[0] = w * h * 2;
+ break;
+@@ -750,6 +784,7 @@ static inline void imr_dl_program_setup(struct imr_ctx *ctx, struct imr_cfg *cfg
+ int W = ctx->queue[1].fmt.width;
+ int H = ctx->queue[1].fmt.height;
+ u32 tricr = ctx->color & 0xFFFFFF;
++ int i;
+
+ v4l2_dbg(2, debug, &ctx->imr->v4l2_dev, "setup %u*%u -> %u*%u mapping (type=%x)\n", w, h, W, H, type);
+
+@@ -775,6 +810,38 @@ static inline void imr_dl_program_setup(struct imr_ctx *ctx, struct imr_cfg *cfg
+ *dl++ = IMR_OP_WTS(IMR_CMRCCR, 0xFFFF);
+ *dl++ = IMR_OP_WTS(IMR_CMRCCR2, 0xFFFF);
+
++ if (type & IMR_MAP_RSE) {
++ /* ...enable RSE */
++ *dl++ = IMR_OP_WTL(IMR_RSCCR, 1);
++ *dl++ = 0xffffffff;
++ *dl++ = IMR_OP_WTL(IMR_RSCSR, 1);
++ cfg->rscr_ptr = dl++;
++
++ for (i = 0; i < RSE_PLANES_NUM; i++) {
++ /* ...set destination planes base address and strides */
++ *dl++ = IMR_OP_WTL(IMR_DSANRR0 + i * 0x10, 4);
++ cfg->dstn_pa_ptr[i] = dl++;
++ cfg->striden_ptr[i] = dl++;
++ cfg->dstr_pa_ptr[i] = dl++;
++ cfg->strider_ptr[i] = dl++;
++ }
++
++ cfg->rscr_sc8 = cfg->rscr_sc4 = cfg->rscr_sc2 = 0;
++ memset(cfg->dstnr_offsets, 0, sizeof(cfg->dstnr_offsets));
++ memset(cfg->dstnr_strides, 0, sizeof(cfg->dstnr_strides));
++ } else {
++ /* ...disable RSE */
++ *dl++ = IMR_OP_WTL(IMR_RSCCR, 1);
++ *dl++ = 0xffffffff;
++
++ for (i = 0; i < RSE_PLANES_NUM; i++) {
++ cfg->dstn_pa_ptr[i] = NULL;
++ cfg->striden_ptr[i] = NULL;
++ cfg->dstr_pa_ptr[i] = NULL;
++ cfg->strider_ptr[i] = NULL;
++ }
++ cfg->rscr_ptr = NULL;
++ }
+ /* ...set source/destination addresses of Y/UV plane */
+ *dl++ = IMR_OP_WTL(IMR_DSAR, 2);
+ cfg->dst_pa_ptr[0] = dl++;
+@@ -907,6 +974,12 @@ static int imr_ioctl_map(struct imr_ctx *ctx, struct imr_map_desc *desc)
+
+ type = desc->type;
+
++ /* ...check for RSE */
++ if ((type & IMR_MAP_RSE) && !imr->rse) {
++ v4l2_err(&imr->v4l2_dev, "Rotator & Scaler extension not supported\n");
++ return -EINVAL;
++ }
++
+ /* ...mesh item size calculation */
+ item_size = (type & IMR_MAP_LUCE ? 4 : 0) + (type & IMR_MAP_CLCE ? 4 : 0);
+
+@@ -1055,6 +1128,12 @@ static int imr_ioctl_map_raw(struct imr_ctx *ctx, struct imr_map_desc *desc)
+ u32 dl_start_offset;
+ dma_addr_t dl_dma_addr;
+
++ /* ...check RSE */
++ if ((type & IMR_MAP_RSE) && !imr->rse) {
++ v4l2_err(&imr->v4l2_dev, "Rotator & Scaler extension not supported\n");
++ return -EINVAL;
++ }
++
+ /* ...calculate main routine length */
+ dl_size = imr_dl_program_length(ctx);
+ if (!dl_size) {
+@@ -1103,6 +1182,46 @@ static int imr_ioctl_color(struct imr_ctx *ctx, u32 color)
+ return 0;
+ }
+
++static int imr_extdst_set(struct imr_ctx *ctx, u32 *extdst)
++{
++ struct imr_device *imr = ctx->imr;
++ struct imr_cfg *cfg = ctx->cfg;
++
++ if (!cfg) {
++ v4l2_err(&imr->v4l2_dev, "failed to set V3H extension dst buffers: No active confguration.\n");
++ return -EINVAL;
++ }
++
++ if (copy_from_user((void *) cfg->dstnr_offsets, (void __user *) extdst, sizeof(cfg->dstnr_offsets))) {
++ v4l2_err(&imr->v4l2_dev, "failed to read V3H extension dst buffers\n");
++ return -EFAULT;
++ }
++
++ return 0;
++}
++
++static int imr_extstride_set(struct imr_ctx *ctx, struct imr_rse_param *param)
++{
++ struct imr_device *imr = ctx->imr;
++ struct imr_cfg *cfg = ctx->cfg;
++
++ if (!cfg) {
++ v4l2_err(&imr->v4l2_dev, "failed to set V3H extension buffers params: No active confguration.\n");
++ return -EINVAL;
++ }
++
++ cfg->rscr_sc8 = param->sc8;
++ cfg->rscr_sc4 = param->sc4;
++ cfg->rscr_sc2 = param->sc2;
++
++ if (copy_from_user((void *) cfg->dstnr_strides, (void __user *) param->strides, sizeof(cfg->dstnr_strides))) {
++ v4l2_err(&imr->v4l2_dev, "failed to read V3H extension buffers strides\n");
++ return -EFAULT;
++ }
++
++ return 0;
++}
++
+ /*******************************************************************************
+ * V4L2 I/O controls
+ ******************************************************************************/
+@@ -1356,6 +1475,14 @@ static long imr_default(struct file *file, void *fh, bool valid_prio, unsigned i
+ /* ...set solid color code */
+ return imr_ioctl_color(ctx, *(u32 *)arg);
+
++ case VIDIOC_IMR_EXTDST:
++ /* ...set V3H extension dst buffers */
++ return imr_extdst_set(ctx, *(u32 **)arg);
++
++ case VIDIOC_IMR_EXTSTRIDE:
++ /* ...set V3H extension dst strides */
++ return imr_extstride_set(ctx, (struct imr_rse_param *)arg);
++
+ default:
+ return -ENOIOCTLCMD;
+ }
+@@ -1579,6 +1706,7 @@ static void imr_device_run(void *priv)
+ struct vb2_v4l2_buffer *src_buf, *dst_buf;
+ u32 src_addr, dst_addr;
+ unsigned long flags;
++ int i;
+
+ v4l2_dbg(3, debug, &imr->v4l2_dev, "run next job...\n");
+
+@@ -1608,6 +1736,17 @@ static void imr_device_run(void *priv)
+ *cfg->src_pa_ptr[0] = src_addr = (u32)vb2_dma_contig_plane_dma_addr(&src_buf->vb2_buf, 0);
+ *cfg->dst_pa_ptr[0] = dst_addr = (u32)vb2_dma_contig_plane_dma_addr(&dst_buf->vb2_buf, 0);
+
++ for (i = 0; i < RSE_PLANES_NUM; i++) {
++ if (cfg->rscr_ptr) *cfg->rscr_ptr = (1 << IMR_RSCR_RSE) | (cfg->rscr_sc8 << IMR_RSCR_SC8) |
++ (cfg->rscr_sc4 << IMR_RSCR_SC4) |(cfg->rscr_sc2 << IMR_RSCR_SC2);
++
++ if (cfg->dstn_pa_ptr[i]) *cfg->dstn_pa_ptr[i] = dst_addr + cfg->dstnr_offsets[i];
++ if (cfg->dstr_pa_ptr[i]) *cfg->dstr_pa_ptr[i] = dst_addr + cfg->dstnr_offsets[i + RSE_PLANES_NUM];
++
++ if (cfg->striden_ptr[i]) *cfg->striden_ptr[i] = cfg->dstnr_strides[i];
++ if (cfg->strider_ptr[i]) *cfg->strider_ptr[i] = cfg->dstnr_strides[i + RSE_PLANES_NUM];
++ }
++
+ /* ...adjust source/destination parameters of the UV-plane as needed */
+ if (cfg->src_pa_ptr[1] && cfg->dst_pa_ptr[1]) {
+ *cfg->src_pa_ptr[1] = src_addr + ctx->queue[0].fmt.width * ctx->queue[0].fmt.height;
+@@ -1776,6 +1915,7 @@ static int imr_probe(struct platform_device *pdev)
+ {
+ struct imr_device *imr;
+ struct resource *res;
++ struct device_node *np = pdev->dev.of_node;
+ int ret;
+
+ imr = devm_kzalloc(&pdev->dev, sizeof(*imr), GFP_KERNEL);
+@@ -1786,6 +1926,9 @@ static int imr_probe(struct platform_device *pdev)
+ spin_lock_init(&imr->lock);
+ imr->dev = &pdev->dev;
+
++ /* Check RSE support */
++ imr->rse = of_property_read_bool(np, "rse");
++
+ /* ...memory-mapped registers */
+ res = platform_get_resource(pdev, IORESOURCE_MEM, 0);
+ if (!res) {
+diff --git a/include/uapi/linux/rcar-imr.h b/include/uapi/linux/rcar-imr.h
+index 7b8ed0c..93098d2 100644
+--- a/include/uapi/linux/rcar-imr.h
++++ b/include/uapi/linux/rcar-imr.h
+@@ -25,8 +25,8 @@ struct imr_map_desc {
+ /* ...total size of the mesh structure */
+ u32 size;
+
+- /* ...map-specific user-pointer */
+- void *data;
++ /* ...map-specific user-pointer */
++ void *data;
+
+ } __attribute__((packed));
+
+@@ -54,6 +54,9 @@ struct imr_map_desc {
+ /* ...bilinear filtration enable flag */
+ #define IMR_MAP_BFE (1 << 7)
+
++/* ...extended functionality (rotation/scaling) enable flag */
++#define IMR_MAP_RSE (1 << 21)
++
+ /* ...source coordinate decimal point position bit index */
+ #define __IMR_MAP_UVDPOR_SHIFT 8
+ #define __IMR_MAP_UVDPOR(v) (((v) >> __IMR_MAP_UVDPOR_SHIFT) & 0x7)
+@@ -88,11 +91,26 @@ struct imr_mesh {
+ } __attribute__((packed));
+
+ /*******************************************************************************
++ * V3H Extension destination data
++ ******************************************************************************/
++/* ...number of V3H extension destination buffers (rotated/non-rotated, scaled 1/1, 1/2, 1/4, 1/8) */
++#define IMR_EXTDST_NUM 8
++
++struct imr_rse_param {
++ /* ...logical right shift data */
++ u8 sc8, sc4, sc2;
++ /* ...destination buffers stride */
++ u32 *strides;
++};
++
++/*******************************************************************************
+ * Private IOCTL codes
+ ******************************************************************************/
+
+ #define VIDIOC_IMR_MESH _IOW('V', BASE_VIDIOC_PRIVATE + 0, struct imr_map_desc)
+ #define VIDIOC_IMR_MESH_RAW _IOW('V', BASE_VIDIOC_PRIVATE + 1, struct imr_map_desc)
+ #define VIDIOC_IMR_COLOR _IOW('V', BASE_VIDIOC_PRIVATE + 2, u32)
++#define VIDIOC_IMR_EXTDST _IOW('V', BASE_VIDIOC_PRIVATE + 3, u32 *)
++#define VIDIOC_IMR_EXTSTRIDE _IOW('V', BASE_VIDIOC_PRIVATE + 4, struct imr_rse_param)
+
+ #endif /* RCAR_IMR_USER_H */
+--
+2.7.4
+
diff --git a/bsp/meta-rcar/meta-rcar-gen3-adas/recipes-kernel/linux/linux-renesas/0337-rcar_imr-v4l2-driver-Fix-module-support.patch b/bsp/meta-rcar/meta-rcar-gen3-adas/recipes-kernel/linux/linux-renesas/0337-rcar_imr-v4l2-driver-Fix-module-support.patch
new file mode 100644
index 00000000..2a5adbf0
--- /dev/null
+++ b/bsp/meta-rcar/meta-rcar-gen3-adas/recipes-kernel/linux/linux-renesas/0337-rcar_imr-v4l2-driver-Fix-module-support.patch
@@ -0,0 +1,278 @@
+From 689485ff61b8b96b180caf7ccaf19f7e3cf3c9bb Mon Sep 17 00:00:00 2001
+From: Andrey Dolnikov <andrey.dolnikov@cogentembedded.com>
+Date: Mon, 5 Nov 2018 23:34:53 +0300
+Subject: [PATCH 157/211] rcar_imr v4l2 driver: Fix module support.
+
+---
+ arch/arm64/boot/dts/renesas/r8a7795.dtsi | 8 ++++++++
+ arch/arm64/boot/dts/renesas/r8a7796.dtsi | 6 ++++++
+ arch/arm64/boot/dts/renesas/r8a77970.dtsi | 8 ++++++++
+ arch/arm64/boot/dts/renesas/r8a77980.dtsi | 10 ++++++++++
+ drivers/media/platform/rcar_imr.c | 32 ++++++++++++++++++++++++++++---
+ 5 files changed, 61 insertions(+), 3 deletions(-)
+
+diff --git a/arch/arm64/boot/dts/renesas/r8a7795.dtsi b/arch/arm64/boot/dts/renesas/r8a7795.dtsi
+index e749633..e1b57e9 100644
+--- a/arch/arm64/boot/dts/renesas/r8a7795.dtsi
++++ b/arch/arm64/boot/dts/renesas/r8a7795.dtsi
+@@ -2785,6 +2785,10 @@
+ status = "disabled";
+ };
+
++ imr_v4l2_alloc: imr_alloc {
++ dma-coherent;
++ };
++
+ imrlx4_ch0: imr0@fe860000 {
+ compatible = "renesas,r8a7795-imr-lx4",
+ "renesas,imr-lx4";
+@@ -2793,6 +2797,7 @@
+ clocks = <&cpg CPG_MOD 823>;
+ power-domains = <&sysc R8A7795_PD_A3VC>;
+ resets = <&cpg 823>;
++ alloc-dev = <&imr_v4l2_alloc>;
+ };
+
+ imrlx4_ch1: imr1@fe870000 {
+@@ -2803,6 +2808,7 @@
+ clocks = <&cpg CPG_MOD 822>;
+ power-domains = <&sysc R8A7795_PD_A3VC>;
+ resets = <&cpg 822>;
++ alloc-dev = <&imr_v4l2_alloc>;
+ };
+
+ imrlx4_ch2: imr2@fe880000 {
+@@ -2813,6 +2819,7 @@
+ clocks = <&cpg CPG_MOD 821>;
+ power-domains = <&sysc R8A7795_PD_A3VC>;
+ resets = <&cpg 821>;
++ alloc-dev = <&imr_v4l2_alloc>;
+ };
+
+ imrlx4_ch3: imr3@fe890000 {
+@@ -2823,6 +2830,7 @@
+ clocks = <&cpg CPG_MOD 820>;
+ power-domains = <&sysc R8A7795_PD_A3VC>;
+ resets = <&cpg 820>;
++ alloc-dev = <&imr_v4l2_alloc>;
+ };
+
+ fcpcs: vcp4@fe90f000 {
+diff --git a/arch/arm64/boot/dts/renesas/r8a7796.dtsi b/arch/arm64/boot/dts/renesas/r8a7796.dtsi
+index 49068a8..7fcac8f 100644
+--- a/arch/arm64/boot/dts/renesas/r8a7796.dtsi
++++ b/arch/arm64/boot/dts/renesas/r8a7796.dtsi
+@@ -2618,6 +2618,10 @@
+ status = "disabled";
+ };
+
++ imr_v4l2_alloc: imr_alloc {
++ dma-coherent;
++ };
++
+ imrlx4_ch0: imr0@fe860000 {
+ compatible = "renesas,r8a7796-imr-lx4",
+ "renesas,imr-lx4";
+@@ -2626,6 +2630,7 @@
+ clocks = <&cpg CPG_MOD 823>;
+ power-domains = <&sysc R8A7796_PD_A3VC>;
+ resets = <&cpg 823>;
++ alloc-dev = <&imr_v4l2_alloc>;
+ };
+
+ imrlx4_ch1: imr1@fe870000 {
+@@ -2636,6 +2641,7 @@
+ clocks = <&cpg CPG_MOD 822>;
+ power-domains = <&sysc R8A7796_PD_A3VC>;
+ resets = <&cpg 822>;
++ alloc-dev = <&imr_v4l2_alloc>;
+ };
+
+ imp_distributer: impdes0 {
+diff --git a/arch/arm64/boot/dts/renesas/r8a77970.dtsi b/arch/arm64/boot/dts/renesas/r8a77970.dtsi
+index 40e28338..77ee934 100644
+--- a/arch/arm64/boot/dts/renesas/r8a77970.dtsi
++++ b/arch/arm64/boot/dts/renesas/r8a77970.dtsi
+@@ -968,6 +968,10 @@
+ power-domains = <&sysc R8A77970_PD_A3IR>;
+ };
+
++ imr_v4l2_alloc: imr_alloc {
++ dma-coherent;
++ };
++
+ imrlx4_ch0: imr0@fe860000 {
+ compatible = "renesas,r8a77970-imr-lx4",
+ "renesas,imr-lx4";
+@@ -976,6 +980,7 @@
+ clocks = <&cpg CPG_MOD 823>;
+ power-domains = <&sysc R8A77970_PD_ALWAYS_ON>;
+ resets = <&cpg 823>;
++ alloc-dev = <&imr_v4l2_alloc>;
+ };
+
+ imrlx4_ch1: imr1@fe870000 {
+@@ -986,6 +991,7 @@
+ clocks = <&cpg CPG_MOD 822>;
+ power-domains = <&sysc R8A77970_PD_ALWAYS_ON>;
+ resets = <&cpg 822>;
++ alloc-dev = <&imr_v4l2_alloc>;
+ };
+
+ imrlx4_ch2: imr2@fe880000 {
+@@ -996,6 +1002,7 @@
+ clocks = <&cpg CPG_MOD 821>;
+ power-domains = <&sysc R8A77970_PD_ALWAYS_ON>;
+ resets = <&cpg 821>;
++ alloc-dev = <&imr_v4l2_alloc>;
+ };
+
+ imrlx4_ch3: imr3@fe890000 {
+@@ -1006,6 +1013,7 @@
+ clocks = <&cpg CPG_MOD 820>;
+ power-domains = <&sysc R8A77970_PD_ALWAYS_ON>;
+ resets = <&cpg 820>;
++ alloc-dev = <&imr_v4l2_alloc>;
+ };
+
+ isp@fec00000 {
+diff --git a/arch/arm64/boot/dts/renesas/r8a77980.dtsi b/arch/arm64/boot/dts/renesas/r8a77980.dtsi
+index fc0b008..8af443d 100644
+--- a/arch/arm64/boot/dts/renesas/r8a77980.dtsi
++++ b/arch/arm64/boot/dts/renesas/r8a77980.dtsi
+@@ -1213,6 +1213,10 @@
+ power-domains = <&sysc R8A77980_PD_A3IR>;
+ };
+
++ imr_v4l2_alloc: imr_alloc {
++ dma-coherent;
++ };
++
+ imrlx4_ch0: imr0@fe860000 {
+ compatible = "renesas,r8a77980-imr-lx4",
+ "renesas,imr-lx4";
+@@ -1221,6 +1225,7 @@
+ clocks = <&cpg CPG_MOD 823>;
+ power-domains = <&sysc R8A77980_PD_ALWAYS_ON>;
+ resets = <&cpg 823>;
++ alloc-dev = <&imr_v4l2_alloc>;
+ };
+
+ imrlx4_ch1: imr1@fe870000 {
+@@ -1231,6 +1236,7 @@
+ clocks = <&cpg CPG_MOD 822>;
+ power-domains = <&sysc R8A77980_PD_ALWAYS_ON>;
+ resets = <&cpg 822>;
++ alloc-dev = <&imr_v4l2_alloc>;
+ };
+
+ imrlx4_ch2: imr2@fe880000 {
+@@ -1241,6 +1247,7 @@
+ clocks = <&cpg CPG_MOD 821>;
+ power-domains = <&sysc R8A77980_PD_ALWAYS_ON>;
+ resets = <&cpg 821>;
++ alloc-dev = <&imr_v4l2_alloc>;
+ };
+
+ imrlx4_ch3: imr3@fe890000 {
+@@ -1251,6 +1258,7 @@
+ clocks = <&cpg CPG_MOD 820>;
+ power-domains = <&sysc R8A77980_PD_ALWAYS_ON>;
+ resets = <&cpg 820>;
++ alloc-dev = <&imr_v4l2_alloc>;
+ };
+
+ imrlx4_ch4: imr4@fe8a0000 {
+@@ -1261,6 +1269,7 @@
+ clocks = <&cpg CPG_MOD 707>;
+ power-domains = <&sysc R8A77980_PD_ALWAYS_ON>;
+ rse;
++ alloc-dev = <&imr_v4l2_alloc>;
+ };
+
+ imrlx4_ch5: imr5@fe8b0000 {
+@@ -1271,6 +1280,7 @@
+ clocks = <&cpg CPG_MOD 706>;
+ power-domains = <&sysc R8A77980_PD_ALWAYS_ON>;
+ rse;
++ alloc-dev = <&imr_v4l2_alloc>;
+ };
+
+ vip_disp_status {
+diff --git a/drivers/media/platform/rcar_imr.c b/drivers/media/platform/rcar_imr.c
+index 7b16765..607778e 100644
+--- a/drivers/media/platform/rcar_imr.c
++++ b/drivers/media/platform/rcar_imr.c
+@@ -18,6 +18,7 @@
+ #include <linux/delay.h>
+ #include <linux/rcar-imr.h>
+ #include <linux/of.h>
++#include <linux/of_device.h>
+ #include <media/v4l2-device.h>
+ #include <media/v4l2-ctrls.h>
+ #include <media/v4l2-fh.h>
+@@ -1917,6 +1918,8 @@ static int imr_probe(struct platform_device *pdev)
+ struct resource *res;
+ struct device_node *np = pdev->dev.of_node;
+ int ret;
++ phandle *prop;
++ struct device_node *node;
+
+ imr = devm_kzalloc(&pdev->dev, sizeof(*imr), GFP_KERNEL);
+ if (!imr)
+@@ -1989,10 +1992,15 @@ static int imr_probe(struct platform_device *pdev)
+ ret = PTR_ERR(adev);
+ goto m2m_init_rollback;
+ }
++
+ adev->dma_mask = &adev->coherent_dma_mask;
+ adev->coherent_dma_mask = DMA_BIT_MASK(32);
+- arch_setup_dma_ops(adev, 0, DMA_BIT_MASK(32) + 1, NULL, true);
+ imr->alloc_dev = adev;
++ prop = of_get_property(np, "alloc-dev", NULL);
++ if (prop) {
++ node = of_find_node_by_phandle(be32_to_cpup(prop));
++ of_dma_configure(adev, node, true);
++ }
+
+ strlcpy(imr->video_dev.name, dev_name(&pdev->dev), sizeof(imr->video_dev.name));
+ imr->video_dev.fops = &imr_fops;
+@@ -2032,7 +2040,6 @@ static int imr_remove(struct platform_device *pdev)
+
+ //pm_runtime_disable(imr->v4l2_dev.dev);
+ video_unregister_device(&imr->video_dev);
+- //device_destroy(imr->alloc_dev, MKDEV(0, 0));
+ v4l2_m2m_release(imr->m2m_dev);
+ v4l2_device_unregister(&imr->v4l2_dev);
+
+@@ -2100,7 +2107,26 @@ static struct platform_driver imr_platform_driver = {
+ },
+ };
+
+-module_platform_driver(imr_platform_driver);
++static int __init imr_module_init(void)
++{
++ return platform_driver_register(&imr_platform_driver);
++}
++
++static int imr_device_destroy(struct device *dev, void *data)
++{
++ device_destroy(imr_alloc_class, dev->devt);
++ return 0;
++}
++
++static void __exit imr_module_exit(void)
++{
++ class_for_each_device(imr_alloc_class, NULL, NULL, imr_device_destroy);
++ class_destroy(imr_alloc_class);
++ platform_driver_unregister(&imr_platform_driver);
++}
++
++module_init(imr_module_init);
++module_exit(imr_module_exit);
+
+ MODULE_ALIAS("imr");
+ MODULE_AUTHOR("Cogent Embedded Inc. <sources@cogentembedded.com>");
+--
+2.7.4
+
diff --git a/bsp/meta-rcar/meta-rcar-gen3-adas/recipes-kernel/linux/linux-renesas/0338-V3Hsk-Condor-and-V3Msk-Eagle-Remove-cma-default-area.patch b/bsp/meta-rcar/meta-rcar-gen3-adas/recipes-kernel/linux/linux-renesas/0338-V3Hsk-Condor-and-V3Msk-Eagle-Remove-cma-default-area.patch
new file mode 100644
index 00000000..11b4ee62
--- /dev/null
+++ b/bsp/meta-rcar/meta-rcar-gen3-adas/recipes-kernel/linux/linux-renesas/0338-V3Hsk-Condor-and-V3Msk-Eagle-Remove-cma-default-area.patch
@@ -0,0 +1,103 @@
+From 7fb5561dd487a5fb987fd94dd016a96bf0547daf Mon Sep 17 00:00:00 2001
+From: Andrey Dolnikov <andrey.dolnikov@cogentembedded.com>
+Date: Tue, 6 Nov 2018 14:00:29 +0300
+Subject: [PATCH 158/211] V3Hsk/Condor and V3Msk/Eagle: Remove cma-default area
+ from dts.
+
+To be defined using 'cma' kernel command line parameter.
+---
+ arch/arm64/boot/dts/renesas/r8a77970-eagle.dts | 9 +--------
+ arch/arm64/boot/dts/renesas/r8a77970-v3msk.dts | 9 +--------
+ arch/arm64/boot/dts/renesas/r8a77980-condor.dts | 10 +---------
+ arch/arm64/boot/dts/renesas/r8a77980-v3hsk.dts | 10 +---------
+ 4 files changed, 4 insertions(+), 34 deletions(-)
+
+diff --git a/arch/arm64/boot/dts/renesas/r8a77970-eagle.dts b/arch/arm64/boot/dts/renesas/r8a77970-eagle.dts
+index dd484d5..b87f418 100644
+--- a/arch/arm64/boot/dts/renesas/r8a77970-eagle.dts
++++ b/arch/arm64/boot/dts/renesas/r8a77970-eagle.dts
+@@ -38,16 +38,9 @@
+ /* device specific region for Lossy Decompression */
+ lossy_decompress: linux,lossy_decompress {
+ no-map;
+- reg = <0x00000000 0x6c000000 0x0 0x03000000>;
++ reg = <0x00000000 0x7c000000 0x0 0x03000000>;
+ };
+
+- /* global autoconfigured region for contiguous allocations */
+- linux,cma {
+- compatible = "shared-dma-pool";
+- reusable;
+- reg = <0x00000000 0x6f000000 0x0 0x10000000>;
+- linux,cma-default;
+- };
+
+ /* device specific region for contiguous allocations */
+ mmp_reserved: linux,multimedia {
+diff --git a/arch/arm64/boot/dts/renesas/r8a77970-v3msk.dts b/arch/arm64/boot/dts/renesas/r8a77970-v3msk.dts
+index 4cc11c9..af6c7b9 100644
+--- a/arch/arm64/boot/dts/renesas/r8a77970-v3msk.dts
++++ b/arch/arm64/boot/dts/renesas/r8a77970-v3msk.dts
+@@ -35,16 +35,9 @@
+ /* device specific region for Lossy Decompression */
+ lossy_decompress: linux,lossy_decompress {
+ no-map;
+- reg = <0x00000000 0x6c000000 0x0 0x03000000>;
++ reg = <0x00000000 0x7c000000 0x0 0x03000000>;
+ };
+
+- /* global autoconfigured region for contiguous allocations */
+- linux,cma {
+- compatible = "shared-dma-pool";
+- reusable;
+- reg = <0x00000000 0x6f000000 0x0 0x10000000>;
+- linux,cma-default;
+- };
+
+ /* device specific region for contiguous allocations */
+ mmp_reserved: linux,multimedia {
+diff --git a/arch/arm64/boot/dts/renesas/r8a77980-condor.dts b/arch/arm64/boot/dts/renesas/r8a77980-condor.dts
+index f3b7ebe..577ff3a 100644
+--- a/arch/arm64/boot/dts/renesas/r8a77980-condor.dts
++++ b/arch/arm64/boot/dts/renesas/r8a77980-condor.dts
+@@ -38,15 +38,7 @@
+ /* device specific region for Lossy Decompression */
+ lossy_decompress: linux,lossy_decompress {
+ no-map;
+- reg = <0x00000000 0x6c000000 0x0 0x03000000>;
+- };
+-
+- /* global autoconfigured region for contiguous allocations */
+- linux,cma {
+- compatible = "shared-dma-pool";
+- reusable;
+- reg = <0x00000000 0x6f000000 0x0 0x10000000>;
+- linux,cma-default;
++ reg = <0x00000000 0x7c000000 0x0 0x03000000>;
+ };
+
+ /* device specific region for contiguous allocations */
+diff --git a/arch/arm64/boot/dts/renesas/r8a77980-v3hsk.dts b/arch/arm64/boot/dts/renesas/r8a77980-v3hsk.dts
+index 549ca5e..cfd9c89 100644
+--- a/arch/arm64/boot/dts/renesas/r8a77980-v3hsk.dts
++++ b/arch/arm64/boot/dts/renesas/r8a77980-v3hsk.dts
+@@ -36,15 +36,7 @@
+ /* device specific region for Lossy Decompression */
+ lossy_decompress: linux,lossy_decompress {
+ no-map;
+- reg = <0x00000000 0x6c000000 0x0 0x03000000>;
+- };
+-
+- /* global autoconfigured region for contiguous allocations */
+- linux,cma {
+- compatible = "shared-dma-pool";
+- reusable;
+- reg = <0x00000000 0x6f000000 0x0 0x10000000>;
+- linux,cma-default;
++ reg = <0x00000000 0x7c000000 0x0 0x03000000>;
+ };
+
+ /* device specific region for contiguous allocations */
+--
+2.7.4
+
diff --git a/bsp/meta-rcar/meta-rcar-gen3-adas/recipes-kernel/linux/linux-renesas/0339-media-rcar_imr-Enable-LUCE-for-NV16-format.patch b/bsp/meta-rcar/meta-rcar-gen3-adas/recipes-kernel/linux/linux-renesas/0339-media-rcar_imr-Enable-LUCE-for-NV16-format.patch
new file mode 100644
index 00000000..bbd3f515
--- /dev/null
+++ b/bsp/meta-rcar/meta-rcar-gen3-adas/recipes-kernel/linux/linux-renesas/0339-media-rcar_imr-Enable-LUCE-for-NV16-format.patch
@@ -0,0 +1,49 @@
+From 0d71cf7d1b39f5a5f65efce898c1953e18a069b5 Mon Sep 17 00:00:00 2001
+From: Konstantin Kozhevnikov <Konstantin.Kozhevnikov@cogentembedded.com>
+Date: Thu, 30 Aug 2018 20:30:13 +0300
+Subject: [PATCH 159/211] media: rcar_imr: Enable LUCE for NV16 format
+
+Enable LUCE for NV16 format
+
+Signed-off-by: Konstantin Kozhevnikov <Konstantin.Kozhevnikov@cogentembedded.com>
+---
+ drivers/media/platform/rcar_imr.c | 8 ++++----
+ 1 file changed, 4 insertions(+), 4 deletions(-)
+
+diff --git a/drivers/media/platform/rcar_imr.c b/drivers/media/platform/rcar_imr.c
+index 607778e..8864b0b 100644
+--- a/drivers/media/platform/rcar_imr.c
++++ b/drivers/media/platform/rcar_imr.c
+@@ -853,14 +853,14 @@ static inline void imr_dl_program_setup(struct imr_ctx *ctx, struct imr_cfg *cfg
+ /* ...planar input means planar output; set Y-plane precision */
+ if (cflags & IMR_F_Y8) {
+ /* ...setup Y-plane processing: YCM=0, SY/DY=xx, SUV/DUV=0 */
+- *dl++ = IMR_OP_WTS(IMR_CMRCSR, src_y_fmt | src_uv_fmt | dst_y_fmt | dst_uv_fmt | __imr_luce(type));
++ *dl++ = IMR_OP_WTS(IMR_CMRCSR, src_y_fmt | src_uv_fmt | dst_y_fmt | dst_uv_fmt | __imr_luce(type) | __imr_clce(type));
+
+ /* ...set source/destination strides basing on Y-plane precision */
+ *dl++ = IMR_OP_WTS(IMR_DSTR, W << (cflags & IMR_F_Y10 ? 1 : 0));
+ *dl++ = IMR_OP_WTS(IMR_SSTR, w << (iflags & IMR_F_Y10 ? 1 : 0));
+ } else {
+ /* ...setup UV-plane processing only */
+- *dl++ = IMR_OP_WTS(IMR_CMRCSR, IMR_CMR_YCM | src_uv_fmt | dst_uv_fmt | __imr_clce(type));
++ *dl++ = IMR_OP_WTS(IMR_CMRCSR, IMR_CMR_YCM | src_uv_fmt | dst_uv_fmt | __imr_clce(type) | __imr_luce(type));
+
+ /* ...set source/destination strides basing on UV-plane precision */
+ *dl++ = IMR_OP_WTS(IMR_DSTR, W << (cflags & IMR_F_UV10 ? 1 : 0));
+@@ -919,10 +919,10 @@ static inline void imr_dl_program_setup(struct imr_ctx *ctx, struct imr_cfg *cfg
+ cfg->src_pa_ptr[1] = dl++;
+
+ /* ...select correction mode */
+- *dl++ = IMR_OP_WTS(IMR_CMRCSR, IMR_CMR_YCM | __imr_clce(type));
++ *dl++ = IMR_OP_WTS(IMR_CMRCSR, IMR_CMR_YCM | __imr_clce(type) | __imr_luce(type));
+
+ /* ...luminance correction bit must be cleared (if it was set) */
+- *dl++ = IMR_OP_WTS(IMR_CMRCCR, IMR_CMR_LUCE);
++ //*dl++ = IMR_OP_WTS(IMR_CMRCCR, IMR_CMR_LUCE);
+
+ /* ...draw triangles */
+ *dl++ = IMR_OP_GOSUB;
+--
+2.7.4
+
diff --git a/bsp/meta-rcar/meta-rcar-gen3-adas/recipes-kernel/linux/linux-renesas/0340-clk-cs2000-add-support-for-cs2300.patch b/bsp/meta-rcar/meta-rcar-gen3-adas/recipes-kernel/linux/linux-renesas/0340-clk-cs2000-add-support-for-cs2300.patch
new file mode 100644
index 00000000..d700542b
--- /dev/null
+++ b/bsp/meta-rcar/meta-rcar-gen3-adas/recipes-kernel/linux/linux-renesas/0340-clk-cs2000-add-support-for-cs2300.patch
@@ -0,0 +1,256 @@
+From 1d14f9f23a8122fb286eb7c93cadd2233ac789ab Mon Sep 17 00:00:00 2001
+From: Andrey Dolnikov <andrey.dolnikov@cogentembedded.com>
+Date: Tue, 6 Nov 2018 16:43:06 +0300
+Subject: [PATCH 160/211] clk: cs2000 add support for cs2300
+
+Signed-off-by: Andrey Gusakov <andrey.gusakov@cogentembedded.com>
+---
+ drivers/clk/Kconfig | 5 ++-
+ drivers/clk/clk-cs2000-cp.c | 101 +++++++++++++++++++++++++++++++++-----------
+ 2 files changed, 79 insertions(+), 27 deletions(-)
+
+diff --git a/drivers/clk/Kconfig b/drivers/clk/Kconfig
+index 1c4e1aa..51667a3 100644
+--- a/drivers/clk/Kconfig
++++ b/drivers/clk/Kconfig
+@@ -128,10 +128,11 @@ config COMMON_CLK_CDCE925
+ divider to best approximate the desired output.
+
+ config COMMON_CLK_CS2000_CP
+- tristate "Clock driver for CS2000 Fractional-N Clock Synthesizer & Clock Multiplier"
++ tristate "Clock driver for CS2x00 Fractional-N Clock Synthesizer & Clock Multiplier"
+ depends on I2C
+ help
+- If you say yes here you get support for the CS2000 clock multiplier.
++ If you say yes here you get support for the CS2000 and CS2300 clock
++ multiplier.
+
+ config COMMON_CLK_GEMINI
+ bool "Clock driver for Cortina Systems Gemini SoC"
+diff --git a/drivers/clk/clk-cs2000-cp.c b/drivers/clk/clk-cs2000-cp.c
+index e8ea81c..2708e82 100644
+--- a/drivers/clk/clk-cs2000-cp.c
++++ b/drivers/clk/clk-cs2000-cp.c
+@@ -28,6 +28,7 @@
+ #define Val_Ratio(x, nth) ((x & 0xFF) << (24 - (8 * nth)))
+ #define FUNC_CFG1 0x16
+ #define FUNC_CFG2 0x17
++#define FUNC_CFG3 0x1E
+
+ /* DEVICE_ID */
+ #define REVISION_MASK (0x7)
+@@ -57,8 +58,11 @@
+
+ /* FUNC_CFG1 */
+ #define CLKSKIPEN (1 << 7)
++#define ENDEV3 (1 << 4)
+ #define REFCLKDIV(x) (((x) & 0x3) << 3)
+ #define REFCLKDIV_MASK REFCLKDIV(0x3)
++#define RMODSEL(x) (((x) & 0x7) << 5)
++#define RMODSEL_MASK RMODSEL(0x7)
+
+ /* FUNC_CFG2 */
+ #define LFRATIO_MASK (1 << 3)
+@@ -74,6 +78,11 @@
+ #define REF_CLK 1
+ #define CLK_MAX 2
+
++enum cs2x00_type {
++ DEVICE_CS2000,
++ DEVICE_CS2300
++};
++
+ struct cs2000_priv {
+ struct clk_hw hw;
+ struct i2c_client *client;
+@@ -83,16 +92,20 @@ struct cs2000_priv {
+ /* suspend/resume */
+ unsigned long saved_rate;
+ unsigned long saved_parent_rate;
++
++ enum cs2x00_type type;
+ };
+
+ static const struct of_device_id cs2000_of_match[] = {
+- { .compatible = "cirrus,cs2000-cp", },
++ { .compatible = "cirrus,cs2000-cp", .data = (void *)DEVICE_CS2000},
++ { .compatible = "cirrus,cs2300-cp", .data = (void *)DEVICE_CS2300},
+ {},
+ };
+ MODULE_DEVICE_TABLE(of, cs2000_of_match);
+
+ static const struct i2c_device_id cs2000_id[] = {
+- { "cs2000-cp", },
++ { "cs2000-cp", DEVICE_CS2000},
++ { "cs2300-cp", DEVICE_CS2300},
+ {}
+ };
+ MODULE_DEVICE_TABLE(i2c, cs2000_id);
+@@ -130,8 +143,13 @@ static int cs2000_enable_dev_config(struct cs2000_priv *priv, bool enable)
+ if (ret < 0)
+ return ret;
+
+- ret = cs2000_bset(priv, FUNC_CFG1, CLKSKIPEN,
+- enable ? CLKSKIPEN : 0);
++ if (priv->type == DEVICE_CS2000) {
++ ret = cs2000_bset(priv, FUNC_CFG1, CLKSKIPEN,
++ enable ? CLKSKIPEN : 0);
++ } else {
++ ret = cs2000_bset(priv, FUNC_CFG1, CLKSKIPEN | ENDEV3,
++ enable ? (CLKSKIPEN | ENDEV3) : 0);
++ }
+ if (ret < 0)
+ return ret;
+
+@@ -163,6 +181,15 @@ static int cs2000_clk_in_bound_rate(struct cs2000_priv *priv,
+ REFCLKDIV(val));
+ }
+
++
++static int cs2300_clk_rmod_set(struct cs2000_priv *priv,
++ u32 rmod)
++{
++ return cs2000_bset(priv, FUNC_CFG1,
++ RMODSEL_MASK,
++ RMODSEL(rmod));
++}
++
+ static int cs2000_wait_pll_lock(struct cs2000_priv *priv)
+ {
+ struct device *dev = priv_to_dev(priv);
+@@ -316,17 +343,27 @@ static int __cs2000_set_rate(struct cs2000_priv *priv, int ch,
+ {
+ int ret;
+
+- ret = cs2000_clk_in_bound_rate(priv, parent_rate);
+- if (ret < 0)
+- return ret;
++ if (priv->type == DEVICE_CS2000) {
++ ret = cs2000_clk_in_bound_rate(priv, parent_rate);
++ if (ret < 0)
++ return ret;
+
+- ret = cs2000_ratio_set(priv, ch, parent_rate, rate);
+- if (ret < 0)
+- return ret;
++ ret = cs2000_ratio_set(priv, ch, parent_rate, rate);
++ if (ret < 0)
++ return ret;
+
+- ret = cs2000_ratio_select(priv, ch);
+- if (ret < 0)
+- return ret;
++ ret = cs2000_ratio_select(priv, ch);
++ if (ret < 0)
++ return ret;
++ } else {
++ ret = cs2300_clk_rmod_set(priv, 0);
++ if (ret < 0)
++ return ret;
++
++ ret = cs2000_ratio_set(priv, 0, parent_rate, rate);
++ if (ret < 0)
++ return ret;
++ }
+
+ priv->saved_rate = rate;
+ priv->saved_parent_rate = parent_rate;
+@@ -383,8 +420,12 @@ static void cs2000_disable(struct clk_hw *hw)
+
+ static u8 cs2000_get_parent(struct clk_hw *hw)
+ {
+- /* always return REF_CLK */
+- return REF_CLK;
++ struct cs2000_priv *priv = hw_to_priv(hw);
++
++ if (priv->type == DEVICE_CS2000)
++ return REF_CLK;
++ else
++ return CLK_IN;
+ }
+
+ static const struct clk_ops cs2000_ops = {
+@@ -399,17 +440,19 @@ static const struct clk_ops cs2000_ops = {
+ static int cs2000_clk_get(struct cs2000_priv *priv)
+ {
+ struct device *dev = priv_to_dev(priv);
+- struct clk *clk_in, *ref_clk;
++ struct clk *clk_in, *ref_clk = NULL;
+
+ clk_in = devm_clk_get(dev, "clk_in");
+ /* not yet provided */
+ if (IS_ERR(clk_in))
+ return -EPROBE_DEFER;
+
+- ref_clk = devm_clk_get(dev, "ref_clk");
+- /* not yet provided */
+- if (IS_ERR(ref_clk))
+- return -EPROBE_DEFER;
++ if (priv->type == DEVICE_CS2000) {
++ ref_clk = devm_clk_get(dev, "ref_clk");
++ /* not yet provided */
++ if (IS_ERR(ref_clk))
++ return -EPROBE_DEFER;
++ }
+
+ priv->clk_in = clk_in;
+ priv->ref_clk = ref_clk;
+@@ -435,19 +478,26 @@ static int cs2000_clk_register(struct cs2000_priv *priv)
+ * otherwise .set_rate which setup ratio
+ * is never called if user requests 1/1 rate
+ */
+- rate = clk_get_rate(priv->ref_clk);
++ if (priv->type == DEVICE_CS2000)
++ rate = clk_get_rate(priv->ref_clk);
++ else
++ rate = clk_get_rate(priv->clk_in);
+ ret = __cs2000_set_rate(priv, ch, rate, rate);
+ if (ret < 0)
+ return ret;
+
+ parent_names[CLK_IN] = __clk_get_name(priv->clk_in);
+- parent_names[REF_CLK] = __clk_get_name(priv->ref_clk);
++ if (priv->type == DEVICE_CS2000)
++ parent_names[REF_CLK] = __clk_get_name(priv->ref_clk);
+
+ init.name = name;
+ init.ops = &cs2000_ops;
+ init.flags = CLK_SET_RATE_GATE;
+ init.parent_names = parent_names;
+- init.num_parents = ARRAY_SIZE(parent_names);
++ if (priv->type == DEVICE_CS2000)
++ init.num_parents = ARRAY_SIZE(parent_names);
++ else
++ init.num_parents = 1;
+
+ priv->hw.init = &init;
+
+@@ -474,7 +524,7 @@ static int cs2000_version_print(struct cs2000_priv *priv)
+ if (val < 0)
+ return val;
+
+- /* CS2000 should be 0x0 */
++ /* CS2000/CS2300 should be 0x0 */
+ if (val >> 3)
+ return -EIO;
+
+@@ -520,6 +570,7 @@ static int cs2000_probe(struct i2c_client *client,
+
+ priv->client = client;
+ i2c_set_clientdata(client, priv);
++ priv->type = (enum cs2x00_type)id->driver_data;
+
+ ret = cs2000_clk_get(priv);
+ if (ret < 0)
+@@ -556,7 +607,7 @@ static struct i2c_driver cs2000_driver = {
+ .driver = {
+ .name = "cs2000-cp",
+ .pm = &cs2000_pm_ops,
+- .of_match_table = cs2000_of_match,
++ .of_match_table = of_match_ptr(cs2000_of_match),
+ },
+ .probe = cs2000_probe,
+ .remove = cs2000_remove,
+--
+2.7.4
+
diff --git a/bsp/meta-rcar/meta-rcar-gen3-adas/recipes-kernel/linux/linux-renesas/0341-V3H-add-support-for-8-4-channel-VideoBox-board-from-.patch b/bsp/meta-rcar/meta-rcar-gen3-adas/recipes-kernel/linux/linux-renesas/0341-V3H-add-support-for-8-4-channel-VideoBox-board-from-.patch
new file mode 100644
index 00000000..7bd6f735
--- /dev/null
+++ b/bsp/meta-rcar/meta-rcar-gen3-adas/recipes-kernel/linux/linux-renesas/0341-V3H-add-support-for-8-4-channel-VideoBox-board-from-.patch
@@ -0,0 +1,1626 @@
+From ef57204bde1eecb536d2d321fa4a549c0d06787c Mon Sep 17 00:00:00 2001
+From: Andrey Dolnikov <andrey.dolnikov@cogentembedded.com>
+Date: Tue, 6 Nov 2018 16:48:39 +0300
+Subject: [PATCH 161/211] V3H: add support for 8/4 channel VideoBox board from
+ Cogent
+
+Signed-off-by: Andrey Gusakov <andrey.gusakov@cogentembedded.com>
+---
+ arch/arm64/boot/dts/renesas/Makefile | 1 +
+ .../boot/dts/renesas/r8a77980-v3hsk-vb-4ch.dts | 661 +++++++++++++++
+ .../boot/dts/renesas/r8a77980-v3hsk-vb-8ch.dts | 924 +++++++++++++++++++++
+ 3 files changed, 1586 insertions(+)
+ create mode 100644 arch/arm64/boot/dts/renesas/r8a77980-v3hsk-vb-4ch.dts
+ create mode 100644 arch/arm64/boot/dts/renesas/r8a77980-v3hsk-vb-8ch.dts
+
+diff --git a/arch/arm64/boot/dts/renesas/Makefile b/arch/arm64/boot/dts/renesas/Makefile
+index cac4b75..222df3d 100644
+--- a/arch/arm64/boot/dts/renesas/Makefile
++++ b/arch/arm64/boot/dts/renesas/Makefile
+@@ -43,5 +43,6 @@ dtb-$(CONFIG_ARCH_R8A77970) += r8a77970-v3msk-vbm-v2.dtb r8a77970-es1-v3msk-vbm-
+ dtb-$(CONFIG_ARCH_R8A77970) += r8a77970-v3mzf.dtb
+ dtb-$(CONFIG_ARCH_R8A77980) += r8a77980-v3hsk-vbm.dtb
+ dtb-$(CONFIG_ARCH_R8A77980) += r8a77980-v3hsk-vbm-v2.dtb
++dtb-$(CONFIG_ARCH_R8A77980) += r8a77980-v3hsk-vb-8ch.dtb r8a77980-v3hsk-vb-4ch.dtb
+
+ always := $(dtb-y)
+diff --git a/arch/arm64/boot/dts/renesas/r8a77980-v3hsk-vb-4ch.dts b/arch/arm64/boot/dts/renesas/r8a77980-v3hsk-vb-4ch.dts
+new file mode 100644
+index 0000000..1dd93fd
+--- /dev/null
++++ b/arch/arm64/boot/dts/renesas/r8a77980-v3hsk-vb-4ch.dts
+@@ -0,0 +1,661 @@
++/*
++ * Device Tree Source for the V3HSK Videobox Mini board on r8a7798
++ *
++ * Copyright (C) 2018 Cogent Embedded, Inc.
++ *
++ * This file is licensed under the terms of the GNU General Public License
++ * version 2. This program is licensed "as is" without any warranty of any
++ * kind, whether express or implied.
++ */
++
++#include "r8a77980-v3hsk.dts"
++#include <dt-bindings/gpio/gpio.h>
++
++/ {
++ model = "Renesas V3HSK 4ch Videobox board based on r8a7798";
++
++ aliases {
++ serial1 = &scif3;
++ ethernet1 = &avb;
++ };
++
++ cs2300_ref_clk: cs2300_ref_clk {
++ compatible = "fixed-clock";
++ #clock-cells = <0>;
++ clock-frequency = <25000000>;
++ };
++
++ leds {
++ compatible = "gpio-leds";
++
++ led0 {
++ label = "board:status";
++ gpios = <&gpio2 12 GPIO_ACTIVE_HIGH>;
++ linux,default-trigger = "none";
++ };
++ };
++
++ mpcie_1v8: regulator2 {
++ compatible = "regulator-fixed";
++ regulator-name = "mPCIe 1v8";
++ regulator-min-microvolt = <1800000>;
++ regulator-max-microvolt = <1800000>;
++ regulator-boot-on;
++ regulator-always-on;
++ };
++
++ mpcie_3v3: regulator3 {
++ compatible = "regulator-fixed";
++ regulator-name = "mPCIe 3v3";
++ regulator-min-microvolt = <3300000>;
++ regulator-max-microvolt = <3300000>;
++ regulator-boot-on;
++ regulator-always-on;
++ };
++
++ common_3v3: regulator4 {
++ compatible = "regulator-fixed";
++ regulator-name = "main 3v3";
++ regulator-min-microvolt = <3300000>;
++ regulator-max-microvolt = <3300000>;
++ regulator-boot-on;
++ regulator-always-on;
++ };
++};
++
++&canfd {
++ pinctrl-0 = <&canfd0_pins &canfd1_pins>;
++ pinctrl-names = "default";
++ status = "okay";
++
++ channel0 {
++ status = "okay";
++ };
++
++ channel1 {
++ status = "okay";
++ };
++};
++
++&avb {
++ pinctrl-0 = <&avb_pins>;
++ pinctrl-names = "default";
++ renesas,no-ether-link;
++ phy-handle = <&avb_phy0>;
++ status = "okay";
++ phy-int-gpio = <&gpio1 17 GPIO_ACTIVE_LOW>;
++
++ avb_phy0: eavb-phy@0 {
++ rxc-skew-ps = <1500>;
++ rxdv-skew-ps = <420>; /* default */
++ rxd0-skew-ps = <420>; /* default */
++ rxd1-skew-ps = <420>; /* default */
++ rxd2-skew-ps = <420>; /* default */
++ rxd3-skew-ps = <420>; /* default */
++ txc-skew-ps = <900>; /* default */
++ txen-skew-ps = <420>; /* default */
++ txd0-skew-ps = <420>; /* default */
++ txd1-skew-ps = <420>; /* default */
++ txd2-skew-ps = <420>; /* default */
++ txd3-skew-ps = <420>; /* default */
++ reg = <3>;
++ interrupt-parent = <&gpio1>;
++ interrupts = <17 IRQ_TYPE_LEVEL_LOW>;
++ max-speed = <1000>;
++ };
++};
++
++&csi40 {
++ status = "okay";
++
++ virtual,channel {
++ csi2_vc0 {
++ data,type = "ycbcr422";
++ receive,vc = <0>;
++ };
++ csi2_vc1 {
++ data,type = "ycbcr422";
++ receive,vc = <1>;
++ };
++ csi2_vc2 {
++ data,type = "ycbcr422";
++ receive,vc = <2>;
++ };
++ csi2_vc3 {
++ data,type = "ycbcr422";
++ receive,vc = <3>;
++ };
++ };
++
++ port {
++ #address-cells = <1>;
++ #size-cells = <0>;
++
++ csi2_40_ep: endpoint {
++ clock-lanes = <0>;
++ data-lanes = <1 2 3>;
++ csi-rate = <1450>;
++ };
++ };
++};
++
++&csi41 {
++ status = "okay";
++
++ virtual,channel {
++ csi2_vc0 {
++ data,type = "ycbcr422";
++ receive,vc = <0>;
++ };
++ csi2_vc1 {
++ data,type = "ycbcr422";
++ receive,vc = <1>;
++ };
++ csi2_vc2 {
++ data,type = "ycbcr422";
++ receive,vc = <2>;
++ };
++ csi2_vc3 {
++ data,type = "ycbcr422";
++ receive,vc = <3>;
++ };
++ };
++
++ port {
++ #address-cells = <1>;
++ #size-cells = <0>;
++
++ csi2_41_ep: endpoint {
++ clock-lanes = <0>;
++ data-lanes = <1 2 3>;
++ csi-rate = <1450>;
++ };
++ };
++};
++
++&i2c1 {
++ pinctrl-0 = <&i2c1_pins>;
++ pinctrl-names = "default";
++ status = "okay";
++
++ clock-frequency = <100000>;
++
++ i2cswitch1: i2c-switch@74 {
++ compatible = "nxp,pca9548";
++ #address-cells = <1>;
++ #size-cells = <0>;
++ reg = <0x74>;
++ reset-gpios = <&gpio2 28 GPIO_ACTIVE_LOW>;
++
++ /* DS0_SDA and DS0_SCL */
++ i2c@2 {
++ #address-cells = <1>;
++ #size-cells = <0>;
++ reg = <2>;
++
++ /* Deser #0 nodes here */
++ ov106xx@0 {
++ compatible = "ovti,ov106xx";
++ reg = <0x60>;
++
++ port@0 {
++ ov106xx_in0: endpoint {
++ clock-lanes = <0>;
++ data-lanes = <1 2 3>;
++ remote-endpoint = <&vin0ep0>;
++ };
++ };
++ port@1 {
++ ov106xx_ti9x4_des0ep0: endpoint@1 {
++ remote-endpoint = <&ti9x4_des0ep0>;
++ };
++ };
++ };
++
++ ov106xx@1 {
++ compatible = "ovti,ov106xx";
++ reg = <0x61>;
++
++ port@0 {
++ ov106xx_in1: endpoint {
++ clock-lanes = <0>;
++ data-lanes = <1 2 3>;
++ remote-endpoint = <&vin1ep0>;
++ };
++ };
++ port@1 {
++ ov106xx_ti9x4_des0ep1: endpoint@1 {
++ remote-endpoint = <&ti9x4_des0ep1>;
++ };
++ };
++ };
++
++ ov106xx@2 {
++ compatible = "ovti,ov106xx";
++ reg = <0x62>;
++
++ port@0 {
++ ov106xx_in2: endpoint {
++ clock-lanes = <0>;
++ data-lanes = <1 2 3>;
++ remote-endpoint = <&vin6ep0>;
++ };
++ };
++ port@1 {
++ ov106xx_ti9x4_des0ep2: endpoint@1 {
++ remote-endpoint = <&ti9x4_des0ep2>;
++ };
++ };
++ };
++
++ ov106xx@3 {
++ compatible = "ovti,ov106xx";
++ reg = <0x63>;
++
++ port@0 {
++ ov106xx_in3: endpoint {
++ clock-lanes = <0>;
++ data-lanes = <1 2 3>;
++ remote-endpoint = <&vin7ep0>;
++ };
++ };
++ port@1 {
++ ov106xx_ti9x4_des0ep3: endpoint@1 {
++ remote-endpoint = <&ti9x4_des0ep3>;
++ };
++ };
++ };
++
++ ti9x4@0 {
++ compatible = "ti,ti9x4";
++ clocks = <&cs2300>;
++ clock-names = "ref_clk";
++ reg = <0x3a>;
++ ti,links = <4>;
++ ti,lanes = <3>;
++ ti,forwarding-mode = "round-robin";
++ ti,cable-mode = "coax";
++ gpios = <&gpio_exp_ch0 13 GPIO_ACTIVE_LOW>;
++ POC0-gpios = <&gpio_exp_ch0 8 GPIO_ACTIVE_HIGH>;
++ POC1-gpios = <&gpio_exp_ch0 9 GPIO_ACTIVE_HIGH>;
++ POC2-gpios = <&gpio_exp_ch0 10 GPIO_ACTIVE_HIGH>;
++ POC3-gpios = <&gpio_exp_ch0 11 GPIO_ACTIVE_HIGH>;
++
++ port@0 {
++ ti9x4_des0ep0: endpoint@0 {
++ ti9x3-addr = <0x0c>;
++ dvp-order = <0>;
++ remote-endpoint = <&ov106xx_in0>;
++ };
++ ti9x4_des0ep1: endpoint@1 {
++ ti9x3-addr = <0x0d>;
++ dvp-order = <0>;
++ remote-endpoint = <&ov106xx_in1>;
++ };
++ ti9x4_des0ep2: endpoint@2 {
++ ti9x3-addr = <0x0e>;
++ dvp-order = <0>;
++ remote-endpoint = <&ov106xx_in2>;
++ };
++ ti9x4_des0ep3: endpoint@3 {
++ ti9x3-addr = <0x0f>;
++ dvp-order = <0>;
++ remote-endpoint = <&ov106xx_in3>;
++ };
++ };
++ port@1 {
++ ti9x4_csi0ep0: endpoint {
++ csi-rate = <1450>;
++ remote-endpoint = <&csi2_40_ep>;
++ };
++ };
++ };
++ };
++
++ /* CTL0_SDA and CTL0_SCL */
++ i2c@3 {
++ #address-cells = <1>;
++ #size-cells = <0>;
++ reg = <3>;
++
++ gpio_exp_ch0: gpio_ch0@6c {
++ compatible = "maxim,max7325";
++ reg = <0x6c>;
++ gpio-controller;
++ #gpio-cells = <2>;
++
++ ch0_virq {
++ gpio-hog;
++ gpios = <5 GPIO_ACTIVE_HIGH>;
++ input;
++ line-name = "CH0_VIRQ";
++ };
++ ch0_des_cfg0 {
++ gpio-hog;
++ gpios = <6 GPIO_ACTIVE_HIGH>;
++ input;
++ line-name = "CH0_CNFG0";
++ };
++ ch0_des_cfg1 {
++ gpio-hog;
++ gpios = <7 GPIO_ACTIVE_HIGH>;
++ input;
++ line-name = "CH0_CNFG1";
++ };
++ };
++ };
++
++ /* CTL1_SDA and CTL1_SCL */
++ i2c@0 {
++ #address-cells = <1>;
++ #size-cells = <0>;
++ reg = <0>;
++
++ /* CS2300 node @0x4e */
++ cs2300: clk_multiplier@4e {
++ #clock-cells = <0>;
++ compatible = "cirrus,cs2300-cp";
++ reg = <0x4e>;
++ clocks = <&cs2300_ref_clk>;
++ clock-names = "clk_in";
++
++ assigned-clocks = <&cs2300>;
++ assigned-clock-rates = <22500000>;
++ };
++ };
++
++ /* CMR_SDA and CMR_SCL */
++ i2c@4 {
++ #address-cells = <1>;
++ #size-cells = <0>;
++ reg = <4>;
++
++ dac_vcam: dac_vcam@60 {
++ compatible = "microchip,mcp4725";
++ reg = <0x60>;
++ vdd-supply = <&common_3v3>;
++ };
++ };
++
++ /* Disp_SDA and Disp_SCL */
++ i2c@5 {
++ #address-cells = <1>;
++ #size-cells = <0>;
++ reg = <5>;
++
++ /* fan node - lm96063 */
++ fan_ctrl: lm96063@4c {
++ compatible = "lm96163";
++ reg = <0x4c>;
++ };
++ };
++
++ /* ESDA and ESCL */
++ i2c@7 {
++ #address-cells = <1>;
++ #size-cells = <0>;
++ reg = <7>;
++
++ /* ext connector nodes here */
++ };
++
++ };
++};
++
++&gpio0 {
++ fpdl_shdn {
++ gpio-hog;
++ gpios = <1 GPIO_ACTIVE_HIGH>;
++ output-high;
++ line-name = "FPDL_SHDN";
++ };
++
++ cam_pwr_en {
++ gpio-hog;
++ gpios = <11 GPIO_ACTIVE_HIGH>;
++ output-high;
++ line-name = "VIPWR_En";
++ };
++
++ wake_pin_8 {
++ gpio-hog;
++ gpios = <0 GPIO_ACTIVE_HIGH>;
++ input;
++ line-name = "WAKE INPUT PIN 8";
++ };
++};
++
++&gpio1 {
++ md_buf_en {
++ gpio-hog;
++ gpios = <19 GPIO_ACTIVE_HIGH>;
++ output-high;
++ line-name = "CPLD_If_En";
++ };
++};
++
++&gpio2 {
++ m2_rst {
++ gpio-hog;
++ gpios = <11 GPIO_ACTIVE_HIGH>;
++ output-high;
++ line-name = "M.2 RST#";
++ };
++
++ can0_load {
++ gpio-hog;
++ gpios = <16 GPIO_ACTIVE_HIGH>;
++ output-high;
++ line-name = "CAN0Loff";
++ };
++
++ can0_stby {
++ gpio-hog;
++ gpios = <27 GPIO_ACTIVE_HIGH>;
++ output-high;
++ line-name = "CAN0STBY";
++ };
++
++ can1_load {
++ gpio-hog;
++ gpios = <29 GPIO_ACTIVE_HIGH>;
++ output-high;
++ line-name = "CAN1Loff";
++ };
++
++ can1_stby {
++ gpio-hog;
++ gpios = <22 GPIO_ACTIVE_HIGH>;
++ output-high;
++ line-name = "CAN1STBY";
++ };
++
++ wake_pin_7 {
++ gpio-hog;
++ gpios = <19 GPIO_ACTIVE_HIGH>;
++ input;
++ line-name = "WAKE INPUT PIN 7";
++ };
++
++ vi1_gpioext_rst {
++ gpio-hog;
++ gpios = <13 GPIO_ACTIVE_HIGH>;
++ output-high;
++ line-name = "VIP1_RST";
++ };
++};
++
++&gpio3 {
++ vi0_gpioext_rst {
++ gpio-hog;
++ gpios = <4 GPIO_ACTIVE_HIGH>;
++ output-high;
++ line-name = "VIP0_RST";
++ };
++};
++
++&pcie_bus_clk {
++ clock-frequency = <100000000>;
++ status = "okay";
++};
++
++&pciec {
++ pcie3v3-supply = <&mpcie_3v3>;
++ pcie1v8-supply = <&mpcie_1v8>;
++ status = "okay";
++};
++
++&pfc {
++ canfd0_pins: canfd0 {
++ groups = "canfd0_data_a";
++ function = "canfd0";
++ };
++
++ canfd1_pins: canfd1 {
++ groups = "canfd1_data";
++ function = "canfd1";
++ };
++
++ avb_pins: avb {
++ groups = "avb_mdc", "avb_mdio",
++ "avb_rx_ctrl", "avb_rxc",
++ "avb_rd4",
++ "avb_tx_ctrl", "avb_txc",
++ "avb_txcrefclk",
++ "avb_td4";
++ function = "avb";
++ };
++
++ i2c1_pins: i2c1 {
++ groups = "i2c1";
++ function = "i2c1";
++ };
++
++ scif3_pins: scif3 {
++ groups = "scif3_data";
++ function = "scif3";
++ };
++};
++
++&scif3 {
++ pinctrl-0 = <&scif3_pins>;
++ pinctrl-names = "default";
++
++ status = "okay";
++};
++
++&tpu {
++ status = "disabled";
++};
++
++&vin0 {
++ status = "okay";
++
++ ports {
++ #address-cells = <1>;
++ #size-cells = <0>;
++
++ port@0 {
++ vin0ep0: endpoint {
++ csi,select = "csi40";
++ virtual,channel = <0>;
++ data-lanes = <1 2 3>;
++ remote-endpoint = <&ov106xx_in0>;
++ };
++ };
++ port@1 {
++ csi0ep0: endpoint {
++ remote-endpoint = <&csi2_40_ep>;
++ };
++ };
++ port@2 {
++ vin0_ti9x4_des0ep0: endpoint@1 {
++ remote-endpoint = <&ti9x4_des0ep0>;
++ };
++ };
++ };
++};
++
++&vin1 {
++ status = "okay";
++
++ ports {
++ #address-cells = <1>;
++ #size-cells = <0>;
++
++ port@0 {
++ vin1ep0: endpoint {
++ csi,select = "csi40";
++ virtual,channel = <1>;
++ data-lanes = <1 2 3>;
++ remote-endpoint = <&ov106xx_in1>;
++ };
++ };
++ port@1 {
++ csi0ep1: endpoint {
++ remote-endpoint = <&csi2_40_ep>;
++ };
++ };
++ port@2 {
++ vin1_ti9x4_des0ep1: endpoint@1 {
++ remote-endpoint = <&ti9x4_des0ep1>;
++ };
++ };
++ };
++};
++
++&vin6 {
++ status = "okay";
++
++ ports {
++ #address-cells = <1>;
++ #size-cells = <0>;
++
++ port@0 {
++ vin6ep0: endpoint {
++ csi,select = "csi41";
++ virtual,channel = <2>;
++ data-lanes = <1 2 3>;
++ remote-endpoint = <&ov106xx_in2>;
++ };
++ };
++ port@1 {
++ csi1ep2: endpoint {
++ remote-endpoint = <&csi2_41_ep>;
++ };
++ };
++ port@2 {
++ vin6_ti9x4_des0ep2: endpoint@1 {
++ remote-endpoint = <&ti9x4_des0ep2>;
++ };
++ };
++ };
++};
++
++&vin7 {
++ status = "okay";
++
++ ports {
++ #address-cells = <1>;
++ #size-cells = <0>;
++
++ port@0 {
++ vin7ep0: endpoint {
++ csi,select = "csi41";
++ virtual,channel = <3>;
++ data-lanes = <1 2 3>;
++ remote-endpoint = <&ov106xx_in3>;
++ };
++ };
++ port@1 {
++ csi1ep3: endpoint {
++ remote-endpoint = <&csi2_41_ep>;
++ };
++ };
++ port@2 {
++ vin7_ti9x4_des0ep3: endpoint@1 {
++ remote-endpoint = <&ti9x4_des0ep3>;
++ };
++ };
++ };
++};
+diff --git a/arch/arm64/boot/dts/renesas/r8a77980-v3hsk-vb-8ch.dts b/arch/arm64/boot/dts/renesas/r8a77980-v3hsk-vb-8ch.dts
+new file mode 100644
+index 0000000..0db52f4
+--- /dev/null
++++ b/arch/arm64/boot/dts/renesas/r8a77980-v3hsk-vb-8ch.dts
+@@ -0,0 +1,924 @@
++/*
++ * Device Tree Source for the V3HSK Videobox Mini board on r8a7798
++ *
++ * Copyright (C) 2018 Cogent Embedded, Inc.
++ *
++ * This file is licensed under the terms of the GNU General Public License
++ * version 2. This program is licensed "as is" without any warranty of any
++ * kind, whether express or implied.
++ */
++
++#include "r8a77980-v3hsk.dts"
++#include <dt-bindings/gpio/gpio.h>
++
++/ {
++ model = "Renesas V3HSK 4ch Videobox board based on r8a7798";
++
++ aliases {
++ serial1 = &scif3;
++ ethernet1 = &avb;
++ };
++
++ cs2300_ref_clk: cs2300_ref_clk {
++ compatible = "fixed-clock";
++ #clock-cells = <0>;
++ clock-frequency = <25000000>;
++ };
++
++ leds {
++ compatible = "gpio-leds";
++
++ led0 {
++ label = "board:status";
++ gpios = <&gpio2 12 GPIO_ACTIVE_HIGH>;
++ linux,default-trigger = "none";
++ };
++ };
++
++ mpcie_1v8: regulator2 {
++ compatible = "regulator-fixed";
++ regulator-name = "mPCIe 1v8";
++ regulator-min-microvolt = <1800000>;
++ regulator-max-microvolt = <1800000>;
++ regulator-boot-on;
++ regulator-always-on;
++ };
++
++ mpcie_3v3: regulator3 {
++ compatible = "regulator-fixed";
++ regulator-name = "mPCIe 3v3";
++ regulator-min-microvolt = <3300000>;
++ regulator-max-microvolt = <3300000>;
++ regulator-boot-on;
++ regulator-always-on;
++ };
++
++ common_3v3: regulator4 {
++ compatible = "regulator-fixed";
++ regulator-name = "main 3v3";
++ regulator-min-microvolt = <3300000>;
++ regulator-max-microvolt = <3300000>;
++ regulator-boot-on;
++ regulator-always-on;
++ };
++};
++
++&canfd {
++ pinctrl-0 = <&canfd0_pins &canfd1_pins>;
++ pinctrl-names = "default";
++ status = "okay";
++
++ channel0 {
++ status = "okay";
++ };
++
++ channel1 {
++ status = "okay";
++ };
++};
++
++&avb {
++ pinctrl-0 = <&avb_pins>;
++ pinctrl-names = "default";
++ renesas,no-ether-link;
++ phy-handle = <&avb_phy0>;
++ status = "okay";
++ phy-int-gpio = <&gpio1 17 GPIO_ACTIVE_LOW>;
++
++ avb_phy0: eavb-phy@0 {
++ rxc-skew-ps = <1500>;
++ rxdv-skew-ps = <420>; /* default */
++ rxd0-skew-ps = <420>; /* default */
++ rxd1-skew-ps = <420>; /* default */
++ rxd2-skew-ps = <420>; /* default */
++ rxd3-skew-ps = <420>; /* default */
++ txc-skew-ps = <900>; /* default */
++ txen-skew-ps = <420>; /* default */
++ txd0-skew-ps = <420>; /* default */
++ txd1-skew-ps = <420>; /* default */
++ txd2-skew-ps = <420>; /* default */
++ txd3-skew-ps = <420>; /* default */
++ reg = <3>;
++ interrupt-parent = <&gpio1>;
++ interrupts = <17 IRQ_TYPE_LEVEL_LOW>;
++ max-speed = <1000>;
++ };
++};
++
++&csi40 {
++ status = "okay";
++
++ virtual,channel {
++ csi2_vc0 {
++ data,type = "ycbcr422";
++ receive,vc = <0>;
++ };
++ csi2_vc1 {
++ data,type = "ycbcr422";
++ receive,vc = <1>;
++ };
++ csi2_vc2 {
++ data,type = "ycbcr422";
++ receive,vc = <2>;
++ };
++ csi2_vc3 {
++ data,type = "ycbcr422";
++ receive,vc = <3>;
++ };
++ };
++
++ port {
++ #address-cells = <1>;
++ #size-cells = <0>;
++
++ csi2_40_ep: endpoint {
++ clock-lanes = <0>;
++ data-lanes = <1 2 3 4>;
++ csi-rate = <1450>;
++ };
++ };
++};
++
++&csi41 {
++ status = "okay";
++
++ virtual,channel {
++ csi2_vc0 {
++ data,type = "ycbcr422";
++ receive,vc = <0>;
++ };
++ csi2_vc1 {
++ data,type = "ycbcr422";
++ receive,vc = <1>;
++ };
++ csi2_vc2 {
++ data,type = "ycbcr422";
++ receive,vc = <2>;
++ };
++ csi2_vc3 {
++ data,type = "ycbcr422";
++ receive,vc = <3>;
++ };
++ };
++
++ port {
++ #address-cells = <1>;
++ #size-cells = <0>;
++
++ csi2_41_ep: endpoint {
++ clock-lanes = <0>;
++ data-lanes = <1 2 3>;
++ csi-rate = <1450>;
++ };
++ };
++};
++
++&i2c1 {
++ pinctrl-0 = <&i2c1_pins>;
++ pinctrl-names = "default";
++ status = "okay";
++
++ clock-frequency = <100000>;
++
++ i2cswitch1: i2c-switch@74 {
++ compatible = "nxp,pca9548";
++ #address-cells = <1>;
++ #size-cells = <0>;
++ reg = <0x74>;
++ reset-gpios = <&gpio2 28 GPIO_ACTIVE_LOW>;
++
++ /* DS0_SDA and DS0_SCL */
++ i2c@2 {
++ #address-cells = <1>;
++ #size-cells = <0>;
++ reg = <2>;
++
++ /* Deser #0 nodes here */
++ ov106xx@0 {
++ compatible = "ovti,ov106xx";
++ reg = <0x60>;
++
++ port@0 {
++ ov106xx_in0: endpoint {
++ clock-lanes = <0>;
++ data-lanes = <1 2 3 4>;
++ remote-endpoint = <&vin0ep0>;
++ };
++ };
++ port@1 {
++ ov106xx_ti9x4_des0ep0: endpoint@1 {
++ remote-endpoint = <&ti9x4_des0ep0>;
++ };
++ };
++ };
++
++ ov106xx@1 {
++ compatible = "ovti,ov106xx";
++ reg = <0x61>;
++
++ port@0 {
++ ov106xx_in1: endpoint {
++ clock-lanes = <0>;
++ data-lanes = <1 2 3 4>;
++ remote-endpoint = <&vin1ep0>;
++ };
++ };
++ port@1 {
++ ov106xx_ti9x4_des0ep1: endpoint@1 {
++ remote-endpoint = <&ti9x4_des0ep1>;
++ };
++ };
++ };
++
++ ov106xx@2 {
++ compatible = "ovti,ov106xx";
++ reg = <0x62>;
++
++ port@0 {
++ ov106xx_in2: endpoint {
++ clock-lanes = <0>;
++ data-lanes = <1 2 3 4>;
++ remote-endpoint = <&vin2ep0>;
++ };
++ };
++ port@1 {
++ ov106xx_ti9x4_des0ep2: endpoint@1 {
++ remote-endpoint = <&ti9x4_des0ep2>;
++ };
++ };
++ };
++
++ ov106xx@3 {
++ compatible = "ovti,ov106xx";
++ reg = <0x63>;
++
++ port@0 {
++ ov106xx_in3: endpoint {
++ clock-lanes = <0>;
++ data-lanes = <1 2 3 4>;
++ remote-endpoint = <&vin3ep0>;
++ };
++ };
++ port@1 {
++ ov106xx_ti9x4_des0ep3: endpoint@1 {
++ remote-endpoint = <&ti9x4_des0ep3>;
++ };
++ };
++ };
++
++ ti9x4@0 {
++ compatible = "ti,ti9x4";
++ reg = <0x3a>;
++ clocks = <&cs2300>;
++ clock-names = "ref_clk";
++ ti,links = <4>;
++ ti,lanes = <4>;
++ ti,forwarding-mode = "round-robin";
++ ti,cable-mode = "coax";
++ gpios = <&gpio_exp_ch0 13 GPIO_ACTIVE_LOW>;
++ POC0-gpios = <&gpio_exp_ch0 8 GPIO_ACTIVE_HIGH>;
++ POC1-gpios = <&gpio_exp_ch0 9 GPIO_ACTIVE_HIGH>;
++ POC2-gpios = <&gpio_exp_ch0 10 GPIO_ACTIVE_HIGH>;
++ POC3-gpios = <&gpio_exp_ch0 11 GPIO_ACTIVE_HIGH>;
++
++ port@0 {
++ ti9x4_des0ep0: endpoint@0 {
++ ti9x3-addr = <0x0c>;
++ dvp-order = <0>;
++ remote-endpoint = <&ov106xx_in0>;
++ };
++ ti9x4_des0ep1: endpoint@1 {
++ ti9x3-addr = <0x0d>;
++ dvp-order = <0>;
++ remote-endpoint = <&ov106xx_in1>;
++ };
++ ti9x4_des0ep2: endpoint@2 {
++ ti9x3-addr = <0x0e>;
++ dvp-order = <0>;
++ remote-endpoint = <&ov106xx_in2>;
++ };
++ ti9x4_des0ep3: endpoint@3 {
++ ti9x3-addr = <0x0f>;
++ dvp-order = <0>;
++ remote-endpoint = <&ov106xx_in3>;
++ };
++ };
++ port@1 {
++ ti9x4_csi0ep0: endpoint {
++ csi-rate = <1450>;
++ remote-endpoint = <&csi2_40_ep>;
++ };
++ };
++ };
++ };
++
++ /* CTL0_SDA and CTL0_SCL */
++ i2c@3 {
++ #address-cells = <1>;
++ #size-cells = <0>;
++ reg = <3>;
++
++ gpio_exp_ch0: gpio_ch0@6c {
++ compatible = "maxim,max7325";
++ reg = <0x6c>;
++ gpio-controller;
++ #gpio-cells = <2>;
++
++ ch0_virq {
++ gpio-hog;
++ gpios = <5 GPIO_ACTIVE_HIGH>;
++ input;
++ line-name = "CH0_VIRQ";
++ };
++ ch0_des_cfg0 {
++ gpio-hog;
++ gpios = <6 GPIO_ACTIVE_HIGH>;
++ input;
++ line-name = "CH0_CNFG0";
++ };
++ ch0_des_cfg1 {
++ gpio-hog;
++ gpios = <7 GPIO_ACTIVE_HIGH>;
++ input;
++ line-name = "CH0_CNFG1";
++ };
++ };
++ };
++
++ /* DS1_SDA and DS1_SCL */
++ i2c@1 {
++ #address-cells = <1>;
++ #size-cells = <0>;
++ reg = <1>;
++
++ /* Deser #1 nodes here */
++ ov106xx@4 {
++ compatible = "ovti,ov106xx";
++ reg = <0x60>;
++
++ port@0 {
++ ov106xx_in4: endpoint {
++ clock-lanes = <0>;
++ data-lanes = <1 2 3>;
++ remote-endpoint = <&vin4ep0>;
++ };
++ };
++ port@1 {
++ ov106xx_ti9x4_des1ep0: endpoint@1 {
++ remote-endpoint = <&ti9x4_des1ep0>;
++ };
++ };
++ };
++
++ ov106xx@5 {
++ compatible = "ovti,ov106xx";
++ reg = <0x61>;
++
++ port@0 {
++ ov106xx_in5: endpoint {
++ clock-lanes = <0>;
++ data-lanes = <1 2 3>;
++ remote-endpoint = <&vin5ep0>;
++ };
++ };
++ port@1 {
++ ov106xx_ti9x4_des1ep1: endpoint@1 {
++ remote-endpoint = <&ti9x4_des1ep1>;
++ };
++ };
++ };
++
++ ov106xx@6 {
++ compatible = "ovti,ov106xx";
++ reg = <0x62>;
++
++ port@0 {
++ ov106xx_in6: endpoint {
++ clock-lanes = <0>;
++ data-lanes = <1 2 3>;
++ remote-endpoint = <&vin6ep0>;
++ };
++ };
++ port@1 {
++ ov106xx_ti9x4_des1ep2: endpoint@1 {
++ remote-endpoint = <&ti9x4_des1ep2>;
++ };
++ };
++ };
++
++ ov106xx@7 {
++ compatible = "ovti,ov106xx";
++ reg = <0x63>;
++
++ port@0 {
++ ov106xx_in7: endpoint {
++ clock-lanes = <0>;
++ data-lanes = <1 2 3>;
++ remote-endpoint = <&vin7ep0>;
++ };
++ };
++ port@1 {
++ ov106xx_ti9x4_des1ep3: endpoint@1 {
++ remote-endpoint = <&ti9x4_des1ep3>;
++ };
++ };
++ };
++
++ ti9x4@1 {
++ compatible = "ti,ti9x4";
++ clocks = <&cs2300>;
++ clock-names = "ref_clk";
++ reg = <0x3a>;
++ ti,links = <4>;
++ ti,lanes = <3>;
++ ti,forwarding-mode = "round-robin";
++ ti,cable-mode = "coax";
++ gpios = <&gpio_exp_ch1 13 GPIO_ACTIVE_LOW>;
++ POC0-gpios = <&gpio_exp_ch1 8 GPIO_ACTIVE_HIGH>;
++ POC1-gpios = <&gpio_exp_ch1 9 GPIO_ACTIVE_HIGH>;
++ POC2-gpios = <&gpio_exp_ch1 10 GPIO_ACTIVE_HIGH>;
++ POC3-gpios = <&gpio_exp_ch1 11 GPIO_ACTIVE_HIGH>;
++
++ port@0 {
++ ti9x4_des1ep0: endpoint@0 {
++ ti9x3-addr = <0x0c>;
++ dvp-order = <0>;
++ remote-endpoint = <&ov106xx_in4>;
++ };
++ ti9x4_des1ep1: endpoint@1 {
++ ti9x3-addr = <0x0d>;
++ dvp-order = <0>;
++ remote-endpoint = <&ov106xx_in5>;
++ };
++ ti9x4_des1ep2: endpoint@2 {
++ ti9x3-addr = <0x0e>;
++ dvp-order = <0>;
++ remote-endpoint = <&ov106xx_in6>;
++ };
++ ti9x4_des1ep3: endpoint@3 {
++ ti9x3-addr = <0x0f>;
++ dvp-order = <0>;
++ remote-endpoint = <&ov106xx_in7>;
++ };
++ };
++ port@1 {
++ ti9x4_csi1ep0: endpoint {
++ csi-rate = <1450>;
++ remote-endpoint = <&csi2_41_ep>;
++ };
++ };
++ };
++ };
++
++ /* CTL1_SDA and CTL1_SCL */
++ i2c@0 {
++ #address-cells = <1>;
++ #size-cells = <0>;
++ reg = <0>;
++
++ /* CS2300 node @0x4e */
++ cs2300: clk_multiplier@4e {
++ #clock-cells = <0>;
++ compatible = "cirrus,cs2300-cp";
++ reg = <0x4e>;
++ clocks = <&cs2300_ref_clk>;
++ clock-names = "clk_in";
++
++ assigned-clocks = <&cs2300>;
++ assigned-clock-rates = <22500000>;
++ };
++
++ gpio_exp_ch1: gpio_ch1@6c {
++ compatible = "maxim,max7325";
++ reg = <0x6c>;
++ gpio-controller;
++ #gpio-cells = <2>;
++
++ ch1_virq {
++ gpio-hog;
++ gpios = <5 GPIO_ACTIVE_HIGH>;
++ input;
++ line-name = "CH1_VIRQ";
++ };
++ ch1_des_cfg0 {
++ gpio-hog;
++ gpios = <6 GPIO_ACTIVE_HIGH>;
++ input;
++ line-name = "CH1_CNFG0";
++ };
++ ch1_des_cfg1 {
++ gpio-hog;
++ gpios = <7 GPIO_ACTIVE_HIGH>;
++ input;
++ line-name = "CH1_CNFG1";
++ };
++ };
++ };
++
++ /* CMR_SDA and CMR_SCL */
++ i2c@4 {
++ #address-cells = <1>;
++ #size-cells = <0>;
++ reg = <4>;
++
++ dac_vcam: dac_vcam@60 {
++ compatible = "microchip,mcp4725";
++ reg = <0x60>;
++ vdd-supply = <&common_3v3>;
++ };
++ };
++
++ /* Disp_SDA and Disp_SCL */
++ i2c@5 {
++ #address-cells = <1>;
++ #size-cells = <0>;
++ reg = <5>;
++
++ /* fan node - lm96063 */
++ fan_ctrl: lm96063@4c {
++ compatible = "lm96163";
++ reg = <0x4c>;
++ };
++ };
++
++ /* ESDA and ESCL */
++ i2c@7 {
++ #address-cells = <1>;
++ #size-cells = <0>;
++ reg = <7>;
++
++ /* ext connector nodes here */
++ };
++
++ };
++};
++
++&gpio0 {
++ fpdl_shdn {
++ gpio-hog;
++ gpios = <1 GPIO_ACTIVE_HIGH>;
++ output-high;
++ line-name = "FPDL_SHDN";
++ };
++
++ cam_pwr_en {
++ gpio-hog;
++ gpios = <11 GPIO_ACTIVE_HIGH>;
++ output-high;
++ line-name = "VIPWR_En";
++ };
++
++ wake_pin_8 {
++ gpio-hog;
++ gpios = <0 GPIO_ACTIVE_HIGH>;
++ input;
++ line-name = "WAKE INPUT PIN 8";
++ };
++};
++
++&gpio1 {
++ md_buf_en {
++ gpio-hog;
++ gpios = <19 GPIO_ACTIVE_HIGH>;
++ output-high;
++ line-name = "CPLD_If_En";
++ };
++};
++
++&gpio2 {
++ m2_rst {
++ gpio-hog;
++ gpios = <11 GPIO_ACTIVE_HIGH>;
++ output-high;
++ line-name = "M.2 RST#";
++ };
++
++ can0_load {
++ gpio-hog;
++ gpios = <16 GPIO_ACTIVE_HIGH>;
++ output-high;
++ line-name = "CAN0Loff";
++ };
++
++ can0_stby {
++ gpio-hog;
++ gpios = <27 GPIO_ACTIVE_HIGH>;
++ output-high;
++ line-name = "CAN0STBY";
++ };
++
++ can1_load {
++ gpio-hog;
++ gpios = <29 GPIO_ACTIVE_HIGH>;
++ output-high;
++ line-name = "CAN1Loff";
++ };
++
++ can1_stby {
++ gpio-hog;
++ gpios = <22 GPIO_ACTIVE_HIGH>;
++ output-high;
++ line-name = "CAN1STBY";
++ };
++
++ wake_pin_7 {
++ gpio-hog;
++ gpios = <19 GPIO_ACTIVE_HIGH>;
++ input;
++ line-name = "WAKE INPUT PIN 7";
++ };
++
++ vi1_gpioext_rst {
++ gpio-hog;
++ gpios = <13 GPIO_ACTIVE_HIGH>;
++ output-high;
++ line-name = "VIP1_RST";
++ };
++};
++
++&gpio3 {
++ vi0_gpioext_rst {
++ gpio-hog;
++ gpios = <4 GPIO_ACTIVE_HIGH>;
++ output-high;
++ line-name = "VIP0_RST";
++ };
++};
++
++&pcie_bus_clk {
++ clock-frequency = <100000000>;
++ status = "okay";
++};
++
++&pciec {
++ pcie3v3-supply = <&mpcie_3v3>;
++ pcie1v8-supply = <&mpcie_1v8>;
++ status = "okay";
++};
++
++&pfc {
++ canfd0_pins: canfd0 {
++ groups = "canfd0_data_a";
++ function = "canfd0";
++ };
++
++ canfd1_pins: canfd1 {
++ groups = "canfd1_data";
++ function = "canfd1";
++ };
++
++ avb_pins: avb {
++ groups = "avb_mdc", "avb_mdio",
++ "avb_rx_ctrl", "avb_rxc",
++ "avb_rd4",
++ "avb_tx_ctrl", "avb_txc",
++ "avb_txcrefclk",
++ "avb_td4";
++ function = "avb";
++ };
++
++ i2c1_pins: i2c1 {
++ groups = "i2c1";
++ function = "i2c1";
++ };
++
++ scif3_pins: scif3 {
++ groups = "scif3_data";
++ function = "scif3";
++ };
++};
++
++&scif3 {
++ pinctrl-0 = <&scif3_pins>;
++ pinctrl-names = "default";
++
++ status = "okay";
++};
++
++&tpu {
++ status = "disabled";
++};
++
++&vin0 {
++ status = "okay";
++
++ ports {
++ #address-cells = <1>;
++ #size-cells = <0>;
++
++ port@0 {
++ vin0ep0: endpoint {
++ csi,select = "csi40";
++ virtual,channel = <0>;
++ data-lanes = <1 2 3 4>;
++ remote-endpoint = <&ov106xx_in0>;
++ };
++ };
++ port@1 {
++ csi0ep0: endpoint {
++ remote-endpoint = <&csi2_40_ep>;
++ };
++ };
++ port@2 {
++ vin0_ti9x4_des0ep0: endpoint@1 {
++ remote-endpoint = <&ti9x4_des0ep0>;
++ };
++ };
++ };
++};
++
++&vin1 {
++ status = "okay";
++
++ ports {
++ #address-cells = <1>;
++ #size-cells = <0>;
++
++ port@0 {
++ vin1ep0: endpoint {
++ csi,select = "csi40";
++ virtual,channel = <1>;
++ data-lanes = <1 2 3 4>;
++ remote-endpoint = <&ov106xx_in1>;
++ };
++ };
++ port@1 {
++ csi0ep1: endpoint {
++ remote-endpoint = <&csi2_40_ep>;
++ };
++ };
++ port@2 {
++ vin1_ti9x4_des0ep1: endpoint@1 {
++ remote-endpoint = <&ti9x4_des0ep1>;
++ };
++ };
++ };
++};
++
++&vin2 {
++ status = "okay";
++
++ ports {
++ #address-cells = <1>;
++ #size-cells = <0>;
++
++ port@0 {
++ vin2ep0: endpoint {
++ csi,select = "csi40";
++ virtual,channel = <2>;
++ data-lanes = <1 2 3 4>;
++ remote-endpoint = <&ov106xx_in2>;
++ };
++ };
++ port@1 {
++ csi0ep2: endpoint {
++ remote-endpoint = <&csi2_40_ep>;
++ };
++ };
++ port@2 {
++ vin6_ti9x4_des0ep2: endpoint@1 {
++ remote-endpoint = <&ti9x4_des0ep2>;
++ };
++ };
++ };
++};
++
++&vin3 {
++ status = "okay";
++
++ ports {
++ #address-cells = <1>;
++ #size-cells = <0>;
++
++ port@0 {
++ vin3ep0: endpoint {
++ csi,select = "csi40";
++ virtual,channel = <3>;
++ data-lanes = <1 2 3 4>;
++ remote-endpoint = <&ov106xx_in3>;
++ };
++ };
++ port@1 {
++ csi0ep3: endpoint {
++ remote-endpoint = <&csi2_40_ep>;
++ };
++ };
++ port@2 {
++ vin7_ti9x4_des0ep3: endpoint@1 {
++ remote-endpoint = <&ti9x4_des0ep3>;
++ };
++ };
++ };
++};
++
++&vin4 {
++ status = "okay";
++
++ ports {
++ #address-cells = <1>;
++ #size-cells = <0>;
++
++ port@0 {
++ vin4ep0: endpoint {
++ csi,select = "csi41";
++ virtual,channel = <0>;
++ data-lanes = <1 2 3>;
++ remote-endpoint = <&ov106xx_in4>;
++ };
++ };
++ port@1 {
++ csi1ep0: endpoint {
++ remote-endpoint = <&csi2_41_ep>;
++ };
++ };
++ port@2 {
++ vin4_ti9x4_des0ep0: endpoint@1 {
++ remote-endpoint = <&ti9x4_des1ep0>;
++ };
++ };
++ };
++};
++
++&vin5 {
++ status = "okay";
++
++ ports {
++ #address-cells = <1>;
++ #size-cells = <0>;
++
++ port@0 {
++ vin5ep0: endpoint {
++ csi,select = "csi41";
++ virtual,channel = <1>;
++ data-lanes = <1 2 3>;
++ remote-endpoint = <&ov106xx_in5>;
++ };
++ };
++ port@1 {
++ csi1ep1: endpoint {
++ remote-endpoint = <&csi2_41_ep>;
++ };
++ };
++ port@2 {
++ vin5_ti9x4_des1ep1: endpoint@1 {
++ remote-endpoint = <&ti9x4_des1ep1>;
++ };
++ };
++ };
++};
++
++&vin6 {
++ status = "okay";
++
++ ports {
++ #address-cells = <1>;
++ #size-cells = <0>;
++
++ port@0 {
++ vin6ep0: endpoint {
++ csi,select = "csi41";
++ virtual,channel = <2>;
++ data-lanes = <1 2 3>;
++ remote-endpoint = <&ov106xx_in6>;
++ };
++ };
++ port@1 {
++ csi1ep2: endpoint {
++ remote-endpoint = <&csi2_41_ep>;
++ };
++ };
++ port@2 {
++ vin6_ti9x4_des1ep2: endpoint@1 {
++ remote-endpoint = <&ti9x4_des1ep2>;
++ };
++ };
++ };
++};
++
++&vin7 {
++ status = "okay";
++
++ ports {
++ #address-cells = <1>;
++ #size-cells = <0>;
++
++ port@0 {
++ vin7ep0: endpoint {
++ csi,select = "csi41";
++ virtual,channel = <3>;
++ data-lanes = <1 2 3>;
++ remote-endpoint = <&ov106xx_in7>;
++ };
++ };
++ port@1 {
++ csi1ep3: endpoint {
++ remote-endpoint = <&csi2_41_ep>;
++ };
++ };
++ port@2 {
++ vin7_ti9x4_des1ep3: endpoint@1 {
++ remote-endpoint = <&ti9x4_des1ep3>;
++ };
++ };
++ };
++};
+--
+2.7.4
+
diff --git a/bsp/meta-rcar/meta-rcar-gen3-adas/recipes-kernel/linux/linux-renesas/0342-arm64-dts-r8a77970-Videobox-Mini-V3-board-support.patch b/bsp/meta-rcar/meta-rcar-gen3-adas/recipes-kernel/linux/linux-renesas/0342-arm64-dts-r8a77970-Videobox-Mini-V3-board-support.patch
new file mode 100644
index 00000000..e7c1c5f0
--- /dev/null
+++ b/bsp/meta-rcar/meta-rcar-gen3-adas/recipes-kernel/linux/linux-renesas/0342-arm64-dts-r8a77970-Videobox-Mini-V3-board-support.patch
@@ -0,0 +1,95 @@
+From 3e52f48ee3314fef332d057cb0c869aec7f9ed26 Mon Sep 17 00:00:00 2001
+From: Andrey Dolnikov <andrey.dolnikov@cogentembedded.com>
+Date: Tue, 6 Nov 2018 18:26:49 +0300
+Subject: [PATCH 162/211] arm64: dts: r8a77970: Videobox Mini V3 board support.
+
+---
+ arch/arm64/boot/dts/renesas/Makefile | 1 +
+ .../boot/dts/renesas/r8a77970-es1-v3msk-vbm-v3.dts | 17 ++++++++++
+ .../boot/dts/renesas/r8a77970-v3msk-vbm-v3.dts | 38 ++++++++++++++++++++++
+ 3 files changed, 56 insertions(+)
+ create mode 100644 arch/arm64/boot/dts/renesas/r8a77970-es1-v3msk-vbm-v3.dts
+ create mode 100644 arch/arm64/boot/dts/renesas/r8a77970-v3msk-vbm-v3.dts
+
+diff --git a/arch/arm64/boot/dts/renesas/Makefile b/arch/arm64/boot/dts/renesas/Makefile
+index 222df3d..4ccf641 100644
+--- a/arch/arm64/boot/dts/renesas/Makefile
++++ b/arch/arm64/boot/dts/renesas/Makefile
+@@ -40,6 +40,7 @@ dtb-$(CONFIG_ARCH_R8A77970) += r8a77970-v3msk-view.dtb r8a77970-es1-v3msk-view.d
+ dtb-$(CONFIG_ARCH_R8A77970) += r8a77970-v3msk-kf.dtb r8a77970-es1-v3msk-kf.dtb
+ dtb-$(CONFIG_ARCH_R8A77970) += r8a77970-v3msk-vbm.dtb r8a77970-es1-v3msk-vbm.dtb
+ dtb-$(CONFIG_ARCH_R8A77970) += r8a77970-v3msk-vbm-v2.dtb r8a77970-es1-v3msk-vbm-v2.dtb
++dtb-$(CONFIG_ARCH_R8A77970) += r8a77970-v3msk-vbm-v3.dtb r8a77970-es1-v3msk-vbm-v3.dtb
+ dtb-$(CONFIG_ARCH_R8A77970) += r8a77970-v3mzf.dtb
+ dtb-$(CONFIG_ARCH_R8A77980) += r8a77980-v3hsk-vbm.dtb
+ dtb-$(CONFIG_ARCH_R8A77980) += r8a77980-v3hsk-vbm-v2.dtb
+diff --git a/arch/arm64/boot/dts/renesas/r8a77970-es1-v3msk-vbm-v3.dts b/arch/arm64/boot/dts/renesas/r8a77970-es1-v3msk-vbm-v3.dts
+new file mode 100644
+index 0000000..32ace13
+--- /dev/null
++++ b/arch/arm64/boot/dts/renesas/r8a77970-es1-v3msk-vbm-v3.dts
+@@ -0,0 +1,17 @@
++/*
++ * Device Tree Source for the V3MSK Videobox Mini V2 board on r8a7797 ES1.0
++ *
++ * Copyright (C) 2018 Renesas Electronics Corp.
++ * Copyright (C) 2018 Cogent Embedded, Inc.
++ *
++ * This file is licensed under the terms of the GNU General Public License
++ * version 2. This program is licensed "as is" without any warranty of any
++ * kind, whether express or implied.
++ */
++
++#include "r8a77970-v3msk-vbm-v3.dts"
++#include "r8a77970-es1.dtsi"
++
++/ {
++ model = "Renesas V3MSK Videobox Mini V3 board based on r8a7797 ES1.0";
++};
+diff --git a/arch/arm64/boot/dts/renesas/r8a77970-v3msk-vbm-v3.dts b/arch/arm64/boot/dts/renesas/r8a77970-v3msk-vbm-v3.dts
+new file mode 100644
+index 0000000..e4d8362
+--- /dev/null
++++ b/arch/arm64/boot/dts/renesas/r8a77970-v3msk-vbm-v3.dts
+@@ -0,0 +1,38 @@
++/*
++ * Device Tree Source for the V3MSK Videobox Mini board V3 on r8a7797
++ *
++ * Copyright (C) 2018 Cogent Embedded, Inc.
++ *
++ * This file is licensed under the terms of the GNU General Public License
++ * version 2. This program is licensed "as is" without any warranty of any
++ * kind, whether express or implied.
++ */
++
++#include "r8a77970-v3msk-vbm-v2.dts"
++
++
++/ {
++ model = "Renesas V3MSK Videobox Mini board V3 based on r8a7797";
++};
++
++&gpio0 {
++ can0_load {
++ gpio-hog;
++ gpios = <19 GPIO_ACTIVE_HIGH>;
++ output-low;
++ line-name = "can0_120R_load";
++ };
++};
++
++&gpio1 {
++ ex_v3m {
++ gpio-hog;
++ gpios = <19 GPIO_ACTIVE_HIGH>;
++ output-high;
++ line-name = "ExV3M";
++ };
++};
++
++&gpio2 {
++ /delete-node/can0_load;
++};
+--
+2.7.4
+
diff --git a/bsp/meta-rcar/meta-rcar-gen3-adas/recipes-kernel/linux/linux-renesas/0343-arm64-dts-renesas-r8a77970-v3msk-Add-ethernet0-alias.patch b/bsp/meta-rcar/meta-rcar-gen3-adas/recipes-kernel/linux/linux-renesas/0343-arm64-dts-renesas-r8a77970-v3msk-Add-ethernet0-alias.patch
new file mode 100644
index 00000000..2498e966
--- /dev/null
+++ b/bsp/meta-rcar/meta-rcar-gen3-adas/recipes-kernel/linux/linux-renesas/0343-arm64-dts-renesas-r8a77970-v3msk-Add-ethernet0-alias.patch
@@ -0,0 +1,31 @@
+From 45e31ba2c9c7f8d00f4ab8837ec54c4d7ebc809b Mon Sep 17 00:00:00 2001
+From: Valentine Barshak <valentine.barshak@cogentembedded.com>
+Date: Sat, 29 Jun 2019 16:49:34 +0300
+Subject: [PATCH 163/211] arm64: dts: renesas: r8a77970-v3msk: Add ethernet0
+ alias
+
+This adds ethernet0 alias to the avb. This is needed
+for U-Boot to pass the MAC address via the device tree.
+The MAC address registers are cleared when the device
+is disabled in U-Boot before starting the kernel.
+
+Signed-off-by: Valentine Barshak <valentine.barshak@cogentembedded.com>
+---
+ arch/arm64/boot/dts/renesas/r8a77970-v3msk.dts | 1 +
+ 1 file changed, 1 insertion(+)
+
+diff --git a/arch/arm64/boot/dts/renesas/r8a77970-v3msk.dts b/arch/arm64/boot/dts/renesas/r8a77970-v3msk.dts
+index af6c7b9..adc2b01 100644
+--- a/arch/arm64/boot/dts/renesas/r8a77970-v3msk.dts
++++ b/arch/arm64/boot/dts/renesas/r8a77970-v3msk.dts
+@@ -15,6 +15,7 @@
+
+ aliases {
+ serial0 = &scif0;
++ ethernet0 = &avb;
+ };
+
+ chosen {
+--
+2.7.4
+
diff --git a/bsp/meta-rcar/meta-rcar-gen3-adas/recipes-kernel/linux/linux-renesas/0344-arm64-dts-renesas-r8a77970-Add-ISP0-alias.patch b/bsp/meta-rcar/meta-rcar-gen3-adas/recipes-kernel/linux/linux-renesas/0344-arm64-dts-renesas-r8a77970-Add-ISP0-alias.patch
new file mode 100644
index 00000000..240082c3
--- /dev/null
+++ b/bsp/meta-rcar/meta-rcar-gen3-adas/recipes-kernel/linux/linux-renesas/0344-arm64-dts-renesas-r8a77970-Add-ISP0-alias.patch
@@ -0,0 +1,36 @@
+From fd575ad0cde7408796a8b94f72601be240d477f4 Mon Sep 17 00:00:00 2001
+From: Valentine Barshak <valentine.barshak@cogentembedded.com>
+Date: Tue, 6 Nov 2018 21:10:13 +0300
+Subject: [PATCH 164/211] arm64: dts: renesas: r8a77970: Add ISP0 alias
+
+This adds ISP0 alias.
+
+Signed-off-by: Valentine Barshak <valentine.barshak@cogentembedded.com>
+---
+ arch/arm64/boot/dts/renesas/r8a77970.dtsi | 3 ++-
+ 1 file changed, 2 insertions(+), 1 deletion(-)
+
+diff --git a/arch/arm64/boot/dts/renesas/r8a77970.dtsi b/arch/arm64/boot/dts/renesas/r8a77970.dtsi
+index 77ee934..35000a7 100644
+--- a/arch/arm64/boot/dts/renesas/r8a77970.dtsi
++++ b/arch/arm64/boot/dts/renesas/r8a77970.dtsi
+@@ -22,6 +22,7 @@
+ i2c2 = &i2c2;
+ i2c3 = &i2c3;
+ i2c4 = &i2c4;
++ isp0 = &isp0;
+ };
+
+ /* External CAN clock - to be overridden by boards that provide it */
+@@ -1016,7 +1017,7 @@
+ alloc-dev = <&imr_v4l2_alloc>;
+ };
+
+- isp@fec00000 {
++ isp0: isp@fec00000 {
+ compatible = "renesas,isp-r8a77970";
+ reg = <0 0xfec00000 0 0x20000>,
+ <0 0xfed00000 0 0x10000>;
+--
+2.7.4
+
diff --git a/bsp/meta-rcar/meta-rcar-gen3-adas/recipes-kernel/linux/linux-renesas/0345-arm64-dts-renesas-r8a77980-Add-ISP-aliases.patch b/bsp/meta-rcar/meta-rcar-gen3-adas/recipes-kernel/linux/linux-renesas/0345-arm64-dts-renesas-r8a77980-Add-ISP-aliases.patch
new file mode 100644
index 00000000..34dc5fb6
--- /dev/null
+++ b/bsp/meta-rcar/meta-rcar-gen3-adas/recipes-kernel/linux/linux-renesas/0345-arm64-dts-renesas-r8a77980-Add-ISP-aliases.patch
@@ -0,0 +1,46 @@
+From 069bb03da39d46d50251459920f3ab95e8ff5c02 Mon Sep 17 00:00:00 2001
+From: Valentine Barshak <valentine.barshak@cogentembedded.com>
+Date: Tue, 6 Nov 2018 21:11:09 +0300
+Subject: [PATCH 165/211] arm64: dts: renesas: r8a77980: Add ISP aliases
+
+This adds ISP0 and ISP1 aliases.
+
+Signed-off-by: Valentine Barshak <valentine.barshak@cogentembedded.com>
+---
+ arch/arm64/boot/dts/renesas/r8a77980.dtsi | 6 ++++--
+ 1 file changed, 4 insertions(+), 2 deletions(-)
+
+diff --git a/arch/arm64/boot/dts/renesas/r8a77980.dtsi b/arch/arm64/boot/dts/renesas/r8a77980.dtsi
+index 8af443d..e0d2213 100644
+--- a/arch/arm64/boot/dts/renesas/r8a77980.dtsi
++++ b/arch/arm64/boot/dts/renesas/r8a77980.dtsi
+@@ -23,6 +23,8 @@
+ i2c3 = &i2c3;
+ i2c4 = &i2c4;
+ i2c5 = &i2c5;
++ isp0 = &isp0;
++ isp1 = &isp1;
+ };
+
+ /* External CAN clock - to be overridden by boards that provide it */
+@@ -1443,7 +1445,7 @@
+ power-domains = <&sysc R8A77980_PD_A3VIP2>;
+ };
+
+- isp@fec00000 {
++ isp0: isp@fec00000 {
+ compatible = "renesas,isp-r8a77980";
+ reg = <0 0xfec00000 0 0x20000>,
+ <0 0xfed00000 0 0x10000>;
+@@ -1453,7 +1455,7 @@
+ power-domains = <&sysc R8A77980_PD_ALWAYS_ON>;
+ };
+
+- isp@fee00000 {
++ isp1: isp@fee00000 {
+ compatible = "renesas,isp-r8a77980";
+ reg = <0 0xfee00000 0 0x20000>,
+ <0 0xfed20000 0 0x10000>;
+--
+2.7.4
+
diff --git a/bsp/meta-rcar/meta-rcar-gen3-adas/recipes-kernel/linux/linux-renesas/0346-media-soc_camera-Add-soc_camera-host-preregister.patch b/bsp/meta-rcar/meta-rcar-gen3-adas/recipes-kernel/linux/linux-renesas/0346-media-soc_camera-Add-soc_camera-host-preregister.patch
new file mode 100644
index 00000000..63ea0db0
--- /dev/null
+++ b/bsp/meta-rcar/meta-rcar-gen3-adas/recipes-kernel/linux/linux-renesas/0346-media-soc_camera-Add-soc_camera-host-preregister.patch
@@ -0,0 +1,74 @@
+From ebe2c882cf0119f9e5a81bcad9bcf4daabe6d8fe Mon Sep 17 00:00:00 2001
+From: Nikita Yushchenko <nikita.yoush@cogentembedded.com>
+Date: Wed, 1 Aug 2018 13:06:00 +0300
+Subject: [PATCH 166/211] media: soc_camera: Add soc_camera host preregister
+
+This adds soc_camera host preregister
+
+Signed-off-by: Nikita Yushchenko <nikita.yoush@cogentembedded.com>
+---
+ drivers/media/platform/soc_camera/soc_camera.c | 20 +++++++++++++++++---
+ include/media/soc_camera.h | 2 ++
+ 2 files changed, 19 insertions(+), 3 deletions(-)
+
+diff --git a/drivers/media/platform/soc_camera/soc_camera.c b/drivers/media/platform/soc_camera/soc_camera.c
+index 0fa1f52..cd2a135 100644
+--- a/drivers/media/platform/soc_camera/soc_camera.c
++++ b/drivers/media/platform/soc_camera/soc_camera.c
+@@ -1910,9 +1910,11 @@ int soc_camera_host_register(struct soc_camera_host *ici)
+ }
+ }
+
+- ret = v4l2_device_register(ici->v4l2_dev.dev, &ici->v4l2_dev);
+- if (ret < 0)
+- goto edevreg;
++ if (!ici->v4l2dev_preregistered) {
++ ret = v4l2_device_register(ici->v4l2_dev.dev, &ici->v4l2_dev);
++ if (ret < 0)
++ goto edevreg;
++ }
+
+ list_add_tail(&ici->list, &hosts);
+ mutex_unlock(&list_lock);
+@@ -1941,6 +1943,18 @@ int soc_camera_host_register(struct soc_camera_host *ici)
+ }
+ EXPORT_SYMBOL(soc_camera_host_register);
+
++int soc_camera_host_preregister_v4l2_dev(struct soc_camera_host *ici)
++{
++ int ret;
++
++ ret = v4l2_device_register(ici->v4l2_dev.dev, &ici->v4l2_dev);
++ if (ret == 0)
++ ici->v4l2dev_preregistered = true;
++
++ return ret;
++}
++EXPORT_SYMBOL(soc_camera_host_preregister_v4l2_dev);
++
+ /* Unregister all clients! */
+ void soc_camera_host_unregister(struct soc_camera_host *ici)
+ {
+diff --git a/include/media/soc_camera.h b/include/media/soc_camera.h
+index c2a7fc2..2e44f96 100644
+--- a/include/media/soc_camera.h
++++ b/include/media/soc_camera.h
+@@ -84,6 +84,7 @@ struct soc_camera_host {
+ struct soc_camera_host_ops *ops;
+ struct v4l2_async_subdev **asd; /* Flat array, arranged in groups */
+ unsigned int *asd_sizes; /* 0-terminated array of asd group sizes */
++ bool v4l2dev_preregistered;
+ };
+
+ struct soc_camera_host_ops {
+@@ -275,6 +276,7 @@ static inline struct v4l2_subdev *soc_camera_to_subdev(
+ }
+
+ int soc_camera_host_register(struct soc_camera_host *ici);
++int soc_camera_host_preregister_v4l2_dev(struct soc_camera_host *ici);
+ void soc_camera_host_unregister(struct soc_camera_host *ici);
+
+ const struct soc_camera_format_xlate *soc_camera_xlate_by_fourcc(
+--
+2.7.4
+
diff --git a/bsp/meta-rcar/meta-rcar-gen3-adas/recipes-kernel/linux/linux-renesas/0347-arm64-renesas-r8a77980-use-CSI-4-lanes.patch b/bsp/meta-rcar/meta-rcar-gen3-adas/recipes-kernel/linux/linux-renesas/0347-arm64-renesas-r8a77980-use-CSI-4-lanes.patch
new file mode 100644
index 00000000..6a3e4cc7
--- /dev/null
+++ b/bsp/meta-rcar/meta-rcar-gen3-adas/recipes-kernel/linux/linux-renesas/0347-arm64-renesas-r8a77980-use-CSI-4-lanes.patch
@@ -0,0 +1,339 @@
+From 64aba50a93e9a1980b291cb71bd7a62d1faa9ca7 Mon Sep 17 00:00:00 2001
+From: Andrey Dolnikov <andrey.dolnikov@cogentembedded.com>
+Date: Wed, 7 Nov 2018 13:06:39 +0300
+Subject: [PATCH 167/211] arm64: renesas: r8a77980: use CSI 4 lanes
+
+H/w must use 4 lanes
+add PWM for external FSIN on deserializers
+
+Signed-off-by: Vladimir Barinov <vladimir.barinov@cogentembedded.com>
+---
+ .../boot/dts/renesas/r8a77980-v3hsk-vb-4ch.dts | 60 ++++---------------
+ .../boot/dts/renesas/r8a77980-v3hsk-vb-8ch.dts | 69 +++++++---------------
+ 2 files changed, 32 insertions(+), 97 deletions(-)
+
+diff --git a/arch/arm64/boot/dts/renesas/r8a77980-v3hsk-vb-4ch.dts b/arch/arm64/boot/dts/renesas/r8a77980-v3hsk-vb-4ch.dts
+index 1dd93fd..406ff2f 100644
+--- a/arch/arm64/boot/dts/renesas/r8a77980-v3hsk-vb-4ch.dts
++++ b/arch/arm64/boot/dts/renesas/r8a77980-v3hsk-vb-4ch.dts
+@@ -108,32 +108,13 @@
+ &csi40 {
+ status = "okay";
+
+- virtual,channel {
+- csi2_vc0 {
+- data,type = "ycbcr422";
+- receive,vc = <0>;
+- };
+- csi2_vc1 {
+- data,type = "ycbcr422";
+- receive,vc = <1>;
+- };
+- csi2_vc2 {
+- data,type = "ycbcr422";
+- receive,vc = <2>;
+- };
+- csi2_vc3 {
+- data,type = "ycbcr422";
+- receive,vc = <3>;
+- };
+- };
+-
+ port {
+ #address-cells = <1>;
+ #size-cells = <0>;
+
+ csi2_40_ep: endpoint {
+ clock-lanes = <0>;
+- data-lanes = <1 2 3>;
++ data-lanes = <1 2 3 4>;
+ csi-rate = <1450>;
+ };
+ };
+@@ -142,32 +123,13 @@
+ &csi41 {
+ status = "okay";
+
+- virtual,channel {
+- csi2_vc0 {
+- data,type = "ycbcr422";
+- receive,vc = <0>;
+- };
+- csi2_vc1 {
+- data,type = "ycbcr422";
+- receive,vc = <1>;
+- };
+- csi2_vc2 {
+- data,type = "ycbcr422";
+- receive,vc = <2>;
+- };
+- csi2_vc3 {
+- data,type = "ycbcr422";
+- receive,vc = <3>;
+- };
+- };
+-
+ port {
+ #address-cells = <1>;
+ #size-cells = <0>;
+
+ csi2_41_ep: endpoint {
+ clock-lanes = <0>;
+- data-lanes = <1 2 3>;
++ data-lanes = <1 2 3 4>;
+ csi-rate = <1450>;
+ };
+ };
+@@ -201,7 +163,7 @@
+ port@0 {
+ ov106xx_in0: endpoint {
+ clock-lanes = <0>;
+- data-lanes = <1 2 3>;
++ data-lanes = <1 2 3 4>;
+ remote-endpoint = <&vin0ep0>;
+ };
+ };
+@@ -219,7 +181,7 @@
+ port@0 {
+ ov106xx_in1: endpoint {
+ clock-lanes = <0>;
+- data-lanes = <1 2 3>;
++ data-lanes = <1 2 3 4>;
+ remote-endpoint = <&vin1ep0>;
+ };
+ };
+@@ -237,7 +199,7 @@
+ port@0 {
+ ov106xx_in2: endpoint {
+ clock-lanes = <0>;
+- data-lanes = <1 2 3>;
++ data-lanes = <1 2 3 4>;
+ remote-endpoint = <&vin6ep0>;
+ };
+ };
+@@ -255,7 +217,7 @@
+ port@0 {
+ ov106xx_in3: endpoint {
+ clock-lanes = <0>;
+- data-lanes = <1 2 3>;
++ data-lanes = <1 2 3 4>;
+ remote-endpoint = <&vin7ep0>;
+ };
+ };
+@@ -272,7 +234,7 @@
+ clock-names = "ref_clk";
+ reg = <0x3a>;
+ ti,links = <4>;
+- ti,lanes = <3>;
++ ti,lanes = <4>;
+ ti,forwarding-mode = "round-robin";
+ ti,cable-mode = "coax";
+ gpios = <&gpio_exp_ch0 13 GPIO_ACTIVE_LOW>;
+@@ -559,7 +521,7 @@
+ vin0ep0: endpoint {
+ csi,select = "csi40";
+ virtual,channel = <0>;
+- data-lanes = <1 2 3>;
++ data-lanes = <1 2 3 4>;
+ remote-endpoint = <&ov106xx_in0>;
+ };
+ };
+@@ -587,7 +549,7 @@
+ vin1ep0: endpoint {
+ csi,select = "csi40";
+ virtual,channel = <1>;
+- data-lanes = <1 2 3>;
++ data-lanes = <1 2 3 4>;
+ remote-endpoint = <&ov106xx_in1>;
+ };
+ };
+@@ -615,7 +577,7 @@
+ vin6ep0: endpoint {
+ csi,select = "csi41";
+ virtual,channel = <2>;
+- data-lanes = <1 2 3>;
++ data-lanes = <1 2 3 4>;
+ remote-endpoint = <&ov106xx_in2>;
+ };
+ };
+@@ -643,7 +605,7 @@
+ vin7ep0: endpoint {
+ csi,select = "csi41";
+ virtual,channel = <3>;
+- data-lanes = <1 2 3>;
++ data-lanes = <1 2 3 4>;
+ remote-endpoint = <&ov106xx_in3>;
+ };
+ };
+diff --git a/arch/arm64/boot/dts/renesas/r8a77980-v3hsk-vb-8ch.dts b/arch/arm64/boot/dts/renesas/r8a77980-v3hsk-vb-8ch.dts
+index 0db52f4..f8657ed 100644
+--- a/arch/arm64/boot/dts/renesas/r8a77980-v3hsk-vb-8ch.dts
++++ b/arch/arm64/boot/dts/renesas/r8a77980-v3hsk-vb-8ch.dts
+@@ -108,25 +108,6 @@
+ &csi40 {
+ status = "okay";
+
+- virtual,channel {
+- csi2_vc0 {
+- data,type = "ycbcr422";
+- receive,vc = <0>;
+- };
+- csi2_vc1 {
+- data,type = "ycbcr422";
+- receive,vc = <1>;
+- };
+- csi2_vc2 {
+- data,type = "ycbcr422";
+- receive,vc = <2>;
+- };
+- csi2_vc3 {
+- data,type = "ycbcr422";
+- receive,vc = <3>;
+- };
+- };
+-
+ port {
+ #address-cells = <1>;
+ #size-cells = <0>;
+@@ -142,32 +123,13 @@
+ &csi41 {
+ status = "okay";
+
+- virtual,channel {
+- csi2_vc0 {
+- data,type = "ycbcr422";
+- receive,vc = <0>;
+- };
+- csi2_vc1 {
+- data,type = "ycbcr422";
+- receive,vc = <1>;
+- };
+- csi2_vc2 {
+- data,type = "ycbcr422";
+- receive,vc = <2>;
+- };
+- csi2_vc3 {
+- data,type = "ycbcr422";
+- receive,vc = <3>;
+- };
+- };
+-
+ port {
+ #address-cells = <1>;
+ #size-cells = <0>;
+
+ csi2_41_ep: endpoint {
+ clock-lanes = <0>;
+- data-lanes = <1 2 3>;
++ data-lanes = <1 2 3 4>;
+ csi-rate = <1450>;
+ };
+ };
+@@ -359,7 +321,7 @@
+ port@0 {
+ ov106xx_in4: endpoint {
+ clock-lanes = <0>;
+- data-lanes = <1 2 3>;
++ data-lanes = <1 2 3 4>;
+ remote-endpoint = <&vin4ep0>;
+ };
+ };
+@@ -377,7 +339,7 @@
+ port@0 {
+ ov106xx_in5: endpoint {
+ clock-lanes = <0>;
+- data-lanes = <1 2 3>;
++ data-lanes = <1 2 3 4>;
+ remote-endpoint = <&vin5ep0>;
+ };
+ };
+@@ -395,7 +357,7 @@
+ port@0 {
+ ov106xx_in6: endpoint {
+ clock-lanes = <0>;
+- data-lanes = <1 2 3>;
++ data-lanes = <1 2 3 4>;
+ remote-endpoint = <&vin6ep0>;
+ };
+ };
+@@ -413,7 +375,7 @@
+ port@0 {
+ ov106xx_in7: endpoint {
+ clock-lanes = <0>;
+- data-lanes = <1 2 3>;
++ data-lanes = <1 2 3 4>;
+ remote-endpoint = <&vin7ep0>;
+ };
+ };
+@@ -430,7 +392,7 @@
+ clock-names = "ref_clk";
+ reg = <0x3a>;
+ ti,links = <4>;
+- ti,lanes = <3>;
++ ti,lanes = <4>;
+ ti,forwarding-mode = "round-robin";
+ ti,cable-mode = "coax";
+ gpios = <&gpio_exp_ch1 13 GPIO_ACTIVE_LOW>;
+@@ -682,12 +644,23 @@
+ function = "i2c1";
+ };
+
++ pwm0_pins: pwm0 {
++ groups = "pwm0_a";
++ function = "pwm0";
++ };
++
+ scif3_pins: scif3 {
+ groups = "scif3_data";
+ function = "scif3";
+ };
+ };
+
++&pwm0 {
++ pinctrl-0 = <&pwm0_pins>;
++ pinctrl-names = "default";
++ status = "okay";
++};
++
+ &scif3 {
+ pinctrl-0 = <&scif3_pins>;
+ pinctrl-names = "default";
+@@ -822,7 +795,7 @@
+ vin4ep0: endpoint {
+ csi,select = "csi41";
+ virtual,channel = <0>;
+- data-lanes = <1 2 3>;
++ data-lanes = <1 2 3 4>;
+ remote-endpoint = <&ov106xx_in4>;
+ };
+ };
+@@ -850,7 +823,7 @@
+ vin5ep0: endpoint {
+ csi,select = "csi41";
+ virtual,channel = <1>;
+- data-lanes = <1 2 3>;
++ data-lanes = <1 2 3 4>;
+ remote-endpoint = <&ov106xx_in5>;
+ };
+ };
+@@ -878,7 +851,7 @@
+ vin6ep0: endpoint {
+ csi,select = "csi41";
+ virtual,channel = <2>;
+- data-lanes = <1 2 3>;
++ data-lanes = <1 2 3 4>;
+ remote-endpoint = <&ov106xx_in6>;
+ };
+ };
+@@ -906,7 +879,7 @@
+ vin7ep0: endpoint {
+ csi,select = "csi41";
+ virtual,channel = <3>;
+- data-lanes = <1 2 3>;
++ data-lanes = <1 2 3 4>;
+ remote-endpoint = <&ov106xx_in7>;
+ };
+ };
+--
+2.7.4
+
diff --git a/bsp/meta-rcar/meta-rcar-gen3-adas/recipes-kernel/linux/linux-renesas/0348-Bunch-update-of-r8a77980-v3hsk-vb-4ch.dts.patch b/bsp/meta-rcar/meta-rcar-gen3-adas/recipes-kernel/linux/linux-renesas/0348-Bunch-update-of-r8a77980-v3hsk-vb-4ch.dts.patch
new file mode 100644
index 00000000..68985e0c
--- /dev/null
+++ b/bsp/meta-rcar/meta-rcar-gen3-adas/recipes-kernel/linux/linux-renesas/0348-Bunch-update-of-r8a77980-v3hsk-vb-4ch.dts.patch
@@ -0,0 +1,139 @@
+From c374786365b9051f341f9fbe1b3f6094a39b0c09 Mon Sep 17 00:00:00 2001
+From: Andrey Dolnikov <andrey.dolnikov@cogentembedded.com>
+Date: Wed, 7 Nov 2018 14:15:35 +0300
+Subject: [PATCH 168/211] Bunch update of r8a77980-v3hsk-vb-4ch.dts...
+
+...to avoid cherry-pick of patched patches...
+---
+ .../boot/dts/renesas/r8a77980-v3hsk-vb-4ch.dts | 30 ++++++++++++----------
+ 1 file changed, 16 insertions(+), 14 deletions(-)
+
+diff --git a/arch/arm64/boot/dts/renesas/r8a77980-v3hsk-vb-4ch.dts b/arch/arm64/boot/dts/renesas/r8a77980-v3hsk-vb-4ch.dts
+index 406ff2f..76855c4 100644
+--- a/arch/arm64/boot/dts/renesas/r8a77980-v3hsk-vb-4ch.dts
++++ b/arch/arm64/boot/dts/renesas/r8a77980-v3hsk-vb-4ch.dts
+@@ -115,7 +115,7 @@
+ csi2_40_ep: endpoint {
+ clock-lanes = <0>;
+ data-lanes = <1 2 3 4>;
+- csi-rate = <1450>;
++ csi-rate = <1500>;
+ };
+ };
+ };
+@@ -130,7 +130,7 @@
+ csi2_41_ep: endpoint {
+ clock-lanes = <0>;
+ data-lanes = <1 2 3 4>;
+- csi-rate = <1450>;
++ csi-rate = <1500>;
+ };
+ };
+ };
+@@ -200,7 +200,7 @@
+ ov106xx_in2: endpoint {
+ clock-lanes = <0>;
+ data-lanes = <1 2 3 4>;
+- remote-endpoint = <&vin6ep0>;
++ remote-endpoint = <&vin4ep0>;
+ };
+ };
+ port@1 {
+@@ -218,7 +218,7 @@
+ ov106xx_in3: endpoint {
+ clock-lanes = <0>;
+ data-lanes = <1 2 3 4>;
+- remote-endpoint = <&vin7ep0>;
++ remote-endpoint = <&vin5ep0>;
+ };
+ };
+ port@1 {
+@@ -237,6 +237,8 @@
+ ti,lanes = <4>;
+ ti,forwarding-mode = "round-robin";
+ ti,cable-mode = "coax";
++ ti,vc-map = <0x1010>;
++ ti,csi1-links = <0 1>;
+ gpios = <&gpio_exp_ch0 13 GPIO_ACTIVE_LOW>;
+ POC0-gpios = <&gpio_exp_ch0 8 GPIO_ACTIVE_HIGH>;
+ POC1-gpios = <&gpio_exp_ch0 9 GPIO_ACTIVE_HIGH>;
+@@ -267,7 +269,7 @@
+ };
+ port@1 {
+ ti9x4_csi0ep0: endpoint {
+- csi-rate = <1450>;
++ csi-rate = <1500>;
+ remote-endpoint = <&csi2_40_ep>;
+ };
+ };
+@@ -322,7 +324,7 @@
+ clock-names = "clk_in";
+
+ assigned-clocks = <&cs2300>;
+- assigned-clock-rates = <22500000>;
++ assigned-clock-rates = <23500000>;
+ };
+ };
+
+@@ -566,7 +568,7 @@
+ };
+ };
+
+-&vin6 {
++&vin4 {
+ status = "okay";
+
+ ports {
+@@ -574,9 +576,9 @@
+ #size-cells = <0>;
+
+ port@0 {
+- vin6ep0: endpoint {
++ vin4ep0: endpoint {
+ csi,select = "csi41";
+- virtual,channel = <2>;
++ virtual,channel = <0>;
+ data-lanes = <1 2 3 4>;
+ remote-endpoint = <&ov106xx_in2>;
+ };
+@@ -587,14 +589,14 @@
+ };
+ };
+ port@2 {
+- vin6_ti9x4_des0ep2: endpoint@1 {
++ vin4_ti9x4_des0ep2: endpoint@1 {
+ remote-endpoint = <&ti9x4_des0ep2>;
+ };
+ };
+ };
+ };
+
+-&vin7 {
++&vin5 {
+ status = "okay";
+
+ ports {
+@@ -602,9 +604,9 @@
+ #size-cells = <0>;
+
+ port@0 {
+- vin7ep0: endpoint {
++ vin5ep0: endpoint {
+ csi,select = "csi41";
+- virtual,channel = <3>;
++ virtual,channel = <1>;
+ data-lanes = <1 2 3 4>;
+ remote-endpoint = <&ov106xx_in3>;
+ };
+@@ -615,7 +617,7 @@
+ };
+ };
+ port@2 {
+- vin7_ti9x4_des0ep3: endpoint@1 {
++ vin5_ti9x4_des0ep3: endpoint@1 {
+ remote-endpoint = <&ti9x4_des0ep3>;
+ };
+ };
+--
+2.7.4
+
diff --git a/bsp/meta-rcar/meta-rcar-gen3-adas/recipes-kernel/linux/linux-renesas/0349-arm64-dts-renesas-r8a77980-VideoBox-Mini-fix-csi-spe.patch b/bsp/meta-rcar/meta-rcar-gen3-adas/recipes-kernel/linux/linux-renesas/0349-arm64-dts-renesas-r8a77980-VideoBox-Mini-fix-csi-spe.patch
new file mode 100644
index 00000000..0e2e9f2f
--- /dev/null
+++ b/bsp/meta-rcar/meta-rcar-gen3-adas/recipes-kernel/linux/linux-renesas/0349-arm64-dts-renesas-r8a77980-VideoBox-Mini-fix-csi-spe.patch
@@ -0,0 +1,26 @@
+From 1412299ecb8c31937e6e2db81c46cc89260ff30a Mon Sep 17 00:00:00 2001
+From: Andrey Dolnikov <andrey.dolnikov@cogentembedded.com>
+Date: Wed, 7 Nov 2018 14:52:34 +0300
+Subject: [PATCH 169/211] arm64: dts: renesas: r8a77980 VideoBox Mini: fix csi
+ speed.
+
+---
+ arch/arm64/boot/dts/renesas/r8a77980-v3hsk-vbm.dts | 2 +-
+ 1 file changed, 1 insertion(+), 1 deletion(-)
+
+diff --git a/arch/arm64/boot/dts/renesas/r8a77980-v3hsk-vbm.dts b/arch/arm64/boot/dts/renesas/r8a77980-v3hsk-vbm.dts
+index 1b0649f..e362045 100644
+--- a/arch/arm64/boot/dts/renesas/r8a77980-v3hsk-vbm.dts
++++ b/arch/arm64/boot/dts/renesas/r8a77980-v3hsk-vbm.dts
+@@ -250,7 +250,7 @@
+ };
+ port@1 {
+ ti9x4_csi0ep0: endpoint {
+- csi-rate = <700>;
++ csi-rate = <1450>;
+ remote-endpoint = <&csi41_ep>;
+ };
+ };
+--
+2.7.4
+
diff --git a/bsp/meta-rcar/meta-rcar-gen3-adas/recipes-kernel/linux/linux-renesas/0350-arm64-dts-renesas-r8a77980-v3hsk-vb-4ch-and-8ch-fix-.patch b/bsp/meta-rcar/meta-rcar-gen3-adas/recipes-kernel/linux/linux-renesas/0350-arm64-dts-renesas-r8a77980-v3hsk-vb-4ch-and-8ch-fix-.patch
new file mode 100644
index 00000000..48c3ef02
--- /dev/null
+++ b/bsp/meta-rcar/meta-rcar-gen3-adas/recipes-kernel/linux/linux-renesas/0350-arm64-dts-renesas-r8a77980-v3hsk-vb-4ch-and-8ch-fix-.patch
@@ -0,0 +1,193 @@
+From 34941d2c45e323bb07c613148fbaff31b955017b Mon Sep 17 00:00:00 2001
+From: Andrey Dolnikov <andrey.dolnikov@cogentembedded.com>
+Date: Wed, 7 Nov 2018 15:27:06 +0300
+Subject: [PATCH 170/211] arm64: dts: renesas: r8a77980 v3hsk vb 4ch and 8ch:
+ fix csi labels.
+
+---
+ .../boot/dts/renesas/r8a77980-v3hsk-vb-4ch.dts | 14 ++++++-------
+ .../boot/dts/renesas/r8a77980-v3hsk-vb-8ch.dts | 24 +++++++++++-----------
+ 2 files changed, 19 insertions(+), 19 deletions(-)
+
+diff --git a/arch/arm64/boot/dts/renesas/r8a77980-v3hsk-vb-4ch.dts b/arch/arm64/boot/dts/renesas/r8a77980-v3hsk-vb-4ch.dts
+index 76855c4..d281871 100644
+--- a/arch/arm64/boot/dts/renesas/r8a77980-v3hsk-vb-4ch.dts
++++ b/arch/arm64/boot/dts/renesas/r8a77980-v3hsk-vb-4ch.dts
+@@ -112,7 +112,7 @@
+ #address-cells = <1>;
+ #size-cells = <0>;
+
+- csi2_40_ep: endpoint {
++ csi40_ep: endpoint {
+ clock-lanes = <0>;
+ data-lanes = <1 2 3 4>;
+ csi-rate = <1500>;
+@@ -127,7 +127,7 @@
+ #address-cells = <1>;
+ #size-cells = <0>;
+
+- csi2_41_ep: endpoint {
++ csi41_ep: endpoint {
+ clock-lanes = <0>;
+ data-lanes = <1 2 3 4>;
+ csi-rate = <1500>;
+@@ -270,7 +270,7 @@
+ port@1 {
+ ti9x4_csi0ep0: endpoint {
+ csi-rate = <1500>;
+- remote-endpoint = <&csi2_40_ep>;
++ remote-endpoint = <&csi40_ep>;
+ };
+ };
+ };
+@@ -529,7 +529,7 @@
+ };
+ port@1 {
+ csi0ep0: endpoint {
+- remote-endpoint = <&csi2_40_ep>;
++ remote-endpoint = <&csi40_ep>;
+ };
+ };
+ port@2 {
+@@ -557,7 +557,7 @@
+ };
+ port@1 {
+ csi0ep1: endpoint {
+- remote-endpoint = <&csi2_40_ep>;
++ remote-endpoint = <&csi40_ep>;
+ };
+ };
+ port@2 {
+@@ -585,7 +585,7 @@
+ };
+ port@1 {
+ csi1ep2: endpoint {
+- remote-endpoint = <&csi2_41_ep>;
++ remote-endpoint = <&csi41_ep>;
+ };
+ };
+ port@2 {
+@@ -613,7 +613,7 @@
+ };
+ port@1 {
+ csi1ep3: endpoint {
+- remote-endpoint = <&csi2_41_ep>;
++ remote-endpoint = <&csi41_ep>;
+ };
+ };
+ port@2 {
+diff --git a/arch/arm64/boot/dts/renesas/r8a77980-v3hsk-vb-8ch.dts b/arch/arm64/boot/dts/renesas/r8a77980-v3hsk-vb-8ch.dts
+index f8657ed..e5a8a18 100644
+--- a/arch/arm64/boot/dts/renesas/r8a77980-v3hsk-vb-8ch.dts
++++ b/arch/arm64/boot/dts/renesas/r8a77980-v3hsk-vb-8ch.dts
+@@ -112,7 +112,7 @@
+ #address-cells = <1>;
+ #size-cells = <0>;
+
+- csi2_40_ep: endpoint {
++ csi40_ep: endpoint {
+ clock-lanes = <0>;
+ data-lanes = <1 2 3 4>;
+ csi-rate = <1450>;
+@@ -127,7 +127,7 @@
+ #address-cells = <1>;
+ #size-cells = <0>;
+
+- csi2_41_ep: endpoint {
++ csi41_ep: endpoint {
+ clock-lanes = <0>;
+ data-lanes = <1 2 3 4>;
+ csi-rate = <1450>;
+@@ -268,7 +268,7 @@
+ port@1 {
+ ti9x4_csi0ep0: endpoint {
+ csi-rate = <1450>;
+- remote-endpoint = <&csi2_40_ep>;
++ remote-endpoint = <&csi40_ep>;
+ };
+ };
+ };
+@@ -426,7 +426,7 @@
+ port@1 {
+ ti9x4_csi1ep0: endpoint {
+ csi-rate = <1450>;
+- remote-endpoint = <&csi2_41_ep>;
++ remote-endpoint = <&csi41_ep>;
+ };
+ };
+ };
+@@ -689,7 +689,7 @@
+ };
+ port@1 {
+ csi0ep0: endpoint {
+- remote-endpoint = <&csi2_40_ep>;
++ remote-endpoint = <&csi40_ep>;
+ };
+ };
+ port@2 {
+@@ -717,7 +717,7 @@
+ };
+ port@1 {
+ csi0ep1: endpoint {
+- remote-endpoint = <&csi2_40_ep>;
++ remote-endpoint = <&csi40_ep>;
+ };
+ };
+ port@2 {
+@@ -745,7 +745,7 @@
+ };
+ port@1 {
+ csi0ep2: endpoint {
+- remote-endpoint = <&csi2_40_ep>;
++ remote-endpoint = <&csi40_ep>;
+ };
+ };
+ port@2 {
+@@ -773,7 +773,7 @@
+ };
+ port@1 {
+ csi0ep3: endpoint {
+- remote-endpoint = <&csi2_40_ep>;
++ remote-endpoint = <&csi40_ep>;
+ };
+ };
+ port@2 {
+@@ -801,7 +801,7 @@
+ };
+ port@1 {
+ csi1ep0: endpoint {
+- remote-endpoint = <&csi2_41_ep>;
++ remote-endpoint = <&csi41_ep>;
+ };
+ };
+ port@2 {
+@@ -829,7 +829,7 @@
+ };
+ port@1 {
+ csi1ep1: endpoint {
+- remote-endpoint = <&csi2_41_ep>;
++ remote-endpoint = <&csi41_ep>;
+ };
+ };
+ port@2 {
+@@ -857,7 +857,7 @@
+ };
+ port@1 {
+ csi1ep2: endpoint {
+- remote-endpoint = <&csi2_41_ep>;
++ remote-endpoint = <&csi41_ep>;
+ };
+ };
+ port@2 {
+@@ -885,7 +885,7 @@
+ };
+ port@1 {
+ csi1ep3: endpoint {
+- remote-endpoint = <&csi2_41_ep>;
++ remote-endpoint = <&csi41_ep>;
+ };
+ };
+ port@2 {
+--
+2.7.4
+
diff --git a/bsp/meta-rcar/meta-rcar-gen3-adas/recipes-kernel/linux/linux-renesas/0351-arm64-dts-renesas-r8a77980-VB-4ch-and-8ch-Add-PCIE-p.patch b/bsp/meta-rcar/meta-rcar-gen3-adas/recipes-kernel/linux/linux-renesas/0351-arm64-dts-renesas-r8a77980-VB-4ch-and-8ch-Add-PCIE-p.patch
new file mode 100644
index 00000000..c25aa562
--- /dev/null
+++ b/bsp/meta-rcar/meta-rcar-gen3-adas/recipes-kernel/linux/linux-renesas/0351-arm64-dts-renesas-r8a77980-VB-4ch-and-8ch-Add-PCIE-p.patch
@@ -0,0 +1,44 @@
+From 75f23c3e3581eca8a5b0098943c246f64f55d406 Mon Sep 17 00:00:00 2001
+From: Andrey Dolnikov <andrey.dolnikov@cogentembedded.com>
+Date: Wed, 7 Nov 2018 19:09:18 +0300
+Subject: [PATCH 171/211] arm64: dts: renesas: r8a77980 VB 4ch and 8ch: Add
+ PCIE phy node.
+
+---
+ arch/arm64/boot/dts/renesas/r8a77980-v3hsk-vb-4ch.dts | 4 ++++
+ arch/arm64/boot/dts/renesas/r8a77980-v3hsk-vb-8ch.dts | 4 ++++
+ 2 files changed, 8 insertions(+)
+
+diff --git a/arch/arm64/boot/dts/renesas/r8a77980-v3hsk-vb-4ch.dts b/arch/arm64/boot/dts/renesas/r8a77980-v3hsk-vb-4ch.dts
+index d281871..7b35608 100644
+--- a/arch/arm64/boot/dts/renesas/r8a77980-v3hsk-vb-4ch.dts
++++ b/arch/arm64/boot/dts/renesas/r8a77980-v3hsk-vb-4ch.dts
+@@ -469,6 +469,10 @@
+ status = "okay";
+ };
+
++&pcie_phy {
++ status = "okay";
++};
++
+ &pfc {
+ canfd0_pins: canfd0 {
+ groups = "canfd0_data_a";
+diff --git a/arch/arm64/boot/dts/renesas/r8a77980-v3hsk-vb-8ch.dts b/arch/arm64/boot/dts/renesas/r8a77980-v3hsk-vb-8ch.dts
+index e5a8a18..84d89d2 100644
+--- a/arch/arm64/boot/dts/renesas/r8a77980-v3hsk-vb-8ch.dts
++++ b/arch/arm64/boot/dts/renesas/r8a77980-v3hsk-vb-8ch.dts
+@@ -618,6 +618,10 @@
+ status = "okay";
+ };
+
++&pcie_phy {
++ status = "okay";
++};
++
+ &pfc {
+ canfd0_pins: canfd0 {
+ groups = "canfd0_data_a";
+--
+2.7.4
+
diff --git a/bsp/meta-rcar/meta-rcar-gen3-adas/recipes-kernel/linux/linux-renesas/0352-gpu-drm-rcar_du-Fix-physical-address-of-the-CMA-back.patch b/bsp/meta-rcar/meta-rcar-gen3-adas/recipes-kernel/linux/linux-renesas/0352-gpu-drm-rcar_du-Fix-physical-address-of-the-CMA-back.patch
new file mode 100644
index 00000000..ac6c1c92
--- /dev/null
+++ b/bsp/meta-rcar/meta-rcar-gen3-adas/recipes-kernel/linux/linux-renesas/0352-gpu-drm-rcar_du-Fix-physical-address-of-the-CMA-back.patch
@@ -0,0 +1,30 @@
+From b31a82407090315c8bfa2c0079e2da263e66140f Mon Sep 17 00:00:00 2001
+From: Valentine Barshak <valentine.barshak@cogentembedded.com>
+Date: Mon, 12 Nov 2018 18:17:43 +0300
+Subject: [PATCH 172/211] gpu: drm: rcar_du: Fix physical address of the CMA
+ backing memory
+
+This fixes physical address of the frame buffer backing memory
+when the frame buffer is created using DMA buffer handle.
+
+Signed-off-by: Valentine Barshak <valentine.barshak@cogentembedded.com>
+---
+ drivers/gpu/drm/rcar-du/rcar_du_kms.c | 2 +-
+ 1 file changed, 1 insertion(+), 1 deletion(-)
+
+diff --git a/drivers/gpu/drm/rcar-du/rcar_du_kms.c b/drivers/gpu/drm/rcar-du/rcar_du_kms.c
+index a6940e6..d66ae53 100644
+--- a/drivers/gpu/drm/rcar-du/rcar_du_kms.c
++++ b/drivers/gpu/drm/rcar-du/rcar_du_kms.c
+@@ -208,7 +208,7 @@ struct drm_gem_object *rcar_du_gem_prime_import_sg_table(struct drm_device *dev,
+ goto error;
+ }
+
+- cma_obj->paddr = 0;
++ cma_obj->paddr = sg_dma_address(sgt->sgl);
+ cma_obj->sgt = sgt;
+
+ return gem_obj;
+--
+2.7.4
+
diff --git a/bsp/meta-rcar/meta-rcar-gen3-adas/recipes-kernel/linux/linux-renesas/0353-media-soc_camera-rcar_csi2-add-dump-module-param.patch b/bsp/meta-rcar/meta-rcar-gen3-adas/recipes-kernel/linux/linux-renesas/0353-media-soc_camera-rcar_csi2-add-dump-module-param.patch
new file mode 100644
index 00000000..12fc8d3c
--- /dev/null
+++ b/bsp/meta-rcar/meta-rcar-gen3-adas/recipes-kernel/linux/linux-renesas/0353-media-soc_camera-rcar_csi2-add-dump-module-param.patch
@@ -0,0 +1,65 @@
+From a9bb83a2edecc903a6025cf458fec465c8886524 Mon Sep 17 00:00:00 2001
+From: Andrey Dolnikov <andrey.dolnikov@cogentembedded.com>
+Date: Fri, 9 Nov 2018 19:28:34 +0300
+Subject: [PATCH 173/211] media: soc_camera: rcar_csi2: add dump module param.
+
+Signed-off-by: Vladimir Barinov <vladimir.barinov@cogentembedded.com>
+---
+ drivers/media/platform/soc_camera/rcar_csi2.c | 15 ++++++++-------
+ 1 file changed, 8 insertions(+), 7 deletions(-)
+
+diff --git a/drivers/media/platform/soc_camera/rcar_csi2.c b/drivers/media/platform/soc_camera/rcar_csi2.c
+index 737a686..deee4cc 100644
+--- a/drivers/media/platform/soc_camera/rcar_csi2.c
++++ b/drivers/media/platform/soc_camera/rcar_csi2.c
+@@ -40,8 +40,6 @@
+
+ #include <media/v4l2-fwnode.h>
+
+-//#define RCAR_CSI2_DUMP
+-
+ #define DRV_NAME "rcar_csi2"
+ #define VC_MAX_CHANNEL 4
+
+@@ -232,6 +230,10 @@ struct rcar_csi2 {
+ atomic_t use_count;
+ };
+
++static int dump = 0;
++module_param(dump, int, 0644);
++MODULE_PARM_DESC(dump, " Dump CSI packets (default: disabled)");
++
+ #define RCAR_CSI_80MBPS 0
+ #define RCAR_CSI_90MBPS 1
+ #define RCAR_CSI_100MBPS 2
+@@ -295,13 +297,15 @@ struct rcar_csi2 {
+
+ #define RCAR_CSI2_INTSTATE_ALL 0x3FFFFCDD
+
+-#ifdef RCAR_CSI2_DUMP
+ static void rcar_sci2_debug_show(struct rcar_csi2 *priv)
+ {
+ int i;
+ u32 reg0, reg1;
+
+- printk("Debug registers:\n");
++ if (!dump)
++ return;
++
++ dev_info(&priv->pdev->dev, "Debug registers:\n");
+ printk("FCNTM : 0x%08x\n", ioread32(priv->base + RCAR_CSI2_FCNTM));
+ printk("FCNTM2: 0x%08x\n", ioread32(priv->base + RCAR_CSI2_FCNTM2));
+
+@@ -355,9 +359,6 @@ static void rcar_sci2_debug_show(struct rcar_csi2 *priv)
+ for (i = 0; i < 2; i++)
+ printk("LCNTM%d: 0x%08x\n", i, ioread32(priv->base + RCAR_CSI2_LCNTM(i)));
+ }
+-#else
+-#define rcar_sci2_debug_show(args)
+-#endif /* RCAR_CSI2_DUMP */
+
+ static int rcar_csi2_set_phy_freq(struct rcar_csi2 *priv)
+ {
+--
+2.7.4
+
diff --git a/bsp/meta-rcar/meta-rcar-gen3-adas/recipes-kernel/linux/linux-renesas/0354-media-rcar_csi2-Disable-data-type-matching.patch b/bsp/meta-rcar/meta-rcar-gen3-adas/recipes-kernel/linux/linux-renesas/0354-media-rcar_csi2-Disable-data-type-matching.patch
new file mode 100644
index 00000000..4f3e0e07
--- /dev/null
+++ b/bsp/meta-rcar/meta-rcar-gen3-adas/recipes-kernel/linux/linux-renesas/0354-media-rcar_csi2-Disable-data-type-matching.patch
@@ -0,0 +1,58 @@
+From 67e7f6de9a3139e12e3112119a062230b4473d3d Mon Sep 17 00:00:00 2001
+From: Andrey Dolnikov <andrey.dolnikov@cogentembedded.com>
+Date: Mon, 12 Nov 2018 16:29:13 +0300
+Subject: [PATCH 174/211] media: rcar_csi2: Disable data type matching.
+
+Signed-off-by: Vladimir Barinov <vladimir.barinov@cogentembedded.com>
+---
+ drivers/media/platform/soc_camera/rcar_csi2.c | 20 +-------------------
+ 1 file changed, 1 insertion(+), 19 deletions(-)
+
+diff --git a/drivers/media/platform/soc_camera/rcar_csi2.c b/drivers/media/platform/soc_camera/rcar_csi2.c
+index deee4cc..ffb28c7 100644
+--- a/drivers/media/platform/soc_camera/rcar_csi2.c
++++ b/drivers/media/platform/soc_camera/rcar_csi2.c
+@@ -87,7 +87,7 @@
+
+ #define RCAR_CSI2_VCDT_VCDTN_EN (1 << 15)
+ #define RCAR_CSI2_VCDT_SEL_VCN (1 << 8)
+-#define RCAR_CSI2_VCDT_SEL_DTN_ON (1 << 6)
++#define RCAR_CSI2_VCDT_SEL_DTN_ON (0 << 6)
+ #define RCAR_CSI2_VCDT_SEL_DTN (1 << 0)
+
+ #define RCAR_CSI2_LINKCNT_MONITOR_EN (1 << 31)
+@@ -682,15 +682,6 @@ static int rcar_csi2_parse_dt(struct device_node *np,
+ return ret;
+
+ if (i < 2) {
+- if (!strcmp(str, "rgb888"))
+- config->vcdt |= (0x24 << (i * 16));
+- else if (!strcmp(str, "ycbcr422"))
+- config->vcdt |= (0x1e << (i * 16));
+- else if (!strcmp(str, "raw8"))
+- config->vcdt |= (0x2a << (i * 16));
+- else
+- config->vcdt |= 0;
+-
+ config->vcdt |= (ch << (8 + (i * 16)));
+ config->vcdt |= (RCAR_CSI2_VCDT_VCDTN_EN << (i * 16)) |
+ (RCAR_CSI2_VCDT_SEL_DTN_ON << (i * 16));
+@@ -698,15 +689,6 @@ static int rcar_csi2_parse_dt(struct device_node *np,
+ if (i >= 2) {
+ int j = (i - 2);
+
+- if (!strcmp(str, "rgb888"))
+- config->vcdt2 |= (0x24 << (j * 16));
+- else if (!strcmp(str, "ycbcr422"))
+- config->vcdt2 |= (0x1e << (j * 16));
+- else if (!strcmp(str, "raw8"))
+- config->vcdt2 |= (0x2a << (j * 16));
+- else
+- config->vcdt2 |= 0;
+-
+ config->vcdt2 |= (ch << (8 + (j * 16)));
+ config->vcdt2 |= (RCAR_CSI2_VCDT_VCDTN_EN << (j * 16)) |
+ (RCAR_CSI2_VCDT_SEL_DTN_ON << (j * 16));
+--
+2.7.4
+
diff --git a/bsp/meta-rcar/meta-rcar-gen3-adas/recipes-kernel/linux/linux-renesas/0355-gpu-drm-rcar-du-Extend-VSP1-DRM-interface.patch b/bsp/meta-rcar/meta-rcar-gen3-adas/recipes-kernel/linux/linux-renesas/0355-gpu-drm-rcar-du-Extend-VSP1-DRM-interface.patch
new file mode 100644
index 00000000..538ca4a6
--- /dev/null
+++ b/bsp/meta-rcar/meta-rcar-gen3-adas/recipes-kernel/linux/linux-renesas/0355-gpu-drm-rcar-du-Extend-VSP1-DRM-interface.patch
@@ -0,0 +1,547 @@
+From 67a755cc6ef9d7ffc36073922610ffab9f3c8dfe Mon Sep 17 00:00:00 2001
+From: Valentine Barshak <valentine.barshak@cogentembedded.com>
+Date: Tue, 13 Nov 2018 20:36:36 +0300
+Subject: [PATCH 175/211] gpu: drm: rcar-du: Extend VSP1-DRM interface
+
+This is based on the original "Extend VSP1-DRM interface" patch
+by Konstantin Kozhevnikov <Konstantin.Kozhevnikov@cogentembedded.com>
+which adds alpha plane and color key properties to DRM planes.
+
+Signed-off-by: Valentine Barshak <valentine.barshak@cogentembedded.com>
+---
+ drivers/gpu/drm/drm_fourcc.c | 1 +
+ drivers/gpu/drm/rcar-du/rcar_du_drv.h | 5 +
+ drivers/gpu/drm/rcar-du/rcar_du_kms.c | 38 ++++++
+ drivers/gpu/drm/rcar-du/rcar_du_plane.c | 2 +
+ drivers/gpu/drm/rcar-du/rcar_du_plane.h | 5 +
+ drivers/gpu/drm/rcar-du/rcar_du_vsp.c | 228 +++++++++++++++++++++++++++-----
+ drivers/gpu/drm/rcar-du/rcar_du_vsp.h | 7 +-
+ 7 files changed, 249 insertions(+), 37 deletions(-)
+
+diff --git a/drivers/gpu/drm/drm_fourcc.c b/drivers/gpu/drm/drm_fourcc.c
+index 9c0152d..5f1a175 100644
+--- a/drivers/gpu/drm/drm_fourcc.c
++++ b/drivers/gpu/drm/drm_fourcc.c
+@@ -106,6 +106,7 @@ const struct drm_format_info *__drm_format_info(u32 format)
+ {
+ static const struct drm_format_info formats[] = {
+ { .format = DRM_FORMAT_C8, .depth = 8, .num_planes = 1, .cpp = { 1, 0, 0 }, .hsub = 1, .vsub = 1 },
++ { .format = DRM_FORMAT_R8, .depth = 8, .num_planes = 1, .cpp = { 1, 0, 0 }, .hsub = 1, .vsub = 1 },
+ { .format = DRM_FORMAT_RGB332, .depth = 8, .num_planes = 1, .cpp = { 1, 0, 0 }, .hsub = 1, .vsub = 1 },
+ { .format = DRM_FORMAT_BGR233, .depth = 8, .num_planes = 1, .cpp = { 1, 0, 0 }, .hsub = 1, .vsub = 1 },
+ { .format = DRM_FORMAT_XRGB4444, .depth = 0, .num_planes = 1, .cpp = { 2, 0, 0 }, .hsub = 1, .vsub = 1 },
+diff --git a/drivers/gpu/drm/rcar-du/rcar_du_drv.h b/drivers/gpu/drm/rcar-du/rcar_du_drv.h
+index 504a188..dc20ebb 100644
+--- a/drivers/gpu/drm/rcar-du/rcar_du_drv.h
++++ b/drivers/gpu/drm/rcar-du/rcar_du_drv.h
+@@ -99,6 +99,11 @@ struct rcar_du_device {
+ struct drm_property *alpha;
+ struct drm_property *colorkey;
+ struct drm_property *colorkey_alpha;
++ struct drm_property *alphaplane;
++ struct drm_property *blend;
++ struct drm_property *ckey;
++ struct drm_property *ckey_set0;
++ struct drm_property *ckey_set1;
+ } props;
+
+ unsigned int dpad0_source;
+diff --git a/drivers/gpu/drm/rcar-du/rcar_du_kms.c b/drivers/gpu/drm/rcar-du/rcar_du_kms.c
+index d66ae53..f74bc6a 100644
+--- a/drivers/gpu/drm/rcar-du/rcar_du_kms.c
++++ b/drivers/gpu/drm/rcar-du/rcar_du_kms.c
+@@ -11,6 +11,7 @@
+ * (at your option) any later version.
+ */
+
++//#define DEBUG
+ #include <drm/drmP.h>
+ #include <drm/drm_atomic.h>
+ #include <drm/drm_atomic_helper.h>
+@@ -96,6 +97,12 @@ static const struct rcar_du_format_info rcar_du_format_infos[] = {
+ .planes = 2,
+ .pnmr = PnMR_SPIM_TP_OFF | PnMR_DDDF_YC,
+ .edf = PnDDCR4_EDF_NONE,
++ }, {
++ .fourcc = DRM_FORMAT_R8,
++ .bpp = 8,
++ .planes = 1,
++ .pnmr = PnMR_SPIM_TP_OFF | PnMR_DDDF_8BPP,
++ .edf = PnDDCR4_EDF_NONE,
+ },
+ /*
+ * The following formats are not supported on Gen2 and thus have no
+@@ -543,6 +550,37 @@ static int rcar_du_properties_init(struct rcar_du_device *rcdu)
+ return -ENOMEM;
+ }
+
++ rcdu->props.alphaplane =
++ drm_property_create(rcdu->ddev, DRM_MODE_PROP_OBJECT, "alphaplane", 1);
++ if (rcdu->props.alphaplane == NULL)
++ return -ENOMEM;
++
++ rcdu->props.alphaplane->values[0] = DRM_MODE_OBJECT_FB;
++
++ rcdu->props.blend =
++ drm_property_create_range(rcdu->ddev, 0, "blend",
++ 0, 0xffffffff);
++ if (rcdu->props.blend == NULL)
++ return -ENOMEM;
++
++ rcdu->props.ckey =
++ drm_property_create_range(rcdu->ddev, 0, "ckey",
++ 0, 0xffffffff);
++ if (rcdu->props.ckey == NULL)
++ return -ENOMEM;
++
++ rcdu->props.ckey_set0 =
++ drm_property_create_range(rcdu->ddev, 0, "ckey_set0",
++ 0, 0xffffffff);
++ if (rcdu->props.ckey_set0 == NULL)
++ return -ENOMEM;
++
++ rcdu->props.ckey_set1 =
++ drm_property_create_range(rcdu->ddev, 0, "ckey_set1",
++ 0, 0xffffffff);
++ if (rcdu->props.ckey_set1 == NULL)
++ return -ENOMEM;
++
+ return 0;
+ }
+
+diff --git a/drivers/gpu/drm/rcar-du/rcar_du_plane.c b/drivers/gpu/drm/rcar-du/rcar_du_plane.c
+index 1b70db3..e934b4c 100644
+--- a/drivers/gpu/drm/rcar-du/rcar_du_plane.c
++++ b/drivers/gpu/drm/rcar-du/rcar_du_plane.c
+@@ -11,6 +11,7 @@
+ * (at your option) any later version.
+ */
+
++//#define DEBUG
+ #include <drm/drmP.h>
+ #include <drm/drm_atomic.h>
+ #include <drm/drm_atomic_helper.h>
+@@ -790,6 +791,7 @@ static const uint32_t formats[] = {
+ DRM_FORMAT_NV12,
+ DRM_FORMAT_NV21,
+ DRM_FORMAT_NV16,
++ DRM_FORMAT_R8,
+ };
+
+ int rcar_du_planes_init(struct rcar_du_group *rgrp)
+diff --git a/drivers/gpu/drm/rcar-du/rcar_du_plane.h b/drivers/gpu/drm/rcar-du/rcar_du_plane.h
+index e0ddecf..3e9dfdb 100644
+--- a/drivers/gpu/drm/rcar-du/rcar_du_plane.h
++++ b/drivers/gpu/drm/rcar-du/rcar_du_plane.h
+@@ -70,6 +70,11 @@ struct rcar_du_plane_state {
+ unsigned int alpha;
+ unsigned int colorkey;
+ unsigned int colorkey_alpha;
++ struct drm_framebuffer *alphaplane;
++ unsigned int blend;
++ unsigned int ckey;
++ unsigned int ckey_set0;
++ unsigned int ckey_set1;
+ };
+
+ static inline struct rcar_du_plane_state *
+diff --git a/drivers/gpu/drm/rcar-du/rcar_du_vsp.c b/drivers/gpu/drm/rcar-du/rcar_du_vsp.c
+index c44d336..2b076cf 100644
+--- a/drivers/gpu/drm/rcar-du/rcar_du_vsp.c
++++ b/drivers/gpu/drm/rcar-du/rcar_du_vsp.c
+@@ -11,6 +11,7 @@
+ * (at your option) any later version.
+ */
+
++//#define DEBUG
+ #include <drm/drmP.h>
+ #include <drm/drm_atomic_helper.h>
+ #include <drm/drm_crtc.h>
+@@ -96,6 +97,16 @@ void rcar_du_vsp_enable(struct rcar_du_crtc *crtc)
+
+ void rcar_du_vsp_disable(struct rcar_du_crtc *crtc)
+ {
++ struct rcar_du_vsp *vsp = crtc->vsp;
++ struct rcar_du_vsp_plane *primary = &vsp->planes[0];
++ struct rcar_du_vsp_plane_state *rstate = to_rcar_vsp_plane_state(primary->plane.state);
++
++ /* ...drop alpha-plane associated with primary plane (why only primary? - tbd) */
++ if (rstate->alphaplane) {
++ drm_framebuffer_unreference(rstate->alphaplane);
++ rstate->alphaplane = NULL;
++ }
++
+ vsp1_du_setup_lif(crtc->vsp->vsp, crtc->vsp_pipe, NULL);
+ }
+
+@@ -142,6 +153,7 @@ static const u32 formats_kms[] = {
+ DRM_FORMAT_YVU422,
+ DRM_FORMAT_YUV444,
+ DRM_FORMAT_YVU444,
++ DRM_FORMAT_R8,
+ };
+
+ static const u32 formats_v4l2[] = {
+@@ -170,6 +182,7 @@ static const u32 formats_v4l2[] = {
+ V4L2_PIX_FMT_YVU422M,
+ V4L2_PIX_FMT_YUV444M,
+ V4L2_PIX_FMT_YVU444M,
++ V4L2_PIX_FMT_GREY,
+ };
+
+ static void rcar_du_vsp_plane_setup(struct rcar_du_vsp_plane *plane)
+@@ -217,6 +230,28 @@ static void rcar_du_vsp_plane_setup(struct rcar_du_vsp_plane *plane)
+ }
+ }
+
++ /* ...add alpha-plane as needed */
++ if (state->alphaplane) {
++ i = state->format->planes;
++ cfg.alpha_mem = sg_dma_address(state->sg_tables[i].sgl);
++ cfg.alpha_pitch = state->alphaplane->pitches[0];
++ pr_debug("alpha-%d: set alpha-mem address: %llx, pitch=%d\n",
++ i, (unsigned long long)cfg.alpha_mem, cfg.alpha_pitch);
++ }
++
++ /* ...add blending formula as needed */
++ if (state->blend) {
++ cfg.blend = state->blend;
++ pr_debug("set blending formula: %X\n", cfg.blend);
++ }
++
++ /* ...add color key property as needed */
++ if (state->ckey) {
++ cfg.ckey = state->ckey;
++ cfg.ckey_set0 = state->ckey_set0;
++ cfg.ckey_set1 = state->ckey_set1;
++ }
++
+ vsp1_du_atomic_update(plane->vsp->vsp, crtc->vsp_pipe,
+ plane->index, &cfg);
+ }
+@@ -285,6 +320,23 @@ static int rcar_du_vsp_plane_prepare_fb(struct drm_plane *plane,
+ if (ret)
+ goto fail;
+
++ /* ...check if we have alpha-plane attached */
++ if (rstate->alphaplane) {
++ struct drm_gem_cma_object *gem = drm_fb_cma_get_gem_obj(rstate->alphaplane, 0);
++ struct sg_table *sgt = &rstate->sg_tables[i++];
++
++ ret = dma_get_sgtable(rcdu->dev, sgt, gem->vaddr, gem->paddr, gem->base.size);
++ if (ret)
++ goto fail;
++
++ ret = vsp1_du_map_sg(vsp->vsp, sgt);
++ if (!ret) {
++ sg_free_table(sgt);
++ ret = -ENOMEM;
++ goto fail;
++ }
++ }
++
+ return 0;
+
+ fail:
+@@ -314,6 +366,14 @@ static void rcar_du_vsp_plane_cleanup_fb(struct drm_plane *plane,
+ vsp1_du_unmap_sg(vsp->vsp, sgt);
+ sg_free_table(sgt);
+ }
++
++ if (rstate->alphaplane) {
++ struct sg_table *sgt = &rstate->sg_tables[i];
++
++ vsp1_du_unmap_sg(vsp->vsp, sgt);
++ sg_free_table(sgt);
++ pr_debug("unmap alpha-plane\n");
++ }
+ }
+
+ static int rcar_du_vsp_plane_atomic_check(struct drm_plane *plane,
+@@ -356,6 +416,13 @@ rcar_du_vsp_plane_atomic_duplicate_state(struct drm_plane *plane)
+ if (copy == NULL)
+ return NULL;
+
++ if (copy->alphaplane) {
++ drm_framebuffer_reference(copy->alphaplane);
++ pr_debug("duplicate alpha-plane '%p' (refcount=%d)\n",
++ copy->alphaplane,
++ drm_framebuffer_read_refcount(copy->alphaplane));
++ }
++
+ __drm_atomic_helper_plane_duplicate_state(plane, &copy->state);
+ copy->alpha = to_rcar_vsp_plane_state(plane->state)->alpha;
+ copy->colorkey = to_rcar_vsp_plane_state(plane->state)->colorkey;
+@@ -367,8 +434,17 @@ rcar_du_vsp_plane_atomic_duplicate_state(struct drm_plane *plane)
+ static void rcar_du_vsp_plane_atomic_destroy_state(struct drm_plane *plane,
+ struct drm_plane_state *state)
+ {
++ struct rcar_du_vsp_plane_state *rstate = to_rcar_vsp_plane_state(state);
++
++ if (rstate->alphaplane) {
++ pr_debug("unref alpha-plane '%p' (refcount=%d)\n",
++ rstate->alphaplane,
++ drm_framebuffer_read_refcount(rstate->alphaplane));
++ drm_framebuffer_unreference(rstate->alphaplane);
++ }
++
+ __drm_atomic_helper_plane_destroy_state(state);
+- kfree(to_rcar_vsp_plane_state(state));
++ kfree(rstate);
+ }
+
+ static void rcar_du_vsp_plane_reset(struct drm_plane *plane)
+@@ -376,6 +452,8 @@ static void rcar_du_vsp_plane_reset(struct drm_plane *plane)
+ struct rcar_du_vsp_plane_state *state;
+
+ if (plane->state) {
++ pr_debug("reset plane '%p'\n",
++ to_rcar_vsp_plane_state(plane->state)->alphaplane);
+ rcar_du_vsp_plane_atomic_destroy_state(plane, plane->state);
+ plane->state = NULL;
+ }
+@@ -403,9 +481,10 @@ int rcar_du_vsp_write_back(struct drm_device *dev, void *data,
+ struct rcar_du_crtc *rcrtc;
+ struct rcar_du_device *rcdu;
+ const struct drm_display_mode *mode;
+- u32 pixelformat, bpp;
+- unsigned int pitch;
++ struct drm_framebuffer *fb;
+ dma_addr_t mem[3];
++ struct sg_table sg_tables[3];
++ int i = 0;
+
+ obj = drm_mode_object_find(dev, sh->crtc_id, DRM_MODE_OBJECT_CRTC);
+ if (!obj)
+@@ -416,65 +495,89 @@ int rcar_du_vsp_write_back(struct drm_device *dev, void *data,
+ rcdu = rcrtc->group->dev;
+ mode = &rcrtc->crtc.state->adjusted_mode;
+
+- switch (sh->fmt) {
+- case DRM_FORMAT_RGB565:
+- bpp = 16;
+- pixelformat = V4L2_PIX_FMT_RGB565;
+- break;
+- case DRM_FORMAT_ARGB1555:
+- bpp = 16;
+- pixelformat = V4L2_PIX_FMT_ARGB555;
+- break;
+- case DRM_FORMAT_ARGB8888:
+- bpp = 32;
+- pixelformat = V4L2_PIX_FMT_ABGR32;
+- break;
+- default:
+- dev_err(rcdu->dev, "specified format is not supported.\n");
++ fb = drm_framebuffer_lookup(dev, sh->buff);
++ if (!fb) {
++ dev_err(dev->dev,
++ "failed to lookup destination framebuffer '%lu'\n",
++ sh->buff);
+ return -EINVAL;
+ }
+
+- pitch = mode->hdisplay * bpp / 8;
++ /* ...check framebuffer is okay */
++ if ((fb->width != (mode->hdisplay)) ||
++ (fb->height != (mode->vdisplay))) {
++ dev_err(dev->dev, "wrong fb mode: %d*%d vs %d*%d\n",
++ fb->width, fb->height, mode->hdisplay, mode->vdisplay);
++ ret = -EINVAL;
++ goto done;
++ }
+
+- mem[0] = sh->buff;
+- mem[1] = 0;
+- mem[2] = 0;
++ /* ...need to verify compatibility of output format, I guess - tbd */
+
+- if (sh->width != mode->hdisplay ||
+- sh->height != mode->vdisplay)
+- return -EINVAL;
++ /* ...fill memory planes addresses */
++ for (i = 0; i < 3; i++) {
++ struct drm_gem_cma_object *gem;
++ struct sg_table *sgt = &sg_tables[i];
+
+- if ((pitch * mode->vdisplay) > sh->buff_len)
+- return -EINVAL;
++ gem = drm_fb_cma_get_gem_obj(fb, i);
++ if (!gem)
++ break;
++
++ ret = dma_get_sgtable(rcdu->dev, sgt, gem->vaddr, gem->paddr,
++ gem->base.size);
++ if (ret)
++ goto done;
++
++ ret = vsp1_du_map_sg(rcrtc->vsp->vsp, sgt);
++ if (!ret) {
++ sg_free_table(sgt);
++ ret = -ENOMEM;
++ goto done;
++ }
++ mem[i] = sg_dma_address(sg_tables[i].sgl) + fb->offsets[i];
++ }
+
+- ret = vsp1_du_setup_wb(rcrtc->vsp->vsp, pixelformat, pitch, mem,
+- rcrtc->vsp_pipe);
++ dev_info(dev->dev, "setup write-back (pixfmt=%X, %u*%u, planes: %d)\n",
++ fb->format->format, fb->width, fb->height, i);
++
++ ret = vsp1_du_setup_wb(rcrtc->vsp->vsp, fb->format->format,
++ fb->pitches[0], mem, rcrtc->vsp_pipe);
+ if (ret != 0)
+- return ret;
++ goto done;
+
+ ret = vsp1_du_wait_wb(rcrtc->vsp->vsp, WB_STAT_CATP_SET,
+ rcrtc->vsp_pipe);
+ if (ret != 0)
+- return ret;
++ goto done;
+
+ ret = rcar_du_async_commit(dev, crtc);
+ if (ret != 0)
+- return ret;
++ goto done;
+
+ ret = vsp1_du_wait_wb(rcrtc->vsp->vsp, WB_STAT_CATP_START,
+ rcrtc->vsp_pipe);
+ if (ret != 0)
+- return ret;
++ goto done;
+
+ ret = rcar_du_async_commit(dev, crtc);
+ if (ret != 0)
+- return ret;
++ goto done;
+
+ ret = vsp1_du_wait_wb(rcrtc->vsp->vsp, WB_STAT_CATP_DONE,
+ rcrtc->vsp_pipe);
+ if (ret != 0)
+- return ret;
++ goto done;
++
++done:
++ /* ...unmap all tables */
++ while (i--) {
++ struct sg_table *sgt = &sg_tables[i];
++
++ vsp1_du_unmap_sg(rcrtc->vsp->vsp, sgt);
++ sg_free_table(sgt);
++ }
+
++ drm_framebuffer_unreference(fb);
+ return ret;
+ }
+
+@@ -518,7 +621,38 @@ static int rcar_du_vsp_plane_atomic_set_property(struct drm_plane *plane,
+ rstate->colorkey = val;
+ else if (property == rcdu->props.colorkey_alpha)
+ rstate->colorkey_alpha = val;
+- else
++ else if (property == rcdu->props.blend)
++ rstate->blend = val;
++ else if (property == rcdu->props.ckey)
++ rstate->ckey = val;
++ else if (property == rcdu->props.ckey_set0)
++ rstate->ckey_set0 = val;
++ else if (property == rcdu->props.ckey_set1)
++ rstate->ckey_set1 = val;
++ else if (property == rcdu->props.alphaplane) {
++ if (rstate->alphaplane) {
++ pr_debug("unref alpha-plane '%p' (refcount=%d)\n",
++ rstate->alphaplane,
++ drm_framebuffer_read_refcount(rstate->alphaplane));
++ drm_framebuffer_unreference(rstate->alphaplane);
++ }
++ rstate->alphaplane = drm_framebuffer_lookup(plane->dev, val);
++ if (rstate->alphaplane) {
++ pr_debug("use alpha-plane '%p' (refcount=%d)\n",
++ rstate->alphaplane,
++ drm_framebuffer_read_refcount(rstate->alphaplane));
++ /* ...the way how we handle this leads to a "loss"
++ * of plane reference (it is acquired within
++ * "drm_property_change_valid_get" but not returned
++ * in symmetric "drm_property_change_valid_put")
++ * Whether it is a bug or was done intentionally,
++ * I don't know. For a moment just drop that
++ * extra reference right here.
++ */
++ if (0)
++ drm_framebuffer_unreference(rstate->alphaplane);
++ }
++ } else
+ return -EINVAL;
+
+ return 0;
+@@ -538,6 +672,16 @@ static int rcar_du_vsp_plane_atomic_get_property(struct drm_plane *plane,
+ *val = rstate->colorkey;
+ else if (property == rcdu->props.colorkey_alpha)
+ *val = rstate->colorkey_alpha;
++ else if (property == rcdu->props.alphaplane)
++ *val = (rstate->alphaplane ? rstate->alphaplane->base.id : 0);
++ else if (property == rcdu->props.blend)
++ *val = rstate->blend;
++ else if (property == rcdu->props.ckey)
++ *val = rstate->ckey;
++ else if (property == rcdu->props.ckey_set0)
++ *val = rstate->ckey_set0;
++ else if (property == rcdu->props.ckey_set1)
++ *val = rstate->ckey_set1;
+ else
+ return -EINVAL;
+
+@@ -633,8 +777,10 @@ int rcar_du_vsp_init(struct rcar_du_vsp *vsp, struct device_node *np,
+ drm_plane_helper_add(&plane->plane,
+ &rcar_du_vsp_plane_helper_funcs);
+
++#if 0 // ...use same set of properties for all planes
+ if (type == DRM_PLANE_TYPE_PRIMARY)
+ continue;
++#endif
+
+ drm_object_attach_property(&plane->plane.base,
+ rcdu->props.alpha, 255);
+@@ -647,6 +793,16 @@ int rcar_du_vsp_init(struct rcar_du_vsp *vsp, struct device_node *np,
+ 0);
+ drm_plane_create_zpos_property(&plane->plane, 1, 1,
+ vsp->num_planes - 1);
++ drm_object_attach_property(&plane->plane.base,
++ rcdu->props.alphaplane, 0);
++ drm_object_attach_property(&plane->plane.base,
++ rcdu->props.blend, 0);
++ drm_object_attach_property(&plane->plane.base,
++ rcdu->props.ckey, 0);
++ drm_object_attach_property(&plane->plane.base,
++ rcdu->props.ckey_set0, 0);
++ drm_object_attach_property(&plane->plane.base,
++ rcdu->props.ckey_set1, 0);
+ }
+
+ return 0;
+diff --git a/drivers/gpu/drm/rcar-du/rcar_du_vsp.h b/drivers/gpu/drm/rcar-du/rcar_du_vsp.h
+index 93dbb9e..083d065 100644
+--- a/drivers/gpu/drm/rcar-du/rcar_du_vsp.h
++++ b/drivers/gpu/drm/rcar-du/rcar_du_vsp.h
+@@ -55,11 +55,16 @@ struct rcar_du_vsp_plane_state {
+ struct drm_plane_state state;
+
+ const struct rcar_du_format_info *format;
+- struct sg_table sg_tables[3];
++ struct sg_table sg_tables[4];
+
+ unsigned int alpha;
+ u32 colorkey;
+ u32 colorkey_alpha;
++ struct drm_framebuffer *alphaplane;
++ unsigned int blend;
++ unsigned int ckey;
++ unsigned int ckey_set0;
++ unsigned int ckey_set1;
+ };
+
+ static inline struct rcar_du_vsp_plane_state *
+--
+2.7.4
+
diff --git a/bsp/meta-rcar/meta-rcar-gen3-adas/recipes-kernel/linux/linux-renesas/0356-media-platform-vsp1-Extend-DRM-VSP1-interface.patch b/bsp/meta-rcar/meta-rcar-gen3-adas/recipes-kernel/linux/linux-renesas/0356-media-platform-vsp1-Extend-DRM-VSP1-interface.patch
new file mode 100644
index 00000000..c6abd77a
--- /dev/null
+++ b/bsp/meta-rcar/meta-rcar-gen3-adas/recipes-kernel/linux/linux-renesas/0356-media-platform-vsp1-Extend-DRM-VSP1-interface.patch
@@ -0,0 +1,374 @@
+From 918dd4d7f4cc9af593617a0bef51bfc531b74b53 Mon Sep 17 00:00:00 2001
+From: Valentine Barshak <valentine.barshak@cogentembedded.com>
+Date: Tue, 13 Nov 2018 18:11:49 +0300
+Subject: [PATCH 176/211] media: platform: vsp1: Extend DRM-VSP1 interface
+
+- Extend DRM-VSP1 interface
+- Add alpha-plane support for VSP1
+
+This is based on the original "extend DRM-VSP1 interface" patch by
+Konstantin Kozhevnikov <Konstantin.Kozhevnikov@cogentembedded.com>.
+
+The only changes are the following:
+ * in vsp1_du_setup_lif() conversion back to ARGB is forced
+ on the pipe's output (pipe->output) instead of the first
+ one (vsp1->wpf[0]);
+ * "ckey", "ckey_set0", and "ckey_set1" properties are used only
+ when the conflicting "colorkey" property is disabled.
+
+Signed-off-by: Valentine Barshak <valentine.barshak@cogentembedded.com>
+---
+ drivers/media/platform/vsp1/vsp1_brx.c | 17 ++++++++++++++++-
+ drivers/media/platform/vsp1/vsp1_dl.c | 5 +++++
+ drivers/media/platform/vsp1/vsp1_drm.c | 32 ++++++++++++++++++++++++++++++--
+ drivers/media/platform/vsp1/vsp1_lif.c | 2 +-
+ drivers/media/platform/vsp1/vsp1_pipe.c | 4 ++++
+ drivers/media/platform/vsp1/vsp1_rpf.c | 26 +++++++++++++++++++++++---
+ drivers/media/platform/vsp1/vsp1_rwpf.c | 1 +
+ drivers/media/platform/vsp1/vsp1_rwpf.h | 6 ++++++
+ drivers/media/platform/vsp1/vsp1_wpf.c | 4 ++++
+ include/media/vsp1.h | 6 ++++++
+ 10 files changed, 96 insertions(+), 7 deletions(-)
+
+diff --git a/drivers/media/platform/vsp1/vsp1_brx.c b/drivers/media/platform/vsp1/vsp1_brx.c
+index 942ff12..7e82821 100644
+--- a/drivers/media/platform/vsp1/vsp1_brx.c
++++ b/drivers/media/platform/vsp1/vsp1_brx.c
+@@ -392,6 +392,20 @@ static void brx_configure_stream(struct vsp1_entity *entity,
+ ctrl |= VI6_BRU_CTRL_SRCSEL_BRUIN(i);
+
+ vsp1_brx_write(brx, dlb, VI6_BRU_CTRL(i), ctrl);
++ dev_dbg(entity->vsp1->dev, "brx#%d: ctrl=%X\n", i, ctrl);
++
++ /* ...set blending formula as defined by the input RPF */
++ if (brx->inputs[i].rpf) {
++ if (brx->inputs[i].rpf->blend) {
++ vsp1_brx_write(brx, dlb, VI6_BRU_BLD(i),
++ brx->inputs[i].rpf->blend);
++ dev_dbg(entity->vsp1->dev,
++ "brx#%d(#%d): setup blending formula: %X\n",
++ i, brx->inputs[i].rpf->entity.index,
++ brx->inputs[i].rpf->blend);
++ continue;
++ }
++ }
+
+ /*
+ * Harcode the blending formula to
+@@ -458,7 +472,8 @@ struct vsp1_brx *vsp1_brx_create(struct vsp1_device *vsp1,
+ v4l2_ctrl_new_std(&brx->ctrls, &brx_ctrl_ops, V4L2_CID_BG_COLOR,
+ 0, 0xffffff, 1, 0);
+
+- brx->bgcolor = 0;
++ /* ...for YUV, set black background */
++ brx->bgcolor = 0x00800080;
+
+ brx->entity.subdev.ctrl_handler = &brx->ctrls;
+
+diff --git a/drivers/media/platform/vsp1/vsp1_dl.c b/drivers/media/platform/vsp1/vsp1_dl.c
+index 48542854..f501307 100644
+--- a/drivers/media/platform/vsp1/vsp1_dl.c
++++ b/drivers/media/platform/vsp1/vsp1_dl.c
+@@ -373,6 +373,7 @@ void vsp1_dl_set_addr_auto_fld(struct vsp1_dl_body *dlb,
+ u32 y_top_index, y_bot_index;
+ u32 u_top_index, u_bot_index;
+ u32 v_top_index, v_bot_index;
++ u32 alpha_index;
+ dma_addr_t y_top_addr, y_bot_addr;
+ dma_addr_t u_top_addr, u_bot_addr;
+ dma_addr_t v_top_addr, v_bot_addr;
+@@ -388,6 +389,7 @@ void vsp1_dl_set_addr_auto_fld(struct vsp1_dl_body *dlb,
+ u_bot_index = rpf->entity.index * 8 + 3;
+ v_top_index = rpf->entity.index * 8 + 4;
+ v_bot_index = rpf->entity.index * 8 + 5;
++ alpha_index = rpf->entity.index * 8 + 6;
+
+ switch (rpf->fmtinfo->fourcc) {
+ case V4L2_PIX_FMT_YUV420M:
+@@ -436,6 +438,9 @@ void vsp1_dl_set_addr_auto_fld(struct vsp1_dl_body *dlb,
+ dlb->src_dst_addr[u_bot_index].addr = u_bot_addr;
+ dlb->src_dst_addr[v_top_index].addr = v_top_addr;
+ dlb->src_dst_addr[v_bot_index].addr = v_bot_addr;
++
++ /* ...set alpha-plane address as needed */
++ dlb->src_dst_addr[alpha_index].addr = rpf->mem.alpha;
+ }
+
+ static struct vsp1_dl_list *vsp1_dl_list_alloc(struct vsp1_dl_manager *dlm)
+diff --git a/drivers/media/platform/vsp1/vsp1_drm.c b/drivers/media/platform/vsp1/vsp1_drm.c
+index 68364d4..27aeabd 100644
+--- a/drivers/media/platform/vsp1/vsp1_drm.c
++++ b/drivers/media/platform/vsp1/vsp1_drm.c
+@@ -7,6 +7,7 @@
+ * Contact: Laurent Pinchart (laurent.pinchart@ideasonboard.com)
+ */
+
++//#define DEBUG
+ #include <linux/device.h>
+ #include <linux/dma-mapping.h>
+ #include <linux/slab.h>
+@@ -207,7 +208,12 @@ static int vsp1_du_pipeline_setup_rpf(struct vsp1_device *vsp1,
+ __func__, format.format.width, format.format.height,
+ format.format.code, rpf->entity.index);
+
++#if 0
+ format.format.code = MEDIA_BUS_FMT_ARGB8888_1X32;
++#else
++ /* ...always blend in YUV colorspace; apply conversion as needed */
++ format.format.code = MEDIA_BUS_FMT_AYUV8_1X32;
++#endif
+
+ ret = v4l2_subdev_call(&rpf->entity.subdev, pad, set_fmt, NULL,
+ &format);
+@@ -512,7 +518,14 @@ static int vsp1_du_pipeline_setup_output(struct vsp1_device *vsp1,
+ format.pad = RWPF_PAD_SINK;
+ format.format.width = drm_pipe->width;
+ format.format.height = drm_pipe->height;
++#if 0
+ format.format.code = MEDIA_BUS_FMT_ARGB8888_1X32;
++#else
++ /* ...always blend in YUV colorspace;
++ * apply conversion as needed
++ */
++ format.format.code = MEDIA_BUS_FMT_AYUV8_1X32;
++#endif
+ format.format.field = V4L2_FIELD_NONE;
+
+ ret = v4l2_subdev_call(&pipe->output->entity.subdev, pad, set_fmt, NULL,
+@@ -525,6 +538,13 @@ static int vsp1_du_pipeline_setup_output(struct vsp1_device *vsp1,
+ format.format.code, pipe->output->entity.index);
+
+ format.pad = RWPF_PAD_SOURCE;
++ /* ...force conversion back to ARGB at the output */
++ format.format.code = MEDIA_BUS_FMT_ARGB8888_1X32;
++ ret = v4l2_subdev_call(&pipe->output->entity.subdev, pad, set_fmt, NULL,
++ &format);
++ if (ret < 0)
++ return ret;
++
+ ret = v4l2_subdev_call(&pipe->output->entity.subdev, pad, get_fmt, NULL,
+ &format);
+ if (ret < 0)
+@@ -846,12 +866,14 @@ int vsp1_du_atomic_update(struct device *dev, unsigned int pipe_index,
+ }
+
+ dev_dbg(vsp1->dev,
+- "%s: RPF%u: (%u,%u)/%ux%u -> (%u,%u)/%ux%u (%08x), pitch %u dma { %pad, %pad, %pad } zpos %u\n",
++ "%s: RPF%u: (%u,%u)/%ux%u -> (%u,%u)/%ux%u (%08x), pitch %u "
++ "dma { %pad, %pad, %pad } zpos %u, alpha %pad, ckey %x/%x/%x\n",
+ __func__, rpf_index,
+ cfg->src.left, cfg->src.top, cfg->src.width, cfg->src.height,
+ cfg->dst.left, cfg->dst.top, cfg->dst.width, cfg->dst.height,
+ cfg->pixelformat, cfg->pitch, &cfg->mem[0], &cfg->mem[1],
+- &cfg->mem[2], cfg->zpos);
++ &cfg->mem[2], cfg->zpos, &cfg->alpha_mem, cfg->ckey,
++ cfg->ckey_set0, cfg->ckey_set1);
+
+ /*
+ * Store the format, stride, memory buffer address, crop and compose
+@@ -879,6 +901,11 @@ int vsp1_du_atomic_update(struct device *dev, unsigned int pipe_index,
+ rpf->colorkey_en = cfg->colorkey_en;
+ rpf->colorkey_alpha = cfg->colorkey_alpha;
+ rpf->interlaced = cfg->interlaced;
++ rpf->alpha_pitch = cfg->alpha_pitch;
++ rpf->ckey = cfg->ckey;
++ rpf->ckey_set0 = cfg->ckey_set0;
++ rpf->ckey_set1 = cfg->ckey_set1;
++ rpf->blend = cfg->blend;
+
+ if ((vsp1->ths_quirks & VSP1_AUTO_FLD_NOT_SUPPORT) &&
+ rpf->interlaced) {
+@@ -890,6 +917,7 @@ int vsp1_du_atomic_update(struct device *dev, unsigned int pipe_index,
+ rpf->mem.addr[0] = cfg->mem[0];
+ rpf->mem.addr[1] = cfg->mem[1];
+ rpf->mem.addr[2] = cfg->mem[2];
++ rpf->mem.alpha = cfg->alpha_mem;
+
+ vsp1->drm->inputs[rpf_index].crop = cfg->src;
+ vsp1->drm->inputs[rpf_index].compose = cfg->dst;
+diff --git a/drivers/media/platform/vsp1/vsp1_lif.c b/drivers/media/platform/vsp1/vsp1_lif.c
+index eae5e6a..86dbaa4 100644
+--- a/drivers/media/platform/vsp1/vsp1_lif.c
++++ b/drivers/media/platform/vsp1/vsp1_lif.c
+@@ -116,7 +116,7 @@ static void lif_configure_stream(struct vsp1_entity *entity,
+
+ vsp1_lif_write(lif, dlb, VI6_LIF_CTRL,
+ (obth << VI6_LIF_CTRL_OBTH_SHIFT) |
+- (format->code == 0 ? VI6_LIF_CTRL_CFMT : 0) |
++ (format->code != MEDIA_BUS_FMT_ARGB8888_1X32 ? VI6_LIF_CTRL_CFMT : 0) |
+ VI6_LIF_CTRL_REQSEL | VI6_LIF_CTRL_LIF_EN);
+
+ /*
+diff --git a/drivers/media/platform/vsp1/vsp1_pipe.c b/drivers/media/platform/vsp1/vsp1_pipe.c
+index 17b9812..5d23cfd 100644
+--- a/drivers/media/platform/vsp1/vsp1_pipe.c
++++ b/drivers/media/platform/vsp1/vsp1_pipe.c
+@@ -141,6 +141,10 @@ static const struct vsp1_format_info vsp1_video_formats[] = {
+ VI6_FMT_Y_U_V_444, VI6_RPF_DSWAP_P_LLS | VI6_RPF_DSWAP_P_LWS |
+ VI6_RPF_DSWAP_P_WDS | VI6_RPF_DSWAP_P_BTS,
+ 3, { 8, 8, 8 }, false, true, 1, 1, false },
++ { V4L2_PIX_FMT_GREY, MEDIA_BUS_FMT_Y8_1X8,
++ /*VI6_FMT_Y_U_V_444*/0xDEAD, VI6_RPF_DSWAP_P_LLS | VI6_RPF_DSWAP_P_LWS |
++ VI6_RPF_DSWAP_P_WDS | VI6_RPF_DSWAP_P_BTS,
++ 1, { 8, 0, 0 }, false, false, 0, 0, false },
+ };
+
+ /**
+diff --git a/drivers/media/platform/vsp1/vsp1_rpf.c b/drivers/media/platform/vsp1/vsp1_rpf.c
+index bb24a42..9875b0b 100644
+--- a/drivers/media/platform/vsp1/vsp1_rpf.c
++++ b/drivers/media/platform/vsp1/vsp1_rpf.c
+@@ -7,6 +7,7 @@
+ * Contact: Laurent Pinchart (laurent.pinchart@ideasonboard.com)
+ */
+
++//#define DEBUG
+ #include <linux/device.h>
+
+ #include <media/v4l2-subdev.h>
+@@ -89,8 +90,10 @@ static void rpf_configure_stream(struct vsp1_entity *entity,
+ if (sink_format->code != source_format->code)
+ infmt |= VI6_RPF_INFMT_CSC;
+
++ dev_dbg(entity->vsp1->dev, "rpf#%d: infmt=%x (csc=%d)\n",
++ rpf->entity.index, infmt, !!(infmt & VI6_RPF_INFMT_CSC));
+ vsp1_rpf_write(rpf, dlb, VI6_RPF_INFMT, infmt);
+- vsp1_rpf_write(rpf, dlb, VI6_RPF_DSWAP, fmtinfo->swap);
++ vsp1_rpf_write(rpf, dlb, VI6_RPF_DSWAP, fmtinfo->swap | 0xF00);
+
+ /* Output location */
+ if (pipe->brx) {
+@@ -113,6 +116,17 @@ static void rpf_configure_stream(struct vsp1_entity *entity,
+ (left << VI6_RPF_LOC_HCOORD_SHIFT) |
+ (top << VI6_RPF_LOC_VCOORD_SHIFT));
+
++ // ...setup alpha-plane as required
++ if (rpf->mem.alpha) {
++ vsp1_rpf_write(rpf, dlb, VI6_RPF_SRCM_ADDR_AI, rpf->mem.alpha);
++ vsp1_rpf_write(rpf, dlb, VI6_RPF_ALPH_SEL, VI6_RPF_ALPH_SEL_ASEL_8B_PLANE);
++ vsp1_rpf_write(rpf, dlb, VI6_RPF_SRCM_ASTRIDE, rpf->alpha_pitch);
++ dev_dbg(entity->vsp1->dev,
++ "rpf#%d: setup alpha-plane: buffer=%pad, stride=%u\n",
++ rpf->entity.index, &rpf->mem.alpha, rpf->alpha_pitch);
++ goto out;
++ }
++
+ /*
+ * On Gen2 use the alpha channel (extended to 8 bits) when available or
+ * a fixed alpha value set through the V4L2_CID_ALPHA_COMPONENT control
+@@ -168,7 +182,9 @@ static void rpf_configure_stream(struct vsp1_entity *entity,
+ if (entity->vsp1->info->gen == 3) {
+ u32 mult;
+
+- if (fmtinfo->alpha &&
++ dev_dbg(entity->vsp1->dev, "rpf#%d: alpha=%x, fourcc=%x\n",
++ rpf->entity.index, fmtinfo->alpha, fmtinfo->fourcc);
++ if (0 && fmtinfo->alpha &&
+ fmtinfo->fourcc != V4L2_PIX_FMT_ARGB555) {
+ /*
+ * When the input contains an alpha channel enable the
+@@ -199,6 +215,7 @@ static void rpf_configure_stream(struct vsp1_entity *entity,
+ rpf->mult_alpha = mult;
+ }
+
++out:
+ vsp1_rpf_write(rpf, dlb, VI6_RPF_MSK_CTRL, 0);
+
+ if (rpf->colorkey_en) {
+@@ -207,7 +224,10 @@ static void rpf_configure_stream(struct vsp1_entity *entity,
+ vsp1_rpf_write(rpf, dlb, VI6_RPF_CKEY_CTRL,
+ VI6_RPF_CKEY_CTRL_SAPE0);
+ } else {
+- vsp1_rpf_write(rpf, dlb, VI6_RPF_CKEY_CTRL, 0);
++ /* ...set up color keying */
++ vsp1_rpf_write(rpf, dlb, VI6_RPF_CKEY_CTRL, rpf->ckey);
++ vsp1_rpf_write(rpf, dlb, VI6_RPF_CKEY_SET0, rpf->ckey_set0);
++ vsp1_rpf_write(rpf, dlb, VI6_RPF_CKEY_SET1, rpf->ckey_set1);
+ }
+ }
+
+diff --git a/drivers/media/platform/vsp1/vsp1_rwpf.c b/drivers/media/platform/vsp1/vsp1_rwpf.c
+index 049bdd9..f763008 100644
+--- a/drivers/media/platform/vsp1/vsp1_rwpf.c
++++ b/drivers/media/platform/vsp1/vsp1_rwpf.c
+@@ -7,6 +7,7 @@
+ * Contact: Laurent Pinchart (laurent.pinchart@ideasonboard.com)
+ */
+
++//#define DEBUG
+ #include <media/v4l2-subdev.h>
+
+ #include "vsp1.h"
+diff --git a/drivers/media/platform/vsp1/vsp1_rwpf.h b/drivers/media/platform/vsp1/vsp1_rwpf.h
+index 58d882e..793f27d 100644
+--- a/drivers/media/platform/vsp1/vsp1_rwpf.h
++++ b/drivers/media/platform/vsp1/vsp1_rwpf.h
+@@ -28,6 +28,7 @@ struct vsp1_video;
+
+ struct vsp1_rwpf_memory {
+ dma_addr_t addr[3];
++ dma_addr_t alpha;
+ };
+
+ struct vsp1_rwpf {
+@@ -71,6 +72,11 @@ struct vsp1_rwpf {
+
+ int write_back;
+ dma_addr_t buf_addr[3];
++ unsigned int alpha_pitch;
++ unsigned int ckey;
++ unsigned int ckey_set0;
++ unsigned int ckey_set1;
++ unsigned int blend;
+ };
+
+ static inline struct vsp1_rwpf *to_rwpf(struct v4l2_subdev *subdev)
+diff --git a/drivers/media/platform/vsp1/vsp1_wpf.c b/drivers/media/platform/vsp1/vsp1_wpf.c
+index 75f9636..c6edeb4 100644
+--- a/drivers/media/platform/vsp1/vsp1_wpf.c
++++ b/drivers/media/platform/vsp1/vsp1_wpf.c
+@@ -7,6 +7,7 @@
+ * Contact: Laurent Pinchart (laurent.pinchart@ideasonboard.com)
+ */
+
++//#define DEBUG
+ #include <linux/device.h>
+
+ #include <media/v4l2-subdev.h>
+@@ -245,6 +246,9 @@ static void wpf_configure_stream(struct vsp1_entity *entity,
+ u32 outfmt = 0;
+ u32 srcrpf = 0;
+
++ dev_dbg(vsp1->dev, "wpf#%d: outfmt=%x (csc=%d)\n",
++ wpf->entity.index, outfmt, !!(outfmt & VI6_WPF_OUTFMT_CSC));
++
+ if (pipe->vmute_flag)
+ return;
+
+diff --git a/include/media/vsp1.h b/include/media/vsp1.h
+index 08d02de..bc14dd3 100644
+--- a/include/media/vsp1.h
++++ b/include/media/vsp1.h
+@@ -63,6 +63,11 @@ struct vsp1_du_atomic_config {
+ u32 pixelformat;
+ unsigned int pitch;
+ dma_addr_t mem[3];
++ dma_addr_t alpha_mem;
++ unsigned int alpha_pitch;
++ unsigned int ckey;
++ unsigned int ckey_set0;
++ unsigned int ckey_set1;
+ struct v4l2_rect src;
+ struct v4l2_rect dst;
+ unsigned int alpha;
+@@ -71,6 +76,7 @@ struct vsp1_du_atomic_config {
+ u32 colorkey_alpha;
+ bool colorkey_en;
+ bool interlaced;
++ unsigned int blend;
+ };
+
+ /**
+--
+2.7.4
+
diff --git a/bsp/meta-rcar/meta-rcar-gen3-adas/recipes-kernel/linux/linux-renesas/0357-gpu-drm-rcar-du-rcar_du_vsp-Check-if-gem-buffer-has-.patch b/bsp/meta-rcar/meta-rcar-gen3-adas/recipes-kernel/linux/linux-renesas/0357-gpu-drm-rcar-du-rcar_du_vsp-Check-if-gem-buffer-has-.patch
new file mode 100644
index 00000000..2c7ae508
--- /dev/null
+++ b/bsp/meta-rcar/meta-rcar-gen3-adas/recipes-kernel/linux/linux-renesas/0357-gpu-drm-rcar-du-rcar_du_vsp-Check-if-gem-buffer-has-.patch
@@ -0,0 +1,29 @@
+From 1bf8035838734ebf1745805ae874feb491eedafa Mon Sep 17 00:00:00 2001
+From: Valentine Barshak <valentine.barshak@cogentembedded.com>
+Date: Thu, 27 Jun 2019 02:55:59 +0300
+Subject: [PATCH 177/211] gpu: drm: rcar-du: rcar_du_vsp: Check if gem buffer
+ has a physical address
+
+Do not copy the sg in case gem buffer does have a physical address.
+
+Signed-off-by: Valentine Barshak <valentine.barshak@cogentembedded.com>
+---
+ drivers/gpu/drm/rcar-du/rcar_du_vsp.c | 2 +-
+ 1 file changed, 1 insertion(+), 1 deletion(-)
+
+diff --git a/drivers/gpu/drm/rcar-du/rcar_du_vsp.c b/drivers/gpu/drm/rcar-du/rcar_du_vsp.c
+index 2b076cf..a904132 100644
+--- a/drivers/gpu/drm/rcar-du/rcar_du_vsp.c
++++ b/drivers/gpu/drm/rcar-du/rcar_du_vsp.c
+@@ -277,7 +277,7 @@ static int rcar_du_vsp_plane_prepare_fb(struct drm_plane *plane,
+ drm_fb_cma_get_gem_obj(state->fb, i);
+ struct sg_table *sgt = &rstate->sg_tables[i];
+
+- if (gem->sgt) {
++ if (gem->sgt && !gem->paddr) {
+ struct scatterlist *src;
+ struct scatterlist *dst;
+
+--
+2.7.4
+
diff --git a/bsp/meta-rcar/meta-rcar-gen3-adas/recipes-kernel/linux/linux-renesas/0358-media-platform-vsp1-Add-cropping-handling-to-VSP-alp.patch b/bsp/meta-rcar/meta-rcar-gen3-adas/recipes-kernel/linux/linux-renesas/0358-media-platform-vsp1-Add-cropping-handling-to-VSP-alp.patch
new file mode 100644
index 00000000..9abaf2e3
--- /dev/null
+++ b/bsp/meta-rcar/meta-rcar-gen3-adas/recipes-kernel/linux/linux-renesas/0358-media-platform-vsp1-Add-cropping-handling-to-VSP-alp.patch
@@ -0,0 +1,56 @@
+From a96e381a1bef24b109331d55da60b9a207784815 Mon Sep 17 00:00:00 2001
+From: Valentine Barshak <valentine.barshak@cogentembedded.com>
+Date: Tue, 13 Nov 2018 18:17:42 +0300
+Subject: [PATCH 178/211] media: platform: vsp1: Add cropping handling to VSP
+ alpha-planes
+
+This is based on the original "Add cropping handling to VSP alpha-planes"
+patch by Konstantin Kozhevnikov <Konstantin.Kozhevnikov@cogentembedded.com>.
+
+Signed-off-by: Valentine Barshak <valentine.barshak@cogentembedded.com>
+---
+ drivers/media/platform/vsp1/vsp1_dl.c | 3 ++-
+ drivers/media/platform/vsp1/vsp1_rpf.c | 10 +++++++---
+ 2 files changed, 9 insertions(+), 4 deletions(-)
+
+diff --git a/drivers/media/platform/vsp1/vsp1_dl.c b/drivers/media/platform/vsp1/vsp1_dl.c
+index f501307..13da682 100644
+--- a/drivers/media/platform/vsp1/vsp1_dl.c
++++ b/drivers/media/platform/vsp1/vsp1_dl.c
+@@ -440,7 +440,8 @@ void vsp1_dl_set_addr_auto_fld(struct vsp1_dl_body *dlb,
+ dlb->src_dst_addr[v_bot_index].addr = v_bot_addr;
+
+ /* ...set alpha-plane address as needed */
+- dlb->src_dst_addr[alpha_index].addr = rpf->mem.alpha;
++ dlb->src_dst_addr[alpha_index].addr = rpf->mem.alpha +
++ crop->top * width + crop->left;
+ }
+
+ static struct vsp1_dl_list *vsp1_dl_list_alloc(struct vsp1_dl_manager *dlm)
+diff --git a/drivers/media/platform/vsp1/vsp1_rpf.c b/drivers/media/platform/vsp1/vsp1_rpf.c
+index 9875b0b..724655b 100644
+--- a/drivers/media/platform/vsp1/vsp1_rpf.c
++++ b/drivers/media/platform/vsp1/vsp1_rpf.c
+@@ -118,12 +118,16 @@ static void rpf_configure_stream(struct vsp1_entity *entity,
+
+ // ...setup alpha-plane as required
+ if (rpf->mem.alpha) {
+- vsp1_rpf_write(rpf, dlb, VI6_RPF_SRCM_ADDR_AI, rpf->mem.alpha);
++ struct v4l2_rect *crop = vsp1_rwpf_get_crop(rpf, rpf->entity.config);
++
++ vsp1_rpf_write(rpf, dlb, VI6_RPF_SRCM_ADDR_AI,
++ rpf->mem.alpha + crop->top * rpf->alpha_pitch + crop->left);
+ vsp1_rpf_write(rpf, dlb, VI6_RPF_ALPH_SEL, VI6_RPF_ALPH_SEL_ASEL_8B_PLANE);
+ vsp1_rpf_write(rpf, dlb, VI6_RPF_SRCM_ASTRIDE, rpf->alpha_pitch);
+ dev_dbg(entity->vsp1->dev,
+- "rpf#%d: setup alpha-plane: buffer=%pad, stride=%u\n",
+- rpf->entity.index, &rpf->mem.alpha, rpf->alpha_pitch);
++ "rpf#%d: setup alpha-plane: buffer=%pad, crop=%d,%d, stride=%u\n",
++ rpf->entity.index, &rpf->mem.alpha, crop->left, crop->top,
++ rpf->alpha_pitch);
+ goto out;
+ }
+
+--
+2.7.4
+
diff --git a/bsp/meta-rcar/meta-rcar-gen3-adas/recipes-kernel/linux/linux-renesas/0359-media-platform-rcar_imr-Clean-up-to-avoid-compiler-w.patch b/bsp/meta-rcar/meta-rcar-gen3-adas/recipes-kernel/linux/linux-renesas/0359-media-platform-rcar_imr-Clean-up-to-avoid-compiler-w.patch
new file mode 100644
index 00000000..0d245924
--- /dev/null
+++ b/bsp/meta-rcar/meta-rcar-gen3-adas/recipes-kernel/linux/linux-renesas/0359-media-platform-rcar_imr-Clean-up-to-avoid-compiler-w.patch
@@ -0,0 +1,106 @@
+From cf65e562f773b04eb2cc07540bf0d5b3b6797790 Mon Sep 17 00:00:00 2001
+From: Valentine Barshak <valentine.barshak@cogentembedded.com>
+Date: Tue, 13 Nov 2018 23:55:41 +0300
+Subject: [PATCH 179/211] media: platform: rcar_imr: Clean up to avoid compiler
+ warnings
+
+This is a slight driver clean-up that helps to avoid compiler warnings.
+
+Signed-off-by: Valentine Barshak <valentine.barshak@cogentembedded.com>
+---
+ drivers/media/platform/rcar_imr.c | 19 +++++++++++--------
+ 1 file changed, 11 insertions(+), 8 deletions(-)
+
+diff --git a/drivers/media/platform/rcar_imr.c b/drivers/media/platform/rcar_imr.c
+index 8864b0b..cdd847c 100644
+--- a/drivers/media/platform/rcar_imr.c
++++ b/drivers/media/platform/rcar_imr.c
+@@ -454,7 +454,7 @@ static int imr_queue_setup(struct vb2_queue *vq,
+
+ static int imr_buf_prepare(struct vb2_buffer *vb)
+ {
+- struct imr_ctx *ctx = vb2_get_drv_priv(vb->vb2_queue);
++ /* struct imr_ctx *ctx = vb2_get_drv_priv(vb->vb2_queue); */
+
+ /* ...unclear yet if we want to prepare a buffer somehow (cache invalidation? - tbd) */
+ return 0;
+@@ -945,8 +945,8 @@ static inline void imr_dl_program_setup(struct imr_ctx *ctx, struct imr_cfg *cfg
+ static int imr_ioctl_map(struct imr_ctx *ctx, struct imr_map_desc *desc)
+ {
+ struct imr_device *imr = ctx->imr;
+- struct imr_mesh *mesh;
+- int vbo_num;
++ struct imr_mesh *mesh = NULL;
++ int vbo_num = 0;
+ struct imr_cfg *cfg;
+ void *buf, *map;
+ u32 type;
+@@ -1122,11 +1122,9 @@ static int imr_ioctl_map_raw(struct imr_ctx *ctx, struct imr_map_desc *desc)
+ {
+ struct imr_device *imr = ctx->imr;
+ u32 type = desc->type;
+- u32 length = desc->size;
+ struct imr_cfg *cfg;
+ void *dl_vaddr;
+ u32 dl_size;
+- u32 dl_start_offset;
+ dma_addr_t dl_dma_addr;
+
+ /* ...check RSE */
+@@ -1157,6 +1155,7 @@ static int imr_ioctl_map_raw(struct imr_ctx *ctx, struct imr_map_desc *desc)
+
+ /* ...get pointer to the new display list */
+ dl_vaddr = cfg->dl_vaddr;
++ dl_dma_addr = cfg->dl_dma_addr;
+
+ /* ...prepare main DL-program */
+ imr_dl_program_setup(ctx, cfg, type, dl_vaddr, (u32)(uintptr_t)desc->data);
+@@ -1169,7 +1168,7 @@ static int imr_ioctl_map_raw(struct imr_ctx *ctx, struct imr_map_desc *desc)
+ cfg->id, (u32)dl_dma_addr, dl_size, 0);
+
+ if (debug >= 4)
+- print_hex_dump_bytes("DL-", DUMP_PREFIX_OFFSET, dl_vaddr + dl_start_offset, dl_size - dl_start_offset);
++ print_hex_dump_bytes("DL-", DUMP_PREFIX_OFFSET, dl_vaddr, dl_size);
+
+ /* ...success */
+ return 0;
+@@ -1679,6 +1678,7 @@ static const struct v4l2_file_operations imr_fops = {
+ ******************************************************************************/
+
+ /* ...job cleanup function */
++#if 0
+ static void imr_cleanup(struct imr_ctx *ctx)
+ {
+ struct imr_device *imr = ctx->imr;
+@@ -1697,6 +1697,7 @@ static void imr_cleanup(struct imr_ctx *ctx)
+ /* ...release lock before we mark current job as finished */
+ spin_unlock_irqrestore(&imr->lock, flags);
+ }
++#endif
+
+ /* ...job execution function */
+ static void imr_device_run(void *priv)
+@@ -1918,8 +1919,9 @@ static int imr_probe(struct platform_device *pdev)
+ struct resource *res;
+ struct device_node *np = pdev->dev.of_node;
+ int ret;
+- phandle *prop;
++ const phandle *prop;
+ struct device_node *node;
++ struct device *adev;
+
+ imr = devm_kzalloc(&pdev->dev, sizeof(*imr), GFP_KERNEL);
+ if (!imr)
+@@ -1986,7 +1988,8 @@ static int imr_probe(struct platform_device *pdev)
+ }
+ }
+
+- struct device *adev = device_create(imr_alloc_class, imr->dev, MKDEV(0, 0), NULL, "%s_alloc", dev_name(&pdev->dev));
++ adev = device_create(imr_alloc_class, imr->dev, MKDEV(0, 0), NULL,
++ "%s_alloc", dev_name(&pdev->dev));
+ if (IS_ERR(adev)) {
+ v4l2_err(&imr->v4l2_dev, "Failed to create alloc-device\n");
+ ret = PTR_ERR(adev);
+--
+2.7.4
+
diff --git a/bsp/meta-rcar/meta-rcar-gen3-adas/recipes-kernel/linux/linux-renesas/0360-arm64-dts-renesas-r8a77970-and-r8a77980-Add-CPU-oper.patch b/bsp/meta-rcar/meta-rcar-gen3-adas/recipes-kernel/linux/linux-renesas/0360-arm64-dts-renesas-r8a77970-and-r8a77980-Add-CPU-oper.patch
new file mode 100644
index 00000000..40b222e8
--- /dev/null
+++ b/bsp/meta-rcar/meta-rcar-gen3-adas/recipes-kernel/linux/linux-renesas/0360-arm64-dts-renesas-r8a77970-and-r8a77980-Add-CPU-oper.patch
@@ -0,0 +1,206 @@
+From e8eee5077c2068cc04972378abcf836d08d7831d Mon Sep 17 00:00:00 2001
+From: Andrey Dolnikov <andrey.dolnikov@cogentembedded.com>
+Date: Tue, 13 Nov 2018 19:11:14 +0300
+Subject: [PATCH 180/211] arm64: dts: renesas: r8a77970 and r8a77980: Add CPU
+ operation points.
+
+This adds CPU operation points and enables cpufreq driver
+for the V3M/V3H SoCs. This is based on the original patch
+by Andrey Dolnikov <andrey.dolnikov@cogentembedded.com>.
+Slight modifications have been done to the Z2 CPG quirk
+definitions.
+
+Signed-off-by: Valentine Barshak <valentine.barshak@cogentembedded.com>
+---
+ arch/arm64/boot/dts/renesas/r8a77970.dtsi | 13 +++++++++++++
+ arch/arm64/boot/dts/renesas/r8a77980.dtsi | 15 +++++++++++++++
+ drivers/clk/renesas/r8a77970-cpg-mssr.c | 1 +
+ drivers/clk/renesas/r8a77980-cpg-mssr.c | 1 +
+ drivers/clk/renesas/rcar-gen3-cpg.c | 27 +++++++++++++++++++++++++--
+ drivers/cpufreq/cpufreq-dt-platdev.c | 2 ++
+ 6 files changed, 57 insertions(+), 2 deletions(-)
+
+diff --git a/arch/arm64/boot/dts/renesas/r8a77970.dtsi b/arch/arm64/boot/dts/renesas/r8a77970.dtsi
+index 35000a7..090122c 100644
+--- a/arch/arm64/boot/dts/renesas/r8a77970.dtsi
++++ b/arch/arm64/boot/dts/renesas/r8a77970.dtsi
+@@ -44,6 +44,7 @@
+ power-domains = <&sysc R8A77970_PD_CA53_CPU0>;
+ next-level-cache = <&L2_CA53>;
+ enable-method = "psci";
++ operating-points-v2 = <&cluster0_opp_tb0>;
+ };
+
+ a53_1: cpu@1 {
+@@ -54,6 +55,7 @@
+ power-domains = <&sysc R8A77970_PD_CA53_CPU1>;
+ next-level-cache = <&L2_CA53>;
+ enable-method = "psci";
++ operating-points-v2 = <&cluster0_opp_tb0>;
+ };
+
+ L2_CA53: cache-controller {
+@@ -64,6 +66,17 @@
+ };
+ };
+
++ cluster0_opp_tb0: opp_table0 {
++ compatible = "operating-points-v2";
++ opp-shared;
++
++ opp@800000000 {
++ opp-hz = /bits/ 64 <800000000>;
++ opp-microvolt = <850000>;
++ clock-latency-ns = <300000>;
++ };
++ };
++
+ extal_clk: extal {
+ compatible = "fixed-clock";
+ #clock-cells = <0>;
+diff --git a/arch/arm64/boot/dts/renesas/r8a77980.dtsi b/arch/arm64/boot/dts/renesas/r8a77980.dtsi
+index e0d2213..24edddb 100644
+--- a/arch/arm64/boot/dts/renesas/r8a77980.dtsi
++++ b/arch/arm64/boot/dts/renesas/r8a77980.dtsi
+@@ -46,6 +46,7 @@
+ power-domains = <&sysc R8A77980_PD_CA53_CPU0>;
+ next-level-cache = <&L2_CA53>;
+ enable-method = "psci";
++ operating-points-v2 = <&cluster0_opp_tb0>;
+ };
+
+ a53_1: cpu@1 {
+@@ -56,6 +57,7 @@
+ power-domains = <&sysc R8A77980_PD_CA53_CPU1>;
+ next-level-cache = <&L2_CA53>;
+ enable-method = "psci";
++ operating-points-v2 = <&cluster0_opp_tb0>;
+ };
+
+ a53_2: cpu@2 {
+@@ -66,6 +68,7 @@
+ power-domains = <&sysc R8A77980_PD_CA53_CPU2>;
+ next-level-cache = <&L2_CA53>;
+ enable-method = "psci";
++ operating-points-v2 = <&cluster0_opp_tb0>;
+ };
+
+ a53_3: cpu@3 {
+@@ -76,6 +79,7 @@
+ power-domains = <&sysc R8A77980_PD_CA53_CPU3>;
+ next-level-cache = <&L2_CA53>;
+ enable-method = "psci";
++ operating-points-v2 = <&cluster0_opp_tb0>;
+ };
+
+ L2_CA53: cache-controller {
+@@ -86,6 +90,17 @@
+ };
+ };
+
++ cluster0_opp_tb0: opp_table0 {
++ compatible = "operating-points-v2";
++ opp-shared;
++
++ opp@1000000000 {
++ opp-hz = /bits/ 64 <1000000000>;
++ opp-microvolt = <850000>; /* TBD; section 87.2 */
++ clock-latency-ns = <300000>;
++ };
++ };
++
+ extal_clk: extal {
+ compatible = "fixed-clock";
+ #clock-cells = <0>;
+diff --git a/drivers/clk/renesas/r8a77970-cpg-mssr.c b/drivers/clk/renesas/r8a77970-cpg-mssr.c
+index 29833b6..1e3f6f8 100644
+--- a/drivers/clk/renesas/r8a77970-cpg-mssr.c
++++ b/drivers/clk/renesas/r8a77970-cpg-mssr.c
+@@ -79,6 +79,7 @@ static const struct cpg_core_clk r8a77970_core_clks[] __initconst = {
+ DEF_FIXED(".pll1_div4", CLK_PLL1_DIV4, CLK_PLL1_DIV2, 2, 1),
+
+ /* Core Clock Outputs */
++ DEF_GEN3_Z("z2", R8A77970_CLK_Z2, CLK_TYPE_GEN3_Z2, CLK_PLL1_DIV4, 1),
+ DEF_FIXED("ztr", R8A77970_CLK_ZTR, CLK_PLL1_DIV2, 6, 1),
+ DEF_FIXED("ztrd2", R8A77970_CLK_ZTRD2, CLK_PLL1_DIV2, 12, 1),
+ DEF_FIXED("zt", R8A77970_CLK_ZT, CLK_PLL1_DIV2, 4, 1),
+diff --git a/drivers/clk/renesas/r8a77980-cpg-mssr.c b/drivers/clk/renesas/r8a77980-cpg-mssr.c
+index 5371c27..4a61b585 100644
+--- a/drivers/clk/renesas/r8a77980-cpg-mssr.c
++++ b/drivers/clk/renesas/r8a77980-cpg-mssr.c
+@@ -75,6 +75,7 @@ static const struct cpg_core_clk r8a77980_core_clks[] __initconst = {
+ R8A77980_CLK_RPC),
+
+ /* Core Clock Outputs */
++ DEF_GEN3_Z("z2", R8A77980_CLK_Z2, CLK_TYPE_GEN3_Z2, CLK_PLL2, 2),
+ DEF_FIXED("ztr", R8A77980_CLK_ZTR, CLK_PLL1_DIV2, 6, 1),
+ DEF_FIXED("ztrd2", R8A77980_CLK_ZTRD2, CLK_PLL1_DIV2, 12, 1),
+ DEF_FIXED("zt", R8A77980_CLK_ZT, CLK_PLL1_DIV2, 4, 1),
+diff --git a/drivers/clk/renesas/rcar-gen3-cpg.c b/drivers/clk/renesas/rcar-gen3-cpg.c
+index c73b269..5993dbd 100644
+--- a/drivers/clk/renesas/rcar-gen3-cpg.c
++++ b/drivers/clk/renesas/rcar-gen3-cpg.c
+@@ -45,6 +45,13 @@ static u32 cpg_quirks;
+ #define RCKCR_CKSEL BIT(1) /* Resverd RCLK clock soruce select */
+ #define Z2FC_BIT_MASK_SFT_8 BIT(2) /* Use Z2FC bit mask range to [12:8] */
+ #define ZG_PARENT_PLL0 BIT(3) /* Use PLL0 as ZG clock parent */
++/*
++ * Z2: SYS-CPU divider 2 on V3H seems to be fixed to 1/2 and 1 on V3M.
++ * It is not 100% clear from the User's Manual but at least
++ * FRQCRC register is missed on V3x.
++ */
++#define Z2_SYSCPU_1 BIT(4) /* Z2 is fixed with SYS-CPU divider 2 set to 1 - V3M */
++#define Z2_SYSCPU_2 BIT(5) /* Z2 is fixed with SYS-CPU divider 2 set to 1/2 - V3H */
+
+ static spinlock_t cpg_lock;
+
+@@ -247,8 +254,16 @@ static unsigned long cpg_z_clk_recalc_rate(struct clk_hw *hw,
+ unsigned int mult;
+ u32 val;
+
+- val = readl(zclk->reg) & zclk->mask;
+- mult = 32 - (val >> __ffs(zclk->mask));
++ if (cpg_quirks & Z2_SYSCPU_1) {
++ /* SYS-CPU divider 2 is 1 == 32/32) */
++ mult = 32;
++ } else if (cpg_quirks & Z2_SYSCPU_2) {
++ /* SYS-CPU divider 2 is 1/2 == 16/32) */
++ mult = 16;
++ } else {
++ val = readl(zclk->reg) & zclk->mask;
++ mult = 32 - (val >> __ffs(zclk->mask));
++ }
+
+ return Z_CLK_ROUND(prate * mult / 32);
+ }
+@@ -827,6 +842,14 @@ static const struct soc_device_attribute cpg_quirks_match[] __initconst = {
+ .soc_id = "r8a77990",
+ .data = (void *)(Z2FC_BIT_MASK_SFT_8 | ZG_PARENT_PLL0),
+ },
++ {
++ .soc_id = "r8a77970",
++ .data = (void *)(Z2_SYSCPU_1),
++ },
++ {
++ .soc_id = "r8a77980",
++ .data = (void *)(Z2_SYSCPU_2),
++ },
+ { /* sentinel */ }
+ };
+
+diff --git a/drivers/cpufreq/cpufreq-dt-platdev.c b/drivers/cpufreq/cpufreq-dt-platdev.c
+index 9e0aa76..6adb4a1 100644
+--- a/drivers/cpufreq/cpufreq-dt-platdev.c
++++ b/drivers/cpufreq/cpufreq-dt-platdev.c
+@@ -69,6 +69,8 @@ static const struct of_device_id whitelist[] __initconst = {
+ { .compatible = "renesas,r8a7794", },
+ { .compatible = "renesas,r8a7795", },
+ { .compatible = "renesas,r8a7796", },
++ { .compatible = "renesas,r8a77970", },
++ { .compatible = "renesas,r8a77980", },
+ { .compatible = "renesas,sh73a0", },
+
+ { .compatible = "rockchip,rk2928", },
+--
+2.7.4
+
diff --git a/bsp/meta-rcar/meta-rcar-gen3-adas/recipes-kernel/linux/linux-renesas/0361-V3H-DTS-Add-FCPR-devices.patch b/bsp/meta-rcar/meta-rcar-gen3-adas/recipes-kernel/linux/linux-renesas/0361-V3H-DTS-Add-FCPR-devices.patch
new file mode 100644
index 00000000..91c32840
--- /dev/null
+++ b/bsp/meta-rcar/meta-rcar-gen3-adas/recipes-kernel/linux/linux-renesas/0361-V3H-DTS-Add-FCPR-devices.patch
@@ -0,0 +1,70 @@
+From 3ba4e9c2cf6d744f6f15a7c2f7b71802f967e038 Mon Sep 17 00:00:00 2001
+From: Andrey Dolnikov <andrey.dolnikov@cogentembedded.com>
+Date: Fri, 26 Oct 2018 18:38:42 +0300
+Subject: [PATCH 181/211] V3H DTS: Add FCPR devices.
+
+---
+ arch/arm64/boot/dts/renesas/r8a77980.dtsi | 47 +++++++++++++++++++++++++++++++
+ 1 file changed, 47 insertions(+)
+
+diff --git a/arch/arm64/boot/dts/renesas/r8a77980.dtsi b/arch/arm64/boot/dts/renesas/r8a77980.dtsi
+index 24edddb..c599814 100644
+--- a/arch/arm64/boot/dts/renesas/r8a77980.dtsi
++++ b/arch/arm64/boot/dts/renesas/r8a77980.dtsi
+@@ -1460,6 +1460,53 @@
+ power-domains = <&sysc R8A77980_PD_A3VIP2>;
+ };
+
++ fcpr_vip {
++ compatible = "generic-uio";
++ reg = <0 0xe7aa0000 0 0x20000>;
++ };
++
++ fcpr_ir {
++ compatible = "generic-uio";
++ reg = <0 0xff8d8000 0 0x10000>;
++ };
++
++ fcpr_vio0 {
++ compatible = "generic-uio";
++ reg = <0 0xfe9c0000 0 0x10000>;
++ };
++
++ fcpr_vio1 {
++ compatible = "generic-uio";
++ reg = <0 0xfea90000 0 0x10000>;
++ };
++
++ fcpr_rt {
++ compatible = "generic-uio";
++ reg = <0 0xffc70000 0 0x10000>;
++ };
++
++ fcpr_peri {
++ compatible = "generic-uio";
++ reg = <0 0xe7320000 0 0x10000>;
++ };
++
++ fcpra_peri {
++ compatible = "generic-uio";
++ reg = <0 0xe7410000 0 0x10000>;
++ };
++
++
++ fcpr_c53 {
++ compatible = "generic-uio";
++ reg = <0 0xf12a0000 0 0x10000>;
++ };
++
++ fcpra_c53 {
++ compatible = "generic-uio";
++ reg = <0 0xf12f0000 0 0x10000>;
++ };
++
++
+ isp0: isp@fec00000 {
+ compatible = "renesas,isp-r8a77980";
+ reg = <0 0xfec00000 0 0x20000>,
+--
+2.7.4
+
diff --git a/bsp/meta-rcar/meta-rcar-gen3-adas/recipes-kernel/linux/linux-renesas/0362-arm64-dts-r8a77980-v3hsk-Enable-onboard-eMMC.patch b/bsp/meta-rcar/meta-rcar-gen3-adas/recipes-kernel/linux/linux-renesas/0362-arm64-dts-r8a77980-v3hsk-Enable-onboard-eMMC.patch
new file mode 100644
index 00000000..e74c3f3d
--- /dev/null
+++ b/bsp/meta-rcar/meta-rcar-gen3-adas/recipes-kernel/linux/linux-renesas/0362-arm64-dts-r8a77980-v3hsk-Enable-onboard-eMMC.patch
@@ -0,0 +1,69 @@
+From b1c0fc5cec81edb5be704011f9fd07c343e47286 Mon Sep 17 00:00:00 2001
+From: Andrey Dolnikov <andrey.dolnikov@cogentembedded.com>
+Date: Thu, 15 Nov 2018 23:18:48 +0300
+Subject: [PATCH 182/211] arm64: dts: r8a77980-v3hsk: Enable onboard eMMC.
+
+---
+ arch/arm64/boot/dts/renesas/r8a77980-v3hsk.dts | 35 ++++++++++++++++++++++++++
+ 1 file changed, 35 insertions(+)
+
+diff --git a/arch/arm64/boot/dts/renesas/r8a77980-v3hsk.dts b/arch/arm64/boot/dts/renesas/r8a77980-v3hsk.dts
+index cfd9c89..0e0aed7 100644
+--- a/arch/arm64/boot/dts/renesas/r8a77980-v3hsk.dts
++++ b/arch/arm64/boot/dts/renesas/r8a77980-v3hsk.dts
+@@ -118,6 +118,15 @@
+ regulator-boot-on;
+ regulator-always-on;
+ };
++
++ vddq_vin01: regulator-2 {
++ compatible = "regulator-fixed";
++ regulator-name = "VDDQ_VIN01";
++ regulator-min-microvolt = <1800000>;
++ regulator-max-microvolt = <1800000>;
++ regulator-boot-on;
++ regulator-always-on;
++ };
+ };
+
+ &du {
+@@ -230,6 +239,18 @@
+ groups = "scif_clk_b";
+ function = "scif_clk";
+ };
++
++ mmc_pins_uhs: mmc_uhs {
++ groups = "mmc_data8", "mmc_ctrl", "mmc_ds";
++ function = "mmc";
++ power-source = <1800>;
++ };
++
++ mmc_pins: mmc {
++ groups = "mmc_data8", "mmc_ctrl", "mmc_ds";
++ function = "mmc";
++ power-source = <3300>;
++ };
+ };
+
+ &rwdt {
+@@ -247,3 +268,17 @@
+ &scif_clk {
+ clock-frequency = <14745600>;
+ };
++
++&mmc0 {
++ /* used for on-board eMMC */
++ pinctrl-0 = <&mmc_pins>;
++ pinctrl-1 = <&mmc_pins_uhs>;
++ pinctrl-names = "default", "state_uhs";
++
++ vmmc-supply = <&vcc3v3_d5>;
++ vqmmc-supply = <&vddq_vin01>;
++ mmc-hs200-1_8v;
++ bus-width = <8>;
++ non-removable;
++ status = "okay";
++};
+--
+2.7.4
+
diff --git a/bsp/meta-rcar/meta-rcar-gen3-adas/recipes-kernel/linux/linux-renesas/0363-arm64-dts-renesas-r8a77980-v3hsk-vb-Xch-Fix-Ethernet.patch b/bsp/meta-rcar/meta-rcar-gen3-adas/recipes-kernel/linux/linux-renesas/0363-arm64-dts-renesas-r8a77980-v3hsk-vb-Xch-Fix-Ethernet.patch
new file mode 100644
index 00000000..fc05d622
--- /dev/null
+++ b/bsp/meta-rcar/meta-rcar-gen3-adas/recipes-kernel/linux/linux-renesas/0363-arm64-dts-renesas-r8a77980-v3hsk-vb-Xch-Fix-Ethernet.patch
@@ -0,0 +1,50 @@
+From 9b1ace6d26cd3234c87bd3f43ec0360485882f74 Mon Sep 17 00:00:00 2001
+From: Andrey Dolnikov <andrey.dolnikov@cogentembedded.com>
+Date: Fri, 16 Nov 2018 12:59:24 +0300
+Subject: [PATCH 183/211] arm64: dts: renesas: r8a77980-v3hsk-vb-Xch: Fix
+ Ethernet AVB pins.
+
+---
+ arch/arm64/boot/dts/renesas/r8a77980-v3hsk-vb-4ch.dts | 7 +------
+ arch/arm64/boot/dts/renesas/r8a77980-v3hsk-vb-8ch.dts | 7 +------
+ 2 files changed, 2 insertions(+), 12 deletions(-)
+
+diff --git a/arch/arm64/boot/dts/renesas/r8a77980-v3hsk-vb-4ch.dts b/arch/arm64/boot/dts/renesas/r8a77980-v3hsk-vb-4ch.dts
+index 7b35608..cb9cd54 100644
+--- a/arch/arm64/boot/dts/renesas/r8a77980-v3hsk-vb-4ch.dts
++++ b/arch/arm64/boot/dts/renesas/r8a77980-v3hsk-vb-4ch.dts
+@@ -485,12 +485,7 @@
+ };
+
+ avb_pins: avb {
+- groups = "avb_mdc", "avb_mdio",
+- "avb_rx_ctrl", "avb_rxc",
+- "avb_rd4",
+- "avb_tx_ctrl", "avb_txc",
+- "avb_txcrefclk",
+- "avb_td4";
++ groups = "avb_mdio", "avb_rgmii";
+ function = "avb";
+ };
+
+diff --git a/arch/arm64/boot/dts/renesas/r8a77980-v3hsk-vb-8ch.dts b/arch/arm64/boot/dts/renesas/r8a77980-v3hsk-vb-8ch.dts
+index 84d89d2..f23f2d0 100644
+--- a/arch/arm64/boot/dts/renesas/r8a77980-v3hsk-vb-8ch.dts
++++ b/arch/arm64/boot/dts/renesas/r8a77980-v3hsk-vb-8ch.dts
+@@ -634,12 +634,7 @@
+ };
+
+ avb_pins: avb {
+- groups = "avb_mdc", "avb_mdio",
+- "avb_rx_ctrl", "avb_rxc",
+- "avb_rd4",
+- "avb_tx_ctrl", "avb_txc",
+- "avb_txcrefclk",
+- "avb_td4";
++ groups = "avb_mdio", "avb_rgmii";
+ function = "avb";
+ };
+
+--
+2.7.4
+
diff --git a/bsp/meta-rcar/meta-rcar-gen3-adas/recipes-kernel/linux/linux-renesas/0364-clocksource-drivers-sh_cmt-Add-R-Car-gen3-support.patch b/bsp/meta-rcar/meta-rcar-gen3-adas/recipes-kernel/linux/linux-renesas/0364-clocksource-drivers-sh_cmt-Add-R-Car-gen3-support.patch
new file mode 100644
index 00000000..5281aa09
--- /dev/null
+++ b/bsp/meta-rcar/meta-rcar-gen3-adas/recipes-kernel/linux/linux-renesas/0364-clocksource-drivers-sh_cmt-Add-R-Car-gen3-support.patch
@@ -0,0 +1,37 @@
+From d6dae604dcb5ebf73e1b0adfdd7773fd9476c7c3 Mon Sep 17 00:00:00 2001
+From: Sergei Shtylyov <sergei.shtylyov@cogentembedded.com>
+Date: Wed, 12 Sep 2018 23:17:37 +0300
+Subject: [PATCH 184/211] clocksource/drivers/sh_cmt: Add R-Car gen3 support
+
+Add support for the R-Car gen3 CMT types 0/1 -- they seem to be the same
+CMT types 0/1 as in R-Car gen2 SoCs.
+
+Signed-off-by: Sergei Shtylyov <sergei.shtylyov@cogentembedded.com>
+Reviewed-by: Geert Uytterhoeven <geert+renesas@glider.be>
+Signed-off-by: Daniel Lezcano <daniel.lezcano@linaro.org>
+---
+ drivers/clocksource/sh_cmt.c | 8 ++++++++
+ 1 file changed, 8 insertions(+)
+
+diff --git a/drivers/clocksource/sh_cmt.c b/drivers/clocksource/sh_cmt.c
+index 70b3cf8..30f18ea 100644
+--- a/drivers/clocksource/sh_cmt.c
++++ b/drivers/clocksource/sh_cmt.c
+@@ -943,6 +943,14 @@ static const struct of_device_id sh_cmt_of_table[] __maybe_unused = {
+ },
+ { .compatible = "renesas,rcar-gen2-cmt0", .data = &sh_cmt_info[SH_CMT0_RCAR_GEN2] },
+ { .compatible = "renesas,rcar-gen2-cmt1", .data = &sh_cmt_info[SH_CMT1_RCAR_GEN2] },
++ {
++ .compatible = "renesas,rcar-gen3-cmt0",
++ .data = &sh_cmt_info[SH_CMT0_RCAR_GEN2]
++ },
++ {
++ .compatible = "renesas,rcar-gen3-cmt1",
++ .data = &sh_cmt_info[SH_CMT1_RCAR_GEN2]
++ },
+ { }
+ };
+ MODULE_DEVICE_TABLE(of, sh_cmt_of_table);
+--
+2.7.4
+
diff --git a/bsp/meta-rcar/meta-rcar-gen3-adas/recipes-kernel/linux/linux-renesas/0365-mtd-spi-nor-Add-R-Car-Gen3-RPC-QSPI-driver.patch b/bsp/meta-rcar/meta-rcar-gen3-adas/recipes-kernel/linux/linux-renesas/0365-mtd-spi-nor-Add-R-Car-Gen3-RPC-QSPI-driver.patch
new file mode 100644
index 00000000..b0149ee8
--- /dev/null
+++ b/bsp/meta-rcar/meta-rcar-gen3-adas/recipes-kernel/linux/linux-renesas/0365-mtd-spi-nor-Add-R-Car-Gen3-RPC-QSPI-driver.patch
@@ -0,0 +1,1334 @@
+From bb7780ccca449ad284a96789d38913d844e1f985 Mon Sep 17 00:00:00 2001
+From: Valentine Barshak <valentine.barshak@cogentembedded.com>
+Date: Thu, 15 Nov 2018 23:55:17 +0300
+Subject: [PATCH 185/211] mtd: spi-nor: Add R-Car Gen3 RPC QSPI driver
+
+This is preliminary Renesas R-Car Gen3 RPC QSPI flash driver.
+The driver should support single and dual mode. Dual mode means
+that there are two SPI-NOR flash chips connected.
+
+This is based on the original patch by patch by Dmitry Shifrin.
+The only change is dual mode support done before calling
+mtd_device_register() instead of implementing spi-nor array
+size support in the generic spi-nor layer.
+
+Signed-off-by: Dmitry Shifrin <dmitry.shifrin@cogentembedded.com>
+Signed-off-by: Valentine Barshak <valentine.barshak@cogentembedded.com>
+---
+ drivers/mtd/spi-nor/Kconfig | 8 +
+ drivers/mtd/spi-nor/Makefile | 1 +
+ drivers/mtd/spi-nor/renesas-rpc.c | 1271 +++++++++++++++++++++++++++++++++++++
+ 3 files changed, 1280 insertions(+)
+ create mode 100644 drivers/mtd/spi-nor/renesas-rpc.c
+
+diff --git a/drivers/mtd/spi-nor/Kconfig b/drivers/mtd/spi-nor/Kconfig
+index 69c638d..2c73adb 100644
+--- a/drivers/mtd/spi-nor/Kconfig
++++ b/drivers/mtd/spi-nor/Kconfig
+@@ -7,6 +7,14 @@ menuconfig MTD_SPI_NOR
+
+ if MTD_SPI_NOR
+
++
++config SPI_RENESAS_RPC
++ tristate "Renesas RPC controller"
++ depends on ARCH_R8A7795 || ARCH_R8A7796 || ARCH_R8A77970 || ARCH_R8A77980 || COMPILE_TEST
++ help
++ QSPI driver for Renesas SPI Multi I/O Bus controller. This controller
++ supports normal, dual and quad spi for one or two SPI NOR Flashes.
++
+ config MTD_MT81xx_NOR
+ tristate "Mediatek MT81xx SPI NOR flash controller"
+ depends on HAS_IOMEM
+diff --git a/drivers/mtd/spi-nor/Makefile b/drivers/mtd/spi-nor/Makefile
+index f4c61d2..0c46c9c 100644
+--- a/drivers/mtd/spi-nor/Makefile
++++ b/drivers/mtd/spi-nor/Makefile
+@@ -7,6 +7,7 @@ obj-$(CONFIG_SPI_FSL_QUADSPI) += fsl-quadspi.o
+ obj-$(CONFIG_SPI_HISI_SFC) += hisi-sfc.o
+ obj-$(CONFIG_MTD_MT81xx_NOR) += mtk-quadspi.o
+ obj-$(CONFIG_SPI_NXP_SPIFI) += nxp-spifi.o
++obj-$(CONFIG_SPI_RENESAS_RPC) += renesas-rpc.o
+ obj-$(CONFIG_SPI_INTEL_SPI) += intel-spi.o
+ obj-$(CONFIG_SPI_INTEL_SPI_PCI) += intel-spi-pci.o
+ obj-$(CONFIG_SPI_INTEL_SPI_PLATFORM) += intel-spi-platform.o
+diff --git a/drivers/mtd/spi-nor/renesas-rpc.c b/drivers/mtd/spi-nor/renesas-rpc.c
+new file mode 100644
+index 0000000..b619a7e
+--- /dev/null
++++ b/drivers/mtd/spi-nor/renesas-rpc.c
+@@ -0,0 +1,1271 @@
++/*
++ * Renesas RPC driver
++ *
++ * Copyright (C) 2018, Cogent Embedded Inc.
++ *
++ * This program is free software; you can redistribute it and/or modify
++ * it under the terms of the GNU General Public License as published by
++ * the Free Software Foundation; version 2 of the License.
++ *
++ * This program is distributed in the hope that it will be useful,
++ * but WITHOUT ANY WARRANTY; without even the implied warranty of
++ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
++ * GNU General Public License for more details.
++ */
++
++#include <linux/clk.h>
++#include <linux/module.h>
++#include <linux/of.h>
++#include <linux/of_device.h>
++#include <linux/interrupt.h>
++#include <linux/platform_device.h>
++#include <linux/delay.h>
++#include <linux/mtd/spi-nor.h>
++
++/* regs offsets */
++#define CMNCR 0x0000
++#define SSLDR 0x0004
++#define DRCR 0x000C
++#define DRCMR 0x0010
++#define DREAR 0x0014
++#define DROPR 0x0018
++#define DRENR 0x001C
++#define SMCR 0x0020
++#define SMCMR 0x0024
++#define SMADR 0x0028
++#define SMOPR 0x002C
++#define SMENR 0x0030
++#define SMRDR0 0x0038
++#define SMRDR1 0x003C
++#define SMWDR0 0x0040
++#define SMWDR1 0x0044
++#define CMNSR 0x0048
++#define DRDMCR 0x0058
++#define DRDRENR 0x005C
++#define SMDMCR 0x0060
++#define SMDRENR 0x0064
++#define PHYCNT 0x007C
++#define PHYOFFSET1 0x0080
++#define PHYOFFSET2 0x0084
++#define PHYINT 0x0088
++#define DIV_REG 0x00A8
++
++/* CMNCR */
++#define CMNCR_BSZ_MASK (0x03)
++#define CMNCR_BSZ_4x1 (0x0)
++#define CMNCR_BSZ_8x1 (0x1)
++#define CMNCR_BSZ_4x2 (0x1)
++#define CMNCR_MD (0x1 << 31)
++#define CMNCR_MOIIO3_MASK (0x3 << 22)
++#define CMNCR_MOIIO3_HIZ (0x3 << 22)
++#define CMNCR_MOIIO2_MASK (0x3 << 20)
++#define CMNCR_MOIIO2_HIZ (0x3 << 20)
++#define CMNCR_MOIIO1_MASK (0x3 << 18)
++#define CMNCR_MOIIO1_HIZ (0x3 << 18)
++#define CMNCR_MOIIO0_MASK (0x3 << 16)
++#define CMNCR_MOIIO0_HIZ (0x3 << 16)
++#define CMNCR_IO0FV_MASK (0x3 << 8)
++#define CMNCR_IO0FV_HIZ (0x3 << 8)
++
++/* DRCR */
++#define DRCR_RBURST_MASK (0x1f << 16)
++#define DRCR_RBURST(v) (((v) & 0x1f) << 16)
++#define DRCR_SSLE (0x1)
++#define DRCR_RBE (0x1 << 8)
++#define DRCR_RCF (0x1 << 9)
++#define DRCR_RBURST_32 (0x1f << 16)
++
++/* SMENR */
++#define SMENR_CDB_MASK (0x03 << 30)
++#define SMENR_CDB(v) (((v) & 0x03) << 30)
++#define SMENR_CDB_1B (0)
++#define SMENR_CDB_2B (0x1 << 30)
++#define SMENR_CDB_4B (0x2 << 30)
++#define SMENR_OCDB_MASK (0x03 << 28)
++#define SMENR_OCDB_1B (0)
++#define SMENR_OCDB_2B (0x1 << 28)
++#define SMENR_OCDB_4B (0x2 << 28)
++#define SMENR_ADB_MASK (0x03 << 24)
++#define SMENR_ADB(v) (((v) & 0x03) << 24)
++#define SMENR_ADB_1B (0)
++#define SMENR_ADB_2B (0x1 << 24)
++#define SMENR_ADB_4B (0x2 << 24)
++#define SMENR_OPDB_MASK (0x03 << 20)
++#define SMENR_OPDB_1B (0)
++#define SMENR_OPDB_2B (0x1 << 20)
++#define SMENR_OPDB_4B (0x2 << 20)
++#define SMENR_SPIDB_MASK (0x03 << 16)
++#define SMENR_SPIDB(v) (((v) & 0x03) << 16)
++#define SMENR_SPIDB_1B (0)
++#define SMENR_SPIDB_2B (0x1 << 16)
++#define SMENR_SPIDB_4B (0x2 << 16)
++#define SMENR_OPDE_MASK (0xf << 4)
++#define SMENR_OPDE_DISABLE (0)
++#define SMENR_OPDE3 (0x8 << 4)
++#define SMENR_OPDE32 (0xC << 4)
++#define SMENR_OPDE321 (0xE << 4)
++#define SMENR_OPDE3210 (0xF << 4)
++#define SMENR_SPIDE_MASK (0x0F)
++#define SMENR_SPIDE_DISABLE (0)
++#define SMENR_SPIDE_8B (0x08)
++#define SMENR_SPIDE_16B (0x0C)
++#define SMENR_SPIDE_32B (0x0F)
++#define SMENR_DME (1<<15)
++#define SMENR_CDE (1<<14)
++#define SMENR_OCDE (1<<12)
++#define SMENR_ADE_MASK (0xf << 8)
++#define SMENR_ADE_DISABLE (0)
++#define SMENR_ADE_23_16 (0x4 << 8)
++#define SMENR_ADE_23_8 (0x6 << 8)
++#define SMENR_ADE_23_0 (0x7 << 8)
++#define SMENR_ADE_31_0 (0xf << 8)
++
++/* SMCMR */
++#define SMCMR_CMD(cmd) (((cmd) & 0xff) << 16)
++#define SMCMR_CMD_MASK (0xff << 16)
++#define SMCMR_OCMD(cmd) (((cmd) & 0xff))
++#define SMCMR_OCMD_MASK (0xff)
++
++/* SMDRENR */
++#define SMDRENR_HYPE_MASK (0x7 << 12)
++#define SMDRENR_HYPE_SPI_FLASH (0x0)
++#define SMDRENR_ADDRE (0x1 << 8)
++#define SMDRENR_OPDRE (0x1 << 4)
++#define SMDRENR_SPIDRE (0x1)
++
++/* PHYCNT */
++#define PHYCNT_CAL (0x1 << 31)
++#define PHYCNT_OCTA_MASK (0x3 << 22)
++#define PHYCNT_EXDS (0x1 << 21)
++#define PHYCNT_OCT (0x1 << 20)
++#define PHYCNT_DDRCAL (0x1 << 19)
++#define PHYCNT_HS (0x1 << 18)
++#define PHYCNT_STREAM_MASK (0x7 << 15)
++#define PHYCNT_STREAM(o) (((o) & 0x7) << 15)
++#define PHYCNT_WBUF2 (0x1 << 4)
++#define PHYCNT_WBUF (0x1 << 2)
++#define PHYCNT_PHYMEM_MASK (0x3)
++
++/* SMCR */
++#define SMCR_SSLKP (0x1 << 8)
++#define SMCR_SPIRE (0x1 << 2)
++#define SMCR_SPIWE (0x1 << 1)
++#define SMCR_SPIE (0x1)
++
++/* CMNSR */
++#define CMNSR_TEND (0x1 << 0)
++
++/* SSLDR */
++#define SSLDR_SPNDL(v) (((v) & 0x7) << 16)
++#define SSLDR_SLNDL(v) ((((v) | 0x4) & 0x7) << 8)
++#define SSLDR_SCKDL(v) ((v) & 0x7)
++
++/* DREAR */
++#define DREAR_EAV_MASK (0xff << 16)
++#define DREAR_EAV(v) (((v) & 0xff) << 16)
++#define DREAR_EAC_MASK (0x7)
++#define DREAR_24B (0)
++#define DREAR_25B (1)
++
++/* DRENR */
++#define DRENR_CDB_MASK (0x03 << 30)
++#define DRENR_CDB(v) (((v) & 0x3) << 30)
++#define DRENR_CDB_1B (0)
++#define DRENR_CDB_2B (0x1 << 30)
++#define DRENR_CDB_4B (0x2 << 30)
++#define DRENR_OCDB_MASK (0x03 << 28)
++#define DRENR_OCDB_1B (0)
++#define DRENR_OCDB_2B (0x1 << 28)
++#define DRENR_OCDB_4B (0x2 << 28)
++#define DRENR_ADB_MASK (0x03 << 24)
++#define DRENR_ADB(v) (((v) & 0x3) << 24)
++#define DRENR_ADB_1B (0)
++#define DRENR_ADB_2B (0x1 << 24)
++#define DRENR_ADB_4B (0x2 << 24)
++#define DRENR_OPDB_MASK (0x03 << 20)
++#define DRENR_OPDB_1B (0)
++#define DRENR_OPDB_2B (0x1 << 20)
++#define DRENR_OPDB_4B (0x2 << 20)
++#define DRENR_DRDB_MASK (0x03 << 16)
++#define DRENR_DRDB(v) (((v) & 0x3) << 16)
++#define DRENR_DRDB_1B (0)
++#define DRENR_DRDB_2B (0x1 << 16)
++#define DRENR_DRDB_4B (0x2 << 16)
++#define DRENR_OPDE_MASK (0xf << 4)
++#define DRENR_OPDE_DISABLE (0)
++#define DRENR_OPDE3 (0x8 << 4)
++#define DRENR_OPDE32 (0xC << 4)
++#define DRENR_OPDE321 (0xE << 4)
++#define DRENR_OPDE3210 (0xF << 4)
++#define DRENR_DME (1<<15)
++#define DRENR_CDE (1<<14)
++#define DRENR_OCDE (1<<12)
++#define DRENR_ADE_MASK (0xf << 8)
++#define DRENR_ADE_DISABLE (0)
++#define DRENR_ADE_23_0 (0x7 << 8)
++#define DRENR_ADE_31_0 (0xf << 8)
++
++/* DRCMR */
++#define DRCMR_CMD(cmd) (((cmd) & 0xff) << 16)
++#define DRCMR_CMD_MASK (0xff << 16)
++#define DRCMR_OCMD(cmd) (((cmd) & 0xff))
++#define DRCMR_OCMD_MASK (0xff)
++
++/* DRCMR */
++#define DRDMCR_DMCYC(v) ((v) & 0x1f)
++#define DRDMCR_DMCYC_MASK (0x1f)
++
++/* SMDMCR */
++#define SMDMCR_DMCYC(v) ((v) & 0x0f)
++#define SMDMCR_DMCYC_MASK (0x0f)
++
++/* PHYOFFSET1 */
++#define PHYOFFSET1_DDRTMG (1 << 28)
++
++/* DIVREG */
++#define DIVREG_RATIO_MASK (0x03)
++#define DIVREG_RATIO(v) ((v) & 0x03)
++#define DIVREG_RATIO_MAX (0x2)
++
++
++#define DEFAULT_TO (100)
++#define WRITE_BUF_SIZE (0x100)
++#define WRITE_BUF_ADR_MASK (0xff)
++
++#define REPEAT_MAX (20)
++#define REPEAT_TIME (10)
++
++struct rpc_spi {
++ struct platform_device *pdev;
++ void __iomem *base;
++ void __iomem *read_area;
++ void __iomem *write_area;
++ struct clk *clk;
++ unsigned int irq;
++ struct spi_nor spi_nor;
++
++#define MTD_QSPI_1x 0
++#define MTD_QSPI_2x 1
++
++ u32 mtdtype;
++};
++
++/* IP block use it's own clock divigion register */
++#define OWN_CLOCK_DIVIDER BIT(0)
++
++/* debug */
++static void __maybe_unused regs_dump(struct rpc_spi *rpc)
++{
++ static u32 regs[] = {
++ CMNCR, SSLDR, DRCR, DRCMR, DREAR,
++ DROPR, DRENR, SMCR, SMCMR, SMADR,
++ SMOPR, SMENR, SMRDR0, SMRDR1, SMWDR0,
++ SMWDR1, CMNSR, DRDMCR, DRDRENR, SMDMCR,
++ SMDRENR, PHYCNT, PHYOFFSET1, PHYOFFSET2,
++ PHYINT
++ };
++
++ static const char *const names[] = {
++ "CMNCR", "SSLDR", "DRCR", "DRCMR", "DREAR",
++ "DROPR", "DRENR", "SMCR", "SMCMR", "SMADR",
++ "SMOPR", "SMENR", "SMRDR0", "SMRDR1", "SMWDR0",
++ "SMWDR1", "CMNSR", "DRDMCR", "DRDRENR", "SMDMCR",
++ "SMDRENR", "PHYCNT", "PHYOFFSET1", "PHYOFFSET2",
++ "PHYINT"
++ };
++
++ int i;
++
++ dev_dbg(&rpc->pdev->dev, "RPC regs dump:\n");
++ for (i = 0; i < ARRAY_SIZE(regs); i++)
++ dev_dbg(&rpc->pdev->dev, "%s = 0x%08x\n", names[i],
++ readl(rpc->base + regs[i]));
++}
++
++/* register acces */
++static u32 rpc_read(struct rpc_spi *rpc, unsigned int reg)
++{
++ u32 val;
++
++ val = readl(rpc->base + reg);
++ return val;
++}
++
++static void rpc_write(struct rpc_spi *rpc, unsigned int reg, u32 val)
++{
++ writel(val, rpc->base + reg);
++}
++
++static int rpc_wait(struct rpc_spi *rpc, u32 to)
++{
++ u32 val;
++ int i;
++
++ for (i = 0; i < to; i++) {
++ val = rpc_read(rpc, CMNSR);
++ val &= CMNSR_TEND;
++ if (val)
++ break;
++
++ udelay(100);
++ }
++
++ if (i == to) {
++ dev_err(&rpc->pdev->dev, "timeout waiting for operation end %d\n",
++ rpc_read(rpc, CMNSR));
++ return -ETIMEDOUT;
++ }
++
++ return 0;
++}
++
++static int rpc_setup_clk_ratio(struct rpc_spi *rpc, u32 max_clk_rate)
++{
++ unsigned long rate = clk_get_rate(rpc->clk);
++ u32 ratio;
++ u32 val;
++
++ ratio = DIV_ROUND_UP(rate, max_clk_rate * 2) >> 1;
++ if (ratio > DIVREG_RATIO_MAX)
++ ratio = DIVREG_RATIO_MAX;
++
++ val = rpc_read(rpc, DIV_REG);
++ val &= DIVREG_RATIO_MASK;
++ val |= DIVREG_RATIO(ratio);
++ rpc_write(rpc, DIV_REG, val);
++
++ return 0;
++}
++
++static int rpc_endisable_write_buf(struct rpc_spi *rpc, bool en)
++{
++ u32 val;
++
++ val = rpc_read(rpc, PHYCNT);
++
++ if (en)
++ val |= PHYCNT_WBUF | PHYCNT_WBUF2;
++ else
++ val &= ~(PHYCNT_WBUF | PHYCNT_WBUF2);
++
++ rpc_write(rpc, PHYCNT, val);
++
++ return 0;
++}
++
++static int rpc_begin(struct rpc_spi *rpc,
++ bool rx, bool tx, bool last)
++{
++ u32 val = SMCR_SPIE;
++
++ if (rx)
++ val |= SMCR_SPIRE;
++
++ if (tx)
++ val |= SMCR_SPIWE;
++
++ if (!last)
++ val |= SMCR_SSLKP;
++
++ rpc_write(rpc, SMCR, val);
++
++ return 0;
++}
++
++static int rpc_setup_reg_mode(struct rpc_spi *rpc)
++{
++ u32 val;
++
++ rpc_wait(rpc, DEFAULT_TO);
++
++ rpc_endisable_write_buf(rpc, false);
++
++ /* ...setup manual mode */
++ val = rpc_read(rpc, CMNCR);
++ val |= CMNCR_MD;
++ rpc_write(rpc, CMNCR, val);
++
++ /* disable ddr */
++ val = rpc_read(rpc, SMDRENR);
++ val &= ~(SMDRENR_ADDRE | SMDRENR_OPDRE | SMDRENR_SPIDRE);
++ rpc_write(rpc, SMDRENR, val);
++
++ /* enable 1bit command */
++ val = rpc_read(rpc, SMENR);
++ val &= ~(SMENR_CDB_MASK | SMENR_OCDB_MASK | SMENR_DME
++ | SMENR_OCDE | SMENR_SPIDB_MASK
++ | SMENR_ADE_MASK | SMENR_ADB_MASK
++ | SMENR_OPDE_MASK | SMENR_SPIDE_MASK);
++ val |= SMENR_CDB_1B | SMENR_CDE | SMENR_SPIDE_32B;
++ rpc_write(rpc, SMENR, val);
++
++
++ return 0;
++}
++
++static void rpc_flush_cache(struct rpc_spi *rpc)
++{
++ u32 val;
++
++ val = rpc_read(rpc, DRCR);
++ val |= DRCR_RCF;
++ rpc_write(rpc, DRCR, val);
++}
++
++static int rpc_setup_ext_mode(struct rpc_spi *rpc)
++{
++ u32 val;
++ u32 cmncr;
++
++ rpc_wait(rpc, DEFAULT_TO);
++
++ rpc_endisable_write_buf(rpc, false);
++
++ /* ...setup ext mode */
++ val = rpc_read(rpc, CMNCR);
++ cmncr = val;
++ val &= ~(CMNCR_MD);
++ rpc_write(rpc, CMNCR, val);
++
++ /* ...enable burst and clear cache */
++ val = rpc_read(rpc, DRCR);
++ val &= ~(DRCR_RBURST_MASK | DRCR_RBE | DRCR_SSLE);
++ val |= DRCR_RBURST(0x1f) | DRCR_RBE;
++
++ if (cmncr & CMNCR_MD)
++ val |= DRCR_RCF;
++
++ rpc_write(rpc, DRCR, val);
++
++ return 0;
++}
++
++static int rpc_setup_data_size(struct rpc_spi *rpc, u32 size, bool copy)
++{
++ u32 val;
++
++ val = rpc_read(rpc, SMENR);
++ val &= ~(SMENR_SPIDE_MASK);
++
++ if (rpc->mtdtype == MTD_QSPI_2x && !copy)
++ size >>= 1;
++
++ switch (size) {
++ case 0:
++ break;
++ case 1:
++ val |= SMENR_SPIDE_8B;
++ break;
++ case 2:
++ val |= SMENR_SPIDE_16B;
++ break;
++ case 4:
++ val |= SMENR_SPIDE_32B;
++ break;
++ default:
++ dev_err(&rpc->pdev->dev, "Unsupported data width %d\n", size);
++ return -EINVAL;
++ }
++ rpc_write(rpc, SMENR, val);
++
++ return 0;
++}
++
++static int rpc_setup_extmode_read_addr(struct rpc_spi *rpc,
++ int adr_width, loff_t adr)
++{
++ u32 val;
++ u32 v;
++
++ val = rpc_read(rpc, DREAR);
++ val &= ~(DREAR_EAV_MASK | DREAR_EAC_MASK);
++
++ if (adr_width == 4) {
++ v = adr >> 25;
++ val |= DREAR_EAV(v) | DREAR_25B;
++ }
++ rpc_write(rpc, DREAR, val);
++
++ val = rpc_read(rpc, DRENR);
++ val &= ~(DRENR_ADE_MASK);
++ if (adr_width == 4)
++ val |= DRENR_ADE_31_0;
++ else
++ val |= DRENR_ADE_23_0;
++ rpc_write(rpc, DRENR, val);
++
++ return 0;
++}
++
++static inline int rpc_get_read_addr_nbits(u8 opcode)
++{
++ if (opcode == SPINOR_OP_READ_1_4_4_4B)
++ return 4;
++ return 1;
++}
++
++#define NBITS_TO_VAL(v) ((v >> 1) & 3)
++static int rpc_setup_extmode_nbits(struct rpc_spi *rpc, int cnb,
++ int anb, int dnb)
++{
++ u32 val;
++
++ val = rpc_read(rpc, DRENR);
++ val &= ~(DRENR_CDB_MASK | DRENR_ADB_MASK | DRENR_DRDB_MASK);
++ val |= DRENR_CDB(NBITS_TO_VAL(cnb))
++ | DRENR_ADB(NBITS_TO_VAL(anb))
++ | DRENR_DRDB(NBITS_TO_VAL(dnb));
++ rpc_write(rpc, DRENR, val);
++
++ return 0;
++}
++
++static int rpc_setup_writemode_nbits(struct rpc_spi *rpc, int cnb,
++ int anb, int dnb)
++{
++ u32 val;
++
++ val = rpc_read(rpc, SMENR);
++ val &= ~(SMENR_CDB_MASK | SMENR_ADB_MASK | SMENR_SPIDB_MASK);
++ val |= SMENR_CDB(NBITS_TO_VAL(cnb))
++ | SMENR_ADB(NBITS_TO_VAL(anb))
++ | SMENR_SPIDB(NBITS_TO_VAL(dnb));
++ rpc_write(rpc, SMENR, val);
++
++ return 0;
++}
++
++static void rpc_setup_write_mode_command_and_adr(struct rpc_spi *rpc,
++ int adr_width, bool ena)
++{
++ u32 val;
++
++ val = rpc_read(rpc, SMENR);
++ val &= ~(SMENR_CDB_MASK | SMENR_CDE | SMENR_ADE_MASK);
++
++ if (ena) {
++ /* enable 1bit command */
++ val |= SMENR_CDB_1B | SMENR_CDE;
++
++ if (adr_width == 4)
++ val |= SMENR_ADE_31_0;
++ else
++ val |= SMENR_ADE_23_0;
++ }
++ rpc_write(rpc, SMENR, val);
++}
++
++static int rpc_setup_write_mode(struct rpc_spi *rpc)
++{
++ u32 val;
++
++ rpc_wait(rpc, DEFAULT_TO);
++
++ rpc_endisable_write_buf(rpc, true);
++
++ /* ...setup manual mode */
++ val = rpc_read(rpc, CMNCR);
++ val |= CMNCR_MD;
++ rpc_write(rpc, CMNCR, val);
++
++ /* disable ddr */
++ val = rpc_read(rpc, SMDRENR);
++ val &= ~(SMDRENR_ADDRE | SMDRENR_OPDRE | SMDRENR_SPIDRE);
++ rpc_write(rpc, SMDRENR, val);
++
++ val = rpc_read(rpc, SMENR);
++ val &= ~(SMENR_OCDB_MASK | SMENR_DME | SMENR_OCDE | SMENR_SPIDB_MASK
++ | SMENR_ADB_MASK | SMENR_OPDE_MASK | SMENR_SPIDE_MASK);
++ val |= SMENR_SPIDE_32B;
++ rpc_write(rpc, SMENR, val);
++
++ return 0;
++}
++
++static void rpc_read_manual_data(struct rpc_spi *rpc, u32 *pv0, u32 *pv1)
++{
++ u32 val0, val1, rd0, rd1;
++
++ val0 = rpc_read(rpc, SMRDR0);
++ val1 = rpc_read(rpc, SMRDR1);
++
++ if (rpc->mtdtype == MTD_QSPI_2x) {
++ rd1 = (val0 & 0xff000000) | ((val0 << 8) & 0xff0000) |
++ ((val1 >> 16) & 0xff00) | ((val1 >> 8) & 0xff);
++ rd0 = ((val0 & 0xff0000) << 8) | ((val0 << 16) & 0xff0000) |
++ ((val1 >> 8) & 0xff00) | (val1 & 0xff);
++ } else
++ rd0 = val0;
++
++ if (pv0)
++ *pv0 = rd0;
++
++ if (pv1 && rpc->mtdtype == MTD_QSPI_2x)
++ *pv1 = rd1;
++}
++
++static int rpc_datalen2trancfersize(struct rpc_spi *rpc, int len, bool copy)
++{
++ int sz = len;
++
++ if (len >= 2)
++ sz = 2;
++
++ if (len >= 4)
++ sz = 4;
++
++ if (rpc->mtdtype == MTD_QSPI_2x && len >= 8 && !copy)
++ sz = 8;
++
++ return sz;
++}
++
++static int __rpc_write_data2reg(struct rpc_spi *rpc, int off,
++ const u8 *buf, int sz)
++{
++ const u32 *b32 = (const u32 *)buf;
++ const u16 *b16 = (const u16 *)buf;
++
++ if (sz == 4)
++ rpc_write(rpc, off, *b32);
++ else if (sz == 2)
++ writew(*b16, rpc->base + off);
++ else if (sz == 1)
++ writeb(*buf, rpc->base + off);
++ else if (sz != 0) {
++ dev_err(&rpc->pdev->dev, "incorrect data size %d\n", sz);
++ return -EINVAL;
++ }
++
++ return 0;
++}
++
++#define __SETVAL(x) ((((x) & 0xff) << 8) | ((x) & 0xff))
++static int rpc_write_data2reg(struct rpc_spi *rpc, const u8 *buf,
++ int sz, bool copy)
++{
++ int i, ret;
++ u32 v = 0;
++
++ if (rpc->mtdtype == MTD_QSPI_2x) {
++ if (copy) {
++ for (i = 0; i < sz && i < 2; i++)
++ v |= (__SETVAL(buf[i]) << 16*i);
++
++ ret = __rpc_write_data2reg(rpc,
++ sz == 4 ? SMWDR1 : SMWDR0,
++ (u8 *)&v,
++ sz == 4 ? sz : sz * 2);
++ if (ret)
++ return ret;
++
++ v = 0;
++ for (; i < sz; i++)
++ v |= (__SETVAL(buf[i]) << 16*i);
++
++
++ ret = __rpc_write_data2reg(rpc,
++ sz == 4 ? SMWDR0 : SMWDR1,
++ (u8 *)&v,
++ sz == 4 ? sz : sz * 2);
++ if (ret)
++ return ret;
++
++ return 0;
++ }
++
++ sz >>= 1;
++ ret = __rpc_write_data2reg(rpc,
++ sz == 4 ? SMWDR1 : SMWDR0,
++ buf,
++ sz == 4 ? sz : sz * 2);
++ if (ret)
++ return ret;
++ buf += sz;
++
++ return __rpc_write_data2reg(rpc,
++ sz == 4 ? SMWDR0 : SMWDR1,
++ buf, sz == 4 ? sz : sz * 2);
++ }
++
++ return __rpc_write_data2reg(rpc, SMWDR0, buf, sz);
++}
++
++static ssize_t rpc_write_unaligned(struct spi_nor *nor, loff_t to, size_t len,
++ const u_char *buf, size_t fullen)
++{
++ int ret = len, dsize;
++ struct rpc_spi *rpc = nor->priv;
++ bool copy = false, last;
++ loff_t _to;
++
++ rpc_endisable_write_buf(rpc, false);
++
++ while (len > 0) {
++ _to = to;
++ if (rpc->mtdtype == MTD_QSPI_2x)
++ _to >>= 1;
++ rpc_write(rpc, SMADR, _to);
++ dsize = rpc_datalen2trancfersize(rpc, len, copy);
++
++ if (rpc_setup_data_size(rpc, dsize, copy))
++ return -EINVAL;
++
++ rpc_write_data2reg(rpc, buf, dsize, copy);
++
++ last = (len <= dsize && fullen <= ret);
++ rpc_begin(rpc, false, true, last);
++ if (rpc_wait(rpc, DEFAULT_TO))
++ return -ETIMEDOUT;
++
++ /* ...disable command */
++ rpc_setup_write_mode_command_and_adr(rpc,
++ nor->addr_width, false);
++
++ buf += dsize;
++ len -= dsize;
++ to += dsize;
++ }
++
++ return ret;
++}
++
++static ssize_t rpc_write_flash(struct spi_nor *nor, loff_t to, size_t len,
++ const u_char *buf)
++{
++ ssize_t res = len, full = len;
++ u32 val;
++ u8 rval[2];
++ struct rpc_spi *rpc = nor->priv;
++ loff_t bo;
++ loff_t offset;
++ bool is_rounded = false;
++
++ /* ...len should be rounded to 2 bytes */
++ if (rpc->mtdtype == MTD_QSPI_2x && (len & 1)) {
++ is_rounded = true;
++ len &= ~(1);
++ }
++
++ bo = to & (WRITE_BUF_ADR_MASK);
++
++ rpc_flush_cache(rpc);
++ rpc_setup_write_mode(rpc);
++ rpc_setup_write_mode_command_and_adr(rpc, nor->addr_width, true);
++ rpc_setup_writemode_nbits(rpc, 1, 1, 1);
++
++ /* ...setup command */
++ val = rpc_read(rpc, SMCMR);
++ val &= ~(SMCMR_CMD_MASK);
++ val |= SMCMR_CMD(nor->program_opcode);
++ rpc_write(rpc, SMCMR, val);
++
++ offset = (to & (~WRITE_BUF_ADR_MASK));
++
++ /* ...write unaligned first bytes */
++ if (bo) {
++ size_t min = (len < (WRITE_BUF_SIZE - bo)) ? len : (WRITE_BUF_SIZE - bo);
++
++ rpc_write_unaligned(nor, to, min, buf, full);
++ rpc_setup_write_mode(rpc);
++
++ len -= min;
++ buf += min;
++ to += min;
++ full -= min;
++ }
++
++ /*
++ * TODO: Unfortunately RPC does not write properly in write buf mode
++ * without transferring command. Investigate this.
++ */
++
++ if (len) {
++ rpc_write_unaligned(nor, to, len, buf, full);
++ buf += len;
++ to += len;
++ full -= len;
++ len = 0;
++ }
++
++ if (is_rounded) {
++ rval[0] = *buf;
++ rval[1] = 0xFF;
++ rpc_write_unaligned(nor, to, 2, rval, full);
++ }
++
++ rpc_flush_cache(rpc);
++
++ return res;
++}
++
++static inline unsigned int rpc_rx_nbits(struct spi_nor *nor)
++{
++ return spi_nor_get_protocol_data_nbits(nor->read_proto);
++}
++
++#define READ_ADR_MASK (BIT(26) - 1)
++static ssize_t rpc_read_flash(struct spi_nor *nor, loff_t from, size_t len,
++ u_char *buf)
++{
++ u32 val;
++ struct rpc_spi *rpc = nor->priv;
++ int adr_width = nor->addr_width;
++ int opcode_nbits = 1;
++ int addr_nbits = rpc_get_read_addr_nbits(nor->read_opcode);
++ int data_nbits = rpc_rx_nbits(nor);
++ int dummy = nor->read_dummy - 1;
++ ssize_t ret = len;
++ ssize_t readlen;
++ loff_t _from;
++
++ rpc_setup_ext_mode(rpc);
++ /* ...setup n bits */
++ rpc_setup_extmode_nbits(rpc, opcode_nbits, addr_nbits, data_nbits);
++
++ /* TODO: setup DDR */
++
++ /* ...setup command */
++ val = rpc_read(rpc, DRCMR);
++ val &= ~(DRCMR_CMD_MASK);
++ val |= DRCMR_CMD(nor->read_opcode);
++ rpc_write(rpc, DRCMR, val);
++
++ /* ...setup dummy cycles */
++ val = rpc_read(rpc, DRDMCR);
++ val &= ~(DRDMCR_DMCYC_MASK);
++ val |= DRDMCR_DMCYC(dummy);
++ rpc_write(rpc, DRDMCR, val);
++
++ /* ...setup read sequence */
++ val = rpc_read(rpc, DRENR);
++ val |= DRENR_DME | DRENR_CDE;
++ rpc_write(rpc, DRENR, val);
++
++ while (len > 0) {
++ /* ...setup address */
++ rpc_setup_extmode_read_addr(rpc, adr_width, from);
++ /* ...use adr [25...0] */
++ _from = from & READ_ADR_MASK;
++
++ readlen = READ_ADR_MASK - _from + 1;
++ readlen = readlen > len ? len : readlen;
++
++ memcpy_fromio(buf, rpc->read_area + _from, readlen);
++ buf += readlen;
++ from += readlen;
++ len -= readlen;
++ }
++
++ return ret;
++}
++
++static int __rpc_read_reg(struct spi_nor *nor, u8 opcode, u8 *buf, int len)
++{
++ u32 val;
++ u32 val2 = 0;
++ u32 *buf32;
++ int i;
++ u32 mask = 0, type;
++ struct rpc_spi *rpc = nor->priv;
++
++ type = rpc->mtdtype;
++
++ rpc_setup_reg_mode(rpc);
++ val = rpc_read(rpc, SMCMR);
++ val &= ~(SMCMR_CMD_MASK);
++ val |= SMCMR_CMD(opcode);
++ rpc_write(rpc, SMCMR, val);
++
++ rpc_begin(rpc, true, false, len <= 4);
++ if (rpc_wait(rpc, DEFAULT_TO))
++ return -ETIMEDOUT;
++
++ /* ...disable command */
++ val = rpc_read(rpc, SMENR);
++ val &= ~(SMENR_CDE);
++ rpc_write(rpc, SMENR, val);
++
++ buf32 = (u32 *)buf;
++
++ while (len > 0) {
++ rpc_read_manual_data(rpc, &val, &val2);
++
++ if (mask) {
++ dev_warn(&rpc->pdev->dev,
++ "Using mask workaround (0x%x)\n", mask);
++ val &= ~(mask);
++ val2 &= ~(mask);
++ }
++
++ /* ... spi flashes should be the same */
++ if (type == MTD_QSPI_2x && val != val2) {
++ /* clear cs */
++ rpc_begin(rpc, true, false, true);
++ return -EAGAIN;
++ }
++
++ if (len > 4) {
++ *buf32 = val;
++ buf32++;
++ len -= 4;
++ } else {
++ buf = (u8 *)buf32;
++ for (i = 0; i < len; i++) {
++ *buf = (val >> (8 * i)) & 0x000000ff;
++ buf++;
++ }
++ len = 0;
++ }
++
++ if (!len)
++ break;
++
++ mask = 0xff;
++
++ rpc_begin(rpc, true, false, len <= 4);
++ if (rpc_wait(rpc, DEFAULT_TO))
++ return -ETIMEDOUT;
++
++ }
++
++ return 0;
++}
++
++static int rpc_read_reg(struct spi_nor *nor, u8 opcode, u8 *buf, int len)
++{
++ int i, ret;
++
++ /* A few read commands like read status can
++ * generate different answers. We repeat reading
++ * in that case
++ */
++ for (i = 0; i < REPEAT_MAX; i++) {
++ ret = __rpc_read_reg(nor, opcode, buf, len);
++ if (!ret || ret != -EAGAIN)
++ break;
++ mdelay(REPEAT_TIME);
++ }
++
++ return ret;
++}
++
++static int rpc_write_reg(struct spi_nor *nor, u8 opcode, u8 *buf, int len)
++{
++ struct rpc_spi *rpc = nor->priv;
++ u32 val;
++ int dsize;
++ bool copy = true;
++
++ rpc_setup_reg_mode(rpc);
++
++ val = rpc_read(rpc, SMCMR);
++ val &= ~(SMCMR_CMD_MASK);
++ val |= SMCMR_CMD(opcode);
++ rpc_write(rpc, SMCMR, val);
++
++ dsize = rpc_datalen2trancfersize(rpc, len, copy);
++
++ if (rpc_setup_data_size(rpc, dsize, copy))
++ return -EINVAL;
++
++ if (rpc_write_data2reg(rpc, buf, dsize, copy))
++ return -EINVAL;
++ buf += dsize;
++ len -= dsize;
++ rpc_begin(rpc, false, dsize > 0, len == 0);
++
++ if (rpc_wait(rpc, DEFAULT_TO))
++ return -ETIMEDOUT;
++
++ /* ...disable command */
++ val = rpc_read(rpc, SMENR);
++ val &= ~(SMENR_CDE);
++ rpc_write(rpc, SMENR, val);
++
++ while (len > 0) {
++ dsize = rpc_datalen2trancfersize(rpc, len, copy);
++ if (rpc_setup_data_size(rpc, dsize, copy))
++ return -EINVAL;
++ rpc_write_data2reg(rpc, buf, dsize, copy);
++ buf += dsize;
++ len -= dsize;
++
++ rpc_begin(rpc, false, dsize, len == 0);
++
++ if (rpc_wait(rpc, DEFAULT_TO))
++ return -ETIMEDOUT;
++
++ }
++
++ return 0;
++}
++
++/* hw init for spi-nor flashes */
++static int rpc_hw_init_1x2x(struct rpc_spi *rpc)
++{
++ u32 val;
++
++ /* Exec calibration */
++ val = rpc_read(rpc, PHYCNT);
++ val &= ~(PHYCNT_OCTA_MASK | PHYCNT_EXDS | PHYCNT_OCT
++ | PHYCNT_DDRCAL | PHYCNT_HS | PHYCNT_STREAM_MASK
++ | PHYCNT_WBUF2 | PHYCNT_WBUF | PHYCNT_PHYMEM_MASK);
++ val |= (PHYCNT_CAL) | PHYCNT_STREAM(6);
++ rpc_write(rpc, PHYCNT, val);
++
++ /* disable rpc_* pins */
++ val = rpc_read(rpc, PHYINT);
++ val &= ~((1<<24) | (7<<16));
++ rpc_write(rpc, PHYINT, val);
++
++ val = rpc_read(rpc, SMDRENR);
++ val &= ~(SMDRENR_HYPE_MASK);
++ val |= SMDRENR_HYPE_SPI_FLASH;
++ rpc_write(rpc, SMDRENR, val);
++
++ val = rpc_read(rpc, CMNCR);
++ val &= ~(CMNCR_BSZ_MASK);
++ if (rpc->mtdtype != MTD_QSPI_1x)
++ val |= CMNCR_BSZ_4x2;
++ rpc_write(rpc, CMNCR, val);
++
++ val = rpc_read(rpc, PHYOFFSET1);
++ val |= PHYOFFSET1_DDRTMG;
++ rpc_write(rpc, PHYOFFSET1, val);
++
++ val = SSLDR_SPNDL(0) | SSLDR_SLNDL(4) | SSLDR_SCKDL(0);
++ rpc_write(rpc, SSLDR, val);
++
++ return 0;
++}
++
++static int rpc_hw_init(struct rpc_spi *rpc)
++{
++ switch (rpc->mtdtype) {
++ case MTD_QSPI_1x:
++ case MTD_QSPI_2x:
++ return rpc_hw_init_1x2x(rpc);
++
++ default:
++ dev_err(&rpc->pdev->dev, "Unsupported connection mode\n");
++ return -ENODEV;
++ }
++}
++
++static int rpc_erase_sector(struct spi_nor *nor, loff_t addr)
++{
++ struct rpc_spi *rpc = nor->priv;
++ u8 buf[6];
++ int i;
++
++ if (rpc->mtdtype == MTD_QSPI_2x)
++ addr >>= 1;
++
++ for (i = nor->addr_width - 1; i >= 0; i--) {
++ buf[i] = addr & 0xff;
++ addr >>= 8;
++ }
++
++ return nor->write_reg(nor, nor->erase_opcode, buf, nor->addr_width);
++}
++
++static const struct of_device_id rpc_of_match[] = {
++ { .compatible = "renesas,qspi-rpc-r8a77980" },
++ { .compatible = "renesas,qspi-rpc-r8a77970", .data = (void *)OWN_CLOCK_DIVIDER },
++ { },
++};
++
++MODULE_DEVICE_TABLE(of, rpc_of_match);
++
++static int rpc_spi_probe(struct platform_device *pdev)
++{
++ struct device_node *flash_np;
++ struct spi_nor *nor;
++ struct rpc_spi *rpc;
++ struct resource *res;
++ struct spi_nor_hwcaps hwcaps = {
++ .mask = SNOR_HWCAPS_READ |
++ SNOR_HWCAPS_READ_FAST |
++ SNOR_HWCAPS_PP,
++ };
++ u32 max_clk_rate = 50000000;
++ u32 property;
++ int ret;
++ int own_clk;
++
++
++ flash_np = of_get_next_available_child(pdev->dev.of_node, NULL);
++ if (!flash_np) {
++ dev_err(&pdev->dev, "no SPI flash device to configure\n");
++ return -ENODEV;
++ }
++
++ if (!of_property_read_u32(flash_np, "spi-rx-bus-width", &property)) {
++ switch (property) {
++ case 1:
++ break;
++ case 2:
++ hwcaps.mask |= SNOR_HWCAPS_READ_DUAL;
++ break;
++ case 4:
++ hwcaps.mask |= SNOR_HWCAPS_READ_QUAD;
++ break;
++ default:
++ dev_err(&pdev->dev, "unsupported rx-bus-width\n");
++ return -EINVAL;
++ }
++ }
++
++ of_property_read_u32(flash_np, "spi-max-frequency", &max_clk_rate);
++ own_clk = (of_device_get_match_data(&pdev->dev) == (void *)OWN_CLOCK_DIVIDER);
++
++ rpc = devm_kzalloc(&pdev->dev, sizeof(*rpc), GFP_KERNEL);
++ if (!rpc)
++ return -ENOMEM;
++
++ rpc->pdev = pdev;
++
++ /* ... setup nor hooks */
++ nor = &rpc->spi_nor;
++ nor->dev = &pdev->dev;
++ spi_nor_set_flash_node(nor, flash_np);
++ nor->read = rpc_read_flash;
++ nor->write = rpc_write_flash;
++ nor->read_reg = rpc_read_reg;
++ nor->write_reg = rpc_write_reg;
++ nor->priv = rpc;
++ rpc->mtdtype = MTD_QSPI_1x;
++
++ if (of_find_property(pdev->dev.of_node, "dual", NULL)) {
++ rpc->mtdtype = MTD_QSPI_2x;
++ nor->erase = rpc_erase_sector;
++ }
++
++ /* ...get memory */
++ res = platform_get_resource(pdev, IORESOURCE_MEM, 0);
++ rpc->base = devm_ioremap_resource(&pdev->dev, res);
++ if (IS_ERR(rpc->base)) {
++ dev_err(&pdev->dev, "cannot get resources\n");
++ ret = PTR_ERR(rpc->base);
++ goto error;
++ }
++
++ res = platform_get_resource(pdev, IORESOURCE_MEM, 1);
++
++ rpc->read_area = devm_ioremap_resource(&pdev->dev, res);
++ if (IS_ERR(rpc->base)) {
++ dev_err(&pdev->dev, "cannot get resources\n");
++ ret = PTR_ERR(rpc->base);
++ goto error;
++ }
++
++ /* ...get memory */
++ res = platform_get_resource(pdev, IORESOURCE_MEM, 2);
++ rpc->write_area = devm_ioremap_resource(&pdev->dev, res);
++ if (IS_ERR(rpc->base)) {
++ dev_err(&pdev->dev, "cannot get resources\n");
++ ret = PTR_ERR(rpc->base);
++ goto error;
++ }
++
++ /* ...get clk */
++ rpc->clk = devm_clk_get(&pdev->dev, NULL);
++ if (IS_ERR(rpc->clk)) {
++ dev_err(&pdev->dev, "cannot get clock\n");
++ ret = PTR_ERR(rpc->clk);
++ goto error;
++ }
++
++ /* ...set max clk rate */
++ if (!own_clk) {
++ ret = clk_set_rate(rpc->clk, max_clk_rate);
++ if (ret) {
++ dev_err(&pdev->dev, "cannot set clock rate\n");
++ goto error;
++ }
++ }
++
++ /* ... enable clk */
++ ret = clk_prepare_enable(rpc->clk);
++ if (ret) {
++ dev_err(&pdev->dev, "cannot prepare clock\n");
++ goto error;
++ }
++
++ /* ...init device */
++ ret = rpc_hw_init(rpc);
++ if (ret < 0) {
++ dev_err(&pdev->dev, "rpc_hw_init error.\n");
++ goto error_clk_disable;
++ }
++
++ /* ...set clk ratio */
++ if (own_clk) {
++ ret = rpc_setup_clk_ratio(rpc, max_clk_rate);
++ if (ret) {
++ dev_err(&pdev->dev, "cannot set clock ratio\n");
++ goto error;
++ }
++ }
++
++ platform_set_drvdata(pdev, rpc);
++
++ ret = spi_nor_scan(nor, NULL, &hwcaps);
++ if (ret) {
++ dev_err(&pdev->dev, "spi_nor_scan error.\n");
++ goto error_clk_disable;
++ }
++
++ /* Dual mode support */
++ if (rpc->mtdtype == MTD_QSPI_2x) {
++ nor->page_size <<= 1;
++ nor->mtd.erasesize <<= 1;
++ nor->mtd.size <<= 1;
++ nor->mtd.writebufsize <<= 1;
++ }
++
++ ret = mtd_device_register(&nor->mtd, NULL, 0);
++ if (ret) {
++ dev_err(&pdev->dev, "mtd_device_register error.\n");
++ goto error_clk_disable;
++ }
++
++ dev_info(&pdev->dev, "probed as %s\n",
++ rpc->mtdtype == MTD_QSPI_1x ? "single" : "dual");
++
++ return 0;
++
++error_clk_disable:
++ clk_disable_unprepare(rpc->clk);
++error:
++ return ret;
++}
++
++static int rpc_spi_remove(struct platform_device *pdev)
++{
++ struct rpc_spi *rpc = platform_get_drvdata(pdev);
++
++ /* HW shutdown */
++ clk_disable_unprepare(rpc->clk);
++ mtd_device_unregister(&rpc->spi_nor.mtd);
++ return 0;
++}
++
++/* platform driver interface */
++static struct platform_driver rpc_platform_driver = {
++ .probe = rpc_spi_probe,
++ .remove = rpc_spi_remove,
++ .driver = {
++ .owner = THIS_MODULE,
++ .name = "rpc",
++ .of_match_table = of_match_ptr(rpc_of_match),
++ },
++};
++
++module_platform_driver(rpc_platform_driver);
++
++MODULE_ALIAS("rpc");
++MODULE_AUTHOR("Cogent Embedded Inc. <sources@cogentembedded.com>");
++MODULE_DESCRIPTION("Renesas RPC Driver");
++MODULE_LICENSE("GPL");
+--
+2.7.4
+
diff --git a/bsp/meta-rcar/meta-rcar-gen3-adas/recipes-kernel/linux/linux-renesas/0366-mtd-spi-nor-renesas-rpc-Workaround-256-byte-data-siz.patch b/bsp/meta-rcar/meta-rcar-gen3-adas/recipes-kernel/linux/linux-renesas/0366-mtd-spi-nor-renesas-rpc-Workaround-256-byte-data-siz.patch
new file mode 100644
index 00000000..e132f64f
--- /dev/null
+++ b/bsp/meta-rcar/meta-rcar-gen3-adas/recipes-kernel/linux/linux-renesas/0366-mtd-spi-nor-renesas-rpc-Workaround-256-byte-data-siz.patch
@@ -0,0 +1,35 @@
+From bc75cae7624f73ff866668793b4addd57228f5c2 Mon Sep 17 00:00:00 2001
+From: Valentine Barshak <valentine.barshak@cogentembedded.com>
+Date: Thu, 15 Nov 2018 23:58:54 +0300
+Subject: [PATCH 186/211] mtd: spi-nor: renesas-rpc: Workaround 256-byte data
+ size limitation
+
+Looks like QSPI controller does not support page sizes more
+than write buffer size. This limits maximum page size detected
+by the spi_nor_scan() callback at the RPC write buffer size.
+
+Signed-off-by: Valentine Barshak <valentine.barshak@cogentembedded.com>
+---
+ drivers/mtd/spi-nor/renesas-rpc.c | 6 ++++++
+ 1 file changed, 6 insertions(+)
+
+diff --git a/drivers/mtd/spi-nor/renesas-rpc.c b/drivers/mtd/spi-nor/renesas-rpc.c
+index b619a7e..af99762 100644
+--- a/drivers/mtd/spi-nor/renesas-rpc.c
++++ b/drivers/mtd/spi-nor/renesas-rpc.c
+@@ -1225,6 +1225,12 @@ static int rpc_spi_probe(struct platform_device *pdev)
+ nor->mtd.writebufsize <<= 1;
+ }
+
++ /* Workaround data size limitation */
++ if (nor->page_size > WRITE_BUF_SIZE) {
++ nor->page_size = WRITE_BUF_SIZE;
++ nor->mtd.writebufsize = WRITE_BUF_SIZE;
++ }
++
+ ret = mtd_device_register(&nor->mtd, NULL, 0);
+ if (ret) {
+ dev_err(&pdev->dev, "mtd_device_register error.\n");
+--
+2.7.4
+
diff --git a/bsp/meta-rcar/meta-rcar-gen3-adas/recipes-kernel/linux/linux-renesas/0367-mtd-spi-nor-Add-s25fs512s-and-s25fs128s-01-SPI-NOR-f.patch b/bsp/meta-rcar/meta-rcar-gen3-adas/recipes-kernel/linux/linux-renesas/0367-mtd-spi-nor-Add-s25fs512s-and-s25fs128s-01-SPI-NOR-f.patch
new file mode 100644
index 00000000..e0e9bf29
--- /dev/null
+++ b/bsp/meta-rcar/meta-rcar-gen3-adas/recipes-kernel/linux/linux-renesas/0367-mtd-spi-nor-Add-s25fs512s-and-s25fs128s-01-SPI-NOR-f.patch
@@ -0,0 +1,37 @@
+From 30f4055ad0dd5f3331def3131405fdc20879b828 Mon Sep 17 00:00:00 2001
+From: Valentine Barshak <valentine.barshak@cogentembedded.com>
+Date: Fri, 16 Nov 2018 00:01:22 +0300
+Subject: [PATCH 187/211] mtd: spi-nor: Add s25fs512s and s25fs128s[01] SPI NOR
+ flash support
+
+Add support for the "s25fs512s", "s25fs128s0", and "s25fs128s1"
+SPI NOR flash chips. Update "s25fl512s" device info as well because
+the difference between FS and FL devices is at JEDEC byte 5.
+
+This is based on the original patch by Dmitry Shifrin.
+
+Signed-off-by: Dmitry Shifrin <dmitry.shifrin@cogentembedded.com>
+Signed-off-by: Valentine Barshak <valentine.barshak@cogentembedded.com>
+---
+ drivers/mtd/spi-nor/spi-nor.c | 5 ++++-
+ 1 file changed, 4 insertions(+), 1 deletion(-)
+
+diff --git a/drivers/mtd/spi-nor/spi-nor.c b/drivers/mtd/spi-nor/spi-nor.c
+index d458523..49ffc9a 100644
+--- a/drivers/mtd/spi-nor/spi-nor.c
++++ b/drivers/mtd/spi-nor/spi-nor.c
+@@ -1057,7 +1057,10 @@ static const struct flash_info spi_nor_ids[] = {
+ { "s25sl064p", INFO(0x010216, 0x4d00, 64 * 1024, 128, SPI_NOR_DUAL_READ | SPI_NOR_QUAD_READ) },
+ { "s25fl256s0", INFO(0x010219, 0x4d00, 256 * 1024, 128, USE_CLSR) },
+ { "s25fl256s1", INFO(0x010219, 0x4d01, 64 * 1024, 512, SPI_NOR_DUAL_READ | SPI_NOR_QUAD_READ | USE_CLSR) },
+- { "s25fl512s", INFO(0x010220, 0x4d00, 256 * 1024, 256, SPI_NOR_DUAL_READ | SPI_NOR_QUAD_READ | USE_CLSR) },
++ { "s25fl512s", INFO6(0x010220, 0x4d0080, 256 * 1024, 256, SPI_NOR_DUAL_READ | SPI_NOR_QUAD_READ) },
++ { "s25fs512s", INFO6(0x010220, 0x4d0081, 256 * 1024, 256, SPI_NOR_DUAL_READ | SPI_NOR_QUAD_READ | USE_CLSR | SECT_4K) },
++ { "s25fs128s0", INFO6(0x012018, 0x4d0381, 256 * 1024, 64, SPI_NOR_DUAL_READ | SPI_NOR_QUAD_READ | USE_CLSR | SECT_4K) },
++ { "s25fs128s1", INFO6(0x012018, 0x4d0181, 64 * 1024, 256, SPI_NOR_DUAL_READ | SPI_NOR_QUAD_READ | USE_CLSR | SECT_4K) },
+ { "s70fl01gs", INFO(0x010221, 0x4d00, 256 * 1024, 256, 0) },
+ { "s25sl12800", INFO(0x012018, 0x0300, 256 * 1024, 64, 0) },
+ { "s25sl12801", INFO(0x012018, 0x0301, 64 * 1024, 256, 0) },
+--
+2.7.4
+
diff --git a/bsp/meta-rcar/meta-rcar-gen3-adas/recipes-kernel/linux/linux-renesas/0368-arm64-dts-renesas-r8a77970-Add-RPC-QSPI-node.patch b/bsp/meta-rcar/meta-rcar-gen3-adas/recipes-kernel/linux/linux-renesas/0368-arm64-dts-renesas-r8a77970-Add-RPC-QSPI-node.patch
new file mode 100644
index 00000000..917875a3
--- /dev/null
+++ b/bsp/meta-rcar/meta-rcar-gen3-adas/recipes-kernel/linux/linux-renesas/0368-arm64-dts-renesas-r8a77970-Add-RPC-QSPI-node.patch
@@ -0,0 +1,41 @@
+From aa31c93e29d6e4dca93e167a97875cb225b062e4 Mon Sep 17 00:00:00 2001
+From: Valentine Barshak <valentine.barshak@cogentembedded.com>
+Date: Fri, 16 Nov 2018 00:01:48 +0300
+Subject: [PATCH 188/211] arm64: dts: renesas: r8a77970: Add RPC QSPI node
+
+Add RPC QSPI device node. This is based
+on the original patch by Dmitry Shifrin.
+
+Signed-off-by: Dmitry Shifrin <dmitry.shifrin@cogentembedded.com>
+Signed-off-by: Valentine Barshak <valentine.barshak@cogentembedded.com>
+---
+ arch/arm64/boot/dts/renesas/r8a77970.dtsi | 13 +++++++++++++
+ 1 file changed, 13 insertions(+)
+
+diff --git a/arch/arm64/boot/dts/renesas/r8a77970.dtsi b/arch/arm64/boot/dts/renesas/r8a77970.dtsi
+index 090122c..23422c7 100644
+--- a/arch/arm64/boot/dts/renesas/r8a77970.dtsi
++++ b/arch/arm64/boot/dts/renesas/r8a77970.dtsi
+@@ -767,6 +767,19 @@
+ status = "disabled";
+ };
+
++ qspi0: qspi@ee200000 {
++ compatible = "renesas,qspi-rpc-r8a77970";
++ reg = <0 0xee200000 0 0x1f0>,
++ <0 0x08000000 0 0x04000000>,
++ <0 0xee208000 0 0x100>;
++ interrupts = <GIC_SPI 38 IRQ_TYPE_LEVEL_HIGH>;
++ clocks = <&cpg CPG_MOD 917>;
++ power-domains = <&sysc R8A77970_PD_ALWAYS_ON>;
++ #address-cells = <1>;
++ #size-cells = <0>;
++ status = "disabled";
++ };
++
+ msiof0: spi@e6e90000 {
+ compatible = "renesas,msiof-r8a77970",
+ "renesas,rcar-gen3-msiof";
+--
+2.7.4
+
diff --git a/bsp/meta-rcar/meta-rcar-gen3-adas/recipes-kernel/linux/linux-renesas/0369-arm64-dts-renesas-r8a77980-Add-RPC-QSPI-node.patch b/bsp/meta-rcar/meta-rcar-gen3-adas/recipes-kernel/linux/linux-renesas/0369-arm64-dts-renesas-r8a77980-Add-RPC-QSPI-node.patch
new file mode 100644
index 00000000..ba242de3
--- /dev/null
+++ b/bsp/meta-rcar/meta-rcar-gen3-adas/recipes-kernel/linux/linux-renesas/0369-arm64-dts-renesas-r8a77980-Add-RPC-QSPI-node.patch
@@ -0,0 +1,41 @@
+From aaf5960d267e42b7bc1699e8e614c806723e263b Mon Sep 17 00:00:00 2001
+From: Valentine Barshak <valentine.barshak@cogentembedded.com>
+Date: Fri, 16 Nov 2018 00:02:16 +0300
+Subject: [PATCH 189/211] arm64: dts: renesas: r8a77980: Add RPC QSPI node
+
+Add RPC QSPI device node. This is based
+on the original patch by Dmitry Shifrin.
+
+Signed-off-by: Dmitry Shifrin <dmitry.shifrin@cogentembedded.com>
+Signed-off-by: Valentine Barshak <valentine.barshak@cogentembedded.com>
+---
+ arch/arm64/boot/dts/renesas/r8a77980.dtsi | 13 +++++++++++++
+ 1 file changed, 13 insertions(+)
+
+diff --git a/arch/arm64/boot/dts/renesas/r8a77980.dtsi b/arch/arm64/boot/dts/renesas/r8a77980.dtsi
+index c599814..688bc09 100644
+--- a/arch/arm64/boot/dts/renesas/r8a77980.dtsi
++++ b/arch/arm64/boot/dts/renesas/r8a77980.dtsi
+@@ -823,6 +823,19 @@
+ status = "disabled";
+ };
+
++ qspi0: qspi@ee200000 {
++ compatible = "renesas,qspi-rpc-r8a77980";
++ reg = <0 0xee200000 0 0x1f0>,
++ <0 0x08000000 0 0x04000000>,
++ <0 0xee208000 0 0x100>;
++ interrupts = <GIC_SPI 38 IRQ_TYPE_LEVEL_HIGH>;
++ clocks = <&cpg CPG_MOD 917>;
++ power-domains = <&sysc R8A77980_PD_ALWAYS_ON>;
++ #address-cells = <1>;
++ #size-cells = <0>;
++ status = "disabled";
++ };
++
+ msiof0: spi@e6e90000 {
+ compatible = "renesas,msiof-r8a77980",
+ "renesas,rcar-gen3-msiof";
+--
+2.7.4
+
diff --git a/bsp/meta-rcar/meta-rcar-gen3-adas/recipes-kernel/linux/linux-renesas/0370-arm64-dts-renesas-v3msk-Add-s25fs512s-QSPI-flash-nod.patch b/bsp/meta-rcar/meta-rcar-gen3-adas/recipes-kernel/linux/linux-renesas/0370-arm64-dts-renesas-v3msk-Add-s25fs512s-QSPI-flash-nod.patch
new file mode 100644
index 00000000..4753e389
--- /dev/null
+++ b/bsp/meta-rcar/meta-rcar-gen3-adas/recipes-kernel/linux/linux-renesas/0370-arm64-dts-renesas-v3msk-Add-s25fs512s-QSPI-flash-nod.patch
@@ -0,0 +1,107 @@
+From d9c1db5efa52e0febebfdc351905501760d37454 Mon Sep 17 00:00:00 2001
+From: Valentine Barshak <valentine.barshak@cogentembedded.com>
+Date: Fri, 16 Nov 2018 00:02:40 +0300
+Subject: [PATCH 190/211] arm64: dts: renesas: v3msk: Add s25fs512s QSPI flash
+ node
+
+Add s25fs512s QSPI flash node. This is based
+on the original patch by Dmitry Shifrin.
+
+Signed-off-by: Dmitry Shifrin <dmitry.shifrin@cogentembedded.com>
+Signed-off-by: Valentine Barshak <valentine.barshak@cogentembedded.com>
+---
+ arch/arm64/boot/dts/renesas/r8a77970-v3msk.dts | 72 ++++++++++++++++++++++++++
+ 1 file changed, 72 insertions(+)
+
+diff --git a/arch/arm64/boot/dts/renesas/r8a77970-v3msk.dts b/arch/arm64/boot/dts/renesas/r8a77970-v3msk.dts
+index adc2b01..ef9a2c5 100644
+--- a/arch/arm64/boot/dts/renesas/r8a77970-v3msk.dts
++++ b/arch/arm64/boot/dts/renesas/r8a77970-v3msk.dts
+@@ -179,12 +179,84 @@
+ power-source = <3300>;
+ };
+
++ qspi0_pins: qspi0 {
++ groups = "qspi0_ctrl", "qspi0_data4";
++ function = "qspi0";
++ };
++
++ qspi1_pins: qspi1 {
++ groups = "qspi1_ctrl", "qspi1_data4";
++ function = "qspi1";
++ };
++
+ scif0_pins: scif0 {
+ groups = "scif0_data";
+ function = "scif0";
+ };
+ };
+
++&qspi0 {
++ pinctrl-0 = <&qspi0_pins &qspi1_pins>;
++ pinctrl-names = "default";
++
++ status = "okay";
++
++ flash@0 {
++ compatible = "spansion,s25fs512s", "jedec,spi-nor";
++ reg = <0>;
++ spi-max-frequency = <50000000>;
++ spi-rx-bus-width = <4>;
++
++ partitions {
++ compatible = "fixed-partitions";
++ #address-cells = <1>;
++ #size-cells = <1>;
++
++ bootparam@0 {
++ reg = <0x00000000 0x040000>;
++ read-only;
++ };
++ cr7@00040000 {
++ reg = <0x00040000 0x080000>;
++ read-only;
++ };
++ cert_header_sa3@000C0000 {
++ reg = <0x000C0000 0x080000>;
++ read-only;
++ };
++ bl2@00140000 {
++ reg = <0x00140000 0x040000>;
++ read-only;
++ };
++ cert_header_sa6@00180000 {
++ reg = <0x00180000 0x040000>;
++ read-only;
++ };
++ bl31@001C0000 {
++ reg = <0x001C0000 0x480000>;
++ read-only;
++ };
++ uboot@00640000 {
++ reg = <0x00640000 0x0C0000>;
++ read-only;
++ };
++ uboot-env@00700000 {
++ reg = <0x00700000 0x040000>;
++ read-only;
++ };
++ dtb@00740000 {
++ reg = <0x00740000 0x080000>;
++ };
++ kernel@007C0000 {
++ reg = <0x007C0000 0x1400000>;
++ };
++ user@01BC0000 {
++ reg = <0x01BC0000 0x2440000>;
++ };
++ };
++ };
++};
++
+ &i2c0 {
+ pinctrl-0 = <&i2c0_pins>;
+ pinctrl-names = "default";
+--
+2.7.4
+
diff --git a/bsp/meta-rcar/meta-rcar-gen3-adas/recipes-kernel/linux/linux-renesas/0371-arm64-dts-renesas-v3mzf-Add-s25fs512s-QSPI-flash-nod.patch b/bsp/meta-rcar/meta-rcar-gen3-adas/recipes-kernel/linux/linux-renesas/0371-arm64-dts-renesas-v3mzf-Add-s25fs512s-QSPI-flash-nod.patch
new file mode 100644
index 00000000..7eb94366
--- /dev/null
+++ b/bsp/meta-rcar/meta-rcar-gen3-adas/recipes-kernel/linux/linux-renesas/0371-arm64-dts-renesas-v3mzf-Add-s25fs512s-QSPI-flash-nod.patch
@@ -0,0 +1,104 @@
+From bad00e588837b41775c80fe9fa6ee999e398f462 Mon Sep 17 00:00:00 2001
+From: Valentine Barshak <valentine.barshak@cogentembedded.com>
+Date: Fri, 16 Nov 2018 00:03:02 +0300
+Subject: [PATCH 191/211] arm64: dts: renesas: v3mzf: Add s25fs512s QSPI flash
+ node
+
+Add s25fs512s QSPI flash node. This is based
+on the original patch by Dmitry Shifrin.
+
+Signed-off-by: Dmitry Shifrin <dmitry.shifrin@cogentembedded.com>
+Signed-off-by: Valentine Barshak <valentine.barshak@cogentembedded.com>
+---
+ arch/arm64/boot/dts/renesas/r8a77970-v3mzf.dts | 68 ++++++++++++++++++++++++++
+ 1 file changed, 68 insertions(+)
+
+diff --git a/arch/arm64/boot/dts/renesas/r8a77970-v3mzf.dts b/arch/arm64/boot/dts/renesas/r8a77970-v3mzf.dts
+index 71a765a..caecf8c 100644
+--- a/arch/arm64/boot/dts/renesas/r8a77970-v3mzf.dts
++++ b/arch/arm64/boot/dts/renesas/r8a77970-v3mzf.dts
+@@ -372,6 +372,16 @@
+ function = "msiof3";
+ };
+
++ qspi0_pins: qspi0 {
++ groups = "qspi0_ctrl", "qspi0_data4";
++ function = "qspi0";
++ };
++
++ qspi1_pins: qspi1 {
++ groups = "qspi1_ctrl", "qspi1_data4";
++ function = "qspi1";
++ };
++
+ scif0_pins: scif0 {
+ groups = "scif0_data";
+ function = "scif0";
+@@ -389,6 +399,64 @@
+ };
+ };
+
++&qspi0 {
++ pinctrl-0 = <&qspi0_pins &qspi1_pins>;
++ pinctrl-names = "default";
++
++ status = "okay";
++
++ flash@0 {
++ compatible = "spansion,s25fs512s", "jedec,spi-nor";
++ reg = <0>;
++ spi-max-frequency = <50000000>;
++ spi-rx-bus-width = <4>;
++
++ partitions {
++ compatible = "fixed-partitions";
++ #address-cells = <1>;
++ #size-cells = <1>;
++
++ bootparam@0 {
++ reg = <0x00000000 0x040000>;
++ read-only;
++ };
++ cr7@00040000 {
++ reg = <0x00040000 0x080000>;
++ read-only;
++ };
++ cert_header_sa3@000C0000 {
++ reg = <0x000C0000 0x080000>;
++ read-only;
++ };
++ bl2@00140000 {
++ reg = <0x00140000 0x040000>;
++ read-only;
++ };
++ cert_header_sa6@00180000 {
++ reg = <0x00180000 0x040000>;
++ read-only;
++ };
++ bl31@001C0000 {
++ reg = <0x001C0000 0x480000>;
++ read-only;
++ };
++ uboot@00640000 {
++ reg = <0x00640000 0x100000>;
++ read-only;
++ };
++ dtb@00740000 {
++ reg = <0x00740000 0x080000>;
++ };
++ kernel@007C0000 {
++ reg = <0x007C0000 0x1400000>;
++ };
++ user@01BC0000 {
++ reg = <0x01BC0000 0x2440000>;
++ };
++ };
++ };
++};
++
+ &scif0 {
+ pinctrl-0 = <&scif0_pins>;
+ pinctrl-names = "default";
+--
+2.7.4
+
diff --git a/bsp/meta-rcar/meta-rcar-gen3-adas/recipes-kernel/linux/linux-renesas/0372-arm64-dts-renesas-eagle-Add-s25fs512s-QSPI-flash-nod.patch b/bsp/meta-rcar/meta-rcar-gen3-adas/recipes-kernel/linux/linux-renesas/0372-arm64-dts-renesas-eagle-Add-s25fs512s-QSPI-flash-nod.patch
new file mode 100644
index 00000000..442aac6f
--- /dev/null
+++ b/bsp/meta-rcar/meta-rcar-gen3-adas/recipes-kernel/linux/linux-renesas/0372-arm64-dts-renesas-eagle-Add-s25fs512s-QSPI-flash-nod.patch
@@ -0,0 +1,107 @@
+From 7f2e7da3e400e1cccbe5886e4e3e22f16ed539c3 Mon Sep 17 00:00:00 2001
+From: Valentine Barshak <valentine.barshak@cogentembedded.com>
+Date: Fri, 16 Nov 2018 00:03:20 +0300
+Subject: [PATCH 192/211] arm64: dts: renesas: eagle: Add s25fs512s QSPI flash
+ node
+
+Add s25fs512s QSPI flash node. This is based
+on the original patch by Dmitry Shifrin.
+
+Signed-off-by: Dmitry Shifrin <dmitry.shifrin@cogentembedded.com>
+Signed-off-by: Valentine Barshak <valentine.barshak@cogentembedded.com>
+---
+ arch/arm64/boot/dts/renesas/r8a77970-eagle.dts | 72 ++++++++++++++++++++++++++
+ 1 file changed, 72 insertions(+)
+
+diff --git a/arch/arm64/boot/dts/renesas/r8a77970-eagle.dts b/arch/arm64/boot/dts/renesas/r8a77970-eagle.dts
+index b87f418..7d93834 100644
+--- a/arch/arm64/boot/dts/renesas/r8a77970-eagle.dts
++++ b/arch/arm64/boot/dts/renesas/r8a77970-eagle.dts
+@@ -404,12 +404,84 @@
+ function = "i2c3";
+ };
+
++ qspi0_pins: qspi0 {
++ groups = "qspi0_ctrl", "qspi0_data4";
++ function = "qspi0";
++ };
++
++ qspi1_pins: qspi1 {
++ groups = "qspi1_ctrl", "qspi1_data4";
++ function = "qspi1";
++ };
++
+ scif0_pins: scif0 {
+ groups = "scif0_data";
+ function = "scif0";
+ };
+ };
+
++&qspi0 {
++ pinctrl-0 = <&qspi0_pins &qspi1_pins>;
++ pinctrl-names = "default";
++
++ status = "okay";
++
++ flash@0 {
++ compatible = "spansion,s25fs512s", "jedec,spi-nor";
++ reg = <0>;
++ spi-max-frequency = <50000000>;
++ spi-rx-bus-width = <4>;
++
++ partitions {
++ compatible = "fixed-partitions";
++ #address-cells = <1>;
++ #size-cells = <1>;
++
++ bootparam@0 {
++ reg = <0x00000000 0x040000>;
++ read-only;
++ };
++ cr7@00040000 {
++ reg = <0x00040000 0x080000>;
++ read-only;
++ };
++ cert_header_sa3@000C0000 {
++ reg = <0x000C0000 0x080000>;
++ read-only;
++ };
++ bl2@00140000 {
++ reg = <0x00140000 0x040000>;
++ read-only;
++ };
++ cert_header_sa6@00180000 {
++ reg = <0x00180000 0x040000>;
++ read-only;
++ };
++ bl31@001C0000 {
++ reg = <0x001C0000 0x480000>;
++ read-only;
++ };
++ uboot@00640000 {
++ reg = <0x00640000 0x0C0000>;
++ read-only;
++ };
++ uboot-env@00700000 {
++ reg = <0x00700000 0x040000>;
++ read-only;
++ };
++ dtb@00740000 {
++ reg = <0x00740000 0x080000>;
++ };
++ kernel@007C0000 {
++ reg = <0x007C0000 0x1400000>;
++ };
++ user@01BC0000 {
++ reg = <0x01BC0000 0x2440000>;
++ };
++ };
++ };
++};
++
+ &rwdt {
+ timeout-sec = <60>;
+ status = "okay";
+--
+2.7.4
+
diff --git a/bsp/meta-rcar/meta-rcar-gen3-adas/recipes-kernel/linux/linux-renesas/0373-arm64-dts-renesas-v3hsk-Add-s25fs512s-QSPI-flash-nod.patch b/bsp/meta-rcar/meta-rcar-gen3-adas/recipes-kernel/linux/linux-renesas/0373-arm64-dts-renesas-v3hsk-Add-s25fs512s-QSPI-flash-nod.patch
new file mode 100644
index 00000000..4c3fe0a9
--- /dev/null
+++ b/bsp/meta-rcar/meta-rcar-gen3-adas/recipes-kernel/linux/linux-renesas/0373-arm64-dts-renesas-v3hsk-Add-s25fs512s-QSPI-flash-nod.patch
@@ -0,0 +1,101 @@
+From 44f30278153ce5dc1de882117ebff3526a997d95 Mon Sep 17 00:00:00 2001
+From: Valentine Barshak <valentine.barshak@cogentembedded.com>
+Date: Fri, 16 Nov 2018 00:03:36 +0300
+Subject: [PATCH 193/211] arm64: dts: renesas: v3hsk: Add s25fs512s QSPI flash
+ node
+
+Add s25fs512s QSPI flash node. This is based
+on the original patch by Dmitry Shifrin.
+
+Signed-off-by: Dmitry Shifrin <dmitry.shifrin@cogentembedded.com>
+Signed-off-by: Valentine Barshak <valentine.barshak@cogentembedded.com>
+---
+ arch/arm64/boot/dts/renesas/r8a77980-v3hsk.dts | 72 ++++++++++++++++++++++++++
+ 1 file changed, 72 insertions(+)
+
+diff --git a/arch/arm64/boot/dts/renesas/r8a77980-v3hsk.dts b/arch/arm64/boot/dts/renesas/r8a77980-v3hsk.dts
+index 0e0aed7..cfbfd98 100644
+--- a/arch/arm64/boot/dts/renesas/r8a77980-v3hsk.dts
++++ b/arch/arm64/boot/dts/renesas/r8a77980-v3hsk.dts
+@@ -251,6 +251,78 @@
+ function = "mmc";
+ power-source = <3300>;
+ };
++
++ qspi0_pins: qspi0 {
++ groups = "qspi0_ctrl", "qspi0_data4";
++ function = "qspi0";
++ };
++
++ qspi1_pins: qspi1 {
++ groups = "qspi1_ctrl", "qspi1_data4";
++ function = "qspi1";
++ };
++};
++
++&qspi0 {
++ pinctrl-0 = <&qspi0_pins &qspi1_pins>;
++ pinctrl-names = "default";
++
++ status = "okay";
++
++ flash@0 {
++ compatible = "spansion,s25fs512s", "jedec,spi-nor";
++ reg = <0>;
++ spi-max-frequency = <50000000>;
++ spi-rx-bus-width = <4>;
++
++ partitions {
++ compatible = "fixed-partitions";
++ #address-cells = <1>;
++ #size-cells = <1>;
++
++ bootparam@0 {
++ reg = <0x00000000 0x040000>;
++ read-only;
++ };
++ cr7@00040000 {
++ reg = <0x00040000 0x080000>;
++ read-only;
++ };
++ cert_header_sa3@000C0000 {
++ reg = <0x000C0000 0x080000>;
++ read-only;
++ };
++ bl2@00140000 {
++ reg = <0x00140000 0x040000>;
++ read-only;
++ };
++ cert_header_sa6@00180000 {
++ reg = <0x00180000 0x040000>;
++ read-only;
++ };
++ bl31@001C0000 {
++ reg = <0x001C0000 0x480000>;
++ read-only;
++ };
++ uboot@00640000 {
++ reg = <0x00640000 0x0C0000>;
++ read-only;
++ };
++ uboot-env@00700000 {
++ reg = <0x00700000 0x040000>;
++ read-only;
++ };
++ dtb@00740000 {
++ reg = <0x00740000 0x080000>;
++ };
++ kernel@007C0000 {
++ reg = <0x007C0000 0x1400000>;
++ };
++ user@01BC0000 {
++ reg = <0x01BC0000 0x2440000>;
++ };
++ };
++ };
+ };
+
+ &rwdt {
+--
+2.7.4
+
diff --git a/bsp/meta-rcar/meta-rcar-gen3-adas/recipes-kernel/linux/linux-renesas/0374-arm64-dts-renesas-condor-Add-s25fs512s-QSPI-flash-no.patch b/bsp/meta-rcar/meta-rcar-gen3-adas/recipes-kernel/linux/linux-renesas/0374-arm64-dts-renesas-condor-Add-s25fs512s-QSPI-flash-no.patch
new file mode 100644
index 00000000..22d2fcf6
--- /dev/null
+++ b/bsp/meta-rcar/meta-rcar-gen3-adas/recipes-kernel/linux/linux-renesas/0374-arm64-dts-renesas-condor-Add-s25fs512s-QSPI-flash-no.patch
@@ -0,0 +1,108 @@
+From 8ba13604f545465951c92f5f1d677eb10ff71dec Mon Sep 17 00:00:00 2001
+From: Valentine Barshak <valentine.barshak@cogentembedded.com>
+Date: Fri, 16 Nov 2018 00:03:54 +0300
+Subject: [PATCH 194/211] arm64: dts: renesas: condor: Add s25fs512s QSPI flash
+ node
+
+Add s25fs512s QSPI flash node. This is based
+on the original patch by Dmitry Shifrin.
+
+Signed-off-by: Dmitry Shifrin <dmitry.shifrin@cogentembedded.com>
+Signed-off-by: Valentine Barshak <valentine.barshak@cogentembedded.com>
+---
+ arch/arm64/boot/dts/renesas/r8a77980-condor.dts | 72 +++++++++++++++++++++++++
+ 1 file changed, 72 insertions(+)
+
+diff --git a/arch/arm64/boot/dts/renesas/r8a77980-condor.dts b/arch/arm64/boot/dts/renesas/r8a77980-condor.dts
+index 577ff3a..6b5f574 100644
+--- a/arch/arm64/boot/dts/renesas/r8a77980-condor.dts
++++ b/arch/arm64/boot/dts/renesas/r8a77980-condor.dts
+@@ -629,6 +629,16 @@
+ power-source = <1800>;
+ };
+
++ qspi0_pins: qspi0 {
++ groups = "qspi0_ctrl", "qspi0_data4";
++ function = "qspi0";
++ };
++
++ qspi1_pins: qspi1 {
++ groups = "qspi1_ctrl", "qspi1_data4";
++ function = "qspi1";
++ };
++
+ scif0_pins: scif0 {
+ groups = "scif0_data";
+ function = "scif0";
+@@ -640,6 +650,68 @@
+ };
+ };
+
++&qspi0 {
++ pinctrl-0 = <&qspi0_pins &qspi1_pins>;
++ pinctrl-names = "default";
++
++ status = "okay";
++
++ flash@0 {
++ compatible = "spansion,s25fs512s", "jedec,spi-nor";
++ reg = <0>;
++ spi-max-frequency = <50000000>;
++ spi-rx-bus-width = <4>;
++
++ partitions {
++ compatible = "fixed-partitions";
++ #address-cells = <1>;
++ #size-cells = <1>;
++
++ bootparam@0 {
++ reg = <0x00000000 0x040000>;
++ read-only;
++ };
++ cr7@00040000 {
++ reg = <0x00040000 0x080000>;
++ read-only;
++ };
++ cert_header_sa3@000C0000 {
++ reg = <0x000C0000 0x080000>;
++ read-only;
++ };
++ bl2@00140000 {
++ reg = <0x00140000 0x040000>;
++ read-only;
++ };
++ cert_header_sa6@00180000 {
++ reg = <0x00180000 0x040000>;
++ read-only;
++ };
++ bl31@001C0000 {
++ reg = <0x001C0000 0x480000>;
++ read-only;
++ };
++ uboot@00640000 {
++ reg = <0x00640000 0x0C0000>;
++ read-only;
++ };
++ uboot-env@00700000 {
++ reg = <0x00700000 0x040000>;
++ read-only;
++ };
++ dtb@00740000 {
++ reg = <0x00740000 0x080000>;
++ };
++ kernel@007C0000 {
++ reg = <0x007C0000 0x1400000>;
++ };
++ user@01BC0000 {
++ reg = <0x01BC0000 0x2440000>;
++ };
++ };
++ };
++};
++
+ &rwdt {
+ timeout-sec = <60>;
+ status = "okay";
+--
+2.7.4
+
diff --git a/bsp/meta-rcar/meta-rcar-gen3-adas/recipes-kernel/linux/linux-renesas/0375-mtd-spi-nor-renesas-rpc-Support-single-mode-write-co.patch b/bsp/meta-rcar/meta-rcar-gen3-adas/recipes-kernel/linux/linux-renesas/0375-mtd-spi-nor-renesas-rpc-Support-single-mode-write-co.patch
new file mode 100644
index 00000000..6f0454ab
--- /dev/null
+++ b/bsp/meta-rcar/meta-rcar-gen3-adas/recipes-kernel/linux/linux-renesas/0375-mtd-spi-nor-renesas-rpc-Support-single-mode-write-co.patch
@@ -0,0 +1,61 @@
+From cfdd31e5cef09e255d42a39fe1171db7dfa9bd55 Mon Sep 17 00:00:00 2001
+From: Valentine Barshak <valentine.barshak@cogentembedded.com>
+Date: Fri, 16 Nov 2018 00:04:14 +0300
+Subject: [PATCH 195/211] mtd: spi-nor: renesas: rpc: Support single mode write
+ command
+
+This adds single mode write command support.
+
+Signed-off-by: Andrey Gusakov <andrey.gusakov@cogentembedded.com>
+Signed-off-by: Valentine Barshak <valentine.barshak@cogentembedded.com>
+---
+ drivers/mtd/spi-nor/renesas-rpc.c | 12 ++++++++----
+ 1 file changed, 8 insertions(+), 4 deletions(-)
+
+diff --git a/drivers/mtd/spi-nor/renesas-rpc.c b/drivers/mtd/spi-nor/renesas-rpc.c
+index af99762..4cd50b1 100644
+--- a/drivers/mtd/spi-nor/renesas-rpc.c
++++ b/drivers/mtd/spi-nor/renesas-rpc.c
+@@ -555,7 +555,7 @@ static void rpc_setup_write_mode_command_and_adr(struct rpc_spi *rpc,
+ rpc_write(rpc, SMENR, val);
+ }
+
+-static int rpc_setup_write_mode(struct rpc_spi *rpc)
++static int rpc_setup_write_mode(struct rpc_spi *rpc, u8 opcode)
+ {
+ u32 val;
+
+@@ -576,7 +576,11 @@ static int rpc_setup_write_mode(struct rpc_spi *rpc)
+ val = rpc_read(rpc, SMENR);
+ val &= ~(SMENR_OCDB_MASK | SMENR_DME | SMENR_OCDE | SMENR_SPIDB_MASK
+ | SMENR_ADB_MASK | SMENR_OPDE_MASK | SMENR_SPIDE_MASK);
+- val |= SMENR_SPIDE_32B;
++ if (opcode != SPINOR_OP_PP)
++ val |= SMENR_SPIDE_32B;
++ else
++ val |= SMENR_SPIDE_8B;
++
+ rpc_write(rpc, SMENR, val);
+
+ return 0;
+@@ -750,7 +754,7 @@ static ssize_t rpc_write_flash(struct spi_nor *nor, loff_t to, size_t len,
+ bo = to & (WRITE_BUF_ADR_MASK);
+
+ rpc_flush_cache(rpc);
+- rpc_setup_write_mode(rpc);
++ rpc_setup_write_mode(rpc, nor->program_opcode);
+ rpc_setup_write_mode_command_and_adr(rpc, nor->addr_width, true);
+ rpc_setup_writemode_nbits(rpc, 1, 1, 1);
+
+@@ -767,7 +771,7 @@ static ssize_t rpc_write_flash(struct spi_nor *nor, loff_t to, size_t len,
+ size_t min = (len < (WRITE_BUF_SIZE - bo)) ? len : (WRITE_BUF_SIZE - bo);
+
+ rpc_write_unaligned(nor, to, min, buf, full);
+- rpc_setup_write_mode(rpc);
++ rpc_setup_write_mode(rpc, nor->program_opcode);
+
+ len -= min;
+ buf += min;
+--
+2.7.4
+
diff --git a/bsp/meta-rcar/meta-rcar-gen3-adas/recipes-kernel/linux/linux-renesas/0376-mtd-spi-nor-renesas-rpc-Add-DMA-read-support.patch b/bsp/meta-rcar/meta-rcar-gen3-adas/recipes-kernel/linux/linux-renesas/0376-mtd-spi-nor-renesas-rpc-Add-DMA-read-support.patch
new file mode 100644
index 00000000..4b17f99d
--- /dev/null
+++ b/bsp/meta-rcar/meta-rcar-gen3-adas/recipes-kernel/linux/linux-renesas/0376-mtd-spi-nor-renesas-rpc-Add-DMA-read-support.patch
@@ -0,0 +1,219 @@
+From 094ab0a4aaf8e0797ae51ea4cf7b84bb0b95dadf Mon Sep 17 00:00:00 2001
+From: Valentine Barshak <valentine.barshak@cogentembedded.com>
+Date: Fri, 16 Nov 2018 10:04:14 +0300
+Subject: [PATCH 196/211] mtd: spi-nor: renesas-rpc: Add DMA read support
+
+This adds DMA read support which can be disabled
+by the "use_dma=0" module parameter.
+Minimum DMA transfer size equals 8 RBURST chunks.
+DMA transfer size is truncated to a multiple of
+RBURST size. The remainder is left for the next
+transfer iteration.
+
+Signed-off-by: Valentine Barshak <valentine.barshak@cogentembedded.com>
+---
+ drivers/mtd/spi-nor/renesas-rpc.c | 108 ++++++++++++++++++++++++++++++++++++--
+ 1 file changed, 104 insertions(+), 4 deletions(-)
+
+diff --git a/drivers/mtd/spi-nor/renesas-rpc.c b/drivers/mtd/spi-nor/renesas-rpc.c
+index 4cd50b1..0026b99 100644
+--- a/drivers/mtd/spi-nor/renesas-rpc.c
++++ b/drivers/mtd/spi-nor/renesas-rpc.c
+@@ -14,6 +14,8 @@
+ */
+
+ #include <linux/clk.h>
++#include <linux/dma-mapping.h>
++#include <linux/dmaengine.h>
+ #include <linux/module.h>
+ #include <linux/of.h>
+ #include <linux/of_device.h>
+@@ -73,7 +75,7 @@
+ #define DRCR_SSLE (0x1)
+ #define DRCR_RBE (0x1 << 8)
+ #define DRCR_RCF (0x1 << 9)
+-#define DRCR_RBURST_32 (0x1f << 16)
++#define DRCR_RBURST_32 (0x1f)
+
+ /* SMENR */
+ #define SMENR_CDB_MASK (0x03 << 30)
+@@ -240,6 +242,9 @@ struct rpc_spi {
+ void __iomem *base;
+ void __iomem *read_area;
+ void __iomem *write_area;
++ dma_addr_t read_area_dma;
++ struct completion comp;
++ struct dma_chan *dma_chan;
+ struct clk *clk;
+ unsigned int irq;
+ struct spi_nor spi_nor;
+@@ -253,6 +258,13 @@ struct rpc_spi {
+ /* IP block use it's own clock divigion register */
+ #define OWN_CLOCK_DIVIDER BIT(0)
+
++#define RPC_DMA_BURST ((DRCR_RBURST_32 + 1) << 3)
++#define RPC_DMA_SIZE_MIN (RPC_DMA_BURST << 3)
++
++static bool use_dma = true;
++module_param(use_dma, bool, 0);
++MODULE_PARM_DESC(use_dma, "DMA support. 0 = Disable, 1 = Enable");
++
+ /* debug */
+ static void __maybe_unused regs_dump(struct rpc_spi *rpc)
+ {
+@@ -282,6 +294,70 @@ static void __maybe_unused regs_dump(struct rpc_spi *rpc)
+ readl(rpc->base + regs[i]));
+ }
+
++static void rpc_dma_complete_func(void *completion)
++{
++ complete(completion);
++}
++
++static int rpc_dma_read(struct rpc_spi *rpc, void *buf,
++ loff_t from, ssize_t *plen)
++{
++ struct dma_device *dma_dev;
++ enum dma_ctrl_flags flags;
++ dma_addr_t dma_dst_addr;
++ struct dma_async_tx_descriptor *tx = NULL;
++ dma_cookie_t cookie;
++ int retval = 0;
++ ssize_t len;
++
++ len = *plen;
++
++ if (!rpc->dma_chan || len < RPC_DMA_SIZE_MIN)
++ return -ENODEV;
++
++ dma_dev = rpc->dma_chan->device;
++
++ /* Align size to RBURST */
++ len -= len % RPC_DMA_BURST;
++
++ dma_dst_addr = dma_map_single(dma_dev->dev, buf, len, DMA_FROM_DEVICE);
++ if (dma_mapping_error(dma_dev->dev, dma_dst_addr)) {
++ dev_err(&rpc->pdev->dev, "Failed to dma_map_single\n");
++ return -ENXIO;
++ }
++
++ flags = DMA_CTRL_ACK | DMA_PREP_INTERRUPT;
++ tx = dma_dev->device_prep_dma_memcpy(rpc->dma_chan, dma_dst_addr,
++ rpc->read_area_dma + from,
++ len, flags);
++ if (!tx) {
++ dev_err(&rpc->pdev->dev, "Failed to prepare DMA memcpy\n");
++ retval = -EIO;
++ goto out_dma;
++ }
++
++ init_completion(&rpc->comp);
++ tx->callback = rpc_dma_complete_func;
++ tx->callback_param = &rpc->comp;
++
++ cookie = tx->tx_submit(tx);
++ retval = dma_submit_error(cookie);
++ if (retval) {
++ dev_err(&rpc->pdev->dev, "Failed to do DMA tx_submit\n");
++ goto out_dma;
++ }
++
++ dma_async_issue_pending(rpc->dma_chan);
++ wait_for_completion(&rpc->comp);
++
++ /* Update length with actual transfer size */
++ *plen = len;
++
++out_dma:
++ dma_unmap_single(dma_dev->dev, dma_dst_addr, len, DMA_FROM_DEVICE);
++ return retval;
++}
++
+ /* register acces */
+ static u32 rpc_read(struct rpc_spi *rpc, unsigned int reg)
+ {
+@@ -430,7 +506,7 @@ static int rpc_setup_ext_mode(struct rpc_spi *rpc)
+ /* ...enable burst and clear cache */
+ val = rpc_read(rpc, DRCR);
+ val &= ~(DRCR_RBURST_MASK | DRCR_RBE | DRCR_SSLE);
+- val |= DRCR_RBURST(0x1f) | DRCR_RBE;
++ val |= DRCR_RBURST(DRCR_RBURST_32) | DRCR_RBE;
+
+ if (cmncr & CMNCR_MD)
+ val |= DRCR_RCF;
+@@ -847,6 +923,8 @@ static ssize_t rpc_read_flash(struct spi_nor *nor, loff_t from, size_t len,
+ rpc_write(rpc, DRENR, val);
+
+ while (len > 0) {
++ int retval;
++
+ /* ...setup address */
+ rpc_setup_extmode_read_addr(rpc, adr_width, from);
+ /* ...use adr [25...0] */
+@@ -855,7 +933,10 @@ static ssize_t rpc_read_flash(struct spi_nor *nor, loff_t from, size_t len,
+ readlen = READ_ADR_MASK - _from + 1;
+ readlen = readlen > len ? len : readlen;
+
+- memcpy_fromio(buf, rpc->read_area + _from, readlen);
++ retval = rpc_dma_read(rpc, buf, _from, &readlen);
++ if (retval)
++ memcpy_fromio(buf, rpc->read_area + _from, readlen);
++
+ buf += readlen;
+ from += readlen;
+ len -= readlen;
+@@ -1157,6 +1238,7 @@ static int rpc_spi_probe(struct platform_device *pdev)
+
+ res = platform_get_resource(pdev, IORESOURCE_MEM, 1);
+
++ rpc->read_area_dma = res->start;
+ rpc->read_area = devm_ioremap_resource(&pdev->dev, res);
+ if (IS_ERR(rpc->base)) {
+ dev_err(&pdev->dev, "cannot get resources\n");
+@@ -1235,10 +1317,23 @@ static int rpc_spi_probe(struct platform_device *pdev)
+ nor->mtd.writebufsize = WRITE_BUF_SIZE;
+ }
+
++ if (use_dma) {
++ dma_cap_mask_t mask;
++
++ dma_cap_zero(mask);
++ dma_cap_set(DMA_MEMCPY, mask);
++ rpc->dma_chan = dma_request_channel(mask, NULL, NULL);
++ if (!rpc->dma_chan)
++ dev_warn(&pdev->dev, "Failed to request DMA channel\n");
++ else
++ dev_info(&pdev->dev, "Using DMA read (%s)\n",
++ dma_chan_name(rpc->dma_chan));
++ }
++
+ ret = mtd_device_register(&nor->mtd, NULL, 0);
+ if (ret) {
+ dev_err(&pdev->dev, "mtd_device_register error.\n");
+- goto error_clk_disable;
++ goto error_dma;
+ }
+
+ dev_info(&pdev->dev, "probed as %s\n",
+@@ -1246,6 +1341,9 @@ static int rpc_spi_probe(struct platform_device *pdev)
+
+ return 0;
+
++error_dma:
++ if (rpc->dma_chan)
++ dma_release_channel(rpc->dma_chan);
+ error_clk_disable:
+ clk_disable_unprepare(rpc->clk);
+ error:
+@@ -1259,6 +1357,8 @@ static int rpc_spi_remove(struct platform_device *pdev)
+ /* HW shutdown */
+ clk_disable_unprepare(rpc->clk);
+ mtd_device_unregister(&rpc->spi_nor.mtd);
++ if (rpc->dma_chan)
++ dma_release_channel(rpc->dma_chan);
+ return 0;
+ }
+
+--
+2.7.4
+
diff --git a/bsp/meta-rcar/meta-rcar-gen3-adas/recipes-kernel/linux/linux-renesas/0377-r8a779-78-dtsi-Add-iccom-nodes.patch b/bsp/meta-rcar/meta-rcar-gen3-adas/recipes-kernel/linux/linux-renesas/0377-r8a779-78-dtsi-Add-iccom-nodes.patch
new file mode 100644
index 00000000..0c13d879
--- /dev/null
+++ b/bsp/meta-rcar/meta-rcar-gen3-adas/recipes-kernel/linux/linux-renesas/0377-r8a779-78-dtsi-Add-iccom-nodes.patch
@@ -0,0 +1,196 @@
+From 92a155910d8ccf5aa72c6e0c8b4307e6f6f08aba Mon Sep 17 00:00:00 2001
+From: Nikita Yushchenko <nikita.yoush@cogentembedded.com>
+Date: Wed, 20 Jun 2018 13:18:02 +0300
+Subject: [PATCH 197/211] r8a779[78]: dtsi: Add iccom nodes
+
+Signed-off-by: Nikita Yushchenko <nikita.yoush@cogentembedded.com>
+---
+ arch/arm64/boot/dts/renesas/r8a77970.dtsi | 80 +++++++++++++++++++++++++++++++
+ arch/arm64/boot/dts/renesas/r8a77980.dtsi | 80 +++++++++++++++++++++++++++++++
+ 2 files changed, 160 insertions(+)
+
+diff --git a/arch/arm64/boot/dts/renesas/r8a77970.dtsi b/arch/arm64/boot/dts/renesas/r8a77970.dtsi
+index 23422c7..08b4a05 100644
+--- a/arch/arm64/boot/dts/renesas/r8a77970.dtsi
++++ b/arch/arm64/boot/dts/renesas/r8a77970.dtsi
+@@ -1268,6 +1268,86 @@
+ compatible = "renesas,prr";
+ reg = <0 0xfff00044 0 4>;
+ };
++
++ iccom0 {
++ compatible = "renesas,iccom-rcar";
++ interrupts = <0 224 4>;
++ reg = <0x0 0xe6260000 0x0 0x1000>;
++ iccom,reg-offset = <0x400 0x404 0x440 0x460>;
++ iccom,cta-memory = <0x0 0x47fc7000 0x0 0x2000>;
++ iccom,ack-timeout = <100>;
++ iccom,trg-timeout = <100>;
++ };
++
++ iccom1 {
++ compatible = "renesas,iccom-rcar";
++ interrupts = <0 225 4>;
++ reg = <0x0 0xe6260000 0x0 0x1000>;
++ iccom,reg-offset = <0x408 0x40c 0x444 0x464>;
++ iccom,cta-memory = <0x0 0x47fc9000 0x0 0x2000>;
++ iccom,ack-timeout = <100>;
++ iccom,trg-timeout = <100>;
++ };
++
++ iccom2 {
++ compatible = "renesas,iccom-rcar";
++ interrupts = <0 226 4>;
++ reg = <0x0 0xe6260000 0x0 0x1000>;
++ iccom,reg-offset = <0x410 0x414 0x448 0x468>;
++ iccom,cta-memory = <0x0 0x47fcb000 0x0 0x2000>;
++ iccom,ack-timeout = <100>;
++ iccom,trg-timeout = <100>;
++ };
++
++ iccom3 {
++ compatible = "renesas,iccom-rcar";
++ interrupts = <0 227 4>;
++ reg = <0x0 0xe6260000 0x0 0x1000>;
++ iccom,reg-offset = <0x418 0x41c 0x44c 0x46c>;
++ iccom,cta-memory = <0x0 0x47fcd000 0x0 0x2000>;
++ iccom,ack-timeout = <100>;
++ iccom,trg-timeout = <100>;
++ };
++
++ iccom4 {
++ compatible = "renesas,iccom-rcar";
++ interrupts = <0 228 4>;
++ reg = <0x0 0xe6260000 0x0 0x1000>;
++ iccom,reg-offset = <0x420 0x424 0x450 0x470>;
++ iccom,cta-memory = <0x0 0x47fcf000 0x0 0x2000>;
++ iccom,ack-timeout = <100>;
++ iccom,trg-timeout = <100>;
++ };
++
++ iccom5 {
++ compatible = "renesas,iccom-rcar";
++ interrupts = <0 229 4>;
++ reg = <0x0 0xe6260000 0x0 0x1000>;
++ iccom,reg-offset = <0x428 0x42c 0x454 0x474>;
++ iccom,cta-memory = <0x0 0x47fd1000 0x0 0x2000>;
++ iccom,ack-timeout = <100>;
++ iccom,trg-timeout = <100>;
++ };
++
++ iccom6 {
++ compatible = "renesas,iccom-rcar";
++ interrupts = <0 230 4>;
++ reg = <0x0 0xe6260000 0x0 0x1000>;
++ iccom,reg-offset = <0x430 0x434 0x458 0x478>;
++ iccom,cta-memory = <0x0 0x47fd3000 0x0 0x2000>;
++ iccom,ack-timeout = <100>;
++ iccom,trg-timeout = <100>;
++ };
++
++ iccom7 {
++ compatible = "renesas,iccom-rcar";
++ interrupts = <0 231 4>;
++ reg = <0x0 0xe6260000 0x0 0x1000>;
++ iccom,reg-offset = <0x438 0x43c 0x45c 0x47c>;
++ iccom,cta-memory = <0x0 0x47fd5000 0x0 0x2000>;
++ iccom,ack-timeout = <100>;
++ iccom,trg-timeout = <100>;
++ };
+ };
+
+ thermal-zones {
+diff --git a/arch/arm64/boot/dts/renesas/r8a77980.dtsi b/arch/arm64/boot/dts/renesas/r8a77980.dtsi
+index 688bc09..f649bbdc 100644
+--- a/arch/arm64/boot/dts/renesas/r8a77980.dtsi
++++ b/arch/arm64/boot/dts/renesas/r8a77980.dtsi
+@@ -1861,6 +1861,86 @@
+ compatible = "renesas,prr";
+ reg = <0 0xfff00044 0 4>;
+ };
++
++ iccom0 {
++ compatible = "renesas,iccom-rcar";
++ interrupts = <0 224 4>;
++ reg = <0x0 0xe6260000 0x0 0x1000>;
++ iccom,reg-offset = <0x400 0x404 0x440 0x460>;
++ iccom,cta-memory = <0x0 0x47fc7000 0x0 0x2000>;
++ iccom,ack-timeout = <100>;
++ iccom,trg-timeout = <100>;
++ };
++
++ iccom1 {
++ compatible = "renesas,iccom-rcar";
++ interrupts = <0 225 4>;
++ reg = <0x0 0xe6260000 0x0 0x1000>;
++ iccom,reg-offset = <0x408 0x40c 0x444 0x464>;
++ iccom,cta-memory = <0x0 0x47fc9000 0x0 0x2000>;
++ iccom,ack-timeout = <100>;
++ iccom,trg-timeout = <100>;
++ };
++
++ iccom2 {
++ compatible = "renesas,iccom-rcar";
++ interrupts = <0 226 4>;
++ reg = <0x0 0xe6260000 0x0 0x1000>;
++ iccom,reg-offset = <0x410 0x414 0x448 0x468>;
++ iccom,cta-memory = <0x0 0x47fcb000 0x0 0x2000>;
++ iccom,ack-timeout = <100>;
++ iccom,trg-timeout = <100>;
++ };
++
++ iccom3 {
++ compatible = "renesas,iccom-rcar";
++ interrupts = <0 227 4>;
++ reg = <0x0 0xe6260000 0x0 0x1000>;
++ iccom,reg-offset = <0x418 0x41c 0x44c 0x46c>;
++ iccom,cta-memory = <0x0 0x47fcd000 0x0 0x2000>;
++ iccom,ack-timeout = <100>;
++ iccom,trg-timeout = <100>;
++ };
++
++ iccom4 {
++ compatible = "renesas,iccom-rcar";
++ interrupts = <0 228 4>;
++ reg = <0x0 0xe6260000 0x0 0x1000>;
++ iccom,reg-offset = <0x420 0x424 0x450 0x470>;
++ iccom,cta-memory = <0x0 0x47fcf000 0x0 0x2000>;
++ iccom,ack-timeout = <100>;
++ iccom,trg-timeout = <100>;
++ };
++
++ iccom5 {
++ compatible = "renesas,iccom-rcar";
++ interrupts = <0 229 4>;
++ reg = <0x0 0xe6260000 0x0 0x1000>;
++ iccom,reg-offset = <0x428 0x42c 0x454 0x474>;
++ iccom,cta-memory = <0x0 0x47fd1000 0x0 0x2000>;
++ iccom,ack-timeout = <100>;
++ iccom,trg-timeout = <100>;
++ };
++
++ iccom6 {
++ compatible = "renesas,iccom-rcar";
++ interrupts = <0 230 4>;
++ reg = <0x0 0xe6260000 0x0 0x1000>;
++ iccom,reg-offset = <0x430 0x434 0x458 0x478>;
++ iccom,cta-memory = <0x0 0x47fd3000 0x0 0x2000>;
++ iccom,ack-timeout = <100>;
++ iccom,trg-timeout = <100>;
++ };
++
++ iccom7 {
++ compatible = "renesas,iccom-rcar";
++ interrupts = <0 231 4>;
++ reg = <0x0 0xe6260000 0x0 0x1000>;
++ iccom,reg-offset = <0x438 0x43c 0x45c 0x47c>;
++ iccom,cta-memory = <0x0 0x47fd5000 0x0 0x2000>;
++ iccom,ack-timeout = <100>;
++ iccom,trg-timeout = <100>;
++ };
+ };
+
+ thermal-zones {
+--
+2.7.4
+
diff --git a/bsp/meta-rcar/meta-rcar-gen3-adas/recipes-kernel/linux/linux-renesas/0378-arm64-dts-renesas-Add-temperature-emergency-levels.patch b/bsp/meta-rcar/meta-rcar-gen3-adas/recipes-kernel/linux/linux-renesas/0378-arm64-dts-renesas-Add-temperature-emergency-levels.patch
new file mode 100644
index 00000000..43646810
--- /dev/null
+++ b/bsp/meta-rcar/meta-rcar-gen3-adas/recipes-kernel/linux/linux-renesas/0378-arm64-dts-renesas-Add-temperature-emergency-levels.patch
@@ -0,0 +1,52 @@
+From 96f731ef74970d67cf8126667149cea09d12dacc Mon Sep 17 00:00:00 2001
+From: Dmitry Shifrin <dmitry.shifrin@cogentembedded.com>
+Date: Sat, 17 Nov 2018 19:02:31 +0300
+Subject: [PATCH 198/211] arm64: dts: renesas: Add temperature emergency levels
+
+Add temperature emergency levels for SoCs r8a77970 and r8a77980
+---
+ arch/arm64/boot/dts/renesas/r8a77970.dtsi | 7 +++++++
+ arch/arm64/boot/dts/renesas/r8a77980.dtsi | 9 +++++++++
+ 2 files changed, 16 insertions(+)
+
+diff --git a/arch/arm64/boot/dts/renesas/r8a77970.dtsi b/arch/arm64/boot/dts/renesas/r8a77970.dtsi
+index 08b4a05..dd0a814 100644
+--- a/arch/arm64/boot/dts/renesas/r8a77970.dtsi
++++ b/arch/arm64/boot/dts/renesas/r8a77970.dtsi
+@@ -1351,6 +1351,13 @@
+ };
+
+ thermal-zones {
++ emergency {
++ polling-delay = <1000>;
++ on-temperature = <110000>;
++ off-temperature = <95000>;
++ target_cpus = <&a53_1>;
++ status = "disabled";
++ };
+ cpu-thermal {
+ polling-delay-passive = <250>;
+ polling-delay = <1000>;
+diff --git a/arch/arm64/boot/dts/renesas/r8a77980.dtsi b/arch/arm64/boot/dts/renesas/r8a77980.dtsi
+index f649bbdc..cdbdebc 100644
+--- a/arch/arm64/boot/dts/renesas/r8a77980.dtsi
++++ b/arch/arm64/boot/dts/renesas/r8a77980.dtsi
+@@ -1944,6 +1944,15 @@
+ };
+
+ thermal-zones {
++ emergency {
++ polling-delay = <1000>;
++ on-temperature = <110000>;
++ off-temperature = <95000>;
++ target_cpus = <&a53_1>,
++ <&a53_2>,
++ <&a53_3>;
++ status = "disabled";
++ };
+ thermal-sensor-1 {
+ polling-delay-passive = <250>;
+ polling-delay = <1000>;
+--
+2.7.4
+
diff --git a/bsp/meta-rcar/meta-rcar-gen3-adas/recipes-kernel/linux/linux-renesas/0379-r8a77980-dts-Add-vbm-v3-on-r8a77980-SoC.patch b/bsp/meta-rcar/meta-rcar-gen3-adas/recipes-kernel/linux/linux-renesas/0379-r8a77980-dts-Add-vbm-v3-on-r8a77980-SoC.patch
new file mode 100644
index 00000000..dd27a6e6
--- /dev/null
+++ b/bsp/meta-rcar/meta-rcar-gen3-adas/recipes-kernel/linux/linux-renesas/0379-r8a77980-dts-Add-vbm-v3-on-r8a77980-SoC.patch
@@ -0,0 +1,70 @@
+From 9a278cdb4fe860d80fe95f576f685c78ec7a4113 Mon Sep 17 00:00:00 2001
+From: Roman Meshkevich <roman.meshkevich@cogentembedded.com>
+Date: Mon, 19 Nov 2018 13:27:06 +0300
+Subject: [PATCH 199/211] r8a77980: dts: Add vbm-v3 on r8a77980 SoC.
+
+---
+ arch/arm64/boot/dts/renesas/Makefile | 1 +
+ .../boot/dts/renesas/r8a77980-v3hsk-vbm-v3.dts | 38 ++++++++++++++++++++++
+ 2 files changed, 39 insertions(+)
+ create mode 100644 arch/arm64/boot/dts/renesas/r8a77980-v3hsk-vbm-v3.dts
+
+diff --git a/arch/arm64/boot/dts/renesas/Makefile b/arch/arm64/boot/dts/renesas/Makefile
+index 4ccf641..563e390 100644
+--- a/arch/arm64/boot/dts/renesas/Makefile
++++ b/arch/arm64/boot/dts/renesas/Makefile
+@@ -44,6 +44,7 @@ dtb-$(CONFIG_ARCH_R8A77970) += r8a77970-v3msk-vbm-v3.dtb r8a77970-es1-v3msk-vbm-
+ dtb-$(CONFIG_ARCH_R8A77970) += r8a77970-v3mzf.dtb
+ dtb-$(CONFIG_ARCH_R8A77980) += r8a77980-v3hsk-vbm.dtb
+ dtb-$(CONFIG_ARCH_R8A77980) += r8a77980-v3hsk-vbm-v2.dtb
++dtb-$(CONFIG_ARCH_R8A77980) += r8a77980-v3hsk-vbm-v3.dtb
+ dtb-$(CONFIG_ARCH_R8A77980) += r8a77980-v3hsk-vb-8ch.dtb r8a77980-v3hsk-vb-4ch.dtb
+
+ always := $(dtb-y)
+diff --git a/arch/arm64/boot/dts/renesas/r8a77980-v3hsk-vbm-v3.dts b/arch/arm64/boot/dts/renesas/r8a77980-v3hsk-vbm-v3.dts
+new file mode 100644
+index 0000000..32a1805
+--- /dev/null
++++ b/arch/arm64/boot/dts/renesas/r8a77980-v3hsk-vbm-v3.dts
+@@ -0,0 +1,38 @@
++/*
++ * Device Tree Source for the V3MSK Videobox Mini board V3 on r8a7797
++ *
++ * Copyright (C) 2018 Cogent Embedded, Inc.
++ *
++ * This file is licensed under the terms of the GNU General Public License
++ * version 2. This program is licensed "as is" without any warranty of any
++ * kind, whether express or implied.
++ */
++
++#include "r8a77980-v3hsk-vbm-v2.dts"
++
++
++/ {
++ model = "Renesas V3HSK Videobox Mini board V3 based on r8a7798";
++};
++
++&gpio0 {
++ can0_load {
++ gpio-hog;
++ gpios = <19 GPIO_ACTIVE_HIGH>;
++ output-low;
++ line-name = "can0_120R_load";
++ };
++};
++
++&gpio1 {
++ ex_v3m {
++ gpio-hog;
++ gpios = <19 GPIO_ACTIVE_HIGH>;
++ output-high;
++ line-name = "ExV3M";
++ };
++};
++
++&gpio2 {
++ /delete-node/can0_load;
++};
+--
+2.7.4
+
diff --git a/bsp/meta-rcar/meta-rcar-gen3-adas/recipes-kernel/linux/linux-renesas/0380-arm64-dts-r8a77970-Enable-TMU-and-CMT.patch b/bsp/meta-rcar/meta-rcar-gen3-adas/recipes-kernel/linux/linux-renesas/0380-arm64-dts-r8a77970-Enable-TMU-and-CMT.patch
new file mode 100644
index 00000000..8a0fa92a
--- /dev/null
+++ b/bsp/meta-rcar/meta-rcar-gen3-adas/recipes-kernel/linux/linux-renesas/0380-arm64-dts-r8a77970-Enable-TMU-and-CMT.patch
@@ -0,0 +1,101 @@
+From 6ad86a46afeebe56b69cd5618d416dff58d34168 Mon Sep 17 00:00:00 2001
+From: Dmitry Shifrin <dmitry.shifrin@cogentembedded.com>
+Date: Fri, 16 Nov 2018 13:13:38 +0300
+Subject: [PATCH 200/211] arm64: dts: r8a77970: Enable TMU and CMT
+
+---
+ arch/arm64/boot/dts/renesas/r8a77970-eagle.dts | 36 ++++++++++++++++++++++++++
+ arch/arm64/boot/dts/renesas/r8a77970-v3msk.dts | 36 ++++++++++++++++++++++++++
+ 2 files changed, 72 insertions(+)
+
+diff --git a/arch/arm64/boot/dts/renesas/r8a77970-eagle.dts b/arch/arm64/boot/dts/renesas/r8a77970-eagle.dts
+index 7d93834..642efc7 100644
+--- a/arch/arm64/boot/dts/renesas/r8a77970-eagle.dts
++++ b/arch/arm64/boot/dts/renesas/r8a77970-eagle.dts
+@@ -624,3 +624,39 @@
+ };
+ };
+ };
++
++&tmu0 {
++ status = "okay";
++};
++
++&tmu1 {
++ status = "okay";
++};
++
++&tmu2 {
++ status = "okay";
++};
++
++&tmu3 {
++ status = "okay";
++};
++
++&tmu4 {
++ status = "okay";
++};
++
++&cmt0 {
++ status = "okay";
++};
++
++&cmt1 {
++ status = "okay";
++};
++
++&cmt2 {
++ status = "okay";
++};
++
++&cmt3 {
++ status = "okay";
++};
+diff --git a/arch/arm64/boot/dts/renesas/r8a77970-v3msk.dts b/arch/arm64/boot/dts/renesas/r8a77970-v3msk.dts
+index ef9a2c5..107d041 100644
+--- a/arch/arm64/boot/dts/renesas/r8a77970-v3msk.dts
++++ b/arch/arm64/boot/dts/renesas/r8a77970-v3msk.dts
+@@ -332,3 +332,39 @@
+
+ status = "okay";
+ };
++
++&tmu0 {
++ status = "okay";
++};
++
++&tmu1 {
++ status = "okay";
++};
++
++&tmu2 {
++ status = "okay";
++};
++
++&tmu3 {
++ status = "okay";
++};
++
++&tmu4 {
++ status = "okay";
++};
++
++&cmt0 {
++ status = "okay";
++};
++
++&cmt1 {
++ status = "okay";
++};
++
++&cmt2 {
++ status = "okay";
++};
++
++&cmt3 {
++ status = "okay";
++};
+--
+2.7.4
+
diff --git a/bsp/meta-rcar/meta-rcar-gen3-adas/recipes-kernel/linux/linux-renesas/0381-arm64-dts-r8a77980-Enable-TMU-and-CMT.patch b/bsp/meta-rcar/meta-rcar-gen3-adas/recipes-kernel/linux/linux-renesas/0381-arm64-dts-r8a77980-Enable-TMU-and-CMT.patch
new file mode 100644
index 00000000..b09ab317
--- /dev/null
+++ b/bsp/meta-rcar/meta-rcar-gen3-adas/recipes-kernel/linux/linux-renesas/0381-arm64-dts-r8a77980-Enable-TMU-and-CMT.patch
@@ -0,0 +1,101 @@
+From 6255d98e794cabafdfd3683bdfadb7468e5251d1 Mon Sep 17 00:00:00 2001
+From: Andrey Dolnikov <andrey.dolnikov@cogentembedded.com>
+Date: Mon, 19 Nov 2018 18:59:08 +0300
+Subject: [PATCH 201/211] arm64: dts: r8a77980: Enable TMU and CMT
+
+---
+ arch/arm64/boot/dts/renesas/r8a77980-condor.dts | 36 +++++++++++++++++++++++++
+ arch/arm64/boot/dts/renesas/r8a77980-v3hsk.dts | 36 +++++++++++++++++++++++++
+ 2 files changed, 72 insertions(+)
+
+diff --git a/arch/arm64/boot/dts/renesas/r8a77980-condor.dts b/arch/arm64/boot/dts/renesas/r8a77980-condor.dts
+index 6b5f574..45e4ada 100644
+--- a/arch/arm64/boot/dts/renesas/r8a77980-condor.dts
++++ b/arch/arm64/boot/dts/renesas/r8a77980-condor.dts
+@@ -951,3 +951,39 @@
+ };
+ };
+ };
++
++&tmu0 {
++ status = "okay";
++};
++
++&tmu1 {
++ status = "okay";
++};
++
++&tmu2 {
++ status = "okay";
++};
++
++&tmu3 {
++ status = "okay";
++};
++
++&tmu4 {
++ status = "okay";
++};
++
++&cmt0 {
++ status = "okay";
++};
++
++&cmt1 {
++ status = "okay";
++};
++
++&cmt2 {
++ status = "okay";
++};
++
++&cmt3 {
++ status = "okay";
++};
+diff --git a/arch/arm64/boot/dts/renesas/r8a77980-v3hsk.dts b/arch/arm64/boot/dts/renesas/r8a77980-v3hsk.dts
+index cfbfd98..7a07120 100644
+--- a/arch/arm64/boot/dts/renesas/r8a77980-v3hsk.dts
++++ b/arch/arm64/boot/dts/renesas/r8a77980-v3hsk.dts
+@@ -354,3 +354,39 @@
+ non-removable;
+ status = "okay";
+ };
++
++&tmu0 {
++ status = "okay";
++};
++
++&tmu1 {
++ status = "okay";
++};
++
++&tmu2 {
++ status = "okay";
++};
++
++&tmu3 {
++ status = "okay";
++};
++
++&tmu4 {
++ status = "okay";
++};
++
++&cmt0 {
++ status = "okay";
++};
++
++&cmt1 {
++ status = "okay";
++};
++
++&cmt2 {
++ status = "okay";
++};
++
++&cmt3 {
++ status = "okay";
++};
+--
+2.7.4
+
diff --git a/bsp/meta-rcar/meta-rcar-gen3-adas/recipes-kernel/linux/linux-renesas/0382-arm64-dts-renesas-r8a77970-and-r8a77980-Add-QoS-node.patch b/bsp/meta-rcar/meta-rcar-gen3-adas/recipes-kernel/linux/linux-renesas/0382-arm64-dts-renesas-r8a77970-and-r8a77980-Add-QoS-node.patch
new file mode 100644
index 00000000..cc9f9925
--- /dev/null
+++ b/bsp/meta-rcar/meta-rcar-gen3-adas/recipes-kernel/linux/linux-renesas/0382-arm64-dts-renesas-r8a77970-and-r8a77980-Add-QoS-node.patch
@@ -0,0 +1,46 @@
+From 5afe6a9d9e087dee62d593c09e71da800b5f6e88 Mon Sep 17 00:00:00 2001
+From: Andrey Dolnikov <andrey.dolnikov@cogentembedded.com>
+Date: Wed, 21 Nov 2018 15:22:45 +0300
+Subject: [PATCH 202/211] arm64: dts: renesas: r8a77970 and r8a77980: Add QoS
+ nodes
+
+---
+ arch/arm64/boot/dts/renesas/r8a77970.dtsi | 5 +++++
+ arch/arm64/boot/dts/renesas/r8a77980.dtsi | 5 +++++
+ 2 files changed, 10 insertions(+)
+
+diff --git a/arch/arm64/boot/dts/renesas/r8a77970.dtsi b/arch/arm64/boot/dts/renesas/r8a77970.dtsi
+index dd0a814..be793ff 100644
+--- a/arch/arm64/boot/dts/renesas/r8a77970.dtsi
++++ b/arch/arm64/boot/dts/renesas/r8a77970.dtsi
+@@ -1348,6 +1348,11 @@
+ iccom,ack-timeout = <100>;
+ iccom,trg-timeout = <100>;
+ };
++
++ qos@e67e0000 {
++ compatible = "renesas,qos";
++ reg = <0 0xe67e0000 0 0x10090>;
++ };
+ };
+
+ thermal-zones {
+diff --git a/arch/arm64/boot/dts/renesas/r8a77980.dtsi b/arch/arm64/boot/dts/renesas/r8a77980.dtsi
+index cdbdebc..045b517 100644
+--- a/arch/arm64/boot/dts/renesas/r8a77980.dtsi
++++ b/arch/arm64/boot/dts/renesas/r8a77980.dtsi
+@@ -1941,6 +1941,11 @@
+ iccom,ack-timeout = <100>;
+ iccom,trg-timeout = <100>;
+ };
++
++ qos@e67e0000 {
++ compatible = "renesas,qos";
++ reg = <0 0xe67e0000 0 0x10090>;
++ };
+ };
+
+ thermal-zones {
+--
+2.7.4
+
diff --git a/bsp/meta-rcar/meta-rcar-gen3-adas/recipes-kernel/linux/linux-renesas/0383-clk-renesas-r8a77970-cpg-mssr-Add-sadc-clock.patch b/bsp/meta-rcar/meta-rcar-gen3-adas/recipes-kernel/linux/linux-renesas/0383-clk-renesas-r8a77970-cpg-mssr-Add-sadc-clock.patch
new file mode 100644
index 00000000..0a9f94b4
--- /dev/null
+++ b/bsp/meta-rcar/meta-rcar-gen3-adas/recipes-kernel/linux/linux-renesas/0383-clk-renesas-r8a77970-cpg-mssr-Add-sadc-clock.patch
@@ -0,0 +1,26 @@
+From 76384a2aa1e57174bfa97a2d01b588c49a8cce80 Mon Sep 17 00:00:00 2001
+From: Andrey Gusakov <andrey.gusakov@cogentembedded.com>
+Date: Tue, 10 Jul 2018 15:28:03 +0300
+Subject: [PATCH 203/211] clk: renesas: r8a77970: cpg-mssr: Add sadc clock
+
+Signed-off-by: Andrey Gusakov <andrey.gusakov@cogentembedded.com>
+Signed-off-by: Valentine Barshak <valentine.barshak@cogentembedded.com>
+---
+ drivers/clk/renesas/r8a77970-cpg-mssr.c | 1 +
+ 1 file changed, 1 insertion(+)
+
+diff --git a/drivers/clk/renesas/r8a77970-cpg-mssr.c b/drivers/clk/renesas/r8a77970-cpg-mssr.c
+index 1e3f6f8..dc70a36 100644
+--- a/drivers/clk/renesas/r8a77970-cpg-mssr.c
++++ b/drivers/clk/renesas/r8a77970-cpg-mssr.c
+@@ -137,6 +137,7 @@ static const struct mssr_mod_clk r8a77970_mod_clks[] __initconst = {
+ DEF_MOD("rwdt", 402, R8A77970_CLK_R),
+ DEF_MOD("intc-ex", 407, R8A77970_CLK_CP),
+ DEF_MOD("intc-ap", 408, R8A77970_CLK_S2D1),
++ DEF_MOD("sadc", 503, R8A77970_CLK_S2D1), /* @@ H3=S3D1 */
+ DEF_MOD("hscif3", 517, R8A77970_CLK_S2D1),
+ DEF_MOD("hscif2", 518, R8A77970_CLK_S2D1),
+ DEF_MOD("hscif1", 519, R8A77970_CLK_S2D1),
+--
+2.7.4
+
diff --git a/bsp/meta-rcar/meta-rcar-gen3-adas/recipes-kernel/linux/linux-renesas/0384-arm64-dts-renesas-r8a77970-Add-sadc-node.patch b/bsp/meta-rcar/meta-rcar-gen3-adas/recipes-kernel/linux/linux-renesas/0384-arm64-dts-renesas-r8a77970-Add-sadc-node.patch
new file mode 100644
index 00000000..62629ba7
--- /dev/null
+++ b/bsp/meta-rcar/meta-rcar-gen3-adas/recipes-kernel/linux/linux-renesas/0384-arm64-dts-renesas-r8a77970-Add-sadc-node.patch
@@ -0,0 +1,37 @@
+From 25e00c6c4bd5be1ba742b0d75b7e02f052489d38 Mon Sep 17 00:00:00 2001
+From: Andrey Gusakov <andrey.gusakov@cogentembedded.com>
+Date: Tue, 10 Jul 2018 15:27:33 +0300
+Subject: [PATCH 204/211] arm64: dts: renesas: r8a77970: Add sadc node
+
+Signed-off-by: Andrey Gusakov <andrey.gusakov@cogentembedded.com>
+Signed-off-by: Valentine Barshak <valentine.barshak@cogentembedded.com>
+---
+ arch/arm64/boot/dts/renesas/r8a77970.dtsi | 12 ++++++++++++
+ 1 file changed, 12 insertions(+)
+
+diff --git a/arch/arm64/boot/dts/renesas/r8a77970.dtsi b/arch/arm64/boot/dts/renesas/r8a77970.dtsi
+index be793ff..7ecbc01 100644
+--- a/arch/arm64/boot/dts/renesas/r8a77970.dtsi
++++ b/arch/arm64/boot/dts/renesas/r8a77970.dtsi
+@@ -1053,6 +1053,18 @@
+ power-domains = <&sysc R8A77970_PD_ALWAYS_ON>;
+ };
+
++ sadc0: adc@ffce0000 {
++ compatible = "renesas,sadc-r8a77970";
++ reg = <0 0xffce0000 0 0x10000>;
++ interrupts = <GIC_SPI 295 IRQ_TYPE_LEVEL_HIGH>;
++ clocks = <&cpg CPG_CORE R8A77970_CLK_S2D4>,
++ <&cpg CPG_CORE R8A77970_CLK_S2D2>,
++ <&cpg CPG_MOD 503>; /* RMSTPCR5/bit3:ADC */
++ clock-names = "phy_clk", "ip_clk", "adc";
++ power-domains = <&sysc R8A77970_PD_ALWAYS_ON>;
++ status = "disabled";
++ };
++
+ dmac1: dma-controller@e7300000 {
+ compatible = "renesas,dmac-r8a77970",
+ "renesas,rcar-dmac";
+--
+2.7.4
+
diff --git a/bsp/meta-rcar/meta-rcar-gen3-adas/recipes-kernel/linux/linux-renesas/0385-iio-adc-Add-R-Car-SADC-driver.patch b/bsp/meta-rcar/meta-rcar-gen3-adas/recipes-kernel/linux/linux-renesas/0385-iio-adc-Add-R-Car-SADC-driver.patch
new file mode 100644
index 00000000..0ed90c24
--- /dev/null
+++ b/bsp/meta-rcar/meta-rcar-gen3-adas/recipes-kernel/linux/linux-renesas/0385-iio-adc-Add-R-Car-SADC-driver.patch
@@ -0,0 +1,456 @@
+From 7793b9dcbfd9795853b27f758b93f18e1c90a9c5 Mon Sep 17 00:00:00 2001
+From: Andrey Gusakov <andrey.gusakov@cogentembedded.com>
+Date: Tue, 10 Jul 2018 15:25:58 +0300
+Subject: [PATCH 205/211] iio: adc: Add R-Car SADC driver
+
+Signed-off-by: Andrey Gusakov <andrey.gusakov@cogentembedded.com>
+Signed-off-by: Valentine Barshak <valentine.barshak@cogentembedded.com>
+---
+ drivers/iio/adc/Kconfig | 11 ++
+ drivers/iio/adc/Makefile | 1 +
+ drivers/iio/adc/rcar-sadc.c | 399 ++++++++++++++++++++++++++++++++++++++++++++
+ 3 files changed, 411 insertions(+)
+ create mode 100644 drivers/iio/adc/rcar-sadc.c
+
+diff --git a/drivers/iio/adc/Kconfig b/drivers/iio/adc/Kconfig
+index 369a2c6..a715cdc 100644
+--- a/drivers/iio/adc/Kconfig
++++ b/drivers/iio/adc/Kconfig
+@@ -607,6 +607,17 @@ config RCAR_GYRO_ADC
+ To compile this driver as a module, choose M here: the
+ module will be called rcar-gyroadc.
+
++config RCAR_SADC
++ tristate "Renesas R-Car SADC driver"
++ depends on ARCH_R8A77970
++ depends on OF
++ depends on HAS_IOMEM
++ select IIO_BUFFER
++ select IIO_TRIGGERED_BUFFER
++ help
++ Say yes here to build support for the SADC found in SoCs from
++ Renesas (currently V3M has this ADC).
++
+ config ROCKCHIP_SARADC
+ tristate "Rockchip SARADC driver"
+ depends on ARCH_ROCKCHIP || (ARM && COMPILE_TEST)
+diff --git a/drivers/iio/adc/Makefile b/drivers/iio/adc/Makefile
+index 9572c10..6ee0f32 100644
+--- a/drivers/iio/adc/Makefile
++++ b/drivers/iio/adc/Makefile
+@@ -58,6 +58,7 @@ obj-$(CONFIG_QCOM_VADC_COMMON) += qcom-vadc-common.o
+ obj-$(CONFIG_QCOM_SPMI_VADC) += qcom-spmi-vadc.o
+ obj-$(CONFIG_QCOM_PM8XXX_XOADC) += qcom-pm8xxx-xoadc.o
+ obj-$(CONFIG_RCAR_GYRO_ADC) += rcar-gyroadc.o
++obj-$(CONFIG_RCAR_SADC) += rcar-sadc.o
+ obj-$(CONFIG_ROCKCHIP_SARADC) += rockchip_saradc.o
+ obj-$(CONFIG_SPEAR_ADC) += spear_adc.o
+ obj-$(CONFIG_STX104) += stx104.o
+diff --git a/drivers/iio/adc/rcar-sadc.c b/drivers/iio/adc/rcar-sadc.c
+new file mode 100644
+index 0000000..724ea21
+--- /dev/null
++++ b/drivers/iio/adc/rcar-sadc.c
+@@ -0,0 +1,399 @@
++/*
++ * Renesas R-Car 3 ADC
++ *
++ * Copyright 2018 CogentEmbedded, Inc.
++ *
++ * based on linux/drivers/iio/vf610_adc.c
++ * Copyright 2013 Freescale Semiconductor, Inc.
++ *
++ * This program is free software; you can redistribute it and/or modify
++ * it under the terms of the GNU General Public License as published by
++ * the Free Software Foundation; either version 2 of the License, or
++ * (at your option) any later version.
++ *
++ * This program is distributed in the hope that it will be useful,
++ * but WITHOUT ANY WARRANTY; without even the implied warranty of
++ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
++ * GNU General Public License for more details.
++ */
++
++#include <linux/module.h>
++#include <linux/platform_device.h>
++#include <linux/interrupt.h>
++#include <linux/delay.h>
++#include <linux/kernel.h>
++#include <linux/slab.h>
++#include <linux/io.h>
++#include <linux/clk.h>
++#include <linux/completion.h>
++#include <linux/of.h>
++#include <linux/of_irq.h>
++#include <linux/regulator/consumer.h>
++#include <linux/of_platform.h>
++#include <linux/err.h>
++
++#include <linux/iio/iio.h>
++#include <linux/iio/buffer.h>
++#include <linux/iio/sysfs.h>
++#include <linux/iio/trigger.h>
++#include <linux/iio/trigger_consumer.h>
++#include <linux/iio/triggered_buffer.h>
++
++/* This will be the driver name the kernel reports */
++#define DRIVER_NAME "rcar-sadc"
++
++#define RCAR_ADPHYS 0x00
++#define RCAR_ADFLAG 0x04
++#define RCAR_ADEMSK 0x08
++#define RCAR_ADECLR 0x0c
++#define RCAR_ADFIFOEN 0x10
++#define RCAR_ADFIFORST 0x14
++#define RCAR_ADFIFOSTS 0x18
++#define RCAR_ADFIFORC 0x1c
++#define RCAR_ADCHSELP 0x20
++#define RCAR_ADMON(x) (0x24 + 0x4 * (x))
++#define ADMONSET(x) (0x4c + 0x4 * (x))
++#define RCAR_ADCTRANS(x) (0x74 + 0x4 * (x))
++#define RCAR_ADCLASTREG 0x98
++
++#define RCAR_ALL_CHANS 0x3ff
++
++#define RCAR_ADC_TIMEOUT msecs_to_jiffies(100)
++
++struct rcar_adc {
++ struct device *dev;
++ void __iomem *regs;
++ struct clk *clk;
++
++ u32 vref_uv;
++ struct regulator *vref;
++
++ struct completion completion;
++};
++
++static int rcar_chan_to_idx(int ch)
++{
++ /* regular channels starts from 1 */
++ if ((ch >= 0) && (ch <= 7))
++ return ch + 1;
++ else if (ch == 8)
++ return 0; /* VDD1 */
++ else
++ return 9; /* VDD2 */
++}
++
++static void rcar_adc_hw_init(struct rcar_adc *info)
++{
++ uint32_t reg;
++
++ /* ADCHSELP register should be set 32'H0000 0030 before measuring */
++ writel(0x30, info->regs + RCAR_ADCHSELP);
++ /* reset all fifo */
++ writel(RCAR_ALL_CHANS, info->regs + RCAR_ADFIFORST);
++ /* enable all channels */
++ writel(RCAR_ALL_CHANS, info->regs + RCAR_ADFIFOEN);
++ /* AD FIFO read command register */
++ writel(RCAR_ALL_CHANS, info->regs + RCAR_ADFIFORC);
++
++ reg = readl(info->regs + RCAR_ADPHYS);
++ writel(reg | (1 << 28) | (1 << 24), info->regs + RCAR_ADPHYS);
++}
++
++#define RCAR_ADC_CHAN(_idx, _chan_type) { \
++ .type = (_chan_type), \
++ .indexed = 1, \
++ .channel = (_idx), \
++ .info_mask_separate = BIT(IIO_CHAN_INFO_RAW), \
++ .info_mask_shared_by_type = BIT(IIO_CHAN_INFO_SCALE), \
++ .scan_index = (_idx), \
++ .scan_type = { \
++ .sign = 'u', \
++ .realbits = 12, \
++ .storagebits = 16, \
++ }, \
++}
++
++static const struct iio_chan_spec rcar_adc_iio_channels[] = {
++ /* external */
++ RCAR_ADC_CHAN(0, IIO_VOLTAGE),
++ RCAR_ADC_CHAN(1, IIO_VOLTAGE),
++ RCAR_ADC_CHAN(2, IIO_VOLTAGE),
++ RCAR_ADC_CHAN(3, IIO_VOLTAGE),
++ RCAR_ADC_CHAN(4, IIO_VOLTAGE),
++ RCAR_ADC_CHAN(5, IIO_VOLTAGE),
++ RCAR_ADC_CHAN(6, IIO_VOLTAGE),
++ RCAR_ADC_CHAN(7, IIO_VOLTAGE),
++ /* internal */
++ RCAR_ADC_CHAN(8, IIO_VOLTAGE), /* VDD1 */
++ RCAR_ADC_CHAN(9, IIO_VOLTAGE), /* VDD2 */
++ /* sentinel */
++};
++
++static irqreturn_t rcar_adc_isr(int irq, void *dev_id)
++{
++ struct iio_dev *indio_dev = (struct iio_dev *)dev_id;
++ struct rcar_adc *info = iio_priv(indio_dev);
++
++ writel(RCAR_ALL_CHANS, info->regs + RCAR_ADECLR);
++
++ return IRQ_HANDLED;
++}
++
++static int rcar_adc_read_raw(struct iio_dev *indio_dev,
++ struct iio_chan_spec const *chan,
++ int *val,
++ int *val2,
++ long mask)
++{
++ u32 value;
++ struct rcar_adc *info = iio_priv(indio_dev);
++
++ switch (mask) {
++ case IIO_CHAN_INFO_RAW:
++ case IIO_CHAN_INFO_PROCESSED:
++ value = readl(info->regs +
++ RCAR_ADMON(rcar_chan_to_idx(chan->channel)))
++ & 0x0fff;
++ switch (chan->type) {
++ case IIO_VOLTAGE:
++ *val = value;
++ break;
++ default:
++ return -EINVAL;
++ }
++
++ return IIO_VAL_INT;
++
++ case IIO_CHAN_INFO_SCALE:
++ *val = info->vref_uv / 1000;
++ *val2 = 12; /* 12 bit mode */
++ return IIO_VAL_FRACTIONAL_LOG2;
++
++ default:
++ break;
++ }
++
++ return -EINVAL;
++}
++
++static int rcar_adc_buffer_postenable(struct iio_dev *indio_dev)
++{
++ return 0;
++}
++
++static int rcar_adc_buffer_predisable(struct iio_dev *indio_dev)
++{
++ return iio_triggered_buffer_predisable(indio_dev);
++}
++
++static const struct iio_buffer_setup_ops iio_triggered_buffer_setup_ops = {
++ .postenable = &rcar_adc_buffer_postenable,
++ .predisable = &rcar_adc_buffer_predisable,
++ .validate_scan_mask = &iio_validate_scan_mask_onehot,
++};
++
++static int rcar_adc_reg_access(struct iio_dev *indio_dev,
++ unsigned reg, unsigned writeval,
++ unsigned *readval)
++{
++ struct rcar_adc *info = iio_priv(indio_dev);
++
++ if ((readval == NULL) ||
++ ((reg % 4) || (reg > RCAR_ADCLASTREG)))
++ return -EINVAL;
++
++ *readval = readl(info->regs + reg);
++
++ return 0;
++}
++
++static const struct iio_info rcar_adc_iio_info = {
++ .driver_module = THIS_MODULE,
++ .read_raw = &rcar_adc_read_raw,
++ .debugfs_reg_access = &rcar_adc_reg_access,
++};
++
++static const struct of_device_id rcar_adc_match[] = {
++ { .compatible = "renesas,sadc-r8a77970", },
++ { /* sentinel */ }
++};
++MODULE_DEVICE_TABLE(of, rcar_adc_match);
++
++static int rcar_adc_probe(struct platform_device *pdev)
++{
++ struct rcar_adc *info;
++ struct iio_dev *indio_dev;
++ struct resource *mem;
++ int irq;
++ int ret;
++
++ indio_dev = devm_iio_device_alloc(&pdev->dev, sizeof(struct rcar_adc));
++ if (!indio_dev) {
++ dev_err(&pdev->dev, "Failed allocating iio device\n");
++ return -ENOMEM;
++ }
++
++ info = iio_priv(indio_dev);
++ info->dev = &pdev->dev;
++
++ mem = platform_get_resource(pdev, IORESOURCE_MEM, 0);
++ info->regs = devm_ioremap_resource(&pdev->dev, mem);
++ if (IS_ERR(info->regs))
++ return PTR_ERR(info->regs);
++
++ irq = platform_get_irq(pdev, 0);
++ if (irq < 0) {
++ dev_err(&pdev->dev, "no irq resource?\n");
++ return irq;
++ }
++
++ ret = devm_request_irq(info->dev, irq,
++ rcar_adc_isr, 0,
++ dev_name(&pdev->dev), indio_dev);
++ if (ret < 0) {
++ dev_err(&pdev->dev, "failed requesting irq: %d\n", irq);
++ return ret;
++ }
++
++ info->clk = devm_clk_get(&pdev->dev, "adc");
++ if (IS_ERR(info->clk)) {
++ dev_err(&pdev->dev, "failed getting clock: %ld\n",
++ PTR_ERR(info->clk));
++ return PTR_ERR(info->clk);
++ }
++
++ info->vref = devm_regulator_get(&pdev->dev, "vref");
++ if (IS_ERR(info->vref)) {
++ dev_err(&pdev->dev, "failed getting regulator: %ld\n",
++ PTR_ERR(info->vref));
++ return PTR_ERR(info->vref);
++ }
++
++ ret = regulator_enable(info->vref);
++ if (ret) {
++ dev_err(&pdev->dev, "failed enabling regulator: %d\n",
++ ret);
++ return ret;
++ }
++
++ ret = regulator_get_voltage(info->vref);
++ if (ret <= 0) {
++ dev_err(&pdev->dev, "failed getting regulator voltage: %d\n",
++ ret);
++ return ret;
++ }
++ info->vref_uv = ret;
++
++ platform_set_drvdata(pdev, indio_dev);
++
++ init_completion(&info->completion);
++
++ indio_dev->name = dev_name(&pdev->dev);
++ indio_dev->dev.parent = &pdev->dev;
++ indio_dev->dev.of_node = pdev->dev.of_node;
++ indio_dev->info = &rcar_adc_iio_info;
++ indio_dev->modes = INDIO_DIRECT_MODE;
++ indio_dev->channels = rcar_adc_iio_channels;
++ indio_dev->num_channels = ARRAY_SIZE(rcar_adc_iio_channels);
++
++ ret = clk_prepare_enable(info->clk);
++ if (ret) {
++ dev_err(&pdev->dev,
++ "Could not prepare or enable the clock: %d\n",
++ ret);
++ goto error_adc_clk_enable;
++ }
++
++ rcar_adc_hw_init(info);
++
++ ret = iio_triggered_buffer_setup(indio_dev, &iio_pollfunc_store_time,
++ NULL, &iio_triggered_buffer_setup_ops);
++ if (ret < 0) {
++ dev_err(&pdev->dev, "Couldn't initialise the buffer\n");
++ goto error_iio_device_register;
++ }
++
++ ret = iio_device_register(indio_dev);
++ if (ret) {
++ dev_err(&pdev->dev, "Couldn't register the device.\n");
++ goto error_adc_buffer_init;
++ }
++
++ return 0;
++
++error_adc_buffer_init:
++ iio_triggered_buffer_cleanup(indio_dev);
++error_iio_device_register:
++ clk_disable_unprepare(info->clk);
++error_adc_clk_enable:
++ regulator_disable(info->vref);
++
++ return ret;
++}
++
++static int rcar_adc_remove(struct platform_device *pdev)
++{
++ struct iio_dev *indio_dev = platform_get_drvdata(pdev);
++ struct rcar_adc *info = iio_priv(indio_dev);
++
++ iio_device_unregister(indio_dev);
++ iio_triggered_buffer_cleanup(indio_dev);
++ regulator_disable(info->vref);
++ clk_disable_unprepare(info->clk);
++
++ return 0;
++}
++
++#ifdef CONFIG_PM_SLEEP
++static int rcar_adc_suspend(struct device *dev)
++{
++ struct iio_dev *indio_dev = dev_get_drvdata(dev);
++ struct rcar_adc *info = iio_priv(indio_dev);
++
++ clk_disable_unprepare(info->clk);
++ regulator_disable(info->vref);
++
++ return 0;
++}
++
++static int rcar_adc_resume(struct device *dev)
++{
++ struct iio_dev *indio_dev = dev_get_drvdata(dev);
++ struct rcar_adc *info = iio_priv(indio_dev);
++ int ret;
++
++ ret = regulator_enable(info->vref);
++ if (ret)
++ return ret;
++
++ ret = clk_prepare_enable(info->clk);
++ if (ret)
++ goto disable_reg;
++
++ rcar_adc_hw_init(info);
++
++ return 0;
++
++disable_reg:
++ regulator_disable(info->vref);
++ return ret;
++}
++#endif
++
++static SIMPLE_DEV_PM_OPS(rcar_adc_pm_ops, rcar_adc_suspend, rcar_adc_resume);
++
++static struct platform_driver rcar_adc_driver = {
++ .probe = rcar_adc_probe,
++ .remove = rcar_adc_remove,
++ .driver = {
++ .name = DRIVER_NAME,
++ .of_match_table = rcar_adc_match,
++ .pm = &rcar_adc_pm_ops,
++ },
++};
++
++module_platform_driver(rcar_adc_driver);
++
++MODULE_AUTHOR("Andrey Gusakov <andrey.gusakov@cogentembedded.com>");
++MODULE_DESCRIPTION("Renesas R-Car V3M SADC driver");
++MODULE_LICENSE("GPL v2");
+--
+2.7.4
+
diff --git a/bsp/meta-rcar/meta-rcar-gen3-adas/recipes-kernel/linux/linux-renesas/0386-rcar-vin-add-ISP-source-enable.patch b/bsp/meta-rcar/meta-rcar-gen3-adas/recipes-kernel/linux/linux-renesas/0386-rcar-vin-add-ISP-source-enable.patch
new file mode 100644
index 00000000..0d334bfa
--- /dev/null
+++ b/bsp/meta-rcar/meta-rcar-gen3-adas/recipes-kernel/linux/linux-renesas/0386-rcar-vin-add-ISP-source-enable.patch
@@ -0,0 +1,66 @@
+From 0c86a96a5d552d5f7ddd9004b4639821ab2c3083 Mon Sep 17 00:00:00 2001
+From: Vladimir Barinov <vladimir.barinov@cogentembedded.com>
+Date: Tue, 18 Dec 2018 14:34:58 +0300
+Subject: [PATCH 206/211] rcar-vin: add ISP source enable
+
+This adds possbility to use ISP as a source for VIN8-VIN15
+on V3H
+
+Signed-off-by: Vladimir Barinov <vladimir.barinov@cogentembedded.com>
+---
+ drivers/media/platform/soc_camera/rcar_vin.c | 11 +++++++++++
+ 1 file changed, 11 insertions(+)
+
+diff --git a/drivers/media/platform/soc_camera/rcar_vin.c b/drivers/media/platform/soc_camera/rcar_vin.c
+index 6ba94c3..bcc1cfd 100644
+--- a/drivers/media/platform/soc_camera/rcar_vin.c
++++ b/drivers/media/platform/soc_camera/rcar_vin.c
+@@ -102,6 +102,7 @@
+
+ /* Register bit fields for R-Car VIN */
+ /* Video n Main Control Register bits */
++#define VNMC_ISPE (1 << 30)
+ #define VNMC_DPINE (1 << 27)
+ #define VNMC_SCLE (1 << 26)
+ #define VNMC_FOC (1 << 21)
+@@ -188,6 +189,7 @@
+ #define RCAR_VIN_BT601 (1 << 2)
+ #define RCAR_VIN_BT656 (1 << 3)
+ #define RCAR_VIN_CSI2 (1 << 4)
++#define RCAR_VIN_ISP (1 << 5)
+
+ static int lut_reverse;
+ module_param(lut_reverse, int, 0644);
+@@ -1238,6 +1240,9 @@ static int rcar_vin_setup(struct rcar_vin_priv *priv)
+ vnmc |= VNMC_SCLE;
+ }
+
++ if (priv->pdata_flags & RCAR_VIN_ISP)
++ vnmc |= VNMC_ISPE;
++
+ /* progressive or interlaced mode */
+ interrupts = progressive ? VNIE_FIE : VNIE_EFE;
+
+@@ -2042,6 +2047,9 @@ static int rcar_vin_set_bus_param(struct soc_camera_device *icd)
+ vnmc |= VNMC_DPINE;
+ }
+
++ if (priv->pdata_flags & RCAR_VIN_ISP)
++ vnmc |= VNMC_ISPE;
++
+ if (priv->chip == RCAR_H3 || priv->chip == RCAR_M3 ||
+ priv->chip == RCAR_M3N || priv->chip == RCAR_V3M ||
+ priv->chip == RCAR_V3H)
+@@ -3124,6 +3132,9 @@ static int rcar_vin_probe(struct platform_device *pdev)
+
+ of_node_put(np);
+
++ if (of_property_read_bool(np, "isp,enable"))
++ pdata_flags = RCAR_VIN_ISP;
++
+ dev_dbg(&pdev->dev, "pdata_flags = %08x\n", pdata_flags);
+
+ mem = platform_get_resource(pdev, IORESOURCE_MEM, 0);
+--
+2.7.4
+
diff --git a/bsp/meta-rcar/meta-rcar-gen3-adas/recipes-kernel/linux/linux-renesas/0387-media-soc_camera-Add-events-support.patch b/bsp/meta-rcar/meta-rcar-gen3-adas/recipes-kernel/linux/linux-renesas/0387-media-soc_camera-Add-events-support.patch
new file mode 100644
index 00000000..bb2ab7de
--- /dev/null
+++ b/bsp/meta-rcar/meta-rcar-gen3-adas/recipes-kernel/linux/linux-renesas/0387-media-soc_camera-Add-events-support.patch
@@ -0,0 +1,426 @@
+From 6e47c1eba7112dfcd5f7c07103a99e1e09a150bd Mon Sep 17 00:00:00 2001
+From: Andrey Dolnikov <andrey.dolnikov@cogentembedded.com>
+Date: Thu, 17 Jan 2019 17:48:53 +0300
+Subject: [PATCH 207/211] media: soc_camera: Add events support
+
+---
+ drivers/media/platform/soc_camera/rcar_isp.c | 2 +-
+ drivers/media/platform/soc_camera/rcar_vin.c | 2 +-
+ .../platform/soc_camera/sh_mobile_ceu_camera.c | 2 +-
+ drivers/media/platform/soc_camera/soc_camera.c | 88 ++++++++++++++--------
+ include/media/soc_camera.h | 4 +
+ 5 files changed, 65 insertions(+), 33 deletions(-)
+
+diff --git a/drivers/media/platform/soc_camera/rcar_isp.c b/drivers/media/platform/soc_camera/rcar_isp.c
+index 1127c7d..e7c2801 100644
+--- a/drivers/media/platform/soc_camera/rcar_isp.c
++++ b/drivers/media/platform/soc_camera/rcar_isp.c
+@@ -1549,7 +1549,7 @@ static int rcar_isp_try_fmt(struct soc_camera_device *icd,
+
+ static unsigned int rcar_isp_poll(struct file *file, poll_table *pt)
+ {
+- struct soc_camera_device *icd = file->private_data;
++ struct soc_camera_device *icd = video_drvdata(file);
+
+ return vb2_poll(&icd->vb2_vidq, file, pt);
+ }
+diff --git a/drivers/media/platform/soc_camera/rcar_vin.c b/drivers/media/platform/soc_camera/rcar_vin.c
+index bcc1cfd..9051590 100644
+--- a/drivers/media/platform/soc_camera/rcar_vin.c
++++ b/drivers/media/platform/soc_camera/rcar_vin.c
+@@ -2723,7 +2723,7 @@ static int rcar_vin_try_fmt(struct soc_camera_device *icd,
+
+ static unsigned int rcar_vin_poll(struct file *file, poll_table *pt)
+ {
+- struct soc_camera_device *icd = file->private_data;
++ struct soc_camera_device *icd = video_drvdata(file);
+
+ return vb2_poll(&icd->vb2_vidq, file, pt);
+ }
+diff --git a/drivers/media/platform/soc_camera/sh_mobile_ceu_camera.c b/drivers/media/platform/soc_camera/sh_mobile_ceu_camera.c
+index 9180a1d..564d7e8 100644
+--- a/drivers/media/platform/soc_camera/sh_mobile_ceu_camera.c
++++ b/drivers/media/platform/soc_camera/sh_mobile_ceu_camera.c
+@@ -1560,7 +1560,7 @@ static int sh_mobile_ceu_set_liveselection(struct soc_camera_device *icd,
+
+ static unsigned int sh_mobile_ceu_poll(struct file *file, poll_table *pt)
+ {
+- struct soc_camera_device *icd = file->private_data;
++ struct soc_camera_device *icd = video_drvdata(file);
+
+ return vb2_poll(&icd->vb2_vidq, file, pt);
+ }
+diff --git a/drivers/media/platform/soc_camera/soc_camera.c b/drivers/media/platform/soc_camera/soc_camera.c
+index cd2a135..7e5ca15 100644
+--- a/drivers/media/platform/soc_camera/soc_camera.c
++++ b/drivers/media/platform/soc_camera/soc_camera.c
+@@ -289,7 +289,7 @@ static int soc_camera_try_fmt(struct soc_camera_device *icd,
+ static int soc_camera_try_fmt_vid_cap(struct file *file, void *priv,
+ struct v4l2_format *f)
+ {
+- struct soc_camera_device *icd = file->private_data;
++ struct soc_camera_device *icd = video_drvdata(file);
+
+ WARN_ON(priv != file->private_data);
+
+@@ -304,7 +304,7 @@ static int soc_camera_try_fmt_vid_cap(struct file *file, void *priv,
+ static int soc_camera_enum_input(struct file *file, void *priv,
+ struct v4l2_input *inp)
+ {
+- struct soc_camera_device *icd = file->private_data;
++ struct soc_camera_device *icd = video_drvdata(file);
+
+ if (inp->index != 0)
+ return -EINVAL;
+@@ -334,7 +334,7 @@ static int soc_camera_s_input(struct file *file, void *priv, unsigned int i)
+
+ static int soc_camera_s_std(struct file *file, void *priv, v4l2_std_id a)
+ {
+- struct soc_camera_device *icd = file->private_data;
++ struct soc_camera_device *icd = video_drvdata(file);
+ struct v4l2_subdev *sd = soc_camera_to_subdev(icd);
+
+ return v4l2_subdev_call(sd, video, s_std, a);
+@@ -342,7 +342,7 @@ static int soc_camera_s_std(struct file *file, void *priv, v4l2_std_id a)
+
+ static int soc_camera_g_std(struct file *file, void *priv, v4l2_std_id *a)
+ {
+- struct soc_camera_device *icd = file->private_data;
++ struct soc_camera_device *icd = video_drvdata(file);
+ struct v4l2_subdev *sd = soc_camera_to_subdev(icd);
+
+ return v4l2_subdev_call(sd, video, g_std, a);
+@@ -351,7 +351,7 @@ static int soc_camera_g_std(struct file *file, void *priv, v4l2_std_id *a)
+ static int soc_camera_enum_framesizes(struct file *file, void *fh,
+ struct v4l2_frmsizeenum *fsize)
+ {
+- struct soc_camera_device *icd = file->private_data;
++ struct soc_camera_device *icd = video_drvdata(file);
+ struct soc_camera_host *ici = to_soc_camera_host(icd->parent);
+
+ return ici->ops->enum_framesizes(icd, fsize);
+@@ -361,7 +361,7 @@ static int soc_camera_reqbufs(struct file *file, void *priv,
+ struct v4l2_requestbuffers *p)
+ {
+ int ret;
+- struct soc_camera_device *icd = file->private_data;
++ struct soc_camera_device *icd = video_drvdata(file);
+
+ WARN_ON(priv != file->private_data);
+
+@@ -377,7 +377,7 @@ static int soc_camera_reqbufs(struct file *file, void *priv,
+ static int soc_camera_querybuf(struct file *file, void *priv,
+ struct v4l2_buffer *p)
+ {
+- struct soc_camera_device *icd = file->private_data;
++ struct soc_camera_device *icd = video_drvdata(file);
+
+ WARN_ON(priv != file->private_data);
+
+@@ -387,7 +387,7 @@ static int soc_camera_querybuf(struct file *file, void *priv,
+ static int soc_camera_qbuf(struct file *file, void *priv,
+ struct v4l2_buffer *p)
+ {
+- struct soc_camera_device *icd = file->private_data;
++ struct soc_camera_device *icd = video_drvdata(file);
+
+ WARN_ON(priv != file->private_data);
+
+@@ -400,7 +400,7 @@ static int soc_camera_qbuf(struct file *file, void *priv,
+ static int soc_camera_dqbuf(struct file *file, void *priv,
+ struct v4l2_buffer *p)
+ {
+- struct soc_camera_device *icd = file->private_data;
++ struct soc_camera_device *icd = video_drvdata(file);
+
+ WARN_ON(priv != file->private_data);
+
+@@ -413,7 +413,7 @@ static int soc_camera_dqbuf(struct file *file, void *priv,
+ static int soc_camera_create_bufs(struct file *file, void *priv,
+ struct v4l2_create_buffers *create)
+ {
+- struct soc_camera_device *icd = file->private_data;
++ struct soc_camera_device *icd = video_drvdata(file);
+ int ret;
+
+ if (icd->streamer && icd->streamer != file)
+@@ -428,7 +428,7 @@ static int soc_camera_create_bufs(struct file *file, void *priv,
+ static int soc_camera_prepare_buf(struct file *file, void *priv,
+ struct v4l2_buffer *b)
+ {
+- struct soc_camera_device *icd = file->private_data;
++ struct soc_camera_device *icd = video_drvdata(file);
+
+ return vb2_prepare_buf(&icd->vb2_vidq, b);
+ }
+@@ -436,7 +436,7 @@ static int soc_camera_prepare_buf(struct file *file, void *priv,
+ static int soc_camera_expbuf(struct file *file, void *priv,
+ struct v4l2_exportbuffer *p)
+ {
+- struct soc_camera_device *icd = file->private_data;
++ struct soc_camera_device *icd = video_drvdata(file);
+
+ if (icd->streamer && icd->streamer != file)
+ return -EBUSY;
+@@ -632,6 +632,7 @@ static int soc_camera_open(struct file *file)
+ return -ENODEV;
+ }
+
++ v4l2_fh_open(file);
+ icd = video_get_drvdata(vdev);
+ ici = to_soc_camera_host(icd->parent);
+
+@@ -708,7 +709,6 @@ static int soc_camera_open(struct file *file)
+ }
+ mutex_unlock(&ici->host_lock);
+
+- file->private_data = icd;
+ dev_dbg(icd->pdev, "camera device open\n");
+
+ return 0;
+@@ -736,14 +736,19 @@ static int soc_camera_open(struct file *file)
+
+ static int soc_camera_close(struct file *file)
+ {
+- struct soc_camera_device *icd = file->private_data;
++ struct soc_camera_device *icd = video_drvdata(file);
+ struct soc_camera_host *ici = to_soc_camera_host(icd->parent);
++ struct v4l2_event ev;
+
+ mutex_lock(&ici->host_lock);
+ if (icd->streamer == file) {
+ if (ici->ops->init_videobuf2)
+ vb2_queue_release(&icd->vb2_vidq);
+ icd->streamer = NULL;
++
++ memset(&ev, 0, sizeof(ev));
++ ev.type = V4L2_EVENT_EOS;
++ v4l2_event_queue(icd->vdev, &ev);
+ }
+ icd->use_count--;
+ if (!icd->use_count) {
+@@ -755,6 +760,8 @@ static int soc_camera_close(struct file *file)
+ soc_camera_remove_device(icd);
+ }
+
++ v4l2_fh_release(file);
++
+ mutex_unlock(&ici->host_lock);
+
+ module_put(ici->ops->owner);
+@@ -767,7 +774,7 @@ static int soc_camera_close(struct file *file)
+ static ssize_t soc_camera_read(struct file *file, char __user *buf,
+ size_t count, loff_t *ppos)
+ {
+- struct soc_camera_device *icd = file->private_data;
++ struct soc_camera_device *icd = video_drvdata(file);
+ struct soc_camera_host *ici = to_soc_camera_host(icd->parent);
+
+ dev_dbg(icd->pdev, "read called, buf %p\n", buf);
+@@ -783,7 +790,7 @@ static ssize_t soc_camera_read(struct file *file, char __user *buf,
+
+ static int soc_camera_mmap(struct file *file, struct vm_area_struct *vma)
+ {
+- struct soc_camera_device *icd = file->private_data;
++ struct soc_camera_device *icd = video_drvdata(file);
+ struct soc_camera_host *ici = to_soc_camera_host(icd->parent);
+ int err;
+
+@@ -807,12 +814,14 @@ static int soc_camera_mmap(struct file *file, struct vm_area_struct *vma)
+
+ static unsigned int soc_camera_poll(struct file *file, poll_table *pt)
+ {
+- struct soc_camera_device *icd = file->private_data;
++ struct soc_camera_device *icd = video_drvdata(file);
+ struct soc_camera_host *ici = to_soc_camera_host(icd->parent);
+ unsigned res = POLLERR;
+
++/*
+ if (icd->streamer != file)
+ return POLLERR;
++*/
+
+ mutex_lock(&ici->host_lock);
+ res = ici->ops->poll(file, pt);
+@@ -833,7 +842,7 @@ static const struct v4l2_file_operations soc_camera_fops = {
+ static int soc_camera_s_fmt_vid_cap(struct file *file, void *priv,
+ struct v4l2_format *f)
+ {
+- struct soc_camera_device *icd = file->private_data;
++ struct soc_camera_device *icd = video_drvdata(file);
+ int ret;
+
+ WARN_ON(priv != file->private_data);
+@@ -862,7 +871,7 @@ static int soc_camera_s_fmt_vid_cap(struct file *file, void *priv,
+ static int soc_camera_enum_fmt_vid_cap(struct file *file, void *priv,
+ struct v4l2_fmtdesc *f)
+ {
+- struct soc_camera_device *icd = file->private_data;
++ struct soc_camera_device *icd = video_drvdata(file);
+ const struct soc_mbus_pixelfmt *format;
+
+ WARN_ON(priv != file->private_data);
+@@ -881,7 +890,7 @@ static int soc_camera_enum_fmt_vid_cap(struct file *file, void *priv,
+ static int soc_camera_g_fmt_vid_cap(struct file *file, void *priv,
+ struct v4l2_format *f)
+ {
+- struct soc_camera_device *icd = file->private_data;
++ struct soc_camera_device *icd = video_drvdata(file);
+ struct v4l2_pix_format *pix = &f->fmt.pix;
+
+ WARN_ON(priv != file->private_data);
+@@ -904,7 +913,7 @@ static int soc_camera_g_fmt_vid_cap(struct file *file, void *priv,
+ static int soc_camera_querycap(struct file *file, void *priv,
+ struct v4l2_capability *cap)
+ {
+- struct soc_camera_device *icd = file->private_data;
++ struct soc_camera_device *icd = video_drvdata(file);
+ struct soc_camera_host *ici = to_soc_camera_host(icd->parent);
+
+ WARN_ON(priv != file->private_data);
+@@ -916,8 +925,9 @@ static int soc_camera_querycap(struct file *file, void *priv,
+ static int soc_camera_streamon(struct file *file, void *priv,
+ enum v4l2_buf_type i)
+ {
+- struct soc_camera_device *icd = file->private_data;
++ struct soc_camera_device *icd = video_drvdata(file);
+ struct v4l2_subdev *sd = soc_camera_to_subdev(icd);
++ struct v4l2_event ev;
+ int ret;
+
+ WARN_ON(priv != file->private_data);
+@@ -933,14 +943,19 @@ static int soc_camera_streamon(struct file *file, void *priv,
+ if (!ret)
+ v4l2_subdev_call(sd, video, s_stream, 1);
+
++ memset(&ev, 0, sizeof(ev));
++ ev.type = V4L2_EVENT_SOC_START_STREAM;
++ v4l2_event_queue(icd->vdev, &ev);
++
+ return ret;
+ }
+
+ static int soc_camera_streamoff(struct file *file, void *priv,
+ enum v4l2_buf_type i)
+ {
+- struct soc_camera_device *icd = file->private_data;
++ struct soc_camera_device *icd = video_drvdata(file);
+ struct v4l2_subdev *sd = soc_camera_to_subdev(icd);
++ struct v4l2_event ev;
+ int ret;
+
+ WARN_ON(priv != file->private_data);
+@@ -959,13 +974,17 @@ static int soc_camera_streamoff(struct file *file, void *priv,
+
+ v4l2_subdev_call(sd, video, s_stream, 0);
+
++ memset(&ev, 0, sizeof(ev));
++ ev.type = V4L2_EVENT_EOS;
++ v4l2_event_queue(icd->vdev, &ev);
++
+ return ret;
+ }
+
+ static int soc_camera_g_selection(struct file *file, void *fh,
+ struct v4l2_selection *s)
+ {
+- struct soc_camera_device *icd = file->private_data;
++ struct soc_camera_device *icd = video_drvdata(file);
+ struct soc_camera_host *ici = to_soc_camera_host(icd->parent);
+
+ /* With a wrong type no need to try to fall back to cropping */
+@@ -978,7 +997,7 @@ static int soc_camera_g_selection(struct file *file, void *fh,
+ static int soc_camera_s_selection(struct file *file, void *fh,
+ struct v4l2_selection *s)
+ {
+- struct soc_camera_device *icd = file->private_data;
++ struct soc_camera_device *icd = video_drvdata(file);
+ struct soc_camera_host *ici = to_soc_camera_host(icd->parent);
+ int ret;
+
+@@ -1023,7 +1042,7 @@ static int soc_camera_s_selection(struct file *file, void *fh,
+ static int soc_camera_g_parm(struct file *file, void *fh,
+ struct v4l2_streamparm *a)
+ {
+- struct soc_camera_device *icd = file->private_data;
++ struct soc_camera_device *icd = video_drvdata(file);
+ struct soc_camera_host *ici = to_soc_camera_host(icd->parent);
+
+ if (ici->ops->get_parm)
+@@ -1035,7 +1054,7 @@ static int soc_camera_g_parm(struct file *file, void *fh,
+ static int soc_camera_s_parm(struct file *file, void *fh,
+ struct v4l2_streamparm *a)
+ {
+- struct soc_camera_device *icd = file->private_data;
++ struct soc_camera_device *icd = video_drvdata(file);
+ struct soc_camera_host *ici = to_soc_camera_host(icd->parent);
+
+ if (ici->ops->set_parm)
+@@ -1047,7 +1066,7 @@ static int soc_camera_s_parm(struct file *file, void *fh,
+ static int soc_camera_g_edid(struct file *file, void *fh,
+ struct v4l2_edid *edid)
+ {
+- struct soc_camera_device *icd = file->private_data;
++ struct soc_camera_device *icd = video_drvdata(file);
+ struct soc_camera_host *ici = to_soc_camera_host(icd->parent);
+
+ if (ici->ops->get_edid)
+@@ -1060,7 +1079,7 @@ static int soc_camera_g_edid(struct file *file, void *fh,
+ static int soc_camera_g_register(struct file *file, void *priv,
+ struct v4l2_dbg_register *reg)
+ {
+- struct soc_camera_device *icd = file->private_data;
++ struct soc_camera_device *icd = video_drvdata(file);
+ struct soc_camera_host *ici = to_soc_camera_host(icd->parent);
+
+ if (ici->ops->get_register)
+@@ -1072,7 +1091,7 @@ static int soc_camera_g_register(struct file *file, void *priv,
+ static int soc_camera_s_register(struct file *file, void *priv,
+ const struct v4l2_dbg_register *reg)
+ {
+- struct soc_camera_device *icd = file->private_data;
++ struct soc_camera_device *icd = video_drvdata(file);
+ struct soc_camera_host *ici = to_soc_camera_host(icd->parent);
+
+ if (ici->ops->set_register)
+@@ -2040,6 +2059,13 @@ static int soc_camera_device_register(struct soc_camera_device *icd)
+ return 0;
+ }
+
++static int soc_camera_subscribe_event(struct v4l2_fh *fh,
++ const struct v4l2_event_subscription *sub)
++{
++ /* Just subscribe any event */
++ return v4l2_event_subscribe(fh, sub, 16, NULL);
++}
++
+ static const struct v4l2_ioctl_ops soc_camera_ioctl_ops = {
+ .vidioc_querycap = soc_camera_querycap,
+ .vidioc_try_fmt_vid_cap = soc_camera_try_fmt_vid_cap,
+@@ -2070,6 +2096,8 @@ static const struct v4l2_ioctl_ops soc_camera_ioctl_ops = {
+ .vidioc_g_register = soc_camera_g_register,
+ .vidioc_s_register = soc_camera_s_register,
+ #endif
++ .vidioc_subscribe_event = soc_camera_subscribe_event,
++ .vidioc_unsubscribe_event = v4l2_event_unsubscribe,
+ };
+
+ static int video_dev_create(struct soc_camera_device *icd)
+diff --git a/include/media/soc_camera.h b/include/media/soc_camera.h
+index 2e44f96..53c650d 100644
+--- a/include/media/soc_camera.h
++++ b/include/media/soc_camera.h
+@@ -21,6 +21,10 @@
+ #include <media/v4l2-async.h>
+ #include <media/v4l2-ctrls.h>
+ #include <media/v4l2-device.h>
++#include <media/v4l2-event.h>
++
++#define V4L2_EVENT_SOC_START_STREAM (V4L2_EVENT_PRIVATE_START + 1)
++#define V4L2_EVENT_SOC_PRIVATE_START (V4L2_EVENT_PRIVATE_START + 1)
+
+ struct file;
+ struct soc_camera_desc;
+--
+2.7.4
+
diff --git a/bsp/meta-rcar/meta-rcar-gen3-adas/recipes-kernel/linux/linux-renesas/0388-media-rcar-imr-Add-stride-support-to-IMR.patch b/bsp/meta-rcar/meta-rcar-gen3-adas/recipes-kernel/linux/linux-renesas/0388-media-rcar-imr-Add-stride-support-to-IMR.patch
new file mode 100644
index 00000000..ba522ddb
--- /dev/null
+++ b/bsp/meta-rcar/meta-rcar-gen3-adas/recipes-kernel/linux/linux-renesas/0388-media-rcar-imr-Add-stride-support-to-IMR.patch
@@ -0,0 +1,216 @@
+From 48485fd8cc4049745e286d8a4d3617327e5551e8 Mon Sep 17 00:00:00 2001
+From: Konstantin Kozhevnikov <Konstantin.Kozhevnikov@cogentembedded.com>
+Date: Wed, 23 Jan 2019 08:07:38 -0800
+Subject: [PATCH 208/211] media: rcar-imr: Add stride support to IMR
+
+Add stride support to IMR
+
+Signed-off-by: Konstantin Kozhevnikov <Konstantin.Kozhevnikov@cogentembedded.com>
+---
+ drivers/media/platform/rcar_imr.c | 96 ++++++++++++++++++++++++++++++---------
+ 1 file changed, 74 insertions(+), 22 deletions(-)
+
+diff --git a/drivers/media/platform/rcar_imr.c b/drivers/media/platform/rcar_imr.c
+index cdd847c..cb982b8 100644
+--- a/drivers/media/platform/rcar_imr.c
++++ b/drivers/media/platform/rcar_imr.c
+@@ -418,28 +418,33 @@ static int imr_queue_setup(struct vb2_queue *vq,
+ {
+ struct imr_ctx *ctx = vb2_get_drv_priv(vq);
+ struct imr_q_data *q_data = &ctx->queue[V4L2_TYPE_IS_OUTPUT(vq->type) ? 0 : 1];
+- int w = q_data->fmt.width;
++ int s = q_data->fmt.bytesperline;
+ int h = q_data->fmt.height;
+
+ /* ...we use only single-plane formats */
+ *nplanes = 1;
+
++ v4l2_dbg(1, debug, &ctx->imr->v4l2_dev, "format: %c%c%c%c, s=%d, h=%d\n",
++ (q_data->fmt.pixelformat >> 0) & 0xff, (q_data->fmt.pixelformat >> 8) & 0xff,
++ (q_data->fmt.pixelformat >> 16) & 0xff, (q_data->fmt.pixelformat >> 24) & 0xff,
++ s, h);
++
+ /* ...specify plane size */
+ switch (q_data->fmt.pixelformat) {
+ case V4L2_PIX_FMT_UYVY:
+ case V4L2_PIX_FMT_YUYV:
+ case V4L2_PIX_FMT_VYUY:
+ case V4L2_PIX_FMT_YVYU:
+- case V4L2_PIX_FMT_NV16:
+ case V4L2_PIX_FMT_Y10:
+ case V4L2_PIX_FMT_Y12:
+ case V4L2_PIX_FMT_Y16:
+- sizes[0] = w * h * 2;
+- break;
+-
+ case V4L2_PIX_FMT_UV8:
+ case V4L2_PIX_FMT_GREY:
+- sizes[0] = w * h;
++ sizes[0] = s * h;
++ break;
++
++ case V4L2_PIX_FMT_NV16:
++ sizes[0] = s * h * 2;
+ break;
+
+ default:
+@@ -782,8 +787,10 @@ static inline void imr_dl_program_setup(struct imr_ctx *ctx, struct imr_cfg *cfg
+ u16 dst_uv_fmt = (cflags & IMR_F_UV12 ? 2 : (cflags & IMR_F_UV10 ? 1 : 0)) << IMR_CMR_DUV_SHIFT;
+ int w = ctx->queue[0].fmt.width;
+ int h = ctx->queue[0].fmt.height;
++ int s = ctx->queue[0].fmt.bytesperline;
+ int W = ctx->queue[1].fmt.width;
+ int H = ctx->queue[1].fmt.height;
++ int S = ctx->queue[1].fmt.bytesperline;
+ u32 tricr = ctx->color & 0xFFFFFF;
+ int i;
+
+@@ -856,15 +863,15 @@ static inline void imr_dl_program_setup(struct imr_ctx *ctx, struct imr_cfg *cfg
+ *dl++ = IMR_OP_WTS(IMR_CMRCSR, src_y_fmt | src_uv_fmt | dst_y_fmt | dst_uv_fmt | __imr_luce(type) | __imr_clce(type));
+
+ /* ...set source/destination strides basing on Y-plane precision */
+- *dl++ = IMR_OP_WTS(IMR_DSTR, W << (cflags & IMR_F_Y10 ? 1 : 0));
+- *dl++ = IMR_OP_WTS(IMR_SSTR, w << (iflags & IMR_F_Y10 ? 1 : 0));
++ *dl++ = IMR_OP_WTS(IMR_DSTR, S);
++ *dl++ = IMR_OP_WTS(IMR_SSTR, s);
+ } else {
+ /* ...setup UV-plane processing only */
+ *dl++ = IMR_OP_WTS(IMR_CMRCSR, IMR_CMR_YCM | src_uv_fmt | dst_uv_fmt | __imr_clce(type) | __imr_luce(type));
+
+ /* ...set source/destination strides basing on UV-plane precision */
+- *dl++ = IMR_OP_WTS(IMR_DSTR, W << (cflags & IMR_F_UV10 ? 1 : 0));
+- *dl++ = IMR_OP_WTS(IMR_SSTR, w << (iflags & IMR_F_UV10 ? 1 : 0));
++ *dl++ = IMR_OP_WTS(IMR_DSTR, S);
++ *dl++ = IMR_OP_WTS(IMR_SSTR, s);
+ }
+ } else {
+ u16 src_fmt = (iflags & IMR_F_UV_SWAP ? IMR_CMR2_UVFORM : 0) | (iflags & IMR_F_YUV_SWAP ? IMR_CMR2_YUV422FORM : 0);
+@@ -879,19 +886,22 @@ static inline void imr_dl_program_setup(struct imr_ctx *ctx, struct imr_cfg *cfg
+ *dl++ = IMR_OP_WTS(IMR_CMRCSR, src_y_fmt | src_uv_fmt | dst_y_fmt | dst_uv_fmt | __imr_clce(type) | __imr_luce(type));
+
+ /* ...set source stride basing on precision (2 or 4 bytes/pixel) */
+- *dl++ = IMR_OP_WTS(IMR_SSTR, w << (iflags & IMR_F_Y10 ? 2 : 1));
++ *dl++ = IMR_OP_WTS(IMR_SSTR, s/* << (iflags & IMR_F_Y10 ? 2 : 1)*/);
+
+ /* ...if output is planar, put the offset value */
+ if (oflags & IMR_F_PLANAR) {
+ /* ...specify offset of a destination UV plane */
+ *dl++ = IMR_OP_WTL(IMR_DSOR, 1);
+- *dl++ = W * H;
++ *dl++ = S * H;
++
++ /* ...force planar output */
++ *dl++ = IMR_OP_WTS(IMR_CMRCSR, IMR_CMR_YISM);
+
+ /* ...destination stride is 1 or 2 bytes/pixel (same for both Y and UV planes) */
+- *dl++ = IMR_OP_WTS(IMR_DSTR, W << (cflags & IMR_F_Y10 ? 1 : 0));
++ *dl++ = IMR_OP_WTS(IMR_DSTR, S);
+ } else {
+ /* ...destination stride if 2 or 4 bytes/pixel (Y and UV planes interleaved) */
+- *dl++ = IMR_OP_WTS(IMR_DSTR, W << (cflags & IMR_F_Y10 ? 2 : 1));
++ *dl++ = IMR_OP_WTS(IMR_DSTR, S);
+ }
+ }
+
+@@ -921,9 +931,6 @@ static inline void imr_dl_program_setup(struct imr_ctx *ctx, struct imr_cfg *cfg
+ /* ...select correction mode */
+ *dl++ = IMR_OP_WTS(IMR_CMRCSR, IMR_CMR_YCM | __imr_clce(type) | __imr_luce(type));
+
+- /* ...luminance correction bit must be cleared (if it was set) */
+- //*dl++ = IMR_OP_WTS(IMR_CMRCCR, IMR_CMR_LUCE);
+-
+ /* ...draw triangles */
+ *dl++ = IMR_OP_GOSUB;
+ *dl++ = subaddr;
+@@ -1226,6 +1233,43 @@ static int imr_extstride_set(struct imr_ctx *ctx, struct imr_rse_param *param)
+ * V4L2 I/O controls
+ ******************************************************************************/
+
++/* ...check the format stride */
++static inline int __imr_verify_fmt_stride(struct v4l2_pix_format *pix)
++{
++ int stride;
++
++ switch (pix->pixelformat) {
++ case V4L2_PIX_FMT_NV16:
++ case V4L2_PIX_FMT_GREY:
++ case V4L2_PIX_FMT_UV8:
++ /* ...single byte per pixel */
++ stride = pix->width;
++ break;
++
++ case V4L2_PIX_FMT_UYVY:
++ case V4L2_PIX_FMT_VYUY:
++ case V4L2_PIX_FMT_YUYV:
++ case V4L2_PIX_FMT_YVYU:
++ case V4L2_PIX_FMT_Y10:
++ case V4L2_PIX_FMT_Y12:
++ /* ...two bytes per pixel */
++ stride = pix->width * 2;
++ break;
++
++ default:
++ /* ...unsupported format */
++ return -1;
++ }
++
++ if (pix->bytesperline)
++ return (pix->bytesperline >= stride ? 0 : -1);
++
++ /* ...no stride is specified; use default one */
++ pix->bytesperline = stride;
++
++ return 0;
++}
++
+ /* ...test for a format supported */
+ static int __imr_try_fmt(struct imr_ctx *ctx, struct v4l2_format *f)
+ {
+@@ -1233,22 +1277,30 @@ static int __imr_try_fmt(struct imr_ctx *ctx, struct v4l2_format *f)
+ u32 fourcc = pix->pixelformat;
+ int i;
+
++ /* ...fix-up format stride if needed */
++ if (__imr_verify_fmt_stride(pix) < 0)
++ return -EINVAL;
++
+ /* ...both output and capture interface have the same set of supported formats */
+ for (i = 0; i < ARRAY_SIZE(imr_lx4_formats); i++) {
+ if (fourcc == imr_lx4_formats[i].fourcc) {
+ /* ...fix-up format specification as needed */
+ pix->field = V4L2_FIELD_NONE;
+
+- v4l2_dbg(1, debug, &ctx->imr->v4l2_dev, "format request: '%c%c%c%c', %d*%d\n",
++ v4l2_dbg(1, debug, &ctx->imr->v4l2_dev, "%s-format request: '%c%c%c%c', %d*%d\n",
++ (V4L2_TYPE_IS_OUTPUT(f->type) ? "output" : "capture"),
+ (fourcc >> 0) & 0xff, (fourcc >> 8) & 0xff,
+ (fourcc >> 16) & 0xff, (fourcc >> 24) & 0xff,
+ pix->width, pix->height);
+
+ /* ...verify source/destination image dimensions */
+ if (V4L2_TYPE_IS_OUTPUT(f->type))
+- v4l_bound_align_image(&pix->width, 128, 2048, 7, &pix->height, 1, 2048, 0, 0);
++ v4l_bound_align_image(&pix->bytesperline, 256, 8192, 8, &pix->height, 1, 2048, 0, 0);
+ else
+- v4l_bound_align_image(&pix->width, 64, 2048, 6, &pix->height, 1, 2048, 0, 0);
++ v4l_bound_align_image(&pix->bytesperline, 64, 8192, 6, &pix->height, 1, 2048, 0, 0);
++
++ /* ...verify width is not exceeding the maximal value */
++ (pix->width > 2048 ? pix->width = 2048 : 0);
+
+ return i;
+ }
+@@ -1751,8 +1803,8 @@ static void imr_device_run(void *priv)
+
+ /* ...adjust source/destination parameters of the UV-plane as needed */
+ if (cfg->src_pa_ptr[1] && cfg->dst_pa_ptr[1]) {
+- *cfg->src_pa_ptr[1] = src_addr + ctx->queue[0].fmt.width * ctx->queue[0].fmt.height;
+- *cfg->dst_pa_ptr[1] = dst_addr + ctx->queue[1].fmt.width * ctx->queue[1].fmt.height;
++ *cfg->src_pa_ptr[1] = src_addr + ctx->queue[0].fmt.bytesperline * ctx->queue[0].fmt.height;
++ *cfg->dst_pa_ptr[1] = dst_addr + ctx->queue[1].fmt.bytesperline * ctx->queue[1].fmt.height;
+ }
+
+ v4l2_dbg(3, debug, &imr->v4l2_dev, "process buffer-pair 0x%08x:0x%08x\n",
+--
+2.7.4
+
diff --git a/bsp/meta-rcar/meta-rcar-gen3-adas/recipes-kernel/linux/linux-renesas/0389-arm64-renesas-r8a77980-VB-use-REFCLK-23.0MHZ.patch b/bsp/meta-rcar/meta-rcar-gen3-adas/recipes-kernel/linux/linux-renesas/0389-arm64-renesas-r8a77980-VB-use-REFCLK-23.0MHZ.patch
new file mode 100644
index 00000000..31536c8e
--- /dev/null
+++ b/bsp/meta-rcar/meta-rcar-gen3-adas/recipes-kernel/linux/linux-renesas/0389-arm64-renesas-r8a77980-VB-use-REFCLK-23.0MHZ.patch
@@ -0,0 +1,78 @@
+From 0e76e0d714d4da7b4572c915fc588d111ac659e6 Mon Sep 17 00:00:00 2001
+From: Vladimir Barinov <vladimir.barinov@cogentembedded.com>
+Date: Thu, 7 Feb 2019 11:44:37 +0300
+Subject: [PATCH 209/211] arm64: renesas: r8a77980: VB: use REFCLK=23.0MHZ
+
+This fixes data integrity on FPDLink
+
+Signed-off-by: Vladimir Barinov <vladimir.barinov@cogentembedded.com>
+---
+ arch/arm64/boot/dts/renesas/r8a77980-v3hsk-vb-4ch.dts | 2 +-
+ arch/arm64/boot/dts/renesas/r8a77980-v3hsk-vb-8ch.dts | 10 +++++-----
+ 2 files changed, 6 insertions(+), 6 deletions(-)
+
+diff --git a/arch/arm64/boot/dts/renesas/r8a77980-v3hsk-vb-4ch.dts b/arch/arm64/boot/dts/renesas/r8a77980-v3hsk-vb-4ch.dts
+index cb9cd54..81f9edb 100644
+--- a/arch/arm64/boot/dts/renesas/r8a77980-v3hsk-vb-4ch.dts
++++ b/arch/arm64/boot/dts/renesas/r8a77980-v3hsk-vb-4ch.dts
+@@ -324,7 +324,7 @@
+ clock-names = "clk_in";
+
+ assigned-clocks = <&cs2300>;
+- assigned-clock-rates = <23500000>;
++ assigned-clock-rates = <23000000>;
+ };
+ };
+
+diff --git a/arch/arm64/boot/dts/renesas/r8a77980-v3hsk-vb-8ch.dts b/arch/arm64/boot/dts/renesas/r8a77980-v3hsk-vb-8ch.dts
+index f23f2d0..8749c94 100644
+--- a/arch/arm64/boot/dts/renesas/r8a77980-v3hsk-vb-8ch.dts
++++ b/arch/arm64/boot/dts/renesas/r8a77980-v3hsk-vb-8ch.dts
+@@ -115,7 +115,7 @@
+ csi40_ep: endpoint {
+ clock-lanes = <0>;
+ data-lanes = <1 2 3 4>;
+- csi-rate = <1450>;
++ csi-rate = <1500>;
+ };
+ };
+ };
+@@ -130,7 +130,7 @@
+ csi41_ep: endpoint {
+ clock-lanes = <0>;
+ data-lanes = <1 2 3 4>;
+- csi-rate = <1450>;
++ csi-rate = <1500>;
+ };
+ };
+ };
+@@ -267,7 +267,7 @@
+ };
+ port@1 {
+ ti9x4_csi0ep0: endpoint {
+- csi-rate = <1450>;
++ csi-rate = <1500>;
+ remote-endpoint = <&csi40_ep>;
+ };
+ };
+@@ -425,7 +425,7 @@
+ };
+ port@1 {
+ ti9x4_csi1ep0: endpoint {
+- csi-rate = <1450>;
++ csi-rate = <1500>;
+ remote-endpoint = <&csi41_ep>;
+ };
+ };
+@@ -447,7 +447,7 @@
+ clock-names = "clk_in";
+
+ assigned-clocks = <&cs2300>;
+- assigned-clock-rates = <22500000>;
++ assigned-clock-rates = <23000000>;
+ };
+
+ gpio_exp_ch1: gpio_ch1@6c {
+--
+2.7.4
+
diff --git a/bsp/meta-rcar/meta-rcar-gen3-adas/recipes-kernel/linux/linux-renesas/0390-arm64-dts-renesas-Add-V3x-VideoBox-FDPLink-support.patch b/bsp/meta-rcar/meta-rcar-gen3-adas/recipes-kernel/linux/linux-renesas/0390-arm64-dts-renesas-Add-V3x-VideoBox-FDPLink-support.patch
new file mode 100644
index 00000000..f732d366
--- /dev/null
+++ b/bsp/meta-rcar/meta-rcar-gen3-adas/recipes-kernel/linux/linux-renesas/0390-arm64-dts-renesas-Add-V3x-VideoBox-FDPLink-support.patch
@@ -0,0 +1,123 @@
+From 902c01c2b4f805de45d93e7551ee7204576aadf9 Mon Sep 17 00:00:00 2001
+From: Valentine Barshak <valentine.barshak@cogentembedded.com>
+Date: Wed, 17 Apr 2019 23:19:53 +0300
+Subject: [PATCH 210/211] arm64: dts: renesas: Add V3x VideoBox FDPLink support
+
+This adds "vb-fdplink-output.dtsi" and includes it
+in the V3x VideoBox device trees. FDPLink is disabled
+by default. Uncomment the include directive in order
+to enable it.
+
+Signed-off-by: Valentine Barshak <valentine.barshak@cogentembedded.com>
+---
+ arch/arm64/boot/dts/renesas/r8a77970-v3msk-vbm.dts | 2 ++
+ .../boot/dts/renesas/r8a77980-v3hsk-vb-4ch.dts | 2 ++
+ .../boot/dts/renesas/r8a77980-v3hsk-vb-8ch.dts | 2 ++
+ arch/arm64/boot/dts/renesas/r8a77980-v3hsk-vbm.dts | 2 ++
+ arch/arm64/boot/dts/renesas/vb-fdplink-output.dtsi | 42 ++++++++++++++++++++++
+ 5 files changed, 50 insertions(+)
+ create mode 100644 arch/arm64/boot/dts/renesas/vb-fdplink-output.dtsi
+
+diff --git a/arch/arm64/boot/dts/renesas/r8a77970-v3msk-vbm.dts b/arch/arm64/boot/dts/renesas/r8a77970-v3msk-vbm.dts
+index 485de2a..f65ebeb 100644
+--- a/arch/arm64/boot/dts/renesas/r8a77970-v3msk-vbm.dts
++++ b/arch/arm64/boot/dts/renesas/r8a77970-v3msk-vbm.dts
+@@ -10,6 +10,8 @@
+
+ #include "r8a77970-v3msk.dts"
+ #include <dt-bindings/gpio/gpio.h>
++/* FDPLink output */
++//#include "vb-fdplink-output.dtsi"
+
+ / {
+ model = "Renesas V3MSK Videobox Mini board based on r8a77970";
+diff --git a/arch/arm64/boot/dts/renesas/r8a77980-v3hsk-vb-4ch.dts b/arch/arm64/boot/dts/renesas/r8a77980-v3hsk-vb-4ch.dts
+index 81f9edb..12ef357 100644
+--- a/arch/arm64/boot/dts/renesas/r8a77980-v3hsk-vb-4ch.dts
++++ b/arch/arm64/boot/dts/renesas/r8a77980-v3hsk-vb-4ch.dts
+@@ -10,6 +10,8 @@
+
+ #include "r8a77980-v3hsk.dts"
+ #include <dt-bindings/gpio/gpio.h>
++/* FDPLink output */
++//#include "vb-fdplink-output.dtsi"
+
+ / {
+ model = "Renesas V3HSK 4ch Videobox board based on r8a7798";
+diff --git a/arch/arm64/boot/dts/renesas/r8a77980-v3hsk-vb-8ch.dts b/arch/arm64/boot/dts/renesas/r8a77980-v3hsk-vb-8ch.dts
+index 8749c94..861b90f 100644
+--- a/arch/arm64/boot/dts/renesas/r8a77980-v3hsk-vb-8ch.dts
++++ b/arch/arm64/boot/dts/renesas/r8a77980-v3hsk-vb-8ch.dts
+@@ -10,6 +10,8 @@
+
+ #include "r8a77980-v3hsk.dts"
+ #include <dt-bindings/gpio/gpio.h>
++/* FDPLink output */
++//#include "vb-fdplink-output.dtsi"
+
+ / {
+ model = "Renesas V3HSK 4ch Videobox board based on r8a7798";
+diff --git a/arch/arm64/boot/dts/renesas/r8a77980-v3hsk-vbm.dts b/arch/arm64/boot/dts/renesas/r8a77980-v3hsk-vbm.dts
+index e362045..f5eb597 100644
+--- a/arch/arm64/boot/dts/renesas/r8a77980-v3hsk-vbm.dts
++++ b/arch/arm64/boot/dts/renesas/r8a77980-v3hsk-vbm.dts
+@@ -10,6 +10,8 @@
+
+ #include "r8a77980-v3hsk.dts"
+ #include <dt-bindings/gpio/gpio.h>
++/* FDPLink output */
++//#include "vb-fdplink-output.dtsi"
+
+ / {
+ model = "Renesas V3HSK Videobox Mini board based on r8a7798";
+diff --git a/arch/arm64/boot/dts/renesas/vb-fdplink-output.dtsi b/arch/arm64/boot/dts/renesas/vb-fdplink-output.dtsi
+new file mode 100644
+index 0000000..b166843
+--- /dev/null
++++ b/arch/arm64/boot/dts/renesas/vb-fdplink-output.dtsi
+@@ -0,0 +1,42 @@
++// SPDX-License-Identifier: GPL-2.0
++/*
++ * Device Tree Source for VideoBox FDPLink output.
++ *
++ * Copyright (C) 2019 Renesas Electronics Corp.
++ * Copyright (C) 2019 Cogent Embedded, Inc.
++ */
++
++/ {
++ lvds: lvds {
++ compatible = "panel-lvds";
++
++ data-mapping = "jeida-24";
++
++ width-mm = <210>;
++ height-mm = <158>;
++
++ panel-timing {
++ /* 1280x800 @60Hz */
++ clock-frequency = <65000000>;
++ hactive = <1280>;
++ vactive = <800>;
++ hsync-len = <40>;
++ hfront-porch = <80>;
++ hback-porch = <40>;
++ vfront-porch = <14>;
++ vback-porch = <14>;
++ vsync-len = <4>;
++ };
++
++ port {
++ lvds_in: endpoint {
++ remote-endpoint = <&du_out_lvds0>;
++ };
++ };
++ };
++};
++
++&lvds0_out {
++ /* FDPLink output */
++ remote-endpoint = <&lvds_in>;
++};
+--
+2.7.4
+
diff --git a/bsp/meta-rcar/meta-rcar-gen3-adas/recipes-kernel/linux/linux-renesas/0391-arm64-dts-renesas-Enable-FDPLink-output-on-V3x-Video.patch b/bsp/meta-rcar/meta-rcar-gen3-adas/recipes-kernel/linux/linux-renesas/0391-arm64-dts-renesas-Enable-FDPLink-output-on-V3x-Video.patch
new file mode 100644
index 00000000..d09c9875
--- /dev/null
+++ b/bsp/meta-rcar/meta-rcar-gen3-adas/recipes-kernel/linux/linux-renesas/0391-arm64-dts-renesas-Enable-FDPLink-output-on-V3x-Video.patch
@@ -0,0 +1,71 @@
+From c474a429fcdbe8c68cf87e4c2410840b85cb3627 Mon Sep 17 00:00:00 2001
+From: Valentine Barshak <valentine.barshak@cogentembedded.com>
+Date: Wed, 17 Apr 2019 23:28:56 +0300
+Subject: [PATCH 211/211] arm64: dts: renesas: Enable FDPLink output on V3x
+ VideoBox
+
+This enables FDPLink output on all V3x VideoBox boards.
+
+Signed-off-by: Valentine Barshak <valentine.barshak@cogentembedded.com>
+---
+ arch/arm64/boot/dts/renesas/r8a77970-v3msk-vbm.dts | 2 +-
+ arch/arm64/boot/dts/renesas/r8a77980-v3hsk-vb-4ch.dts | 2 +-
+ arch/arm64/boot/dts/renesas/r8a77980-v3hsk-vb-8ch.dts | 2 +-
+ arch/arm64/boot/dts/renesas/r8a77980-v3hsk-vbm.dts | 2 +-
+ 4 files changed, 4 insertions(+), 4 deletions(-)
+
+diff --git a/arch/arm64/boot/dts/renesas/r8a77970-v3msk-vbm.dts b/arch/arm64/boot/dts/renesas/r8a77970-v3msk-vbm.dts
+index f65ebeb..8d7ec04 100644
+--- a/arch/arm64/boot/dts/renesas/r8a77970-v3msk-vbm.dts
++++ b/arch/arm64/boot/dts/renesas/r8a77970-v3msk-vbm.dts
+@@ -11,7 +11,7 @@
+ #include "r8a77970-v3msk.dts"
+ #include <dt-bindings/gpio/gpio.h>
+ /* FDPLink output */
+-//#include "vb-fdplink-output.dtsi"
++#include "vb-fdplink-output.dtsi"
+
+ / {
+ model = "Renesas V3MSK Videobox Mini board based on r8a77970";
+diff --git a/arch/arm64/boot/dts/renesas/r8a77980-v3hsk-vb-4ch.dts b/arch/arm64/boot/dts/renesas/r8a77980-v3hsk-vb-4ch.dts
+index 12ef357..bca9014 100644
+--- a/arch/arm64/boot/dts/renesas/r8a77980-v3hsk-vb-4ch.dts
++++ b/arch/arm64/boot/dts/renesas/r8a77980-v3hsk-vb-4ch.dts
+@@ -11,7 +11,7 @@
+ #include "r8a77980-v3hsk.dts"
+ #include <dt-bindings/gpio/gpio.h>
+ /* FDPLink output */
+-//#include "vb-fdplink-output.dtsi"
++#include "vb-fdplink-output.dtsi"
+
+ / {
+ model = "Renesas V3HSK 4ch Videobox board based on r8a7798";
+diff --git a/arch/arm64/boot/dts/renesas/r8a77980-v3hsk-vb-8ch.dts b/arch/arm64/boot/dts/renesas/r8a77980-v3hsk-vb-8ch.dts
+index 861b90f..1ef6b11 100644
+--- a/arch/arm64/boot/dts/renesas/r8a77980-v3hsk-vb-8ch.dts
++++ b/arch/arm64/boot/dts/renesas/r8a77980-v3hsk-vb-8ch.dts
+@@ -11,7 +11,7 @@
+ #include "r8a77980-v3hsk.dts"
+ #include <dt-bindings/gpio/gpio.h>
+ /* FDPLink output */
+-//#include "vb-fdplink-output.dtsi"
++#include "vb-fdplink-output.dtsi"
+
+ / {
+ model = "Renesas V3HSK 4ch Videobox board based on r8a7798";
+diff --git a/arch/arm64/boot/dts/renesas/r8a77980-v3hsk-vbm.dts b/arch/arm64/boot/dts/renesas/r8a77980-v3hsk-vbm.dts
+index f5eb597..ea3d9e9 100644
+--- a/arch/arm64/boot/dts/renesas/r8a77980-v3hsk-vbm.dts
++++ b/arch/arm64/boot/dts/renesas/r8a77980-v3hsk-vbm.dts
+@@ -11,7 +11,7 @@
+ #include "r8a77980-v3hsk.dts"
+ #include <dt-bindings/gpio/gpio.h>
+ /* FDPLink output */
+-//#include "vb-fdplink-output.dtsi"
++#include "vb-fdplink-output.dtsi"
+
+ / {
+ model = "Renesas V3HSK Videobox Mini board based on r8a7798";
+--
+2.7.4
+
diff --git a/bsp/meta-rcar/meta-rcar-gen3-adas/recipes-kernel/linux/linux-renesas/0392-gpu-drm-bridge-thc63-Set-upper-clock-limit-to-150-MH.patch b/bsp/meta-rcar/meta-rcar-gen3-adas/recipes-kernel/linux/linux-renesas/0392-gpu-drm-bridge-thc63-Set-upper-clock-limit-to-150-MH.patch
new file mode 100644
index 00000000..4160402a
--- /dev/null
+++ b/bsp/meta-rcar/meta-rcar-gen3-adas/recipes-kernel/linux/linux-renesas/0392-gpu-drm-bridge-thc63-Set-upper-clock-limit-to-150-MH.patch
@@ -0,0 +1,32 @@
+From e97955f52cf6d797ce4a4e6c9c27f96ecac77798 Mon Sep 17 00:00:00 2001
+From: Valentine Barshak <valentine.barshak@cogentembedded.com>
+Date: Wed, 3 Jul 2019 17:24:01 +0300
+Subject: [PATCH] gpu: drm: bridge: thc63: Set upper clock limit to 150 MHz
+
+Commit "drm: bridge: thc63: Restrict modes based on hardware
+operating frequency" limits the maximum resolution to 1280x1024
+on the V3[HM] boards. Clock frequency is set to 138-148.5 MHz
+for the FullHD resolution. This sets maximum clock frequency
+to 150MHz to allow FullHD modes.
+
+Signed-off-by: Valentine Barshak <valentine.barshak@cogentembedded.com>
+---
+ drivers/gpu/drm/bridge/thc63lvd1024.c | 2 +-
+ 1 file changed, 1 insertion(+), 1 deletion(-)
+
+diff --git a/drivers/gpu/drm/bridge/thc63lvd1024.c b/drivers/gpu/drm/bridge/thc63lvd1024.c
+index cc44f37..0f3ad8b 100644
+--- a/drivers/gpu/drm/bridge/thc63lvd1024.c
++++ b/drivers/gpu/drm/bridge/thc63lvd1024.c
+@@ -55,7 +55,7 @@ static enum drm_mode_status thc63_mode_valid(struct drm_bridge *bridge,
+ if (mode->clock < 8000)
+ return MODE_CLOCK_LOW;
+
+- if (mode->clock > 135000)
++ if (mode->clock > 150000)
+ return MODE_CLOCK_HIGH;
+
+ /* Refresh rate 30 or less of full HD is basically not used,
+--
+2.7.4
+
diff --git a/bsp/meta-rcar/meta-rcar-gen3-adas/recipes-kernel/linux/linux-renesas/0393-media-soc_camera-dummy-add-mbus-controls-ids.patch b/bsp/meta-rcar/meta-rcar-gen3-adas/recipes-kernel/linux/linux-renesas/0393-media-soc_camera-dummy-add-mbus-controls-ids.patch
new file mode 100644
index 00000000..7f72578d
--- /dev/null
+++ b/bsp/meta-rcar/meta-rcar-gen3-adas/recipes-kernel/linux/linux-renesas/0393-media-soc_camera-dummy-add-mbus-controls-ids.patch
@@ -0,0 +1,338 @@
+From e0b7cbaad7f2cea64239929ac96af234027bd19f Mon Sep 17 00:00:00 2001
+From: Vladimir Barinov <vladimir.barinov@cogentembedded.com>
+Date: Mon, 17 Jun 2019 23:19:20 +0300
+Subject: [PATCH] media: soc_camera: dummy: add mbus, controls, ids
+
+This add different media buses, controls, otp ids and
+module params
+
+Signed-off-by: Vladimir Barinov <vladimir.barinov@cogentembedded.com>
+---
+ drivers/media/i2c/soc_camera/dummy.c | 216 +++++++++++++++++++++++++++++++----
+ 1 file changed, 195 insertions(+), 21 deletions(-)
+
+diff --git a/drivers/media/i2c/soc_camera/dummy.c b/drivers/media/i2c/soc_camera/dummy.c
+index a38d7c4..d213fff 100644
+--- a/drivers/media/i2c/soc_camera/dummy.c
++++ b/drivers/media/i2c/soc_camera/dummy.c
+@@ -20,17 +20,30 @@
+ #include <media/v4l2-common.h>
+ #include <media/v4l2-ctrls.h>
+
+-#define MEDIA_BUS_FORMAT MEDIA_BUS_FMT_YUYV8_2X8
+-
+ struct dummy_priv {
+ struct v4l2_subdev sd;
+ struct v4l2_ctrl_handler hdl;
+ struct media_pad pad;
+ struct v4l2_rect rect;
++ u8 id[6];
+ int max_width;
+ int max_height;
++ const char * media_bus_format;
++ int mbus_format;
+ };
+
++static int width = 1920;
++module_param(width, int, 0644);
++MODULE_PARM_DESC(width, " width (default: 1920)");
++
++static int height = 1080;
++module_param(height, int, 0644);
++MODULE_PARM_DESC(height, " height (default: 1080)");
++
++static char *mbus = "yuyv";
++module_param(mbus, charp, 0644);
++MODULE_PARM_DESC(mbus, " MEDIA_BUS_FORMAT (default: YUYV)");
++
+ static inline struct dummy_priv *to_dummy(const struct i2c_client *client)
+ {
+ return container_of(i2c_get_clientdata(client), struct dummy_priv, sd);
+@@ -59,7 +72,7 @@ static int dummy_get_fmt(struct v4l2_subdev *sd,
+
+ mf->width = priv->rect.width;
+ mf->height = priv->rect.height;
+- mf->code = MEDIA_BUS_FORMAT;
++ mf->code = priv->mbus_format;
+ mf->colorspace = V4L2_COLORSPACE_SMPTE170M;
+ mf->field = V4L2_FIELD_NONE;
+
+@@ -71,8 +84,10 @@ static int dummy_set_fmt(struct v4l2_subdev *sd,
+ struct v4l2_subdev_format *format)
+ {
+ struct v4l2_mbus_framefmt *mf = &format->format;
++ struct i2c_client *client = v4l2_get_subdevdata(sd);
++ struct dummy_priv *priv = to_dummy(client);
+
+- mf->code = MEDIA_BUS_FORMAT;
++ mf->code = priv->mbus_format;
+ mf->colorspace = V4L2_COLORSPACE_SMPTE170M;
+ mf->field = V4L2_FIELD_NONE;
+
+@@ -86,10 +101,28 @@ static int dummy_enum_mbus_code(struct v4l2_subdev *sd,
+ struct v4l2_subdev_pad_config *cfg,
+ struct v4l2_subdev_mbus_code_enum *code)
+ {
++ struct i2c_client *client = v4l2_get_subdevdata(sd);
++ struct dummy_priv *priv = to_dummy(client);
++
+ if (code->pad || code->index > 0)
+ return -EINVAL;
+
+- code->code = MEDIA_BUS_FORMAT;
++ code->code = priv->mbus_format;
++
++ return 0;
++}
++
++static int dummy_get_edid(struct v4l2_subdev *sd, struct v4l2_edid *edid)
++{
++ struct i2c_client *client = v4l2_get_subdevdata(sd);
++ struct dummy_priv *priv = to_dummy(client);
++
++ memcpy(edid->edid, priv->id, 6);
++
++ edid->edid[6] = 0xff;
++ edid->edid[7] = client->addr;
++ edid->edid[8] = 'D' >> 8;
++ edid->edid[9] = 'Y' & 0xff;
+
+ return 0;
+ }
+@@ -164,9 +197,50 @@ static int dummy_g_mbus_config(struct v4l2_subdev *sd,
+ return 0;
+ }
+
++#ifdef CONFIG_VIDEO_ADV_DEBUG
++static int dummy_g_register(struct v4l2_subdev *sd,
++ struct v4l2_dbg_register *reg)
++{
++ reg->val = 0;
++ reg->size = sizeof(u16);
++
++ return 0;
++}
++
++static int dummy_s_register(struct v4l2_subdev *sd,
++ const struct v4l2_dbg_register *reg)
++{
++ return 0;
++}
++#endif
++
++static struct v4l2_subdev_core_ops dummy_core_ops = {
++#ifdef CONFIG_VIDEO_ADV_DEBUG
++ .g_register = dummy_g_register,
++ .s_register = dummy_s_register,
++#endif
++};
++
+ static int dummy_s_ctrl(struct v4l2_ctrl *ctrl)
+ {
+- return -EINVAL;
++ switch (ctrl->id) {
++ case V4L2_CID_BRIGHTNESS:
++ case V4L2_CID_CONTRAST:
++ case V4L2_CID_SATURATION:
++ case V4L2_CID_HUE:
++ case V4L2_CID_GAMMA:
++ case V4L2_CID_SHARPNESS:
++ case V4L2_CID_AUTOGAIN:
++ case V4L2_CID_GAIN:
++ case V4L2_CID_ANALOGUE_GAIN:
++ case V4L2_CID_EXPOSURE:
++ case V4L2_CID_HFLIP:
++ case V4L2_CID_VFLIP:
++ case V4L2_CID_MIN_BUFFERS_FOR_CAPTURE:
++ break;
++ }
++
++ return 0;
+ }
+
+ static const struct v4l2_ctrl_ops dummy_ctrl_ops = {
+@@ -179,6 +253,7 @@ static struct v4l2_subdev_video_ops dummy_video_ops = {
+ };
+
+ static const struct v4l2_subdev_pad_ops dummy_subdev_pad_ops = {
++ .get_edid = dummy_get_edid,
+ .enum_mbus_code = dummy_enum_mbus_code,
+ .get_selection = dummy_get_selection,
+ .set_selection = dummy_set_selection,
+@@ -187,38 +262,107 @@ static const struct v4l2_subdev_pad_ops dummy_subdev_pad_ops = {
+ };
+
+ static struct v4l2_subdev_ops dummy_subdev_ops = {
++ .core = &dummy_core_ops,
+ .video = &dummy_video_ops,
+ .pad = &dummy_subdev_pad_ops,
+ };
+
++static void dummy_otp_id_read(struct i2c_client *client)
++{
++ struct dummy_priv *priv = to_dummy(client);
++
++ /* dummy camera id */
++ priv->id[0] = 'd';
++ priv->id[1] = 'u';
++ priv->id[2] = 'm';
++ priv->id[3] = 'm';
++ priv->id[4] = 'y';
++ priv->id[5] = '.';
++}
++
++static ssize_t dummy_otp_id_show(struct device *dev,
++ struct device_attribute *attr, char *buf)
++{
++ struct v4l2_subdev *sd = i2c_get_clientdata(to_i2c_client(dev));
++ struct i2c_client *client = v4l2_get_subdevdata(sd);
++ struct dummy_priv *priv = to_dummy(client);
++
++ dummy_otp_id_read(client);
++
++ return snprintf(buf, 32, "%02x:%02x:%02x:%02x:%02x:%02x\n",
++ priv->id[0], priv->id[1], priv->id[2], priv->id[3], priv->id[4], priv->id[5]);
++}
++
++static DEVICE_ATTR(otp_id_dummy, S_IRUGO, dummy_otp_id_show, NULL);
++
+ static int dummy_initialize(struct i2c_client *client)
+ {
+ struct dummy_priv *priv = to_dummy(client);
+
+- dev_info(&client->dev, "Dummy sensor res %dx%d\n", priv->max_width, priv->max_height);
++ if (strcmp(priv->media_bus_format, "yuyv") == 0)
++ priv->mbus_format = MEDIA_BUS_FMT_YUYV8_2X8;
++ else if (strcmp(priv->media_bus_format, "uyvy") == 0)
++ priv->mbus_format = MEDIA_BUS_FMT_UYVY8_2X8;
++ else if (strcmp(priv->media_bus_format, "grey") == 0)
++ priv->mbus_format = MEDIA_BUS_FMT_Y8_1X8;
++ else if (strcmp(priv->media_bus_format, "rggb8") == 0)
++ priv->mbus_format = MEDIA_BUS_FMT_SRGGB8_1X8;
++ else if (strcmp(priv->media_bus_format, "bggr8") == 0)
++ priv->mbus_format = MEDIA_BUS_FMT_SBGGR8_1X8;
++ else if (strcmp(priv->media_bus_format, "grbg8") == 0)
++ priv->mbus_format = MEDIA_BUS_FMT_SGRBG8_1X8;
++ else if (strcmp(priv->media_bus_format, "rggb12") == 0)
++ priv->mbus_format = MEDIA_BUS_FMT_SRGGB12_1X12;
++ else if (strcmp(priv->media_bus_format, "bggr12") == 0)
++ priv->mbus_format = MEDIA_BUS_FMT_SBGGR12_1X12;
++ else if (strcmp(priv->media_bus_format, "grbg12") == 0)
++ priv->mbus_format = MEDIA_BUS_FMT_SGRBG12_1X12;
++ else if (strcmp(priv->media_bus_format, "rggb14") == 0)
++ priv->mbus_format = MEDIA_BUS_FMT_SRGGB14_1X14;
++ else if (strcmp(priv->media_bus_format, "bggr14") == 0)
++ priv->mbus_format = MEDIA_BUS_FMT_SBGGR14_1X14;
++ else if (strcmp(priv->media_bus_format, "grbg14") == 0)
++ priv->mbus_format = MEDIA_BUS_FMT_SGRBG14_1X14;
++ else if (strcmp(priv->media_bus_format, "rggb16") == 0)
++ priv->mbus_format = MEDIA_BUS_FMT_SRGGB16_1X16;
++ else if (strcmp(priv->media_bus_format, "bggr16") == 0)
++ priv->mbus_format = MEDIA_BUS_FMT_SBGGR16_1X16;
++ else if (strcmp(priv->media_bus_format, "grbg16") == 0)
++ priv->mbus_format = MEDIA_BUS_FMT_SGRBG16_1X16;
++ else {
++ v4l_err(client, "failed to parse mbus format (%s)\n", priv->media_bus_format);
++ return -EINVAL;
++ }
++
++ /* Read OTP IDs */
++ dummy_otp_id_read(client);
++
++ dev_info(&client->dev, "Dummy camera sensor, res %dx%d, mbus %s, OTP_ID %02x:%02x:%02x:%02x:%02x:%02x\n",
++ priv->max_width, priv->max_height, priv->media_bus_format, priv->id[0], priv->id[1], priv->id[2], priv->id[3], priv->id[4], priv->id[5]);
+
+ return 0;
+ }
+
+ static int dummy_parse_dt(struct device_node *np, struct dummy_priv *priv)
+ {
+- struct i2c_client *client = v4l2_get_subdevdata(&priv->sd);
+- int err;
++ if (of_property_read_u32(np, "dummy,width", &priv->max_width))
++ priv->max_width = width;
+
+- err = of_property_read_u32(np, "dummy,width", &priv->max_width);
+- if (err) {
+- dev_err(&client->dev, "dummy,width must be defined\n");
+- goto out;
+- }
++ if (of_property_read_u32(np, "dummy,height", &priv->max_height))
++ priv->max_height = height;
+
+- err = of_property_read_u32(np, "dummy,height", &priv->max_height);
+- if (err) {
+- dev_err(&client->dev, "dummy,height must be defined\n");
+- goto out;
+- }
++ if (of_property_read_string(np, "dummy,mbus", &priv->media_bus_format))
++ priv->media_bus_format = mbus;
+
+-out:
+- return err;
++ /* module params override dts */
++ if (strcmp(mbus, "yuyv"))
++ priv->media_bus_format = mbus;
++ if (width != 1920)
++ priv->max_width = width;
++ if (height != 1080)
++ priv->max_height = height;
++
++ return 0;
+ }
+
+ static int dummy_probe(struct i2c_client *client,
+@@ -235,6 +379,30 @@ static int dummy_probe(struct i2c_client *client,
+ priv->sd.flags = V4L2_SUBDEV_FL_HAS_DEVNODE;
+
+ v4l2_ctrl_handler_init(&priv->hdl, 4);
++ v4l2_ctrl_new_std(&priv->hdl, &dummy_ctrl_ops,
++ V4L2_CID_BRIGHTNESS, 0, 16, 1, 7);
++ v4l2_ctrl_new_std(&priv->hdl, &dummy_ctrl_ops,
++ V4L2_CID_CONTRAST, 0, 16, 1, 7);
++ v4l2_ctrl_new_std(&priv->hdl, &dummy_ctrl_ops,
++ V4L2_CID_SATURATION, 0, 7, 1, 2);
++ v4l2_ctrl_new_std(&priv->hdl, &dummy_ctrl_ops,
++ V4L2_CID_HUE, 0, 23, 1, 12);
++ v4l2_ctrl_new_std(&priv->hdl, &dummy_ctrl_ops,
++ V4L2_CID_GAMMA, -128, 128, 1, 0);
++ v4l2_ctrl_new_std(&priv->hdl, &dummy_ctrl_ops,
++ V4L2_CID_SHARPNESS, 0, 10, 1, 3);
++ v4l2_ctrl_new_std(&priv->hdl, &dummy_ctrl_ops,
++ V4L2_CID_AUTOGAIN, 0, 1, 1, 0);
++ v4l2_ctrl_new_std(&priv->hdl, &dummy_ctrl_ops,
++ V4L2_CID_GAIN, 1, 0x7ff, 1, 0x200);
++ v4l2_ctrl_new_std(&priv->hdl, &dummy_ctrl_ops,
++ V4L2_CID_ANALOGUE_GAIN, 1, 0xe, 1, 0xa);
++ v4l2_ctrl_new_std(&priv->hdl, &dummy_ctrl_ops,
++ V4L2_CID_EXPOSURE, 1, 0x600, 1, 0x144);
++ v4l2_ctrl_new_std(&priv->hdl, &dummy_ctrl_ops,
++ V4L2_CID_HFLIP, 0, 1, 1, 0);
++ v4l2_ctrl_new_std(&priv->hdl, &dummy_ctrl_ops,
++ V4L2_CID_VFLIP, 0, 1, 1, 0);
+ priv->sd.ctrl_handler = &priv->hdl;
+
+ ret = priv->hdl.error;
+@@ -266,6 +434,11 @@ static int dummy_probe(struct i2c_client *client,
+ if (ret)
+ goto cleanup;
+
++ if (device_create_file(&client->dev, &dev_attr_otp_id_dummy) != 0) {
++ dev_err(&client->dev, "sysfs otp_id entry creation failed\n");
++ goto cleanup;
++ }
++
+ return 0;
+
+ cleanup:
+@@ -281,6 +454,7 @@ static int dummy_remove(struct i2c_client *client)
+ {
+ struct dummy_priv *priv = i2c_get_clientdata(client);
+
++ device_remove_file(&client->dev, &dev_attr_otp_id_dummy);
+ v4l2_async_unregister_subdev(&priv->sd);
+ media_entity_cleanup(&priv->sd.entity);
+ v4l2_ctrl_handler_free(&priv->hdl);
+--
+2.7.4
+
diff --git a/bsp/meta-rcar/meta-rcar-gen3-adas/recipes-kernel/linux/linux-renesas/0394-media-i2c-ar0233-fix-superexposure.patch b/bsp/meta-rcar/meta-rcar-gen3-adas/recipes-kernel/linux/linux-renesas/0394-media-i2c-ar0233-fix-superexposure.patch
new file mode 100644
index 00000000..aafe1f83
--- /dev/null
+++ b/bsp/meta-rcar/meta-rcar-gen3-adas/recipes-kernel/linux/linux-renesas/0394-media-i2c-ar0233-fix-superexposure.patch
@@ -0,0 +1,31 @@
+From 97424dd7f393ad1d44827062b59c3957369d60a0 Mon Sep 17 00:00:00 2001
+From: Vladimir Barinov <vladimir.barinov@cogentembedded.com>
+Date: Mon, 1 Jul 2019 15:29:47 +0300
+Subject: [PATCH] media: i2c: ar0233: fix superexposure
+
+This fixes superexposure mode for imager 27Mhz REFCLK
+
+Signed-off-by: Vladimir Barinov <vladimir.barinov@cogentembedded.com>
+---
+ drivers/media/i2c/soc_camera/ar0233.c | 4 +++-
+ 1 file changed, 3 insertions(+), 1 deletion(-)
+
+diff --git a/drivers/media/i2c/soc_camera/ar0233.c b/drivers/media/i2c/soc_camera/ar0233.c
+index f3b899e..1b7ba22 100644
+--- a/drivers/media/i2c/soc_camera/ar0233.c
++++ b/drivers/media/i2c/soc_camera/ar0233.c
+@@ -436,8 +436,10 @@ static int ar0233_initialize(struct i2c_client *client)
+ ar0233_set_regs(client, ar0233_regs_hdr_mipi_12bit_30fps_rev1);
+ break;
+ case 0x2:
+- if (extclk == 27)
++ if (extclk == 27) {
+ ar0233_regs_hdr_mipi_12bit_30fps_rev2[4] = ar0233_rev2_pll_27_102_4lane_12b;
++ ar0233_regs_seplus_mipi_12bit_30fps_rev2[2] = ar0233_rev2_pll_27_102_4lane_12b;
++ }
+
+ if (strcmp(mode, "hdr") == 0)
+ ar0233_set_regs(client, ar0233_regs_hdr_mipi_12bit_30fps_rev2);
+--
+2.7.4
+
diff --git a/bsp/meta-rcar/meta-rcar-gen3-adas/recipes-kernel/linux/linux-renesas/0395-media-i2c-ap0101-add-V-H-flip.patch b/bsp/meta-rcar/meta-rcar-gen3-adas/recipes-kernel/linux/linux-renesas/0395-media-i2c-ap0101-add-V-H-flip.patch
new file mode 100644
index 00000000..eb2f9739
--- /dev/null
+++ b/bsp/meta-rcar/meta-rcar-gen3-adas/recipes-kernel/linux/linux-renesas/0395-media-i2c-ap0101-add-V-H-flip.patch
@@ -0,0 +1,63 @@
+From 2fa25532f64b6c7706b523476316490c60384db2 Mon Sep 17 00:00:00 2001
+From: Vladimir Barinov <vladimir.barinov@cogentembedded.com>
+Date: Tue, 2 Jul 2019 15:49:39 +0300
+Subject: [PATCH] media: i2c: ap0101: add V/H flip
+
+This adds image mirror and flip
+
+Signed-off-by: Vladimir Barinov <vladimir.barinov@cogentembedded.com>
+---
+ drivers/media/i2c/soc_camera/ap0101_ar014x.c | 21 ++++++++++++++++++++-
+ 1 file changed, 20 insertions(+), 1 deletion(-)
+
+diff --git a/drivers/media/i2c/soc_camera/ap0101_ar014x.c b/drivers/media/i2c/soc_camera/ap0101_ar014x.c
+index e4f2bda..03b50e9 100644
+--- a/drivers/media/i2c/soc_camera/ap0101_ar014x.c
++++ b/drivers/media/i2c/soc_camera/ap0101_ar014x.c
+@@ -306,6 +306,7 @@ static int ap0101_s_ctrl(struct v4l2_ctrl *ctrl)
+ struct i2c_client *client = v4l2_get_subdevdata(sd);
+ struct ap0101_priv *priv = to_ap0101(client);
+ int ret = -EINVAL;
++ u16 val = 0;
+
+ if (!priv->init_complete)
+ return 0;
+@@ -320,8 +321,26 @@ static int ap0101_s_ctrl(struct v4l2_ctrl *ctrl)
+ case V4L2_CID_AUTOGAIN:
+ case V4L2_CID_GAIN:
+ case V4L2_CID_EXPOSURE:
++ break;
+ case V4L2_CID_HFLIP:
++ reg16_read16(client, 0xc846, &val);
++ if (ctrl->val)
++ val |= 0x01;
++ else
++ val &= ~0x01;
++ reg16_write16(client, 0xc846, val);
++ reg16_write16(client, 0xfc00, 0x2800);
++ ret = reg16_write16(client, 0x0040, 0x8100);
++ break;
+ case V4L2_CID_VFLIP:
++ reg16_read16(client, 0xc846, &val);
++ if (ctrl->val)
++ val |= 0x02;
++ else
++ val &= ~0x02;
++ reg16_write16(client, 0xc846, val);
++ reg16_write16(client, 0xfc00, 0x2800);
++ ret = reg16_write16(client, 0x0040, 0x8100);
+ break;
+ }
+
+@@ -558,7 +577,7 @@ static int ap0101_probe(struct i2c_client *client,
+ v4l2_ctrl_new_std(&priv->hdl, &ap0101_ctrl_ops,
+ V4L2_CID_HFLIP, 0, 1, 1, 1);
+ v4l2_ctrl_new_std(&priv->hdl, &ap0101_ctrl_ops,
+- V4L2_CID_VFLIP, 0, 1, 1, 0);
++ V4L2_CID_VFLIP, 0, 1, 1, 1);
+ priv->sd.ctrl_handler = &priv->hdl;
+
+ ret = priv->hdl.error;
+--
+2.7.4
+
diff --git a/bsp/meta-rcar/meta-rcar-gen3-adas/recipes-kernel/linux/linux-renesas/0396-media-i2c-ap0101-ar014x-get-OTP-more-complex.patch b/bsp/meta-rcar/meta-rcar-gen3-adas/recipes-kernel/linux/linux-renesas/0396-media-i2c-ap0101-ar014x-get-OTP-more-complex.patch
new file mode 100644
index 00000000..a7be90d8
--- /dev/null
+++ b/bsp/meta-rcar/meta-rcar-gen3-adas/recipes-kernel/linux/linux-renesas/0396-media-i2c-ap0101-ar014x-get-OTP-more-complex.patch
@@ -0,0 +1,72 @@
+From bb5a3717068ec667d316a051354b4edff069bf33 Mon Sep 17 00:00:00 2001
+From: Vladimir Barinov <vladimir.barinov@cogentembedded.com>
+Date: Fri, 5 Jul 2019 14:04:11 +0300
+Subject: [PATCH] media: i2c: ap0101-ar014x: get OTP more complex
+
+Involve more OTP bytes for ID to reduce the chance of similar OTP_IDs
+
+Signed-off-by: Vladimir Barinov <vladimir.barinov@cogentembedded.com>
+---
+ drivers/media/i2c/soc_camera/ap0101_ar014x.c | 20 ++++++++++----------
+ 1 file changed, 10 insertions(+), 10 deletions(-)
+
+diff --git a/drivers/media/i2c/soc_camera/ap0101_ar014x.c b/drivers/media/i2c/soc_camera/ap0101_ar014x.c
+index 03b50e9..74e6e51 100644
+--- a/drivers/media/i2c/soc_camera/ap0101_ar014x.c
++++ b/drivers/media/i2c/soc_camera/ap0101_ar014x.c
+@@ -97,16 +97,16 @@ static u16 ap0101_ar014x_read(struct i2c_client *client, u16 addr)
+ u16 reg_val = 0;
+
+ reg16_write16(client, 0x0040, 0x8d00);
+- usleep_range(100, 150); /* wait 100 us */
++ usleep_range(1000, 1500); /* wait 1000 us */
+ reg16_write16(client, 0xfc00, addr);
+ reg16_write16(client, 0xfc02, 0x0200); /* 2 bytes */
+ reg16_write16(client, 0x0040, 0x8d05);
+- usleep_range(100, 150); /* wait 100 us */
++ usleep_range(1000, 1500); /* wait 1000 us */
+ reg16_write16(client, 0x0040, 0x8d08);
+- usleep_range(100, 150); /* wait 100 us */
++ usleep_range(1000, 1500); /* wait 1000 us */
+ reg16_read16(client, 0xfc00, &reg_val);
+ reg16_write16(client, 0x0040, 0x8d02);
+- usleep_range(100, 150); /* wait 100 us */
++ usleep_range(1000, 1500); /* wait 1000 us */
+
+ return reg_val;
+ }
+@@ -114,16 +114,16 @@ static u16 ap0101_ar014x_read(struct i2c_client *client, u16 addr)
+ static void ap0101_ar014x_write(struct i2c_client *client, u16 addr, u16 val)
+ {
+ reg16_write16(client, 0x0040, 0x8d00);
+- usleep_range(100, 150); /* wait 100 us */
++ usleep_range(1000, 1500); /* wait 1000 us */
+ reg16_write16(client, 0xfc00, addr);
+ reg16_write16(client, 0xfc02, 0x0200 | (val >> 8)); /* 2 bytes */
+ reg16_write16(client, 0xfc04, (val & 0xff) << 8);
+ reg16_write16(client, 0x0040, 0x8d06);
+- usleep_range(100, 150); /* wait 100 us */
++ usleep_range(1000, 1500); /* wait 1000 us */
+ reg16_write16(client, 0x0040, 0x8d08);
+- usleep_range(100, 150); /* wait 100 us */
++ usleep_range(1000, 1500); /* wait 1000 us */
+ reg16_write16(client, 0x0040, 0x8d02);
+- usleep_range(100, 150); /* wait 100 us */
++ usleep_range(1000, 1500); /* wait 1000 us */
+ }
+
+ static int ap0101_s_stream(struct v4l2_subdev *sd, int enable)
+@@ -383,8 +383,8 @@ static void ap0101_otp_id_read(struct i2c_client *client)
+
+ for (i = 0; i < 6; i += 2) {
+ /* first 4 bytes are equal on all ar014x */
+- priv->id[i] = ap0101_ar014x_read(client, 0x3800 + i + 4) >> 8;
+- priv->id[i + 1] = ap0101_ar014x_read(client, 0x3800 + i + 4) & 0xff;
++ priv->id[i] = (ap0101_ar014x_read(client, 0x3800 + i + 4) >> 8) ^ (ap0101_ar014x_read(client, 0x3800 + i + 16) >> 8);
++ priv->id[i + 1] = (ap0101_ar014x_read(client, 0x3800 + i + 4) & 0xff) ^ (ap0101_ar014x_read(client, 0x3800 + i + 16) & 0xff);
+ }
+ }
+
+--
+2.7.4
+
diff --git a/bsp/meta-rcar/meta-rcar-gen3-adas/recipes-kernel/linux/linux-renesas/0397-media-i2c-ar0147-add-mipi-rev3-lvds-support.patch b/bsp/meta-rcar/meta-rcar-gen3-adas/recipes-kernel/linux/linux-renesas/0397-media-i2c-ar0147-add-mipi-rev3-lvds-support.patch
new file mode 100644
index 00000000..c0d55d98
--- /dev/null
+++ b/bsp/meta-rcar/meta-rcar-gen3-adas/recipes-kernel/linux/linux-renesas/0397-media-i2c-ar0147-add-mipi-rev3-lvds-support.patch
@@ -0,0 +1,1083 @@
+From 04fdc5dcea8695045c7c00d6ea1f6d9594afbd89 Mon Sep 17 00:00:00 2001
+From: Vladimir Barinov <vladimir.barinov@cogentembedded.com>
+Date: Wed, 10 Jul 2019 00:08:47 +0300
+Subject: [PATCH] media: i2c: ar0147: add mipi, rev3, lvds support
+
+This adds DVP/MIPI interfaces, silicon rev3 and
+possibility to use serializers with this imager
+
+Signed-off-by: Vladimir Barinov <vladimir.barinov@cogentembedded.com>
+---
+ drivers/media/i2c/soc_camera/ar0147.c | 53 +-
+ drivers/media/i2c/soc_camera/ar0147.h | 1 +
+ drivers/media/i2c/soc_camera/ar0147_rev3.h | 886 +++++++++++++++++++++++++++++
+ drivers/media/i2c/soc_camera/ov106xx.c | 11 +
+ 4 files changed, 948 insertions(+), 3 deletions(-)
+ create mode 100644 drivers/media/i2c/soc_camera/ar0147_rev3.h
+
+diff --git a/drivers/media/i2c/soc_camera/ar0147.c b/drivers/media/i2c/soc_camera/ar0147.c
+index cc4e761..563708c 100644
+--- a/drivers/media/i2c/soc_camera/ar0147.c
++++ b/drivers/media/i2c/soc_camera/ar0147.c
+@@ -49,21 +49,33 @@ struct ar0147_priv {
+ int hts;
+ int vts;
+ int frame_preamble;
++ int trigger;
+ };
+
++#ifdef CONFIG_SOC_CAMERA_AR0147
++static int trigger = 0;
++module_param(trigger, int, 0644);
++MODULE_PARM_DESC(trigger, " Trigger gpio number (default: 0 - GPIO0) ");
++
+ static char *mode = "hdr";
+ module_param(mode, charp, 0644);
+ MODULE_PARM_DESC(mode, " Modes linear,hdr,se,seplus (default: hdr)");
++#endif
++static char *mbus = "mipi";
++module_param(mbus, charp, 0644);
++MODULE_PARM_DESC(mbus, " Interfaces mipi,dvp (default: mipi)");
+
+ static inline struct ar0147_priv *to_ar0147(const struct i2c_client *client)
+ {
+ return container_of(i2c_get_clientdata(client), struct ar0147_priv, sd);
+ }
+
++#ifdef CONFIG_SOC_CAMERA_AR0147
+ static inline struct v4l2_subdev *to_sd(struct v4l2_ctrl *ctrl)
+ {
+ return &container_of(ctrl->handler, struct ar0147_priv, hdl)->sd;
+ }
++#endif
+
+ static void ar0147_s_port(struct i2c_client *client, int fwd_en)
+ {
+@@ -463,7 +475,7 @@ static int ar0147_initialize(struct i2c_client *client)
+ reg16_read16(client, AR0147_PID, &pid);
+
+ if (pid != AR0147_VERSION_REG) {
+- dev_dbg(&client->dev, "Product ID error %x\n\n\n", pid);
++ dev_dbg(&client->dev, "Product ID error %x\n", pid);
+ ret = -ENODEV;
+ goto err;
+ }
+@@ -485,6 +497,16 @@ static int ar0147_initialize(struct i2c_client *client)
+ else
+ dev_err(&client->dev, "Unsupported mode %s\n", mode);
+ break;
++ case 0x3:
++ if (strcmp(mode, "hdr") == 0)
++ ar0147_set_regs(client, ar0147_regs_hdr_mipi450mbps_12bit_30fps_rev3);
++ else if (strcmp(mode, "seplus1") == 0)
++ ar0147_set_regs(client, ar0147_regs_seplus1_mipi450mbps_12bit_30fps_rev3);
++ else if (strcmp(mode, "seplus2") == 0)
++ ar0147_set_regs(client, ar0147_regs_seplus2_mipi450mbps_12bit_30fps_rev3);
++ else
++ dev_err(&client->dev, "Unsupported mode %s\n", mode);
++ break;
+ default:
+ dev_err(&client->dev, "Unsupported chip revision\n");
+ }
+@@ -505,13 +527,31 @@ static int ar0147_initialize(struct i2c_client *client)
+ }
+ client->addr = tmp_addr;
+
++ /* Enable trigger */
++ if (priv->trigger < 4) {
++ reg16_write16(client, 0x340A, (~(BIT(priv->trigger) << 4)) & 0xf0);/* GPIO_CONTROL1: GPIOn input enable */
++ reg16_write16(client, 0x340C, (0x2 << 2*priv->trigger)); /* GPIO_CONTROL2: GPIOn is trigger */
++ reg16_write16(client, 0x30CE, 0x0120); /* TRIGGER_MODE */
++ //reg16_write16(client, 0x30DC, 0x0120); /* TRIGGER_DELAY */
++ }
++
+ /* Enable stream */
+ reg16_read16(client, 0x301a, &val);
++ val |= (1 << 8); /* GPI pins enable */
+ val |= (1 << 2);
++ if (strcmp(mbus, "mipi") == 0) {
++ val &= ~(1 << 12); /* HISPI interface enable */
++ val &= ~(1 << 7); /* Parallel interface disable */
++ val &= ~(1 << 6); /* Parallel pins high-impedance state */
++ } else if (strcmp(mbus, "dvp") == 0) {
++ val |= (1 << 12); /* HISPI interface disable */
++ val |= (1 << 7); /* Parallel interface enable */
++ val |= (1 << 6); /* Parallel pins drive */
++ }
+ reg16_write16(client, 0x301a, val);
+
+- dev_info(&client->dev, "ar0147 PID %x (rev %x), res %dx%d, mode=%s, OTP_ID %02x:%02x:%02x:%02x:%02x:%02x\n",
+- pid, rev, AR0147_MAX_WIDTH, AR0147_MAX_HEIGHT, mode, priv->id[0], priv->id[1], priv->id[2], priv->id[3], priv->id[4], priv->id[5]);
++ dev_info(&client->dev, "ar0147 PID %x (rev %x), res %dx%d, mode=%s, mbus=%s, OTP_ID %02x:%02x:%02x:%02x:%02x:%02x\n",
++ pid, rev, AR0147_MAX_WIDTH, AR0147_MAX_HEIGHT, mode, mbus, priv->id[0], priv->id[1], priv->id[2], priv->id[3], priv->id[4], priv->id[5]);
+ err:
+ ar0147_s_port(client, 0);
+
+@@ -530,6 +570,9 @@ static int ar0147_parse_dt(struct device_node *np, struct ar0147_priv *priv)
+ if (!endpoint)
+ break;
+
++ if (of_property_read_u32(endpoint, "trigger", &priv->trigger))
++ priv->trigger = 0;
++
+ rendpoint = of_parse_phandle(endpoint, "remote-endpoint", 0);
+ if (!rendpoint)
+ continue;
+@@ -576,6 +619,10 @@ static int ar0147_parse_dt(struct device_node *np, struct ar0147_priv *priv)
+ }
+ client->addr = tmp_addr;
+
++ /* module params override dts */
++ if (trigger)
++ priv->trigger = trigger;
++
+ mdelay(10);
+
+ return 0;
+diff --git a/drivers/media/i2c/soc_camera/ar0147.h b/drivers/media/i2c/soc_camera/ar0147.h
+index 0f7ce31..2963708 100644
+--- a/drivers/media/i2c/soc_camera/ar0147.h
++++ b/drivers/media/i2c/soc_camera/ar0147.h
+@@ -34,3 +34,4 @@ struct ar0147_reg {
+
+ #include "ar0147_rev1.h"
+ #include "ar0147_rev2.h"
++#include "ar0147_rev3.h"
+diff --git a/drivers/media/i2c/soc_camera/ar0147_rev3.h b/drivers/media/i2c/soc_camera/ar0147_rev3.h
+new file mode 100644
+index 0000000..89b58da
+--- /dev/null
++++ b/drivers/media/i2c/soc_camera/ar0147_rev3.h
+@@ -0,0 +1,886 @@
++/*
++ * ON Semiconductor AR0147 sensor camera wizard 1344x968@30/BGGR/BT601/RAW12
++ *
++ * Copyright (C) 2019 Cogent Embedded, Inc.
++ *
++ * This program is free software; you can redistribute it and/or modify it
++ * under the terms of the GNU General Public License as published by the
++ * Free Software Foundation; either version 2 of the License, or (at your
++ * option) any later version.
++ */
++
++static const struct ar0147_reg ar0147_rev3_Reset[] = {
++{0x301A, 0x0001}, // reset
++{AR0147_DELAY, 100},
++{0x301A, 0x10D8}, // Stream off and setup parallel
++{0x3070, 0x0001},
++{0x3070, 0x0000}, // 1: Solid color test pattern,
++ // 2: Full color bar test pattern,
++ // 3: Fade to grey color bar test pattern,
++ //256: Walking 1 test pattern (12 bit)
++#ifdef AR0147_DISPLAY_PATTERN_FIXED
++{0x3070, 0x0001},
++#endif
++{0x3072, 0x0fff}, // R
++{0x3074, 0x0fff}, // G(GR row)
++{0x3076, 0x0fff}, // B
++{0x3078, 0x0fff}, // G(GB row)
++#ifdef AR0147_DISPLAY_PATTERN_COLOR_BAR
++{0x3070, 0x0002},
++#endif
++{AR0147_DELAY, 250},
++{ }
++}; /* Reset */
++
++static const struct ar0147_reg ar0147_rev3_Sensor_Setup[] = {
++/* Recommended_Settings */
++{0x3500, 0x0100},
++{AR0147_DELAY, 1},
++{0x30B0, 0x980E}, // DIGITAL_TEST
++{0x3C08, 0x0000},
++{0x3C0C, 0x0518}, // DELAY_BUFFER_LLPCK_RD_WR_OVERLAP
++{0x3092, 0x1A24},
++{0x30B4, 0x01C7}, // TEMPSENS0_CTRL_REG
++{0x3372, 0x700F}, // DBLC_FS0_CONTROL
++{0x33EE, 0x0344},
++{0x350C, 0x035A},
++{0x350E, 0x0514},
++{0x3518, 0x14FE},
++{0x351A, 0x6000},
++{0x3520, 0x08CC},
++{0x3522, 0xCC08},
++{0x3524, 0x0C00},
++{0x3526, 0x0F00},
++{0x3528, 0xEEEE},
++{0x352A, 0x089F},
++{0x352C, 0x0012},
++{0x352E, 0x00EE},
++{0x3530, 0xEE00},
++{0x3536, 0xFF20},
++{0x3538, 0x3CFF},
++{0x353A, 0x9000},
++{0x353C, 0x7F00},
++{0x3540, 0xC62C},
++{0x3542, 0x4B4B},
++{0x3544, 0x3C46},
++{0x3546, 0x5A5A},
++{0x3548, 0x6400},
++{0x354A, 0x007F},
++{0x3556, 0x1010},
++{0x3566, 0x7328},
++{0x3F90, 0x0800}, // TEMPVSENS0_TMG_CTRL
++{0x3510, 0x011F},
++{0x353E, 0x801F},
++{0x3F9A, 0x0001}, // TEMPVSENS0_BOOST_SAMP_CTRL
++{0x3116, 0x0001}, // HDR_CONTROL3
++{0x3102, 0x60A0},
++{0x3104, 0x60A0},
++{0x3106, 0x60A0},
++{0x3362, 0x0000}, // DC_GAIN
++{0x3366, 0xCCCC}, // ANALOG_GAIN
++
++// Corrects defect tagged pixels
++{0x31E0, 0x0003},
++
++// Writes to bitfield R0x3552[5:4].
++// Be sure not to overwrite the other bitfields in this register.
++{0x3552, 0x0FB0},
++/* Recommended_Settings */
++
++/* Sequencer_Update */
++{0x2512, 0x8000},
++{0x2510, 0x0901},
++{0x2510, 0x3350},
++{0x2510, 0x2004},
++{0x2510, 0x1420},
++{0x2510, 0x1578},
++{0x2510, 0x087B},
++{0x2510, 0x24FF},
++{0x2510, 0x24FF},
++{0x2510, 0x24EA},
++{0x2510, 0x2410},
++{0x2510, 0x2224},
++{0x2510, 0x1015},
++{0x2510, 0xD813},
++{0x2510, 0x0214},
++{0x2510, 0x0024},
++{0x2510, 0xFF24},
++{0x2510, 0xFF24},
++{0x2510, 0xEA23},
++{0x2510, 0x2464},
++{0x2510, 0x7A24},
++{0x2510, 0x0405},
++{0x2510, 0x2C40},
++{0x2510, 0x0AFF},
++{0x2510, 0x0A78},
++{0x2510, 0x3851},
++{0x2510, 0x2A54},
++{0x2510, 0x1440},
++{0x2510, 0x0015},
++{0x2510, 0x0804},
++{0x2510, 0x0801},
++{0x2510, 0x0408},
++{0x2510, 0x2652},
++{0x2510, 0x0813},
++{0x2510, 0xC810},
++{0x2510, 0x0210},
++{0x2510, 0x1611},
++{0x2510, 0x8111},
++{0x2510, 0x8910},
++{0x2510, 0x5612},
++{0x2510, 0x1009},
++{0x2510, 0x020D},
++{0x2510, 0x0903},
++{0x2510, 0x1402},
++{0x2510, 0x15A8},
++{0x2510, 0x1388},
++{0x2510, 0x0938},
++{0x2510, 0x1199},
++{0x2510, 0x11D9},
++{0x2510, 0x091E},
++{0x2510, 0x1214},
++{0x2510, 0x10D6},
++{0x2510, 0x0901},
++{0x2510, 0x1210},
++{0x2510, 0x1212},
++{0x2510, 0x1210},
++{0x2510, 0x11DD},
++{0x2510, 0x11D9},
++{0x2510, 0x0901},
++{0x2510, 0x1441},
++{0x2510, 0x0904},
++{0x2510, 0x1056},
++{0x2510, 0x0811},
++{0x2510, 0xDB09},
++{0x2510, 0x0311},
++{0x2510, 0xFB11},
++{0x2510, 0xBB12},
++{0x2510, 0x1A12},
++{0x2510, 0x1008},
++{0x2510, 0x1250},
++{0x2510, 0x0B10},
++{0x2510, 0x7610},
++{0x2510, 0xE614},
++{0x2510, 0x6109},
++{0x2510, 0x0612},
++{0x2510, 0x4012},
++{0x2510, 0x6009},
++{0x2510, 0x1C14},
++{0x2510, 0x6009},
++{0x2510, 0x1215},
++{0x2510, 0xC813},
++{0x2510, 0xC808},
++{0x2510, 0x1066},
++{0x2510, 0x090B},
++{0x2510, 0x1588},
++{0x2510, 0x1388},
++{0x2510, 0x0913},
++{0x2510, 0x0C14},
++{0x2510, 0x4009},
++{0x2510, 0x0310},
++{0x2510, 0xE611},
++{0x2510, 0xFB12},
++{0x2510, 0x6212},
++{0x2510, 0x6011},
++{0x2510, 0xFF11},
++{0x2510, 0xFB14},
++{0x2510, 0x4109},
++{0x2510, 0x0210},
++{0x2510, 0x6609},
++{0x2510, 0x1211},
++{0x2510, 0xBB12},
++{0x2510, 0x6312},
++{0x2510, 0x6014},
++{0x2510, 0x0015},
++{0x2510, 0x1811},
++{0x2510, 0xB812},
++{0x2510, 0xA012},
++{0x2510, 0x0010},
++{0x2510, 0x2610},
++{0x2510, 0x0013},
++{0x2510, 0x0011},
++{0x2510, 0x0030},
++{0x2510, 0x5342},
++{0x2510, 0x1100},
++{0x2510, 0x1002},
++{0x2510, 0x1016},
++{0x2510, 0x1101},
++{0x2510, 0x1109},
++{0x2510, 0x1056},
++{0x2510, 0x1210},
++{0x2510, 0x0D09},
++{0x2510, 0x0314},
++{0x2510, 0x0214},
++{0x2510, 0x4309},
++{0x2510, 0x0514},
++{0x2510, 0x4009},
++{0x2510, 0x0115},
++{0x2510, 0xC813},
++{0x2510, 0xC809},
++{0x2510, 0x1A11},
++{0x2510, 0x4909},
++{0x2510, 0x0815},
++{0x2510, 0x8813},
++{0x2510, 0x8809},
++{0x2510, 0x1B11},
++{0x2510, 0x5909},
++{0x2510, 0x0B12},
++{0x2510, 0x1409},
++{0x2510, 0x0112},
++{0x2510, 0x1010},
++{0x2510, 0xD612},
++{0x2510, 0x1212},
++{0x2510, 0x1011},
++{0x2510, 0x5D11},
++{0x2510, 0x5910},
++{0x2510, 0x5609},
++{0x2510, 0x0311},
++{0x2510, 0x5B08},
++{0x2510, 0x1441},
++{0x2510, 0x0901},
++{0x2510, 0x1440},
++{0x2510, 0x090C},
++{0x2510, 0x117B},
++{0x2510, 0x113B},
++{0x2510, 0x121A},
++{0x2510, 0x1210},
++{0x2510, 0x0901},
++{0x2510, 0x1250},
++{0x2510, 0x10F6},
++{0x2510, 0x10E6},
++{0x2510, 0x1460},
++{0x2510, 0x0901},
++{0x2510, 0x15A8},
++{0x2510, 0x13A8},
++{0x2510, 0x1240},
++{0x2510, 0x1260},
++{0x2510, 0x0924},
++{0x2510, 0x1588},
++{0x2510, 0x0901},
++{0x2510, 0x1066},
++{0x2510, 0x0B08},
++{0x2510, 0x1388},
++{0x2510, 0x0925},
++{0x2510, 0x0C09},
++{0x2510, 0x0214},
++{0x2510, 0x4009},
++{0x2510, 0x0710},
++{0x2510, 0xE612},
++{0x2510, 0x6212},
++{0x2510, 0x6011},
++{0x2510, 0x7F11},
++{0x2510, 0x7B10},
++{0x2510, 0x6609},
++{0x2510, 0x0614},
++{0x2510, 0x4109},
++{0x2510, 0x0114},
++{0x2510, 0x4009},
++{0x2510, 0x0D11},
++{0x2510, 0x3B12},
++{0x2510, 0x6312},
++{0x2510, 0x6014},
++{0x2510, 0x0015},
++{0x2510, 0x1811},
++{0x2510, 0x3812},
++{0x2510, 0xA012},
++{0x2510, 0x0010},
++{0x2510, 0x2610},
++{0x2510, 0x0013},
++{0x2510, 0x0011},
++{0x2510, 0x0043},
++{0x2510, 0x7A06},
++{0x2510, 0x0507},
++{0x2510, 0x410E},
++{0x2510, 0x0237},
++{0x2510, 0x502C},
++{0x2510, 0x4414},
++{0x2510, 0x4000},
++{0x2510, 0x1508},
++{0x2510, 0x0408},
++{0x2510, 0x0104},
++{0x2510, 0x0826},
++{0x2510, 0x5508},
++{0x2510, 0x13C8},
++{0x2510, 0x1002},
++{0x2510, 0x1016},
++{0x2510, 0x1181},
++{0x2510, 0x1189},
++{0x2510, 0x1056},
++{0x2510, 0x1210},
++{0x2510, 0x0902},
++{0x2510, 0x0D09},
++{0x2510, 0x0314},
++{0x2510, 0x0215},
++{0x2510, 0xA813},
++{0x2510, 0xA814},
++{0x2510, 0x0309},
++{0x2510, 0x0614},
++{0x2510, 0x0209},
++{0x2510, 0x1F15},
++{0x2510, 0x8813},
++{0x2510, 0x8809},
++{0x2510, 0x0B11},
++{0x2510, 0x9911},
++{0x2510, 0xD909},
++{0x2510, 0x1E12},
++{0x2510, 0x1409},
++{0x2510, 0x0312},
++{0x2510, 0x1012},
++{0x2510, 0x1212},
++{0x2510, 0x1011},
++{0x2510, 0xDD11},
++{0x2510, 0xD909},
++{0x2510, 0x0114},
++{0x2510, 0x4009},
++{0x2510, 0x0711},
++{0x2510, 0xDB09},
++{0x2510, 0x0311},
++{0x2510, 0xFB11},
++{0x2510, 0xBB12},
++{0x2510, 0x1A12},
++{0x2510, 0x1009},
++{0x2510, 0x0112},
++{0x2510, 0x500B},
++{0x2510, 0x1076},
++{0x2510, 0x1066},
++{0x2510, 0x1460},
++{0x2510, 0x0901},
++{0x2510, 0x15C8},
++{0x2510, 0x0901},
++{0x2510, 0x1240},
++{0x2510, 0x1260},
++{0x2510, 0x0901},
++{0x2510, 0x13C8},
++{0x2510, 0x0956},
++{0x2510, 0x1588},
++{0x2510, 0x0901},
++{0x2510, 0x0C14},
++{0x2510, 0x4009},
++{0x2510, 0x0511},
++{0x2510, 0xFB12},
++{0x2510, 0x6212},
++{0x2510, 0x6011},
++{0x2510, 0xFF11},
++{0x2510, 0xFB09},
++{0x2510, 0x1911},
++{0x2510, 0xBB12},
++{0x2510, 0x6312},
++{0x2510, 0x6014},
++{0x2510, 0x0015},
++{0x2510, 0x1811},
++{0x2510, 0xB812},
++{0x2510, 0xA012},
++{0x2510, 0x0010},
++{0x2510, 0x2610},
++{0x2510, 0x0013},
++{0x2510, 0x0011},
++{0x2510, 0x0030},
++{0x2510, 0x5345},
++{0x2510, 0x1444},
++{0x2510, 0x1002},
++{0x2510, 0x1016},
++{0x2510, 0x1101},
++{0x2510, 0x1109},
++{0x2510, 0x1056},
++{0x2510, 0x1210},
++{0x2510, 0x0D09},
++{0x2510, 0x0314},
++{0x2510, 0x0614},
++{0x2510, 0x4709},
++{0x2510, 0x0514},
++{0x2510, 0x4409},
++{0x2510, 0x0115},
++{0x2510, 0x9813},
++{0x2510, 0x9809},
++{0x2510, 0x1A11},
++{0x2510, 0x4909},
++{0x2510, 0x0815},
++{0x2510, 0x8813},
++{0x2510, 0x8809},
++{0x2510, 0x1B11},
++{0x2510, 0x5909},
++{0x2510, 0x0B12},
++{0x2510, 0x1409},
++{0x2510, 0x0112},
++{0x2510, 0x1009},
++{0x2510, 0x0112},
++{0x2510, 0x1212},
++{0x2510, 0x1011},
++{0x2510, 0x5D11},
++{0x2510, 0x5909},
++{0x2510, 0x0511},
++{0x2510, 0x5B09},
++{0x2510, 0x1311},
++{0x2510, 0x7B11},
++{0x2510, 0x3B12},
++{0x2510, 0x1A12},
++{0x2510, 0x1009},
++{0x2510, 0x0112},
++{0x2510, 0x5010},
++{0x2510, 0x7610},
++{0x2510, 0x6614},
++{0x2510, 0x6409},
++{0x2510, 0x0115},
++{0x2510, 0xA813},
++{0x2510, 0xA812},
++{0x2510, 0x4012},
++{0x2510, 0x6009},
++{0x2510, 0x2015},
++{0x2510, 0x8809},
++{0x2510, 0x020B},
++{0x2510, 0x0901},
++{0x2510, 0x1388},
++{0x2510, 0x0925},
++{0x2510, 0x0C09},
++{0x2510, 0x0214},
++{0x2510, 0x4409},
++{0x2510, 0x0912},
++{0x2510, 0x6212},
++{0x2510, 0x6011},
++{0x2510, 0x7F11},
++{0x2510, 0x7B09},
++{0x2510, 0x1C11},
++{0x2510, 0x3B12},
++{0x2510, 0x6312},
++{0x2510, 0x6014},
++{0x2510, 0x0015},
++{0x2510, 0x1811},
++{0x2510, 0x3812},
++{0x2510, 0xA012},
++{0x2510, 0x0010},
++{0x2510, 0x2610},
++{0x2510, 0x0013},
++{0x2510, 0x0011},
++{0x2510, 0x0008},
++{0x2510, 0x7A06},
++{0x2510, 0x0508},
++{0x2510, 0x070E},
++{0x2510, 0x0237},
++{0x2510, 0x502C},
++{0x2510, 0xFE32},
++{0x2510, 0xFE06},
++{0x2510, 0x2C2C},
++
++{AR0147_DELAY, 200},
++
++{0x32e6, 0x009a}, //min_subrow
++{0x322e, 0x258c}, //clks_per_sample 396
++/* Sequencer_Update */
++
++{0x32D0, 0x3A02},
++{0x32D2, 0x3508},
++{0x32D4, 0x3702},
++{0x32D6, 0x3C04},
++{0x32DC, 0x370A},
++{0x32EA, 0x3CA8},
++{0x351E, 0x0000},
++{0x3510, 0x811F},
++
++//settings to rev1 default for non-Super Exposure mode settings
++//Super Exposure mode settings have additional settings
++{0x1010, 0x0155}, // FINE_INTEGRATION_TIME4_MIN
++{0x3236, 0x00B2}, // FINE_CORRECTION4
++{0x32EA, 0x3C0E},
++{0x32EC, 0x7151},
++{0x3116, 0x0001}, // HDR_CONTROL3
++{0x33E2, 0x0000}, // SAMPLE_CTRL
++{0x3088, 0x0400}, // LFM_CTRL
++{0x322A, 0x0039}, // FINE_INTEGRATION_CTRL
++{0x3238, 0x0333}, // EXPOSURE_RATIO
++{ }
++}; /* Sensor_Setup */
++
++static const struct ar0147_reg ar0147_rev3_Super_Exposure_Plus_T2_Mode_1_Setup[] = {
++{0x3C06, 0x2024}, // CONFIGURE_BUFFERS1
++{0x3C08, 0x2100}, // CONFIGURE_BUFFERS2
++{0x3088, 0x0400},
++{0x32EC, 0x7281},
++{0x33E2, 0x0A10},
++{0x322A, 0x0539}, // FINE_INTEGRATION_CTRL
++{0x1008, 0x0137}, // FINE_INTEGRATION_TIME_MIN
++{0x100E, 0x044F}, // FINE_INTEGRATION_TIME3_MIN
++{0x3230, 0x00DB}, // FINE_CORRECTION
++{0x3234, 0x03F3}, // FINE_CORRECTION3
++{0x30FE, 0x0040}, // NOISE_PEDESTAL
++{0x3372, 0xF40F}, // DBLC_FS0_CONTROL
++{0x3180, 0x0188},
++{0x3108, 0x0CB1},
++{0x3280, 0x0CB2}, // T1_BARRIER_C0
++{0x3282, 0x0CB2}, // T1_BARRIER_C1
++{0x3284, 0x0CB2}, // T1_BARRIER_C2
++{0x3286, 0x0CB2}, // T1_BARRIER_C3
++{0x3288, 0x0CB2}, // T2_BARRIER_C0
++{0x328A, 0x0CB2}, // T2_BARRIER_C1
++{0x328C, 0x0CB2}, // T2_BARRIER_C2
++{0x328E, 0x0CB2}, // T2_BARRIER_C3
++{0x3290, 0x0CB2}, // T3_BARRIER_C0
++{0x3292, 0x0CB2}, // T3_BARRIER_C1
++{0x3294, 0x0CB2}, // T3_BARRIER_C2
++{0x3296, 0x0CB2}, // T3_BARRIER_C3
++{0x3298, 0x0ED8}, // T4_BARRIER_C0
++{0x329A, 0x0ED8}, // T4_BARRIER_C1
++{0x329C, 0x0ED8}, // T4_BARRIER_C2
++{0x329E, 0x0ED8}, // T4_BARRIER_C3
++{0x32F6, 0x3A01},
++{0x32D2, 0x200A},
++{0x32D0, 0x3005},
++{0x32D4, 0x3505},
++{0x32F8, 0x3C03},
++{0x32DC, 0x220C},
++{0x32D6, 0x3207},
++{0x32E2, 0x3707},
++{0x3260, 0x00FF},
++{0x3262, 0x00FF},
++{0x32EA, 0x3CA9},
++{0x3250, 0x0005},
++{0x3256, 0x03E8},
++{0x3258, 0x0300},
++{0x325A, 0x0A13},
++{0x325E, 0x0186},
++{0x3252, 0x0107},
++{0x325E, 0x0186},
++{0x3096, 0x0000},
++{0x3372, 0xF50F}, // DBLC_FS0_CONTROL
++{0x337A, 0x100E}, // DBLC_SCALE0
++{0x3504, 0x9100},
++{0x350C, 0x034A},
++{0x350E, 0x051C},
++{0x3510, 0x9753},
++{0x351E, 0x0100},
++{0x3520, 0x0800},
++{0x3522, 0x0008},
++{0x3524, 0x0C00},
++{0x3526, 0x0F00},
++{0x3528, 0xDDDD},
++{0x352A, 0x089F},
++{0x352C, 0x0012},
++{0x352E, 0x00FF},
++{0x3530, 0xFF00},
++{0x3532, 0x8F48},
++{0x3536, 0xFF38},
++{0x3538, 0x24FF},
++{0x353A, 0x9000},
++{0x353C, 0x7F00},
++{0x353E, 0x801F},
++{0x3540, 0xC62C},
++{0x3542, 0x4B4B},
++{0x3544, 0x4B46},
++{0x3546, 0x5A5A},
++{0x3548, 0x6400},
++{0x354A, 0x007F},
++{0x354E, 0x1480},
++{0x3554, 0x1599},
++{0x355A, 0x0B0E},
++
++/* Digital Lateral Overflow for SE Mode 1 */
++{0x3116, 0x0001},
++{0x3100, 0xC001}, // FIELD_WR= DLO_CONTROL0, 0xE001
++{0x3102, 0x6100},
++{0x3104, 0x6100},
++{0x3106, 0x6100},
++{0x3108, 0x0CB1},
++{0x312A, 0x83E8},
++{0x3C82, 0x0FFF},
++/* Digital Lateral Overflow for SE Mode 1 */
++{ }
++}; /* Super_Exposure_Plus_T2_Mode_1_Setup */
++
++static const struct ar0147_reg ar0147_rev3_Super_Exposure_Plus_T2_Mode_2_Setup[] = {
++{0x3C06, 0x141C},
++{0x3C08, 0x2114},
++{0x3088, 0x0400},
++{0x32EC, 0x7101},
++{0x33E2, 0x0530},
++{0x322A, 0x0939}, // FINE_INTEGRATION_CTRL
++{0x1008, 0x0271}, // FINE_INTEGRATION_TIME_MIN
++{0x1010, 0x0129}, // FINE_INTEGRATION_TIME4_MIN
++{0x3230, 0x020F}, // FINE_CORRECTION
++{0x3236, 0x00C7}, // FINE_CORRECTION4
++{0x30FE, 0x0040}, // NOISE_PEDESTAL
++{0x3372, 0xF40F}, // DBLC_FS0_CONTROL
++{0x3180, 0x0188},
++{0x3108, 0x0CB1},
++{0x3280, 0x0CB2}, // T1_BARRIER_C0
++{0x3282, 0x0CB2}, // T1_BARRIER_C1
++{0x3284, 0x0CB2}, // T1_BARRIER_C2
++{0x3286, 0x0CB2}, // T1_BARRIER_C3
++{0x3288, 0x0226}, // T2_BARRIER_C0
++{0x328A, 0x0226}, // T2_BARRIER_C1
++{0x328C, 0x0226}, // T2_BARRIER_C2
++{0x328E, 0x0226}, // T2_BARRIER_C3
++{0x3290, 0x0CB2}, // T3_BARRIER_C0
++{0x3292, 0x0CB2}, // T3_BARRIER_C1
++{0x3294, 0x0CB2}, // T3_BARRIER_C2
++{0x3296, 0x0CB2}, // T3_BARRIER_C3
++{0x3298, 0x0ED8}, // T4_BARRIER_C0
++{0x329A, 0x0ED8}, // T4_BARRIER_C1
++{0x329C, 0x0ED8}, // T4_BARRIER_C2
++{0x329E, 0x0ED8}, // T4_BARRIER_C3
++{0x32F6, 0x3A01},
++{0x32D2, 0x200A},
++{0x32D0, 0x3005},
++{0x32D4, 0x3505},
++{0x32F8, 0x3C03},
++{0x32DC, 0x220C},
++{0x32D6, 0x3207},
++{0x32E2, 0x3707},
++{0x3260, 0x00FF},
++{0x3262, 0x00FF},
++{0x32EA, 0x3C69},
++{0x3250, 0x0005},
++{0x3256, 0x03E8},
++{0x3258, 0x0300},
++{0x325A, 0x0A13},
++{0x325E, 0x0186},
++{0x3252, 0x0107},
++{0x325E, 0x0186},
++{0x3752, 0x0000},
++{0x3372, 0xF50F}, // DBLC_FS0_CONTROL
++{0x337A, 0x100E}, // DBLC_SCALE0
++{0x3504, 0x9100},
++{0x350C, 0x034A},
++{0x350E, 0x051C},
++{0x3510, 0x9753},
++{0x351E, 0x0100},
++{0x3520, 0x0800},
++{0x3522, 0x0008},
++{0x3524, 0x0C00},
++{0x3526, 0x0F00},
++{0x3528, 0xDDDD},
++{0x352A, 0x089F},
++{0x352C, 0x0012},
++{0x352E, 0x00FF},
++{0x3530, 0xFF00},
++{0x3532, 0x8F08},
++{0x3536, 0xFF38},
++{0x3538, 0x24FF},
++{0x353A, 0x9000},
++{0x353C, 0x7F00},
++{0x353E, 0x801F},
++{0x3540, 0xC62C},
++{0x3542, 0x4B4B},
++{0x3544, 0x4B46},
++{0x3546, 0x5A5A},
++{0x3548, 0x6400},
++{0x354A, 0x007F},
++{0x354E, 0x1480},
++{0x3554, 0x1599},
++{0x355A, 0x0B0E},
++{0x3364, 0x0004},
++{0x3F72, 0x0A08}, // GCF_TRIM_0
++{0x3F74, 0x40E8}, // GCF_TRIM_1
++{0x3F76, 0x0E09}, // GCF_TRIM_2
++{0x3F78, 0x0210}, // GCF_TRIM_3
++
++/* Digital Lateral Overflow for SE Mode 2 */
++{0x3116, 0x0001},
++{0x3100, 0xC003}, // DLO_CONTROL0
++{0x3102, 0x8FA0}, // DLO_CONTROL1
++{0x3104, 0x8FA0}, // DLO_CONTROL2
++{0x3106, 0x8FA0}, // DLO_CONTROL3
++{0x312A, 0x83E8}, // HDR_SE_CONTROL0
++{0x3C82, 0x4FFF}, // HDR_SE_CONTROL1[]
++/* Digital Lateral Overflow for SE Mode 2 */
++{ }
++}; /* Super_Exposure_Plus_T2_Mode_2_Setup */
++
++static const struct ar0147_reg ar0147_rev3_Serial_12_bit_Timing_Setup[] = {
++#if 0
++/* PCLK=24Mhz/3 *50 /1/8 = 50MHz */
++{0x302A, 8}, // VT_PIX_CLK_DIV
++{0x302C, 1}, // VT_SYS_CLK_DIV
++{0x302E, 3}, // PRE_PLL_CLK_DIV
++{0x3030, 50}, // PLL_MULTIPLIER
++{0x3036, 8}, // OP_WORD_CLK_DIV
++{0x3038, 1}, // OP_SYS_CLK_DIV
++#else
++/* PCLK=24Mhz/4 *75 /1/9 = 50MHz */
++{0x302A, 9}, // VT_PIX_CLK_DIV
++{0x302C, 1}, // VT_SYS_CLK_DIV
++{0x302E, 4}, // PRE_PLL_CLK_DIV
++{0x3030, 75}, // PLL_MULTIPLIER
++{0x3036, 12}, // OP_WORD_CLK_DIV
++{0x3038, 1}, // OP_SYS_CLK_DIV
++#endif
++{0x30B0, 0x980C}, // DIGITAL_TEST
++{0x31DC, 0x1FB0},
++{ }
++}; /* Serial_12_bit_Timing_Setup */
++
++static const struct ar0147_reg ar0147_rev3_Readout_Mode_Configuration[] = {
++{0x30A2, 0x0001}, // X_ODD_INC_
++{0x30A6, 0x0001}, // Y_ODD_INC_
++{0x3040, 0x0000}, // READ_MODE
++{0x3082, 0x0008}, // OPERATION_MODE_CTRL: 3exp
++{0x3044, 0x0400}, // DARK_CONTROL
++{0x3064, 0x0000}, // SMIA_TEST: disable emb data and stats
++{0x33E0, 0x0C80}, // TEST_ASIL_ROWS
++{0x3180, 0x0080}, // RESERVED_MFR_3180
++{0x33E4, 0x0080}, // RESERVED_MFR_33E4
++#ifdef AR0147_EMBEDDED_LINE
++{0x3064, 0x0180}, // SMIA_TEST: enable emb data and stats
++#endif
++{ }
++}; /* Readout_Mode_Configuration */
++
++static const struct ar0147_reg ar0147_rev3_Full_Res_FOV[] = {
++{0x31B0, 0x0056}, // FRAME_PREAMBLE
++{0x31B2, 0x0045}, // LINE_PREAMBLE
++{0x3004, AR0147_X_START}, // X_ADDR_START_
++{0x3008, AR0147_X_END}, // X_ADDR_END_
++{0x3002, AR0147_Y_START}, // Y_ADDR_START_
++{0x3006, AR0147_Y_END}, // Y_ADDR_END_
++{0x3400, 0x10},
++{0x3402, (0x8000 & 0) | AR0147_MAX_WIDTH}, // X_OUTPUT_CONTROL
++{0x3404, (0x8000 & 0) | AR0147_MAX_HEIGHT}, // Y_OUTPUT_CONTROL
++{ }
++}; /* Full_Res_FOV */
++
++static const struct ar0147_reg ar0147_rev3_3exp_30FPS_Timing_and_Exposure[] = {
++{0x3082, 0x0008}, // OPERATION_MODE_CTRL: 3exp
++{0x30BA, 0x1002}, // DIGITAL_CTRL: 3exp max
++
++/* Row and Pixel Timing */
++{0x300C, AR0147_SENSOR_WIDTH + 52}, // LINE_LENGTH_PCK_ (1396)
++{0x300A, AR0147_SENSOR_HEIGHT + 226}, // FRAME_LENGTH_LINES_
++{0x3042, 0x0000}, // EXTRA_DELAY
++
++/* Exposure Settings */
++{0x3238, 0x0222}, // EXPOSURE_RATIO
++{0x3012, 0x0300}, // COARSE_INTEGRATION_TIME_
++
++{0x3014, 1550}, // FINE_INTEGRATION_TIME_
++{0x321E, 1550}, // FINE_INTEGRATION_TIME2
++{0x3222, 1550}, // FINE_INTEGRATION_TIME3
++{0x30B0, 0x980C}, // DIGITAL_TEST (MIPI ...)
++{0x32EA, 0x3C0E},
++{0x32EC, 0x72A1},
++{0x3362, 0x0000}, // DC_GAIN
++{0x3366, 0xCCCC}, // ANALOG_GAIN
++{0x3364, 0x01CF}, // DCG_TRIM
++{0x3C06, 0x083C},
++{0x3C08, 0x0100},
++{ }
++}; /* 3exp_30FPS_Timing_and_Exposure */
++
++static const struct ar0147_reg ar0147_rev3_SE_Plus_T2_Mode_1_30FPS_Timing_and_Exposure[] = {
++{0x3082, 0x0008}, // OPERATION_MODE_CTRL: 3exp
++{0x30BA, 0x1003}, // DIGITAL_CTRL: 4exp max
++
++/* Row and Pixel Timing */
++{0x300C, AR0147_SENSOR_WIDTH + 52}, // LINE_LENGTH_PCK_ (1396)
++{0x300A, AR0147_SENSOR_HEIGHT + 226}, // FRAME_LENGTH_LINES_
++{0x3042, 0x0000}, // EXTRA_DELAY
++
++/* Exposure Settings */
++{0x3238, 0x8222}, // EXPOSURE_RATIO: separate integartion time!?
++{0x3012, 0x0300}, // COARSE_INTEGRATION_TIME_
++
++{0x322A, 0x0539}, // FINE_INTEGRATION_CTRL
++{0x3014, 0x0137}, // FINE_INTEGRATION_TIME_
++{0x3222, 0x0926}, // FINE_INTEGRATION_TIME3
++{0x3362, 0x0001}, // DC_GAIN
++{0x3366, 0xFDF7}, // ANALOG_GAIN
++
++{0x30B0, 0x980C}, // DIGITAL_TEST (MIPI ...)
++{0x32EC, 0x7281},
++{ }
++}; /* SE_Plus_T2_Mode_1_30FPS_Timing_and_Exposure */
++
++static const struct ar0147_reg ar0147_rev3_SE_Plus_T2_Mode_2_50MHz_29FPS_Timing_and_Exposure[] = {
++{0x3082, 0x000C}, // OPERATION_MODE_CTRL: 3exp
++{0x30BA, 0x1003}, // DIGITAL_CTRL: 4exp max
++
++/* Row and Pixel Timing */
++{0x300C, AR0147_SENSOR_WIDTH + 326}, // LINE_LENGTH_PCK_ (1670)
++{0x300A, AR0147_SENSOR_HEIGHT + 30}, // FRAME_LENGTH_LINES_
++{0x3042, 0x0000}, // EXTRA_DELAY
++
++/* Exposure Settings */
++{0x3012, 0x0300}, // COARSE_INTEGRATION_TIME_
++{0x321A, 12}, // COARSE_INTEGRATION_TIME4_
++{0x3238, 0x8222}, // EXPOSURE_RATIO: separate integartion time!?
++
++{0x322A, 0x0939}, // FINE_INTEGRATION_CTRL
++{0x3014, 0x0271}, // FINE_INTEGRATION_TIME_
++{0x3226, 0x0594}, // FINE_INTEGRATION_TIME4
++{0x3362, 0x0D02}, // DC_GAIN
++{0x3366, 0xDE79}, // ANALOG_GAIN
++
++{0x30B0, 0x980C}, // DIGITAL_TEST (MIPI ...)
++{0x32EC, 0x7101},
++{0x33E0, 0x0080}, // TEST_ASIL_ROWS
++{ }
++}; /* SE_Plus_T2_Mode_2_30FPS_Timing_and_Exposure */
++
++static const struct ar0147_reg ar0147_rev3_Serial_4_Lane_20_to_12_bit_Output[] = {
++{0x31D0, 0x0001}, // COMPANDING
++{0x31AE, 0x0304}, // SERIAL_FORMAT: HISPI 4-lanes
++{0x31AC, 0x140C}, // DATA_FORMAT_BITS: ADC20, RAW12
++//{0x301A, 0x0118}, // RESET_REGISTER
++{0x301A, 0x0018}, // RESET_REGISTER (MIPI)
++//{0x301A, 0x11d8}, // RESET_REGISTER (DVP)
++{ }
++}; /* Serial_4_Lane_20_to_12_bit_Output */
++
++static const struct ar0147_reg ar0147_rev3_MIPI_12_bit_450MBps_Settings[] = {
++{0x31AE, 0x0204}, // SERIAL_FORMAT: MIPI 4-lanes
++{0x3342, 0x122C}, // exposure1 DT=0x2c emb=0x12
++{0x3346, 0x122C}, // exposure2 DT=0x2c emb=0x12
++{0x334A, 0x122C}, // exposure3 DT=0x2c emb=0x12
++{0x334E, 0x122C}, // exposure4 DT=0x2c emb=0x12
++{0x3344, 0x0011}, // exposure1 VC=0
++{0x3348, 0x0111}, // exposure1 VC=1
++{0x334C, 0x0211}, // exposure1 VC=2
++{0x3350, 0x0311}, // exposure1 VC=3
++{0x31B0, 0x41}, // frame_preamble
++{0x31B2, 0x2e}, // line_preamble
++
++{0x31B4, 0x2185},
++{0x31B6, 0x1105},
++{0x31B8, 0x2047},
++{0x31BA, 0x105},
++{0x31BC, 0x704},
++{ }
++}; /* MIPI_12_bit_450MBps_Settings */
++
++/* 3 Exp HDR, Full Resolution, MIPI 450MBPS 4 lane 12-bit, 30FPS, XMCLK=24MHz */
++static const struct ar0147_reg *ar0147_regs_hdr_mipi450mbps_12bit_30fps_rev3[] = {
++ ar0147_rev3_Reset,
++ ar0147_rev3_Sensor_Setup,
++ ar0147_rev3_Serial_12_bit_Timing_Setup,
++ ar0147_rev3_Readout_Mode_Configuration,
++ ar0147_rev3_Full_Res_FOV,
++ ar0147_rev3_3exp_30FPS_Timing_and_Exposure,
++ ar0147_rev3_Serial_4_Lane_20_to_12_bit_Output,
++ ar0147_rev3_MIPI_12_bit_450MBps_Settings,
++ NULL
++};
++
++/* Super-Exposure Plus T2 Mode 1, Full Resolution, MIPI 450MBPS 4 lane 12-bit, 30FPS, XMCLK=24MHz */
++static const struct ar0147_reg *ar0147_regs_seplus1_mipi450mbps_12bit_30fps_rev3[] = {
++ ar0147_rev3_Reset,
++ ar0147_rev3_Sensor_Setup,
++ ar0147_rev3_Super_Exposure_Plus_T2_Mode_1_Setup,
++ ar0147_rev3_Serial_12_bit_Timing_Setup,
++ ar0147_rev3_Readout_Mode_Configuration,
++ ar0147_rev3_Full_Res_FOV,
++ ar0147_rev3_SE_Plus_T2_Mode_1_30FPS_Timing_and_Exposure,
++ ar0147_rev3_Serial_4_Lane_20_to_12_bit_Output,
++ ar0147_rev3_MIPI_12_bit_450MBps_Settings,
++ NULL
++};
++
++/* Super-Exposure Plus T2 Mode 2, Full Resolution, MIPI 450MBPS 4 lane 12-bit, 30FPS, XMCLK=24MHz */
++static const struct ar0147_reg *ar0147_regs_seplus2_mipi450mbps_12bit_30fps_rev3[] = {
++ ar0147_rev3_Reset,
++ ar0147_rev3_Sensor_Setup,
++ ar0147_rev3_Super_Exposure_Plus_T2_Mode_2_Setup,
++ ar0147_rev3_Serial_12_bit_Timing_Setup,
++ ar0147_rev3_Readout_Mode_Configuration,
++ ar0147_rev3_Full_Res_FOV,
++ ar0147_rev3_SE_Plus_T2_Mode_2_50MHz_29FPS_Timing_and_Exposure,
++ ar0147_rev3_Serial_4_Lane_20_to_12_bit_Output,
++ ar0147_rev3_MIPI_12_bit_450MBps_Settings,
++ NULL
++};
+diff --git a/drivers/media/i2c/soc_camera/ov106xx.c b/drivers/media/i2c/soc_camera/ov106xx.c
+index 70067d7..21dffcd8 100644
+--- a/drivers/media/i2c/soc_camera/ov106xx.c
++++ b/drivers/media/i2c/soc_camera/ov106xx.c
+@@ -29,6 +29,7 @@
+ #include "isx016.c"
+ #include "isx019.c"
+ #include "ov2311.c"
++#include "ar0147.c"
+
+ static enum {
+ ID_OV10635,
+@@ -38,6 +39,7 @@ static enum {
+ ID_AR0132,
+ ID_AR0140,
+ ID_AR0143,
++ ID_AR0147,
+ ID_AR0220,
+ ID_AR0231,
+ ID_AR0233,
+@@ -119,6 +121,12 @@ static int ov106xx_probe(struct i2c_client *client,
+ goto out;
+ }
+
++ ret = ar0147_probe(client, did);
++ if (!ret) {
++ chip_id = ID_AR0147;
++ goto out;
++ }
++
+ ret = ar0220_probe(client, did);
+ if (!ret) {
+ chip_id = ID_AR0220;
+@@ -209,6 +217,9 @@ static int ov106xx_remove(struct i2c_client *client)
+ case ID_AR0143:
+ ar0143_remove(client);
+ break;
++ case ID_AR0147:
++ ar0147_remove(client);
++ break;
+ case ID_AR0220:
+ ar0220_remove(client);
+ break;
+--
+2.7.4
+
diff --git a/bsp/meta-rcar/meta-rcar-gen3-adas/recipes-kernel/linux/linux-renesas/0398-media-i2c-ar0147-add-SE-mode.patch b/bsp/meta-rcar/meta-rcar-gen3-adas/recipes-kernel/linux/linux-renesas/0398-media-i2c-ar0147-add-SE-mode.patch
new file mode 100644
index 00000000..4a003f71
--- /dev/null
+++ b/bsp/meta-rcar/meta-rcar-gen3-adas/recipes-kernel/linux/linux-renesas/0398-media-i2c-ar0147-add-SE-mode.patch
@@ -0,0 +1,284 @@
+From f424f98ee6a4fd3b8add8d126b340914e0643929 Mon Sep 17 00:00:00 2001
+From: Vladimir Barinov <vladimir.barinov@cogentembedded.com>
+Date: Tue, 16 Jul 2019 12:29:00 +0300
+Subject: [PATCH] media: i2c: ar0147: add SE mode
+
+This adds super-exposure default mode
+
+Signed-off-by: Vladimir Barinov <vladimir.barinov@cogentembedded.com>
+---
+ drivers/media/i2c/soc_camera/ar0147.c | 4 ++
+ drivers/media/i2c/soc_camera/ar0147_rev2.h | 111 +++++++++++++++++++++++++++++
+ drivers/media/i2c/soc_camera/ar0147_rev3.h | 77 ++++++++++++++++++++
+ 3 files changed, 192 insertions(+)
+
+diff --git a/drivers/media/i2c/soc_camera/ar0147.c b/drivers/media/i2c/soc_camera/ar0147.c
+index 563708c..53be588 100644
+--- a/drivers/media/i2c/soc_camera/ar0147.c
++++ b/drivers/media/i2c/soc_camera/ar0147.c
+@@ -492,6 +492,8 @@ static int ar0147_initialize(struct i2c_client *client)
+ case 0x2:
+ if (strcmp(mode, "hdr") == 0)
+ ar0147_set_regs(client, ar0147_regs_hdr_mipi450mbps_12bit_30fps_rev2);
++ else if (strcmp(mode, "se") == 0)
++ ar0147_set_regs(client, ar0147_regs_se_mipi450mbps_12bit_30fps_rev2);
+ else if (strcmp(mode, "seplus") == 0)
+ ar0147_set_regs(client, ar0147_regs_seplus_mipi450mbps_12bit_30fps_rev2);
+ else
+@@ -500,6 +502,8 @@ static int ar0147_initialize(struct i2c_client *client)
+ case 0x3:
+ if (strcmp(mode, "hdr") == 0)
+ ar0147_set_regs(client, ar0147_regs_hdr_mipi450mbps_12bit_30fps_rev3);
++ else if (strcmp(mode, "se") == 0)
++ ar0147_set_regs(client, ar0147_regs_se_mipi450mbps_12bit_30fps_rev3);
+ else if (strcmp(mode, "seplus1") == 0)
+ ar0147_set_regs(client, ar0147_regs_seplus1_mipi450mbps_12bit_30fps_rev3);
+ else if (strcmp(mode, "seplus2") == 0)
+diff --git a/drivers/media/i2c/soc_camera/ar0147_rev2.h b/drivers/media/i2c/soc_camera/ar0147_rev2.h
+index 04d8e5e..c7a643e 100644
+--- a/drivers/media/i2c/soc_camera/ar0147_rev2.h
++++ b/drivers/media/i2c/soc_camera/ar0147_rev2.h
+@@ -485,6 +485,78 @@ static const struct ar0147_reg ar0147_rev2_Sensor_Setup[] = {
+ { }
+ }; /* Sensor_Setup */
+
++static const struct ar0147_reg ar0147_rev2_Super_Exposure_Default_Setup[] = {
++{0x3082, 0x0004}, // OPERATION_MODE_CTRL
++{0x30BA, 0x1002}, // DIGITAL_CTRL
++{0x3C06, 0x000C},
++{0x3C08, 0x1100},
++{0x3116, 0x0000}, // HDR_CONTROL3
++{0x3088, 0x0480},
++{0x3510, 0x814F},
++{0x351E, 0x0100},
++{0x32EA, 0x3CA9},
++{0x32EC, 0x7281},
++{0x3212, 0x0000}, // COARSE_INTEGRATION_TIME2
++{0x3238, 0x8222}, // EXPOSURE_RATIO
++{0x33E2, 0x0910}, // SAMPLE_CTRL
++{0x3362, 0x0001}, // DC_GAIN
++{0x322A, 0x0539}, // FINE_INTEGRATION_CTRL
++{0x3014, 0x0123}, // FINE_INTEGRATION_TIME_
++{0x1008, 0x0123}, // FINE_INTEGRATION_TIME_MIN
++{0x3230, 0x00C7}, // FINE_CORRECTION
++{0x32D0, 0x3A02},
++{0x32D2, 0x3508},
++{0x32D4, 0x3702},
++{0x32D6, 0x3C04},
++{0x32DC, 0x370A},
++{0x3528, 0x99EE},
++{0x30FE, 0x0040}, // NOISE_PEDESTAL
++{0x3782, 0x0000},
++
++/* Other_Super_Exposure_Setup */
++{0x3536, 0xFF20},
++{0x3520, 0x0800},
++{0x3522, 0x0008},
++{0x3536, 0xFF20},
++{0x350C, 0x034A},
++{0x350E, 0x051C},
++{0x3540, 0xC62C},
++{0x3542, 0x4B4B},
++{0x3544, 0x4B46},
++{0x3546, 0x5A5A},
++{0x3548, 0x6400},
++{0x354A, 0x007F},
++{0x3524, 0x0600},
++{0x3372, 0xF40F}, // DBLC_FS0_CONTROL
++{0x3180, 0x0188},
++{0x3280, 0x0CB2}, // T1_BARRIER_C0
++{0x3282, 0x0CB2}, // T1_BARRIER_C1
++{0x3284, 0x0CB2}, // T1_BARRIER_C2
++{0x3286, 0x0CB2}, // T1_BARRIER_C3
++{0x3288, 0x0CB2}, // T2_BARRIER_C0
++{0x328A, 0x0CB2}, // T2_BARRIER_C1
++{0x328C, 0x0CB2}, // T2_BARRIER_C2
++{0x328E, 0x0CB2}, // T2_BARRIER_C3
++{0x3290, 0x0CB2}, // T3_BARRIER_C0
++{0x3292, 0x0CB2}, // T3_BARRIER_C1
++{0x3294, 0x0CB2}, // T3_BARRIER_C2
++{0x3296, 0x0CB2}, // T3_BARRIER_C3
++{0x3298, 0x0CB2}, // T4_BARRIER_C0
++{0x329A, 0x0CB2}, // T4_BARRIER_C1
++{0x329C, 0x0CB2}, // T4_BARRIER_C2
++{0x329E, 0x0CB2}, // T4_BARRIER_C3
++{0x3108, 0x0CB1},
++{0x312A, 0x83E8},
++{0x3C82, 0x0FFF},
++{0x3102, 0x6100},
++{0x3104, 0x6100},
++{0x3106, 0x6100},
++{0x3120, 0x0AF0},
++{0x3122, 0x0CB2},
++/* Other_Super_Exposure_Setup */
++{ }
++}; /* Super_Exposure_Default_Setup */
++
+ static const struct ar0147_reg ar0147_rev2_Super_Exposure_Default_Plus_T2_Setup[] = {
+ {0x3082, 0x0008}, // OPERATION_MODE_CTRL
+ {0x30BA, 0x1003}, // DIGITAL_CTRL
+@@ -651,6 +723,30 @@ static const struct ar0147_reg ar0147_rev2_3exp_30FPS_Timing_and_Exposure[] = {
+ { }
+ }; /* 3exp_30FPS_Timing_and_Exposure */
+
++static const struct ar0147_reg ar0147_rev2_SE_Default_Mode_30FPS_Timing_and_Exposure[] = {
++{0x3082, 0x0004}, // OPERATION_MODE_CTRL: 2exp
++{0x30BA, 0x1002}, // DIGITAL_CTRL: 3exp max
++
++/* Row and Pixel Timing */
++{0x300C, AR0147_SENSOR_WIDTH + 52}, // LINE_LENGTH_PCK_ (1396)
++{0x300A, AR0147_SENSOR_HEIGHT + 226}, // FRAME_LENGTH_LINES_
++{0x3042, 0x0000}, // EXTRA_DELAY
++
++/* Exposure Settings */
++{0x3238, 0x8222}, // EXPOSURE_RATIO: separate integartion time!?
++{0x3012, 0x0300}, // COARSE_INTEGRATION_TIME_
++
++{0x322A, 0x0139}, // FINE_INTEGRATION_CTRL
++{0x3014, 0x0123}, // FINE_INTEGRATION_TIME_
++{0x3362, 0x0001}, // DC_GAIN
++{0x3366, 0xFFF7}, // ANALOG_GAIN
++{0x3364, 0x01CF}, // DCG_TRIM
++
++{0x30B0, 0x980C}, // DIGITAL_TEST (MIPI ...)
++{0x32EC, 0x7281},
++{ }
++}; /* SE_Default_Mode_30FPS_Timing_and_Exposure */
++
+ static const struct ar0147_reg ar0147_rev2_SE_Plus_T2_Default_Mode_30FPS_Timing_and_Exposure[] = {
+ {0x3082, 0x0008}, // OPERATION_MODE_CTRL: 3exp
+ {0x30BA, 0x1003}, // DIGITAL_CTRL: 4exp max
+@@ -780,6 +876,21 @@ static const struct ar0147_reg *ar0147_regs_hdr_mipi450mbps_12bit_30fps_rev2[] =
+ NULL
+ };
+
++/* Super-Exposure, Full Resolution, MIPI 450MBPS 4 lane 12-bit, 30FPS, XMCLK=24MHz */
++static const struct ar0147_reg *ar0147_regs_se_mipi450mbps_12bit_30fps_rev2[] = {
++ ar0147_rev2_Reset,
++ ar0147_rev2_Sensor_Setup,
++ ar0147_rev2_Super_Exposure_Default_Setup,
++ ar0147_rev2_Serial_12_bit_Timing_Setup,
++ ar0147_rev2_Readout_Mode_Configuration,
++ ar0147_rev2_Full_Res_FOV,
++ ar0147_rev2_SE_Default_Mode_30FPS_Timing_and_Exposure,
++ ar0147_rev2_Serial_4_Lane_20_to_12_bit_Output,
++ ar0147_rev2_MIPI_12_bit_450MBps_Settings,
++ ar0147_rev2_shutter_and_booster_settings,
++ NULL
++};
++
+ /* Super-Exposure Plus T2, Full Resolution, MIPI 450MBPS 4 lane 12-bit, 30FPS, XMCLK=24MHz */
+ static const struct ar0147_reg *ar0147_regs_seplus_mipi450mbps_12bit_30fps_rev2[] = {
+ ar0147_rev2_Reset,
+diff --git a/drivers/media/i2c/soc_camera/ar0147_rev3.h b/drivers/media/i2c/soc_camera/ar0147_rev3.h
+index 89b58da..02acf1a 100644
+--- a/drivers/media/i2c/soc_camera/ar0147_rev3.h
++++ b/drivers/media/i2c/soc_camera/ar0147_rev3.h
+@@ -490,6 +490,36 @@ static const struct ar0147_reg ar0147_rev3_Sensor_Setup[] = {
+ { }
+ }; /* Sensor_Setup */
+
++static const struct ar0147_reg ar0147_rev3_Super_Exposure_Mode_1_Setup[] = {
++{0x3082, 0x0004}, // OPERATION_MODE_CTRL
++{0x30BA, 0x1002}, // DIGITAL_CTRL
++{0x3C06, 0x000C}, //
++{0x3C08, 0x1100}, //
++{0x3116, 0x0000}, // HDR_CONTROL3
++{0x3088, 0x0480}, //
++{0x3510, 0x814F}, //
++{0x351E, 0x0100}, //
++{0x32EA, 0x3CA9}, //
++{0x32EC, 0x7281}, //
++{0x3212, 0x0000}, // COARSE_INTEGRATION_TIME2
++{0x3238, 0x8222}, // EXPOSURE_RATIO
++{0x33E2, 0x0910}, // SAMPLE_CTRL
++{0x3362, 0x0001}, // DC_GAIN
++{0x322A, 0x0539}, // FINE_INTEGRATION_CTRL
++{0x3014, 0x0137}, // FINE_INTEGRATION_TIME_
++{0x1008, 0x0137}, // FINE_INTEGRATION_TIME_MIN
++{0x3230, 0x00DB}, // FINE_CORRECTION
++{0x32D0, 0x3A02}, //
++{0x32D2, 0x3508}, //
++{0x32D4, 0x3702}, //
++{0x32D6, 0x3C04}, //
++{0x32DC, 0x370A}, //
++{0x3528, 0x99EE}, //
++{0x30FE, 0x0040}, // NOISE_PEDESTAL
++{0x3782, 0x0000}, //
++{ }
++}; /* Super_Exposure_Mode_1_Setup */
++
+ static const struct ar0147_reg ar0147_rev3_Super_Exposure_Plus_T2_Mode_1_Setup[] = {
+ {0x3C06, 0x2024}, // CONFIGURE_BUFFERS1
+ {0x3C08, 0x2100}, // CONFIGURE_BUFFERS2
+@@ -763,6 +793,29 @@ static const struct ar0147_reg ar0147_rev3_3exp_30FPS_Timing_and_Exposure[] = {
+ { }
+ }; /* 3exp_30FPS_Timing_and_Exposure */
+
++static const struct ar0147_reg ar0147_rev3_SE_Mode_1_30FPS_Timing_and_Exposure[] = {
++{0x3082, 0x0004}, // OPERATION_MODE_CTRL: 2exp
++{0x30BA, 0x1002}, // DIGITAL_CTRL: 3exp max
++
++/* Row and Pixel Timing */
++{0x300C, AR0147_SENSOR_WIDTH + 52}, // LINE_LENGTH_PCK_ (1396)
++{0x300A, AR0147_SENSOR_HEIGHT + 226}, // FRAME_LENGTH_LINES_
++{0x3042, 0x0000}, // EXTRA_DELAY
++
++/* Exposure Settings */
++{0x3238, 0x8222}, // EXPOSURE_RATIO: separate integartion time!?
++{0x3012, 0x0300}, // COARSE_INTEGRATION_TIME_
++
++{0x322A, 0x0139}, // FINE_INTEGRATION_CTRL
++{0x3014, 0x0123}, // FINE_INTEGRATION_TIME_
++{0x3362, 0x0001}, // DC_GAIN
++{0x3366, 0xFFF7}, // ANALOG_GAIN
++
++{0x30B0, 0x980C}, // DIGITAL_TEST (MIPI ...)
++{0x32EC, 0x7281},
++{ }
++}; /* SE_Mode_1_30FPS_Timing_and_Exposure */
++
+ static const struct ar0147_reg ar0147_rev3_SE_Plus_T2_Mode_1_30FPS_Timing_and_Exposure[] = {
+ {0x3082, 0x0008}, // OPERATION_MODE_CTRL: 3exp
+ {0x30BA, 0x1003}, // DIGITAL_CTRL: 4exp max
+@@ -813,6 +866,16 @@ static const struct ar0147_reg ar0147_rev3_SE_Plus_T2_Mode_2_50MHz_29FPS_Timing_
+ { }
+ }; /* SE_Plus_T2_Mode_2_30FPS_Timing_and_Exposure */
+
++static const struct ar0147_reg ar0147_rev3_Serial_4_Lane_16_to_12_bit_Output[] = {
++{0x31D0, 0x0001}, // COMPANDING
++{0x31AE, 0x0304}, // SERIAL_FORMAT: HISPI 4-lanes
++{0x31AC, 0x100C}, // DATA_FORMAT_BITS: ADC16, RAW12
++//{0x301A, 0x0118}, // RESET_REGISTER
++{0x301A, 0x0018}, // RESET_REGISTER (MIPI)
++//{0x301A, 0x11d8}, // RESET_REGISTER (DVP)
++{ }
++}; /* Serial_4_Lane_16_to_12_bit_Output */
++
+ static const struct ar0147_reg ar0147_rev3_Serial_4_Lane_20_to_12_bit_Output[] = {
+ {0x31D0, 0x0001}, // COMPANDING
+ {0x31AE, 0x0304}, // SERIAL_FORMAT: HISPI 4-lanes
+@@ -857,6 +920,20 @@ static const struct ar0147_reg *ar0147_regs_hdr_mipi450mbps_12bit_30fps_rev3[] =
+ NULL
+ };
+
++/* Super-Exposure Mode 1, Full Resolution, MIPI 450MBPS 4 lane 12-bit, 30FPS, XMCLK=24MHz */
++static const struct ar0147_reg *ar0147_regs_se_mipi450mbps_12bit_30fps_rev3[] = {
++ ar0147_rev3_Reset,
++ ar0147_rev3_Sensor_Setup,
++ ar0147_rev3_Super_Exposure_Mode_1_Setup,
++ ar0147_rev3_Serial_12_bit_Timing_Setup,
++ ar0147_rev3_Readout_Mode_Configuration,
++ ar0147_rev3_Full_Res_FOV,
++ ar0147_rev3_SE_Mode_1_30FPS_Timing_and_Exposure,
++ ar0147_rev3_Serial_4_Lane_16_to_12_bit_Output,
++ ar0147_rev3_MIPI_12_bit_450MBps_Settings,
++ NULL
++};
++
+ /* Super-Exposure Plus T2 Mode 1, Full Resolution, MIPI 450MBPS 4 lane 12-bit, 30FPS, XMCLK=24MHz */
+ static const struct ar0147_reg *ar0147_regs_seplus1_mipi450mbps_12bit_30fps_rev3[] = {
+ ar0147_rev3_Reset,
+--
+2.7.4
+
diff --git a/bsp/meta-rcar/meta-rcar-gen3-adas/recipes-kernel/linux/linux-renesas/0399-media-i2c-ar0233-fix-artifact-line-at-vflip.patch b/bsp/meta-rcar/meta-rcar-gen3-adas/recipes-kernel/linux/linux-renesas/0399-media-i2c-ar0233-fix-artifact-line-at-vflip.patch
new file mode 100644
index 00000000..bca65f39
--- /dev/null
+++ b/bsp/meta-rcar/meta-rcar-gen3-adas/recipes-kernel/linux/linux-renesas/0399-media-i2c-ar0233-fix-artifact-line-at-vflip.patch
@@ -0,0 +1,59 @@
+From f64967aaa784f0c9bebf0f58ac3b239a093dee00 Mon Sep 17 00:00:00 2001
+From: Vladimir Barinov <vladimir.barinov@cogentembedded.com>
+Date: Fri, 19 Jul 2019 14:05:43 +0300
+Subject: [PATCH] media: i2c: ar0233: fix artifact line at vflip
+
+This fixes artifact line in super-exposure mode at vflip=1
+
+Signed-off-by: Vladimir Barinov <vladimir.barinov@cogentembedded.com>
+---
+ drivers/media/i2c/soc_camera/ar0231.c | 2 +-
+ drivers/media/i2c/soc_camera/ar0233.c | 6 ++++++
+ drivers/media/i2c/soc_camera/ar0233_rev2.h | 1 +
+ 3 files changed, 8 insertions(+), 1 deletion(-)
+
+diff --git a/drivers/media/i2c/soc_camera/ar0231.c b/drivers/media/i2c/soc_camera/ar0231.c
+index b239f56..dfca9e2 100644
+--- a/drivers/media/i2c/soc_camera/ar0231.c
++++ b/drivers/media/i2c/soc_camera/ar0231.c
+@@ -93,7 +93,7 @@ static int ar0231_set_window(struct v4l2_subdev *sd)
+ struct i2c_client *client = v4l2_get_subdevdata(sd);
+ struct ar0231_priv *priv = to_ar0231(client);
+
+- dev_err(&client->dev, "L=%d T=%d %dx%d\n", priv->rect.left, priv->rect.top, priv->rect.width, priv->rect.height);
++ dev_dbg(&client->dev, "L=%d T=%d %dx%d\n", priv->rect.left, priv->rect.top, priv->rect.width, priv->rect.height);
+
+ /* horiz crop start */
+ reg16_write16(client, 0x3004, priv->rect.left + AR0231_X_START);
+diff --git a/drivers/media/i2c/soc_camera/ar0233.c b/drivers/media/i2c/soc_camera/ar0233.c
+index 1b7ba22..71bff3f 100644
+--- a/drivers/media/i2c/soc_camera/ar0233.c
++++ b/drivers/media/i2c/soc_camera/ar0233.c
+@@ -328,6 +328,12 @@ static int ar0233_s_ctrl(struct v4l2_ctrl *ctrl)
+ else
+ val &= ~(1 << 15);
+ ret |= reg16_write16(client, 0x3040, val);
++ ret = reg16_read16(client, 0x350e, &val);
++ if (ctrl->val)
++ val |= (1 << 0);
++ else
++ val &= ~(1 << 0);
++ ret |= reg16_write16(client, 0x350e, val);
+ break;
+ case V4L2_CID_MIN_BUFFERS_FOR_CAPTURE:
+ ret = 0;
+diff --git a/drivers/media/i2c/soc_camera/ar0233_rev2.h b/drivers/media/i2c/soc_camera/ar0233_rev2.h
+index 66c79ca..7085fbc 100644
+--- a/drivers/media/i2c/soc_camera/ar0233_rev2.h
++++ b/drivers/media/i2c/soc_camera/ar0233_rev2.h
+@@ -2266,6 +2266,7 @@ static const struct ar0233_reg ar0233_rev2_O1_Recommended_Defaults_SE_T1_LIN_T2[
+
+ static const struct ar0233_reg ar0233_rev2_disable_embed_data_stat[] = {
+ {0x3040, 0xC000}, //Embedded stat2 and data2 rows, hflip/vflip=1
++{0x350e, 0x2089}, // bit0 must be set for vflip=1
+ #ifdef AR0233_EMBEDDED_LINE
+ {0x3064, 0x0180}, // SMIA_TEST: enable emb data and stats
+ #else
+--
+2.7.4
+
diff --git a/bsp/meta-rcar/meta-rcar-gen3-adas/recipes-kernel/linux/linux-renesas/0400-media-platform-soc_mediabus-add-Bayer-16bit-format.patch b/bsp/meta-rcar/meta-rcar-gen3-adas/recipes-kernel/linux/linux-renesas/0400-media-platform-soc_mediabus-add-Bayer-16bit-format.patch
new file mode 100644
index 00000000..a5007fc0
--- /dev/null
+++ b/bsp/meta-rcar/meta-rcar-gen3-adas/recipes-kernel/linux/linux-renesas/0400-media-platform-soc_mediabus-add-Bayer-16bit-format.patch
@@ -0,0 +1,36 @@
+From c735a6b07b3fdb830cf0655c7c3aa447be8d62d6 Mon Sep 17 00:00:00 2001
+From: Vladimir Barinov <vladimir.barinov@cogentembedded.com>
+Date: Mon, 29 Jul 2019 16:01:38 +0300
+Subject: [PATCH] media: platform: soc_mediabus: add Bayer 16bit format
+
+This adds MBUS format SBGGR16
+
+Signed-off-by: Vladimir Barinov <vladimir.barinov@cogentembedded.com>
+---
+ drivers/media/platform/soc_camera/soc_mediabus.c | 10 ++++++++++
+ 1 file changed, 10 insertions(+)
+
+diff --git a/drivers/media/platform/soc_camera/soc_mediabus.c b/drivers/media/platform/soc_camera/soc_mediabus.c
+index d4e5c1e..768918e 100644
+--- a/drivers/media/platform/soc_camera/soc_mediabus.c
++++ b/drivers/media/platform/soc_camera/soc_mediabus.c
+@@ -392,6 +392,16 @@ static const struct soc_mbus_lookup mbus_fmt[] = {
+ .order = SOC_MBUS_ORDER_LE,
+ .layout = SOC_MBUS_LAYOUT_PACKED,
+ },
++}, {
++ .code = MEDIA_BUS_FMT_SBGGR16_1X16,
++ .fmt = {
++ .fourcc = V4L2_PIX_FMT_SBGGR16,
++ .name = "Bayer 16 RGGB",
++ .bits_per_sample = 16,
++ .packing = SOC_MBUS_PACKING_NONE,
++ .order = SOC_MBUS_ORDER_LE,
++ .layout = SOC_MBUS_LAYOUT_PACKED,
++ },
+ },
+ };
+
+--
+2.7.4
+
diff --git a/bsp/meta-rcar/meta-rcar-gen3-adas/recipes-kernel/linux/linux-renesas/0401-media-i2c-ov490_ov10640-add-group-switch.patch b/bsp/meta-rcar/meta-rcar-gen3-adas/recipes-kernel/linux/linux-renesas/0401-media-i2c-ov490_ov10640-add-group-switch.patch
new file mode 100644
index 00000000..184ff719
--- /dev/null
+++ b/bsp/meta-rcar/meta-rcar-gen3-adas/recipes-kernel/linux/linux-renesas/0401-media-i2c-ov490_ov10640-add-group-switch.patch
@@ -0,0 +1,103 @@
+From 2e0f2e9bd61f8a76b2cb6b9022a4787c6e6768ff Mon Sep 17 00:00:00 2001
+From: Vladimir Barinov <vladimir.barinov@cogentembedded.com>
+Date: Wed, 31 Jul 2019 13:46:17 +0300
+Subject: [PATCH] media: i2c: ov490_ov10640: add group switch
+
+This adds possible to use group switch.
+By default vendors use group#1 in firmware.
+Some vendors start with different group#
+
+Signed-off-by: Vladimir Barinov <vladimir.barinov@cogentembedded.com>
+---
+ drivers/media/i2c/soc_camera/ov490_ov10640.c | 21 +++++++++++++++++++++
+ drivers/media/i2c/soc_camera/ov490_ov10640.h | 9 ---------
+ 2 files changed, 21 insertions(+), 9 deletions(-)
+
+diff --git a/drivers/media/i2c/soc_camera/ov490_ov10640.c b/drivers/media/i2c/soc_camera/ov490_ov10640.c
+index 0f1a0d4..49f373c 100644
+--- a/drivers/media/i2c/soc_camera/ov490_ov10640.c
++++ b/drivers/media/i2c/soc_camera/ov490_ov10640.c
+@@ -54,6 +54,7 @@ struct ov490_priv {
+ int blue;
+ int awb;
+ int dvp_order;
++ int group;
+ /* serializers */
+ int max9286_addr;
+ int max9271_addr;
+@@ -77,6 +78,10 @@ static int max_height;
+ module_param(max_height, int, 0644);
+ MODULE_PARM_DESC(max_height, " Fixed sensor height");
+
++static int group = 0;
++module_param(group, int, 0644);
++MODULE_PARM_DESC(group, " group number (0 - does not apply)");
++
+ static inline struct ov490_priv *to_ov490(const struct i2c_client *client)
+ {
+ return container_of(i2c_get_clientdata(client), struct ov490_priv, sd);
+@@ -858,6 +863,19 @@ static int ov490_initialize(struct i2c_client *client)
+ goto again;
+ }
+
++ if (priv->group) {
++ /* switch to group# */
++ reg16_write(client, 0xFFFD, 0x80);
++ reg16_write(client, 0xFFFE, 0x19);
++ usleep_range(100, 150); /* wait 100 us */
++ reg16_write(client, 0x5000, priv->group);
++ reg16_write(client, 0xFFFE, 0x80);
++ usleep_range(100, 150); /* wait 100 us */
++ reg16_write(client, 0xc0, 0x3f);
++
++ mdelay(30);
++ }
++
+ /* read resolution used by current firmware */
+ reg16_write(client, 0xFFFD, 0x80);
+ reg16_write(client, 0xFFFE, 0x82);
+@@ -903,6 +921,7 @@ static int ov490_parse_dt(struct device_node *np, struct ov490_priv *priv)
+ break;
+
+ of_property_read_u32(endpoint, "dvp-order", &priv->dvp_order);
++ of_property_read_u32(endpoint, "group", &priv->group);
+
+ rendpoint = of_parse_phandle(endpoint, "remote-endpoint", 0);
+ if (!rendpoint)
+@@ -978,6 +997,8 @@ static int ov490_parse_dt(struct device_node *np, struct ov490_priv *priv)
+ priv->max_height = max_height;
+ priv->is_fixed_sensor = true;
+ }
++ if (group)
++ priv->group = group;
+
+ return 0;
+ }
+diff --git a/drivers/media/i2c/soc_camera/ov490_ov10640.h b/drivers/media/i2c/soc_camera/ov490_ov10640.h
+index b00dc3ade..8ce8611 100644
+--- a/drivers/media/i2c/soc_camera/ov490_ov10640.h
++++ b/drivers/media/i2c/soc_camera/ov490_ov10640.h
+@@ -17,12 +17,6 @@ struct ov490_reg {
+ };
+
+ static const struct ov490_reg ov490_regs_wizard[] = {
+-/* Firmware start (some firmwares need this to kick processing) */
+-{0xfffd, 0x80},
+-{0xfffe, 0x19},
+-{0x5000, 0x05},
+-{0xfffe, 0x80},
+-{0x00c0, 0x3f},
+ /* The following registers should match firmware */
+ {0xfffd, 0x80},
+ {0xfffe, 0x82},
+@@ -104,7 +98,4 @@ static const struct ov490_reg ov490_regs_wizard[] = {
+ {0xfffe, 0x80},
+ {0x00c0, 0xd6},
+ #endif
+-/* respin register 0x6010 due to added firmware start HOST command */
+-{0xfffe, 0x29},
+-{0x6010, 0x01},
+ };
+--
+2.7.4
+
diff --git a/bsp/meta-rcar/meta-rcar-gen3-adas/recipes-kernel/linux/linux-renesas/0402-media-i2c-gw5200-detection-workaround.patch b/bsp/meta-rcar/meta-rcar-gen3-adas/recipes-kernel/linux/linux-renesas/0402-media-i2c-gw5200-detection-workaround.patch
new file mode 100644
index 00000000..f9d063d0
--- /dev/null
+++ b/bsp/meta-rcar/meta-rcar-gen3-adas/recipes-kernel/linux/linux-renesas/0402-media-i2c-gw5200-detection-workaround.patch
@@ -0,0 +1,118 @@
+From 78f7140c81532ad42eb3a167d7b4f83eee13701e Mon Sep 17 00:00:00 2001
+From: Vladimir Barinov <vladimir.barinov@cogentembedded.com>
+Date: Fri, 2 Aug 2019 21:20:00 +0300
+Subject: [PATCH] media: i2c: gw5200: detection workaround
+
+This adds detection of GW5200 workaround:
+ISP starts for more then 1 second. Force detect gw5200
+if enabled in dts/cmdline and the serizlier presents
+---
+ drivers/media/i2c/soc_camera/gw5200_imx390.c | 39 +++++++++++++++++++++++++---
+ 1 file changed, 35 insertions(+), 4 deletions(-)
+
+diff --git a/drivers/media/i2c/soc_camera/gw5200_imx390.c b/drivers/media/i2c/soc_camera/gw5200_imx390.c
+index 90de41f..98352a9 100644
+--- a/drivers/media/i2c/soc_camera/gw5200_imx390.c
++++ b/drivers/media/i2c/soc_camera/gw5200_imx390.c
+@@ -22,10 +22,10 @@
+
+ #include "gw5200_imx390.h"
+
+-static const int gw5200_i2c_addr[] = {0x18};
++static const int gw5200_i2c_addr[] = {0x6d};
+
+ #define GW5200_PID 0x00
+-#define GW5200_VERSION_REG 0x30
++#define GW5200_VERSION_REG 0x00
+
+ #define GW5200_MEDIA_BUS_FMT MEDIA_BUS_FMT_YUYV8_2X8
+
+@@ -41,6 +41,7 @@ struct gw5200_priv {
+ int exposure;
+ int gain;
+ int autogain;
++ int gw5200;
+ /* serializers */
+ int max9286_addr;
+ int max9271_addr;
+@@ -51,6 +52,10 @@ struct gw5200_priv {
+ int gpio_fsin;
+ };
+
++static int gw5200 = 0;
++module_param(gw5200, int, 0644);
++MODULE_PARM_DESC(gw5200, " gw5200 force (0 - imager disabled)");
++
+ static inline struct gw5200_priv *to_gw5200(const struct i2c_client *client)
+ {
+ return container_of(i2c_get_clientdata(client), struct gw5200_priv, sd);
+@@ -337,9 +342,10 @@ static DEVICE_ATTR(otp_id_gw5200, S_IRUGO, gw5200_otp_id_show, NULL);
+ static int gw5200_initialize(struct i2c_client *client)
+ {
+ struct gw5200_priv *priv = to_gw5200(client);
+- u8 pid = 0;
++ u8 pid = 0xff;
+ int ret = 0;
+ int tmp_addr;
++#if 0
+ int i;
+
+ for (i = 0; i < ARRAY_SIZE(gw5200_i2c_addr); i++) {
+@@ -357,7 +363,7 @@ static int gw5200_initialize(struct i2c_client *client)
+ client->addr = tmp_addr;
+
+ /* check model ID */
+- reg8_read(client, GW5200_PID, &pid);
++ ret = reg8_read(client, GW5200_PID, &pid);
+
+ if (pid == GW5200_VERSION_REG)
+ break;
+@@ -368,6 +374,23 @@ static int gw5200_initialize(struct i2c_client *client)
+ ret = -ENODEV;
+ goto err;
+ }
++#else
++ // Workaround: GW5200 has some hidden protocol to access it's registers, hence check serializer and dts
++ tmp_addr = client->addr;
++ if (priv->ti9x4_addr) {
++ client->addr = priv->ti9x3_addr; /* Serializer I2C address */
++ /* check UB953 ID */
++ reg8_read(client, 0xf1, &pid);
++ }
++ client->addr = tmp_addr;
++
++ if (pid != 'U') {
++ dev_dbg(&client->dev, "Product ID error %x\n", pid);
++ ret = -ENODEV;
++ goto err;
++ }
++#endif
++
+ #if 0
+ /* Program wizard registers */
+ gw5200_set_regs(client, gw5200_regs_wizard, ARRAY_SIZE(gw5200_regs_wizard));
+@@ -393,6 +416,8 @@ static int gw5200_parse_dt(struct device_node *np, struct gw5200_priv *priv)
+ if (!endpoint)
+ break;
+
++ of_property_read_u32(endpoint, "gw5200", &priv->gw5200);
++
+ rendpoint = of_parse_phandle(endpoint, "remote-endpoint", 0);
+ if (!rendpoint)
+ continue;
+@@ -437,6 +462,12 @@ static int gw5200_parse_dt(struct device_node *np, struct gw5200_priv *priv)
+
+ mdelay(10);
+
++ if (gw5200)
++ priv->gw5200 = gw5200;
++
++ if (!priv->gw5200)
++ return -ENODEV;
++
+ return 0;
+ }
+
+--
+2.7.4
+
diff --git a/bsp/meta-rcar/meta-rcar-gen3-adas/recipes-kernel/linux/linux-renesas/0403-media-i2c-ov2311-put-to-autodetect-head.patch b/bsp/meta-rcar/meta-rcar-gen3-adas/recipes-kernel/linux/linux-renesas/0403-media-i2c-ov2311-put-to-autodetect-head.patch
new file mode 100644
index 00000000..460474a3
--- /dev/null
+++ b/bsp/meta-rcar/meta-rcar-gen3-adas/recipes-kernel/linux/linux-renesas/0403-media-i2c-ov2311-put-to-autodetect-head.patch
@@ -0,0 +1,48 @@
+From 724e16aa8fbc060167beeb3faeb375537616fa2c Mon Sep 17 00:00:00 2001
+From: Vladimir Barinov <vladimir.barinov@cogentembedded.com>
+Date: Fri, 2 Aug 2019 23:12:13 +0300
+Subject: [PATCH] media: i2c: ov2311: put to autodetect head
+
+This puts OV2311 in autodetect head becase the serializer
+remote gpio is controlled from command line only
+
+Imagers that have remote gpios in glue must be in tail
+
+Signed-off-by: Vladimir Barinov <vladimir.barinov@cogentembedded.com>
+---
+ drivers/media/i2c/soc_camera/ov106xx.c | 12 ++++++------
+ 1 file changed, 6 insertions(+), 6 deletions(-)
+
+diff --git a/drivers/media/i2c/soc_camera/ov106xx.c b/drivers/media/i2c/soc_camera/ov106xx.c
+index 21dffcd8..eaa492e 100644
+--- a/drivers/media/i2c/soc_camera/ov106xx.c
++++ b/drivers/media/i2c/soc_camera/ov106xx.c
+@@ -91,6 +91,12 @@ static int ov106xx_probe(struct i2c_client *client,
+ goto out;
+ }
+
++ ret = ov2311_probe(client, did);
++ if (!ret) {
++ chip_id = ID_OV2311;
++ goto out;
++ }
++
+ ret = ov10635_probe(client, did);
+ if (!ret) {
+ chip_id = ID_OV10635;
+@@ -145,12 +151,6 @@ static int ov106xx_probe(struct i2c_client *client,
+ goto out;
+ }
+
+- ret = ov2311_probe(client, did);
+- if (!ret) {
+- chip_id = ID_OV2311;
+- goto out;
+- }
+-
+ ret = imx390_probe(client, did);
+ if (!ret) {
+ chip_id = ID_IMX390;
+--
+2.7.4
+
diff --git a/bsp/meta-rcar/meta-rcar-gen3-adas/recipes-kernel/linux/linux-renesas/0404-media-i2c-onsemi-imager-correct-trigger-handling.patch b/bsp/meta-rcar/meta-rcar-gen3-adas/recipes-kernel/linux/linux-renesas/0404-media-i2c-onsemi-imager-correct-trigger-handling.patch
new file mode 100644
index 00000000..79b12c5a
--- /dev/null
+++ b/bsp/meta-rcar/meta-rcar-gen3-adas/recipes-kernel/linux/linux-renesas/0404-media-i2c-onsemi-imager-correct-trigger-handling.patch
@@ -0,0 +1,165 @@
+From 783eb39cdc3a26582dbe6031f7d112441a7cccd1 Mon Sep 17 00:00:00 2001
+From: Vladimir Barinov <vladimir.barinov@cogentembedded.com>
+Date: Sat, 3 Aug 2019 00:24:36 +0300
+Subject: [PATCH] media: i2c: onsemi imager correct trigger handling
+
+This add trigger enablement from dts/bootargs
+
+Signed-off-by: Vladimir Barinov <vladimir.barinov@cogentembedded.com>
+---
+ drivers/media/i2c/soc_camera/ar0147.c | 6 +++---
+ drivers/media/i2c/soc_camera/ar0231.c | 24 ++++++++++++++++++++++--
+ drivers/media/i2c/soc_camera/ar0231_rev7.h | 6 +++---
+ drivers/media/i2c/soc_camera/ar0233.c | 18 ++++++++----------
+ 4 files changed, 36 insertions(+), 18 deletions(-)
+
+diff --git a/drivers/media/i2c/soc_camera/ar0147.c b/drivers/media/i2c/soc_camera/ar0147.c
+index 53be588..08fd136 100644
+--- a/drivers/media/i2c/soc_camera/ar0147.c
++++ b/drivers/media/i2c/soc_camera/ar0147.c
+@@ -532,7 +532,7 @@ static int ar0147_initialize(struct i2c_client *client)
+ client->addr = tmp_addr;
+
+ /* Enable trigger */
+- if (priv->trigger < 4) {
++ if (priv->trigger >= 0 && priv->trigger < 4) {
+ reg16_write16(client, 0x340A, (~(BIT(priv->trigger) << 4)) & 0xf0);/* GPIO_CONTROL1: GPIOn input enable */
+ reg16_write16(client, 0x340C, (0x2 << 2*priv->trigger)); /* GPIO_CONTROL2: GPIOn is trigger */
+ reg16_write16(client, 0x30CE, 0x0120); /* TRIGGER_MODE */
+@@ -554,8 +554,8 @@ static int ar0147_initialize(struct i2c_client *client)
+ }
+ reg16_write16(client, 0x301a, val);
+
+- dev_info(&client->dev, "ar0147 PID %x (rev %x), res %dx%d, mode=%s, mbus=%s, OTP_ID %02x:%02x:%02x:%02x:%02x:%02x\n",
+- pid, rev, AR0147_MAX_WIDTH, AR0147_MAX_HEIGHT, mode, mbus, priv->id[0], priv->id[1], priv->id[2], priv->id[3], priv->id[4], priv->id[5]);
++ dev_info(&client->dev, "ar0147 PID %x (rev%x), res %dx%d, mode=%s, mbus=%s, OTP_ID %02x:%02x:%02x:%02x:%02x:%02x\n",
++ pid, rev & 0xf, AR0147_MAX_WIDTH, AR0147_MAX_HEIGHT, mode, mbus, priv->id[0], priv->id[1], priv->id[2], priv->id[3], priv->id[4], priv->id[5]);
+ err:
+ ar0147_s_port(client, 0);
+
+diff --git a/drivers/media/i2c/soc_camera/ar0231.c b/drivers/media/i2c/soc_camera/ar0231.c
+index dfca9e2..36b5657 100644
+--- a/drivers/media/i2c/soc_camera/ar0231.c
++++ b/drivers/media/i2c/soc_camera/ar0231.c
+@@ -45,8 +45,13 @@ struct ar0231_priv {
+ int port;
+ int gpio_resetb;
+ int gpio_fsin;
++ int trigger;
+ };
+
++static int trigger = 0;
++module_param(trigger, int, 0644);
++MODULE_PARM_DESC(trigger, " Trigger gpio number (default: 0 - GPIO0) ");
++
+ static inline struct ar0231_priv *to_ar0231(const struct i2c_client *client)
+ {
+ return container_of(i2c_get_clientdata(client), struct ar0231_priv, sd);
+@@ -436,13 +441,21 @@ static int ar0231_initialize(struct i2c_client *client)
+ if (priv->max9286_addr)
+ ar0231_set_regs(client, ar0231_regs_wizard_rev6_dvp, ARRAY_SIZE(ar0231_regs_wizard_rev6_dvp));
+
++ /* Enable trigger */
++ if (priv->trigger >= 0 && priv->trigger < 4) {
++ reg16_write16(client, 0x340A, (~(BIT(priv->trigger) << 4)) & 0xf0);/* GPIO_CONTROL1: GPIOn input enable */
++ reg16_write16(client, 0x340C, (0x2 << 2*priv->trigger)); /* GPIO_CONTROL2: GPIOn is trigger */
++ reg16_write16(client, 0x30CE, 0x0120); /* TRIGGER_MODE */
++ //reg16_write16(client, 0x30DC, 0x0120); /* TRIGGER_DELAY */
++ }
++
+ /* Enable stream */
+ reg16_read16(client, 0x301a, &val);
+ val |= (1 << 2);
+ reg16_write16(client, 0x301a, val);
+
+- dev_info(&client->dev, "ar0231 PID %x (rev %x), res %dx%d, OTP_ID %02x:%02x:%02x:%02x:%02x:%02x\n",
+- pid, rev, AR0231_MAX_WIDTH, AR0231_MAX_HEIGHT, priv->id[0], priv->id[1], priv->id[2], priv->id[3], priv->id[4], priv->id[5]);
++ dev_info(&client->dev, "ar0231 PID %x (rev%x), res %dx%d, OTP_ID %02x:%02x:%02x:%02x:%02x:%02x\n",
++ pid, rev & 0xf, AR0231_MAX_WIDTH, AR0231_MAX_HEIGHT, priv->id[0], priv->id[1], priv->id[2], priv->id[3], priv->id[4], priv->id[5]);
+ err:
+ ar0231_s_port(client, 0);
+ return ret;
+@@ -460,6 +473,9 @@ static int ar0231_parse_dt(struct device_node *np, struct ar0231_priv *priv)
+ if (!endpoint)
+ break;
+
++ if (of_property_read_u32(endpoint, "trigger", &priv->trigger))
++ priv->trigger = 0;
++
+ rendpoint = of_parse_phandle(endpoint, "remote-endpoint", 0);
+ if (!rendpoint)
+ continue;
+@@ -502,6 +518,10 @@ static int ar0231_parse_dt(struct device_node *np, struct ar0231_priv *priv)
+ }
+ client->addr = tmp_addr;
+
++ /* module params override dts */
++ if (trigger)
++ priv->trigger = trigger;
++
+ return 0;
+ }
+
+diff --git a/drivers/media/i2c/soc_camera/ar0231_rev7.h b/drivers/media/i2c/soc_camera/ar0231_rev7.h
+index 5f196e8..704024a 100644
+--- a/drivers/media/i2c/soc_camera/ar0231_rev7.h
++++ b/drivers/media/i2c/soc_camera/ar0231_rev7.h
+@@ -389,9 +389,9 @@ static const struct ar0231_reg ar0231_regs_wizard_rev7[] = {
+ {0x300C, AR0231_SENSOR_WIDTH + 550}, // Line_length_pck
+ {0x3012, 0x144}, //Integration_time
+
+-#if 1 /* Enable trigger input */
+-{0x340A, 0x00E0}, // GPIO_CONTROL1: GPIO1 is trigger
+-{0x340C, 0x0002}, // GPIO_CONTROL2: GPIO1 is trigger
++#if 0 /* Enable trigger input */
++{0x340A, 0x00E0}, // GPIO_CONTROL1: GPIO0 is trigger
++{0x340C, 0x0002}, // GPIO_CONTROL2: GPIO0 is trigger
+ {0x30CE, 0x0120}, // TRIGGER_MODE
+ //{0x30DC, 0x0120}, // TRIGGER_DELAY
+ {0x301A, 0x0118}, // GPI pins enable
+diff --git a/drivers/media/i2c/soc_camera/ar0233.c b/drivers/media/i2c/soc_camera/ar0233.c
+index 71bff3f..9294267 100644
+--- a/drivers/media/i2c/soc_camera/ar0233.c
++++ b/drivers/media/i2c/soc_camera/ar0233.c
+@@ -44,10 +44,6 @@ struct ar0233_priv {
+ int trigger;
+ };
+
+-static int trigger = 0;
+-module_param(trigger, int, 0644);
+-MODULE_PARM_DESC(trigger, " Trigger gpio number (default: 0 - GPIO0) ");
+-
+ static int extclk = 23;
+ module_param(extclk, int, 0644);
+ MODULE_PARM_DESC(extclk, " EXTCLK value in MHz (default: 23) ");
+@@ -459,10 +455,12 @@ static int ar0233_initialize(struct i2c_client *client)
+ }
+
+ /* Enable trigger */
+- reg16_write16(client, 0x340A, (~(BIT(priv->trigger) << 4)) & 0xf0); /* GPIO_CONTROL1: GPIOn input enable */
+- reg16_write16(client, 0x340C, (0x2 << 2*priv->trigger)); /* GPIO_CONTROL2: GPIOn is trigger */
+- reg16_write16(client, 0x30CE, 0x0120); /* TRIGGER_MODE */
+- //reg16_write16(client, 0x30DC, 0x0120); /* TRIGGER_DELAY */
++ if (priv->trigger >= 0 && priv->trigger < 4) {
++ reg16_write16(client, 0x340A, (~(BIT(priv->trigger) << 4)) & 0xf0); /* GPIO_CONTROL1: GPIOn input enable */
++ reg16_write16(client, 0x340C, (0x2 << 2*priv->trigger)); /* GPIO_CONTROL2: GPIOn is trigger */
++ reg16_write16(client, 0x30CE, 0x0120); /* TRIGGER_MODE */
++ //reg16_write16(client, 0x30DC, 0x0120); /* TRIGGER_DELAY */
++ }
+
+ /* Enable stream */
+ reg16_read16(client, 0x301a, &val); // read inital reset_register value
+@@ -470,8 +468,8 @@ static int ar0233_initialize(struct i2c_client *client)
+ val |= (1 << 2); // Set streamOn bit
+ reg16_write16(client, 0x301a, val); // Start Streaming
+
+- dev_info(&client->dev, "ar0233 PID %x (rev %x), res %dx%d, mode=%s, OTP_ID %02x:%02x:%02x:%02x:%02x:%02x\n",
+- pid, rev, AR0233_MAX_WIDTH, AR0233_MAX_HEIGHT, mode, priv->id[0], priv->id[1], priv->id[2], priv->id[3], priv->id[4], priv->id[5]);
++ dev_info(&client->dev, "ar0233 PID %x (rev%x), res %dx%d, mode=%s, OTP_ID %02x:%02x:%02x:%02x:%02x:%02x\n",
++ pid, rev & 0xf, AR0233_MAX_WIDTH, AR0233_MAX_HEIGHT, mode, priv->id[0], priv->id[1], priv->id[2], priv->id[3], priv->id[4], priv->id[5]);
+ err:
+ return ret;
+ }
+--
+2.7.4
+
diff --git a/bsp/meta-rcar/meta-rcar-gen3-adas/recipes-kernel/linux/linux-renesas/0405-media-i2c-ov10640-fix-controls.patch b/bsp/meta-rcar/meta-rcar-gen3-adas/recipes-kernel/linux/linux-renesas/0405-media-i2c-ov10640-fix-controls.patch
new file mode 100644
index 00000000..179e28c7
--- /dev/null
+++ b/bsp/meta-rcar/meta-rcar-gen3-adas/recipes-kernel/linux/linux-renesas/0405-media-i2c-ov10640-fix-controls.patch
@@ -0,0 +1,70 @@
+From 9a56fad72e10479fb7ec44a9e871261daba75a18 Mon Sep 17 00:00:00 2001
+From: Vladimir Barinov <vladimir.barinov@cogentembedded.com>
+Date: Sat, 3 Aug 2019 01:34:49 +0300
+Subject: [PATCH] media: i2c: ov10640: fix controls
+
+This fixes v4l2 controls
+
+Signed-off-by: Vladimir Barinov <vladimir.barinov@cogentembedded.com>
+---
+ drivers/media/i2c/soc_camera/ov10640.c | 14 +++++++++-----
+ 1 file changed, 9 insertions(+), 5 deletions(-)
+
+diff --git a/drivers/media/i2c/soc_camera/ov10640.c b/drivers/media/i2c/soc_camera/ov10640.c
+index 31117e5..4ce6e15 100644
+--- a/drivers/media/i2c/soc_camera/ov10640.c
++++ b/drivers/media/i2c/soc_camera/ov10640.c
+@@ -320,7 +320,7 @@ static int ov10640_s_ctrl(struct v4l2_ctrl *ctrl)
+ case V4L2_CID_GAIN:
+ reg16_write(client, 0x30EC, ctrl->val); // L
+ reg16_write(client, 0x30EE, ctrl->val); // S
+- reg16_write(client, 0x30F0, ctrl->val); // VS
++ ret = reg16_write(client, 0x30F0, ctrl->val); // VS
+ break;
+ case V4L2_CID_ANALOGUE_GAIN:
+ reg16_read(client, 0x30EB, &val);
+@@ -328,7 +328,7 @@ static int ov10640_s_ctrl(struct v4l2_ctrl *ctrl)
+ val |= ((ctrl->val / 2) << 0); // L
+ val |= (ctrl->val << 2); // S
+ val |= ((ctrl->val / 2) << 4); // VS
+- reg16_write(client, 0x30EB, val);
++ ret = reg16_write(client, 0x30EB, val);
+ break;
+ case V4L2_CID_EXPOSURE:
+ val16 = 0xfff - ctrl->val;
+@@ -337,16 +337,18 @@ static int ov10640_s_ctrl(struct v4l2_ctrl *ctrl)
+ reg16_write(client, 0x30E7, val16 & 0xff); // L
+
+ reg16_write(client, 0x30E8, val16 >> 8); // S
+- reg16_write(client, 0x30E9, val16 & 0xff); // S
++ ret = reg16_write(client, 0x30E9, val16 & 0xff);// S
+
+-// reg16_write(client, 0x30EA, val >> 8); // VS - fractional ...
++// ret = reg16_write(client, 0x30EA, val >> 8); // VS - fractional ...
+ break;
++#if 0
+ case V4L2_CID_EXPOSURE_AUTO:
+ reg16_read(client, 0x30FA, &val);
+ val &= ~(0x1 << 6);
+ val |= (ctrl->val << 6);
+- reg16_write(client, 0x30FA, val);
++ ret = reg16_write(client, 0x30FA, val);
+ break;
++#endif
+ case V4L2_CID_HFLIP:
+ reg16_read(client, 0x3128, &val);
+ val &= ~(0x1 << 0);
+@@ -585,8 +587,10 @@ static int ov10640_probe(struct i2c_client *client,
+ V4L2_CID_ANALOGUE_GAIN, 0, 3, 1, 1);
+ v4l2_ctrl_new_std(&priv->hdl, &ov10640_ctrl_ops,
+ V4L2_CID_EXPOSURE, 0, 0xfff, 1, 0x448);
++#if 0
+ v4l2_ctrl_new_std(&priv->hdl, &ov10640_ctrl_ops,
+ V4L2_CID_EXPOSURE_AUTO, 0, 1, 1, 0);
++#endif
+ v4l2_ctrl_new_std(&priv->hdl, &ov10640_ctrl_ops,
+ V4L2_CID_HFLIP, 0, 1, 1, 1);
+ v4l2_ctrl_new_std(&priv->hdl, &ov10640_ctrl_ops,
+--
+2.7.4
+
diff --git a/bsp/meta-rcar/meta-rcar-gen3-adas/recipes-kernel/linux/linux-renesas/0406-Add-new-custom_ioctl-ops-for-soc-camera.patch b/bsp/meta-rcar/meta-rcar-gen3-adas/recipes-kernel/linux/linux-renesas/0406-Add-new-custom_ioctl-ops-for-soc-camera.patch
new file mode 100644
index 00000000..599b8a42
--- /dev/null
+++ b/bsp/meta-rcar/meta-rcar-gen3-adas/recipes-kernel/linux/linux-renesas/0406-Add-new-custom_ioctl-ops-for-soc-camera.patch
@@ -0,0 +1,58 @@
+From cf252d28e6db8fdcc6e21ae456835cdd3920b3ce Mon Sep 17 00:00:00 2001
+From: Petr Nechaev <petr.nechaev@cogentembedded.com>
+Date: Sat, 3 Aug 2019 00:39:57 +0300
+Subject: [PATCH] Add new custom_ioctl ops for soc camera
+
+It allows to implement custom ioctls in soc_camera host drivers.
+---
+ drivers/media/platform/soc_camera/soc_camera.c | 13 +++++++++++++
+ include/media/soc_camera.h | 2 ++
+ 2 files changed, 15 insertions(+)
+
+diff --git a/drivers/media/platform/soc_camera/soc_camera.c b/drivers/media/platform/soc_camera/soc_camera.c
+index 7e5ca15adb2b..80846832dd61 100644
+--- a/drivers/media/platform/soc_camera/soc_camera.c
++++ b/drivers/media/platform/soc_camera/soc_camera.c
+@@ -1075,6 +1075,18 @@ static int soc_camera_g_edid(struct file *file, void *fh,
+ return -ENOIOCTLCMD;
+ }
+
++static long soc_camera_default(struct file *file, void *fh,
++ bool valid_prio, unsigned int cmd, void *arg)
++{
++ struct soc_camera_device *icd = video_drvdata(file);
++ struct soc_camera_host *ici = to_soc_camera_host(icd->parent);
++
++ if (ici->ops->custom_ioctl)
++ return ici->ops->custom_ioctl(icd, valid_prio, cmd, arg);
++
++ return -ENOIOCTLCMD;
++}
++
+ #ifdef CONFIG_VIDEO_ADV_DEBUG
+ static int soc_camera_g_register(struct file *file, void *priv,
+ struct v4l2_dbg_register *reg)
+@@ -2092,6 +2104,7 @@ static const struct v4l2_ioctl_ops soc_camera_ioctl_ops = {
+ .vidioc_g_parm = soc_camera_g_parm,
+ .vidioc_s_parm = soc_camera_s_parm,
+ .vidioc_g_edid = soc_camera_g_edid,
++ .vidioc_default = soc_camera_default,
+ #ifdef CONFIG_VIDEO_ADV_DEBUG
+ .vidioc_g_register = soc_camera_g_register,
+ .vidioc_s_register = soc_camera_s_register,
+diff --git a/include/media/soc_camera.h b/include/media/soc_camera.h
+index 53c650d82b57..adcfadabcdc5 100644
+--- a/include/media/soc_camera.h
++++ b/include/media/soc_camera.h
+@@ -124,6 +124,8 @@ struct soc_camera_host_ops {
+ int (*enum_framesizes)(struct soc_camera_device *, struct v4l2_frmsizeenum *);
+ unsigned int (*poll)(struct file *, poll_table *);
+ int (*get_edid)(struct soc_camera_device *, struct v4l2_edid *);
++ long (*custom_ioctl)(struct soc_camera_device *, bool valid_prio,
++ unsigned int cmd, void *arg);
+ #ifdef CONFIG_VIDEO_ADV_DEBUG
+ int (*get_register)(struct soc_camera_device *, struct v4l2_dbg_register *reg);
+ int (*set_register)(struct soc_camera_device *, const struct v4l2_dbg_register *reg);
+--
+2.20.1
+
diff --git a/bsp/meta-rcar/meta-rcar-gen3-adas/recipes-kernel/linux/linux-renesas/0407-arm64-dts-renesas-r8a77970-v3msk-Fix-memory-size.patch b/bsp/meta-rcar/meta-rcar-gen3-adas/recipes-kernel/linux/linux-renesas/0407-arm64-dts-renesas-r8a77970-v3msk-Fix-memory-size.patch
new file mode 100644
index 00000000..d193d6e2
--- /dev/null
+++ b/bsp/meta-rcar/meta-rcar-gen3-adas/recipes-kernel/linux/linux-renesas/0407-arm64-dts-renesas-r8a77970-v3msk-Fix-memory-size.patch
@@ -0,0 +1,28 @@
+From 0eaccc1648824c2059d93d0395552efe5c057e38 Mon Sep 17 00:00:00 2001
+From: Valentine Barshak <valentine.barshak@cogentembedded.com>
+Date: Fri, 9 Aug 2019 01:36:33 +0300
+Subject: [PATCH] arm64: dts: renesas: r8a77970-v3msk: Fix memory size
+
+The V3MSK board has 2GB RAM according to the datasheet.
+
+Signed-off-by: Valentine Barshak <valentine.barshak@cogentembedded.com>
+---
+ arch/arm64/boot/dts/renesas/r8a77970-v3msk.dts | 2 +-
+ 1 file changed, 1 insertion(+), 1 deletion(-)
+
+diff --git a/arch/arm64/boot/dts/renesas/r8a77970-v3msk.dts b/arch/arm64/boot/dts/renesas/r8a77970-v3msk.dts
+index 107d041..d6deffe 100644
+--- a/arch/arm64/boot/dts/renesas/r8a77970-v3msk.dts
++++ b/arch/arm64/boot/dts/renesas/r8a77970-v3msk.dts
+@@ -25,7 +25,7 @@
+ memory@48000000 {
+ device_type = "memory";
+ /* first 128MB is reserved for secure area. */
+- reg = <0x0 0x48000000 0x0 0x38000000>;
++ reg = <0x0 0x48000000 0x0 0x78000000>;
+ };
+
+ reserved-memory {
+--
+2.7.4
+
diff --git a/bsp/meta-rcar/meta-rcar-gen3-adas/recipes-kernel/linux/linux-renesas/0408-arm64-dts-renesas-v3hsk-Add-GEther-PHY-GPIO-reset-pi.patch b/bsp/meta-rcar/meta-rcar-gen3-adas/recipes-kernel/linux/linux-renesas/0408-arm64-dts-renesas-v3hsk-Add-GEther-PHY-GPIO-reset-pi.patch
new file mode 100644
index 00000000..54e4762c
--- /dev/null
+++ b/bsp/meta-rcar/meta-rcar-gen3-adas/recipes-kernel/linux/linux-renesas/0408-arm64-dts-renesas-v3hsk-Add-GEther-PHY-GPIO-reset-pi.patch
@@ -0,0 +1,36 @@
+From 94eabe59e8f83cdd68ce763f3ce8a9e2533cc737 Mon Sep 17 00:00:00 2001
+From: Valentine Barshak <valentine.barshak@cogentembedded.com>
+Date: Tue, 13 Aug 2019 23:02:19 +0300
+Subject: [PATCH 1/3] arm64: dts: renesas: v3hsk: Add GEther PHY GPIO reset pin
+ support
+
+This adds "reset-gpios" property to the GEther PHY device tree node.
+
+Signed-off-by: Valentine Barshak <valentine.barshak@cogentembedded.com>
+---
+ arch/arm64/boot/dts/renesas/r8a77980-v3hsk.dts | 2 ++
+ 1 file changed, 2 insertions(+)
+
+diff --git a/arch/arm64/boot/dts/renesas/r8a77980-v3hsk.dts b/arch/arm64/boot/dts/renesas/r8a77980-v3hsk.dts
+index f52dc2d..9e907b9 100644
+--- a/arch/arm64/boot/dts/renesas/r8a77980-v3hsk.dts
++++ b/arch/arm64/boot/dts/renesas/r8a77980-v3hsk.dts
+@@ -8,6 +8,7 @@
+
+ /dts-v1/;
+ #include "r8a77980.dtsi"
++#include <dt-bindings/gpio/gpio.h>
+
+ / {
+ model = "Renesas V3H Starter Kit board";
+@@ -150,6 +151,7 @@
+ reg = <0>;
+ interrupt-parent = <&gpio4>;
+ interrupts = <23 IRQ_TYPE_LEVEL_LOW>;
++ reset-gpios = <&gpio4 22 GPIO_ACTIVE_LOW>;
+ };
+ };
+
+--
+2.7.4
+
diff --git a/bsp/meta-rcar/meta-rcar-gen3-adas/recipes-kernel/linux/linux-renesas/0409-arm64-dts-renesas-condor-Add-GEther-PHY-GPIO-reset-p.patch b/bsp/meta-rcar/meta-rcar-gen3-adas/recipes-kernel/linux/linux-renesas/0409-arm64-dts-renesas-condor-Add-GEther-PHY-GPIO-reset-p.patch
new file mode 100644
index 00000000..a3baca8e
--- /dev/null
+++ b/bsp/meta-rcar/meta-rcar-gen3-adas/recipes-kernel/linux/linux-renesas/0409-arm64-dts-renesas-condor-Add-GEther-PHY-GPIO-reset-p.patch
@@ -0,0 +1,28 @@
+From 96c4aea87df924d7430957b9c37eac5f200e382a Mon Sep 17 00:00:00 2001
+From: Valentine Barshak <valentine.barshak@cogentembedded.com>
+Date: Tue, 13 Aug 2019 23:04:03 +0300
+Subject: [PATCH 2/3] arm64: dts: renesas: condor: Add GEther PHY GPIO reset
+ pin support
+
+This adds "reset-gpios" property to the GEther PHY device tree node.
+
+Signed-off-by: Valentine Barshak <valentine.barshak@cogentembedded.com>
+---
+ arch/arm64/boot/dts/renesas/r8a77980-condor.dts | 1 +
+ 1 file changed, 1 insertion(+)
+
+diff --git a/arch/arm64/boot/dts/renesas/r8a77980-condor.dts b/arch/arm64/boot/dts/renesas/r8a77980-condor.dts
+index e21dadd..f98a25e 100644
+--- a/arch/arm64/boot/dts/renesas/r8a77980-condor.dts
++++ b/arch/arm64/boot/dts/renesas/r8a77980-condor.dts
+@@ -145,6 +145,7 @@
+ reg = <0>;
+ interrupt-parent = <&gpio1>;
+ interrupts = <17 IRQ_TYPE_LEVEL_LOW>;
++ reset-gpios = <&gpio4 22 GPIO_ACTIVE_LOW>;
+ };
+ };
+
+--
+2.7.4
+
diff --git a/bsp/meta-rcar/meta-rcar-gen3-adas/recipes-kernel/linux/linux-renesas/0410-arm64-dts-renesas-eagle-Add-RAVB-PHY-GPIO-reset-pin-.patch b/bsp/meta-rcar/meta-rcar-gen3-adas/recipes-kernel/linux/linux-renesas/0410-arm64-dts-renesas-eagle-Add-RAVB-PHY-GPIO-reset-pin-.patch
new file mode 100644
index 00000000..c4c3b018
--- /dev/null
+++ b/bsp/meta-rcar/meta-rcar-gen3-adas/recipes-kernel/linux/linux-renesas/0410-arm64-dts-renesas-eagle-Add-RAVB-PHY-GPIO-reset-pin-.patch
@@ -0,0 +1,28 @@
+From 587b37dfb949accafc981f9c6f6b1a245f940ab6 Mon Sep 17 00:00:00 2001
+From: Valentine Barshak <valentine.barshak@cogentembedded.com>
+Date: Tue, 13 Aug 2019 23:05:00 +0300
+Subject: [PATCH 3/3] arm64: dts: renesas: eagle: Add RAVB PHY GPIO reset pin
+ support
+
+This adds "gpio-resets" property to the RAVB PHY device tree node.
+
+Signed-off-by: Valentine Barshak <valentine.barshak@cogentembedded.com>
+---
+ arch/arm64/boot/dts/renesas/r8a77970-eagle.dts | 1 +
+ 1 file changed, 1 insertion(+)
+
+diff --git a/arch/arm64/boot/dts/renesas/r8a77970-eagle.dts b/arch/arm64/boot/dts/renesas/r8a77970-eagle.dts
+index 7525bc9..706d75e 100644
+--- a/arch/arm64/boot/dts/renesas/r8a77970-eagle.dts
++++ b/arch/arm64/boot/dts/renesas/r8a77970-eagle.dts
+@@ -132,6 +132,7 @@
+ reg = <0>;
+ interrupt-parent = <&gpio1>;
+ interrupts = <17 IRQ_TYPE_LEVEL_LOW>;
++ reset-gpios = <&gpio1 16 GPIO_ACTIVE_LOW>;
+ };
+ };
+
+--
+2.7.4
+
diff --git a/bsp/meta-rcar/meta-rcar-gen3-adas/recipes-kernel/linux/linux-renesas/0411-media-soc_camera-add-MAX9288-support.patch b/bsp/meta-rcar/meta-rcar-gen3-adas/recipes-kernel/linux/linux-renesas/0411-media-soc_camera-add-MAX9288-support.patch
new file mode 100644
index 00000000..78712a42
--- /dev/null
+++ b/bsp/meta-rcar/meta-rcar-gen3-adas/recipes-kernel/linux/linux-renesas/0411-media-soc_camera-add-MAX9288-support.patch
@@ -0,0 +1,956 @@
+From 21d57c5af828faddf2bea88a1dc3715a936ffe5d Mon Sep 17 00:00:00 2001
+From: Vladimir Barinov <vladimir.barinov@cogentembedded.com>
+Date: Wed, 14 Aug 2019 14:15:02 +0300
+Subject: [PATCH 1/3] media: soc_camera: add MAX9288 support
+
+This adds MAX9288 deserializer support
+
+Signed-off-by: Vladimir Barinov <vladimir.barinov@cogentembedded.com>
+---
+ drivers/media/i2c/soc_camera/Kconfig | 6 +
+ drivers/media/i2c/soc_camera/Makefile | 1 +
+ drivers/media/i2c/soc_camera/max9286.h | 57 +-
+ drivers/media/i2c/soc_camera/max9288.c | 747 +++++++++++++++++++++++++++
+ drivers/media/platform/soc_camera/rcar_vin.c | 19 +-
+ 5 files changed, 779 insertions(+), 51 deletions(-)
+ create mode 100644 drivers/media/i2c/soc_camera/max9288.c
+
+diff --git a/drivers/media/i2c/soc_camera/Kconfig b/drivers/media/i2c/soc_camera/Kconfig
+index edff0b0..729b5af 100644
+--- a/drivers/media/i2c/soc_camera/Kconfig
++++ b/drivers/media/i2c/soc_camera/Kconfig
+@@ -89,6 +89,12 @@ config SOC_CAMERA_MAX9286
+ help
+ This is a MAXIM max9286 GMSL driver
+
++config SOC_CAMERA_MAX9288
++ tristate "max9288 GMSL support"
++ depends on SOC_CAMERA && I2C
++ help
++ This is a MAXIM max9288 GMSL driver
++
+ config SOC_CAMERA_TI9X4
+ tristate "ti9x4 FPDLink3 support"
+ depends on SOC_CAMERA && I2C
+diff --git a/drivers/media/i2c/soc_camera/Makefile b/drivers/media/i2c/soc_camera/Makefile
+index 367674b..7bbcaaa 100644
+--- a/drivers/media/i2c/soc_camera/Makefile
++++ b/drivers/media/i2c/soc_camera/Makefile
+@@ -12,6 +12,7 @@ obj-$(CONFIG_SOC_CAMERA_OV9740) += ov9740.o
+ obj-$(CONFIG_SOC_CAMERA_RJ54N1) += rj54n1cb0c.o
+ obj-$(CONFIG_SOC_CAMERA_TW9910) += tw9910.o
+ obj-$(CONFIG_SOC_CAMERA_MAX9286) += max9286.o
++obj-$(CONFIG_SOC_CAMERA_MAX9288) += max9288.o
+ obj-$(CONFIG_SOC_CAMERA_TI9X4) += ti9x4.o
+ obj-$(CONFIG_SOC_CAMERA_OV106XX) += ov106xx.o
+ obj-$(CONFIG_SOC_CAMERA_IMX219) += imx219.o
+diff --git a/drivers/media/i2c/soc_camera/max9286.h b/drivers/media/i2c/soc_camera/max9286.h
+index 2875b3c..23ed035 100644
+--- a/drivers/media/i2c/soc_camera/max9286.h
++++ b/drivers/media/i2c/soc_camera/max9286.h
+@@ -1,7 +1,7 @@
+ /*
+- * MAXIM max9286-max9271 GMSL driver include file
++ * MAXIM max9286/max9288 GMSL driver include file
+ *
+- * Copyright (C) 2015-2017 Cogent Embedded, Inc.
++ * Copyright (C) 2015-2019 Cogent Embedded, Inc.
+ *
+ * This program is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License as published by the
+@@ -9,8 +9,8 @@
+ * option) any later version.
+ */
+
+-#ifndef _MAX9286_MAX9271_H
+-#define _MAX9286_MAX9271_H
++#ifndef _MAX92XX_H
++#define _MAX92XX_H
+
+ //#define DEBUG
+ #ifdef DEBUG
+@@ -26,6 +26,8 @@
+ #define MAX96705_ID 0x41
+ #define MAX96707_ID 0x45 /* MAX96715: there is no HS pin */
+ #define MAX9286_ID 0x40
++#define MAX9288_ID 0x2A
++#define MAX9290_ID 0x2C
+ #define BROADCAST 0x6f
+
+ static inline int reg8_read(struct i2c_client *client, u8 reg, u8 *val)
+@@ -177,52 +179,7 @@ static inline int reg16_write16(struct i2c_client *client, u16 reg, u16 val)
+ return ret < 0 ? ret : 0;
+ }
+
+-
+ #ifdef MAXIM_DUMP
+-static void maxim_ovsensor_dump_regs(struct i2c_client *client)
+-{
+- int ret, i;
+- u8 val = 0;
+- u16 regs[] = {0x300a, 0x300b, 0x300c};
+-
+- dev_dbg(&client->dev, "dump regs 0x%x\n", client->addr);
+-
+- for (i = 0; i < sizeof(regs) / 2; i++) {
+- ret = reg16_read(client, regs[i], &val);
+- if (ret < 0)
+- dev_err(&client->dev,
+- "read fail: chip 0x%x register 0x%02x: %d\n",
+- client->addr, regs[i], ret);
+- printk("0x%02x -> 0x%x\n", regs[i], val);
+- }
+-}
+-
+-static void maxim_ov10635_dump_format_regs(struct i2c_client *client)
+-{
+- int ret, i;
+- u8 val;
+- u16 regs[] = {0x3003, 0x3004, 0x4300,
+- 0x4605, 0x3621, 0x3702, 0x3703, 0x3704,
+- 0x3802, 0x3803, 0x3806, 0x3807, 0x3808, 0x3809, 0x380a,
+- 0x380b, 0x380c, 0x380d, 0x380e, 0x380f,
+- 0x4606, 0x4607, 0x460a, 0x460b,
+- 0xc488, 0xc489, 0xc48a, 0xc48b,
+- 0xc4cc, 0xc4cd, 0xc4ce, 0xc4cf, 0xc512, 0xc513,
+- 0xc518, 0xc519, 0xc51a, 0xc51b,
+- };
+-
+- dev_dbg(&client->dev, "dump regs 0x%x\n", client->addr);
+-
+- for (i = 0; i < sizeof(regs) / 2; i++) {
+- ret = reg16_read(client, regs[i], &val);
+- if (ret < 0)
+- dev_err(&client->dev,
+- "read fail: chip 0x%x register 0x%02x: %d\n",
+- client->addr, regs[i], ret);
+- printk("0x%02x -> 0x%x\n", regs[i], val);
+- }
+-}
+-
+ static void maxim_max927x_dump_regs(struct i2c_client *client)
+ {
+ int ret;
+@@ -242,4 +199,4 @@ static void maxim_max927x_dump_regs(struct i2c_client *client)
+ }
+ }
+ #endif /* MAXIM_DUMP */
+-#endif /* _MAX9286_MAX9271_H */
++#endif /* _MAX92XX_H */
+diff --git a/drivers/media/i2c/soc_camera/max9288.c b/drivers/media/i2c/soc_camera/max9288.c
+new file mode 100644
+index 0000000..dd57074
+--- /dev/null
++++ b/drivers/media/i2c/soc_camera/max9288.c
+@@ -0,0 +1,747 @@
++/*
++ * MAXIM max9288 GMSL driver
++ *
++ * Copyright (C) 2019 Cogent Embedded, Inc.
++ *
++ * This program is free software; you can redistribute it and/or modify it
++ * under the terms of the GNU General Public License as published by the
++ * Free Software Foundation; either version 2 of the License, or (at your
++ * option) any later version.
++ */
++
++#include <linux/delay.h>
++#include <linux/i2c.h>
++#include <linux/module.h>
++#include <linux/notifier.h>
++#include <linux/of_gpio.h>
++#include <linux/of_graph.h>
++#include <linux/videodev2.h>
++
++#include <media/v4l2-common.h>
++#include <media/v4l2-device.h>
++#include <media/v4l2-subdev.h>
++
++#include "max9286.h"
++
++#define MAXIM_I2C_I2C_SPEED_837KHZ (0x7 << 2) /* 837kbps */
++#define MAXIM_I2C_I2C_SPEED_533KHZ (0x6 << 2) /* 533kbps */
++#define MAXIM_I2C_I2C_SPEED_339KHZ (0x5 << 2) /* 339 kbps */
++#define MAXIM_I2C_I2C_SPEED_173KHZ (0x4 << 2) /* 174kbps */
++#define MAXIM_I2C_I2C_SPEED_105KHZ (0x3 << 2) /* 105 kbps */
++#define MAXIM_I2C_I2C_SPEED_085KHZ (0x2 << 2) /* 84.7 kbps */
++#define MAXIM_I2C_I2C_SPEED_028KHZ (0x1 << 2) /* 28.3 kbps */
++#define MAXIM_I2C_I2C_SPEED MAXIM_I2C_I2C_SPEED_339KHZ
++
++struct max9288_priv {
++ struct v4l2_subdev sd;
++ struct fwnode_handle *sd_fwnode;
++ int des_addr;
++ int lanes;
++ int csi_rate;
++ int pclk;
++ char pclk_rising_edge;
++ int gpio_resetb;
++ int active_low_resetb;
++ int him;
++ int hsync;
++ int vsync;
++ int timeout;
++ int poc_delay;
++ int bws;
++ int dbl;
++ int dt;
++ int hsgen;
++ int hts;
++ int vts;
++ int hts_delay;
++ struct i2c_client *client;
++ int max9271_addr;
++ int ser_id;
++ struct gpio_desc *poc_gpio; /* PoC power supply */
++};
++
++static int conf_link;
++module_param(conf_link, int, 0644);
++MODULE_PARM_DESC(conf_link, " Force configuration link. Used only if robust firmware flashing required (f.e. recovery)");
++
++static int poc_trig;
++module_param(poc_trig, int, 0644);
++MODULE_PARM_DESC(poc_trig, " Use PoC triggering during reverse channel setup. Useful on systems with dedicated PoC and unstable ser-des lock");
++
++static int him = 0;
++module_param(him, int, 0644);
++MODULE_PARM_DESC(him, " Use High-Immunity mode (default: leagacy mode)");
++
++static int hsync;
++module_param(hsync, int, 0644);
++MODULE_PARM_DESC(hsync, " HSYNC invertion (default: 0 - not inverted)");
++
++static int vsync = 1;
++module_param(vsync, int, 0644);
++MODULE_PARM_DESC(vsync, " VSYNC invertion (default: 1 - inverted)");
++
++static int gpio_resetb;
++module_param(gpio_resetb, int, 0644);
++MODULE_PARM_DESC(gpio_resetb, " Serializer GPIO reset (default: 0 - not used)");
++
++static int active_low_resetb;
++module_param(active_low_resetb, int, 0644);
++MODULE_PARM_DESC(active_low_resetb, " Serializer GPIO reset level (default: 0 - active high)");
++
++static int timeout_n = 100;
++module_param(timeout_n, int, 0644);
++MODULE_PARM_DESC(timeout_n, " Timeout of link detection (default: 100 retries)");
++
++static int poc_delay = 50;
++module_param(poc_delay, int, 0644);
++MODULE_PARM_DESC(poc_delay, " Delay in ms after POC enable (default: 50 ms)");
++
++static int bws = 0;
++module_param(bws, int, 0644);
++MODULE_PARM_DESC(bws, " BWS mode (default: 0 - 24-bit gmsl packets)");
++
++static int dbl = 1;
++module_param(dbl, int, 0644);
++MODULE_PARM_DESC(dbl, " DBL mode (default: 1 - DBL mode enabled)");
++
++static int dt = 3;
++module_param(dt, int, 0644);
++MODULE_PARM_DESC(dt, " DataType (default: 3 - YUV8), 0 - RGB888, 5 - RAW8, 6 - RAW10, 7 - RAW12, 8 - RAW14");
++
++static int hsgen;
++module_param(hsgen, int, 0644);
++MODULE_PARM_DESC(hsgen, " Enable HS embedded generator (default: 0 - disabled)");
++
++static int pclk = 100;
++module_param(pclk, int, 0644);
++MODULE_PARM_DESC(pclk, " PCLK rate (default: 100MHz)");
++
++enum {
++ RGB888_DT = 0,
++ RGB565_DT,
++ RGB666_DT,
++ YUV8_DT, /* default */
++ YUV10_DT,
++ RAW8_DT,
++ RAW10_DT,
++ RAW12_DT,
++ RAW14_DT,
++};
++
++static int dt2bpp [9] = {
++ 24, /* RGB888 */
++ 16, /* RGB565 */
++ 18, /* RGB666 */
++ 8, /* YUV8 - default */
++ 10, /* YUV10 */
++ 8, /* RAW8/RAW16 */
++ 10, /* RAW10 */
++ 12, /* RAW12 */
++ 14, /* RAW14 */
++};
++
++static char* ser_name(int id)
++{
++ switch (id) {
++ case MAX9271_ID:
++ return "MAX9271";
++ case MAX96705_ID:
++ return "MAX96705";
++ case MAX96707_ID:
++ return "MAX96707";
++ default:
++ return "unknown";
++ }
++}
++
++static void max9288_preinit(struct i2c_client *client, int addr)
++{
++
++ struct max9288_priv *priv = i2c_get_clientdata(client);
++
++ client->addr = addr; /* MAX9288-CAMx I2C */
++ reg8_write(client, 0x04, 0x00); /* disable reverse control */
++ reg8_write(client, 0x16, (priv->him ? 0x80 : 0x00) |
++ 0x5a); /* high-immunity/legacy mode */
++}
++
++static void max9288_sensor_reset(struct i2c_client *client, int addr, int reset_on)
++{
++ struct max9288_priv *priv = i2c_get_clientdata(client);
++
++ if (priv->gpio_resetb < 1 || priv->gpio_resetb > 5)
++ return;
++
++ /* sensor reset/unreset */
++ client->addr = addr; /* MAX9271-CAMx I2C */
++ reg8_write(client, 0x0f, (0xfe & ~BIT(priv->gpio_resetb)) | /* set GPIOn value to reset/unreset */
++ ((priv->active_low_resetb ? BIT(priv->gpio_resetb) : 0) ^ reset_on));
++ reg8_write(client, 0x0e, 0x42 | BIT(priv->gpio_resetb)); /* set GPIOn direction output */
++}
++
++static int max9288_reverse_channel_setup(struct i2c_client *client)
++{
++ struct max9288_priv *priv = i2c_get_clientdata(client);
++ u8 val = 0, lock_sts = 0;
++ int timeout = priv->timeout;
++ char timeout_str[40];
++ int ret = 0;
++
++ /* Reverse channel enable */
++ client->addr = priv->des_addr; /* MAX9288-CAMx I2C */
++ reg8_write(client, 0x1c, 0xa2 | MAXIM_I2C_I2C_SPEED); /* enable artificial ACKs, I2C speed set */
++ usleep_range(2000, 2500); /* wait 2ms after any change of reverse channel settings */
++ reg8_write(client, 0x04, 0x03); /* enable reverse control */
++ usleep_range(2000, 2500); /* wait 2ms after any change of reverse channel settings */
++
++ for (;;) {
++ if (priv->him) {
++ /* HIM mode setup */
++ client->addr = 0x40; /* MAX9271-CAMx I2C */
++ reg8_write(client, 0x4d, 0xc0);
++ usleep_range(2000, 2500); /* wait 2ms after any change of reverse channel settings */
++ reg8_write(client, 0x04, 0x43); /* wake-up, enable reverse_control/conf_link */
++ usleep_range(2000, 2500); /* wait 2ms after any change of reverse channel settings */
++ if (priv->bws) {
++ reg8_write(client, 0x07, (priv->pclk_rising_edge ? 0 : 0x10) |
++ (priv->dbl ? 0x80 : 0) |
++ (priv->bws ? 0x20 : 0)); /* RAW/YUV, PCLK edge, HS/VS disabled enabled, DBL mode, BWS 24/32-bit */
++ usleep_range(2000, 2500); /* wait 2ms after any change of reverse channel settings */
++ }
++ } else {
++ /* Legacy mode setup */
++ client->addr = priv->des_addr; /* MAX9288-CAMx I2C */
++ reg8_write(client, 0x13, 0x00);
++ reg8_write(client, 0x11, 0x42); /* enable custom reverse channel & first pulse length */
++ reg8_write(client, 0x0a, 0x0f); /* first pulse length rise time changed from 300ns to 200ns, amplitude 100mV */
++ usleep_range(2000, 2500); /* wait 2ms after any change of reverse channel settings */
++
++ client->addr = 0x40; /* MAX9271-CAMx I2C */
++ reg8_write(client, 0x04, 0x43); /* wake-up, enable reverse_control/conf_link */
++ usleep_range(2000, 2500); /* wait 2ms after any change of reverse channel settings */
++ reg8_write(client, 0x08, 0x01); /* reverse channel receiver high threshold enable */
++ usleep_range(2000, 2500); /* wait 2ms after any change of reverse channel settings */
++ if (priv->bws) {
++ reg8_write(client, 0x07, (priv->pclk_rising_edge ? 0 : 0x10) |
++ (priv->dbl ? 0x80 : 0) |
++ (priv->bws ? 0x20 : 0)); /* RAW/YUV, PCLK edge, HS/VS encoding disabled, DBL mode, BWS 24/32-bit */
++ usleep_range(2000, 2500); /* wait 2ms after any change of reverse channel settings */
++ }
++ reg8_write(client, 0x97, 0x5f); /* enable reverse control channel programming (MAX96705-MAX96711 only) */
++ usleep_range(2000, 2500); /* wait 2ms after any change of reverse channel settings */
++
++ client->addr = priv->des_addr; /* MAX9288-CAMx I2C */
++ reg8_write(client, 0x0a, 0x0c); /* first pulse length rise time changed from 300ns to 200ns, amplitude 100mV */
++ reg8_write(client, 0x13, 0x20); /* reverse channel increase amplitude 170mV to compensate high threshold enabled */
++ usleep_range(2000, 2500); /* wait 2ms after any change of reverse channel settings */
++ }
++
++ client->addr = 0x40; /* MAX9271-CAMx I2C */
++ reg8_read(client, 0x1e, &val); /* read max9271 ID */
++ if (val == MAX9271_ID || val == MAX96705_ID || val == MAX96707_ID || --timeout == 0) {
++ priv->ser_id = val;
++ break;
++ }
++
++ /* Check if already initialized (after reboot/reset ?) */
++ client->addr = priv->max9271_addr; /* MAX9271-CAMx I2C */
++ reg8_read(client, 0x1e, &val); /* read max9271 ID */
++ if (val == MAX9271_ID || val == MAX96705_ID || val == MAX96707_ID) {
++ priv->ser_id = val;
++ reg8_write(client, 0x04, 0x43); /* enable reverse_control/conf_link */
++ usleep_range(2000, 2500); /* wait 2ms after any change of reverse channel settings */
++ ret = -EADDRINUSE;
++ break;
++ }
++
++ if (poc_trig) {
++ if (!IS_ERR(priv->poc_gpio) && (timeout % poc_trig == 0)) {
++ gpiod_direction_output(priv->poc_gpio, 0); /* POC power off */
++ mdelay(200);
++ gpiod_direction_output(priv->poc_gpio, 1); /* POC power on */
++ mdelay(priv->poc_delay);
++ }
++ }
++ }
++
++ max9288_sensor_reset(client, client->addr, 1); /* sensor reset */
++
++ client->addr = priv->des_addr; /* MAX9288-CAMx I2C */
++ reg8_read(client, 0x04, &lock_sts); /* LOCK status */
++
++ if (!timeout) {
++ ret = -ETIMEDOUT;
++ goto out;
++ }
++
++out:
++ sprintf(timeout_str, "retries=%d lock_sts=%d", priv->timeout - timeout, !!(lock_sts & 0x80));
++ dev_info(&client->dev, "link %s %sat 0x%x %s %s\n", ser_name(priv->ser_id),
++ ret == -EADDRINUSE ? "already " : "", priv->max9271_addr,
++ ret == -ETIMEDOUT ? "not found: timeout GMSL link establish" : "",
++ priv->timeout - timeout ? timeout_str : "");
++
++ return ret;
++}
++
++static void max9288_initial_setup(struct i2c_client *client)
++{
++ struct max9288_priv *priv = i2c_get_clientdata(client);
++
++ /* Initial setup */
++ client->addr = priv->des_addr; /* MAX9288-CAMx I2C */
++ reg8_write(client, 0x09, 0x40); /* Automatic pixel count enable */
++ reg8_write(client, 0x15, 0x70); /* Enable HV and DE tracking by register 0x69 */
++ reg8_write(client, 0x60, (priv->dbl ? 0x20 : 0) |
++ (priv->dt & 0xf)); /* VC=0, DBL mode, DataType */
++ reg8_write(client, 0x65, 0x47 | ((priv->lanes - 1) << 4)); /* setup CSI lanes, DE input is HS */
++
++ reg8_write(client, 0x08, 0x20); /* use D18/19 for HS/VS */
++ reg8_write(client, 0x14, (priv->vsync ? 0x80 : 0) | (priv->hsync ? 0x40 : 0)); /* setup HS/VS inversion */
++ reg8_write(client, 0x64, 0x0c); /* Drive HSTRAIL state for 120ns after the last payload bit */
++}
++
++static void max9288_gmsl_link_setup(struct i2c_client *client)
++{
++ struct max9288_priv *priv = i2c_get_clientdata(client);
++
++ /* GMSL setup */
++ client->addr = 0x40; /* MAX9271-CAMx I2C */
++ reg8_write(client, 0x0d, 0x22 | MAXIM_I2C_I2C_SPEED); /* disable artificial ACK, I2C speed set */
++ reg8_write(client, 0x07, (priv->pclk_rising_edge ? 0 : 0x10) |
++ (priv->dbl ? 0x80 : 0) |
++ (priv->bws ? 0x20 : 0)); /* RAW/YUV, PCLK edge, HS/VS encoding disabled, DBL mode, BWS 24/32-bit */
++ usleep_range(2000, 2500); /* wait 2ms */
++ reg8_write(client, 0x02, 0xff); /* spread spectrum +-4%, pclk range automatic, Gbps automatic */
++ usleep_range(2000, 2500); /* wait 2ms */
++
++ if (priv->ser_id == MAX96705_ID || priv->ser_id == MAX96707_ID) {
++ switch (priv->dt) {
++ case YUV8_DT:
++ /* setup crossbar for YUV8/RAW8: reverse DVP bus */
++ reg8_write(client, 0x20, 3);
++ reg8_write(client, 0x21, 4);
++ reg8_write(client, 0x22, 5);
++ reg8_write(client, 0x23, 6);
++ reg8_write(client, 0x24, 7);
++ reg8_write(client, 0x25, 0x40);
++ reg8_write(client, 0x26, 0x40);
++ if (priv->ser_id == MAX96705_ID) {
++ reg8_write(client, 0x27, 14); /* HS: D14->D18 */
++ reg8_write(client, 0x28, 15); /* VS: D15->D19 */
++ }
++ if (priv->ser_id == MAX96707_ID) {
++ reg8_write(client, 0x27, 14); /* HS: D14->D18, this is a virtual NC pin, hence it is D14 at HS */
++ reg8_write(client, 0x28, 13); /* VS: D13->D19 */
++ }
++ reg8_write(client, 0x29, 0x40);
++ reg8_write(client, 0x2A, 0x40);
++
++ /* this is second byte if DBL=1 */
++ reg8_write(client, 0x30, 0x10 + 0);
++ reg8_write(client, 0x31, 0x10 + 1);
++ reg8_write(client, 0x32, 0x10 + 2);
++ reg8_write(client, 0x33, 0x10 + 3);
++ reg8_write(client, 0x34, 0x10 + 4);
++ reg8_write(client, 0x35, 0x10 + 5);
++ reg8_write(client, 0x36, 0x10 + 6);
++ reg8_write(client, 0x37, 0x10 + 7);
++ reg8_write(client, 0x38, 0);
++ reg8_write(client, 0x39, 1);
++ reg8_write(client, 0x3A, 2);
++
++ reg8_write(client, 0x67, 0xC4); /* DBL_ALIGN_TO = 100b */
++
++ break;
++ case RAW12_DT:
++#if 0 /* Not supported yet */
++ /* setup crossbar for RAW12: reverse DVP bus */
++ reg8_write(client, 0x20, 11);
++ reg8_write(client, 0x21, 10);
++ reg8_write(client, 0x22, 9);
++ reg8_write(client, 0x23, 8);
++ reg8_write(client, 0x24, 7);
++ reg8_write(client, 0x25, 6);
++ reg8_write(client, 0x26, 5);
++ reg8_write(client, 0x27, 4);
++ reg8_write(client, 0x28, 3);
++ reg8_write(client, 0x29, 2);
++ reg8_write(client, 0x2a, 1);
++ reg8_write(client, 0x2b, 0);
++
++ /* this is second byte if DBL=1 */
++ reg8_write(client, 0x30, 27);
++ reg8_write(client, 0x31, 26);
++ reg8_write(client, 0x32, 25);
++ reg8_write(client, 0x33, 24);
++ reg8_write(client, 0x34, 23);
++ reg8_write(client, 0x35, 22);
++ reg8_write(client, 0x36, 21);
++ reg8_write(client, 0x37, 20);
++ reg8_write(client, 0x38, 19);
++ reg8_write(client, 0x39, 18);
++ reg8_write(client, 0x3a, 17);
++ reg8_write(client, 0x3b, 16);
++
++ if (!priv->bws && priv->dbl)
++ dev_err(&client->dev, " BWS must be 27/32-bit for RAW12 in DBL mode\n");
++#endif
++ break;
++ }
++
++ if (priv->hsgen) {
++ /* HS/VS pins map */
++ reg8_write(client, 0x3f, 0x10); /* HS (NC) */
++ reg8_write(client, 0x41, 0x10); /* DE (NC) */
++ if (priv->ser_id == MAX96705_ID)
++ reg8_write(client, 0x40, 15); /* VS (DIN13) */
++ if (priv->ser_id == MAX96707_ID)
++ reg8_write(client, 0x40, 13); /* VS (DIN13) */
++#if 0
++ /* following must come from imager */
++#define SENSOR_WIDTH (1280*2)
++#define HTS (1288*2)
++#define VTS 960
++#define HTS_DELAY 0x9
++ reg8_write(client, 0x4e, HTS_DELAY >> 16); /* HS delay */
++ reg8_write(client, 0x4f, (HTS_DELAY >> 8) & 0xff);
++ reg8_write(client, 0x50, HTS_DELAY & 0xff);
++ reg8_write(client, 0x54, SENSOR_WIDTH >> 8); /* HS high period */
++ reg8_write(client, 0x55, SENSOR_WIDTH & 0xff);
++ reg8_write(client, 0x56, (HTS - SENSOR_WIDTH) >> 8); /* HS low period */
++ reg8_write(client, 0x57, (HTS - SENSOR_WIDTH) & 0xff);
++ reg8_write(client, 0x58, VTS >> 8); /* HS count */
++ reg8_write(client, 0x59, VTS & 0xff );
++#endif
++ reg8_write(client, 0x43, 0x15); /* enable HS generator */
++ }
++ }
++
++ client->addr = priv->des_addr; /* MAX9288-CAMx I2C */
++ reg8_write(client, 0x1c, 0x22 | MAXIM_I2C_I2C_SPEED); /* disable artificial ACK, I2C speed set */
++ usleep_range(2000, 2500); /* wait 2ms */
++
++ /* I2C translator setup */
++ client->addr = 0x40; /* MAX9271-CAMx I2C */
++// reg8_write(client, 0x09, maxim_map[2][idx] << 1); /* SENSOR I2C translated - must be set by sensor driver */
++// reg8_write(client, 0x0A, 0x30 << 1); /* SENSOR I2C native - must be set by sensor driver */
++ reg8_write(client, 0x0B, BROADCAST << 1); /* broadcast I2C */
++ reg8_write(client, 0x0C, priv->max9271_addr << 1); /* MAX9271-CAMx I2C new */
++ /* I2C addresse change */
++ reg8_write(client, 0x01, priv->des_addr << 1); /* MAX9288 I2C */
++ reg8_write(client, 0x00, priv->max9271_addr << 1); /* MAX9271-CAM0 I2C new */
++ usleep_range(2000, 2500); /* wait 2ms */
++ /* put MAX9271 in configuration link state */
++ client->addr = priv->max9271_addr; /* MAX9271-CAMx I2C new */
++ reg8_write(client, 0x04, 0x43); /* enable reverse_control/conf_link */
++ usleep_range(2000, 2500); /* wait 2ms */
++#ifdef MAXIM_DUMP
++ client->addr = priv->des_addr; /* MAX9288-CAMx I2C */
++ maxim_max927x_dump_regs(client);
++ client->addr = priv->max9271_addr; /* MAX9271-CAMx I2C new */
++ maxim_max927x_dump_regs(client);
++#endif
++}
++
++static int max9288_initialize(struct i2c_client *client)
++{
++ struct max9288_priv *priv = i2c_get_clientdata(client);
++
++ dev_info(&client->dev, "LANES=%d, PCLK edge=%s\n",
++ priv->lanes, priv->pclk_rising_edge ? "rising" : "falling");
++
++ max9288_preinit(client, priv->des_addr);
++ max9288_initial_setup(client);
++
++ if (!IS_ERR(priv->poc_gpio)) {
++ gpiod_direction_output(priv->poc_gpio, 1); /* POC power on */
++ mdelay(priv->poc_delay);
++ }
++
++ max9288_reverse_channel_setup(client);
++ max9288_gmsl_link_setup(client);
++
++ client->addr = priv->des_addr;
++
++ return 0;
++}
++
++#ifdef CONFIG_VIDEO_ADV_DEBUG
++static int max9288_g_register(struct v4l2_subdev *sd,
++ struct v4l2_dbg_register *reg)
++{
++ struct max9288_priv *priv = v4l2_get_subdevdata(sd);
++ struct i2c_client *client = priv->client;
++ int ret;
++ u8 val = 0;
++
++ ret = reg8_read(client, (u8)reg->reg, &val);
++ if (ret < 0)
++ return ret;
++
++ reg->val = val;
++ reg->size = sizeof(u8);
++
++ return 0;
++}
++
++static int max9288_s_register(struct v4l2_subdev *sd,
++ const struct v4l2_dbg_register *reg)
++{
++ struct max9288_priv *priv = v4l2_get_subdevdata(sd);
++ struct i2c_client *client = priv->client;
++
++ return reg8_write(client, (u8)reg->reg, (u8)reg->val);
++}
++#endif
++
++static int max9288_s_power(struct v4l2_subdev *sd, int on)
++{
++ struct max9288_priv *priv = v4l2_get_subdevdata(sd);
++ struct i2c_client *client = priv->client;
++
++ client->addr = priv->max9271_addr; /* MAX9271-CAMx I2C new */
++ reg8_write(client, 0x04, on ? (conf_link ? 0x43 : 0x83) : 0x43); /* enable serial_link or conf_link */
++ usleep_range(2000, 2500); /* wait 2ms after changing reverse_control */
++ client->addr = priv->des_addr; /* MAX9288-CAMx I2C */
++
++ return 0;
++}
++
++static struct v4l2_subdev_core_ops max9288_subdev_core_ops = {
++#ifdef CONFIG_VIDEO_ADV_DEBUG
++ .g_register = max9288_g_register,
++ .s_register = max9288_s_register,
++#endif
++ .s_power = max9288_s_power,
++};
++
++static struct v4l2_subdev_ops max9288_subdev_ops = {
++ .core = &max9288_subdev_core_ops,
++};
++
++static int max9288_parse_dt(struct i2c_client *client)
++{
++ struct max9288_priv *priv = i2c_get_clientdata(client);
++ struct device_node *np = client->dev.of_node;
++ struct device_node *endpoint = NULL;
++ struct property *prop;
++ int err, pwen;
++ int sensor_delay, gpio0 = 1, gpio1 = 1;
++ u8 val = 0;
++ char poc_name[10];
++
++ if (of_property_read_u32(np, "maxim,lanes", &priv->lanes))
++ priv->lanes = 4;
++
++ pwen = of_get_gpio(np, 0);
++ if (pwen > 0) {
++ err = gpio_request_one(pwen, GPIOF_OUT_INIT_HIGH, dev_name(&client->dev));
++ if (err)
++ dev_err(&client->dev, "cannot request PWEN gpio %d: %d\n", pwen, err);
++ }
++
++ mdelay(250);
++
++ sprintf(poc_name, "POC%d", 0);
++ priv->poc_gpio = devm_gpiod_get_optional(&client->dev, kstrdup(poc_name, GFP_KERNEL), 0);
++
++ reg8_read(client, 0x1e, &val); /* read max9288 ID */
++ if (val != MAX9288_ID) {
++ prop = of_find_property(np, "reg", NULL);
++ if (prop)
++ of_remove_property(np, prop);
++ return -ENODEV;
++ }
++
++ if (!of_property_read_u32(np, "maxim,gpio0", &gpio0) ||
++ !of_property_read_u32(np, "maxim,gpio1", &gpio1))
++ reg8_write(client, 0x06, (gpio1 << 3) | (gpio0 << 1));
++
++ if (of_property_read_u32(np, "maxim,resetb-gpio", &priv->gpio_resetb)) {
++ priv->gpio_resetb = -1;
++ } else {
++ if (of_property_read_bool(np, "maxim,resetb-active-high"))
++ priv->active_low_resetb = 0;
++ else
++ priv->active_low_resetb = 1;
++ }
++
++ if (!of_property_read_u32(np, "maxim,sensor_delay", &sensor_delay))
++ mdelay(sensor_delay);
++ priv->pclk_rising_edge = true;
++ if (of_property_read_bool(np, "maxim,pclk-falling-edge"))
++ priv->pclk_rising_edge = false;
++ if (of_property_read_u32(np, "maxim,timeout", &priv->timeout))
++ priv->timeout = 100;
++ if (of_property_read_u32(np, "maxim,him", &priv->him))
++ priv->him = 0;
++ if (of_property_read_u32(np, "maxim,hsync", &priv->hsync))
++ priv->hsync = 0;
++ if (of_property_read_u32(np, "maxim,vsync", &priv->vsync))
++ priv->vsync = 1;
++ if (of_property_read_u32(np, "maxim,poc-delay", &priv->poc_delay))
++ priv->poc_delay = 50;
++ if (of_property_read_u32(np, "maxim,bws", &priv->bws))
++ priv->bws = 0;
++ if (of_property_read_u32(np, "maxim,dbl", &priv->dbl))
++ priv->dbl = 1;
++ if (of_property_read_u32(np, "maxim,dt", &priv->dt))
++ priv->dt = 3;
++ if (of_property_read_u32(np, "maxim,hsgen", &priv->hsgen))
++ priv->hsgen = 0;
++ if (of_property_read_u32(np, "maxim,pclk", &priv->pclk))
++ priv->pclk = pclk;
++
++ /* module params override dts */
++ if (him)
++ priv->him = him;
++ if (hsync)
++ priv->hsync = hsync;
++ if (!vsync)
++ priv->vsync = vsync;
++ if (gpio_resetb)
++ priv->gpio_resetb = gpio_resetb;
++ if (active_low_resetb)
++ priv->active_low_resetb = active_low_resetb;
++ if (timeout_n)
++ priv->timeout = timeout_n;
++ if (poc_delay)
++ priv->poc_delay = poc_delay;
++ if (bws)
++ priv->bws = bws;
++ if (!dbl)
++ priv->dbl = dbl;
++ if (dt != 3)
++ priv->dt = dt;
++ if (hsgen)
++ priv->hsgen = hsgen;
++ if (pclk != 100)
++ priv->pclk = pclk;
++
++ endpoint = of_graph_get_next_endpoint(np, endpoint);
++ if (endpoint) {
++ if (of_property_read_u32(endpoint, "max9271-addr", &priv->max9271_addr)) {
++ of_node_put(endpoint);
++ dev_err(&client->dev, "max9271-addr not set\n");
++ return -EINVAL;
++ }
++
++ priv->sd_fwnode = of_fwnode_handle(endpoint);
++ }
++
++ of_node_put(endpoint);
++ return 0;
++}
++
++static void max9288_setup_remote_endpoint(struct i2c_client *client)
++{
++ struct max9288_priv *priv = i2c_get_clientdata(client);
++ struct device_node *np = client->dev.of_node;
++ struct device_node *endpoint = NULL, *rendpoint = NULL;
++ int i;
++ struct property *csi_rate_prop, *dvp_order_prop;
++
++ for (i = 0; ; i++) {
++ endpoint = of_graph_get_next_endpoint(np, endpoint);
++ if (!endpoint)
++ break;
++
++ rendpoint = of_parse_phandle(endpoint, "remote-endpoint", 0);
++ if (!rendpoint)
++ continue;
++
++ csi_rate_prop = of_find_property(endpoint, "csi-rate", NULL);
++ if (csi_rate_prop) {
++ /* CSI2_RATE = PCLK*bpp/lanes */
++ priv->csi_rate = cpu_to_be32(priv->pclk * dt2bpp[priv->dt] / priv->lanes);
++ csi_rate_prop->value = &priv->csi_rate;
++ of_update_property(rendpoint, csi_rate_prop);
++ }
++
++ dvp_order_prop = of_find_property(endpoint, "dvp-order", NULL);
++ if (dvp_order_prop)
++ of_update_property(rendpoint, dvp_order_prop);
++ }
++
++ of_node_put(endpoint);
++}
++
++static int max9288_probe(struct i2c_client *client,
++ const struct i2c_device_id *did)
++{
++ struct max9288_priv *priv;
++ int err;
++
++ priv = devm_kzalloc(&client->dev, sizeof(*priv), GFP_KERNEL);
++ if (!priv)
++ return -ENOMEM;
++
++ i2c_set_clientdata(client, priv);
++ priv->des_addr = client->addr;
++ priv->client = client;
++
++ err = max9288_parse_dt(client);
++ if (err)
++ goto out;
++
++ err = max9288_initialize(client);
++ if (err < 0)
++ goto out;
++
++ max9288_setup_remote_endpoint(client);
++
++ v4l2_subdev_init(&priv->sd, &max9288_subdev_ops);
++ priv->sd.owner = client->dev.driver->owner;
++ priv->sd.dev = &client->dev;
++ v4l2_set_subdevdata(&priv->sd, priv);
++ priv->sd.fwnode = priv->sd_fwnode;
++
++ snprintf(priv->sd.name, V4L2_SUBDEV_NAME_SIZE, "%s %d-%04x",
++ client->dev.driver->name, i2c_adapter_id(client->adapter),
++ client->addr);
++
++ err = v4l2_async_register_subdev(&priv->sd);
++ if (err < 0)
++ goto out;
++out:
++ return err;
++}
++
++static int max9288_remove(struct i2c_client *client)
++{
++ struct max9288_priv *priv = i2c_get_clientdata(client);
++
++ v4l2_async_unregister_subdev(&priv->sd);
++ v4l2_device_unregister_subdev(&priv->sd);
++
++ return 0;
++}
++
++static const struct of_device_id max9288_dt_ids[] = {
++ { .compatible = "maxim,max9288" },
++ {},
++};
++MODULE_DEVICE_TABLE(of, max9288_dt_ids);
++
++static const struct i2c_device_id max9288_id[] = {
++ { "max9288", 0 },
++ { }
++};
++MODULE_DEVICE_TABLE(i2c, max9288_id);
++
++static struct i2c_driver max9288_i2c_driver = {
++ .driver = {
++ .name = "max9288",
++ .of_match_table = of_match_ptr(max9288_dt_ids),
++ },
++ .probe = max9288_probe,
++ .remove = max9288_remove,
++ .id_table = max9288_id,
++};
++
++module_i2c_driver(max9288_i2c_driver);
++
++MODULE_DESCRIPTION("GMSL driver for MAX9288");
++MODULE_AUTHOR("Vladimir Barinov");
++MODULE_LICENSE("GPL");
+diff --git a/drivers/media/platform/soc_camera/rcar_vin.c b/drivers/media/platform/soc_camera/rcar_vin.c
+index 9051590..501598c 100644
+--- a/drivers/media/platform/soc_camera/rcar_vin.c
++++ b/drivers/media/platform/soc_camera/rcar_vin.c
+@@ -1587,6 +1587,7 @@ static struct v4l2_subdev *find_deser(struct rcar_vin_priv *pcdev)
+ struct v4l2_subdev *sd;
+ char name[] = "max9286";
+ char name2[] = "ti9x4";
++ char name3[] = "max9288";
+
+ v4l2_device_for_each_subdev(sd, &pcdev->ici.v4l2_dev) {
+ if (!strncmp(name, sd->name, sizeof(name) - 1)) {
+@@ -1597,6 +1598,10 @@ static struct v4l2_subdev *find_deser(struct rcar_vin_priv *pcdev)
+ pcdev->deser_sd = sd;
+ return sd;
+ }
++ if (!strncmp(name3, sd->name, sizeof(name3) - 1)) {
++ pcdev->deser_sd = sd;
++ return sd;
++ }
+ }
+
+ return NULL;
+@@ -3064,10 +3069,11 @@ static int rcar_vin_probe(struct platform_device *pdev)
+ const char *str;
+ unsigned int i;
+ struct device_node *epn = NULL, *ren = NULL;
+- struct device_node *csi2_ren = NULL, *max9286_ren = NULL, *ti9x4_ren = NULL;
++ struct device_node *csi2_ren = NULL, *max9286_ren = NULL, *ti9x4_ren = NULL, *max9288_ren = NULL;
+ bool csi_use = false;
+ bool max9286_use = false;
+ bool ti9x4_use = false;
++ bool max9288_use = false;
+
+ match = of_match_device(of_match_ptr(rcar_vin_of_table), &pdev->dev);
+
+@@ -3109,6 +3115,11 @@ static int rcar_vin_probe(struct platform_device *pdev)
+ ti9x4_use = true;
+ }
+
++ if (strcmp(ren->parent->name, "max9288") == 0) {
++ max9288_ren = of_parse_phandle(epn, "remote-endpoint", 0);
++ max9288_use = true;
++ }
++
+ of_node_put(ren);
+ }
+
+@@ -3385,6 +3396,12 @@ static int rcar_vin_probe(struct platform_device *pdev)
+ goto cleanup;
+ }
+
++ if (max9288_use) {
++ ret = rcar_vin_soc_of_bind(priv, &priv->ici, epn, max9288_ren);
++ if (ret)
++ goto cleanup;
++ }
++
+ vin_debug = 0;
+
+ return 0;
+--
+2.7.4
+
diff --git a/bsp/meta-rcar/meta-rcar-gen3-adas/recipes-kernel/linux/linux-renesas/0412-media-i2c-soc_camera-differenciate-max9286-and-max92.patch b/bsp/meta-rcar/meta-rcar-gen3-adas/recipes-kernel/linux/linux-renesas/0412-media-i2c-soc_camera-differenciate-max9286-and-max92.patch
new file mode 100644
index 00000000..68e569e2
--- /dev/null
+++ b/bsp/meta-rcar/meta-rcar-gen3-adas/recipes-kernel/linux/linux-renesas/0412-media-i2c-soc_camera-differenciate-max9286-and-max92.patch
@@ -0,0 +1,351 @@
+From 3fea12b6dfa46dc30dc2cdbd1f27dc3f5a07d003 Mon Sep 17 00:00:00 2001
+From: Vladimir Barinov <vladimir.barinov@cogentembedded.com>
+Date: Wed, 14 Aug 2019 15:06:18 +0300
+Subject: [PATCH 2/3] media: i2c: soc_camera: differenciate max9286 and max9288
+
+The max9288 needs to be differenciated from max9286, because
+it does not have the link control block
+
+Signed-off-by: Vladimir Barinov <vladimir.barinov@cogentembedded.com>
+---
+ drivers/media/i2c/soc_camera/ap0101_ar014x.c | 8 ++++++--
+ drivers/media/i2c/soc_camera/ar0132.c | 8 ++++++--
+ drivers/media/i2c/soc_camera/ar0140.c | 8 ++++++--
+ drivers/media/i2c/soc_camera/ar0143.c | 8 ++++++--
+ drivers/media/i2c/soc_camera/ar0147.c | 8 ++++++--
+ drivers/media/i2c/soc_camera/ar0231.c | 8 ++++++--
+ drivers/media/i2c/soc_camera/gw4200_ar014x.c | 8 ++++++--
+ drivers/media/i2c/soc_camera/gw5200_imx390.c | 8 ++++++--
+ drivers/media/i2c/soc_camera/isx016.c | 8 ++++++--
+ drivers/media/i2c/soc_camera/isx019.c | 8 ++++++--
+ drivers/media/i2c/soc_camera/ov10635.c | 8 ++++++--
+ drivers/media/i2c/soc_camera/ov10640.c | 8 ++++++--
+ drivers/media/i2c/soc_camera/ov2311.c | 8 ++++++--
+ drivers/media/i2c/soc_camera/ov490_ov10640.c | 8 ++++++--
+ 14 files changed, 84 insertions(+), 28 deletions(-)
+
+diff --git a/drivers/media/i2c/soc_camera/ap0101_ar014x.c b/drivers/media/i2c/soc_camera/ap0101_ar014x.c
+index 74e6e51..c35e5a0 100644
+--- a/drivers/media/i2c/soc_camera/ap0101_ar014x.c
++++ b/drivers/media/i2c/soc_camera/ap0101_ar014x.c
+@@ -65,12 +65,16 @@ static void ap0101_s_port(struct i2c_client *client, int fwd_en)
+ {
+ struct ap0101_priv *priv = to_ap0101(client);
+ int tmp_addr;
++ u8 val = 0;
+
+ if (priv->max9286_addr) {
+ tmp_addr = client->addr;
+ client->addr = priv->max9286_addr; /* Deserializer I2C address */
+- reg8_write(client, 0x0a, fwd_en ? 0x11 << priv->port : 0); /* Enable/disable reverse/forward control for this port */
+- usleep_range(5000, 5500); /* wait 5ms */
++ reg8_read(client, 0x1e, &val); /* read max928X ID */
++ if (val == MAX9286_ID) {
++ reg8_write(client, 0x0a, fwd_en ? 0x11 << priv->port : 0); /* Enable/disable reverse/forward control for this port */
++ usleep_range(5000, 5500); /* wait 5ms */
++ }
+ client->addr = tmp_addr;
+ };
+ }
+diff --git a/drivers/media/i2c/soc_camera/ar0132.c b/drivers/media/i2c/soc_camera/ar0132.c
+index 18bc5dc..e4926e8 100644
+--- a/drivers/media/i2c/soc_camera/ar0132.c
++++ b/drivers/media/i2c/soc_camera/ar0132.c
+@@ -61,12 +61,16 @@ static void ar0132_s_port(struct i2c_client *client, int fwd_en)
+ {
+ struct ar0132_priv *priv = to_ar0132(client);
+ int tmp_addr;
++ u8 val = 0;
+
+ if (priv->max9286_addr) {
+ tmp_addr = client->addr;
+ client->addr = priv->max9286_addr; /* Deserializer I2C address */
+- reg8_write(client, 0x0a, fwd_en ? 0x11 << priv->port : 0); /* Enable/disable reverse/forward control for this port */
+- usleep_range(5000, 5500); /* wait 5ms */
++ reg8_read(client, 0x1e, &val); /* read max928X ID */
++ if (val == MAX9286_ID) {
++ reg8_write(client, 0x0a, fwd_en ? 0x11 << priv->port : 0); /* Enable/disable reverse/forward control for this port */
++ usleep_range(5000, 5500); /* wait 5ms */
++ }
+ client->addr = tmp_addr;
+ };
+ }
+diff --git a/drivers/media/i2c/soc_camera/ar0140.c b/drivers/media/i2c/soc_camera/ar0140.c
+index c52ca4e..b156fc5 100644
+--- a/drivers/media/i2c/soc_camera/ar0140.c
++++ b/drivers/media/i2c/soc_camera/ar0140.c
+@@ -58,12 +58,16 @@ static void ar0140_s_port(struct i2c_client *client, int fwd_en)
+ {
+ struct ar0140_priv *priv = to_ar0140(client);
+ int tmp_addr;
++ u8 val = 0;
+
+ if (priv->max9286_addr) {
+ tmp_addr = client->addr;
+ client->addr = priv->max9286_addr; /* Deserializer I2C address */
+- reg8_write(client, 0x0a, fwd_en ? 0x11 << priv->port : 0); /* Enable/disable reverse/forward control for this port */
+- usleep_range(5000, 5500); /* wait 5ms */
++ reg8_read(client, 0x1e, &val); /* read max928X ID */
++ if (val == MAX9286_ID) {
++ reg8_write(client, 0x0a, fwd_en ? 0x11 << priv->port : 0);/* Enable/disable reverse/forward control for this port */
++ usleep_range(5000, 5500); /* wait 5ms */
++ }
+ client->addr = tmp_addr;
+ };
+ }
+diff --git a/drivers/media/i2c/soc_camera/ar0143.c b/drivers/media/i2c/soc_camera/ar0143.c
+index b61c7eb..0c4b970 100644
+--- a/drivers/media/i2c/soc_camera/ar0143.c
++++ b/drivers/media/i2c/soc_camera/ar0143.c
+@@ -64,12 +64,16 @@ static void ar0143_s_port(struct i2c_client *client, int fwd_en)
+ {
+ struct ar0143_priv *priv = to_ar0143(client);
+ int tmp_addr;
++ u8 val = 0;
+
+ if (priv->max9286_addr) {
+ tmp_addr = client->addr;
+ client->addr = priv->max9286_addr; /* Deserializer I2C address */
+- reg8_write(client, 0x0a, fwd_en ? 0x11 << priv->port : 0); /* Enable/disable reverse/forward control for this port */
+- usleep_range(5000, 5500); /* wait 5ms */
++ reg8_read(client, 0x1e, &val); /* read max928X ID */
++ if (val == MAX9286_ID) {
++ reg8_write(client, 0x0a, fwd_en ? 0x11 << priv->port : 0); /* Enable/disable reverse/forward control for this port */
++ usleep_range(5000, 5500); /* wait 5ms */
++ }
+ client->addr = tmp_addr;
+ };
+ }
+diff --git a/drivers/media/i2c/soc_camera/ar0147.c b/drivers/media/i2c/soc_camera/ar0147.c
+index 08fd136..fc2a09e 100644
+--- a/drivers/media/i2c/soc_camera/ar0147.c
++++ b/drivers/media/i2c/soc_camera/ar0147.c
+@@ -81,12 +81,16 @@ static void ar0147_s_port(struct i2c_client *client, int fwd_en)
+ {
+ struct ar0147_priv *priv = to_ar0147(client);
+ int tmp_addr;
++ u8 val = 0;
+
+ if (priv->max9286_addr) {
+ tmp_addr = client->addr;
+ client->addr = priv->max9286_addr; /* Deserializer I2C address */
+- reg8_write(client, 0x0a, fwd_en ? 0x11 << priv->port : 0); /* Enable/disable reverse/forward control for this port */
+- usleep_range(5000, 5500); /* wait 5ms */
++ reg8_read(client, 0x1e, &val); /* read max928X ID */
++ if (val == MAX9286_ID) {
++ reg8_write(client, 0x0a, fwd_en ? 0x11 << priv->port : 0); /* Enable/disable reverse/forward control for this port */
++ usleep_range(5000, 5500); /* wait 5ms */
++ }
+ client->addr = tmp_addr;
+ };
+ }
+diff --git a/drivers/media/i2c/soc_camera/ar0231.c b/drivers/media/i2c/soc_camera/ar0231.c
+index 36b5657..c51ae9ad 100644
+--- a/drivers/media/i2c/soc_camera/ar0231.c
++++ b/drivers/media/i2c/soc_camera/ar0231.c
+@@ -61,12 +61,16 @@ static void ar0231_s_port(struct i2c_client *client, int fwd_en)
+ {
+ struct ar0231_priv *priv = to_ar0231(client);
+ int tmp_addr;
++ u8 val = 0;
+
+ if (priv->max9286_addr) {
+ tmp_addr = client->addr;
+ client->addr = priv->max9286_addr; /* Deserializer I2C address */
+- reg8_write(client, 0x0a, fwd_en ? 0x11 << priv->port : 0); /* Enable/disable reverse/forward control for this port */
+- usleep_range(5000, 5500); /* wait 5ms */
++ reg8_read(client, 0x1e, &val); /* read max928X ID */
++ if (val == MAX9286_ID) {
++ reg8_write(client, 0x0a, fwd_en ? 0x11 << priv->port : 0); /* Enable/disable reverse/forward control for this port */
++ usleep_range(5000, 5500); /* wait 5ms */
++ }
+ client->addr = tmp_addr;
+ };
+ }
+diff --git a/drivers/media/i2c/soc_camera/gw4200_ar014x.c b/drivers/media/i2c/soc_camera/gw4200_ar014x.c
+index 45123ae..71c34f9 100644
+--- a/drivers/media/i2c/soc_camera/gw4200_ar014x.c
++++ b/drivers/media/i2c/soc_camera/gw4200_ar014x.c
+@@ -58,12 +58,16 @@ static void gw4200_s_port(struct i2c_client *client, int fwd_en)
+ {
+ struct gw4200_priv *priv = to_gw4200(client);
+ int tmp_addr;
++ u8 val = 0;
+
+ if (priv->max9286_addr) {
+ tmp_addr = client->addr;
+ client->addr = priv->max9286_addr; /* Deserializer I2C address */
+- reg8_write(client, 0x0a, fwd_en ? 0x11 << priv->port : 0); /* Enable/disable reverse/forward control for this port */
+- usleep_range(5000, 5500); /* wait 5ms */
++ reg8_read(client, 0x1e, &val); /* read max928X ID */
++ if (val == MAX9286_ID) {
++ reg8_write(client, 0x0a, fwd_en ? 0x11 << priv->port : 0); /* Enable/disable reverse/forward control for this port */
++ usleep_range(5000, 5500); /* wait 5ms */
++ }
+ client->addr = tmp_addr;
+ };
+ }
+diff --git a/drivers/media/i2c/soc_camera/gw5200_imx390.c b/drivers/media/i2c/soc_camera/gw5200_imx390.c
+index 98352a9..e750a85 100644
+--- a/drivers/media/i2c/soc_camera/gw5200_imx390.c
++++ b/drivers/media/i2c/soc_camera/gw5200_imx390.c
+@@ -65,12 +65,16 @@ static void gw5200_s_port(struct i2c_client *client, int fwd_en)
+ {
+ struct gw5200_priv *priv = to_gw5200(client);
+ int tmp_addr;
++ u8 val = 0;
+
+ if (priv->max9286_addr) {
+ tmp_addr = client->addr;
+ client->addr = priv->max9286_addr; /* Deserializer I2C address */
+- reg8_write(client, 0x0a, fwd_en ? 0x11 << priv->port : 0); /* Enable/disable reverse/forward control for this port */
+- usleep_range(5000, 5500); /* wait 5ms */
++ reg8_read(client, 0x1e, &val); /* read max928X ID */
++ if (val == MAX9286_ID) {
++ reg8_write(client, 0x0a, fwd_en ? 0x11 << priv->port : 0); /* Enable/disable reverse/forward control for this port */
++ usleep_range(5000, 5500); /* wait 5ms */
++ }
+ client->addr = tmp_addr;
+ };
+ }
+diff --git a/drivers/media/i2c/soc_camera/isx016.c b/drivers/media/i2c/soc_camera/isx016.c
+index ab85b7d..9465c8f 100644
+--- a/drivers/media/i2c/soc_camera/isx016.c
++++ b/drivers/media/i2c/soc_camera/isx016.c
+@@ -62,12 +62,16 @@ static void isx016_s_port(struct i2c_client *client, int fwd_en)
+ {
+ struct isx016_priv *priv = to_isx016(client);
+ int tmp_addr;
++ u8 val = 0;
+
+ if (priv->max9286_addr) {
+ tmp_addr = client->addr;
+ client->addr = priv->max9286_addr; /* Deserializer I2C address */
+- reg8_write(client, 0x0a, fwd_en ? 0x11 << priv->port : 0); /* Enable/disable reverse/forward control for this port */
+- usleep_range(5000, 5500); /* wait 5ms */
++ reg8_read(client, 0x1e, &val); /* read max928X ID */
++ if (val == MAX9286_ID) {
++ reg8_write(client, 0x0a, fwd_en ? 0x11 << priv->port : 0); /* Enable/disable reverse/forward control for this port */
++ usleep_range(5000, 5500); /* wait 5ms */
++ }
+ client->addr = tmp_addr;
+ };
+ }
+diff --git a/drivers/media/i2c/soc_camera/isx019.c b/drivers/media/i2c/soc_camera/isx019.c
+index 188fd28..d75d8f3 100644
+--- a/drivers/media/i2c/soc_camera/isx019.c
++++ b/drivers/media/i2c/soc_camera/isx019.c
+@@ -64,12 +64,16 @@ static void isx019_s_port(struct i2c_client *client, int fwd_en)
+ {
+ struct isx019_priv *priv = to_isx019(client);
+ int tmp_addr;
++ u8 val = 0;
+
+ if (priv->max9286_addr) {
+ tmp_addr = client->addr;
+ client->addr = priv->max9286_addr; /* Deserializer I2C address */
+- reg8_write(client, 0x0a, fwd_en ? 0x11 << priv->port : 0); /* Enable/disable reverse/forward control for this port */
+- usleep_range(5000, 5500); /* wait 5ms */
++ reg8_read(client, 0x1e, &val); /* read max928X ID */
++ if (val == MAX9286_ID) {
++ reg8_write(client, 0x0a, fwd_en ? 0x11 << priv->port : 0); /* Enable/disable reverse/forward control for this port */
++ usleep_range(5000, 5500); /* wait 5ms */
++ }
+ client->addr = tmp_addr;
+ };
+ }
+diff --git a/drivers/media/i2c/soc_camera/ov10635.c b/drivers/media/i2c/soc_camera/ov10635.c
+index 1bbde91..14bb339 100644
+--- a/drivers/media/i2c/soc_camera/ov10635.c
++++ b/drivers/media/i2c/soc_camera/ov10635.c
+@@ -69,12 +69,16 @@ static void ov10635_s_port(struct i2c_client *client, int fwd_en)
+ {
+ struct ov10635_priv *priv = to_ov10635(client);
+ int tmp_addr;
++ u8 val = 0;
+
+ if (priv->max9286_addr) {
+ tmp_addr = client->addr;
+ client->addr = priv->max9286_addr; /* Deserializer I2C address */
+- reg8_write(client, 0x0a, fwd_en ? 0x11 << priv->port : 0); /* Enable/disable reverse/forward control for this port */
+- usleep_range(5000, 5500); /* wait 5ms */
++ reg8_read(client, 0x1e, &val); /* read max928X ID */
++ if (val == MAX9286_ID) {
++ reg8_write(client, 0x0a, fwd_en ? 0x11 << priv->port : 0); /* Enable/disable reverse/forward control for this port */
++ usleep_range(5000, 5500); /* wait 5ms */
++ }
+ client->addr = tmp_addr;
+ };
+ }
+diff --git a/drivers/media/i2c/soc_camera/ov10640.c b/drivers/media/i2c/soc_camera/ov10640.c
+index 4ce6e15..89dac1b 100644
+--- a/drivers/media/i2c/soc_camera/ov10640.c
++++ b/drivers/media/i2c/soc_camera/ov10640.c
+@@ -65,12 +65,16 @@ static void ov10640_s_port(struct i2c_client *client, int fwd_en)
+ {
+ struct ov10640_priv *priv = to_ov10640(client);
+ int tmp_addr;
++ u8 val = 0;
+
+ if (priv->max9286_addr) {
+ tmp_addr = client->addr;
+ client->addr = priv->max9286_addr; /* Deserializer I2C address */
+- reg8_write(client, 0x0a, fwd_en ? 0x11 << priv->port : 0); /* Enable/disable reverse/forward control for this port */
+- usleep_range(5000, 5500); /* wait 5ms */
++ reg8_read(client, 0x1e, &val); /* read max928X ID */
++ if (val == MAX9286_ID) {
++ reg8_write(client, 0x0a, fwd_en ? 0x11 << priv->port : 0); /* Enable/disable reverse/forward control for this port */
++ usleep_range(5000, 5500); /* wait 5ms */
++ }
+ client->addr = tmp_addr;
+ };
+ }
+diff --git a/drivers/media/i2c/soc_camera/ov2311.c b/drivers/media/i2c/soc_camera/ov2311.c
+index c8d260c..f04f271 100644
+--- a/drivers/media/i2c/soc_camera/ov2311.c
++++ b/drivers/media/i2c/soc_camera/ov2311.c
+@@ -66,12 +66,16 @@ static void ov2311_s_port(struct i2c_client *client, int fwd_en)
+ {
+ struct ov2311_priv *priv = to_ov2311(client);
+ int tmp_addr;
++ u8 val = 0;
+
+ if (priv->max9286_addr) {
+ tmp_addr = client->addr;
+ client->addr = priv->max9286_addr; /* Deserializer I2C address */
+- reg8_write(client, 0x0a, fwd_en ? 0x11 << priv->port : 0); /* Enable/disable reverse/forward control for this port */
+- usleep_range(5000, 5500); /* wait 5ms */
++ reg8_read(client, 0x1e, &val); /* read max928X ID */
++ if (val == MAX9286_ID) {
++ reg8_write(client, 0x0a, fwd_en ? 0x11 << priv->port : 0); /* Enable/disable reverse/forward control for this port */
++ usleep_range(5000, 5500); /* wait 5ms */
++ }
+ client->addr = tmp_addr;
+ };
+ }
+diff --git a/drivers/media/i2c/soc_camera/ov490_ov10640.c b/drivers/media/i2c/soc_camera/ov490_ov10640.c
+index c492792..b85f871 100644
+--- a/drivers/media/i2c/soc_camera/ov490_ov10640.c
++++ b/drivers/media/i2c/soc_camera/ov490_ov10640.c
+@@ -91,12 +91,16 @@ static void ov490_s_port(struct i2c_client *client, int fwd_en)
+ {
+ struct ov490_priv *priv = to_ov490(client);
+ int tmp_addr;
++ u8 val = 0;
+
+ if (priv->max9286_addr) {
+ tmp_addr = client->addr;
+ client->addr = priv->max9286_addr; /* Deserializer I2C address */
+- reg8_write(client, 0x0a, fwd_en ? 0x11 << priv->port : 0); /* Enable/disable reverse/forward control for this port */
+- usleep_range(5000, 5500); /* wait 5ms */
++ reg8_read(client, 0x1e, &val); /* read max928X ID */
++ if (val == MAX9286_ID) {
++ reg8_write(client, 0x0a, fwd_en ? 0x11 << priv->port : 0); /* Enable/disable reverse/forward control for this port */
++ usleep_range(5000, 5500); /* wait 5ms */
++ }
+ client->addr = tmp_addr;
+ };
+ }
+--
+2.7.4
+
diff --git a/bsp/meta-rcar/meta-rcar-gen3-adas/recipes-kernel/linux/linux-renesas/0413-media-i2c-max9288-fix-stream-on-off.patch b/bsp/meta-rcar/meta-rcar-gen3-adas/recipes-kernel/linux/linux-renesas/0413-media-i2c-max9288-fix-stream-on-off.patch
new file mode 100644
index 00000000..f45837a2
--- /dev/null
+++ b/bsp/meta-rcar/meta-rcar-gen3-adas/recipes-kernel/linux/linux-renesas/0413-media-i2c-max9288-fix-stream-on-off.patch
@@ -0,0 +1,57 @@
+From 0bd5979e4ae470c914a941c97e178d71ecb8d7f9 Mon Sep 17 00:00:00 2001
+From: Vladimir Barinov <vladimir.barinov@cogentembedded.com>
+Date: Thu, 15 Aug 2019 14:18:51 +0300
+Subject: [PATCH 3/3] media: i2c: max9288: fix stream on/off
+
+The remote i2c write can fail seldom.
+Implement write_verify.
+
+Signed-off-by: Vladimir Barinov <vladimir.barinov@cogentembedded.com>
+---
+ drivers/media/i2c/soc_camera/max9288.c | 23 ++++++++++++++++++++++-
+ 1 file changed, 22 insertions(+), 1 deletion(-)
+
+diff --git a/drivers/media/i2c/soc_camera/max9288.c b/drivers/media/i2c/soc_camera/max9288.c
+index dd57074..4840795 100644
+--- a/drivers/media/i2c/soc_camera/max9288.c
++++ b/drivers/media/i2c/soc_camera/max9288.c
+@@ -154,6 +154,27 @@ static char* ser_name(int id)
+ }
+ }
+
++static void max9288_write_remote_verify(struct i2c_client *client, u8 reg, u8 val)
++{
++ struct max9288_priv *priv = i2c_get_clientdata(client);
++ int timeout;
++
++ for (timeout = 0; timeout < 10; timeout++) {
++ u8 val2 = 0;
++
++ reg8_write(client, reg, val);
++ reg8_read(client, reg, &val2);
++ if (val2 == val)
++ break;
++
++ usleep_range(1000, 1500);
++ }
++
++ if (timeout >= 10)
++ dev_err(&client->dev, "timeout remote write acked\n");
++}
++
++
+ static void max9288_preinit(struct i2c_client *client, int addr)
+ {
+
+@@ -501,7 +522,7 @@ static int max9288_s_power(struct v4l2_subdev *sd, int on)
+ struct i2c_client *client = priv->client;
+
+ client->addr = priv->max9271_addr; /* MAX9271-CAMx I2C new */
+- reg8_write(client, 0x04, on ? (conf_link ? 0x43 : 0x83) : 0x43); /* enable serial_link or conf_link */
++ max9288_write_remote_verify(client, 0x04, on ? (conf_link ? 0x43 : 0x83) : 0x43); /* enable serial_link or conf_link */
+ usleep_range(2000, 2500); /* wait 2ms after changing reverse_control */
+ client->addr = priv->des_addr; /* MAX9288-CAMx I2C */
+
+--
+2.7.4
+
diff --git a/bsp/meta-rcar/meta-rcar-gen3-adas/recipes-kernel/linux/linux-renesas/0414-gpio-pca953x-do-not-ignore-i2c-errors.patch b/bsp/meta-rcar/meta-rcar-gen3-adas/recipes-kernel/linux/linux-renesas/0414-gpio-pca953x-do-not-ignore-i2c-errors.patch
new file mode 100644
index 00000000..ca7a2493
--- /dev/null
+++ b/bsp/meta-rcar/meta-rcar-gen3-adas/recipes-kernel/linux/linux-renesas/0414-gpio-pca953x-do-not-ignore-i2c-errors.patch
@@ -0,0 +1,33 @@
+From cb6211b6dc99e19b5c45f9714478a085d180266c Mon Sep 17 00:00:00 2001
+From: Andrey Gusakov <andrey.gusakov@cogentembedded.com>
+Date: Tue, 27 Aug 2019 13:08:42 +0300
+Subject: [PATCH 1/6] gpio: pca953x: do not ignore i2c errors
+
+Signed-off-by: Andrey Gusakov <andrey.gusakov@cogentembedded.com>
+---
+ drivers/gpio/gpio-pca953x.c | 9 ++-------
+ 1 file changed, 2 insertions(+), 7 deletions(-)
+
+diff --git a/drivers/gpio/gpio-pca953x.c b/drivers/gpio/gpio-pca953x.c
+index 587bb3e..9ad0720 100644
+--- a/drivers/gpio/gpio-pca953x.c
++++ b/drivers/gpio/gpio-pca953x.c
+@@ -349,13 +349,8 @@ static int pca953x_gpio_get_value(struct gpio_chip *gc, unsigned off)
+ mutex_lock(&chip->i2c_lock);
+ ret = pca953x_read_single(chip, chip->regs->input, &reg_val, off);
+ mutex_unlock(&chip->i2c_lock);
+- if (ret < 0) {
+- /* NOTE: diagnostic already emitted; that's all we should
+- * do unless gpio_*_value_cansleep() calls become different
+- * from their nonsleeping siblings (and report faults).
+- */
+- return 0;
+- }
++ if (ret < 0)
++ return ret;
+
+ return (reg_val & (1u << (off % BANK_SZ))) ? 1 : 0;
+ }
+--
+2.7.4
+
diff --git a/bsp/meta-rcar/meta-rcar-gen3-adas/recipes-kernel/linux/linux-renesas/0415-usb-host-xhci-rcar-Add-XHCI_TRUST_TX_LENGTH-quirk.patch b/bsp/meta-rcar/meta-rcar-gen3-adas/recipes-kernel/linux/linux-renesas/0415-usb-host-xhci-rcar-Add-XHCI_TRUST_TX_LENGTH-quirk.patch
new file mode 100644
index 00000000..889a3729
--- /dev/null
+++ b/bsp/meta-rcar/meta-rcar-gen3-adas/recipes-kernel/linux/linux-renesas/0415-usb-host-xhci-rcar-Add-XHCI_TRUST_TX_LENGTH-quirk.patch
@@ -0,0 +1,37 @@
+From 1e82360f4dd318a8ca4bd2e0d0b75a1780c158d7 Mon Sep 17 00:00:00 2001
+From: Yasushi Asano <yasano@jp.adit-jv.com>
+Date: Mon, 18 Feb 2019 11:26:34 +0100
+Subject: [PATCH 2/6] usb: host: xhci-rcar: Add XHCI_TRUST_TX_LENGTH quirk
+
+When plugging BUFFALO LUA4-U3-AGT USB3.0 to Gigabit Ethernet LAN
+Adapter, warning messages filled up dmesg.
+
+[ 101.098287] xhci-hcd ee000000.usb: WARN Successful completion on short TX for slot 1 ep 4: needs XHCI_TRUST_TX_LENGTH quirk?
+[ 101.117463] xhci-hcd ee000000.usb: WARN Successful completion on short TX for slot 1 ep 4: needs XHCI_TRUST_TX_LENGTH quirk?
+[ 101.136513] xhci-hcd ee000000.usb: WARN Successful completion on short TX for slot 1 ep 4: needs XHCI_TRUST_TX_LENGTH quirk?
+
+Adding the XHCI_TRUST_TX_LENGTH quirk resolves the issue.
+
+Signed-off-by: Yasushi Asano <yasano@jp.adit-jv.com>
+Signed-off-by: Spyridon Papageorgiou <spapageorgiou@de.adit-jv.com>
+Acked-by: Yoshihiro Shimoda <yoshihiro.shimoda.uh@renesas.com>
+Signed-off-by: Andrey Gusakov <andrey.gusakov@cogentembedded.com>
+---
+ drivers/usb/host/xhci-rcar.c | 1 +
+ 1 file changed, 1 insertion(+)
+
+diff --git a/drivers/usb/host/xhci-rcar.c b/drivers/usb/host/xhci-rcar.c
+index b05c937..1f31f84 100644
+--- a/drivers/usb/host/xhci-rcar.c
++++ b/drivers/usb/host/xhci-rcar.c
+@@ -264,6 +264,7 @@ int xhci_rcar_init_quirk(struct usb_hcd *hcd)
+ return -ETIMEDOUT;
+
+ xhci->quirks |= XHCI_SLOW_SUSPEND;
++ xhci->quirks |= XHCI_TRUST_TX_LENGTH;
+ return xhci_rcar_download_firmware(hcd);
+ }
+
+--
+2.7.4
+
diff --git a/bsp/meta-rcar/meta-rcar-gen3-adas/recipes-kernel/linux/linux-renesas/0416-arm64-dtb-renesas-vb2.1-enable-usb2-channel-3.patch b/bsp/meta-rcar/meta-rcar-gen3-adas/recipes-kernel/linux/linux-renesas/0416-arm64-dtb-renesas-vb2.1-enable-usb2-channel-3.patch
new file mode 100644
index 00000000..609f7f54
--- /dev/null
+++ b/bsp/meta-rcar/meta-rcar-gen3-adas/recipes-kernel/linux/linux-renesas/0416-arm64-dtb-renesas-vb2.1-enable-usb2-channel-3.patch
@@ -0,0 +1,55 @@
+From 2bda1ee68a17dcc3774073dd2b35d2525a079a7d Mon Sep 17 00:00:00 2001
+From: Andrey Gusakov <andrey.gusakov@cogentembedded.com>
+Date: Tue, 27 Aug 2019 17:26:13 +0300
+Subject: [PATCH 3/6] arm64: dtb: renesas: vb2.1: enable usb2 channel 3
+
+Signed-off-by: Andrey Gusakov <andrey.gusakov@cogentembedded.com>
+---
+ arch/arm64/boot/dts/renesas/ulcb-vb2.1.dtsi | 20 ++++++++++++++++++++
+ 1 file changed, 20 insertions(+)
+
+diff --git a/arch/arm64/boot/dts/renesas/ulcb-vb2.1.dtsi b/arch/arm64/boot/dts/renesas/ulcb-vb2.1.dtsi
+index 0df720d..f77b4c3 100644
+--- a/arch/arm64/boot/dts/renesas/ulcb-vb2.1.dtsi
++++ b/arch/arm64/boot/dts/renesas/ulcb-vb2.1.dtsi
+@@ -72,6 +72,11 @@
+ groups = "usb1";
+ function = "usb1";
+ };
++
++ usb3_pins: usb3 {
++ groups = "usb2_ch3";
++ function = "usb2_ch3";
++ };
+ };
+
+ &usb2_phy1 {
+@@ -81,6 +86,13 @@
+ status = "okay";
+ };
+
++&usb2_phy3 {
++ pinctrl-0 = <&usb3_pins>;
++ pinctrl-names = "default";
++
++ status = "okay";
++};
++
+ &ehci1 {
+ status = "okay";
+ };
+@@ -88,3 +100,11 @@
+ &ohci1 {
+ status = "okay";
+ };
++
++&ehci3 {
++ status = "okay";
++};
++
++&ohci3 {
++ status = "okay";
++};
+--
+2.7.4
+
diff --git a/bsp/meta-rcar/meta-rcar-gen3-adas/recipes-kernel/linux/linux-renesas/0417-USB-tusb8041-add-simple-driver-to-start-device-over-.patch b/bsp/meta-rcar/meta-rcar-gen3-adas/recipes-kernel/linux/linux-renesas/0417-USB-tusb8041-add-simple-driver-to-start-device-over-.patch
new file mode 100644
index 00000000..2e889b43
--- /dev/null
+++ b/bsp/meta-rcar/meta-rcar-gen3-adas/recipes-kernel/linux/linux-renesas/0417-USB-tusb8041-add-simple-driver-to-start-device-over-.patch
@@ -0,0 +1,288 @@
+From 542ce2e546efc78892b0d81b7b012424d153d2b5 Mon Sep 17 00:00:00 2001
+From: Andrey Gusakov <andrey.gusakov@cogentembedded.com>
+Date: Wed, 30 May 2018 17:59:22 +0300
+Subject: [PATCH 4/6] USB: tusb8041: add simple driver to start device over
+ smbus
+
+Signed-off-by: Andrey Gusakov <andrey.gusakov@cogentembedded.com>
+---
+ drivers/usb/misc/Kconfig | 7 ++
+ drivers/usb/misc/Makefile | 1 +
+ drivers/usb/misc/tusb8041.c | 235 ++++++++++++++++++++++++++++++++++++++++++++
+ 3 files changed, 243 insertions(+)
+ create mode 100644 drivers/usb/misc/tusb8041.c
+
+diff --git a/drivers/usb/misc/Kconfig b/drivers/usb/misc/Kconfig
+index 0f9f25d..0476717 100644
+--- a/drivers/usb/misc/Kconfig
++++ b/drivers/usb/misc/Kconfig
+@@ -255,6 +255,13 @@ config USB_HSIC_USB4604
+ help
+ This option enables support for SMSC USB4604 HSIC to USB 2.0 Driver.
+
++config USB_TUSB8041
++ tristate "TUSB8041 HUB"
++ depends on I2C
++ help
++ This option enables support for TI TUSB8041 3.0 HUB configuration
++ over SMBUS.
++
+ config USB_LINK_LAYER_TEST
+ tristate "USB Link Layer Test driver"
+ help
+diff --git a/drivers/usb/misc/Makefile b/drivers/usb/misc/Makefile
+index 109f54f..9ae89e5 100644
+--- a/drivers/usb/misc/Makefile
++++ b/drivers/usb/misc/Makefile
+@@ -27,6 +27,7 @@ obj-$(CONFIG_USB_YUREX) += yurex.o
+ obj-$(CONFIG_USB_HUB_USB251XB) += usb251xb.o
+ obj-$(CONFIG_USB_HSIC_USB3503) += usb3503.o
+ obj-$(CONFIG_USB_HSIC_USB4604) += usb4604.o
++obj-$(CONFIG_USB_TUSB8041) += tusb8041.o
+ obj-$(CONFIG_USB_CHAOSKEY) += chaoskey.o
+
+ obj-$(CONFIG_USB_SISUSBVGA) += sisusbvga/
+diff --git a/drivers/usb/misc/tusb8041.c b/drivers/usb/misc/tusb8041.c
+new file mode 100644
+index 0000000..7405ace
+--- /dev/null
++++ b/drivers/usb/misc/tusb8041.c
+@@ -0,0 +1,235 @@
++/*
++ * Driver for TI TUSB8041 USB SSIC 4-port 3.0 hub controller driver
++ * Based on tusb8041 and usb3503 drivers
++ *
++ * Copyright (c) 2012-2013 Dongjin Kim (tobetter@gmail.com)
++ * Copyright (c) 2016 Linaro Ltd.
++ * Copyright (c) 2018 Andrey Gusakov (andrey.gusakov@cogentembedded.com)
++ *
++ * This program is free software; you can redistribute it and/or modify
++ * it under the terms of the GNU General Public License as published by
++ * the Free Software Foundation; either version 2 of the License, or
++ * (at your option) any later version.
++ *
++ * This program is distributed in the hope that it will be useful,
++ * but WITHOUT ANY WARRANTY; without even the implied warranty of
++ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
++ * GNU General Public License for more details.
++ */
++
++#include <linux/i2c.h>
++#include <linux/delay.h>
++#include <linux/slab.h>
++#include <linux/module.h>
++#include <linux/gpio/consumer.h>
++
++enum tusb8041_mode {
++ TUSB8041_MODE_UNKNOWN,
++ TUSB8041_MODE_HUB,
++ TUSB8041_MODE_STANDBY,
++};
++
++struct tusb8041 {
++ enum tusb8041_mode mode;
++ u8 *regs;
++ int regs_sz;
++ struct device *dev;
++ struct gpio_desc *gpio_reset;
++};
++
++static void tusb8041_reset(struct tusb8041 *hub, int state)
++{
++ gpiod_set_value_cansleep(hub->gpio_reset, state);
++}
++
++static int tusb8041_connect(struct tusb8041 *hub)
++{
++ struct device *dev = hub->dev;
++ struct i2c_client *client = to_i2c_client(dev);
++ int ret;
++ int retry = 100;
++
++ tusb8041_reset(hub, 1);
++
++ /* reset and load defaults */
++ ret = i2c_smbus_write_byte_data(client, 0xf8, 0x03);
++ if (ret < 0)
++ goto err;
++
++ /* wait reset finished */
++ do {
++ /* check reset bit cleared */
++ ret = i2c_smbus_read_byte_data(client, 0xf8);
++ if (ret >= 0) {
++ if (ret & 0x02)
++ ret = -EIO;
++ else
++ ret = 0;
++ }
++ } while ((retry--) && (ret < 0));
++ if (ret < 0)
++ goto err;
++
++ /* write settings */
++ if ((hub->regs) && (hub->regs_sz)) {
++ int i;
++
++ for (i = 0; i < hub->regs_sz; i += 2) {
++ do {
++ ret = i2c_master_send(client, &(hub->regs[i]), 2);
++ } while ((retry--) && (ret < 0));
++ }
++ if (ret < 0)
++ goto err;
++ }
++
++ /* attach */
++ do {
++ ret = i2c_smbus_write_byte_data(client, 0xf8, 0x01);
++ if (ret >= 0) {
++ /* check bit cleared */
++ ret = i2c_smbus_read_byte_data(client, 0xf8);
++ if (ret >= 0) {
++ if (ret & 0x01)
++ ret = -EIO;
++ else
++ ret = 0;
++ }
++ }
++ } while ((retry--) && (ret < 0));
++
++ if (ret < 0)
++ goto err;
++
++ hub->mode = TUSB8041_MODE_HUB;
++ dev_dbg(dev, "switched to HUB mode\n");
++ return 0;
++
++err:
++ dev_err(dev, "Failed to write settings: %d\n", ret);
++ tusb8041_reset(hub, 0);
++ return ret;
++}
++
++static int tusb8041_switch_mode(struct tusb8041 *hub, enum tusb8041_mode mode)
++{
++ struct device *dev = hub->dev;
++ int err = 0;
++
++ switch (mode) {
++ case TUSB8041_MODE_HUB:
++ err = tusb8041_connect(hub);
++ break;
++
++ case TUSB8041_MODE_STANDBY:
++ tusb8041_reset(hub, 0);
++ dev_dbg(dev, "switched to STANDBY mode\n");
++ break;
++
++ default:
++ dev_err(dev, "unknown mode is requested\n");
++ err = -EINVAL;
++ break;
++ }
++
++ return err;
++}
++
++static int tusb8041_probe(struct tusb8041 *hub)
++{
++ struct device *dev = hub->dev;
++ struct device_node *np = dev->of_node;
++ struct gpio_desc *gpio;
++ int ret;
++ u32 mode = TUSB8041_MODE_HUB;
++ int sz;
++
++ gpio = devm_gpiod_get_optional(dev, "reset", GPIOD_OUT_LOW);
++ if (IS_ERR(gpio))
++ return PTR_ERR(gpio);
++ hub->gpio_reset = gpio;
++
++ if (of_property_read_u32(np, "initial-mode", &hub->mode))
++ hub->mode = mode;
++
++ if (of_find_property(np, "ti,registers", &sz) && ((sz & 0x01) == 0)) {
++ hub->regs = devm_kzalloc(hub->dev, sz, GFP_KERNEL);
++ ret = of_property_read_u8_array(np, "ti,registers", hub->regs, sz);
++ if (ret == 0)
++ hub->regs_sz = sz;
++ }
++
++ /* reset */
++ tusb8041_reset(hub, 0);
++ msleep(250);
++
++ return tusb8041_switch_mode(hub, hub->mode);
++}
++
++static int tusb8041_i2c_probe(struct i2c_client *i2c,
++ const struct i2c_device_id *id)
++{
++ struct tusb8041 *hub;
++
++ hub = devm_kzalloc(&i2c->dev, sizeof(*hub), GFP_KERNEL);
++ if (!hub)
++ return -ENOMEM;
++
++ i2c_set_clientdata(i2c, hub);
++ hub->dev = &i2c->dev;
++
++ return tusb8041_probe(hub);
++}
++
++#ifdef CONFIG_PM_SLEEP
++static int tusb8041_i2c_suspend(struct device *dev)
++{
++ struct i2c_client *client = to_i2c_client(dev);
++ struct tusb8041 *hub = i2c_get_clientdata(client);
++
++ tusb8041_switch_mode(hub, TUSB8041_MODE_STANDBY);
++
++ return 0;
++}
++
++static int tusb8041_i2c_resume(struct device *dev)
++{
++ struct i2c_client *client = to_i2c_client(dev);
++ struct tusb8041 *hub = i2c_get_clientdata(client);
++
++ tusb8041_switch_mode(hub, hub->mode);
++
++ return 0;
++}
++#endif
++
++static SIMPLE_DEV_PM_OPS(tusb8041_i2c_pm_ops, tusb8041_i2c_suspend,
++ tusb8041_i2c_resume);
++
++static const struct i2c_device_id tusb8041_id[] = {
++ { "tusb8041", 0 },
++ { }
++};
++MODULE_DEVICE_TABLE(i2c, tusb8041_id);
++
++#ifdef CONFIG_OF
++static const struct of_device_id tusb8041_of_match[] = {
++ { .compatible = "ti,tusb8041" },
++ {}
++};
++MODULE_DEVICE_TABLE(of, tusb8041_of_match);
++#endif
++
++static struct i2c_driver tusb8041_i2c_driver = {
++ .driver = {
++ .name = "tusb8041",
++ .pm = &tusb8041_i2c_pm_ops,
++ .of_match_table = of_match_ptr(tusb8041_of_match),
++ },
++ .probe = tusb8041_i2c_probe,
++ .id_table = tusb8041_id,
++};
++module_i2c_driver(tusb8041_i2c_driver);
++
++MODULE_DESCRIPTION("TUSB8041 USB HUB driver");
++MODULE_LICENSE("GPL v2");
+--
+2.7.4
+
diff --git a/bsp/meta-rcar/meta-rcar-gen3-adas/recipes-kernel/linux/linux-renesas/0418-arm64-dts-renesas-ulcb-vb2-fix-USB30-and-HUB.patch b/bsp/meta-rcar/meta-rcar-gen3-adas/recipes-kernel/linux/linux-renesas/0418-arm64-dts-renesas-ulcb-vb2-fix-USB30-and-HUB.patch
new file mode 100644
index 00000000..b39c51fb
--- /dev/null
+++ b/bsp/meta-rcar/meta-rcar-gen3-adas/recipes-kernel/linux/linux-renesas/0418-arm64-dts-renesas-ulcb-vb2-fix-USB30-and-HUB.patch
@@ -0,0 +1,116 @@
+From ef159033e2ef9917c15335ba89bcbeb4270773c6 Mon Sep 17 00:00:00 2001
+From: Andrey Gusakov <andrey.gusakov@cogentembedded.com>
+Date: Tue, 11 Jun 2019 16:21:41 +0300
+Subject: [PATCH 5/6] arm64: dts: renesas: ulcb-vb2: fix USB30 and HUB
+
+- add two HUB nodes as HUB can populate one of two i2c addresses
+depending on power supply start order. Driver just fixes few
+registers values over i2c for proper operation.
+- same driver handles reset gpio, so remove regulator.
+- add pinctl for XHCI and remove PWEN regulator.
+
+Signed-off-by: Andrey Gusakov <andrey.gusakov@cogentembedded.com>
+---
+ arch/arm64/boot/dts/renesas/ulcb-vb2.dtsi | 58 +++++++++++++++++++------------
+ 1 file changed, 35 insertions(+), 23 deletions(-)
+
+diff --git a/arch/arm64/boot/dts/renesas/ulcb-vb2.dtsi b/arch/arm64/boot/dts/renesas/ulcb-vb2.dtsi
+index 5831d12..50cdfd8 100644
+--- a/arch/arm64/boot/dts/renesas/ulcb-vb2.dtsi
++++ b/arch/arm64/boot/dts/renesas/ulcb-vb2.dtsi
+@@ -74,27 +74,7 @@
+ regulator-always-on;
+ };
+
+- hub_reset: regulator@9 {
+- compatible = "regulator-fixed";
+- regulator-name = "hub_reset";
+- regulator-min-microvolt = <3300000>;
+- regulator-max-microvolt = <3300000>;
+- gpio = <&gpio5 5 0>;
+- enable-active-high;
+- regulator-always-on;
+- };
+-
+- hub_power: regulator@10 {
+- compatible = "regulator-fixed";
+- regulator-name = "hub_power";
+- regulator-min-microvolt = <5000000>;
+- regulator-max-microvolt = <5000000>;
+- gpio = <&gpio6 28 0>;
+- enable-active-high;
+- regulator-always-on;
+- };
+-
+- can2_power: regulator@11 {
++ can2_power: regulator@9 {
+ compatible = "regulator-fixed";
+ regulator-name = "can2_power";
+ regulator-min-microvolt = <3300000>;
+@@ -103,7 +83,7 @@
+ enable-active-high;
+ };
+
+- can3_power: regulator@12 {
++ can3_power: regulator@10 {
+ compatible = "regulator-fixed";
+ regulator-name = "can3_power";
+ regulator-min-microvolt = <3300000>;
+@@ -242,6 +222,12 @@
+ function = "usb2";
+ };
+
++ usb30_pins: usb30 {
++ groups = "usb30";
++ function = "usb30";
++ };
++
++
+ can0_pins: can0 {
+ groups = "can0_data_a";
+ function = "can0";
+@@ -449,7 +435,30 @@
+ #size-cells = <0>;
+ reg = <4>;
+ /* USB3.0 HUB node(s) */
+- /* addr of TUSB8041 is 100.0100 = 0x44 */
++ tusb8041_44@44 {
++ compatible = "ti,tusb8041";
++ reg = <0x44>;
++ reset-gpios = <&gpio5 5 0>;
++ ti,registers = /bits/ 8 <
++ 0x05 0x10
++ 0x06 0x0f
++ 0x07 0x8f
++ 0x08 0x0f
++ 0x0a 0x20
++ 0x0b 0x80>;
++ };
++ tusb8041_45@45 {
++ compatible = "ti,tusb8041";
++ reg = <0x45>;
++ reset-gpios = <&gpio5 5 0>;
++ ti,registers = /bits/ 8 <
++ 0x05 0x10
++ 0x06 0x0f
++ 0x07 0x8f
++ 0x08 0x0f
++ 0x0a 0x20
++ 0x0b 0x80>;
++ };
+ };
+
+ i2c@1 {
+@@ -1594,6 +1603,9 @@
+ };
+
+ &xhci0 {
++ pinctrl-0 = <&usb30_pins>;
++ pinctrl-names = "default";
++
+ status = "okay";
+ };
+
+--
+2.7.4
+
diff --git a/bsp/meta-rcar/meta-rcar-gen3-adas/recipes-kernel/linux/linux-renesas/0419-phy-rcar-gen3-usb2-power-on-port-in-host-mode-to.patch b/bsp/meta-rcar/meta-rcar-gen3-adas/recipes-kernel/linux/linux-renesas/0419-phy-rcar-gen3-usb2-power-on-port-in-host-mode-to.patch
new file mode 100644
index 00000000..4987d79b
--- /dev/null
+++ b/bsp/meta-rcar/meta-rcar-gen3-adas/recipes-kernel/linux/linux-renesas/0419-phy-rcar-gen3-usb2-power-on-port-in-host-mode-to.patch
@@ -0,0 +1,62 @@
+From 47f3896e8938401a641d5c48c8b1dc9389fcb7b1 Mon Sep 17 00:00:00 2001
+From: Andrey Gusakov <andrey.gusakov@cogentembedded.com>
+Date: Wed, 28 Aug 2019 17:16:35 +0300
+Subject: [PATCH 6/6] phy: rcar-gen3-usb2: power-on port in host mode to
+
+Signed-off-by: Andrey Gusakov <andrey.gusakov@cogentembedded.com>
+---
+ drivers/phy/renesas/phy-rcar-gen3-usb2.c | 12 ++++++++----
+ 1 file changed, 8 insertions(+), 4 deletions(-)
+
+diff --git a/drivers/phy/renesas/phy-rcar-gen3-usb2.c b/drivers/phy/renesas/phy-rcar-gen3-usb2.c
+index 0d03c5d..c35f1a1 100644
+--- a/drivers/phy/renesas/phy-rcar-gen3-usb2.c
++++ b/drivers/phy/renesas/phy-rcar-gen3-usb2.c
+@@ -156,7 +156,8 @@ static void rcar_gen3_init_for_host(struct rcar_gen3_chan *ch)
+ rcar_gen3_enable_vbus_ctrl(ch, 1);
+
+ ch->extcon_host = true;
+- schedule_work(&ch->work);
++ if (ch->extcon)
++ schedule_work(&ch->work);
+ }
+
+ static void rcar_gen3_init_for_peri(struct rcar_gen3_chan *ch)
+@@ -166,7 +167,8 @@ static void rcar_gen3_init_for_peri(struct rcar_gen3_chan *ch)
+ rcar_gen3_enable_vbus_ctrl(ch, 0);
+
+ ch->extcon_host = false;
+- schedule_work(&ch->work);
++ if (ch->extcon)
++ schedule_work(&ch->work);
+ }
+
+ static void rcar_gen3_init_for_b_host(struct rcar_gen3_chan *ch)
+@@ -290,8 +292,6 @@ static void rcar_gen3_init_otg(struct rcar_gen3_chan *ch)
+ void __iomem *usb2_base = ch->base;
+ u32 val;
+
+- val = readl(usb2_base + USB2_VBCTRL);
+- writel(val | USB2_VBCTRL_DRVVBUSSEL, usb2_base + USB2_VBCTRL);
+ writel(USB2_OBINT_BITS, usb2_base + USB2_OBINTSTA);
+ val = readl(usb2_base + USB2_OBINTEN);
+ writel(val | USB2_OBINT_BITS, usb2_base + USB2_OBINTEN);
+@@ -321,11 +321,15 @@ static int rcar_gen3_phy_usb2_init(struct phy *p)
+ writel(USB2_OC_TIMSET_INIT, usb2_base + USB2_OC_TIMSET);
+ val = readl(usb2_base + USB2_VBCTRL);
+ val &= ~USB2_VBCTRL_OCCLREN;
++ /* setup Vbus control pin */
++ val |= USB2_VBCTRL_DRVVBUSSEL;
+ writel(val, usb2_base + USB2_VBCTRL);
+
+ /* Initialize otg part */
+ if (channel->has_otg_pins)
+ rcar_gen3_init_otg(channel);
++ else
++ rcar_gen3_init_for_host(channel);
+
+ return 0;
+ }
+--
+2.7.4
+
diff --git a/bsp/meta-rcar/meta-rcar-gen3-adas/recipes-kernel/linux/linux-renesas/cma.cfg b/bsp/meta-rcar/meta-rcar-gen3-adas/recipes-kernel/linux/linux-renesas/cma.cfg
new file mode 100644
index 00000000..e5b5e83f
--- /dev/null
+++ b/bsp/meta-rcar/meta-rcar-gen3-adas/recipes-kernel/linux/linux-renesas/cma.cfg
@@ -0,0 +1,2 @@
+CONFIG_CMA_SIZE_MBYTES=256
+CONFIG_CMA_SIZE_SEL_MBYTES=y
diff --git a/bsp/meta-rcar/meta-rcar-gen3-adas/recipes-kernel/linux/linux-renesas/condor.cfg b/bsp/meta-rcar/meta-rcar-gen3-adas/recipes-kernel/linux/linux-renesas/condor.cfg
new file mode 100644
index 00000000..015a94a4
--- /dev/null
+++ b/bsp/meta-rcar/meta-rcar-gen3-adas/recipes-kernel/linux/linux-renesas/condor.cfg
@@ -0,0 +1,34 @@
+CONFIG_ARCH_R8A77980=y
+CONFIG_CAN=y
+CONFIG_CAN_BCM=y
+CONFIG_CAN_RAW=y
+CONFIG_CAN_DEV=y
+CONFIG_CAN_CALC_BITTIMING=y
+CONFIG_CAN_RCAR=y
+CONFIG_CAN_RCAR_CANFD=y
+CONFIG_DUMMY=y
+CONFIG_DRM_I2C_ADV7511=y
+CONFIG_GPIO_PCA953X=y
+CONFIG_GPIO_PCA953X_IRQ=y
+CONFIG_VIDEO_ADV_DEBUG=y
+CONFIG_VIDEO_RCAR_VIN_LEGACY=y
+CONFIG_VIDEO_RCAR_CSI2_LEGACY=y
+# CONFIG_VIDEO_RCAR_VIN is not set
+# CONFIG_VIDEO_RCAR_CSI2 is not set
+CONFIG_SOC_CAMERA=y
+CONFIG_SOC_CAMERA_SCALE_CROP=y
+CONFIG_SOC_CAMERA_PLATFORM=y
+CONFIG_SOC_CAMERA_MAX9286=y
+CONFIG_SOC_CAMERA_OV106XX=y
+CONFIG_INPUT_TOUCHSCREEN=y
+CONFIG_INPUT_UINPUT=y
+CONFIG_TOUCHSCREEN_PROPERTIES=y
+CONFIG_HID_MULTITOUCH=y
+CONFIG_SERIAL_SH_SCI_DMA=y
+CONFIG_UIO=y
+CONFIG_UIO_PDRV_GENIRQ=m
+CONFIG_SH_ETH=y
+CONFIG_SATA_ACARD_AHCI=y
+CONFIG_GPIO_SYSFS=y
+CONFIG_DRM_THINE_THC63LVD1024=y
+CONFIG_PHY_RCAR_GEN3_PCIE=y
diff --git a/bsp/meta-rcar/meta-rcar-gen3-adas/recipes-kernel/linux/linux-renesas/disable-unused.cfg b/bsp/meta-rcar/meta-rcar-gen3-adas/recipes-kernel/linux/linux-renesas/disable-unused.cfg
new file mode 100644
index 00000000..ea050a8e
--- /dev/null
+++ b/bsp/meta-rcar/meta-rcar-gen3-adas/recipes-kernel/linux/linux-renesas/disable-unused.cfg
@@ -0,0 +1,33 @@
+# CONFIG_ARCH_SUNXI is not set
+# CONFIG_ARCH_ALPINE is not set
+# CONFIG_ARCH_BCM2835 is not set
+# CONFIG_ARCH_BCM_IPROC is not set
+# CONFIG_ARCH_BERLIN is not set
+# CONFIG_ARCH_BRCMSTB is not set
+# CONFIG_ARCH_EXYNOS is not set
+# CONFIG_ARCH_LAYERSCAPE is not set
+# CONFIG_ARCH_LG1K is not set
+# CONFIG_ARCH_HISI is not set
+# CONFIG_ARCH_MEDIATEK is not set
+# CONFIG_ARCH_MESON is not set
+# CONFIG_ARCH_MVEBU is not set
+# CONFIG_ARCH_QCOM is not set
+# CONFIG_ARCH_ROCKCHIP is not set
+# CONFIG_ARCH_SEATTLE is not set
+# CONFIG_ARCH_STRATIX10 is not set
+# CONFIG_ARCH_TEGRA is not set
+# CONFIG_ARCH_SPRD is not set
+# CONFIG_ARCH_THUNDER is not set
+# CONFIG_ARCH_THUNDER2 is not set
+# CONFIG_ARCH_UNIPHIER is not set
+# CONFIG_ARCH_VEXPRESS is not set
+# CONFIG_ARCH_XGENE is not set
+# CONFIG_ARCH_ZX is not set
+# CONFIG_ARCH_ZYNQMP is not set
+# CONFIG_SUNXI_SRAM is not set
+# CONFIG_RESET_BERLIN is not set
+# CONFIG_RESET_MESON is not set
+# CONFIG_RESET_SOCFPGA is not set
+# CONFIG_RESET_SUNXI is not set
+# CONFIG_RESET_TEGRA_BPMP is not set
+# CONFIG_MESON_SM is not set
diff --git a/bsp/meta-rcar/meta-rcar-gen3-adas/recipes-kernel/linux/linux-renesas/eagle.cfg b/bsp/meta-rcar/meta-rcar-gen3-adas/recipes-kernel/linux/linux-renesas/eagle.cfg
new file mode 100644
index 00000000..d6ee9177
--- /dev/null
+++ b/bsp/meta-rcar/meta-rcar-gen3-adas/recipes-kernel/linux/linux-renesas/eagle.cfg
@@ -0,0 +1,35 @@
+CONFIG_ARCH_R8A77970=y
+CONFIG_CAN=y
+CONFIG_CAN_BCM=y
+CONFIG_CAN_RAW=y
+CONFIG_CAN_DEV=y
+CONFIG_CAN_CALC_BITTIMING=y
+CONFIG_CAN_RCAR=y
+CONFIG_CAN_RCAR_CANFD=y
+CONFIG_DUMMY=y
+CONFIG_DRM_I2C_ADV7511=y
+CONFIG_GPIO_PCA953X=y
+CONFIG_GPIO_PCA953X_IRQ=y
+CONFIG_VIDEO_ADV_DEBUG=y
+CONFIG_VIDEO_RCAR_VIN_LEGACY=y
+CONFIG_VIDEO_RCAR_CSI2_LEGACY=y
+# CONFIG_VIDEO_RCAR_VIN is not set
+# CONFIG_VIDEO_RCAR_CSI2 is not set
+CONFIG_SOC_CAMERA=y
+CONFIG_SOC_CAMERA_SCALE_CROP=y
+CONFIG_SOC_CAMERA_PLATFORM=y
+CONFIG_SOC_CAMERA_MAX9286=y
+CONFIG_SOC_CAMERA_OV106XX=y
+CONFIG_INPUT_TOUCHSCREEN=y
+CONFIG_INPUT_UINPUT=y
+CONFIG_TOUCHSCREEN_PROPERTIES=y
+CONFIG_HID_MULTITOUCH=y
+CONFIG_SERIAL_SH_SCI_DMA=y
+CONFIG_UIO=y
+CONFIG_MFD_DA9063=y
+CONFIG_INPUT_DA9063_ONKEY=y
+CONFIG_DA9063_WATCHDOG=y
+CONFIG_REGULATOR_DA9063=y
+CONFIG_RCAR_THERMAL=y
+CONFIG_GPIO_SYSFS=y
+CONFIG_DRM_THINE_THC63LVD1024=y
diff --git a/bsp/meta-rcar/meta-rcar-gen3-adas/recipes-kernel/linux/linux-renesas/hyperflash.cfg b/bsp/meta-rcar/meta-rcar-gen3-adas/recipes-kernel/linux/linux-renesas/hyperflash.cfg
new file mode 100644
index 00000000..df45d5e9
--- /dev/null
+++ b/bsp/meta-rcar/meta-rcar-gen3-adas/recipes-kernel/linux/linux-renesas/hyperflash.cfg
@@ -0,0 +1,2 @@
+CONFIG_MTD=y
+CONFIG_MTD_RPC_HYPERFLASH=y
diff --git a/bsp/meta-rcar/meta-rcar-gen3-adas/recipes-kernel/linux/linux-renesas/imr.cfg b/bsp/meta-rcar/meta-rcar-gen3-adas/recipes-kernel/linux/linux-renesas/imr.cfg
new file mode 100644
index 00000000..cc7f69e9
--- /dev/null
+++ b/bsp/meta-rcar/meta-rcar-gen3-adas/recipes-kernel/linux/linux-renesas/imr.cfg
@@ -0,0 +1,3 @@
+CONFIG_VIDEO_RENESAS_IMR=m
+CONFIG_UIO=y
+CONFIG_UIO_IMR=m
diff --git a/bsp/meta-rcar/meta-rcar-gen3-adas/recipes-kernel/linux/linux-renesas/nvme.cfg b/bsp/meta-rcar/meta-rcar-gen3-adas/recipes-kernel/linux/linux-renesas/nvme.cfg
new file mode 100644
index 00000000..740a25e4
--- /dev/null
+++ b/bsp/meta-rcar/meta-rcar-gen3-adas/recipes-kernel/linux/linux-renesas/nvme.cfg
@@ -0,0 +1,2 @@
+CONFIG_NVME_CORE=y
+CONFIG_BLK_DEV_NVME=y
diff --git a/bsp/meta-rcar/meta-rcar-gen3-adas/recipes-kernel/linux/linux-renesas/qspi.cfg b/bsp/meta-rcar/meta-rcar-gen3-adas/recipes-kernel/linux/linux-renesas/qspi.cfg
new file mode 100644
index 00000000..9a1c695e
--- /dev/null
+++ b/bsp/meta-rcar/meta-rcar-gen3-adas/recipes-kernel/linux/linux-renesas/qspi.cfg
@@ -0,0 +1,3 @@
+CONFIG_SPI_RENESAS_RPC=y
+CONFIG_MTD_BLOCK=y
+CONFIG_JFFS2_FS=y
diff --git a/bsp/meta-rcar/meta-rcar-gen3-adas/recipes-kernel/linux/linux-renesas/renesas-not-applied.scc b/bsp/meta-rcar/meta-rcar-gen3-adas/recipes-kernel/linux/linux-renesas/renesas-not-applied.scc
new file mode 100644
index 00000000..6d542846
--- /dev/null
+++ b/bsp/meta-rcar/meta-rcar-gen3-adas/recipes-kernel/linux/linux-renesas/renesas-not-applied.scc
@@ -0,0 +1,16 @@
+0014-lib-swiotlb-reduce-verbosity.patch
+0018-arm64-renesas-r8a7797-Add-Renesas-R8A7797-SoC-suppor.patch
+0026-drm-adv7511-add-polling-mode-when-no-irq-available.patch
+0051-arm64-renesas-r8a7798-Add-Renesas-R8A7798-SoC-suppor.patch
+0052-soc-renesas-rcar-sysc-Add-workaround-for-A3-PD-issue.patch
+0079-Revert-dmaengine-rcar-dmac-use-TCRB-instead-of-TCR-f.patch
+0082-gpio-pca953x-fix-interrupt-trigger.patch
+0090-ASoC-rsnd-fixup-rsnd_ssi_master_clk_start-user-count.patch
+0100-LVDS-ar0132-use-raw12.patch
+0101-LVDS-ar0132-use-context-swwitch.patch
+0103-gpu-drm-rcar-du-Extend-VSP1-DRM-interface.patch
+0104-media-vsp1-extend-DRM-VSP1-interface.patch
+0105-media-rcar-imr-IMR-driver-updates-for-raw-DL.patch
+0106-media-rcar-imr-Add-RSE-support.patch
+0110-mmc-tmio-Add-SDHI-SEQUENCER-support.patch
+0111-mmc-renesas_sdhi-Add-SDHI-SEQUENCER-support.patch
diff --git a/bsp/meta-rcar/meta-rcar-gen3-adas/recipes-kernel/linux/linux-renesas/renesas.scc b/bsp/meta-rcar/meta-rcar-gen3-adas/recipes-kernel/linux/linux-renesas/renesas.scc
new file mode 100644
index 00000000..31146743
--- /dev/null
+++ b/bsp/meta-rcar/meta-rcar-gen3-adas/recipes-kernel/linux/linux-renesas/renesas.scc
@@ -0,0 +1,357 @@
+patch 0001-spi-sh-msiof-fixes.patch
+patch 0002-spi-spidev-add-spi-gpio-into-spidev.patch
+patch 0003-spi-spi-gpio-fix-CPOL-mode.patch
+patch 0006-spi-spi-gpio-fix-set-CPOL-default-inverted.patch
+patch 0008-Revert-PCI-rcar-pcie-Add-bus-notifier-so-we-can-limi.patch
+patch 0009-arm64-dma-check-parent-bus-restrictions-in-dma_capab.patch
+patch 0010-can-rcar_can-add-enable-and-standby-control-pins.patch
+patch 0011-can-rcar_canfd-add-enable-and-standby-control-pins.patch
+patch 0012-mtd-Add-RPC-HyperFlash-driver.patch
+patch 0013-IMR-driver-interim-patch.patch
+patch 0015-gpio-max732x-fix-gpio-set.patch
+patch 0016-gpio-gpiolib-suppress-gpiod-warning.patch
+patch 0017-media-soc_camera-add-legacy-VIN-CSI2.patch
+patch 0019-Revert-media-v4l2-async-remove-unneeded-.registered_.patch
+patch 0020-ti-st-add-device-tree-support.patch
+patch 0021-btwilink-add-minimal-device-tree-support.patch
+patch 0022-ASoC-Modify-check-condition-of-multiple-bindings-of-.patch
+patch 0023-ASoC-add-dummy-Si468x-driver.patch
+patch 0024-wl18xx-do-not-invert-IRQ-on-WLxxxx-side.patch
+patch 0025-drm-adv7511-Enable-HPD-interrupts-to-support-hotplug.patch
+patch 0027-gpu-drm-bridge-adv7511-Add-interlaced-mode-support.patch
+patch 0030-Gen3-LVDS-cameras.patch
+patch 0031-media-i2c-Add-ov5647-sensor.patch
+patch 0032-media-i2c-Add-ov5642-sensor.patch
+patch 0033-media-soc-camera-fix-parallel-i-f-in-VIN.patch
+patch 0034-media-soc_camera-Fix-VIDIOC_S_SELECTION-ioctl-miscal.patch
+patch 0036-Add-MOST-support-for-r8a77965.patch
+patch 0037-media-soc_camera-rcar_vin-Fix-VnCSI_IFMD-settings.patch
+patch 0038-media-soc_camera-rcar_vin-Add-R-Car-M3N-support.patch
+patch 0039-media-soc_camera-rcar_csi2-Add-R-Car-M3N-support.patch
+patch 0040-arm64-dts-renesas-add-ADAS-boards.patch
+patch 0041-arm64-dts-renesas-ulcb-kf-Move-panel-configuration-t.patch
+patch 0042-arm64-dts-renesas-r8a7795-es1-h3ulcb-disable-eMMC.patch
+patch 0043-pinctrl-sh-pfc-pfc-r8a77965-Add-missing-avb_mii-pin-.patch
+patch 0045-clk-r8a779x-add-mlp-clock.patch
+patch 0046-arm64-dts-renesas-r8a779x-add-mlp-nodes.patch
+patch 0049-clk-r8a779x-add-IMP-clock.patch
+patch 0050-arm64-dts-renesas-r8a779x-add-IMP-nodes.patch
+patch 0062-IIO-lsm9ds0-add-IMU-driver.patch
+patch 0063-ASoC-PCM3168A-add-TDM-modes-merge-ADC-and-DAC.patch
+patch 0064-drm-bridge-adv7511-Add-frequency-and-vrefresh-limita.patch
+patch 0066-pci-pcie-rcar-add-regulators-support.patch
+patch 0067-ti-st-use-proper-way-to-get-shutdown-gpio.patch
+patch 0068-drm-adv7511-use-smbus-to-retrieve-edid.patch
+patch 0071-ASoC-add-dummy-device-for-WL18xx-PCM-audio.patch
+patch 0072-usb-hub-disable-autosuspend-for-SMSC-hubs.patch
+patch 0073-MOST-dim2-add-device-tree-support.patch
+patch 0074-MOST-dim2-add-R-Car3-related-initialization.patch
+patch 0075-MOST-core-fix-memory-allocation-at-arm64.patch
+patch 0076-MOST-dim2-Renesas-R-Car3-variant.patch
+patch 0077-MOST-dim2-add-timeouts.patch
+patch 0078-MOST-aim-fix-null-pointer-crash.patch
+patch 0109-serial-sh-sci-Fix-minimal-rx_timeout-value.patch
+patch 0112-ARM64-dts-renesas-ulcb-Make-AK4613-sound-device-name.patch
+patch 0113-arm64-dts-ulcb-kf-increase-SDIO-frequency-for-WLAN-c.patch
+patch 0114-Sony-IMX219-driver.patch
+patch 0116-media-i2c-soc_camera-Fix-Bad-of_node_put-error.patch
+patch 0117-rcar-vin-fix-get_selection-use.patch
+patch 0118-clk-clk-gpio-Allow-GPIO-to-sleep-in-set-get_parent.patch
+patch 0119-i2c-mix-pca954x-reset-mux-in-case-of-error-during-bu.patch
+patch 0120-arm64-dts-ulcb-kf-pcm3168a-reset-earlier-i2c-mux-dis.patch
+patch 0122-block-blk-mq-Fix-IO-hang.patch
+patch 0123-nvme-Workaround-Samsung-970-Pro-power-state-issues.patch
+patch 0124-nvme-pci-add-SGL-support.patch
+patch 0125-nvme-pci-don-t-open-code-nvme_reset_ctrl.patch
+patch 0126-nvme-pci-limit-max-IO-size-and-segments-to-avoid-hig.patch
+patch 0127-swiotlb-Respect-DMA_ATTR_NO_WARN-in-swiotlb_map_sg_a.patch
+patch 0128-arm64-dts-Add-H3ULCB-VideoBox-2.1-support.patch
+patch 0129-can-rcar_canfd-fix-possible-IRQ-storm-on-high-load.patch
+patch 0130-LVDS-ar0132-use-context-swwitch.patch
+patch 0131-media-i2c-soc_camera-Bunch-update-from-2.23.1.patch
+patch 0132-lvds-ti960-fix-frame-sync-time-for-different-ref-clo.patch
+patch 0133-lvds-add-AR0323-imager.patch
+patch 0134-lvds-add-ISX016-imager.patch
+patch 0135-LVDS-ar0233-set-frame-size-1920x1200.patch
+patch 0136-lvds-AR0233-add-different-vendor.patch
+patch 0137-lvds-poll-ub960-deserializer-lock-status.patch
+patch 0138-lvds-AR0231-modify-with-rev7-silicon.patch
+patch 0139-lvds-AR0233-modify-with-rev2-silicon.patch
+patch 0140-lvds-ti9x4-fix-remote-gpio-enablement-for-4-cams.patch
+patch 0141-media-soc_camera-imx390-Add-new-V4L-controls.patch
+patch 0142-lvds-AR233-add-rev1-silion-setup.patch
+patch 0143-LVDS-AR0231-add-rev6-rev4-on-max9286.patch
+patch 0144-lvds-add-OV10640-imager.patch
+patch 0145-lvds-ti9x4-fix-remote-gpio-enablement-on-UB913.patch
+patch 0146-lvds-add-dummy-imager-driver.patch
+patch 0147-lvds-ti9x4-use-REFCLK-23.0MHz.patch
+patch 0148-lvds-ar0231-fix-comments.patch
+patch 0149-lvds-ISX019-rename-isx016-to-isx019.patch
+patch 0150-lvds-add-ISX016-imager.patch
+patch 0151-lvds-ti9x4-add-DVP-LSB-MSB-selection.patch
+patch 0152-lvds-AR323-fix-reset-gpio-nadling.patch
+patch 0153-lvds-OV495-fix-reset-gpio-handling.patch
+patch 0154-lvds-AR0323-replace-with-REV2-setup-table.patch
+patch 0155-AR0143-add-original-ONSEMI-setup.patch
+patch 0156-AR0143-enable-3exp-in-custom-setup.patch
+patch 0157-AR0143-add-choose-of-imager-setup.patch
+patch 0158-MAX9286-fix-BWS-setup-to-reserve-reboot.patch
+patch 0159-MAX9286-adjust-POC-trigger-for-unstable-link.patch
+patch 0160-lvds-onsemi-fix-revsion-parsing.patch
+patch 0161-lvds-AR0233-add-module-trigger-parameter.patch
+patch 0162-lvds-AR0233-migrate-to-composed-tables.patch
+patch 0163-lvds-AP0101-AR014X-add-TI-serializers.patch
+patch 0164-lvds-fix-vendor-names.patch
+patch 0165-LVDS-add-GW5200-IMX390-camera.patch
+patch 0166-lvds-AR0233-add-superexposure-plus.patch
+patch 0167-lvds-AR0233-fix-matrix-size-set-default-h-vflip.patch
+patch 0168-lvds-ISX019-fix-add-address-intf-fix-read-write.patch
+patch 0169-lvds-OVT-add-dvp_order-parameter-for-ov10635.patch
+patch 0170-media-i2c-add-AR0147-imager.patch
+patch 0171-lvds-ONSEMI-fix-matrix-position-during-crop.patch
+patch 0172-media-i2c-ar0147-fix-super-exposure-artifact-line.patch
+patch 0173-lvds-ti9x4-fix-remote-gpio-setup.patch
+patch 0174-arm64-dts-renesas-ulcb-vb2-Drive-CAN-controller-rese.patch
+patch 0175-lvds-ov2775-add-exposure-gain.patch
+patch 0177-media-rcar_vin-add-GREY-Y8-bypass.patch
+patch 0178-lvds-add-OV2311-imager.patch
+patch 0179-media-i2c-soc_camera-Fix-more-Bad-of_node_put-errors.patch
+patch 0180-media-i2c-ov490-add-LI-cameras.patch
+patch 0181-ARM64-dts-Remove-conflicting-with-mainline-V3M-and-V.patch
+patch 0182-iommu-msm-Claim-bus-ops-on-probe.patch
+patch 0183-iommu-Clean-up-of_iommu_init_fn.patch
+patch 0184-iommu-ipmmu-vmsa-Hook-up-r8a779-70-95-DT-matching-co.patch
+patch 0185-dt-bindings-display-bridge-Document-THC63LVD1024-LVD.patch
+patch 0186-gpio-rcar-document-R8A77980-bindings.patch
+patch 0187-arm64-dts-renesas-r8a77980-add-SMP-support.patch
+patch 0188-arm64-dts-renesas-r8a77980-add-GEther-support.patch
+patch 0189-arm64-dts-renesas-v3hsk-add-GEther-support.patch
+patch 0190-arm64-dts-renesas-r8a77980-add-I2C-support.patch
+patch 0191-arm64-dts-renesas-condor-add-I2C0-support.patch
+patch 0192-arm64-dts-renesas-r8a77980-add-GPIO-support.patch
+patch 0193-arm64-dts-renesas-condor-v3hsk-specify-Ethernet-PHY-.patch
+patch 0194-arm64-dts-renesas-r8a77980-add-FCPVD-VSPD-DU-LVDS-su.patch
+patch 0195-sh_eth-fix-enum-RPADIR_BIT.patch
+patch 0196-sh_eth-remove-sh_eth_cpu_data-rpadir_value.patch
+patch 0197-sh_eth-fix-enum-A-M-PR_BIT.patch
+patch 0198-iommu-ipmmu-vmsa-Document-R-Car-V3H-and-E3-IPMMU-DT-.patch
+patch 0199-dt-bindings-phy-Renesas-R-Car-Gen3-PCIe-PHY-bindings.patch
+patch 0200-phy-Renesas-R-Car-gen3-PCIe-PHY-driver.patch
+patch 0201-dt-bindings-irqchip-renesas-irqc-Document-r8a77980-s.patch
+patch 0202-arm64-dts-renesas-r8a77980-add-INTC-EX-support.patch
+patch 0203-net-phy-allow-scanning-busses-with-missing-phys.patch
+patch 0204-arm64-dts-renesas-r8a77980-add-RWDT-support.patch
+patch 0205-arm64-enable-CMT-TMU-support-for-Renesas-SoC.patch
+patch 0206-arm64-dts-renesas-r8a77980-add-Cortex-A53-PMU-suppor.patch
+patch 0207-arm64-dts-renesas-r8a77980-move-IPMMU-nodes.patch
+patch 0208-arm64-dts-renesas-r8a779-7-8-0-move-CAN-clock-node.patch
+patch 0209-arm64-dts-renesas-r8a77980-add-CSI2-VIN-support.patch
+patch 0210-arm64-dts-renesas-r8a77970-add-MMC-support.patch
+patch 0211-arm64-dts-renesas-v3msk-add-eMMC-support.patch
+patch 0212-arm64-dts-renesas-condor-v3hsk-add-DU-LVDS-HDMI-supp.patch
+patch 0213-arm64-dts-renesas-r8a77980-add-PCIe-support.patch
+patch 0214-arm64-dts-renesas-condor-add-PCIe-support.patch
+patch 0215-arm64-dts-renesas-v3hsk-Move-lvds0-node.patch
+patch 0216-arm64-dts-renesas-r8a77980-Attach-the-SYS-DMAC-to-th.patch
+patch 0217-arm64-dts-renesas-r8a779-7-8-0-add-CMT-support.patch
+patch 0218-dt-bindings-timer-renesas-tmu-document-R8A779-7-8-0-.patch
+patch 0219-arm64-dts-renesas-r8a779-7-8-0-add-TPU-support.patch
+patch 0220-arm64-dts-renesas-r8a779-7-8-0-add-PWM-support.patch
+patch 0221-media-vsp1-Use-header-display-lists-for-all-WPF-outp.patch
+patch 0222-arm64-dts-renesas-r8a77970-add-thermal-support.patch
+patch 0223-arm64-dts-renesas-r8a77980-add-thermal-support.patch
+patch 0224-arm64-dts-renesas-r8a779-7-8-0-add-TMU-support.patch
+patch 0225-arm64-dts-renesas-r8a779-7-8-0-add-MSIOF-support.patch
+patch 0226-arm64-dts-renesas-r8a77980-Connect-R-Car-V3H-AVB-to-.patch
+patch 0227-clk-renesas-r8a77980-Add-OSC-predivider-configuratio.patch
+patch 0228-clk-renesas-r8a77980-Add-RCLK-for-watchdog-timer.patch
+patch 0229-drm-rcar-du-lvds-add-R8A77980-support.patch
+patch 0230-drivers-flag-buses-which-demand-DMA-configuration.patch
+patch 0231-gpu-host1x-Call-of_dma_configure-after-setting-bus.patch
+patch 0232-gpu-host1x-Cleanup-on-initialization-failure.patch
+patch 0233-dma-mapping-move-dma-configuration-to-bus-infrastruc.patch
+patch 0234-drivers-remove-force-dma-flag-from-buses.patch
+patch 0235-clk-renesas-r8a77980-Add-CMT-clocks.patch
+patch 0236-clk-renesas-r8a77970-Add-SD0H-SD0-clocks-for-SDHI.patch
+patch 0237-clk-renesas-r8a77970-Add-CMT-clocks.patch
+patch 0238-clk-renesas-r8a77970-Add-TMU-clocks.patch
+patch 0239-dt-bindings-display-renesas-du-document-R8A77980-bin.patch
+patch 0240-dt-bindings-display-renesas-lvds-document-R8A77980-b.patch
+patch 0241-clk-renesas-r8a77970-Add-TPU-clock.patch
+patch 0242-mmc-renesas_sdhi_internal_dmac-add-R8A77970-to-white.patch
+patch 0243-dt-bindings-mmc-tmio_mmc-document-Renesas-R8A77970-b.patch
+patch 0244-dt-bindings-thermal-rcar-gen3-thermal-document-R8A77.patch
+patch 0245-thermal-rcar_gen3_thermal-add-R8A77980-support.patch
+patch 0246-dt-bindings-thermal-rcar-thermal-document-R8A77970-b.patch
+patch 0247-thermal-rcar_thermal-add-R8A77970-support.patch
+patch 0248-clk-renesas-r8a77970-Add-RPC-clocks.patch
+patch 0249-pinctrl-sh-pfc-r8a77970-Add-QSPI-pins-groups-and-fun.patch
+patch 0250-pinctrl-sh-pfc-r8a77980-Add-QSPI-pins-groups-and-fun.patch
+patch 0251-media-rcar-rcar-csi2-Update-V3M-E3-PHTW-tables.patch
+patch 0252-soc-renesas-r8a77970-sysc-Remove-non-existent-CR7-po.patch
+patch 0253-soc-renesas-r8a77970-sysc-Correct-names-of-A2DP-A2CN.patch
+patch 0254-soc-renesas-r8a77980-sysc-Correct-names-of-A2DP-01-p.patch
+patch 0255-soc-renesas-r8a77980-sysc-Correct-A3VIP-012-power-do.patch
+patch 0256-clk-renesas-r8a77970-Add-CPEX-clock.patch
+patch 0257-media-rcar-csi2-add-R8A77980-support.patch
+patch 0258-media-rcar-vin-add-R8A77980-support.patch
+patch 0259-pinctrl-sh-pfc-r8a77970-Add-missing-MOD_SEL0-field.patch
+patch 0260-pinctrl-sh-pfc-r8a77980-Add-missing-MOD_SEL0-field.patch
+patch 0261-media-rcar-csi2-Fix-PHTW-table-values-for-E3-V3M.patch
+patch 0262-pinctrl-sh-pfc-Reduce-kernel-size-for-narrow-VIN-cha.patch
+patch 0263-pinctrl-sh-pfc-r8a77970-Deduplicate-VIN-01-pin-defin.patch
+patch 0264-pinctrl-sh-pfc-r8a77980-Deduplicate-VIN1-pin-definit.patch
+patch 0265-arm64-dts-renesas-v3msk-specify-EtherAVB-PHY-IRQ.patch
+patch 0266-sh_eth-rename-sh_eth_cpu_data-hw_checksum.patch
+patch 0267-sh_eth-RX-checksum-offload-support.patch
+patch 0268-sh_eth-offload-RX-checksum-on-R7S72100.patch
+patch 0269-sh_eth-offload-RX-checksum-on-R8A7740.patch
+patch 0270-sh_eth-offload-RX-checksum-on-R8A77980.patch
+patch 0271-sh_eth-offload-RX-checksum-on-SH7734.patch
+patch 0272-sh_eth-offload-RX-checksum-on-SH7763.patch
+patch 0273-clk-renesas-rcar-gen3-Factor-out-cpg_reg_modify.patch
+patch 0274-clk-renesas-rcar-gen3-Add-spinlock.patch
+patch 0275-clk-renesas-rcar-gen3-Add-RPC-clocks.patch
+patch 0276-clk-renesas-r8a77980-Add-RPC-clocks.patch
+patch 0277-pinctrl-sh-pfc-r8a77970-Rename-IOCTRLx-registers.patch
+patch 0278-pinctrl-sh-pfc-r8a77980-Rename-IOCTRLx-registers.patch
+patch 0279-clk-renesas-r8a77980-Fix-RPC-IF-module-clock-s-paren.patch
+patch 0280-arm64-dts-renesas-r8a77980-Add-renesas-id-to-VIN.patch
+patch 0281-arm64-dts-renesas-eagle-Add-x1-clock.patch
+patch 0282-arm64-dts-renesas-r8a77980-condor-Add-GEther-support.patch
+patch 0283-iommu-ipmmu-vmsa-Add-r8a77980-support.patch
+patch 0284-iommu-ipmmu-vmsa-Fix-NULL-pointer-dereference.patch
+patch 0285-iommu-ipmmu-vmsa-Add-r8a779-7-8-0-whitelist.patch
+patch 0286-clk-renesas-r8a77980-cpg-mssr-Add-VIN-clocks.patch
+patch 0287-clk-renesas-r8a77970-cpg-mssr-Add-IMR-clocks.patch
+patch 0288-clk-renesas-r8a77980-cpg-mssr-Add-IMR-clocks.patch
+patch 0289-clk-renesas-r8a77970-cpg-mssr-Add-ISP-clock.patch
+patch 0290-clk-renesas-r8a77980-cpg-mssr-Add-ISP-clocks.patch
+patch 0291-clk-renesas-r8a77980-cpg-mssr-Add-IMP-clocks.patch
+patch 0292-clk-renesas-r8a77980-cpg-mssr-Add-VIP-clocks.patch
+patch 0293-clk-renesas-r8a77970-cpg-mssr-Add-IMP-clocks.patch
+patch 0294-media-soc_camera-Add-CONFIG_VIDEO_ADV_DEBUG-support.patch
+patch 0295-media-platform-soc_camera-Add-V4L2-R-Car-ISP-driver.patch
+patch 0296-media-platform-soc_camera-rcar_isp-Fix-unused-variab.patch
+patch 0297-media-platform-soc_camera-rcar_vin-Update-R-Car-V3M-.patch
+patch 0298-media-platform-soc_camera-rcar_vin-Add-r8a77980-supp.patch
+patch 0299-media-platform-soc_camera-rcar_csi2-r8a77970-Update-.patch
+patch 0300-media-platform-soc_camera-rcar_csi2-Add-r8a77980-sup.patch
+patch 0301-arm64-dts-renesas-r8a77970-Convert-VIN-nodes-to-soc_.patch
+patch 0302-arm64-dts-renesas-r8a77980-Convert-VIN-nodes-to-soc_.patch
+patch 0303-arm64-dts-renesas-r8a77970-Convert-SCI2-nodes-to-soc.patch
+patch 0304-arm64-dts-renesas-r8a77980-Convert-CSI2-nodes-to-soc.patch
+patch 0305-arm64-dts-renesas-r8a77970-Add-IMR-nodes.patch
+patch 0306-arm64-dts-renesas-r8a77980-Add-IMR-nodes.patch
+patch 0307-arm64-dts-renesas-r8a77970-Add-ISP-node.patch
+patch 0308-arm64-dts-renesas-r8a77980-Add-ISP-nodes.patch
+patch 0309-arm64-dts-renesas-eagle-Add-video-input-support.patch
+patch 0310-arm64-dts-renesas-condor-Add-video-input-support.patch
+patch 0311-arm64-dts-renesas-v3msk-Add-reserved-memory-nodes.patch
+patch 0312-arm64-dts-renesas-v3hsk-Add-reserved-memory-nodes.patch
+patch 0313-arm64-dts-renesas-eagle-Add-reserved-memory-nodes.patch
+patch 0314-arm64-dts-renesas-condor-Add-reserved-memory-nodes.patch
+patch 0315-arm64-dts-renesas-v3msk-Add-mmngr-and-mmngrbuf-nodes.patch
+patch 0316-arm64-dts-renesas-v3hsk-Add-mmngr-and-mmngrbuf-nodes.patch
+patch 0317-arm64-dts-renesas-eagle-Add-mmngr-and-mmngrbuf-nodes.patch
+patch 0318-arm64-dts-renesas-condor-Add-mmngr-and-mmngrbuf-node.patch
+patch 0319-arm64-dts-renesas-v3msk-Add-vspm_if-node.patch
+patch 0320-arm64-dts-renesas-v3hsk-Add-vspm_if-node.patch
+patch 0321-arm64-dts-renesas-eagle-Add-vspm_if-node.patch
+patch 0322-arm64-dts-renesas-condor-Add-vspm_if-node.patch
+patch 0323-arm64-dts-renesas-eagle-Add-Dialog-DA9063-MFD.patch
+patch 0324-arm64-dts-renesas-Add-r8a77970-eagle-function-suppor.patch
+patch 0325-arm64-dts-renesas-Add-r8a77970-es1-support.patch
+patch 0326-arm64-dts-renesas-Add-r8a77970-v3msk-view-support.patch
+patch 0327-arm64-dts-renesas-Add-r8a77970-v3msk-kf-support.patch
+patch 0328-arm64-dts-renesas-Add-r8a77970-v3msk-vbm-support.patch
+patch 0329-arm64-dts-renesas-Add-r8a77970-v3mzf-support.patch
+patch 0330-arm64-dts-renesas-Add-r8a77980-v3hsk-vbm-support.patch
+patch 0331-arm64-dts-renesas-r8a779-7-8-0-Add-IMP-devices.patch
+patch 0332-arm64-dts-renesas-r8a77980-Add-VIP-nodes.patch
+patch 0333-arm64-dts-renesas-r8a779-78-0-Add-linux-multimedia-r.patch
+patch 0334-IMR-UIO-Driver-initial-version.patch
+patch 0335-media-rcar-imr-IMR-driver-updates-for-raw-DL.patch
+patch 0336-media-rcar-imr-Add-RSE-support.patch
+patch 0337-rcar_imr-v4l2-driver-Fix-module-support.patch
+patch 0338-V3Hsk-Condor-and-V3Msk-Eagle-Remove-cma-default-area.patch
+patch 0339-media-rcar_imr-Enable-LUCE-for-NV16-format.patch
+patch 0340-clk-cs2000-add-support-for-cs2300.patch
+patch 0341-V3H-add-support-for-8-4-channel-VideoBox-board-from-.patch
+patch 0342-arm64-dts-r8a77970-Videobox-Mini-V3-board-support.patch
+patch 0343-arm64-dts-renesas-r8a77970-v3msk-Add-ethernet0-alias.patch
+patch 0344-arm64-dts-renesas-r8a77970-Add-ISP0-alias.patch
+patch 0345-arm64-dts-renesas-r8a77980-Add-ISP-aliases.patch
+patch 0346-media-soc_camera-Add-soc_camera-host-preregister.patch
+patch 0347-arm64-renesas-r8a77980-use-CSI-4-lanes.patch
+patch 0348-Bunch-update-of-r8a77980-v3hsk-vb-4ch.dts.patch
+patch 0349-arm64-dts-renesas-r8a77980-VideoBox-Mini-fix-csi-spe.patch
+patch 0350-arm64-dts-renesas-r8a77980-v3hsk-vb-4ch-and-8ch-fix-.patch
+patch 0351-arm64-dts-renesas-r8a77980-VB-4ch-and-8ch-Add-PCIE-p.patch
+patch 0352-gpu-drm-rcar_du-Fix-physical-address-of-the-CMA-back.patch
+patch 0353-media-soc_camera-rcar_csi2-add-dump-module-param.patch
+patch 0354-media-rcar_csi2-Disable-data-type-matching.patch
+patch 0355-gpu-drm-rcar-du-Extend-VSP1-DRM-interface.patch
+patch 0356-media-platform-vsp1-Extend-DRM-VSP1-interface.patch
+patch 0357-gpu-drm-rcar-du-rcar_du_vsp-Check-if-gem-buffer-has-.patch
+patch 0358-media-platform-vsp1-Add-cropping-handling-to-VSP-alp.patch
+patch 0359-media-platform-rcar_imr-Clean-up-to-avoid-compiler-w.patch
+patch 0360-arm64-dts-renesas-r8a77970-and-r8a77980-Add-CPU-oper.patch
+patch 0361-V3H-DTS-Add-FCPR-devices.patch
+patch 0362-arm64-dts-r8a77980-v3hsk-Enable-onboard-eMMC.patch
+patch 0363-arm64-dts-renesas-r8a77980-v3hsk-vb-Xch-Fix-Ethernet.patch
+patch 0364-clocksource-drivers-sh_cmt-Add-R-Car-gen3-support.patch
+patch 0365-mtd-spi-nor-Add-R-Car-Gen3-RPC-QSPI-driver.patch
+patch 0366-mtd-spi-nor-renesas-rpc-Workaround-256-byte-data-siz.patch
+patch 0367-mtd-spi-nor-Add-s25fs512s-and-s25fs128s-01-SPI-NOR-f.patch
+patch 0368-arm64-dts-renesas-r8a77970-Add-RPC-QSPI-node.patch
+patch 0369-arm64-dts-renesas-r8a77980-Add-RPC-QSPI-node.patch
+patch 0370-arm64-dts-renesas-v3msk-Add-s25fs512s-QSPI-flash-nod.patch
+patch 0371-arm64-dts-renesas-v3mzf-Add-s25fs512s-QSPI-flash-nod.patch
+patch 0372-arm64-dts-renesas-eagle-Add-s25fs512s-QSPI-flash-nod.patch
+patch 0373-arm64-dts-renesas-v3hsk-Add-s25fs512s-QSPI-flash-nod.patch
+patch 0374-arm64-dts-renesas-condor-Add-s25fs512s-QSPI-flash-no.patch
+patch 0375-mtd-spi-nor-renesas-rpc-Support-single-mode-write-co.patch
+patch 0376-mtd-spi-nor-renesas-rpc-Add-DMA-read-support.patch
+patch 0377-r8a779-78-dtsi-Add-iccom-nodes.patch
+patch 0378-arm64-dts-renesas-Add-temperature-emergency-levels.patch
+patch 0379-r8a77980-dts-Add-vbm-v3-on-r8a77980-SoC.patch
+patch 0380-arm64-dts-r8a77970-Enable-TMU-and-CMT.patch
+patch 0381-arm64-dts-r8a77980-Enable-TMU-and-CMT.patch
+patch 0382-arm64-dts-renesas-r8a77970-and-r8a77980-Add-QoS-node.patch
+patch 0383-clk-renesas-r8a77970-cpg-mssr-Add-sadc-clock.patch
+patch 0384-arm64-dts-renesas-r8a77970-Add-sadc-node.patch
+patch 0385-iio-adc-Add-R-Car-SADC-driver.patch
+patch 0386-rcar-vin-add-ISP-source-enable.patch
+patch 0387-media-soc_camera-Add-events-support.patch
+patch 0388-media-rcar-imr-Add-stride-support-to-IMR.patch
+patch 0389-arm64-renesas-r8a77980-VB-use-REFCLK-23.0MHZ.patch
+patch 0390-arm64-dts-renesas-Add-V3x-VideoBox-FDPLink-support.patch
+patch 0392-gpu-drm-bridge-thc63-Set-upper-clock-limit-to-150-MH.patch
+patch 0393-media-soc_camera-dummy-add-mbus-controls-ids.patch
+patch 0394-media-i2c-ar0233-fix-superexposure.patch
+patch 0395-media-i2c-ap0101-add-V-H-flip.patch
+patch 0396-media-i2c-ap0101-ar014x-get-OTP-more-complex.patch
+patch 0397-media-i2c-ar0147-add-mipi-rev3-lvds-support.patch
+patch 0398-media-i2c-ar0147-add-SE-mode.patch
+patch 0399-media-i2c-ar0233-fix-artifact-line-at-vflip.patch
+patch 0400-media-platform-soc_mediabus-add-Bayer-16bit-format.patch
+patch 0401-media-i2c-ov490_ov10640-add-group-switch.patch
+patch 0402-media-i2c-gw5200-detection-workaround.patch
+patch 0403-media-i2c-ov2311-put-to-autodetect-head.patch
+patch 0404-media-i2c-onsemi-imager-correct-trigger-handling.patch
+patch 0405-media-i2c-ov10640-fix-controls.patch
+patch 0406-Add-new-custom_ioctl-ops-for-soc-camera.patch
+patch 0407-arm64-dts-renesas-r8a77970-v3msk-Fix-memory-size.patch
+patch 0408-arm64-dts-renesas-v3hsk-Add-GEther-PHY-GPIO-reset-pi.patch
+patch 0409-arm64-dts-renesas-condor-Add-GEther-PHY-GPIO-reset-p.patch
+patch 0410-arm64-dts-renesas-eagle-Add-RAVB-PHY-GPIO-reset-pin-.patch
+patch 0411-media-soc_camera-add-MAX9288-support.patch
+patch 0412-media-i2c-soc_camera-differenciate-max9286-and-max92.patch
+patch 0413-media-i2c-max9288-fix-stream-on-off.patch
+patch 0414-gpio-pca953x-do-not-ignore-i2c-errors.patch
+patch 0415-usb-host-xhci-rcar-Add-XHCI_TRUST_TX_LENGTH-quirk.patch
+patch 0416-arm64-dtb-renesas-vb2.1-enable-usb2-channel-3.patch
+patch 0417-USB-tusb8041-add-simple-driver-to-start-device-over-.patch
+patch 0418-arm64-dts-renesas-ulcb-vb2-fix-USB30-and-HUB.patch
+patch 0419-phy-rcar-gen3-usb2-power-on-port-in-host-mode-to.patch
diff --git a/bsp/meta-rcar/meta-rcar-gen3-adas/recipes-kernel/linux/linux-renesas/salvator-x.cfg b/bsp/meta-rcar/meta-rcar-gen3-adas/recipes-kernel/linux/linux-renesas/salvator-x.cfg
new file mode 100644
index 00000000..b43866d8
--- /dev/null
+++ b/bsp/meta-rcar/meta-rcar-gen3-adas/recipes-kernel/linux/linux-renesas/salvator-x.cfg
@@ -0,0 +1,27 @@
+CONFIG_CAN=y
+CONFIG_CAN_PEAK_USB=y
+CONFIG_CAN_BCM=y
+CONFIG_CAN_RAW=y
+CONFIG_CAN_DEV=y
+CONFIG_CAN_CALC_BITTIMING=y
+CONFIG_CAN_RCAR=y
+CONFIG_CAN_RCAR_CANFD=y
+CONFIG_DUMMY=y
+CONFIG_VIDEO_ADV_DEBUG=y
+CONFIG_VIDEO_RCAR_VIN_LEGACY=y
+CONFIG_VIDEO_RCAR_CSI2_LEGACY=y
+# CONFIG_VIDEO_RCAR_VIN is not set
+# CONFIG_VIDEO_RCAR_CSI2 is not set
+CONFIG_SOC_CAMERA=y
+CONFIG_SOC_CAMERA_SCALE_CROP=y
+CONFIG_SOC_CAMERA_PLATFORM=y
+CONFIG_SOC_CAMERA_MAX9286=y
+CONFIG_SOC_CAMERA_OV106XX=y
+CONFIG_MMC_SDHI_PRE_REQ=y
+CONFIG_MMC_SDHI_SEQ=y
+CONFIG_INPUT_TOUCHSCREEN=y
+CONFIG_TOUCHSCREEN_PROPERTIES=y
+CONFIG_HID_MULTITOUCH=y
+CONFIG_SERIAL_SH_SCI_DMA=y
+CONFIG_UIO=y
+CONFIG_GPIO_SYSFS=y
diff --git a/bsp/meta-rcar/meta-rcar-gen3-adas/recipes-kernel/linux/linux-renesas/sdhi_seq.cfg b/bsp/meta-rcar/meta-rcar-gen3-adas/recipes-kernel/linux/linux-renesas/sdhi_seq.cfg
new file mode 100644
index 00000000..9c43599c
--- /dev/null
+++ b/bsp/meta-rcar/meta-rcar-gen3-adas/recipes-kernel/linux/linux-renesas/sdhi_seq.cfg
@@ -0,0 +1,2 @@
+CONFIG_MMC_SDHI_PRE_REQ=y
+CONFIG_MMC_SDHI_SEQ=y
diff --git a/bsp/meta-rcar/meta-rcar-gen3-adas/recipes-kernel/linux/linux-renesas/ulcb.cfg b/bsp/meta-rcar/meta-rcar-gen3-adas/recipes-kernel/linux/linux-renesas/ulcb.cfg
new file mode 100644
index 00000000..e053969e
--- /dev/null
+++ b/bsp/meta-rcar/meta-rcar-gen3-adas/recipes-kernel/linux/linux-renesas/ulcb.cfg
@@ -0,0 +1,87 @@
+CONFIG_CAN=y
+CONFIG_CAN_PEAK_USB=y
+CONFIG_CAN_BCM=y
+CONFIG_CAN_RAW=y
+CONFIG_CAN_DEV=y
+CONFIG_CAN_CALC_BITTIMING=y
+CONFIG_CAN_RCAR=y
+CONFIG_CAN_RCAR_CANFD=y
+CONFIG_CAN_MCP251X=y
+CONFIG_DUMMY=y
+CONFIG_EXTRA_FIRMWARE="r8a779x_usb3_v2.dlmem r8a779x_usb3_v3.dlmem"
+CONFIG_EXTRA_FIRMWARE_DIR="firmware"
+CONFIG_SATA_ACARD_AHCI=y
+CONFIG_FIXED_PHY=y
+CONFIG_SPI_BITBANG=y
+CONFIG_SPI_GPIO=y
+CONFIG_GPIO_MAX732X=y
+CONFIG_GPIO_MAX732X_IRQ=y
+CONFIG_GPIO_PCA953X=y
+CONFIG_GPIO_PCA953X_IRQ=y
+CONFIG_VIDEO_ADV_DEBUG=y
+CONFIG_VIDEO_RCAR_VIN_LEGACY=y
+CONFIG_VIDEO_RCAR_CSI2_LEGACY=y
+# CONFIG_VIDEO_RCAR_VIN is not set
+# CONFIG_VIDEO_RCAR_CSI2 is not set
+CONFIG_SOC_CAMERA=y
+CONFIG_SOC_CAMERA_SCALE_CROP=y
+CONFIG_SOC_CAMERA_PLATFORM=y
+CONFIG_SOC_CAMERA_MAX9286=y
+CONFIG_SOC_CAMERA_TI9X4=y
+CONFIG_SOC_CAMERA_OV106XX=y
+CONFIG_SOC_CAMERA_OV5647=y
+CONFIG_SOC_CAMERA_OV5642=y
+CONFIG_SOC_CAMERA_IMX219=y
+CONFIG_VIRTIO_RCAR_PCIE=y
+CONFIG_BT=y
+CONFIG_BT_BNEP=m
+CONFIG_BT_RFCOMM=m
+CONFIG_BT_HIDP=m
+CONFIG_TI_ST=m
+CONFIG_BT_WILINK=m
+CONFIG_WEXT_CORE=y
+CONFIG_WEXT_PROC=y
+CONFIG_CFG80211_WEXT=y
+CONFIG_MAC80211=y
+CONFIG_WLAN=y
+CONFIG_WL18XX=m
+CONFIG_WLCORE=m
+CONFIG_WLCORE_SDIO=m
+CONFIG_SND_SOC_SI468X=y
+CONFIG_SND_SOC_PCM3168A=y
+CONFIG_SND_SOC_PCM3168A_I2C=y
+CONFIG_SND_SOC_WL18XX=y
+CONFIG_INPUT_POLLDEV=y
+CONFIG_KEYBOARD_GPIO_POLLED=y
+CONFIG_INPUT_TOUCHSCREEN=y
+CONFIG_TOUCHSCREEN_PROPERTIES=y
+CONFIG_HID_MULTITOUCH=y
+CONFIG_IIO=y
+CONFIG_IIO_BUFFER=y
+CONFIG_IIO_BUFFER_CB=y
+CONFIG_IIO_KFIFO_BUF=y
+CONFIG_IIO_TRIGGERED_BUFFER=y
+CONFIG_IIO_TRIGGER=y
+CONFIG_IIO_CONSUMERS_PER_TRIGGER=2
+CONFIG_LSM9DS0=m
+CONFIG_DRM_I2C_ADV7511=y
+CONFIG_TOUCHSCREEN_EDT_FT5X06=y
+CONFIG_SERIAL_SH_SCI_DMA=y
+CONFIG_STAGING=y
+CONFIG_MOST=y
+CONFIG_MOSTCORE=y
+CONFIG_AIM_CDEV=y
+CONFIG_AIM_NETWORK=y
+CONFIG_AIM_SOUND=y
+CONFIG_AIM_V4L2=y
+CONFIG_HDM_DIM2=y
+CONFIG_UIO=y
+CONFIG_SENSORS_EMC2103=y
+CONFIG_PMBUS=y
+CONFIG_RTC_DRV_DS1307=y
+CONFIG_RTC_DRV_DS1307_HWMON=y
+CONFIG_SENSORS_LM63=y
+CONFIG_MD=y
+CONFIG_BLK_DEV_MD=y
+CONFIG_MD_RAID0=y
+CONFIG_GPIO_SYSFS=y
diff --git a/bsp/meta-rcar/meta-rcar-gen3-adas/recipes-kernel/linux/linux-renesas/v3hsk.cfg b/bsp/meta-rcar/meta-rcar-gen3-adas/recipes-kernel/linux/linux-renesas/v3hsk.cfg
new file mode 100644
index 00000000..c633e9ed
--- /dev/null
+++ b/bsp/meta-rcar/meta-rcar-gen3-adas/recipes-kernel/linux/linux-renesas/v3hsk.cfg
@@ -0,0 +1,43 @@
+CONFIG_ARCH_R8A77980=y
+CONFIG_CAN=y
+CONFIG_CAN_PEAK_USB=y
+CONFIG_CAN_BCM=y
+CONFIG_CAN_RAW=y
+CONFIG_CAN_DEV=y
+CONFIG_CAN_CALC_BITTIMING=y
+CONFIG_CAN_RCAR=y
+CONFIG_CAN_RCAR_CANFD=y
+CONFIG_DUMMY=y
+CONFIG_DRM_I2C_ADV7511=y
+CONFIG_GPIO_MAX732X=y
+CONFIG_GPIO_MAX732X_IRQ=y
+CONFIG_GPIO_PCA953X=y
+CONFIG_GPIO_PCA953X_IRQ=y
+CONFIG_VIDEO_ADV_DEBUG=y
+CONFIG_VIDEO_RCAR_VIN_LEGACY=y
+CONFIG_VIDEO_RCAR_CSI2_LEGACY=y
+# CONFIG_VIDEO_RCAR_VIN is not set
+# CONFIG_VIDEO_RCAR_CSI2 is not set
+CONFIG_SOC_CAMERA=y
+CONFIG_SOC_CAMERA_SCALE_CROP=y
+CONFIG_SOC_CAMERA_PLATFORM=y
+CONFIG_SOC_CAMERA_MAX9286=y
+CONFIG_SOC_CAMERA_TI9X4=y
+CONFIG_SOC_CAMERA_OV106XX=y
+CONFIG_INPUT_TOUCHSCREEN=y
+CONFIG_INPUT_UINPUT=y
+CONFIG_TOUCHSCREEN_PROPERTIES=y
+CONFIG_HID_MULTITOUCH=y
+CONFIG_SERIAL_SH_SCI_DMA=y
+CONFIG_UIO=y
+CONFIG_UIO_PDRV_GENIRQ=m
+CONFIG_SPI_SLAVE=y
+CONFIG_SPI_SLAVE_TIME=y
+CONFIG_SPI_SLAVE_SYSTEM_CONTROL=y
+CONFIG_SENSORS_LM63=y
+CONFIG_SH_ETH=y
+CONFIG_SATA_ACARD_AHCI=y
+CONFIG_GPIO_SYSFS=y
+CONFIG_DRM_THINE_THC63LVD1024=y
+CONFIG_MCP4725=y
+CONFIG_PHY_RCAR_GEN3_PCIE=y
diff --git a/bsp/meta-rcar/meta-rcar-gen3-adas/recipes-kernel/linux/linux-renesas/v3msk.cfg b/bsp/meta-rcar/meta-rcar-gen3-adas/recipes-kernel/linux/linux-renesas/v3msk.cfg
new file mode 100644
index 00000000..3a4e283b
--- /dev/null
+++ b/bsp/meta-rcar/meta-rcar-gen3-adas/recipes-kernel/linux/linux-renesas/v3msk.cfg
@@ -0,0 +1,39 @@
+CONFIG_ARCH_R8A77970=y
+CONFIG_CAN=y
+CONFIG_CAN_PEAK_USB=y
+CONFIG_CAN_BCM=y
+CONFIG_CAN_RAW=y
+CONFIG_CAN_DEV=y
+CONFIG_CAN_CALC_BITTIMING=y
+CONFIG_CAN_RCAR=y
+CONFIG_CAN_RCAR_CANFD=y
+CONFIG_DUMMY=y
+CONFIG_DRM_I2C_ADV7511=y
+CONFIG_GPIO_MAX732X=y
+CONFIG_GPIO_MAX732X_IRQ=y
+CONFIG_GPIO_PCA953X=y
+CONFIG_GPIO_PCA953X_IRQ=y
+CONFIG_VIDEO_ADV_DEBUG=y
+CONFIG_VIDEO_RCAR_VIN_LEGACY=y
+CONFIG_VIDEO_RCAR_CSI2_LEGACY=y
+# CONFIG_VIDEO_RCAR_VIN is not set
+# CONFIG_VIDEO_RCAR_CSI2 is not set
+CONFIG_SOC_CAMERA=y
+CONFIG_SOC_CAMERA_SCALE_CROP=y
+CONFIG_SOC_CAMERA_PLATFORM=y
+CONFIG_SOC_CAMERA_MAX9286=y
+CONFIG_SOC_CAMERA_TI9X4=y
+CONFIG_SOC_CAMERA_OV106XX=y
+CONFIG_INPUT_TOUCHSCREEN=y
+CONFIG_INPUT_UINPUT=y
+CONFIG_TOUCHSCREEN_PROPERTIES=y
+CONFIG_HID_MULTITOUCH=y
+CONFIG_SERIAL_SH_SCI_DMA=y
+CONFIG_UIO=y
+CONFIG_SPI_SLAVE=y
+CONFIG_SPI_SLAVE_TIME=y
+CONFIG_SPI_SLAVE_SYSTEM_CONTROL=y
+CONFIG_SENSORS_LM63=y
+CONFIG_RCAR_THERMAL=y
+CONFIG_GPIO_SYSFS=y
+CONFIG_DRM_THINE_THC63LVD1024=y
diff --git a/bsp/meta-rcar/meta-rcar-gen3-adas/recipes-kernel/linux/linux-renesas/v3mzf.cfg b/bsp/meta-rcar/meta-rcar-gen3-adas/recipes-kernel/linux/linux-renesas/v3mzf.cfg
new file mode 100644
index 00000000..84efece5
--- /dev/null
+++ b/bsp/meta-rcar/meta-rcar-gen3-adas/recipes-kernel/linux/linux-renesas/v3mzf.cfg
@@ -0,0 +1,25 @@
+CONFIG_ARCH_R8A77970=y
+CONFIG_CAN=y
+CONFIG_CAN_BCM=y
+CONFIG_CAN_RAW=y
+CONFIG_CAN_DEV=y
+CONFIG_CAN_CALC_BITTIMING=y
+CONFIG_CAN_RCAR=y
+CONFIG_CAN_RCAR_CANFD=y
+CONFIG_DUMMY=y
+CONFIG_VIDEO_ADV_DEBUG=y
+CONFIG_VIDEO_RCAR_VIN_LEGACY=y
+CONFIG_VIDEO_RCAR_CSI2_LEGACY=y
+# CONFIG_VIDEO_RCAR_VIN is not set
+# CONFIG_VIDEO_RCAR_CSI2 is not set
+CONFIG_SOC_CAMERA=y
+CONFIG_SOC_CAMERA_SCALE_CROP=y
+CONFIG_SOC_CAMERA_PLATFORM=y
+CONFIG_SOC_CAMERA_TI9X4=y
+CONFIG_SOC_CAMERA_OV106XX=y
+CONFIG_SERIAL_SH_SCI_DMA=y
+CONFIG_SPI_SLAVE=y
+CONFIG_SPI_SLAVE_TIME=y
+CONFIG_SPI_SLAVE_SYSTEM_CONTROL=y
+CONFIG_RCAR_THERMAL=y
+CONFIG_GPIO_SYSFS=y
diff --git a/bsp/meta-rcar/meta-rcar-gen3-adas/recipes-kernel/linux/linux-renesas_4.14.bbappend b/bsp/meta-rcar/meta-rcar-gen3-adas/recipes-kernel/linux/linux-renesas_4.14.bbappend
new file mode 100644
index 00000000..5473336d
--- /dev/null
+++ b/bsp/meta-rcar/meta-rcar-gen3-adas/recipes-kernel/linux/linux-renesas_4.14.bbappend
@@ -0,0 +1,134 @@
+FILESEXTRAPATHS_prepend := "${THISDIR}/${PN}:"
+
+COMPATIBLE_MACHINE_eagle = "eagle"
+COMPATIBLE_MACHINE_v3msk = "v3msk"
+COMPATIBLE_MACHINE_condor = "condor"
+COMPATIBLE_MACHINE_v3mzf = "v3mzf"
+COMPATIBLE_MACHINE_v3hsk = "v3hsk"
+
+SRC_URI_append = " \
+ ${@bb.utils.contains('MACHINE_FEATURES', 'h3ulcb-had', ' file://hyperflash.cfg', '', d)} \
+ ${@oe.utils.conditional("SDHI_SEQ", "1", " file://sdhi_seq.cfg", "", d)} \
+ file://nvme.cfg \
+ file://imr.cfg \
+ file://disable-unused.cfg \
+ file://renesas.scc \
+ ${@oe.utils.conditional("KF_ENABLE_SD3", "1", " file://0047-arm64-dts-renesas-ulcb-kf-enable-sd3.patch", "", d)} \
+ ${@oe.utils.conditional("KF_ENABLE_MOST", "1", " file://0048-arm64-dts-renesas-ulcb-kf-enable-most.patch", "", d)} \
+ ${@oe.utils.conditional("KF_ENABLE_IMX219", "1", " file://0115-arm64-dts-renesas-ulcb-kf-enable-enable-IMX219.patch", "", d)} \
+ ${@oe.utils.conditional("KF_PANEL_MODEL", "TX31D200VM0BAA", " file://0121-arm64-dts-renesas-ulcb-kf-Set-KOE-TX31D200VM0BAA-128.patch", "", d)} \
+ ${@oe.utils.conditional("KF_PANEL_MODEL", "AA104XD12", " file://0121-arm64-dts-renesas-ulcb-kf-Set-Mitsubishi-AA104XD12-1.patch", "", d)} \
+ ${@oe.utils.conditional("KF_PANEL_MODEL", "AA121TD01", " file://0121-arm64-dts-renesas-ulcb-kf-Set-Mitsubishi-AA121TD01-1.patch", "", d)} \
+ ${@oe.utils.conditional("VB_ENABLE_FDPLINK", "1", " file://0391-arm64-dts-renesas-Enable-FDPLink-output-on-V3x-Video.patch", "", d)} \
+"
+
+SRC_URI_append_h3ulcb = " file://ulcb.cfg"
+SRC_URI_append_m3ulcb = " file://ulcb.cfg"
+SRC_URI_append_m3nulcb = " file://ulcb.cfg"
+SRC_URI_append_salvator-x = " file://salvator-x.cfg"
+SRC_URI_append_eagle = " file://eagle.cfg"
+SRC_URI_append_v3msk = " file://v3msk.cfg"
+SRC_URI_append_condor = " file://condor.cfg"
+SRC_URI_append_v3mzf = " file://v3mzf.cfg"
+SRC_URI_append_v3hsk = " file://v3hsk.cfg"
+
+SRC_URI_append_rcar-gen3-v3x = " \
+ file://cma.cfg \
+ file://qspi.cfg \
+"
+
+KERNEL_DEVICETREE_append_h3ulcb = " \
+ renesas/r8a7795-es1-h3ulcb-view.dtb \
+ renesas/r8a7795-es1-h3ulcb-had-alfa.dtb \
+ renesas/r8a7795-es1-h3ulcb-had-beta.dtb \
+ renesas/r8a7795-es1-h3ulcb-kf.dtb \
+ renesas/r8a7795-es1-h3ulcb-vb.dtb \
+ renesas/r8a7795-es1-h3ulcb-vb2.dtb \
+ renesas/r8a7795-es1-h3ulcb-vbm.dtb \
+ renesas/r8a7795-h3ulcb-view.dtb \
+ renesas/r8a7795-h3ulcb-had-alfa.dtb \
+ renesas/r8a7795-h3ulcb-had-beta.dtb \
+ renesas/r8a7795-h3ulcb-kf.dtb \
+ renesas/r8a7795-h3ulcb-4x2g-kf.dtb \
+ renesas/r8a7795-h3ulcb-vb.dtb \
+ renesas/r8a7795-h3ulcb-vb2.dtb \
+ renesas/r8a7795-h3ulcb-vb2.1.dtb \
+ renesas/r8a7795-h3ulcb-vbm.dtb \
+ renesas/r8a7795-h3ulcb-4x2g-vb.dtb \
+ renesas/r8a7795-h3ulcb-4x2g-vb2.dtb \
+ renesas/r8a7795-h3ulcb-4x2g-vb2.1.dtb \
+ renesas/r8a7795-h3ulcb-4x2g-vbm.dtb \
+"
+
+KERNEL_DEVICETREE_append_m3ulcb = " \
+ renesas/r8a7796-m3ulcb-view.dtb \
+ renesas/r8a7796-m3ulcb-kf.dtb \
+"
+
+KERNEL_DEVICETREE_append_m3nulcb = " \
+ renesas/r8a77965-m3nulcb-kf.dtb \
+"
+
+KERNEL_DEVICETREE_append_salvator-x = " \
+ renesas/r8a7795-es1-salvator-x-view.dtb \
+ renesas/r8a7795-salvator-x-view.dtb \
+ renesas/r8a7796-salvator-x-view.dtb \
+"
+
+KERNEL_DEVICETREE_append_eagle = " \
+ renesas/r8a77970-es1-eagle.dtb \
+ renesas/r8a77970-es1-eagle-function.dtb \
+ renesas/r8a77970-eagle.dtb \
+ renesas/r8a77970-eagle-function.dtb \
+"
+
+KERNEL_DEVICETREE_append_v3msk = " \
+ renesas/r8a77970-es1-v3msk.dtb \
+ renesas/r8a77970-es1-v3msk-kf.dtb \
+ renesas/r8a77970-es1-v3msk-vbm.dtb \
+ renesas/r8a77970-es1-v3msk-vbm-v2.dtb \
+ renesas/r8a77970-es1-v3msk-vbm-v3.dtb \
+ renesas/r8a77970-es1-v3msk-view.dtb \
+ renesas/r8a77970-v3msk.dtb \
+ renesas/r8a77970-v3msk-kf.dtb \
+ renesas/r8a77970-v3msk-vbm.dtb \
+ renesas/r8a77970-v3msk-vbm-v2.dtb \
+ renesas/r8a77970-v3msk-vbm-v3.dtb \
+ renesas/r8a77970-v3msk-view.dtb \
+"
+
+KERNEL_DEVICETREE_append_v3mzf = " \
+ renesas/r8a77970-v3mzf.dtb \
+"
+
+KERNEL_DEVICETREE_append_condor = " \
+ renesas/r8a77980-condor.dtb \
+"
+
+KERNEL_DEVICETREE_append_v3hsk = " \
+ renesas/r8a77980-v3hsk.dtb \
+ renesas/r8a77980-v3hsk-vbm.dtb \
+ renesas/r8a77980-v3hsk-vbm-v2.dtb \
+ renesas/r8a77980-v3hsk-vbm-v3.dtb \
+ renesas/r8a77980-v3hsk-vb-4ch.dtb \
+ renesas/r8a77980-v3hsk-vb-8ch.dtb \
+"
+# Prefer V4L2 rcar_imr driver over UIO uio_imr
+KERNEL_MODULE_AUTOLOAD_append = " rcar_imr"
+KERNEL_MODULE_PROBECONF_append = " rcar_imr"
+KERNEL_MODULE_PROBECONF_append = " uio_imr"
+module_conf_uio_imr = 'blacklist uio_imr'
+
+# V3H VIP devices
+KERNEL_MODULE_AUTOLOAD_append_r8a77980 = " uio_pdrv_genirq"
+KERNEL_MODULE_PROBECONF_append_r8a77980 = " uio_pdrv_genirq"
+module_conf_uio_pdrv_genirq_r8a77980 = 'options uio_pdrv_genirq of_id="generic-uio"'
+
+# Install RCAR Gen3 specific UAPI headers
+do_install_append_rcar-gen3() {
+ install -d ${D}/usr/include/linux/
+ install -m 0644 ${STAGING_KERNEL_DIR}/include/uapi/linux/rcar-imr.h ${D}/usr/include/linux/
+}
+
+PACKAGES += "${PN}-uapi"
+FILES_${PN}-uapi = "/usr/include"