aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorTom Rini <trini@konsulko.com>2017-12-19 15:07:39 -0500
committerTom Rini <trini@konsulko.com>2017-12-19 15:07:39 -0500
commit9ae3b81724f87dcc1f5cbd618c472e0cf79b2791 (patch)
treed3d1e6ac479ba64a78dcf16e521898a44ed08878
parent592c4aca65cc41ea9e5757084ae1d488d2bbd8b0 (diff)
parenteb675727a6bfdee2ba7dd36644403163f9d905e2 (diff)
Merge branch 'pyro' into eel
-rw-r--r--meta-rcar-gen3-adas/conf/layer.conf12
-rw-r--r--meta-rcar-gen3-adas/conf/machine/eagle.conf35
-rw-r--r--meta-rcar-gen3-adas/conf/machine/include/r8a7797.inc3
-rw-r--r--meta-rcar-gen3-adas/conf/machine/include/tune-cortexa53.inc18
-rw-r--r--meta-rcar-gen3-adas/conf/machine/v3msk.conf35
-rw-r--r--meta-rcar-gen3-adas/docs/sample/conf/eagle/linaro-gcc/bsp/bblayers.conf16
-rw-r--r--meta-rcar-gen3-adas/docs/sample/conf/eagle/linaro-gcc/bsp/local.conf267
-rw-r--r--meta-rcar-gen3-adas/docs/sample/conf/v3msk/linaro-gcc/bsp/bblayers.conf16
-rw-r--r--meta-rcar-gen3-adas/docs/sample/conf/v3msk/linaro-gcc/bsp/local.conf267
-rw-r--r--meta-rcar-gen3-adas/docs/sample/patch/0001-meta-linaro-python-wand-fix-BB_NO_NETWORK-build.patch28
-rw-r--r--meta-rcar-gen3-adas/docs/sample/patch/0002-meta-renesas-gstreamer-fix-BB_NO_NETWORK-build.patch92
-rw-r--r--meta-rcar-gen3-adas/docs/sample/patch/0003-poky-bitbake-gitsm-fix-BB_NO_NETWORK-build.patch47
-rw-r--r--meta-rcar-gen3-adas/recipes-bsp/arm-trusted-firmware/arm-trusted-firmware_git.bbappend14
-rw-r--r--meta-rcar-gen3-adas/recipes-bsp/arm-trusted-firmware/files/0001-plat-renesas-rcar-Make-RPC-secure-settings-optional.patch84
-rw-r--r--meta-rcar-gen3-adas/recipes-bsp/arm-trusted-firmware/files/0002-plat-renesas-rcar-kingfisher-reboot-fix-power-off-on-reset.diff37
-rw-r--r--meta-rcar-gen3-adas/recipes-bsp/capture/capture_1.0.bb39
-rw-r--r--meta-rcar-gen3-adas/recipes-bsp/capture/files/capture.tar.gzbin0 -> 7308 bytes
-rw-r--r--meta-rcar-gen3-adas/recipes-bsp/iio-utils/files/iio-utils.tar.gzbin0 -> 12531 bytes
-rw-r--r--meta-rcar-gen3-adas/recipes-bsp/iio-utils/iio-utils_%.bb31
-rw-r--r--meta-rcar-gen3-adas/recipes-bsp/most-tools/files/most-tools.tar.gzbin0 -> 65178 bytes
-rw-r--r--meta-rcar-gen3-adas/recipes-bsp/most-tools/most-tools.bb22
-rw-r--r--meta-rcar-gen3-adas/recipes-bsp/mpssd/files/mpssd.tar.gzbin0 -> 12660 bytes
-rw-r--r--meta-rcar-gen3-adas/recipes-bsp/mpssd/mpssd_1.0.bb27
-rw-r--r--meta-rcar-gen3-adas/recipes-bsp/si-tools/files/si-tools.tar.gzbin0 -> 1593308 bytes
-rw-r--r--meta-rcar-gen3-adas/recipes-bsp/si-tools/si-tools.bb46
-rw-r--r--meta-rcar-gen3-adas/recipes-bsp/spidev-dbg/files/spidev-dbg.tar.gzbin0 -> 5503 bytes
-rw-r--r--meta-rcar-gen3-adas/recipes-bsp/spidev-dbg/spidev-dbg_1.0.bb21
-rw-r--r--meta-rcar-gen3-adas/recipes-bsp/ti-bt-firmware/ti-bt-firmware_git.bb25
-rw-r--r--meta-rcar-gen3-adas/recipes-bsp/ti-bt/files/0001-Improve-debug-output.patch125
-rw-r--r--meta-rcar-gen3-adas/recipes-bsp/ti-bt/files/0001-fix-poll-restart-after-fail.patch52
-rw-r--r--meta-rcar-gen3-adas/recipes-bsp/ti-bt/files/0002-Fix-possible-cross-compile-issue.patch29
-rw-r--r--meta-rcar-gen3-adas/recipes-bsp/ti-bt/files/uim-sysfs36
-rw-r--r--meta-rcar-gen3-adas/recipes-bsp/ti-bt/ti-bt_git.bb35
-rw-r--r--meta-rcar-gen3-adas/recipes-bsp/u-boot/u-boot/0001-net-phy-support-fixed-PHY.patch115
-rw-r--r--meta-rcar-gen3-adas/recipes-bsp/u-boot/u-boot/0002-net-ravb-remove-APSR-quirk.patch33
-rw-r--r--meta-rcar-gen3-adas/recipes-bsp/u-boot/u-boot/0003-net-ravb-fix-unsafe-phy-access.patch30
-rw-r--r--meta-rcar-gen3-adas/recipes-bsp/u-boot/u-boot/0004-configs-rcar-gen3-add-CMD_GPIO.patch27
-rw-r--r--meta-rcar-gen3-adas/recipes-bsp/u-boot/u-boot/0005-common-cmd_source.c-Fix-the-source-command-failure-u.patch53
-rw-r--r--meta-rcar-gen3-adas/recipes-bsp/u-boot/u-boot/0006-configs-rcar-gen3-common-Enable-U-Boot-scripts.patch30
-rw-r--r--meta-rcar-gen3-adas/recipes-bsp/u-boot/u-boot/0007-configs-rcar-gen3-common-Enable-echo-command.patch28
-rw-r--r--meta-rcar-gen3-adas/recipes-bsp/u-boot/u-boot/0008-configs-rcar-gen3-common-Enable-setexpr-command.patch28
-rw-r--r--meta-rcar-gen3-adas/recipes-bsp/u-boot/u-boot/0009-configs-rcar-gen3-common-Enable-askenv-command.patch28
-rw-r--r--meta-rcar-gen3-adas/recipes-bsp/u-boot/u-boot/0010-configs-rcar-gen3-common-Enable-hush-parser.patch30
-rw-r--r--meta-rcar-gen3-adas/recipes-bsp/u-boot/u-boot/0011-configs-rcar-gen3-common-Enable-GPT-support.patch32
-rw-r--r--meta-rcar-gen3-adas/recipes-bsp/u-boot/u-boot/0013-mtd-spi-QSPI-flash-support.patch1763
-rw-r--r--meta-rcar-gen3-adas/recipes-bsp/u-boot/u-boot/0014-arm-renesas-Add-Renesas-R8A7797-SoC-support.patch3542
-rw-r--r--meta-rcar-gen3-adas/recipes-bsp/u-boot/u-boot/0015-board-renesas-Add-V3M-Eagle-board.patch499
-rw-r--r--meta-rcar-gen3-adas/recipes-bsp/u-boot/u-boot/0017-board-renesas-Add-V3MSK-board.patch813
-rw-r--r--meta-rcar-gen3-adas/recipes-bsp/u-boot/u-boot/0021-ARM-rcar_gen3-Add-RPC-flash-definitions.patch224
-rw-r--r--meta-rcar-gen3-adas/recipes-bsp/u-boot/u-boot/0022-mtd-Add-RPC-HyperFlash-support.patch727
-rw-r--r--meta-rcar-gen3-adas/recipes-bsp/u-boot/u-boot/0023-board-renesas-salvator-x-Enable-RPC-clock.patch37
-rw-r--r--meta-rcar-gen3-adas/recipes-bsp/u-boot/u-boot/0024-board-renesas-ulcb-Enable-RPC-clock.patch37
-rw-r--r--meta-rcar-gen3-adas/recipes-bsp/u-boot/u-boot/0025-configs-r8a7795_salvator-x-Enable-RPC-HyperFlash-sup.patch35
-rw-r--r--meta-rcar-gen3-adas/recipes-bsp/u-boot/u-boot/0026-configs-r8a7796_salvator-x-Enable-RPC-HyperFlash-sup.patch35
-rw-r--r--meta-rcar-gen3-adas/recipes-bsp/u-boot/u-boot/0027-configs-h3ulcb-Enable-RPC-HyperFlash-support.patch36
-rw-r--r--meta-rcar-gen3-adas/recipes-bsp/u-boot/u-boot/0028-configs-m3ulcb-Enable-RPC-HyperFlash-support.patch36
-rw-r--r--meta-rcar-gen3-adas/recipes-bsp/u-boot/u-boot/0041-board-renesas-ulcb-console-on-scif1.patch28
-rw-r--r--meta-rcar-gen3-adas/recipes-bsp/u-boot/u-boot/0042-board-renesas-ulcb-set-all-RAVB-pins-strengh-to-maximum.patch55
-rw-r--r--meta-rcar-gen3-adas/recipes-bsp/u-boot/u-boot/0043-board-renesas-ulcb-support-fixed-PHY.patch54
-rw-r--r--meta-rcar-gen3-adas/recipes-bsp/u-boot/u-boot_2015.04.bbappend33
-rw-r--r--meta-rcar-gen3-adas/recipes-bsp/utest-apps/files/utest-cam-imr-drm.tar.gzbin0 -> 56006 bytes
-rw-r--r--meta-rcar-gen3-adas/recipes-bsp/utest-apps/utest-cam-imr-drm.bb25
-rw-r--r--meta-rcar-gen3-adas/recipes-bsp/v4l2-fw/files/v4l2-fw.tar.gzbin0 -> 214278 bytes
-rw-r--r--meta-rcar-gen3-adas/recipes-bsp/v4l2-fw/v4l2-fw_1.0.bb58
-rw-r--r--meta-rcar-gen3-adas/recipes-core/images/core-image-minimal.bbappend5
-rw-r--r--meta-rcar-gen3-adas/recipes-core/images/core-image-weston.bbappend6
-rw-r--r--meta-rcar-gen3-adas/recipes-core/packagegroups/nativesdk-packagegroup-sdk-host.bbappend3
-rw-r--r--meta-rcar-gen3-adas/recipes-core/packagegroups/packagegroup-opencv-sdk.bb28
-rw-r--r--meta-rcar-gen3-adas/recipes-core/packagegroups/packagegroup-surroundview-drm.bb19
-rw-r--r--meta-rcar-gen3-adas/recipes-core/packagegroups/packagegroup-surroundview.bb19
-rw-r--r--meta-rcar-gen3-adas/recipes-core/udev/udev-rules-cvlib.bb13
-rw-r--r--meta-rcar-gen3-adas/recipes-core/udev/udev-rules-cvlib/51-imp.rules1
-rw-r--r--meta-rcar-gen3-adas/recipes-core/udev/udev-rules-cvlib/52-cmem.rules1
-rw-r--r--meta-rcar-gen3-adas/recipes-devtools/yaml-cpp/yaml-cpp_0.5.3.bb19
-rw-r--r--meta-rcar-gen3-adas/recipes-devtools/yaml-cpp/yaml-cpp_git.bb23
-rw-r--r--meta-rcar-gen3-adas/recipes-kernel/kernel-module-cmemdrv/files/GPL-COPYING339
-rw-r--r--meta-rcar-gen3-adas/recipes-kernel/kernel-module-cmemdrv/files/MIT-COPYING41
-rw-r--r--meta-rcar-gen3-adas/recipes-kernel/kernel-module-cmemdrv/files/Makefile14
-rw-r--r--meta-rcar-gen3-adas/recipes-kernel/kernel-module-cmemdrv/files/cmemdrv.c457
-rw-r--r--meta-rcar-gen3-adas/recipes-kernel/kernel-module-cmemdrv/kernel-module-cmemdrv_0.1.bb24
-rw-r--r--meta-rcar-gen3-adas/recipes-kernel/kernel-module-gles/kernel-module-gles.bbappend5
-rw-r--r--meta-rcar-gen3-adas/recipes-kernel/kernel-module-gles/kernel-module-gles/clockfreq-fix-out-of-bounds-access.patch23
-rw-r--r--meta-rcar-gen3-adas/recipes-kernel/kernel-module-mmngr/files/0001-free-dma-buf-on-error.patch23
-rw-r--r--meta-rcar-gen3-adas/recipes-kernel/kernel-module-mmngr/files/0002-mmngr-Add-V3MSK-board.patch31
-rw-r--r--meta-rcar-gen3-adas/recipes-kernel/kernel-module-mmngr/kernel-module-mmngr.bbappend6
-rw-r--r--meta-rcar-gen3-adas/recipes-kernel/kernel-module-mmngr/kernel-module-mmngrbuf.bbappend3
-rw-r--r--meta-rcar-gen3-adas/recipes-kernel/kernel-module-uio-imp/files/GPL-COPYING339
-rw-r--r--meta-rcar-gen3-adas/recipes-kernel/kernel-module-uio-imp/files/MIT-COPYING41
-rw-r--r--meta-rcar-gen3-adas/recipes-kernel/kernel-module-uio-imp/files/Makefile14
-rw-r--r--meta-rcar-gen3-adas/recipes-kernel/kernel-module-uio-imp/files/uio_imp.c559
-rw-r--r--meta-rcar-gen3-adas/recipes-kernel/kernel-module-uio-imp/kernel-module-uio-imp_0.1.bb27
-rw-r--r--meta-rcar-gen3-adas/recipes-kernel/kernel-module-uvcs/kernel-module-uvcs-drv.bbappend1
-rw-r--r--meta-rcar-gen3-adas/recipes-kernel/kernel-module-vspmif/kernel-module-vspmif.bbappend1
-rw-r--r--meta-rcar-gen3-adas/recipes-kernel/linux/linux-renesas/0001-arm64-dts-renesas-preserve-drm-HDMI-connector-naming.patch54
-rw-r--r--meta-rcar-gen3-adas/recipes-kernel/linux/linux-renesas/0001-spi-sh-msiof-fixes.patch33
-rw-r--r--meta-rcar-gen3-adas/recipes-kernel/linux/linux-renesas/0002-spi-spidev-add-spi-gpio-into-spidev.patch27
-rw-r--r--meta-rcar-gen3-adas/recipes-kernel/linux/linux-renesas/0003-spi-spi-gpio-fix-CPOL-mode.patch42
-rw-r--r--meta-rcar-gen3-adas/recipes-kernel/linux/linux-renesas/0004-xhci-rcar-add-firmware-for-R-Car-H2-M2-USB-3.0-host-.patch205
-rw-r--r--meta-rcar-gen3-adas/recipes-kernel/linux/linux-renesas/0005-usb-host-xhci-plat-add-support-for-the-R-Car-H3-xHCI.patch174
-rw-r--r--meta-rcar-gen3-adas/recipes-kernel/linux/linux-renesas/0006-spi-spi-gpio-fix-set-CPOL-default-inverted.patch30
-rw-r--r--meta-rcar-gen3-adas/recipes-kernel/linux/linux-renesas/0008-arm64-do-not-set-dma-masks-that-device-connection-ca.patch132
-rw-r--r--meta-rcar-gen3-adas/recipes-kernel/linux/linux-renesas/0009-swiotlb-ensure-that-page-sized-mappings-are-page-ali.patch38
-rw-r--r--meta-rcar-gen3-adas/recipes-kernel/linux/linux-renesas/0010-can-rcar_can-add-enable-and-standby-control-pins.patch156
-rw-r--r--meta-rcar-gen3-adas/recipes-kernel/linux/linux-renesas/0011-can-rcar_canfd-add-enable-and-standby-control-pins.patch119
-rw-r--r--meta-rcar-gen3-adas/recipes-kernel/linux/linux-renesas/0012-mtd-Add-RPC-HyperFlash-driver.patch1028
-rw-r--r--meta-rcar-gen3-adas/recipes-kernel/linux/linux-renesas/0013-IMR-driver-interim-patch.patch2104
-rw-r--r--meta-rcar-gen3-adas/recipes-kernel/linux/linux-renesas/0014-lib-swiotlb-reduce-verbosity.patch40
-rw-r--r--meta-rcar-gen3-adas/recipes-kernel/linux/linux-renesas/0015-gpio-max732x-fix-gpio-set.patch29
-rw-r--r--meta-rcar-gen3-adas/recipes-kernel/linux/linux-renesas/0016-gpio-gpiolib-suppress-gpiod-warning.patch29
-rw-r--r--meta-rcar-gen3-adas/recipes-kernel/linux/linux-renesas/0017-media-soc_camera-add-legacy-VIN-CSI2.patch5055
-rw-r--r--meta-rcar-gen3-adas/recipes-kernel/linux/linux-renesas/0018-arm64-renesas-r8a7797-Add-Renesas-R8A7797-SoC-suppor.patch5132
-rw-r--r--meta-rcar-gen3-adas/recipes-kernel/linux/linux-renesas/0019-Revert-media-v4l2-async-remove-unneeded-.registered_.patch54
-rw-r--r--meta-rcar-gen3-adas/recipes-kernel/linux/linux-renesas/0020-ti-st-add-device-tree-support.patch236
-rw-r--r--meta-rcar-gen3-adas/recipes-kernel/linux/linux-renesas/0021-btwilink-add-minimal-device-tree-support.patch54
-rw-r--r--meta-rcar-gen3-adas/recipes-kernel/linux/linux-renesas/0022-ASoC-Modify-check-condition-of-multiple-bindings-of-.patch48
-rw-r--r--meta-rcar-gen3-adas/recipes-kernel/linux/linux-renesas/0023-ASoC-add-dummy-Si468x-driver.patch123
-rw-r--r--meta-rcar-gen3-adas/recipes-kernel/linux/linux-renesas/0024-wl18xx-do-not-invert-IRQ-on-WLxxxx-side.patch48
-rw-r--r--meta-rcar-gen3-adas/recipes-kernel/linux/linux-renesas/0025-drm-adv7511-Enable-HPD-interrupts-to-support-hotplug.patch46
-rw-r--r--meta-rcar-gen3-adas/recipes-kernel/linux/linux-renesas/0026-drm-adv7511-add-polling-mode-when-no-irq-available.patch30
-rw-r--r--meta-rcar-gen3-adas/recipes-kernel/linux/linux-renesas/0027-usb-host-xhci-plat-add-firmware-for-the-R-Car-M3-W-x.patch179
-rw-r--r--meta-rcar-gen3-adas/recipes-kernel/linux/linux-renesas/0028-usb-host-xhci-rcar-update-firmware-for-R-Car-H3-and-.patch206
-rw-r--r--meta-rcar-gen3-adas/recipes-kernel/linux/linux-renesas/0029-i2c-mux-pca954x-fix-i2c-mux-selection-caching.patch51
-rw-r--r--meta-rcar-gen3-adas/recipes-kernel/linux/linux-renesas/0030-Gen3-LVDS-cameras.patch7768
-rw-r--r--meta-rcar-gen3-adas/recipes-kernel/linux/linux-renesas/0031-media-i2c-Add-ov5647-sensor.patch952
-rw-r--r--meta-rcar-gen3-adas/recipes-kernel/linux/linux-renesas/0032-media-i2c-Add-ov5642-sensor.patch2173
-rw-r--r--meta-rcar-gen3-adas/recipes-kernel/linux/linux-renesas/0033-media-soc-camera-fix-parallel-i-f-in-VIN.patch69
-rw-r--r--meta-rcar-gen3-adas/recipes-kernel/linux/linux-renesas/0034-media-soc_camera-Fix-VIDIOC_S_SELECTION-ioctl-miscal.patch67
-rw-r--r--meta-rcar-gen3-adas/recipes-kernel/linux/linux-renesas/0035-regulator-fixed-probe-after-i2c.patch53
-rw-r--r--meta-rcar-gen3-adas/recipes-kernel/linux/linux-renesas/0040-arm64-dts-renesas-add-ADAS-boards.patch17543
-rw-r--r--meta-rcar-gen3-adas/recipes-kernel/linux/linux-renesas/0041-arm64-dts-renesas-ulcb-enlarge-cma-region.patch56
-rw-r--r--meta-rcar-gen3-adas/recipes-kernel/linux/linux-renesas/0042-arm64-dts-renesas-r8a7795-es1-h3ulcb-disable-eMMC.patch28
-rw-r--r--meta-rcar-gen3-adas/recipes-kernel/linux/linux-renesas/0043-arm64-dts-renesas-ulcb-use-versaclock-for-du-rgb-and-lvds.patch143
-rw-r--r--meta-rcar-gen3-adas/recipes-kernel/linux/linux-renesas/0044-pinctrl-r8a779x-add-mlb-pinmux.patch154
-rw-r--r--meta-rcar-gen3-adas/recipes-kernel/linux/linux-renesas/0045-clk-r8a779x-add-mlp-clock.patch38
-rw-r--r--meta-rcar-gen3-adas/recipes-kernel/linux/linux-renesas/0046-arm64-dts-renesas-r8a779x-add-mlp-nodes.patch87
-rw-r--r--meta-rcar-gen3-adas/recipes-kernel/linux/linux-renesas/0047-arm64-dts-renesas-ulcb-kf-enable-sd3.patch28
-rw-r--r--meta-rcar-gen3-adas/recipes-kernel/linux/linux-renesas/0048-arm64-dts-renesas-ulcb-kf-enable-most.patch28
-rw-r--r--meta-rcar-gen3-adas/recipes-kernel/linux/linux-renesas/0049-clk-r8a779x-add-IMP-clock.patch59
-rw-r--r--meta-rcar-gen3-adas/recipes-kernel/linux/linux-renesas/0050-arm64-dts-Gen3-view-boards-TYPE1-first-4-cameras.patch302
-rw-r--r--meta-rcar-gen3-adas/recipes-kernel/linux/linux-renesas/0050-arm64-dts-renesas-r8a779x-add-IMP-nodes.patch425
-rw-r--r--meta-rcar-gen3-adas/recipes-kernel/linux/linux-renesas/0051-arm64-dts-Gen3-view-boards-TYPE1-second-4-cameras.patch206
-rw-r--r--meta-rcar-gen3-adas/recipes-kernel/linux/linux-renesas/0052-arm64-dts-Gen3-view-boards-TYPE2-first-4-cameras.patch527
-rw-r--r--meta-rcar-gen3-adas/recipes-kernel/linux/linux-renesas/0062-IIO-lsm9ds0-add-IMU-driver.patch972
-rw-r--r--meta-rcar-gen3-adas/recipes-kernel/linux/linux-renesas/0063-ASoC-PCM3168A-add-TDM-modes-merge-ADC-and-DAC.patch479
-rw-r--r--meta-rcar-gen3-adas/recipes-kernel/linux/linux-renesas/0064-ADV7511-limit-maximum-pixelclock.patch76
-rw-r--r--meta-rcar-gen3-adas/recipes-kernel/linux/linux-renesas/0066-pci-pcie-rcar-add-regulators-support.patch107
-rw-r--r--meta-rcar-gen3-adas/recipes-kernel/linux/linux-renesas/0067-ti-st-use-proper-way-to-get-shutdown-gpio.patch61
-rw-r--r--meta-rcar-gen3-adas/recipes-kernel/linux/linux-renesas/0068-drm-adv7511-use-smbus-to-retrieve-edid.patch53
-rw-r--r--meta-rcar-gen3-adas/recipes-kernel/linux/linux-renesas/0070-clk-clk-5p49x-add-5P49V5925-chip.patch49
-rw-r--r--meta-rcar-gen3-adas/recipes-kernel/linux/linux-renesas/0071-ASoC-add-dummy-device-for-WL18xx-PCM-audio.patch128
-rw-r--r--meta-rcar-gen3-adas/recipes-kernel/linux/linux-renesas/0072-usb-hub-disable-autosuspend-for-SMSC-hubs.patch51
-rw-r--r--meta-rcar-gen3-adas/recipes-kernel/linux/linux-renesas/0073-MOST-dim2-add-device-tree-support.patch169
-rw-r--r--meta-rcar-gen3-adas/recipes-kernel/linux/linux-renesas/0074-MOST-dim2-add-R-Car3-related-initialization.patch63
-rw-r--r--meta-rcar-gen3-adas/recipes-kernel/linux/linux-renesas/0075-MOST-core-fix-memory-allocation-at-arm64.patch54
-rw-r--r--meta-rcar-gen3-adas/recipes-kernel/linux/linux-renesas/0076-MOST-dim2-Renesas-R-Car3-variant.patch120
-rw-r--r--meta-rcar-gen3-adas/recipes-kernel/linux/linux-renesas/0077-MOST-dim2-add-timeouts.patch46
-rw-r--r--meta-rcar-gen3-adas/recipes-kernel/linux/linux-renesas/0078-MOST-aim-fix-null-pointer-crash.patch29
-rw-r--r--meta-rcar-gen3-adas/recipes-kernel/linux/linux-renesas/0079-Revert-dmaengine-rcar-dmac-use-TCRB-instead-of-TCR-f.patch29
-rw-r--r--meta-rcar-gen3-adas/recipes-kernel/linux/linux-renesas/0080-dmaengine-rcar-dmac-ensure-CHCR-DE-bit-is-actually-0.patch87
-rw-r--r--meta-rcar-gen3-adas/recipes-kernel/linux/linux-renesas/0081-dmaengine-rcar-dmac-use-TCRB-instead-of-TCR-for-resi.patch108
-rw-r--r--meta-rcar-gen3-adas/recipes-kernel/linux/linux-renesas/0100-LVDS-ar0132-use-raw12.patch152
-rw-r--r--meta-rcar-gen3-adas/recipes-kernel/linux/linux-renesas/0101-LVDS-ar0132-use-context-swwitch.patch119
-rw-r--r--meta-rcar-gen3-adas/recipes-kernel/linux/linux-renesas/0103-gpu-drm-rcar-du-Extend-VSP1-DRM-interface.patch546
-rw-r--r--meta-rcar-gen3-adas/recipes-kernel/linux/linux-renesas/0104-media-vsp1-extend-DRM-VSP1-interface.patch367
-rw-r--r--meta-rcar-gen3-adas/recipes-kernel/linux/linux-renesas/0105-media-rcar-imr-IMR-driver-updates-for-raw-DL.patch538
-rw-r--r--meta-rcar-gen3-adas/recipes-kernel/linux/linux-renesas/eagle.cfg29
-rw-r--r--meta-rcar-gen3-adas/recipes-kernel/linux/linux-renesas/hyperflash.cfg2
-rw-r--r--meta-rcar-gen3-adas/recipes-kernel/linux/linux-renesas/salvator-x.cfg32
-rw-r--r--meta-rcar-gen3-adas/recipes-kernel/linux/linux-renesas/sdhi_seq.cfg2
-rw-r--r--meta-rcar-gen3-adas/recipes-kernel/linux/linux-renesas/ulcb.cfg82
-rw-r--r--meta-rcar-gen3-adas/recipes-kernel/linux/linux-renesas/v3msk.cfg33
-rw-r--r--meta-rcar-gen3-adas/recipes-kernel/linux/linux-renesas_4.9.bbappend133
-rw-r--r--meta-rcar-gen3-adas/recipes-multimedia/gstreamer/gstreamer1.0-plugin-vspfilter_1.0.0.bbappend1
-rw-r--r--meta-rcar-gen3-adas/recipes-multimedia/gstreamer/gstreamer1.0-plugins-bad-1.6.3/0001-install-wayland.h-header.patch33
-rw-r--r--meta-rcar-gen3-adas/recipes-multimedia/gstreamer/gstreamer1.0-plugins-bad-1.6.3/0002-pkgconfig-libgstwayland.patch34
-rw-r--r--meta-rcar-gen3-adas/recipes-multimedia/gstreamer/gstreamer1.0-plugins-bad_1.6.3.bbappend6
-rw-r--r--meta-rcar-gen3-adas/recipes-multimedia/mm-init/mm-init.bb16
-rw-r--r--meta-rcar-gen3-adas/recipes-multimedia/mm-init/mm-init/init28
-rw-r--r--meta-rcar-gen3-adas/recipes-multimedia/v4l2apps/libmediactl-v4l2.bb16
-rw-r--r--meta-rcar-gen3-adas/recipes-support/ctemplate/ctemplate.inc12
-rw-r--r--meta-rcar-gen3-adas/recipes-support/ctemplate/ctemplate_2.3.bb9
-rw-r--r--meta-rcar-gen3-adas/recipes-support/ctemplate/ctemplate_svn.bb11
-rw-r--r--meta-rcar-gen3-adas/recipes-support/gflags/gflags_git.bb20
-rw-r--r--meta-rcar-gen3-adas/recipes-support/glm/glm.inc16
-rw-r--r--meta-rcar-gen3-adas/recipes-support/glm/glm/0001-Fix-cmake-pathes.patch25
-rw-r--r--meta-rcar-gen3-adas/recipes-support/glm/glm_0.9.7.0.bb10
-rw-r--r--meta-rcar-gen3-adas/recipes-support/glm/glm_git.bb13
-rw-r--r--meta-rcar-gen3-adas/recipes-support/libiio/libiio.inc11
-rw-r--r--meta-rcar-gen3-adas/recipes-support/libiio/libiio_0.5.bb9
-rw-r--r--meta-rcar-gen3-adas/recipes-support/libiio/libiio_git.bb8
-rw-r--r--meta-rcar-gen3-adas/recipes-support/libusbg/libusbg.inc10
-rw-r--r--meta-rcar-gen3-adas/recipes-support/libusbg/libusbg_0.1.0.bb9
-rw-r--r--meta-rcar-gen3-adas/recipes-support/libusbg/libusbg_git.bb9
-rw-r--r--meta-rcar-gen3-adas/recipes-support/netevent/netevent/0001-fix-endian-for-cross-arch.patch113
-rw-r--r--meta-rcar-gen3-adas/recipes-support/netevent/netevent/0002-fix-cross-compile.patch70
-rw-r--r--meta-rcar-gen3-adas/recipes-support/netevent/netevent/0003-use-socket-instead-of-stdout.patch653
-rw-r--r--meta-rcar-gen3-adas/recipes-support/netevent/netevent/0004-Add-TCP-keep-alive-to-handle-peer-death-properly.patch162
-rw-r--r--meta-rcar-gen3-adas/recipes-support/netevent/netevent_git.bb29
-rw-r--r--meta-rcar-gen3-adas/recipes-support/nlopt/nlopt.inc32
-rw-r--r--meta-rcar-gen3-adas/recipes-support/nlopt/nlopt/0001-Fix-compilation-error.patch25
-rw-r--r--meta-rcar-gen3-adas/recipes-support/nlopt/nlopt_2.4.2.bb7
-rw-r--r--meta-rcar-gen3-adas/recipes-support/nlopt/nlopt_git.bb8
-rw-r--r--meta-rcar-gen3-adas/recipes-support/spacenav/libspnav/0001-libspnav-cross-compile.patch42
-rw-r--r--meta-rcar-gen3-adas/recipes-support/spacenav/libspnav/0002-Fix-configuration-for-libdir.patch87
-rw-r--r--meta-rcar-gen3-adas/recipes-support/spacenav/libspnav/libspnav-0.2.3.tar.gzbin0 -> 11985 bytes
-rw-r--r--meta-rcar-gen3-adas/recipes-support/spacenav/libspnav_0.2.3.bb24
-rw-r--r--meta-rcar-gen3-adas/recipes-support/spacenav/spacenavd/0001-spacenavd-cross-compile.patch95
-rw-r--r--meta-rcar-gen3-adas/recipes-support/spacenav/spacenavd/0002-Fix-build-configuration.patch27
-rw-r--r--meta-rcar-gen3-adas/recipes-support/spacenav/spacenavd/spacenavd-0.6.tar.gzbin0 -> 54730 bytes
-rw-r--r--meta-rcar-gen3-adas/recipes-support/spacenav/spacenavd/spacenavd.service13
-rw-r--r--meta-rcar-gen3-adas/recipes-support/spacenav/spacenavd_0.6.bb39
211 files changed, 64671 insertions, 0 deletions
diff --git a/meta-rcar-gen3-adas/conf/layer.conf b/meta-rcar-gen3-adas/conf/layer.conf
new file mode 100644
index 0000000..a091d3a
--- /dev/null
+++ b/meta-rcar-gen3-adas/conf/layer.conf
@@ -0,0 +1,12 @@
+# We have a conf and classes directory, append to BBPATH
+BBPATH .= ":${LAYERDIR}"
+
+# We have a recipes directory, add to BBFILES
+BBFILES += " \
+ ${LAYERDIR}/recipes-*/*/*.bb \
+ ${LAYERDIR}/recipes-*/*/*.bbappend \
+"
+
+BBFILE_COLLECTIONS += "rcar-gen3-adas"
+BBFILE_PATTERN_rcar-gen3-adas := "^${LAYERDIR}/"
+BBFILE_PRIORITY_rcar-gen3-adas = "7"
diff --git a/meta-rcar-gen3-adas/conf/machine/eagle.conf b/meta-rcar-gen3-adas/conf/machine/eagle.conf
new file mode 100644
index 0000000..02e2a45
--- /dev/null
+++ b/meta-rcar-gen3-adas/conf/machine/eagle.conf
@@ -0,0 +1,35 @@
+#@TYPE: Machine
+#@NAME: Eagle machine
+#@DESCRIPTION: Machine configuration for running Eagle
+
+DEFAULTTUNE ?= "cortexa53"
+require conf/machine/include/tune-cortexa53.inc
+require conf/machine/include/${SOC_FAMILY}.inc
+
+# 32BIT package install (default is disable)
+# This variables can be used only in multilib.
+USE_32BIT_PKGS ?= "0"
+USE_32BIT_WAYLAND ?= "0"
+USE_32BIT_MMP ?= "0"
+
+MACHINE_FEATURES = ""
+
+KERNEL_IMAGETYPE = "Image"
+IMAGE_FSTYPES = "tar.bz2 ext4 cpio.gz"
+
+SERIAL_CONSOLE = "115200 ttySC0"
+
+# Configuration for kernel
+PREFERRED_PROVIDER_virtual/kernel = "linux-renesas"
+KERNEL_DEVICETREE = "renesas/r8a7797-eagle.dtb"
+
+# u-boot
+PREFERRED_VERSION_u-boot = "v2015.04%"
+EXTRA_IMAGEDEPENDS += " u-boot"
+UBOOT_MACHINE = "r8a7797_eagle_defconfig"
+
+# libdrm
+PREFERRED_VERSION_libdrm = "2.4.68"
+
+# Add variable to Build Configuration in build log
+BUILDCFG_VARS_append = " SOC_FAMILY"
diff --git a/meta-rcar-gen3-adas/conf/machine/include/r8a7797.inc b/meta-rcar-gen3-adas/conf/machine/include/r8a7797.inc
new file mode 100644
index 0000000..e2cc4ac
--- /dev/null
+++ b/meta-rcar-gen3-adas/conf/machine/include/r8a7797.inc
@@ -0,0 +1,3 @@
+SOC_FAMILY =. "rcar-gen3:"
+require conf/machine/include/soc-family.inc
+LINUXLIBCVERSION = "4.9"
diff --git a/meta-rcar-gen3-adas/conf/machine/include/tune-cortexa53.inc b/meta-rcar-gen3-adas/conf/machine/include/tune-cortexa53.inc
new file mode 100644
index 0000000..ebf2c4f
--- /dev/null
+++ b/meta-rcar-gen3-adas/conf/machine/include/tune-cortexa53.inc
@@ -0,0 +1,18 @@
+DEFAULTTUNE ?= "cortexa53"
+require conf/machine/include/arm/arch-armv8.inc
+
+TUNEVALID[cortexa53] = "Enable Cortex-A53 specific processor optimizations"
+TUNECONFLICTS[aarch64] = "armv4 armv5 armv6 armv7 armv7a"
+
+TUNE_CCARGS .= "${@bb.utils.contains("TUNE_FEATURES", "aarch64", " -march=armv8-a", "" ,d)}"
+
+MACHINEOVERRIDES =. "${@bb.utils.contains("TUNE_FEATURES", "cortexa53", "cortexa53:", "" ,d)}"
+
+TUNE_CCARGS .= "${@bb.utils.contains("TUNE_FEATURES", "cortexa53", " -mtune=cortex-a53", "", d)}"
+
+# Little Endian base configs
+AVAILTUNES += "cortexa53"
+ARMPKGARCH_tune-cortexa53 = "cortexa53"
+TUNE_FEATURES_tune-cortexa53 = "${TUNE_FEATURES_tune-aarch64} cortexa53"
+PACKAGE_EXTRA_ARCHS_tune-cortexa53 = "${PACKAGE_EXTRA_ARCHS_tune-aarch64} cortexa53"
+BASE_LIB_tune-cortexa53 = "lib64"
diff --git a/meta-rcar-gen3-adas/conf/machine/v3msk.conf b/meta-rcar-gen3-adas/conf/machine/v3msk.conf
new file mode 100644
index 0000000..75292c1
--- /dev/null
+++ b/meta-rcar-gen3-adas/conf/machine/v3msk.conf
@@ -0,0 +1,35 @@
+#@TYPE: Machine
+#@NAME: V3MSK machine
+#@DESCRIPTION: Machine configuration for running V3MSK
+
+DEFAULTTUNE ?= "cortexa53"
+require conf/machine/include/tune-cortexa53.inc
+require conf/machine/include/${SOC_FAMILY}.inc
+
+# 32BIT package install (default is disable)
+# This variables can be used only in multilib.
+USE_32BIT_PKGS ?= "0"
+USE_32BIT_WAYLAND ?= "0"
+USE_32BIT_MMP ?= "0"
+
+MACHINE_FEATURES = ""
+
+KERNEL_IMAGETYPE = "Image"
+IMAGE_FSTYPES = "tar.bz2 ext4 cpio.gz"
+
+SERIAL_CONSOLE = "115200 ttySC0"
+
+# Configuration for kernel
+PREFERRED_PROVIDER_virtual/kernel = "linux-renesas"
+KERNEL_DEVICETREE = "renesas/r8a7797-v3msk.dtb"
+
+# u-boot
+PREFERRED_VERSION_u-boot = "v2015.04%"
+EXTRA_IMAGEDEPENDS += " u-boot"
+UBOOT_MACHINE = "v3msk_defconfig"
+
+# libdrm
+PREFERRED_VERSION_libdrm = "2.4.68"
+
+# Add variable to Build Configuration in build log
+BUILDCFG_VARS_append = " SOC_FAMILY"
diff --git a/meta-rcar-gen3-adas/docs/sample/conf/eagle/linaro-gcc/bsp/bblayers.conf b/meta-rcar-gen3-adas/docs/sample/conf/eagle/linaro-gcc/bsp/bblayers.conf
new file mode 100644
index 0000000..96ff8ad
--- /dev/null
+++ b/meta-rcar-gen3-adas/docs/sample/conf/eagle/linaro-gcc/bsp/bblayers.conf
@@ -0,0 +1,16 @@
+# POKY_BBLAYERS_CONF_VERSION is increased each time build/conf/bblayers.conf
+# changes incompatibly
+POKY_BBLAYERS_CONF_VERSION = "2"
+
+BBPATH = "${TOPDIR}"
+BBFILES ?= ""
+
+BBLAYERS ?= " \
+ ${TOPDIR}/../poky/meta \
+ ${TOPDIR}/../poky/meta-poky \
+ ${TOPDIR}/../poky/meta-yocto-bsp \
+ ${TOPDIR}/../meta-renesas/meta-rcar-gen3 \
+ ${TOPDIR}/../meta-linaro/meta-linaro-toolchain \
+ ${TOPDIR}/../meta-linaro/meta-optee \
+ ${TOPDIR}/../meta-openembedded/meta-oe \
+ "
diff --git a/meta-rcar-gen3-adas/docs/sample/conf/eagle/linaro-gcc/bsp/local.conf b/meta-rcar-gen3-adas/docs/sample/conf/eagle/linaro-gcc/bsp/local.conf
new file mode 100644
index 0000000..a1c3b2a
--- /dev/null
+++ b/meta-rcar-gen3-adas/docs/sample/conf/eagle/linaro-gcc/bsp/local.conf
@@ -0,0 +1,267 @@
+#
+# This file is your local configuration file and is where all local user settings
+# are placed. The comments in this file give some guide to the options a new user
+# to the system might want to change but pretty much any configuration option can
+# be set in this file. More adventurous users can look at local.conf.extended
+# which contains other examples of configuration which can be placed in this file
+# but new users likely won't need any of them initially.
+#
+# Lines starting with the '#' character are commented out and in some cases the
+# default values are provided as comments to show people example syntax. Enabling
+# the option is a question of removing the # character and making any change to the
+# variable as required.
+
+#
+# Machine Selection
+#
+# You need to select a specific machine to target the build with. There are a selection
+# of emulated machines available which can boot and run in the QEMU emulator:
+#
+#MACHINE ?= "qemuarm"
+#MACHINE ?= "qemuarm64"
+#MACHINE ?= "qemumips"
+#MACHINE ?= "qemumips64"
+#MACHINE ?= "qemuppc"
+#MACHINE ?= "qemux86"
+#MACHINE ?= "qemux86-64"
+#
+# There are also the following hardware board target machines included for
+# demonstration purposes:
+#
+#MACHINE ?= "beaglebone"
+#MACHINE ?= "genericx86"
+#MACHINE ?= "genericx86-64"
+#MACHINE ?= "mpc8315e-rdb"
+#MACHINE ?= "edgerouter"
+#
+# This sets the default machine to be qemux86 if no other machine is selected:
+MACHINE ??= "eagle"
+
+SOC_FAMILY = "r8a7797"
+
+#
+# Where to place downloads
+#
+# During a first build the system will download many different source code tarballs
+# from various upstream projects. This can take a while, particularly if your network
+# connection is slow. These are all stored in DL_DIR. When wiping and rebuilding you
+# can preserve this directory to speed up this part of subsequent builds. This directory
+# is safe to share between multiple builds on the same machine too.
+#
+# The default is a downloads directory under TOPDIR which is the build directory.
+#
+#DL_DIR ?= "${TOPDIR}/downloads"
+
+#
+# Where to place shared-state files
+#
+# BitBake has the capability to accelerate builds based on previously built output.
+# This is done using "shared state" files which can be thought of as cache objects
+# and this option determines where those files are placed.
+#
+# You can wipe out TMPDIR leaving this directory intact and the build would regenerate
+# from these files if no changes were made to the configuration. If changes were made
+# to the configuration, only shared state files where the state was still valid would
+# be used (done using checksums).
+#
+# The default is a sstate-cache directory under TOPDIR.
+#
+#SSTATE_DIR ?= "${TOPDIR}/sstate-cache"
+
+#
+# Where to place the build output
+#
+# This option specifies where the bulk of the building work should be done and
+# where BitBake should place its temporary files and output. Keep in mind that
+# this includes the extraction and compilation of many applications and the toolchain
+# which can use Gigabytes of hard disk space.
+#
+# The default is a tmp directory under TOPDIR.
+#
+#TMPDIR = "${TOPDIR}/tmp"
+
+#
+# Default policy config
+#
+# The distribution setting controls which policy settings are used as defaults.
+# The default value is fine for general Yocto project use, at least initially.
+# Ultimately when creating custom policy, people will likely end up subclassing
+# these defaults.
+#
+DISTRO ?= "poky"
+# As an example of a subclass there is a "bleeding" edge policy configuration
+# where many versions are set to the absolute latest code from the upstream
+# source control systems. This is just mentioned here as an example, its not
+# useful to most new users.
+# DISTRO ?= "poky-bleeding"
+
+#
+# Package Management configuration
+#
+# This variable lists which packaging formats to enable. Multiple package backends
+# can be enabled at once and the first item listed in the variable will be used
+# to generate the root filesystems.
+# Options are:
+# - 'package_deb' for debian style deb files
+# - 'package_ipk' for ipk files are used by opkg (a debian style embedded package manager)
+# - 'package_rpm' for rpm style packages
+# E.g.: PACKAGE_CLASSES ?= "package_rpm package_deb package_ipk"
+# We default to rpm:
+PACKAGE_CLASSES ?= "package_ipk"
+
+#
+# SDK target architecture
+#
+# This variable specifies the architecture to build SDK items for and means
+# you can build the SDK packages for architectures other than the machine you are
+# running the build on (i.e. building i686 packages on an x86_64 host).
+# Supported values are i686 and x86_64
+#SDKMACHINE ?= "i686"
+
+#
+# Extra image configuration defaults
+#
+# The EXTRA_IMAGE_FEATURES variable allows extra packages to be added to the generated
+# images. Some of these options are added to certain image types automatically. The
+# variable can contain the following options:
+# "dbg-pkgs" - add -dbg packages for all installed packages
+# (adds symbol information for debugging/profiling)
+# "dev-pkgs" - add -dev packages for all installed packages
+# (useful if you want to develop against libs in the image)
+# "ptest-pkgs" - add -ptest packages for all ptest-enabled packages
+# (useful if you want to run the package test suites)
+# "tools-sdk" - add development tools (gcc, make, pkgconfig etc.)
+# "tools-debug" - add debugging tools (gdb, strace)
+# "eclipse-debug" - add Eclipse remote debugging support
+# "tools-profile" - add profiling tools (oprofile, lttng, valgrind)
+# "tools-testapps" - add useful testing tools (ts_print, aplay, arecord etc.)
+# "debug-tweaks" - make an image suitable for development
+# e.g. ssh root access has a blank password
+# There are other application targets that can be used here too, see
+# meta/classes/image.bbclass and meta/classes/core-image.bbclass for more details.
+# We default to enabling the debugging tweaks.
+EXTRA_IMAGE_FEATURES ?= "debug-tweaks"
+
+#
+# Additional image features
+#
+# The following is a list of additional classes to use when building images which
+# enable extra features. Some available options which can be included in this variable
+# are:
+# - 'buildstats' collect build statistics
+# - 'image-mklibs' to reduce shared library files size for an image
+# - 'image-prelink' in order to prelink the filesystem image
+# - 'image-swab' to perform host system intrusion detection
+# NOTE: if listing mklibs & prelink both, then make sure mklibs is before prelink
+# NOTE: mklibs also needs to be explicitly enabled for a given image, see local.conf.extended
+# image-prelink disabled for now due to issues with IFUNC symbol relocation
+USER_CLASSES ?= "buildstats image-mklibs"
+
+#
+# Runtime testing of images
+#
+# The build system can test booting virtual machine images under qemu (an emulator)
+# after any root filesystems are created and run tests against those images. To
+# enable this uncomment this line. See classes/testimage(-auto).bbclass for
+# further details.
+#TEST_IMAGE = "1"
+#
+# Interactive shell configuration
+#
+# Under certain circumstances the system may need input from you and to do this it
+# can launch an interactive shell. It needs to do this since the build is
+# multithreaded and needs to be able to handle the case where more than one parallel
+# process may require the user's attention. The default is iterate over the available
+# terminal types to find one that works.
+#
+# Examples of the occasions this may happen are when resolving patches which cannot
+# be applied, to use the devshell or the kernel menuconfig
+#
+# Supported values are auto, gnome, xfce, rxvt, screen, konsole (KDE 3.x only), none
+# Note: currently, Konsole support only works for KDE 3.x due to the way
+# newer Konsole versions behave
+#OE_TERMINAL = "auto"
+# By default disable interactive patch resolution (tasks will just fail instead):
+PATCHRESOLVE = "noop"
+
+#
+# Disk Space Monitoring during the build
+#
+# Monitor the disk space during the build. If there is less that 1GB of space or less
+# than 100K inodes in any key build location (TMPDIR, DL_DIR, SSTATE_DIR), gracefully
+# shutdown the build. If there is less that 100MB or 1K inodes, perform a hard abort
+# of the build. The reason for this is that running completely out of space can corrupt
+# files and damages the build in ways which may not be easily recoverable.
+# It's necesary to monitor /tmp, if there is no space left the build will fail
+# with very exotic errors.
+BB_DISKMON_DIRS = "\
+ STOPTASKS,${TMPDIR},1G,100K \
+ STOPTASKS,${DL_DIR},1G,100K \
+ STOPTASKS,${SSTATE_DIR},1G,100K \
+ STOPTASKS,/tmp,100M,100K \
+ ABORT,${TMPDIR},100M,1K \
+ ABORT,${DL_DIR},100M,1K \
+ ABORT,${SSTATE_DIR},100M,1K \
+ ABORT,/tmp,10M,1K"
+
+#
+# Shared-state files from other locations
+#
+# As mentioned above, shared state files are prebuilt cache data objects which can
+# used to accelerate build time. This variable can be used to configure the system
+# to search other mirror locations for these objects before it builds the data itself.
+#
+# This can be a filesystem directory, or a remote url such as http or ftp. These
+# would contain the sstate-cache results from previous builds (possibly from other
+# machines). This variable works like fetcher MIRRORS/PREMIRRORS and points to the
+# cache locations to check for the shared objects.
+# NOTE: if the mirror uses the same structure as SSTATE_DIR, you need to add PATH
+# at the end as shown in the examples below. This will be substituted with the
+# correct path within the directory structure.
+#SSTATE_MIRRORS ?= "\
+#file://.* http://someserver.tld/share/sstate/PATH;downloadfilename=PATH \n \
+#file://.* file:///some/local/dir/sstate/PATH"
+
+
+#
+# Qemu configuration
+#
+# By default qemu will build with a builtin VNC server where graphical output can be
+# seen. The two lines below enable the SDL backend too. By default libsdl-native will
+# be built, if you want to use your host's libSDL instead of the minimal libsdl built
+# by libsdl-native then uncomment the ASSUME_PROVIDED line below.
+PACKAGECONFIG_append_pn-qemu-native = " sdl"
+PACKAGECONFIG_append_pn-nativesdk-qemu = " sdl"
+#ASSUME_PROVIDED += "libsdl-native"
+
+# CONF_VERSION is increased each time build/conf/ changes incompatibly and is used to
+# track the version of this file when it was generated. This can safely be ignored if
+# this doesn't mean anything to you.
+CONF_VERSION = "1"
+
+# Add systemd configuration
+DISTRO_FEATURES_append = " systemd"
+VIRTUAL-RUNTIME_init_manager = "systemd"
+
+# Linaro GCC
+GCCVERSION = "linaro-5.2"
+
+# add the static lib to SDK toolchain
+SDKIMAGE_FEATURES_append = " staticdev-pkgs"
+
+# Disable optee in meta-linaro layer
+BBMASK = "meta-linaro/meta-optee/recipes-security/optee"
+
+# Mask graphic Pkgs
+BBMASK .= "|gles-user-module|kernel-module-gles|wayland-kms|libgbm"
+# Mask MMP recipes
+BBMASK .= "|kernel-module-uvcs-drv|omx-user-module"
+
+# Add for gstreamer plugins ugly
+LICENSE_FLAGS_WHITELIST = "commercial"
+
+# Linux ICCOM driver (RCG3ZLIDL4001ZNO)
+# Linux ICCOM library (RCG3ZLILL4001ZNO)
+#DISTRO_FEATURES_append = " iccom"
+
+IMAGE_INSTALL_remove = "optee-linuxdriver optee-linuxdriver-armtz optee-client"
diff --git a/meta-rcar-gen3-adas/docs/sample/conf/v3msk/linaro-gcc/bsp/bblayers.conf b/meta-rcar-gen3-adas/docs/sample/conf/v3msk/linaro-gcc/bsp/bblayers.conf
new file mode 100644
index 0000000..96ff8ad
--- /dev/null
+++ b/meta-rcar-gen3-adas/docs/sample/conf/v3msk/linaro-gcc/bsp/bblayers.conf
@@ -0,0 +1,16 @@
+# POKY_BBLAYERS_CONF_VERSION is increased each time build/conf/bblayers.conf
+# changes incompatibly
+POKY_BBLAYERS_CONF_VERSION = "2"
+
+BBPATH = "${TOPDIR}"
+BBFILES ?= ""
+
+BBLAYERS ?= " \
+ ${TOPDIR}/../poky/meta \
+ ${TOPDIR}/../poky/meta-poky \
+ ${TOPDIR}/../poky/meta-yocto-bsp \
+ ${TOPDIR}/../meta-renesas/meta-rcar-gen3 \
+ ${TOPDIR}/../meta-linaro/meta-linaro-toolchain \
+ ${TOPDIR}/../meta-linaro/meta-optee \
+ ${TOPDIR}/../meta-openembedded/meta-oe \
+ "
diff --git a/meta-rcar-gen3-adas/docs/sample/conf/v3msk/linaro-gcc/bsp/local.conf b/meta-rcar-gen3-adas/docs/sample/conf/v3msk/linaro-gcc/bsp/local.conf
new file mode 100644
index 0000000..75b33e7
--- /dev/null
+++ b/meta-rcar-gen3-adas/docs/sample/conf/v3msk/linaro-gcc/bsp/local.conf
@@ -0,0 +1,267 @@
+#
+# This file is your local configuration file and is where all local user settings
+# are placed. The comments in this file give some guide to the options a new user
+# to the system might want to change but pretty much any configuration option can
+# be set in this file. More adventurous users can look at local.conf.extended
+# which contains other examples of configuration which can be placed in this file
+# but new users likely won't need any of them initially.
+#
+# Lines starting with the '#' character are commented out and in some cases the
+# default values are provided as comments to show people example syntax. Enabling
+# the option is a question of removing the # character and making any change to the
+# variable as required.
+
+#
+# Machine Selection
+#
+# You need to select a specific machine to target the build with. There are a selection
+# of emulated machines available which can boot and run in the QEMU emulator:
+#
+#MACHINE ?= "qemuarm"
+#MACHINE ?= "qemuarm64"
+#MACHINE ?= "qemumips"
+#MACHINE ?= "qemumips64"
+#MACHINE ?= "qemuppc"
+#MACHINE ?= "qemux86"
+#MACHINE ?= "qemux86-64"
+#
+# There are also the following hardware board target machines included for
+# demonstration purposes:
+#
+#MACHINE ?= "beaglebone"
+#MACHINE ?= "genericx86"
+#MACHINE ?= "genericx86-64"
+#MACHINE ?= "mpc8315e-rdb"
+#MACHINE ?= "edgerouter"
+#
+# This sets the default machine to be qemux86 if no other machine is selected:
+MACHINE ??= "v3msk"
+
+SOC_FAMILY = "r8a7797"
+
+#
+# Where to place downloads
+#
+# During a first build the system will download many different source code tarballs
+# from various upstream projects. This can take a while, particularly if your network
+# connection is slow. These are all stored in DL_DIR. When wiping and rebuilding you
+# can preserve this directory to speed up this part of subsequent builds. This directory
+# is safe to share between multiple builds on the same machine too.
+#
+# The default is a downloads directory under TOPDIR which is the build directory.
+#
+#DL_DIR ?= "${TOPDIR}/downloads"
+
+#
+# Where to place shared-state files
+#
+# BitBake has the capability to accelerate builds based on previously built output.
+# This is done using "shared state" files which can be thought of as cache objects
+# and this option determines where those files are placed.
+#
+# You can wipe out TMPDIR leaving this directory intact and the build would regenerate
+# from these files if no changes were made to the configuration. If changes were made
+# to the configuration, only shared state files where the state was still valid would
+# be used (done using checksums).
+#
+# The default is a sstate-cache directory under TOPDIR.
+#
+#SSTATE_DIR ?= "${TOPDIR}/sstate-cache"
+
+#
+# Where to place the build output
+#
+# This option specifies where the bulk of the building work should be done and
+# where BitBake should place its temporary files and output. Keep in mind that
+# this includes the extraction and compilation of many applications and the toolchain
+# which can use Gigabytes of hard disk space.
+#
+# The default is a tmp directory under TOPDIR.
+#
+#TMPDIR = "${TOPDIR}/tmp"
+
+#
+# Default policy config
+#
+# The distribution setting controls which policy settings are used as defaults.
+# The default value is fine for general Yocto project use, at least initially.
+# Ultimately when creating custom policy, people will likely end up subclassing
+# these defaults.
+#
+DISTRO ?= "poky"
+# As an example of a subclass there is a "bleeding" edge policy configuration
+# where many versions are set to the absolute latest code from the upstream
+# source control systems. This is just mentioned here as an example, its not
+# useful to most new users.
+# DISTRO ?= "poky-bleeding"
+
+#
+# Package Management configuration
+#
+# This variable lists which packaging formats to enable. Multiple package backends
+# can be enabled at once and the first item listed in the variable will be used
+# to generate the root filesystems.
+# Options are:
+# - 'package_deb' for debian style deb files
+# - 'package_ipk' for ipk files are used by opkg (a debian style embedded package manager)
+# - 'package_rpm' for rpm style packages
+# E.g.: PACKAGE_CLASSES ?= "package_rpm package_deb package_ipk"
+# We default to rpm:
+PACKAGE_CLASSES ?= "package_ipk"
+
+#
+# SDK target architecture
+#
+# This variable specifies the architecture to build SDK items for and means
+# you can build the SDK packages for architectures other than the machine you are
+# running the build on (i.e. building i686 packages on an x86_64 host).
+# Supported values are i686 and x86_64
+#SDKMACHINE ?= "i686"
+
+#
+# Extra image configuration defaults
+#
+# The EXTRA_IMAGE_FEATURES variable allows extra packages to be added to the generated
+# images. Some of these options are added to certain image types automatically. The
+# variable can contain the following options:
+# "dbg-pkgs" - add -dbg packages for all installed packages
+# (adds symbol information for debugging/profiling)
+# "dev-pkgs" - add -dev packages for all installed packages
+# (useful if you want to develop against libs in the image)
+# "ptest-pkgs" - add -ptest packages for all ptest-enabled packages
+# (useful if you want to run the package test suites)
+# "tools-sdk" - add development tools (gcc, make, pkgconfig etc.)
+# "tools-debug" - add debugging tools (gdb, strace)
+# "eclipse-debug" - add Eclipse remote debugging support
+# "tools-profile" - add profiling tools (oprofile, lttng, valgrind)
+# "tools-testapps" - add useful testing tools (ts_print, aplay, arecord etc.)
+# "debug-tweaks" - make an image suitable for development
+# e.g. ssh root access has a blank password
+# There are other application targets that can be used here too, see
+# meta/classes/image.bbclass and meta/classes/core-image.bbclass for more details.
+# We default to enabling the debugging tweaks.
+EXTRA_IMAGE_FEATURES ?= "debug-tweaks"
+
+#
+# Additional image features
+#
+# The following is a list of additional classes to use when building images which
+# enable extra features. Some available options which can be included in this variable
+# are:
+# - 'buildstats' collect build statistics
+# - 'image-mklibs' to reduce shared library files size for an image
+# - 'image-prelink' in order to prelink the filesystem image
+# - 'image-swab' to perform host system intrusion detection
+# NOTE: if listing mklibs & prelink both, then make sure mklibs is before prelink
+# NOTE: mklibs also needs to be explicitly enabled for a given image, see local.conf.extended
+# image-prelink disabled for now due to issues with IFUNC symbol relocation
+USER_CLASSES ?= "buildstats image-mklibs"
+
+#
+# Runtime testing of images
+#
+# The build system can test booting virtual machine images under qemu (an emulator)
+# after any root filesystems are created and run tests against those images. To
+# enable this uncomment this line. See classes/testimage(-auto).bbclass for
+# further details.
+#TEST_IMAGE = "1"
+#
+# Interactive shell configuration
+#
+# Under certain circumstances the system may need input from you and to do this it
+# can launch an interactive shell. It needs to do this since the build is
+# multithreaded and needs to be able to handle the case where more than one parallel
+# process may require the user's attention. The default is iterate over the available
+# terminal types to find one that works.
+#
+# Examples of the occasions this may happen are when resolving patches which cannot
+# be applied, to use the devshell or the kernel menuconfig
+#
+# Supported values are auto, gnome, xfce, rxvt, screen, konsole (KDE 3.x only), none
+# Note: currently, Konsole support only works for KDE 3.x due to the way
+# newer Konsole versions behave
+#OE_TERMINAL = "auto"
+# By default disable interactive patch resolution (tasks will just fail instead):
+PATCHRESOLVE = "noop"
+
+#
+# Disk Space Monitoring during the build
+#
+# Monitor the disk space during the build. If there is less that 1GB of space or less
+# than 100K inodes in any key build location (TMPDIR, DL_DIR, SSTATE_DIR), gracefully
+# shutdown the build. If there is less that 100MB or 1K inodes, perform a hard abort
+# of the build. The reason for this is that running completely out of space can corrupt
+# files and damages the build in ways which may not be easily recoverable.
+# It's necesary to monitor /tmp, if there is no space left the build will fail
+# with very exotic errors.
+BB_DISKMON_DIRS = "\
+ STOPTASKS,${TMPDIR},1G,100K \
+ STOPTASKS,${DL_DIR},1G,100K \
+ STOPTASKS,${SSTATE_DIR},1G,100K \
+ STOPTASKS,/tmp,100M,100K \
+ ABORT,${TMPDIR},100M,1K \
+ ABORT,${DL_DIR},100M,1K \
+ ABORT,${SSTATE_DIR},100M,1K \
+ ABORT,/tmp,10M,1K"
+
+#
+# Shared-state files from other locations
+#
+# As mentioned above, shared state files are prebuilt cache data objects which can
+# used to accelerate build time. This variable can be used to configure the system
+# to search other mirror locations for these objects before it builds the data itself.
+#
+# This can be a filesystem directory, or a remote url such as http or ftp. These
+# would contain the sstate-cache results from previous builds (possibly from other
+# machines). This variable works like fetcher MIRRORS/PREMIRRORS and points to the
+# cache locations to check for the shared objects.
+# NOTE: if the mirror uses the same structure as SSTATE_DIR, you need to add PATH
+# at the end as shown in the examples below. This will be substituted with the
+# correct path within the directory structure.
+#SSTATE_MIRRORS ?= "\
+#file://.* http://someserver.tld/share/sstate/PATH;downloadfilename=PATH \n \
+#file://.* file:///some/local/dir/sstate/PATH"
+
+
+#
+# Qemu configuration
+#
+# By default qemu will build with a builtin VNC server where graphical output can be
+# seen. The two lines below enable the SDL backend too. By default libsdl-native will
+# be built, if you want to use your host's libSDL instead of the minimal libsdl built
+# by libsdl-native then uncomment the ASSUME_PROVIDED line below.
+PACKAGECONFIG_append_pn-qemu-native = " sdl"
+PACKAGECONFIG_append_pn-nativesdk-qemu = " sdl"
+#ASSUME_PROVIDED += "libsdl-native"
+
+# CONF_VERSION is increased each time build/conf/ changes incompatibly and is used to
+# track the version of this file when it was generated. This can safely be ignored if
+# this doesn't mean anything to you.
+CONF_VERSION = "1"
+
+# Add systemd configuration
+DISTRO_FEATURES_append = " systemd"
+VIRTUAL-RUNTIME_init_manager = "systemd"
+
+# Linaro GCC
+GCCVERSION = "linaro-5.2"
+
+# add the static lib to SDK toolchain
+SDKIMAGE_FEATURES_append = " staticdev-pkgs"
+
+# Disable optee in meta-linaro layer
+BBMASK = "meta-linaro/meta-optee/recipes-security/optee"
+
+# Mask graphic Pkgs
+BBMASK .= "|gles-user-module|kernel-module-gles|wayland-kms|libgbm"
+# Mask MMP recipes
+BBMASK .= "|kernel-module-uvcs-drv|omx-user-module"
+
+# Add for gstreamer plugins ugly
+LICENSE_FLAGS_WHITELIST = "commercial"
+
+# Linux ICCOM driver (RCG3ZLIDL4001ZNO)
+# Linux ICCOM library (RCG3ZLILL4001ZNO)
+#DISTRO_FEATURES_append = " iccom"
+
+IMAGE_INSTALL_remove = "optee-linuxdriver optee-linuxdriver-armtz optee-client"
diff --git a/meta-rcar-gen3-adas/docs/sample/patch/0001-meta-linaro-python-wand-fix-BB_NO_NETWORK-build.patch b/meta-rcar-gen3-adas/docs/sample/patch/0001-meta-linaro-python-wand-fix-BB_NO_NETWORK-build.patch
new file mode 100644
index 0000000..9be94b0
--- /dev/null
+++ b/meta-rcar-gen3-adas/docs/sample/patch/0001-meta-linaro-python-wand-fix-BB_NO_NETWORK-build.patch
@@ -0,0 +1,28 @@
+From 749accec83f1b300fc14b5e31fd11c372ca03927 Mon Sep 17 00:00:00 2001
+From: Vladimir Barinov <vladimir.barinov@cogentembedded.com>
+Date: Sun, 17 Sep 2017 00:31:15 +0300
+Subject: [PATCH] meta-linaro: python-wand: fix BB_NO_NETWORK build
+
+This fixes python-wand tag in BSP2.23 to build with BB_NO_NETWORK=1
+
+Signed-off-by: Vladimir Barinov <vladimir.barinov@cogentembedded.com>
+---
+ meta-optee/recipes-devtools/python/python-wand_0.4.3.bb | 2 +-
+ 1 file changed, 1 insertion(+), 1 deletion(-)
+
+diff --git a/meta-optee/recipes-devtools/python/python-wand_0.4.3.bb b/meta-optee/recipes-devtools/python/python-wand_0.4.3.bb
+index cc91892..41a6b8f 100644
+--- a/meta-optee/recipes-devtools/python/python-wand_0.4.3.bb
++++ b/meta-optee/recipes-devtools/python/python-wand_0.4.3.bb
+@@ -6,7 +6,7 @@ LIC_FILES_CHKSUM = "file://LICENSE;md5=170eafd687d4a2b950819cd5e067e6d5"
+
+ SRCNAME = "wand"
+
+-SRC_URI = "git://github.com/dahlia/wand.git;tag=${PV}"
++SRC_URI = "git://github.com/dahlia/wand.git;tag=81b2ce5ac117cd69e4894780925fab12ff0383b9"
+ S = "${WORKDIR}/git"
+
+ inherit setuptools
+--
+1.9.1
+
diff --git a/meta-rcar-gen3-adas/docs/sample/patch/0002-meta-renesas-gstreamer-fix-BB_NO_NETWORK-build.patch b/meta-rcar-gen3-adas/docs/sample/patch/0002-meta-renesas-gstreamer-fix-BB_NO_NETWORK-build.patch
new file mode 100644
index 0000000..3dcb6be
--- /dev/null
+++ b/meta-rcar-gen3-adas/docs/sample/patch/0002-meta-renesas-gstreamer-fix-BB_NO_NETWORK-build.patch
@@ -0,0 +1,92 @@
+From 4babf852ffee2e08e5fd1c1097bd17c235cd78fa Mon Sep 17 00:00:00 2001
+From: Vladimir Barinov <vladimir.barinov@cogentembedded.com>
+Date: Sun, 17 Sep 2017 00:36:21 +0300
+Subject: [PATCH] meta-renesas: gstreamer: fix BB_NO_NETWORK build
+
+Use gitsm for submodule intiializeation. This will enable caching
+submodule gits into downloads.
+Later it is needed for build with BB_NO_NETWORK=1
+
+Signed-off-by: Vladimir Barinov <vladimir.barinov@cogentembedded.com>
+---
+ .../gstreamer/gstreamer1.0-omx_1.2.0.bbappend | 2 +-
+ .../gstreamer/gstreamer1.0-plugins-bad_1.6.3.bbappend | 15 +--------------
+ .../gstreamer/gstreamer1.0-plugins-good_1.6.3.bbappend | 15 +--------------
+ 3 files changed, 3 insertions(+), 29 deletions(-)
+
+diff --git a/meta-rcar-gen3/recipes-multimedia/gstreamer/gstreamer1.0-omx_1.2.0.bbappend b/meta-rcar-gen3/recipes-multimedia/gstreamer/gstreamer1.0-omx_1.2.0.bbappend
+index 9a30dd9..4606392 100644
+--- a/meta-rcar-gen3/recipes-multimedia/gstreamer/gstreamer1.0-omx_1.2.0.bbappend
++++ b/meta-rcar-gen3/recipes-multimedia/gstreamer/gstreamer1.0-omx_1.2.0.bbappend
+@@ -1,5 +1,5 @@
+ SRC_URI_remove = "http://gstreamer.freedesktop.org/src/gst-omx/gst-omx-${PV}.tar.xz"
+-SRC_URI_append = " git://github.com/renesas-rcar/gst-omx.git;branch=RCAR-GEN3/1.2.0"
++SRC_URI_append = " gitsm://github.com/renesas-rcar/gst-omx.git;branch=RCAR-GEN3/1.2.0"
+
+ DEPENDS += "omx-user-module mmngrbuf-user-module"
+
+diff --git a/meta-rcar-gen3/recipes-multimedia/gstreamer/gstreamer1.0-plugins-bad_1.6.3.bbappend b/meta-rcar-gen3/recipes-multimedia/gstreamer/gstreamer1.0-plugins-bad_1.6.3.bbappend
+index 73b5529..b44408c 100644
+--- a/meta-rcar-gen3/recipes-multimedia/gstreamer/gstreamer1.0-plugins-bad_1.6.3.bbappend
++++ b/meta-rcar-gen3/recipes-multimedia/gstreamer/gstreamer1.0-plugins-bad_1.6.3.bbappend
+@@ -1,5 +1,5 @@
+ SRC_URI_remove = "http://gstreamer.freedesktop.org/src/gst-plugins-bad/gst-plugins-bad-${PV}.tar.xz"
+-SRC_URI_append = " git://github.com/renesas-rcar/gst-plugins-bad.git;branch=RCAR-GEN3/1.6.3"
++SRC_URI_append = " gitsm://github.com/renesas-rcar/gst-plugins-bad.git;branch=RCAR-GEN3/1.6.3"
+
+ SRCREV = "e336b2dacf29a155dc8f6896ee0f3a89d87d805e"
+
+@@ -7,19 +7,6 @@ DEPENDS += "weston"
+
+ S = "${WORKDIR}/git"
+
+-# submodule is extracted before do_populate_lic
+-addtask do_init_submodule after do_unpack before do_patch
+-
+-do_init_submodule() {
+- export http_proxy=${http_proxy}
+- export https_proxy=${https_proxy}
+- export HTTP_PROXY=${HTTP_PROXY}
+- export HTTPS_PROXY=${HTTPS_PROXY}
+- cd ${S}
+- git submodule init
+- git submodule update
+-}
+-
+ do_configure_prepend() {
+ cd ${S}
+ ./autogen.sh --noconfigure
+diff --git a/meta-rcar-gen3/recipes-multimedia/gstreamer/gstreamer1.0-plugins-good_1.6.3.bbappend b/meta-rcar-gen3/recipes-multimedia/gstreamer/gstreamer1.0-plugins-good_1.6.3.bbappend
+index 1d353ec..76a3979 100644
+--- a/meta-rcar-gen3/recipes-multimedia/gstreamer/gstreamer1.0-plugins-good_1.6.3.bbappend
++++ b/meta-rcar-gen3/recipes-multimedia/gstreamer/gstreamer1.0-plugins-good_1.6.3.bbappend
+@@ -1,5 +1,5 @@
+ SRC_URI_remove = "http://gstreamer.freedesktop.org/src/gst-plugins-good/gst-plugins-good-${PV}.tar.xz"
+-SRC_URI_append = " git://github.com/renesas-rcar/gst-plugins-good.git;branch=RCAR-GEN3/1.6.3"
++SRC_URI_append = " gitsm://github.com/renesas-rcar/gst-plugins-good.git;branch=RCAR-GEN3/1.6.3"
+
+ SRCREV = "00beed48b36e0b7f2c92199806cc4cb9e0990166"
+
+@@ -12,19 +12,6 @@ EXTRA_OECONF_append = " \
+ --enable-ignore-fps-of-video-standard \
+ "
+
+-# submodule is extracted before do_populate_lic
+-addtask do_init_submodule after do_unpack before do_patch
+-
+-do_init_submodule() {
+- export http_proxy=${http_proxy}
+- export https_proxy=${https_proxy}
+- export HTTP_PROXY=${HTTP_PROXY}
+- export HTTPS_PROXY=${HTTPS_PROXY}
+- cd ${S}
+- git submodule init
+- git submodule update
+-}
+-
+ do_configure_prepend() {
+ cd ${S}
+ ./autogen.sh --noconfigure
+--
+1.9.1
+
diff --git a/meta-rcar-gen3-adas/docs/sample/patch/0003-poky-bitbake-gitsm-fix-BB_NO_NETWORK-build.patch b/meta-rcar-gen3-adas/docs/sample/patch/0003-poky-bitbake-gitsm-fix-BB_NO_NETWORK-build.patch
new file mode 100644
index 0000000..4160351
--- /dev/null
+++ b/meta-rcar-gen3-adas/docs/sample/patch/0003-poky-bitbake-gitsm-fix-BB_NO_NETWORK-build.patch
@@ -0,0 +1,47 @@
+From e0eb46a08a0bdd278800f75c0004e33af2376374 Mon Sep 17 00:00:00 2001
+From: Vladimir Barinov <vladimir.barinov@cogentembedded.com>
+Date: Sun, 17 Sep 2017 00:39:12 +0300
+Subject: [PATCH] poky: bitbake: gitsm: fix BB_NO_NETWORK build
+
+This allows to fetch submodules from download cache.
+
+Signed-off-by: Mikko Rapeli <mikko.rapeli@bmw.de>
+Signed-off-by: Vladimir Barinov <vladimir.barinov@cogentembedded.com>
+---
+ bitbake/lib/bb/fetch2/gitsm.py | 15 +++++++++++++--
+ 1 file changed, 13 insertions(+), 2 deletions(-)
+
+diff --git a/bitbake/lib/bb/fetch2/gitsm.py b/bitbake/lib/bb/fetch2/gitsm.py
+index 752f1d3..cb417a3 100644
+--- a/bitbake/lib/bb/fetch2/gitsm.py
++++ b/bitbake/lib/bb/fetch2/gitsm.py
+@@ -109,7 +109,7 @@ class GitSM(Git):
+ runfetchcmd("sed " + gitdir + "/config -i -e 's/bare.*=.*true/bare = false/'", d)
+ os.chdir(tmpclonedir)
+ runfetchcmd(ud.basecmd + " reset --hard", d)
+- runfetchcmd(ud.basecmd + " checkout " + ud.revisions[ud.names[0]], d)
++ runfetchcmd(ud.basecmd + " checkout -f " + ud.revisions[ud.names[0]], d)
+ runfetchcmd(ud.basecmd + " submodule update --init --recursive", d)
+ self._set_relative_paths(tmpclonedir)
+ runfetchcmd("sed " + gitdir + "/config -i -e 's/bare.*=.*false/bare = true/'", d)
+@@ -130,5 +130,16 @@ class GitSM(Git):
+ os.chdir(ud.destdir)
+ submodules = self.uses_submodules(ud, d)
+ if submodules:
++ # Copy also submodule trees from download cache instead of
++ # downloading again from the upstream repository.
++ # For some reason git does not clone them.
++ clone_modules = os.path.join(ud.clonedir, "modules")
++ if os.path.exists(clone_modules):
++ dest_modules = os.path.join(ud.destdir, ".git")
++ runfetchcmd("cp -a " + clone_modules + " " + dest_modules, d)
++
+ runfetchcmd(ud.basecmd + " checkout " + ud.revisions[ud.names[0]], d)
+- runfetchcmd(ud.basecmd + " submodule update --init --recursive", d)
++ if d.getVar("BB_NO_NETWORK", True) == "1":
++ runfetchcmd(ud.basecmd + " submodule update --no-fetch --init --recursive", d)
++ else:
++ runfetchcmd(ud.basecmd + " submodule update --init --recursive", d)
+--
+1.9.1
+
diff --git a/meta-rcar-gen3-adas/recipes-bsp/arm-trusted-firmware/arm-trusted-firmware_git.bbappend b/meta-rcar-gen3-adas/recipes-bsp/arm-trusted-firmware/arm-trusted-firmware_git.bbappend
new file mode 100644
index 0000000..aefd88a
--- /dev/null
+++ b/meta-rcar-gen3-adas/recipes-bsp/arm-trusted-firmware/arm-trusted-firmware_git.bbappend
@@ -0,0 +1,14 @@
+FILESEXTRAPATHS_prepend := "${THISDIR}/files:"
+
+ATFW_OPT_append = " ${@base_conditional("CA57CA53BOOT", "1", " PSCI_DISABLE_BIGLITTLE_IN_CA57BOOT=0", "", d)}"
+ATFW_OPT_append += " ${@base_conditional("DISABLE_RPC_ACCESS", "1", " RCAR_DISABLE_NONSECURE_RPC_ACCESS=1", "", d)}"
+
+SRC_URI_append = " \
+ file://0001-plat-renesas-rcar-Make-RPC-secure-settings-optional.patch \
+ file://0002-plat-renesas-rcar-kingfisher-reboot-fix-power-off-on-reset.diff \
+"
+
+do_deploy_append() {
+ install -m 0644 ${S}/tools/dummy_create/bootparam_sa0.bin ${DEPLOYDIR}/bootparam_sa0.bin
+ install -m 0644 ${S}/tools/dummy_create/cert_header_sa6.bin ${DEPLOYDIR}/cert_header_sa6.bin
+}
diff --git a/meta-rcar-gen3-adas/recipes-bsp/arm-trusted-firmware/files/0001-plat-renesas-rcar-Make-RPC-secure-settings-optional.patch b/meta-rcar-gen3-adas/recipes-bsp/arm-trusted-firmware/files/0001-plat-renesas-rcar-Make-RPC-secure-settings-optional.patch
new file mode 100644
index 0000000..06a6fe1
--- /dev/null
+++ b/meta-rcar-gen3-adas/recipes-bsp/arm-trusted-firmware/files/0001-plat-renesas-rcar-Make-RPC-secure-settings-optional.patch
@@ -0,0 +1,84 @@
+From 88373fb822f737b60c8c71ca799ec50efaebf5bc Mon Sep 17 00:00:00 2001
+From: Valentine Barshak <valentine.barshak@cogentembedded.com>
+Date: Tue, 4 Jul 2017 21:09:26 +0300
+Subject: [PATCH] plat: renesas: rcar: Make RPC secure settings optional
+
+This adds RCAR_DISABLE_NONSECURE_RPC_ACCESS make variable which
+disables non-secure RPC access when set to a non-zero value.
+
+Signed-off-by: Valentine Barshak <valentine.barshak@cogentembedded.com>
+---
+ plat/renesas/rcar/bl2_secure_setting.c | 4 ++++
+ plat/renesas/rcar/bl31_rcar_setup.c | 16 ++++++++++++++++
+ plat/renesas/rcar/platform.mk | 6 ++++++
+ 3 files changed, 26 insertions(+)
+
+diff --git a/plat/renesas/rcar/bl2_secure_setting.c b/plat/renesas/rcar/bl2_secure_setting.c
+index 3ab651f..40e6a36 100644
+--- a/plat/renesas/rcar/bl2_secure_setting.c
++++ b/plat/renesas/rcar/bl2_secure_setting.c
+@@ -108,7 +108,9 @@ static const struct {
+ /** Security attribute setting for slave ports 13 */
+ /* Bit22: RPC slave ports. */
+ /* 0: registers can be accessed from secure resource only. */
++#if (RCAR_DISABLE_NONSECURE_RPC_ACCESS != 0)
+ {SEC_SEL13, 0xFFBFFFFFU},
++#endif
+
+ /** Security attribute setting for slave ports 14 */
+ /* Bit27: System Timer (SCMT) slave ports. */
+@@ -232,8 +234,10 @@ static const struct {
+ /** Security group 1 attribute setting for slave ports 13 */
+ /* Bit22: RPC slave ports. */
+ /* SecurityGroup3 */
++#if (RCAR_DISABLE_NONSECURE_RPC_ACCESS != 0)
+ {SEC_GRP0COND13, 0x00400000U},
+ {SEC_GRP1COND13, 0x00400000U},
++#endif
+
+ /** Security group 0 attribute setting for slave ports 14 */
+ /** Security group 1 attribute setting for slave ports 14 */
+diff --git a/plat/renesas/rcar/bl31_rcar_setup.c b/plat/renesas/rcar/bl31_rcar_setup.c
+index cc6ad2c..c91297d 100644
+--- a/plat/renesas/rcar/bl31_rcar_setup.c
++++ b/plat/renesas/rcar/bl31_rcar_setup.c
+@@ -232,3 +232,19 @@ int32_t bl31_plat_denied_cpu_off_chk(void)
+ return rc;
+ }
+
++/*******************************************************************************
++ * Perform the runtime platform specific setup here.
++ ******************************************************************************/
++void bl31_plat_runtime_setup(void)
++{
++#if (RCAR_DISABLE_NONSECURE_RPC_ACCESS == 0)
++ /* Enable non-secure access to the RPC HyperFlash region. */
++ mmio_write_32(0xee2000b8, 0x155);
++ mmio_write_32(0xee200000, mmio_read_32(0xee200000) & 0x7fffffff);
++#endif
++ /*
++ * Finish the use of console driver in BL31 so that any runtime logs
++ * from BL31 will be suppressed.
++ */
++ console_uninit();
++}
+diff --git a/plat/renesas/rcar/platform.mk b/plat/renesas/rcar/platform.mk
+index 6abc088..60f41ae 100644
+--- a/plat/renesas/rcar/platform.mk
++++ b/plat/renesas/rcar/platform.mk
+@@ -223,6 +223,12 @@ RCAR_GEN3_ULCB := 0
+ endif
+ $(eval $(call add_define,RCAR_GEN3_ULCB))
+
++# Process RCAR_DISABLE_NONSECURE_RPC_ACCESS flag
++ifndef RCAR_DISABLE_NONSECURE_RPC_ACCESS
++RCAR_DISABLE_NONSECURE_RPC_ACCESS := 0
++endif
++$(eval $(call add_define,RCAR_DISABLE_NONSECURE_RPC_ACCESS))
++
+ include plat/renesas/rcar/ddr/ddr.mk
+ include plat/renesas/rcar/qos/qos.mk
+ include plat/renesas/rcar/pfc/pfc.mk
+--
+2.7.5
+
diff --git a/meta-rcar-gen3-adas/recipes-bsp/arm-trusted-firmware/files/0002-plat-renesas-rcar-kingfisher-reboot-fix-power-off-on-reset.diff b/meta-rcar-gen3-adas/recipes-bsp/arm-trusted-firmware/files/0002-plat-renesas-rcar-kingfisher-reboot-fix-power-off-on-reset.diff
new file mode 100644
index 0000000..144b013
--- /dev/null
+++ b/meta-rcar-gen3-adas/recipes-bsp/arm-trusted-firmware/files/0002-plat-renesas-rcar-kingfisher-reboot-fix-power-off-on-reset.diff
@@ -0,0 +1,37 @@
+From 04ad289ba1e861ab1dd915d7327095173707c236 Mon Sep 17 00:00:00 2001
+From: Sergii Boryshchenko <sergii.boryshchenko@globallogic.com>
+Date: Thu, 30 Nov 2017 14:53:52 +0200
+Subject: [PATCH] kingfisher: reboot: fix power-off on reset
+
+Method cpld_reset_cpu of bl31 is called from the Linux kernel and uses
+GPIO6, GPIO2 pins as SPI bus lines to control the CPLD device. But in the
+kernel GPIO6_8 pin are initialized to work in interrupt mode instead of
+the input/output mode. This leads to the fact that the SPI bus becomes
+non-functional. In this patch we switch the GPIO6_8 pin back to the
+input-output mode.
+
+Signed-off-by: Sergii Boryshchenko <sergii.boryshchenko@globallogic.com>
+---
+
+diff --git a/plat/renesas/rcar/drivers/cpld/ulcb_cpld.c b/plat/renesas/rcar/drivers/cpld/ulcb_cpld.c
+index b0117ef..b171d79 100644
+--- a/plat/renesas/rcar/drivers/cpld/ulcb_cpld.c
++++ b/plat/renesas/rcar/drivers/cpld/ulcb_cpld.c
+@@ -49,6 +49,9 @@
+ #define GPIO_INOUTSEL2 0xE6052004
+ #define GPIO_INOUTSEL6 0xE6055404
+
++/* General IO/Interrupt Switching Register */
++#define GPIO_IOINTSEL6 0xE6055400
++
+ /* GPIO/perihperal function select */
+ #define PFC_GPSR2 0xE6060108
+ #define PFC_GPSR6 0xE6060118
+@@ -115,6 +118,7 @@
+ gpio_pfc(PFC_GPSR2, SSTBZ);
+ gpio_pfc(PFC_GPSR6, MOSI);
+
++ gpio_set_value(GPIO_IOINTSEL6, SCLK, 0);
+ gpio_set_value(GPIO_OUTDT6, SCLK, 0);
+ gpio_set_value(GPIO_OUTDT2, SSTBZ, 1);
+ gpio_set_value(GPIO_OUTDT6, MOSI, 0);
diff --git a/meta-rcar-gen3-adas/recipes-bsp/capture/capture_1.0.bb b/meta-rcar-gen3-adas/recipes-bsp/capture/capture_1.0.bb
new file mode 100644
index 0000000..dbfc8c4
--- /dev/null
+++ b/meta-rcar-gen3-adas/recipes-bsp/capture/capture_1.0.bb
@@ -0,0 +1,39 @@
+SUMMARY = "Camera application test"
+LICENSE = "GPLv2"
+LIC_FILES_CHKSUM = "file://COPYING;md5=9504a7b7666faec5abd046d28a69450e"
+
+S = "${WORKDIR}/capture"
+
+SRC_URI = " \
+ file://capture.tar.gz \
+"
+
+do_compile() {
+ cd ${S}
+ make all || die
+}
+
+do_install() {
+ install -d ${D}${bindir}
+ install -m 755 ${S}/capture ${D}${bindir}
+
+ install -d ${D}/usr/share/tests/
+ install -m 755 ${S}/test_lvds_camera_0.sh ${D}/usr/share/tests/
+ install -m 755 ${S}/test_lvds_camera_4.sh ${D}/usr/share/tests/
+ install -m 755 ${S}/test_lvds_camera_0-3.sh ${D}/usr/share/tests/
+ install -m 755 ${S}/test_lvds_camera_4-7.sh ${D}/usr/share/tests/
+ install -m 755 ${S}/test_lvds_2cameras_on_display1920x1080.sh ${D}/usr/share/tests/
+ install -m 755 ${S}/test_lvds_4cameras_on_display1920x1080.sh ${D}/usr/share/tests/
+ install -m 755 ${S}/test_lvds_8cameras_on_display1920x1080.sh ${D}/usr/share/tests/
+}
+
+FILES_${PN} = " \
+ ${bindir}/capture \
+ /usr/share/tests/test_lvds_camera_0.sh \
+ /usr/share/tests/test_lvds_camera_4.sh \
+ /usr/share/tests/test_lvds_camera_0-3.sh \
+ /usr/share/tests/test_lvds_camera_4-7.sh \
+ /usr/share/tests/test_lvds_2cameras_on_display1920x1080.sh \
+ /usr/share/tests/test_lvds_4cameras_on_display1920x1080.sh \
+ /usr/share/tests/test_lvds_8cameras_on_display1920x1080.sh \
+"
diff --git a/meta-rcar-gen3-adas/recipes-bsp/capture/files/capture.tar.gz b/meta-rcar-gen3-adas/recipes-bsp/capture/files/capture.tar.gz
new file mode 100644
index 0000000..24b9896
--- /dev/null
+++ b/meta-rcar-gen3-adas/recipes-bsp/capture/files/capture.tar.gz
Binary files differ
diff --git a/meta-rcar-gen3-adas/recipes-bsp/iio-utils/files/iio-utils.tar.gz b/meta-rcar-gen3-adas/recipes-bsp/iio-utils/files/iio-utils.tar.gz
new file mode 100644
index 0000000..1282552
--- /dev/null
+++ b/meta-rcar-gen3-adas/recipes-bsp/iio-utils/files/iio-utils.tar.gz
Binary files differ
diff --git a/meta-rcar-gen3-adas/recipes-bsp/iio-utils/iio-utils_%.bb b/meta-rcar-gen3-adas/recipes-bsp/iio-utils/iio-utils_%.bb
new file mode 100644
index 0000000..e84668c
--- /dev/null
+++ b/meta-rcar-gen3-adas/recipes-bsp/iio-utils/iio-utils_%.bb
@@ -0,0 +1,31 @@
+SUMMARY = "IIO Utils"
+LICENSE = "GPLv2"
+LIC_FILES_CHKSUM = "file://COPYING;md5=574295575bba94ba7980d611516fe3d2"
+
+DEPENDS = "virtual/kernel"
+
+export KERNELDIR = "${STAGING_KERNEL_DIR}"
+
+S = "${WORKDIR}/iio-utils"
+
+SRC_URI = " \
+ file://iio-utils.tar.gz \
+"
+
+do_compile() {
+ cd ${S}
+ make all || die
+}
+
+do_install() {
+ install -d ${D}${bindir}
+ install -m 755 ${S}/iio_event_monitor ${D}${bindir}
+ install -m 755 ${S}/lsiio ${D}${bindir}
+ install -m 755 ${S}/iio_generic_buffer ${D}${bindir}
+}
+
+FILES_${PN} = " \
+ ${bindir}/iio_event_monitor \
+ ${bindir}/lsiio \
+ ${bindir}/iio_generic_buffer \
+"
diff --git a/meta-rcar-gen3-adas/recipes-bsp/most-tools/files/most-tools.tar.gz b/meta-rcar-gen3-adas/recipes-bsp/most-tools/files/most-tools.tar.gz
new file mode 100644
index 0000000..f1eaacb
--- /dev/null
+++ b/meta-rcar-gen3-adas/recipes-bsp/most-tools/files/most-tools.tar.gz
Binary files differ
diff --git a/meta-rcar-gen3-adas/recipes-bsp/most-tools/most-tools.bb b/meta-rcar-gen3-adas/recipes-bsp/most-tools/most-tools.bb
new file mode 100644
index 0000000..809db9a
--- /dev/null
+++ b/meta-rcar-gen3-adas/recipes-bsp/most-tools/most-tools.bb
@@ -0,0 +1,22 @@
+SUMMARY = "MOST tools"
+SECTION = "multimedia"
+LICENSE = "CLOSED"
+
+S = "${WORKDIR}/most-tools"
+
+SRC_URI = " \
+ file://most-tools.tar.gz \
+"
+
+do_install() {
+ install -d ${D}/usr/share/most/
+ install -m 755 ${S}/most_setup.sh ${D}/usr/share/most/
+ install -m 755 ${S}/most_play.sh ${D}/usr/share/most/
+ install -m 755 ${S}/setup-audio-50 ${D}/usr/share/most/
+}
+
+FILES_${PN} = " \
+ /usr/share/most/most_setup.sh \
+ /usr/share/most/most_play.sh \
+ /usr/share/most/setup-audio-50 \
+"
diff --git a/meta-rcar-gen3-adas/recipes-bsp/mpssd/files/mpssd.tar.gz b/meta-rcar-gen3-adas/recipes-bsp/mpssd/files/mpssd.tar.gz
new file mode 100644
index 0000000..4439f2a
--- /dev/null
+++ b/meta-rcar-gen3-adas/recipes-bsp/mpssd/files/mpssd.tar.gz
Binary files differ
diff --git a/meta-rcar-gen3-adas/recipes-bsp/mpssd/mpssd_1.0.bb b/meta-rcar-gen3-adas/recipes-bsp/mpssd/mpssd_1.0.bb
new file mode 100644
index 0000000..0d7db01
--- /dev/null
+++ b/meta-rcar-gen3-adas/recipes-bsp/mpssd/mpssd_1.0.bb
@@ -0,0 +1,27 @@
+SUMMARY = "MPSSD"
+LICENSE = "GPLv2"
+LIC_FILES_CHKSUM = "file://COPYING;md5=58dd7e3251f8a7d8c3784355098b8d53"
+
+DEPENDS = "virtual/kernel"
+
+export KERNELDIR = "${STAGING_KERNEL_DIR}"
+
+S = "${WORKDIR}/mpssd"
+
+SRC_URI = " \
+ file://mpssd.tar.gz \
+"
+
+do_compile() {
+ cd ${S}
+ make all || die
+}
+
+do_install() {
+ install -d ${D}${bindir}
+ install -m 755 ${S}/mpssd ${D}${bindir}
+}
+
+FILES_${PN} = " \
+ ${bindir}/mpssd \
+"
diff --git a/meta-rcar-gen3-adas/recipes-bsp/si-tools/files/si-tools.tar.gz b/meta-rcar-gen3-adas/recipes-bsp/si-tools/files/si-tools.tar.gz
new file mode 100644
index 0000000..6115218
--- /dev/null
+++ b/meta-rcar-gen3-adas/recipes-bsp/si-tools/files/si-tools.tar.gz
Binary files differ
diff --git a/meta-rcar-gen3-adas/recipes-bsp/si-tools/si-tools.bb b/meta-rcar-gen3-adas/recipes-bsp/si-tools/si-tools.bb
new file mode 100644
index 0000000..99347e5
--- /dev/null
+++ b/meta-rcar-gen3-adas/recipes-bsp/si-tools/si-tools.bb
@@ -0,0 +1,46 @@
+SUMMARY = "Tools for si46xx AM/FM/DAB radio chip"
+SECTION = "multimedia"
+
+LICENSE = "CLOSED"
+
+PE = "1"
+PV = "0.2"
+
+SRC_URI = " \
+ file://si-tools.tar.gz \
+"
+
+S = "${WORKDIR}/si-tools"
+
+EXTRA_OEMAKE_append = " 'LDFLAGS=${LDFLAGS}'"
+
+do_install() {
+ install -d ${D}${bindir}
+ install -d ${D}/lib/firmware/radio/
+
+ install -m 755 si_ctl ${D}${bindir}
+ install -m 755 si_flash ${D}${bindir}
+ install -m 755 ${S}/scripts/si_init ${D}${bindir}
+ install -m 755 ${S}/scripts/si_firmware_update ${D}${bindir}
+ install -m 755 ${S}/scripts/si_fm ${D}${bindir}
+ install -m 755 ${S}/scripts/si_preset ${D}${bindir}
+ install -m 755 ${S}/scripts/si_scan ${D}${bindir}
+ install -m 644 ${S}/firmware/am.bif ${D}/lib/firmware/radio/
+ install -m 644 ${S}/firmware/fm.bif ${D}/lib/firmware/radio/
+ install -m 644 ${S}/firmware/dab.bif ${D}/lib/firmware/radio/
+ install -m 644 ${S}/firmware/patch.bin ${D}/lib/firmware/radio/
+}
+
+FILES_${PN} = " \
+ ${bindir}/si_ctl \
+ ${bindir}/si_flash \
+ ${bindir}/si_init \
+ ${bindir}/si_firmware_update \
+ ${bindir}/si_fm \
+ ${bindir}/si_preset \
+ ${bindir}/si_scan \
+ /lib/firmware/radio/am.bif \
+ /lib/firmware/radio/fm.bif \
+ /lib/firmware/radio/dab.bif \
+ /lib/firmware/radio/patch.bin \
+"
diff --git a/meta-rcar-gen3-adas/recipes-bsp/spidev-dbg/files/spidev-dbg.tar.gz b/meta-rcar-gen3-adas/recipes-bsp/spidev-dbg/files/spidev-dbg.tar.gz
new file mode 100644
index 0000000..5556478
--- /dev/null
+++ b/meta-rcar-gen3-adas/recipes-bsp/spidev-dbg/files/spidev-dbg.tar.gz
Binary files differ
diff --git a/meta-rcar-gen3-adas/recipes-bsp/spidev-dbg/spidev-dbg_1.0.bb b/meta-rcar-gen3-adas/recipes-bsp/spidev-dbg/spidev-dbg_1.0.bb
new file mode 100644
index 0000000..36aa562
--- /dev/null
+++ b/meta-rcar-gen3-adas/recipes-bsp/spidev-dbg/spidev-dbg_1.0.bb
@@ -0,0 +1,21 @@
+SUMMARY = "SPI device debug utility"
+LICENSE = "GPLv2"
+LIC_FILES_CHKSUM = "file://COPYING;md5=26cdfe4d6a85afebc7ccd5623f195fa2"
+
+S = "${WORKDIR}/spidev-dbg"
+
+SRC_URI = " \
+ file://spidev-dbg.tar.gz \
+"
+
+do_compile() {
+ cd ${S}
+ make all || die
+}
+
+do_install() {
+ install -d ${D}${bindir}
+ install -m 755 ${S}/spidev-dbg ${D}${bindir}
+}
+
+FILES_${PN} = "${bindir}/spidev-dbg"
diff --git a/meta-rcar-gen3-adas/recipes-bsp/ti-bt-firmware/ti-bt-firmware_git.bb b/meta-rcar-gen3-adas/recipes-bsp/ti-bt-firmware/ti-bt-firmware_git.bb
new file mode 100644
index 0000000..3251662
--- /dev/null
+++ b/meta-rcar-gen3-adas/recipes-bsp/ti-bt-firmware/ti-bt-firmware_git.bb
@@ -0,0 +1,25 @@
+SUMMARY = "Bluetooth firmare files for WL18xx combo modules"
+SECTION = "misc"
+
+LICENSE = "CLOSED"
+
+PE = "1"
+PV = "0.0"
+
+SRC_URI = "git://github.com/TI-ECS/bt-firmware.git;protocol=git "
+SRCREV = "169b2df5b968f0ede32ea9044859942fc220c435"
+
+S = "${WORKDIR}/git"
+
+CLEANBROKEN = "1"
+
+do_populate_lic[noexec] = "1"
+do_compile[noexec] = "1"
+do_configure[noexec] = "1"
+
+do_install() {
+ install -d ${D}/lib/firmware/ti-connectivity/
+ cp *.bts ${D}/lib/firmware/ti-connectivity/
+}
+
+FILES_${PN} = "/lib/firmware/ti-connectivity/*" \ No newline at end of file
diff --git a/meta-rcar-gen3-adas/recipes-bsp/ti-bt/files/0001-Improve-debug-output.patch b/meta-rcar-gen3-adas/recipes-bsp/ti-bt/files/0001-Improve-debug-output.patch
new file mode 100644
index 0000000..85c7407
--- /dev/null
+++ b/meta-rcar-gen3-adas/recipes-bsp/ti-bt/files/0001-Improve-debug-output.patch
@@ -0,0 +1,125 @@
+From 3dd59ce6ef2bb0470e325be1fc5fb79b50842e31 Mon Sep 17 00:00:00 2001
+From: Andrey Gusakov <andrey.gusakov@cogentembedded.com>
+Date: Tue, 13 Dec 2016 19:21:00 +0300
+Subject: [PATCH] Improve debug output
+
+Signed-off-by: Andrey Gusakov <andrey.gusakov@cogentembedded.com>
+---
+ uim.c | 51 +++++++++++++++++++++++++++++----------------------
+ 1 file changed, 29 insertions(+), 22 deletions(-)
+
+diff --git a/uim.c b/uim.c
+index 89bafd8..9a58eab 100644
+--- a/uim.c
++++ b/uim.c
+@@ -86,9 +86,10 @@ int read_hci_event(int fd, unsigned char *buf, int size)
+
+ UIM_START_FUNC();
+
+- UIM_VER(" read_hci_event");
+- if (size <= 0)
+- return -1;
++ if (size <= 0) {
++ UIM_VER(" invalid size: %d", size);
++ return -EINVAL;
++ }
+
+ /* The first byte identifies the packet type. For HCI event packets, it
+ * should be 0x04, so we read until we get to the 0x04. */
+@@ -98,7 +99,8 @@ int read_hci_event(int fd, unsigned char *buf, int size)
+ nanosleep(&tm, NULL);
+ continue;
+ } else if (rd_retry_count >= 4) {
+- return -1;
++ UIM_VER(" no retry left. nothing readed");
++ return -EBUSY;
+ }
+
+ if (buf[0] == RESP_PREFIX) {
+@@ -110,8 +112,10 @@ int read_hci_event(int fd, unsigned char *buf, int size)
+ /* The next two bytes are the event code and parameter total length. */
+ while (count < 3) {
+ rd = read(fd, buf + count, 3 - count);
+- if (rd <= 0)
+- return -1;
++ if (rd <= 0) {
++ UIM_VER(" read failed: %d", rd);
++ return -EINVAL;
++ }
+ count += rd;
+ }
+
+@@ -123,8 +127,10 @@ int read_hci_event(int fd, unsigned char *buf, int size)
+
+ while ((count - 3) < remain) {
+ rd = read(fd, buf + count, remain - (count - 3));
+- if (rd <= 0)
+- return -1;
++ if (rd <= 0) {
++ UIM_VER(" failed to read buffer tail: %d", rd);
++ return -EINVAL;
++ }
+ count += rd;
+ }
+
+@@ -139,42 +145,43 @@ int read_hci_event(int fd, unsigned char *buf, int size)
+ */
+ static int read_command_complete(int fd, unsigned short opcode)
+ {
++ int ret = 0;
+ command_complete_t resp;
+
+ UIM_START_FUNC();
+
+- UIM_VER(" Command complete started");
+- if (read_hci_event(fd, (unsigned char *)&resp, sizeof(resp)) < 0) {
+- UIM_ERR("Invalid response");
+- return -1;
++ ret = read_hci_event(fd, (unsigned char *)&resp, sizeof(resp));
++ if (ret < 0) {
++ UIM_ERR("Failed to read response: %d", ret);
++ return ret;
+ }
+
+ /* Response should be an event packet */
+ if (resp.uart_prefix != HCI_EVENT_PKT) {
+- UIM_ERR ("Error in response: not an event packet, 0x%02x!",
+- resp.uart_prefix);
+- return -1;
++ UIM_ERR ("Error in response: not an event packet, 0x%02x != 0x%02x!",
++ resp.uart_prefix, HCI_EVENT_PKT);
++ return -EINVAL;
+ }
+
+ /* Response should be a command complete event */
+ if (resp.hci_hdr.evt != EVT_CMD_COMPLETE) {
+ /* event must be event-complete */
+- UIM_ERR("Error in response: not a cmd-complete event,0x%02x!",
+- resp.hci_hdr.evt);
+- return -1;
++ UIM_ERR("Error in response: not a cmd-complete event,0x%02x != 0x%02x!",
++ resp.hci_hdr.evt, EVT_CMD_COMPLETE);
++ return -EINVAL;
+ }
+
+ if (resp.hci_hdr.plen < 4) {
+ /* plen >= 4 for EVT_CMD_COMPLETE */
+- UIM_ERR("Error in response: plen is not >= 4, but 0x%02x!",
++ UIM_ERR("Error in response: length < 4, but 0x%02x!",
+ resp.hci_hdr.plen);
+- return -1;
++ return -EINVAL;
+ }
+
+ if (resp.cmd_complete.opcode != (unsigned short)opcode) {
+- UIM_ERR("Error in response: opcode is 0x%04x, not 0x%04x!",
++ UIM_ERR("Error in response: opcode is 0x%04x != 0x%04x!",
+ resp.cmd_complete.opcode, opcode);
+- return -1;
++ return -EINVAL;
+ }
+
+ UIM_DBG("Command complete done");
+--
+1.8.3.1
+
diff --git a/meta-rcar-gen3-adas/recipes-bsp/ti-bt/files/0001-fix-poll-restart-after-fail.patch b/meta-rcar-gen3-adas/recipes-bsp/ti-bt/files/0001-fix-poll-restart-after-fail.patch
new file mode 100644
index 0000000..3eeddec
--- /dev/null
+++ b/meta-rcar-gen3-adas/recipes-bsp/ti-bt/files/0001-fix-poll-restart-after-fail.patch
@@ -0,0 +1,52 @@
+From c4b8eca95c37d728c39c57811d975c50900605fd Mon Sep 17 00:00:00 2001
+From: Andrey Gusakov <andrey.gusakov@cogentembedded.com>
+Date: Tue, 31 May 2016 19:50:27 +0300
+Subject: [PATCH] fix poll restart after fail
+
+also add some delay before starting speaking with BT
+
+Signed-off-by: Andrey Gusakov <andrey.gusakov@cogentembedded.com>
+---
+ uim.c | 5 ++++-
+ 1 file changed, 4 insertions(+), 1 deletion(-)
+
+diff --git a/uim.c b/uim.c
+index 6bde5ca..89bafd8 100644
+--- a/uim.c
++++ b/uim.c
+@@ -286,6 +286,8 @@ int st_uart_config(unsigned char install)
+
+ UIM_START_FUNC();
+
++ usleep(100 * 1000);
++
+ if (install == '1') {
+ memset(buf, 0, UART_DEV_NAME_LEN);
+ fd = open(DEV_NAME_SYSFS, O_RDONLY);
+@@ -375,6 +377,7 @@ int st_uart_config(unsigned char install)
+
+ /* Read the response for the Change speed command */
+ if (read_command_complete(dev_fd, HCI_HDR_OPCODE) < 0) {
++ tcflush(dev_fd, TCIOFLUSH);
+ close(dev_fd);
+ return -1;
+ }
+@@ -534,7 +537,6 @@ int main(int argc, char *argv[])
+ return -1;
+ }
+
+-RE_POLL:
+ /* read to start proper poll */
+ err = read(st_fd, &install, 1);
+ /* special case where bluetoothd starts before the UIM, and UIM
+@@ -547,6 +549,7 @@ RE_POLL:
+
+ UIM_DBG("begin polling...");
+
++RE_POLL:
+ memset(&p, 0, sizeof(p));
+ p.fd = st_fd;
+ p.events = POLLERR | POLLPRI;
+--
+1.7.10.4
+
diff --git a/meta-rcar-gen3-adas/recipes-bsp/ti-bt/files/0002-Fix-possible-cross-compile-issue.patch b/meta-rcar-gen3-adas/recipes-bsp/ti-bt/files/0002-Fix-possible-cross-compile-issue.patch
new file mode 100644
index 0000000..e305dcd
--- /dev/null
+++ b/meta-rcar-gen3-adas/recipes-bsp/ti-bt/files/0002-Fix-possible-cross-compile-issue.patch
@@ -0,0 +1,29 @@
+From 961301d5f9c8369f96b26d9255d249c8c26a8903 Mon Sep 17 00:00:00 2001
+From: Andrey Gusakov <andrey.gusakov@cogentembedded.com>
+Date: Fri, 26 May 2017 13:07:10 +0300
+Subject: [PATCH] Fix possible cross-compile issue
+
+Signed-off-by: Andrey Gusakov <andrey.gusakov@cogentembedded.com>
+---
+ uim.c | 4 +++-
+ 1 file changed, 3 insertions(+), 1 deletion(-)
+
+diff --git a/uim.c b/uim.c
+index 197bfd4..61a89a5 100644
+--- a/uim.c
++++ b/uim.c
+@@ -367,8 +367,10 @@ int st_uart_config(unsigned char install)
+ UIM_VER("Setting speed to %ld", cust_baud_rate);
+ /* Forming the packet for Change speed command */
+ cmd.uart_prefix = HCI_COMMAND_PKT;
++ /* FIXME: endian */
+ cmd.hci_hdr.opcode = HCI_HDR_OPCODE;
+- cmd.hci_hdr.plen = sizeof(unsigned long);
++ cmd.hci_hdr.plen = sizeof(uint32_t);
++ /* FIXME: endian */
+ cmd.speed = cust_baud_rate;
+
+ /* Writing the change speed command to the UART
+--
+2.13.0
+
diff --git a/meta-rcar-gen3-adas/recipes-bsp/ti-bt/files/uim-sysfs b/meta-rcar-gen3-adas/recipes-bsp/ti-bt/files/uim-sysfs
new file mode 100644
index 0000000..93c2cac
--- /dev/null
+++ b/meta-rcar-gen3-adas/recipes-bsp/ti-bt/files/uim-sysfs
@@ -0,0 +1,36 @@
+#! /bin/sh
+
+uim="/usr/bin/uim"
+test -x "$uim" || exit 0
+
+case "$1" in
+ start)
+ echo -n "Starting uim-sysfs daemon"
+ modprobe st_drv
+ NODE=`cd /sys; find . | grep kim | grep install`
+ if [ $NODE ]
+ then
+ echo UIM SYSFS Node Found at /sys/$NODE
+ else
+ echo UIM SYSFS Node Not Found
+ rmmod st_drv
+ exit 0
+ fi
+ uim_args="-f `dirname /sys/$NODE`"
+ start-stop-daemon --start --quiet --pidfile /var/run/uim.pid --make-pidfile --exec $uim -- $uim_args &
+ modprobe btwilink
+ echo "."
+ ;;
+ stop)
+ echo -n "Stopping uim-sysfs daemon"
+ start-stop-daemon --stop --quiet --pidfile /var/run/uim.pid
+ rmmod btwilink
+ rmmod st_drv
+ echo "."
+ ;;
+ *)
+ echo "Usage: /etc/init.d/uim-sysfs {start|stop}"
+ exit 1
+esac
+
+exit 0
diff --git a/meta-rcar-gen3-adas/recipes-bsp/ti-bt/ti-bt_git.bb b/meta-rcar-gen3-adas/recipes-bsp/ti-bt/ti-bt_git.bb
new file mode 100644
index 0000000..6986e2e
--- /dev/null
+++ b/meta-rcar-gen3-adas/recipes-bsp/ti-bt/ti-bt_git.bb
@@ -0,0 +1,35 @@
+SUMMARY = "UIM tool for WL18xx module"
+SECTION = "misc"
+
+LICENSE = "GPLv2"
+LIC_FILES_CHKSUM = "file://uim.c;beginline=3;endline=16;md5=ee2f4f9fa92404f383fc3e6315b9dda3"
+
+inherit update-rc.d
+INITSCRIPT_NAME="uim-sysfs"
+INITSCRIPT_PARAMS = "start 20 2 3 4 5 ."
+
+PR = "0+gitr${SRCPV}"
+PV = "0.1"
+
+SRC_URI = "git://git.ti.com/ti-bt/uim.git;protocol=git \
+ file://0001-fix-poll-restart-after-fail.patch \
+ file://0001-Improve-debug-output.patch \
+ file://0002-Fix-possible-cross-compile-issue.patch \
+ file://uim-sysfs"
+SRCREV = "a75f45be2d5c74fc1dd913d08afc30f09a230aa9"
+
+S = "${WORKDIR}/git"
+
+do_install() {
+ install -d ${D}${bindir}
+ install -d ${D}${sysconfdir}/init.d
+
+ install -m 0755 uim ${D}${bindir}/
+ install -m 0755 ${WORKDIR}/uim-sysfs ${D}${sysconfdir}/init.d
+
+ # Blacklist st_drv and btwilink to prevent modules autoload
+ # /etc/init.d/uim-sysfs will do the work with the proper parameters
+ install -d ${D}/${sysconfdir}/modprobe.d
+ echo "blacklist st_drv" > ${D}/${sysconfdir}/modprobe.d/ti_bt.conf
+ echo "blacklist btwilink" >> ${D}/${sysconfdir}/modprobe.d/ti_bt.conf
+} \ No newline at end of file
diff --git a/meta-rcar-gen3-adas/recipes-bsp/u-boot/u-boot/0001-net-phy-support-fixed-PHY.patch b/meta-rcar-gen3-adas/recipes-bsp/u-boot/u-boot/0001-net-phy-support-fixed-PHY.patch
new file mode 100644
index 0000000..e745be7
--- /dev/null
+++ b/meta-rcar-gen3-adas/recipes-bsp/u-boot/u-boot/0001-net-phy-support-fixed-PHY.patch
@@ -0,0 +1,115 @@
+From 1f65b4710c1f51d01032db201543d0a8269a715f Mon Sep 17 00:00:00 2001
+From: Vladimir Barinov <vladimir.barinov@cogentembedded.com>
+Date: Fri, 20 May 2016 01:18:44 +0300
+Subject: [PATCH] uboot: net: support fixed-PHY
+
+Add support for fixed-PHY
+
+Signed-off-by: Vladimir Barinov <vladimir.barinov@cogentembedded.com>
+---
+ drivers/net/phy/Makefile | 1 +
+ drivers/net/phy/fixed.c | 43 +++++++++++++++++++++++++++++++++++++++++++
+ drivers/net/phy/phy.c | 5 ++++-
+ include/phy.h | 1 +
+ 6 files changed, 57 insertions(+), 1 deletion(-)
+ create mode 100644 drivers/net/phy/fixed.c
+
+diff --git a/drivers/net/phy/Makefile b/drivers/net/phy/Makefile
+index d096db8..497785e 100644
+--- a/drivers/net/phy/Makefile
++++ b/drivers/net/phy/Makefile
+@@ -17,6 +17,7 @@ obj-$(CONFIG_PHY_BROADCOM) += broadcom.o
+ obj-$(CONFIG_PHY_CORTINA) += cortina.o
+ obj-$(CONFIG_PHY_DAVICOM) += davicom.o
+ obj-$(CONFIG_PHY_ET1011C) += et1011c.o
++obj-$(CONFIG_PHY_FIXED) += fixed.o
+ obj-$(CONFIG_PHY_LXT) += lxt.o
+ obj-$(CONFIG_PHY_MARVELL) += marvell.o
+ obj-$(CONFIG_PHY_MICREL) += micrel.o
+diff --git a/drivers/net/phy/fixed.c b/drivers/net/phy/fixed.c
+new file mode 100644
+index 0000000..4d44aad
+--- /dev/null
++++ b/drivers/net/phy/fixed.c
+@@ -0,0 +1,43 @@
++/*
++ * Fixed PHY driver
++ *
++ * Copyright (C) 2016 Renesas Electronics Corporation
++ * Copyright (C) 2016 Cogent Embedded, Inc.
++ *
++ * SPDX-License-Identifier: GPL-2.0+
++ */
++
++#include <config.h>
++#include <common.h>
++#include <phy.h>
++
++int fixed_config(struct phy_device *phydev)
++{
++ phydev->speed = CONFIG_PHY_FIXED_SPEED;
++ phydev->duplex = CONFIG_PHY_FIXED_DUPLEX;
++ phydev->link = 1;
++
++ return 0;
++}
++
++static int fixed_startup(struct phy_device *phydev)
++{
++ return 0;
++}
++
++static struct phy_driver fixed_driver = {
++ .uid = 0x0,
++ .mask = 0x0,
++ .name = "fixed-PHY",
++ .features = PHY_10G_FEATURES,
++ .config = &fixed_config,
++ .startup = &fixed_startup,
++ .shutdown = &genphy_shutdown,
++};
++
++int phy_fixed_init(void)
++{
++ phy_register(&fixed_driver);
++
++ return 0;
++}
+diff --git a/drivers/net/phy/phy.c b/drivers/net/phy/phy.c
+index df7e945..3ee6402 100644
+--- a/drivers/net/phy/phy.c
++++ b/drivers/net/phy/phy.c
+@@ -484,6 +484,9 @@ int phy_init(void)
+ #ifdef CONFIG_PHY_VITESSE
+ phy_vitesse_init();
+ #endif
++#ifdef CONFIG_PHY_FIXED
++ phy_fixed_init();
++#endif
+
+ return 0;
+ }
+@@ -764,7 +767,7 @@ void phy_connect_dev(struct phy_device *phydev, struct eth_device *dev)
+ phydev->dev->name, dev->name);
+ }
+ phydev->dev = dev;
+- debug("%s connected to %s\n", dev->name, phydev->drv->name);
++ printf("%s connected to %s\n", dev->name, phydev->drv->name);
+ }
+
+ struct phy_device *phy_connect(struct mii_dev *bus, int addr,
+diff --git a/include/phy.h b/include/phy.h
+index d117fc1..c2f2cbc 100644
+--- a/include/phy.h
++++ b/include/phy.h
+@@ -239,6 +239,7 @@ int phy_realtek_init(void);
+ int phy_smsc_init(void);
+ int phy_teranetics_init(void);
+ int phy_vitesse_init(void);
++int phy_fixed_init(void);
+
+ int board_phy_config(struct phy_device *phydev);
+
+--
+1.9.1
+
diff --git a/meta-rcar-gen3-adas/recipes-bsp/u-boot/u-boot/0002-net-ravb-remove-APSR-quirk.patch b/meta-rcar-gen3-adas/recipes-bsp/u-boot/u-boot/0002-net-ravb-remove-APSR-quirk.patch
new file mode 100644
index 0000000..60c9e14
--- /dev/null
+++ b/meta-rcar-gen3-adas/recipes-bsp/u-boot/u-boot/0002-net-ravb-remove-APSR-quirk.patch
@@ -0,0 +1,33 @@
+From 1247dea7b49d7e66e1848da71e28ff5fe9acf5e1 Mon Sep 17 00:00:00 2001
+From: Vladimir Barinov <vladimir.barinov@cogentembedded.com>
+Date: Thu, 16 Jun 2016 11:41:43 +0300
+Subject: [PATCH] uboot: ravb: remove APSR quirk
+
+Remove 2ns delay interoduces by DMAC APSR. This is
+not used in linux kernel, hence it is important to skips this
+in uboot.
+
+Signed-off-by: Vladimir Barinov <vladimir.barinov@cogentembedded.com>
+---
+ drivers/net/ravb.c | 5 -----
+ 1 files changed, 0 insertions(+), 5 deletions(-)
+
+diff --git a/drivers/net/ravb.c b/drivers/net/ravb.c
+index c168381..f4d7aed 100644
+--- a/drivers/net/ravb.c
++++ b/drivers/net/ravb.c
+@@ -428,11 +428,6 @@ static int ravb_dmac_init(struct ravb_dev *eth)
+ /* FIFO size set */
+ ravb_write(eth, 0x00222210, TGC);
+
+- if (CONFIG_RAVB_PHY_MODE == PHY_INTERFACE_MODE_RGMII_ID) {
+- /* delay CLK: 2ns */
+- ravb_write(eth, 0x1ul << 14, APSR);
+- }
+-
+ return ret;
+ }
+
+--
+1.9.1
+
diff --git a/meta-rcar-gen3-adas/recipes-bsp/u-boot/u-boot/0003-net-ravb-fix-unsafe-phy-access.patch b/meta-rcar-gen3-adas/recipes-bsp/u-boot/u-boot/0003-net-ravb-fix-unsafe-phy-access.patch
new file mode 100644
index 0000000..584d6d5
--- /dev/null
+++ b/meta-rcar-gen3-adas/recipes-bsp/u-boot/u-boot/0003-net-ravb-fix-unsafe-phy-access.patch
@@ -0,0 +1,30 @@
+From 63534a79e2fb1e4102fe38f339ecb891682a781e Mon Sep 17 00:00:00 2001
+From: Vladimir Barinov <vladimir.barinov@cogentembedded.com>
+Date: Fri, 23 Sep 2016 18:26:53 +0300
+Subject: [PATCH] net: ravb: fix unsafe phy access
+
+This fixes the ravb driver crash for phy/phyless glue
+that do not have writeext field
+
+Signed-off-by: Vladimir Barinov <vladimir.barinov@cogentembedded.com>
+---
+ drivers/net/ravb.c | 3 ++-
+ 1 file changed, 2 insertions(+), 1 deletion(-)
+
+diff --git a/drivers/net/ravb.c b/drivers/net/ravb.c
+index f4d7aed..5d90a3e 100644
+--- a/drivers/net/ravb.c
++++ b/drivers/net/ravb.c
+@@ -475,7 +475,8 @@ static int ravb_config(struct ravb_dev *eth, bd_t *bd)
+ ravb_write(eth, ECMR_CHG_DM | ECMR_RE | ECMR_TE, ECMR);
+ }
+
+- phy->drv->writeext(phy, -1, 0x02, 0x08, (0x0f<<5) | 0x19);
++ if (phy->drv->writeext)
++ phy->drv->writeext(phy, -1, 0x02, 0x08, (0x0f<<5) | 0x19);
+
+ err_phy_cfg:
+ return ret;
+--
+1.9.1
+
diff --git a/meta-rcar-gen3-adas/recipes-bsp/u-boot/u-boot/0004-configs-rcar-gen3-add-CMD_GPIO.patch b/meta-rcar-gen3-adas/recipes-bsp/u-boot/u-boot/0004-configs-rcar-gen3-add-CMD_GPIO.patch
new file mode 100644
index 0000000..f95994f
--- /dev/null
+++ b/meta-rcar-gen3-adas/recipes-bsp/u-boot/u-boot/0004-configs-rcar-gen3-add-CMD_GPIO.patch
@@ -0,0 +1,27 @@
+From 3e733c036e8f50cf073b598074ce9fd6796ec89f Mon Sep 17 00:00:00 2001
+From: Vladimir Barinov <vladimir.barinov@cogentembedded.com>
+Date: Sun, 31 Jul 2016 03:59:13 +0300
+Subject: [PATCH] configs: rcar-gen3: add CMD_GPIO
+
+Enable CONFIG_CMD_GPIO
+
+Signed-off-by: Vladimir Barinov <vladimir.barinov@cogentembedded.com>
+---
+ include/configs/rcar-gen3-common.h | 1 +
+ 1 file changed, 1 insertion(+)
+
+diff --git a/include/configs/rcar-gen3-common.h b/include/configs/rcar-gen3-common.h
+index 63b80a4..50cfa8a 100644
+--- a/include/configs/rcar-gen3-common.h
++++ b/include/configs/rcar-gen3-common.h
+@@ -31,6 +31,7 @@
+ #define CONFIG_CMD_EXT2
+ #define CONFIG_CMD_EXT4
+ #define CONFIG_CMD_EXT4_WRITE
++#define CONFIG_CMD_GPIO
+
+ #define CONFIG_SYS_THUMB_BUILD
+ #define CONFIG_SYS_GENERIC_BOARD
+--
+1.9.1
+
diff --git a/meta-rcar-gen3-adas/recipes-bsp/u-boot/u-boot/0005-common-cmd_source.c-Fix-the-source-command-failure-u.patch b/meta-rcar-gen3-adas/recipes-bsp/u-boot/u-boot/0005-common-cmd_source.c-Fix-the-source-command-failure-u.patch
new file mode 100644
index 0000000..81a205f
--- /dev/null
+++ b/meta-rcar-gen3-adas/recipes-bsp/u-boot/u-boot/0005-common-cmd_source.c-Fix-the-source-command-failure-u.patch
@@ -0,0 +1,53 @@
+From 5b189130c95630cf68c50255fb0d1ed0515cb92a Mon Sep 17 00:00:00 2001
+From: Gong Qianyu <Qianyu.Gong@freescale.com>
+Date: Thu, 30 Jul 2015 14:00:01 +0800
+Subject: [PATCH] common/cmd_source.c: Fix the source command failure
+ under 64-bit platform
+
+Modify the data pointer type from ulong* to u32*.
+
+For arm64 type "ulong" could be 64-bit. Then in line 88 of common/cmd_source.c:
+"while (*data++);" data will point to the next 64 bits each time. As the uImage
+file generated by mkimage tool keeps the same data format in either 32-bit or 64-bit
+platform, the difference would cause failure in 64-bit platform.
+
+Signed-off-by: Gong Qianyu <Qianyu.Gong@freescale.com>
+Signed-off-by: Valentine Barshak <valentine.barshak@cogentembedded.com>
+---
+ common/cmd_source.c | 6 +++---
+ 1 file changed, 3 insertions(+), 3 deletions(-)
+
+diff --git a/common/cmd_source.c b/common/cmd_source.c
+index 6881bc9..291e5f4 100644
+--- a/common/cmd_source.c
++++ b/common/cmd_source.c
+@@ -32,7 +32,7 @@ source (ulong addr, const char *fit_uname)
+ #if defined(CONFIG_IMAGE_FORMAT_LEGACY)
+ const image_header_t *hdr;
+ #endif
+- ulong *data;
++ u32 *data;
+ int verify;
+ void *buf;
+ #if defined(CONFIG_FIT)
+@@ -73,7 +73,7 @@ source (ulong addr, const char *fit_uname)
+ }
+
+ /* get length of script */
+- data = (ulong *)image_get_data (hdr);
++ data = (u32 *)image_get_data (hdr);
+
+ if ((len = uimage_to_cpu (*data)) == 0) {
+ puts ("Empty Script\n");
+@@ -127,7 +127,7 @@ source (ulong addr, const char *fit_uname)
+ return 1;
+ }
+
+- data = (ulong *)fit_data;
++ data = (u32 *)fit_data;
+ len = (ulong)fit_len;
+ break;
+ #endif
+--
+1.9.3
+
diff --git a/meta-rcar-gen3-adas/recipes-bsp/u-boot/u-boot/0006-configs-rcar-gen3-common-Enable-U-Boot-scripts.patch b/meta-rcar-gen3-adas/recipes-bsp/u-boot/u-boot/0006-configs-rcar-gen3-common-Enable-U-Boot-scripts.patch
new file mode 100644
index 0000000..aa92851
--- /dev/null
+++ b/meta-rcar-gen3-adas/recipes-bsp/u-boot/u-boot/0006-configs-rcar-gen3-common-Enable-U-Boot-scripts.patch
@@ -0,0 +1,30 @@
+From 3defaae29edd09e89ea0d05082a7a8d5d2cb48d0 Mon Sep 17 00:00:00 2001
+From: Valentine Barshak <valentine.barshak@cogentembedded.com>
+Date: Sat, 10 Sep 2016 04:26:24 +0300
+Subject: [PATCH] configs: rcar-gen3-common: Enable U-Boot scripts
+
+This enables "source" command, which can be used
+for running U-Boot scripts in order to simplify
+flashing procedure.
+
+Signed-off-by: Valentine Barshak <valentine.barshak@cogentembedded.com>
+---
+ include/configs/rcar-gen3-common.h | 2 ++
+ 1 file changed, 2 insertions(+)
+
+diff --git a/include/configs/rcar-gen3-common.h b/include/configs/rcar-gen3-common.h
+index 50cfa8a..bab2c2c 100644
+--- a/include/configs/rcar-gen3-common.h
++++ b/include/configs/rcar-gen3-common.h
+@@ -33,6 +33,8 @@
+ #define CONFIG_CMD_EXT4_WRITE
+ #define CONFIG_CMD_GPIO
+
++#define CONFIG_CMD_SOURCE
++
+ #define CONFIG_SYS_THUMB_BUILD
+ #define CONFIG_SYS_GENERIC_BOARD
+
+--
+1.9.3
+
diff --git a/meta-rcar-gen3-adas/recipes-bsp/u-boot/u-boot/0007-configs-rcar-gen3-common-Enable-echo-command.patch b/meta-rcar-gen3-adas/recipes-bsp/u-boot/u-boot/0007-configs-rcar-gen3-common-Enable-echo-command.patch
new file mode 100644
index 0000000..fe5ab67
--- /dev/null
+++ b/meta-rcar-gen3-adas/recipes-bsp/u-boot/u-boot/0007-configs-rcar-gen3-common-Enable-echo-command.patch
@@ -0,0 +1,28 @@
+From bb2193f5970ca989910df135010f39d0931c79fb Mon Sep 17 00:00:00 2001
+From: Valentine Barshak <valentine.barshak@cogentembedded.com>
+Date: Sat, 10 Sep 2016 05:20:07 +0300
+Subject: [PATCH] configs: rcar-gen3-common: Enable echo command
+
+This enables "echo" command, which can be used
+to make U-Boot scripts more verbose.
+
+Signed-off-by: Valentine Barshak <valentine.barshak@cogentembedded.com>
+---
+ include/configs/rcar-gen3-common.h | 1 +
+ 1 file changed, 1 insertion(+)
+
+diff --git a/include/configs/rcar-gen3-common.h b/include/configs/rcar-gen3-common.h
+index bab2c2c..7b75562 100644
+--- a/include/configs/rcar-gen3-common.h
++++ b/include/configs/rcar-gen3-common.h
+@@ -34,6 +34,7 @@
+ #define CONFIG_CMD_GPIO
+
+ #define CONFIG_CMD_SOURCE
++#define CONFIG_CMD_ECHO
+
+ #define CONFIG_SYS_THUMB_BUILD
+ #define CONFIG_SYS_GENERIC_BOARD
+--
+1.9.3
+
diff --git a/meta-rcar-gen3-adas/recipes-bsp/u-boot/u-boot/0008-configs-rcar-gen3-common-Enable-setexpr-command.patch b/meta-rcar-gen3-adas/recipes-bsp/u-boot/u-boot/0008-configs-rcar-gen3-common-Enable-setexpr-command.patch
new file mode 100644
index 0000000..34e0942
--- /dev/null
+++ b/meta-rcar-gen3-adas/recipes-bsp/u-boot/u-boot/0008-configs-rcar-gen3-common-Enable-setexpr-command.patch
@@ -0,0 +1,28 @@
+From d26edbbf50868a39e840c5f775a9e48f063ec638 Mon Sep 17 00:00:00 2001
+From: Valentine Barshak <valentine.barshak@cogentembedded.com>
+Date: Tue, 20 Sep 2016 23:20:15 +0300
+Subject: [PATCH] configs: rcar-gen3-common: Enable setexpr command
+
+This enables "setexpr" command, which can be used
+to evaluate expressions.
+
+Signed-off-by: Valentine Barshak <valentine.barshak@cogentembedded.com>
+---
+ include/configs/rcar-gen3-common.h | 1 +
+ 1 file changed, 1 insertion(+)
+
+diff --git a/include/configs/rcar-gen3-common.h b/include/configs/rcar-gen3-common.h
+index 7b75562..aaeaf57 100644
+--- a/include/configs/rcar-gen3-common.h
++++ b/include/configs/rcar-gen3-common.h
+@@ -35,6 +35,7 @@
+
+ #define CONFIG_CMD_SOURCE
+ #define CONFIG_CMD_ECHO
++#define CONFIG_CMD_SETEXPR
+
+ #define CONFIG_SYS_THUMB_BUILD
+ #define CONFIG_SYS_GENERIC_BOARD
+--
+1.9.3
+
diff --git a/meta-rcar-gen3-adas/recipes-bsp/u-boot/u-boot/0009-configs-rcar-gen3-common-Enable-askenv-command.patch b/meta-rcar-gen3-adas/recipes-bsp/u-boot/u-boot/0009-configs-rcar-gen3-common-Enable-askenv-command.patch
new file mode 100644
index 0000000..4cb1b03
--- /dev/null
+++ b/meta-rcar-gen3-adas/recipes-bsp/u-boot/u-boot/0009-configs-rcar-gen3-common-Enable-askenv-command.patch
@@ -0,0 +1,28 @@
+From 5e9a9694daa132d7b4acfd334fe3fe7f3a25b839 Mon Sep 17 00:00:00 2001
+From: Valentine Barshak <valentine.barshak@cogentembedded.com>
+Date: Wed, 21 Sep 2016 02:19:13 +0300
+Subject: [PATCH] configs: rcar-gen3-common: Enable askenv command
+
+This enables "askenv" command, which can be used
+in U-Boot scripts for user input.
+
+Signed-off-by: Valentine Barshak <valentine.barshak@cogentembedded.com>
+---
+ include/configs/rcar-gen3-common.h | 1 +
+ 1 file changed, 1 insertion(+)
+
+diff --git a/include/configs/rcar-gen3-common.h b/include/configs/rcar-gen3-common.h
+index aaeaf57..2c2a5a5 100644
+--- a/include/configs/rcar-gen3-common.h
++++ b/include/configs/rcar-gen3-common.h
+@@ -36,6 +36,7 @@
+ #define CONFIG_CMD_SOURCE
+ #define CONFIG_CMD_ECHO
+ #define CONFIG_CMD_SETEXPR
++#define CONFIG_CMD_ASKENV
+
+ #define CONFIG_SYS_THUMB_BUILD
+ #define CONFIG_SYS_GENERIC_BOARD
+--
+1.9.3
+
diff --git a/meta-rcar-gen3-adas/recipes-bsp/u-boot/u-boot/0010-configs-rcar-gen3-common-Enable-hush-parser.patch b/meta-rcar-gen3-adas/recipes-bsp/u-boot/u-boot/0010-configs-rcar-gen3-common-Enable-hush-parser.patch
new file mode 100644
index 0000000..b02cd7a
--- /dev/null
+++ b/meta-rcar-gen3-adas/recipes-bsp/u-boot/u-boot/0010-configs-rcar-gen3-common-Enable-hush-parser.patch
@@ -0,0 +1,30 @@
+From d3687cb45f88245068027956b3e42f13f854dbc0 Mon Sep 17 00:00:00 2001
+From: Valentine Barshak <valentine.barshak@cogentembedded.com>
+Date: Mon, 12 Sep 2016 21:00:01 +0300
+Subject: [PATCH] configs: rcar-gen3-common: Enable hush parser
+
+This enables hush parser, which supports
+conditionals and can be used to make
+U-Boot scripts more flexible.
+
+Signed-off-by: Valentine Barshak <valentine.barshak@cogentembedded.com>
+---
+ include/configs/rcar-gen3-common.h | 2 ++
+ 1 file changed, 2 insertions(+)
+
+diff --git a/include/configs/rcar-gen3-common.h b/include/configs/rcar-gen3-common.h
+index 2c2a5a5..aa692e5 100644
+--- a/include/configs/rcar-gen3-common.h
++++ b/include/configs/rcar-gen3-common.h
+@@ -41,6 +41,8 @@
+ #define CONFIG_SYS_THUMB_BUILD
+ #define CONFIG_SYS_GENERIC_BOARD
+
++#define CONFIG_SYS_HUSH_PARSER
++
+ #define CONFIG_REMAKE_ELF
+
+ /* boot option */
+--
+1.9.3
+
diff --git a/meta-rcar-gen3-adas/recipes-bsp/u-boot/u-boot/0011-configs-rcar-gen3-common-Enable-GPT-support.patch b/meta-rcar-gen3-adas/recipes-bsp/u-boot/u-boot/0011-configs-rcar-gen3-common-Enable-GPT-support.patch
new file mode 100644
index 0000000..a45cbc7
--- /dev/null
+++ b/meta-rcar-gen3-adas/recipes-bsp/u-boot/u-boot/0011-configs-rcar-gen3-common-Enable-GPT-support.patch
@@ -0,0 +1,32 @@
+From 04c11b42dc2eca5858e393c80e15d72c73440fb9 Mon Sep 17 00:00:00 2001
+From: Valentine Barshak <valentine.barshak@cogentembedded.com>
+Date: Fri, 21 Oct 2016 01:21:55 +0300
+Subject: [PATCH] configs: rcar-gen3-common: Enable GPT support
+
+This enables GPT support in rcar-gen3-common.h.
+It can be used for disk partitioning in U-Boot.
+
+Signed-off-by: Valentine Barshak <valentine.barshak@cogentembedded.com>
+---
+ include/configs/rcar-gen3-common.h | 5 +++++
+ 1 file changed, 5 insertions(+)
+
+diff --git a/include/configs/rcar-gen3-common.h b/include/configs/rcar-gen3-common.h
+index aa692e5..0fc46ab 100644
+--- a/include/configs/rcar-gen3-common.h
++++ b/include/configs/rcar-gen3-common.h
+@@ -38,6 +38,11 @@
+ #define CONFIG_CMD_SETEXPR
+ #define CONFIG_CMD_ASKENV
+
++#define CONFIG_EFI_PARTITION
++#define CONFIG_PARTITION_UUIDS
++#define CONFIG_RANDOM_UUID
++#define CONFIG_CMD_GPT
++
+ #define CONFIG_SYS_THUMB_BUILD
+ #define CONFIG_SYS_GENERIC_BOARD
+
+--
+1.9.3
+
diff --git a/meta-rcar-gen3-adas/recipes-bsp/u-boot/u-boot/0013-mtd-spi-QSPI-flash-support.patch b/meta-rcar-gen3-adas/recipes-bsp/u-boot/u-boot/0013-mtd-spi-QSPI-flash-support.patch
new file mode 100644
index 0000000..a4e8a7c
--- /dev/null
+++ b/meta-rcar-gen3-adas/recipes-bsp/u-boot/u-boot/0013-mtd-spi-QSPI-flash-support.patch
@@ -0,0 +1,1763 @@
+From 423d01a1b367d82a3855972483530968309cbbd4 Mon Sep 17 00:00:00 2001
+From: Daisuke Matsushita <daisuke.matsushita.ns@hitachi.com>
+Date: Tue, 21 Mar 2017 15:05:15 +0900
+Subject: [PATCH] mtd: spi: Add QSPI flash
+
+This supports QSPI flash
+
+Signed-off-by: Vladimir Barinov <vladimir.barinov@cogentembedded.com>
+---
+ arch/arm/include/asm/arch-rcar_gen3/rcar-base.h | 1
+ drivers/mtd/spi/sf.c | 15
+ drivers/mtd/spi/sf_internal.h | 195 ++++++---
+ drivers/mtd/spi/sf_ops.c | 64 +++
+ drivers/mtd/spi/sf_params.c | 249 +++++++-----
+ drivers/mtd/spi/sf_probe.c | 72 +--
+ drivers/spi/Makefile | 1
+ drivers/spi/rcar_gen3_qspi.c | 484 ++++++++++++++++++++++++
+ drivers/spi/rcar_gen3_qspi.h | 301 ++++++++++++++
+ include/linux/bitops.h | 1
+ include/spi.h | 22 -
+ 11 files changed, 1191 insertions(+), 214 deletions(-)
+ create mode 100644 drivers/spi/rcar_gen3_qspi.c
+ create mode 100644 drivers/spi/rcar_gen3_qspi.h
+
+diff --git a/arch/arm/include/asm/arch-rcar_gen3/rcar-base.h b/arch/arm/include/asm/arch-rcar_gen3/rcar-base.h
+index 59d34b8..b75e4fb 100644
+--- a/arch/arm/include/asm/arch-rcar_gen3/rcar-base.h
++++ b/arch/arm/include/asm/arch-rcar_gen3/rcar-base.h
+@@ -18,6 +18,7 @@
+ #define LBSC_BASE 0xEE220200
+ #define TMU_BASE 0xE61E0000
+ #define GPIO5_BASE 0xE6055000
++#define SH_QSPI_BASE 0xEE200000
+
+ /* SCIF */
+ #define SCIF0_BASE 0xE6E60000
+diff --git a/drivers/mtd/spi/sf.c b/drivers/mtd/spi/sf.c
+index 664e860..4e27bab 100644
+--- a/drivers/mtd/spi/sf.c
++++ b/drivers/mtd/spi/sf.c
+@@ -8,7 +8,11 @@
+ */
+
+ #include <common.h>
++#if defined(CONFIG_RCAR_GEN3)
++#include "../../spi/rcar_gen3_qspi.h"
++#else
+ #include <spi.h>
++#endif
+
+ static int spi_flash_read_write(struct spi_slave *spi,
+ const u8 *cmd, size_t cmd_len,
+@@ -25,16 +29,13 @@ static int spi_flash_read_write(struct spi_slave *spi,
+ if (data_len == 0)
+ flags |= SPI_XFER_END;
+
+- ret = spi_xfer(spi, cmd_len * 8, cmd, NULL, flags);
++ ret = spi_xfer_cmd(spi, *cmd);
+ if (ret) {
+- debug("SF: Failed to send command (%zu bytes): %d\n",
+- cmd_len, ret);
++ debug("SF: Failed to send command (%zu bytes): %d\n", cmd_len, ret);
+ } else if (data_len != 0) {
+- ret = spi_xfer(spi, data_len * 8, data_out, data_in,
+- SPI_XFER_END);
++ ret = spi_xfer(spi, data_len * 8, data_out, data_in, flags|SPI_XFER_END);
+ if (ret)
+- debug("SF: Failed to transfer %zu bytes of data: %d\n",
+- data_len, ret);
++ debug("SF: Failed to transfer %zu bytes of data: %d\n", data_len, ret);
+ }
+
+ return ret;
+diff --git a/drivers/mtd/spi/sf_internal.h b/drivers/mtd/spi/sf_internal.h
+index 785f7a9..aacee1a 100644
+--- a/drivers/mtd/spi/sf_internal.h
++++ b/drivers/mtd/spi/sf_internal.h
+@@ -12,6 +12,7 @@
+
+ #include <linux/types.h>
+ #include <linux/compiler.h>
++#include <spi_flash.h>
+
+ /* Dual SPI flash memories - see SPI_COMM_DUAL_... */
+ enum spi_dual_flash {
+@@ -20,33 +21,6 @@ enum spi_dual_flash {
+ SF_DUAL_PARALLEL_FLASH = 1 << 1,
+ };
+
+-/* Enum list - Full read commands */
+-enum spi_read_cmds {
+- ARRAY_SLOW = 1 << 0,
+- ARRAY_FAST = 1 << 1,
+- DUAL_OUTPUT_FAST = 1 << 2,
+- DUAL_IO_FAST = 1 << 3,
+- QUAD_OUTPUT_FAST = 1 << 4,
+- QUAD_IO_FAST = 1 << 5,
+-};
+-
+-/* Normal - Extended - Full command set */
+-#define RD_NORM (ARRAY_SLOW | ARRAY_FAST)
+-#define RD_EXTN (RD_NORM | DUAL_OUTPUT_FAST | DUAL_IO_FAST)
+-#define RD_FULL (RD_EXTN | QUAD_OUTPUT_FAST | QUAD_IO_FAST)
+-
+-/* sf param flags */
+-enum {
+- SECT_4K = 1 << 0,
+- SECT_32K = 1 << 1,
+- E_FSR = 1 << 2,
+- SST_BP = 1 << 3,
+- SST_WP = 1 << 4,
+- WR_QPP = 1 << 5,
+-};
+-
+-#define SST_WR (SST_BP | SST_WP)
+-
+ #define SPI_FLASH_3B_ADDR_LEN 3
+ #define SPI_FLASH_CMD_LEN (1 + SPI_FLASH_3B_ADDR_LEN)
+ #define SPI_FLASH_16MB_BOUN 0x1000000
+@@ -57,31 +31,101 @@ enum {
+ #define SPI_FLASH_CFI_MFR_MACRONIX 0xc2
+ #define SPI_FLASH_CFI_MFR_WINBOND 0xef
+
+-/* Erase commands */
+-#define CMD_ERASE_4K 0x20
+-#define CMD_ERASE_32K 0x52
+-#define CMD_ERASE_CHIP 0xc7
+-#define CMD_ERASE_64K 0xd8
++/* Read Device ID */
++#define CMD_READ_ID 0x9f
++#define CMD_READ_SFDP 0x5a
++#define CMD_READ_QUAD_ID 0xaf
+
+-/* Write commands */
++/* Register Access */
++#define CMD_READ_STATUS 0x05
++#define CMD_READ_STATUS2 0x07
++#define CMD_READ_STATUS1 0x35
++#define CMD_READ_CONFIG 0x35
++#define CMD_READ_ANY_REG 0x65
+ #define CMD_WRITE_STATUS 0x01
+-#define CMD_PAGE_PROGRAM 0x02
+ #define CMD_WRITE_DISABLE 0x04
+-#define CMD_READ_STATUS 0x05
+-#define CMD_QUAD_PAGE_PROGRAM 0x32
+-#define CMD_READ_STATUS1 0x35
+ #define CMD_WRITE_ENABLE 0x06
+-#define CMD_READ_CONFIG 0x35
+-#define CMD_FLAG_STATUS 0x70
++#define CMD_WRITE_ANY_REG 0x71
++#define CMD_CLSR 0x30
++#define CMD_CLSR_ALT 0x82
++#define CMD_4BYTE_ADDR_MODE 0xb7
++#define CMD_SET_BURST_LEN 0xc0
++#define CMD_EVALUATE_ERASE_STATUS 0xd0
++#define CMD_ECC_READ 0x19
++#define CMD_ECC_READ_ADDR4 0x18
++#define CMD_DLPRD 0x41
++#define CMD_PNVDLR 0x43
++#define CMD_WVDLR 0x4a
+
+ /* Read commands */
+ #define CMD_READ_ARRAY_SLOW 0x03
++#define CMD_READ_ARRAY_SLOW_ADDR4 0x13
+ #define CMD_READ_ARRAY_FAST 0x0b
++#define CMD_READ_ARRAY_FAST_ADDR4 0x0c
+ #define CMD_READ_DUAL_OUTPUT_FAST 0x3b
+ #define CMD_READ_DUAL_IO_FAST 0xbb
++#define CMD_READ_DUAL_IO_FAST_ADDR4 0xbc
+ #define CMD_READ_QUAD_OUTPUT_FAST 0x6b
+ #define CMD_READ_QUAD_IO_FAST 0xeb
+-#define CMD_READ_ID 0x9f
++#define CMD_READ_QUAD_IO_FAST_ADDR4 0xec
++#define CMD_READ_QUAD_IO_DDR 0xed
++#define CMD_READ_QUAD_IO_DDR_ADDR4 0xee
++
++/* Write commands */
++#define CMD_PAGE_PROGRAM 0x02
++#define CMD_PAGE_PROGRAM_ADDR4 0x12
++#define CMD_QUAD_PAGE_PROGRAM 0x32
++#define CMD_FLAG_STATUS 0x70
++
++/* Erase commands */
++#define CMD_ERASE_4K 0x20
++#define CMD_ERASE_4K_ADDR4 0x21
++#define CMD_ERASE_32K 0x52
++#define CMD_ERASE_CHIP 0xc7
++#define CMD_ERASE_64K 0xd8
++#define CMD_ERASE_256K_ADDR4 0xdc
++#define CMD_BULK_ERASE 0x60
++#define CMD_BULK_ERASE_ALT 0xc7
++
++/* Erase Program / Suspend Program */
++#define CMD_EPS 0x75
++#define CMD_EPS_ALT 0x85
++#define CMD_EPS_ALT2 0xb0
++#define CMD_EPR 0x7a
++#define CMD_EPR_ALT 0x8a
++#define CMD_EPR_ALT2 0x30
++
++/* One Time Program Array */
++#define CMD_OTP_PROGRAM 0x42
++#define CMD_OTP_READ 0x4b
++
++/* Advanced Sector Protection */
++#define CMD_DYB_READ 0xfa
++#define CMD_DYB_READ_ADDR4 0xe0
++#define CMD_DYB_WRITE 0xfb
++#define CMD_DYB_WRITE_ADDR4 0xe1
++#define CMD_PPB_READ 0xfc
++#define CMD_PPB_READ_ADDR4 0xe2
++#define CMD_PPB_PROGRAM 0xfd
++#define CMD_PPB_PROGRAM_ADDR4 0xe3
++#define CMD_PPB_ERASE 0xe4
++#define CMD_ASP_READ 0x2b
++#define CMD_ASP_PROGRAM 0x2f
++#define CMD_PPB_LOCKBIT_READ 0xa7
++#define CMD_PPB_LOCKBIT_WRITE 0xa6
++#define CMD_PASSWD_READ 0xe7
++#define CMD_PASSWD_PROGRAM 0xe8
++#define CMD_PASSWD_UNLOCK 0xe9
++
++/* Reset */
++#define CMD_SOFT_RESET_ENABLE 0x66
++#define CMD_SOFT_RESET 0x99
++#define CMD_LEGACY_SOFT_RESET 0xf0
++#define CMD_MODE_BIT_RESET 0xff
++
++/* DPD */
++#define CMD_ENT_DEEP_POWER_DOWN 0xb9
++#define CMD_REL_DEEP_POWER_DOWN 0xab
+
+ /* Bank addr access commands */
+ #ifdef CONFIG_SPI_FLASH_BAR
+@@ -94,13 +138,22 @@ enum {
+ /* Common status */
+ #define STATUS_WIP (1 << 0)
+ #define STATUS_QEB_WINSPAN (1 << 1)
+-#define STATUS_QEB_MXIC (1 << 6)
++#define STATUS_QEB_MXIC (1 << 6)
+ #define STATUS_PEC (1 << 7)
+
+ #ifdef CONFIG_SYS_SPI_ST_ENABLE_WP_PIN
+ #define STATUS_SRWD (1 << 7) /* SR write protect */
+ #endif
+
++/* Status Register 1(SR1V) */
++#define SR1V_WEL (1 << 1)
++#define SR1V_WIP (1 << 0)
++
++/* Status Register 2(SR2V) */
++#define SR2V_ESTAT (1 << 2)
++#define SR2V_ES (1 << 1)
++#define SR2V_PS (1 << 0)
++
+ /* Flash timeout values */
+ #define SPI_FLASH_PROG_TIMEOUT (2 * CONFIG_SYS_HZ)
+ #define SPI_FLASH_PAGE_ERASE_TIMEOUT (5 * CONFIG_SYS_HZ)
+@@ -117,25 +170,43 @@ int sst_write_bp(struct spi_flash *flash, u32 offset, size_t len,
+ const void *buf);
+ #endif
+
+-/**
+- * struct spi_flash_params - SPI/QSPI flash device params structure
+- *
+- * @name: Device name ([MANUFLETTER][DEVTYPE][DENSITY][EXTRAINFO])
+- * @jedec: Device jedec ID (0x[1byte_manuf_id][2byte_dev_id])
+- * @ext_jedec: Device ext_jedec ID
+- * @sector_size: Sector size of this device
+- * @nr_sectors: No.of sectors on this device
+- * @e_rd_cmd: Enum list for read commands
+- * @flags: Important param, for flash specific behaviour
+- */
++#define JEDEC_MFR(info) ((info)->id[0])
++#define JEDEC_ID(info) (((info)->id[1]) << 8 | ((info)->id[2]))
++#define JEDEC_EXT(info) (((info)->id[3]) << 8 | ((info)->id[4]))
++#define JEDEC_FID(info) ((info)->id[5])
++#define SPI_FLASH_MAX_ID_LEN 6
++
+ struct spi_flash_params {
+- const char *name;
+- u32 jedec;
+- u16 ext_jedec;
+- u32 sector_size;
+- u32 nr_sectors;
+- u8 e_rd_cmd;
+- u16 flags;
++ /* Device name ([MANUFLETTER][DEVTYPE][DENSITY][EXTRAINFO]) */
++ const char *name;
++
++ /*
++ * This array stores the ID bytes.
++ * The first three bytes are the JEDIC ID.
++ * JEDEC ID zero means "no ID" (mostly older chips).
++ */
++ u8 id[SPI_FLASH_MAX_ID_LEN];
++ u8 id_len;
++
++ /*
++ * The size listed here is what works with SPINOR_OP_SE, which isn't
++ * necessarily called a "sector" by the vendor.
++ */
++ u32 sector_size;
++ u32 n_sectors;
++
++ u16 page_size;
++
++ u16 flags;
++#define SECT_4K BIT(0) /* CMD_ERASE_4K works uniformly */
++#define E_FSR BIT(1) /* use flag status register for */
++#define SST_WR BIT(2) /* use SST byte/word programming */
++#define WR_QPP BIT(3) /* use Quad Page Program */
++#define RD_QUAD BIT(4) /* use Quad Read */
++#define RD_DUAL BIT(5) /* use Dual Read */
++#define RD_QUADIO BIT(6) /* use Quad IO Read */
++#define RD_DUALIO BIT(7) /* use Dual IO Read */
++#define RD_FULL (RD_QUAD | RD_DUAL | RD_QUADIO | RD_DUALIO)
+ };
+
+ extern const struct spi_flash_params spi_flash_params_table[];
+@@ -164,6 +235,12 @@ int spi_flash_cmd_erase_ops(struct spi_flash *flash, u32 offset, size_t len);
+ /* Read the status register */
+ int spi_flash_cmd_read_status(struct spi_flash *flash, u8 *rs);
+
++/* Read the status register2 */
++int spi_flash_cmd_read_status2(struct spi_flash *flash, u8 *rs);
++
++/* Evaluate Erase Status */
++int spi_flash_cmd_evaluate_erase_status(struct spi_flash *flash, u32 addr);
++
+ /* Program the status register */
+ int spi_flash_cmd_write_status(struct spi_flash *flash, u8 ws);
+
+diff --git a/drivers/mtd/spi/sf_ops.c b/drivers/mtd/spi/sf_ops.c
+index 34bc54e..6af38c1 100644
+--- a/drivers/mtd/spi/sf_ops.c
++++ b/drivers/mtd/spi/sf_ops.c
+@@ -11,7 +11,11 @@
+ #include <common.h>
+ #include <errno.h>
+ #include <malloc.h>
++#if defined(CONFIG_RCAR_GEN3)
++#include "../../spi/rcar_gen3_qspi.h"
++#else
+ #include <spi.h>
++#endif
+ #include <spi_flash.h>
+ #include <watchdog.h>
+
+@@ -40,6 +44,38 @@ int spi_flash_cmd_read_status(struct spi_flash *flash, u8 *rs)
+ return 0;
+ }
+
++int spi_flash_cmd_read_status2(struct spi_flash *flash, u8 *rs)
++{
++ int ret;
++ u8 cmd;
++
++ cmd = CMD_READ_STATUS2;
++ ret = spi_flash_read_common(flash, &cmd, 1, rs, 1);
++ if (ret < 0) {
++ debug("SF: fail to read status register2\n");
++ return ret;
++ }
++
++ return 0;
++}
++
++int spi_flash_cmd_evaluate_erase_status(struct spi_flash *flash, u32 addr)
++{
++ int ret;
++ u8 cmd;
++
++ cmd = CMD_EVALUATE_ERASE_STATUS;
++ spi_set_addr(addr & 0x00ffffff);
++
++ ret = spi_xfer_cmd(flash->spi, (int)cmd);
++ if (ret < 0) {
++ debug("SF: fail to Evaluate Erase Status\n");
++ return ret;
++ }
++
++ return 0;
++}
++
+ int spi_flash_cmd_write_status(struct spi_flash *flash, u8 ws)
+ {
+ u8 cmd;
+@@ -158,7 +194,10 @@ int spi_flash_cmd_wait_ready(struct spi_flash *flash, unsigned long timeout)
+ {
+ struct spi_slave *spi = flash->spi;
+ unsigned long timebase;
++#ifdef CONFIG_SF_DUAL_FLASH
+ unsigned long flags = SPI_XFER_BEGIN;
++#endif
++
+ int ret;
+ u8 status;
+ u8 check_status = 0x0;
+@@ -174,7 +213,7 @@ int spi_flash_cmd_wait_ready(struct spi_flash *flash, unsigned long timeout)
+ if (spi->flags & SPI_XFER_U_PAGE)
+ flags |= SPI_XFER_U_PAGE;
+ #endif
+- ret = spi_xfer(spi, 8, &cmd, NULL, flags);
++ ret = spi_xfer_cmd(spi, cmd);
+ if (ret) {
+ debug("SF: fail to read %s status register\n",
+ cmd == CMD_READ_STATUS ? "read" : "flag");
+@@ -250,6 +289,8 @@ int spi_flash_cmd_erase_ops(struct spi_flash *flash, u32 offset, size_t len)
+ u32 erase_size, erase_addr;
+ u8 cmd[SPI_FLASH_CMD_LEN];
+ int ret = -1;
++ u8 read_sts;
++ int wait_msec, wait_interval;
+
+ erase_size = flash->erase_size;
+ if (offset % erase_size || len % erase_size) {
+@@ -270,6 +311,7 @@ int spi_flash_cmd_erase_ops(struct spi_flash *flash, u32 offset, size_t len)
+ if (ret < 0)
+ return ret;
+ #endif
++ spi_set_addr(erase_addr);
+ spi_flash_addr(erase_addr, cmd);
+
+ debug("SF: erase %2x %2x %2x %2x (%x)\n", cmd[0], cmd[1],
+@@ -285,6 +327,24 @@ int spi_flash_cmd_erase_ops(struct spi_flash *flash, u32 offset, size_t len)
+ len -= erase_size;
+ }
+
++ /* Wait for Erase Complete */
++ wait_msec = 0;
++ wait_interval = 100;
++ while (wait_msec < 3000) { /* Max 3sec */
++ mdelay(wait_interval);
++ ret = spi_flash_cmd_evaluate_erase_status(flash, offset-erase_size);
++ WaitReadyDevice(flash->spi);
++ ret = spi_flash_cmd_read_status2(flash, &read_sts);
++ if (read_sts & SR2V_ESTAT) {
++ break;
++ }
++ wait_msec += wait_interval;
++ }
++
++ if ((ret != 0) || (read_sts != SR2V_ESTAT)) {
++ ret = -1;
++ }
++
+ return ret;
+ }
+
+@@ -319,6 +379,7 @@ int spi_flash_cmd_write_ops(struct spi_flash *flash, u32 offset,
+ chunk_len = min(chunk_len,
+ (size_t)flash->spi->max_write_size);
+
++ spi_set_addr(write_addr);
+ spi_flash_addr(write_addr, cmd);
+
+ debug("SF: 0x%p => cmd = { 0x%02x 0x%02x%02x%02x } chunk_len = %zu\n",
+@@ -409,6 +470,7 @@ int spi_flash_cmd_read_ops(struct spi_flash *flash, u32 offset,
+ else
+ read_len = remain_len;
+
++ spi_set_addr(read_addr);
+ spi_flash_addr(read_addr, cmd);
+
+ ret = spi_flash_read_common(flash, cmd, cmdsz, data, read_len);
+diff --git a/drivers/mtd/spi/sf_params.c b/drivers/mtd/spi/sf_params.c
+index c12e8c6..bd19bfb 100644
+--- a/drivers/mtd/spi/sf_params.c
++++ b/drivers/mtd/spi/sf_params.c
+@@ -12,129 +12,172 @@
+
+ #include "sf_internal.h"
+
+-/* SPI/QSPI flash device params structure */
++/* Used when the "_ext_id" is two bytes at most */
++#define INFO(_jedec_id, _ext_id, _sector_size, _n_sectors, _flags) \
++ .id = { \
++ ((_jedec_id) >> 16) & 0xff, \
++ ((_jedec_id) >> 8) & 0xff, \
++ (_jedec_id) & 0xff, \
++ ((_ext_id) >> 8) & 0xff, \
++ (_ext_id) & 0xff, \
++ }, \
++ .id_len = (!(_jedec_id) ? 0 : (3 + ((_ext_id) ? 2 : 0))), \
++ .sector_size = (_sector_size), \
++ .n_sectors = (_n_sectors), \
++ .page_size = 256, \
++ .flags = (_flags),
++
++#define INFO6(_jedec_id, _ext_id, _sector_size, _n_sectors, _flags) \
++ .id = { \
++ ((_jedec_id) >> 16) & 0xff, \
++ ((_jedec_id) >> 8) & 0xff, \
++ (_jedec_id) & 0xff, \
++ ((_ext_id) >> 16) & 0xff, \
++ ((_ext_id) >> 8) & 0xff, \
++ (_ext_id) & 0xff, \
++ }, \
++ .id_len = 6, \
++ .sector_size = (_sector_size), \
++ .n_sectors = (_n_sectors), \
++ .page_size = 256, \
++ .flags = (_flags),
++
+ const struct spi_flash_params spi_flash_params_table[] = {
+ #ifdef CONFIG_SPI_FLASH_ATMEL /* ATMEL */
+- {"AT45DB011D", 0x1f2200, 0x0, 64 * 1024, 4, RD_NORM, SECT_4K},
+- {"AT45DB021D", 0x1f2300, 0x0, 64 * 1024, 8, RD_NORM, SECT_4K},
+- {"AT45DB041D", 0x1f2400, 0x0, 64 * 1024, 8, RD_NORM, SECT_4K},
+- {"AT45DB081D", 0x1f2500, 0x0, 64 * 1024, 16, RD_NORM, SECT_4K},
+- {"AT45DB161D", 0x1f2600, 0x0, 64 * 1024, 32, RD_NORM, SECT_4K},
+- {"AT45DB321D", 0x1f2700, 0x0, 64 * 1024, 64, RD_NORM, SECT_4K},
+- {"AT45DB641D", 0x1f2800, 0x0, 64 * 1024, 128, RD_NORM, SECT_4K},
+- {"AT25DF321", 0x1f4701, 0x0, 64 * 1024, 64, RD_NORM, SECT_4K},
++ {"at45db011d", INFO(0x1f2200, 0x0, 64 * 1024, 4, SECT_4K) },
++ {"at45db021d", INFO(0x1f2300, 0x0, 64 * 1024, 8, SECT_4K) },
++ {"at45db041d", INFO(0x1f2400, 0x0, 64 * 1024, 8, SECT_4K) },
++ {"at45db081d", INFO(0x1f2500, 0x0, 64 * 1024, 16, SECT_4K) },
++ {"at45db161d", INFO(0x1f2600, 0x0, 64 * 1024, 32, SECT_4K) },
++ {"at45db321d", INFO(0x1f2700, 0x0, 64 * 1024, 64, SECT_4K) },
++ {"at45db641d", INFO(0x1f2800, 0x0, 64 * 1024, 128, SECT_4K) },
++ {"at25df321a", INFO(0x1f4701, 0x0, 64 * 1024, 64, SECT_4K) },
++ {"at25df321", INFO(0x1f4700, 0x0, 64 * 1024, 64, SECT_4K) },
++ {"at26df081a", INFO(0x1f4501, 0x0, 64 * 1024, 16, SECT_4K) },
+ #endif
+ #ifdef CONFIG_SPI_FLASH_EON /* EON */
+- {"EN25Q32B", 0x1c3016, 0x0, 64 * 1024, 64, RD_NORM, 0},
+- {"EN25Q64", 0x1c3017, 0x0, 64 * 1024, 128, RD_NORM, SECT_4K},
+- {"EN25Q128B", 0x1c3018, 0x0, 64 * 1024, 256, RD_NORM, 0},
+- {"EN25S64", 0x1c3817, 0x0, 64 * 1024, 128, RD_NORM, 0},
++ {"en25q32b", INFO(0x1c3016, 0x0, 64 * 1024, 64, 0) },
++ {"en25q64", INFO(0x1c3017, 0x0, 64 * 1024, 128, SECT_4K) },
++ {"en25q128b", INFO(0x1c3018, 0x0, 64 * 1024, 256, 0) },
++ {"en25s64", INFO(0x1c3817, 0x0, 64 * 1024, 128, 0) },
+ #endif
+ #ifdef CONFIG_SPI_FLASH_GIGADEVICE /* GIGADEVICE */
+- {"GD25Q64B", 0xc84017, 0x0, 64 * 1024, 128, RD_NORM, SECT_4K},
+- {"GD25LQ32", 0xc86016, 0x0, 64 * 1024, 64, RD_NORM, SECT_4K},
++ {"gd25q64b", INFO(0xc84017, 0x0, 64 * 1024, 128, SECT_4K) },
++ {"gd25lq32", INFO(0xc86016, 0x0, 64 * 1024, 64, SECT_4K) },
++#endif
++#ifdef CONFIG_SPI_FLASH_ISSI /* ISSI */
++ {"is25lp032", INFO(0x9d6016, 0x0, 64 * 1024, 64, 0) },
++ {"is25lp064", INFO(0x9d6017, 0x0, 64 * 1024, 128, 0) },
++ {"is25lp128", INFO(0x9d6018, 0x0, 64 * 1024, 256, 0) },
+ #endif
+ #ifdef CONFIG_SPI_FLASH_MACRONIX /* MACRONIX */
+- {"MX25L2006E", 0xc22012, 0x0, 64 * 1024, 4, RD_NORM, 0},
+- {"MX25L4005", 0xc22013, 0x0, 64 * 1024, 8, RD_NORM, 0},
+- {"MX25L8005", 0xc22014, 0x0, 64 * 1024, 16, RD_NORM, 0},
+- {"MX25L1605D", 0xc22015, 0x0, 64 * 1024, 32, RD_NORM, 0},
+- {"MX25L3205D", 0xc22016, 0x0, 64 * 1024, 64, RD_NORM, 0},
+- {"MX25L6405D", 0xc22017, 0x0, 64 * 1024, 128, RD_NORM, 0},
+- {"MX25L12805", 0xc22018, 0x0, 64 * 1024, 256, RD_FULL, WR_QPP},
+- {"MX25L25635F", 0xc22019, 0x0, 64 * 1024, 512, RD_FULL, WR_QPP},
+- {"MX25L51235F", 0xc2201a, 0x0, 64 * 1024, 1024, RD_FULL, WR_QPP},
+- {"MX25L12855E", 0xc22618, 0x0, 64 * 1024, 256, RD_FULL, WR_QPP},
++ {"mx25l2006e", INFO(0xc22012, 0x0, 64 * 1024, 4, 0) },
++ {"mx25l4005", INFO(0xc22013, 0x0, 64 * 1024, 8, 0) },
++ {"mx25l8005", INFO(0xc22014, 0x0, 64 * 1024, 16, 0) },
++ {"mx25l1605d", INFO(0xc22015, 0x0, 64 * 1024, 32, 0) },
++ {"mx25l3205d", INFO(0xc22016, 0x0, 64 * 1024, 64, 0) },
++ {"mx25l6405d", INFO(0xc22017, 0x0, 64 * 1024, 128, 0) },
++ {"mx25l12805", INFO(0xc22018, 0x0, 64 * 1024, 256, RD_FULL | WR_QPP) },
++ {"mx25l25635f", INFO(0xc22019, 0x0, 64 * 1024, 512, RD_FULL | WR_QPP) },
++ {"mx25l51235f", INFO(0xc2201a, 0x0, 64 * 1024, 1024, RD_FULL | WR_QPP) },
++ {"mx25l12855e", INFO(0xc22618, 0x0, 64 * 1024, 256, RD_FULL | WR_QPP) },
++ {"mx66u51235f", INFO(0xc2253a, 0x0, 64 * 1024, 1024, RD_FULL | WR_QPP) },
++ {"mx66l1g45g", INFO(0xc2201b, 0x0, 64 * 1024, 2048, RD_FULL | WR_QPP) },
+ #endif
+ #ifdef CONFIG_SPI_FLASH_SPANSION /* SPANSION */
+- {"S25FL008A", 0x010213, 0x0, 64 * 1024, 16, RD_NORM, 0},
+- {"S25FL016A", 0x010214, 0x0, 64 * 1024, 32, RD_NORM, 0},
+- {"S25FL032A", 0x010215, 0x0, 64 * 1024, 64, RD_NORM, 0},
+- {"S25FL064A", 0x010216, 0x0, 64 * 1024, 128, RD_NORM, 0},
+- {"S25FL116K", 0x014015, 0x0, 64 * 1024, 128, RD_NORM, 0},
+- {"S25FL164K", 0x014017, 0x0140, 64 * 1024, 128, RD_NORM, 0},
+- {"S25FL128P_256K", 0x012018, 0x0300, 256 * 1024, 64, RD_FULL, WR_QPP},
+- {"S25FL128P_64K", 0x012018, 0x0301, 64 * 1024, 256, RD_FULL, WR_QPP},
+- {"S25FL032P", 0x010215, 0x4d00, 64 * 1024, 64, RD_FULL, WR_QPP},
+- {"S25FL064P", 0x010216, 0x4d00, 64 * 1024, 128, RD_FULL, WR_QPP},
+- {"S25FL128S_256K", 0x012018, 0x4d00, 256 * 1024, 64, RD_FULL, WR_QPP},
+- {"S25FL128S_64K", 0x012018, 0x4d01, 64 * 1024, 256, RD_FULL, WR_QPP},
+- {"S25FL256S_256K", 0x010219, 0x4d00, 256 * 1024, 128, RD_FULL, WR_QPP},
+- {"S25FL256S_64K", 0x010219, 0x4d01, 64 * 1024, 512, RD_FULL, WR_QPP},
+- {"S25FL512S_256K", 0x010220, 0x4d00, 256 * 1024, 256, RD_FULL, WR_QPP},
+- {"S25FL512S_64K", 0x010220, 0x4d01, 64 * 1024, 1024, RD_FULL, WR_QPP},
+- {"S25FL512S_512K", 0x010220, 0x4f00, 256 * 1024, 256, RD_FULL, WR_QPP},
++ {"s25fl008a", INFO(0x010213, 0x0, 64 * 1024, 16, 0) },
++ {"s25fl016a", INFO(0x010214, 0x0, 64 * 1024, 32, 0) },
++ {"s25fl032a", INFO(0x010215, 0x0, 64 * 1024, 64, 0) },
++ {"s25fl064a", INFO(0x010216, 0x0, 64 * 1024, 128, 0) },
++ {"s25fl116k", INFO(0x014015, 0x0, 64 * 1024, 128, 0) },
++ {"s25fl164k", INFO(0x014017, 0x0140, 64 * 1024, 128, 0) },
++ {"s25fl128p_256k", INFO(0x012018, 0x0300, 256 * 1024, 64, RD_FULL | WR_QPP) },
++ {"s25fl128p_64k", INFO(0x012018, 0x0301, 64 * 1024, 256, RD_FULL | WR_QPP) },
++ {"s25fl032p", INFO(0x010215, 0x4d00, 64 * 1024, 64, RD_FULL | WR_QPP) },
++ {"s25fl064p", INFO(0x010216, 0x4d00, 64 * 1024, 128, RD_FULL | WR_QPP) },
++ {"s25fl128s_256k", INFO(0x012018, 0x4d00, 256 * 1024, 64, RD_FULL | WR_QPP) },
++ {"s25fl128s_64k", INFO(0x012018, 0x4d01, 64 * 1024, 256, RD_FULL | WR_QPP) },
++ {"s25fl256s_256k", INFO(0x010219, 0x4d00, 256 * 1024, 128, RD_FULL | WR_QPP) },
++ {"s25fl256s_64k", INFO(0x010219, 0x4d01, 64 * 1024, 512, RD_FULL | WR_QPP) },
++ {"s25fs256s_64k", INFO6(0x010219, 0x4d0181, 64 * 1024, 512, RD_FULL | WR_QPP | SECT_4K) },
++ {"s25fs512s", INFO6(0x010220, 0x4d0081, 256 * 1024, 2048, RD_FULL | WR_QPP | SECT_4K) },
++ {"s25fl512s_256k", INFO(0x010220, 0x4d00, 256 * 1024, 256, RD_FULL | WR_QPP) },
++ {"s25fl512s_64k", INFO(0x010220, 0x4d01, 64 * 1024, 1024, RD_FULL | WR_QPP) },
++ {"s25fl512s_512k", INFO(0x010220, 0x4f00, 256 * 1024, 256, RD_FULL | WR_QPP) },
+ #endif
+ #ifdef CONFIG_SPI_FLASH_STMICRO /* STMICRO */
+- {"M25P10", 0x202011, 0x0, 32 * 1024, 4, RD_NORM, 0},
+- {"M25P20", 0x202012, 0x0, 64 * 1024, 4, RD_NORM, 0},
+- {"M25P40", 0x202013, 0x0, 64 * 1024, 8, RD_NORM, 0},
+- {"M25P80", 0x202014, 0x0, 64 * 1024, 16, RD_NORM, 0},
+- {"M25P16", 0x202015, 0x0, 64 * 1024, 32, RD_NORM, 0},
+- {"M25PE16", 0x208015, 0x1000, 64 * 1024, 32, RD_NORM, 0},
+- {"M25PX16", 0x207115, 0x1000, 64 * 1024, 32, RD_EXTN, 0},
+- {"M25P32", 0x202016, 0x0, 64 * 1024, 64, RD_NORM, 0},
+- {"M25P64", 0x202017, 0x0, 64 * 1024, 128, RD_NORM, 0},
+- {"M25P128", 0x202018, 0x0, 256 * 1024, 64, RD_NORM, 0},
+- {"M25PX64", 0x207117, 0x0, 64 * 1024, 128, RD_NORM, SECT_4K},
+- {"N25Q32", 0x20ba16, 0x0, 64 * 1024, 64, RD_FULL, WR_QPP | SECT_4K},
+- {"N25Q32A", 0x20bb16, 0x0, 64 * 1024, 64, RD_FULL, WR_QPP | SECT_4K},
+- {"N25Q64", 0x20ba17, 0x0, 64 * 1024, 128, RD_FULL, WR_QPP | SECT_4K},
+- {"N25Q64A", 0x20bb17, 0x0, 64 * 1024, 128, RD_FULL, WR_QPP | SECT_4K},
+- {"N25Q128", 0x20ba18, 0x0, 64 * 1024, 256, RD_FULL, WR_QPP},
+- {"N25Q128A", 0x20bb18, 0x0, 64 * 1024, 256, RD_FULL, WR_QPP},
+- {"N25Q256", 0x20ba19, 0x0, 64 * 1024, 512, RD_FULL, WR_QPP | SECT_4K},
+- {"N25Q256A", 0x20bb19, 0x0, 64 * 1024, 512, RD_FULL, WR_QPP | SECT_4K},
+- {"N25Q512", 0x20ba20, 0x0, 64 * 1024, 1024, RD_FULL, WR_QPP | E_FSR | SECT_4K},
+- {"N25Q512A", 0x20bb20, 0x0, 64 * 1024, 1024, RD_FULL, WR_QPP | E_FSR | SECT_4K},
+- {"N25Q1024", 0x20ba21, 0x0, 64 * 1024, 2048, RD_FULL, WR_QPP | E_FSR | SECT_4K},
+- {"N25Q1024A", 0x20bb21, 0x0, 64 * 1024, 2048, RD_FULL, WR_QPP | E_FSR | SECT_4K},
++ {"m25p10", INFO(0x202011, 0x0, 32 * 1024, 4, 0) },
++ {"m25p20", INFO(0x202012, 0x0, 64 * 1024, 4, 0) },
++ {"m25p40", INFO(0x202013, 0x0, 64 * 1024, 8, 0) },
++ {"m25p80", INFO(0x202014, 0x0, 64 * 1024, 16, 0) },
++ {"m25p16", INFO(0x202015, 0x0, 64 * 1024, 32, 0) },
++ {"m25pE16", INFO(0x208015, 0x1000, 64 * 1024, 32, 0) },
++ {"m25pX16", INFO(0x207115, 0x1000, 64 * 1024, 32, RD_QUAD | RD_DUAL) },
++ {"m25p32", INFO(0x202016, 0x0, 64 * 1024, 64, 0) },
++ {"m25p64", INFO(0x202017, 0x0, 64 * 1024, 128, 0) },
++ {"m25p128", INFO(0x202018, 0x0, 256 * 1024, 64, 0) },
++ {"m25pX64", INFO(0x207117, 0x0, 64 * 1024, 128, SECT_4K) },
++ {"n25q016a", INFO(0x20bb15, 0x0, 64 * 1024, 32, SECT_4K) },
++ {"n25q32", INFO(0x20ba16, 0x0, 64 * 1024, 64, RD_FULL | WR_QPP | SECT_4K) },
++ {"n25q32a", INFO(0x20bb16, 0x0, 64 * 1024, 64, RD_FULL | WR_QPP | SECT_4K) },
++ {"n25q64", INFO(0x20ba17, 0x0, 64 * 1024, 128, RD_FULL | WR_QPP | SECT_4K) },
++ {"n25q64a", INFO(0x20bb17, 0x0, 64 * 1024, 128, RD_FULL | WR_QPP | SECT_4K) },
++ {"n25q128", INFO(0x20ba18, 0x0, 64 * 1024, 256, RD_FULL | WR_QPP) },
++ {"n25q128a", INFO(0x20bb18, 0x0, 64 * 1024, 256, RD_FULL | WR_QPP) },
++ {"n25q256", INFO(0x20ba19, 0x0, 64 * 1024, 512, RD_FULL | WR_QPP | SECT_4K) },
++ {"n25q256a", INFO(0x20bb19, 0x0, 64 * 1024, 512, RD_FULL | WR_QPP | SECT_4K) },
++ {"n25q512", INFO(0x20ba20, 0x0, 64 * 1024, 1024, RD_FULL | WR_QPP | E_FSR | SECT_4K) },
++ {"n25q512a", INFO(0x20bb20, 0x0, 64 * 1024, 1024, RD_FULL | WR_QPP | E_FSR | SECT_4K) },
++ {"n25q1024", INFO(0x20ba21, 0x0, 64 * 1024, 2048, RD_FULL | WR_QPP | E_FSR | SECT_4K) },
++ {"n25q1024a", INFO(0x20bb21, 0x0, 64 * 1024, 2048, RD_FULL | WR_QPP | E_FSR | SECT_4K) },
++ {"mt25qu02g", INFO(0x20bb22, 0x0, 64 * 1024, 4096, RD_FULL | WR_QPP | E_FSR | SECT_4K) },
++ {"mt25ql02g", INFO(0x20ba22, 0x0, 64 * 1024, 4096, RD_FULL | WR_QPP | E_FSR | SECT_4K) },
+ #endif
+ #ifdef CONFIG_SPI_FLASH_SST /* SST */
+- {"SST25VF040B", 0xbf258d, 0x0, 64 * 1024, 8, RD_NORM, SECT_4K | SST_WR},
+- {"SST25VF080B", 0xbf258e, 0x0, 64 * 1024, 16, RD_NORM, SECT_4K | SST_WR},
+- {"SST25VF016B", 0xbf2541, 0x0, 64 * 1024, 32, RD_NORM, SECT_4K | SST_WR},
+- {"SST25VF032B", 0xbf254a, 0x0, 64 * 1024, 64, RD_NORM, SECT_4K | SST_WR},
+- {"SST25VF064C", 0xbf254b, 0x0, 64 * 1024, 128, RD_NORM, SECT_4K},
+- {"SST25WF512", 0xbf2501, 0x0, 64 * 1024, 1, RD_NORM, SECT_4K | SST_WR},
+- {"SST25WF010", 0xbf2502, 0x0, 64 * 1024, 2, RD_NORM, SECT_4K | SST_WR},
+- {"SST25WF020", 0xbf2503, 0x0, 64 * 1024, 4, RD_NORM, SECT_4K | SST_WR},
+- {"SST25WF040", 0xbf2504, 0x0, 64 * 1024, 8, RD_NORM, SECT_4K | SST_WR},
+- {"SST25WF040B", 0x621613, 0x0, 64 * 1024, 8, RD_NORM, SECT_4K | SST_WR},
+- {"SST25WF080", 0xbf2505, 0x0, 64 * 1024, 16, RD_NORM, SECT_4K | SST_WR},
++ {"sst25vf040b", INFO(0xbf258d, 0x0, 64 * 1024, 8, SECT_4K | SST_WR) },
++ {"sst25vf080b", INFO(0xbf258e, 0x0, 64 * 1024, 16, SECT_4K | SST_WR) },
++ {"sst25vf016b", INFO(0xbf2541, 0x0, 64 * 1024, 32, SECT_4K | SST_WR) },
++ {"sst25vf032b", INFO(0xbf254a, 0x0, 64 * 1024, 64, SECT_4K | SST_WR) },
++ {"sst25vf064c", INFO(0xbf254b, 0x0, 64 * 1024, 128, SECT_4K) },
++ {"sst25wf512", INFO(0xbf2501, 0x0, 64 * 1024, 1, SECT_4K | SST_WR) },
++ {"sst25wf010", INFO(0xbf2502, 0x0, 64 * 1024, 2, SECT_4K | SST_WR) },
++ {"sst25wf020", INFO(0xbf2503, 0x0, 64 * 1024, 4, SECT_4K | SST_WR) },
++ {"sst25wf040", INFO(0xbf2504, 0x0, 64 * 1024, 8, SECT_4K | SST_WR) },
++ {"sst25wf040b", INFO(0x621613, 0x0, 64 * 1024, 8, SECT_4K) },
++ {"sst25wf080", INFO(0xbf2505, 0x0, 64 * 1024, 16, SECT_4K | SST_WR) },
+ #endif
+ #ifdef CONFIG_SPI_FLASH_WINBOND /* WINBOND */
+- {"W25P80", 0xef2014, 0x0, 64 * 1024, 16, RD_NORM, 0},
+- {"W25P16", 0xef2015, 0x0, 64 * 1024, 32, RD_NORM, 0},
+- {"W25P32", 0xef2016, 0x0, 64 * 1024, 64, RD_NORM, 0},
+- {"W25X40", 0xef3013, 0x0, 64 * 1024, 8, RD_NORM, SECT_4K},
+- {"W25X16", 0xef3015, 0x0, 64 * 1024, 32, RD_NORM, SECT_4K},
+- {"W25X32", 0xef3016, 0x0, 64 * 1024, 64, RD_NORM, SECT_4K},
+- {"W25X64", 0xef3017, 0x0, 64 * 1024, 128, RD_NORM, SECT_4K},
+- {"W25Q80BL", 0xef4014, 0x0, 64 * 1024, 16, RD_FULL, WR_QPP | SECT_4K},
+- {"W25Q16CL", 0xef4015, 0x0, 64 * 1024, 32, RD_FULL, WR_QPP | SECT_4K},
+- {"W25Q32BV", 0xef4016, 0x0, 64 * 1024, 64, RD_FULL, WR_QPP | SECT_4K},
+- {"W25Q64CV", 0xef4017, 0x0, 64 * 1024, 128, RD_FULL, WR_QPP | SECT_4K},
+- {"W25Q128BV", 0xef4018, 0x0, 64 * 1024, 256, RD_FULL, WR_QPP | SECT_4K},
+- {"W25Q256", 0xef4019, 0x0, 64 * 1024, 512, RD_FULL, WR_QPP | SECT_4K},
+- {"W25Q80BW", 0xef5014, 0x0, 64 * 1024, 16, RD_FULL, WR_QPP | SECT_4K},
+- {"W25Q16DW", 0xef6015, 0x0, 64 * 1024, 32, RD_FULL, WR_QPP | SECT_4K},
+- {"W25Q32DW", 0xef6016, 0x0, 64 * 1024, 64, RD_FULL, WR_QPP | SECT_4K},
+- {"W25Q64DW", 0xef6017, 0x0, 64 * 1024, 128, RD_FULL, WR_QPP | SECT_4K},
+- {"W25Q128FW", 0xef6018, 0x0, 64 * 1024, 256, RD_FULL, WR_QPP | SECT_4K},
++ {"w25p80", INFO(0xef2014, 0x0, 64 * 1024, 16, 0) },
++ {"w25p16", INFO(0xef2015, 0x0, 64 * 1024, 32, 0) },
++ {"w25p32", INFO(0xef2016, 0x0, 64 * 1024, 64, 0) },
++ {"w25x40", INFO(0xef3013, 0x0, 64 * 1024, 8, SECT_4K) },
++ {"w25x16", INFO(0xef3015, 0x0, 64 * 1024, 32, SECT_4K) },
++ {"w25x32", INFO(0xef3016, 0x0, 64 * 1024, 64, SECT_4K) },
++ {"w25x64", INFO(0xef3017, 0x0, 64 * 1024, 128, SECT_4K) },
++ {"w25q80bl", INFO(0xef4014, 0x0, 64 * 1024, 16, RD_FULL | WR_QPP | SECT_4K) },
++ {"w25q16cl", INFO(0xef4015, 0x0, 64 * 1024, 32, RD_FULL | WR_QPP | SECT_4K) },
++ {"w25q32bv", INFO(0xef4016, 0x0, 64 * 1024, 64, RD_FULL | WR_QPP | SECT_4K) },
++ {"w25q64cv", INFO(0xef4017, 0x0, 64 * 1024, 128, RD_FULL | WR_QPP | SECT_4K) },
++ {"w25q128bv", INFO(0xef4018, 0x0, 64 * 1024, 256, RD_FULL | WR_QPP | SECT_4K) },
++ {"w25q256", INFO(0xef4019, 0x0, 64 * 1024, 512, RD_FULL | WR_QPP | SECT_4K) },
++ {"w25q80bw", INFO(0xef5014, 0x0, 64 * 1024, 16, RD_FULL | WR_QPP | SECT_4K) },
++ {"w25q16dw", INFO(0xef6015, 0x0, 64 * 1024, 32, RD_FULL | WR_QPP | SECT_4K) },
++ {"w25q32dw", INFO(0xef6016, 0x0, 64 * 1024, 64, RD_FULL | WR_QPP | SECT_4K) },
++ {"w25q64dw", INFO(0xef6017, 0x0, 64 * 1024, 128, RD_FULL | WR_QPP | SECT_4K) },
++ {"w25q128fw", INFO(0xef6018, 0x0, 64 * 1024, 256, RD_FULL | WR_QPP | SECT_4K) },
+ #endif
+ {}, /* Empty entry to terminate the list */
+ /*
+ * Note:
+ * Below paired flash devices has similar spi_flash params.
+- * (S25FL129P_64K, S25FL128S_64K)
+- * (W25Q80BL, W25Q80BV)
+- * (W25Q16CL, W25Q16DV)
+- * (W25Q32BV, W25Q32FV_SPI)
+- * (W25Q64CV, W25Q64FV_SPI)
+- * (W25Q128BV, W25Q128FV_SPI)
+- * (W25Q32DW, W25Q32FV_QPI)
+- * (W25Q64DW, W25Q64FV_QPI)
+- * (W25Q128FW, W25Q128FV_QPI)
++ * (s25fl129p_64k, s25fl128s_64k)
++ * (w25q80bl, w25q80bv)
++ * (w25q16cl, w25q16dv)
++ * (w25q32bv, w25q32fv_spi)
++ * (w25q64cv, w25q64fv_spi)
++ * (w25q128bv, w25q128fv_spi)
++ * (w25q32dw, w25q32fv_qpi)
++ * (w25q64dw, w25q64fv_qpi)
++ * (w25q128fw, w25q128fv_qpi)
+ */
+ };
+diff --git a/drivers/mtd/spi/sf_probe.c b/drivers/mtd/spi/sf_probe.c
+index 4103723..28ef787 100644
+--- a/drivers/mtd/spi/sf_probe.c
++++ b/drivers/mtd/spi/sf_probe.c
+@@ -21,16 +21,6 @@
+
+ DECLARE_GLOBAL_DATA_PTR;
+
+-/* Read commands array */
+-static u8 spi_read_cmds_array[] = {
+- CMD_READ_ARRAY_SLOW,
+- CMD_READ_ARRAY_FAST,
+- CMD_READ_DUAL_OUTPUT_FAST,
+- CMD_READ_DUAL_IO_FAST,
+- CMD_READ_QUAD_OUTPUT_FAST,
+- CMD_READ_QUAD_IO_FAST,
+-};
+-
+ #ifdef CONFIG_SPI_FLASH_MACRONIX
+ static int spi_flash_set_qeb_mxic(struct spi_flash *flash)
+ {
+@@ -102,19 +92,27 @@ static int spi_flash_validate_params(struct spi_slave *spi, u8 *idcode,
+ struct spi_flash *flash)
+ {
+ const struct spi_flash_params *params;
+- u8 cmd;
++ u8 manufacture_id = idcode[0];
+ u16 jedec = idcode[1] << 8 | idcode[2];
+ u16 ext_jedec = idcode[3] << 8 | idcode[4];
++ u8 family_id = idcode[5];
+
+ /* Validate params from spi_flash_params table */
+ params = spi_flash_params_table;
+ for (; params->name != NULL; params++) {
+- if ((params->jedec >> 16) == idcode[0]) {
+- if ((params->jedec & 0xFFFF) == jedec) {
+- if (params->ext_jedec == 0)
+- break;
+- else if (params->ext_jedec == ext_jedec)
++ if (JEDEC_MFR(params) == manufacture_id) {
++ if (JEDEC_ID(params) == jedec) {
++ if (params->id_len - 3 == 0) {
+ break;
++ } else if (params->id_len - 3 == 2) {
++ if (JEDEC_EXT(params) == ext_jedec) {
++ break;
++ }
++ } else {
++ if ((JEDEC_EXT(params) == (ext_jedec & 0xFF00)) && (JEDEC_FID(params) == family_id)) {
++ break;
++ }
++ }
+ }
+ }
+ }
+@@ -149,48 +147,48 @@ static int spi_flash_validate_params(struct spi_slave *spi, u8 *idcode,
+
+ /* Compute the flash size */
+ flash->shift = (flash->dual_flash & SF_DUAL_PARALLEL_FLASH) ? 1 : 0;
++ flash->page_size = params->page_size;
+ /*
+ * The Spansion S25FL032P and S25FL064P have 256b pages, yet use the
+ * 0x4d00 Extended JEDEC code. The rest of the Spansion flashes with
+ * the 0x4d00 Extended JEDEC code have 512b pages. All of the others
+ * have 256b pages.
+ */
+- if (ext_jedec == 0x4d00) {
+- if ((jedec == 0x0215) || (jedec == 0x216))
+- flash->page_size = 256;
+- else
++ if ((ext_jedec & 0xFF00) == 0x4d00) {
++ if ((jedec != 0x0215) && (jedec != 0x0216) && (jedec != 0x220)) {
+ flash->page_size = 512;
+- } else {
+- flash->page_size = 256;
++ }
+ }
++
+ flash->page_size <<= flash->shift;
+ flash->sector_size = params->sector_size << flash->shift;
+- flash->size = flash->sector_size * params->nr_sectors << flash->shift;
++ flash->size = flash->sector_size * params->n_sectors << flash->shift;
+ #ifdef CONFIG_SF_DUAL_FLASH
+ if (flash->dual_flash & SF_DUAL_STACKED_FLASH)
+ flash->size <<= 1;
+ #endif
+
++#ifdef CONFIG_SPI_FLASH_USE_4K_SECTORS
+ /* Compute erase sector and command */
+ if (params->flags & SECT_4K) {
+ flash->erase_cmd = CMD_ERASE_4K;
+ flash->erase_size = 4096 << flash->shift;
+- } else if (params->flags & SECT_32K) {
+- flash->erase_cmd = CMD_ERASE_32K;
+- flash->erase_size = 32768 << flash->shift;
+- } else {
+- flash->erase_cmd = CMD_ERASE_64K;
++ } else
++#endif
++ {
++ flash->erase_cmd = CMD_ERASE_256K_ADDR4;
+ flash->erase_size = flash->sector_size;
+ }
+
+ /* Look for the fastest read cmd */
+- cmd = fls(params->e_rd_cmd & flash->spi->op_mode_rx);
+- if (cmd) {
+- cmd = spi_read_cmds_array[cmd - 1];
+- flash->read_cmd = cmd;
++ if (flash->spi->op_mode_rx & SPI_RX_SLOW) {
++ flash->read_cmd = CMD_READ_ARRAY_SLOW;
++ } else if ((flash->spi->op_mode_rx & SPI_RX_QUAD) && (params->flags & RD_QUAD)) {
++ flash->read_cmd = CMD_READ_QUAD_OUTPUT_FAST;
++ } else if ((flash->spi->op_mode_rx & SPI_RX_DUAL) && (params->flags & RD_DUAL)) {
++ flash->read_cmd = CMD_READ_DUAL_OUTPUT_FAST;
+ } else {
+- /* Go for default supported read cmd */
+- flash->read_cmd = CMD_READ_ARRAY_FAST;
++ flash->read_cmd = CMD_READ_ARRAY_FAST_ADDR4;
+ }
+
+ /* Not require to look for fastest only two write cmds yet */
+@@ -198,7 +196,7 @@ static int spi_flash_validate_params(struct spi_slave *spi, u8 *idcode,
+ flash->write_cmd = CMD_QUAD_PAGE_PROGRAM;
+ else
+ /* Go for default supported write cmd */
+- flash->write_cmd = CMD_PAGE_PROGRAM;
++ flash->write_cmd = CMD_PAGE_PROGRAM_ADDR4;
+
+ /* Read dummy_byte: dummy byte is determined based on the
+ * dummy cycles of a particular command.
+@@ -324,7 +322,7 @@ static int spi_enable_wp_pin(struct spi_flash *flash)
+ */
+ int spi_flash_probe_slave(struct spi_slave *spi, struct spi_flash *flash)
+ {
+- u8 idcode[5];
++ u8 idcode[SPI_FLASH_MAX_ID_LEN];
+ int ret;
+
+ /* Setup spi_slave */
+@@ -385,6 +383,7 @@ int spi_flash_probe_slave(struct spi_slave *spi, struct spi_flash *flash)
+ puts("\n");
+ #endif
+ #ifndef CONFIG_SPI_FLASH_BAR
++#ifndef CONFIG_R8A7797
+ if (((flash->dual_flash == SF_SINGLE_FLASH) &&
+ (flash->size > SPI_FLASH_16MB_BOUN)) ||
+ ((flash->dual_flash > SF_SINGLE_FLASH) &&
+@@ -393,6 +392,7 @@ int spi_flash_probe_slave(struct spi_slave *spi, struct spi_flash *flash)
+ puts(" Full access #define CONFIG_SPI_FLASH_BAR\n");
+ }
+ #endif
++#endif
+ if (spi_enable_wp_pin(flash))
+ puts("Enable WP pin failed\n");
+
+diff --git a/drivers/spi/Makefile b/drivers/spi/Makefile
+index ce6f1cc..fd1dd7c 100644
+--- a/drivers/spi/Makefile
++++ b/drivers/spi/Makefile
+@@ -39,6 +39,7 @@ obj-$(CONFIG_MXC_SPI) += mxc_spi.o
+ obj-$(CONFIG_MXS_SPI) += mxs_spi.o
+ obj-$(CONFIG_OC_TINY_SPI) += oc_tiny_spi.o
+ obj-$(CONFIG_OMAP3_SPI) += omap3_spi.o
++obj-$(CONFIG_RCAR_GEN3_QSPI) += rcar_gen3_qspi.o
+ obj-$(CONFIG_SANDBOX_SPI) += sandbox_spi.o
+ obj-$(CONFIG_SH_SPI) += sh_spi.o
+ obj-$(CONFIG_SH_QSPI) += sh_qspi.o
+diff --git a/drivers/spi/rcar_gen3_qspi.c b/drivers/spi/rcar_gen3_qspi.c
+new file mode 100644
+index 0000000..5095b07
+--- /dev/null
++++ b/drivers/spi/rcar_gen3_qspi.c
+@@ -0,0 +1,485 @@
++/*
++ * R-CarH3 QSPI (Quad SPI) driver
++ *
++ */
++
++#include <common.h>
++#include <malloc.h>
++#include "rcar_gen3_qspi.h"
++#include <asm/arch/rcar_gen3.h>
++#include <asm/arch/rpc-flash.h>
++#include <asm/io.h>
++
++#include "../mtd/spi/sf_internal.h"
++
++/* if DEBUG_PRINT defined, Output debug log */
++//#define DEBUG_PRINT
++#ifdef DEBUG_PRINT
++#define debug_print(format, arg...) printf("[DBG] " format, ## arg)
++#else
++#define debug_print(format, arg...) do {} while(0)
++#endif
++
++struct rcar_gen3_qspi_regs {
++ unsigned int cmncr;
++ unsigned int ssldr;
++ unsigned int dummy0;
++ unsigned int drcr;
++ unsigned int drcmr;
++ unsigned int drear;
++ unsigned int dropr;
++ unsigned int drenr;
++ unsigned int smcr;
++ unsigned int smcmr;
++ unsigned int smadr;
++ unsigned int smopr;
++ unsigned int smenr;
++ unsigned int dummy1;
++ unsigned int smrdr0;
++ unsigned int smrdr1;
++ unsigned int smwdr0;
++ unsigned int smwdr1;
++ unsigned int cmnsr;
++ unsigned int dummy2[3];
++ unsigned int drdmcr;
++ unsigned int drdrenr;
++ unsigned int smdmcr;
++ unsigned int smdrenr;
++ unsigned int dummy3[5];
++ unsigned int phycnt;
++ unsigned int phyoffset1;
++ unsigned int phyoffset2;
++ unsigned int phyint;
++ unsigned int dummy4[7];
++ unsigned int div_reg;
++};
++
++struct sh_qspi_slave {
++ struct spi_slave slave;
++ struct rcar_gen3_qspi_regs *regs;
++};
++
++const SPI_COMMAND spi_cmd_tbl[] = {
++ { CMD_READ_ID, SPI_CMD_READ, SPI_DATA_ENABLE, 0, 0, "Read ID (JEDEC Manufacturer ID and JEDEC CFI)" },
++ { CMD_READ_SFDP, SPI_CMD_READ, SPI_DATA_ENABLE, 3, 8, "Read JEDEC Serial Flash Discoverable Parameters" },
++ { CMD_READ_QUAD_ID, SPI_CMD_READ, SPI_DATA_ENABLE, 0, 0, "Read Quad ID" },
++ { CMD_READ_STATUS, SPI_CMD_READ, SPI_DATA_ENABLE, 0, 0, "Read Status Register-1" },
++ { CMD_READ_STATUS2, SPI_CMD_READ, SPI_DATA_ENABLE, 0, 0, "Read Status Register-2" },
++ { CMD_READ_CONFIG, SPI_CMD_READ, SPI_DATA_ENABLE, 0, 0, "Read Configuration Register-1" },
++ { CMD_READ_ANY_REG, SPI_CMD_READ, SPI_DATA_ENABLE, 3, 8, "Read Any Register" },
++ { CMD_WRITE_STATUS, SPI_CMD_WRITE, SPI_DATA_ENABLE, 0, 0, "Write Register (Status-1, Configuration-1)" },
++ { CMD_WRITE_DISABLE, SPI_CMD_OTHER, SPI_DATA_DISABLE, 0, 0, "Write Disable" },
++ { CMD_WRITE_ENABLE, SPI_CMD_OTHER, SPI_DATA_DISABLE, 0, 0, "Write Enable" },
++ { CMD_WRITE_ANY_REG, SPI_CMD_WRITE, SPI_DATA_ENABLE, 3, 0, "Write Any Register" },
++ { CMD_CLSR, SPI_CMD_OTHER, SPI_DATA_DISABLE, 0, 0, "Clear Status Register-1 - Erase/Prog. Fail Reset" },
++ { CMD_CLSR_ALT, SPI_CMD_OTHER, SPI_DATA_DISABLE, 0, 0, "Clear Status Register-1 - Erase/Prog. Fail Reset" },
++ { CMD_4BYTE_ADDR_MODE, SPI_CMD_OTHER, SPI_DATA_DISABLE, 0, 0, "Enter 4-byte Address Mode" },
++ { CMD_SET_BURST_LEN, SPI_CMD_WRITE, SPI_DATA_ENABLE, 0, 0, "Set Burst Length" },
++ { CMD_EVALUATE_ERASE_STATUS, SPI_CMD_OTHER, SPI_DATA_DISABLE, 3, 0, "Evaluate Erase Status" },
++ { CMD_ECC_READ, SPI_CMD_READ, SPI_DATA_ENABLE, 3, 8, "ECC Read (3- or 4-byte address)" },
++ { CMD_ECC_READ_ADDR4, SPI_CMD_READ, SPI_DATA_ENABLE, 4, 8, "ECC Read (4-byte address)" },
++ { CMD_DLPRD, SPI_CMD_READ, SPI_DATA_ENABLE, 0, 0, "Data Learning Pattern Read" },
++ { CMD_PNVDLR, SPI_CMD_WRITE, SPI_DATA_ENABLE, 0, 0, "Program NV Data Learning Register" },
++ { CMD_WVDLR, SPI_CMD_WRITE, SPI_DATA_ENABLE, 0, 0, "Write Volatile Data Learning Register" },
++ { CMD_READ_ARRAY_SLOW, SPI_CMD_READ, SPI_DATA_ENABLE, 3, 0, "Read (3- or 4-byte address)" },
++ { CMD_READ_ARRAY_SLOW_ADDR4, SPI_CMD_READ, SPI_DATA_ENABLE, 4, 0, "Read (4-byte address)" },
++ { CMD_READ_ARRAY_FAST, SPI_CMD_READ, SPI_DATA_ENABLE, 3, 8, "Fast Read (3- or 4-byte address)" },
++ { CMD_READ_ARRAY_FAST_ADDR4, SPI_CMD_READ, SPI_DATA_ENABLE, 4, 8, "Fast Read (4-byte address)" },
++ { CMD_READ_DUAL_IO_FAST, SPI_CMD_READ, SPI_DATA_ENABLE, 3, 8, "Dual I/O Read (3- or 4-byte address)" },
++ { CMD_READ_DUAL_IO_FAST_ADDR4, SPI_CMD_READ, SPI_DATA_ENABLE, 4, 8, "Dual I/O Read (4-byte address)" },
++ { CMD_READ_QUAD_IO_FAST, SPI_CMD_READ, SPI_DATA_ENABLE, 3, 8, "Quad I/O Read (3- or 4-byte address)" },
++ { CMD_READ_QUAD_IO_FAST_ADDR4, SPI_CMD_READ, SPI_DATA_ENABLE, 4, 8, "Quad I/O Read (4-byte address)" },
++ { CMD_READ_QUAD_IO_DDR, SPI_CMD_READ, SPI_DATA_ENABLE, 3, 8, "DDR Quad I/O Read (3- or 4-byte address)" },
++ { CMD_READ_QUAD_IO_DDR_ADDR4, SPI_CMD_READ, SPI_DATA_ENABLE, 4, 8, "DDR Quad I/O Read (4-byte address)" },
++ { CMD_PAGE_PROGRAM, SPI_CMD_WRITE, SPI_DATA_ENABLE, 3, 0, "Page Program (3- or 4-byte address)" },
++ { CMD_PAGE_PROGRAM_ADDR4, SPI_CMD_WRITE, SPI_DATA_ENABLE, 4, 0, "Page Program (4-byte address)" },
++ { CMD_ERASE_4K, SPI_CMD_ERASE, SPI_DATA_DISABLE, 3, 0, "Parameter 4 kB-sector Erase (3- or 4-byte address)" },
++ { CMD_ERASE_4K_ADDR4, SPI_CMD_ERASE, SPI_DATA_DISABLE, 4, 0, "Parameter 4 kB-sector Erase (4-byte address)" },
++ { CMD_ERASE_64K, SPI_CMD_ERASE, SPI_DATA_DISABLE, 3, 0, "Erase 256 kB (3- or 4-byte address)" },
++ { CMD_ERASE_256K_ADDR4, SPI_CMD_ERASE, SPI_DATA_DISABLE, 4, 0, "Erase 256 kB (4-byte address)" },
++ { CMD_BULK_ERASE, SPI_CMD_ERASE, SPI_DATA_DISABLE, 0, 0, "Bulk Erase" },
++ { CMD_BULK_ERASE_ALT, SPI_CMD_ERASE, SPI_DATA_DISABLE, 0, 0, "Bulk Erase (alternate command)" },
++ { CMD_EPS, SPI_CMD_ERASE, SPI_DATA_DISABLE, 0, 0, "Erase / Program Suspend" },
++ { CMD_EPS_ALT, SPI_CMD_ERASE, SPI_DATA_DISABLE, 0, 0, "Erase / Program Suspend" },
++ { CMD_EPS_ALT2, SPI_CMD_ERASE, SPI_DATA_DISABLE, 0, 0, "Erase / Program Suspend" },
++ { CMD_EPR, SPI_CMD_ERASE, SPI_DATA_DISABLE, 0, 0, "Erase / Program Resume" },
++ { CMD_EPR_ALT, SPI_CMD_ERASE, SPI_DATA_DISABLE, 0, 0, "Erase / Program Resume" },
++ { CMD_EPR_ALT2, SPI_CMD_ERASE, SPI_DATA_DISABLE, 0, 0, "Erase / Program Resume" },
++ { CMD_OTP_PROGRAM, SPI_CMD_WRITE, SPI_DATA_ENABLE, 3, 0, "OTP Program" },
++ { CMD_OTP_READ, SPI_CMD_WRITE, SPI_DATA_ENABLE, 3, 0, "OTP Read" },
++ { CMD_DYB_READ, SPI_CMD_READ, SPI_DATA_ENABLE, 3, 0, "DYB Read" },
++ { CMD_DYB_READ_ADDR4, SPI_CMD_READ, SPI_DATA_ENABLE, 4, 0, "DYB Read" },
++ { CMD_DYB_WRITE, SPI_CMD_WRITE, SPI_DATA_ENABLE, 3, 0, "DYB Write" },
++ { CMD_DYB_WRITE_ADDR4, SPI_CMD_WRITE, SPI_DATA_ENABLE, 4, 0, "DYB Write" },
++ { CMD_PPB_READ, SPI_CMD_READ, SPI_DATA_ENABLE, 3, 0, "PPB Read" },
++ { CMD_PPB_READ_ADDR4, SPI_CMD_READ, SPI_DATA_ENABLE, 3, 0, "PPB Read" },
++ { CMD_PPB_PROGRAM, SPI_CMD_WRITE, SPI_DATA_DISABLE, 3, 0, "PPB Program" },
++ { CMD_PPB_PROGRAM_ADDR4, SPI_CMD_WRITE, SPI_DATA_DISABLE, 3, 0, "PPB Program" },
++ { CMD_PPB_ERASE, SPI_CMD_OTHER, SPI_DATA_DISABLE, 0, 0, "PPB Erase" },
++ { CMD_ASP_READ, SPI_CMD_READ, SPI_DATA_ENABLE, 0, 0, "ASP Read" },
++ { CMD_ASP_PROGRAM, SPI_CMD_WRITE, SPI_DATA_ENABLE, 0, 0, "ASP Program" },
++ { CMD_PPB_LOCKBIT_READ, SPI_CMD_READ, SPI_DATA_ENABLE, 0, 0, "PPB Lock Bit Read" },
++ { CMD_PPB_LOCKBIT_WRITE, SPI_CMD_WRITE, SPI_DATA_DISABLE, 0, 0, "PPB Lock Bit Write" },
++ { CMD_PASSWD_READ, SPI_CMD_READ, SPI_DATA_ENABLE, 0, 0, "Password Read" },
++ { CMD_PASSWD_PROGRAM, SPI_CMD_WRITE, SPI_DATA_ENABLE, 0, 0, "Password Program" },
++ { CMD_PASSWD_UNLOCK, SPI_CMD_OTHER, SPI_DATA_ENABLE, 0, 0, "Password Unlock" },
++ { CMD_SOFT_RESET_ENABLE, SPI_CMD_OTHER, SPI_DATA_DISABLE, 0, 0, "Software Reset Enable" },
++ { CMD_SOFT_RESET, SPI_CMD_OTHER, SPI_DATA_DISABLE, 0, 0, "Software Reset" },
++ { CMD_LEGACY_SOFT_RESET, SPI_CMD_OTHER, SPI_DATA_DISABLE, 0, 0, "Legacy Software Reset" },
++ { CMD_MODE_BIT_RESET, SPI_CMD_OTHER, SPI_DATA_DISABLE, 0, 0, "Mode Bit Reset" },
++ { CMD_ENT_DEEP_POWER_DOWN, SPI_CMD_OTHER, SPI_DATA_DISABLE, 0, 0, "Enter Deep Power-Down Mode" },
++ { CMD_REL_DEEP_POWER_DOWN, SPI_CMD_OTHER, SPI_DATA_DISABLE, 0, 0, "Release from Deep Power-Down Mode" },
++ { SPI_COMMAND_LAST, SPI_CMD_OTHER, SPI_DATA_DISABLE, 0, 0, "Last Command" },
++};
++
++static inline struct sh_qspi_slave *to_sh_qspi(struct spi_slave *slave)
++{
++ return container_of(slave, struct sh_qspi_slave, slave);
++}
++
++void spi_set_addr(uint32_t addr)
++{
++ debug_print("Set Addr: %08X\n", addr);
++ out_le32(SH_QSPI_BASE + RPC_SMADR, addr);
++ return;
++}
++
++static void rcar_gen3_qspi_init(void)
++{
++ out_le32(SH_QSPI_BASE + RPC_PHYCNT, 0x80000260);
++ out_le32(SH_QSPI_BASE + RPC_CMNCR, 0x81FFF300);
++
++ return;
++}
++
++int spi_cs_is_valid(unsigned int bus, unsigned int cs)
++{
++ return 1;
++}
++
++void spi_cs_activate(struct spi_slave *slave)
++{
++ out_le32(SH_QSPI_BASE + RPC_PHYCNT, 0x80000260);
++
++ return;
++}
++
++void spi_cs_deactivate(struct spi_slave *slave)
++{
++ out_le32(SH_QSPI_BASE + RPC_SMCR, SPI_SMCR_SPIE);
++ WaitRpcTxEnd();
++ out_le32(SH_QSPI_BASE + RPC_PHYCNT, 0x00000274);
++ out_le32(SH_QSPI_BASE + RPC_DRCR, 0x01FF0301);
++
++ return;
++}
++
++void spi_init(void)
++{
++ /* nothing to do */
++}
++
++struct spi_slave *spi_setup_slave(unsigned int bus, unsigned int cs,
++ unsigned int max_hz, unsigned int mode)
++{
++ struct sh_qspi_slave *ss;
++
++ if (!spi_cs_is_valid(bus, cs))
++ return NULL;
++
++ ss = spi_alloc_slave(struct sh_qspi_slave, bus, cs);
++ if (!ss) {
++ printf("SPI_error: Fail to allocate sh_qspi_slave\n");
++ return NULL;
++ }
++
++ ss->regs = (struct rcar_gen3_qspi_regs *)SH_QSPI_BASE;
++
++ /* Init R-Car-Gen3 QSPI */
++ rcar_gen3_qspi_init();
++
++ return &ss->slave;
++}
++
++void spi_free_slave(struct spi_slave *slave)
++{
++ struct sh_qspi_slave *spi = to_sh_qspi(slave);
++
++ free(spi);
++}
++
++int spi_claim_bus(struct spi_slave *slave)
++{
++ return 0;
++}
++
++void spi_release_bus(struct spi_slave *slave)
++{
++}
++
++#define BUFFER_SIZE (128)
++int spi_xfer(struct spi_slave *slave, unsigned int bitlen, const void *dout,
++ void *din, unsigned long flags)
++{
++ unsigned long nbyte, rnbyte, wnbyte;
++ int i, ret = 0;
++ uint32_t *tdata_l = (uint32_t *)dout;
++ uint32_t *rdata_l = (uint32_t *)din;
++ uint8_t *ptr_b;
++ uint32_t readVal, writeVal;
++
++ if (dout == NULL && din == NULL) {
++ if (flags & SPI_XFER_END)
++ spi_cs_deactivate(slave);
++ return 0;
++ }
++
++ if (bitlen % 8) {
++ printf("%s: bitlen is not 8bit alined %d", __func__, bitlen);
++ return 1;
++ }
++
++ if (flags & SPI_XFER_BEGIN) {
++ spi_cs_activate(slave);
++ }
++
++ /* Set Data Enable 32bit */
++ readVal = in_le32(SH_QSPI_BASE + RPC_SMENR);
++ writeVal = (readVal & 0xffff0000);
++ writeVal |= SPI_SMENR_SPIDE_32BIT;
++ out_le32(SH_QSPI_BASE + RPC_SMENR, writeVal);
++
++ nbyte = bitlen / 8;
++ if (tdata_l != NULL)
++ wnbyte = nbyte;
++ else
++ wnbyte = 0;
++
++ if (rdata_l != NULL)
++ rnbyte = nbyte;
++ else
++ rnbyte = 0;
++
++ while (wnbyte > 0) {
++ if (wnbyte < BYTE_32BIT) {
++ out_8(RPC_SMWDR0, *(uint8_t*)tdata_l);
++ /* Set Data Enable 8bit */
++ readVal = in_le32(SH_QSPI_BASE + RPC_SMENR);
++ writeVal = (readVal & 0xffff0000);
++ writeVal |= SPI_SMENR_SPIDE_8BIT;
++ out_le32(SH_QSPI_BASE + RPC_SMENR, writeVal);
++ }else{
++ out_le32(SH_QSPI_BASE + RPC_SMWDR0, *tdata_l);
++ }
++
++ if (wnbyte >= BYTE_32BIT) {
++ tdata_l++;
++ wnbyte -= BYTE_32BIT;
++ }else{
++ ptr_b = (uint8_t*) tdata_l;
++ ptr_b++;
++ tdata_l = (uint32_t*) ptr_b;
++ wnbyte -= BYTE_8BIT;
++ }
++
++ if (wnbyte > 0) {
++ out_le32(SH_QSPI_BASE + RPC_SMCR, SPI_SMCR_SSLKP | SPI_SMCR_SPIWE | SPI_SMCR_SPIE);
++ }else{
++ out_le32(SH_QSPI_BASE + RPC_SMCR, SPI_SMCR_SPIWE | SPI_SMCR_SPIE);
++ }
++
++ WaitRpcTxEnd();
++
++ if (wnbyte == 0) {
++ WaitReadyDevice(slave);
++ }
++ }
++
++ while (rnbyte > 0) {
++ if (rnbyte < BYTE_32BIT) {
++ readVal = in_le32(SH_QSPI_BASE + RPC_SMRDR0);
++ ptr_b = (uint8_t*) rdata_l;
++ for(i=0; i<rnbyte; i++) {
++ *ptr_b = (readVal >> (8*i)) & 0x000000ff;
++ ptr_b++;
++ }
++ }else{
++ *rdata_l = in_le32(SH_QSPI_BASE + RPC_SMRDR0);
++ }
++
++ rdata_l++;
++
++ if(slave->spi_cmd->cmd_code == CMD_READ_ARRAY_FAST_ADDR4) {
++ readVal = in_le32(SH_QSPI_BASE + RPC_SMENR);
++ writeVal = readVal | 0x0000CF00;
++ out_le32(SH_QSPI_BASE + RPC_SMENR, writeVal);
++ readVal = in_le32(SH_QSPI_BASE + RPC_SMADR);
++ readVal += BYTE_32BIT;
++ spi_set_addr(readVal);
++ out_le32(SH_QSPI_BASE + RPC_SMCR, SPI_SMCR_SPIRE | SPI_SMCR_SPIE);
++ }else{
++ if (rnbyte > BYTE_32BIT) {
++ out_le32(SH_QSPI_BASE + RPC_SMCR, SPI_SMCR_SSLKP | SPI_SMCR_SPIRE | SPI_SMCR_SPIE);
++ }else{
++ out_le32(SH_QSPI_BASE + RPC_SMCR, SPI_SMCR_SPIRE | SPI_SMCR_SPIE);
++ }
++ }
++
++ WaitRpcTxEnd();
++
++ if (rnbyte >= BYTE_32BIT) {
++ rnbyte -= BYTE_32BIT;
++ }else{
++ rnbyte = 0;
++ }
++ }
++
++ if (flags & SPI_XFER_END){
++ spi_cs_deactivate(slave);
++ }
++
++ return ret;
++}
++
++int spi_xfer_cmd(struct spi_slave *slave, int cmd_no)
++{
++ uint32_t readVal, writeVal, dummy_cyc;
++ const SPI_COMMAND *cur_cmd_tbl;
++ cur_cmd_tbl = spi_cmd_tbl;
++
++ while(cur_cmd_tbl->cmd_code != SPI_COMMAND_LAST) {
++ if(cur_cmd_tbl->cmd_code != cmd_no) {
++ cur_cmd_tbl++;
++ continue;
++ }
++
++ slave->spi_cmd = cur_cmd_tbl;
++
++ spi_cs_activate(slave);
++ out_le32(SH_QSPI_BASE + RPC_SMCMR, cmd_no << SPI_SMCMR_CMD_BIT);
++ debug_print("SPI CODE:0x%02X [ %s ]\n", cur_cmd_tbl->cmd_code, cur_cmd_tbl->cmd_desc);
++
++ readVal = in_le32(SH_QSPI_BASE + RPC_SMENR);
++ writeVal = readVal & 0xFFFF0000;
++ writeVal |= SPI_SMENR_CDE;
++
++ /* Setting Address */
++ switch (cur_cmd_tbl->addr_len) {
++ case 3:
++ writeVal |= SPI_SMENR_ADE_3BYTE;
++ break;
++ case 4:
++ writeVal |= SPI_SMENR_ADE_4BYTE;
++ break;
++ default:
++ writeVal |= SPI_SMENR_ADE_DISABLE;
++ break;
++ }
++
++ /* Setting dummy cycle */
++ if (cur_cmd_tbl->dummy_len != 0) {
++ writeVal |= SPI_SMENR_DME;
++ dummy_cyc = cur_cmd_tbl->dummy_len - 1;
++ out_le32(SH_QSPI_BASE + RPC_SMDMCR, dummy_cyc);
++ }
++ out_le32(SH_QSPI_BASE + RPC_SMENR, writeVal);
++
++ switch(cur_cmd_tbl->rw_type) {
++ case SPI_CMD_READ:
++ readVal = in_le32(SH_QSPI_BASE + RPC_SMENR);
++ writeVal = readVal & 0xFFFFFFF0;
++ writeVal |= SPI_SMENR_SPIDE_32BIT;
++ out_le32(SH_QSPI_BASE + RPC_SMENR, writeVal);
++
++ if(cur_cmd_tbl->data_enable == SPI_DATA_ENABLE) {
++ if(cur_cmd_tbl->cmd_code == CMD_READ_ARRAY_FAST_ADDR4) {
++ out_le32(SH_QSPI_BASE + RPC_SMCR, SPI_SMCR_SPIRE | SPI_SMCR_SPIE);
++ }else{
++ out_le32(SH_QSPI_BASE + RPC_SMCR, SPI_SMCR_SSLKP | SPI_SMCR_SPIRE | SPI_SMCR_SPIE);
++ }
++ }else{
++ out_le32(SH_QSPI_BASE + RPC_SMCR, SPI_SMCR_SPIRE | SPI_SMCR_SPIE);
++ }
++ break;
++ case SPI_CMD_WRITE:
++ if(cur_cmd_tbl->data_enable == SPI_DATA_ENABLE) {
++ out_le32(SH_QSPI_BASE + RPC_SMCR, SPI_SMCR_SSLKP | SPI_SMCR_SPIWE | SPI_SMCR_SPIE);
++ }else{
++ out_le32(SH_QSPI_BASE + RPC_SMCR, SPI_SMCR_SPIWE | SPI_SMCR_SPIE);
++ }
++ break;
++ default:
++ if(cur_cmd_tbl->data_enable == SPI_DATA_ENABLE) {
++ out_le32(SH_QSPI_BASE + RPC_SMCR, SPI_SMCR_SSLKP | SPI_SMCR_SPIE);
++ }else{
++ out_le32(SH_QSPI_BASE + RPC_SMCR, SPI_SMCR_SPIE);
++ }
++ break;
++ }
++
++ WaitRpcTxEnd();
++
++ if (cur_cmd_tbl->data_enable != SPI_DATA_ENABLE) {
++ spi_cs_deactivate(slave);
++ }
++ break;
++ }
++
++ if(cur_cmd_tbl->cmd_code == SPI_COMMAND_LAST) {
++ printf("Unknown SPI Command : %02x\n", cmd_no);
++ return -1;
++ }
++ return 0;
++}
++
++void WaitRpcTxEnd(void)
++{
++ uint32_t dataL=0;
++
++ while(1) {
++ dataL = in_le32(SH_QSPI_BASE + RPC_CMNSR);
++ if(dataL & 0x00000001) {
++ break;
++ }
++ // Wait for TEND = 1
++ if(ctrlc()) {
++ puts("abort\n");
++ return;
++ }
++ udelay(1);
++ }
++ return;
++}
++
++void WaitReadyDevice(struct spi_slave *slave)
++{
++ int ret;
++ u8 status;
++ while(1) {
++ ret = spi_get_read_status(slave, &status);
++ if (ret < 0) {
++ printf("SF: fail to get read status\n");
++ return;
++ }
++ if ((status & SR1V_WIP) == 0) {
++ break;
++ }
++ udelay(1);
++ }
++ return;
++}
++
++int spi_get_read_status(struct spi_slave *slave, u8 *rs)
++{
++ int ret;
++ u8 cmd;
++
++ cmd = CMD_READ_STATUS;
++ ret = spi_flash_cmd_read(slave, &cmd, 1, rs, 1);
++ if (ret < 0) {
++ debug("SF: fail to get read status register\n");
++ return ret;
++ }
++
++ return 0;
++}
+diff --git a/drivers/spi/rcar_gen3_qspi.h b/drivers/spi/rcar_gen3_qspi.h
+new file mode 100644
+index 0000000..deb18d3
+--- /dev/null
++++ b/drivers/spi/rcar_gen3_qspi.h
+@@ -0,0 +1,301 @@
++/*
++ * Common R-Car-Gen3 QSPI Interface: Controller-specific definitions
++ *
++ */
++
++#ifndef _R_CAR_GEN3_QSPI_H_
++#define _R_CAR_GEN3_QSPI_H_
++
++/* SPI transfer flags */
++#define SPI_XFER_BEGIN 0x01 /* Assert CS before transfer */
++#define SPI_XFER_END 0x02 /* Deassert CS after transfer */
++#define SPI_XFER_MMAP 0x08 /* Memory Mapped start */
++#define SPI_XFER_MMAP_END 0x10 /* Memory Mapped End */
++#define SPI_XFER_ONCE (SPI_XFER_BEGIN | SPI_XFER_END)
++#define SPI_XFER_U_PAGE (1 << 5)
++
++#define SPI_COMMAND_LAST 0xffffffff
++#define SPI_SMCMR_CMD_BIT 16
++
++#define SPI_CMD_OTHER 0
++#define SPI_CMD_READ 1
++#define SPI_CMD_WRITE 2
++#define SPI_CMD_ERASE 3
++
++#define SPI_DATA_DISABLE 0
++#define SPI_DATA_ENABLE 1
++
++#define SPI_SMCR_SPIE 0x00000001
++#define SPI_SMCR_SPIWE 0x00000002
++#define SPI_SMCR_SPIRE 0x00000004
++#define SPI_SMCR_SSLKP 0x00000100
++
++#define SPI_SMENR_DME (1 << 15)
++#define SPI_SMENR_CDE (1 << 14)
++#define SPI_SMENR_ADE_DISABLE (0x0 << 8)
++#define SPI_SMENR_ADE_3BYTE (0x7 << 8)
++#define SPI_SMENR_ADE_4BYTE (0xF << 8)
++#define SPI_SMENR_SPIDE_DISABLE (0x0)
++#define SPI_SMENR_SPIDE_8BIT (0x8)
++#define SPI_SMENR_SPIDE_16BIT (0xC)
++#define SPI_SMENR_SPIDE_32BIT (0xF)
++
++#define BYTE_32BIT (4)
++#define BYTE_8BIT (1)
++
++typedef struct {
++ uint32_t cmd_code;
++ uint8_t rw_type;
++ uint32_t data_enable;
++ uint32_t addr_len;
++ uint32_t dummy_len;
++ char* cmd_desc;
++} SPI_COMMAND;
++
++/**
++ * struct spi_slave - Representation of a SPI slave
++ *
++ * For driver model this is the per-child data used by the SPI bus. It can
++ * be accessed using dev_get_parentdata() on the slave device. The SPI uclass
++ * sets uip per_child_auto_alloc_size to sizeof(struct spi_slave), and the
++ * driver should not override it. Two platform data fields (max_hz and mode)
++ * are copied into this structure to provide an initial value. This allows
++ * them to be changed, since we should never change platform data in drivers.
++ *
++ * If not using driver model, drivers are expected to extend this with
++ * controller-specific data.
++ *
++ * @dev: SPI slave device
++ * @max_hz: Maximum speed for this slave
++ * @mode: SPI mode to use for this slave (see SPI mode flags)
++ * @bus: ID of the bus that the slave is attached to. For
++ * driver model this is the sequence number of the SPI
++ * bus (bus->seq) so does not need to be stored
++ * @cs: ID of the chip select connected to the slave.
++ * @op_mode_rx: SPI RX operation mode.
++ * @op_mode_tx: SPI TX operation mode.
++ * @wordlen: Size of SPI word in number of bits
++ * @max_write_size: If non-zero, the maximum number of bytes which can
++ * be written at once, excluding command bytes.
++ * @memory_map: Address of read-only SPI flash access.
++ * @option: Varies SPI bus options - separate, shared bus.
++ * @flags: Indication of SPI flags.
++ */
++struct spi_slave {
++#ifdef CONFIG_DM_SPI
++ struct udevice *dev; /* struct spi_slave is dev->parentdata */
++ uint max_hz;
++ uint mode;
++#else
++ unsigned int bus;
++ unsigned int cs;
++#endif
++ u8 op_mode_rx;
++ u8 op_mode_tx;
++ unsigned int wordlen;
++ unsigned int max_write_size;
++ void *memory_map;
++ u8 option;
++ u8 flags;
++ const SPI_COMMAND *spi_cmd;
++};
++
++/**
++ * Initialization, must be called once on start up.
++ *
++ * TODO: I don't think we really need this.
++ */
++void spi_init(void);
++
++/**
++ * spi_do_alloc_slave - Allocate a new SPI slave (internal)
++ *
++ * Allocate and zero all fields in the spi slave, and set the bus/chip
++ * select. Use the helper macro spi_alloc_slave() to call this.
++ *
++ * @offset: Offset of struct spi_slave within slave structure.
++ * @size: Size of slave structure.
++ * @bus: Bus ID of the slave chip.
++ * @cs: Chip select ID of the slave chip on the specified bus.
++ */
++void *spi_do_alloc_slave(int offset, int size, unsigned int bus,
++ unsigned int cs);
++
++/**
++ * spi_alloc_slave - Allocate a new SPI slave
++ *
++ * Allocate and zero all fields in the spi slave, and set the bus/chip
++ * select.
++ *
++ * @_struct: Name of structure to allocate (e.g. struct tegra_spi).
++ * This structure must contain a member 'struct spi_slave *slave'.
++ * @bus: Bus ID of the slave chip.
++ * @cs: Chip select ID of the slave chip on the specified bus.
++ */
++#define spi_alloc_slave(_struct, bus, cs) \
++ spi_do_alloc_slave(offsetof(_struct, slave), \
++ sizeof(_struct), bus, cs)
++
++/**
++ * spi_alloc_slave_base - Allocate a new SPI slave with no private data
++ *
++ * Allocate and zero all fields in the spi slave, and set the bus/chip
++ * select.
++ *
++ * @bus: Bus ID of the slave chip.
++ * @cs: Chip select ID of the slave chip on the specified bus.
++ */
++#define spi_alloc_slave_base(bus, cs) \
++ spi_do_alloc_slave(0, sizeof(struct spi_slave), bus, cs)
++
++/**
++ * Set up communications parameters for a SPI slave.
++ *
++ * This must be called once for each slave. Note that this function
++ * usually doesn't touch any actual hardware, it only initializes the
++ * contents of spi_slave so that the hardware can be easily
++ * initialized later.
++ *
++ * @bus: Bus ID of the slave chip.
++ * @cs: Chip select ID of the slave chip on the specified bus.
++ * @max_hz: Maximum SCK rate in Hz.
++ * @mode: Clock polarity, clock phase and other parameters.
++ *
++ * Returns: A spi_slave reference that can be used in subsequent SPI
++ * calls, or NULL if one or more of the parameters are not supported.
++ */
++struct spi_slave *spi_setup_slave(unsigned int bus, unsigned int cs,
++ unsigned int max_hz, unsigned int mode);
++
++/**
++ * Free any memory associated with a SPI slave.
++ *
++ * @slave: The SPI slave
++ */
++void spi_free_slave(struct spi_slave *slave);
++
++/**
++ * Claim the bus and prepare it for communication with a given slave.
++ *
++ * This must be called before doing any transfers with a SPI slave. It
++ * will enable and initialize any SPI hardware as necessary, and make
++ * sure that the SCK line is in the correct idle state. It is not
++ * allowed to claim the same bus for several slaves without releasing
++ * the bus in between.
++ *
++ * @slave: The SPI slave
++ *
++ * Returns: 0 if the bus was claimed successfully, or a negative value
++ * if it wasn't.
++ */
++int spi_claim_bus(struct spi_slave *slave);
++
++/**
++ * Release the SPI bus
++ *
++ * This must be called once for every call to spi_claim_bus() after
++ * all transfers have finished. It may disable any SPI hardware as
++ * appropriate.
++ *
++ * @slave: The SPI slave
++ */
++void spi_release_bus(struct spi_slave *slave);
++
++/**
++ * Set the word length for SPI transactions
++ *
++ * Set the word length (number of bits per word) for SPI transactions.
++ *
++ * @slave: The SPI slave
++ * @wordlen: The number of bits in a word
++ *
++ * Returns: 0 on success, -1 on failure.
++ */
++int spi_set_wordlen(struct spi_slave *slave, unsigned int wordlen);
++
++/**
++ * SPI transfer
++ *
++ * This writes "bitlen" bits out the SPI MOSI port and simultaneously clocks
++ * "bitlen" bits in the SPI MISO port. That's just the way SPI works.
++ *
++ * The source of the outgoing bits is the "dout" parameter and the
++ * destination of the input bits is the "din" parameter. Note that "dout"
++ * and "din" can point to the same memory location, in which case the
++ * input data overwrites the output data (since both are buffered by
++ * temporary variables, this is OK).
++ *
++ * spi_xfer() interface:
++ * @slave: The SPI slave which will be sending/receiving the data.
++ * @bitlen: How many bits to write and read.
++ * @dout: Pointer to a string of bits to send out. The bits are
++ * held in a byte array and are sent MSB first.
++ * @din: Pointer to a string of bits that will be filled in.
++ * @flags: A bitwise combination of SPI_XFER_* flags.
++ *
++ * Returns: 0 on success, not 0 on failure
++ */
++int spi_xfer(struct spi_slave *slave, unsigned int bitlen, const void *dout,
++ void *din, unsigned long flags);
++
++/**
++ * Determine if a SPI chipselect is valid.
++ * This function is provided by the board if the low-level SPI driver
++ * needs it to determine if a given chipselect is actually valid.
++ *
++ * Returns: 1 if bus:cs identifies a valid chip on this board, 0
++ * otherwise.
++ */
++int spi_cs_is_valid(unsigned int bus, unsigned int cs);
++
++#ifndef CONFIG_DM_SPI
++/**
++ * Activate a SPI chipselect.
++ * This function is provided by the board code when using a driver
++ * that can't control its chipselects automatically (e.g.
++ * common/soft_spi.c). When called, it should activate the chip select
++ * to the device identified by "slave".
++ */
++void spi_cs_activate(struct spi_slave *slave);
++
++/**
++ * Deactivate a SPI chipselect.
++ * This function is provided by the board code when using a driver
++ * that can't control its chipselects automatically (e.g.
++ * common/soft_spi.c). When called, it should deactivate the chip
++ * select to the device identified by "slave".
++ */
++void spi_cs_deactivate(struct spi_slave *slave);
++
++/**
++ * Set transfer speed.
++ * This sets a new speed to be applied for next spi_xfer().
++ * @slave: The SPI slave
++ * @hz: The transfer speed
++ */
++void spi_set_speed(struct spi_slave *slave, uint hz);
++#endif
++
++
++/**
++ * Set up a SPI slave for a particular device tree node
++ *
++ * This calls spi_setup_slave() with the correct bus number. Call
++ * spi_free_slave() to free it later.
++ *
++ * @param blob: Device tree blob
++ * @param slave_node: Slave node to use
++ * @param spi_node: SPI peripheral node to use
++ * @return pointer to new spi_slave structure
++ */
++struct spi_slave *spi_setup_slave_fdt(const void *blob, int slave_node,
++ int spi_node);
++
++/* QSPI Flash Read/Write function */
++void spi_set_addr(uint32_t addr);
++int spi_xfer_cmd(struct spi_slave *slave, int cmd_no);
++void WaitRpcTxEnd(void);
++void WaitReadyDevice(struct spi_slave *slave);
++int spi_get_read_status(struct spi_slave *slave, u8 *rs);
++
++#endif /* _R_CAR_GEN3_QSPI_H_ */
+diff --git a/include/linux/bitops.h b/include/linux/bitops.h
+index e724310..3bf04d2 100644
+--- a/include/linux/bitops.h
++++ b/include/linux/bitops.h
+@@ -104,6 +104,7 @@ static inline unsigned int generic_hweight8(unsigned int w)
+ return (res & 0x0F) + ((res >> 4) & 0x0F);
+ }
+
++#define BIT(nr) (1UL << (nr))
+ #define BIT_MASK(nr) (1UL << ((nr) % BITS_PER_LONG))
+ #define BIT_WORD(nr) ((nr) / BITS_PER_LONG)
+
+diff --git a/include/spi.h b/include/spi.h
+index c58e453..d6978c7 100644
+--- a/include/spi.h
++++ b/include/spi.h
+@@ -11,18 +11,24 @@
+ #define _SPI_H_
+
+ /* SPI mode flags */
+-#define SPI_CPHA 0x01 /* clock phase */
+-#define SPI_CPOL 0x02 /* clock polarity */
++#define SPI_CPHA BIT(0) /* clock phase */
++#define SPI_CPOL BIT(1) /* clock polarity */
+ #define SPI_MODE_0 (0|0) /* (original MicroWire) */
+ #define SPI_MODE_1 (0|SPI_CPHA)
+ #define SPI_MODE_2 (SPI_CPOL|0)
+ #define SPI_MODE_3 (SPI_CPOL|SPI_CPHA)
+-#define SPI_CS_HIGH 0x04 /* CS active high */
+-#define SPI_LSB_FIRST 0x08 /* per-word bits-on-wire */
+-#define SPI_3WIRE 0x10 /* SI/SO signals shared */
+-#define SPI_LOOP 0x20 /* loopback mode */
+-#define SPI_SLAVE 0x40 /* slave mode */
+-#define SPI_PREAMBLE 0x80 /* Skip preamble bytes */
++#define SPI_CS_HIGH BIT(2) /* CS active high */
++#define SPI_LSB_FIRST BIT(3) /* per-word bits-on-wire */
++#define SPI_3WIRE BIT(4) /* SI/SO signals shared */
++#define SPI_LOOP BIT(5) /* loopback mode */
++#define SPI_SLAVE BIT(6) /* slave mode */
++#define SPI_PREAMBLE BIT(7) /* Skip preamble bytes */
++#define SPI_TX_BYTE BIT(8) /* transmit with 1 wire byte */
++#define SPI_TX_DUAL BIT(9) /* transmit with 2 wires */
++#define SPI_TX_QUAD BIT(10) /* transmit with 4 wires */
++#define SPI_RX_SLOW BIT(11) /* receive with 1 wire slow */
++#define SPI_RX_DUAL BIT(12) /* receive with 2 wires */
++#define SPI_RX_QUAD BIT(13) /* receive with 4 wires */
+
+ /* SPI transfer flags */
+ #define SPI_XFER_BEGIN 0x01 /* Assert CS before transfer */
+--
+1.9.1
diff --git a/meta-rcar-gen3-adas/recipes-bsp/u-boot/u-boot/0014-arm-renesas-Add-Renesas-R8A7797-SoC-support.patch b/meta-rcar-gen3-adas/recipes-bsp/u-boot/u-boot/0014-arm-renesas-Add-Renesas-R8A7797-SoC-support.patch
new file mode 100644
index 0000000..8545634
--- /dev/null
+++ b/meta-rcar-gen3-adas/recipes-bsp/u-boot/u-boot/0014-arm-renesas-Add-Renesas-R8A7797-SoC-support.patch
@@ -0,0 +1,3542 @@
+From 02cc2edc21e6c6895cf0304beecae4d990225ea2 Mon Sep 17 00:00:00 2001
+From: Daisuke Matsushita <daisuke.matsushita.ns@hitachi.com>
+Date: Tue, 21 Mar 2017 15:05:15 +0900
+Subject: [PATCH] arm: renesas: Add Renesas R8A7797 SoC support
+
+This adds Renesas R8A7797 SoC support
+
+Signed-off-by: Vladimir Barinov <vladimir.barinov@cogentembedded.com>
+---
+ arch/arm/cpu/armv8/Kconfig | 3 +
+ arch/arm/cpu/armv8/rcar_gen3/Makefile | 3 +
+ arch/arm/cpu/armv8/rcar_gen3/cpu_info-r8a7797.c | 39 +
+ arch/arm/cpu/armv8/rcar_gen3/cpu_info.c | 8 +
+ arch/arm/cpu/armv8/rcar_gen3/pfc-r8a7797.c | 2764 ++++++++++++++++++++
+ arch/arm/cpu/armv8/rcar_gen3/pfc.c | 2 +
+ arch/arm/cpu/armv8/rcar_gen3/prr_depend.c | 27 +
+ arch/arm/include/asm/arch-rcar_gen3/gpio.h | 4 +
+ arch/arm/include/asm/arch-rcar_gen3/r8a7797-gpio.h | 456 ++++
+ arch/arm/include/asm/arch-rcar_gen3/r8a7797.h | 33 +
+ arch/arm/include/asm/arch-rcar_gen3/rcar-base.h | 5 +
+ arch/arm/include/asm/arch-rcar_gen3/rcar_gen3.h | 2 +
+ drivers/serial/serial_sh.h | 3 +-
+ include/configs/rcar-gen3-common.h | 12 +
+ 14 files changed, 3360 insertions(+), 1 deletion(-)
+ create mode 100644 arch/arm/cpu/armv8/rcar_gen3/cpu_info-r8a7797.c
+ create mode 100644 arch/arm/cpu/armv8/rcar_gen3/pfc-r8a7797.c
+ create mode 100644 arch/arm/include/asm/arch-rcar_gen3/r8a7797-gpio.h
+ create mode 100644 arch/arm/include/asm/arch-rcar_gen3/r8a7797.h
+
+diff --git a/arch/arm/cpu/armv8/Kconfig b/arch/arm/cpu/armv8/Kconfig
+index 01646e9..dfd9bab 100644
+--- a/arch/arm/cpu/armv8/Kconfig
++++ b/arch/arm/cpu/armv8/Kconfig
+@@ -35,6 +35,9 @@ config R8A77965
+ bool "Renesas SoC R8A77965"
+ select R8A7796X
+
++config R8A7797
++ bool "Renesas SoC R8A7797"
++
+ endchoice
+
+ config SYS_SOC
+diff --git a/arch/arm/cpu/armv8/rcar_gen3/Makefile b/arch/arm/cpu/armv8/rcar_gen3/Makefile
+index 01ecaa1..a7a8f79 100644
+--- a/arch/arm/cpu/armv8/rcar_gen3/Makefile
++++ b/arch/arm/cpu/armv8/rcar_gen3/Makefile
+@@ -15,3 +15,6 @@ obj-$(CONFIG_R8A7795) += lowlevel_init.o cpu_info-r8a7795.o \
+ obj-$(CONFIG_R8A7796X) += lowlevel_init.o cpu_info-r8a7796.o \
+ pfc.o pfc-r8a7796.o prr_depend.o \
+ board.o
++obj-$(CONFIG_R8A7797) += lowlevel_init.o cpu_info-r8a7797.o \
++ pfc.o pfc-r8a7797.o prr_depend.o \
++ board.o
+diff --git a/arch/arm/cpu/armv8/rcar_gen3/cpu_info-r8a7797.c b/arch/arm/cpu/armv8/rcar_gen3/cpu_info-r8a7797.c
+new file mode 100644
+index 0000000..cc8e1e6
+--- /dev/null
++++ b/arch/arm/cpu/armv8/rcar_gen3/cpu_info-r8a7797.c
+@@ -0,0 +1,39 @@
++/*
++ * arch/arm/cpu/armv8/rcar_gen3/cpu_info-r8a7797.c
++ * This file defines cpu information funstions.
++ *
++ * Copyright (C) 2016 Renesas Electronics Corporation
++ *
++ * SPDX-License-Identifier: GPL-2.0+
++ */
++#include <common.h>
++#include <asm/io.h>
++
++#define PRR 0xFFF00044
++
++u32 rcar_get_cpu_type(void)
++{
++ u32 product;
++
++ product = readl(PRR);
++
++ return (product & 0x00007F00) >> 8;
++}
++
++u32 rcar_get_cpu_rev_integer(void)
++{
++ u32 product;
++
++ product = readl(PRR);
++
++ return (u32)(((product & 0x000000F0) >> 4) + 1);
++}
++
++u32 rcar_get_cpu_rev_fraction(void)
++{
++ u32 product;
++
++ product = readl(PRR);
++
++ return (u32)(product & 0x0000000F);
++}
+diff --git a/arch/arm/cpu/armv8/rcar_gen3/cpu_info.c b/arch/arm/cpu/armv8/rcar_gen3/cpu_info.c
+index 1a699e4..0046c75 100644
+--- a/arch/arm/cpu/armv8/rcar_gen3/cpu_info.c
++++ b/arch/arm/cpu/armv8/rcar_gen3/cpu_info.c
+@@ -81,6 +81,14 @@ int print_cpuinfo(void)
+ CONFIG_RCAR_TARGET_STRING);
+ }
+ break;
++ case 0x54:
++ printf("CPU: Renesas Electronics R8A7797 rev %d.%d\n",
++ rev_integer, rev_fraction);
++ if (strcmp(CONFIG_RCAR_TARGET_STRING, "r8a7797")) {
++ printf("Warning: this code supports only %s\n",
++ CONFIG_RCAR_TARGET_STRING);
++ }
++ break;
+ }
+ return 0;
+ }
+diff --git a/arch/arm/cpu/armv8/rcar_gen3/pfc-r8a7797.c b/arch/arm/cpu/armv8/rcar_gen3/pfc-r8a7797.c
+new file mode 100644
+index 0000000..3b2f75e
+--- /dev/null
++++ b/arch/arm/cpu/armv8/rcar_gen3/pfc-r8a7797.c
+@@ -0,0 +1,2764 @@
++/*
++ * arch/arm/cpu/armv8/rcar_gen3/pfc-r8a7797.c
++ * This file is r8a7797 processor support - PFC hardware block.
++ *
++ * Copyright (C) 2016 Renesas Electronics Corporation
++ *
++ * SPDX-License-Identifier: GPL-2.0+
++ */
++
++#include <common.h>
++#include <sh_pfc.h>
++#include <asm/gpio.h>
++
++#define CPU_32_PORT(fn, pfx, sfx) \
++ PORT_10(fn, pfx, sfx), PORT_10(fn, pfx##1, sfx), \
++ PORT_10(fn, pfx##2, sfx), PORT_1(fn, pfx##30, sfx), \
++ PORT_1(fn, pfx##31, sfx)
++
++#define CPU_32_PORT1(fn, pfx, sfx) \
++ PORT_10(fn, pfx, sfx), PORT_10(fn, pfx##1, sfx), \
++ PORT_10(fn, pfx##2, sfx)
++
++#define CPU_32_PORT2(fn, pfx, sfx) \
++ PORT_10(fn, pfx, sfx), PORT_10(fn, pfx##1, sfx), \
++ PORT_10(fn, pfx##2, sfx)
++
++#define CPU_32_PORT_28(fn, pfx, sfx) \
++ PORT_10(fn, pfx, sfx), \
++ PORT_10(fn, pfx##1, sfx), \
++ PORT_1(fn, pfx##20, sfx), \
++ PORT_1(fn, pfx##21, sfx), \
++ PORT_1(fn, pfx##22, sfx), \
++ PORT_1(fn, pfx##23, sfx), \
++ PORT_1(fn, pfx##24, sfx), \
++ PORT_1(fn, pfx##25, sfx), \
++ PORT_1(fn, pfx##26, sfx), \
++ PORT_1(fn, pfx##27, sfx)
++
++#define CPU_32_PORT_22(fn, pfx, sfx) \
++ PORT_10(fn, pfx, sfx), \
++ PORT_10(fn, pfx##1, sfx), \
++ PORT_1(fn, pfx##20, sfx), \
++ PORT_1(fn, pfx##21, sfx)
++
++#define CPU_32_PORT_17(fn, pfx, sfx) \
++ PORT_10(fn, pfx, sfx), \
++ PORT_1(fn, pfx##10, sfx), \
++ PORT_1(fn, pfx##11, sfx), \
++ PORT_1(fn, pfx##12, sfx), \
++ PORT_1(fn, pfx##13, sfx), \
++ PORT_1(fn, pfx##14, sfx), \
++ PORT_1(fn, pfx##15, sfx), \
++ PORT_1(fn, pfx##16, sfx)
++
++#define CPU_32_PORT_15(fn, pfx, sfx) \
++ PORT_10(fn, pfx, sfx), \
++ PORT_1(fn, pfx##10, sfx), \
++ PORT_1(fn, pfx##11, sfx), \
++ PORT_1(fn, pfx##12, sfx), \
++ PORT_1(fn, pfx##13, sfx), \
++ PORT_1(fn, pfx##14, sfx)
++
++#define CPU_32_PORT_6(fn, pfx, sfx) \
++ PORT_1(fn, pfx##0, sfx), \
++ PORT_1(fn, pfx##1, sfx), \
++ PORT_1(fn, pfx##2, sfx), \
++ PORT_1(fn, pfx##3, sfx), \
++ PORT_1(fn, pfx##4, sfx), \
++ PORT_1(fn, pfx##5, sfx)
++
++
++/* --gen3-- */
++/* GP_0_0_DATA -> GP_5_14_DATA */
++/* except for GP0[22] - [31],
++ GP1[28] - [31],
++ GP2[17] - [31],
++ GP3[17] - [31],
++ GP4[6] - [31],
++ GP5[15] - [31], */
++
++#define CPU_ALL_PORT(fn, pfx, sfx) \
++ CPU_32_PORT_22(fn, pfx##_0_, sfx), \
++ CPU_32_PORT_28(fn, pfx##_1_, sfx), \
++ CPU_32_PORT_17(fn, pfx##_2_, sfx), \
++ CPU_32_PORT_17(fn, pfx##_3_, sfx), \
++ CPU_32_PORT_6(fn, pfx##_4_, sfx), \
++ CPU_32_PORT_15(fn, pfx##_5_, sfx)
++
++#define _GP_GPIO(pfx, sfx) PINMUX_GPIO(GPIO_GP##pfx, GP##pfx##_DATA)
++#define _GP_DATA(pfx, sfx) PINMUX_DATA(GP##pfx##_DATA, GP##pfx##_FN, \
++ GP##pfx##_IN, GP##pfx##_OUT)
++
++#define _GP_INOUTSEL(pfx, sfx) GP##pfx##_IN, GP##pfx##_OUT
++#define _GP_INDT(pfx, sfx) GP##pfx##_DATA
++
++#define GP_ALL(str) CPU_ALL_PORT(_PORT_ALL, GP, str)
++#define PINMUX_GPIO_GP_ALL() CPU_ALL_PORT(_GP_GPIO, , unused)
++#define PINMUX_DATA_GP_ALL() CPU_ALL_PORT(_GP_DATA, , unused)
++
++
++#define PORT_10_REV(fn, pfx, sfx) \
++ PORT_1(fn, pfx##9, sfx), PORT_1(fn, pfx##8, sfx), \
++ PORT_1(fn, pfx##7, sfx), PORT_1(fn, pfx##6, sfx), \
++ PORT_1(fn, pfx##5, sfx), PORT_1(fn, pfx##4, sfx), \
++ PORT_1(fn, pfx##3, sfx), PORT_1(fn, pfx##2, sfx), \
++ PORT_1(fn, pfx##1, sfx), PORT_1(fn, pfx##0, sfx)
++
++#define CPU_32_PORT_REV(fn, pfx, sfx) \
++ PORT_1(fn, pfx##31, sfx), PORT_1(fn, pfx##30, sfx), \
++ PORT_10_REV(fn, pfx##2, sfx), PORT_10_REV(fn, pfx##1, sfx), \
++ PORT_10_REV(fn, pfx, sfx)
++
++#define GP_INOUTSEL(bank) CPU_32_PORT_REV(_GP_INOUTSEL, _##bank##_, unused)
++#define GP_INDT(bank) CPU_32_PORT_REV(_GP_INDT, _##bank##_, unused)
++
++#define PINMUX_IPSR_IDATA(fn) PINMUX_DATA(fn##_IMARK, GFN_##fn, IFN_##fn)
++#define PINMUX_IPSR_DATA(ipsr, fn) PINMUX_DATA(fn##_MARK, GFN_##ipsr, FN_##fn)
++#define PINMUX_IPSR_MODSEL_DATA(ipsr, fn, ms) PINMUX_DATA(fn##_MARK, FN_##ms, \
++ FN_##ipsr, FN_##fn)
++
++enum {
++ PINMUX_RESERVED = 0,
++
++ PINMUX_DATA_BEGIN,
++ GP_ALL(DATA),
++ PINMUX_DATA_END,
++
++ PINMUX_INPUT_BEGIN,
++ GP_ALL(IN),
++ PINMUX_INPUT_END,
++
++ PINMUX_OUTPUT_BEGIN,
++ GP_ALL(OUT),
++ PINMUX_OUTPUT_END,
++
++ PINMUX_FUNCTION_BEGIN,
++ GP_ALL(FN),
++
++ /* GPSR0 */
++ GFN_DU_EXODDF_DU_ODDF_DISP_CDE,
++ GFN_DU_EXVSYNC_DU_VSYNC,
++ GFN_DU_EXHSYNC_DU_HSYNC,
++ GFN_DU_DOTCLKOUT,
++ GFN_DU_DB7,
++ GFN_DU_DB6,
++ GFN_DU_DB5,
++ GFN_DU_DB4,
++ GFN_DU_DB3,
++ GFN_DU_DB2,
++ GFN_DU_DG7,
++ GFN_DU_DG6,
++ GFN_DU_DG5,
++ GFN_DU_DG4,
++ GFN_DU_DG3,
++ GFN_DU_DG2,
++ GFN_DU_DR7,
++ GFN_DU_DR6,
++ GFN_DU_DR5,
++ GFN_DU_DR4,
++ GFN_DU_DR3,
++ GFN_DU_DR2,
++
++ /* GPSR1 */
++ GFN_DIGRF_CLKOUT,
++ GFN_DIGRF_CLKIN,
++ GFN_CANFD_CLK_A,
++ GFN_CANFD1_RX,
++ GFN_CANFD1_TX,
++ GFN_CANFD0_RX_A,
++ GFN_CANFD0_TX_A,
++ GFN_AVB0_AVTP_CAPTURE,
++ FN_AVB0_AVTP_MATCH,
++ FN_AVB0_LINK,
++ FN_AVB0_PHY_INT,
++ FN_AVB0_MAGIC,
++ FN_AVB0_MDC,
++ FN_AVB0_MDIO,
++ FN_AVB0_TXCREFCLK,
++ FN_AVB0_TD3,
++ FN_AVB0_TD2,
++ FN_AVB0_TD1,
++ FN_AVB0_TD0,
++ FN_AVB0_TXC,
++ FN_AVB0_TX_CTL,
++ FN_AVB0_RD3,
++ FN_AVB0_RD2,
++ FN_AVB0_RD1,
++ FN_AVB0_RD0,
++ FN_AVB0_RXC,
++ FN_AVB0_RX_CTL,
++ GFN_IRQ0,
++
++ /* GPSR2 */
++ GFN_VI0_FIELD,
++ GFN_VI0_DATA11,
++ GFN_VI0_DATA10,
++ GFN_VI0_DATA9,
++ GFN_VI0_DATA8,
++ GFN_VI0_DATA7,
++ GFN_VI0_DATA6,
++ GFN_VI0_DATA5,
++ GFN_VI0_DATA4,
++ GFN_VI0_DATA3,
++ GFN_VI0_DATA2,
++ GFN_VI0_DATA1,
++ GFN_VI0_DATA0,
++ GFN_VI0_VSYNC_N,
++ GFN_VI0_HSYNC_N,
++ GFN_VI0_CLKENB,
++ GFN_VI0_CLK,
++
++ /* GPSR3 */
++ GFN_VI1_FIELD,
++ GFN_VI1_DATA11,
++ GFN_VI1_DATA10,
++ GFN_VI1_DATA9,
++ GFN_VI1_DATA8,
++ GFN_VI1_DATA7,
++ GFN_VI1_DATA6,
++ GFN_VI1_DATA5,
++ GFN_VI1_DATA4,
++ GFN_VI1_DATA3,
++ GFN_VI1_DATA2,
++ GFN_VI1_DATA1,
++ GFN_VI1_DATA0,
++ GFN_VI1_VSYNC_N,
++ GFN_VI1_HSYNC_N,
++ GFN_VI1_CLKENB,
++ GFN_VI1_CLK,
++
++ /* GPSR4 */
++ GFN_SDA2,
++ GFN_SCL2,
++ GFN_SDA1,
++ GFN_SCL1,
++ GFN_SDA0,
++ GFN_SCL0,
++
++ /* GPSR5 */
++ FN_RPC_INT_N,
++ FN_RPC_WP_N,
++ FN_RPC_RESET_N,
++ FN_QSPI1_SSL,
++ FN_QSPI1_IO3,
++ FN_QSPI1_IO2,
++ FN_QSPI1_MISO_IO1,
++ FN_QSPI1_MOSI_IO0,
++ FN_QSPI1_SPCLK,
++ FN_QSPI0_SSL,
++ FN_QSPI0_IO3,
++ FN_QSPI0_IO2,
++ FN_QSPI0_MISO_IO1,
++ FN_QSPI0_MOSI_IO0,
++ FN_QSPI0_SPCLK,
++
++ /* IPSR0 */
++ IFN_DU_DR2,
++ FN_HSCK0,
++ FN_A0,
++ IFN_DU_DR3,
++ FN_HRTS0_N,
++ FN_A1,
++ IFN_DU_DR4,
++ FN_HCTS0_N,
++ FN_A2,
++ IFN_DU_DR5,
++ FN_HTX0,
++ FN_A3,
++ IFN_DU_DR6,
++ FN_MSIOF3_RXD,
++ FN_A4,
++ IFN_DU_DR7,
++ FN_MSIOF3_TXD,
++ FN_A5,
++ IFN_DU_DG2,
++ FN_MSIOF3_SS1,
++ FN_A6,
++ IFN_DU_DG3,
++ FN_MSIOF3_SS2,
++ FN_A7,
++ FN_PWMFSW0,
++
++ /* IPSR1 */
++ IFN_DU_DG4,
++ FN_A8,
++ FN_FSO_CFE_0_N_A,
++ IFN_DU_DG5,
++ FN_A9,
++ FN_FSO_CFE_1_N_A,
++ IFN_DU_DG6,
++ FN_A10,
++ FN_FSO_TOE_N_A,
++ IFN_DU_DG7,
++ FN_A11,
++ FN_IRQ1,
++ IFN_DU_DB2,
++ FN_A12,
++ FN_IRQ2,
++ IFN_DU_DB3,
++ FN_A13,
++ FN_FXR_CLKOUT1,
++ IFN_DU_DB4,
++ FN_A14,
++ FN_FXR_CLKOUT2,
++ IFN_DU_DB5,
++ FN_A15,
++ FN_FXR_TXENA_N,
++
++ /* IPSR2 */
++ IFN_DU_DB6,
++ FN_A16,
++ FN_FXR_TXENB_N,
++ IFN_DU_DB7,
++ FN_A17,
++ FN_STPWT_EXTFXR,
++ IFN_DU_DOTCLKOUT,
++ FN_SCIF_CLK_A,
++ FN_A18,
++ IFN_DU_EXHSYNC_DU_HSYNC,
++ FN_HRX0,
++ FN_A19,
++ FN_IRQ3,
++ IFN_DU_EXVSYNC_DU_VSYNC,
++ FN_MSIOF3_SCK,
++ FN_A20,
++ IFN_DU_EXODDF_DU_ODDF_DISP_CDE,
++ FN_MSIOF3_SYNC,
++ FN_A21,
++ IFN_IRQ0,
++ FN_CC5_OSCOUT,
++ IFN_VI0_CLK,
++ FN_MSIOF2_SCK,
++ FN_SCK3,
++ FN_HSCK3,
++
++ /* IPSR3 */
++ IFN_VI0_CLKENB,
++ FN_MSIOF2_RXD,
++ FN_RX3,
++ FN_RD_WR_N,
++ FN_HCTS3_N,
++ IFN_VI0_HSYNC_N,
++ FN_MSIOF2_TXD,
++ FN_TX3,
++ FN_HRTS3_N,
++ IFN_VI0_VSYNC_N,
++ FN_MSIOF2_SYNC,
++ FN_CTS3_N,
++ FN_HTX3,
++ IFN_VI0_DATA0,
++ FN_MSIOF2_SS1,
++ FN_RTS3_N_TANS,
++ FN_HRX3,
++ IFN_VI0_DATA1,
++ FN_MSIOF2_SS2,
++ FN_SCK1,
++ FN_SPEEDIN_A,
++ IFN_VI0_DATA2,
++ FN_AVB0_AVTP_PPS,
++ FN_SDA3_A,
++ IFN_VI0_DATA3,
++ FN_HSCK1,
++ FN_SCL3_A,
++ IFN_VI0_DATA4,
++ FN_HRTS1_N,
++ FN_RX1_A,
++
++ /* IPSR4 */
++ IFN_VI0_DATA5,
++ FN_HCTS1_N,
++ FN_TX1_A,
++ IFN_VI0_DATA6,
++ FN_HTX1,
++ FN_CTS1_N,
++ IFN_VI0_DATA7,
++ FN_HRX1,
++ FN_RTS1_N_TANS,
++ IFN_VI0_DATA8,
++ FN_HSCK2,
++ FN_PWM0_A,
++ FN_A22,
++ IFN_VI0_DATA9,
++ FN_HCTS2_N,
++ FN_PWM1_A,
++ FN_A23,
++ FN_FSO_CFE_0_N_B,
++ IFN_VI0_DATA10,
++ FN_HRTS2_N,
++ FN_PWM2_A,
++ FN_A24,
++ FN_FSO_CFE_1_N_B,
++ IFN_VI0_DATA11,
++ FN_HTX2,
++ FN_PWM3_A,
++ FN_A25,
++ FN_FSO_TOE_N_B,
++ IFN_VI0_FIELD,
++ FN_HRX2,
++ FN_PWM4_A,
++ FN_CS1_N_A26,
++ FN_FSCLKST2_N_A,
++
++ /* IPSR5 */
++ IFN_VI1_CLK,
++ FN_MSIOF1_RXD,
++ FN_CS0_N,
++ IFN_VI1_CLKENB,
++ FN_MSIOF1_TXD,
++ FN_D0,
++ IFN_VI1_HSYNC_N,
++ FN_MSIOF1_SCK,
++ FN_D1,
++ IFN_VI1_VSYNC_N,
++ FN_MSIOF1_SYNC,
++ FN_D2,
++ IFN_VI1_DATA0,
++ FN_MSIOF1_SS1,
++ FN_D3,
++ IFN_VI1_DATA1,
++ FN_MSIOF1_SS2,
++ FN_D4,
++ FN_MMC_CMD,
++ IFN_VI1_DATA2,
++ FN_CANFD0_TX_B,
++ FN_D5,
++ FN_MMC_D0,
++ IFN_VI1_DATA3,
++ FN_CANFD0_RX_B,
++ FN_D6,
++ FN_MMC_D1,
++
++ /* IPSR6 */
++ IFN_VI1_DATA4,
++ FN_CANFD_CLK_B,
++ FN_D7,
++ FN_MMC_D2,
++ IFN_VI1_DATA5,
++ FN_SCK4,
++ FN_D8,
++ FN_MMC_D3,
++ IFN_VI1_DATA6,
++ FN_RX4,
++ FN_D9,
++ FN_MMC_CLK,
++ IFN_VI1_DATA7,
++ FN_TX4,
++ FN_D10,
++ FN_MMC_D4,
++ IFN_VI1_DATA8,
++ FN_CTS4_N,
++ FN_D11,
++ FN_MMC_D5,
++ IFN_VI1_DATA9,
++ FN_RTS4_N_TANS,
++ FN_D12,
++ FN_MMC_D6,
++ FN_SCL3_B,
++ IFN_VI1_DATA10,
++ FN_D13,
++ FN_MMC_D7,
++ FN_SDA3_B,
++ IFN_VI1_DATA11,
++ FN_SCL4,
++ FN_IRQ4,
++ FN_D14,
++ FN_MMC_WP,
++
++ /* IPSR7 */
++ IFN_VI1_FIELD,
++ FN_SDA4,
++ FN_IRQ5,
++ FN_D15,
++ FN_MMC_CD,
++ IFN_SCL0,
++ FN_DU_DR0,
++ FN_TPU0TO0,
++ FN_CLKOUT,
++ FN_MSIOF0_RXD,
++ IFN_SDA0,
++ FN_DU_DR1,
++ FN_TPU0TO1,
++ FN_BS_N,
++ FN_SCK0,
++ FN_MSIOF0_TXD,
++ IFN_SCL1,
++ FN_DU_DG0,
++ FN_TPU0TO2,
++ FN_RD_N,
++ FN_CTS0_N,
++ FN_MSIOF0_SCK,
++ IFN_SDA1,
++ FN_DU_DG1,
++ FN_TPU0TO3,
++ FN_WE0_N,
++ FN_RTS0_N_TANS,
++ FN_MSIOF0_SYNC,
++ IFN_SCL2,
++ FN_DU_DB0,
++ FN_TCLK1_A,
++ FN_WE1_N,
++ FN_RX0,
++ FN_MSIOF0_SS1,
++ IFN_SDA2,
++ FN_DU_DB1,
++ FN_TCLK2_A,
++ FN_EX_WAIT0,
++ FN_TX0,
++ FN_MSIOF0_SS2,
++ IFN_AVB0_AVTP_CAPTURE,
++ FN_FSCLKST2_N_B,
++
++ /* IPSR8 */
++ IFN_CANFD0_TX_A,
++ FN_FXR_TXDA,
++ FN_PWM0_B,
++ FN_DU_DISP,
++ FN_FSCLKST2_N_C,
++ IFN_CANFD0_RX_A,
++ FN_RXDA_EXTFXR,
++ FN_PWM1_B,
++ FN_DU_CDE,
++ IFN_CANFD1_TX,
++ FN_FXR_TXDB,
++ FN_PWM2_B,
++ FN_TCLK1_B,
++ FN_TX1_B,
++ IFN_CANFD1_RX,
++ FN_RXDB_EXTFXR,
++ FN_PWM3_B,
++ FN_TCLK2_B,
++ FN_RX1_B,
++ IFN_CANFD_CLK_A,
++ FN_CLK_EXTFXR,
++ FN_PWM4_B,
++ FN_SPEEDIN_B,
++ FN_SCIF_CLK_B,
++ IFN_DIGRF_CLKIN,
++ FN_DIGRF_CLKEN_IN,
++ IFN_DIGRF_CLKOUT,
++ FN_DIGRF_CLKEN_OUT,
++
++ /* MOD_SEL0 */
++ FN_SEL_HSCIF0_0, FN_SEL_HSCIF0_1,
++ FN_SEL_SCIF1_0, FN_SEL_SCIF1_1,
++ FN_SEL_CANFD0_0, FN_SEL_CANFD0_1,
++ FN_SEL_PWM4_0, FN_SEL_PWM4_1,
++ FN_SEL_PWM3_0, FN_SEL_PWM3_1,
++ FN_SEL_PWM2_0, FN_SEL_PWM2_1,
++ FN_SEL_PWM1_0, FN_SEL_PWM1_1,
++ FN_SEL_PWM0_0, FN_SEL_PWM0_1,
++ FN_SEL_RFSO_0, FN_SEL_RFSO_1,
++ FN_SEL_RSP_0, FN_SEL_RSP_1,
++ FN_SEL_TMU_0, FN_SEL_TMU_1,
++
++ PINMUX_FUNCTION_END,
++
++ PINMUX_MARK_BEGIN,
++
++ /* GPSR0 */
++ DU_EXODDF_DU_ODDF_DISP_CDE_GMARK,
++ DU_EXVSYNC_DU_VSYNC_GMARK,
++ DU_EXHSYNC_DU_HSYNC_GMARK,
++ DU_DOTCLKOUT_GMARK,
++ DU_DB7_GMARK,
++ DU_DB6_GMARK,
++ DU_DB5_GMARK,
++ DU_DB4_GMARK,
++ DU_DB3_GMARK,
++ DU_DB2_GMARK,
++ DU_DG7_GMARK,
++ DU_DG6_GMARK,
++ DU_DG5_GMARK,
++ DU_DG4_GMARK,
++ DU_DG3_GMARK,
++ DU_DG2_GMARK,
++ DU_DR7_GMARK,
++ DU_DR6_GMARK,
++ DU_DR5_GMARK,
++ DU_DR4_GMARK,
++ DU_DR3_GMARK,
++ DU_DR2_GMARK,
++
++ /* GPSR1 */
++ DIGRF_CLKOUT_GMARK,
++ DIGRF_CLKIN_GMARK,
++ CANFD_CLK_A_GMARK,
++ CANFD1_RX_GMARK,
++ CANFD1_TX_GMARK,
++ CANFD0_RX_A_GMARK,
++ CANFD0_TX_A_GMARK,
++ AVB0_AVTP_CAPTURE_GMARK,
++ AVB0_AVTP_MATCH_MARK,
++ AVB0_LINK_MARK,
++ AVB0_PHY_INT_MARK,
++ AVB0_MAGIC_MARK,
++ AVB0_MDC_MARK,
++ AVB0_MDIO_MARK,
++ AVB0_TXCREFCLK_MARK,
++ AVB0_TD3_MARK,
++ AVB0_TD2_MARK,
++ AVB0_TD1_MARK,
++ AVB0_TD0_MARK,
++ AVB0_TXC_MARK,
++ AVB0_TX_CTL_MARK,
++ AVB0_RD3_MARK,
++ AVB0_RD2_MARK,
++ AVB0_RD1_MARK,
++ AVB0_RD0_MARK,
++ AVB0_RXC_MARK,
++ AVB0_RX_CTL_MARK,
++ IRQ0_GMARK,
++
++ /* GPSR2 */
++ VI0_FIELD_GMARK,
++ VI0_DATA11_GMARK,
++ VI0_DATA10_GMARK,
++ VI0_DATA9_GMARK,
++ VI0_DATA8_GMARK,
++ VI0_DATA7_GMARK,
++ VI0_DATA6_GMARK,
++ VI0_DATA5_GMARK,
++ VI0_DATA4_GMARK,
++ VI0_DATA3_GMARK,
++ VI0_DATA2_GMARK,
++ VI0_DATA1_GMARK,
++ VI0_DATA0_GMARK,
++ VI0_VSYNC_N_GMARK,
++ VI0_HSYNC_N_GMARK,
++ VI0_CLKENB_GMARK,
++ VI0_CLK_GMARK,
++
++ /* GPSR3 */
++ VI1_FIELD_GMARK,
++ VI1_DATA11_GMARK,
++ VI1_DATA10_GMARK,
++ VI1_DATA9_GMARK,
++ VI1_DATA8_GMARK,
++ VI1_DATA7_GMARK,
++ VI1_DATA6_GMARK,
++ VI1_DATA5_GMARK,
++ VI1_DATA4_GMARK,
++ VI1_DATA3_GMARK,
++ VI1_DATA2_GMARK,
++ VI1_DATA1_GMARK,
++ VI1_DATA0_GMARK,
++ VI1_VSYNC_N_GMARK,
++ VI1_HSYNC_N_GMARK,
++ VI1_CLKENB_GMARK,
++ VI1_CLK_GMARK,
++
++ /* GPSR4 */
++ SDA2_GMARK,
++ SCL2_GMARK,
++ SDA1_GMARK,
++ SCL1_GMARK,
++ SDA0_GMARK,
++ SCL0_GMARK,
++
++ /* GPSR5 */
++ RPC_INT_N_MARK,
++ RPC_WP_N_MARK,
++ RPC_RESET_N_MARK,
++ QSPI1_SSL_MARK,
++ QSPI1_IO3_MARK,
++ QSPI1_IO2_MARK,
++ QSPI1_MISO_IO1_MARK,
++ QSPI1_MOSI_IO0_MARK,
++ QSPI1_SPCLK_MARK,
++ QSPI0_SSL_MARK,
++ QSPI0_IO3_MARK,
++ QSPI0_IO2_MARK,
++ QSPI0_MISO_IO1_MARK,
++ QSPI0_MOSI_IO0_MARK,
++ QSPI0_SPCLK_MARK,
++
++ /* IPSR0 */
++ DU_DR2_IMARK,
++ HSCK0_MARK,
++ A0_MARK,
++ DU_DR3_IMARK,
++ HRTS0_N_MARK,
++ A1_MARK,
++ DU_DR4_IMARK,
++ HCTS0_N_MARK,
++ A2_MARK,
++ DU_DR5_IMARK,
++ HTX0_MARK,
++ A3_MARK,
++ DU_DR6_IMARK,
++ MSIOF3_RXD_MARK,
++ A4_MARK,
++ DU_DR7_IMARK,
++ MSIOF3_TXD_MARK,
++ A5_MARK,
++ DU_DG2_IMARK,
++ MSIOF3_SS1_MARK,
++ A6_MARK,
++ DU_DG3_IMARK,
++ MSIOF3_SS2_MARK,
++ A7_MARK,
++ PWMFSW0_MARK,
++
++ /* IPSR1 */
++ DU_DG4_IMARK,
++ A8_MARK,
++ FSO_CFE_0_N_A_MARK,
++ DU_DG5_IMARK,
++ A9_MARK,
++ FSO_CFE_1_N_A_MARK,
++ DU_DG6_IMARK,
++ A10_MARK,
++ FSO_TOE_N_A_MARK,
++ DU_DG7_IMARK,
++ A11_MARK,
++ IRQ1_MARK,
++ DU_DB2_IMARK,
++ A12_MARK,
++ IRQ2_MARK,
++ DU_DB3_IMARK,
++ A13_MARK,
++ FXR_CLKOUT1_MARK,
++ DU_DB4_IMARK,
++ A14_MARK,
++ FXR_CLKOUT2_MARK,
++ DU_DB5_IMARK,
++ A15_MARK,
++ FXR_TXENA_N_MARK,
++
++ /* IPSR2 */
++ DU_DB6_IMARK,
++ A16_MARK,
++ FXR_TXENB_N_MARK,
++ DU_DB7_IMARK,
++ A17_MARK,
++ STPWT_EXTFXR_MARK,
++ DU_DOTCLKOUT_IMARK,
++ SCIF_CLK_A_MARK,
++ A18_MARK,
++ DU_EXHSYNC_DU_HSYNC_IMARK,
++ HRX0_MARK,
++ A19_MARK,
++ IRQ3_MARK,
++ DU_EXVSYNC_DU_VSYNC_IMARK,
++ MSIOF3_SCK_MARK,
++ A20_MARK,
++ DU_EXODDF_DU_ODDF_DISP_CDE_IMARK,
++ MSIOF3_SYNC_MARK,
++ A21_MARK,
++ IRQ0_IMARK,
++ CC5_OSCOUT_MARK,
++ VI0_CLK_IMARK,
++ MSIOF2_SCK_MARK,
++ SCK3_MARK,
++ HSCK3_MARK,
++
++ /* IPSR3 */
++ VI0_CLKENB_IMARK,
++ MSIOF2_RXD_MARK,
++ RX3_MARK,
++ RD_WR_N_MARK,
++ HCTS3_N_MARK,
++ VI0_HSYNC_N_IMARK,
++ MSIOF2_TXD_MARK,
++ TX3_MARK,
++ HRTS3_N_MARK,
++ VI0_VSYNC_N_IMARK,
++ MSIOF2_SYNC_MARK,
++ CTS3_N_MARK,
++ HTX3_MARK,
++ VI0_DATA0_IMARK,
++ MSIOF2_SS1_MARK,
++ RTS3_N_TANS_MARK,
++ HRX3_MARK,
++ VI0_DATA1_IMARK,
++ MSIOF2_SS2_MARK,
++ SCK1_MARK,
++ SPEEDIN_A_MARK,
++ VI0_DATA2_IMARK,
++ AVB0_AVTP_PPS_MARK,
++ SDA3_A_MARK,
++ VI0_DATA3_IMARK,
++ HSCK1_MARK,
++ SCL3_A_MARK,
++ VI0_DATA4_IMARK,
++ HRTS1_N_MARK,
++ RX1_A_MARK,
++
++ /* IPSR4 */
++ VI0_DATA5_IMARK,
++ HCTS1_N_MARK,
++ TX1_A_MARK,
++ VI0_DATA6_IMARK,
++ HTX1_MARK,
++ CTS1_N_MARK,
++ VI0_DATA7_IMARK,
++ HRX1_MARK,
++ RTS1_N_TANS_MARK,
++ VI0_DATA8_IMARK,
++ HSCK2_MARK,
++ PWM0_A_MARK,
++ A22_MARK,
++ VI0_DATA9_IMARK,
++ HCTS2_N_MARK,
++ PWM1_A_MARK,
++ A23_MARK,
++ FSO_CFE_0_N_B_MARK,
++ VI0_DATA10_IMARK,
++ HRTS2_N_MARK,
++ PWM2_A_MARK,
++ A24_MARK,
++ FSO_CFE_1_N_B_MARK,
++ VI0_DATA11_IMARK,
++ HTX2_MARK,
++ PWM3_A_MARK,
++ A25_MARK,
++ FSO_TOE_N_B_MARK,
++ VI0_FIELD_IMARK,
++ HRX2_MARK,
++ PWM4_A_MARK,
++ CS1_N_A26_MARK,
++ FSCLKST2_N_A_MARK,
++
++ /* IPSR5 */
++ VI1_CLK_IMARK,
++ MSIOF1_RXD_MARK,
++ CS0_N_MARK,
++ VI1_CLKENB_IMARK,
++ MSIOF1_TXD_MARK,
++ D0_MARK,
++ VI1_HSYNC_N_IMARK,
++ MSIOF1_SCK_MARK,
++ D1_MARK,
++ VI1_VSYNC_N_IMARK,
++ MSIOF1_SYNC_MARK,
++ D2_MARK,
++ VI1_DATA0_IMARK,
++ MSIOF1_SS1_MARK,
++ D3_MARK,
++ VI1_DATA1_IMARK,
++ MSIOF1_SS2_MARK,
++ D4_MARK,
++ MMC_CMD_MARK,
++ VI1_DATA2_IMARK,
++ CANFD0_TX_B_MARK,
++ D5_MARK,
++ MMC_D0_MARK,
++ VI1_DATA3_IMARK,
++ CANFD0_RX_B_MARK,
++ D6_MARK,
++ MMC_D1_MARK,
++
++ /* IPSR6 */
++ VI1_DATA4_IMARK,
++ CANFD_CLK_B_MARK,
++ D7_MARK,
++ MMC_D2_MARK,
++ VI1_DATA5_IMARK,
++ SCK4_MARK,
++ D8_MARK,
++ MMC_D3_MARK,
++ VI1_DATA6_IMARK,
++ RX4_MARK,
++ D9_MARK,
++ MMC_CLK_MARK,
++ VI1_DATA7_IMARK,
++ TX4_MARK,
++ D10_MARK,
++ MMC_D4_MARK,
++ VI1_DATA8_IMARK,
++ CTS4_N_MARK,
++ D11_MARK,
++ MMC_D5_MARK,
++ VI1_DATA9_IMARK,
++ RTS4_N_TANS_MARK,
++ D12_MARK,
++ MMC_D6_MARK,
++ SCL3_B_MARK,
++ VI1_DATA10_IMARK,
++ D13_MARK,
++ MMC_D7_MARK,
++ SDA3_B_MARK,
++ VI1_DATA11_IMARK,
++ SCL4_MARK,
++ IRQ4_MARK,
++ D14_MARK,
++ MMC_WP_MARK,
++
++ /* IPSR7 */
++ VI1_FIELD_IMARK,
++ SDA4_MARK,
++ IRQ5_MARK,
++ D15_MARK,
++ MMC_CD_MARK,
++ SCL0_IMARK,
++ DU_DR0_MARK,
++ TPU0TO0_MARK,
++ CLKOUT_MARK,
++ MSIOF0_RXD_MARK,
++ SDA0_IMARK,
++ DU_DR1_MARK,
++ TPU0TO1_MARK,
++ BS_N_MARK,
++ SCK0_MARK,
++ MSIOF0_TXD_MARK,
++ SCL1_IMARK,
++ DU_DG0_MARK,
++ TPU0TO2_MARK,
++ RD_N_MARK,
++ CTS0_N_MARK,
++ MSIOF0_SCK_MARK,
++ SDA1_IMARK,
++ DU_DG1_MARK,
++ TPU0TO3_MARK,
++ WE0_N_MARK,
++ RTS0_N_TANS_MARK,
++ MSIOF0_SYNC_MARK,
++ SCL2_IMARK,
++ DU_DB0_MARK,
++ TCLK1_A_MARK,
++ WE1_N_MARK,
++ RX0_MARK,
++ MSIOF0_SS1_MARK,
++ SDA2_IMARK,
++ DU_DB1_MARK,
++ TCLK2_A_MARK,
++ EX_WAIT0_MARK,
++ TX0_MARK,
++ MSIOF0_SS2_MARK,
++ AVB0_AVTP_CAPTURE_IMARK,
++ FSCLKST2_N_B_MARK,
++
++ /* IPSR8 */
++ CANFD0_TX_A_IMARK,
++ FXR_TXDA_MARK,
++ PWM0_B_MARK,
++ DU_DISP_MARK,
++ FSCLKST2_N_C_MARK,
++ CANFD0_RX_A_IMARK,
++ RXDA_EXTFXR_MARK,
++ PWM1_B_MARK,
++ DU_CDE_MARK,
++ CANFD1_TX_IMARK,
++ FXR_TXDB_MARK,
++ PWM2_B_MARK,
++ TCLK1_B_MARK,
++ TX1_B_MARK,
++ CANFD1_RX_IMARK,
++ RXDB_EXTFXR_MARK,
++ PWM3_B_MARK,
++ TCLK2_B_MARK,
++ RX1_B_MARK,
++ CANFD_CLK_A_IMARK,
++ CLK_EXTFXR_MARK,
++ PWM4_B_MARK,
++ SPEEDIN_B_MARK,
++ SCIF_CLK_B_MARK,
++ DIGRF_CLKIN_IMARK,
++ DIGRF_CLKEN_IN_MARK,
++ DIGRF_CLKOUT_IMARK,
++ DIGRF_CLKEN_OUT_MARK,
++
++ PINMUX_MARK_END,
++};
++
++static pinmux_enum_t pinmux_data[] = {
++ PINMUX_DATA_GP_ALL(), /* PINMUX_DATA(GP_M_N_DATA, GP_M_N_FN...), */
++
++ /* GPSR0 */
++ PINMUX_DATA(DU_EXODDF_DU_ODDF_DISP_CDE_GMARK, GFN_DU_EXODDF_DU_ODDF_DISP_CDE),
++ PINMUX_DATA(DU_EXVSYNC_DU_VSYNC_GMARK, GFN_DU_EXVSYNC_DU_VSYNC),
++ PINMUX_DATA(DU_EXHSYNC_DU_HSYNC_GMARK, GFN_DU_EXHSYNC_DU_HSYNC),
++ PINMUX_DATA(DU_DOTCLKOUT_GMARK, GFN_DU_DOTCLKOUT),
++ PINMUX_DATA(DU_DB7_GMARK, GFN_DU_DB7),
++ PINMUX_DATA(DU_DB6_GMARK, GFN_DU_DB6),
++ PINMUX_DATA(DU_DB5_GMARK, GFN_DU_DB5),
++ PINMUX_DATA(DU_DB4_GMARK, GFN_DU_DB4),
++ PINMUX_DATA(DU_DB3_GMARK, GFN_DU_DB3),
++ PINMUX_DATA(DU_DB2_GMARK, GFN_DU_DB2),
++ PINMUX_DATA(DU_DG7_GMARK, GFN_DU_DG7),
++ PINMUX_DATA(DU_DG6_GMARK, GFN_DU_DG6),
++ PINMUX_DATA(DU_DG5_GMARK, GFN_DU_DG5),
++ PINMUX_DATA(DU_DG4_GMARK, GFN_DU_DG4),
++ PINMUX_DATA(DU_DG3_GMARK, GFN_DU_DG3),
++ PINMUX_DATA(DU_DG2_GMARK, GFN_DU_DG2),
++ PINMUX_DATA(DU_DR7_GMARK, GFN_DU_DR7),
++ PINMUX_DATA(DU_DR6_GMARK, GFN_DU_DR6),
++ PINMUX_DATA(DU_DR5_GMARK, GFN_DU_DR5),
++ PINMUX_DATA(DU_DR4_GMARK, GFN_DU_DR4),
++ PINMUX_DATA(DU_DR3_GMARK, GFN_DU_DR3),
++ PINMUX_DATA(DU_DR2_GMARK, GFN_DU_DR2),
++
++ /* GPSR1 */
++ PINMUX_DATA(DIGRF_CLKOUT_GMARK, GFN_DIGRF_CLKOUT),
++ PINMUX_DATA(DIGRF_CLKIN_GMARK, GFN_DIGRF_CLKIN),
++ PINMUX_DATA(CANFD_CLK_A_GMARK, GFN_CANFD_CLK_A),
++ PINMUX_DATA(CANFD1_RX_GMARK, GFN_CANFD1_RX),
++ PINMUX_DATA(CANFD1_TX_GMARK, GFN_CANFD1_TX),
++ PINMUX_DATA(CANFD0_RX_A_GMARK, GFN_CANFD0_RX_A),
++ PINMUX_DATA(CANFD0_TX_A_GMARK, GFN_CANFD0_TX_A),
++ PINMUX_DATA(AVB0_AVTP_CAPTURE_GMARK, GFN_AVB0_AVTP_CAPTURE),
++ PINMUX_DATA(AVB0_AVTP_MATCH_MARK, FN_AVB0_AVTP_MATCH),
++ PINMUX_DATA(AVB0_LINK_MARK, FN_AVB0_LINK),
++ PINMUX_DATA(AVB0_PHY_INT_MARK, FN_AVB0_PHY_INT),
++ PINMUX_DATA(AVB0_MAGIC_MARK, FN_AVB0_MAGIC),
++ PINMUX_DATA(AVB0_MDC_MARK, FN_AVB0_MDC),
++ PINMUX_DATA(AVB0_MDIO_MARK, FN_AVB0_MDIO),
++ PINMUX_DATA(AVB0_TXCREFCLK_MARK, FN_AVB0_TXCREFCLK),
++ PINMUX_DATA(AVB0_TD3_MARK, FN_AVB0_TD3),
++ PINMUX_DATA(AVB0_TD2_MARK, FN_AVB0_TD2),
++ PINMUX_DATA(AVB0_TD1_MARK, FN_AVB0_TD1),
++ PINMUX_DATA(AVB0_TD0_MARK, FN_AVB0_TD0),
++ PINMUX_DATA(AVB0_TXC_MARK, FN_AVB0_TXC),
++ PINMUX_DATA(AVB0_TX_CTL_MARK, FN_AVB0_TX_CTL),
++ PINMUX_DATA(AVB0_RD3_MARK, FN_AVB0_RD3),
++ PINMUX_DATA(AVB0_RD2_MARK, FN_AVB0_RD2),
++ PINMUX_DATA(AVB0_RD1_MARK, FN_AVB0_RD1),
++ PINMUX_DATA(AVB0_RD0_MARK, FN_AVB0_RD0),
++ PINMUX_DATA(AVB0_RXC_MARK, FN_AVB0_RXC),
++ PINMUX_DATA(AVB0_RX_CTL_MARK, FN_AVB0_RX_CTL),
++ PINMUX_DATA(IRQ0_GMARK, GFN_IRQ0),
++
++ /* GPSR2 */
++ PINMUX_DATA(VI0_FIELD_GMARK, GFN_VI0_FIELD),
++ PINMUX_DATA(VI0_DATA11_GMARK, GFN_VI0_DATA11),
++ PINMUX_DATA(VI0_DATA10_GMARK, GFN_VI0_DATA10),
++ PINMUX_DATA(VI0_DATA9_GMARK, GFN_VI0_DATA9),
++ PINMUX_DATA(VI0_DATA8_GMARK, GFN_VI0_DATA8),
++ PINMUX_DATA(VI0_DATA7_GMARK, GFN_VI0_DATA7),
++ PINMUX_DATA(VI0_DATA6_GMARK, GFN_VI0_DATA6),
++ PINMUX_DATA(VI0_DATA5_GMARK, GFN_VI0_DATA5),
++ PINMUX_DATA(VI0_DATA4_GMARK, GFN_VI0_DATA4),
++ PINMUX_DATA(VI0_DATA3_GMARK, GFN_VI0_DATA3),
++ PINMUX_DATA(VI0_DATA2_GMARK, GFN_VI0_DATA2),
++ PINMUX_DATA(VI0_DATA1_GMARK, GFN_VI0_DATA1),
++ PINMUX_DATA(VI0_DATA0_GMARK, GFN_VI0_DATA0),
++ PINMUX_DATA(VI0_VSYNC_N_GMARK, GFN_VI0_VSYNC_N),
++ PINMUX_DATA(VI0_HSYNC_N_GMARK, GFN_VI0_HSYNC_N),
++ PINMUX_DATA(VI0_CLKENB_GMARK, GFN_VI0_CLKENB),
++ PINMUX_DATA(VI0_CLK_GMARK, GFN_VI0_CLK),
++
++ /* GPSR3 */
++ PINMUX_DATA(VI1_FIELD_GMARK, GFN_VI1_FIELD),
++ PINMUX_DATA(VI1_DATA11_GMARK, GFN_VI1_DATA11),
++ PINMUX_DATA(VI1_DATA10_GMARK, GFN_VI1_DATA10),
++ PINMUX_DATA(VI1_DATA9_GMARK, GFN_VI1_DATA9),
++ PINMUX_DATA(VI1_DATA8_GMARK, GFN_VI1_DATA8),
++ PINMUX_DATA(VI1_DATA7_GMARK, GFN_VI1_DATA7),
++ PINMUX_DATA(VI1_DATA6_GMARK, GFN_VI1_DATA6),
++ PINMUX_DATA(VI1_DATA5_GMARK, GFN_VI1_DATA5),
++ PINMUX_DATA(VI1_DATA4_GMARK, GFN_VI1_DATA4),
++ PINMUX_DATA(VI1_DATA3_GMARK, GFN_VI1_DATA3),
++ PINMUX_DATA(VI1_DATA2_GMARK, GFN_VI1_DATA2),
++ PINMUX_DATA(VI1_DATA1_GMARK, GFN_VI1_DATA1),
++ PINMUX_DATA(VI1_DATA0_GMARK, GFN_VI1_DATA0),
++ PINMUX_DATA(VI1_VSYNC_N_GMARK, GFN_VI1_VSYNC_N),
++ PINMUX_DATA(VI1_HSYNC_N_GMARK, GFN_VI1_HSYNC_N),
++ PINMUX_DATA(VI1_CLKENB_GMARK, GFN_VI1_CLKENB),
++ PINMUX_DATA(VI1_CLK_GMARK, GFN_VI1_CLK),
++
++ /* GPSR4 */
++ PINMUX_DATA(SDA2_GMARK, GFN_SDA2),
++ PINMUX_DATA(SCL2_GMARK, GFN_SCL2),
++ PINMUX_DATA(SDA1_GMARK, GFN_SDA1),
++ PINMUX_DATA(SCL1_GMARK, GFN_SCL1),
++ PINMUX_DATA(SDA0_GMARK, GFN_SDA0),
++ PINMUX_DATA(SCL0_GMARK, GFN_SCL0),
++
++ /* GPSR5 */
++ PINMUX_DATA(RPC_INT_N_MARK, FN_RPC_INT_N),
++ PINMUX_DATA(RPC_WP_N_MARK, FN_RPC_WP_N),
++ PINMUX_DATA(RPC_RESET_N_MARK, FN_RPC_RESET_N),
++ PINMUX_DATA(QSPI1_SSL_MARK, FN_QSPI1_SSL),
++ PINMUX_DATA(QSPI1_IO3_MARK, FN_QSPI1_IO3),
++ PINMUX_DATA(QSPI1_IO2_MARK, FN_QSPI1_IO2),
++ PINMUX_DATA(QSPI1_MISO_IO1_MARK, FN_QSPI1_MISO_IO1),
++ PINMUX_DATA(QSPI1_MOSI_IO0_MARK, FN_QSPI1_MOSI_IO0),
++ PINMUX_DATA(QSPI1_SPCLK_MARK, FN_QSPI1_SPCLK),
++ PINMUX_DATA(QSPI0_SSL_MARK, FN_QSPI0_SSL),
++ PINMUX_DATA(QSPI0_IO3_MARK, FN_QSPI0_IO3),
++ PINMUX_DATA(QSPI0_IO2_MARK, FN_QSPI0_IO2),
++ PINMUX_DATA(QSPI0_MISO_IO1_MARK, FN_QSPI0_MISO_IO1),
++ PINMUX_DATA(QSPI0_MOSI_IO0_MARK, FN_QSPI0_MOSI_IO0),
++ PINMUX_DATA(QSPI0_SPCLK_MARK, FN_QSPI0_SPCLK),
++
++
++ /* IPSR0 */
++ PINMUX_IPSR_IDATA(DU_DR2),
++ PINMUX_IPSR_DATA(DU_DR2, HSCK0),
++ PINMUX_IPSR_DATA(DU_DR2, A0),
++ PINMUX_IPSR_IDATA(DU_DR3),
++ PINMUX_IPSR_DATA(DU_DR3, HRTS0_N),
++ PINMUX_IPSR_DATA(DU_DR3, A1),
++ PINMUX_IPSR_IDATA(DU_DR4),
++ PINMUX_IPSR_DATA(DU_DR4, HCTS0_N),
++ PINMUX_IPSR_DATA(DU_DR4, A2),
++ PINMUX_IPSR_IDATA(DU_DR5),
++ PINMUX_IPSR_DATA(DU_DR5, HTX0),
++ PINMUX_IPSR_DATA(DU_DR5, A3),
++ PINMUX_IPSR_IDATA(DU_DR6),
++ PINMUX_IPSR_DATA(DU_DR6, MSIOF3_RXD),
++ PINMUX_IPSR_DATA(DU_DR6, A4),
++ PINMUX_IPSR_IDATA(DU_DR7),
++ PINMUX_IPSR_DATA(DU_DR7, MSIOF3_TXD),
++ PINMUX_IPSR_DATA(DU_DR7, A5),
++ PINMUX_IPSR_IDATA(DU_DG2),
++ PINMUX_IPSR_DATA(DU_DG2, MSIOF3_SS1),
++ PINMUX_IPSR_DATA(DU_DG2, A6),
++ PINMUX_IPSR_IDATA(DU_DG3),
++ PINMUX_IPSR_DATA(DU_DG3, MSIOF3_SS2),
++ PINMUX_IPSR_DATA(DU_DG3, A7),
++ PINMUX_IPSR_DATA(DU_DG3, PWMFSW0),
++
++ /* IPSR1 */
++ PINMUX_IPSR_IDATA(DU_DG4),
++ PINMUX_IPSR_DATA(DU_DG4, A8),
++ PINMUX_IPSR_DATA(DU_DG4, FSO_CFE_0_N_A),
++ PINMUX_IPSR_IDATA(DU_DG5),
++ PINMUX_IPSR_DATA(DU_DG5, A9),
++ PINMUX_IPSR_DATA(DU_DG5, FSO_CFE_1_N_A),
++ PINMUX_IPSR_IDATA(DU_DG6),
++ PINMUX_IPSR_DATA(DU_DG6, A10),
++ PINMUX_IPSR_DATA(DU_DG6, FSO_TOE_N_A),
++ PINMUX_IPSR_IDATA(DU_DG7),
++ PINMUX_IPSR_DATA(DU_DG7, A11),
++ PINMUX_IPSR_DATA(DU_DG7, IRQ1),
++ PINMUX_IPSR_IDATA(DU_DB2),
++ PINMUX_IPSR_DATA(DU_DB2, A12),
++ PINMUX_IPSR_DATA(DU_DB2, IRQ2),
++ PINMUX_IPSR_IDATA(DU_DB3),
++ PINMUX_IPSR_DATA(DU_DB3, A13),
++ PINMUX_IPSR_DATA(DU_DB3, FXR_CLKOUT1),
++ PINMUX_IPSR_IDATA(DU_DB4),
++ PINMUX_IPSR_DATA(DU_DB4, A14),
++ PINMUX_IPSR_DATA(DU_DB4, FXR_CLKOUT2),
++ PINMUX_IPSR_IDATA(DU_DB5),
++ PINMUX_IPSR_DATA(DU_DB5, A15),
++ PINMUX_IPSR_DATA(DU_DB5, FXR_TXENA_N),
++
++ /* IPSR2 */
++ PINMUX_IPSR_IDATA(DU_DB6),
++ PINMUX_IPSR_DATA(DU_DB6, A16),
++ PINMUX_IPSR_DATA(DU_DB6, FXR_TXENB_N),
++ PINMUX_IPSR_IDATA(DU_DB7),
++ PINMUX_IPSR_DATA(DU_DB7, A17),
++ PINMUX_IPSR_DATA(DU_DB7, STPWT_EXTFXR),
++ PINMUX_IPSR_IDATA(DU_DOTCLKOUT),
++ PINMUX_IPSR_DATA(DU_DOTCLKOUT, SCIF_CLK_A),
++ PINMUX_IPSR_DATA(DU_DOTCLKOUT, A18),
++ PINMUX_IPSR_IDATA(DU_EXHSYNC_DU_HSYNC),
++ PINMUX_IPSR_DATA(DU_EXHSYNC_DU_HSYNC, HRX0),
++ PINMUX_IPSR_DATA(DU_EXHSYNC_DU_HSYNC, A19),
++ PINMUX_IPSR_DATA(DU_EXHSYNC_DU_HSYNC, IRQ3),
++ PINMUX_IPSR_IDATA(DU_EXVSYNC_DU_VSYNC),
++ PINMUX_IPSR_DATA(DU_EXVSYNC_DU_VSYNC, MSIOF3_SCK),
++ PINMUX_IPSR_DATA(DU_EXVSYNC_DU_VSYNC, A20),
++ PINMUX_IPSR_IDATA(DU_EXODDF_DU_ODDF_DISP_CDE),
++ PINMUX_IPSR_DATA(DU_EXODDF_DU_ODDF_DISP_CDE, MSIOF3_SYNC),
++ PINMUX_IPSR_DATA(DU_EXODDF_DU_ODDF_DISP_CDE, A21),
++ PINMUX_IPSR_IDATA(IRQ0),
++ PINMUX_IPSR_DATA(IRQ0, CC5_OSCOUT),
++ PINMUX_IPSR_IDATA(VI0_CLK),
++ PINMUX_IPSR_DATA(VI0_CLK, MSIOF2_SCK),
++ PINMUX_IPSR_DATA(VI0_CLK, SCK3),
++ PINMUX_IPSR_DATA(VI0_CLK, HSCK3),
++
++ /* IPSR3 */
++ PINMUX_IPSR_IDATA(VI0_CLKENB),
++ PINMUX_IPSR_DATA(VI0_CLKENB, MSIOF2_RXD),
++ PINMUX_IPSR_DATA(VI0_CLKENB, RX3),
++ PINMUX_IPSR_DATA(VI0_CLKENB, RD_WR_N),
++ PINMUX_IPSR_DATA(VI0_CLKENB, HCTS3_N),
++ PINMUX_IPSR_IDATA(VI0_HSYNC_N),
++ PINMUX_IPSR_DATA(VI0_HSYNC_N, MSIOF2_TXD),
++ PINMUX_IPSR_DATA(VI0_HSYNC_N, TX3),
++ PINMUX_IPSR_DATA(VI0_HSYNC_N, HRTS3_N),
++ PINMUX_IPSR_IDATA(VI0_VSYNC_N),
++ PINMUX_IPSR_DATA(VI0_VSYNC_N, MSIOF2_SYNC),
++ PINMUX_IPSR_DATA(VI0_VSYNC_N, CTS3_N),
++ PINMUX_IPSR_DATA(VI0_VSYNC_N, HTX3),
++ PINMUX_IPSR_IDATA(VI0_DATA0),
++ PINMUX_IPSR_DATA(VI0_DATA0, MSIOF2_SS1),
++ PINMUX_IPSR_DATA(VI0_DATA0, RTS3_N_TANS),
++ PINMUX_IPSR_DATA(VI0_DATA0, HRX3),
++ PINMUX_IPSR_IDATA(VI0_DATA1),
++ PINMUX_IPSR_DATA(VI0_DATA1, MSIOF2_SS2),
++ PINMUX_IPSR_DATA(VI0_DATA3, SCK1),
++ PINMUX_IPSR_DATA(VI0_DATA1, SPEEDIN_A),
++ PINMUX_IPSR_IDATA(VI0_DATA2),
++ PINMUX_IPSR_DATA(VI0_DATA2, AVB0_AVTP_PPS),
++ PINMUX_IPSR_DATA(VI0_DATA2, SDA3_A),
++ PINMUX_IPSR_IDATA(VI0_DATA3),
++ PINMUX_IPSR_DATA(VI0_DATA3, HSCK1),
++ PINMUX_IPSR_DATA(VI0_DATA1, SCL3_A),
++ PINMUX_IPSR_IDATA(VI0_DATA4),
++ PINMUX_IPSR_DATA(VI0_DATA4, HRTS1_N),
++ PINMUX_IPSR_DATA(VI0_DATA4, RX1_A),
++
++ /* IPSR4 */
++ PINMUX_IPSR_IDATA(VI0_DATA5),
++ PINMUX_IPSR_DATA(VI0_DATA5, HCTS1_N),
++ PINMUX_IPSR_DATA(VI0_DATA5, TX1_A),
++ PINMUX_IPSR_IDATA(VI0_DATA6),
++ PINMUX_IPSR_DATA(VI0_DATA6, HTX1),
++ PINMUX_IPSR_DATA(VI0_DATA6, CTS1_N),
++ PINMUX_IPSR_IDATA(VI0_DATA7),
++ PINMUX_IPSR_DATA(VI0_DATA7, HRX1),
++ PINMUX_IPSR_DATA(VI0_DATA7, RTS1_N_TANS),
++ PINMUX_IPSR_IDATA(VI0_DATA8),
++ PINMUX_IPSR_DATA(VI0_DATA8, HSCK2),
++ PINMUX_IPSR_DATA(VI0_DATA8, PWM0_A),
++ PINMUX_IPSR_DATA(VI0_DATA8, A22),
++ PINMUX_IPSR_IDATA(VI0_DATA9),
++ PINMUX_IPSR_DATA(VI0_DATA9, HCTS2_N),
++ PINMUX_IPSR_DATA(VI0_DATA9, PWM1_A),
++ PINMUX_IPSR_DATA(VI0_DATA9, A23),
++ PINMUX_IPSR_DATA(VI0_DATA9, FSO_CFE_0_N_B),
++ PINMUX_IPSR_IDATA(VI0_DATA10),
++ PINMUX_IPSR_DATA(VI0_DATA10, HRTS2_N),
++ PINMUX_IPSR_DATA(VI0_DATA10, PWM2_A),
++ PINMUX_IPSR_DATA(VI0_DATA10, A24),
++ PINMUX_IPSR_DATA(VI0_DATA10, FSO_CFE_1_N_B),
++ PINMUX_IPSR_IDATA(VI0_DATA11),
++ PINMUX_IPSR_DATA(VI0_DATA11, HTX2),
++ PINMUX_IPSR_DATA(VI0_DATA11, PWM3_A),
++ PINMUX_IPSR_DATA(VI0_DATA11, A25),
++ PINMUX_IPSR_DATA(VI0_DATA11, FSO_TOE_N_B),
++ PINMUX_IPSR_IDATA(VI0_FIELD),
++ PINMUX_IPSR_DATA(VI0_FIELD, HRX2),
++ PINMUX_IPSR_DATA(VI0_FIELD, PWM4_A),
++ PINMUX_IPSR_DATA(VI0_FIELD, CS1_N_A26),
++ PINMUX_IPSR_DATA(VI0_FIELD, FSCLKST2_N_A),
++
++ /* IPSR5 */
++ PINMUX_IPSR_IDATA(VI1_CLK),
++ PINMUX_IPSR_DATA(VI1_CLK, MSIOF1_RXD),
++ PINMUX_IPSR_DATA(VI1_CLK, CS0_N),
++ PINMUX_IPSR_IDATA(VI1_CLKENB),
++ PINMUX_IPSR_DATA(VI1_CLKENB, MSIOF1_TXD),
++ PINMUX_IPSR_DATA(VI1_CLKENB, D0),
++ PINMUX_IPSR_IDATA(VI1_HSYNC_N),
++ PINMUX_IPSR_DATA(VI1_HSYNC_N, MSIOF1_SCK),
++ PINMUX_IPSR_DATA(VI1_HSYNC_N, D1),
++ PINMUX_IPSR_IDATA(VI1_VSYNC_N),
++ PINMUX_IPSR_DATA(VI1_VSYNC_N, MSIOF1_SYNC),
++ PINMUX_IPSR_DATA(VI1_VSYNC_N, D2),
++ PINMUX_IPSR_IDATA(VI1_DATA0),
++ PINMUX_IPSR_DATA(VI1_DATA0, MSIOF1_SS1),
++ PINMUX_IPSR_DATA(VI1_DATA0, D3),
++ PINMUX_IPSR_IDATA(VI1_DATA1),
++ PINMUX_IPSR_DATA(VI1_DATA1, MSIOF1_SS2),
++ PINMUX_IPSR_DATA(VI1_DATA1, D4),
++ PINMUX_IPSR_DATA(VI1_DATA1, MMC_CMD),
++ PINMUX_IPSR_IDATA(VI1_DATA2),
++ PINMUX_IPSR_DATA(VI1_DATA2, CANFD0_TX_B),
++ PINMUX_IPSR_DATA(VI1_DATA2, D5),
++ PINMUX_IPSR_DATA(VI1_DATA2, MMC_D0),
++ PINMUX_IPSR_IDATA(VI1_DATA3),
++ PINMUX_IPSR_DATA(VI1_DATA3, CANFD0_RX_B),
++ PINMUX_IPSR_DATA(VI1_DATA3, D6),
++ PINMUX_IPSR_DATA(VI1_DATA3, MMC_D1),
++
++ /* IPSR6 */
++ PINMUX_IPSR_IDATA(VI1_DATA4),
++ PINMUX_IPSR_DATA(VI1_DATA4, CANFD_CLK_B),
++ PINMUX_IPSR_DATA(VI1_DATA4, D7),
++ PINMUX_IPSR_DATA(VI1_DATA4, MMC_D2),
++ PINMUX_IPSR_IDATA(VI1_DATA5),
++ PINMUX_IPSR_DATA(VI1_DATA5, SCK4),
++ PINMUX_IPSR_DATA(VI1_DATA5, D8),
++ PINMUX_IPSR_DATA(VI1_DATA5, MMC_D3),
++ PINMUX_IPSR_IDATA(VI1_DATA6),
++ PINMUX_IPSR_DATA(VI1_DATA6, RX4),
++ PINMUX_IPSR_DATA(VI1_DATA6, D9),
++ PINMUX_IPSR_DATA(VI1_DATA6, MMC_CLK),
++ PINMUX_IPSR_IDATA(VI1_DATA7),
++ PINMUX_IPSR_DATA(VI1_DATA7, TX4),
++ PINMUX_IPSR_DATA(VI1_DATA7, D10),
++ PINMUX_IPSR_DATA(VI1_DATA7, MMC_D4),
++ PINMUX_IPSR_IDATA(VI1_DATA8),
++ PINMUX_IPSR_DATA(VI1_DATA8, CTS4_N),
++ PINMUX_IPSR_DATA(VI1_DATA8, D11),
++ PINMUX_IPSR_DATA(VI1_DATA8, MMC_D5),
++ PINMUX_IPSR_IDATA(VI1_DATA9),
++ PINMUX_IPSR_DATA(VI1_DATA9, RTS4_N_TANS),
++ PINMUX_IPSR_DATA(VI1_DATA9, D12),
++ PINMUX_IPSR_DATA(VI1_DATA9, MMC_D6),
++ PINMUX_IPSR_DATA(VI1_DATA9, SCL3_B),
++ PINMUX_IPSR_IDATA(VI1_DATA10),
++ PINMUX_IPSR_DATA(VI1_DATA10, D13),
++ PINMUX_IPSR_DATA(VI1_DATA10, MMC_D7),
++ PINMUX_IPSR_DATA(VI1_DATA10, SDA3_B),
++ PINMUX_IPSR_IDATA(VI1_DATA11),
++ PINMUX_IPSR_DATA(VI1_DATA11, SCL4),
++ PINMUX_IPSR_DATA(VI1_DATA11, IRQ4),
++ PINMUX_IPSR_DATA(VI1_DATA11, D14),
++ PINMUX_IPSR_DATA(VI1_DATA11, MMC_WP),
++
++ /* IPSR7 */
++ PINMUX_IPSR_IDATA(VI1_FIELD),
++ PINMUX_IPSR_DATA(VI1_FIELD, SDA4),
++ PINMUX_IPSR_DATA(VI1_FIELD, IRQ5),
++ PINMUX_IPSR_DATA(VI1_FIELD, D15),
++ PINMUX_IPSR_DATA(VI1_FIELD, MMC_CD),
++ PINMUX_IPSR_IDATA(SCL0),
++ PINMUX_IPSR_DATA(SCL0, DU_DR0),
++ PINMUX_IPSR_DATA(SCL0, TPU0TO0),
++ PINMUX_IPSR_DATA(SCL0, CLKOUT),
++ PINMUX_IPSR_DATA(SCL0, MSIOF0_RXD),
++ PINMUX_IPSR_IDATA(SDA0),
++ PINMUX_IPSR_DATA(SDA0, DU_DR1),
++ PINMUX_IPSR_DATA(SDA0, TPU0TO1),
++ PINMUX_IPSR_DATA(SDA0, BS_N),
++ PINMUX_IPSR_DATA(SDA0, SCK0),
++ PINMUX_IPSR_DATA(SDA0, MSIOF0_TXD),
++ PINMUX_IPSR_IDATA(SCL1),
++ PINMUX_IPSR_DATA(SCL1, DU_DG0),
++ PINMUX_IPSR_DATA(SCL1, TPU0TO2),
++ PINMUX_IPSR_DATA(SCL1, RD_N),
++ PINMUX_IPSR_DATA(SCL1, CTS0_N),
++ PINMUX_IPSR_DATA(SCL1, MSIOF0_SCK),
++ PINMUX_IPSR_IDATA(SDA1),
++ PINMUX_IPSR_DATA(SDA1, DU_DG1),
++ PINMUX_IPSR_DATA(SDA1, TPU0TO3),
++ PINMUX_IPSR_DATA(SDA1, WE0_N),
++ PINMUX_IPSR_DATA(SDA1, RTS0_N_TANS),
++ PINMUX_IPSR_DATA(SDA1, MSIOF0_SYNC),
++ PINMUX_IPSR_IDATA(SCL2),
++ PINMUX_IPSR_DATA(SCL2, DU_DB0),
++ PINMUX_IPSR_DATA(SCL2, TCLK1_A),
++ PINMUX_IPSR_DATA(SCL2, WE1_N),
++ PINMUX_IPSR_DATA(SCL2, RX0),
++ PINMUX_IPSR_DATA(SCL2, MSIOF0_SS1),
++ PINMUX_IPSR_IDATA(SDA2),
++ PINMUX_IPSR_DATA(SDA2, DU_DB1),
++ PINMUX_IPSR_DATA(SDA2, TCLK2_A),
++ PINMUX_IPSR_DATA(SDA2, EX_WAIT0),
++ PINMUX_IPSR_DATA(SDA2, TX0),
++ PINMUX_IPSR_DATA(SDA2, MSIOF0_SS2),
++ PINMUX_IPSR_IDATA(AVB0_AVTP_CAPTURE),
++ PINMUX_IPSR_DATA(AVB0_AVTP_CAPTURE, FSCLKST2_N_B),
++
++ /* IPSR8 */
++ PINMUX_IPSR_IDATA(CANFD0_TX_A),
++ PINMUX_IPSR_DATA(CANFD0_TX_A, FXR_TXDA),
++ PINMUX_IPSR_DATA(CANFD0_TX_A, PWM0_B),
++ PINMUX_IPSR_DATA(CANFD0_TX_A, DU_DISP),
++ PINMUX_IPSR_DATA(CANFD0_TX_A, FSCLKST2_N_C),
++ PINMUX_IPSR_IDATA(CANFD0_RX_A),
++ PINMUX_IPSR_DATA(CANFD0_RX_A, RXDA_EXTFXR),
++ PINMUX_IPSR_DATA(CANFD0_RX_A, PWM1_B),
++ PINMUX_IPSR_DATA(CANFD0_RX_A, DU_CDE),
++ PINMUX_IPSR_IDATA(CANFD1_TX),
++ PINMUX_IPSR_DATA(CANFD1_TX, FXR_TXDB),
++ PINMUX_IPSR_DATA(CANFD1_TX, PWM2_B),
++ PINMUX_IPSR_DATA(CANFD1_TX, TCLK1_B),
++ PINMUX_IPSR_DATA(CANFD1_TX, TX1_B),
++ PINMUX_IPSR_IDATA(CANFD1_RX),
++ PINMUX_IPSR_DATA(CANFD1_RX, RXDB_EXTFXR),
++ PINMUX_IPSR_DATA(CANFD1_RX, PWM3_B),
++ PINMUX_IPSR_DATA(CANFD1_RX, TCLK2_B),
++ PINMUX_IPSR_DATA(CANFD1_RX, RX1_B),
++ PINMUX_IPSR_IDATA(CANFD_CLK_A),
++ PINMUX_IPSR_DATA(CANFD_CLK_A, CLK_EXTFXR),
++ PINMUX_IPSR_DATA(CANFD_CLK_A, PWM4_B),
++ PINMUX_IPSR_DATA(CANFD_CLK_A, SPEEDIN_B),
++ PINMUX_IPSR_DATA(CANFD_CLK_A, SCIF_CLK_B),
++ PINMUX_IPSR_IDATA(DIGRF_CLKIN),
++ PINMUX_IPSR_DATA(DIGRF_CLKIN, DIGRF_CLKEN_IN),
++ PINMUX_IPSR_IDATA(DIGRF_CLKOUT),
++ PINMUX_IPSR_DATA(DIGRF_CLKOUT, DIGRF_CLKEN_OUT),
++};
++
++static struct pinmux_gpio pinmux_gpios[] = {
++ PINMUX_GPIO_GP_ALL(),
++
++ /* GPSR0 */
++ GPIO_GFN(DU_EXODDF_DU_ODDF_DISP_CDE),
++ GPIO_GFN(DU_EXVSYNC_DU_VSYNC),
++ GPIO_GFN(DU_EXHSYNC_DU_HSYNC),
++ GPIO_GFN(DU_DOTCLKOUT),
++ GPIO_GFN(DU_DB7),
++ GPIO_GFN(DU_DB6),
++ GPIO_GFN(DU_DB5),
++ GPIO_GFN(DU_DB4),
++ GPIO_GFN(DU_DB3),
++ GPIO_GFN(DU_DB2),
++ GPIO_GFN(DU_DG7),
++ GPIO_GFN(DU_DG6),
++ GPIO_GFN(DU_DG5),
++ GPIO_GFN(DU_DG4),
++ GPIO_GFN(DU_DG3),
++ GPIO_GFN(DU_DG2),
++ GPIO_GFN(DU_DR7),
++ GPIO_GFN(DU_DR6),
++ GPIO_GFN(DU_DR5),
++ GPIO_GFN(DU_DR4),
++ GPIO_GFN(DU_DR3),
++ GPIO_GFN(DU_DR2),
++
++ /* GPSR1 */
++ GPIO_GFN(DIGRF_CLKOUT),
++ GPIO_GFN(DIGRF_CLKIN),
++ GPIO_GFN(CANFD_CLK_A),
++ GPIO_GFN(CANFD1_RX),
++ GPIO_GFN(CANFD1_TX),
++ GPIO_GFN(CANFD0_RX_A),
++ GPIO_GFN(CANFD0_TX_A),
++ GPIO_GFN(AVB0_AVTP_CAPTURE),
++ GPIO_FN(AVB0_AVTP_MATCH),
++ GPIO_FN(AVB0_LINK),
++ GPIO_FN(AVB0_PHY_INT),
++ GPIO_FN(AVB0_MAGIC),
++ GPIO_FN(AVB0_MDC),
++ GPIO_FN(AVB0_MDIO),
++ GPIO_FN(AVB0_TXCREFCLK),
++ GPIO_FN(AVB0_TD3),
++ GPIO_FN(AVB0_TD2),
++ GPIO_FN(AVB0_TD1),
++ GPIO_FN(AVB0_TD0),
++ GPIO_FN(AVB0_TXC),
++ GPIO_FN(AVB0_TX_CTL),
++ GPIO_FN(AVB0_RD3),
++ GPIO_FN(AVB0_RD2),
++ GPIO_FN(AVB0_RD1),
++ GPIO_FN(AVB0_RD0),
++ GPIO_FN(AVB0_RXC),
++ GPIO_FN(AVB0_RX_CTL),
++ GPIO_GFN(IRQ0),
++
++ /* GPSR2 */
++ GPIO_GFN(VI0_FIELD),
++ GPIO_GFN(VI0_DATA11),
++ GPIO_GFN(VI0_DATA10),
++ GPIO_GFN(VI0_DATA9),
++ GPIO_GFN(VI0_DATA8),
++ GPIO_GFN(VI0_DATA7),
++ GPIO_GFN(VI0_DATA6),
++ GPIO_GFN(VI0_DATA5),
++ GPIO_GFN(VI0_DATA4),
++ GPIO_GFN(VI0_DATA3),
++ GPIO_GFN(VI0_DATA2),
++ GPIO_GFN(VI0_DATA1),
++ GPIO_GFN(VI0_DATA0),
++ GPIO_GFN(VI0_VSYNC_N),
++ GPIO_GFN(VI0_HSYNC_N),
++ GPIO_GFN(VI0_CLKENB),
++ GPIO_GFN(VI0_CLK),
++
++ /* GPSR3 */
++ GPIO_GFN(VI1_FIELD),
++ GPIO_GFN(VI1_DATA11),
++ GPIO_GFN(VI1_DATA10),
++ GPIO_GFN(VI1_DATA9),
++ GPIO_GFN(VI1_DATA8),
++ GPIO_GFN(VI1_DATA7),
++ GPIO_GFN(VI1_DATA6),
++ GPIO_GFN(VI1_DATA5),
++ GPIO_GFN(VI1_DATA4),
++ GPIO_GFN(VI1_DATA3),
++ GPIO_GFN(VI1_DATA2),
++ GPIO_GFN(VI1_DATA1),
++ GPIO_GFN(VI1_DATA0),
++ GPIO_GFN(VI1_VSYNC_N),
++ GPIO_GFN(VI1_HSYNC_N),
++ GPIO_GFN(VI1_CLKENB),
++ GPIO_GFN(VI1_CLK),
++
++ /* GPSR4 */
++ GPIO_GFN(SDA2),
++ GPIO_GFN(SCL2),
++ GPIO_GFN(SDA1),
++ GPIO_GFN(SCL1),
++ GPIO_GFN(SDA0),
++ GPIO_GFN(SCL0),
++
++ /* GPSR5 */
++ GPIO_FN(RPC_INT_N),
++ GPIO_FN(RPC_WP_N),
++ GPIO_FN(RPC_RESET_N),
++ GPIO_FN(QSPI1_SSL),
++ GPIO_FN(QSPI1_IO3),
++ GPIO_FN(QSPI1_IO2),
++ GPIO_FN(QSPI1_MISO_IO1),
++ GPIO_FN(QSPI1_MOSI_IO0),
++ GPIO_FN(QSPI1_SPCLK),
++ GPIO_FN(QSPI0_SSL),
++ GPIO_FN(QSPI0_IO3),
++ GPIO_FN(QSPI0_IO2),
++ GPIO_FN(QSPI0_MISO_IO1),
++ GPIO_FN(QSPI0_MOSI_IO0),
++ GPIO_FN(QSPI0_SPCLK),
++
++ /* IPSR0 */
++ GPIO_IFN(DU_DR2),
++ GPIO_FN(HSCK0),
++ GPIO_FN(A0),
++ GPIO_IFN(DU_DR3),
++ GPIO_FN(HRTS0_N),
++ GPIO_FN(A1),
++ GPIO_IFN(DU_DR4),
++ GPIO_FN(HCTS0_N),
++ GPIO_FN(A2),
++ GPIO_IFN(DU_DR5),
++ GPIO_FN(HTX0),
++ GPIO_FN(A3),
++ GPIO_IFN(DU_DR6),
++ GPIO_FN(MSIOF3_RXD),
++ GPIO_FN(A4),
++ GPIO_IFN(DU_DR7),
++ GPIO_FN(MSIOF3_TXD),
++ GPIO_FN(A5),
++ GPIO_IFN(DU_DG2),
++ GPIO_FN(MSIOF3_SS1),
++ GPIO_FN(A6),
++ GPIO_IFN(DU_DG3),
++ GPIO_FN(MSIOF3_SS2),
++ GPIO_FN(A7),
++ GPIO_FN(PWMFSW0),
++
++ /* IPSR1 */
++ GPIO_IFN(DU_DG4),
++ GPIO_FN(A8),
++ GPIO_FN(FSO_CFE_0_N_A),
++ GPIO_IFN(DU_DG5),
++ GPIO_FN(A9),
++ GPIO_FN(FSO_CFE_1_N_A),
++ GPIO_IFN(DU_DG6),
++ GPIO_FN(A10),
++ GPIO_FN(FSO_TOE_N_A),
++ GPIO_IFN(DU_DG7),
++ GPIO_FN(A11),
++ GPIO_FN(IRQ1),
++ GPIO_IFN(DU_DB2),
++ GPIO_FN(A12),
++ GPIO_FN(IRQ2),
++ GPIO_IFN(DU_DB3),
++ GPIO_FN(A13),
++ GPIO_FN(FXR_CLKOUT1),
++ GPIO_IFN(DU_DB4),
++ GPIO_FN(A14),
++ GPIO_FN(FXR_CLKOUT2),
++ GPIO_IFN(DU_DB5),
++ GPIO_FN(A15),
++ GPIO_FN(FXR_TXENA_N),
++
++ /* IPSR2 */
++ GPIO_IFN(DU_DB6),
++ GPIO_FN(A16),
++ GPIO_FN(FXR_TXENB_N),
++ GPIO_IFN(DU_DB7),
++ GPIO_FN(A17),
++ GPIO_FN(STPWT_EXTFXR),
++ GPIO_IFN(DU_DOTCLKOUT),
++ GPIO_FN(SCIF_CLK_A),
++ GPIO_FN(A18),
++ GPIO_IFN(DU_EXHSYNC_DU_HSYNC),
++ GPIO_FN(HRX0),
++ GPIO_FN(A19),
++ GPIO_FN(IRQ3),
++ GPIO_IFN(DU_EXVSYNC_DU_VSYNC),
++ GPIO_FN(MSIOF3_SCK),
++ GPIO_FN(A20),
++ GPIO_IFN(DU_EXODDF_DU_ODDF_DISP_CDE),
++ GPIO_FN(MSIOF3_SYNC),
++ GPIO_FN(A21),
++ GPIO_IFN(IRQ0),
++ GPIO_FN(CC5_OSCOUT),
++ GPIO_IFN(VI0_CLK),
++ GPIO_FN(MSIOF2_SCK),
++ GPIO_FN(SCK3),
++ GPIO_FN(HSCK3),
++
++ /* IPSR3 */
++ GPIO_IFN(VI0_CLKENB),
++ GPIO_FN(MSIOF2_RXD),
++ GPIO_FN(RX3),
++ GPIO_FN(RD_WR_N),
++ GPIO_FN(HCTS3_N),
++ GPIO_IFN(VI0_HSYNC_N),
++ GPIO_FN(MSIOF2_TXD),
++ GPIO_FN(TX3),
++ GPIO_FN(HRTS3_N),
++ GPIO_IFN(VI0_VSYNC_N),
++ GPIO_FN(MSIOF2_SYNC),
++ GPIO_FN(CTS3_N),
++ GPIO_FN(HTX3),
++ GPIO_IFN(VI0_DATA0),
++ GPIO_FN(MSIOF2_SS1),
++ GPIO_FN(RTS3_N_TANS),
++ GPIO_FN(HRX3),
++ GPIO_IFN(VI0_DATA1),
++ GPIO_FN(MSIOF2_SS2),
++ GPIO_FN(SCK1),
++ GPIO_FN(SPEEDIN_A),
++ GPIO_IFN(VI0_DATA2),
++ GPIO_FN(AVB0_AVTP_PPS),
++ GPIO_FN(SDA3_A),
++ GPIO_IFN(VI0_DATA3),
++ GPIO_FN(HSCK1),
++ GPIO_FN(SCL3_A),
++ GPIO_IFN(VI0_DATA4),
++ GPIO_FN(HRTS1_N),
++ GPIO_FN(RX1_A),
++
++ /* IPSR4 */
++ GPIO_IFN(VI0_DATA5),
++ GPIO_FN(HCTS1_N),
++ GPIO_FN(TX1_A),
++ GPIO_IFN(VI0_DATA6),
++ GPIO_FN(HTX1),
++ GPIO_FN(CTS1_N),
++ GPIO_IFN(VI0_DATA7),
++ GPIO_FN(HRX1),
++ GPIO_FN(RTS1_N_TANS),
++ GPIO_IFN(VI0_DATA8),
++ GPIO_FN(HSCK2),
++ GPIO_FN(PWM0_A),
++ GPIO_FN(A22),
++ GPIO_IFN(VI0_DATA9),
++ GPIO_FN(HCTS2_N),
++ GPIO_FN(PWM1_A),
++ GPIO_FN(A23),
++ GPIO_FN(FSO_CFE_0_N_B),
++ GPIO_IFN(VI0_DATA10),
++ GPIO_FN(HRTS2_N),
++ GPIO_FN(PWM2_A),
++ GPIO_FN(A24),
++ GPIO_FN(FSO_CFE_1_N_B),
++ GPIO_IFN(VI0_DATA11),
++ GPIO_FN(HTX2),
++ GPIO_FN(PWM3_A),
++ GPIO_FN(A25),
++ GPIO_FN(FSO_TOE_N_B),
++ GPIO_IFN(VI0_FIELD),
++ GPIO_FN(HRX2),
++ GPIO_FN(PWM4_A),
++ GPIO_FN(CS1_N_A26),
++ GPIO_FN(FSCLKST2_N_A),
++
++ /* IPSR5 */
++ GPIO_IFN(VI1_CLK),
++ GPIO_FN(MSIOF1_RXD),
++ GPIO_FN(CS0_N),
++ GPIO_IFN(VI1_CLKENB),
++ GPIO_FN(MSIOF1_TXD),
++ GPIO_FN(D0),
++ GPIO_IFN(VI1_HSYNC_N),
++ GPIO_FN(MSIOF1_SCK),
++ GPIO_FN(D1),
++ GPIO_IFN(VI1_VSYNC_N),
++ GPIO_FN(MSIOF1_SYNC),
++ GPIO_FN(D2),
++ GPIO_IFN(VI1_DATA0),
++ GPIO_FN(MSIOF1_SS1),
++ GPIO_FN(D3),
++ GPIO_IFN(VI1_DATA1),
++ GPIO_FN(MSIOF1_SS2),
++ GPIO_FN(D4),
++ GPIO_FN(MMC_CMD),
++ GPIO_IFN(VI1_DATA2),
++ GPIO_FN(CANFD0_TX_B),
++ GPIO_FN(D5),
++ GPIO_FN(MMC_D0),
++ GPIO_IFN(VI1_DATA3),
++ GPIO_FN(CANFD0_RX_B),
++ GPIO_FN(D6),
++ GPIO_FN(MMC_D1),
++
++ /* IPSR6 */
++ GPIO_IFN(VI1_DATA4),
++ GPIO_FN(CANFD_CLK_B),
++ GPIO_FN(D7),
++ GPIO_FN(MMC_D2),
++ GPIO_IFN(VI1_DATA5),
++ GPIO_FN(SCK4),
++ GPIO_FN(D8),
++ GPIO_FN(MMC_D3),
++ GPIO_IFN(VI1_DATA6),
++ GPIO_FN(RX4),
++ GPIO_FN(D9),
++ GPIO_FN(MMC_CLK),
++ GPIO_IFN(VI1_DATA7),
++ GPIO_FN(TX4),
++ GPIO_FN(D10),
++ GPIO_FN(MMC_D4),
++ GPIO_IFN(VI1_DATA8),
++ GPIO_FN(CTS4_N),
++ GPIO_FN(D11),
++ GPIO_FN(MMC_D5),
++ GPIO_IFN(VI1_DATA9),
++ GPIO_FN(RTS4_N_TANS),
++ GPIO_FN(D12),
++ GPIO_FN(MMC_D6),
++ GPIO_FN(SCL3_B),
++ GPIO_IFN(VI1_DATA10),
++ GPIO_FN(D13),
++ GPIO_FN(MMC_D7),
++ GPIO_FN(SDA3_B),
++ GPIO_IFN(VI1_DATA11),
++ GPIO_FN(SCL4),
++ GPIO_FN(IRQ4),
++ GPIO_FN(D14),
++ GPIO_FN(MMC_WP),
++
++ /* IPSR7 */
++ GPIO_IFN(VI1_FIELD),
++ GPIO_FN(SDA4),
++ GPIO_FN(IRQ5),
++ GPIO_FN(D15),
++ GPIO_FN(MMC_CD),
++ GPIO_IFN(SCL0),
++ GPIO_FN(DU_DR0),
++ GPIO_FN(TPU0TO0),
++ GPIO_FN(CLKOUT),
++ GPIO_FN(MSIOF0_RXD),
++ GPIO_IFN(SDA0),
++ GPIO_FN(DU_DR1),
++ GPIO_FN(TPU0TO1),
++ GPIO_FN(BS_N),
++ GPIO_FN(SCK0),
++ GPIO_FN(MSIOF0_TXD),
++ GPIO_IFN(SCL1),
++ GPIO_FN(DU_DG0),
++ GPIO_FN(TPU0TO2),
++ GPIO_FN(RD_N),
++ GPIO_FN(CTS0_N),
++ GPIO_FN(MSIOF0_SCK),
++ GPIO_IFN(SDA1),
++ GPIO_FN(DU_DG1),
++ GPIO_FN(TPU0TO3),
++ GPIO_FN(WE0_N),
++ GPIO_FN(RTS0_N_TANS),
++ GPIO_FN(MSIOF0_SYNC),
++ GPIO_IFN(SCL2),
++ GPIO_FN(DU_DB0),
++ GPIO_FN(TCLK1_A),
++ GPIO_FN(WE1_N),
++ GPIO_FN(RX0),
++ GPIO_FN(MSIOF0_SS1),
++ GPIO_IFN(SDA2),
++ GPIO_FN(DU_DB1),
++ GPIO_FN(TCLK2_A),
++ GPIO_FN(EX_WAIT0),
++ GPIO_FN(TX0),
++ GPIO_FN(MSIOF0_SS2),
++ GPIO_IFN(AVB0_AVTP_CAPTURE),
++ GPIO_FN(FSCLKST2_N_B),
++
++ /* IPSR8 */
++ GPIO_IFN(CANFD0_TX_A),
++ GPIO_FN(FXR_TXDA),
++ GPIO_FN(PWM0_B),
++ GPIO_FN(DU_DISP),
++ GPIO_FN(FSCLKST2_N_C),
++ GPIO_IFN(CANFD0_RX_A),
++ GPIO_FN(RXDA_EXTFXR),
++ GPIO_FN(PWM1_B),
++ GPIO_FN(DU_CDE),
++ GPIO_IFN(CANFD1_TX),
++ GPIO_FN(FXR_TXDB),
++ GPIO_FN(PWM2_B),
++ GPIO_FN(TCLK1_B),
++ GPIO_FN(TX1_B),
++ GPIO_IFN(CANFD1_RX),
++ GPIO_FN(RXDB_EXTFXR),
++ GPIO_FN(PWM3_B),
++ GPIO_FN(TCLK2_B),
++ GPIO_FN(RX1_B),
++ GPIO_IFN(CANFD_CLK_A),
++ GPIO_FN(CLK_EXTFXR),
++ GPIO_FN(PWM4_B),
++ GPIO_FN(SPEEDIN_B),
++ GPIO_FN(SCIF_CLK_B),
++ GPIO_IFN(DIGRF_CLKIN),
++ GPIO_FN(DIGRF_CLKEN_IN),
++ GPIO_IFN(DIGRF_CLKOUT),
++ GPIO_FN(DIGRF_CLKEN_OUT),
++
++};
++
++static struct pinmux_cfg_reg pinmux_config_regs[] = {
++ /* GPSR0(0xE6060100) md[3:1] controls initial value */
++ /* md[3:1] .. 0 : 0x0000FFFF */
++ /* .. other : 0x00000000 */
++ { 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, GFN_DU_EXODDF_DU_ODDF_DISP_CDE,
++ GP_0_20_FN, GFN_DU_EXVSYNC_DU_VSYNC,
++ GP_0_19_FN, GFN_DU_EXHSYNC_DU_HSYNC,
++ GP_0_18_FN, GFN_DU_DOTCLKOUT,
++ GP_0_17_FN, GFN_DU_DB7,
++ GP_0_16_FN, GFN_DU_DB6,
++ GP_0_15_FN, GFN_DU_DB5,
++ GP_0_14_FN, GFN_DU_DB4,
++ GP_0_13_FN, GFN_DU_DB3,
++ GP_0_12_FN, GFN_DU_DB2,
++ GP_0_11_FN, GFN_DU_DG7,
++ GP_0_10_FN, GFN_DU_DG6,
++ GP_0_9_FN, GFN_DU_DG5,
++ GP_0_8_FN, GFN_DU_DG4,
++ GP_0_7_FN, GFN_DU_DG3,
++ GP_0_6_FN, GFN_DU_DG2,
++ GP_0_5_FN, GFN_DU_DR7,
++ GP_0_4_FN, GFN_DU_DR6,
++ GP_0_3_FN, GFN_DU_DR5,
++ GP_0_2_FN, GFN_DU_DR4,
++ GP_0_1_FN, GFN_DU_DR3,
++ GP_0_0_FN, GFN_DU_DR2 }
++ },
++ /* GPSR1(0xE6060104) is md[3:1] controls initial value */
++ /* md[3:1] .. 0 : 0x0EFFFFFF */
++ /* .. other : 0x00000000 */
++ { PINMUX_CFG_REG("GPSR1", 0xE6060104, 32, 1) {
++ 0, 0,
++ 0, 0,
++ 0, 0,
++ 0, 0,
++ GP_1_27_FN, GFN_DIGRF_CLKOUT,
++ GP_1_26_FN, GFN_DIGRF_CLKIN,
++ GP_1_25_FN, GFN_CANFD_CLK_A,
++ GP_1_24_FN, GFN_CANFD1_RX,
++ GP_1_23_FN, GFN_CANFD1_TX,
++ GP_1_22_FN, GFN_CANFD0_RX_A,
++ GP_1_21_FN, GFN_CANFD0_TX_A,
++ GP_1_20_FN, GFN_AVB0_AVTP_CAPTURE,
++ GP_1_19_FN, FN_AVB0_AVTP_MATCH,
++ GP_1_18_FN, FN_AVB0_LINK,
++ GP_1_17_FN, FN_AVB0_PHY_INT,
++ GP_1_16_FN, FN_AVB0_MAGIC,
++ GP_1_15_FN, FN_AVB0_MDC,
++ GP_1_14_FN, FN_AVB0_MDIO,
++ GP_1_13_FN, FN_AVB0_TXCREFCLK,
++ GP_1_12_FN, FN_AVB0_TD3,
++ GP_1_11_FN, FN_AVB0_TD2,
++ GP_1_10_FN, FN_AVB0_TD1,
++ GP_1_9_FN, FN_AVB0_TD0,
++ GP_1_8_FN, FN_AVB0_TXC,
++ GP_1_7_FN, FN_AVB0_TX_CTL,
++ GP_1_6_FN, FN_AVB0_RD3,
++ GP_1_5_FN, FN_AVB0_RD2,
++ GP_1_4_FN, FN_AVB0_RD1,
++ GP_1_3_FN, FN_AVB0_RD0,
++ GP_1_2_FN, FN_AVB0_RXC,
++ GP_1_1_FN, FN_AVB0_RX_CTL,
++ GP_1_0_FN, GFN_IRQ0 }
++ },
++ /* GPSR2(0xE6060108) is md[3:1] controls */
++ /* md[3:1] .. 0 : 0x000003C0 */
++ /* .. other : 0x00000200 */
++ { 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, GFN_VI0_FIELD,
++ GP_2_15_FN, GFN_VI0_DATA11,
++ GP_2_14_FN, GFN_VI0_DATA10,
++ GP_2_13_FN, GFN_VI0_DATA9,
++ GP_2_12_FN, GFN_VI0_DATA8,
++ GP_2_11_FN, GFN_VI0_DATA7,
++ GP_2_10_FN, GFN_VI0_DATA6,
++ GP_2_9_FN, GFN_VI0_DATA5,
++ GP_2_8_FN, GFN_VI0_DATA4,
++ GP_2_7_FN, GFN_VI0_DATA3,
++ GP_2_6_FN, GFN_VI0_DATA2,
++ GP_2_5_FN, GFN_VI0_DATA1,
++ GP_2_4_FN, GFN_VI0_DATA0,
++ GP_2_3_FN, GFN_VI0_VSYNC_N,
++ GP_2_2_FN, GFN_VI0_HSYNC_N,
++ GP_2_1_FN, GFN_VI0_CLKENB,
++ GP_2_0_FN, GFN_VI0_CLK }
++ },
++
++ /* GPSR3 */
++ { 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, GFN_VI1_FIELD,
++ GP_3_15_FN, GFN_VI1_DATA11,
++ GP_3_14_FN, GFN_VI1_DATA10,
++ GP_3_13_FN, GFN_VI1_DATA9,
++ GP_3_12_FN, GFN_VI1_DATA8,
++ GP_3_11_FN, GFN_VI1_DATA7,
++ GP_3_10_FN, GFN_VI1_DATA6,
++ GP_3_9_FN, GFN_VI1_DATA5,
++ GP_3_8_FN, GFN_VI1_DATA4,
++ GP_3_7_FN, GFN_VI1_DATA3,
++ GP_3_6_FN, GFN_VI1_DATA2,
++ GP_3_5_FN, GFN_VI1_DATA1,
++ GP_3_4_FN, GFN_VI1_DATA0,
++ GP_3_3_FN, GFN_VI1_VSYNC_N,
++ GP_3_2_FN, GFN_VI1_HSYNC_N,
++ GP_3_1_FN, GFN_VI1_CLKENB,
++ GP_3_0_FN, GFN_VI1_CLK }
++ },
++ /* GPSR4 */
++ { 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, GFN_SDA2,
++ GP_4_4_FN, GFN_SCL2,
++ GP_4_3_FN, GFN_SDA1,
++ GP_4_2_FN, GFN_SCL1,
++ GP_4_1_FN, GFN_SDA0,
++ GP_4_0_FN, GFN_SCL0 }
++ },
++ /* GPSR5 */
++ { 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, FN_RPC_INT_N,
++ GP_5_13_FN, FN_RPC_WP_N,
++ GP_5_12_FN, FN_RPC_RESET_N,
++ GP_5_11_FN, FN_QSPI1_SSL,
++ GP_5_10_FN, FN_QSPI1_IO3,
++ GP_5_9_FN, FN_QSPI1_IO2,
++ GP_5_8_FN, FN_QSPI1_MISO_IO1,
++ GP_5_7_FN, FN_QSPI1_MOSI_IO0,
++ GP_5_6_FN, FN_QSPI1_SPCLK,
++ GP_5_5_FN, FN_QSPI0_SSL,
++ GP_5_4_FN, FN_QSPI0_IO3,
++ GP_5_3_FN, FN_QSPI0_IO2,
++ GP_5_2_FN, FN_QSPI0_MISO_IO1,
++ GP_5_1_FN, FN_QSPI0_MOSI_IO0,
++ GP_5_0_FN, FN_QSPI0_SPCLK }
++ },
++
++ { PINMUX_CFG_REG_VAR("IPSR0", 0xE6060200, 32,
++ 4, 4, 4, 4, 4, 4, 4, 4) {
++ /* IPSR0_31_28 [4] */
++ IFN_DU_DG3, FN_MSIOF3_SS2, 0, FN_A7,
++ FN_PWMFSW0, 0, 0, 0,
++ 0, 0, 0, 0,
++ 0, 0, 0, 0,
++ /* IPSR0_27_24 [4] */
++ IFN_DU_DG2, FN_MSIOF3_SS1, 0, FN_A6,
++ 0, 0, 0, 0,
++ 0, 0, 0, 0,
++ 0, 0, 0, 0,
++ /* IPSR0_23_20 [4] */
++ IFN_DU_DR7, FN_MSIOF3_TXD, 0, FN_A5,
++ 0, 0, 0, 0,
++ 0, 0, 0, 0,
++ 0, 0, 0, 0,
++ /* IPSR0_19_16 [4] */
++ IFN_DU_DR6, FN_MSIOF3_RXD, 0, FN_A4,
++ 0, 0, 0, 0,
++ 0, 0, 0, 0,
++ 0, 0, 0, 0,
++ /* IPSR0_15_12 [4] */
++ IFN_DU_DR5, FN_HTX0, 0, FN_A3,
++ 0, 0, 0, 0,
++ 0, 0, 0, 0,
++ 0, 0, 0, 0,
++ /* IPSR0_11_8 [4] */
++ IFN_DU_DR4, FN_HCTS0_N, 0, FN_A2,
++ 0, 0, 0, 0,
++ 0, 0, 0, 0,
++ 0, 0, 0, 0,
++ /* IPSR0_7_4 [4] */
++ IFN_DU_DR3, FN_HRTS0_N, 0, FN_A1,
++ 0, 0, 0, 0,
++ 0, 0, 0, 0,
++ 0, 0, 0, 0,
++ /* IPSR0_3_0 [4] */
++ IFN_DU_DR2, FN_HSCK0, 0, FN_A0,
++ 0, 0, 0, 0,
++ 0, 0, 0, 0,
++ 0, 0, 0, 0,
++ }
++ },
++ { PINMUX_CFG_REG_VAR("IPSR1", 0xE6060204, 32,
++ 4, 4, 4, 4, 4, 4, 4, 4) {
++ /* IPSR1_31_28 [4] */
++ IFN_DU_DB5, 0, 0, FN_A15,
++ FN_FXR_TXENA_N, 0, 0, 0,
++ 0, 0, 0, 0,
++ 0, 0, 0, 0,
++ /* IPSR1_27_24 [4] */
++ IFN_DU_DB4, 0, 0, FN_A14,
++ FN_FXR_CLKOUT2, 0, 0, 0,
++ 0, 0, 0, 0,
++ 0, 0, 0, 0,
++ /* IPSR1_23_20 [4] */
++ IFN_DU_DB3, 0, 0, FN_A13,
++ FN_FXR_CLKOUT1, 0, 0, 0,
++ 0, 0, 0, 0,
++ 0, 0, 0, 0,
++ /* IPSR1_19_16 [4] */
++ IFN_DU_DB2, 0, 0, FN_A12,
++ FN_IRQ2, 0, 0, 0,
++ 0, 0, 0, 0,
++ 0, 0, 0, 0,
++ /* IPSR1_15_12 [4] */
++ IFN_DU_DG7, 0, 0, FN_A11,
++ FN_IRQ1, 0, 0, 0,
++ 0, 0, 0, 0,
++ 0, 0, 0, 0,
++ /* IPSR1_11_8 [4] */
++ IFN_DU_DG6, 0, 0, FN_A10,
++ FN_FSO_TOE_N_A, 0, 0, 0,
++ 0, 0, 0, 0,
++ 0, 0, 0, 0,
++ /* IPSR1_7_4 [4] */
++ IFN_DU_DG5, 0, 0, FN_A9,
++ FN_FSO_CFE_1_N_A, 0, 0,
++ 0, 0, 0, 0,
++ 0, 0, 0, 0,
++ /* IPSR1_3_0 [4] */
++ IFN_DU_DG4, 0, 0, FN_A8,
++ FN_FSO_CFE_0_N_A, 0, 0, 0,
++ 0, 0, 0, 0,
++ 0, 0, 0, 0
++ }
++ },
++ { PINMUX_CFG_REG_VAR("IPSR2", 0xE6060208, 32,
++ 4, 4, 4, 4, 4, 4, 4, 4) {
++ /* IPSR2_31_28 [4] */
++ IFN_VI0_CLK, FN_MSIOF2_SCK, FN_SCK3, 0,
++ FN_HSCK3, 0, 0, 0,
++ 0, 0, 0, 0,
++ 0, 0, 0, 0,
++ /* IPSR2_27_24 [4] */
++ IFN_IRQ0, FN_CC5_OSCOUT, 0, 0,
++ 0, 0, 0, 0,
++ 0, 0, 0, 0,
++ 0, 0, 0, 0,
++ /* IPSR2_23_20 [4] */
++ IFN_DU_EXODDF_DU_ODDF_DISP_CDE, FN_MSIOF3_SYNC, 0, FN_A21,
++ 0, 0, 0, 0,
++ 0, 0, 0, 0,
++ 0, 0, 0, 0,
++ /* IPSR2_19_16 [4] */
++ IFN_DU_EXVSYNC_DU_VSYNC, FN_MSIOF3_SCK, 0, FN_A20,
++ 0, 0, 0, 0,
++ 0, 0, 0, 0,
++ 0, 0, 0, 0,
++ /* IPSR2_15_12 [4] */
++ IFN_DU_EXHSYNC_DU_HSYNC, FN_HRX0, 0, FN_A19,
++ FN_IRQ3, 0, 0, 0,
++ 0, 0, 0, 0,
++ 0, 0, 0, 0,
++ /* IPSR2_11_8 [4] */
++ IFN_DU_DOTCLKOUT, FN_SCIF_CLK_A, 0, FN_A18,
++ 0, 0, 0, 0,
++ 0, 0, 0, 0,
++ 0, 0, 0, 0,
++ /* IPSR2_7_4 [4] */
++ IFN_DU_DB7, 0, 0, FN_A17,
++ FN_STPWT_EXTFXR, 0, 0, 0,
++ 0, 0, 0, 0,
++ 0, 0, 0, 0,
++ /* IPSR2_3_0 [4] */
++ IFN_DU_DB6, 0, 0, FN_A16,
++ FN_FXR_TXENB_N, 0, 0, 0,
++ 0, 0, 0, 0,
++ 0, 0, 0, 0,
++ }
++ },
++ { PINMUX_CFG_REG_VAR("IPSR3", 0xE606020C, 32,
++ 4, 4, 4, 4, 4, 4, 4, 4) {
++ /* IPSR3_31_28 [4] */
++ IFN_VI0_DATA4, FN_HRTS1_N, FN_RX1_A, 0,
++ 0, 0, 0, 0,
++ 0, 0, 0, 0,
++ 0, 0, 0, 0,
++ /* IPSR3_27_24 [4] */
++ IFN_VI0_DATA3, FN_HSCK1, FN_SCL3_A, 0,
++ 0, 0, 0, 0,
++ 0, 0, 0, 0,
++ 0, 0, 0, 0,
++ /* IPSR3_23_20 [4] */
++ IFN_VI0_DATA2, FN_AVB0_AVTP_PPS, FN_SDA3_A, 0,
++ 0, 0, 0, 0,
++ 0, 0, 0, 0,
++ 0, 0, 0, 0,
++ /* IPSR3_19_16 [4] */
++ IFN_VI0_DATA1, FN_MSIOF2_SS2, FN_SCK1, 0,
++ FN_SPEEDIN_A, 0, 0, 0,
++ 0, 0, 0, 0,
++ 0, 0, 0, 0,
++ /* IPSR3_15_12 [4] */
++ IFN_VI0_DATA0, FN_MSIOF2_SS1, FN_RTS3_N_TANS, 0,
++ FN_HRX3, 0, 0, 0,
++ 0, 0, 0, 0,
++ 0, 0, 0, 0,
++ /* IPSR3_11_8 [4] */
++ IFN_VI0_VSYNC_N, FN_MSIOF2_SYNC, FN_CTS3_N, 0,
++ FN_HTX3, 0, 0, 0,
++ 0, 0, 0, 0,
++ 0, 0, 0, 0,
++ /* IPSR3_7_4 [4] */
++ IFN_VI0_HSYNC_N, FN_MSIOF2_TXD, FN_TX3, 0,
++ FN_HRTS3_N, 0, 0, 0,
++ 0, 0, 0, 0,
++ 0, 0, 0, 0,
++ /* IPSR3_3_0 [4] */
++ IFN_VI0_CLKENB, FN_MSIOF2_RXD, FN_RX3, FN_RD_WR_N,
++ FN_HCTS3_N, 0, 0, 0,
++ 0, 0, 0, 0,
++ 0, 0, 0, 0,
++ }
++ },
++ { PINMUX_CFG_REG_VAR("IPSR4", 0xE6060210, 32,
++ 4, 4, 4, 4, 4, 4, 4, 4) {
++ /* IPSR4_31_28 [4] */
++ IFN_VI0_FIELD, FN_HRX2, FN_PWM4_A, FN_CS1_N_A26,
++ FN_FSCLKST2_N_A, 0, 0, 0,
++ 0, 0, 0, 0,
++ 0, 0, 0, 0,
++ /* IPSR4_27_24 [4] */
++ IFN_VI0_DATA11, FN_HTX2, FN_PWM3_A, FN_A25,
++ FN_FSO_TOE_N_B, 0, 0, 0,
++ 0, 0, 0, 0,
++ 0, 0, 0, 0,
++ /* IPSR4_23_20 [4] */
++ IFN_VI0_DATA10, FN_HRTS2_N, FN_PWM2_A, FN_A24,
++ FN_FSO_CFE_1_N_B, 0, 0, 0,
++ 0, 0, 0, 0,
++ 0, 0, 0, 0,
++ /* IPSR4_19_16 [4] */
++ IFN_VI0_DATA9, FN_HCTS2_N, FN_PWM1_A, FN_A23,
++ FN_FSO_CFE_0_N_B, 0, 0, 0,
++ 0, 0, 0, 0,
++ 0, 0, 0, 0,
++ /* IPSR4_15_12 [4] */
++ IFN_VI0_DATA8, FN_HSCK2, FN_PWM0_A, FN_A22,
++ 0, 0, 0, 0,
++ 0, 0, 0, 0,
++ 0, 0, 0, 0,
++ /* IPSR4_11_8 [4] */
++ IFN_VI0_DATA7, FN_HRX1, FN_RTS1_N_TANS, 0,
++ 0, 0, 0, 0,
++ 0, 0, 0, 0,
++ 0, 0, 0, 0,
++ /* IPSR4_7_4 [4] */
++ IFN_VI0_DATA6, FN_HTX1, FN_CTS1_N, 0,
++ 0, 0, 0, 0,
++ 0, 0, 0, 0,
++ 0, 0, 0, 0,
++ /* IPSR4_3_0 [4] */
++ IFN_VI0_DATA5, FN_HCTS1_N, FN_TX1_A, 0,
++ 0, 0, 0, 0,
++ 0, 0, 0, 0,
++ 0, 0, 0, 0,
++ }
++ },
++ { PINMUX_CFG_REG_VAR("IPSR5", 0xE6060214, 32,
++ 4, 4, 4, 4, 4, 4, 4, 4) {
++ /* IPSR5_31_28 [4] */
++ IFN_VI1_DATA3, FN_CANFD0_RX_B, 0, FN_D6,
++ FN_MMC_D1, 0, 0, 0,
++ 0, 0, 0, 0,
++ 0, 0, 0, 0,
++ /* IPSR5_27_24 [4] */
++ IFN_VI1_DATA2, FN_CANFD0_TX_B, 0, FN_D5,
++ FN_MMC_D0, 0, 0, 0,
++ 0, 0, 0, 0,
++ 0, 0, 0, 0,
++ /* IPSR5_23_20 [4] */
++ IFN_VI1_DATA1, FN_MSIOF1_SS2, 0, FN_D4,
++ FN_MMC_CMD, 0, 0, 0,
++ 0, 0, 0, 0,
++ 0, 0, 0, 0,
++ /* IPSR5_19_16 [4] */
++ IFN_VI1_DATA0, FN_MSIOF1_SS1, 0, FN_D3,
++ 0, 0, 0, 0,
++ 0, 0, 0, 0,
++ 0, 0, 0, 0,
++ /* IPSR5_15_12 [4] */
++ IFN_VI1_VSYNC_N, FN_MSIOF1_SYNC, 0, FN_D2,
++ 0, 0, 0, 0,
++ 0, 0, 0, 0,
++ 0, 0, 0, 0,
++ /* IPSR5_11_8 [4] */
++ IFN_VI1_HSYNC_N, FN_MSIOF1_SCK, 0, FN_D1,
++ 0, 0, 0, 0,
++ 0, 0, 0, 0,
++ 0, 0, 0, 0,
++ /* IPSR5_7_4 [4] */
++ IFN_VI1_CLKENB, FN_MSIOF1_TXD, 0, FN_D0,
++ 0, 0, 0, 0,
++ 0, 0, 0, 0,
++ 0, 0, 0, 0,
++ /* IPSR5_3_0 [4] */
++ IFN_VI1_CLK, FN_MSIOF1_RXD, 0, FN_CS0_N,
++ 0, 0, 0, 0,
++ 0, 0, 0, 0,
++ 0, 0, 0, 0,
++ }
++ },
++ { PINMUX_CFG_REG_VAR("IPSR6", 0xE6060218, 32,
++ 4, 4, 4, 4, 4, 4, 4, 4) {
++ /* IPSR6_31_28 [4] */
++ IFN_VI1_DATA11, FN_SCL4, FN_IRQ4, FN_D14,
++ FN_MMC_WP, 0, 0, 0,
++ 0, 0, 0, 0,
++ 0, 0, 0, 0,
++ /* IPSR6_27_24 [4] */
++ IFN_VI1_DATA10, 0, 0, FN_D13,
++ FN_MMC_D7, FN_SDA3_B, 0, 0,
++ 0, 0, 0, 0,
++ 0, 0, 0, 0,
++ /* IPSR6_23_20 [4] */
++ IFN_VI1_DATA9, 0, FN_RTS4_N_TANS, FN_D12,
++ FN_MMC_D6, FN_SCL3_B, 0, 0,
++ 0, 0, 0, 0,
++ 0, 0, 0, 0,
++ /* IPSR6_19_16 [4] */
++ IFN_VI1_DATA8, 0, FN_CTS4_N, FN_D11,
++ FN_MMC_D5, 0, 0, 0,
++ 0, 0, 0, 0,
++ 0, 0, 0, 0,
++ /* IPSR6_15_12 [4] */
++ IFN_VI1_DATA7, 0, FN_TX4, FN_D10,
++ FN_MMC_D4, 0, 0, 0,
++ 0, 0, 0, 0,
++ 0, 0, 0, 0,
++ /* IPSR6_11_8 [4] */
++ IFN_VI1_DATA6, 0, FN_RX4, FN_D9,
++ FN_MMC_CLK, 0, 0, 0,
++ 0, 0, 0, 0,
++ 0, 0, 0, 0,
++ /* IPSR6_7_4 [4] */
++ IFN_VI1_DATA5, 0, FN_SCK4, FN_D8,
++ FN_MMC_D3, 0, 0, 0,
++ 0, 0, 0, 0,
++ 0, 0, 0, 0,
++ /* IPSR6_3_0 [4] */
++ IFN_VI1_DATA4, FN_CANFD_CLK_B, 0, FN_D7,
++ FN_MMC_D2, 0, 0, 0,
++ 0, 0, 0, 0,
++ 0, 0, 0, 0,
++ }
++ },
++ { PINMUX_CFG_REG_VAR("IPSR7", 0xE606021C, 32,
++ 4, 4, 4, 4, 4, 4, 4, 4) {
++ /* IPSR7_31_28 [4] */
++ IFN_AVB0_AVTP_CAPTURE, 0, 0, 0,
++ FN_FSCLKST2_N_B, 0, 0, 0,
++ 0, 0, 0, 0,
++ 0, 0, 0, 0,
++ /* IPSR7_27_24 [4] */
++ IFN_SDA2, FN_DU_DB1, FN_TCLK2_A, FN_EX_WAIT0,
++ FN_TX0, FN_MSIOF0_SS2, 0, 0,
++ 0, 0, 0, 0,
++ 0, 0, 0, 0,
++ /* IPSR7_23_20 [4] */
++ IFN_SCL2, FN_DU_DB0, FN_TCLK1_A, FN_WE1_N,
++ FN_RX0, FN_MSIOF0_SS1, 0, 0,
++ 0, 0, 0, 0,
++ 0, 0, 0, 0,
++ /* IPSR7_19_16 [4] */
++ IFN_SDA1, FN_DU_DG1, FN_TPU0TO3, FN_WE0_N,
++ FN_RTS0_N_TANS, FN_MSIOF0_SYNC, 0, 0,
++ 0, 0, 0, 0,
++ 0, 0, 0, 0,
++ /* IPSR7_15_12 [4] */
++ IFN_SCL1, FN_DU_DG0, FN_TPU0TO2, FN_RD_N,
++ FN_CTS0_N, FN_MSIOF0_SCK, 0, 0,
++ 0, 0, 0, 0,
++ 0, 0, 0, 0,
++ /* IPSR7_11_8 [4] */
++ IFN_SDA0, FN_DU_DR1, FN_TPU0TO1, FN_BS_N,
++ FN_SCK0, FN_MSIOF0_TXD, 0, 0,
++ 0, 0, 0, 0,
++ 0, 0, 0, 0,
++ /* IPSR7_7_4 [4] */
++ IFN_SCL0, FN_DU_DR0, FN_TPU0TO0, FN_CLKOUT,
++ 0, FN_MSIOF0_RXD, 0, 0,
++ 0, 0, 0, 0,
++ 0, 0, 0, 0,
++ /* IPSR7_3_0 [4] */
++ IFN_VI1_FIELD, FN_SDA4, FN_IRQ5, FN_D15,
++ FN_MMC_CD, 0, 0, 0,
++ 0, 0, 0, 0,
++ 0, 0, 0, 0,
++ }
++ },
++ { PINMUX_CFG_REG_VAR("IPSR8", 0xE6060220, 32,
++ 4, 4, 4, 4, 4, 4, 4, 4) {
++ /* IPSR8_31_28 [4] */
++ 0, 0, 0, 0,
++ 0, 0, 0, 0,
++ 0, 0, 0, 0,
++ 0, 0, 0, 0,
++ /* IPSR8_27_24 [4] */
++ IFN_DIGRF_CLKOUT, FN_DIGRF_CLKEN_OUT, 0, 0,
++ 0, 0, 0, 0,
++ 0, 0, 0, 0,
++ 0, 0, 0, 0,
++ /* IPSR8_23_20 [4] */
++ IFN_DIGRF_CLKIN, FN_DIGRF_CLKEN_IN, 0, 0,
++ 0, 0, 0, 0,
++ 0, 0, 0, 0,
++ 0, 0, 0, 0,
++ /* IPSR8_19_16 [4] */
++ IFN_CANFD_CLK_A, FN_CLK_EXTFXR, FN_PWM4_B, FN_SPEEDIN_B,
++ FN_SCIF_CLK_B, 0, 0, 0,
++ 0, 0, 0, 0,
++ 0, 0, 0, 0,
++ /* IPSR8_15_12 [4] */
++ IFN_CANFD1_RX, FN_RXDB_EXTFXR, FN_PWM3_B, FN_TCLK2_B,
++ FN_RX1_B, 0, 0, 0,
++ 0, 0, 0, 0,
++ 0, 0, 0, 0,
++ /* IPSR8_11_8 [4] */
++ IFN_CANFD1_TX, FN_FXR_TXDB, FN_PWM2_B, FN_TCLK1_B,
++ FN_TX1_B, 0, 0, 0,
++ 0, 0, 0, 0,
++ 0, 0, 0, 0,
++ /* IPSR8_7_4 [4] */
++ IFN_CANFD0_RX_A, FN_RXDA_EXTFXR, FN_PWM1_B, FN_DU_CDE,
++ 0, 0, 0, 0,
++ 0, 0, 0, 0,
++ 0, 0, 0, 0,
++ /* IPSR8_3_0 [4] */
++ IFN_CANFD0_TX_A, FN_FXR_TXDA, FN_PWM0_B, FN_DU_DISP,
++ FN_FSCLKST2_N_C, 0, 0, 0,
++ 0, 0, 0, 0,
++ 0, 0, 0, 0,
++ }
++ },
++ { PINMUX_CFG_REG("MOD_SEL0", 0xE6060500, 32, 1) {
++ /* reserved [31..24] */
++ 0, 0,
++ 0, 0,
++ 0, 0,
++ 0, 0,
++ 0, 0,
++ 0, 0,
++ 0, 0,
++ 0, 0,
++ /* reserved [23..16] */
++ 0, 0,
++ 0, 0,
++ 0, 0,
++ 0, 0,
++ 0, 0,
++ 0, 0,
++ 0, 0,
++ 0, 0,
++ /* reserved [15..11] */
++ 0, 0,
++ 0, 0,
++ 0, 0,
++ 0, 0,
++ 0, 0,
++ /* SEL_HSCIF0 [1] */
++ FN_SEL_HSCIF0_0,
++ FN_SEL_HSCIF0_1,
++ /* SEL_SCIF1 [1] */
++ FN_SEL_SCIF1_0,
++ FN_SEL_SCIF1_1,
++ /* SEL_CANFD0 [1] */
++ FN_SEL_CANFD0_0,
++ FN_SEL_CANFD0_1,
++ /* SEL_PWM4 [1] */
++ FN_SEL_PWM4_0,
++ FN_SEL_PWM4_1,
++ /* SEL_PWM3 [1] */
++ FN_SEL_PWM3_0,
++ FN_SEL_PWM3_1,
++ /* SEL_PWM2 [1] */
++ FN_SEL_PWM2_0,
++ FN_SEL_PWM2_1,
++ /* SEL_PWM1 [1] */
++ FN_SEL_PWM1_0,
++ FN_SEL_PWM1_1,
++ /* SEL_PWM0 [1] */
++ FN_SEL_PWM0_0,
++ FN_SEL_PWM0_1,
++ /* SEL_RFSO [1] */
++ FN_SEL_RFSO_0,
++ FN_SEL_RFSO_1,
++ /* SEL_RSP [1] */
++ FN_SEL_RSP_0,
++ FN_SEL_RSP_1,
++ /* SEL_TMU [1] */
++ FN_SEL_TMU_0,
++ FN_SEL_TMU_1,
++ }
++ },
++
++ /* under construction */
++ { PINMUX_CFG_REG("INOUTSEL0", 0xE6050004, 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_IN, GP_0_21_OUT,
++ GP_0_20_IN, GP_0_20_OUT,
++ GP_0_19_IN, GP_0_19_OUT,
++ GP_0_18_IN, GP_0_18_OUT,
++ GP_0_17_IN, GP_0_17_OUT,
++ GP_0_16_IN, GP_0_16_OUT,
++ GP_0_15_IN, GP_0_15_OUT,
++ GP_0_14_IN, GP_0_14_OUT,
++ GP_0_13_IN, GP_0_13_OUT,
++ GP_0_12_IN, GP_0_12_OUT,
++ GP_0_11_IN, GP_0_11_OUT,
++ GP_0_10_IN, GP_0_10_OUT,
++ GP_0_9_IN, GP_0_9_OUT,
++ GP_0_8_IN, GP_0_8_OUT,
++ GP_0_7_IN, GP_0_7_OUT,
++ GP_0_6_IN, GP_0_6_OUT,
++ GP_0_5_IN, GP_0_5_OUT,
++ GP_0_4_IN, GP_0_4_OUT,
++ GP_0_3_IN, GP_0_3_OUT,
++ GP_0_2_IN, GP_0_2_OUT,
++ GP_0_1_IN, GP_0_1_OUT,
++ GP_0_0_IN, GP_0_0_OUT,
++ }
++ },
++ { PINMUX_CFG_REG("INOUTSEL1", 0xE6051004, 32, 1) {
++ 0, 0,
++ 0, 0,
++ 0, 0,
++ 0, 0,
++ GP_1_27_IN, GP_1_27_OUT,
++ GP_1_26_IN, GP_1_26_OUT,
++ GP_1_25_IN, GP_1_25_OUT,
++ GP_1_24_IN, GP_1_24_OUT,
++ GP_1_23_IN, GP_1_23_OUT,
++ GP_1_22_IN, GP_1_22_OUT,
++ GP_1_21_IN, GP_1_21_OUT,
++ GP_1_20_IN, GP_1_20_OUT,
++ GP_1_19_IN, GP_1_19_OUT,
++ GP_1_18_IN, GP_1_18_OUT,
++ GP_1_17_IN, GP_1_17_OUT,
++ GP_1_16_IN, GP_1_16_OUT,
++ GP_1_15_IN, GP_1_15_OUT,
++ GP_1_14_IN, GP_1_14_OUT,
++ GP_1_13_IN, GP_1_13_OUT,
++ GP_1_12_IN, GP_1_12_OUT,
++ GP_1_11_IN, GP_1_11_OUT,
++ GP_1_10_IN, GP_1_10_OUT,
++ GP_1_9_IN, GP_1_9_OUT,
++ GP_1_8_IN, GP_1_8_OUT,
++ GP_1_7_IN, GP_1_7_OUT,
++ GP_1_6_IN, GP_1_6_OUT,
++ GP_1_5_IN, GP_1_5_OUT,
++ GP_1_4_IN, GP_1_4_OUT,
++ GP_1_3_IN, GP_1_3_OUT,
++ GP_1_2_IN, GP_1_2_OUT,
++ GP_1_1_IN, GP_1_1_OUT,
++ GP_1_0_IN, GP_1_0_OUT,
++ }
++ },
++ { PINMUX_CFG_REG("INOUTSEL2", 0xE6052004, 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_IN, GP_2_16_OUT,
++ GP_2_15_IN, GP_2_15_OUT,
++ GP_2_14_IN, GP_2_14_OUT,
++ GP_2_13_IN, GP_2_13_OUT,
++ GP_2_12_IN, GP_2_12_OUT,
++ GP_2_11_IN, GP_2_11_OUT,
++ GP_2_10_IN, GP_2_10_OUT,
++ GP_2_9_IN, GP_2_9_OUT,
++ GP_2_8_IN, GP_2_8_OUT,
++ GP_2_7_IN, GP_2_7_OUT,
++ GP_2_6_IN, GP_2_6_OUT,
++ GP_2_5_IN, GP_2_5_OUT,
++ GP_2_4_IN, GP_2_4_OUT,
++ GP_2_3_IN, GP_2_3_OUT,
++ GP_2_2_IN, GP_2_2_OUT,
++ GP_2_1_IN, GP_2_1_OUT,
++ GP_2_0_IN, GP_2_0_OUT,
++ }
++ },
++ { PINMUX_CFG_REG("INOUTSEL3", 0xE6053004, 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_IN, GP_3_16_OUT,
++ GP_3_15_IN, GP_3_15_OUT,
++ GP_3_14_IN, GP_3_14_OUT,
++ GP_3_13_IN, GP_3_13_OUT,
++ GP_3_12_IN, GP_3_12_OUT,
++ GP_3_11_IN, GP_3_11_OUT,
++ GP_3_10_IN, GP_3_10_OUT,
++ GP_3_9_IN, GP_3_9_OUT,
++ GP_3_8_IN, GP_3_8_OUT,
++ GP_3_7_IN, GP_3_7_OUT,
++ GP_3_6_IN, GP_3_6_OUT,
++ GP_3_5_IN, GP_3_5_OUT,
++ GP_3_4_IN, GP_3_4_OUT,
++ GP_3_3_IN, GP_3_3_OUT,
++ GP_3_2_IN, GP_3_2_OUT,
++ GP_3_1_IN, GP_3_1_OUT,
++ GP_3_0_IN, GP_3_0_OUT,
++ }
++ },
++ { PINMUX_CFG_REG("INOUTSEL4", 0xE6054004, 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_IN, GP_4_5_OUT,
++ GP_4_4_IN, GP_4_4_OUT,
++ GP_4_3_IN, GP_4_3_OUT,
++ GP_4_2_IN, GP_4_2_OUT,
++ GP_4_1_IN, GP_4_1_OUT,
++ GP_4_0_IN, GP_4_0_OUT,
++ }
++ },
++ { PINMUX_CFG_REG("INOUTSEL5", 0xE6055004, 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_IN, GP_5_14_OUT,
++ GP_5_13_IN, GP_5_13_OUT,
++ GP_5_12_IN, GP_5_12_OUT,
++ GP_5_11_IN, GP_5_11_OUT,
++ GP_5_10_IN, GP_5_10_OUT,
++ GP_5_9_IN, GP_5_9_OUT,
++ GP_5_8_IN, GP_5_8_OUT,
++ GP_5_7_IN, GP_5_7_OUT,
++ GP_5_6_IN, GP_5_6_OUT,
++ GP_5_5_IN, GP_5_5_OUT,
++ GP_5_4_IN, GP_5_4_OUT,
++ GP_5_3_IN, GP_5_3_OUT,
++ GP_5_2_IN, GP_5_2_OUT,
++ GP_5_1_IN, GP_5_1_OUT,
++ GP_5_0_IN, GP_5_0_OUT,
++ }
++ },
++ { },
++ { },
++ { },
++};
++
++static struct pinmux_data_reg pinmux_data_regs[] = {
++ /* use OUTDT registers? */
++ { PINMUX_DATA_REG("INDT0", 0xE6050008, 32) {
++ 0, 0, 0, 0, 0, 0, 0, 0,
++ 0, 0, GP_0_21_DATA, GP_0_20_DATA,
++ GP_0_19_DATA, GP_0_18_DATA, GP_0_17_DATA, GP_0_16_DATA,
++ GP_0_15_DATA, GP_0_14_DATA, GP_0_13_DATA, GP_0_12_DATA,
++ GP_0_11_DATA, GP_0_10_DATA, GP_0_9_DATA, GP_0_8_DATA,
++ GP_0_7_DATA, GP_0_6_DATA, GP_0_5_DATA, GP_0_4_DATA,
++ GP_0_3_DATA, GP_0_2_DATA, GP_0_1_DATA, GP_0_0_DATA }
++ },
++ { PINMUX_DATA_REG("INDT1", 0xE6051008, 32) {
++ 0, 0, 0, 0,
++ GP_1_27_DATA, GP_1_26_DATA, GP_1_25_DATA, GP_1_24_DATA,
++ GP_1_23_DATA, GP_1_22_DATA, GP_1_21_DATA, GP_1_20_DATA,
++ GP_1_19_DATA, GP_1_18_DATA, GP_1_17_DATA, GP_1_16_DATA,
++ GP_1_15_DATA, GP_1_14_DATA, GP_1_13_DATA, GP_1_12_DATA,
++ GP_1_11_DATA, GP_1_10_DATA, GP_1_9_DATA, GP_1_8_DATA,
++ GP_1_7_DATA, GP_1_6_DATA, GP_1_5_DATA, GP_1_4_DATA,
++ GP_1_3_DATA, GP_1_2_DATA, GP_1_1_DATA, GP_1_0_DATA }
++ },
++ { PINMUX_DATA_REG("INDT2", 0xE6052008, 32) {
++ 0, 0, 0, 0, 0, 0, 0, 0,
++ 0, 0, 0, 0, 0, 0, 0, GP_2_16_DATA,
++ GP_2_15_DATA, GP_2_14_DATA, GP_2_13_DATA, GP_2_12_DATA,
++ GP_2_11_DATA, GP_2_10_DATA, GP_2_9_DATA, GP_2_8_DATA,
++ GP_2_7_DATA, GP_2_6_DATA, GP_2_5_DATA, GP_2_4_DATA,
++ GP_2_3_DATA, GP_2_2_DATA, GP_2_1_DATA, GP_2_0_DATA }
++ },
++ { PINMUX_DATA_REG("INDT3", 0xE6053008, 32) {
++ 0, 0, 0, 0, 0, 0, 0, 0,
++ 0, 0, 0, 0, 0, 0, 0, GP_3_16_DATA,
++ GP_3_15_DATA, GP_3_14_DATA, GP_3_13_DATA, GP_3_12_DATA,
++ GP_3_11_DATA, GP_3_10_DATA, GP_3_9_DATA, GP_3_8_DATA,
++ GP_3_7_DATA, GP_3_6_DATA, GP_3_5_DATA, GP_3_4_DATA,
++ GP_3_3_DATA, GP_3_2_DATA, GP_3_1_DATA, GP_3_0_DATA }
++ },
++ { PINMUX_DATA_REG("INDT4", 0xE6054008, 32) {
++ 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_DATA, GP_4_4_DATA,
++ GP_4_3_DATA, GP_4_2_DATA, GP_4_1_DATA, GP_4_0_DATA }
++ },
++ { PINMUX_DATA_REG("INDT5", 0xE6055008, 32) {
++ 0, 0, 0, 0, 0, 0, 0, 0,
++ 0, 0, 0, 0, 0, 0, 0, 0,
++ 0, GP_5_14_DATA, GP_5_13_DATA, GP_5_12_DATA,
++ GP_5_11_DATA, GP_5_10_DATA, GP_5_9_DATA, GP_5_8_DATA,
++ GP_5_7_DATA, GP_5_6_DATA, GP_5_5_DATA, GP_5_4_DATA,
++ GP_5_3_DATA, GP_5_2_DATA, GP_5_1_DATA, GP_5_0_DATA }
++ },
++ { },
++ { },
++ { },
++};
++
++static struct pinmux_info r8a7797_pinmux_info = {
++ .name = "r8a7797_pfc",
++
++ .unlock_reg = 0xe6060000, /* PMMR */
++
++ .reserved_id = PINMUX_RESERVED,
++ .data = { PINMUX_DATA_BEGIN, PINMUX_DATA_END },
++ .input = { PINMUX_INPUT_BEGIN, PINMUX_INPUT_END },
++ .output = { PINMUX_OUTPUT_BEGIN, PINMUX_OUTPUT_END },
++ .mark = { PINMUX_MARK_BEGIN, PINMUX_MARK_END },
++ .function = { PINMUX_FUNCTION_BEGIN, PINMUX_FUNCTION_END },
++
++ .first_gpio = GPIO_GP_0_0,
++ .last_gpio = GPIO_FN_DIGRF_CLKEN_OUT,
++
++ .gpios = pinmux_gpios,
++ .cfg_regs = pinmux_config_regs,
++ .data_regs = pinmux_data_regs,
++
++ .gpio_data = pinmux_data,
++ .gpio_data_size = ARRAY_SIZE(pinmux_data),
++};
++
++void r8a7797_pinmux_init(void)
++{
++ register_pinmux(&r8a7797_pinmux_info);
++}
+diff --git a/arch/arm/cpu/armv8/rcar_gen3/pfc.c b/arch/arm/cpu/armv8/rcar_gen3/pfc.c
+index 0543f11..bd3aa0a 100644
+--- a/arch/arm/cpu/armv8/rcar_gen3/pfc.c
++++ b/arch/arm/cpu/armv8/rcar_gen3/pfc.c
+@@ -20,5 +20,7 @@ void pinmux_init(void)
+ r8a7795_pinmux_init();
+ #elif defined(CONFIG_R8A7796X)
+ r8a7796_pinmux_init();
++#elif defined(CONFIG_R8A7797)
++ r8a7797_pinmux_init();
+ #endif
+ }
+diff --git a/arch/arm/cpu/armv8/rcar_gen3/prr_depend.c b/arch/arm/cpu/armv8/rcar_gen3/prr_depend.c
+index 776c596..8de3a16 100644
+--- a/arch/arm/cpu/armv8/rcar_gen3/prr_depend.c
++++ b/arch/arm/cpu/armv8/rcar_gen3/prr_depend.c
+@@ -98,10 +98,37 @@ int rcar_need_reconfig_sdhi_drvctrl(void)
+ #define SDH800_SD200 (SD_SRCFC_DIV1 | SD_FC_DIV4)
+ #define SDH400_SD200 (SD_SRCFC_DIV1 | SD_FC_DIV2)
+
++/*
++ * for sd/mmc function(V3M)
++ */
++#define SDHFC_BIT (8)
++#define SD_SDHFC_DIV2 (0 << SDHFC_BIT)
++#define SD_SDHFC_DIV3 (1 << SDHFC_BIT)
++#define SD_SDHFC_DIV4 (2 << SDHFC_BIT)
++#define SD_SDHFC_DIV6 (3 << SDHFC_BIT)
++#define SD_SDHFC_DIV8 (4 << SDHFC_BIT)
++#define SD_SDHFC_DIV12 (5 << SDHFC_BIT)
++#define SD_SDHFC_DIV16 (6 << SDHFC_BIT)
++#define SD_SDHFC_DIV18 (7 << SDHFC_BIT)
++#define SD_SDHFC_DIV24 (8 << SDHFC_BIT)
++#define SD_SDHFC_DIV36 (10 << SDHFC_BIT)
++#define SD_SDHFC_DIV48 (11 << SDHFC_BIT)
++#define SD0FC_BIT (4)
++#define SD_SD0FC_DIV8 (4 << SD0FC_BIT)
++#define SD_SD0FC_DIV10 (12 << SD0FC_BIT)
++#define SD_SD0FC_DIV12 (5 << SD0FC_BIT)
++#define SD_SD0FC_DIV16 (6 << SD0FC_BIT)
++#define SD_SD0FC_DIV18 (7 << SD0FC_BIT)
++#define SD_SD0FC_DIV24 (8 << SD0FC_BIT)
++#define SD_SD0FC_DIV36 (10 << SD0FC_BIT)
++#define SD_SD0FC_DIV48 (11 << SD0FC_BIT)
++
+ int rcar_get_sdhi_config_clk(void)
+ {
+ if (RCAR_PRR_IS_PRODUCT(H3) && (!RCAR_PRR_CHK_CUT(H3, WS10)))
+ return SDH400_SD200;
++ else if (RCAR_PRR_IS_PRODUCT(V3M))
++ return (SD_SDHFC_DIV2 | SD_SD0FC_DIV8);
+ else
+ return SDH800_SD200;
+ }
+diff --git a/arch/arm/include/asm/arch-rcar_gen3/gpio.h b/arch/arm/include/asm/arch-rcar_gen3/gpio.h
+index c58edf4..fb8b758 100644
+--- a/arch/arm/include/asm/arch-rcar_gen3/gpio.h
++++ b/arch/arm/include/asm/arch-rcar_gen3/gpio.h
+@@ -16,6 +16,8 @@
+ #include <asm/arch/r8a7795-gpio.h>
+ #elif defined(CONFIG_R8A7796X)
+ #include <asm/arch/r8a7796-gpio.h>
++#elif defined(CONFIG_R8A7797)
++#include <asm/arch/r8a7797-gpio.h>
+ #endif
+
+ #if defined(CONFIG_R8A7795)
+@@ -23,6 +25,8 @@ void r8a7795_pinmux_init(void);
+ void r8a7795_es_pinmux_init(void);
+ #elif defined(CONFIG_R8A7796X)
+ void r8a7796_pinmux_init(void);
++#elif defined(CONFIG_R8A7797)
++void r8a7797_pinmux_init(void);
+ #endif
+ void pinmux_init(void);
+
+diff --git a/arch/arm/include/asm/arch-rcar_gen3/r8a7797-gpio.h b/arch/arm/include/asm/arch-rcar_gen3/r8a7797-gpio.h
+new file mode 100644
+index 0000000..40cccd9
+--- /dev/null
++++ b/arch/arm/include/asm/arch-rcar_gen3/r8a7797-gpio.h
+@@ -0,0 +1,456 @@
++/*
++ * arch/arm/include/asm/arch-rcar_gen3/r8a7797-gpio.h
++ * This file defines pin function control of gpio.
++ *
++ * Copyright (C) 2016 Renesas Electronics Corporation
++ *
++ * SPDX-License-Identifier: GPL-2.0+
++ */
++#ifndef __ASM_R8A7797_GPIO_H__
++#define __ASM_R8A7797_GPIO_H__
++
++/* Pin Function Controller:
++ * GPIO_FN_xx - GPIO used to select pin function
++ * GPIO_GP_x_x - GPIO mapped to real I/O pin on CPU
++ */
++enum {
++ GPIO_GP_0_0, GPIO_GP_0_1, GPIO_GP_0_2, GPIO_GP_0_3,
++ GPIO_GP_0_4, GPIO_GP_0_5, GPIO_GP_0_6, GPIO_GP_0_7,
++ GPIO_GP_0_8, GPIO_GP_0_9, GPIO_GP_0_10, GPIO_GP_0_11,
++ GPIO_GP_0_12, GPIO_GP_0_13, GPIO_GP_0_14, GPIO_GP_0_15,
++ GPIO_GP_0_16, GPIO_GP_0_17, GPIO_GP_0_18, GPIO_GP_0_19,
++ GPIO_GP_0_20, GPIO_GP_0_21,
++
++ GPIO_GP_1_0, GPIO_GP_1_1, GPIO_GP_1_2, GPIO_GP_1_3,
++ GPIO_GP_1_4, GPIO_GP_1_5, GPIO_GP_1_6, GPIO_GP_1_7,
++ GPIO_GP_1_8, GPIO_GP_1_9, GPIO_GP_1_10, GPIO_GP_1_11,
++ GPIO_GP_1_12, GPIO_GP_1_13, GPIO_GP_1_14, GPIO_GP_1_15,
++ GPIO_GP_1_16, GPIO_GP_1_17, GPIO_GP_1_18, GPIO_GP_1_19,
++ GPIO_GP_1_20, GPIO_GP_1_21, GPIO_GP_1_22, GPIO_GP_1_23,
++ GPIO_GP_1_24, GPIO_GP_1_25, GPIO_GP_1_26, GPIO_GP_1_27,
++
++ GPIO_GP_2_0, GPIO_GP_2_1, GPIO_GP_2_2, GPIO_GP_2_3,
++ GPIO_GP_2_4, GPIO_GP_2_5, GPIO_GP_2_6, GPIO_GP_2_7,
++ GPIO_GP_2_8, GPIO_GP_2_9, GPIO_GP_2_10, GPIO_GP_2_11,
++ GPIO_GP_2_12, GPIO_GP_2_13, GPIO_GP_2_14, GPIO_GP_2_15,
++ GPIO_GP_2_16,
++
++ GPIO_GP_3_0, GPIO_GP_3_1, GPIO_GP_3_2, GPIO_GP_3_3,
++ GPIO_GP_3_4, GPIO_GP_3_5, GPIO_GP_3_6, GPIO_GP_3_7,
++ GPIO_GP_3_8, GPIO_GP_3_9, GPIO_GP_3_10, GPIO_GP_3_11,
++ GPIO_GP_3_12, GPIO_GP_3_13, GPIO_GP_3_14, GPIO_GP_3_15,
++ GPIO_GP_3_16,
++
++ GPIO_GP_4_0, GPIO_GP_4_1, GPIO_GP_4_2, GPIO_GP_4_3,
++ GPIO_GP_4_4, GPIO_GP_4_5,
++
++ GPIO_GP_5_0, GPIO_GP_5_1, GPIO_GP_5_2, GPIO_GP_5_3,
++ GPIO_GP_5_4, GPIO_GP_5_5, GPIO_GP_5_6, GPIO_GP_5_7,
++ GPIO_GP_5_8, GPIO_GP_5_9, GPIO_GP_5_10, GPIO_GP_5_11,
++ GPIO_GP_5_12, GPIO_GP_5_13, GPIO_GP_5_14,
++
++ /* GPSR0 */
++ GPIO_GFN_DU_EXODDF_DU_ODDF_DISP_CDE,
++ GPIO_GFN_DU_EXVSYNC_DU_VSYNC,
++ GPIO_GFN_DU_EXHSYNC_DU_HSYNC,
++ GPIO_GFN_DU_DOTCLKOUT,
++ GPIO_GFN_DU_DB7,
++ GPIO_GFN_DU_DB6,
++ GPIO_GFN_DU_DB5,
++ GPIO_GFN_DU_DB4,
++ GPIO_GFN_DU_DB3,
++ GPIO_GFN_DU_DB2,
++ GPIO_GFN_DU_DG7,
++ GPIO_GFN_DU_DG6,
++ GPIO_GFN_DU_DG5,
++ GPIO_GFN_DU_DG4,
++ GPIO_GFN_DU_DG3,
++ GPIO_GFN_DU_DG2,
++ GPIO_GFN_DU_DR7,
++ GPIO_GFN_DU_DR6,
++ GPIO_GFN_DU_DR5,
++ GPIO_GFN_DU_DR4,
++ GPIO_GFN_DU_DR3,
++ GPIO_GFN_DU_DR2,
++
++ /* GPSR1 */
++ GPIO_GFN_DIGRF_CLKOUT,
++ GPIO_GFN_DIGRF_CLKIN,
++ GPIO_GFN_CANFD_CLK_A,
++ GPIO_GFN_CANFD1_RX,
++ GPIO_GFN_CANFD1_TX,
++ GPIO_GFN_CANFD0_RX_A,
++ GPIO_GFN_CANFD0_TX_A,
++ GPIO_GFN_AVB0_AVTP_CAPTURE,
++ GPIO_FN_AVB0_AVTP_MATCH,
++ GPIO_FN_AVB0_LINK,
++ GPIO_FN_AVB0_PHY_INT,
++ GPIO_FN_AVB0_MAGIC,
++ GPIO_FN_AVB0_MDC,
++ GPIO_FN_AVB0_MDIO,
++ GPIO_FN_AVB0_TXCREFCLK,
++ GPIO_FN_AVB0_TD3,
++ GPIO_FN_AVB0_TD2,
++ GPIO_FN_AVB0_TD1,
++ GPIO_FN_AVB0_TD0,
++ GPIO_FN_AVB0_TXC,
++ GPIO_FN_AVB0_TX_CTL,
++ GPIO_FN_AVB0_RD3,
++ GPIO_FN_AVB0_RD2,
++ GPIO_FN_AVB0_RD1,
++ GPIO_FN_AVB0_RD0,
++ GPIO_FN_AVB0_RXC,
++ GPIO_FN_AVB0_RX_CTL,
++ GPIO_GFN_IRQ0,
++
++ /* GPSR2 */
++ GPIO_GFN_VI0_FIELD,
++ GPIO_GFN_VI0_DATA11,
++ GPIO_GFN_VI0_DATA10,
++ GPIO_GFN_VI0_DATA9,
++ GPIO_GFN_VI0_DATA8,
++ GPIO_GFN_VI0_DATA7,
++ GPIO_GFN_VI0_DATA6,
++ GPIO_GFN_VI0_DATA5,
++ GPIO_GFN_VI0_DATA4,
++ GPIO_GFN_VI0_DATA3,
++ GPIO_GFN_VI0_DATA2,
++ GPIO_GFN_VI0_DATA1,
++ GPIO_GFN_VI0_DATA0,
++ GPIO_GFN_VI0_VSYNC_N,
++ GPIO_GFN_VI0_HSYNC_N,
++ GPIO_GFN_VI0_CLKENB,
++ GPIO_GFN_VI0_CLK,
++
++ /* GPSR3 */
++ GPIO_GFN_VI1_FIELD,
++ GPIO_GFN_VI1_DATA11,
++ GPIO_GFN_VI1_DATA10,
++ GPIO_GFN_VI1_DATA9,
++ GPIO_GFN_VI1_DATA8,
++ GPIO_GFN_VI1_DATA7,
++ GPIO_GFN_VI1_DATA6,
++ GPIO_GFN_VI1_DATA5,
++ GPIO_GFN_VI1_DATA4,
++ GPIO_GFN_VI1_DATA3,
++ GPIO_GFN_VI1_DATA2,
++ GPIO_GFN_VI1_DATA1,
++ GPIO_GFN_VI1_DATA0,
++ GPIO_GFN_VI1_VSYNC_N,
++ GPIO_GFN_VI1_HSYNC_N,
++ GPIO_GFN_VI1_CLKENB,
++ GPIO_GFN_VI1_CLK,
++
++ /* GPSR4 */
++ GPIO_GFN_SDA2,
++ GPIO_GFN_SCL2,
++ GPIO_GFN_SDA1,
++ GPIO_GFN_SCL1,
++ GPIO_GFN_SDA0,
++ GPIO_GFN_SCL0,
++
++ /* GPSR5 */
++ GPIO_FN_RPC_INT_N,
++ GPIO_FN_RPC_WP_N,
++ GPIO_FN_RPC_RESET_N,
++ GPIO_FN_QSPI1_SSL,
++ GPIO_FN_QSPI1_IO3,
++ GPIO_FN_QSPI1_IO2,
++ GPIO_FN_QSPI1_MISO_IO1,
++ GPIO_FN_QSPI1_MOSI_IO0,
++ GPIO_FN_QSPI1_SPCLK,
++ GPIO_FN_QSPI0_SSL,
++ GPIO_FN_QSPI0_IO3,
++ GPIO_FN_QSPI0_IO2,
++ GPIO_FN_QSPI0_MISO_IO1,
++ GPIO_FN_QSPI0_MOSI_IO0,
++ GPIO_FN_QSPI0_SPCLK,
++
++ /* IPSR0 */
++ GPIO_IFN_DU_DR2,
++ GPIO_FN_HSCK0,
++ GPIO_FN_A0,
++ GPIO_IFN_DU_DR3,
++ GPIO_FN_HRTS0_N,
++ GPIO_FN_A1,
++ GPIO_IFN_DU_DR4,
++ GPIO_FN_HCTS0_N,
++ GPIO_FN_A2,
++ GPIO_IFN_DU_DR5,
++ GPIO_FN_HTX0,
++ GPIO_FN_A3,
++ GPIO_IFN_DU_DR6,
++ GPIO_FN_MSIOF3_RXD,
++ GPIO_FN_A4,
++ GPIO_IFN_DU_DR7,
++ GPIO_FN_MSIOF3_TXD,
++ GPIO_FN_A5,
++ GPIO_IFN_DU_DG2,
++ GPIO_FN_MSIOF3_SS1,
++ GPIO_FN_A6,
++ GPIO_IFN_DU_DG3,
++ GPIO_FN_MSIOF3_SS2,
++ GPIO_FN_A7,
++ GPIO_FN_PWMFSW0,
++
++ /* IPSR1 */
++ GPIO_IFN_DU_DG4,
++ GPIO_FN_A8,
++ GPIO_FN_FSO_CFE_0_N_A,
++ GPIO_IFN_DU_DG5,
++ GPIO_FN_A9,
++ GPIO_FN_FSO_CFE_1_N_A,
++ GPIO_IFN_DU_DG6,
++ GPIO_FN_A10,
++ GPIO_FN_FSO_TOE_N_A,
++ GPIO_IFN_DU_DG7,
++ GPIO_FN_A11,
++ GPIO_FN_IRQ1,
++ GPIO_IFN_DU_DB2,
++ GPIO_FN_A12,
++ GPIO_FN_IRQ2,
++ GPIO_IFN_DU_DB3,
++ GPIO_FN_A13,
++ GPIO_FN_FXR_CLKOUT1,
++ GPIO_IFN_DU_DB4,
++ GPIO_FN_A14,
++ GPIO_FN_FXR_CLKOUT2,
++ GPIO_IFN_DU_DB5,
++ GPIO_FN_A15,
++ GPIO_FN_FXR_TXENA_N,
++
++ /* IPSR2 */
++ GPIO_IFN_DU_DB6,
++ GPIO_FN_A16,
++ GPIO_FN_FXR_TXENB_N,
++ GPIO_IFN_DU_DB7,
++ GPIO_FN_A17,
++ GPIO_FN_STPWT_EXTFXR,
++ GPIO_IFN_DU_DOTCLKOUT,
++ GPIO_FN_SCIF_CLK_A,
++ GPIO_FN_A18,
++ GPIO_IFN_DU_EXHSYNC_DU_HSYNC,
++ GPIO_FN_HRX0,
++ GPIO_FN_A19,
++ GPIO_FN_IRQ3,
++ GPIO_IFN_DU_EXVSYNC_DU_VSYNC,
++ GPIO_FN_MSIOF3_SCK,
++ GPIO_FN_A20,
++ GPIO_IFN_DU_EXODDF_DU_ODDF_DISP_CDE,
++ GPIO_FN_MSIOF3_SYNC,
++ GPIO_FN_A21,
++ GPIO_IFN_IRQ0,
++ GPIO_FN_CC5_OSCOUT,
++ GPIO_IFN_VI0_CLK,
++ GPIO_FN_MSIOF2_SCK,
++ GPIO_FN_SCK3,
++ GPIO_FN_HSCK3,
++
++ /* IPSR3 */
++ GPIO_IFN_VI0_CLKENB,
++ GPIO_FN_MSIOF2_RXD,
++ GPIO_FN_RX3,
++ GPIO_FN_RD_WR_N,
++ GPIO_FN_HCTS3_N,
++ GPIO_IFN_VI0_HSYNC_N,
++ GPIO_FN_MSIOF2_TXD,
++ GPIO_FN_TX3,
++ GPIO_FN_HRTS3_N,
++ GPIO_IFN_VI0_VSYNC_N,
++ GPIO_FN_MSIOF2_SYNC,
++ GPIO_FN_CTS3_N,
++ GPIO_FN_HTX3,
++ GPIO_IFN_VI0_DATA0,
++ GPIO_FN_MSIOF2_SS1,
++ GPIO_FN_RTS3_N_TANS,
++ GPIO_FN_HRX3,
++ GPIO_IFN_VI0_DATA1,
++ GPIO_FN_MSIOF2_SS2,
++ GPIO_FN_SCK1,
++ GPIO_FN_SPEEDIN_A,
++ GPIO_IFN_VI0_DATA2,
++ GPIO_FN_AVB0_AVTP_PPS,
++ GPIO_FN_SDA3_A,
++ GPIO_IFN_VI0_DATA3,
++ GPIO_FN_HSCK1,
++ GPIO_FN_SCL3_A,
++ GPIO_IFN_VI0_DATA4,
++ GPIO_FN_HRTS1_N,
++ GPIO_FN_RX1_A,
++
++ /* IPSR4 */
++ GPIO_IFN_VI0_DATA5,
++ GPIO_FN_HCTS1_N,
++ GPIO_FN_TX1_A,
++ GPIO_IFN_VI0_DATA6,
++ GPIO_FN_HTX1,
++ GPIO_FN_CTS1_N,
++ GPIO_IFN_VI0_DATA7,
++ GPIO_FN_HRX1,
++ GPIO_FN_RTS1_N_TANS,
++ GPIO_IFN_VI0_DATA8,
++ GPIO_FN_HSCK2,
++ GPIO_FN_PWM0_A,
++ GPIO_FN_A22,
++ GPIO_IFN_VI0_DATA9,
++ GPIO_FN_HCTS2_N,
++ GPIO_FN_PWM1_A,
++ GPIO_FN_A23,
++ GPIO_FN_FSO_CFE_0_N_B,
++ GPIO_IFN_VI0_DATA10,
++ GPIO_FN_HRTS2_N,
++ GPIO_FN_PWM2_A,
++ GPIO_FN_A24,
++ GPIO_FN_FSO_CFE_1_N_B,
++ GPIO_IFN_VI0_DATA11,
++ GPIO_FN_HTX2,
++ GPIO_FN_PWM3_A,
++ GPIO_FN_A25,
++ GPIO_FN_FSO_TOE_N_B,
++ GPIO_IFN_VI0_FIELD,
++ GPIO_FN_HRX2,
++ GPIO_FN_PWM4_A,
++ GPIO_FN_CS1_N_A26,
++ GPIO_FN_FSCLKST2_N_A,
++
++ /* IPSR5 */
++ GPIO_IFN_VI1_CLK,
++ GPIO_FN_MSIOF1_RXD,
++ GPIO_FN_CS0_N,
++ GPIO_IFN_VI1_CLKENB,
++ GPIO_FN_MSIOF1_TXD,
++ GPIO_FN_D0,
++ GPIO_IFN_VI1_HSYNC_N,
++ GPIO_FN_MSIOF1_SCK,
++ GPIO_FN_D1,
++ GPIO_IFN_VI1_VSYNC_N,
++ GPIO_FN_MSIOF1_SYNC,
++ GPIO_FN_D2,
++ GPIO_IFN_VI1_DATA0,
++ GPIO_FN_MSIOF1_SS1,
++ GPIO_FN_D3,
++ GPIO_IFN_VI1_DATA1,
++ GPIO_FN_MSIOF1_SS2,
++ GPIO_FN_D4,
++ GPIO_FN_MMC_CMD,
++ GPIO_IFN_VI1_DATA2,
++ GPIO_FN_CANFD0_TX_B,
++ GPIO_FN_D5,
++ GPIO_FN_MMC_D0,
++ GPIO_IFN_VI1_DATA3,
++ GPIO_FN_CANFD0_RX_B,
++ GPIO_FN_D6,
++ GPIO_FN_MMC_D1,
++
++ /* IPSR6 */
++ GPIO_IFN_VI1_DATA4,
++ GPIO_FN_CANFD_CLK_B,
++ GPIO_FN_D7,
++ GPIO_FN_MMC_D2,
++ GPIO_IFN_VI1_DATA5,
++ GPIO_FN_SCK4,
++ GPIO_FN_D8,
++ GPIO_FN_MMC_D3,
++ GPIO_IFN_VI1_DATA6,
++ GPIO_FN_RX4,
++ GPIO_FN_D9,
++ GPIO_FN_MMC_CLK,
++ GPIO_IFN_VI1_DATA7,
++ GPIO_FN_TX4,
++ GPIO_FN_D10,
++ GPIO_FN_MMC_D4,
++ GPIO_IFN_VI1_DATA8,
++ GPIO_FN_CTS4_N,
++ GPIO_FN_D11,
++ GPIO_FN_MMC_D5,
++ GPIO_IFN_VI1_DATA9,
++ GPIO_FN_RTS4_N_TANS,
++ GPIO_FN_D12,
++ GPIO_FN_MMC_D6,
++ GPIO_FN_SCL3_B,
++ GPIO_IFN_VI1_DATA10,
++ GPIO_FN_D13,
++ GPIO_FN_MMC_D7,
++ GPIO_FN_SDA3_B,
++ GPIO_IFN_VI1_DATA11,
++ GPIO_FN_SCL4,
++ GPIO_FN_IRQ4,
++ GPIO_FN_D14,
++ GPIO_FN_MMC_WP,
++
++ /* IPSR7 */
++ GPIO_IFN_VI1_FIELD,
++ GPIO_FN_SDA4,
++ GPIO_FN_IRQ5,
++ GPIO_FN_D15,
++ GPIO_FN_MMC_CD,
++ GPIO_IFN_SCL0,
++ GPIO_FN_DU_DR0,
++ GPIO_FN_TPU0TO0,
++ GPIO_FN_CLKOUT,
++ GPIO_FN_MSIOF0_RXD,
++ GPIO_IFN_SDA0,
++ GPIO_FN_DU_DR1,
++ GPIO_FN_TPU0TO1,
++ GPIO_FN_BS_N,
++ GPIO_FN_SCK0,
++ GPIO_FN_MSIOF0_TXD,
++ GPIO_IFN_SCL1,
++ GPIO_FN_DU_DG0,
++ GPIO_FN_TPU0TO2,
++ GPIO_FN_RD_N,
++ GPIO_FN_CTS0_N,
++ GPIO_FN_MSIOF0_SCK,
++ GPIO_IFN_SDA1,
++ GPIO_FN_DU_DG1,
++ GPIO_FN_TPU0TO3,
++ GPIO_FN_WE0_N,
++ GPIO_FN_RTS0_N_TANS,
++ GPIO_FN_MSIOF0_SYNC,
++ GPIO_IFN_SCL2,
++ GPIO_FN_DU_DB0,
++ GPIO_FN_TCLK1_A,
++ GPIO_FN_WE1_N,
++ GPIO_FN_RX0,
++ GPIO_FN_MSIOF0_SS1,
++ GPIO_IFN_SDA2,
++ GPIO_FN_DU_DB1,
++ GPIO_FN_TCLK2_A,
++ GPIO_FN_EX_WAIT0,
++ GPIO_FN_TX0,
++ GPIO_FN_MSIOF0_SS2,
++ GPIO_IFN_AVB0_AVTP_CAPTURE,
++ GPIO_FN_FSCLKST2_N_B,
++
++ /* IPSR8 */
++ GPIO_IFN_CANFD0_TX_A,
++ GPIO_FN_FXR_TXDA,
++ GPIO_FN_PWM0_B,
++ GPIO_FN_DU_DISP,
++ GPIO_FN_FSCLKST2_N_C,
++ GPIO_IFN_CANFD0_RX_A,
++ GPIO_FN_RXDA_EXTFXR,
++ GPIO_FN_PWM1_B,
++ GPIO_FN_DU_CDE,
++ GPIO_IFN_CANFD1_TX,
++ GPIO_FN_FXR_TXDB,
++ GPIO_FN_PWM2_B,
++ GPIO_FN_TCLK1_B,
++ GPIO_FN_TX1_B,
++ GPIO_IFN_CANFD1_RX,
++ GPIO_FN_RXDB_EXTFXR,
++ GPIO_FN_PWM3_B,
++ GPIO_FN_TCLK2_B,
++ GPIO_FN_RX1_B,
++ GPIO_IFN_CANFD_CLK_A,
++ GPIO_FN_CLK_EXTFXR,
++ GPIO_FN_PWM4_B,
++ GPIO_FN_SPEEDIN_B,
++ GPIO_FN_SCIF_CLK_B,
++ GPIO_IFN_DIGRF_CLKIN,
++ GPIO_FN_DIGRF_CLKEN_IN,
++ GPIO_IFN_DIGRF_CLKOUT,
++ GPIO_FN_DIGRF_CLKEN_OUT,
++};
++
++#endif /* __ASM_R8A7797_GPIO_H__ */
+diff --git a/arch/arm/include/asm/arch-rcar_gen3/r8a7797.h b/arch/arm/include/asm/arch-rcar_gen3/r8a7797.h
+new file mode 100644
+index 0000000..09e83ba
+--- /dev/null
++++ b/arch/arm/include/asm/arch-rcar_gen3/r8a7797.h
+@@ -0,0 +1,33 @@
++/*
++ * arch/arm/include/asm/arch-rcar_gen3/r8a7797.h
++ * This file defines registers and value for r8a7797.
++ *
++ * Copyright (C) 2016 Renesas Electronics Corporation
++ *
++ * SPDX-License-Identifier: GPL-2.0+
++ */
++
++#ifndef __ASM_ARCH_R8A7797_H
++#define __ASM_ARCH_R8A7797_H
++
++#include "rcar-base.h"
++
++/* Module stop control/status register bits */
++#define MSTP0_BITS 0x00230000
++#define MSTP1_BITS 0xFFFFFFFF
++#define MSTP2_BITS 0x14062FD8
++#define MSTP3_BITS 0xFFFFFFDF
++#define MSTP4_BITS 0x80000184
++#define MSTP5_BITS 0x83FFFFFF
++#define MSTP6_BITS 0xFFFFFFFF
++#define MSTP7_BITS 0xFFFFFFFF
++#define MSTP8_BITS 0x7FF3FFF4
++#define MSTP9_BITS 0xFBF7FF97
++#define MSTP10_BITS 0xFFFEFFE0
++#define MSTP11_BITS 0x000000B7
++
++/* SDHI */
++#define CONFIG_SYS_SH_SDHI2_BASE 0xEE140000 /* either MMC0 */
++#define CONFIG_SYS_SH_SDHI_NR_CHANNEL 1
++
++#endif /* __ASM_ARCH_R8A7797_H */
+diff --git a/arch/arm/include/asm/arch-rcar_gen3/rcar-base.h b/arch/arm/include/asm/arch-rcar_gen3/rcar-base.h
+index 18c1a74..fa24fc4 100644
+--- a/arch/arm/include/asm/arch-rcar_gen3/rcar-base.h
++++ b/arch/arm/include/asm/arch-rcar_gen3/rcar-base.h
+@@ -70,6 +70,11 @@
+ #define SMSTPCR10 0xE6150998
+ #define SMSTPCR11 0xE615099C
+
++/* PLL */
++#define PLL0CR 0xE61500D8
++#define PLL0_STC_MASK 0x7F000000
++#define PLL0_STC_BIT 24
++
+ /* SH-I2C */
+ #define CONFIG_SYS_I2C_SH_BASE0 0xE60B0000
+
+diff --git a/arch/arm/include/asm/arch-rcar_gen3/rcar_gen3.h b/arch/arm/include/asm/arch-rcar_gen3/rcar_gen3.h
+index b412fad..c2ba0fb 100644
+--- a/arch/arm/include/asm/arch-rcar_gen3/rcar_gen3.h
++++ b/arch/arm/include/asm/arch-rcar_gen3/rcar_gen3.h
+@@ -14,6 +14,8 @@
+ #include <asm/arch/r8a7795.h>
+ #elif defined(CONFIG_R8A7796X)
+ #include <asm/arch/r8a7796.h>
++ #elif defined(CONFIG_R8A7797)
++ #include <asm/arch/r8a7797.h>
+ #else
+ #error "SOC Name not defined"
+ #endif
+diff --git a/drivers/serial/serial_sh.h b/drivers/serial/serial_sh.h
+index fe71e9a..478824e 100644
+--- a/drivers/serial/serial_sh.h
++++ b/drivers/serial/serial_sh.h
+@@ -226,7 +226,8 @@ struct uart_port {
+ # define SCSCR_INIT(port) 0x38 /* TIE=0,RIE=0,TE=1,RE=1,REIE=1 */
+ #elif defined(CONFIG_R8A7790) || defined(CONFIG_R8A7791) || \
+ defined(CONFIG_R8A7793) || defined(CONFIG_R8A7794) || \
+- defined(CONFIG_R8A7795) || defined(CONFIG_R8A7796X)
++ defined(CONFIG_R8A7795) || defined(CONFIG_R8A7796X) || \
++ defined(CONFIG_R8A7797)
+ # define SCIF_ORER 0x0001
+ # define SCSCR_INIT(port) (port->clk_mode == EXT_CLK ? 0x32 : 0x30)
+ /* TIE=0,RIE=0,TE=1,RE=1,REIE=0, */
+diff --git a/include/configs/rcar-gen3-common.h b/include/configs/rcar-gen3-common.h
+index 0a959f7..ec20aba 100644
+--- a/include/configs/rcar-gen3-common.h
++++ b/include/configs/rcar-gen3-common.h
+@@ -93,7 +93,11 @@
+ #define CONFIG_SYS_BAUDRATE_TABLE { 115200, 38400 }
+
+ /* MEMORY */
++#if defined(CONFIG_R8A7797)
++#define CONFIG_SYS_TEXT_BASE 0x58280000
++#else
+ #define CONFIG_SYS_TEXT_BASE 0x50000000
++#endif
+ #define CONFIG_SYS_INIT_SP_ADDR (CONFIG_SYS_TEXT_BASE + 0x7fff0)
+
+
+@@ -124,6 +128,14 @@
+ #define PHYS_SDRAM_1_SIZE ((unsigned long)(0x80000000 - DRAM_RSV_SIZE))
+ #define CONFIG_SYS_SDRAM_BASE PHYS_SDRAM_1
+ #define CONFIG_SYS_SDRAM_SIZE PHYS_SDRAM_1_SIZE
++#elif defined(CONFIG_R8A7797)
++#define CONFIG_NR_DRAM_BANKS 1
++#define PHYS_SDRAM_1 (0x40000000 + DRAM_RSV_SIZE) /* legacy */
++#define PHYS_SDRAM_1_SIZE ((unsigned long)(0x40000000 - DRAM_RSV_SIZE))
++#define PHYS_SDRAM_2 0x0600000000 /* ext */
++#define PHYS_SDRAM_2_SIZE ((unsigned long)0x80000000)
++#define CONFIG_SYS_SDRAM_BASE PHYS_SDRAM_1
++#define CONFIG_SYS_SDRAM_SIZE PHYS_SDRAM_1_SIZE
+ #else
+ #define CONFIG_NR_DRAM_BANKS 1
+ #define CONFIG_SYS_SDRAM_BASE 0x40000000
+--
+1.9.1
+
diff --git a/meta-rcar-gen3-adas/recipes-bsp/u-boot/u-boot/0015-board-renesas-Add-V3M-Eagle-board.patch b/meta-rcar-gen3-adas/recipes-bsp/u-boot/u-boot/0015-board-renesas-Add-V3M-Eagle-board.patch
new file mode 100644
index 0000000..5b300eb
--- /dev/null
+++ b/meta-rcar-gen3-adas/recipes-bsp/u-boot/u-boot/0015-board-renesas-Add-V3M-Eagle-board.patch
@@ -0,0 +1,499 @@
+From 423d01a1b367d82a3855972483530968309cbbd4 Mon Sep 17 00:00:00 2001
+From: Daisuke Matsushita <daisuke.matsushita.ns@hitachi.com>
+Date: Tue, 21 Mar 2017 15:05:15 +0900
+Subject: [PATCH] board: renesas: Add V3M Eagle board
+
+V3M Eagle is a board based on R-Car V3M SoC (R8A7797)
+
+Signed-off-by: Vladimir Barinov <vladimir.barinov@cogentembedded.com>
+---
+ arch/arm/cpu/armv8/Kconfig | 4 +
+ board/renesas/eagle/Kconfig | 15 +++
+ board/renesas/eagle/MAINTAINERS | 6 ++
+ board/renesas/eagle/Makefile | 9 ++
+ board/renesas/eagle/eagle.c | 224 ++++++++++++++++++++++++++++++++++++++++
+ configs/r8a7797_eagle_defconfig | 9 ++
+ include/configs/r8a7797_eagle.h | 152 +++++++++++++++++++++++++++
+ 7 files changed, 419 insertions(+)
+ create mode 100644 board/renesas/eagle/Kconfig
+ create mode 100644 board/renesas/eagle/MAINTAINERS
+ create mode 100644 board/renesas/eagle/Makefile
+ create mode 100644 board/renesas/eagle/eagle.c
+ create mode 100644 configs/r8a7797_eagle_defconfig
+ create mode 100644 include/configs/r8a7797_eagle.h
+
+diff --git a/arch/arm/cpu/armv8/Kconfig b/arch/arm/cpu/armv8/Kconfig
+index dfd9bab..c857214 100644
+--- a/arch/arm/cpu/armv8/Kconfig
++++ b/arch/arm/cpu/armv8/Kconfig
+@@ -16,6 +16,9 @@ config TARGET_SALVATOR_X
+ config TARGET_ULCB
+ bool "ULCB board"
+
++config TARGET_EAGLE
++ bool "EAGLE board"
++
+ endchoice
+
+ config R8A7796X
+@@ -45,5 +48,6 @@ config SYS_SOC
+
+ source "board/renesas/salvator-x/Kconfig"
+ source "board/renesas/ulcb/Kconfig"
++source "board/renesas/eagle/Kconfig"
+
+ endif
+diff --git a/board/renesas/eagle/Kconfig b/board/renesas/eagle/Kconfig
+new file mode 100644
+index 0000000..dffbbeb
+--- /dev/null
++++ b/board/renesas/eagle/Kconfig
+@@ -0,0 +1,15 @@
++if TARGET_EAGLE
++
++config SYS_SOC
++ default "rcar_gen3"
++
++config SYS_BOARD
++ default "eagle"
++
++config SYS_VENDOR
++ default "renesas"
++
++config SYS_CONFIG_NAME
++ default "r8a7797_eagle" if R8A7797
++
++endif
+diff --git a/board/renesas/eagle/MAINTAINERS b/board/renesas/eagle/MAINTAINERS
+new file mode 100644
+index 0000000..c411373
+--- /dev/null
++++ b/board/renesas/eagle/MAINTAINERS
+@@ -0,0 +1,6 @@
++EAGLE BOARD
++M: foo <foo@renesas.com>
++S: Maintained
++F: board/renesas/eagle/
++F: include/configs/r8a7797_eagle.h
++F: configs/r8a7797_eagle_defconfig
+diff --git a/board/renesas/eagle/Makefile b/board/renesas/eagle/Makefile
+new file mode 100644
+index 0000000..87d63e1
+--- /dev/null
++++ b/board/renesas/eagle/Makefile
+@@ -0,0 +1,9 @@
++#
++# board/renesas/eagle/Makefile
++#
++# Copyright (C) 2016 Renesas Electronics Corporation
++#
++# SPDX-License-Identifier: GPL-2.0+
++#
++
++obj-y := eagle.o ../rcar-gen3-common/common.o
+diff --git a/board/renesas/eagle/eagle.c b/board/renesas/eagle/eagle.c
+new file mode 100644
+index 0000000..4eda15c
+--- /dev/null
++++ b/board/renesas/eagle/eagle.c
+@@ -0,0 +1,224 @@
++/*
++ * board/renesas/eagle/eagle.c
++ * This file is Eagle board support.
++ *
++ * Copyright (C) 2016 Renesas Electronics Corporation
++ *
++ * SPDX-License-Identifier: GPL-2.0+
++ */
++
++#include <common.h>
++#include <malloc.h>
++#include <netdev.h>
++#include <dm.h>
++#include <dm/platform_data/serial_sh.h>
++#include <asm/processor.h>
++#include <asm/mach-types.h>
++#include <asm/io.h>
++#include <asm/errno.h>
++#include <asm/arch/sys_proto.h>
++#include <asm/gpio.h>
++#include <asm/arch/prr_depend.h>
++#include <asm/arch/gpio.h>
++#include <asm/arch/rcar_gen3.h>
++#include <asm/arch/rcar-mstp.h>
++#include <asm/arch/sh_sdhi.h>
++#include <i2c.h>
++#include <mmc.h>
++
++DECLARE_GLOBAL_DATA_PTR;
++
++#define SCIF0_MSTP207 (1 << 7)
++#define ETHERAVB_MSTP812 (1 << 12)
++#define RPC_MSTP917 (1 << 17)
++
++#define CLK2MHZ(clk) (clk / 1000 / 1000)
++void s_init(void)
++{
++ struct rcar_rwdt *rwdt = (struct rcar_rwdt *)RWDT_BASE;
++ struct rcar_swdt *swdt = (struct rcar_swdt *)SWDT_BASE;
++ u32 stc;
++
++ /* Watchdog init */
++ writel(0xA5A5A500, &rwdt->rwtcsra);
++ writel(0xA5A5A500, &swdt->swtcsra);
++
++ /* CPU frequency setting. Set to 0.8GHz */
++ stc = ((800 / CLK2MHZ(CONFIG_SYS_CLK_FREQ)) - 1) << PLL0_STC_BIT;
++ clrsetbits_le32(PLL0CR, PLL0_STC_MASK, stc);
++}
++
++int board_early_init_f(void)
++{
++ rcar_prr_init();
++
++ writel(0xa5a5ffff, 0xe6150900);
++ writel(0x5a5a0000, 0xe6150904);
++ mstp_clrbits_le32(MSTPSR1, SMSTPCR1, 0x02000000);
++ /* SCIF0 */
++ mstp_clrbits_le32(MSTPSR2, SMSTPCR2, SCIF0_MSTP207);
++ /* EHTERAVB */
++ mstp_clrbits_le32(MSTPSR8, SMSTPCR8, ETHERAVB_MSTP812);
++ /* QSPI */
++ mstp_clrbits_le32(MSTPSR9, SMSTPCR9, RPC_MSTP917);
++
++ return 0;
++}
++
++int board_init(void)
++{
++ /* adress of boot parameters */
++ gd->bd->bi_boot_params = CONFIG_SYS_TEXT_BASE + 0x50000;
++
++ /* Init PFC controller */
++ pinmux_init();
++
++#ifdef CONFIG_RAVB
++ /* GPSR1 */
++ gpio_request(GPIO_GFN_AVB0_AVTP_CAPTURE, NULL);
++ gpio_request(GPIO_FN_AVB0_AVTP_MATCH, NULL);
++ gpio_request(GPIO_FN_AVB0_LINK, NULL);
++ gpio_request(GPIO_FN_AVB0_PHY_INT, NULL);
++ gpio_request(GPIO_FN_AVB0_MAGIC, NULL);
++ gpio_request(GPIO_FN_AVB0_MDC, NULL);
++ gpio_request(GPIO_FN_AVB0_MDIO, NULL);
++ gpio_request(GPIO_FN_AVB0_TXCREFCLK, NULL);
++ gpio_request(GPIO_FN_AVB0_TD3, NULL);
++ gpio_request(GPIO_FN_AVB0_TD2, NULL);
++ gpio_request(GPIO_FN_AVB0_TD1, NULL);
++ gpio_request(GPIO_FN_AVB0_TD0, NULL);
++ gpio_request(GPIO_FN_AVB0_TXC, NULL);
++ gpio_request(GPIO_FN_AVB0_TX_CTL, NULL);
++ gpio_request(GPIO_FN_AVB0_RD3, NULL);
++ gpio_request(GPIO_FN_AVB0_RD2, NULL);
++ gpio_request(GPIO_FN_AVB0_RD1, NULL);
++ gpio_request(GPIO_FN_AVB0_RD0, NULL);
++ gpio_request(GPIO_FN_AVB0_RXC, NULL);
++ gpio_request(GPIO_FN_AVB0_RX_CTL, NULL);
++
++ /* IPSR7 */
++ gpio_request(GPIO_IFN_AVB0_AVTP_CAPTURE, NULL);
++ /* IPSR3 */
++ gpio_request(GPIO_FN_AVB0_AVTP_PPS, NULL);
++
++ /* AVB_PHY_RST */
++ gpio_request(GPIO_GP_1_16, NULL);
++ gpio_direction_output(GPIO_GP_1_16, 0);
++ mdelay(20);
++ gpio_set_value(GPIO_GP_1_16, 1);
++ udelay(1);
++#endif
++
++ /* QSPI */
++#if !defined(CONFIG_SYS_NO_FLASH)
++ gpio_request(GPIO_FN_QSPI0_SPCLK, NULL);
++ gpio_request(GPIO_FN_QSPI0_MOSI_IO0, NULL);
++ gpio_request(GPIO_FN_QSPI0_MISO_IO1, NULL);
++ gpio_request(GPIO_FN_QSPI0_IO2, NULL);
++ gpio_request(GPIO_FN_QSPI0_IO3, NULL);
++ gpio_request(GPIO_FN_QSPI0_SSL, NULL);
++ gpio_request(GPIO_FN_QSPI1_SPCLK, NULL);
++ gpio_request(GPIO_FN_QSPI1_MOSI_IO0, NULL);
++ gpio_request(GPIO_FN_QSPI1_MISO_IO1, NULL);
++ gpio_request(GPIO_FN_QSPI1_IO2, NULL);
++ gpio_request(GPIO_FN_QSPI1_IO3, NULL);
++ gpio_request(GPIO_FN_QSPI1_SSL, NULL);
++ gpio_request(GPIO_FN_RPC_RESET_N, NULL);
++ gpio_request(GPIO_FN_RPC_WP_N, NULL);
++ gpio_request(GPIO_FN_RPC_INT_N, NULL);
++#endif
++ return 0;
++}
++
++#define MAHR 0xE68005C0
++#define MALR 0xE68005C8
++int board_eth_init(bd_t *bis)
++{
++ int ret = -ENODEV;
++ u32 val;
++ unsigned char enetaddr[6];
++
++ if (!eth_getenv_enetaddr("ethaddr", enetaddr))
++ return ret;
++
++ /* Set Mac address */
++ val = enetaddr[0] << 24 | enetaddr[1] << 16 |
++ enetaddr[2] << 8 | enetaddr[3];
++ writel(val, MAHR);
++
++ val = enetaddr[4] << 8 | enetaddr[5];
++ writel(val, MALR);
++
++#ifdef CONFIG_RAVB
++ ret = ravb_initialize(bis);
++#endif
++ return ret;
++}
++
++/* Salvator-X has KSZ9031RNX */
++/* Tri-color dual-LED mode(Pin 41 pull-down) */
++int board_phy_config(struct phy_device *phydev)
++{
++ /* hardware use default(Tri-color:0) setting. */
++
++ return 0;
++}
++
++int board_mmc_init(bd_t *bis)
++{
++ return -ENODEV;
++}
++
++
++int dram_init(void)
++{
++ gd->ram_size = PHYS_SDRAM_1_SIZE;
++#if (CONFIG_NR_DRAM_BANKS >= 2)
++ gd->ram_size += PHYS_SDRAM_2_SIZE;
++#endif
++#if (CONFIG_NR_DRAM_BANKS >= 3)
++ gd->ram_size += PHYS_SDRAM_3_SIZE;
++#endif
++#if (CONFIG_NR_DRAM_BANKS >= 4)
++ gd->ram_size += PHYS_SDRAM_4_SIZE;
++#endif
++
++ return 0;
++}
++
++void dram_init_banksize(void)
++{
++ gd->bd->bi_dram[0].start = PHYS_SDRAM_1;
++ gd->bd->bi_dram[0].size = PHYS_SDRAM_1_SIZE;
++#if (CONFIG_NR_DRAM_BANKS >= 2)
++ gd->bd->bi_dram[1].start = PHYS_SDRAM_2;
++ gd->bd->bi_dram[1].size = PHYS_SDRAM_2_SIZE;
++#endif
++#if (CONFIG_NR_DRAM_BANKS >= 3)
++ gd->bd->bi_dram[2].start = PHYS_SDRAM_3;
++ gd->bd->bi_dram[2].size = PHYS_SDRAM_3_SIZE;
++#endif
++#if (CONFIG_NR_DRAM_BANKS >= 4)
++ gd->bd->bi_dram[3].start = PHYS_SDRAM_4;
++ gd->bd->bi_dram[3].size = PHYS_SDRAM_4_SIZE;
++#endif
++}
++
++const struct rcar_sysinfo sysinfo = {
++ CONFIG_RCAR_BOARD_STRING
++};
++
++void reset_cpu(ulong addr)
++{
++#if defined(CONFIG_SYS_I2C) && defined(CONFIG_SYS_I2C_SH)
++ i2c_reg_write(CONFIG_SYS_I2C_POWERIC_ADDR, 0x20, 0x80);
++#endif
++}
++
++#if defined(CONFIG_DISPLAY_BOARDINFO)
++int checkboard(void)
++{
++ printf("Board: %s\n", sysinfo.board_string);
++ return 0;
++}
++#endif
+diff --git a/configs/r8a7797_eagle_defconfig b/configs/r8a7797_eagle_defconfig
+new file mode 100644
+index 0000000..d68e28f
+--- /dev/null
++++ b/configs/r8a7797_eagle_defconfig
+@@ -0,0 +1,9 @@
++CONFIG_ARM=y
++CONFIG_RCAR_GEN3=y
++CONFIG_DM_SERIAL=y
++CONFIG_TARGET_EAGLE=y
++CONFIG_R8A7797=y
++CONFIG_SPL=y
++CONFIG_SH_SDHI=y
++CONFIG_SPI_FLASH=y
++CONFIG_SPI_FLASH_SPANSION=y
+diff --git a/include/configs/r8a7797_eagle.h b/include/configs/r8a7797_eagle.h
+new file mode 100644
+index 0000000..a4ae6bf
+--- /dev/null
++++ b/include/configs/r8a7797_eagle.h
+@@ -0,0 +1,152 @@
++/*
++ * include/configs/eagle.h
++ * This file is eagle board configuration.
++ * CPU r8a7797.
++ *
++ * Copyright (C) 2016 Renesas Electronics Corporation
++ *
++ * SPDX-License-Identifier: GPL-2.0+
++ */
++
++#ifndef __EAGLE_H
++#define __EAGLE_H
++
++#undef DEBUG
++#define CONFIG_RCAR_BOARD_STRING "R-Car EAGLE"
++#define CONFIG_RCAR_TARGET_STRING "r8a7797"
++
++#include "rcar-gen3-common.h"
++
++/* Cache Definitions */
++#define CONFIG_SYS_DCACHE_OFF
++#define CONFIG_SYS_ICACHE_OFF
++
++/* SCIF */
++#define CONFIG_SCIF_CONSOLE
++#define CONFIG_CONS_SCIF0
++#define CONFIG_SH_SCIF_CLK_FREQ CONFIG_S3D4_CLK_FREQ
++
++/* [A] Hyper Flash */
++/* use to RPC(SPI Multi I/O Bus Controller) */
++
++ /* underconstruction */
++
++#define CONFIG_SYS_NO_FLASH
++#if defined(CONFIG_SYS_NO_FLASH)
++#define CONFIG_SPI
++#define CONFIG_RCAR_GEN3_QSPI
++#define CONFIG_SH_QSPI_BASE 0xEE200000
++#define CONFIG_CMD_SF
++#define CONFIG_CMD_SPI
++#define CONFIG_SPI_FLASH
++#define CONFIG_SPI_FLASH_SPANSION
++#else
++#undef CONFIG_CMD_SF
++#undef CONFIG_CMD_SPI
++#undef CONFIG_SPI_FLASH
++#undef CONFIG_SPI_FLASH_SPANSION
++#endif
++
++/* Ethernet RAVB */
++#define CONFIG_RAVB
++#define CONFIG_RAVB_PHY_ADDR 0x0
++#define CONFIG_RAVB_PHY_MODE PHY_INTERFACE_MODE_RGMII_ID
++#define CONFIG_NET_MULTI
++#define CONFIG_PHYLIB
++#define CONFIG_PHY_MICREL
++#define CONFIG_BITBANGMII
++#define CONFIG_BITBANGMII_MULTI
++#define CONFIG_SH_ETHER_BITBANG
++
++/* Board Clock */
++/* XTAL_CLK : 33.33MHz */
++#define RCAR_XTAL_CLK 33333333u
++#define CONFIG_SYS_CLK_FREQ RCAR_XTAL_CLK
++/* ch0to2 CPclk, ch3to11 S3D2_PEREclk, ch12to14 S3D2_RTclk */
++/* CPclk 16.66MHz, S3D2 133.33MHz , S3D4 66.66MHz */
++#define CONFIG_CP_CLK_FREQ (CONFIG_SYS_CLK_FREQ / 2)
++#define CONFIG_PLL1_CLK_FREQ (CONFIG_SYS_CLK_FREQ * 192 / 2)
++#define CONFIG_S3D2_CLK_FREQ (266666666u/2)
++#define CONFIG_S3D4_CLK_FREQ (266666666u/4)
++
++/* Generic Timer Definitions (use in assembler source) */
++#define COUNTER_FREQUENCY 0xFE502A /* 16.66MHz from CPclk */
++
++/* Generic Interrupt Controller Definitions */
++#define GICD_BASE (0xF1010000)
++#define GICC_BASE (0xF1020000)
++#define CONFIG_GICV2
++
++/* i2c */
++#define CONFIG_SYS_I2C
++#define CONFIG_SYS_I2C_SH
++#define CONFIG_SYS_I2C_SLAVE 0x60
++#define CONFIG_SYS_I2C_SH_NUM_CONTROLLERS 1
++#define CONFIG_SYS_I2C_SH_SPEED0 400000
++#define CONFIG_SH_I2C_DATA_HIGH 4
++#define CONFIG_SH_I2C_DATA_LOW 5
++#define CONFIG_SH_I2C_CLOCK 10000000
++
++#define CONFIG_SYS_I2C_POWERIC_ADDR 0x30
++
++/* USB */
++#undef CONFIG_CMD_USB
++
++/* Module clock supply/stop status bits */
++/* MFIS */
++#define CONFIG_SMSTP2_ENA 0x00002000
++/* serial(SCIF0) */
++#define CONFIG_SMSTP3_ENA 0x00000400
++/* INTC-AP, INTC-EX */
++#define CONFIG_SMSTP4_ENA 0x00000180
++
++/* SDHI */
++#define CONFIG_MMC
++#define CONFIG_CMD_MMC
++#define CONFIG_GENERIC_MMC
++#define CONFIG_SH_SDHI_FREQ 200000000
++#define CONFIG_SH_SDHI_MMC
++
++#define CONFIG_SH_MMCIF
++#define CONFIG_SH_MMCIF_ADDR 0xee140000
++#define CONFIG_SH_MMCIF_CLK (CONFIG_SH_SDHI_FREQ)
++
++/* Environment */
++#define CONFIG_ENV_IS_IN_SPI_FLASH
++
++#define CONFIG_ENV_OVERWRITE
++#define CONFIG_ENV_SECT_SIZE (256 * 1024)
++#define CONFIG_ENV_SIZE (CONFIG_ENV_SECT_SIZE)
++
++/* Environment in eMMC, at the end of 2nd "boot sector" */
++#if defined(CONFIG_ENV_IS_IN_MMC)
++#define CONFIG_ENV_OFFSET (-CONFIG_ENV_SIZE)
++#define CONFIG_SYS_MMC_ENV_DEV 0
++#define CONFIG_SYS_MMC_ENV_PART 2
++#define CONFIG_GENERIC_MMC
++
++#elif defined(CONFIG_ENV_IS_IN_SPI_FLASH)
++/* Environment in QSPI */
++#define CONFIG_ENV_ADDR 0x700000
++#define CONFIG_ENV_OFFSET (CONFIG_ENV_ADDR)
++
++#else
++/* Unused Environment */
++#define CONFIG_ENV_IS_NOWHERE
++#endif
++
++#define CONFIG_EXTRA_ENV_SETTINGS \
++ "fdt_high=0xffffffffffffffff\0" \
++ "initrd_high=0xffffffffffffffff\0" \
++ "ethact=ravb\0"
++
++#define CONFIG_BOOTARGS \
++ "root=/dev/nfs rw " \
++ "nfsroot=192.168.0.1:/export/rfs ip=192.168.0.20"
++
++#define CONFIG_BOOTCOMMAND \
++ "tftp 0x48080000 Image; " \
++ "tftp 0x48000000 Image-r8a7797-eagle.dtb; " \
++ "booti 0x48080000 - 0x48000000"
++
++#endif /* __EAGLE_H */
+--
+1.9.1
+
diff --git a/meta-rcar-gen3-adas/recipes-bsp/u-boot/u-boot/0017-board-renesas-Add-V3MSK-board.patch b/meta-rcar-gen3-adas/recipes-bsp/u-boot/u-boot/0017-board-renesas-Add-V3MSK-board.patch
new file mode 100644
index 0000000..773ca26
--- /dev/null
+++ b/meta-rcar-gen3-adas/recipes-bsp/u-boot/u-boot/0017-board-renesas-Add-V3MSK-board.patch
@@ -0,0 +1,813 @@
+From 2e9bb759bda6ce52a446c2b7f7d79d51140c4316 Mon Sep 17 00:00:00 2001
+From: Vladimir Barinov <vladimir.barinov@cogentembedded.com>
+Date: Fri, 17 Nov 2017 13:01:38 +0300
+Subject: [PATCH] board: renesas: Add V3M Starter Kit board
+
+V3M Starter Kit is a board based on R-Car V3M SoC (R8A7797)
+
+Signed-off-by: Vladimir Barinov <vladimir.barinov@cogentembedded.com>
+---
+ arch/arm/cpu/armv8/Kconfig | 4 +
+ board/renesas/v3msk/Kconfig | 15 +++
+ board/renesas/v3msk/MAINTAINERS | 6 ++
+ board/renesas/v3msk/Makefile | 9 ++
+ board/renesas/v3msk/cpld.c | 164 +++++++++++++++++++++++++++++++
+ board/renesas/v3msk/mdio_bb.h | 156 ++++++++++++++++++++++++++++++
+ board/renesas/v3msk/v3msk.c | 209 ++++++++++++++++++++++++++++++++++++++++
+ configs/v3msk_defconfig | 9 ++
+ include/configs/v3msk.h | 145 ++++++++++++++++++++++++++++
+ 9 files changed, 717 insertions(+)
+ create mode 100644 board/renesas/v3msk/Kconfig
+ create mode 100644 board/renesas/v3msk/MAINTAINERS
+ create mode 100644 board/renesas/v3msk/Makefile
+ create mode 100644 board/renesas/v3msk/cpld.c
+ create mode 100644 board/renesas/v3msk/mdio_bb.h
+ create mode 100644 board/renesas/v3msk/v3msk.c
+ create mode 100644 configs/v3msk_defconfig
+ create mode 100644 include/configs/v3msk.h
+
+diff --git a/arch/arm/cpu/armv8/Kconfig b/arch/arm/cpu/armv8/Kconfig
+index c857214..343b121 100644
+--- a/arch/arm/cpu/armv8/Kconfig
++++ b/arch/arm/cpu/armv8/Kconfig
+@@ -19,6 +19,9 @@ config TARGET_ULCB
+ config TARGET_EAGLE
+ bool "EAGLE board"
+
++config TARGET_V3MSK
++ bool "V3MSK board"
++
+ endchoice
+
+ config R8A7796X
+@@ -49,5 +52,6 @@ config SYS_SOC
+ source "board/renesas/salvator-x/Kconfig"
+ source "board/renesas/ulcb/Kconfig"
+ source "board/renesas/eagle/Kconfig"
++source "board/renesas/v3msk/Kconfig"
+
+ endif
+diff --git a/board/renesas/v3msk/Kconfig b/board/renesas/v3msk/Kconfig
+new file mode 100644
+index 0000000..dafbaef
+--- /dev/null
++++ b/board/renesas/v3msk/Kconfig
+@@ -0,0 +1,15 @@
++if TARGET_V3MSK
++
++config SYS_SOC
++ default "rcar_gen3"
++
++config SYS_BOARD
++ default "v3msk"
++
++config SYS_VENDOR
++ default "renesas"
++
++config SYS_CONFIG_NAME
++ default "v3msk" if R8A7797
++
++endif
+diff --git a/board/renesas/v3msk/MAINTAINERS b/board/renesas/v3msk/MAINTAINERS
+new file mode 100644
+index 0000000..c39eb76
+--- /dev/null
++++ b/board/renesas/v3msk/MAINTAINERS
+@@ -0,0 +1,6 @@
++V3MSK BOARD
++M: Cogent Embedded, Inc. <source@cogentembedded.com>
++S: Maintained
++F: board/renesas/v3msk/
++F: include/configs/r8a7797_v3msk.h
++F: configs/r8a7797_v3msk_defconfig
+diff --git a/board/renesas/v3msk/Makefile b/board/renesas/v3msk/Makefile
+new file mode 100644
+index 0000000..1f2ea42
+--- /dev/null
++++ b/board/renesas/v3msk/Makefile
+@@ -0,0 +1,9 @@
++#
++# board/renesas/v3msk/Makefile
++#
++# Copyright (C) 2017 Cogent Embedded, Inc.
++#
++# SPDX-License-Identifier: GPL-2.0+
++#
++
++obj-y := v3msk.o ../rcar-gen3-common/common.o cpld.o
+diff --git a/board/renesas/v3msk/cpld.c b/board/renesas/v3msk/cpld.c
+new file mode 100644
+index 0000000..ffb0637
+--- /dev/null
++++ b/board/renesas/v3msk/cpld.c
+@@ -0,0 +1,164 @@
++/*
++ * V3MSK board CPLD access support
++ *
++ * Copyright (C) 2017 Renesas Electronics Corporation
++ * Copyright (C) 2017 Cogent Embedded, Inc.
++ *
++ * SPDX-License-Identifier: GPL-2.0+
++ */
++
++#include <common.h>
++#include <asm/arch/prr_depend.h>
++#include <asm/arch/rcar-mstp.h>
++#include <asm/io.h>
++#include <asm/gpio.h>
++
++#define ENABLEZ GPIO_GP_1_19
++#define MDC GPIO_GP_1_21
++#define MOSI GPIO_GP_1_22
++#define MISO GPIO_GP_1_23
++
++#define ADDR_PRODUCT_L 0x000 /* R */
++#define ADDR_PRODUCT_H 0x001 /* R */
++#define ADDR_CPLD_VERSION_D 0x002 /* R */
++#define ADDR_CPLD_VERSION_Y 0x003 /* R */
++#define ADDR_MODE_SET_L 0x004 /* R/W */
++#define ADDR_MODE_SET_H 0x005 /* R/W */
++#define ADDR_MODE_APPLIED_L 0x006 /* R */
++#define ADDR_MODE_APPLIED_H 0x007 /* R */
++#define ADDR_DIPSW 0x008 /* R */
++#define ADDR_RESET 0x00A /* R/W */
++#define ADDR_POWER_CFG 0x00B /* R/W */
++#define ADDR_PERI_CFG1 0x00C /* R/W */
++#define ADDR_PERI_CFG2 0x00D /* R/W */
++#define ADDR_LEDS 0x00E /* R/W */
++#define ADDR_PCB_VERSION 0x300 /* R */
++#define ADDR_SOC_VERSION 0x301 /* R */
++#define ADDR_PCB_SN_L 0x302 /* R */
++#define ADDR_PCB_SN_H 0x303 /* R */
++
++/* LSI pin pull-up control */
++#define PFC_PUEN2 0xe6060408
++#define PUEN_CANFD1_TX (1 << 29)
++
++#define MDIO_DELAY 10 /* microseconds */
++
++#define mdio_bb_active_mdio() gpio_direction_output(MOSI, 0)
++#define mdio_bb_tristate_mdio() gpio_direction_input(MOSI)
++#define mdio_bb_set_mdio(val) gpio_set_value(MOSI, val)
++#define mdio_bb_get_mdio() gpio_get_value(MISO)
++#define mdio_bb_set_mdc(val) gpio_set_value(MDC, val)
++
++#include "mdio_bb.h"
++
++static int cpld_initialized;
++
++static u16 cpld_read(u16 addr)
++{
++ /* random flash reads require 2 reads: first read is unreliable */
++ if (addr >= ADDR_PCB_VERSION)
++ mdio_bb_read(addr >> 5, addr & 0x1f);
++
++ return mdio_bb_read(addr >> 5, addr & 0x1f);
++}
++
++static void cpld_write(u16 addr, u16 data)
++{
++ mdio_bb_write(addr >> 5, addr & 0x1f, data);
++}
++
++static void cpld_init(void)
++{
++ if (cpld_initialized)
++ return;
++
++ cpld_initialized = 1;
++#if 0
++ /* PULL-UP on MISO line (should be pulled up after POR on V3M) */
++ writel(readl(PFC_PUEN2) | PUEN_CANFD1_TX, PFC_PUEN2);
++#endif
++ gpio_request(MDC, NULL);
++ gpio_request(ENABLEZ, NULL);
++ gpio_request(MOSI, NULL);
++ gpio_request(MISO, NULL);
++
++ gpio_direction_output(MDC, 0);
++ gpio_direction_output(ENABLEZ, 0);
++ gpio_direction_output(MOSI, 0);
++ gpio_direction_input(MISO);
++
++ /* V3MSK Videobox Mini board has CANFD PHY connected
++ * we must shutdown this chip to use bb pins
++ */
++ gpio_request(GPIO_GP_0_12, NULL);
++ gpio_direction_output(GPIO_GP_0_12, 1);
++}
++
++static int do_cpld(cmd_tbl_t *cmdtp, int flag, int argc, char * const argv[])
++{
++ u16 addr, val;
++
++ cpld_init();
++
++ if (argc == 2 && strcmp(argv[1], "info") == 0) {
++ printf("Product: 0x%08x\n",
++ (cpld_read(ADDR_PRODUCT_H) << 16) |
++ cpld_read(ADDR_PRODUCT_L));
++ printf("CPLD version: 0x%08x\n",
++ (cpld_read(ADDR_CPLD_VERSION_Y) << 16) |
++ cpld_read(ADDR_CPLD_VERSION_D));
++ printf("Mode setting (MD0..26): 0x%08x\n",
++ (cpld_read(ADDR_MODE_APPLIED_H) << 16) |
++ cpld_read(ADDR_MODE_APPLIED_L));
++ printf("DIPSW (SW4, SW5): 0x%02x, 0x%x\n",
++ (cpld_read(ADDR_DIPSW) & 0xff) ^ 0xff,
++ (cpld_read(ADDR_DIPSW) >> 8) ^ 0xf);
++ printf("Power config: 0x%08x\n",
++ cpld_read(ADDR_POWER_CFG));
++ printf("Periferals config: 0x%08x\n",
++ (cpld_read(ADDR_PERI_CFG2) << 16) |
++ cpld_read(ADDR_PERI_CFG1));
++ printf("PCB version: %d.%d\n",
++ cpld_read(ADDR_PCB_VERSION) >> 8,
++ cpld_read(ADDR_PCB_VERSION) & 0xff);
++ printf("SOC version: %d.%d\n",
++ cpld_read(ADDR_SOC_VERSION) >> 8,
++ cpld_read(ADDR_SOC_VERSION) & 0xff);
++ printf("PCB S/N: %d\n",
++ (cpld_read(ADDR_PCB_SN_H) << 16 ) |
++ cpld_read(ADDR_PCB_SN_L));
++ return 0;
++ }
++
++ if (argc < 3)
++ return CMD_RET_USAGE;
++
++ addr = simple_strtoul(argv[2], NULL, 16);
++ if (!(addr >= ADDR_PRODUCT_L && addr <= ADDR_LEDS)) {
++ printf("cpld invalid addr\n");
++ return CMD_RET_USAGE;
++ }
++
++ if (argc == 3 && strcmp(argv[1], "read") == 0) {
++ printf("0x%x\n", cpld_read(addr));
++ } else if (argc == 4 && strcmp(argv[1], "write") == 0) {
++ val = simple_strtoul(argv[3], NULL, 16);
++ cpld_write(addr, val);
++ }
++
++ return 0;
++}
++
++U_BOOT_CMD(
++ cpld, 4, 1, do_cpld,
++ "CPLD access",
++ "info\n"
++ "cpld read addr\n"
++ "cpld write addr val\n"
++);
++
++void reset_cpu(ulong addr)
++{
++ cpld_init();
++ cpld_write(ADDR_RESET, 1);
++}
+diff --git a/board/renesas/v3msk/mdio_bb.h b/board/renesas/v3msk/mdio_bb.h
+new file mode 100644
+index 0000000..0311006
+--- /dev/null
++++ b/board/renesas/v3msk/mdio_bb.h
+@@ -0,0 +1,156 @@
++/*
++ * Bit-banged MDIO interface
++ *
++ * Copyright (C) 2017 Cogent Embedded, Inc.
++ * based on drivers/net/phy/miiphybb.c
++ *
++ * SPDX-License-Identifier: GPL-2.0+
++ */
++
++
++static void mdio_bb_delay(void)
++{
++ udelay(MDIO_DELAY);
++}
++
++/* Send the preamble, address, and register (common to read and write) */
++static void mdio_bb_pre(u8 op, u8 addr, u8 reg)
++{
++ int i;
++
++ /* 32-bit preamble */
++ mdio_bb_active_mdio();
++ mdio_bb_set_mdio(1);
++ for (i = 0; i < 32; i++) {
++ mdio_bb_set_mdc(0);
++ mdio_bb_delay();
++ mdio_bb_set_mdc(1);
++ mdio_bb_delay();
++ }
++ /* send the ST (2-bits of '01') */
++ mdio_bb_set_mdio(0);
++ mdio_bb_set_mdc(0);
++ mdio_bb_delay();
++ mdio_bb_set_mdc(1);
++ mdio_bb_delay();
++ mdio_bb_set_mdio(1);
++ mdio_bb_set_mdc(0);
++ mdio_bb_delay();
++ mdio_bb_set_mdc(1);
++ mdio_bb_delay();
++ /* send the OP (2-bits of Opcode: '10'-read, '01'-write) */
++ mdio_bb_set_mdio(op >> 1);
++ mdio_bb_set_mdc(0);
++ mdio_bb_delay();
++ mdio_bb_set_mdc(1);
++ mdio_bb_delay();
++ mdio_bb_set_mdio(op & 1);
++ mdio_bb_set_mdc(0);
++ mdio_bb_delay();
++ mdio_bb_set_mdc(1);
++ mdio_bb_delay();
++ /* send the PA5 (5-bits of PHY address) */
++ for (i = 0; i < 5; i++) {
++ mdio_bb_set_mdio(addr & 0x10); /* MSB first */
++ mdio_bb_set_mdc(0);
++ mdio_bb_delay();
++ mdio_bb_set_mdc(1);
++ mdio_bb_delay();
++ addr <<= 1;
++ }
++ /* send the RA5 (5-bits of register address) */
++ for (i = 0; i < 5; i++) {
++ mdio_bb_set_mdio(reg & 0x10); /* MSB first */
++ mdio_bb_set_mdc(0);
++ mdio_bb_delay();
++ mdio_bb_set_mdc(1);
++ mdio_bb_delay();
++ reg <<= 1;
++ }
++}
++
++static int mdio_bb_read(u8 addr, u8 reg)
++{
++ int i;
++ u16 data = 0;
++
++ mdio_bb_pre(2, addr, reg);
++ /* tri-state MDIO */
++ mdio_bb_tristate_mdio();
++ /* read TA (2-bits of turn-around, last bit must be '0') */
++ mdio_bb_set_mdc(0);
++ mdio_bb_delay();
++ mdio_bb_set_mdc(1);
++ mdio_bb_delay();
++ mdio_bb_set_mdc(0);
++ mdio_bb_delay();
++ mdio_bb_set_mdc(1);
++ mdio_bb_delay();
++ /* check the turnaround bit: the PHY should drive line to zero */
++ if (mdio_bb_get_mdio() != 0) {
++ printf ("PHY didn't drive TA low\n");
++ for (i = 0; i < 32; i++) {
++ mdio_bb_set_mdc(0);
++ mdio_bb_delay();
++ mdio_bb_set_mdc(1);
++ mdio_bb_delay();
++ }
++ /* There is no PHY, set value to 0xFFFF */
++ return 0xFFFF;
++ }
++ mdio_bb_set_mdc(0);
++ mdio_bb_delay();
++ /* read 16-bits of data */
++ for (i = 0; i < 16; i++) {
++ mdio_bb_set_mdc(1);
++ mdio_bb_delay();
++ data <<= 1;
++ data |= mdio_bb_get_mdio();
++ mdio_bb_set_mdc(0);
++ mdio_bb_delay();
++ }
++
++ mdio_bb_set_mdc(1);
++ mdio_bb_delay();
++ mdio_bb_set_mdc(0);
++ mdio_bb_delay();
++ mdio_bb_set_mdc(1);
++ mdio_bb_delay();
++#ifdef DEBUG
++ printf("cpld_read(0x%x) @ 0x%x = 0x%04x\n", reg, addr, data);
++#endif
++ return data;
++}
++
++static void mdio_bb_write(u8 addr, u8 reg, u16 val)
++{
++ int i;
++
++ mdio_bb_pre(1, addr, reg);
++ /* send the TA (2-bits of turn-around '10') */
++ mdio_bb_set_mdio(1);
++ mdio_bb_set_mdc(0);
++ mdio_bb_delay();
++ mdio_bb_set_mdc(1);
++ mdio_bb_delay();
++ mdio_bb_set_mdio(0);
++ mdio_bb_set_mdc(0);
++ mdio_bb_delay();
++ mdio_bb_set_mdc(1);
++ mdio_bb_delay();
++ /* write 16-bits of data */
++ for (i = 0; i < 16; i++) {
++ mdio_bb_set_mdio(val & 0x8000); /* MSB first */
++ mdio_bb_set_mdc(0);
++ mdio_bb_delay();
++ mdio_bb_set_mdc(1);
++ mdio_bb_delay();
++ val <<= 1;
++ }
++ /* tri-state MDIO */
++ mdio_bb_tristate_mdio();
++ mdio_bb_set_mdc(0);
++ mdio_bb_delay();
++ mdio_bb_set_mdc(1);
++ mdio_bb_delay();
++}
+diff --git a/board/renesas/v3msk/v3msk.c b/board/renesas/v3msk/v3msk.c
+new file mode 100644
+index 0000000..b0de041
+--- /dev/null
++++ b/board/renesas/v3msk/v3msk.c
+@@ -0,0 +1,209 @@
++/*
++ * board/renesas/v3msk/v3msk.c
++ * This is V3MSK board support.
++ *
++ * Copyright (C) 2017 Cogent Embedded, Inc.
++ *
++ * SPDX-License-Identifier: GPL-2.0+
++ */
++
++#include <common.h>
++#include <malloc.h>
++#include <netdev.h>
++#include <dm.h>
++#include <dm/platform_data/serial_sh.h>
++#include <asm/processor.h>
++#include <asm/mach-types.h>
++#include <asm/io.h>
++#include <asm/errno.h>
++#include <asm/arch/sys_proto.h>
++#include <asm/gpio.h>
++#include <asm/arch/prr_depend.h>
++#include <asm/arch/gpio.h>
++#include <asm/arch/rcar_gen3.h>
++#include <asm/arch/rcar-mstp.h>
++#include <asm/arch/sh_sdhi.h>
++#include <i2c.h>
++#include <mmc.h>
++
++DECLARE_GLOBAL_DATA_PTR;
++
++#define SCIF0_MSTP207 (1 << 7)
++#define ETHERAVB_MSTP812 (1 << 12)
++#define RPC_MSTP917 (1 << 17)
++#define SD0_MSTP314 (1 << 14)
++
++#define SD0CKCR 0xE6150074
++
++#define CLK2MHZ(clk) (clk / 1000 / 1000)
++void s_init(void)
++{
++ struct rcar_rwdt *rwdt = (struct rcar_rwdt *)RWDT_BASE;
++ struct rcar_swdt *swdt = (struct rcar_swdt *)SWDT_BASE;
++ u32 stc;
++
++ /* Watchdog init */
++ writel(0xA5A5A500, &rwdt->rwtcsra);
++ writel(0xA5A5A500, &swdt->swtcsra);
++
++ /* CPU frequency setting. Set to 0.8GHz */
++ stc = ((800 / CLK2MHZ(CONFIG_SYS_CLK_FREQ)) - 1) << PLL0_STC_BIT;
++ clrsetbits_le32(PLL0CR, PLL0_STC_MASK, stc);
++}
++
++int board_early_init_f(void)
++{
++ int freq;
++
++ rcar_prr_init();
++
++ writel(0xa5a5ffff, 0xe6150900);
++ writel(0x5a5a0000, 0xe6150904);
++ mstp_clrbits_le32(MSTPSR1, SMSTPCR1, 0x02000000);
++ /* SCIF0 */
++ mstp_clrbits_le32(MSTPSR2, SMSTPCR2, SCIF0_MSTP207);
++ /* SDHI0/MMC */
++ mstp_clrbits_le32(MSTPSR3, SMSTPCR3, SD0_MSTP314);
++ /* EHTERAVB */
++ mstp_clrbits_le32(MSTPSR8, SMSTPCR8, ETHERAVB_MSTP812);
++ /* QSPI/RPC */
++ mstp_clrbits_le32(MSTPSR9, SMSTPCR9, RPC_MSTP917);
++
++ freq = rcar_get_sdhi_config_clk();
++ writel(freq, SD0CKCR);
++
++ return 0;
++}
++
++int board_init(void)
++{
++ /* adress of boot parameters */
++ gd->bd->bi_boot_params = CONFIG_SYS_TEXT_BASE + 0x50000;
++
++ /* Init PFC controller */
++ pinmux_init();
++#ifdef CONFIG_RAVB
++ /* GPSR1 */
++ gpio_request(GPIO_GFN_AVB0_AVTP_CAPTURE, NULL);
++ gpio_request(GPIO_FN_AVB0_AVTP_MATCH, NULL);
++ gpio_request(GPIO_FN_AVB0_LINK, NULL);
++ gpio_request(GPIO_FN_AVB0_PHY_INT, NULL);
++ /* gpio_request(GPIO_FN_AVB0_MAGIC, NULL); */
++ gpio_request(GPIO_FN_AVB0_MDC, NULL);
++ gpio_request(GPIO_FN_AVB0_MDIO, NULL);
++ gpio_request(GPIO_FN_AVB0_TXCREFCLK, NULL);
++ gpio_request(GPIO_FN_AVB0_TD3, NULL);
++ gpio_request(GPIO_FN_AVB0_TD2, NULL);
++ gpio_request(GPIO_FN_AVB0_TD1, NULL);
++ gpio_request(GPIO_FN_AVB0_TD0, NULL);
++ gpio_request(GPIO_FN_AVB0_TXC, NULL);
++ gpio_request(GPIO_FN_AVB0_TX_CTL, NULL);
++ gpio_request(GPIO_FN_AVB0_RD3, NULL);
++ gpio_request(GPIO_FN_AVB0_RD2, NULL);
++ gpio_request(GPIO_FN_AVB0_RD1, NULL);
++ gpio_request(GPIO_FN_AVB0_RD0, NULL);
++ gpio_request(GPIO_FN_AVB0_RXC, NULL);
++ gpio_request(GPIO_FN_AVB0_RX_CTL, NULL);
++ /* IPSR7 */
++ gpio_request(GPIO_IFN_AVB0_AVTP_CAPTURE, NULL);
++ /* IPSR3 */
++ gpio_request(GPIO_FN_AVB0_AVTP_PPS, NULL);
++#endif
++ /* QSPI/RPC */
++ gpio_request(GPIO_FN_QSPI0_SPCLK, NULL);
++ gpio_request(GPIO_FN_QSPI0_MOSI_IO0, NULL);
++ gpio_request(GPIO_FN_QSPI0_MISO_IO1, NULL);
++ gpio_request(GPIO_FN_QSPI0_IO2, NULL);
++ gpio_request(GPIO_FN_QSPI0_IO3, NULL);
++ gpio_request(GPIO_FN_QSPI0_SSL, NULL);
++ gpio_request(GPIO_FN_QSPI1_SPCLK, NULL);
++ gpio_request(GPIO_FN_QSPI1_MOSI_IO0, NULL);
++ gpio_request(GPIO_FN_QSPI1_MISO_IO1, NULL);
++ gpio_request(GPIO_FN_QSPI1_IO2, NULL);
++ gpio_request(GPIO_FN_QSPI1_IO3, NULL);
++ gpio_request(GPIO_FN_QSPI1_SSL, NULL);
++ gpio_request(GPIO_FN_RPC_RESET_N, NULL);
++ gpio_request(GPIO_FN_RPC_WP_N, NULL);
++ gpio_request(GPIO_FN_RPC_INT_N, NULL);
++
++ return 0;
++}
++
++#define MAHR 0xE68005C0
++#define MALR 0xE68005C8
++int board_eth_init(bd_t *bis)
++{
++ int ret = -ENODEV;
++ u32 val;
++ unsigned char enetaddr[6];
++
++ if (!eth_getenv_enetaddr("ethaddr", enetaddr))
++ return ret;
++
++ /* Set Mac address */
++ val = enetaddr[0] << 24 | enetaddr[1] << 16 |
++ enetaddr[2] << 8 | enetaddr[3];
++ writel(val, MAHR);
++
++ val = enetaddr[4] << 8 | enetaddr[5];
++ writel(val, MALR);
++#ifdef CONFIG_RAVB
++ ret = ravb_initialize(bis);
++#endif
++ return ret;
++}
++
++/* V3MSK has KSZ9031RNX */
++int board_phy_config(struct phy_device *phydev)
++{
++ return 0;
++}
++
++int board_mmc_init(bd_t *bis)
++{
++ int ret = -ENODEV;
++#ifdef CONFIG_SH_SDHI
++ /* SDHI2/eMMC */
++ gpio_request(GPIO_FN_MMC_D0, NULL);
++ gpio_request(GPIO_FN_MMC_D1, NULL);
++ gpio_request(GPIO_FN_MMC_D2, NULL);
++ gpio_request(GPIO_FN_MMC_D3, NULL);
++ gpio_request(GPIO_FN_MMC_D4, NULL);
++ gpio_request(GPIO_FN_MMC_D5, NULL);
++ gpio_request(GPIO_FN_MMC_D6, NULL);
++ gpio_request(GPIO_FN_MMC_D7, NULL);
++ gpio_request(GPIO_FN_MMC_CLK, NULL);
++ gpio_request(GPIO_FN_MMC_CMD, NULL);
++ gpio_request(GPIO_FN_MMC_CD, NULL);
++ gpio_request(GPIO_FN_MMC_WP, NULL);
++
++ ret = sh_sdhi_init(CONFIG_SYS_SH_SDHI2_BASE, 0,
++ SH_SDHI_QUIRK_64BIT_BUF);
++#endif
++ return ret;
++}
++
++int dram_init(void)
++{
++ gd->ram_size = PHYS_SDRAM_1_SIZE;
++
++ return 0;
++}
++
++void dram_init_banksize(void)
++{
++ gd->bd->bi_dram[0].start = PHYS_SDRAM_1;
++ gd->bd->bi_dram[0].size = PHYS_SDRAM_1_SIZE;
++}
++
++const struct rcar_sysinfo sysinfo = {
++ CONFIG_RCAR_BOARD_STRING
++};
++
++#if defined(CONFIG_DISPLAY_BOARDINFO)
++int checkboard(void)
++{
++ printf("Board: %s\n", sysinfo.board_string);
++ return 0;
++}
++#endif
+diff --git a/configs/v3msk_defconfig b/configs/v3msk_defconfig
+new file mode 100644
+index 0000000..d32840c
+--- /dev/null
++++ b/configs/v3msk_defconfig
+@@ -0,0 +1,9 @@
++CONFIG_ARM=y
++CONFIG_RCAR_GEN3=y
++CONFIG_DM_SERIAL=y
++CONFIG_TARGET_V3MSK=y
++CONFIG_R8A7797=y
++CONFIG_SPL=y
++CONFIG_SH_SDHI=y
++CONFIG_SPI_FLASH=y
++CONFIG_SPI_FLASH_SPANSION=y
+diff --git a/include/configs/v3msk.h b/include/configs/v3msk.h
+new file mode 100644
+index 0000000..8998da4
+--- /dev/null
++++ b/include/configs/v3msk.h
+@@ -0,0 +1,145 @@
++/*
++ * include/configs/v3msk.h
++ * This file is V3MSK board configuration.
++ * CPU r8a7797.
++ *
++ * Copyright (C) 2017 Cogent Embedded, Inc.
++ *
++ * SPDX-License-Identifier: GPL-2.0+
++ */
++
++#ifndef __V3MSK_H
++#define __V3MSK_H
++
++#undef DEBUG
++#define CONFIG_RCAR_BOARD_STRING "V3MSK"
++#define CONFIG_RCAR_TARGET_STRING "r8a7797"
++
++#include "rcar-gen3-common.h"
++
++/* Cache Definitions */
++//#define CONFIG_SYS_DCACHE_OFF
++//#define CONFIG_SYS_ICACHE_OFF
++
++/* SCIF */
++#define CONFIG_SCIF_CONSOLE
++#define CONFIG_CONS_SCIF0
++#define CONFIG_SH_SCIF_CLK_FREQ CONFIG_S3D4_CLK_FREQ
++
++/* [A] Hyper Flash */
++/* use to RPC(SPI Multi I/O Bus Controller) */
++
++ /* underconstruction */
++
++#define CONFIG_SYS_NO_FLASH
++#if defined(CONFIG_SYS_NO_FLASH)
++#define CONFIG_SPI
++#define CONFIG_RCAR_GEN3_QSPI
++#define CONFIG_SH_QSPI_BASE 0xEE200000
++#define CONFIG_CMD_SF
++#define CONFIG_CMD_SPI
++#define CONFIG_SPI_FLASH
++#define CONFIG_SPI_FLASH_SPANSION
++#else
++#undef CONFIG_CMD_SF
++#undef CONFIG_CMD_SPI
++#undef CONFIG_SPI_FLASH
++#undef CONFIG_SPI_FLASH_SPANSION
++#endif
++
++/* Ethernet RAVB */
++#define CONFIG_RAVB
++#define CONFIG_RAVB_PHY_ADDR 0x0
++#define CONFIG_RAVB_PHY_MODE PHY_INTERFACE_MODE_RGMII_ID
++#define CONFIG_NET_MULTI
++#define CONFIG_PHYLIB
++#define CONFIG_PHY_MICREL
++#define CONFIG_BITBANGMII
++#define CONFIG_BITBANGMII_MULTI
++#define CONFIG_SH_ETHER_BITBANG
++
++/* Board Clock */
++/* XTAL_CLK : 33.33MHz */
++#define RCAR_XTAL_CLK 33333333u
++#define CONFIG_SYS_CLK_FREQ RCAR_XTAL_CLK
++/* ch0to2 CPclk, ch3to11 S3D2_PEREclk, ch12to14 S3D2_RTclk */
++/* CPclk 16.66MHz, S3D2 133.33MHz , S3D4 66.66MHz */
++#define CONFIG_CP_CLK_FREQ (CONFIG_SYS_CLK_FREQ / 2)
++#define CONFIG_PLL1_CLK_FREQ (CONFIG_SYS_CLK_FREQ * 192 / 2)
++#define CONFIG_S3D2_CLK_FREQ (266666666u/2)
++#define CONFIG_S3D4_CLK_FREQ (266666666u/4)
++
++/* Generic Timer Definitions (use in assembler source) */
++#define COUNTER_FREQUENCY 0xFE502A /* 16.66MHz from CPclk */
++
++/* Generic Interrupt Controller Definitions */
++#define GICD_BASE (0xF1010000)
++#define GICC_BASE (0xF1020000)
++#define CONFIG_GICV2
++
++/* i2c */
++#define CONFIG_SYS_I2C
++#define CONFIG_SYS_I2C_SH
++#define CONFIG_SYS_I2C_SLAVE 0x60
++#define CONFIG_SYS_I2C_SH_NUM_CONTROLLERS 1
++#define CONFIG_SYS_I2C_SH_SPEED0 400000
++#define CONFIG_SH_I2C_DATA_HIGH 4
++#define CONFIG_SH_I2C_DATA_LOW 5
++#define CONFIG_SH_I2C_CLOCK 10000000
++
++#define CONFIG_SYS_I2C_POWERIC_ADDR 0x30
++
++/* USB */
++#undef CONFIG_CMD_USB
++
++/* SDHI */
++#define CONFIG_MMC
++#define CONFIG_CMD_MMC
++#define CONFIG_GENERIC_MMC
++#define CONFIG_SH_SDHI_FREQ 200000000
++#define CONFIG_SH_SDHI_MMC
++
++/* ENV setting */
++#define CONFIG_ENV_OVERWRITE
++#define CONFIG_ENV_SECT_SIZE (256 * 1024)
++#define CONFIG_ENV_SIZE (CONFIG_ENV_SECT_SIZE)
++#define CONFIG_ENV_SIZE_REDUND (CONFIG_ENV_SIZE)
++
++#define CONFIG_ENV_IS_IN_MMC
++//#define CONFIG_ENV_IS_IN_SPI_FLASH
++
++#if defined(CONFIG_ENV_IS_IN_MMC)
++/* Environment in eMMC, at the end of 2nd "boot sector" */
++#define CONFIG_ENV_OFFSET (-CONFIG_ENV_SIZE)
++#define CONFIG_SYS_MMC_ENV_DEV 0
++#define CONFIG_SYS_MMC_ENV_PART 2
++#elif defined(CONFIG_ENV_IS_IN_SPI_FLASH)
++/* Environment in QSPI */
++#define CONFIG_ENV_ADDR 0x700000
++#define CONFIG_ENV_OFFSET (CONFIG_ENV_ADDR)
++#else
++#define CONFIG_ENV_IS_NOWHERE
++#endif
++
++/* Module clock supply/stop status bits */
++/* MFIS */
++#define CONFIG_SMSTP2_ENA 0x00002000
++/* serial(SCIF0) */
++#define CONFIG_SMSTP3_ENA 0x00000400
++/* INTC-AP, INTC-EX */
++#define CONFIG_SMSTP4_ENA 0x00000180
++
++#define CONFIG_EXTRA_ENV_SETTINGS \
++ "fdt_high=0xffffffffffffffff\0" \
++ "initrd_high=0xffffffffffffffff\0" \
++ "ethact=ravb\0" \
++ "ethaddr=2E:11:22:33:44:55\0"
++
++#define CONFIG_BOOTARGS \
++ "root=/dev/nfs rw ip=dhcp"
++
++#define CONFIG_BOOTCOMMAND \
++ "bootp 0x48080000 Image; tftp 0x48000000 Image-r8a7797-v3msk.dtb; " \
++ "booti 0x48080000 - 0x48000000"
++
++#endif /* __V3MSK_H */
+--
+1.9.1
+
diff --git a/meta-rcar-gen3-adas/recipes-bsp/u-boot/u-boot/0021-ARM-rcar_gen3-Add-RPC-flash-definitions.patch b/meta-rcar-gen3-adas/recipes-bsp/u-boot/u-boot/0021-ARM-rcar_gen3-Add-RPC-flash-definitions.patch
new file mode 100644
index 0000000..b47c724
--- /dev/null
+++ b/meta-rcar-gen3-adas/recipes-bsp/u-boot/u-boot/0021-ARM-rcar_gen3-Add-RPC-flash-definitions.patch
@@ -0,0 +1,224 @@
+From 2b31e91d7ea86934badebcebb2309b09b79725ca Mon Sep 17 00:00:00 2001
+From: Valentine Barshak <valentine.barshak@cogentembedded.com>
+Date: Mon, 4 Apr 2016 18:39:26 +0300
+Subject: [PATCH] ARM: rcar_gen3: Add RPC flash definitions
+
+This adds common RPC flash definitions to RCAR Gen3 platform.
+
+Signed-off-by: Valentine Barshak <valentine.barshak@cogentembedded.com>
+---
+ arch/arm/include/asm/arch-rcar_gen3/rcar-base.h | 6 +
+ arch/arm/include/asm/arch-rcar_gen3/rpc-flash.h | 184 ++++++++++++++++++++++++
+ 2 files changed, 190 insertions(+)
+ create mode 100644 arch/arm/include/asm/arch-rcar_gen3/rpc-flash.h
+
+diff --git a/arch/arm/include/asm/arch-rcar_gen3/rcar-base.h b/arch/arm/include/asm/arch-rcar_gen3/rcar-base.h
+index 59d34b8..538cdc2 100644
+--- a/arch/arm/include/asm/arch-rcar_gen3/rcar-base.h
++++ b/arch/arm/include/asm/arch-rcar_gen3/rcar-base.h
+@@ -78,6 +78,12 @@
+ /* SH-I2C */
+ #define CONFIG_SYS_I2C_SH_BASE0 0xE60B0000
+
++/* RPC */
++#define CONFIG_SYS_RPC_BASE 0xEE200000
++
++#define CONFIG_SYS_RPC_FLASH_BASE 0x08000000
++#define CONFIG_SYS_RPC_FLASH_SIZE 0x04000000
++
+ /* PFC */
+ #define PFC_PUEN6 0xE6060418
+ #define PUEN_USB1_OVC (1 << 2)
+diff --git a/arch/arm/include/asm/arch-rcar_gen3/rpc-flash.h b/arch/arm/include/asm/arch-rcar_gen3/rpc-flash.h
+new file mode 100644
+index 0000000..403aaee
+--- /dev/null
++++ b/arch/arm/include/asm/arch-rcar_gen3/rpc-flash.h
+@@ -0,0 +1,184 @@
++/*
++ * Copyright (C) 2016 Renesas Electronics Corporation
++ * Copyright (C) 2016 Cogent Embedded, Inc.
++ *
++ * SPDX-License-Identifier: GPL-2.0
++ */
++
++#ifndef __RPC_FLASH_H__
++#define __RPC_FLASH_H__
++
++#include <common.h>
++#include <flash.h>
++#include <asm/io.h>
++#include <asm/arch/rcar_gen3.h>
++
++#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
++
++#ifndef CONFIG_SYS_NO_FLASH
++static inline phys_addr_t rpc_addr(flash_info_t *info, u32 offset)
++{
++ return offset + CONFIG_SYS_RPC_BASE;
++}
++
++static inline u32 rpc_readl(flash_info_t *info, u32 offset)
++{
++ u32 val;
++
++ val = readl(rpc_addr(info, offset));
++ return val;
++}
++
++static inline void rpc_writel(flash_info_t *info, u32 offset, u32 val)
++{
++ writel(val, rpc_addr(info, offset));
++}
++
++static inline void rpc_setl(flash_info_t *info, u32 offset, u32 msk, u32 set)
++{
++ phys_addr_t addr;
++ u32 val;
++
++ addr = rpc_addr(info, offset);
++ val = readl(addr);
++ val &= msk;
++ val |= set;
++ writel(val, addr);
++}
++
++static void rpc_wait_tend(flash_info_t *info)
++{
++ while (!(rpc_readl(info, RPC_CMNSR) & RPC_CMNSR_TEND))
++ barrier();
++}
++#endif /* CONFIG_SYS_NO_FLASH */
++
++#endif /* __RPC_FLASH_H__ */
+--
+1.9.3
+
diff --git a/meta-rcar-gen3-adas/recipes-bsp/u-boot/u-boot/0022-mtd-Add-RPC-HyperFlash-support.patch b/meta-rcar-gen3-adas/recipes-bsp/u-boot/u-boot/0022-mtd-Add-RPC-HyperFlash-support.patch
new file mode 100644
index 0000000..8d34bce
--- /dev/null
+++ b/meta-rcar-gen3-adas/recipes-bsp/u-boot/u-boot/0022-mtd-Add-RPC-HyperFlash-support.patch
@@ -0,0 +1,727 @@
+From 00ea5714ecc7ca61919cb3942d0edf20e8190160 Mon Sep 17 00:00:00 2001
+From: Valentine Barshak <valentine.barshak@cogentembedded.com>
+Date: Mon, 4 Apr 2016 18:40:39 +0300
+Subject: [PATCH] mtd: Add RPC HyperFlash support
+
+This adds RCAR Gen3 RPC HyperFlash driver.
+
+Signed-off-by: Valentine Barshak <valentine.barshak@cogentembedded.com>
+---
+ drivers/mtd/Makefile | 1 +
+ drivers/mtd/rpc_hyperflash.c | 695 +++++++++++++++++++++++++++++++++++++++++++
+ 2 files changed, 696 insertions(+)
+ create mode 100644 drivers/mtd/rpc_hyperflash.c
+
+diff --git a/drivers/mtd/Makefile b/drivers/mtd/Makefile
+index 5467a95..8e794a2 100644
+--- a/drivers/mtd/Makefile
++++ b/drivers/mtd/Makefile
+@@ -18,3 +18,4 @@ obj-$(CONFIG_FTSMC020) += ftsmc020.o
+ obj-$(CONFIG_FLASH_CFI_LEGACY) += jedec_flash.o
+ obj-$(CONFIG_MW_EEPROM) += mw_eeprom.o
+ obj-$(CONFIG_ST_SMI) += st_smi.o
++obj-$(CONFIG_RPC_HYPERFLASH) += rpc_hyperflash.o
+diff --git a/drivers/mtd/rpc_hyperflash.c b/drivers/mtd/rpc_hyperflash.c
+new file mode 100644
+index 0000000..fc67ecd
+--- /dev/null
++++ b/drivers/mtd/rpc_hyperflash.c
+@@ -0,0 +1,695 @@
++/*
++ * Copyright (C) 2016 Renesas Electronics Corporation
++ * Copyright (C) 2016 Cogent Embedded, Inc.
++ *
++ * SPDX-License-Identifier: GPL-2.0
++ */
++
++#include <asm/arch/rpc-flash.h>
++
++#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),
++};
++
++static inline u32 rpc_hf_flash_map(flash_info_t *info, int sector)
++{
++ return info->start[sector] - CONFIG_SYS_RPC_FLASH_BASE;
++}
++
++static inline int rpc_hf_flash_sector(flash_info_t *info, u32 addr)
++{
++ return (addr - info->start[0]) / RPC_HF_ERASE_SIZE;
++}
++
++static inline int rpc_hf_flash_sector_size(flash_info_t *info, int sector)
++{
++ return RPC_HF_ERASE_SIZE;
++}
++
++static void rpc_hf_mode_man(flash_info_t *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(flash_info_t *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(flash_info_t *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(flash_info_t *info, u32 addr)
++{
++ 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_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);
++
++ /*
++ * 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(flash_info_t *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(flash_info_t *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(flash_info_t *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(flash_info_t *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(flash_info_t *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(flash_info_t *info, int enable)
++{
++ rpc_setl(info, RPC_PHYINT, ~RPC_PHYINT_WP, enable ? RPC_PHYINT_WP : 0);
++}
++
++static void rpc_hf_unlock(flash_info_t *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(flash_info_t *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)
++ udelay(delay);
++ }
++
++ if (!(status & RPC_CFI_STATUS_DRB)) {
++ retval = ERR_TIMOUT;
++ goto out;
++ }
++
++ if (status & RPC_CFI_STATUS_PSB) {
++ retval = ERR_PROG_ERROR;
++ goto out;
++ }
++
++ if (status & RPC_CFI_STATUS_ESB) {
++ retval = ERR_NOT_ERASED;
++ goto out;
++ }
++
++ return ERR_OK;
++
++out:
++ rpc_hf_write_cmd(info, 0, RPC_CFI_CMD_RESET);
++ return retval;
++}
++
++static int rpc_hf_sector_erase(flash_info_t *info, int sector)
++{
++ u32 addr = rpc_hf_flash_map(info, sector);
++
++ 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, 10000, 1000);
++}
++
++static ulong rpc_hf_get_size(phys_addr_t base, int banknum)
++{
++ flash_info_t *info = &flash_info[banknum];
++ u16 data[2] = { 0, 0 };
++ ulong id, size = 0;
++ ushort sectors, i;
++
++ info->flash_id = FLASH_UNKNOWN;
++ info->sector_count = -1;
++ info->size = 0;
++
++ 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)
++ 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 & (RPC_HF_ERASE_SIZE - 1))
++ goto out;
++
++ sectors = size / RPC_HF_ERASE_SIZE;
++ if (sectors < 1 || sectors > CONFIG_SYS_MAX_FLASH_SECT)
++ goto out;
++
++ info->flash_id = id;
++ info->size = size;
++ info->sector_count = sectors;
++
++ for (i = 0; i < sectors; i++) {
++ info->start[i] = base;
++ base += RPC_HF_ERASE_SIZE;
++ }
++
++out:
++ rpc_hf_write_cmd(info, 0, RPC_CFI_CMD_RESET);
++ rpc_hf_mode_ext(info);
++ return info->size;
++}
++
++/*
++ * Flash erase, returns:
++ * ERR_OK : OK
++ * ERR_ABORTED : Aborted by user
++ * ERR_PROTECTED : Protected sector
++ */
++int flash_erase(flash_info_t *info, int s_first, int s_last)
++{
++ int s, retval = ERR_OK;
++
++ puts("Erasing Flash... ");
++ for (s = s_first; s <= s_last; s++) {
++ if (ctrlc()) {
++ printf("aborted sector %i\n", s);
++ retval = ERR_ABORTED;
++ goto out;
++ }
++
++ if (info->protect[s]) {
++ printf("protected sector %i\n", s);
++ retval = ERR_PROTECTED;
++ goto out;
++ }
++
++ putc('.');
++
++ retval = rpc_hf_sector_erase(info, s);
++ if (retval != ERR_OK) {
++ printf("error sector %i\n", s);
++ goto out;
++ }
++ }
++ puts("done\n");
++
++out:
++ rpc_hf_mode_ext(info);
++ return retval;
++}
++
++/*
++ * Copy memory to flash, returns:
++ * ERR_OK : OK
++ * ERR_ABORTED : Aborted by user
++ * ERR_PROTECTED : Protected sector
++ */
++int write_buff(flash_info_t *info, uchar *src, ulong addr, ulong cnt)
++{
++ union {
++ u8 b[4];
++ u16 w[2];
++ u32 d;
++ } data;
++ ulong offset, size;
++ int sector, idx, retval;
++ u8 last;
++
++ retval = ERR_OK;
++ idx = 0;
++
++ /* Handle unaligned start */
++ if (addr & 0x1) {
++ addr--;
++ data.b[idx] = readb(addr);
++ idx++;
++ }
++
++ /* Handle unaligned end */
++ offset = addr + idx + cnt;
++ last = offset & 0x1 ? readb(offset) : 0xFF;
++
++ sector = rpc_hf_flash_sector(info, addr);
++ offset = addr - info->start[sector];
++ size = rpc_hf_flash_sector_size(info, sector) - offset;
++ offset += rpc_hf_flash_map(info, sector);
++
++ while (cnt) {
++ if (ctrlc()) {
++ retval = ERR_ABORTED;
++ goto out;
++ }
++
++ if (info->protect[sector]) {
++ retval = ERR_PROTECTED;
++ goto out;
++ }
++
++ if (size > cnt)
++ size = cnt;
++
++ putc('.');
++
++ cnt -= size;
++ while (size) {
++ rpc_hf_unlock(info, info->start[sector]);
++ rpc_hf_write_cmd(info,
++ info->start[sector] + 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, offset);
++ 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;
++ }
++
++ rpc_wait_tend(info);
++ 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));
++
++ retval = rpc_hf_status(info, info->start[sector],
++ 1000000, 10);
++ if (retval)
++ goto out;
++ }
++
++ sector++;
++ offset = rpc_hf_flash_map(info, sector);
++ size = rpc_hf_flash_sector_size(info, sector);
++ }
++
++out:
++ rpc_hf_mode_ext(info);
++ return retval;
++}
++
++/* Print flash information */
++void flash_print_info(flash_info_t *info)
++{
++ if (info->flash_id == FLASH_UNKNOWN)
++ return;
++
++ printf("HyperFlash Id: %lx\n", info->flash_id);
++ printf("Base Address: %lx\n", info->start[0]);
++ printf("Size: %lu MiB\n", info->size >> 20);
++ printf("Sectors: %u\n", info->sector_count);
++}
++
++flash_info_t flash_info[CONFIG_SYS_MAX_FLASH_BANKS];
++
++unsigned long flash_init(void)
++{
++ int i;
++
++ for (i = 0; i < CONFIG_SYS_MAX_FLASH_BANKS; ++i) {
++ flash_info[i].flash_id = FLASH_UNKNOWN;
++ flash_info[i].sector_count = -1;
++ flash_info[i].size = 0;
++ }
++
++ return rpc_hf_get_size(CONFIG_SYS_RPC_FLASH_BASE, 0);
++}
+--
+1.9.3
+
diff --git a/meta-rcar-gen3-adas/recipes-bsp/u-boot/u-boot/0023-board-renesas-salvator-x-Enable-RPC-clock.patch b/meta-rcar-gen3-adas/recipes-bsp/u-boot/u-boot/0023-board-renesas-salvator-x-Enable-RPC-clock.patch
new file mode 100644
index 0000000..bcbf1f6
--- /dev/null
+++ b/meta-rcar-gen3-adas/recipes-bsp/u-boot/u-boot/0023-board-renesas-salvator-x-Enable-RPC-clock.patch
@@ -0,0 +1,37 @@
+From 23e0725daf7ab27d9fa85201b4097112d8c74e1e Mon Sep 17 00:00:00 2001
+From: Valentine Barshak <valentine.barshak@cogentembedded.com>
+Date: Sat, 11 Jun 2016 00:50:06 +0300
+Subject: [PATCH] board: renesas: salvator-x: Enable RPC clock
+
+The RPC clock should have been enabled by the ARM trusted firmware.
+Enable it here just in case.
+
+Signed-off-by: Valentine Barshak <valentine.barshak@cogentembedded.com>
+---
+ board/renesas/salvator-x/salvator-x.c | 3 +++
+ 1 file changed, 3 insertions(+)
+
+diff --git a/board/renesas/salvator-x/salvator-x.c b/board/renesas/salvator-x/salvator-x.c
+index 491d378..803636e 100644
+--- a/board/renesas/salvator-x/salvator-x.c
++++ b/board/renesas/salvator-x/salvator-x.c
+@@ -31,6 +31,7 @@ DECLARE_GLOBAL_DATA_PTR;
+ #define SCIF2_MSTP310 (1 << 10)
+ #define ETHERAVB_MSTP812 (1 << 12)
+ #define DVFS_MSTP926 (1 << 26)
++#define RPC_MSTP917 (1 << 17)
+ #define SD0_MSTP314 (1 << 14)
+ #define SD1_MSTP313 (1 << 13)
+ #define SD2_MSTP312 (1 << 12) /* either MMC0 */
+@@ -51,6 +52,8 @@ int board_early_init_f(void)
+ mstp_clrbits_le32(SMSTPCR3, SMSTPCR3, SCIF2_MSTP310);
+ /* EHTERAVB */
+ mstp_clrbits_le32(SMSTPCR8, SMSTPCR8, ETHERAVB_MSTP812);
++ /* RPC */
++ mstp_clrbits_le32(SMSTPCR9, SMSTPCR9, RPC_MSTP917);
+ /* eMMC */
+ mstp_clrbits_le32(SMSTPCR3, SMSTPCR3, SD1_MSTP313 | SD2_MSTP312);
+ /* SDHI0, 3 */
+--
+1.9.3
+
diff --git a/meta-rcar-gen3-adas/recipes-bsp/u-boot/u-boot/0024-board-renesas-ulcb-Enable-RPC-clock.patch b/meta-rcar-gen3-adas/recipes-bsp/u-boot/u-boot/0024-board-renesas-ulcb-Enable-RPC-clock.patch
new file mode 100644
index 0000000..6328773
--- /dev/null
+++ b/meta-rcar-gen3-adas/recipes-bsp/u-boot/u-boot/0024-board-renesas-ulcb-Enable-RPC-clock.patch
@@ -0,0 +1,37 @@
+From 721d2a219485d106b577701e8643638a500bba30 Mon Sep 17 00:00:00 2001
+From: Valentine Barshak <valentine.barshak@cogentembedded.com>
+Date: Wed, 2 Nov 2016 21:31:24 +0300
+Subject: [PATCH] board: renesas: ulcb: Enable RPC clock
+
+The RPC clock should have been enabled by the ARM trusted firmware.
+Enable it here just in case.
+
+Signed-off-by: Valentine Barshak <valentine.barshak@cogentembedded.com>
+---
+ board/renesas/ulcb/ulcb.c | 3 +++
+ 1 file changed, 3 insertions(+)
+
+diff --git a/board/renesas/ulcb/ulcb.c b/board/renesas/ulcb/ulcb.c
+index 3939f97..2e9baac 100644
+--- a/board/renesas/ulcb/ulcb.c
++++ b/board/renesas/ulcb/ulcb.c
+@@ -33,6 +33,7 @@ DECLARE_GLOBAL_DATA_PTR;
+ #define SCIF2_MSTP310 (1 << 10)
+ #define ETHERAVB_MSTP812 (1 << 12)
+ #define DVFS_MSTP926 (1 << 26)
++#define RPC_MSTP917 (1 << 17)
+ #define SD0_MSTP314 (1 << 14)
+ #define SD1_MSTP313 (1 << 13)
+ #define SD2_MSTP312 (1 << 12)
+@@ -53,6 +54,8 @@ int board_early_init_f(void)
+ mstp_clrbits_le32(SMSTPCR3, SMSTPCR3, SCIF2_MSTP310);
+ /* EHTERAVB */
+ mstp_clrbits_le32(SMSTPCR8, SMSTPCR8, ETHERAVB_MSTP812);
++ /* RPC */
++ mstp_clrbits_le32(SMSTPCR9, SMSTPCR9, RPC_MSTP917);
+ /* eMMC */
+ mstp_clrbits_le32(SMSTPCR3, SMSTPCR3, SD1_MSTP313 | SD2_MSTP312);
+ /* SDHI0 */
+--
+1.9.3
+
diff --git a/meta-rcar-gen3-adas/recipes-bsp/u-boot/u-boot/0025-configs-r8a7795_salvator-x-Enable-RPC-HyperFlash-sup.patch b/meta-rcar-gen3-adas/recipes-bsp/u-boot/u-boot/0025-configs-r8a7795_salvator-x-Enable-RPC-HyperFlash-sup.patch
new file mode 100644
index 0000000..55f141e
--- /dev/null
+++ b/meta-rcar-gen3-adas/recipes-bsp/u-boot/u-boot/0025-configs-r8a7795_salvator-x-Enable-RPC-HyperFlash-sup.patch
@@ -0,0 +1,35 @@
+From 3b35b4c283d4dc95cf92d4a5e15f1a048eb4013f Mon Sep 17 00:00:00 2001
+From: Valentine Barshak <valentine.barshak@cogentembedded.com>
+Date: Mon, 4 Apr 2016 18:41:55 +0300
+Subject: [PATCH] configs: r8a7795_salvator-x: Enable RPC HyperFlash support
+
+This enables flash commands along with the RPC HyperFlash support.
+
+Signed-off-by: Valentine Barshak <valentine.barshak@cogentembedded.com>
+---
+ include/configs/r8a7795_salvator-x.h | 7 +++++--
+ 1 file changed, 5 insertions(+), 2 deletions(-)
+
+diff --git a/include/configs/r8a7795_salvator-x.h b/include/configs/r8a7795_salvator-x.h
+index d5c4c93..db5eae5 100644
+--- a/include/configs/r8a7795_salvator-x.h
++++ b/include/configs/r8a7795_salvator-x.h
+@@ -28,10 +28,13 @@
+
+ /* [A] Hyper Flash */
+ /* use to RPC(SPI Multi I/O Bus Controller) */
++#define CONFIG_RPC_HYPERFLASH
+
+- /* underconstruction */
++#define CONFIG_SYS_FLASH_BASE CONFIG_SYS_RPC_FLASH_BASE
++#define CONFIG_SYS_MAX_FLASH_BANKS 1
++#define CONFIG_SYS_MAX_FLASH_SECT 256
+
+-#define CONFIG_SYS_NO_FLASH
++#define CONFIG_CMD_FLASH
+
+ /* Ethernet RAVB */
+ #define CONFIG_RAVB
+--
+1.9.3
+
diff --git a/meta-rcar-gen3-adas/recipes-bsp/u-boot/u-boot/0026-configs-r8a7796_salvator-x-Enable-RPC-HyperFlash-sup.patch b/meta-rcar-gen3-adas/recipes-bsp/u-boot/u-boot/0026-configs-r8a7796_salvator-x-Enable-RPC-HyperFlash-sup.patch
new file mode 100644
index 0000000..cbc8ac2
--- /dev/null
+++ b/meta-rcar-gen3-adas/recipes-bsp/u-boot/u-boot/0026-configs-r8a7796_salvator-x-Enable-RPC-HyperFlash-sup.patch
@@ -0,0 +1,35 @@
+From 573a190264dabefd8899c681f62d3eb3ec94a78f Mon Sep 17 00:00:00 2001
+From: Valentine Barshak <valentine.barshak@cogentembedded.com>
+Date: Wed, 2 Nov 2016 22:17:32 +0300
+Subject: [PATCH] configs: r8a7796_salvator-x: Enable RPC HyperFlash support
+
+This enables flash commands along with the RPC HyperFlash support.
+
+Signed-off-by: Valentine Barshak <valentine.barshak@cogentembedded.com>
+---
+ include/configs/r8a7796_salvator-x.h | 7 +++++--
+ 1 file changed, 5 insertions(+), 2 deletions(-)
+
+diff --git a/include/configs/r8a7796_salvator-x.h b/include/configs/r8a7796_salvator-x.h
+index 2926b95..6d6a2ef 100644
+--- a/include/configs/r8a7796_salvator-x.h
++++ b/include/configs/r8a7796_salvator-x.h
+@@ -28,10 +28,13 @@
+
+ /* [A] Hyper Flash */
+ /* use to RPC(SPI Multi I/O Bus Controller) */
++#define CONFIG_RPC_HYPERFLASH
+
+- /* underconstruction */
++#define CONFIG_SYS_FLASH_BASE CONFIG_SYS_RPC_FLASH_BASE
++#define CONFIG_SYS_MAX_FLASH_BANKS 1
++#define CONFIG_SYS_MAX_FLASH_SECT 256
+
+-#define CONFIG_SYS_NO_FLASH
++#define CONFIG_CMD_FLASH
+
+ /* Ethernet RAVB */
+ #define CONFIG_RAVB
+--
+1.9.3
+
diff --git a/meta-rcar-gen3-adas/recipes-bsp/u-boot/u-boot/0027-configs-h3ulcb-Enable-RPC-HyperFlash-support.patch b/meta-rcar-gen3-adas/recipes-bsp/u-boot/u-boot/0027-configs-h3ulcb-Enable-RPC-HyperFlash-support.patch
new file mode 100644
index 0000000..ecc5768
--- /dev/null
+++ b/meta-rcar-gen3-adas/recipes-bsp/u-boot/u-boot/0027-configs-h3ulcb-Enable-RPC-HyperFlash-support.patch
@@ -0,0 +1,36 @@
+From be046fe3844db04b04a0c1051375ce7bde7c1dc7 Mon Sep 17 00:00:00 2001
+From: Valentine Barshak <valentine.barshak@cogentembedded.com>
+Date: Wed, 2 Nov 2016 21:34:50 +0300
+Subject: [PATCH] configs: h3ulcb: Enable RPC HyperFlash support
+
+This enables flash commands along with the RPC HyperFlash support.
+
+Signed-off-by: Valentine Barshak <valentine.barshak@cogentembedded.com>
+---
+ include/configs/h3ulcb.h | 10 +++++++++-
+ 1 file changed, 9 insertions(+), 1 deletion(-)
+
+diff --git a/include/configs/h3ulcb.h b/include/configs/h3ulcb.h
+index 73e856d..edda5e8 100644
+--- a/include/configs/h3ulcb.h
++++ b/include/configs/h3ulcb.h
+@@ -27,7 +27,15 @@
+ #define CONFIG_CONS_SCIF2
+ #define CONFIG_SH_SCIF_CLK_FREQ CONFIG_S3D4_CLK_FREQ
+
+-#define CONFIG_SYS_NO_FLASH
++/* [A] Hyper Flash */
++/* use to RPC(SPI Multi I/O Bus Controller) */
++#define CONFIG_RPC_HYPERFLASH
++
++#define CONFIG_SYS_FLASH_BASE CONFIG_SYS_RPC_FLASH_BASE
++#define CONFIG_SYS_MAX_FLASH_BANKS 1
++#define CONFIG_SYS_MAX_FLASH_SECT 256
++
++#define CONFIG_CMD_FLASH
+
+ /* Ethernet RAVB */
+ #define CONFIG_RAVB
+--
+1.9.3
+
diff --git a/meta-rcar-gen3-adas/recipes-bsp/u-boot/u-boot/0028-configs-m3ulcb-Enable-RPC-HyperFlash-support.patch b/meta-rcar-gen3-adas/recipes-bsp/u-boot/u-boot/0028-configs-m3ulcb-Enable-RPC-HyperFlash-support.patch
new file mode 100644
index 0000000..9903433
--- /dev/null
+++ b/meta-rcar-gen3-adas/recipes-bsp/u-boot/u-boot/0028-configs-m3ulcb-Enable-RPC-HyperFlash-support.patch
@@ -0,0 +1,36 @@
+From 592ada9568e8cd9ebbee8f3a609435471e5357d6 Mon Sep 17 00:00:00 2001
+From: Valentine Barshak <valentine.barshak@cogentembedded.com>
+Date: Wed, 2 Nov 2016 21:33:43 +0300
+Subject: [PATCH] configs: m3ulcb: Enable RPC HyperFlash support
+
+This enables flash commands along with the RPC HyperFlash support.
+
+Signed-off-by: Valentine Barshak <valentine.barshak@cogentembedded.com>
+---
+ include/configs/m3ulcb.h | 10 +++++++++-
+ 1 file changed, 9 insertions(+), 1 deletion(-)
+
+diff --git a/include/configs/m3ulcb.h b/include/configs/m3ulcb.h
+index a242079..e3fd75b 100644
+--- a/include/configs/m3ulcb.h
++++ b/include/configs/m3ulcb.h
+@@ -27,7 +27,15 @@
+ #define CONFIG_CONS_SCIF2
+ #define CONFIG_SH_SCIF_CLK_FREQ CONFIG_S3D4_CLK_FREQ
+
+-#define CONFIG_SYS_NO_FLASH
++/* [A] Hyper Flash */
++/* use to RPC(SPI Multi I/O Bus Controller) */
++#define CONFIG_RPC_HYPERFLASH
++
++#define CONFIG_SYS_FLASH_BASE CONFIG_SYS_RPC_FLASH_BASE
++#define CONFIG_SYS_MAX_FLASH_BANKS 1
++#define CONFIG_SYS_MAX_FLASH_SECT 256
++
++#define CONFIG_CMD_FLASH
+
+ /* MEMORY */
+ /* M3ULCB has 2 banks each 1GB */
+--
+1.9.3
+
diff --git a/meta-rcar-gen3-adas/recipes-bsp/u-boot/u-boot/0041-board-renesas-ulcb-console-on-scif1.patch b/meta-rcar-gen3-adas/recipes-bsp/u-boot/u-boot/0041-board-renesas-ulcb-console-on-scif1.patch
new file mode 100644
index 0000000..479f23f
--- /dev/null
+++ b/meta-rcar-gen3-adas/recipes-bsp/u-boot/u-boot/0041-board-renesas-ulcb-console-on-scif1.patch
@@ -0,0 +1,28 @@
+From 4afdb59d00b3cf8c92006b929bd9e48f4f87d6ce Mon Sep 17 00:00:00 2001
+From: Vladimir Barinov <vladimir.barinov@cogentembedded.com>
+Date: Thu, 19 May 2016 08:32:56 +0300
+Subject: [PATCH] uboot: H3ULCB console on scif1
+
+Set console on SCIF1 port for H3ULCB.
+This is only for H3ULCB.HAD
+
+Signed-off-by: Vladimir Barinov <vladimir.barinov@cogentembedded.com>
+---
+ include/configs/h3ulcb.h | 4 ++--
+ 1 file changed, 1 insertions(+), 1 deletions(-)
+
+diff --git a/include/configs/h3ulcb.h b/include/configs/h3ulcb.h
+index b9be845..3da2e5a 100644
+--- a/include/configs/h3ulcb.h
++++ b/include/configs/h3ulcb.h
+@@ -23,6 +23,6 @@
+
+ /* SCIF */
+ #define CONFIG_SCIF_CONSOLE
+-#define CONFIG_CONS_SCIF2
++#define CONFIG_CONS_SCIF1
+ #define CONFIG_SH_SCIF_CLK_FREQ CONFIG_S3D4_CLK_FREQ
+
+--
+1.9.1
+
diff --git a/meta-rcar-gen3-adas/recipes-bsp/u-boot/u-boot/0042-board-renesas-ulcb-set-all-RAVB-pins-strengh-to-maximum.patch b/meta-rcar-gen3-adas/recipes-bsp/u-boot/u-boot/0042-board-renesas-ulcb-set-all-RAVB-pins-strengh-to-maximum.patch
new file mode 100644
index 0000000..638fa7c
--- /dev/null
+++ b/meta-rcar-gen3-adas/recipes-bsp/u-boot/u-boot/0042-board-renesas-ulcb-set-all-RAVB-pins-strengh-to-maximum.patch
@@ -0,0 +1,55 @@
+From b247dea7b49d7e66e1848da71e28ff5fe9acf5e1 Mon Sep 17 00:00:00 2001
+From: Vladimir Barinov <vladimir.barinov@cogentembedded.com>
+Date: Thu, 16 Jun 2016 11:41:43 +0300
+Subject: [PATCH] board: renesas: ulcb: set all RAVB pins strengh to maximum
+
+This is only for H3ULCB.HAD with custom TTTeck ethernet switch
+parameters
+
+Signed-off-by: Vladimir Barinov <vladimir.barinov@cogentembedded.com>
+---
+ board/renesas/ulcb/ulcb.c | 21 +++++++++++++++++++++
+ 2 files changed, 21 insertions(+), 5 deletions(-)
+
+diff --git a/board/renesas/ulcb/ulcb.c b/board/renesas/ulcb/ulcb.c
+index 5652014..f77f946 100644
+--- a/board/renesas/ulcb/ulcb.c
++++ b/board/renesas/ulcb/ulcb.c
+@@ -72,6 +72,22 @@ int board_early_init_f(void)
+
+ DECLARE_GLOBAL_DATA_PTR;
+
++#define PFC_PMMR 0xE6060000
++#define PFC_DRVCTRL1 0xE6060304
++#define PFC_DRVCTRL2 0xE6060308
++#define PFC_DRVCTRL3 0xE606030C
++
++static void write_drvctrl(u32 value, u32 modify_bit, void *reg)
++{
++ u32 val;
++
++ val = readl(reg);
++ val &= ~modify_bit;
++ val |= value;
++ writel(~val, PFC_PMMR);
++ writel(val, reg);
++}
++
+ int board_init(void)
+ {
+ u32 val;
+@@ -86,6 +102,11 @@ int board_init(void)
+ val = readl(PFC_PUEN6) | PUEN_USB1_OVC | PUEN_USB1_PWEN;
+ writel(val, PFC_PUEN6);
+
++ /* EtherAVB pin strength */
++ write_drvctrl(0x00000007, 0x00000007, (void *)PFC_DRVCTRL1);
++ write_drvctrl(0x77777777, 0x77777777, (void *)PFC_DRVCTRL2);
++ write_drvctrl(0x77700000, 0x77700000, (void *)PFC_DRVCTRL3);
++
+ #ifdef CONFIG_RAVB
+ #if defined(CONFIG_R8A7795)
+ if (rcar_is_legacy()) {
+--
+1.9.1
+
diff --git a/meta-rcar-gen3-adas/recipes-bsp/u-boot/u-boot/0043-board-renesas-ulcb-support-fixed-PHY.patch b/meta-rcar-gen3-adas/recipes-bsp/u-boot/u-boot/0043-board-renesas-ulcb-support-fixed-PHY.patch
new file mode 100644
index 0000000..b646d99
--- /dev/null
+++ b/meta-rcar-gen3-adas/recipes-bsp/u-boot/u-boot/0043-board-renesas-ulcb-support-fixed-PHY.patch
@@ -0,0 +1,54 @@
+From 8f65b4710c1f51d01032db201543d0a8269a715f Mon Sep 17 00:00:00 2001
+From: Vladimir Barinov <vladimir.barinov@cogentembedded.com>
+Date: Fri, 20 May 2016 01:18:44 +0300
+Subject: [PATCH] board: renesas/ ulcb: support fixed-PHY
+
+Add support for fixed-PHY on ULCB board
+
+Signed-off-by: Vladimir Barinov <vladimir.barinov@cogentembedded.com>
+---
+ board/renesas/ulcb/ulcb.c | 5 +++++
+ include/configs/h3ulcb.h | 3 +++
+ 2 files changed, 8 insertions(+), 0 deletion(-)
+
+diff --git a/board/renesas/ulcb/ulcb.c b/board/renesas/ulcb/ulcb.c
+index 32a63c9..dcca4f8 100644
+--- a/board/renesas/ulcb/ulcb.c
++++ b/board/renesas/ulcb/ulcb.c
+@@ -26,6 +26,7 @@
+ #include <asm/arch/sh_sdhi.h>
+ #include <i2c.h>
+ #include <mmc.h>
++#include <phy.h>
+
+ DECLARE_GLOBAL_DATA_PTR;
+
+@@ -193,6 +193,10 @@ int board_eth_init(bd_t *bis)
+ /* ULCB has KSZ9031RNX */
+ int board_phy_config(struct phy_device *phydev)
+ {
++#ifdef CONFIG_PHY_FIXED
++ if (!strncmp(phydev->drv->name, "fixed-PHY", 9) && phydev->drv->config)
++ return phydev->drv->config(phydev);
++#endif
+ return 0;
+ }
+
+diff --git a/include/configs/h3ulcb.h b/include/configs/h3ulcb.h
+index 8582b64..b9be845 100644
+--- a/include/configs/h3ulcb.h
++++ b/include/configs/h3ulcb.h
+@@ -40,7 +40,9 @@
+ #define CONFIG_RAVB_PHY_MODE PHY_INTERFACE_MODE_RGMII_ID
+ #define CONFIG_NET_MULTI
+ #define CONFIG_PHYLIB
+-#define CONFIG_PHY_MICREL
++#define CONFIG_PHY_FIXED
++#define CONFIG_PHY_FIXED_SPEED SPEED_1000
++#define CONFIG_PHY_FIXED_DUPLEX DUPLEX_FULL
+ #define CONFIG_BITBANGMII
+ #define CONFIG_BITBANGMII_MULTI
+ #define CONFIG_SH_ETHER_BITBANG
+--
+1.9.1
+
diff --git a/meta-rcar-gen3-adas/recipes-bsp/u-boot/u-boot_2015.04.bbappend b/meta-rcar-gen3-adas/recipes-bsp/u-boot/u-boot_2015.04.bbappend
new file mode 100644
index 0000000..044c598
--- /dev/null
+++ b/meta-rcar-gen3-adas/recipes-bsp/u-boot/u-boot_2015.04.bbappend
@@ -0,0 +1,33 @@
+FILESEXTRAPATHS_prepend := "${THISDIR}/${PN}:"
+
+BRANCH = "v2015.04/rcar-3.5.9"
+SRCREV = "24add58d915191d901915a6a8cc44faa748fcaa2"
+
+SRC_URI_append = " \
+ file://0001-net-phy-support-fixed-PHY.patch \
+ ${@bb.utils.contains('MACHINE_FEATURES', 'h3ulcb-had', ' file://0002-net-ravb-remove-APSR-quirk.patch', '', d)} \
+ file://0003-net-ravb-fix-unsafe-phy-access.patch \
+ file://0004-configs-rcar-gen3-add-CMD_GPIO.patch \
+ file://0005-common-cmd_source.c-Fix-the-source-command-failure-u.patch \
+ file://0006-configs-rcar-gen3-common-Enable-U-Boot-scripts.patch \
+ file://0007-configs-rcar-gen3-common-Enable-echo-command.patch \
+ file://0008-configs-rcar-gen3-common-Enable-setexpr-command.patch \
+ file://0009-configs-rcar-gen3-common-Enable-askenv-command.patch \
+ file://0010-configs-rcar-gen3-common-Enable-hush-parser.patch \
+ file://0011-configs-rcar-gen3-common-Enable-GPT-support.patch \
+ file://0013-mtd-spi-QSPI-flash-support.patch \
+ file://0014-arm-renesas-Add-Renesas-R8A7797-SoC-support.patch \
+ file://0015-board-renesas-Add-V3M-Eagle-board.patch \
+ file://0017-board-renesas-Add-V3MSK-board.patch \
+ file://0021-ARM-rcar_gen3-Add-RPC-flash-definitions.patch \
+ file://0022-mtd-Add-RPC-HyperFlash-support.patch \
+ file://0023-board-renesas-salvator-x-Enable-RPC-clock.patch \
+ file://0024-board-renesas-ulcb-Enable-RPC-clock.patch \
+ file://0025-configs-r8a7795_salvator-x-Enable-RPC-HyperFlash-sup.patch \
+ file://0026-configs-r8a7796_salvator-x-Enable-RPC-HyperFlash-sup.patch \
+ file://0027-configs-h3ulcb-Enable-RPC-HyperFlash-support.patch \
+ file://0028-configs-m3ulcb-Enable-RPC-HyperFlash-support.patch \
+ ${@bb.utils.contains('MACHINE_FEATURES', 'h3ulcb-had', ' file://0041-board-renesas-ulcb-console-on-scif1.patch', '', d)} \
+ ${@bb.utils.contains('MACHINE_FEATURES', 'h3ulcb-had', ' file://0042-board-renesas-ulcb-set-all-RAVB-pins-strengh-to-maximum.patch', '', d)} \
+ ${@bb.utils.contains('MACHINE_FEATURES', 'h3ulcb-had', ' file://0043-board-renesas-ulcb-support-fixed-PHY.patch', '', d)} \
+"
diff --git a/meta-rcar-gen3-adas/recipes-bsp/utest-apps/files/utest-cam-imr-drm.tar.gz b/meta-rcar-gen3-adas/recipes-bsp/utest-apps/files/utest-cam-imr-drm.tar.gz
new file mode 100644
index 0000000..7502d90
--- /dev/null
+++ b/meta-rcar-gen3-adas/recipes-bsp/utest-apps/files/utest-cam-imr-drm.tar.gz
Binary files differ
diff --git a/meta-rcar-gen3-adas/recipes-bsp/utest-apps/utest-cam-imr-drm.bb b/meta-rcar-gen3-adas/recipes-bsp/utest-apps/utest-cam-imr-drm.bb
new file mode 100644
index 0000000..48747ea
--- /dev/null
+++ b/meta-rcar-gen3-adas/recipes-bsp/utest-apps/utest-cam-imr-drm.bb
@@ -0,0 +1,25 @@
+SUMMARY = "Unit test for VIN-IMR-DRM camera capture pipe"
+LICENSE = "CLOSED"
+
+inherit cmake
+
+S = "${WORKDIR}/utest-cam-imr-drm"
+
+SRC_URI = " \
+ file://utest-cam-imr-drm.tar.gz \
+"
+
+DEPENDS = " \
+ libspnav \
+ libdrm \
+ gstreamer1.0-plugins-base \
+ mmngr-user-module \
+ mmngrbuf-user-module \
+"
+
+do_install() {
+ install -d ${D}${bindir}
+ install -m 755 ${S}/../build/utest/utest-cam-imr-drm ${D}${bindir}
+}
+
+EXTRA_OECMAKE += " -DCMAKE_SYSROOT=${STAGING_DIR_TARGET} "
diff --git a/meta-rcar-gen3-adas/recipes-bsp/v4l2-fw/files/v4l2-fw.tar.gz b/meta-rcar-gen3-adas/recipes-bsp/v4l2-fw/files/v4l2-fw.tar.gz
new file mode 100644
index 0000000..b028ce0
--- /dev/null
+++ b/meta-rcar-gen3-adas/recipes-bsp/v4l2-fw/files/v4l2-fw.tar.gz
Binary files differ
diff --git a/meta-rcar-gen3-adas/recipes-bsp/v4l2-fw/v4l2-fw_1.0.bb b/meta-rcar-gen3-adas/recipes-bsp/v4l2-fw/v4l2-fw_1.0.bb
new file mode 100644
index 0000000..31647d4
--- /dev/null
+++ b/meta-rcar-gen3-adas/recipes-bsp/v4l2-fw/v4l2-fw_1.0.bb
@@ -0,0 +1,58 @@
+SUMMARY = "OV10640/OV490 SPI flash firmware update tool"
+LICENSE = "GPLv2"
+LIC_FILES_CHKSUM = "file://COPYING;md5=eb766567485731157b3c21013c3ce4b8"
+
+S = "${WORKDIR}/v4l2-fw"
+
+SRC_URI = " \
+ file://v4l2-fw.tar.gz \
+"
+
+do_compile() {
+ cd ${S}
+ make all || die
+}
+
+do_install() {
+ install -d ${D}${bindir}
+ install -m 755 ${S}/v4l2-fw ${D}${bindir}
+
+ install -d ${D}/usr/share/factory/
+ install -m 644 ${S}/OV10640_OV490_combine_general_v491_20160105_common_withSPIHeader_1280x1080@30_96Mhz.bin ${D}/usr/share/factory/
+ install -m 644 ${S}/OV10640_OV490_combine_general_v491_20160105_common_withSPIHeader_1280x800@30_96Mhz.bin ${D}/usr/share/factory/
+ install -m 644 ${S}/OV10640_OV490_combine_general_v491_20160105_common_withSPIHeader_1280x966@30_96Mhz.bin ${D}/usr/share/factory/
+ install -m 644 ${S}/OV10640_OV490_combine_general_v491_20160105_common_withSPIHeader_640x480@30_96Mhz.bin ${D}/usr/share/factory/
+ install -m 644 ${S}/OV10640_OV490_combine_general_v491_20160105_common_withSPIHeader_640x480@60_96MHz.bin ${D}/usr/share/factory/
+ install -m 644 ${S}/OV10640_OV490_combine_general_v491_20160105_common_withSPIHeader_1280x528@60_96MHz.bin ${D}/usr/share/factory/
+ install -m 644 ${S}/rdcam21.rdcam24.1280x1080@30.bin ${D}/usr/share/factory/
+ install -m 755 ${S}/ov10640_ov490_flash_0-3.sh ${D}/usr/share/factory/
+ install -m 755 ${S}/ov10640_ov490_flash_4-7.sh ${D}/usr/share/factory/
+ install -m 755 ${S}/rdcam21_rdcam24_flash_0-3.sh ${D}/usr/share/factory/
+
+ install -m 755 ${S}/otp_10640_read_bank1.sh ${D}/usr/share/factory/
+ install -m 755 ${S}/otp_10640_write_bank1.sh ${D}/usr/share/factory/
+ install -m 755 ${S}/ov10640_read.sh ${D}/usr/share/factory/
+ install -m 755 ${S}/ov10640_write.sh ${D}/usr/share/factory/
+ install -m 755 ${S}/ov490_read.sh ${D}/usr/share/factory/
+ install -m 755 ${S}/ov490_write.sh ${D}/usr/share/factory/
+}
+
+FILES_${PN} = " \
+ ${bindir}/v4l2-fw \
+ /usr/share/factory/OV10640_OV490_combine_general_v491_20160105_common_withSPIHeader_1280x1080@30_96Mhz.bin \
+ /usr/share/factory/OV10640_OV490_combine_general_v491_20160105_common_withSPIHeader_1280x800@30_96Mhz.bin \
+ /usr/share/factory/OV10640_OV490_combine_general_v491_20160105_common_withSPIHeader_1280x966@30_96Mhz.bin \
+ /usr/share/factory/OV10640_OV490_combine_general_v491_20160105_common_withSPIHeader_640x480@30_96Mhz.bin \
+ /usr/share/factory/OV10640_OV490_combine_general_v491_20160105_common_withSPIHeader_640x480@60_96MHz.bin \
+ /usr/share/factory/OV10640_OV490_combine_general_v491_20160105_common_withSPIHeader_1280x528@60_96MHz.bin \
+ /usr/share/factory/rdcam21.rdcam24.1280x1080@30.bin \
+ /usr/share/factory/ov10640_ov490_flash_0-3.sh \
+ /usr/share/factory/ov10640_ov490_flash_4-7.sh \
+ /usr/share/factory/rdcam21_rdcam24_flash_0-3.sh \
+ /usr/share/factory/otp_10640_read_bank1.sh \
+ /usr/share/factory/otp_10640_write_bank1.sh \
+ /usr/share/factory/ov10640_read.sh \
+ /usr/share/factory/ov10640_write.sh \
+ /usr/share/factory/ov490_read.sh \
+ /usr/share/factory/ov490_write.sh \
+"
diff --git a/meta-rcar-gen3-adas/recipes-core/images/core-image-minimal.bbappend b/meta-rcar-gen3-adas/recipes-core/images/core-image-minimal.bbappend
new file mode 100644
index 0000000..b33763d
--- /dev/null
+++ b/meta-rcar-gen3-adas/recipes-core/images/core-image-minimal.bbappend
@@ -0,0 +1,5 @@
+IMAGE_INSTALL_append = " \
+ packagegroup-opencv-sdk \
+ packagegroup-surroundview-drm \
+ utest-cam-imr-drm \
+"
diff --git a/meta-rcar-gen3-adas/recipes-core/images/core-image-weston.bbappend b/meta-rcar-gen3-adas/recipes-core/images/core-image-weston.bbappend
new file mode 100644
index 0000000..945d9b0
--- /dev/null
+++ b/meta-rcar-gen3-adas/recipes-core/images/core-image-weston.bbappend
@@ -0,0 +1,6 @@
+IMAGE_INSTALL_append = " \
+ packagegroup-opencv-sdk \
+ packagegroup-surroundview \
+"
+
+CONFLICT_DISTRO_FEATURES = "x11" \ No newline at end of file
diff --git a/meta-rcar-gen3-adas/recipes-core/packagegroups/nativesdk-packagegroup-sdk-host.bbappend b/meta-rcar-gen3-adas/recipes-core/packagegroups/nativesdk-packagegroup-sdk-host.bbappend
new file mode 100644
index 0000000..a936b24
--- /dev/null
+++ b/meta-rcar-gen3-adas/recipes-core/packagegroups/nativesdk-packagegroup-sdk-host.bbappend
@@ -0,0 +1,3 @@
+RDEPENDS_${PN} += " \
+ nativesdk-cmake \
+"
diff --git a/meta-rcar-gen3-adas/recipes-core/packagegroups/packagegroup-opencv-sdk.bb b/meta-rcar-gen3-adas/recipes-core/packagegroups/packagegroup-opencv-sdk.bb
new file mode 100644
index 0000000..81d81d9
--- /dev/null
+++ b/meta-rcar-gen3-adas/recipes-core/packagegroups/packagegroup-opencv-sdk.bb
@@ -0,0 +1,28 @@
+DESCRIPTION = "OpenCV SDK packages"
+LICENSE = "GPL"
+
+inherit packagegroup
+
+PACKAGES = " \
+ packagegroup-opencv-sdk \
+"
+
+RDEPENDS_packagegroup-opencv-sdk = '${@ " \
+ opencv \
+ opencv-apps \
+ opencv-dbg \
+ libopencv-calib3d \
+ libopencv-core \
+ libopencv-features2d \
+ libopencv-flann \
+ libopencv-highgui \
+ libopencv-imgproc \
+ libopencv-ml \
+ libopencv-objdetect \
+ libopencv-photo \
+ libopencv-stitching \
+ libopencv-superres \
+ libopencv-video \
+ libopencv-videostab \
+ gstreamer1.0-plugins-base-app \
+" if 'opencv-sdk' in '${DISTRO_FEATURES}' else ""}'
diff --git a/meta-rcar-gen3-adas/recipes-core/packagegroups/packagegroup-surroundview-drm.bb b/meta-rcar-gen3-adas/recipes-core/packagegroups/packagegroup-surroundview-drm.bb
new file mode 100644
index 0000000..f518caf
--- /dev/null
+++ b/meta-rcar-gen3-adas/recipes-core/packagegroups/packagegroup-surroundview-drm.bb
@@ -0,0 +1,19 @@
+DESCRIPTION = "Packages required for DRM Surroundview demo"
+LICENSE = "GPL"
+
+inherit packagegroup
+
+PACKAGES = " \
+ packagegroup-surroundview-drm \
+"
+
+RDEPENDS_packagegroup-surroundview-drm = '${@ " \
+ spacenavd \
+ libspnav \
+ gstreamer1.0-plugins-base libgstallocators-1.0 \
+ gstreamer1.0-plugins-base-app libgstapp-1.0 \
+ libdrm \
+ kernel-module-mmngr \
+ kernel-module-mmngrbuf \
+ mmngr-user-module \
+" if 'surroundview' in '${DISTRO_FEATURES}' else ""}'
diff --git a/meta-rcar-gen3-adas/recipes-core/packagegroups/packagegroup-surroundview.bb b/meta-rcar-gen3-adas/recipes-core/packagegroups/packagegroup-surroundview.bb
new file mode 100644
index 0000000..d31e5fe
--- /dev/null
+++ b/meta-rcar-gen3-adas/recipes-core/packagegroups/packagegroup-surroundview.bb
@@ -0,0 +1,19 @@
+DESCRIPTION = "Packages required for GPU Surroundview demo"
+LICENSE = "GPL"
+
+inherit packagegroup
+
+PACKAGES = " \
+ packagegroup-surroundview \
+"
+
+RDEPENDS_packagegroup-surroundview = '${@ " \
+ spacenavd \
+ libspnav \
+ glm \
+ nlopt \
+ gstreamer1.0-omx \
+ gstreamer1.0-plugins-base-app libgstapp-1.0 \
+ yaml-cpp \
+ libmediactl-v4l2 \
+" if 'surroundview' in '${DISTRO_FEATURES}' else ""}'
diff --git a/meta-rcar-gen3-adas/recipes-core/udev/udev-rules-cvlib.bb b/meta-rcar-gen3-adas/recipes-core/udev/udev-rules-cvlib.bb
new file mode 100644
index 0000000..98485c6
--- /dev/null
+++ b/meta-rcar-gen3-adas/recipes-core/udev/udev-rules-cvlib.bb
@@ -0,0 +1,13 @@
+SUMMARY = "udev rules for R-Car Gen3 CV Library"
+LICENSE = "CLOSED"
+
+SRC_URI = " \
+ file://51-imp.rules \
+ file://52-cmem.rules \
+"
+
+do_install () {
+ install -d ${D}${sysconfdir}/udev/rules.d/
+ install -m 0644 ${WORKDIR}/51-imp.rules ${D}${sysconfdir}/udev/rules.d/
+ install -m 0644 ${WORKDIR}/52-cmem.rules ${D}${sysconfdir}/udev/rules.d/
+}
diff --git a/meta-rcar-gen3-adas/recipes-core/udev/udev-rules-cvlib/51-imp.rules b/meta-rcar-gen3-adas/recipes-core/udev/udev-rules-cvlib/51-imp.rules
new file mode 100644
index 0000000..df1a4b2
--- /dev/null
+++ b/meta-rcar-gen3-adas/recipes-core/udev/udev-rules-cvlib/51-imp.rules
@@ -0,0 +1 @@
+SUBSYSTEM=="uio", ATTR{name}=="im*", SYMLINK+="$attr{name}", MODE="0666"
diff --git a/meta-rcar-gen3-adas/recipes-core/udev/udev-rules-cvlib/52-cmem.rules b/meta-rcar-gen3-adas/recipes-core/udev/udev-rules-cvlib/52-cmem.rules
new file mode 100644
index 0000000..7846e68
--- /dev/null
+++ b/meta-rcar-gen3-adas/recipes-core/udev/udev-rules-cvlib/52-cmem.rules
@@ -0,0 +1 @@
+SUBSYSTEM=="cmem", MODE="0666"
diff --git a/meta-rcar-gen3-adas/recipes-devtools/yaml-cpp/yaml-cpp_0.5.3.bb b/meta-rcar-gen3-adas/recipes-devtools/yaml-cpp/yaml-cpp_0.5.3.bb
new file mode 100644
index 0000000..0a05595
--- /dev/null
+++ b/meta-rcar-gen3-adas/recipes-devtools/yaml-cpp/yaml-cpp_0.5.3.bb
@@ -0,0 +1,19 @@
+DESCRIPTION = "yaml-cpp is a YAML parser and emitter in C++ matching the YAML 1.2 spec"
+HOMEPAGE = "https://github.com/jbeder/yaml-cpp/"
+SECTION = "libs"
+LICENSE = "MIT"
+LIC_FILES_CHKSUM = "file://LICENSE;md5=6a8aaf0595c2efc1a9c2e0913e9c1a2c"
+
+DEPENDS = "boost"
+
+PR = "r0"
+
+S = "${WORKDIR}/yaml-cpp-release-${PV}"
+
+SRC_URI = "https://github.com/jbeder/yaml-cpp/archive/release-${PV}.tar.gz"
+SRC_URI[md5sum] = "64200ca0bf5e0af065804d8d3e8f6d42"
+SRC_URI[sha256sum] = "ac50a27a201d16dc69a881b80ad39a7be66c4d755eda1f76c3a68781b922af8f"
+
+EXTRA_OECMAKE = "-DBUILD_SHARED_LIBS=ON"
+
+inherit cmake
diff --git a/meta-rcar-gen3-adas/recipes-devtools/yaml-cpp/yaml-cpp_git.bb b/meta-rcar-gen3-adas/recipes-devtools/yaml-cpp/yaml-cpp_git.bb
new file mode 100644
index 0000000..9c27f81
--- /dev/null
+++ b/meta-rcar-gen3-adas/recipes-devtools/yaml-cpp/yaml-cpp_git.bb
@@ -0,0 +1,23 @@
+DESCRIPTION = "yaml-cpp is a YAML parser and emitter in C++ matching the YAML 1.2 spec"
+HOMEPAGE = "https://github.com/jbeder/yaml-cpp/"
+SECTION = "libs"
+LICENSE = "MIT"
+LIC_FILES_CHKSUM = "file://LICENSE;md5=6a8aaf0595c2efc1a9c2e0913e9c1a2c"
+
+DEPENDS = "boost"
+
+PR = "r0"
+
+S = "${WORKDIR}/git"
+
+SRC_URI = "git://github.com/jbeder/yaml-cpp.git"
+SRCREV = "bedb28fdb4fd52d97e02f6cb946cae631037089e"
+
+# pkgconfig is enough
+do_install_append() {
+ rm -r ${D}${libdir}/cmake
+}
+
+EXTRA_OECMAKE = "-DBUILD_SHARED_LIBS=ON"
+
+inherit cmake \ No newline at end of file
diff --git a/meta-rcar-gen3-adas/recipes-kernel/kernel-module-cmemdrv/files/GPL-COPYING b/meta-rcar-gen3-adas/recipes-kernel/kernel-module-cmemdrv/files/GPL-COPYING
new file mode 100644
index 0000000..d159169
--- /dev/null
+++ b/meta-rcar-gen3-adas/recipes-kernel/kernel-module-cmemdrv/files/GPL-COPYING
@@ -0,0 +1,339 @@
+ GNU GENERAL PUBLIC LICENSE
+ Version 2, June 1991
+
+ Copyright (C) 1989, 1991 Free Software Foundation, Inc.,
+ 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
+ Everyone is permitted to copy and distribute verbatim copies
+ of this license document, but changing it is not allowed.
+
+ Preamble
+
+ The licenses for most software are designed to take away your
+freedom to share and change it. By contrast, the GNU General Public
+License is intended to guarantee your freedom to share and change free
+software--to make sure the software is free for all its users. This
+General Public License applies to most of the Free Software
+Foundation's software and to any other program whose authors commit to
+using it. (Some other Free Software Foundation software is covered by
+the GNU Lesser General Public License instead.) You can apply it to
+your programs, too.
+
+ When we speak of free software, we are referring to freedom, not
+price. Our General Public Licenses are designed to make sure that you
+have the freedom to distribute copies of free software (and charge for
+this service if you wish), that you receive source code or can get it
+if you want it, that you can change the software or use pieces of it
+in new free programs; and that you know you can do these things.
+
+ To protect your rights, we need to make restrictions that forbid
+anyone to deny you these rights or to ask you to surrender the rights.
+These restrictions translate to certain responsibilities for you if you
+distribute copies of the software, or if you modify it.
+
+ For example, if you distribute copies of such a program, whether
+gratis or for a fee, you must give the recipients all the rights that
+you have. You must make sure that they, too, receive or can get the
+source code. And you must show them these terms so they know their
+rights.
+
+ We protect your rights with two steps: (1) copyright the software, and
+(2) offer you this license which gives you legal permission to copy,
+distribute and/or modify the software.
+
+ Also, for each author's protection and ours, we want to make certain
+that everyone understands that there is no warranty for this free
+software. If the software is modified by someone else and passed on, we
+want its recipients to know that what they have is not the original, so
+that any problems introduced by others will not reflect on the original
+authors' reputations.
+
+ Finally, any free program is threatened constantly by software
+patents. We wish to avoid the danger that redistributors of a free
+program will individually obtain patent licenses, in effect making the
+program proprietary. To prevent this, we have made it clear that any
+patent must be licensed for everyone's free use or not licensed at all.
+
+ The precise terms and conditions for copying, distribution and
+modification follow.
+
+ GNU GENERAL PUBLIC LICENSE
+ TERMS AND CONDITIONS FOR COPYING, DISTRIBUTION AND MODIFICATION
+
+ 0. This License applies to any program or other work which contains
+a notice placed by the copyright holder saying it may be distributed
+under the terms of this General Public License. The "Program", below,
+refers to any such program or work, and a "work based on the Program"
+means either the Program or any derivative work under copyright law:
+that is to say, a work containing the Program or a portion of it,
+either verbatim or with modifications and/or translated into another
+language. (Hereinafter, translation is included without limitation in
+the term "modification".) Each licensee is addressed as "you".
+
+Activities other than copying, distribution and modification are not
+covered by this License; they are outside its scope. The act of
+running the Program is not restricted, and the output from the Program
+is covered only if its contents constitute a work based on the
+Program (independent of having been made by running the Program).
+Whether that is true depends on what the Program does.
+
+ 1. You may copy and distribute verbatim copies of the Program's
+source code as you receive it, in any medium, provided that you
+conspicuously and appropriately publish on each copy an appropriate
+copyright notice and disclaimer of warranty; keep intact all the
+notices that refer to this License and to the absence of any warranty;
+and give any other recipients of the Program a copy of this License
+along with the Program.
+
+You may charge a fee for the physical act of transferring a copy, and
+you may at your option offer warranty protection in exchange for a fee.
+
+ 2. You may modify your copy or copies of the Program or any portion
+of it, thus forming a work based on the Program, and copy and
+distribute such modifications or work under the terms of Section 1
+above, provided that you also meet all of these conditions:
+
+ a) You must cause the modified files to carry prominent notices
+ stating that you changed the files and the date of any change.
+
+ b) You must cause any work that you distribute or publish, that in
+ whole or in part contains or is derived from the Program or any
+ part thereof, to be licensed as a whole at no charge to all third
+ parties under the terms of this License.
+
+ c) If the modified program normally reads commands interactively
+ when run, you must cause it, when started running for such
+ interactive use in the most ordinary way, to print or display an
+ announcement including an appropriate copyright notice and a
+ notice that there is no warranty (or else, saying that you provide
+ a warranty) and that users may redistribute the program under
+ these conditions, and telling the user how to view a copy of this
+ License. (Exception: if the Program itself is interactive but
+ does not normally print such an announcement, your work based on
+ the Program is not required to print an announcement.)
+
+These requirements apply to the modified work as a whole. If
+identifiable sections of that work are not derived from the Program,
+and can be reasonably considered independent and separate works in
+themselves, then this License, and its terms, do not apply to those
+sections when you distribute them as separate works. But when you
+distribute the same sections as part of a whole which is a work based
+on the Program, the distribution of the whole must be on the terms of
+this License, whose permissions for other licensees extend to the
+entire whole, and thus to each and every part regardless of who wrote it.
+
+Thus, it is not the intent of this section to claim rights or contest
+your rights to work written entirely by you; rather, the intent is to
+exercise the right to control the distribution of derivative or
+collective works based on the Program.
+
+In addition, mere aggregation of another work not based on the Program
+with the Program (or with a work based on the Program) on a volume of
+a storage or distribution medium does not bring the other work under
+the scope of this License.
+
+ 3. You may copy and distribute the Program (or a work based on it,
+under Section 2) in object code or executable form under the terms of
+Sections 1 and 2 above provided that you also do one of the following:
+
+ a) Accompany it with the complete corresponding machine-readable
+ source code, which must be distributed under the terms of Sections
+ 1 and 2 above on a medium customarily used for software interchange; or,
+
+ b) Accompany it with a written offer, valid for at least three
+ years, to give any third party, for a charge no more than your
+ cost of physically performing source distribution, a complete
+ machine-readable copy of the corresponding source code, to be
+ distributed under the terms of Sections 1 and 2 above on a medium
+ customarily used for software interchange; or,
+
+ c) Accompany it with the information you received as to the offer
+ to distribute corresponding source code. (This alternative is
+ allowed only for noncommercial distribution and only if you
+ received the program in object code or executable form with such
+ an offer, in accord with Subsection b above.)
+
+The source code for a work means the preferred form of the work for
+making modifications to it. For an executable work, complete source
+code means all the source code for all modules it contains, plus any
+associated interface definition files, plus the scripts used to
+control compilation and installation of the executable. However, as a
+special exception, the source code distributed need not include
+anything that is normally distributed (in either source or binary
+form) with the major components (compiler, kernel, and so on) of the
+operating system on which the executable runs, unless that component
+itself accompanies the executable.
+
+If distribution of executable or object code is made by offering
+access to copy from a designated place, then offering equivalent
+access to copy the source code from the same place counts as
+distribution of the source code, even though third parties are not
+compelled to copy the source along with the object code.
+
+ 4. You may not copy, modify, sublicense, or distribute the Program
+except as expressly provided under this License. Any attempt
+otherwise to copy, modify, sublicense or distribute the Program is
+void, and will automatically terminate your rights under this License.
+However, parties who have received copies, or rights, from you under
+this License will not have their licenses terminated so long as such
+parties remain in full compliance.
+
+ 5. You are not required to accept this License, since you have not
+signed it. However, nothing else grants you permission to modify or
+distribute the Program or its derivative works. These actions are
+prohibited by law if you do not accept this License. Therefore, by
+modifying or distributing the Program (or any work based on the
+Program), you indicate your acceptance of this License to do so, and
+all its terms and conditions for copying, distributing or modifying
+the Program or works based on it.
+
+ 6. Each time you redistribute the Program (or any work based on the
+Program), the recipient automatically receives a license from the
+original licensor to copy, distribute or modify the Program subject to
+these terms and conditions. You may not impose any further
+restrictions on the recipients' exercise of the rights granted herein.
+You are not responsible for enforcing compliance by third parties to
+this License.
+
+ 7. If, as a consequence of a court judgment or allegation of patent
+infringement or for any other reason (not limited to patent issues),
+conditions are imposed on you (whether by court order, agreement or
+otherwise) that contradict the conditions of this License, they do not
+excuse you from the conditions of this License. If you cannot
+distribute so as to satisfy simultaneously your obligations under this
+License and any other pertinent obligations, then as a consequence you
+may not distribute the Program at all. For example, if a patent
+license would not permit royalty-free redistribution of the Program by
+all those who receive copies directly or indirectly through you, then
+the only way you could satisfy both it and this License would be to
+refrain entirely from distribution of the Program.
+
+If any portion of this section is held invalid or unenforceable under
+any particular circumstance, the balance of the section is intended to
+apply and the section as a whole is intended to apply in other
+circumstances.
+
+It is not the purpose of this section to induce you to infringe any
+patents or other property right claims or to contest validity of any
+such claims; this section has the sole purpose of protecting the
+integrity of the free software distribution system, which is
+implemented by public license practices. Many people have made
+generous contributions to the wide range of software distributed
+through that system in reliance on consistent application of that
+system; it is up to the author/donor to decide if he or she is willing
+to distribute software through any other system and a licensee cannot
+impose that choice.
+
+This section is intended to make thoroughly clear what is believed to
+be a consequence of the rest of this License.
+
+ 8. If the distribution and/or use of the Program is restricted in
+certain countries either by patents or by copyrighted interfaces, the
+original copyright holder who places the Program under this License
+may add an explicit geographical distribution limitation excluding
+those countries, so that distribution is permitted only in or among
+countries not thus excluded. In such case, this License incorporates
+the limitation as if written in the body of this License.
+
+ 9. The Free Software Foundation may publish revised and/or new versions
+of the General Public License from time to time. Such new versions will
+be similar in spirit to the present version, but may differ in detail to
+address new problems or concerns.
+
+Each version is given a distinguishing version number. If the Program
+specifies a version number of this License which applies to it and "any
+later version", you have the option of following the terms and conditions
+either of that version or of any later version published by the Free
+Software Foundation. If the Program does not specify a version number of
+this License, you may choose any version ever published by the Free Software
+Foundation.
+
+ 10. If you wish to incorporate parts of the Program into other free
+programs whose distribution conditions are different, write to the author
+to ask for permission. For software which is copyrighted by the Free
+Software Foundation, write to the Free Software Foundation; we sometimes
+make exceptions for this. Our decision will be guided by the two goals
+of preserving the free status of all derivatives of our free software and
+of promoting the sharing and reuse of software generally.
+
+ NO WARRANTY
+
+ 11. BECAUSE THE PROGRAM IS LICENSED FREE OF CHARGE, THERE IS NO WARRANTY
+FOR THE PROGRAM, TO THE EXTENT PERMITTED BY APPLICABLE LAW. EXCEPT WHEN
+OTHERWISE STATED IN WRITING THE COPYRIGHT HOLDERS AND/OR OTHER PARTIES
+PROVIDE THE PROGRAM "AS IS" WITHOUT WARRANTY OF ANY KIND, EITHER EXPRESSED
+OR IMPLIED, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
+MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE. THE ENTIRE RISK AS
+TO THE QUALITY AND PERFORMANCE OF THE PROGRAM IS WITH YOU. SHOULD THE
+PROGRAM PROVE DEFECTIVE, YOU ASSUME THE COST OF ALL NECESSARY SERVICING,
+REPAIR OR CORRECTION.
+
+ 12. IN NO EVENT UNLESS REQUIRED BY APPLICABLE LAW OR AGREED TO IN WRITING
+WILL ANY COPYRIGHT HOLDER, OR ANY OTHER PARTY WHO MAY MODIFY AND/OR
+REDISTRIBUTE THE PROGRAM AS PERMITTED ABOVE, BE LIABLE TO YOU FOR DAMAGES,
+INCLUDING ANY GENERAL, SPECIAL, INCIDENTAL OR CONSEQUENTIAL DAMAGES ARISING
+OUT OF THE USE OR INABILITY TO USE THE PROGRAM (INCLUDING BUT NOT LIMITED
+TO LOSS OF DATA OR DATA BEING RENDERED INACCURATE OR LOSSES SUSTAINED BY
+YOU OR THIRD PARTIES OR A FAILURE OF THE PROGRAM TO OPERATE WITH ANY OTHER
+PROGRAMS), EVEN IF SUCH HOLDER OR OTHER PARTY HAS BEEN ADVISED OF THE
+POSSIBILITY OF SUCH DAMAGES.
+
+ END OF TERMS AND CONDITIONS
+
+ How to Apply These Terms to Your New Programs
+
+ If you develop a new program, and you want it to be of the greatest
+possible use to the public, the best way to achieve this is to make it
+free software which everyone can redistribute and change under these terms.
+
+ To do so, attach the following notices to the program. It is safest
+to attach them to the start of each source file to most effectively
+convey the exclusion of warranty; and each file should have at least
+the "copyright" line and a pointer to where the full notice is found.
+
+ <one line to give the program's name and a brief idea of what it does.>
+ Copyright (C) <year> <name of author>
+
+ 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.
+
+ 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 Street, Fifth Floor, Boston, MA 02110-1301 USA.
+
+Also add information on how to contact you by electronic and paper mail.
+
+If the program is interactive, make it output a short notice like this
+when it starts in an interactive mode:
+
+ Gnomovision version 69, Copyright (C) year name of author
+ Gnomovision comes with ABSOLUTELY NO WARRANTY; for details type `show w'.
+ This is free software, and you are welcome to redistribute it
+ under certain conditions; type `show c' for details.
+
+The hypothetical commands `show w' and `show c' should show the appropriate
+parts of the General Public License. Of course, the commands you use may
+be called something other than `show w' and `show c'; they could even be
+mouse-clicks or menu items--whatever suits your program.
+
+You should also get your employer (if you work as a programmer) or your
+school, if any, to sign a "copyright disclaimer" for the program, if
+necessary. Here is a sample; alter the names:
+
+ Yoyodyne, Inc., hereby disclaims all copyright interest in the program
+ `Gnomovision' (which makes passes at compilers) written by James Hacker.
+
+ <signature of Ty Coon>, 1 April 1989
+ Ty Coon, President of Vice
+
+This General Public License does not permit incorporating your program into
+proprietary programs. If your program is a subroutine library, you may
+consider it more useful to permit linking proprietary applications with the
+library. If this is what you want to do, use the GNU Lesser General
+Public License instead of this License.
diff --git a/meta-rcar-gen3-adas/recipes-kernel/kernel-module-cmemdrv/files/MIT-COPYING b/meta-rcar-gen3-adas/recipes-kernel/kernel-module-cmemdrv/files/MIT-COPYING
new file mode 100644
index 0000000..28e2a15
--- /dev/null
+++ b/meta-rcar-gen3-adas/recipes-kernel/kernel-module-cmemdrv/files/MIT-COPYING
@@ -0,0 +1,41 @@
+
+This software is Copyright (C) 2013 Renesas Electronics Corporation
+
+You may use, distribute and copy this software under the terms of the MIT
+license displayed 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.
+
+-----------------------------------------------------------------------------
+
+ 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.
+
+-----------------------------------------------------------------------------
diff --git a/meta-rcar-gen3-adas/recipes-kernel/kernel-module-cmemdrv/files/Makefile b/meta-rcar-gen3-adas/recipes-kernel/kernel-module-cmemdrv/files/Makefile
new file mode 100644
index 0000000..2e26bfb
--- /dev/null
+++ b/meta-rcar-gen3-adas/recipes-kernel/kernel-module-cmemdrv/files/Makefile
@@ -0,0 +1,14 @@
+obj-m := cmemdrv.o
+
+SRC := $(shell pwd)
+
+all:
+ $(MAKE) -C $(KERNEL_SRC) M=$(SRC)
+
+modules_install:
+ $(MAKE) -C $(KERNEL_SRC) M=$(SRC) modules_install
+
+clean:
+ rm -f *.o *~ core .depend .*.cmd *.ko *.mod.c
+ rm -f Module.markers Module.symvers modules.order
+ rm -rf .tmp_versions Modules.symvers
diff --git a/meta-rcar-gen3-adas/recipes-kernel/kernel-module-cmemdrv/files/cmemdrv.c b/meta-rcar-gen3-adas/recipes-kernel/kernel-module-cmemdrv/files/cmemdrv.c
new file mode 100644
index 0000000..a5d4363
--- /dev/null
+++ b/meta-rcar-gen3-adas/recipes-kernel/kernel-module-cmemdrv/files/cmemdrv.c
@@ -0,0 +1,457 @@
+/*************************************************************************/ /*
+ Memory Driver (kernel module)
+
+ 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
+*/ /*************************************************************************/
+
+#include <linux/module.h>
+#include <linux/kernel.h>
+#include <linux/string.h>
+#include <linux/fs.h>
+#include <asm/uaccess.h>
+#include <linux/dma-mapping.h>
+#include <linux/slab.h>
+#include <linux/device.h>
+#include <linux/of_device.h>
+
+#define MAX_AREA_NUM 4
+#define DEFAULT_AREA_SIZE (16 * 1024 * 1024)
+
+#define PARAM_SET 1
+#define M_LOCK 3
+#define M_UNLOCK 4
+#define GET_PHYS_ADDR 5
+#define M_ALLOCATE 6
+#define M_UNALLOCATE 7
+#define TRY_CONV 8
+
+#define IOCTL_FROM_IMP_TO_CPU 0
+#define IOCTL_FROM_CPU_TO_IMP 1
+
+struct mem_area_data {
+ struct device *dev;
+ size_t size;
+ void *virt_ptr;
+ dma_addr_t phys_addr;
+};
+
+struct mem_access_data {
+ struct mem_area_data* area;
+ int start_offset;
+ int offset;
+ int width;
+ int height;
+ int stride;
+ int locked;
+ int tl;
+};
+
+static unsigned int bsize_count;
+static unsigned long bsize[MAX_AREA_NUM];
+module_param_array(bsize, ulong, &bsize_count, S_IRUGO);
+static int cached = 1;
+module_param(cached, int, S_IRUGO);
+
+#ifdef CFG_USE_FPGA
+static unsigned long cfg_bsize = 0;
+module_param(cfg_bsize, ulong, S_IRUGO);
+#endif
+
+static unsigned int cmem_major = 88; // 0:auto
+module_param(cmem_major, uint, S_IRUGO);
+
+static struct class *cmem_class = NULL;
+static struct mem_area_data *cmem_areas[MAX_AREA_NUM];
+
+static int cv_v_to_p(unsigned long vaddr, unsigned long *paddr)
+{
+ struct vm_area_struct *vma;
+ unsigned long start, offset;
+ unsigned long pfn;
+ int ret;
+
+ *paddr = 0;
+
+ vma = find_vma(current->active_mm, vaddr);
+ if (vma == NULL)
+ return -EINVAL;
+
+ start = vaddr & PAGE_MASK;
+ ret = follow_pfn(vma, start, &pfn);
+ if (ret < 0)
+ return ret;
+
+ offset = offset_in_page(vaddr);
+ *paddr = (pfn << PAGE_SHIFT) + offset;
+
+ return 0;
+}
+
+static void do_tl(u64 *src, u64 *dst, unsigned int height, unsigned int step)
+{
+ unsigned int i;
+ int j;
+ unsigned int yaddr;
+ u64 *isrc, *idst, *isrcp, *idstp;
+
+ for (j = 0; j < height ; j += 2) {
+ yaddr = (j & ~0x1f) * step | ((j & 0x1f) << 7);
+ isrc = src + (yaddr >> 3);
+ idst = dst + (j * step >> 3);
+ for (i = 0; i < step >> 3; i += 16) {
+ idstp = idst + i;
+ isrcp = isrc + (i << 5);
+ *idstp++ = *isrcp++;
+ *idstp++ = *isrcp++;
+ *idstp++ = *isrcp++;
+ *idstp++ = *isrcp++;
+
+ *idstp++ = *isrcp++;
+ *idstp++ = *isrcp++;
+ *idstp++ = *isrcp++;
+ *idstp++ = *isrcp++;
+
+ *idstp++ = *isrcp++;
+ *idstp++ = *isrcp++;
+ *idstp++ = *isrcp++;
+ *idstp++ = *isrcp++;
+
+ *idstp++ = *isrcp++;
+ *idstp++ = *isrcp++;
+ *idstp++ = *isrcp++;
+ *idstp++ = *isrcp++;
+
+ idstp = idst + i + (step >> 3);
+ *idstp++ = *isrcp++;
+ *idstp++ = *isrcp++;
+ *idstp++ = *isrcp++;
+ *idstp++ = *isrcp++;
+
+ *idstp++ = *isrcp++;
+ *idstp++ = *isrcp++;
+ *idstp++ = *isrcp++;
+ *idstp++ = *isrcp++;
+
+ *idstp++ = *isrcp++;
+ *idstp++ = *isrcp++;
+ *idstp++ = *isrcp++;
+ *idstp++ = *isrcp++;
+
+ *idstp++ = *isrcp++;
+ *idstp++ = *isrcp++;
+ *idstp++ = *isrcp++;
+ *idstp++ = *isrcp++;
+
+ //idst[i] = isrc[((i >> 4) << 9) + (i & 0xf)];
+ }
+ }
+}
+
+static ssize_t dev_read(struct file *filep, char *buf, size_t len, loff_t *ppos)
+{
+ size_t count;
+ struct mem_access_data *p = filep->private_data;
+
+ if (p->tl) {
+ do_tl( (u64 *)(p->area->virt_ptr + p->offset + p->start_offset),
+ (u64 *)buf, p->height, p->stride );
+ count = len;
+ } else {
+ count = copy_to_user(buf, p->area->virt_ptr + p->offset + p->start_offset, len);
+ }
+
+ return count;
+}
+
+static ssize_t dev_write(struct file *filep, const char *buf, size_t len, loff_t *ppos)
+{
+ size_t count;
+ struct mem_access_data *p = filep->private_data;
+
+ count = copy_from_user(p->area->virt_ptr + p->offset + p->start_offset, buf, len);
+
+ return count;
+}
+
+static long dev_ioctl(struct file *filep, unsigned int cmd, unsigned long arg)
+{
+ struct mem_access_data *p = filep->private_data;
+ struct device *dev = p->area->dev;
+ u32 offset, size, dir;
+
+ switch (cmd) {
+ case PARAM_SET :
+ p->width = ((unsigned int *)arg)[0];
+ p->height = ((unsigned int *)arg)[1];
+ p->stride = ((unsigned int *)arg)[2];
+ p->tl = ((unsigned int *)arg)[3];
+ p->offset = ((unsigned int *)arg)[4];
+ break;
+ case M_ALLOCATE :
+ break;
+ case M_LOCK :
+ if (cached) {
+ offset = ((unsigned int *)arg)[0];
+ size = ((unsigned int *)arg)[1];
+ dir = ((unsigned int *)arg)[2];
+ if (dir == IOCTL_FROM_IMP_TO_CPU)
+ dma_sync_single_for_device(dev, p->area->phys_addr + p->start_offset + offset, size, DMA_FROM_DEVICE);
+ else
+ dma_sync_single_for_device(dev, p->area->phys_addr + p->start_offset + offset, size, DMA_TO_DEVICE);
+ }
+ break;
+ case M_UNLOCK :
+ if (cached) {
+ offset = ((unsigned int *)arg)[0];
+ size = ((unsigned int *)arg)[1];
+ dir = ((unsigned int *)arg)[2];
+ if (dir == IOCTL_FROM_IMP_TO_CPU)
+ dma_sync_single_for_cpu(dev, p->area->phys_addr + p->start_offset + offset, size, DMA_FROM_DEVICE);
+ else
+ dma_sync_single_for_cpu(dev, p->area->phys_addr + p->start_offset + offset, size, DMA_TO_DEVICE);
+ }
+ break;
+ case M_UNALLOCATE :
+ break;
+ case GET_PHYS_ADDR :
+ *((unsigned int *)arg) = p->area->phys_addr;
+ break;
+ case TRY_CONV :
+ cv_v_to_p( ( (unsigned long *)arg )[0], (unsigned long *)arg + 1);
+ break;
+ default:
+ dev_warn(dev, "## unknown ioctl command %d\n", cmd);
+ return -EINVAL;
+ }
+
+ return 0;
+}
+
+static int dev_mmap(struct file *filep, struct vm_area_struct *vma)
+{
+ struct mem_access_data *p = filep->private_data;
+ unsigned long off;
+ unsigned long start;
+
+ if (vma->vm_pgoff > (~0UL >> PAGE_SHIFT))
+ return -EINVAL;
+
+ off = vma->vm_pgoff << PAGE_SHIFT;
+ start = p->area->phys_addr;
+
+ if ((vma->vm_end - vma->vm_start + off) > p->area->size)
+ return -EINVAL;
+
+ off += start;
+ vma->vm_pgoff = off >> PAGE_SHIFT;
+ vma->vm_flags |= VM_DONTEXPAND | VM_DONTDUMP;
+ if (!cached)
+ vma->vm_page_prot = pgprot_noncached(vma->vm_page_prot);
+
+ return remap_pfn_range( vma,
+ vma->vm_start,
+ vma->vm_pgoff,
+ vma->vm_end - vma->vm_start,
+ vma->vm_page_prot ) ;
+}
+
+static int dev_open(struct inode *inode, struct file *filep)
+{
+ struct mem_access_data *mem_access_p;
+ int minor = iminor(inode);
+ struct mem_area_data* area = cmem_areas[minor];
+
+ mem_access_p = kzalloc(sizeof(*mem_access_p), GFP_KERNEL);
+ if (!mem_access_p)
+ return -ENOMEM;
+
+ dev_dbg(area->dev, "Device Open\n");
+ mem_access_p->area = area;
+ filep->private_data = mem_access_p;
+
+ return 0;
+}
+
+static int dev_rls(struct inode *inode, struct file *filep)
+{
+ struct mem_access_data *mem_access_p = filep->private_data;
+ kfree(mem_access_p);
+ return 0;
+}
+
+static struct file_operations fops = {
+ .owner = THIS_MODULE,
+ .read = dev_read,
+ .write = dev_write,
+ .unlocked_ioctl = dev_ioctl,
+ .compat_ioctl = dev_ioctl,
+ .mmap = dev_mmap,
+ .open = dev_open,
+ .release = dev_rls,
+};
+
+static int cmemdrv_create_device(dev_t devt, size_t size)
+{
+ int ret;
+ struct mem_area_data *area;
+ struct device *dev;
+ void *virt_b_ptr;
+ dma_addr_t phy_b_addr;
+
+ dev = device_create(cmem_class, NULL, devt, NULL, "cmem%d", MINOR(devt));
+ if (IS_ERR(dev)) {
+ pr_err("cmem: unable to create device cmem%d\n", MINOR(devt));
+ return PTR_ERR(dev);
+ }
+
+ area = devm_kzalloc(dev, sizeof(*area), GFP_KERNEL);
+ if (!area) {
+ ret = -ENOMEM;
+ goto err;
+ }
+ area->dev = dev;
+
+#ifdef CONFIG_ARM64
+ {
+ struct device_node *np;
+ np = of_find_compatible_node(NULL, NULL, "shared-dma-pool");
+ of_dma_configure(dev, np);
+ }
+#endif
+
+ virt_b_ptr = dmam_alloc_coherent(dev, size + PAGE_SIZE, &phy_b_addr, GFP_KERNEL);
+ if (!virt_b_ptr) {
+ dev_err(dev, "Memory allocation failed.. (size:0x%zx)\n", size);
+ ret = -ENOMEM;
+ goto err;
+ }
+
+ area->virt_ptr = PTR_ALIGN(virt_b_ptr, PAGE_SIZE);
+ area->phys_addr = phy_b_addr + (area->virt_ptr - virt_b_ptr);
+ area->size = size;
+ cmem_areas[MINOR(devt)] = area;
+ dev_notice(dev, "Memory allocated.. 0x%08lx (size:0x%zx)\n", (unsigned long)area->phys_addr, size);
+
+ return 0;
+
+err:
+ device_destroy(cmem_class, devt);
+ return ret;
+}
+
+static int __init cmemdrv_init(void)
+{
+ int i = 0;
+ int ret;
+
+ if (bsize_count == 0)
+ bsize[bsize_count++] = DEFAULT_AREA_SIZE; /* add default area */
+
+#ifdef CFG_USE_FPGA
+ if (cfg_bsize && bsize_count < MAX_AREA_NUM)
+ bsize[bsize_count++] = cfg_bsize; /* for compatibility */
+#endif
+
+ ret = register_chrdev(cmem_major, "CMem", &fops);
+ if (ret < 0) {
+ pr_err("cmem: unable to get major %d\n", cmem_major);
+ return ret;
+ }
+ if (cmem_major == 0)
+ cmem_major = ret;
+
+ cmem_class = class_create(THIS_MODULE, "cmem");
+ if (IS_ERR(cmem_class)) {
+ pr_err("cmem: unable to create class\n");
+ ret = PTR_ERR(cmem_class);
+ goto err1;
+ }
+
+ for (i = 0; i < bsize_count; i++) {
+ ret = cmemdrv_create_device(MKDEV(cmem_major, i), bsize[i]);
+ if (ret < 0)
+ goto err2;
+ }
+
+ return 0;
+
+err2:
+ for (i--; i >= 0; i--)
+ device_destroy(cmem_class, MKDEV(cmem_major, i));
+
+ class_destroy(cmem_class);
+err1:
+ unregister_chrdev(cmem_major, "CMem");
+ return ret;
+}
+
+static void __exit cmemdrv_exit(void)
+{
+ int i;
+ for (i = 0; i < bsize_count; i++)
+ device_destroy(cmem_class, MKDEV(cmem_major, i));
+
+ class_destroy(cmem_class);
+ unregister_chrdev(cmem_major, "CMem");
+}
+
+module_init(cmemdrv_init)
+module_exit(cmemdrv_exit)
+
+MODULE_AUTHOR("RenesasElectronicsCorp.");
+MODULE_DESCRIPTION("Userspace I/O driver for image memory");
+MODULE_LICENSE("GPL v2");
diff --git a/meta-rcar-gen3-adas/recipes-kernel/kernel-module-cmemdrv/kernel-module-cmemdrv_0.1.bb b/meta-rcar-gen3-adas/recipes-kernel/kernel-module-cmemdrv/kernel-module-cmemdrv_0.1.bb
new file mode 100644
index 0000000..c460c6f
--- /dev/null
+++ b/meta-rcar-gen3-adas/recipes-kernel/kernel-module-cmemdrv/kernel-module-cmemdrv_0.1.bb
@@ -0,0 +1,24 @@
+SUMMARY = "Cache Memory Primitive Module"
+LICENSE = "GPLv2 & MIT"
+LIC_FILES_CHKSUM = " \
+ file://GPL-COPYING;md5=b234ee4d69f5fce4486a80fdaf4a4263 \
+ file://MIT-COPYING;md5=fea016ce2bdf2ec10080f69e9381d378 \
+ "
+
+inherit module
+
+PR = "r0"
+PV = "0.1"
+
+SRC_URI = " \
+ file://Makefile \
+ file://cmemdrv.c \
+ file://GPL-COPYING \
+ file://MIT-COPYING \
+ "
+
+S = "${WORKDIR}"
+
+KERNEL_MODULE_AUTOLOAD += "cmemdrv"
+KERNEL_MODULE_PROBECONF += "cmemdrv"
+module_conf_cmemdrv = "options cmemdrv bsize=0x7000000"
diff --git a/meta-rcar-gen3-adas/recipes-kernel/kernel-module-gles/kernel-module-gles.bbappend b/meta-rcar-gen3-adas/recipes-kernel/kernel-module-gles/kernel-module-gles.bbappend
new file mode 100644
index 0000000..d3b3e6f
--- /dev/null
+++ b/meta-rcar-gen3-adas/recipes-kernel/kernel-module-gles/kernel-module-gles.bbappend
@@ -0,0 +1,5 @@
+FILESEXTRAPATHS_prepend := "${THISDIR}/${PN}:"
+
+SRC_URI_append_r8a7795 = " \
+ file://clockfreq-fix-out-of-bounds-access.patch \
+"
diff --git a/meta-rcar-gen3-adas/recipes-kernel/kernel-module-gles/kernel-module-gles/clockfreq-fix-out-of-bounds-access.patch b/meta-rcar-gen3-adas/recipes-kernel/kernel-module-gles/kernel-module-gles/clockfreq-fix-out-of-bounds-access.patch
new file mode 100644
index 0000000..5ac3e12
--- /dev/null
+++ b/meta-rcar-gen3-adas/recipes-kernel/kernel-module-gles/kernel-module-gles/clockfreq-fix-out-of-bounds-access.patch
@@ -0,0 +1,23 @@
+diff -pruN '--exclude=*~' '--exclude=binary*' rogue_km/build/linux/r8a7795_linux/Makefile rogue_km.new/build/linux/r8a7795_linux/Makefile
+--- rogue_km/build/linux/r8a7795_linux/Makefile 2016-08-03 23:17:38.000000000 -0700
++++ rogue_km.new/build/linux/r8a7795_linux/Makefile 2016-11-01 07:02:27.887988779 -0700
+@@ -91,6 +91,7 @@ endif
+ SYSROOT := $(SDKTARGETSYSROOT)
+
+ SUPPORT_WRAPEXTMEM ?= 1
++SUPPORT_PVRTL := 1
+
+ SUPPORT_EXTENSION_REL ?= 1
+ ifeq ($(SUPPORT_EXTENSION_REL),1)
+diff -pruN '--exclude=*~' '--exclude=binary*' rogue_km/services/server/devices/rgx/rgxdevice.h rogue_km.new/services/server/devices/rgx/rgxdevice.h
+--- rogue_km/services/server/devices/rgx/rgxdevice.h 2016-08-03 23:14:20.000000000 -0700
++++ rogue_km.new/services/server/devices/rgx/rgxdevice.h 2016-11-22 02:23:56.136282383 -0800
+@@ -81,7 +81,7 @@ typedef struct {
+ *****************************************************************************/
+
+ #define RGX_GPU_DVFS_TABLE_SIZE 100 /* DVFS Table size */
+-#define RGX_GPU_DVFS_GET_INDEX(clockfreq) ((clockfreq) / 10000000) /* Assuming different GPU clocks are separated by at least 10MHz
++#define RGX_GPU_DVFS_GET_INDEX(clockfreq) (((clockfreq) / 10000000) % RGX_GPU_DVFS_TABLE_SIZE) /* Assuming different GPU clocks are separated by at least 10MHz
+ * WARNING: this macro must be used only with nominal values of
+ * the GPU clock speed (the ones provided by the customer code) */
+ #define RGX_GPU_DVFS_FIRST_CALIBRATION_TIME_US 25000 /* Time required to calibrate a clock frequency the first time */
diff --git a/meta-rcar-gen3-adas/recipes-kernel/kernel-module-mmngr/files/0001-free-dma-buf-on-error.patch b/meta-rcar-gen3-adas/recipes-kernel/kernel-module-mmngr/files/0001-free-dma-buf-on-error.patch
new file mode 100644
index 0000000..e41f141
--- /dev/null
+++ b/meta-rcar-gen3-adas/recipes-kernel/kernel-module-mmngr/files/0001-free-dma-buf-on-error.patch
@@ -0,0 +1,23 @@
+From 9362c86c52dcd1577e07f01604e1a7b363c504ca Mon Sep 17 00:00:00 2001
+From: Roman Meshkevich <roman.meshkevich@cogentembedded.com>
+Date: Wed, 22 Feb 2017 01:27:51 +0300
+Subject: [PATCH] unref dma_fb descriptor
+
+---
+ mmngr_drv/mmngrbuf/mmngrbuf-module/files/mmngrbuf/drv/mmngr_buf_drv.c | 1 +
+ 1 file changed, 1 insertion(+)
+
+diff --git a/mmngr_drv/mmngrbuf/mmngrbuf-module/files/mmngrbuf/drv/mmngr_buf_drv.c b/mmngr_drv/mmngrbuf/mmngrbuf-module/files/mmngrbuf/drv/mmngr_buf_drv.c
+index 2e260cb..6a4d0a6 100644
+--- a/mmngr_drv/mmngrbuf/mmngrbuf-module/files/mmngrbuf/drv/mmngr_buf_drv.c
++++ b/mmngr_drv/mmngrbuf/mmngrbuf-module/files/mmngrbuf/drv/mmngr_buf_drv.c
+@@ -99,6 +99,7 @@ static int close(struct inode *inode, struct file *file)
+ if (priv->attach) {
+ pr_err("detach@close\n");
+ dma_buf_detach(priv->dma_buf, priv->attach);
++ dma_buf_put(priv->dma_buf);
+ }
+
+ kfree(priv);
+--
+2.7.4 \ No newline at end of file
diff --git a/meta-rcar-gen3-adas/recipes-kernel/kernel-module-mmngr/files/0002-mmngr-Add-V3MSK-board.patch b/meta-rcar-gen3-adas/recipes-kernel/kernel-module-mmngr/files/0002-mmngr-Add-V3MSK-board.patch
new file mode 100644
index 0000000..cfb5297
--- /dev/null
+++ b/meta-rcar-gen3-adas/recipes-kernel/kernel-module-mmngr/files/0002-mmngr-Add-V3MSK-board.patch
@@ -0,0 +1,31 @@
+From 5b50bdd074c162d927bfd3711546928ac93d4a13 Mon Sep 17 00:00:00 2001
+From: Vladimir Barinov <vladimir.barinov@cogentembedded.com>
+Date: Wed, 15 Nov 2017 00:03:43 +0300
+Subject: [PATCH] mmngr: Add V3MSK board
+
+This adds V3MSK board support
+
+Signed-off-by: Konstantin Kozhevnikov <Konstantin.Kozhevnikov@cogentembedded.com>
+Signed-off-by: Vladimir Barinov <vladimir.barinov@cogentembedded.com>
+---
+ mmngr_drv/mmngr/mmngr-module/files/mmngr/include/mmngr_private.h | 5 ++
+ 1 file changed, 5 insertions(+), 0 deletions(-)
+
+diff --git a/mmngr_drv/mmngr/mmngr-module/files/mmngr/include/mmngr_private.h b/mmngr_drv/mmngr/mmngr-module/files/mmngr/include/mmngr_private.h
+index e593380..8282d42 100644
+--- a/mmngr_drv/mmngr/mmngr-module/files/mmngr/include/mmngr_private.h
++++ b/mmngr_drv/mmngr/mmngr-module/files/mmngr/include/mmngr_private.h
+@@ -211,6 +211,11 @@ static int validate_memory_map(void);
+ #define MM_OMXBUF_SIZE (256 * 1024 * 1024)
+ #endif /* MMNGR_SALVATORX */
+
++#ifdef MMNGR_V3MSK
++#define MM_OMXBUF_ADDR (0x7F000000UL)
++#define MM_OMXBUF_SIZE (16 * 1024 * 1024)
++#endif /* MMNGR_V3MSK */
++
+ #define MM_CO_ORDER (12)
+
+ #ifdef MMNGR_SSP_ENABLE
+--
+1.9.1
diff --git a/meta-rcar-gen3-adas/recipes-kernel/kernel-module-mmngr/kernel-module-mmngr.bbappend b/meta-rcar-gen3-adas/recipes-kernel/kernel-module-mmngr/kernel-module-mmngr.bbappend
new file mode 100644
index 0000000..6abdc7d
--- /dev/null
+++ b/meta-rcar-gen3-adas/recipes-kernel/kernel-module-mmngr/kernel-module-mmngr.bbappend
@@ -0,0 +1,6 @@
+FILESEXTRAPATHS_prepend := "${THISDIR}/files:"
+
+MMNGR_CFG_eagle = "MMNGR_V3MSK"
+MMNGR_CFG_v3msk = "MMNGR_V3MSK"
+
+SRC_URI_append = " file://0002-mmngr-Add-V3MSK-board.patch"
diff --git a/meta-rcar-gen3-adas/recipes-kernel/kernel-module-mmngr/kernel-module-mmngrbuf.bbappend b/meta-rcar-gen3-adas/recipes-kernel/kernel-module-mmngr/kernel-module-mmngrbuf.bbappend
new file mode 100644
index 0000000..5120cb1
--- /dev/null
+++ b/meta-rcar-gen3-adas/recipes-kernel/kernel-module-mmngr/kernel-module-mmngrbuf.bbappend
@@ -0,0 +1,3 @@
+FILESEXTRAPATHS_prepend := "${THISDIR}/files:"
+
+SRC_URI_append = " file://0001-free-dma-buf-on-error.patch"
diff --git a/meta-rcar-gen3-adas/recipes-kernel/kernel-module-uio-imp/files/GPL-COPYING b/meta-rcar-gen3-adas/recipes-kernel/kernel-module-uio-imp/files/GPL-COPYING
new file mode 100644
index 0000000..d159169
--- /dev/null
+++ b/meta-rcar-gen3-adas/recipes-kernel/kernel-module-uio-imp/files/GPL-COPYING
@@ -0,0 +1,339 @@
+ GNU GENERAL PUBLIC LICENSE
+ Version 2, June 1991
+
+ Copyright (C) 1989, 1991 Free Software Foundation, Inc.,
+ 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
+ Everyone is permitted to copy and distribute verbatim copies
+ of this license document, but changing it is not allowed.
+
+ Preamble
+
+ The licenses for most software are designed to take away your
+freedom to share and change it. By contrast, the GNU General Public
+License is intended to guarantee your freedom to share and change free
+software--to make sure the software is free for all its users. This
+General Public License applies to most of the Free Software
+Foundation's software and to any other program whose authors commit to
+using it. (Some other Free Software Foundation software is covered by
+the GNU Lesser General Public License instead.) You can apply it to
+your programs, too.
+
+ When we speak of free software, we are referring to freedom, not
+price. Our General Public Licenses are designed to make sure that you
+have the freedom to distribute copies of free software (and charge for
+this service if you wish), that you receive source code or can get it
+if you want it, that you can change the software or use pieces of it
+in new free programs; and that you know you can do these things.
+
+ To protect your rights, we need to make restrictions that forbid
+anyone to deny you these rights or to ask you to surrender the rights.
+These restrictions translate to certain responsibilities for you if you
+distribute copies of the software, or if you modify it.
+
+ For example, if you distribute copies of such a program, whether
+gratis or for a fee, you must give the recipients all the rights that
+you have. You must make sure that they, too, receive or can get the
+source code. And you must show them these terms so they know their
+rights.
+
+ We protect your rights with two steps: (1) copyright the software, and
+(2) offer you this license which gives you legal permission to copy,
+distribute and/or modify the software.
+
+ Also, for each author's protection and ours, we want to make certain
+that everyone understands that there is no warranty for this free
+software. If the software is modified by someone else and passed on, we
+want its recipients to know that what they have is not the original, so
+that any problems introduced by others will not reflect on the original
+authors' reputations.
+
+ Finally, any free program is threatened constantly by software
+patents. We wish to avoid the danger that redistributors of a free
+program will individually obtain patent licenses, in effect making the
+program proprietary. To prevent this, we have made it clear that any
+patent must be licensed for everyone's free use or not licensed at all.
+
+ The precise terms and conditions for copying, distribution and
+modification follow.
+
+ GNU GENERAL PUBLIC LICENSE
+ TERMS AND CONDITIONS FOR COPYING, DISTRIBUTION AND MODIFICATION
+
+ 0. This License applies to any program or other work which contains
+a notice placed by the copyright holder saying it may be distributed
+under the terms of this General Public License. The "Program", below,
+refers to any such program or work, and a "work based on the Program"
+means either the Program or any derivative work under copyright law:
+that is to say, a work containing the Program or a portion of it,
+either verbatim or with modifications and/or translated into another
+language. (Hereinafter, translation is included without limitation in
+the term "modification".) Each licensee is addressed as "you".
+
+Activities other than copying, distribution and modification are not
+covered by this License; they are outside its scope. The act of
+running the Program is not restricted, and the output from the Program
+is covered only if its contents constitute a work based on the
+Program (independent of having been made by running the Program).
+Whether that is true depends on what the Program does.
+
+ 1. You may copy and distribute verbatim copies of the Program's
+source code as you receive it, in any medium, provided that you
+conspicuously and appropriately publish on each copy an appropriate
+copyright notice and disclaimer of warranty; keep intact all the
+notices that refer to this License and to the absence of any warranty;
+and give any other recipients of the Program a copy of this License
+along with the Program.
+
+You may charge a fee for the physical act of transferring a copy, and
+you may at your option offer warranty protection in exchange for a fee.
+
+ 2. You may modify your copy or copies of the Program or any portion
+of it, thus forming a work based on the Program, and copy and
+distribute such modifications or work under the terms of Section 1
+above, provided that you also meet all of these conditions:
+
+ a) You must cause the modified files to carry prominent notices
+ stating that you changed the files and the date of any change.
+
+ b) You must cause any work that you distribute or publish, that in
+ whole or in part contains or is derived from the Program or any
+ part thereof, to be licensed as a whole at no charge to all third
+ parties under the terms of this License.
+
+ c) If the modified program normally reads commands interactively
+ when run, you must cause it, when started running for such
+ interactive use in the most ordinary way, to print or display an
+ announcement including an appropriate copyright notice and a
+ notice that there is no warranty (or else, saying that you provide
+ a warranty) and that users may redistribute the program under
+ these conditions, and telling the user how to view a copy of this
+ License. (Exception: if the Program itself is interactive but
+ does not normally print such an announcement, your work based on
+ the Program is not required to print an announcement.)
+
+These requirements apply to the modified work as a whole. If
+identifiable sections of that work are not derived from the Program,
+and can be reasonably considered independent and separate works in
+themselves, then this License, and its terms, do not apply to those
+sections when you distribute them as separate works. But when you
+distribute the same sections as part of a whole which is a work based
+on the Program, the distribution of the whole must be on the terms of
+this License, whose permissions for other licensees extend to the
+entire whole, and thus to each and every part regardless of who wrote it.
+
+Thus, it is not the intent of this section to claim rights or contest
+your rights to work written entirely by you; rather, the intent is to
+exercise the right to control the distribution of derivative or
+collective works based on the Program.
+
+In addition, mere aggregation of another work not based on the Program
+with the Program (or with a work based on the Program) on a volume of
+a storage or distribution medium does not bring the other work under
+the scope of this License.
+
+ 3. You may copy and distribute the Program (or a work based on it,
+under Section 2) in object code or executable form under the terms of
+Sections 1 and 2 above provided that you also do one of the following:
+
+ a) Accompany it with the complete corresponding machine-readable
+ source code, which must be distributed under the terms of Sections
+ 1 and 2 above on a medium customarily used for software interchange; or,
+
+ b) Accompany it with a written offer, valid for at least three
+ years, to give any third party, for a charge no more than your
+ cost of physically performing source distribution, a complete
+ machine-readable copy of the corresponding source code, to be
+ distributed under the terms of Sections 1 and 2 above on a medium
+ customarily used for software interchange; or,
+
+ c) Accompany it with the information you received as to the offer
+ to distribute corresponding source code. (This alternative is
+ allowed only for noncommercial distribution and only if you
+ received the program in object code or executable form with such
+ an offer, in accord with Subsection b above.)
+
+The source code for a work means the preferred form of the work for
+making modifications to it. For an executable work, complete source
+code means all the source code for all modules it contains, plus any
+associated interface definition files, plus the scripts used to
+control compilation and installation of the executable. However, as a
+special exception, the source code distributed need not include
+anything that is normally distributed (in either source or binary
+form) with the major components (compiler, kernel, and so on) of the
+operating system on which the executable runs, unless that component
+itself accompanies the executable.
+
+If distribution of executable or object code is made by offering
+access to copy from a designated place, then offering equivalent
+access to copy the source code from the same place counts as
+distribution of the source code, even though third parties are not
+compelled to copy the source along with the object code.
+
+ 4. You may not copy, modify, sublicense, or distribute the Program
+except as expressly provided under this License. Any attempt
+otherwise to copy, modify, sublicense or distribute the Program is
+void, and will automatically terminate your rights under this License.
+However, parties who have received copies, or rights, from you under
+this License will not have their licenses terminated so long as such
+parties remain in full compliance.
+
+ 5. You are not required to accept this License, since you have not
+signed it. However, nothing else grants you permission to modify or
+distribute the Program or its derivative works. These actions are
+prohibited by law if you do not accept this License. Therefore, by
+modifying or distributing the Program (or any work based on the
+Program), you indicate your acceptance of this License to do so, and
+all its terms and conditions for copying, distributing or modifying
+the Program or works based on it.
+
+ 6. Each time you redistribute the Program (or any work based on the
+Program), the recipient automatically receives a license from the
+original licensor to copy, distribute or modify the Program subject to
+these terms and conditions. You may not impose any further
+restrictions on the recipients' exercise of the rights granted herein.
+You are not responsible for enforcing compliance by third parties to
+this License.
+
+ 7. If, as a consequence of a court judgment or allegation of patent
+infringement or for any other reason (not limited to patent issues),
+conditions are imposed on you (whether by court order, agreement or
+otherwise) that contradict the conditions of this License, they do not
+excuse you from the conditions of this License. If you cannot
+distribute so as to satisfy simultaneously your obligations under this
+License and any other pertinent obligations, then as a consequence you
+may not distribute the Program at all. For example, if a patent
+license would not permit royalty-free redistribution of the Program by
+all those who receive copies directly or indirectly through you, then
+the only way you could satisfy both it and this License would be to
+refrain entirely from distribution of the Program.
+
+If any portion of this section is held invalid or unenforceable under
+any particular circumstance, the balance of the section is intended to
+apply and the section as a whole is intended to apply in other
+circumstances.
+
+It is not the purpose of this section to induce you to infringe any
+patents or other property right claims or to contest validity of any
+such claims; this section has the sole purpose of protecting the
+integrity of the free software distribution system, which is
+implemented by public license practices. Many people have made
+generous contributions to the wide range of software distributed
+through that system in reliance on consistent application of that
+system; it is up to the author/donor to decide if he or she is willing
+to distribute software through any other system and a licensee cannot
+impose that choice.
+
+This section is intended to make thoroughly clear what is believed to
+be a consequence of the rest of this License.
+
+ 8. If the distribution and/or use of the Program is restricted in
+certain countries either by patents or by copyrighted interfaces, the
+original copyright holder who places the Program under this License
+may add an explicit geographical distribution limitation excluding
+those countries, so that distribution is permitted only in or among
+countries not thus excluded. In such case, this License incorporates
+the limitation as if written in the body of this License.
+
+ 9. The Free Software Foundation may publish revised and/or new versions
+of the General Public License from time to time. Such new versions will
+be similar in spirit to the present version, but may differ in detail to
+address new problems or concerns.
+
+Each version is given a distinguishing version number. If the Program
+specifies a version number of this License which applies to it and "any
+later version", you have the option of following the terms and conditions
+either of that version or of any later version published by the Free
+Software Foundation. If the Program does not specify a version number of
+this License, you may choose any version ever published by the Free Software
+Foundation.
+
+ 10. If you wish to incorporate parts of the Program into other free
+programs whose distribution conditions are different, write to the author
+to ask for permission. For software which is copyrighted by the Free
+Software Foundation, write to the Free Software Foundation; we sometimes
+make exceptions for this. Our decision will be guided by the two goals
+of preserving the free status of all derivatives of our free software and
+of promoting the sharing and reuse of software generally.
+
+ NO WARRANTY
+
+ 11. BECAUSE THE PROGRAM IS LICENSED FREE OF CHARGE, THERE IS NO WARRANTY
+FOR THE PROGRAM, TO THE EXTENT PERMITTED BY APPLICABLE LAW. EXCEPT WHEN
+OTHERWISE STATED IN WRITING THE COPYRIGHT HOLDERS AND/OR OTHER PARTIES
+PROVIDE THE PROGRAM "AS IS" WITHOUT WARRANTY OF ANY KIND, EITHER EXPRESSED
+OR IMPLIED, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
+MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE. THE ENTIRE RISK AS
+TO THE QUALITY AND PERFORMANCE OF THE PROGRAM IS WITH YOU. SHOULD THE
+PROGRAM PROVE DEFECTIVE, YOU ASSUME THE COST OF ALL NECESSARY SERVICING,
+REPAIR OR CORRECTION.
+
+ 12. IN NO EVENT UNLESS REQUIRED BY APPLICABLE LAW OR AGREED TO IN WRITING
+WILL ANY COPYRIGHT HOLDER, OR ANY OTHER PARTY WHO MAY MODIFY AND/OR
+REDISTRIBUTE THE PROGRAM AS PERMITTED ABOVE, BE LIABLE TO YOU FOR DAMAGES,
+INCLUDING ANY GENERAL, SPECIAL, INCIDENTAL OR CONSEQUENTIAL DAMAGES ARISING
+OUT OF THE USE OR INABILITY TO USE THE PROGRAM (INCLUDING BUT NOT LIMITED
+TO LOSS OF DATA OR DATA BEING RENDERED INACCURATE OR LOSSES SUSTAINED BY
+YOU OR THIRD PARTIES OR A FAILURE OF THE PROGRAM TO OPERATE WITH ANY OTHER
+PROGRAMS), EVEN IF SUCH HOLDER OR OTHER PARTY HAS BEEN ADVISED OF THE
+POSSIBILITY OF SUCH DAMAGES.
+
+ END OF TERMS AND CONDITIONS
+
+ How to Apply These Terms to Your New Programs
+
+ If you develop a new program, and you want it to be of the greatest
+possible use to the public, the best way to achieve this is to make it
+free software which everyone can redistribute and change under these terms.
+
+ To do so, attach the following notices to the program. It is safest
+to attach them to the start of each source file to most effectively
+convey the exclusion of warranty; and each file should have at least
+the "copyright" line and a pointer to where the full notice is found.
+
+ <one line to give the program's name and a brief idea of what it does.>
+ Copyright (C) <year> <name of author>
+
+ 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.
+
+ 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 Street, Fifth Floor, Boston, MA 02110-1301 USA.
+
+Also add information on how to contact you by electronic and paper mail.
+
+If the program is interactive, make it output a short notice like this
+when it starts in an interactive mode:
+
+ Gnomovision version 69, Copyright (C) year name of author
+ Gnomovision comes with ABSOLUTELY NO WARRANTY; for details type `show w'.
+ This is free software, and you are welcome to redistribute it
+ under certain conditions; type `show c' for details.
+
+The hypothetical commands `show w' and `show c' should show the appropriate
+parts of the General Public License. Of course, the commands you use may
+be called something other than `show w' and `show c'; they could even be
+mouse-clicks or menu items--whatever suits your program.
+
+You should also get your employer (if you work as a programmer) or your
+school, if any, to sign a "copyright disclaimer" for the program, if
+necessary. Here is a sample; alter the names:
+
+ Yoyodyne, Inc., hereby disclaims all copyright interest in the program
+ `Gnomovision' (which makes passes at compilers) written by James Hacker.
+
+ <signature of Ty Coon>, 1 April 1989
+ Ty Coon, President of Vice
+
+This General Public License does not permit incorporating your program into
+proprietary programs. If your program is a subroutine library, you may
+consider it more useful to permit linking proprietary applications with the
+library. If this is what you want to do, use the GNU Lesser General
+Public License instead of this License.
diff --git a/meta-rcar-gen3-adas/recipes-kernel/kernel-module-uio-imp/files/MIT-COPYING b/meta-rcar-gen3-adas/recipes-kernel/kernel-module-uio-imp/files/MIT-COPYING
new file mode 100644
index 0000000..28e2a15
--- /dev/null
+++ b/meta-rcar-gen3-adas/recipes-kernel/kernel-module-uio-imp/files/MIT-COPYING
@@ -0,0 +1,41 @@
+
+This software is Copyright (C) 2013 Renesas Electronics Corporation
+
+You may use, distribute and copy this software under the terms of the MIT
+license displayed 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.
+
+-----------------------------------------------------------------------------
+
+ 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.
+
+-----------------------------------------------------------------------------
diff --git a/meta-rcar-gen3-adas/recipes-kernel/kernel-module-uio-imp/files/Makefile b/meta-rcar-gen3-adas/recipes-kernel/kernel-module-uio-imp/files/Makefile
new file mode 100644
index 0000000..9d35e2a
--- /dev/null
+++ b/meta-rcar-gen3-adas/recipes-kernel/kernel-module-uio-imp/files/Makefile
@@ -0,0 +1,14 @@
+obj-m := uio_imp.o
+
+SRC := $(shell pwd)
+
+all:
+ $(MAKE) -C $(KERNEL_SRC) M=$(SRC)
+
+modules_install:
+ $(MAKE) -C $(KERNEL_SRC) M=$(SRC) modules_install
+
+clean:
+ rm -f *.o *~ core .depend .*.cmd *.ko *.mod.c
+ rm -f Module.markers Module.symvers modules.order
+ rm -rf .tmp_versions Modules.symvers
diff --git a/meta-rcar-gen3-adas/recipes-kernel/kernel-module-uio-imp/files/uio_imp.c b/meta-rcar-gen3-adas/recipes-kernel/kernel-module-uio-imp/files/uio_imp.c
new file mode 100644
index 0000000..ca90d2c
--- /dev/null
+++ b/meta-rcar-gen3-adas/recipes-kernel/kernel-module-uio-imp/files/uio_imp.c
@@ -0,0 +1,559 @@
+/*************************************************************************/ /*
+ IMP Driver (kernel module)
+
+ 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
+*/ /*************************************************************************/
+
+#include <linux/platform_device.h>
+#include <linux/uio_driver.h>
+#include <linux/module.h>
+#include <linux/interrupt.h>
+#include <linux/pm_runtime.h>
+#include <linux/slab.h>
+#include <linux/io.h>
+#include <linux/dma-mapping.h>
+#include <linux/irq.h>
+#include <linux/irqdomain.h>
+
+#include <linux/of.h>
+#include <linux/of_platform.h>
+#include <linux/of_address.h>
+#include <linux/of_irq.h>
+
+#define DRIVER_NAME "uio_imp"
+#define DRIVER_VER "0.0"
+
+#define LUIO_DEVICE_IMP 0
+#define LUIO_DEVICE_IMPSC 1
+#define LUIO_DEVICE_IMPDES 2
+#define LUIO_DEVICE_IMRLSX 3
+#define LUIO_DEVICE_IMRX 4
+#define LUIO_DEVICE_MEM 5
+#define LUIO_DEVICE_VSP 6
+#define LUIO_DEVICE_IMPDMAC 7
+
+#define IMP_INTERNAL_REG_SIZE 0x1000
+#define IMP_NUM_DIST_HWIRQ 32
+
+static int bsize = 7 * 1024 * 1024;
+module_param(bsize, uint, S_IRUGO);
+
+static bool clear_int = 0;
+module_param(clear_int, bool, S_IRUGO);
+
+struct imp_dev_data {
+ int dtype;
+ irqreturn_t (*handler)(int irq, struct uio_info *dev_info);
+ void (*sreset)(struct uio_info *info);
+ const char *name;
+};
+
+struct uio_imp_platdata {
+ struct uio_info *uioinfo;
+ struct platform_device *pdev;
+ const struct imp_dev_data *dev_data;
+
+ struct irq_chip irq_chip;
+ struct irq_domain *irq_domain;
+ unsigned int domain_irq[IMP_NUM_DIST_HWIRQ];
+ int max_hwirq;
+};
+
+static unsigned int ReadReg(struct uio_info *info,
+ unsigned long reg_offs)
+{
+ return ioread32(info->mem[0].internal_addr + reg_offs);
+}
+
+static void WriteReg(struct uio_info *info,
+ unsigned long reg_offs, u32 data)
+{
+ iowrite32(data, info->mem[0].internal_addr + reg_offs);
+}
+
+static irqreturn_t imp_handler(int irq, struct uio_info *dev_info)
+{
+ u32 stat = ReadReg(dev_info, 0x10);
+
+ if (clear_int && (stat & 0x00000020)) {
+ /* clear INT state */
+ WriteReg(dev_info, 0x10, 0x00000020);
+ return IRQ_NONE;
+ }
+
+ if (stat != 0) {
+ /* mask all interrupts */
+ WriteReg(dev_info, 0x14, ReadReg(dev_info, 0x14) & 0x0fffffff);
+
+ return IRQ_HANDLED;
+ } else {
+ return IRQ_NONE;
+ }
+}
+
+static void imp_sreset(struct uio_info *info)
+{
+ /* software reset */
+ WriteReg(info, 0x08, 0x80000000);
+ WriteReg(info, 0x08, 0x00000000);
+ ReadReg(info, 0x08);
+
+ /* 32bit addressing mode */
+ WriteReg(info, 0x08, 0x00000001);
+
+ /* mask all interrupts */
+ WriteReg(info, 0x14, 0);
+}
+
+static irqreturn_t impsc_handler(int irq, struct uio_info *dev_info)
+{
+ u32 stat = ReadReg(dev_info, 0x14);
+
+ if (clear_int && (stat & 0x00000004)) {
+ /* clear INT state */
+ WriteReg(dev_info, 0x18, 0x00000004);
+ return IRQ_NONE;
+ }
+
+ if (stat != 0) {
+ /* mask all interrupts */
+ WriteReg(dev_info, 0x20, 0xffffffff);
+
+ return IRQ_HANDLED;
+ } else {
+ return IRQ_NONE;
+ }
+}
+
+static void impsc_sreset(struct uio_info *info)
+{
+ /* software reset */
+ WriteReg(info, 0x08, 0x00000001);
+ WriteReg(info, 0x08, 0x00000000);
+ ReadReg(info, 0x08);
+
+ /* mask all interrupts */
+ WriteReg(info, 0x20, 0xffffffff);
+}
+
+static irqreturn_t impdist_handler(int irq, struct uio_info *dev_info)
+{
+ unsigned int bit;
+ unsigned long stat;
+ struct uio_imp_platdata *priv = dev_info->priv;
+
+ stat = ReadReg(dev_info, 0x100); /* sr */
+ stat &= ~ReadReg(dev_info, 0x10c); /* imr */
+
+ if (stat & 0x100)
+ stat |= ReadReg(dev_info, 0x110); /* g0intsel */
+ if (stat & 0x200)
+ stat |= ReadReg(dev_info, 0x114); /* g1intsel */
+ if (stat & 0x400)
+ stat |= ReadReg(dev_info, 0x118); /* g2intsel */
+ stat &= ~0x700;
+
+ if (!stat)
+ return IRQ_NONE;
+
+ for_each_set_bit(bit, &stat, IMP_NUM_DIST_HWIRQ)
+ generic_handle_irq(priv->domain_irq[bit]);
+
+ return IRQ_HANDLED;
+}
+
+static void impdist_irq_enable(struct irq_data *d)
+{
+ struct uio_imp_platdata *priv = irq_data_get_irq_chip_data(d);
+ int hw_irq = irqd_to_hwirq(d);
+ unsigned int d_var;
+
+ d_var = ReadReg(priv->uioinfo, 0x10c) & ~BIT(hw_irq);
+ WriteReg(priv->uioinfo, 0x10c, d_var);
+}
+
+static void impdist_irq_disable(struct irq_data *d)
+{
+ struct uio_imp_platdata *priv = irq_data_get_irq_chip_data(d);
+ int hw_irq = irqd_to_hwirq(d);
+ unsigned int d_var;
+
+ d_var = ReadReg(priv->uioinfo, 0x10c) | BIT(hw_irq);
+ WriteReg(priv->uioinfo, 0x10c, d_var);
+}
+
+static int impdist_irq_domain_map(struct irq_domain *h, unsigned int virq,
+ irq_hw_number_t hw)
+{
+ struct uio_imp_platdata *priv = h->host_data;
+
+ dev_dbg(&priv->pdev->dev, "impdist_irq_domain_map: virq=%d, hw=%d\n", virq, (int)hw);
+ priv->domain_irq[hw] = virq;
+ irq_set_chip_data(virq, priv);
+ irq_set_chip_and_handler(virq, &priv->irq_chip, handle_simple_irq);
+ return 0;
+}
+
+static struct irq_domain_ops impdist_irq_domain_ops = {
+ .map = impdist_irq_domain_map,
+};
+
+static void impdist_sreset(struct uio_info *info)
+{
+ WriteReg(info, 0x500, 0);
+}
+
+static irqreturn_t impdmac_handler(int irq, struct uio_info *dev_info)
+{
+ u32 stat = ReadReg(dev_info, 0x08);
+
+ if (clear_int && (stat & 0x00000040)) {
+ /* clear INT state */
+ WriteReg(dev_info, 0x0c, 0x00000040);
+ return IRQ_NONE;
+ }
+
+ if (stat != 0) {
+ /* mask all interrupts */
+ WriteReg(dev_info, 0x14, 0xffffffff);
+
+ return IRQ_HANDLED;
+ } else {
+ return IRQ_NONE;
+ }
+}
+
+static void impdmac_sreset(struct uio_info *info)
+{
+ /* software reset */
+ WriteReg(info, 0x04, 0x80000000);
+ WriteReg(info, 0x04, 0x00000000);
+ ReadReg(info, 0x04);
+
+ /* mask all interrupts */
+ WriteReg(info, 0x14, 0xffffffff);
+}
+
+static const struct imp_dev_data imp_dev_data_legacy = {
+ .dtype = LUIO_DEVICE_IMP,
+ .handler = imp_handler,
+ .sreset = imp_sreset,
+};
+static const struct imp_dev_data imp_dev_data_shader = {
+ .dtype = LUIO_DEVICE_IMPSC,
+ .handler = impsc_handler,
+ .sreset = impsc_sreset,
+};
+static const struct imp_dev_data imp_dev_data_distributer = {
+ .dtype = LUIO_DEVICE_IMPDES,
+ .handler = impdist_handler,
+ .sreset = impdist_sreset,
+};
+static const struct imp_dev_data imp_dev_data_memory = {
+ .dtype = LUIO_DEVICE_MEM,
+};
+static const struct imp_dev_data imp_dev_data_dmac = {
+ .dtype = LUIO_DEVICE_IMPDMAC,
+ .handler = impdmac_handler,
+ .sreset = impdmac_sreset,
+};
+
+static const struct of_device_id of_imp_match[] = {
+ { .compatible = "renesas,impx4-legacy", .data = &imp_dev_data_legacy },
+ { .compatible = "renesas,impx4-shader", .data = &imp_dev_data_shader },
+ { .compatible = "renesas,impx4-distributer", .data = &imp_dev_data_distributer },
+ { .compatible = "renesas,impx4-memory", .data = &imp_dev_data_memory },
+ { .compatible = "renesas,impx5-dmac", .data = &imp_dev_data_dmac },
+ { /* Terminator */ },
+};
+MODULE_DEVICE_TABLE(of, of_imp_match);
+
+static int uio_imp_open(struct uio_info *info, struct inode *inode)
+{
+ struct uio_imp_platdata *priv = info->priv;
+
+ /* software reset */
+ if (priv->dev_data->sreset)
+ priv->dev_data->sreset(info);
+
+ return 0;
+}
+
+static int uio_imp_release(struct uio_info *info, struct inode *inode)
+{
+ return 0;
+}
+
+static int uio_imp_probe(struct platform_device *pdev)
+{
+ struct uio_info *uioinfo;
+ struct uio_imp_platdata *priv;
+ const struct imp_dev_data *dev_data;
+ struct resource *res;
+ struct uio_mem *uiomem;
+ int ret = -EINVAL;
+
+ /* alloc uioinfo for one device */
+ uioinfo = devm_kzalloc(&pdev->dev, sizeof(*uioinfo),
+ GFP_KERNEL);
+ if (!uioinfo) {
+ dev_err(&pdev->dev, "unable to kmalloc\n");
+ return -ENOMEM;
+ }
+
+ if (pdev->dev.of_node) {
+ const struct of_device_id *match;
+ match = of_match_node(of_imp_match, pdev->dev.of_node);
+ if (!match)
+ return ret;
+
+ dev_data = match->data;
+ uioinfo->name = pdev->dev.of_node->name;
+ uioinfo->version = DRIVER_VER;
+ } else {
+ dev_data = pdev->dev.platform_data;
+ uioinfo->name = dev_data->name;
+ uioinfo->version = DRIVER_VER;
+ }
+
+ if (!dev_data) {
+ dev_err(&pdev->dev, "missing platform_data\n");
+ return ret;
+ }
+
+ priv = devm_kzalloc(&pdev->dev, sizeof(*priv), GFP_KERNEL);
+ if (!priv) {
+ dev_err(&pdev->dev, "unable to kmalloc\n");
+ return -ENOMEM;
+ }
+
+ priv->uioinfo = uioinfo;
+ priv->pdev = pdev;
+ priv->dev_data = dev_data;
+
+ /* MEM */
+ uiomem = &uioinfo->mem[0];
+ res = platform_get_resource(pdev, IORESOURCE_MEM, 0);
+
+ if (res) {
+ uiomem->memtype = UIO_MEM_PHYS;
+ uiomem->addr = res->start;
+ uiomem->size = resource_size(res);
+ uiomem->name = res->name;
+
+ /* If reg[1] is shown, use it as internnal addr.
+ Otherwise, use reg[0]. */
+ res = platform_get_resource(pdev, IORESOURCE_MEM, 1);
+ if (res)
+ uiomem->internal_addr = devm_ioremap_nocache(&pdev->dev,
+ res->start, resource_size(res));
+ else
+ uiomem->internal_addr = devm_ioremap_nocache(&pdev->dev,
+ uiomem->addr, IMP_INTERNAL_REG_SIZE);
+
+ if (!uiomem->internal_addr) {
+ dev_err(&pdev->dev, "unable to ioremap\n");
+ return -ENOMEM;
+ }
+ } else if (dev_data->dtype == LUIO_DEVICE_MEM) {
+ /* allocate physically-contiguous memory */
+ int buffer_size = bsize;
+ dev_info(&pdev->dev, "Allocating Buffer size = %d\n", buffer_size);
+ uiomem->memtype = UIO_MEM_PHYS;
+ uiomem->size = buffer_size;
+ uiomem->name = "mem";
+
+ uiomem->internal_addr = dmam_alloc_coherent(&pdev->dev,
+ buffer_size, &uiomem->addr, GFP_KERNEL);
+ if (!uiomem->internal_addr) {
+ dev_err(&pdev->dev, "unable to dma_alloc_coherent\n");
+ return -ENOMEM;
+ }
+ } else {
+ dev_err(&pdev->dev, "missing memory map\n");
+ return -EINVAL;
+ }
+
+ /* IRQ */
+ if (dev_data->handler) {
+ if (pdev->dev.of_node)
+ uioinfo->irq = irq_of_parse_and_map(pdev->dev.of_node, 0);
+ else {
+ ret = platform_get_irq(pdev, 0);
+ if (ret >= 0)
+ uioinfo->irq = ret;
+ else if (ret != -ENXIO) {
+ dev_err(&pdev->dev, "failed to get IRQ\n");
+ return ret;
+ }
+ }
+ if (uioinfo->irq) {
+ uioinfo->handler = dev_data->handler;
+ if (dev_data->dtype != LUIO_DEVICE_IMPDES)
+ uioinfo->irq_flags = IRQF_SHARED;
+ }
+ }
+ dev_dbg(&pdev->dev, "irq = %d\n", (int)uioinfo->irq);
+
+ /* irq demuxing on distributer handler */
+ if (uioinfo->irq && dev_data->dtype == LUIO_DEVICE_IMPDES) {
+ struct irq_chip *irq_chip = &priv->irq_chip;
+ irq_chip->name = uioinfo->name;
+ irq_chip->irq_mask = impdist_irq_disable;
+ irq_chip->irq_unmask = impdist_irq_enable;
+ irq_chip->irq_enable = impdist_irq_enable;
+ irq_chip->irq_disable = impdist_irq_disable;
+ irq_chip->flags = IRQCHIP_SKIP_SET_WAKE;
+
+ priv->irq_domain = irq_domain_add_simple(pdev->dev.of_node,
+ IMP_NUM_DIST_HWIRQ, 0,
+ &impdist_irq_domain_ops, priv);
+ if (!priv->irq_domain) {
+ dev_err(&pdev->dev, "cannot initialize irq domain\n");
+ ret = -ENXIO;
+ goto err1;
+ }
+ }
+
+ pm_runtime_enable(&pdev->dev);
+ pm_runtime_get_sync(&priv->pdev->dev);
+
+#ifdef CFG_USE_FPGA
+ dev_info(&pdev->dev, "%s(0x%08lx)\n",
+ uioinfo->name, (unsigned long)uiomem->addr);
+#else
+ /* software reset */
+ if (dev_data->sreset)
+ dev_data->sreset(uioinfo);
+
+ /* print hardware version */
+ if (uiomem->internal_addr && dev_data->dtype != LUIO_DEVICE_MEM) {
+ unsigned int vcr0 = ReadReg(uioinfo, 0x0);
+ unsigned int vcr1 = ReadReg(uioinfo, 0x4);
+ dev_info(&pdev->dev, "%s(0x%08lx): VCR = 0x%08x, 0x%08x\n",
+ uioinfo->name, (unsigned long)uiomem->addr, vcr0, vcr1);
+ }
+#endif /* CFG_USE_FPGA */
+
+ uioinfo->open = uio_imp_open;
+ uioinfo->release = uio_imp_release;
+ uioinfo->priv = priv;
+
+ ret = uio_register_device(&pdev->dev, priv->uioinfo);
+ if (ret) {
+ dev_err(&pdev->dev, "unable to register uio device\n");
+ goto err2;
+ }
+
+ platform_set_drvdata(pdev, priv);
+ return 0;
+
+err2:
+ pm_runtime_put_sync(&priv->pdev->dev);
+ pm_runtime_disable(&pdev->dev);
+ if (priv->irq_domain)
+ irq_domain_remove(priv->irq_domain);
+
+err1:
+ if (pdev->dev.of_node && uioinfo->irq)
+ irq_dispose_mapping(uioinfo->irq);
+
+ return ret;
+}
+
+static int uio_imp_remove(struct platform_device *pdev)
+{
+ struct uio_imp_platdata *priv = platform_get_drvdata(pdev);
+
+ uio_unregister_device(priv->uioinfo);
+ pm_runtime_put_sync(&priv->pdev->dev);
+ pm_runtime_disable(&pdev->dev);
+
+ if (priv->irq_domain)
+ irq_domain_remove(priv->irq_domain);
+
+ if (pdev->dev.of_node && priv->uioinfo->irq)
+ irq_dispose_mapping(priv->uioinfo->irq);
+
+ return 0;
+}
+
+static int uio_imp_runtime_nop(struct device *dev)
+{
+ return 0;
+}
+
+static const struct dev_pm_ops uio_imp_dev_pm_ops = {
+ .runtime_suspend = uio_imp_runtime_nop,
+ .runtime_resume = uio_imp_runtime_nop,
+};
+
+static struct platform_driver uio_imp = {
+ .probe = uio_imp_probe,
+ .remove = uio_imp_remove,
+ .driver = {
+ .name = DRIVER_NAME,
+ .pm = &uio_imp_dev_pm_ops,
+ .of_match_table = of_match_ptr(of_imp_match),
+ },
+};
+
+module_platform_driver(uio_imp);
+
+MODULE_AUTHOR("RenesasElectronicsCorp.");
+MODULE_DESCRIPTION("Userspace I/O driver for IMP");
+MODULE_LICENSE("GPL v2");
diff --git a/meta-rcar-gen3-adas/recipes-kernel/kernel-module-uio-imp/kernel-module-uio-imp_0.1.bb b/meta-rcar-gen3-adas/recipes-kernel/kernel-module-uio-imp/kernel-module-uio-imp_0.1.bb
new file mode 100644
index 0000000..1000b7d
--- /dev/null
+++ b/meta-rcar-gen3-adas/recipes-kernel/kernel-module-uio-imp/kernel-module-uio-imp_0.1.bb
@@ -0,0 +1,27 @@
+SUMMARY = "IMP Primitive Driver Module"
+LICENSE = "GPLv2 & MIT"
+LIC_FILES_CHKSUM = " \
+ file://GPL-COPYING;md5=b234ee4d69f5fce4486a80fdaf4a4263 \
+ file://MIT-COPYING;md5=fea016ce2bdf2ec10080f69e9381d378 \
+ "
+
+inherit module
+
+PR = "r0"
+PV = "0.1"
+
+SRC_URI = " \
+ file://Makefile \
+ file://uio_imp.c \
+ file://GPL-COPYING \
+ file://MIT-COPYING \
+ "
+
+S = "${WORKDIR}"
+
+KERNEL_MODULE_AUTOLOAD += "uio_imp"
+KERNEL_MODULE_PROBECONF += "uio_imp"
+
+module_conf_uio_imp = ""
+module_conf_uio_imp_r8a7795 = "options uio_imp clear_int"
+module_conf_uio_imp_r8a7796 = "options uio_imp clear_int"
diff --git a/meta-rcar-gen3-adas/recipes-kernel/kernel-module-uvcs/kernel-module-uvcs-drv.bbappend b/meta-rcar-gen3-adas/recipes-kernel/kernel-module-uvcs/kernel-module-uvcs-drv.bbappend
new file mode 100644
index 0000000..f145074
--- /dev/null
+++ b/meta-rcar-gen3-adas/recipes-kernel/kernel-module-uvcs/kernel-module-uvcs-drv.bbappend
@@ -0,0 +1 @@
+KERNEL_MODULE_AUTOLOAD = "uvcs_drv"
diff --git a/meta-rcar-gen3-adas/recipes-kernel/kernel-module-vspmif/kernel-module-vspmif.bbappend b/meta-rcar-gen3-adas/recipes-kernel/kernel-module-vspmif/kernel-module-vspmif.bbappend
new file mode 100644
index 0000000..098e1b0
--- /dev/null
+++ b/meta-rcar-gen3-adas/recipes-kernel/kernel-module-vspmif/kernel-module-vspmif.bbappend
@@ -0,0 +1 @@
+KERNEL_MODULE_AUTOLOAD = "vspm_if"
diff --git a/meta-rcar-gen3-adas/recipes-kernel/linux/linux-renesas/0001-arm64-dts-renesas-preserve-drm-HDMI-connector-naming.patch b/meta-rcar-gen3-adas/recipes-kernel/linux/linux-renesas/0001-arm64-dts-renesas-preserve-drm-HDMI-connector-naming.patch
new file mode 100644
index 0000000..4f87f30
--- /dev/null
+++ b/meta-rcar-gen3-adas/recipes-kernel/linux/linux-renesas/0001-arm64-dts-renesas-preserve-drm-HDMI-connector-naming.patch
@@ -0,0 +1,54 @@
+From df5348a8ec6f611fe3fc51d7c12898b8830d89d3 Mon Sep 17 00:00:00 2001
+From: Matt Porter <mporter@konsulko.com>
+Date: Wed, 13 Dec 2017 12:49:20 -0500
+Subject: [PATCH] arm64: dts: renesas: preserve drm HDMI connector naming on KF
+
+Kingfisher adds encoders on ports 0 and 2 of the R-Car
+display unit. The bare ULCB SK has only an HDMI encoder
+in use on port 1. When the system is booted with an SK
+dtb, port 1's HDMI encoder is assigned as HDMI-A-1 because
+it is the first (and only) encoder present. When booting
+a KF dtb, port 0's HDMI encoder preceeds port1 in the dtb due
+to incremental ordering of the endpoint port nodes. This causes
+the KF HDMI to be assigned HDMI-A-1 and the SK HDMI to be assigned
+as HDMI-A-2. In order to preserve the SK's HDMI output naming as
+connector HDMI-A-1, reorder the endpoint port nodes so that port1
+is first.
+
+Change-Id: Ibbb1975c2383a526a54c257fb7d68d32a042d468
+Signed-off-by: Matt Porter <mporter@konsulko.com>
+---
+ arch/arm64/boot/dts/renesas/r8a7796.dtsi | 10 +++++-----
+ 1 file changed, 5 insertions(+), 5 deletions(-)
+
+diff --git a/arch/arm64/boot/dts/renesas/r8a7796.dtsi b/arch/arm64/boot/dts/renesas/r8a7796.dtsi
+index bf37b8aa0e2f..e3a5c25bc3da 100644
+--- a/arch/arm64/boot/dts/renesas/r8a7796.dtsi
++++ b/arch/arm64/boot/dts/renesas/r8a7796.dtsi
+@@ -2391,11 +2391,6 @@
+ #address-cells = <1>;
+ #size-cells = <0>;
+
+- port@0 {
+- reg = <0>;
+- du_out_rgb: endpoint {
+- };
+- };
+ port@1 {
+ reg = <1>;
+ du_out_hdmi0: endpoint {
+@@ -2406,6 +2401,11 @@
+ du_out_lvds0: endpoint {
+ };
+ };
++ port@0 {
++ reg = <0>;
++ du_out_rgb: endpoint {
++ };
++ };
+ };
+ };
+
+--
+2.11.0
+
diff --git a/meta-rcar-gen3-adas/recipes-kernel/linux/linux-renesas/0001-spi-sh-msiof-fixes.patch b/meta-rcar-gen3-adas/recipes-kernel/linux/linux-renesas/0001-spi-sh-msiof-fixes.patch
new file mode 100644
index 0000000..d8806ba
--- /dev/null
+++ b/meta-rcar-gen3-adas/recipes-kernel/linux/linux-renesas/0001-spi-sh-msiof-fixes.patch
@@ -0,0 +1,33 @@
+From 32db8cc989d7dfdf0315d286b06234e008e56d7c 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] 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 | 30 ++++++++++++++++++++----------
+ 1 file changed, 20 insertions(+), 10 deletions(-)
+
+diff --git a/drivers/spi/spi-sh-msiof.c b/drivers/spi/spi-sh-msiof.c
+index d096f5a..6817304 100644
+--- a/drivers/spi/spi-sh-msiof.c
++++ b/drivers/spi/spi-sh-msiof.c
+@@ -228,11 +228,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;
+--
+1.9.1
+
diff --git a/meta-rcar-gen3-adas/recipes-kernel/linux/linux-renesas/0002-spi-spidev-add-spi-gpio-into-spidev.patch b/meta-rcar-gen3-adas/recipes-kernel/linux/linux-renesas/0002-spi-spidev-add-spi-gpio-into-spidev.patch
new file mode 100644
index 0000000..2aec664
--- /dev/null
+++ b/meta-rcar-gen3-adas/recipes-kernel/linux/linux-renesas/0002-spi-spidev-add-spi-gpio-into-spidev.patch
@@ -0,0 +1,27 @@
+From 4f85719492ae77bc166f90a046e97bb169396062 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] 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 b016a5a..bcee148 100644
+--- a/drivers/spi/spidev.c
++++ b/drivers/spi/spidev.c
+@@ -697,6 +697,7 @@ static const struct of_device_id spidev_dt_ids[] = {
+ { .compatible = "rohm,dh2228fv" },
+ { .compatible = "lineartechnology,ltc2488" },
+ { .compatible = "renesas,sh-msiof" },
++ { .compatible = "spi-gpio" },
+ {},
+ };
+ MODULE_DEVICE_TABLE(of, spidev_dt_ids);
+--
+1.9.1
+
diff --git a/meta-rcar-gen3-adas/recipes-kernel/linux/linux-renesas/0003-spi-spi-gpio-fix-CPOL-mode.patch b/meta-rcar-gen3-adas/recipes-kernel/linux/linux-renesas/0003-spi-spi-gpio-fix-CPOL-mode.patch
new file mode 100644
index 0000000..e802f68
--- /dev/null
+++ b/meta-rcar-gen3-adas/recipes-kernel/linux/linux-renesas/0003-spi-spi-gpio-fix-CPOL-mode.patch
@@ -0,0 +1,42 @@
+From db37427756bc9e42723f58067a3f387a2861fbbb 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] 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 | 10 +++++-----
+ 1 file changed, 5 insertions(+), 5 deletions(-)
+
+diff --git a/drivers/spi/spi-gpio.c b/drivers/spi/spi-gpio.c
+index 1c34c93..428417d 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;
+--
+1.9.1
+
diff --git a/meta-rcar-gen3-adas/recipes-kernel/linux/linux-renesas/0004-xhci-rcar-add-firmware-for-R-Car-H2-M2-USB-3.0-host-.patch b/meta-rcar-gen3-adas/recipes-kernel/linux/linux-renesas/0004-xhci-rcar-add-firmware-for-R-Car-H2-M2-USB-3.0-host-.patch
new file mode 100644
index 0000000..8487d5f
--- /dev/null
+++ b/meta-rcar-gen3-adas/recipes-kernel/linux/linux-renesas/0004-xhci-rcar-add-firmware-for-R-Car-H2-M2-USB-3.0-host-.patch
@@ -0,0 +1,205 @@
+From 63aa7951b66cc771b23a002748a20a5555cf847f Mon Sep 17 00:00:00 2001
+From: Yoshihiro Shimoda <yoshihiro.shimoda.uh@renesas.com>
+Date: Thu, 10 Jul 2014 10:41:55 +0900
+Subject: [PATCH] xhci-rcar: add firmware for R-Car H2/M2 USB 3.0 host
+ controller
+
+This patch adds a firmware for the USB 3.0 host controller of Renesas
+R-Car H2 and M2 SoCs.
+
+Signed-off-by: Yoshihiro Shimoda <yoshihiro.shimoda.uh@renesas.com>
+Signed-off-by: Kyle McMartin <kyle@kernel.org>
+---
+ firmware/LICENCE.r8a779x_usb3 | 26 ++++++++++++++++++++++++++
+ firmware/WHENCE | 8 ++++++++
+ firmware/r8a779x_usb3_v1.dlmem | Bin 0 -> 9452 bytes
+ 3 files changed, 34 insertions(+)
+ create mode 100644 firmware/LICENCE.r8a779x_usb3
+ create mode 100644 firmware/r8a779x_usb3_v1.dlmem
+
+diff --git a/firmware/LICENCE.r8a779x_usb3 b/firmware/LICENCE.r8a779x_usb3
+new file mode 100644
+index 0000000..e2afcc9
+--- /dev/null
++++ b/firmware/LICENCE.r8a779x_usb3
+@@ -0,0 +1,26 @@
++Copyright (c) 2014, Renesas Electronics Corporation
++All rights reserved.
++
++Redistribution and use in binary form, without modification, are permitted
++provided that the following conditions are met:
++
++1. Redistribution in binary form must reproduce the above copyright notice,
++ this list of conditions and the following disclaimer in the documentation
++ and/or other materials provided with the distribution.
++2. The name of Renesas Electronics Corporation may not be used to endorse or
++ promote products derived from this software without specific prior written
++ permission.
++3. Reverse engineering, decompilation, or disassembly of this software is
++ not permitted.
++
++THIS SOFTWARE IS PROVIDED "AS IS" AND RENESAS ELECTRONICS CORPORATION DISCLAIMS
++ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
++WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE, AND
++NONINFRINGEMENT OF THIRD PARTY RIGHTS. IN NO EVENT SHALL RENESAS ELECTRONICS
++CORPORATION BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY,
++OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
++SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
++INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
++CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
++ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
++POSSIBILITY OF SUCH DAMAGE.
+diff --git a/firmware/WHENCE b/firmware/WHENCE
+index 8388f02..4b45ad1 100644
+--- a/firmware/WHENCE
++++ b/firmware/WHENCE
+@@ -852,3 +852,11 @@ Licence:
+ Found in hex form in kernel source.
+
+ --------------------------------------------------------------------------
++
++Driver: xhci-rcar -- Renesas R-Car H2/M2 USB 3.0 host controller driver
++
++File: r8a779x_usb3_v1.dlmem
++
++Licence: Redistributable. See LICENCE.r8a779x_usb3 for details.
++
++--------------------------------------------------------------------------
+diff --git a/firmware/r8a779x_usb3_v1.dlmem b/firmware/r8a779x_usb3_v1.dlmem
+new file mode 100644
+index 0000000000000000000000000000000000000000..d094157084173b3c741d3d3d214bdd83f2c48d6b
+GIT binary patch
+literal 9452
+zcmai44O~=J+J9z-JD0DEGZ$tq5~HKdn7P^_tEi-cgshqM3Mwd?%7<iTW^K8>tsf%}
+zN@k|M>6%}e4VGlBlDK6#(FA717NCr1io*zgj4mLntf_S0|G5L=zU}*4e!u@c=bn4c
+zbDrlp&w0*so}qZ!Zx2LJEwR7LL>5+Z=2=lWvWjeSA9@gFa?}dyZt<$RTWow5S+!gH
+zsEK=o5*e%=WE-U2aF*zWX@j&8=ZFF%(ftS1eFma=8Fd9NV;iZp9@%HINY<t|#nYVG
+zNV;6qEt0|gu6WR7ZMCjW&=!)KRI$s5Vx96PjVIO1v04*qM>tBmY4G>@1ic8o*w~%o
+z=bTesCzMMOZp$voePRTWQ?8z<N=wwPpjQqL)o$xWl%UNGBU(ZEjQ6*C+bk_anwSLb
+z4N!WKtZNLm0orOdcYK02P^G5DWNPC$6*p#iAZeB*8p)<N2!<eorGq+yxW1ysVEv=X
+z_TUH=^$~L={j3D-Sd3akNtl!AM|;^RhYHIwRK&P&^1*_|XqE<PX@{&?tIy^8Nowsi
+z`E|k4VU|?GHC(><w8$A&K%#z9ioV3e+SSv7buO`7pPev73O1@pW3XgAEO}GE;BtAZ
+z1U-UY3;vWo8ABxh%&V2TJ@`IjR`B$d;z7Z4Ws_i$IB4oL=PzqILnbr6hHBl9_UPu<
+z>zd403o0>LsuAq1HA0rJk#h+-z8axjC^gvR6vFzLZ1RqXn}SU?sw(h|SC?`&d9KDL
+zJ0dDL71mBI*%NAn&Qa~>`fEvFT&y0&TI-EB>lg=YPN%#T>szVxZoyl8v{PPvujMSP
+zab$o^-V@L__AB|zU!3xSd*8~SFTtHJUNJc3ACj;(ZZeqD<?9pmDg%?0*_maR%6(!D
+z3|#u$oh!8kI^{w4#@onmPj}URt8>a>_rB#~UUvYj!lDLGmrb73cFfYE?&dVPYwSpk
+z-xfV<=Bk)vuNqWo$r;sxU%JK^#s}5DDeePDjMo}v4GP5f1j{aRpOBcf1}EEOFV#Ko
+zl%pnCq${WFVog`?jhJ&lAB&`NZ-t$gf2DRadfOovY%(Ahb$|bToT}C@@kXpQo98s=
+zsX2n3ai)*8^<aL2wgG&y9mBru8}6y`4QCozDgJD=OaBP;=#N-cJ}c~8-B3<-22;#x
+z@U^!dD=Z9xl|On(g+0_iKut@r>Xlsin$O%t!Z;tZGIiQY5%Z_{uAFLS*79>;`CFlG
+zPt6(3o@utp2Q-OVIYzNAWsffa6}HEn@=K7e!O(374%k_ic*J0rW;A*9?SfNoPqMZ?
+zZ%fc_!wB%ctC#ykU!r8bMzQAt@d{V|P>I_nZ=$;K*4ED<Wx3MRlj_3UeIkp-U_UiM
+z7XtGl4dK?-uhHkS(udi0(Gd2%Q1Kv>`!mn<x>BE{)YmF?x5X*nQe;-e9+jW^g^gGV
+zihgd-z`p!kmA@MbP6jCZy+_t`&Tkz~IUBMrGBQ~eAJp0#a=nbNnwVu>mXv?5?>eJX
+zK4fIx#oB6O^5YBBmqqgXmqx53<6<TBFsjKeevLi1fhxLma9ru_*TLGz&10;sb&%TA
+zMcvw}UzMP}ru1=0|70tV(Q#~tsqJ{r7W1wC_DYjeUN}D3<CMn^wYD~bMt?2i!`gZs
+z^+%MtQ+_Sh)7TDeCyi%5+9}@{jMctR#_8zSBV!)k*xJLQeeg|OIZr;=sFCg6>4wB~
+z9R=%WKvPjtkMvu+X8pJzLF?$MGwqdhQFh8t-Pik=(xclC_Z2~T77x!I0{@MACue{k
+z?Vu~1foG+gGiVL@;zpq_{5a=kr=b7O+N#1F5xiewc0OE#hgai#7}(X;58sC=b-xAo
+zqoZ=w9ka2Tw{(2g%NAivm*tgH^QW$gFdL)E(h(VWAUq)L;1rEm68>qpD)Z3H(kUxv
+znbVI`{#5hq4XRbM%(HXJKC58r>VP!?=JeZCi1xv%*JrIo89{HLZ<%J@R4#4Xl<iZr
+z**kKA7VLa(*UWdP?4I&oPH^U)ndaF#dVi)m(=oGX=HBoR!aoe(H?w%=N8$U!KMwz7
+z%3o$CY7@FVt~rwJ9Bb>7u!UQS3{Lq-<iA>{80cR)2mC{pxE3cj=iVWHXMpDkRCFbF
+z>xyWc_>8!v)8FGDm(2eIem2Sq8-xulvi7WHE@-mV=iG_uq?xF9VXa3-;k`3oZ0y?A
+z8#^}(JtMX#BiMTO?3?{voZ&1O;7MhErfmTH`a?aVs_u=l@%^xK%ny4~OVID)pl%&l
+zTZbavxS{m(Tkeur|2j4<rdsC5rUfeg@P`<Ux?z~cB9;2omn(hSd@f@Gd9S#JpELF)
+zZ(Jyq57kPC-X0Kl;O%;GhnOW^H`Q`E@b4}|k!h6TH#38n->ftEz36=9tyn9|E<sgW
+zBs_X4h!V8Rl~#6oj-_$FbLk0`oN?G!SCNR5A9m`~7%~m_&%gF)R_$%h+Bym=cm!jY
+z!Sl$Andi~A<xbax*Jtj?tQX%Ak3g#`8?+rWQD19i^-6J@sGjUfD^DGifiHPvo0OVw
+z3emR7H8{JjX5dtvGrZ{ucz*RruQ3$+{mFuIz4!Ou^-7LS&<+Up&&AH}MjEZ9{>8<X
+z4hPM>Y}c>|As-RKMxjKgga6*2REL;g7!~2Ugl<Crw~{J2HGJ{4FndA~b&jg#qDQg!
+z<6(AbAHf%$W8Q;F;b<))MsJfLN1<8-dIKM0PxoVtk~z78(_rMDFo!}ZUqF2EI~HFA
+zp!L<TuC*k4>j&hx^Z}W4YVF_U#wU{~oQ%|)qNy+SCo2u4-_Rp8l!nm=il;G@NRQFu
+zlmeRxNG=)!`pGwkJ7q_5#c-Rvl{VvflA4Fu<Oo$Mo*$|T@bswatTy=<brGHixSNQH
+zPI48n{Q1vr#&h(7W<*N?S{5_)(H6ksKU>JO6YxBf=D_nznpYQ9aE$Mhf<55_=tYqx
+znMo6f)?&ed*1MxNF&U?^R&$&V9Bx9CA(KP;fSwgUG9^(kh0+5QMmju2ionx|*mG^N
+zlOH|a$$tnO2Zp6M`KiEx6fV}uXA3L3D15I_FoA{+G>i%b6Gei8@%K)?4VeA7lV3N%
+z$xoi><Q>4<cwhg77F43UsHnA<<eKqG&~FN6H$lh!=s{@tA$k~k9zwr`rhiAn@pS}^
+zqDP_c6iNWbVU}%AIQds6Ir#xkViw>Uu=gn^Kls0#eBNXyuS<3EDS!tUoaW@?r#Shg
+zQ=PmIh)8$x6Mz!H2c%4Q@`q>e;4DA1TfR3G`FcaXFz}}XL?8k)PtSDnZeY<&Cw~$c
+zJ<G|bKMl?E$z7wfaMtD<a>VOgt&l5vIjk8!_GufBRp3+R1fgdXdamXh7u!eZ11&~-
+zzV>p3&vk{J&*Y_AOM`=7g?Pm=;!_^ClZDOmoU*RiB&q1MxKqp(w+ZL|sU<JB^Ab<0
+z+IsK1-Y+D97%l6Mf5Q&nBdDoCd{<PD{BKg>OxsU8!gp#sHThOg;~Bvu8Q>$PUOgx7
+z62B2$*ZYbpoN`5m?w+QM5UNb?OXJdfQW?z=cZOR!4)H2Z!<GMeYFK%%sbP;M2vp8b
+z4b#ByeL#H7*4Xdkx5pogcgnW|EphwFY)m9g8>n(tY3C}-*r{Q`i6Ij>*z!d#Me#fR
+z6f4TYN!o766*pSj4SC{9lULY`-4G9t-@CIy+$<)EE~AE$r3k42yCGJ^_Cf3%<{$Q|
+z*gg=mD!5=+d{waDPb1QqbC9>RICu;ERETb?;<>6)J$h(FdtScI4T28g-E2vSK0;zE
+zo@SmdDb+j86(>`O?t9UC$z<OSy&(b$V_rBpLl?M~g69ibm3)NbVoS$YED&_%`u@^8
+z`7R?*Sz`N`9MLyCSXUsr@-$QlFR#k<&MBkZXL?Jn>`<le<G$QECg}-1yU*T}Y>DQc
+zoJ`6V{kG2XXNTOQTLSwj7Rs{*OON}KX4G<8Mb{Mub6hwbP3VRFJn*?X!G9xJ-^(8-
+zu@!WXJ$zL-+vzOov&?qzh(B?Q7}c~2<wqkhl3%{SF6jd+a9iw_BS&oK*w|GXm1qwy
+zg6HooSu#u#yDj!-9He%0j++hFvo3XlJ;NX|{(bt}+(+Px@rNC`U<DQ8EVVpy&{vzi
+zEj!dG%UR;5kZF_QS+QMsPOKH47fY}zt#ZDgHvS!7zu{)!Jly`IJp+4Uwmm;sS0R3{
+z&&n?0va^o}{u8Lcwm$7N?)Evn3MYgm<N2#O894DWUc9Pl(@eu^KEO@mIblj=x`x)K
+z+vv?HVKe)q$M>^6RJo`x2{YEuJel@R+FMgX5pQLsUErQgb8*4o!pG&qs=poEi|RN_
+z!a-kE{Em1{j8mQ*z$u!afM|&M&VRSJkIi=S4RhcL=7wNzj}7ehA^*RZojey_HOtAD
+z0Ulsdwv%57__9Mm;V$o|kcInSiI6S2xH@={v|RX{c>=zlz3;o1%kJ_pne&`{WS*0^
+z<%OZoXFN_^9lPIG_{y&=<6qBT#=i+{1U3Wj06T&A^0l5d#Mk4De9j~l<UcSnI>zs1
+zDzU>BEiA=z_d?i{4)hlD_1h`1dK(2D*LrqPG-xyL<+@^up?GtO8CIFBjgEO>WK?4B
+z2{@k?M#nI(<$w26UCU0iMa+Noo)DGDW@GaVd!ZT6`7f~97QKMk5S#RH-_2pnV#eW^
+z7JELM!%xo#pD=haqt{Jq`C>-PvzXBmU-WaHMNAXr;MT#pt_+ko;-|ks>dESu>a?wC
+z!DCglhBm}zW$qc0lj$<$W)=@W15cX;&E|;t!aQ*gB9uT_!{CCOR#t|sE>+65)i+J-
+z{qUMnlYc}BH&0{|y;N8PNtYJh6#ljSwL-?-?n1`hvBK`04~t>$=kVLs0Qgl#r$Ont
+z;q_%1oN`-S%QwpAxG$k;_qyQS$c?Pa$zVB$YLo#ee?Y0lE@VB9qaN5*FGoEXZ5=2>
+zQMRBALwOCQuB*>Q)Dfl^(-A76O2g%En7#tAx@~jopDD}n+&FJmM?%_J>r8D~I^QL;
+z`a*_=F3jP`Cz;jrCjZoUHN&hvt9PYdn8Q=9?kZZd>nrsaGJ+`2<5NbvPCMn8b!@Du
+z?We}M)fc1?ij2vr_ntDVaSQiTM$Zcw0x0+DqI~8wqx_RXS>H{$no$m?ym}wTM#i{m
+zaOYjeW;t{E?&tfs=+EvP+{Zm|z|@jR<0{{w+{&+a8jvGXPcBbg@YPWba%F!#rx{ng
+zndTQ?FPMl3n??UxDFC*>){J?ztoVb|Ttjl=YsPpDx$$S7%n}<puaJXhzR*10DMvdh
+z@LcZLjOW~<W<-F|drQaM->Y=EQ?7k~GoHg7%|oDXM=72k78MM+zgL0PDKB}y8S$U*
+z{Zc%)I12DgE2=Zx-;14paqpMnS@wPbo=J{64(C8o5%MYi6R;oIrLTJ-9|CXwS+8ef
+z3N^6R{T4~zX=nH6zJZ-xCuJKuIdF49j9zK*-?ESaEL$mFxkTi@$&^v4DO$<wR2>Vx
+z?732cJdaJ@O=Cu=Xw-R@;R!IR=}(je4|?uL4V56Pv{@MEWmz83L9WW%xTe{ELdBqG
+zBytx~$Rx^bY;P;MAl&Ma3+l=wl~Hq7CTZ5OV2`KKD@0?y7#fZF{CA<3L1iiCEBRF}
+z>Dy+424vl=r~&XdgS09{YdNTWFTNp8)F-BkIG=oiT1=6UVfi<IEO%|`un0Dd*?5*#
+zhO5Q=@Ku^z{$ZgoTqV99?!Uj-TN{HMml}gix@W}g)+7p~5JZQ1M1>MXA%3;Vi*RqV
+z$!ay*`{~s;u||8UEASL+HX~{osb+g$SIhQ(*a>?=V^F6*O3(90>CAs#Q#sJy6}|t_
+z-=2u}lPbH^8068H;Lf*S3t4gRVNq0L5IZH>6+gx17);IRv4z+iEq`;$u3CErxRx#i
+zc~fg)6<-E9!i$h&OHl4j;IGQRUe|~CSLzHj<j=Xhawj-uy;x(iOIfp6^yKRF*BWFm
+z@>s9jIq_SfW}%!<zSG_A>g;YWUz2>tPj6sk_YJTRKF&W^<MS5jy)qVuP1JA0jk6yz
+z1;})6dC*;pj9t&SJx^;`My712VX|SOzGRx8;!;rT=5ReS48P{jhj?e_9hWwgZr`+Q
+zdF4*+Ux>=z$}Ll7c$ct8YH+IF#;*mccuG=FbjrUBRpXRz46;aBW%=TF$VoH?l_IZB
+zWtn5957#9fm4E2881DwMsMc&OLw4P4Br|8QN*}MZ#C;jW;#=NuR6cNff|959uZ&0U
+z<#G{O&BGb88CI~mimiWD6<eFhSepSgJ!?~fn*z%ZK3;Z$hYo(VPVqmo_0JQ}Am)1#
+z88usPrdMlgD(dT$dUsw4S+-icWC(`m5Lj-3`6@R1#acG|p%ZNO^(VXi1#-N>zkxN$
+zGNnDC&&ElYxFv?#^|&o=8H&<Bw*4d<TU*D*UPdmSSr4K+jHNW!Y{br5o9r`e#ff>)
+zz-)1)ut#_S@g1{$qnph>z|APcxfzAgZbrc&^#YG8mHyYk;|qQ*@x$CsJ`=D3+uUsD
+zF|WpEQe&2%1uv)8E|;%#NmZ@T^(b_2D|A_3))V<f-h4`}U7^&HPT|gXs+;ToEb-k_
+zjNeb{8NbKs8NW>bs<b?j(Y;Z>;$Pk~PcuGY-z`*O!U=icv?(qKyVivgCn|16XHe^{
+z)U;<zakwR*?HJkyD7E&}{?+TDa1Gx$P`J_cr4hf9Ee-PDIZB{mmOWkY6Wc2VV$Bd_
+zRtk%Y9jz~hB=d_yvXq=kj?X2`^VJG@KCi$$k?Sm5jfit>H4dL+(uFp#4ANe5B)k~X
+zIm(OdiaE}PyySfB^cO=s`n6s86*l+i|1<ZdpI~QKJ*k`U%fLMzsu&L$p~-xD=)dRT
+zu$S==c!BZYy1;lyZ(=<B0v<9#yLq61qjJ+-yOa^y!$THwGk*v%>7Em}4^P6aycayY
+z0r`dps1LFR7UT>DA!C5d`MJ$jn>>ryS$gdpJ4+)Q*jc)$p$<NINdxoD%Nv+J#Pf_7
+z`+3I8k@Jj~>ho;1AMw}|{s4U_`IC429+*@|<+QuqYvceYSw3dtIlhBJEwt>{u+GCM
+z#(5aUmpqK3%fl$X)adA;_(c~*^--DbQM9+t2>s8p?YYn+TgL?^+tel|+mR+Fo41L{
+z7TnBa>(k6Qxz)@#$-KxoS$vUkqP}ELm;pU2vYqSVB=D%b<W7%lGq83mAr&%d0(@7O
+zY)uy##js0^V$@|ualvIqao1%>55<-)in^n+<sL=mQ&)@c2xg<1a#2^uvi;D};%Kdd
+zrJTNJDPJ2(pvkWVzb?hAY`&3K*?eVJ*?g93Y`#6$90_&Z63AWinUBhcZabvYu$ME+
+zFNF>Gb#}0h5GfMv0;2UqnLrY<@>7AmsJ8%nu{kFLH-IJKM8~U$?gB6Ujp#!l_y?jY
+z;4osO@*jyJtBJCKI7A|k)SwR#P)qbOPz?+_LG%ldeG<Qu0~71e4#eWOg4X~q5Pyp3
+z5HP78rxIX1O*9{90^-gPl>h-hfnUH5IDmSfKYlTv46t9$j{)qL^K4)>um?B-`~Y}?
+zTY%U=G!PgI*nwYwlJi6tfhZ4X0jq&8fp+%ZNVEf}21GA-xB#9}Mxt~8gPMo}kAWB9
+zsc(rE0ILBvkawIY<~yRfz<S^~&;Z;8238U+1U3MBfF_{ud-R8%(|}i-p?e?r0v23F
+zKb&SxpraLYw-Mb&eRPzX`dlYU0di4)8yMRTy#c#`19(6F59l1YhWcG#?G2*P2h{Ww
+zu>2<K9pDdG3+w?(fV04Sd~X60f5tikvwwk3Wax}k<l$7*f@rco@(tO*THqEiD^Nwd
+zfXhMX6QUw}sETd?`GSge17Tq*nhP8PB73PQ4_E{&0S*Hv0e2tB(hqa>2hR^ePe6>7
+zl)sZGCq0C<z%LGmh7nZ`C;B9g=#de?Nbm^gMnN86J#ZJ8A5XLu_yGue6#am?zyhF&
+z(Ls4+G|_}HL?;2;SfT+5m=3=O#3Vv5fN>mtF$J1{fsf%m8GB$n_5<)Ca2J@ILbMKO
+z05<#{^$Ea4qWvfjpuGPtauSgTZS9aT_bJ%VBJj2l<!j&rI0BpjZUOm!BB})vmqJ!x
+zhh9zBfJ{+Mc02ZP0qhZ|1ZJ-$n!W~l1NIbx*6T!5*TU`qT<qyA&<;#mhrI^OeiQZu
+zEL@L0`WD`S8$iki%nw9wL>*WUd;;7Cnl=&b{vYfo!16Ze0);>&5V{$B0;_@jTZlUT
+z%zTNOO148UfVcxZg{!G}Cy{v<_y!IEQSTBh2i!pLZs-+#s!;0QBT5H00bXGJ9?14S
+zXgkms7*s?wcrW%lu=E4`7XZ)%m_Gz<AYvbA0kOr<2XN~ntl!7r0XP7peS$Rt3jac+
+zJ^&ek;)6tOCHVd+{Nf>^#XwXk))#mc*alPq9l(Uc;OVc>A@KHRu(1d=E%^exehEKu
+z6m7s(Cun_zeFd}wbIaf>fazbuUjbp?fCl_%A<F7<yjOrOPzW3cn!@4#BA_2&FVFzA
+z11SdhNr3%#&?F=10_%ZFpbh9FVLgGZfD>o};v-@AKot<*8#Lkb^H8n_Dxu#)F6=wB
+Ty<7#|>98+>v#~@WEkyqdyL9e;
+
+literal 0
+HcmV?d00001
+
+--
+1.9.1
+
diff --git a/meta-rcar-gen3-adas/recipes-kernel/linux/linux-renesas/0005-usb-host-xhci-plat-add-support-for-the-R-Car-H3-xHCI.patch b/meta-rcar-gen3-adas/recipes-kernel/linux/linux-renesas/0005-usb-host-xhci-plat-add-support-for-the-R-Car-H3-xHCI.patch
new file mode 100644
index 0000000..564d4fe
--- /dev/null
+++ b/meta-rcar-gen3-adas/recipes-kernel/linux/linux-renesas/0005-usb-host-xhci-plat-add-support-for-the-R-Car-H3-xHCI.patch
@@ -0,0 +1,174 @@
+From 98d922b9bc891f33efd04b9cf8efde22d7949213 Mon Sep 17 00:00:00 2001
+From: Yoshihiro Shimoda <yoshihiro.shimoda.uh@renesas.com>
+Date: Mon, 5 Oct 2015 21:05:56 +0900
+Subject: [PATCH] usb: host: xhci-plat: add support for the R-Car H3 xHCI
+ controllers
+
+This patch adds a firmware for the USB 3.0 host controllers of Renesas
+R-Car H3 SoC.
+This firmware is possible to use on R-Car H2 and M2. However, this
+version causes performance degradation on R-Car H2 and M2. So, we would
+like to keep the v1 firmware.
+
+Signed-off-by: Yoshihiro Shimoda <yoshihiro.shimoda.uh@renesas.com>
+Signed-off-by: Kyle McMartin <kyle@kernel.org>
+---
+ firmware/WHENCE | 3 ++-
+ firmware/r8a779x_usb3_v2.dlmem | Bin 0 -> 9472 bytes
+ 2 files changed, 2 insertions(+), 1 deletion(-)
+ create mode 100644 r8a779x_usb3_v2.dlmem
+
+diff --git a/WHENCE b/WHENCE
+index c310c8b..2890465 100644
+--- a/firmware/WHENCE
++++ b/firmware/WHENCE
+@@ -853,9 +853,10 @@ Licence:
+
+ --------------------------------------------------------------------------
+
+-Driver: xhci-rcar -- Renesas R-Car H2/M2 USB 3.0 host controller driver
++Driver: xhci-rcar -- Renesas R-Car H2/M2/H3 USB 3.0 host controller driver
+
+ File: r8a779x_usb3_v1.dlmem
++File: r8a779x_usb3_v2.dlmem
+
+ Licence: Redistributable. See LICENCE.r8a779x_usb3 for details.
+
+diff --git a/firmware/r8a779x_usb3_v2.dlmem b/firmware/r8a779x_usb3_v2.dlmem
+new file mode 100644
+index 0000000000000000000000000000000000000000..7db71726f45943e7162d8e21ce7d80885bd79184
+GIT binary patch
+literal 9472
+zcmai44O~=J+J9z-JD0DE%!QeY<mgB<W~{cz`bjBB=$cutpn@Ny@*$Ox*>2nRww5Cf
+zN@k|M>6%}e4W?AC61Zi0qY280H9#4W6o(P~7+pbD-BR(s|8ob#ecSi9{C@v?&b{~C
+z=R9BMInQ~9k{Q48Mp8YozY7#;Wv$+l8J(kO$gcFK`_ZOEFQuL*UQN#vJD){1{m1>a
+z#63hw47M9&kJYa|MfAdqSbgMaq5w&B{~mpxk!V3iL!rymL0Y{>@tLiXt@SPOBxf;E
+zcrN-@$>@Gh+;6tE+g2p%i%3hF_}7TyWo5n2lj`MIuNA$69Hm`1`bX`>D8eZA?Kbgq
+zPF7Y6l~SbJx?OS~8$~25wUaezN&2Pq%=KaV&3%Xx^|@h0OR0eI{&rux^$L+LE>V9C
+zlwKs;N~3*{zLw3Mkf;yTXlXH-J2+0mjeR|kbgw0u$ZjwS#vr5h26Y8-14NzC_D8e*
+z{!tq0FXl>y%tZY-e6@&@F(=cH{(`K83a@2oh;bqF!GhIfkz)0<Rne_7<njY0t^Ts|
+zhG4y6ku)Q8T!HwM$QhSHqJh#xL#dfP*UktIcZrpT?8Ko`ut`HYqc!6}$(#BGm&@BE
+z=n?d;;7=WsF;w!;yh5GZgZHyCgJ&)i_Y0nj>jkUCK~pC=e_PiTGL`W)Oz(cUS2w@3
+zYYJa0Xv7q$PH?o>30b}t&L!md>V!_A+-O%O66|BPD|;ia3wFh%slqiuTh7^)`8vCD
+zAhL?nz;;^6kys~mjp;lcqbEa2iFOQo+Gx7oz&K!Y%E~6#w^|*21$PPkWM#$OC#T?z
+zqXX>9&VT{&Un+<0$jZXI?<$}#!CfF;G|I}+WZ1?{MoYSKb+SQYWRfyJvu@Y8kF6w(
+z{M?-@bp*;v?A`C}<oBoBTEExHO4!|ZxtP}-Fi78O)q<xBW>0D-X1Sv6;WVZD+tE6|
+zFM3wa*D%RmF>2CMGHM0CbS-g=52}Al+yjmnuXU;o3dQ#Y>vnP<lbE*#r`Q!QH9RjX
+z(UYvw#S;#(u6y)4%sHsPRnoXO!Ottd)VdkHEszU78IX&<fBYU!Q}35}9c<0!ImvnI
+z4q|0A^|!U}FG$okgHN_%*t<O=JaxViOe4$0pKT85AAugjL7T>BgP&`gE2+U~j#~k~
+zb~VDnLM*)e;qw}-p_l+IErHdmxyqHFxr>GIKIUcGv}GdZPxD<o(Z;;x=fKLhL*1Ub
+zCd@wDVpm+cB)t-+dY8J!7lH~~<FfKQNY`xa@dGFPEK59SbV##WJ%&y}Ryvby?a$j2
+z^_%epc;DW~eQW?x3SX!CbD?;Vt9+o;ZCBP)!vtIV=a8~e9qCDRVebA>#bdFaTA>Sp
+zMUmzRTl-fSb3q-$e7krkdtanRkf|{&GQFYpr>Ol^YTs>@m7i3ZHSvd)C-1N?mVu(5
+z+a~yzpR3CELcz%(b-nk>n$G#XLsqgO>mn1ARgFRIeIeINc&m$ht=p3d?v7n;l9e(O
+zi!QcyGm{^0n7*u%KfbiUj*N?C(8HKkhxirN+*+#Y*1-{Vv|k6SqBe}RwKqU&Pd9a2
+zyJ2~v{<1p8DgBdK9$!zw3M<n(aGxy}*!<6{&9ag|A=o1;<A&MVTR<a5&-k#lUq$~R
+zwJ$5L#(P>iq3z@eEJn-9wIQ(fJu=S3xLz6aaK~&9kM<!pag{vz;G-tCc4r!s(!(j(
+zFbkTBmU^Y%)IIAbg^7A+cb{pmw41W5JbBOPZ`2Vzad?0T%9%VOcL?G)`dyq6ar6dV
+z<cvIP-JDTxED+ZT0}#hKH`@jMf3|iF=7{9|60`l`G9tVd`@`VwX9MwmxZ3x7@IX4O
+z)ZDU|YI*C8&-&OS?dgiLY<j`;<&hRsKeFD43fvbFkhXuCPArZ1G(t1GY)<*KWto=r
+zBUCWmGIy<Jd8TD<E;%v_r>_WD8DL4jNkw=*MDs@GDzuUGCdO9iR!`^BHc#6!O`p9r
+zCurfe=eEyzZ`zJ&@8<;1-Z{rIH=I70qn+)XQ#@x^#D@{PBlgTGne$P^#}S`I?49<P
+zIZ66NHR3{UPm0m9QRzrC6qrae0U8gBVr$9P{sg=uIMDBJyQBWqU#)n~Z0SVA$P!m!
+zFX!A_#qW%WMS-gJ#2)PtjTfI5H+K0)?B`PWe<1P(+TfM&s!Ut2bzfHJV&jt1NjKTx
+z0xyH2ao<%Swsf!abzK{T-Y<5mUoZ>zt|YmeGg+BA$dk$<PxByIiF%;-tLD33+4+H3
+zOJNUsQcE%Jcx;bWZ0*C4f#`#n?0#R)jrUu&Wii#W$TlNTjgUv<blT?OI;&Lf(_X0d
+zZT7iLiR8WL8gbe*fV?9^sdAWJDtl+p$bIiLid)4j@v6C=%R$6<8H>$h)JU3-S(YHq
+z`s3=W>RpLmQCxzizF2tpd=Mq-*Q!t1emaiE`%b4PQcA`FUqe+AasgP-r!&qr-aG%Q
+z!&&t=Ia~V}Sg=Nw0xNMbi$(g5+?l$F#@SnEH;V6y2ccDs9omkYY^b-fezmw+)J}D!
+zRi?&f;7uOcr=%8`L-ZX=9d@%z8Q5p%jc9!wdx3Ve*A$8f@I+yy!Ta0q`lQ4s>PH7N
+zjdg2^9??@wNs0A_ljdJ==vdBBfSh5SP%1PaqHj)aK$b9^igA6Ju0#LllB+l^qH|N2
+zBe9se#?*8D#<2SXVGd~zAv&FA@q|g?Y%eB8Z@n=`rCJPnrbpSe@=-=9ETxLm;mfsQ
+zPL)!DfQ;ieEaM2k)4Z@A4jt_ulJoqBWDeKr|E{z=kxUU}qQ2CR22c#yXfXYX9-?71
+zoJLUsjin@dlpdpr@R`m>i^qa~%JmV*PE)Ez*p*GR0oUWyHq@>}YRYllttrISqiL|&
+zl{?yET=#L;ktH4Hs^IzQ&u+jqc3~UxrvN?6qWbF#;qkljnRYt!nKav<XVT;?s^S>m
+zF2RxbA@rh3lftA4#M4cJ6HjlCS<hsg!Jb-1hJ!;p@(u;-^Fw-8{K%Y4!4yjOQ5c2e
+zDpDk_CS;?pq{w{i1exCm8~|b_%6u}geIgex^HYVT-4wo8DVRYc95hTS1v5o~Lcnij
+zz8RSEn9RRAN#@5*mihHS0q&PPt_PLiZYo;+d8KYbGW0tUvzwvgfpkB#`~W=&JrAW{
+zL({*Z5qLX_#?Zsi_e4qr#$%SE$7Mcmip)nofmwhi;GHLBKKj38e)?3IzXJ?UmHDGU
+zbehZ$o+k4Pr^|dJpiP(gk-!e15g0yG=AE;6aJD$KN4_^z`T9b>Fz^=+h(IJ}o;X|P
+zD}l^8GVcOnGi5&IDQKRL@BTUqyKjLpN4(0_3%R0~gU$FMPuY1`fge6E2qObAas}VA
+z*fGiwXf-(s^cSjpu8VBPCNI@no1Oe}WH8QApYpOI=eI48l{<UPl7>!-+r(UPvvB&K
+zdh&AH&hw<HZ}h(B{X!Cm(X##UH>~h7K}*fzd!lyqf0G8g+{d&vVw=uWS77tBGzn(O
+zh!`>b(rIzK__gS|IzZH5-zzruj5KG2P<8qM8lUEqDrla#Ey8-EjMs2FuJX^*!z%ks
+z4|_OKph|vvm=1C8L*nB$#ebi$CE=R{<idg0ksp)Altj7?P~~jWw&m7w)5C(3LMCzW
+z<>TB$HSP>ly(kNNYo{?+TxaVv=84P9USR`PLjp2@zFk$~1~FN5nRJvQMM{NO4e=Vb
+z4lMIneAuO7>wvPVxL|nv!C-%!M(#6jKX1L_<gJKPA>o_U$W@c-G3*qy`ZLN^E*3gO
+zbh9TT9|?)CdWuE5<W%nr*GPpz!oL@7=gp2S&|9LuGmJ&yl#KAeRTTV;pw}n|IWE3@
+zLe)YcywVUOy<6Zi@suTYj?EE$BZ9*VMOU7VsuATiv%T{wDEH~Uk}Eq@9s8Iscb-{#
+z+`vw_cO`pScUMj(<rTx`uF7YJ-lba#|0xkFvxZ2I`I2YVb9z<RRYuFm2s)hD2kY7N
+zT!Y|0qwMJ8&zzVAo#cpE9>G>R%LA=*ojfv9oGZq(E=T*(D16E1FLX$Tz$%;{d*sLw
+zJ3034a-BwWL=+?P_m!*}W{I62V;BdiJ)GmL!}Z#wL2zUkCC0zcaFhE8d@=s8A{Q>D
+zBJ8Esr}z8nvo~jlniM5V{1h^+H$E$N3eSo4!t-J&tkSL&2wKzM@%C$O7WTs}PdGBL
+zCgwT{g2SuC?+sbmrCfIQLBYQR724ONoy2KBhu2_-ux31eDJKIvUdD@;bRD`Gu;zW-
+z44xCFRj2D{Rl1$tnie)E1|z<o>!IpJ14x*)X3p`nchlaU7K#ikEA1@zY?_M;1{XfA
+z0ABs=xIWatSrhmBY7(|4=;Dyy25_q8Cm}y#vGd=p?XtNtUo#JpV15YJ_K?7y81nx|
+z*>Up`RkLJ%FK`q{$d>upKx1|&DEN3kg)E#1ONDIF#Wf&;B;_LJED-R%`kwb*F1tIz
+zOj;oG`aGFmloy6EyLda_63$NiRldrLukmjbyvDx;tOGUx?*iL^_Y3r%mBcq<k9^K7
+z6&Bn#x?h|>%2Z>8W#*UTx+Wj~6b^ce`Nl02Si6~mj_5sGsUK*w=;gX-j-v$2L<_t!
+zUf(b7zR}T1eJ5dm%I_D)qL%;OPjwaB(H61z)pt^K5}S?96Z1kFuIVqZ*)m_iY{*S|
+zx$ohy|6<1B*ei|#Hiw^{4>2KnF{9T*D}OPgb#yVKMKAg}&myLYN^tAsTo(sR9Pu;X
+zB<)mfTy5H>wBT_XT1ji;vu5ucnlsyF&YfK{q6v{U3!2Rl3xoyYPGl&7@P_EZ>o(Tj
+zE-Y8u<`vh??B2Pu-0c6Nlv^M&iRKp-L(+vs*M)z5{!9_$ZcP#6uB@o13dC}ldpZ2J
+zJpgf)(Wy~KzW&B*8JwC&t>Rl0%g95}bmi*c9kTMx>YNN#g^<w(pgn|Ek5$M<96&#?
+zyI+caFrKxd4MlqjZ5Y}nwBg-jj-!t>y@U=@DODRUe9iO~0PA+lZ+yBU$8+tBMH>Za
+zC$BblWQF_ATeN30baZweM?T4-T`={>mP;8H?J0vR_3S*Ja>Fm-X?A0^;cP|_<#~MS
+z*RGQ|eXnNUnmc}MnO}QW3ZbaDoJQ{nixzb;KV^(On<0R5pKi)cCmH1*Rmz4Q%C(Gg
+z1m!jQ@NHC_t4>zL)ohlglea(L!}a^@*8V-*ef!K;l4yMOyOdk~)ixulX4<KhsSCe6
+ztV8weucvk6OE%CmC07e4Bg1Cdzg`M}FEE?2sFszme}-#lPD0&SuQ4~F>4_|{h4TtI
+zxE2U)6HuLTR^giO+<@zo#cjv{gLjpWy?0dk2wAE4U<0l(&bFb@x3e7Ajm3pS?;TZW
+zla<^L+K~S>eo&69!&!)HQgMUv-cfA-vwl#H>)sCvagB2}aM%Zmi&0_m?|=izA$`>c
+z6%s`A&-y$YSEPfleq@ylT@H4l9uU~oy;F9uodYKq<mji2EJs&sf)&fei|2{_Cz%Q=
+zH}_L(JqN!DzTml7ipq~&*+FARX=uzDR`W5LwDc#+LIgeigN{m3XWAf)_cBVLgX)#H
+zWo4Uxhf2oCD4Y(XQCn0x*xFXBLpbN7I@DcTs-U*++S252f<2xVuh0+k#nB^}&wmzL
+z0V+!{U+FKZOW(E;G@yiMMh`-~iPdY6t>vKiz4)d$*^rbjVt?`pT5+O;n#;fWW7TZy
+z4Xa?+Sxl#BS%g+Bh*+-6<sTG^A~fO~5v&^7LXP&9Am{m(AanTB;uc#n1yTsILj$rx
+ziK3Ce+Lc8(x7ih~maYAi+Uu~<+S)2yscr+ZmeE?a_V3iOwST+bk=PQ{<<HXd{8>7S
+zpG_Jko_A;OfAl|3!gH6#A+-c~45c{peXNJ9;D}{WEkSIT=v3nrn_~#IVZ=sabDa8{
+ztn90IWPoewY>+p#9$s-M$Qe<Ls+<3`5B_TW_PRRMZ>h`BkiQD^hg-pMYs5OUL(0lz
+z*^{fw-)mO9sBHb=*0Em`wF#Ac%B`N~uCAWvl`B(j`ROG@^_&2U5aaxFwLEW?-mhSJ
+z*kr?IoHz%fQh?g$#{1p%sNwa#+xe7^)o3b)8K)X28%k&RDXsy<9uC)_!thJ}e8_jU
+z-E!$e>E?Co#y{Mu{|iy&+qo6$4DS)vNF8?7oA~`elR(MZ$+B{Jm=?QyOORE{swfb@
+zLrtP3s2r7cs+c`?=7{j*!^)v9tLb(i%W5sA3e?*zCbDowoAk*t>&QbvEWhQAhn4L&
+zC#jWdzhyiIFPDqVY613;4e)}OYMA{G)-c<QgKZ+~dTmpRlLD(4K2~vzhYo&Wr@=ok
+z`{#*G$oZZ?jct8jrdL~gD*D^izW)r%>KD({J0xQ;B8R|g3oKT#*^k$=*>@gevoAT`
+z6E9Hp4gM9pNl_^6aYHtCx}=S9)M;3cb{Ja!x1Qtd+lmJEtsB*O<~_*n@GYge<|232
+z+ZCU26L!q~M&^slgq^|*$nTi%2e{enk#0u8>Sh#T-Hd`$>H{8^spGGL#~1us;$z%0
+zKM7a_6uH^TV^NLGq{S>h3tmpEe_grQEtRa&J*v{ZpweYy*+^6z`LGjO{Zh3TcLHa=
+z6Fpr2XNi3$7{6N^8NX$Xj9;dIO<JDF=z1HM{>%NOlZ;RJ_Z6x#V~5;+(mXN<me_|D
+zJ1R~_N6_o5_O79aQv#lqp*KkFc~1JR*Gr)Z?>JEKcE4%C?`BJa{AZ3*XqeSgXa306
+zN}*Uc6qS{tk`ib8iy<le;*c!0rjp}x2@8DnLY~hnut>D;6tjl*G_!{DG?VV;X;wkn
+zMb5+*L%POzQC+c&w4+j)j+Opmh{v$1yS~Eae&qkmZT}H|cFB{v9={db<)Mc0kP(`~
+zr-%M~9-Lmr!woOvVc%KCLrN>-;SPAn2<_p40uC$nw;fVOXfF?0h`zrMF^4}VZW)n`
+zQ+Xdmcq8f!_fdaT4Xmgc#G+y#D^pKzu-TPNVtZ-RX||W@o7rBP+1!AboZHMIbAB_^
+z2c2QO{O%0nW%n7zi+qMzyPwCA_<QI>t)IN>kHDlktR&s;v5^y;Wciqn=lJ#u_0Y0k
+z!*^7QRu7{%-@_>G^Dv6@Tb#WVzv!l@J*-^0)kD$IJ}dM;%eMAxuWYSnnQY0eOt#&v
+zOt#uqCfiS~Ot#QACfm6-#>u2}jFY+N7$+U)9Er1_XH~Y--JAp-R&wuh;shs5wtC3c
+zA|Q5k%T|AmQM`SQQ4GAmD9*gVD6YQX?4@|6n_~E3MZ8Oq#nctzyMo1Jp<MK}@oYV`
+zUU9ZJz*A1%^^~uSrO@P8f?t<(iOo0Y5}R-DB{rXUna#KMvNN%vM*^jLKFeWc=S`<{
+z68_Sp{&q;zj9+YrgcEW_qU}IG1JP_C8I}6!z%KN!0K2d}rvlf2mm`Rd)DYbUe)l(`
+z-9YeBq8i``vZTr%h@xtVvVlp+MINfd7$BgY=p~>Q7=DcC4v>8uznue<8}J;6$L|NP
+z0$w2D1W_3<r4joQU^+?k4A2UUY$7TJ0)7O)fCF#>jX(^3MV|_=U(>$<*stl?zzSd|
+za1b~Oc!8e)v6*NvFb;44cYx9}MCX8L4`=}^fI~nhyKf=d3e*Ck7d)H=&uF92I)T_$
+zqQGy!3-IK(L<@lxfE&m=LKOEM(R^SHa0F-uZUcj>iSmK9z)qkQDEc1bq31N<l{V<!
+z2fl!XmoNtVSuJp*9dmaOg+^=XNud8#qKUxE=<fo?bwY2zcEE-EBmaQTfjj7j-KV8h
+z*NFO~oe#Wz9dvGhKVTKG6DS2v0k7iy4It@fq65I(JJ5*&osot-oQAF-pNv7pAsbi)
+z`~+kMYG^xfAqZnaG~@`?&^4ey(9jMbEKEc5fifVfkB0JqMZn9z0pK{`?hpSQh`C~j
+zF5eG50dY1`|Bj=b@&Ig!-zLh26IG8O+B=fyp;5qS@CbyDfjqz(;5P6~0?{VmC=m8A
+z#sTwzg}@C)2kpT};Jagqjsx~_M1vAxYy2V*mjt~4rt$a{6=($pKZ^Sltbqww55R8V
+zHZXM}(Q2R>So>S_Cjpa*K1RC_?Y)0dQ;0lx)(IJNpM?J`0&n?fUj-k)L7)lv2`Kmz
+zQ9Y2f1hO(1v~&l^7q#SYU=0_-RzNi{cLmYRmCzfovk0`_Aez1keh1)aPp5!RV9IK&
+zHDK;r@Gl^L4c6$}xCgEQ6W3yXpx-+5fi=Kh;3m+zo@mGazy^Tz9nb}efNCIg1Na11
+z03UCJe*aAL8Tc&S0=)p@R;=F$EtPB|vTO(6Kp7DI9?|Q78wlP3AH$d$wBhd)r332$
+zFR*4OWcvWLofr$m784EGh4l_B`4ImZ0JH*@-JlIb?tzVf_!8&?_~|3q?-S?+*axKT
+zg^hrszYuBnK}MitKT$_1-hYa?SVpuMh%SeHfmeXdKn-vMm~;R<{S`U{-uVnRjnvZ1
+zUx3#`h!cnL4A>-t)|XgUKqoN20<i*^`4!?75cW0ni8xw>wzd-YRiFzL0Y`w=2*kfg
+z=m*#ZGy|Q$L?hxP!2V-siV1XqH9$4c0rZz(Phb-u1Fb+p6#O2j0TTLxCSrab+BHBm
+Z^jqe_y2G=VYM{GttV`fjJa~cL{uf;D@)rOA
+
+literal 0
+HcmV?d00001
+
+--
+1.9.1
+
diff --git a/meta-rcar-gen3-adas/recipes-kernel/linux/linux-renesas/0006-spi-spi-gpio-fix-set-CPOL-default-inverted.patch b/meta-rcar-gen3-adas/recipes-kernel/linux/linux-renesas/0006-spi-spi-gpio-fix-set-CPOL-default-inverted.patch
new file mode 100644
index 0000000..d7b42f3
--- /dev/null
+++ b/meta-rcar-gen3-adas/recipes-kernel/linux/linux-renesas/0006-spi-spi-gpio-fix-set-CPOL-default-inverted.patch
@@ -0,0 +1,30 @@
+From db37427756bc9e42723f58067a3f387a2861fbbb 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] 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 | 10 +++++-----
+ 1 file changed, 5 insertions(+), 5 deletions(-)
+
+diff --git a/drivers/spi/spi-gpio.c b/drivers/spi/spi-gpio.c
+index 1c34c93..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;
+ }
+--
+1.9.1
+
diff --git a/meta-rcar-gen3-adas/recipes-kernel/linux/linux-renesas/0008-arm64-do-not-set-dma-masks-that-device-connection-ca.patch b/meta-rcar-gen3-adas/recipes-kernel/linux/linux-renesas/0008-arm64-do-not-set-dma-masks-that-device-connection-ca.patch
new file mode 100644
index 0000000..14612cd
--- /dev/null
+++ b/meta-rcar-gen3-adas/recipes-kernel/linux/linux-renesas/0008-arm64-do-not-set-dma-masks-that-device-connection-ca.patch
@@ -0,0 +1,132 @@
+From e3218ab51b0bf3f193a9f64e5c0dafe74e292ad2 Mon Sep 17 00:00:00 2001
+From: Nikita Yushchenko <nikita.yoush@cogentembedded.com>
+Date: Fri, 6 Jan 2017 17:12:49 +0300
+Subject: [PATCH] arm64: do not set dma masks that device connection can't
+ handle
+
+It is possible that device is capable of 64-bit DMA addresses, and
+device driver tries to set wide DMA mask, but bridge or bus used to
+connect device to the system can't handle wide addresses.
+
+With swiotlb, memory above 4G still can be used by drivers for streaming
+DMA, but *dev->mask and dev->dma_coherent_mask must still keep values
+that hardware handles physically.
+
+This patch enforces that. Based on original version by
+Arnd Bergmann <arnd@arndb.de>, extended with coherent mask hadnling.
+
+Signed-off-by: Nikita Yushchenko <nikita.yoush@cogentembedded.com>
+CC: Arnd Bergmann <arnd@arndb.de>
+---
+ arch/arm64/Kconfig | 3 +++
+ arch/arm64/include/asm/device.h | 1 +
+ arch/arm64/mm/dma-mapping.c | 51 +++++++++++++++++++++++++++++++++++++++++
+ 3 files changed, 55 insertions(+)
+
+diff --git a/arch/arm64/Kconfig b/arch/arm64/Kconfig
+index 76747d92bc72..9513d2eb5c8a 100644
+--- a/arch/arm64/Kconfig
++++ b/arch/arm64/Kconfig
+@@ -191,6 +191,9 @@ config NEED_DMA_MAP_STATE
+ config NEED_SG_DMA_LENGTH
+ def_bool y
+
++config ARCH_HAS_DMA_SET_COHERENT_MASK
++ def_bool y
++
+ config SMP
+ def_bool y
+
+diff --git a/arch/arm64/include/asm/device.h b/arch/arm64/include/asm/device.h
+index 243ef256b8c9..a57e7bb10e71 100644
+--- a/arch/arm64/include/asm/device.h
++++ b/arch/arm64/include/asm/device.h
+@@ -22,6 +22,7 @@ struct dev_archdata {
+ void *iommu; /* private IOMMU data */
+ #endif
+ bool dma_coherent;
++ u64 parent_dma_mask;
+ };
+
+ struct pdev_archdata {
+diff --git a/arch/arm64/mm/dma-mapping.c b/arch/arm64/mm/dma-mapping.c
+index 46a4157adc17..04b9bce96f1b 100644
+--- a/arch/arm64/mm/dma-mapping.c
++++ b/arch/arm64/mm/dma-mapping.c
+@@ -351,6 +351,30 @@ static int __swiotlb_dma_supported(struct device *hwdev, u64 mask)
+ return 1;
+ }
+
++static int __swiotlb_set_dma_mask(struct device *dev, u64 mask)
++{
++ /* device is not DMA capable */
++ if (!dev->dma_mask)
++ return -EIO;
++
++ /* mask is below swiotlb bounce buffer, so fail */
++ if (!swiotlb_dma_supported(dev, mask))
++ return -EIO;
++
++ /*
++ * because of the swiotlb, we can return success for
++ * larger masks, but need to ensure that bounce buffers
++ * are used above parent_dma_mask, so set that as
++ * the effective mask.
++ */
++ if (mask > dev->archdata.parent_dma_mask)
++ mask = dev->archdata.parent_dma_mask;
++
++ *dev->dma_mask = mask;
++
++ return 0;
++}
++
+ static struct dma_map_ops swiotlb_dma_ops = {
+ .alloc = __dma_alloc,
+ .free = __dma_free,
+@@ -366,8 +390,23 @@ static struct dma_map_ops swiotlb_dma_ops = {
+ .sync_sg_for_device = __swiotlb_sync_sg_for_device,
+ .dma_supported = __swiotlb_dma_supported,
+ .mapping_error = swiotlb_dma_mapping_error,
++ .set_dma_mask = __swiotlb_set_dma_mask,
+ };
+
++int dma_set_coherent_mask(struct device *dev, u64 mask)
++{
++ if (!dma_supported(dev, mask))
++ return -EIO;
++
++ if (get_dma_ops(dev) == &swiotlb_dma_ops &&
++ mask > dev->archdata.parent_dma_mask)
++ mask = dev->archdata.parent_dma_mask;
++
++ dev->coherent_dma_mask = mask;
++ return 0;
++}
++EXPORT_SYMBOL(dma_set_coherent_mask);
++
+ static int __init atomic_pool_init(void)
+ {
+ pgprot_t prot = __pgprot(PROT_NORMAL_NC);
+@@ -971,6 +1010,18 @@ void arch_setup_dma_ops(struct device *dev, u64 dma_base, u64 size,
+ if (!dev->archdata.dma_ops)
+ dev->archdata.dma_ops = &swiotlb_dma_ops;
+
++ /*
++ * 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);
++
++ /*
++ * Whatever the parent bus can set. A device must not set
++ * a DMA mask larger than this.
++ */
++ dev->archdata.parent_dma_mask = size - 1;
++
+ dev->archdata.dma_coherent = coherent;
+ __iommu_setup_dma_ops(dev, dma_base, size, iommu);
+ }
+--
+2.11.0
+
diff --git a/meta-rcar-gen3-adas/recipes-kernel/linux/linux-renesas/0009-swiotlb-ensure-that-page-sized-mappings-are-page-ali.patch b/meta-rcar-gen3-adas/recipes-kernel/linux/linux-renesas/0009-swiotlb-ensure-that-page-sized-mappings-are-page-ali.patch
new file mode 100644
index 0000000..cccc80d
--- /dev/null
+++ b/meta-rcar-gen3-adas/recipes-kernel/linux/linux-renesas/0009-swiotlb-ensure-that-page-sized-mappings-are-page-ali.patch
@@ -0,0 +1,38 @@
+From c92eeec67eb96b79fe3d01b0045789de52fd5af3 Mon Sep 17 00:00:00 2001
+From: Nikita Yushchenko <nikita.yoush@cogentembedded.com>
+Date: Tue, 3 Jan 2017 14:24:58 +0300
+Subject: [PATCH] swiotlb: ensure that page-sized mappings are page-aligned
+
+Some drivers (e.g. nvme) do depend on page mappings to be page
+aligned.
+
+Swiotlb already enforces such alignment for mappings greater than page,
+extend that to page-sized mappings as well.
+
+Signed-off-by: Nikita Yushchenko <nikita.yoush@cogentembedded.com>
+---
+ lib/swiotlb.c | 6 +++---
+ 1 file changed, 3 insertions(+), 3 deletions(-)
+
+diff --git a/lib/swiotlb.c b/lib/swiotlb.c
+index 76f29ecba8f4..771234d050c7 100644
+--- a/lib/swiotlb.c
++++ b/lib/swiotlb.c
+@@ -452,11 +452,11 @@ phys_addr_t swiotlb_tbl_map_single(struct device *hwdev,
+ : 1UL << (BITS_PER_LONG - IO_TLB_SHIFT);
+
+ /*
+- * For mappings greater than a page, we limit the stride (and
+- * hence alignment) to a page size.
++ * For mappings greater than or equal to a page, we limit the stride
++ * (and hence alignment) to a page size.
+ */
+ nslots = ALIGN(size, 1 << IO_TLB_SHIFT) >> IO_TLB_SHIFT;
+- if (size > PAGE_SIZE)
++ if (size >= PAGE_SIZE)
+ stride = (1 << (PAGE_SHIFT - IO_TLB_SHIFT));
+ else
+ stride = 1;
+--
+2.11.0
+
diff --git a/meta-rcar-gen3-adas/recipes-kernel/linux/linux-renesas/0010-can-rcar_can-add-enable-and-standby-control-pins.patch b/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 0000000..38d8e09
--- /dev/null
+++ b/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 5d5eef59a48e3b8e0f67c2ab0963d380c7a7399d 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] 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 8d40ab2..9293cf8 100644
+--- a/Documentation/devicetree/bindings/net/can/rcar_can.txt
++++ b/Documentation/devicetree/bindings/net/can/rcar_can.txt
+@@ -38,6 +38,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
+ -------
+@@ -59,5 +60,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 788459f..887ca37 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 (regs @ %p, IRQ%d)\n",
+ priv->regs, ndev->irq);
+
+diff --git a/include/linux/can/platform/rcar_can.h b/include/linux/can/platform/rcar_can.h
+index 0f4a2f3..7ef810d 100644
+--- a/include/linux/can/platform/rcar_can.h
++++ b/include/linux/can/platform/rcar_can.h
+@@ -12,6 +12,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_ */
+--
+1.9.1
+
diff --git a/meta-rcar-gen3-adas/recipes-kernel/linux/linux-renesas/0011-can-rcar_canfd-add-enable-and-standby-control-pins.patch b/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 0000000..60834a9
--- /dev/null
+++ b/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 0f55d888c83aed7ea5a10761edaff52de8dc06a1 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] 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 | 48 ++++++++++++++++++----
+ 2 files changed, 44 insertions(+), 9 deletions(-)
+
+diff --git a/Documentation/devicetree/bindings/net/can/rcar_canfd.txt b/Documentation/devicetree/bindings/net/can/rcar_canfd.txt
+index 4299bd8..eede77a 100644
+--- a/Documentation/devicetree/bindings/net/can/rcar_canfd.txt
++++ b/Documentation/devicetree/bindings/net/can/rcar_canfd.txt
+@@ -16,6 +16,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.
+@@ -49,6 +50,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 15a14c5..4aa670d 100644
+--- a/drivers/net/can/rcar/rcar_canfd.c
++++ b/drivers/net/can/rcar/rcar_canfd.c
+@@ -21,6 +21,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>
+@@ -386,6 +387,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 */
+@@ -1063,6 +1066,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) {
+@@ -1131,6 +1138,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;
+ }
+
+@@ -1409,8 +1419,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 */
+@@ -1552,6 +1555,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);
+--
+1.9.1
+
diff --git a/meta-rcar-gen3-adas/recipes-kernel/linux/linux-renesas/0012-mtd-Add-RPC-HyperFlash-driver.patch b/meta-rcar-gen3-adas/recipes-kernel/linux/linux-renesas/0012-mtd-Add-RPC-HyperFlash-driver.patch
new file mode 100644
index 0000000..a6d08e7
--- /dev/null
+++ b/meta-rcar-gen3-adas/recipes-kernel/linux/linux-renesas/0012-mtd-Add-RPC-HyperFlash-driver.patch
@@ -0,0 +1,1028 @@
+From cc3bccbe6c479d8ad76a09b62fb63126403d0bab 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] 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 42cc953..0c58a89 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 99bb9a1..3b81efb 100644
+--- a/drivers/mtd/Makefile
++++ b/drivers/mtd/Makefile
+@@ -13,6 +13,7 @@ obj-$(CONFIG_MTD_AFS_PARTS) += afs.o
+ obj-$(CONFIG_MTD_AR7_PARTS) += ar7part.o
+ obj-$(CONFIG_MTD_BCM63XX_PARTS) += bcm63xxpart.o
+ obj-$(CONFIG_MTD_BCM47XX_PARTS) += bcm47xxpart.o
++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..f8a2c90
+--- /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/meta-rcar-gen3-adas/recipes-kernel/linux/linux-renesas/0013-IMR-driver-interim-patch.patch b/meta-rcar-gen3-adas/recipes-kernel/linux/linux-renesas/0013-IMR-driver-interim-patch.patch
new file mode 100644
index 0000000..30cf006
--- /dev/null
+++ b/meta-rcar-gen3-adas/recipes-kernel/linux/linux-renesas/0013-IMR-driver-interim-patch.patch
@@ -0,0 +1,2104 @@
+From 240504b182a2816696c6a02fe37a5048925cc1fb 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] IMR driver - interim patch
+
+Signed-off-by: Konstantin Kozhevnikov <Konstantin.Kozhevnikov@cogentembedded.com>
+---
+ arch/arm64/boot/dts/renesas/r8a7795-es1.dtsi | 32 +
+ arch/arm64/boot/dts/renesas/r8a7795.dtsi | 32 +
+ drivers/clk/renesas/r8a7795-cpg-mssr.c | 4 +
+ drivers/media/platform/Kconfig | 11 +
+ drivers/media/platform/Makefile | 1 +
+ drivers/media/platform/rcar_imr.c | 1840 ++++++++++++++++++++++++++
+ include/uapi/linux/rcar-imr.h | 98 ++
+ 7 files changed, 2018 insertions(+)
+ create mode 100644 drivers/media/platform/rcar_imr.c
+ create mode 100644 include/uapi/linux/rcar-imr.h
+
+diff --git a/arch/arm64/boot/dts/renesas/r8a7795-es1.dtsi b/arch/arm64/boot/dts/renesas/r8a7795-es1.dtsi
+index 09e1284..d530100 100644
+--- a/arch/arm64/boot/dts/renesas/r8a7795-es1.dtsi
++++ b/arch/arm64/boot/dts/renesas/r8a7795-es1.dtsi
+@@ -2713,5 +2713,37 @@
+ };
+ };
+ };
++
++ 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 R8A7795_PD_A3VC>;
++ };
++
++ 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 R8A7795_PD_A3VC>;
++ };
++
++ 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 R8A7795_PD_A3VC>;
++ };
++
++ 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 R8A7795_PD_A3VC>;
++ };
+ };
+ };
+diff --git a/arch/arm64/boot/dts/renesas/r8a7795.dtsi b/arch/arm64/boot/dts/renesas/r8a7795.dtsi
+index 82ebfd4..9b4ee2f 100644
+--- a/arch/arm64/boot/dts/renesas/r8a7795.dtsi
++++ b/arch/arm64/boot/dts/renesas/r8a7795.dtsi
+@@ -2699,5 +2699,37 @@
+ };
+ };
+ };
++
++ 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 R8A7795_PD_A3VC>;
++ };
++
++ 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 R8A7795_PD_A3VC>;
++ };
++
++ 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 R8A7795_PD_A3VC>;
++ };
++
++ 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 R8A7795_PD_A3VC>;
++ };
+ };
+ };
+diff --git a/drivers/clk/renesas/r8a7795-cpg-mssr.c b/drivers/clk/renesas/r8a7795-cpg-mssr.c
+index 718afd6..f833031 100644
+--- a/drivers/clk/renesas/r8a7795-cpg-mssr.c
++++ b/drivers/clk/renesas/r8a7795-cpg-mssr.c
+@@ -229,6 +229,10 @@ enum clk_ids {
+ DEF_MOD("vin0", 811, R8A7795_CLK_S0D2),
+ DEF_MOD("etheravb", 812, R8A7795_CLK_S0D6),
+ DEF_MOD("sata0", 815, R8A7795_CLK_S3D2),
++ DEF_MOD("imr3", 820, R8A7795_CLK_S2D1),
++ DEF_MOD("imr2", 821, R8A7795_CLK_S2D1),
++ DEF_MOD("imr1", 822, R8A7795_CLK_S2D1),
++ DEF_MOD("imr0", 823, R8A7795_CLK_S2D1),
+ 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/media/platform/Kconfig b/drivers/media/platform/Kconfig
+index ba2b892..f4d12f5 100644
+--- a/drivers/media/platform/Kconfig
++++ b/drivers/media/platform/Kconfig
+@@ -315,6 +315,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 40b18d1..9e9464c 100644
+--- a/drivers/media/platform/Makefile
++++ b/drivers/media/platform/Makefile
+@@ -49,6 +49,7 @@ obj-$(CONFIG_SOC_CAMERA) += soc_camera/
+
+ obj-$(CONFIG_VIDEO_RENESAS_FCP) += rcar-fcp.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 */
+--
+1.9.1
+
diff --git a/meta-rcar-gen3-adas/recipes-kernel/linux/linux-renesas/0014-lib-swiotlb-reduce-verbosity.patch b/meta-rcar-gen3-adas/recipes-kernel/linux/linux-renesas/0014-lib-swiotlb-reduce-verbosity.patch
new file mode 100644
index 0000000..6cb5f65
--- /dev/null
+++ b/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/meta-rcar-gen3-adas/recipes-kernel/linux/linux-renesas/0015-gpio-max732x-fix-gpio-set.patch b/meta-rcar-gen3-adas/recipes-kernel/linux/linux-renesas/0015-gpio-max732x-fix-gpio-set.patch
new file mode 100644
index 0000000..c08c0ed
--- /dev/null
+++ b/meta-rcar-gen3-adas/recipes-kernel/linux/linux-renesas/0015-gpio-max732x-fix-gpio-set.patch
@@ -0,0 +1,29 @@
+From 75b9bdbafde96b6af222f96e47d7a4a260ed32df 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] 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 a9aaf9d..b6fc8c5 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,
+--
+1.9.1
+
diff --git a/meta-rcar-gen3-adas/recipes-kernel/linux/linux-renesas/0016-gpio-gpiolib-suppress-gpiod-warning.patch b/meta-rcar-gen3-adas/recipes-kernel/linux/linux-renesas/0016-gpio-gpiolib-suppress-gpiod-warning.patch
new file mode 100644
index 0000000..9a6ae18
--- /dev/null
+++ b/meta-rcar-gen3-adas/recipes-kernel/linux/linux-renesas/0016-gpio-gpiolib-suppress-gpiod-warning.patch
@@ -0,0 +1,29 @@
+From d5f7b238ab2b458876a50521f9c92487f4ba3226 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] 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 d407f904..06201ff 100644
+--- a/drivers/gpio/gpiolib.c
++++ b/drivers/gpio/gpiolib.c
+@@ -1945,7 +1945,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);
+--
+1.9.1
+
diff --git a/meta-rcar-gen3-adas/recipes-kernel/linux/linux-renesas/0017-media-soc_camera-add-legacy-VIN-CSI2.patch b/meta-rcar-gen3-adas/recipes-kernel/linux/linux-renesas/0017-media-soc_camera-add-legacy-VIN-CSI2.patch
new file mode 100644
index 0000000..9a349a0
--- /dev/null
+++ b/meta-rcar-gen3-adas/recipes-kernel/linux/linux-renesas/0017-media-soc_camera-add-legacy-VIN-CSI2.patch
@@ -0,0 +1,5055 @@
+From fd6f489456137d148132010c9da3251ba80f7948 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] 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 | 348 ---
+ arch/arm64/boot/dts/renesas/r8a7795.dtsi | 271 ---
+ arch/arm64/boot/dts/renesas/r8a7796.dtsi | 258 ---
+ drivers/media/platform/soc_camera/Kconfig | 26 +
+ 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 +
+ 8 files changed, 3873 insertions(+), 877 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 2bf5911..09e1284 100644
+--- a/arch/arm64/boot/dts/renesas/r8a7795-es1.dtsi
++++ b/arch/arm64/boot/dts/renesas/r8a7795-es1.dtsi
+@@ -1927,31 +1927,6 @@
+ clocks = <&cpg CPG_MOD 811>;
+ power-domains = <&sysc R8A7795_PD_ALWAYS_ON>;
+ 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>;
+- };
+- vin0csi21: endpoint@1 {
+- reg = <1>;
+- remote-endpoint= <&csi21vin0>;
+- };
+- vin0csi40: endpoint@2 {
+- reg = <2>;
+- remote-endpoint= <&csi40vin0>;
+- };
+- };
+- };
+ };
+
+ vin1: video@e6ef1000 {
+@@ -1961,31 +1936,6 @@
+ clocks = <&cpg CPG_MOD 810>;
+ power-domains = <&sysc R8A7795_PD_ALWAYS_ON>;
+ 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>;
+- };
+- vin1csi21: endpoint@1 {
+- reg = <1>;
+- remote-endpoint= <&csi21vin1>;
+- };
+- vin1csi40: endpoint@2 {
+- reg = <2>;
+- remote-endpoint= <&csi40vin1>;
+- };
+- };
+- };
+ };
+
+ vin2: video@e6ef2000 {
+@@ -1995,31 +1945,6 @@
+ clocks = <&cpg CPG_MOD 809>;
+ power-domains = <&sysc R8A7795_PD_ALWAYS_ON>;
+ 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>;
+- };
+- vin2csi21: endpoint@1 {
+- reg = <1>;
+- remote-endpoint= <&csi21vin2>;
+- };
+- vin2csi40: endpoint@2 {
+- reg = <2>;
+- remote-endpoint= <&csi40vin2>;
+- };
+- };
+- };
+ };
+
+ vin3: video@e6ef3000 {
+@@ -2029,31 +1954,6 @@
+ clocks = <&cpg CPG_MOD 808>;
+ power-domains = <&sysc R8A7795_PD_ALWAYS_ON>;
+ 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>;
+- };
+- vin3csi21: endpoint@1 {
+- reg = <1>;
+- remote-endpoint= <&csi21vin3>;
+- };
+- vin3csi40: endpoint@2 {
+- reg = <2>;
+- remote-endpoint= <&csi40vin3>;
+- };
+- };
+- };
+ };
+
+ vin4: video@e6ef4000 {
+@@ -2063,31 +1963,6 @@
+ clocks = <&cpg CPG_MOD 807>;
+ power-domains = <&sysc R8A7795_PD_ALWAYS_ON>;
+ 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>;
+- };
+- vin4csi21: endpoint@1 {
+- reg = <1>;
+- remote-endpoint= <&csi21vin4>;
+- };
+- vin4csi41: endpoint@3 {
+- reg = <3>;
+- remote-endpoint= <&csi41vin4>;
+- };
+- };
+- };
+ };
+
+ vin5: video@e6ef5000 {
+@@ -2097,31 +1972,6 @@
+ clocks = <&cpg CPG_MOD 806>;
+ power-domains = <&sysc R8A7795_PD_ALWAYS_ON>;
+ 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>;
+- };
+- vin5csi21: endpoint@1 {
+- reg = <1>;
+- remote-endpoint= <&csi21vin5>;
+- };
+- vin5csi41: endpoint@3 {
+- reg = <3>;
+- remote-endpoint= <&csi41vin5>;
+- };
+- };
+- };
+ };
+
+ vin6: video@e6ef6000 {
+@@ -2131,31 +1981,6 @@
+ clocks = <&cpg CPG_MOD 805>;
+ power-domains = <&sysc R8A7795_PD_ALWAYS_ON>;
+ 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>;
+- };
+- vin6csi21: endpoint@1 {
+- reg = <1>;
+- remote-endpoint= <&csi21vin6>;
+- };
+- vin6csi41: endpoint@3 {
+- reg = <3>;
+- remote-endpoint= <&csi41vin6>;
+- };
+- };
+- };
+ };
+
+ vin7: video@e6ef7000 {
+@@ -2165,31 +1990,6 @@
+ clocks = <&cpg CPG_MOD 804>;
+ power-domains = <&sysc R8A7795_PD_ALWAYS_ON>;
+ 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>;
+- };
+- vin7csi21: endpoint@1 {
+- reg = <1>;
+- remote-endpoint= <&csi21vin7>;
+- };
+- vin7csi41: endpoint@3 {
+- reg = <3>;
+- remote-endpoint= <&csi41vin7>;
+- };
+- };
+- };
+ };
+
+ csi2_20: csi2@fea80000 {
+@@ -2199,51 +1999,6 @@
+ clocks = <&cpg CPG_MOD 714>;
+ power-domains = <&sysc R8A7795_PD_ALWAYS_ON>;
+ 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>;
+- };
+- };
+- };
+ };
+
+ csi2_21: csi2@fea90000 {
+@@ -2253,51 +2008,6 @@
+ clocks = <&cpg CPG_MOD 713>;
+ power-domains = <&sysc R8A7795_PD_ALWAYS_ON>;
+ 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>;
+- };
+- };
+- };
+ };
+
+ csi2_40: csi2@feaa0000 {
+@@ -2307,35 +2017,6 @@
+ clocks = <&cpg CPG_MOD 716>;
+ power-domains = <&sysc R8A7795_PD_ALWAYS_ON>;
+ 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>;
+- };
+- };
+- };
+ };
+
+ csi2_41: csi2@feab0000 {
+@@ -2345,35 +2026,6 @@
+ clocks = <&cpg CPG_MOD 715>;
+ power-domains = <&sysc R8A7795_PD_ALWAYS_ON>;
+ status = "disabled";
+-
+- ports {
+- #address-cells = <1>;
+- #size-cells = <0>;
+-
+- port@1 {
+- #address-cells = <1>;
+- #size-cells = <0>;
+-
+- reg = <1>;
+-
+- csi41vin4: endpoint@4 {
+- reg = <4>;
+- remote-endpoint = <&vin4csi41>;
+- };
+- csi41vin5: endpoint@5 {
+- reg = <5>;
+- remote-endpoint = <&vin5csi41>;
+- };
+- csi41vin6: endpoint@6 {
+- reg = <6>;
+- remote-endpoint = <&vin6csi41>;
+- };
+- csi41vin7: endpoint@7 {
+- reg = <7>;
+- remote-endpoint = <&vin7csi41>;
+- };
+- };
+- };
+ };
+
+ sata: sata@ee300000 {
+diff --git a/arch/arm64/boot/dts/renesas/r8a7795.dtsi b/arch/arm64/boot/dts/renesas/r8a7795.dtsi
+index 94262a1..82ebfd4 100644
+--- a/arch/arm64/boot/dts/renesas/r8a7795.dtsi
++++ b/arch/arm64/boot/dts/renesas/r8a7795.dtsi
+@@ -1902,27 +1902,6 @@
+ clocks = <&cpg CPG_MOD 811>;
+ power-domains = <&sysc R8A7795_PD_ALWAYS_ON>;
+ 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 {
+@@ -1932,27 +1911,6 @@
+ clocks = <&cpg CPG_MOD 810>;
+ power-domains = <&sysc R8A7795_PD_ALWAYS_ON>;
+ 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 {
+@@ -1962,27 +1920,6 @@
+ clocks = <&cpg CPG_MOD 809>;
+ power-domains = <&sysc R8A7795_PD_ALWAYS_ON>;
+ 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 {
+@@ -1992,27 +1929,6 @@
+ clocks = <&cpg CPG_MOD 808>;
+ power-domains = <&sysc R8A7795_PD_ALWAYS_ON>;
+ 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 {
+@@ -2022,27 +1938,6 @@
+ clocks = <&cpg CPG_MOD 807>;
+ power-domains = <&sysc R8A7795_PD_ALWAYS_ON>;
+ 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 {
+@@ -2052,27 +1947,6 @@
+ clocks = <&cpg CPG_MOD 806>;
+ power-domains = <&sysc R8A7795_PD_ALWAYS_ON>;
+ 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 {
+@@ -2082,27 +1956,6 @@
+ clocks = <&cpg CPG_MOD 805>;
+ power-domains = <&sysc R8A7795_PD_ALWAYS_ON>;
+ 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 {
+@@ -2112,27 +1965,6 @@
+ clocks = <&cpg CPG_MOD 804>;
+ power-domains = <&sysc R8A7795_PD_ALWAYS_ON>;
+ 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>;
+- };
+- };
+- };
+ };
+
+ csi2_20: csi2@fea80000 {
+@@ -2142,51 +1974,6 @@
+ clocks = <&cpg CPG_MOD 714>;
+ power-domains = <&sysc R8A7795_PD_ALWAYS_ON>;
+ 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>;
+- };
+- };
+- };
+ };
+
+ csi2_40: csi2@feaa0000 {
+@@ -2196,35 +1983,6 @@
+ clocks = <&cpg CPG_MOD 716>;
+ power-domains = <&sysc R8A7795_PD_ALWAYS_ON>;
+ 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>;
+- };
+- };
+- };
+ };
+
+ csi2_41: csi2@feab0000 {
+@@ -2234,35 +1992,6 @@
+ clocks = <&cpg CPG_MOD 715>;
+ power-domains = <&sysc R8A7795_PD_ALWAYS_ON>;
+ status = "disabled";
+-
+- ports {
+- #address-cells = <1>;
+- #size-cells = <0>;
+-
+- port@1 {
+- #address-cells = <1>;
+- #size-cells = <0>;
+-
+- reg = <1>;
+-
+- csi41vin4: endpoint@4 {
+- reg = <4>;
+- remote-endpoint = <&vin4csi41>;
+- };
+- csi41vin5: endpoint@5 {
+- reg = <5>;
+- remote-endpoint = <&vin5csi41>;
+- };
+- csi41vin6: endpoint@6 {
+- reg = <6>;
+- remote-endpoint = <&vin6csi41>;
+- };
+- csi41vin7: endpoint@7 {
+- reg = <7>;
+- remote-endpoint = <&vin7csi41>;
+- };
+- };
+- };
+ };
+
+ sata: sata@ee300000 {
+diff --git a/arch/arm64/boot/dts/renesas/r8a7796.dtsi b/arch/arm64/boot/dts/renesas/r8a7796.dtsi
+index afdd69d..e653814 100644
+--- a/arch/arm64/boot/dts/renesas/r8a7796.dtsi
++++ b/arch/arm64/boot/dts/renesas/r8a7796.dtsi
+@@ -1592,27 +1592,6 @@
+ clocks = <&cpg CPG_MOD 811>;
+ power-domains = <&sysc R8A7796_PD_ALWAYS_ON>;
+ 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 {
+@@ -1622,27 +1601,6 @@
+ clocks = <&cpg CPG_MOD 810>;
+ power-domains = <&sysc R8A7796_PD_ALWAYS_ON>;
+ 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 {
+@@ -1652,27 +1610,6 @@
+ clocks = <&cpg CPG_MOD 809>;
+ power-domains = <&sysc R8A7796_PD_ALWAYS_ON>;
+ 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 {
+@@ -1682,27 +1619,6 @@
+ clocks = <&cpg CPG_MOD 808>;
+ power-domains = <&sysc R8A7796_PD_ALWAYS_ON>;
+ 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 {
+@@ -1712,27 +1628,6 @@
+ clocks = <&cpg CPG_MOD 807>;
+ power-domains = <&sysc R8A7796_PD_ALWAYS_ON>;
+ 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 {
+@@ -1742,27 +1637,6 @@
+ clocks = <&cpg CPG_MOD 806>;
+ power-domains = <&sysc R8A7796_PD_ALWAYS_ON>;
+ 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 {
+@@ -1772,27 +1646,6 @@
+ clocks = <&cpg CPG_MOD 805>;
+ power-domains = <&sysc R8A7796_PD_ALWAYS_ON>;
+ 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 {
+@@ -1802,27 +1655,6 @@
+ clocks = <&cpg CPG_MOD 804>;
+ power-domains = <&sysc R8A7796_PD_ALWAYS_ON>;
+ 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>;
+- };
+- };
+- };
+ };
+
+ csi2_20: csi2@fea80000 {
+@@ -1832,51 +1664,6 @@
+ clocks = <&cpg CPG_MOD 714>;
+ power-domains = <&sysc R8A7796_PD_ALWAYS_ON>;
+ 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>;
+- };
+- };
+- };
+ };
+
+ csi2_40: csi2@feaa0000 {
+@@ -1886,51 +1673,6 @@
+ clocks = <&cpg CPG_MOD 716>;
+ power-domains = <&sysc R8A7796_PD_ALWAYS_ON>;
+ 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>;
+- };
+- };
+- };
+ };
+
+ vcplf: vcp4@fe910000 {
+diff --git a/drivers/media/platform/soc_camera/Kconfig b/drivers/media/platform/soc_camera/Kconfig
+index 86d7478..17178ad 100644
+--- a/drivers/media/platform/soc_camera/Kconfig
++++ b/drivers/media/platform/soc_camera/Kconfig
+@@ -17,6 +17,32 @@ 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
++ ---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
++ ---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 7633a0f..8c7ede6 100644
+--- a/drivers/media/platform/soc_camera/Makefile
++++ b/drivers/media/platform/soc_camera/Makefile
+@@ -8,3 +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_ATMEL_ISI) += atmel-isi.o
+ 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
+--
+1.9.1
+
diff --git a/meta-rcar-gen3-adas/recipes-kernel/linux/linux-renesas/0018-arm64-renesas-r8a7797-Add-Renesas-R8A7797-SoC-suppor.patch b/meta-rcar-gen3-adas/recipes-kernel/linux/linux-renesas/0018-arm64-renesas-r8a7797-Add-Renesas-R8A7797-SoC-suppor.patch
new file mode 100644
index 0000000..d6726a3
--- /dev/null
+++ b/meta-rcar-gen3-adas/recipes-kernel/linux/linux-renesas/0018-arm64-renesas-r8a7797-Add-Renesas-R8A7797-SoC-suppor.patch
@@ -0,0 +1,5132 @@
+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 | 6 +
+ arch/arm64/boot/dts/renesas/r8a7797.dtsi | 1002 ++++++++++
+ drivers/clk/renesas/Kconfig | 1 +
+ drivers/clk/renesas/Makefile | 1 +
+ drivers/clk/renesas/r8a7797-cpg-mssr.c | 222 +++
+ 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 | 2586 +++++++++++++++++++++++++
+ 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, 4281 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..d3b6771 100644
+--- a/arch/arm64/Kconfig.platforms
++++ b/arch/arm64/Kconfig.platforms
+@@ -166,6 +166,12 @@ config ARCH_R8A77965
+ help
+ This enables support for the Renesas R-Car M3N SoC.
+
++config ARCH_R8A7797
++ bool "Renesas R-Car V3M SoC Platform"
++ 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..6eaa5ba
+--- /dev/null
++++ b/arch/arm64/boot/dts/renesas/r8a7797.dtsi
+@@ -0,0 +1,1002 @@
++/*
++ * 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";
++ };
++ };
++
++ 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,thermal-r8a7797";
++ reg = <0 0xe6190000 0 0x5c>;
++ 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..29dfe4a
+--- /dev/null
++++ b/drivers/clk/renesas/r8a7797-cpg-mssr.c
+@@ -0,0 +1,222 @@
++/*
++ * 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("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("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..9b6127f
+--- /dev/null
++++ b/drivers/pinctrl/sh-pfc/pfc-r8a7797.c
+@@ -0,0 +1,2586 @@
++/*
++ * 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,
++};
++
++/* - 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(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 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(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..b71bdedb
+--- /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_ALWAYS_ON },
++ { "a2ir1", 0x400, 1, R8A7797_PD_A2IR1, R8A7797_PD_A2IR0 },
++ { "a2ir2", 0x400, 2, R8A7797_PD_A2IR2, R8A7797_PD_A2IR0 },
++ { "a2ir3", 0x400, 3, R8A7797_PD_A2IR3, R8A7797_PD_A2IR0 },
++ { "a2sc0", 0x400, 4, R8A7797_PD_A2SC0, R8A7797_PD_ALWAYS_ON },
++ { "a2sc1", 0x400, 5, R8A7797_PD_A2SC1, R8A7797_PD_A2SC0 },
++};
++
++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/meta-rcar-gen3-adas/recipes-kernel/linux/linux-renesas/0019-Revert-media-v4l2-async-remove-unneeded-.registered_.patch b/meta-rcar-gen3-adas/recipes-kernel/linux/linux-renesas/0019-Revert-media-v4l2-async-remove-unneeded-.registered_.patch
new file mode 100644
index 0000000..72c22f5
--- /dev/null
+++ b/meta-rcar-gen3-adas/recipes-kernel/linux/linux-renesas/0019-Revert-media-v4l2-async-remove-unneeded-.registered_.patch
@@ -0,0 +1,54 @@
+From 050637736af144f4bfb096f5f47120c477349732 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] Revert "[media] v4l2-async: remove unneeded .registered_async
+ callback"
+
+This reverts commit a53d2f299dc83340c695e153363a2f21641d5f58.
+---
+ drivers/media/v4l2-core/v4l2-async.c | 7 +++++++
+ include/media/v4l2-subdev.h | 3 +++
+ 2 files changed, 10 insertions(+)
+
+diff --git a/drivers/media/v4l2-core/v4l2-async.c b/drivers/media/v4l2-core/v4l2-async.c
+index 5bada20..a4b224d 100644
+--- a/drivers/media/v4l2-core/v4l2-async.c
++++ b/drivers/media/v4l2-core/v4l2-async.c
+@@ -119,6 +119,13 @@ static int v4l2_async_test_notify(struct v4l2_async_notifier *notifier,
+ return ret;
+ }
+
++ ret = v4l2_subdev_call(sd, core, registered_async);
++ if (ret < 0 && ret != -ENOIOCTLCMD) {
++ if (notifier->unbind)
++ notifier->unbind(notifier, sd, asd);
++ return ret;
++ }
++
+ if (list_empty(&notifier->waiting) && notifier->complete)
+ return notifier->complete(notifier);
+
+diff --git a/include/media/v4l2-subdev.h b/include/media/v4l2-subdev.h
+index cf778c5..269904d 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);
+ };
+
+ /**
+--
+1.9.1
+
diff --git a/meta-rcar-gen3-adas/recipes-kernel/linux/linux-renesas/0020-ti-st-add-device-tree-support.patch b/meta-rcar-gen3-adas/recipes-kernel/linux/linux-renesas/0020-ti-st-add-device-tree-support.patch
new file mode 100644
index 0000000..fff9a40
--- /dev/null
+++ b/meta-rcar-gen3-adas/recipes-kernel/linux/linux-renesas/0020-ti-st-add-device-tree-support.patch
@@ -0,0 +1,236 @@
+From 36122fec4390663b5c05d5836beb977ba2c09a68 Mon Sep 17 00:00:00 2001
+From: Eyal Reizer <eyalr@ti.com>
+Date: Thu, 23 May 2013 17:11:14 +0300
+Subject: [PATCH 099/104] 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 71b6455..a36db89 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
+@@ -464,7 +467,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 */
+@@ -524,12 +532,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);
+@@ -721,13 +734,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;
+@@ -808,9 +861,16 @@ err_core_init:
+ 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
+@@ -828,12 +888,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);
+@@ -843,7 +913,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);
+@@ -860,6 +937,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);
+ }
+--
+1.7.10.4
+
diff --git a/meta-rcar-gen3-adas/recipes-kernel/linux/linux-renesas/0021-btwilink-add-minimal-device-tree-support.patch b/meta-rcar-gen3-adas/recipes-kernel/linux/linux-renesas/0021-btwilink-add-minimal-device-tree-support.patch
new file mode 100644
index 0000000..b628784
--- /dev/null
+++ b/meta-rcar-gen3-adas/recipes-kernel/linux/linux-renesas/0021-btwilink-add-minimal-device-tree-support.patch
@@ -0,0 +1,54 @@
+From ce021cc0ed5fe1f8068edb41996d05ebe5e11954 Mon Sep 17 00:00:00 2001
+From: Eyal Reizer <eyalr@ti.com>
+Date: Thu, 23 May 2013 17:15:21 +0300
+Subject: [PATCH 100/104] 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 24a652f..a369bf7 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"
+@@ -273,6 +274,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)
+ {
+ static struct ti_st *hst;
+@@ -336,6 +345,7 @@ static struct platform_driver btwilink_driver = {
+ .remove = bt_ti_remove,
+ .driver = {
+ .name = "btwilink",
++ .of_match_table = of_match_ptr(btwilink_of_match),
+ },
+ };
+
+--
+1.7.10.4
+
diff --git a/meta-rcar-gen3-adas/recipes-kernel/linux/linux-renesas/0022-ASoC-Modify-check-condition-of-multiple-bindings-of-.patch b/meta-rcar-gen3-adas/recipes-kernel/linux/linux-renesas/0022-ASoC-Modify-check-condition-of-multiple-bindings-of-.patch
new file mode 100644
index 0000000..d979a41
--- /dev/null
+++ b/meta-rcar-gen3-adas/recipes-kernel/linux/linux-renesas/0022-ASoC-Modify-check-condition-of-multiple-bindings-of-.patch
@@ -0,0 +1,48 @@
+From 2fc4f16b075264fae016ea3db1f1f81d30cb0ab6 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] 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 files changed, 6 insertions(+), 0 deletions(-)
+
+diff --git a/sound/soc/soc-core.c b/sound/soc/soc-core.c
+index 16369ca..899d013 100644
+--- a/sound/soc/soc-core.c
++++ b/sound/soc/soc-core.c
+@@ -1373,7 +1373,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);
+@@ -3049,7 +3050,8 @@ int snd_soc_register_component(struct device *dev,
+ goto err_free;
+
+ cmpnt->ignore_pmdown_time = true;
+- cmpnt->registered_as_component = true;
++ if (num_dai == 1)
++ cmpnt->registered_as_component = true;
+
+ ret = snd_soc_register_dais(cmpnt, dai_drv, num_dai, true);
+ if (ret < 0) {
+--
+1.7.10.4
diff --git a/meta-rcar-gen3-adas/recipes-kernel/linux/linux-renesas/0023-ASoC-add-dummy-Si468x-driver.patch b/meta-rcar-gen3-adas/recipes-kernel/linux/linux-renesas/0023-ASoC-add-dummy-Si468x-driver.patch
new file mode 100644
index 0000000..fa27dc1
--- /dev/null
+++ b/meta-rcar-gen3-adas/recipes-kernel/linux/linux-renesas/0023-ASoC-add-dummy-Si468x-driver.patch
@@ -0,0 +1,123 @@
+From 8829efb30ecbecde33a266ddaed25a74cebbbaf2 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 103/104] 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 4d82a58..264fe79 100644
+--- a/sound/soc/codecs/Kconfig
++++ b/sound/soc/codecs/Kconfig
+@@ -588,6 +588,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 0f548fd3..71a6c2f 100644
+--- a/sound/soc/codecs/Makefile
++++ b/sound/soc/codecs/Makefile
+@@ -116,6 +116,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
+@@ -328,6 +329,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_SSM2518) += snd-soc-ssm2518.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");
+--
+1.7.10.4
+
diff --git a/meta-rcar-gen3-adas/recipes-kernel/linux/linux-renesas/0024-wl18xx-do-not-invert-IRQ-on-WLxxxx-side.patch b/meta-rcar-gen3-adas/recipes-kernel/linux/linux-renesas/0024-wl18xx-do-not-invert-IRQ-on-WLxxxx-side.patch
new file mode 100644
index 0000000..f956c58
--- /dev/null
+++ b/meta-rcar-gen3-adas/recipes-kernel/linux/linux-renesas/0024-wl18xx-do-not-invert-IRQ-on-WLxxxx-side.patch
@@ -0,0 +1,48 @@
+From 60d86113a92ac35421865f9b8db504530962c829 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] 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 ae47c79..cdde6e0 100644
+--- a/drivers/net/wireless/ti/wl18xx/main.c
++++ b/drivers/net/wireless/ti/wl18xx/main.c
+@@ -876,7 +876,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);
+@@ -929,6 +931,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);
+@@ -948,6 +955,7 @@ static int wl18xx_pre_upload(struct wl1271 *wl)
+
+ ret = wlcore_set_partition(wl, &wl->ptable[PART_PHY_INIT]);
+ }
++#endif
+
+ out:
+ return ret;
+--
+1.7.10.4
+
diff --git a/meta-rcar-gen3-adas/recipes-kernel/linux/linux-renesas/0025-drm-adv7511-Enable-HPD-interrupts-to-support-hotplug.patch b/meta-rcar-gen3-adas/recipes-kernel/linux/linux-renesas/0025-drm-adv7511-Enable-HPD-interrupts-to-support-hotplug.patch
new file mode 100644
index 0000000..dc29695
--- /dev/null
+++ b/meta-rcar-gen3-adas/recipes-kernel/linux/linux-renesas/0025-drm-adv7511-Enable-HPD-interrupts-to-support-hotplug.patch
@@ -0,0 +1,46 @@
+From 0ec0f782c0d19b1e1293e8e281c335186ce3f3cc 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] 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 | 6 +++---
+ 1 file changed, 3 insertions(+), 3 deletions(-)
+
+diff --git a/drivers/gpu/drm/bridge/adv7511/adv7511_drv.c b/drivers/gpu/drm/bridge/adv7511/adv7511_drv.c
+index a104b43..e20f475 100644
+--- a/drivers/gpu/drm/bridge/adv7511/adv7511_drv.c
++++ b/drivers/gpu/drm/bridge/adv7511/adv7511_drv.c
+@@ -55,7 +55,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 },
+@@ -369,7 +369,7 @@ static void adv7511_power_on(struct adv7511 *adv7511)
+ * Still, let's be safe and stick to the documentation.
+ */
+ regmap_write(adv7511->regmap, ADV7511_REG_INT_ENABLE(0),
+- ADV7511_INT0_EDID_READY);
++ ADV7511_INT0_EDID_READY | ADV7511_INT0_HPD);
+ regmap_write(adv7511->regmap, ADV7511_REG_INT_ENABLE(1),
+ ADV7511_INT1_DDC_ERROR);
+ }
+@@ -575,7 +575,7 @@ static int adv7511_get_modes(struct adv7511 *adv7511,
+ ADV7511_POWER_POWER_DOWN, 0);
+ if (adv7511->i2c_main->irq) {
+ regmap_write(adv7511->regmap, ADV7511_REG_INT_ENABLE(0),
+- ADV7511_INT0_EDID_READY);
++ ADV7511_INT0_EDID_READY | ADV7511_INT0_HPD);
+ regmap_write(adv7511->regmap, ADV7511_REG_INT_ENABLE(1),
+ ADV7511_INT1_DDC_ERROR);
+ }
+--
+1.9.1
+
diff --git a/meta-rcar-gen3-adas/recipes-kernel/linux/linux-renesas/0026-drm-adv7511-add-polling-mode-when-no-irq-available.patch b/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 0000000..3adfa21
--- /dev/null
+++ b/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/meta-rcar-gen3-adas/recipes-kernel/linux/linux-renesas/0027-usb-host-xhci-plat-add-firmware-for-the-R-Car-M3-W-x.patch b/meta-rcar-gen3-adas/recipes-kernel/linux/linux-renesas/0027-usb-host-xhci-plat-add-firmware-for-the-R-Car-M3-W-x.patch
new file mode 100644
index 0000000..dc79798
--- /dev/null
+++ b/meta-rcar-gen3-adas/recipes-kernel/linux/linux-renesas/0027-usb-host-xhci-plat-add-firmware-for-the-R-Car-M3-W-x.patch
@@ -0,0 +1,179 @@
+From b0668886def608d352cd0263a7ef04e64e25574a Mon Sep 17 00:00:00 2001
+From: Yoshihiro Shimoda <yoshihiro.shimoda.uh@renesas.com>
+Date: Tue, 12 Apr 2016 16:28:44 +0900
+Subject: [PATCH] usb: host: xhci-plat: add firmware for the R-Car M3-W xHCI
+ controllers
+
+This patch adds a firmware for the USB 3.0 host controllers of Renesas
+R-Car M3-W SoC.
+
+ - This firmware is possible to be used on R-Car H2 and M2. However,
+ this version causes performance degradation on such SoCs.
+ - This firmware is impossible to be used on R-Car H3 because data
+ transfer might not work correctly.
+
+So, we would like to keep the v1 and v2 firmware.
+
+Signed-off-by: Yoshihiro Shimoda <yoshihiro.shimoda.uh@renesas.com>
+Signed-off-by: Kyle McMartin <kyle@kernel.org>
+---
+ firmware/WHENCE | 3 ++-
+ firmware/r8a779x_usb3_v3.dlmem | Bin 0 -> 9472 bytes
+ 2 files changed, 2 insertions(+), 1 deletion(-)
+ create mode 100644 r8a779x_usb3_v3.dlmem
+
+diff --git a/firmware/WHENCE b/firmware/WHENCE
+index c2d83f4..02b46c7 100644
+--- a/firmware/WHENCE
++++ b/firmware/WHENCE
+@@ -2922,10 +2922,11 @@ Licence:
+
+ --------------------------------------------------------------------------
+
+-Driver: xhci-rcar -- Renesas R-Car H2/M2/H3 USB 3.0 host controller driver
++Driver: xhci-rcar -- Renesas R-Car Gen2/3 USB 3.0 host controller driver
+
+ File: r8a779x_usb3_v1.dlmem
+ File: r8a779x_usb3_v2.dlmem
++File: r8a779x_usb3_v3.dlmem
+
+ Licence: Redistributable. See LICENCE.r8a779x_usb3 for details.
+
+diff --git a/firmware/r8a779x_usb3_v3.dlmem b/firmware/r8a779x_usb3_v3.dlmem
+new file mode 100644
+index 0000000000000000000000000000000000000000..eac36a96bee1a8614eef9caa88e5a9de136af30c
+GIT binary patch
+literal 9472
+zcmai44O~=J+J9z-JD0DE%!QeY<mgB<W~{cz`bjBB=$cutpn@Ny@*$Ox*>2nRwwB{K
+zD4Ci1rfYs>HkeYmO5m31jV34~)&K>O6o(P~7+pbD-BR(s|8ob#ecSi9{C@v?&b{~C
+z=R9BMInQ~9;u*j3Mp7NIzY7#;Wi4;XjLuOsWLNsr{b*C7mr~CYucqgTozEhh{^R~y
+z;vS+T2HOp?$LiOfB6?v)tUmHIQGg^i{2qOuk!V3ieSzE5L0Y{>@tLiXt@SPOBxf;E
+zcrN-@$=L9oxZiARx2;Ij7m}7V@vjlZ%gTD4C)LZbUMqSBIZC^3^pDz$QG`+K+il|K
+zoUE)CDx}B;>vpN(*eD`dshO-vOVTf;lBi+&&3%Xx^|@h0OUc1_f4i^UdWA?Am#Du6
+zN-vUarO`e}U&H23NYn>vw6vJa9UQ0O#=ag%y4R9SWH%TEW028$gSvva0iw=m`=i-@
+z|0oUh7jq>;W}<!^zFI`dn3L&8e?eA4h1W7P#JG_8V8Lp#NU?g_s_0f3a`}OhR)1M}
+zL$KbkNSYBk&LKV}a>k{QXrMIFP-14!wKIal-C~6yJ8`HKY|@a<Xw7&~@}_>l<?=QO
+zdIY^I_*2JZ43+#duTbaq;Qg%3;F-(B{etJ>dci7j(9}uJ-_~}8Ol5ox(>FZatD9fi
+zHHEJcG-8TWD>&P0g)CnS=N58&wL+&*X0$643HCADmA#SI1-oL>RN|VTE#vIUe4Sl6
+z5LwA-U^}hkOso~U#&n*J(UYOLSUZM2Z8Tl4XB@COWn~lWTcwV^g1dx%va;gtlT+}<
+z(E)a4XTX5?FO@@gWM$#qcjeHR(BKd+8fE2ZGHla8MoYSKb+SQYWRfyJvu@Wk99u~k
+z`FTUG)Db8vv3I|>li#0iYyDm)D`9uv<zn83fI<3Js}?+6FndxvG0PQg52q>J-;UP#
+zebKXWzJ^Kmicyo6l2If0rE7^}d{Et6;vR6sc&$}!P$0f9ShrKdF^PF=aEe{=QvLI?
+z5<ST(T|D6wYr99U!<>WqTP01yCir>9m)ZtKZwustPX^?o?;pR1)71GTUI$yVc}{Yk
+z+JjgbP5o`{`yGk;X7I^Y412d{gs0Xwf@x%#__NI^{Ugw0IB3)OZ18h!a|P8K&2cNh
+z*RDobScrv}KYU(;H53z|r6sU>6<4wHvxXvJypMUAHf@=R`O|zCPqZ;_`8lxS?a&5K
+zZ4+jnZLuqEU6NjjQ@u-F;|oEBt#MiT9i(eE_V|GdewHO3G&-eOtsX<CAS<28w)W@k
+ziTcg>0=#eU({OA6Q3_wH`g4JJk*j#1q`|JNr}_!D_Rk?@g*wuc>c-stql(62J+(p?
+z0*fNe5w`ZPFy?|fhWU2UQ1-r1jUZEFSY&!b?N3qrtJHpjRaSmdW!A(WR-U}WzE}o|
+zer}uKUw*DC-U|gMgVgojD{DIE_YPUfhOCQBOjb1pwfBWwFX62&?zL`Da@-xe+9WHb
+zCKg?6?PexF-Y|VxC4YQrfgKqa%b<rbtxoYPthu#R*{y>k>S(_XRz+<XYiqBE)ShnY
+zwsynvMEzxTj7$0_vpl|@gcVk*b>co-blCjQtIV>JKOxv7E8~XQ+FL*)M$h=LwO>X5
+zA+;|nuf}^?I-%|42`om-%C#Y|_B}Gr#JFA=^Ki#(50CaCHgOd^`QW1_wsvP4lhVT}
+z*f0y4ik5n%-_$+pCk2UmS9hOjucVu@tUP(o=x@{!J#lz|2+El}B6kSlH~L+i5pnbe
+zUF3{BYa2MD-slk52?G$vxdyfi`u}Y08q5*N`z2=k!(~KxE%t}O-OmQ%{cyGK_uzqa
+zSgF2cG1c(a8=v*DN7~aBW!ZGc^yQHjQ$Moahzi^n5s<cjnocZ<_%uQ@yL3+3v}Ku=
+z^dsb$ZkfAQvpmx>H<z551=CjqtPHTE-=so3AEJ39a~0Z1dJ|*Ib*rayX`82QnWoR)
+zniI5e+jHCJyf<yfwD)s@XYZV2nHx?Y%+bzv%_*9*E8@e5-4T1{6wmo6;^T-<BKA)E
+z%bX;Aq8f1_w<pDD*{F1+85}0kO@PM3qS#upwLbyx2oCi7+wQ1;^;avNGh4b4F|x!}
+z*vq+wt>Sk^#G*h|dt#6Fh{lUgiyOQABldGC{67$R18wk1cvYsY*SasObFpzr>7<)%
+zaD$gY(YWt&h%Mdgd|lTDq4$g3>KDwyy(>xX=1f**4)Ub3$kRMXR-zv0{i^xyS9X3N
+z)>7Dmp41YIJ09Dk6<hl-WFYz=CcEF4bL0J%ZCOlpEV9iAR3qfkIGwh6xXvn-`Lq|R
+ze4Bl4QzCgUx<{Ng4IuBxP^uWFmrCCmG;-fNjp9}@OT22X<8l!3-NqvG7&VgSW0oa|
+zv;MgHs(M$fR}{CPsVfp5J|9Gh`nBp)wx5op@xIgPiIkFYz*k?Hgj@g?^y!SVjrY#K
+z>Tp)wP0rRn1{SPVrNByD%wmzgBX_1QqH*@t*^T16;z4LtV~4imCL8K(tY0N=7PV8|
+zX%(rl8F-UN_9>|jbBMk}sl{$~DFgfLyb-OBV=vH-_L@Qw0iGzRFnE9aU7wWrME&Ss
+zrm=2K(Ia|_DK56&aMAn=P94h`9LO2g2_-^3BKqd!dSnU1sR-AX={od(F1eD^B04vP
+zITMShYfK&2Zw$LX5ayKj5Tes*7EhQIuJ$5g^wt}5RH{XwXL^)fD;{N(!cr<Z9ll%}
+z=29s+1Y{h)VHrmNp5}%1aOiCRkX+|KBy+e{|97S3iDZf(6ZNHjG=O5rMuX{B^bifB
+z;WUa8Xe=esqx2X}gwJ$7S~M2)Q?8FdcA8Q-!mezh4Y(eswxM<<Qd5TOZcPEM9!<T?
+zuH4ZU;ku8zjx6aoR|(Hge|7_|u?yRfKLzMn7S&&00FU35&$QE-&!pM@Jd-AGQ6<Ot
+zb_>qL51|)TniM8YAf9d#TzGnW%z7r{4EEGAG8`P*k#{IqpC8h*;z#CW3Z_uHkHRP%
+zSCJxdH6a^)B}L|AC&>Ip-~bRaQRb6@?Gw3pnV%{w?WXX(O2G^o;h<qsDVQk=6as!L
+z^Uc7N$7KH1Nisifvdpgs9JpWdxE@r3yQygP=at$C$<Xga%x;E`2h#n}@&oiB^gNV)
+z4Nd=sM&Ruz8bc35-xDbj7>`*BAD8*ODKa1V1ZDx6fOnph`RM<W`RP+-{thraRpyTZ
+z(P=V2c$&;FoG$Z?fHqy`M*=&5Mqv0%nRm_N!P(-_9{Ju><?9Ri!oXiRAOew?dE#uD
+zuK+UV$h;ef&6N3+r=WR0zWeJe?7j|Tj(C-;6LLi_2b=Ljp0e|>0zZ6S5Jm=K<O;rJ
+zv2&Cm&}woz^cO09?u%^4CNI@ln_c{JWH7E#pYpOI=eI48l{<UPl7>!-+r(UPvvB&K
+zdh&AH&hw<HYxKV7{X!Cm(X##UH>~hdK}*fzd!lyqf0G8g+{d&vVw=uW>#%uRngp|C
+zM2whz>9n|A{91Hh9UyA3?-dz)Mw&B1s49H`jZgDQ<up&+7Gb?n%4;|sSMlfRVHJI*
+zhdrDqPz66dOozDlA@OmW;=fPWlJHFea^XPh$dAclN+MkcsB$)G+j8r;>0!Z1A(J@x
+z@^NmW8g~Y&UX+EswbPg@uCsL-^TcIludo5DApsdc->yn=gP1J3O*%@EBBcVXhIkEI
+z2bOs(KJ3!4bwF8_TrfQTV6Z<<BlnrNpSNCd@m9pCknl}v<f=~f7<LL;{Tbyd7YiLC
+zy4jPFkA%cmKE)zka;kTRd!#}k;opn4^JeE3=q*v-8OEY;N=A6#Dhhr^&})=~92Z|U
+zp>m-RUSWul-gUT5JY|WUV{=5`h~V%7(VeHGDnxnBZ122s%6+=8<jxLN$3EuEooALF
+zH?R}#UCCb7-IbF`dBw1~tK!+Acj=bEe~N{QtRd24zT{bToL<#+rO`4nf(|G4!Fo15
+zS1<U_C_DQ2Gbd(27da!AN3fO7@<8ic7mth-=ZZ0{%h7%`3SaX13!Rc7uoCCT9yxNv
+zPL6%MT&EG85k-jneI;v#Sz_nM7{)<r59c`RaJ_b^7n~VJiSh3<+~ht2UyMJj$c0O(
+z5PPZh>HWUC?9JJsCPm2-KZQ)|jn9gm!gFGs@Vr<8tF$W)L2LRu-hR!^!hX2r31<e@
+z#9XH%IJ{E)-jJ1D!ewV46#P3-fqhNdNu2g`cnx+4YsT}Jax$>vWxRMv*P)vMYu?Ar
+z;5lJhRl1H=rQ7MPX<>6>Fyi~U9;#Y2fP`6V<{VFZH|_0dp~%3p(#~?vrn$LbaN*+|
+z@ak{J^`Uysnz-Lrov<}Q7l-^dfKxR;3HcF=o&Roam(G>>>UoF+^Fy$<hXnS-kpDl*
+zj+>9DnkDmlfule|w#?548nZ(|!N>b4WZ^_uB4mqht{xF2DHkzkfq?f__q_LV+1(Ll
+z(gK;+=gIt{yfBQ}#oPIoaCYLa^i^DZjeo=O8vhos4%h&^3v2`4cj!GUiEqRn`J7oQ
+zaNIY#Uz|V6RAGf>=9l5RCLjJ34tk6E#w`?Bvzda9=sjDhA851a<-TZ+qXf%D3%oL3
+z-!JaI(a}kLCt-ie?-$3SmjB*Qbrsvu7P0u%cT#i`n~lvA^FkZ0=`XO^GGD-K$W3~=
+z@8PijV#eXvD^3TS!%xqLm=L{~(d(g=znIZFx|q?T7yX=P5z|BkxOH*vi-RSO_?d5#
+zcB(e6CT&w%@Hh>vq_y!`vv&^7ne8^`&MqF&gh-nO&E|*>VS%_48A>3$A-dqYjkUK6
+z%G9=b#dR~gcdaZl`@bmR7Kluu`GrN0bYbCj;a{IWQ^>emQ^>e0E$pcRu^i@J4!>;=
+zKwM>Xs@0LNzwufIr{+<s_!h-7@(?s#u{wB%tbDUNCxcZXWV8Wj524j#6|xZr&=2hH
+zm!KbvXRT;M(VjvZhPDZ9c=wp&=p#)prh`;MRmKZnGkpcXx*hWypDxewTsvdYMnT%i
+ztIZu*;lA@0?b!?+ot?*#PqJtiO#QLtQier)%HU2tJCCQ_@Jo1_-B@Kfn-N5L9-sQP
+z`y@`^tJ$~ajvrg**PN9?C@L<e(R;$8MP1BK86(eT2%y}jn{v}hM)^mTvZ04^4Wk@E
+zd5u1N8x`lSl@)O{o2BXG?a%jc{XV<3e-C%xKJ%3%8ejD;<yL*Q&4{X*c4|fH!Y>c&
+zP(AzWY2EnZ4fIU$)q=^$uvzx6mjd7m%w{aAWhLyN;U1ckP&?LZ%uQ%|B1>%Hyh0AH
+z4xw!Vsxz)iT=QKUaDB3<4H;nYuClTBjw%}=E9D<-z%|CzHWd1HmEpRvs9@;5qY7-Y
+zlKVj$^1sFp%5ZhM3UEy-syE&{itT^a56W=e`#}M&ajtp}`#@0<DlGmTa3DFQulk@u
+zf@uC(pJ(F=b@0`XtdgP2$xhS*0=v3*$_}=3;N*fF{gjdA=xR-{e3^LhJdyt-Q%+^(
+zerm1f;5We+JQqt)`LQcIXzVBrjXA?=J|>fv{zO@bpr?P(Q3>iy8-(#*MhSFKz4ErK
+zZ1e9>$ru@h(_u7fi%JJu+iG<P=X_L$x@$}2)Ye^Fn*2?$$J62!`eD8}dIa<N&q6Ce
+zWeMgh`9*c<+cts*l<>^xL5Mf8dJVF*9Q3{y-xMbslF~)&Pd-5_PLxn{`8R*8nr*#d
+z73?~T=@c!C(29<T<+@z{L7^~0Bfb&As*x?^Y;Os2oo@*;hd(WDu_aR=g&;dLAS;w8
+z8u_bTS%h<&UD0aU+E1yu4jZklsl=6PHy~>ntz~QfPAyyex9gmVEkRxWEIrSkrL*|i
+zq;cVSclQ2A|MMg~cWazdOOVG<f-~R8ddLcnSQgb1#CC~JHBPZPhEN+uY$P_vslUm}
+zzB*?HxR%Zac~k4)6^DXc5k;uF`A_@cui9^~t3&;kx(p5Zt1y4K6&$xltTj8OtW1_Y
+zxx4(mX2pxj)*o&i`!!LUP{F6%>Ur+&>UmzVGUb+^UP4sQ39t|`&OcYn^H%Boa+Zfp
+zHf+X;b08`OsC{m{zo8B_yxw;^pVF}!P5Ch6RO4hr$qYZmHK5qT;TlvJe#xH?`Odam
+zZha`-yl&n2hg)@jA*y&gw_Kg!J;EBP#jbi2zaMB4C|NsMRxS_IVwZ0TvPxOy4)HtG
+zBwB*XP-&;~*<)vp2v0t&9O|-~ZU?fg)?zA0z1?CW3um-RpDeSEJQT$8Ti$qB*?x19
+zTDkUH#$)huxyY;*U=P^<FL<e%+5ccQv&}fzCbG8IHYGSIu!`Yh<;QsF;1_lp`~$Op
+zp4fz(?+Mh{*7s$4wY8_Bzg_M7&#<h1@l2glG6o}Z2&}fiVilYHcpaO4=P@?>lH)z`
+z0#)DOU%{Ich0-23WMijG+89TjhV^KNq4j_3InKT<uV>#jpgPaI2iYCIr8M_k<j#7#
+z;xlf-j=A5+d~unuQ+NUS9rOKw1~z+S1EXMVU=(5-7zLNq2RtrQ$6p1HFZi{@$27?N
+zBw!Ix*uYjEi)w5pEoS*y@N!!H>&nG$sbrPzQI+lml`b30Mxx@#hn>*sm#V$E6FBpo
+z=;8W5OYA$r_}$vb_$_T@{4)J(((*(`*W0-CU+yQJWPHNEuTZ5KJLLA0=8-|L#6Gmx
+zQE@Ulf?i*>cMUz967Z}Py+LZvbJB0UUJ6Zk$AN;k`%MdeH(L_qKXa5o!>pb<^GCK;
+z3dGu>sH_wg7rWYD3`yY^hh(WWl^ma2Sm3J@@_b%_MWTJDm^HMgnKfLenRGW#vkKBK
+zawWbP(ly45>WXEg9hJ&-tn?Q{Jcd=>^%XYvBmZY^`;YLmOP<vA_^seB57mr^jL;N5
+zJ@nu6;PNsaZg?3F`_3{RQd$`gcfdnNXb%q*a9F9k?UXV?dwIx0^!<H^Is7?s%ZOy0
+z%KIR~8&Pk#kNTr(U`5R!78L_onR<GI&8}n;+e@2Hv%OT`%=XgE=6b~B+-4S;^P8DI
+z=nUiKcV`$cyU#FQ<TK3L{XEXZ-$Ng2{p4ML1SZX4CFypLja=X)%g1~?$G2aogO>do
+zzN1pKdKks|9!7DWhf$p0;_9XNMK?w5VdcuL9*WNPS)u<~wzX$_WotdlWJ_*kvh8kV
+zvemRQ*?wwevW2!W+0L~wP9~jWoXkDPIO#a&Oq>NhtFoQ$<|Od2l6#jE7dT<E)j_rv
+z0kNxFwz_kS;_Y*cV&DZvapna^arFgPFU2d}6vGcI;$4a?rmhg*6)YwT<)W{RXX~N$
+zimSaIo^tZ8r+j5BfhNBa{JNw|Y`#I4*nE30vH8TyY`(RZU5WKQ5-8pCSq>{ZZ@Q$D
+z@Rug_w?m?4{9-#KoRBLLZ3p@ph-L%HsMJpfcA<X-*oEae6}Sex96@xXn&>w0yT1|b
+z27-?gRRc$mB~|=D6jei%4NO8V@=z_t00DJGF99{c@MA=Gfb8S=?Hrg~kLN%<em{5>
+z@B#@Zh)RJejo6m}(@COdfL35+6Hy5e@FVyIoPY~x1Y+<j`c#1Zn*I&IeofB?RscJJ
+zgTPV13;YC#%|wHNaex!J1C*R0ItN61Knqv_90EGoeGAc6pau}V;NdKIMjM6J1;n-z
+z1%3lwfG58tS_rHF8i2ebL~-8{%?H*1M}TJFHZZt~C?8l0>;zhY!tXI2dQJmgX@l;4
+z;0suI31hII)c`lzF?R=1Xtb7|1o~eknh3m%{w`o#C-eqv2i&+n@(<`7xPyM!eOg*|
+zji^7``M~SfLFWee16Bb$ffC>p@G9Ql0Fr(tIsnYQ1Dz<)8EMGFY3K^_$rw}|vVm2=
+zPe5j%hPDG2f-ojTL(WhQT>~6~hIRm9VH%nblmbzGG?WJ{0$v6V0LOub{_xL%m@9_p
+z^8L^g5N9Lx?>O2i55SiAZK8BIQPl{dy(5Vp8U>67k3jes$OEhaZUfIG5N!gE0$~qh
+z955eP2;5+F&>nmQzB`uaIA9+~G$;|a#xDYKNze;m8joL5fmUGfqqtAO8km6f0PF^C
+z15+mwtp=KbwZBDw5-^$QW3>Cw-uo9dg~)?voscp2N%+qq@RpDERqz2E1e$=K0LPz*
+z>VTvrkd?upr8_{rs3oTpYq$Wm0;+(yD~M*Ugx-Lig`o8Y(ezdDI{-&}It6qBQ&wZG
+z0dwDie*yVxutwj;J#Y<}xEAvR{nnumtO51{H-XmmL_7WmHUO;efG$u7Q~{wIz$dT*
+z_;@4q`)8uhz-P%8=mikBV*N&FsdyWaWjpu=N`dJ2h+YR8fZ!eQF^s838~#2~I<Ow_
+z0&8|cwhuttg|R?v5z&xcSnt4+5AmM?Kr3L`4cb8D9@q$oFNQvVpFV>9K7n3<eL&h?
+z*a#^63z2poWCV)$6Lpl}{ileFr9_K?=rY(Bcm>!DR0B7FNe95wU!g<bozGy?NG-km
+z1$aG#IB^)yfK4)JeTj7ibOQ6s5i5Y1Um;!rVP8X^h@*vQYbtPG3A#Wba0F<LK>Uk@
+zet=y-Gtdc4G$Kv{>_3L4m_Qd;15^PWKz|AL1U3OO&<Z3(!S8`;AfYd4BIf6zT?14>
+Zzol-hJ3M=-8oCR|x&%(egRelM{{{cB@hkuU
+
+literal 0
+HcmV?d00001
+
+--
+1.9.1
+
diff --git a/meta-rcar-gen3-adas/recipes-kernel/linux/linux-renesas/0028-usb-host-xhci-rcar-update-firmware-for-R-Car-H3-and-.patch b/meta-rcar-gen3-adas/recipes-kernel/linux/linux-renesas/0028-usb-host-xhci-rcar-update-firmware-for-R-Car-H3-and-.patch
new file mode 100644
index 0000000..2068abc
--- /dev/null
+++ b/meta-rcar-gen3-adas/recipes-kernel/linux/linux-renesas/0028-usb-host-xhci-rcar-update-firmware-for-R-Car-H3-and-.patch
@@ -0,0 +1,206 @@
+From 7c3dfc0bb21bf717dc19a6b677a866aef8b70c35 Mon Sep 17 00:00:00 2001
+From: Yoshihiro Shimoda <yoshihiro.shimoda.uh@renesas.com>
+Date: Wed, 10 Aug 2016 19:56:39 +0900
+Subject: [PATCH] usb: host: xhci-rcar: update firmware for R-Car H3 and M3-W
+
+This patch updates the firmware files for R-Car H3 and M3-W to fix
+the device detection issue.
+
+The md5sum of the files are:
+645db7e9056029efa15f158e51cc8a11 r8a779x_usb3_v2.dlmem
+687d5d42f38f9850f8d5a6071dca3109 r8a779x_usb3_v3.dlmem
+
+Signed-off-by: Yoshihiro Shimoda <yoshihiro.shimoda.uh@renesas.com>
+Signed-off-by: Kyle McMartin <kyle@kernel.org>
+---
+ firmware/r8a779x_usb3_v2.dlmem | Bin 9472 -> 9416 bytes
+ firmware/r8a779x_usb3_v3.dlmem | Bin 9472 -> 9416 bytes
+ 2 files changed, 0 insertions(+), 0 deletions(-)
+
+diff --git a/firmware/r8a779x_usb3_v2.dlmem b/firmware/r8a779x_usb3_v2.dlmem
+index 7db71726f45943e7162d8e21ce7d80885bd79184..2b85222467e555a0f33002d1dad5ecf39da9d9b8 100644
+GIT binary patch
+delta 2698
+zcmY*b4Nz3q6~6b$zQ-=?!aiA+U3U4~T_YkEsUnEF2x#y(qNq_(0hRFwm1eAyrdn14
+zmQw3zZZKr3Mu#6Q<Cu!B%}{ciSg_WTksz!}6&Dp`)Cn~Lb&{CZa~2zuo%zl^_ug~9
+zbKZI9-nXv#SLOvbEN>YKAsqyN1LU^taBu?Mb$E82Fymk61`;UU#Z1Cv<He9+txE}|
+ztstihZk0>P8{<+q%NPDZ&zz4PGn>+@=ePOQP}LGYm(qNGtoV#hvmgKEw@dY<p@hyc
+zT>qF5u83hRuQhrcgNxpEin6~z_QKkUur#rRluG%;F=%o*#ffaHzcZFNyxEtmT*-0R
+zrcv0j!p?7e9(JS3leU74nXkWO;7SBL=5H<evu`K;Cp?#7ZA=12STfF=-L2w^XB=08
+zUwg&Z|AUuHipK0>z1fXm*ES(dbP|^@qsjZ7qE3yOdb68gFE<ghbxFO&q=U+t#^wHw
+zP{LBwa~!+CY7gl$q&}p?DVF+X4Wgo4($bDPZR$fctX8ucbt>&-ch%cy8e5==i+eA<
+z3raeL)PdYhh9N>vdaFuE<VuIG%vncXq;#k(DL6mNPHG%+x{Nw4SDG`>Qp{{sje(sC
+zU9HcuR2w6bpEooJDSoiJjy=_6Xdh+N%>;|g;i+7yWU~XN&Re{t3hElOwa?&E{6sg%
+z2(cV0dAz6#m>(4(|B>y;zivmX3YnU;WzJKOiH|=M`Tb$_5c^wzQT4VqO;p%yeRO1T
+zCYNI7aOoi6EWkXMOVa^I=Bg68l*PgWZMN@V?s=U{ne({xRu-3%=5whM@D9v(EfB#@
+zVEKU=D_sk?v~D4n0vCZDpaXDVF_+{wxU_Hymqq{+v$=E`ATQ-o)G{s=<Z!7S@Xc~A
+zO<KXFYCt<+;+tGLx=I4>&FtGiTllQiTxtg7tl?4<ASRbfGuFZrNfTI#Hay6_)+GfK
+z@LR8jHNrM%<D`p4eVe#4!m6}!w3&Ub{T21HR9z%(V{3G?4Poo??bTDP+4H<sl?JNQ
+z$j<4O(QlY4=wyIyTbI@`=zvZ-&CUh=jBaGTLHYD8mJ$3<n#8nvThN(xTxwYlx#R^v
+zOgnSxZIMZNP``XG)dMaA5(~Jr6wqD}2sZcFKD{9zc_Tc>CN0b_v6Fg3P}(LgeGe!s
+z)WO<u)~cTzE^f0L%S*$PEeW^eWAaA%DrA{c<OaE)>E*bL38Ez-JlULP%7QmtWJ$0Z
+zDH)xQ+E-$4?6~t^k(jc~X~=^N=AC^Y7w<%#99ANmri2z_oS9#hl_KA$?<43Xxfp%_
+z@3*lS{Vo@y-}7SDCNF+NE+2OICvat`-0d4Z`-iPKKl)p@wHs2-mm5`^d}+T~Q3uHs
+zR19l>x}H~or28w7^bFfF)>hKu(|7-F?@ATH16wKeDp5(zaLAhvXijj2AK0)`fZ0VD
+z{b0NRqew<A&Vug$Qf~lV1N*mO41}>0MjebDFb2Q0X#-s*q=7V%Msn3K@b^b{77${f
+z=`1?LNkdtFh>7~KUxTh;e+}7LBGk6d;mXF^Dv)#Q`rvp9_3oMZa<A&1b_2*#ts4&O
+zCpA?d&9!~;5Uth?@?c$g{Ew~59dI4h^ub|nuW^IiQ(F!)xvtCbV=Fw=mKrz6`kHc(
+z<Hg!8D3gwTY>1>o>>9`iY|s!*8<{@TNF!KmXe^!2mW9T{1MGv9gY3i5Q!_77Ed7l3
+zVW6mJZw2|hy$ZViImObCe2JwW>L_#es$ZnMhxbq+-V;$tQCKXt*J#u>(K2JN+N*Db
+zk4F(ZX^ak7LC~x73$C1IUl=3p6>WCos@#3@)0d}Z$S4q+xEF4JJUc>|Kr{(#N!Vh#
+zf_)UWOt2@ip|B`;27}2#JuKB^)t_m@Y`$(o-rc~vkZm!=#phka$c1t@@GdHKimOd{
+zpF0M#K`->_qjx%f15U8dO$IseI`VX1N1h9v_%&eN<_Ws6E?j=zh08h*i!x6dJHt~2
+zwOHuEja(0I6tH}=RlC~5B^RI`@EQBPIXZsCXCvM~o2VPeS!UE~1kt6ycSV|eLl8@R
+z+U6Tv+QDv_<4R&~B5UVO^muY})T38Tmln$CVZK!Y46o)cnBzCg{uODp!twFkvL>nF
+zi3VVV_MFZY(rryL`Lv0kMG^{YPhfYPPYdfFt-=os0g4P}DxffTvxDJgdWiigJU(vV
+zHopDocksDy-@yzMd+-lIJ*jp6BH%^JJ@{TlCAr9_%0WggHq|Hp#;V3zCXc;+4?QQ{
+zN6&%#=(&e&w-^P@3%1{qlu>b~%HdLS33jyHgB?Aq2Rr)xo-Sy;qdnMwwLRE?$#;>c
+z;Vu$+?;_F2T`W=#Q!GaMHZxkIO-Wv~$@QX5wHIv$yl7L+vaLp8+;?oNb<&zE_g{sy
+zJiw6eJiw6N2N=@74?`yOVaUurq>JcBI#)l^9qC89@ej+Ks{&v4{GHLBC;p!*N7*w-
+zLh}&4raVNiv;p)wG=N?$EIz^rr)*9{q+l6jg%J^^<i}{b?lGG7KStB}Ptf!VI|ioR
+z%pI{_-);~{%QZs6+6gHDEIIFpTtl<BLJwC1Mh0Q)KZJCG9%>dy#8X1%0%n1}12F4r
+zLN)`A11e#D<r)0t16&5(1E?G#q#wrd?8~S~ReCsFkZd^W1Nw;lA^LUe_waA&LMkCm
+zGYH9=2~hy9S%i#p5@Kdgqd!nz)C)wE1+t4Bjya|O47A2S64C>Zk3zz1p3O!Nu<f?L
+U&;jPKPot;VTKh+StJ4YjA4B_1P5=M^
+
+delta 2932
+zcmY*b4Ny~87QXMndyfQOfCnK22n3Q~714moimn6^6}6)H|3fP%vR3hLckAvtx}*ro
+zb{q%2i{0*4RwbZS$FT@@wQ{GE1y?)NA|;4aAVfg?sedhYw*qg^4OrUDeCM8b&-u<h
+z_vhT3>+`Jh{mv|(<O)Phi2nLepz*MunK^fOW(B*c|C2s5!<@rfHcoRsuwS&wK}<c!
+zX>1K=m9spo@+F+j{)g$lIM!n(!`Lrw@hoS!G*7EseKCOlj+wZ`zaR)Pv(-da1=o$K
+zYB4=sxX;2Xy;!st5&3j*GM|qMgluGbs<m2pBc9=9QG1!38Fn3!GfjqHF<{YwWfwl|
+z6_6htV$^Vh1yYv?ZA+1Kc(7C)^*Qa1n(~W?1o}M8bgWg;&WtvW$Q{u{4jwbg>iCIe
+z6(Ye;HP)F?1%A!rl6ecVx^s)$Z{c|btAwPT8CSrVgJTt|O?e6y?LiLp^!p65@Vnh#
+zXLwn*i%e66IQ_l?dQ0$G#dM|t-&bs5rsAc_n3%t(IA8@QqY99_P(MWLO{wSDcp|r{
+z3N00AFtLdXOQheI@W)D1Owg<fk;rwksHZBmp7Q`piOS~oED)o3H0jJ4HqjG$bMgO_
+zv&0v(DrSI3YX1}>AHnmyr%YP$PAM$sxXnFktL(|wfDGr0U`s0V91!_M9*tkNmB!EA
+zR?pE$cKnIATKhNAW;ulh5|7YPmeW!634X9dR@~`riuhwH5ys6X!co8_K-3%}qyWn1
+zaPdS~j14{pgXdf#bO7F*M}*yJL`a%Xgd>0g_};UC2R|i#$7j~c;sr#=eUk`*3&9W2
+z2KZ|_5keLbVcB9L3;`x*5aA{uWC;=8SW1M=%ZShlU{??!0dO493Yff#2)5M%#NL5D
+zL__GDHAJWbWUeKG9WXAF2&r#*fju726hnQ-zhxC*R>I_U3h48~Tf`WF<n?SM@(?~I
+z#xT|RhWMw*J}+a!IiwFtMjp=?wFhU?9NTA1TBcGad#7=*md$vBYNlGhj_ztDL)Q{z
+z*K<l(%PaV@YAN#qi@qnkgSI$C(^C^1r{nmt??fgKKk&_FcH;$pH<%=>_BZ%ezfFXO
+zb&zG2H)Jy&&-FKKNXmkh%_hQmz)irk^+Z?$XkG6EJ`aU_WYe5N+0repN?b45IR{6C
+z<Q$msMiJ~^{LJp+)=Mr9vJ=ua5`oVp!nRx$_*CLA{o_JaTXdSDg3zg9<~!0cDM$JO
+zW|5g!1M(2oN-<(QA7&1n8j`F{qbDRo(j-=HYyW{q+O&{l%A)>J+j~H+*iKoQ+mm^D
+zhgInE+mHCZ`iFH7c;^8mv=TWSpO7?RAv-AhH8XDqW!~IDnP?|&meLo66!n|D%tRh2
+zs&Tg+`}=kD+jgKv*9IwOOI6%PcbZwn6|f1Li~Gf2_HQbtK@Szvpw)P1fMIKcTmSQ4
+z_O9d*y?x#nx@3LARXEml2bIT(eC^<dl`MP_Xg#653N4R@JuZRnHKJF6t^|8Gv_8<@
+zg;oV^8?=5SKFyd39K+1VV*@Rr;Rhey*R#53-*ja)-qU!aVDpAn*KIvZWFNdQ(85Ug
+z-+|lLDQ)$$iJWIE1({ya1BI-tteKH5b#X3n1IPlg2Fm*L@=}mdww_oR&sGESXhl)%
+z&%KIFa7mT-K-ssJ*MKav6@g5~ht&ZA#_}2{`19pOAk8)htV|I8R2{(#;M*YY;vdwJ
+z+AG(Tea;6}YMt3CA4fCb9!~6}ms}8z3mVI$;I%=q+WFU%PG^@(3<DoC`Zf3rUxfSd
+ziJ(&^mZdwA+Sm`Hlr+|ZM7K(zIHt06M}}_E9T~t|H5yYJW3zNAMy{DZ3|}+Ju#$GB
+zP}8Mw`d7hIa}Iy3iS#~-DC_Q*M81F>nuwf|2BT(m=6llf*x{mjtYHxozZV%b@4ix+
+z4@tLlg_`V4mhY79gTq>f?Ba}N@4otaB0@c4osjzKb-#V^b${J~)K|mtrUkPI2M4D!
+zhwyKLm$HxJ@YP^Fa}~D-n<ke1m<FeZz8N-mmM$(wdI6`gKrDs1{=R|E@=62EHwp3$
+z#Bth~MQ?mXXOt_o!6mS;z``HV(s$7GGz0W9w@y#w@H@1rsZgU<!k&sv-0;rRxXn#8
+z?#Zud+&%cLcB0DJOnW|e(4H0t?$b^P@NA*3fi2WvY@vp6cx;GHjB0_p2W$fr<E0^y
+zvBd3j)9usOLLa<Bji_XKs|>H4pt{ZS`EJd88}3+qA|xjN;cXiAqgEQVx^<Y*rC^ri
+zN|fPh&4&o1-)VQ~bh450398pY;g;ReB`9EPFF-3HG>ypDLDRam??H<|4D?ll7VXxY
+zcZL__rwGw<8yGnV;Tkb@Ay3U7g*`}s3$O}SiayV)@XpZKm<xC5sbkyeV%XYg+CR3_
+zzb%!>X4&aInCOCMR-a%+wekvlBh<iIzajD_{5&*nyv;?KFI|**;T~nCc2njMFjxA#
+zW+Km8xoH5Whb63C++J$3%9)53Tw6OWIKG1xTxN#@iXf+hmO@@fKZHY_H1uyfY3S3P
+zG&Jd?YZ>M&wEPZ|a=*174i^DpYN2F1!y@B{+$^J$va+0%b-_tlSzWeK)@LIuwpM=f
+z3didvtSz}WnpXEcnpR3TP3v?wO{=k+ruE-$nwC!wO{=$u4v^MM2Y9=e4)CnE(6Sn4
+z>`tqFWB{*P_yhErE;6pEm$C+WDa)&mvR3s`*1<m8DC@}x%db|Juoxb}c0a)r!o%ax
+zBT9~bM9JqLQL^-yl1m=jERNSh$|Gcbt$Y&i4PWPfUCpApuMi4uL})!A?c%rLYnhCb
+zP(6)+mrud;3?ZKo7NrBipCdE}unY7`K++3@HUY{2cKE*j9sK1541ul+WzqZJBNPs8
+z7XDBl!R-d^C9c(fz_{@8$hpi*d@M2)ZtBaCA1KcIvuFsAhgV0P^8c5_qN;x&)B%t_
+gLTC;4HyD^gJjL)S<HX;>-_7ILWc;UR@mYla4-;9yJOBUy
+
+diff --git a/firmware/r8a779x_usb3_v3.dlmem b/firmware/r8a779x_usb3_v3.dlmem
+index eac36a96bee1a8614eef9caa88e5a9de136af30c..1e09014d1876e1acd638db7b067f96397216af1b 100644
+GIT binary patch
+delta 2698
+zcmY*b4Nz3q6~6buzQ-=?!aiA+U3U4~T_PeDsUnEFC}{kTC~8zxKxO<vr5Woasg{)h
+zrPMl_8;qH%(cwqSIHsa&GnCvW7OZv1NDx+~ii-*|>Vz7BI!VmyIg5?S&V1*dd+#~l
+zIq$r4?_1aWEAv7cmbVOrk`98u0dm`RC?tvQIyAFR=#M)$kVNS&W)dbEFNO|lT}l{j
+z1vyo4t6WN+pG)B^U-&0Ib3Wd0CZ$);Z}YFAswMs|rTP3A@fn?BKmP0Qmg-Bxh~I3(
+z^-l=liWuJVTBFA?xad8nC<h2+FRYyi&k##UsgzF~gC>_#9M2{PIOB=Kn|;a3l^lm{
+z3WXgj?EKc}VK=Hg87qk2eElT@S0dT50Bgx#d^@v##&a3g{E{%jk~nX6w~8yCIIe`e
+z_KL6nM=zHYgW1J<vm3##ZCr-vBrab@6DypePK}v*vzuTqHyN{aNxj9SgUVUP<pGW`
+z!qU{U9lOA459u<bKcvJdmilH5qM}^V(vCW9`a?CW9$_`=blS=8s<+V$wm_4R@cyhW
+zDCs0p2XZ$Vh6p{gT2(?aS2}cM&N}iUtwUu=!}(cuQsYR_W!7oA(wvEwVpgll4|Xbb
+zwLZ&IZLCOs+0Y=Q`NQfu_EeLpeUw=@9W1hjCv&BW%?zA8Z}FCDsB7%jK7&i~7u_Hu
+z#d4_R@uDtZepH0~hqojDx*e@5WNOluIZr_*KK?A^4}jH!?C*g_)!W((QDHOnF;T@?
+zT#B8|r2~Mo0P`F!O$8jDqe|w|Tow^zvwaV9&+A;un#ZNL=5i@zK9{Nh@4|f70uk&4
+zmLHV4(zSp~>lSh;Xc5=}Isp3@b4h-KOAD89X#_Ann@g7g@=`8EFXK`{4wu>i-!A9U
+zgcV#m0%!+}f0Ii`S4qIVnSB>zi<q&ROU;0sHC$=}#O88o+FE!bX&g(_Mg-f}x}*>S
+ze(Tk+M%V^zf^@N{ZxdHWShY5RHnT6Z?@%vG*G17bwnjJ85WXJYUOmN{J<n@ZX`nid
+z?3`{H{g$bMPX_9?b!i=g4(O!Q>|F3K=tkBXoKN3knIZq8DNL)k1)o{RrIz)OOI{$v
+zv@@sP7L}3*^~>i{J>W7RxqwSc0qq4rU~`Y{(;EU)H^Osl(!%@_JE=DWXKdoq4}ii#
+z9jqN^t@?=(;x?<Xyfh-!l5|TxCU2ClLY6s2ZjcpBFDGP<6D>&*spbsRTzJz(mL#i@
+zlF|97eHHe`jywMqiD|Am19_0ayt5DF;+@Eo!%Ae+q_AR)GyUtbQsf);eFVKE7o+e0
+z{Wcb(-{oTTdtS`i<i&5u<-?AEB(4mVyM3dlV%UoFqrY=oyCLO#xly&rm-d^Lb&yO!
+z<*@eW>v@$(T2YClXV{i8wvrZ~zWeukSE>je*ea=4iB4&TL*Be!bAl^;|Av(U%r3&{
+z590+GMKWq}7W9CZdIRVh*uM>95R9EL>R{}EG32F98|X424Wx-QlB<S+e>}3Yz)%C7
+z#bQF8G>qkkny5ef4d@#7x6qv>LT&48u57HW205p$500l$@1CA7_p0t`H-IeFy5X>X
+zT2l?uT-%oj(Q4fw57d<>{?w}60oPGY9~|cP8aK#2wdEjF>$(g-wZcPfsd0m>uPFyP
+zR;=xUGU?bShA2A3u7P~O1`RQ^k?F&XG?K-K#nbt0Sy&=Gz&=<xz&;8)HT@FB(obt2
+z28zn|R*=uztD)<kQ!M?+S6KR?jxuMj`bFCNcn=lgJrSJ}jm2VnjYe$~Ei?A2z4}J@
+zcoead#+bkr1id=H<jQIGr7_B0*=9Gc%H1bFeR*1ji~^y_d*SxSvm=BHM3cmpgfFHm
+z*vH|^1bZ?Y3Xg_oFqj<F!_rMw{h2n*=9@O;-3`18*%nhmV%{~3Tqt(~@1jztxY~sG
+zxnnRJ^g^FLdZ*(z-~{`^WRQcdBTx5r<hjs^Ujx={9;XZM!sX{(xUBQAX!C?I(>&Es
+zi-jKC$o1ex0n0aAwW~c`aslcApR+%hV-iPvHsTGmiN1lHWk#(=5M2s<SEM;N1hK@Y
+zZN9;!9qg7lp(OSuvUc7?k0&=rJ$lu2X`zfB=36De@M`XYIexS3Uz1iV93RguYl<44
+zXaGiN&#7D?-PRP7Pa6+f6rr&81a{+mT6p(p6@Fw0RAewy0fo7n9f&Z~gY3@{i3tO@
+z@$FB&gU@~Y4rZ9#gMSF>Nv-o&fiKeT!S^aU#YH|-4lru5sXqNTRyE!-am?*|=sDp&
+zdJf!2&pm9r#VBZAunJ2`X62n~hfB#N*wJzicJz!M?C1}Ax}f!r_Fx0n_Fx01-bJE@
+zyGZ1{i$o)Lu}C>gu^8#w%xH}<rFhXM*NZksyl6AvMVlim+iDczzGqvl6V_b0|0<;A
+z0fv0{0fzKGz>oob7&563LuU0MU1UGfx%!dra6i(GeOTsP74)*_?~L|53HVGo%AP?I
+znuq8$=^=V$44~J+0rYBNiIGM)WwRrr1j`^RjEpp;K1S1ZkI}UMF`CYQf~Hs4F);0B
+z?#T7}c7s4#t`QR6PDlY@$$3ZA8k)TodiV%nWDvIgLr5p+VP=6uJ|$!hU<T+r05iTJ
+zWHaD6pbF+!p21%}z-7=qfT|%v`e7W)zKV`g&5D2vk_|_HNFT93#=LI*0sbvrNGGIe
+z8X<G1Lll5(1|e}yLd@)G%!lfWdVz?tKz6Z1v8VK(gVy*bLV5u5QAn80v)Sl=w%ztu
+UI=~$EDfBd3Yya5)+B<~&507_F0RR91
+
+delta 2932
+zcmY*b4Ny~87QXMndoKyR2oFLMAP`7`RYU_SD|RJ_sHhdi{~uaGk+q6{yIXhH(IrJt
+zw&OVHUF>$ZvMK?sbsUReS1WfqEV$aC7AYW7fg}RrPyK7LyA^nQZotxJ<~#Sid(L<6
+zxj*OLT$^W~?{{YTWOpEHLiE>%0?mj0tjyWNGt1dZ-6wrkhB=G%Y^?TNV83XWgP3}d
+z)7fgyE@yh#<%>9r{SVW9VVu`YhN-=<#k-8*QoZeR)rA25J7&@n|NJ22HCsbuwXSY#
+zWvk`M!hJSgrC`xsMC8-DBt8%23t7nWL~pn8W;{b-(<m&?^jZUvGc2ZGF<>!(WfwlI
+z2*`^HHfy=Te90w3+gd0c9xM?@eNKC#CjTNLfj%!Q9cxvTGrgT7a%U8gbz?_aoj<Yc
+zLIn7!$2rq0!LNCI5^qCxPj0dMZ9K1JRgknZ{W2J{ag1`cC0EI!J*Y+V`aK5O_}!kb
+zGrTO<icC|v`1(C1^cLffm9H}m_?~hLGYv0QMMwWVxdm2m3MvP=3-v>^-sF0YjU#fq
+zy1-VB1{0dN&;<H@5r3qzL<h|(7l~Xqi+ZY4>Nzj46ssK`&wMeGN0ZN-VH3QeHwXVu
+zHA{Rxt9%A{r1VcE@)11GXX@k?Z<oMwj^Es)vCH0kHOMf&5VoWuw*?|U&!zE8x6=4I
+z+v+(QsTP0YqtX9Obl6UzfrKM;l;w03W4s?MksWvWSi=99LWJ?NiEtEf5fC|t2+4rb
+zIb0kO7GsmI$>cqk2%Ug8<`H3cDiIRr6X6ITAHMf2;K5IY-}argvS<Mja^4_9;6m^N
+zv;+Q{Mugx+L|C?%2t$A==|s2z2wp;j*On4t^D-i|0oWBphzA@8v;n59B7$SJ0I_#q
+zFVPe-XAKeR02ynEPzxBJL4=ey6=09UGsTcG6W+87Fe_ooIwkZe@D?#zAh|soi9Cdl
+ziP20IzApYLqEBItKZ}e(NyzIdqw(S_+GG37iObZgB%f3c*0LFIP|wsD*U??AVCY(+
+zta?rbYk3)8QZHqmV{yz0pP(%*qUDJNj?-~`Y0M-h7vCR~#q7ol{H`;JSmSRRQ}q@R
+z8rDIUnLd!s1U%Q@v>`DQRyK<W=KwbV)7KMW4WMnkFZetV@{mJ&3S~(*xk_=pRLiw+
+zL`cep8E+K9{>9JiZf?Eg<{&#Ebt4h@93pJXQG-tf{?b1-M7_nJEzA#@7HYjM9h0)9
+zFJKlKxz!*KVZ9VB#_^%nkZHk5`c!&C(j{#|#kP(gc%)AaPNFR8AGy5;<cjT-m9agE
+zmv`6&m*0NG_tihByU#lhAfb)OVfcik4GrEw*{_(nJ1FzU4$4G3akG@RD7diSqOcNq
+zps?E0cJA*t&~L|qYC}7um?c$m8$D@e7L~&$Y%b~-f7!pOhz31WM1xl0odKq;4Icf^
+zf7!c|L-h7}PjJb`_$zR%>kg`p6Zz`F4J%prBG7t6dj(n^4SQS!T`{6pg02F4H?+Rc
+z-hoyPZ9BAnBR<WT2^`DJ$KwKRAz=p}+%vL<r{B0T8}Dj;kj}cH&3((r64@8;3$!s3
+z{&(Q^bt*^wY$E46N<gNS_dp@5DynB>NiNPUZUC7tRzq2TURDA!($NzG<2kB99xX47
+z`MFo21um(w9w_^^vTBe8jzW-0_^>7*z+6@h1%Ixr5Tw=70xJ`QKh=aY1NaumJNO4p
+zg#PkXRiE>IrN&^j%g50SxQ7$E=p`3~V}r&q$#`v0jDG%AmDA~Ri=p6SMZX50;fruT
+zJ`r@v!m@NnQX2bVl;XyEkmzO!6vs4{?#R$hx+4R4t5$1iXB;+{a^#x%!|*ke1S?s~
+z6lh&ar++0pHD~ch+6bSch_dc{N#ygmMH`-7++fzO&UjaP7BgH_kF+de;`So5_MMk1
+z>mli;p+K9J!SY>l?clK1DZ4py={qmKo`g`3SSO^seAQn&_^Q9|K+4PEc++((!a7|V
+za|r)Nx0HPpi?8U6%oW_BvrH=eF%?b^eKQ=MEZtnT^c+rOzE}ct{e1(S<>dyNZzALy
+zh-3B9i(dPR&L~G}hf82#zKuVkr|+QUNjm7I9-W@Z;df|LQ-M~af;|<RxZ$0rahscH
+z+>>9^xO?!&`blbMGwu1jh4!?z;6DAt0Pj}n8rVt==2mJLkH-ZY#K=~td%!k85ndV`
+z5kovaH#|Olt@Obw(26RSx6AO#3F=!cpXbr6x8RP&CxWB%9^9f)KWw8>tJ;PcE+w-h
+zN1_aOTOLFh{Z742r;~-uk5Rn=3b*vOAzlevdmdT|q3J}v2AbZZeGghVVxX@Iv?!0}
+zygj@iKShX=+rh{|2=|D|g}k+Ul(j(uT!59ZQuKLVg?EO;M4!JyPaWGq7sJs()Bdr8
+z{%xs14%<$j!2~xvv&MKks*zXV>mer2{tb~g;b$SS6C7^JeBq|d^LHsTrJFK`fVtB5
+z6%%>a$V~${Ei``Z;*JuFUCuzX;MzNA!SS86;4(T}pa`-%X({A(_Cq+-MMM9#i-tbk
+zMMIM=x|X5N0^9E(DbHK`!Eg~ErUpv3D>Nc*$ip%_DJ#=SS?8UUmFaSfvOXJOu{HAJ
+zmpINaac%M4(X_hn(zKGhX<DbdX<CilG_C)3)3khhXj;8Jbb!=eI>1}KbbzP51-8{N
+zV^3NgBLgUE;1AGehKSgvUdkHir7T4sWv%L?tb=`yQP$%TmS2r5VKFS6?S70WhK0qV
+zhm;)kkdn_mq-5z4B^N((*jio<DUXniHS$TkH*B5%H4TgEzCuXXh|qdK>V<E^)-vfQ
+zp?VqtFP?zuDMG%%EJ_1}Jws>?U>E2WfW+qrZ32`6YT^6Zckq`NFa)|fghlUtk5Cx2
+znfL=^IJX<L7r4gwKI6vABjz$M@Ue&xxT!Biystdx&!QnfE?ymZ%Ku*yiz@$tP$xk8
+g5TP~L-(+G6@Kn>Mj1zwge>aa~i}|14jS7VR52nDsPyhe`
+
+--
+1.9.1
+
diff --git a/meta-rcar-gen3-adas/recipes-kernel/linux/linux-renesas/0029-i2c-mux-pca954x-fix-i2c-mux-selection-caching.patch b/meta-rcar-gen3-adas/recipes-kernel/linux/linux-renesas/0029-i2c-mux-pca954x-fix-i2c-mux-selection-caching.patch
new file mode 100644
index 0000000..1640b51
--- /dev/null
+++ b/meta-rcar-gen3-adas/recipes-kernel/linux/linux-renesas/0029-i2c-mux-pca954x-fix-i2c-mux-selection-caching.patch
@@ -0,0 +1,51 @@
+From 7f638c1cb0a1112dbe0b682a42db30521646686b Mon Sep 17 00:00:00 2001
+From: Russell King <rmk+kernel@armlinux.org.uk>
+Date: Sat, 17 Dec 2016 12:10:56 +0000
+Subject: [PATCH] i2c: mux: pca954x: fix i2c mux selection caching
+
+smbus functions return -ve on error, 0 on success. However,
+__i2c_transfer() have a different return signature - -ve on error, or
+number of buffers transferred (which may be zero or greater.)
+
+The upshot of this is that the sense of the test is reversed when using
+the mux on a bus supporting the master_xfer method: we cache the value
+and never retry if we fail to transfer any buffers, but if we succeed,
+we clear the cached value.
+
+Fix this by making pca954x_reg_write() return a negative error code for
+all failure cases.
+
+Fixes: 463e8f845cbf ("i2c: mux: pca954x: retry updating the mux selection on failure")
+Acked-by: Peter Rosin <peda@axentia.se>
+Signed-off-by: Russell King <rmk+kernel@armlinux.org.uk>
+Signed-off-by: Wolfram Sang <wsa@the-dreams.de>
+---
+ drivers/i2c/muxes/i2c-mux-pca954x.c | 5 ++++-
+ 1 file changed, 4 insertions(+), 1 deletion(-)
+
+diff --git a/drivers/i2c/muxes/i2c-mux-pca954x.c b/drivers/i2c/muxes/i2c-mux-pca954x.c
+index 9a348ee..dd18b9c 100644
+--- a/drivers/i2c/muxes/i2c-mux-pca954x.c
++++ b/drivers/i2c/muxes/i2c-mux-pca954x.c
+@@ -167,6 +167,9 @@ static int pca954x_reg_write(struct i2c_adapter *adap,
+ buf[0] = val;
+ msg.buf = buf;
+ ret = __i2c_transfer(adap, &msg, 1);
++
++ if (ret >= 0 && ret != 1)
++ ret = -EREMOTEIO;
+ } else {
+ union i2c_smbus_data data;
+ ret = adap->algo->smbus_xfer(adap, client->addr,
+@@ -195,7 +198,7 @@ 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);
+- data->last_chan = ret ? 0 : regval;
++ data->last_chan = ret < 0 ? 0 : regval;
+ }
+
+ return ret;
+--
+1.9.1
+
diff --git a/meta-rcar-gen3-adas/recipes-kernel/linux/linux-renesas/0030-Gen3-LVDS-cameras.patch b/meta-rcar-gen3-adas/recipes-kernel/linux/linux-renesas/0030-Gen3-LVDS-cameras.patch
new file mode 100644
index 0000000..75b3fb9
--- /dev/null
+++ b/meta-rcar-gen3-adas/recipes-kernel/linux/linux-renesas/0030-Gen3-LVDS-cameras.patch
@@ -0,0 +1,7768 @@
+From 7a6b0c38e5e1502f309b89b16fad8c70645e1221 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] Gen3: LVDS cameras
+
+This add Gen3 LVDS cameras support:
+- deserializers: MAX9286, TI964, TI954, TI960
+- cameras: ov10635, ov490+ov10640, ov495+OV2775, ar0132
+
+Signed-off-by: Vladimir Barinov <vladimir.barinov@cogentembedded.com>
+---
+ drivers/media/i2c/soc_camera/Kconfig | 47 +
+ drivers/media/i2c/soc_camera/Makefile | 7 +
+ drivers/media/i2c/soc_camera/ar0132.c | 581 +++++++++++
+ drivers/media/i2c/soc_camera/ar0132.h | 213 ++++
+ drivers/media/i2c/soc_camera/max9286_max9271.c | 607 ++++++++++++
+ drivers/media/i2c/soc_camera/max9286_max9271.h | 244 +++++
+ drivers/media/i2c/soc_camera/ov10635.c | 758 ++++++++++++++
+ drivers/media/i2c/soc_camera/ov10635.h | 1139 ++++++++++++++++++++++
+ drivers/media/i2c/soc_camera/ov10635_debug.h | 54 +
+ drivers/media/i2c/soc_camera/ov106xx.c | 106 ++
+ drivers/media/i2c/soc_camera/ov490_ov10640.c | 1092 +++++++++++++++++++++
+ drivers/media/i2c/soc_camera/ov490_ov10640.h | 93 ++
+ drivers/media/i2c/soc_camera/ov495_ov2775.c | 658 +++++++++++++
+ drivers/media/i2c/soc_camera/ov495_ov2775.h | 23 +
+ drivers/media/i2c/soc_camera/ti954_ti9x3.c | 431 ++++++++
+ drivers/media/i2c/soc_camera/ti964_ti9x3.c | 399 ++++++++
+ drivers/media/i2c/soc_camera/ti9x4_ti9x3.h | 153 +++
+ drivers/media/platform/soc_camera/rcar_csi2.c | 297 ++++--
+ drivers/media/platform/soc_camera/rcar_vin.c | 174 +++-
+ drivers/media/platform/soc_camera/soc_camera.c | 17 +-
+ drivers/media/platform/soc_camera/soc_mediabus.c | 16 +
+ include/media/drv-intf/soc_mediabus.h | 3 +
+ include/media/soc_camera.h | 1 +
+ 23 files changed, 7004 insertions(+), 109 deletions(-)
+ 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/max9286_max9271.c
+ create mode 100644 drivers/media/i2c/soc_camera/max9286_max9271.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/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/ti954_ti9x3.c
+ create mode 100644 drivers/media/i2c/soc_camera/ti964_ti9x3.c
+ create mode 100644 drivers/media/i2c/soc_camera/ti9x4_ti9x3.h
+
+diff --git a/drivers/media/i2c/soc_camera/Kconfig b/drivers/media/i2c/soc_camera/Kconfig
+index 7704bcf..82da59f 100644
+--- a/drivers/media/i2c/soc_camera/Kconfig
++++ b/drivers/media/i2c/soc_camera/Kconfig
+@@ -6,6 +6,53 @@ config SOC_CAMERA_IMX074
+ help
+ This driver supports IMX074 cameras from Sony
+
++config SOC_CAMERA_MAX9286_MAX9271
++ tristate "max9286-max9271 GMSL support"
++ depends on SOC_CAMERA && I2C
++ help
++ This is a MAXIM max9286-max9271 GMSL driver
++
++config SOC_CAMERA_OV106XX
++ tristate "ov106xx camera support"
++ depends on SOC_CAMERA && SOC_CAMERA_MAX9286_MAX9271 && I2C
++ help
++ This is a runtime detected OmniVision ov10635 or ov490-ov10640
++ or ov495-ov2775 sensors camera driver
++
++if !SOC_CAMERA_OV106XX
++
++config SOC_CAMERA_OV10635
++ tristate "ov10635 camera support"
++ depends on SOC_CAMERA && SOC_CAMERA_MAX9286_MAX9271 && I2C
++ help
++ This is an OmniVision ov10635 sensor camera driver
++
++config SOC_CAMERA_OV490_OV10640
++ tristate "ov490-ov10640 camera support"
++ depends on SOC_CAMERA && SOC_CAMERA_MAX9286_MAX9271 && I2C
++ help
++ This is an OmniVision ov490-ov10640 sensor camera driver
++
++config SOC_CAMERA_OV495_OV2775
++ tristate "ov495-ov2775 camera support"
++ depends on SOC_CAMERA && I2C
++ help
++ This is an OmniVision ov495-ov2775 sensor camera driver
++
++endif
++
++config SOC_CAMERA_TI964_TI9X3
++ tristate "ti964-ti9x3 FPDLinkIII support"
++ depends on SOC_CAMERA && I2C
++ help
++ This is an Texas Instruments ti964-ti9X3 FPDLinkIII driver
++
++config SOC_CAMERA_TI954_TI9X3
++ tristate "ti954-ti9X3 FPDLinkIII support"
++ depends on SOC_CAMERA && I2C
++ help
++ This is an Texas Instruments ti954-ti9X3 FPDLinkIII driver
++
+ config SOC_CAMERA_MT9M001
+ tristate "mt9m001 support"
+ depends on SOC_CAMERA && I2C
+diff --git a/drivers/media/i2c/soc_camera/Makefile b/drivers/media/i2c/soc_camera/Makefile
+index 6f994f9..7d4c1ab 100644
+--- a/drivers/media/i2c/soc_camera/Makefile
++++ b/drivers/media/i2c/soc_camera/Makefile
+@@ -1,8 +1,15 @@
+ obj-$(CONFIG_SOC_CAMERA_IMX074) += imx074.o
++obj-$(CONFIG_SOC_CAMERA_MAX9286_MAX9271) += max9286_max9271.o
++obj-$(CONFIG_SOC_CAMERA_TI964_TI9X3) += ti964_ti9x3.o
++obj-$(CONFIG_SOC_CAMERA_TI954_TI9X3) += ti954_ti9x3.o
+ obj-$(CONFIG_SOC_CAMERA_MT9M001) += mt9m001.o
+ 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_OV10635) += ov10635.o
++obj-$(CONFIG_SOC_CAMERA_OV490_OV10640) += ov490_ov10640.o
++obj-$(CONFIG_SOC_CAMERA_OV495_OV2775) += ov495_ov2775.o
++obj-$(CONFIG_SOC_CAMERA_OV106XX) += ov106xx.o
+ obj-$(CONFIG_SOC_CAMERA_OV2640) += ov2640.o
+ obj-$(CONFIG_SOC_CAMERA_OV5642) += ov5642.o
+ obj-$(CONFIG_SOC_CAMERA_OV6650) += ov6650.o
+diff --git a/drivers/media/i2c/soc_camera/ar0132.c b/drivers/media/i2c/soc_camera/ar0132.c
+new file mode 100644
+index 0000000..decbf5f
+--- /dev/null
++++ b/drivers/media/i2c/soc_camera/ar0132.c
+@@ -0,0 +1,581 @@
++/*
++ * Aptina 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/videodev2.h>
++
++#include <media/soc_camera.h>
++#include <media/v4l2-common.h>
++#include <media/v4l2-ctrls.h>
++#include <media/v4l2-of.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 ti964_addr;
++ int ti954_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 */
++ 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,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 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->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, AR0132_I2C_ADDR << 1); /* Sensor native I2C address */
++
++ reg8_write(client, 0x6e, 0xa9); /* GPIO0 - reset, 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, 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..055841d
+--- /dev/null
++++ b/drivers/media/i2c/soc_camera/ar0132.h
+@@ -0,0 +1,213 @@
++/*
++ * OmniVision 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/max9286_max9271.c b/drivers/media/i2c/soc_camera/max9286_max9271.c
+new file mode 100644
+index 0000000..91223a0
+--- /dev/null
++++ b/drivers/media/i2c/soc_camera/max9286_max9271.c
+@@ -0,0 +1,607 @@
++/*
++ * MAXIM max9286-max9271 GMSL 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/i2c.h>
++#include <linux/module.h>
++#include <linux/notifier.h>
++#include <linux/of_gpio.h>
++#include <linux/regulator/consumer.h>
++#include <linux/videodev2.h>
++
++#include <media/v4l2-common.h>
++#include <media/v4l2-device.h>
++#include <media/v4l2-of.h>
++#include <media/v4l2-subdev.h>
++
++#include "max9286_max9271.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_max9271_priv {
++ struct v4l2_subdev sd[4];
++ struct device_node *sd_of_node[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 timeout;
++ atomic_t use_count;
++ u32 csi2_outord;
++ struct i2c_client *client;
++ int max9271_addr_map[4];
++ struct regulator *poc_supply[4]; /* PoC power supply */
++};
++
++static int force_conf_link;
++static int force_poc_trig;
++#ifndef MODULE
++static __init int max9286_max9271_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", max9286_max9271_force_conf_link);
++
++static __init int max9286_max9271_force_poc_trig(char *str)
++{
++ /* force PoC triggering during reverse channel setup */
++ /* to be used on systems with dedicated PoC and unstable ser-des lock */
++ force_poc_trig = 1;
++ return 0;
++}
++early_param("force_poc_trig", max9286_max9271_force_poc_trig);
++#endif
++
++static void max9286_max9271_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 */
++}
++
++static void max9286_max9271_sensor_reset(struct i2c_client *client, int addr, int reset_on)
++{
++ struct max9286_max9271_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_max9271_postinit(struct i2c_client *client, int addr)
++{
++ struct max9286_max9271_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_max9271_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 */
++}
++
++static int max9286_max9271_reverse_channel_setup(struct i2c_client *client, int idx)
++{
++ struct max9286_max9271_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, 0x1); /* 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 = 0x40; /* MAX9271-CAMx I2C */
++ reg8_read(client, 0x1e, &val); /* read max9271 ID */
++ if (val == MAX9271_ID || val == MAX96705_ID || --timeout == 0)
++ 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) {
++ 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 && force_poc_trig) {
++ if (!IS_ERR(priv->poc_supply[idx])) {
++ if (regulator_disable(priv->poc_supply[idx]))
++ dev_err(&client->dev, "fail to disable POC%d regulator\n", idx);
++ mdelay(200);
++ if (regulator_enable(priv->poc_supply[idx]))
++ dev_err(&client->dev, "fail to enable POC%d regulator\n", idx);
++ }
++ }
++ }
++
++ max9286_max9271_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 MAX9271 %sat 0x%x %s %s\n", idx,
++ 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_max9271_initial_setup(struct i2c_client *client)
++{
++ struct max9286_max9271_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);
++ }
++
++ if (strcmp(priv->fsync_mode, "manual") == 0) {
++ 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, 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 */
++ }
++
++ reg8_write(client, 0x63, 0); /* disable overlap window */
++ reg8_write(client, 0x64, 0);
++ reg8_write(client, 0x0c, 0x89); /* enable HS/VS encoding, use D14/15 for HS/VS, invert VS */
++}
++
++static void max9286_max9271_gmsl_link_setup(struct i2c_client *client, int idx)
++{
++ struct max9286_max9271_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 */
++
++ 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_max9271_initialize(struct i2c_client *client)
++{
++ struct max9286_max9271_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_max9271_preinit(client, priv->des_quirk_addr);
++
++ max9286_max9271_preinit(client, priv->des_addr);
++ max9286_max9271_initial_setup(client);
++
++ for (idx = 0; idx < priv->links; idx++) {
++ if (!IS_ERR(priv->poc_supply[idx])) {
++ if (regulator_enable(priv->poc_supply[idx]))
++ dev_err(&client->dev, "fail to enable POC%d regulator\n", idx);
++ }
++
++ ret = max9286_max9271_reverse_channel_setup(client, idx);
++ if (ret)
++ continue;
++ max9286_max9271_gmsl_link_setup(client, idx);
++ }
++
++ max9286_max9271_postinit(client, priv->des_addr);
++
++ client->addr = priv->des_addr;
++
++ return 0;
++}
++
++#ifdef CONFIG_VIDEO_ADV_DEBUG
++static int max9286_max9271_g_register(struct v4l2_subdev *sd,
++ struct v4l2_dbg_register *reg)
++{
++ struct max9286_max9271_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_max9271_s_register(struct v4l2_subdev *sd,
++ const struct v4l2_dbg_register *reg)
++{
++ struct max9286_max9271_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_max9271_s_power(struct v4l2_subdev *sd, int on)
++{
++ struct max9286_max9271_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_max9271_registered_async(struct v4l2_subdev *sd)
++{
++ struct max9286_max9271_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, force_conf_link ? 0x43 : 0x83); /* enable reverse_control/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_max9271_subdev_core_ops = {
++#ifdef CONFIG_VIDEO_ADV_DEBUG
++ .g_register = max9286_max9271_g_register,
++ .s_register = max9286_max9271_s_register,
++#endif
++ .s_power = max9286_max9271_s_power,
++ .registered_async = max9286_max9271_registered_async,
++};
++
++static struct v4l2_subdev_ops max9286_max9271_subdev_ops = {
++ .core = &max9286_max9271_subdev_core_ops,
++};
++
++static int max9286_max9271_parse_dt(struct i2c_client *client)
++{
++ struct max9286_max9271_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;
++ char fsync_mode_default[20] = "manual"; /* manual, automatic, semi-automatic, external */
++ u8 val = 0;
++
++ 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);
++
++ 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 = false;
++ else
++ priv->active_low_resetb = true;
++ }
++
++ 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;
++
++ 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_of_node[i] = endpoint;
++ }
++
++ return 0;
++}
++
++static void max9286_max9271_setup_remote_endpoint(struct i2c_client *client)
++{
++ struct max9286_max9271_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_max9271_probe(struct i2c_client *client,
++ const struct i2c_device_id *did)
++{
++ struct max9286_max9271_priv *priv;
++ int err, i;
++ char supply_name[10];
++
++ 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_max9271_parse_dt(client);
++ if (err)
++ goto out;
++
++ for (i = 0; i < 4; i++) {
++ sprintf(supply_name, "POC%d", i);
++ priv->poc_supply[i] = devm_regulator_get_optional(&client->dev, supply_name);
++ }
++
++ err = max9286_max9271_initialize(client);
++ if (err < 0)
++ goto out;
++
++ max9286_max9271_setup_remote_endpoint(client);
++
++ for (i = 0; i < 4; i++) {
++ v4l2_subdev_init(&priv->sd[i], &max9286_max9271_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].of_node = priv->sd_of_node[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_max9271_remove(struct i2c_client *client)
++{
++ struct max9286_max9271_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_max9271_dt_ids[] = {
++ { .compatible = "maxim,max9286-max9271" },
++ {},
++};
++MODULE_DEVICE_TABLE(of, max9286_max9271_dt_ids);
++
++static const struct i2c_device_id max9286_max9271_id[] = {
++ { "max9286_max9271", 0 },
++ { }
++};
++MODULE_DEVICE_TABLE(i2c, max9286_max9271_id);
++
++static struct i2c_driver max9286_max9271_i2c_driver = {
++ .driver = {
++ .name = "max9286_max9271",
++ .of_match_table = of_match_ptr(max9286_max9271_dt_ids),
++ },
++ .probe = max9286_max9271_probe,
++ .remove = max9286_max9271_remove,
++ .id_table = max9286_max9271_id,
++};
++
++module_i2c_driver(max9286_max9271_i2c_driver);
++
++MODULE_DESCRIPTION("GMSL driver for MAX9286-MAX9271");
++MODULE_AUTHOR("Vladimir Barinov");
++MODULE_LICENSE("GPL");
+diff --git a/drivers/media/i2c/soc_camera/max9286_max9271.h b/drivers/media/i2c/soc_camera/max9286_max9271.h
+new file mode 100644
+index 0000000..6c2a9e0
+--- /dev/null
++++ b/drivers/media/i2c/soc_camera/max9286_max9271.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..6296647
+--- /dev/null
++++ b/drivers/media/i2c/soc_camera/ov10635.c
+@@ -0,0 +1,758 @@
++/*
++ * 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/videodev2.h>
++
++#include <media/soc_camera.h>
++#include <media/v4l2-common.h>
++#include <media/v4l2-ctrls.h>
++#include <media/v4l2-of.h>
++
++#include "max9286_max9271.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 */
++ 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..f2bb706
+--- /dev/null
++++ b/drivers/media/i2c/soc_camera/ov106xx.c
+@@ -0,0 +1,106 @@
++/*
++ * 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"
++
++static enum {
++ ID_OV10635,
++ ID_OV490_OV10640,
++ ID_OV495_OV2775,
++ ID_AR0132,
++} 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;
++ }
++
++ 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;
++ };
++
++ 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 or OV490/OV10640 or OV495/OV2775 or AR0132");
++MODULE_AUTHOR("Vladimir Barinov");
++MODULE_LICENSE("GPL");
+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..813c08e
+--- /dev/null
++++ b/drivers/media/i2c/soc_camera/ov490_ov10640.c
+@@ -0,0 +1,1092 @@
++/*
++ * OmniVision ov490-ov10640 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 <linux/delay.h>
++#include <linux/init.h>
++#include <linux/i2c.h>
++#include <linux/module.h>
++#include <linux/videodev2.h>
++
++#include <media/soc_camera.h>
++#include <media/v4l2-common.h>
++#include <media/v4l2-ctrls.h>
++#include <media/v4l2-of.h>
++
++#include "max9286_max9271.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 dvp_order;
++ /* serializers */
++ int max9286_addr;
++ int max9271_addr;
++ int ti964_addr;
++ int ti954_addr;
++ int ti9x3_addr;
++ int port;
++ int gpio_resetb;
++ int active_low_resetb;
++ int gpio_fsin;
++};
++
++static int force_conf_link;
++
++static __init int ov490_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", ov490_force_conf_link);
++
++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(2000, 2500); /* wait 2ms */
++ 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->ti964_addr) {
++ client->addr = priv->ti964_addr; /* TI964 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 */
++ }
++
++ if (priv->ti954_addr) {
++ client->addr = priv->ti954_addr; /* TI964 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_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(force_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 err, 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,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 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->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, OV490_I2C_ADDR << 1); /* Sensor native I2C address */
++
++ reg8_write(client, 0x6e, 0x9a); /* GPIO0 - fsin, GPIO1 - resetb */
++ }
++ 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, OV490_I2C_ADDR << 1); /* Sensor native I2C address */
++
++ reg8_write(client, 0x6e, 0x9a); /* GPIO0 - fsin, GPIO1 - resetb */
++ }
++ client->addr = tmp_addr;
++
++ err = of_property_read_string(np, "maxim,fixed-sensor", &fixed_sensor);
++ if (err)
++ return 0;
++
++ if (strcmp(fixed_sensor, "ov490") == 0) {
++ err = of_property_read_u32(np, "maxim,width", &priv->max_width);
++ if (err) {
++ dev_err(&client->dev, "maxim,width must be set for fixed-sensor\n");
++ goto out;
++ }
++
++ err = of_property_read_u32(np, "maxim,height", &priv->max_height);
++ if (err) {
++ dev_err(&client->dev, "maxim,height must be set for fixed-sensor\n");
++ goto out;
++ }
++
++ priv->is_fixed_sensor = true;
++ }
++
++out:
++ return err;
++}
++
++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;
++ 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_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..8c9ecf1
+--- /dev/null
++++ b/drivers/media/i2c/soc_camera/ov490_ov10640.h
+@@ -0,0 +1,93 @@
++/*
++ * 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.
++ */
++
++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},
++};
+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..6dc0675
+--- /dev/null
++++ b/drivers/media/i2c/soc_camera/ov495_ov2775.c
+@@ -0,0 +1,658 @@
++/*
++ * 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/videodev2.h>
++
++#include <media/soc_camera.h>
++#include <media/v4l2-common.h>
++#include <media/v4l2-ctrls.h>
++#include <media/v4l2-of.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 ti960_addr;
++ int ti954_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,ti964-ti9x3") &&
++ !of_property_read_u32(rendpoint->parent->parent, "reg", &priv->ti960_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->ti960_addr && !priv->ti954_addr) {
++ dev_err(&client->dev, "deserializer does not present for OV495\n");
++ return -EINVAL;
++ }
++
++ /* setup I2C translator address */
++ tmp_addr = client->addr;
++ if (priv->ti960_addr) {
++ client->addr = priv->ti960_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 */
++ }
++ 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, 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..3f53689
+--- /dev/null
++++ b/drivers/media/i2c/soc_camera/ov495_ov2775.h
+@@ -0,0 +1,23 @@
++/*
++ * OmniVision ov495-ov2775 sensor camera wizard 1280x1080@30/UYVY/BT601/8bit
++ *
++ * 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/ti954_ti9x3.c b/drivers/media/i2c/soc_camera/ti954_ti9x3.c
+new file mode 100644
+index 0000000..1672173
+--- /dev/null
++++ b/drivers/media/i2c/soc_camera/ti954_ti9x3.c
+@@ -0,0 +1,431 @@
++/*
++ * TI ti954-(ti913/ti953) FPDLinkIII 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/i2c.h>
++#include <linux/module.h>
++#include <linux/notifier.h>
++#include <linux/of_gpio.h>
++#include <linux/regulator/consumer.h>
++#include <linux/videodev2.h>
++
++#include <media/v4l2-common.h>
++#include <media/v4l2-device.h>
++#include <media/v4l2-of.h>
++#include <media/v4l2-subdev.h>
++
++#include "ti9x4_ti9x3.h"
++
++struct ti954_ti9x3_priv {
++ struct v4l2_subdev sd[4];
++ struct device_node *sd_of_node[4];
++ int des_addr;
++ int links;
++ int lanes;
++ int csi_rate;
++ const char *forwarding_mode;
++ const char *cable_mode;
++ atomic_t use_count;
++ struct i2c_client *client;
++ int ti9x3_addr_map[4];
++ char chip_id[6];
++ struct regulator *poc_supply[4]; /* PoC power supply */
++ int xtal_gpio;
++};
++
++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;
++}
++
++#if 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 ti954_ti9x3_read_chipid(struct i2c_client *client)
++{
++ struct ti954_ti9x3_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 ti954_ti9x3_initial_setup(struct i2c_client *client)
++{
++ struct ti954_ti9x3_priv *priv = i2c_get_clientdata(client);
++
++ /* Initial setup */
++ client->addr = priv->des_addr; /* TI954 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 */
++ reg8_write(client, 0x1f, 0x02); /* CSI rate 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 ti954_ti9x3_fpdlink3_setup(struct i2c_client *client, int idx)
++{
++ struct ti954_ti9x3_priv *priv = i2c_get_clientdata(client);
++
++ /* FPDLinkIII setup */
++ client->addr = priv->des_addr; /* TI954 I2C */
++ reg8_write(client, 0x4c, (idx << 4) | (1 << idx)); /* Select RX port number */
++ usleep_range(2000, 2500); /* wait 2ms */
++ reg8_write(client, 0x58, 0x58); /* Back channel: pass-through/backchannel/CRC enable, Freq=2.5Mbps */
++ 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 (strcmp(priv->cable_mode, "coax") == 0) {
++ reg8_write(client, 0x6d, 0x7f); /* Coax, RAW10 */
++ } 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, 0x6e, 0x88); /* Sensor reset: backchannel GPIO0/GPIO1 set low */
++}
++
++static int ti954_ti9x3_initialize(struct i2c_client *client)
++{
++ struct ti954_ti9x3_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->cable_mode, priv->chip_id);
++
++ ti954_ti9x3_initial_setup(client);
++
++ for (idx = 0; idx < priv->links; idx++) {
++ if (!IS_ERR(priv->poc_supply[idx])) {
++ if (regulator_enable(priv->poc_supply[idx]))
++ dev_err(&client->dev, "fail to enable POC%d regulator\n", idx);
++ }
++
++ ti954_ti9x3_fpdlink3_setup(client, idx);
++ }
++
++ client->addr = priv->des_addr;
++
++ return 0;
++}
++
++#ifdef CONFIG_VIDEO_ADV_DEBUG
++static int ti954_ti9x3_g_register(struct v4l2_subdev *sd,
++ struct v4l2_dbg_register *reg)
++{
++ struct ti954_ti9x3_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 ti954_ti9x3_s_register(struct v4l2_subdev *sd,
++ const struct v4l2_dbg_register *reg)
++{
++ struct ti954_ti9x3_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 ti954_ti9x3_s_power(struct v4l2_subdev *sd, int on)
++{
++ struct ti954_ti9x3_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 ti954_ti9x3_registered_async(struct v4l2_subdev *sd)
++{
++ struct ti954_ti9x3_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 ti954_ti9x3_subdev_core_ops = {
++#ifdef CONFIG_VIDEO_ADV_DEBUG
++ .g_register = ti954_ti9x3_g_register,
++ .s_register = ti954_ti9x3_s_register,
++#endif
++ .s_power = ti954_ti9x3_s_power,
++ .registered_async = ti954_ti9x3_registered_async,
++};
++
++static struct v4l2_subdev_ops ti954_ti9x3_subdev_ops = {
++ .core = &ti954_ti9x3_subdev_core_ops,
++};
++
++static int ti954_ti9x3_parse_dt(struct i2c_client *client)
++{
++ struct ti954_ti9x3_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, i;
++ int sensor_delay;
++ char forwarding_mode_default[20] = "round-robin"; /* round-robin, synchronized */
++ char cable_mode_default[5] = "coax"; /* coax, stp */
++ struct property *csi_rate_prop, *dvp_order_prop;
++ u8 val = 0;
++
++ if (of_property_read_u32(np, "ti,links", &priv->links))
++ priv->links = 2;
++
++ if (of_property_read_u32(np, "ti,lanes", &priv->lanes))
++ priv->lanes = 4;
++
++ priv->xtal_gpio = of_get_gpio(np, 0);
++ if (priv->xtal_gpio > 0) {
++ err = devm_gpio_request_one(&client->dev, priv->xtal_gpio, GPIOF_OUT_INIT_LOW, dev_name(&client->dev));
++ if (err)
++ dev_err(&client->dev, "cannot request XTAL gpio %d: %d\n", priv->xtal_gpio, err);
++ else
++ mdelay(250);
++ }
++
++ reg8_read(client, 0x00, &val); /* read TI954 I2C address */
++ if (val != (priv->des_addr << 1)) {
++ prop = of_find_property(np, "reg", NULL);
++ if (prop)
++ of_remove_property(np, prop);
++ return -ENODEV;
++ }
++
++ ti954_ti9x3_read_chipid(client);
++
++ indirect_write(client, 7, 0x15, 0x30);
++ gpio_set_value(priv->xtal_gpio, 1);
++ usleep_range(5000, 5500); /* wait 5ms */
++ indirect_write(client, 7, 0x15, 0);
++
++ if (!of_property_read_u32(np, "ti,sensor_delay", &sensor_delay))
++ mdelay(sensor_delay);
++
++ err = of_property_read_string(np, "ti,forwarding-mode", &priv->forwarding_mode);
++ if (err)
++ priv->forwarding_mode = forwarding_mode_default;
++
++ err = of_property_read_string(np, "ti,cable-mode", &priv->cable_mode);
++ if (err)
++ priv->cable_mode = cable_mode_default;
++
++ 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_of_node[i] = 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 ti954_ti9x3_probe(struct i2c_client *client,
++ const struct i2c_device_id *did)
++{
++ struct ti954_ti9x3_priv *priv;
++ int err, i;
++ char supply_name[10];
++
++ 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 = ti954_ti9x3_parse_dt(client);
++ if (err)
++ goto out;
++
++ for (i = 0; i < 4; i++) {
++ sprintf(supply_name, "POC%d", i);
++ priv->poc_supply[i] = devm_regulator_get_optional(&client->dev, supply_name);
++ }
++
++ err = ti954_ti9x3_initialize(client);
++ if (err < 0)
++ goto out;
++
++ for (i = 0; i < priv->links; i++) {
++ v4l2_subdev_init(&priv->sd[i], &ti954_ti9x3_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].of_node = priv->sd_of_node[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 ti954_ti9x3_remove(struct i2c_client *client)
++{
++ struct ti954_ti9x3_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 ti954_ti9x3_dt_ids[] = {
++ { .compatible = "ti,ti954-ti9x3" },
++ {},
++};
++MODULE_DEVICE_TABLE(of, ti954_ti9x3_dt_ids);
++
++static const struct i2c_device_id ti954_ti9x3_id[] = {
++ { "ti954_ti9x3", 0 },
++ { }
++};
++MODULE_DEVICE_TABLE(i2c, ti954_ti9x3_id);
++
++static struct i2c_driver ti954_ti9x3_i2c_driver = {
++ .driver = {
++ .name = "ti954_ti9x3",
++ .of_match_table = of_match_ptr(ti954_ti9x3_dt_ids),
++ },
++ .probe = ti954_ti9x3_probe,
++ .remove = ti954_ti9x3_remove,
++ .id_table = ti954_ti9x3_id,
++};
++
++module_i2c_driver(ti954_ti9x3_i2c_driver);
++
++MODULE_DESCRIPTION("FPDLinkIII driver for TI954-TI9X3");
++MODULE_AUTHOR("Vladimir Barinov");
++MODULE_LICENSE("GPL");
+diff --git a/drivers/media/i2c/soc_camera/ti964_ti9x3.c b/drivers/media/i2c/soc_camera/ti964_ti9x3.c
+new file mode 100644
+index 0000000..770d306
+--- /dev/null
++++ b/drivers/media/i2c/soc_camera/ti964_ti9x3.c
+@@ -0,0 +1,399 @@
++/*
++ * TI (ti964/ti960)-(ti913/ti953) FPDLinkIII 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/i2c.h>
++#include <linux/module.h>
++#include <linux/notifier.h>
++#include <linux/of_gpio.h>
++#include <linux/regulator/consumer.h>
++#include <linux/videodev2.h>
++
++#include <media/v4l2-common.h>
++#include <media/v4l2-device.h>
++#include <media/v4l2-of.h>
++#include <media/v4l2-subdev.h>
++
++#include "ti9x4_ti9x3.h"
++
++struct ti964_ti9x3_priv {
++ struct v4l2_subdev sd[4];
++ struct device_node *sd_of_node[4];
++ int des_addr;
++ int links;
++ int lanes;
++ int csi_rate;
++ const char *forwarding_mode;
++ const char *cable_mode;
++ atomic_t use_count;
++ struct i2c_client *client;
++ int ti9x3_addr_map[4];
++ char chip_id[6];
++ struct regulator *poc_supply[4]; /* PoC power supply */
++};
++
++static void ti964_ti9x3_read_chipid(struct i2c_client *client)
++{
++ struct ti964_ti9x3_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 ti964_ti9x3_initial_setup(struct i2c_client *client)
++{
++ struct ti964_ti9x3_priv *priv = i2c_get_clientdata(client);
++
++ /* Initial setup */
++ client->addr = priv->des_addr; /* TI964 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 */
++ reg8_write(client, 0x1f, 0x02); /* CSI rate 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 ti964_ti9x3_fpdlink3_setup(struct i2c_client *client, int idx)
++{
++ struct ti964_ti9x3_priv *priv = i2c_get_clientdata(client);
++
++ /* FPDLinkIII setup */
++ client->addr = priv->des_addr; /* TI964 I2C */
++ reg8_write(client, 0x4c, (idx << 4) | (1 << idx)); /* Select RX port number */
++ usleep_range(2000, 2500); /* wait 2ms */
++ reg8_write(client, 0x58, 0x58); /* Back channel: pass-through/backchannel/CRC enable, Freq=2.5Mbps */
++ 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 (strcmp(priv->cable_mode, "coax") == 0) {
++ reg8_write(client, 0x6d, 0x7f); /* Coax, RAW10 */
++ } 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, 0x6e, 0x88); /* Sensor reset: backchannel GPIO0/GPIO1 set low */
++}
++
++static int ti964_ti9x3_initialize(struct i2c_client *client)
++{
++ struct ti964_ti9x3_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->cable_mode, priv->chip_id);
++
++ ti964_ti9x3_initial_setup(client);
++
++ for (idx = 0; idx < priv->links; idx++) {
++ if (!IS_ERR(priv->poc_supply[idx])) {
++ if (regulator_enable(priv->poc_supply[idx]))
++ dev_err(&client->dev, "fail to enable POC%d regulator\n", idx);
++ }
++
++ ti964_ti9x3_fpdlink3_setup(client, idx);
++ }
++
++ client->addr = priv->des_addr;
++
++ return 0;
++}
++
++#ifdef CONFIG_VIDEO_ADV_DEBUG
++static int ti964_ti9x3_g_register(struct v4l2_subdev *sd,
++ struct v4l2_dbg_register *reg)
++{
++ struct ti964_ti9x3_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 ti964_ti9x3_s_register(struct v4l2_subdev *sd,
++ const struct v4l2_dbg_register *reg)
++{
++ struct ti964_ti9x3_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 ti964_ti9x3_s_power(struct v4l2_subdev *sd, int on)
++{
++ struct ti964_ti9x3_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 ti964_ti9x3_registered_async(struct v4l2_subdev *sd)
++{
++ struct ti964_ti9x3_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 ti964_ti9x3_subdev_core_ops = {
++#ifdef CONFIG_VIDEO_ADV_DEBUG
++ .g_register = ti964_ti9x3_g_register,
++ .s_register = ti964_ti9x3_s_register,
++#endif
++ .s_power = ti964_ti9x3_s_power,
++ .registered_async = ti964_ti9x3_registered_async,
++};
++
++static struct v4l2_subdev_ops ti964_ti9x3_subdev_ops = {
++ .core = &ti964_ti9x3_subdev_core_ops,
++};
++
++static int ti964_ti9x3_parse_dt(struct i2c_client *client)
++{
++ struct ti964_ti9x3_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 */
++ char cable_mode_default[5] = "coax"; /* coax, stp */
++ struct property *csi_rate_prop, *dvp_order_prop;
++ u8 val = 0;
++
++ 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_HIGH, dev_name(&client->dev));
++ if (err)
++ dev_err(&client->dev, "cannot request PWEN gpio %d: %d\n", pwen, err);
++ else
++ mdelay(250);
++ }
++
++ reg8_read(client, 0x00, &val); /* read TI964 I2C address */
++ if (val != (priv->des_addr << 1)) {
++ prop = of_find_property(np, "reg", NULL);
++ if (prop)
++ of_remove_property(np, prop);
++ return -ENODEV;
++ }
++
++ ti964_ti9x3_read_chipid(client);
++
++ if (!of_property_read_u32(np, "ti,sensor_delay", &sensor_delay))
++ mdelay(sensor_delay);
++
++ err = of_property_read_string(np, "ti,forwarding-mode", &priv->forwarding_mode);
++ if (err)
++ priv->forwarding_mode = forwarding_mode_default;
++
++ err = of_property_read_string(np, "ti,cable-mode", &priv->cable_mode);
++ if (err)
++ priv->cable_mode = cable_mode_default;
++
++ 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_of_node[i] = 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 ti964_ti9x3_probe(struct i2c_client *client,
++ const struct i2c_device_id *did)
++{
++ struct ti964_ti9x3_priv *priv;
++ int err, i;
++ char supply_name[10];
++
++ 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 = ti964_ti9x3_parse_dt(client);
++ if (err)
++ goto out;
++
++ for (i = 0; i < 4; i++) {
++ sprintf(supply_name, "POC%d", i);
++ priv->poc_supply[i] = devm_regulator_get_optional(&client->dev, supply_name);
++ }
++
++ err = ti964_ti9x3_initialize(client);
++ if (err < 0)
++ goto out;
++
++ for (i = 0; i < priv->links; i++) {
++ v4l2_subdev_init(&priv->sd[i], &ti964_ti9x3_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].of_node = priv->sd_of_node[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 ti964_ti9x3_remove(struct i2c_client *client)
++{
++ struct ti964_ti9x3_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 ti964_ti9x3_dt_ids[] = {
++ { .compatible = "ti,ti964-ti9x3" },
++ {},
++};
++MODULE_DEVICE_TABLE(of, ti964_ti9x3_dt_ids);
++
++static const struct i2c_device_id ti964_ti9x3_id[] = {
++ { "ti964_ti9x3", 0 },
++ { }
++};
++MODULE_DEVICE_TABLE(i2c, ti964_ti9x3_id);
++
++static struct i2c_driver ti964_ti9x3_i2c_driver = {
++ .driver = {
++ .name = "ti964_ti9x3",
++ .of_match_table = of_match_ptr(ti964_ti9x3_dt_ids),
++ },
++ .probe = ti964_ti9x3_probe,
++ .remove = ti964_ti9x3_remove,
++ .id_table = ti964_ti9x3_id,
++};
++
++module_i2c_driver(ti964_ti9x3_i2c_driver);
++
++MODULE_DESCRIPTION("FPDLinkIII driver for TI964-TI9X3");
++MODULE_AUTHOR("Vladimir Barinov");
++MODULE_LICENSE("GPL");
+diff --git a/drivers/media/i2c/soc_camera/ti9x4_ti9x3.h b/drivers/media/i2c/soc_camera/ti9x4_ti9x3.h
+new file mode 100644
+index 0000000..69d3728
+--- /dev/null
++++ b/drivers/media/i2c/soc_camera/ti9x4_ti9x3.h
+@@ -0,0 +1,153 @@
++/*
++ * 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 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 4d95da6..2ef27e8 100644
+--- a/drivers/media/platform/soc_camera/rcar_csi2.c
++++ b/drivers/media/platform/soc_camera/rcar_csi2.c
+@@ -37,8 +37,9 @@
+
+ #include <media/v4l2-of.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
+@@ -63,6 +64,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
+
+@@ -70,6 +72,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)
+@@ -106,6 +112,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 */
+@@ -159,6 +168,11 @@
+ { }
+ };
+
++static const struct soc_device_attribute r8a7795[] = {
++ { .soc_id = "r8a7795", .revision = "ES2.0" },
++ { }
++};
++
+ enum chip_id {
+ RCAR_GEN3,
+ RCAR_GEN2,
+@@ -179,6 +193,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) \
+@@ -192,8 +207,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;
+@@ -205,7 +219,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
+@@ -251,6 +267,89 @@ 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)
+ {
+@@ -265,7 +364,7 @@ static int rcar_csi2_set_phy_freq(struct rcar_csi2 *priv)
+ 0x16, 0x36, 0x56, 0x76, 0x18, /* 1150M, 1200M, 1250M, 1300M, 1350M */
+ 0x38, 0x58, 0x78 /* 1400M, 1450M, 1500M */
+ };
+- const uint32_t const hs_freq_range[43] = {
++ const uint32_t const 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 */
+@@ -276,47 +375,33 @@ 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 const 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 const 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);
+@@ -325,16 +410,14 @@ 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))
++ iowrite32(hs_freq_range_h3[bps_per_lane] << 16,
++ priv->base + RCAR_CSI2_PHYPLL);
+ else
+- iowrite32(hs_freq_range[bps_per_lane] << 16,
++ /* 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)
+@@ -392,6 +475,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);
+@@ -404,11 +497,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);
+
+@@ -469,32 +578,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;
+@@ -543,18 +642,19 @@ static int rcar_csi2_parse_dt(struct device_node *np,
+ return -EINVAL;
+
+ v4l2_of_parse_endpoint(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);
+
+@@ -573,6 +673,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;
+
+@@ -587,6 +689,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;
+
+@@ -608,6 +712,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");
+
+@@ -618,12 +723,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)
+@@ -655,23 +755,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);
+
+@@ -684,10 +788,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 74fb005..496a8bd 100644
+--- a/drivers/media/platform/soc_camera/rcar_vin.c
++++ b/drivers/media/platform/soc_camera/rcar_vin.c
+@@ -106,6 +106,7 @@
+ #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 +139,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)
+@@ -408,6 +410,7 @@ enum csi2_fmt {
+ RCAR_CSI_FMT_NONE = -1,
+ RCAR_CSI_RGB888,
+ RCAR_CSI_YCBCR422,
++ RCAR_CSI_RAW8,
+ };
+
+ struct vin_coeff {
+@@ -773,10 +776,13 @@ struct rcar_vin_priv {
+ enum csi2_fmt csi_fmt;
+ enum virtual_ch vc;
+ bool csi_sync;
++ bool deser_sync;
+
+ 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;
+
+@@ -989,6 +995,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;
+ }
+@@ -1021,6 +1031,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;
+@@ -1043,6 +1057,10 @@ static int rcar_vin_setup(struct rcar_vin_priv *priv)
+
+ dmr = VNDMR_EXRGB | VNDMR_DTMD_ARGB;
+ break;
++ case V4L2_PIX_FMT_SBGGR8:
++ case V4L2_PIX_FMT_SBGGR12:
++ dmr = 0;
++ break;
+ default:
+ goto e_format;
+ }
+@@ -1061,7 +1079,9 @@ static int rcar_vin_setup(struct rcar_vin_priv *priv)
+ 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;
+ }
+@@ -1211,6 +1231,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)
+@@ -1361,6 +1385,31 @@ 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_max9271";
++ char name2[] = "ti964_ti9x3";
++ char name3[] = "ti954_ti9x3";
++
++ 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;
++ }
++ if (!strncmp(name3, sd->name, sizeof(name3) - 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);
+@@ -1375,7 +1424,8 @@ static int rcar_vin_add_device(struct soc_camera_device *icd)
+ 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);
+@@ -1390,6 +1440,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
+@@ -1417,6 +1479,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 */
+@@ -1443,6 +1506,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);
+@@ -1621,13 +1686,19 @@ static int rcar_vin_set_rect(struct soc_camera_device *icd)
+
+ if (priv->chip == RCAR_H3 || priv->chip == RCAR_M3 ||
+ priv->chip == RCAR_V3M) {
+- 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)) {
+ 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),
+@@ -1868,6 +1939,14 @@ static bool rcar_vin_packing_supported(const struct soc_mbus_pixelfmt *fmt)
+ .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,
+@@ -1899,6 +1978,22 @@ static bool rcar_vin_packing_supported(const struct soc_mbus_pixelfmt *fmt)
+ .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,
+@@ -2012,6 +2107,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;
+
+@@ -2218,12 +2315,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;
+@@ -2316,7 +2416,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
+@@ -2486,6 +2587,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,
+@@ -2504,6 +2618,7 @@ static int rcar_vin_cropcap(struct soc_camera_device *icd,
+ .get_selection = rcar_vin_get_selection,
+ .cropcap = rcar_vin_cropcap,
+ #endif
++ .get_edid = rcar_vin_get_edid,
+ };
+
+ #ifdef CONFIG_OF
+@@ -2524,7 +2639,7 @@ static int rcar_vin_cropcap(struct soc_camera_device *icd,
+ 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);
+
+@@ -2714,7 +2829,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, *ti964_ren = NULL, *ti954_ren = NULL;
+ bool csi_use = false;
++ bool max9286_use = false;
++ bool ti964_use = false;
++ bool ti954_use = false;
+
+ match = of_match_device(of_match_ptr(rcar_vin_of_table), &pdev->dev);
+
+@@ -2741,13 +2860,27 @@ 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-max9271") == 0) {
++ max9286_ren = of_parse_phandle(epn, "remote-endpoint", 0);
++ max9286_use = true;
++ }
+
+- if (i)
+- break;
++ if (strcmp(ren->parent->name, "ti964-ti9x3") == 0) {
++ ti964_ren = of_parse_phandle(epn, "remote-endpoint", 0);
++ ti964_use = true;
++ }
++
++ if (strcmp(ren->parent->name, "ti954-ti9x3") == 0) {
++ ti954_ren = of_parse_phandle(epn, "remote-endpoint", 0);
++ ti954_use = true;
++ }
++
++ of_node_put(ren);
+ }
+
+ ret = v4l2_of_parse_endpoint(np, &ep);
+@@ -2799,6 +2932,7 @@ 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) {
+@@ -2983,7 +3117,25 @@ 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 (ti964_use) {
++ ret = rcar_vin_soc_of_bind(priv, &priv->ici, epn, ti964_ren);
++ if (ret)
++ goto cleanup;
++ }
++
++ if (ti954_use) {
++ ret = rcar_vin_soc_of_bind(priv, &priv->ici, epn, ti954_ren);
+ if (ret)
+ goto cleanup;
+ }
+diff --git a/drivers/media/platform/soc_camera/soc_camera.c b/drivers/media/platform/soc_camera/soc_camera.c
+index edd1c1d..54f4c9d 100644
+--- a/drivers/media/platform/soc_camera/soc_camera.c
++++ b/drivers/media/platform/soc_camera/soc_camera.c
+@@ -49,7 +49,7 @@
+ (icd)->vb_vidq.streaming : \
+ vb2_is_streaming(&(icd)->vb2_vidq))
+
+-#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);
+@@ -1106,6 +1106,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);
+
+@@ -1664,7 +1676,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;
+ }
+ }
+@@ -2077,6 +2089,7 @@ static int soc_camera_device_register(struct soc_camera_device *icd)
+ .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 e3e665e..84754a4 100644
+--- a/drivers/media/platform/soc_camera/soc_mediabus.c
++++ b/drivers/media/platform/soc_camera/soc_mediabus.c
+@@ -57,6 +57,16 @@
+ .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/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 1a15c3e..dad1ed8 100644
+--- a/include/media/soc_camera.h
++++ b/include/media/soc_camera.h
+@@ -125,6 +125,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)
+--
+1.9.1
+
diff --git a/meta-rcar-gen3-adas/recipes-kernel/linux/linux-renesas/0031-media-i2c-Add-ov5647-sensor.patch b/meta-rcar-gen3-adas/recipes-kernel/linux/linux-renesas/0031-media-i2c-Add-ov5647-sensor.patch
new file mode 100644
index 0000000..1cd366c
--- /dev/null
+++ b/meta-rcar-gen3-adas/recipes-kernel/linux/linux-renesas/0031-media-i2c-Add-ov5647-sensor.patch
@@ -0,0 +1,952 @@
+From 8b97232e3ecbb4ee38bda454915e62914ef52fcc 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] 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 | 649 ++++++++++++++++++++++++++++++++++
+ drivers/media/i2c/soc_camera/ov5647.h | 242 +++++++++++++
+ 4 files changed, 898 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 e1c65ca..c272aeb 100644
+--- a/drivers/media/i2c/soc_camera/Kconfig
++++ b/drivers/media/i2c/soc_camera/Kconfig
+@@ -97,6 +97,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_OV6650
+ tristate "ov6650 sensor support"
+ depends on SOC_CAMERA && I2C
+diff --git a/drivers/media/i2c/soc_camera/Makefile b/drivers/media/i2c/soc_camera/Makefile
+index 8e24d5d..a67fff8 100644
+--- a/drivers/media/i2c/soc_camera/Makefile
++++ b/drivers/media/i2c/soc_camera/Makefile
+@@ -13,6 +13,7 @@ obj-$(CONFIG_SOC_CAMERA_OV495_OV2775) += ov495_ov2775.o
+ obj-$(CONFIG_SOC_CAMERA_OV106XX) += ov106xx.o
+ obj-$(CONFIG_SOC_CAMERA_OV2640) += ov2640.o
+ obj-$(CONFIG_SOC_CAMERA_OV5642) += ov5642.o
++obj-$(CONFIG_SOC_CAMERA_OV5647) += ov5647.o
+ obj-$(CONFIG_SOC_CAMERA_OV6650) += ov6650.o
+ obj-$(CONFIG_SOC_CAMERA_OV772X) += ov772x.o
+ obj-$(CONFIG_SOC_CAMERA_OV9640) += ov9640.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..caccf39
+--- /dev/null
++++ b/drivers/media/i2c/soc_camera/ov5647.c
+@@ -0,0 +1,649 @@
++/*
++ * 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 <media/v4l2-of.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*/
++};
+--
+1.9.1
+
diff --git a/meta-rcar-gen3-adas/recipes-kernel/linux/linux-renesas/0032-media-i2c-Add-ov5642-sensor.patch b/meta-rcar-gen3-adas/recipes-kernel/linux/linux-renesas/0032-media-i2c-Add-ov5642-sensor.patch
new file mode 100644
index 0000000..99183fa
--- /dev/null
+++ b/meta-rcar-gen3-adas/recipes-kernel/linux/linux-renesas/0032-media-i2c-Add-ov5642-sensor.patch
@@ -0,0 +1,2173 @@
+From 79ff5931fa2dede0a4c2e22e7a83c2edddcc6c20 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] 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 | 708 +++++-----------------------
+ drivers/media/i2c/soc_camera/ov5642.h | 592 ++++++++++++++++++++++++
+ drivers/media/i2c/soc_camera/ov5642_720p.h | 711 +++++++++++++++++++++++++++++
+ 3 files changed, 1418 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 bab9ac0..b58859e 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,
+@@ -866,15 +303,15 @@ static int ov5642_s_crop(struct v4l2_subdev *sd, const struct v4l2_crop *a)
+ 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;
+ }
+
+@@ -909,10 +346,10 @@ static int ov5642_cropcap(struct v4l2_subdev *sd, struct v4l2_cropcap *a)
+ 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;
+ }
+
+@@ -930,12 +367,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;
+ }
+
+@@ -966,6 +406,63 @@ static 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);
+@@ -1008,19 +505,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];
+
+@@ -1036,8 +537,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;
+ }
+@@ -1060,8 +573,17 @@ static const struct i2c_device_id ov5642_id[] = {
+ };
+ MODULE_DEVICE_TABLE(i2c, ov5642_id);
+
++#if IS_ENABLED(CONFIG_OF)
++static const struct of_device_id ov5642_of_match[] = {
++ { .compatible = "ovti,ov5642" },
++ { /* sentinel */ },
++};
++MODULE_DEVICE_TABLE(of, ov5642_of_match);
++#endif
++
+ static struct i2c_driver ov5642_i2c_driver = {
+ .driver = {
++ .of_match_table = of_match_ptr(ov5642_of_match),
+ .name = "ov5642",
+ },
+ .probe = ov5642_probe,
+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},
++};
+--
+1.9.1
+
diff --git a/meta-rcar-gen3-adas/recipes-kernel/linux/linux-renesas/0033-media-soc-camera-fix-parallel-i-f-in-VIN.patch b/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 0000000..c56049a
--- /dev/null
+++ b/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 112395ed601c67a6ba935cec0107335e966888dc 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] 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 f5c2528..a9cb72d 100644
+--- a/drivers/media/platform/soc_camera/rcar_vin.c
++++ b/drivers/media/platform/soc_camera/rcar_vin.c
+@@ -149,6 +149,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)
+
+@@ -1850,10 +1853,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);
+@@ -2937,8 +2945,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;
+@@ -2973,12 +2981,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)
+--
+1.9.1
+
diff --git a/meta-rcar-gen3-adas/recipes-kernel/linux/linux-renesas/0034-media-soc_camera-Fix-VIDIOC_S_SELECTION-ioctl-miscal.patch b/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 0000000..fb15260
--- /dev/null
+++ b/meta-rcar-gen3-adas/recipes-kernel/linux/linux-renesas/0034-media-soc_camera-Fix-VIDIOC_S_SELECTION-ioctl-miscal.patch
@@ -0,0 +1,67 @@
+From 4b971606c7ef3e85be57b31d2583e169f983d91f 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] 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 | 10 +++++-----
+ 1 file changed, 5 insertions(+), 5 deletions(-)
+
+diff --git a/drivers/media/platform/soc_camera/soc_scale_crop.c b/drivers/media/platform/soc_camera/soc_scale_crop.c
+index f77252d..79a7d95 100644
+--- a/drivers/media/platform/soc_camera/soc_scale_crop.c
++++ b/drivers/media/platform/soc_camera/soc_scale_crop.c
+@@ -72,14 +72,14 @@ static void update_subrect(struct v4l2_rect *rect, struct v4l2_rect *subrect)
+
+ if (rect->left > subrect->left)
+ subrect->left = rect->left;
+- else if (rect->left + rect->width >
++ else if (rect->left + rect->width <
+ subrect->left + subrect->width)
+ subrect->left = rect->left + rect->width -
+ subrect->width;
+
+ if (rect->top > subrect->top)
+ subrect->top = rect->top;
+- else if (rect->top + rect->height >
++ else if (rect->top + rect->height <
+ subrect->top + subrect->height)
+ subrect->top = rect->top + rect->height -
+ subrect->height;
+@@ -125,6 +125,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;
+ }
+
+@@ -216,6 +217,7 @@ int soc_camera_client_s_selection(struct v4l2_subdev *sd,
+
+ if (!ret) {
+ *target_rect = *cam_rect;
++ *subrect = *rect;
+ update_subrect(target_rect, subrect);
+ }
+
+@@ -296,9 +298,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)
+ update_subrect(rect, subrect);
+
+ return 0;
+--
+1.9.1
+
diff --git a/meta-rcar-gen3-adas/recipes-kernel/linux/linux-renesas/0035-regulator-fixed-probe-after-i2c.patch b/meta-rcar-gen3-adas/recipes-kernel/linux/linux-renesas/0035-regulator-fixed-probe-after-i2c.patch
new file mode 100644
index 0000000..31c79ce
--- /dev/null
+++ b/meta-rcar-gen3-adas/recipes-kernel/linux/linux-renesas/0035-regulator-fixed-probe-after-i2c.patch
@@ -0,0 +1,53 @@
+From ef0ae334de1e1b318f4fb26bc8045451318a60c4 Mon Sep 17 00:00:00 2001
+From: Vladimir Barinov <vladimir.barinov@cogentembedded.com>
+Date: Sun, 26 Nov 2017 21:35:54 +0300
+Subject: [PATCH] regulator: fixed: probe after i2c
+
+This is a workaround for LVDS cameras that use I2C gpio expanders.
+Set fixed regulator booted after i2c expander to have PoC
+power controlled in LVDS driver.
+
+Signed-off-by: Vladimir Barinov <vladimir.barinov@cogentembedded.com>
+---
+ drivers/Makefile | 4 +++-
+ drivers/regulator/fixed.c | 2 +-
+ 2 files changed, 4 insertions(+), 2 deletions(-)
+
+diff --git a/drivers/Makefile b/drivers/Makefile
+index 194d20b..f49ed8f 100644
+--- a/drivers/Makefile
++++ b/drivers/Makefile
+@@ -41,6 +41,8 @@ obj-y += soc/
+ obj-$(CONFIG_VIRTIO) += virtio/
+ obj-$(CONFIG_XEN) += xen/
+
++obj-y += i2c/
++
+ # regulators early, since some subsystems rely on them to initialize
+ obj-$(CONFIG_REGULATOR) += regulator/
+
+@@ -105,7 +107,7 @@ obj-$(CONFIG_SERIO) += input/serio/
+ obj-$(CONFIG_GAMEPORT) += input/gameport/
+ obj-$(CONFIG_INPUT) += input/
+ obj-$(CONFIG_RTC_LIB) += rtc/
+-obj-y += i2c/ media/
++obj-y += media/
+ obj-$(CONFIG_PPS) += pps/
+ obj-$(CONFIG_PTP_1588_CLOCK) += ptp/
+ obj-$(CONFIG_W1) += w1/
+diff --git a/drivers/regulator/fixed.c b/drivers/regulator/fixed.c
+index 988a747..44a169c 100644
+--- a/drivers/regulator/fixed.c
++++ b/drivers/regulator/fixed.c
+@@ -211,7 +211,7 @@ static int __init regulator_fixed_voltage_init(void)
+ {
+ return platform_driver_register(&regulator_fixed_voltage_driver);
+ }
+-subsys_initcall(regulator_fixed_voltage_init);
++module_init(regulator_fixed_voltage_init);
+
+ static void __exit regulator_fixed_voltage_exit(void)
+ {
+--
+1.9.1
+
diff --git a/meta-rcar-gen3-adas/recipes-kernel/linux/linux-renesas/0040-arm64-dts-renesas-add-ADAS-boards.patch b/meta-rcar-gen3-adas/recipes-kernel/linux/linux-renesas/0040-arm64-dts-renesas-add-ADAS-boards.patch
new file mode 100644
index 0000000..9db9056
--- /dev/null
+++ b/meta-rcar-gen3-adas/recipes-kernel/linux/linux-renesas/0040-arm64-dts-renesas-add-ADAS-boards.patch
@@ -0,0 +1,17543 @@
+From 51718d8f768ba719a8a295e013e3456e13b70a98 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] 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 R8A7797 SoC
+Videobox board on R8A7795 ES1.x SoC
+Videobox board on R8A7795 SoC
+Eagle board on R8A7797 SoC
+V3MSK board on R8A7797 SoC
+V3MSK.View board on R8A7797 SoC
+Videobox Mini board on R8A7795 ES1.x SoC
+Videobox Mini board on R8A7795 SoC
+Videobox Mini board on R8A7797 SoC
+
+Signed-off-by: Vladimir Barinov <vladimir.barinov@cogentembedded.com>
+---
+ arch/arm64/boot/dts/renesas/Makefile | 19 +
+ arch/arm64/boot/dts/renesas/legacy/Makefile | 8 +
+ .../renesas/legacy/r8a7795-es1-h3ulcb-kf-v0.dts | 1710 +++++++++++++++++++
+ .../renesas/legacy/r8a7795-es1-h3ulcb-kf-v1.dts | 441 +++++
+ .../dts/renesas/legacy/r8a7795-h3ulcb-kf-v0.dts | 1724 +++++++++++++++++++
+ .../dts/renesas/legacy/r8a7795-h3ulcb-kf-v1.dts | 465 ++++++
+ .../dts/renesas/legacy/r8a7796-m3ulcb-kf-v0.dts | 1214 ++++++++++++++
+ .../dts/renesas/legacy/r8a7796-m3ulcb-kf-v1.dts | 465 ++++++
+ .../dts/renesas/legacy/r8a7797-v3msk-kf-v0.dts | 82 +
+ .../boot/dts/renesas/legacy/ulcb-kf-cmos.dtsi | 75 +
+ .../arm64/boot/dts/renesas/legacy/ulcb-kf-rpi.dtsi | 77 +
+ .../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 | 225 +++
+ .../boot/dts/renesas/r8a7795-es1-h3ulcb-kf.dts | 39 +
+ .../boot/dts/renesas/r8a7795-es1-h3ulcb-vb.dts | 69 +
+ .../boot/dts/renesas/r8a7795-es1-h3ulcb-vbm.dts | 26 +
+ .../boot/dts/renesas/r8a7795-es1-h3ulcb-view.dts | 546 +++++++
+ .../dts/renesas/r8a7795-es1-salvator-x-view.dts | 552 +++++++
+ .../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 | 219 +++
+ arch/arm64/boot/dts/renesas/r8a7795-h3ulcb-kf.dts | 39 +
+ arch/arm64/boot/dts/renesas/r8a7795-h3ulcb-vb.dts | 68 +
+ arch/arm64/boot/dts/renesas/r8a7795-h3ulcb-vbm.dts | 26 +
+ .../arm64/boot/dts/renesas/r8a7795-h3ulcb-view.dts | 546 +++++++
+ .../boot/dts/renesas/r8a7795-salvator-x-view.dts | 552 +++++++
+ arch/arm64/boot/dts/renesas/r8a7796-m3ulcb-kf.dts | 40 +
+ .../arm64/boot/dts/renesas/r8a7796-m3ulcb-view.dts | 287 ++++
+ .../boot/dts/renesas/r8a7796-salvator-x-view.dts | 318 ++++
+ arch/arm64/boot/dts/renesas/r8a7797-eagle.dts | 560 +++++++
+ arch/arm64/boot/dts/renesas/r8a7797-v3msk-kf.dts | 578 +++++++
+ arch/arm64/boot/dts/renesas/r8a7797-v3msk-vbm.dts | 518 ++++++
+ arch/arm64/boot/dts/renesas/r8a7797-v3msk-view.dts | 298 ++++
+ arch/arm64/boot/dts/renesas/r8a7797-v3msk.dts | 314 ++++
+ arch/arm64/boot/dts/renesas/ulcb-kf-cn11.dtsi | 545 ++++++
+ 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 | 1541 +++++++++++++++++
+ arch/arm64/boot/dts/renesas/ulcb-vb-cn12.dtsi | 515 ++++++
+ arch/arm64/boot/dts/renesas/ulcb-vb.dtsi | 1726 ++++++++++++++++++++
+ arch/arm64/boot/dts/renesas/ulcb-vbm.dtsi | 578 +++++++
+ 42 files changed, 17171 insertions(+)
+ create mode 100644 arch/arm64/boot/dts/renesas/legacy/Makefile
+ create mode 100644 arch/arm64/boot/dts/renesas/legacy/r8a7795-es1-h3ulcb-kf-v0.dts
+ create mode 100644 arch/arm64/boot/dts/renesas/legacy/r8a7795-es1-h3ulcb-kf-v1.dts
+ create mode 100644 arch/arm64/boot/dts/renesas/legacy/r8a7795-h3ulcb-kf-v0.dts
+ create mode 100644 arch/arm64/boot/dts/renesas/legacy/r8a7795-h3ulcb-kf-v1.dts
+ create mode 100644 arch/arm64/boot/dts/renesas/legacy/r8a7796-m3ulcb-kf-v0.dts
+ create mode 100644 arch/arm64/boot/dts/renesas/legacy/r8a7796-m3ulcb-kf-v1.dts
+ create mode 100644 arch/arm64/boot/dts/renesas/legacy/r8a7797-v3msk-kf-v0.dts
+ create mode 100644 arch/arm64/boot/dts/renesas/legacy/ulcb-kf-cmos.dtsi
+ create mode 100644 arch/arm64/boot/dts/renesas/legacy/ulcb-kf-rpi.dtsi
+ 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-kf.dts
+ create mode 100644 arch/arm64/boot/dts/renesas/r8a7795-es1-h3ulcb-vb.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-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-kf.dts
+ create mode 100644 arch/arm64/boot/dts/renesas/r8a7795-h3ulcb-vb.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-kf.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/r8a7797-eagle.dts
+ create mode 100644 arch/arm64/boot/dts/renesas/r8a7797-v3msk-kf.dts
+ create mode 100644 arch/arm64/boot/dts/renesas/r8a7797-v3msk-vbm.dts
+ create mode 100644 arch/arm64/boot/dts/renesas/r8a7797-v3msk-view.dts
+ create mode 100644 arch/arm64/boot/dts/renesas/r8a7797-v3msk.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-kf.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-vbm.dtsi
+
+diff --git a/arch/arm64/boot/dts/renesas/Makefile b/arch/arm64/boot/dts/renesas/Makefile
+index f9c71df..af88350 100644
+--- a/arch/arm64/boot/dts/renesas/Makefile
++++ b/arch/arm64/boot/dts/renesas/Makefile
+@@ -6,5 +6,24 @@ dtb-$(CONFIG_ARCH_R8A7796) += r8a7796-salvator-xs.dtb
+ dtb-$(CONFIG_ARCH_R8A77965) += r8a77965-salvator-x.dtb
+ dtb-$(CONFIG_ARCH_R8A77965) += r8a77965-salvator-xs.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
++dtb-$(CONFIG_ARCH_R8A7795) += r8a7795-h3ulcb-vb.dtb r8a7795-es1-h3ulcb-vb.dtb
++dtb-$(CONFIG_ARCH_R8A7795) += r8a7795-h3ulcb-vbm.dtb r8a7795-es1-h3ulcb-vbm.dtb
++dtb-$(CONFIG_ARCH_R8A7797) += r8a7797-eagle.dtb
++dtb-$(CONFIG_ARCH_R8A7797) += r8a7797-v3msk.dtb
++dtb-$(CONFIG_ARCH_R8A7797) += r8a7797-v3msk-view.dtb
++dtb-$(CONFIG_ARCH_R8A7797) += r8a7797-v3msk-kf.dtb
++dtb-$(CONFIG_ARCH_R8A7797) += r8a7797-v3msk-vbm.dtb
++
++# ADAS legacy boards
++subdir-y := legacy
++
+ always := $(dtb-y)
+ clean-files := *.dtb
+diff --git a/arch/arm64/boot/dts/renesas/legacy/Makefile b/arch/arm64/boot/dts/renesas/legacy/Makefile
+new file mode 100644
+index 0000000..7f25079
+--- /dev/null
++++ b/arch/arm64/boot/dts/renesas/legacy/Makefile
+@@ -0,0 +1,8 @@
++# Legacy KF board: V0, V1 (V2 is the same as V1), V3 is latest and deployed in default directory
++dtb-$(CONFIG_ARCH_R8A7795) += r8a7795-es1-h3ulcb-kf-v0.dtb r8a7795-es1-h3ulcb-kf-v1.dtb
++dtb-$(CONFIG_ARCH_R8A7796) += r8a7796-m3ulcb-kf-v0.dtb r8a7796-m3ulcb-kf-v1.dtb
++dtb-$(CONFIG_ARCH_R8A7795) += r8a7795-h3ulcb-kf-v0.dtb r8a7795-h3ulcb-kf-v1.dtb
++dtb-$(CONFIG_ARCH_R8A7797) += r8a7797-v3msk-kf-v0.dtb
++
++always := $(dtb-y)
++clean-files := *.dtb
+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
+new file mode 100644
+index 0000000..2fee788
+--- /dev/null
++++ b/arch/arm64/boot/dts/renesas/legacy/r8a7795-es1-h3ulcb-kf-v0.dts
+@@ -0,0 +1,1710 @@
++/*
++ * Device Tree Source for the H3ULCB Kingfisher V0 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"
++
++/ {
++ model = "Renesas H3ULCB Kingfisher V0 board based on r8a7795";
++
++ aliases {
++ serial1 = &hscif4;
++ };
++
++ 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_ext_20 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>;
++ regulator-always-on;
++ };
++
++ 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_ext_20 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_ext_20 0 0>;
++
++ startup-delay-us = <0>;
++ enable-active-high;
++ };
++
++ lvds_switch: regulator@8 {
++ compatible = "regulator-fixed";
++ regulator-name = "lvds_on";
++ regulator-min-microvolt = <3300000>;
++ regulator-max-microvolt = <3300000>;
++ /* gpio = <&gpio1 24 0>; */
++ enable-active-high;
++ regulator-always-on;
++ };
++
++ sdio_switch: regulator@9 {
++ compatible = "regulator-fixed";
++ regulator-name = "wifi_on";
++ regulator-min-microvolt = <3300000>;
++ regulator-max-microvolt = <3300000>;
++ gpio = <&gpio_ext_20 5 0>;
++ enable-active-low;
++ regulator-always-on;
++ };
++
++ sound_switch: regulator@10 {
++ compatible = "regulator-fixed";
++ regulator-name = "pcm3168a_on";
++ regulator-min-microvolt = <3300000>;
++ regulator-max-microvolt = <3300000>;
++ gpio = <&gpio_ext_21 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_ext_20 13 GPIO_ACTIVE_HIGH>;
++ enable-active-high;
++ regulator-always-on;
++ };
++
++ kim {
++ compatible = "kim";
++ shutdown-gpios = <&gpio_ext_20 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 = "simple-audio-card";
++
++ simple-audio-card,format = "left_j";
++ simple-audio-card,name = "pcm3168a";
++
++ simple-audio-card,bitclock-master = <&sound_ext_master>;
++ simple-audio-card,frame-master = <&sound_ext_master>;
++ sound_ext_master: simple-audio-card,cpu@0 {
++ sound-dai = <&rcar_sound 0>;
++ dai-tdm-slot-num = <8>;
++ dai-tdm-slot-width = <32>;
++ };
++
++ simple-audio-card,codec@0 {
++ sound-dai = <&pcm3168a>;
++ dai-tdm-slot-num = <8>;
++ dai-tdm-slot-width = <32>;
++ system-clock-frequency = <24576000>;
++ };
++ };
++
++ /delete-node/sound;
++
++ rsnd_ak4613: sound@1 {
++ pinctrl-0 = <&sound_1_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 1>;
++ };
++
++ sndcodec: simple-audio-card,codec@1 {
++ sound-dai = <&ak4613>;
++ };
++ };
++
++ sound_radio: sound@2 {
++ pinctrl-0 = <&sound_2_pins>;
++ pinctrl-names = "default";
++ compatible = "simple-audio-card";
++
++ simple-audio-card,format = "i2s";
++ simple-audio-card,name = "radio";
++
++ simple-audio-card,bitclock-master = <&sound_radio_master>;
++ simple-audio-card,frame-master = <&sound_radio_master>;
++ simple-audio-card,cpu@2 {
++ sound-dai = <&rcar_sound 2>;
++ };
++
++ sound_radio_master: simple-audio-card,codec@2 {
++ sound-dai = <&radio>;
++ system-clock-frequency = <12288000>;
++ };
++ };
++
++ lvds-encoder {
++ compatible = "thine,thc63lvdm83d";
++
++ ports {
++ #address-cells = <1>;
++ #size-cells = <0>;
++ port@0 {
++ reg = <0>;
++ lvds_enc_in: endpoint {
++ remote-endpoint = <&du_out_lvds0>;
++ };
++ };
++ port@1 {
++ reg = <1>;
++ lvds_enc_out: endpoint {
++ remote-endpoint = <&lvds_in>;
++ };
++ };
++ };
++ };
++
++ lvds {
++ compatible = "lvds-connector";
++
++ 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 = <&lvds_enc_out>;
++ };
++ };
++ };
++
++ radio: si468x@0 {
++ compatible = "si,si468x-pcm";
++ status = "okay";
++
++ #sound-dai-cells = <0>;
++ };
++};
++
++&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>;
++ };
++
++ sound_0_pins: sound0 {
++ groups = "ssi78_ctrl", "ssi7_data", "ssi8_data";
++ function = "ssi";
++ };
++
++ sound_1_pins: sound1 {
++ groups = "ssi01239_ctrl", "ssi0_data", "ssi1_data_a";
++ function = "ssi";
++ };
++
++ sound_2_pins: sound2 {
++ groups = "ssi6_ctrl", "ssi6_data";
++ 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";
++ };
++};
++
++&du {
++ ports {
++ port@3 {
++ endpoint {
++ remote-endpoint = <&lvds_enc_in>;
++ };
++ };
++ };
++};
++
++&gpio0 {
++ video_a_irq {
++ gpio-hog;
++ gpios = <13 GPIO_ACTIVE_HIGH>;
++ input;
++ line-name = "Video-A irq";
++ };
++
++ video_b_irq {
++ gpio-hog;
++ gpios = <14 GPIO_ACTIVE_HIGH>;
++ input;
++ line-name = "Video-B irq";
++ };
++
++ gpioext_2_20_irq {
++ gpio-hog;
++ gpios = <15 GPIO_ACTIVE_HIGH>;
++ input;
++ line-name = "0x20@i2c2 irq";
++ };
++};
++
++&gpio1 {
++ gpioext_2_21_irq {
++ gpio-hog;
++ gpios = <15 GPIO_ACTIVE_HIGH>;
++ input;
++ line-name = "0x21@i2c2 irq";
++ };
++
++ wifi_irq {
++ gpio-hog;
++ gpios = <25 GPIO_ACTIVE_HIGH>;
++ input;
++ line-name = "wifi irq";
++ };
++};
++
++&gpio5 {
++ touch_irq {
++ gpio-hog;
++ gpios = <6 GPIO_ACTIVE_HIGH>;
++ input;
++ line-name = "touch irq";
++ };
++
++ /* From TI forum */
++ /* BT_AUD_OUT should be pulled low when WL_EN is activated. */
++ /* in case it isn't, wilink8 ends up in one of the test modes that introduces various issues */
++ bt_strap {
++ gpio-hog;
++ gpios = <14 GPIO_ACTIVE_HIGH>;
++ output-low;
++ line-name = "BT strap pin";
++ };
++};
++
++&gpio7 {
++ gpioext_2_21_irq {
++ gpio-hog;
++ gpios = <3 GPIO_ACTIVE_HIGH>;
++ input;
++ line-name = "0x21@i2c4 irq";
++ };
++};
++
++&hscif4 {
++ pinctrl-0 = <&hscif4_pins>;
++ pinctrl-names = "default";
++ uart-has-rtscts;
++
++ status = "okay";
++};
++
++&i2c2 {
++ clock-frequency = <400000>;
++
++ gpio_ext_20: pca9535@20 {
++ compatible = "nxp,pca9535";
++ reg = <0x20>;
++ gpio-controller;
++ #gpio-cells = <2>;
++ interrupt-controller;
++ interrupt-parent = <&gpio0>;
++ interrupts = <15 IRQ_TYPE_EDGE_FALLING>;
++ };
++
++ gpio_ext_21: pca9535@21 {
++ compatible = "nxp,pca9535";
++ reg = <0x21>;
++ gpio-controller;
++ #gpio-cells = <2>;
++ interrupt-controller;
++ interrupt-parent = <&gpio1>;
++ interrupts = <15 IRQ_TYPE_EDGE_FALLING>;
++ };
++
++ 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>;
++ /* 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>;
++ /* A2B node(s) */
++ };
++
++ 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>;
++ };
++
++ lsm9ds0_acc_mag@1d {
++ compatible = "st,lsm9ds0_accel_magn";
++ reg = <0x1d>;
++ };
++
++ lsm9ds0_gyr@6b {
++ compatible = "st,lsm9ds0_gyro";
++ reg = <0x6b>;
++ };
++
++ /* GPS@ 0x42 */
++ };
++ };
++};
++
++&i2c4 {
++ gpio_ext_22: pca9535@21 {
++ compatible = "nxp,pca9535";
++ reg = <0x22>;
++ gpio-controller;
++ #gpio-cells = <2>;
++ interrupt-controller;
++ interrupt-parent = <&gpio7>;
++ interrupts = <3 IRQ_TYPE_EDGE_FALLING>;
++
++ 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";
++ };
++ };
++
++ i2cswitch4: pca9548@74 {
++ compatible = "nxp,pca9548";
++ #address-cells = <1>;
++ #size-cells = <0>;
++ reg = <0x74>;
++ reset-gpios= <&gpio6 21 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_ti964_des0ep0: endpoint@1 {
++ remote-endpoint = <&ti964_des0ep0>;
++ };
++ ov106xx_ti954_des0ep0: endpoint@2 {
++ remote-endpoint = <&ti954_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_ti964_des0ep1: endpoint@1 {
++ remote-endpoint = <&ti964_des0ep1>;
++ };
++ ov106xx_ti954_des0ep1: endpoint@2 {
++ remote-endpoint = <&ti954_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_ti964_des0ep2: endpoint@1 {
++ remote-endpoint = <&ti964_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_ti964_des0ep3: endpoint@1 {
++ remote-endpoint = <&ti964_des0ep3>;
++ };
++ };
++ };
++
++ /* DS90UB964 @ 0x3a */
++ ti964-ti9x3@0 {
++ compatible = "ti,ti964-ti9x3";
++ reg = <0x3a>;
++ ti,sensor_delay = <350>;
++ ti,links = <4>;
++ ti,lanes = <4>;
++ ti,forwarding-mode = "round-robin";
++ ti,cable-mode = "coax";
++
++ port@0 {
++ ti964_des0ep0: endpoint@0 {
++ ti9x3-addr = <0x0c>;
++ dvp-order = <0>;
++ remote-endpoint = <&ov106xx_in0>;
++ };
++ ti964_des0ep1: endpoint@1 {
++ ti9x3-addr = <0x0d>;
++ dvp-order = <0>;
++ remote-endpoint = <&ov106xx_in1>;
++ };
++ ti964_des0ep2: endpoint@2 {
++ ti9x3-addr = <0x0e>;
++ dvp-order = <0>;
++ remote-endpoint = <&ov106xx_in2>;
++ };
++ ti964_des0ep3: endpoint@3 {
++ ti9x3-addr = <0x0f>;
++ dvp-order = <0>;
++ remote-endpoint = <&ov106xx_in3>;
++ };
++ };
++ port@1 {
++ ti964_csi0ep0: endpoint {
++ csi-rate = <1450>;
++ remote-endpoint = <&csi2_40_ep>;
++ };
++ };
++ };
++
++ /* DS90UB954 @ 0x38 */
++ ti954-ti9x3@0 {
++ compatible = "ti,ti954-ti9x3";
++ reg = <0x38>;
++ /* gpios = <&video_a_ext1 10 GPIO_ACTIVE_HIGH>; */
++ ti,sensor_delay = <350>;
++ ti,links = <2>;
++ ti,lanes = <4>;
++ ti,forwarding-mode = "round-robin";
++ ti,cable-mode = "coax";
++
++ port@0 {
++ ti954_des0ep0: endpoint@0 {
++ ti9x3-addr = <0x0c>;
++ dvp-order = <0>;
++ remote-endpoint = <&ov106xx_in0>;
++ };
++ ti954_des0ep1: endpoint@1 {
++ ti9x3-addr = <0x0d>;
++ dvp-order = <0>;
++ remote-endpoint = <&ov106xx_in1>;
++ };
++ };
++ port@1 {
++ ti954_csi0ep0: endpoint {
++ csi-rate = <1450>;
++ remote-endpoint = <&csi2_40_ep>;
++ };
++ };
++ };
++
++ /* MAX9286 @ 0x2c */
++ max9286-max9271@0 {
++ compatible = "maxim,max9286-max9271";
++ reg = <0x2c>;
++ maxim,sensor_delay = <350>;
++ 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>;
++ };
++ };
++ };
++ };
++
++ 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_ti964_des1ep0: endpoint@1 {
++ remote-endpoint = <&ti964_des1ep0>;
++ };
++ ov106xx_ti954_des1ep0: endpoint@2 {
++ remote-endpoint = <&ti954_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_ti964_des1ep1: endpoint@1 {
++ remote-endpoint = <&ti964_des1ep1>;
++ };
++ ov106xx_ti954_des1ep1: endpoint@2 {
++ remote-endpoint = <&ti954_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_ti964_des1ep2: endpoint@1 {
++ remote-endpoint = <&ti964_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_ti964_des1ep3: endpoint@1 {
++ remote-endpoint = <&ti964_des1ep3>;
++ };
++ };
++ };
++
++ /* DS90UB964 @ 0x3a */
++ ti964-ti9x3@1 {
++ compatible = "ti,ti964-ti9x3";
++ reg = <0x3a>;
++ ti,sensor_delay = <350>;
++ ti,links = <4>;
++ ti,lanes = <4>;
++ ti,forwarding-mode = "round-robin";
++ ti,cable-mode = "coax";
++
++ port@0 {
++ ti964_des1ep0: endpoint@0 {
++ ti9x3-addr = <0x0c>;
++ dvp-order = <0>;
++ remote-endpoint = <&ov106xx_in4>;
++ };
++ ti964_des1ep1: endpoint@1 {
++ ti9x3-addr = <0x0d>;
++ dvp-order = <0>;
++ remote-endpoint = <&ov106xx_in5>;
++ };
++ ti964_des1ep2: endpoint@2 {
++ ti9x3-addr = <0x0e>;
++ dvp-order = <0>;
++ remote-endpoint = <&ov106xx_in6>;
++ };
++ ti964_des1ep3: endpoint@3 {
++ ti9x3-addr = <0x0f>;
++ dvp-order = <0>;
++ remote-endpoint = <&ov106xx_in7>;
++ };
++ };
++ port@1 {
++ ti964_csi2ep0: endpoint {
++ csi-rate = <1450>;
++ remote-endpoint = <&csi2_41_ep>;
++ };
++ };
++ };
++
++ /* DS90UB954 @ 0x38 */
++ ti954-ti9x3@1 {
++ compatible = "ti,ti954-ti9x3";
++ reg = <0x38>;
++ /* gpios = <&video_b_ext1 10 GPIO_ACTIVE_HIGH>; */
++ ti,sensor_delay = <350>;
++ ti,links = <2>;
++ ti,lanes = <4>;
++ ti,forwarding-mode = "round-robin";
++ ti,cable-mode = "coax";
++
++ port@0 {
++ ti954_des1ep0: endpoint@0 {
++ ti9x3-addr = <0x0c>;
++ dvp-order = <0>;
++ remote-endpoint = <&ov106xx_in4>;
++ };
++ ti954_des1ep1: endpoint@1 {
++ ti9x3-addr = <0x0d>;
++ dvp-order = <0>;
++ remote-endpoint = <&ov106xx_in5>;
++ };
++ };
++ port@1 {
++ ti954_csi2ep0: endpoint {
++ csi-rate = <1450>;
++ remote-endpoint = <&csi2_41_ep>;
++ };
++ };
++ };
++
++ /* MAX9286 @ 0x2c */
++ max9286-max9271@1 {
++ compatible = "maxim,max9286-max9271";
++ reg = <0x2c>;
++ maxim,sensor_delay = <350>;
++ 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 = <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 = <&csi2_41_ep>;
++ };
++ };
++ };
++ };
++
++ i2c@6 {
++ #address-cells = <1>;
++ #size-cells = <0>;
++ reg = <6>;
++ /* Slot B (CN11) */
++
++ video_b_ext0: pca9535@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";
++ };
++ };
++
++ video_b_ext1: max7325@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_cam_pwr0 {
++ gpio-hog;
++ gpios = <8 GPIO_ACTIVE_HIGH>;
++ output-high;
++ line-name = "Video-B PWR0";
++ };
++ video_b_cam_pwr1 {
++ gpio-hog;
++ gpios = <9 GPIO_ACTIVE_HIGH>;
++ output-high;
++ line-name = "Video-B PWR1";
++ };
++ video_b_cam_pwr2 {
++ gpio-hog;
++ gpios = <10 GPIO_ACTIVE_HIGH>;
++ output-high;
++ line-name = "Video-B PWR2";
++ };
++ video_b_cam_pwr3 {
++ gpio-hog;
++ gpios = <11 GPIO_ACTIVE_HIGH>;
++ output-high;
++ line-name = "Video-B PWR3";
++ };
++ 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@7 {
++ #address-cells = <1>;
++ #size-cells = <0>;
++ reg = <7>;
++ /* Slot A (CN10) */
++
++ video_a_ext0: pca9535@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";
++ };
++ };
++
++ video_a_ext1: max7325@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_cam_pwr0 {
++ gpio-hog;
++ gpios = <8 GPIO_ACTIVE_HIGH>;
++ output-high;
++ line-name = "Video-A PWR0";
++ };
++ video_a_cam_pwr1 {
++ gpio-hog;
++ gpios = <9 GPIO_ACTIVE_HIGH>;
++ output-high;
++ line-name = "Video-A PWR1";
++ };
++ video_a_cam_pwr2 {
++ gpio-hog;
++ gpios = <10 GPIO_ACTIVE_HIGH>;
++ output-high;
++ line-name = "Video-A PWR2";
++ };
++ video_a_cam_pwr3 {
++ gpio-hog;
++ gpios = <11 GPIO_ACTIVE_HIGH>;
++ output-high;
++ line-name = "Video-A PWR3";
++ };
++ 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";
++ };
++ };
++ };
++ };
++};
++
++&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 = <&csi2_40_ep>;
++ };
++ };
++ port@2 {
++ vin0_max9286_des0ep0: endpoint@0 {
++ remote-endpoint = <&max9286_des0ep0>;
++ };
++ vin0_ti964_des0ep0: endpoint@1 {
++ remote-endpoint = <&ti964_des0ep0>;
++ };
++ vin0_ti954_des0ep0: endpoint@2 {
++ remote-endpoint = <&ti954_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>;
++ };
++ vin1_ti964_des0ep1: endpoint@1 {
++ remote-endpoint = <&ti964_des0ep1>;
++ };
++ vin1_ti954_des0ep1: endpoint@2 {
++ remote-endpoint = <&ti954_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>;
++ };
++ vin2_ti964_des0ep2: endpoint@1 {
++ remote-endpoint = <&ti964_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>;
++ };
++ vin3_ti964_des0ep3: endpoint@1 {
++ remote-endpoint = <&ti964_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 = <&csi2_41_ep>;
++ };
++ };
++ port@2 {
++ vin4_max9286_des1ep0: endpoint@0 {
++ remote-endpoint = <&max9286_des1ep0>;
++ };
++ vin4_ti964_des1ep0: endpoint@1 {
++ remote-endpoint = <&ti964_des1ep0>;
++ };
++ vin4_ti954_des1ep0: endpoint@2 {
++ remote-endpoint = <&ti954_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 = <&csi2_41_ep>;
++ };
++ };
++ port@2 {
++ vin5_max9286_des1ep1: endpoint@0 {
++ remote-endpoint = <&max9286_des1ep1>;
++ };
++ vin5_ti964_des1ep1: endpoint@1 {
++ remote-endpoint = <&ti964_des1ep1>;
++ };
++ vin5_ti954_des1ep1: endpoint@2 {
++ remote-endpoint = <&ti954_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 = <&csi2_41_ep>;
++ };
++ };
++ port@2 {
++ vin6_max9286_des1ep2: endpoint@0 {
++ remote-endpoint = <&max9286_des1ep2>;
++ };
++ vin6_ti964_des1ep2: endpoint@1 {
++ remote-endpoint = <&ti964_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 = <&csi2_41_ep>;
++ };
++ };
++ port@2 {
++ vin7_max9286_des1ep3: endpoint@0 {
++ remote-endpoint = <&max9286_des1ep3>;
++ };
++ vin7_ti964_des1ep3: endpoint@1 {
++ remote-endpoint = <&ti964_des1ep3>;
++ };
++ };
++ };
++};
++
++&csi2_40 {
++ 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>;
++ };
++ };
++};
++
++&csi2_41 {
++ 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 4>;
++ csi-rate = <300>;
++ };
++ };
++};
++
++&rcar_sound {
++ pinctrl-0 = <&sound_clk_pins>;
++
++ /* Multi DAI */
++ #sound-dai-cells = <1>;
++
++ rcar_sound,dai {
++ dai0 {
++ playback = <&ssi7>;
++ capture = <&ssi8>;
++ };
++
++ dai1 {
++ playback = <&ssi0 &src0 &dvc0>;
++ capture = <&ssi1 &src1 &dvc1>;
++ };
++
++ dai2 {
++ capture = <&ssi6>;
++ };
++ };
++};
++
++&sdhi3 {
++ pinctrl-0 = <&sdhi3_pins_3v3>;
++ pinctrl-names = "default";
++
++ 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_RISING>;
++ };
++};
++
++&usb2_phy0 {
++ pinctrl-0 = <&usb0_pins>;
++ pinctrl-names = "default";
++
++ status = "okay";
++};
++
++&hsusb {
++ status = "okay";
++};
++
++&ehci0 {
++ status = "okay";
++};
++
++&ohci0 {
++ status = "okay";
++};
++
++&xhci0 {
++ status = "okay";
++};
++
++&msiof1 {
++ status = "disabled";
++};
++
++&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";
++
++ channel0 {
++ status = "okay";
++ };
++
++ channel1 {
++ status = "okay";
++ };
++};
++
++&ssi8 {
++ shared-pin;
++};
+diff --git a/arch/arm64/boot/dts/renesas/legacy/r8a7795-es1-h3ulcb-kf-v1.dts b/arch/arm64/boot/dts/renesas/legacy/r8a7795-es1-h3ulcb-kf-v1.dts
+new file mode 100644
+index 0000000..ac6a12b
+--- /dev/null
++++ b/arch/arm64/boot/dts/renesas/legacy/r8a7795-es1-h3ulcb-kf-v1.dts
+@@ -0,0 +1,441 @@
++/*
++ * Device Tree Source for the H3ULCB Kingfisher V1 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-kf-v0.dts"
++
++/ {
++ model = "Renesas H3ULCB Kingfisher V1 board based on r8a7795";
++
++ aliases {
++ serial1 = &hscif0;
++ serial2 = &hscif1;
++ serial3 = &scif1;
++ };
++
++ wlan_en: regulator@4 {
++ compatible = "regulator-fixed";
++ regulator-name = "wlan-en-regulator";
++
++ regulator-min-microvolt = <3300000>;
++ regulator-max-microvolt = <3300000>;
++
++ gpio = <&gpio_ext_74 4 GPIO_ACTIVE_HIGH>;
++ enable-active-high;
++ };
++
++ codec_en_reg: regulator@6 {
++ compatible = "regulator-fixed";
++ regulator-name = "codec-en-regulator";
++ regulator-min-microvolt = <3300000>;
++ regulator-max-microvolt = <3300000>;
++
++ gpio = <&gpio_ext_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_ext_74 0 0>;
++
++ startup-delay-us = <0>;
++ enable-active-high;
++ };
++
++ /delete-node/regulator@8;
++
++ sdio_switch: regulator@9 {
++ compatible = "regulator-fixed";
++ regulator-name = "wifi_on";
++ regulator-min-microvolt = <3300000>;
++ regulator-max-microvolt = <3300000>;
++ gpio = <&gpio_ext_74 5 0>;
++ enable-active-low;
++ regulator-always-on;
++ };
++
++ /delete-node/regulator@10;
++
++ radio_switch: regulator@11 {
++ compatible = "regulator-fixed";
++ regulator-name = "radio_on";
++ regulator-min-microvolt = <3300000>;
++ regulator-max-microvolt = <3300000>;
++ gpio = <&gpio_ext_74 13 GPIO_ACTIVE_HIGH>;
++ enable-active-high;
++ regulator-always-on;
++ };
++
++ kim {
++ shutdown-gpios = <&gpio_ext_74 3 GPIO_ACTIVE_HIGH>;
++ };
++
++ hdmi-out {
++ compatible = "hdmi-connector";
++ type = "a";
++
++ port {
++ hdmi_con: endpoint {
++ remote-endpoint = <&adv7513_out>;
++ };
++ };
++ };
++};
++
++&pfc {
++ /delete-node/hscif4;
++
++ scif1_pins: scif1 {
++ groups = "scif1_data_b";
++ function = "scif1";
++ };
++
++ hscif0_pins: hscif0 {
++ groups = "hscif0_data", "hscif0_ctrl";
++ function = "hscif0";
++ };
++
++ hscif1_pins: hscif1 {
++ groups = "hscif1_data_a", "hscif1_ctrl_a";
++ function = "hscif1";
++ };
++
++ du_pins: du {
++ groups = "du_rgb888", "du_sync", "du_clk_out_0", "du_disp";
++ function = "du";
++ };
++};
++
++&du {
++ pinctrl-0 = <&du_pins>;
++ pinctrl-names = "default";
++
++ ports {
++ port@0 {
++ endpoint {
++ remote-endpoint = <&adv7513_in>;
++ };
++ };
++ };
++};
++
++&gpio0 {
++ /delete-node/video_a_irq;
++ /delete-node/video_b_irq;
++ /delete-node/gpioext_2_20_irq;
++};
++
++&gpio1 {
++ /delete-node/gpioext_2_21_irq;
++ /delete-node/wifi_irq;
++};
++
++&gpio2 {
++ bl_pwm {
++ gpio-hog;
++ gpios = <3 GPIO_ACTIVE_HIGH>;
++ output-high;
++ line-name = "BL PWM 100%";
++ };
++};
++
++&gpio5 {
++ /delete-node/touch_irq;
++ /delete-node/bt_strap;
++};
++
++&gpio7 {
++ /delete-node/gpioext_2_21_irq;
++};
++
++&scif1 {
++ pinctrl-0 = <&scif1_pins>;
++ pinctrl-names = "default";
++
++ status = "okay";
++};
++
++&hscif0 {
++ pinctrl-0 = <&hscif0_pins>;
++ pinctrl-names = "default";
++ uart-has-rtscts;
++
++ status = "okay";
++};
++
++&hscif1 {
++ pinctrl-0 = <&hscif1_pins>;
++ pinctrl-names = "default";
++
++ status = "okay";
++};
++
++&hscif4 {
++ /delete-property/pinctrl-0;
++ /delete-property/pinctrl-names;
++
++ status = "disabled";
++};
++
++&i2c2 {
++ /delete-node/pca9535@20;
++ /delete-node/pca9535@21;
++
++ gpio_ext_74: pca9539@74 {
++ compatible = "nxp,pca9539";
++ 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>;
++ output-high;
++ line-name = "HUB pwen";
++ };
++ hub_rst {
++ gpio-hog;
++ gpios = <7 GPIO_ACTIVE_HIGH>;
++ output-high;
++ line-name = "HUB rst";
++ };
++ otg_offvbus {
++ gpio-hog;
++ gpios = <8 GPIO_ACTIVE_HIGH>;
++ output-low;
++ line-name = "OTG off VBUSn";
++ };
++ otg_extlpn {
++ gpio-hog;
++ gpios = <9 GPIO_ACTIVE_HIGH>;
++ output-high;
++ line-name = "OTG EXTLPn";
++ };
++ otg_stat1 {
++ gpio-hog;
++ gpios = <10 GPIO_ACTIVE_HIGH>;
++ input;
++ line-name = "OTG Stat1";
++ };
++ otg_stat2 {
++ gpio-hog;
++ gpios = <11 GPIO_ACTIVE_HIGH>;
++ input;
++ line-name = "OTG Stat2";
++ };
++ };
++
++ gpio_ext_75: pca9539@75 {
++ compatible = "nxp,pca9539";
++ reg = <0x75>;
++ gpio-controller;
++ #gpio-cells = <2>;
++ 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 {
++ reg = <0x71>;
++ reset-gpios= <&gpio5 3 GPIO_ACTIVE_LOW>;
++
++ i2c@4 {
++ #address-cells = <1>;
++ #size-cells = <0>;
++ reg = <4>;
++
++ hdmi@3d {
++ compatible = "adi,adv7511w";
++ reg = <0x3d>;
++// interrupt-parent = <&gpio2>;
++// interrupts = <0 IRQ_TYPE_EDGE_BOTH>;
++ pd-gpios = <&gpio_ext_75 5 GPIO_ACTIVE_LOW>;
++
++ adi,input-depth = <8>;
++ adi,input-colorspace = "rgb";
++ adi,input-clock = "1x";
++ adi,input-style = <1>;
++ adi,input-justification = "evenly";
++ adi,clock-delay = <1200>;
++ adi,clock-max-rate = <100000>;
++
++ 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>;
++ };
++ };
++ };
++ };
++ };
++};
++
++&i2c4 {
++ /delete-node/pca9535@21;
++
++ gpio_ext_76: pca9539@76 {
++ compatible = "nxp,pca9539";
++ reg = <0x76>;
++ gpio-controller;
++ #gpio-cells = <2>;
++ 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_ext_77: pca9539@77 {
++ compatible = "nxp,pca9539";
++ reg = <0x77>;
++ gpio-controller;
++ #gpio-cells = <2>;
++ 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 {
++ reg = <0x71>;
++ reset-gpios= <&gpio3 15 GPIO_ACTIVE_LOW>;
++};
++
++&wlcore {
++ interrupts = <25 IRQ_TYPE_EDGE_FALLING>;
++};
+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
+new file mode 100644
+index 0000000..78c766b
+--- /dev/null
++++ b/arch/arm64/boot/dts/renesas/legacy/r8a7795-h3ulcb-kf-v0.dts
+@@ -0,0 +1,1724 @@
++/*
++ * Device Tree Source for the H3ULCB Kingfisher V0 board on r8a7795
++ *
++ * 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.dts"
++
++/ {
++ model = "Renesas H3ULCB Kingfisher V0 board based on r8a7795";
++
++ aliases {
++ serial1 = &hscif4;
++ };
++
++ 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_ext_20 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>;
++ regulator-always-on;
++ };
++
++ 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_ext_20 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_ext_20 0 0>;
++
++ startup-delay-us = <0>;
++ enable-active-high;
++ };
++
++ lvds_switch: regulator@8 {
++ compatible = "regulator-fixed";
++ regulator-name = "lvds_on";
++ regulator-min-microvolt = <3300000>;
++ regulator-max-microvolt = <3300000>;
++ /* gpio = <&gpio1 24 0>; */
++ enable-active-high;
++ regulator-always-on;
++ };
++
++ sdio_switch: regulator@9 {
++ compatible = "regulator-fixed";
++ regulator-name = "wifi_on";
++ regulator-min-microvolt = <3300000>;
++ regulator-max-microvolt = <3300000>;
++ gpio = <&gpio_ext_20 5 0>;
++ enable-active-low;
++ regulator-always-on;
++ };
++
++ sound_switch: regulator@10 {
++ compatible = "regulator-fixed";
++ regulator-name = "pcm3168a_on";
++ regulator-min-microvolt = <3300000>;
++ regulator-max-microvolt = <3300000>;
++ gpio = <&gpio_ext_21 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_ext_20 13 GPIO_ACTIVE_HIGH>;
++ enable-active-high;
++ regulator-always-on;
++ };
++
++ kim {
++ compatible = "kim";
++ shutdown-gpios = <&gpio_ext_20 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 = "simple-audio-card";
++
++ simple-audio-card,format = "left_j";
++ simple-audio-card,name = "pcm3168a";
++
++ simple-audio-card,bitclock-master = <&sound_ext_master>;
++ simple-audio-card,frame-master = <&sound_ext_master>;
++ sound_ext_master: simple-audio-card,cpu@0 {
++ sound-dai = <&rcar_sound 0>;
++ dai-tdm-slot-num = <8>;
++ dai-tdm-slot-width = <32>;
++ };
++
++ simple-audio-card,codec@0 {
++ sound-dai = <&pcm3168a>;
++ dai-tdm-slot-num = <8>;
++ dai-tdm-slot-width = <32>;
++ system-clock-frequency = <24576000>;
++ };
++ };
++
++ /delete-node/sound;
++
++ rsnd_ak4613: sound@1 {
++ pinctrl-0 = <&sound_1_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 1>;
++ };
++
++ sndcodec: simple-audio-card,codec@1 {
++ sound-dai = <&ak4613>;
++ };
++ };
++
++ sound_radio: sound@2 {
++ pinctrl-0 = <&sound_2_pins>;
++ pinctrl-names = "default";
++ compatible = "simple-audio-card";
++
++ simple-audio-card,format = "i2s";
++ simple-audio-card,name = "radio";
++
++ simple-audio-card,bitclock-master = <&sound_radio_master>;
++ simple-audio-card,frame-master = <&sound_radio_master>;
++ simple-audio-card,cpu@2 {
++ sound-dai = <&rcar_sound 2>;
++ };
++
++ sound_radio_master: simple-audio-card,codec@2 {
++ sound-dai = <&radio>;
++ system-clock-frequency = <12288000>;
++ };
++ };
++
++ lvds-encoder {
++ compatible = "thine,thc63lvdm83d";
++
++ ports {
++ #address-cells = <1>;
++ #size-cells = <0>;
++ port@0 {
++ reg = <0>;
++ lvds_enc_in: endpoint {
++ remote-endpoint = <&du_out_lvds0>;
++ };
++ };
++ port@1 {
++ reg = <1>;
++ lvds_enc_out: endpoint {
++ remote-endpoint = <&lvds_in>;
++ };
++ };
++ };
++ };
++
++ lvds {
++ compatible = "lvds-connector";
++
++ 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 = <&lvds_enc_out>;
++ };
++ };
++ };
++
++ radio: si468x@0 {
++ compatible = "si,si468x-pcm";
++ status = "okay";
++
++ #sound-dai-cells = <0>;
++ };
++};
++
++&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>;
++ };
++
++ sound_0_pins: sound0 {
++ groups = "ssi78_ctrl", "ssi7_data", "ssi8_data";
++ function = "ssi";
++ };
++
++ sound_1_pins: sound1 {
++ groups = "ssi01239_ctrl", "ssi0_data", "ssi1_data_a";
++ function = "ssi";
++ };
++
++ sound_2_pins: sound2 {
++ groups = "ssi6_ctrl", "ssi6_data";
++ 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";
++ };
++};
++
++&du {
++ ports {
++ port@3 {
++ endpoint {
++ remote-endpoint = <&lvds_enc_in>;
++ };
++ };
++ };
++};
++
++&gpio0 {
++ video_a_irq {
++ gpio-hog;
++ gpios = <13 GPIO_ACTIVE_HIGH>;
++ input;
++ line-name = "Video-A irq";
++ };
++
++ video_b_irq {
++ gpio-hog;
++ gpios = <14 GPIO_ACTIVE_HIGH>;
++ input;
++ line-name = "Video-B irq";
++ };
++
++ gpioext_2_20_irq {
++ gpio-hog;
++ gpios = <15 GPIO_ACTIVE_HIGH>;
++ input;
++ line-name = "0x20@i2c2 irq";
++ };
++};
++
++&gpio1 {
++ gpioext_2_21_irq {
++ gpio-hog;
++ gpios = <15 GPIO_ACTIVE_HIGH>;
++ input;
++ line-name = "0x21@i2c2 irq";
++ };
++
++ wifi_irq {
++ gpio-hog;
++ gpios = <25 GPIO_ACTIVE_HIGH>;
++ input;
++ line-name = "wifi irq";
++ };
++};
++
++&gpio5 {
++ touch_irq {
++ gpio-hog;
++ gpios = <6 GPIO_ACTIVE_HIGH>;
++ input;
++ line-name = "touch irq";
++ };
++
++ /* From TI forum */
++ /* BT_AUD_OUT should be pulled low when WL_EN is activated. */
++ /* in case it isn't, wilink8 ends up in one of the test modes that introduces various issues */
++ bt_strap {
++ gpio-hog;
++ gpios = <14 GPIO_ACTIVE_HIGH>;
++ output-low;
++ line-name = "BT strap pin";
++ };
++};
++
++&gpio7 {
++ gpioext_2_21_irq {
++ gpio-hog;
++ gpios = <3 GPIO_ACTIVE_HIGH>;
++ input;
++ line-name = "0x21@i2c4 irq";
++ };
++};
++
++&hscif4 {
++ pinctrl-0 = <&hscif4_pins>;
++ pinctrl-names = "default";
++ uart-has-rtscts;
++
++ status = "okay";
++};
++
++&i2c2 {
++ clock-frequency = <400000>;
++
++ gpio_ext_20: pca9535@20 {
++ compatible = "nxp,pca9535";
++ reg = <0x20>;
++ gpio-controller;
++ #gpio-cells = <2>;
++ interrupt-controller;
++ interrupt-parent = <&gpio0>;
++ interrupts = <15 IRQ_TYPE_EDGE_FALLING>;
++ };
++
++ gpio_ext_21: pca9535@21 {
++ compatible = "nxp,pca9535";
++ reg = <0x21>;
++ gpio-controller;
++ #gpio-cells = <2>;
++ interrupt-controller;
++ interrupt-parent = <&gpio1>;
++ interrupts = <15 IRQ_TYPE_EDGE_FALLING>;
++ };
++
++ 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>;
++ /* 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>;
++ /* A2B node(s) */
++ };
++
++ 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>;
++ };
++
++ lsm9ds0_acc_mag@1d {
++ compatible = "st,lsm9ds0_accel_magn";
++ reg = <0x1d>;
++ };
++
++ lsm9ds0_gyr@6b {
++ compatible = "st,lsm9ds0_gyro";
++ reg = <0x6b>;
++ };
++
++ /* GPS@ 0x42 */
++ };
++ };
++};
++
++&i2c4 {
++ gpio_ext_22: pca9535@21 {
++ compatible = "nxp,pca9535";
++ reg = <0x22>;
++ gpio-controller;
++ #gpio-cells = <2>;
++ interrupt-controller;
++ interrupt-parent = <&gpio7>;
++ interrupts = <3 IRQ_TYPE_EDGE_FALLING>;
++
++ 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";
++ };
++ };
++
++ i2cswitch4: pca9548@74 {
++ compatible = "nxp,pca9548";
++ #address-cells = <1>;
++ #size-cells = <0>;
++ reg = <0x74>;
++ reset-gpios= <&gpio6 21 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_ti964_des0ep0: endpoint@1 {
++ remote-endpoint = <&ti964_des0ep0>;
++ };
++ ov106xx_ti954_des0ep0: endpoint@2 {
++ remote-endpoint = <&ti954_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_ti964_des0ep1: endpoint@1 {
++ remote-endpoint = <&ti964_des0ep1>;
++ };
++ ov106xx_ti954_des0ep1: endpoint@2 {
++ remote-endpoint = <&ti954_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_ti964_des0ep2: endpoint@1 {
++ remote-endpoint = <&ti964_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_ti964_des0ep3: endpoint@1 {
++ remote-endpoint = <&ti964_des0ep3>;
++ };
++ };
++ };
++
++ /* DS90UB964 @ 0x3a */
++ ti964-ti9x3@0 {
++ compatible = "ti,ti964-ti9x3";
++ reg = <0x3a>;
++ ti,sensor_delay = <350>;
++ ti,links = <4>;
++ ti,lanes = <4>;
++ ti,forwarding-mode = "round-robin";
++ ti,cable-mode = "coax";
++
++ port@0 {
++ ti964_des0ep0: endpoint@0 {
++ ti9x3-addr = <0x0c>;
++ dvp-order = <0>;
++ remote-endpoint = <&ov106xx_in0>;
++ };
++ ti964_des0ep1: endpoint@1 {
++ ti9x3-addr = <0x0d>;
++ dvp-order = <0>;
++ remote-endpoint = <&ov106xx_in1>;
++ };
++ ti964_des0ep2: endpoint@2 {
++ ti9x3-addr = <0x0e>;
++ dvp-order = <0>;
++ remote-endpoint = <&ov106xx_in2>;
++ };
++ ti964_des0ep3: endpoint@3 {
++ ti9x3-addr = <0x0f>;
++ dvp-order = <0>;
++ remote-endpoint = <&ov106xx_in3>;
++ };
++ };
++ port@1 {
++ ti964_csi0ep0: endpoint {
++ csi-rate = <1450>;
++ remote-endpoint = <&csi2_40_ep>;
++ };
++ };
++ };
++
++ /* DS90UB954 @ 0x38 */
++ ti954-ti9x3@0 {
++ compatible = "ti,ti954-ti9x3";
++ reg = <0x38>;
++ /* gpios = <&video_a_ext1 10 GPIO_ACTIVE_HIGH>; */
++ ti,sensor_delay = <350>;
++ ti,links = <2>;
++ ti,lanes = <4>;
++ ti,forwarding-mode = "round-robin";
++ ti,cable-mode = "coax";
++
++ port@0 {
++ ti954_des0ep0: endpoint@0 {
++ ti9x3-addr = <0x0c>;
++ dvp-order = <0>;
++ remote-endpoint = <&ov106xx_in0>;
++ };
++ ti954_des0ep1: endpoint@1 {
++ ti9x3-addr = <0x0d>;
++ dvp-order = <0>;
++ remote-endpoint = <&ov106xx_in1>;
++ };
++ };
++ port@1 {
++ ti954_csi0ep0: endpoint {
++ csi-rate = <1450>;
++ remote-endpoint = <&csi2_40_ep>;
++ };
++ };
++ };
++
++ /* MAX9286 @ 0x2c */
++ max9286-max9271@0 {
++ compatible = "maxim,max9286-max9271";
++ reg = <0x2c>;
++ maxim,sensor_delay = <350>;
++ 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>;
++ };
++ };
++ };
++ };
++
++ 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_ti964_des1ep0: endpoint@1 {
++ remote-endpoint = <&ti964_des1ep0>;
++ };
++ ov106xx_ti954_des1ep0: endpoint@2 {
++ remote-endpoint = <&ti954_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_ti964_des1ep1: endpoint@1 {
++ remote-endpoint = <&ti964_des1ep1>;
++ };
++ ov106xx_ti954_des1ep1: endpoint@2 {
++ remote-endpoint = <&ti954_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_ti964_des1ep2: endpoint@1 {
++ remote-endpoint = <&ti964_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_ti964_des1ep3: endpoint@1 {
++ remote-endpoint = <&ti964_des1ep3>;
++ };
++ };
++ };
++
++ /* DS90UB964 @ 0x3a */
++ ti964-ti9x3@1 {
++ compatible = "ti,ti964-ti9x3";
++ reg = <0x3a>;
++ ti,sensor_delay = <350>;
++ ti,links = <4>;
++ ti,lanes = <4>;
++ ti,forwarding-mode = "round-robin";
++ ti,cable-mode = "coax";
++
++ port@0 {
++ ti964_des1ep0: endpoint@0 {
++ ti9x3-addr = <0x0c>;
++ dvp-order = <0>;
++ remote-endpoint = <&ov106xx_in4>;
++ };
++ ti964_des1ep1: endpoint@1 {
++ ti9x3-addr = <0x0d>;
++ dvp-order = <0>;
++ remote-endpoint = <&ov106xx_in5>;
++ };
++ ti964_des1ep2: endpoint@2 {
++ ti9x3-addr = <0x0e>;
++ dvp-order = <0>;
++ remote-endpoint = <&ov106xx_in6>;
++ };
++ ti964_des1ep3: endpoint@3 {
++ ti9x3-addr = <0x0f>;
++ dvp-order = <0>;
++ remote-endpoint = <&ov106xx_in7>;
++ };
++ };
++ port@1 {
++ ti964_csi2ep0: endpoint {
++ csi-rate = <1450>;
++ remote-endpoint = <&csi2_41_ep>;
++ };
++ };
++ };
++
++ /* DS90UB954 @ 0x38 */
++ ti954-ti9x3@1 {
++ compatible = "ti,ti954-ti9x3";
++ reg = <0x38>;
++ /* gpios = <&video_b_ext1 10 GPIO_ACTIVE_HIGH>; */
++ ti,sensor_delay = <350>;
++ ti,links = <2>;
++ ti,lanes = <4>;
++ ti,forwarding-mode = "round-robin";
++ ti,cable-mode = "coax";
++
++ port@0 {
++ ti954_des1ep0: endpoint@0 {
++ ti9x3-addr = <0x0c>;
++ dvp-order = <0>;
++ remote-endpoint = <&ov106xx_in4>;
++ };
++ ti954_des1ep1: endpoint@1 {
++ ti9x3-addr = <0x0d>;
++ dvp-order = <0>;
++ remote-endpoint = <&ov106xx_in5>;
++ };
++ };
++ port@1 {
++ ti954_csi2ep0: endpoint {
++ csi-rate = <1450>;
++ remote-endpoint = <&csi2_41_ep>;
++ };
++ };
++ };
++
++ /* MAX9286 @ 0x2c */
++ max9286-max9271@1 {
++ compatible = "maxim,max9286-max9271";
++ reg = <0x2c>;
++ maxim,sensor_delay = <350>;
++ 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 = <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 = <&csi2_41_ep>;
++ };
++ };
++ };
++ };
++
++ i2c@3 {
++ #address-cells = <1>;
++ #size-cells = <0>;
++ reg = <3>;
++ /* MOST node(s) */
++ };
++
++ i2c@6 {
++ #address-cells = <1>;
++ #size-cells = <0>;
++ reg = <6>;
++ /* Slot B (CN11) */
++
++ video_b_ext0: pca9535@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";
++ };
++ };
++
++ video_b_ext1: max7325@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_cam_pwr0 {
++ gpio-hog;
++ gpios = <8 GPIO_ACTIVE_HIGH>;
++ output-high;
++ line-name = "Video-B PWR0";
++ };
++ video_b_cam_pwr1 {
++ gpio-hog;
++ gpios = <9 GPIO_ACTIVE_HIGH>;
++ output-high;
++ line-name = "Video-B PWR1";
++ };
++ video_b_cam_pwr2 {
++ gpio-hog;
++ gpios = <10 GPIO_ACTIVE_HIGH>;
++ output-high;
++ line-name = "Video-B PWR2";
++ };
++ video_b_cam_pwr3 {
++ gpio-hog;
++ gpios = <11 GPIO_ACTIVE_HIGH>;
++ output-high;
++ line-name = "Video-B PWR3";
++ };
++ 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@7 {
++ #address-cells = <1>;
++ #size-cells = <0>;
++ reg = <7>;
++ /* Slot A (CN10) */
++
++ video_a_ext0: pca9535@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";
++ };
++ };
++
++ video_a_ext1: max7325@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_cam_pwr0 {
++ gpio-hog;
++ gpios = <8 GPIO_ACTIVE_HIGH>;
++ output-high;
++ line-name = "Video-A PWR0";
++ };
++ video_a_cam_pwr1 {
++ gpio-hog;
++ gpios = <9 GPIO_ACTIVE_HIGH>;
++ output-high;
++ line-name = "Video-A PWR1";
++ };
++ video_a_cam_pwr2 {
++ gpio-hog;
++ gpios = <10 GPIO_ACTIVE_HIGH>;
++ output-high;
++ line-name = "Video-A PWR2";
++ };
++ video_a_cam_pwr3 {
++ gpio-hog;
++ gpios = <11 GPIO_ACTIVE_HIGH>;
++ output-high;
++ line-name = "Video-A PWR3";
++ };
++ 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";
++ };
++ };
++ };
++ };
++};
++
++&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 = <&csi2_40_ep>;
++ };
++ };
++ port@2 {
++ vin0_max9286_des0ep0: endpoint@0 {
++ remote-endpoint = <&max9286_des0ep0>;
++ };
++ vin0_ti964_des0ep0: endpoint@1 {
++ remote-endpoint = <&ti964_des0ep0>;
++ };
++ vin0_ti954_des0ep0: endpoint@2 {
++ remote-endpoint = <&ti954_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>;
++ };
++ vin1_ti964_des0ep1: endpoint@1 {
++ remote-endpoint = <&ti964_des0ep1>;
++ };
++ vin1_ti954_des0ep1: endpoint@2 {
++ remote-endpoint = <&ti954_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>;
++ };
++ vin2_ti964_des0ep2: endpoint@1 {
++ remote-endpoint = <&ti964_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>;
++ };
++ vin3_ti964_des0ep3: endpoint@1 {
++ remote-endpoint = <&ti964_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 = <&csi2_41_ep>;
++ };
++ };
++ port@2 {
++ vin4_max9286_des1ep0: endpoint@0 {
++ remote-endpoint = <&max9286_des1ep0>;
++ };
++ vin4_ti964_des1ep0: endpoint@1 {
++ remote-endpoint = <&ti964_des1ep0>;
++ };
++ vin4_ti954_des1ep0: endpoint@2 {
++ remote-endpoint = <&ti954_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 = <&csi2_41_ep>;
++ };
++ };
++ port@2 {
++ vin5_max9286_des1ep1: endpoint@0 {
++ remote-endpoint = <&max9286_des1ep1>;
++ };
++ vin5_ti964_des1ep1: endpoint@1 {
++ remote-endpoint = <&ti964_des1ep1>;
++ };
++ vin5_ti954_des1ep1: endpoint@2 {
++ remote-endpoint = <&ti954_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 = <&csi2_41_ep>;
++ };
++ };
++ port@2 {
++ vin6_max9286_des1ep2: endpoint@0 {
++ remote-endpoint = <&max9286_des1ep2>;
++ };
++ vin6_ti964_des1ep2: endpoint@1 {
++ remote-endpoint = <&ti964_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 = <&csi2_41_ep>;
++ };
++ };
++ port@2 {
++ vin7_max9286_des1ep3: endpoint@0 {
++ remote-endpoint = <&max9286_des1ep3>;
++ };
++ vin7_ti964_des1ep3: endpoint@1 {
++ remote-endpoint = <&ti964_des1ep3>;
++ };
++ };
++ };
++};
++
++&csi2_40 {
++ 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>;
++ };
++ };
++};
++
++&csi2_41 {
++ 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 4>;
++ csi-rate = <300>;
++ };
++ };
++};
++
++&rcar_sound {
++ pinctrl-0 = <&sound_clk_pins>;
++
++ /* Multi DAI */
++ #sound-dai-cells = <1>;
++
++ rcar_sound,dai {
++ dai0 {
++ playback = <&ssi7>;
++ capture = <&ssi8>;
++ };
++
++ dai1 {
++ playback = <&ssi0 &src0 &dvc0>;
++ capture = <&ssi1 &src1 &dvc1>;
++ };
++
++ dai2 {
++ capture = <&ssi6>;
++ };
++ };
++};
++
++&sdhi3 {
++ pinctrl-0 = <&sdhi3_pins_3v3>;
++ pinctrl-names = "default";
++
++ 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_RISING>;
++ };
++};
++
++&usb2_phy0 {
++ pinctrl-0 = <&usb0_pins>;
++ pinctrl-names = "default";
++
++ status = "okay";
++};
++
++&hsusb0 {
++ status = "okay";
++};
++
++&ehci0 {
++ status = "okay";
++};
++
++&ohci0 {
++ status = "okay";
++};
++
++&xhci0 {
++ status = "okay";
++};
++
++&msiof1 {
++ status = "disabled";
++};
++
++&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";
++
++ channel0 {
++ status = "okay";
++ };
++
++ channel1 {
++ status = "okay";
++ };
++};
++
++&ssi8 {
++ shared-pin;
++};
++
++/* uncomment to enable CN47: SD on SDHI3 */
++//#include "../ulcb-kf-sd3.dtsi"
++/* CN48 (Raspberry Pi) on VIN4 */
++//#include "ulcb-kf-rpi.dtsi"
++/* CN29: (CMOS camera) on VIN5 */
++//#include "ulcb-kf-cmos.dtsi"
+diff --git a/arch/arm64/boot/dts/renesas/legacy/r8a7795-h3ulcb-kf-v1.dts b/arch/arm64/boot/dts/renesas/legacy/r8a7795-h3ulcb-kf-v1.dts
+new file mode 100644
+index 0000000..14b6f52
+--- /dev/null
++++ b/arch/arm64/boot/dts/renesas/legacy/r8a7795-h3ulcb-kf-v1.dts
+@@ -0,0 +1,465 @@
++/*
++ * Device Tree Source for the H3ULCB Kingfisher V1 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 "r8a7795-h3ulcb-kf-v0.dts"
++
++/ {
++ model = "Renesas H3ULCB Kingfisher V1 board based on r8a7795";
++
++ aliases {
++ serial1 = &hscif0;
++ serial2 = &hscif1;
++ serial3 = &scif1;
++ };
++
++ wlan_en: regulator@4 {
++ compatible = "regulator-fixed";
++ regulator-name = "wlan-en-regulator";
++
++ regulator-min-microvolt = <3300000>;
++ regulator-max-microvolt = <3300000>;
++
++ gpio = <&gpio_ext_74 4 GPIO_ACTIVE_HIGH>;
++ enable-active-high;
++ };
++
++ codec_en_reg: regulator@6 {
++ compatible = "regulator-fixed";
++ regulator-name = "codec-en-regulator";
++ regulator-min-microvolt = <3300000>;
++ regulator-max-microvolt = <3300000>;
++
++ gpio = <&gpio_ext_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_ext_74 0 0>;
++
++ startup-delay-us = <0>;
++ enable-active-high;
++ };
++
++ /delete-node/regulator@8;
++
++ sdio_switch: regulator@9 {
++ compatible = "regulator-fixed";
++ regulator-name = "wifi_on";
++ regulator-min-microvolt = <3300000>;
++ regulator-max-microvolt = <3300000>;
++ gpio = <&gpio_ext_74 5 0>;
++ enable-active-low;
++ regulator-always-on;
++ };
++
++ /delete-node/regulator@10;
++
++ radio_switch: regulator@11 {
++ compatible = "regulator-fixed";
++ regulator-name = "radio_on";
++ regulator-min-microvolt = <3300000>;
++ regulator-max-microvolt = <3300000>;
++ gpio = <&gpio_ext_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_ext_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_ext_77 15 GPIO_ACTIVE_HIGH>;
++ startup-delay-us = <200000>;
++ enable-active-high;
++ };
++
++ kim {
++ shutdown-gpios = <&gpio_ext_74 3 GPIO_ACTIVE_HIGH>;
++ };
++
++ hdmi-out {
++ compatible = "hdmi-connector";
++ type = "a";
++
++ port {
++ hdmi_con: endpoint {
++ remote-endpoint = <&adv7513_out>;
++ };
++ };
++ };
++};
++
++&pfc {
++ /delete-node/hscif4;
++
++ scif1_pins: scif1 {
++ groups = "scif1_data_b";
++ function = "scif1";
++ };
++
++ hscif0_pins: hscif0 {
++ groups = "hscif0_data", "hscif0_ctrl";
++ function = "hscif0";
++ };
++
++ hscif1_pins: hscif1 {
++ groups = "hscif1_data_a", "hscif1_ctrl_a";
++ function = "hscif1";
++ };
++
++ du_pins: du {
++ groups = "du_rgb888", "du_sync", "du_clk_out_0", "du_disp";
++ function = "du";
++ };
++};
++
++&du {
++ pinctrl-0 = <&du_pins>;
++ pinctrl-names = "default";
++
++ ports {
++ port@0 {
++ endpoint {
++ remote-endpoint = <&adv7513_in>;
++ };
++ };
++ };
++};
++
++&gpio0 {
++ /delete-node/video_a_irq;
++ /delete-node/video_b_irq;
++ /delete-node/gpioext_2_20_irq;
++};
++
++&gpio1 {
++ /delete-node/gpioext_2_21_irq;
++ /delete-node/wifi_irq;
++};
++
++&gpio2 {
++ bl_pwm {
++ gpio-hog;
++ gpios = <3 GPIO_ACTIVE_HIGH>;
++ output-high;
++ line-name = "BL PWM 100%";
++ };
++};
++
++&gpio5 {
++ /delete-node/touch_irq;
++ /delete-node/bt_strap;
++};
++
++&gpio7 {
++ /delete-node/gpioext_2_21_irq;
++};
++
++&scif1 {
++ pinctrl-0 = <&scif1_pins>;
++ pinctrl-names = "default";
++
++ status = "okay";
++};
++
++&hscif0 {
++ pinctrl-0 = <&hscif0_pins>;
++ pinctrl-names = "default";
++ uart-has-rtscts;
++
++ status = "okay";
++};
++
++&hscif1 {
++ pinctrl-0 = <&hscif1_pins>;
++ pinctrl-names = "default";
++
++ status = "okay";
++};
++
++&hscif4 {
++ /delete-property/pinctrl-0;
++ /delete-property/pinctrl-names;
++
++ status = "disabled";
++};
++
++&i2c2 {
++ /delete-node/pca9535@20;
++ /delete-node/pca9535@21;
++
++ gpio_ext_74: pca9539@74 {
++ compatible = "nxp,pca9539";
++ 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>;
++ output-high;
++ line-name = "HUB pwen";
++ };
++ hub_rst {
++ gpio-hog;
++ gpios = <7 GPIO_ACTIVE_HIGH>;
++ output-high;
++ line-name = "HUB rst";
++ };
++ otg_offvbus {
++ gpio-hog;
++ gpios = <8 GPIO_ACTIVE_HIGH>;
++ output-low;
++ line-name = "OTG off VBUSn";
++ };
++ otg_extlpn {
++ gpio-hog;
++ gpios = <9 GPIO_ACTIVE_HIGH>;
++ output-high;
++ line-name = "OTG EXTLPn";
++ };
++ otg_stat1 {
++ gpio-hog;
++ gpios = <10 GPIO_ACTIVE_HIGH>;
++ input;
++ line-name = "OTG Stat1";
++ };
++ otg_stat2 {
++ gpio-hog;
++ gpios = <11 GPIO_ACTIVE_HIGH>;
++ input;
++ line-name = "OTG Stat2";
++ };
++ };
++
++ gpio_ext_75: pca9539@75 {
++ compatible = "nxp,pca9539";
++ reg = <0x75>;
++ gpio-controller;
++ #gpio-cells = <2>;
++ 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 {
++ reg = <0x71>;
++ reset-gpios= <&gpio5 3 GPIO_ACTIVE_LOW>;
++
++ i2c@4 {
++ #address-cells = <1>;
++ #size-cells = <0>;
++ reg = <4>;
++
++ hdmi@3d {
++ compatible = "adi,adv7511w";
++ reg = <0x3d>;
++// interrupt-parent = <&gpio2>;
++// interrupts = <0 IRQ_TYPE_EDGE_BOTH>;
++ pd-gpios = <&gpio_ext_75 5 GPIO_ACTIVE_LOW>;
++
++ adi,input-depth = <8>;
++ adi,input-colorspace = "rgb";
++ adi,input-clock = "1x";
++ adi,input-style = <1>;
++ adi,input-justification = "evenly";
++ adi,clock-delay = <1200>;
++ adi,clock-max-rate = <100000>;
++
++ 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>;
++ };
++ };
++ };
++ };
++ };
++};
++
++&i2c4 {
++ /delete-node/pca9535@21;
++
++ gpio_ext_76: pca9539@76 {
++ compatible = "nxp,pca9539";
++ reg = <0x76>;
++ gpio-controller;
++ #gpio-cells = <2>;
++ 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_ext_77: pca9539@77 {
++ compatible = "nxp,pca9539";
++ reg = <0x77>;
++ gpio-controller;
++ #gpio-cells = <2>;
++ 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 {
++ reg = <0x71>;
++ reset-gpios= <&gpio3 15 GPIO_ACTIVE_LOW>;
++};
++
++&wlcore {
++ interrupts = <25 IRQ_TYPE_EDGE_FALLING>;
++};
++
++&pciec1 {
++ pcie3v3-supply = <&mpcie_3v3>;
++ pcie1v8-supply = <&mpcie_1v8>;
++};
+diff --git a/arch/arm64/boot/dts/renesas/legacy/r8a7796-m3ulcb-kf-v0.dts b/arch/arm64/boot/dts/renesas/legacy/r8a7796-m3ulcb-kf-v0.dts
+new file mode 100644
+index 0000000..ffa1879
+--- /dev/null
++++ b/arch/arm64/boot/dts/renesas/legacy/r8a7796-m3ulcb-kf-v0.dts
+@@ -0,0 +1,1214 @@
++/*
++ * Device Tree Source for the M3ULCB Kingfisher V0 board on r8a7796
++ *
++ * 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 "../r8a7796-m3ulcb.dts"
++
++/ {
++ model = "Renesas M3ULCB Kingfisher V0 board based on r8a7796";
++
++ aliases {
++ serial1 = &hscif4;
++ };
++
++ 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_ext_20 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>;
++ regulator-always-on;
++ };
++
++ 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_ext_20 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_ext_20 0 0>;
++
++ startup-delay-us = <0>;
++ enable-active-high;
++ };
++
++ lvds_switch: regulator@8 {
++ compatible = "regulator-fixed";
++ regulator-name = "lvds_on";
++ regulator-min-microvolt = <3300000>;
++ regulator-max-microvolt = <3300000>;
++ /* gpio = <&gpio1 24 0>; */
++ enable-active-high;
++ regulator-always-on;
++ };
++
++ sdio_switch: regulator@9 {
++ compatible = "regulator-fixed";
++ regulator-name = "wifi_on";
++ regulator-min-microvolt = <3300000>;
++ regulator-max-microvolt = <3300000>;
++ gpio = <&gpio_ext_20 5 0>;
++ enable-active-low;
++ regulator-always-on;
++ };
++
++ sound_switch: regulator@10 {
++ compatible = "regulator-fixed";
++ regulator-name = "pcm3168a_on";
++ regulator-min-microvolt = <3300000>;
++ regulator-max-microvolt = <3300000>;
++ gpio = <&gpio_ext_21 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_ext_20 13 GPIO_ACTIVE_HIGH>;
++ enable-active-high;
++ regulator-always-on;
++ };
++
++ kim {
++ compatible = "kim";
++ shutdown-gpios = <&gpio_ext_20 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 = "simple-audio-card";
++
++ simple-audio-card,format = "left_j";
++ simple-audio-card,name = "pcm3168a";
++
++ simple-audio-card,bitclock-master = <&sound_ext_master>;
++ simple-audio-card,frame-master = <&sound_ext_master>;
++ sound_ext_master: simple-audio-card,cpu@0 {
++ sound-dai = <&rcar_sound 0>;
++ dai-tdm-slot-num = <8>;
++ dai-tdm-slot-width = <32>;
++ };
++
++ simple-audio-card,codec@0 {
++ sound-dai = <&pcm3168a>;
++ dai-tdm-slot-num = <8>;
++ dai-tdm-slot-width = <32>;
++ system-clock-frequency = <24576000>;
++ };
++ };
++
++ /delete-node/sound;
++
++ rsnd_ak4613: sound@1 {
++ pinctrl-0 = <&sound_1_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 1>;
++ };
++
++ sndcodec: simple-audio-card,codec@1 {
++ sound-dai = <&ak4613>;
++ };
++ };
++
++ sound_radio: sound@2 {
++ pinctrl-0 = <&sound_2_pins>;
++ pinctrl-names = "default";
++ compatible = "simple-audio-card";
++
++ simple-audio-card,format = "i2s";
++ simple-audio-card,name = "radio";
++
++ simple-audio-card,bitclock-master = <&sound_radio_master>;
++ simple-audio-card,frame-master = <&sound_radio_master>;
++ simple-audio-card,cpu@2 {
++ sound-dai = <&rcar_sound 2>;
++ };
++
++ sound_radio_master: simple-audio-card,codec@2 {
++ sound-dai = <&radio>;
++ system-clock-frequency = <12288000>;
++ };
++ };
++
++ lvds-encoder {
++ compatible = "thine,thc63lvdm83d";
++
++ ports {
++ #address-cells = <1>;
++ #size-cells = <0>;
++ port@0 {
++ reg = <0>;
++ lvds_enc_in: endpoint {
++ remote-endpoint = <&du_out_lvds0>;
++ };
++ };
++ port@1 {
++ reg = <1>;
++ lvds_enc_out: endpoint {
++ remote-endpoint = <&lvds_in>;
++ };
++ };
++ };
++ };
++
++ lvds {
++ compatible = "lvds-connector";
++
++ 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 = <&lvds_enc_out>;
++ };
++ };
++ };
++
++ radio: si468x@0 {
++ compatible = "si,si468x-pcm";
++ status = "okay";
++
++ #sound-dai-cells = <0>;
++ };
++};
++
++&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>;
++ };
++
++ sound_0_pins: sound0 {
++ groups = "ssi78_ctrl", "ssi7_data", "ssi8_data";
++ function = "ssi";
++ };
++
++ sound_1_pins: sound1 {
++ groups = "ssi0129_ctrl", "ssi0_data", "ssi1_data_a";
++ function = "ssi";
++ };
++
++ sound_2_pins: sound2 {
++ groups = "ssi6_ctrl", "ssi6_data";
++ 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";
++ };
++};
++
++&du {
++ ports {
++ port@2 {
++ endpoint {
++ remote-endpoint = <&lvds_enc_in>;
++ };
++ };
++ };
++};
++
++&gpio0 {
++ video_a_irq {
++ gpio-hog;
++ gpios = <13 GPIO_ACTIVE_HIGH>;
++ input;
++ line-name = "Video-A irq";
++ };
++
++ video_b_irq {
++ gpio-hog;
++ gpios = <14 GPIO_ACTIVE_HIGH>;
++ input;
++ line-name = "Video-B irq";
++ };
++
++ gpioext_2_20_irq {
++ gpio-hog;
++ gpios = <15 GPIO_ACTIVE_HIGH>;
++ input;
++ line-name = "0x20@i2c2 irq";
++ };
++};
++
++&gpio1 {
++ gpioext_2_21_irq {
++ gpio-hog;
++ gpios = <15 GPIO_ACTIVE_HIGH>;
++ input;
++ line-name = "0x21@i2c2 irq";
++ };
++
++ wifi_irq {
++ gpio-hog;
++ gpios = <25 GPIO_ACTIVE_HIGH>;
++ input;
++ line-name = "wifi irq";
++ };
++};
++
++&gpio5 {
++ touch_irq {
++ gpio-hog;
++ gpios = <6 GPIO_ACTIVE_HIGH>;
++ input;
++ line-name = "touch irq";
++ };
++
++ /* From TI forum */
++ /* BT_AUD_OUT should be pulled low when WL_EN is activated. */
++ /* in case it isn't, wilink8 ends up in one of the test modes that introduces various issues */
++ bt_strap {
++ gpio-hog;
++ gpios = <14 GPIO_ACTIVE_HIGH>;
++ output-low;
++ line-name = "BT strap pin";
++ };
++};
++
++&gpio7 {
++ gpioext_2_21_irq {
++ gpio-hog;
++ gpios = <3 GPIO_ACTIVE_HIGH>;
++ input;
++ line-name = "0x21@i2c4 irq";
++ };
++};
++
++&hscif4 {
++ pinctrl-0 = <&hscif4_pins>;
++ pinctrl-names = "default";
++ uart-has-rtscts;
++
++ status = "okay";
++};
++
++&i2c2 {
++ clock-frequency = <400000>;
++
++ gpio_ext_20: pca9535@20 {
++ compatible = "nxp,pca9535";
++ reg = <0x20>;
++ gpio-controller;
++ #gpio-cells = <2>;
++ interrupt-controller;
++ interrupt-parent = <&gpio0>;
++ interrupts = <15 IRQ_TYPE_EDGE_FALLING>;
++ };
++
++ gpio_ext_21: pca9535@21 {
++ compatible = "nxp,pca9535";
++ reg = <0x21>;
++ gpio-controller;
++ #gpio-cells = <2>;
++ interrupt-controller;
++ interrupt-parent = <&gpio1>;
++ interrupts = <15 IRQ_TYPE_EDGE_FALLING>;
++ };
++
++ 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>;
++ /* 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>;
++ /* A2B node(s) */
++ };
++
++ 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>;
++ };
++
++ lsm9ds0_acc_mag@1d {
++ compatible = "st,lsm9ds0_accel_magn";
++ reg = <0x1d>;
++ };
++
++ lsm9ds0_gyr@6b {
++ compatible = "st,lsm9ds0_gyro";
++ reg = <0x6b>;
++ };
++
++ /* GPS@ 0x42 */
++ };
++ };
++};
++
++&i2c4 {
++ gpio_ext_22: pca9535@21 {
++ compatible = "nxp,pca9535";
++ reg = <0x22>;
++ gpio-controller;
++ #gpio-cells = <2>;
++ interrupt-controller;
++ interrupt-parent = <&gpio7>;
++ interrupts = <3 IRQ_TYPE_EDGE_FALLING>;
++
++ 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";
++ };
++ };
++
++ i2cswitch4: pca9548@74 {
++ compatible = "nxp,pca9548";
++ #address-cells = <1>;
++ #size-cells = <0>;
++ reg = <0x74>;
++ reset-gpios= <&gpio6 21 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_ti964_des0ep0: endpoint@1 {
++ remote-endpoint = <&ti964_des0ep0>;
++ };
++ ov106xx_ti954_des0ep0: endpoint@2 {
++ remote-endpoint = <&ti954_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_ti964_des0ep1: endpoint@1 {
++ remote-endpoint = <&ti964_des0ep1>;
++ };
++ ov106xx_ti954_des0ep1: endpoint@2 {
++ remote-endpoint = <&ti954_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_ti964_des0ep2: endpoint@1 {
++ remote-endpoint = <&ti964_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_ti964_des0ep3: endpoint@1 {
++ remote-endpoint = <&ti964_des0ep3>;
++ };
++ };
++ };
++
++ /* DS90UB964 @ 0x3a */
++ ti964-ti9x3@0 {
++ compatible = "ti,ti964-ti9x3";
++ reg = <0x3a>;
++ ti,sensor_delay = <350>;
++ ti,links = <4>;
++ ti,lanes = <4>;
++ ti,forwarding-mode = "round-robin";
++ ti,cable-mode = "coax";
++
++ port@0 {
++ ti964_des0ep0: endpoint@0 {
++ ti9x3-addr = <0x0c>;
++ dvp-order = <0>;
++ remote-endpoint = <&ov106xx_in0>;
++ };
++ ti964_des0ep1: endpoint@1 {
++ ti9x3-addr = <0x0d>;
++ dvp-order = <0>;
++ remote-endpoint = <&ov106xx_in1>;
++ };
++ ti964_des0ep2: endpoint@2 {
++ ti9x3-addr = <0x0e>;
++ dvp-order = <0>;
++ remote-endpoint = <&ov106xx_in2>;
++ };
++ ti964_des0ep3: endpoint@3 {
++ ti9x3-addr = <0x0f>;
++ dvp-order = <0>;
++ remote-endpoint = <&ov106xx_in3>;
++ };
++ };
++ port@1 {
++ ti964_csi0ep0: endpoint {
++ csi-rate = <1450>;
++ remote-endpoint = <&csi2_40_ep>;
++ };
++ };
++ };
++
++ /* DS90UB954 @ 0x38 */
++ ti954-ti9x3@0 {
++ compatible = "ti,ti954-ti9x3";
++ reg = <0x38>;
++ /* gpios = <&video_a_ext1 10 GPIO_ACTIVE_HIGH>; */
++ ti,sensor_delay = <350>;
++ ti,links = <2>;
++ ti,lanes = <4>;
++ ti,forwarding-mode = "round-robin";
++ ti,cable-mode = "coax";
++
++ port@0 {
++ ti954_des0ep0: endpoint@0 {
++ ti9x3-addr = <0x0c>;
++ dvp-order = <0>;
++ remote-endpoint = <&ov106xx_in0>;
++ };
++ ti954_des0ep1: endpoint@1 {
++ ti9x3-addr = <0x0d>;
++ dvp-order = <0>;
++ remote-endpoint = <&ov106xx_in1>;
++ };
++ };
++ port@1 {
++ ti954_csi0ep0: endpoint {
++ csi-rate = <1450>;
++ remote-endpoint = <&csi2_40_ep>;
++ };
++ };
++ };
++
++ /* MAX9286 @ 0x2c */
++ max9286-max9271@0 {
++ compatible = "maxim,max9286-max9271";
++ reg = <0x2c>;
++ maxim,sensor_delay = <350>;
++ 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>;
++ };
++ };
++ };
++ };
++
++ i2c@3 {
++ #address-cells = <1>;
++ #size-cells = <0>;
++ reg = <3>;
++ /* MOST node(s) */
++ };
++
++ i2c@7 {
++ #address-cells = <1>;
++ #size-cells = <0>;
++ reg = <7>;
++ /* Slot A (CN10) */
++
++ video_a_ext0: pca9535@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";
++ };
++ };
++
++ video_a_ext1: max7325@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_cam_pwr0 {
++ gpio-hog;
++ gpios = <8 GPIO_ACTIVE_HIGH>;
++ output-high;
++ line-name = "Video-A PWR0";
++ };
++ video_a_cam_pwr1 {
++ gpio-hog;
++ gpios = <9 GPIO_ACTIVE_HIGH>;
++ output-high;
++ line-name = "Video-A PWR1";
++ };
++ video_a_cam_pwr2 {
++ gpio-hog;
++ gpios = <10 GPIO_ACTIVE_HIGH>;
++ output-high;
++ line-name = "Video-A PWR2";
++ };
++ video_a_cam_pwr3 {
++ gpio-hog;
++ gpios = <11 GPIO_ACTIVE_HIGH>;
++ output-high;
++ line-name = "Video-A PWR3";
++ };
++ 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";
++ };
++ };
++ };
++ };
++};
++
++&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 = <&csi2_40_ep>;
++ };
++ };
++ port@2 {
++ vin0_max9286_des0ep0: endpoint@0 {
++ remote-endpoint = <&max9286_des0ep0>;
++ };
++ vin0_ti964_des0ep0: endpoint@1 {
++ remote-endpoint = <&ti964_des0ep0>;
++ };
++ vin0_ti954_des0ep0: endpoint@2 {
++ remote-endpoint = <&ti954_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>;
++ };
++ vin1_ti964_des0ep1: endpoint@1 {
++ remote-endpoint = <&ti964_des0ep1>;
++ };
++ vin1_ti954_des0ep1: endpoint@2 {
++ remote-endpoint = <&ti954_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>;
++ };
++ vin2_ti964_des0ep2: endpoint@1 {
++ remote-endpoint = <&ti964_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>;
++ };
++ vin3_ti964_des0ep3: endpoint@1 {
++ remote-endpoint = <&ti964_des0ep3>;
++ };
++ };
++ };
++};
++
++&csi2_40 {
++ 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>;
++ };
++ };
++};
++
++&rcar_sound {
++ pinctrl-0 = <&sound_clk_pins>;
++
++ /* Multi DAI */
++ #sound-dai-cells = <1>;
++
++ rcar_sound,dai {
++ dai0 {
++ playback = <&ssi7>;
++ capture = <&ssi8>;
++ };
++
++ dai1 {
++ playback = <&ssi0 &src0 &dvc0>;
++ capture = <&ssi1 &src1 &dvc1>;
++ };
++
++ dai2 {
++ capture = <&ssi6>;
++ };
++ };
++};
++
++&sdhi3 {
++ pinctrl-0 = <&sdhi3_pins_3v3>;
++ pinctrl-names = "default";
++
++ 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_RISING>;
++ };
++};
++
++&usb2_phy0 {
++ pinctrl-0 = <&usb0_pins>;
++ pinctrl-names = "default";
++
++ status = "okay";
++};
++
++&hsusb {
++ status = "okay";
++};
++
++&ehci0 {
++ status = "okay";
++};
++
++&ohci0 {
++ status = "okay";
++};
++
++&xhci0 {
++ status = "okay";
++};
++
++&msiof1 {
++ status = "disabled";
++};
++
++&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";
++
++ channel0 {
++ status = "okay";
++ };
++
++ channel1 {
++ status = "okay";
++ };
++};
++
++&ssi8 {
++ shared-pin;
++};
++
++/* uncomment to enable CN47: SD on SDHI3 */
++//#include "../ulcb-kf-sd3.dtsi"
++/* CN48 (Raspberry Pi) on VIN4 */
++#include "ulcb-kf-rpi.dtsi"
++/* CN29: (CMOS camera) on VIN5 */
++#include "ulcb-kf-cmos.dtsi"
+diff --git a/arch/arm64/boot/dts/renesas/legacy/r8a7796-m3ulcb-kf-v1.dts b/arch/arm64/boot/dts/renesas/legacy/r8a7796-m3ulcb-kf-v1.dts
+new file mode 100644
+index 0000000..637c840
+--- /dev/null
++++ b/arch/arm64/boot/dts/renesas/legacy/r8a7796-m3ulcb-kf-v1.dts
+@@ -0,0 +1,465 @@
++/*
++ * Device Tree Source for the M3ULCB Kingfisher V1 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 "r8a7796-m3ulcb-kf-v0.dts"
++
++/ {
++ model = "Renesas M3ULCB Kingfisher V1 board based on r8a7796";
++
++ aliases {
++ serial1 = &hscif0;
++ serial2 = &hscif1;
++ serial3 = &scif1;
++ };
++
++ wlan_en: regulator@4 {
++ compatible = "regulator-fixed";
++ regulator-name = "wlan-en-regulator";
++
++ regulator-min-microvolt = <3300000>;
++ regulator-max-microvolt = <3300000>;
++
++ gpio = <&gpio_ext_74 4 GPIO_ACTIVE_HIGH>;
++ enable-active-high;
++ };
++
++ codec_en_reg: regulator@6 {
++ compatible = "regulator-fixed";
++ regulator-name = "codec-en-regulator";
++ regulator-min-microvolt = <3300000>;
++ regulator-max-microvolt = <3300000>;
++
++ gpio = <&gpio_ext_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_ext_74 0 0>;
++
++ startup-delay-us = <0>;
++ enable-active-high;
++ };
++
++ /delete-node/regulator@8;
++
++ sdio_switch: regulator@9 {
++ compatible = "regulator-fixed";
++ regulator-name = "wifi_on";
++ regulator-min-microvolt = <3300000>;
++ regulator-max-microvolt = <3300000>;
++ gpio = <&gpio_ext_74 5 0>;
++ enable-active-low;
++ regulator-always-on;
++ };
++
++ /delete-node/regulator@10;
++
++ radio_switch: regulator@11 {
++ compatible = "regulator-fixed";
++ regulator-name = "radio_on";
++ regulator-min-microvolt = <3300000>;
++ regulator-max-microvolt = <3300000>;
++ gpio = <&gpio_ext_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_ext_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_ext_77 15 GPIO_ACTIVE_HIGH>;
++ startup-delay-us = <200000>;
++ enable-active-high;
++ };
++
++ kim {
++ shutdown-gpios = <&gpio_ext_74 3 GPIO_ACTIVE_HIGH>;
++ };
++
++ hdmi-out {
++ compatible = "hdmi-connector";
++ type = "a";
++
++ port {
++ hdmi_con: endpoint {
++ remote-endpoint = <&adv7513_out>;
++ };
++ };
++ };
++};
++
++&pfc {
++ /delete-node/hscif4;
++
++ scif1_pins: scif1 {
++ groups = "scif1_data_b";
++ function = "scif1";
++ };
++
++ hscif0_pins: hscif0 {
++ groups = "hscif0_data", "hscif0_ctrl";
++ function = "hscif0";
++ };
++
++ hscif1_pins: hscif1 {
++ groups = "hscif1_data_a", "hscif1_ctrl_a";
++ function = "hscif1";
++ };
++
++ du_pins: du {
++ groups = "du_rgb888", "du_sync", "du_clk_out_0", "du_disp";
++ function = "du";
++ };
++};
++
++&du {
++ pinctrl-0 = <&du_pins>;
++ pinctrl-names = "default";
++
++ ports {
++ port@0 {
++ endpoint {
++ remote-endpoint = <&adv7513_in>;
++ };
++ };
++ };
++};
++
++&gpio0 {
++ /delete-node/video_a_irq;
++ /delete-node/video_b_irq;
++ /delete-node/gpioext_2_20_irq;
++};
++
++&gpio1 {
++ /delete-node/gpioext_2_21_irq;
++ /delete-node/wifi_irq;
++};
++
++&gpio2 {
++ bl_pwm {
++ gpio-hog;
++ gpios = <3 GPIO_ACTIVE_HIGH>;
++ output-high;
++ line-name = "BL PWM 100%";
++ };
++};
++
++&gpio5 {
++ /delete-node/touch_irq;
++ /delete-node/bt_strap;
++};
++
++&gpio7 {
++ /delete-node/gpioext_2_21_irq;
++};
++
++&scif1 {
++ pinctrl-0 = <&scif1_pins>;
++ pinctrl-names = "default";
++
++ status = "okay";
++};
++
++&hscif0 {
++ pinctrl-0 = <&hscif0_pins>;
++ pinctrl-names = "default";
++ uart-has-rtscts;
++
++ status = "okay";
++};
++
++&hscif1 {
++ pinctrl-0 = <&hscif1_pins>;
++ pinctrl-names = "default";
++
++ status = "okay";
++};
++
++&hscif4 {
++ /delete-property/pinctrl-0;
++ /delete-property/pinctrl-names;
++
++ status = "disabled";
++};
++
++&i2c2 {
++ /delete-node/pca9535@20;
++ /delete-node/pca9535@21;
++
++ gpio_ext_74: pca9539@74 {
++ compatible = "nxp,pca9539";
++ 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>;
++ output-high;
++ line-name = "HUB pwen";
++ };
++ hub_rst {
++ gpio-hog;
++ gpios = <7 GPIO_ACTIVE_HIGH>;
++ output-high;
++ line-name = "HUB rst";
++ };
++ otg_offvbus {
++ gpio-hog;
++ gpios = <8 GPIO_ACTIVE_HIGH>;
++ output-low;
++ line-name = "OTG off VBUSn";
++ };
++ otg_extlpn {
++ gpio-hog;
++ gpios = <9 GPIO_ACTIVE_HIGH>;
++ output-high;
++ line-name = "OTG EXTLPn";
++ };
++ otg_stat1 {
++ gpio-hog;
++ gpios = <10 GPIO_ACTIVE_HIGH>;
++ input;
++ line-name = "OTG Stat1";
++ };
++ otg_stat2 {
++ gpio-hog;
++ gpios = <11 GPIO_ACTIVE_HIGH>;
++ input;
++ line-name = "OTG Stat2";
++ };
++ };
++
++ gpio_ext_75: pca9539@75 {
++ compatible = "nxp,pca9539";
++ reg = <0x75>;
++ gpio-controller;
++ #gpio-cells = <2>;
++ 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 {
++ reg = <0x71>;
++ reset-gpios= <&gpio5 3 GPIO_ACTIVE_LOW>;
++
++ i2c@4 {
++ #address-cells = <1>;
++ #size-cells = <0>;
++ reg = <4>;
++
++ hdmi@3d {
++ compatible = "adi,adv7511w";
++ reg = <0x3d>;
++// interrupt-parent = <&gpio2>;
++// interrupts = <0 IRQ_TYPE_EDGE_BOTH>;
++ pd-gpios = <&gpio_ext_75 5 GPIO_ACTIVE_LOW>;
++
++ adi,input-depth = <8>;
++ adi,input-colorspace = "rgb";
++ adi,input-clock = "1x";
++ adi,input-style = <1>;
++ adi,input-justification = "evenly";
++ adi,clock-delay = <1200>;
++ adi,clock-max-rate = <100000>;
++
++ 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>;
++ };
++ };
++ };
++ };
++ };
++};
++
++&i2c4 {
++ /delete-node/pca9535@21;
++
++ gpio_ext_76: pca9539@76 {
++ compatible = "nxp,pca9539";
++ reg = <0x76>;
++ gpio-controller;
++ #gpio-cells = <2>;
++ 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_ext_77: pca9539@77 {
++ compatible = "nxp,pca9539";
++ reg = <0x77>;
++ gpio-controller;
++ #gpio-cells = <2>;
++ 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 {
++ reg = <0x71>;
++ reset-gpios= <&gpio3 15 GPIO_ACTIVE_LOW>;
++};
++
++&wlcore {
++ interrupts = <25 IRQ_TYPE_EDGE_FALLING>;
++};
++
++&pciec1 {
++ pcie3v3-supply = <&mpcie_3v3>;
++ pcie1v8-supply = <&mpcie_1v8>;
++};
+diff --git a/arch/arm64/boot/dts/renesas/legacy/r8a7797-v3msk-kf-v0.dts b/arch/arm64/boot/dts/renesas/legacy/r8a7797-v3msk-kf-v0.dts
+new file mode 100644
+index 0000000..674d3bf
+--- /dev/null
++++ b/arch/arm64/boot/dts/renesas/legacy/r8a7797-v3msk-kf-v0.dts
+@@ -0,0 +1,82 @@
++/*
++ * Device Tree Source for the V3MSK Kingfisher V0 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 "../r8a7797-v3msk-kf.dts"
++
++/ {
++ model = "Renesas V3MSK Kingfisher V0 board based on r8a7797";
++};
++
++&i2cswitch4 {
++ reg = <0x74>;
++};
++
++&msiof1 {
++ pinctrl-0 = <&msiof1_pins>;
++ pinctrl-names = "default";
++ status = "okay";
++
++ spidev@0 {
++ compatible = "renesas,sh-msiof";
++ reg = <0>;
++ spi-max-frequency = <66666666>;
++ spi-cpha;
++ spi-cpol;
++ };
++};
++
++&msiof2 {
++ pinctrl-0 = <&msiof2_pins>;
++ pinctrl-names = "default";
++ status = "okay";
++
++ spidev@0 {
++ compatible = "renesas,sh-msiof";
++ reg = <0>;
++ spi-max-frequency = <66666666>;
++ spi-cpha;
++ spi-cpol;
++ };
++};
++
++&msiof3 {
++ pinctrl-0 = <&msiof3_pins>;
++ pinctrl-names = "default";
++ status = "okay";
++
++ spidev@0 {
++ compatible = "renesas,sh-msiof";
++ reg = <0>;
++ spi-max-frequency = <66666666>;
++ spi-cpha;
++ spi-cpol;
++ };
++};
++
++&pfc {
++ msiof1_pins: spi2 {
++ groups = "msiof1_clk", "msiof1_sync", "msiof1_rxd",
++ "msiof1_txd";
++ function = "msiof1";
++ };
++
++ msiof2_pins: spi3 {
++ groups = "msiof2_clk", "msiof2_sync", "msiof2_rxd",
++ "msiof2_txd";
++ function = "msiof2";
++ };
++
++ msiof3_pins: spi4 {
++ groups = "msiof3_clk", "msiof3_sync", "msiof3_rxd",
++ "msiof3_txd";
++ function = "msiof3";
++ };
++};
+diff --git a/arch/arm64/boot/dts/renesas/legacy/ulcb-kf-cmos.dtsi b/arch/arm64/boot/dts/renesas/legacy/ulcb-kf-cmos.dtsi
+new file mode 100644
+index 0000000..2145f5e
+--- /dev/null
++++ b/arch/arm64/boot/dts/renesas/legacy/ulcb-kf-cmos.dtsi
+@@ -0,0 +1,75 @@
++/*
++ * Device Tree Source for the H3ULCB Kingfisher board:
++ * this adding conflicting resource on VIN5 for CMOS camera
++ *
++ * 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.
++ */
++
++/ {
++ camera_clk: camera_clk {
++ compatible = "fixed-clock";
++ #clock-cells = <0>;
++ clock-frequency = <24000000>;
++ clock-output-names = "mclk";
++ };
++};
++
++&pfc {
++ vin5_pins: vin5 {
++ groups = "vin5_data8", "vin5_sync", "vin5_clk";
++ function = "vin5";
++ };
++};
++
++&i2cswitch4 {
++ 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>;
++ };
++ };
++ };
++ };
++};
++
++&vin5 {
++ pinctrl-0 = <&vin5_pins>;
++ pinctrl-names = "default";
++ status = "okay";
++
++ ports {
++ #address-cells = <1>;
++ #size-cells = <0>;
++
++ port@0 {
++ vin5ep0: endpoint@0 {
++ /delete-property/csi,select;
++ /delete-property/virtual,channel;
++ /delete-property/data-lanes;
++ bus-width = <8>;
++ /* #HSYNC, #VSYNC */
++ vsync-active = <1>;
++ hsync-active = <0>;
++ remote-endpoint = <&cmos_camera_in>;
++ };
++ };
++ port@1 {
++ /delete-node/endpoint;
++ };
++ };
++};
+diff --git a/arch/arm64/boot/dts/renesas/legacy/ulcb-kf-rpi.dtsi b/arch/arm64/boot/dts/renesas/legacy/ulcb-kf-rpi.dtsi
+new file mode 100644
+index 0000000..bcd9865
+--- /dev/null
++++ b/arch/arm64/boot/dts/renesas/legacy/ulcb-kf-rpi.dtsi
+@@ -0,0 +1,77 @@
++/*
++ * Device Tree Source for the H3ULCB Kingfisher board:
++ * this adding conflicting resource on VIN4 for Raspberry Pi camera
++ *
++ * 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@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>;
++ };
++ };
++ };
++ };
++};
++
++&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 = <&csi2_20_ep>;
++ };
++ };
++ };
++};
++
++&csi2_20 {
++ status = "okay";
++
++ virtual,channel {
++ csi2_vc0 {
++ data,type = "raw8";
++ receive,vc = <0>;
++ };
++ };
++
++ port {
++ #address-cells = <1>;
++ #size-cells = <0>;
++
++ csi2_20_ep: endpoint {
++ clock-lanes = <0>;
++ data-lanes = <1 2>;
++ csi-rate = <280>;
++ };
++ };
++};
+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..d50ff7a
+--- /dev/null
++++ b/arch/arm64/boot/dts/renesas/r8a7795-es1-h3ulcb-had.dtsi
+@@ -0,0 +1,225 @@
++/*
++ * 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 {
++ serial1 = &scif1;
++ spi1 = &spi0_gpio;
++ spi2 = &spi1_gpio;
++ };
++
++ chosen {
++ stdout-path = "serial1:115200n8";
++ };
++
++ 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";
++ type = "a";
++
++ port {
++ hdmi1_con: endpoint {
++ remote-endpoint = <&rcar_dw_hdmi1_out>;
++ };
++ };
++ };
++};
++
++&du {
++ ports {
++ port@1 {
++ endpoint {
++ remote-endpoint = <&rcar_dw_hdmi0_in>;
++ };
++ };
++ port@2 {
++ endpoint {
++ remote-endpoint = <&rcar_dw_hdmi1_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>;
++ };
++ };
++ };
++};
++
++&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
+new file mode 100644
+index 0000000..849afae
+--- /dev/null
++++ b/arch/arm64/boot/dts/renesas/r8a7795-es1-h3ulcb-kf.dts
+@@ -0,0 +1,39 @@
++/*
++ * Device Tree Source for the H3ULCB Kingfisher 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-kf.dtsi"
++
++/ {
++ model = "Renesas H3ULCB Kingfisher board based on r8a7795";
++};
++
++&du {
++ ports {
++ port@0 {
++ endpoint {
++ remote-endpoint = <&adv7513_in>;
++ };
++ };
++ port@3 {
++ endpoint {
++ remote-endpoint = <&lvds_enc_in>;
++ };
++ };
++ };
++};
++
++&hsusb {
++ status = "okay";
++};
++
++/* 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..549a717
+--- /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_enc_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-vbm.dts b/arch/arm64/boot/dts/renesas/r8a7795-es1-h3ulcb-vbm.dts
+new file mode 100644
+index 0000000..323722c
+--- /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_enc_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..de56fa4
+--- /dev/null
++++ b/arch/arm64/boot/dts/renesas/r8a7795-es1-h3ulcb-view.dts
+@@ -0,0 +1,546 @@
++/*
++ * 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-max9271@0 {
++ compatible = "maxim,max9286-max9271";
++ reg = <0x4c>;
++ gpios = <&gpio2 6 GPIO_ACTIVE_HIGH>;
++ maxim,sensor_delay = <0>;
++ 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 = <&csi2_40_ep>;
++ };
++ };
++ };
++
++ max9286-max9271@1 {
++ compatible = "maxim,max9286-max9271";
++ reg = <0x6c>;
++ gpios = <&gpio5 25 GPIO_ACTIVE_HIGH>;
++ maxim,sensor_delay = <0>;
++ 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 = <&csi2_41_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 = <&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>;
++ };
++ };
++ };
++};
++
++&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 = <&csi2_41_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 = <&csi2_41_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 = <&csi2_41_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 = <&csi2_41_ep>;
++ };
++ };
++ port@2 {
++ vin7_max9286_des1ep3: endpoint@0 {
++ remote-endpoint = <&max9286_des1ep3>;
++ };
++ };
++ };
++};
++
++&csi2_40 {
++ 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>;
++ };
++ };
++};
++
++&csi2_41 {
++ 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 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..3f3d66a
+--- /dev/null
++++ b/arch/arm64/boot/dts/renesas/r8a7795-es1-salvator-x-view.dts
+@@ -0,0 +1,552 @@
++/*
++ * 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-max9271@0 {
++ compatible = "maxim,max9286-max9271";
++ reg = <0x4c>;
++ gpios = <&gpio6 30 GPIO_ACTIVE_LOW>;
++ maxim,sensor_delay = <0>;
++ 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 = <&csi2_40_ep>;
++ };
++ };
++ };
++
++ max9286-max9271@1 {
++ compatible = "maxim,max9286-max9271";
++ reg = <0x6c>;
++ maxim,sensor_delay = <0>;
++ 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 = <&csi2_41_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 = <&csi2_40_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 = <&csi2_40_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 = <&csi2_40_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 = <&csi2_40_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 = <&csi2_41_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 = <&csi2_41_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 = <&csi2_41_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 = <&csi2_41_ep>;
++ };
++ };
++ port@2 {
++ vin7_max9286_des1ep3: endpoint@0 {
++ remote-endpoint = <&max9286_des1ep3>;
++ };
++ };
++ };
++};
++
++&csi2_20 {
++ status = "disabled";
++ /delete-node/ports;
++};
++
++&csi2_40 {
++ /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>;
++
++ csi2_40_ep: endpoint {
++ clock-lanes = <0>;
++ data-lanes = <1 2 3 4>;
++ csi-rate = <300>;
++ };
++ };
++};
++
++&csi2_41 {
++ 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 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-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..4a00426
+--- /dev/null
++++ b/arch/arm64/boot/dts/renesas/r8a7795-h3ulcb-had.dtsi
+@@ -0,0 +1,219 @@
++/*
++ * 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 {
++ serial1 = &scif1;
++ spi1 = &spi0_gpio;
++ spi2 = &spi1_gpio;
++ };
++
++ chosen {
++ stdout-path = "serial1:115200n8";
++ };
++
++ 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";
++ type = "a";
++
++ port {
++ hdmi1_con: endpoint {
++ remote-endpoint = <&rcar_dw_hdmi1_out>;
++ };
++ };
++ };
++};
++
++&du {
++ ports {
++ port@1 {
++ endpoint {
++ remote-endpoint = <&rcar_dw_hdmi0_in>;
++ };
++ };
++ port@2 {
++ endpoint {
++ remote-endpoint = <&rcar_dw_hdmi1_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>;
++ };
++ };
++ };
++};
++
++&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
+new file mode 100644
+index 0000000..4fe67f8
+--- /dev/null
++++ b/arch/arm64/boot/dts/renesas/r8a7795-h3ulcb-kf.dts
+@@ -0,0 +1,39 @@
++/*
++ * Device Tree Source for the H3ULCB Kingfisher board on r8a7795
++ *
++ * 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.dts"
++#include "ulcb-kf.dtsi"
++
++/ {
++ model = "Renesas H3ULCB Kingfisher board based on r8a7795";
++};
++
++&du {
++ ports {
++ port@0 {
++ endpoint {
++ remote-endpoint = <&adv7513_in>;
++ };
++ };
++ port@3 {
++ endpoint {
++ remote-endpoint = <&lvds_enc_in>;
++ };
++ };
++ };
++};
++
++&hsusb0 {
++ status = "okay";
++};
++
++/* 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..330bba2
+--- /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_enc_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>;
++ };
++ };
++ };
++};
++
++&hsusb0 {
++ 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..87f1889
+--- /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_enc_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..2c24b85
+--- /dev/null
++++ b/arch/arm64/boot/dts/renesas/r8a7795-h3ulcb-view.dts
+@@ -0,0 +1,546 @@
++/*
++ * 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-max9271@0 {
++ compatible = "maxim,max9286-max9271";
++ reg = <0x4c>;
++ gpios = <&gpio2 6 GPIO_ACTIVE_HIGH>;
++ maxim,sensor_delay = <0>;
++ 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 = <&csi2_40_ep>;
++ };
++ };
++ };
++
++ max9286-max9271@1 {
++ compatible = "maxim,max9286-max9271";
++ reg = <0x6c>;
++ gpios = <&gpio5 25 GPIO_ACTIVE_HIGH>;
++ maxim,sensor_delay = <0>;
++ 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 = <&csi2_41_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 = <&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>;
++ };
++ };
++ };
++};
++
++&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 = <&csi2_41_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 = <&csi2_41_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 = <&csi2_41_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 = <&csi2_41_ep>;
++ };
++ };
++ port@2 {
++ vin7_max9286_des1ep3: endpoint@0 {
++ remote-endpoint = <&max9286_des1ep3>;
++ };
++ };
++ };
++};
++
++&csi2_40 {
++ 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>;
++ };
++ };
++};
++
++&csi2_41 {
++ 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 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..fb12a39f3
+--- /dev/null
++++ b/arch/arm64/boot/dts/renesas/r8a7795-salvator-x-view.dts
+@@ -0,0 +1,552 @@
++/*
++ * 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-max9271@0 {
++ compatible = "maxim,max9286-max9271";
++ reg = <0x4c>;
++ gpios = <&gpio6 30 GPIO_ACTIVE_LOW>;
++ maxim,sensor_delay = <0>;
++ 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 = <&csi2_40_ep>;
++ };
++ };
++ };
++
++ max9286-max9271@1 {
++ compatible = "maxim,max9286-max9271";
++ reg = <0x6c>;
++ maxim,sensor_delay = <0>;
++ 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 = <&csi2_41_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 = <&csi2_40_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 = <&csi2_40_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 = <&csi2_40_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 = <&csi2_40_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 = <&csi2_41_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 = <&csi2_41_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 = <&csi2_41_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 = <&csi2_41_ep>;
++ };
++ };
++ port@2 {
++ vin7_max9286_des1ep3: endpoint@0 {
++ remote-endpoint = <&max9286_des1ep3>;
++ };
++ };
++ };
++};
++
++&csi2_20 {
++ status = "disabled";
++ /delete-node/ports;
++};
++
++&csi2_40 {
++ /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>;
++
++ csi2_40_ep: endpoint {
++ clock-lanes = <0>;
++ data-lanes = <1 2 3 4>;
++ csi-rate = <300>;
++ };
++ };
++};
++
++&csi2_41 {
++ 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 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
+new file mode 100644
+index 0000000..a409402
+--- /dev/null
++++ b/arch/arm64/boot/dts/renesas/r8a7796-m3ulcb-kf.dts
+@@ -0,0 +1,40 @@
++/*
++ * Device Tree Source for the M3ULCB Kingfisher board on r8a7796
++ *
++ * 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 "r8a7796-m3ulcb.dts"
++#include "ulcb-kf.dtsi"
++
++/ {
++ model = "Renesas M3ULCB Kingfisher board based on r8a7796";
++};
++
++&du {
++ ports {
++ port@0 {
++ endpoint {
++ remote-endpoint = <&adv7513_in>;
++ };
++ };
++ port@2 {
++ endpoint {
++ remote-endpoint = <&lvds_enc_in>;
++ };
++ };
++ };
++};
++
++&hsusb {
++ status = "okay";
++};
++
++&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..1ac0041
+--- /dev/null
++++ b/arch/arm64/boot/dts/renesas/r8a7796-m3ulcb-view.dts
+@@ -0,0 +1,287 @@
++/*
++ * 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-max9271@0 {
++ compatible = "maxim,max9286-max9271";
++ reg = <0x4c>;
++ gpios = <&gpio2 6 GPIO_ACTIVE_HIGH>;
++ maxim,sensor_delay = <0>;
++ 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 = <&csi2_40_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 = <&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>;
++ };
++ };
++ };
++};
++
++&csi2_40 {
++ 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>;
++ };
++ };
++};
+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..cc6866c
+--- /dev/null
++++ b/arch/arm64/boot/dts/renesas/r8a7796-salvator-x-view.dts
+@@ -0,0 +1,318 @@
++/*
++ * 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-max9271@0 {
++ compatible = "maxim,max9286-max9271";
++ reg = <0x4c>;
++ gpios = <&gpio6 30 GPIO_ACTIVE_LOW>;
++ maxim,sensor_delay = <0>;
++ 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 = <&csi2_40_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 = <&csi2_40_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 = <&csi2_40_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 = <&csi2_40_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 = <&csi2_40_ep>;
++ };
++ };
++ port@2 {
++ vin3_max9286_des0ep3: endpoint@0 {
++ remote-endpoint = <&max9286_des0ep3>;
++ };
++ };
++ };
++};
++
++&vin4 {
++ status = "disabled";
++};
++
++&vin5 {
++ status = "disabled";
++};
++
++&vin6 {
++ status = "disabled";
++};
++
++&vin7 {
++ status = "disabled";
++};
++
++&csi2_20 {
++ status = "disabled";
++ /delete-node/ports;
++};
++
++&csi2_40 {
++ /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>;
++
++ csi2_40_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/r8a7797-eagle.dts b/arch/arm64/boot/dts/renesas/r8a7797-eagle.dts
+new file mode 100644
+index 0000000..3fb3bf1
+--- /dev/null
++++ b/arch/arm64/boot/dts/renesas/r8a7797-eagle.dts
+@@ -0,0 +1,560 @@
++/*
++ * Device Tree Source for the Eagle board
++ *
++ * 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.
++ */
++
++/dts-v1/;
++#include "r8a7797.dtsi"
++#include <dt-bindings/gpio/gpio.h>
++
++/ {
++ model = "Renesas Eagle board based on r8a7797";
++ compatible = "renesas,eagle", "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 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";
++ };
++
++ lvds-encoder {
++ compatible = "thine,thc63lvdm83d";
++
++ ports {
++ #address-cells = <1>;
++ #size-cells = <0>;
++
++ port@0 {
++ reg = <0>;
++ lvds_enc_in: endpoint {
++ remote-endpoint = <&du_out_lvds0>;
++ };
++ };
++ port@1 {
++ reg = <1>;
++ lvds_enc_out: endpoint {
++ remote-endpoint = <&lvds_in>;
++ };
++ };
++ };
++ };
++
++ lvds {
++ compatible = "lvds-connector";
++
++ width-mm = <210>;
++ height-mm = <158>;
++
++ panel-timing {
++ clock-frequency = <133000000>;
++ hactive = <1024>;
++ vactive = <768>;
++ hsync-len = <136>;
++ hfront-porch = <20>;
++ hback-porch = <160>;
++ vfront-porch = <3>;
++ vback-porch = <29>;
++ vsync-len = <6>;
++ };
++
++ port {
++ lvds_in: endpoint {
++ remote-endpoint = <&lvds_enc_out>;
++ };
++ };
++ };
++
++ hdmi-out {
++ compatible = "hdmi-connector";
++ type = "a";
++
++ port {
++ hdmi_con: endpoint {
++ remote-endpoint = <&adv7511_out>;
++ };
++ };
++ };
++
++ 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>;
++ };
++};
++
++&du {
++ pinctrl-0 = <&du_pins>;
++ pinctrl-names = "default";
++ status = "okay";
++
++ ports {
++ port@0 {
++ endpoint {
++ remote-endpoint = <&adv7511_in>;
++ };
++ };
++ };
++};
++
++&extal_clk {
++ clock-frequency = <16666666>;
++};
++
++&extalr_clk {
++ clock-frequency = <32768>;
++};
++
++&pfc {
++ pinctrl-0 = <&scif_clk_pins>;
++ pinctrl-names = "default";
++
++ scif0_pins: scif0 {
++ groups = "scif0_data";
++ function = "scif0";
++ };
++
++ scif_clk_pins: scif_clk {
++ groups = "scif_clk_b";
++ function = "scif_clk";
++ };
++
++ i2c0_pins: i2c0 {
++ groups = "i2c0";
++ function = "i2c0";
++ };
++
++ i2c3_pins: i2c3 {
++ groups = "i2c3";
++ function = "i2c3";
++ };
++
++ avb_pins: avb {
++ groups = "avb0_mdc";
++ function = "avb0";
++ };
++
++ du_pins: du {
++ groups = "du_rgb666", "du_sync", "du_clk_out_0", "du_disp";
++ function = "du";
++ };
++};
++
++&scif0 {
++ pinctrl-0 = <&scif0_pins>;
++ pinctrl-names = "default";
++
++ status = "okay";
++};
++
++&scif_clk {
++ clock-frequency = <14745600>;
++ status = "okay";
++};
++
++&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>;
++
++ 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 = <&lvds_enc_out>;
++ };
++ };
++ port@1 {
++ reg = <1>;
++ adv7511_out: endpoint {
++ remote-endpoint = <&hdmi_con>;
++ };
++ };
++ };
++ };
++
++ gpio_ext: pca9654@20 {
++ compatible = "onsemi,pca9654";
++ reg = <0x20>;
++ gpio-controller;
++ #gpio-cells = <2>;
++ };
++};
++
++&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-max9271@0 {
++ compatible = "maxim,max9286-max9271";
++ reg = <0x48>;
++ gpios = <&gpio_ext 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>;
++ };
++ };
++ };
++};
++
++&wdt0 {
++ status = "okay";
++};
++
++&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>;
++ };
++};
++
++&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>;
++ };
++ };
++ };
++};
++
++&csi2_40 {
++ 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>;
++ };
++ };
++};
+diff --git a/arch/arm64/boot/dts/renesas/r8a7797-v3msk-kf.dts b/arch/arm64/boot/dts/renesas/r8a7797-v3msk-kf.dts
+new file mode 100644
+index 0000000..979cebe
+--- /dev/null
++++ b/arch/arm64/boot/dts/renesas/r8a7797-v3msk-kf.dts
+@@ -0,0 +1,578 @@
++/*
++ * 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 "r8a7797-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";
++ };
++};
++
++&csi2_40 {
++ 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>;
++ };
++ };
++};
++
++&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_ti964_des0ep0: endpoint@1 {
++ remote-endpoint = <&ti964_des0ep0>;
++ };
++ ov106xx_ti954_des0ep0: endpoint@2 {
++ remote-endpoint = <&ti954_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_ti964_des0ep1: endpoint@1 {
++ remote-endpoint = <&ti964_des0ep1>;
++ };
++ ov106xx_ti954_des0ep1: endpoint@2 {
++ remote-endpoint = <&ti954_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_ti964_des0ep2: endpoint@1 {
++ remote-endpoint = <&ti964_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_ti964_des0ep3: endpoint@1 {
++ remote-endpoint = <&ti964_des0ep3>;
++ };
++ };
++ };
++
++ /* DS90UB964 @ 0x3a */
++ ti964-ti9x3@0 {
++ compatible = "ti,ti964-ti9x3";
++ reg = <0x3a>;
++ ti,sensor_delay = <350>;
++ ti,links = <4>;
++ ti,lanes = <4>;
++ ti,forwarding-mode = "round-robin";
++ ti,cable-mode = "coax";
++
++ port@0 {
++ ti964_des0ep0: endpoint@0 {
++ ti9x3-addr = <0x0c>;
++ dvp-order = <0>;
++ remote-endpoint = <&ov106xx_in0>;
++ };
++ ti964_des0ep1: endpoint@1 {
++ ti9x3-addr = <0x0d>;
++ dvp-order = <0>;
++ remote-endpoint = <&ov106xx_in1>;
++ };
++ ti964_des0ep2: endpoint@2 {
++ ti9x3-addr = <0x0e>;
++ dvp-order = <0>;
++ remote-endpoint = <&ov106xx_in2>;
++ };
++ ti964_des0ep3: endpoint@3 {
++ ti9x3-addr = <0x0f>;
++ dvp-order = <0>;
++ remote-endpoint = <&ov106xx_in3>;
++ };
++ };
++ port@1 {
++ ti964_csi0ep0: endpoint {
++ csi-rate = <800>;
++ remote-endpoint = <&csi2_40_ep>;
++ };
++ };
++ };
++
++ /* DS90UB954 @ 0x38 */
++ ti954-ti9x3@0 {
++ compatible = "ti,ti954-ti9x3";
++ reg = <0x38>;
++ /* gpios = <&video_a_ext1 10 GPIO_ACTIVE_HIGH>; */
++ ti,sensor_delay = <350>;
++ ti,links = <2>;
++ ti,lanes = <4>;
++ ti,forwarding-mode = "round-robin";
++ ti,cable-mode = "coax";
++
++ port@0 {
++ ti954_des0ep0: endpoint@0 {
++ ti9x3-addr = <0x0c>;
++ dvp-order = <0>;
++ remote-endpoint = <&ov106xx_in0>;
++ };
++ ti954_des0ep1: endpoint@1 {
++ ti9x3-addr = <0x0d>;
++ dvp-order = <0>;
++ remote-endpoint = <&ov106xx_in1>;
++ };
++ };
++ port@1 {
++ ti954_csi0ep0: endpoint {
++ csi-rate = <800>;
++ remote-endpoint = <&csi2_40_ep>;
++ };
++ };
++ };
++
++ /* MAX9286 @ 0x2c */
++ max9286-max9271@0 {
++ compatible = "maxim,max9286-max9271";
++ reg = <0x2c>;
++ maxim,sensor_delay = <350>;
++ 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>;
++ };
++ };
++ };
++ };
++
++ i2c@6 {
++ #address-cells = <1>;
++ #size-cells = <0>;
++ reg = <6>;
++ /* Slot B (CN11) */
++
++ video_a_ext0: pca9535@27 {
++ compatible = "nxp,pca9535";
++ reg = <0x27>;
++ 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";
++ };
++ };
++
++ video_a_ext1: max7325@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_cam_pwr0 {
++ gpio-hog;
++ gpios = <8 GPIO_ACTIVE_HIGH>;
++ output-high;
++ line-name = "Video-A PWR0";
++ };
++ video_a_cam_pwr1 {
++ gpio-hog;
++ gpios = <9 GPIO_ACTIVE_HIGH>;
++ output-high;
++ line-name = "Video-A PWR1";
++ };
++ video_a_cam_pwr2 {
++ gpio-hog;
++ gpios = <10 GPIO_ACTIVE_HIGH>;
++ output-high;
++ line-name = "Video-A PWR2";
++ };
++ video_a_cam_pwr3 {
++ gpio-hog;
++ gpios = <11 GPIO_ACTIVE_HIGH>;
++ output-high;
++ line-name = "Video-A PWR3";
++ };
++ 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 = <&csi2_40_ep>;
++ };
++ };
++ port@2 {
++ vin0_max9286_des0ep0: endpoint@0 {
++ remote-endpoint = <&max9286_des0ep0>;
++ };
++ vin0_ti964_des0ep0: endpoint@1 {
++ remote-endpoint = <&ti964_des0ep0>;
++ };
++ vin0_ti954_des0ep0: endpoint@2 {
++ remote-endpoint = <&ti954_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>;
++ };
++ vin1_ti964_des0ep1: endpoint@1 {
++ remote-endpoint = <&ti964_des0ep1>;
++ };
++ vin1_ti954_des0ep1: endpoint@2 {
++ remote-endpoint = <&ti954_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>;
++ };
++ vin2_ti964_des0ep2: endpoint@1 {
++ remote-endpoint = <&ti964_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>;
++ };
++ vin3_ti964_des0ep3: endpoint@1 {
++ remote-endpoint = <&ti964_des0ep3>;
++ };
++ };
++ };
++};
+diff --git a/arch/arm64/boot/dts/renesas/r8a7797-v3msk-vbm.dts b/arch/arm64/boot/dts/renesas/r8a7797-v3msk-vbm.dts
+new file mode 100644
+index 0000000..4292b7b
+--- /dev/null
++++ b/arch/arm64/boot/dts/renesas/r8a7797-v3msk-vbm.dts
+@@ -0,0 +1,518 @@
++/*
++ * 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 "r8a7797-v3msk.dts"
++
++/ {
++ model = "Renesas V3MSK Videobox Mini board based on r8a7797";
++
++ aliases {
++ serial1 = &scif3;
++ };
++
++ pwr0: regulator-pwr0 {
++ compatible = "regulator-fixed";
++ regulator-name = "PWR0";
++ regulator-min-microvolt = <9000000>;
++ regulator-max-microvolt = <9000000>;
++ gpio = <&gpio_exp_6c 8 GPIO_ACTIVE_HIGH>;
++ enable-active-high;
++ };
++
++ pwr1: regulator-pwr1 {
++ compatible = "regulator-fixed";
++ regulator-name = "PWR1";
++ regulator-min-microvolt = <9000000>;
++ regulator-max-microvolt = <9000000>;
++ gpio = <&gpio_exp_6c 9 GPIO_ACTIVE_HIGH>;
++ enable-active-high;
++ };
++
++ pwr2: regulator-pwr2 {
++ compatible = "regulator-fixed";
++ regulator-name = "PWR2";
++ regulator-min-microvolt = <9000000>;
++ regulator-max-microvolt = <9000000>;
++ gpio = <&gpio_exp_6c 10 GPIO_ACTIVE_HIGH>;
++ enable-active-high;
++ };
++
++ pwr3: regulator-pwr3 {
++ compatible = "regulator-fixed";
++ regulator-name = "PWR3";
++ regulator-min-microvolt = <9000000>;
++ regulator-max-microvolt = <9000000>;
++ gpio = <&gpio_exp_6c 11 GPIO_ACTIVE_HIGH>;
++ enable-active-high;
++ };
++};
++
++&canfd {
++ pinctrl-0 = <&canfd0_pins &canfd1_pins>;
++ pinctrl-names = "default";
++ status = "okay";
++
++ channel0 {
++ status = "okay";
++ };
++
++ channel1 {
++ status = "okay";
++ };
++};
++
++&csi2_40 {
++ 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>;
++ };
++ };
++};
++
++&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_ti964_des0ep0: endpoint@1 {
++ remote-endpoint = <&ti964_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_ti964_des0ep1: endpoint@1 {
++ remote-endpoint = <&ti964_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_ti964_des0ep2: endpoint@1 {
++ remote-endpoint = <&ti964_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_ti964_des0ep3: endpoint@1 {
++ remote-endpoint = <&ti964_des0ep3>;
++ };
++ };
++ };
++
++ max9286-max9271@0 {
++ compatible = "maxim,max9286-max9271";
++ reg = <0x2c>;
++ maxim,sensor_delay = <350>;
++ maxim,links = <4>;
++ maxim,lanes = <4>;
++ maxim,resetb-gpio = <1>;
++ maxim,fsync-mode = "automatic";
++ maxim,timeout = <100>;
++ POC0-supply = <&pwr0>;
++ POC1-supply = <&pwr1>;
++ POC2-supply = <&pwr2>;
++ POC3-supply = <&pwr3>;
++
++ 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>;
++ };
++ };
++ };
++
++ ti964-ti9x3@0 {
++ compatible = "ti,ti964-ti9x3";
++ reg = <0x3a>;
++ ti,sensor_delay = <350>;
++ ti,links = <4>;
++ ti,lanes = <4>;
++ ti,forwarding-mode = "round-robin";
++ ti,cable-mode = "coax";
++ POC0-supply = <&pwr0>;
++ POC1-supply = <&pwr1>;
++ POC2-supply = <&pwr2>;
++ POC3-supply = <&pwr3>;
++
++ port@0 {
++ ti964_des0ep0: endpoint@0 {
++ ti9x3-addr = <0x0c>;
++ dvp-order = <0>;
++ remote-endpoint = <&ov106xx_in0>;
++ };
++ ti964_des0ep1: endpoint@1 {
++ ti9x3-addr = <0x0d>;
++ dvp-order = <0>;
++ remote-endpoint = <&ov106xx_in1>;
++ };
++ ti964_des0ep2: endpoint@2 {
++ ti9x3-addr = <0x0e>;
++ dvp-order = <0>;
++ remote-endpoint = <&ov106xx_in2>;
++ };
++ ti964_des0ep3: endpoint@3 {
++ ti9x3-addr = <0x0f>;
++ dvp-order = <0>;
++ remote-endpoint = <&ov106xx_in3>;
++ };
++ };
++ port@1 {
++ ti964_csi0ep0: endpoint {
++ csi-rate = <1450>;
++ remote-endpoint = <&csi2_40_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";
++ };
++ };
++ };
++ };
++};
++
++&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";
++ };
++};
++
++&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 = <&csi2_40_ep>;
++ };
++ };
++ port@2 {
++ vin0_max9286_des0ep0: endpoint@0 {
++ remote-endpoint = <&max9286_des0ep0>;
++ };
++ vin0_ti964_des0ep0: endpoint@1 {
++ remote-endpoint = <&ti964_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>;
++ };
++ vin1_ti964_des0ep1: endpoint@1 {
++ remote-endpoint = <&ti964_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>;
++ };
++ vin2_ti964_des0ep2: endpoint@1 {
++ remote-endpoint = <&ti964_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>;
++ };
++ vin3_ti964_des0ep3: endpoint@1 {
++ remote-endpoint = <&ti964_des0ep3>;
++ };
++ };
++ };
++};
+diff --git a/arch/arm64/boot/dts/renesas/r8a7797-v3msk-view.dts b/arch/arm64/boot/dts/renesas/r8a7797-v3msk-view.dts
+new file mode 100644
+index 0000000..573e2bc
+--- /dev/null
++++ b/arch/arm64/boot/dts/renesas/r8a7797-v3msk-view.dts
+@@ -0,0 +1,298 @@
++/*
++ * 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 "r8a7797-v3msk.dts"
++
++/ {
++ model = "Renesas V3MSK View board based on r8a7797";
++};
++
++&csi2_40 {
++ 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>;
++ };
++ };
++};
++
++&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-max9271@0 {
++ compatible = "maxim,max9286-max9271";
++ reg = <0x6c>;
++ gpios = <&gpio0 9 GPIO_ACTIVE_HIGH>;
++ maxim,sensor_delay = <0>;
++ 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>;
++ };
++ };
++ };
++};
++
++&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 = <&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>;
++ };
++ };
++ };
++};
+diff --git a/arch/arm64/boot/dts/renesas/r8a7797-v3msk.dts b/arch/arm64/boot/dts/renesas/r8a7797-v3msk.dts
+new file mode 100644
+index 0000000..91d10c5
+--- /dev/null
++++ b/arch/arm64/boot/dts/renesas/r8a7797-v3msk.dts
+@@ -0,0 +1,314 @@
++/*
++ * Device Tree Source for the V3M Starter Kit 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.
++ */
++
++/dts-v1/;
++#include "r8a7797.dtsi"
++#include <dt-bindings/gpio/gpio.h>
++
++/ {
++ model = "Renesas V3M Starter Kit board based on r8a7797";
++ compatible = "renesas,v3msk", "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 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";
++ };
++
++ lvds-encoder {
++ compatible = "thine,thc63lvdm83d";
++
++ ports {
++ #address-cells = <1>;
++ #size-cells = <0>;
++
++ port@0 {
++ reg = <0>;
++ lvds_enc_in: endpoint {
++ remote-endpoint = <&du_out_lvds0>;
++ };
++ };
++ port@1 {
++ reg = <1>;
++ lvds_enc_out: endpoint {
++ remote-endpoint = <&lvds_in>;
++ };
++ };
++ };
++ };
++
++ lvds {
++ compatible = "lvds-connector";
++
++ 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 = <&lvds_enc_out>;
++ };
++ };
++ };
++
++ hdmi-out {
++ compatible = "hdmi-connector";
++ type = "a";
++
++ port {
++ hdmi_con: endpoint {
++ remote-endpoint = <&adv7511_out>;
++ };
++ };
++ };
++
++ 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;
++ };
++};
++
++&du {
++ status = "okay";
++
++ ports {
++ port@0 {
++ endpoint {
++ remote-endpoint = <&adv7511_in>;
++// remote-endpoint = <&lvds_in>;
++ };
++ };
++ };
++};
++
++&extal_clk {
++ clock-frequency = <16666666>;
++};
++
++&extalr_clk {
++ clock-frequency = <32768>;
++};
++
++&pfc {
++ pinctrl-0 = <&scif_clk_pins>;
++ pinctrl-names = "default";
++
++ scif0_pins: scif0 {
++ groups = "scif0_data";
++ function = "scif0";
++ };
++
++ scif_clk_pins: scif_clk {
++ groups = "scif_clk_b";
++ function = "scif_clk";
++ };
++
++ i2c0_pins: i2c0 {
++ groups = "i2c0";
++ function = "i2c0";
++ };
++
++ avb_pins: avb {
++ groups = "avb0_mdc";
++ function = "avb0";
++ };
++
++ 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";
++};
++
++&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>;
++
++ 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 = <&lvds_enc_out>;
++ };
++ };
++ port@1 {
++ reg = <1>;
++ adv7511_out: endpoint {
++ remote-endpoint = <&hdmi_con>;
++ };
++ };
++ };
++ };
++};
++
++&wdt0 {
++ status = "okay";
++};
++
++&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>;
++ };
++};
++
++&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";
++};
+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..589a774
+--- /dev/null
++++ b/arch/arm64/boot/dts/renesas/ulcb-kf-cn11.dtsi
+@@ -0,0 +1,545 @@
++/*
++ * 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.
++ */
++
++/ {
++ pwr0B: regulator-pwr0B {
++ compatible = "regulator-fixed";
++ regulator-name = "PWR0B";
++ regulator-min-microvolt = <9000000>;
++ regulator-max-microvolt = <9000000>;
++ gpio = <&gpio_exp_b_5c 8 GPIO_ACTIVE_HIGH>;
++ enable-active-high;
++ };
++
++ pwr1B: regulator-pwr1B {
++ compatible = "regulator-fixed";
++ regulator-name = "PWR1B";
++ regulator-min-microvolt = <9000000>;
++ regulator-max-microvolt = <9000000>;
++ gpio = <&gpio_exp_b_5c 9 GPIO_ACTIVE_HIGH>;
++ enable-active-high;
++ };
++
++ pwr2B: regulator-pwr2B {
++ compatible = "regulator-fixed";
++ regulator-name = "PWR2B";
++ regulator-min-microvolt = <9000000>;
++ regulator-max-microvolt = <9000000>;
++ gpio = <&gpio_exp_b_5c 10 GPIO_ACTIVE_HIGH>;
++ enable-active-high;
++ };
++
++ pwr3B: regulator-pwr3B {
++ compatible = "regulator-fixed";
++ regulator-name = "PWR3B";
++ regulator-min-microvolt = <9000000>;
++ regulator-max-microvolt = <9000000>;
++ gpio = <&gpio_exp_b_5c 11 GPIO_ACTIVE_HIGH>;
++ enable-active-high;
++ };
++};
++
++&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_ti964_des1ep0: endpoint@1 {
++ remote-endpoint = <&ti964_des1ep0>;
++ };
++ ov106xx_ti954_des1ep0: endpoint@2 {
++ remote-endpoint = <&ti954_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_ti964_des1ep1: endpoint@1 {
++ remote-endpoint = <&ti964_des1ep1>;
++ };
++ ov106xx_ti954_des1ep1: endpoint@2 {
++ remote-endpoint = <&ti954_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_ti964_des1ep2: endpoint@1 {
++ remote-endpoint = <&ti964_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_ti964_des1ep3: endpoint@1 {
++ remote-endpoint = <&ti964_des1ep3>;
++ };
++ };
++ };
++
++ /* DS90UB964 @ 0x3a */
++ ti964-ti9x3@1 {
++ compatible = "ti,ti964-ti9x3";
++ reg = <0x3a>;
++ ti,sensor_delay = <350>;
++ ti,links = <4>;
++ ti,lanes = <4>;
++ ti,forwarding-mode = "round-robin";
++ ti,cable-mode = "coax";
++ POC0-supply = <&pwr0B>;
++ POC1-supply = <&pwr1B>;
++ POC2-supply = <&pwr2B>;
++ POC3-supply = <&pwr3B>;
++
++ port@0 {
++ ti964_des1ep0: endpoint@0 {
++ ti9x3-addr = <0x0c>;
++ dvp-order = <0>;
++ remote-endpoint = <&ov106xx_in4>;
++ };
++ ti964_des1ep1: endpoint@1 {
++ ti9x3-addr = <0x0d>;
++ dvp-order = <0>;
++ remote-endpoint = <&ov106xx_in5>;
++ };
++ ti964_des1ep2: endpoint@2 {
++ ti9x3-addr = <0x0e>;
++ dvp-order = <0>;
++ remote-endpoint = <&ov106xx_in6>;
++ };
++ ti964_des1ep3: endpoint@3 {
++ ti9x3-addr = <0x0f>;
++ dvp-order = <0>;
++ remote-endpoint = <&ov106xx_in7>;
++ };
++ };
++ port@1 {
++ ti964_csi2ep0: endpoint {
++ csi-rate = <1450>;
++ remote-endpoint = <&csi2_41_ep>;
++ };
++ };
++ };
++
++ /* DS90UB954 @ 0x38 */
++ ti954-ti9x3@1 {
++ compatible = "ti,ti954-ti9x3";
++ reg = <0x38>;
++ /* gpios = <&video_b_ext1 10 GPIO_ACTIVE_HIGH>; */
++ ti,sensor_delay = <350>;
++ ti,links = <2>;
++ ti,lanes = <4>;
++ ti,forwarding-mode = "round-robin";
++ ti,cable-mode = "coax";
++ POC0-supply = <&pwr0B>;
++ POC1-supply = <&pwr1B>;
++ POC2-supply = <&pwr2B>;
++ POC3-supply = <&pwr3B>;
++
++ port@0 {
++ ti954_des1ep0: endpoint@0 {
++ ti9x3-addr = <0x0c>;
++ dvp-order = <0>;
++ remote-endpoint = <&ov106xx_in4>;
++ };
++ ti954_des1ep1: endpoint@1 {
++ ti9x3-addr = <0x0d>;
++ dvp-order = <0>;
++ remote-endpoint = <&ov106xx_in5>;
++ };
++ };
++ port@1 {
++ ti954_csi2ep0: endpoint {
++ csi-rate = <1450>;
++ remote-endpoint = <&csi2_41_ep>;
++ };
++ };
++ };
++
++ /* MAX9286 @ 0x2c */
++ max9286-max9271@1 {
++ compatible = "maxim,max9286-max9271";
++ reg = <0x2c>;
++ maxim,sensor_delay = <350>;
++ maxim,links = <4>;
++ maxim,lanes = <4>;
++ maxim,resetb-gpio = <1>;
++ maxim,fsync-mode = "automatic";
++ maxim,timeout = <100>;
++ POC0-supply = <&pwr0B>;
++ POC1-supply = <&pwr1B>;
++ POC2-supply = <&pwr2B>;
++ POC3-supply = <&pwr3B>;
++
++ 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 = <&csi2_41_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 = <&csi2_41_ep>;
++ };
++ };
++ port@2 {
++ vin4_max9286_des1ep0: endpoint@0 {
++ remote-endpoint = <&max9286_des1ep0>;
++ };
++ vin4_ti964_des1ep0: endpoint@1 {
++ remote-endpoint = <&ti964_des1ep0>;
++ };
++ vin4_ti954_des1ep0: endpoint@2 {
++ remote-endpoint = <&ti954_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 = <&csi2_41_ep>;
++ };
++ };
++ port@2 {
++ vin5_max9286_des1ep1: endpoint@0 {
++ remote-endpoint = <&max9286_des1ep1>;
++ };
++ vin5_ti964_des1ep1: endpoint@1 {
++ remote-endpoint = <&ti964_des1ep1>;
++ };
++ vin5_ti954_des1ep1: endpoint@2 {
++ remote-endpoint = <&ti954_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 = <&csi2_41_ep>;
++ };
++ };
++ port@2 {
++ vin6_max9286_des1ep2: endpoint@0 {
++ remote-endpoint = <&max9286_des1ep2>;
++ };
++ vin6_ti964_des1ep2: endpoint@1 {
++ remote-endpoint = <&ti964_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 = <&csi2_41_ep>;
++ };
++ };
++ port@2 {
++ vin7_max9286_des1ep3: endpoint@0 {
++ remote-endpoint = <&max9286_des1ep3>;
++ };
++ vin7_ti964_des1ep3: endpoint@1 {
++ remote-endpoint = <&ti964_des1ep3>;
++ };
++ };
++ };
++};
++
++&csi2_41 {
++ 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 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
+new file mode 100644
+index 0000000..5958450
+--- /dev/null
++++ b/arch/arm64/boot/dts/renesas/ulcb-kf.dtsi
+@@ -0,0 +1,1541 @@
++/*
++ * Device Tree Source for the ULCB 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.
++ */
++
++/ {
++ aliases {
++ serial1 = &hscif0;
++ serial2 = &hscif1;
++ serial3 = &scif1;
++ };
++
++ 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_ext_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_ext_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_ext_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_ext_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_ext_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_ext_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_ext_77 15 GPIO_ACTIVE_HIGH>;
++ startup-delay-us = <200000>;
++ enable-active-high;
++ };
++
++ pwr0A: regulator-pwr0A {
++ compatible = "regulator-fixed";
++ regulator-name = "PWR0A";
++ regulator-min-microvolt = <9000000>;
++ regulator-max-microvolt = <9000000>;
++ gpio = <&gpio_exp_a_5c 8 GPIO_ACTIVE_HIGH>;
++ enable-active-high;
++ };
++
++ pwr1A: regulator-pwr1A {
++ compatible = "regulator-fixed";
++ regulator-name = "PWR1A";
++ regulator-min-microvolt = <9000000>;
++ regulator-max-microvolt = <9000000>;
++ gpio = <&gpio_exp_a_5c 9 GPIO_ACTIVE_HIGH>;
++ enable-active-high;
++ };
++
++ pwr2A: regulator-pwr2A {
++ compatible = "regulator-fixed";
++ regulator-name = "PWR2A";
++ regulator-min-microvolt = <9000000>;
++ regulator-max-microvolt = <9000000>;
++ gpio = <&gpio_exp_a_5c 10 GPIO_ACTIVE_HIGH>;
++ enable-active-high;
++ };
++
++ pwr3A: regulator-pwr3A {
++ compatible = "regulator-fixed";
++ regulator-name = "PWR3A";
++ regulator-min-microvolt = <9000000>;
++ regulator-max-microvolt = <9000000>;
++ gpio = <&gpio_exp_a_5c 11 GPIO_ACTIVE_HIGH>;
++ enable-active-high;
++ };
++
++ kim {
++ compatible = "kim";
++ shutdown-gpios = <&gpio_ext_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 = "simple-audio-card";
++
++ simple-audio-card,format = "left_j";
++ simple-audio-card,name = "pcm3168a";
++
++ simple-audio-card,bitclock-master = <&sound_ext_master>;
++ simple-audio-card,frame-master = <&sound_ext_master>;
++ sound_ext_master: simple-audio-card,cpu@0 {
++ sound-dai = <&rcar_sound 0>;
++ dai-tdm-slot-num = <8>;
++ dai-tdm-slot-width = <32>;
++ };
++
++ simple-audio-card,codec@0 {
++ sound-dai = <&pcm3168a>;
++ dai-tdm-slot-num = <8>;
++ dai-tdm-slot-width = <32>;
++ system-clock-frequency = <24576000>;
++ };
++ };
++
++ /delete-node/sound;
++
++ rsnd_ak4613: sound@1 {
++ pinctrl-0 = <&sound_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 1>;
++ };
++
++ sndcodec: simple-audio-card,codec@1 {
++ sound-dai = <&ak4613>;
++ };
++ };
++
++ sound_radio: sound@2 {
++ pinctrl-0 = <&sound_2_pins>;
++ pinctrl-names = "default";
++ compatible = "simple-audio-card";
++
++ simple-audio-card,format = "i2s";
++ simple-audio-card,name = "radio";
++
++ simple-audio-card,bitclock-master = <&sound_radio_master>;
++ simple-audio-card,frame-master = <&sound_radio_master>;
++ simple-audio-card,cpu@2 {
++ sound-dai = <&rcar_sound 2>;
++ };
++
++ sound_radio_master: simple-audio-card,codec@2 {
++ sound-dai = <&radio>;
++ system-clock-frequency = <12288000>;
++ };
++ };
++
++ sound_wl18xx: sound@3 {
++ pinctrl-0 = <&sound_3_pins>;
++ pinctrl-names = "default";
++ compatible = "simple-audio-card";
++
++ simple-audio-card,format = "i2s";
++ simple-audio-card,name = "wl18xx";
++
++ simple-audio-card,bitclock-master = <&sound_wl18xx_master>;
++ simple-audio-card,frame-master = <&sound_wl18xx_master>;
++ sound_wl18xx_master: simple-audio-card,cpu@3 {
++ sound-dai = <&rcar_sound 3>;
++ };
++
++ simple-audio-card,codec@3 {
++ sound-dai = <&wl18xx_pcm>;
++ };
++ };
++
++ lvds-encoder {
++ compatible = "thine,thc63lvdm83d";
++
++ ports {
++ #address-cells = <1>;
++ #size-cells = <0>;
++ port@0 {
++ reg = <0>;
++ lvds_enc_in: endpoint {
++ remote-endpoint = <&du_out_lvds0>;
++ };
++ };
++ port@1 {
++ reg = <1>;
++ lvds_enc_out: endpoint {
++ remote-endpoint = <&lvds_in>;
++ };
++ };
++ };
++ };
++
++ lvds {
++ compatible = "lvds-connector";
++
++ 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 = <&lvds_enc_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";
++
++ #sound-dai-cells = <0>;
++ };
++
++ wl18xx_pcm: wl18xx_pcm@0 {
++ compatible = "ti,wl18xx-pcm";
++ status = "okay";
++
++ #sound-dai-cells = <0>;
++ };
++
++ camera_clk: camera_clk {
++ compatible = "fixed-clock";
++ #clock-cells = <0>;
++ clock-frequency = <24000000>;
++ clock-output-names = "mclk";
++ };
++};
++
++&pfc {
++ scif1_pins: scif1 {
++ groups = "scif1_data_b";
++ function = "scif1";
++ };
++
++ hscif0_pins: hscif0 {
++ groups = "hscif0_data", "hscif0_ctrl";
++ function = "hscif0";
++ };
++
++ hscif1_pins: hscif1 {
++ groups = "hscif1_data_a", "hscif1_ctrl_a";
++ function = "hscif1";
++ };
++
++ du_pins: du {
++ groups = "du_rgb888", "du_sync", "du_clk_out_0", "du_disp";
++ function = "du";
++ };
++
++ 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";
++ };
++
++ 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";
++ };
++
++ vin5_pins: vin5 {
++ groups = "vin5_data8", "vin5_sync", "vin5_clk";
++ function = "vin5";
++ };
++};
++
++&du {
++ pinctrl-0 = <&du_pins>;
++ pinctrl-names = "default";
++};
++
++&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";
++ };
++};
++
++&scif1 {
++ pinctrl-0 = <&scif1_pins>;
++ pinctrl-names = "default";
++
++ status = "okay";
++};
++
++&hscif0 {
++ pinctrl-0 = <&hscif0_pins>;
++ pinctrl-names = "default";
++ uart-has-rtscts;
++
++ status = "okay";
++};
++
++&hscif1 {
++ pinctrl-0 = <&hscif1_pins>;
++ pinctrl-names = "default";
++
++ status = "okay";
++};
++
++&i2c2 {
++ clock-frequency = <400000>;
++
++ gpio_ext_74: pca9539@74 {
++ compatible = "nxp,pca9539";
++ 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>;
++ output-high;
++ line-name = "HUB pwen";
++ };
++ hub_rst {
++ gpio-hog;
++ gpios = <7 GPIO_ACTIVE_HIGH>;
++ output-high;
++ line-name = "HUB rst";
++ };
++ otg_offvbus {
++ gpio-hog;
++ gpios = <8 GPIO_ACTIVE_HIGH>;
++ output-low;
++ line-name = "OTG off VBUSn";
++ };
++ otg_extlpn {
++ gpio-hog;
++ gpios = <9 GPIO_ACTIVE_HIGH>;
++ output-high;
++ line-name = "OTG EXTLPn";
++ };
++ };
++
++ gpio_ext_75: pca9539@75 {
++ compatible = "nxp,pca9539";
++ reg = <0x75>;
++ gpio-controller;
++ #gpio-cells = <2>;
++ 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: pca9548@71 {
++ compatible = "nxp,pca9548";
++ #address-cells = <1>;
++ #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,adv7511w";
++ reg = <0x3d>;
++// interrupt-parent = <&gpio2>;
++// interrupts = <0 IRQ_TYPE_EDGE_BOTH>;
++ pd-gpios = <&gpio_ext_75 5 GPIO_ACTIVE_LOW>;
++
++ adi,input-depth = <8>;
++ adi,input-colorspace = "rgb";
++ adi,input-clock = "1x";
++ adi,input-style = <1>;
++ adi,input-justification = "evenly";
++ adi,clock-delay = <1200>;
++ adi,clock-max-rate = <100000>;
++
++ 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>;
++ };
++
++ lsm9ds0_acc_mag@1d {
++ compatible = "st,lsm9ds0_accel_magn";
++ reg = <0x1d>;
++ };
++
++ lsm9ds0_gyr@6b {
++ compatible = "st,lsm9ds0_gyro";
++ reg = <0x6b>;
++ };
++
++ /* GPS@ 0x42 */
++ };
++ };
++};
++
++&i2c4 {
++ gpio_ext_76: pca9539@76 {
++ compatible = "nxp,pca9539";
++ reg = <0x76>;
++ gpio-controller;
++ #gpio-cells = <2>;
++ 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_ext_77: pca9539@77 {
++ compatible = "nxp,pca9539";
++ reg = <0x77>;
++ gpio-controller;
++ #gpio-cells = <2>;
++ 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: pca9548@71 {
++ compatible = "nxp,pca9548";
++ #address-cells = <1>;
++ #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_ti964_des0ep0: endpoint@1 {
++ remote-endpoint = <&ti964_des0ep0>;
++ };
++ ov106xx_ti954_des0ep0: endpoint@2 {
++ remote-endpoint = <&ti954_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_ti964_des0ep1: endpoint@1 {
++ remote-endpoint = <&ti964_des0ep1>;
++ };
++ ov106xx_ti954_des0ep1: endpoint@2 {
++ remote-endpoint = <&ti954_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_ti964_des0ep2: endpoint@1 {
++ remote-endpoint = <&ti964_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_ti964_des0ep3: endpoint@1 {
++ remote-endpoint = <&ti964_des0ep3>;
++ };
++ };
++ };
++
++ /* DS90UB964 @ 0x3a */
++ ti964-ti9x3@0 {
++ compatible = "ti,ti964-ti9x3";
++ reg = <0x3a>;
++ ti,sensor_delay = <350>;
++ ti,links = <4>;
++ ti,lanes = <4>;
++ ti,forwarding-mode = "round-robin";
++ ti,cable-mode = "coax";
++ POC0-supply = <&pwr0A>;
++ POC1-supply = <&pwr1A>;
++ POC2-supply = <&pwr2A>;
++ POC3-supply = <&pwr3A>;
++
++ port@0 {
++ ti964_des0ep0: endpoint@0 {
++ ti9x3-addr = <0x0c>;
++ dvp-order = <0>;
++ remote-endpoint = <&ov106xx_in0>;
++ };
++ ti964_des0ep1: endpoint@1 {
++ ti9x3-addr = <0x0d>;
++ dvp-order = <0>;
++ remote-endpoint = <&ov106xx_in1>;
++ };
++ ti964_des0ep2: endpoint@2 {
++ ti9x3-addr = <0x0e>;
++ dvp-order = <0>;
++ remote-endpoint = <&ov106xx_in2>;
++ };
++ ti964_des0ep3: endpoint@3 {
++ ti9x3-addr = <0x0f>;
++ dvp-order = <0>;
++ remote-endpoint = <&ov106xx_in3>;
++ };
++ };
++ port@1 {
++ ti964_csi0ep0: endpoint {
++ csi-rate = <1450>;
++ remote-endpoint = <&csi2_40_ep>;
++ };
++ };
++ };
++
++ /* DS90UB954 @ 0x38 */
++ ti954-ti9x3@0 {
++ compatible = "ti,ti954-ti9x3";
++ reg = <0x38>;
++ /* gpios = <&video_a_ext1 10 GPIO_ACTIVE_HIGH>; */
++ ti,sensor_delay = <350>;
++ ti,links = <2>;
++ ti,lanes = <4>;
++ ti,forwarding-mode = "round-robin";
++ ti,cable-mode = "coax";
++ POC0-supply = <&pwr0A>;
++ POC1-supply = <&pwr1A>;
++ POC2-supply = <&pwr2A>;
++ POC3-supply = <&pwr3A>;
++
++ port@0 {
++ ti954_des0ep0: endpoint@0 {
++ ti9x3-addr = <0x0c>;
++ dvp-order = <0>;
++ remote-endpoint = <&ov106xx_in0>;
++ };
++ ti954_des0ep1: endpoint@1 {
++ ti9x3-addr = <0x0d>;
++ dvp-order = <0>;
++ remote-endpoint = <&ov106xx_in1>;
++ };
++ };
++ port@1 {
++ ti954_csi0ep0: endpoint {
++ csi-rate = <1450>;
++ remote-endpoint = <&csi2_40_ep>;
++ };
++ };
++ };
++
++ /* MAX9286 @ 0x2c */
++ max9286-max9271@0 {
++ compatible = "maxim,max9286-max9271";
++ reg = <0x2c>;
++ maxim,sensor_delay = <350>;
++ maxim,links = <4>;
++ maxim,lanes = <4>;
++ maxim,resetb-gpio = <1>;
++ maxim,fsync-mode = "automatic";
++ maxim,timeout = <100>;
++ POC0-supply = <&pwr0A>;
++ POC1-supply = <&pwr1A>;
++ POC2-supply = <&pwr2A>;
++ POC3-supply = <&pwr3A>;
++
++ 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>;
++ };
++ };
++ };
++ };
++
++ 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";
++ };
++ };
++ };
++ };
++};
++
++&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 = <&csi2_40_ep>;
++ };
++ };
++ port@2 {
++ vin0_max9286_des0ep0: endpoint@0 {
++ remote-endpoint = <&max9286_des0ep0>;
++ };
++ vin0_ti964_des0ep0: endpoint@1 {
++ remote-endpoint = <&ti964_des0ep0>;
++ };
++ vin0_ti954_des0ep0: endpoint@2 {
++ remote-endpoint = <&ti954_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>;
++ };
++ vin1_ti964_des0ep1: endpoint@1 {
++ remote-endpoint = <&ti964_des0ep1>;
++ };
++ vin1_ti954_des0ep1: endpoint@2 {
++ remote-endpoint = <&ti954_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>;
++ };
++ vin2_ti964_des0ep2: endpoint@1 {
++ remote-endpoint = <&ti964_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>;
++ };
++ vin3_ti964_des0ep3: endpoint@1 {
++ remote-endpoint = <&ti964_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 = <&csi2_20_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>;
++ };
++ };
++ };
++};
++
++&csi2_40 {
++ 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>;
++ };
++ };
++};
++
++&csi2_20 {
++ status = "okay";
++
++ virtual,channel {
++ csi2_vc0 {
++ data,type = "raw8";
++ receive,vc = <0>;
++ };
++ };
++
++ port {
++ #address-cells = <1>;
++ #size-cells = <0>;
++
++ csi2_20_ep: endpoint {
++ clock-lanes = <0>;
++ data-lanes = <1 2>;
++ csi-rate = <280>;
++ };
++ };
++};
++
++
++&rcar_sound {
++ pinctrl-0 = <&sound_clk_pins>;
++ pinctrl-names = "default";
++
++ /* Multi DAI */
++ #sound-dai-cells = <1>;
++
++ rcar_sound,dai {
++ dai0 {
++ playback = <&ssi3>;
++ capture = <&ssi4>;
++ };
++
++ dai1 {
++ playback = <&ssi0 &src0 &dvc0>;
++ capture = <&ssi1 &src1 &dvc1>;
++ };
++
++ dai2 {
++ capture = <&ssi6>;
++ };
++
++ dai3 {
++ playback = <&ssi7>;
++ capture = <&ssi8>;
++ };
++ };
++};
++
++&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>;
++ };
++};
++
++&usb2_phy0 {
++ pinctrl-0 = <&usb0_pins>;
++ pinctrl-names = "default";
++
++ status = "okay";
++};
++
++&ehci0 {
++ status = "okay";
++};
++
++&ohci0 {
++ status = "okay";
++};
++
++&xhci0 {
++ status = "okay";
++};
++
++&msiof1 {
++ status = "disabled";
++};
++
++&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";
++
++ channel0 {
++ status = "okay";
++ };
++
++ channel1 {
++ status = "okay";
++ };
++};
++
++&ssi4 {
++ shared-pin;
++};
++
++&ssi8 {
++ shared-pin;
++};
++
++&pciec1 {
++ pcie3v3-supply = <&mpcie_3v3>;
++ pcie1v8-supply = <&mpcie_1v8>;
++};
++
+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..92ed4a4
+--- /dev/null
++++ b/arch/arm64/boot/dts/renesas/ulcb-vb-cn12.dtsi
+@@ -0,0 +1,515 @@
++/*
++ * 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_ti964_des2ep0: endpoint@1 {
++ remote-endpoint = <&ti964_des2ep0>;
++ };
++ ov106xx_ti954_des2ep0: endpoint@2 {
++ remote-endpoint = <&ti954_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_ti964_des2ep1: endpoint@1 {
++ remote-endpoint = <&ti964_des2ep1>;
++ };
++ ov106xx_ti954_des2ep1: endpoint@2 {
++ remote-endpoint = <&ti954_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_ti964_des2ep2: endpoint@1 {
++ remote-endpoint = <&ti964_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_ti964_des2ep3: endpoint@1 {
++ remote-endpoint = <&ti964_des2ep3>;
++ };
++ };
++ };
++
++ /* DS90UB964 @ 0x3a */
++ ti964-ti9x3@2 {
++ compatible = "ti,ti964-ti9x3";
++ reg = <0x3a>;
++ ti,sensor_delay = <350>;
++ ti,links = <4>;
++ ti,lanes = <2>;
++ ti,forwarding-mode = "round-robin";
++ ti,cable-mode = "coax";
++
++ port@0 {
++ ti964_des2ep0: endpoint@0 {
++ ti9x3-addr = <0x0c>;
++ dvp-order = <0>;
++ remote-endpoint = <&ov106xx_in8>;
++ };
++ ti964_des2ep1: endpoint@1 {
++ ti9x3-addr = <0x0d>;
++ dvp-order = <0>;
++ remote-endpoint = <&ov106xx_in9>;
++ };
++ ti964_des2ep2: endpoint@2 {
++ ti9x3-addr = <0x0e>;
++ dvp-order = <0>;
++ remote-endpoint = <&ov106xx_in10>;
++ };
++ ti964_des2ep3: endpoint@3 {
++ ti9x3-addr = <0x0f>;
++ dvp-order = <0>;
++ remote-endpoint = <&ov106xx_in11>;
++ };
++ };
++ port@1 {
++ ti964_csi1ep0: endpoint {
++ csi-rate = <1450>;
++ remote-endpoint = <&csi2_20_ep>;
++ };
++ };
++ };
++
++ /* DS90UB954 @ 0x38 */
++ ti954-ti9x3@2 {
++ compatible = "ti,ti954-ti9x3";
++ reg = <0x38>;
++ /* gpios = <&video_c_ext1 10 GPIO_ACTIVE_HIGH>; */
++ ti,sensor_delay = <350>;
++ ti,links = <2>;
++ ti,lanes = <2>;
++ ti,forwarding-mode = "round-robin";
++ ti,cable-mode = "coax";
++
++ port@0 {
++ ti954_des2ep0: endpoint@0 {
++ ti9x3-addr = <0x0c>;
++ dvp-order = <0>;
++ remote-endpoint = <&ov106xx_in8>;
++ };
++ ti954_des2ep1: endpoint@1 {
++ ti9x3-addr = <0x0d>;
++ dvp-order = <0>;
++ remote-endpoint = <&ov106xx_in9>;
++ };
++ };
++ port@1 {
++ ti954_csi1ep0: endpoint {
++ csi-rate = <1450>;
++ remote-endpoint = <&csi2_20_ep>;
++ };
++ };
++ };
++
++ /* MAX9286 @ 0x2c */
++ max9286-max9271@2 {
++ compatible = "maxim,max9286-max9271";
++ reg = <0x2c>;
++ maxim,sensor_delay = <350>;
++ maxim,links = <4>;
++ maxim,lanes = <2>;
++ maxim,resetb-gpio = <1>;
++ maxim,fsync-mode = "automatic";
++ maxim,timeout = <100>;
++
++ 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 = <&csi2_20_ep>;
++ };
++ };
++ };
++ };
++
++ i2c@4 {
++ #address-cells = <1>;
++ #size-cells = <0>;
++ reg = <4>;
++ /* Slot C (CN12) */
++
++ video_c_ext0: pca9535@26 {
++ 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";
++ };
++ };
++
++ video_c_ext1: max7325@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_cam_pwr0 {
++ gpio-hog;
++ gpios = <8 GPIO_ACTIVE_HIGH>;
++ output-high;
++ line-name = "Video-C PWR0";
++ };
++ video_c_cam_pwr1 {
++ gpio-hog;
++ gpios = <9 GPIO_ACTIVE_HIGH>;
++ output-high;
++ line-name = "Video-C PWR1";
++ };
++ video_c_cam_pwr2 {
++ gpio-hog;
++ gpios = <10 GPIO_ACTIVE_HIGH>;
++ output-high;
++ line-name = "Video-C PWR2";
++ };
++ video_c_cam_pwr3 {
++ gpio-hog;
++ gpios = <11 GPIO_ACTIVE_HIGH>;
++ output-high;
++ line-name = "Video-C PWR3";
++ };
++ 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 = <&csi2_20_ep>;
++ };
++ };
++ port@2 {
++ vin4_max9286_des2ep0: endpoint@0 {
++ remote-endpoint = <&max9286_des2ep0>;
++ };
++ vin4_ti964_des2ep0: endpoint@1 {
++ remote-endpoint = <&ti964_des2ep0>;
++ };
++ vin4_ti954_des2ep0: endpoint@2 {
++ remote-endpoint = <&ti954_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 = <&csi2_20_ep>;
++ };
++ };
++ port@2 {
++ vin5_max9286_des2ep1: endpoint@0 {
++ remote-endpoint = <&max9286_des2ep1>;
++ };
++ vin5_ti964_des2ep1: endpoint@1 {
++ remote-endpoint = <&ti964_des2ep1>;
++ };
++ vin5_ti954_des2ep1: endpoint@2 {
++ remote-endpoint = <&ti954_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 = <&csi2_20_ep>;
++ };
++ };
++ port@2 {
++ vin6_max9286_des2ep2: endpoint@0 {
++ remote-endpoint = <&max9286_des2ep2>;
++ };
++ vin6_ti964_des2ep2: endpoint@1 {
++ remote-endpoint = <&ti964_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 = <&csi2_20_ep>;
++ };
++ };
++ port@2 {
++ vin7_max9286_des2ep3: endpoint@0 {
++ remote-endpoint = <&max9286_des2ep3>;
++ };
++ vin7_ti964_des2ep3: endpoint@1 {
++ remote-endpoint = <&ti964_des2ep3>;
++ };
++ };
++ };
++};
++
++&csi2_20 {
++ 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_20_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..193153e
+--- /dev/null
++++ b/arch/arm64/boot/dts/renesas/ulcb-vb.dtsi
+@@ -0,0 +1,1726 @@
++/*
++ * 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-encoder {
++ compatible = "thine,thc63lvdm83d";
++
++ ports {
++ #address-cells = <1>;
++ #size-cells = <0>;
++ port@0 {
++ reg = <0>;
++ lvds_enc_in: endpoint {
++ remote-endpoint = <&du_out_lvds0>;
++ };
++ };
++ port@1 {
++ reg = <1>;
++ lvds_enc_out: endpoint {
++ remote-endpoint = <&lvds_in>;
++ };
++ };
++ };
++ };
++
++ lvds {
++ compatible = "lvds-connector";
++
++ 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 = <&lvds_enc_out>;
++ };
++ };
++ };
++
++ 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_ti964_des0ep0: endpoint@1 {
++ remote-endpoint = <&ti964_des0ep0>;
++ };
++ ov106xx_ti954_des0ep0: endpoint@2 {
++ remote-endpoint = <&ti954_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_ti964_des0ep1: endpoint@1 {
++ remote-endpoint = <&ti964_des0ep1>;
++ };
++ ov106xx_ti954_des0ep1: endpoint@2 {
++ remote-endpoint = <&ti954_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_ti964_des0ep2: endpoint@1 {
++ remote-endpoint = <&ti964_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_ti964_des0ep3: endpoint@1 {
++ remote-endpoint = <&ti964_des0ep3>;
++ };
++ };
++ };
++
++ /* DS90UB964 @ 0x3a */
++ ti964-ti9x3@0 {
++ compatible = "ti,ti964-ti9x3";
++ reg = <0x3a>;
++ ti,sensor_delay = <350>;
++ ti,links = <4>;
++ ti,lanes = <4>;
++ ti,forwarding-mode = "round-robin";
++ ti,cable-mode = "stp";
++
++ port@0 {
++ ti964_des0ep0: endpoint@0 {
++ ti9x3-addr = <0x0c>;
++ dvp-order = <0>;
++ remote-endpoint = <&ov106xx_in0>;
++ };
++ ti964_des0ep1: endpoint@1 {
++ ti9x3-addr = <0x0d>;
++ dvp-order = <0>;
++ remote-endpoint = <&ov106xx_in1>;
++ };
++ ti964_des0ep2: endpoint@2 {
++ ti9x3-addr = <0x0e>;
++ dvp-order = <0>;
++ remote-endpoint = <&ov106xx_in2>;
++ };
++ ti964_des0ep3: endpoint@3 {
++ ti9x3-addr = <0x0f>;
++ dvp-order = <0>;
++ remote-endpoint = <&ov106xx_in3>;
++ };
++ };
++ port@1 {
++ ti964_csi0ep0: endpoint {
++ csi-rate = <1450>;
++ remote-endpoint = <&csi2_40_ep>;
++ };
++ };
++ };
++
++ /* DS90UB954 @ 0x38 */
++ ti954-ti9x3@0 {
++ compatible = "ti,ti954-ti9x3";
++ reg = <0x38>;
++ /* gpios = <&video_a_ext1 10 GPIO_ACTIVE_HIGH>; */
++ ti,sensor_delay = <350>;
++ ti,links = <2>;
++ ti,lanes = <4>;
++ ti,forwarding-mode = "round-robin";
++ ti,cable-mode = "stp";
++
++ port@0 {
++ ti954_des0ep0: endpoint@0 {
++ ti9x3-addr = <0x0c>;
++ dvp-order = <0>;
++ remote-endpoint = <&ov106xx_in0>;
++ };
++ ti954_des0ep1: endpoint@1 {
++ ti9x3-addr = <0x0d>;
++ dvp-order = <0>;
++ remote-endpoint = <&ov106xx_in1>;
++ };
++ };
++ port@1 {
++ ti954_csi0ep0: endpoint {
++ csi-rate = <1450>;
++ remote-endpoint = <&csi2_40_ep>;
++ };
++ };
++ };
++
++ /* MAX9286 @ 0x2c */
++ max9286-max9271@0 {
++ compatible = "maxim,max9286-max9271";
++ reg = <0x2c>;
++ maxim,sensor_delay = <350>;
++ 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>;
++ };
++ };
++ };
++ };
++
++ 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_ti964_des1ep0: endpoint@1 {
++ remote-endpoint = <&ti964_des1ep0>;
++ };
++ ov106xx_ti954_des1ep0: endpoint@2 {
++ remote-endpoint = <&ti954_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_ti964_des1ep1: endpoint@1 {
++ remote-endpoint = <&ti964_des1ep1>;
++ };
++ ov106xx_ti954_des1ep1: endpoint@2 {
++ remote-endpoint = <&ti954_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_ti964_des1ep2: endpoint@1 {
++ remote-endpoint = <&ti964_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_ti964_des1ep3: endpoint@1 {
++ remote-endpoint = <&ti964_des1ep3>;
++ };
++ };
++ };
++
++ /* DS90UB964 @ 0x3a */
++ ti964-ti9x3@1 {
++ compatible = "ti,ti964-ti9x3";
++ reg = <0x3a>;
++ ti,sensor_delay = <350>;
++ ti,links = <4>;
++ ti,lanes = <4>;
++ ti,forwarding-mode = "round-robin";
++ ti,cable-mode = "stp";
++
++ port@0 {
++ ti964_des1ep0: endpoint@0 {
++ ti9x3-addr = <0x0c>;
++ dvp-order = <0>;
++ remote-endpoint = <&ov106xx_in4>;
++ };
++ ti964_des1ep1: endpoint@1 {
++ ti9x3-addr = <0x0d>;
++ dvp-order = <0>;
++ remote-endpoint = <&ov106xx_in5>;
++ };
++ ti964_des1ep2: endpoint@2 {
++ ti9x3-addr = <0x0e>;
++ dvp-order = <0>;
++ remote-endpoint = <&ov106xx_in6>;
++ };
++ ti964_des1ep3: endpoint@3 {
++ ti9x3-addr = <0x0f>;
++ dvp-order = <0>;
++ remote-endpoint = <&ov106xx_in7>;
++ };
++ };
++ port@1 {
++ ti964_csi2ep0: endpoint {
++ csi-rate = <1450>;
++ remote-endpoint = <&csi2_41_ep>;
++ };
++ };
++ };
++
++ /* DS90UB954 @ 0x38 */
++ ti954-ti9x3@1 {
++ compatible = "ti,ti954-ti9x3";
++ reg = <0x38>;
++ /* gpios = <&video_b_ext1 10 GPIO_ACTIVE_HIGH>; */
++ ti,sensor_delay = <350>;
++ ti,links = <2>;
++ ti,lanes = <4>;
++ ti,forwarding-mode = "round-robin";
++ ti,cable-mode = "stp";
++
++ port@0 {
++ ti954_des1ep0: endpoint@0 {
++ ti9x3-addr = <0x0c>;
++ dvp-order = <0>;
++ remote-endpoint = <&ov106xx_in4>;
++ };
++ ti954_des1ep1: endpoint@1 {
++ ti9x3-addr = <0x0d>;
++ dvp-order = <0>;
++ remote-endpoint = <&ov106xx_in5>;
++ };
++ };
++ port@1 {
++ ti954_csi2ep0: endpoint {
++ csi-rate = <1450>;
++ remote-endpoint = <&csi2_41_ep>;
++ };
++ };
++ };
++
++ /* MAX9286 @ 0x2c */
++ max9286-max9271@1 {
++ compatible = "maxim,max9286-max9271";
++ reg = <0x2c>;
++ maxim,sensor_delay = <350>;
++ 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 = <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 = <&csi2_41_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) */
++
++ video_a_ext0: pca9535@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";
++ };
++ };
++
++ video_a_ext1: max7325@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_cam_pwr0 {
++ gpio-hog;
++ gpios = <8 GPIO_ACTIVE_HIGH>;
++ output-high;
++ line-name = "Video-A PWR0";
++ };
++ video_a_cam_pwr1 {
++ gpio-hog;
++ gpios = <9 GPIO_ACTIVE_HIGH>;
++ output-high;
++ line-name = "Video-A PWR1";
++ };
++ video_a_cam_pwr2 {
++ gpio-hog;
++ gpios = <10 GPIO_ACTIVE_HIGH>;
++ output-high;
++ line-name = "Video-A PWR2";
++ };
++ video_a_cam_pwr3 {
++ gpio-hog;
++ gpios = <11 GPIO_ACTIVE_HIGH>;
++ output-high;
++ line-name = "Video-A PWR3";
++ };
++ 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) */
++
++ video_b_ext0: pca9535@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";
++ };
++ };
++
++ video_b_ext1: max7325@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_cam_pwr0 {
++ gpio-hog;
++ gpios = <8 GPIO_ACTIVE_HIGH>;
++ output-high;
++ line-name = "Video-B PWR0";
++ };
++ video_b_cam_pwr1 {
++ gpio-hog;
++ gpios = <9 GPIO_ACTIVE_HIGH>;
++ output-high;
++ line-name = "Video-B PWR1";
++ };
++ video_b_cam_pwr2 {
++ gpio-hog;
++ gpios = <10 GPIO_ACTIVE_HIGH>;
++ output-high;
++ line-name = "Video-B PWR2";
++ };
++ video_b_cam_pwr3 {
++ gpio-hog;
++ gpios = <11 GPIO_ACTIVE_HIGH>;
++ output-high;
++ line-name = "Video-B PWR3";
++ };
++ 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 = <&csi2_40_ep>;
++ };
++ };
++ port@2 {
++ vin0_max9286_des0ep0: endpoint@0 {
++ remote-endpoint = <&max9286_des0ep0>;
++ };
++ vin0_ti964_des0ep0: endpoint@1 {
++ remote-endpoint = <&ti964_des0ep0>;
++ };
++ vin0_ti954_des0ep0: endpoint@2 {
++ remote-endpoint = <&ti954_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>;
++ };
++ vin1_ti964_des0ep1: endpoint@1 {
++ remote-endpoint = <&ti964_des0ep1>;
++ };
++ vin1_ti954_des0ep1: endpoint@2 {
++ remote-endpoint = <&ti954_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>;
++ };
++ vin2_ti964_des0ep2: endpoint@1 {
++ remote-endpoint = <&ti964_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>;
++ };
++ vin3_ti964_des0ep3: endpoint@1 {
++ remote-endpoint = <&ti964_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 = <&csi2_41_ep>;
++ };
++ };
++ port@2 {
++ vin4_max9286_des1ep0: endpoint@0 {
++ remote-endpoint = <&max9286_des1ep0>;
++ };
++ vin4_ti964_des1ep0: endpoint@1 {
++ remote-endpoint = <&ti964_des1ep0>;
++ };
++ vin4_ti954_des1ep0: endpoint@2 {
++ remote-endpoint = <&ti954_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 = <&csi2_41_ep>;
++ };
++ };
++ port@2 {
++ vin5_max9286_des1ep1: endpoint@0 {
++ remote-endpoint = <&max9286_des1ep1>;
++ };
++ vin5_ti964_des1ep1: endpoint@1 {
++ remote-endpoint = <&ti964_des1ep1>;
++ };
++ vin5_ti954_des1ep1: endpoint@2 {
++ remote-endpoint = <&ti954_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 = <&csi2_41_ep>;
++ };
++ };
++ port@2 {
++ vin6_max9286_des1ep2: endpoint@0 {
++ remote-endpoint = <&max9286_des1ep2>;
++ };
++ vin6_ti964_des1ep2: endpoint@1 {
++ remote-endpoint = <&ti964_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 = <&csi2_41_ep>;
++ };
++ };
++ port@2 {
++ vin7_max9286_des1ep3: endpoint@0 {
++ remote-endpoint = <&max9286_des1ep3>;
++ };
++ vin7_ti964_des1ep3: endpoint@1 {
++ remote-endpoint = <&ti964_des1ep3>;
++ };
++ };
++ };
++};
++
++&csi2_40 {
++ 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>;
++ };
++ };
++};
++
++&csi2_41 {
++ 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 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-vbm.dtsi b/arch/arm64/boot/dts/renesas/ulcb-vbm.dtsi
+new file mode 100644
+index 0000000..beb52e9
+--- /dev/null
++++ b/arch/arm64/boot/dts/renesas/ulcb-vbm.dtsi
+@@ -0,0 +1,578 @@
++/*
++ * 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;
++ };
++
++ pwr0: regulator-pwr0 {
++ compatible = "regulator-fixed";
++ regulator-name = "PWR0";
++ regulator-min-microvolt = <9000000>;
++ regulator-max-microvolt = <9000000>;
++ gpio = <&gpio_exp_6c 8 GPIO_ACTIVE_HIGH>;
++ enable-active-high;
++ };
++
++ pwr1: regulator-pwr1 {
++ compatible = "regulator-fixed";
++ regulator-name = "PWR1";
++ regulator-min-microvolt = <9000000>;
++ regulator-max-microvolt = <9000000>;
++ gpio = <&gpio_exp_6c 9 GPIO_ACTIVE_HIGH>;
++ enable-active-high;
++ };
++
++ pwr2: regulator-pwr2 {
++ compatible = "regulator-fixed";
++ regulator-name = "PWR2";
++ regulator-min-microvolt = <9000000>;
++ regulator-max-microvolt = <9000000>;
++ gpio = <&gpio_exp_6c 10 GPIO_ACTIVE_HIGH>;
++ enable-active-high;
++ };
++
++ pwr3: regulator-pwr3 {
++ compatible = "regulator-fixed";
++ regulator-name = "PWR3";
++ regulator-min-microvolt = <9000000>;
++ regulator-max-microvolt = <9000000>;
++ gpio = <&gpio_exp_6c 11 GPIO_ACTIVE_HIGH>;
++ enable-active-high;
++ };
++
++ lvds-encoder {
++ compatible = "thine,thc63lvdm83d";
++
++ ports {
++ #address-cells = <1>;
++ #size-cells = <0>;
++
++ port@0 {
++ reg = <0>;
++ lvds_enc_in: endpoint {
++ remote-endpoint = <&du_out_lvds0>;
++ };
++ };
++ port@1 {
++ reg = <1>;
++ lvds_enc_out: endpoint {
++ remote-endpoint = <&lvds_in>;
++ };
++ };
++ };
++ };
++
++ lvds {
++ compatible = "lvds-connector";
++
++ 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 = <&lvds_enc_out>;
++ };
++ };
++ };
++};
++
++&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";
++ };
++};
++
++&csi2_41 {
++ 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 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_ti964_des0ep0: endpoint@1 {
++ remote-endpoint = <&ti964_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_ti964_des0ep1: endpoint@1 {
++ remote-endpoint = <&ti964_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_ti964_des0ep2: endpoint@1 {
++ remote-endpoint = <&ti964_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_ti964_des0ep3: endpoint@1 {
++ remote-endpoint = <&ti964_des0ep3>;
++ };
++ };
++ };
++
++ max9286-max9271@0 {
++ compatible = "maxim,max9286-max9271";
++ reg = <0x2c>;
++ maxim,sensor_delay = <350>;
++ maxim,links = <4>;
++ maxim,lanes = <4>;
++ maxim,resetb-gpio = <1>;
++ maxim,fsync-mode = "automatic";
++ maxim,timeout = <100>;
++ POC0-supply = <&pwr0>;
++ POC1-supply = <&pwr1>;
++ POC2-supply = <&pwr2>;
++ POC3-supply = <&pwr3>;
++
++ 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_41_ep>;
++ };
++ };
++ };
++
++ ti964-ti9x3@0 {
++ compatible = "ti,ti964-ti9x3";
++ reg = <0x3a>;
++ ti,sensor_delay = <350>;
++ ti,links = <4>;
++ ti,lanes = <4>;
++ ti,forwarding-mode = "round-robin";
++ ti,cable-mode = "coax";
++ POC0-supply = <&pwr0>;
++ POC1-supply = <&pwr1>;
++ POC2-supply = <&pwr2>;
++ POC3-supply = <&pwr3>;
++
++ port@0 {
++ ti964_des0ep0: endpoint@0 {
++ ti9x3-addr = <0x0c>;
++ dvp-order = <0>;
++ remote-endpoint = <&ov106xx_in0>;
++ };
++ ti964_des0ep1: endpoint@1 {
++ ti9x3-addr = <0x0d>;
++ dvp-order = <0>;
++ remote-endpoint = <&ov106xx_in1>;
++ };
++ ti964_des0ep2: endpoint@2 {
++ ti9x3-addr = <0x0e>;
++ dvp-order = <0>;
++ remote-endpoint = <&ov106xx_in2>;
++ };
++ ti964_des0ep3: endpoint@3 {
++ ti9x3-addr = <0x0f>;
++ dvp-order = <0>;
++ remote-endpoint = <&ov106xx_in3>;
++ };
++ };
++ port@1 {
++ ti964_csi0ep0: endpoint {
++ csi-rate = <1450>;
++ remote-endpoint = <&csi2_41_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 = <&csi2_41_ep>;
++ };
++ };
++ port@2 {
++ vin4_max9286_des0ep0: endpoint@0 {
++ remote-endpoint = <&max9286_des0ep0>;
++ };
++ vin4_ti964_des0ep0: endpoint@1 {
++ remote-endpoint = <&ti964_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 = <&csi2_41_ep>;
++ };
++ };
++ port@2 {
++ vin5_max9286_des0ep1: endpoint@0 {
++ remote-endpoint = <&max9286_des0ep1>;
++ };
++ vin5_ti964_des0ep1: endpoint@1 {
++ remote-endpoint = <&ti964_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 = <&csi2_41_ep>;
++ };
++ };
++ port@2 {
++ vin6_max9286_des0ep2: endpoint@0 {
++ remote-endpoint = <&max9286_des0ep2>;
++ };
++ vin6_ti964_des0ep2: endpoint@1 {
++ remote-endpoint = <&ti964_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 = <&csi2_41_ep>;
++ };
++ };
++ port@2 {
++ vin7_max9286_des0ep3: endpoint@0 {
++ remote-endpoint = <&max9286_des0ep3>;
++ };
++ vin7_ti964_des0ep3: endpoint@1 {
++ remote-endpoint = <&ti964_des0ep3>;
++ };
++ };
++ };
++};
++
+--
+1.9.1
+
diff --git a/meta-rcar-gen3-adas/recipes-kernel/linux/linux-renesas/0041-arm64-dts-renesas-ulcb-enlarge-cma-region.patch b/meta-rcar-gen3-adas/recipes-kernel/linux/linux-renesas/0041-arm64-dts-renesas-ulcb-enlarge-cma-region.patch
new file mode 100644
index 0000000..755317b
--- /dev/null
+++ b/meta-rcar-gen3-adas/recipes-kernel/linux/linux-renesas/0041-arm64-dts-renesas-ulcb-enlarge-cma-region.patch
@@ -0,0 +1,56 @@
+From 0636358bc75e9d5187515ee99d7c8d490c56bd52 Mon Sep 17 00:00:00 2001
+From: Vladimir Barinov <vladimir.barinov@cogentembedded.com>
+Date: Sat, 15 Jul 2017 00:41:49 +0300
+Subject: [PATCH] arm64: dts: renesas: ulcb: enlarge cma region
+
+Enlarge cma region since ADSP is not used on ulcb
+
+Signed-off-by: Vladimir Barinov <vladimir.barinov@cogentembedded.com>
+---
+ arch/arm64/boot/dts/renesas/r8a7795-es1-h3ulcb.dts | 2 +-
+ arch/arm64/boot/dts/renesas/r8a7795-h3ulcb.dts | 2 +-
+ arch/arm64/boot/dts/renesas/r8a7796-m3ulcb.dts | 2 +-
+ 3 files changed, 3 insertions(+), 3 deletions(-)
+
+diff --git a/arch/arm64/boot/dts/renesas/r8a7795-es1-h3ulcb.dts b/arch/arm64/boot/dts/renesas/r8a7795-es1-h3ulcb.dts
+index 1ba7a22..9d83c6c 100644
+--- a/arch/arm64/boot/dts/renesas/r8a7795-es1-h3ulcb.dts
++++ b/arch/arm64/boot/dts/renesas/r8a7795-es1-h3ulcb.dts
+@@ -63,7 +63,7 @@
+ linux,cma {
+ compatible = "shared-dma-pool";
+ reusable;
+- reg = <0x00000000 0x58000000 0x0 0x18000000>;
++ reg = <0x00000000 0x57000000 0x0 0x19000000>;
+ linux,cma-default;
+ };
+
+diff --git a/arch/arm64/boot/dts/renesas/r8a7795-h3ulcb.dts b/arch/arm64/boot/dts/renesas/r8a7795-h3ulcb.dts
+index c237888..7406534 100644
+--- a/arch/arm64/boot/dts/renesas/r8a7795-h3ulcb.dts
++++ b/arch/arm64/boot/dts/renesas/r8a7795-h3ulcb.dts
+@@ -63,7 +63,7 @@
+ linux,cma {
+ compatible = "shared-dma-pool";
+ reusable;
+- reg = <0x00000000 0x58000000 0x0 0x18000000>;
++ reg = <0x00000000 0x57000000 0x0 0x19000000>;
+ linux,cma-default;
+ };
+
+diff --git a/arch/arm64/boot/dts/renesas/r8a7796-m3ulcb.dts b/arch/arm64/boot/dts/renesas/r8a7796-m3ulcb.dts
+index b3ecbd3..9aa4292 100644
+--- a/arch/arm64/boot/dts/renesas/r8a7796-m3ulcb.dts
++++ b/arch/arm64/boot/dts/renesas/r8a7796-m3ulcb.dts
+@@ -53,7 +53,7 @@
+ linux,cma {
+ compatible = "shared-dma-pool";
+ reusable;
+- reg = <0x00000000 0x58000000 0x0 0x18000000>;
++ reg = <0x00000000 0x57000000 0x0 0x19000000>;
+ linux,cma-default;
+ };
+
+--
+1.9.1
+
diff --git a/meta-rcar-gen3-adas/recipes-kernel/linux/linux-renesas/0042-arm64-dts-renesas-r8a7795-es1-h3ulcb-disable-eMMC.patch b/meta-rcar-gen3-adas/recipes-kernel/linux/linux-renesas/0042-arm64-dts-renesas-r8a7795-es1-h3ulcb-disable-eMMC.patch
new file mode 100644
index 0000000..1146a09
--- /dev/null
+++ b/meta-rcar-gen3-adas/recipes-kernel/linux/linux-renesas/0042-arm64-dts-renesas-r8a7795-es1-h3ulcb-disable-eMMC.patch
@@ -0,0 +1,28 @@
+From 7440eb1bd8d9fdd197664086d67c540495832620 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] 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 | 2 +-
+ 1 file changed, 1 insertion(+), 1 deletion(-)
+
+diff --git a/arch/arm64/boot/dts/renesas/r8a7795-es1-h3ulcb.dts b/arch/arm64/boot/dts/renesas/r8a7795-es1-h3ulcb.dts
+index 9d83c6c..677bf88 100644
+--- a/arch/arm64/boot/dts/renesas/r8a7795-es1-h3ulcb.dts
++++ b/arch/arm64/boot/dts/renesas/r8a7795-es1-h3ulcb.dts
+@@ -458,7 +458,7 @@
+ mmc-hs200-1_8v;
+ bus-width = <8>;
+ non-removable;
+- status = "okay";
++ status = "disabled";
+ };
+
+ &ssi1 {
+--
+1.9.1
+
diff --git a/meta-rcar-gen3-adas/recipes-kernel/linux/linux-renesas/0043-arm64-dts-renesas-ulcb-use-versaclock-for-du-rgb-and-lvds.patch b/meta-rcar-gen3-adas/recipes-kernel/linux/linux-renesas/0043-arm64-dts-renesas-ulcb-use-versaclock-for-du-rgb-and-lvds.patch
new file mode 100644
index 0000000..1298ba8
--- /dev/null
+++ b/meta-rcar-gen3-adas/recipes-kernel/linux/linux-renesas/0043-arm64-dts-renesas-ulcb-use-versaclock-for-du-rgb-and-lvds.patch
@@ -0,0 +1,143 @@
+From 29bcecbb93b009e650dfdf9e6a1ff6efadc871bc Mon Sep 17 00:00:00 2001
+From: Vladimir Barinov <vladimir.barinov@cogentembedded.com>
+Date: Thu, 10 Aug 2017 08:41:53 +0300
+Subject: [PATCH] arm64: dts: renesas: ulcb: use versaclock for DU RGB and LVDS
+
+This allows to chgange preprogrammed clock in Versa5 clock
+generator.
+DU has PLL that is not too accurate, hence use prescaled value by VC5.
+
+[200~Signed-off-by: Vladimir Barinov <vladimir.barinov@cogentembedded.com>
+---
+ arch/arm64/boot/dts/renesas/r8a7795-es1-h3ulcb.dts | 24 ++++++++++++++++++++++
+ arch/arm64/boot/dts/renesas/r8a7795-h3ulcb.dts | 24 ++++++++++++++++++++++
+ arch/arm64/boot/dts/renesas/r8a7796-m3ulcb.dts | 22 ++++++++++++++++++++
+ 3 files changed, 70 insertions(+)
+
+diff --git a/arch/arm64/boot/dts/renesas/r8a7795-es1-h3ulcb.dts b/arch/arm64/boot/dts/renesas/r8a7795-es1-h3ulcb.dts
+index 677bf88..6fe4416 100644
+--- a/arch/arm64/boot/dts/renesas/r8a7795-es1-h3ulcb.dts
++++ b/arch/arm64/boot/dts/renesas/r8a7795-es1-h3ulcb.dts
+@@ -229,6 +229,15 @@
+ &du {
+ status = "okay";
+
++ /* update <du_dotclkin0/3> to <programable_clk0/1> */
++ clocks = <&cpg CPG_MOD 724>,
++ <&cpg CPG_MOD 723>,
++ <&cpg CPG_MOD 722>,
++ <&cpg CPG_MOD 721>,
++ <&cpg CPG_MOD 727>,
++ <&programmable_clk0>, <&du_dotclkin1>, <&du_dotclkin2>,
++ <&programmable_clk1>;
++
+ ports {
+ port@1 {
+ endpoint {
+@@ -390,6 +399,21 @@
+ status = "okay";
+
+ clock-frequency = <400000>;
++
++ clk_5p49v5925: programmable_clk@6a {
++ compatible = "idt,5p49v5925";
++ reg = <0x6a>;
++
++ programmable_clk0: 5p49x_clk1@6a {
++ #clock-cells = <0>;
++ clocks = <&du_dotclkin0>;
++ };
++
++ programmable_clk1: 5p49x_clk2@6a {
++ #clock-cells = <0>;
++ clocks = <&du_dotclkin3>;
++ };
++ };
+ };
+
+ &rcar_sound {
+diff --git a/arch/arm64/boot/dts/renesas/r8a7795-h3ulcb.dts b/arch/arm64/boot/dts/renesas/r8a7795-h3ulcb.dts
+index 7406534..e018f21 100644
+--- a/arch/arm64/boot/dts/renesas/r8a7795-h3ulcb.dts
++++ b/arch/arm64/boot/dts/renesas/r8a7795-h3ulcb.dts
+@@ -229,6 +229,15 @@
+ &du {
+ status = "okay";
+
++ /* update <du_dotclkin0/3> to <programable_clk0/1> */
++ clocks = <&cpg CPG_MOD 724>,
++ <&cpg CPG_MOD 723>,
++ <&cpg CPG_MOD 722>,
++ <&cpg CPG_MOD 721>,
++ <&cpg CPG_MOD 727>,
++ <&programmable_clk0>, <&du_dotclkin1>, <&du_dotclkin2>,
++ <&programmable_clk1>;
++
+ ports {
+ port@1 {
+ endpoint {
+@@ -390,6 +399,21 @@
+ status = "okay";
+
+ clock-frequency = <400000>;
++
++ clk_5p49v5925: programmable_clk@6a {
++ compatible = "idt,5p49v5925";
++ reg = <0x6a>;
++
++ programmable_clk0: 5p49x_clk1@6a {
++ #clock-cells = <0>;
++ clocks = <&du_dotclkin0>;
++ };
++
++ programmable_clk1: 5p49x_clk2@6a {
++ #clock-cells = <0>;
++ clocks = <&du_dotclkin3>;
++ };
++ };
+ };
+
+ &rcar_sound {
+diff --git a/arch/arm64/boot/dts/renesas/r8a7796-m3ulcb.dts b/arch/arm64/boot/dts/renesas/r8a7796-m3ulcb.dts
+index 9aa4292..130c068 100644
+--- a/arch/arm64/boot/dts/renesas/r8a7796-m3ulcb.dts
++++ b/arch/arm64/boot/dts/renesas/r8a7796-m3ulcb.dts
+@@ -312,6 +312,13 @@
+ &du {
+ status = "okay";
+
++ /* update <du_dotclkin0/2> to <programable_clk0/1> */
++ clocks = <&cpg CPG_MOD 724>,
++ <&cpg CPG_MOD 723>,
++ <&cpg CPG_MOD 722>,
++ <&cpg CPG_MOD 727>,
++ <&programmable_clk0>, <&du_dotclkin1>, <&programmable_clk1>;
++
+ ports {
+ port@1 {
+ endpoint {
+@@ -422,6 +429,21 @@
+ &i2c4 {
+ status = "okay";
+ clock-frequency = <400000>;
++
++ clk_5p49v5925: programmable_clk@6a {
++ compatible = "idt,5p49v5925";
++ reg = <0x6a>;
++
++ programmable_clk0: 5p49x_clk1@6a {
++ #clock-cells = <0>;
++ clocks = <&du_dotclkin0>;
++ };
++
++ programmable_clk1: 5p49x_clk2@6a {
++ #clock-cells = <0>;
++ clocks = <&du_dotclkin2>;
++ };
++ };
+ };
+
+ &rcar_sound {
+--
+1.9.1
+
diff --git a/meta-rcar-gen3-adas/recipes-kernel/linux/linux-renesas/0044-pinctrl-r8a779x-add-mlb-pinmux.patch b/meta-rcar-gen3-adas/recipes-kernel/linux/linux-renesas/0044-pinctrl-r8a779x-add-mlb-pinmux.patch
new file mode 100644
index 0000000..8541e19
--- /dev/null
+++ b/meta-rcar-gen3-adas/recipes-kernel/linux/linux-renesas/0044-pinctrl-r8a779x-add-mlb-pinmux.patch
@@ -0,0 +1,154 @@
+From 7f797fef45307ed6c5960cc116ce8de65d192269 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] 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 378065d..f544546 100644
+--- a/drivers/pinctrl/sh-pfc/pfc-r8a7795-es1.c
++++ b/drivers/pinctrl/sh-pfc/pfc-r8a7795-es1.c
+@@ -2403,6 +2403,14 @@ enum {
+ 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 */
+@@ -4266,6 +4274,7 @@ enum {
+ 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),
+@@ -4682,6 +4691,10 @@ enum {
+ "intc_ex_irq5",
+ };
+
++static const char * const mlb_3pin_groups[] = {
++ "mlb_3pin",
++};
++
+ static const char * const msiof0_groups[] = {
+ "msiof0_clk",
+ "msiof0_sync",
+@@ -5032,6 +5045,7 @@ enum {
+ 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 1198998..928bbbc 100644
+--- a/drivers/pinctrl/sh-pfc/pfc-r8a7795.c
++++ b/drivers/pinctrl/sh-pfc/pfc-r8a7795.c
+@@ -2466,6 +2466,14 @@ enum {
+ 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 */
+@@ -4387,6 +4395,7 @@ enum {
+ 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),
+@@ -4811,6 +4820,10 @@ enum {
+ "intc_ex_irq5",
+ };
+
++static const char * const mlb_3pin_groups[] = {
++ "mlb_3pin",
++};
++
+ static const char * const msiof0_groups[] = {
+ "msiof0_clk",
+ "msiof0_sync",
+@@ -5169,6 +5182,7 @@ enum {
+ 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 1cef61b..26a69dc 100644
+--- a/drivers/pinctrl/sh-pfc/pfc-r8a7796.c
++++ b/drivers/pinctrl/sh-pfc/pfc-r8a7796.c
+@@ -2468,6 +2468,14 @@ enum {
+ 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 */
+@@ -4310,6 +4318,7 @@ enum {
+ 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),
+@@ -4722,6 +4731,10 @@ enum {
+ "intc_ex_irq5",
+ };
+
++static const char * const mlb_3pin_groups[] = {
++ "mlb_3pin",
++};
++
+ static const char * const msiof0_groups[] = {
+ "msiof0_clk",
+ "msiof0_sync",
+@@ -5054,6 +5067,7 @@ enum {
+ 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),
+--
+1.9.1
+
diff --git a/meta-rcar-gen3-adas/recipes-kernel/linux/linux-renesas/0045-clk-r8a779x-add-mlp-clock.patch b/meta-rcar-gen3-adas/recipes-kernel/linux/linux-renesas/0045-clk-r8a779x-add-mlp-clock.patch
new file mode 100644
index 0000000..ca473a1
--- /dev/null
+++ b/meta-rcar-gen3-adas/recipes-kernel/linux/linux-renesas/0045-clk-r8a779x-add-mlp-clock.patch
@@ -0,0 +1,38 @@
+From 741e7fcf44527632a06538419f000843b24d9293 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] 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 f833031..38d1f41 100644
+--- a/drivers/clk/renesas/r8a7795-cpg-mssr.c
++++ b/drivers/clk/renesas/r8a7795-cpg-mssr.c
+@@ -219,6 +219,7 @@ enum clk_ids {
+ 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 b938750..6a5936e 100644
+--- a/drivers/clk/renesas/r8a7796-cpg-mssr.c
++++ b/drivers/clk/renesas/r8a7796-cpg-mssr.c
+@@ -194,6 +194,7 @@ enum clk_ids {
+ 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),
+--
+1.9.1
+
diff --git a/meta-rcar-gen3-adas/recipes-kernel/linux/linux-renesas/0046-arm64-dts-renesas-r8a779x-add-mlp-nodes.patch b/meta-rcar-gen3-adas/recipes-kernel/linux/linux-renesas/0046-arm64-dts-renesas-r8a779x-add-mlp-nodes.patch
new file mode 100644
index 0000000..1f17f0e
--- /dev/null
+++ b/meta-rcar-gen3-adas/recipes-kernel/linux/linux-renesas/0046-arm64-dts-renesas-r8a779x-add-mlp-nodes.patch
@@ -0,0 +1,87 @@
+From 8d5de721b2e037ce77f886a4307ea5668df9417f 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] arm64: dts: renesas: r8a779x: add mlp nodes
+
+Signed-off-by: Andrey Gusakov <andrey.gusakov@cogentembedded.com>
+---
+ arch/arm64/boot/dts/renesas/r8a7795-es1.dtsi | 13 +++++++++++++
+ arch/arm64/boot/dts/renesas/r8a7795.dtsi | 13 +++++++++++++
+ arch/arm64/boot/dts/renesas/r8a7796.dtsi | 13 +++++++++++++
+ 3 files changed, 39 insertions(+)
+
+diff --git a/arch/arm64/boot/dts/renesas/r8a7795-es1.dtsi b/arch/arm64/boot/dts/renesas/r8a7795-es1.dtsi
+index 89c70bb7738b..44a290b32899 100644
+--- a/arch/arm64/boot/dts/renesas/r8a7795-es1.dtsi
++++ b/arch/arm64/boot/dts/renesas/r8a7795-es1.dtsi
+@@ -2072,6 +2072,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 {
+ #address-cells = <1>;
+ #size-cells = <0>;
+diff --git a/arch/arm64/boot/dts/renesas/r8a7795.dtsi b/arch/arm64/boot/dts/renesas/r8a7795.dtsi
+index 89c70bb7738b..44a290b32899 100644
+--- a/arch/arm64/boot/dts/renesas/r8a7795.dtsi
++++ b/arch/arm64/boot/dts/renesas/r8a7795.dtsi
+@@ -2072,6 +2072,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 {
+ #address-cells = <1>;
+ #size-cells = <0>;
+diff --git a/arch/arm64/boot/dts/renesas/r8a7796.dtsi b/arch/arm64/boot/dts/renesas/r8a7796.dtsi
+index f430df9df961..565d6e7de4cc 100644
+--- a/arch/arm64/boot/dts/renesas/r8a7796.dtsi
++++ b/arch/arm64/boot/dts/renesas/r8a7796.dtsi
+@@ -1955,6 +1955,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";
+ reg = <0 0xe6ea0000 0 0x0064>;
+--
+2.13.0
+
diff --git a/meta-rcar-gen3-adas/recipes-kernel/linux/linux-renesas/0047-arm64-dts-renesas-ulcb-kf-enable-sd3.patch b/meta-rcar-gen3-adas/recipes-kernel/linux/linux-renesas/0047-arm64-dts-renesas-ulcb-kf-enable-sd3.patch
new file mode 100644
index 0000000..81b3dc9
--- /dev/null
+++ b/meta-rcar-gen3-adas/recipes-kernel/linux/linux-renesas/0047-arm64-dts-renesas-ulcb-kf-enable-sd3.patch
@@ -0,0 +1,28 @@
+From a5eed343caa82837c72a2c0e3d53f4db0c5944e4 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] 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 8ffafb2..ea6cb1b 100644
+--- a/arch/arm64/boot/dts/renesas/ulcb-kf.dtsi
++++ b/arch/arm64/boot/dts/renesas/ulcb-kf.dtsi
+@@ -1527,3 +1527,8 @@
+
+
+
++/* enable CN47: SD on SDHI3 */
++#include "ulcb-kf-sd3.dtsi"
++
++
++
+--
+1.9.1
+
diff --git a/meta-rcar-gen3-adas/recipes-kernel/linux/linux-renesas/0048-arm64-dts-renesas-ulcb-kf-enable-most.patch b/meta-rcar-gen3-adas/recipes-kernel/linux/linux-renesas/0048-arm64-dts-renesas-ulcb-kf-enable-most.patch
new file mode 100644
index 0000000..37ad738
--- /dev/null
+++ b/meta-rcar-gen3-adas/recipes-kernel/linux/linux-renesas/0048-arm64-dts-renesas-ulcb-kf-enable-most.patch
@@ -0,0 +1,28 @@
+From ab803d3c36d8444948c7eec238c19926fd036fcc 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] 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 ea6cb1b..ddd5450 100644
+--- a/arch/arm64/boot/dts/renesas/ulcb-kf.dtsi
++++ b/arch/arm64/boot/dts/renesas/ulcb-kf.dtsi
+@@ -1532,3 +1532,8 @@
+
+
+
++/* enable CN22: enable MOST and disable GPS (move R661->R660, R663->R662) */
++#include "ulcb-kf-most.dtsi"
++
++
++
+--
+1.9.1
+
diff --git a/meta-rcar-gen3-adas/recipes-kernel/linux/linux-renesas/0049-clk-r8a779x-add-IMP-clock.patch b/meta-rcar-gen3-adas/recipes-kernel/linux/linux-renesas/0049-clk-r8a779x-add-IMP-clock.patch
new file mode 100644
index 0000000..a7cf942
--- /dev/null
+++ b/meta-rcar-gen3-adas/recipes-kernel/linux/linux-renesas/0049-clk-r8a779x-add-IMP-clock.patch
@@ -0,0 +1,59 @@
+From 9075957822c829026acfb5e8982a77f895a7a640 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] 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 +
+ drivers/clk/renesas/r8a7797-cpg-mssr.c | 7 +++++++
+ 3 files changed, 9 insertions(+)
+
+diff --git a/drivers/clk/renesas/r8a7795-cpg-mssr.c b/drivers/clk/renesas/r8a7795-cpg-mssr.c
+index bc10df3..9061f7f 100644
+--- a/drivers/clk/renesas/r8a7795-cpg-mssr.c
++++ b/drivers/clk/renesas/r8a7795-cpg-mssr.c
+@@ -234,6 +234,7 @@ enum clk_ids {
+ DEF_MOD("imr2", 821, R8A7795_CLK_S2D1),
+ DEF_MOD("imr1", 822, R8A7795_CLK_S2D1),
+ DEF_MOD("imr0", 823, R8A7795_CLK_S2D1),
++ 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 819d3c6..e886d8a 100644
+--- a/drivers/clk/renesas/r8a7796-cpg-mssr.c
++++ b/drivers/clk/renesas/r8a7796-cpg-mssr.c
+@@ -204,6 +204,7 @@ enum clk_ids {
+ DEF_MOD("vin1", 810, R8A7796_CLK_S0D2),
+ DEF_MOD("vin0", 811, R8A7796_CLK_S0D2),
+ DEF_MOD("etheravb", 812, R8A7796_CLK_S0D6),
++ 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),
+diff --git a/drivers/clk/renesas/r8a7797-cpg-mssr.c b/drivers/clk/renesas/r8a7797-cpg-mssr.c
+index 29dfe4a..6655592 100644
+--- a/drivers/clk/renesas/r8a7797-cpg-mssr.c
++++ b/drivers/clk/renesas/r8a7797-cpg-mssr.c
+@@ -129,6 +129,13 @@ enum clk_ids {
+ DEF_MOD("imr2", 821, R8A7797_CLK_S2D1),
+ DEF_MOD("imr1", 822, R8A7797_CLK_S2D1),
+ DEF_MOD("imr0", 823, R8A7797_CLK_S2D1),
++ DEF_MOD("imp3", 824, R8A7797_CLK_S1D1),
++ DEF_MOD("imp2", 825, R8A7797_CLK_S1D1),
++ DEF_MOD("imp1", 826, R8A7797_CLK_S1D1),
++ DEF_MOD("imp0", 827, R8A7797_CLK_S1D1),
++ DEF_MOD("imp-ocv1", 828, R8A7797_CLK_S1D1),
++ DEF_MOD("imp-ocv0", 829, R8A7797_CLK_S1D1),
++ DEF_MOD("impram", 830, R8A7797_CLK_S1D1),
+ DEF_MOD("gpio5", 907, R8A7797_CLK_CP),
+ DEF_MOD("gpio4", 908, R8A7797_CLK_CP),
+ DEF_MOD("gpio3", 909, R8A7797_CLK_CP),
+--
+1.9.1
+
diff --git a/meta-rcar-gen3-adas/recipes-kernel/linux/linux-renesas/0050-arm64-dts-Gen3-view-boards-TYPE1-first-4-cameras.patch b/meta-rcar-gen3-adas/recipes-kernel/linux/linux-renesas/0050-arm64-dts-Gen3-view-boards-TYPE1-first-4-cameras.patch
new file mode 100644
index 0000000..d368b6a
--- /dev/null
+++ b/meta-rcar-gen3-adas/recipes-kernel/linux/linux-renesas/0050-arm64-dts-Gen3-view-boards-TYPE1-first-4-cameras.patch
@@ -0,0 +1,302 @@
+From 67d29f4fe320f555366ea45f5439ac52641472ec Mon Sep 17 00:00:00 2001
+From: Vladimir Barinov <vladimir.barinov@cogentembedded.com>
+Date: Mon, 15 May 2017 19:16:23 +0300
+Subject: [PATCH] arm64: dts: Gen3 view boards: TYPE1 first 4 cameras
+
+This set 4 cameras to TYPE1 in DT
+
+Signed-off-by: Vladimir Barinov <vladimir.barinov@cogentembedded.com>
+---
+ arch/arm64/boot/dts/renesas/r8a7795-es1-h3ulcb-kf.dts | 8 ++++----
+ arch/arm64/boot/dts/renesas/r8a7795-es1-h3ulcb-view.dts | 8 ++++----
+ arch/arm64/boot/dts/renesas/r8a7795-es1-salvator-x-view.dts | 8 ++++----
+ arch/arm64/boot/dts/renesas/r8a7795-h3ulcb-kf.dts | 8 ++++----
+ arch/arm64/boot/dts/renesas/r8a7795-h3ulcb-view.dts | 8 ++++----
+ arch/arm64/boot/dts/renesas/r8a7795-salvator-x-view.dts | 8 ++++----
+ arch/arm64/boot/dts/renesas/r8a7796-m3ulcb-kf.dts | 8 ++++----
+ arch/arm64/boot/dts/renesas/r8a7796-m3ulcb-view.dts | 8 ++++----
+ arch/arm64/boot/dts/renesas/r8a7796-salvator-x-view.dts | 8 ++++----
+ 9 files changed, 36 insertions(+), 36 deletions(-)
+
+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 50a37e0..8da87dd 100644
+--- a/arch/arm64/boot/dts/renesas/r8a7795-es1-h3ulcb-kf.dts
++++ b/arch/arm64/boot/dts/renesas/r8a7795-es1-h3ulcb-kf.dts
+@@ -780,22 +780,22 @@
+ port@0 {
+ max9286_des0ep0: endpoint@0 {
+ max9271-addr = <0x50>;
+- dvp-order = <1>;
++ dvp-order = <2>;
+ remote-endpoint = <&ov106xx_in0>;
+ };
+ max9286_des0ep1: endpoint@1 {
+ max9271-addr = <0x51>;
+- dvp-order = <1>;
++ dvp-order = <2>;
+ remote-endpoint = <&ov106xx_in1>;
+ };
+ max9286_des0ep2: endpoint@2 {
+ max9271-addr = <0x52>;
+- dvp-order = <1>;
++ dvp-order = <2>;
+ remote-endpoint = <&ov106xx_in2>;
+ };
+ max9286_des0ep3: endpoint@3 {
+ max9271-addr = <0x53>;
+- dvp-order = <1>;
++ dvp-order = <2>;
+ remote-endpoint = <&ov106xx_in3>;
+ };
+ };
+diff --git a/arch/arm64/boot/dts/renesas/r8a7795-es1-h3ulcb-view.dts b/arch/arm64/boot/dts/renesas/r8a7795-es1-h3ulcb-view.dts
+index de56fa4..b36b9d8 100644
+--- a/arch/arm64/boot/dts/renesas/r8a7795-es1-h3ulcb-view.dts
++++ b/arch/arm64/boot/dts/renesas/r8a7795-es1-h3ulcb-view.dts
+@@ -175,22 +175,22 @@
+ port@0 {
+ max9286_des0ep0: endpoint@0 {
+ max9271-addr = <0x50>;
+- dvp-order = <1>;
++ dvp-order = <2>;
+ remote-endpoint = <&ov106xx_in0>;
+ };
+ max9286_des0ep1: endpoint@1 {
+ max9271-addr = <0x51>;
+- dvp-order = <1>;
++ dvp-order = <2>;
+ remote-endpoint = <&ov106xx_in1>;
+ };
+ max9286_des0ep2: endpoint@2 {
+ max9271-addr = <0x52>;
+- dvp-order = <1>;
++ dvp-order = <2>;
+ remote-endpoint = <&ov106xx_in2>;
+ };
+ max9286_des0ep3: endpoint@3 {
+ max9271-addr = <0x53>;
+- dvp-order = <1>;
++ dvp-order = <2>;
+ remote-endpoint = <&ov106xx_in3>;
+ };
+ };
+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
+index 3f3d66a..c063899 100644
+--- a/arch/arm64/boot/dts/renesas/r8a7795-es1-salvator-x-view.dts
++++ b/arch/arm64/boot/dts/renesas/r8a7795-es1-salvator-x-view.dts
+@@ -190,22 +190,22 @@
+ port@0 {
+ max9286_des0ep0: endpoint@0 {
+ max9271-addr = <0x50>;
+- dvp-order = <1>;
++ dvp-order = <2>;
+ remote-endpoint = <&ov106xx_in0>;
+ };
+ max9286_des0ep1: endpoint@1 {
+ max9271-addr = <0x51>;
+- dvp-order = <1>;
++ dvp-order = <2>;
+ remote-endpoint = <&ov106xx_in1>;
+ };
+ max9286_des0ep2: endpoint@2 {
+ max9271-addr = <0x52>;
+- dvp-order = <1>;
++ dvp-order = <2>;
+ remote-endpoint = <&ov106xx_in2>;
+ };
+ max9286_des0ep3: endpoint@3 {
+ max9271-addr = <0x53>;
+- dvp-order = <1>;
++ dvp-order = <2>;
+ remote-endpoint = <&ov106xx_in3>;
+ };
+ };
+diff --git a/arch/arm64/boot/dts/renesas/r8a7795-h3ulcb-kf.dts b/arch/arm64/boot/dts/renesas/r8a7795-h3ulcb-kf.dts
+index 94c86f6..b26d8e2 100644
+--- a/arch/arm64/boot/dts/renesas/r8a7795-h3ulcb-kf.dts
++++ b/arch/arm64/boot/dts/renesas/r8a7795-h3ulcb-kf.dts
+@@ -780,22 +780,22 @@
+ port@0 {
+ max9286_des0ep0: endpoint@0 {
+ max9271-addr = <0x50>;
+- dvp-order = <1>;
++ dvp-order = <2>;
+ remote-endpoint = <&ov106xx_in0>;
+ };
+ max9286_des0ep1: endpoint@1 {
+ max9271-addr = <0x51>;
+- dvp-order = <1>;
++ dvp-order = <2>;
+ remote-endpoint = <&ov106xx_in1>;
+ };
+ max9286_des0ep2: endpoint@2 {
+ max9271-addr = <0x52>;
+- dvp-order = <1>;
++ dvp-order = <2>;
+ remote-endpoint = <&ov106xx_in2>;
+ };
+ max9286_des0ep3: endpoint@3 {
+ max9271-addr = <0x53>;
+- dvp-order = <1>;
++ dvp-order = <2>;
+ remote-endpoint = <&ov106xx_in3>;
+ };
+ };
+diff --git a/arch/arm64/boot/dts/renesas/r8a7795-h3ulcb-view.dts b/arch/arm64/boot/dts/renesas/r8a7795-h3ulcb-view.dts
+index 2c24b85..a8b9eea 100644
+--- a/arch/arm64/boot/dts/renesas/r8a7795-h3ulcb-view.dts
++++ b/arch/arm64/boot/dts/renesas/r8a7795-h3ulcb-view.dts
+@@ -175,22 +175,22 @@
+ port@0 {
+ max9286_des0ep0: endpoint@0 {
+ max9271-addr = <0x50>;
+- dvp-order = <1>;
++ dvp-order = <2>;
+ remote-endpoint = <&ov106xx_in0>;
+ };
+ max9286_des0ep1: endpoint@1 {
+ max9271-addr = <0x51>;
+- dvp-order = <1>;
++ dvp-order = <2>;
+ remote-endpoint = <&ov106xx_in1>;
+ };
+ max9286_des0ep2: endpoint@2 {
+ max9271-addr = <0x52>;
+- dvp-order = <1>;
++ dvp-order = <2>;
+ remote-endpoint = <&ov106xx_in2>;
+ };
+ max9286_des0ep3: endpoint@3 {
+ max9271-addr = <0x53>;
+- dvp-order = <1>;
++ dvp-order = <2>;
+ remote-endpoint = <&ov106xx_in3>;
+ };
+ };
+diff --git a/arch/arm64/boot/dts/renesas/r8a7795-salvator-x-view.dts b/arch/arm64/boot/dts/renesas/r8a7795-salvator-x-view.dts
+index fb12a39f3..eb09ef0 100644
+--- a/arch/arm64/boot/dts/renesas/r8a7795-salvator-x-view.dts
++++ b/arch/arm64/boot/dts/renesas/r8a7795-salvator-x-view.dts
+@@ -190,22 +190,22 @@
+ port@0 {
+ max9286_des0ep0: endpoint@0 {
+ max9271-addr = <0x50>;
+- dvp-order = <1>;
++ dvp-order = <2>;
+ remote-endpoint = <&ov106xx_in0>;
+ };
+ max9286_des0ep1: endpoint@1 {
+ max9271-addr = <0x51>;
+- dvp-order = <1>;
++ dvp-order = <2>;
+ remote-endpoint = <&ov106xx_in1>;
+ };
+ max9286_des0ep2: endpoint@2 {
+ max9271-addr = <0x52>;
+- dvp-order = <1>;
++ dvp-order = <2>;
+ remote-endpoint = <&ov106xx_in2>;
+ };
+ max9286_des0ep3: endpoint@3 {
+ max9271-addr = <0x53>;
+- dvp-order = <1>;
++ dvp-order = <2>;
+ remote-endpoint = <&ov106xx_in3>;
+ };
+ };
+diff --git a/arch/arm64/boot/dts/renesas/r8a7796-m3ulcb-kf.dts b/arch/arm64/boot/dts/renesas/r8a7796-m3ulcb-kf.dts
+index ffaef74..83c6355 100644
+--- a/arch/arm64/boot/dts/renesas/r8a7796-m3ulcb-kf.dts
++++ b/arch/arm64/boot/dts/renesas/r8a7796-m3ulcb-kf.dts
+@@ -780,22 +780,22 @@
+ port@0 {
+ max9286_des0ep0: endpoint@0 {
+ max9271-addr = <0x50>;
+- dvp-order = <1>;
++ dvp-order = <2>;
+ remote-endpoint = <&ov106xx_in0>;
+ };
+ max9286_des0ep1: endpoint@1 {
+ max9271-addr = <0x51>;
+- dvp-order = <1>;
++ dvp-order = <2>;
+ remote-endpoint = <&ov106xx_in1>;
+ };
+ max9286_des0ep2: endpoint@2 {
+ max9271-addr = <0x52>;
+- dvp-order = <1>;
++ dvp-order = <2>;
+ remote-endpoint = <&ov106xx_in2>;
+ };
+ max9286_des0ep3: endpoint@3 {
+ max9271-addr = <0x53>;
+- dvp-order = <1>;
++ dvp-order = <2>;
+ remote-endpoint = <&ov106xx_in3>;
+ };
+ };
+diff --git a/arch/arm64/boot/dts/renesas/r8a7796-m3ulcb-view.dts b/arch/arm64/boot/dts/renesas/r8a7796-m3ulcb-view.dts
+index 1ac0041..096fb5f 100644
+--- a/arch/arm64/boot/dts/renesas/r8a7796-m3ulcb-view.dts
++++ b/arch/arm64/boot/dts/renesas/r8a7796-m3ulcb-view.dts
+@@ -103,22 +103,22 @@
+ port@0 {
+ max9286_des0ep0: endpoint@0 {
+ max9271-addr = <0x50>;
+- dvp-order = <1>;
++ dvp-order = <2>;
+ remote-endpoint = <&ov106xx_in0>;
+ };
+ max9286_des0ep1: endpoint@1 {
+ max9271-addr = <0x51>;
+- dvp-order = <1>;
++ dvp-order = <2>;
+ remote-endpoint = <&ov106xx_in1>;
+ };
+ max9286_des0ep2: endpoint@2 {
+ max9271-addr = <0x52>;
+- dvp-order = <1>;
++ dvp-order = <2>;
+ remote-endpoint = <&ov106xx_in2>;
+ };
+ max9286_des0ep3: endpoint@3 {
+ max9271-addr = <0x53>;
+- dvp-order = <1>;
++ dvp-order = <2>;
+ remote-endpoint = <&ov106xx_in3>;
+ };
+ };
+diff --git a/arch/arm64/boot/dts/renesas/r8a7796-salvator-x-view.dts b/arch/arm64/boot/dts/renesas/r8a7796-salvator-x-view.dts
+index cc6866c..7a592d1 100644
+--- a/arch/arm64/boot/dts/renesas/r8a7796-salvator-x-view.dts
++++ b/arch/arm64/boot/dts/renesas/r8a7796-salvator-x-view.dts
+@@ -118,22 +118,22 @@
+ port@0 {
+ max9286_des0ep0: endpoint@0 {
+ max9271-addr = <0x50>;
+- dvp-order = <1>;
++ dvp-order = <2>;
+ remote-endpoint = <&ov106xx_in0>;
+ };
+ max9286_des0ep1: endpoint@1 {
+ max9271-addr = <0x51>;
+- dvp-order = <1>;
++ dvp-order = <2>;
+ remote-endpoint = <&ov106xx_in1>;
+ };
+ max9286_des0ep2: endpoint@2 {
+ max9271-addr = <0x52>;
+- dvp-order = <1>;
++ dvp-order = <2>;
+ remote-endpoint = <&ov106xx_in2>;
+ };
+ max9286_des0ep3: endpoint@3 {
+ max9271-addr = <0x53>;
+- dvp-order = <1>;
++ dvp-order = <2>;
+ remote-endpoint = <&ov106xx_in3>;
+ };
+ };
+--
+1.9.1
+
diff --git a/meta-rcar-gen3-adas/recipes-kernel/linux/linux-renesas/0050-arm64-dts-renesas-r8a779x-add-IMP-nodes.patch b/meta-rcar-gen3-adas/recipes-kernel/linux/linux-renesas/0050-arm64-dts-renesas-r8a779x-add-IMP-nodes.patch
new file mode 100644
index 0000000..b38a623
--- /dev/null
+++ b/meta-rcar-gen3-adas/recipes-kernel/linux/linux-renesas/0050-arm64-dts-renesas-r8a779x-add-IMP-nodes.patch
@@ -0,0 +1,425 @@
+From 9dcc1345c0b04ebab6e5b9f676881716bf985753 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] 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-es1.dtsi | 98 +++++++++++++++++++++++++++
+ arch/arm64/boot/dts/renesas/r8a7795.dtsi | 98 +++++++++++++++++++++++++++
+ arch/arm64/boot/dts/renesas/r8a7796.dtsi | 62 +++++++++++++++++
+ arch/arm64/boot/dts/renesas/r8a7797.dtsi | 99 ++++++++++++++++++++++++++++
+ 4 files changed, 357 insertions(+)
+
+diff --git a/arch/arm64/boot/dts/renesas/r8a7795-es1.dtsi b/arch/arm64/boot/dts/renesas/r8a7795-es1.dtsi
+index b3f3102..e15af8c 100644
+--- a/arch/arm64/boot/dts/renesas/r8a7795-es1.dtsi
++++ b/arch/arm64/boot/dts/renesas/r8a7795-es1.dtsi
+@@ -2794,6 +2794,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>;
++ };
++
+ imrlx4_ch0: imr-lx4@fe860000 {
+ compatible = "renesas,imr-lx4";
+ reg = <0 0xfe860000 0 0x2000>;
+diff --git a/arch/arm64/boot/dts/renesas/r8a7795.dtsi b/arch/arm64/boot/dts/renesas/r8a7795.dtsi
+index 02c5931..8ba4cec 100644
+--- a/arch/arm64/boot/dts/renesas/r8a7795.dtsi
++++ b/arch/arm64/boot/dts/renesas/r8a7795.dtsi
+@@ -2790,6 +2790,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>;
++ };
++
+ imrlx4_ch0: imr-lx4@fe860000 {
+ compatible = "renesas,imr-lx4";
+ reg = <0 0xfe860000 0 0x2000>;
+diff --git a/arch/arm64/boot/dts/renesas/r8a7796.dtsi b/arch/arm64/boot/dts/renesas/r8a7796.dtsi
+index b94d9e0..7c19f35 100644
+--- a/arch/arm64/boot/dts/renesas/r8a7796.dtsi
++++ b/arch/arm64/boot/dts/renesas/r8a7796.dtsi
+@@ -2531,5 +2531,67 @@
+ };
+ };
+ };
++
++ 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>;
++ };
+ };
+ };
+diff --git a/arch/arm64/boot/dts/renesas/r8a7797.dtsi b/arch/arm64/boot/dts/renesas/r8a7797.dtsi
+index 1be93e8..232eb19 100644
+--- a/arch/arm64/boot/dts/renesas/r8a7797.dtsi
++++ b/arch/arm64/boot/dts/renesas/r8a7797.dtsi
+@@ -970,6 +970,112 @@
+ status = "okay";
+ };
+
++ imp_distributer: impdes0 {
++ compatible = "renesas,impx4-distributer";
++ reg = <0 0xffa00000 0 0x4000>;
++ 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-dmac";
++ reg = <0 0xffa20000 0 0x4000>;
++ interrupt-parent = <&imp_distributer>;
++ interrupts = <12>;
++ clocks = <&cpg CPG_MOD 830>;
++ power-domains = <&sysc R8A7797_PD_A3IR>;
++ };
++
++ impc0 {
++ compatible = "renesas,impx4-memory";
++ reg = <0 0xed000000 0 0x100000>;
++ clocks = <&cpg CPG_MOD 830>;
++ power-domains = <&sysc R8A7797_PD_A3IR>;
++ };
++
++ impcnn0 {
++ compatible = "renesas,impx4-legacy";
++ reg = <0 0xff9e0000 0 0x10000>;
++ clocks = <&cpg CPG_MOD 824>;
++ power-domains = <&sysc R8A7797_PD_A2IR3>;
++ };
++
+ imrlx4_ch0: imr-lx4@fe860000 {
+ compatible = "renesas,imr-lx4";
+ reg = <0 0xfe860000 0 0x2000>;
+--
+1.9.1
+
diff --git a/meta-rcar-gen3-adas/recipes-kernel/linux/linux-renesas/0051-arm64-dts-Gen3-view-boards-TYPE1-second-4-cameras.patch b/meta-rcar-gen3-adas/recipes-kernel/linux/linux-renesas/0051-arm64-dts-Gen3-view-boards-TYPE1-second-4-cameras.patch
new file mode 100644
index 0000000..a09c485
--- /dev/null
+++ b/meta-rcar-gen3-adas/recipes-kernel/linux/linux-renesas/0051-arm64-dts-Gen3-view-boards-TYPE1-second-4-cameras.patch
@@ -0,0 +1,206 @@
+From d9ec2149ffc47fd2ea4ab5e9a503a3be7c6f09f5 Mon Sep 17 00:00:00 2001
+From: Vladimir Barinov <vladimir.barinov@cogentembedded.com>
+Date: Mon, 15 May 2017 19:18:06 +0300
+Subject: [PATCH] arm64: dts: Gen3 view boards: TYPE1 second 4 cameras
+
+This set 4 cameras to TYPE1 in DT
+
+Signed-off-by: Vladimir Barinov <vladimir.barinov@cogentembedded.com>
+---
+ arch/arm64/boot/dts/renesas/r8a7795-es1-h3ulcb-kf.dts | 8 ++++----
+ arch/arm64/boot/dts/renesas/r8a7795-es1-h3ulcb-view.dts | 8 ++++----
+ arch/arm64/boot/dts/renesas/r8a7795-es1-salvator-x-view.dts | 8 ++++----
+ arch/arm64/boot/dts/renesas/r8a7795-h3ulcb-kf.dts | 8 ++++----
+ arch/arm64/boot/dts/renesas/r8a7795-h3ulcb-view.dts | 8 ++++----
+ arch/arm64/boot/dts/renesas/r8a7795-salvator-x-view.dts | 8 ++++----
+ 6 files changed, 24 insertions(+), 24 deletions(-)
+
+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 8da87dd..d2e6f66 100644
+--- a/arch/arm64/boot/dts/renesas/r8a7795-es1-h3ulcb-kf.dts
++++ b/arch/arm64/boot/dts/renesas/r8a7795-es1-h3ulcb-kf.dts
+@@ -989,22 +989,22 @@
+ port@0 {
+ max9286_des1ep0: endpoint@0 {
+ max9271-addr = <0x50>;
+- dvp-order = <1>;
++ dvp-order = <2>;
+ remote-endpoint = <&ov106xx_in4>;
+ };
+ max9286_des1ep1: endpoint@1 {
+ max9271-addr = <0x51>;
+- dvp-order = <1>;
++ dvp-order = <2>;
+ remote-endpoint = <&ov106xx_in5>;
+ };
+ max9286_des1ep2: endpoint@2 {
+ max9271-addr = <0x52>;
+- dvp-order = <1>;
++ dvp-order = <2>;
+ remote-endpoint = <&ov106xx_in6>;
+ };
+ max9286_des1ep3: endpoint@3 {
+ max9271-addr = <0x53>;
+- dvp-order = <1>;
++ dvp-order = <2>;
+ remote-endpoint = <&ov106xx_in7>;
+ };
+ };
+diff --git a/arch/arm64/boot/dts/renesas/r8a7795-es1-h3ulcb-view.dts b/arch/arm64/boot/dts/renesas/r8a7795-es1-h3ulcb-view.dts
+index b36b9d8..e3a9414 100644
+--- a/arch/arm64/boot/dts/renesas/r8a7795-es1-h3ulcb-view.dts
++++ b/arch/arm64/boot/dts/renesas/r8a7795-es1-h3ulcb-view.dts
+@@ -216,22 +216,22 @@
+ port@0 {
+ max9286_des1ep0: endpoint@0 {
+ max9271-addr = <0x54>;
+- dvp-order = <1>;
++ dvp-order = <2>;
+ remote-endpoint = <&ov106xx_in4>;
+ };
+ max9286_des1ep1: endpoint@1 {
+ max9271-addr = <0x55>;
+- dvp-order = <1>;
++ dvp-order = <2>;
+ remote-endpoint = <&ov106xx_in5>;
+ };
+ max9286_des1ep2: endpoint@2 {
+ max9271-addr = <0x56>;
+- dvp-order = <1>;
++ dvp-order = <2>;
+ remote-endpoint = <&ov106xx_in6>;
+ };
+ max9286_des1ep3: endpoint@3 {
+ max9271-addr = <0x57>;
+- dvp-order = <1>;
++ dvp-order = <2>;
+ remote-endpoint = <&ov106xx_in7>;
+ };
+ };
+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
+index c063899..2785fd7 100644
+--- a/arch/arm64/boot/dts/renesas/r8a7795-es1-salvator-x-view.dts
++++ b/arch/arm64/boot/dts/renesas/r8a7795-es1-salvator-x-view.dts
+@@ -230,22 +230,22 @@
+ port@0 {
+ max9286_des1ep0: endpoint@0 {
+ max9271-addr = <0x54>;
+- dvp-order = <1>;
++ dvp-order = <2>;
+ remote-endpoint = <&ov106xx_in4>;
+ };
+ max9286_des1ep1: endpoint@1 {
+ max9271-addr = <0x55>;
+- dvp-order = <1>;
++ dvp-order = <2>;
+ remote-endpoint = <&ov106xx_in5>;
+ };
+ max9286_des1ep2: endpoint@2 {
+ max9271-addr = <0x56>;
+- dvp-order = <1>;
++ dvp-order = <2>;
+ remote-endpoint = <&ov106xx_in6>;
+ };
+ max9286_des1ep3: endpoint@3 {
+ max9271-addr = <0x57>;
+- dvp-order = <1>;
++ dvp-order = <2>;
+ remote-endpoint = <&ov106xx_in7>;
+ };
+ };
+diff --git a/arch/arm64/boot/dts/renesas/r8a7795-h3ulcb-kf.dts b/arch/arm64/boot/dts/renesas/r8a7795-h3ulcb-kf.dts
+index b26d8e2..b8f8819 100644
+--- a/arch/arm64/boot/dts/renesas/r8a7795-h3ulcb-kf.dts
++++ b/arch/arm64/boot/dts/renesas/r8a7795-h3ulcb-kf.dts
+@@ -989,22 +989,22 @@
+ port@0 {
+ max9286_des1ep0: endpoint@0 {
+ max9271-addr = <0x50>;
+- dvp-order = <1>;
++ dvp-order = <2>;
+ remote-endpoint = <&ov106xx_in4>;
+ };
+ max9286_des1ep1: endpoint@1 {
+ max9271-addr = <0x51>;
+- dvp-order = <1>;
++ dvp-order = <2>;
+ remote-endpoint = <&ov106xx_in5>;
+ };
+ max9286_des1ep2: endpoint@2 {
+ max9271-addr = <0x52>;
+- dvp-order = <1>;
++ dvp-order = <2>;
+ remote-endpoint = <&ov106xx_in6>;
+ };
+ max9286_des1ep3: endpoint@3 {
+ max9271-addr = <0x53>;
+- dvp-order = <1>;
++ dvp-order = <2>;
+ remote-endpoint = <&ov106xx_in7>;
+ };
+ };
+diff --git a/arch/arm64/boot/dts/renesas/r8a7795-h3ulcb-view.dts b/arch/arm64/boot/dts/renesas/r8a7795-h3ulcb-view.dts
+index a8b9eea..86ed4a8 100644
+--- a/arch/arm64/boot/dts/renesas/r8a7795-h3ulcb-view.dts
++++ b/arch/arm64/boot/dts/renesas/r8a7795-h3ulcb-view.dts
+@@ -216,22 +216,22 @@
+ port@0 {
+ max9286_des1ep0: endpoint@0 {
+ max9271-addr = <0x54>;
+- dvp-order = <1>;
++ dvp-order = <2>;
+ remote-endpoint = <&ov106xx_in4>;
+ };
+ max9286_des1ep1: endpoint@1 {
+ max9271-addr = <0x55>;
+- dvp-order = <1>;
++ dvp-order = <2>;
+ remote-endpoint = <&ov106xx_in5>;
+ };
+ max9286_des1ep2: endpoint@2 {
+ max9271-addr = <0x56>;
+- dvp-order = <1>;
++ dvp-order = <2>;
+ remote-endpoint = <&ov106xx_in6>;
+ };
+ max9286_des1ep3: endpoint@3 {
+ max9271-addr = <0x57>;
+- dvp-order = <1>;
++ dvp-order = <2>;
+ remote-endpoint = <&ov106xx_in7>;
+ };
+ };
+diff --git a/arch/arm64/boot/dts/renesas/r8a7795-salvator-x-view.dts b/arch/arm64/boot/dts/renesas/r8a7795-salvator-x-view.dts
+index eb09ef0..37eabc0 100644
+--- a/arch/arm64/boot/dts/renesas/r8a7795-salvator-x-view.dts
++++ b/arch/arm64/boot/dts/renesas/r8a7795-salvator-x-view.dts
+@@ -230,22 +230,22 @@
+ port@0 {
+ max9286_des1ep0: endpoint@0 {
+ max9271-addr = <0x54>;
+- dvp-order = <1>;
++ dvp-order = <2>;
+ remote-endpoint = <&ov106xx_in4>;
+ };
+ max9286_des1ep1: endpoint@1 {
+ max9271-addr = <0x55>;
+- dvp-order = <1>;
++ dvp-order = <2>;
+ remote-endpoint = <&ov106xx_in5>;
+ };
+ max9286_des1ep2: endpoint@2 {
+ max9271-addr = <0x56>;
+- dvp-order = <1>;
++ dvp-order = <2>;
+ remote-endpoint = <&ov106xx_in6>;
+ };
+ max9286_des1ep3: endpoint@3 {
+ max9271-addr = <0x57>;
+- dvp-order = <1>;
++ dvp-order = <2>;
+ remote-endpoint = <&ov106xx_in7>;
+ };
+ };
+--
+1.9.1
+
diff --git a/meta-rcar-gen3-adas/recipes-kernel/linux/linux-renesas/0052-arm64-dts-Gen3-view-boards-TYPE2-first-4-cameras.patch b/meta-rcar-gen3-adas/recipes-kernel/linux/linux-renesas/0052-arm64-dts-Gen3-view-boards-TYPE2-first-4-cameras.patch
new file mode 100644
index 0000000..2c4d9f3
--- /dev/null
+++ b/meta-rcar-gen3-adas/recipes-kernel/linux/linux-renesas/0052-arm64-dts-Gen3-view-boards-TYPE2-first-4-cameras.patch
@@ -0,0 +1,527 @@
+From fa7c75c71d40c8ce44b0fbaea79031daaede2ba7 Mon Sep 17 00:00:00 2001
+From: Vladimir Barinov <vladimir.barinov@cogentembedded.com>
+Date: Mon, 15 May 2017 19:24:29 +0300
+Subject: [PATCH] arm64: dts: Gen3 view boards: TYPE2 first 4 cameras
+
+This set 4 cameras to TYPE2 in DT
+
+Signed-off-by: Vladimir Barinov <vladimir.barinov@cogentembedded.com>
+---
+ arch/arm64/boot/dts/renesas/r8a7795-es1-h3ulcb-kf.dts | 17 +++++++++++++++--
+ arch/arm64/boot/dts/renesas/r8a7795-es1-h3ulcb-view.dts | 17 +++++++++++++++--
+ .../boot/dts/renesas/r8a7795-es1-salvator-x-view.dts | 17 +++++++++++++++--
+ arch/arm64/boot/dts/renesas/r8a7795-h3ulcb-kf.dts | 17 +++++++++++++++--
+ arch/arm64/boot/dts/renesas/r8a7795-h3ulcb-view.dts | 17 +++++++++++++++--
+ arch/arm64/boot/dts/renesas/r8a7795-salvator-x-view.dts | 17 +++++++++++++++--
+ arch/arm64/boot/dts/renesas/r8a7796-m3ulcb-kf.dts | 17 +++++++++++++++--
+ arch/arm64/boot/dts/renesas/r8a7796-m3ulcb-view.dts | 17 +++++++++++++++--
+ arch/arm64/boot/dts/renesas/r8a7796-salvator-x-view.dts | 17 +++++++++++++++--
+ 9 files changed, 135 insertions(+), 18 deletions(-)
+
+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 50a37e0..8808e80 100644
+--- a/arch/arm64/boot/dts/renesas/r8a7795-es1-h3ulcb-kf.dts
++++ b/arch/arm64/boot/dts/renesas/r8a7795-es1-h3ulcb-kf.dts
+@@ -609,6 +609,9 @@
+ compatible = "ovti,ov106xx";
+ reg = <0x60>;
+
++ maxim,fixed-sensor = "ov490";
++ maxim,width = <1280>;
++ maxim,height = <966>;
+ port@0 {
+ ov106xx_in0: endpoint {
+ clock-lanes = <0>;
+@@ -633,6 +636,9 @@
+ compatible = "ovti,ov106xx";
+ reg = <0x61>;
+
++ maxim,fixed-sensor = "ov490";
++ maxim,width = <1280>;
++ maxim,height = <966>;
+ port@0 {
+ ov106xx_in1: endpoint {
+ clock-lanes = <0>;
+@@ -657,6 +663,9 @@
+ compatible = "ovti,ov106xx";
+ reg = <0x62>;
+
++ maxim,fixed-sensor = "ov490";
++ maxim,width = <1280>;
++ maxim,height = <966>;
+ port@0 {
+ ov106xx_in2: endpoint {
+ clock-lanes = <0>;
+@@ -678,6 +687,9 @@
+ compatible = "ovti,ov106xx";
+ reg = <0x63>;
+
++ maxim,fixed-sensor = "ov490";
++ maxim,width = <1280>;
++ maxim,height = <966>;
+ port@0 {
+ ov106xx_in3: endpoint {
+ clock-lanes = <0>;
+@@ -773,8 +785,9 @@
+ maxim,sensor_delay = <350>;
+ maxim,links = <4>;
+ maxim,lanes = <4>;
+- maxim,resetb-gpio = <1>;
+- maxim,fsync-mode = "automatic";
++ maxim,resetb-gpio = <4>;
++ maxim,resetb-active-high;
++ maxim,fsync-mode = "manual";
+ maxim,timeout = <100>;
+
+ port@0 {
+diff --git a/arch/arm64/boot/dts/renesas/r8a7795-es1-h3ulcb-view.dts b/arch/arm64/boot/dts/renesas/r8a7795-es1-h3ulcb-view.dts
+index de56fa4..007aa7a 100644
+--- a/arch/arm64/boot/dts/renesas/r8a7795-es1-h3ulcb-view.dts
++++ b/arch/arm64/boot/dts/renesas/r8a7795-es1-h3ulcb-view.dts
+@@ -20,6 +20,9 @@
+ compatible = "ovti,ov106xx";
+ reg = <0x60>;
+
++ maxim,fixed-sensor = "ov490";
++ maxim,width = <1280>;
++ maxim,height = <966>;
+ port@0 {
+ ov106xx_in0: endpoint {
+ clock-lanes = <0>;
+@@ -38,6 +41,9 @@
+ compatible = "ovti,ov106xx";
+ reg = <0x61>;
+
++ maxim,fixed-sensor = "ov490";
++ maxim,width = <1280>;
++ maxim,height = <966>;
+ port@0 {
+ ov106xx_in1: endpoint {
+ clock-lanes = <0>;
+@@ -56,6 +62,9 @@
+ compatible = "ovti,ov106xx";
+ reg = <0x62>;
+
++ maxim,fixed-sensor = "ov490";
++ maxim,width = <1280>;
++ maxim,height = <966>;
+ port@0 {
+ ov106xx_in2: endpoint {
+ clock-lanes = <0>;
+@@ -74,6 +83,9 @@
+ compatible = "ovti,ov106xx";
+ reg = <0x63>;
+
++ maxim,fixed-sensor = "ov490";
++ maxim,width = <1280>;
++ maxim,height = <966>;
+ port@0 {
+ ov106xx_in3: endpoint {
+ clock-lanes = <0>;
+@@ -167,8 +179,9 @@
+ maxim,sensor_delay = <0>;
+ maxim,links = <4>;
+ maxim,lanes = <4>;
+- maxim,resetb-gpio = <1>;
+- maxim,fsync-mode = "automatic";
++ maxim,resetb-gpio = <4>;
++ maxim,resetb-active-high;
++ maxim,fsync-mode = "manual";
+ maxim,timeout = <100>;
+ maxim,i2c-quirk = <0x6c>;
+
+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
+index 3f3d66a..4b3513a 100644
+--- a/arch/arm64/boot/dts/renesas/r8a7795-es1-salvator-x-view.dts
++++ b/arch/arm64/boot/dts/renesas/r8a7795-es1-salvator-x-view.dts
+@@ -35,6 +35,9 @@
+ compatible = "ovti,ov106xx";
+ reg = <0x60>;
+
++ maxim,fixed-sensor = "ov490";
++ maxim,width = <1280>;
++ maxim,height = <966>;
+ port@0 {
+ ov106xx_in0: endpoint {
+ clock-lanes = <0>;
+@@ -53,6 +56,9 @@
+ compatible = "ovti,ov106xx";
+ reg = <0x61>;
+
++ maxim,fixed-sensor = "ov490";
++ maxim,width = <1280>;
++ maxim,height = <966>;
+ port@0 {
+ ov106xx_in1: endpoint {
+ clock-lanes = <0>;
+@@ -71,6 +77,9 @@
+ compatible = "ovti,ov106xx";
+ reg = <0x62>;
+
++ maxim,fixed-sensor = "ov490";
++ maxim,width = <1280>;
++ maxim,height = <966>;
+ port@0 {
+ ov106xx_in2: endpoint {
+ clock-lanes = <0>;
+@@ -89,6 +98,9 @@
+ compatible = "ovti,ov106xx";
+ reg = <0x63>;
+
++ maxim,fixed-sensor = "ov490";
++ maxim,width = <1280>;
++ maxim,height = <966>;
+ port@0 {
+ ov106xx_in3: endpoint {
+ clock-lanes = <0>;
+@@ -182,8 +194,9 @@
+ maxim,sensor_delay = <0>;
+ maxim,links = <4>;
+ maxim,lanes = <4>;
+- maxim,resetb-gpio = <1>;
+- maxim,fsync-mode = "automatic";
++ maxim,resetb-gpio = <4>;
++ maxim,resetb-active-high;
++ maxim,fsync-mode = "manual";
+ maxim,timeout = <100>;
+ maxim,i2c-quirk = <0x6c>;
+
+diff --git a/arch/arm64/boot/dts/renesas/r8a7795-h3ulcb-kf.dts b/arch/arm64/boot/dts/renesas/r8a7795-h3ulcb-kf.dts
+index 94c86f6..e650c5b 100644
+--- a/arch/arm64/boot/dts/renesas/r8a7795-h3ulcb-kf.dts
++++ b/arch/arm64/boot/dts/renesas/r8a7795-h3ulcb-kf.dts
+@@ -609,6 +609,9 @@
+ compatible = "ovti,ov106xx";
+ reg = <0x60>;
+
++ maxim,fixed-sensor = "ov490";
++ maxim,width = <1280>;
++ maxim,height = <966>;
+ port@0 {
+ ov106xx_in0: endpoint {
+ clock-lanes = <0>;
+@@ -633,6 +636,9 @@
+ compatible = "ovti,ov106xx";
+ reg = <0x61>;
+
++ maxim,fixed-sensor = "ov490";
++ maxim,width = <1280>;
++ maxim,height = <966>;
+ port@0 {
+ ov106xx_in1: endpoint {
+ clock-lanes = <0>;
+@@ -657,6 +663,9 @@
+ compatible = "ovti,ov106xx";
+ reg = <0x62>;
+
++ maxim,fixed-sensor = "ov490";
++ maxim,width = <1280>;
++ maxim,height = <966>;
+ port@0 {
+ ov106xx_in2: endpoint {
+ clock-lanes = <0>;
+@@ -678,6 +687,9 @@
+ compatible = "ovti,ov106xx";
+ reg = <0x63>;
+
++ maxim,fixed-sensor = "ov490";
++ maxim,width = <1280>;
++ maxim,height = <966>;
+ port@0 {
+ ov106xx_in3: endpoint {
+ clock-lanes = <0>;
+@@ -773,8 +785,9 @@
+ maxim,sensor_delay = <350>;
+ maxim,links = <4>;
+ maxim,lanes = <4>;
+- maxim,resetb-gpio = <1>;
+- maxim,fsync-mode = "automatic";
++ maxim,resetb-gpio = <4>;
++ maxim,resetb-active-high;
++ maxim,fsync-mode = "manual";
+ maxim,timeout = <100>;
+
+ port@0 {
+diff --git a/arch/arm64/boot/dts/renesas/r8a7795-h3ulcb-view.dts b/arch/arm64/boot/dts/renesas/r8a7795-h3ulcb-view.dts
+index 2c24b85..ac0723d 100644
+--- a/arch/arm64/boot/dts/renesas/r8a7795-h3ulcb-view.dts
++++ b/arch/arm64/boot/dts/renesas/r8a7795-h3ulcb-view.dts
+@@ -20,6 +20,9 @@
+ compatible = "ovti,ov106xx";
+ reg = <0x60>;
+
++ maxim,fixed-sensor = "ov490";
++ maxim,width = <1280>;
++ maxim,height = <966>;
+ port@0 {
+ ov106xx_in0: endpoint {
+ clock-lanes = <0>;
+@@ -38,6 +41,9 @@
+ compatible = "ovti,ov106xx";
+ reg = <0x61>;
+
++ maxim,fixed-sensor = "ov490";
++ maxim,width = <1280>;
++ maxim,height = <966>;
+ port@0 {
+ ov106xx_in1: endpoint {
+ clock-lanes = <0>;
+@@ -56,6 +62,9 @@
+ compatible = "ovti,ov106xx";
+ reg = <0x62>;
+
++ maxim,fixed-sensor = "ov490";
++ maxim,width = <1280>;
++ maxim,height = <966>;
+ port@0 {
+ ov106xx_in2: endpoint {
+ clock-lanes = <0>;
+@@ -74,6 +83,9 @@
+ compatible = "ovti,ov106xx";
+ reg = <0x63>;
+
++ maxim,fixed-sensor = "ov490";
++ maxim,width = <1280>;
++ maxim,height = <966>;
+ port@0 {
+ ov106xx_in3: endpoint {
+ clock-lanes = <0>;
+@@ -167,8 +179,9 @@
+ maxim,sensor_delay = <0>;
+ maxim,links = <4>;
+ maxim,lanes = <4>;
+- maxim,resetb-gpio = <1>;
+- maxim,fsync-mode = "automatic";
++ maxim,resetb-gpio = <4>;
++ maxim,resetb-active-high;
++ maxim,fsync-mode = "manual";
+ maxim,timeout = <100>;
+ maxim,i2c-quirk = <0x6c>;
+
+diff --git a/arch/arm64/boot/dts/renesas/r8a7795-salvator-x-view.dts b/arch/arm64/boot/dts/renesas/r8a7795-salvator-x-view.dts
+index fb12a39f3..ef0895e 100644
+--- a/arch/arm64/boot/dts/renesas/r8a7795-salvator-x-view.dts
++++ b/arch/arm64/boot/dts/renesas/r8a7795-salvator-x-view.dts
+@@ -35,6 +35,9 @@
+ compatible = "ovti,ov106xx";
+ reg = <0x60>;
+
++ maxim,fixed-sensor = "ov490";
++ maxim,width = <1280>;
++ maxim,height = <966>;
+ port@0 {
+ ov106xx_in0: endpoint {
+ clock-lanes = <0>;
+@@ -53,6 +56,9 @@
+ compatible = "ovti,ov106xx";
+ reg = <0x61>;
+
++ maxim,fixed-sensor = "ov490";
++ maxim,width = <1280>;
++ maxim,height = <966>;
+ port@0 {
+ ov106xx_in1: endpoint {
+ clock-lanes = <0>;
+@@ -71,6 +77,9 @@
+ compatible = "ovti,ov106xx";
+ reg = <0x62>;
+
++ maxim,fixed-sensor = "ov490";
++ maxim,width = <1280>;
++ maxim,height = <966>;
+ port@0 {
+ ov106xx_in2: endpoint {
+ clock-lanes = <0>;
+@@ -89,6 +98,9 @@
+ compatible = "ovti,ov106xx";
+ reg = <0x63>;
+
++ maxim,fixed-sensor = "ov490";
++ maxim,width = <1280>;
++ maxim,height = <966>;
+ port@0 {
+ ov106xx_in3: endpoint {
+ clock-lanes = <0>;
+@@ -182,8 +194,9 @@
+ maxim,sensor_delay = <0>;
+ maxim,links = <4>;
+ maxim,lanes = <4>;
+- maxim,resetb-gpio = <1>;
+- maxim,fsync-mode = "automatic";
++ maxim,resetb-gpio = <4>;
++ maxim,resetb-active-high;
++ maxim,fsync-mode = "manual";
+ maxim,timeout = <100>;
+ maxim,i2c-quirk = <0x6c>;
+
+diff --git a/arch/arm64/boot/dts/renesas/r8a7796-m3ulcb-kf.dts b/arch/arm64/boot/dts/renesas/r8a7796-m3ulcb-kf.dts
+index ffaef74..5670f3a 100644
+--- a/arch/arm64/boot/dts/renesas/r8a7796-m3ulcb-kf.dts
++++ b/arch/arm64/boot/dts/renesas/r8a7796-m3ulcb-kf.dts
+@@ -609,6 +609,9 @@
+ compatible = "ovti,ov106xx";
+ reg = <0x60>;
+
++ maxim,fixed-sensor = "ov490";
++ maxim,width = <1280>;
++ maxim,height = <966>;
+ port@0 {
+ ov106xx_in0: endpoint {
+ clock-lanes = <0>;
+@@ -633,6 +636,9 @@
+ compatible = "ovti,ov106xx";
+ reg = <0x61>;
+
++ maxim,fixed-sensor = "ov490";
++ maxim,width = <1280>;
++ maxim,height = <966>;
+ port@0 {
+ ov106xx_in1: endpoint {
+ clock-lanes = <0>;
+@@ -657,6 +663,9 @@
+ compatible = "ovti,ov106xx";
+ reg = <0x62>;
+
++ maxim,fixed-sensor = "ov490";
++ maxim,width = <1280>;
++ maxim,height = <966>;
+ port@0 {
+ ov106xx_in2: endpoint {
+ clock-lanes = <0>;
+@@ -678,6 +687,9 @@
+ compatible = "ovti,ov106xx";
+ reg = <0x63>;
+
++ maxim,fixed-sensor = "ov490";
++ maxim,width = <1280>;
++ maxim,height = <966>;
+ port@0 {
+ ov106xx_in3: endpoint {
+ clock-lanes = <0>;
+@@ -773,8 +785,9 @@
+ maxim,sensor_delay = <350>;
+ maxim,links = <4>;
+ maxim,lanes = <4>;
+- maxim,resetb-gpio = <1>;
+- maxim,fsync-mode = "automatic";
++ maxim,resetb-gpio = <4>;
++ maxim,resetb-active-high;
++ maxim,fsync-mode = "manual";
+ maxim,timeout = <100>;
+
+ port@0 {
+diff --git a/arch/arm64/boot/dts/renesas/r8a7796-m3ulcb-view.dts b/arch/arm64/boot/dts/renesas/r8a7796-m3ulcb-view.dts
+index 1ac0041..8a67c5f 100644
+--- a/arch/arm64/boot/dts/renesas/r8a7796-m3ulcb-view.dts
++++ b/arch/arm64/boot/dts/renesas/r8a7796-m3ulcb-view.dts
+@@ -20,6 +20,9 @@
+ compatible = "ovti,ov106xx";
+ reg = <0x60>;
+
++ maxim,fixed-sensor = "ov490";
++ maxim,width = <1280>;
++ maxim,height = <966>;
+ port@0 {
+ ov106xx_in0: endpoint {
+ clock-lanes = <0>;
+@@ -38,6 +41,9 @@
+ compatible = "ovti,ov106xx";
+ reg = <0x61>;
+
++ maxim,fixed-sensor = "ov490";
++ maxim,width = <1280>;
++ maxim,height = <966>;
+ port@0 {
+ ov106xx_in1: endpoint {
+ clock-lanes = <0>;
+@@ -56,6 +62,9 @@
+ compatible = "ovti,ov106xx";
+ reg = <0x62>;
+
++ maxim,fixed-sensor = "ov490";
++ maxim,width = <1280>;
++ maxim,height = <966>;
+ port@0 {
+ ov106xx_in2: endpoint {
+ clock-lanes = <0>;
+@@ -74,6 +83,9 @@
+ compatible = "ovti,ov106xx";
+ reg = <0x63>;
+
++ maxim,fixed-sensor = "ov490";
++ maxim,width = <1280>;
++ maxim,height = <966>;
+ port@0 {
+ ov106xx_in3: endpoint {
+ clock-lanes = <0>;
+@@ -95,8 +107,9 @@
+ maxim,sensor_delay = <0>;
+ maxim,links = <4>;
+ maxim,lanes = <4>;
+- maxim,resetb-gpio = <1>;
+- maxim,fsync-mode = "automatic";
++ maxim,resetb-gpio = <4>;
++ maxim,resetb-active-high;
++ maxim,fsync-mode = "manual";
+ maxim,timeout = <100>;
+ maxim,i2c-quirk = <0x6c>;
+
+diff --git a/arch/arm64/boot/dts/renesas/r8a7796-salvator-x-view.dts b/arch/arm64/boot/dts/renesas/r8a7796-salvator-x-view.dts
+index cc6866c..ab6e28a 100644
+--- a/arch/arm64/boot/dts/renesas/r8a7796-salvator-x-view.dts
++++ b/arch/arm64/boot/dts/renesas/r8a7796-salvator-x-view.dts
+@@ -35,6 +35,9 @@
+ compatible = "ovti,ov106xx";
+ reg = <0x60>;
+
++ maxim,fixed-sensor = "ov490";
++ maxim,width = <1280>;
++ maxim,height = <966>;
+ port@0 {
+ ov106xx_in0: endpoint {
+ clock-lanes = <0>;
+@@ -53,6 +56,9 @@
+ compatible = "ovti,ov106xx";
+ reg = <0x61>;
+
++ maxim,fixed-sensor = "ov490";
++ maxim,width = <1280>;
++ maxim,height = <966>;
+ port@0 {
+ ov106xx_in1: endpoint {
+ clock-lanes = <0>;
+@@ -71,6 +77,9 @@
+ compatible = "ovti,ov106xx";
+ reg = <0x62>;
+
++ maxim,fixed-sensor = "ov490";
++ maxim,width = <1280>;
++ maxim,height = <966>;
+ port@0 {
+ ov106xx_in2: endpoint {
+ clock-lanes = <0>;
+@@ -89,6 +98,9 @@
+ compatible = "ovti,ov106xx";
+ reg = <0x63>;
+
++ maxim,fixed-sensor = "ov490";
++ maxim,width = <1280>;
++ maxim,height = <966>;
+ port@0 {
+ ov106xx_in3: endpoint {
+ clock-lanes = <0>;
+@@ -110,8 +122,9 @@
+ maxim,sensor_delay = <0>;
+ maxim,links = <4>;
+ maxim,lanes = <4>;
+- maxim,resetb-gpio = <1>;
+- maxim,fsync-mode = "automatic";
++ maxim,resetb-gpio = <4>;
++ maxim,resetb-active-high;
++ maxim,fsync-mode = "manual";
+ maxim,timeout = <100>;
+ maxim,i2c-quirk = <0x6c>;
+
+--
+1.9.1
+
diff --git a/meta-rcar-gen3-adas/recipes-kernel/linux/linux-renesas/0062-IIO-lsm9ds0-add-IMU-driver.patch b/meta-rcar-gen3-adas/recipes-kernel/linux/linux-renesas/0062-IIO-lsm9ds0-add-IMU-driver.patch
new file mode 100644
index 0000000..d3a329f
--- /dev/null
+++ b/meta-rcar-gen3-adas/recipes-kernel/linux/linux-renesas/0062-IIO-lsm9ds0-add-IMU-driver.patch
@@ -0,0 +1,972 @@
+From 4631208dd9557e0183acba14dec79318f9cabdc3 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] 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 | 912 ++++++++++++++++++++++++++++++++++++++++++++++
+ 3 files changed, 925 insertions(+)
+ create mode 100644 drivers/iio/imu/lsm9ds0.c
+
+diff --git a/drivers/iio/imu/Kconfig b/drivers/iio/imu/Kconfig
+index 1f1ad41ef881..063c09b8fc53 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"
+
+ endmenu
+diff --git a/drivers/iio/imu/Makefile b/drivers/iio/imu/Makefile
+index c71bcd30dc38..4de076d0766e 100644
+--- a/drivers/iio/imu/Makefile
++++ b/drivers/iio/imu/Makefile
+@@ -13,6 +13,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 000000000000..15e2671daef9
+--- /dev/null
++++ b/drivers/iio/imu/lsm9ds0.c
+@@ -0,0 +1,912 @@
++/*
++ * 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/iio.h>
++#include <linux/iio/sysfs.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;
++ struct iio_buffer *buffer;
++ 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;
++
++ buffer = iio_kfifo_allocate();
++ if (!buffer) {
++ ret = -ENOMEM;
++ goto error_free_device;
++ }
++ iio_device_attach_buffer(indio_dev, buffer);
++ buffer->scan_timestamp = true;
++ indio_dev->setup_ops = &lsm9ds0_buffer_setup_ops;
++ indio_dev->pollfunc = iio_alloc_pollfunc(NULL,
++ &lsm9ds0_trigger_h,
++ IRQF_ONESHOT,
++ indio_dev,
++ "lsm9ds0_consumer%d",
++ indio_dev->id);
++ if (!indio_dev->pollfunc) {
++ ret = -ENOMEM;
++ goto error_free_buffer;
++ }
++
++ ret = iio_device_register(indio_dev);
++ if (ret < 0)
++ goto error_unconfigure_buffer;
++
++ return 0;
++
++error_unconfigure_buffer:
++ iio_dealloc_pollfunc(indio_dev->pollfunc);
++error_free_buffer:
++ iio_kfifo_free(indio_dev->buffer);
++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.13.0
+
diff --git a/meta-rcar-gen3-adas/recipes-kernel/linux/linux-renesas/0063-ASoC-PCM3168A-add-TDM-modes-merge-ADC-and-DAC.patch b/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 0000000..46d5d84
--- /dev/null
+++ b/meta-rcar-gen3-adas/recipes-kernel/linux/linux-renesas/0063-ASoC-PCM3168A-add-TDM-modes-merge-ADC-and-DAC.patch
@@ -0,0 +1,479 @@
+From 963d9e84748bc43a8dbcd28019bd8ff0942b5934 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] 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 | 320 ++++++++++++++++++++++++++++----------------
+ sound/soc/codecs/pcm3168a.h | 2 +-
+ 2 files changed, 205 insertions(+), 117 deletions(-)
+
+diff --git a/sound/soc/codecs/pcm3168a.c b/sound/soc/codecs/pcm3168a.c
+index 992a77edcd5d..8b9e4ff6b354 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,127 +430,170 @@ 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;
+ snd_pcm_format_t format;
+
+ rate = params_rate(params);
+ format = params_format(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 (i == max_ratio) {
+- dev_err(codec->dev, "unsupported sysclk ratio\n");
+- return -EINVAL;
+- }
++ if (pcm3168a->master_mode) {
++ ratio = pcm3168a->sysclk / rate;
++ for (i = 0; i < max_ratio; i++)
++ if (pcm3168a_scki_ratios[i] == ratio)
++ break;
+
+- 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 (i == max_ratio) {
++ dev_err(codec->dev, "unsupported sysclk ratio: %d\n", ratio);
+ 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");
+- return -EINVAL;
+- }
+- break;
+- case 64:
+- break;
+- default:
+- dev_err(codec->dev, "unsupported frame size: %d\n", min_frame_size);
+- return -EINVAL;
++ val = i + 1;
++ } else {
++ /* slave mode */
++ val = 0;
+ }
+
+- if (master_mode)
+- val = ((i + 1) << shift);
+- else
++ 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;
++ }
++ }
++ 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;
++ }
++ }
++
++ /* 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 56c8332d82fb..658507f86c97 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.13.0
+
diff --git a/meta-rcar-gen3-adas/recipes-kernel/linux/linux-renesas/0064-ADV7511-limit-maximum-pixelclock.patch b/meta-rcar-gen3-adas/recipes-kernel/linux/linux-renesas/0064-ADV7511-limit-maximum-pixelclock.patch
new file mode 100644
index 0000000..3ca9284
--- /dev/null
+++ b/meta-rcar-gen3-adas/recipes-kernel/linux/linux-renesas/0064-ADV7511-limit-maximum-pixelclock.patch
@@ -0,0 +1,76 @@
+From 1df040dabaec1697f81b71f15739b499f3e4266e Mon Sep 17 00:00:00 2001
+From: Andrey Gusakov <andrey.gusakov@cogentembedded.com>
+Date: Fri, 9 Jun 2017 20:12:26 +0300
+Subject: [PATCH] ADV7511: limit maximum pixelclock
+
+DU0 (RGB) supports clock freq up to 100MHz only.
+Add ability to set max clock via dts.
+
+Signed-off-by: Andrey Gusakov <andrey.gusakov@cogentembedded.com>
+---
+ drivers/gpu/drm/bridge/adv7511/adv7511.h | 3 +++
+ drivers/gpu/drm/bridge/adv7511/adv7511_drv.c | 6 +++++-
+ 2 files changed, 8 insertions(+), 1 deletion(-)
+
+diff --git a/drivers/gpu/drm/bridge/adv7511/adv7511.h b/drivers/gpu/drm/bridge/adv7511/adv7511.h
+index 161c923..12ee238 100644
+--- a/drivers/gpu/drm/bridge/adv7511/adv7511.h
++++ b/drivers/gpu/drm/bridge/adv7511/adv7511.h
+@@ -242,6 +242,7 @@ enum adv7511_sync_polarity {
+ * @input_style: The input component arrangement variant
+ * @input_justification: Video input format bit justification
+ * @clock_delay: Clock delay for the input clock (in ps)
++ * @clock_max_rate: Clock maximum rate (in Hz)
+ * @embedded_sync: Video input uses BT.656-style embedded sync
+ * @sync_pulse: Select the sync pulse
+ * @vsync_polarity: vsync input signal configuration
+@@ -255,6 +256,7 @@ struct adv7511_link_config {
+ enum adv7511_input_justification input_justification;
+
+ int clock_delay;
++ int clock_max_rate;
+
+ bool embedded_sync;
+ enum adv7511_input_sync_pulse sync_pulse;
+@@ -307,6 +309,7 @@ struct adv7511 {
+ bool powered;
+
+ struct drm_display_mode curr_mode;
++ int clock_max_rate;
+
+ unsigned int f_tmds;
+
+diff --git a/drivers/gpu/drm/bridge/adv7511/adv7511_drv.c b/drivers/gpu/drm/bridge/adv7511/adv7511_drv.c
+index 41b45de..5dfa619 100644
+--- a/drivers/gpu/drm/bridge/adv7511/adv7511_drv.c
++++ b/drivers/gpu/drm/bridge/adv7511/adv7511_drv.c
+@@ -323,6 +323,7 @@ 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->clock_max_rate = config->clock_max_rate;
+ }
+
+ static void adv7511_power_on(struct adv7511 *adv7511)
+@@ -621,7 +622,7 @@ static int adv7511_get_modes(struct adv7511 *adv7511,
+ static int adv7511_mode_valid(struct adv7511 *adv7511,
+ struct drm_display_mode *mode)
+ {
+- if (mode->clock > 165000)
++ if (mode->clock > adv7511->clock_max_rate)
+ return MODE_CLOCK_HIGH;
+
+ return MODE_OK;
+@@ -917,6 +918,9 @@ static int adv7511_parse_dt(struct device_node *np,
+ if (config->clock_delay < -1200 || config->clock_delay > 1600)
+ return -EINVAL;
+
++ if (of_property_read_u32(np, "adi,clock-max-rate", &config->clock_max_rate))
++ config->clock_max_rate = 166000;
++
+ config->embedded_sync = of_property_read_bool(np, "adi,embedded-sync");
+
+ /* Hardcode the sync pulse configurations for now. */
+--
+1.9.1
+
diff --git a/meta-rcar-gen3-adas/recipes-kernel/linux/linux-renesas/0066-pci-pcie-rcar-add-regulators-support.patch b/meta-rcar-gen3-adas/recipes-kernel/linux/linux-renesas/0066-pci-pcie-rcar-add-regulators-support.patch
new file mode 100644
index 0000000..2a9a2a0
--- /dev/null
+++ b/meta-rcar-gen3-adas/recipes-kernel/linux/linux-renesas/0066-pci-pcie-rcar-add-regulators-support.patch
@@ -0,0 +1,107 @@
+From d5a3dee65f4ee9d320128bbf79df80d51aec7687 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] pci: pcie-rcar: add regulators support
+
+Add PCIE regulators
+
+Signed-off-by: Andrey Gusakov <andrey.gusakov@cogentembedded.com>
+---
+ drivers/pci/host/pcie-rcar.c | 54 ++++++++++++++++++++++++++++++++++++++++++++
+ 1 file changed, 54 insertions(+)
+
+diff --git a/drivers/pci/host/pcie-rcar.c b/drivers/pci/host/pcie-rcar.c
+index 8e24d5f88415..6994ea2ac936 100644
+--- a/drivers/pci/host/pcie-rcar.c
++++ b/drivers/pci/host/pcie-rcar.c
+@@ -16,6 +16,7 @@
+
+ #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>
+@@ -155,6 +156,8 @@ struct rcar_pcie {
+ int root_bus_nr;
+ struct clk *clk;
+ struct clk *bus_clk;
++ struct regulator *pcie3v3; /* 3.3V power supply */
++ struct regulator *pcie1v8; /* 1.8V power supply */
+ struct rcar_msi msi;
+ };
+
+@@ -1193,6 +1196,36 @@ static int rcar_pcie_parse_request_of_pci_ranges(struct rcar_pcie *pci)
+ return err;
+ }
+
++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;
+@@ -1209,6 +1242,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");
++ goto err_set_pcie;
++ }
++
+ INIT_LIST_HEAD(&pcie->resources);
+
+ rcar_pcie_parse_request_of_pci_ranges(pcie);
+@@ -1267,6 +1320,7 @@ static int rcar_pcie_probe(struct platform_device *pdev)
+
+ err_pm_disable:
+ pm_runtime_disable(dev);
++err_set_pcie:
+ return err;
+ }
+
+--
+2.13.0
diff --git a/meta-rcar-gen3-adas/recipes-kernel/linux/linux-renesas/0067-ti-st-use-proper-way-to-get-shutdown-gpio.patch b/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 0000000..4d99054
--- /dev/null
+++ b/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 36a9b5317c58a1cdcb8a6fa05416efd524480fbe 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] 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 cb2734568471..03b21d314b0b 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.13.0
+
diff --git a/meta-rcar-gen3-adas/recipes-kernel/linux/linux-renesas/0068-drm-adv7511-use-smbus-to-retrieve-edid.patch b/meta-rcar-gen3-adas/recipes-kernel/linux/linux-renesas/0068-drm-adv7511-use-smbus-to-retrieve-edid.patch
new file mode 100644
index 0000000..1b4dbd8
--- /dev/null
+++ b/meta-rcar-gen3-adas/recipes-kernel/linux/linux-renesas/0068-drm-adv7511-use-smbus-to-retrieve-edid.patch
@@ -0,0 +1,53 @@
+From 2e2b673a2a47e8358ef92ec4019be87552949304 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] 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 d3ece87..b2e1b58 100644
+--- a/drivers/gpu/drm/bridge/adv7511/adv7511_drv.c
++++ b/drivers/gpu/drm/bridge/adv7511/adv7511_drv.c
+@@ -500,18 +500,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)
+@@ -519,8 +520,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;
+--
+1.9.1
+
diff --git a/meta-rcar-gen3-adas/recipes-kernel/linux/linux-renesas/0070-clk-clk-5p49x-add-5P49V5925-chip.patch b/meta-rcar-gen3-adas/recipes-kernel/linux/linux-renesas/0070-clk-clk-5p49x-add-5P49V5925-chip.patch
new file mode 100644
index 0000000..0608eca
--- /dev/null
+++ b/meta-rcar-gen3-adas/recipes-kernel/linux/linux-renesas/0070-clk-clk-5p49x-add-5P49V5925-chip.patch
@@ -0,0 +1,49 @@
+From d9e198a198e8892ac7e1e2636f55207757ee505a Mon Sep 17 00:00:00 2001
+From: Vladimir Barinov <vladimir.barinov@cogentembedded.com>
+Date: Thu, 10 Aug 2017 08:46:54 +0300
+Subject: [PATCH] clk: clk-5p49x: add 5P49V5925 chip
+
+Add 5P49V5925 chip
+
+Signed-off-by: Vladimir Barinov <vladimir.barinov@cogentembedded.com>
+---
+ drivers/clk/clk-5p49x.c | 9 +++++++++
+ 1 file changed, 9 insertions(+)
+
+diff --git a/drivers/clk/clk-5p49x.c b/drivers/clk/clk-5p49x.c
+index 928bacb..8070154 100644
+--- a/drivers/clk/clk-5p49x.c
++++ b/drivers/clk/clk-5p49x.c
+@@ -60,6 +60,10 @@ struct clk_5p49_priv {
+ .xtal_fre = 25000000,
+ };
+
++static const struct clk_5p49_info clk_5p49v5925 = {
++ .xtal_fre = 25000000,
++};
++
+ static const struct clk_5p49_info clk_5p49v6901a = {
+ .xtal_fre = 50000000,
+ };
+@@ -70,6 +74,10 @@ struct clk_5p49_priv {
+ .data = &clk_5p49v5923a,
+ },
+ {
++ .compatible = "idt,5p49v5925",
++ .data = &clk_5p49v5925,
++ },
++ {
+ .compatible = "idt,5p49v6901a",
+ .data = &clk_5p49v6901a,
+ },
+@@ -79,6 +87,7 @@ struct clk_5p49_priv {
+
+ static const struct i2c_device_id clk_5p49_id[] = {
+ { "5p49v5923a",},
++ { "5p49v5925",},
+ { "5p49v6901a",},
+ {}
+ };
+--
+1.9.1
+
diff --git a/meta-rcar-gen3-adas/recipes-kernel/linux/linux-renesas/0071-ASoC-add-dummy-device-for-WL18xx-PCM-audio.patch b/meta-rcar-gen3-adas/recipes-kernel/linux/linux-renesas/0071-ASoC-add-dummy-device-for-WL18xx-PCM-audio.patch
new file mode 100644
index 0000000..30aebe0
--- /dev/null
+++ b/meta-rcar-gen3-adas/recipes-kernel/linux/linux-renesas/0071-ASoC-add-dummy-device-for-WL18xx-PCM-audio.patch
@@ -0,0 +1,128 @@
+From 81ddd8a5dbf200938ef70efaa9254742f49d3034 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] 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 140f1597966a..6658d05f1648 100644
+--- a/sound/soc/codecs/Kconfig
++++ b/sound/soc/codecs/Kconfig
+@@ -625,6 +625,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 8e02341428d8..17fd313489de 100644
+--- a/sound/soc/codecs/Makefile
++++ b/sound/soc/codecs/Makefile
+@@ -126,6 +126,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
+@@ -349,6 +350,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_SSM2518) += snd-soc-ssm2518.o
+diff --git a/sound/soc/codecs/wl18xx.c b/sound/soc/codecs/wl18xx.c
+new file mode 100644
+index 000000000000..50ebbd4c0013
+--- /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.13.0
+
diff --git a/meta-rcar-gen3-adas/recipes-kernel/linux/linux-renesas/0072-usb-hub-disable-autosuspend-for-SMSC-hubs.patch b/meta-rcar-gen3-adas/recipes-kernel/linux/linux-renesas/0072-usb-hub-disable-autosuspend-for-SMSC-hubs.patch
new file mode 100644
index 0000000..4989e05
--- /dev/null
+++ b/meta-rcar-gen3-adas/recipes-kernel/linux/linux-renesas/0072-usb-hub-disable-autosuspend-for-SMSC-hubs.patch
@@ -0,0 +1,51 @@
+From 8276db72581e4d1e3f89ccce84555c9fea145e16 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] 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 cbb1467..2c4c006 100644
+--- a/drivers/usb/core/hub.c
++++ b/drivers/usb/core/hub.c
+@@ -34,7 +34,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
+@@ -1845,6 +1847,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, endpoint) >= 0)
+ return 0;
+
+@@ -5226,6 +5231,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,
+--
+1.9.1
+
diff --git a/meta-rcar-gen3-adas/recipes-kernel/linux/linux-renesas/0073-MOST-dim2-add-device-tree-support.patch b/meta-rcar-gen3-adas/recipes-kernel/linux/linux-renesas/0073-MOST-dim2-add-device-tree-support.patch
new file mode 100644
index 0000000..b3e2e0b
--- /dev/null
+++ b/meta-rcar-gen3-adas/recipes-kernel/linux/linux-renesas/0073-MOST-dim2-add-device-tree-support.patch
@@ -0,0 +1,169 @@
+From cc64770782e6bb01b2d8b76c1731a28d5d06d135 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] 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 a36449551513..f28f169180fe 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>
+@@ -101,6 +103,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;
+@@ -165,6 +168,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
+@@ -178,32 +202,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);
+@@ -735,6 +739,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)
+@@ -765,6 +770,14 @@ static int dim2_probe(struct platform_device *pdev)
+ dev_err(&pdev->dev, "failed to request mlb_int irq %d\n", irq);
+ 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;
+@@ -814,6 +827,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);
+@@ -866,6 +885,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
+@@ -882,12 +903,19 @@ static 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.13.0
+
diff --git a/meta-rcar-gen3-adas/recipes-kernel/linux/linux-renesas/0074-MOST-dim2-add-R-Car3-related-initialization.patch b/meta-rcar-gen3-adas/recipes-kernel/linux/linux-renesas/0074-MOST-dim2-add-R-Car3-related-initialization.patch
new file mode 100644
index 0000000..572da2a
--- /dev/null
+++ b/meta-rcar-gen3-adas/recipes-kernel/linux/linux-renesas/0074-MOST-dim2-add-R-Car3-related-initialization.patch
@@ -0,0 +1,63 @@
+From 41d15fa6003b65080f05d271bf495104013754f9 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 112/114] MOST: dim2: add R-Car3 related initialization
+
+Signed-off-by: Andrey Gusakov <andrey.gusakov@cogentembedded.com>
+---
+ drivers/staging/most/hdm-dim2/dim2_hdm.c | 28 +++++++++++++++++++++++++++-
+ 1 file changed, 27 insertions(+), 1 deletion(-)
+
+diff --git a/drivers/staging/most/hdm-dim2/dim2_hdm.c b/drivers/staging/most/hdm-dim2/dim2_hdm.c
+index f28f169180fe..c1beabc28fa8 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 <networking.h>
+@@ -189,6 +191,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
+@@ -216,6 +238,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.13.0
+
diff --git a/meta-rcar-gen3-adas/recipes-kernel/linux/linux-renesas/0075-MOST-core-fix-memory-allocation-at-arm64.patch b/meta-rcar-gen3-adas/recipes-kernel/linux/linux-renesas/0075-MOST-core-fix-memory-allocation-at-arm64.patch
new file mode 100644
index 0000000..33a7c3a
--- /dev/null
+++ b/meta-rcar-gen3-adas/recipes-kernel/linux/linux-renesas/0075-MOST-core-fix-memory-allocation-at-arm64.patch
@@ -0,0 +1,54 @@
+From 90bfbf16c895aa53e1d017d4ce7f4f8121e0da3c 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 113/114] 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 c1beabc28fa8..81edf4f4beb3 100644
+--- a/drivers/staging/most/hdm-dim2/dim2_hdm.c
++++ b/drivers/staging/most/hdm-dim2/dim2_hdm.c
+@@ -852,6 +852,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 7c619feb12d3..ce56d5ca582c 100644
+--- a/drivers/staging/most/mostcore/core.c
++++ b/drivers/staging/most/mostcore/core.c
+@@ -1265,7 +1265,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 60e018e499ef..334908639067 100644
+--- a/drivers/staging/most/mostcore/mostcore.h
++++ b/drivers/staging/most/mostcore/mostcore.h
+@@ -247,6 +247,7 @@ struct most_interface {
+ struct mbo *mbo);
+ int (*poison_channel)(struct most_interface *iface, int channel_idx);
+ void (*request_netinfo)(struct most_interface *iface, int channel_idx);
++ struct device *dev;
+ void *priv;
+ };
+
+--
+2.13.0
+
diff --git a/meta-rcar-gen3-adas/recipes-kernel/linux/linux-renesas/0076-MOST-dim2-Renesas-R-Car3-variant.patch b/meta-rcar-gen3-adas/recipes-kernel/linux/linux-renesas/0076-MOST-dim2-Renesas-R-Car3-variant.patch
new file mode 100644
index 0000000..5ab496b
--- /dev/null
+++ b/meta-rcar-gen3-adas/recipes-kernel/linux/linux-renesas/0076-MOST-dim2-Renesas-R-Car3-variant.patch
@@ -0,0 +1,120 @@
+From d595053486568b5be30fda582becf9240d171c66 Mon Sep 17 00:00:00 2001
+From: Andrey Gusakov <andrey.gusakov@cogentembedded.com>
+Date: Mon, 25 Sep 2017 7:16:25 +0300
+Subject: [PATCH] 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 0b9816c..231138c 100644
+--- a/drivers/staging/most/hdm-dim2/dim2_hal.c
++++ b/drivers/staging/most/hdm-dim2/dim2_hal.c
+@@ -528,11 +528,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)
+@@ -548,7 +548,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));
+@@ -778,7 +778,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 195efff..84f56c9 100644
+--- a/drivers/staging/most/hdm-dim2/dim2_hdm.c
++++ b/drivers/staging/most/hdm-dim2/dim2_hdm.c
+@@ -54,7 +54,7 @@
+ * 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, 0);
+ 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 01fe499..54e9b6e 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)))
+--
+1.9.1
+
diff --git a/meta-rcar-gen3-adas/recipes-kernel/linux/linux-renesas/0077-MOST-dim2-add-timeouts.patch b/meta-rcar-gen3-adas/recipes-kernel/linux/linux-renesas/0077-MOST-dim2-add-timeouts.patch
new file mode 100644
index 0000000..d47c5c6
--- /dev/null
+++ b/meta-rcar-gen3-adas/recipes-kernel/linux/linux-renesas/0077-MOST-dim2-add-timeouts.patch
@@ -0,0 +1,46 @@
+From f02aa2831e169a9f17eebb2784db4c95944ba927 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] 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 231138c..ee0e307 100644
+--- a/drivers/staging/most/hdm-dim2/dim2_hal.c
++++ b/drivers/staging/most/hdm-dim2/dim2_hal.c
+@@ -18,6 +18,7 @@
+ #include "dim2_errors.h"
+ #include "dim2_reg.h"
+ #include <linux/stddef.h>
++#include <linux/delay.h>
+
+ /*
+ * Size factor for isochronous DBR buffer.
+@@ -148,11 +149,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 */
+ }
+--
+1.9.1
+
diff --git a/meta-rcar-gen3-adas/recipes-kernel/linux/linux-renesas/0078-MOST-aim-fix-null-pointer-crash.patch b/meta-rcar-gen3-adas/recipes-kernel/linux/linux-renesas/0078-MOST-aim-fix-null-pointer-crash.patch
new file mode 100644
index 0000000..fd66258
--- /dev/null
+++ b/meta-rcar-gen3-adas/recipes-kernel/linux/linux-renesas/0078-MOST-aim-fix-null-pointer-crash.patch
@@ -0,0 +1,29 @@
+From f3c2f6f40c2b3e43a447c89b523de40ce2211e91 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] 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 e4198e5..a2ccc79 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;
+--
+1.9.1
+
diff --git a/meta-rcar-gen3-adas/recipes-kernel/linux/linux-renesas/0079-Revert-dmaengine-rcar-dmac-use-TCRB-instead-of-TCR-f.patch b/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 0000000..97409fa
--- /dev/null
+++ b/meta-rcar-gen3-adas/recipes-kernel/linux/linux-renesas/0079-Revert-dmaengine-rcar-dmac-use-TCRB-instead-of-TCR-f.patch
@@ -0,0 +1,29 @@
+From b3026b3a8ddcd9801583aa5e653ef432fbe60bf0 Mon Sep 17 00:00:00 2001
+From: Vladimir Barinov <vladimir.barinov@cogentembedded.com>
+Date: Mon, 4 Dec 2017 17:49:47 +0300
+Subject: [PATCH] Revert "dmaengine: rcar-dmac: use TCRB instead of TCR for
+ residue"
+
+The patch breaks SCIF DMA support
+
+This reverts commit 936abcc1d0b13ff4a112b153e56c0e60bbdc0f5f.
+---
+ 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 9120ff4..0ae7131 100644
+--- a/drivers/dma/sh/rcar-dmac.c
++++ b/drivers/dma/sh/rcar-dmac.c
+@@ -1298,7 +1298,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;
+ }
+--
+1.9.1
+
diff --git a/meta-rcar-gen3-adas/recipes-kernel/linux/linux-renesas/0080-dmaengine-rcar-dmac-ensure-CHCR-DE-bit-is-actually-0.patch b/meta-rcar-gen3-adas/recipes-kernel/linux/linux-renesas/0080-dmaengine-rcar-dmac-ensure-CHCR-DE-bit-is-actually-0.patch
new file mode 100644
index 0000000..e1597ea
--- /dev/null
+++ b/meta-rcar-gen3-adas/recipes-kernel/linux/linux-renesas/0080-dmaengine-rcar-dmac-ensure-CHCR-DE-bit-is-actually-0.patch
@@ -0,0 +1,87 @@
+From a8d46a7f5d17ca9cbe9e9c7d1d23dc6ea437e141 Mon Sep 17 00:00:00 2001
+From: Kuninori Morimoto <kuninori.morimoto.gx@renesas.com>
+Date: Fri, 17 Nov 2017 11:00:28 +0900
+Subject: [PATCH 1/2] dmaengine: rcar-dmac: ensure CHCR DE bit is actually 0
+ after clearing
+
+DMAC reads data from source device, and buffered it until transferable
+size for sink device. Because of this behavior, DMAC is including
+buffered data .
+
+Now, CHCR DE bit is controlling DMA transfer enable/disable.
+
+If DE bit was cleared during data transferring, or during buffering,
+it will flush buffered data if source device was peripheral device
+(The buffered data will be removed if source device was memory).
+Because of this behavior, driver should ensure that DE bit is actually
+0 after clearing.
+
+This patch adds new rcar_dmac_chcr_de_barrier() and call it after CHCR
+register access.
+
+Signed-off-by: Kuninori Morimoto <kuninori.morimoto.gx@renesas.com>
+Tested-by: Hiroyuki Yokoyama <hiroyuki.yokoyama.vx@renesas.com>
+Tested-by: Ryo Kodama <ryo.kodama.vz@renesas.com>
+Tested-by: Geert Uytterhoeven <geert+renesas@glider.be>
+Signed-off-by: Vinod Koul <vinod.koul@intel.com>
+---
+ drivers/dma/sh/rcar-dmac.c | 22 ++++++++++++++++++++++
+ 1 file changed, 22 insertions(+)
+
+diff --git a/drivers/dma/sh/rcar-dmac.c b/drivers/dma/sh/rcar-dmac.c
+index 2b2c7db..c99fd0f 100644
+--- a/drivers/dma/sh/rcar-dmac.c
++++ b/drivers/dma/sh/rcar-dmac.c
+@@ -10,6 +10,7 @@
+ * published by the Free Software Foundation.
+ */
+
++#include <linux/delay.h>
+ #include <linux/dma-mapping.h>
+ #include <linux/dmaengine.h>
+ #include <linux/interrupt.h>
+@@ -741,6 +742,24 @@ static int rcar_dmac_fill_hwdesc(struct rcar_dmac_chan *chan,
+ /* -----------------------------------------------------------------------------
+ * Stop and reset
+ */
++static void rcar_dmac_chcr_de_barrier(struct rcar_dmac_chan *chan)
++{
++ u32 chcr;
++ unsigned int i;
++
++ /*
++ * Ensure that the setting of the DE bit is actually 0 after
++ * clearing it.
++ */
++ for (i = 0; i < 1024; i++) {
++ chcr = rcar_dmac_chan_read(chan, RCAR_DMACHCR);
++ if (!(chcr & RCAR_DMACHCR_DE))
++ return;
++ udelay(1);
++ }
++
++ dev_err(chan->chan.device->dev, "CHCR DE check error\n");
++}
+
+ static void rcar_dmac_chan_halt(struct rcar_dmac_chan *chan)
+ {
+@@ -749,6 +768,7 @@ static void rcar_dmac_chan_halt(struct rcar_dmac_chan *chan)
+ chcr &= ~(RCAR_DMACHCR_DSE | RCAR_DMACHCR_DSIE | RCAR_DMACHCR_IE |
+ RCAR_DMACHCR_TE | RCAR_DMACHCR_DE);
+ rcar_dmac_chan_write(chan, RCAR_DMACHCR, chcr);
++ rcar_dmac_chcr_de_barrier(chan);
+ }
+
+ static void rcar_dmac_chan_reinit(struct rcar_dmac_chan *chan)
+@@ -1481,6 +1501,8 @@ static irqreturn_t rcar_dmac_isr_channel(int irq, void *dev)
+ if (chcr & RCAR_DMACHCR_TE)
+ mask |= RCAR_DMACHCR_DE;
+ rcar_dmac_chan_write(chan, RCAR_DMACHCR, chcr & ~mask);
++ if (mask & RCAR_DMACHCR_DE)
++ rcar_dmac_chcr_de_barrier(chan);
+
+ if (chcr & RCAR_DMACHCR_DSE)
+ ret |= rcar_dmac_isr_desc_stage_end(chan);
+--
+1.9.1
+
diff --git a/meta-rcar-gen3-adas/recipes-kernel/linux/linux-renesas/0081-dmaengine-rcar-dmac-use-TCRB-instead-of-TCR-for-resi.patch b/meta-rcar-gen3-adas/recipes-kernel/linux/linux-renesas/0081-dmaengine-rcar-dmac-use-TCRB-instead-of-TCR-for-resi.patch
new file mode 100644
index 0000000..c9bfdfb
--- /dev/null
+++ b/meta-rcar-gen3-adas/recipes-kernel/linux/linux-renesas/0081-dmaengine-rcar-dmac-use-TCRB-instead-of-TCR-for-resi.patch
@@ -0,0 +1,108 @@
+From 73a47bd0da668c99f04e9076f2b02101a5b2749b Mon Sep 17 00:00:00 2001
+From: Kuninori Morimoto <kuninori.morimoto.gx@renesas.com>
+Date: Fri, 17 Nov 2017 02:09:32 +0000
+Subject: [PATCH 2/2] dmaengine: rcar-dmac: use TCRB instead of TCR for residue
+
+SYS/RT/Audio DMAC includes independent data buffers for reading
+and writing. Therefore, the read transfer counter and write transfer
+counter have different values.
+TCR indicates read counter, and TCRB indicates write counter.
+The relationship is like below.
+
+ TCR TCRB
+ [SOURCE] -> [DMAC] -> [SINK]
+
+In the MEM_TO_DEV direction, what really matters is how much data has
+been written to the device. If the DMA is interrupted between read and
+write, then, the data doesn't end up in the destination, so shouldn't
+be counted. TCRB is thus the register we should use in this cases.
+
+In the DEV_TO_MEM direction, the situation is more complex. Both the
+read and write side are important. What matters from a data consumer
+point of view is how much data has been written to memory.
+On the other hand, if the transfer is interrupted between read and
+write, we'll end up losing data. It can also be important to report.
+
+In the MEM_TO_MEM direction, what matters is of course how much data
+has been written to memory from data consumer point of view.
+Here, because read and write have independent data buffers, it will
+take a while for TCR and TCRB to become equal. Thus we should check
+TCRB in this case, too.
+
+Thus, all cases we should check TCRB instead of TCR.
+
+Without this patch, Sound Capture has noise after PulseAudio support
+(= 07b7acb51d2 ("ASoC: rsnd: update pointer more accurate")), because
+the recorder will use wrong residue counter which indicates transferred
+from sound device, but in reality the data was not yet put to memory
+and recorder will record it.
+
+However, because DMAC is buffering data until it can be transferable
+size, TCRB might not be updated.
+For example, if consumer doesn't know how much data can be received,
+it requests enough size to DMAC. But in reality, it might receive very
+few data. In such case, DMAC just buffered it until transferable size,
+and no TCRB updated.
+
+In such case, this buffered data will be transferred if CHCR::DE bit was
+cleared, and this is happen if rcar_dmac_chan_halt(). In other word, it
+happen when consumer called dmaengine_terminate_all().
+
+Because of this behavior, it need to flush buffered data when it returns
+"residue" (= dmaengine_tx_status()).
+Otherwise, consumer might calculate wrong things if it called
+dmaengine_tx_status() and dmaengine_terminate_all() consecutively.
+
+Signed-off-by: Kuninori Morimoto <kuninori.morimoto.gx@renesas.com>
+Tested-by: Hiroyuki Yokoyama <hiroyuki.yokoyama.vx@renesas.com>
+Tested-by: Ryo Kodama <ryo.kodama.vz@renesas.com>
+Tested-by: Geert Uytterhoeven <geert+renesas@glider.be>
+Signed-off-by: Vinod Koul <vinod.koul@intel.com>
+---
+ drivers/dma/sh/rcar-dmac.c | 22 +++++++++++++++++++++-
+ 1 file changed, 21 insertions(+), 1 deletion(-)
+
+diff --git a/drivers/dma/sh/rcar-dmac.c b/drivers/dma/sh/rcar-dmac.c
+index c99fd0f..3bbd11d 100644
+--- a/drivers/dma/sh/rcar-dmac.c
++++ b/drivers/dma/sh/rcar-dmac.c
+@@ -761,6 +761,23 @@ static void rcar_dmac_chcr_de_barrier(struct rcar_dmac_chan *chan)
+ dev_err(chan->chan.device->dev, "CHCR DE check error\n");
+ }
+
++static void rcar_dmac_sync_tcr(struct rcar_dmac_chan *chan)
++{
++ u32 chcr = rcar_dmac_chan_read(chan, RCAR_DMACHCR);
++
++ if (!(chcr & RCAR_DMACHCR_DE))
++ return;
++
++ /* set DE=0 and flush remaining data */
++ rcar_dmac_chan_write(chan, RCAR_DMACHCR, (chcr & ~RCAR_DMACHCR_DE));
++
++ /* make sure all remaining data was flushed */
++ rcar_dmac_chcr_de_barrier(chan);
++
++ /* back DE */
++ rcar_dmac_chan_write(chan, RCAR_DMACHCR, chcr);
++}
++
+ static void rcar_dmac_chan_halt(struct rcar_dmac_chan *chan)
+ {
+ u32 chcr = rcar_dmac_chan_read(chan, RCAR_DMACHCR);
+@@ -1329,8 +1346,11 @@ static unsigned int rcar_dmac_chan_get_residue(struct rcar_dmac_chan *chan,
+ residue += chunk->size;
+ }
+
++ if (desc->direction == DMA_DEV_TO_MEM)
++ rcar_dmac_sync_tcr(chan);
++
+ /* Add the residue for the current chunk. */
+- residue += rcar_dmac_chan_read(chan, RCAR_DMATCR) << desc->xfer_shift;
++ residue += rcar_dmac_chan_read(chan, RCAR_DMATCRB) << desc->xfer_shift;
+
+ return residue;
+ }
+--
+1.9.1
+
diff --git a/meta-rcar-gen3-adas/recipes-kernel/linux/linux-renesas/0100-LVDS-ar0132-use-raw12.patch b/meta-rcar-gen3-adas/recipes-kernel/linux/linux-renesas/0100-LVDS-ar0132-use-raw12.patch
new file mode 100644
index 0000000..7822b35
--- /dev/null
+++ b/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/meta-rcar-gen3-adas/recipes-kernel/linux/linux-renesas/0101-LVDS-ar0132-use-context-swwitch.patch b/meta-rcar-gen3-adas/recipes-kernel/linux/linux-renesas/0101-LVDS-ar0132-use-context-swwitch.patch
new file mode 100644
index 0000000..00b62e8
--- /dev/null
+++ b/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/meta-rcar-gen3-adas/recipes-kernel/linux/linux-renesas/0103-gpu-drm-rcar-du-Extend-VSP1-DRM-interface.patch b/meta-rcar-gen3-adas/recipes-kernel/linux/linux-renesas/0103-gpu-drm-rcar-du-Extend-VSP1-DRM-interface.patch
new file mode 100644
index 0000000..e3f24a6
--- /dev/null
+++ b/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/meta-rcar-gen3-adas/recipes-kernel/linux/linux-renesas/0104-media-vsp1-extend-DRM-VSP1-interface.patch b/meta-rcar-gen3-adas/recipes-kernel/linux/linux-renesas/0104-media-vsp1-extend-DRM-VSP1-interface.patch
new file mode 100644
index 0000000..2f6fa35
--- /dev/null
+++ b/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/meta-rcar-gen3-adas/recipes-kernel/linux/linux-renesas/0105-media-rcar-imr-IMR-driver-updates-for-raw-DL.patch b/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 0000000..42d2e32
--- /dev/null
+++ b/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/meta-rcar-gen3-adas/recipes-kernel/linux/linux-renesas/eagle.cfg b/meta-rcar-gen3-adas/recipes-kernel/linux/linux-renesas/eagle.cfg
new file mode 100644
index 0000000..9796ba5
--- /dev/null
+++ b/meta-rcar-gen3-adas/recipes-kernel/linux/linux-renesas/eagle.cfg
@@ -0,0 +1,29 @@
+CONFIG_ARCH_R8A7797=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_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_MAX9271=y
+CONFIG_SOC_CAMERA_OV106XX=y
+CONFIG_VIDEO_RENESAS_IMR=y
+CONFIG_INPUT_TOUCHSCREEN=y
+CONFIG_TOUCHSCREEN_PROPERTIES=y
+CONFIG_HID_MULTITOUCH=y
+CONFIG_SERIAL_SH_SCI_DMA=y
+CONFIG_UIO=y
diff --git a/meta-rcar-gen3-adas/recipes-kernel/linux/linux-renesas/hyperflash.cfg b/meta-rcar-gen3-adas/recipes-kernel/linux/linux-renesas/hyperflash.cfg
new file mode 100644
index 0000000..df45d5e
--- /dev/null
+++ b/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/meta-rcar-gen3-adas/recipes-kernel/linux/linux-renesas/salvator-x.cfg b/meta-rcar-gen3-adas/recipes-kernel/linux/linux-renesas/salvator-x.cfg
new file mode 100644
index 0000000..a42b74c
--- /dev/null
+++ b/meta-rcar-gen3-adas/recipes-kernel/linux/linux-renesas/salvator-x.cfg
@@ -0,0 +1,32 @@
+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_EXTRA_FIRMWARE="r8a779x_usb3_v2.dlmem"
+CONFIG_EXTRA_FIRMWARE_DIR="firmware"
+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_MAX9271=y
+CONFIG_SOC_CAMERA_OV106XX=y
+CONFIG_USB_XHCI_HCD=y
+CONFIG_USB_XHCI_PLATFORM=y
+CONFIG_USB_XHCI_RCAR=y
+CONFIG_MMC_SDHI_PRE_REQ=y
+CONFIG_MMC_SDHI_SEQ=y
+CONFIG_VIDEO_RENESAS_IMR=y
+CONFIG_INPUT_TOUCHSCREEN=y
+CONFIG_TOUCHSCREEN_PROPERTIES=y
+CONFIG_HID_MULTITOUCH=y
+CONFIG_SERIAL_SH_SCI_DMA=y
+CONFIG_UIO=y
diff --git a/meta-rcar-gen3-adas/recipes-kernel/linux/linux-renesas/sdhi_seq.cfg b/meta-rcar-gen3-adas/recipes-kernel/linux/linux-renesas/sdhi_seq.cfg
new file mode 100644
index 0000000..9c43599
--- /dev/null
+++ b/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/meta-rcar-gen3-adas/recipes-kernel/linux/linux-renesas/ulcb.cfg b/meta-rcar-gen3-adas/recipes-kernel/linux/linux-renesas/ulcb.cfg
new file mode 100644
index 0000000..5b637e2
--- /dev/null
+++ b/meta-rcar-gen3-adas/recipes-kernel/linux/linux-renesas/ulcb.cfg
@@ -0,0 +1,82 @@
+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_EXTRA_FIRMWARE="r8a779x_usb3_v2.dlmem r8a779x_usb3_v3.dlmem"
+CONFIG_EXTRA_FIRMWARE_DIR="firmware"
+CONFIG_BLK_DEV_NVME=m
+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_MAX9271=y
+CONFIG_SOC_CAMERA_TI964_TI9X3=y
+CONFIG_SOC_CAMERA_TI954_TI9X3=y
+CONFIG_SOC_CAMERA_OV106XX=y
+CONFIG_SOC_CAMERA_OV5647=y
+CONFIG_SOC_CAMERA_OV5642=y
+CONFIG_USB_XHCI_HCD=y
+CONFIG_USB_XHCI_PLATFORM=y
+CONFIG_USB_XHCI_RCAR=y
+CONFIG_USB_ACM=y
+CONFIG_VIDEO_RENESAS_IMR=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_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=y
+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_MMC_SDHI_SEQ_WORKAROUND=y
diff --git a/meta-rcar-gen3-adas/recipes-kernel/linux/linux-renesas/v3msk.cfg b/meta-rcar-gen3-adas/recipes-kernel/linux/linux-renesas/v3msk.cfg
new file mode 100644
index 0000000..211da49
--- /dev/null
+++ b/meta-rcar-gen3-adas/recipes-kernel/linux/linux-renesas/v3msk.cfg
@@ -0,0 +1,33 @@
+CONFIG_ARCH_R8A7797=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_MAX9271=y
+CONFIG_SOC_CAMERA_TI964_TI9X3=y
+CONFIG_SOC_CAMERA_TI954_TI9X3=y
+CONFIG_SOC_CAMERA_OV106XX=y
+CONFIG_VIDEO_RENESAS_IMR=y
+CONFIG_INPUT_TOUCHSCREEN=y
+CONFIG_TOUCHSCREEN_PROPERTIES=y
+CONFIG_HID_MULTITOUCH=y
+CONFIG_SERIAL_SH_SCI_DMA=y
+CONFIG_UIO=y
diff --git a/meta-rcar-gen3-adas/recipes-kernel/linux/linux-renesas_4.9.bbappend b/meta-rcar-gen3-adas/recipes-kernel/linux/linux-renesas_4.9.bbappend
new file mode 100644
index 0000000..924e309
--- /dev/null
+++ b/meta-rcar-gen3-adas/recipes-kernel/linux/linux-renesas_4.9.bbappend
@@ -0,0 +1,133 @@
+FILESEXTRAPATHS_prepend := "${THISDIR}/${PN}:"
+
+COMPATIBLE_MACHINE_eagle = "eagle"
+COMPATIBLE_MACHINE_v3msk = "v3msk"
+
+BRANCH = "v4.9/rcar-3.5.9"
+SRCREV = "2c20c9881d53f1b5c7a3ebf55bb83ec15902d0d0"
+
+SRC_URI_remove = " \
+ file://0001-dmaengine-rcar-dmac-ensure-CHCR-DE-bit-is-actually-0.patch \
+ file://0002-dmaengine-rcar-dmac-use-TCRB-instead-of-TCR-for-resi.patch \
+"
+
+SRC_URI_append = " \
+ ${@bb.utils.contains('MACHINE_FEATURES', 'h3ulcb-had', ' file://hyperflash.cfg', '', d)} \
+ ${@base_conditional("SDHI_SEQ", "1", " file://sdhi_seq.cfg", "", d)} \
+ file://0001-spi-sh-msiof-fixes.patch \
+ file://0002-spi-spidev-add-spi-gpio-into-spidev.patch \
+ file://0003-spi-spi-gpio-fix-CPOL-mode.patch \
+ file://0004-xhci-rcar-add-firmware-for-R-Car-H2-M2-USB-3.0-host-.patch \
+ file://0005-usb-host-xhci-plat-add-support-for-the-R-Car-H3-xHCI.patch \
+ file://0006-spi-spi-gpio-fix-set-CPOL-default-inverted.patch \
+ file://0008-arm64-do-not-set-dma-masks-that-device-connection-ca.patch \
+ file://0009-swiotlb-ensure-that-page-sized-mappings-are-page-ali.patch \
+ file://0010-can-rcar_can-add-enable-and-standby-control-pins.patch \
+ file://0011-can-rcar_canfd-add-enable-and-standby-control-pins.patch \
+ file://0012-mtd-Add-RPC-HyperFlash-driver.patch \
+ file://0013-IMR-driver-interim-patch.patch \
+ file://0014-lib-swiotlb-reduce-verbosity.patch \
+ file://0015-gpio-max732x-fix-gpio-set.patch \
+ file://0016-gpio-gpiolib-suppress-gpiod-warning.patch \
+ file://0017-media-soc_camera-add-legacy-VIN-CSI2.patch \
+ file://0018-arm64-renesas-r8a7797-Add-Renesas-R8A7797-SoC-suppor.patch \
+ file://0019-Revert-media-v4l2-async-remove-unneeded-.registered_.patch \
+ file://0020-ti-st-add-device-tree-support.patch \
+ file://0021-btwilink-add-minimal-device-tree-support.patch \
+ file://0022-ASoC-Modify-check-condition-of-multiple-bindings-of-.patch \
+ file://0023-ASoC-add-dummy-Si468x-driver.patch \
+ file://0024-wl18xx-do-not-invert-IRQ-on-WLxxxx-side.patch \
+ file://0025-drm-adv7511-Enable-HPD-interrupts-to-support-hotplug.patch \
+ file://0026-drm-adv7511-add-polling-mode-when-no-irq-available.patch \
+ file://0027-usb-host-xhci-plat-add-firmware-for-the-R-Car-M3-W-x.patch \
+ file://0028-usb-host-xhci-rcar-update-firmware-for-R-Car-H3-and-.patch \
+ file://0029-i2c-mux-pca954x-fix-i2c-mux-selection-caching.patch \
+ file://0030-Gen3-LVDS-cameras.patch \
+ file://0031-media-i2c-Add-ov5647-sensor.patch \
+ file://0032-media-i2c-Add-ov5642-sensor.patch \
+ file://0033-media-soc-camera-fix-parallel-i-f-in-VIN.patch \
+ file://0034-media-soc_camera-Fix-VIDIOC_S_SELECTION-ioctl-miscal.patch \
+ file://0035-regulator-fixed-probe-after-i2c.patch \
+ file://0040-arm64-dts-renesas-add-ADAS-boards.patch \
+ file://0041-arm64-dts-renesas-ulcb-enlarge-cma-region.patch \
+ file://0042-arm64-dts-renesas-r8a7795-es1-h3ulcb-disable-eMMC.patch \
+ file://0043-arm64-dts-renesas-ulcb-use-versaclock-for-du-rgb-and-lvds.patch \
+ file://0044-pinctrl-r8a779x-add-mlb-pinmux.patch \
+ file://0045-clk-r8a779x-add-mlp-clock.patch \
+ file://0046-arm64-dts-renesas-r8a779x-add-mlp-nodes.patch \
+ ${@base_conditional("KF_ENABLE_SD3", "1", " file://0047-arm64-dts-renesas-ulcb-kf-enable-sd3.patch", "", d)} \
+ ${@base_conditional("KF_ENABLE_MOST", "1", " file://0048-arm64-dts-renesas-ulcb-kf-enable-most.patch", "", d)} \
+ file://0049-clk-r8a779x-add-IMP-clock.patch \
+ file://0050-arm64-dts-renesas-r8a779x-add-IMP-nodes.patch \
+ ${@base_conditional("LVDSCAMERA_FIRST4_TYPE1", "1", " file://0050-arm64-dts-Gen3-view-boards-TYPE1-first-4-cameras.patch", "", d)} \
+ ${@base_conditional("LVDSCAMERA_SECOND4_TYPE1", "1", " file://0051-arm64-dts-Gen3-view-boards-TYPE1-second-4-cameras.patch", "", d)} \
+ ${@base_conditional("LVDSCAMERA_FIRST4_TYPE2", "1", " file://0052-arm64-dts-Gen3-view-boards-TYPE2-first-4-cameras.patch", "", d)} \
+ file://0062-IIO-lsm9ds0-add-IMU-driver.patch \
+ file://0063-ASoC-PCM3168A-add-TDM-modes-merge-ADC-and-DAC.patch \
+ file://0064-ADV7511-limit-maximum-pixelclock.patch \
+ file://0066-pci-pcie-rcar-add-regulators-support.patch \
+ file://0067-ti-st-use-proper-way-to-get-shutdown-gpio.patch \
+ file://0068-drm-adv7511-use-smbus-to-retrieve-edid.patch \
+ file://0070-clk-clk-5p49x-add-5P49V5925-chip.patch \
+ file://0071-ASoC-add-dummy-device-for-WL18xx-PCM-audio.patch \
+ file://0072-usb-hub-disable-autosuspend-for-SMSC-hubs.patch \
+ file://0073-MOST-dim2-add-device-tree-support.patch \
+ file://0074-MOST-dim2-add-R-Car3-related-initialization.patch \
+ file://0075-MOST-core-fix-memory-allocation-at-arm64.patch \
+ file://0076-MOST-dim2-Renesas-R-Car3-variant.patch \
+ file://0077-MOST-dim2-add-timeouts.patch \
+ file://0078-MOST-aim-fix-null-pointer-crash.patch \
+ file://0079-Revert-dmaengine-rcar-dmac-use-TCRB-instead-of-TCR-f.patch \
+ file://0080-dmaengine-rcar-dmac-ensure-CHCR-DE-bit-is-actually-0.patch \
+ file://0081-dmaengine-rcar-dmac-use-TCRB-instead-of-TCR-for-resi.patch \
+ file://0001-arm64-dts-renesas-preserve-drm-HDMI-connector-naming.patch \
+"
+
+SRC_URI_append_r8a7797 = " \
+ file://0103-gpu-drm-rcar-du-Extend-VSP1-DRM-interface.patch \
+ file://0104-media-vsp1-extend-DRM-VSP1-interface.patch \
+ file://0105-media-rcar-imr-IMR-driver-updates-for-raw-DL.patch \
+"
+
+SRC_URI_append_h3ulcb = " file://ulcb.cfg"
+SRC_URI_append_m3ulcb = " 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"
+
+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-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-vb.dtb \
+ renesas/r8a7795-h3ulcb-vbm.dtb \
+"
+
+KERNEL_DEVICETREE_append_m3ulcb = " \
+ renesas/r8a7796-m3ulcb-view.dtb \
+ renesas/r8a7796-m3ulcb-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/r8a7797-eagle.dtb \
+"
+
+KERNEL_DEVICETREE_append_v3msk = " \
+ renesas/r8a7797-v3msk.dtb \
+ renesas/r8a7797-v3msk-kf.dtb \
+ renesas/r8a7797-v3msk-vbm.dtb \
+ renesas/r8a7797-v3msk-view.dtb \
+"
diff --git a/meta-rcar-gen3-adas/recipes-multimedia/gstreamer/gstreamer1.0-plugin-vspfilter_1.0.0.bbappend b/meta-rcar-gen3-adas/recipes-multimedia/gstreamer/gstreamer1.0-plugin-vspfilter_1.0.0.bbappend
new file mode 100644
index 0000000..d13853c
--- /dev/null
+++ b/meta-rcar-gen3-adas/recipes-multimedia/gstreamer/gstreamer1.0-plugin-vspfilter_1.0.0.bbappend
@@ -0,0 +1 @@
+COMPATIBLE_MACHINE = "r8a7795|r8a7796"
diff --git a/meta-rcar-gen3-adas/recipes-multimedia/gstreamer/gstreamer1.0-plugins-bad-1.6.3/0001-install-wayland.h-header.patch b/meta-rcar-gen3-adas/recipes-multimedia/gstreamer/gstreamer1.0-plugins-bad-1.6.3/0001-install-wayland.h-header.patch
new file mode 100644
index 0000000..c8a5784
--- /dev/null
+++ b/meta-rcar-gen3-adas/recipes-multimedia/gstreamer/gstreamer1.0-plugins-bad-1.6.3/0001-install-wayland.h-header.patch
@@ -0,0 +1,33 @@
+From 688a7bfe44a3ca9029fccdb1f7bfdd405927dade Mon Sep 17 00:00:00 2001
+From: Grigory Kletsko <grigory.kletsko@cogentembedded.com>
+Date: Thu, 5 May 2016 15:55:55 +0300
+Subject: [PATCH] install wayland.h header
+
+---
+ gst-libs/gst/wayland/Makefile.am | 6 ++----
+ 1 file changed, 2 insertions(+), 4 deletions(-)
+
+diff --git a/gst-libs/gst/wayland/Makefile.am b/gst-libs/gst/wayland/Makefile.am
+index 0344598..487ba6a 100644
+--- a/gst-libs/gst/wayland/Makefile.am
++++ b/gst-libs/gst/wayland/Makefile.am
+@@ -5,6 +5,8 @@ libgstwayland_@GST_API_VERSION@_la_SOURCES = wayland.c
+ libgstwayland_@GST_API_VERSION@includedir = \
+ $(includedir)/gstreamer-@GST_API_VERSION@/gst/wayland
+
++libgstwayland_@GST_API_VERSION@include_HEADERS = wayland.h
++
+ libgstwayland_@GST_API_VERSION@_la_CFLAGS = \
+ $(GST_PLUGINS_BAD_CFLAGS) \
+ $(GST_PLUGINS_BASE_CFLAGS) \
+@@ -20,7 +22,3 @@ libgstwayland_@GST_API_VERSION@_la_LDFLAGS = \
+ $(GST_LIB_LDFLAGS) \
+ $(GST_ALL_LDFLAGS) \
+ $(GST_LT_LDFLAGS)
+-
+-noinst_HEADERS = \
+- wayland.h
+-
+--
+2.5.0
+
diff --git a/meta-rcar-gen3-adas/recipes-multimedia/gstreamer/gstreamer1.0-plugins-bad-1.6.3/0002-pkgconfig-libgstwayland.patch b/meta-rcar-gen3-adas/recipes-multimedia/gstreamer/gstreamer1.0-plugins-bad-1.6.3/0002-pkgconfig-libgstwayland.patch
new file mode 100644
index 0000000..0fe08b7
--- /dev/null
+++ b/meta-rcar-gen3-adas/recipes-multimedia/gstreamer/gstreamer1.0-plugins-bad-1.6.3/0002-pkgconfig-libgstwayland.patch
@@ -0,0 +1,34 @@
+From 96044f1d3773ba2783e3956729cd9c85b04733da Mon Sep 17 00:00:00 2001
+From: Grigory Kletsko <grigory.kletsko@cogentembedded.com>
+Date: Thu, 12 May 2016 21:24:38 +0300
+Subject: [PATCH] fix
+
+---
+ pkgconfig/Makefile.am | 6 ++++--
+ 1 file changed, 4 insertions(+), 2 deletions(-)
+
+diff --git a/pkgconfig/Makefile.am b/pkgconfig/Makefile.am
+index 3e53a6e..7ed611e 100644
+--- a/pkgconfig/Makefile.am
++++ b/pkgconfig/Makefile.am
+@@ -4,13 +4,15 @@ pcverfiles = \
+ gstreamer-plugins-bad-@GST_API_VERSION@.pc \
+ gstreamer-codecparsers-@GST_API_VERSION@.pc \
+ gstreamer-insertbin-@GST_API_VERSION@.pc \
+- gstreamer-mpegts-@GST_API_VERSION@.pc
++ gstreamer-mpegts-@GST_API_VERSION@.pc \
++ gstreamer-wayland-@GST_API_VERSION@.pc
+
+ pcverfiles_uninstalled = \
+ gstreamer-plugins-bad-@GST_API_VERSION@-uninstalled.pc \
+ gstreamer-codecparsers-@GST_API_VERSION@-uninstalled.pc \
+ gstreamer-insertbin-@GST_API_VERSION@-uninstalled.pc \
+- gstreamer-mpegts-@GST_API_VERSION@-uninstalled.pc
++ gstreamer-mpegts-@GST_API_VERSION@-uninstalled.pc \
++ gstreamer-wayland-@GST_API_VERSION@-uninstalled.pc
+
+ if HAVE_GST_GL
+ pcverfiles += gstreamer-gl-@GST_API_VERSION@.pc
+--
+2.5.0
+
diff --git a/meta-rcar-gen3-adas/recipes-multimedia/gstreamer/gstreamer1.0-plugins-bad_1.6.3.bbappend b/meta-rcar-gen3-adas/recipes-multimedia/gstreamer/gstreamer1.0-plugins-bad_1.6.3.bbappend
new file mode 100644
index 0000000..e7e476b
--- /dev/null
+++ b/meta-rcar-gen3-adas/recipes-multimedia/gstreamer/gstreamer1.0-plugins-bad_1.6.3.bbappend
@@ -0,0 +1,6 @@
+FILESEXTRAPATHS_prepend := "${THISDIR}/${PN}-${PV}:"
+
+SRC_URI_append = " \
+ file://0001-install-wayland.h-header.patch \
+ file://0002-pkgconfig-libgstwayland.patch \
+"
diff --git a/meta-rcar-gen3-adas/recipes-multimedia/mm-init/mm-init.bb b/meta-rcar-gen3-adas/recipes-multimedia/mm-init/mm-init.bb
new file mode 100644
index 0000000..3781a76
--- /dev/null
+++ b/meta-rcar-gen3-adas/recipes-multimedia/mm-init/mm-init.bb
@@ -0,0 +1,16 @@
+SUMMARY = "Startup script for Renesas MM modules"
+LICENSE = "CLOSED"
+
+SRC_URI = "file://init"
+
+S = "${WORKDIR}"
+
+do_install() {
+ install -d ${D}/${sysconfdir}/init.d
+ install -m755 ${WORKDIR}/init ${D}/${sysconfdir}/init.d/rc.mm
+}
+
+inherit allarch update-rc.d
+
+INITSCRIPT_NAME = "rc.mm"
+INITSCRIPT_PARAMS = "start 8 5 2 . stop 21 0 1 6 ."
diff --git a/meta-rcar-gen3-adas/recipes-multimedia/mm-init/mm-init/init b/meta-rcar-gen3-adas/recipes-multimedia/mm-init/mm-init/init
new file mode 100644
index 0000000..b6c9985
--- /dev/null
+++ b/meta-rcar-gen3-adas/recipes-multimedia/mm-init/mm-init/init
@@ -0,0 +1,28 @@
+#!/bin/sh
+#
+### BEGIN INIT INFO
+# Provides: mm
+# Required-Start: $local_fs $remote_fs
+# Required-Stop: $local_fs $remote_fs
+# Default-Start: 2 5
+# Default-Stop: 0 1 6
+### END INIT INFO
+
+case "$1" in
+"start")
+ # insert multimedia modules
+ /sbin/modprobe -q -a mmngr mmngrbuf vspm vspm_if uvcs_drv
+ ;;
+stop)
+ # remove multimedia modules
+ /sbin/modprobe -q -r -a mmngr mmngrbuf vspm vspm_if uvcs_drv
+ ;;
+reload|restart)
+ $0 stop
+ sleep 1
+ $0 start
+ ;;
+*)
+ echo "usage: $0 { start | stop | restart }"
+ ;;
+esac
diff --git a/meta-rcar-gen3-adas/recipes-multimedia/v4l2apps/libmediactl-v4l2.bb b/meta-rcar-gen3-adas/recipes-multimedia/v4l2apps/libmediactl-v4l2.bb
new file mode 100644
index 0000000..e45558c
--- /dev/null
+++ b/meta-rcar-gen3-adas/recipes-multimedia/v4l2apps/libmediactl-v4l2.bb
@@ -0,0 +1,16 @@
+DESCRIPTION = "V4L2 media controller support library"
+LICENSE = "LGPLv2.1"
+LIC_FILES_CHKSUM = " \
+ file://COPYING;md5=d749e86a105281d7a44c2328acebc4b0 \
+"
+
+PR = "r0"
+
+inherit autotools pkgconfig
+
+SRCREV = "998aaa0fa4a594bfc8d98ce0f5971ffc083be231"
+SRC_URI = " \
+ git://github.com/renesas-rcar/libmediactl-v4l2.git;protocol=git;branch=rcar-gen3 \
+"
+
+S = "${WORKDIR}/git"
diff --git a/meta-rcar-gen3-adas/recipes-support/ctemplate/ctemplate.inc b/meta-rcar-gen3-adas/recipes-support/ctemplate/ctemplate.inc
new file mode 100644
index 0000000..3caba6b
--- /dev/null
+++ b/meta-rcar-gen3-adas/recipes-support/ctemplate/ctemplate.inc
@@ -0,0 +1,12 @@
+SUMMARY = "CTemplate is a simple but powerful template language for C++. It emphasizes separating logic from presentation: it is impossible to embed application logic in this template language."
+HOMEPAGE = "https://code.google.com/p/ctemplate/"
+LICENSE = "GOOGLE-NEW-BSD"
+SECTION = "libs"
+
+inherit autotools pkgconfig
+
+LIC_FILES_CHKSUM = "file://COPYING;md5=762732742c73dc6c7fbe8632f06c059a"
+
+BBCLASSEXTEND = "native nativesdk"
+
+
diff --git a/meta-rcar-gen3-adas/recipes-support/ctemplate/ctemplate_2.3.bb b/meta-rcar-gen3-adas/recipes-support/ctemplate/ctemplate_2.3.bb
new file mode 100644
index 0000000..8383c12
--- /dev/null
+++ b/meta-rcar-gen3-adas/recipes-support/ctemplate/ctemplate_2.3.bb
@@ -0,0 +1,9 @@
+require ctemplate.inc
+
+SRC_URI = "svn://ctemplate.googlecode.com/svn/;module=tags/ctemplate-2.3;protocol=http"
+SRC_URI[md5sum] = ""
+SRC_URI[sha256sum] = ""
+SRCREV = "r141"
+S = "${WORKDIR}/tags/ctemplate-2.3"
+B = "${WORKDIR}/tags/ctemplate-2.3"
+
diff --git a/meta-rcar-gen3-adas/recipes-support/ctemplate/ctemplate_svn.bb b/meta-rcar-gen3-adas/recipes-support/ctemplate/ctemplate_svn.bb
new file mode 100644
index 0000000..c51ed40
--- /dev/null
+++ b/meta-rcar-gen3-adas/recipes-support/ctemplate/ctemplate_svn.bb
@@ -0,0 +1,11 @@
+require ctemplate.inc
+
+SRC_URI = "svn://ctemplate.googlecode.com/svn/;module=trunk;protocol=http"
+SRC_URI[md5sum] = ""
+SRC_URI[sha256sum] = ""
+SRCREV = "${AUTOREV}"
+S = "${WORKDIR}/trunk"
+
+PV = "2.3+svnr${SRCREV}"
+
+DEFAULT_PREFERENCE = "-1"
diff --git a/meta-rcar-gen3-adas/recipes-support/gflags/gflags_git.bb b/meta-rcar-gen3-adas/recipes-support/gflags/gflags_git.bb
new file mode 100644
index 0000000..79b5116
--- /dev/null
+++ b/meta-rcar-gen3-adas/recipes-support/gflags/gflags_git.bb
@@ -0,0 +1,20 @@
+SUMMARY = "GFlags library"
+DESCRIPTION = "The gflags package contains a C++ library that implements commandline flags processing"
+
+LICENSE = "BSD"
+LIC_FILES_CHKSUM = "file://${S}/COPYING.txt;md5=c80d1a3b623f72bb85a4c75b556551df"
+
+SRC_URI = "git://github.com/gflags/gflags.git"
+SRCREV = "14c0e93755d5a32c3d2029d83094564b8823b7b4"
+
+S = "${WORKDIR}/git"
+
+inherit cmake
+
+RDEPENDS_${PN} += "bash"
+
+EXTRA_OECMAKE = "-DBUILD_SHARED_LIBS=ON -DINSTALL_HEADERS=ON -DINSTALL_SHARED_LIBS=ON"
+
+FILES_${PN}-dev += " \
+ ${libdir}/cmake \
+"
diff --git a/meta-rcar-gen3-adas/recipes-support/glm/glm.inc b/meta-rcar-gen3-adas/recipes-support/glm/glm.inc
new file mode 100644
index 0000000..a550a73
--- /dev/null
+++ b/meta-rcar-gen3-adas/recipes-support/glm/glm.inc
@@ -0,0 +1,16 @@
+SUMMARY = "OpenGL Mathematics"
+HOMEPAGE = "http://glm.g-truc.net"
+DESCRIPTION = "OpenGL Mathematics (GLM) is a header only C++ mathematics library for graphics software based on the OpenGL Shading Language (GLSL) specifications."
+LICENSE = "MIT"
+SECTION = "multimedia"
+
+inherit pkgconfig cmake
+
+LIC_FILES_CHKSUM = " \
+ file://copying.txt;md5=6ba02d5f908587c6f3942e76bf6d92d6 \
+"
+
+ALLOW_EMPTY_${PN} = "1"
+
+FILES_${PN}-dev += "/usr/lib/cmake/"
+
diff --git a/meta-rcar-gen3-adas/recipes-support/glm/glm/0001-Fix-cmake-pathes.patch b/meta-rcar-gen3-adas/recipes-support/glm/glm/0001-Fix-cmake-pathes.patch
new file mode 100644
index 0000000..5ca3daa
--- /dev/null
+++ b/meta-rcar-gen3-adas/recipes-support/glm/glm/0001-Fix-cmake-pathes.patch
@@ -0,0 +1,25 @@
+From 4a3e9a475a6688abc81f336a5089e99b15cb5b14 Mon Sep 17 00:00:00 2001
+From: Petr Nechaev <petr.nechaev@cogentembedded.com>
+Date: Fri, 28 Aug 2015 16:16:09 +0300
+Subject: [PATCH] Fix cmake pathes
+
+---
+ CMakeLists.txt | 4 ++--
+ 1 file changed, 2 insertions(+), 2 deletions(-)
+
+diff --git a/CMakeLists.txt b/CMakeLists.txt
+index 860a6ee..174f35d 100644
+--- a/CMakeLists.txt
++++ b/CMakeLists.txt
+@@ -164,7 +164,7 @@ configure_file(
+ # install tree package config
+ configure_package_config_file(
+ cmake/glmConfig.cmake.in
+- ${GLM_INSTALL_CONFIGDIR}/glmConfig.cmake
++ ${CMAKE_CURRENT_BINARY_DIR}/${GLM_INSTALL_CONFIGDIR}/glmConfig.cmake
+ INSTALL_DESTINATION ${GLM_INSTALL_CONFIGDIR}
+ PATH_VARS CMAKE_INSTALL_INCLUDEDIR
+ NO_CHECK_REQUIRED_COMPONENTS_MACRO
+--
+1.9.3
+
diff --git a/meta-rcar-gen3-adas/recipes-support/glm/glm_0.9.7.0.bb b/meta-rcar-gen3-adas/recipes-support/glm/glm_0.9.7.0.bb
new file mode 100644
index 0000000..0ba9214
--- /dev/null
+++ b/meta-rcar-gen3-adas/recipes-support/glm/glm_0.9.7.0.bb
@@ -0,0 +1,10 @@
+require glm.inc
+
+SRC_URI = "\
+ https://github.com/g-truc/${BPN}/archive/${PV}.tar.gz \
+ file://0001-Fix-cmake-pathes.patch \
+"
+
+SRC_URI[md5sum] = "33025d322f08e7783f6513272ef60aff"
+SRC_URI[sha256sum] = "71f95cb20602dff9e799e7f4854d4173474382dbd9d0efc6f77bde6d289351fa"
+
diff --git a/meta-rcar-gen3-adas/recipes-support/glm/glm_git.bb b/meta-rcar-gen3-adas/recipes-support/glm/glm_git.bb
new file mode 100644
index 0000000..68f0d3e
--- /dev/null
+++ b/meta-rcar-gen3-adas/recipes-support/glm/glm_git.bb
@@ -0,0 +1,13 @@
+require glm.inc
+
+SRC_URI = "\
+ git://github.com/g-truc/glm.git \
+ file://0001-Fix-cmake-pathes.patch \
+"
+
+SRCREV = "ebdd48fa6f4a3f1436badeb43580a7910551740e"
+S = "${WORKDIR}/git"
+
+PV = "0.999+git${SRCREV}"
+
+DEFAULT_PREFERENCE = "-1"
diff --git a/meta-rcar-gen3-adas/recipes-support/libiio/libiio.inc b/meta-rcar-gen3-adas/recipes-support/libiio/libiio.inc
new file mode 100644
index 0000000..81662a5
--- /dev/null
+++ b/meta-rcar-gen3-adas/recipes-support/libiio/libiio.inc
@@ -0,0 +1,11 @@
+DESCRIPTION = "Library for interfacing with IIO devices"
+HOMEPAGE = "http://wiki.analog.com/resources/tools-software/linux-software/libiio"
+SECTION = "System/Libraries"
+LICENSE = "LGPL-2.1"
+
+LIC_FILES_CHKSUM ??= "file://COPYING.txt;md5=7c13b3376cea0ce68d2d2da0a1b3a72c"
+
+inherit cmake pkgconfig
+
+DEPENDS = "libxml2 bison-native flex-native systemd"
+
diff --git a/meta-rcar-gen3-adas/recipes-support/libiio/libiio_0.5.bb b/meta-rcar-gen3-adas/recipes-support/libiio/libiio_0.5.bb
new file mode 100644
index 0000000..664dc96
--- /dev/null
+++ b/meta-rcar-gen3-adas/recipes-support/libiio/libiio_0.5.bb
@@ -0,0 +1,9 @@
+require ${BPN}.inc
+
+SRC_URI = "https://github.com/analogdevicesinc/${BPN}/archive/v${PV}.tar.gz"
+SRC_URI[md5sum] = "4496c24dabdce60bdcf231ebe19bb501"
+SRC_URI[sha256sum] = "c41cdcfeae8717e72f1100b4dac9d7cc9d86f4e0731da3354149cb7e051666f3"
+
+LIC_FILES_CHKSUM ??= "file://COPYING;md5=7c13b3376cea0ce68d2d2da0a1b3a72c"
+
+S = "${WORKDIR}/${BPN}-${PV}"
diff --git a/meta-rcar-gen3-adas/recipes-support/libiio/libiio_git.bb b/meta-rcar-gen3-adas/recipes-support/libiio/libiio_git.bb
new file mode 100644
index 0000000..0c02133
--- /dev/null
+++ b/meta-rcar-gen3-adas/recipes-support/libiio/libiio_git.bb
@@ -0,0 +1,8 @@
+require ${BPN}.inc
+
+SRC_URI = "git://github.com/analogdevicesinc/${BPN}.git"
+S = "${WORKDIR}/git"
+SRCREV = "7ce5cd5b508389077aedaaa4d5f1c0b08b78ded5"
+
+DEFAULT_PREFERENCE = "1"
+
diff --git a/meta-rcar-gen3-adas/recipes-support/libusbg/libusbg.inc b/meta-rcar-gen3-adas/recipes-support/libusbg/libusbg.inc
new file mode 100644
index 0000000..eb62395
--- /dev/null
+++ b/meta-rcar-gen3-adas/recipes-support/libusbg/libusbg.inc
@@ -0,0 +1,10 @@
+SUMMARY = "USB Gadget Configfs Library"
+
+LICENSE = "GPLv2 & LGPLv2.1"
+LIC_FILES_CHKSUM = "file://COPYING;md5=b234ee4d69f5fce4486a80fdaf4a4263 \
+ file://COPYING.LGPL;md5=4fbd65380cdd255951079008b364516c"
+
+DEPENDS += " libconfig "
+
+inherit autotools pkgconfig
+
diff --git a/meta-rcar-gen3-adas/recipes-support/libusbg/libusbg_0.1.0.bb b/meta-rcar-gen3-adas/recipes-support/libusbg/libusbg_0.1.0.bb
new file mode 100644
index 0000000..b63bcd4
--- /dev/null
+++ b/meta-rcar-gen3-adas/recipes-support/libusbg/libusbg_0.1.0.bb
@@ -0,0 +1,9 @@
+require libusbg.inc
+
+SRC_URI = "https://github.com/libusbg/libusbg/archive/v${PV}.tar.gz"
+
+SRC_URI[md5sum] = "2d3af961f7007a35ed3816de6b712ac1"
+SRC_URI[sha256sum] = "82fa5c71741a70477148ed455c307611075a4f9af6886ab3e7a4471377dfd2c7"
+
+S = "${WORKDIR}/libusbg-${PV}"
+
diff --git a/meta-rcar-gen3-adas/recipes-support/libusbg/libusbg_git.bb b/meta-rcar-gen3-adas/recipes-support/libusbg/libusbg_git.bb
new file mode 100644
index 0000000..4f873da
--- /dev/null
+++ b/meta-rcar-gen3-adas/recipes-support/libusbg/libusbg_git.bb
@@ -0,0 +1,9 @@
+require libusbg.inc
+
+PV = "0.1.0b"
+SRCREV = "f1613aab97513188478087e001defbfca6847eca"
+SRC_URI = "git://github.com/kopasiak/libusbg.git"
+
+S = "${WORKDIR}/git"
+
+DEFAULT_PREFERENCE = "1"
diff --git a/meta-rcar-gen3-adas/recipes-support/netevent/netevent/0001-fix-endian-for-cross-arch.patch b/meta-rcar-gen3-adas/recipes-support/netevent/netevent/0001-fix-endian-for-cross-arch.patch
new file mode 100644
index 0000000..e984447
--- /dev/null
+++ b/meta-rcar-gen3-adas/recipes-support/netevent/netevent/0001-fix-endian-for-cross-arch.patch
@@ -0,0 +1,113 @@
+From d9e02e86cacb6771381c4cde45f6badd71ec01cf Mon Sep 17 00:00:00 2001
+From: Andrey Gusakov <andrey.gusakov@cogentembedded.com>
+Date: Tue, 13 Sep 2016 15:51:33 +0300
+Subject: [PATCH 1/2] fix endian for cross-arch
+
+
+Signed-off-by: Andrey Gusakov <andrey.gusakov@cogentembedded.com>
+---
+ reader.cpp | 21 +++++++++++++++------
+ write.cpp | 21 ++++++++++++++++-----
+ 2 files changed, 31 insertions(+), 11 deletions(-)
+
+diff --git a/reader.cpp b/reader.cpp
+index ab047bd..651967a 100644
+--- a/reader.cpp
++++ b/reader.cpp
+@@ -3,9 +3,18 @@
+ #include <signal.h>
+ #include <sys/wait.h>
+ #include <sys/types.h>
++#include <arpa/inet.h>
+ #include <stdint.h>
+ #include <unistd.h>
+
++int64_t htonll(int64_t value){
++ int num = 42;
++ if(*(char *)&num == 42) //test big/little endian
++ return (((int64_t)htonl(value)) << 32) + htonl(value >> 32);
++ else
++ return value;
++}
++
+ static bool running = true;
+ bool on = true;
+ static int fd = 0;
+@@ -159,7 +168,7 @@ int read_device(const char *devfile)
+
+ // First thing to write is the size of the structures as a 16 bit uint!
+ uint16_t strsz;
+- strsz = sizeof(dev);
++ strsz = htons(sizeof(dev));
+ if (!cout.write((const char*)&strsz, sizeof(strsz)))
+ exit(1);
+ if (cout.eof())
+@@ -272,11 +281,11 @@ int read_device(const char *devfile)
+ }
+ else if (on) {
+ input_event_t et;
+- et.tv_sec = ev.time.tv_sec;
+- et.tv_usec = ev.time.tv_usec;
+- et.type = ev.type;
+- et.code = ev.code;
+- et.value = ev.value;
++ et.tv_sec = htonll(ev.time.tv_sec);
++ et.tv_usec = htonl(ev.time.tv_usec);
++ et.type = htons(ev.type);
++ et.code = htons(ev.code);
++ et.value = htonl(ev.value);
+ if (!cout.write((const char*)&et, sizeof(et)))
+ exit(1);
+ if (cout.eof())
+diff --git a/write.cpp b/write.cpp
+index 7d58bf6..91c956c 100644
+--- a/write.cpp
++++ b/write.cpp
+@@ -1,9 +1,18 @@
+ #include "main.h"
+ #include <sys/wait.h>
+ #include <sys/types.h>
++#include <arpa/inet.h>
+ #include <stdint.h>
+ #include <unistd.h>
+
++int64_t ntohll(int64_t value){
++ int num = 42;
++ if(*(char *)&num == 42) //test big/little endian
++ return value;
++ else
++ return (((int64_t)ntohl(value)) << 32) + ntohl(value >> 32);
++}
++
+ static const char *uinput_file[] = {
+ "/dev/uinput",
+ "/dev/input/uinput",
+@@ -35,6 +44,7 @@ int spawn_device()
+ struct input_event ev;
+
+ cin.read((char*)&strsz, sizeof(strsz));
++ strsz = ntohs(strsz);
+ if (strsz != sizeof(uinput_user_dev)) {
+ cerr << "Device information field sizes do not match. Sorry." << endl;
+ return 1;
+@@ -126,11 +136,12 @@ int spawn_device()
+ cerr << "End of data" << endl;
+ break;
+ }
+- ev.time.tv_sec = et.tv_sec;
+- ev.time.tv_usec = et.tv_usec;
+- ev.type = et.type;
+- ev.code = et.code;
+- ev.value = et.value;
++ ev.time.tv_sec = ntohll(et.tv_sec);
++ ev.time.tv_usec = ntohl(et.tv_usec);
++ ev.type = ntohs(et.type);
++ ev.code = ntohs(et.code);
++ ev.value = ntohl(et.value);
++ //cErr << "EV " << ev.time.tv_sec << "." << ev.time.tv_usec << ": type " << ev.type << ", code " << ev.code << ", value " << ev.value << endl;
+ if (hotkey_hook(ev.type, ev.code, ev.value))
+ continue;
+ if (write(fd, &ev, sizeof(ev)) < (ssize_t)sizeof(ev)) {
+--
+1.7.10.4
+
diff --git a/meta-rcar-gen3-adas/recipes-support/netevent/netevent/0002-fix-cross-compile.patch b/meta-rcar-gen3-adas/recipes-support/netevent/netevent/0002-fix-cross-compile.patch
new file mode 100644
index 0000000..cca70ba
--- /dev/null
+++ b/meta-rcar-gen3-adas/recipes-support/netevent/netevent/0002-fix-cross-compile.patch
@@ -0,0 +1,70 @@
+From 7b30e567552535d9546e34d4fc38337095347224 Mon Sep 17 00:00:00 2001
+From: Andrey Gusakov <andrey.gusakov@cogentembedded.com>
+Date: Tue, 13 Sep 2016 15:51:55 +0300
+Subject: [PATCH 2/2] fix cross-compile
+
+
+Signed-off-by: Andrey Gusakov <andrey.gusakov@cogentembedded.com>
+---
+ Makefile | 19 ++++++++++---------
+ reader.cpp | 1 +
+ 2 files changed, 11 insertions(+), 9 deletions(-)
+
+diff --git a/Makefile b/Makefile
+index 02d25c7..9bbe82e 100644
+--- a/Makefile
++++ b/Makefile
+@@ -1,14 +1,15 @@
+-prefix = /usr/local
+-bindir = $(prefix)/bin
+-CXX = g++
+-CC = gcc
+-CFLAGS = -Wall -pthread
+-LDFLAGS = -g -pthread
++PREFIX ?= /usr
++SBINDIR ?= $(PREFIX)/bin
++CXX ?= g++
++CC ?= gcc
++CFLAGS += -Wall -pthread
++LDFLAGS += -g
++LIBS = -lpthread
+
+ SOURCES = main.cpp reader.cpp write.cpp showev.cpp
+
+ ifneq ($(inotify),no)
+- CFLAGS += -DWITH_INOTIFY
++ GCC_FLAGS += -DWITH_INOTIFY
+ endif
+
+ all: build netevent devname
+@@ -23,13 +24,13 @@ build/%.o: %.c
+ $(CC) $(CFLAGS) -c -o $@ $*.c -MMD -MF build/$*.d -MT $@
+
+ netevent: $(patsubst %.cpp,build/%.o,$(SOURCES))
+- $(CXX) $(LDFLAGS) -o $@ $^
++ $(CXX) $(LDFLAGS) -o $@ $^ $(LIBS)
+
+ devname: build/devname.o
+ $(CC) -o $@ $^
+
+ install: all
+- install -m 755 -p -t "$(DESTDIR)$(bindir)" netevent devname
++ install -m 755 -p -t "$(DESTDIR)$(SBINDIR)" netevent devname
+
+ clean:
+ -rm -rf build
+diff --git a/reader.cpp b/reader.cpp
+index 651967a..07fa64a 100644
+--- a/reader.cpp
++++ b/reader.cpp
+@@ -6,6 +6,7 @@
+ #include <arpa/inet.h>
+ #include <stdint.h>
+ #include <unistd.h>
++#include <pthread.h>
+
+ int64_t htonll(int64_t value){
+ int num = 42;
+--
+1.7.10.4
+
diff --git a/meta-rcar-gen3-adas/recipes-support/netevent/netevent/0003-use-socket-instead-of-stdout.patch b/meta-rcar-gen3-adas/recipes-support/netevent/netevent/0003-use-socket-instead-of-stdout.patch
new file mode 100644
index 0000000..4fb3039
--- /dev/null
+++ b/meta-rcar-gen3-adas/recipes-support/netevent/netevent/0003-use-socket-instead-of-stdout.patch
@@ -0,0 +1,653 @@
+From 68944103c94f4957c2dbc0d246bf1360d28bd5b4 Mon Sep 17 00:00:00 2001
+From: Andrey Gusakov <andrey.gusakov@cogentembedded.com>
+Date: Wed, 14 Sep 2016 18:16:47 +0300
+Subject: [PATCH] use socket instead of stdout
+
+---
+ main.cpp | 16 +++---
+ reader.cpp | 181 +++++++++++++++++++++++++++++++++++++------------------------
+ write.cpp | 139 ++++++++++++++++++++++++++++++++++++-----------
+ 3 files changed, 226 insertions(+), 110 deletions(-)
+
+diff --git a/main.cpp b/main.cpp
+index da512b0..e695328 100644
+--- a/main.cpp
++++ b/main.cpp
+@@ -9,15 +9,15 @@ bool no_grab = false;
+ bool count_syn = false;
+ bool be_quiet = false;
+
+-int read_device(const char *devname);
+-int spawn_device();
++int read_device(const char *devname, const char *hostname, int port);
++int spawn_device(int port);
+ int show_events(int count, const char *devname);
+
+ static void usage(const char *arg0)
+ {
+ size_t len = strlen(arg0);
+- cerr << "usage: " << arg0 << " [options] -read <device>" << endl;
+- cerr << " " << std::string(len, ' ') << " -write" << endl;
++ cerr << "usage: " << arg0 << " [options] -read <device> <ip/hostname> <port>" << endl;
++ cerr << " " << std::string(len, ' ') << " -write <port>" << endl;
+ cerr << " " << std::string(len, ' ') << " [options] -showevents <count> <device>" << endl;
+ cerr << "options are:" << endl;
+ cerr << " -ontoggle <command> Command to execute when grabbing is toggled." << endl;
+@@ -53,12 +53,14 @@ int main(int argc, char **argv)
+ usage(arg0);
+ }
+ else if (command == "-read") {
+- if (argc < 3)
++ if (argc < 5)
+ usage(arg0);
+- return read_device(argv[2]);
++ return read_device(argv[2], argv[3], atoi(argv[4]));
+ }
+ else if (command == "-write") {
+- return spawn_device();
++ if (argc < 3)
++ usage(arg0);
++ return spawn_device(atoi(argv[2]));
+ }
+ else if (command == "-toggler") {
+ if (argc < 3)
+diff --git a/reader.cpp b/reader.cpp
+index 07fa64a..0b6de20 100644
+--- a/reader.cpp
++++ b/reader.cpp
+@@ -3,10 +3,14 @@
+ #include <signal.h>
+ #include <sys/wait.h>
+ #include <sys/types.h>
++#include <sys/socket.h>
+ #include <arpa/inet.h>
+ #include <stdint.h>
++#include <stdio.h>
+ #include <unistd.h>
+ #include <pthread.h>
++#include <netinet/in.h>
++#include <netdb.h>
+
+ int64_t htonll(int64_t value){
+ int num = 42;
+@@ -50,26 +54,26 @@ static void *tog_func(void *ign)
+ #if !defined( WITH_INOTIFY )
+ struct stat st;
+ if (lstat(toggle_file, &st) != 0) {
+- cErr << "stat failed on " << toggle_file << ": " << err << endl;
++ fprintf(stderr, "stat failed on %s, %d\n", toggle_file, errno);
+ tog_on = false;
+ }
+ else
+ {
+ if (!S_ISFIFO(st.st_mode)) {
+- cerr << "The toggle file is not a fifo, and inotify support has not been compiled in." << endl;
+- cerr << "This is evil, please compile with inotify support." << endl;
++ fprintf(stderr, "The toggle file is not a fifo, and inotify support has not been compiled in.\n");
++ fprintf(stderr, "This is evil, please compile with inotify support.\n");
+ tog_on = false;
+ }
+ }
+ #else
+ inf_fd = inotify_init();
+ if (inf_fd == -1) {
+- cErr << "inotify_init failed: " << err << endl;
++ fprintf(stderr, "inotify_init failed: %d\n");
+ tog_on = false;
+ } else {
+ watch_fd = inotify_add_watch(inf_fd, toggle_file, IN_CLOSE_WRITE | IN_CREATE);
+ if (watch_fd == -1) {
+- cErr << "inotify_add_watch failed: " << err << endl;
++ fprintf(stderr, "inotify_add_watch failed: %d\n", err);
+ tog_on = false;
+ }
+ }
+@@ -79,17 +83,17 @@ static void *tog_func(void *ign)
+ #if defined( WITH_INOTIFY )
+ inotify_event iev;
+ if (read(inf_fd, &iev, sizeof(iev)) != (ssize_t)sizeof(iev)) {
+- cErr << "Failed to read from inotify watch: " << err << endl;
++ fprintf(stderr, "Failed to read from inotify watch: %d\n", err);
+ break;
+ }
+ if (iev.wd != watch_fd) {
+- cerr << "Inotify sent is bogus information..." << endl;
++ fprintf(stderr, "Inotify sent is bogus information...\n");
+ continue;
+ }
+ #endif
+ tfd = open(toggle_file, O_RDONLY);
+ if (tfd < 0) {
+- cErr << "Failed to open '" << toggle_file << "': " << err << endl;
++ fprintf(stderr, "Failed to open '%s', %d\n", toggle_file, errno);
+ break;
+ }
+ memset(dat, 0, sizeof(dat));
+@@ -110,22 +114,58 @@ static void *tog_func(void *ign)
+ static void toggle_hook()
+ {
+ if (ioctl(fd, EVIOCGRAB, (on ? (void*)1 : (void*)0)) == -1) {
+- cErr << "Grab failed: " << err << endl;
++ fprintf(stderr, "Grab failed: %d\n", errno);
+ }
+ setenv("GRAB", (on ? "1" : "0"), -1);
+- if (toggle_cmd) {
++ if (toggle_cmd) {
+ if (!fork()) {
+ execlp("sh", "sh", "-c", toggle_cmd, NULL);
+- cErr << "Failed to run command: " << err << endl;
+- exit(1);
++ fprintf(stderr, "Failed to run command: %d\n", errno);
++ exit(1);
+ }
+
+- }
++ }
++}
++
++int socket_open(const char *hostname, int port)
++{
++ int ret;
++ int sockfd;
++ struct sockaddr_in serv_addr;
++ struct hostent *server;
++
++ printf("connecting to %s:%d\n", hostname, port);
++
++ sockfd = socket(AF_INET, SOCK_STREAM, 0);
++ if (sockfd < 0) {
++ fprintf(stderr, "ERROR opening socket\n");
++ return sockfd;
++ }
++
++ server = gethostbyname(hostname);
++ if (server == NULL) {
++ fprintf(stderr, "ERROR, no such host\n");
++ return -1;
++ }
++
++ bzero((char *) &serv_addr, sizeof(serv_addr));
++ serv_addr.sin_family = AF_INET;
++ bcopy((char *)server->h_addr,
++ (char *)&serv_addr.sin_addr.s_addr,
++ server->h_length);
++ serv_addr.sin_port = htons(port);
++ ret = connect(sockfd,(struct sockaddr *)&serv_addr,sizeof(serv_addr));
++ if (ret < 0) {
++ fprintf(stderr, "ERROR connecting %d, %d\n", ret, errno);
++ return ret;
++ }
++ return sockfd;
+ }
+
+-int read_device(const char *devfile)
++int read_device_new(const char *devfile, const char *hostname, int port)
+ {
+ struct input_event ev;
++ int sock_fd;
+ size_t i;
+ ssize_t s;
+ //int e = 0;
+@@ -136,14 +176,13 @@ int read_device(const char *devfile)
+
+ if (fd < 0) {
+ std::string err(strerror(errno));
+- cerr << "Failed to open device '" << devfile << "': " << err << endl;
++ fprintf(stderr, "Failed to open device '%s', %d\n", devfile, errno);
+ return 1;
+ }
+
+ if (on) {
+ if (ioctl(fd, EVIOCGRAB, (void*)1) == -1) {
+- std::string err(strerror(errno));
+- cerr << "Failed to grab device: " << err << endl;
++ fprintf(stderr, "Failed to grab device: %d\n", errno);
+ }
+ setenv("GRAB", "1", -1);
+ }
+@@ -154,59 +193,54 @@ int read_device(const char *devfile)
+ memset(&dev, 0, sizeof(dev));
+
+ if (ioctl(fd, EVIOCGNAME(sizeof(dev.name)), dev.name) == -1) {
+- cErr << "Failed to get device name: " << err << endl;
++ fprintf(stderr, "Failed to get device name: %d\n", errno);
+ goto error;
+ }
+
+ if (ioctl(fd, EVIOCGID, &dev.id) == -1) {
+- cErr << "Failed to get device id: " << err << endl;
++ fprintf(stderr, "Failed to get device id: %d\n", errno);
+ goto error;
+ }
+
+- cerr << " Device: " << dev.name << endl;
+- cerr << " Id: " << dev.id.version << endl;
+- cerr << "BusType: " << dev.id.bustype << endl;
++ fprintf(stderr, " Device: %s\n", dev.name);
++ fprintf(stderr, " Id: %d\n", dev.id.version);
++ fprintf(stderr, "BusType: %d\n", dev.id.bustype);
++
++ sock_fd = socket_open(hostname, port);
++ if (sock_fd < 0)
++ goto error;
+
+ // First thing to write is the size of the structures as a 16 bit uint!
+ uint16_t strsz;
+ strsz = htons(sizeof(dev));
+- if (!cout.write((const char*)&strsz, sizeof(strsz)))
+- exit(1);
+- if (cout.eof())
+- exit(0);
+-
+- if (!cout.write(dev.name, sizeof(dev.name)))
+- exit(1);
+- if (cout.eof())
+- exit(0);
+- if (!cout.write((const char*)&dev.id, sizeof(dev.id)))
+- exit(1);
+- if (cout.eof())
+- exit(0);
+-
+- cerr << "Getting input bits." << endl;
++ if (!write(sock_fd, (const char*)&strsz, sizeof(strsz)))
++ goto err_close;
++
++ if (!write(sock_fd, dev.name, sizeof(dev.name)))
++ goto err_close;
++
++ if (!write(sock_fd, (const char*)&dev.id, sizeof(dev.id)))
++ goto err_close;
++
++ fprintf(stderr, "Getting input bits.\n");
+ if (ioctl(fd, EVIOCGBIT(0, sizeof(input_bits)), &input_bits) == -1) {
+- cErr << "Failed to get input-event bits: " << err << endl;
++ fprintf(stderr, "Failed to get input-event bits: %d\n", errno);
+ goto error;
+ }
+- if (!cout.write((const char*)input_bits, sizeof(input_bits)))
+- exit(1);
+- if (cout.eof())
+- exit(0);
++ if (!write(sock_fd, (const char*)input_bits, sizeof(input_bits)))
++ goto err_close;
+
+ #define TransferBitsFor(REL, rel, REL_MAX) \
+ do { \
+ if (testbit(input_bits, EV_##REL)) { \
+ unsigned char bits##rel[1+REL_MAX/8]; \
+- cerr << "Getting " #rel "-bits." << endl; \
++ fprintf(stderr, "Getting " #rel "-bits.\n"); \
+ if (ioctl(fd, EVIOCGBIT(EV_##REL, sizeof(bits##rel)), bits##rel) == -1) { \
+- cErr << "Failed to get " #rel " bits: " << err << endl; \
++ fprintf(stderr, "Failed to get " #rel " bits: %d\n", errno); \
+ goto error; \
+ } \
+- if (!cout.write((const char*)&bits##rel, sizeof(bits##rel))) \
+- exit(1); \
+- if (cout.eof()) \
+- exit(0); \
++ if (!write(sock_fd, (const char*)&bits##rel, sizeof(bits##rel))) \
++ goto err_close; \
+ } \
+ } while(0)
+
+@@ -220,16 +254,14 @@ int read_device(const char *devfile)
+ #define TransferDataFor(KEY, key, KEY_MAX) \
+ do { \
+ if (testbit(input_bits, EV_##KEY)) { \
+- cerr << "Getting " #key "-state." << endl; \
++ fprintf(stderr, "Getting " #key "-state.\n"); \
+ unsigned char bits##key[1+KEY_MAX/8]; \
+ if (ioctl(fd, EVIOCG##KEY(sizeof(bits##key)), bits##key) == -1) { \
+- cErr << "Failed to get " #key " state: " << err << endl; \
++ fprintf(stderr, "Failed to get " #key " state: %d\n", errno); \
+ goto error; \
+ } \
+- if (!cout.write((const char*)bits##key, sizeof(bits##key))) \
+- exit(1); \
+- if (cout.eof()) \
+- exit(0); \
++ if (!write(sock_fd, (const char*)bits##key, sizeof(bits##key))) \
++ goto err_close; \
+ } \
+ } while(0)
+
+@@ -239,39 +271,35 @@ int read_device(const char *devfile)
+
+ if (testbit(input_bits, EV_ABS)) {
+ struct input_absinfo ai;
+- cerr << "Getting abs-info." << endl;
++ fprintf(stderr, "Getting abs-info.\n");
+ for (i = 0; i < ABS_MAX; ++i) {
+ if (ioctl(fd, EVIOCGABS(i), &ai) == -1) {
+- cErr << "Failed to get device id: " << err << endl;
++ fprintf(stderr, "Failed to get device id: %d\n", errno);
+ goto error;
+ }
+- if (!cout.write((const char*)&ai, sizeof(ai)))
+- exit(1);
+- if (cout.eof())
+- exit(0);
++ if (!write(sock_fd, (const char*)&ai, sizeof(ai)))
++ goto err_close;
+ }
+ }
+
+- cout.flush();
+-
+ if (toggle_file) {
+ if (pthread_create(&tog_thread, 0, &tog_func, 0) != 0) {
+- cErr << "Failed to create toggling-thread: " << err << endl;
++ fprintf(stderr, "Failed to create toggling-thread: %d\n", errno);
+ goto error;
+ }
+ }
+
+- cerr << "Transferring input events." << endl;
++ fprintf(stderr, "Transferring input events.\n");
+ while (running) {
+ int dummy;
+ waitpid(0, &dummy, WNOHANG);
+ s = read(fd, &ev, sizeof(ev));
+ if (!s) {
+- cerr << "EOF" << endl;
++ fprintf(stderr, "EOF\n");
+ break;
+ }
+ else if (s < 0) {
+- cErr << "When reading from device: " << err << endl;
++ fprintf(stderr, "When reading from device: %d\n", errno);
+ goto error;
+ }
+
+@@ -282,20 +310,22 @@ int read_device(const char *devfile)
+ }
+ else if (on) {
+ input_event_t et;
++
++ //fprintf(stderr, "EV %d.%06d: type %d, code %d, value %d\n",
++ // (int)ev.time.tv_sec, (int)ev.time.tv_usec, (int)ev.type, ev.code, ev.value);
+ et.tv_sec = htonll(ev.time.tv_sec);
+ et.tv_usec = htonl(ev.time.tv_usec);
+ et.type = htons(ev.type);
+ et.code = htons(ev.code);
+ et.value = htonl(ev.value);
+- if (!cout.write((const char*)&et, sizeof(et)))
+- exit(1);
+- if (cout.eof())
+- exit(0);
+- cout.flush();
++ if (!write(sock_fd, (const char*)&et, sizeof(et)))
++ goto err_close;
+ }
+ }
+
+ goto end;
++err_close:
++ close(sock_fd);
+ error:
+ //e = 1;
+ end:
+@@ -306,3 +336,12 @@ end:
+
+ return 0;
+ }
++
++int read_device(const char *devfile, const char *hostname, int port)
++{
++ while (1) {
++ read_device_new(devfile, hostname, port);
++ sleep(1);
++ }
++ return 0;
++}
+\ No newline at end of file
+diff --git a/write.cpp b/write.cpp
+index 91c956c..dc6c3bc 100644
+--- a/write.cpp
++++ b/write.cpp
+@@ -1,9 +1,13 @@
+ #include "main.h"
+ #include <sys/wait.h>
+ #include <sys/types.h>
++#include <sys/socket.h>
+ #include <arpa/inet.h>
+ #include <stdint.h>
++#include <stdio.h>
+ #include <unistd.h>
++#include <netinet/in.h>
++#include <netdb.h>
+
+ int64_t ntohll(int64_t value){
+ int num = 42;
+@@ -22,12 +26,55 @@ static const size_t uinput_cnt = sizeof(uinput_file) / sizeof(uinput_file[0]);
+
+ static uint16_t strsz;
+
+-int spawn_device()
++int socket_start_listen(int port)
++{
++ int ret;
++ int sockfd;
++ struct sockaddr_in serv_addr;
++
++ printf("starting on port %d\n", port);
++
++ sockfd = socket(AF_INET, SOCK_STREAM, 0);
++ if (sockfd < 0) {
++ fprintf(stderr, "ERROR opening socket %d", sockfd);
++ return sockfd;
++ }
++ bzero((char *) &serv_addr, sizeof(serv_addr));
++ serv_addr.sin_family = AF_INET;
++ serv_addr.sin_addr.s_addr = INADDR_ANY;
++ serv_addr.sin_port = htons(port);
++ ret = bind(sockfd, (struct sockaddr *) &serv_addr, sizeof(serv_addr));
++ if (ret < 0) {
++ fprintf(stderr, "ERROR on binding %d", ret);
++ return ret;
++ }
++ listen(sockfd, 1);
++ return sockfd;
++}
++
++int socket_wait_connection(int sockfd)
++{
++ int newsockfd;
++ struct sockaddr_in cli_addr;
++ socklen_t clilen;
++
++ clilen = sizeof(cli_addr);
++ newsockfd = accept(sockfd, (struct sockaddr *) &cli_addr, &clilen);
++ if (newsockfd < 0) {
++ fprintf(stderr, "ERROR on accept %d", newsockfd);
++ return newsockfd;
++ }
++ return newsockfd;
++}
++
++int spawn_device_new(int sock_con)
+ {
+ int e;
+ int fd;
+- size_t i;
++ int i;
+ ssize_t si;
++ struct uinput_user_dev dev;
++ struct input_event ev;
+
+ for (i = 0; i < uinput_cnt; ++i) {
+ fd = open(uinput_file[i], O_WRONLY | O_NDELAY);
+@@ -36,30 +83,28 @@ int spawn_device()
+ }
+
+ if (i >= uinput_cnt) {
+- cerr << "Failed to open uinput device file. Please specify." << endl;
++ fprintf(stderr, "Failed to open uinput device file. Please specify.\n");
+ return 1;
+ }
+
+- struct uinput_user_dev dev;
+- struct input_event ev;
+-
+- cin.read((char*)&strsz, sizeof(strsz));
++ read(sock_con, (char*)&strsz, sizeof(strsz));
+ strsz = ntohs(strsz);
+ if (strsz != sizeof(uinput_user_dev)) {
+- cerr << "Device information field sizes do not match. Sorry." << endl;
+- return 1;
++ fprintf(stderr, "Device information field sizes do not match (%d != %d). Sorry.\n",
++ strsz, (int)sizeof(uinput_user_dev));
++ goto err_close;
+ }
+
+ memset(&dev, 0, sizeof(dev));
+- cin.read((char*)dev.name, sizeof(dev.name));
+- cin.read((char*)&dev.id, sizeof(dev.id));
++ read(sock_con, dev.name, sizeof(dev.name));
++ read(sock_con, &dev.id, sizeof(dev.id));
+
+- cin.read((char*)input_bits, sizeof(input_bits));
++ read(sock_con, input_bits, sizeof(input_bits));
+ for (i = 0; i < EV_MAX; ++i) {
+ if (!testbit(input_bits, i))
+ continue;
+ if (ioctl(fd, UI_SET_EVBIT, i) == -1) {
+- cErr << "Failed to set evbit " << i << ": " << err << endl;
++ fprintf(stderr, "Failed to set evbit %d, %d\n", i, errno);
+ goto error;
+ }
+ }
+@@ -68,13 +113,13 @@ int spawn_device()
+ do { \
+ if (testbit(input_bits, EV_##REL)) { \
+ unsigned char bits##rel[1+REL_MAX/8]; \
+- cerr << "Reading " #rel "-bits" << endl; \
+- cin.read((char*)bits##rel, sizeof(bits##rel)); \
++ fprintf(stderr, "Reading " #rel "-bits\n"); \
++ read(sock_con, (char*)bits##rel, sizeof(bits##rel)); \
+ for (i = 0; i < REL_MAX; ++i) { \
+ if (!testbit(bits##rel, i)) continue; \
+ if (ioctl(fd, UI_SET_##RELBIT, i) == -1) { \
+- cErr << "Failed to set " #rel "-bit: " << i << ": " << err << endl; \
+- goto error; \
++ fprintf(stderr, "Failed to set " #rel "-bit: %d, %d\n", i, errno); \
++ goto err_close; \
+ } \
+ } \
+ } \
+@@ -91,13 +136,13 @@ int spawn_device()
+ do { \
+ if (testbit(input_bits, EV_##KEY)) { \
+ unsigned char bits##key[1+KEY_MAX/8]; \
+- cerr << "Reading " #key "-data" << endl; \
+- cin.read((char*)bits##key, sizeof(bits##key)); \
++ fprintf(stderr, "Reading " #key "-data\n"); \
++ read(sock_con, (char*)bits##key, sizeof(bits##key)); \
+ for (i = 0; i < KEY_MAX; ++i) { \
+ if (!testbit(bits##key, i)) continue; \
+ if (ioctl(fd, UI_SET_##KEYBIT, i) == -1) { \
+- cErr << "Failed to activate " #key "-bit: " << i << ": " << err << endl; \
+- goto error; \
++ fprintf(stderr, "Failed to activate " #key "-bit: %d, %d\n", i, errno); \
++ goto err_close; \
+ } \
+ } \
+ } \
+@@ -110,7 +155,7 @@ int spawn_device()
+ if (testbit(input_bits, EV_ABS)) {
+ struct input_absinfo ai;
+ for (i = 0; i < ABS_MAX; ++i) {
+- cin.read((char*)&ai, sizeof(ai));
++ read(sock_con, (char*)&ai, sizeof(ai));
+ dev.absmin[i] = ai.minimum;
+ dev.absmax[i] = ai.maximum;
+ }
+@@ -118,22 +163,22 @@ int spawn_device()
+
+ si = write(fd, &dev, sizeof(dev));
+ if (si < (ssize_t)sizeof(dev)) {
+- cErr << "Failed to write initial data to device: " << err << endl;
+- goto error;
++ fprintf(stderr, "Failed to write initial data to device: %d\n", errno);
++ goto err_close;
+ }
+
+ if (ioctl(fd, UI_DEV_CREATE) == -1) {
+- cErr << "Failed to create device: " << err << endl;
+- goto error;
++ fprintf(stderr, "Failed to create device: %d\n", errno);
++ goto err_close;
+ }
+
+- cerr << "Transferring input events." << endl;
++ fprintf(stderr, "Transferring input events.\n");
+ while (true) {
+ input_event_t et;
+ int dummy;
+ waitpid(0, &dummy, WNOHANG);
+- if (!cin.read((char*)&et, sizeof(et))) {
+- cerr << "End of data" << endl;
++ if (!read(sock_con, (char*)&et, sizeof(et))) {
++ fprintf(stderr, "End of data\n");
+ break;
+ }
+ ev.time.tv_sec = ntohll(et.tv_sec);
+@@ -141,16 +186,21 @@ int spawn_device()
+ ev.type = ntohs(et.type);
+ ev.code = ntohs(et.code);
+ ev.value = ntohl(et.value);
+- //cErr << "EV " << ev.time.tv_sec << "." << ev.time.tv_usec << ": type " << ev.type << ", code " << ev.code << ", value " << ev.value << endl;
++ //fprintf(stderr, "EV %d.%06d: type %d, code %d, value %d\n",
++ // (int)ev.time.tv_sec, (int)ev.time.tv_usec, (int)ev.type, ev.code, ev.value);
+ if (hotkey_hook(ev.type, ev.code, ev.value))
+ continue;
+ if (write(fd, &ev, sizeof(ev)) < (ssize_t)sizeof(ev)) {
+- cErr << "Write error: " << err << endl;
+- goto error;
++ fprintf(stderr, "Write error: %d\n", errno);
++ goto err_close;
+ }
+ }
+
+ goto end;
++
++err_close:
++ if (sock_con > 0)
++ close(sock_con);
+ error:
+ e = 1;
+ end:
+@@ -159,3 +209,28 @@ end:
+
+ return e;
+ }
++
++int spawn_device(int port)
++{
++ int ret;
++ int sock_listen, sock_con;
++ printf("...%d\n", port);
++
++ sock_listen = socket_start_listen(port);
++ if (sock_listen < 0)
++ return sock_listen;
++
++ printf("Got connection on port %d\n", port);
++ while(1) {
++ sock_con = socket_wait_connection(sock_listen);
++ if (sock_con < 0)
++ goto err_close;
++ ret = spawn_device_new(sock_con);
++ printf("connection closed %d\n", ret);
++ sleep(1);
++ }
++ return 0;
++err_close:
++ close(sock_listen);
++ return -1;
++}
+\ No newline at end of file
+--
+2.7.4
+
diff --git a/meta-rcar-gen3-adas/recipes-support/netevent/netevent/0004-Add-TCP-keep-alive-to-handle-peer-death-properly.patch b/meta-rcar-gen3-adas/recipes-support/netevent/netevent/0004-Add-TCP-keep-alive-to-handle-peer-death-properly.patch
new file mode 100644
index 0000000..f84f113
--- /dev/null
+++ b/meta-rcar-gen3-adas/recipes-support/netevent/netevent/0004-Add-TCP-keep-alive-to-handle-peer-death-properly.patch
@@ -0,0 +1,162 @@
+From 0d797dca82a714688657523a89a14c37ae7767cf Mon Sep 17 00:00:00 2001
+From: Grigory Kletsko <grigory.kletsko@cogentembedded.com>
+Date: Wed, 5 Oct 2016 22:15:25 +0300
+Subject: [PATCH] Add TCP keep alive to handle peer death properly
+
+---
+ reader.cpp | 32 +++++++++++++++++++++++++++++++-
+ write.cpp | 46 ++++++++++++++++++++++++++++++++++++++++++++--
+ 2 files changed, 75 insertions(+), 3 deletions(-)
+
+diff --git a/reader.cpp b/reader.cpp
+index 0b6de20..e1a26e3 100644
+--- a/reader.cpp
++++ b/reader.cpp
+@@ -11,6 +11,8 @@
+ #include <pthread.h>
+ #include <netinet/in.h>
+ #include <netdb.h>
++#include <netinet/in.h>
++#include <netinet/tcp.h>
+
+ int64_t htonll(int64_t value){
+ int num = 42;
+@@ -131,6 +133,8 @@ int socket_open(const char *hostname, int port)
+ {
+ int ret;
+ int sockfd;
++ int val;
++
+ struct sockaddr_in serv_addr;
+ struct hostent *server;
+
+@@ -159,6 +163,32 @@ int socket_open(const char *hostname, int port)
+ fprintf(stderr, "ERROR connecting %d, %d\n", ret, errno);
+ return ret;
+ }
++
++ val = 5;
++ ret = setsockopt(sockfd, IPPROTO_TCP, TCP_KEEPCNT, &val,
++ sizeof(val));
++ if (ret < 0) {
++ fprintf(stderr, "ERROR on setsockopt %d", ret);
++ return ret;
++ }
++
++ val = 1;
++ ret = setsockopt(sockfd, IPPROTO_TCP, TCP_KEEPIDLE, &val,
++ sizeof(val));
++ if (ret < 0) {
++ fprintf(stderr, "ERROR on setsockopt %d", ret);
++ return ret;
++ }
++
++ val = 1;
++ ret = setsockopt(sockfd, IPPROTO_TCP, TCP_KEEPINTVL, &val,
++ sizeof(val));
++ if (ret < 0) {
++ fprintf(stderr, "ERROR on setsockopt %d", ret);
++ return ret;
++ }
++
++
+ return sockfd;
+ }
+
+@@ -344,4 +374,4 @@ int read_device(const char *devfile, const char *hostname, int port)
+ sleep(1);
+ }
+ return 0;
+-}
+\ No newline at end of file
++}
+diff --git a/write.cpp b/write.cpp
+index dc6c3bc..67ce412 100644
+--- a/write.cpp
++++ b/write.cpp
+@@ -8,6 +8,9 @@
+ #include <unistd.h>
+ #include <netinet/in.h>
+ #include <netdb.h>
++#include <sys/socket.h>
++#include <netinet/in.h>
++#include <netinet/tcp.h>
+
+ int64_t ntohll(int64_t value){
+ int num = 42;
+@@ -30,6 +33,8 @@ int socket_start_listen(int port)
+ {
+ int ret;
+ int sockfd;
++ int val;
++
+ struct sockaddr_in serv_addr;
+
+ printf("starting on port %d\n", port);
+@@ -48,7 +53,41 @@ int socket_start_listen(int port)
+ fprintf(stderr, "ERROR on binding %d", ret);
+ return ret;
+ }
++
++ val = 1;
++ ret = setsockopt(sockfd, SOL_SOCKET, SO_KEEPALIVE, &val,
++ sizeof(val));
++ if (ret < 0) {
++ fprintf(stderr, "ERROR on setsockopt %d", ret);
++ return ret;
++ }
++
++ val = 5;
++ ret = setsockopt(sockfd, IPPROTO_TCP, TCP_KEEPCNT, &val,
++ sizeof(val));
++ if (ret < 0) {
++ fprintf(stderr, "ERROR on setsockopt %d", ret);
++ return ret;
++ }
++
++ val = 1;
++ ret = setsockopt(sockfd, IPPROTO_TCP, TCP_KEEPIDLE, &val,
++ sizeof(val));
++ if (ret < 0) {
++ fprintf(stderr, "ERROR on setsockopt %d", ret);
++ return ret;
++ }
++
++ val = 1;
++ ret = setsockopt(sockfd, IPPROTO_TCP, TCP_KEEPINTVL, &val,
++ sizeof(val));
++ if (ret < 0) {
++ fprintf(stderr, "ERROR on setsockopt %d", ret);
++ return ret;
++ }
++
+ listen(sockfd, 1);
++
+ return sockfd;
+ }
+
+@@ -174,10 +213,13 @@ int spawn_device_new(int sock_con)
+
+ fprintf(stderr, "Transferring input events.\n");
+ while (true) {
++ int ret;
+ input_event_t et;
+ int dummy;
+ waitpid(0, &dummy, WNOHANG);
+- if (!read(sock_con, (char*)&et, sizeof(et))) {
++ ret = read(sock_con, (char*)&et, sizeof(et));
++
++ if (ret <= 0) {
+ fprintf(stderr, "End of data\n");
+ break;
+ }
+@@ -233,4 +275,4 @@ int spawn_device(int port)
+ err_close:
+ close(sock_listen);
+ return -1;
+-}
+\ No newline at end of file
++}
+--
+2.7.4
+
diff --git a/meta-rcar-gen3-adas/recipes-support/netevent/netevent_git.bb b/meta-rcar-gen3-adas/recipes-support/netevent/netevent_git.bb
new file mode 100644
index 0000000..7dde8f5
--- /dev/null
+++ b/meta-rcar-gen3-adas/recipes-support/netevent/netevent_git.bb
@@ -0,0 +1,29 @@
+SUMMARY = "netevent - share input devices over net"
+SECTION = "misc"
+
+LICENSE = "CLOSED"
+
+PN = "netevent"
+PE = "1"
+PV = "0.1"
+PR = "r1"
+
+SRC_URI = "git://github.com/Blub/netevent.git \
+ file://0001-fix-endian-for-cross-arch.patch \
+ file://0002-fix-cross-compile.patch \
+ file://0003-use-socket-instead-of-stdout.patch \
+ file://0004-Add-TCP-keep-alive-to-handle-peer-death-properly.patch \
+"
+
+SRCREV = "06f1fe545f2063ae882fc8b66dc07f1ced85d1da"
+
+S = "${WORKDIR}/git"
+
+B = "${S}"
+
+do_install() {
+ install -d ${D}${bindir}
+
+ install -m 0755 netevent ${D}${bindir}/
+ install -m 0755 devname ${D}${bindir}/
+}
diff --git a/meta-rcar-gen3-adas/recipes-support/nlopt/nlopt.inc b/meta-rcar-gen3-adas/recipes-support/nlopt/nlopt.inc
new file mode 100644
index 0000000..245fef2
--- /dev/null
+++ b/meta-rcar-gen3-adas/recipes-support/nlopt/nlopt.inc
@@ -0,0 +1,32 @@
+DESCRIPTION = "library for nonlinear optimization, wrapping many algorithms for global and local, constrained or unconstrained, optimization"
+HOMEPAGE = "http://ab-initio.mit.edu/wiki/index.php/NLopt"
+SECTION = "System/Libraries"
+LICENSE = "LGPL-2.1 | MIT"
+
+LIC_FILES_CHKSUM ??= "file://COPYING;md5=7036bf07f719818948a837064b1af213"
+
+inherit autotools pkgconfig
+
+DEPENDS += "swig-native"
+
+# remove dead weight from the build
+EXTRA_OECONF += " \
+ --without-guile \
+ --without-python \
+ --without-octave \
+ --without-matlab \
+ --enable-shared \
+"
+
+# see https://github.com/stevengj/nlopt/issues/29
+EXTRA_OECONF += "--enable-maintainer-mode"
+
+EXTRA_OECONF_remove = "--disable-static"
+
+# see https://github.com/stevengj/nlopt/issues/9
+do_configure_prepend () {
+ touch ${S}/swig/nlopt.scm.in
+}
+
+SRC_URI_append = " file://0001-Fix-compilation-error.patch"
+
diff --git a/meta-rcar-gen3-adas/recipes-support/nlopt/nlopt/0001-Fix-compilation-error.patch b/meta-rcar-gen3-adas/recipes-support/nlopt/nlopt/0001-Fix-compilation-error.patch
new file mode 100644
index 0000000..10b3594
--- /dev/null
+++ b/meta-rcar-gen3-adas/recipes-support/nlopt/nlopt/0001-Fix-compilation-error.patch
@@ -0,0 +1,25 @@
+From 994c3fdbde7ce1b2a31d4bd3053aed7cdc857760 Mon Sep 17 00:00:00 2001
+From: Petr Nechaev <petr.nechaev@cogentembedded.com>
+Date: Sat, 31 Oct 2015 15:24:11 +0300
+Subject: [PATCH 1/1] Fix compilation error
+
+---
+ swig/Makefile.am | 2 --
+ 1 file changed, 2 deletions(-)
+
+diff --git a/swig/Makefile.am b/swig/Makefile.am
+index 5ccbfe1..d55ac28 100644
+--- a/swig/Makefile.am
++++ b/swig/Makefile.am
+@@ -44,8 +44,6 @@ if MAINTAINER_MODE
+
+ nlopt-guile.cpp nlopt.scm.in: $(SWIG_SRC) nlopt-guile.i $(HDR)
+ swig -I$(top_srcdir)/api -outdir $(builddir) -c++ -guile -scmstub -o $@ $(srcdir)/nlopt.i
+- rm -f nlopt.scm.in
+- mv nlopt.scm nlopt.scm.in
+
+ nlopt-python.cpp nlopt.py: $(SWIG_SRC) nlopt-python.i numpy.i $(HDR)
+ swig -I$(top_srcdir)/api -outdir $(builddir) -c++ -python -o $@ $(srcdir)/nlopt.i
+--
+2.4.3
+
diff --git a/meta-rcar-gen3-adas/recipes-support/nlopt/nlopt_2.4.2.bb b/meta-rcar-gen3-adas/recipes-support/nlopt/nlopt_2.4.2.bb
new file mode 100644
index 0000000..5c72a31
--- /dev/null
+++ b/meta-rcar-gen3-adas/recipes-support/nlopt/nlopt_2.4.2.bb
@@ -0,0 +1,7 @@
+require ${PN}.inc
+
+SRC_URI = "https://github.com/stevengj/${BPN}/archive/${BPN}-${PV}.tar.gz"
+SRC_URI[md5sum] = "5f60160dd0cb0f7c4fed983940bd5224"
+SRC_URI[sha256sum] = "d838b5b4b1c6b6493666ff61a8817a4ebcee924f54fb95f6f64e5f727ddbf2a6"
+
+S = "${WORKDIR}/${BPN}-${BPN}-${PV}"
diff --git a/meta-rcar-gen3-adas/recipes-support/nlopt/nlopt_git.bb b/meta-rcar-gen3-adas/recipes-support/nlopt/nlopt_git.bb
new file mode 100644
index 0000000..dd425d9
--- /dev/null
+++ b/meta-rcar-gen3-adas/recipes-support/nlopt/nlopt_git.bb
@@ -0,0 +1,8 @@
+require ${PN}.inc
+
+SRC_URI = "git://github.com/stevengj/${BPN}.git"
+S = "${WORKDIR}/git"
+SRCREV = "cc413c5491df015c93992ddedd43b222d4369b45"
+
+DEFAULT_PREFERENCE = "-1"
+
diff --git a/meta-rcar-gen3-adas/recipes-support/spacenav/libspnav/0001-libspnav-cross-compile.patch b/meta-rcar-gen3-adas/recipes-support/spacenav/libspnav/0001-libspnav-cross-compile.patch
new file mode 100644
index 0000000..3a33da1
--- /dev/null
+++ b/meta-rcar-gen3-adas/recipes-support/spacenav/libspnav/0001-libspnav-cross-compile.patch
@@ -0,0 +1,42 @@
+diff -pruN libspnav-0.2.3.orig/configure libspnav-0.2.3/configure
+--- libspnav-0.2.3.orig/configure 2011-11-25 18:36:43.000000000 -0800
++++ libspnav-0.2.3/configure 2016-03-18 04:46:31.327083251 -0700
+@@ -8,7 +8,7 @@ DBG=yes
+ X11=yes
+
+ srcdir="`dirname "$0"`"
+-libdir=lib
++libdir=lib64
+
+ #if [ "`uname -m`" = 'x86_64' ]; then
+ # libdir=lib64
+diff -pruN libspnav-0.2.3.orig/Makefile.in libspnav-0.2.3/Makefile.in
+--- libspnav-0.2.3.orig/Makefile.in 2014-08-17 18:38:31.000000000 -0700
++++ libspnav-0.2.3/Makefile.in 2016-03-18 04:46:31.339083251 -0700
+@@ -8,10 +8,11 @@ lib_a = lib$(name).a
+ incpaths = -I. -I/usr/local/include -I/usr/X11R6/include
+ libpaths = -L/usr/local/lib -L/usr/X11R6/lib
+
+-CC = gcc
+-AR = ar
+-CFLAGS = $(opt) $(dbg) -std=c89 $(pic) -pedantic -Wall -fno-strict-aliasing $(incpaths) $(user_cflags)
+-LDFLAGS = $(libpaths) $(user_ldflags) $(xlib)
++CC ?= gcc
++AR ?= ar
++CFLAGS ?= -std=c89 -pedantic -Wall -fno-strict-aliasing
++CFLAGS += $(opt) $(dbg) $(pic) -I. $(user_cflags)
++LDFLAGS ?= $(libpaths) $(user_ldflags) $(xlib)
+
+ ifeq ($(shell uname -s), Darwin)
+ lib_so = libspnav.dylib
+@@ -54,8 +55,8 @@ install: $(lib_a) $(lib_so)
+ cp $(lib_so) $(DESTDIR)$(PREFIX)/$(libdir)/$(lib_so)
+ [ -n "$(soname)" ] && \
+ rm -f $(DESTDIR)$(PREFIX)/$(libdir)/$(soname) $(DESTDIR)$(PREFIX)/$(libdir)/$(devlink) && \
+- ln -s $(DESTDIR)$(PREFIX)/$(libdir)/$(lib_so) $(DESTDIR)$(PREFIX)/$(libdir)/$(soname) && \
+- ln -s $(DESTDIR)$(PREFIX)/$(libdir)/$(soname) $(DESTDIR)$(PREFIX)/$(libdir)/$(devlink) || \
++ ln -s $(lib_so) $(DESTDIR)$(PREFIX)/$(libdir)/$(soname) && \
++ ln -s $(soname) $(DESTDIR)$(PREFIX)/$(libdir)/$(devlink) || \
+ true
+ for h in $(hdr); do cp -p $(srcdir)/$$h $(DESTDIR)$(PREFIX)/include/; done
+
diff --git a/meta-rcar-gen3-adas/recipes-support/spacenav/libspnav/0002-Fix-configuration-for-libdir.patch b/meta-rcar-gen3-adas/recipes-support/spacenav/libspnav/0002-Fix-configuration-for-libdir.patch
new file mode 100644
index 0000000..8976eb6
--- /dev/null
+++ b/meta-rcar-gen3-adas/recipes-support/spacenav/libspnav/0002-Fix-configuration-for-libdir.patch
@@ -0,0 +1,87 @@
+From c79af49c33f8ce705f63dee9dbc48cd716064e98 Mon Sep 17 00:00:00 2001
+From: Andrey Vostrikov <andrey.vostrikov@cogentembedded.com>
+Date: Fri, 22 Apr 2016 13:38:21 +0300
+Subject: [PATCH] Fix configuration for libdir
+
+Signed-off-by: Andrey Vostrikov <andrey.vostrikov@cogentembedded.com>
+---
+ Makefile.in | 18 +++++++++---------
+ configure | 13 +++++++------
+ 2 files changed, 16 insertions(+), 15 deletions(-)
+
+diff --git a/Makefile.in b/Makefile.in
+index eb996a9..6808e44 100644
+--- a/Makefile.in
++++ b/Makefile.in
+@@ -50,22 +50,22 @@ distclean:
+
+ .PHONY: install
+ install: $(lib_a) $(lib_so)
+- mkdir -p $(DESTDIR)$(PREFIX)/$(libdir) $(DESTDIR)$(PREFIX)/include
+- cp $(lib_a) $(DESTDIR)$(PREFIX)/$(libdir)/$(lib_a)
+- cp $(lib_so) $(DESTDIR)$(PREFIX)/$(libdir)/$(lib_so)
++ mkdir -p $(DESTDIR)/$(libdir) $(DESTDIR)$(PREFIX)/include
++ cp $(lib_a) $(DESTDIR)/$(libdir)/$(lib_a)
++ cp $(lib_so) $(DESTDIR)/$(libdir)/$(lib_so)
+ [ -n "$(soname)" ] && \
+- rm -f $(DESTDIR)$(PREFIX)/$(libdir)/$(soname) $(DESTDIR)$(PREFIX)/$(libdir)/$(devlink) && \
+- ln -s $(lib_so) $(DESTDIR)$(PREFIX)/$(libdir)/$(soname) && \
+- ln -s $(soname) $(DESTDIR)$(PREFIX)/$(libdir)/$(devlink) || \
++ rm -f $(DESTDIR)/$(libdir)/$(soname) $(DESTDIR)/$(libdir)/$(devlink) && \
++ ln -s $(lib_so) $(DESTDIR)/$(libdir)/$(soname) && \
++ ln -s $(soname) $(DESTDIR)/$(libdir)/$(devlink) || \
+ true
+ for h in $(hdr); do cp -p $(srcdir)/$$h $(DESTDIR)$(PREFIX)/include/; done
+
+ .PHONY: uninstall
+ uninstall:
+- rm -f $(DESTDIR)$(PREFIX)/$(libdir)/$(lib_a)
+- rm -f $(DESTDIR)$(PREFIX)/$(libdir)/$(lib_so)
++ rm -f $(DESTDIR)/$(libdir)/$(lib_a)
++ rm -f $(DESTDIR)/$(libdir)/$(lib_so)
+ [ -n "$(soname)" ] && \
+- rm -f $(DESTDIR)$(PREFIX)/$(libdir)/$(soname) $(DESTDIR)$(PREFIX)/$(libdir)/$(devlink) || \
++ rm -f $(DESTDIR)/$(libdir)/$(soname) $(DESTDIR)/$(libdir)/$(devlink) || \
+ true
+ for i in $(hdr); do rm -f $(DESTDIR)$(PREFIX)/include/$$i; done
+
+diff --git a/configure b/configure
+index 6f85fec..7f6289d 100755
+--- a/configure
++++ b/configure
+@@ -8,18 +8,18 @@ DBG=yes
+ X11=yes
+
+ srcdir="`dirname "$0"`"
+-libdir=lib64
+-
+-#if [ "`uname -m`" = 'x86_64' ]; then
+-# libdir=lib64
+-#fi
+-
++libdir=/usr/lib
++echo "initial $prefix"
+ for arg; do
+ case "$arg" in
+ --prefix=*)
+ value=`echo $arg | sed 's/--prefix=//'`
+ PREFIX=${value:-$prefix}
+ ;;
++ --libdir=*)
++ value=`echo $arg | sed 's/--libdir=//'`
++ libdir=${value:-$libdir}
++ ;;
+
+ --enable-opt)
+ OPT=yes;;
+@@ -53,6 +53,7 @@ for arg; do
+ done
+
+ echo " prefix: $PREFIX"
++echo " libdir: $libdir"
+ echo " optimize for speed: $OPT"
+ echo " include debugging symbols: $DBG"
+ echo " x11 communication method: $X11"
+--
+2.1.4
+
diff --git a/meta-rcar-gen3-adas/recipes-support/spacenav/libspnav/libspnav-0.2.3.tar.gz b/meta-rcar-gen3-adas/recipes-support/spacenav/libspnav/libspnav-0.2.3.tar.gz
new file mode 100644
index 0000000..ed9da47
--- /dev/null
+++ b/meta-rcar-gen3-adas/recipes-support/spacenav/libspnav/libspnav-0.2.3.tar.gz
Binary files differ
diff --git a/meta-rcar-gen3-adas/recipes-support/spacenav/libspnav_0.2.3.bb b/meta-rcar-gen3-adas/recipes-support/spacenav/libspnav_0.2.3.bb
new file mode 100644
index 0000000..8586a7c
--- /dev/null
+++ b/meta-rcar-gen3-adas/recipes-support/spacenav/libspnav_0.2.3.bb
@@ -0,0 +1,24 @@
+SUMMARY = "SpaceNavigator 3D-mouse daemon interface library"
+SECTION = "libs/multimedia"
+LICENSE = "BSD"
+LIC_FILES_CHKSUM = "file://README;md5=a8f5600270c9340ba8f2d956133a91d3"
+
+SRC_URI = " \
+ file://libspnav-0.2.3.tar.gz \
+ file://0001-libspnav-cross-compile.patch \
+ file://0002-Fix-configuration-for-libdir.patch \
+"
+
+SRC_URI[md5sum] = "44d840540d53326d4a119c0f1aa7bf0a"
+SRC_URI[sha256sum] = "7ae4d7bb7f6a5dda28b487891e01accc856311440f582299760dace6ee5f1f93"
+
+S = "${WORKDIR}/libspnav-${PV}"
+
+inherit autotools pkgconfig
+
+B = "${WORKDIR}/libspnav-${PV}"
+
+# Disable X11 protocol
+EXTRA_OECONF = "--disable-x11"
+
+FILES_${PN} = " ${libdir} "
diff --git a/meta-rcar-gen3-adas/recipes-support/spacenav/spacenavd/0001-spacenavd-cross-compile.patch b/meta-rcar-gen3-adas/recipes-support/spacenav/spacenavd/0001-spacenavd-cross-compile.patch
new file mode 100644
index 0000000..ed4cc51
--- /dev/null
+++ b/meta-rcar-gen3-adas/recipes-support/spacenav/spacenavd/0001-spacenavd-cross-compile.patch
@@ -0,0 +1,95 @@
+diff -pruN spacenavd-0.6.orig/configure spacenavd-0.6/configure
+--- spacenavd-0.6.orig/configure 2012-05-16 20:56:12.000000000 -0700
++++ spacenavd-0.6/configure 2016-03-18 04:35:24.259067397 -0700
+@@ -154,25 +154,25 @@ cat "$srcdir/Makefile.in" >>Makefile
+
+ # create config.h
+ echo 'creating config.h'
+-echo '#ifndef CONFIG_H_' >src/config.h
+-echo '#define CONFIG_H_' >>src/config.h
+-echo >>src/config.h
++echo '#ifndef CONFIG_H_' >$srcdir/src/config.h
++echo '#define CONFIG_H_' >>$srcdir/src/config.h
++echo >>$srcdir/src/config.h
+ if [ "$X11" = yes ]; then
+- echo '#define USE_X11' >>src/config.h
+- echo >>src/config.h
++ echo '#define USE_X11' >>$srcdir/src/config.h
++ echo >>$srcdir/src/config.h
+ fi
+ if [ "$HOTPLUG" = yes ]; then
+- echo '#define USE_NETLINK' >>src/config.h
+- echo >>src/config.h
++ echo '#define USE_NETLINK' >>$srcdir/src/config.h
++ echo >>$srcdir/src/config.h
+ fi
+-echo '#define VERSION "'$VER'"' >>src/config.h
+-echo >>src/config.h
++echo '#define VERSION "'$VER'"' >>$srcdir/src/config.h
++echo >>$srcdir/src/config.h
+
+ # check for alloca.h
+-check_header alloca.h >>src/config.h
++check_header alloca.h >>$srcdir/src/config.h
+
+-echo >>src/config.h
+-echo '#endif /* CONFIG_H_ */' >>src/config.h
++echo >>$srcdir/src/config.h
++echo '#endif /* CONFIG_H_ */' >>$srcdir/src/config.h
+
+ echo ''
+ echo 'Done. You can now type make (or gmake) to compile spacenavd.'
+diff -pruN spacenavd-0.6.orig/Makefile.in spacenavd-0.6/Makefile.in
+--- spacenavd-0.6.orig/Makefile.in 2013-06-25 17:12:28.000000000 -0700
++++ spacenavd-0.6/Makefile.in 2016-03-18 04:44:10.451079903 -0700
+@@ -1,14 +1,14 @@
+-src = $(wildcard src/*.c) $(wildcard src/serial/*.c) $(wildcard src/magellan/*.c)
+-hdr = $(wildcard src/*.h) $(wildcard src/serial/*.h) $(wildcard src/magellan/*.h)
++src = $(wildcard $(srcdir)/src/*.c) $(wildcard $(srcdir)/src/serial/*.c) $(wildcard $(srcdir)/src/magellan/*.c)
++hdr = $(wildcard $(srcdir)/src/*.h) $(wildcard $(srcdir)/src/serial/*.h) $(wildcard $(srcdir)/src/magellan/*.h)
+ obj = $(src:.c=.o)
+ dep = $(obj:.o=.d)
+ bin = spacenavd
+-ctl = spnavd_ctl
+
+-CC = gcc
++CC ?= gcc
+ INSTALL = install
+-CFLAGS = -pedantic -Wall $(dbg) $(opt) -fno-strict-aliasing -I$(srcdir)/src -I/usr/local/include $(add_cflags)
+-LDFLAGS = -L/usr/local/lib $(xlib) $(add_ldflags)
++CFLAGS ?= -pedantic -Wall -fno-strict-aliasing -I/usr/local/include $(add_cflags)
++CFLAGS += $(dbg) $(opt) -I$(srcdir)/src
++LDFLAGS ?= -L/usr/local/lib $(xlib) $(add_ldflags)
+
+ $(bin): $(obj)
+ $(CC) -o $@ $(obj) $(LDFLAGS)
+@@ -36,7 +36,6 @@ cleandep:
+ install: $(bin)
+ $(INSTALL) -d $(DESTDIR)$(PREFIX)/bin
+ $(INSTALL) -m 755 $(bin) $(DESTDIR)$(PREFIX)/bin/$(bin)
+- $(INSTALL) -m 755 $(srcdir)/$(ctl) $(DESTDIR)$(PREFIX)/bin/$(ctl)
+ cd $(srcdir) && ./setup_init --no-install
+
+ # [ -d /etc/hal/fdi/policy ] && \
+@@ -45,7 +44,5 @@ install: $(bin)
+ .PHONY: uninstall
+ uninstall:
+ rm -f $(DESTDIR)$(PREFIX)/bin/$(bin)
+- rm -f $(DESTDIR)$(PREFIX)/bin/$(ctl)
+- rm -f $(DESTDIR)/etc/hal/fdi/policy/spacenav.fdi
+
+ # cd $(srcdir) && ./setup_init remove
+diff -pruN spacenavd-0.6.orig/src/config.h spacenavd-0.6/src/config.h
+--- spacenavd-0.6.orig/src/config.h 1969-12-31 16:00:00.000000000 -0800
++++ spacenavd-0.6/src/config.h 2016-03-18 04:35:24.295067398 -0700
+@@ -0,0 +1,10 @@
++#ifndef CONFIG_H_
++#define CONFIG_H_
++
++#define USE_NETLINK
++
++#define VERSION ""
++
++#define HAVE_ALLOCA_H
++
++#endif /* CONFIG_H_ */
diff --git a/meta-rcar-gen3-adas/recipes-support/spacenav/spacenavd/0002-Fix-build-configuration.patch b/meta-rcar-gen3-adas/recipes-support/spacenav/spacenavd/0002-Fix-build-configuration.patch
new file mode 100644
index 0000000..a2500b9
--- /dev/null
+++ b/meta-rcar-gen3-adas/recipes-support/spacenav/spacenavd/0002-Fix-build-configuration.patch
@@ -0,0 +1,27 @@
+From 10138bf87a7d4c23ce3c067455fb299410b37a49 Mon Sep 17 00:00:00 2001
+From: Andrey Vostrikov <andrey.vostrikov@cogentembedded.com>
+Date: Fri, 22 Apr 2016 13:36:28 +0300
+Subject: [PATCH] Fix build configuration
+
+Signed-off-by: Andrey Vostrikov <andrey.vostrikov@cogentembedded.com>
+---
+ Makefile.in | 6 +++---
+ configure | 16 ++++++++--------
+ 2 files changed, 11 insertions(+), 11 deletions(-)
+
+diff --git a/Makefile.in b/Makefile.in
+index 27d1a21..48dc517 100644
+--- a/Makefile.in
++++ b/Makefile.in
+@@ -8,7 +8,7 @@ CC ?= gcc
+ INSTALL = install
+ CFLAGS ?= -pedantic -Wall -fno-strict-aliasing -I/usr/local/include $(add_cflags)
+ CFLAGS += $(dbg) $(opt) -I$(srcdir)/src
+-LDFLAGS ?= -L/usr/local/lib $(xlib) $(add_ldflags)
++LDFLAGS ?= -L/usr/lib64 $(xlib) $(add_ldflags)
+
+ $(bin): $(obj)
+ $(CC) -o $@ $(obj) $(LDFLAGS)
+diff --git a/configure b/configure
+index 2795a3c..c016b33 100755
+
diff --git a/meta-rcar-gen3-adas/recipes-support/spacenav/spacenavd/spacenavd-0.6.tar.gz b/meta-rcar-gen3-adas/recipes-support/spacenav/spacenavd/spacenavd-0.6.tar.gz
new file mode 100644
index 0000000..fa9fa37
--- /dev/null
+++ b/meta-rcar-gen3-adas/recipes-support/spacenav/spacenavd/spacenavd-0.6.tar.gz
Binary files differ
diff --git a/meta-rcar-gen3-adas/recipes-support/spacenav/spacenavd/spacenavd.service b/meta-rcar-gen3-adas/recipes-support/spacenav/spacenavd/spacenavd.service
new file mode 100644
index 0000000..46302a6
--- /dev/null
+++ b/meta-rcar-gen3-adas/recipes-support/spacenav/spacenavd/spacenavd.service
@@ -0,0 +1,13 @@
+[Unit]
+Description=Spacenavd startup
+RequiresMountsFor=/run
+
+[Service]
+User=root
+EnvironmentFile=-/etc/default/spacenavd
+ExecStart=/usr/bin/spacenavd $OPTARGS
+Type=forking
+
+[Install]
+WantedBy=multi-user.target
+
diff --git a/meta-rcar-gen3-adas/recipes-support/spacenav/spacenavd_0.6.bb b/meta-rcar-gen3-adas/recipes-support/spacenav/spacenavd_0.6.bb
new file mode 100644
index 0000000..943aa9a
--- /dev/null
+++ b/meta-rcar-gen3-adas/recipes-support/spacenav/spacenavd_0.6.bb
@@ -0,0 +1,39 @@
+SUMMARY = "Userspace library to SpaceNavigator 3D-mouse"
+SECTION = "libs/multimedia"
+LICENSE = "GPLv3"
+LIC_FILES_CHKSUM = "file://COPYING;md5=d32239bcb673463ab874e80d47fae504"
+
+BBCLASSEXTEND = "native nativesdk"
+
+SRC_URI = " \
+ file://spacenavd-0.6.tar.gz \
+ file://0001-spacenavd-cross-compile.patch \
+ file://0002-Fix-build-configuration.patch \
+"
+
+SRC_URI[md5sum] = "7e2c04fb8dbb7d39b9ee7b64565e0c4f"
+SRC_URI[sha256sum] = "c2d203bf96c5a959590146a43fe5d6e5e8c5c38a8b2f55aa199d967d0d88d0ab"
+
+S = "${WORKDIR}/spacenavd-${PV}"
+B = "${S}"
+
+inherit autotools pkgconfig useradd systemd
+
+# Don't configure udev by default since it will cause a circular
+# dependecy with udev package, which depends on libusb
+EXTRA_OECONF = " --disable-x11"
+
+SRC_URI_append = " file://spacenavd.service"
+
+SYSTEMD_SERVICE_${PN} = "spacenavd.service"
+
+USERADD_PACKAGES = "${PN}"
+GROUPADD_PARAM_${PN} = "--system spacenavd"
+
+do_install_append() {
+ if ${@bb.utils.contains('DISTRO_FEATURES', 'systemd', 'true', 'false', d)}; then
+ install -d ${D}${systemd_unitdir}/system/
+ install -m 0644 ${WORKDIR}/spacenavd.service ${D}${systemd_unitdir}/system/
+ fi
+}
+