--- /dev/null
+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.
+
+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. 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.
--- /dev/null
+This README file contains information on the contents of the meta-somdevices layer.
+
+Please see the corresponding sections below for details.
+
+Dependencies
+============
+
+ URI: <first dependency>
+ branch: <branch name>
+
+ URI: <second dependency>
+ branch: <branch name>
+
+ .
+ .
+ .
+
+Patches
+=======
+
+Please submit any patches against the meta-somdevices layer to the xxxx mailing list (xxxx@zzzz.org)
+and cc: the maintainer:
+
+Maintainer: XXX YYYYYY <xxx.yyyyyy@zzzzz.com>
+
+Table of Contents
+=================
+
+ I. Adding the meta-somdevices layer to your build
+ II. Misc
+
+
+I. Adding the meta-somdevices layer to your build
+=================================================
+
+Run 'bitbake-layers add-layer meta-somdevices'
+
+II. Misc
+========
+
+--- replace with specific information about the meta-somdevices layer ---
--- /dev/null
+# We have a conf and classes directory, add to BBPATH
+BBPATH .= ":${LAYERDIR}"
+
+# We have a recipes directory, add to BBFILES
+BBFILES += "${LAYERDIR}/recipes-*/*/*.bb \
+ ${LAYERDIR}/recipes-*/*/*.bbappend"
+
+BBFILE_COLLECTIONS += "somdevices"
+BBFILE_PATTERN_somdevices = "^${LAYERDIR}/"
+BBFILE_PRIORITY_somdevices = "9"
+LAYERSERIES_COMPAT_somdevices = "hardknott"
+
+UBOOT_DTB_NAME_imx8mm-somdevices-c0p1 = "imx8mm-evk.dtb"
+KERNEL_DEVICETREE_imx8mm-somdevices-c0p1 = "freescale/imx8mm-somdevices-c0p1.dtb"
+
+# Avoid multiple runtime providers for u-boot-default-env
+PREFERRED_RPROVIDER_u-boot-default-env ??= "${IMX_DEFAULT_BOOTLOADER}"
--- /dev/null
+#@TYPE: Machine
+#@NAME: NXP i.MX8MM LPDDR4 SomDevices SMARC
+#@SOC: i.MX8MM
+#@DESCRIPTION: Machine configuration for SomDevices SMARC imx8mm
+#@MAINTAINER: SomDevices <somdevices@somdevices.com>
+
+MACHINEOVERRIDES =. "mx8:mx8m:mx8mm:"
+
+require conf/machine/include/imx-base.inc
+require conf/machine/include/tune-cortexa53.inc
+
+MACHINE_FEATURES += " pci wifi bluetooth optee"
+KERNEL_DEVICETREE = "freescale/imx8mm-somdevices-c0p1.dtb"
+
+UBOOT_CONFIG ??= "sd"
+UBOOT_CONFIG[sd] = "imx8mm_evk_config,sdcard"
+UBOOT_CONFIG[fspi] = "imx8mm_evk_fspi_defconfig"
+UBOOT_CONFIG[mfgtool] = "imx8mm_evk_config"
+SPL_BINARY = "spl/u-boot-spl.bin"
+
+# Set DDR FIRMWARE
+DDR_FIRMWARE_NAME = "lpddr4_pmu_train_1d_imem.bin lpddr4_pmu_train_1d_dmem.bin lpddr4_pmu_train_2d_imem.bin lpddr4_pmu_train_2d_dmem.bin"
+
+# Set u-boot DTB
+UBOOT_DTB_NAME = "fsl-imx8mm-evk.dtb"
+
+# Set imx-mkimage boot target
+IMXBOOT_TARGETS = "${@bb.utils.contains('UBOOT_CONFIG', 'fspi', 'flash_evk_flexspi', 'flash_evk', d)}"
+
+# Set Serial console
+SERIAL_CONSOLES = "115200;ttymxc1"
+
+IMAGE_BOOTLOADER = "imx-boot"
+
+LOADADDR = ""
+UBOOT_SUFFIX = "bin"
+UBOOT_MAKE_TARGET = ""
+IMX_BOOT_SEEK = "33"
+
+OPTEE_BIN_EXT = "8mm"
--- /dev/null
+From 5b452d3f172774859a273db5535587bcdc0a6760 Mon Sep 17 00:00:00 2001
+From: Josep Orga <jorga@somdevices.com>
+Date: Wed, 30 Jun 2021 19:52:08 +0200
+Subject: [PATCH] imx: Add somdevices imx8mm lpddr4 configuration.
+
+Signed-off-by: Josep Orga <jorga@somdevices.com>
+---
+ board/freescale/imx8mm_evk/lpddr4_timing.c | 78 +++++++++++-----------
+ 1 file changed, 39 insertions(+), 39 deletions(-)
+
+diff --git a/board/freescale/imx8mm_evk/lpddr4_timing.c b/board/freescale/imx8mm_evk/lpddr4_timing.c
+index 3495b9c931..348b0b8e8d 100644
+--- a/board/freescale/imx8mm_evk/lpddr4_timing.c
++++ b/board/freescale/imx8mm_evk/lpddr4_timing.c
+@@ -1,22 +1,27 @@
+ /*
+- * Copyright 2018-2019 NXP
++ * Copyright 2019 NXP
+ *
+ * SPDX-License-Identifier: GPL-2.0+
+ *
+ * Generated code from MX8M_DDR_tool
++ *
++ * Align with uboot version:
++ * imx_v2019.04_5.4.x and above version
++ * For imx_v2018.03_4.14.78_1.0.0_ga ~ imx_v2018.04_4.19.35_1.1.0_ga:
++ * please replace #include <asm/arch/ddr.h> with #include <asm/arch/imx8m_ddr.h>
+ */
+
+ #include <linux/kernel.h>
+ #include <asm/arch/ddr.h>
+
+ struct dram_cfg_param ddr_ddrc_cfg[] = {
+- /* Initialize DDRC registers */
++ /** Initialize DDRC registers **/
+ { 0x3d400304, 0x1 },
+ { 0x3d400030, 0x1 },
+ { 0x3d400000, 0xa1080020 },
+- { 0x3d400020, 0x223 },
+- { 0x3d400024, 0x16e3600 },
+- { 0x3d400064, 0x5b00d2 },
++ { 0x3d400020, 0x203 },
++ { 0x3d400024, 0x3a980 },
++ { 0x3d400064, 0x5b0087 },
+ { 0x3d4000d0, 0xc00305ba },
+ { 0x3d4000d4, 0x940000 },
+ { 0x3d4000dc, 0xd4002d },
+@@ -32,7 +37,7 @@ struct dram_cfg_param ddr_ddrc_cfg[] = {
+ { 0x3d40011c, 0x401 },
+ { 0x3d400130, 0x20600 },
+ { 0x3d400134, 0xc100002 },
+- { 0x3d400138, 0xd8 },
++ { 0x3d400138, 0x8d },
+ { 0x3d400144, 0x96004b },
+ { 0x3d400180, 0x2ee0017 },
+ { 0x3d400184, 0x2605b8e },
+@@ -45,7 +50,7 @@ struct dram_cfg_param ddr_ddrc_cfg[] = {
+ { 0x3d4001a8, 0x80000000 },
+ { 0x3d4001b0, 0x11 },
+ { 0x3d4001c0, 0x1 },
+- { 0x3d4001c4, 0x0 },
++ { 0x3d4001c4, 0x1 },
+ { 0x3d4000f4, 0xc99 },
+ { 0x3d400108, 0x70e1617 },
+ { 0x3d400200, 0x1f },
+@@ -53,9 +58,7 @@ struct dram_cfg_param ddr_ddrc_cfg[] = {
+ { 0x3d400210, 0x1f1f },
+ { 0x3d400204, 0x80808 },
+ { 0x3d400214, 0x7070707 },
+- { 0x3d400218, 0x7070707 },
+-
+- /* performance setting */
++ { 0x3d400218, 0xf070707 },
+ { 0x3d400250, 0x29001701 },
+ { 0x3d400254, 0x2c },
+ { 0x3d40025c, 0x4000030 },
+@@ -67,12 +70,10 @@ struct dram_cfg_param ddr_ddrc_cfg[] = {
+ { 0x3d400498, 0x620096 },
+ { 0x3d40049c, 0x1100e07 },
+ { 0x3d4004a0, 0xc8012c },
+-
+- /* P1: 400mts */
+- { 0x3d402020, 0x21 },
+- { 0x3d402024, 0x30d400 },
++ { 0x3d402020, 0x1 },
++ { 0x3d402024, 0x7d00 },
+ { 0x3d402050, 0x20d040 },
+- { 0x3d402064, 0xc001c },
++ { 0x3d402064, 0xc0012 },
+ { 0x3d4020dc, 0x840000 },
+ { 0x3d4020e0, 0x310000 },
+ { 0x3d4020e8, 0x66004d },
+@@ -87,18 +88,17 @@ struct dram_cfg_param ddr_ddrc_cfg[] = {
+ { 0x3d40211c, 0x301 },
+ { 0x3d402130, 0x20300 },
+ { 0x3d402134, 0xa100002 },
+- { 0x3d402138, 0x1d },
++ { 0x3d402138, 0x13 },
+ { 0x3d402144, 0x14000a },
+ { 0x3d402180, 0x640004 },
+ { 0x3d402190, 0x3818200 },
+ { 0x3d402194, 0x80303 },
+ { 0x3d4021b4, 0x100 },
+-
+- /* p2: 100mts */
+- { 0x3d403020, 0x21 },
+- { 0x3d403024, 0xc3500 },
++ { 0x3d4020f4, 0xc99 },
++ { 0x3d403020, 0x1 },
++ { 0x3d403024, 0x1f40 },
+ { 0x3d403050, 0x20d040 },
+- { 0x3d403064, 0x30007 },
++ { 0x3d403064, 0x30005 },
+ { 0x3d4030dc, 0x840000 },
+ { 0x3d4030e0, 0x310000 },
+ { 0x3d4030e8, 0x66004d },
+@@ -113,14 +113,13 @@ struct dram_cfg_param ddr_ddrc_cfg[] = {
+ { 0x3d40311c, 0x301 },
+ { 0x3d403130, 0x20300 },
+ { 0x3d403134, 0xa100002 },
+- { 0x3d403138, 0x8 },
++ { 0x3d403138, 0x5 },
+ { 0x3d403144, 0x50003 },
+ { 0x3d403180, 0x190004 },
+ { 0x3d403190, 0x3818200 },
+ { 0x3d403194, 0x80303 },
+ { 0x3d4031b4, 0x100 },
+-
+- /* default boot point */
++ { 0x3d4030f4, 0xc99 },
+ { 0x3d400028, 0x0 },
+ };
+
+@@ -136,20 +135,20 @@ struct dram_cfg_param ddr_ddrphy_cfg[] = {
+ { 0x100a7, 0x7 },
+ { 0x110a0, 0x0 },
+ { 0x110a1, 0x1 },
+- { 0x110a2, 0x3 },
+- { 0x110a3, 0x4 },
+- { 0x110a4, 0x5 },
+- { 0x110a5, 0x2 },
+- { 0x110a6, 0x7 },
+- { 0x110a7, 0x6 },
++ { 0x110a2, 0x2 },
++ { 0x110a3, 0x3 },
++ { 0x110a4, 0x4 },
++ { 0x110a5, 0x5 },
++ { 0x110a6, 0x6 },
++ { 0x110a7, 0x7 },
+ { 0x120a0, 0x0 },
+- { 0x120a1, 0x1 },
+- { 0x120a2, 0x3 },
+- { 0x120a3, 0x2 },
+- { 0x120a4, 0x5 },
+- { 0x120a5, 0x4 },
+- { 0x120a6, 0x7 },
+- { 0x120a7, 0x6 },
++ { 0x120a1, 0x6 },
++ { 0x120a2, 0x7 },
++ { 0x120a3, 0x5 },
++ { 0x120a4, 0x4 },
++ { 0x120a5, 0x2 },
++ { 0x120a6, 0x3 },
++ { 0x120a7, 0x1 },
+ { 0x130a0, 0x0 },
+ { 0x130a1, 0x1 },
+ { 0x130a2, 0x2 },
+@@ -208,8 +207,8 @@ struct dram_cfg_param ddr_ddrphy_cfg[] = {
+ { 0x220024, 0x1ab },
+ { 0x2003a, 0x0 },
+ { 0x20056, 0x3 },
+- { 0x120056, 0xa },
+- { 0x220056, 0xa },
++ { 0x120056, 0x3 },
++ { 0x220056, 0x3 },
+ { 0x1004d, 0xe00 },
+ { 0x1014d, 0xe00 },
+ { 0x1104d, 0xe00 },
+@@ -1850,3 +1849,4 @@ struct dram_timing_info dram_timing = {
+ .ddrphy_pie_num = ARRAY_SIZE(ddr_phy_pie),
+ .fsp_table = { 3000, 400, 100, },
+ };
++
+--
+2.17.1
+
--- /dev/null
+From eb818b6d998dbae07ff690286bc6d9a127567994 Mon Sep 17 00:00:00 2001
+From: josep orga <jorga@somdevices.com>
+Date: Thu, 1 Jul 2021 13:13:15 +0000
+Subject: [PATCH] change memory size 2G to 1G
+
+---
+ arch/arm/dts/imx8mm-evk.dtsi | 2 +-
+ include/configs/imx8mm_evk.h | 5 +++--
+ 2 files changed, 4 insertions(+), 3 deletions(-)
+
+diff --git a/arch/arm/dts/imx8mm-evk.dtsi b/arch/arm/dts/imx8mm-evk.dtsi
+index 097fdce9e1..a3c8be9048 100644
+--- a/arch/arm/dts/imx8mm-evk.dtsi
++++ b/arch/arm/dts/imx8mm-evk.dtsi
+@@ -15,7 +15,7 @@
+
+ memory@40000000 {
+ device_type = "memory";
+- reg = <0x0 0x40000000 0 0x80000000>;
++ reg = <0x0 0x40000000 0 0x40000000>;
+ };
+
+ leds {
+diff --git a/include/configs/imx8mm_evk.h b/include/configs/imx8mm_evk.h
+index f5bcdd245e..8a8f171408 100644
+--- a/include/configs/imx8mm_evk.h
++++ b/include/configs/imx8mm_evk.h
+@@ -204,7 +204,7 @@
+ #define CONFIG_SYS_LOAD_ADDR CONFIG_LOADADDR
+
+ #define CONFIG_SYS_INIT_RAM_ADDR 0x40000000
+-#define CONFIG_SYS_INIT_RAM_SIZE 0x200000
++#define CONFIG_SYS_INIT_RAM_SIZE 0x100000
+ #define CONFIG_SYS_INIT_SP_OFFSET \
+ (CONFIG_SYS_INIT_RAM_SIZE - GENERATED_GBL_DATA_SIZE)
+ #define CONFIG_SYS_INIT_SP_ADDR \
+@@ -224,7 +224,8 @@
+
+ #define CONFIG_SYS_SDRAM_BASE 0x40000000
+ #define PHYS_SDRAM 0x40000000
+-#define PHYS_SDRAM_SIZE 0x80000000 /* 2GB DDR */
++#define PHYS_SDRAM_SIZE 0x40000000 /* 1GB DDR */
++#define CONFIG_NR_DRAM_BANKS 1
+
+ #define CONFIG_MXC_UART_BASE UART2_BASE_ADDR
+
+--
+2.25.1
+
--- /dev/null
+From 1acd222f1cca4e34d34ec9399998cd85fbb5176f Mon Sep 17 00:00:00 2001
+From: eduard gavin <e@somdevices.com>
+Date: Sun, 4 Jul 2021 10:59:39 +0000
+Subject: [PATCH] Change usd-cd gpio
+
+---
+ arch/arm/dts/imx8mm-evk.dtsi | 5 +++--
+ 1 file changed, 3 insertions(+), 2 deletions(-)
+
+diff --git a/arch/arm/dts/imx8mm-evk.dtsi b/arch/arm/dts/imx8mm-evk.dtsi
+index a3c8be9048..d96275c7ff 100644
+--- a/arch/arm/dts/imx8mm-evk.dtsi
++++ b/arch/arm/dts/imx8mm-evk.dtsi
+@@ -403,7 +403,7 @@
+ pinctrl-0 = <&pinctrl_usdhc2>, <&pinctrl_usdhc2_gpio>;
+ pinctrl-1 = <&pinctrl_usdhc2_100mhz>, <&pinctrl_usdhc2_gpio>;
+ pinctrl-2 = <&pinctrl_usdhc2_200mhz>, <&pinctrl_usdhc2_gpio>;
+- cd-gpios = <&gpio1 15 GPIO_ACTIVE_LOW>;
++ cd-gpios = <&gpio2 12 GPIO_ACTIVE_LOW>;
+ bus-width = <4>;
+ vmmc-supply = <®_usdhc2_vmmc>;
+ status = "okay";
+@@ -573,7 +573,8 @@
+
+ pinctrl_usdhc2_gpio: usdhc2grpgpiogrp {
+ fsl,pins = <
+- MX8MM_IOMUXC_GPIO1_IO15_GPIO1_IO15 0x1c4
++// MX8MM_IOMUXC_GPIO1_IO15_GPIO1_IO15 0x1c4
++ MX8MM_IOMUXC_SD2_CD_B_GPIO2_IO12 0x1c4
+ >;
+ };
+
+--
+2.25.1
+
--- /dev/null
+From f068f583a25cc552aa9ece3b378a49858f13e7c1 Mon Sep 17 00:00:00 2001
+From: eduard gavin <e@somdevices.com>
+Date: Wed, 7 Jul 2021 20:42:39 +0000
+Subject: [PATCH] Change uart2 pinmux
+
+---
+ arch/arm/dts/imx8mm-evk.dtsi | 4 ++--
+ 1 file changed, 2 insertions(+), 2 deletions(-)
+
+diff --git a/arch/arm/dts/imx8mm-evk.dtsi b/arch/arm/dts/imx8mm-evk.dtsi
+index d96275c7ff..952173f815 100644
+--- a/arch/arm/dts/imx8mm-evk.dtsi
++++ b/arch/arm/dts/imx8mm-evk.dtsi
+@@ -566,8 +566,8 @@
+
+ pinctrl_uart2: uart2grp {
+ fsl,pins = <
+- MX8MM_IOMUXC_UART2_RXD_UART2_DCE_RX 0x140
+- MX8MM_IOMUXC_UART2_TXD_UART2_DCE_TX 0x140
++ MX8MM_IOMUXC_SAI3_TXC_UART2_DCE_TX 0x140
++ MX8MM_IOMUXC_SAI3_TXFS_UART2_DCE_RX 0x140
+ >;
+ };
+
+--
+2.25.1
+
--- /dev/null
+From a2d880ece8c0fc196c6fd1bb0e11f578641a2fc4 Mon Sep 17 00:00:00 2001
+From: eduard gavin <e@somdevices.com>
+Date: Wed, 7 Jul 2021 21:41:17 +0000
+Subject: [PATCH] Change UART2 PAD on imx8mm_evk.c
+
+---
+ board/freescale/imx8mm_evk/imx8mm_evk.c | 4 ++--
+ 1 file changed, 2 insertions(+), 2 deletions(-)
+
+diff --git a/board/freescale/imx8mm_evk/imx8mm_evk.c b/board/freescale/imx8mm_evk/imx8mm_evk.c
+index eaa2c6b7f1..1ff74f43ae 100644
+--- a/board/freescale/imx8mm_evk/imx8mm_evk.c
++++ b/board/freescale/imx8mm_evk/imx8mm_evk.c
+@@ -28,8 +28,8 @@ DECLARE_GLOBAL_DATA_PTR;
+ #define WDOG_PAD_CTRL (PAD_CTL_DSE6 | PAD_CTL_ODE | PAD_CTL_PUE | PAD_CTL_PE)
+
+ static iomux_v3_cfg_t const uart_pads[] = {
+- IMX8MM_PAD_UART2_RXD_UART2_RX | MUX_PAD_CTRL(UART_PAD_CTRL),
+- IMX8MM_PAD_UART2_TXD_UART2_TX | MUX_PAD_CTRL(UART_PAD_CTRL),
++ IMX8MM_PAD_SAI3_TXC_UART2_TX | MUX_PAD_CTRL(UART_PAD_CTRL),
++ IMX8MM_PAD_SAI3_TXFS_UART2_RX | MUX_PAD_CTRL(UART_PAD_CTRL),
+ };
+
+ static iomux_v3_cfg_t const wdog_pads[] = {
+--
+2.25.1
+
--- /dev/null
+FILESEXTRAPATHS_prepend := "${THISDIR}/files:"
+
+SRC_URI_append_imx8mm-somdevices-c0p1 += " \
+ file://0001-imx-Add-somdevices-imx8mm-lpddr4-configuration.patch \
+ file://0002-change-memory-size-2G-to-1G.patch \
+ file://0003-Change-usd-cd-gpio.patch \
+ file://0004-Change-uart2-pinmux.patch \
+ file://0005-Change-uart2-PAD-on-imx8mm_evk.c.patch \
+"
--- /dev/null
+SUMMARY = "bitbake-layers recipe"
+DESCRIPTION = "Recipe created by bitbake-layers"
+LICENSE = "MIT"
+
+python do_display_banner() {
+ bb.plain("***********************************************");
+ bb.plain("* *");
+ bb.plain("* Example recipe created by bitbake-layers *");
+ bb.plain("* *");
+ bb.plain("***********************************************");
+}
+
+addtask display_banner before do_build
--- /dev/null
+From 17a4ba640e3dc5759559420b295db1e1edb6cef4 Mon Sep 17 00:00:00 2001
+From: OpenEmbedded <oe.patch@oe>
+Date: Sun, 25 Jul 2021 21:27:32 +0000
+Subject: [PATCH] arm64: dts: Add SomDevices Smarc C0P1 to Makefile
+
+---
+ arch/arm64/boot/dts/freescale/Makefile | 1 +
+ 1 file changed, 1 insertion(+)
+
+diff --git a/arch/arm64/boot/dts/freescale/Makefile b/arch/arm64/boot/dts/freescale/Makefile
+index 177d8c269134..239edfaeb895 100644
+--- a/arch/arm64/boot/dts/freescale/Makefile
++++ b/arch/arm64/boot/dts/freescale/Makefile
+@@ -51,6 +51,7 @@ dtb-$(CONFIG_ARCH_LAYERSCAPE) += fsl-lx2160a-qds.dtb
+ dtb-$(CONFIG_ARCH_LAYERSCAPE) += fsl-lx2160a-rdb.dtb
+ dtb-$(CONFIG_ARCH_LAYERSCAPE) += fsl-lx2162a-qds.dtb
+
++dtb-$(CONFIG_ARCH_MXC) += imx8mm-somdevices-c0p1.dtb
+ dtb-$(CONFIG_ARCH_MXC) += imx8mm-beacon-kit.dtb
+ dtb-$(CONFIG_ARCH_MXC) += imx8mm-evk.dtb imx8mm-evk-rpmsg.dtb imx8mm-evk-rm67191.dtb \
+ imx8mm-evk-root.dtb imx8mm-evk-inmate.dtb imx8mm-evk-revb-qca-wifi.dtb \
+--
+2.25.1
+
--- /dev/null
+From 4054ba5246dee5b87fff9060e2b6ecdcda048f2c Mon Sep 17 00:00:00 2001
+From: OpenEmbedded <oe.patch@oe>
+Date: Tue, 3 Aug 2021 18:39:30 +0000
+Subject: [PATCH] arm64: Add sn65dsi83-4 support
+
+---
+ drivers/gpu/drm/bridge/Kconfig | 2 +
+ drivers/gpu/drm/bridge/Makefile | 1 +
+ drivers/gpu/drm/bridge/sn65dsi83/Kconfig | 6 +
+ drivers/gpu/drm/bridge/sn65dsi83/Makefile | 2 +
+ .../gpu/drm/bridge/sn65dsi83/sn65dsi83_brg.c | 422 +++++++++++++++++
+ .../gpu/drm/bridge/sn65dsi83/sn65dsi83_brg.h | 63 +++
+ .../gpu/drm/bridge/sn65dsi83/sn65dsi83_drv.c | 429 ++++++++++++++++++
+ .../drm/bridge/sn65dsi83/sn65dsi83_timing.h | 38 ++
+ 8 files changed, 963 insertions(+)
+ create mode 100644 drivers/gpu/drm/bridge/sn65dsi83/Kconfig
+ create mode 100644 drivers/gpu/drm/bridge/sn65dsi83/Makefile
+ create mode 100644 drivers/gpu/drm/bridge/sn65dsi83/sn65dsi83_brg.c
+ create mode 100644 drivers/gpu/drm/bridge/sn65dsi83/sn65dsi83_brg.h
+ create mode 100644 drivers/gpu/drm/bridge/sn65dsi83/sn65dsi83_drv.c
+ create mode 100644 drivers/gpu/drm/bridge/sn65dsi83/sn65dsi83_timing.h
+
+diff --git a/drivers/gpu/drm/bridge/Kconfig b/drivers/gpu/drm/bridge/Kconfig
+index 7e15d7c41eed..d71108c2a29b 100644
+--- a/drivers/gpu/drm/bridge/Kconfig
++++ b/drivers/gpu/drm/bridge/Kconfig
+@@ -277,3 +277,5 @@ config DRM_ITE_IT6263
+ ITE IT6263 bridge chip driver.
+
+ endmenu
++
++source "drivers/gpu/drm/bridge/sn65dsi83/Kconfig"
+diff --git a/drivers/gpu/drm/bridge/Makefile b/drivers/gpu/drm/bridge/Makefile
+index 17d70fc62f89..795f34388f70 100644
+--- a/drivers/gpu/drm/bridge/Makefile
++++ b/drivers/gpu/drm/bridge/Makefile
+@@ -31,3 +31,4 @@ obj-y += synopsys/
+ obj-$(CONFIG_DRM_ITE_IT6263) += it6263.o
+ obj-$(CONFIG_DRM_SEC_MIPI_DSIM) += sec-dsim.o
+ obj-$(CONFIG_DRM_NXP_SEIKO_43WVFIG) += nxp-seiko-43wvfig.o
++obj-$(CONFIG_DRM_I2C_SN65DSI83) += sn65dsi83/
+diff --git a/drivers/gpu/drm/bridge/sn65dsi83/Kconfig b/drivers/gpu/drm/bridge/sn65dsi83/Kconfig
+new file mode 100644
+index 000000000000..e1b8e802f61f
+--- /dev/null
++++ b/drivers/gpu/drm/bridge/sn65dsi83/Kconfig
+@@ -0,0 +1,6 @@
++config DRM_I2C_SN65DSI83
++ bool "TI SN65DSI83 MIPI DSI to LVDS bridge"
++ depends on OF
++ select DRM_MIPI_DSI
++ help
++ TI SN65DSI83 MIPI DSI to LVDS bridge driver
+diff --git a/drivers/gpu/drm/bridge/sn65dsi83/Makefile b/drivers/gpu/drm/bridge/sn65dsi83/Makefile
+new file mode 100644
+index 000000000000..dee7f493b323
+--- /dev/null
++++ b/drivers/gpu/drm/bridge/sn65dsi83/Makefile
+@@ -0,0 +1,2 @@
++sn65dsi83-objs := sn65dsi83_drv.o sn65dsi83_brg.o
++obj-$(CONFIG_DRM_I2C_SN65DSI83) := sn65dsi83.o
+diff --git a/drivers/gpu/drm/bridge/sn65dsi83/sn65dsi83_brg.c b/drivers/gpu/drm/bridge/sn65dsi83/sn65dsi83_brg.c
+new file mode 100644
+index 000000000000..211c7fcb3e53
+--- /dev/null
++++ b/drivers/gpu/drm/bridge/sn65dsi83/sn65dsi83_brg.c
+@@ -0,0 +1,422 @@
++// SPDX-License-Identifier: GPL-2.0
++/*
++ * Copyright (C) 2018 CopuLab Ltd.
++ *
++ * This program is free software; you can redistribute it and/or
++ * modify it under the terms of the GNU General Public License
++ * as published by the Free Software Foundation; either version 2
++ * of the License, or (at your option) any later version.
++ *
++ * This program is distributed in the hope that it will be useful,
++ * but WITHOUT ANY WARRANTY; without even the implied warranty of
++ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
++ * GNU General Public License for more details.
++ */
++
++#include <linux/i2c.h>
++#include <linux/delay.h>
++#include <linux/device.h>
++#include <linux/gpio/consumer.h>
++#include <linux/module.h>
++#include <linux/of.h>
++#include <linux/of_device.h>
++#include <linux/of_graph.h>
++#include <linux/slab.h>
++
++#include <drm/drm_print.h>
++#include <drm/drm_atomic.h>
++#include <drm/drm_atomic_helper.h>
++#include <drm/drm_edid.h>
++#include <drm/drm_mipi_dsi.h>
++#include <drm/drm_connector.h>
++#include <video/mipi_display.h>
++#include <video/of_videomode.h>
++#include <video/videomode.h>
++
++#include "sn65dsi83_brg.h"
++
++/* Register addresses */
++
++#define SN65DSI83_SOFT_RESET 0x09
++#define SN65DSI83_CORE_PLL 0x0A
++#define LVDS_CLK_RANGE_SHIFT 1
++#define HS_CLK_SRC_SHIFT 0
++#define PLL_LOCK_BIT BIT(7)
++
++#define SN65DSI83_PLL_DIV 0x0B
++#define DSI_CLK_DIV_SHIFT 3
++
++#define SN65DSI83_PLL_EN 0x0D
++#define SN65DSI83_DSI_CFG 0x10
++#define CHA_DSI_LANES_SHIFT 3
++
++#define SN65DSI83_DSI_EQ 0x11
++#define SN65DSI83_CHA_DSI_CLK_RNG 0x12
++#define SN65DSI83_CHB_DSI_CLK_RNG 0x13
++#define SN65DSI83_LVDS_MODE 0x18
++#define DE_NEG_POLARITY_SHIFT 7
++#define HS_NEG_POLARITY_SHIFT 6
++#define VS_NEG_POLARITY_SHIFT 5
++#define LVDS_LINK_CFG_SHIFT 4
++#define CHA_24BPP_MODE_SHIFT 3
++#define CHA_24BPP_FMT1_SHIFT 1
++
++#define SN65DSI83_LVDS_SIGN 0x19
++#define SN65DSI83_LVDS_TERM 0x1A
++#define SN65DSI83_LVDS_CM_ADJ 0x1B
++#define SN65DSI83_CHA_LINE_LEN_LO 0x20
++#define SN65DSI83_CHA_LINE_LEN_HI 0x21
++#define SN65DSI83_CHB_LINE_LEN_LO 0x22
++#define SN65DSI83_CHB_LINE_LEN_HI 0x23
++#define SN65DSI83_CHA_VERT_LINES_LO 0x24
++#define SN65DSI83_CHA_VERT_LINES_HI 0x25
++#define SN65DSI83_CHB_VERT_LINES_LO 0x26
++#define SN65DSI83_CHB_VERT_LINES_HI 0x27
++#define SN65DSI83_CHA_SYNC_DELAY_LO 0x28
++#define SN65DSI83_CHA_SYNC_DELAY_HI 0x29
++#define SN65DSI83_CHB_SYNC_DELAY_LO 0x2A
++#define SN65DSI83_CHB_SYNC_DELAY_HI 0x2B
++#define SN65DSI83_CHA_HSYNC_WIDTH_LO 0x2C
++#define SN65DSI83_CHA_HSYNC_WIDTH_HI 0x2D
++#define SN65DSI83_CHB_HSYNC_WIDTH_LO 0x2E
++#define SN65DSI83_CHB_HSYNC_WIDTH_HI 0x2F
++#define SN65DSI83_CHA_VSYNC_WIDTH_LO 0x30
++#define SN65DSI83_CHA_VSYNC_WIDTH_HI 0x31
++#define SN65DSI83_CHB_VSYNC_WIDTH_LO 0x32
++#define SN65DSI83_CHB_VSYNC_WIDTH_HI 0x33
++#define SN65DSI83_CHA_HORZ_BACKPORCH 0x34
++#define SN65DSI83_CHB_HORZ_BACKPORCH 0x35
++#define SN65DSI83_CHA_VERT_BACKPORCH 0x36
++#define SN65DSI83_CHB_VERT_BACKPORCH 0x37
++#define SN65DSI83_CHA_HORZ_FRONTPORCH 0x38
++#define SN65DSI83_CHB_HORZ_FRONTPORCH 0x39
++#define SN65DSI83_CHA_VERT_FRONTPORCH 0x3A
++#define SN65DSI83_CHB_VERT_FRONTPORCH 0x3B
++#define SN65DSI83_CHA_ERR 0xE5
++#define SN65DSI83_TEST_PATTERN 0x3C
++#define SN65DSI83_REG_3D 0x3D
++#define SN65DSI83_REG_3E 0x3E
++
++static int sn65dsi83_brg_power_on(struct sn65dsi83_brg *brg)
++{
++ dev_dbg(&brg->client->dev, "%s\n", __func__);
++ gpiod_set_value_cansleep(brg->gpio_enable, 1);
++ /* Wait for 1ms for the internal voltage regulator to stabilize */
++ usleep_range(1000, 1100);
++
++ return 0;
++}
++
++static void sn65dsi83_brg_power_off(struct sn65dsi83_brg *brg)
++{
++ dev_dbg(&brg->client->dev, "%s\n", __func__);
++ gpiod_set_value_cansleep(brg->gpio_enable, 0);
++ /*
++ * The EN pin must be held low for at least 10 ms
++ * before being asserted high
++ */
++ usleep_range(10000, 12000);
++}
++
++static int sn65dsi83_write(struct i2c_client *client, u8 reg, u8 val)
++{
++ int ret;
++
++ ret = i2c_smbus_write_byte_data(client, reg, val);
++ if (ret)
++ dev_err(&client->dev, "failed to write at 0x%02x", reg);
++
++ dev_dbg(&client->dev, "%s: write reg 0x%02x data 0x%02x", __func__, reg,
++ val);
++
++ return ret;
++}
++#define SN65DSI83_WRITE(reg, val) sn65dsi83_write(client, (reg), (val))
++
++static int sn65dsi83_read(struct i2c_client *client, u8 reg)
++{
++ int ret;
++
++ dev_dbg(&client->dev, "client 0x%p", client);
++
++ ret = i2c_smbus_read_byte_data(client, reg);
++ if (ret < 0) {
++ dev_err(&client->dev, "failed reading at 0x%02x", reg);
++ return ret;
++ }
++
++ dev_dbg(&client->dev, "%s: read reg 0x%02x data 0x%02x", __func__, reg,
++ ret);
++
++ return ret;
++}
++#define SN65DSI83_READ(reg) sn65dsi83_read(client, (reg))
++
++static inline int sn65dsi83_i2c_poll_timeout(struct i2c_client *client, u8 reg,
++ u64 timeout_us)
++{
++ int ret;
++ ktime_t timeout = ktime_add_us(ktime_get(), timeout_us);
++
++ for (;;) {
++ ret = sn65dsi83_read(client, reg);
++ if (ret < 0)
++ return ret;
++ if (ret & PLL_LOCK_BIT)
++ return 0;
++ if (timeout_us && ktime_compare(ktime_get(), timeout) > 0)
++ return -ETIMEDOUT;
++ udelay(100);
++ }
++}
++
++static int sn65dsi83_brg_start_stream(struct sn65dsi83_brg *brg)
++{
++ int regval;
++ struct i2c_client *client = I2C_CLIENT(brg);
++
++ dev_dbg(&client->dev, "%s\n", __func__);
++ /* Set the PLL_EN bit (CSR 0x0D.0) */
++ SN65DSI83_WRITE(SN65DSI83_PLL_EN, 0x1);
++ /* Wait for the PLL_LOCK bit to be set (CSR 0x0A.7) */
++ regval = sn65dsi83_i2c_poll_timeout(client, SN65DSI83_CORE_PLL, 200000);
++ if (regval < 0)
++ return regval;
++
++ /* Perform SW reset to apply changes */
++ SN65DSI83_WRITE(SN65DSI83_SOFT_RESET, 0x01);
++
++ /* Read CHA Error register */
++ regval = SN65DSI83_READ(SN65DSI83_CHA_ERR);
++ dev_dbg(&client->dev, "CHA (0x%02x) = 0x%02x", SN65DSI83_CHA_ERR,
++ regval);
++
++ if (!IS_ERR(brg->gpio_panel_enable))
++ gpiod_set_value_cansleep(brg->gpio_panel_enable, 1);
++
++ return 0;
++}
++
++static void sn65dsi83_brg_stop_stream(struct sn65dsi83_brg *brg)
++{
++ struct i2c_client *client = I2C_CLIENT(brg);
++
++ dev_dbg(&client->dev, "%s\n", __func__);
++ /* Clear the PLL_EN bit (CSR 0x0D.0) */
++ SN65DSI83_WRITE(SN65DSI83_PLL_EN, 0x00);
++
++ if (!IS_ERR(brg->gpio_panel_enable))
++ gpiod_set_value_cansleep(brg->gpio_panel_enable, 0);
++}
++
++static int sn65dsi83_calk_clk_range(int min_regval, int max_regval,
++ unsigned long min_clk, unsigned long inc,
++ unsigned long target_clk)
++{
++ int regval = min_regval;
++ unsigned long clk = min_clk;
++
++ while (regval <= max_regval) {
++ if ((clk <= target_clk) && (target_clk < (clk + inc)))
++ return regval;
++
++ regval++;
++ clk += inc;
++ }
++
++ return -1;
++}
++
++#define ABS(X) ((X) < 0 ? (-1 * (X)) : (X))
++static int sn65dsi83_calk_div(int min_regval, int max_regval, int min_div,
++ int inc, unsigned long source_clk,
++ unsigned long target_clk)
++{
++ int regval = min_regval;
++ int div = min_div;
++ unsigned long curr_delta;
++ unsigned long prev_delta =
++ ABS(DIV_ROUND_UP(source_clk, div) - target_clk);
++
++ while (regval <= max_regval) {
++ curr_delta = ABS(DIV_ROUND_UP(source_clk, div) - target_clk);
++ if (curr_delta > prev_delta)
++ return --regval;
++
++ regval++;
++ div += inc;
++ }
++
++ return -1;
++}
++
++static int sn65dsi83_brg_configure(struct sn65dsi83_brg *brg)
++{
++ int regval = 0;
++ struct i2c_client *client = I2C_CLIENT(brg);
++ struct videomode *vm = VM(brg);
++ u32 dsi_clk = (((PIXCLK * BPP(brg)) / DSI_LANES(brg)) >> 1);
++
++ dev_info(&client->dev, "DSI clock [ %u ] Hz\n", dsi_clk);
++ dev_info(&client->dev, "Resolution [ %d x %d ] Hz\n", HACTIVE, VACTIVE);
++
++ /* Reset PLL_EN and SOFT_RESET registers */
++ SN65DSI83_WRITE(SN65DSI83_SOFT_RESET, 0x00);
++ SN65DSI83_WRITE(SN65DSI83_PLL_EN, 0x00);
++
++ /* LVDS clock setup */
++ if ((25000000 <= PIXCLK) && (PIXCLK < 37500000))
++ regval = 0;
++ else
++ regval = sn65dsi83_calk_clk_range(0x01, 0x05, 37500000,
++ 25000000, PIXCLK);
++
++ if (regval < 0) {
++ dev_err(&client->dev, "failed to configure LVDS clock");
++ return -EINVAL;
++ }
++
++ regval = (regval << LVDS_CLK_RANGE_SHIFT);
++ regval |= (1 << HS_CLK_SRC_SHIFT); /* Use DSI clock */
++ SN65DSI83_WRITE(SN65DSI83_CORE_PLL, regval);
++
++ /* DSI clock range */
++ regval = sn65dsi83_calk_clk_range(0x08, 0x64, 40000000, 5000000,
++ dsi_clk);
++ if (regval < 0) {
++ dev_err(&client->dev, "failed to configure DSI clock range\n");
++ return -EINVAL;
++ }
++ SN65DSI83_WRITE(SN65DSI83_CHA_DSI_CLK_RNG, regval);
++
++ /* DSI clock divider */
++ regval = sn65dsi83_calk_div(0x0, 0x18, 1, 1, dsi_clk, PIXCLK);
++ if (regval < 0) {
++ dev_err(&client->dev, "failed to calculate DSI clock divider");
++ return -EINVAL;
++ }
++
++ regval = regval << DSI_CLK_DIV_SHIFT;
++ SN65DSI83_WRITE(SN65DSI83_PLL_DIV, regval);
++
++ /* Configure DSI_LANES */
++ regval = SN65DSI83_READ(SN65DSI83_DSI_CFG);
++ regval &= ~(3 << CHA_DSI_LANES_SHIFT);
++ regval |= ((4 - DSI_LANES(brg)) << CHA_DSI_LANES_SHIFT);
++ SN65DSI83_WRITE(SN65DSI83_DSI_CFG, regval);
++
++ /* CHA_DSI_DATA_EQ - No Equalization */
++ /* CHA_DSI_CLK_EQ - No Equalization */
++ SN65DSI83_WRITE(SN65DSI83_DSI_EQ, 0x00);
++
++ /* Video formats */
++ regval = 0;
++ if (FLAGS & DISPLAY_FLAGS_HSYNC_LOW)
++ regval |= (1 << HS_NEG_POLARITY_SHIFT);
++
++ if (FLAGS & DISPLAY_FLAGS_VSYNC_LOW)
++ regval |= (1 << VS_NEG_POLARITY_SHIFT);
++
++ if (brg->de_neg_polarity)
++ regval |= (1 << DE_NEG_POLARITY_SHIFT);
++
++ if (BPP(brg) == 24)
++ regval |= (1 << CHA_24BPP_MODE_SHIFT);
++
++ if (FORMAT(brg) == 1)
++ regval |= (1 << CHA_24BPP_FMT1_SHIFT);
++
++ regval |= (1 << LVDS_LINK_CFG_SHIFT);
++ SN65DSI83_WRITE(SN65DSI83_LVDS_MODE, regval);
++
++ /* Voltage and pins */
++ SN65DSI83_WRITE(SN65DSI83_LVDS_SIGN, 0x00);
++ SN65DSI83_WRITE(SN65DSI83_LVDS_TERM, 0x03);
++ SN65DSI83_WRITE(SN65DSI83_LVDS_CM_ADJ, 0x00);
++
++ /* Configure sync delay to minimal allowed value */
++ SN65DSI83_WRITE(SN65DSI83_CHA_SYNC_DELAY_LO, 0x21);
++ SN65DSI83_WRITE(SN65DSI83_CHA_SYNC_DELAY_HI, 0x00);
++
++ /* Geometry */
++ SN65DSI83_WRITE(SN65DSI83_CHA_LINE_LEN_LO, LOW(HACTIVE));
++ SN65DSI83_WRITE(SN65DSI83_CHA_LINE_LEN_HI, HIGH(HACTIVE));
++
++ SN65DSI83_WRITE(SN65DSI83_CHA_VERT_LINES_LO, LOW(VACTIVE));
++ SN65DSI83_WRITE(SN65DSI83_CHA_VERT_LINES_HI, HIGH(VACTIVE));
++
++ SN65DSI83_WRITE(SN65DSI83_CHA_HSYNC_WIDTH_LO, LOW(HPW));
++ SN65DSI83_WRITE(SN65DSI83_CHA_HSYNC_WIDTH_HI, HIGH(HPW));
++
++ SN65DSI83_WRITE(SN65DSI83_CHA_VSYNC_WIDTH_LO, LOW(VPW));
++ SN65DSI83_WRITE(SN65DSI83_CHA_VSYNC_WIDTH_HI, HIGH(VPW));
++
++ SN65DSI83_WRITE(SN65DSI83_CHA_HORZ_BACKPORCH, LOW(HBP));
++ SN65DSI83_WRITE(SN65DSI83_CHA_VERT_BACKPORCH, LOW(VBP));
++
++ SN65DSI83_WRITE(SN65DSI83_CHA_HORZ_FRONTPORCH, LOW(HFP));
++ SN65DSI83_WRITE(SN65DSI83_CHA_VERT_FRONTPORCH, LOW(VFP));
++
++ SN65DSI83_WRITE(SN65DSI83_TEST_PATTERN, 0x00);
++ SN65DSI83_WRITE(SN65DSI83_REG_3D, 0x00);
++ SN65DSI83_WRITE(SN65DSI83_REG_3E, 0x00);
++
++ /* mute channel B */
++ SN65DSI83_WRITE(SN65DSI83_CHB_DSI_CLK_RNG, 0x00);
++ SN65DSI83_WRITE(SN65DSI83_CHB_LINE_LEN_LO, 0x00);
++ SN65DSI83_WRITE(SN65DSI83_CHB_LINE_LEN_HI, 0x00);
++ SN65DSI83_WRITE(SN65DSI83_CHB_VERT_LINES_LO, 0x00);
++ SN65DSI83_WRITE(SN65DSI83_CHB_VERT_LINES_HI, 0x00);
++ SN65DSI83_WRITE(SN65DSI83_CHB_SYNC_DELAY_LO, 0x00);
++ SN65DSI83_WRITE(SN65DSI83_CHB_SYNC_DELAY_HI, 0x00);
++ SN65DSI83_WRITE(SN65DSI83_CHB_HSYNC_WIDTH_LO, 0x00);
++ SN65DSI83_WRITE(SN65DSI83_CHB_HSYNC_WIDTH_HI, 0x00);
++ SN65DSI83_WRITE(SN65DSI83_CHB_VSYNC_WIDTH_LO, 0x00);
++ SN65DSI83_WRITE(SN65DSI83_CHB_VSYNC_WIDTH_HI, 0x00);
++ SN65DSI83_WRITE(SN65DSI83_CHB_HORZ_BACKPORCH, 0x00);
++ SN65DSI83_WRITE(SN65DSI83_CHB_VERT_BACKPORCH, 0x00);
++ SN65DSI83_WRITE(SN65DSI83_CHB_HORZ_FRONTPORCH, 0x00);
++ SN65DSI83_WRITE(SN65DSI83_CHB_VERT_FRONTPORCH, 0x00);
++ return 0;
++}
++
++static int sn65dsi83_brg_setup(struct sn65dsi83_brg *brg)
++{
++ struct i2c_client *client = I2C_CLIENT(brg);
++
++ dev_dbg(&client->dev, "%s\n", __func__);
++ sn65dsi83_brg_power_on(brg);
++ return sn65dsi83_brg_configure(brg);
++}
++
++static int sn65dsi83_brg_reset(struct sn65dsi83_brg *brg)
++{
++ /* Soft Reset reg value at power on should be 0x00 */
++ struct i2c_client *client = I2C_CLIENT(brg);
++ int ret = SN65DSI83_READ(SN65DSI83_SOFT_RESET);
++
++ dev_dbg(&client->dev, "%s\n", __func__);
++ if (ret != 0x00) {
++ dev_err(&client->dev, "Failed to reset the device");
++ return -ENODEV;
++ }
++ return 0;
++}
++
++static struct sn65dsi83_brg_funcs brg_func = {
++ .power_on = sn65dsi83_brg_power_on,
++ .power_off = sn65dsi83_brg_power_off,
++ .setup = sn65dsi83_brg_setup,
++ .reset = sn65dsi83_brg_reset,
++ .start_stream = sn65dsi83_brg_start_stream,
++ .stop_stream = sn65dsi83_brg_stop_stream,
++};
++
++static struct sn65dsi83_brg brg = {
++ .funcs = &brg_func,
++};
++
++struct sn65dsi83_brg *sn65dsi83_brg_get(void)
++{
++ return &brg;
++}
+diff --git a/drivers/gpu/drm/bridge/sn65dsi83/sn65dsi83_brg.h b/drivers/gpu/drm/bridge/sn65dsi83/sn65dsi83_brg.h
+new file mode 100644
+index 000000000000..659b24f6071b
+--- /dev/null
++++ b/drivers/gpu/drm/bridge/sn65dsi83/sn65dsi83_brg.h
+@@ -0,0 +1,63 @@
++/* SPDX-License-Identifier: GPL-2.0 */
++/*
++ * Copyright (C) 2020 Markus Bauer <mb@karo-electronics.de>
++ */
++
++#ifndef _SN65DSI83_BRG_H__
++#define _SN65DSI83_BRG_H__
++
++#include <linux/i2c.h>
++#include <linux/gpio/consumer.h>
++#include <video/videomode.h>
++
++struct sn65dsi83_brg;
++struct sn65dsi83_brg_funcs {
++ int (*power_on)(struct sn65dsi83_brg *sn65dsi8383_brg);
++ void (*power_off)(struct sn65dsi83_brg *sn65dsi8383_brg);
++ int (*reset)(struct sn65dsi83_brg *sn65dsi8383_brg);
++ int (*setup)(struct sn65dsi83_brg *sn65dsi8383_brg);
++ int (*start_stream)(struct sn65dsi83_brg *sn65dsi8383_brg);
++ void (*stop_stream)(struct sn65dsi83_brg *sn65dsi8383_brg);
++};
++
++struct sn65dsi83_brg {
++ struct i2c_client *client;
++ struct gpio_desc *gpio_enable;
++ struct gpio_desc *gpio_panel_enable;
++ /* Bridge Panel Parameters */
++ struct videomode vm;
++ u32 width_mm;
++ u32 height_mm;
++ u32 format;
++ u32 bpp;
++
++ u8 num_dsi_lanes;
++ u8 burst_mode;
++ u8 de_neg_polarity;
++ struct sn65dsi83_brg_funcs *funcs;
++};
++struct sn65dsi83_brg *sn65dsi83_brg_get(void);
++
++#define I2C_DEVICE(A) (&(A)->client->dev)
++#define I2C_CLIENT(A) ((A)->client)
++#define VM(A) (&(A)->vm)
++#define BPP(A) ((A)->bpp)
++#define FORMAT(A) ((A)->format)
++#define DSI_LANES(A) ((A)->num_dsi_lanes)
++
++/* The caller has to have a vm structure defined */
++#define PIXCLK vm->pixelclock
++#define HACTIVE vm->hactive
++#define HFP vm->hfront_porch
++#define HBP vm->hback_porch
++#define HPW vm->hsync_len
++#define VACTIVE vm->vactive
++#define VFP vm->vfront_porch
++#define VBP vm->vback_porch
++#define VPW vm->vsync_len
++#define FLAGS vm->flags
++
++#define HIGH(A) (((A) >> 8) & 0xFF)
++#define LOW(A) ((A) & 0xFF)
++
++#endif /* _SN65DSI83_BRG_H__ */
+diff --git a/drivers/gpu/drm/bridge/sn65dsi83/sn65dsi83_drv.c b/drivers/gpu/drm/bridge/sn65dsi83/sn65dsi83_drv.c
+new file mode 100644
+index 000000000000..e06c2ddaaf72
+--- /dev/null
++++ b/drivers/gpu/drm/bridge/sn65dsi83/sn65dsi83_drv.c
+@@ -0,0 +1,429 @@
++// SPDX-License-Identifier: GPL-2.0
++/*
++ * Copyright (C) 2020 Markus Bauer <mb@karo-electronics.de>
++ */
++
++#include <linux/delay.h>
++#include <linux/device.h>
++#include <linux/gpio/consumer.h>
++#include <linux/module.h>
++#include <linux/of.h>
++#include <linux/of_device.h>
++#include <linux/of_graph.h>
++#include <linux/slab.h>
++
++#include <drm/drm_print.h>
++#include <drm/drm_atomic.h>
++#include <drm/drm_atomic_helper.h>
++#include <drm/drm_edid.h>
++#include <drm/drm_mipi_dsi.h>
++#include <drm/drm_bridge.h>
++#include <drm/drm_connector.h>
++#include <drm/drm_crtc_helper.h>
++#include <drm/drm_modes.h>
++#include <video/mipi_display.h>
++#include <video/of_videomode.h>
++#include <video/videomode.h>
++
++#include "sn65dsi83_timing.h"
++#include "sn65dsi83_brg.h"
++
++struct sn65dsi83 {
++ u8 channel_id;
++ enum drm_connector_status status;
++ bool powered;
++ struct drm_display_mode curr_mode;
++ struct drm_bridge bridge;
++ struct drm_connector connector;
++ struct device_node *host_node;
++ struct mipi_dsi_device *dsi;
++ struct sn65dsi83_brg *brg;
++};
++
++static int sn65dsi83_attach_dsi(struct sn65dsi83 *sn65dsi83);
++#define DRM_DEVICE(A) A->dev->dev
++/* Connector funcs */
++static struct sn65dsi83 *connector_to_sn65dsi83(struct drm_connector *connector)
++{
++ return container_of(connector, struct sn65dsi83, connector);
++}
++
++static int sn65dsi83_connector_get_modes(struct drm_connector *connector)
++{
++ struct sn65dsi83 *sn65dsi83 = connector_to_sn65dsi83(connector);
++ struct sn65dsi83_brg *brg = sn65dsi83->brg;
++ struct device *dev = connector->dev->dev;
++ struct drm_display_mode *mode;
++ u32 bus_format = MEDIA_BUS_FMT_RGB888_1X24;
++ u32 *bus_flags = &connector->display_info.bus_flags;
++ int ret;
++
++ dev_dbg(dev, "%s\n", __func__);
++ mode = drm_mode_create(connector->dev);
++ if (!mode) {
++ DRM_DEV_ERROR(dev, "Failed to create display mode!\n");
++ return 0;
++ }
++
++ drm_display_mode_from_videomode(&brg->vm, mode);
++ mode->width_mm = brg->width_mm;
++ mode->height_mm = brg->height_mm;
++ mode->type = DRM_MODE_TYPE_DRIVER | DRM_MODE_TYPE_PREFERRED;
++
++ drm_mode_probed_add(connector, mode);
++ drm_connector_list_update(connector);
++
++ connector->display_info.width_mm = mode->width_mm;
++ connector->display_info.height_mm = mode->height_mm;
++
++ if (brg->vm.flags & DISPLAY_FLAGS_DE_HIGH)
++ *bus_flags |= DRM_BUS_FLAG_DE_HIGH;
++ if (brg->vm.flags & DISPLAY_FLAGS_DE_LOW)
++ *bus_flags |= DRM_BUS_FLAG_DE_LOW;
++ if (brg->vm.flags & DISPLAY_FLAGS_PIXDATA_NEGEDGE)
++ *bus_flags |= DRM_BUS_FLAG_PIXDATA_DRIVE_NEGEDGE;
++ if (brg->vm.flags & DISPLAY_FLAGS_PIXDATA_POSEDGE)
++ *bus_flags |= DRM_BUS_FLAG_PIXDATA_DRIVE_POSEDGE;
++
++ ret = drm_display_info_set_bus_formats(&connector->display_info,
++ &bus_format, 1);
++ if (ret)
++ return ret;
++
++ return 1;
++}
++
++static enum drm_mode_status
++sn65dsi83_connector_mode_valid(struct drm_connector *connector,
++ struct drm_display_mode *mode)
++{
++ struct sn65dsi83 *sn65dsi83 = connector_to_sn65dsi83(connector);
++ struct device *dev = connector->dev->dev;
++
++ if (mode->clock > (sn65dsi83->brg->vm.pixelclock / 1000))
++ return MODE_CLOCK_HIGH;
++
++ dev_dbg(dev, "%s: mode: %d*%d@%d is valid\n", __func__, mode->hdisplay,
++ mode->vdisplay, mode->clock);
++ return MODE_OK;
++}
++
++static struct drm_connector_helper_funcs sn65dsi83_connector_helper_funcs = {
++ .get_modes = sn65dsi83_connector_get_modes,
++ .mode_valid = sn65dsi83_connector_mode_valid,
++};
++
++static enum drm_connector_status
++sn65dsi83_connector_detect(struct drm_connector *connector, bool force)
++{
++ struct sn65dsi83 *sn65dsi83 = connector_to_sn65dsi83(connector);
++ struct device *dev = connector->dev->dev;
++ enum drm_connector_status status;
++
++ dev_dbg(dev, "%s\n", __func__);
++
++ status = connector_status_connected;
++ sn65dsi83->status = status;
++ return status;
++}
++
++int drm_helper_probe_single_connector_modes(struct drm_connector *connector,
++ uint32_t maxX, uint32_t maxY);
++
++static const struct drm_connector_funcs sn65dsi83_connector_funcs = {
++ .dpms = drm_helper_connector_dpms,
++ .fill_modes = drm_helper_probe_single_connector_modes,
++ .detect = sn65dsi83_connector_detect,
++ .destroy = drm_connector_cleanup,
++ .reset = drm_atomic_helper_connector_reset,
++ .atomic_duplicate_state = drm_atomic_helper_connector_duplicate_state,
++ .atomic_destroy_state = drm_atomic_helper_connector_destroy_state,
++};
++
++/* Bridge funcs */
++static struct sn65dsi83 *bridge_to_sn65dsi83(struct drm_bridge *bridge)
++{
++ return container_of(bridge, struct sn65dsi83, bridge);
++}
++
++static void sn65dsi83_bridge_enable(struct drm_bridge *bridge)
++{
++ struct sn65dsi83 *sn65dsi83 = bridge_to_sn65dsi83(bridge);
++
++ dev_dbg(DRM_DEVICE(bridge), "%s\n", __func__);
++ sn65dsi83->brg->funcs->setup(sn65dsi83->brg);
++ sn65dsi83->brg->funcs->start_stream(sn65dsi83->brg);
++}
++
++static void sn65dsi83_bridge_disable(struct drm_bridge *bridge)
++{
++ struct sn65dsi83 *sn65dsi83 = bridge_to_sn65dsi83(bridge);
++
++ dev_dbg(DRM_DEVICE(bridge), "%s\n", __func__);
++ sn65dsi83->brg->funcs->stop_stream(sn65dsi83->brg);
++ sn65dsi83->brg->funcs->power_off(sn65dsi83->brg);
++}
++
++static void sn65dsi83_bridge_mode_set(struct drm_bridge *bridge,
++ const struct drm_display_mode *mode,
++ const struct drm_display_mode *adj_mode)
++{
++ struct sn65dsi83 *sn65dsi83 = bridge_to_sn65dsi83(bridge);
++
++ dev_dbg(DRM_DEVICE(bridge), "%s: mode: %d*%d@%d\n", __func__,
++ mode->hdisplay, mode->vdisplay, mode->clock);
++ drm_mode_copy(&sn65dsi83->curr_mode, adj_mode);
++}
++
++static int sn65dsi83_bridge_attach(struct drm_bridge *bridge, enum drm_bridge_attach_flags flags)
++{
++ struct sn65dsi83 *sn65dsi83 = bridge_to_sn65dsi83(bridge);
++ int ret;
++
++ dev_dbg(DRM_DEVICE(bridge), "%s\n", __func__);
++ if (!bridge->encoder) {
++ DRM_ERROR("Parent encoder object not found");
++ return -ENODEV;
++ }
++
++ sn65dsi83->connector.polled = DRM_CONNECTOR_POLL_CONNECT;
++
++ ret = drm_connector_init(bridge->dev, &sn65dsi83->connector,
++ &sn65dsi83_connector_funcs,
++ DRM_MODE_CONNECTOR_DSI);
++ if (ret) {
++ DRM_ERROR("Failed to initialize connector with drm\n");
++ return ret;
++ }
++ drm_connector_helper_add(&sn65dsi83->connector,
++ &sn65dsi83_connector_helper_funcs);
++ drm_connector_attach_encoder(&sn65dsi83->connector, bridge->encoder);
++
++ ret = sn65dsi83_attach_dsi(sn65dsi83);
++
++ return ret;
++}
++
++static struct drm_bridge_funcs sn65dsi83_bridge_funcs = {
++ .enable = sn65dsi83_bridge_enable,
++ .disable = sn65dsi83_bridge_disable,
++ .mode_set = sn65dsi83_bridge_mode_set,
++ .attach = sn65dsi83_bridge_attach,
++};
++
++static int sn65dsi83_parse_dt(struct device_node *np,
++ struct sn65dsi83 *sn65dsi83)
++{
++ struct device *dev = &sn65dsi83->brg->client->dev;
++ u32 num_lanes = 2, bpp = 24, format = 2, width = 149, height = 93;
++ u8 burst_mode = 0;
++ u8 de_neg_polarity = 0;
++ struct device_node *endpoint;
++
++ endpoint = of_graph_get_next_endpoint(np, NULL);
++ if (!endpoint)
++ return -ENODEV;
++
++ sn65dsi83->host_node = of_graph_get_remote_port_parent(endpoint);
++ if (!sn65dsi83->host_node) {
++ of_node_put(endpoint);
++ return -ENODEV;
++ }
++
++ of_property_read_u32(np, "ti,dsi-lanes", &num_lanes);
++ of_property_read_u32(np, "ti,lvds-format", &format);
++ of_property_read_u32(np, "ti,lvds-bpp", &bpp);
++ of_property_read_u32(np, "ti,width-mm", &width);
++ of_property_read_u32(np, "ti,height-mm", &height);
++ burst_mode = of_property_read_bool(np, "ti,burst-mode");
++ de_neg_polarity = of_property_read_bool(np, "ti,de-neg-polarity");
++
++ if (num_lanes < 1 || num_lanes > 4) {
++ dev_err(dev, "Invalid dsi-lanes: %d\n", num_lanes);
++ return -EINVAL;
++ }
++ sn65dsi83->brg->num_dsi_lanes = num_lanes;
++ sn65dsi83->brg->burst_mode = burst_mode;
++ sn65dsi83->brg->de_neg_polarity = de_neg_polarity;
++
++ sn65dsi83->brg->gpio_enable =
++ devm_gpiod_get(dev, "enable", GPIOD_OUT_LOW);
++ if (IS_ERR(sn65dsi83->brg->gpio_enable)) {
++ dev_err(dev, "failed to parse enable gpio");
++ return PTR_ERR(sn65dsi83->brg->gpio_enable);
++ }
++
++ sn65dsi83->brg->gpio_panel_enable =
++ devm_gpiod_get(dev, "enable-panel", GPIOD_OUT_LOW);
++ if (!IS_ERR(sn65dsi83->brg->gpio_panel_enable)) {
++ gpiod_set_value_cansleep(sn65dsi83->brg->gpio_panel_enable, 0);
++ msleep(200);
++ } else {
++ dev_warn(dev, "failed to parse enable panel gpio");
++ }
++
++ sn65dsi83->brg->format = format;
++ sn65dsi83->brg->bpp = bpp;
++
++ sn65dsi83->brg->width_mm = width;
++ sn65dsi83->brg->height_mm = height;
++
++ /* Read default timing if there is not device tree node for */
++ if ((of_get_videomode(np, &sn65dsi83->brg->vm, 0)) < 0)
++ videomode_from_timing(&panel_default_timing,
++ &sn65dsi83->brg->vm);
++
++ of_node_put(endpoint);
++ of_node_put(sn65dsi83->host_node);
++
++ return 0;
++}
++
++static int sn65dsi83_probe(struct i2c_client *i2c,
++ const struct i2c_device_id *id)
++{
++ struct sn65dsi83 *sn65dsi83;
++ struct device *dev = &i2c->dev;
++ int ret;
++
++ dev_dbg(dev, "%s\n", __func__);
++ if (!dev->of_node)
++ return -EINVAL;
++
++ sn65dsi83 = devm_kzalloc(dev, sizeof(*sn65dsi83), GFP_KERNEL);
++ if (!sn65dsi83)
++ return -ENOMEM;
++
++ /* Initialize it before DT parser */
++ sn65dsi83->brg = sn65dsi83_brg_get();
++ sn65dsi83->brg->client = i2c;
++
++ sn65dsi83->powered = false;
++ sn65dsi83->status = connector_status_disconnected;
++
++ i2c_set_clientdata(i2c, sn65dsi83);
++
++ ret = sn65dsi83_parse_dt(dev->of_node, sn65dsi83);
++ if (ret)
++ return ret;
++
++ sn65dsi83->brg->funcs->power_off(sn65dsi83->brg);
++ sn65dsi83->brg->funcs->power_on(sn65dsi83->brg);
++ ret = sn65dsi83->brg->funcs->reset(sn65dsi83->brg);
++ if (ret != 0x00) {
++ dev_err(dev, "Failed to reset the device");
++ return -ENODEV;
++ }
++ sn65dsi83->brg->funcs->power_off(sn65dsi83->brg);
++
++ sn65dsi83->bridge.funcs = &sn65dsi83_bridge_funcs;
++ sn65dsi83->bridge.of_node = dev->of_node;
++
++ drm_bridge_add(&sn65dsi83->bridge);
++
++ return ret;
++}
++
++static int sn65dsi83_attach_dsi(struct sn65dsi83 *sn65dsi83)
++{
++ struct device *dev = &sn65dsi83->brg->client->dev;
++ struct mipi_dsi_host *host;
++ struct mipi_dsi_device *dsi;
++ int ret = 0;
++ const struct mipi_dsi_device_info info = { .type = "sn65dsi83",
++ .channel = 0,
++ .node = NULL,
++ };
++
++ dev_dbg(dev, "%s\n", __func__);
++ host = of_find_mipi_dsi_host_by_node(sn65dsi83->host_node);
++ if (!host) {
++ dev_err(dev, "failed to find dsi host\n");
++ return -EPROBE_DEFER;
++ }
++
++ dsi = mipi_dsi_device_register_full(host, &info);
++ if (IS_ERR(dsi)) {
++ dev_err(dev, "failed to create dsi device\n");
++ ret = PTR_ERR(dsi);
++ return -ENODEV;
++ }
++
++ sn65dsi83->dsi = dsi;
++
++ dsi->lanes = sn65dsi83->brg->num_dsi_lanes;
++ dsi->format = MIPI_DSI_FMT_RGB888;
++ dsi->mode_flags = MIPI_DSI_MODE_VIDEO;
++ if (sn65dsi83->brg->burst_mode)
++ dsi->mode_flags |= MIPI_DSI_MODE_VIDEO_BURST;
++ else
++ dsi->mode_flags |= MIPI_DSI_MODE_VIDEO_SYNC_PULSE;
++
++ ret = mipi_dsi_attach(dsi);
++ if (ret < 0) {
++ dev_err(dev, "failed to attach dsi to host\n");
++ mipi_dsi_device_unregister(dsi);
++ }
++
++ return ret;
++}
++
++static void sn65dsi83_detach_dsi(struct sn65dsi83 *sn65dsi83)
++{
++ struct device *dev = &sn65dsi83->brg->client->dev;
++
++ dev_dbg(dev, "%s\n", __func__);
++ mipi_dsi_detach(sn65dsi83->dsi);
++ mipi_dsi_device_unregister(sn65dsi83->dsi);
++}
++
++static int sn65dsi83_remove(struct i2c_client *i2c)
++{
++ struct sn65dsi83 *sn65dsi83 = i2c_get_clientdata(i2c);
++ struct device *dev = &sn65dsi83->brg->client->dev;
++
++ dev_dbg(dev, "%s\n", __func__);
++
++ sn65dsi83_detach_dsi(sn65dsi83);
++ drm_bridge_remove(&sn65dsi83->bridge);
++
++ return 0;
++}
++
++static const struct i2c_device_id sn65dsi83_i2c_ids[] = {
++ { "sn65dsi83", },
++ { /* sentinel */ }
++};
++MODULE_DEVICE_TABLE(i2c, sn65dsi83_i2c_ids);
++
++static const struct of_device_id sn65dsi83_of_ids[] = {
++ { .compatible = "ti,sn65dsi83" },
++ { /* sentinel */ }
++};
++MODULE_DEVICE_TABLE(of, sn65dsi83_of_ids);
++
++static struct i2c_driver sn65dsi83_driver = {
++ .driver = {
++ .name = "sn65dsi83",
++ .of_match_table = sn65dsi83_of_ids,
++ },
++ .id_table = sn65dsi83_i2c_ids,
++ .probe = sn65dsi83_probe,
++ .remove = sn65dsi83_remove,
++};
++
++static int __init sn65dsi83_init(void)
++{
++ return i2c_add_driver(&sn65dsi83_driver);
++}
++module_init(sn65dsi83_init);
++
++static void __exit sn65dsi83_exit(void)
++{
++ i2c_del_driver(&sn65dsi83_driver);
++}
++module_exit(sn65dsi83_exit);
++
++MODULE_AUTHOR("CompuLab <compulab@compula.co.il>");
++MODULE_DESCRIPTION("SN65DSI bridge driver");
++MODULE_LICENSE("GPL");
+diff --git a/drivers/gpu/drm/bridge/sn65dsi83/sn65dsi83_timing.h b/drivers/gpu/drm/bridge/sn65dsi83/sn65dsi83_timing.h
+new file mode 100644
+index 000000000000..228f0d0b4a7f
+--- /dev/null
++++ b/drivers/gpu/drm/bridge/sn65dsi83/sn65dsi83_timing.h
+@@ -0,0 +1,38 @@
++/* SPDX-License-Identifier: GPL-2.0 */
++/*
++ * Copyright (C) 2020 Markus Bauer <mb@karo-electronics.de>
++ */
++
++#ifndef __SN65DSI83_TIMING_H__
++#define __SN65DSI83_TIMING_H__
++
++#include <video/display_timing.h>
++
++/* Default Video Parameters */
++#define PIXCLK_INIT 62500000
++
++#define HACTIVE_INIT 1280
++#define HPW_INIT 2
++#define HBP_INIT 6
++#define HFP_INIT 5
++
++#define VACTIVE_INIT 800
++#define VPW_INIT 1
++#define VBP_INIT 2
++#define VFP_INIT 3
++
++static const struct display_timing panel_default_timing = {
++ .pixelclock = { PIXCLK_INIT, PIXCLK_INIT, PIXCLK_INIT },
++ .hactive = { HACTIVE_INIT, HACTIVE_INIT, HACTIVE_INIT },
++ .hfront_porch = { HFP_INIT, HFP_INIT, HFP_INIT },
++ .hsync_len = { HPW_INIT, HPW_INIT, HPW_INIT },
++ .hback_porch = { HBP_INIT, HBP_INIT, HBP_INIT },
++ .vactive = { VACTIVE_INIT, VACTIVE_INIT, VACTIVE_INIT },
++ .vfront_porch = { VFP_INIT, VFP_INIT, VFP_INIT },
++ .vsync_len = { VPW_INIT, VPW_INIT, VPW_INIT },
++ .vback_porch = { VBP_INIT, VBP_INIT, VBP_INIT },
++ .flags = DISPLAY_FLAGS_HSYNC_LOW | DISPLAY_FLAGS_VSYNC_LOW |
++ DISPLAY_FLAGS_DE_LOW | DISPLAY_FLAGS_PIXDATA_NEGEDGE,
++};
++
++#endif /* __SN65DSI83_TIMING_H__ */
+--
+2.25.1
+
--- /dev/null
+From 150afeaf3cdd87d6cd1cd03b958269441f63b088 Mon Sep 17 00:00:00 2001
+From: OpenEmbedded <oe.patch@oe>
+Date: Tue, 3 Aug 2021 18:49:48 +0000
+Subject: [PATCH] arm64: Not to show warning CAN interface
+
+---
+ kernel/time/tick-sched.c | 4 ++--
+ 1 file changed, 2 insertions(+), 2 deletions(-)
+
+diff --git a/kernel/time/tick-sched.c b/kernel/time/tick-sched.c
+index e8d351b7f9b0..be1a47fc7ed7 100644
+--- a/kernel/time/tick-sched.c
++++ b/kernel/time/tick-sched.c
+@@ -927,8 +927,8 @@ static bool can_stop_idle_tick(int cpu, struct tick_sched *ts)
+
+ if (ratelimit < 10 &&
+ (local_softirq_pending() & SOFTIRQ_STOP_IDLE_MASK)) {
+- pr_warn("NOHZ tick-stop error: Non-RCU local softirq work is pending, handler #%02x!!!\n",
+- (unsigned int) local_softirq_pending());
++ /*pr_warn("NOHZ tick-stop error: Non-RCU local softirq work is pending, handler #%02x!!!\n",
++ (unsigned int) local_softirq_pending());*/
+ ratelimit++;
+ }
+ return false;
+--
+2.25.1
+
--- /dev/null
+// SPDX-License-Identifier: (GPL-2.0+ OR MIT)
+/*
+ * Copyright 2019-2020 NXP
+ */
+
+/dts-v1/;
+
+#include <dt-bindings/usb/pd.h>
+#include "imx8mm-somdevices-c0p1.dtsi"
+
+/ {
+ model = "FSL i.MX8MM µSMARC SOMDEVICES board";
+ compatible = "fsl,imx8mm-somdevices", "fsl,imx8mm";
+
+ aliases {
+ spi0 = &flexspi;
+ };
+
+ usdhc1_pwrseq: usdhc1_pwrseq {
+ compatible = "mmc-pwrseq-simple";
+ pinctrl-names = "default";
+ pinctrl-0 = <&pinctrl_usdhc1_gpio>;
+ reset-gpios = <&gpio2 10 GPIO_ACTIVE_LOW>;
+ };
+};
+
+&ddrc {
+ operating-points-v2 = <&ddrc_opp_table>;
+
+ ddrc_opp_table: opp-table {
+ compatible = "operating-points-v2";
+
+ opp-25M {
+ opp-hz = /bits/ 64 <25000000>;
+ };
+
+ opp-100M {
+ opp-hz = /bits/ 64 <100000000>;
+ };
+
+ opp-750M {
+ opp-hz = /bits/ 64 <750000000>;
+ };
+ };
+};
+
+&flexspi {
+ pinctrl-names = "default";
+ pinctrl-0 = <&pinctrl_flexspi>;
+ status = "okay";
+
+ flash@0 {
+ reg = <0>;
+ #address-cells = <1>;
+ #size-cells = <1>;
+ compatible = "jedec,spi-nor";
+ spi-max-frequency = <80000000>;
+ spi-tx-bus-width = <4>;
+ spi-rx-bus-width = <4>;
+ };
+};
+
+&usdhc1 {
+ pinctrl-names = "default", "state_100mhz", "state_200mhz";
+ pinctrl-0 = <&pinctrl_usdhc1>, <&pinctrl_wlan>;
+ pinctrl-1 = <&pinctrl_usdhc1_100mhz>, <&pinctrl_wlan>;
+ pinctrl-2 = <&pinctrl_usdhc1_200mhz>, <&pinctrl_wlan>;
+ bus-width = <4>;
+ cap-power-off-card;
+ pm-ignore-notify;
+ keep-power-in-suspend;
+ non-removable;
+ mmc-pwrseq = <&usdhc1_pwrseq>;
+ status = "okay";
+};
+
+&usdhc3 {
+ assigned-clocks = <&clk IMX8MM_CLK_USDHC3_ROOT>;
+ assigned-clock-rates = <400000000>;
+ pinctrl-names = "default", "state_100mhz", "state_200mhz";
+ pinctrl-0 = <&pinctrl_usdhc3>;
+ pinctrl-1 = <&pinctrl_usdhc3_100mhz>;
+ pinctrl-2 = <&pinctrl_usdhc3_200mhz>;
+ bus-width = <8>;
+ non-removable;
+ status = "okay";
+};
+
+&iomuxc {
+ pinctrl_flexspi: flexspigrp {
+ fsl,pins = <
+ MX8MM_IOMUXC_NAND_ALE_QSPI_A_SCLK 0x1c2
+ MX8MM_IOMUXC_NAND_CE0_B_QSPI_A_SS0_B 0x82
+ MX8MM_IOMUXC_NAND_DATA00_QSPI_A_DATA0 0x82
+ MX8MM_IOMUXC_NAND_DATA01_QSPI_A_DATA1 0x82
+ MX8MM_IOMUXC_NAND_DATA02_QSPI_A_DATA2 0x82
+ MX8MM_IOMUXC_NAND_DATA03_QSPI_A_DATA3 0x82
+ >;
+ };
+
+ pinctrl_usdhc3: usdhc3grp {
+ fsl,pins = <
+ MX8MM_IOMUXC_NAND_WE_B_USDHC3_CLK 0x190
+ MX8MM_IOMUXC_NAND_WP_B_USDHC3_CMD 0x1d0
+ MX8MM_IOMUXC_NAND_DATA04_USDHC3_DATA0 0x1d0
+ MX8MM_IOMUXC_NAND_DATA05_USDHC3_DATA1 0x1d0
+ MX8MM_IOMUXC_NAND_DATA06_USDHC3_DATA2 0x1d0
+ MX8MM_IOMUXC_NAND_DATA06_USDHC3_DATA2 0x1d0
+ MX8MM_IOMUXC_NAND_DATA07_USDHC3_DATA3 0x1d0
+ MX8MM_IOMUXC_NAND_RE_B_USDHC3_DATA4 0x1d0
+ MX8MM_IOMUXC_NAND_CE2_B_USDHC3_DATA5 0x1d0
+ MX8MM_IOMUXC_NAND_CE3_B_USDHC3_DATA6 0x1d0
+ MX8MM_IOMUXC_NAND_CLE_USDHC3_DATA7 0x1d0
+ MX8MM_IOMUXC_NAND_CE1_B_USDHC3_STROBE 0x190
+ >;
+ };
+
+ pinctrl_usdhc3_100mhz: usdhc3-100mhzgrp {
+ fsl,pins = <
+ MX8MM_IOMUXC_NAND_WE_B_USDHC3_CLK 0x194
+ MX8MM_IOMUXC_NAND_WP_B_USDHC3_CMD 0x1d4
+ MX8MM_IOMUXC_NAND_DATA04_USDHC3_DATA0 0x1d4
+ MX8MM_IOMUXC_NAND_DATA05_USDHC3_DATA1 0x1d4
+ MX8MM_IOMUXC_NAND_DATA06_USDHC3_DATA2 0x1d4
+ MX8MM_IOMUXC_NAND_DATA07_USDHC3_DATA3 0x1d4
+ MX8MM_IOMUXC_NAND_RE_B_USDHC3_DATA4 0x1d4
+ MX8MM_IOMUXC_NAND_CE2_B_USDHC3_DATA5 0x1d4
+ MX8MM_IOMUXC_NAND_CE3_B_USDHC3_DATA6 0x1d4
+ MX8MM_IOMUXC_NAND_CLE_USDHC3_DATA7 0x1d4
+ MX8MM_IOMUXC_NAND_CE1_B_USDHC3_STROBE 0x194
+ >;
+ };
+
+ pinctrl_usdhc3_200mhz: usdhc3-200mhzgrp {
+ fsl,pins = <
+ MX8MM_IOMUXC_NAND_WE_B_USDHC3_CLK 0x196
+ MX8MM_IOMUXC_NAND_WP_B_USDHC3_CMD 0x1d6
+ MX8MM_IOMUXC_NAND_DATA04_USDHC3_DATA0 0x1d6
+ MX8MM_IOMUXC_NAND_DATA05_USDHC3_DATA1 0x1d6
+ MX8MM_IOMUXC_NAND_DATA06_USDHC3_DATA2 0x1d6
+ MX8MM_IOMUXC_NAND_DATA07_USDHC3_DATA3 0x1d6
+ MX8MM_IOMUXC_NAND_RE_B_USDHC3_DATA4 0x1d6
+ MX8MM_IOMUXC_NAND_CE2_B_USDHC3_DATA5 0x1d6
+ MX8MM_IOMUXC_NAND_CE3_B_USDHC3_DATA6 0x1d6
+ MX8MM_IOMUXC_NAND_CLE_USDHC3_DATA7 0x1d6
+ MX8MM_IOMUXC_NAND_CE1_B_USDHC3_STROBE 0x196
+ >;
+ };
+
+ pinctrl_wlan: wlangrp {
+ fsl,pins = <
+ MX8MM_IOMUXC_GPIO1_IO00_ANAMIX_REF_CLK_32K 0x141
+ MX8MM_IOMUXC_SD1_DATA7_GPIO2_IO9 0x111
+ >;
+ };
+};
--- /dev/null
+// SPDX-License-Identifier: (GPL-2.0+ OR MIT)
+/*
+ * Copyright 2020 NXP
+ */
+
+/dts-v1/;
+
+#include <dt-bindings/usb/pd.h>
+#include "imx8mm.dtsi"
+
+/ {
+ chosen {
+ stdout-path = &uart2;
+ };
+
+ memory@40000000 {
+ device_type = "memory";
+ reg = <0x0 0x40000000 0 0x80000000>;
+ };
+
+ ir_recv: ir-receiver {
+ compatible = "gpio-ir-receiver";
+ gpios = <&gpio1 13 GPIO_ACTIVE_LOW>;
+ pinctrl-names = "default";
+ pinctrl-0 = <&pinctrl_ir_recv>;
+ linux,autosuspend-period = <125>;
+ };
+
+ leds {
+ compatible = "gpio-leds";
+ pinctrl-names = "default";
+ pinctrl-0 = <&pinctrl_gpio_led>;
+
+ status {
+ label = "status";
+ gpios = <&gpio1 10 GPIO_ACTIVE_HIGH>;
+ linux,default-trigger = "heartbeat";
+ };
+ };
+
+ modem_reset: modem-reset {
+ compatible = "gpio-reset";
+ reset-gpios = <&gpio2 6 GPIO_ACTIVE_LOW>;
+ reset-delay-us = <2000>;
+ reset-post-delay-ms = <40>;
+ #reset-cells = <0>;
+ };
+
+ pcie0_refclk: pcie0-refclk {
+ compatible = "fixed-clock";
+ #clock-cells = <0>;
+ clock-frequency = <100000000>;
+ };
+
+ reg_audio_board: regulator-audio-board {
+ compatible = "regulator-fixed";
+ regulator-name = "EXT_PWREN";
+ regulator-min-microvolt = <3300000>;
+ regulator-max-microvolt = <3300000>;
+ enable-active-high;
+ startup-delay-us = <300000>;
+ gpio = <&pca6416 1 GPIO_ACTIVE_HIGH>;
+ regulator-always-on;
+ };
+
+ reg_usdhc2_vmmc: regulator-usdhc2 {
+ compatible = "regulator-fixed";
+ pinctrl-names = "default";
+ pinctrl-0 = <&pinctrl_reg_usdhc2_vmmc>;
+ regulator-name = "VSD_3V3";
+ regulator-min-microvolt = <3300000>;
+ regulator-max-microvolt = <3300000>;
+ gpio = <&gpio2 19 GPIO_ACTIVE_HIGH>;
+ off-on-delay-us = <20000>;
+ enable-active-high;
+ };
+
+ bt_sco_codec: bt_sco_codec {
+ #sound-dai-cells = <1>;
+ compatible = "linux,bt-sco";
+ };
+
+ sound-bt-sco {
+ compatible = "simple-audio-card";
+ simple-audio-card,name = "bt-sco-audio";
+ simple-audio-card,format = "dsp_a";
+ simple-audio-card,bitclock-inversion;
+ simple-audio-card,frame-master = <&btcpu>;
+ simple-audio-card,bitclock-master = <&btcpu>;
+
+ btcpu: simple-audio-card,cpu {
+ sound-dai = <&sai1>;
+ dai-tdm-slot-num = <2>;
+ dai-tdm-slot-width = <16>;
+ };
+
+ simple-audio-card,codec {
+ sound-dai = <&bt_sco_codec 1>;
+ };
+ };
+
+ /*wm8524: audio-codec {
+ #sound-dai-cells = <0>;
+ compatible = "wlf,wm8524";
+ pinctrl-names = "default";
+ pinctrl-0 = <&pinctrl_gpio_wlf>;
+ wlf,mute-gpios = <&gpio5 21 GPIO_ACTIVE_LOW>;
+ };
+
+ sound-wm8524 {
+ compatible = "simple-audio-card";
+ simple-audio-card,name = "wm8524-audio";
+ simple-audio-card,format = "i2s";
+ simple-audio-card,frame-master = <&cpudai>;
+ simple-audio-card,bitclock-master = <&cpudai>;
+ simple-audio-card,widgets =
+ "Line", "Left Line Out Jack",
+ "Line", "Right Line Out Jack";
+ simple-audio-card,routing =
+ "Left Line Out Jack", "LINEVOUTL",
+ "Right Line Out Jack", "LINEVOUTR";
+
+ cpudai: simple-audio-card,cpu {
+ sound-dai = <&sai3>;
+ dai-tdm-slot-num = <2>;
+ dai-tdm-slot-width = <32>;
+ };
+
+ simple-audio-card,codec {
+ sound-dai = <&wm8524>;
+ clocks = <&clk IMX8MM_CLK_SAI3_ROOT>;
+ };
+ };*/
+
+ /*sound-ak4458 {
+ compatible = "fsl,imx-audio-ak4458";
+ model = "ak4458-audio";
+ audio-cpu = <&sai1>;
+ audio-codec = <&ak4458_1>, <&ak4458_2>;
+ reset-gpios = <&pca6416 4 GPIO_ACTIVE_HIGH>;
+ };
+
+ sound-ak5558 {
+ compatible = "fsl,imx-audio-ak5558";
+ model = "ak5558-audio";
+ audio-cpu = <&sai5>;
+ audio-codec = <&ak5558>;
+ status = "disabled";
+ };
+
+ sound-ak4497 {
+ compatible = "fsl,imx-audio-ak4497";
+ model = "ak4497-audio";
+ audio-cpu = <&sai1>;
+ audio-codec = <&ak4497>;
+ status = "disabled";
+ };
+
+ sound-spdif {
+ compatible = "fsl,imx-audio-spdif";
+ model = "imx-spdif";
+ spdif-controller = <&spdif1>;
+ spdif-out;
+ spdif-in;
+ };*/
+
+ sound-micfil {
+ compatible = "fsl,imx-audio-micfil";
+ model = "imx-audio-micfil";
+ cpu-dai = <&micfil>;
+ };
+
+ /* fixed clock dedicated to SPI CAN controller */
+ clk20m: oscillator {
+ compatible = "fixed-clock";
+ #clock-cells = <0>;
+ clock-frequency = <20000000>;
+ };
+
+};
+
+&A53_0 {
+ cpu-supply = <&buck2_reg>;
+};
+
+&A53_1 {
+ cpu-supply = <&buck2_reg>;
+};
+
+&A53_2 {
+ cpu-supply = <&buck2_reg>;
+};
+
+&A53_3 {
+ cpu-supply = <&buck2_reg>;
+};
+
+&csi1_bridge {
+ fsl,mipi-mode;
+ status = "okay";
+ port {
+ csi1_ep: endpoint {
+ remote-endpoint = <&csi1_mipi_ep>;
+ };
+ };
+};
+
+&ecspi2 {
+ #address-cells = <1>;
+ #size-cells = <0>;
+ fsl,spi-num-chipselects = <1>;
+ pinctrl-names = "default";
+ pinctrl-0 = <&pinctrl_ecspi2 &pinctrl_ecspi2_cs>;
+ cs-gpios = <&gpio5 13 GPIO_ACTIVE_LOW>;
+ status = "okay";
+
+ spidev0: spi@0 {
+ reg = <0>;
+ compatible = "rohm,dh2228fv";
+ spi-max-frequency = <500000>;
+ };
+};
+
+&ecspi3 {
+ #address-cells = <1>;
+ #size-cells = <0>;
+ cs-gpios = <&gpio5 25 GPIO_ACTIVE_LOW>;
+ /* This property is required, even if marked as obsolete in the doku */
+ //fsl,spi-num-chipselects = <1>;
+ pinctrl-names = "default";
+ pinctrl-0 = <&pinctrl_ecspi3>;
+ status = "okay";
+
+ can0: can@0 {
+ compatible = "microchip,mcp2518fd";
+ clocks = <&clk20m>;
+ gpio-controller;
+ interrupt-parent = <&gpio5>;
+ interrupts = <26 IRQ_TYPE_EDGE_FALLING>;
+ microchip,clock-allways-on;
+ microchip,clock-out-div = <1>;
+ pinctrl-names = "default";
+ pinctrl-0 = <&pinctrl_can1_int>;
+ reg = <0>;
+ spi-max-frequency = <2000000>;
+ };
+};
+
+&fec1 {
+ pinctrl-names = "default";
+ pinctrl-0 = <&pinctrl_fec1>;
+ phy-mode = "rgmii-id";
+ phy-handle = <ðphy0>;
+ phy-reset-gpios = <&gpio5 29 GPIO_ACTIVE_LOW>;
+ phy-reset-post-delay = <150>;
+ phy-reset-duration = <10>;
+ fsl,magic-packet;
+ status = "okay";
+
+ mdio {
+ #address-cells = <1>;
+ #size-cells = <0>;
+ //JOC
+ //https://github.com/boundarydevices/linux-imx6/tree/boundary-imx_5.10.x_1.0.0-pass1/arch/arm64/boot/dts/freescale
+ ethphy0: ethernet-phy@4 {
+ compatible = "ethernet-phy-ieee802.3-c22";
+ reg = <4>;
+ };
+ };
+};
+
+&i2c1 {
+ clock-frequency = <400000>;
+ pinctrl-names = "default";
+ pinctrl-0 = <&pinctrl_i2c1>;
+ status = "okay";
+
+ pmic_nxp: pca9450@25 {
+ compatible = "nxp,pca9450a";
+ reg = <0x25>;
+ pinctrl-0 = <&pinctrl_pmic>;
+ pinctrl-names = "default";
+ interrupt-parent = <&gpio1>;
+ interrupts = <3 IRQ_TYPE_LEVEL_LOW>;
+
+ regulators {
+ buck1_reg: BUCK1 {
+ regulator-name = "BUCK1";
+ regulator-min-microvolt = <600000>;
+ regulator-max-microvolt = <2187500>;
+ regulator-boot-on;
+ regulator-always-on;
+ regulator-ramp-delay = <3125>;
+ nxp,dvs-run-voltage = <850000>;
+ nxp,dvs-standby-voltage = <800000>;
+ };
+
+ buck2_reg: BUCK2 {
+ regulator-name = "BUCK2";
+ regulator-min-microvolt = <600000>;
+ regulator-max-microvolt = <2187500>;
+ regulator-boot-on;
+ regulator-always-on;
+ regulator-ramp-delay = <3125>;
+ };
+
+ buck3_reg: BUCK3 {
+ regulator-name = "BUCK3";
+ regulator-min-microvolt = <600000>;
+ regulator-max-microvolt = <2187500>;
+ regulator-boot-on;
+ regulator-always-on;
+ };
+
+ buck4_reg: BUCK4 {
+ regulator-name = "BUCK4";
+ regulator-min-microvolt = <600000>;
+ regulator-max-microvolt = <3400000>;
+ regulator-boot-on;
+ regulator-always-on;
+ };
+
+ buck5_reg: BUCK5 {
+ regulator-name = "BUCK5";
+ regulator-min-microvolt = <600000>;
+ regulator-max-microvolt = <3400000>;
+ regulator-boot-on;
+ regulator-always-on;
+ };
+
+ buck6_reg: BUCK6 {
+ regulator-name = "BUCK6";
+ regulator-min-microvolt = <600000>;
+ regulator-max-microvolt = <3400000>;
+ regulator-boot-on;
+ regulator-always-on;
+ };
+
+ ldo1_reg: LDO1 {
+ regulator-name = "LDO1";
+ regulator-min-microvolt = <1600000>;
+ regulator-max-microvolt = <3300000>;
+ regulator-boot-on;
+ regulator-always-on;
+ };
+
+ ldo2_reg: LDO2 {
+ regulator-name = "LDO2";
+ regulator-min-microvolt = <800000>;
+ regulator-max-microvolt = <1150000>;
+ regulator-boot-on;
+ regulator-always-on;
+ };
+
+ ldo3_reg: LDO3 {
+ regulator-name = "LDO3";
+ regulator-min-microvolt = <800000>;
+ regulator-max-microvolt = <3300000>;
+ regulator-boot-on;
+ regulator-always-on;
+ };
+
+ ldo4_reg: LDO4 {
+ regulator-name = "LDO4";
+ regulator-min-microvolt = <800000>;
+ regulator-max-microvolt = <3300000>;
+ regulator-boot-on;
+ regulator-always-on;
+ };
+
+ ldo5_reg: LDO5 {
+ regulator-name = "LDO5";
+ regulator-min-microvolt = <1800000>;
+ regulator-max-microvolt = <3300000>;
+ };
+ };
+ };
+ //https://github.com/karo-electronics/karo-tx-linux/tree/imx_5.10.9_1.0.0/drivers/gpu/drm/bridge/sn65dsi83
+ //https://github.com/varigit/linux-imx/blob/5.4-2.1.x-imx_var01/arch/arm64/boot/dts/freescale/imx8mm-var-som.dtsi
+ //https://www.digi.com/resources/documentation/digidocs/embedded/dey/2.6/cc8mnano/bsp_r_video-lvds_8mn
+ dsi_lvds_bridge: sn65dsi84@2c {
+ compatible = "ti,sn65dsi83";
+ reg = <0x2c>;
+ ti,dsi-lanes = <4>;
+ ti,lvds-format = <1>;
+ ti,lvds-bpp = <24>;
+ ti,lvds-channels = <1>;
+ ti,width-mm = <154>;
+ ti,height-mm = <87>;
+ enable-gpios = <&gpio5 21 GPIO_ACTIVE_HIGH>;
+ pinctrl-names = "default";
+ pinctrl-0 = <&pinctrl_lvds>;
+ status = "okay";
+
+ display-timings {
+ lvds {
+ /*clock-frequency = <33000000>;
+ hactive = <800>;
+ vactive = <480>;
+ hback-porch = <40>;
+ hfront-porch = <40>;
+ vback-porch = <29>;
+ vfront-porch = <13>;
+ hsync-len = <48>;
+ vsync-len = <3>;
+ hsync-active = <0>;
+ vsync-active = <0>;
+ de-active = <1>;
+ pixelclk-active = <0>;*/
+
+ //clock-frequency = <74200000>;
+ clock-frequency = <33000000>;
+ hactive = <800>;
+ vactive = <480>;
+ hfront-porch = <72>;
+ hsync-len = <80>;
+ hback-porch = <216>;
+ vfront-porch = <3>;
+ vsync-len = <5>;
+ vback-porch = <22>;
+
+ hsync-active = <0>;
+ vsync-active = <0>;
+ de-active = <1>;
+ pixelclk-active = <0>;
+ };
+ };
+
+ port {
+ dsi_lvds_bridge_in: endpoint {
+ remote-endpoint = <&mipi_dsi_out>;
+ };
+ };
+ };
+};
+
+&i2c2 {
+ clock-frequency = <400000>;
+ pinctrl-names = "default";
+ pinctrl-0 = <&pinctrl_i2c2>;
+ status = "okay";
+
+ /*adv_bridge: adv7535@3d {
+ compatible = "adi,adv7533";
+ reg = <0x3d>;
+ adi,addr-cec = <0x3b>;
+ adi,dsi-lanes = <4>;
+ pinctrl-names = "default";
+ pinctrl-0 = <&pinctrl_i2c2_synaptics_dsx_io>;
+ interrupt-parent = <&gpio1>;
+ interrupts = <9 IRQ_TYPE_LEVEL_LOW>;
+
+ status = "okay";
+
+ port {
+ adv7535_from_dsim: endpoint {
+ remote-endpoint = <&dsim_to_adv7535>;
+ };
+ };
+ };*/
+
+ /*ptn5110: tcpc@50 {
+ compatible = "nxp,ptn5110";
+ pinctrl-names = "default";
+ pinctrl-0 = <&pinctrl_typec1>;
+ reg = <0x50>;
+ interrupt-parent = <&gpio2>;
+ interrupts = <11 8>;
+ status = "okay";
+
+ port {
+ typec1_dr_sw: endpoint {
+ remote-endpoint = <&usb1_drd_sw>;
+ };
+ };
+
+ typec1_con: connector {
+ compatible = "usb-c-connector";
+ label = "USB-C";
+ power-role = "dual";
+ data-role = "dual";
+ try-power-role = "sink";
+ source-pdos = <PDO_FIXED(5000, 3000, PDO_FIXED_USB_COMM)>;
+ sink-pdos = <PDO_FIXED(5000, 3000, PDO_FIXED_USB_COMM)
+ PDO_VAR(5000, 20000, 3000)>;
+ op-sink-microwatt = <15000000>;
+ self-powered;
+ };
+ };*/
+};
+
+&i2c3 {
+ clock-frequency = <100000>;
+ pinctrl-names = "default";
+ pinctrl-0 = <&pinctrl_i2c3>;
+ status = "okay";
+
+ pca6416: gpio@20 {
+ compatible = "ti,tca6416";
+ reg = <0x20>;
+ gpio-controller;
+ #gpio-cells = <2>;
+ vcc-supply = <&buck4_reg>;
+ };
+
+ /*ak4458_1: ak4458@10 {
+ compatible = "asahi-kasei,ak4458";
+ reg = <0x10>;
+ AVDD-supply = <®_audio_board>;
+ DVDD-supply = <®_audio_board>;
+ };
+
+ ak4458_2: ak4458@12 {
+ compatible = "asahi-kasei,ak4458";
+ reg = <0x12>;
+ AVDD-supply = <®_audio_board>;
+ DVDD-supply = <®_audio_board>;
+ };
+
+ ak5558: ak5558@13 {
+ compatible = "asahi-kasei,ak5558";
+ reg = <0x13>;
+ reset-gpios = <&pca6416 3 GPIO_ACTIVE_HIGH>;
+ AVDD-supply = <®_audio_board>;
+ DVDD-supply = <®_audio_board>;
+ };
+
+ ak4497: ak4497@11 {
+ compatible = "asahi-kasei,ak4497";
+ reg = <0x11>;
+ reset-gpios = <&pca6416 5 GPIO_ACTIVE_HIGH>;
+ AVDD-supply = <®_audio_board>;
+ DVDD-supply = <®_audio_board>;
+ dsd-path = <1>;
+ };*/
+
+ ov5640_mipi: ov5640_mipi@3c {
+ compatible = "ovti,ov5640_mipi";
+ reg = <0x3c>;
+ status = "okay";
+ pinctrl-names = "default";
+ pinctrl-0 = <&pinctrl_csi_pwn>, <&pinctrl_csi_rst>;
+ clocks = <&clk IMX8MM_CLK_CLKO1>;
+ clock-names = "csi_mclk";
+ assigned-clocks = <&clk IMX8MM_CLK_CLKO1>;
+ assigned-clock-parents = <&clk IMX8MM_CLK_24M>;
+ assigned-clock-rates = <24000000>;
+ csi_id = <0>;
+ pwn-gpios = <&gpio1 7 GPIO_ACTIVE_HIGH>;
+ mclk = <24000000>;
+ mclk_source = <0>;
+ port {
+ ov5640_mipi1_ep: endpoint {
+ remote-endpoint = <&mipi1_sensor_ep>;
+ };
+ };
+ };
+};
+
+&lcdif {
+ status = "okay";
+};
+
+&mipi_csi_1 {
+ #address-cells = <1>;
+ #size-cells = <0>;
+ status = "okay";
+ port {
+ mipi1_sensor_ep: endpoint@1 {
+ remote-endpoint = <&ov5640_mipi1_ep>;
+ data-lanes = <2>;
+ csis-hs-settle = <13>;
+ csis-clk-settle = <2>;
+ csis-wclk;
+ };
+
+ csi1_mipi_ep: endpoint@2 {
+ remote-endpoint = <&csi1_ep>;
+ };
+ };
+};
+
+&micfil {
+ pinctrl-names = "default";
+ pinctrl-0 = <&pinctrl_pdm>;
+ assigned-clocks = <&clk IMX8MM_CLK_PDM>;
+ assigned-clock-parents = <&clk IMX8MM_AUDIO_PLL1_OUT>;
+ assigned-clock-rates = <196608000>;
+ status = "okay";
+};
+
+&mipi_dsi {
+ status = "okay";
+
+ port@1 {
+ mipi_dsi_out: endpoint {
+ remote-endpoint = <&dsi_lvds_bridge_in>;
+ attach-bridge;
+ };
+ };
+};
+
+&pcie0{
+ pinctrl-names = "default";
+ pinctrl-0 = <&pinctrl_pcie0>;
+ disable-gpio = <&gpio1 5 GPIO_ACTIVE_LOW>;
+ reset-gpio = <&gpio4 21 GPIO_ACTIVE_LOW>;
+ clocks = <&clk IMX8MM_CLK_PCIE1_ROOT>,
+ <&clk IMX8MM_CLK_PCIE1_AUX>,
+ <&clk IMX8MM_CLK_PCIE1_PHY>,
+ <&pcie0_refclk>;
+ clock-names = "pcie", "pcie_aux", "pcie_phy", "pcie_bus";
+ assigned-clocks = <&clk IMX8MM_CLK_PCIE1_AUX>;
+ assigned-clock-rates = <10000000>;
+ assigned-clock-parents = <&clk IMX8MM_SYS_PLL2_50M>;
+ ext_osc = <1>;
+ status = "disabled";
+};
+
+&pcie0_ep{
+ pinctrl-names = "default";
+ pinctrl-0 = <&pinctrl_pcie0>;
+ clocks = <&clk IMX8MM_CLK_PCIE1_ROOT>,
+ <&clk IMX8MM_CLK_PCIE1_AUX>,
+ <&clk IMX8MM_CLK_PCIE1_PHY>,
+ <&pcie0_refclk>;
+ clock-names = "pcie", "pcie_aux", "pcie_phy", "pcie_bus";
+ assigned-clocks = <&clk IMX8MM_CLK_PCIE1_AUX>;
+ assigned-clock-rates = <10000000>;
+ assigned-clock-parents = <&clk IMX8MM_SYS_PLL2_50M>;
+ ext_osc = <1>;
+ status = "disabled";
+};
+
+//JOC: TODO check if it is necessary to change sai2
+/*R&sai2 {
+ #sound-dai-cells = <0>;
+ pinctrl-names = "default";
+ pinctrl-0 = <&pinctrl_sai2>;
+ assigned-clocks = <&clk IMX8MM_CLK_SAI2>;
+ assigned-clock-parents = <&clk IMX8MM_AUDIO_PLL1_OUT>;
+ assigned-clock-rates = <24576000>;
+ status = "okay";
+};*/
+
+&sai1 {
+ pinctrl-names = "default", "dsd";
+ pinctrl-0 = <&pinctrl_sai1>;
+ pinctrl-1 = <&pinctrl_sai1_dsd>;
+ assigned-clocks = <&clk IMX8MM_CLK_SAI1>;
+ assigned-clock-parents = <&clk IMX8MM_AUDIO_PLL1_OUT>;
+ assigned-clock-rates = <49152000>;
+ clocks = <&clk IMX8MM_CLK_SAI1_IPG>, <&clk IMX8MM_CLK_DUMMY>,
+ <&clk IMX8MM_CLK_SAI1_ROOT>, <&clk IMX8MM_CLK_DUMMY>,
+ <&clk IMX8MM_CLK_DUMMY>, <&clk IMX8MM_AUDIO_PLL1_OUT>,
+ <&clk IMX8MM_AUDIO_PLL2_OUT>;
+ clock-names = "bus", "mclk0", "mclk1", "mclk2", "mclk3", "pll8k", "pll11k";
+ fsl,sai-multi-lane;
+ fsl,dataline,dsd = <0 0xff 0xff 2 0xff 0x11>;
+ dmas = <&sdma2 0 25 0>, <&sdma2 1 25 0>;
+ status = "okay";
+};
+
+/*&sai3 {
+ pinctrl-names = "default";
+ pinctrl-0 = <&pinctrl_sai3>;
+ assigned-clocks = <&clk IMX8MM_CLK_SAI3>;
+ assigned-clock-parents = <&clk IMX8MM_AUDIO_PLL1_OUT>;
+ assigned-clock-rates = <24576000>;
+ status = "okay";
+};*/
+
+&sai5 {
+ pinctrl-names = "default";
+ pinctrl-0 = <&pinctrl_sai5>;
+ assigned-clocks = <&clk IMX8MM_CLK_SAI5>;
+ assigned-clock-parents = <&clk IMX8MM_AUDIO_PLL1_OUT>;
+ assigned-clock-rates = <49152000>;
+ clocks = <&clk IMX8MM_CLK_SAI5_IPG>, <&clk IMX8MM_CLK_DUMMY>,
+ <&clk IMX8MM_CLK_SAI5_ROOT>, <&clk IMX8MM_CLK_DUMMY>,
+ <&clk IMX8MM_CLK_DUMMY>, <&clk IMX8MM_AUDIO_PLL1_OUT>,
+ <&clk IMX8MM_AUDIO_PLL2_OUT>;
+ clock-names = "bus", "mclk0", "mclk1", "mclk2", "mclk3", "pll8k", "pll11k";
+ fsl,sai-asynchronous;
+ status = "disabled";
+};
+
+&sai6 {
+ fsl,sai-monitor-spdif;
+ fsl,sai-asynchronous;
+ status = "okay";
+};
+
+&snvs_pwrkey {
+ status = "okay";
+};
+
+&spdif1 {
+ pinctrl-names = "default";
+ pinctrl-0 = <&pinctrl_spdif1>;
+ assigned-clocks = <&clk IMX8MM_CLK_SPDIF1>;
+ assigned-clock-parents = <&clk IMX8MM_AUDIO_PLL1_OUT>;
+ assigned-clock-rates = <24576000>;
+ clocks = <&clk IMX8MM_CLK_AUDIO_AHB>, <&clk IMX8MM_CLK_24M>,
+ <&clk IMX8MM_CLK_SPDIF1>, <&clk IMX8MM_CLK_DUMMY>,
+ <&clk IMX8MM_CLK_DUMMY>, <&clk IMX8MM_CLK_DUMMY>,
+ <&clk IMX8MM_CLK_AUDIO_AHB>, <&clk IMX8MM_CLK_DUMMY>,
+ <&clk IMX8MM_CLK_DUMMY>, <&clk IMX8MM_CLK_DUMMY>,
+ <&clk IMX8MM_AUDIO_PLL1_OUT>, <&clk IMX8MM_AUDIO_PLL2_OUT>;
+ clock-names = "core", "rxtx0", "rxtx1", "rxtx2", "rxtx3",
+ "rxtx4", "rxtx5", "rxtx6", "rxtx7", "spba", "pll8k", "pll11k";
+ status = "okay";
+};
+
+&uart1 { /* BT */
+ pinctrl-names = "default";
+ pinctrl-0 = <&pinctrl_uart1>;
+ assigned-clocks = <&clk IMX8MM_CLK_UART1>;
+ assigned-clock-parents = <&clk IMX8MM_SYS_PLL1_80M>;
+ fsl,uart-has-rtscts;
+ resets = <&modem_reset>;
+ status = "okay";
+};
+
+&uart2 { /* console */
+ pinctrl-names = "default";
+ pinctrl-0 = <&pinctrl_uart2>;
+ status = "okay";
+};
+
+&uart3 {
+ pinctrl-names = "default";
+ pinctrl-0 = <&pinctrl_uart3>;
+ assigned-clocks = <&clk IMX8MM_CLK_UART3>;
+ assigned-clock-parents = <&clk IMX8MM_SYS_PLL1_80M>;
+ fsl,uart-has-rtscts;
+ status = "okay";
+};
+
+/*&usbotg1 {
+ dr_mode = "otg";
+ hnp-disable;
+ srp-disable;
+ adp-disable;
+ usb-role-switch;
+ samsung,picophy-pre-emp-curr-control = <3>;
+ samsung,picophy-dc-vol-level-adjust = <7>;
+ status = "okay";
+
+ port {
+ usb1_drd_sw: endpoint {
+ remote-endpoint = <&typec1_dr_sw>;
+ };
+ };
+};*/
+&usbotg1 {
+ dr_mode = "otg";
+ //over-current-active-low;
+ pinctrl-names = "default";
+ //pinctrl-0 = <&pinctrl_usbotg1>;
+ //power-active-high;
+ status = "okay";
+};
+
+&usdhc2 {
+ assigned-clocks = <&clk IMX8MM_CLK_USDHC2>;
+ assigned-clock-rates = <200000000>;
+ pinctrl-names = "default", "state_100mhz", "state_200mhz";
+ pinctrl-0 = <&pinctrl_usdhc2>, <&pinctrl_usdhc2_gpio>;
+ pinctrl-1 = <&pinctrl_usdhc2_100mhz>, <&pinctrl_usdhc2_gpio>;
+ pinctrl-2 = <&pinctrl_usdhc2_200mhz>, <&pinctrl_usdhc2_gpio>;
+ cd-gpios = <&gpio2 12 GPIO_ACTIVE_LOW>;
+ bus-width = <4>;
+ vmmc-supply = <®_usdhc2_vmmc>;
+ status = "okay";
+};
+
+&vpu_g1 {
+ status = "okay";
+};
+
+&vpu_g2 {
+ status = "okay";
+};
+
+&vpu_h1 {
+ status = "okay";
+};
+
+&wdog1 {
+ pinctrl-names = "default";
+ pinctrl-0 = <&pinctrl_wdog>;
+ fsl,ext-reset-output;
+ status = "okay";
+};
+
+&gpu {
+ status = "okay";
+};
+
+&iomuxc {
+ pinctrl_ir_recv: ir-recv {
+ fsl,pins = <
+ MX8MM_IOMUXC_GPIO1_IO13_GPIO1_IO13 0x4f
+
+ >;
+ };
+
+ pinctrl_usbotg1: usbotg1grp {
+ fsl,pins = <
+ //MX8MMN(IOMUXC_GPIO1_IO12_USB1_OTG_PWR, 0x16)
+ //MX8MMN(IOMUXC_GPIO1_IO13_USB1_OTG_OC, 0x156)
+ MX8MM_IOMUXC_GPIO1_IO12_USB1_OTG_PWR 0x16
+ MX8MM_IOMUXC_GPIO1_IO13_USB1_OTG_OC 0x156
+ >;
+ };
+
+ pinctrl_csi_pwn: csi_pwn_grp {
+ fsl,pins = <
+ MX8MM_IOMUXC_GPIO1_IO07_GPIO1_IO7 0x19
+ >;
+ };
+
+ pinctrl_csi_rst: csi_rst_grp {
+ fsl,pins = <
+ MX8MM_IOMUXC_GPIO1_IO06_GPIO1_IO6 0x19
+ MX8MM_IOMUXC_GPIO1_IO14_CCMSRCGPCMIX_CLKO1 0x59
+ >;
+ };
+
+ pinctrl_ecspi2: ecspi2grp {
+ fsl,pins = <
+ MX8MM_IOMUXC_ECSPI2_SCLK_ECSPI2_SCLK 0x82
+ MX8MM_IOMUXC_ECSPI2_MOSI_ECSPI2_MOSI 0x82
+ MX8MM_IOMUXC_ECSPI2_MISO_ECSPI2_MISO 0x82
+ >;
+ };
+
+ pinctrl_ecspi2_cs: ecspi2cs {
+ fsl,pins = <
+ MX8MM_IOMUXC_ECSPI2_SS0_GPIO5_IO13 0x40000
+ >;
+ };
+ //JOC
+ pinctrl_ecspi3: ecspi3grp {
+ fsl,pins = <
+ MX8MM_IOMUXC_UART1_RXD_ECSPI3_SCLK 0x4 /* CAN_SPI_SCK */
+ MX8MM_IOMUXC_UART1_TXD_ECSPI3_MOSI 0x4 /* CAN_SPI_MOSI */
+ MX8MM_IOMUXC_UART2_RXD_ECSPI3_MISO 0x1c4 /* CAN_SPI_MISO */
+ MX8MM_IOMUXC_UART2_TXD_GPIO5_IO25 0x1c4 /* CAN_1_SPI_CS */
+ >;
+ };
+
+ pinctrl_can1_int: can1intgrp {
+ fsl,pins = <
+ MX8MM_IOMUXC_UART3_RXD_GPIO5_IO26 0x1c4 /* CAN_1_SPI_INT#_1.8V */
+ >;
+ };
+
+ pinctrl_fec1: fec1grp {
+ fsl,pins = <
+ MX8MM_IOMUXC_ENET_MDC_ENET1_MDC 0x3
+ MX8MM_IOMUXC_ENET_MDIO_ENET1_MDIO 0x3
+ MX8MM_IOMUXC_ENET_TD3_ENET1_RGMII_TD3 0x1f
+ MX8MM_IOMUXC_ENET_TD2_ENET1_RGMII_TD2 0x1f
+ MX8MM_IOMUXC_ENET_TD1_ENET1_RGMII_TD1 0x1f
+ MX8MM_IOMUXC_ENET_TD0_ENET1_RGMII_TD0 0x1f
+ MX8MM_IOMUXC_ENET_RD3_ENET1_RGMII_RD3 0x91
+ MX8MM_IOMUXC_ENET_RD2_ENET1_RGMII_RD2 0x91
+ MX8MM_IOMUXC_ENET_RD1_ENET1_RGMII_RD1 0x91
+ MX8MM_IOMUXC_ENET_RD0_ENET1_RGMII_RD0 0x91
+ MX8MM_IOMUXC_ENET_TXC_ENET1_RGMII_TXC 0x1f
+ MX8MM_IOMUXC_ENET_RXC_ENET1_RGMII_RXC 0x91
+ MX8MM_IOMUXC_ENET_RX_CTL_ENET1_RGMII_RX_CTL 0x91
+ MX8MM_IOMUXC_ENET_TX_CTL_ENET1_RGMII_TX_CTL 0x1f
+ //MX8MM_IOMUXC_SAI2_RXC_GPIO4_IO22 0x19
+ MX8MM_IOMUXC_UART4_TXD_GPIO5_IO29 0x19 //JOC
+ >;
+ };
+
+ pinctrl_gpio_led: gpioledgrp {
+ fsl,pins = <
+ MX8MM_IOMUXC_NAND_READY_B_GPIO3_IO16 0x19
+ >;
+ };
+
+ /*pinctrl_gpio_wlf: gpiowlfgrp {
+ fsl,pins = <
+ MX8MM_IOMUXC_I2C4_SDA_GPIO5_IO21 0xd6
+ >;
+ };*/
+
+ pinctrl_i2c1: i2c1grp {
+ fsl,pins = <
+ MX8MM_IOMUXC_I2C1_SCL_I2C1_SCL 0x400001c3
+ MX8MM_IOMUXC_I2C1_SDA_I2C1_SDA 0x400001c3
+ >;
+ };
+
+ pinctrl_i2c2: i2c2grp {
+ fsl,pins = <
+ MX8MM_IOMUXC_I2C2_SCL_I2C2_SCL 0x400001c3
+ MX8MM_IOMUXC_I2C2_SDA_I2C2_SDA 0x400001c3
+ >;
+ };
+
+ pinctrl_i2c2_synaptics_dsx_io: synaptics_dsx_iogrp {
+ fsl,pins = <
+ MX8MM_IOMUXC_GPIO1_IO09_GPIO1_IO9 0x19 /* Touch int */
+ >;
+ };
+
+ pinctrl_i2c3: i2c3grp {
+ fsl,pins = <
+ MX8MM_IOMUXC_I2C3_SCL_I2C3_SCL 0x400001c3
+ MX8MM_IOMUXC_I2C3_SDA_I2C3_SDA 0x400001c3
+ >;
+ };
+
+ pinctrl_mipi_dsi_en: mipi_dsi_en {
+ fsl,pins = <
+ MX8MM_IOMUXC_GPIO1_IO08_GPIO1_IO8 0x16
+ >;
+ };
+
+ pinctrl_lvds: lvdsgrp {
+ fsl,pins = <
+ MX8MM_IOMUXC_I2C4_SDA_GPIO5_IO21 0x16
+ >;
+ };
+
+ pinctrl_pcie0: pcie0grp {
+ fsl,pins = <
+ MX8MM_IOMUXC_I2C4_SCL_PCIE1_CLKREQ_B 0x61 /* open drain, pull up */
+ MX8MM_IOMUXC_GPIO1_IO05_GPIO1_IO5 0x41
+ MX8MM_IOMUXC_SAI2_RXFS_GPIO4_IO21 0x41
+ >;
+ };
+
+ pinctrl_pdm: pdmgrp {
+ fsl,pins = <
+ MX8MM_IOMUXC_SAI5_MCLK_SAI5_MCLK 0xd6
+ MX8MM_IOMUXC_SAI5_RXC_PDM_CLK 0xd6
+ MX8MM_IOMUXC_SAI5_RXFS_SAI5_RX_SYNC 0xd6
+ MX8MM_IOMUXC_SAI5_RXD0_PDM_DATA0 0xd6
+ MX8MM_IOMUXC_SAI5_RXD1_PDM_DATA1 0xd6
+ MX8MM_IOMUXC_SAI5_RXD2_PDM_DATA2 0xd6
+ MX8MM_IOMUXC_SAI5_RXD3_PDM_DATA3 0xd6
+ >;
+ };
+
+ pinctrl_pmic: pmicirqgrp {
+ fsl,pins = <
+ MX8MM_IOMUXC_GPIO1_IO03_GPIO1_IO3 0x141
+ >;
+ };
+
+ pinctrl_reg_usdhc2_vmmc: regusdhc2vmmcgrp {
+ fsl,pins = <
+ MX8MM_IOMUXC_SD2_RESET_B_GPIO2_IO19 0x41
+ >;
+ };
+
+ pinctrl_sai1: sai1grp {
+ fsl,pins = <
+ MX8MM_IOMUXC_SAI1_MCLK_SAI1_MCLK 0xd6
+ MX8MM_IOMUXC_SAI1_TXFS_SAI1_TX_SYNC 0xd6
+ MX8MM_IOMUXC_SAI1_RXD7_SAI1_TX_SYNC 0xd6
+ MX8MM_IOMUXC_SAI1_TXC_SAI1_TX_BCLK 0xd6
+ MX8MM_IOMUXC_SAI1_TXD0_SAI1_TX_DATA0 0xd6
+ MX8MM_IOMUXC_SAI1_TXD1_SAI1_TX_DATA1 0xd6
+ MX8MM_IOMUXC_SAI1_TXD2_SAI1_TX_DATA2 0xd6
+ MX8MM_IOMUXC_SAI1_TXD3_SAI1_TX_DATA3 0xd6
+ MX8MM_IOMUXC_SAI1_TXD4_SAI1_TX_DATA4 0xd6
+ MX8MM_IOMUXC_SAI1_TXD5_SAI1_TX_DATA5 0xd6
+ MX8MM_IOMUXC_SAI1_TXD6_SAI1_TX_DATA6 0xd6
+ MX8MM_IOMUXC_SAI1_TXD7_SAI1_TX_DATA7 0xd6
+ >;
+ };
+
+ pinctrl_sai1_dsd: sai1grp_dsd {
+ fsl,pins = <
+ MX8MM_IOMUXC_SAI1_MCLK_SAI1_MCLK 0xd6
+ MX8MM_IOMUXC_SAI1_TXFS_SAI1_TX_SYNC 0xd6
+ MX8MM_IOMUXC_SAI1_RXD7_SAI1_TX_DATA4 0xd6
+ MX8MM_IOMUXC_SAI1_TXC_SAI1_TX_BCLK 0xd6
+ MX8MM_IOMUXC_SAI1_TXD0_SAI1_TX_DATA0 0xd6
+ MX8MM_IOMUXC_SAI1_TXD1_SAI1_TX_DATA1 0xd6
+ MX8MM_IOMUXC_SAI1_TXD2_SAI1_TX_DATA2 0xd6
+ MX8MM_IOMUXC_SAI1_TXD3_SAI1_TX_DATA3 0xd6
+ MX8MM_IOMUXC_SAI1_TXD4_SAI1_TX_DATA4 0xd6
+ MX8MM_IOMUXC_SAI1_TXD5_SAI1_TX_DATA5 0xd6
+ MX8MM_IOMUXC_SAI1_TXD6_SAI1_TX_DATA6 0xd6
+ MX8MM_IOMUXC_SAI1_TXD7_SAI1_TX_DATA7 0xd6
+ >;
+ };
+
+ pinctrl_sai2: sai2grp {
+ fsl,pins = <
+ MX8MM_IOMUXC_SAI2_TXC_SAI2_TX_BCLK 0xd6
+ MX8MM_IOMUXC_SAI2_TXFS_SAI2_TX_SYNC 0xd6
+ MX8MM_IOMUXC_SAI2_TXD0_SAI2_TX_DATA0 0xd6
+ MX8MM_IOMUXC_SAI2_RXD0_SAI2_RX_DATA0 0xd6
+ >;
+ };
+
+ pinctrl_sai3: sai3grp {
+ fsl,pins = <
+ MX8MM_IOMUXC_SAI3_TXFS_SAI3_TX_SYNC 0xd6
+ MX8MM_IOMUXC_SAI3_TXC_SAI3_TX_BCLK 0xd6
+ MX8MM_IOMUXC_SAI3_MCLK_SAI3_MCLK 0xd6
+ MX8MM_IOMUXC_SAI3_TXD_SAI3_TX_DATA0 0xd6
+ >;
+ };
+
+ pinctrl_sai5: sai5grp {
+ fsl,pins = <
+ MX8MM_IOMUXC_SAI5_MCLK_SAI5_MCLK 0xd6
+ MX8MM_IOMUXC_SAI5_RXC_SAI5_RX_BCLK 0xd6
+ MX8MM_IOMUXC_SAI5_RXFS_SAI5_RX_SYNC 0xd6
+ MX8MM_IOMUXC_SAI5_RXD0_SAI5_RX_DATA0 0xd6
+ MX8MM_IOMUXC_SAI5_RXD1_SAI5_RX_DATA1 0xd6
+ MX8MM_IOMUXC_SAI5_RXD2_SAI5_RX_DATA2 0xd6
+ MX8MM_IOMUXC_SAI5_RXD3_SAI5_RX_DATA3 0xd6
+ >;
+ };
+
+ pinctrl_spdif1: spdif1grp {
+ fsl,pins = <
+ MX8MM_IOMUXC_SPDIF_TX_SPDIF1_OUT 0xd6
+ MX8MM_IOMUXC_SPDIF_RX_SPDIF1_IN 0xd6
+ >;
+ };
+
+ pinctrl_typec1: typec1grp {
+ fsl,pins = <
+ MX8MM_IOMUXC_SD1_STROBE_GPIO2_IO11 0x159
+ >;
+ };
+
+ pinctrl_uart1: uart1grp {
+ fsl,pins = <
+ /*MX8MM_IOMUXC_UART1_RXD_UART1_DCE_RX 0x140
+ MX8MM_IOMUXC_UART1_TXD_UART1_DCE_TX 0x140
+ MX8MM_IOMUXC_UART3_RXD_UART1_DCE_CTS_B 0x140
+ MX8MM_IOMUXC_UART3_TXD_UART1_DCE_RTS_B 0x140*/
+ MX8MM_IOMUXC_SAI2_RXC_UART1_DCE_RX 0x140
+ MX8MM_IOMUXC_SAI2_RXFS_UART1_DCE_TX 0x140
+ MX8MM_IOMUXC_SAI2_TXFS_UART1_DCE_CTS_B 0x140
+ MX8MM_IOMUXC_SAI2_RXD0_UART1_DCE_RTS_B 0x140
+ MX8MM_IOMUXC_SD1_DATA4_GPIO2_IO6 0x19
+ >;
+ };
+
+ pinctrl_uart2: uart2grp {
+ fsl,pins = <
+ //MX8MM_IOMUXC_UART2_RXD_UART2_DCE_RX 0x140
+ //MX8MM_IOMUXC_UART2_TXD_UART2_DCE_TX 0x140
+ MX8MM_IOMUXC_SAI3_TXFS_UART2_DCE_RX 0x140
+ MX8MM_IOMUXC_SAI3_TXC_UART2_DCE_TX 0x140
+ >;
+ };
+
+ pinctrl_uart3: uart3grp {
+ fsl,pins = <
+ MX8MM_IOMUXC_ECSPI1_SCLK_UART3_DCE_RX 0x140
+ MX8MM_IOMUXC_ECSPI1_MOSI_UART3_DCE_TX 0x140
+ MX8MM_IOMUXC_ECSPI1_SS0_UART3_DCE_RTS_B 0x140
+ MX8MM_IOMUXC_ECSPI1_MISO_UART3_DCE_CTS_B 0x140
+ >;
+ };
+
+ pinctrl_usdhc1_gpio: usdhc1grpgpio {
+ fsl,pins = <
+ MX8MM_IOMUXC_SD1_RESET_B_GPIO2_IO10 0x41
+ >;
+ };
+
+ pinctrl_usdhc1: usdhc1grp {
+ fsl,pins = <
+ MX8MM_IOMUXC_SD1_CLK_USDHC1_CLK 0x190
+ MX8MM_IOMUXC_SD1_CMD_USDHC1_CMD 0x1d0
+ MX8MM_IOMUXC_SD1_DATA0_USDHC1_DATA0 0x1d0
+ MX8MM_IOMUXC_SD1_DATA1_USDHC1_DATA1 0x1d0
+ MX8MM_IOMUXC_SD1_DATA2_USDHC1_DATA2 0x1d0
+ MX8MM_IOMUXC_SD1_DATA3_USDHC1_DATA3 0x1d0
+ >;
+ };
+
+ pinctrl_usdhc1_100mhz: usdhc1grp100mhz {
+ fsl,pins = <
+ MX8MM_IOMUXC_SD1_CLK_USDHC1_CLK 0x194
+ MX8MM_IOMUXC_SD1_CMD_USDHC1_CMD 0x1d4
+ MX8MM_IOMUXC_SD1_DATA0_USDHC1_DATA0 0x1d4
+ MX8MM_IOMUXC_SD1_DATA1_USDHC1_DATA1 0x1d4
+ MX8MM_IOMUXC_SD1_DATA2_USDHC1_DATA2 0x1d4
+ MX8MM_IOMUXC_SD1_DATA3_USDHC1_DATA3 0x1d4
+ >;
+ };
+
+ pinctrl_usdhc1_200mhz: usdhc1grp200mhz {
+ fsl,pins = <
+ MX8MM_IOMUXC_SD1_CLK_USDHC1_CLK 0x196
+ MX8MM_IOMUXC_SD1_CMD_USDHC1_CMD 0x1d6
+ MX8MM_IOMUXC_SD1_DATA0_USDHC1_DATA0 0x1d6
+ MX8MM_IOMUXC_SD1_DATA1_USDHC1_DATA1 0x1d6
+ MX8MM_IOMUXC_SD1_DATA2_USDHC1_DATA2 0x1d6
+ MX8MM_IOMUXC_SD1_DATA3_USDHC1_DATA3 0x1d6
+ >;
+ };
+
+ pinctrl_usdhc2_gpio: usdhc2grpgpiogrp {
+ fsl,pins = <
+ //MX8MM_IOMUXC_GPIO1_IO15_GPIO1_IO15 0x1c4
+ MX8MM_IOMUXC_SD2_CD_B_GPIO2_IO12 0x1c4
+ >;
+ };
+
+ pinctrl_usdhc2: usdhc2grp {
+ fsl,pins = <
+ MX8MM_IOMUXC_SD2_CLK_USDHC2_CLK 0x190
+ MX8MM_IOMUXC_SD2_CMD_USDHC2_CMD 0x1d0
+ MX8MM_IOMUXC_SD2_DATA0_USDHC2_DATA0 0x1d0
+ MX8MM_IOMUXC_SD2_DATA1_USDHC2_DATA1 0x1d0
+ MX8MM_IOMUXC_SD2_DATA2_USDHC2_DATA2 0x1d0
+ MX8MM_IOMUXC_SD2_DATA3_USDHC2_DATA3 0x1d0
+ MX8MM_IOMUXC_GPIO1_IO04_USDHC2_VSELECT 0x1d0
+ >;
+ };
+
+ pinctrl_usdhc2_100mhz: usdhc2-100mhzgrp {
+ fsl,pins = <
+ MX8MM_IOMUXC_SD2_CLK_USDHC2_CLK 0x194
+ MX8MM_IOMUXC_SD2_CMD_USDHC2_CMD 0x1d4
+ MX8MM_IOMUXC_SD2_DATA0_USDHC2_DATA0 0x1d4
+ MX8MM_IOMUXC_SD2_DATA1_USDHC2_DATA1 0x1d4
+ MX8MM_IOMUXC_SD2_DATA2_USDHC2_DATA2 0x1d4
+ MX8MM_IOMUXC_SD2_DATA3_USDHC2_DATA3 0x1d4
+ MX8MM_IOMUXC_GPIO1_IO04_USDHC2_VSELECT 0x1d0
+ >;
+ };
+
+ pinctrl_usdhc2_200mhz: usdhc2-200mhzgrp {
+ fsl,pins = <
+ MX8MM_IOMUXC_SD2_CLK_USDHC2_CLK 0x196
+ MX8MM_IOMUXC_SD2_CMD_USDHC2_CMD 0x1d6
+ MX8MM_IOMUXC_SD2_DATA0_USDHC2_DATA0 0x1d6
+ MX8MM_IOMUXC_SD2_DATA1_USDHC2_DATA1 0x1d6
+ MX8MM_IOMUXC_SD2_DATA2_USDHC2_DATA2 0x1d6
+ MX8MM_IOMUXC_SD2_DATA3_USDHC2_DATA3 0x1d6
+ MX8MM_IOMUXC_GPIO1_IO04_USDHC2_VSELECT 0x1d0
+ >;
+ };
+
+ pinctrl_wdog: wdoggrp {
+ fsl,pins = <
+ MX8MM_IOMUXC_GPIO1_IO02_WDOG1_WDOG_B 0xc6
+ >;
+ };
+};
--- /dev/null
+SUMMARY = "Linux Kernel provided by NXP and patched by SomDevices"
+DESCRIPTION = "Linux Kernel for SomDevices i.MX based COM boards. \
+The kernel is based on the kernel provided by NXP."
+
+FILESEXTRAPATHS_prepend := "${THISDIR}/files:"
+
+SRC_URI_append_imx8mm-somdevices-c0p1 += "\
+ file://imx8mm-somdevices-c0p1.dts \
+ file://imx8mm-somdevices-c0p1.dtsi \
+ file://0001-arm64-Add-SomDevices-Smarc-C0P1-to-Makefile.patch \
+ file://0002-arm64-Add-sn65dsi83-4-support.patch \
+ file://0003-arm64-Not-to-show-warning-CAN-interface.patch \
+ "
+
+do_configure_append_imx8mm-somdevices-c0p1 () {
+ # For arm64 bit freescale/NXP devices
+ cp ${WORKDIR}/imx8mm-somdevices-c0p1.dts ${S}/arch/arm64/boot/dts/freescale
+ cp ${WORKDIR}/imx8mm-somdevices-c0p1.dtsi ${S}/arch/arm64/boot/dts/freescale
+}